public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-platforms: Patch 0/8] Add packages from edk2
@ 2019-05-10  3:34 Michael D Kinney
  2019-05-10  3:34 ` [edk2-platforms: Patch 1/8] Silicon/TexasInsturments: Import Omap35xxPkg " Michael D Kinney
                   ` (10 more replies)
  0 siblings, 11 replies; 23+ messages in thread
From: Michael D Kinney @ 2019-05-10  3:34 UTC (permalink / raw)
  To: devel
  Cc: Zailiang Sun, Yi Qian, Kelly Steele, Ray Ni, Michael Kubacki,
	Leif Lindholm, Ard Biesheuvel

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

Add the following platform, silicon, and driver packages from the edk2 repo
to the edk2-platforms repo
* Drivers/OptionRomPkg
* Platform/BeagleBoard/BeagleBoardPkg
* Platform/Intel/QuarkPlatformPkg
* Platform/Intel/Vlv2TbltDevicePkg
* Silicon/Intel/QuarkSocPkg
* Silicon/Intel/Vlv2DeviceRefCodePkg
* Silicon/TexasInsturments/Omap35xxPkg

Cc: Zailiang Sun <zailiang.sun@intel.com>
Cc: Yi Qian <yi.qian@intel.com>
Cc: Kelly Steele <kelly.steele@intel.com>
Cc: Ray Ni <ray.ni@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>

Michael D Kinney (8):
  Silicon/TexasInsturments: Import Omap35xxPkg from edk2
  Platform/BeagleBoard: Import BeagleBoardPkg from edk2
  Silicon/Intel: Import QuarkSocPkg from edk2
  Platform/QuarkPlatformPkg: Import QuarkPlatformPkg from edk2
  Platform/Vlv2DeviceRefCodePkg: Import Vlv2DeviceRefCodePkg from edk2
  Platform/Vlv2TbltDevicePkg: Import Vlv2TbltDevicePkg from edk2
  Drivers/OptionRomPkg: Import OptionRomPkg from edk2
  edk2-platforms: Update Maintainers.txt/Readme.md for imported packages

 .../Application/BltLibSample/BltLibSample.c   |  279 +
 .../Application/BltLibSample/BltLibSample.inf |   30 +
 .../AtapiPassThruDxe/AtapiPassThru.c          | 3410 +++++++++++++
 .../AtapiPassThruDxe/AtapiPassThru.h          | 1618 ++++++
 .../AtapiPassThruDxe/AtapiPassThruDxe.inf     |   70 +
 .../AtapiPassThruDxe/ComponentName.c          |  169 +
 .../DriverSupportedEfiVersion.c               |   14 +
 .../FtdiUsbSerialDxe/CompatibleDevices.txt    |    5 +
 .../Bus/Usb/FtdiUsbSerialDxe/ComponentName.c  |  218 +
 .../FtdiUsbSerialDxe/FtdiUsbSerialDriver.c    | 2580 ++++++++++
 .../FtdiUsbSerialDxe/FtdiUsbSerialDriver.h    |  589 +++
 .../Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf |   55 +
 .../Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt       |   32 +
 .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.c   | 1318 +++++
 .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.h   |  969 ++++
 .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf |   61 +
 .../Usb/UsbNetworking/Ax88772/ComponentName.c |  178 +
 .../Usb/UsbNetworking/Ax88772/DriverBinding.c |  507 ++
 .../Usb/UsbNetworking/Ax88772/SimpleNetwork.c | 1503 ++++++
 .../Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c  |  875 ++++
 .../Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h  | 1026 ++++
 .../Usb/UsbNetworking/Ax88772b/Ax88772b.inf   |   61 +
 .../UsbNetworking/Ax88772b/ComponentName.c    |  175 +
 .../UsbNetworking/Ax88772b/DriverBinding.c    |  696 +++
 .../UsbNetworking/Ax88772b/SimpleNetwork.c    | 1657 ++++++
 .../CirrusLogic5430Dxe/CirrusLogic5430.c      |  917 ++++
 .../CirrusLogic5430Dxe/CirrusLogic5430.h      |  432 ++
 .../CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf |   84 +
 .../CirrusLogic5430GraphicsOutput.c           |  556 ++
 .../CirrusLogic5430Dxe/CirrusLogic5430I2c.c   |  427 ++
 .../CirrusLogic5430Dxe/CirrusLogic5430I2c.h   |   62 +
 .../CirrusLogic5430UgaDraw.c                  |  412 ++
 .../CirrusLogic5430Dxe/ComponentName.c        |  203 +
 .../DriverSupportedEfiVersion.c               |   14 +
 .../OptionRomPkg/CirrusLogic5430Dxe/Edid.c    |  525 ++
 Drivers/OptionRomPkg/Include/Library/BltLib.h |  253 +
 .../FrameBufferBltLib/FrameBufferBltLib.c     |  744 +++
 .../FrameBufferBltLib/FrameBufferBltLib.inf   |   29 +
 .../Library/GopBltLib/GopBltLib.c             |  449 ++
 .../Library/GopBltLib/GopBltLib.inf           |   31 +
 Drivers/OptionRomPkg/OptionRomPkg.dec         |   41 +
 Drivers/OptionRomPkg/OptionRomPkg.dsc         |  113 +
 Drivers/OptionRomPkg/ReadMe.txt               |   17 +
 .../UndiRuntimeDxe/ComponentName.c            |  359 ++
 Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c  | 1516 ++++++
 Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c   | 3541 +++++++++++++
 Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h   |  665 +++
 Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c    | 1051 ++++
 Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h  |  439 ++
 .../OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c |  145 +
 .../UndiRuntimeDxe/UndiRuntimeDxe.inf         |   72 +
 Maintainers.txt                               |   20 +
 .../BeagleBoardPkg/BeagleBoardPkg.dec         |   30 +
 .../BeagleBoardPkg/BeagleBoardPkg.dsc         |  496 ++
 .../BeagleBoardPkg/BeagleBoardPkg.fdf         |  308 ++
 .../BeagleBoardPkg/ConfigurationHeader.bin    |  Bin 0 -> 512 bytes
 .../BeagleBoardPkg/ConfigurationHeader.dat    |   41 +
 .../Debugger_scripts/rvi_boot_from_ram.inc    |   15 +
 .../Debugger_scripts/rvi_convert_symbols.sh   |   17 +
 .../Debugger_scripts/rvi_dummy.axf            |  Bin 0 -> 7984 bytes
 .../Debugger_scripts/rvi_hw_setup.inc         |   61 +
 .../Debugger_scripts/rvi_load_symbols.inc     |   17 +
 .../Debugger_scripts/rvi_symbols_macros.inc   |  188 +
 .../Debugger_scripts/rvi_unload_symbols.inc   |  112 +
 .../Debugger_scripts/trace32_load_symbols.cmm |  205 +
 .../trace32_load_symbols_cygwin.cmm           |  182 +
 .../BeagleBoardPkg/Include/BeagleBoard.h      |  173 +
 .../Library/BeagleBoardLib/BeagleBoard.c      |  115 +
 .../BeagleBoardLib/BeagleBoardHelper.S        |   41 +
 .../BeagleBoardLib/BeagleBoardHelper.asm      |   47 +
 .../Library/BeagleBoardLib/BeagleBoardLib.inf |   48 +
 .../Library/BeagleBoardLib/BeagleBoardMem.c   |   74 +
 .../Library/BeagleBoardLib/Clock.c            |   63 +
 .../Library/BeagleBoardLib/PadConfiguration.c |  316 ++
 .../Library/DxeHobPeCoffLib/DxeHobPeCoff.c    |  282 ++
 .../DxeHobPeCoffLib/DxeHobPeCoffLib.inf       |   39 +
 .../LzmaHobCustomDecompressLib.c              |   44 +
 .../LzmaHobCustomDecompressLib.inf            |   45 +
 .../MemoryInitPeiLib/MemoryInitPeiLib.c       |  192 +
 .../MemoryInitPeiLib/MemoryInitPeiLib.inf     |   58 +
 .../Library/ResetSystemLib/ResetSystemLib.c   |  149 +
 .../Library/ResetSystemLib/ResetSystemLib.inf |   37 +
 .../BeagleBoardPkg/PrePi/Arm/ArchPrePi.c      |   23 +
 .../PrePi/Arm/ModuleEntryPoint.S              |  124 +
 .../PrePi/Arm/ModuleEntryPoint.asm            |  142 +
 .../BeagleBoardPkg/PrePi/LzmaDecompress.h     |   97 +
 .../BeagleBoardPkg/PrePi/MainUniCore.c        |   33 +
 .../BeagleBoardPkg/PrePi/PeiUniCore.inf       |   97 +
 .../BeagleBoard/BeagleBoardPkg/PrePi/PrePi.c  |  179 +
 .../BeagleBoard/BeagleBoardPkg/PrePi/PrePi.h  |   90 +
 .../BeagleBoardPkg/Tools/GNUmakefile          |   14 +
 .../BeagleBoardPkg/Tools/generate_image.c     |  402 ++
 .../BeagleBoard/BeagleBoardPkg/Tools/makefile |   16 +
 .../BeagleBoardPkg/Tools/replace.c            |  140 +
 .../Acpi/AcpiTables/AcpiTables.inf            |   42 +
 .../Acpi/AcpiTables/Cpu0Cst/Cpu0Cst.asl       |  399 ++
 .../Acpi/AcpiTables/Cpu0Ist/Cpu0Ist.asl       |  159 +
 .../Acpi/AcpiTables/Cpu0Tst/Cpu0Tst.asl       |  133 +
 .../Acpi/AcpiTables/CpuPm/CpuPm.asl           |   73 +
 .../Acpi/AcpiTables/Dsdt/AD7298.asi           |   38 +
 .../Acpi/AcpiTables/Dsdt/ADC108S102.asi       |   33 +
 .../Acpi/AcpiTables/Dsdt/CAT24C08.asi         |   34 +
 .../Acpi/AcpiTables/Dsdt/CY8C9540A.asi        |   47 +
 .../Acpi/AcpiTables/Dsdt/GpioClient.asi       |   89 +
 .../Acpi/AcpiTables/Dsdt/LpcDev.asi           |  248 +
 .../Acpi/AcpiTables/Dsdt/PCA9685.asi          |   34 +
 .../Acpi/AcpiTables/Dsdt/PCAL9555A.asi        |   90 +
 .../Acpi/AcpiTables/Dsdt/PciHostBridge.asi    |  195 +
 .../Acpi/AcpiTables/Dsdt/PciIrq.asi           |  552 ++
 .../Acpi/AcpiTables/Dsdt/PcieExpansionPrt.asi |  127 +
 .../Acpi/AcpiTables/Dsdt/Platform.asl         |  347 ++
 .../Acpi/AcpiTables/Dsdt/QNC.asi              |   49 +
 .../Acpi/AcpiTables/Dsdt/QNCApic.asi          |   32 +
 .../Acpi/AcpiTables/Dsdt/QNCLpc.asi           |   23 +
 .../AcpiTables/Dsdt/QuarkSouthCluster.asi     |  110 +
 .../Acpi/AcpiTables/Dsdt/Tpm.asi              |   45 +
 .../Acpi/AcpiTables/Facs/Facs.aslc            |   74 +
 .../Acpi/AcpiTables/Facs/Facs.h               |   29 +
 .../Acpi/AcpiTables/Fadt/Fadt.h               |  102 +
 .../Acpi/AcpiTables/Fadt/Fadt1.0.aslc         |   76 +
 .../Acpi/AcpiTables/Fadt/Fadt2.0.aslc         |  157 +
 .../Acpi/AcpiTables/Hpet/Hpet.aslc            |   68 +
 .../Acpi/AcpiTables/Hpet/Hpet.h               |   45 +
 .../Acpi/AcpiTables/Mcfg/Mcfg.aslc            |   75 +
 .../Acpi/AcpiTables/Mcfg/Mcfg.h               |   56 +
 .../Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.c     | 1402 +++++
 .../Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.h     |  316 ++
 .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.c      |  805 +++
 .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.h      |  120 +
 .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.inf    |  196 +
 .../Acpi/Dxe/AcpiPlatform/Madt.h              |  207 +
 .../Acpi/Dxe/AcpiPlatform/MadtPlatform.c      |  300 ++
 .../BootScriptExecutorDxe.inf                 |   77 +
 .../Dxe/BootScriptExecutorDxe/IA32/S3Asm.S    |   44 +
 .../Dxe/BootScriptExecutorDxe/IA32/S3Asm.asm  |   51 +
 .../BootScriptExecutorDxe/IA32/SetIdtEntry.c  |   57 +
 .../Dxe/BootScriptExecutorDxe/ScriptExecute.c |  379 ++
 .../Dxe/BootScriptExecutorDxe/ScriptExecute.h |   70 +
 .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.c     | 1011 ++++
 .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.h     |  167 +
 .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.inf   |   78 +
 .../Acpi/DxeSmm/SmmPowerManagement/Ppm.c      |  372 ++
 .../Acpi/DxeSmm/SmmPowerManagement/Ppm.h      |  150 +
 .../SmmPowerManagement/SmmPowerManagement.c   |  113 +
 .../SmmPowerManagement/SmmPowerManagement.h   |   52 +
 .../SmmPowerManagement/SmmPowerManagement.inf |   74 +
 .../Application/ForceRecovery/ForceRecovery.c |   47 +
 .../ForceRecovery/ForceRecovery.inf           |   34 +
 .../PlatformFlashAccessLibDxe.c               |  262 +
 .../PlatformFlashAccessLibDxe.inf             |   47 +
 .../PlatformFlashAccessLib/SpiFlashDevice.c   |  330 ++
 .../PlatformFlashAccessLib/SpiFlashDevice.h   |  180 +
 .../SystemFirmwareDescriptor.aslc             |   83 +
 .../SystemFirmwareDescriptor.inf              |   40 +
 .../SystemFirmwareDescriptorPei.c             |   60 +
 .../SystemFirmwareUpdateConfig.ini            |   57 +
 .../Include/Guid/CapsuleOnDataCD.h            |   23 +
 .../Include/Guid/CapsuleOnFatFloppyDisk.h     |   23 +
 .../Include/Guid/CapsuleOnFatIdeDisk.h        |   24 +
 .../Include/Guid/CapsuleOnFatUsbDisk.h        |   24 +
 .../Include/Guid/MemoryConfigData.h           |   23 +
 .../Include/Guid/QuarkCapsuleGuid.h           |   46 +
 .../Include/Guid/QuarkVariableLock.h          |   23 +
 .../Include/Guid/SystemNvDataHobGuid.h        |   29 +
 .../Include/Library/PlatformHelperLib.h       |  266 +
 .../Include/Library/PlatformPcieHelperLib.h   |   56 +
 .../Intel/QuarkPlatformPkg/Include/Pcal9555.h |   24 +
 .../Intel/QuarkPlatformPkg/Include/Platform.h |  119 +
 .../QuarkPlatformPkg/Include/PlatformBoards.h |  166 +
 .../Include/Protocol/GlobalNvsArea.h          |   82 +
 .../Include/Protocol/PlatformSmmSpiReady.h    |   23 +
 .../PlatformBootManager.c                     |  472 ++
 .../PlatformBootManager.h                     |   49 +
 .../PlatformBootManagerLib.inf                |   83 +
 .../PlatformBootManagerLib/PlatformData.c     |  275 +
 .../Library/PlatformHelperLib/CommonHeader.h  |   51 +
 .../DxePlatformHelperLib.inf                  |   70 +
 .../PeiPlatformHelperLib.inf                  |   45 +
 .../PlatformHelperLib/PlatformHelperDxe.c     |  337 ++
 .../PlatformHelperLib/PlatformHelperLib.c     |  481 ++
 .../PlatformHelperLib/PlatformHelperPei.c     |  159 +
 .../Library/PlatformHelperLib/PlatformLeds.c  |  146 +
 .../PlatformPcieHelperLib/CommonHeader.h      |   55 +
 .../PlatformPcieHelperLib.c                   |  114 +
 .../PlatformPcieHelperLib.inf                 |   41 +
 .../Library/PlatformPcieHelperLib/SocUnit.c   |  125 +
 .../Library/PlatformSecLib/Ia32/Flat32.S      |  796 +++
 .../Library/PlatformSecLib/Ia32/Flat32.asm    |  685 +++
 .../Library/PlatformSecLib/Ia32/Platform.inc  |  134 +
 .../Library/PlatformSecLib/PlatformSecLib.c   |  207 +
 .../Library/PlatformSecLib/PlatformSecLib.inf |   54 +
 .../PlatformSecLib/PlatformSecLibModStrs.uni  |   18 +
 .../PlatformSecureLib/PlatformSecureLib.c     |  164 +
 .../PlatformSecureLib/PlatformSecureLib.inf   |   41 +
 .../Library/Tpm12DeviceLibAtmelI2c/TisPc.c    |  408 ++
 .../Tpm12DeviceLibAtmelI2c.inf                |   39 +
 .../Tpm12DeviceLibAtmelI2c.uni                |   16 +
 .../Library/Tpm12DeviceLibInfineonI2c/TisPc.c |  612 +++
 .../Tpm12DeviceLibInfineonI2c.inf             |   39 +
 .../Tpm12DeviceLibInfineonI2c.uni             |   16 +
 .../Pci/Dxe/PciHostBridge/PciHostBridge.c     | 1397 +++++
 .../Pci/Dxe/PciHostBridge/PciHostBridge.h     |  389 ++
 .../Pci/Dxe/PciHostBridge/PciHostBridge.inf   |   61 +
 .../Dxe/PciHostBridge/PciHostBridgeSupport.c  |  140 +
 .../Pci/Dxe/PciHostBridge/PciHostResource.h   |   60 +
 .../Pci/Dxe/PciHostBridge/PciRootBridge.h     |  693 +++
 .../Pci/Dxe/PciHostBridge/PciRootBridgeIo.c   | 1610 ++++++
 .../Pci/Dxe/PciPlatform/CommonHeader.h        |   31 +
 .../Pci/Dxe/PciPlatform/PciPlatform.c         |  194 +
 .../Pci/Dxe/PciPlatform/PciPlatform.h         |   82 +
 .../Pci/Dxe/PciPlatform/PciPlatform.inf       |   54 +
 .../Dxe/MemorySubClass/MemorySubClass.c       |  435 ++
 .../Dxe/MemorySubClass/MemorySubClass.h       |   65 +
 .../Dxe/MemorySubClass/MemorySubClass.inf     |   60 +
 .../MemorySubClass/MemorySubClassStrings.uni  |   29 +
 .../Dxe/PlatformInit/PlatformConfig.c         |  443 ++
 .../Dxe/PlatformInit/PlatformInitDxe.c        |   87 +
 .../Dxe/PlatformInit/PlatformInitDxe.h        |   58 +
 .../Dxe/PlatformInit/PlatformInitDxe.inf      |   56 +
 .../Dxe/SaveMemoryConfig/SaveMemoryConfig.c   |  118 +
 .../Dxe/SaveMemoryConfig/SaveMemoryConfig.inf |   44 +
 .../Platform/Dxe/Setup/CommonHeader.h         |   55 +
 .../Platform/Dxe/Setup/DxePlatform.inf        |   76 +
 .../Platform/Dxe/Setup/KeyboardLayout.c       |  262 +
 .../Platform/Dxe/Setup/QNCRegTable.c          |   80 +
 .../Platform/Dxe/Setup/SetupPlatform.c        |   97 +
 .../Platform/Dxe/Setup/SetupPlatform.h        |   71 +
 .../Platform/Dxe/Setup/Strings.uni            |   47 +
 .../Platform/Dxe/Setup/processor.c            |   40 +
 .../Platform/Dxe/SmbiosMiscDxe/CommonHeader.h |   34 +
 .../MiscBaseBoardManufacturer.uni             |   19 +
 .../MiscBaseBoardManufacturerData.c           |   45 +
 .../MiscBaseBoardManufacturerFunction.c       |  181 +
 .../Dxe/SmbiosMiscDxe/MiscBiosVendor.uni      |   18 +
 .../Dxe/SmbiosMiscDxe/MiscBiosVendorData.c    |   92 +
 .../SmbiosMiscDxe/MiscBiosVendorFunction.c    |  222 +
 .../SmbiosMiscDxe/MiscBootInformationData.c   |   24 +
 .../MiscBootInformationFunction.c             |   71 +
 .../SmbiosMiscDxe/MiscChassisManufacturer.uni |   17 +
 .../MiscChassisManufacturerData.c             |   36 +
 .../MiscChassisManufacturerFunction.c         |  168 +
 .../Dxe/SmbiosMiscDxe/MiscDevicePath.h        |   42 +
 .../MiscNumberOfInstallableLanguagesData.c    |   28 +
 ...MiscNumberOfInstallableLanguagesFunction.c |  240 +
 .../Dxe/SmbiosMiscDxe/MiscOemString.uni       |   12 +
 .../Dxe/SmbiosMiscDxe/MiscOemStringData.c     |   20 +
 .../Dxe/SmbiosMiscDxe/MiscOemStringFunction.c |   78 +
 .../Dxe/SmbiosMiscDxe/MiscOnboardDevice.uni   |   18 +
 .../Dxe/SmbiosMiscDxe/MiscOnboardDeviceData.c |   49 +
 .../SmbiosMiscDxe/MiscOnboardDeviceFunction.c |  105 +
 .../MiscPortInternalConnectorDesignator.uni   |   53 +
 .../MiscPortInternalConnectorDesignatorData.c |  184 +
 ...cPortInternalConnectorDesignatorFunction.c |  292 ++
 .../SmbiosMiscDxe/MiscSystemManufacturer.uni  |   20 +
 .../MiscSystemManufacturerData.c              |   32 +
 .../MiscSystemManufacturerFunction.c          |  198 +
 .../SmbiosMiscDxe/MiscSystemOptionString.uni  |   14 +
 .../MiscSystemOptionStringData.c              |   23 +
 .../MiscSystemOptionStringFunction.c          |   81 +
 .../MiscSystemSlotDesignation.uni             |   27 +
 .../MiscSystemSlotDesignationData.c           |  357 ++
 .../MiscSystemSlotDesignationFunction.c       |  285 ++
 .../MiscSystemSlotOnboardDevices.uni          |   23 +
 .../Platform/Dxe/SmbiosMiscDxe/SmbiosMisc.h   |  137 +
 .../Dxe/SmbiosMiscDxe/SmbiosMiscDataTable.c   |  109 +
 .../Dxe/SmbiosMiscDxe/SmbiosMiscDxe.inf       |  308 ++
 .../Dxe/SmbiosMiscDxe/SmbiosMiscEntryPoint.c  |   82 +
 .../Dxe/SmbiosMiscDxe/SmbiosMiscStrings.uni   |   26 +
 .../Pei/PlatformConfig/PlatformConfigPei.c    |   81 +
 .../Pei/PlatformConfig/PlatformConfigPei.inf  |   45 +
 .../Platform/Pei/PlatformInit/BootMode.c      |  218 +
 .../Platform/Pei/PlatformInit/CommonHeader.h  |   81 +
 .../Pei/PlatformInit/Generic/Recovery.c       |  467 ++
 .../Pei/PlatformInit/MemoryCallback.c         |  279 +
 .../Platform/Pei/PlatformInit/MrcWrapper.c    | 1565 ++++++
 .../Platform/Pei/PlatformInit/MrcWrapper.h    |  225 +
 .../Platform/Pei/PlatformInit/PeiFvSecurity.c |  111 +
 .../Platform/Pei/PlatformInit/PeiFvSecurity.h |   67 +
 .../Pei/PlatformInit/PlatformEarlyInit.c      | 1227 +++++
 .../Pei/PlatformInit/PlatformEarlyInit.h      |  301 ++
 .../Pei/PlatformInit/PlatformEarlyInit.inf    |  193 +
 .../Pei/PlatformInit/PlatformErratas.c        |  178 +
 .../Platform/SpiFvbServices/FvbInfo.c         |  332 ++
 .../Platform/SpiFvbServices/FwBlockService.c  | 2053 ++++++++
 .../Platform/SpiFvbServices/FwBlockService.h  |  308 ++
 .../Platform/SpiFvbServices/PlatformSmmSpi.c  |   31 +
 .../SpiFvbServices/PlatformSmmSpi.inf         |   80 +
 .../Platform/SpiFvbServices/PlatformSpi.inf   |   79 +
 .../Platform/SpiFvbServices/SpiFlashDevice.c  |  331 ++
 .../Platform/SpiFvbServices/SpiFlashDevice.h  |  181 +
 Platform/Intel/QuarkPlatformPkg/Quark.dsc     |  948 ++++
 Platform/Intel/QuarkPlatformPkg/Quark.fdf     |  907 ++++
 Platform/Intel/QuarkPlatformPkg/QuarkMin.dsc  |  648 +++
 Platform/Intel/QuarkPlatformPkg/QuarkMin.fdf  |  608 +++
 .../QuarkPlatformPkg/QuarkPlatformPkg.dec     |  933 ++++
 Platform/Intel/QuarkPlatformPkg/Readme.md     |  685 +++
 Platform/Intel/Vlv2TbltDevicePkg/.gitignore   |    5 +
 .../AcpiPlatform/AcpiPlatform.c               | 1338 +++++
 .../AcpiPlatform/AcpiPlatform.h               |  219 +
 .../AcpiPlatform/AcpiPlatform.inf             |   89 +
 .../AcpiPlatform/AcpiPlatformHooks.c          |  493 ++
 .../AcpiPlatform/AcpiPlatformHooks.h          |  127 +
 .../AcpiPlatform/AcpiPlatformHooksLib.h       |   91 +
 .../Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h     |   56 +
 .../FirmwareUpdate/FirmwareUpdate.c           |  922 ++++
 .../FirmwareUpdate/FirmwareUpdate.h           |  185 +
 .../FirmwareUpdate/FirmwareUpdate.inf         |   83 +
 .../FirmwareUpdate/FirmwareUpdateStrings.uni  |   45 +
 Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe   |  Bin 0 -> 499712 bytes
 Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env  |   25 +
 Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env  |   25 +
 .../Intel/Vlv2TbltDevicePkg/BiosIdx64D.env    |   25 +
 .../Intel/Vlv2TbltDevicePkg/BiosIdx64R.env    |   25 +
 .../BootScriptSaveDxe/BootScriptSaveDxe.inf   |   60 +
 .../InternalBootScriptSave.h                  |  102 +
 .../BootScriptSaveDxe/ScriptSave.c            |  626 +++
 .../Intel/Vlv2TbltDevicePkg/Build_IFWI.bat    |  200 +
 .../Intel/Vlv2TbltDevicePkg/Build_IFWI.sh     |  104 +
 Platform/Intel/Vlv2TbltDevicePkg/FCE.exe      |  Bin 0 -> 632832 bytes
 .../Capsule/GenerateCapsule/GenCapsuleAll.bat |   35 +
 .../Capsule/GenerateCapsule/GenCapsuleAll.sh  |   28 +
 .../GenerateCapsule/GenCapsuleMinnowMax.bat   |  131 +
 .../GenerateCapsule/GenCapsuleMinnowMax.sh    |   65 +
 .../GenCapsuleMinnowMaxRelease.bat            |  131 +
 .../GenCapsuleMinnowMaxRelease.sh             |   65 +
 .../GenerateCapsule/GenCapsuleSampleColor.bat |  137 +
 .../GenerateCapsule/GenCapsuleSampleColor.sh  |   70 +
 .../Feature/Capsule/GenerateCapsule/Lvfs.ddf  |   14 +
 .../LvfsGenCapsuleMinnowMax.bat               |  139 +
 .../LvfsGenCapsuleMinnowMaxRelease.bat        |  139 +
 .../LvfsGenCapsuleSampleColor.bat             |  145 +
 ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
 ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
 ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
 .../GenerateCapsule/template.metainfo.xml     |   27 +
 .../Library/FmpDeviceLib/FmpDeviceLib.c       |  589 +++
 .../Library/FmpDeviceLib/FmpDeviceLib.inf     |   46 +
 .../Library/FmpDeviceLibSample/FmpDeviceLib.c |  412 ++
 .../FmpDeviceLibSample/FmpDeviceLib.inf       |   34 +
 .../PlatformFlashAccessLib.c                  |  685 +++
 .../PlatformFlashAccessLib.inf                |   54 +
 .../SystemFirmwareDescriptor.aslc             |   83 +
 .../SystemFirmwareDescriptor.inf              |   40 +
 .../SystemFirmwareDescriptorPei.c             |   60 +
 .../SystemFirmwareUpdateConfig.ini            |   66 +
 .../SystemFirmwareUpdateConfigGcc.ini         |   66 +
 .../Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc |   55 +
 .../Vlv2TbltDevicePkg/FmpCertificate.dsc      |   22 +
 .../FmpGreenSampleDevice.dsc                  |   55 +
 .../Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc  |   59 +
 .../Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc  |   55 +
 .../FspAzaliaConfigData/AzaliaConfig.bin      |  Bin 0 -> 3708 bytes
 .../FspSupport/BootModePei/BootModePei.c      |   42 +
 .../FspSupport/BootModePei/BootModePei.inf    |   40 +
 .../FspHobProcessLibVlv2.c                    |  421 ++
 .../FspHobProcessLibVlv2.inf                  |   74 +
 .../FspPlatformSecLibVlv2.c                   |  144 +
 .../FspPlatformSecLibVlv2.inf                 |   82 +
 .../Ia32/AsmSaveSecContext.asm                |   45 +
 .../SecFspPlatformSecLibVlv2/Ia32/Fsp.inc     |   45 +
 .../Ia32/PeiCoreEntry.asm                     |  135 +
 .../Ia32/SecEntry.asm                         |  338 ++
 .../SecFspPlatformSecLibVlv2/Ia32/Stack.S     |   71 +
 .../SecFspPlatformSecLibVlv2/Ia32/Stack.asm   |   76 +
 .../SecFspPlatformSecLibVlv2/PlatformInit.c   |   36 +
 .../SecFspPlatformSecLibVlv2/SaveSecContext.c |  108 +
 .../SecGetPerformance.c                       |   83 +
 .../SecPlatformInformation.c                  |   77 +
 .../SecFspPlatformSecLibVlv2/SecRamInitData.c |   16 +
 .../SecTempRamSupport.c                       |  149 +
 .../SecFspPlatformSecLibVlv2/UartInit.c       |  192 +
 .../Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c   |   68 +
 .../Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf |   49 +
 .../Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c |  170 +
 .../FvbRuntimeDxe/FvbRuntimeDxe.inf           |   80 +
 .../FvbRuntimeDxe/FvbService.c                | 1098 ++++
 .../FvbRuntimeDxe/FvbService.h                |  182 +
 .../FvbRuntimeDxe/FvbServiceDxe.c             |  199 +
 .../FvbRuntimeDxe/FvbServiceSmm.c             |  127 +
 .../FvbRuntimeDxe/FvbSmm.inf                  |   82 +
 .../FvbRuntimeDxe/FvbSmmCommon.h              |   73 +
 .../FvbRuntimeDxe/FvbSmmDxe.c                 |  944 ++++
 .../FvbRuntimeDxe/FvbSmmDxe.h                 |  232 +
 .../FvbRuntimeDxe/FvbSmmDxe.inf               |   50 +
 Platform/Intel/Vlv2TbltDevicePkg/GenBiosId    |  Bin 0 -> 12236 bytes
 .../Intel/Vlv2TbltDevicePkg/GenBiosId.exe     |  Bin 0 -> 384000 bytes
 .../Include/AlertStandardFormatTable.h        |  122 +
 .../Vlv2TbltDevicePkg/Include/ChipsetAccess.h |   28 +
 .../Include/CommonIncludes.h                  |  115 +
 .../Intel/Vlv2TbltDevicePkg/Include/CpuType.h |   59 +
 .../Vlv2TbltDevicePkg/Include/FileHandleLib.h |  499 ++
 .../Include/Guid/AcpiTableStorage.h           |   30 +
 .../Include/Guid/AlertStandardFormat.h        |   86 +
 .../Vlv2TbltDevicePkg/Include/Guid/BiosId.h   |   30 +
 .../Include/Guid/BoardFeatures.h              |  214 +
 .../Include/Guid/EfiVpdData.h                 |  156 +
 .../Include/Guid/FirmwareId.h                 |   61 +
 .../Include/Guid/HwWatchdogTimerHob.h         |  134 +
 .../Vlv2TbltDevicePkg/Include/Guid/IdccData.h |  104 +
 .../Vlv2TbltDevicePkg/Include/Guid/ItkData.h  |   70 +
 .../Include/Guid/MemoryConfigData.h           |   32 +
 .../Include/Guid/OsSelection.h                |   85 +
 .../Include/Guid/PciLanInfo.h                 |   39 +
 .../Include/Guid/PlatformCpuInfo.h            |  180 +
 .../Include/Guid/PlatformInfo.h               |  433 ++
 .../Include/Guid/SensorInfoVariable.h         |  279 +
 .../Include/Guid/SetupVariable.h              | 1344 +++++
 .../Intel/Vlv2TbltDevicePkg/Include/Hpet.h    |   40 +
 .../Include/Library/BiosIdLib.h               |  104 +
 .../Include/Library/CpuIA32.h                 |  345 ++
 .../Include/Library/EfiRegTableLib.h          |  196 +
 .../Vlv2TbltDevicePkg/Include/Library/Esrt.h  |   74 +
 .../Vlv2TbltDevicePkg/Include/Library/Fd.h    |  264 +
 .../Include/Library/FlashDeviceLib.h          |  122 +
 .../Include/Library/I2CLib.h                  |   58 +
 .../Include/Library/I2cMmioConfigLib.h        |   23 +
 .../Include/Library/I2cPort_platform.h        |   26 +
 .../Include/Library/PlatformFsaLib.h          |   50 +
 .../Include/Library/PlatformFspLib.h          |   23 +
 .../Include/Library/SpiFlash.H                |  239 +
 .../Include/Library/StallSmmLib.h             |   40 +
 .../Include/Library/UsbDeviceModeLib.h        |  181 +
 .../Intel/Vlv2TbltDevicePkg/Include/Mcfg.h    |   69 +
 .../Vlv2TbltDevicePkg/Include/McfgTable.h     |   65 +
 .../Vlv2TbltDevicePkg/Include/Platform.h      |  133 +
 .../Include/PlatformBootMode.h                |   35 +
 .../Include/PlatformDefinitions.h             |   43 +
 .../Include/Ppi/MfgMemoryTest.h               |   42 +
 .../Include/Ppi/Sha256Hash.h                  |  131 +
 .../Vlv2TbltDevicePkg/Include/Ppi/Speaker.h   |   65 +
 .../Include/Ppi/UsbController.h               |   85 +
 .../Include/Protocol/CK505ClockPlatformInfo.h |  126 +
 .../Include/Protocol/EnhancedSpeedstep.h      |   76 +
 .../Include/Protocol/GlobalNvsArea.h          |  475 ++
 .../Include/Protocol/HwWatchdogTimer.h        |  235 +
 .../Include/Protocol/I2cAcpi.h                |  107 +
 .../Include/Protocol/I2cBus.h                 |  164 +
 .../Include/Protocol/I2cBusMcg.h              |  163 +
 .../Include/Protocol/I2cHostMcg.h             |  138 +
 .../Include/Protocol/I2cMasterMcg.h           |  519 ++
 .../Include/Protocol/I2cSlave.h               |  194 +
 .../Include/Protocol/LpcWpc83627Policy.h      |   92 +
 .../Include/Protocol/LpcWpce791Policy.h       |   55 +
 .../Include/Protocol/MmioDevice.h             |   84 +
 .../Include/Protocol/Observable.h             |  186 +
 .../Include/Protocol/PlatformGopPolicy.h      |   68 +
 .../Include/Protocol/PlatformIdeInit.h        |   43 +
 .../Include/Protocol/SetupMode.h              |   79 +
 .../Include/Protocol/SmbiosSlotPopulation.h   |   47 +
 .../Include/Protocol/Speaker.h                |   65 +
 .../Include/Protocol/TcoReset.h               |   67 +
 .../Include/Protocol/TpmMp.h                  |  136 +
 .../Include/Protocol/UsbPolicy.h              |  126 +
 .../Include/Protocol/VlvPlatformPolicy.h      |  102 +
 .../Vlv2TbltDevicePkg/Include/SetupMode.h     |   85 +
 .../IntelGopDepex/IntelGopDriver.depex        |    1 +
 .../Library/BiosIdLib/BiosIdLib.c             |  337 ++
 .../Library/BiosIdLib/BiosIdLib.inf           |   50 +
 .../Library/CpuIA32Lib/CpuIA32Lib.inf         |   41 +
 .../Library/CpuIA32Lib/EfiCpuVersion.c        |   70 +
 .../Library/CpuIA32Lib/IA32/CpuIA32.S         |  223 +
 .../Library/CpuIA32Lib/IA32/CpuIA32.asm       |  206 +
 .../Library/CpuIA32Lib/IA32/CpuIA32.c         |  177 +
 .../Library/CpuIA32Lib/X64/Cpu.S              |  207 +
 .../Library/CpuIA32Lib/X64/Cpu.asm            |  222 +
 .../Library/EfiRegTableLib/EfiRegTableLib.c   |  282 ++
 .../Library/EfiRegTableLib/EfiRegTableLib.inf |   47 +
 .../Library/FlashDeviceLib/FlashDeviceLib.c   |  461 ++
 .../Library/FlashDeviceLib/FlashDeviceLib.inf |   44 +
 .../FlashDeviceLib/FlashDeviceLibDxe.c        |   56 +
 .../FlashDeviceLib/FlashDeviceLibDxe.inf      |   43 +
 .../FlashDeviceLibDxeRuntimeSmm.c             |  173 +
 .../FlashDeviceLib/SpiChipDefinitions.h       |  835 +++
 .../Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c |   46 +
 .../Library/I2CLib/I2CLibNull.inf             |   39 +
 .../Library/I2CLibDxe/I2CLib.c                |  735 +++
 .../Library/I2CLibDxe/I2CLibDxe.inf           |   39 +
 .../Library/I2CLibDxe/I2CRegs.h               |  126 +
 .../Library/I2CLibPei/I2CAccess.h             |   44 +
 .../Library/I2CLibPei/I2CDelayPei.c           |   46 +
 .../Library/I2CLibPei/I2CDelayPei.h           |   30 +
 .../Library/I2CLibPei/I2CIoLibPei.c           |  178 +
 .../Library/I2CLibPei/I2CIoLibPei.h           |  153 +
 .../Library/I2CLibPei/I2CLibPei.c             |  638 +++
 .../Library/I2CLibPei/I2CLibPei.h             |  280 +
 .../Library/I2CLibPei/I2CLibPei.inf           |   40 +
 .../IntelPchAcpiTimerLib/CommonHeader.h       |   27 +
 .../IntelPchAcpiTimerLib.c                    |  255 +
 .../IntelPchAcpiTimerLib.inf                  |   51 +
 .../BoardClkGens/BoardClkGens.c               |  430 ++
 .../BoardClkGens/BoardClkGens.h               |  255 +
 .../MultiPlatformLib/BoardGpios/BoardGpios.c  |  531 ++
 .../MultiPlatformLib/BoardGpios/BoardGpios.h  |  324 ++
 .../BoardJumpers/BoardJumpers.c               |   30 +
 .../BoardJumpers/BoardJumpers.h               |   30 +
 .../BoardOemIds/BoardOemIds.c                 |   43 +
 .../BoardOemIds/BoardOemIds.h                 |   29 +
 .../BoardSsidSvid/BoardSsidSvid.c             |   38 +
 .../BoardSsidSvid/BoardSsidSvid.h             |   35 +
 .../MultiPlatformLib/MultiPlatformLib.c       |  120 +
 .../MultiPlatformLib/MultiPlatformLib.h       |   89 +
 .../MultiPlatformLib/MultiPlatformLib.inf     |   77 +
 .../MultiPlatformLib/PlatformInfoHob.c        |   54 +
 .../Library/PchPlatformLib/PchPlatformLib.inf |   50 +
 .../PchPlatformLib/PchPlatformLibrary.c       |  131 +
 .../PchPlatformLib/PchPlatformLibrary.h       |   35 +
 .../Library/PchSmmLib/CommonHeader.h          |   32 +
 .../Library/PchSmmLib/PchSmmLib.c             |  157 +
 .../Library/PchSmmLib/PchSmmLib.inf           |   46 +
 .../Library/PlatformBdsLib/BdsPlatform.c      | 3098 ++++++++++++
 .../Library/PlatformBdsLib/BdsPlatform.h      |  516 ++
 .../Library/PlatformBdsLib/PlatformBdsLib.inf |  127 +
 .../PlatformBdsLib/PlatformBdsStrings.uni     |   30 +
 .../Library/PlatformBdsLib/PlatformData.c     |  306 ++
 .../Library/PlatformCmosLib/PlatformCmosLib.c |  106 +
 .../PlatformCmosLib/PlatformCmosLib.inf       |   30 +
 .../Library/PlatformFspLib/PlatformFspLib.c   |   44 +
 .../Library/PlatformFspLib/PlatformFspLib.inf |   49 +
 .../Library/ResetSystemLib/ResetSystemLib.c   |  235 +
 .../Library/ResetSystemLib/ResetSystemLib.inf |   47 +
 .../SerialPortLib/PlatformSerialPortLib.h     |   53 +
 .../Library/SerialPortLib/SerialPortLib.c     |  246 +
 .../Library/SerialPortLib/SerialPortLib.inf   |   52 +
 .../Library/SerialPortLib/SioInit.c           |  127 +
 .../Library/SerialPortLib/SioInit.h           |   62 +
 .../Library/SmbusLib/CommonHeader.h           |   26 +
 .../Library/SmbusLib/SmbusLib.c               |  873 ++++
 .../Library/SmbusLib/SmbusLib.inf             |   46 +
 .../Library/StallSmmLib/StallSmm.c            |   89 +
 .../Library/StallSmmLib/StallSmmLib.inf       |   51 +
 .../Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.c    |  117 +
 .../Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.inf  |   61 +
 .../Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.c    |  145 +
 .../Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.inf  |   60 +
 .../Intel/Vlv2TbltDevicePkg/Logo/Logo.bmp     |  Bin 0 -> 94434 bytes
 .../Metronome/LegacyMetronome.c               |  185 +
 .../Metronome/LegacyMetronome.h               |   64 +
 .../Vlv2TbltDevicePkg/Metronome/Metronome.inf |   49 +
 .../MonoStatusCode/EfiStatusCode.h            |  178 +
 .../MonoStatusCode/MonoStatusCode.c           |  132 +
 .../MonoStatusCode/MonoStatusCode.h           |  128 +
 .../MonoStatusCode/MonoStatusCode.inf         |   72 +
 .../MonoStatusCode/PeiPostCode.c              |  121 +
 .../MonoStatusCode/PlatformStatusCode.c       |  381 ++
 .../MonoStatusCode/PlatformStatusCode.h       |  138 +
 .../Library/GenericBdsLib/BdsBoot.c           | 4490 +++++++++++++++++
 .../Library/GenericBdsLib/BdsConnect.c        |  429 ++
 .../Library/GenericBdsLib/BdsConsole.c        | 1061 ++++
 .../Library/GenericBdsLib/BdsMisc.c           | 1575 ++++++
 .../Library/GenericBdsLib/DevicePath.c        |   27 +
 .../Library/GenericBdsLib/GenericBdsLib.inf   |  142 +
 .../Library/GenericBdsLib/GenericBdsLib.uni   |   19 +
 .../GenericBdsLib/GenericBdsStrings.uni       |   30 +
 .../Library/GenericBdsLib/InternalBdsLib.h    |  173 +
 .../Library/GenericBdsLib/String.c            |   26 +
 .../Library/GenericBdsLib/String.h            |   42 +
 .../PciPlatform/BoardPciPlatform.c            |   55 +
 .../PciPlatform/PciPlatform.c                 |  367 ++
 .../PciPlatform/PciPlatform.h                 |   83 +
 .../PciPlatform/PciPlatform.inf               |   65 +
 .../Vlv2TbltDevicePkg/PlatformCapsule.dsc     |   39 +
 .../Vlv2TbltDevicePkg/PlatformCapsule.fdf     |   52 +
 .../Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc  |   38 +
 .../Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf  |   52 +
 .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.c   |   60 +
 .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.h   |   29 +
 .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf |   55 +
 .../PlatformDxe/AzaliaVerbTable.h             |  247 +
 .../Vlv2TbltDevicePkg/PlatformDxe/BoardId.c   |  223 +
 .../PlatformDxe/BoardIdDecode.c               |  129 +
 .../PlatformDxe/BoardIdDecode.h               |   61 +
 .../PlatformDxe/ClockControl.c                |  202 +
 .../PlatformDxe/Configuration.h               |  692 +++
 .../Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c |   89 +
 .../PlatformDxe/IchPlatformPolicy.c           |  484 ++
 .../PlatformDxe/IchRegTable.c                 |  134 +
 .../PlatformDxe/IchTcoReset.c                 |  211 +
 .../Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c  |   72 +
 .../PlatformDxe/LegacySpeaker.c               |  161 +
 .../PlatformDxe/LegacySpeaker.h               |   69 +
 .../PlatformDxe/Observable/Observable.c       |  582 +++
 .../PlatformDxe/Observable/Observable.h       |  137 +
 .../Vlv2TbltDevicePkg/PlatformDxe/PciBus.h    |  379 ++
 .../Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c |  506 ++
 .../Vlv2TbltDevicePkg/PlatformDxe/Platform.c  | 1820 +++++++
 .../PlatformDxe/PlatformDxe.h                 |  722 +++
 .../PlatformDxe/PlatformDxe.inf               |  149 +
 .../Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c |  154 +
 .../Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c |  112 +
 .../PlatformDxe/SioPlatformPolicy.c           |   82 +
 .../PlatformDxe/SlotConfig.c                  |  148 +
 .../PlatformDxe/SlotConfig.h                  |   80 +
 .../PlatformGopPolicy/PlatformGopPolicy.c     |  201 +
 .../PlatformGopPolicy/PlatformGopPolicy.inf   |   51 +
 .../PlatformInfoDxe/PlatformInfoDxe.c         |  169 +
 .../PlatformInfoDxe/PlatformInfoDxe.h         |   30 +
 .../PlatformInfoDxe/PlatformInfoDxe.inf       |   52 +
 .../PlatformInitPei/BootMode.c                |  434 ++
 .../PlatformInitPei/CpuInitPeim.c             |   44 +
 .../Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c  |  319 ++
 .../PlatformInitPei/FlashMap.c                |  143 +
 .../PlatformInitPei/LegacySpeaker.c           |  168 +
 .../PlatformInitPei/LegacySpeaker.h           |   71 +
 .../PlatformInitPei/MchInit.c                 |   72 +
 .../PlatformInitPei/MemoryCallback.c          |  338 ++
 .../PlatformInitPei/MemoryPeim.c              |  408 ++
 .../PlatformInitPei/PchInitPeim.c             |  808 +++
 .../PlatformInitPei/PlatformEarlyInit.c       | 1195 +++++
 .../PlatformInitPei/PlatformEarlyInit.h       | 1499 ++++++
 .../PlatformInitPei/PlatformInfoInit.c        |  181 +
 .../PlatformInitPei/PlatformInitPei.inf       |  117 +
 .../PlatformInitPei/PlatformSsaInitPeim.c     |   58 +
 .../PlatformInitPei/Recovery.c                |  361 ++
 .../Vlv2TbltDevicePkg/PlatformInitPei/Stall.c |   91 +
 .../Vlv2TbltDevicePkg/PlatformPei/BootMode.c  |  346 ++
 .../PlatformPei/CommonHeader.h                |   60 +
 .../PlatformPei/MemoryCallback.c              |  154 +
 .../Vlv2TbltDevicePkg/PlatformPei/Platform.c  | 1198 +++++
 .../Vlv2TbltDevicePkg/PlatformPei/Platform.h  |  213 +
 .../PlatformPei/PlatformPei.inf               |  129 +
 .../Vlv2TbltDevicePkg/PlatformPei/Stall.c     |   90 +
 .../Intel/Vlv2TbltDevicePkg/PlatformPkg.dec   |  211 +
 .../Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf   | 1073 ++++
 .../Vlv2TbltDevicePkg/PlatformPkgConfig.dsc   |  107 +
 .../Vlv2TbltDevicePkg/PlatformPkgGcc.fdf      | 1033 ++++
 .../Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc   | 1711 +++++++
 .../Vlv2TbltDevicePkg/PlatformPkgIA32.dsc     | 1699 +++++++
 .../Vlv2TbltDevicePkg/PlatformPkgX64.dsc      | 1714 +++++++
 .../PlatformSetupDxe/Boot.vfi                 |   72 +
 .../PlatformSetupDxe/Configuration.h          |   56 +
 .../PlatformSetupDxe/DebugConfig.vfi          |  118 +
 .../PlatformSetupDxe/FwVersionStrings.uni     |   40 +
 .../PlatformSetupDxe/Main.vfi                 |  331 ++
 .../PlatformSetupDxe/PlatformSetupDxe.c       |  929 ++++
 .../PlatformSetupDxe/PlatformSetupDxe.h       |   97 +
 .../PlatformSetupDxe/PlatformSetupDxe.inf     |  141 +
 .../PlatformSetupDxe/Security.vfi             |  104 +
 .../PlatformSetupDxe/SetupFunctions.c         |   85 +
 .../PlatformSetupDxe/SetupInfoRecords.c       | 1855 +++++++
 .../PlatformSetupDxe/SouthClusterConfig.vfi   |  933 ++++
 .../PlatformSetupDxe/SystemComponent.vfi      |   81 +
 .../PlatformSetupDxe/Thermal.vfi              |  106 +
 .../PlatformSetupDxe/UnCore.vfi               |  235 +
 .../PlatformSetupDxe/UqiList.uni              |  452 ++
 .../PlatformSetupDxe/Vfr.vfr                  |  123 +
 .../PlatformSetupDxe/VfrStrings.uni           | 1417 ++++++
 .../Vlv2TbltDevicePkg/PlatformSmm/Platform.c  |  997 ++++
 .../PlatformSmm/PlatformSmm.inf               |   93 +
 .../Vlv2TbltDevicePkg/PlatformSmm/S3Save.c    |  377 ++
 .../PlatformSmm/SmmPlatform.h                 |  240 +
 .../PlatformSmm/SmmScriptSave.c               |  252 +
 .../PlatformSmm/SmmScriptSave.h               |   50 +
 .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c   |  148 +
 .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h   |   36 +
 .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf |   49 +
 Platform/Intel/Vlv2TbltDevicePkg/Readme.md    |  233 +
 .../SaveMemoryConfig/SaveMemoryConfig.c       |  181 +
 .../SaveMemoryConfig/SaveMemoryConfig.h       |   66 +
 .../SaveMemoryConfig/SaveMemoryConfig.inf     |   60 +
 .../SmBiosMiscDxe/CommonHeader.h              |   39 +
 .../MiscBaseBoardManufacturer.uni             |   33 +
 .../MiscBaseBoardManufacturerData.c           |   58 +
 .../MiscBaseBoardManufacturerFunction.c       |  238 +
 .../SmBiosMiscDxe/MiscBiosVendor.uni          |   26 +
 .../SmBiosMiscDxe/MiscBiosVendorData.c        |  101 +
 .../SmBiosMiscDxe/MiscBiosVendorFunction.c    |  336 ++
 .../SmBiosMiscDxe/MiscBootInformationData.c   |   34 +
 .../MiscBootInformationFunction.c             |   82 +
 .../SmBiosMiscDxe/MiscChassisManufacturer.uni |   28 +
 .../MiscChassisManufacturerData.c             |   57 +
 .../MiscChassisManufacturerFunction.c         |  158 +
 .../SmBiosMiscDxe/MiscMemoryDevice.uni        |   35 +
 .../SmBiosMiscDxe/MiscMemoryDeviceData.c      |   45 +
 .../SmBiosMiscDxe/MiscMemoryDeviceFunction.c  |  319 ++
 .../MiscNumberOfInstallableLanguagesData.c    |   38 +
 ...MiscNumberOfInstallableLanguagesFunction.c |  251 +
 .../SmBiosMiscDxe/MiscOemString.uni           |   25 +
 .../SmBiosMiscDxe/MiscOemStringData.c         |   34 +
 .../SmBiosMiscDxe/MiscOemStringFunction.c     |   89 +
 .../SmBiosMiscDxe/MiscOemType0x90.uni         |   31 +
 .../SmBiosMiscDxe/MiscOemType0x90Data.c       |   36 +
 .../SmBiosMiscDxe/MiscOemType0x90Function.c   |  442 ++
 .../SmBiosMiscDxe/MiscOemType0x94.uni         |   42 +
 .../SmBiosMiscDxe/MiscOemType0x94Data.c       |   54 +
 .../SmBiosMiscDxe/MiscOemType0x94Function.c   | 1218 +++++
 .../SmBiosMiscDxe/MiscOnboardDevice.uni       |   26 +
 .../SmBiosMiscDxe/MiscOnboardDeviceData.c     |   48 +
 .../SmBiosMiscDxe/MiscOnboardDeviceFunction.c |  135 +
 .../SmBiosMiscDxe/MiscPhysicalArray.uni       |   25 +
 .../SmBiosMiscDxe/MiscPhysicalArrayData.c     |   38 +
 .../SmBiosMiscDxe/MiscPhysicalArrayFunction.c |  101 +
 .../MiscPortInternalConnectorDesignator.uni   |   31 +
 .../MiscPortInternalConnectorDesignatorData.c |   56 +
 ...cPortInternalConnectorDesignatorFunction.c |  152 +
 .../SmBiosMiscDxe/MiscProcessorCache.uni      |   22 +
 .../SmBiosMiscDxe/MiscProcessorCacheData.c    |   33 +
 .../MiscProcessorCacheFunction.c              |  189 +
 .../MiscProcessorInformation.uni              |   27 +
 .../MiscProcessorInformationData.c            |   71 +
 .../MiscProcessorInformationFunction.c        |  448 ++
 .../SmBiosMiscDxe/MiscResetCapabilitiesData.c |   43 +
 .../MiscResetCapabilitiesFunction.c           |   85 +
 .../SmBiosMiscDxe/MiscSubclassDriver.h        |  188 +
 .../SmBiosMiscDxe/MiscSubclassDriver.uni      |   35 +
 .../MiscSubclassDriverDataTable.c             |   98 +
 .../MiscSubclassDriverEntryPoint.c            |  182 +
 .../MiscSystemLanguageString.uni              |   24 +
 .../MiscSystemLanguageStringData.c            |   34 +
 .../MiscSystemLanguageStringFunction.c        |   93 +
 .../SmBiosMiscDxe/MiscSystemManufacturer.uni  |   30 +
 .../MiscSystemManufacturerData.c              |   48 +
 .../MiscSystemManufacturerFunction.c          |  364 ++
 .../SmBiosMiscDxe/MiscSystemOptionString.uni  |   24 +
 .../MiscSystemOptionStringData.c              |   31 +
 .../MiscSystemOptionStringFunction.c          |   93 +
 .../MiscSystemSlotDesignation.uni             |   34 +
 .../MiscSystemSlotDesignationData.c           |  246 +
 .../MiscSystemSlotDesignationFunction.c       |  127 +
 .../SmBiosMiscDxe/SmBiosMiscDxe.inf           |  139 +
 .../SmmSwDispatch2OnSmmSwDispatchThunk.c      |  459 ++
 .../SmmSwDispatch2OnSmmSwDispatchThunk.inf    |   54 +
 .../SmramSaveInfoHandlerSmm.c                 |  164 +
 .../SmramSaveInfoHandlerSmm.inf               |   60 +
 .../Stitch/Gcc/NvStorageFtwSpare.bin          |  Bin 0 -> 262144 bytes
 .../Stitch/Gcc/NvStorageFtwWorking.bin        |  Bin 0 -> 8192 bytes
 .../Stitch/Gcc/NvStorageVariable.bin          |  Bin 0 -> 253952 bytes
 .../Stitch/IFWIHeader/IFWI_HEADER.bin         |  Bin 0 -> 4096 bytes
 .../Stitch/IFWIHeader/IFWI_HEADER_SPILOCK.bin |  Bin 0 -> 4096 bytes
 .../Stitch/IFWIHeader/Vacant.bin              |  Bin 0 -> 3928064 bytes
 .../Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat   |  270 +
 .../Stitch/MNW2_Stitch_Config.txt             |   10 +
 .../Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c |   33 +
 .../Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf   |   32 +
 .../VlvPlatformInitDxe/IgdOpRegion.c          |  929 ++++
 .../VlvPlatformInitDxe/IgdOpRegion.h          |  235 +
 .../VlvPlatformInitDxe/VlvPlatformInit.c      |  287 ++
 .../VlvPlatformInitDxe/VlvPlatformInit.h      |   65 +
 .../VlvPlatformInitDxe/VlvPlatformInitDxe.inf |   74 +
 .../Vlv2TbltDevicePkg/Wpce791/LpcDriver.c     |  340 ++
 .../Vlv2TbltDevicePkg/Wpce791/LpcDriver.h     |  112 +
 .../Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c    |  366 ++
 .../Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h    |  103 +
 .../Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c  |  126 +
 .../Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h  |  101 +
 .../Vlv2TbltDevicePkg/Wpce791/Wpce791.inf     |   63 +
 Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat  |  332 ++
 Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh   |  256 +
 Platform/Intel/Vlv2TbltDevicePkg/cln.sh       |   62 +
 Readme.md                                     |    9 +
 .../Include/DdrMemoryController.h             |  251 +
 .../QuarkNorthCluster/Include/IntelQNCBase.h  |   17 +
 .../Include/IntelQNCConfig.h                  |  100 +
 .../QuarkNorthCluster/Include/IntelQNCDxe.h   |   17 +
 .../QuarkNorthCluster/Include/IntelQNCPeim.h  |   17 +
 .../QuarkNorthCluster/Include/IntelQNCRegs.h  |   48 +
 .../Include/Library/IntelQNCLib.h             |  284 ++
 .../Include/Library/QNCAccessLib.h            |  161 +
 .../Include/Library/QNCSmmLib.h               |   57 +
 .../Include/Ppi/QNCMemoryInit.h               |   36 +
 .../Include/Protocol/PchInfo.h                |   48 +
 .../Include/Protocol/PlatformPolicy.h         |   31 +
 .../Include/Protocol/QncS3Support.h           |   84 +
 .../Include/Protocol/SmmIchnDispatch2.h       |  115 +
 .../QuarkNorthCluster/Include/Protocol/Spi.h  |  345 ++
 .../QuarkNorthCluster/Include/QNCAccess.h     |  177 +
 .../Include/QNCCommonDefinitions.h            |  350 ++
 .../QuarkNorthCluster/Include/QuarkNcSocId.h  |  751 +++
 .../Library/IntelQNCLib/CommonHeader.h        |   32 +
 .../Library/IntelQNCLib/IntelQNCLib.c         |  771 +++
 .../Library/IntelQNCLib/IntelQNCLib.inf       |   57 +
 .../Library/IntelQNCLib/PciExpress.c          |  932 ++++
 .../Library/MtrrLib/MtrrLib.c                 | 2112 ++++++++
 .../Library/MtrrLib/MtrrLib.inf               |   42 +
 .../Library/MtrrLib/MtrrLib.uni               |   18 +
 .../Library/QNCAccessLib/BaseAccess.c         |   28 +
 .../Library/QNCAccessLib/QNCAccessLib.c       |  327 ++
 .../Library/QNCAccessLib/QNCAccessLib.inf     |   37 +
 .../Library/QNCAccessLib/RuntimeAccess.c      |  142 +
 .../QNCAccessLib/RuntimeQNCAccessLib.inf      |   43 +
 .../Library/QNCSmmLib/QNCSmmLib.c             |  313 ++
 .../Library/QNCSmmLib/QNCSmmLib.inf           |   44 +
 .../Library/ResetSystemLib/ResetSystemLib.c   |  379 ++
 .../Library/ResetSystemLib/ResetSystemLib.inf |   46 +
 .../Library/SmbusLib/CommonHeader.h           |   25 +
 .../Library/SmbusLib/SmbusLib.c               |  797 +++
 .../Library/SmbusLib/SmbusLib.inf             |   47 +
 .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.c     |  446 ++
 .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf   |   30 +
 .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.uni   |   12 +
 .../MemoryInit/Pei/MemoryInit.c               |   59 +
 .../MemoryInit/Pei/MemoryInit.h               |   35 +
 .../MemoryInit/Pei/MemoryInitPei.inf          |   70 +
 .../MemoryInit/Pei/core_types.h               |   43 +
 .../MemoryInit/Pei/gen5_iosf_sb_definitions.h |  738 +++
 .../MemoryInit/Pei/general_definitions.h      |   84 +
 .../QuarkNorthCluster/MemoryInit/Pei/hte.c    |  536 ++
 .../QuarkNorthCluster/MemoryInit/Pei/hte.h    |   66 +
 .../QuarkNorthCluster/MemoryInit/Pei/io.h     |  132 +
 .../QuarkNorthCluster/MemoryInit/Pei/lprint.c |  382 ++
 .../MemoryInit/Pei/meminit.c                  | 2638 ++++++++++
 .../MemoryInit/Pei/meminit.h                  |   22 +
 .../MemoryInit/Pei/meminit_utils.c            | 1574 ++++++
 .../MemoryInit/Pei/meminit_utils.h            |   95 +
 .../MemoryInit/Pei/memory_options.h           |   77 +
 .../QuarkNorthCluster/MemoryInit/Pei/mrc.c    |   40 +
 .../QuarkNorthCluster/MemoryInit/Pei/mrc.h    |  160 +
 .../MemoryInit/Pei/platform.c                 |  186 +
 .../MemoryInit/Pei/prememinit.c               |  187 +
 .../MemoryInit/Pei/prememinit.h               |   15 +
 .../QNCInit/Dxe/CommonHeader.h                |   49 +
 .../QNCInit/Dxe/DxeQNCSmbus.c                 |  612 +++
 .../QNCInit/Dxe/DxeQNCSmbus.h                 |  205 +
 .../QNCInit/Dxe/LegacyRegion.c                |  237 +
 .../QNCInit/Dxe/LegacyRegion.h                |  198 +
 .../QuarkNorthCluster/QNCInit/Dxe/QNCInit.c   |  518 ++
 .../QuarkNorthCluster/QNCInit/Dxe/QNCInit.h   |   49 +
 .../QNCInit/Dxe/QNCInitDxe.inf                |   92 +
 .../QNCInit/Dxe/QNCRootPorts.c                |   76 +
 .../QuarkNorthCluster/QNCInit/Dxe/QNCSmbus.h  |   80 +
 .../QNCInit/Dxe/QNCSmbusExec.c                |  246 +
 .../S3Support/Dxe/QncS3Support.c              |  417 ++
 .../S3Support/Dxe/QncS3Support.h              |  117 +
 .../S3Support/Dxe/QncS3Support.inf            |   64 +
 .../Smm/Dxe/SmmAccessDxe/SmmAccess.inf        |   49 +
 .../Smm/Dxe/SmmAccessDxe/SmmAccessDriver.c    |  405 ++
 .../Smm/Dxe/SmmAccessDxe/SmmAccessDriver.h    |  230 +
 .../Smm/Dxe/SmmControlDxe/SmmControlDriver.c  |  358 ++
 .../Smm/Dxe/SmmControlDxe/SmmControlDxe.inf   |   55 +
 .../DxeSmm/QncSmmDispatcher/CommonHeader.h    |   45 +
 .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmGpi.c   |   32 +
 .../QncSmmDispatcher/QNC/QNCSmmHelpers.c      |  549 ++
 .../QNC/QNCSmmPeriodicTimer.c                 |  424 ++
 .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmQncn.c  |  211 +
 .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmSw.c    |   90 +
 .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmSx.c    |  147 +
 .../Smm/DxeSmm/QncSmmDispatcher/QNCSmm.h      |  868 ++++
 .../Smm/DxeSmm/QncSmmDispatcher/QNCSmmCore.c  |  825 +++
 .../QncSmmDispatcher/QNCSmmDispatcher.inf     |   81 +
 .../DxeSmm/QncSmmDispatcher/QNCSmmHelpers.c   |  367 ++
 .../DxeSmm/QncSmmDispatcher/QNCSmmHelpers.h   |  219 +
 .../DxeSmm/QncSmmDispatcher/QNCSmmRegisters.h |   13 +
 .../DxeSmm/QncSmmDispatcher/QNCxSmmHelpers.h  |  178 +
 .../Smm/Pei/SmmAccessPei/SmmAccessPei.c       |  376 ++
 .../Smm/Pei/SmmAccessPei/SmmAccessPei.inf     |   45 +
 .../Smm/Pei/SmmControlPei/SmmControlPei.c     |  274 +
 .../Smm/Pei/SmmControlPei/SmmControlPei.inf   |   51 +
 .../QuarkNorthCluster/Spi/Common/SpiCommon.c  |  927 ++++
 .../QuarkNorthCluster/Spi/Common/SpiCommon.h  |  317 ++
 .../QuarkNorthCluster/Spi/PchSpiRuntime.inf   |   84 +
 .../QuarkNorthCluster/Spi/PchSpiSmm.inf       |   50 +
 .../QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.c |  205 +
 .../QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.h |   79 +
 .../QuarkNorthCluster/Spi/Smm/PchSpi.c        |  123 +
 .../QuarkNorthCluster/Spi/Smm/PchSpi.h        |   47 +
 Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dec     |  234 +
 Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dsc     |  254 +
 .../QuarkSouthCluster/Include/CEATA.h         |  114 +
 .../QuarkSouthCluster/Include/I2cRegs.h       |   95 +
 .../QuarkSouthCluster/Include/Ioh.h           |  248 +
 .../QuarkSouthCluster/Include/IohAccess.h     |   18 +
 .../Include/IohCommonDefinitions.h            |  342 ++
 .../Include/Library/I2cLib.h                  |  152 +
 .../Include/Library/IohLib.h                  |   36 +
 .../QuarkSouthCluster/Include/MMC.h           |  274 +
 .../QuarkSouthCluster/Include/SDCard.h        |  146 +
 .../QuarkSouthCluster/Include/SDHostIo.h      |  333 ++
 .../IohInit/Dxe/CommonHeader.h                |   55 +
 .../QuarkSouthCluster/IohInit/Dxe/IohBds.h    |   83 +
 .../QuarkSouthCluster/IohInit/Dxe/IohData.c   |   42 +
 .../QuarkSouthCluster/IohInit/Dxe/IohInit.c   |   37 +
 .../IohInit/Dxe/IohInitDxe.inf                |   76 +
 .../Library/I2cLib/CommonHeader.h             |  214 +
 .../QuarkSouthCluster/Library/I2cLib/I2cLib.c |  998 ++++
 .../Library/I2cLib/I2cLib.inf                 |   62 +
 .../Library/IohLib/CommonHeader.h             |   29 +
 .../QuarkSouthCluster/Library/IohLib/IohLib.c |   99 +
 .../Library/IohLib/IohLib.inf                 |   49 +
 .../Sdio/Dxe/SDControllerDxe/ComponentName.c  |  227 +
 .../Sdio/Dxe/SDControllerDxe/ComponentName.h  |  141 +
 .../Sdio/Dxe/SDControllerDxe/SDController.c   | 1784 +++++++
 .../Sdio/Dxe/SDControllerDxe/SDController.h   |  316 ++
 .../Dxe/SDControllerDxe/SDControllerDxe.inf   |   56 +
 .../Sdio/Dxe/SDMediaDeviceDxe/CEATA.c         |  647 +++
 .../Sdio/Dxe/SDMediaDeviceDxe/CEATABlockIo.c  |  389 ++
 .../Sdio/Dxe/SDMediaDeviceDxe/ComponentName.c |  215 +
 .../Sdio/Dxe/SDMediaDeviceDxe/ComponentName.h |  139 +
 .../Sdio/Dxe/SDMediaDeviceDxe/MMCSDBlockIo.c  |  538 ++
 .../Sdio/Dxe/SDMediaDeviceDxe/MMCSDTransfer.c | 1708 +++++++
 .../Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.c |  317 ++
 .../Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.h |  462 ++
 .../Dxe/SDMediaDeviceDxe/SDMediaDeviceDxe.inf |   60 +
 .../QuarkSouthCluster/Usb/Common/Pei/UsbPei.c |  320 ++
 .../QuarkSouthCluster/Usb/Common/Pei/UsbPei.h |   38 +
 .../Usb/Common/Pei/UsbPei.inf                 |   53 +
 .../Usb/Ohci/Dxe/ComponentName.c              |  219 +
 .../Usb/Ohci/Dxe/ComponentName.h              |  141 +
 .../Usb/Ohci/Dxe/Descriptor.h                 |  132 +
 .../QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.c     | 2473 +++++++++
 .../QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.h     |  663 +++
 .../Usb/Ohci/Dxe/OhciDebug.c                  |   78 +
 .../Usb/Ohci/Dxe/OhciDebug.h                  |   42 +
 .../Usb/Ohci/Dxe/OhciDxe.inf                  |   71 +
 .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.c  | 1390 +++++
 .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.h  |  920 ++++
 .../Usb/Ohci/Dxe/OhciSched.c                  |  528 ++
 .../Usb/Ohci/Dxe/OhciSched.h                  |  225 +
 .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.c  |  889 ++++
 .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.h  |  387 ++
 .../QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.c |  560 ++
 .../QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.h |  152 +
 .../Usb/Ohci/Pei/Descriptor.h                 |  131 +
 .../QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.c  | 1386 +++++
 .../QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.h  |  252 +
 .../Usb/Ohci/Pei/OhciPei.inf                  |   56 +
 .../QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.c  | 1386 +++++
 .../QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.h  |  875 ++++
 .../Usb/Ohci/Pei/OhciSched.c                  |  223 +
 .../Usb/Ohci/Pei/OhciSched.h                  |  108 +
 .../QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.c  |  560 ++
 .../QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.h  |  231 +
 .../QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.c |  491 ++
 .../QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.h |  134 +
 .../AcpiTablesPCAT/98_LINK.ASL                |  617 +++
 .../AcpiTablesPCAT/AcpiTablePlatform.h        |   70 +
 .../AcpiTablesPCAT/AcpiTables.inf             |   40 +
 .../AcpiTablesPCAT/CPU.asl                    |   49 +
 .../AcpiTablesPCAT/DSDT.ASL                   |   75 +
 .../AcpiTablesPCAT/Facp/Facp.aslc             |  188 +
 .../AcpiTablesPCAT/Facs/Facs.aslc             |   84 +
 .../AcpiTablesPCAT/GloblNvs.asl               |  348 ++
 .../AcpiTablesPCAT/Gpe.asl                    |   99 +
 .../AcpiTablesPCAT/HOST_BUS.ASL               |  347 ++
 .../AcpiTablesPCAT/Hpet/Hpet.aslc             |   63 +
 .../AcpiTablesPCAT/INTELGFX.ASL               |  879 ++++
 .../AcpiTablesPCAT/INTELISPDev2.ASL           |   71 +
 .../AcpiTablesPCAT/IgdOGBDA.ASL               |  155 +
 .../AcpiTablesPCAT/IgdOMOBF.ASL               |  485 ++
 .../AcpiTablesPCAT/IgdOSBCB.ASL               |  274 +
 .../AcpiTablesPCAT/IgdOpRn.ASL                |  299 ++
 .../AcpiTablesPCAT/IoTVirtualDevice.asl       |  171 +
 .../AcpiTablesPCAT/LPC_DEV.ASL                |  151 +
 .../AcpiTablesPCAT/LpcB.asl                   |   59 +
 .../AcpiTablesPCAT/Lpit/Lpit.aslc             |  223 +
 .../AcpiTablesPCAT/Madt/Madt.h                |  189 +
 .../AcpiTablesPCAT/Madt/Madt30.aslc           |  178 +
 .../AcpiTablesPCAT/Mcfg/Mcfg.aslc             |   86 +
 .../AcpiTablesPCAT/PCI_DRC.ASL                |   90 +
 .../AcpiTablesPCAT/Pch.asl                    |  686 +++
 .../AcpiTablesPCAT/PchAudio.asl               |   36 +
 .../AcpiTablesPCAT/PchEhci.asl                |  269 +
 .../AcpiTablesPCAT/PchLpss.asl                | 1093 ++++
 .../AcpiTablesPCAT/PchPcie.asl                |   50 +
 .../AcpiTablesPCAT/PchScc.asl                 |  610 +++
 .../AcpiTablesPCAT/PchSmb.asl                 |  833 +++
 .../AcpiTablesPCAT/PchXhci.asl                |  379 ++
 .../AcpiTablesPCAT/PciTree.asl                |  377 ++
 .../AcpiTablesPCAT/Platform.asl               |  703 +++
 .../AcpiTablesPCAT/RTD3.asl                   |  197 +
 .../AcpiTablesPCAT/RhProxy.asl                |  160 +
 .../AcpiTablesPCAT/THERMAL.ASL                |  137 +
 .../AcpiTablesPCAT/UsbSbd.asl                 |   93 +
 .../AcpiTablesPCAT/Video.asl                  |   34 +
 .../AcpiTablesPCAT/Vlv.asl                    |   39 +
 .../AcpiTablesPCAT/Wsmt/Wsmt.aslc             |   54 +
 .../AcpiTablesPCAT/token.asl                  |   39 +
 .../Guid/Vlv2DeviceRefCodePkgTokenSpace.h     |   24 +
 .../Include/Ppi/PttPassThruPpi.h              |   92 +
 .../Include/Ppi/fTPMPolicy.h                  |   26 +
 .../Include/Protocol/PttPassThru.h            |   91 +
 .../Guid/PowerManagementAcpiTableStorage.h    |   27 +
 .../CPU/Include/Ppi/VlvPolicy.h               |  104 +
 .../CPU/Include/Protocol/PpmPlatformPolicy.h  |  132 +
 .../ValleyView2Soc/CPU/Include/Types.h        |   55 +
 .../AcpiTables/PowerManagementAcpiTables.inf  |   39 +
 .../PowerManagement/AcpiTables/Ssdt/ApCst.asl |  110 +
 .../PowerManagement/AcpiTables/Ssdt/ApIst.asl |  166 +
 .../PowerManagement/AcpiTables/Ssdt/ApTst.asl |  262 +
 .../AcpiTables/Ssdt/Cpu0Cst.asl               |  274 +
 .../AcpiTables/Ssdt/Cpu0Ist.asl               |  260 +
 .../AcpiTables/Ssdt/Cpu0Tst.asl               |  235 +
 .../PowerManagement/AcpiTables/Ssdt/CpuPm.asl |  793 +++
 .../Include/PlatformBaseAddresses.h           |   92 +
 .../NorthCluster/Include/Ppi/Capsule.h        |   60 +
 .../Include/Ppi/PlatformMemoryRange.h         |  144 +
 .../Include/Ppi/PlatformMemorySize.h          |   46 +
 .../NorthCluster/Include/Ppi/SmmAccess.h      |  165 +
 .../NorthCluster/Include/Ppi/VlvMmioPolicy.h  |   39 +
 .../NorthCluster/Include/Ppi/VlvPeiInit.h     |   35 +
 .../NorthCluster/Include/Ppi/VlvPolicy.h      |  106 +
 .../Include/Protocol/IgdOpRegion.h            |  213 +
 .../NorthCluster/Include/Protocol/MemInfo.h   |   83 +
 .../Include/Protocol/PlatformGopPolicy.h      |   67 +
 .../Include/Protocol/VlvPlatformPolicy.h      |  105 +
 .../NorthCluster/Include/Valleyview.h         |   55 +
 .../NorthCluster/Include/VlvAccess.h          |  254 +
 .../Include/VlvCommonDefinitions.h            |  252 +
 .../SouthCluster/Include/Guid/PchInitVar.h    |   48 +
 .../Include/Guid/SataControllerGuid.h         |   34 +
 .../SouthCluster/Include/Guid/SmbusArpMap.h   |   30 +
 .../SouthCluster/Include/Guid/Vlv2Variable.h  |   28 +
 .../Include/IndustryStandard/CeAta.h          |  126 +
 .../Include/IndustryStandard/Mmc.h            |  349 ++
 .../Include/IndustryStandard/SdCard.h         |  157 +
 .../SouthCluster/Include/Library/I2CLib.h     |  169 +
 .../Include/Library/PchPlatformLib.h          |  115 +
 .../SouthCluster/Include/PchAccess.h          |  471 ++
 .../Include/PchCommonDefinitions.h            |  210 +
 .../SouthCluster/Include/PchRegs.h            |  205 +
 .../SouthCluster/Include/PchRegs/PchRegsHda.h |   50 +
 .../Include/PchRegs/PchRegsLpss.h             |  486 ++
 .../Include/PchRegs/PchRegsPcie.h             |   83 +
 .../SouthCluster/Include/PchRegs/PchRegsPcu.h | 1201 +++++
 .../Include/PchRegs/PchRegsRcrb.h             |   48 +
 .../Include/PchRegs/PchRegsSata.h             |  245 +
 .../SouthCluster/Include/PchRegs/PchRegsScc.h |   53 +
 .../Include/PchRegs/PchRegsSmbus.h            |  149 +
 .../SouthCluster/Include/PchRegs/PchRegsSpi.h |  119 +
 .../SouthCluster/Include/PchRegs/PchRegsUsb.h |   92 +
 .../SouthCluster/Include/Ppi/PchInit.h        |   75 +
 .../SouthCluster/Include/Ppi/PchPeiInit.h     |   34 +
 .../Include/Ppi/PchPlatformPolicy.h           |  161 +
 .../SouthCluster/Include/Ppi/PchUsbPolicy.h   |   69 +
 .../SouthCluster/Include/Ppi/PeiBlockIo.h     |  230 +
 .../SouthCluster/Include/Ppi/Sdhc.h           |  359 ++
 .../SouthCluster/Include/Ppi/SmbusPolicy.h    |   40 +
 .../SouthCluster/Include/Ppi/Spi.h            |   42 +
 .../Include/Protocol/ActiveBios.h             |  123 +
 .../Include/Protocol/ActiveBiosProtocol.h     |  125 +
 .../Protocol/DxePchPolicyUpdateProtocol.h     |   51 +
 .../Include/Protocol/EmmcCardInfoProtocol.h   |   42 +
 .../SouthCluster/Include/Protocol/Gpio.h      |  161 +
 .../Include/Protocol/HwWatchdogTimer.h        |  294 ++
 .../SouthCluster/Include/Protocol/I2cBus.h    |  164 +
 .../Include/Protocol/PchExtendedReset.h       |   84 +
 .../SouthCluster/Include/Protocol/PchInfo.h   |   60 +
 .../Include/Protocol/PchPlatformPolicy.h      |  550 ++
 .../SouthCluster/Include/Protocol/PchReset.h  |  114 +
 .../Include/Protocol/PchS3Support.h           |  132 +
 .../SouthCluster/Include/Protocol/SdHostIo.h  |  409 ++
 .../Include/Protocol/SmbiosSlotPopulation.h   |   47 +
 .../Include/Protocol/SmmIchnDispatchEx.h      |  159 +
 .../SouthCluster/Include/Protocol/SmmSmbus.h  |   39 +
 .../SouthCluster/Include/Protocol/Spi.h       |  260 +
 .../SouthCluster/Include/Protocol/TcoReset.h  |   88 +
 .../SouthCluster/Include/Rsci.h               |   28 +
 .../SouthCluster/Include/TianoApi.h           |   61 +
 .../Vlv2DeviceRefCodePkg.dec                  |  231 +
 .../Omap35xxPkg/Flash/Flash.c                 |  768 +++
 .../Omap35xxPkg/Flash/Flash.h                 |  100 +
 .../Omap35xxPkg/Flash/Flash.inf               |   42 +
 .../TexasInsturments/Omap35xxPkg/Gpio/Gpio.c  |  129 +
 .../Omap35xxPkg/Gpio/Gpio.inf                 |   39 +
 .../Omap35xxPkg/Include/Library/OmapDmaLib.h  |   84 +
 .../Omap35xxPkg/Include/Library/OmapLib.h     |   38 +
 .../Omap35xxPkg/Include/Omap3530/Omap3530.h   |   34 +
 .../Include/Omap3530/Omap3530Dma.h            |  124 +
 .../Include/Omap3530/Omap3530Gpio.h           |  125 +
 .../Include/Omap3530/Omap3530Gpmc.h           |  101 +
 .../Include/Omap3530/Omap3530I2c.h            |   56 +
 .../Include/Omap3530/Omap3530Interrupt.h      |   45 +
 .../Include/Omap3530/Omap3530MMCHS.h          |  208 +
 .../Omap3530/Omap3530PadConfiguration.h       |  297 ++
 .../Include/Omap3530/Omap3530Prcm.h           |  159 +
 .../Include/Omap3530/Omap3530Timer.h          |   76 +
 .../Include/Omap3530/Omap3530Uart.h           |   48 +
 .../Include/Omap3530/Omap3530Usb.h            |   42 +
 .../Omap35xxPkg/Include/TPS65950.h            |   74 +
 .../InterruptDxe/HardwareInterrupt.c          |  396 ++
 .../Omap35xxPkg/InterruptDxe/InterruptDxe.inf |   48 +
 .../LcdGraphicsOutputBlt.c                    |  439 ++
 .../LcdGraphicsOutputDxe.c                    |  394 ++
 .../LcdGraphicsOutputDxe.h                    |  151 +
 .../LcdGraphicsOutputDxe.inf                  |   46 +
 .../DebugAgentTimerLib/DebugAgentTimerLib.c   |  159 +
 .../DebugAgentTimerLib/DebugAgentTimerLib.inf |   42 +
 .../Library/GdbSerialLib/GdbSerialLib.c       |   96 +
 .../Library/GdbSerialLib/GdbSerialLib.inf     |   35 +
 .../Omap35xxTimerLib/Omap35xxTimerLib.inf     |   40 +
 .../Library/Omap35xxTimerLib/TimerLib.c       |  151 +
 .../Library/OmapDmaLib/OmapDmaLib.c           |  170 +
 .../Library/OmapDmaLib/OmapDmaLib.inf         |   43 +
 .../Omap35xxPkg/Library/OmapLib/OmapLib.c     |   77 +
 .../Omap35xxPkg/Library/OmapLib/OmapLib.inf   |   31 +
 .../RealTimeClockLib/RealTimeClockLib.c       |  291 ++
 .../RealTimeClockLib/RealTimeClockLib.inf     |   32 +
 .../Library/SerialPortLib/SerialPortLib.c     |  208 +
 .../Library/SerialPortLib/SerialPortLib.inf   |   40 +
 .../Omap35xxPkg/MMCHSDxe/MMCHS.c              | 1492 ++++++
 .../Omap35xxPkg/MMCHSDxe/MMCHS.h              |  169 +
 .../Omap35xxPkg/MMCHSDxe/MMCHS.inf            |   48 +
 .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.c       |  671 +++
 .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.h       |   38 +
 .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf     |   47 +
 .../Omap35xxPkg/Omap35xxPkg.dec               |   52 +
 .../Omap35xxPkg/Omap35xxPkg.dsc               |  183 +
 .../Omap35xxPkg/PciEmulation/PciEmulation.c   |  107 +
 .../Omap35xxPkg/PciEmulation/PciEmulation.inf |   41 +
 .../Omap35xxPkg/SmbusDxe/Smbus.c              |  319 ++
 .../Omap35xxPkg/SmbusDxe/Smbus.inf            |   39 +
 .../Omap35xxPkg/TPS65950Dxe/TPS65950.c        |  110 +
 .../Omap35xxPkg/TPS65950Dxe/TPS65950.inf      |   42 +
 .../Omap35xxPkg/TimerDxe/Timer.c              |  370 ++
 .../Omap35xxPkg/TimerDxe/TimerDxe.inf         |   51 +
 1103 files changed, 259532 insertions(+)
 create mode 100644 Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.c
 create mode 100644 Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.inf
 create mode 100644 Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.c
 create mode 100644 Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.h
 create mode 100644 Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThruDxe.inf
 create mode 100644 Drivers/OptionRomPkg/AtapiPassThruDxe/ComponentName.c
 create mode 100644 Drivers/OptionRomPkg/AtapiPassThruDxe/DriverSupportedEfiVersion.c
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/CompatibleDevices.txt
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ComponentName.c
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.c
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.h
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.c
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.h
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/ComponentName.c
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/DriverBinding.c
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/SimpleNetwork.c
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/ComponentName.c
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/DriverBinding.c
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwork.c
 create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.c
 create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.h
 create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf
 create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430GraphicsOutput.c
 create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.c
 create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.h
 create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430UgaDraw.c
 create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/ComponentName.c
 create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/DriverSupportedEfiVersion.c
 create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/Edid.c
 create mode 100644 Drivers/OptionRomPkg/Include/Library/BltLib.h
 create mode 100644 Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.c
 create mode 100644 Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
 create mode 100644 Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.c
 create mode 100644 Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.inf
 create mode 100644 Drivers/OptionRomPkg/OptionRomPkg.dec
 create mode 100644 Drivers/OptionRomPkg/OptionRomPkg.dsc
 create mode 100644 Drivers/OptionRomPkg/ReadMe.txt
 create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/ComponentName.c
 create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c
 create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c
 create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h
 create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c
 create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h
 create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c
 create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.dec
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.dsc
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.fdf
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/ConfigurationHeader.bin
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/ConfigurationHeader.dat
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_boot_from_ram.inc
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_convert_symbols.sh
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_dummy.axf
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_hw_setup.inc
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_load_symbols.inc
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_symbols_macros.inc
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_unload_symbols.inc
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/trace32_load_symbols.cmm
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/trace32_load_symbols_cygwin.cmm
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Include/BeagleBoard.h
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoard.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoardHelper.S
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoardHelper.asm
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoardLib.inf
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoardMem.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/Clock.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/PadConfiguration.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/DxeHobPeCoffLib/DxeHobPeCoff.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/DxeHobPeCoffLib/DxeHobPeCoffLib.inf
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/LzmaHobCustomDecompressLib/LzmaHobCustomDecompressLib.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/LzmaHobCustomDecompressLib/LzmaHobCustomDecompressLib.inf
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/ResetSystemLib/ResetSystemLib.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/ResetSystemLib/ResetSystemLib.inf
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ArchPrePi.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ModuleEntryPoint.S
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ModuleEntryPoint.asm
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/PrePi/LzmaDecompress.h
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/PrePi/MainUniCore.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/PrePi/PeiUniCore.inf
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/PrePi/PrePi.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/PrePi/PrePi.h
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Tools/GNUmakefile
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Tools/generate_image.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Tools/makefile
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Tools/replace.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/AcpiTables.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Cst/Cpu0Cst.asl
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Ist/Cpu0Ist.asl
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Tst/Cpu0Tst.asl
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/CpuPm/CpuPm.asl
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/AD7298.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/ADC108S102.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/CAT24C08.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/CY8C9540A.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/GpioClient.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/LpcDev.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PCA9685.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PCAL9555A.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PciHostBridge.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PciIrq.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PcieExpansionPrt.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Platform.asl
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNC.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNCApic.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNCLpc.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QuarkSouthCluster.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Tpm.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Facs/Facs.aslc
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Facs/Facs.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt1.0.aslc
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt2.0.aslc
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.aslc
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Mcfg/Mcfg.aslc
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Mcfg/Mcfg.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Madt.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/MadtPlatform.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/S3Asm.S
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/S3Asm.asm
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/SetIdtEntry.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/ScriptExecute.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/ScriptExecute.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/Ppm.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/Ppm.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/SmmPowerManagement.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/SmmPowerManagement.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/SmmPowerManagement.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Application/ForceRecovery/ForceRecovery.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Application/ForceRecovery/ForceRecovery.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLibDxe.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLibDxe.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAccessLib/SpiFlashDevice.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAccessLib/SpiFlashDevice.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptor.aslc
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptor.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptorPei.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareUpdateConfig/SystemFirmwareUpdateConfig.ini
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnDataCD.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatFloppyDisk.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatIdeDisk.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatUsbDisk.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Guid/MemoryConfigData.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Guid/QuarkCapsuleGuid.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Guid/QuarkVariableLock.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Guid/SystemNvDataHobGuid.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Library/PlatformHelperLib.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Library/PlatformPcieHelperLib.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Pcal9555.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Platform.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/PlatformBoards.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Protocol/GlobalNvsArea.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Protocol/PlatformSmmSpiReady.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManager.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManager.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/CommonHeader.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/DxePlatformHelperLib.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PeiPlatformHelperLib.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperDxe.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperLib.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperPei.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformLeds.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/CommonHeader.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPcieHelperLib.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPcieHelperLib.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/SocUnit.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Flat32.S
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Flat32.asm
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Platform.inc
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLibModStrs.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecureLib.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/TisPc.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/TisPc.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/Tpm12DeviceLibInfineonI2c.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/Tpm12DeviceLibInfineonI2c.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridgeSupport.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostResource.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridge.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridgeIo.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/CommonHeader.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClassStrings.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformConfig.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveMemoryConfig.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveMemoryConfig.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/CommonHeader.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/DxePlatform.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/KeyboardLayout.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/QNCRegTable.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/Strings.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/processor.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/CommonHeader.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturer.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturerData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturerFunction.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendor.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendorData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendorFunction.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootInformationData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootInformationFunction.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturer.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturerData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturerFunction.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscDevicePath.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumberOfInstallableLanguagesData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumberOfInstallableLanguagesFunction.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemString.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemStringData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemStringFunction.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDevice.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDeviceData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDeviceFunction.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignator.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignatorData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignatorFunction.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturer.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturerData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturerFunction.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionString.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionStringData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionStringFunction.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignation.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignationData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignationFunction.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotOnboardDevices.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMisc.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscDataTable.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscDxe.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscEntryPoint.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscStrings.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/BootMode.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/CommonHeader.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/Generic/Recovery.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MemoryCallback.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformErratas.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FvbInfo.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSpi.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Quark.dsc
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Quark.fdf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/QuarkMin.dsc
 create mode 100644 Platform/Intel/QuarkPlatformPkg/QuarkMin.fdf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/QuarkPlatformPkg.dec
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Readme.md
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/.gitignore
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooksLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdate.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdate.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdate.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdateStrings.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64D.env
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64R.env
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/BootScriptSaveDxe.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/InternalBootScriptSave.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/ScriptSave.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.bat
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.sh
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FCE.exe
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleAll.bat
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleAll.sh
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMax.bat
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMax.sh
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMaxRelease.bat
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMaxRelease.sh
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleSampleColor.bat
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleSampleColor.sh
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Lvfs.ddf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGenCapsuleMinnowMax.bat
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGenCapsuleMinnowMaxRelease.bat
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGenCapsuleSampleColor.bat
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/NewRoot.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMPLE_DEVELOPMENT.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMPLE_DEVELOPMENT_SAMPLE_PRODUCTION.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/template.metainfo.xml
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptor.aslc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptor.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptorPei.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdateConfig/SystemFirmwareUpdateConfig.ini
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdateConfig/SystemFirmwareUpdateConfigGcc.ini
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FmpCertificate.dsc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FmpGreenSampleDevice.dsc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspAzaliaConfigData/AzaliaConfig.bin
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLibVlv2/FspHobProcessLibVlv2.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLibVlv2/FspHobProcessLibVlv2.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/FspPlatformSecLibVlv2.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/FspPlatformSecLibVlv2.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/AsmSaveSecContext.asm
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Fsp.inc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/PeiCoreEntry.asm
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/SecEntry.asm
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Stack.S
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Stack.asm
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/PlatformInit.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SaveSecContext.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecGetPerformance.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecPlatformInformation.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecRamInitData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecTempRamSupport.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/UartInit.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbRuntimeDxe.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceDxe.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceSmm.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmm.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmCommon.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.inf
 create mode 100755 Platform/Intel/Vlv2TbltDevicePkg/GenBiosId
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/GenBiosId.exe
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/AlertStandardFormatTable.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/ChipsetAccess.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/CommonIncludes.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/CpuType.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/FileHandleLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AcpiTableStorage.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AlertStandardFormat.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BiosId.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BoardFeatures.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/EfiVpdData.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/FirmwareId.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/HwWatchdogTimerHob.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/IdccData.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/ItkData.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/MemoryConfigData.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/OsSelection.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PciLanInfo.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformCpuInfo.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformInfo.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SensorInfoVariable.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SetupVariable.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Hpet.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/BiosIdLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/CpuIA32.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/EfiRegTableLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Esrt.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Fd.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/FlashDeviceLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2CLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cMmioConfigLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cPort_platform.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFsaLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFspLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/SpiFlash.H
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/StallSmmLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/UsbDeviceModeLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Mcfg.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/McfgTable.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Platform.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformBootMode.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformDefinitions.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/MfgMemoryTest.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Sha256Hash.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Speaker.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/UsbController.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/CK505ClockPlatformInfo.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/EnhancedSpeedstep.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/GlobalNvsArea.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/HwWatchdogTimer.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cAcpi.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBus.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBusMcg.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cHostMcg.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cMasterMcg.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cSlave.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpc83627Policy.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpce791Policy.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/MmioDevice.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Observable.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformGopPolicy.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformIdeInit.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SetupMode.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SmbiosSlotPopulation.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Speaker.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TcoReset.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TpmMp.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/UsbPolicy.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/VlvPlatformPolicy.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/SetupMode.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/IntelGopDepex/IntelGopDriver.depex
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/CpuIA32Lib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/EfiCpuVersion.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.S
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.asm
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.S
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.asm
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxe.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxe.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxeRuntimeSmm.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/SpiChipDefinitions.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLibNull.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLibDxe.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CRegs.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CAccess.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/CommonHeader.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens/BoardClkGens.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens/BoardClkGens.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/BoardGpios.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/BoardGpios.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers/BoardJumpers.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers/BoardJumpers.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/BoardOemIds.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/BoardOemIds.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid/BoardSsidSvid.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid/BoardSsidSvid.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/PlatformInfoHob.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibrary.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibrary.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/CommonHeader.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsStrings.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmosLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmosLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/PlatformSerialPortLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/CommonHeader.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmm.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmmLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Logo/Logo.bmp
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Metronome/Metronome.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/EfiStatusCode.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PeiPostCode.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConnect.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/DevicePath.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsStrings.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/InternalBdsLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/BoardPciPlatform.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.dsc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.fdf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/AzaliaVerbTable.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardId.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ClockControl.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Configuration.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchPlatformPolicy.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchRegTable.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchTcoReset.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciBus.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Platform.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SioPlatformPolicy.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/BootMode.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/CpuInitPeim.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/FlashMap.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MchInit.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryCallback.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryPeim.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PchInitPeim.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInfoInit.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInitPei.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformSsaInitPeim.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Recovery.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Stall.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/BootMode.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/CommonHeader.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/MemoryCallback.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/PlatformPei.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Stall.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.dec
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgConfig.dsc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGcc.fdf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgIA32.dsc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgX64.dsc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Boot.vfi
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Configuration.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/DebugConfig.vfi
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/FwVersionStrings.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Main.vfi
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Security.vfi
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupFunctions.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupInfoRecords.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SouthClusterConfig.vfi
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SystemComponent.vfi
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Thermal.vfi
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UnCore.vfi
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UqiList.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Vfr.vfr
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/VfrStrings.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/Platform.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/PlatformSmm.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/S3Save.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmPlatform.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Readme.md
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/CommonHeader.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufacturer.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufacturerData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufacturerFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendor.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturer.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturerData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturerFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDevice.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstallableLanguagesData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstallableLanguagesFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemString.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Data.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Function.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Data.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Function.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDevice.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArray.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnectorDesignator.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnectorDesignatorData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnectorDesignatorFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCache.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformation.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformationData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformationFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverDataTable.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverEntryPoint.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageString.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageStringData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageStringFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacturer.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacturerData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacturerFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionString.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStringData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStringFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignation.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignationData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignationFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/SmBiosMiscDxe.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchThunk/SmmSwDispatch2OnSmmSwDispatchThunk.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchThunk/SmmSwDispatch2OnSmmSwDispatchThunk.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwSpare.bin
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwWorking.bin
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageVariable.bin
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_HEADER.bin
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_HEADER_SPILOCK.bin
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/Vacant.bin
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Stitch/MNW2_Stitch_Config.txt
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInitDxe.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/Wpce791.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/cln.sh
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/DdrMemoryController.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCBase.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCConfig.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCDxe.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCPeim.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCRegs.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/IntelQNCLib.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/QNCAccessLib.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/QNCSmmLib.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Ppi/QNCMemoryInit.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/PchInfo.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/PlatformPolicy.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/QncS3Support.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/SmmIchnDispatch2.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/Spi.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QNCAccess.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QNCCommonDefinitions.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QuarkNcSocId.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/CommonHeader.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNCLib.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNCLib.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/PciExpress.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.uni
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/BaseAccess.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/QNCAccessLib.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/QNCAccessLib.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/RuntimeAccess.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/RuntimeQNCAccessLib.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCSmmLib/QNCSmmLib.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCSmmLib/QNCSmmLib.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/ResetSystemLib.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/ResetSystemLib.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/CommonHeader.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/SmbusLib.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/SmbusLib.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.uni
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInit.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInit.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInitPei.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/core_types.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/gen5_iosf_sb_definitions.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/general_definitions.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/hte.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/hte.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/io.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/lprint.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit_utils.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit_utils.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/memory_options.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/mrc.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/mrc.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/platform.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/prememinit.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/prememinit.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/CommonHeader.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInitDxe.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCRootPorts.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbus.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbusExec.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/SmmAccess.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/SmmAccessDriver.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/SmmAccessDriver.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmControlDxe/SmmControlDriver.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmControlDxe/SmmControlDxe.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/CommonHeader.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmGpi.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmHelpers.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmPeriodicTimer.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmQncn.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmSw.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmSx.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmm.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmCore.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmDispatcher.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmHelpers.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmHelpers.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmRegisters.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCxSmmHelpers.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmAccessPei/SmmAccessPei.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmAccessPei/SmmAccessPei.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/SmmControlPei.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/SmmControlPei.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Common/SpiCommon.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Common/SpiCommon.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiRuntime.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiSmm.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchSpi.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchSpi.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dec
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dsc
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/CEATA.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/I2cRegs.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Ioh.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/IohAccess.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/IohCommonDefinitions.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Library/I2cLib.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Library/IohLib.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/MMC.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/SDCard.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/SDHostIo.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/CommonHeader.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohBds.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohData.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohInit.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohInitDxe.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/CommonHeader.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/I2cLib.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/I2cLib.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/CommonHeader.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/IohLib.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/IohLib.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/ComponentName.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/ComponentName.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SDController.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SDController.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SDControllerDxe.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/CEATA.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/CEATABlockIo.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/ComponentName.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/ComponentName.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/MMCSDBlockIo.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/MMCSDTransfer.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/SDMediaDeviceDxe.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/ComponentName.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/ComponentName.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Descriptor.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDebug.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDebug.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDxe.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciSched.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciSched.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/Descriptor.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciPei.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciSched.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciSched.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/98_LINK.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTablePlatform.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTables.inf
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/CPU.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/DSDT.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facp/Facp.aslc
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facs/Facs.aslc
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/GloblNvs.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Gpe.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/HOST_BUS.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Hpet/Hpet.aslc
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELGFX.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELISPDev2.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOGBDA.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOMOBF.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOSBCB.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOpRn.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IoTVirtualDevice.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LPC_DEV.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LpcB.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Lpit/Lpit.aslc
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt30.aslc
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Mcfg/Mcfg.aslc
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PCI_DRC.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Pch.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchAudio.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchEhci.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchLpss.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchPcie.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchScc.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchSmb.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchXhci.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PciTree.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Platform.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RTD3.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RhProxy.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/THERMAL.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/UsbSbd.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Video.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Vlv.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Wsmt/Wsmt.aslc
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/token.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Guid/Vlv2DeviceRefCodePkgTokenSpace.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/PttPassThruPpi.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/fTPMPolicy.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Protocol/PttPassThru.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Guid/PowerManagementAcpiTableStorage.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Ppi/VlvPolicy.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Protocol/PpmPlatformPolicy.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Types.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/PowerManagementAcpiTables.inf
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/ApCst.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/ApIst.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/ApTst.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/Cpu0Cst.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/Cpu0Ist.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/Cpu0Tst.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/CpuPm.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/PlatformBaseAddresses.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/Capsule.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/PlatformMemoryRange.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/PlatformMemorySize.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/SmmAccess.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/VlvMmioPolicy.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/VlvPeiInit.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/VlvPolicy.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Protocol/IgdOpRegion.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Protocol/MemInfo.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Protocol/PlatformGopPolicy.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Protocol/VlvPlatformPolicy.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Valleyview.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/VlvAccess.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/VlvCommonDefinitions.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Guid/PchInitVar.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Guid/SataControllerGuid.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Guid/SmbusArpMap.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Guid/Vlv2Variable.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/IndustryStandard/CeAta.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/IndustryStandard/Mmc.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/IndustryStandard/SdCard.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Library/I2CLib.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Library/PchPlatformLib.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchAccess.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchCommonDefinitions.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsHda.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsLpss.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsPcie.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsPcu.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsRcrb.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsSata.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsScc.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsSmbus.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsSpi.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsUsb.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PchInit.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PchPeiInit.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PchPlatformPolicy.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PchUsbPolicy.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PeiBlockIo.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/Sdhc.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/SmbusPolicy.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/Spi.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/ActiveBios.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/ActiveBiosProtocol.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/DxePchPolicyUpdateProtocol.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/EmmcCardInfoProtocol.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/Gpio.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/HwWatchdogTimer.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/I2cBus.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchExtendedReset.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchInfo.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchPlatformPolicy.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchReset.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchS3Support.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/SdHostIo.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/SmbiosSlotPopulation.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/SmmIchnDispatchEx.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/SmmSmbus.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/Spi.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/TcoReset.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Rsci.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/TianoApi.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapDmaLib.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapLib.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Dma.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpio.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpmc.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530I2c.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Interrupt.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530MMCHS.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530PadConfiguration.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Prcm.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Timer.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Uart.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Usb.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/TPS65950.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/HardwareInterrupt.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/InterruptDxe.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/Omap35xxTimerLib.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/TimerLib.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTimeClockLib.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTimeClockLib.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dec
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dsc
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/Timer.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/TimerDxe.inf

-- 
2.21.0.windows.1


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [edk2-platforms: Patch 1/8] Silicon/TexasInsturments: Import Omap35xxPkg from edk2
  2019-05-10  3:34 [edk2-platforms: Patch 0/8] Add packages from edk2 Michael D Kinney
@ 2019-05-10  3:34 ` Michael D Kinney
  2019-05-10 17:56   ` Leif Lindholm
  2019-05-10  3:34 ` [edk2-platforms: Patch 2/8] Platform/BeagleBoard: Import BeagleBoardPkg " Michael D Kinney
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 23+ messages in thread
From: Michael D Kinney @ 2019-05-10  3:34 UTC (permalink / raw)
  To: devel; +Cc: Leif Lindholm, Ard Biesheuvel

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

Import Omap35xxPkg from edk2/master.

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>
---
 .../Omap35xxPkg/Flash/Flash.c                 |  768 +++++++++
 .../Omap35xxPkg/Flash/Flash.h                 |  100 ++
 .../Omap35xxPkg/Flash/Flash.inf               |   42 +
 .../TexasInsturments/Omap35xxPkg/Gpio/Gpio.c  |  129 ++
 .../Omap35xxPkg/Gpio/Gpio.inf                 |   39 +
 .../Omap35xxPkg/Include/Library/OmapDmaLib.h  |   84 +
 .../Omap35xxPkg/Include/Library/OmapLib.h     |   38 +
 .../Omap35xxPkg/Include/Omap3530/Omap3530.h   |   34 +
 .../Include/Omap3530/Omap3530Dma.h            |  124 ++
 .../Include/Omap3530/Omap3530Gpio.h           |  125 ++
 .../Include/Omap3530/Omap3530Gpmc.h           |  101 ++
 .../Include/Omap3530/Omap3530I2c.h            |   56 +
 .../Include/Omap3530/Omap3530Interrupt.h      |   45 +
 .../Include/Omap3530/Omap3530MMCHS.h          |  208 +++
 .../Omap3530/Omap3530PadConfiguration.h       |  297 ++++
 .../Include/Omap3530/Omap3530Prcm.h           |  159 ++
 .../Include/Omap3530/Omap3530Timer.h          |   76 +
 .../Include/Omap3530/Omap3530Uart.h           |   48 +
 .../Include/Omap3530/Omap3530Usb.h            |   42 +
 .../Omap35xxPkg/Include/TPS65950.h            |   74 +
 .../InterruptDxe/HardwareInterrupt.c          |  396 +++++
 .../Omap35xxPkg/InterruptDxe/InterruptDxe.inf |   48 +
 .../LcdGraphicsOutputBlt.c                    |  439 +++++
 .../LcdGraphicsOutputDxe.c                    |  394 +++++
 .../LcdGraphicsOutputDxe.h                    |  151 ++
 .../LcdGraphicsOutputDxe.inf                  |   46 +
 .../DebugAgentTimerLib/DebugAgentTimerLib.c   |  159 ++
 .../DebugAgentTimerLib/DebugAgentTimerLib.inf |   42 +
 .../Library/GdbSerialLib/GdbSerialLib.c       |   96 ++
 .../Library/GdbSerialLib/GdbSerialLib.inf     |   35 +
 .../Omap35xxTimerLib/Omap35xxTimerLib.inf     |   40 +
 .../Library/Omap35xxTimerLib/TimerLib.c       |  151 ++
 .../Library/OmapDmaLib/OmapDmaLib.c           |  170 ++
 .../Library/OmapDmaLib/OmapDmaLib.inf         |   43 +
 .../Omap35xxPkg/Library/OmapLib/OmapLib.c     |   77 +
 .../Omap35xxPkg/Library/OmapLib/OmapLib.inf   |   31 +
 .../RealTimeClockLib/RealTimeClockLib.c       |  291 ++++
 .../RealTimeClockLib/RealTimeClockLib.inf     |   32 +
 .../Library/SerialPortLib/SerialPortLib.c     |  208 +++
 .../Library/SerialPortLib/SerialPortLib.inf   |   40 +
 .../Omap35xxPkg/MMCHSDxe/MMCHS.c              | 1492 +++++++++++++++++
 .../Omap35xxPkg/MMCHSDxe/MMCHS.h              |  169 ++
 .../Omap35xxPkg/MMCHSDxe/MMCHS.inf            |   48 +
 .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.c       |  671 ++++++++
 .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.h       |   38 +
 .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf     |   47 +
 .../Omap35xxPkg/Omap35xxPkg.dec               |   52 +
 .../Omap35xxPkg/Omap35xxPkg.dsc               |  183 ++
 .../Omap35xxPkg/PciEmulation/PciEmulation.c   |  107 ++
 .../Omap35xxPkg/PciEmulation/PciEmulation.inf |   41 +
 .../Omap35xxPkg/SmbusDxe/Smbus.c              |  319 ++++
 .../Omap35xxPkg/SmbusDxe/Smbus.inf            |   39 +
 .../Omap35xxPkg/TPS65950Dxe/TPS65950.c        |  110 ++
 .../Omap35xxPkg/TPS65950Dxe/TPS65950.inf      |   42 +
 .../Omap35xxPkg/TimerDxe/Timer.c              |  370 ++++
 .../Omap35xxPkg/TimerDxe/TimerDxe.inf         |   51 +
 56 files changed, 9257 insertions(+)
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapDmaLib.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapLib.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Dma.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpio.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpmc.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530I2c.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Interrupt.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530MMCHS.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530PadConfiguration.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Prcm.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Timer.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Uart.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Usb.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/TPS65950.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/HardwareInterrupt.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/InterruptDxe.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/Omap35xxTimerLib.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/TimerLib.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTimeClockLib.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTimeClockLib.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dec
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dsc
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/Timer.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/TimerDxe.inf

diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.c b/Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.c
new file mode 100644
index 0000000000..43f8f4279e
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.c
@@ -0,0 +1,768 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Flash.h"
+
+NAND_PART_INFO_TABLE gNandPartInfoTable[1] = {
+  { 0x2C, 0xBA, 17, 11 }
+};
+
+NAND_FLASH_INFO *gNandFlashInfo = NULL;
+UINT8           *gEccCode;
+UINTN           gNum512BytesChunks = 0;
+
+//
+
+// Device path for SemiHosting. It contains our autogened Caller ID GUID.
+
+//
+
+typedef struct {
+
+  VENDOR_DEVICE_PATH        Guid;
+
+  EFI_DEVICE_PATH_PROTOCOL  End;
+
+} FLASH_DEVICE_PATH;
+
+
+
+FLASH_DEVICE_PATH gDevicePath = {
+  {
+    { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0 } },
+    EFI_CALLER_ID_GUID
+  },
+  { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0} }
+};
+
+
+
+//Actual page address = Column address + Page address + Block address.
+UINTN
+GetActualPageAddressInBytes (
+  UINTN BlockIndex,
+  UINTN PageIndex
+)
+{
+  //BlockAddressStart = Start of the Block address in actual NAND
+  //PageAddressStart = Start of the Page address in actual NAND
+  return ((BlockIndex << gNandFlashInfo->BlockAddressStart) + (PageIndex << gNandFlashInfo->PageAddressStart));
+}
+
+VOID
+NandSendCommand (
+  UINT8 Command
+)
+{
+  MmioWrite16(GPMC_NAND_COMMAND_0, Command);
+}
+
+VOID
+NandSendAddress (
+  UINT8 Address
+)
+{
+  MmioWrite16(GPMC_NAND_ADDRESS_0, Address);
+}
+
+UINT16
+NandReadStatus (
+  VOID
+  )
+{
+  //Send READ STATUS command
+  NandSendCommand(READ_STATUS_CMD);
+
+  //Read status.
+  return MmioRead16(GPMC_NAND_DATA_0);
+}
+
+VOID
+NandSendAddressCycles (
+  UINTN Address
+)
+{
+  //Column address
+  NandSendAddress(Address & 0xff);
+  Address >>= 8;
+
+  //Column address
+  NandSendAddress(Address & 0x07);
+  Address >>= 3;
+
+  //Page and Block address
+  NandSendAddress(Address & 0xff);
+  Address >>= 8;
+
+  //Block address
+  NandSendAddress(Address & 0xff);
+  Address >>= 8;
+
+  //Block address
+  NandSendAddress(Address & 0x01);
+}
+
+VOID
+GpmcInit (
+  VOID
+  )
+{
+  //Enable Smart-idle mode.
+  MmioWrite32 (GPMC_SYSCONFIG, SMARTIDLEMODE);
+
+  //Set IRQSTATUS and IRQENABLE to the reset value
+  MmioWrite32 (GPMC_IRQSTATUS, 0x0);
+  MmioWrite32 (GPMC_IRQENABLE, 0x0);
+
+  //Disable GPMC timeout control.
+  MmioWrite32 (GPMC_TIMEOUT_CONTROL, TIMEOUTDISABLE);
+
+  //Set WRITEPROTECT bit to enable write access.
+  MmioWrite32 (GPMC_CONFIG, WRITEPROTECT_HIGH);
+
+  //NOTE: Following GPMC_CONFIGi_0 register settings are taken from u-boot memory dump.
+  MmioWrite32 (GPMC_CONFIG1_0, DEVICETYPE_NAND | DEVICESIZE_X16);
+  MmioWrite32 (GPMC_CONFIG2_0, CSRDOFFTIME | CSWROFFTIME);
+  MmioWrite32 (GPMC_CONFIG3_0, ADVRDOFFTIME | ADVWROFFTIME);
+  MmioWrite32 (GPMC_CONFIG4_0, OEONTIME | OEOFFTIME | WEONTIME | WEOFFTIME);
+  MmioWrite32 (GPMC_CONFIG5_0, RDCYCLETIME | WRCYCLETIME | RDACCESSTIME | PAGEBURSTACCESSTIME);
+  MmioWrite32 (GPMC_CONFIG6_0, WRACCESSTIME | WRDATAONADMUXBUS | CYCLE2CYCLEDELAY | CYCLE2CYCLESAMECSEN);
+  MmioWrite32 (GPMC_CONFIG7_0, MASKADDRESS_128MB | CSVALID | BASEADDRESS);
+}
+
+EFI_STATUS
+NandDetectPart (
+  VOID
+)
+{
+  UINT8      NandInfo = 0;
+  UINT8      PartInfo[5];
+  UINTN      Index;
+  BOOLEAN    Found = FALSE;
+
+  //Send READ ID command
+  NandSendCommand(READ_ID_CMD);
+
+  //Send one address cycle.
+  NandSendAddress(0);
+
+  //Read 5-bytes to idenfity code programmed into the NAND flash devices.
+  //BYTE 0 = Manufacture ID
+  //Byte 1 = Device ID
+  //Byte 2, 3, 4 = Nand part specific information (Page size, Block size etc)
+  for (Index = 0; Index < sizeof(PartInfo); Index++) {
+    PartInfo[Index] = MmioRead16(GPMC_NAND_DATA_0);
+  }
+
+  //Check if the ManufactureId and DeviceId are part of the currently supported nand parts.
+  for (Index = 0; Index < sizeof(gNandPartInfoTable)/sizeof(NAND_PART_INFO_TABLE); Index++) {
+    if (gNandPartInfoTable[Index].ManufactureId == PartInfo[0] && gNandPartInfoTable[Index].DeviceId == PartInfo[1]) {
+      gNandFlashInfo->BlockAddressStart = gNandPartInfoTable[Index].BlockAddressStart;
+      gNandFlashInfo->PageAddressStart = gNandPartInfoTable[Index].PageAddressStart;
+      Found = TRUE;
+      break;
+    }
+  }
+
+  if (Found == FALSE) {
+    DEBUG ((EFI_D_ERROR, "Nand part is not currently supported. Manufacture id: %x, Device id: %x\n", PartInfo[0], PartInfo[1]));
+    return EFI_NOT_FOUND;
+  }
+
+  //Populate NAND_FLASH_INFO based on the result of READ ID command.
+  gNandFlashInfo->ManufactureId = PartInfo[0];
+  gNandFlashInfo->DeviceId = PartInfo[1];
+  NandInfo = PartInfo[3];
+
+  if (PAGE_SIZE(NandInfo) == PAGE_SIZE_2K_VAL) {
+    gNandFlashInfo->PageSize = PAGE_SIZE_2K;
+  } else {
+    DEBUG ((EFI_D_ERROR, "Unknown Page size.\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (SPARE_AREA_SIZE(NandInfo) == SPARE_AREA_SIZE_64B_VAL) {
+    gNandFlashInfo->SparePageSize = SPARE_AREA_SIZE_64B;
+  } else {
+    DEBUG ((EFI_D_ERROR, "Unknown Spare area size.\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (BLOCK_SIZE(NandInfo) == BLOCK_SIZE_128K_VAL) {
+    gNandFlashInfo->BlockSize = BLOCK_SIZE_128K;
+  } else {
+    DEBUG ((EFI_D_ERROR, "Unknown Block size.\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (ORGANIZATION(NandInfo) == ORGANIZATION_X8) {
+    gNandFlashInfo->Organization = 0;
+  } else if (ORGANIZATION(NandInfo) == ORGANIZATION_X16) {
+    gNandFlashInfo->Organization = 1;
+  }
+
+  //Calculate total number of blocks.
+  gNandFlashInfo->NumPagesPerBlock = DivU64x32(gNandFlashInfo->BlockSize, gNandFlashInfo->PageSize);
+
+  return EFI_SUCCESS;
+}
+
+VOID
+NandConfigureEcc (
+  VOID
+  )
+{
+  //Define ECC size 0 and size 1 to 512 bytes
+  MmioWrite32 (GPMC_ECC_SIZE_CONFIG, (ECCSIZE0_512BYTES | ECCSIZE1_512BYTES));
+}
+
+VOID
+NandEnableEcc (
+  VOID
+  )
+{
+  //Clear all the ECC result registers and select ECC result register 1
+  MmioWrite32 (GPMC_ECC_CONTROL, (ECCCLEAR | ECCPOINTER_REG1));
+
+  //Enable ECC engine on CS0
+  MmioWrite32 (GPMC_ECC_CONFIG, (ECCENABLE | ECCCS_0 | ECC16B));
+}
+
+VOID
+NandDisableEcc (
+  VOID
+  )
+{
+  //Turn off ECC engine.
+  MmioWrite32 (GPMC_ECC_CONFIG, ECCDISABLE);
+}
+
+VOID
+NandCalculateEcc (
+  VOID
+  )
+{
+  UINTN Index;
+  UINTN EccResultRegister;
+  UINTN EccResult;
+
+  //Capture 32-bit ECC result for each 512-bytes chunk.
+  //In our case PageSize is 2K so read ECC1-ECC4 result registers and
+  //generate total of 12-bytes of ECC code for the particular page.
+
+  EccResultRegister = GPMC_ECC1_RESULT;
+
+  for (Index = 0; Index < gNum512BytesChunks; Index++) {
+
+    EccResult = MmioRead32 (EccResultRegister);
+
+    //Calculate ECC code from 32-bit ECC result value.
+    //NOTE: Following calculation is not part of TRM. We got this information
+    //from Beagleboard mailing list.
+    gEccCode[Index * 3] = EccResult & 0xFF;
+    gEccCode[(Index * 3) + 1] = (EccResult >> 16) & 0xFF;
+    gEccCode[(Index * 3) + 2] = (((EccResult >> 20) & 0xF0) | ((EccResult >> 8) & 0x0F));
+
+    //Point to next ECC result register.
+    EccResultRegister += 4;
+  }
+}
+
+EFI_STATUS
+NandReadPage (
+  IN  UINTN                         BlockIndex,
+  IN  UINTN                         PageIndex,
+  OUT VOID                          *Buffer,
+  OUT UINT8                         *SpareBuffer
+)
+{
+  UINTN      Address;
+  UINTN      Index;
+  UINTN      NumMainAreaWords = (gNandFlashInfo->PageSize/2);
+  UINTN      NumSpareAreaWords = (gNandFlashInfo->SparePageSize/2);
+  UINT16     *MainAreaWordBuffer = Buffer;
+  UINT16     *SpareAreaWordBuffer = (UINT16 *)SpareBuffer;
+  UINTN      Timeout = MAX_RETRY_COUNT;
+
+  //Generate device address in bytes to access specific block and page index
+  Address = GetActualPageAddressInBytes(BlockIndex, PageIndex);
+
+  //Send READ command
+  NandSendCommand(PAGE_READ_CMD);
+
+  //Send 5 Address cycles to access specific device address
+  NandSendAddressCycles(Address);
+
+  //Send READ CONFIRM command
+  NandSendCommand(PAGE_READ_CONFIRM_CMD);
+
+  //Poll till device is busy.
+  while (Timeout) {
+    if ((NandReadStatus() & NAND_READY) == NAND_READY) {
+      break;
+    }
+    Timeout--;
+  }
+
+  if (Timeout == 0) {
+    DEBUG ((EFI_D_ERROR, "Read page timed out.\n"));
+    return EFI_TIMEOUT;
+  }
+
+  //Reissue READ command
+  NandSendCommand(PAGE_READ_CMD);
+
+  //Enable ECC engine.
+  NandEnableEcc();
+
+  //Read data into the buffer.
+  for (Index = 0; Index < NumMainAreaWords; Index++) {
+    *MainAreaWordBuffer++ = MmioRead16(GPMC_NAND_DATA_0);
+  }
+
+  //Read spare area into the buffer.
+  for (Index = 0; Index < NumSpareAreaWords; Index++) {
+    *SpareAreaWordBuffer++ = MmioRead16(GPMC_NAND_DATA_0);
+  }
+
+  //Calculate ECC.
+  NandCalculateEcc();
+
+  //Turn off ECC engine.
+  NandDisableEcc();
+
+  //Perform ECC correction.
+  //Need to implement..
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+NandWritePage (
+  IN  UINTN                         BlockIndex,
+  IN  UINTN                         PageIndex,
+  OUT VOID                          *Buffer,
+  IN  UINT8                         *SpareBuffer
+)
+{
+  UINTN      Address;
+  UINT16     *MainAreaWordBuffer = Buffer;
+  UINT16     *SpareAreaWordBuffer = (UINT16 *)SpareBuffer;
+  UINTN      Index;
+  UINTN      NandStatus;
+  UINTN      Timeout = MAX_RETRY_COUNT;
+
+  //Generate device address in bytes to access specific block and page index
+  Address = GetActualPageAddressInBytes(BlockIndex, PageIndex);
+
+  //Send SERIAL DATA INPUT command
+  NandSendCommand(PROGRAM_PAGE_CMD);
+
+  //Send 5 Address cycles to access specific device address
+  NandSendAddressCycles(Address);
+
+  //Enable ECC engine.
+  NandEnableEcc();
+
+  //Data input from Buffer
+  for (Index = 0; Index < (gNandFlashInfo->PageSize/2); Index++) {
+    MmioWrite16(GPMC_NAND_DATA_0, *MainAreaWordBuffer++);
+
+    //After each write access, device has to wait to accept data.
+    //Currently we may not be programming proper timing parameters to
+    //the GPMC_CONFIGi_0 registers and we would need to figure that out.
+    //Without following delay, page programming fails.
+    gBS->Stall(1);
+  }
+
+  //Calculate ECC.
+  NandCalculateEcc();
+
+  //Turn off ECC engine.
+  NandDisableEcc();
+
+  //Prepare Spare area buffer with ECC codes.
+  SetMem(SpareBuffer, gNandFlashInfo->SparePageSize, 0xFF);
+  CopyMem(&SpareBuffer[ECC_POSITION], gEccCode, gNum512BytesChunks * 3);
+
+  //Program spare area with calculated ECC.
+  for (Index = 0; Index < (gNandFlashInfo->SparePageSize/2); Index++) {
+    MmioWrite16(GPMC_NAND_DATA_0, *SpareAreaWordBuffer++);
+  }
+
+  //Send PROGRAM command
+  NandSendCommand(PROGRAM_PAGE_CONFIRM_CMD);
+
+  //Poll till device is busy.
+  NandStatus = 0;
+  while (Timeout) {
+    NandStatus = NandReadStatus();
+    if ((NandStatus & NAND_READY) == NAND_READY) {
+      break;
+    }
+    Timeout--;
+  }
+
+  if (Timeout == 0) {
+    DEBUG ((EFI_D_ERROR, "Program page timed out.\n"));
+    return EFI_TIMEOUT;
+  }
+
+  //Bit0 indicates Pass/Fail status
+  if (NandStatus & NAND_FAILURE) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+NandEraseBlock (
+  IN UINTN BlockIndex
+)
+{
+  UINTN      Address;
+  UINTN      NandStatus;
+  UINTN      Timeout = MAX_RETRY_COUNT;
+
+  //Generate device address in bytes to access specific block and page index
+  Address = GetActualPageAddressInBytes(BlockIndex, 0);
+
+  //Send ERASE SETUP command
+  NandSendCommand(BLOCK_ERASE_CMD);
+
+  //Send 3 address cycles to device to access Page address and Block address
+  Address >>= 11; //Ignore column addresses
+
+  NandSendAddress(Address & 0xff);
+  Address >>= 8;
+
+  NandSendAddress(Address & 0xff);
+  Address >>= 8;
+
+  NandSendAddress(Address & 0xff);
+
+  //Send ERASE CONFIRM command
+  NandSendCommand(BLOCK_ERASE_CONFIRM_CMD);
+
+  //Poll till device is busy.
+  NandStatus = 0;
+  while (Timeout) {
+    NandStatus = NandReadStatus();
+    if ((NandStatus & NAND_READY) == NAND_READY) {
+      break;
+    }
+    Timeout--;
+    gBS->Stall(1);
+  }
+
+  if (Timeout == 0) {
+    DEBUG ((EFI_D_ERROR, "Erase block timed out for Block: %d.\n", BlockIndex));
+    return EFI_TIMEOUT;
+  }
+
+  //Bit0 indicates Pass/Fail status
+  if (NandStatus & NAND_FAILURE) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+NandReadBlock (
+  IN UINTN                          StartBlockIndex,
+  IN UINTN                          EndBlockIndex,
+  OUT VOID                          *Buffer,
+  OUT VOID                          *SpareBuffer
+)
+{
+  UINTN      BlockIndex;
+  UINTN      PageIndex;
+  EFI_STATUS Status = EFI_SUCCESS;
+
+  for (BlockIndex = StartBlockIndex; BlockIndex <= EndBlockIndex; BlockIndex++) {
+    //For each block read number of pages
+    for (PageIndex = 0; PageIndex < gNandFlashInfo->NumPagesPerBlock; PageIndex++) {
+      Status = NandReadPage(BlockIndex, PageIndex, Buffer, SpareBuffer);
+      if (EFI_ERROR(Status)) {
+        return Status;
+      }
+      Buffer = ((UINT8 *)Buffer + gNandFlashInfo->PageSize);
+    }
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+NandWriteBlock (
+  IN UINTN                          StartBlockIndex,
+  IN UINTN                          EndBlockIndex,
+  OUT VOID                          *Buffer,
+  OUT VOID                          *SpareBuffer
+  )
+{
+  UINTN      BlockIndex;
+  UINTN      PageIndex;
+  EFI_STATUS Status = EFI_SUCCESS;
+
+  for (BlockIndex = StartBlockIndex; BlockIndex <= EndBlockIndex; BlockIndex++) {
+    //Page programming.
+    for (PageIndex = 0; PageIndex < gNandFlashInfo->NumPagesPerBlock; PageIndex++) {
+      Status = NandWritePage(BlockIndex, PageIndex, Buffer, SpareBuffer);
+      if (EFI_ERROR(Status)) {
+        return Status;
+      }
+      Buffer = ((UINT8 *)Buffer + gNandFlashInfo->PageSize);
+    }
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+NandFlashReset (
+  IN EFI_BLOCK_IO_PROTOCOL          *This,
+  IN BOOLEAN                        ExtendedVerification
+  )
+{
+  UINTN BusyStall = 50;                            // microSeconds
+  UINTN ResetBusyTimeout = (1000000 / BusyStall);  // 1 Second
+
+  //Send RESET command to device.
+  NandSendCommand(RESET_CMD);
+
+  //Wait for 1ms before we check status register.
+  gBS->Stall(1000);
+
+  //Check BIT#5 & BIT#6 in Status register to make sure RESET is done.
+  while ((NandReadStatus() & NAND_RESET_STATUS) != NAND_RESET_STATUS) {
+
+    //In case of extended verification, wait for extended amount of time
+    //to make sure device is reset.
+    if (ExtendedVerification) {
+      if (ResetBusyTimeout == 0) {
+        return EFI_DEVICE_ERROR;
+      }
+
+      gBS->Stall(BusyStall);
+      ResetBusyTimeout--;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+NandFlashReadBlocks (
+  IN EFI_BLOCK_IO_PROTOCOL          *This,
+  IN UINT32                         MediaId,
+  IN EFI_LBA                        Lba,
+  IN UINTN                          BufferSize,
+  OUT VOID                          *Buffer
+  )
+{
+  UINTN      NumBlocks;
+  UINTN      EndBlockIndex;
+  EFI_STATUS Status;
+  UINT8      *SpareBuffer = NULL;
+
+  if (Buffer == NULL) {
+    Status = EFI_INVALID_PARAMETER;
+    goto exit;
+  }
+
+  if (Lba > LAST_BLOCK) {
+    Status = EFI_INVALID_PARAMETER;
+    goto exit;
+  }
+
+  if ((BufferSize % gNandFlashInfo->BlockSize) != 0) {
+    Status = EFI_BAD_BUFFER_SIZE;
+    goto exit;
+  }
+
+  NumBlocks = DivU64x32(BufferSize, gNandFlashInfo->BlockSize);
+  EndBlockIndex = ((UINTN)Lba + NumBlocks) - 1;
+
+  SpareBuffer = (UINT8 *)AllocatePool(gNandFlashInfo->SparePageSize);
+  if (SpareBuffer == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto exit;
+  }
+
+  //Read block
+  Status = NandReadBlock((UINTN)Lba, EndBlockIndex, Buffer, SpareBuffer);
+  if (EFI_ERROR(Status)) {
+    DEBUG((EFI_D_ERROR, "Read block fails: %x\n", Status));
+    goto exit;
+  }
+
+exit:
+  if (SpareBuffer != NULL) {
+    FreePool (SpareBuffer);
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+NandFlashWriteBlocks (
+  IN EFI_BLOCK_IO_PROTOCOL          *This,
+  IN UINT32                         MediaId,
+  IN EFI_LBA                        Lba,
+  IN UINTN                          BufferSize,
+  IN VOID                           *Buffer
+  )
+{
+  UINTN      BlockIndex;
+  UINTN      NumBlocks;
+  UINTN      EndBlockIndex;
+  EFI_STATUS Status;
+  UINT8      *SpareBuffer = NULL;
+
+  if (Buffer == NULL) {
+    Status = EFI_INVALID_PARAMETER;
+    goto exit;
+  }
+
+  if (Lba > LAST_BLOCK) {
+    Status = EFI_INVALID_PARAMETER;
+    goto exit;
+  }
+
+  if ((BufferSize % gNandFlashInfo->BlockSize) != 0) {
+    Status = EFI_BAD_BUFFER_SIZE;
+    goto exit;
+  }
+
+  NumBlocks = DivU64x32(BufferSize, gNandFlashInfo->BlockSize);
+  EndBlockIndex = ((UINTN)Lba + NumBlocks) - 1;
+
+  SpareBuffer = (UINT8 *)AllocatePool(gNandFlashInfo->SparePageSize);
+  if (SpareBuffer == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto exit;
+  }
+
+  // Erase block
+  for (BlockIndex = (UINTN)Lba; BlockIndex <= EndBlockIndex; BlockIndex++) {
+    Status = NandEraseBlock(BlockIndex);
+    if (EFI_ERROR(Status)) {
+      DEBUG((EFI_D_ERROR, "Erase block failed. Status: %x\n", Status));
+      goto exit;
+    }
+  }
+
+  // Program data
+  Status = NandWriteBlock((UINTN)Lba, EndBlockIndex, Buffer, SpareBuffer);
+  if (EFI_ERROR(Status)) {
+    DEBUG((EFI_D_ERROR, "Block write fails: %x\n", Status));
+    goto exit;
+  }
+
+exit:
+  if (SpareBuffer != NULL) {
+    FreePool (SpareBuffer);
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+NandFlashFlushBlocks (
+  IN EFI_BLOCK_IO_PROTOCOL  *This
+  )
+{
+  return EFI_SUCCESS;
+}
+
+
+
+EFI_BLOCK_IO_MEDIA gNandFlashMedia = {
+  SIGNATURE_32('n','a','n','d'),            // MediaId
+  FALSE,                                    // RemovableMedia
+  TRUE,                                     // MediaPresent
+  FALSE,                                    // LogicalPartition
+  FALSE,                                    // ReadOnly
+  FALSE,                                    // WriteCaching
+  0,                                        // BlockSize
+  2,                                        // IoAlign
+  0,                                        // Pad
+  0                                         // LastBlock
+};
+
+EFI_BLOCK_IO_PROTOCOL BlockIo =
+{
+  EFI_BLOCK_IO_INTERFACE_REVISION,  // Revision
+  &gNandFlashMedia,                  // *Media
+  NandFlashReset,                   // Reset
+  NandFlashReadBlocks,              // ReadBlocks
+  NandFlashWriteBlocks,             // WriteBlocks
+  NandFlashFlushBlocks              // FlushBlocks
+};
+
+EFI_STATUS
+NandFlashInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  gNandFlashInfo = (NAND_FLASH_INFO *)AllocateZeroPool (sizeof(NAND_FLASH_INFO));
+
+  //Initialize GPMC module.
+  GpmcInit();
+
+  //Reset NAND part
+  NandFlashReset(&BlockIo, FALSE);
+
+  //Detect NAND part and populate gNandFlashInfo structure
+  Status = NandDetectPart ();
+  if (EFI_ERROR(Status)) {
+    DEBUG((EFI_D_ERROR, "Nand part id detection failure: Status: %x\n", Status));
+    return Status;
+  }
+
+  //Count total number of 512Bytes chunk based on the page size.
+  if (gNandFlashInfo->PageSize == PAGE_SIZE_512B) {
+    gNum512BytesChunks = 1;
+  } else if (gNandFlashInfo->PageSize == PAGE_SIZE_2K) {
+    gNum512BytesChunks = 4;
+  } else if (gNandFlashInfo->PageSize == PAGE_SIZE_4K) {
+    gNum512BytesChunks = 8;
+  }
+
+  gEccCode = (UINT8 *)AllocatePool(gNum512BytesChunks * 3);
+  if (gEccCode == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //Configure ECC
+  NandConfigureEcc ();
+
+  //Patch EFI_BLOCK_IO_MEDIA structure.
+  gNandFlashMedia.BlockSize = gNandFlashInfo->BlockSize;
+  gNandFlashMedia.LastBlock = LAST_BLOCK;
+
+  //Publish BlockIO.
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gEfiBlockIoProtocolGuid, &BlockIo,
+                  &gEfiDevicePathProtocolGuid, &gDevicePath,
+                  NULL
+                  );
+  return Status;
+}
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.h b/Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.h
new file mode 100644
index 0000000000..62f7eb30dc
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.h
@@ -0,0 +1,100 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef FLASH_H
+#define FLASH_H
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/IoLib.h>
+
+#include <Protocol/BlockIo.h>
+#include <Protocol/Cpu.h>
+#include <Omap3530/Omap3530.h>
+
+#define PAGE_SIZE(x)             ((x) & 0x01)
+#define PAGE_SIZE_2K_VAL         (0x01UL)
+
+#define SPARE_AREA_SIZE(x)       (((x) >> 2) & 0x01)
+#define SPARE_AREA_SIZE_64B_VAL  (0x1UL)
+
+#define BLOCK_SIZE(x)            (((x) >> 4) & 0x01)
+#define BLOCK_SIZE_128K_VAL      (0x01UL)
+
+#define ORGANIZATION(x)          (((x) >> 6) & 0x01)
+#define ORGANIZATION_X8          (0x0UL)
+#define ORGANIZATION_X16         (0x1UL)
+
+#define PAGE_SIZE_512B           (512)
+#define PAGE_SIZE_2K             (2048)
+#define PAGE_SIZE_4K             (4096)
+#define SPARE_AREA_SIZE_16B      (16)
+#define SPARE_AREA_SIZE_64B      (64)
+
+#define BLOCK_SIZE_16K           (16*1024)
+#define BLOCK_SIZE_128K          (128*1024)
+
+#define BLOCK_COUNT              (2048)
+#define LAST_BLOCK               (BLOCK_COUNT - 1)
+
+#define ECC_POSITION             2
+
+//List of commands.
+#define RESET_CMD                0xFF
+#define READ_ID_CMD              0x90
+
+#define READ_STATUS_CMD          0x70
+
+#define PAGE_READ_CMD            0x00
+#define PAGE_READ_CONFIRM_CMD    0x30
+
+#define BLOCK_ERASE_CMD          0x60
+#define BLOCK_ERASE_CONFIRM_CMD  0xD0
+
+#define PROGRAM_PAGE_CMD         0x80
+#define PROGRAM_PAGE_CONFIRM_CMD 0x10
+
+//Nand status register bit definition
+#define NAND_SUCCESS             (0x0UL << 0)
+#define NAND_FAILURE             BIT0
+
+#define NAND_BUSY                (0x0UL << 6)
+#define NAND_READY               BIT6
+
+#define NAND_RESET_STATUS        (0x60UL << 0)
+
+#define MAX_RETRY_COUNT          1500
+
+
+typedef struct {
+  UINT8 ManufactureId;
+  UINT8 DeviceId;
+  UINT8 BlockAddressStart; //Start of the Block address in actual NAND
+  UINT8 PageAddressStart;  //Start of the Page address in actual NAND
+} NAND_PART_INFO_TABLE;
+
+typedef struct {
+  UINT8     ManufactureId;
+  UINT8     DeviceId;
+  UINT8     Organization;      //x8 or x16
+  UINT32    PageSize;
+  UINT32    SparePageSize;
+  UINT32    BlockSize;
+  UINT32    NumPagesPerBlock;
+  UINT8     BlockAddressStart; //Start of the Block address in actual NAND
+  UINT8     PageAddressStart;  //Start of the Page address in actual NAND
+} NAND_FLASH_INFO;
+
+#endif //FLASH_H
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.inf b/Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.inf
new file mode 100644
index 0000000000..39e36ec9ce
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.inf
@@ -0,0 +1,42 @@
+#/** @file
+#
+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = NandFlash
+  FILE_GUID                      = 4d00ef14-c4e0-426b-81b7-30a00a14aad6
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = NandFlashInitialize
+
+
+[Sources.common]
+  Flash.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  UefiLib
+  UefiDriverEntryPoint
+  MemoryAllocationLib
+  IoLib
+
+[Guids]
+
+[Protocols]
+  gEfiBlockIoProtocolGuid
+  gEfiCpuArchProtocolGuid
+
+[Pcd]
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxGpmcOffset
+
+[depex]
+  TRUE
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.c b/Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.c
new file mode 100644
index 0000000000..6ea096bcef
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.c
@@ -0,0 +1,129 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/IoLib.h>
+#include <Library/OmapLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/EmbeddedGpio.h>
+
+#include <Omap3530/Omap3530.h>
+
+EFI_STATUS
+Get (
+  IN  EMBEDDED_GPIO     *This,
+  IN  EMBEDDED_GPIO_PIN Gpio,
+  OUT UINTN               *Value
+  )
+{
+  UINTN  Port;
+  UINTN  Pin;
+  UINT32 DataInRegister;
+
+  if (Value == NULL)
+  {
+    return EFI_UNSUPPORTED;
+  }
+
+  Port    = GPIO_PORT(Gpio);
+  Pin     = GPIO_PIN(Gpio);
+
+  DataInRegister = GpioBase(Port) + GPIO_DATAIN;
+
+  if (MmioRead32 (DataInRegister) & GPIO_DATAIN_MASK(Pin)) {
+    *Value = 1;
+  } else {
+    *Value = 0;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+Set (
+  IN  EMBEDDED_GPIO       *This,
+  IN  EMBEDDED_GPIO_PIN   Gpio,
+  IN  EMBEDDED_GPIO_MODE  Mode
+  )
+{
+  UINTN  Port;
+  UINTN  Pin;
+  UINT32 OutputEnableRegister;
+  UINT32 SetDataOutRegister;
+  UINT32 ClearDataOutRegister;
+
+  Port    = GPIO_PORT(Gpio);
+  Pin     = GPIO_PIN(Gpio);
+
+  OutputEnableRegister = GpioBase(Port) + GPIO_OE;
+  SetDataOutRegister   = GpioBase(Port) + GPIO_SETDATAOUT;
+  ClearDataOutRegister = GpioBase(Port) + GPIO_CLEARDATAOUT;
+
+  switch (Mode)
+  {
+    case GPIO_MODE_INPUT:
+      MmioAndThenOr32(OutputEnableRegister, ~GPIO_OE_MASK(Pin), GPIO_OE_INPUT(Pin));
+      break;
+
+    case GPIO_MODE_OUTPUT_0:
+      MmioWrite32 (ClearDataOutRegister, GPIO_CLEARDATAOUT_BIT(Pin));
+      MmioAndThenOr32(OutputEnableRegister, ~GPIO_OE_MASK(Pin), GPIO_OE_OUTPUT(Pin));
+      break;
+
+    case GPIO_MODE_OUTPUT_1:
+      MmioWrite32 (SetDataOutRegister, GPIO_SETDATAOUT_BIT(Pin));
+      MmioAndThenOr32(OutputEnableRegister, ~GPIO_OE_MASK(Pin), GPIO_OE_OUTPUT(Pin));
+      break;
+
+    default:
+      return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetMode (
+  IN  EMBEDDED_GPIO       *This,
+  IN  EMBEDDED_GPIO_PIN   Gpio,
+  OUT EMBEDDED_GPIO_MODE  *Mode
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+SetPull (
+  IN  EMBEDDED_GPIO       *This,
+  IN  EMBEDDED_GPIO_PIN   Gpio,
+  IN  EMBEDDED_GPIO_PULL  Direction
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+EMBEDDED_GPIO Gpio = {
+  Get,
+  Set,
+  GetMode,
+  SetPull
+};
+
+EFI_STATUS
+GpioInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = gBS->InstallMultipleProtocolInterfaces(&ImageHandle, &gEmbeddedGpioProtocolGuid, &Gpio, NULL);
+  return Status;
+}
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.inf b/Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.inf
new file mode 100644
index 0000000000..16850a3e66
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.inf
@@ -0,0 +1,39 @@
+#/** @file
+#
+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = Gpio
+  FILE_GUID                      = E7D9CAE1-6930-46E3-BDF9-0027446E7DF2
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = GpioInitialize
+
+
+[Sources.common]
+  Gpio.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[LibraryClasses]
+  IoLib
+  UefiDriverEntryPoint
+  OmapLib
+
+[Guids]
+
+[Protocols]
+  gEmbeddedGpioProtocolGuid
+
+[Pcd]
+
+[depex]
+  TRUE
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapDmaLib.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapDmaLib.h
new file mode 100644
index 0000000000..21987d0e6b
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapDmaLib.h
@@ -0,0 +1,84 @@
+/** @file
+
+  Abstractions for simple OMAP DMA.
+  OMAP_DMA4 structure elements are described in the OMAP35xx TRM.
+
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP_DMA_LIB_H__
+#define __OMAP_DMA_LIB_H__
+
+
+// Example from DMA chapter of the OMAP35xx spec
+typedef struct {
+  UINT8     DataType;                      // DMA4_CSDPi[1:0]
+  UINT8     ReadPortAccessType;            // DMA4_CSDPi[8:7]
+  UINT8     WritePortAccessType;           // DMA4_CSDPi[15:14]
+  UINT8     SourceEndiansim;               // DMA4_CSDPi[21]
+  UINT8     DestinationEndianism;          // DMA4_CSDPi[19]
+  UINT8     WriteMode;                     // DMA4_CSDPi[17:16]
+  UINT8     SourcePacked;                  // DMA4_CSDPi[6]
+  UINT8     DestinationPacked;             // DMA4_CSDPi[13]
+  UINT32    NumberOfElementPerFrame;       // DMA4_CENi
+  UINT32    NumberOfFramePerTransferBlock; // DMA4_CFNi
+  UINT32    SourceStartAddress;            // DMA4_CSSAi
+  UINT32    DestinationStartAddress;       // DMA4_CDSAi
+  UINT32    SourceElementIndex;            // DMA4_CSEi
+  UINT32    SourceFrameIndex;              // DMA4_CSFi
+  UINT32    DestinationElementIndex;       // DMA4_CDEi
+  UINT32    DestinationFrameIndex;         // DMA4_CDFi
+  UINT8     ReadPortAccessMode;            // DMA4_CCRi[13:12]
+  UINT8     WritePortAccessMode;           // DMA4_CCRi[15:14]
+  UINT8     ReadPriority;                  // DMA4_CCRi[6]
+  UINT8     WritePriority;                 // DMA4_CCRi[23]
+  UINT8     ReadRequestNumber;             // DMA4_CCRi[4:0]
+  UINT8     WriteRequestNumber;            // DMA4_CCRi[20:19]
+} OMAP_DMA4;
+
+
+/**
+  Configure OMAP DMA Channel
+
+  @param  Channel               DMA Channel to configure
+  @param  Dma4                  Pointer to structure used to initialize DMA registers for the Channel
+
+  @retval EFI_SUCCESS           The range was mapped for the returned NumberOfBytes.
+  @retval EFI_INVALID_PARAMETER Channel is not valid
+  @retval EFI_DEVICE_ERROR      The system hardware could not map the requested information.
+
+**/
+EFI_STATUS
+EFIAPI
+EnableDmaChannel (
+  IN  UINTN       Channel,
+  IN  OMAP_DMA4   *Dma4
+  );
+
+/**
+  Turn of DMA channel configured by EnableDma().
+
+  @param  Channel               DMA Channel to configure
+  @param  SuccesMask            Bits in DMA4_CSR register indicate EFI_SUCCESS
+  @param  ErrorMask             Bits in DMA4_CSR register indicate EFI_DEVICE_ERROR
+
+  @retval EFI_SUCCESS           DMA hardware disabled
+  @retval EFI_INVALID_PARAMETER Channel is not valid
+  @retval EFI_DEVICE_ERROR      The system hardware could not map the requested information.
+
+**/
+EFI_STATUS
+EFIAPI
+DisableDmaChannel (
+  IN  UINTN       Channel,
+  IN  UINT32      SuccessMask,
+  IN  UINT32      ErrorMask
+  );
+
+
+
+#endif
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapLib.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapLib.h
new file mode 100644
index 0000000000..e92a5aee4b
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapLib.h
@@ -0,0 +1,38 @@
+/** @file
+
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAPLIB_H__
+#define __OMAPLIB_H__
+
+UINT32
+EFIAPI
+GpioBase (
+  IN  UINTN Port
+  );
+
+UINT32
+EFIAPI
+TimerBase (
+  IN  UINTN Timer
+  );
+
+UINTN
+EFIAPI
+InterruptVectorForTimer (
+  IN  UINTN TImer
+  );
+
+UINT32
+EFIAPI
+UartBase (
+  IN  UINTN Uart
+  );
+
+
+#endif // __OMAPLIB_H__
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530.h
new file mode 100644
index 0000000000..1658d597ff
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530.h
@@ -0,0 +1,34 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530_H__
+#define __OMAP3530_H__
+
+#include "Omap3530Gpio.h"
+#include "Omap3530Interrupt.h"
+#include "Omap3530Prcm.h"
+#include "Omap3530Timer.h"
+#include "Omap3530Uart.h"
+#include "Omap3530Usb.h"
+#include "Omap3530MMCHS.h"
+#include "Omap3530I2c.h"
+#include "Omap3530PadConfiguration.h"
+#include "Omap3530Gpmc.h"
+#include "Omap3530Dma.h"
+
+
+//CONTROL_PBIAS_LITE
+#define CONTROL_PBIAS_LITE    0x48002520
+#define PBIASLITEVMODE0       BIT0
+#define PBIASLITEPWRDNZ0      BIT1
+#define PBIASSPEEDCTRL0       BIT2
+#define PBIASLITEVMODE1       BIT8
+#define PBIASLITEWRDNZ1       BIT9
+
+#endif // __OMAP3530_H__
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Dma.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Dma.h
new file mode 100644
index 0000000000..c04fb7f70a
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Dma.h
@@ -0,0 +1,124 @@
+/** @file
+
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530DMA_H__
+#define __OMAP3530DMA_H__
+
+
+#define DMA4_MAX_CHANNEL 31
+
+#define DMA4_IRQENABLE_L(_i)  (0x48056018 + (0x4*(_i)))
+
+#define DMA4_CCR(_i)  (0x48056080 + (0x60*(_i)))
+#define DMA4_CICR(_i) (0x48056088 + (0x60*(_i)))
+#define DMA4_CSR(_i)  (0x4805608c + (0x60*(_i)))
+#define DMA4_CSDP(_i) (0x48056090 + (0x60*(_i)))
+#define DMA4_CEN(_i)  (0x48056094 + (0x60*(_i)))
+#define DMA4_CFN(_i)  (0x48056098 + (0x60*(_i)))
+#define DMA4_CSSA(_i) (0x4805609c + (0x60*(_i)))
+#define DMA4_CDSA(_i) (0x480560a0 + (0x60*(_i)))
+#define DMA4_CSEI(_i) (0x480560a4 + (0x60*(_i)))
+#define DMA4_CSFI(_i) (0x480560a8 + (0x60*(_i)))
+#define DMA4_CDEI(_i) (0x480560ac + (0x60*(_i)))
+#define DMA4_CDFI(_i) (0x480560b0 + (0x60*(_i)))
+
+#define DMA4_GCR      (0x48056078)
+
+// Channel Source Destination parameters
+#define DMA4_CSDP_DATA_TYPE8    0
+#define DMA4_CSDP_DATA_TYPE16   1
+#define DMA4_CSDP_DATA_TYPE32   2
+
+#define DMA4_CSDP_SRC_PACKED      BIT6
+#define DMA4_CSDP_SRC_NONPACKED   0
+
+#define DMA4_CSDP_SRC_BURST_EN    (0x0 << 7)
+#define DMA4_CSDP_SRC_BURST_EN16  (0x1 << 7)
+#define DMA4_CSDP_SRC_BURST_EN32  (0x2 << 7)
+#define DMA4_CSDP_SRC_BURST_EN64  (0x3 << 7)
+
+#define DMA4_CSDP_DST_PACKED      BIT13
+#define DMA4_CSDP_DST_NONPACKED   0
+
+#define DMA4_CSDP_BURST_EN        (0x0 << 14)
+#define DMA4_CSDP_BURST_EN16      (0x1 << 14)
+#define DMA4_CSDP_BURST_EN32      (0x2 << 14)
+#define DMA4_CSDP_BURST_EN64      (0x3 << 14)
+
+#define DMA4_CSDP_WRITE_MODE_NONE_POSTED      (0x0 << 16)
+#define DMA4_CSDP_WRITE_MODE_POSTED           (0x1 << 16)
+#define DMA4_CSDP_WRITE_MODE_LAST_NON_POSTED  (0x2 << 16)
+
+#define DMA4_CSDP_DST_ENDIAN_LOCK_LOCK    BIT18
+#define DMA4_CSDP_DST_ENDIAN_LOCK_ADAPT   0
+
+#define DMA4_CSDP_DST_ENDIAN_BIG          BIT19
+#define DMA4_CSDP_DST_ENDIAN_LITTLE       0
+
+#define DMA4_CSDP_SRC_ENDIAN_LOCK_LOCK    BIT20
+#define DMA4_CSDP_SRC_ENDIAN_LOCK_ADAPT   0
+
+#define DMA4_CSDP_SRC_ENDIAN_BIG          BIT21
+#define DMA4_CSDP_SRC_ENDIAN_LITTLE       0
+
+// Channel Control
+#define DMA4_CCR_SYNCHRO_CONTROL_MASK     0x1f
+
+#define DMA4_CCR_FS_ELEMENT     (0    | 0)
+#define DMA4_CCR_FS_BLOCK       (0    | BIT18)
+#define DMA4_CCR_FS_FRAME       (BIT5 | 0)
+#define DMA4_CCR_FS_PACKET      (BIT5 | BIT18)
+
+#define DMA4_CCR_READ_PRIORITY_HIGH   BIT6
+#define DMA4_CCR_READ_PRIORITY_LOW    0
+
+#define DMA4_CCR_ENABLE               BIT7
+#define DMA4_CCR_DISABLE              0
+
+#define DMA4_CCR_SUSPEND_SENSITIVE_IGNORE BIT8
+#define DMA4_CCR_SUSPEND_SENSITIVE        0
+
+#define DMA4_CCR_RD_ACTIVE                BIT9
+#define DMA4_CCR_WR_ACTIVE                BIT10
+
+#define DMA4_CCR_SRC_AMODE                (0     | 0)
+#define DMA4_CCR_SRC_AMODE_POST_INC       (0     | BIT12)
+#define DMA4_CCR_SRC_AMODE_SINGLE_INDEX   (BIT13 | 0)
+#define DMA4_CCR_SRC_AMODE_DOUBLE_INDEX   (BIT13 | BIT12)
+
+#define DMA4_CCR_DST_AMODE                (0     | 0)
+#define DMA4_CCR_DST_AMODE_POST_INC       (0     | BIT14)
+#define DMA4_CCR_DST_AMODE_SINGLE_INDEX   (BIT15 | 0)
+#define DMA4_CCR_DST_AMODE_DOUBLE_INDEX   (BIT15 | BIT14)
+
+#define DMA4_CCR_CONST_FILL_ENABLE        BIT16
+#define DMA4_CCR_TRANSPARENT_COPY_ENABLE  BIT17
+
+#define DMA4_CCR_SEL_SRC_DEST_SYNC_SOURCE BIT24
+
+#define DMA4_CSR_DROP                     BIT1
+#define DMA4_CSR_HALF                     BIT2
+#define DMA4_CSR_FRAME                    BIT3
+#define DMA4_CSR_LAST                     BIT4
+#define DMA4_CSR_BLOCK                    BIT5
+#define DMA4_CSR_SYNC                     BIT6
+#define DMA4_CSR_PKT                      BIT7
+#define DMA4_CSR_TRANS_ERR                BIT8
+#define DMA4_CSR_SECURE_ERR               BIT9
+#define DMA4_CSR_SUPERVISOR_ERR           BIT10
+#define DMA4_CSR_MISALIGNED_ADRS_ERR      BIT11
+#define DMA4_CSR_DRAIN_END                BIT12
+#define DMA4_CSR_RESET                    0x1FE
+#define DMA4_CSR_ERR                      (DMA4_CSR_TRANS_ERR | DMA4_CSR_SECURE_ERR | DMA4_CSR_SUPERVISOR_ERR | DMA4_CSR_MISALIGNED_ADRS_ERR)
+
+// same mapping as CSR except for SYNC. Enable all since we are polling
+#define DMA4_CICR_ENABLE_ALL              0x1FBE
+
+
+#endif
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpio.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpio.h
new file mode 100644
index 0000000000..51ccd17146
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpio.h
@@ -0,0 +1,125 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530GPIO_H__
+#define __OMAP3530GPIO_H__
+
+#define GPIO1_BASE (0x48310000)
+#define GPIO2_BASE (0x49050000)
+#define GPIO3_BASE (0x49052000)
+#define GPIO4_BASE (0x49054000)
+#define GPIO5_BASE (0x49056000)
+#define GPIO6_BASE (0x49058000)
+
+#define GPIO_SYSCONFIG        (0x0010)
+#define GPIO_SYSSTATUS        (0x0014)
+#define GPIO_IRQSTATUS1       (0x0018)
+#define GPIO_IRQENABLE1       (0x001C)
+#define GPIO_WAKEUPENABLE     (0x0020)
+#define GPIO_IRQSTATUS2       (0x0028)
+#define GPIO_IRQENABLE2       (0x002C)
+#define GPIO_CTRL             (0x0030)
+#define GPIO_OE               (0x0034)
+#define GPIO_DATAIN           (0x0038)
+#define GPIO_DATAOUT          (0x003C)
+#define GPIO_LEVELDETECT0     (0x0040)
+#define GPIO_LEVELDETECT1     (0x0044)
+#define GPIO_RISINGDETECT     (0x0048)
+#define GPIO_FALLINGDETECT    (0x004C)
+#define GPIO_DEBOUNCENABLE    (0x0050)
+#define GPIO_DEBOUNCINGTIME   (0x0054)
+#define GPIO_CLEARIRQENABLE1  (0x0060)
+#define GPIO_SETIRQENABLE1    (0x0064)
+#define GPIO_CLEARIRQENABLE2  (0x0070)
+#define GPIO_SETIRQENABLE2    (0x0074)
+#define GPIO_CLEARWKUENA      (0x0080)
+#define GPIO_SETWKUENA        (0x0084)
+#define GPIO_CLEARDATAOUT     (0x0090)
+#define GPIO_SETDATAOUT       (0x0094)
+
+#define GPIO_SYSCONFIG_IDLEMODE_MASK      (3UL << 3)
+#define GPIO_SYSCONFIG_IDLEMODE_FORCE     (0UL << 3)
+#define GPIO_SYSCONFIG_IDLEMODE_NONE      BIT3
+#define GPIO_SYSCONFIG_IDLEMODE_SMART     (2UL << 3)
+#define GPIO_SYSCONFIG_ENAWAKEUP_MASK     BIT2
+#define GPIO_SYSCONFIG_ENAWAKEUP_DISABLE  (0UL << 2)
+#define GPIO_SYSCONFIG_ENAWAKEUP_ENABLE   BIT2
+#define GPIO_SYSCONFIG_SOFTRESET_MASK     BIT1
+#define GPIO_SYSCONFIG_SOFTRESET_NORMAL   (0UL << 1)
+#define GPIO_SYSCONFIG_SOFTRESET_RESET    BIT1
+#define GPIO_SYSCONFIG_AUTOIDLE_MASK      BIT0
+#define GPIO_SYSCONFIG_AUTOIDLE_FREE_RUN  (0UL << 0)
+#define GPIO_SYSCONFIG_AUTOIDLE_ON        BIT0
+
+#define GPIO_SYSSTATUS_RESETDONE_MASK     BIT0
+#define GPIO_SYSSTATUS_RESETDONE_ONGOING  (0UL << 0)
+#define GPIO_SYSSTATUS_RESETDONE_COMPLETE BIT0
+
+#define GPIO_IRQSTATUS_MASK(x)            (1UL << (x))
+#define GPIO_IRQSTATUS_NOT_TRIGGERED(x)   (0UL << (x))
+#define GPIO_IRQSTATUS_TRIGGERED(x)       (1UL << (x))
+#define GPIO_IRQSTATUS_CLEAR(x)           (1UL << (x))
+
+#define GPIO_IRQENABLE_MASK(x)            (1UL << (x))
+#define GPIO_IRQENABLE_DISABLE(x)         (0UL << (x))
+#define GPIO_IRQENABLE_ENABLE(x)          (1UL << (x))
+
+#define GPIO_WAKEUPENABLE_MASK(x)         (1UL << (x))
+#define GPIO_WAKEUPENABLE_DISABLE(x)      (0UL << (x))
+#define GPIO_WAKEUPENABLE_ENABLE(x)       (1UL << (x))
+
+#define GPIO_CTRL_GATINGRATIO_MASK        (3UL << 1)
+#define GPIO_CTRL_GATINGRATIO_DIV_1       (0UL << 1)
+#define GPIO_CTRL_GATINGRATIO_DIV_2       BIT1
+#define GPIO_CTRL_GATINGRATIO_DIV_4       (2UL << 1)
+#define GPIO_CTRL_GATINGRATIO_DIV_8       (3UL << 1)
+#define GPIO_CTRL_DISABLEMODULE_MASK      BIT0
+#define GPIO_CTRL_DISABLEMODULE_ENABLE    (0UL << 0)
+#define GPIO_CTRL_DISABLEMODULE_DISABLE   BIT0
+
+#define GPIO_OE_MASK(x)                   (1UL << (x))
+#define GPIO_OE_OUTPUT(x)                 (0UL << (x))
+#define GPIO_OE_INPUT(x)                  (1UL << (x))
+
+#define GPIO_DATAIN_MASK(x)               (1UL << (x))
+
+#define GPIO_DATAOUT_MASK(x)              (1UL << (x))
+
+#define GPIO_LEVELDETECT_MASK(x)          (1UL << (x))
+#define GPIO_LEVELDETECT_DISABLE(x)       (0UL << (x))
+#define GPIO_LEVELDETECT_ENABLE(x)        (1UL << (x))
+
+#define GPIO_RISINGDETECT_MASK(x)         (1UL << (x))
+#define GPIO_RISINGDETECT_DISABLE(x)      (0UL << (x))
+#define GPIO_RISINGDETECT_ENABLE(x)       (1UL << (x))
+
+#define GPIO_FALLINGDETECT_MASK(x)        (1UL << (x))
+#define GPIO_FALLINGDETECT_DISABLE(x)     (0UL << (x))
+#define GPIO_FALLINGDETECT_ENABLE(x)      (1UL << (x))
+
+#define GPIO_DEBOUNCENABLE_MASK(x)        (1UL << (x))
+#define GPIO_DEBOUNCENABLE_DISABLE(x)     (0UL << (x))
+#define GPIO_DEBOUNCENABLE_ENABLE(x)      (1UL << (x))
+
+#define GPIO_DEBOUNCINGTIME_MASK          (0xFF)
+#define GPIO_DEBOUNCINGTIME_US(x)         ((((x) / 31) - 1) & GPIO_DEBOUNCINGTIME_MASK)
+
+#define GPIO_CLEARIRQENABLE_BIT(x)        (1UL << (x))
+
+#define GPIO_SETIRQENABLE_BIT(x)          (1UL << (x))
+
+#define GPIO_CLEARWKUENA_BIT(x)           (1UL << (x))
+
+#define GPIO_SETWKUENA_BIT(x)             (1UL << (x))
+
+#define GPIO_CLEARDATAOUT_BIT(x)          (1UL << (x))
+
+#define GPIO_SETDATAOUT_BIT(x)            (1UL << (x))
+
+#endif // __OMAP3530GPIO_H__
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpmc.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpmc.h
new file mode 100644
index 0000000000..4465b4fa2b
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpmc.h
@@ -0,0 +1,101 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530GPMC_H__
+#define __OMAP3530GPMC_H__
+
+#define GPMC_BASE             (0x6E000000)
+
+//GPMC NAND definitions.
+#define GPMC_SYSCONFIG        (GPMC_BASE + 0x10)
+#define SMARTIDLEMODE         (0x2UL << 3)
+
+#define GPMC_SYSSTATUS        (GPMC_BASE + 0x14)
+#define GPMC_IRQSTATUS        (GPMC_BASE + 0x18)
+#define GPMC_IRQENABLE        (GPMC_BASE + 0x1C)
+
+#define GPMC_TIMEOUT_CONTROL  (GPMC_BASE + 0x40)
+#define TIMEOUTENABLE         BIT0
+#define TIMEOUTDISABLE        (0x0UL << 0)
+
+#define GPMC_ERR_ADDRESS      (GPMC_BASE + 0x44)
+#define GPMC_ERR_TYPE         (GPMC_BASE + 0x48)
+
+#define GPMC_CONFIG           (GPMC_BASE + 0x50)
+#define WRITEPROTECT_HIGH     BIT4
+#define WRITEPROTECT_LOW      (0x0UL << 4)
+
+#define GPMC_STATUS           (GPMC_BASE + 0x54)
+
+#define GPMC_CONFIG1_0        (GPMC_BASE + 0x60)
+#define DEVICETYPE_NOR        (0x0UL << 10)
+#define DEVICETYPE_NAND       (0x2UL << 10)
+#define DEVICESIZE_X8         (0x0UL << 12)
+#define DEVICESIZE_X16        BIT12
+
+#define GPMC_CONFIG2_0        (GPMC_BASE + 0x64)
+#define CSONTIME              (0x0UL << 0)
+#define CSRDOFFTIME           (0x14UL << 8)
+#define CSWROFFTIME           (0x14UL << 16)
+
+#define GPMC_CONFIG3_0        (GPMC_BASE + 0x68)
+#define ADVRDOFFTIME          (0x14UL << 8)
+#define ADVWROFFTIME          (0x14UL << 16)
+
+#define GPMC_CONFIG4_0        (GPMC_BASE + 0x6C)
+#define OEONTIME              BIT0
+#define OEOFFTIME             (0xFUL << 8)
+#define WEONTIME              BIT16
+#define WEOFFTIME             (0xFUL << 24)
+
+#define GPMC_CONFIG5_0        (GPMC_BASE + 0x70)
+#define RDCYCLETIME           (0x14UL << 0)
+#define WRCYCLETIME           (0x14UL << 8)
+#define RDACCESSTIME          (0xCUL << 16)
+#define PAGEBURSTACCESSTIME   BIT24
+
+#define GPMC_CONFIG6_0        (GPMC_BASE + 0x74)
+#define CYCLE2CYCLESAMECSEN   BIT7
+#define CYCLE2CYCLEDELAY      (0xAUL << 8)
+#define WRDATAONADMUXBUS      (0xFUL << 16)
+#define WRACCESSTIME          BIT24
+
+#define GPMC_CONFIG7_0        (GPMC_BASE + 0x78)
+#define BASEADDRESS           (0x30UL << 0)
+#define CSVALID               BIT6
+#define MASKADDRESS_128MB     (0x8UL << 8)
+
+#define GPMC_NAND_COMMAND_0   (GPMC_BASE + 0x7C)
+#define GPMC_NAND_ADDRESS_0   (GPMC_BASE + 0x80)
+#define GPMC_NAND_DATA_0      (GPMC_BASE + 0x84)
+
+#define GPMC_ECC_CONFIG       (GPMC_BASE + 0x1F4)
+#define ECCENABLE             BIT0
+#define ECCDISABLE            (0x0UL << 0)
+#define ECCCS_0               (0x0UL << 1)
+#define ECC16B                BIT7
+
+#define GPMC_ECC_CONTROL      (GPMC_BASE + 0x1F8)
+#define ECCPOINTER_REG1       BIT0
+#define ECCCLEAR              BIT8
+
+#define GPMC_ECC_SIZE_CONFIG  (GPMC_BASE + 0x1FC)
+#define ECCSIZE0_512BYTES     (0xFFUL << 12)
+#define ECCSIZE1_512BYTES     (0xFFUL << 22)
+
+#define GPMC_ECC1_RESULT      (GPMC_BASE + 0x200)
+#define GPMC_ECC2_RESULT      (GPMC_BASE + 0x204)
+#define GPMC_ECC3_RESULT      (GPMC_BASE + 0x208)
+#define GPMC_ECC4_RESULT      (GPMC_BASE + 0x20C)
+#define GPMC_ECC5_RESULT      (GPMC_BASE + 0x210)
+#define GPMC_ECC6_RESULT      (GPMC_BASE + 0x214)
+#define GPMC_ECC7_RESULT      (GPMC_BASE + 0x218)
+#define GPMC_ECC8_RESULT      (GPMC_BASE + 0x21C)
+#define GPMC_ECC9_RESULT      (GPMC_BASE + 0x220)
+
+#endif //__OMAP3530GPMC_H__
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530I2c.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530I2c.h
new file mode 100644
index 0000000000..e91f421b80
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530I2c.h
@@ -0,0 +1,56 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530I2C_H__
+#define __OMAP3530I2C_H__
+
+//I2C register definitions.
+#define I2C1BASE        0x48070000
+
+#define I2C_IE          (I2C1BASE + 0x4)
+#define XRDY_IE         BIT4
+#define RRDY_IE         BIT3
+#define ARDY_IE         BIT2
+#define NACK_IE         BIT1
+
+#define I2C_STAT        (I2C1BASE + 0x8)
+#define BB              BIT12
+#define XRDY            BIT4
+#define RRDY            BIT3
+#define ARDY            BIT2
+#define NACK            BIT1
+
+#define I2C_WE          (I2C1BASE + 0xC)
+#define I2C_SYSS        (I2C1BASE + 0x10)
+#define I2C_BUF         (I2C1BASE + 0x14)
+#define I2C_CNT         (I2C1BASE + 0x18)
+#define I2C_DATA        (I2C1BASE + 0x1C)
+#define I2C_SYSC        (I2C1BASE + 0x20)
+
+#define I2C_CON         (I2C1BASE + 0x24)
+#define STT             BIT0
+#define STP             BIT1
+#define XSA             BIT8
+#define TRX             BIT9
+#define MST             BIT10
+#define I2C_EN          BIT15
+
+#define I2C_OA0         (I2C1BASE + 0x28)
+#define I2C_SA          (I2C1BASE + 0x2C)
+#define I2C_PSC         (I2C1BASE + 0x30)
+#define I2C_SCLL        (I2C1BASE + 0x34)
+#define I2C_SCLH        (I2C1BASE + 0x38)
+#define I2C_SYSTEST     (I2C1BASE + 0x3C)
+#define I2C_BUFSTAT     (I2C1BASE + 0x40)
+#define I2C_OA1         (I2C1BASE + 0x44)
+#define I2C_OA2         (I2C1BASE + 0x48)
+#define I2C_OA3         (I2C1BASE + 0x4C)
+#define I2C_ACTOA       (I2C1BASE + 0x50)
+#define I2C_SBLOCK      (I2C1BASE + 0x54)
+
+#endif //__OMAP3530I2C_H__
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Interrupt.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Interrupt.h
new file mode 100644
index 0000000000..20339e2bd5
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Interrupt.h
@@ -0,0 +1,45 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530INTERRUPT_H__
+#define __OMAP3530INTERRUPT_H__
+
+#include <Library/PcdLib.h>
+
+#define INTERRUPT_BASE        (PcdGet32 (PcdInterruptBaseAddress))
+
+#define INT_NROF_VECTORS      (96)
+#define MAX_VECTOR            (INT_NROF_VECTORS - 1)
+#define INTCPS_SYSCONFIG      (INTERRUPT_BASE + 0x0010)
+#define INTCPS_SYSSTATUS      (INTERRUPT_BASE + 0x0014)
+#define INTCPS_SIR_IRQ        (INTERRUPT_BASE + 0x0040)
+#define INTCPS_SIR_IFQ        (INTERRUPT_BASE + 0x0044)
+#define INTCPS_CONTROL        (INTERRUPT_BASE + 0x0048)
+#define INTCPS_PROTECTION     (INTERRUPT_BASE + 0x004C)
+#define INTCPS_IDLE           (INTERRUPT_BASE + 0x0050)
+#define INTCPS_IRQ_PRIORITY   (INTERRUPT_BASE + 0x0060)
+#define INTCPS_FIQ_PRIORITY   (INTERRUPT_BASE + 0x0064)
+#define INTCPS_THRESHOLD      (INTERRUPT_BASE + 0x0068)
+#define INTCPS_ITR(n)         (INTERRUPT_BASE + 0x0080 + (0x20 * (n)))
+#define INTCPS_MIR(n)         (INTERRUPT_BASE + 0x0084 + (0x20 * (n)))
+#define INTCPS_MIR_CLEAR(n)   (INTERRUPT_BASE + 0x0088 + (0x20 * (n)))
+#define INTCPS_MIR_SET(n)     (INTERRUPT_BASE + 0x008C + (0x20 * (n)))
+#define INTCPS_ISR_SET(n)     (INTERRUPT_BASE + 0x0090 + (0x20 * (n)))
+#define INTCPS_ISR_CLEAR(n)   (INTERRUPT_BASE + 0x0094 + (0x20 * (n)))
+#define INTCPS_PENDING_IRQ(n) (INTERRUPT_BASE + 0x0098 + (0x20 * (n)))
+#define INTCPS_PENDING_FIQ(n) (INTERRUPT_BASE + 0x009C + (0x20 * (n)))
+#define INTCPS_ILR(m)         (INTERRUPT_BASE + 0x0100 + (0x04 * (m)))
+
+#define INTCPS_ILR_FIQ            BIT0
+#define INTCPS_SIR_IRQ_MASK       (0x7F)
+#define INTCPS_CONTROL_NEWIRQAGR  BIT0
+#define INTCPS_CONTROL_NEWFIQAGR  BIT1
+
+#endif // __OMAP3530INTERRUPT_H__
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530MMCHS.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530MMCHS.h
new file mode 100644
index 0000000000..1819ff5031
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530MMCHS.h
@@ -0,0 +1,208 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530SDIO_H__
+#define __OMAP3530SDIO_H__
+
+//MMC/SD/SDIO1 register definitions.
+#define MMCHS1BASE        0x4809C000
+#define MMC_REFERENCE_CLK (96000000)
+
+#define MMCHS_SYSCONFIG   (MMCHS1BASE + 0x10)
+#define SOFTRESET         BIT1
+#define ENAWAKEUP         BIT2
+
+#define MMCHS_SYSSTATUS   (MMCHS1BASE + 0x14)
+#define RESETDONE_MASK    BIT0
+#define RESETDONE         BIT0
+
+#define MMCHS_CSRE        (MMCHS1BASE + 0x24)
+#define MMCHS_SYSTEST     (MMCHS1BASE + 0x28)
+
+#define MMCHS_CON         (MMCHS1BASE + 0x2C)
+#define OD                BIT0
+#define NOINIT            (0x0UL << 1)
+#define INIT              BIT1
+#define HR                BIT2
+#define STR               BIT3
+#define MODE              BIT4
+#define DW8_1_4_BIT       (0x0UL << 5)
+#define DW8_8_BIT         BIT5
+#define MIT               BIT6
+#define CDP               BIT7
+#define WPP               BIT8
+#define CTPL              BIT11
+#define CEATA_OFF         (0x0UL << 12)
+#define CEATA_ON          BIT12
+
+#define MMCHS_PWCNT       (MMCHS1BASE + 0x30)
+
+#define MMCHS_BLK         (MMCHS1BASE + 0x104)
+#define BLEN_512BYTES     (0x200UL << 0)
+
+#define MMCHS_ARG         (MMCHS1BASE + 0x108)
+
+#define MMCHS_CMD         (MMCHS1BASE + 0x10C)
+#define DE_ENABLE         BIT0
+#define BCE_ENABLE        BIT1
+#define ACEN_ENABLE       BIT2
+#define DDIR_READ         BIT4
+#define DDIR_WRITE        (0x0UL << 4)
+#define MSBS_SGLEBLK      (0x0UL << 5)
+#define MSBS_MULTBLK      BIT5
+#define RSP_TYPE_MASK     (0x3UL << 16)
+#define RSP_TYPE_136BITS  BIT16
+#define RSP_TYPE_48BITS   (0x2UL << 16)
+#define CCCE_ENABLE       BIT19
+#define CICE_ENABLE       BIT20
+#define DP_ENABLE         BIT21
+#define INDX(CMD_INDX)    ((CMD_INDX & 0x3F) << 24)
+
+#define MMCHS_RSP10       (MMCHS1BASE + 0x110)
+#define MMCHS_RSP32       (MMCHS1BASE + 0x114)
+#define MMCHS_RSP54       (MMCHS1BASE + 0x118)
+#define MMCHS_RSP76       (MMCHS1BASE + 0x11C)
+#define MMCHS_DATA        (MMCHS1BASE + 0x120)
+
+#define MMCHS_PSTATE      (MMCHS1BASE + 0x124)
+#define CMDI_MASK         BIT0
+#define CMDI_ALLOWED      (0x0UL << 0)
+#define CMDI_NOT_ALLOWED  BIT0
+#define DATI_MASK         BIT1
+#define DATI_ALLOWED      (0x0UL << 1)
+#define DATI_NOT_ALLOWED  BIT1
+
+#define MMCHS_HCTL        (MMCHS1BASE + 0x128)
+#define DTW_1_BIT         (0x0UL << 1)
+#define DTW_4_BIT         BIT1
+#define SDBP_MASK         BIT8
+#define SDBP_OFF          (0x0UL << 8)
+#define SDBP_ON           BIT8
+#define SDVS_1_8_V        (0x5UL << 9)
+#define SDVS_3_0_V        (0x6UL << 9)
+#define IWE               BIT24
+
+#define MMCHS_SYSCTL      (MMCHS1BASE + 0x12C)
+#define ICE               BIT0
+#define ICS_MASK          BIT1
+#define ICS               BIT1
+#define CEN               BIT2
+#define CLKD_MASK         (0x3FFUL << 6)
+#define CLKD_80KHZ        (0x258UL) //(96*1000/80)/2
+#define CLKD_400KHZ       (0xF0UL)
+#define DTO_MASK          (0xFUL << 16)
+#define DTO_VAL           (0xEUL << 16)
+#define SRA               BIT24
+#define SRC_MASK          BIT25
+#define SRC               BIT25
+#define SRD               BIT26
+
+#define MMCHS_STAT        (MMCHS1BASE + 0x130)
+#define CC                BIT0
+#define TC                BIT1
+#define BWR               BIT4
+#define BRR               BIT5
+#define ERRI              BIT15
+#define CTO               BIT16
+#define DTO               BIT20
+#define DCRC              BIT21
+#define DEB               BIT22
+
+#define MMCHS_IE          (MMCHS1BASE + 0x134)
+#define CC_EN             BIT0
+#define TC_EN             BIT1
+#define BWR_EN            BIT4
+#define BRR_EN            BIT5
+#define CTO_EN            BIT16
+#define CCRC_EN           BIT17
+#define CEB_EN            BIT18
+#define CIE_EN            BIT19
+#define DTO_EN            BIT20
+#define DCRC_EN           BIT21
+#define DEB_EN            BIT22
+#define CERR_EN           BIT28
+#define BADA_EN           BIT29
+
+#define MMCHS_ISE         (MMCHS1BASE + 0x138)
+#define CC_SIGEN          BIT0
+#define TC_SIGEN          BIT1
+#define BWR_SIGEN         BIT4
+#define BRR_SIGEN         BIT5
+#define CTO_SIGEN         BIT16
+#define CCRC_SIGEN        BIT17
+#define CEB_SIGEN         BIT18
+#define CIE_SIGEN         BIT19
+#define DTO_SIGEN         BIT20
+#define DCRC_SIGEN        BIT21
+#define DEB_SIGEN         BIT22
+#define CERR_SIGEN        BIT28
+#define BADA_SIGEN        BIT29
+
+#define MMCHS_AC12        (MMCHS1BASE + 0x13C)
+
+#define MMCHS_CAPA        (MMCHS1BASE + 0x140)
+#define VS30              BIT25
+#define VS18              BIT26
+
+#define MMCHS_CUR_CAPA    (MMCHS1BASE + 0x148)
+#define MMCHS_REV         (MMCHS1BASE + 0x1FC)
+
+#define CMD0              INDX(0)
+#define CMD0_INT_EN       (CC_EN | CEB_EN)
+
+#define CMD1              (INDX(1) | RSP_TYPE_48BITS)
+#define CMD1_INT_EN       (CC_EN | CEB_EN | CTO_EN)
+
+#define CMD2              (INDX(2) | CCCE_ENABLE | RSP_TYPE_136BITS)
+#define CMD2_INT_EN       (CERR_EN | CIE_EN | CCRC_EN | CC_EN | CEB_EN | CTO_EN)
+
+#define CMD3              (INDX(3) | CICE_ENABLE | CCCE_ENABLE | RSP_TYPE_48BITS)
+#define CMD3_INT_EN       (CERR_EN | CIE_EN | CCRC_EN | CC_EN | CEB_EN | CTO_EN)
+
+#define CMD5              (INDX(5) | RSP_TYPE_48BITS)
+#define CMD5_INT_EN       (CC_EN | CEB_EN | CTO_EN)
+
+#define CMD7              (INDX(7) | CICE_ENABLE | CCCE_ENABLE | RSP_TYPE_48BITS)
+#define CMD7_INT_EN       (CERR_EN | CIE_EN | CCRC_EN | CC_EN | CEB_EN | CTO_EN)
+
+#define CMD8              (INDX(8) | CICE_ENABLE | CCCE_ENABLE | RSP_TYPE_48BITS)
+#define CMD8_INT_EN       (CERR_EN | CIE_EN | CCRC_EN | CC_EN | CEB_EN | CTO_EN)
+//Reserved(0)[12:31], Supply voltage(1)[11:8], check pattern(0xCE)[7:0] = 0x1CE
+#define CMD8_ARG          (0x0UL << 12 | BIT8 | 0xCEUL << 0)
+
+#define CMD9              (INDX(9) | CCCE_ENABLE | RSP_TYPE_136BITS)
+#define CMD9_INT_EN       (CCRC_EN | CC_EN | CEB_EN | CTO_EN)
+
+#define CMD16             (INDX(16) | CICE_ENABLE | CCCE_ENABLE | RSP_TYPE_48BITS)
+#define CMD16_INT_EN      (CERR_EN | CIE_EN | CCRC_EN | CC_EN | CEB_EN | CTO_EN)
+
+#define CMD17             (INDX(17) | DP_ENABLE | CICE_ENABLE | CCCE_ENABLE | RSP_TYPE_48BITS | DDIR_READ)
+#define CMD17_INT_EN      (CERR_EN | CIE_EN | CCRC_EN | CC_EN | TC_EN | BRR_EN | CTO_EN | DTO_EN | DCRC_EN | DEB_EN | CEB_EN)
+
+#define CMD18             (INDX(18) | DP_ENABLE | CICE_ENABLE | CCCE_ENABLE | RSP_TYPE_48BITS | MSBS_MULTBLK | DDIR_READ | BCE_ENABLE | DE_ENABLE)
+#define CMD18_INT_EN      (CERR_EN | CIE_EN | CCRC_EN | CC_EN | TC_EN | BRR_EN | CTO_EN | DTO_EN | DCRC_EN | DEB_EN | CEB_EN)
+
+#define CMD23             (INDX(23) | CICE_ENABLE | CCCE_ENABLE | RSP_TYPE_48BITS)
+#define CMD23_INT_EN      (CERR_EN | CIE_EN | CCRC_EN | CC_EN | CEB_EN | CTO_EN)
+
+#define CMD24             (INDX(24) | DP_ENABLE | CICE_ENABLE | CCCE_ENABLE | RSP_TYPE_48BITS | DDIR_WRITE)
+#define CMD24_INT_EN      (CERR_EN | CIE_EN | CCRC_EN | CC_EN | TC_EN | BWR_EN | CTO_EN | DTO_EN | DCRC_EN | DEB_EN | CEB_EN)
+
+#define CMD25             (INDX(25) | DP_ENABLE | CICE_ENABLE | CCCE_ENABLE | RSP_TYPE_48BITS | MSBS_MULTBLK | DDIR_READ | BCE_ENABLE | DE_ENABLE)
+#define CMD25_INT_EN      (CERR_EN | CIE_EN | CCRC_EN | CC_EN | TC_EN | BRR_EN | CTO_EN | DTO_EN | DCRC_EN | DEB_EN | CEB_EN)
+
+#define CMD55             (INDX(55) | CICE_ENABLE | CCCE_ENABLE | RSP_TYPE_48BITS)
+#define CMD55_INT_EN      (CERR_EN | CIE_EN | CCRC_EN | CC_EN | CEB_EN | CTO_EN)
+
+#define ACMD41            (INDX(41) | RSP_TYPE_48BITS)
+#define ACMD41_INT_EN     (CERR_EN | CIE_EN | CCRC_EN | CC_EN | CEB_EN | CTO_EN)
+
+#define ACMD6             (INDX(6) | RSP_TYPE_48BITS)
+#define ACMD6_INT_EN      (CERR_EN | CIE_EN | CCRC_EN | CC_EN | CEB_EN | CTO_EN)
+
+#endif //__OMAP3530SDIO_H__
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530PadConfiguration.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530PadConfiguration.h
new file mode 100644
index 0000000000..53456a820d
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530PadConfiguration.h
@@ -0,0 +1,297 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530_PAD_CONFIGURATION_H__
+#define __OMAP3530_PAD_CONFIGURATION_H__
+
+#define SYSTEM_CONTROL_MODULE_BASE  0x48002000
+
+//Pin definition
+#define SDRC_D0             (SYSTEM_CONTROL_MODULE_BASE + 0x030)
+#define SDRC_D1             (SYSTEM_CONTROL_MODULE_BASE + 0x032)
+#define SDRC_D2             (SYSTEM_CONTROL_MODULE_BASE + 0x034)
+#define SDRC_D3             (SYSTEM_CONTROL_MODULE_BASE + 0x036)
+#define SDRC_D4             (SYSTEM_CONTROL_MODULE_BASE + 0x038)
+#define SDRC_D5             (SYSTEM_CONTROL_MODULE_BASE + 0x03A)
+#define SDRC_D6             (SYSTEM_CONTROL_MODULE_BASE + 0x03C)
+#define SDRC_D7             (SYSTEM_CONTROL_MODULE_BASE + 0x03E)
+#define SDRC_D8             (SYSTEM_CONTROL_MODULE_BASE + 0x040)
+#define SDRC_D9             (SYSTEM_CONTROL_MODULE_BASE + 0x042)
+#define SDRC_D10            (SYSTEM_CONTROL_MODULE_BASE + 0x044)
+#define SDRC_D11            (SYSTEM_CONTROL_MODULE_BASE + 0x046)
+#define SDRC_D12            (SYSTEM_CONTROL_MODULE_BASE + 0x048)
+#define SDRC_D13            (SYSTEM_CONTROL_MODULE_BASE + 0x04A)
+#define SDRC_D14            (SYSTEM_CONTROL_MODULE_BASE + 0x04C)
+#define SDRC_D15            (SYSTEM_CONTROL_MODULE_BASE + 0x04E)
+#define SDRC_D16            (SYSTEM_CONTROL_MODULE_BASE + 0x050)
+#define SDRC_D17            (SYSTEM_CONTROL_MODULE_BASE + 0x052)
+#define SDRC_D18            (SYSTEM_CONTROL_MODULE_BASE + 0x054)
+#define SDRC_D19            (SYSTEM_CONTROL_MODULE_BASE + 0x056)
+#define SDRC_D20            (SYSTEM_CONTROL_MODULE_BASE + 0x058)
+#define SDRC_D21            (SYSTEM_CONTROL_MODULE_BASE + 0x05A)
+#define SDRC_D22            (SYSTEM_CONTROL_MODULE_BASE + 0x05C)
+#define SDRC_D23            (SYSTEM_CONTROL_MODULE_BASE + 0x05E)
+#define SDRC_D24            (SYSTEM_CONTROL_MODULE_BASE + 0x060)
+#define SDRC_D25            (SYSTEM_CONTROL_MODULE_BASE + 0x062)
+#define SDRC_D26            (SYSTEM_CONTROL_MODULE_BASE + 0x064)
+#define SDRC_D27            (SYSTEM_CONTROL_MODULE_BASE + 0x066)
+#define SDRC_D28            (SYSTEM_CONTROL_MODULE_BASE + 0x068)
+#define SDRC_D29            (SYSTEM_CONTROL_MODULE_BASE + 0x06A)
+#define SDRC_D30            (SYSTEM_CONTROL_MODULE_BASE + 0x06C)
+#define SDRC_D31            (SYSTEM_CONTROL_MODULE_BASE + 0x06E)
+#define SDRC_CLK            (SYSTEM_CONTROL_MODULE_BASE + 0x070)
+#define SDRC_DQS0           (SYSTEM_CONTROL_MODULE_BASE + 0x072)
+#define SDRC_CKE0           (SYSTEM_CONTROL_MODULE_BASE + 0x262)
+#define SDRC_CKE1           (SYSTEM_CONTROL_MODULE_BASE + 0x264)
+#define SDRC_DQS1           (SYSTEM_CONTROL_MODULE_BASE + 0x074)
+#define SDRC_DQS2           (SYSTEM_CONTROL_MODULE_BASE + 0x076)
+#define SDRC_DQS3           (SYSTEM_CONTROL_MODULE_BASE + 0x078)
+#define GPMC_A1             (SYSTEM_CONTROL_MODULE_BASE + 0x07A)
+#define GPMC_A2             (SYSTEM_CONTROL_MODULE_BASE + 0x07C)
+#define GPMC_A3             (SYSTEM_CONTROL_MODULE_BASE + 0x07E)
+#define GPMC_A4             (SYSTEM_CONTROL_MODULE_BASE + 0x080)
+#define GPMC_A5             (SYSTEM_CONTROL_MODULE_BASE + 0x082)
+#define GPMC_A6             (SYSTEM_CONTROL_MODULE_BASE + 0x084)
+#define GPMC_A7             (SYSTEM_CONTROL_MODULE_BASE + 0x086)
+#define GPMC_A8             (SYSTEM_CONTROL_MODULE_BASE + 0x088)
+#define GPMC_A9             (SYSTEM_CONTROL_MODULE_BASE + 0x08A)
+#define GPMC_A10            (SYSTEM_CONTROL_MODULE_BASE + 0x08C)
+#define GPMC_D0             (SYSTEM_CONTROL_MODULE_BASE + 0x08E)
+#define GPMC_D1             (SYSTEM_CONTROL_MODULE_BASE + 0x090)
+#define GPMC_D2             (SYSTEM_CONTROL_MODULE_BASE + 0x092)
+#define GPMC_D3             (SYSTEM_CONTROL_MODULE_BASE + 0x094)
+#define GPMC_D4             (SYSTEM_CONTROL_MODULE_BASE + 0x096)
+#define GPMC_D5             (SYSTEM_CONTROL_MODULE_BASE + 0x098)
+#define GPMC_D6             (SYSTEM_CONTROL_MODULE_BASE + 0x09A)
+#define GPMC_D7             (SYSTEM_CONTROL_MODULE_BASE + 0x09C)
+#define GPMC_D8             (SYSTEM_CONTROL_MODULE_BASE + 0x09E)
+#define GPMC_D9             (SYSTEM_CONTROL_MODULE_BASE + 0x0A0)
+#define GPMC_D10            (SYSTEM_CONTROL_MODULE_BASE + 0x0A2)
+#define GPMC_D11            (SYSTEM_CONTROL_MODULE_BASE + 0x0A4)
+#define GPMC_D12            (SYSTEM_CONTROL_MODULE_BASE + 0x0A6)
+#define GPMC_D13            (SYSTEM_CONTROL_MODULE_BASE + 0x0A8)
+#define GPMC_D14            (SYSTEM_CONTROL_MODULE_BASE + 0x0AA)
+#define GPMC_D15            (SYSTEM_CONTROL_MODULE_BASE + 0x0AC)
+#define GPMC_NCS0           (SYSTEM_CONTROL_MODULE_BASE + 0x0AE)
+#define GPMC_NCS1           (SYSTEM_CONTROL_MODULE_BASE + 0x0B0)
+#define GPMC_NCS2           (SYSTEM_CONTROL_MODULE_BASE + 0x0B2)
+#define GPMC_NCS3           (SYSTEM_CONTROL_MODULE_BASE + 0x0B4)
+#define GPMC_NCS4           (SYSTEM_CONTROL_MODULE_BASE + 0x0B6)
+#define GPMC_NCS5           (SYSTEM_CONTROL_MODULE_BASE + 0x0B8)
+#define GPMC_NCS6           (SYSTEM_CONTROL_MODULE_BASE + 0x0BA)
+#define GPMC_NCS7           (SYSTEM_CONTROL_MODULE_BASE + 0x0BC)
+#define GPMC_CLK            (SYSTEM_CONTROL_MODULE_BASE + 0x0BE)
+#define GPMC_NADV_ALE       (SYSTEM_CONTROL_MODULE_BASE + 0x0C0)
+#define GPMC_NOE            (SYSTEM_CONTROL_MODULE_BASE + 0x0C2)
+#define GPMC_NWE            (SYSTEM_CONTROL_MODULE_BASE + 0x0C4)
+#define GPMC_NBE0_CLE       (SYSTEM_CONTROL_MODULE_BASE + 0x0C6)
+#define GPMC_NBE1           (SYSTEM_CONTROL_MODULE_BASE + 0x0C8)
+#define GPMC_NWP            (SYSTEM_CONTROL_MODULE_BASE + 0x0CA)
+#define GPMC_WAIT0          (SYSTEM_CONTROL_MODULE_BASE + 0x0CC)
+#define GPMC_WAIT1          (SYSTEM_CONTROL_MODULE_BASE + 0x0CE)
+#define GPMC_WAIT2          (SYSTEM_CONTROL_MODULE_BASE + 0x0D0)
+#define GPMC_WAIT3          (SYSTEM_CONTROL_MODULE_BASE + 0x0D2)
+#define DSS_PCLK            (SYSTEM_CONTROL_MODULE_BASE + 0x0D4)
+#define DSS_HSYNC           (SYSTEM_CONTROL_MODULE_BASE + 0x0D6)
+#define DSS_PSYNC           (SYSTEM_CONTROL_MODULE_BASE + 0x0D8)
+#define DSS_ACBIAS          (SYSTEM_CONTROL_MODULE_BASE + 0x0DA)
+#define DSS_DATA0           (SYSTEM_CONTROL_MODULE_BASE + 0x0DC)
+#define DSS_DATA1           (SYSTEM_CONTROL_MODULE_BASE + 0x0DE)
+#define DSS_DATA2           (SYSTEM_CONTROL_MODULE_BASE + 0x0E0)
+#define DSS_DATA3           (SYSTEM_CONTROL_MODULE_BASE + 0x0E2)
+#define DSS_DATA4           (SYSTEM_CONTROL_MODULE_BASE + 0x0E4)
+#define DSS_DATA5           (SYSTEM_CONTROL_MODULE_BASE + 0x0E6)
+#define DSS_DATA6           (SYSTEM_CONTROL_MODULE_BASE + 0x0E8)
+#define DSS_DATA7           (SYSTEM_CONTROL_MODULE_BASE + 0x0EA)
+#define DSS_DATA8           (SYSTEM_CONTROL_MODULE_BASE + 0x0EC)
+#define DSS_DATA9           (SYSTEM_CONTROL_MODULE_BASE + 0x0EE)
+#define DSS_DATA10          (SYSTEM_CONTROL_MODULE_BASE + 0x0F0)
+#define DSS_DATA11          (SYSTEM_CONTROL_MODULE_BASE + 0x0F2)
+#define DSS_DATA12          (SYSTEM_CONTROL_MODULE_BASE + 0x0F4)
+#define DSS_DATA13          (SYSTEM_CONTROL_MODULE_BASE + 0x0F6)
+#define DSS_DATA14          (SYSTEM_CONTROL_MODULE_BASE + 0x0F8)
+#define DSS_DATA15          (SYSTEM_CONTROL_MODULE_BASE + 0x0FA)
+#define DSS_DATA16          (SYSTEM_CONTROL_MODULE_BASE + 0x0FC)
+#define DSS_DATA17          (SYSTEM_CONTROL_MODULE_BASE + 0x0FE)
+#define DSS_DATA18          (SYSTEM_CONTROL_MODULE_BASE + 0x100)
+#define DSS_DATA19          (SYSTEM_CONTROL_MODULE_BASE + 0x102)
+#define DSS_DATA20          (SYSTEM_CONTROL_MODULE_BASE + 0x104)
+#define DSS_DATA21          (SYSTEM_CONTROL_MODULE_BASE + 0x106)
+#define DSS_DATA22          (SYSTEM_CONTROL_MODULE_BASE + 0x108)
+#define DSS_DATA23          (SYSTEM_CONTROL_MODULE_BASE + 0x10A)
+#define CAM_HS              (SYSTEM_CONTROL_MODULE_BASE + 0x10C)
+#define CAM_VS              (SYSTEM_CONTROL_MODULE_BASE + 0x10E)
+#define CAM_XCLKA           (SYSTEM_CONTROL_MODULE_BASE + 0x110)
+#define CAM_PCLK            (SYSTEM_CONTROL_MODULE_BASE + 0x112)
+#define CAM_FLD             (SYSTEM_CONTROL_MODULE_BASE + 0x114)
+#define CAM_D0              (SYSTEM_CONTROL_MODULE_BASE + 0x116)
+#define CAM_D1              (SYSTEM_CONTROL_MODULE_BASE + 0x118)
+#define CAM_D2              (SYSTEM_CONTROL_MODULE_BASE + 0x11A)
+#define CAM_D3              (SYSTEM_CONTROL_MODULE_BASE + 0x11C)
+#define CAM_D4              (SYSTEM_CONTROL_MODULE_BASE + 0x11E)
+#define CAM_D5              (SYSTEM_CONTROL_MODULE_BASE + 0x120)
+#define CAM_D6              (SYSTEM_CONTROL_MODULE_BASE + 0x122)
+#define CAM_D7              (SYSTEM_CONTROL_MODULE_BASE + 0x124)
+#define CAM_D8              (SYSTEM_CONTROL_MODULE_BASE + 0x126)
+#define CAM_D9              (SYSTEM_CONTROL_MODULE_BASE + 0x128)
+#define CAM_D10             (SYSTEM_CONTROL_MODULE_BASE + 0x12A)
+#define CAM_D11             (SYSTEM_CONTROL_MODULE_BASE + 0x12C)
+#define CAM_XCLKB           (SYSTEM_CONTROL_MODULE_BASE + 0x12E)
+#define CAM_WEN             (SYSTEM_CONTROL_MODULE_BASE + 0x130)
+#define CAM_STROBE          (SYSTEM_CONTROL_MODULE_BASE + 0x132)
+#define CSI2_DX0            (SYSTEM_CONTROL_MODULE_BASE + 0x134)
+#define CSI2_DY0            (SYSTEM_CONTROL_MODULE_BASE + 0x136)
+#define CSI2_DX1            (SYSTEM_CONTROL_MODULE_BASE + 0x138)
+#define CSI2_DY1            (SYSTEM_CONTROL_MODULE_BASE + 0x13A)
+#define MCBSP2_FSX          (SYSTEM_CONTROL_MODULE_BASE + 0x13C)
+#define MCBSP2_CLKX         (SYSTEM_CONTROL_MODULE_BASE + 0x13E)
+#define MCBSP2_DR           (SYSTEM_CONTROL_MODULE_BASE + 0x140)
+#define MCBSP2_DX           (SYSTEM_CONTROL_MODULE_BASE + 0x142)
+#define MMC1_CLK            (SYSTEM_CONTROL_MODULE_BASE + 0x144)
+#define MMC1_CMD            (SYSTEM_CONTROL_MODULE_BASE + 0x146)
+#define MMC1_DAT0           (SYSTEM_CONTROL_MODULE_BASE + 0x148)
+#define MMC1_DAT1           (SYSTEM_CONTROL_MODULE_BASE + 0x14A)
+#define MMC1_DAT2           (SYSTEM_CONTROL_MODULE_BASE + 0x14C)
+#define MMC1_DAT3           (SYSTEM_CONTROL_MODULE_BASE + 0x14E)
+#define MMC1_DAT4           (SYSTEM_CONTROL_MODULE_BASE + 0x150)
+#define MMC1_DAT5           (SYSTEM_CONTROL_MODULE_BASE + 0x152)
+#define MMC1_DAT6           (SYSTEM_CONTROL_MODULE_BASE + 0x154)
+#define MMC1_DAT7           (SYSTEM_CONTROL_MODULE_BASE + 0x156)
+#define MMC2_CLK            (SYSTEM_CONTROL_MODULE_BASE + 0x158)
+#define MMC2_CMD            (SYSTEM_CONTROL_MODULE_BASE + 0x15A)
+#define MMC2_DAT0           (SYSTEM_CONTROL_MODULE_BASE + 0x15C)
+#define MMC2_DAT1           (SYSTEM_CONTROL_MODULE_BASE + 0x15E)
+#define MMC2_DAT2           (SYSTEM_CONTROL_MODULE_BASE + 0x160)
+#define MMC2_DAT3           (SYSTEM_CONTROL_MODULE_BASE + 0x162)
+#define MMC2_DAT4           (SYSTEM_CONTROL_MODULE_BASE + 0x164)
+#define MMC2_DAT5           (SYSTEM_CONTROL_MODULE_BASE + 0x166)
+#define MMC2_DAT6           (SYSTEM_CONTROL_MODULE_BASE + 0x168)
+#define MMC2_DAT7           (SYSTEM_CONTROL_MODULE_BASE + 0x16A)
+#define MCBSP3_DX           (SYSTEM_CONTROL_MODULE_BASE + 0x16C)
+#define MCBSP3_DR           (SYSTEM_CONTROL_MODULE_BASE + 0x16E)
+#define MCBSP3_CLKX         (SYSTEM_CONTROL_MODULE_BASE + 0x170)
+#define MCBSP3_FSX          (SYSTEM_CONTROL_MODULE_BASE + 0x172)
+#define UART2_CTS           (SYSTEM_CONTROL_MODULE_BASE + 0x174)
+#define UART2_RTS           (SYSTEM_CONTROL_MODULE_BASE + 0x176)
+#define UART2_TX            (SYSTEM_CONTROL_MODULE_BASE + 0x178)
+#define UART2_RX            (SYSTEM_CONTROL_MODULE_BASE + 0x17A)
+#define UART1_TX            (SYSTEM_CONTROL_MODULE_BASE + 0x17C)
+#define UART1_RTS           (SYSTEM_CONTROL_MODULE_BASE + 0x17E)
+#define UART1_CTS           (SYSTEM_CONTROL_MODULE_BASE + 0x180)
+#define UART1_RX            (SYSTEM_CONTROL_MODULE_BASE + 0x182)
+#define MCBSP4_CLKX         (SYSTEM_CONTROL_MODULE_BASE + 0x184)
+#define MCBSP4_DR           (SYSTEM_CONTROL_MODULE_BASE + 0x186)
+#define MCBSP4_DX           (SYSTEM_CONTROL_MODULE_BASE + 0x188)
+#define MCBSP4_FSX          (SYSTEM_CONTROL_MODULE_BASE + 0x18A)
+#define MCBSP1_CLKR         (SYSTEM_CONTROL_MODULE_BASE + 0x18C)
+#define MCBSP1_FSR          (SYSTEM_CONTROL_MODULE_BASE + 0x18E)
+#define MCBSP1_DX           (SYSTEM_CONTROL_MODULE_BASE + 0x190)
+#define MCBSP1_DR           (SYSTEM_CONTROL_MODULE_BASE + 0x192)
+#define MCBSP1_CLKS         (SYSTEM_CONTROL_MODULE_BASE + 0x194)
+#define MCBSP1_FSX          (SYSTEM_CONTROL_MODULE_BASE + 0x196)
+#define MCBSP1_CLKX         (SYSTEM_CONTROL_MODULE_BASE + 0x198)
+#define UART3_CTS_RCTX      (SYSTEM_CONTROL_MODULE_BASE + 0x19A)
+#define UART3_RTS_SD        (SYSTEM_CONTROL_MODULE_BASE + 0x19C)
+#define UART3_RX_IRRX       (SYSTEM_CONTROL_MODULE_BASE + 0x19E)
+#define UART3_TX_IRTX       (SYSTEM_CONTROL_MODULE_BASE + 0x1A0)
+#define HSUSB0_CLK          (SYSTEM_CONTROL_MODULE_BASE + 0x1A2)
+#define HSUSB0_STP          (SYSTEM_CONTROL_MODULE_BASE + 0x1A4)
+#define HSUSB0_DIR          (SYSTEM_CONTROL_MODULE_BASE + 0x1A6)
+#define HSUSB0_NXT          (SYSTEM_CONTROL_MODULE_BASE + 0x1A8)
+#define HSUSB0_DATA0        (SYSTEM_CONTROL_MODULE_BASE + 0x1AA)
+#define HSUSB0_DATA1        (SYSTEM_CONTROL_MODULE_BASE + 0x1AC)
+#define HSUSB0_DATA2        (SYSTEM_CONTROL_MODULE_BASE + 0x1AE)
+#define HSUSB0_DATA3        (SYSTEM_CONTROL_MODULE_BASE + 0x1B0)
+#define HSUSB0_DATA4        (SYSTEM_CONTROL_MODULE_BASE + 0x1B2)
+#define HSUSB0_DATA5        (SYSTEM_CONTROL_MODULE_BASE + 0x1B4)
+#define HSUSB0_DATA6        (SYSTEM_CONTROL_MODULE_BASE + 0x1B6)
+#define HSUSB0_DATA7        (SYSTEM_CONTROL_MODULE_BASE + 0x1B8)
+#define I2C1_SCL            (SYSTEM_CONTROL_MODULE_BASE + 0x1BA)
+#define I2C1_SDA            (SYSTEM_CONTROL_MODULE_BASE + 0x1BC)
+#define I2C2_SCL            (SYSTEM_CONTROL_MODULE_BASE + 0x1BE)
+#define I2C2_SDA            (SYSTEM_CONTROL_MODULE_BASE + 0x1C0)
+#define I2C3_SCL            (SYSTEM_CONTROL_MODULE_BASE + 0x1C2)
+#define I2C3_SDA            (SYSTEM_CONTROL_MODULE_BASE + 0x1C4)
+#define HDQ_SIO             (SYSTEM_CONTROL_MODULE_BASE + 0x1C6)
+#define MCSPI1_CLK          (SYSTEM_CONTROL_MODULE_BASE + 0x1C8)
+#define MCSPI1_SIMO         (SYSTEM_CONTROL_MODULE_BASE + 0x1CA)
+#define MCSPI1_SOMI         (SYSTEM_CONTROL_MODULE_BASE + 0x1CC)
+#define MCSPI1_CS0          (SYSTEM_CONTROL_MODULE_BASE + 0x1CE)
+#define MCSPI1_CS1          (SYSTEM_CONTROL_MODULE_BASE + 0x1D0)
+#define MCSPI1_CS2          (SYSTEM_CONTROL_MODULE_BASE + 0x1D2)
+#define MCSPI1_CS3          (SYSTEM_CONTROL_MODULE_BASE + 0x1D4)
+#define MCSPI2_CLK          (SYSTEM_CONTROL_MODULE_BASE + 0x1D6)
+#define MCSPI2_SIMO         (SYSTEM_CONTROL_MODULE_BASE + 0x1D8)
+#define MCSPI2_SOMI         (SYSTEM_CONTROL_MODULE_BASE + 0x1DA)
+#define MCSPI2_CS0          (SYSTEM_CONTROL_MODULE_BASE + 0x1DC)
+#define MCSPI2_CS1          (SYSTEM_CONTROL_MODULE_BASE + 0x1DE)
+#define SYS_NIRQ            (SYSTEM_CONTROL_MODULE_BASE + 0x1E0)
+#define SYS_CLKOUT2         (SYSTEM_CONTROL_MODULE_BASE + 0x1E2)
+#define ETK_CLK             (SYSTEM_CONTROL_MODULE_BASE + 0x5D8)
+#define ETK_CTL             (SYSTEM_CONTROL_MODULE_BASE + 0x5DA)
+#define ETK_D0              (SYSTEM_CONTROL_MODULE_BASE + 0x5DC)
+#define ETK_D1              (SYSTEM_CONTROL_MODULE_BASE + 0x5DE)
+#define ETK_D2              (SYSTEM_CONTROL_MODULE_BASE + 0x5E0)
+#define ETK_D3              (SYSTEM_CONTROL_MODULE_BASE + 0x5E2)
+#define ETK_D4              (SYSTEM_CONTROL_MODULE_BASE + 0x5E4)
+#define ETK_D5              (SYSTEM_CONTROL_MODULE_BASE + 0x5E6)
+#define ETK_D6              (SYSTEM_CONTROL_MODULE_BASE + 0x5E8)
+#define ETK_D7              (SYSTEM_CONTROL_MODULE_BASE + 0x5EA)
+#define ETK_D8              (SYSTEM_CONTROL_MODULE_BASE + 0x5EC)
+#define ETK_D9              (SYSTEM_CONTROL_MODULE_BASE + 0x5EE)
+#define ETK_D10             (SYSTEM_CONTROL_MODULE_BASE + 0x5F0)
+#define ETK_D11             (SYSTEM_CONTROL_MODULE_BASE + 0x5F2)
+#define ETK_D12             (SYSTEM_CONTROL_MODULE_BASE + 0x5F4)
+#define ETK_D13             (SYSTEM_CONTROL_MODULE_BASE + 0x5F6)
+#define ETK_D14             (SYSTEM_CONTROL_MODULE_BASE + 0x5F8)
+#define ETK_D15             (SYSTEM_CONTROL_MODULE_BASE + 0x5FA)
+#define SYS_BOOT0           (SYSTEM_CONTROL_MODULE_BASE + 0xA0A)
+#define SYS_BOOT1           (SYSTEM_CONTROL_MODULE_BASE + 0xA0C)
+#define SYS_BOOT3           (SYSTEM_CONTROL_MODULE_BASE + 0xA10)
+#define SYS_BOOT4           (SYSTEM_CONTROL_MODULE_BASE + 0xA12)
+#define SYS_BOOT5           (SYSTEM_CONTROL_MODULE_BASE + 0xA14)
+#define SYS_BOOT6           (SYSTEM_CONTROL_MODULE_BASE + 0xA16)
+
+//Mux modes
+#define MUXMODE0            (0x0UL)
+#define MUXMODE1            (0x1UL)
+#define MUXMODE2            (0x2UL)
+#define MUXMODE3            (0x3UL)
+#define MUXMODE4            (0x4UL)
+#define MUXMODE5            (0x5UL)
+#define MUXMODE6            (0x6UL)
+#define MUXMODE7            (0x7UL)
+
+//Pad configuration register.
+#define PAD_CONFIG_MASK      (0xFFFFUL)
+#define MUXMODE_OFFSET       0
+#define MUXMODE_MASK         (0x7UL << MUXMODE_OFFSET)
+#define PULL_CONFIG_OFFSET   3
+#define PULL_CONFIG_MASK     (0x3UL << PULL_CONFIG_OFFSET)
+#define INPUTENABLE_OFFSET   8
+#define INPUTENABLE_MASK     (0x1UL << INPUTENABLE_OFFSET)
+#define OFFMODE_VALUE_OFFSET 9
+#define OFFMODE_VALUE_MASK   (0x1FUL << OFFMODE_VALUE_OFFSET)
+#define WAKEUP_OFFSET        14
+#define WAKEUP_MASK          (0x2UL << WAKEUP_OFFSET)
+
+#define PULL_DOWN_SELECTED   ((0x0UL << 1) | BIT0)
+#define PULL_UP_SELECTED     (BIT1 | BIT0)
+#define PULL_DISABLED        (0x0UL << 0)
+
+#define OUTPUT               (0x0UL) //Pin is configured in output only mode.
+#define INPUT                (0x1UL) //Pin is configured in bi-directional mode.
+
+typedef struct {
+  UINTN   Pin;
+  UINTN   MuxMode;
+  UINTN   PullConfig;
+  UINTN   InputEnable;
+} PAD_CONFIGURATION;
+
+#endif //__OMAP3530_PAD_CONFIGURATION_H__
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Prcm.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Prcm.h
new file mode 100644
index 0000000000..80853e460e
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Prcm.h
@@ -0,0 +1,159 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530PRCM_H__
+#define __OMAP3530PRCM_H__
+
+#define CM_FCLKEN1_CORE   (0x48004A00)
+#define CM_FCLKEN3_CORE   (0x48004A08)
+#define CM_ICLKEN1_CORE   (0x48004A10)
+#define CM_ICLKEN3_CORE   (0x48004A18)
+#define CM_CLKEN2_PLL     (0x48004D04)
+#define CM_CLKSEL4_PLL    (0x48004D4C)
+#define CM_CLKSEL5_PLL    (0x48004D50)
+#define CM_FCLKEN_USBHOST  (0x48005400)
+#define CM_ICLKEN_USBHOST  (0x48005410)
+#define CM_CLKSTST_USBHOST (0x4800544c)
+
+//Wakeup clock defintion
+#define CM_FCLKEN_WKUP    (0x48004C00)
+#define CM_ICLKEN_WKUP    (0x48004C10)
+
+//Peripheral clock definition
+#define CM_FCLKEN_PER     (0x48005000)
+#define CM_ICLKEN_PER     (0x48005010)
+#define CM_CLKSEL_PER     (0x48005040)
+
+//Reset management definition
+#define PRM_RSTCTRL       (0x48307250)
+#define PRM_RSTST         (0x48307258)
+
+//CORE clock
+#define CM_FCLKEN1_CORE_EN_I2C1_MASK    BIT15
+#define CM_FCLKEN1_CORE_EN_I2C1_DISABLE (0UL << 15)
+#define CM_FCLKEN1_CORE_EN_I2C1_ENABLE  BIT15
+
+#define CM_ICLKEN1_CORE_EN_I2C1_MASK    BIT15
+#define CM_ICLKEN1_CORE_EN_I2C1_DISABLE (0UL << 15)
+#define CM_ICLKEN1_CORE_EN_I2C1_ENABLE  BIT15
+
+#define CM_FCLKEN1_CORE_EN_MMC1_MASK    BIT24
+#define CM_FCLKEN1_CORE_EN_MMC1_DISABLE (0UL << 24)
+#define CM_FCLKEN1_CORE_EN_MMC1_ENABLE  BIT24
+
+#define CM_FCLKEN3_CORE_EN_USBTLL_MASK    BIT2
+#define CM_FCLKEN3_CORE_EN_USBTLL_DISABLE (0UL << 2)
+#define CM_FCLKEN3_CORE_EN_USBTLL_ENABLE  BIT2
+
+#define CM_ICLKEN1_CORE_EN_MMC1_MASK    BIT24
+#define CM_ICLKEN1_CORE_EN_MMC1_DISABLE (0UL << 24)
+#define CM_ICLKEN1_CORE_EN_MMC1_ENABLE  BIT24
+
+#define CM_ICLKEN3_CORE_EN_USBTLL_MASK    BIT2
+#define CM_ICLKEN3_CORE_EN_USBTLL_DISABLE (0UL << 2)
+#define CM_ICLKEN3_CORE_EN_USBTLL_ENABLE  BIT2
+
+#define CM_CLKEN_FREQSEL_075_100        (0x03UL << 4)
+#define CM_CLKEN_ENABLE                 (7UL << 0)
+
+#define CM_CLKSEL_PLL_MULT(x)           (((x) & 0x07FF) << 8)
+#define CM_CLKSEL_PLL_DIV(x)            ((((x) - 1) & 0x7F) << 0)
+
+#define CM_CLKSEL_DIV_120M(x)           (((x) & 0x1F) << 0)
+
+#define CM_FCLKEN_USBHOST_EN_USBHOST2_MASK    BIT1
+#define CM_FCLKEN_USBHOST_EN_USBHOST2_DISABLE (0UL << 1)
+#define CM_FCLKEN_USBHOST_EN_USBHOST2_ENABLE  BIT1
+
+#define CM_FCLKEN_USBHOST_EN_USBHOST1_MASK    BIT0
+#define CM_FCLKEN_USBHOST_EN_USBHOST1_DISABLE (0UL << 0)
+#define CM_FCLKEN_USBHOST_EN_USBHOST1_ENABLE  BIT0
+
+#define CM_ICLKEN_USBHOST_EN_USBHOST_MASK     BIT0
+#define CM_ICLKEN_USBHOST_EN_USBHOST_DISABLE  (0UL << 0)
+#define CM_ICLKEN_USBHOST_EN_USBHOST_ENABLE   BIT0
+
+//Wakeup functional clock
+#define CM_FCLKEN_WKUP_EN_GPIO1_DISABLE       (0UL << 3)
+#define CM_FCLKEN_WKUP_EN_GPIO1_ENABLE        BIT3
+
+#define CM_FCLKEN_WKUP_EN_WDT2_DISABLE        (0UL << 5)
+#define CM_FCLKEN_WKUP_EN_WDT2_ENABLE         BIT5
+
+//Wakeup interface clock
+#define CM_ICLKEN_WKUP_EN_GPIO1_DISABLE       (0UL << 3)
+#define CM_ICLKEN_WKUP_EN_GPIO1_ENABLE        BIT3
+
+#define CM_ICLKEN_WKUP_EN_WDT2_DISABLE        (0UL << 5)
+#define CM_ICLKEN_WKUP_EN_WDT2_ENABLE         BIT5
+
+//Peripheral functional clock
+#define CM_FCLKEN_PER_EN_GPT3_DISABLE         (0UL << 4)
+#define CM_FCLKEN_PER_EN_GPT3_ENABLE          BIT4
+
+#define CM_FCLKEN_PER_EN_GPT4_DISABLE         (0UL << 5)
+#define CM_FCLKEN_PER_EN_GPT4_ENABLE          BIT5
+
+#define CM_FCLKEN_PER_EN_UART3_DISABLE        (0UL << 11)
+#define CM_FCLKEN_PER_EN_UART3_ENABLE         BIT11
+
+#define CM_FCLKEN_PER_EN_GPIO2_DISABLE        (0UL << 13)
+#define CM_FCLKEN_PER_EN_GPIO2_ENABLE         BIT13
+
+#define CM_FCLKEN_PER_EN_GPIO3_DISABLE        (0UL << 14)
+#define CM_FCLKEN_PER_EN_GPIO3_ENABLE         BIT14
+
+#define CM_FCLKEN_PER_EN_GPIO4_DISABLE        (0UL << 15)
+#define CM_FCLKEN_PER_EN_GPIO4_ENABLE         BIT15
+
+#define CM_FCLKEN_PER_EN_GPIO5_DISABLE        (0UL << 16)
+#define CM_FCLKEN_PER_EN_GPIO5_ENABLE         BIT16
+
+#define CM_FCLKEN_PER_EN_GPIO6_DISABLE        (0UL << 17)
+#define CM_FCLKEN_PER_EN_GPIO6_ENABLE         BIT17
+
+//Peripheral interface clock
+#define CM_ICLKEN_PER_EN_GPT3_DISABLE         (0UL << 4)
+#define CM_ICLKEN_PER_EN_GPT3_ENABLE          BIT4
+
+#define CM_ICLKEN_PER_EN_GPT4_DISABLE         (0UL << 5)
+#define CM_ICLKEN_PER_EN_GPT4_ENABLE          BIT5
+
+#define CM_ICLKEN_PER_EN_UART3_DISABLE        (0UL << 11)
+#define CM_ICLKEN_PER_EN_UART3_ENABLE         BIT11
+
+#define CM_ICLKEN_PER_EN_GPIO2_DISABLE        (0UL << 13)
+#define CM_ICLKEN_PER_EN_GPIO2_ENABLE         BIT13
+
+#define CM_ICLKEN_PER_EN_GPIO3_DISABLE        (0UL << 14)
+#define CM_ICLKEN_PER_EN_GPIO3_ENABLE         BIT14
+
+#define CM_ICLKEN_PER_EN_GPIO4_DISABLE        (0UL << 15)
+#define CM_ICLKEN_PER_EN_GPIO4_ENABLE         BIT15
+
+#define CM_ICLKEN_PER_EN_GPIO5_DISABLE        (0UL << 16)
+#define CM_ICLKEN_PER_EN_GPIO5_ENABLE         BIT16
+
+#define CM_ICLKEN_PER_EN_GPIO6_DISABLE        (0UL << 17)
+#define CM_ICLKEN_PER_EN_GPIO6_ENABLE         BIT17
+
+//Timer source clock selection
+#define CM_CLKSEL_PER_CLKSEL_GPT3_32K         (0UL << 1)
+#define CM_CLKSEL_PER_CLKSEL_GPT3_SYS         BIT1
+
+#define CM_CLKSEL_PER_CLKSEL_GPT4_32K         (0UL << 2)
+#define CM_CLKSEL_PER_CLKSEL_GPT4_SYS         BIT2
+
+//Reset management (Global and Cold reset)
+#define RST_GS            BIT1
+#define RST_DPLL3         BIT2
+#define GLOBAL_SW_RST     BIT1
+#define GLOBAL_COLD_RST   (0x0UL << 0)
+
+#endif // __OMAP3530PRCM_H__
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Timer.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Timer.h
new file mode 100644
index 0000000000..26ddcd536d
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Timer.h
@@ -0,0 +1,76 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530TIMER_H__
+#define __OMAP3530TIMER_H__
+
+#define GPTIMER1_BASE   (0x48313000)
+#define GPTIMER2_BASE   (0x49032000)
+#define GPTIMER3_BASE   (0x49034000)
+#define GPTIMER4_BASE   (0x49036000)
+#define GPTIMER5_BASE   (0x49038000)
+#define GPTIMER6_BASE   (0x4903A000)
+#define GPTIMER7_BASE   (0x4903C000)
+#define GPTIMER8_BASE   (0x4903E000)
+#define GPTIMER9_BASE   (0x49040000)
+#define GPTIMER10_BASE  (0x48086000)
+#define GPTIMER11_BASE  (0x48088000)
+#define GPTIMER12_BASE  (0x48304000)
+#define WDTIMER2_BASE   (0x48314000)
+
+#define GPTIMER_TIOCP_CFG (0x0010)
+#define GPTIMER_TISTAT    (0x0014)
+#define GPTIMER_TISR      (0x0018)
+#define GPTIMER_TIER      (0x001C)
+#define GPTIMER_TWER      (0x0020)
+#define GPTIMER_TCLR      (0x0024)
+#define GPTIMER_TCRR      (0x0028)
+#define GPTIMER_TLDR      (0x002C)
+#define GPTIMER_TTGR      (0x0030)
+#define GPTIMER_TWPS      (0x0034)
+#define GPTIMER_TMAR      (0x0038)
+#define GPTIMER_TCAR1     (0x003C)
+#define GPTIMER_TSICR     (0x0040)
+#define GPTIMER_TCAR2     (0x0044)
+#define GPTIMER_TPIR      (0x0048)
+#define GPTIMER_TNIR      (0x004C)
+#define GPTIMER_TCVR      (0x0050)
+#define GPTIMER_TOCR      (0x0054)
+#define GPTIMER_TOWR      (0x0058)
+
+#define WSPR              (0x048)
+
+#define TISR_TCAR_IT_FLAG_MASK  BIT2
+#define TISR_OVF_IT_FLAG_MASK   BIT1
+#define TISR_MAT_IT_FLAG_MASK   BIT0
+#define TISR_ALL_INTERRUPT_MASK (TISR_TCAR_IT_FLAG_MASK | TISR_OVF_IT_FLAG_MASK | TISR_MAT_IT_FLAG_MASK)
+
+#define TISR_TCAR_IT_FLAG_NOT_PENDING   (0UL << 2)
+#define TISR_OVF_IT_FLAG_NOT_PENDING    (0UL << 1)
+#define TISR_MAT_IT_FLAG_NOT_PENDING    (0UL << 0)
+#define TISR_NO_INTERRUPTS_PENDING      (TISR_TCAR_IT_FLAG_NOT_PENDING | TISR_OVF_IT_FLAG_NOT_PENDING | TISR_MAT_IT_FLAG_NOT_PENDING)
+
+#define TISR_TCAR_IT_FLAG_CLEAR BIT2
+#define TISR_OVF_IT_FLAG_CLEAR  BIT1
+#define TISR_MAT_IT_FLAG_CLEAR  BIT0
+#define TISR_CLEAR_ALL          (TISR_TCAR_IT_FLAG_CLEAR | TISR_OVF_IT_FLAG_CLEAR | TISR_MAT_IT_FLAG_CLEAR)
+
+#define TCLR_AR_AUTORELOAD      BIT1
+#define TCLR_AR_ONESHOT         (0UL << 1)
+#define TCLR_ST_ON              BIT0
+#define TCLR_ST_OFF             (0UL << 0)
+
+#define TIER_TCAR_IT_ENABLE     (BIT2
+#define TIER_TCAR_IT_DISABLE    (0UL << 2)
+#define TIER_OVF_IT_ENABLE      BIT1
+#define TIER_OVF_IT_DISABLE     (0UL << 1)
+#define TIER_MAT_IT_ENABLE      BIT0
+#define TIER_MAT_IT_DISABLE     (0UL << 0)
+
+#endif // __OMAP3530TIMER_H__
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Uart.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Uart.h
new file mode 100644
index 0000000000..54be17b1d7
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Uart.h
@@ -0,0 +1,48 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530UART_H__
+#define __OMAP3530UART_H__
+
+#define UART1_BASE  (0x4806A000)
+#define UART2_BASE  (0x4806C000)
+#define UART3_BASE  (0x49020000)
+
+#define UART_DLL_REG  (0x0000)
+#define UART_RBR_REG  (0x0000)
+#define UART_THR_REG  (0x0000)
+#define UART_DLH_REG  (0x0004)
+#define UART_FCR_REG  (0x0008)
+#define UART_LCR_REG  (0x000C)
+#define UART_MCR_REG  (0x0010)
+#define UART_LSR_REG  (0x0014)
+#define UART_MDR1_REG (0x0020)
+
+#define UART_FCR_TX_FIFO_CLEAR          BIT2
+#define UART_FCR_RX_FIFO_CLEAR          BIT1
+#define UART_FCR_FIFO_ENABLE            BIT0
+
+#define UART_LCR_DIV_EN_ENABLE          BIT7
+#define UART_LCR_DIV_EN_DISABLE         (0UL << 7)
+#define UART_LCR_CHAR_LENGTH_8          (BIT1 | BIT0)
+
+#define UART_MCR_RTS_FORCE_ACTIVE       BIT1
+#define UART_MCR_DTR_FORCE_ACTIVE       BIT0
+
+#define UART_LSR_TX_FIFO_E_MASK         BIT5
+#define UART_LSR_TX_FIFO_E_NOT_EMPTY    (0UL << 5)
+#define UART_LSR_TX_FIFO_E_EMPTY        BIT5
+#define UART_LSR_RX_FIFO_E_MASK         BIT0
+#define UART_LSR_RX_FIFO_E_NOT_EMPTY    BIT0
+#define UART_LSR_RX_FIFO_E_EMPTY        (0UL << 0)
+
+// BIT2:BIT0
+#define UART_MDR1_MODE_SELECT_DISABLE   (7UL)
+#define UART_MDR1_MODE_SELECT_UART_16X  (0UL)
+
+#endif // __OMAP3530UART_H__
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Usb.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Usb.h
new file mode 100644
index 0000000000..a438117232
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Usb.h
@@ -0,0 +1,42 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530USB_H__
+#define __OMAP3530USB_H__
+
+#define USB_BASE            (0x48060000)
+
+#define UHH_SYSCONFIG       (USB_BASE + 0x4010)
+#define UHH_HOSTCONFIG      (USB_BASE + 0x4040)
+#define UHH_SYSSTATUS       (USB_BASE + 0x4014)
+
+#define USB_EHCI_HCCAPBASE  (USB_BASE + 0x4800)
+
+#define UHH_SYSCONFIG_MIDLEMODE_NO_STANDBY  BIT12
+#define UHH_SYSCONFIG_CLOCKACTIVITY_ON      BIT8
+#define UHH_SYSCONFIG_SIDLEMODE_NO_STANDBY  BIT3
+#define UHH_SYSCONFIG_ENAWAKEUP_ENABLE      BIT2
+#define UHH_SYSCONFIG_SOFTRESET             BIT1
+#define UHH_SYSCONFIG_AUTOIDLE_ALWAYS_RUN   (0UL <<  0)
+
+#define UHH_HOSTCONFIG_P3_CONNECT_STATUS_DISCONNECT (0UL << 10)
+#define UHH_HOSTCONFIG_P2_CONNECT_STATUS_DISCONNECT (0UL <<  9)
+#define UHH_HOSTCONFIG_P1_CONNECT_STATUS_DISCONNECT (0UL <<  8)
+#define UHH_HOSTCONFIG_ENA_INCR_ALIGN_DISABLE       (0UL <<  5)
+#define UHH_HOSTCONFIG_ENA_INCR16_ENABLE            BIT4
+#define UHH_HOSTCONFIG_ENA_INCR8_ENABLE             BIT3
+#define UHH_HOSTCONFIG_ENA_INCR4_ENABLE             BIT2
+#define UHH_HOSTCONFIG_AUTOPPD_ON_OVERCUR_EN_ON     (0UL <<  1)
+#define UHH_HOSTCONFIG_P1_ULPI_BYPASS_ULPI_MODE     (0UL <<  0)
+
+#define UHH_SYSSTATUS_RESETDONE                (BIT0 | BIT1 | BIT2)
+
+#endif // __OMAP3530USB_H__
+
+
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/TPS65950.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/TPS65950.h
new file mode 100644
index 0000000000..d0f2950b06
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/TPS65950.h
@@ -0,0 +1,74 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __TPS65950_H__
+#define __TPS65950_H__
+
+#define EXTERNAL_DEVICE_REGISTER_TO_SLAVE_ADDRESS(x)     (((x) >> 8) & 0xFF)
+#define EXTERNAL_DEVICE_REGISTER_TO_REGISTER(x)          ((x) & 0xFF)
+#define EXTERNAL_DEVICE_REGISTER(SlaveAddress, Register) (((SlaveAddress) & 0xFF) << 8 | ((Register) & 0xFF))
+
+// I2C Address group
+#define I2C_ADDR_GRP_ID1      0x48
+#define I2C_ADDR_GRP_ID2      0x49
+#define I2C_ADDR_GRP_ID3      0x4A
+#define I2C_ADDR_GRP_ID4      0x4B
+#define I2C_ADDR_GRP_ID5      0x12
+
+// MMC definitions.
+#define VMMC1_DEV_GRP         0x82
+#define DEV_GRP_P1            BIT5
+
+#define VMMC1_DEDICATED_REG   0x85
+#define VSEL_1_85V            0x0
+#define VSEL_2_85V            0x1
+#define VSEL_3_00V            0x2
+#define VSEL_3_15V            0x3
+
+#define TPS65950_GPIO_CTRL    0xaa  //I2C_ADDR_GRP_ID2
+#define CARD_DETECT_ENABLE    (BIT2 | BIT0) // GPIO ON + GPIO CD1 enabled
+
+
+#define GPIODATAIN1           0x98  //I2C_ADDR_GRP_ID2
+#define CARD_DETECT_BIT       BIT0
+
+// LEDEN register
+#define LEDEN                 0xEE
+#define LEDAON                BIT0
+#define LEDBON                BIT1
+#define LEDAPWM               BIT4
+#define LEDBPWM               BIT5
+
+// RTC registers
+#define SECONDS_REG           0x1C
+#define MINUTES_REG           0x1D
+#define HOURS_REG             0x1E
+#define DAYS_REG              0x1F
+#define MONTHS_REG            0x20
+#define YEARS_REG             0x21
+#define WEEKS_REG             0x22
+#define RTC_CTRL_REG          0x29
+
+// USB PHY power
+#define VAUX2_DEDICATED       0x79
+#define VAUX2_DEV_GRP         0x76
+
+#define VAUX_DEV_GRP_NONE     0x00
+#define VAUX_DEV_GRP_P1       0x20
+#define VAUX_DEV_GRP_P2       0x40
+#define VAUX_DEV_GRP_P3       0x80
+#define VAUX_DEDICATED_18V    0x05
+
+// Display subsystem
+#define VPLL2_DEDICATED       0x91
+#define VPLL2_DEV_GRP         0x8E
+
+#define GPIODATADIR1          0x9B
+#define SETGPIODATAOUT1       0xA4
+
+#endif //__TPS65950_H__
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/HardwareInterrupt.c b/Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/HardwareInterrupt.c
new file mode 100644
index 0000000000..d15e68edfc
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/HardwareInterrupt.c
@@ -0,0 +1,396 @@
+/** @file
+  Handle OMAP35xx interrupt controller
+
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/ArmLib.h>
+
+#include <Protocol/Cpu.h>
+#include <Protocol/HardwareInterrupt.h>
+
+#include <Omap3530/Omap3530.h>
+
+//
+// Notifications
+//
+EFI_EVENT EfiExitBootServicesEvent      = (EFI_EVENT)NULL;
+
+
+HARDWARE_INTERRUPT_HANDLER  gRegisteredInterruptHandlers[INT_NROF_VECTORS];
+
+/**
+  Shutdown our hardware
+
+  DXE Core will disable interrupts and turn off the timer and disable interrupts
+  after all the event handlers have run.
+
+  @param[in]  Event   The Event that is being processed
+  @param[in]  Context Event Context
+**/
+VOID
+EFIAPI
+ExitBootServicesEvent (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  // Disable all interrupts
+  MmioWrite32 (INTCPS_MIR(0), 0xFFFFFFFF);
+  MmioWrite32 (INTCPS_MIR(1), 0xFFFFFFFF);
+  MmioWrite32 (INTCPS_MIR(2), 0xFFFFFFFF);
+  MmioWrite32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWIRQAGR);
+
+  // Add code here to disable all FIQs as debugger may have turned one on
+}
+
+/**
+  Register Handler for the specified interrupt source.
+
+  @param This     Instance pointer for this protocol
+  @param Source   Hardware source of the interrupt
+  @param Handler  Callback for interrupt. NULL to unregister
+
+  @retval EFI_SUCCESS Source was updated to support Handler.
+  @retval EFI_DEVICE_ERROR  Hardware could not be programmed.
+
+**/
+EFI_STATUS
+EFIAPI
+RegisterInterruptSource (
+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,
+  IN HARDWARE_INTERRUPT_SOURCE          Source,
+  IN HARDWARE_INTERRUPT_HANDLER         Handler
+  )
+{
+  if (Source > MAX_VECTOR) {
+    ASSERT(FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  if ((MmioRead32 (INTCPS_ILR(Source)) & INTCPS_ILR_FIQ) == INTCPS_ILR_FIQ) {
+    // This vector has been programmed as FIQ so we can't use it for IRQ
+    // EFI does not use FIQ, but the debugger can use it to check for
+    // ctrl-c. So this ASSERT means you have a conflict with the debug agent
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  if ((Handler == NULL) && (gRegisteredInterruptHandlers[Source] == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((Handler != NULL) && (gRegisteredInterruptHandlers[Source] != NULL)) {
+    return EFI_ALREADY_STARTED;
+  }
+
+  gRegisteredInterruptHandlers[Source] = Handler;
+  return This->EnableInterruptSource(This, Source);
+}
+
+
+/**
+  Enable interrupt source Source.
+
+  @param This     Instance pointer for this protocol
+  @param Source   Hardware source of the interrupt
+
+  @retval EFI_SUCCESS       Source interrupt enabled.
+  @retval EFI_DEVICE_ERROR  Hardware could not be programmed.
+
+**/
+EFI_STATUS
+EFIAPI
+EnableInterruptSource (
+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,
+  IN HARDWARE_INTERRUPT_SOURCE          Source
+  )
+{
+  UINTN Bank;
+  UINTN Bit;
+
+  if (Source > MAX_VECTOR) {
+    ASSERT(FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  Bank = Source / 32;
+  Bit  = 1UL << (Source % 32);
+
+  MmioWrite32 (INTCPS_MIR_CLEAR(Bank), Bit);
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Disable interrupt source Source.
+
+  @param This     Instance pointer for this protocol
+  @param Source   Hardware source of the interrupt
+
+  @retval EFI_SUCCESS       Source interrupt disabled.
+  @retval EFI_DEVICE_ERROR  Hardware could not be programmed.
+
+**/
+EFI_STATUS
+EFIAPI
+DisableInterruptSource (
+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,
+  IN HARDWARE_INTERRUPT_SOURCE          Source
+  )
+{
+  UINTN Bank;
+  UINTN Bit;
+
+  if (Source > MAX_VECTOR) {
+    ASSERT(FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  Bank = Source / 32;
+  Bit  = 1UL << (Source % 32);
+
+  MmioWrite32 (INTCPS_MIR_SET(Bank), Bit);
+
+  return EFI_SUCCESS;
+}
+
+
+
+/**
+  Return current state of interrupt source Source.
+
+  @param This     Instance pointer for this protocol
+  @param Source   Hardware source of the interrupt
+  @param InterruptState  TRUE: source enabled, FALSE: source disabled.
+
+  @retval EFI_SUCCESS       InterruptState is valid
+  @retval EFI_DEVICE_ERROR  InterruptState is not valid
+
+**/
+EFI_STATUS
+EFIAPI
+GetInterruptSourceState (
+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,
+  IN HARDWARE_INTERRUPT_SOURCE          Source,
+  IN BOOLEAN                            *InterruptState
+  )
+{
+  UINTN Bank;
+  UINTN Bit;
+
+  if (InterruptState == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Source > MAX_VECTOR) {
+    ASSERT(FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  Bank = Source / 32;
+  Bit  = 1UL << (Source % 32);
+
+  if ((MmioRead32(INTCPS_MIR(Bank)) & Bit) == Bit) {
+    *InterruptState = FALSE;
+  } else {
+    *InterruptState = TRUE;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Signal to the hardware that the End Of Intrrupt state
+  has been reached.
+
+  @param This     Instance pointer for this protocol
+  @param Source   Hardware source of the interrupt
+
+  @retval EFI_SUCCESS       Source interrupt EOI'ed.
+  @retval EFI_DEVICE_ERROR  Hardware could not be programmed.
+
+**/
+EFI_STATUS
+EFIAPI
+EndOfInterrupt (
+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,
+  IN HARDWARE_INTERRUPT_SOURCE          Source
+  )
+{
+  MmioWrite32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWIRQAGR);
+  ArmDataSynchronizationBarrier ();
+  return EFI_SUCCESS;
+}
+
+
+/**
+  EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs.
+
+  @param  InterruptType    Defines the type of interrupt or exception that
+                           occurred on the processor.This parameter is processor architecture specific.
+  @param  SystemContext    A pointer to the processor context when
+                           the interrupt occurred on the processor.
+
+  @return None
+
+**/
+VOID
+EFIAPI
+IrqInterruptHandler (
+  IN EFI_EXCEPTION_TYPE           InterruptType,
+  IN EFI_SYSTEM_CONTEXT           SystemContext
+  )
+{
+  UINT32                     Vector;
+  HARDWARE_INTERRUPT_HANDLER InterruptHandler;
+
+  Vector = MmioRead32 (INTCPS_SIR_IRQ) & INTCPS_SIR_IRQ_MASK;
+
+  // Needed to prevent infinite nesting when Time Driver lowers TPL
+  MmioWrite32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWIRQAGR);
+  ArmDataSynchronizationBarrier ();
+
+  InterruptHandler = gRegisteredInterruptHandlers[Vector];
+  if (InterruptHandler != NULL) {
+    // Call the registered interrupt handler.
+    InterruptHandler (Vector, SystemContext);
+  }
+
+  // Needed to clear after running the handler
+  MmioWrite32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWIRQAGR);
+  ArmDataSynchronizationBarrier ();
+}
+
+//
+// Making this global saves a few bytes in image size
+//
+EFI_HANDLE  gHardwareInterruptHandle = NULL;
+
+//
+// The protocol instance produced by this driver
+//
+EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol = {
+  RegisterInterruptSource,
+  EnableInterruptSource,
+  DisableInterruptSource,
+  GetInterruptSourceState,
+  EndOfInterrupt
+};
+
+STATIC VOID *mCpuArchProtocolNotifyEventRegistration;
+
+STATIC
+VOID
+EFIAPI
+CpuArchEventProtocolNotify (
+  IN  EFI_EVENT       Event,
+  IN  VOID            *Context
+  )
+{
+  EFI_CPU_ARCH_PROTOCOL   *Cpu;
+  EFI_STATUS              Status;
+
+  //
+  // Get the CPU protocol that this driver requires.
+  //
+  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: gBS->LocateProtocol() - %r\n", __FUNCTION__,
+      Status));
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // Unregister the default exception handler.
+  //
+  Status = Cpu->RegisterInterruptHandler (Cpu, EXCEPT_ARM_IRQ, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Cpu->RegisterInterruptHandler() - %r\n",
+      __FUNCTION__, Status));
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // Register to receive interrupts
+  //
+  Status = Cpu->RegisterInterruptHandler (Cpu, EXCEPT_ARM_IRQ,
+                  IrqInterruptHandler);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Cpu->RegisterInterruptHandler() - %r\n",
+      __FUNCTION__, Status));
+    ASSERT (FALSE);
+    return;
+  }
+}
+
+/**
+  Initialize the state information for the CPU Architectural Protocol
+
+  @param  ImageHandle   of the loaded driver
+  @param  SystemTable   Pointer to the System Table
+
+  @retval EFI_SUCCESS           Protocol registered
+  @retval EFI_OUT_OF_RESOURCES  Cannot allocate protocol data structure
+  @retval EFI_DEVICE_ERROR      Hardware problems
+
+**/
+EFI_STATUS
+InterruptDxeInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+  EFI_EVENT   CpuArchEvent;
+
+  // Make sure the Interrupt Controller Protocol is not already installed in the system.
+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
+
+  // Make sure all interrupts are disabled by default.
+  MmioWrite32 (INTCPS_MIR(0), 0xFFFFFFFF);
+  MmioWrite32 (INTCPS_MIR(1), 0xFFFFFFFF);
+  MmioWrite32 (INTCPS_MIR(2), 0xFFFFFFFF);
+  MmioOr32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWIRQAGR);
+
+  Status = gBS->InstallMultipleProtocolInterfaces(&gHardwareInterruptHandle,
+                                                  &gHardwareInterruptProtocolGuid,   &gHardwareInterruptProtocol,
+                                                  NULL);
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  // Install the interrupt handler as soon as the CPU arch protocol appears.
+  //
+  CpuArchEvent = EfiCreateProtocolNotifyEvent (
+                   &gEfiCpuArchProtocolGuid,
+                   TPL_CALLBACK,
+                   CpuArchEventProtocolNotify,
+                   NULL,
+                   &mCpuArchProtocolNotifyEventRegistration
+                   );
+  ASSERT (CpuArchEvent != NULL);
+
+  // Register for an ExitBootServicesEvent
+  Status = gBS->CreateEvent(EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    gBS->CloseEvent (CpuArchEvent);
+  }
+
+  return Status;
+}
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/InterruptDxe.inf b/Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/InterruptDxe.inf
new file mode 100644
index 0000000000..2a956c2767
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/InterruptDxe.inf
@@ -0,0 +1,48 @@
+#/** @file
+#
+#  Interrupt DXE driver
+#
+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = Omap35xxBoardInterruptDxe
+  FILE_GUID                      = 23eed05d-1b93-4a1a-8e1b-931d69e37952
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = InterruptDxeInitialize
+
+
+[Sources.common]
+  HardwareInterrupt.c
+
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  UefiLib
+  UefiBootServicesTableLib
+  DebugLib
+  PrintLib
+  UefiDriverEntryPoint
+  IoLib
+  ArmLib
+
+[Protocols]
+  gHardwareInterruptProtocolGuid  ## PRODUCES
+  gEfiCpuArchProtocolGuid         ## CONSUMES ## NOTIFY
+
+[FixedPcd.common]
+  gEmbeddedTokenSpaceGuid.PcdInterruptBaseAddress
+
+[Depex]
+  TRUE
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c b/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c
new file mode 100644
index 0000000000..f8af498056
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c
@@ -0,0 +1,439 @@
+/** @file
+
+ Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ **/
+
+#include <PiDxe.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Guid/GlobalVariable.h>
+
+#include "LcdGraphicsOutputDxe.h"
+
+extern BOOLEAN mDisplayInitialized;
+
+//
+// Function Definitions
+//
+
+STATIC
+EFI_STATUS
+VideoCopyNoHorizontalOverlap (
+  IN UINTN          BitsPerPixel,
+  IN volatile VOID  *FrameBufferBase,
+  IN UINT32         HorizontalResolution,
+  IN UINTN          SourceX,
+  IN UINTN          SourceY,
+  IN UINTN          DestinationX,
+  IN UINTN          DestinationY,
+  IN UINTN          Width,
+  IN UINTN          Height
+  )
+{
+  EFI_STATUS    Status = EFI_SUCCESS;
+  UINTN         SourceLine;
+  UINTN         DestinationLine;
+  UINTN         WidthInBytes;
+  UINTN         LineCount;
+  INTN          Step;
+  VOID          *SourceAddr;
+  VOID          *DestinationAddr;
+
+  if( DestinationY <= SourceY ) {
+    // scrolling up (or horizontally but without overlap)
+    SourceLine       = SourceY;
+    DestinationLine  = DestinationY;
+    Step             = 1;
+  } else {
+    // scrolling down
+    SourceLine       = SourceY + Height;
+    DestinationLine  = DestinationY + Height;
+    Step             = -1;
+  }
+
+  WidthInBytes = Width * 2;
+
+  for( LineCount = 0; LineCount < Height; LineCount++ ) {
+    // Update the start addresses of source & destination using 16bit pointer arithmetic
+    SourceAddr      = (VOID *)((UINT16 *)FrameBufferBase + SourceLine      * HorizontalResolution + SourceX     );
+    DestinationAddr = (VOID *)((UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationX);
+
+    // Copy the entire line Y from video ram to the temp buffer
+    CopyMem( DestinationAddr, SourceAddr, WidthInBytes);
+
+    // Update the line numbers
+    SourceLine      += Step;
+    DestinationLine += Step;
+  }
+
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+VideoCopyHorizontalOverlap (
+  IN UINTN          BitsPerPixel,
+  IN volatile VOID  *FrameBufferBase,
+  UINT32            HorizontalResolution,
+  IN UINTN          SourceX,
+  IN UINTN          SourceY,
+  IN UINTN          DestinationX,
+  IN UINTN          DestinationY,
+  IN UINTN          Width,
+  IN UINTN          Height
+  )
+{
+  EFI_STATUS      Status = EFI_SUCCESS;
+
+  UINT16 *PixelBuffer16bit;
+  UINT16 *SourcePixel16bit;
+  UINT16 *DestinationPixel16bit;
+
+  UINT32          SourcePixelY;
+  UINT32          DestinationPixelY;
+  UINTN           SizeIn16Bits;
+
+  // Allocate a temporary buffer
+  PixelBuffer16bit = (UINT16 *) AllocatePool((Height * Width) * sizeof(UINT16));
+
+  if (PixelBuffer16bit == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto EXIT;
+  }
+
+  // Access each pixel inside the source area of the Video Memory and copy it to the temp buffer
+
+  SizeIn16Bits = Width * 2;
+
+  for (SourcePixelY = SourceY, DestinationPixel16bit = PixelBuffer16bit;
+       SourcePixelY < SourceY + Height;
+       SourcePixelY++, DestinationPixel16bit += Width)
+  {
+    // Calculate the source address:
+    SourcePixel16bit = (UINT16 *)FrameBufferBase + SourcePixelY * HorizontalResolution + SourceX;
+
+    // Copy the entire line Y from Video to the temp buffer
+    CopyMem( (VOID *)DestinationPixel16bit, (CONST VOID *)SourcePixel16bit, SizeIn16Bits);
+  }
+
+  // Copy from the temp buffer into the destination area of the Video Memory
+
+  for (DestinationPixelY = DestinationY, SourcePixel16bit = PixelBuffer16bit;
+       DestinationPixelY < DestinationY + Height;
+       DestinationPixelY++, SourcePixel16bit += Width)
+  {
+    // Calculate the target address:
+    DestinationPixel16bit = (UINT16 *)FrameBufferBase + (DestinationPixelY * HorizontalResolution + DestinationX);
+
+    // Copy the entire line Y from the temp buffer to Video
+    CopyMem( (VOID *)DestinationPixel16bit, (CONST VOID *)SourcePixel16bit, SizeIn16Bits);
+  }
+
+  // Free the allocated memory
+  FreePool((VOID *) PixelBuffer16bit);
+
+
+EXIT:
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+BltVideoFill (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *EfiSourcePixel,     OPTIONAL
+  IN UINTN                               SourceX,
+  IN UINTN                               SourceY,
+  IN UINTN                               DestinationX,
+  IN UINTN                               DestinationY,
+  IN UINTN                               Width,
+  IN UINTN                               Height,
+  IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer
+  )
+{
+  EFI_PIXEL_BITMASK*  PixelInformation;
+  EFI_STATUS          Status;
+  UINT32              HorizontalResolution;
+  VOID                *FrameBufferBase;
+  UINT16              *DestinationPixel16bit;
+  UINT16              Pixel16bit;
+  UINT32              DestinationPixelX;
+  UINT32              DestinationLine;
+
+  Status           = EFI_SUCCESS;
+  PixelInformation = &This->Mode->Info->PixelInformation;
+  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
+  HorizontalResolution = This->Mode->Info->HorizontalResolution;
+
+  // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
+  Pixel16bit = (UINT16) (
+      ( (EfiSourcePixel->Red      <<  8) & PixelInformation->RedMask      )
+    | ( (EfiSourcePixel->Green    <<  3) & PixelInformation->GreenMask    )
+    | ( (EfiSourcePixel->Blue     >>  3) & PixelInformation->BlueMask     )
+   );
+
+  // Copy the SourcePixel into every pixel inside the target rectangle
+  for (DestinationLine = DestinationY;
+       DestinationLine < DestinationY + Height;
+       DestinationLine++)
+  {
+    for (DestinationPixelX = DestinationX;
+         DestinationPixelX < DestinationX + Width;
+         DestinationPixelX++)
+    {
+      // Calculate the target address:
+      DestinationPixel16bit =  (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution  + DestinationPixelX;
+
+      // Copy the pixel into the new target
+      *DestinationPixel16bit = Pixel16bit;
+    }
+  }
+
+
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+BltVideoToBltBuffer (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *BltBuffer,     OPTIONAL
+  IN UINTN                               SourceX,
+  IN UINTN                               SourceY,
+  IN UINTN                               DestinationX,
+  IN UINTN                               DestinationY,
+  IN UINTN                               Width,
+  IN UINTN                               Height,
+  IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer
+  )
+{
+  EFI_STATUS         Status;
+  UINT32             HorizontalResolution;
+  EFI_PIXEL_BITMASK  *PixelInformation;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiDestinationPixel;
+  VOID               *FrameBufferBase;
+  UINT16             *SourcePixel16bit;
+  UINT16             Pixel16bit;
+  UINT32             SourcePixelX;
+  UINT32             SourceLine;
+  UINT32             DestinationPixelX;
+  UINT32             DestinationLine;
+  UINT32             BltBufferHorizontalResolution;
+
+  Status = EFI_SUCCESS;
+  PixelInformation = &This->Mode->Info->PixelInformation;
+  HorizontalResolution = This->Mode->Info->HorizontalResolution;
+  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
+
+  if(( Delta != 0 ) && ( Delta != Width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
+    // Delta is not zero and it is different from the width.
+    // Divide it by the size of a pixel to find out the buffer's horizontal resolution.
+    BltBufferHorizontalResolution = (UINT32) (Delta / sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+  } else {
+    BltBufferHorizontalResolution = Width;
+  }
+
+  // Access each pixel inside the Video Memory
+  for (SourceLine = SourceY, DestinationLine = DestinationY;
+       SourceLine < SourceY + Height;
+       SourceLine++, DestinationLine++)
+  {
+    for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;
+         SourcePixelX < SourceX + Width;
+         SourcePixelX++, DestinationPixelX++)
+    {
+      // Calculate the source and target addresses:
+      SourcePixel16bit = (UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourcePixelX;
+      EfiDestinationPixel = BltBuffer + DestinationLine * BltBufferHorizontalResolution + DestinationPixelX;
+
+      // Snapshot the pixel from the video buffer once, to speed up the operation.
+      // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
+      Pixel16bit = *SourcePixel16bit;
+
+      // Copy the pixel into the new target
+      EfiDestinationPixel->Red      = (UINT8) ( (Pixel16bit & PixelInformation->RedMask     ) >>  8 );
+      EfiDestinationPixel->Green    = (UINT8) ( (Pixel16bit & PixelInformation->GreenMask   ) >>  3 );
+      EfiDestinationPixel->Blue     = (UINT8) ( (Pixel16bit & PixelInformation->BlueMask    ) <<  3 );
+    }
+  }
+
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+BltBufferToVideo (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *BltBuffer,     OPTIONAL
+  IN UINTN                               SourceX,
+  IN UINTN                               SourceY,
+  IN UINTN                               DestinationX,
+  IN UINTN                               DestinationY,
+  IN UINTN                               Width,
+  IN UINTN                               Height,
+  IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer
+  )
+{
+  EFI_STATUS         Status;
+  UINT32             HorizontalResolution;
+  EFI_PIXEL_BITMASK  *PixelInformation;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiSourcePixel;
+  VOID               *FrameBufferBase;
+  UINT16             *DestinationPixel16bit;
+  UINT32             SourcePixelX;
+  UINT32             SourceLine;
+  UINT32             DestinationPixelX;
+  UINT32             DestinationLine;
+  UINT32             BltBufferHorizontalResolution;
+
+  Status = EFI_SUCCESS;
+  PixelInformation = &This->Mode->Info->PixelInformation;
+  HorizontalResolution = This->Mode->Info->HorizontalResolution;
+  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
+
+  if(( Delta != 0 ) && ( Delta != Width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
+    // Delta is not zero and it is different from the width.
+    // Divide it by the size of a pixel to find out the buffer's horizontal resolution.
+    BltBufferHorizontalResolution = (UINT32) (Delta / sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+  } else {
+    BltBufferHorizontalResolution = Width;
+  }
+
+  // Access each pixel inside the BltBuffer Memory
+  for (SourceLine = SourceY, DestinationLine = DestinationY;
+       SourceLine < SourceY + Height;
+       SourceLine++, DestinationLine++) {
+
+    for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;
+         SourcePixelX < SourceX + Width;
+         SourcePixelX++, DestinationPixelX++)
+    {
+      // Calculate the source and target addresses:
+      EfiSourcePixel  = BltBuffer + SourceLine * BltBufferHorizontalResolution + SourcePixelX;
+      DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX;
+
+      // Copy the pixel into the new target
+      // Only the most significant bits will be copied across:
+      // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits
+        *DestinationPixel16bit = (UINT16) (
+              ( (EfiSourcePixel->Red      <<  8) & PixelInformation->RedMask      )
+            | ( (EfiSourcePixel->Green    <<  3) & PixelInformation->GreenMask    )
+            | ( (EfiSourcePixel->Blue     >>  3) & PixelInformation->BlueMask     )
+            );
+      }
+    }
+
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+BltVideoToVideo (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *BltBuffer,     OPTIONAL
+  IN UINTN                               SourceX,
+  IN UINTN                               SourceY,
+  IN UINTN                               DestinationX,
+  IN UINTN                               DestinationY,
+  IN UINTN                               Width,
+  IN UINTN                               Height,
+  IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer
+  )
+{
+  EFI_STATUS         Status;
+  UINT32             HorizontalResolution;
+  UINTN              BitsPerPixel;
+  VOID               *FrameBufferBase;
+
+  BitsPerPixel = 16;
+
+  HorizontalResolution = This->Mode->Info->HorizontalResolution;
+  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
+
+  //
+  // BltVideo to BltVideo:
+  //
+  //  Source is the Video Memory,
+  //  Destination is the Video Memory
+
+  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
+
+  // The UEFI spec currently states:
+  // "There is no limitation on the overlapping of the source and destination rectangles"
+  // Therefore, we must be careful to avoid overwriting the source data
+  if( SourceY == DestinationY ) {
+    // Copying within the same height, e.g. horizontal shift
+    if( SourceX == DestinationX ) {
+      // Nothing to do
+      Status = EFI_SUCCESS;
+    } else if( ((SourceX>DestinationX)?(SourceX - DestinationX):(DestinationX - SourceX)) < Width ) {
+      // There is overlap
+      Status = VideoCopyHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );
+    } else {
+      // No overlap
+      Status = VideoCopyNoHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );
+    }
+  } else {
+    // Copying from different heights
+    Status = VideoCopyNoHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+LcdGraphicsBlt (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *BltBuffer,     OPTIONAL
+  IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION   BltOperation,
+  IN UINTN                               SourceX,
+  IN UINTN                               SourceY,
+  IN UINTN                               DestinationX,
+  IN UINTN                               DestinationY,
+  IN UINTN                               Width,
+  IN UINTN                               Height,
+  IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer
+  )
+{
+  EFI_STATUS    Status;
+  LCD_INSTANCE  *Instance;
+
+  Instance = LCD_INSTANCE_FROM_GOP_THIS(This);
+
+  if (!mDisplayInitialized) {
+    InitializeDisplay (Instance);
+  }
+
+  switch (BltOperation) {
+  case EfiBltVideoFill:
+    Status = BltVideoFill (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
+    break;
+
+  case EfiBltVideoToBltBuffer:
+    Status = BltVideoToBltBuffer (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
+    break;
+
+  case EfiBltBufferToVideo:
+    Status = BltBufferToVideo (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
+    break;
+
+  case EfiBltVideoToVideo:
+    Status = BltVideoToVideo (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
+    break;
+
+  case EfiGraphicsOutputBltOperationMax:
+  default:
+    DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: Invalid Operation\n"));
+    Status = EFI_INVALID_PARAMETER;
+    break;
+}
+
+  return Status;
+}
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c b/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c
new file mode 100644
index 0000000000..ebb520a0ac
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c
@@ -0,0 +1,394 @@
+/** @file
+
+ Copyright (c) 2011-2014, ARM Ltd. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "LcdGraphicsOutputDxe.h"
+
+BOOLEAN mDisplayInitialized = FALSE;
+
+LCD_MODE LcdModes[] = {
+  {
+    0, 640, 480,
+    9, 4,
+    96, 16, 48,
+    2, 10, 33
+  },
+  {
+    1, 800, 600,
+    11, 2,
+    120, 56, 64,
+    5, 37, 22
+  },
+  {
+    2, 1024, 768,
+    6, 2,
+    96, 16, 48,
+    2, 10, 33
+  },
+};
+
+LCD_INSTANCE mLcdTemplate = {
+  LCD_INSTANCE_SIGNATURE,
+  NULL, // Handle
+  { // ModeInfo
+    0, // Version
+    0, // HorizontalResolution
+    0, // VerticalResolution
+    PixelBltOnly, // PixelFormat
+    {
+      0xF800, //RedMask;
+      0x7E0, //GreenMask;
+      0x1F, //BlueMask;
+      0x0//ReservedMask
+    }, // PixelInformation
+    0, // PixelsPerScanLine
+  },
+  { // Mode
+    3, // MaxMode;
+    0, // Mode;
+    NULL, // Info;
+    0, // SizeOfInfo;
+    0, // FrameBufferBase;
+    0 // FrameBufferSize;
+  },
+  { // Gop
+    LcdGraphicsQueryMode,  // QueryMode
+    LcdGraphicsSetMode,    // SetMode
+    LcdGraphicsBlt,        // Blt
+    NULL                     // *Mode
+  },
+  { // DevicePath
+    {
+      {
+        HARDWARE_DEVICE_PATH, HW_VENDOR_DP,
+        { (UINT8) (sizeof(VENDOR_DEVICE_PATH)), (UINT8) ((sizeof(VENDOR_DEVICE_PATH)) >> 8) },
+      },
+      // Hardware Device Path for Lcd
+      EFI_CALLER_ID_GUID // Use the driver's GUID
+    },
+    {
+      END_DEVICE_PATH_TYPE,
+      END_ENTIRE_DEVICE_PATH_SUBTYPE,
+      { sizeof(EFI_DEVICE_PATH_PROTOCOL), 0}
+    }
+  }
+};
+
+EFI_STATUS
+LcdInstanceContructor (
+  OUT LCD_INSTANCE** NewInstance
+  )
+{
+  LCD_INSTANCE* Instance;
+
+  Instance = AllocateCopyPool (sizeof(LCD_INSTANCE), &mLcdTemplate);
+  if (Instance == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Instance->Gop.Mode          = &Instance->Mode;
+  Instance->Mode.Info         = &Instance->ModeInfo;
+
+  *NewInstance = Instance;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+LcdPlatformGetVram (
+  OUT EFI_PHYSICAL_ADDRESS*  VramBaseAddress,
+  OUT UINTN*                 VramSize
+  )
+{
+  EFI_STATUS             Status;
+  EFI_CPU_ARCH_PROTOCOL  *Cpu;
+  UINTN                  MaxSize;
+
+  MaxSize = 0x500000;
+  *VramSize = MaxSize;
+
+  // Allocate VRAM from DRAM
+  Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, EFI_SIZE_TO_PAGES((MaxSize)), VramBaseAddress);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  // Ensure the Cpu architectural protocol is already installed
+  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);
+  ASSERT_EFI_ERROR(Status);
+
+  // Mark the VRAM as un-cacheable. The VRAM is inside the DRAM, which is cacheable.
+  Status = Cpu->SetMemoryAttributes (Cpu, *VramBaseAddress, *VramSize, EFI_MEMORY_UC);
+  if (EFI_ERROR(Status)) {
+    gBS->FreePool (VramBaseAddress);
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DssSetMode (
+  UINT32 VramBaseAddress,
+  UINTN  ModeNumber
+  )
+{
+  // Make sure the interface clock is running
+  MmioWrite32 (CM_ICLKEN_DSS, EN_DSS);
+
+  // Stop the functional clocks
+  MmioAnd32 (CM_FCLKEN_DSS, ~(EN_DSS1 | EN_DSS2 | EN_TV));
+
+  // Program the DSS clock divisor
+  MmioWrite32 (CM_CLKSEL_DSS, 0x1000 | (LcdModes[ModeNumber].DssDivisor));
+
+  // Start the functional clocks
+  MmioOr32 (CM_FCLKEN_DSS, (EN_DSS1 | EN_DSS2 | EN_TV));
+
+  // Wait for DSS to stabilize
+  gBS->Stall(1);
+
+  // Reset the subsystem
+  MmioWrite32(DSS_SYSCONFIG, DSS_SOFTRESET);
+  while (!(MmioRead32 (DSS_SYSSTATUS) & DSS_RESETDONE));
+
+  // Configure LCD parameters
+  MmioWrite32 (DISPC_SIZE_LCD,
+               ((LcdModes[ModeNumber].HorizontalResolution - 1)
+               | ((LcdModes[ModeNumber].VerticalResolution - 1) << 16))
+              );
+  MmioWrite32 (DISPC_TIMING_H,
+               ( (LcdModes[ModeNumber].HSync - 1)
+               | ((LcdModes[ModeNumber].HFrontPorch - 1) << 8)
+               | ((LcdModes[ModeNumber].HBackPorch - 1) << 20))
+              );
+  MmioWrite32 (DISPC_TIMING_V,
+               ( (LcdModes[ModeNumber].VSync - 1)
+               | ((LcdModes[ModeNumber].VFrontPorch - 1) << 8)
+               | ((LcdModes[ModeNumber].VBackPorch - 1) << 20))
+              );
+
+  // Set the framebuffer to only load frames (no gamma tables)
+  MmioAnd32 (DISPC_CONFIG, CLEARLOADMODE);
+  MmioOr32  (DISPC_CONFIG, LOAD_FRAME_ONLY);
+
+  // Divisor for the pixel clock
+  MmioWrite32(DISPC_DIVISOR, ((1 << 16) | LcdModes[ModeNumber].DispcDivisor) );
+
+  // Set up the graphics layer
+  MmioWrite32 (DISPC_GFX_PRELD, 0x2D8);
+  MmioWrite32 (DISPC_GFX_BA0, VramBaseAddress);
+  MmioWrite32 (DISPC_GFX_SIZE,
+               ((LcdModes[ModeNumber].HorizontalResolution - 1)
+               | ((LcdModes[ModeNumber].VerticalResolution - 1) << 16))
+              );
+
+  MmioWrite32(DISPC_GFX_ATTR, (GFXENABLE | RGB16 | BURSTSIZE16));
+
+  // Start it all
+  MmioOr32 (DISPC_CONTROL, (LCDENABLE | ACTIVEMATRIX | DATALINES24 | BYPASS_MODE | LCDENABLESIGNAL));
+  MmioOr32 (DISPC_CONTROL, GOLCD);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+HwInitializeDisplay (
+  UINTN VramBaseAddress,
+  UINTN VramSize
+  )
+{
+  EFI_STATUS    Status;
+  UINT8         Data;
+  EFI_TPL       OldTpl;
+  EMBEDDED_EXTERNAL_DEVICE   *gTPS65950;
+
+  // Enable power lines used by TFP410
+  Status = gBS->LocateProtocol (&gEmbeddedExternalDeviceProtocolGuid, NULL, (VOID **)&gTPS65950);
+  ASSERT_EFI_ERROR (Status);
+
+  OldTpl = gBS->RaiseTPL(TPL_NOTIFY);
+  Data = VAUX_DEV_GRP_P1;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VPLL2_DEV_GRP), 1, &Data);
+  ASSERT_EFI_ERROR(Status);
+
+  Data = VAUX_DEDICATED_18V;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VPLL2_DEDICATED), 1, &Data);
+  ASSERT_EFI_ERROR (Status);
+
+  // Power up TFP410 (set GPIO2 on TPS - for BeagleBoard-xM)
+  Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, GPIODATADIR1), 1, &Data);
+  ASSERT_EFI_ERROR (Status);
+  Data |= BIT2;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, GPIODATADIR1), 1, &Data);
+  ASSERT_EFI_ERROR (Status);
+
+  Data = BIT2;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, SETGPIODATAOUT1), 1, &Data);
+  ASSERT_EFI_ERROR (Status);
+
+  gBS->RestoreTPL(OldTpl);
+
+  // Power up TFP410 (set GPIO 170 - for older BeagleBoards)
+  MmioAnd32 (GPIO6_BASE + GPIO_OE, ~BIT10);
+  MmioOr32  (GPIO6_BASE + GPIO_SETDATAOUT, BIT10);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+InitializeDisplay (
+  IN LCD_INSTANCE* Instance
+  )
+{
+  EFI_STATUS           Status;
+  UINTN                VramSize;
+  EFI_PHYSICAL_ADDRESS VramBaseAddress;
+
+  Status = LcdPlatformGetVram (&VramBaseAddress, &VramSize);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Instance->Mode.FrameBufferBase = VramBaseAddress;
+  Instance->Mode.FrameBufferSize = VramSize;
+
+  Status = HwInitializeDisplay((UINTN)VramBaseAddress, VramSize);
+  if (!EFI_ERROR (Status)) {
+    mDisplayInitialized = TRUE;
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+LcdGraphicsQueryMode (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL            *This,
+  IN UINT32                                  ModeNumber,
+  OUT UINTN                                  *SizeOfInfo,
+  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION   **Info
+  )
+{
+  LCD_INSTANCE  *Instance;
+
+  Instance = LCD_INSTANCE_FROM_GOP_THIS(This);
+
+  if (!mDisplayInitialized) {
+    InitializeDisplay (Instance);
+  }
+
+  // Error checking
+  if ( (This == NULL) || (Info == NULL) || (SizeOfInfo == NULL) || (ModeNumber >= This->Mode->MaxMode) ) {
+    DEBUG((DEBUG_ERROR, "LcdGraphicsQueryMode: ERROR - For mode number %d : Invalid Parameter.\n", ModeNumber ));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *Info = AllocateCopyPool(sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), &Instance->ModeInfo);
+  if (*Info == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
+
+  (*Info)->Version = 0;
+  (*Info)->HorizontalResolution = LcdModes[ModeNumber].HorizontalResolution;
+  (*Info)->VerticalResolution = LcdModes[ModeNumber].VerticalResolution;
+  (*Info)->PixelFormat = PixelBltOnly;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+LcdGraphicsSetMode (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL   *This,
+  IN UINT32                         ModeNumber
+  )
+{
+  LCD_INSTANCE  *Instance;
+
+  Instance = LCD_INSTANCE_FROM_GOP_THIS(This);
+
+  if (ModeNumber >= Instance->Mode.MaxMode) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (!mDisplayInitialized) {
+    InitializeDisplay (Instance);
+  }
+
+  DssSetMode((UINT32)Instance->Mode.FrameBufferBase, ModeNumber);
+
+  Instance->Mode.Mode = ModeNumber;
+  Instance->ModeInfo.HorizontalResolution = LcdModes[ModeNumber].HorizontalResolution;
+  Instance->ModeInfo.VerticalResolution = LcdModes[ModeNumber].VerticalResolution;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+LcdGraphicsOutputDxeInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS Status = EFI_SUCCESS;
+  LCD_INSTANCE* Instance;
+
+  Status = LcdInstanceContructor (&Instance);
+  if (EFI_ERROR(Status)) {
+    goto EXIT;
+  }
+
+  // Install the Graphics Output Protocol and the Device Path
+  Status = gBS->InstallMultipleProtocolInterfaces(
+             &Instance->Handle,
+             &gEfiGraphicsOutputProtocolGuid, &Instance->Gop,
+             &gEfiDevicePathProtocolGuid,     &Instance->DevicePath,
+             NULL
+             );
+
+  if (EFI_ERROR(Status)) {
+    DEBUG((DEBUG_ERROR, "GraphicsOutputDxeInitialize: Can not install the protocol. Exit Status=%r\n", Status));
+    goto EXIT;
+  }
+
+  // Register for an ExitBootServicesEvent
+  // When ExitBootServices starts, this function here will make sure that the graphics driver will shut down properly,
+  // i.e. it will free up all allocated memory and perform any necessary hardware re-configuration.
+  /*Status = gBS->CreateEvent (
+               EVT_SIGNAL_EXIT_BOOT_SERVICES,
+               TPL_NOTIFY,
+               LcdGraphicsExitBootServicesEvent, NULL,
+               &Instance->ExitBootServicesEvent
+               );
+
+  if (EFI_ERROR(Status)) {
+    DEBUG((DEBUG_ERROR, "GraphicsOutputDxeInitialize: Can not install the ExitBootServicesEvent handler. Exit Status=%r\n", Status));
+    goto EXIT_ERROR_UNINSTALL_PROTOCOL;
+  }*/
+
+  // To get here, everything must be fine, so just exit
+  goto EXIT;
+
+//EXIT_ERROR_UNINSTALL_PROTOCOL:
+  /* The following function could return an error message,
+   * however, to get here something must have gone wrong already,
+   * so preserve the original error, i.e. don't change
+   * the Status variable, even it fails to uninstall the protocol.
+   */
+  /*  gBS->UninstallMultipleProtocolInterfaces (
+        Instance->Handle,
+        &gEfiGraphicsOutputProtocolGuid, &Instance->Gop, // Uninstall Graphics Output protocol
+        &gEfiDevicePathProtocolGuid,     &Instance->DevicePath,     // Uninstall device path
+        NULL
+        );*/
+
+EXIT:
+  return Status;
+
+}
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.h b/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.h
new file mode 100644
index 0000000000..c4671ab444
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.h
@@ -0,0 +1,151 @@
+/** @file
+
+ Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3_DSS_GRAPHICS__
+#define __OMAP3_DSS_GRAPHICS__
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/IoLib.h>
+
+#include <Protocol/DevicePathToText.h>
+#include <Protocol/EmbeddedExternalDevice.h>
+#include <Protocol/Cpu.h>
+
+#include <Guid/GlobalVariable.h>
+
+#include <Omap3530/Omap3530.h>
+#include <TPS65950.h>
+
+typedef struct {
+  VENDOR_DEVICE_PATH            Guid;
+  EFI_DEVICE_PATH_PROTOCOL      End;
+} LCD_GRAPHICS_DEVICE_PATH;
+
+typedef struct {
+  UINTN                                 Signature;
+  EFI_HANDLE                            Handle;
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  ModeInfo;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE     Mode;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL          Gop;
+  LCD_GRAPHICS_DEVICE_PATH              DevicePath;
+//  EFI_EVENT                             ExitBootServicesEvent;
+} LCD_INSTANCE;
+
+#define LCD_INSTANCE_SIGNATURE  SIGNATURE_32('l', 'c', 'd', '0')
+#define LCD_INSTANCE_FROM_GOP_THIS(a)     CR (a, LCD_INSTANCE, Gop, LCD_INSTANCE_SIGNATURE)
+
+typedef struct {
+  UINTN             Mode;
+  UINTN             HorizontalResolution;
+  UINTN             VerticalResolution;
+
+  UINT32            DssDivisor;
+  UINT32            DispcDivisor;
+
+  UINT32            HSync;
+  UINT32            HFrontPorch;
+  UINT32            HBackPorch;
+
+  UINT32            VSync;
+  UINT32            VFrontPorch;
+  UINT32            VBackPorch;
+} LCD_MODE;
+
+EFI_STATUS
+InitializeDisplay (
+  IN LCD_INSTANCE* Instance
+);
+
+EFI_STATUS
+EFIAPI
+LcdGraphicsQueryMode (
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,
+  IN  UINT32                                ModeNumber,
+  OUT UINTN                                 *SizeOfInfo,
+  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  **Info
+);
+
+EFI_STATUS
+EFIAPI
+LcdGraphicsSetMode (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL  *This,
+  IN UINT32                        ModeNumber
+);
+
+EFI_STATUS
+EFIAPI
+LcdGraphicsBlt (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *BltBuffer,     OPTIONAL
+  IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION   BltOperation,
+  IN UINTN                               SourceX,
+  IN UINTN                               SourceY,
+  IN UINTN                               DestinationX,
+  IN UINTN                               DestinationY,
+  IN UINTN                               Width,
+  IN UINTN                               Height,
+  IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer
+);
+
+// HW registers
+#define CM_FCLKEN_DSS   0x48004E00
+#define CM_ICLKEN_DSS   0x48004E10
+
+#define DSS_CONTROL     0x48050040
+#define DSS_SYSCONFIG   0x48050010
+#define DSS_SYSSTATUS   0x48050014
+
+#define DISPC_CONTROL   0x48050440
+#define DISPC_CONFIG    0x48050444
+#define DISPC_SIZE_LCD  0x4805047C
+#define DISPC_TIMING_H  0x48050464
+#define DISPC_TIMING_V  0x48050468
+
+#define CM_CLKSEL_DSS   0x48004E40
+#define DISPC_DIVISOR   0x48050470
+#define DISPC_POL_FREQ  0x4805046C
+
+#define DISPC_GFX_TABLE_BA 0x480504B8
+#define DISPC_GFX_BA0   0x48050480
+#define DISPC_GFX_BA1   0x48050484
+#define DISPC_GFX_POS   0x48050488
+#define DISPC_GFX_SIZE  0x4805048C
+#define DISPC_GFX_ATTR  0x480504A0
+#define DISPC_GFX_PRELD 0x4805062C
+
+#define DISPC_DEFAULT_COLOR_0 0x4805044C
+
+//#define DISPC_IRQSTATUS
+
+// Bits
+#define EN_TV           0x4
+#define EN_DSS2         0x2
+#define EN_DSS1         0x1
+#define EN_DSS          0x1
+
+#define DSS_SOFTRESET   0x2
+#define DSS_RESETDONE   0x1
+
+#define BYPASS_MODE     (BIT15 | BIT16)
+
+#define LCDENABLE       BIT0
+#define ACTIVEMATRIX    BIT3
+#define GOLCD           BIT5
+#define DATALINES24     (BIT8 | BIT9)
+#define LCDENABLESIGNAL BIT28
+
+#define GFXENABLE       BIT0
+#define RGB16           (0x6 << 1)
+#define BURSTSIZE16     (0x2 << 6)
+
+#define CLEARLOADMODE   ~(BIT2 | BIT1)
+#define LOAD_FRAME_ONLY BIT2
+
+#endif
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.inf b/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.inf
new file mode 100644
index 0000000000..b017d8bf92
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.inf
@@ -0,0 +1,46 @@
+#/** @file
+#
+#  Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = LcdGraphicsDxe
+  FILE_GUID                      = E68088EF-D1A4-4336-C1DB-4D3A204730A6
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = LcdGraphicsOutputDxeInitialize
+
+[Sources.common]
+  LcdGraphicsOutputDxe.c
+  LcdGraphicsOutputBlt.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+
+[LibraryClasses]
+  ArmLib
+  UefiLib
+  BaseLib
+  DebugLib
+  TimerLib
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  IoLib
+  BaseMemoryLib
+
+[Protocols]
+  gEfiDevicePathProtocolGuid
+  gEfiGraphicsOutputProtocolGuid
+  gEfiDevicePathToTextProtocolGuid
+  gEmbeddedExternalDeviceProtocolGuid
+
+[Depex]
+  gEfiCpuArchProtocolGuid AND gEfiTimerArchProtocolGuid
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.c b/Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.c
new file mode 100644
index 0000000000..d0e77e12e5
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.c
@@ -0,0 +1,159 @@
+/** @file
+  Debug Agent timer lib for OMAP 35xx.
+
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/OmapLib.h>
+#include <Library/ArmLib.h>
+#include <Library/PcdLib.h>
+
+#include <Omap3530/Omap3530.h>
+
+
+volatile UINT32 gVector;
+
+// Cached registers
+volatile UINT32 gTISR;
+volatile UINT32 gTCLR;
+volatile UINT32 gTLDR;
+volatile UINT32 gTCRR;
+volatile UINT32 gTIER;
+
+VOID
+EnableInterruptSource (
+  VOID
+  )
+{
+  UINTN Bank;
+  UINTN Bit;
+
+  // Map vector to FIQ, IRQ is default
+  MmioWrite32 (INTCPS_ILR (gVector), 1);
+
+  Bank = gVector / 32;
+  Bit  = 1UL << (gVector % 32);
+
+  MmioWrite32 (INTCPS_MIR_CLEAR(Bank), Bit);
+}
+
+VOID
+DisableInterruptSource (
+  VOID
+  )
+{
+  UINTN Bank;
+  UINTN Bit;
+
+  Bank = gVector / 32;
+  Bit  = 1UL << (gVector % 32);
+
+  MmioWrite32 (INTCPS_MIR_SET(Bank), Bit);
+}
+
+
+
+/**
+  Setup all the hardware needed for the debug agents timer.
+
+  This function is used to set up debug enviroment. It may enable interrupts.
+
+**/
+VOID
+EFIAPI
+DebugAgentTimerIntialize (
+  VOID
+  )
+{
+  UINT32      TimerBaseAddress;
+  UINT32      TimerNumber;
+
+  TimerNumber = PcdGet32(PcdOmap35xxDebugAgentTimer);
+  gVector = InterruptVectorForTimer (TimerNumber);
+
+  // Set up the timer registers
+  TimerBaseAddress = TimerBase (TimerNumber);
+  gTISR = TimerBaseAddress + GPTIMER_TISR;
+  gTCLR = TimerBaseAddress + GPTIMER_TCLR;
+  gTLDR = TimerBaseAddress + GPTIMER_TLDR;
+  gTCRR = TimerBaseAddress + GPTIMER_TCRR;
+  gTIER = TimerBaseAddress + GPTIMER_TIER;
+
+  if ((TimerNumber < 2) || (TimerNumber > 9)) {
+    // This code assumes one the General Purpose timers is used
+    // GPT2 - GPT9
+    CpuDeadLoop ();
+  }
+  // Set source clock for GPT2 - GPT9 to SYS_CLK
+  MmioOr32 (CM_CLKSEL_PER, 1 << (TimerNumber - 2));
+
+}
+
+
+/**
+  Set the period for the debug agent timer. Zero means disable the timer.
+
+  @param[in] TimerPeriodMilliseconds    Frequency of the debug agent timer.
+
+**/
+VOID
+EFIAPI
+DebugAgentTimerSetPeriod (
+  IN  UINT32  TimerPeriodMilliseconds
+  )
+{
+  UINT64      TimerCount;
+  INT32       LoadValue;
+
+  if (TimerPeriodMilliseconds == 0) {
+    // Turn off GPTIMER3
+    MmioWrite32 (gTCLR, TCLR_ST_OFF);
+
+    DisableInterruptSource ();
+  } else {
+    // Calculate required timer count
+    TimerCount = DivU64x32(TimerPeriodMilliseconds * 1000000, PcdGet32(PcdDebugAgentTimerFreqNanoSeconds));
+
+    // Set GPTIMER5 Load register
+    LoadValue = (INT32) -TimerCount;
+    MmioWrite32 (gTLDR, LoadValue);
+    MmioWrite32 (gTCRR, LoadValue);
+
+    // Enable Overflow interrupt
+    MmioWrite32 (gTIER, TIER_TCAR_IT_DISABLE | TIER_OVF_IT_ENABLE | TIER_MAT_IT_DISABLE);
+
+    // Turn on GPTIMER3, it will reload at overflow
+    MmioWrite32 (gTCLR, TCLR_AR_AUTORELOAD | TCLR_ST_ON);
+
+    EnableInterruptSource ();
+  }
+}
+
+
+/**
+  Perform End Of Interrupt for the debug agent timer. This is called in the
+  interrupt handler after the interrupt has been processed.
+
+**/
+VOID
+EFIAPI
+DebugAgentTimerEndOfInterrupt (
+  VOID
+  )
+{
+   // Clear all timer interrupts
+  MmioWrite32 (gTISR, TISR_CLEAR_ALL);
+
+  // Poll interrupt status bits to ensure clearing
+  while ((MmioRead32 (gTISR) & TISR_ALL_INTERRUPT_MASK) != TISR_NO_INTERRUPTS_PENDING);
+
+  MmioWrite32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWFIQAGR);
+  ArmDataSynchronizationBarrier ();
+
+}
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf b/Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf
new file mode 100644
index 0000000000..ee178e7bd2
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf
@@ -0,0 +1,42 @@
+#/** @file
+# Component description file for Base PCI Cf8 Library.
+#
+# PCI CF8 Library that uses I/O ports 0xCF8 and 0xCFC to perform PCI Configuration cycles.
+#  Layers on top of an I/O Library instance.
+# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = DebugAgentTimerLibNull
+  FILE_GUID                      = E82F99DE-74ED-4e56-BBA1-B143FCA3F69A
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = DebugAgentTimerLib|SEC BASE DXE_CORE
+
+
+[Sources.common]
+  DebugAgentTimerLib.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+  ArmPkg/ArmPkg.dec
+
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  OmapLib
+  ArmLib
+
+[Pcd]
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxDebugAgentTimer
+  gOmap35xxTokenSpaceGuid.PcdDebugAgentTimerFreqNanoSeconds
+  gEmbeddedTokenSpaceGuid.PcdInterruptBaseAddress
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.c b/Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.c
new file mode 100644
index 0000000000..4e9fa0175b
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.c
@@ -0,0 +1,96 @@
+/** @file
+  Basic serial IO abstaction for GDB
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/GdbSerialLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/OmapLib.h>
+#include <Omap3530/Omap3530.h>
+
+RETURN_STATUS
+EFIAPI
+GdbSerialLibConstructor (
+  VOID
+  )
+{
+  return RETURN_SUCCESS;
+}
+
+RETURN_STATUS
+EFIAPI
+GdbSerialInit (
+  IN UINT64     BaudRate,
+  IN UINT8      Parity,
+  IN UINT8      DataBits,
+  IN UINT8      StopBits
+  )
+{
+  return RETURN_SUCCESS;
+}
+
+BOOLEAN
+EFIAPI
+GdbIsCharAvailable (
+  VOID
+  )
+{
+  UINT32 LSR = UartBase(PcdGet32(PcdOmap35xxConsoleUart)) + UART_LSR_REG;
+
+  if ((MmioRead8(LSR) & UART_LSR_RX_FIFO_E_MASK) == UART_LSR_RX_FIFO_E_NOT_EMPTY) {
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
+
+CHAR8
+EFIAPI
+GdbGetChar (
+  VOID
+  )
+{
+  UINT32  LSR = UartBase(PcdGet32(PcdOmap35xxConsoleUart)) + UART_LSR_REG;
+  UINT32  RBR = UartBase(PcdGet32(PcdOmap35xxConsoleUart)) + UART_RBR_REG;
+  CHAR8   Char;
+
+  while ((MmioRead8(LSR) & UART_LSR_RX_FIFO_E_MASK) == UART_LSR_RX_FIFO_E_EMPTY);
+  Char = MmioRead8(RBR);
+
+  return Char;
+}
+
+VOID
+EFIAPI
+GdbPutChar (
+  IN  CHAR8   Char
+  )
+{
+  UINT32  LSR = UartBase(PcdGet32(PcdOmap35xxConsoleUart)) + UART_LSR_REG;
+  UINT32  THR = UartBase(PcdGet32(PcdOmap35xxConsoleUart)) + UART_THR_REG;
+
+  while ((MmioRead8(LSR) & UART_LSR_TX_FIFO_E_MASK) == UART_LSR_TX_FIFO_E_NOT_EMPTY);
+  MmioWrite8(THR, Char);
+}
+
+VOID
+GdbPutString (
+  IN CHAR8  *String
+  )
+{
+  while (*String != '\0') {
+    GdbPutChar (*String);
+    String++;
+  }
+}
+
+
+
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.inf b/Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.inf
new file mode 100644
index 0000000000..c372e35c55
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.inf
@@ -0,0 +1,35 @@
+#/** @file
+#
+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = GdbSerialLib
+  FILE_GUID                      = E2423349-EF5D-439B-95F5-8B8D8E3B443F
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = GdbSerialLib
+
+  CONSTRUCTOR                    = GdbSerialLibConstructor
+
+
+[Sources.common]
+  GdbSerialLib.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  IoLib
+  OmapLib
+
+[FixedPcd]
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxConsoleUart
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/Omap35xxTimerLib.inf b/Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/Omap35xxTimerLib.inf
new file mode 100644
index 0000000000..ddb95c6542
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/Omap35xxTimerLib.inf
@@ -0,0 +1,40 @@
+#/** @file
+# Timer library implementation
+#
+# A non-functional instance of the Timer Library that can be used as a template
+#  for the implementation of a functional timer library instance. This library instance can
+#  also be used to test build DXE, Runtime, DXE SAL, and DXE SMM modules that require timer
+#  services as well as EBC modules that require timer services
+# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BeagleBoardTimerLib
+  FILE_GUID                      = fe1d7183-9abb-42ce-9a3b-36d7c6a8959f
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = TimerLib
+
+[Sources.common]
+  TimerLib.c
+
+[Packages]
+  Omap35xxPkg/Omap35xxPkg.dec
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  OmapLib
+  IoLib
+
+[Pcd]
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedPerformanceCounterFrequencyInHz
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedPerformanceCounterPeriodInNanoseconds
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxFreeTimer
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/TimerLib.c b/Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/TimerLib.c
new file mode 100644
index 0000000000..a69cad83a9
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/TimerLib.c
@@ -0,0 +1,151 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/TimerLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/OmapLib.h>
+
+#include <Omap3530/Omap3530.h>
+
+RETURN_STATUS
+EFIAPI
+TimerConstructor (
+  VOID
+  )
+{
+  UINTN  Timer            = PcdGet32(PcdOmap35xxFreeTimer);
+  UINT32 TimerBaseAddress = TimerBase(Timer);
+
+  if ((MmioRead32 (TimerBaseAddress + GPTIMER_TCLR) & TCLR_ST_ON) == 0) {
+    // Set source clock for GPT3 & GPT4 to SYS_CLK
+    MmioOr32 (CM_CLKSEL_PER, CM_CLKSEL_PER_CLKSEL_GPT3_SYS | CM_CLKSEL_PER_CLKSEL_GPT4_SYS);
+
+    // Set count & reload registers
+    MmioWrite32 (TimerBaseAddress + GPTIMER_TCRR, 0x00000000);
+    MmioWrite32 (TimerBaseAddress + GPTIMER_TLDR, 0x00000000);
+
+    // Disable interrupts
+    MmioWrite32 (TimerBaseAddress + GPTIMER_TIER, TIER_TCAR_IT_DISABLE | TIER_OVF_IT_DISABLE | TIER_MAT_IT_DISABLE);
+
+    // Start Timer
+    MmioWrite32 (TimerBaseAddress + GPTIMER_TCLR, TCLR_AR_AUTORELOAD | TCLR_ST_ON);
+
+    // Disable OMAP Watchdog timer (WDT2)
+    MmioWrite32 (WDTIMER2_BASE + WSPR, 0xAAAA);
+    DEBUG ((EFI_D_ERROR, "Magic delay to disable watchdog timers properly.\n"));
+    MmioWrite32 (WDTIMER2_BASE + WSPR, 0x5555);
+  }
+  return EFI_SUCCESS;
+}
+
+UINTN
+EFIAPI
+MicroSecondDelay (
+  IN  UINTN MicroSeconds
+  )
+{
+  UINT64  NanoSeconds;
+
+  NanoSeconds = MultU64x32(MicroSeconds, 1000);
+
+  while (NanoSeconds > (UINTN)-1) {
+    NanoSecondDelay((UINTN)-1);
+    NanoSeconds -= (UINTN)-1;
+  }
+
+  NanoSecondDelay(NanoSeconds);
+
+  return MicroSeconds;
+}
+
+UINTN
+EFIAPI
+NanoSecondDelay (
+  IN  UINTN NanoSeconds
+  )
+{
+  UINT32  Delay;
+  UINT32  StartTime;
+  UINT32  CurrentTime;
+  UINT32  ElapsedTime;
+  UINT32  TimerCountRegister;
+
+  Delay = (NanoSeconds / PcdGet32(PcdEmbeddedPerformanceCounterPeriodInNanoseconds)) + 1;
+
+  TimerCountRegister = TimerBase(PcdGet32(PcdOmap35xxFreeTimer)) + GPTIMER_TCRR;
+
+  StartTime = MmioRead32 (TimerCountRegister);
+
+  do
+  {
+    CurrentTime = MmioRead32 (TimerCountRegister);
+    ElapsedTime = CurrentTime - StartTime;
+  } while (ElapsedTime < Delay);
+
+  NanoSeconds = ElapsedTime * PcdGet32(PcdEmbeddedPerformanceCounterPeriodInNanoseconds);
+
+  return NanoSeconds;
+}
+
+UINT64
+EFIAPI
+GetPerformanceCounter (
+  VOID
+  )
+{
+  return (UINT64)MmioRead32 (TimerBase(PcdGet32(PcdOmap35xxFreeTimer)) + GPTIMER_TCRR);
+}
+
+UINT64
+EFIAPI
+GetPerformanceCounterProperties (
+  OUT UINT64  *StartValue,  OPTIONAL
+  OUT UINT64  *EndValue     OPTIONAL
+  )
+{
+  if (StartValue != NULL) {
+    // Timer starts with the reload value
+    *StartValue = (UINT64)MmioRead32 (TimerBase(PcdGet32(PcdOmap35xxFreeTimer)) + GPTIMER_TLDR);
+  }
+
+  if (EndValue != NULL) {
+    // Timer counts up to 0xFFFFFFFF
+    *EndValue = 0xFFFFFFFF;
+  }
+
+  return PcdGet64(PcdEmbeddedPerformanceCounterFrequencyInHz);
+}
+
+/**
+  Converts elapsed ticks of performance counter to time in nanoseconds.
+
+  This function converts the elapsed ticks of running performance counter to
+  time value in unit of nanoseconds.
+
+  @param  Ticks     The number of elapsed ticks of running performance counter.
+
+  @return The elapsed time in nanoseconds.
+
+**/
+UINT64
+EFIAPI
+GetTimeInNanoSecond (
+  IN      UINT64                     Ticks
+  )
+{
+  UINT32 Period;
+
+  Period = PcdGet32 (PcdEmbeddedPerformanceCounterPeriodInNanoseconds);
+
+  return (Ticks * Period);
+}
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.c b/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.c
new file mode 100644
index 0000000000..22393389b9
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.c
@@ -0,0 +1,170 @@
+/** @file
+  Abstractions for simple OMAP DMA channel.
+
+
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Library/DebugLib.h>
+#include <Library/OmapDmaLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Omap3530/Omap3530.h>
+
+
+/**
+  Configure OMAP DMA Channel
+
+  @param  Channel               DMA Channel to configure
+  @param  Dma4                  Pointer to structure used to initialize DMA registers for the Channel
+
+  @retval EFI_SUCCESS           The range was mapped for the returned NumberOfBytes.
+  @retval EFI_INVALID_PARAMETER Channel is not valid
+  @retval EFI_DEVICE_ERROR      The system hardware could not map the requested information.
+
+**/
+EFI_STATUS
+EFIAPI
+EnableDmaChannel (
+  IN  UINTN       Channel,
+  IN  OMAP_DMA4   *DMA4
+  )
+{
+  UINT32  RegVal;
+
+
+  if (Channel > DMA4_MAX_CHANNEL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  /* 1) Configure the transfer parameters in the logical DMA registers */
+  /*-------------------------------------------------------------------*/
+
+  /* a) Set the data type CSDP[1:0], the Read/Write Port access type
+        CSDP[8:7]/[15:14], the Source/dest endianism CSDP[21]/CSDP[19],
+        write mode CSDP[17:16], source/dest packed or nonpacked CSDP[6]/CSDP[13] */
+
+  // Read CSDP
+  RegVal = MmioRead32 (DMA4_CSDP (Channel));
+
+  // Build reg
+  RegVal = ((RegVal & ~ 0x3) | DMA4->DataType );
+  RegVal = ((RegVal & ~(0x3 <<  7)) | (DMA4->ReadPortAccessType << 7));
+  RegVal = ((RegVal & ~(0x3 << 14)) | (DMA4->WritePortAccessType << 14));
+  RegVal = ((RegVal & ~(0x1 << 21)) | (DMA4->SourceEndiansim << 21));
+  RegVal = ((RegVal & ~(0x1 << 19)) | (DMA4->DestinationEndianism << 19));
+  RegVal = ((RegVal & ~(0x3 << 16)) | (DMA4->WriteMode << 16));
+  RegVal = ((RegVal & ~(0x1 <<  6)) | (DMA4->SourcePacked << 6));
+  RegVal = ((RegVal & ~(0x1 << 13)) | (DMA4->DestinationPacked << 13));
+  // Write CSDP
+  MmioWrite32 (DMA4_CSDP (Channel), RegVal);
+
+  /* b) Set the number of element per frame CEN[23:0]*/
+  MmioWrite32 (DMA4_CEN (Channel), DMA4->NumberOfElementPerFrame);
+
+  /* c) Set the number of frame per block CFN[15:0]*/
+  MmioWrite32 (DMA4_CFN (Channel), DMA4->NumberOfFramePerTransferBlock);
+
+  /* d) Set the Source/dest start address index CSSA[31:0]/CDSA[31:0]*/
+  MmioWrite32 (DMA4_CSSA (Channel), DMA4->SourceStartAddress);
+  MmioWrite32 (DMA4_CDSA (Channel), DMA4->DestinationStartAddress);
+
+  /* e) Set the Read Port addressing mode CCR[13:12], the Write Port addressing mode CCR[15:14],
+        read/write priority CCR[6]/CCR[26]
+        I changed LCH CCR[20:19]=00 and CCR[4:0]=00000 to
+        LCH CCR[20:19]= DMA4->WriteRequestNumber and CCR[4:0]=DMA4->ReadRequestNumber
+  */
+
+  // Read CCR
+  RegVal = MmioRead32 (DMA4_CCR (Channel));
+
+  // Build reg
+  RegVal  = ((RegVal &  ~0x1f)            | DMA4->ReadRequestNumber);
+  RegVal  = ((RegVal &  ~(BIT20 | BIT19)) | DMA4->WriteRequestNumber << 19);
+  RegVal  = ((RegVal & ~(0x3 << 12)) | (DMA4->ReadPortAccessMode << 12));
+  RegVal  = ((RegVal & ~(0x3 << 14)) | (DMA4->WritePortAccessMode << 14));
+  RegVal  = ((RegVal & ~(0x1 <<  6)) | (DMA4->ReadPriority << 6));
+  RegVal  = ((RegVal & ~(0x1 << 26)) | (DMA4->WritePriority << 26));
+
+  // Write CCR
+  MmioWrite32 (DMA4_CCR (Channel), RegVal);
+
+  /* f)- Set the source element index CSEI[15:0]*/
+  MmioWrite32 (DMA4_CSEI (Channel), DMA4->SourceElementIndex);
+
+  /* - Set the source frame index CSFI[15:0]*/
+  MmioWrite32 (DMA4_CSFI (Channel), DMA4->SourceFrameIndex);
+
+
+  /* - Set the destination element index CDEI[15:0]*/
+  MmioWrite32 (DMA4_CDEI (Channel), DMA4->DestinationElementIndex);
+
+  /* - Set the destination frame index CDFI[31:0]*/
+  MmioWrite32 (DMA4_CDFI (Channel), DMA4->DestinationFrameIndex);
+
+  MmioWrite32 (DMA4_CDFI (Channel), DMA4->DestinationFrameIndex);
+
+  // Enable all the status bits since we are polling
+  MmioWrite32 (DMA4_CICR (Channel), DMA4_CICR_ENABLE_ALL);
+  MmioWrite32 (DMA4_CSR (Channel),  DMA4_CSR_RESET);
+
+  /* 2) Start the DMA transfer by Setting the enable bit CCR[7]=1 */
+  /*--------------------------------------------------------------*/
+  //write enable bit
+  MmioOr32 (DMA4_CCR(Channel), DMA4_CCR_ENABLE); //Launch transfer
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Turn of DMA channel configured by EnableDma().
+
+  @param  Channel               DMA Channel to configure
+  @param  SuccesMask            Bits in DMA4_CSR register indicate EFI_SUCCESS
+  @param  ErrorMask             Bits in DMA4_CSR register indicate EFI_DEVICE_ERROR
+
+  @retval EFI_SUCCESS           DMA hardware disabled
+  @retval EFI_INVALID_PARAMETER Channel is not valid
+  @retval EFI_DEVICE_ERROR      The system hardware could not map the requested information.
+
+**/
+EFI_STATUS
+EFIAPI
+DisableDmaChannel (
+  IN  UINTN       Channel,
+  IN  UINT32      SuccessMask,
+  IN  UINT32      ErrorMask
+  )
+{
+  EFI_STATUS  Status = EFI_SUCCESS;
+  UINT32      Reg;
+
+
+  if (Channel > DMA4_MAX_CHANNEL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  do {
+    Reg = MmioRead32 (DMA4_CSR(Channel));
+    if ((Reg & ErrorMask) != 0) {
+      Status = EFI_DEVICE_ERROR;
+      DEBUG ((EFI_D_ERROR, "DMA Error (%d) %x\n", Channel, Reg));
+      break;
+    }
+  } while ((Reg & SuccessMask) != SuccessMask);
+
+
+  // Disable all status bits and clear them
+  MmioWrite32 (DMA4_CICR (Channel), 0);
+  MmioWrite32 (DMA4_CSR (Channel),  DMA4_CSR_RESET);
+
+  MmioAnd32 (DMA4_CCR(0), ~(DMA4_CCR_ENABLE | DMA4_CCR_RD_ACTIVE | DMA4_CCR_WR_ACTIVE));
+  return Status;
+}
+
+
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.inf b/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.inf
new file mode 100644
index 0000000000..68a0606cdf
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.inf
@@ -0,0 +1,43 @@
+#/** @file
+#
+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = OmapDmaLib
+  FILE_GUID                      = 09B17D99-BB07-49a8-B0D2-06D6AFCBE3AB
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = OmapDmaLib
+
+
+[Sources.common]
+  OmapDmaLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPkg/ArmPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  UefiBootServicesTableLib
+  MemoryAllocationLib
+  IoLib
+  BaseMemoryLib
+  ArmLib
+
+
+[Protocols]
+  gEfiCpuArchProtocolGuid
+
+[Guids]
+
+[Pcd]
+
+[Depex]
+  gEfiCpuArchProtocolGuid
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.c b/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.c
new file mode 100644
index 0000000000..cfea62e6d6
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.c
@@ -0,0 +1,77 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Library/DebugLib.h>
+#include <Library/OmapLib.h>
+#include <Omap3530/Omap3530.h>
+
+UINT32
+GpioBase (
+  IN  UINTN Port
+  )
+{
+  switch (Port) {
+  case 1:  return GPIO1_BASE;
+  case 2:  return GPIO2_BASE;
+  case 3:  return GPIO3_BASE;
+  case 4:  return GPIO4_BASE;
+  case 5:  return GPIO5_BASE;
+  case 6:  return GPIO6_BASE;
+  default: ASSERT(FALSE); return 0;
+  }
+}
+
+UINT32
+TimerBase (
+  IN  UINTN Timer
+  )
+{
+  switch (Timer) {
+  case  1: return GPTIMER1_BASE;
+  case  2: return GPTIMER2_BASE;
+  case  3: return GPTIMER3_BASE;
+  case  4: return GPTIMER4_BASE;
+  case  5: return GPTIMER5_BASE;
+  case  6: return GPTIMER6_BASE;
+  case  7: return GPTIMER7_BASE;
+  case  8: return GPTIMER8_BASE;
+  case  9: return GPTIMER9_BASE;
+  case 10: return GPTIMER10_BASE;
+  case 11: return GPTIMER11_BASE;
+  case 12: return GPTIMER12_BASE;
+  default: return 0;
+  }
+}
+
+UINTN
+InterruptVectorForTimer (
+  IN  UINTN Timer
+  )
+{
+  if ((Timer < 1) || (Timer > 12)) {
+    ASSERT(FALSE);
+    return 0xFFFFFFFF;
+  }
+
+  return 36 + Timer;
+}
+
+UINT32
+UartBase (
+  IN  UINTN Uart
+  )
+{
+  switch (Uart) {
+  case 1:  return UART1_BASE;
+  case 2:  return UART2_BASE;
+  case 3:  return UART3_BASE;
+  default: ASSERT(FALSE); return 0;
+  }
+}
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.inf b/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.inf
new file mode 100644
index 0000000000..df37387622
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.inf
@@ -0,0 +1,31 @@
+#/** @file
+#
+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = OmapLib
+  FILE_GUID                      = d035f5c2-1b92-4746-9f6c-5ff6202970df
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = OmapLib
+
+[Sources.common]
+  OmapLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[LibraryClasses]
+  DebugLib
+
+[Protocols]
+
+[Guids]
+
+[Pcd]
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTimeClockLib.c b/Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTimeClockLib.c
new file mode 100644
index 0000000000..ddde1868ac
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTimeClockLib.c
@@ -0,0 +1,291 @@
+/** @file
+*
+*  Copyright (c) 2011, ARM Limited. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include <Uefi.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+
+#include <Protocol/RealTimeClock.h>
+#include <Protocol/EmbeddedExternalDevice.h>
+
+#include <Omap3530/Omap3530.h>
+#include <TPS65950.h>
+
+
+EMBEDDED_EXTERNAL_DEVICE   *gTPS65950;
+INT16                      TimeZone = EFI_UNSPECIFIED_TIMEZONE;
+
+/**
+  Returns the current time and date information, and the time-keeping capabilities
+  of the hardware platform.
+
+  @param  Time                  A pointer to storage to receive a snapshot of the current time.
+  @param  Capabilities          An optional pointer to a buffer to receive the real time clock
+                                device's capabilities.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER Time is NULL.
+  @retval EFI_DEVICE_ERROR      The time could not be retrieved due to hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+LibGetTime (
+  OUT EFI_TIME                *Time,
+  OUT EFI_TIME_CAPABILITIES   *Capabilities
+  )
+{
+  EFI_STATUS            Status;
+  UINT8                 Data;
+  EFI_TPL               OldTpl;
+
+  if (Time == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  OldTpl = gBS->RaiseTPL(TPL_NOTIFY);
+
+  /* Get time and date */
+  ZeroMem(Time, sizeof(EFI_TIME));
+
+  // Latch values
+  Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, RTC_CTRL_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+  Data |= BIT6;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, RTC_CTRL_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+
+  // Read registers
+  Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, YEARS_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+  Time->Year = 2000 + ((Data >> 4) & 0xF) * 10 + (Data & 0xF);
+
+  Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, MONTHS_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+  Time->Month = ((Data >> 4) & 0x1) * 10 + (Data & 0xF);
+
+  Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, DAYS_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+  Time->Day = ((Data >> 4) & 0x3) * 10 + (Data & 0xF);
+
+  Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, HOURS_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+  Time->Hour = ((Data >> 4) & 0x3) * 10 + (Data & 0xF);
+
+  Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, MINUTES_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+  Time->Minute = ((Data >> 4) & 0x7) * 10 + (Data & 0xF);
+
+  Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, SECONDS_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+  Time->Second = ((Data >> 4) & 0x7) * 10 + (Data & 0xF);
+
+  Time->TimeZone = TimeZone;
+  // TODO: check what to use here
+  Time->Daylight = EFI_TIME_ADJUST_DAYLIGHT;
+
+  // Set capabilities
+
+  // TODO: Set real capabilities
+  if (Capabilities != NULL) {
+    Capabilities->Resolution = 1;
+    Capabilities->Accuracy = 50000000;
+    Capabilities->SetsToZero = FALSE;
+  }
+
+EXIT:
+  gBS->RestoreTPL(OldTpl);
+
+  return (Status == EFI_SUCCESS) ? Status : EFI_DEVICE_ERROR;
+}
+
+/**
+  Sets the current local time and date information.
+
+  @param  Time                  A pointer to the current time.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER A time field is out of range.
+  @retval EFI_DEVICE_ERROR      The time could not be set due due to hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+LibSetTime (
+  IN EFI_TIME                *Time
+  )
+{
+  EFI_STATUS Status;
+  UINT8      Data;
+  UINT8      MonthDayCount[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+  EFI_TPL    OldTpl;
+
+  // Input validation according both to UEFI spec and hardware constraints
+  // UEFI spec says valid year range is 1900-9999 but TPS only supports 2000-2099
+  if ( (Time == NULL)
+    || (Time->Year < 2000 || Time->Year > 2099)
+    || (Time->Month < 1 || Time->Month > 12)
+    || (Time->Day < 1 || Time->Day > MonthDayCount[Time->Month])
+    || (Time->Hour > 23)
+    || (Time->Minute > 59)
+    || (Time->Second > 59)
+    || (Time->Nanosecond > 999999999)
+    || ((Time->TimeZone < -1440 || Time->TimeZone > 1440) && Time->TimeZone != 2047)
+  ) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  OldTpl = gBS->RaiseTPL(TPL_NOTIFY);
+
+  Data = Time->Year - 2000;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, YEARS_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+
+  Data = ((Time->Month / 10) << 4) | (Time->Month % 10);
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, MONTHS_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+
+  Data = ((Time->Day / 10) << 4) | (Time->Day % 10);
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, DAYS_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+
+  Data = ((Time->Hour / 10) << 4) | (Time->Hour % 10);
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, HOURS_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+
+  Data = ((Time->Minute / 10) << 4) | (Time->Minute % 10);
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, MINUTES_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+
+  Data = ((Time->Second / 10) << 4) | (Time->Second % 10);
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, SECONDS_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+
+  TimeZone = Time->TimeZone;
+
+EXIT:
+  gBS->RestoreTPL(OldTpl);
+
+  return (Status == EFI_SUCCESS) ? Status : EFI_DEVICE_ERROR;
+}
+
+/**
+  Returns the current wakeup alarm clock setting.
+
+  @param  Enabled               Indicates if the alarm is currently enabled or disabled.
+  @param  Pending               Indicates if the alarm signal is pending and requires acknowledgement.
+  @param  Time                  The current alarm setting.
+
+  @retval EFI_SUCCESS           The alarm settings were returned.
+  @retval EFI_INVALID_PARAMETER Any parameter is NULL.
+  @retval EFI_DEVICE_ERROR      The wakeup time could not be retrieved due to a hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+LibGetWakeupTime (
+  OUT BOOLEAN     *Enabled,
+  OUT BOOLEAN     *Pending,
+  OUT EFI_TIME    *Time
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Sets the system wakeup alarm clock time.
+
+  @param  Enabled               Enable or disable the wakeup alarm.
+  @param  Time                  If Enable is TRUE, the time to set the wakeup alarm for.
+
+  @retval EFI_SUCCESS           If Enable is TRUE, then the wakeup alarm was enabled. If
+                                Enable is FALSE, then the wakeup alarm was disabled.
+  @retval EFI_INVALID_PARAMETER A time field is out of range.
+  @retval EFI_DEVICE_ERROR      The wakeup time could not be set due to a hardware error.
+  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.
+
+**/
+EFI_STATUS
+EFIAPI
+LibSetWakeupTime (
+  IN BOOLEAN      Enabled,
+  OUT EFI_TIME    *Time
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  This is the declaration of an EFI image entry point. This can be the entry point to an application
+  written to this specification, an EFI boot service driver, or an EFI runtime driver.
+
+  @param  ImageHandle           Handle that identifies the loaded image.
+  @param  SystemTable           System Table for this image.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+LibRtcInitialize (
+  IN EFI_HANDLE                            ImageHandle,
+  IN EFI_SYSTEM_TABLE                      *SystemTable
+  )
+{
+  EFI_STATUS    Status;
+  EFI_HANDLE    Handle;
+  UINT8         Data;
+  EFI_TPL       OldTpl;
+
+  Status = gBS->LocateProtocol (&gEmbeddedExternalDeviceProtocolGuid, NULL, (VOID **)&gTPS65950);
+  ASSERT_EFI_ERROR(Status);
+
+  OldTpl = gBS->RaiseTPL(TPL_NOTIFY);
+  Data = 1;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, RTC_CTRL_REG), 1, &Data);
+  ASSERT_EFI_ERROR(Status);
+  gBS->RestoreTPL(OldTpl);
+
+  // Setup the setters and getters
+  gRT->GetTime       = LibGetTime;
+  gRT->SetTime       = LibSetTime;
+  gRT->GetWakeupTime = LibGetWakeupTime;
+  gRT->SetWakeupTime = LibSetWakeupTime;
+
+  // Install the protocol
+  Handle = NULL;
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Handle,
+                  &gEfiRealTimeClockArchProtocolGuid,  NULL,
+                  NULL
+                 );
+
+  return Status;
+}
+
+/**
+  Fixup internal data so that EFI can be call in virtual mode.
+  Call the passed in Child Notify event and convert any pointers in
+  lib to virtual mode.
+
+  @param[in]    Event   The Event that is being processed
+  @param[in]    Context Event Context
+**/
+VOID
+EFIAPI
+LibRtcVirtualNotifyEvent (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  )
+{
+  return;
+}
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTimeClockLib.inf b/Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTimeClockLib.inf
new file mode 100644
index 0000000000..85c914796b
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTimeClockLib.inf
@@ -0,0 +1,32 @@
+#  Copyright (c) 2011, ARM Limited. All rights reserved.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = RealTimeClockLib
+  FILE_GUID                      = EC1713DB-7DB5-4c99-8FE2-6F52F95A1132
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = RealTimeClockLib
+
+[Sources.common]
+  RealTimeClockLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[LibraryClasses]
+  IoLib
+  UefiLib
+  DebugLib
+  PcdLib
+
+[Protocols]
+  gEmbeddedExternalDeviceProtocolGuid
+
+[depex]
+  gEmbeddedExternalDeviceProtocolGuid
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.c b/Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.c
new file mode 100644
index 0000000000..2b94f0bfc2
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.c
@@ -0,0 +1,208 @@
+/** @file
+  Serial I/O Port library functions with no library constructor/destructor
+
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Library/DebugLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/OmapLib.h>
+#include <Omap3530/Omap3530.h>
+
+/*
+
+  Programmed hardware of Serial port.
+
+  @return    Always return EFI_UNSUPPORTED.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortInitialize (
+  VOID
+  )
+{
+  // assume assembly code at reset vector has setup UART
+  return RETURN_SUCCESS;
+}
+
+/**
+  Write data to serial device.
+
+  @param  Buffer           Point of data buffer which need to be writed.
+  @param  NumberOfBytes    Number of output bytes which are cached in Buffer.
+
+  @retval 0                Write data failed.
+  @retval !0               Actual number of bytes writed to serial device.
+
+**/
+UINTN
+EFIAPI
+SerialPortWrite (
+  IN UINT8     *Buffer,
+  IN UINTN     NumberOfBytes
+)
+{
+  UINT32  LSR = UartBase(PcdGet32(PcdOmap35xxConsoleUart)) + UART_LSR_REG;
+  UINT32  THR = UartBase(PcdGet32(PcdOmap35xxConsoleUart)) + UART_THR_REG;
+  UINTN   Count;
+
+  for (Count = 0; Count < NumberOfBytes; Count++, Buffer++) {
+    while ((MmioRead8(LSR) & UART_LSR_TX_FIFO_E_MASK) == UART_LSR_TX_FIFO_E_NOT_EMPTY);
+    MmioWrite8(THR, *Buffer);
+  }
+
+  return NumberOfBytes;
+}
+
+
+/**
+  Read data from serial device and save the datas in buffer.
+
+  @param  Buffer           Point of data buffer which need to be writed.
+  @param  NumberOfBytes    Number of output bytes which are cached in Buffer.
+
+  @retval 0                Read data failed.
+  @retval !0               Aactual number of bytes read from serial device.
+
+**/
+UINTN
+EFIAPI
+SerialPortRead (
+  OUT UINT8     *Buffer,
+  IN  UINTN     NumberOfBytes
+)
+{
+  UINT32  LSR = UartBase(PcdGet32(PcdOmap35xxConsoleUart)) + UART_LSR_REG;
+  UINT32  RBR = UartBase(PcdGet32(PcdOmap35xxConsoleUart)) + UART_RBR_REG;
+  UINTN   Count;
+
+  for (Count = 0; Count < NumberOfBytes; Count++, Buffer++) {
+    while ((MmioRead8(LSR) & UART_LSR_RX_FIFO_E_MASK) == UART_LSR_RX_FIFO_E_EMPTY);
+    *Buffer = MmioRead8(RBR);
+  }
+
+  return NumberOfBytes;
+}
+
+
+/**
+  Check to see if any data is avaiable to be read from the debug device.
+
+  @retval EFI_SUCCESS       At least one byte of data is avaiable to be read
+  @retval EFI_NOT_READY     No data is avaiable to be read
+  @retval EFI_DEVICE_ERROR  The serial device is not functioning properly
+
+**/
+BOOLEAN
+EFIAPI
+SerialPortPoll (
+  VOID
+  )
+{
+  UINT32 LSR = UartBase(PcdGet32(PcdOmap35xxConsoleUart)) + UART_LSR_REG;
+
+  if ((MmioRead8(LSR) & UART_LSR_RX_FIFO_E_MASK) == UART_LSR_RX_FIFO_E_NOT_EMPTY) {
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
+
+/**
+  Sets the control bits on a serial device.
+
+  @param[in] Control            Sets the bits of Control that are settable.
+
+  @retval RETURN_SUCCESS        The new control bits were set on the serial device.
+  @retval RETURN_UNSUPPORTED    The serial device does not support this operation.
+  @retval RETURN_DEVICE_ERROR   The serial device is not functioning correctly.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortSetControl (
+  IN UINT32 Control
+  )
+{
+  return RETURN_UNSUPPORTED;
+}
+
+/**
+  Retrieve the status of the control bits on a serial device.
+
+  @param[out] Control           A pointer to return the current control signals from the serial device.
+
+  @retval RETURN_SUCCESS        The control bits were read from the serial device.
+  @retval RETURN_UNSUPPORTED    The serial device does not support this operation.
+  @retval RETURN_DEVICE_ERROR   The serial device is not functioning correctly.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortGetControl (
+  OUT UINT32 *Control
+  )
+{
+  *Control = 0;
+  if (!SerialPortPoll ()) {
+    *Control = EFI_SERIAL_INPUT_BUFFER_EMPTY;
+  }
+  return RETURN_SUCCESS;
+}
+
+/**
+  Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,
+  data bits, and stop bits on a serial device.
+
+  @param BaudRate           The requested baud rate. A BaudRate value of 0 will use the
+                            device's default interface speed.
+                            On output, the value actually set.
+  @param ReveiveFifoDepth   The requested depth of the FIFO on the receive side of the
+                            serial interface. A ReceiveFifoDepth value of 0 will use
+                            the device's default FIFO depth.
+                            On output, the value actually set.
+  @param Timeout            The requested time out for a single character in microseconds.
+                            This timeout applies to both the transmit and receive side of the
+                            interface. A Timeout value of 0 will use the device's default time
+                            out value.
+                            On output, the value actually set.
+  @param Parity             The type of parity to use on this serial device. A Parity value of
+                            DefaultParity will use the device's default parity value.
+                            On output, the value actually set.
+  @param DataBits           The number of data bits to use on the serial device. A DataBits
+                            vaule of 0 will use the device's default data bit setting.
+                            On output, the value actually set.
+  @param StopBits           The number of stop bits to use on this serial device. A StopBits
+                            value of DefaultStopBits will use the device's default number of
+                            stop bits.
+                            On output, the value actually set.
+
+  @retval RETURN_SUCCESS            The new attributes were set on the serial device.
+  @retval RETURN_UNSUPPORTED        The serial device does not support this operation.
+  @retval RETURN_INVALID_PARAMETER  One or more of the attributes has an unsupported value.
+  @retval RETURN_DEVICE_ERROR       The serial device is not functioning correctly.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortSetAttributes (
+  IN OUT UINT64             *BaudRate,
+  IN OUT UINT32             *ReceiveFifoDepth,
+  IN OUT UINT32             *Timeout,
+  IN OUT EFI_PARITY_TYPE    *Parity,
+  IN OUT UINT8              *DataBits,
+  IN OUT EFI_STOP_BITS_TYPE *StopBits
+  )
+{
+  return RETURN_UNSUPPORTED;
+}
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.inf b/Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.inf
new file mode 100644
index 0000000000..086ed3c2a9
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.inf
@@ -0,0 +1,40 @@
+#/** @file
+# EDK Serial port lib
+#
+#  Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2009, Apple Inc. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BeagleBoardSerialPortLib
+  FILE_GUID                      = 97546cbd-c0ff-4c48-ab0b-e4f58862acd3
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SerialPortLib
+
+
+#
+#  VALID_ARCHITECTURES           = ARM IA32 X64 EBC
+#
+
+[Sources.common]
+  SerialPortLib.c
+
+[LibraryClasses]
+  DebugLib
+  IoLib
+  OmapLib
+
+[Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdePkg/MdePkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[FixedPcd]
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxConsoleUart
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.c b/Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.c
new file mode 100644
index 0000000000..099e37c469
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.c
@@ -0,0 +1,1492 @@
+/** @file
+  MMC/SD Card driver for OMAP 35xx (SDIO not supported)
+
+  This driver always produces a BlockIo protocol but it starts off with no Media
+  present. A TimerCallBack detects when media is inserted or removed and after
+  a media change event a call to BlockIo ReadBlocks/WriteBlocks will cause the
+  media to be detected (or removed) and the BlockIo Media structure will get
+  updated. No MMC/SD Card harward registers are updated until the first BlockIo
+  ReadBlocks/WriteBlocks after media has been insterted (booting with a card
+  plugged in counts as an insertion event).
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MMCHS.h"
+
+EFI_BLOCK_IO_MEDIA gMMCHSMedia = {
+  SIGNATURE_32('s','d','i','o'),            // MediaId
+  TRUE,                                     // RemovableMedia
+  FALSE,                                    // MediaPresent
+  FALSE,                                    // LogicalPartition
+  FALSE,                                    // ReadOnly
+  FALSE,                                    // WriteCaching
+  512,                                      // BlockSize
+  4,                                        // IoAlign
+  0,                                        // Pad
+  0                                         // LastBlock
+};
+
+typedef struct {
+  VENDOR_DEVICE_PATH  Mmc;
+  EFI_DEVICE_PATH     End;
+} MMCHS_DEVICE_PATH;
+
+MMCHS_DEVICE_PATH gMmcHsDevicePath = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      {
+        (UINT8)(sizeof(VENDOR_DEVICE_PATH)),
+        (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8),
+      },
+    },
+    { 0xb615f1f5, 0x5088, 0x43cd, { 0x80, 0x9c, 0xa1, 0x6e, 0x52, 0x48, 0x7d, 0x00 } },
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }
+  }
+};
+
+CARD_INFO                  gCardInfo;
+EMBEDDED_EXTERNAL_DEVICE   *gTPS65950;
+EFI_EVENT                  gTimerEvent;
+BOOLEAN                    gMediaChange = FALSE;
+
+//
+// Internal Functions
+//
+
+
+VOID
+ParseCardCIDData (
+  UINT32 Response0,
+  UINT32 Response1,
+  UINT32 Response2,
+  UINT32 Response3
+  )
+{
+  gCardInfo.CIDData.MDT = ((Response0 >> 8) & 0xFFF);
+  gCardInfo.CIDData.PSN = (((Response0 >> 24) & 0xFF) | ((Response1 & 0xFFFFFF) << 8));
+  gCardInfo.CIDData.PRV = ((Response1 >> 24) & 0xFF);
+  gCardInfo.CIDData.PNM[4] = ((Response2) & 0xFF);
+  gCardInfo.CIDData.PNM[3] = ((Response2 >> 8) & 0xFF);
+  gCardInfo.CIDData.PNM[2] = ((Response2 >> 16) & 0xFF);
+  gCardInfo.CIDData.PNM[1] = ((Response2 >> 24) & 0xFF);
+  gCardInfo.CIDData.PNM[0] = ((Response3) & 0xFF);
+  gCardInfo.CIDData.OID = ((Response3 >> 8) & 0xFFFF);
+  gCardInfo.CIDData.MID = ((Response3 >> 24) & 0xFF);
+}
+
+
+VOID
+UpdateMMCHSClkFrequency (
+  UINTN NewCLKD
+  )
+{
+  //Set Clock enable to 0x0 to not provide the clock to the card
+  MmioAnd32 (MMCHS_SYSCTL, ~CEN);
+
+  //Set new clock frequency.
+  MmioAndThenOr32 (MMCHS_SYSCTL, ~CLKD_MASK, NewCLKD << 6);
+
+  //Poll till Internal Clock Stable
+  while ((MmioRead32 (MMCHS_SYSCTL) & ICS_MASK) != ICS);
+
+  //Set Clock enable to 0x1 to provide the clock to the card
+  MmioOr32 (MMCHS_SYSCTL, CEN);
+}
+
+
+EFI_STATUS
+SendCmd (
+  UINTN Cmd,
+  UINTN CmdInterruptEnableVal,
+  UINTN CmdArgument
+  )
+{
+  UINTN MmcStatus;
+  UINTN RetryCount = 0;
+
+  //Check if command line is in use or not. Poll till command line is available.
+  while ((MmioRead32 (MMCHS_PSTATE) & DATI_MASK) == DATI_NOT_ALLOWED);
+
+  //Provide the block size.
+  MmioWrite32 (MMCHS_BLK, BLEN_512BYTES);
+
+  //Setting Data timeout counter value to max value.
+  MmioAndThenOr32 (MMCHS_SYSCTL, ~DTO_MASK, DTO_VAL);
+
+  //Clear Status register.
+  MmioWrite32 (MMCHS_STAT, 0xFFFFFFFF);
+
+  //Set command argument register
+  MmioWrite32 (MMCHS_ARG, CmdArgument);
+
+  //Enable interrupt enable events to occur
+  MmioWrite32 (MMCHS_IE, CmdInterruptEnableVal);
+
+  //Send a command
+  MmioWrite32 (MMCHS_CMD, Cmd);
+
+  //Check for the command status.
+  while (RetryCount < MAX_RETRY_COUNT) {
+    do {
+      MmcStatus = MmioRead32 (MMCHS_STAT);
+    } while (MmcStatus == 0);
+
+    //Read status of command response
+    if ((MmcStatus & ERRI) != 0) {
+
+      //Perform soft-reset for mmci_cmd line.
+      MmioOr32 (MMCHS_SYSCTL, SRC);
+      while ((MmioRead32 (MMCHS_SYSCTL) & SRC));
+
+      DEBUG ((EFI_D_INFO, "MmcStatus: %x\n", MmcStatus));
+      return EFI_DEVICE_ERROR;
+    }
+
+    //Check if command is completed.
+    if ((MmcStatus & CC) == CC) {
+      MmioWrite32 (MMCHS_STAT, CC);
+      break;
+    }
+
+    RetryCount++;
+  }
+
+  if (RetryCount == MAX_RETRY_COUNT) {
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+VOID
+GetBlockInformation (
+  UINTN *BlockSize,
+  UINTN *NumBlocks
+  )
+{
+  CSD_SDV2 *CsdSDV2Data;
+  UINTN    CardSize;
+
+  if (gCardInfo.CardType == SD_CARD_2_HIGH) {
+    CsdSDV2Data = (CSD_SDV2 *)&gCardInfo.CSDData;
+
+    //Populate BlockSize.
+    *BlockSize = (0x1UL << CsdSDV2Data->READ_BL_LEN);
+
+    //Calculate Total number of blocks.
+    CardSize = CsdSDV2Data->C_SIZELow16 | (CsdSDV2Data->C_SIZEHigh6 << 2);
+    *NumBlocks = ((CardSize + 1) * 1024);
+  } else {
+    //Populate BlockSize.
+    *BlockSize = (0x1UL << gCardInfo.CSDData.READ_BL_LEN);
+
+    //Calculate Total number of blocks.
+    CardSize = gCardInfo.CSDData.C_SIZELow2 | (gCardInfo.CSDData.C_SIZEHigh10 << 2);
+    *NumBlocks = (CardSize + 1) * (1 << (gCardInfo.CSDData.C_SIZE_MULT + 2));
+  }
+
+  //For >=2G card, BlockSize may be 1K, but the transfer size is 512 bytes.
+  if (*BlockSize > 512) {
+    *NumBlocks = MultU64x32(*NumBlocks, *BlockSize/2);
+    *BlockSize = 512;
+  }
+
+  DEBUG ((EFI_D_INFO, "Card type: %x, BlockSize: %x, NumBlocks: %x\n", gCardInfo.CardType, *BlockSize, *NumBlocks));
+}
+
+
+VOID
+CalculateCardCLKD (
+  UINTN *ClockFrequencySelect
+  )
+{
+  UINT8    MaxDataTransferRate;
+  UINTN    TransferRateValue = 0;
+  UINTN    TimeValue = 0 ;
+  UINTN    Frequency = 0;
+
+  MaxDataTransferRate = gCardInfo.CSDData.TRAN_SPEED;
+
+  // For SD Cards  we would need to send CMD6 to set
+  // speeds abouve 25MHz. High Speed mode 50 MHz and up
+
+  //Calculate Transfer rate unit (Bits 2:0 of TRAN_SPEED)
+  switch (MaxDataTransferRate & 0x7) {
+    case 0:
+      TransferRateValue = 100 * 1000;
+      break;
+
+    case 1:
+      TransferRateValue = 1 * 1000 * 1000;
+      break;
+
+    case 2:
+      TransferRateValue = 10 * 1000 * 1000;
+      break;
+
+    case 3:
+      TransferRateValue = 100 * 1000 * 1000;
+      break;
+
+    default:
+      DEBUG((EFI_D_ERROR, "Invalid parameter.\n"));
+      ASSERT(FALSE);
+  }
+
+  //Calculate Time value (Bits 6:3 of TRAN_SPEED)
+  switch ((MaxDataTransferRate >> 3) & 0xF) {
+    case 1:
+      TimeValue = 10;
+      break;
+
+    case 2:
+      TimeValue = 12;
+      break;
+
+    case 3:
+      TimeValue = 13;
+      break;
+
+    case 4:
+      TimeValue = 15;
+      break;
+
+    case 5:
+      TimeValue = 20;
+      break;
+
+    case 6:
+      TimeValue = 25;
+      break;
+
+    case 7:
+      TimeValue = 30;
+      break;
+
+    case 8:
+      TimeValue = 35;
+      break;
+
+    case 9:
+      TimeValue = 40;
+      break;
+
+    case 10:
+      TimeValue = 45;
+      break;
+
+    case 11:
+      TimeValue = 50;
+      break;
+
+    case 12:
+      TimeValue = 55;
+      break;
+
+    case 13:
+      TimeValue = 60;
+      break;
+
+    case 14:
+      TimeValue = 70;
+      break;
+
+    case 15:
+      TimeValue = 80;
+      break;
+
+    default:
+      DEBUG((EFI_D_ERROR, "Invalid parameter.\n"));
+      ASSERT(FALSE);
+  }
+
+  Frequency = TransferRateValue * TimeValue/10;
+
+  //Calculate Clock divider value to program in MMCHS_SYSCTL[CLKD] field.
+  *ClockFrequencySelect = ((MMC_REFERENCE_CLK/Frequency) + 1);
+
+  DEBUG ((EFI_D_INFO, "MaxDataTransferRate: 0x%x, Frequency: %d KHz, ClockFrequencySelect: %x\n", MaxDataTransferRate, Frequency/1000, *ClockFrequencySelect));
+}
+
+
+VOID
+GetCardConfigurationData (
+  VOID
+  )
+{
+  UINTN  BlockSize;
+  UINTN  NumBlocks;
+  UINTN  ClockFrequencySelect;
+
+  //Calculate BlockSize and Total number of blocks in the detected card.
+  GetBlockInformation(&BlockSize, &NumBlocks);
+  gCardInfo.BlockSize = BlockSize;
+  gCardInfo.NumBlocks = NumBlocks;
+
+  //Calculate Card clock divider value.
+  CalculateCardCLKD(&ClockFrequencySelect);
+  gCardInfo.ClockFrequencySelect = ClockFrequencySelect;
+}
+
+
+EFI_STATUS
+InitializeMMCHS (
+  VOID
+  )
+{
+  UINT8      Data = 0;
+  EFI_STATUS Status;
+
+  //Select Device group to belong to P1 device group in Power IC.
+  Data = DEV_GRP_P1;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VMMC1_DEV_GRP), 1, &Data);
+  ASSERT_EFI_ERROR(Status);
+
+  //Configure voltage regulator for MMC1 in Power IC to output 3.0 voltage.
+  Data = VSEL_3_00V;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VMMC1_DEDICATED_REG), 1, &Data);
+  ASSERT_EFI_ERROR(Status);
+
+  //After ramping up voltage, set VDDS stable bit to indicate that voltage level is stable.
+  MmioOr32 (CONTROL_PBIAS_LITE, (PBIASLITEVMODE0 | PBIASLITEPWRDNZ0 | PBIASSPEEDCTRL0 | PBIASLITEVMODE1 | PBIASLITEWRDNZ1));
+
+  // Enable WP GPIO
+  MmioAndThenOr32 (GPIO1_BASE + GPIO_OE, ~BIT23, BIT23);
+
+  // Enable Card Detect
+  Data = CARD_DETECT_ENABLE;
+  gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, TPS65950_GPIO_CTRL), 1, &Data);
+
+
+  return Status;
+}
+
+
+EFI_STATUS
+PerformCardIdenfication (
+  VOID
+  )
+{
+  EFI_STATUS Status;
+  UINTN      CmdArgument = 0;
+  UINTN      Response = 0;
+  UINTN      RetryCount = 0;
+  BOOLEAN    SDCmd8Supported = FALSE;
+
+  //Enable interrupts.
+  MmioWrite32 (MMCHS_IE, (BADA_EN | CERR_EN | DEB_EN | DCRC_EN | DTO_EN | CIE_EN |
+    CEB_EN | CCRC_EN | CTO_EN | BRR_EN | BWR_EN | TC_EN | CC_EN));
+
+  //Controller INIT procedure start.
+  MmioOr32 (MMCHS_CON, INIT);
+  MmioWrite32 (MMCHS_CMD, 0x00000000);
+  while (!(MmioRead32 (MMCHS_STAT) & CC));
+
+  //Wait for 1 ms
+  gBS->Stall(1000);
+
+  //Set CC bit to 0x1 to clear the flag
+  MmioOr32 (MMCHS_STAT, CC);
+
+  //Retry INIT procedure.
+  MmioWrite32 (MMCHS_CMD, 0x00000000);
+  while (!(MmioRead32 (MMCHS_STAT) & CC));
+
+  //End initialization sequence
+  MmioAnd32 (MMCHS_CON, ~INIT);
+
+  MmioOr32 (MMCHS_HCTL, (SDVS_3_0_V | DTW_1_BIT | SDBP_ON));
+
+  //Change clock frequency to 400KHz to fit protocol
+  UpdateMMCHSClkFrequency(CLKD_400KHZ);
+
+  MmioOr32 (MMCHS_CON, OD);
+
+  //Send CMD0 command.
+  Status = SendCmd (CMD0, CMD0_INT_EN, CmdArgument);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "Cmd0 fails.\n"));
+    return Status;
+  }
+
+  DEBUG ((EFI_D_INFO, "CMD0 response: %x\n", MmioRead32 (MMCHS_RSP10)));
+
+  //Send CMD5 command.
+  Status = SendCmd (CMD5, CMD5_INT_EN, CmdArgument);
+  if (Status == EFI_SUCCESS) {
+    DEBUG ((EFI_D_ERROR, "CMD5 Success. SDIO card. Follow SDIO card specification.\n"));
+    DEBUG ((EFI_D_INFO, "CMD5 response: %x\n", MmioRead32 (MMCHS_RSP10)));
+    //NOTE: Returning unsupported error for now. Need to implement SDIO specification.
+    return EFI_UNSUPPORTED;
+  } else {
+    DEBUG ((EFI_D_INFO, "CMD5 fails. Not an SDIO card.\n"));
+  }
+
+  MmioOr32 (MMCHS_SYSCTL, SRC);
+  gBS->Stall(1000);
+  while ((MmioRead32 (MMCHS_SYSCTL) & SRC));
+
+  //Send CMD8 command. (New v2.00 command for Voltage check)
+  //Only 2.7V - 3.6V is supported for SD2.0, only SD 2.0 card can pass.
+  //MMC & SD1.1 card will fail this command.
+  CmdArgument = CMD8_ARG;
+  Status = SendCmd (CMD8, CMD8_INT_EN, CmdArgument);
+  if (Status == EFI_SUCCESS) {
+    Response = MmioRead32 (MMCHS_RSP10);
+    DEBUG ((EFI_D_INFO, "CMD8 success. CMD8 response: %x\n", Response));
+    if (Response != CmdArgument) {
+      return EFI_DEVICE_ERROR;
+    }
+    DEBUG ((EFI_D_INFO, "Card is SD2.0\n"));
+    SDCmd8Supported = TRUE; //Supports high capacity.
+  } else {
+    DEBUG ((EFI_D_INFO, "CMD8 fails. Not an SD2.0 card.\n"));
+  }
+
+  MmioOr32 (MMCHS_SYSCTL, SRC);
+  gBS->Stall(1000);
+  while ((MmioRead32 (MMCHS_SYSCTL) & SRC));
+
+  //Poll till card is busy
+  while (RetryCount < MAX_RETRY_COUNT) {
+    //Send CMD55 command.
+    CmdArgument = 0;
+    Status = SendCmd (CMD55, CMD55_INT_EN, CmdArgument);
+    if (Status == EFI_SUCCESS) {
+      DEBUG ((EFI_D_INFO, "CMD55 success. CMD55 response: %x\n", MmioRead32 (MMCHS_RSP10)));
+      gCardInfo.CardType = SD_CARD;
+    } else {
+      DEBUG ((EFI_D_INFO, "CMD55 fails.\n"));
+      gCardInfo.CardType = MMC_CARD;
+    }
+
+    //Send appropriate command for the card type which got detected.
+    if (gCardInfo.CardType == SD_CARD) {
+      CmdArgument = ((UINTN *) &(gCardInfo.OCRData))[0];
+
+      //Set HCS bit.
+      if (SDCmd8Supported) {
+        CmdArgument |= HCS;
+      }
+
+      Status = SendCmd (ACMD41, ACMD41_INT_EN, CmdArgument);
+      if (EFI_ERROR(Status)) {
+        DEBUG ((EFI_D_INFO, "ACMD41 fails.\n"));
+        return Status;
+      }
+      ((UINT32 *) &(gCardInfo.OCRData))[0] = MmioRead32 (MMCHS_RSP10);
+      DEBUG ((EFI_D_INFO, "SD card detected. ACMD41 OCR: %x\n", ((UINT32 *) &(gCardInfo.OCRData))[0]));
+    } else if (gCardInfo.CardType == MMC_CARD) {
+      CmdArgument = 0;
+      Status = SendCmd (CMD1, CMD1_INT_EN, CmdArgument);
+      if (EFI_ERROR(Status)) {
+        DEBUG ((EFI_D_INFO, "CMD1 fails.\n"));
+        return Status;
+      }
+      Response = MmioRead32 (MMCHS_RSP10);
+      DEBUG ((EFI_D_INFO, "MMC card detected.. CMD1 response: %x\n", Response));
+
+      //NOTE: For now, I am skipping this since I only have an SD card.
+      //Compare card OCR and host OCR (Section 22.6.1.3.2.4)
+      return EFI_UNSUPPORTED; //For now, MMC is not supported.
+    }
+
+    //Poll the card until it is out of its power-up sequence.
+    if (gCardInfo.OCRData.Busy == 1) {
+
+      if (SDCmd8Supported) {
+        gCardInfo.CardType = SD_CARD_2;
+      }
+
+      //Card is ready. Check CCS (Card capacity status) bit (bit#30).
+      //SD 2.0 standard card will response with CCS 0, SD high capacity card will respond with CCS 1.
+      if (gCardInfo.OCRData.AccessMode & BIT1) {
+        gCardInfo.CardType = SD_CARD_2_HIGH;
+        DEBUG ((EFI_D_INFO, "High capacity card.\n"));
+      } else {
+        DEBUG ((EFI_D_INFO, "Standard capacity card.\n"));
+      }
+
+      break;
+    }
+
+    gBS->Stall(1000);
+    RetryCount++;
+  }
+
+  if (RetryCount == MAX_RETRY_COUNT) {
+    DEBUG ((EFI_D_ERROR, "Timeout error. RetryCount: %d\n", RetryCount));
+    return EFI_TIMEOUT;
+  }
+
+  //Read CID data.
+  CmdArgument = 0;
+  Status = SendCmd (CMD2, CMD2_INT_EN, CmdArgument);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "CMD2 fails. Status: %x\n", Status));
+    return Status;
+  }
+
+  DEBUG ((EFI_D_INFO, "CMD2 response: %x %x %x %x\n", MmioRead32 (MMCHS_RSP10), MmioRead32 (MMCHS_RSP32), MmioRead32 (MMCHS_RSP54), MmioRead32 (MMCHS_RSP76)));
+
+  //Parse CID register data.
+  ParseCardCIDData(MmioRead32 (MMCHS_RSP10), MmioRead32 (MMCHS_RSP32), MmioRead32 (MMCHS_RSP54), MmioRead32 (MMCHS_RSP76));
+
+  //Read RCA
+  CmdArgument = 0;
+  Status = SendCmd (CMD3, CMD3_INT_EN, CmdArgument);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "CMD3 fails. Status: %x\n", Status));
+    return Status;
+  }
+
+  //Set RCA for the detected card. RCA is CMD3 response.
+  gCardInfo.RCA = (MmioRead32 (MMCHS_RSP10) >> 16);
+  DEBUG ((EFI_D_INFO, "CMD3 response: RCA %x\n", gCardInfo.RCA));
+
+  //MMC Bus setting change after card identification.
+  MmioAnd32 (MMCHS_CON, ~OD);
+  MmioOr32 (MMCHS_HCTL, SDVS_3_0_V);
+  UpdateMMCHSClkFrequency(CLKD_400KHZ); //Set the clock frequency to 400KHz.
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+GetCardSpecificData (
+  VOID
+  )
+{
+  EFI_STATUS Status;
+  UINTN      CmdArgument;
+
+  //Send CMD9 to retrieve CSD.
+  CmdArgument = gCardInfo.RCA << 16;
+  Status = SendCmd (CMD9, CMD9_INT_EN, CmdArgument);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "CMD9 fails. Status: %x\n", Status));
+    return Status;
+  }
+
+  //Populate 128-bit CSD register data.
+  ((UINT32 *)&(gCardInfo.CSDData))[0] = MmioRead32 (MMCHS_RSP10);
+  ((UINT32 *)&(gCardInfo.CSDData))[1] = MmioRead32 (MMCHS_RSP32);
+  ((UINT32 *)&(gCardInfo.CSDData))[2] = MmioRead32 (MMCHS_RSP54);
+  ((UINT32 *)&(gCardInfo.CSDData))[3] = MmioRead32 (MMCHS_RSP76);
+
+  DEBUG ((EFI_D_INFO, "CMD9 response: %x %x %x %x\n", MmioRead32 (MMCHS_RSP10), MmioRead32 (MMCHS_RSP32), MmioRead32 (MMCHS_RSP54), MmioRead32 (MMCHS_RSP76)));
+
+  //Calculate total number of blocks and max. data transfer rate supported by the detected card.
+  GetCardConfigurationData();
+
+  return Status;
+}
+
+
+EFI_STATUS
+PerformCardConfiguration (
+  VOID
+  )
+{
+  UINTN      CmdArgument = 0;
+  EFI_STATUS Status;
+
+  //Send CMD7
+  CmdArgument = gCardInfo.RCA << 16;
+  Status = SendCmd (CMD7, CMD7_INT_EN, CmdArgument);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "CMD7 fails. Status: %x\n", Status));
+    return Status;
+  }
+
+  if ((gCardInfo.CardType != UNKNOWN_CARD) && (gCardInfo.CardType != MMC_CARD)) {
+    // We could read SCR register, but SD Card Phys spec stats any SD Card shall
+    // set SCR.SD_BUS_WIDTHS to support 4-bit mode, so why bother?
+
+    // Send ACMD6 (application specific commands must be prefixed with CMD55)
+    Status = SendCmd (CMD55, CMD55_INT_EN, CmdArgument);
+    if (!EFI_ERROR (Status)) {
+      // set device into 4-bit data bus mode
+      Status = SendCmd (ACMD6, ACMD6_INT_EN, 0x2);
+      if (!EFI_ERROR (Status)) {
+        // Set host controler into 4-bit mode
+        MmioOr32 (MMCHS_HCTL, DTW_4_BIT);
+        DEBUG ((EFI_D_INFO, "SD Memory Card set to 4-bit mode\n"));
+      }
+    }
+  }
+
+  //Send CMD16 to set the block length
+  CmdArgument = gCardInfo.BlockSize;
+  Status = SendCmd (CMD16, CMD16_INT_EN, CmdArgument);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "CMD16 fails. Status: %x\n", Status));
+    return Status;
+  }
+
+  //Change MMCHS clock frequency to what detected card can support.
+  UpdateMMCHSClkFrequency(gCardInfo.ClockFrequencySelect);
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+ReadBlockData (
+  IN  EFI_BLOCK_IO_PROTOCOL       *This,
+  OUT VOID                        *Buffer
+  )
+{
+  UINTN MmcStatus;
+  UINTN *DataBuffer = Buffer;
+  UINTN DataSize = This->Media->BlockSize/4;
+  UINTN Count;
+  UINTN RetryCount = 0;
+
+  //Check controller status to make sure there is no error.
+  while (RetryCount < MAX_RETRY_COUNT) {
+    do {
+      //Read Status.
+      MmcStatus = MmioRead32 (MMCHS_STAT);
+    } while(MmcStatus == 0);
+
+    //Check if Buffer read ready (BRR) bit is set?
+    if (MmcStatus & BRR) {
+
+      //Clear BRR bit
+      MmioOr32 (MMCHS_STAT, BRR);
+
+      //Read block worth of data.
+      for (Count = 0; Count < DataSize; Count++) {
+        *DataBuffer++ = MmioRead32 (MMCHS_DATA);
+      }
+      break;
+    }
+    RetryCount++;
+  }
+
+  if (RetryCount == MAX_RETRY_COUNT) {
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+WriteBlockData (
+  IN  EFI_BLOCK_IO_PROTOCOL       *This,
+  OUT VOID                        *Buffer
+  )
+{
+  UINTN MmcStatus;
+  UINTN *DataBuffer = Buffer;
+  UINTN DataSize = This->Media->BlockSize/4;
+  UINTN Count;
+  UINTN RetryCount = 0;
+
+  //Check controller status to make sure there is no error.
+  while (RetryCount < MAX_RETRY_COUNT) {
+    do {
+      //Read Status.
+      MmcStatus = MmioRead32 (MMCHS_STAT);
+    } while(MmcStatus == 0);
+
+    //Check if Buffer write ready (BWR) bit is set?
+    if (MmcStatus & BWR) {
+
+      //Clear BWR bit
+      MmioOr32 (MMCHS_STAT, BWR);
+
+      //Write block worth of data.
+      for (Count = 0; Count < DataSize; Count++) {
+        MmioWrite32 (MMCHS_DATA, *DataBuffer++);
+      }
+
+      break;
+    }
+    RetryCount++;
+  }
+
+  if (RetryCount == MAX_RETRY_COUNT) {
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DmaBlocks (
+  IN EFI_BLOCK_IO_PROTOCOL        *This,
+  IN  UINTN                       Lba,
+  IN OUT VOID                     *Buffer,
+  IN  UINTN                       BlockCount,
+  IN  OPERATION_TYPE              OperationType
+  )
+{
+  EFI_STATUS            Status;
+  UINTN                 DmaSize = 0;
+  UINTN                 Cmd = 0;
+  UINTN                 CmdInterruptEnable;
+  UINTN                 CmdArgument;
+  VOID                  *BufferMap;
+  EFI_PHYSICAL_ADDRESS  BufferAddress;
+  OMAP_DMA4             Dma4;
+  DMA_MAP_OPERATION     DmaOperation;
+  EFI_STATUS            MmcStatus;
+  UINTN                 RetryCount = 0;
+
+CpuDeadLoop ();
+  // Map passed in buffer for DMA xfer
+  DmaSize = BlockCount * This->Media->BlockSize;
+  Status = DmaMap (DmaOperation, Buffer, &DmaSize, &BufferAddress, &BufferMap);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ZeroMem (&DmaOperation, sizeof (DMA_MAP_OPERATION));
+
+
+  Dma4.DataType = 2;                      // DMA4_CSDPi[1:0]   32-bit elements from MMCHS_DATA
+
+  Dma4.SourceEndiansim = 0;               // DMA4_CSDPi[21]
+
+  Dma4.DestinationEndianism = 0;          // DMA4_CSDPi[19]
+
+  Dma4.SourcePacked = 0;                  // DMA4_CSDPi[6]
+
+  Dma4.DestinationPacked = 0;             // DMA4_CSDPi[13]
+
+  Dma4.NumberOfElementPerFrame = This->Media->BlockSize/4; // DMA4_CENi  (TRM 4K is optimum value)
+
+  Dma4.NumberOfFramePerTransferBlock = BlockCount;         // DMA4_CFNi
+
+  Dma4.ReadPriority = 0;                  // DMA4_CCRi[6]      Low priority read
+
+  Dma4.WritePriority = 0;                 // DMA4_CCRi[23]     Prefetech disabled
+
+
+  //Populate the command information based on the operation type.
+  if (OperationType == READ) {
+    Cmd = CMD18; //Multiple block read
+    CmdInterruptEnable = CMD18_INT_EN;
+    DmaOperation = MapOperationBusMasterCommonBuffer;
+
+    Dma4.ReadPortAccessType =0 ;            // DMA4_CSDPi[8:7]   Can not burst MMCHS_DATA reg
+
+    Dma4.WritePortAccessType = 3;           // DMA4_CSDPi[15:14] Memory burst 16x32
+
+    Dma4.WriteMode = 1;                     // DMA4_CSDPi[17:16] Write posted
+
+
+
+    Dma4.SourceStartAddress = MMCHS_DATA;                   // DMA4_CSSAi
+
+    Dma4.DestinationStartAddress = (UINT32)BufferAddress;   // DMA4_CDSAi
+
+    Dma4.SourceElementIndex = 1;                            // DMA4_CSEi
+
+    Dma4.SourceFrameIndex = 0x200;                          // DMA4_CSFi
+
+    Dma4.DestinationElementIndex = 1;                       // DMA4_CDEi
+
+    Dma4.DestinationFrameIndex = 0;                         // DMA4_CDFi
+
+
+
+    Dma4.ReadPortAccessMode = 0;            // DMA4_CCRi[13:12]  Always read MMCHS_DATA
+
+    Dma4.WritePortAccessMode = 1;           // DMA4_CCRi[15:14]  Post increment memory address
+
+    Dma4.ReadRequestNumber = 0x1e;          // DMA4_CCRi[4:0]    Syncro with MMCA_DMA_RX (61)
+
+    Dma4.WriteRequestNumber = 1;            // DMA4_CCRi[20:19]  Syncro upper 0x3e == 62 (one based)
+
+  } else if (OperationType == WRITE) {
+    Cmd = CMD25; //Multiple block write
+    CmdInterruptEnable = CMD25_INT_EN;
+    DmaOperation = MapOperationBusMasterRead;
+
+    Dma4.ReadPortAccessType = 3;            // DMA4_CSDPi[8:7]   Memory burst 16x32
+
+    Dma4.WritePortAccessType = 0;           // DMA4_CSDPi[15:14] Can not burst MMCHS_DATA reg
+
+    Dma4.WriteMode = 1;                     // DMA4_CSDPi[17:16] Write posted ???
+
+
+
+    Dma4.SourceStartAddress = (UINT32)BufferAddress;        // DMA4_CSSAi
+
+    Dma4.DestinationStartAddress = MMCHS_DATA;              // DMA4_CDSAi
+
+    Dma4.SourceElementIndex = 1;                            // DMA4_CSEi
+
+    Dma4.SourceFrameIndex = 0x200;                          // DMA4_CSFi
+
+    Dma4.DestinationElementIndex = 1;                       // DMA4_CDEi
+
+    Dma4.DestinationFrameIndex = 0;                         // DMA4_CDFi
+
+
+
+    Dma4.ReadPortAccessMode = 1;            // DMA4_CCRi[13:12]  Post increment memory address
+
+    Dma4.WritePortAccessMode = 0;           // DMA4_CCRi[15:14]  Always write MMCHS_DATA
+
+    Dma4.ReadRequestNumber = 0x1d;          // DMA4_CCRi[4:0]    Syncro with MMCA_DMA_TX (60)
+
+    Dma4.WriteRequestNumber = 1;            // DMA4_CCRi[20:19]  Syncro upper 0x3d == 61 (one based)
+
+  } else {
+    return EFI_INVALID_PARAMETER;
+  }
+
+
+  EnableDmaChannel (2, &Dma4);
+
+
+  //Set command argument based on the card access mode (Byte mode or Block mode)
+  if (gCardInfo.OCRData.AccessMode & BIT1) {
+    CmdArgument = Lba;
+  } else {
+    CmdArgument = Lba * This->Media->BlockSize;
+  }
+
+  //Send Command.
+  Status = SendCmd (Cmd, CmdInterruptEnable, CmdArgument);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "CMD fails. Status: %x\n", Status));
+    return Status;
+  }
+
+    //Check for the Transfer completion.
+  while (RetryCount < MAX_RETRY_COUNT) {
+    //Read Status
+    do {
+      MmcStatus = MmioRead32 (MMCHS_STAT);
+    } while (MmcStatus == 0);
+
+    //Check if Transfer complete (TC) bit is set?
+    if (MmcStatus & TC) {
+      break;
+    } else {
+      DEBUG ((EFI_D_ERROR, "MmcStatus for TC: %x\n", MmcStatus));
+      //Check if DEB, DCRC or DTO interrupt occured.
+      if ((MmcStatus & DEB) | (MmcStatus & DCRC) | (MmcStatus & DTO)) {
+        //There was an error during the data transfer.
+
+        //Set SRD bit to 1 and wait until it return to 0x0.
+        MmioOr32 (MMCHS_SYSCTL, SRD);
+        while((MmioRead32 (MMCHS_SYSCTL) & SRD) != 0x0);
+
+        DisableDmaChannel (2, DMA4_CSR_BLOCK, DMA4_CSR_ERR);
+        DmaUnmap (BufferMap);
+        return EFI_DEVICE_ERROR;
+      }
+    }
+    RetryCount++;
+  }
+
+  DisableDmaChannel (2, DMA4_CSR_BLOCK, DMA4_CSR_ERR);
+  Status = DmaUnmap (BufferMap);
+
+  if (RetryCount == MAX_RETRY_COUNT) {
+    DEBUG ((EFI_D_ERROR, "TransferBlockData timed out.\n"));
+    return EFI_TIMEOUT;
+  }
+
+  return Status;
+}
+
+
+EFI_STATUS
+TransferBlock (
+  IN EFI_BLOCK_IO_PROTOCOL        *This,
+  IN  UINTN                       Lba,
+  IN OUT VOID                     *Buffer,
+  IN  OPERATION_TYPE              OperationType
+  )
+{
+  EFI_STATUS Status;
+  UINTN      MmcStatus;
+  UINTN      RetryCount = 0;
+  UINTN      Cmd = 0;
+  UINTN      CmdInterruptEnable = 0;
+  UINTN      CmdArgument = 0;
+
+
+  //Populate the command information based on the operation type.
+  if (OperationType == READ) {
+    Cmd = CMD17; //Single block read
+    CmdInterruptEnable = CMD18_INT_EN;
+  } else if (OperationType == WRITE) {
+    Cmd = CMD24; //Single block write
+    CmdInterruptEnable = CMD24_INT_EN;
+  }
+
+  //Set command argument based on the card access mode (Byte mode or Block mode)
+  if (gCardInfo.OCRData.AccessMode & BIT1) {
+    CmdArgument = Lba;
+  } else {
+    CmdArgument = Lba * This->Media->BlockSize;
+  }
+
+  //Send Command.
+  Status = SendCmd (Cmd, CmdInterruptEnable, CmdArgument);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "CMD fails. Status: %x\n", Status));
+    return Status;
+  }
+
+  //Read or Write data.
+  if (OperationType == READ) {
+    Status = ReadBlockData (This, Buffer);
+    if (EFI_ERROR(Status)) {
+      DEBUG((EFI_D_ERROR, "ReadBlockData fails.\n"));
+      return Status;
+    }
+  } else if (OperationType == WRITE) {
+    Status = WriteBlockData (This, Buffer);
+    if (EFI_ERROR(Status)) {
+      DEBUG((EFI_D_ERROR, "WriteBlockData fails.\n"));
+      return Status;
+    }
+  }
+
+  //Check for the Transfer completion.
+  while (RetryCount < MAX_RETRY_COUNT) {
+    //Read Status
+    do {
+      MmcStatus = MmioRead32 (MMCHS_STAT);
+    } while (MmcStatus == 0);
+
+    //Check if Transfer complete (TC) bit is set?
+    if (MmcStatus & TC) {
+      break;
+    } else {
+      DEBUG ((EFI_D_ERROR, "MmcStatus for TC: %x\n", MmcStatus));
+      //Check if DEB, DCRC or DTO interrupt occured.
+      if ((MmcStatus & DEB) | (MmcStatus & DCRC) | (MmcStatus & DTO)) {
+        //There was an error during the data transfer.
+
+        //Set SRD bit to 1 and wait until it return to 0x0.
+        MmioOr32 (MMCHS_SYSCTL, SRD);
+        while((MmioRead32 (MMCHS_SYSCTL) & SRD) != 0x0);
+
+        return EFI_DEVICE_ERROR;
+      }
+    }
+    RetryCount++;
+  }
+
+  if (RetryCount == MAX_RETRY_COUNT) {
+    DEBUG ((EFI_D_ERROR, "TransferBlockData timed out.\n"));
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+BOOLEAN
+CardPresent (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+  UINT8       Data;
+
+  //
+  // Card detect is a GPIO0 on the TPS65950
+  //
+  Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, GPIODATAIN1), 1, &Data);
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+
+  if ((Data & CARD_DETECT_BIT) == CARD_DETECT_BIT) {
+    // No Card present
+    return FALSE;
+  } else {
+    return TRUE;
+  }
+}
+
+EFI_STATUS
+DetectCard (
+  VOID
+  )
+{
+  EFI_STATUS    Status;
+
+  if (!CardPresent ()) {
+    return EFI_NO_MEDIA;
+  }
+
+  //Initialize MMC host controller clocks.
+  Status = InitializeMMCHS ();
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "Initialize MMC host controller fails. Status: %x\n", Status));
+    return Status;
+  }
+
+  //Software reset of the MMCHS host controller.
+  MmioWrite32 (MMCHS_SYSCONFIG, SOFTRESET);
+  gBS->Stall(1000);
+  while ((MmioRead32 (MMCHS_SYSSTATUS) & RESETDONE_MASK) != RESETDONE);
+
+  //Soft reset for all.
+  MmioWrite32 (MMCHS_SYSCTL, SRA);
+  gBS->Stall(1000);
+  while ((MmioRead32 (MMCHS_SYSCTL) & SRA) != 0x0);
+
+  //Voltage capabilities initialization. Activate VS18 and VS30.
+  MmioOr32 (MMCHS_CAPA, (VS30 | VS18));
+
+  //Wakeup configuration
+  MmioOr32 (MMCHS_SYSCONFIG, ENAWAKEUP);
+  MmioOr32 (MMCHS_HCTL, IWE);
+
+  //MMCHS Controller default initialization
+  MmioOr32 (MMCHS_CON, (OD | DW8_1_4_BIT | CEATA_OFF));
+
+  MmioWrite32 (MMCHS_HCTL, (SDVS_3_0_V | DTW_1_BIT | SDBP_OFF));
+
+  //Enable internal clock
+  MmioOr32 (MMCHS_SYSCTL, ICE);
+
+  //Set the clock frequency to 80KHz.
+  UpdateMMCHSClkFrequency (CLKD_80KHZ);
+
+  //Enable SD bus power.
+  MmioOr32 (MMCHS_HCTL, (SDBP_ON));
+
+  //Poll till SD bus power bit is set.
+  while ((MmioRead32 (MMCHS_HCTL) & SDBP_MASK) != SDBP_ON);
+
+  //Card idenfication
+  Status = PerformCardIdenfication ();
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "No MMC/SD card detected.\n"));
+    return Status;
+  }
+
+  //Get CSD (Card specific data) for the detected card.
+  Status = GetCardSpecificData();
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  //Configure the card in data transfer mode.
+  Status = PerformCardConfiguration();
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  //Patch the Media structure.
+  gMMCHSMedia.LastBlock    = (gCardInfo.NumBlocks - 1);
+  gMMCHSMedia.BlockSize    = gCardInfo.BlockSize;
+  gMMCHSMedia.ReadOnly     = (MmioRead32 (GPIO1_BASE + GPIO_DATAIN) & BIT23) == BIT23;
+  gMMCHSMedia.MediaPresent = TRUE;
+  gMMCHSMedia.MediaId++;
+
+  DEBUG ((EFI_D_INFO, "SD Card Media Change on Handle 0x%08x\n", gImageHandle));
+
+  return Status;
+}
+
+#define MAX_MMCHS_TRANSFER_SIZE  0x4000
+
+EFI_STATUS
+SdReadWrite (
+  IN EFI_BLOCK_IO_PROTOCOL    *This,
+  IN  UINTN                   Lba,
+  OUT VOID                    *Buffer,
+  IN  UINTN                   BufferSize,
+  IN  OPERATION_TYPE          OperationType
+  )
+{
+  EFI_STATUS Status = EFI_SUCCESS;
+  UINTN      RetryCount = 0;
+  UINTN      BlockCount;
+  UINTN      BytesToBeTranferedThisPass = 0;
+  UINTN      BytesRemainingToBeTransfered;
+  EFI_TPL    OldTpl;
+
+  BOOLEAN    Update;
+
+
+
+  Update               = FALSE;
+
+  if (gMediaChange) {
+    Update = TRUE;
+    Status = DetectCard  ();
+    if (EFI_ERROR (Status)) {
+      // We detected a removal
+      gMMCHSMedia.MediaPresent = FALSE;
+      gMMCHSMedia.LastBlock    = 0;
+      gMMCHSMedia.BlockSize    = 512;  // Should be zero but there is a bug in DiskIo
+      gMMCHSMedia.ReadOnly     = FALSE;
+    }
+    gMediaChange             = FALSE;
+  } else if (!gMMCHSMedia.MediaPresent) {
+    Status = EFI_NO_MEDIA;
+    goto Done;
+  }
+
+  if (Update) {
+    DEBUG ((EFI_D_INFO, "SD Card ReinstallProtocolInterface ()\n"));
+    gBS->ReinstallProtocolInterface (
+          gImageHandle,
+          &gEfiBlockIoProtocolGuid,
+          &gBlockIo,
+          &gBlockIo
+          );
+    return EFI_MEDIA_CHANGED;
+  }
+
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  if (Buffer == NULL) {
+    Status = EFI_INVALID_PARAMETER;
+    goto Done;
+  }
+
+  if (Lba > This->Media->LastBlock) {
+    Status = EFI_INVALID_PARAMETER;
+    goto Done;
+  }
+
+  if ((BufferSize % This->Media->BlockSize) != 0) {
+    Status = EFI_BAD_BUFFER_SIZE;
+    goto Done;
+  }
+
+  //Check if the data lines are not in use.
+  while ((RetryCount++ < MAX_RETRY_COUNT) && ((MmioRead32 (MMCHS_PSTATE) & DATI_MASK) != DATI_ALLOWED));
+  if (RetryCount == MAX_RETRY_COUNT) {
+    Status = EFI_TIMEOUT;
+    goto Done;
+  }
+
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+  BytesRemainingToBeTransfered = BufferSize;
+  while (BytesRemainingToBeTransfered > 0) {
+
+    if (gMediaChange) {
+      Status = EFI_NO_MEDIA;
+      DEBUG ((EFI_D_INFO, "SdReadWrite() EFI_NO_MEDIA due to gMediaChange\n"));
+      goto DoneRestoreTPL;
+    }
+
+    // Turn OFF DMA path until it is debugged
+    // BytesToBeTranferedThisPass = (BytesToBeTranferedThisPass >= MAX_MMCHS_TRANSFER_SIZE) ? MAX_MMCHS_TRANSFER_SIZE : BytesRemainingToBeTransfered;
+    BytesToBeTranferedThisPass   = This->Media->BlockSize;
+
+    BlockCount = BytesToBeTranferedThisPass/This->Media->BlockSize;
+
+    if (BlockCount > 1) {
+      Status = DmaBlocks (This, Lba, Buffer, BlockCount, OperationType);
+    } else {
+      //Transfer a block worth of data.
+      Status = TransferBlock (This, Lba, Buffer, OperationType);
+    }
+
+    if (EFI_ERROR(Status)) {
+      DEBUG ((EFI_D_ERROR, "TransferBlockData fails. %x\n", Status));
+      goto DoneRestoreTPL;
+    }
+
+    BytesRemainingToBeTransfered -= BytesToBeTranferedThisPass;
+    Lba    += BlockCount;
+    Buffer = (UINT8 *)Buffer + This->Media->BlockSize;
+  }
+
+DoneRestoreTPL:
+
+  gBS->RestoreTPL (OldTpl);
+
+Done:
+
+  return Status;
+
+}
+
+
+/**
+
+  Reset the Block Device.
+
+
+
+  @param  This                 Indicates a pointer to the calling context.
+
+  @param  ExtendedVerification Driver may perform diagnostics on reset.
+
+
+
+  @retval EFI_SUCCESS          The device was reset.
+
+  @retval EFI_DEVICE_ERROR     The device is not functioning properly and could
+
+                               not be reset.
+
+
+
+**/
+EFI_STATUS
+EFIAPI
+MMCHSReset (
+  IN EFI_BLOCK_IO_PROTOCOL          *This,
+  IN BOOLEAN                        ExtendedVerification
+  )
+{
+  return EFI_SUCCESS;
+}
+
+
+/**
+
+  Read BufferSize bytes from Lba into Buffer.
+
+
+
+  @param  This       Indicates a pointer to the calling context.
+
+  @param  MediaId    Id of the media, changes every time the media is replaced.
+
+  @param  Lba        The starting Logical Block Address to read from
+
+  @param  BufferSize Size of Buffer, must be a multiple of device block size.
+
+  @param  Buffer     A pointer to the destination buffer for the data. The caller is
+
+                     responsible for either having implicit or explicit ownership of the buffer.
+
+
+
+  @retval EFI_SUCCESS           The data was read correctly from the device.
+
+  @retval EFI_DEVICE_ERROR      The device reported an error while performing the read.
+
+  @retval EFI_NO_MEDIA          There is no media in the device.
+
+  @retval EFI_MEDIA_CHANGED     The MediaId does not matched the current device.
+
+  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
+
+  @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
+
+                                or the buffer is not on proper alignment.
+
+EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+MMCHSReadBlocks (
+  IN EFI_BLOCK_IO_PROTOCOL          *This,
+  IN UINT32                         MediaId,
+  IN EFI_LBA                        Lba,
+  IN UINTN                          BufferSize,
+  OUT VOID                          *Buffer
+  )
+{
+  EFI_STATUS Status;
+
+  //Perform Read operation.
+  Status = SdReadWrite (This, (UINTN)Lba, Buffer, BufferSize, READ);
+
+  return Status;
+
+}
+
+
+/**
+
+  Write BufferSize bytes from Lba into Buffer.
+
+
+
+  @param  This       Indicates a pointer to the calling context.
+
+  @param  MediaId    The media ID that the write request is for.
+
+  @param  Lba        The starting logical block address to be written. The caller is
+
+                     responsible for writing to only legitimate locations.
+
+  @param  BufferSize Size of Buffer, must be a multiple of device block size.
+
+  @param  Buffer     A pointer to the source buffer for the data.
+
+
+
+  @retval EFI_SUCCESS           The data was written correctly to the device.
+
+  @retval EFI_WRITE_PROTECTED   The device can not be written to.
+
+  @retval EFI_DEVICE_ERROR      The device reported an error while performing the write.
+
+  @retval EFI_NO_MEDIA          There is no media in the device.
+
+  @retval EFI_MEDIA_CHNAGED     The MediaId does not matched the current device.
+
+  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
+
+  @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
+
+                                or the buffer is not on proper alignment.
+
+
+
+**/
+EFI_STATUS
+EFIAPI
+MMCHSWriteBlocks (
+  IN EFI_BLOCK_IO_PROTOCOL          *This,
+  IN UINT32                         MediaId,
+  IN EFI_LBA                        Lba,
+  IN UINTN                          BufferSize,
+  IN VOID                           *Buffer
+  )
+{
+  EFI_STATUS  Status;
+
+  //Perform write operation.
+  Status = SdReadWrite (This, (UINTN)Lba, Buffer, BufferSize, WRITE);
+
+
+  return Status;
+
+}
+
+
+/**
+
+  Flush the Block Device.
+
+
+
+  @param  This              Indicates a pointer to the calling context.
+
+
+
+  @retval EFI_SUCCESS       All outstanding data was written to the device
+
+  @retval EFI_DEVICE_ERROR  The device reported an error while writting back the data
+
+  @retval EFI_NO_MEDIA      There is no media in the device.
+
+
+
+**/
+EFI_STATUS
+EFIAPI
+MMCHSFlushBlocks (
+  IN EFI_BLOCK_IO_PROTOCOL  *This
+  )
+{
+  return EFI_SUCCESS;
+}
+
+
+EFI_BLOCK_IO_PROTOCOL gBlockIo = {
+  EFI_BLOCK_IO_INTERFACE_REVISION,   // Revision
+  &gMMCHSMedia,                      // *Media
+  MMCHSReset,                        // Reset
+  MMCHSReadBlocks,                   // ReadBlocks
+  MMCHSWriteBlocks,                  // WriteBlocks
+  MMCHSFlushBlocks                   // FlushBlocks
+};
+
+
+/**
+
+  Timer callback to convert card present hardware into a boolean that indicates
+
+  a media change event has happened. If you just check the GPIO you could see
+
+  card 1 and then check again after card 1 was removed and card 2 was inserted
+
+  and you would still see media present. Thus you need the timer tick to catch
+
+  the toggle event.
+
+
+
+  @param  Event                 Event whose notification function is being invoked.
+
+  @param  Context               The pointer to the notification function's context,
+
+                                which is implementation-dependent. Not used.
+
+
+
+**/
+VOID
+EFIAPI
+TimerCallback (
+  IN  EFI_EVENT   Event,
+  IN  VOID        *Context
+  )
+{
+  BOOLEAN Present;
+
+  Present = CardPresent ();
+  if (gMMCHSMedia.MediaPresent) {
+    if (!Present && !gMediaChange) {
+      gMediaChange = TRUE;
+    }
+  } else {
+    if (Present && !gMediaChange) {
+      gMediaChange = TRUE;
+    }
+  }
+}
+
+
+EFI_STATUS
+EFIAPI
+MMCHSInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = gBS->LocateProtocol (&gEmbeddedExternalDeviceProtocolGuid, NULL, (VOID **)&gTPS65950);
+  ASSERT_EFI_ERROR(Status);
+
+  ZeroMem (&gCardInfo, sizeof (CARD_INFO));
+
+  Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, TimerCallback, NULL, &gTimerEvent);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gBS->SetTimer (gTimerEvent, TimerPeriodic, FixedPcdGet32 (PcdMmchsTimerFreq100NanoSeconds));
+  ASSERT_EFI_ERROR (Status);
+
+  //Publish BlockIO.
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gEfiBlockIoProtocolGuid,    &gBlockIo,
+                  &gEfiDevicePathProtocolGuid, &gMmcHsDevicePath,
+                  NULL
+                  );
+  return Status;
+}
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.h b/Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.h
new file mode 100644
index 0000000000..63eaf2354a
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.h
@@ -0,0 +1,169 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _MMCHS_H_
+#define _MMCHS_H_
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/OmapLib.h>
+#include <Library/OmapDmaLib.h>
+#include <Library/DmaLib.h>
+
+#include <Protocol/EmbeddedExternalDevice.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/DevicePath.h>
+
+#include <Omap3530/Omap3530.h>
+#include <TPS65950.h>
+
+#define MAX_RETRY_COUNT  (100*5)
+
+#define HCS               BIT30 //Host capacity support/1 = Supporting high capacity
+#define CCS               BIT30 //Card capacity status/1 = High capacity card
+typedef struct {
+  UINT32  Reserved0:   7; // 0
+  UINT32  V170_V195:   1; // 1.70V - 1.95V
+  UINT32  V200_V260:   7; // 2.00V - 2.60V
+  UINT32  V270_V360:   9; // 2.70V - 3.60V
+  UINT32  RESERVED_1:  5; // Reserved
+  UINT32  AccessMode:  2; // 00b (byte mode), 10b (sector mode)
+  UINT32  Busy:        1; // This bit is set to LOW if the card has not finished the power up routine
+}OCR;
+
+typedef struct {
+  UINT32  NOT_USED;   // 1 [0:0]
+  UINT32  CRC;        // CRC7 checksum [7:1]
+  UINT32  MDT;        // Manufacturing date [19:8]
+  UINT32  RESERVED_1; // Reserved [23:20]
+  UINT32  PSN;        // Product serial number [55:24]
+  UINT8   PRV;        // Product revision [63:56]
+  UINT8   PNM[5];     // Product name [64:103]
+  UINT16  OID;        // OEM/Application ID [119:104]
+  UINT8   MID;        // Manufacturer ID [127:120]
+}CID;
+
+typedef struct {
+  UINT8   NOT_USED:           1; // Not used, always 1 [0:0]
+  UINT8   CRC:                7; // CRC [7:1]
+
+  UINT8   RESERVED_1:         2; // Reserved [9:8]
+  UINT8   FILE_FORMAT:        2; // File format [11:10]
+  UINT8   TMP_WRITE_PROTECT:  1; // Temporary write protection [12:12]
+  UINT8   PERM_WRITE_PROTECT: 1; // Permanent write protection [13:13]
+  UINT8   COPY:               1; // Copy flag (OTP) [14:14]
+  UINT8   FILE_FORMAT_GRP:    1; // File format group [15:15]
+
+  UINT16  RESERVED_2:         5; // Reserved [20:16]
+  UINT16  WRITE_BL_PARTIAL:   1; // Partial blocks for write allowed [21:21]
+  UINT16  WRITE_BL_LEN:       4; // Max. write data block length [25:22]
+  UINT16  R2W_FACTOR:         3; // Write speed factor [28:26]
+  UINT16  RESERVED_3:         2; // Reserved [30:29]
+  UINT16  WP_GRP_ENABLE:      1; // Write protect group enable [31:31]
+
+  UINT32  WP_GRP_SIZE:        7; // Write protect group size [38:32]
+  UINT32  SECTOR_SIZE:        7; // Erase sector size [45:39]
+  UINT32  ERASE_BLK_EN:       1; // Erase single block enable [46:46]
+  UINT32  C_SIZE_MULT:        3; // Device size multiplier [49:47]
+  UINT32  VDD_W_CURR_MAX:     3; // Max. write current @ VDD max [52:50]
+  UINT32  VDD_W_CURR_MIN:     3; // Max. write current @ VDD min [55:53]
+  UINT32  VDD_R_CURR_MAX:     3; // Max. read current @ VDD max [58:56]
+  UINT32  VDD_R_CURR_MIN:     3; // Max. read current @ VDD min [61:59]
+  UINT32  C_SIZELow2:         2; // Device size [63:62]
+
+  UINT32  C_SIZEHigh10:       10;// Device size [73:64]
+  UINT32  RESERVED_4:         2; // Reserved [75:74]
+  UINT32  DSR_IMP:            1; // DSR implemented [76:76]
+  UINT32  READ_BLK_MISALIGN:  1; // Read block misalignment [77:77]
+  UINT32  WRITE_BLK_MISALIGN: 1; // Write block misalignment [78:78]
+  UINT32  READ_BL_PARTIAL:    1; // Partial blocks for read allowed [79:79]
+  UINT32  READ_BL_LEN:        4; // Max. read data block length [83:80]
+  UINT32  CCC:                12;// Card command classes [95:84]
+
+  UINT8   TRAN_SPEED          ;  // Max. bus clock frequency [103:96]
+  UINT8   NSAC                ;  // Data read access-time 2 in CLK cycles (NSAC*100) [111:104]
+  UINT8   TAAC                ;  // Data read access-time 1 [119:112]
+
+  UINT8   RESERVED_5:         6; // Reserved [125:120]
+  UINT8   CSD_STRUCTURE:      2; // CSD structure [127:126]
+}CSD;
+
+typedef struct {
+  UINT8   NOT_USED:           1; // Not used, always 1 [0:0]
+  UINT8   CRC:                7; // CRC [7:1]
+  UINT8   RESERVED_1:         2; // Reserved [9:8]
+  UINT8   FILE_FORMAT:        2; // File format [11:10]
+  UINT8   TMP_WRITE_PROTECT:  1; // Temporary write protection [12:12]
+  UINT8   PERM_WRITE_PROTECT: 1; // Permanent write protection [13:13]
+  UINT8   COPY:               1; // Copy flag (OTP) [14:14]
+  UINT8   FILE_FORMAT_GRP:    1; // File format group [15:15]
+  UINT16  RESERVED_2:         5; // Reserved [20:16]
+  UINT16  WRITE_BL_PARTIAL:   1; // Partial blocks for write allowed [21:21]
+  UINT16  WRITE_BL_LEN:       4; // Max. write data block length [25:22]
+  UINT16  R2W_FACTOR:         3; // Write speed factor [28:26]
+  UINT16  RESERVED_3:         2; // Reserved [30:29]
+  UINT16  WP_GRP_ENABLE:      1; // Write protect group enable [31:31]
+  UINT16  WP_GRP_SIZE:        7; // Write protect group size [38:32]
+  UINT16  SECTOR_SIZE:        7; // Erase sector size [45:39]
+  UINT16  ERASE_BLK_EN:       1; // Erase single block enable [46:46]
+  UINT16  RESERVED_4:         1; // Reserved [47:47]
+  UINT32  C_SIZELow16:        16;// Device size [69:48]
+  UINT32  C_SIZEHigh6:        6; // Device size [69:48]
+  UINT32  RESERVED_5:         6; // Reserved [75:70]
+  UINT32  DSR_IMP:            1; // DSR implemented [76:76]
+  UINT32  READ_BLK_MISALIGN:  1; // Read block misalignment [77:77]
+  UINT32  WRITE_BLK_MISALIGN: 1; // Write block misalignment [78:78]
+  UINT32  READ_BL_PARTIAL:    1; // Partial blocks for read allowed [79:79]
+  UINT16  READ_BL_LEN:        4; // Max. read data block length [83:80]
+  UINT16  CCC:                12;// Card command classes [95:84]
+  UINT8   TRAN_SPEED          ;  // Max. bus clock frequency [103:96]
+  UINT8   NSAC                ;  // Data read access-time 2 in CLK cycles (NSAC*100) [111:104]
+  UINT8   TAAC                ;  // Data read access-time 1 [119:112]
+  UINT8   RESERVED_6:         6; // 0 [125:120]
+  UINT8   CSD_STRUCTURE:      2; // CSD structure [127:126]
+}CSD_SDV2;
+
+typedef enum {
+  UNKNOWN_CARD,
+  MMC_CARD,              //MMC card
+  SD_CARD,               //SD 1.1 card
+  SD_CARD_2,             //SD 2.0 or above standard card
+  SD_CARD_2_HIGH         //SD 2.0 or above high capacity card
+} CARD_TYPE;
+
+typedef enum {
+  READ,
+  WRITE
+} OPERATION_TYPE;
+
+typedef struct  {
+  UINT16    RCA;
+  UINTN     BlockSize;
+  UINTN     NumBlocks;
+  UINTN     ClockFrequencySelect;
+  CARD_TYPE CardType;
+  OCR       OCRData;
+  CID       CIDData;
+  CSD       CSDData;
+} CARD_INFO;
+
+EFI_STATUS
+DetectCard (
+  VOID
+  );
+
+extern EFI_BLOCK_IO_PROTOCOL gBlockIo;
+
+#endif
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.inf b/Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.inf
new file mode 100644
index 0000000000..a759f59394
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.inf
@@ -0,0 +1,48 @@
+#/** @file
+#
+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = MMCHS
+  FILE_GUID                      = 100c2cfa-b586-4198-9b4c-1683d195b1da
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = MMCHSInitialize
+
+
+[Sources.common]
+  MMCHS.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  UefiLib
+  UefiDriverEntryPoint
+  MemoryAllocationLib
+  IoLib
+  OmapDmaLib
+  DmaLib
+
+[Guids]
+
+[Protocols]
+  gEfiBlockIoProtocolGuid
+  gEfiCpuArchProtocolGuid
+  gEfiDevicePathProtocolGuid
+  gEmbeddedExternalDeviceProtocolGuid
+
+[Pcd]
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxMMCHS1Base
+  gOmap35xxTokenSpaceGuid.PcdMmchsTimerFreq100NanoSeconds
+
+[depex]
+  gEmbeddedExternalDeviceProtocolGuid
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.c b/Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.c
new file mode 100644
index 0000000000..410fed9366
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.c
@@ -0,0 +1,671 @@
+/** @file
+*
+*  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+*  Copyright (c) 2011 - 2014, ARM Limited. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include "MmcHostDxe.h"
+
+EMBEDDED_EXTERNAL_DEVICE   *gTPS65950;
+UINT8                      mMaxDataTransferRate = 0;
+UINT32                     mRca = 0;
+BOOLEAN                    mBitModeSet = FALSE;
+
+
+typedef struct {
+  VENDOR_DEVICE_PATH  Mmc;
+  EFI_DEVICE_PATH     End;
+} MMCHS_DEVICE_PATH;
+
+MMCHS_DEVICE_PATH gMMCDevicePath = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      { (UINT8)(sizeof(VENDOR_DEVICE_PATH)), (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8) },
+    },
+    { 0xb615f1f5, 0x5088, 0x43cd, { 0x80, 0x9c, 0xa1, 0x6e, 0x52, 0x48, 0x7d, 0x00 } }
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }
+  }
+};
+
+BOOLEAN
+IgnoreCommand (
+  UINT32 Command
+  )
+{
+  switch(Command) {
+    case MMC_CMD12:
+      return TRUE;
+    case MMC_CMD13:
+      return TRUE;
+    default:
+      return FALSE;
+  }
+}
+
+UINT32
+TranslateCommand (
+  UINT32 Command
+  )
+{
+  UINT32 Translation;
+
+  switch(Command) {
+    case MMC_CMD2:
+      Translation = CMD2;
+      break;
+    case MMC_CMD3:
+      Translation = CMD3;
+      break;
+    /*case MMC_CMD6:
+      Translation = CMD6;
+      break;*/
+    case MMC_CMD7:
+      Translation = CMD7;
+      break;
+    case MMC_CMD8:
+      Translation = CMD8;
+      break;
+    case MMC_CMD9:
+      Translation = CMD9;
+      break;
+    /*case MMC_CMD12:
+      Translation = CMD12;
+      break;
+    case MMC_CMD13:
+      Translation = CMD13;
+      break;*/
+    case MMC_CMD16:
+      Translation = CMD16;
+      break;
+    case MMC_CMD17:
+      Translation = 0x113A0014;//CMD17;
+      break;
+    case MMC_CMD24:
+      Translation = CMD24 | 4;
+      break;
+    case MMC_CMD55:
+      Translation = CMD55;
+      break;
+    case MMC_ACMD41:
+      Translation = ACMD41;
+      break;
+    default:
+      Translation = Command;
+  }
+
+  return Translation;
+}
+
+VOID
+CalculateCardCLKD (
+  UINTN *ClockFrequencySelect
+  )
+{
+  UINTN    TransferRateValue = 0;
+  UINTN    TimeValue = 0 ;
+  UINTN    Frequency = 0;
+
+  DEBUG ((DEBUG_BLKIO, "CalculateCardCLKD()\n"));
+
+  // For SD Cards  we would need to send CMD6 to set
+  // speeds abouve 25MHz. High Speed mode 50 MHz and up
+
+  // Calculate Transfer rate unit (Bits 2:0 of TRAN_SPEED)
+  switch (mMaxDataTransferRate & 0x7) { // 2
+    case 0:
+      TransferRateValue = 100 * 1000;
+      break;
+
+    case 1:
+      TransferRateValue = 1 * 1000 * 1000;
+      break;
+
+    case 2:
+      TransferRateValue = 10 * 1000 * 1000;
+      break;
+
+    case 3:
+      TransferRateValue = 100 * 1000 * 1000;
+      break;
+
+    default:
+      DEBUG ((DEBUG_BLKIO, "Invalid parameter.\n"));
+      ASSERT(FALSE);
+      return;
+  }
+
+  //Calculate Time value (Bits 6:3 of TRAN_SPEED)
+  switch ((mMaxDataTransferRate >> 3) & 0xF) { // 6
+    case 1:
+      TimeValue = 10;
+      break;
+
+    case 2:
+      TimeValue = 12;
+      break;
+
+    case 3:
+      TimeValue = 13;
+      break;
+
+    case 4:
+      TimeValue = 15;
+      break;
+
+    case 5:
+      TimeValue = 20;
+      break;
+
+    case 6:
+      TimeValue = 25;
+      break;
+
+    case 7:
+      TimeValue = 30;
+      break;
+
+    case 8:
+      TimeValue = 35;
+      break;
+
+    case 9:
+      TimeValue = 40;
+      break;
+
+    case 10:
+      TimeValue = 45;
+      break;
+
+    case 11:
+      TimeValue = 50;
+      break;
+
+    case 12:
+      TimeValue = 55;
+      break;
+
+    case 13:
+      TimeValue = 60;
+      break;
+
+    case 14:
+      TimeValue = 70;
+      break;
+
+    case 15:
+      TimeValue = 80;
+      break;
+
+    default:
+      DEBUG ((DEBUG_BLKIO, "Invalid parameter.\n"));
+      ASSERT(FALSE);
+      return;
+  }
+
+  Frequency = TransferRateValue * TimeValue/10;
+
+  // Calculate Clock divider value to program in MMCHS_SYSCTL[CLKD] field.
+  *ClockFrequencySelect = ((MMC_REFERENCE_CLK/Frequency) + 1);
+
+  DEBUG ((DEBUG_BLKIO, "mMaxDataTransferRate: 0x%x, Frequency: %d KHz, ClockFrequencySelect: %x\n", mMaxDataTransferRate, Frequency/1000, *ClockFrequencySelect));
+}
+
+VOID
+UpdateMMCHSClkFrequency (
+  UINTN NewCLKD
+  )
+{
+  DEBUG ((DEBUG_BLKIO, "UpdateMMCHSClkFrequency()\n"));
+
+  // Set Clock enable to 0x0 to not provide the clock to the card
+  MmioAnd32 (MMCHS_SYSCTL, ~CEN);
+
+  // Set new clock frequency.
+  MmioAndThenOr32 (MMCHS_SYSCTL, ~CLKD_MASK, NewCLKD << 6);
+
+  // Poll till Internal Clock Stable
+  while ((MmioRead32 (MMCHS_SYSCTL) & ICS_MASK) != ICS);
+
+  // Set Clock enable to 0x1 to provide the clock to the card
+  MmioOr32 (MMCHS_SYSCTL, CEN);
+}
+
+EFI_STATUS
+InitializeMMCHS (
+  VOID
+  )
+{
+  UINT8      Data;
+  EFI_STATUS Status;
+
+  DEBUG ((DEBUG_BLKIO, "InitializeMMCHS()\n"));
+
+  // Select Device group to belong to P1 device group in Power IC.
+  Data = DEV_GRP_P1;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VMMC1_DEV_GRP), 1, &Data);
+  ASSERT_EFI_ERROR(Status);
+
+  // Configure voltage regulator for MMC1 in Power IC to output 3.0 voltage.
+  Data = VSEL_3_00V;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VMMC1_DEDICATED_REG), 1, &Data);
+  ASSERT_EFI_ERROR(Status);
+
+  // After ramping up voltage, set VDDS stable bit to indicate that voltage level is stable.
+  MmioOr32 (CONTROL_PBIAS_LITE, (PBIASLITEVMODE0 | PBIASLITEPWRDNZ0 | PBIASSPEEDCTRL0 | PBIASLITEVMODE1 | PBIASLITEWRDNZ1));
+
+  // Enable WP GPIO
+  MmioAndThenOr32 (GPIO1_BASE + GPIO_OE, ~BIT23, BIT23);
+
+  // Enable Card Detect
+  Data = CARD_DETECT_ENABLE;
+  gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, TPS65950_GPIO_CTRL), 1, &Data);
+
+  return Status;
+}
+
+BOOLEAN
+MMCIsCardPresent (
+  IN EFI_MMC_HOST_PROTOCOL     *This
+  )
+{
+  EFI_STATUS  Status;
+  UINT8       Data;
+
+  //
+  // Card detect is a GPIO0 on the TPS65950
+  //
+  Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, GPIODATAIN1), 1, &Data);
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+
+  return !(Data & CARD_DETECT_BIT);
+}
+
+BOOLEAN
+MMCIsReadOnly (
+  IN EFI_MMC_HOST_PROTOCOL     *This
+  )
+{
+  /* Note:
+   * On our BeagleBoard the SD card WP pin is always read as TRUE.
+   * Probably something wrong with GPIO configuration.
+   * BeagleBoard-xM uses microSD cards so there is no write protect at all.
+   * Hence commenting out SD card WP pin read status.
+   */
+  //return (MmioRead32 (GPIO1_BASE + GPIO_DATAIN) & BIT23) == BIT23;
+  return 0;
+
+}
+
+// TODO
+EFI_GUID mPL180MciDevicePathGuid = EFI_CALLER_ID_GUID;
+
+EFI_STATUS
+MMCBuildDevicePath (
+  IN EFI_MMC_HOST_PROTOCOL     *This,
+  IN EFI_DEVICE_PATH_PROTOCOL  **DevicePath
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL    *NewDevicePathNode;
+
+  NewDevicePathNode = CreateDeviceNode(HARDWARE_DEVICE_PATH,HW_VENDOR_DP,sizeof(VENDOR_DEVICE_PATH));
+  CopyGuid(&((VENDOR_DEVICE_PATH*)NewDevicePathNode)->Guid,&mPL180MciDevicePathGuid);
+  *DevicePath = NewDevicePathNode;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+MMCSendCommand (
+  IN EFI_MMC_HOST_PROTOCOL     *This,
+  IN MMC_CMD                   MmcCmd,
+  IN UINT32                    Argument
+  )
+{
+  UINTN MmcStatus;
+  UINTN RetryCount = 0;
+
+  if (IgnoreCommand(MmcCmd))
+    return EFI_SUCCESS;
+
+  MmcCmd = TranslateCommand(MmcCmd);
+
+  //DEBUG ((EFI_D_ERROR, "MMCSendCommand(%d)\n", MmcCmd));
+
+  // Check if command line is in use or not. Poll till command line is available.
+  while ((MmioRead32 (MMCHS_PSTATE) & DATI_MASK) == DATI_NOT_ALLOWED);
+
+  // Provide the block size.
+  MmioWrite32 (MMCHS_BLK, BLEN_512BYTES);
+
+  // Setting Data timeout counter value to max value.
+  MmioAndThenOr32 (MMCHS_SYSCTL, ~DTO_MASK, DTO_VAL);
+
+  // Clear Status register.
+  MmioWrite32 (MMCHS_STAT, 0xFFFFFFFF);
+
+  // Set command argument register
+  MmioWrite32 (MMCHS_ARG, Argument);
+
+  //TODO: fix this
+  //Enable interrupt enable events to occur
+  //MmioWrite32 (MMCHS_IE, CmdInterruptEnableVal);
+
+  // Send a command
+  MmioWrite32 (MMCHS_CMD, MmcCmd);
+
+  // Check for the command status.
+  while (RetryCount < MAX_RETRY_COUNT) {
+    do {
+      MmcStatus = MmioRead32 (MMCHS_STAT);
+    } while (MmcStatus == 0);
+
+    // Read status of command response
+    if ((MmcStatus & ERRI) != 0) {
+
+      // Perform soft-reset for mmci_cmd line.
+      MmioOr32 (MMCHS_SYSCTL, SRC);
+      while ((MmioRead32 (MMCHS_SYSCTL) & SRC));
+
+      //DEBUG ((EFI_D_INFO, "MmcStatus: 0x%x\n", MmcStatus));
+      return EFI_DEVICE_ERROR;
+    }
+
+    // Check if command is completed.
+    if ((MmcStatus & CC) == CC) {
+      MmioWrite32 (MMCHS_STAT, CC);
+      break;
+    }
+
+    RetryCount++;
+  }
+
+  if (RetryCount == MAX_RETRY_COUNT) {
+    DEBUG ((DEBUG_BLKIO, "MMCSendCommand: Timeout\n"));
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+MMCNotifyState (
+  IN EFI_MMC_HOST_PROTOCOL    *This,
+  IN MMC_STATE                State
+  )
+{
+  EFI_STATUS              Status;
+  UINTN                   FreqSel;
+
+  switch(State) {
+    case MmcInvalidState:
+      ASSERT(0);
+      break;
+    case MmcHwInitializationState:
+      mBitModeSet = FALSE;
+
+      DEBUG ((DEBUG_BLKIO, "MMCHwInitializationState()\n"));
+      Status = InitializeMMCHS ();
+      if (EFI_ERROR(Status)) {
+        DEBUG ((DEBUG_BLKIO, "Initialize MMC host controller fails. Status: %x\n", Status));
+        return Status;
+      }
+
+      // Software reset of the MMCHS host controller.
+      MmioWrite32 (MMCHS_SYSCONFIG, SOFTRESET);
+      gBS->Stall(1000);
+      while ((MmioRead32 (MMCHS_SYSSTATUS) & RESETDONE_MASK) != RESETDONE);
+
+      // Soft reset for all.
+      MmioWrite32 (MMCHS_SYSCTL, SRA);
+      gBS->Stall(1000);
+      while ((MmioRead32 (MMCHS_SYSCTL) & SRA) != 0x0);
+
+      //Voltage capabilities initialization. Activate VS18 and VS30.
+      MmioOr32 (MMCHS_CAPA, (VS30 | VS18));
+
+      // Wakeup configuration
+      MmioOr32 (MMCHS_SYSCONFIG, ENAWAKEUP);
+      MmioOr32 (MMCHS_HCTL, IWE);
+
+      // MMCHS Controller default initialization
+      MmioOr32 (MMCHS_CON, (OD | DW8_1_4_BIT | CEATA_OFF));
+
+      MmioWrite32 (MMCHS_HCTL, (SDVS_3_0_V | DTW_1_BIT | SDBP_OFF));
+
+      // Enable internal clock
+      MmioOr32 (MMCHS_SYSCTL, ICE);
+
+      // Set the clock frequency to 80KHz.
+      UpdateMMCHSClkFrequency (CLKD_80KHZ);
+
+      // Enable SD bus power.
+      MmioOr32 (MMCHS_HCTL, (SDBP_ON));
+
+      // Poll till SD bus power bit is set.
+      while ((MmioRead32 (MMCHS_HCTL) & SDBP_MASK) != SDBP_ON);
+
+      // Enable interrupts.
+      MmioWrite32 (MMCHS_IE, (BADA_EN | CERR_EN | DEB_EN | DCRC_EN | DTO_EN | CIE_EN |
+        CEB_EN | CCRC_EN | CTO_EN | BRR_EN | BWR_EN | TC_EN | CC_EN));
+
+      // Controller INIT procedure start.
+      MmioOr32 (MMCHS_CON, INIT);
+      MmioWrite32 (MMCHS_CMD, 0x00000000);
+      while (!(MmioRead32 (MMCHS_STAT) & CC));
+
+      // Wait for 1 ms
+      gBS->Stall (1000);
+
+      // Set CC bit to 0x1 to clear the flag
+      MmioOr32 (MMCHS_STAT, CC);
+
+      // Retry INIT procedure.
+      MmioWrite32 (MMCHS_CMD, 0x00000000);
+      while (!(MmioRead32 (MMCHS_STAT) & CC));
+
+      // End initialization sequence
+      MmioAnd32 (MMCHS_CON, ~INIT);
+
+      MmioOr32 (MMCHS_HCTL, (SDVS_3_0_V | DTW_1_BIT | SDBP_ON));
+
+      // Change clock frequency to 400KHz to fit protocol
+      UpdateMMCHSClkFrequency(CLKD_400KHZ);
+
+      MmioOr32 (MMCHS_CON, OD);
+      break;
+    case MmcIdleState:
+      break;
+    case MmcReadyState:
+      break;
+    case MmcIdentificationState:
+      break;
+    case MmcStandByState:
+      CalculateCardCLKD (&FreqSel);
+      UpdateMMCHSClkFrequency (FreqSel);
+      break;
+    case MmcTransferState:
+      if (!mBitModeSet) {
+        Status = MMCSendCommand (This, CMD55, mRca << 16);
+        if (!EFI_ERROR (Status)) {
+          // Set device into 4-bit data bus mode
+          Status = MMCSendCommand (This, ACMD6, 0x2);
+          if (!EFI_ERROR (Status)) {
+            // Set host controler into 4-bit mode
+            MmioOr32 (MMCHS_HCTL, DTW_4_BIT);
+            DEBUG ((DEBUG_BLKIO, "SD Memory Card set to 4-bit mode\n"));
+            mBitModeSet = TRUE;
+          }
+        }
+      }
+      break;
+    case MmcSendingDataState:
+      break;
+    case MmcReceiveDataState:
+      break;
+    case MmcProgrammingState:
+      break;
+    case MmcDisconnectState:
+    default:
+      ASSERT(0);
+  }
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+MMCReceiveResponse (
+  IN EFI_MMC_HOST_PROTOCOL     *This,
+  IN MMC_RESPONSE_TYPE         Type,
+  IN UINT32*                   Buffer
+  )
+{
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Type == MMC_RESPONSE_TYPE_R2) {
+    Buffer[0] = MmioRead32 (MMCHS_RSP10);
+    Buffer[1] = MmioRead32 (MMCHS_RSP32);
+    Buffer[2] = MmioRead32 (MMCHS_RSP54);
+    Buffer[3] = MmioRead32 (MMCHS_RSP76);
+  } else {
+    Buffer[0] = MmioRead32 (MMCHS_RSP10);
+  }
+
+  if (Type == MMC_RESPONSE_TYPE_CSD) {
+    mMaxDataTransferRate = Buffer[3] & 0xFF;
+  } else if (Type == MMC_RESPONSE_TYPE_RCA) {
+    mRca = Buffer[0] >> 16;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+MMCReadBlockData (
+  IN EFI_MMC_HOST_PROTOCOL      *This,
+  IN EFI_LBA                    Lba,
+  IN UINTN                      Length,
+  IN UINT32*                    Buffer
+  )
+{
+  UINTN MmcStatus;
+  UINTN Count;
+  UINTN RetryCount = 0;
+
+  DEBUG ((DEBUG_BLKIO, "MMCReadBlockData(LBA: 0x%x, Length: 0x%x, Buffer: 0x%x)\n", Lba, Length, Buffer));
+
+  // Check controller status to make sure there is no error.
+  while (RetryCount < MAX_RETRY_COUNT) {
+    do {
+      // Read Status.
+      MmcStatus = MmioRead32 (MMCHS_STAT);
+    } while(MmcStatus == 0);
+
+    // Check if Buffer read ready (BRR) bit is set?
+    if (MmcStatus & BRR) {
+
+      // Clear BRR bit
+      MmioOr32 (MMCHS_STAT, BRR);
+
+      for (Count = 0; Count < Length / 4; Count++) {
+        *Buffer++ = MmioRead32(MMCHS_DATA);
+      }
+      break;
+    }
+    RetryCount++;
+  }
+
+  if (RetryCount == MAX_RETRY_COUNT) {
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+MMCWriteBlockData (
+  IN EFI_MMC_HOST_PROTOCOL    *This,
+  IN EFI_LBA                  Lba,
+  IN UINTN                    Length,
+  IN UINT32*                  Buffer
+  )
+{
+  UINTN MmcStatus;
+  UINTN Count;
+  UINTN RetryCount = 0;
+
+  // Check controller status to make sure there is no error.
+  while (RetryCount < MAX_RETRY_COUNT) {
+    do {
+      // Read Status.
+      MmcStatus = MmioRead32 (MMCHS_STAT);
+    } while(MmcStatus == 0);
+
+    // Check if Buffer write ready (BWR) bit is set?
+    if (MmcStatus & BWR) {
+
+      // Clear BWR bit
+      MmioOr32 (MMCHS_STAT, BWR);
+
+      // Write block worth of data.
+      for (Count = 0; Count < Length / 4; Count++) {
+        MmioWrite32 (MMCHS_DATA, *Buffer++);
+      }
+
+      break;
+    }
+    RetryCount++;
+  }
+
+  if (RetryCount == MAX_RETRY_COUNT) {
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_MMC_HOST_PROTOCOL gMMCHost = {
+  MMC_HOST_PROTOCOL_REVISION,
+  MMCIsCardPresent,
+  MMCIsReadOnly,
+  MMCBuildDevicePath,
+  MMCNotifyState,
+  MMCSendCommand,
+  MMCReceiveResponse,
+  MMCReadBlockData,
+  MMCWriteBlockData
+};
+
+EFI_STATUS
+MMCInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS    Status;
+  EFI_HANDLE    Handle = NULL;
+
+  DEBUG ((DEBUG_BLKIO, "MMCInitialize()\n"));
+
+  Status = gBS->LocateProtocol (&gEmbeddedExternalDeviceProtocolGuid, NULL, (VOID **)&gTPS65950);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Handle,
+                  &gEfiMmcHostProtocolGuid,         &gMMCHost,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.h b/Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.h
new file mode 100644
index 0000000000..7c043ae726
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.h
@@ -0,0 +1,38 @@
+/** @file
+*
+*  Copyright (c) 2011, ARM Limited. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#ifndef _MMC_HOST_DXE_H_
+#define _MMC_HOST_DXE_H_
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/OmapLib.h>
+#include <Library/OmapDmaLib.h>
+#include <Library/DmaLib.h>
+
+#include <Protocol/EmbeddedExternalDevice.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/MmcHost.h>
+
+#include <Omap3530/Omap3530.h>
+#include <TPS65950.h>
+
+#define MAX_RETRY_COUNT  (100*5)
+
+extern EFI_BLOCK_IO_PROTOCOL gBlockIo;
+
+#endif
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf b/Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf
new file mode 100644
index 0000000000..88407211a5
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf
@@ -0,0 +1,47 @@
+#  Copyright (c) 2011, ARM Limited. All rights reserved.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = MMC
+  FILE_GUID                      = 100c2cfa-b586-4198-9b4c-1683d195b1da
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = MMCInitialize
+
+
+[Sources.common]
+  MmcHostDxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  UefiLib
+  UefiDriverEntryPoint
+  MemoryAllocationLib
+  IoLib
+  OmapDmaLib
+  DmaLib
+
+[Guids]
+
+[Protocols]
+  gEfiBlockIoProtocolGuid
+  gEfiCpuArchProtocolGuid
+  gEfiDevicePathProtocolGuid
+  gEmbeddedExternalDeviceProtocolGuid
+  gEfiMmcHostProtocolGuid
+
+[Pcd]
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxMMCHS1Base
+  gOmap35xxTokenSpaceGuid.PcdMmchsTimerFreq100NanoSeconds
+
+[depex]
+  gEmbeddedExternalDeviceProtocolGuid
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dec b/Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dec
new file mode 100644
index 0000000000..3415e1c087
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dec
@@ -0,0 +1,52 @@
+#/** @file
+# Omap35xx SoC package.
+#
+# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
+#
+#    SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  DEC_SPECIFICATION              = 0x00010005
+  PACKAGE_NAME                   = Omap35xxPkg
+  PACKAGE_GUID                   = D196A631-B7B7-4953-A3EE-0F773CBABF20
+  PACKAGE_VERSION                = 0.1
+
+################################################################################
+#
+# Include Section - list of Include Paths that are provided by this package.
+#                   Comments are used for Keywords and Module Types.
+#
+# Supported Module Types:
+#  BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
+#
+################################################################################
+[Includes.common]
+  Include                        # Root include for the package
+
+[LibraryClasses]
+  ##  @libraryclass  Abstract location of basic OMAP components
+  ##
+  OmapLib|Include/Library/OmapLib.h
+
+  ##  @libraryclass  Abstract OMAP and ARM DMA, modeled after PCI IO protocol
+  ##
+  OmapDmaLib|Include/Library/OmapDmaLib.h
+
+
+[Guids.common]
+  gOmap35xxTokenSpaceGuid    =  { 0x24b09abe, 0x4e47, 0x481c, { 0xa9, 0xad, 0xce, 0xf1, 0x2c, 0x39, 0x23, 0x27} }
+
+[PcdsFeatureFlag.common]
+
+[PcdsFixedAtBuild.common]
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxConsoleUart|3|UINT32|0x00000202
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxGpmcOffset|0x00000000|UINT32|0x00000203
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxMMCHS1Base|0x00000000|UINT32|0x00000204
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxArchTimer|3|UINT32|0x00000205
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxFreeTimer|4|UINT32|0x00000206
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxDebugAgentTimer|5|UINT32|0x00000207
+  gOmap35xxTokenSpaceGuid.PcdDebugAgentTimerFreqNanoSeconds|77|UINT32|0x00000208
+  gOmap35xxTokenSpaceGuid.PcdMmchsTimerFreq100NanoSeconds|1000000|UINT32|0x00000209
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dsc b/Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dsc
new file mode 100644
index 0000000000..1ad991a8ab
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dsc
@@ -0,0 +1,183 @@
+#/** @file
+# Omap35xx SoC package.
+#
+# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
+# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
+#
+#    SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  PLATFORM_NAME                  = Omap35xxPkg
+  PLATFORM_GUID                  = D196A631-B7B7-4953-A3EE-0F773CBABF20
+  PLATFORM_VERSION               = 0.1
+  DSC_SPECIFICATION              = 0x00010005
+  OUTPUT_DIRECTORY               = Build/Omap35xxPkg
+  SUPPORTED_ARCHITECTURES        = ARM
+  BUILD_TARGETS                  = DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+  DEFINE TARGET_HACK             = DEBUG
+
+
+[LibraryClasses.common]
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+
+  ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+
+  CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
+  DefaultExceptioHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
+  PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
+
+  RealTimeClockLib|EmbeddedPkg/Library/TemplateRealTimeClockLib/TemplateRealTimeClockLib.inf
+
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+  OmapLib|Omap35xxPkg/Library/OmapLib/OmapLib.inf
+  OmapDmaLib|Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.inf
+
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+
+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+  DmaLib|EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.inf
+
+  TimerLib|Omap35xxPkg/Library/Omap35xxTimerLib/Omap35xxTimerLib.inf
+
+#
+# Assume everything is fixed at build
+#
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+
+
+[LibraryClasses.common.DXE_DRIVER]
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  NonDiscoverableDeviceRegistrationLib|MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.inf
+
+[LibraryClasses.ARM]
+  NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+  NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
+
+[BuildOptions]
+  XCODE:*_*_ARM_ARCHCC_FLAGS     == -arch armv7 -march=armv7
+  XCODE:*_*_ARM_ARCHASM_FLAGS    == -arch armv7
+  XCODE:*_*_ARM_ARCHDLINK_FLAGS  == -arch armv7
+
+  GCC:*_*_ARM_ARCHCC_FLAGS     == -march=armv7-a -mthumb
+  GCC:*_*_ARM_ARCHASM_FLAGS    == -march=armv7-a
+
+  RVCT:*_*_ARM_ARCHCC_FLAGS     == --cpu 7-A
+  RVCT:*_*_ARM_ARCHASM_FLAGS    == --cpu 7-A
+
+  *_*_*_CC_FLAGS = -DDISABLE_NEW_DEPRECATED_INTERFACES
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+
+[PcdsFixedAtBuild.common]
+
+# DEBUG_ASSERT_ENABLED       0x01
+# DEBUG_PRINT_ENABLED        0x02
+# DEBUG_CODE_ENABLED         0x04
+# CLEAR_MEMORY_ENABLED       0x08
+# ASSERT_BREAKPOINT_ENABLED  0x10
+# ASSERT_DEADLOOP_ENABLED    0x20
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2f
+
+#  DEBUG_INIT      0x00000001  // Initialization
+#  DEBUG_WARN      0x00000002  // Warnings
+#  DEBUG_LOAD      0x00000004  // Load events
+#  DEBUG_FS        0x00000008  // EFI File system
+#  DEBUG_POOL      0x00000010  // Alloc & Free (pool)
+#  DEBUG_PAGE      0x00000020  // Alloc & Free (page)
+#  DEBUG_INFO      0x00000040  // Informational debug messages
+#  DEBUG_DISPATCH  0x00000080  // PEI/DXE/SMM Dispatchers
+#  DEBUG_VARIABLE  0x00000100  // Variable
+#  DEBUG_BM        0x00000400  // Boot Manager
+#  DEBUG_BLKIO     0x00001000  // BlkIo Driver
+#  DEBUG_NET       0x00004000  // SNP Driver
+#  DEBUG_UNDI      0x00010000  // UNDI Driver
+#  DEBUG_LOADFILE  0x00020000  // LoadFile
+#  DEBUG_EVENT     0x00080000  // Event messages
+#  DEBUG_GCD       0x00100000  // Global Coherency Database changes
+#  DEBUG_CACHE     0x00200000  // Memory range cachability changes
+#  DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may
+#                              // significantly impact boot performance
+#  DEBUG_ERROR     0x80000000  // Error
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000004
+
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+
+  gEmbeddedTokenSpaceGuid.PcdFlashFvMainBase|0
+  gEmbeddedTokenSpaceGuid.PcdFlashFvMainSize|0
+  gEmbeddedTokenSpaceGuid.PcdPrePiStackBase|0x87FE0000 # stack at top of memory
+  gEmbeddedTokenSpaceGuid.PcdPrePiStackSize|0x20000  # 128K stack
+  gArmTokenSpaceGuid.PcdCpuVectorBaseAddress|0x80000000
+  gArmTokenSpaceGuid.PcdCpuResetAddress|0x80008000
+
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxGpmcOffset|0x6E000000
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxMMCHS1Base|0x4809C000
+
+  # Console
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxConsoleUart|3
+
+  # Timers
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxArchTimer|3
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxFreeTimer|4
+  gEmbeddedTokenSpaceGuid.PcdTimerPeriod|100000
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedPerformanceCounterPeriodInNanoseconds|77
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedPerformanceCounterFrequencyInHz|13000000
+
+  # OMAP Interrupt Controller
+  gEmbeddedTokenSpaceGuid.PcdInterruptBaseAddress|0x48200000
+
+################################################################################
+#
+# Components Section - list of all EDK II Modules needed by this Platform
+#
+################################################################################
+[Components.common]
+  Omap35xxPkg/Library/Omap35xxTimerLib/Omap35xxTimerLib.inf
+  Omap35xxPkg/Library/OmapLib/OmapLib.inf
+  Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.inf
+
+  Omap35xxPkg/Flash/Flash.inf
+  Omap35xxPkg/MMCHSDxe/MMCHS.inf
+  Omap35xxPkg/SmbusDxe/Smbus.inf
+  Omap35xxPkg/Gpio/Gpio.inf
+  Omap35xxPkg/InterruptDxe/InterruptDxe.inf
+  Omap35xxPkg/TimerDxe/TimerDxe.inf
+  Omap35xxPkg/TPS65950Dxe/TPS65950.inf
+
+  Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.inf
+  Omap35xxPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf
+  Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.inf
+  Omap35xxPkg/Library/RealTimeClockLib/RealTimeClockLib.inf
+  Omap35xxPkg/Library/SerialPortLib/SerialPortLib.inf
+  Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf
+  Omap35xxPkg/PciEmulation/PciEmulation.inf
+
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.c b/Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.c
new file mode 100644
index 0000000000..a05d98183a
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.c
@@ -0,0 +1,107 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+  Copyright (c) 2016, Linaro, Ltd. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/NonDiscoverableDeviceRegistrationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/EmbeddedExternalDevice.h>
+
+#include <TPS65950.h>
+#include <Omap3530/Omap3530.h>
+
+EMBEDDED_EXTERNAL_DEVICE   *gTPS65950;
+
+#define HOST_CONTROLLER_OPERATION_REG_SIZE  0x44
+
+STATIC
+EFI_STATUS
+ConfigureUSBHost (
+  NON_DISCOVERABLE_DEVICE   *Device
+  )
+{
+  EFI_STATUS Status;
+  UINT8      Data = 0;
+
+  // Take USB host out of force-standby mode
+  MmioWrite32 (UHH_SYSCONFIG, UHH_SYSCONFIG_MIDLEMODE_NO_STANDBY
+                            | UHH_SYSCONFIG_CLOCKACTIVITY_ON
+                            | UHH_SYSCONFIG_SIDLEMODE_NO_STANDBY
+                            | UHH_SYSCONFIG_ENAWAKEUP_ENABLE
+                            | UHH_SYSCONFIG_AUTOIDLE_ALWAYS_RUN);
+  MmioWrite32 (UHH_HOSTCONFIG, UHH_HOSTCONFIG_P3_CONNECT_STATUS_DISCONNECT
+                             | UHH_HOSTCONFIG_P2_CONNECT_STATUS_DISCONNECT
+                             | UHH_HOSTCONFIG_P1_CONNECT_STATUS_DISCONNECT
+                             | UHH_HOSTCONFIG_ENA_INCR_ALIGN_DISABLE
+                             | UHH_HOSTCONFIG_ENA_INCR16_ENABLE
+                             | UHH_HOSTCONFIG_ENA_INCR8_ENABLE
+                             | UHH_HOSTCONFIG_ENA_INCR4_ENABLE
+                             | UHH_HOSTCONFIG_AUTOPPD_ON_OVERCUR_EN_ON
+                             | UHH_HOSTCONFIG_P1_ULPI_BYPASS_ULPI_MODE);
+
+  // USB reset (GPIO 147 - Port 5 pin 19) output high
+  MmioAnd32 (GPIO5_BASE + GPIO_OE, ~BIT19);
+  MmioWrite32 (GPIO5_BASE + GPIO_SETDATAOUT, BIT19);
+
+  // Get the Power IC protocol
+  Status = gBS->LocateProtocol (&gEmbeddedExternalDeviceProtocolGuid, NULL, (VOID **)&gTPS65950);
+  ASSERT_EFI_ERROR (Status);
+
+  // Power the USB PHY
+  Data = VAUX_DEV_GRP_P1;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VAUX2_DEV_GRP), 1, &Data);
+  ASSERT_EFI_ERROR(Status);
+
+  Data = VAUX_DEDICATED_18V;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VAUX2_DEDICATED), 1, &Data);
+  ASSERT_EFI_ERROR (Status);
+
+  // Enable power to the USB hub
+  Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID3, LEDEN), 1, &Data);
+  ASSERT_EFI_ERROR (Status);
+
+  // LEDAON controls the power to the USB host, PWM is disabled
+  Data &= ~LEDAPWM;
+  Data |= LEDAON;
+
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID3, LEDEN), 1, &Data);
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PciEmulationEntryPoint (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  UINT8                   CapabilityLength;
+  UINT8                   PhysicalPorts;
+  UINTN                   MemorySize;
+
+  CapabilityLength = MmioRead8 (USB_EHCI_HCCAPBASE);
+  PhysicalPorts    = MmioRead32 (USB_EHCI_HCCAPBASE + 0x4) & 0x0000000F;
+  MemorySize       = CapabilityLength + HOST_CONTROLLER_OPERATION_REG_SIZE +
+                     4 * PhysicalPorts - 1;
+
+  return RegisterNonDiscoverableMmioDevice (
+           NonDiscoverableDeviceTypeEhci,
+           NonDiscoverableDeviceDmaTypeNonCoherent,
+           ConfigureUSBHost,
+           NULL,
+           1,
+           USB_EHCI_HCCAPBASE, MemorySize
+           );
+}
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.inf b/Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.inf
new file mode 100644
index 0000000000..2e8e258985
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.inf
@@ -0,0 +1,41 @@
+/** @file
+
+  Copyright (c) 2009, Apple Inc. All rights reserved.<BR>
+  Copyright (c) 2016, Linaro, Ltd. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+[Defines]
+  INF_VERSION                     = 0x00010005
+  BASE_NAME                       = BeagleBoardPciEmulation
+  FILE_GUID                       = feaa2e2b-53ac-4d5e-ae10-1efd5da4a2ba
+  MODULE_TYPE                     = DXE_DRIVER
+  VERSION_STRING                  = 1.0
+
+  ENTRY_POINT                     = PciEmulationEntryPoint
+
+[Sources.common]
+  PciEmulation.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  IoLib
+  NonDiscoverableDeviceRegistrationLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+
+[Protocols]
+  gEmbeddedExternalDeviceProtocolGuid
+
+[Depex]
+  gEfiMetronomeArchProtocolGuid AND
+  gEmbeddedExternalDeviceProtocolGuid
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.c b/Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.c
new file mode 100644
index 0000000000..894ba3313c
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.c
@@ -0,0 +1,319 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Omap3530/Omap3530.h>
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/SmbusHc.h>
+
+#define MAX_RETRY  1000
+
+//
+// Internal Functions
+//
+STATIC
+EFI_STATUS
+WaitForBusBusy (
+  VOID
+  )
+{
+  UINTN Retry = 0;
+
+  while (++Retry < MAX_RETRY && (MmioRead16(I2C_STAT) & BB) == 0x1);
+
+  if (Retry == MAX_RETRY) {
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+PollForStatus(
+  UINT16 StatusBit
+  )
+{
+  UINTN Retry = 0;
+
+  while(Retry < MAX_RETRY) {
+    if (MmioRead16(I2C_STAT) & StatusBit) {
+      //Clear particular status bit from Status register.
+      MmioOr16(I2C_STAT, StatusBit);
+      break;
+    }
+    Retry++;
+  }
+
+  if (Retry == MAX_RETRY) {
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+ConfigureI2c (
+  VOID
+  )
+{
+  //Program prescaler to obtain 12-MHz clock
+  MmioWrite16(I2C_PSC, 0x0000);
+
+  //Program SCLL and SCLH
+  //NOTE: Following values are the register dump after U-Boot code executed.
+  //We need to figure out how its calculated based on the I2C functional clock and I2C_PSC.
+  MmioWrite16(I2C_SCLL, 0x0035);
+  MmioWrite16(I2C_SCLH, 0x0035);
+
+  //Take the I2C controller out of reset.
+  MmioOr16(I2C_CON, I2C_EN);
+
+  //Initialize the I2C controller.
+
+  //Set I2C controller in Master mode.
+  MmioOr16(I2C_CON, MST);
+
+  //Enable interrupts for receive/transmit mode.
+  MmioOr16(I2C_IE, (XRDY_IE | RRDY_IE | ARDY_IE | NACK_IE));
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+I2CReadOneByte (
+  UINT8 *Data
+  )
+{
+  EFI_STATUS Status;
+
+  //I2C bus status checking
+  Status = WaitForBusBusy();
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  //Poll till Receive ready bit is set.
+  Status = PollForStatus(RRDY);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  *Data = MmioRead8(I2C_DATA);
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+I2CWriteOneByte (
+  UINT8 Data
+  )
+{
+  EFI_STATUS Status;
+
+  //I2C bus status checking
+  Status = WaitForBusBusy();
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  //Data transfer
+  //Poll till Transmit ready bit is set
+  Status = PollForStatus(XRDY);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  MmioWrite8(I2C_DATA, Data);
+
+  //Wait and check if the NACK is not set.
+  gBS->Stall(1000);
+  if (MmioRead16(I2C_STAT) & NACK) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+SmbusBlockRead (
+  OUT UINT8       *Buffer,
+  IN  UINTN       Length
+  )
+{
+  UINTN      Index = 0;
+  EFI_STATUS Status = EFI_SUCCESS;
+
+  //Transfer configuration for receiving data.
+  MmioWrite16(I2C_CNT, Length);
+  //Need stop bit before sending data.
+  MmioWrite16(I2C_CON, (I2C_EN | MST | STP | STT));
+
+  while (Index < Length) {
+    //Read a byte
+    Status = I2CReadOneByte(&Buffer[Index++]);
+    if (EFI_ERROR(Status)) {
+      return Status;
+    }
+  }
+
+  //Transfer completion
+  Status = PollForStatus(ARDY);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+SmbusBlockWrite (
+  IN UINT8       *Buffer,
+  IN UINTN       Length
+  )
+{
+  UINTN      Index = 0;
+  EFI_STATUS Status = EFI_SUCCESS;
+
+  //Transfer configuration for transmitting data
+  MmioWrite16(I2C_CNT, Length);
+  MmioWrite16(I2C_CON, (I2C_EN | TRX | MST | STT | STP));
+
+  while (Index < Length) {
+    //Send a byte
+    Status = I2CWriteOneByte(Buffer[Index++]);
+    if (EFI_ERROR(Status)) {
+      return Status;
+    }
+  }
+
+  //Transfer completion
+  Status = PollForStatus(ARDY);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  return Status;
+}
+
+//
+// Public Functions.
+//
+EFI_STATUS
+EFIAPI
+SmbusExecute (
+  IN CONST EFI_SMBUS_HC_PROTOCOL    *This,
+  IN CONST EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+  IN CONST EFI_SMBUS_DEVICE_COMMAND Command,
+  IN CONST EFI_SMBUS_OPERATION      Operation,
+  IN CONST BOOLEAN                  PecCheck,
+  IN OUT   UINTN                    *Length,
+  IN OUT   VOID                     *Buffer
+  )
+{
+  UINT8      *ByteBuffer  = Buffer;
+  EFI_STATUS Status       = EFI_SUCCESS;
+  UINT8      SlaveAddr    = (UINT8)(SlaveAddress.SmbusDeviceAddress);
+
+  if (PecCheck) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if ((Operation != EfiSmbusWriteBlock) && (Operation != EfiSmbusReadBlock)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //Set the Slave address.
+  MmioWrite16(I2C_SA, SlaveAddr);
+
+  if (Operation == EfiSmbusReadBlock) {
+    Status = SmbusBlockRead(ByteBuffer, *Length);
+  } else if (Operation == EfiSmbusWriteBlock) {
+    Status = SmbusBlockWrite(ByteBuffer, *Length);
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+SmbusArpDevice (
+  IN CONST EFI_SMBUS_HC_PROTOCOL    *This,
+  IN       BOOLEAN                  ArpAll,
+  IN       EFI_SMBUS_UDID           *SmbusUdid OPTIONAL,
+  IN OUT   EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+
+EFI_STATUS
+EFIAPI
+SmbusGetArpMap (
+  IN CONST EFI_SMBUS_HC_PROTOCOL    *This,
+  IN OUT   UINTN                    *Length,
+  IN OUT   EFI_SMBUS_DEVICE_MAP     **SmbusDeviceMap
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+
+EFI_STATUS
+EFIAPI
+SmbusNotify (
+  IN CONST  EFI_SMBUS_HC_PROTOCOL     *This,
+  IN CONST  EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress,
+  IN CONST  UINTN                     Data,
+  IN CONST  EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+EFI_SMBUS_HC_PROTOCOL SmbusProtocol =
+{
+  SmbusExecute,
+  SmbusArpDevice,
+  SmbusGetArpMap,
+  SmbusNotify
+};
+
+EFI_STATUS
+InitializeSmbus (
+    IN EFI_HANDLE       ImageHandle,
+    IN EFI_SYSTEM_TABLE *SystemTable
+    )
+{
+  EFI_HANDLE      Handle = NULL;
+  EFI_STATUS      Status;
+
+  //Configure I2C controller.
+  Status = ConfigureI2c();
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "InitializeI2c fails.\n"));
+    return Status;
+  }
+
+  // Install the SMBUS interface
+  Status = gBS->InstallMultipleProtocolInterfaces(&Handle, &gEfiSmbusHcProtocolGuid, &SmbusProtocol, NULL);
+  ASSERT_EFI_ERROR(Status);
+
+  return Status;
+}
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.inf b/Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.inf
new file mode 100644
index 0000000000..0a3f4240ba
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.inf
@@ -0,0 +1,39 @@
+#/** @file
+#
+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = Smbus
+  FILE_GUID                      = d5125e0f-1226-444f-a218-0085996ed5da
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = InitializeSmbus
+
+[Sources.common]
+  Smbus.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  UefiLib
+  UefiDriverEntryPoint
+  MemoryAllocationLib
+  IoLib
+
+[Guids]
+
+[Protocols]
+  gEfiSmbusHcProtocolGuid
+
+[Pcd]
+
+[depex]
+  TRUE
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.c b/Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.c
new file mode 100644
index 0000000000..a5107dcc15
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.c
@@ -0,0 +1,110 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <TPS65950.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/EmbeddedExternalDevice.h>
+#include <Protocol/SmbusHc.h>
+
+EFI_SMBUS_HC_PROTOCOL *Smbus;
+
+EFI_STATUS
+Read (
+  IN  EMBEDDED_EXTERNAL_DEVICE    *This,
+  IN  UINTN                       Register,
+  IN  UINTN                       Length,
+  OUT VOID                        *Buffer
+  )
+{
+  EFI_STATUS               Status;
+  EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+  UINT8                    DeviceRegister;
+  UINTN                    DeviceRegisterLength = 1;
+
+  SlaveAddress.SmbusDeviceAddress = EXTERNAL_DEVICE_REGISTER_TO_SLAVE_ADDRESS(Register);
+  DeviceRegister = (UINT8)EXTERNAL_DEVICE_REGISTER_TO_REGISTER(Register);
+
+  //Write DeviceRegister.
+  Status = Smbus->Execute(Smbus, SlaveAddress, 0, EfiSmbusWriteBlock, FALSE, &DeviceRegisterLength, &DeviceRegister);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  //Read Data
+  Status = Smbus->Execute(Smbus, SlaveAddress, 0, EfiSmbusReadBlock, FALSE, &Length, Buffer);
+  return Status;
+}
+
+EFI_STATUS
+Write (
+  IN EMBEDDED_EXTERNAL_DEVICE   *This,
+  IN UINTN                      Register,
+  IN UINTN                      Length,
+  IN VOID                       *Buffer
+  )
+{
+  EFI_STATUS               Status;
+  EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+  UINT8                    DeviceRegister;
+  UINTN                    DeviceBufferLength = Length + 1;
+  UINT8                    *DeviceBuffer;
+
+  SlaveAddress.SmbusDeviceAddress = EXTERNAL_DEVICE_REGISTER_TO_SLAVE_ADDRESS(Register);
+  DeviceRegister = (UINT8)EXTERNAL_DEVICE_REGISTER_TO_REGISTER(Register);
+
+  //Prepare buffer for writing
+  DeviceBuffer = (UINT8 *)AllocatePool(DeviceBufferLength);
+  if (DeviceBuffer == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto exit;
+  }
+
+  //Set Device register followed by data to write.
+  DeviceBuffer[0] = DeviceRegister;
+  CopyMem(&DeviceBuffer[1], Buffer, Length);
+
+  //Write Data
+  Status = Smbus->Execute(Smbus, SlaveAddress, 0, EfiSmbusWriteBlock, FALSE, &DeviceBufferLength, DeviceBuffer);
+  if (EFI_ERROR(Status)) {
+    goto exit;
+  }
+
+exit:
+  if (DeviceBuffer) {
+    FreePool(DeviceBuffer);
+  }
+
+  return Status;
+}
+
+EMBEDDED_EXTERNAL_DEVICE ExternalDevice = {
+  Read,
+  Write
+};
+
+EFI_STATUS
+TPS65950Initialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = gBS->LocateProtocol(&gEfiSmbusHcProtocolGuid, NULL, (VOID **)&Smbus);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = gBS->InstallMultipleProtocolInterfaces(&ImageHandle, &gEmbeddedExternalDeviceProtocolGuid, &ExternalDevice, NULL);
+  return Status;
+}
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.inf b/Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.inf
new file mode 100644
index 0000000000..e37d0a0f52
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.inf
@@ -0,0 +1,42 @@
+#/** @file
+#
+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = TPS65950
+  FILE_GUID                      = 71fe861a-5450-48b6-bfb0-b93522616f99
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = TPS65950Initialize
+
+
+[Sources.common]
+  TPS65950.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  PcdLib
+  UefiLib
+  UefiDriverEntryPoint
+  MemoryAllocationLib
+
+[Guids]
+
+[Protocols]
+  gEfiSmbusHcProtocolGuid
+  gEmbeddedExternalDeviceProtocolGuid
+
+[Pcd]
+
+[depex]
+  gEfiSmbusHcProtocolGuid
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/Timer.c b/Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/Timer.c
new file mode 100644
index 0000000000..da7cd9f6b7
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/Timer.c
@@ -0,0 +1,370 @@
+/** @file
+  Template for Timer Architecture Protocol driver of the ARM flavor
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/OmapLib.h>
+
+#include <Protocol/Timer.h>
+#include <Protocol/HardwareInterrupt.h>
+
+#include <Omap3530/Omap3530.h>
+
+
+// The notification function to call on every timer interrupt.
+volatile EFI_TIMER_NOTIFY      mTimerNotifyFunction   = (EFI_TIMER_NOTIFY)NULL;
+
+
+// The current period of the timer interrupt
+volatile UINT64 mTimerPeriod = 0;
+
+// Cached copy of the Hardware Interrupt protocol instance
+EFI_HARDWARE_INTERRUPT_PROTOCOL *gInterrupt = NULL;
+
+// Cached registers
+volatile UINT32 TISR;
+volatile UINT32 TCLR;
+volatile UINT32 TLDR;
+volatile UINT32 TCRR;
+volatile UINT32 TIER;
+
+// Cached interrupt vector
+volatile UINTN  gVector;
+
+
+/**
+
+  C Interrupt Handler calledin the interrupt context when Source interrupt is active.
+
+
+  @param Source         Source of the interrupt. Hardware routing off a specific platform defines
+                        what source means.
+
+  @param SystemContext  Pointer to system register context. Mostly used by debuggers and will
+                        update the system context after the return from the interrupt if
+                        modified. Don't change these values unless you know what you are doing
+
+**/
+VOID
+EFIAPI
+TimerInterruptHandler (
+  IN  HARDWARE_INTERRUPT_SOURCE   Source,
+  IN  EFI_SYSTEM_CONTEXT          SystemContext
+  )
+{
+  EFI_TPL OriginalTPL;
+
+
+
+  //
+  // DXE core uses this callback for the EFI timer tick. The DXE core uses locks
+  // that raise to TPL_HIGH and then restore back to current level. Thus we need
+  // to make sure TPL level is set to TPL_HIGH while we are handling the timer tick.
+  //
+  OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+
+  if (mTimerNotifyFunction) {
+    mTimerNotifyFunction(mTimerPeriod);
+  }
+
+  // Clear all timer interrupts
+  MmioWrite32 (TISR, TISR_CLEAR_ALL);
+
+  // Poll interrupt status bits to ensure clearing
+  while ((MmioRead32 (TISR) & TISR_ALL_INTERRUPT_MASK) != TISR_NO_INTERRUPTS_PENDING);
+
+  gBS->RestoreTPL (OriginalTPL);
+}
+
+/**
+  This function registers the handler NotifyFunction so it is called every time
+  the timer interrupt fires.  It also passes the amount of time since the last
+  handler call to the NotifyFunction.  If NotifyFunction is NULL, then the
+  handler is unregistered.  If the handler is registered, then EFI_SUCCESS is
+  returned.  If the CPU does not support registering a timer interrupt handler,
+  then EFI_UNSUPPORTED is returned.  If an attempt is made to register a handler
+  when a handler is already registered, then EFI_ALREADY_STARTED is returned.
+  If an attempt is made to unregister a handler when a handler is not registered,
+  then EFI_INVALID_PARAMETER is returned.  If an error occurs attempting to
+  register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR
+  is returned.
+
+  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param  NotifyFunction   The function to call when a timer interrupt fires. This
+                           function executes at TPL_HIGH_LEVEL. The DXE Core will
+                           register a handler for the timer interrupt, so it can know
+                           how much time has passed. This information is used to
+                           signal timer based events. NULL will unregister the handler.
+  @retval EFI_SUCCESS           The timer handler was registered.
+  @retval EFI_UNSUPPORTED       The platform does not support timer interrupts.
+  @retval EFI_ALREADY_STARTED   NotifyFunction is not NULL, and a handler is already
+                                registered.
+  @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not
+                                previously registered.
+  @retval EFI_DEVICE_ERROR      The timer handler could not be registered.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverRegisterHandler (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This,
+  IN EFI_TIMER_NOTIFY         NotifyFunction
+  )
+{
+  if ((NotifyFunction == NULL) && (mTimerNotifyFunction == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((NotifyFunction != NULL) && (mTimerNotifyFunction != NULL)) {
+    return EFI_ALREADY_STARTED;
+  }
+
+  mTimerNotifyFunction = NotifyFunction;
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  This function adjusts the period of timer interrupts to the value specified
+  by TimerPeriod.  If the timer period is updated, then the selected timer
+  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If
+  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
+  If an error occurs while attempting to update the timer period, then the
+  timer hardware will be put back in its state prior to this call, and
+  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt
+  is disabled.  This is not the same as disabling the CPU's interrupts.
+  Instead, it must either turn off the timer hardware, or it must adjust the
+  interrupt controller so that a CPU interrupt is not generated when the timer
+  interrupt fires.
+
+  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param  TimerPeriod      The rate to program the timer interrupt in 100 nS units. If
+                           the timer hardware is not programmable, then EFI_UNSUPPORTED is
+                           returned. If the timer is programmable, then the timer period
+                           will be rounded up to the nearest timer period that is supported
+                           by the timer hardware. If TimerPeriod is set to 0, then the
+                           timer interrupts will be disabled.
+
+
+  @retval EFI_SUCCESS           The timer period was changed.
+  @retval EFI_UNSUPPORTED       The platform cannot change the period of the timer interrupt.
+  @retval EFI_DEVICE_ERROR      The timer period could not be changed due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverSetTimerPeriod (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This,
+  IN UINT64                   TimerPeriod
+  )
+{
+  EFI_STATUS  Status;
+  UINT64      TimerCount;
+  INT32       LoadValue;
+
+  if (TimerPeriod == 0) {
+    // Turn off GPTIMER3
+    MmioWrite32 (TCLR, TCLR_ST_OFF);
+
+    Status = gInterrupt->DisableInterruptSource(gInterrupt, gVector);
+  } else {
+    // Calculate required timer count
+    TimerCount = DivU64x32(TimerPeriod * 100, PcdGet32(PcdEmbeddedPerformanceCounterPeriodInNanoseconds));
+
+    // Set GPTIMER3 Load register
+    LoadValue = (INT32) -TimerCount;
+    MmioWrite32 (TLDR, LoadValue);
+    MmioWrite32 (TCRR, LoadValue);
+
+    // Enable Overflow interrupt
+    MmioWrite32 (TIER, TIER_TCAR_IT_DISABLE | TIER_OVF_IT_ENABLE | TIER_MAT_IT_DISABLE);
+
+    // Turn on GPTIMER3, it will reload at overflow
+    MmioWrite32 (TCLR, TCLR_AR_AUTORELOAD | TCLR_ST_ON);
+
+    Status = gInterrupt->EnableInterruptSource(gInterrupt, gVector);
+  }
+
+  //
+  // Save the new timer period
+  //
+  mTimerPeriod = TimerPeriod;
+  return Status;
+}
+
+
+/**
+  This function retrieves the period of timer interrupts in 100 ns units,
+  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod
+  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is
+  returned, then the timer is currently disabled.
+
+  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param  TimerPeriod      A pointer to the timer period to retrieve in 100 ns units. If
+                           0 is returned, then the timer is currently disabled.
+
+
+  @retval EFI_SUCCESS           The timer period was returned in TimerPeriod.
+  @retval EFI_INVALID_PARAMETER TimerPeriod is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGetTimerPeriod (
+  IN EFI_TIMER_ARCH_PROTOCOL   *This,
+  OUT UINT64                   *TimerPeriod
+  )
+{
+  if (TimerPeriod == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *TimerPeriod = mTimerPeriod;
+  return EFI_SUCCESS;
+}
+
+/**
+  This function generates a soft timer interrupt. If the platform does not support soft
+  timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.
+  If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()
+  service, then a soft timer interrupt will be generated. If the timer interrupt is
+  enabled when this service is called, then the registered handler will be invoked. The
+  registered handler should not be able to distinguish a hardware-generated timer
+  interrupt from a software-generated timer interrupt.
+
+  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.
+
+  @retval EFI_SUCCESS           The soft timer interrupt was generated.
+  @retval EFI_UNSUPPORTED       The platform does not support the generation of soft timer interrupts.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGenerateSoftInterrupt (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+
+/**
+  Interface stucture for the Timer Architectural Protocol.
+
+  @par Protocol Description:
+  This protocol provides the services to initialize a periodic timer
+  interrupt, and to register a handler that is called each time the timer
+  interrupt fires.  It may also provide a service to adjust the rate of the
+  periodic timer interrupt.  When a timer interrupt occurs, the handler is
+  passed the amount of time that has passed since the previous timer
+  interrupt.
+
+  @param RegisterHandler
+  Registers a handler that will be called each time the
+  timer interrupt fires.  TimerPeriod defines the minimum
+  time between timer interrupts, so TimerPeriod will also
+  be the minimum time between calls to the registered
+  handler.
+
+  @param SetTimerPeriod
+  Sets the period of the timer interrupt in 100 nS units.
+  This function is optional, and may return EFI_UNSUPPORTED.
+  If this function is supported, then the timer period will
+  be rounded up to the nearest supported timer period.
+
+
+  @param GetTimerPeriod
+  Retrieves the period of the timer interrupt in 100 nS units.
+
+  @param GenerateSoftInterrupt
+  Generates a soft timer interrupt that simulates the firing of
+  the timer interrupt. This service can be used to invoke the   registered handler if the timer interrupt has been masked for
+  a period of time.
+
+**/
+EFI_TIMER_ARCH_PROTOCOL   gTimer = {
+  TimerDriverRegisterHandler,
+  TimerDriverSetTimerPeriod,
+  TimerDriverGetTimerPeriod,
+  TimerDriverGenerateSoftInterrupt
+};
+
+
+/**
+  Initialize the state information for the Timer Architectural Protocol and
+  the Timer Debug support protocol that allows the debugger to break into a
+  running program.
+
+  @param  ImageHandle   of the loaded driver
+  @param  SystemTable   Pointer to the System Table
+
+  @retval EFI_SUCCESS           Protocol registered
+  @retval EFI_OUT_OF_RESOURCES  Cannot allocate protocol data structure
+  @retval EFI_DEVICE_ERROR      Hardware problems
+
+**/
+EFI_STATUS
+EFIAPI
+TimerInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_HANDLE  Handle = NULL;
+  EFI_STATUS  Status;
+  UINT32      TimerBaseAddress;
+
+  // Find the interrupt controller protocol.  ASSERT if not found.
+  Status = gBS->LocateProtocol (&gHardwareInterruptProtocolGuid, NULL, (VOID **)&gInterrupt);
+  ASSERT_EFI_ERROR (Status);
+
+  // Set up the timer registers
+  TimerBaseAddress = TimerBase (FixedPcdGet32(PcdOmap35xxArchTimer));
+  TISR = TimerBaseAddress + GPTIMER_TISR;
+  TCLR = TimerBaseAddress + GPTIMER_TCLR;
+  TLDR = TimerBaseAddress + GPTIMER_TLDR;
+  TCRR = TimerBaseAddress + GPTIMER_TCRR;
+  TIER = TimerBaseAddress + GPTIMER_TIER;
+
+  // Disable the timer
+  Status = TimerDriverSetTimerPeriod (&gTimer, 0);
+  ASSERT_EFI_ERROR (Status);
+
+  // Install interrupt handler
+  gVector = InterruptVectorForTimer (FixedPcdGet32(PcdOmap35xxArchTimer));
+  Status = gInterrupt->RegisterInterruptSource (gInterrupt, gVector, TimerInterruptHandler);
+  ASSERT_EFI_ERROR (Status);
+
+  // Turn on the functional clock for Timer
+  MmioOr32 (CM_FCLKEN_PER, CM_FCLKEN_PER_EN_GPT3_ENABLE);
+
+  // Set up default timer
+  Status = TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32(PcdTimerPeriod));
+  ASSERT_EFI_ERROR (Status);
+
+  // Install the Timer Architectural Protocol onto a new handle
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Handle,
+                  &gEfiTimerArchProtocolGuid,      &gTimer,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+  return Status;
+}
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/TimerDxe.inf b/Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/TimerDxe.inf
new file mode 100644
index 0000000000..e072982d51
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/TimerDxe.inf
@@ -0,0 +1,51 @@
+#/** @file
+#
+#    Component description file for Timer module
+#
+#  Copyright (c) 2009, Apple Inc. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BeagleBoardTimerDxe
+  FILE_GUID                      = 6ddbf08b-cfc9-43cc-9e81-0784ba312ca0
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = TimerInitialize
+
+[Sources.common]
+  Timer.c
+
+[Packages]
+  Omap35xxPkg/Omap35xxPkg.dec
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  UefiRuntimeServicesTableLib
+  UefiLib
+  UefiBootServicesTableLib
+  BaseMemoryLib
+  DebugLib
+  UefiDriverEntryPoint
+  IoLib
+  OmapLib
+
+[Guids]
+
+[Protocols]
+  gEfiTimerArchProtocolGuid
+  gHardwareInterruptProtocolGuid
+
+[Pcd.common]
+  gEmbeddedTokenSpaceGuid.PcdTimerPeriod
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedPerformanceCounterPeriodInNanoseconds
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxArchTimer
+
+[Depex]
+  gHardwareInterruptProtocolGuid
-- 
2.21.0.windows.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [edk2-platforms: Patch 2/8] Platform/BeagleBoard: Import BeagleBoardPkg from edk2
  2019-05-10  3:34 [edk2-platforms: Patch 0/8] Add packages from edk2 Michael D Kinney
  2019-05-10  3:34 ` [edk2-platforms: Patch 1/8] Silicon/TexasInsturments: Import Omap35xxPkg " Michael D Kinney
@ 2019-05-10  3:34 ` Michael D Kinney
  2019-05-10  3:34 ` [edk2-platforms: Patch 3/8] Silicon/Intel: Import QuarkSocPkg " Michael D Kinney
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 23+ messages in thread
From: Michael D Kinney @ 2019-05-10  3:34 UTC (permalink / raw)
  To: devel; +Cc: Leif Lindholm, Ard Biesheuvel

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

Import BeagleBoardPkg from edk2/master.

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>
---
 .../BeagleBoardPkg/BeagleBoardPkg.dec         |  30 ++
 .../BeagleBoardPkg/BeagleBoardPkg.dsc         | 496 ++++++++++++++++++
 .../BeagleBoardPkg/BeagleBoardPkg.fdf         | 308 +++++++++++
 .../BeagleBoardPkg/ConfigurationHeader.bin    | Bin 0 -> 512 bytes
 .../BeagleBoardPkg/ConfigurationHeader.dat    |  41 ++
 .../Debugger_scripts/rvi_boot_from_ram.inc    |  15 +
 .../Debugger_scripts/rvi_convert_symbols.sh   |  17 +
 .../Debugger_scripts/rvi_dummy.axf            | Bin 0 -> 7984 bytes
 .../Debugger_scripts/rvi_hw_setup.inc         |  61 +++
 .../Debugger_scripts/rvi_load_symbols.inc     |  17 +
 .../Debugger_scripts/rvi_symbols_macros.inc   | 188 +++++++
 .../Debugger_scripts/rvi_unload_symbols.inc   | 112 ++++
 .../Debugger_scripts/trace32_load_symbols.cmm | 205 ++++++++
 .../trace32_load_symbols_cygwin.cmm           | 182 +++++++
 .../BeagleBoardPkg/Include/BeagleBoard.h      | 173 ++++++
 .../Library/BeagleBoardLib/BeagleBoard.c      | 115 ++++
 .../BeagleBoardLib/BeagleBoardHelper.S        |  41 ++
 .../BeagleBoardLib/BeagleBoardHelper.asm      |  47 ++
 .../Library/BeagleBoardLib/BeagleBoardLib.inf |  48 ++
 .../Library/BeagleBoardLib/BeagleBoardMem.c   |  74 +++
 .../Library/BeagleBoardLib/Clock.c            |  63 +++
 .../Library/BeagleBoardLib/PadConfiguration.c | 316 +++++++++++
 .../Library/DxeHobPeCoffLib/DxeHobPeCoff.c    | 282 ++++++++++
 .../DxeHobPeCoffLib/DxeHobPeCoffLib.inf       |  39 ++
 .../LzmaHobCustomDecompressLib.c              |  44 ++
 .../LzmaHobCustomDecompressLib.inf            |  45 ++
 .../MemoryInitPeiLib/MemoryInitPeiLib.c       | 192 +++++++
 .../MemoryInitPeiLib/MemoryInitPeiLib.inf     |  58 ++
 .../Library/ResetSystemLib/ResetSystemLib.c   | 149 ++++++
 .../Library/ResetSystemLib/ResetSystemLib.inf |  37 ++
 .../BeagleBoardPkg/PrePi/Arm/ArchPrePi.c      |  23 +
 .../PrePi/Arm/ModuleEntryPoint.S              | 124 +++++
 .../PrePi/Arm/ModuleEntryPoint.asm            | 142 +++++
 .../BeagleBoardPkg/PrePi/LzmaDecompress.h     |  97 ++++
 .../BeagleBoardPkg/PrePi/MainUniCore.c        |  33 ++
 .../BeagleBoardPkg/PrePi/PeiUniCore.inf       |  97 ++++
 .../BeagleBoard/BeagleBoardPkg/PrePi/PrePi.c  | 179 +++++++
 .../BeagleBoard/BeagleBoardPkg/PrePi/PrePi.h  |  90 ++++
 .../BeagleBoardPkg/Tools/GNUmakefile          |  14 +
 .../BeagleBoardPkg/Tools/generate_image.c     | 402 ++++++++++++++
 .../BeagleBoard/BeagleBoardPkg/Tools/makefile |  16 +
 .../BeagleBoardPkg/Tools/replace.c            | 140 +++++
 42 files changed, 4752 insertions(+)
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.dec
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.dsc
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.fdf
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/ConfigurationHeader.bin
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/ConfigurationHeader.dat
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_boot_from_ram.inc
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_convert_symbols.sh
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_dummy.axf
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_hw_setup.inc
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_load_symbols.inc
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_symbols_macros.inc
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_unload_symbols.inc
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/trace32_load_symbols.cmm
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/trace32_load_symbols_cygwin.cmm
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Include/BeagleBoard.h
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoard.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoardHelper.S
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoardHelper.asm
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoardLib.inf
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoardMem.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/Clock.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/PadConfiguration.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/DxeHobPeCoffLib/DxeHobPeCoff.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/DxeHobPeCoffLib/DxeHobPeCoffLib.inf
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/LzmaHobCustomDecompressLib/LzmaHobCustomDecompressLib.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/LzmaHobCustomDecompressLib/LzmaHobCustomDecompressLib.inf
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/ResetSystemLib/ResetSystemLib.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Library/ResetSystemLib/ResetSystemLib.inf
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ArchPrePi.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ModuleEntryPoint.S
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ModuleEntryPoint.asm
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/PrePi/LzmaDecompress.h
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/PrePi/MainUniCore.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/PrePi/PeiUniCore.inf
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/PrePi/PrePi.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/PrePi/PrePi.h
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Tools/GNUmakefile
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Tools/generate_image.c
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Tools/makefile
 create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Tools/replace.c

diff --git a/Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.dec b/Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.dec
new file mode 100644
index 0000000000..a82f8756b5
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.dec
@@ -0,0 +1,30 @@
+#/** @file
+# Beagle board package.
+#
+# Copyright (c) 2009, Apple Inc. All rights reserved.<BR>
+#
+#    SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  DEC_SPECIFICATION              = 0x00010005
+  PACKAGE_NAME                   = BeagleBoardPkg
+  PACKAGE_GUID                   = 6eba6648-d853-4eb3-9761-528b82d5ab04
+  PACKAGE_VERSION                = 0.1
+
+################################################################################
+#
+# Include Section - list of Include Paths that are provided by this package.
+#                   Comments are used for Keywords and Module Types.
+#
+# Supported Module Types:
+#  BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
+#
+################################################################################
+[Includes.common]
+  Include                        # Root include for the package
+
+[Guids.common]
+  gBeagleBoardTokenSpaceGuid    =  { 0x6834fe45, 0x4aee, 0x4fc6, { 0xbc, 0xb5, 0xff, 0x45, 0xb7, 0xa8, 0x71, 0xe2 } }
+
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.dsc b/Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.dsc
new file mode 100644
index 0000000000..2d5d6f9977
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.dsc
@@ -0,0 +1,496 @@
+#/** @file
+# Beagle board package.
+#
+# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
+# Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
+#
+#    SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  PLATFORM_NAME                  = BeagleBoardPkg
+  PLATFORM_GUID                  = 91fa6c28-33df-46ac-aee6-292d6811ea31
+  PLATFORM_VERSION               = 0.1
+  DSC_SPECIFICATION              = 0x00010005
+  OUTPUT_DIRECTORY               = Build/BeagleBoard
+  SUPPORTED_ARCHITECTURES        = ARM
+  BUILD_TARGETS                  = DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+  FLASH_DEFINITION               = BeagleBoardPkg/BeagleBoardPkg.fdf
+
+
+[LibraryClasses.common]
+  ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
+  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
+  ArmPlatformLib|BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoardLib.inf
+  ArmPlatformStackLib|ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
+  ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
+
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+
+!if $(TARGET) == RELEASE
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+!else
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!endif
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+
+  ResetSystemLib|BeagleBoardPkg/Library/ResetSystemLib/ResetSystemLib.inf
+
+  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+
+  # These libraries are used by the dynamic EFI Shell commands
+  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+
+  #
+  # Uncomment (and comment out the next line) For RealView Debugger. The Standard IO window
+  # in the debugger will show load and unload commands for symbols. You can cut and paste this
+  # into the command window to load symbols. We should be able to use a script to do this, but
+  # the version of RVD I have does not support scipts accessing system memory.
+  #
+#  PeCoffExtraActionLib|ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf
+  PeCoffExtraActionLib|ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
+#  PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+
+
+  CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
+  DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
+  CpuExceptionHandlerLib|ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.inf
+  PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
+
+  SerialPortLib|Omap35xxPkg/Library/SerialPortLib/SerialPortLib.inf
+  SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf
+
+  RealTimeClockLib|Omap35xxPkg/Library/RealTimeClockLib/RealTimeClockLib.inf
+
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+
+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+
+#
+# Assume everything is fixed at build
+#
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+
+  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+
+  TimerLib|Omap35xxPkg/Library/Omap35xxTimerLib/Omap35xxTimerLib.inf
+  OmapLib|Omap35xxPkg/Library/OmapLib/OmapLib.inf
+  OmapDmaLib|Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.inf
+  DebugAgentTimerLib|Omap35xxPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf
+
+  GdbSerialLib|Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.inf
+  ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
+  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+  DmaLib|EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.inf
+
+  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+  FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
+
+  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+  PlatformBootManagerLib|ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+  BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
+  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+
+  # UiApp dependencies
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+
+  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+  AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
+  TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
+  VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
+
+  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+
+[LibraryClasses.common.SEC]
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf
+  ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
+
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+
+  HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf
+  PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
+  MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
+  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+  PlatformPeiLib|ArmPlatformPkg/PlatformPei/PlatformPeiLib.inf
+  MemoryInitPeiLib|BeagleBoardPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf
+
+  # 1/123 faster than Stm or Vstm version
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+
+[LibraryClasses.common.PEI_CORE]
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf
+
+[LibraryClasses.common.DXE_CORE]
+  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
+  MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+  ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+#  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  PeCoffLib|BeagleBoardPkg/Library/DxeHobPeCoffLib/DxeHobPeCoffLib.inf
+
+  PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
+
+
+[LibraryClasses.common.DXE_DRIVER]
+  ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+  NonDiscoverableDeviceRegistrationLib|MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.inf
+
+[LibraryClasses.common.UEFI_APPLICATION]
+  ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+
+[LibraryClasses.common.UEFI_DRIVER]
+  ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+#  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  PeCoffLib|BeagleBoardPkg/Library/DxeHobPeCoffLib/DxeHobPeCoffLib.inf
+
+
+[LibraryClasses.ARM]
+  #
+  # It is not possible to prevent the ARM compiler for generic intrinsic functions.
+  # This library provides the instrinsic functions generate by a given compiler.
+  # [LibraryClasses.ARM] and NULL mean link this library into all ARM images.
+  #
+  NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+
+  # Add support for GCC stack protector
+  NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
+
+[BuildOptions]
+  XCODE:*_*_ARM_PLATFORM_FLAGS == -arch armv7
+  GCC:*_*_ARM_PLATFORM_FLAGS == -march=armv7-a
+  RVCT:*_*_ARM_PLATFORM_FLAGS == --cpu Cortex-A8
+
+  *_*_*_CC_FLAGS = -DDISABLE_NEW_DEPRECATED_INTERFACES
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsFeatureFlag.common]
+  gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable|TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable|TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|TRUE
+
+  # Use the Vector Table location in CpuDxe. We will not copy the Vector Table at PcdCpuVectorBaseAddress
+  gArmTokenSpaceGuid.PcdRelocateVectorTable|FALSE
+
+  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|TRUE
+  gArmTokenSpaceGuid.PcdCpuDxeProduceDebugSupport|FALSE
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE
+
+  ## If TRUE, Graphics Output Protocol will be installed on virtual handle created by ConsplitterDxe.
+  #  It could be set FALSE to save size.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
+
+[PcdsFixedAtBuild.common]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVendor|L"Beagle Board"
+
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000
+  gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout|10000000
+  gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue|0xAF
+  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|1
+  gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask|0
+  gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|320
+
+# DEBUG_ASSERT_ENABLED       0x01
+# DEBUG_PRINT_ENABLED        0x02
+# DEBUG_CODE_ENABLED         0x04
+# CLEAR_MEMORY_ENABLED       0x08
+# ASSERT_BREAKPOINT_ENABLED  0x10
+# ASSERT_DEADLOOP_ENABLED    0x20
+!if $(TARGET) == RELEASE
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x21
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2f
+!endif
+
+#  DEBUG_INIT      0x00000001  // Initialization
+#  DEBUG_WARN      0x00000002  // Warnings
+#  DEBUG_LOAD      0x00000004  // Load events
+#  DEBUG_FS        0x00000008  // EFI File system
+#  DEBUG_POOL      0x00000010  // Alloc & Free (pool)
+#  DEBUG_PAGE      0x00000020  // Alloc & Free (page)
+#  DEBUG_INFO      0x00000040  // Informational debug messages
+#  DEBUG_DISPATCH  0x00000080  // PEI/DXE/SMM Dispatchers
+#  DEBUG_VARIABLE  0x00000100  // Variable
+#  DEBUG_BM        0x00000400  // Boot Manager
+#  DEBUG_BLKIO     0x00001000  // BlkIo Driver
+#  DEBUG_NET       0x00004000  // SNP Driver
+#  DEBUG_UNDI      0x00010000  // UNDI Driver
+#  DEBUG_LOADFILE  0x00020000  // LoadFile
+#  DEBUG_EVENT     0x00080000  // Event messages
+#  DEBUG_GCD       0x00100000  // Global Coherency Database changes
+#  DEBUG_CACHE     0x00200000  // Memory range cachability changes
+#  DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may
+#                              // significantly impact boot performance
+#  DEBUG_ERROR     0x80000000  // Error
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000000F
+
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+
+#
+# Optional feature to help prevent EFI memory map fragments
+# Turned on and off via: PcdPrePiProduceMemoryTypeInformationHob
+# Values are in EFI Pages (4K). DXE Core will make sure that
+# at least this much of each type of memory can be allocated
+# from a single memory range. This way you only end up with
+# maximum of two fragements for each type in the memory map
+# (the memory used, and the free memory that was prereserved
+# but not used).
+#
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory|0
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS|0
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType|0
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|80
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|40
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode|400
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData|3000
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|10
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0
+
+  gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|4
+
+#
+# Beagle board Specific PCDs
+#
+  gArmTokenSpaceGuid.PcdVFPEnabled|1
+
+  gArmTokenSpaceGuid.PcdSystemMemoryBase|0x80000000
+  gArmTokenSpaceGuid.PcdSystemMemorySize|0x08000000
+
+  # Size of the region used by UEFI in permanent memory (Reserved 16MB)
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x01000000
+
+  gArmTokenSpaceGuid.PcdCpuVectorBaseAddress|0x80008000
+  gArmTokenSpaceGuid.PcdCpuResetAddress|0x80008000
+
+  gEmbeddedTokenSpaceGuid.PcdTimerPeriod|100000
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedPerformanceCounterPeriodInNanoseconds|77
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedPerformanceCounterFrequencyInHz|13000000
+
+  # OMAP Interrupt Controller
+  gEmbeddedTokenSpaceGuid.PcdInterruptBaseAddress|0x48200000
+
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|10
+
+  # GUID of the UEFI Shell
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 }
+
+  # GUID of the UI app
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+
+  #
+  # Make VariableRuntimeDxe work at emulated non-volatile variable mode.
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE
+
+################################################################################
+#
+# Components Section - list of all EDK II Modules needed by this Platform
+#
+################################################################################
+[Components.common]
+
+  #
+  # SEC
+  #
+  BeagleBoardPkg/PrePi/PeiUniCore.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+  }
+
+  #
+  # DXE
+  #
+  MdeModulePkg/Core/Dxe/DxeMain.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+      NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
+      NULL|BeagleBoardPkg/Library/LzmaHobCustomDecompressLib/LzmaHobCustomDecompressLib.inf
+  }
+
+  ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+
+  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+  EmbeddedPkg/EmbeddedMonotonicCounter/EmbeddedMonotonicCounter.inf
+
+  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+  MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+#
+# This version uses semi-hosting console
+#  EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf {
+#    <LibraryClasses>
+#      SerialPortLib|ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf
+#  }
+
+  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+  EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+  #
+  # Semi-hosting filesystem
+  #
+  ArmPkg/Filesystem/SemihostFs/SemihostFs.inf
+
+  #
+  # FAT filesystem + GPT/MBR partitioning
+  #
+  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+  FatPkg/EnhancedFatDxe/Fat.inf
+
+  #
+  # USB
+  #
+  Omap35xxPkg/PciEmulation/PciEmulation.inf
+  MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceDxe.inf
+
+  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf {
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x800fffff
+  }
+
+  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+  #
+  # Nand Flash
+  #
+  Omap35xxPkg/Flash/Flash.inf
+
+  #
+  # MMC/SD
+  #
+  EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
+  Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf
+
+  #
+  # I2C
+  #
+  Omap35xxPkg/SmbusDxe/Smbus.inf
+
+  #
+  # SoC Drivers
+  #
+  Omap35xxPkg/Gpio/Gpio.inf
+  Omap35xxPkg/InterruptDxe/InterruptDxe.inf
+  Omap35xxPkg/TimerDxe/TimerDxe.inf
+  Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.inf
+
+  #
+  # Power IC
+  #
+  Omap35xxPkg/TPS65950Dxe/TPS65950.inf
+
+  #
+  # Bds
+  #
+  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+  MdeModulePkg/Application/UiApp/UiApp.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
+      NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
+      NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
+  }
+
+  #
+  # Shell
+  #
+  ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf {
+    <PcdsFixedAtBuild>
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+  }
+  ShellPkg/Application/Shell/Shell.inf {
+    <LibraryClasses>
+      ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
+      HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+      PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+      BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+      gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
+  }
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.fdf b/Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.fdf
new file mode 100644
index 0000000000..1d5c0040b5
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.fdf
@@ -0,0 +1,308 @@
+# FLASH layout file for Beagle board.
+#
+# Copyright (c) 2009, Apple Inc. All rights reserved.<BR>
+# Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2016, Linaro, Ltd. All rights reserved.<BR>
+#
+#    SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+################################################################################
+#
+# FD Section
+# The [FD] Section is made up of the definition statements and a
+# description of what goes into  the Flash Device Image.  Each FD section
+# defines one flash "device" image.  A flash device image may be one of
+# the following: Removable media bootable image (like a boot floppy
+# image,) an Option ROM image (that would be "flashed" into an add-in
+# card,) a System "Flash"  image (that would be burned into a system's
+# flash) or an Update ("Capsule") image that will be used to update and
+# existing system flash.
+#
+################################################################################
+
+
+[FD.BeagleBoard_EFI]
+BaseAddress   = 0x80007DF8|gArmTokenSpaceGuid.PcdFdBaseAddress  #The base address of the FLASH Device.
+Size          = 0x000B0000|gArmTokenSpaceGuid.PcdFdSize         #The size in bytes of the FLASH Device
+ErasePolarity = 1
+BlockSize     = 0x1
+NumBlocks     = 0xB0000
+
+################################################################################
+#
+# Following are lists of FD Region layout which correspond to the locations of different
+# images within the flash device.
+#
+# Regions must be defined in ascending order and may not overlap.
+#
+# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
+# the pipe "|" character, followed by the size of the region, also in hex with the leading
+# "0x" characters. Like:
+# Offset|Size
+# PcdOffsetCName|PcdSizeCName
+# RegionType <FV, DATA, or FILE>
+#
+################################################################################
+0x00000000|0x00000200
+FILE = BeagleBoardPkg/ConfigurationHeader.bin
+
+0x00000200|0x00000008
+DATA = {
+  0xF8, 0xFD, 0x0A, 0x00,   # image size:   0xB0000 - 0x208 == 0xAFDF8
+  0x00, 0x80, 0x00, 0x80    # entry point:  0x80008000
+}
+
+0x00000208|0x000AFDF8
+gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
+FV = FVMAIN_COMPACT
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file.  This section also defines order the components and modules are positioned
+# within the image.  The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+
+[FV.FvMain]
+BlockSize          = 0x1
+NumBlocks          = 0         # This FV gets compressed so make it just big enough
+FvAlignment        = 8         # FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = d0dd3e90-343d-4cb3-8f69-772214989282
+
+  INF MdeModulePkg/Core/Dxe/DxeMain.inf
+
+  #
+  # PI DXE Drivers producing Architectural Protocols (EFI Services)
+  #
+  INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+
+  INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+  INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+  INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+  INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+  INF EmbeddedPkg/EmbeddedMonotonicCounter/EmbeddedMonotonicCounter.inf
+
+  INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+  INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+  INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+
+  INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+  INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+  INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+!if $(TARGET) == RELEASE
+  #
+  # Semi-hosting filesystem
+  #
+  INF ArmPkg/Filesystem/SemihostFs/SemihostFs.inf
+!endif
+
+  #
+  # Nand Flash
+  #
+  INF Omap35xxPkg/Flash/Flash.inf
+
+  #
+  # MMC/SD
+  #
+  INF EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
+  INF Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf
+
+  #
+  # I2C
+  #
+  INF Omap35xxPkg/SmbusDxe/Smbus.inf
+
+  #
+  # SoC Drivers
+  #
+  INF Omap35xxPkg/Gpio/Gpio.inf
+  INF Omap35xxPkg/InterruptDxe/InterruptDxe.inf
+  INF Omap35xxPkg/TimerDxe/TimerDxe.inf
+  INF Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.inf
+
+  #
+  # Power IC
+  #
+  INF Omap35xxPkg/TPS65950Dxe/TPS65950.inf
+
+  #
+  # FAT filesystem + GPT/MBR partitioning
+  #
+  INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+  INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+  INF FatPkg/EnhancedFatDxe/Fat.inf
+  INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+
+  #
+  # USB Support
+  #
+
+  INF Omap35xxPkg/PciEmulation/PciEmulation.inf
+  INF MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceDxe.inf
+
+  INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+  INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+  INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+  #
+  # UEFI application (Shell Embedded Boot Loader)
+  #
+  INF ShellPkg/Application/Shell/Shell.inf
+  INF ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf
+
+  #
+  # Bds
+  #
+  INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+  INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+  INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+  INF MdeModulePkg/Application/UiApp/UiApp.inf
+
+
+[FV.FVMAIN_COMPACT]
+FvAlignment        = 8
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+  INF BeagleBoardPkg/PrePi/PeiUniCore.inf
+
+  FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+    SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+      SECTION FV_IMAGE = FVMAIN
+    }
+  }
+
+
+################################################################################
+#
+# Rules are use with the [FV] section's module INF type to define
+# how an FFS file is created for a given INF file. The following Rule are the default
+# rules for the different module type. User can add the customized rules to define the
+# content of the FFS file.
+#
+################################################################################
+
+
+############################################################################
+# Example of a DXE_DRIVER FFS file with a Checksum encapsulation section   #
+############################################################################
+#
+#[Rule.Common.DXE_DRIVER]
+#  FILE DRIVER = $(NAMED_GUID) {
+#    DXE_DEPEX    DXE_DEPEX               Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+#    COMPRESS PI_STD {
+#      GUIDED {
+#        PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
+#        UI       STRING="$(MODULE_NAME)" Optional
+#        VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+#      }
+#    }
+#  }
+#
+############################################################################
+
+[Rule.Common.SEC]
+  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+    TE  TE    Align = 32                $(INF_OUTPUT)/$(MODULE_NAME).efi
+  }
+
+[Rule.Common.PEI_CORE]
+  FILE PEI_CORE = $(NAMED_GUID) {
+    TE     TE                           $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI     STRING ="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.PEIM]
+  FILE PEIM = $(NAMED_GUID) {
+     PEI_DEPEX PEI_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+     PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI       STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.DXE_CORE]
+  FILE DXE_CORE = $(NAMED_GUID) {
+    PE32     PE32                       $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+  }
+
+
+[Rule.Common.UEFI_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI           STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.DXE_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI           STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.DXE_RUNTIME_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI           STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.UEFI_APPLICATION]
+  FILE APPLICATION = $(NAMED_GUID) {
+    UI     STRING ="$(MODULE_NAME)" Optional
+    PE32   PE32                         $(INF_OUTPUT)/$(MODULE_NAME).efi
+  }
+
+[Rule.Common.UEFI_DRIVER.BINARY]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional      |.depex
+    PE32      PE32                    |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION.BINARY]
+  FILE APPLICATION = $(NAMED_GUID) {
+    PE32      PE32                    |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/ConfigurationHeader.bin b/Platform/BeagleBoard/BeagleBoardPkg/ConfigurationHeader.bin
new file mode 100644
index 0000000000000000000000000000000000000000..150b3849fc35f6526f51ce32b3ab30c9555b284f
GIT binary patch
literal 512
zcmZ3$z`zgy#K^$eBiJ=0#M93`n1SH~P$C9d63BM;2y*m=iv0%yG-;}G4<0yhfRT}b
z;V&ZtYXi_^W*`pWVq)e3GDLxFb07o*9v@B^n`Z+f11DGxD)mK>0cZpm90HjKW&uec
n;)04d0%?%hf({p$jG$u2j?CSqq{_&^_=p9s97s7x?@$B)<?bO_

literal 0
HcmV?d00001

diff --git a/Platform/BeagleBoard/BeagleBoardPkg/ConfigurationHeader.dat b/Platform/BeagleBoard/BeagleBoardPkg/ConfigurationHeader.dat
new file mode 100644
index 0000000000..5f6897e306
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/ConfigurationHeader.dat
@@ -0,0 +1,41 @@
+PRM_CLKSRC_CTRL=0x00000080
+PRM_CLKSEL=0x00000003
+CM_CLKSEL1_EMU=0x03020A50
+CM_CLKSEL_CORE=0x0000030A
+CM_CLKSEL_WKUP=0x00000015
+CM_CLKEN_PLL_DPLL3=0x00370037
+CM_AUTOIDLE_PLL_DPLL3=0x00000000
+CM_CLKSEL1_PLL=0x094C0C00
+CM_CLKEN_PLL_DPLL4=0x00370037
+CM_AUTOIDLE_PLL_DPLL4=0x00000000
+CM_CLKSEL2_PLL=0x0001B00C
+CM_CLKSEL3_PLL=0x00000009
+CM_CLKEN_PLL_MPU=0x00000037
+CM_AUTOIDLE_PLL_MPU=0x00000000
+CM_CLKSEL1_PLL_MPU=0x0011F40C
+CM_CLKSEL2_PLL_MPU=0x00000001
+CM_CLKSTCTRL_MPU=0x00000000
+SDRC_SYSCONFIG_LSB=0x0000
+SDRC_CS_CFG_LSB=0x0001
+SDRC_SHARING_LSB=0x0100
+SDRC_ERR_TYPE_LSB=0x0000
+SDRC_DLLA_CTRL=0x0000000A
+SDRC_POWER=0x00000081
+MEMORY_TYPE_CS0=0x0003
+SDRC_MCFG_0=0x02D04011
+SDRC_MR_0_LSB=0x0032
+SDRC_EMR1_0_LSB=0x0000
+SDRC_EMR2_0_LSB=0x0000
+SDRC_EMR3_0_LSB=0x0000
+SDRC_ACTIM_CTRLA_0=0xBA9DC4C6
+SDRC_ACTIM_CTRLB_0=0x00012522
+SDRC_RFRCTRL_0=0x0004E201
+MEMORY_TYPE_CS1=0x0003
+SDRC_MCFG_1=0x02D04011
+SDRC_MR_1_LSB=0x0032
+SDRC_EMR1_1_LSB=0x0000
+SDRC_EMR2_1_LSB=0x0000
+SDRC_EMR3_1_LSB=0x0000
+SDRC_ACTIM_CTRLA_1=0xBA9DC4C6
+SDRC_ACTIM_CTRLB_1=0x00012522
+SDRC_RFRCTRL_1=0x0004E201
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_boot_from_ram.inc b/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_boot_from_ram.inc
new file mode 100644
index 0000000000..7bc96ab8d2
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_boot_from_ram.inc
@@ -0,0 +1,15 @@
+//
+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+//
+//  SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+error = continue
+unload
+error = abort
+
+setreg @CP15_CONTROL = 0x0005107E
+setreg @pc=0x80008208
+setreg @cpsr=0x000000D3
+dis/D
+readfile,raw,nowarn "ZZZZZZ/FV/BEAGLEBOARD_EFI.fd"=0x80008000
+
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_convert_symbols.sh b/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_convert_symbols.sh
new file mode 100644
index 0000000000..b1a819382c
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_convert_symbols.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+#
+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+#  
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+
+IN=`/usr/bin/cygpath -u $1`
+OUT=`/usr/bin/cygpath -u $2`
+
+/usr/bin/sed -e "s/\/cygdrive\/\(.\)/load\/a\/ni\/np \"\1:/g" \
+             -e 's:\\:/:g' \
+             -e "s/^/load\/a\/ni\/np \"/g" \
+             -e "s/dll /dll\" \&/g" \
+              $IN | /usr/bin/sort.exe --key=3 --output=$OUT
+
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_dummy.axf b/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_dummy.axf
new file mode 100644
index 0000000000000000000000000000000000000000..17fabaa6cc649d520848f087954c0729043bf001
GIT binary patch
literal 7984
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

literal 0
HcmV?d00001

diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_hw_setup.inc b/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_hw_setup.inc
new file mode 100644
index 0000000000..4c410f56b7
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_hw_setup.inc
@@ -0,0 +1,61 @@
+//
+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+//
+//  SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+error = continue
+unload
+error = abort
+
+setreg @CP15_CONTROL = 0x0005107E
+setreg @cpsr=0x000000D3
+
+; General clock settings.
+setmem /32 0x48307270=0x00000080
+setmem /32 0x48306D40=0x00000003
+setmem /32 0x48005140=0x03020A50
+
+;Clock configuration
+setmem /32 0x48004A40=0x0000030A
+setmem /32 0x48004C40=0x00000015
+
+;DPLL3 (Core) settings
+setmem /32 0x48004D00=0x00370037
+setmem /32 0x48004D30=0x00000000
+setmem /32 0x48004D40=0x094C0C00
+
+;DPLL4 (Peripheral) settings
+setmem /32 0x48004D00=0x00370037
+setmem /32 0x48004D30=0x00000000
+setmem /32 0x48004D44=0x0001B00C
+setmem /32 0x48004D48=0x00000009
+
+;DPLL1 (MPU) settings
+setmem /32 0x48004904=0x00000037
+setmem /32 0x48004934=0x00000000
+setmem /32 0x48004940=0x0011F40C
+setmem /32 0x48004944=0x00000001
+setmem /32 0x48004948=0x00000000
+
+;RAM setup.
+setmem /16 0x6D000010=0x0000
+setmem /16 0x6D000040=0x0001
+setmem /16 0x6D000044=0x0100
+setmem /16 0x6D000048=0x0000
+setmem /32 0x6D000060=0x0000000A
+setmem /32 0x6D000070=0x00000081
+setmem /16 0x6D000040=0x0003
+setmem /32 0x6D000080=0x02D04011
+setmem /16 0x6D000084=0x0032
+setmem /16 0x6D00008C=0x0000
+setmem /32 0x6D00009C=0xBA9DC4C6
+setmem /32 0x6D0000A0=0x00012522
+setmem /32 0x6D0000A4=0x0004E201
+setmem /16 0x6D000040=0x0003
+setmem /32 0x6D0000B0=0x02D04011
+setmem /16 0x6D0000B4=0x0032
+setmem /16 0x6D0000BC=0x0000
+setmem /32 0x6D0000C4=0xBA9DC4C6
+setmem /32 0x6D0000C8=0x00012522
+setmem /32 0x6D0000D4=0x0004E201
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_load_symbols.inc b/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_load_symbols.inc
new file mode 100644
index 0000000000..c3a04c34c0
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_load_symbols.inc
@@ -0,0 +1,17 @@
+//
+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+//
+//  SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+include 'ZZZZZZ/rvi_symbols_macros.inc'
+
+macro write_symbols_file("ZZZZZZ/rvi_symbols.tmp", 0x00000000, 0x10000000)
+
+host "bash -o igncr ZZZZZZ/rvi_convert_symbols.sh ZZZZZZ/rvi_symbols.tmp ZZZZZZ/rvi_symbols.inc"
+include 'ZZZZZZ/rvi_symbols.inc'
+load /NI /NP 'ZZZZZZ/rvi_dummy.axf' ;.constdata
+unload rvi_dummy.axf
+delfile rvi_dummy.axf
+
+
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_symbols_macros.inc b/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_symbols_macros.inc
new file mode 100644
index 0000000000..4ea3ae1a13
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_symbols_macros.inc
@@ -0,0 +1,188 @@
+//
+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+//
+//  SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+define /R int compare_guid(guid1, guid2)
+    unsigned char *guid1;
+    unsigned char *guid2;
+{
+    return strncmp(guid1, guid2, 16);
+}
+.
+
+define /R unsigned char * find_system_table(mem_start, mem_size)
+    unsigned char *mem_start;
+    unsigned long mem_size;
+{
+    unsigned char *mem_ptr;
+
+    mem_ptr = mem_start + mem_size;
+
+    do
+    {
+        mem_ptr -= 0x400000; // 4 MB
+
+        if (strncmp(mem_ptr, "IBI SYST", 8) == 0)
+        {
+            return *(unsigned long *)(mem_ptr + 8); // EfiSystemTableBase
+        }
+
+    } while (mem_ptr > mem_start);
+
+    return 0;
+}
+.
+
+define /R unsigned char * find_debug_info_table_header(system_table)
+    unsigned char *system_table;
+{
+    unsigned long configuration_table_entries;
+    unsigned char *configuration_table;
+    unsigned long index;
+    unsigned char debug_table_guid[16];
+
+    // Fill in the debug table's guid
+    debug_table_guid[ 0] = 0x77;
+    debug_table_guid[ 1] = 0x2E;
+    debug_table_guid[ 2] = 0x15;
+    debug_table_guid[ 3] = 0x49;
+    debug_table_guid[ 4] = 0xDA;
+    debug_table_guid[ 5] = 0x1A;
+    debug_table_guid[ 6] = 0x64;
+    debug_table_guid[ 7] = 0x47;
+    debug_table_guid[ 8] = 0xB7;
+    debug_table_guid[ 9] = 0xA2;
+    debug_table_guid[10] = 0x7A;
+    debug_table_guid[11] = 0xFE;
+    debug_table_guid[12] = 0xFE;
+    debug_table_guid[13] = 0xD9;
+    debug_table_guid[14] = 0x5E;
+    debug_table_guid[15] = 0x8B;
+
+    configuration_table_entries = *(unsigned long *)(system_table + 64);
+    configuration_table         = *(unsigned long *)(system_table + 68);
+
+    for (index = 0; index < configuration_table_entries; index++)
+    {
+        if (compare_guid(configuration_table, debug_table_guid) == 0)
+        {
+            return *(unsigned long *)(configuration_table + 16);
+        }
+
+        configuration_table += 20;
+    }
+
+    return 0;
+}
+.
+
+define /R int valid_pe_header(header)
+        unsigned char *header;
+{
+    if ((header[0x00] == 'M') &&
+        (header[0x01] == 'Z') &&
+        (header[0x80] == 'P') &&
+        (header[0x81] == 'E'))
+    {
+        return 1;
+    }
+
+    return 0;
+}
+.
+
+define /R unsigned long pe_headersize(header)
+        unsigned char *header;
+{
+    unsigned long *size;
+
+    size = header + 0x00AC;
+
+    return *size;
+}
+.
+
+define /R unsigned char *pe_filename(header)
+        unsigned char *header;
+{
+    unsigned long *debugOffset;
+    unsigned char *stringOffset;
+
+    if (valid_pe_header(header))
+    {
+        debugOffset  = header + 0x0128;
+        stringOffset = header + *debugOffset + 0x002C;
+
+        return stringOffset;
+    }
+
+    return 0;
+}
+.
+
+define /R int char_is_valid(c)
+        unsigned char c;
+{
+    if (c >= 32 && c < 127)
+    	return 1;
+
+    return 0;
+}
+.
+
+define /R write_symbols_file(filename, mem_start, mem_size)
+    unsigned char *filename;
+    unsigned char *mem_start;
+    unsigned long mem_size;
+{
+    unsigned char *system_table;
+    unsigned char *debug_info_table_header;
+    unsigned char *debug_info_table;
+    unsigned long debug_info_table_size;
+    unsigned long index;
+    unsigned char *debug_image_info;
+    unsigned char *loaded_image_protocol;
+    unsigned char *image_base;
+    unsigned char *debug_filename;
+    unsigned long header_size;
+    int           status;
+
+    system_table = find_system_table(mem_start, mem_size);
+    if (system_table == 0)
+    {
+        return;
+    }
+
+    status = fopen(88, filename, "w");
+
+    debug_info_table_header = find_debug_info_table_header(system_table);
+
+    debug_info_table      = *(unsigned long *)(debug_info_table_header + 8);
+    debug_info_table_size = *(unsigned long *)(debug_info_table_header + 4);
+
+    for (index = 0; index < (debug_info_table_size * 4); index += 4)
+    {
+        debug_image_info = *(unsigned long *)(debug_info_table + index);
+
+        if (debug_image_info == 0)
+        {
+            break;
+        }
+
+        loaded_image_protocol = *(unsigned long *)(debug_image_info + 4);
+
+        image_base = *(unsigned long *)(loaded_image_protocol + 32);
+
+        debug_filename = pe_filename(image_base);
+        header_size    = pe_headersize(image_base);
+
+        $fprintf 88, "%s 0x%08x\n", debug_filename, image_base + header_size$;
+    }
+
+
+    fclose(88);
+}
+.
+
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_unload_symbols.inc b/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_unload_symbols.inc
new file mode 100644
index 0000000000..cade1f9acf
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_unload_symbols.inc
@@ -0,0 +1,112 @@
+//
+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+//
+//  SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+error = continue
+
+unload
+
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+
+error = abort
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/trace32_load_symbols.cmm b/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/trace32_load_symbols.cmm
new file mode 100644
index 0000000000..83fd991db6
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/trace32_load_symbols.cmm
@@ -0,0 +1,205 @@
+//
+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+//  
+//  SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+  ENTRY &ram_start &ram_size
+  
+  ;If system is running then stop the execution so we can load symbols.
+  break
+  
+  ;Reset all windows
+  WINPAGE.RESET
+  
+  ;Create AREA to display the symbols we are loading.
+  AREA.Reset
+  AREA.Create SYMBOL 300. 100.
+  AREA.View SYMBOL
+  AREA.Select SYMBOL
+  SYS.Option BE OFF
+ 
+  ;Added based on suggestion from Lauterbach support.
+  MMU.TABLEWALK ON
+  MMU.ON
+
+  ;Load symbols.
+  GOSUB load_symbols &ram_start &ram_size
+
+  ;Open some windows and enable semihosting.
+  TOOLBAR ON
+  STATUSBAR ON
+  WINPAGE.RESET
+   
+  WINCLEAR
+  WINPOS 0.0 17.0 72. 13. 0. 0. W000
+  SYStem
+   
+  WINPOS 0.0 0.0 110. 55. 13. 1. W001
+  WINTABS 10. 10. 25. 62.
+  Data.List
+   
+  WINPAGE.SELECT P000
+
+  //Enable semihosting
+  System.Option.BigEndian OFF
+
+  tronchip.set swi on		// ARM9/10/11 variant
+
+  // configure and open semihosting channel
+  winpos 50% 50% 50% 50%
+  term.heapinfo 0 0x20000 0x30000 0x20000
+  term.method armswi
+  term.mode string
+  term.gate
+
+  WINPOS 115.0 0. 70. 35. 0. 1. W002
+  Var.Local %HEX
+  
+  WINPOS 115.10 45. 48. 9. 0. 0. W003
+  Register
+    
+  END
+
+find_system_table:
+  ENTRY &mem_start &mem_size
+  &mem_ptr=&mem_start+&mem_size
+  RPT    
+  (
+    &mem_ptr=&mem_ptr-0x400000  // 4 MB
+    &word1=Data.LONG(D:&mem_ptr)
+    &word2=Data.LONG(D:&mem_ptr+0x04)
+    IF &word1==0x20494249
+    (
+      IF &word2==0x54535953
+      (
+        &result=Data.LONG(D:&mem_ptr+0x08)
+        RETURN &result
+      )
+    )
+  )
+  WHILE &mem_ptr>&mem_start
+  &result=0
+  RETURN &result
+
+compare_guid:
+  ENTRY &guid
+  IF Data.LONG(D:&guid)==0x49152E77
+  (
+    IF Data.LONG(D:&guid+0x04)==0x47641ADA
+    (
+      IF Data.LONG(D:&guid+0x08)==0xFE7AA2B7
+      (
+        IF Data.LONG(D:&guid+0x0C)==0x8B5ED9FE
+        (
+          RETURN 0
+        )
+      )
+    )
+  )
+  RETURN 1  
+
+find_debug_info_table_header:
+  ENTRY &system_table
+  &config_table_entries=Data.LONG(D:&system_table+0x40)
+  &config_table_pointer=Data.LONG(D:&system_table+0x44)
+  RPT &config_table_entries
+  (
+    GOSUB compare_guid &config_table_pointer
+    ENTRY &result
+    IF &result==0
+    (
+      &result=Data.LONG(D:&config_table_pointer+0x10)
+      RETURN &result
+    )  
+    &config_table_pointer=&config_table_pointer+0x14
+  )
+  RETURN 0;
+
+valid_pe_header:
+  ENTRY &header
+  IF Data.BYTE(D:&header+0x00)==0x4D
+  (
+    IF Data.BYTE(D:&header+0x01)==0x5A
+    (
+      IF Data.BYTE(D:&header+0x80)==0x50
+      (
+        IF Data.BYTE(D:&header+0x81)==0x45
+        (
+          RETURN 1
+        )
+      )
+    )
+  )
+  RETURN 0
+
+get_file_string:
+  ENTRY &stringOffset
+
+  local &string
+
+  &more_string=data.string(d:&stringOffset)
+
+  if (string.len("&more_string")>=128.)
+  (
+    &string="&string"+"&more_string"
+    &stringOffset=&stringOffset+string.len("&more_string")
+
+    //Get remaining file string
+    GOSUB get_file_string &stringOffset
+    ENTRY &more_string
+    &string="&string"+"&more_string"
+  )
+  else
+  (
+    &string="&string"+"&more_string"
+    &more_string=""
+  )
+  RETURN &string
+ 
+load_symbol_file:
+  ENTRY &header &load_address
+  GOSUB valid_pe_header &header
+  ENTRY &result
+ 
+  IF &result==1
+  (
+    &debugOffset=Data.LONG(D:&header+0x0128)
+    &stringOffset=&header+&debugOffset+0x002C
+    
+    GOSUB get_file_string &stringOffset
+    ENTRY &filestring
+        
+    PRINT "&filestring 0x" &load_address
+    TDIAG Data.load.elf &filestring &load_address /nocode /noclear
+  )
+  RETURN
+
+pe_headersize:
+  ENTRY &header;
+  RETURN Data.LONG(D:&header+0x00AC)
+
+load_symbols:
+  ENTRY &mem_start &mem_size
+  GOSUB find_system_table &mem_start &mem_size
+  ENTRY &system_table
+  GOSUB find_debug_info_table_header &system_table
+  ENTRY &debug_info_table_header
+  &debug_info_table=Data.LONG(D:&debug_info_table_header+0x08)
+  &debug_info_table_size=Data.LONG(D:&debug_info_table_header+0x04)
+  &index=0
+  RPT &debug_info_table_size
+  (
+    &debug_image_info=Data.LONG(D:&debug_info_table+&index)
+    IF &debug_image_info==0
+      RETURN        
+    &loaded_image_protocol=Data.LONG(D:&debug_image_info+0x04);
+    &image_base=Data.LONG(D:&loaded_image_protocol+0x20);
+    GOSUB pe_headersize &image_base
+    ENTRY &header_size
+    &image_load_address=&image_base+&header_size
+    GOSUB load_symbol_file &image_base &image_load_address
+    &index=&index+0x4
+  )
+    
+  RETURN
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/trace32_load_symbols_cygwin.cmm b/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/trace32_load_symbols_cygwin.cmm
new file mode 100644
index 0000000000..87045e8769
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/trace32_load_symbols_cygwin.cmm
@@ -0,0 +1,182 @@
+//
+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+//  
+//  SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+  ENTRY &ram_start &ram_size
+
+  ;If system is running then stop the execution so we can load symbols.
+  break
+  
+  ;Reset all windows
+  WINPAGE.RESET
+  
+  AREA.Reset
+  AREA.Create SYMBOL 300. 100.
+  AREA.View SYMBOL
+  AREA.Select SYMBOL
+  SYS.Option BE OFF
+ 
+  ; Added based on suggestion from Lauterbach support.
+  MMU.TABLEWALK ON
+  MMU.ON
+
+  GOSUB load_symbols &ram_start &ram_size
+
+  ;Open some windows.
+  WINPOS 83.125 29.063 48. 9. 0. 0. W003
+  Register
+
+  WINPOS 83.25 10. 48. 9. 0. 1. W002
+  Var.Local
+  
+  END
+
+find_system_table:
+  ENTRY &mem_start &mem_size
+  &mem_ptr=&mem_start+&mem_size
+  RPT    
+  (
+    &mem_ptr=&mem_ptr-0x400000  // 4 MB
+    &word1=Data.LONG(D:&mem_ptr)
+    &word2=Data.LONG(D:&mem_ptr+0x04)
+    IF &word1==0x20494249
+    (
+      IF &word2==0x54535953
+      (
+        &result=Data.LONG(D:&mem_ptr+0x08)
+        RETURN &result
+      )
+    )
+  )
+  WHILE &mem_ptr>&mem_start
+  &result=0
+  RETURN &result
+
+compare_guid:
+  ENTRY &guid
+  IF Data.LONG(D:&guid)==0x49152E77
+  (
+    IF Data.LONG(D:&guid+0x04)==0x47641ADA
+    (
+      IF Data.LONG(D:&guid+0x08)==0xFE7AA2B7
+      (
+        IF Data.LONG(D:&guid+0x0C)==0x8B5ED9FE
+        (
+          RETURN 0
+        )
+      )
+    )
+  )
+  RETURN 1  
+
+find_debug_info_table_header:
+  ENTRY &system_table
+  &config_table_entries=Data.LONG(D:&system_table+0x40)
+  &config_table_pointer=Data.LONG(D:&system_table+0x44)
+  RPT &config_table_entries
+  (
+    GOSUB compare_guid &config_table_pointer
+    ENTRY &result
+    IF &result==0
+    (
+      &result=Data.LONG(D:&config_table_pointer+0x10)
+      RETURN &result
+    )  
+    &config_table_pointer=&config_table_pointer+0x14
+  )
+  RETURN 0;
+
+valid_pe_header:
+  ENTRY &header
+  IF Data.BYTE(D:&header+0x00)==0x4D
+  (
+    IF Data.BYTE(D:&header+0x01)==0x5A
+    (
+      IF Data.BYTE(D:&header+0x80)==0x50
+      (
+        IF Data.BYTE(D:&header+0x81)==0x45
+        (
+          RETURN 1
+        )
+      )
+    )
+  )
+  RETURN 0
+
+get_file_string:
+  ENTRY &stringOffset
+
+  local &string
+  
+  &more_string=data.string(d:&stringOffset)
+
+  if (string.len("&more_string")>=128.)
+  (
+    &string="&string"+"&more_string"
+    &stringOffset=&stringOffset+string.len("&more_string")
+
+    //Get remaining file string
+    GOSUB get_file_string &stringOffset
+    ENTRY &more_string
+    &string="&string"+"&more_string"
+  )
+  else
+  (
+    &string="&string"+"&more_string"
+    &more_string=""
+  )
+  RETURN &string
+ 
+load_symbol_file:
+  ENTRY &header &load_address
+  GOSUB valid_pe_header &header
+  ENTRY &result
+ 
+  IF &result==1
+  (
+    &debugOffset=Data.LONG(D:&header+0x0128)
+    &stringOffset=&header+&debugOffset+0x002C
+    
+    &stringOffset=&stringOffset+11.
+
+    GOSUB get_file_string &stringOffset
+    ENTRY &filestring
+  
+    &filestring="c:"+"&filestring"
+
+    PRINT "&filestring 0x" &load_address
+    Data.load.elf &filestring &load_address /nocode /noclear
+  )
+  RETURN
+
+pe_headersize:
+  ENTRY &header;
+  RETURN Data.LONG(D:&header+0x00AC)
+
+load_symbols:
+  ENTRY &mem_start &mem_size
+  GOSUB find_system_table &mem_start &mem_size
+  ENTRY &system_table
+  GOSUB find_debug_info_table_header &system_table
+  ENTRY &debug_info_table_header
+  &debug_info_table=Data.LONG(D:&debug_info_table_header+0x08)
+  &debug_info_table_size=Data.LONG(D:&debug_info_table_header+0x04)
+  &index=0
+  RPT &debug_info_table_size
+  (
+    &debug_image_info=Data.LONG(D:&debug_info_table+&index)
+    IF &debug_image_info==0
+      RETURN        
+    &loaded_image_protocol=Data.LONG(D:&debug_image_info+0x04);
+    &image_base=Data.LONG(D:&loaded_image_protocol+0x20);
+    GOSUB pe_headersize &image_base
+    ENTRY &header_size
+    &image_load_address=&image_base+&header_size
+    GOSUB load_symbol_file &image_base &image_load_address
+    &index=&index+0x4
+  )
+    
+  RETURN
+  
\ No newline at end of file
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Include/BeagleBoard.h b/Platform/BeagleBoard/BeagleBoardPkg/Include/BeagleBoard.h
new file mode 100644
index 0000000000..860685b764
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Include/BeagleBoard.h
@@ -0,0 +1,173 @@
+/** @file
+*  Header defining the BeagleBoard constants (Base addresses, sizes, flags)
+*
+*  Copyright (c) 2011, ARM Limited. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#ifndef __BEAGLEBOARD_PLATFORM_H__
+#define __BEAGLEBOARD_PLATFORM_H__
+
+// DDR attributes
+#define DDR_ATTRIBUTES_CACHED                ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
+#define DDR_ATTRIBUTES_UNCACHED              ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
+
+// SoC registers. L3 interconnects
+#define SOC_REGISTERS_L3_PHYSICAL_BASE       0x68000000
+#define SOC_REGISTERS_L3_PHYSICAL_LENGTH     0x08000000
+#define SOC_REGISTERS_L3_ATTRIBUTES          ARM_MEMORY_REGION_ATTRIBUTE_DEVICE
+
+// SoC registers. L4 interconnects
+#define SOC_REGISTERS_L4_PHYSICAL_BASE       0x48000000
+#define SOC_REGISTERS_L4_PHYSICAL_LENGTH     0x08000000
+#define SOC_REGISTERS_L4_ATTRIBUTES          ARM_MEMORY_REGION_ATTRIBUTE_DEVICE
+
+
+#if 0
+/*******************************************
+// Platform Memory Map
+*******************************************/
+
+// Can be NOR, DOC, DRAM, SRAM
+#define ARM_EB_REMAP_BASE                     0x00000000
+#define ARM_EB_REMAP_SZ                       0x04000000
+
+// Motherboard Peripheral and On-chip peripheral
+#define ARM_EB_SMB_MB_ON_CHIP_PERIPH_BASE     0x10000000
+#define ARM_EB_SMB_MB_ON_CHIP_PERIPH_SZ       0x00100000
+#define ARM_EB_BOARD_PERIPH_BASE              0x10000000
+//#define ARM_EB_CHIP_PERIPH_BASE             0x10020000
+
+// SMC
+#define ARM_EB_SMC_BASE                       0x40000000
+#define ARM_EB_SMC_SZ                         0x20000000
+
+// NOR Flash 1
+#define ARM_EB_SMB_NOR_BASE                   0x40000000
+#define ARM_EB_SMB_NOR_SZ                     0x04000000 /* 64 MB */
+// DOC Flash
+#define ARM_EB_SMB_DOC_BASE                   0x44000000
+#define ARM_EB_SMB_DOC_SZ                     0x04000000 /* 64 MB */
+// SRAM
+#define ARM_EB_SMB_SRAM_BASE                  0x48000000
+#define ARM_EB_SMB_SRAM_SZ                    0x02000000 /* 32 MB */
+// USB, Ethernet, VRAM
+#define ARM_EB_SMB_PERIPH_BASE                0x4E000000
+//#define ARM_EB_SMB_PERIPH_VRAM              0x4C000000
+#define ARM_EB_SMB_PERIPH_SZ                  0x02000000 /* 32 MB */
+
+// DRAM
+#define ARM_EB_DRAM_BASE                      0x70000000
+#define ARM_EB_DRAM_SZ                        0x10000000
+
+// Logic Tile
+#define ARM_EB_LOGIC_TILE_BASE                0xC0000000
+#define ARM_EB_LOGIC_TILE_SZ                  0x40000000
+
+/*******************************************
+// Motherboard peripherals
+*******************************************/
+
+// Define MotherBoard SYS flags offsets (from ARM_EB_BOARD_PERIPH_BASE)
+#define ARM_EB_SYS_FLAGS_REG                  (ARM_EB_BOARD_PERIPH_BASE + 0x00030)
+#define ARM_EB_SYS_FLAGS_SET_REG              (ARM_EB_BOARD_PERIPH_BASE + 0x00030)
+#define ARM_EB_SYS_FLAGS_CLR_REG              (ARM_EB_BOARD_PERIPH_BASE + 0x00034)
+#define ARM_EB_SYS_FLAGS_NV_REG               (ARM_EB_BOARD_PERIPH_BASE + 0x00038)
+#define ARM_EB_SYS_FLAGS_NV_SET_REG           (ARM_EB_BOARD_PERIPH_BASE + 0x00038)
+#define ARM_EB_SYS_FLAGS_NV_CLR_REG           (ARM_EB_BOARD_PERIPH_BASE + 0x0003C)
+#define ARM_EB_SYS_CLCD                       (ARM_EB_BOARD_PERIPH_BASE + 0x00050)
+#define ARM_EB_SYS_PROCID0_REG                (ARM_EB_BOARD_PERIPH_BASE + 0x00084)
+#define ARM_EB_SYS_PROCID1_REG                (ARM_EB_BOARD_PERIPH_BASE + 0x00088)
+#define ARM_EB_SYS_CFGDATA_REG                (ARM_EB_BOARD_PERIPH_BASE + 0x000A0)
+#define ARM_EB_SYS_CFGCTRL_REG                (ARM_EB_BOARD_PERIPH_BASE + 0x000A4)
+#define ARM_EB_SYS_CFGSTAT_REG                (ARM_EB_BOARD_PERIPH_BASE + 0x000A8)
+
+// SP810 Controller
+#define SP810_CTRL_BASE                       (ARM_EB_BOARD_PERIPH_BASE + 0x01000)
+
+// SYSTRCL Register
+#define ARM_EB_SYSCTRL                        0x10001000
+
+// Uart0
+#define PL011_CONSOLE_UART_BASE               (ARM_EB_BOARD_PERIPH_BASE + 0x09000)
+#define PL011_CONSOLE_UART_SPEED              115200
+
+// SP804 Timer Bases
+#define SP804_TIMER0_BASE                     (ARM_EB_BOARD_PERIPH_BASE + 0x11000)
+#define SP804_TIMER1_BASE                     (ARM_EB_BOARD_PERIPH_BASE + 0x11020)
+#define SP804_TIMER2_BASE                     (ARM_EB_BOARD_PERIPH_BASE + 0x12000)
+#define SP804_TIMER3_BASE                     (ARM_EB_BOARD_PERIPH_BASE + 0x12020)
+
+// PL301 RTC
+#define PL031_RTC_BASE                        (ARM_EB_BOARD_PERIPH_BASE + 0x17000)
+
+// Dynamic Memory Controller Base
+#define ARM_EB_DMC_BASE                       0x10018000
+
+// Static Memory Controller Base
+#define ARM_EB_SMC_CTRL_BASE                  0x10080000
+
+#define PL111_CLCD_BASE                       0x10020000
+//TODO: FIXME ... Reserved the memory in UEFI !!! Otherwise risk of corruption
+#define PL111_CLCD_VRAM_BASE                  0x78000000
+
+#define ARM_EB_SYS_OSCCLK4                    0x1000001C
+
+
+/*// System Configuration Controller register Base addresses
+//#define ARM_EB_SYS_CFG_CTRL_BASE                0x100E2000
+#define ARM_EB_SYS_CFGRW0_REG                   0x100E2000
+#define ARM_EB_SYS_CFGRW1_REG                   0x100E2004
+#define ARM_EB_SYS_CFGRW2_REG                   0x100E2008
+
+#define ARM_EB_CFGRW1_REMAP_NOR0                0
+#define ARM_EB_CFGRW1_REMAP_NOR1                (1 << 28)
+#define ARM_EB_CFGRW1_REMAP_EXT_AXI             (1 << 29)
+#define ARM_EB_CFGRW1_REMAP_DRAM                (1 << 30)
+
+// PL301 Fast AXI Base Address
+#define ARM_EB_FAXI_BASE                        0x100E9000
+
+// L2x0 Cache Controller Base Address
+//#define ARM_EB_L2x0_CTLR_BASE                   0x1E00A000*/
+
+
+// PL031 RTC - Other settings
+#define PL031_PPM_ACCURACY                      300000000
+
+/*******************************************
+// Interrupt Map
+*******************************************/
+
+// Timer Interrupts
+#define TIMER01_INTERRUPT_NUM                34
+#define TIMER23_INTERRUPT_NUM                35
+
+
+/*******************************************
+// EFI Memory Map in Permanent Memory (DRAM)
+*******************************************/
+
+// This region is allocated at the bottom of the DRAM. It will be used
+// for fixed address allocations such as Vector Table
+#define ARM_EB_EFI_FIX_ADDRESS_REGION_SZ        SIZE_8MB
+
+// This region is the memory declared to PEI as permanent memory for PEI
+// and DXE. EFI stacks and heaps will be declared in this region.
+#define ARM_EB_EFI_MEMORY_REGION_SZ             0x1000000
+#endif
+
+typedef enum {
+  REVISION_XM,
+  REVISION_UNKNOWN0,
+  REVISION_UNKNOWN1,
+  REVISION_UNKNOWN2,
+  REVISION_UNKNOWN3,
+  REVISION_C4,
+  REVISION_C123,
+  REVISION_AB,
+} BEAGLEBOARD_REVISION;
+
+#endif
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoard.c b/Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoard.c
new file mode 100644
index 0000000000..70a5107974
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoard.c
@@ -0,0 +1,115 @@
+/** @file
+*
+*  Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include <Library/IoLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+
+#include <Omap3530/Omap3530.h>
+#include <BeagleBoard.h>
+
+VOID
+PadConfiguration (
+  BEAGLEBOARD_REVISION Revision
+  );
+
+VOID
+ClockInit (
+  VOID
+  );
+
+/**
+  Detect board revision
+
+  @return Board revision
+**/
+BEAGLEBOARD_REVISION
+BeagleBoardGetRevision (
+  VOID
+  )
+{
+  UINT32 OldPinDir;
+  UINT32 Revision;
+
+  // Read GPIO 171, 172, 173
+  OldPinDir = MmioRead32 (GPIO6_BASE + GPIO_OE);
+  MmioWrite32(GPIO6_BASE + GPIO_OE, (OldPinDir | BIT11 | BIT12 | BIT13));
+  Revision = MmioRead32 (GPIO6_BASE + GPIO_DATAIN);
+
+  // Restore I/O settings
+  MmioWrite32 (GPIO6_BASE + GPIO_OE, OldPinDir);
+
+  return (BEAGLEBOARD_REVISION)((Revision >> 11) & 0x7);
+}
+
+/**
+  Return the current Boot Mode
+
+  This function returns the boot reason on the platform
+
+**/
+EFI_BOOT_MODE
+ArmPlatformGetBootMode (
+  VOID
+  )
+{
+  return BOOT_WITH_FULL_CONFIGURATION;
+}
+
+/**
+  Initialize controllers that must setup at the early stage
+
+  Some peripherals must be initialized in Secure World.
+  For example, some L2x0 requires to be initialized in Secure World
+
+**/
+RETURN_STATUS
+ArmPlatformInitialize (
+  IN  UINTN                     MpId
+  )
+{
+  BEAGLEBOARD_REVISION Revision;
+
+  Revision = BeagleBoardGetRevision();
+
+  // Set up Pin muxing.
+  PadConfiguration (Revision);
+
+  // Set up system clocking
+  ClockInit ();
+
+  // Turn off the functional clock for Timer 3
+  MmioAnd32 (CM_FCLKEN_PER, 0xFFFFFFFF ^ CM_ICLKEN_PER_EN_GPT3_ENABLE );
+  ArmDataSynchronizationBarrier ();
+
+  // Clear IRQs
+  MmioWrite32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWIRQAGR);
+  ArmDataSynchronizationBarrier ();
+
+  return RETURN_SUCCESS;
+}
+
+VOID
+ArmPlatformGetPlatformPpiList (
+  OUT UINTN                   *PpiListSize,
+  OUT EFI_PEI_PPI_DESCRIPTOR  **PpiList
+  )
+{
+  *PpiListSize = 0;
+  *PpiList = NULL;
+}
+
+UINTN
+ArmPlatformGetCorePosition (
+  IN UINTN MpId
+  )
+{
+  return 1;
+}
+
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoardHelper.S b/Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoardHelper.S
new file mode 100644
index 0000000000..313763a5eb
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoardHelper.S
@@ -0,0 +1,41 @@
+#
+#  Copyright (c) 2012-2013, ARM Limited. All rights reserved.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+
+#include <AsmMacroIoLib.h>
+#include <AutoGen.h>
+
+.text
+.align 2
+
+GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore)
+GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId)
+GCC_ASM_EXPORT(ArmPlatformPeiBootAction)
+
+GCC_ASM_IMPORT(ArmReadMpidr)
+
+//UINTN
+//ArmPlatformIsPrimaryCore (
+//  IN UINTN MpId
+//  );
+ASM_PFX(ArmPlatformIsPrimaryCore):
+  // BeagleBoard has a single core. We must always return 1.
+  mov   r0, #1
+  bx    lr
+
+ASM_PFX(ArmPlatformPeiBootAction):
+  bx    lr
+
+//UINTN
+//ArmPlatformGetPrimaryCoreMpId (
+//  VOID
+//  );
+ASM_PFX(ArmPlatformGetPrimaryCoreMpId):
+  // The BeagleBoard is a uniprocessor platform. The MPIDR of primary core is
+  // always the MPIDR of the calling CPU.
+  b   ASM_PFX(ArmReadMpidr)
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoardHelper.asm b/Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoardHelper.asm
new file mode 100644
index 0000000000..884f567cef
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoardHelper.asm
@@ -0,0 +1,47 @@
+//
+//  Copyright (c) 2012-2013, ARM Limited. All rights reserved.
+//
+//  SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+
+#include <AsmMacroIoLib.h>
+#include <Base.h>
+
+#include <AutoGen.h>
+
+  INCLUDE AsmMacroIoLib.inc
+
+  EXPORT    ArmPlatformPeiBootAction
+  EXPORT    ArmPlatformIsPrimaryCore
+  EXPORT    ArmPlatformGetPrimaryCoreMpId
+
+  IMPORT    ArmReadMpidr
+
+  AREA BeagleBoardHelper, CODE, READONLY
+
+//UINTN
+//ArmPlatformIsPrimaryCore (
+//  IN UINTN MpId
+//  );
+ArmPlatformIsPrimaryCore FUNCTION
+  // BeagleBoard has a single core. We must always return 1.
+  mov   r0, #1
+  bx    lr
+  ENDFUNC
+
+ArmPlatformPeiBootAction FUNCTION
+  bx    lr
+  ENDFUNC
+
+//UINTN
+//ArmPlatformGetPrimaryCoreMpId (
+//  VOID
+//  );
+ArmPlatformGetPrimaryCoreMpId FUNCTION
+  // The BeagleBoard is a uniprocessor platform. The MPIDR of primary core is
+  // always the MPIDR of the calling CPU.
+  b     ArmReadMpidr
+  ENDFUNC
+
+  END
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoardLib.inf b/Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoardLib.inf
new file mode 100644
index 0000000000..53f75a3ccc
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoardLib.inf
@@ -0,0 +1,48 @@
+#/* @file
+#  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+#  Copyright (c) 2016, Linaro Ltd. All rights reserved.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#*/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BeagleBoardLib
+  FILE_GUID                      = 736343a0-1d96-11e0-aaaa-0002a5d5c51b
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ArmPlatformLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+  BeagleBoardPkg/BeagleBoardPkg.dec
+
+[LibraryClasses]
+  IoLib
+  ArmLib
+  MemoryAllocationLib
+
+[Sources.common]
+  BeagleBoardHelper.asm  | RVCT
+  BeagleBoardHelper.S    | GCC
+  BeagleBoard.c
+  BeagleBoardMem.c
+  PadConfiguration.c
+  Clock.c
+  BeagleBoardHelper.S    | GCC
+  BeagleBoardHelper.asm  | RVCT
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdFdBaseAddress
+  gArmTokenSpaceGuid.PcdFdSize
+
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdSystemMemorySize
+
+  gEmbeddedTokenSpaceGuid.PcdInterruptBaseAddress
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoardMem.c b/Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoardMem.c
new file mode 100644
index 0000000000..3bf67d452d
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoardMem.c
@@ -0,0 +1,74 @@
+/** @file
+*
+*  Copyright (c) 2011, ARM Limited. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/IoLib.h>
+
+#include <BeagleBoard.h>
+
+#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS          4
+
+/**
+  Return the Virtual Memory Map of your platform
+
+  This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform.
+
+  @param[out]   VirtualMemoryMap    Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to-
+                                    Virtual Memory mapping. This array must be ended by a zero-filled
+                                    entry
+
+**/
+VOID
+ArmPlatformGetVirtualMemoryMap (
+  IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap
+  )
+{
+  ARM_MEMORY_REGION_ATTRIBUTES  CacheAttributes;
+  UINTN                         Index = 0;
+  ARM_MEMORY_REGION_DESCRIPTOR  *VirtualMemoryTable;
+
+  ASSERT(VirtualMemoryMap != NULL);
+
+  VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages(EFI_SIZE_TO_PAGES (sizeof(ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS));
+  if (VirtualMemoryTable == NULL) {
+    return;
+  }
+
+  CacheAttributes = DDR_ATTRIBUTES_CACHED;
+
+  // ReMap (Either NOR Flash or DRAM)
+  VirtualMemoryTable[Index].PhysicalBase = PcdGet64 (PcdSystemMemoryBase);
+  VirtualMemoryTable[Index].VirtualBase  = PcdGet64 (PcdSystemMemoryBase);
+  VirtualMemoryTable[Index].Length       = PcdGet64 (PcdSystemMemorySize);
+  VirtualMemoryTable[Index].Attributes   = CacheAttributes;
+
+  // SOC Registers. L3 interconnects
+  VirtualMemoryTable[++Index].PhysicalBase = SOC_REGISTERS_L3_PHYSICAL_BASE;
+  VirtualMemoryTable[Index].VirtualBase  = SOC_REGISTERS_L3_PHYSICAL_BASE;
+  VirtualMemoryTable[Index].Length       = SOC_REGISTERS_L3_PHYSICAL_LENGTH;
+  VirtualMemoryTable[Index].Attributes   = SOC_REGISTERS_L3_ATTRIBUTES;
+
+  // SOC Registers. L4 interconnects
+  VirtualMemoryTable[++Index].PhysicalBase = SOC_REGISTERS_L4_PHYSICAL_BASE;
+  VirtualMemoryTable[Index].VirtualBase  = SOC_REGISTERS_L4_PHYSICAL_BASE;
+  VirtualMemoryTable[Index].Length       = SOC_REGISTERS_L4_PHYSICAL_LENGTH;
+  VirtualMemoryTable[Index].Attributes   = SOC_REGISTERS_L4_ATTRIBUTES;
+
+  // End of Table
+  VirtualMemoryTable[++Index].PhysicalBase = 0;
+  VirtualMemoryTable[Index].VirtualBase  = 0;
+  VirtualMemoryTable[Index].Length       = 0;
+  VirtualMemoryTable[Index].Attributes   = (ARM_MEMORY_REGION_ATTRIBUTES)0;
+
+  ASSERT((Index + 1) == MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS);
+
+  *VirtualMemoryMap = VirtualMemoryTable;
+}
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/Clock.c b/Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/Clock.c
new file mode 100644
index 0000000000..f7bf6e15e3
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/Clock.c
@@ -0,0 +1,63 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+
+#include <Omap3530/Omap3530.h>
+
+VOID
+ClockInit (
+  VOID
+  )
+{
+  //DPLL1 - DPLL4 are configured part of Configuration header which OMAP3 ROM parses.
+
+  // Enable PLL5 and set to 120 MHz as a reference clock.
+  MmioWrite32 (CM_CLKSEL4_PLL, CM_CLKSEL_PLL_MULT(120) | CM_CLKSEL_PLL_DIV(13));
+  MmioWrite32 (CM_CLKSEL5_PLL, CM_CLKSEL_DIV_120M(1));
+  MmioWrite32 (CM_CLKEN2_PLL, CM_CLKEN_FREQSEL_075_100 | CM_CLKEN_ENABLE);
+
+  // Turn on functional & interface clocks to the USBHOST power domain
+  MmioOr32(CM_FCLKEN_USBHOST, CM_FCLKEN_USBHOST_EN_USBHOST2_ENABLE
+                              | CM_FCLKEN_USBHOST_EN_USBHOST1_ENABLE);
+  MmioOr32(CM_ICLKEN_USBHOST, CM_ICLKEN_USBHOST_EN_USBHOST_ENABLE);
+
+  // Turn on functional & interface clocks to the USBTLL block.
+  MmioOr32(CM_FCLKEN3_CORE, CM_FCLKEN3_CORE_EN_USBTLL_ENABLE);
+  MmioOr32(CM_ICLKEN3_CORE, CM_ICLKEN3_CORE_EN_USBTLL_ENABLE);
+
+  // Turn on functional & interface clocks to MMC1 and I2C1 modules.
+  MmioOr32(CM_FCLKEN1_CORE, CM_FCLKEN1_CORE_EN_MMC1_ENABLE
+                            | CM_FCLKEN1_CORE_EN_I2C1_ENABLE);
+  MmioOr32(CM_ICLKEN1_CORE, CM_ICLKEN1_CORE_EN_MMC1_ENABLE
+                            | CM_ICLKEN1_CORE_EN_I2C1_ENABLE);
+
+  // Turn on functional & interface clocks to various Peripherals.
+  MmioOr32(CM_FCLKEN_PER, CM_FCLKEN_PER_EN_UART3_ENABLE
+                          | CM_FCLKEN_PER_EN_GPT4_ENABLE
+                          | CM_FCLKEN_PER_EN_GPIO2_ENABLE
+                          | CM_FCLKEN_PER_EN_GPIO3_ENABLE
+                          | CM_FCLKEN_PER_EN_GPIO4_ENABLE
+                          | CM_FCLKEN_PER_EN_GPIO5_ENABLE
+                          | CM_FCLKEN_PER_EN_GPIO6_ENABLE);
+  MmioOr32(CM_ICLKEN_PER, CM_ICLKEN_PER_EN_UART3_ENABLE
+                          | CM_ICLKEN_PER_EN_GPT3_ENABLE
+                          | CM_ICLKEN_PER_EN_GPT4_ENABLE
+                          | CM_ICLKEN_PER_EN_GPIO2_ENABLE
+                          | CM_ICLKEN_PER_EN_GPIO3_ENABLE
+                          | CM_ICLKEN_PER_EN_GPIO4_ENABLE
+                          | CM_ICLKEN_PER_EN_GPIO5_ENABLE
+                          | CM_ICLKEN_PER_EN_GPIO6_ENABLE);
+
+  // Turn on functional & inteface clocks to various wakeup modules.
+  MmioOr32(CM_FCLKEN_WKUP, CM_FCLKEN_WKUP_EN_GPIO1_ENABLE
+                           | CM_FCLKEN_WKUP_EN_WDT2_ENABLE);
+  MmioOr32(CM_ICLKEN_WKUP, CM_ICLKEN_WKUP_EN_GPIO1_ENABLE
+                           | CM_ICLKEN_WKUP_EN_WDT2_ENABLE);
+}
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/PadConfiguration.c b/Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/PadConfiguration.c
new file mode 100644
index 0000000000..396cf67c0e
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/PadConfiguration.c
@@ -0,0 +1,316 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Omap3530/Omap3530.h>
+#include <BeagleBoard.h>
+
+#define NUM_PINS_SHARED 232
+#define NUM_PINS_ABC 6
+#define NUM_PINS_XM 12
+
+PAD_CONFIGURATION PadConfigurationTableShared[] = {
+  //Pin,           MuxMode,    PullConfig,                      InputEnable
+  { SDRC_D0,       MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D1,       MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D2,       MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D3,       MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D4,       MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D5,       MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D6,       MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D7,       MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D8,       MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D9,       MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D10,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D11,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D12,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D13,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D14,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D15,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D16,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D17,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D18,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D19,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D20,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D21,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D22,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D23,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D24,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D25,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D26,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D27,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D28,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D29,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D30,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_D31,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_CLK,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_DQS0,     MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_CKE0,     MUXMODE0,   PULL_UP_SELECTED,             INPUT  },
+  { SDRC_CKE1,     MUXMODE7,   PULL_DISABLED,                INPUT  },
+  { SDRC_DQS1,     MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_DQS2,     MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { SDRC_DQS3,     MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { GPMC_A1,       MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { GPMC_A2,       MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { GPMC_A3,       MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { GPMC_A4,       MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { GPMC_A5,       MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { GPMC_A6,       MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { GPMC_A7,       MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { GPMC_A8,       MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { GPMC_A9,       MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { GPMC_A10,      MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { GPMC_D0,       MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { GPMC_D1,       MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { GPMC_D2,       MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { GPMC_D3,       MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { GPMC_D4,       MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { GPMC_D5,       MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { GPMC_D6,       MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { GPMC_D7,       MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { GPMC_D8,       MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { GPMC_D9,       MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { GPMC_D10,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { GPMC_D11,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { GPMC_D12,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { GPMC_D13,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { GPMC_D14,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { GPMC_D15,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { GPMC_NCS0,     MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { GPMC_NCS1,     MUXMODE0,   PULL_UP_SELECTED,             OUTPUT },
+  { GPMC_NCS2,     MUXMODE0,   PULL_UP_SELECTED,             OUTPUT },
+  { GPMC_NCS3,     MUXMODE0,   PULL_UP_SELECTED,             OUTPUT },
+  { GPMC_NCS4,     MUXMODE0,   PULL_UP_SELECTED,             OUTPUT },
+  { GPMC_NCS5,     MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { GPMC_NCS6,     MUXMODE1,   PULL_DISABLED,                INPUT  },
+  { GPMC_NCS7,     MUXMODE1,   PULL_UP_SELECTED,             INPUT  },
+  { GPMC_CLK,      MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { GPMC_NADV_ALE, MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { GPMC_NOE,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { GPMC_NWE,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { GPMC_NBE0_CLE, MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { GPMC_NBE1,     MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { GPMC_NWP,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { GPMC_WAIT0,    MUXMODE0,   PULL_UP_SELECTED,             INPUT  },
+  { GPMC_WAIT1,    MUXMODE0,   PULL_UP_SELECTED,             INPUT  },
+  { GPMC_WAIT2,    MUXMODE0,   PULL_UP_SELECTED,             INPUT  },
+  { GPMC_WAIT3,    MUXMODE0,   PULL_UP_SELECTED,             INPUT  },
+  { DSS_PCLK,      MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_HSYNC,     MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_PSYNC,     MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_ACBIAS,    MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA0,     MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA1,     MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA2,     MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA3,     MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA4,     MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA5,     MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA6,     MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA7,     MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA8,     MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA9,     MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA10,    MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA11,    MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA12,    MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA13,    MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA14,    MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA15,    MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA16,    MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA17,    MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { CAM_HS,        MUXMODE0,   PULL_UP_SELECTED,             INPUT },
+  { CAM_VS,        MUXMODE0,   PULL_UP_SELECTED,             INPUT },
+  { CAM_XCLKA,     MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { CAM_PCLK,      MUXMODE0,   PULL_UP_SELECTED,             INPUT },
+  { CAM_FLD,       MUXMODE4,   PULL_DISABLED,                OUTPUT },
+  { CAM_D0,        MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { CAM_D1,        MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { CAM_D2,        MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { CAM_D3,        MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { CAM_D4,        MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { CAM_D5,        MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { CAM_D6,        MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { CAM_D7,        MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { CAM_D8,        MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { CAM_D9,        MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { CAM_D10,       MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { CAM_D11,       MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { CAM_XCLKB,     MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { CAM_WEN,       MUXMODE4,   PULL_DISABLED,                INPUT  },
+  { CAM_STROBE,    MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { CSI2_DX0,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { CSI2_DY0,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { CSI2_DX1,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { CSI2_DY1,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { MCBSP2_FSX,    MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { MCBSP2_CLKX,   MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { MCBSP2_DR,     MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { MCBSP2_DX,     MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { MMC1_CLK,      MUXMODE0,   PULL_UP_SELECTED,             OUTPUT },
+  { MMC1_CMD,      MUXMODE0,   PULL_UP_SELECTED,             INPUT  },
+  { MMC1_DAT0,     MUXMODE0,   PULL_UP_SELECTED,             INPUT  },
+  { MMC1_DAT1,     MUXMODE0,   PULL_UP_SELECTED,             INPUT  },
+  { MMC1_DAT2,     MUXMODE0,   PULL_UP_SELECTED,             INPUT  },
+  { MMC1_DAT3,     MUXMODE0,   PULL_UP_SELECTED,             INPUT  },
+  { MMC1_DAT4,     MUXMODE0,   PULL_UP_SELECTED,             INPUT  },
+  { MMC1_DAT5,     MUXMODE0,   PULL_UP_SELECTED,             INPUT  },
+  { MMC1_DAT6,     MUXMODE0,   PULL_UP_SELECTED,             INPUT  },
+  { MMC1_DAT7,     MUXMODE0,   PULL_UP_SELECTED,             INPUT  },
+  { MMC2_CLK,      MUXMODE4,   PULL_UP_SELECTED,             INPUT  },
+  { MMC2_CMD,      MUXMODE4,   PULL_UP_SELECTED,             INPUT  },
+  { MMC2_DAT0,     MUXMODE4,   PULL_UP_SELECTED,             INPUT  },
+  { MMC2_DAT1,     MUXMODE4,   PULL_UP_SELECTED,             INPUT  },
+  { MMC2_DAT2,     MUXMODE4,   PULL_UP_SELECTED,             INPUT  },
+  { MMC2_DAT3,     MUXMODE4,   PULL_UP_SELECTED,             INPUT  },
+  { MMC2_DAT4,     MUXMODE4,   PULL_UP_SELECTED,             INPUT  },
+  { MMC2_DAT5,     MUXMODE4,   PULL_UP_SELECTED,             INPUT  },
+  { MMC2_DAT6,     MUXMODE4,   PULL_UP_SELECTED,             INPUT  },
+  { MMC2_DAT7,     MUXMODE4,   PULL_UP_SELECTED,             INPUT  },
+  { MCBSP3_DX,     MUXMODE4,   PULL_DISABLED,                OUTPUT },
+  { MCBSP3_DR,     MUXMODE4,   PULL_DISABLED,                OUTPUT },
+  { MCBSP3_CLKX,   MUXMODE4,   PULL_DISABLED,                OUTPUT },
+  { MCBSP3_FSX,    MUXMODE4,   PULL_DISABLED,                OUTPUT },
+  { UART2_CTS,     MUXMODE0,   PULL_UP_SELECTED,             INPUT  },
+  { UART2_RTS,     MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { UART2_TX,      MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { UART2_RX,      MUXMODE4,   PULL_DISABLED,                OUTPUT },
+  { UART1_TX,      MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { UART1_RTS,     MUXMODE4,   PULL_DISABLED,                OUTPUT },
+  { UART1_CTS,     MUXMODE4,   PULL_DISABLED,                OUTPUT },
+  { UART1_RX,      MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { MCBSP4_CLKX,   MUXMODE1,   PULL_DISABLED,                INPUT  },
+  { MCBSP4_DR,     MUXMODE1,   PULL_DISABLED,                INPUT  },
+  { MCBSP4_DX,     MUXMODE1,   PULL_DISABLED,                INPUT  },
+  { MCBSP4_FSX,    MUXMODE1,   PULL_DISABLED,                INPUT  },
+  { MCBSP1_CLKR,   MUXMODE4,   PULL_DISABLED,                OUTPUT },
+  { MCBSP1_FSR,    MUXMODE4,   PULL_UP_SELECTED,             OUTPUT },
+  { MCBSP1_DX,     MUXMODE4,   PULL_DISABLED,                OUTPUT },
+  { MCBSP1_DR,     MUXMODE4,   PULL_DISABLED,                OUTPUT },
+  { MCBSP1_CLKS,   MUXMODE0,   PULL_UP_SELECTED,             INPUT  },
+  { MCBSP1_FSX,    MUXMODE4,   PULL_DISABLED,                OUTPUT },
+  { MCBSP1_CLKX,   MUXMODE4,   PULL_DISABLED,                OUTPUT },
+  { UART3_CTS_RCTX,MUXMODE0,   PULL_UP_SELECTED,                 INPUT  },
+  { UART3_RTS_SD,  MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { UART3_RX_IRRX, MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { UART3_TX_IRTX, MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { HSUSB0_CLK,    MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { HSUSB0_STP,    MUXMODE0,   PULL_UP_SELECTED,             OUTPUT },
+  { HSUSB0_DIR,    MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { HSUSB0_NXT,    MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { HSUSB0_DATA0,  MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { HSUSB0_DATA1,  MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { HSUSB0_DATA2,  MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { HSUSB0_DATA3,  MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { HSUSB0_DATA4,  MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { HSUSB0_DATA5,  MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { HSUSB0_DATA6,  MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { HSUSB0_DATA7,  MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { I2C1_SCL,      MUXMODE0,   PULL_UP_SELECTED,             INPUT  },
+  { I2C1_SDA,      MUXMODE0,   PULL_UP_SELECTED,             INPUT  },
+  { I2C2_SCL,      MUXMODE4,   PULL_UP_SELECTED,             INPUT  },
+  { I2C2_SDA,      MUXMODE4,   PULL_UP_SELECTED,             INPUT  },
+  { I2C3_SCL,      MUXMODE0,   PULL_UP_SELECTED,             INPUT  },
+  { I2C3_SDA,      MUXMODE0,   PULL_UP_SELECTED,             INPUT  },
+  { HDQ_SIO,       MUXMODE4,   PULL_DISABLED,                OUTPUT },
+  { MCSPI1_CLK,    MUXMODE4,   PULL_UP_SELECTED,             INPUT  },
+  { MCSPI1_SIMO,   MUXMODE4,   PULL_UP_SELECTED,             INPUT  },
+  { MCSPI1_SOMI,   MUXMODE0,   PULL_DISABLED,                INPUT  },
+  { MCSPI1_CS0,    MUXMODE0,   PULL_UP_SELECTED,                 INPUT  },
+  { MCSPI1_CS1,    MUXMODE0,   PULL_UP_SELECTED,                 OUTPUT },
+  { MCSPI1_CS2,    MUXMODE4,   PULL_DISABLED,                OUTPUT },
+  { MCSPI1_CS3,    MUXMODE3,   PULL_UP_SELECTED,             INPUT  },
+  { MCSPI2_CLK,    MUXMODE3,   PULL_UP_SELECTED,             INPUT  },
+  { MCSPI2_SIMO,   MUXMODE3,   PULL_UP_SELECTED,             INPUT  },
+  { MCSPI2_SOMI,   MUXMODE3,   PULL_UP_SELECTED,             INPUT  },
+  { MCSPI2_CS0,    MUXMODE3,   PULL_UP_SELECTED,             INPUT  },
+  { MCSPI2_CS1,    MUXMODE3,   PULL_UP_SELECTED,             INPUT  },
+  { SYS_NIRQ,      MUXMODE0,   PULL_UP_SELECTED,             INPUT  },
+  { SYS_CLKOUT2,   MUXMODE4,   PULL_UP_SELECTED,             INPUT  },
+  { ETK_CLK,       MUXMODE3,   PULL_UP_SELECTED,             OUTPUT },
+  { ETK_CTL,       MUXMODE3,   PULL_UP_SELECTED,             OUTPUT },
+  { ETK_D0,        MUXMODE3,   PULL_UP_SELECTED,             INPUT  },
+  { ETK_D1,        MUXMODE3,   PULL_UP_SELECTED,             INPUT  },
+  { ETK_D2,        MUXMODE3,   PULL_UP_SELECTED,             INPUT  },
+  { ETK_D3,        MUXMODE3,   PULL_UP_SELECTED,             INPUT  },
+  { ETK_D4,        MUXMODE3,   PULL_UP_SELECTED,             INPUT  },
+  { ETK_D5,        MUXMODE3,   PULL_UP_SELECTED,             INPUT  },
+  { ETK_D6,        MUXMODE3,   PULL_UP_SELECTED,             INPUT  },
+  { ETK_D7,        MUXMODE3,   PULL_UP_SELECTED,             INPUT  },
+  { ETK_D8,        MUXMODE3,   PULL_UP_SELECTED,             INPUT  },
+  { ETK_D9,        MUXMODE4,   PULL_UP_SELECTED,             INPUT  },
+  { ETK_D10,       MUXMODE3,   PULL_UP_SELECTED,             OUTPUT },
+  { ETK_D11,       MUXMODE3,   PULL_UP_SELECTED,             OUTPUT },
+  { ETK_D12,       MUXMODE3,   PULL_UP_SELECTED,             INPUT  },
+  { ETK_D13,       MUXMODE3,   PULL_UP_SELECTED,             INPUT  },
+  { ETK_D14,       MUXMODE3,   PULL_UP_SELECTED,             INPUT  },
+  { ETK_D15,       MUXMODE3,   PULL_UP_SELECTED,             INPUT  }
+};
+
+PAD_CONFIGURATION PadConfigurationTableAbc[] = {
+  { DSS_DATA18,    MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA19,    MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA20,    MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA21,    MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA22,    MUXMODE0,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA23,    MUXMODE0,   PULL_DISABLED,                OUTPUT }
+};
+
+PAD_CONFIGURATION PadConfigurationTableXm[] = {
+  { DSS_DATA18,    MUXMODE3,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA19,    MUXMODE3,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA20,    MUXMODE3,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA21,    MUXMODE3,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA22,    MUXMODE3,   PULL_DISABLED,                OUTPUT },
+  { DSS_DATA23,    MUXMODE3,   PULL_DISABLED,                OUTPUT },
+  { SYS_BOOT0,     MUXMODE3,   PULL_DISABLED,                OUTPUT },
+  { SYS_BOOT1,     MUXMODE3,   PULL_DISABLED,                OUTPUT },
+  { SYS_BOOT3,     MUXMODE3,   PULL_DISABLED,                OUTPUT },
+  { SYS_BOOT4,     MUXMODE3,   PULL_DISABLED,                OUTPUT },
+  { SYS_BOOT5,     MUXMODE3,   PULL_DISABLED,                OUTPUT },
+  { SYS_BOOT6,     MUXMODE3,   PULL_DISABLED,                OUTPUT }
+};
+
+VOID
+PadConfiguration (
+  BEAGLEBOARD_REVISION Revision
+  )
+{
+  UINTN             Index;
+  UINT16            PadConfiguration;
+  PAD_CONFIGURATION *BoardConfiguration;
+  UINTN             NumPinsToConfigure;
+
+  for (Index = 0; Index < NUM_PINS_SHARED; Index++) {
+    // Set up Pad configuration for particular pin.
+    PadConfiguration =  (PadConfigurationTableShared[Index].MuxMode << MUXMODE_OFFSET);
+    PadConfiguration |= (PadConfigurationTableShared[Index].PullConfig << PULL_CONFIG_OFFSET);
+    PadConfiguration |= (PadConfigurationTableShared[Index].InputEnable << INPUTENABLE_OFFSET);
+
+    // Configure the pin with specific Pad configuration.
+    MmioWrite16(PadConfigurationTableShared[Index].Pin, PadConfiguration);
+  }
+
+  if (Revision == REVISION_XM) {
+    BoardConfiguration = PadConfigurationTableXm;
+    NumPinsToConfigure = NUM_PINS_XM;
+  } else {
+    BoardConfiguration = PadConfigurationTableAbc;
+    NumPinsToConfigure = NUM_PINS_ABC;
+  }
+
+  for (Index = 0; Index < NumPinsToConfigure; Index++) {
+    //Set up Pad configuration for particular pin.
+    PadConfiguration =  (BoardConfiguration[Index].MuxMode << MUXMODE_OFFSET);
+    PadConfiguration |= (BoardConfiguration[Index].PullConfig << PULL_CONFIG_OFFSET);
+    PadConfiguration |= (BoardConfiguration[Index].InputEnable << INPUTENABLE_OFFSET);
+
+    //Configure the pin with specific Pad configuration.
+    MmioWrite16(BoardConfiguration[Index].Pin, PadConfiguration);
+  }
+}
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Library/DxeHobPeCoffLib/DxeHobPeCoff.c b/Platform/BeagleBoard/BeagleBoardPkg/Library/DxeHobPeCoffLib/DxeHobPeCoff.c
new file mode 100644
index 0000000000..cf9dede8a4
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Library/DxeHobPeCoffLib/DxeHobPeCoff.c
@@ -0,0 +1,282 @@
+/** @file
+  PE/COFF Loader Library implementation that wraps a protocol passed up from
+  SEC/PEI via a HOB. This is done to save space.
+
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+  Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+
+#include <Protocol/PeCoffLoader.h>
+
+
+PE_COFF_LOADER_PROTOCOL  *gPeCoffLoader = NULL;
+
+
+/**
+  Retrieves information about a PE/COFF image.
+
+  Computes the PeCoffHeaderOffset, IsTeImage, ImageType, ImageAddress, ImageSize,
+  DestinationAddress, RelocationsStripped, SectionAlignment, SizeOfHeaders, and
+  DebugDirectoryEntryRva fields of the ImageContext structure.
+  If ImageContext is NULL, then return RETURN_INVALID_PARAMETER.
+  If the PE/COFF image accessed through the ImageRead service in the ImageContext
+  structure is not a supported PE/COFF image type, then return RETURN_UNSUPPORTED.
+  If any errors occur while computing the fields of ImageContext,
+  then the error status is returned in the ImageError field of ImageContext.
+  If the image is a TE image, then SectionAlignment is set to 0.
+  The ImageRead and Handle fields of ImageContext structure must be valid prior
+  to invoking this service.
+
+  @param  ImageContext              Pointer to the image context structure that describes the PE/COFF
+                                    image that needs to be examined by this function.
+
+  @retval RETURN_SUCCESS            The information on the PE/COFF image was collected.
+  @retval RETURN_INVALID_PARAMETER  ImageContext is NULL.
+  @retval RETURN_UNSUPPORTED        The PE/COFF image is not supported.
+
+**/
+RETURN_STATUS
+EFIAPI
+PeCoffLoaderGetImageInfo (
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
+  )
+{
+  return gPeCoffLoader->GetImageInfo (ImageContext);
+}
+
+
+/**
+  Applies relocation fixups to a PE/COFF image that was loaded with PeCoffLoaderLoadImage().
+
+  If the DestinationAddress field of ImageContext is 0, then use the ImageAddress field of
+  ImageContext as the relocation base address.  Otherwise, use the DestinationAddress field
+  of ImageContext as the relocation base address.  The caller must allocate the relocation
+  fixup log buffer and fill in the FixupData field of ImageContext prior to calling this function.
+
+  The ImageRead, Handle, PeCoffHeaderOffset, IsTeImage, Machine, ImageType, ImageAddress,
+  ImageSize, DestinationAddress, RelocationsStripped, SectionAlignment, SizeOfHeaders,
+  DebugDirectoryEntryRva, EntryPoint, FixupDataSize, CodeView, PdbPointer, and FixupData of
+  the ImageContext structure must be valid prior to invoking this service.
+
+  If ImageContext is NULL, then ASSERT().
+
+  Note that if the platform does not maintain coherency between the instruction cache(s) and the data
+  cache(s) in hardware, then the caller is responsible for performing cache maintenance operations
+  prior to transferring control to a PE/COFF image that is loaded using this library.
+
+  @param  ImageContext        Pointer to the image context structure that describes the PE/COFF
+                              image that is being relocated.
+
+  @retval RETURN_SUCCESS      The PE/COFF image was relocated.
+                              Extended status information is in the ImageError field of ImageContext.
+  @retval RETURN_LOAD_ERROR   The image in not a valid PE/COFF image.
+                              Extended status information is in the ImageError field of ImageContext.
+  @retval RETURN_UNSUPPORTED  A relocation record type is not supported.
+                              Extended status information is in the ImageError field of ImageContext.
+
+**/
+RETURN_STATUS
+EFIAPI
+PeCoffLoaderRelocateImage (
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
+  )
+{
+  return gPeCoffLoader->RelocateImage (ImageContext);
+}
+
+/**
+  Loads a PE/COFF image into memory.
+
+  Loads the PE/COFF image accessed through the ImageRead service of ImageContext into the buffer
+  specified by the ImageAddress and ImageSize fields of ImageContext.  The caller must allocate
+  the load buffer and fill in the ImageAddress and ImageSize fields prior to calling this function.
+  The EntryPoint, FixupDataSize, CodeView, PdbPointer and HiiResourceData fields of ImageContext are computed.
+  The ImageRead, Handle, PeCoffHeaderOffset, IsTeImage, Machine, ImageType, ImageAddress, ImageSize,
+  DestinationAddress, RelocationsStripped, SectionAlignment, SizeOfHeaders, and DebugDirectoryEntryRva
+  fields of the ImageContext structure must be valid prior to invoking this service.
+
+  If ImageContext is NULL, then ASSERT().
+
+  Note that if the platform does not maintain coherency between the instruction cache(s) and the data
+  cache(s) in hardware, then the caller is responsible for performing cache maintenance operations
+  prior to transferring control to a PE/COFF image that is loaded using this library.
+
+  @param  ImageContext              Pointer to the image context structure that describes the PE/COFF
+                                    image that is being loaded.
+
+  @retval RETURN_SUCCESS            The PE/COFF image was loaded into the buffer specified by
+                                    the ImageAddress and ImageSize fields of ImageContext.
+                                    Extended status information is in the ImageError field of ImageContext.
+  @retval RETURN_BUFFER_TOO_SMALL   The caller did not provide a large enough buffer.
+                                    Extended status information is in the ImageError field of ImageContext.
+  @retval RETURN_LOAD_ERROR         The PE/COFF image is an EFI Runtime image with no relocations.
+                                    Extended status information is in the ImageError field of ImageContext.
+  @retval RETURN_INVALID_PARAMETER  The image address is invalid.
+                                    Extended status information is in the ImageError field of ImageContext.
+
+**/
+RETURN_STATUS
+EFIAPI
+PeCoffLoaderLoadImage (
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
+  )
+{
+  return gPeCoffLoader->LoadImage (ImageContext);
+}
+
+
+
+/**
+  Reads contents of a PE/COFF image from a buffer in system memory.
+
+  This is the default implementation of a PE_COFF_LOADER_READ_FILE function
+  that assumes FileHandle pointer to the beginning of a PE/COFF image.
+  This function reads contents of the PE/COFF image that starts at the system memory
+  address specified by FileHandle. The read operation copies ReadSize bytes from the
+  PE/COFF image starting at byte offset FileOffset into the buffer specified by Buffer.
+  The size of the buffer actually read is returned in ReadSize.
+
+  If FileHandle is NULL, then ASSERT().
+  If ReadSize is NULL, then ASSERT().
+  If Buffer is NULL, then ASSERT().
+
+  @param  FileHandle        Pointer to base of the input stream
+  @param  FileOffset        Offset into the PE/COFF image to begin the read operation.
+  @param  ReadSize          On input, the size in bytes of the requested read operation.
+                            On output, the number of bytes actually read.
+  @param  Buffer            Output buffer that contains the data read from the PE/COFF image.
+
+  @retval RETURN_SUCCESS    Data is read from FileOffset from the Handle into
+                            the buffer.
+**/
+RETURN_STATUS
+EFIAPI
+PeCoffLoaderImageReadFromMemory (
+  IN     VOID    *FileHandle,
+  IN     UINTN   FileOffset,
+  IN OUT UINTN   *ReadSize,
+  OUT    VOID    *Buffer
+  )
+{
+  return gPeCoffLoader->ReadFromMemory (
+                          FileHandle,
+                          FileOffset,
+                          ReadSize,
+                          Buffer
+                          );
+
+}
+
+
+
+/**
+  Reapply fixups on a fixed up PE32/PE32+ image to allow virutal calling at EFI
+  runtime.
+
+  This function reapplies relocation fixups to the PE/COFF image specified by ImageBase
+  and ImageSize so the image will execute correctly when the PE/COFF image is mapped
+  to the address specified by VirtualImageBase. RelocationData must be identical
+  to the FiuxupData buffer from the PE_COFF_LOADER_IMAGE_CONTEXT structure
+  after this PE/COFF image was relocated with PeCoffLoaderRelocateImage().
+
+  Note that if the platform does not maintain coherency between the instruction cache(s) and the data
+  cache(s) in hardware, then the caller is responsible for performing cache maintenance operations
+  prior to transferring control to a PE/COFF image that is loaded using this library.
+
+  @param  ImageBase          Base address of a PE/COFF image that has been loaded
+                             and relocated into system memory.
+  @param  VirtImageBase      The request virtual address that the PE/COFF image is to
+                             be fixed up for.
+  @param  ImageSize          The size, in bytes, of the PE/COFF image.
+  @param  RelocationData     A pointer to the relocation data that was collected when the PE/COFF
+                             image was relocated using PeCoffLoaderRelocateImage().
+
+**/
+VOID
+EFIAPI
+PeCoffLoaderRelocateImageForRuntime (
+  IN  PHYSICAL_ADDRESS        ImageBase,
+  IN  PHYSICAL_ADDRESS        VirtImageBase,
+  IN  UINTN                   ImageSize,
+  IN  VOID                    *RelocationData
+  )
+{
+  return gPeCoffLoader->RelocateImageForRuntime (
+                          ImageBase,
+                          VirtImageBase,
+                          ImageSize,
+                          RelocationData
+                          );
+}
+
+
+/**
+  Unloads a loaded PE/COFF image from memory and releases its taken resource.
+  Releases any environment specific resources that were allocated when the image
+  specified by ImageContext was loaded using PeCoffLoaderLoadImage().
+
+  For NT32 emulator, the PE/COFF image loaded by system needs to release.
+  For real platform, the PE/COFF image loaded by Core doesn't needs to be unloaded,
+  this function can simply return RETURN_SUCCESS.
+
+  If ImageContext is NULL, then ASSERT().
+
+  @param  ImageContext              Pointer to the image context structure that describes the PE/COFF
+                                    image to be unloaded.
+
+  @retval RETURN_SUCCESS            The PE/COFF image was unloaded successfully.
+**/
+RETURN_STATUS
+EFIAPI
+PeCoffLoaderUnloadImage (
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
+  )
+{
+  return gPeCoffLoader->UnloadImage (ImageContext);
+}
+
+typedef struct {
+  EFI_HOB_GUID_TYPE             Hob;
+  VOID                          *Interface;
+} PROTOCOL_HOB;
+
+
+/**
+  The constructor function caches the pointer of DXE Services Table.
+
+  The constructor function caches the pointer of DXE Services Table.
+  It will ASSERT() if that operation fails.
+  It will ASSERT() if the pointer of DXE Services Table is NULL.
+  It will always return EFI_SUCCESS.
+
+  @param  ImageHandle   The firmware allocated handle for the EFI image.
+  @param  SystemTable   A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+DxeHobPeCoffLibConstructor (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  PROTOCOL_HOB   *Hob;
+
+  Hob = GetFirstGuidHob (&gPeCoffLoaderProtocolGuid);
+  if (Hob == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  gPeCoffLoader = Hob->Interface;
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Library/DxeHobPeCoffLib/DxeHobPeCoffLib.inf b/Platform/BeagleBoard/BeagleBoardPkg/Library/DxeHobPeCoffLib/DxeHobPeCoffLib.inf
new file mode 100644
index 0000000000..654bd8c874
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Library/DxeHobPeCoffLib/DxeHobPeCoffLib.inf
@@ -0,0 +1,39 @@
+#/** @file
+#  PE/COFF Loader Library implementation that wraps a protocol passed up from
+#  SEC/PEI via a HOB. This is done to save space.
+#
+#  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+#  Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = DxeHobPeCoffLib
+  FILE_GUID                      = 671C6FD7-99FB-4EE3-B640-4B1D463BC3B5
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PeCoffLib
+  CONSTRUCTOR                    = DxeHobPeCoffLibConstructor
+
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC ARM
+#
+
+[Sources.common]
+  DxeHobPeCoff.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  HobLib
+
+[Protocols]
+  gPeCoffLoaderProtocolGuid
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Library/LzmaHobCustomDecompressLib/LzmaHobCustomDecompressLib.c b/Platform/BeagleBoard/BeagleBoardPkg/Library/LzmaHobCustomDecompressLib/LzmaHobCustomDecompressLib.c
new file mode 100644
index 0000000000..5c4211827a
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Library/LzmaHobCustomDecompressLib/LzmaHobCustomDecompressLib.c
@@ -0,0 +1,44 @@
+/** @file
+  LZMA Decompress GUIDed Section Extraction Library.
+  It wraps Lzma decompress interfaces to GUIDed Section Extraction interfaces
+  and registers them into GUIDed handler table.
+
+  Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <Library/HobLib.h>
+#include <Library/ExtractGuidedSectionLib.h>
+
+#include <Guid/ExtractSection.h>
+#include <Guid/LzmaDecompress.h>
+
+
+/**
+  Register LzmaDecompress and LzmaDecompressGetInfo handlers with LzmaCustomerDecompressGuid.
+
+  @retval  RETURN_SUCCESS            Register successfully.
+  @retval  RETURN_OUT_OF_RESOURCES   No enough memory to store this handler.
+**/
+EFI_STATUS
+EFIAPI
+LzmaDecompressLibConstructor (
+  )
+{
+  EXTRACT_SECTION_HOB   *Hob;
+
+  Hob = GetFirstGuidHob (&gLzmaCustomDecompressGuid);
+  if (Hob == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  // Locate Guided Hob
+
+  return ExtractGuidedSectionRegisterHandlers (
+          &gLzmaCustomDecompressGuid,
+          Hob->Data.SectionGetInfo,
+          Hob->Data.SectionExtraction
+          );
+}
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Library/LzmaHobCustomDecompressLib/LzmaHobCustomDecompressLib.inf b/Platform/BeagleBoard/BeagleBoardPkg/Library/LzmaHobCustomDecompressLib/LzmaHobCustomDecompressLib.inf
new file mode 100644
index 0000000000..0bad5eeed1
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Library/LzmaHobCustomDecompressLib/LzmaHobCustomDecompressLib.inf
@@ -0,0 +1,45 @@
+#/** @file
+#  LzmaCustomDecompressLib produces LZMA custom decompression algorithm.
+#
+#  It is based on the LZMA SDK 4.65.
+#  LZMA SDK 4.65 was placed in the public domain on 2009-02-03.
+#  It was released on the http://www.7-zip.org/sdk.html website.
+#
+#  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = LzmaDecompressLib
+  FILE_GUID                      = 35194660-7421-44ad-9636-e44885f092d1
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = NULL
+  CONSTRUCTOR                    = LzmaDecompressLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources.common]
+  LzmaHobCustomDecompressLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+
+[Guids]
+  gLzmaCustomDecompressGuid  ## PRODUCED  ## GUID specifies LZMA custom decompress algorithm.
+
+[LibraryClasses]
+  DebugLib
+  HobLib
+  ExtractGuidedSectionLib
+
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.c b/Platform/BeagleBoard/BeagleBoardPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.c
new file mode 100644
index 0000000000..1e7a63e4be
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.c
@@ -0,0 +1,192 @@
+/** @file
+*
+*  Copyright (c) 2011-2015, ARM Limited. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include <PiPei.h>
+
+#include <Library/ArmMmuLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+
+VOID
+BuildMemoryTypeInformationHob (
+  VOID
+  );
+
+STATIC
+VOID
+InitMmu (
+  IN ARM_MEMORY_REGION_DESCRIPTOR  *MemoryTable
+  )
+{
+
+  VOID                          *TranslationTableBase;
+  UINTN                         TranslationTableSize;
+  RETURN_STATUS                 Status;
+
+  //Note: Because we called PeiServicesInstallPeiMemory() before to call InitMmu() the MMU Page Table resides in
+  //      DRAM (even at the top of DRAM as it is the first permanent memory allocation)
+  Status = ArmConfigureMmu (MemoryTable, &TranslationTableBase, &TranslationTableSize);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Error: Failed to enable MMU\n"));
+  }
+}
+
+/*++
+
+Routine Description:
+
+
+
+Arguments:
+
+  FileHandle  - Handle of the file being invoked.
+  PeiServices - Describes the list of possible PEI Services.
+
+Returns:
+
+  Status -  EFI_SUCCESS if the boot mode could be set
+
+--*/
+EFI_STATUS
+EFIAPI
+MemoryPeim (
+  IN EFI_PHYSICAL_ADDRESS               UefiMemoryBase,
+  IN UINT64                             UefiMemorySize
+  )
+{
+  ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable;
+  EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttributes;
+  UINT64                       ResourceLength;
+  EFI_PEI_HOB_POINTERS         NextHob;
+  EFI_PHYSICAL_ADDRESS         FdTop;
+  EFI_PHYSICAL_ADDRESS         SystemMemoryTop;
+  EFI_PHYSICAL_ADDRESS         ResourceTop;
+  BOOLEAN                      Found;
+
+  // Get Virtual Memory Map from the Platform Library
+  ArmPlatformGetVirtualMemoryMap (&MemoryTable);
+
+  // Ensure PcdSystemMemorySize has been set
+  ASSERT (PcdGet64 (PcdSystemMemorySize) != 0);
+
+  //
+  // Now, the permanent memory has been installed, we can call AllocatePages()
+  //
+  ResourceAttributes = (
+      EFI_RESOURCE_ATTRIBUTE_PRESENT |
+      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
+      EFI_RESOURCE_ATTRIBUTE_TESTED
+  );
+
+  //
+  // Check if the resource for the main system memory has been declared
+  //
+  Found = FALSE;
+  NextHob.Raw = GetHobList ();
+  while ((NextHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, NextHob.Raw)) != NULL) {
+    if ((NextHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
+        (PcdGet64 (PcdSystemMemoryBase) >= NextHob.ResourceDescriptor->PhysicalStart) &&
+        (NextHob.ResourceDescriptor->PhysicalStart + NextHob.ResourceDescriptor->ResourceLength <= PcdGet64 (PcdSystemMemoryBase) + PcdGet64 (PcdSystemMemorySize)))
+    {
+      Found = TRUE;
+      break;
+    }
+    NextHob.Raw = GET_NEXT_HOB (NextHob);
+  }
+
+  if (!Found) {
+    // Reserved the memory space occupied by the firmware volume
+    BuildResourceDescriptorHob (
+        EFI_RESOURCE_SYSTEM_MEMORY,
+        ResourceAttributes,
+        PcdGet64 (PcdSystemMemoryBase),
+        PcdGet64 (PcdSystemMemorySize)
+    );
+  }
+
+  //
+  // Reserved the memory space occupied by the firmware volume
+  //
+
+  SystemMemoryTop = (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdSystemMemoryBase) + (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdSystemMemorySize);
+  FdTop = (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdFdBaseAddress) + (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFdSize);
+
+  // EDK2 does not have the concept of boot firmware copied into DRAM. To avoid the DXE
+  // core to overwrite this area we must mark the region with the attribute non-present
+  if ((PcdGet64 (PcdFdBaseAddress) >= PcdGet64 (PcdSystemMemoryBase)) && (FdTop <= SystemMemoryTop)) {
+    Found = FALSE;
+
+    // Search for System Memory Hob that contains the firmware
+    NextHob.Raw = GetHobList ();
+    while ((NextHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, NextHob.Raw)) != NULL) {
+      if ((NextHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
+          (PcdGet64 (PcdFdBaseAddress) >= NextHob.ResourceDescriptor->PhysicalStart) &&
+          (FdTop <= NextHob.ResourceDescriptor->PhysicalStart + NextHob.ResourceDescriptor->ResourceLength))
+      {
+        ResourceAttributes = NextHob.ResourceDescriptor->ResourceAttribute;
+        ResourceLength = NextHob.ResourceDescriptor->ResourceLength;
+        ResourceTop = NextHob.ResourceDescriptor->PhysicalStart + ResourceLength;
+
+        if (PcdGet64 (PcdFdBaseAddress) == NextHob.ResourceDescriptor->PhysicalStart) {
+          if (SystemMemoryTop == FdTop) {
+            NextHob.ResourceDescriptor->ResourceAttribute = ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT;
+          } else {
+            // Create the System Memory HOB for the firmware with the non-present attribute
+            BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,
+                                        ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT,
+                                        PcdGet64 (PcdFdBaseAddress),
+                                        PcdGet32 (PcdFdSize));
+
+            // Top of the FD is system memory available for UEFI
+            NextHob.ResourceDescriptor->PhysicalStart += PcdGet32(PcdFdSize);
+            NextHob.ResourceDescriptor->ResourceLength -= PcdGet32(PcdFdSize);
+          }
+        } else {
+          // Create the System Memory HOB for the firmware with the non-present attribute
+          BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,
+                                      ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT,
+                                      PcdGet64 (PcdFdBaseAddress),
+                                      PcdGet32 (PcdFdSize));
+
+          // Update the HOB
+          NextHob.ResourceDescriptor->ResourceLength = PcdGet64 (PcdFdBaseAddress) - NextHob.ResourceDescriptor->PhysicalStart;
+
+          // If there is some memory available on the top of the FD then create a HOB
+          if (FdTop < NextHob.ResourceDescriptor->PhysicalStart + ResourceLength) {
+            // Create the System Memory HOB for the remaining region (top of the FD)
+            BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,
+                                        ResourceAttributes,
+                                        FdTop,
+                                        ResourceTop - FdTop);
+          }
+        }
+        Found = TRUE;
+        break;
+      }
+      NextHob.Raw = GET_NEXT_HOB (NextHob);
+    }
+
+    ASSERT(Found);
+  }
+
+  // Build Memory Allocation Hob
+  InitMmu (MemoryTable);
+
+  if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) {
+    // Optional feature that helps prevent EFI memory map fragmentation.
+    BuildMemoryTypeInformationHob ();
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf b/Platform/BeagleBoard/BeagleBoardPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf
new file mode 100644
index 0000000000..cbb15eb4c4
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf
@@ -0,0 +1,58 @@
+#/** @file
+#
+#  Copyright (c) 2011-2014, ARM Ltd. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x0001001A
+  BASE_NAME                      = BeagleBoardMemoryInitPeiLib
+  FILE_GUID                      = e489db0a-d847-4d67-910b-48a833f6fef5
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = MemoryInitPeiLib|SEC PEIM
+
+[Sources]
+  MemoryInitPeiLib.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  HobLib
+  ArmMmuLib
+  ArmPlatformLib
+
+[Guids]
+  gEfiMemoryTypeInformationGuid
+
+[FeaturePcd]
+  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdFdBaseAddress
+  gArmTokenSpaceGuid.PcdFdSize
+
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
+
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData
+
+[Pcd]
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdSystemMemorySize
+
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Library/ResetSystemLib/ResetSystemLib.c b/Platform/BeagleBoard/BeagleBoardPkg/Library/ResetSystemLib/ResetSystemLib.c
new file mode 100644
index 0000000000..f3e0201a6f
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Library/ResetSystemLib/ResetSystemLib.c
@@ -0,0 +1,149 @@
+/** @file
+  Do a generic Cold Reset for OMAP3550 and BeagleBoard specific Warm reset
+
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+  Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include <Uefi.h>
+
+#include <Library/IoLib.h>
+#include <Library/ResetSystemLib.h>
+
+#include <Omap3530/Omap3530.h>
+
+/**
+  This function causes a system-wide reset (cold reset), in which
+  all circuitry within the system returns to its initial state. This type of
+  reset is asynchronous to system operation and operates without regard to
+  cycle boundaries.
+
+  If this function returns, it means that the system does not support cold
+  reset.
+**/
+VOID
+EFIAPI
+ResetCold (
+  VOID
+  )
+{
+  //Perform cold reset of the system.
+  MmioOr32 (PRM_RSTCTRL, RST_DPLL3);
+  while ((MmioRead32(PRM_RSTST) & GLOBAL_COLD_RST) != 0x1);
+}
+
+/**
+  This function causes a system-wide initialization (warm reset), in which all
+  processors are set to their initial state. Pending cycles are not corrupted.
+
+  If this function returns, it means that the system does not support warm
+  reset.
+**/
+VOID
+EFIAPI
+ResetWarm (
+  VOID
+  )
+{
+  ResetCold ();
+}
+
+/**
+  This function causes the system to enter a power state equivalent
+  to the ACPI G2/S5 or G3 states.
+
+  If this function returns, it means that the system does not support shut down
+  reset.
+**/
+VOID
+EFIAPI
+ResetShutdown (
+  VOID
+  )
+{
+  // not implemented
+}
+
+/**
+  This function causes the system to enter S3 and then wake up immediately.
+
+  If this function returns, it means that the system does not support S3
+  feature.
+**/
+VOID
+EFIAPI
+EnterS3WithImmediateWake (
+  VOID
+  )
+{
+  // not implemented
+}
+
+/**
+  This function causes a systemwide reset. The exact type of the reset is
+  defined by the EFI_GUID that follows the Null-terminated Unicode string passed
+  into ResetData. If the platform does not recognize the EFI_GUID in ResetData
+  the platform must pick a supported reset type to perform.The platform may
+  optionally log the parameters from any non-normal reset that occurs.
+
+  @param[in]  DataSize   The size, in bytes, of ResetData.
+  @param[in]  ResetData  The data buffer starts with a Null-terminated string,
+                         followed by the EFI_GUID.
+**/
+VOID
+EFIAPI
+ResetPlatformSpecific (
+  IN UINTN   DataSize,
+  IN VOID    *ResetData
+  )
+{
+  ResetCold ();
+}
+
+/**
+  The ResetSystem function resets the entire platform.
+
+  @param[in] ResetType      The type of reset to perform.
+  @param[in] ResetStatus    The status code for the reset.
+  @param[in] DataSize       The size, in bytes, of ResetData.
+  @param[in] ResetData      For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown
+                            the data buffer starts with a Null-terminated string, optionally
+                            followed by additional binary data. The string is a description
+                            that the caller may use to further indicate the reason for the
+                            system reset.
+**/
+VOID
+EFIAPI
+ResetSystem (
+  IN EFI_RESET_TYPE               ResetType,
+  IN EFI_STATUS                   ResetStatus,
+  IN UINTN                        DataSize,
+  IN VOID                         *ResetData OPTIONAL
+  )
+{
+  switch (ResetType) {
+  case EfiResetWarm:
+    ResetWarm ();
+    break;
+
+  case EfiResetCold:
+    ResetCold ();
+    break;
+
+  case EfiResetShutdown:
+    ResetShutdown ();
+    return;
+
+  case EfiResetPlatformSpecific:
+    ResetPlatformSpecific (DataSize, ResetData);
+    return;
+
+  default:
+    return;
+  }
+}
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Library/ResetSystemLib/ResetSystemLib.inf b/Platform/BeagleBoard/BeagleBoardPkg/Library/ResetSystemLib/ResetSystemLib.inf
new file mode 100644
index 0000000000..3f50b21c18
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Library/ResetSystemLib/ResetSystemLib.inf
@@ -0,0 +1,37 @@
+#/** @file
+# Reset System lib to make it easy to port new platforms
+#
+# Copyright (c) 2008, Apple Inc. All rights reserved.<BR>
+# Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BeagleBoardResetSystemLib
+  FILE_GUID                      = 781371a2-3fdd-41d4-96a1-7b34cbc9e895
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ResetSystemLib
+
+
+[Sources.common]
+  ResetSystemLib.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[Pcd.common]
+  gArmTokenSpaceGuid.PcdCpuResetAddress
+
+[LibraryClasses]
+  IoLib
+
+[Pcd]
+  gArmTokenSpaceGuid.PcdFvBaseAddress
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ArchPrePi.c b/Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ArchPrePi.c
new file mode 100644
index 0000000000..250b622f45
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ArchPrePi.c
@@ -0,0 +1,23 @@
+/** @file
+*
+*  Copyright (c) 2011 - 2013, ARM Limited. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include "PrePi.h"
+
+VOID
+ArchInitialize (
+  VOID
+  )
+{
+  // Enable program flow prediction, if supported.
+  ArmEnableBranchPrediction ();
+
+  if (FixedPcdGet32 (PcdVFPEnabled)) {
+    ArmEnableVFP ();
+  }
+}
+
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ModuleEntryPoint.S b/Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ModuleEntryPoint.S
new file mode 100644
index 0000000000..ff7e3a4548
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ModuleEntryPoint.S
@@ -0,0 +1,124 @@
+//
+//  Copyright (c) 2011-2015, ARM Limited. All rights reserved.
+//
+//  SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+
+#include <AsmMacroIoLib.h>
+
+#include <Chipset/ArmV7.h>
+
+ASM_FUNC(_ModuleEntryPoint)
+  // Do early platform specific actions
+  bl    ASM_PFX(ArmPlatformPeiBootAction)
+
+  // Get ID of this CPU in Multicore system
+  bl    ASM_PFX(ArmReadMpidr)
+  // Keep a copy of the MpId register value
+  mov   r8, r0
+
+_SetSVCMode:
+  // Enter SVC mode, Disable FIQ and IRQ
+  mov     r1, #(CPSR_MODE_SVC | CPSR_IRQ | CPSR_FIQ)
+  msr     CPSR_c, r1
+
+// Check if we can install the stack at the top of the System Memory or if we need
+// to install the stacks at the bottom of the Firmware Device (case the FD is located
+// at the top of the DRAM)
+_SystemMemoryEndInit:
+  ADRL  (r1, mSystemMemoryEnd)
+  ldrd  r2, r3, [r1]
+  teq   r3, #0
+  moveq r1, r2
+  mvnne r1, #0
+
+_SetupStackPosition:
+  // r1 = SystemMemoryTop
+
+  // Calculate Top of the Firmware Device
+  MOV32 (r2, FixedPcdGet32(PcdFdBaseAddress))
+  MOV32 (r3, FixedPcdGet32(PcdFdSize) - 1)
+  add   r3, r3, r2      // r3 = FdTop = PcdFdBaseAddress + PcdFdSize
+
+  // UEFI Memory Size (stacks are allocated in this region)
+  MOV32 (r4, FixedPcdGet32(PcdSystemMemoryUefiRegionSize))
+
+  //
+  // Reserve the memory for the UEFI region (contain stacks on its top)
+  //
+
+  // Calculate how much space there is between the top of the Firmware and the Top of the System Memory
+  subs  r0, r1, r3      // r0 = SystemMemoryTop - FdTop
+  bmi   _SetupStack     // Jump if negative (FdTop > SystemMemoryTop). Case when the PrePi is in XIP memory outside of the DRAM
+  cmp   r0, r4
+  bge   _SetupStack
+
+  // Case the top of stacks is the FdBaseAddress
+  mov   r1, r2
+
+_SetupStack:
+  // r1 contains the top of the stack (and the UEFI Memory)
+
+  // Because the 'push' instruction is equivalent to 'stmdb' (decrement before), we need to increment
+  // one to the top of the stack. We check if incrementing one does not overflow (case of DRAM at the
+  // top of the memory space)
+  adds  r9, r1, #1
+  bcs   _SetupOverflowStack
+
+_SetupAlignedStack:
+  mov   r1, r9
+  b     _GetBaseUefiMemory
+
+_SetupOverflowStack:
+  // Case memory at the top of the address space. Ensure the top of the stack is EFI_PAGE_SIZE
+  // aligned (4KB)
+  MOV32 (r9, ~EFI_PAGE_MASK & 0xFFFFFFFF)
+  and   r1, r1, r9
+
+_GetBaseUefiMemory:
+  // Calculate the Base of the UEFI Memory
+  sub   r9, r1, r4
+
+_GetStackBase:
+  // r1 = The top of the Mpcore Stacks
+  // Stack for the primary core = PrimaryCoreStack
+  MOV32 (r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize))
+  sub   r10, r1, r2
+
+  // Stack for the secondary core = Number of Cores - 1
+  MOV32 (r1, (FixedPcdGet32(PcdCoreCount) - 1) * FixedPcdGet32(PcdCPUCoreSecondaryStackSize))
+  sub   r10, r10, r1
+
+  // r10 = The base of the MpCore Stacks (primary stack & secondary stacks)
+  mov   r0, r10
+  mov   r1, r8
+  //ArmPlatformStackSet(StackBase, MpId, PrimaryStackSize, SecondaryStackSize)
+  MOV32 (r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize))
+  MOV32 (r3, FixedPcdGet32(PcdCPUCoreSecondaryStackSize))
+  bl    ASM_PFX(ArmPlatformStackSet)
+
+  // Is it the Primary Core ?
+  mov   r0, r8
+  bl    ASM_PFX(ArmPlatformIsPrimaryCore)
+  cmp   r0, #1
+  bne   _PrepareArguments
+
+_PrepareArguments:
+  mov   r0, r8
+  mov   r1, r9
+  mov   r2, r10
+  mov   r3, sp
+
+  // Move sec startup address into a data register
+  // Ensure we're jumping to FV version of the code (not boot remapped alias)
+  ldr   r4, =ASM_PFX(CEntryPoint)
+
+  // Jump to PrePiCore C code
+  //    r0 = MpId
+  //    r1 = UefiMemoryBase
+  //    r2 = StacksBase
+  blx   r4
+
+_NeverReturn:
+  b _NeverReturn
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ModuleEntryPoint.asm b/Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ModuleEntryPoint.asm
new file mode 100644
index 0000000000..3da7892051
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ModuleEntryPoint.asm
@@ -0,0 +1,142 @@
+//
+//  Copyright (c) 2011-2015, ARM Limited. All rights reserved.
+//
+//  SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+
+#include <AutoGen.h>
+#include <Chipset/ArmV7.h>
+
+  INCLUDE AsmMacroIoLib.inc
+
+  IMPORT  CEntryPoint
+  IMPORT  ArmPlatformIsPrimaryCore
+  IMPORT  ArmReadMpidr
+  IMPORT  ArmPlatformPeiBootAction
+  IMPORT  ArmPlatformStackSet
+  IMPORT  mSystemMemoryEnd
+
+  EXPORT  _ModuleEntryPoint
+
+  PRESERVE8
+  AREA    PrePiCoreEntryPoint, CODE, READONLY
+
+StartupAddr        DCD      CEntryPoint
+
+_ModuleEntryPoint
+  // Do early platform specific actions
+  bl    ArmPlatformPeiBootAction
+
+  // Get ID of this CPU in Multicore system
+  bl    ArmReadMpidr
+  // Keep a copy of the MpId register value
+  mov   r8, r0
+
+_SetSVCMode
+  // Enter SVC mode, Disable FIQ and IRQ
+  mov     r1, #(CPSR_MODE_SVC :OR: CPSR_IRQ :OR: CPSR_FIQ)
+  msr     CPSR_c, r1
+
+// Check if we can install the stack at the top of the System Memory or if we need
+// to install the stacks at the bottom of the Firmware Device (case the FD is located
+// at the top of the DRAM)
+_SystemMemoryEndInit
+  adrll r1, mSystemMemoryEnd
+  ldrd  r2, r3, [r1]
+  teq   r3, #0
+  moveq r1, r2
+  mvnne r1, #0
+
+_SetupStackPosition
+  // r1 = SystemMemoryTop
+
+  // Calculate Top of the Firmware Device
+  mov32 r2, FixedPcdGet32(PcdFdBaseAddress)
+  mov32 r3, FixedPcdGet32(PcdFdSize)
+  sub   r3, r3, #1
+  add   r3, r3, r2      // r3 = FdTop = PcdFdBaseAddress + PcdFdSize
+
+  // UEFI Memory Size (stacks are allocated in this region)
+  mov32 r4, FixedPcdGet32(PcdSystemMemoryUefiRegionSize)
+
+  //
+  // Reserve the memory for the UEFI region (contain stacks on its top)
+  //
+
+  // Calculate how much space there is between the top of the Firmware and the Top of the System Memory
+  subs  r0, r1, r3      // r0 = SystemMemoryTop - FdTop
+  bmi   _SetupStack     // Jump if negative (FdTop > SystemMemoryTop). Case when the PrePi is in XIP memory outside of the DRAM
+  cmp   r0, r4
+  bge   _SetupStack
+
+  // Case the top of stacks is the FdBaseAddress
+  mov   r1, r2
+
+_SetupStack
+  // r1 contains the top of the stack (and the UEFI Memory)
+
+  // Because the 'push' instruction is equivalent to 'stmdb' (decrement before), we need to increment
+  // one to the top of the stack. We check if incrementing one does not overflow (case of DRAM at the
+  // top of the memory space)
+  adds  r9, r1, #1
+  bcs   _SetupOverflowStack
+
+_SetupAlignedStack
+  mov   r1, r9
+  b     _GetBaseUefiMemory
+
+_SetupOverflowStack
+  // Case memory at the top of the address space. Ensure the top of the stack is EFI_PAGE_SIZE
+  // aligned (4KB)
+  mov32 r9, EFI_PAGE_MASK
+  and   r9, r9, r1
+  sub   r1, r1, r9
+
+_GetBaseUefiMemory
+  // Calculate the Base of the UEFI Memory
+  sub   r9, r1, r4
+
+_GetStackBase
+  // r1 = The top of the Mpcore Stacks
+  // Stack for the primary core = PrimaryCoreStack
+  mov32 r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize)
+  sub   r10, r1, r2
+
+  // Stack for the secondary core = Number of Cores - 1
+  mov32 r1, (FixedPcdGet32(PcdCoreCount) - 1) * FixedPcdGet32(PcdCPUCoreSecondaryStackSize)
+  sub   r10, r10, r1
+
+  // r10 = The base of the MpCore Stacks (primary stack & secondary stacks)
+  mov   r0, r10
+  mov   r1, r8
+  //ArmPlatformStackSet(StackBase, MpId, PrimaryStackSize, SecondaryStackSize)
+  mov32 r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize)
+  mov32 r3, FixedPcdGet32(PcdCPUCoreSecondaryStackSize)
+  bl    ArmPlatformStackSet
+
+  // Is it the Primary Core ?
+  mov   r0, r8
+  bl    ArmPlatformIsPrimaryCore
+  cmp   r0, #1
+  bne   _PrepareArguments
+
+_PrepareArguments
+  mov   r0, r8
+  mov   r1, r9
+  mov   r2, r10
+
+  // Move sec startup address into a data register
+  // Ensure we're jumping to FV version of the code (not boot remapped alias)
+  ldr   r4, StartupAddr
+
+  // Jump to PrePiCore C code
+  //    r0 = MpId
+  //    r1 = UefiMemoryBase
+  //    r2 = StacksBase
+  blx   r4
+
+_NeverReturn
+  b _NeverReturn
+
+  END
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/PrePi/LzmaDecompress.h b/Platform/BeagleBoard/BeagleBoardPkg/PrePi/LzmaDecompress.h
new file mode 100644
index 0000000000..cc99ce99ac
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/PrePi/LzmaDecompress.h
@@ -0,0 +1,97 @@
+/** @file
+  LZMA Decompress Library header file
+
+  Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __LZMA_DECOMPRESS_H___
+#define __LZMA_DECOMPRESS_H___
+
+/**
+  Examines a GUIDed section and returns the size of the decoded buffer and the
+  size of an scratch buffer required to actually decode the data in a GUIDed section.
+
+  Examines a GUIDed section specified by InputSection.
+  If GUID for InputSection does not match the GUID that this handler supports,
+  then RETURN_UNSUPPORTED is returned.
+  If the required information can not be retrieved from InputSection,
+  then RETURN_INVALID_PARAMETER is returned.
+  If the GUID of InputSection does match the GUID that this handler supports,
+  then the size required to hold the decoded buffer is returned in OututBufferSize,
+  the size of an optional scratch buffer is returned in ScratchSize, and the Attributes field
+  from EFI_GUID_DEFINED_SECTION header of InputSection is returned in SectionAttribute.
+
+  If InputSection is NULL, then ASSERT().
+  If OutputBufferSize is NULL, then ASSERT().
+  If ScratchBufferSize is NULL, then ASSERT().
+  If SectionAttribute is NULL, then ASSERT().
+
+
+  @param[in]  InputSection       A pointer to a GUIDed section of an FFS formatted file.
+  @param[out] OutputBufferSize   A pointer to the size, in bytes, of an output buffer required
+                                 if the buffer specified by InputSection were decoded.
+  @param[out] ScratchBufferSize  A pointer to the size, in bytes, required as scratch space
+                                 if the buffer specified by InputSection were decoded.
+  @param[out] SectionAttribute   A pointer to the attributes of the GUIDed section. See the Attributes
+                                 field of EFI_GUID_DEFINED_SECTION in the PI Specification.
+
+  @retval  RETURN_SUCCESS            The information about InputSection was returned.
+  @retval  RETURN_UNSUPPORTED        The section specified by InputSection does not match the GUID this handler supports.
+  @retval  RETURN_INVALID_PARAMETER  The information can not be retrieved from the section specified by InputSection.
+
+**/
+RETURN_STATUS
+EFIAPI
+LzmaGuidedSectionGetInfo (
+  IN  CONST VOID  *InputSection,
+  OUT UINT32      *OutputBufferSize,
+  OUT UINT32      *ScratchBufferSize,
+  OUT UINT16      *SectionAttribute
+  );
+
+/**
+  Decompress a LZAM compressed GUIDed section into a caller allocated output buffer.
+
+  Decodes the GUIDed section specified by InputSection.
+  If GUID for InputSection does not match the GUID that this handler supports, then RETURN_UNSUPPORTED is returned.
+  If the data in InputSection can not be decoded, then RETURN_INVALID_PARAMETER is returned.
+  If the GUID of InputSection does match the GUID that this handler supports, then InputSection
+  is decoded into the buffer specified by OutputBuffer and the authentication status of this
+  decode operation is returned in AuthenticationStatus.  If the decoded buffer is identical to the
+  data in InputSection, then OutputBuffer is set to point at the data in InputSection.  Otherwise,
+  the decoded data will be placed in caller allocated buffer specified by OutputBuffer.
+
+  If InputSection is NULL, then ASSERT().
+  If OutputBuffer is NULL, then ASSERT().
+  If ScratchBuffer is NULL and this decode operation requires a scratch buffer, then ASSERT().
+  If AuthenticationStatus is NULL, then ASSERT().
+
+
+  @param[in]  InputSection  A pointer to a GUIDed section of an FFS formatted file.
+  @param[out] OutputBuffer  A pointer to a buffer that contains the result of a decode operation.
+  @param[out] ScratchBuffer A caller allocated buffer that may be required by this function
+                            as a scratch buffer to perform the decode operation.
+  @param[out] AuthenticationStatus
+                            A pointer to the authentication status of the decoded output buffer.
+                            See the definition of authentication status in the EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
+                            section of the PI Specification. EFI_AUTH_STATUS_PLATFORM_OVERRIDE must
+                            never be set by this handler.
+
+  @retval  RETURN_SUCCESS            The buffer specified by InputSection was decoded.
+  @retval  RETURN_UNSUPPORTED        The section specified by InputSection does not match the GUID this handler supports.
+  @retval  RETURN_INVALID_PARAMETER  The section specified by InputSection can not be decoded.
+
+**/
+RETURN_STATUS
+EFIAPI
+LzmaGuidedSectionExtraction (
+  IN CONST  VOID    *InputSection,
+  OUT       VOID    **OutputBuffer,
+  OUT       VOID    *ScratchBuffer,        OPTIONAL
+  OUT       UINT32  *AuthenticationStatus
+  );
+
+#endif // __LZMADECOMPRESS_H__
+
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/PrePi/MainUniCore.c b/Platform/BeagleBoard/BeagleBoardPkg/PrePi/MainUniCore.c
new file mode 100644
index 0000000000..7b4bdf7dfd
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/PrePi/MainUniCore.c
@@ -0,0 +1,33 @@
+/** @file
+*
+*  Copyright (c) 2011, ARM Limited. All rights reserved.
+*  Copyright (c) 2017, Linaro, Ltd. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include "PrePi.h"
+
+VOID
+PrimaryMain (
+  IN  UINTN                     UefiMemoryBase,
+  IN  UINTN                     StacksBase,
+  IN  UINT64                    StartTimeStamp
+  )
+{
+  PrePiMain (UefiMemoryBase, StacksBase, StartTimeStamp);
+
+  // We must never return
+  ASSERT(FALSE);
+}
+
+VOID
+SecondaryMain (
+  IN  UINTN                     MpId
+  )
+{
+  // We must never get into this function on UniCore system
+  ASSERT(FALSE);
+}
+
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/PrePi/PeiUniCore.inf b/Platform/BeagleBoard/BeagleBoardPkg/PrePi/PeiUniCore.inf
new file mode 100644
index 0000000000..a4bf25b595
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/PrePi/PeiUniCore.inf
@@ -0,0 +1,97 @@
+#/** @file
+#
+#  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
+#  Copyright (c) 2011-2017, ARM Ltd. All rights reserved.<BR>
+#  Copyright (c) 2017, Linaro, Ltd. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x0001001A
+  BASE_NAME                      = BeagleBoardPrePiUniCore
+  FILE_GUID                      = 8a5dc3de-fe31-4ad9-9c93-dd73626932e7
+  MODULE_TYPE                    = SEC
+  VERSION_STRING                 = 1.0
+
+[Sources]
+  PrePi.c
+  MainUniCore.c
+
+[Sources.ARM]
+  Arm/ArchPrePi.c
+  Arm/ModuleEntryPoint.S   | GCC
+  Arm/ModuleEntryPoint.asm | RVCT
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  ArmLib
+  ArmPlatformLib
+  ArmPlatformStackLib
+  BaseLib
+  DebugLib
+  DebugAgentLib
+  ExtractGuidedSectionLib
+  HobLib
+  IoLib
+  MemoryAllocationLib
+  MemoryInitPeiLib
+  PeCoffGetEntryPointLib
+  PlatformPeiLib
+  PrePiHobListPointerLib
+  PrePiLib
+  SerialPortLib
+  TimerLib
+
+[Ppis]
+  gArmMpCoreInfoPpiGuid
+
+[Guids]
+  gArmMpCoreInfoGuid
+  gEfiFirmwarePerformanceGuid
+
+[FeaturePcd]
+  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
+  gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdVFPEnabled
+
+  gArmTokenSpaceGuid.PcdFdBaseAddress
+  gArmTokenSpaceGuid.PcdFdSize
+
+  gArmTokenSpaceGuid.PcdFvBaseAddress
+  gArmTokenSpaceGuid.PcdFvSize
+
+  gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize
+  gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize
+
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
+
+  gArmPlatformTokenSpaceGuid.PcdCoreCount
+
+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize
+
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData
+
+[Pcd]
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdSystemMemorySize
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/PrePi/PrePi.c b/Platform/BeagleBoard/BeagleBoardPkg/PrePi/PrePi.c
new file mode 100644
index 0000000000..5c2fb4007e
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/PrePi/PrePi.c
@@ -0,0 +1,179 @@
+/** @file
+*
+*  Copyright (c) 2011-2017, ARM Limited. All rights reserved.
+*  Copyright (c) 2017, Linaro, Ltd. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include <PiPei.h>
+
+#include <Library/DebugAgentLib.h>
+#include <Library/PrePiLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+#include <Library/PrePiHobListPointerLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PerformanceLib.h>
+
+#include <Ppi/GuidedSectionExtraction.h>
+#include <Ppi/ArmMpCoreInfo.h>
+#include <Ppi/SecPerformance.h>
+#include <Guid/LzmaDecompress.h>
+
+#include "PrePi.h"
+#include "LzmaDecompress.h"
+
+#define IS_XIP() (((UINT64)FixedPcdGet64 (PcdFdBaseAddress) > mSystemMemoryEnd) || \
+                  ((FixedPcdGet64 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) < FixedPcdGet64 (PcdSystemMemoryBase)))
+
+UINT64 mSystemMemoryEnd = FixedPcdGet64(PcdSystemMemoryBase) +
+                          FixedPcdGet64(PcdSystemMemorySize) - 1;
+
+EFI_STATUS
+GetPlatformPpi (
+  IN  EFI_GUID  *PpiGuid,
+  OUT VOID      **Ppi
+  )
+{
+  UINTN                   PpiListSize;
+  UINTN                   PpiListCount;
+  EFI_PEI_PPI_DESCRIPTOR  *PpiList;
+  UINTN                   Index;
+
+  PpiListSize = 0;
+  ArmPlatformGetPlatformPpiList (&PpiListSize, &PpiList);
+  PpiListCount = PpiListSize / sizeof(EFI_PEI_PPI_DESCRIPTOR);
+  for (Index = 0; Index < PpiListCount; Index++, PpiList++) {
+    if (CompareGuid (PpiList->Guid, PpiGuid) == TRUE) {
+      *Ppi = PpiList->Ppi;
+      return EFI_SUCCESS;
+    }
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+VOID
+PrePiMain (
+  IN  UINTN                     UefiMemoryBase,
+  IN  UINTN                     StacksBase,
+  IN  UINT64                    StartTimeStamp
+  )
+{
+  EFI_HOB_HANDOFF_INFO_TABLE*   HobList;
+  EFI_STATUS                    Status;
+  CHAR8                         Buffer[100];
+  UINTN                         CharCount;
+  UINTN                         StacksSize;
+  FIRMWARE_SEC_PERFORMANCE      Performance;
+
+  // If ensure the FD is either part of the System Memory or totally outside of the System Memory (XIP)
+  ASSERT (IS_XIP() ||
+          ((FixedPcdGet64 (PcdFdBaseAddress) >= FixedPcdGet64 (PcdSystemMemoryBase)) &&
+           ((UINT64)(FixedPcdGet64 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= (UINT64)mSystemMemoryEnd)));
+
+  // Initialize the architecture specific bits
+  ArchInitialize ();
+
+  // Initialize the Serial Port
+  SerialPortInitialize ();
+  CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"UEFI firmware (version %s built at %a on %a)\n\r",
+    (CHAR16*)PcdGetPtr(PcdFirmwareVersionString), __TIME__, __DATE__);
+  SerialPortWrite ((UINT8 *) Buffer, CharCount);
+
+  // Initialize the Debug Agent for Source Level Debugging
+  InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL);
+  SaveAndSetDebugTimerInterrupt (TRUE);
+
+  // Declare the PI/UEFI memory region
+  HobList = HobConstructor (
+    (VOID*)UefiMemoryBase,
+    FixedPcdGet32 (PcdSystemMemoryUefiRegionSize),
+    (VOID*)UefiMemoryBase,
+    (VOID*)StacksBase  // The top of the UEFI Memory is reserved for the stacks
+    );
+  PrePeiSetHobList (HobList);
+
+  // Initialize MMU and Memory HOBs (Resource Descriptor HOBs)
+  Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
+  ASSERT_EFI_ERROR (Status);
+
+  StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize);
+  BuildStackHob (StacksBase, StacksSize);
+
+  //TODO: Call CpuPei as a library
+  BuildCpuHob (ArmGetPhysicalAddressBits (), PcdGet8 (PcdPrePiCpuIoSize));
+
+  // Store timer value logged at the beginning of firmware image execution
+  Performance.ResetEnd = GetTimeInNanoSecond (StartTimeStamp);
+
+  // Build SEC Performance Data Hob
+  BuildGuidDataHob (&gEfiFirmwarePerformanceGuid, &Performance, sizeof (Performance));
+
+  // Set the Boot Mode
+  SetBootMode (ArmPlatformGetBootMode ());
+
+  // Initialize Platform HOBs (CpuHob and FvHob)
+  Status = PlatformPeim ();
+  ASSERT_EFI_ERROR (Status);
+
+  // Now, the HOB List has been initialized, we can register performance information
+  PERF_START (NULL, "PEI", NULL, StartTimeStamp);
+
+  // SEC phase needs to run library constructors by hand.
+  ProcessLibraryConstructorList ();
+
+  // Build HOBs to pass up our version of stuff the DXE Core needs to save space
+  BuildPeCoffLoaderHob ();
+  BuildExtractSectionHob (
+    &gLzmaCustomDecompressGuid,
+    LzmaGuidedSectionGetInfo,
+    LzmaGuidedSectionExtraction
+    );
+
+  // Assume the FV that contains the SEC (our code) also contains a compressed FV.
+  Status = DecompressFirstFv ();
+  ASSERT_EFI_ERROR (Status);
+
+  // Load the DXE Core and transfer control to it
+  Status = LoadDxeCoreFromFv (NULL, 0);
+  ASSERT_EFI_ERROR (Status);
+}
+
+VOID
+CEntryPoint (
+  IN  UINTN                     MpId,
+  IN  UINTN                     UefiMemoryBase,
+  IN  UINTN                     StacksBase
+  )
+{
+  UINT64   StartTimeStamp;
+
+  // Initialize the platform specific controllers
+  ArmPlatformInitialize (MpId);
+
+  if (PerformanceMeasurementEnabled ()) {
+    // Initialize the Timer Library to setup the Timer HW controller
+    TimerConstructor ();
+    // We cannot call yet the PerformanceLib because the HOB List has not been initialized
+    StartTimeStamp = GetPerformanceCounter ();
+  } else {
+    StartTimeStamp = 0;
+  }
+
+  // Data Cache enabled on Primary core when MMU is enabled.
+  ArmDisableDataCache ();
+  // Invalidate Data cache
+  ArmInvalidateDataCache ();
+  // Invalidate instruction cache
+  ArmInvalidateInstructionCache ();
+  // Enable Instruction Caches on all cores.
+  ArmEnableInstructionCache ();
+
+  PrimaryMain (UefiMemoryBase, StacksBase, StartTimeStamp);
+
+  // DXE Core should always load and never return
+  ASSERT (FALSE);
+}
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/PrePi/PrePi.h b/Platform/BeagleBoard/BeagleBoardPkg/PrePi/PrePi.h
new file mode 100644
index 0000000000..b64dd764a4
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/PrePi/PrePi.h
@@ -0,0 +1,90 @@
+/** @file
+*
+*  Copyright (c) 2011-2015, ARM Limited. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#ifndef _PREPI_H_
+#define _PREPI_H_
+
+#include <PiPei.h>
+
+#include <Library/PcdLib.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/HobLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/ArmPlatformLib.h>
+
+#define SerialPrint(txt)  SerialPortWrite (txt, AsciiStrLen(txt)+1);
+
+extern UINT64 mSystemMemoryEnd;
+
+RETURN_STATUS
+EFIAPI
+TimerConstructor (
+  VOID
+  );
+
+VOID
+PrePiMain (
+  IN  UINTN                     UefiMemoryBase,
+  IN  UINTN                     StacksBase,
+  IN  UINT64                    StartTimeStamp
+  );
+
+EFI_STATUS
+EFIAPI
+MemoryPeim (
+  IN EFI_PHYSICAL_ADDRESS       UefiMemoryBase,
+  IN UINT64                     UefiMemorySize
+  );
+
+EFI_STATUS
+EFIAPI
+PlatformPeim (
+  VOID
+  );
+
+VOID
+PrimaryMain (
+  IN  UINTN                     UefiMemoryBase,
+  IN  UINTN                     StacksBase,
+  IN  UINT64                    StartTimeStamp
+  );
+
+VOID
+SecondaryMain (
+  IN  UINTN                     MpId
+  );
+
+// Either implemented by PrePiLib or by MemoryInitPei
+VOID
+BuildMemoryTypeInformationHob (
+  VOID
+  );
+
+EFI_STATUS
+GetPlatformPpi (
+  IN  EFI_GUID  *PpiGuid,
+  OUT VOID      **Ppi
+  );
+
+// Initialize the Architecture specific controllers
+VOID
+ArchInitialize (
+  VOID
+  );
+
+VOID
+EFIAPI
+ProcessLibraryConstructorList (
+  VOID
+  );
+
+#endif /* _PREPI_H_ */
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Tools/GNUmakefile b/Platform/BeagleBoard/BeagleBoardPkg/Tools/GNUmakefile
new file mode 100644
index 0000000000..8be6182bf3
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Tools/GNUmakefile
@@ -0,0 +1,14 @@
+#
+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+#  
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+CC     = gcc
+CFLAGS = -g
+
+generate_image: generate_image.c
+		$(CC) $(CCFLAGS) $(LDFLAGS) -o generate_image generate_image.c
+
+clean:
+	rm -f generate_image generate_image.exe
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Tools/generate_image.c b/Platform/BeagleBoard/BeagleBoardPkg/Tools/generate_image.c
new file mode 100644
index 0000000000..fd93a0b472
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Tools/generate_image.c
@@ -0,0 +1,402 @@
+/** @file
+ The data structures in this code come from:
+ OMAP35x Applications Processor Technical Reference Manual chapter 25
+ OMAP34xx Multimedia Device Technical Reference Manual chapter 26.4.8.
+
+ You should use the OMAP35x manual when possible. Some things, like SectionKey,
+ are not defined in the OMAP35x manual and you have to use the OMAP34xx manual
+ to find the data.
+
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+
+
+//TOC structure as defined by OMAP35XX TRM.
+typedef struct {
+  unsigned int  Start;
+  unsigned int  Size;
+  unsigned int  Reserved1;
+  unsigned int  Reserved2;
+  unsigned int  Reserved3;
+  unsigned char Filename[12];
+} TOC_DATA;
+
+//NOTE: OMAP3430 TRM has CHSETTINGS and CHRAM structures.
+typedef struct {
+  unsigned int   SectionKey;
+  unsigned char  Valid;
+  unsigned char  Version;
+  unsigned short Reserved;
+  unsigned int   Flags;
+  unsigned int   PRM_CLKSRC_CTRL;
+  unsigned int   PRM_CLKSEL;
+  unsigned int   CM_CLKSEL1_EMU;
+  unsigned int   CM_CLKSEL_CORE;
+  unsigned int   CM_CLKSEL_WKUP;
+  unsigned int   CM_CLKEN_PLL_DPLL3;
+  unsigned int   CM_AUTOIDLE_PLL_DPLL3;
+  unsigned int   CM_CLKSEL1_PLL;
+  unsigned int   CM_CLKEN_PLL_DPLL4;
+  unsigned int   CM_AUTOIDLE_PLL_DPLL4;
+  unsigned int   CM_CLKSEL2_PLL;
+  unsigned int   CM_CLKSEL3_PLL;
+  unsigned int   CM_CLKEN_PLL_MPU;
+  unsigned int   CM_AUTOIDLE_PLL_MPU;
+  unsigned int   CM_CLKSEL1_PLL_MPU;
+  unsigned int   CM_CLKSEL2_PLL_MPU;
+  unsigned int   CM_CLKSTCTRL_MPU;
+} CHSETTINGS_DATA;
+
+typedef struct {
+  unsigned int   SectionKey;
+  unsigned char  Valid;
+  unsigned char  Reserved1;
+  unsigned char  Reserved2;
+  unsigned char  Reserved3;
+  unsigned short SDRC_SYSCONFIG_LSB;
+  unsigned short SDRC_CS_CFG_LSB;
+  unsigned short SDRC_SHARING_LSB;
+  unsigned short SDRC_ERR_TYPE_LSB;
+  unsigned int   SDRC_DLLA_CTRL;
+  unsigned short Reserved4;
+  unsigned short Reserved5;
+  unsigned int   SDRC_POWER;
+  unsigned short MEMORY_TYPE_CS0;
+  unsigned short Reserved6;
+  unsigned int   SDRC_MCFG_0;
+  unsigned short SDRC_MR_0_LSB;
+  unsigned short SDRC_EMR1_0_LSB;
+  unsigned short SDRC_EMR2_0_LSB;
+  unsigned short SDRC_EMR3_0_LSB;
+  unsigned int   SDRC_ACTIM_CTRLA_0;
+  unsigned int   SDRC_ACTIM_CTRLB_0;
+  unsigned int   SDRC_RFRCTRL_0;
+  unsigned short MEMORY_TYPE_CS1;
+  unsigned short Reserved7;
+  unsigned int   SDRC_MCFG_1;
+  unsigned short SDRC_MR_1_LSB;
+  unsigned short SDRC_EMR1_1_LSB;
+  unsigned short SDRC_EMR2_1_LSB;
+  unsigned short SDRC_EMR3_1_LSB;
+  unsigned int   SDRC_ACTIM_CTRLA_1;
+  unsigned int   SDRC_ACTIM_CTRLB_1;
+  unsigned int   SDRC_RFRCTRL_1;
+  unsigned int   Reserved8;
+  unsigned short Flags;
+  unsigned short Reserved9;
+} CHRAM_DATA;
+
+#define CHSETTINGS_START      0xA0
+#define CHSETTINGS_SIZE       0x50
+#define CHRAM_START           0xF0
+#define CHRAM_SIZE            0x5C
+#define CLOSING_TOC_ITEM_SIZE 4
+
+unsigned char gConfigurationHeader[512];
+unsigned int  gImageExecutionAddress;
+char          *gInputImageFile = NULL;
+char          *gOutputImageFile = NULL;
+char          *gDataFile = NULL;
+
+static
+void
+PrintUsage (
+  void
+  )
+{
+  printf("Usage..\n");
+}
+
+static
+void
+PopulateCHSETTINGSData (
+  FILE            *DataFile,
+  CHSETTINGS_DATA *CHSETTINGSData
+  )
+{
+  unsigned int Value;
+
+  CHSETTINGSData->SectionKey            = 0xC0C0C0C1;
+  CHSETTINGSData->Valid                 = 0x1;
+  CHSETTINGSData->Version               = 0x1;
+  CHSETTINGSData->Reserved              = 0x00;
+  CHSETTINGSData->Flags                 = 0x050001FD;
+
+  //General clock settings.
+  fscanf(DataFile, "PRM_CLKSRC_CTRL=0x%08x\n", &Value);
+  CHSETTINGSData->PRM_CLKSRC_CTRL = Value;
+  fscanf(DataFile, "PRM_CLKSEL=0x%08x\n", &Value);
+  CHSETTINGSData->PRM_CLKSEL = Value;
+  fscanf(DataFile, "CM_CLKSEL1_EMU=0x%08x\n", &Value);
+  CHSETTINGSData->CM_CLKSEL1_EMU = Value;
+
+  //Clock configuration
+  fscanf(DataFile, "CM_CLKSEL_CORE=0x%08x\n", &Value);
+  CHSETTINGSData->CM_CLKSEL_CORE = Value;
+  fscanf(DataFile, "CM_CLKSEL_WKUP=0x%08x\n", &Value);
+  CHSETTINGSData->CM_CLKSEL_WKUP = Value;
+
+  //DPLL3 (Core) settings
+  fscanf(DataFile, "CM_CLKEN_PLL_DPLL3=0x%08x\n", &Value);
+  CHSETTINGSData->CM_CLKEN_PLL_DPLL3 = Value;
+  fscanf(DataFile, "CM_AUTOIDLE_PLL_DPLL3=0x%08x\n", &Value);
+  CHSETTINGSData->CM_AUTOIDLE_PLL_DPLL3 = Value;
+  fscanf(DataFile, "CM_CLKSEL1_PLL=0x%08x\n", &Value);
+  CHSETTINGSData->CM_CLKSEL1_PLL = Value;
+
+  //DPLL4 (Peripheral) settings
+  fscanf(DataFile, "CM_CLKEN_PLL_DPLL4=0x%08x\n", &Value);
+  CHSETTINGSData->CM_CLKEN_PLL_DPLL4 = Value;
+  fscanf(DataFile, "CM_AUTOIDLE_PLL_DPLL4=0x%08x\n", &Value);
+  CHSETTINGSData->CM_AUTOIDLE_PLL_DPLL4 = Value;
+  fscanf(DataFile, "CM_CLKSEL2_PLL=0x%08x\n", &Value);
+  CHSETTINGSData->CM_CLKSEL2_PLL = Value;
+  fscanf(DataFile, "CM_CLKSEL3_PLL=0x%08x\n", &Value);
+  CHSETTINGSData->CM_CLKSEL3_PLL = Value;
+
+  //DPLL1 (MPU) settings
+  fscanf(DataFile, "CM_CLKEN_PLL_MPU=0x%08x\n", &Value);
+  CHSETTINGSData->CM_CLKEN_PLL_MPU = Value;
+  fscanf(DataFile, "CM_AUTOIDLE_PLL_MPU=0x%08x\n", &Value);
+  CHSETTINGSData->CM_AUTOIDLE_PLL_MPU = Value;
+  fscanf(DataFile, "CM_CLKSEL1_PLL_MPU=0x%08x\n", &Value);
+  CHSETTINGSData->CM_CLKSEL1_PLL_MPU = Value;
+  fscanf(DataFile, "CM_CLKSEL2_PLL_MPU=0x%08x\n", &Value);
+  CHSETTINGSData->CM_CLKSEL2_PLL_MPU = Value;
+  fscanf(DataFile, "CM_CLKSTCTRL_MPU=0x%08x\n", &Value);
+  CHSETTINGSData->CM_CLKSTCTRL_MPU = Value;
+}
+
+static
+void
+PopulateCHRAMData (
+  FILE       *DataFile,
+  CHRAM_DATA *CHRAMData
+  )
+{
+  unsigned int Value;
+
+  CHRAMData->SectionKey         = 0xC0C0C0C2;
+  CHRAMData->Valid              = 0x1;
+
+  fscanf(DataFile, "SDRC_SYSCONFIG_LSB=0x%04x\n", &Value);
+  CHRAMData->SDRC_SYSCONFIG_LSB = Value;
+  fscanf(DataFile, "SDRC_CS_CFG_LSB=0x%04x\n", &Value);
+  CHRAMData->SDRC_CS_CFG_LSB    = Value;
+  fscanf(DataFile, "SDRC_SHARING_LSB=0x%04x\n", &Value);
+  CHRAMData->SDRC_SHARING_LSB   = Value;
+  fscanf(DataFile, "SDRC_ERR_TYPE_LSB=0x%04x\n", &Value);
+  CHRAMData->SDRC_ERR_TYPE_LSB  = Value;
+  fscanf(DataFile, "SDRC_DLLA_CTRL=0x%08x\n", &Value);
+  CHRAMData->SDRC_DLLA_CTRL     = Value;
+  fscanf(DataFile, "SDRC_POWER=0x%08x\n", &Value);
+  CHRAMData->SDRC_POWER         = Value;
+  fscanf(DataFile, "MEMORY_TYPE_CS0=0x%04x\n", &Value);
+  CHRAMData->MEMORY_TYPE_CS0    = Value;
+  fscanf(DataFile, "SDRC_MCFG_0=0x%08x\n", &Value);
+  CHRAMData->SDRC_MCFG_0        = Value;
+  fscanf(DataFile, "SDRC_MR_0_LSB=0x%04x\n", &Value);
+  CHRAMData->SDRC_MR_0_LSB      = Value;
+  fscanf(DataFile, "SDRC_EMR1_0_LSB=0x%04x\n", &Value);
+  CHRAMData->SDRC_EMR1_0_LSB    = Value;
+  fscanf(DataFile, "SDRC_EMR2_0_LSB=0x%04x\n", &Value);
+  CHRAMData->SDRC_EMR2_0_LSB    = Value;
+  fscanf(DataFile, "SDRC_EMR3_0_LSB=0x%04x\n", &Value);
+  CHRAMData->SDRC_EMR3_0_LSB    = Value;
+  fscanf(DataFile, "SDRC_ACTIM_CTRLA_0=0x%08x\n", &Value);
+  CHRAMData->SDRC_ACTIM_CTRLA_0 = Value;
+  fscanf(DataFile, "SDRC_ACTIM_CTRLB_0=0x%08x\n", &Value);
+  CHRAMData->SDRC_ACTIM_CTRLB_0 = Value;
+  fscanf(DataFile, "SDRC_RFRCTRL_0=0x%08x\n", &Value);
+  CHRAMData->SDRC_RFRCTRL_0     = Value;
+  fscanf(DataFile, "MEMORY_TYPE_CS1=0x%04x\n", &Value);
+  CHRAMData->MEMORY_TYPE_CS1    = Value;
+  fscanf(DataFile, "SDRC_MCFG_1=0x%08x\n", &Value);
+  CHRAMData->SDRC_MCFG_1        = Value;
+  fscanf(DataFile, "SDRC_MR_1_LSB=0x%04x\n", &Value);
+  CHRAMData->SDRC_MR_1_LSB      = Value;
+  fscanf(DataFile, "SDRC_EMR1_1_LSB=0x%04x\n", &Value);
+  CHRAMData->SDRC_EMR1_1_LSB    = Value;
+  fscanf(DataFile, "SDRC_EMR2_1_LSB=0x%04x\n", &Value);
+  CHRAMData->SDRC_EMR2_1_LSB    = Value;
+  fscanf(DataFile, "SDRC_EMR3_1_LSB=0x%04x\n", &Value);
+  CHRAMData->SDRC_EMR3_1_LSB    = Value;
+  fscanf(DataFile, "SDRC_ACTIM_CTRLA_1=0x%08x\n", &Value);
+  CHRAMData->SDRC_ACTIM_CTRLA_1 = Value;
+  fscanf(DataFile, "SDRC_ACTIM_CTRLB_1=0x%08x\n", &Value);
+  CHRAMData->SDRC_ACTIM_CTRLB_1 = Value;
+  fscanf(DataFile, "SDRC_RFRCTRL_1=0x%08x\n", &Value);
+  CHRAMData->SDRC_RFRCTRL_1     = Value;
+
+  CHRAMData->Flags              = 0x0003;
+}
+
+static
+void
+PrepareConfigurationHeader (
+  void
+  )
+{
+  TOC_DATA        Toc;
+  CHSETTINGS_DATA CHSETTINGSData;
+  CHRAM_DATA      CHRAMData;
+  unsigned int    ConfigurationHdrOffset = 0;
+  FILE            *DataFile;
+
+  // Open data file
+  DataFile = fopen(gDataFile, "rb");
+  if (DataFile == NULL) {
+    fprintf(stderr, "Can't open data file %s.\n", gDataFile);
+    exit(1);
+  }
+
+  //Initialize configuration header.
+  memset(gConfigurationHeader, 0x00, sizeof(gConfigurationHeader));
+
+  //CHSETTINGS TOC
+  memset(&Toc, 0x00, sizeof(TOC_DATA));
+  Toc.Start = CHSETTINGS_START;
+  Toc.Size = CHSETTINGS_SIZE;
+  strcpy((char *)Toc.Filename, (const char *)"CHSETTINGS");
+  memcpy(gConfigurationHeader + ConfigurationHdrOffset, &Toc, sizeof(TOC_DATA));
+
+  //Populate CHSETTINGS Data
+  memset(&CHSETTINGSData, 0x00, sizeof(CHSETTINGS_DATA));
+  PopulateCHSETTINGSData(DataFile, &CHSETTINGSData);
+  memcpy(gConfigurationHeader + Toc.Start, &CHSETTINGSData, Toc.Size);
+
+  //Adjust ConfigurationHdrOffset to point to next TOC
+  ConfigurationHdrOffset += sizeof(TOC_DATA);
+
+  //CHRAM TOC
+  memset(&Toc, 0x00, sizeof(TOC_DATA));
+  Toc.Start = CHRAM_START;
+  Toc.Size = CHRAM_SIZE;
+  strcpy((char *)Toc.Filename, (const char *)"CHRAM");
+  memcpy(gConfigurationHeader + ConfigurationHdrOffset, &Toc, sizeof(TOC_DATA));
+
+  //Populate CHRAM Data
+  memset(&CHRAMData, 0x00, sizeof(CHRAM_DATA));
+  PopulateCHRAMData(DataFile, &CHRAMData);
+  memcpy(gConfigurationHeader + Toc.Start, &CHRAMData, Toc.Size);
+
+  //Adjust ConfigurationHdrOffset to point to next TOC
+  ConfigurationHdrOffset += sizeof(TOC_DATA);
+
+  //Closing TOC item
+  memset(gConfigurationHeader + ConfigurationHdrOffset, 0xFF, CLOSING_TOC_ITEM_SIZE);
+  ConfigurationHdrOffset += CLOSING_TOC_ITEM_SIZE;
+
+  // Close data file
+  fclose(DataFile);
+}
+
+static
+void
+ConstructImage (
+  void
+  )
+{
+  FILE         *InputFile;
+  FILE         *OutputFile;
+  unsigned int InputImageFileSize;
+  struct       stat FileStat;
+  char         Ch;
+  unsigned int i;
+
+  InputFile = fopen(gInputImageFile, "rb");
+  if (InputFile == NULL) {
+    fprintf(stderr, "Can't open input file.\n");
+    exit(0);
+  }
+
+  // Get the size of the input image.
+  fstat(fileno(InputFile), &FileStat);
+  InputImageFileSize = FileStat.st_size;
+
+  OutputFile = fopen(gOutputImageFile, "wb");
+  if (OutputFile == NULL) {
+    fprintf(stderr, "Can't open output file %s.\n", gOutputImageFile);
+    exit(0);
+  }
+
+  // Write Configuration header
+  fwrite(gConfigurationHeader, 1, sizeof(gConfigurationHeader), OutputFile);
+
+  // Write image header (Input image size, execution address)
+  fwrite(&InputImageFileSize, 1, 4, OutputFile);
+  fwrite(&gImageExecutionAddress, 1, 4, OutputFile);
+
+  // Copy input image to the output file.
+  for (i = 0; i < InputImageFileSize; i++) {
+    fread(&Ch, 1, 1, InputFile);
+    fwrite(&Ch, 1, 1, OutputFile);
+  }
+
+  fclose(InputFile);
+  fclose(OutputFile);
+}
+
+
+int
+main (
+  int    argc,
+  char** argv
+  )
+{
+  char          Ch;
+  unsigned char *ptr;
+  int           i;
+  int           TwoArg;
+
+  if (argc == 1) {
+    PrintUsage ();
+    exit(1);
+  }
+
+  for (i=1; i < argc; i++) {
+    if (argv[i][0] == '-') {
+      // TwoArg TRUE -E 0x123, FALSE -E0x1234
+      TwoArg = (argv[i][2] != ' ');
+      switch (argv[i][1]) {
+        case 'E': /* Image execution address */
+          gImageExecutionAddress = strtoul (TwoArg ? argv[i+1] : &argv[i][2], (char **)&ptr, 16);
+          break;
+
+        case 'I': /* Input image file */
+          gInputImageFile = TwoArg ? argv[i+1] : &argv[i][2];
+          break;
+
+        case 'O': /* Output image file */
+          gOutputImageFile = TwoArg ? argv[i+1] : &argv[i][2];
+          break;
+
+        case 'D': /* Data file */
+          gDataFile = TwoArg ? argv[i+1] : &argv[i][2];
+          break;
+
+        default:
+          abort ();
+      }
+    }
+  }
+
+
+  //Prepare configuration header
+  PrepareConfigurationHeader ();
+
+  //Build image with configuration header + image header + image
+  ConstructImage ();
+
+  return 0;
+}
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Tools/makefile b/Platform/BeagleBoard/BeagleBoardPkg/Tools/makefile
new file mode 100644
index 0000000000..42030df5ff
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Tools/makefile
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+#  
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+all: GenerateImage replace
+
+GenerateImage: generate_image.c
+		$(CC) $(CCFLAGS) $(LDFLAGS) -o GenerateImage.exe generate_image.c
+
+replace: replace.c
+		$(CC) $(CCFLAGS) $(LDFLAGS) -o replace.exe replace.c
+
+clean:
+	del GenerateImage.exe generate_image.obj replace.exe replace.obj
diff --git a/Platform/BeagleBoard/BeagleBoardPkg/Tools/replace.c b/Platform/BeagleBoard/BeagleBoardPkg/Tools/replace.c
new file mode 100644
index 0000000000..6a1dad4408
--- /dev/null
+++ b/Platform/BeagleBoard/BeagleBoardPkg/Tools/replace.c
@@ -0,0 +1,140 @@
+//
+// Quick hack to work around not having sed, or any other reasonable
+// way to edit a file from a script on Windows......
+//
+// Copyright (c) 2010, Apple Inc. All rights reserved.<BR>
+//
+//  SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#define TRUE  1
+#define FALSE 0
+
+typedef struct {
+  char  *Match;
+  int   MatchSize;
+  char  *Replace;
+} MATCH_PAIR;
+
+void
+Usage (char *Name)
+{
+  printf ("\n%s OldFile NewFile MatchString ReplaceString [MatchString2 ReplaceString2]*\n", Name);
+  printf ("    OldFile - Must be arg[1] File to search for MatchStrings\n");
+  printf ("    NewFile - Must be arg[2] File where MatchString has been replaced with ReplaceString\n");
+  printf ("    MatchString & ReplaceString. Required arguments.\n");
+  printf ("    More MatchString/ReplaceString pairs are supported.\n");
+}
+
+//
+// argv[1] - Old File
+// argv[2] - New File
+// argv[3+n] - Match String
+// argv[4+n] - Replace string
+int
+main (int argc, char **argv)
+{
+  FILE *In, *Out;
+  char *Key, *Replace;
+  int  c, i, n, Len, MaxLenKey = 0, MinLenKey = INT_MAX;
+  unsigned long  InFileSize, InFilePos;
+  MATCH_PAIR *Match;
+  int MaxMatch;
+  int ReadCount;
+  int Found;
+
+  if (argc < 5) {
+    fprintf (stderr, "Need at least two files and one Match/Replacement string pair\n");
+    Usage (argv[0]);
+    return -1;
+  } else if ((argc % 2) == 0) {
+    fprintf (stderr, "Match and Replace string must come in pairs\n");
+    return -4;
+  }
+
+  In  = fopen (argv[1], "r");
+  fseek (In, 0, SEEK_END);
+  InFileSize = ftell (In);
+  if (InFileSize == 0) {
+    fprintf (stderr, "Could not open %s\n", argv[1]);
+    return -6;
+  }
+  fseek (In, 0, SEEK_SET);
+
+
+  Out = fopen (argv[2], "w+");
+  if ((In == NULL) || (Out == NULL)) {
+    fprintf (stderr, "Could not open %s\n", argv[2]);
+    return -2;
+  }
+
+  MaxMatch = (argc - 2)/2;
+  Match = calloc (MaxMatch, sizeof (MATCH_PAIR));
+  if (Match == NULL) {
+    return -7;
+  }
+
+  for (n=0; n < MaxMatch; n++) {
+    Match[n].Match   = argv[3 + n*2];
+    Match[n].MatchSize = strlen (argv[3 + n*2]);
+    Match[n].Replace = argv[3 + n*2 + 1];
+    if (Match[n].MatchSize > MaxLenKey) {
+      // Max size of match/replace string pair
+      MaxLenKey = Match[n].MatchSize;
+    }
+    if (Match[n].MatchSize < MinLenKey) {
+      MinLenKey = Match[n].MatchSize;
+    }
+  }
+
+  Key = malloc (MaxLenKey);
+  if (Key == NULL) {
+    return -5;
+  }
+
+  // Search for a match by reading every possition of the file
+  // into a buffer that is as big as the maximum search key size.
+  // Then we can search the keys for a match. If no match
+  // copy the old file character to the new file. If it is a match
+  // then copy the replacement string into the output file.
+  // This code assumes the file system is smart and caches the
+  // file in a buffer. So all the reads don't really hit the disk.
+  InFilePos = 0;
+  while (InFilePos < (InFileSize - MinLenKey)) {
+    fseek (In, InFilePos, SEEK_SET);
+    ReadCount = fread (Key, 1, MaxLenKey, In);
+    for (i = 0, Found = FALSE;i < MaxMatch; i++) {
+      if (ReadCount >= Match[i].MatchSize) {
+        if (!memcmp (Key, Match[i].Match, Match[i].MatchSize)) {
+          InFilePos += (Match[i].MatchSize - 1);
+          fputs (Match[i].Replace, Out);
+          Found = TRUE;
+          break;
+        }
+      }
+    }
+    if (!Found) {
+      fputc (Key[0], Out);
+    }
+
+    InFilePos++;
+  }
+
+  // We stoped searching when we got to the point that we could no longer match.
+  // So the last few bytes of the file are not copied in the privous loop
+  fseek (In, InFilePos, SEEK_SET);
+  while ((c = fgetc (In)) != EOF) {
+    fputc (c, Out);
+  }
+
+  fclose (In);
+  fclose (Out);
+  free (Key);
+  free (Match);
+  return 0;
+}
+
-- 
2.21.0.windows.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [edk2-platforms: Patch 3/8] Silicon/Intel: Import QuarkSocPkg from edk2
  2019-05-10  3:34 [edk2-platforms: Patch 0/8] Add packages from edk2 Michael D Kinney
  2019-05-10  3:34 ` [edk2-platforms: Patch 1/8] Silicon/TexasInsturments: Import Omap35xxPkg " Michael D Kinney
  2019-05-10  3:34 ` [edk2-platforms: Patch 2/8] Platform/BeagleBoard: Import BeagleBoardPkg " Michael D Kinney
@ 2019-05-10  3:34 ` Michael D Kinney
  2019-05-10  3:34 ` [edk2-platforms: Patch 4/8] Platform/QuarkPlatformPkg: Import QuarkPlatformPkg " Michael D Kinney
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 23+ messages in thread
From: Michael D Kinney @ 2019-05-10  3:34 UTC (permalink / raw)
  To: devel; +Cc: Kelly Steele, Michael Kubacki, Leif Lindholm, Ard Biesheuvel

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

Import QuarkSocPkg from edk2/master.

Cc: Kelly Steele <kelly.steele@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>
---
 .../Include/DdrMemoryController.h             |  251 ++
 .../QuarkNorthCluster/Include/IntelQNCBase.h  |   17 +
 .../Include/IntelQNCConfig.h                  |  100 +
 .../QuarkNorthCluster/Include/IntelQNCDxe.h   |   17 +
 .../QuarkNorthCluster/Include/IntelQNCPeim.h  |   17 +
 .../QuarkNorthCluster/Include/IntelQNCRegs.h  |   48 +
 .../Include/Library/IntelQNCLib.h             |  284 ++
 .../Include/Library/QNCAccessLib.h            |  161 +
 .../Include/Library/QNCSmmLib.h               |   57 +
 .../Include/Ppi/QNCMemoryInit.h               |   36 +
 .../Include/Protocol/PchInfo.h                |   48 +
 .../Include/Protocol/PlatformPolicy.h         |   31 +
 .../Include/Protocol/QncS3Support.h           |   84 +
 .../Include/Protocol/SmmIchnDispatch2.h       |  115 +
 .../QuarkNorthCluster/Include/Protocol/Spi.h  |  345 +++
 .../QuarkNorthCluster/Include/QNCAccess.h     |  177 ++
 .../Include/QNCCommonDefinitions.h            |  350 +++
 .../QuarkNorthCluster/Include/QuarkNcSocId.h  |  751 +++++
 .../Library/IntelQNCLib/CommonHeader.h        |   32 +
 .../Library/IntelQNCLib/IntelQNCLib.c         |  771 +++++
 .../Library/IntelQNCLib/IntelQNCLib.inf       |   57 +
 .../Library/IntelQNCLib/PciExpress.c          |  932 ++++++
 .../Library/MtrrLib/MtrrLib.c                 | 2112 +++++++++++++
 .../Library/MtrrLib/MtrrLib.inf               |   42 +
 .../Library/MtrrLib/MtrrLib.uni               |   18 +
 .../Library/QNCAccessLib/BaseAccess.c         |   28 +
 .../Library/QNCAccessLib/QNCAccessLib.c       |  327 ++
 .../Library/QNCAccessLib/QNCAccessLib.inf     |   37 +
 .../Library/QNCAccessLib/RuntimeAccess.c      |  142 +
 .../QNCAccessLib/RuntimeQNCAccessLib.inf      |   43 +
 .../Library/QNCSmmLib/QNCSmmLib.c             |  313 ++
 .../Library/QNCSmmLib/QNCSmmLib.inf           |   44 +
 .../Library/ResetSystemLib/ResetSystemLib.c   |  379 +++
 .../Library/ResetSystemLib/ResetSystemLib.inf |   46 +
 .../Library/SmbusLib/CommonHeader.h           |   25 +
 .../Library/SmbusLib/SmbusLib.c               |  797 +++++
 .../Library/SmbusLib/SmbusLib.inf             |   47 +
 .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.c     |  446 +++
 .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf   |   30 +
 .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.uni   |   12 +
 .../MemoryInit/Pei/MemoryInit.c               |   59 +
 .../MemoryInit/Pei/MemoryInit.h               |   35 +
 .../MemoryInit/Pei/MemoryInitPei.inf          |   70 +
 .../MemoryInit/Pei/core_types.h               |   43 +
 .../MemoryInit/Pei/gen5_iosf_sb_definitions.h |  738 +++++
 .../MemoryInit/Pei/general_definitions.h      |   84 +
 .../QuarkNorthCluster/MemoryInit/Pei/hte.c    |  536 ++++
 .../QuarkNorthCluster/MemoryInit/Pei/hte.h    |   66 +
 .../QuarkNorthCluster/MemoryInit/Pei/io.h     |  132 +
 .../QuarkNorthCluster/MemoryInit/Pei/lprint.c |  382 +++
 .../MemoryInit/Pei/meminit.c                  | 2638 +++++++++++++++++
 .../MemoryInit/Pei/meminit.h                  |   22 +
 .../MemoryInit/Pei/meminit_utils.c            | 1574 ++++++++++
 .../MemoryInit/Pei/meminit_utils.h            |   95 +
 .../MemoryInit/Pei/memory_options.h           |   77 +
 .../QuarkNorthCluster/MemoryInit/Pei/mrc.c    |   40 +
 .../QuarkNorthCluster/MemoryInit/Pei/mrc.h    |  160 +
 .../MemoryInit/Pei/platform.c                 |  186 ++
 .../MemoryInit/Pei/prememinit.c               |  187 ++
 .../MemoryInit/Pei/prememinit.h               |   15 +
 .../QNCInit/Dxe/CommonHeader.h                |   49 +
 .../QNCInit/Dxe/DxeQNCSmbus.c                 |  612 ++++
 .../QNCInit/Dxe/DxeQNCSmbus.h                 |  205 ++
 .../QNCInit/Dxe/LegacyRegion.c                |  237 ++
 .../QNCInit/Dxe/LegacyRegion.h                |  198 ++
 .../QuarkNorthCluster/QNCInit/Dxe/QNCInit.c   |  518 ++++
 .../QuarkNorthCluster/QNCInit/Dxe/QNCInit.h   |   49 +
 .../QNCInit/Dxe/QNCInitDxe.inf                |   92 +
 .../QNCInit/Dxe/QNCRootPorts.c                |   76 +
 .../QuarkNorthCluster/QNCInit/Dxe/QNCSmbus.h  |   80 +
 .../QNCInit/Dxe/QNCSmbusExec.c                |  246 ++
 .../S3Support/Dxe/QncS3Support.c              |  417 +++
 .../S3Support/Dxe/QncS3Support.h              |  117 +
 .../S3Support/Dxe/QncS3Support.inf            |   64 +
 .../Smm/Dxe/SmmAccessDxe/SmmAccess.inf        |   49 +
 .../Smm/Dxe/SmmAccessDxe/SmmAccessDriver.c    |  405 +++
 .../Smm/Dxe/SmmAccessDxe/SmmAccessDriver.h    |  230 ++
 .../Smm/Dxe/SmmControlDxe/SmmControlDriver.c  |  358 +++
 .../Smm/Dxe/SmmControlDxe/SmmControlDxe.inf   |   55 +
 .../DxeSmm/QncSmmDispatcher/CommonHeader.h    |   45 +
 .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmGpi.c   |   32 +
 .../QncSmmDispatcher/QNC/QNCSmmHelpers.c      |  549 ++++
 .../QNC/QNCSmmPeriodicTimer.c                 |  424 +++
 .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmQncn.c  |  211 ++
 .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmSw.c    |   90 +
 .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmSx.c    |  147 +
 .../Smm/DxeSmm/QncSmmDispatcher/QNCSmm.h      |  868 ++++++
 .../Smm/DxeSmm/QncSmmDispatcher/QNCSmmCore.c  |  825 ++++++
 .../QncSmmDispatcher/QNCSmmDispatcher.inf     |   81 +
 .../DxeSmm/QncSmmDispatcher/QNCSmmHelpers.c   |  367 +++
 .../DxeSmm/QncSmmDispatcher/QNCSmmHelpers.h   |  219 ++
 .../DxeSmm/QncSmmDispatcher/QNCSmmRegisters.h |   13 +
 .../DxeSmm/QncSmmDispatcher/QNCxSmmHelpers.h  |  178 ++
 .../Smm/Pei/SmmAccessPei/SmmAccessPei.c       |  376 +++
 .../Smm/Pei/SmmAccessPei/SmmAccessPei.inf     |   45 +
 .../Smm/Pei/SmmControlPei/SmmControlPei.c     |  274 ++
 .../Smm/Pei/SmmControlPei/SmmControlPei.inf   |   51 +
 .../QuarkNorthCluster/Spi/Common/SpiCommon.c  |  927 ++++++
 .../QuarkNorthCluster/Spi/Common/SpiCommon.h  |  317 ++
 .../QuarkNorthCluster/Spi/PchSpiRuntime.inf   |   84 +
 .../QuarkNorthCluster/Spi/PchSpiSmm.inf       |   50 +
 .../QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.c |  205 ++
 .../QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.h |   79 +
 .../QuarkNorthCluster/Spi/Smm/PchSpi.c        |  123 +
 .../QuarkNorthCluster/Spi/Smm/PchSpi.h        |   47 +
 Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dec     |  234 ++
 Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dsc     |  254 ++
 .../QuarkSouthCluster/Include/CEATA.h         |  114 +
 .../QuarkSouthCluster/Include/I2cRegs.h       |   95 +
 .../QuarkSouthCluster/Include/Ioh.h           |  248 ++
 .../QuarkSouthCluster/Include/IohAccess.h     |   18 +
 .../Include/IohCommonDefinitions.h            |  342 +++
 .../Include/Library/I2cLib.h                  |  152 +
 .../Include/Library/IohLib.h                  |   36 +
 .../QuarkSouthCluster/Include/MMC.h           |  274 ++
 .../QuarkSouthCluster/Include/SDCard.h        |  146 +
 .../QuarkSouthCluster/Include/SDHostIo.h      |  333 +++
 .../IohInit/Dxe/CommonHeader.h                |   55 +
 .../QuarkSouthCluster/IohInit/Dxe/IohBds.h    |   83 +
 .../QuarkSouthCluster/IohInit/Dxe/IohData.c   |   42 +
 .../QuarkSouthCluster/IohInit/Dxe/IohInit.c   |   37 +
 .../IohInit/Dxe/IohInitDxe.inf                |   76 +
 .../Library/I2cLib/CommonHeader.h             |  214 ++
 .../QuarkSouthCluster/Library/I2cLib/I2cLib.c |  998 +++++++
 .../Library/I2cLib/I2cLib.inf                 |   62 +
 .../Library/IohLib/CommonHeader.h             |   29 +
 .../QuarkSouthCluster/Library/IohLib/IohLib.c |   99 +
 .../Library/IohLib/IohLib.inf                 |   49 +
 .../Sdio/Dxe/SDControllerDxe/ComponentName.c  |  227 ++
 .../Sdio/Dxe/SDControllerDxe/ComponentName.h  |  141 +
 .../Sdio/Dxe/SDControllerDxe/SDController.c   | 1784 +++++++++++
 .../Sdio/Dxe/SDControllerDxe/SDController.h   |  316 ++
 .../Dxe/SDControllerDxe/SDControllerDxe.inf   |   56 +
 .../Sdio/Dxe/SDMediaDeviceDxe/CEATA.c         |  647 ++++
 .../Sdio/Dxe/SDMediaDeviceDxe/CEATABlockIo.c  |  389 +++
 .../Sdio/Dxe/SDMediaDeviceDxe/ComponentName.c |  215 ++
 .../Sdio/Dxe/SDMediaDeviceDxe/ComponentName.h |  139 +
 .../Sdio/Dxe/SDMediaDeviceDxe/MMCSDBlockIo.c  |  538 ++++
 .../Sdio/Dxe/SDMediaDeviceDxe/MMCSDTransfer.c | 1708 +++++++++++
 .../Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.c |  317 ++
 .../Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.h |  462 +++
 .../Dxe/SDMediaDeviceDxe/SDMediaDeviceDxe.inf |   60 +
 .../QuarkSouthCluster/Usb/Common/Pei/UsbPei.c |  320 ++
 .../QuarkSouthCluster/Usb/Common/Pei/UsbPei.h |   38 +
 .../Usb/Common/Pei/UsbPei.inf                 |   53 +
 .../Usb/Ohci/Dxe/ComponentName.c              |  219 ++
 .../Usb/Ohci/Dxe/ComponentName.h              |  141 +
 .../Usb/Ohci/Dxe/Descriptor.h                 |  132 +
 .../QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.c     | 2473 +++++++++++++++
 .../QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.h     |  663 +++++
 .../Usb/Ohci/Dxe/OhciDebug.c                  |   78 +
 .../Usb/Ohci/Dxe/OhciDebug.h                  |   42 +
 .../Usb/Ohci/Dxe/OhciDxe.inf                  |   71 +
 .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.c  | 1390 +++++++++
 .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.h  |  920 ++++++
 .../Usb/Ohci/Dxe/OhciSched.c                  |  528 ++++
 .../Usb/Ohci/Dxe/OhciSched.h                  |  225 ++
 .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.c  |  889 ++++++
 .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.h  |  387 +++
 .../QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.c |  560 ++++
 .../QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.h |  152 +
 .../Usb/Ohci/Pei/Descriptor.h                 |  131 +
 .../QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.c  | 1386 +++++++++
 .../QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.h  |  252 ++
 .../Usb/Ohci/Pei/OhciPei.inf                  |   56 +
 .../QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.c  | 1386 +++++++++
 .../QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.h  |  875 ++++++
 .../Usb/Ohci/Pei/OhciSched.c                  |  223 ++
 .../Usb/Ohci/Pei/OhciSched.h                  |  108 +
 .../QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.c  |  560 ++++
 .../QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.h  |  231 ++
 .../QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.c |  491 +++
 .../QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.h |  134 +
 173 files changed, 53495 insertions(+)
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/DdrMemoryController.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCBase.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCConfig.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCDxe.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCPeim.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCRegs.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/IntelQNCLib.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/QNCAccessLib.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/QNCSmmLib.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Ppi/QNCMemoryInit.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/PchInfo.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/PlatformPolicy.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/QncS3Support.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/SmmIchnDispatch2.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/Spi.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QNCAccess.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QNCCommonDefinitions.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QuarkNcSocId.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/CommonHeader.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNCLib.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNCLib.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/PciExpress.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.uni
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/BaseAccess.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/QNCAccessLib.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/QNCAccessLib.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/RuntimeAccess.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/RuntimeQNCAccessLib.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCSmmLib/QNCSmmLib.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCSmmLib/QNCSmmLib.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/ResetSystemLib.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/ResetSystemLib.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/CommonHeader.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/SmbusLib.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/SmbusLib.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.uni
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInit.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInit.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInitPei.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/core_types.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/gen5_iosf_sb_definitions.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/general_definitions.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/hte.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/hte.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/io.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/lprint.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit_utils.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit_utils.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/memory_options.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/mrc.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/mrc.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/platform.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/prememinit.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/prememinit.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/CommonHeader.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInitDxe.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCRootPorts.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbus.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbusExec.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/SmmAccess.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/SmmAccessDriver.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/SmmAccessDriver.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmControlDxe/SmmControlDriver.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmControlDxe/SmmControlDxe.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/CommonHeader.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmGpi.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmHelpers.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmPeriodicTimer.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmQncn.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmSw.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmSx.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmm.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmCore.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmDispatcher.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmHelpers.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmHelpers.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmRegisters.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCxSmmHelpers.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmAccessPei/SmmAccessPei.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmAccessPei/SmmAccessPei.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/SmmControlPei.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/SmmControlPei.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Common/SpiCommon.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Common/SpiCommon.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiRuntime.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiSmm.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchSpi.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchSpi.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dec
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dsc
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/CEATA.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/I2cRegs.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Ioh.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/IohAccess.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/IohCommonDefinitions.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Library/I2cLib.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Library/IohLib.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/MMC.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/SDCard.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/SDHostIo.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/CommonHeader.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohBds.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohData.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohInit.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohInitDxe.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/CommonHeader.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/I2cLib.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/I2cLib.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/CommonHeader.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/IohLib.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/IohLib.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/ComponentName.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/ComponentName.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SDController.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SDController.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SDControllerDxe.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/CEATA.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/CEATABlockIo.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/ComponentName.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/ComponentName.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/MMCSDBlockIo.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/MMCSDTransfer.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/SDMediaDeviceDxe.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/ComponentName.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/ComponentName.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Descriptor.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDebug.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDebug.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDxe.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciSched.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciSched.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/Descriptor.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciPei.inf
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciSched.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciSched.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.h
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.c
 create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.h

diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/DdrMemoryController.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/DdrMemoryController.h
new file mode 100644
index 0000000000..fe96af4405
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/DdrMemoryController.h
@@ -0,0 +1,251 @@
+/** @file
+Memory controller configuration.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef __DDR_MEMORY_CONTROLLER_H__
+#define __DDR_MEMORY_CONTROLLER_H__
+
+//
+// DDR timing data definitions.
+// These are used to create bitmaps of valid timing configurations.
+//
+
+#define DUAL_CHANNEL_DDR_TIMING_DATA_FREQUENCY_UNKNOWN    0xFF
+#define DUAL_CHANNEL_DDR_TIMING_DATA_REFRESH_RATE_UNKNOWN 0xFF
+
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TCL_20    0x01
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TCL_25    0x00
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TCL_30    0x02
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TCL_ALL   0x03
+
+
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRCD_02   0x02
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRCD_03   0x01
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRCD_04   0x00
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRCD_ALL  0x03
+
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRP_02    0x02
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRP_03    0x01
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRP_04    0x00
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRP_ALL   0x03
+
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRAS_05   0x05
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRAS_06   0x04
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRAS_07   0x03
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRAS_08   0x02
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRAS_09   0x01
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRAS_10   0x00
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRAS_ALL  0x07
+
+#define DUAL_CHANNEL_DDR_DATA_TYPE_REGISTERED    0x01
+#define DUAL_CHANNEL_DDR_DATA_TYPE_UNREGISTERED  0x02
+#define DUAL_CHANNEL_DDR_DATA_TYPE_BUFFERED      0x04
+#define DUAL_CHANNEL_DDR_DATA_TYPE_UNBUFFERED    0x08
+#define DUAL_CHANNEL_DDR_DATA_TYPE_SDR           0x10
+#define DUAL_CHANNEL_DDR_DATA_TYPE_DDR           0x20
+
+
+//
+// Maximum number of SDRAM channels supported by the memory controller
+//
+#define MAX_CHANNELS 1
+
+//
+// Maximum number of DIMM sockets supported by the memory controller
+//
+#define MAX_SOCKETS 1
+
+//
+// Maximum number of sides supported per DIMM
+//
+#define   MAX_SIDES                         2
+
+//
+// Maximum number of "Socket Sets", where a "Socket Set is a set of matching
+// DIMM's from the various channels
+//
+#define   MAX_SOCKET_SETS                   2
+
+//
+// Maximum number of rows supported by the memory controller
+//
+#define MAX_ROWS (MAX_SIDES * MAX_SOCKETS)
+
+//
+// Maximum number of memory ranges supported by the memory controller
+//
+#define MAX_RANGES (MAX_ROWS + 5)
+
+//
+// Maximum Number of Log entries
+//
+#define   MEMORY_LOG_MAX_INDEX          16
+
+
+typedef struct _MEMORY_LOG_ENTRY {
+  EFI_STATUS_CODE_VALUE                     Event;
+  EFI_STATUS_CODE_TYPE                      Severity;
+  UINT8                                     Data;
+} MEMORY_LOG_ENTRY;
+
+typedef struct _MEMORY_LOG {
+  UINT8                                     Index;
+  MEMORY_LOG_ENTRY                      Entry[MEMORY_LOG_MAX_INDEX];
+} MEMORY_LOG;
+
+
+
+//
+// Defined ECC types
+//
+#define DUAL_CHANNEL_DDR_ECC_TYPE_NONE             0x01   // No error checking
+#define DUAL_CHANNEL_DDR_ECC_TYPE_EC               0x02   // Error checking only
+#define DUAL_CHANNEL_DDR_ECC_TYPE_SECC             0x04   // Software Scrubbing ECC
+#define DUAL_CHANNEL_DDR_ECC_TYPE_HECC             0x08   // Hardware Scrubbing ECC
+#define DUAL_CHANNEL_DDR_ECC_TYPE_CKECC            0x10   // Chip Kill ECC
+
+//
+// Row configuration status values
+//
+#define DUAL_CHANNEL_DDR_ROW_CONFIG_SUCCESS        0x00  // No error
+#define DUAL_CHANNEL_DDR_ROW_CONFIG_UNKNOWN        0x01  // Pattern mismatch, no memory
+#define DUAL_CHANNEL_DDR_ROW_CONFIG_UNSUPPORTED    0x02  // Memory type not supported
+#define DUAL_CHANNEL_DDR_ROW_CONFIG_ADDRESS_ERROR  0x03  // Row/Col/Bnk mismatch
+#define DUAL_CHANNEL_DDR_ROW_CONFIG_ECC_ERROR      0x04  // Received ECC error
+#define DUAL_CHANNEL_DDR_ROW_CONFIG_NOT_PRESENT    0x05  // Row is not present
+#define DUAL_CHANNEL_DDR_ROW_CONFIG_DISABLED       0x06  // Row is disabled
+
+
+//
+// Memory range types
+//
+typedef enum {
+  DualChannelDdrMainMemory,
+  DualChannelDdrSmramCacheable,
+  DualChannelDdrSmramNonCacheable,
+  DualChannelDdrGraphicsMemoryCacheable,
+  DualChannelDdrGraphicsMemoryNonCacheable,
+  DualChannelDdrReservedMemory,
+  DualChannelDdrMaxMemoryRangeType
+} DUAL_CHANNEL_DDR_MEMORY_RANGE_TYPE;
+
+//
+// Memory map range information
+//
+typedef struct {
+  EFI_PHYSICAL_ADDRESS                          PhysicalAddress;
+  EFI_PHYSICAL_ADDRESS                          CpuAddress;
+  EFI_PHYSICAL_ADDRESS                          RangeLength;
+  DUAL_CHANNEL_DDR_MEMORY_RANGE_TYPE                 Type;
+} DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE;
+typedef struct {
+    unsigned    dramType        :1;                 /**< Type: 0 = RESERVED; 1 = DDR2 */
+    unsigned    dramWidth       :1;                 /**< Width: 0 = x8; 1 = x16 */
+    unsigned    dramDensity     :2;                 /**< Density: 00b = 2Gb; 01b = 1Gb; 10b = 512Mb; 11b = 256Mb */
+    unsigned    dramSpeed       :1;                 /**< Speed Grade: 0 = RESERVED; 1 = 800MT/s;*/
+    unsigned    dramTimings     :3;                 /**< Timings: 4-4-4, 5-5-5, 6-6-6 */
+    unsigned    dramRanks       :1;                 /**< Ranks: 0 = Single Rank; 1 = Dual Rank */
+} DramGeometry;                                     /**< DRAM Geometry Descriptor */
+
+typedef union _RegDRP {
+    UINT32    raw;
+    struct {
+        unsigned rank0Enabled       :1;     /**< Rank 0 Enable */
+        unsigned rank0DevWidth      :2;     /**< DRAM Device Width (x8,x16) */
+        unsigned rank0DevDensity    :2;     /**< DRAM Device Density (256Mb,512Mb,1Gb,2Gb) */
+        unsigned reserved2          :1;
+        unsigned rank1Enabled       :1;     /**< Rank 1 Enable */
+        unsigned reserved3          :5;
+        unsigned dramType           :1;     /**< DRAM Type (0=DDR2) */
+        unsigned reserved4          :5;
+        unsigned reserved5          :14;
+      } field;
+} RegDRP;                                   /**< DRAM Rank Population and Interface Register */
+
+
+typedef union {
+    UINT32    raw;
+    struct {
+        unsigned dramFrequency      :3;     /**< DRAM Frequency (000=RESERVED,010=667,011=800) */
+        unsigned tRP                :2;     /**< Precharge to Activate Delay (3,4,5,6) */
+        unsigned reserved1          :1;
+        unsigned tRCD               :2;     /**< Activate to CAS Delay (3,4,5,6) */
+        unsigned reserved2          :1;
+        unsigned tCL                :2;     /**< CAS Latency (3,4,5,6) */
+        unsigned reserved3          :21;
+      } field;
+} RegDTR0;                                  /**< DRAM Timing Register 0 */
+
+typedef union {
+    UINT32    raw;
+    struct {
+        unsigned tWRRD_dly          :2;     /**< Additional Write to Read Delay (0,1,2,3) */
+        unsigned reserved1          :1;
+        unsigned tRDWR_dly          :2;     /**< Additional Read to Write Delay (0,1,2,3) */
+        unsigned reserved2          :1;
+        unsigned tRDRD_dr_dly       :1;     /**< Additional Read to Read Delay (1,2) */
+        unsigned reserved3          :1;
+        unsigned tRD_dly            :3;     /**< Additional Read Data Sampling Delay (0-7) */
+        unsigned reserved4          :1;
+        unsigned tRCVEN_halfclk_dly :4;     /**< Additional RCVEN Half Clock Delay Control */
+        unsigned reserved5          :1;
+        unsigned readDqDelay        :2;     /**< Read DQ Delay */
+        unsigned reserved6          :13;
+      } field;
+} RegDTR1;                                  /**< DRAM Timing Register 1 */
+
+typedef union {
+    UINT32    raw;
+    struct {
+        unsigned ckStaticDisable    :1;     /**< CK/CK# Static Disable */
+        unsigned reserved1          :3;
+        unsigned ckeStaticDisable   :2;     /**< CKE Static Disable */
+        unsigned reserved2          :8;
+        unsigned refreshPeriod      :2;     /**< Refresh Period (disabled,128clks,3.9us,7.8us) */
+        unsigned refreshQueueDepth  :2;     /**< Refresh Queue Depth (1,2,4,8) */
+        unsigned reserved5          :13;
+        unsigned initComplete       :1;     /**< Initialization Complete */
+      } field;
+} RegDCO;
+
+//
+// MRC Data Structure
+//
+typedef struct {
+    RegDRP          drp;
+    RegDTR0         dtr0;
+    RegDTR1         dtr1;
+    RegDCO          dco;
+    UINT32          reg0104;
+    UINT32          reg0120;
+    UINT32          reg0121;
+    UINT32          reg0123;
+    UINT32          reg0111;
+    UINT32          reg0130;
+    UINT8           refreshPeriod;      /**< Placeholder for the chosen refresh
+                                         *   period.  This value will NOT be
+                                         *   programmed into DCO until all
+                                         *   initialization is done.
+                                         */
+    UINT8           ddr2Odt;            /**< 0 = Disabled, 1 = 75 ohm, 2 = 150ohm, 3 = 50ohm */
+    UINT8           sku;                /**< Detected QuarkNcSocId SKU */
+    UINT8           capabilities;       /**< Capabilities Available on this part */
+    UINT8           state;              /**< NORMAL_BOOT, S3_RESUME */
+    UINT32          memSize;            /**< Memory size */
+    UINT16          pmBase;             /**< PM Base */
+    UINT16          mrcVersion;         /**< MRC Version */
+    UINT32          hecbase;            /**< HECBASE shifted left 16 bits */
+    DramGeometry    geometry;          /**< DRAM Geometry */
+} MRC_DATA_STRUCTURE;             /**< QuarkNcSocId Memory Parameters for MRC */
+
+typedef struct _EFI_MEMINIT_CONFIG_DATA {
+  MRC_DATA_STRUCTURE                        MrcData;
+} EFI_MEMINIT_CONFIG_DATA;
+
+
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCBase.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCBase.h
new file mode 100644
index 0000000000..8c21640f8c
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCBase.h
@@ -0,0 +1,17 @@
+/** @file
+Public include file for the QNC Base
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __INTEL_QNC_BASE_H__
+#define __INTEL_QNC_BASE_H__
+
+#include <IntelQNCRegs.h>
+#include <IntelQNCConfig.h>
+
+#endif
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCConfig.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCConfig.h
new file mode 100644
index 0000000000..17c03a1c72
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCConfig.h
@@ -0,0 +1,100 @@
+/** @file
+Some configuration of QNC Package
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __INTEL_QNC_CONFIG_H__
+#define __INTEL_QNC_CONFIG_H__
+
+//
+// QNC Fixed configurations.
+//
+
+//
+// Memory arbiter fixed config values.
+//
+#define QNC_FIXED_CONFIG_ASTATUS  ((UINT32) (\
+          (ASTATUS_PRI_NORMAL << ASTATUS0_DEFAULT_BP) | \
+          (ASTATUS_PRI_NORMAL << ASTATUS1_DEFAULT_BP) | \
+          (ASTATUS_PRI_URGENT << ASTATUS0_RASISED_BP) | \
+          (ASTATUS_PRI_URGENT << ASTATUS1_RASISED_BP) \
+          ))
+
+//
+// Memory Manager fixed config values.
+//
+#define V_DRAM_NON_HOST_RQ_LIMIT                    2
+
+//
+// RMU Thermal config fixed config values for TS in Vref Mode.
+//
+#define V_TSCGF1_CONFIG_ISNSCURRENTSEL_VREF_MODE    0x04
+#define V_TSCGF2_CONFIG2_ISPARECTRL_VREF_MODE       0x01
+#define V_TSCGF1_CONFIG_IBGEN_VREF_MODE             1
+#define V_TSCGF2_CONFIG_IDSCONTROL_VREF_MODE        0x011b
+#define V_TSCGF2_CONFIG2_ICALCOARSETUNE_VREF_MODE   0x34
+
+//
+// RMU Thermal config fixed config values for TS in Ratiometric mode.
+//
+#define V_TSCGF1_CONFIG_ISNSCURRENTSEL_RATIO_MODE   0x04
+#define V_TSCGF1_CONFIG_ISNSCHOPSEL_RATIO_MODE      0x02
+#define V_TSCGF1_CONFIG_ISNSINTERNALVREFEN_RATIO_MODE 1
+#define V_TSCGF2_CONFIG_IDSCONTROL_RATIO_MODE       0x011f
+#define V_TSCGF2_CONFIG_IDSTIMING_RATIO_MODE        0x0001
+#define V_TSCGF2_CONFIG2_ICALCONFIGSEL_RATIO_MODE   0x01
+#define V_TSCGF2_CONFIG2_ISPARECTRL_RATIO_MODE      0x00
+#define V_TSCGF1_CONFIG_IBGEN_RATIO_MODE            0
+#define V_TSCGF1_CONFIG_IBGCHOPEN_RATIO_MODE        0
+#define V_TSCGF3_CONFIG_ITSGAMMACOEFF_RATIO_MODE    0xC8
+#define V_TSCGF2_CONFIG2_ICALCOARSETUNE_RATIO_MODE  0x17
+
+//
+// iCLK fixed config values.
+//
+#define V_MUXTOP_FLEX2                              3
+#define V_MUXTOP_FLEX1                              1
+
+//
+// PCIe Root Port fixed config values.
+//
+#define V_PCIE_ROOT_PORT_SBIC_VALUE                 (B_QNC_PCIE_IOSFSBCTL_SBIC_IDLE_NEVER)
+
+//
+// QNC structures for configuration.
+//
+
+typedef union {
+  struct {
+    UINT32  PortErrorMask               :8;
+    UINT32  SlotImplemented             :1;
+    UINT32  Reserved1                   :1;
+    UINT32  AspmEnable                  :1;
+    UINT32  AspmAutoEnable              :1;
+    UINT32  AspmL0sEnable               :2;
+    UINT32  AspmL1Enable                :1;
+    UINT32  PmeInterruptEnable          :1;
+    UINT32  PhysicalSlotNumber          :13;
+    UINT32  Reserved2                   :1;
+    UINT32  PmSciEnable                 :1;
+    UINT32  HotplugSciEnable            :1;
+  } Bits;
+  UINT32 Uint32;
+} PCIEXP_ROOT_PORT_CONFIGURATION;
+
+typedef union {
+  UINT32 Uint32;
+  struct {
+    UINT32 Pcie_0     :1;   // 0: Disabled; 1: Enabled*
+    UINT32 Pcie_1     :1;   // 0: Disabled; 1: Enabled*
+    UINT32 Smbus      :1;   // 0: Disabled; 1: Enabled*
+    UINT32 Rsvd       :29;  // 0
+  } Bits;
+} QNC_DEVICE_ENABLES;
+
+#endif
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCDxe.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCDxe.h
new file mode 100644
index 0000000000..45725a4976
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCDxe.h
@@ -0,0 +1,17 @@
+/** @file
+Public include file for the QNC Dxe
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __INTEL_QNC_DXE_H__
+#define __INTEL_QNC_DXE_H__
+
+#include <IntelQNCRegs.h>
+#include <IntelQNCConfig.h>
+
+#endif
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCPeim.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCPeim.h
new file mode 100644
index 0000000000..90cbe35ef9
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCPeim.h
@@ -0,0 +1,17 @@
+/** @file
+Public include file for the QNC Pei
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __INTEL_QNC_PEIM_H__
+#define __INTEL_QNC_PEIM_H__
+
+#include <IntelQNCRegs.h>
+#include <IntelQNCConfig.h>
+
+#endif
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCRegs.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCRegs.h
new file mode 100644
index 0000000000..6f6dd8b323
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCRegs.h
@@ -0,0 +1,48 @@
+/** @file
+Registers definition for Intel QuarkNcSocId.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __INTEL_QNC_REGS_H__
+#define __INTEL_QNC_REGS_H__
+
+#include <QNCAccess.h>
+
+//
+// PCI HostBridge Segment number
+//
+#define QNC_PCI_HOST_BRIDGE_SEGMENT_NUMBER    0
+
+//
+// PCI RootBridge resource allocation's attribute
+//
+#define QNC_PCI_ROOT_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTE \
+  EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
+
+//
+// PCI HostBridge resource appeture
+//
+#define QNC_PCI_HOST_BRIDGE_RESOURCE_APPETURE_BUSBASE     0x0
+#define QNC_PCI_HOST_BRIDGE_RESOURCE_APPETURE_BUSLIMIT    0xff
+#define QNC_PCI_HOST_BRIDGE_RESOURCE_APPETURE_TSEG_SIZE   0x10000000
+
+//
+// PCI RootBridge configure port
+//
+#define QNC_PCI_ROOT_BRIDGE_CONFIGURATION_ADDRESS_PORT  0xCF8
+#define QNC_PCI_ROOT_BRIDGE_CONFIGURATION_DATA_PORT     0xCFC
+
+//
+// PCI Rootbridge's support feature
+//
+#define QNC_PCI_ROOT_BRIDGE_SUPPORTED                   (EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO | \
+                                                         EFI_PCI_ATTRIBUTE_ISA_IO         | \
+                                                         EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO | \
+                                                         EFI_PCI_ATTRIBUTE_VGA_MEMORY     | \
+                                                         EFI_PCI_ATTRIBUTE_VGA_IO)
+
+#endif // __INTEL_QNC_REGS_H__
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/IntelQNCLib.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/IntelQNCLib.h
new file mode 100644
index 0000000000..218fa84917
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/IntelQNCLib.h
@@ -0,0 +1,284 @@
+/** @file
+Library that provides QNC specific library services in PEI phase
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __INTEL_QNC_LIB_H__
+#define __INTEL_QNC_LIB_H__
+
+/**
+  This function initializes the QNC register before MRC.
+  It sets RCBA, PMBASE, disable Watchdog timer and initialize QNC GPIO.
+  If the function cannot complete it'll ASSERT().
+**/
+VOID
+EFIAPI
+PeiQNCPreMemInit (
+  VOID
+  );
+
+
+/**
+  Used to check SCH if it's S3 state.  Clear the register state after query.
+
+  @retval TRUE if it's S3 state.
+  @retval FALSE if it's not S3 state.
+
+**/
+BOOLEAN
+EFIAPI
+QNCCheckS3AndClearState (
+   VOID
+  );
+
+/**
+  Used to check SCH if system wakes up from power on reset. Clear the register state after query.
+
+  @retval TRUE  if system wakes up from power on reset
+  @retval FALSE if system does not wake up from power on reset
+
+**/
+BOOLEAN
+EFIAPI
+QNCCheckPowerOnResetAndClearState (
+   VOID
+  );
+
+/**
+  This function is used to clear SMI and wake status.
+
+**/
+VOID
+EFIAPI
+QNCClearSmiAndWake (
+  VOID
+  );
+
+/**
+  Used to initialize the QNC register after MRC.
+
+**/
+VOID
+EFIAPI
+PeiQNCPostMemInit (
+  VOID
+  );
+
+/** Send DRAM Ready opcode.
+
+  @param[in]       OpcodeParam  Parameter to DRAM ready opcode.
+
+  @retval          VOID
+**/
+VOID
+EFIAPI
+QNCSendOpcodeDramReady (
+  IN UINT32   OpcodeParam
+  );
+
+/**
+
+  Relocate RMU Main binary to memory after MRC to improve performance.
+
+  @param[in]  DestBaseAddress  - Specify the new memory address for the RMU Main binary.
+  @param[in]  SrcBaseAddress   - Specify the current memory address for the RMU Main binary.
+  @param[in]  Size             - Specify size of the RMU Main binary.
+
+  @retval     VOID
+
+**/
+VOID
+EFIAPI
+RmuMainRelocation (
+  IN CONST UINT32   DestBaseAddress,
+  IN CONST UINT32   SrcBaseAddress,
+  IN CONST UINTN    Size
+  );
+
+/**
+  Get the total memory size
+
+**/
+UINT32
+EFIAPI
+QNCGetTotalMemorysize (
+  VOID
+  );
+
+/**
+  Get the memory range of TSEG.
+  The TSEG's memory is below TOLM.
+
+  @param[out] BaseAddress The base address of TSEG's memory range
+  @param[out] MemorySize  The size of TSEG's memory range
+
+**/
+VOID
+EFIAPI
+QNCGetTSEGMemoryRange (
+  OUT UINT64  *BaseAddress,
+  OUT UINT64  *MemorySize
+  );
+
+/**
+  Updates the PAM registers in the MCH for the requested range and mode.
+
+  @param   Start        The start address of the memory region
+  @param   Length       The length, in bytes, of the memory region
+  @param   ReadEnable   Pointer to the boolean variable on whether to enable read for legacy memory section.
+                        If NULL, then read attribute will not be touched by this call.
+  @param   ReadEnable   Pointer to the boolean variable on whether to enable write for legacy memory section.
+                        If NULL, then write attribute will not be touched by this call.
+  @param   Granularity  A pointer to granularity, in bytes, that the PAM registers support
+
+  @retval  RETURN_SUCCESS            The PAM registers in the MCH were updated
+  @retval  RETURN_INVALID_PARAMETER  The memory range is not valid in legacy region.
+
+**/
+RETURN_STATUS
+EFIAPI
+QNCLegacyRegionManipulation (
+  IN  UINT32                  Start,
+  IN  UINT32                  Length,
+  IN  BOOLEAN                 *ReadEnable,
+  IN  BOOLEAN                 *WriteEnable,
+  OUT UINT32                  *Granularity
+  );
+
+/**
+  Do early init of pci express rootports on Soc.
+
+**/
+VOID
+EFIAPI
+PciExpressEarlyInit (
+  VOID
+  );
+
+/**
+  Complete initialization of all the pci express rootports on Soc.
+**/
+EFI_STATUS
+EFIAPI
+PciExpressInit (
+  );
+
+/**
+  Determine if QNC is supported.
+
+  @retval FALSE  QNC is not supported.
+  @retval TRUE   QNC is supported.
+**/
+BOOLEAN
+EFIAPI
+IsQncSupported (
+  VOID
+  );
+
+/**
+  Get the DeviceId of the SoC
+
+  @retval PCI DeviceId of the SoC
+**/
+UINT16
+EFIAPI
+QncGetSocDeviceId (
+  VOID
+  );
+
+/**
+  Enable SMI detection of legacy flash access violations.
+**/
+VOID
+EFIAPI
+QncEnableLegacyFlashAccessViolationSmi (
+  VOID
+  );
+
+/**
+  Setup RMU Thermal sensor registers for Vref mode.
+**/
+VOID
+EFIAPI
+QNCThermalSensorSetVRefMode (
+  VOID
+  );
+
+/**
+  Setup RMU Thermal sensor registers for Ratiometric mode.
+**/
+VOID
+EFIAPI
+QNCThermalSensorSetRatiometricMode (
+  VOID
+  );
+
+/**
+  Setup RMU Thermal sensor trip point values.
+
+  @param[in]  CatastrophicTripOnDegreesCelsius  - Catastrophic set trip point threshold.
+  @param[in]  HotTripOnDegreesCelsius           - Hot set trip point threshold.
+  @param[in]  HotTripOffDegreesCelsius          - Hot clear trip point threshold.
+
+  @retval     VOID
+**/
+EFI_STATUS
+EFIAPI
+QNCThermalSensorSetTripValues (
+  IN  CONST UINTN             CatastrophicTripOnDegreesCelsius,
+  IN  CONST UINTN             HotTripOnDegreesCelsius,
+  IN  CONST UINTN             HotTripOffDegreesCelsius
+  );
+
+/**
+  Enable RMU Thermal sensor with a Catastrophic Trip point.
+
+  @retval  EFI_SUCCESS            Trip points setup.
+  @retval  EFI_INVALID_PARAMETER  Invalid trip point value.
+
+**/
+EFI_STATUS
+EFIAPI
+QNCThermalSensorEnableWithCatastrophicTrip (
+  IN  CONST UINTN             CatastrophicTripOnDegreesCelsius
+  );
+
+/**
+  Lock all RMU Thermal sensor control & trip point registers.
+
+**/
+VOID
+EFIAPI
+QNCThermalSensorLockAllRegisters (
+  VOID
+  );
+
+/**
+  Set chipset policy for double bit ECC error.
+
+  @param[in]       PolicyValue  Policy to config on double bit ECC error.
+
+**/
+VOID
+EFIAPI
+QNCPolicyDblEccBitErr (
+  IN  CONST UINT32                        PolicyValue
+  );
+
+/**
+  Determine if running on secure Quark hardware Sku.
+
+  @retval FALSE  Base Quark Sku or unprovisioned Secure Sku running.
+  @retval TRUE   Provisioned SecureSku hardware running.
+**/
+BOOLEAN
+EFIAPI
+QncIsSecureProvisionedSku (
+  VOID
+  );
+#endif
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/QNCAccessLib.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/QNCAccessLib.h
new file mode 100644
index 0000000000..290902c67f
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/QNCAccessLib.h
@@ -0,0 +1,161 @@
+/** @file
+Library functions for Setting QNC internal network port
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __QNC_ACCESS_LIB_H__
+#define __QNC_ACCESS_LIB_H__
+
+#include <IntelQNCRegs.h>
+
+#define MESSAGE_READ_DW(Port, Reg)  \
+        (UINT32)((QUARK_OPCODE_READ << QNC_MCR_OP_OFFSET) | ((Port << QNC_MCR_PORT_OFFSET) & 0xFF0000) | ((Reg << QNC_MCR_REG_OFFSET) & 0xFF00) | 0xF0)
+
+#define MESSAGE_WRITE_DW(Port, Reg)  \
+        (UINT32)((QUARK_OPCODE_WRITE << QNC_MCR_OP_OFFSET) | ((Port << QNC_MCR_PORT_OFFSET) & 0xFF0000) | ((Reg << QNC_MCR_REG_OFFSET) & 0xFF00) | 0xF0)
+
+#define ALT_MESSAGE_READ_DW(Port, Reg)  \
+        (UINT32)((QUARK_ALT_OPCODE_READ << QNC_MCR_OP_OFFSET) | ((Port << QNC_MCR_PORT_OFFSET) & 0xFF0000) | ((Reg << QNC_MCR_REG_OFFSET) & 0xFF00) | 0xF0)
+
+#define ALT_MESSAGE_WRITE_DW(Port, Reg)  \
+        (UINT32)((QUARK_ALT_OPCODE_WRITE << QNC_MCR_OP_OFFSET) | ((Port << QNC_MCR_PORT_OFFSET) & 0xFF0000) | ((Reg << QNC_MCR_REG_OFFSET) & 0xFF00) | 0xF0)
+
+#define MESSAGE_IO_READ_DW(Port, Reg)  \
+        (UINT32)((QUARK_OPCODE_IO_READ << QNC_MCR_OP_OFFSET) | ((Port << QNC_MCR_PORT_OFFSET) & 0xFF0000) | ((Reg << QNC_MCR_REG_OFFSET) & 0xFF00) | 0xF0)
+
+#define MESSAGE_IO_WRITE_DW(Port, Reg)  \
+        (UINT32)((QUARK_OPCODE_IO_WRITE << QNC_MCR_OP_OFFSET) | ((Port << QNC_MCR_PORT_OFFSET) & 0xFF0000) | ((Reg << QNC_MCR_REG_OFFSET) & 0xFF00) | 0xF0)
+
+#define MESSAGE_SHADOW_DW(Port, Reg)  \
+        (UINT32)((QUARK_DRAM_BASE_ADDR_READY << QNC_MCR_OP_OFFSET) | ((Port << QNC_MCR_PORT_OFFSET) & 0xFF0000) | ((Reg << QNC_MCR_REG_OFFSET) & 0xFF00) | 0xF0)
+
+
+/**
+  Read required data from QNC internal message network
+**/
+UINT32
+EFIAPI
+QNCPortRead(
+  UINT8 Port,
+  UINT32 RegAddress
+  );
+
+/**
+  Write prepared data into QNC internal message network.
+
+**/
+VOID
+EFIAPI
+QNCPortWrite (
+  UINT8 Port,
+  UINT32 RegAddress,
+  UINT32 WriteValue
+  );
+
+/**
+  Read required data from QNC internal message network
+**/
+UINT32
+EFIAPI
+QNCAltPortRead(
+  UINT8 Port,
+  UINT32 RegAddress
+  );
+
+/**
+  Write prepared data into QNC internal message network.
+
+**/
+VOID
+EFIAPI
+QNCAltPortWrite (
+  UINT8 Port,
+  UINT32 RegAddress,
+  UINT32 WriteValue
+  );
+
+/**
+  Read required data from QNC internal message network
+**/
+UINT32
+EFIAPI
+QNCPortIORead(
+  UINT8 Port,
+  UINT32 RegAddress
+  );
+
+/**
+  Write prepared data into QNC internal message network.
+
+**/
+VOID
+EFIAPI
+QNCPortIOWrite (
+  UINT8 Port,
+  UINT32 RegAddress,
+  UINT32 WriteValue
+  );
+
+/**
+  This is for the special consideration for QNC MMIO write, as required by FWG,
+  a reading must be performed after MMIO writing to ensure the expected write
+  is processed and data is flushed into chipset
+
+**/
+RETURN_STATUS
+EFIAPI
+QNCMmIoWrite (
+  UINT32             MmIoAddress,
+  QNC_MEM_IO_WIDTH    Width,
+  UINT32             DataNumber,
+  VOID               *pData
+  );
+
+UINT32
+EFIAPI
+QncHsmmcRead (
+  VOID
+  );
+
+VOID
+EFIAPI
+QncHsmmcWrite (
+  UINT32 WriteValue
+  );
+
+VOID
+EFIAPI
+QncImrWrite (
+  UINT32 ImrBaseOffset,
+  UINT32 ImrLow,
+  UINT32 ImrHigh,
+  UINT32 ImrReadMask,
+  UINT32 ImrWriteMask
+  );
+
+VOID
+EFIAPI
+QncIClkAndThenOr (
+  UINT32 RegAddress,
+  UINT32 AndValue,
+  UINT32 OrValue
+  );
+
+VOID
+EFIAPI
+QncIClkOr (
+  UINT32 RegAddress,
+  UINT32 OrValue
+  );
+
+UINTN
+EFIAPI
+QncGetPciExpressBaseAddress (
+  VOID
+  );
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/QNCSmmLib.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/QNCSmmLib.h
new file mode 100644
index 0000000000..a68ecc4566
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/QNCSmmLib.h
@@ -0,0 +1,57 @@
+/** @file
+QNC Smm Library Services header file.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __QNC_SMM_LIB_H__
+#define __QNC_SMM_LIB_H__
+
+/**
+  This routine is the chipset code that accepts a request to "open" a region of SMRAM.
+  The region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
+  The use of "open" means that the memory is visible from all boot-service
+  and SMM agents.
+
+  @retval FALSE  Cannot open a locked SMRAM region
+  @retval TRUE   Success to open SMRAM region.
+**/
+BOOLEAN
+EFIAPI
+QNCOpenSmramRegion (
+  VOID
+  );
+
+/**
+  This routine is the chipset code that accepts a request to "close" a region of SMRAM.
+  The region could be legacy AB or TSEG near top of physical memory.
+  The use of "close" means that the memory is only visible from SMM agents,
+  not from BS or RT code.
+
+  @retval FALSE  Cannot open a locked SMRAM region
+  @retval TRUE   Success to open SMRAM region.
+**/
+BOOLEAN
+EFIAPI
+QNCCloseSmramRegion (
+  VOID
+  );
+
+/**
+  This routine is the chipset code that accepts a request to "lock" SMRAM.
+  The region could be legacy AB or TSEG near top of physical memory.
+  The use of "lock" means that the memory can no longer be opened
+  to BS state.
+**/
+VOID
+EFIAPI
+QNCLockSmramRegion (
+  VOID
+  );
+
+
+#endif
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Ppi/QNCMemoryInit.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Ppi/QNCMemoryInit.h
new file mode 100644
index 0000000000..498a42b18b
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Ppi/QNCMemoryInit.h
@@ -0,0 +1,36 @@
+/** @file
+Memory Initialization PPI used in EFI PEI interface
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __QNC_MEMORY_INIT_H__
+#define __QNC_MEMORY_INIT_H__
+
+#include "mrc.h"
+
+#define PEI_QNC_MEMORY_INIT_PPI_GUID \
+  {0x21ff1fee, 0xd33a, 0x4fce, {0xa6, 0x5e, 0x95, 0x5e, 0xa3, 0xc4, 0x1f, 0x40}}
+
+
+
+
+//
+// PPI Function Declarations
+//
+typedef
+VOID
+(EFIAPI *PEI_QNC_MEMORY_INIT) (
+  IN OUT    MRCParams_t     *MRCDATA
+  );
+
+typedef struct _PEI_QNC_MEMORY_INIT_PPI {
+  PEI_QNC_MEMORY_INIT     MrcStart;
+}PEI_QNC_MEMORY_INIT_PPI;
+
+extern EFI_GUID gQNCMemoryInitPpiGuid;
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/PchInfo.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/PchInfo.h
new file mode 100644
index 0000000000..18e7f5c4dd
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/PchInfo.h
@@ -0,0 +1,48 @@
+/** @file
+This file defines the QNC Info Protocol.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+#ifndef _PCH_INFO_H_
+#define _PCH_INFO_H_
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID                       gEfiQncInfoProtocolGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _EFI_QNC_INFO_PROTOCOL EFI_QNC_INFO_PROTOCOL;
+
+//
+// Protocol revision number
+// Any backwards compatible changes to this protocol will result in an update in the revision number
+// Major changes will require publication of a new protocol
+//
+// Revision 1:  Original version
+// Revision 2:   Add RCVersion item to EFI_QNC_INFO_PROTOCOL
+//
+#define QNC_INFO_PROTOCOL_REVISION_1  1
+#define QNC_INFO_PROTOCOL_REVISION_2  2
+
+//
+// RCVersion[7:0] is the release number.
+//
+#define QNC_RC_VERSION                0x01020000
+
+//
+// Protocol definition
+//
+struct _EFI_QNC_INFO_PROTOCOL {
+  UINT8   Revision;
+  UINT8   BusNumber;
+  UINT32  RCVersion;
+};
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/PlatformPolicy.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/PlatformPolicy.h
new file mode 100644
index 0000000000..ad79ae3e87
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/PlatformPolicy.h
@@ -0,0 +1,31 @@
+/** @file
+Protocol used for Platform Policy definition.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#ifndef _PLATFORM_POLICY_H_
+#define _PLATFORM_POLICY_H_
+
+typedef struct _EFI_PLATFORM_POLICY_PROTOCOL EFI_PLATFORM_POLICY_PROTOCOL;
+
+#define EFI_PLATFORM_POLICY_PROTOCOL_GUID \
+  { \
+    0x2977064f, 0xab96, 0x4fa9, { 0x85, 0x45, 0xf9, 0xc4, 0x02, 0x51, 0xe0, 0x7f } \
+  }
+
+//
+// Protocol to describe various platform information. Add to this as needed.
+//
+struct _EFI_PLATFORM_POLICY_PROTOCOL {
+  UINT8 NumRsvdSmbusAddresses;
+  UINT8 *RsvdSmbusAddresses;
+};
+
+extern EFI_GUID gEfiPlatformPolicyProtocolGuid;
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/QncS3Support.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/QncS3Support.h
new file mode 100644
index 0000000000..d9d697d844
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/QncS3Support.h
@@ -0,0 +1,84 @@
+/** @file
+This file defines the QNC S3 support Protocol.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+#ifndef _QNC_S3_SUPPORT_PROTOCOL_H_
+#define _QNC_S3_SUPPORT_PROTOCOL_H_
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID                             gEfiQncS3SupportProtocolGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _EFI_QNC_S3_SUPPORT_PROTOCOL EFI_QNC_S3_SUPPORT_PROTOCOL;
+
+typedef enum {
+  QncS3ItemTypeInitPcieRootPortDownstream,
+  QncS3ItemTypeMax
+} EFI_QNC_S3_DISPATCH_ITEM_TYPE;
+
+//
+// It's better not to use pointer here because the size of pointer in DXE is 8, but it's 4 in PEI
+// plug 4 to ParameterSize in PEIM if you really need it
+//
+typedef struct {
+  UINT32                        Reserved;
+} EFI_QNC_S3_PARAMETER_INIT_PCIE_ROOT_PORT_DOWNSTREAM;
+
+typedef union {
+  EFI_QNC_S3_PARAMETER_INIT_PCIE_ROOT_PORT_DOWNSTREAM   PcieRootPortData;
+} EFI_DISPATCH_CONTEXT_UNION;
+
+typedef struct {
+  EFI_QNC_S3_DISPATCH_ITEM_TYPE Type;
+  VOID                          *Parameter;
+} EFI_QNC_S3_DISPATCH_ITEM;
+
+//
+// Member functions
+//
+typedef
+EFI_STATUS
+(EFIAPI *EFI_QNC_S3_SUPPORT_SET_S3_DISPATCH_ITEM) (
+  IN     EFI_QNC_S3_SUPPORT_PROTOCOL   * This,
+  IN     EFI_QNC_S3_DISPATCH_ITEM      * DispatchItem,
+  OUT    VOID                         **S3DispatchEntryPoint,
+  OUT    VOID                         **Context
+  );
+
+/*++
+
+Routine Description:
+
+  Set an item to be dispatched at S3 resume time. At the same time, the entry point
+  of the QNC S3 support image is returned to be used in subsequent boot script save
+  call
+
+Arguments:
+
+  This                    - Pointer to the protocol instance.
+  DispatchItem            - The item to be dispatched.
+  S3DispatchEntryPoint    - The entry point of the QNC S3 support image.
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+
+//
+// Protocol definition
+//
+struct _EFI_QNC_S3_SUPPORT_PROTOCOL {
+  EFI_QNC_S3_SUPPORT_SET_S3_DISPATCH_ITEM SetDispatchItem;
+};
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/SmmIchnDispatch2.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/SmmIchnDispatch2.h
new file mode 100644
index 0000000000..57d919bc5a
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/SmmIchnDispatch2.h
@@ -0,0 +1,115 @@
+/** @file
+Intel-only SMM Child Dispatcher Protocol.
+
+This protocol provides a parent dispatch service for a collection of
+chipset-specific SMI source.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#ifndef __SMM_ICHN_DISPATCH2_H__
+#define __SMM_ICHN_DISPATCH2_H__
+
+//
+// Share some common definitions with Framework SMM
+//
+#include <Protocol/SmmIchnDispatch.h>
+
+#include <PiSmm.h>
+
+//
+// Global ID for the ICH SMI Protocol
+//
+#define EFI_SMM_ICHN_DISPATCH2_PROTOCOL_GUID \
+  { \
+    0xadf3a128, 0x416d, 0x4060, {0x8d, 0xdf, 0x30, 0xa1, 0xd7, 0xaa, 0xb6, 0x99 } \
+  }
+
+typedef struct _EFI_SMM_ICHN_DISPATCH2_PROTOCOL EFI_SMM_ICHN_DISPATCH2_PROTOCOL;
+
+typedef struct {
+  EFI_SMM_ICHN_SMI_TYPE Type;
+} EFI_SMM_ICHN_REGISTER_CONTEXT;
+
+//
+// Member functions
+//
+/**
+  Register a child SMI source dispatch function with a parent SMM driver
+
+  @param  This                  Protocol instance pointer.
+  @param  DispatchFunction      Pointer to dispatch function to be invoked for
+                                this SMI source
+  @param  RegisterContext       Pointer to the dispatch function's context.
+                                The caller fills this context in before calling
+                                the register function to indicate to the register
+                                function the ICHN SMI source for which the dispatch
+                                function should be invoked.
+  @param  DispatchHandle        Handle generated by the dispatcher to track the
+                                function instance.
+
+  @retval EFI_SUCCESS           The dispatch function has been successfully
+                                registered and the SMI source has been enabled.
+  @retval EFI_DEVICE_ERROR      The driver was unable to enable the SMI source.
+  @retval EFI_OUT_OF_RESOURCES  Not enough memory (system or SMM) to manage this
+                                child.
+  @retval EFI_INVALID_PARAMETER RegisterContext is invalid. The ICHN input value
+                                is not within valid range.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SMM_ICHN_DISPATCH2_REGISTER) (
+  IN CONST EFI_SMM_ICHN_DISPATCH2_PROTOCOL   *This,
+  IN       EFI_SMM_HANDLER_ENTRY_POINT2      DispatchFunction,
+  IN OUT   EFI_SMM_ICHN_REGISTER_CONTEXT     *RegisterContext,
+     OUT   EFI_HANDLE                        *DispatchHandle
+  );
+
+/**
+  Unregister a child SMI source dispatch function with a parent SMM driver
+
+  @param  This                  Protocol instance pointer.
+  @param  DispatchHandle        Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS           The dispatch function has been successfully
+                                unregistered and the SMI source has been disabled
+                                if there are no other registered child dispatch
+                                functions for this SMI source.
+  @retval EFI_INVALID_PARAMETER Handle is invalid.
+  @retval other
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SMM_ICHN_DISPATCH2_UNREGISTER) (
+  IN EFI_SMM_ICHN_DISPATCH2_PROTOCOL          *This,
+  IN EFI_HANDLE                               DispatchHandle
+  );
+
+//
+// Interface structure for the SMM Ich n specific SMI Dispatch Protocol
+//
+/**
+  @par Protocol Description:
+  Provides a parent dispatch service for ICH SMI sources.
+
+  @param Register
+  Installs a child service to be dispatched by this protocol.
+
+  @param UnRegister
+  Removes a child service dispatched by this protocol.
+
+**/
+struct _EFI_SMM_ICHN_DISPATCH2_PROTOCOL {
+  EFI_SMM_ICHN_DISPATCH2_REGISTER   Register;
+  EFI_SMM_ICHN_DISPATCH2_UNREGISTER UnRegister;
+};
+
+extern EFI_GUID gEfiSmmIchnDispatch2ProtocolGuid;
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/Spi.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/Spi.h
new file mode 100644
index 0000000000..ee549baa9b
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/Spi.h
@@ -0,0 +1,345 @@
+/** @file
+This file defines the EFI SPI Protocol which implements the
+Intel(R) ICH SPI Host Controller Compatibility Interface.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+#ifndef _SPI_H_
+#define _SPI_H_
+
+//
+// Define the SPI protocol GUID
+//
+// EDK and EDKII have different GUID formats
+//
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define EFI_SPI_PROTOCOL_GUID \
+  { \
+    0x1156efc6, 0xea32, 0x4396, 0xb5, 0xd5, 0x26, 0x93, 0x2e, 0x83, 0xc3, 0x13 \
+  }
+#define EFI_SMM_SPI_PROTOCOL_GUID \
+  { \
+    0xD9072C35, 0xEB8F, 0x43ad, 0xA2, 0x20, 0x34, 0xD4, 0x0E, 0x2A, 0x82, 0x85 \
+  }
+#else
+#define EFI_SPI_PROTOCOL_GUID \
+  { \
+    0x1156efc6, 0xea32, 0x4396, \
+    { \
+      0xb5, 0xd5, 0x26, 0x93, 0x2e, 0x83, 0xc3, 0x13 \
+    } \
+  }
+#define EFI_SMM_SPI_PROTOCOL_GUID \
+  { \
+    0xD9072C35, 0xEB8F, 0x43ad, \
+    { \
+      0xA2, 0x20, 0x34, 0xD4, 0x0E, 0x2A, 0x82, 0x85 \
+    } \
+  }
+#endif
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID                   gEfiSpiProtocolGuid;
+extern EFI_GUID                   gEfiSmmSpiProtocolGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _EFI_SPI_PROTOCOL  EFI_SPI_PROTOCOL;
+
+//
+// SPI protocol data structures and definitions
+//
+//
+// Number of Prefix Opcodes allowed on the SPI interface
+//
+#define SPI_NUM_PREFIX_OPCODE 2
+
+//
+// Number of Opcodes in the Opcode Menu
+//
+#define SPI_NUM_OPCODE  8
+
+#ifdef SERVER_BIOS_FLAG
+//
+// SPI default opcode slots
+//
+#define SPI_OPCODE_JEDEC_ID_INDEX        0
+#endif // SERVER_BIOS_FLAG
+
+//
+// Opcode Type
+//    EnumSpiOpcodeCommand: Command without address
+//    EnumSpiOpcodeRead: Read with address
+//    EnumSpiOpcodeWrite: Write with address
+//
+typedef enum {
+  EnumSpiOpcodeReadNoAddr,
+  EnumSpiOpcodeWriteNoAddr,
+  EnumSpiOpcodeRead,
+  EnumSpiOpcodeWrite,
+  EnumSpiOpcodeMax
+} SPI_OPCODE_TYPE;
+
+typedef enum {
+  EnumSpiCycle20MHz,
+  EnumSpiCycle33MHz,
+  EnumSpiCycle66MHz,  // not supported by PCH
+  EnumSpiCycle50MHz,
+  EnumSpiCycleMax
+} SPI_CYCLE_FREQUENCY;
+
+typedef enum {
+  EnumSpiRegionAll,
+  EnumSpiRegionBios,
+  EnumSpiRegionMe,
+  EnumSpiRegionGbE,
+  EnumSpiRegionDescriptor,
+  EnumSpiRegionPlatformData,
+  EnumSpiRegionMax
+} SPI_REGION_TYPE;
+
+//
+// Hardware Sequencing required operations (as listed in CougarPoint EDS Table 5-55: "Hardware
+// Sequencing Commands and Opcode Requirements"
+//
+typedef enum {
+  EnumSpiOperationWriteStatus,
+  EnumSpiOperationProgramData_1_Byte,
+  EnumSpiOperationProgramData_64_Byte,
+  EnumSpiOperationReadData,
+  EnumSpiOperationWriteDisable,
+  EnumSpiOperationReadStatus,
+  EnumSpiOperationWriteEnable,
+  EnumSpiOperationFastRead,
+  EnumSpiOperationEnableWriteStatus,
+  EnumSpiOperationErase_256_Byte,
+  EnumSpiOperationErase_4K_Byte,
+  EnumSpiOperationErase_8K_Byte,
+  EnumSpiOperationErase_64K_Byte,
+  EnumSpiOperationFullChipErase,
+  EnumSpiOperationJedecId,
+  EnumSpiOperationDualOutputFastRead,
+  EnumSpiOperationDiscoveryParameters,
+  EnumSpiOperationOther,
+  EnumSpiOperationMax
+} SPI_OPERATION;
+
+//
+// Opcode menu entries
+//   Type            Operation Type (value to be programmed to the OPTYPE register)
+//   Code            The opcode (value to be programmed to the OPMENU register)
+//   Frequency       The expected frequency to be used (value to be programmed to the SSFC
+//                   Register)
+//   Operation       Which Hardware Sequencing required operation this opcode respoinds to.
+//                   The required operations are listed in EDS Table 5-55: "Hardware
+//                   Sequencing Commands and Opcode Requirements"
+//                   If the opcode does not corresponds to any operation listed, use
+//                   EnumSpiOperationOther
+//
+typedef struct _SPI_OPCODE_MENU_ENTRY {
+  SPI_OPCODE_TYPE     Type;
+  UINT8               Code;
+  SPI_CYCLE_FREQUENCY Frequency;
+  SPI_OPERATION       Operation;
+} SPI_OPCODE_MENU_ENTRY;
+
+//
+// Initialization data table loaded to the SPI host controller
+//    VendorId        Vendor ID of the SPI device
+//    DeviceId0       Device ID0 of the SPI device
+//    DeviceId1       Device ID1 of the SPI device
+//    PrefixOpcode    Prefix opcodes which are loaded into the SPI host controller
+//    OpcodeMenu      Opcodes which are loaded into the SPI host controller Opcode Menu
+//    BiosStartOffset The offset of the start of the BIOS image relative to the flash device.
+//                    Please note this is a Flash Linear Address, NOT a memory space address.
+//                    This value is platform specific and depends on the system flash map.
+//                    This value is only used on non Descriptor mode.
+//    BiosSize        The the BIOS Image size in flash. This value is platform specific
+//                    and depends on the system flash map. Please note BIOS Image size may
+//                    be smaller than BIOS Region size (in Descriptor Mode) or the flash size
+//                    (in Non Descriptor Mode), and in this case, BIOS Image is supposed to be
+//                    placed at the top end of the BIOS Region (in Descriptor Mode) or the flash
+//                    (in Non Descriptor Mode)
+//
+typedef struct _SPI_INIT_TABLE {
+  UINT8                 VendorId;
+  UINT8                 DeviceId0;
+  UINT8                 DeviceId1;
+  UINT8                 PrefixOpcode[SPI_NUM_PREFIX_OPCODE];
+  SPI_OPCODE_MENU_ENTRY OpcodeMenu[SPI_NUM_OPCODE];
+  UINTN                 BiosStartOffset;
+  UINTN                 BiosSize;
+} SPI_INIT_TABLE;
+
+//
+// Public Info struct to show current initialized state of the spi interface.
+// OpcodeIndex must be less then SPI_NUM_OPCODE for operation to be supported.
+//
+typedef struct _SPI_INIT_INFO {
+  SPI_INIT_TABLE        *InitTable;
+  UINT8                 JedecIdOpcodeIndex;
+  UINT8                 OtherOpcodeIndex;
+  UINT8                 WriteStatusOpcodeIndex;
+  UINT8                 ProgramOpcodeIndex;
+  UINT8                 ReadOpcodeIndex;
+  UINT8                 EraseOpcodeIndex;
+  UINT8                 ReadStatusOpcodeIndex;
+  UINT8                 FullChipEraseOpcodeIndex;
+} SPI_INIT_INFO;
+
+//
+// Protocol member functions
+//
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SPI_INIT) (
+  IN EFI_SPI_PROTOCOL     * This,
+  IN SPI_INIT_TABLE       * InitTable
+  );
+/*++
+
+Routine Description:
+
+  Initializes the host controller to execute SPI commands.
+
+Arguments:
+
+  This                    Pointer to the EFI_SPI_PROTOCOL instance.
+  InitTable               Pointer to caller-allocated buffer containing the SPI
+                          interface initialization table.
+
+Returns:
+
+  EFI_SUCCESS             Opcode initialization on the SPI host controller completed.
+  EFI_ACCESS_DENIED       The SPI configuration interface is locked.
+  EFI_OUT_OF_RESOURCES    Not enough resource available to initialize the device.
+  EFI_DEVICE_ERROR        Device error, operation failed.
+
+--*/
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SPI_LOCK) (
+  IN EFI_SPI_PROTOCOL     * This
+  );
+/*++
+
+Routine Description:
+
+  Lock the SPI Static Configuration Interface.
+  Once locked, the interface is no longer open for configuration changes.
+  The lock state automatically clears on next system reset.
+
+Arguments:
+
+  This      Pointer to the EFI_SPI_PROTOCOL instance.
+
+Returns:
+
+  EFI_SUCCESS             Lock operation succeed.
+  EFI_DEVICE_ERROR        Device error, operation failed.
+  EFI_ACCESS_DENIED       The interface has already been locked.
+
+--*/
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SPI_EXECUTE) (
+  IN     EFI_SPI_PROTOCOL   * This,
+  IN     UINT8              OpcodeIndex,
+  IN     UINT8              PrefixOpcodeIndex,
+  IN     BOOLEAN            DataCycle,
+  IN     BOOLEAN            Atomic,
+  IN     BOOLEAN            ShiftOut,
+  IN     UINTN              Address,
+  IN     UINT32             DataByteCount,
+  IN OUT UINT8              *Buffer,
+  IN     SPI_REGION_TYPE    SpiRegionType
+  );
+/*++
+
+Routine Description:
+
+  Execute SPI commands from the host controller.
+
+Arguments:
+
+  This                    Pointer to the EFI_SPI_PROTOCOL instance.
+  OpcodeIndex             Index of the command in the OpCode Menu.
+  PrefixOpcodeIndex       Index of the first command to run when in an atomic cycle sequence.
+  DataCycle               TRUE if the SPI cycle contains data
+  Atomic                  TRUE if the SPI cycle is atomic and interleave cycles are not allowed.
+  ShiftOut                If DataByteCount is not zero, TRUE to shift data out and FALSE to shift data in.
+  Address                 In Descriptor Mode, for Descriptor Region, GbE Region, ME Region and Platform
+                          Region, this value specifies the offset from the Region Base; for BIOS Region,
+                          this value specifies the offset from the start of the BIOS Image. In Non
+                          Descriptor Mode, this value specifies the offset from the start of the BIOS Image.
+                          Please note BIOS Image size may be smaller than BIOS Region size (in Descriptor
+                          Mode) or the flash size (in Non Descriptor Mode), and in this case, BIOS Image is
+                          supposed to be placed at the top end of the BIOS Region (in Descriptor Mode) or
+                          the flash (in Non Descriptor Mode)
+  DataByteCount           Number of bytes in the data portion of the SPI cycle.
+  Buffer                  Pointer to caller-allocated buffer containing the dada received or sent during the SPI cycle.
+  SpiRegionType           SPI Region type. Values EnumSpiRegionBios, EnumSpiRegionGbE, EnumSpiRegionMe,
+                          EnumSpiRegionDescriptor, and EnumSpiRegionPlatformData are only applicable in
+                          Descriptor mode. Value EnumSpiRegionAll is applicable to both Descriptor Mode
+                          and Non Descriptor Mode, which indicates "SpiRegionOffset" is actually relative
+                          to base of the 1st flash device (i.e., it is a Flash Linear Address).
+
+Returns:
+
+  EFI_SUCCESS             Command succeed.
+  EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  EFI_UNSUPPORTED         Command not supported.
+  EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+
+--*/
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SPI_INFO) (
+  IN EFI_SPI_PROTOCOL     *This,
+  OUT SPI_INIT_INFO      **InitInfoPtr
+  );
+/*++
+
+Routine Description:
+
+  Return info about SPI host controller, to help callers usage of Execute
+  service.
+
+  If 0xff is returned as an opcode index in init info struct
+  then device does not support the operation.
+
+Arguments:
+
+  This                    Pointer to the EFI_SPI_PROTOCOL instance.
+  InitInfoPtr             Pointer to init info written to this memory location.
+
+Returns:
+
+  EFI_SUCCESS             Information returned.
+  EFI_INVALID_PARAMETER   Invalid parameter.
+  EFI_NOT_READY           Required resources not setup.
+  Others                  Unexpected error happened.
+
+--*/
+
+//
+// Protocol definition
+//
+struct _EFI_SPI_PROTOCOL {
+  EFI_SPI_INIT    Init;
+  EFI_SPI_LOCK    Lock;
+  EFI_SPI_EXECUTE Execute;
+  EFI_SPI_INFO    Info;
+};
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QNCAccess.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QNCAccess.h
new file mode 100644
index 0000000000..a03454369c
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QNCAccess.h
@@ -0,0 +1,177 @@
+/** @file
+Macros to simplify and abstract the interface to PCI configuration.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#ifndef _QNC_ACCESS_H_
+#define _QNC_ACCESS_H_
+
+#include "QuarkNcSocId.h"
+#include "QNCCommonDefinitions.h"
+
+#define EFI_LPC_PCI_ADDRESS( Register ) \
+  EFI_PCI_ADDRESS(PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, PCI_FUNCTION_NUMBER_QNC_LPC, Register)
+
+//
+// QNC Controller PCI access macros
+//
+#define QNC_RCRB_BASE (QNCMmio32 (PciDeviceMmBase (0, PCI_DEVICE_NUMBER_QNC_LPC, 0), R_QNC_LPC_RCBA) & B_QNC_LPC_RCBA_MASK)
+
+//
+// Device 0x1f, Function 0
+//
+
+#define LpcPciCfg32( Register ) \
+  QNCMmPci32(0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register )
+
+#define LpcPciCfg32Or( Register, OrData ) \
+  QNCMmPci32Or( 0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register, OrData )
+
+#define LpcPciCfg32And( Register, AndData ) \
+  QNCMmPci32And( 0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register, AndData )
+
+#define LpcPciCfg32AndThenOr( Register, AndData, OrData ) \
+  QNCMmPci32AndThenOr( 0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register, AndData, OrData )
+
+#define LpcPciCfg16( Register ) \
+  QNCMmPci16( 0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register )
+
+#define LpcPciCfg16Or( Register, OrData ) \
+  QNCMmPci16Or(  0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register, OrData )
+
+#define LpcPciCfg16And( Register, AndData ) \
+  QNCMmPci16And( 0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register, AndData )
+
+#define LpcPciCfg16AndThenOr( Register, AndData, OrData ) \
+  QNCMmPci16AndThenOr( 0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register, AndData, OrData )
+
+#define LpcPciCfg8( Register ) \
+  QNCMmPci8( 0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register )
+
+#define LpcPciCfg8Or( Register, OrData ) \
+  QNCMmPci8Or(  0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register, OrData )
+
+#define LpcPciCfg8And( Register, AndData ) \
+  QNCMmPci8And(  0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register, AndData )
+
+#define LpcPciCfg8AndThenOr( Register, AndData, OrData ) \
+  QNCMmPci8AndThenOr(  0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register, AndData, OrData )
+
+//
+// Root Complex Register Block
+//
+
+#define MmRcrb32( Register ) \
+  QNCMmio32( QNC_RCRB_BASE, Register )
+
+#define MmRcrb32Or( Register, OrData ) \
+  QNCMmio32Or( QNC_RCRB_BASE, Register, OrData )
+
+#define MmRcrb32And( Register, AndData ) \
+  QNCMmio32And( QNC_RCRB_BASE, Register, AndData )
+
+#define MmRcrb32AndThenOr( Register, AndData, OrData ) \
+  QNCMmio32AndThenOr( QNC_RCRB_BASE, Register, AndData, OrData )
+
+#define MmRcrb16( Register ) \
+  QNCMmio16( QNC_RCRB_BASE, Register )
+
+#define MmRcrb16Or( Register, OrData ) \
+  QNCMmio16Or( QNC_RCRB_BASE, Register, OrData )
+
+#define MmRcrb16And( Register, AndData ) \
+  QNCMmio16And( QNC_RCRB_BASE, Register, AndData )
+
+#define MmRcrb16AndThenOr( Register, AndData, OrData ) \
+  QNCMmio16AndThenOr( QNC_RCRB_BASE, Register, AndData, OrData )
+
+#define MmRcrb8( Register ) \
+  QNCMmio8( QNC_RCRB_BASE, Register )
+
+#define MmRcrb8Or( Register, OrData ) \
+  QNCMmio8Or( QNC_RCRB_BASE, Register, OrData )
+
+#define MmRcrb8And( Register, AndData ) \
+  QNCMmio8And( QNC_RCRB_BASE, Register, AndData )
+
+#define MmRcrb8AndThenOr( Register, AndData, OrData ) \
+  QNCMmio8AndThenOr( QNC_RCRB_BASE, Register, AndData, OrData )
+
+//
+// Memory Controller PCI access macros
+//
+
+//
+// Device 0, Function 0
+//
+
+#define McD0PciCfg64(Register)                              QNCMmPci32           (0, MC_BUS, 0, 0, Register)
+#define McD0PciCfg64Or(Register, OrData)                    QNCMmPci32Or         (0, MC_BUS, 0, 0, Register, OrData)
+#define McD0PciCfg64And(Register, AndData)                  QNCMmPci32And        (0, MC_BUS, 0, 0, Register, AndData)
+#define McD0PciCfg64AndThenOr(Register, AndData, OrData)    QNCMmPci32AndThenOr  (0, MC_BUS, 0, 0, Register, AndData, OrData)
+
+#define McD0PciCfg32(Register)                              QNCMmPci32           (0, MC_BUS, 0, 0, Register)
+#define McD0PciCfg32Or(Register, OrData)                    QNCMmPci32Or         (0, MC_BUS, 0, 0, Register, OrData)
+#define McD0PciCfg32And(Register, AndData)                  QNCMmPci32And        (0, MC_BUS, 0, 0, Register, AndData)
+#define McD0PciCfg32AndThenOr(Register, AndData, OrData)    QNCMmPci32AndThenOr  (0, MC_BUS, 0, 0, Register, AndData, OrData)
+
+#define McD0PciCfg16(Register)                              QNCMmPci16           (0, MC_BUS, 0, 0, Register)
+#define McD0PciCfg16Or(Register, OrData)                    QNCMmPci16Or         (0, MC_BUS, 0, 0, Register, OrData)
+#define McD0PciCfg16And(Register, AndData)                  QNCMmPci16And        (0, MC_BUS, 0, 0, Register, AndData)
+#define McD0PciCfg16AndThenOr(Register, AndData, OrData)    QNCMmPci16AndThenOr  (0, MC_BUS, 0, 0, Register, AndData, OrData)
+
+#define McD0PciCfg8(Register)                               QNCMmPci8            (0, MC_BUS, 0, 0, Register)
+#define McD0PciCfg8Or(Register, OrData)                     QNCMmPci8Or          (0, MC_BUS, 0, 0, Register, OrData)
+#define McD0PciCfg8And(Register, AndData)                   QNCMmPci8And         (0, MC_BUS, 0, 0, Register, AndData)
+#define McD0PciCfg8AndThenOr( Register, AndData, OrData )   QNCMmPci8AndThenOr   (0, MC_BUS, 0, 0, Register, AndData, OrData)
+
+
+//
+// Memory Controller Hub Memory Mapped IO register access ???
+//
+#define MCH_REGION_BASE                     (McD0PciCfg64 (MC_MCHBAR_OFFSET) & ~BIT0)
+#define McMmioAddress(Register)             ((UINTN) MCH_REGION_BASE + (UINTN) (Register))
+
+#define McMmio32Ptr(Register)               ((volatile UINT32*) McMmioAddress (Register))
+#define McMmio64Ptr(Register)               ((volatile UINT64*) McMmioAddress (Register))
+
+#define McMmio64(Register)                            *McMmio64Ptr( Register )
+#define McMmio64Or(Register, OrData)                  (McMmio64 (Register) |= (UINT64)(OrData))
+#define McMmio64And(Register, AndData)                (McMmio64 (Register) &= (UINT64)(AndData))
+#define McMmio64AndThenOr(Register, AndData, OrData)  (McMmio64 ( Register ) = (McMmio64( Register ) & (UINT64)(AndData)) | (UINT64)(OrData))
+
+#define McMmio32(Register)                            *McMmio32Ptr (Register)
+#define McMmio32Or(Register, OrData)                  (McMmio32 (Register) |= (UINT32)(OrData))
+#define McMmio32And(Register, AndData)                (McMmio32 (Register) &= (UINT32)(AndData))
+#define McMmio32AndThenOr(Register, AndData, OrData)  (McMmio32 (Register) = (McMmio32 (Register) & (UINT32) (AndData)) | (UINT32) (OrData))
+
+#define McMmio16Ptr(Register)                         ((volatile UINT16*) McMmioAddress (Register))
+#define McMmio16(Register)                            *McMmio16Ptr (Register)
+#define McMmio16Or(Register, OrData)                  (McMmio16 (Register) |= (UINT16) (OrData))
+#define McMmio16And(Register, AndData)                (McMmio16 (Register) &= (UINT16) (AndData))
+#define McMmio16AndThenOr(Register, AndData, OrData)  (McMmio16 (Register) = (McMmio16 (Register) & (UINT16) (AndData)) | (UINT16) (OrData))
+
+#define McMmio8Ptr(Register)                          ((volatile UINT8 *)McMmioAddress (Register))
+#define McMmio8(Register)                             *McMmio8Ptr (Register)
+#define McMmio8Or(Register, OrData)                   (McMmio8 (Register) |= (UINT8) (OrData))
+#define McMmio8And(Register, AndData)                 (McMmio8 (Register) &= (UINT8) (AndData))
+#define McMmio8AndThenOr(Register, AndData, OrData)   (McMmio8 (Register) = (McMmio8 (Register) & (UINT8) (AndData)) | (UINT8) (OrData))
+
+//
+// QNC memory mapped related data structure deifinition
+//
+typedef enum {
+  QNCMmioWidthUint8  = 0,
+  QNCMmioWidthUint16 = 1,
+  QNCMmioWidthUint32 = 2,
+  QNCMmioWidthUint64 = 3,
+  QNCMmioWidthMaximum
+} QNC_MEM_IO_WIDTH;
+
+#endif
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QNCCommonDefinitions.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QNCCommonDefinitions.h
new file mode 100644
index 0000000000..1e0451302b
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QNCCommonDefinitions.h
@@ -0,0 +1,350 @@
+/** @file
+This header file provides common definitions just for MCH using to avoid including extra module's file.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _QNC_COMMON_DEFINITIONS_H_
+#define _QNC_COMMON_DEFINITIONS_H_
+
+//
+// PCI CONFIGURATION MAP REGISTER OFFSETS
+//
+#ifndef PCI_VID
+#define PCI_VID             0x0000        // Vendor ID Register
+#define PCI_DID             0x0002        // Device ID Register
+#define PCI_CMD             0x0004        // PCI Command Register
+#define PCI_STS             0x0006        // PCI Status Register
+#define PCI_RID             0x0008        // Revision ID Register
+#define PCI_IFT             0x0009        // Interface Type
+#define PCI_SCC             0x000A        // Sub Class Code Register
+#define PCI_BCC             0x000B        // Base Class Code Register
+#define PCI_CLS             0x000C        // Cache Line Size
+#define PCI_PMLT            0x000D        // Primary Master Latency Timer
+#define PCI_HDR             0x000E        // Header Type Register
+#define PCI_BIST            0x000F        // Built in Self Test Register
+#define PCI_BAR0            0x0010        // Base Address Register 0
+#define PCI_BAR1            0x0014        // Base Address Register 1
+#define PCI_BAR2            0x0018        // Base Address Register 2
+#define PCI_PBUS            0x0018        // Primary Bus Number Register
+#define PCI_SBUS            0x0019        // Secondary Bus Number Register
+#define PCI_SUBUS           0x001A        // Subordinate Bus Number Register
+#define PCI_SMLT            0x001B        // Secondary Master Latency Timer
+#define PCI_BAR3            0x001C        // Base Address Register 3
+#define PCI_IOBASE          0x001C        // I/O base Register
+#define PCI_IOLIMIT         0x001D        // I/O Limit Register
+#define PCI_SECSTATUS       0x001E        // Secondary Status Register
+#define PCI_BAR4            0x0020        // Base Address Register 4
+#define PCI_MEMBASE         0x0020        // Memory Base Register
+#define PCI_MEMLIMIT        0x0022        // Memory Limit Register
+#define PCI_BAR5            0x0024        // Base Address Register 5
+#define PCI_PRE_MEMBASE     0x0024        // Prefetchable memory Base register
+#define PCI_PRE_MEMLIMIT    0x0026        // Prefetchable memory Limit register
+#define PCI_PRE_MEMBASE_U   0x0028        // Prefetchable memory base upper 32 bits
+#define PCI_PRE_MEMLIMIT_U  0x002C        // Prefetchable memory limit upper 32 bits
+#define PCI_SVID            0x002C        // Subsystem Vendor ID
+#define PCI_SID             0x002E        // Subsystem ID
+#define PCI_IOBASE_U        0x0030        // I/O base Upper Register
+#define PCI_IOLIMIT_U       0x0032        // I/O Limit Upper Register
+#define PCI_CAPP            0x0034        // Capabilities Pointer
+#define PCI_EROM            0x0038        // Expansion ROM Base Address
+#define PCI_INTLINE         0x003C        // Interrupt Line Register
+#define PCI_INTPIN          0x003D        // Interrupt Pin Register
+#define PCI_MAXGNT          0x003E        // Max Grant Register
+#define PCI_BRIDGE_CNTL     0x003E        // Bridge Control Register
+#define PCI_MAXLAT          0x003F        // Max Latency Register
+#endif
+//
+// Bit Difinitions
+//
+#ifndef BIT0
+#define BIT0                     0x0001
+#define BIT1                     0x0002
+#define BIT2                     0x0004
+#define BIT3                     0x0008
+#define BIT4                     0x0010
+#define BIT5                     0x0020
+#define BIT6                     0x0040
+#define BIT7                     0x0080
+#define BIT8                     0x0100
+#define BIT9                     0x0200
+#define BIT10                    0x0400
+#define BIT11                    0x0800
+#define BIT12                    0x1000
+#define BIT13                    0x2000
+#define BIT14                    0x4000
+#define BIT15                    0x8000
+#define BIT16                0x00010000
+#define BIT17                0x00020000
+#define BIT18                0x00040000
+#define BIT19                0x00080000
+#define BIT20                0x00100000
+#define BIT21                0x00200000
+#define BIT22                0x00400000
+#define BIT23                0x00800000
+#define BIT24                0x01000000
+#define BIT25                0x02000000
+#define BIT26                0x04000000
+#define BIT27                0x08000000
+#define BIT28                0x10000000
+#define BIT29                0x20000000
+#define BIT30                0x40000000
+#define BIT31                0x80000000
+#endif
+
+
+//
+//  Common Memory mapped Io access macros ------------------------------------------
+//
+#define QNCMmioAddress( BaseAddr, Register ) \
+    ( (UINTN)BaseAddr + \
+      (UINTN)(Register) \
+    )
+
+//
+// UINT64
+//
+#define QNCMmio64Ptr( BaseAddr, Register ) \
+    ( (volatile UINT64 *)QNCMmioAddress( BaseAddr, Register ) )
+
+#define QNCMmio64( BaseAddr, Register ) \
+    *QNCMmio64Ptr( BaseAddr, Register )
+
+#define QNCMmio64Or( BaseAddr, Register, OrData ) \
+    QNCMmio64( BaseAddr, Register ) = \
+      (UINT64) ( \
+        QNCMmio64( BaseAddr, Register ) | \
+        (UINT64)(OrData) \
+      )
+
+#define QNCMmio64And( BaseAddr, Register, AndData ) \
+    QNCMmio64( BaseAddr, Register ) = \
+      (UINT64) ( \
+        QNCMmio64( BaseAddr, Register ) & \
+        (UINT64)(AndData) \
+      )
+
+#define QNCMmio64AndThenOr( BaseAddr, Register, AndData, OrData ) \
+    QNCMmio64( BaseAddr, Register ) = \
+      (UINT64) ( \
+        ( QNCMmio64( BaseAddr, Register ) & \
+            (UINT64)(AndData) \
+        ) | \
+        (UINT64)(OrData) \
+      )
+
+//
+// UINT32
+//
+#define QNCMmio32Ptr( BaseAddr, Register ) \
+    ( (volatile UINT32 *)QNCMmioAddress( BaseAddr, Register ) )
+
+#define QNCMmio32( BaseAddr, Register ) \
+    *QNCMmio32Ptr( BaseAddr, Register )
+
+#define QNCMmio32Or( BaseAddr, Register, OrData ) \
+    QNCMmio32( BaseAddr, Register ) = \
+      (UINT32) ( \
+        QNCMmio32( BaseAddr, Register ) | \
+        (UINT32)(OrData) \
+      )
+
+#define QNCMmio32And( BaseAddr, Register, AndData ) \
+    QNCMmio32( BaseAddr, Register ) = \
+      (UINT32) ( \
+        QNCMmio32( BaseAddr, Register ) & \
+        (UINT32)(AndData) \
+      )
+
+#define QNCMmio32AndThenOr( BaseAddr, Register, AndData, OrData ) \
+    QNCMmio32( BaseAddr, Register ) = \
+      (UINT32) ( \
+        ( QNCMmio32( BaseAddr, Register ) & \
+            (UINT32)(AndData) \
+        ) | \
+        (UINT32)(OrData) \
+      )
+//
+// UINT16
+//
+
+#define QNCMmio16Ptr( BaseAddr, Register ) \
+    ( (volatile UINT16 *)QNCMmioAddress( BaseAddr, Register ) )
+
+#define QNCMmio16( BaseAddr, Register ) \
+    *QNCMmio16Ptr( BaseAddr, Register )
+
+#define QNCMmio16Or( BaseAddr, Register, OrData ) \
+    QNCMmio16( BaseAddr, Register ) = \
+      (UINT16) ( \
+        QNCMmio16( BaseAddr, Register ) | \
+        (UINT16)(OrData) \
+      )
+
+#define QNCMmio16And( BaseAddr, Register, AndData ) \
+    QNCMmio16( BaseAddr, Register ) = \
+      (UINT16) ( \
+        QNCMmio16( BaseAddr, Register ) & \
+        (UINT16)(AndData) \
+      )
+
+#define QNCMmio16AndThenOr( BaseAddr, Register, AndData, OrData ) \
+    QNCMmio16( BaseAddr, Register ) = \
+      (UINT16) ( \
+        ( QNCMmio16( BaseAddr, Register ) & \
+            (UINT16)(AndData) \
+        ) | \
+        (UINT16)(OrData) \
+      )
+//
+// UINT8
+//
+#define QNCMmio8Ptr( BaseAddr, Register ) \
+    ( (volatile UINT8 *)QNCMmioAddress( BaseAddr, Register ) )
+
+#define QNCMmio8( BaseAddr, Register ) \
+    *QNCMmio8Ptr( BaseAddr, Register )
+
+#define QNCMmio8Or( BaseAddr, Register, OrData ) \
+    QNCMmio8( BaseAddr, Register ) = \
+      (UINT8) ( \
+        QNCMmio8( BaseAddr, Register ) | \
+        (UINT8)(OrData) \
+      )
+
+#define QNCMmio8And( BaseAddr, Register, AndData ) \
+    QNCMmio8( BaseAddr, Register ) = \
+      (UINT8) ( \
+        QNCMmio8( BaseAddr, Register ) & \
+        (UINT8)(AndData) \
+      )
+
+#define QNCMmio8AndThenOr( BaseAddr, Register, AndData, OrData ) \
+    QNCMmio8( BaseAddr, Register ) = \
+      (UINT8) ( \
+        ( QNCMmio8( BaseAddr, Register ) & \
+            (UINT8)(AndData) \
+          ) | \
+        (UINT8)(OrData) \
+      )
+
+//
+//  Common Memory mapped Pci access macros ------------------------------------------
+//
+
+#define QNCMmPciAddress( Segment, Bus, Device, Function, Register ) \
+  ( (UINTN) QncGetPciExpressBaseAddress() + \
+    (UINTN)(Bus << 20) + \
+    (UINTN)(Device << 15) + \
+    (UINTN)(Function << 12) + \
+    (UINTN)(Register) \
+  )
+
+//
+// Macro to calculate the Pci device's base memory mapped address
+//
+#define PciDeviceMmBase( Bus, Device, Function) \
+    ( (UINTN) QncGetPciExpressBaseAddress () + \
+      (UINTN)(Bus << 20) + \
+      (UINTN)(Device << 15) + \
+      (UINTN)(Function << 12) \
+    )
+
+//
+// UINT32
+//
+#define QNCMmPci32Ptr( Segment, Bus, Device, Function, Register ) \
+  ( (volatile UINT32 *)QNCMmPciAddress( Segment, Bus, Device, Function, Register ) )
+
+#define QNCMmPci32( Segment, Bus, Device, Function, Register ) \
+  *QNCMmPci32Ptr( Segment, Bus, Device, Function, Register )
+
+#define QNCMmPci32Or( Segment, Bus, Device, Function, Register, OrData ) \
+  QNCMmPci32( Segment, Bus, Device, Function, Register ) = \
+    (UINT32) ( \
+      QNCMmPci32( Segment, Bus, Device, Function, Register ) | \
+      (UINT32)(OrData) \
+    )
+
+#define QNCMmPci32And( Segment, Bus, Device, Function, Register, AndData ) \
+  QNCMmPci32( Segment, Bus, Device, Function, Register ) = \
+    (UINT32) ( \
+      QNCMmPci32( Segment, Bus, Device, Function, Register ) & \
+      (UINT32)(AndData) \
+    )
+
+#define QNCMmPci32AndThenOr( Segment, Bus, Device, Function, Register, AndData, OrData ) \
+  QNCMmPci32( Segment, Bus, Device, Function, Register ) = \
+    (UINT32) ( \
+      ( QNCMmPci32( Segment, Bus, Device, Function, Register ) & \
+          (UINT32)(AndData) \
+      ) | \
+      (UINT32)(OrData) \
+    )
+//
+// UINT16
+//
+#define QNCMmPci16Ptr( Segment, Bus, Device, Function, Register ) \
+  ( (volatile UINT16 *)QNCMmPciAddress( Segment, Bus, Device, Function, Register ) )
+
+#define QNCMmPci16( Segment, Bus, Device, Function, Register ) \
+  *QNCMmPci16Ptr( Segment, Bus, Device, Function, Register )
+
+#define QNCMmPci16Or( Segment, Bus, Device, Function, Register, OrData ) \
+  QNCMmPci16( Segment, Bus, Device, Function, Register ) = \
+    (UINT16) ( \
+      QNCMmPci16( Segment, Bus, Device, Function, Register ) | \
+      (UINT16)(OrData) \
+    )
+
+#define QNCMmPci16And( Segment, Bus, Device, Function, Register, AndData ) \
+  QNCMmPci16( Segment, Bus, Device, Function, Register ) = \
+    (UINT16) ( \
+      QNCMmPci16( Segment, Bus, Device, Function, Register ) & \
+      (UINT16)(AndData) \
+    )
+
+#define QNCMmPci16AndThenOr( Segment, Bus, Device, Function, Register, AndData, OrData ) \
+  QNCMmPci16( Segment, Bus, Device, Function, Register ) = \
+    (UINT16) ( \
+      ( QNCMmPci16( Segment, Bus, Device, Function, Register ) & \
+          (UINT16)(AndData) \
+      ) | \
+      (UINT16)(OrData) \
+    )
+//
+// UINT8
+//
+#define QNCMmPci8Ptr( Segment, Bus, Device, Function, Register ) \
+  ( (volatile UINT8 *)QNCMmPciAddress( Segment, Bus, Device, Function, Register ) )
+
+#define QNCMmPci8( Segment, Bus, Device, Function, Register ) \
+  *QNCMmPci8Ptr( Segment, Bus, Device, Function, Register )
+
+#define QNCMmPci8Or( Segment, Bus, Device, Function, Register, OrData ) \
+  QNCMmPci8( Segment, Bus, Device, Function, Register ) = \
+    (UINT8) ( \
+      QNCMmPci8( Segment, Bus, Device, Function, Register ) | \
+      (UINT8)(OrData) \
+    )
+
+#define QNCMmPci8And( Segment, Bus, Device, Function, Register, AndData ) \
+  QNCMmPci8( Segment, Bus, Device, Function, Register ) = \
+    (UINT8) ( \
+      QNCMmPci8( Segment, Bus, Device, Function, Register ) & \
+      (UINT8)(AndData) \
+    )
+
+#define QNCMmPci8AndThenOr( Segment, Bus, Device, Function, Register, AndData, OrData ) \
+  QNCMmPci8( Segment, Bus, Device, Function, Register ) = \
+    (UINT8) ( \
+      ( QNCMmPci8( Segment, Bus, Device, Function, Register ) & \
+          (UINT8)(AndData) \
+        ) | \
+      (UINT8)(OrData) \
+    )
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QuarkNcSocId.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QuarkNcSocId.h
new file mode 100644
index 0000000000..33aab21f1d
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QuarkNcSocId.h
@@ -0,0 +1,751 @@
+/** @file
+QuarkNcSocId Register Definitions
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Definitions beginning with "R_" are registers
+Definitions beginning with "B_" are bits within registers
+Definitions beginning with "V_" are meaningful values of bits within the registers
+Definitions beginning with "S_" are register sizes
+Definitions beginning with "N_" are the bit position
+
+**/
+
+#ifndef _QUARK_NC_SOC_ID_H_
+#define _QUARK_NC_SOC_ID_H_
+
+//
+// QNC GMCH Equates
+//
+
+//
+// DEVICE 0 (Memroy Controller Hub)
+//
+#define MC_BUS                  PCI_BUS_NUMBER_QNC
+#define MC_DEV                  0x00
+#define MC_FUN                  0x00
+
+#define   QUARK_MC_VENDOR_ID      V_INTEL_VENDOR_ID
+#define   QUARK_MC_DEVICE_ID      0x0958
+#define   QUARK2_MC_DEVICE_ID     0x12C0
+#define   QNC_MC_REV_ID_A0      0x00
+
+
+//
+// MCR - B0:D0:F0:RD0h (WO)- Message control register
+// [31:24] Message opcode - D0 read; E0 write;
+// [23:16] Message port
+// [15:8 ] Message target register address
+// [ 7:4 ] Message write byte enable : F is enable
+// [ 3:0 ] Reserved
+//
+#define QNC_ACCESS_PORT_MCR              0xD0          // Message Control Register
+// Always Set to 0xF0
+
+//
+//MDR - B0:D0:F0:RD4h (RW)- Message data register
+//
+#define QNC_ACCESS_PORT_MDR              0xD4          // Message Data Register
+
+//
+//MEA - B0:D0:F0:RD8h (RW)- Message extended address register
+//
+#define QNC_ACCESS_PORT_MEA              0xD8          // Message Extended Address Register
+
+#define  QNC_MCR_OP_OFFSET           24           // Offset of the opcode field in MCR
+#define  QNC_MCR_PORT_OFFSET         16           // Offset of the port field in MCR
+#define  QNC_MCR_REG_OFFSET          8            // Offset of the register field in MCR
+
+//
+// Misc Useful Macros
+//
+
+#define LShift16(value) (value << 16)
+
+//
+// QNC Message OpCodes and Attributes
+//
+#define QUARK_OPCODE_READ              0x10         // Quark message bus "read" opcode
+#define QUARK_OPCODE_WRITE             0x11         // Quark message bus "write" opcode
+
+//
+// Alternative opcodes for the SCSS block
+//
+#define QUARK_ALT_OPCODE_READ          0x06         // Quark message bus "read" opcode
+#define QUARK_ALT_OPCODE_WRITE         0x07         // Quark message bus "write" opcode
+
+//
+// QNC Message OpCodes and Attributes for IO
+//
+#define QUARK_OPCODE_IO_READ           0x02         // Quark message bus "IO read" opcode
+#define QUARK_OPCODE_IO_WRITE          0x03         // Quark message bus "IO write" opcode
+
+
+#define QUARK_DRAM_BASE_ADDR_READY     0x78         // Quark message bus "RMU Main binary shadow" opcode
+
+#define QUARK_ECC_SCRUB_RESUME         0xC2         // Quark Remote Management Unit "scrub resume" opcode
+#define QUARK_ECC_SCRUB_PAUSE          0xC3         // Quark Remote Management Unit "scrub pause" opcode
+
+//
+// QNC Message Ports and Registers
+//
+// Start of SB Port IDs
+#define QUARK_NC_MEMORY_ARBITER_SB_PORT_ID    0x00
+#define QUARK_NC_MEMORY_CONTROLLER_SB_PORT_ID 0x01
+#define QUARK_NC_HOST_BRIDGE_SB_PORT_ID       0x03
+#define QUARK_NC_RMU_SB_PORT_ID               0x04
+#define QUARK_NC_MEMORY_MANAGER_SB_PORT_ID    0x05
+#define QUARK_SC_USB_AFE_SB_PORT_ID           0x14
+#define QUARK_SC_PCIE_AFE_SB_PORT_ID          0x16
+#define QUARK_SCSS_SOC_UNIT_SB_PORT_ID        0x31
+#define QUARK_SCSS_FUSE_SB_PORT_ID            0x33
+#define QUARK_ICLK_SB_PORT_ID                 0x32
+#define QUARK_SCSS_CRU_SB_PORT_ID             0x34
+
+//
+// Quark Memory Arbiter Registers.
+//
+#define   QUARK_NC_MEMORY_ARBITER_REG_ASTATUS     0x21        // Memory Arbiter PRI Status encodings register.
+#define   ASTATUS_PRI_CASUAL                    0x0         // Serviced only if convenient
+#define   ASTATUS_PRI_IMPENDING                 0x1         // Serviced if the DRAM is in Self-Refresh.
+#define   ASTATUS_PRI_NORMAL                    0x2         // Normal request servicing.
+#define   ASTATUS_PRI_URGENT                    0x3         // Urgent request servicing.
+#define   ASTATUS1_RASISED_BP                   (10)
+#define   ASTATUS1_RASISED_BP_MASK              (0x03 << ASTATUS1_RASISED_BP)
+#define   ASTATUS0_RASISED_BP                   (8)
+#define   ASTATUS0_RASISED_BP_MASK              (0x03 << ASTATUS1_RASISED_BP)
+#define   ASTATUS1_DEFAULT_BP                   (2)
+#define   ASTATUS1_DEFAULT_BP_MASK              (0x03 << ASTATUS1_RASISED_BP)
+#define   ASTATUS0_DEFAULT_BP                   (0)
+#define   ASTATUS0_DEFAULT_BP_MASK              (0x03 << ASTATUS1_RASISED_BP)
+
+//
+// Quark Memory Controller Registers.
+//
+#define QUARK_NC_MEMORY_CONTROLLER_REG_DFUSESTAT  0x70        // Fuse status register.
+#define   B_DFUSESTAT_ECC_DIS                     (BIT0)    // Disable ECC.
+
+//
+// Quark Remote Management Unit Registers.
+//
+#define QNC_MSG_TMPM_REG_PMBA                   0x70        // Power Management I/O Base Address
+
+#define QUARK_NC_RMU_REG_CONFIG                   0x71        // Remote Management Unit configuration register.
+#define   TS_LOCK_AUX_TRIP_PT_REGS_ENABLE         (BIT6)
+#define   TS_LOCK_THRM_CTRL_REGS_ENABLE           (BIT5)
+
+#define QUARK_NC_RMU_REG_OPTIONS_1              0x72        // Remote Management Unit Options register 1.
+#define   OPTIONS_1_DMA_DISABLE                   (BIT0)
+
+#define QUARK_NC_RMU_REG_WDT_CONTROL              0x74        // Remote Management Unit Watchdog control register.
+#define   B_WDT_CONTROL_DBL_ECC_BIT_ERR_MASK      (BIT19 | BIT18)
+#define   B_WDT_CONTROL_DBL_ECC_BIT_ERR_BP        18
+#define   V_WDT_CONTROL_DBL_ECC_BIT_ERR_NONE      (0x0 << B_WDT_CONTROL_DBL_ECC_BIT_ERR_BP)
+#define   V_WDT_CONTROL_DBL_ECC_BIT_ERR_CAT       (0x1 << B_WDT_CONTROL_DBL_ECC_BIT_ERR_BP)
+#define   V_WDT_CONTROL_DBL_ECC_BIT_ERR_WARM      (0x2 << B_WDT_CONTROL_DBL_ECC_BIT_ERR_BP)
+#define   V_WDT_CONTROL_DBL_ECC_BIT_ERR_SERR      (0x3 << B_WDT_CONTROL_DBL_ECC_BIT_ERR_BP)
+
+#define QUARK_NC_RMU_REG_TS_MODE                  0xB0        // Remote Management Unit Thermal sensor mode register.
+#define   TS_ENABLE                               (BIT15)
+#define QUARK_NC_RMU_REG_TS_TRIP                  0xB2        // Remote Management Unit Thermal sensor programmable trip point register.
+#define   TS_HOT_TRIP_CLEAR_THOLD_BP              24
+#define   TS_HOT_TRIP_CLEAR_THOLD_MASK            (0xFF << TS_HOT_TRIP_CLEAR_THOLD_BP)
+#define   TS_CAT_TRIP_CLEAR_THOLD_BP              16
+#define   TS_CAT_TRIP_CLEAR_THOLD_MASK            (0xFF << TS_CAT_TRIP_CLEAR_THOLD_BP)
+#define   TS_HOT_TRIP_SET_THOLD_BP                8
+#define   TS_HOT_TRIP_SET_THOLD_MASK              (0xFF << TS_HOT_TRIP_SET_THOLD_BP)
+#define   TS_CAT_TRIP_SET_THOLD_BP                0
+#define   TS_CAT_TRIP_SET_THOLD_MASK              (0xFF << TS_CAT_TRIP_SET_THOLD_BP)
+
+#define QUARK_NC_ECC_SCRUB_CONFIG_REG             0x50
+#define   SCRUB_CFG_INTERVAL_SHIFT              0x00
+#define   SCRUB_CFG_INTERVAL_MASK               0xFF
+#define   SCRUB_CFG_BLOCKSIZE_SHIFT             0x08
+#define   SCRUB_CFG_BLOCKSIZE_MASK              0x1F
+#define   SCRUB_CFG_ACTIVE                      (BIT13)
+#define   SCRUB_CFG_INVALID                     0x00000FFF
+
+#define QUARK_NC_ECC_SCRUB_START_MEM_REG          0x76
+#define QUARK_NC_ECC_SCRUB_END_MEM_REG            0x77
+#define QUARK_NC_ECC_SCRUB_NEXT_READ_REG          0x7C
+
+#define SCRUB_RESUME_MSG() ((UINT32)( \
+          (QUARK_ECC_SCRUB_RESUME << QNC_MCR_OP_OFFSET) | \
+          (QUARK_NC_RMU_SB_PORT_ID << QNC_MCR_PORT_OFFSET) | \
+          0xF0))
+
+#define SCRUB_PAUSE_MSG() ((UINT32)( \
+          (QUARK_ECC_SCRUB_PAUSE << QNC_MCR_OP_OFFSET) | \
+          (QUARK_NC_RMU_SB_PORT_ID << QNC_MCR_PORT_OFFSET) | \
+          0xF0))
+
+//
+// Quark Memory Manager Registers
+//
+#define QUARK_NC_MEMORY_MANAGER_ESRAMPGCTRL_BLOCK     0x82
+#define   BLOCK_ENABLE_PG                           (1 << 28)
+#define   BLOCK_DISABLE_PG                          (1 << 29)
+#define QUARK_NC_MEMORY_MANAGER_BIMRVCTL              0x19
+#define   EnableIMRInt                                BIT31
+#define QUARK_NC_MEMORY_MANAGER_BSMMVCTL              0x1C
+#define   EnableSMMInt                                BIT31
+#define QUARK_NC_MEMORY_MANAGER_BTHCTRL               0x20
+#define   DRAM_NON_HOST_RQ_LIMIT_BP                   0
+#define   DRAM_NON_HOST_RQ_LIMIT_MASK                 (0x3f << DRAM_NON_HOST_RQ_LIMIT_BP)
+
+#define QUARK_NC_TOTAL_IMR_SET                        0x8
+#define QUARK_NC_MEMORY_MANAGER_IMR0                  0x40
+#define QUARK_NC_MEMORY_MANAGER_IMR1                  0x44
+#define QUARK_NC_MEMORY_MANAGER_IMR2                  0x48
+#define QUARK_NC_MEMORY_MANAGER_IMR3                  0x4C
+#define QUARK_NC_MEMORY_MANAGER_IMR4                  0x50
+#define QUARK_NC_MEMORY_MANAGER_IMR5                  0x54
+#define QUARK_NC_MEMORY_MANAGER_IMR6                  0x58
+#define QUARK_NC_MEMORY_MANAGER_IMR7                  0x5C
+  #define QUARK_NC_MEMORY_MANAGER_IMRXL               0x00
+    #define IMR_LOCK                                BIT31
+    #define IMR_EN                                  BIT30
+    #define IMRL_MASK                               0x00FFFFFC
+    #define IMRL_RESET                              0x00000000
+  #define QUARK_NC_MEMORY_MANAGER_IMRXH               0x01
+    #define IMRH_MASK                               0x00FFFFFC
+    #define IMRH_RESET                              0x00000000
+  #define QUARK_NC_MEMORY_MANAGER_IMRXRM              0x02
+  #define QUARK_NC_MEMORY_MANAGER_IMRXWM              0x03
+    #define IMRX_ALL_ACCESS                         0xFFFFFFFF
+    #define CPU_SNOOP                               BIT30
+    #define RMU                                     BIT29
+    #define CPU0_NON_SMM                            BIT0
+
+//
+// Quark Host Bridge Registers
+//
+#define QNC_MSG_FSBIC_REG_HMISC                0x03       // Host Misellaneous Controls
+#define   SMI_EN                              (BIT19)     // SMI Global Enable (from Legacy Bridge)
+#define QNC_MSG_FSBIC_REG_HSMMC                0x04       // Host SMM Control
+#define   NON_HOST_SMM_WR_OPEN                (BIT18)     // SMM Writes OPEN
+#define   NON_HOST_SMM_RD_OPEN                (BIT17)     // SMM Writes OPEN
+#define   SMM_CODE_RD_OPEN                    (BIT16)     // SMM Code read OPEN
+#define   SMM_CTL_EN                          (BIT3)      // SMM enable
+#define   SMM_WRITE_OPEN                      (BIT2)      // SMM Writes OPEN
+#define   SMM_READ_OPEN                       (BIT1)      // SMM Reads OPEN
+#define   SMM_LOCKED                          (BIT0)      // SMM Locked
+#define   SMM_START_MASK                      0x0000FFF0
+#define   SMM_END_MASK                        0xFFF00000
+#define QUARK_NC_HOST_BRIDGE_HMBOUND_REG              0x08
+#define   HMBOUND_MASK                        0x0FFFFF000
+#define   HMBOUND_LOCK                        BIT0
+#define QUARK_NC_HOST_BRIDGE_HLEGACY_REG              0x0A
+#define   HLEGACY_SMI_PIN_VALUE               BIT12
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_CAP            0x40
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_DEF_TYPE       0x41
+#define QUARK_NC_HOST_BRIDGE_MTRR_FIX64K_00000        0x42
+#define QUARK_NC_HOST_BRIDGE_MTRR_FIX16K_80000        0x44
+#define QUARK_NC_HOST_BRIDGE_MTRR_FIX16K_A0000        0x46
+#define QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_C0000         0x48
+#define QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_C8000         0x4A
+#define QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_D0000         0x4C
+#define QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_D8000         0x4E
+#define QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_E0000         0x50
+#define QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_E8000         0x52
+#define QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_F0000         0x54
+#define QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_F8000         0x56
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_SMRR_PHYSBASE  0x58
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_SMRR_PHYSMASK  0x59
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE0      0x5A
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSMASK0      0x5B
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE1      0x5C
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSMASK1      0x5D
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE2      0x5E
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSMASK2      0x5F
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE3      0x60
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSMASK3      0x61
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE4      0x62
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSMASK4      0x63
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE5      0x64
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSMASK5      0x65
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE6      0x66
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSMASK6      0x67
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE7      0x68
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSMASK7      0x69
+
+//
+// System On Chip Unit (SOCUnit) Registers.
+//
+#define QUARK_SCSS_SOC_UNIT_STPDDRCFG           0x00
+#define   B_STPDDRCFG_FORCE_RECOVERY              BIT0
+#define QUARK_SCSS_SOC_UNIT_SPI_ROM_FUSE    0x25
+#define   B_ROM_FUSE_IN_SECURE_SKU              BIT6
+
+#define QUARK_SCSS_SOC_UNIT_TSCGF1_CONFIG       0x31
+#define   B_TSCGF1_CONFIG_ISNSCURRENTSEL_MASK   (BIT5 | BIT4 | BIT3)
+#define   B_TSCGF1_CONFIG_ISNSCURRENTSEL_BP     3
+#define   B_TSCGF1_CONFIG_ISNSCHOPSEL_MASK      (BIT12 | BIT11 | BIT10 | BIT9 | BIT8)
+#define   B_TSCGF1_CONFIG_ISNSCHOPSEL_BP        8
+#define   B_TSCGF1_CONFIG_IBGEN                 BIT17
+#define   B_TSCGF1_CONFIG_IBGEN_BP              17
+#define   B_TSCGF1_CONFIG_IBGCHOPEN             BIT18
+#define   B_TSCGF1_CONFIG_IBGCHOPEN_BP          18
+#define   B_TSCGF1_CONFIG_ISNSINTERNALVREFEN    BIT14
+#define   B_TSCGF1_CONFIG_ISNSINTERNALVREFEN_BP 14
+
+#define QUARK_SCSS_SOC_UNIT_TSCGF2_CONFIG       0x32
+#define   B_TSCGF2_CONFIG_IDSCONTROL_MASK       0x0000FFFF
+#define   B_TSCGF2_CONFIG_IDSCONTROL_BP         0
+#define   B_TSCGF2_CONFIG_IDSTIMING_MASK        0xFFFF0000
+#define   B_TSCGF2_CONFIG_IDSTIMING_BP          16
+
+#define QUARK_SCSS_SOC_UNIT_TSCGF2_CONFIG2      0x33
+#define   B_TSCGF2_CONFIG2_ISPARECTRL_MASK      0xFF000000
+#define   B_TSCGF2_CONFIG2_ISPARECTRL_BP        24
+#define   B_TSCGF2_CONFIG2_ICALCONFIGSEL_MASK   (BIT9 | BIT8)
+#define   B_TSCGF2_CONFIG2_ICALCONFIGSEL_BP     8
+#define   B_TSCGF2_CONFIG2_ICALCOARSETUNE_MASK  0x000000FF
+#define   B_TSCGF2_CONFIG2_ICALCOARSETUNE_BP    0
+
+#define QUARK_SCSS_SOC_UNIT_TSCGF3_CONFIG       0x34
+#define   B_TSCGF3_CONFIG_ITSRST                BIT0
+#define   B_TSCGF3_CONFIG_ITSGAMMACOEFF_BP      11
+#define   B_TSCGF3_CONFIG_ITSGAMMACOEFF_MASK    (0xFFF << B_TSCGF3_CONFIG_ITSGAMMACOEFF_BP)
+
+#define QUARK_SCSS_SOC_UNIT_SOCCLKEN_CONFIG     0x36
+#define   SOCCLKEN_CONFIG_PHY_I_SIDE_RST_L      BIT20
+#define   SOCCLKEN_CONFIG_PHY_I_CMNRESET_L      BIT19
+#define   SOCCLKEN_CONFIG_SBI_BB_RST_B          BIT18
+#define   SOCCLKEN_CONFIG_SBI_RST_100_CORE_B    BIT17
+#define   SOCCLKEN_CONFIG_BB_RST_B              BIT16
+
+#define QUARK_SCSS_SOC_UNIT_SOCCLKEN_CONFIG     0x36
+
+#define QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW       0x51
+#define   B_CFG_STICKY_RW_SMM_VIOLATION         BIT0
+#define   B_CFG_STICKY_RW_HMB_VIOLATION         BIT1
+#define   B_CFG_STICKY_RW_IMR_VIOLATION         BIT2
+#define   B_CFG_STICKY_RW_DECC_VIOLATION        BIT3
+#define   B_CFG_STICKY_RW_WARM_RST              BIT4
+#define   B_CFG_STICKY_RW_FORCE_RECOVERY        BIT9
+#define   B_CFG_STICKY_RW_VIOLATION             (B_CFG_STICKY_RW_SMM_VIOLATION | B_CFG_STICKY_RW_HMB_VIOLATION | B_CFG_STICKY_RW_IMR_VIOLATION | B_CFG_STICKY_RW_DECC_VIOLATION)
+#define   B_CFG_STICKY_RW_ALL                   (B_CFG_STICKY_RW_VIOLATION | B_CFG_STICKY_RW_WARM_RST)
+
+//
+// iCLK Registers.
+//
+#define QUARK_ICLK_MUXTOP                       0x0140
+#define   B_MUXTOP_FLEX2_MASK                   (BIT25 | BIT24 | BIT23)
+#define   B_MUXTOP_FLEX2_BP                     23
+#define   B_MUXTOP_FLEX1_MASK                   (BIT22 | BIT21 | BIT20)
+#define   B_MUXTOP_FLEX1_BP                     20
+
+#define QUARK_ICLK_SSC1                         0x0314
+#define QUARK_ICLK_SSC2                         0x0414
+#define QUARK_ICLK_SSC3                         0x0514
+#define QUARK_ICLK_REF2_DBUFF0                  0x2000
+
+//
+// PCIe AFE Unit Registers (QUARK_SC_PCIE_AFE_SB_PORT_ID).
+//
+#define QUARK_PCIE_AFE_PCIE_RXPICTRL0_L0        0x2080
+#define QUARK_PCIE_AFE_PCIE_RXPICTRL0_L1        0x2180
+#define   OCFGPIMIXLOAD_1_0                   BIT6
+#define   OCFGPIMIXLOAD_1_0_MASK              0xFFFFFF3F
+
+//
+// QNC ICH Equates
+//
+#define V_INTEL_VENDOR_ID              0x8086
+
+#define PCI_BUS_NUMBER_QNC              0x00
+
+//
+// PCI to LPC Bridge Registers (D31:F0)
+//
+#define PCI_DEVICE_NUMBER_QNC_LPC       31
+#define PCI_FUNCTION_NUMBER_QNC_LPC     0
+
+#define R_QNC_LPC_VENDOR_ID             0x00
+#define   V_LPC_VENDOR_ID             V_INTEL_VENDOR_ID
+#define R_QNC_LPC_DEVICE_ID             0x02
+#define   QUARK_V_LPC_DEVICE_ID_0           0x095E
+#define R_QNC_LPC_REV_ID                0x08
+
+#define R_QNC_LPC_SMBUS_BASE            0x40 //~0x43
+#define   B_QNC_LPC_SMBUS_BASE_EN         (BIT31)
+#define   B_QNC_LPC_SMBUS_BASE_MASK       0x0000FFC0 //[15:6]
+//
+// SMBus register offsets from SMBA - "SMBA" (D31:F0:R40h)
+//        Suggested Value for SMBA = 0x1040
+//
+#define R_QNC_SMBUS_HCTL                0x00   // Host Control Register R/W
+#define   B_QNC_SMBUS_START               (BIT4)   // Start/Stop
+#define     V_QNC_SMBUS_HCTL_CMD_QUICK               0
+#define     V_QNC_SMBUS_HCTL_CMD_BYTE                1
+#define     V_QNC_SMBUS_HCTL_CMD_BYTE_DATA           2
+#define     V_QNC_SMBUS_HCTL_CMD_WORD_DATA           3
+#define     V_QNC_SMBUS_HCTL_CMD_PROCESS_CALL        4
+#define     V_QNC_SMBUS_HCTL_CMD_BLOCK               5
+
+#define R_QNC_SMBUS_HSTS                0x01   // Host Status Register R/W
+#define   B_QNC_SMBUS_BERR                (BIT2)   // BUS Error
+#define   B_QNC_SMBUS_DERR                (BIT1)   // Device Error
+#define   B_QNC_SMBUS_BYTE_DONE_STS       (BIT0)   // Completion Status
+#define   B_QNC_SMBUS_HSTS_ALL            0x07
+
+#define R_QNC_SMBUS_HCLK                0x02   // Host Clock Divider Register R/W
+#define     V_QNC_SMBUS_HCLK_100KHZ         0x0054
+
+#define R_QNC_SMBUS_TSA                 0x04   // Transmit Slave Address Register R/W
+#define     V_QNC_SMBUS_RW_SEL_READ         1
+#define     V_QNC_SMBUS_RW_SEL_WRITE        0
+
+#define R_QNC_SMBUS_HCMD                0x05   // Host Command Register R/W
+#define R_QNC_SMBUS_HD0                 0x06   // Data 0 Register R/W
+#define R_QNC_SMBUS_HD1                 0x07   // Data 1 Register R/W
+#define R_QNC_SMBUS_HBD                 0x20   // Host Block Data Register R/W [255:0] ~ 3Fh
+
+#define R_QNC_LPC_GBA_BASE              0x44
+#define   B_QNC_LPC_GPA_BASE_MASK         0x0000FFC0
+//
+// GPIO register offsets from GBA - "GPIO" (D31:F0:R44h)
+//        Suggested Value for GBA = 0x1080
+//
+#define R_QNC_GPIO_CGEN_CORE_WELL       0x00
+#define R_QNC_GPIO_CGIO_CORE_WELL       0x04
+#define R_QNC_GPIO_CGLVL_CORE_WELL      0x08
+#define R_QNC_GPIO_CGTPE_CORE_WELL      0x0C   // Core well GPIO Trigger Positive Edge Enable
+#define R_QNC_GPIO_CGTNE_CORE_WELL      0x10   // Core well GPIO Trigger Negative Edge Enable
+#define R_QNC_GPIO_CGGPE_CORE_WELL      0x14   // Core well GPIO GPE Enable
+#define R_QNC_GPIO_CGSMI_CORE_WELL      0x18   // Core well GPIO SMI Enable
+#define R_QNC_GPIO_CGTS_CORE_WELL       0x1C   // Core well GPIO Trigger Status
+#define R_QNC_GPIO_RGEN_RESUME_WELL     0x20
+#define R_QNC_GPIO_RGIO_RESUME_WELL     0x24
+#define R_QNC_GPIO_RGLVL_RESUME_WELL    0x28
+#define R_QNC_GPIO_RGTPE_RESUME_WELL    0x2C   // Resume well GPIO Trigger Positive Edge Enable
+#define R_QNC_GPIO_RGTNE_RESUME_WELL    0x30   // Resume well GPIO Trigger Negative Edge Enable
+#define R_QNC_GPIO_RGGPE_RESUME_WELL    0x34   // Resume well GPIO GPE Enable
+#define R_QNC_GPIO_RGSMI_RESUME_WELL    0x38   // Resume well GPIO SMI Enable
+#define R_QNC_GPIO_RGTS_RESUME_WELL     0x3C   // Resume well GPIO Trigger Status
+#define R_QNC_GPIO_CNMIEN_CORE_WELL     0x40   // Core well GPIO NMI Enable
+#define R_QNC_GPIO_RNMIEN_RESUME_WELL   0x44   // Resume well GPIO NMI Enable
+
+#define R_QNC_LPC_PM1BLK                0x48
+#define   B_QNC_LPC_PM1BLK_MASK           0x0000FFF0
+//
+// ACPI register offsets from PM1BLK - "ACPI PM1 Block" (D31:F0:R48h)
+//        Suggested Value for PM1BLK = 0x1000
+//
+#define R_QNC_PM1BLK_PM1S               0x00
+#define  S_QNC_PM1BLK_PM1S               2
+#define   B_QNC_PM1BLK_PM1S_ALL           (BIT15+BIT14+BIT10+BIT5+BIT0)
+#define   B_QNC_PM1BLK_PM1S_WAKE          (BIT15)
+#define   B_QNC_PM1BLK_PM1S_PCIEWSTS      (BIT14)
+#define   B_QNC_PM1BLK_PM1S_RTC           (BIT10)
+#define   B_QNC_PM1BLK_PM1S_GLOB          (BIT5)
+#define   B_QNC_PM1BLK_PM1S_TO            (BIT0)
+#define    N_QNC_PM1BLK_PM1S_RTC           10
+
+
+#define R_QNC_PM1BLK_PM1E               0x02
+#define  S_QNC_PM1BLK_PM1E               2
+#define   B_QNC_PM1BLK_PM1E_PWAKED        (BIT14)
+#define   B_QNC_PM1BLK_PM1E_RTC           (BIT10)
+#define   B_QNC_PM1BLK_PM1E_GLOB          (BIT5)
+#define    N_QNC_PM1BLK_PM1E_RTC           10
+
+#define R_QNC_PM1BLK_PM1C               0x04
+#define   B_QNC_PM1BLK_PM1C_SLPEN         (BIT13)
+#define   B_QNC_PM1BLK_PM1C_SLPTP         (BIT12+BIT11+BIT10)
+#define    V_S0                           0x00000000
+#define    V_S3                           0x00001400
+#define    V_S4                           0x00001800
+#define    V_S5                           0x00001C00
+#define   B_QNC_PM1BLK_PM1C_SCIEN         (BIT0)
+
+#define R_QNC_PM1BLK_PM1T               0x08
+
+#define R_QNC_LPC_GPE0BLK               0x4C
+#define   B_QNC_LPC_GPE0BLK_MASK          0x0000FFC0
+//        Suggested Value for GPE0BLK = 0x10C0
+//
+#define R_QNC_GPE0BLK_GPE0S             0x00          // General Purpose Event 0 Status
+#define  S_QNC_GPE0BLK_GPE0S             4
+#define   B_QNC_GPE0BLK_GPE0S_ALL         0x00003F800 // used to clear the status reg
+#define   B_QNC_GPE0BLK_GPE0S_PCIE        (BIT17)     // PCIE
+#define   B_QNC_GPE0BLK_GPE0S_GPIO        (BIT14)     // GPIO
+#define   B_QNC_GPE0BLK_GPE0S_EGPE        (BIT13)     // External GPE
+#define    N_QNC_GPE0BLK_GPE0S_THRM        12
+
+#define R_QNC_GPE0BLK_GPE0E             0x04          // General Purpose Event 0 Enable
+#define  S_QNC_GPE0BLK_GPE0E             4
+#define   B_QNC_GPE0BLK_GPE0E_PCIE        (BIT17)     // PCIE
+#define   B_QNC_GPE0BLK_GPE0E_GPIO        (BIT14)     // GPIO
+#define   B_QNC_GPE0BLK_GPE0E_EGPE        (BIT13)     // External GPE
+#define    N_QNC_GPE0BLK_GPE0E_THRM        12
+
+#define R_QNC_GPE0BLK_SMIE              0x10          // SMI_B Enable
+#define  S_QNC_GPE0BLK_SMIE              4
+#define   B_QNC_GPE0BLK_SMIE_ALL          0x0003871F
+#define   B_QNC_GPE0BLK_SMIE_APM          (BIT4)      // APM
+#define   B_QNC_GPE0BLK_SMIE_SLP          (BIT2)      // Sleep
+#define   B_QNC_GPE0BLK_SMIE_SWT          (BIT1)      // Software Timer
+#define    N_QNC_GPE0BLK_SMIE_GPIO         9
+#define    N_QNC_GPE0BLK_SMIE_ESMI         8
+#define    N_QNC_GPE0BLK_SMIE_APM          4
+#define    N_QNC_GPE0BLK_SMIE_SPI          3
+#define    N_QNC_GPE0BLK_SMIE_SLP          2
+#define    N_QNC_GPE0BLK_SMIE_SWT          1
+
+#define R_QNC_GPE0BLK_SMIS              0x14           // SMI Status Register.
+#define  S_QNC_GPE0BLK_SMIS              4
+#define   B_QNC_GPE0BLK_SMIS_ALL          0x0003871F
+#define   B_QNC_GPE0BLK_SMIS_EOS          (BIT31)      // End of SMI
+#define   B_QNC_GPE0BLK_SMIS_APM          (BIT4)       // APM
+#define   B_QNC_GPE0BLK_SMIS_SPI          (BIT3)       // SPI
+#define   B_QNC_GPE0BLK_SMIS_SLP          (BIT2)       // Sleep
+#define   B_QNC_GPE0BLK_SMIS_SWT          (BIT1)       // Software Timer
+#define   B_QNC_GPE0BLK_SMIS_BIOS         (BIT0)       // BIOS
+#define    N_QNC_GPE0BLK_SMIS_GPIO         9
+#define    N_QNC_GPE0BLK_SMIS_APM          4
+#define    N_QNC_GPE0BLK_SMIS_SPI          3
+#define    N_QNC_GPE0BLK_SMIS_SLP          2
+#define    N_QNC_GPE0BLK_SMIS_SWT          1
+
+#define R_QNC_GPE0BLK_PMCW              0x28            // Power Management Configuration Core Well
+#define   B_QNC_GPE0BLK_PMCW_PSE          (BIT31)       // Periodic SMI Enable
+
+#define R_QNC_GPE0BLK_PMSW              0x2C            // Power Management Configuration Suspend/Resume Well
+#define    B_QNC_GPE0BLK_PMSW_DRAM_INIT   (BIT0)        // Dram Initialization Sctrachpad
+
+#define R_QNC_LPC_ACTL                  0x58
+#define    V_QNC_LPC_ACTL_SCIS_IRQ9        0x00
+
+//
+// Number of PIRQs supported. PIRQA~PIRQH
+//
+#define QNC_NUMBER_PIRQS                8
+#define R_QNC_LPC_PIRQA_ROUT            0x60
+#define R_QNC_LPC_PIRQB_ROUT            0x61
+#define R_QNC_LPC_PIRQC_ROUT            0x62
+#define R_QNC_LPC_PIRQD_ROUT            0x63
+#define R_QNC_LPC_PIRQE_ROUT            0x64
+#define R_QNC_LPC_PIRQF_ROUT            0x65
+#define R_QNC_LPC_PIRQG_ROUT            0x66
+#define R_QNC_LPC_PIRQH_ROUT            0x67
+
+//
+// Bit values are the same for R_TNC_LPC_PIRQA_ROUT to
+//                             R_TNC_LPC_PIRQH_ROUT
+#define   B_QNC_LPC_PIRQX_ROUT            (BIT3+BIT2+BIT1+BIT0)
+
+#define R_QNC_LPC_WDTBA                 0x84
+// Watchdog Timer register offsets from WDTBASE (in R_QNC_LPC_WDTBA)------------BEGIN
+#define R_QNC_LPC_WDT_WDTCR             0x10
+#define R_QNC_LPC_WDT_WDTLR             0x18
+// Watchdog Timer register offsets from WDTBASE (in R_QNC_LPC_WDTBA)--------------END
+
+#define R_QNC_LPC_FWH_BIOS_DEC          0xD4
+#define   B_QNC_LPC_FWH_BIOS_DEC_F8       (BIT31)
+#define   B_QNC_LPC_FWH_BIOS_DEC_F0       (BIT30)
+#define   B_QNC_LPC_FWH_BIOS_DEC_E8       (BIT29)
+#define   B_QNC_LPC_FWH_BIOS_DEC_E0       (BIT28)
+#define   B_QNC_LPC_FWH_BIOS_DEC_D8       (BIT27)
+#define   B_QNC_LPC_FWH_BIOS_DEC_D0       (BIT26)
+#define   B_QNC_LPC_FWH_BIOS_DEC_C8       (BIT25)
+#define   B_QNC_LPC_FWH_BIOS_DEC_C0       (BIT24)
+
+#define R_QNC_LPC_BIOS_CNTL             0xD8
+#define  S_QNC_LPC_BIOS_CNTL             4
+#define   B_QNC_LPC_BIOS_CNTL_PFE         (BIT8)
+#define   B_QNC_LPC_BIOS_CNTL_SMM_BWP     (BIT5)
+#define   B_QNC_LPC_BIOS_CNTL_BCD         (BIT2)
+#define   B_QNC_LPC_BIOS_CNTL_BLE         (BIT1)
+#define   B_QNC_LPC_BIOS_CNTL_BIOSWE      (BIT0)
+#define    N_QNC_LPC_BIOS_CNTL_BLE         1
+#define    N_QNC_LPC_BIOS_CNTL_BIOSWE      0
+
+#define R_QNC_LPC_RCBA                  0xF0
+#define   B_QNC_LPC_RCBA_MASK             0xFFFFC000
+#define   B_QNC_LPC_RCBA_EN               (BIT0)
+
+//---------------------------------------------------------------------------
+//  Fixed IO Decode on QuarkNcSocId
+//
+//  20h(2B) 24h(2B) 28h(2B) 2Ch(2B) 30h(2B) 34h(2B) 38h(2B) 3Ch(2B) : R/W 8259 master
+//  40h(3B): R/W 8254
+//  43h(1B): W   8254
+//  50h(3B): R/W 8254
+//  53h(1B): W   8254
+//  61h(1B): R/W NMI Controller
+//  63h(1B): R/W NMI Controller - can be disabled
+//  65h(1B): R/W NMI Controller - can be disabled
+//  67h(1B): R/W NMI Controller - can be disabled
+//  70h(1B): W   NMI & RTC
+//  71h(1B): R/W RTC
+//  72h(1B): R RTC; W NMI&RTC
+//  73h(1B): R/W RTC
+//  74h(1B): R RTC; W NMI&RTC
+//  75h(1B): R/W RTC
+//  76h(1B): R RTC; W NMI&RTC
+//  77h(1B): R/W RTC
+//  84h(3B): R/W Internal/LPC
+//  88h(1B): R/W Internal/LPC
+//  8Ch(3B): R/W Internal/LPC
+//  A0h(2B) A4h(2B) A8h(2B) ACh(2B) B0h(2B) B4h(2B) B8h(2B) BCh(2B): R/W 8259 slave
+//  B2h(1B) B3h(1B): R/W Power management
+//  3B0h-3BBh: R/W VGA
+//  3C0h-3DFh: R/W VGA
+//  CF8h(4B): R/W Internal
+//  CF9h(1B): R/W LPC
+//  CFCh(4B): R/W Internal
+//---------------------------------------------------------------------------
+
+#define R_APM_CNT                                       0xB2
+
+//
+// Reset Generator I/O Port
+//
+#define RST_CNT                                       0xCF9
+#define   B_RST_CNT_COLD_RST                            (BIT3)     // Cold reset
+#define   B_RST_CNT_WARM_RST                            (BIT1)     // Warm reset
+
+//
+// Processor interface registers (NMI)
+//
+
+#define  PCI_DEVICE_NUMBER_QNC_IOSF2AHB_0                20
+#define  PCI_DEVICE_NUMBER_QNC_IOSF2AHB_1                21
+#define  PCI_FUNCTION_NUMBER_QNC_IOSF2AHB                 0
+
+//
+// Pci Express Root Ports (D23:F0/F1)
+//
+#define PCI_DEVICE_NUMBER_PCIE_ROOTPORT                 23
+#define PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0             0
+#define PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_1             1
+
+#define MAX_PCI_EXPRESS_ROOT_PORTS                      2
+
+#define R_QNC_PCIE_BNUM                             0x18
+#define R_QNC_PCIE_CAP_PTR                          0x34
+
+#define PCIE_CAPID                                  0x10  //PCIE Capability ID
+#define PCIE_CAP_EXT_HEARDER_OFFSET                 0x100 //PCIE Capability ID
+#define PCIE_DEV_CAP_OFFSET                         0x04 //PCIE Device Capability reg offset
+#define PCIE_LINK_CAP_OFFSET                        0x0C //PCIE Link Capability reg offset
+#define PCIE_LINK_CNT_OFFSET                        0x10 //PCIE Link control reg offset
+#define PCIE_LINK_STS_OFFSET                        0x12 //PCIE Link status reg offset
+#define PCIE_SLOT_CAP_OFFSET                        0x14 //PCIE Link Capability reg offset
+
+#define R_QNC_PCIE_XCAP                             0x42  //~ 43h
+#define   B_QNC_PCIE_XCAP_SI                          (BIT8)  //slot implemented
+#define R_QNC_PCIE_DCAP                             0x44  //~ 47h
+#define   B_QNC_PCIE_DCAP_E1AL                        (BIT11 | BIT10 | BIT9) // L1 Acceptable exit latency
+#define   B_QNC_PCIE_DCAP_E0AL                        (BIT8 | BIT7 | BIT6)   // L0 Acceptable exit latency
+#define R_QNC_PCIE_DCTL                             0x48  //~ 49h
+#define   B_QNC_PCIE_DCTL_URE                         (BIT3)  //Unsupported Request Reporting Enable
+#define   B_QNC_PCIE_DCTL_FEE                         (BIT2)  //Fatal error Reporting Enable
+#define   B_QNC_PCIE_DCTL_NFE                         (BIT1)  //Non Fatal error Reporting Enable
+#define   B_QNC_PCIE_DCTL_CEE                         (BIT0)  //Correctable error Reporting Enable
+#define R_QNC_PCIE_LCAP                             0x4C  //~ 4Fh
+#define   B_QNC_PCIE_LCAP_CPM                         (BIT18)  //clock power management supported
+#define   B_QNC_PCIE_LCAP_EL1_MASK                   (BIT17 | BIT16 | BIT15)  //L1 Exit latency mask
+#define   B_QNC_PCIE_LCAP_EL0_MASK                   (BIT14 | BIT13 | BIT12)  //L0 Exit latency mask
+#define   B_QNC_PCIE_LCAP_APMS_MASK                   (BIT11 | BIT10)  //Active state link PM support mask
+#define   V_QNC_PCIE_LCAP_APMS_OFFSET                 10  //Active state link PM support mask
+#define R_QNC_PCIE_LCTL                             0x50  //~ 51h
+#define   B_QNC_PCIE_LCTL_CCC                         (BIT6)  // Clock clock configuration
+#define   B_QNC_PCIE_LCTL_RL                          (BIT5)  // Retrain link
+#define R_QNC_PCIE_LSTS                             0x52  //~ 53h
+#define   B_QNC_PCIE_LSTS_SCC                         (BIT12) //Slot clock configuration
+#define   B_QNC_PCIE_LSTS_LT                          (BIT11) //Link training
+#define R_QNC_PCIE_SLCAP                            0x54  //~ 57h
+#define   B_QNC_PCIE_SLCAP_MASK_RSV_VALUE             0x0006007F
+#define   V_QNC_PCIE_SLCAP_SLV                        0x0A  //Slot power limit value [14:7]
+#define   V_QNC_PCIE_SLCAP_SLV_OFFSET                 7     //Slot power limit value offset is 7 [14:7]
+#define   V_QNC_PCIE_SLCAP_PSN_OFFSET                 19    //Slot number offset is 19 [31:19]
+#define R_QNC_PCIE_SLCTL                            0x58    //~ 59h
+#define   B_QNC_PCIE_SLCTL_HPE                        (BIT5)  // Hot plug interrupt enable
+#define   B_QNC_PCIE_SLCTL_PDE                        (BIT3)  // Presense detect change enable
+#define   B_QNC_PCIE_SLCTL_ABE                        (BIT0)  // Attention Button Pressed Enable
+#define R_QNC_PCIE_SLSTS                            0x5A    //~ 5Bh
+#define   B_QNC_PCIE_SLSTS_PDS                        (BIT6)  // Present Detect State = 1b : has device connected
+#define   B_QNC_PCIE_SLSTS_PDC                        (BIT3)  // Present Detect changed = 1b : PDS state has changed
+#define   B_QNC_PCIE_SLSTS_ABP                        (BIT0)  // Attention Button Pressed
+#define R_QNC_PCIE_RCTL                             0x5C    //~ 5Dh
+#define   B_QNC_PCIE_RCTL_PIE                         (BIT3)  //Root PCI-E PME Interrupt Enable
+#define   B_QNC_PCIE_RCTL_SFE                         (BIT2)  //Root PCI-E System Error on Fatal Error Enable
+#define   B_QNC_PCIE_RCTL_SNE                         (BIT1)  //Root PCI-E System Error on Non-Fatal Error Enable
+#define   B_QNC_PCIE_RCTL_SCE                         (BIT0)  //Root PCI-E System Error on Correctable Error Enable
+#define R_QNC_PCIE_SVID                             0x94  //~ 97h
+#define R_QNC_PCIE_CCFG                             0xD0  //~ D3h
+#define   B_QNC_PCIE_CCFG_UPSD                        (BIT24)  // Upstream Posted Split Disable
+#define   B_QNC_PCIE_CCFG_UNRS                        (BIT15)  // Upstream Non-Posted Request Size
+#define   B_QNC_PCIE_CCFG_UPRS                        (BIT14)  // Upstream Posted Request Size
+#define R_QNC_PCIE_MPC2                             0xD4  //~ D7h
+#define   B_QNC_PCIE_MPC2_IPF                         (BIT11)  // ISOF Packet Fast Transmit Mode
+#define R_QNC_PCIE_MPC                              0xD8  //~ DBh
+#define   B_QNC_PCIE_MPC_PMCE                         (BIT31)  // PM SCI Enable
+#define   B_QNC_PCIE_MPC_HPCE                         (BIT30)  // Hot plug SCI enable
+
+#define   B_QNC_PCIE_MPC_HPME                         (BIT1)   // Hot plug SMI enable
+#define   B_QNC_PCIE_MPC_PMME                         (BIT0)   // PM SMI Enable
+#define R_QNC_PCIE_IOSFSBCTL                        0xF6
+#define   B_QNC_PCIE_IOSFSBCTL_SBIC_MASK              (BIT1 | BIT0) // IOSF Sideband ISM Idle Counter.
+#define   B_QNC_PCIE_IOSFSBCTL_SBIC_IDLE_NEVER        (BIT1 | BIT0) // Never transition to IDLE.
+
+#define V_PCIE_MAX_TRY_TIMES                       200
+
+//
+// Misc PCI register offsets and sizes
+//
+#define R_EFI_PCI_SVID                              0x2C
+
+//
+// IO_APIC
+//
+#define IOAPIC_BASE                                 0xFEC00000
+#define IOAPIC_SIZE                                 0x1000
+
+//
+// Chipset configuration registers RCBA - "Root Complex Base Address" (D31:F0:RF0h)
+//            Suggested Value for  RCBA = 0xFED1C000
+//
+
+#define R_QNC_RCRB_SPIBASE                          0x3020       // SPI (Serial Peripheral Interface) in RCRB
+#define R_QNC_RCRB_SPIS                             (R_QNC_RCRB_SPIBASE + 0x00)  // SPI Status
+#define   B_QNC_RCRB_SPIS_SCL                       (BIT15)    // SPI Configuration Lockdown
+#define   B_QNC_RCRB_SPIS_BAS                       (BIT3)     // Blocked Access Status
+#define   B_QNC_RCRB_SPIS_CDS                       (BIT2)     // Cycle Done Status
+#define   B_QNC_RCRB_SPIS_SCIP                      (BIT0)     // SPI Cycle in Progress
+
+#define R_QNC_RCRB_SPIC                             (R_QNC_RCRB_SPIBASE + 0x02)  // SPI Control
+#define   B_QNC_RCRB_SPIC_DC                          (BIT14)    // SPI Data Cycle Enable
+#define   B_QNC_RCRB_SPIC_DBC                         0x3F00     // SPI Data Byte Count (1..8,16,24,32,40,48,56,64)
+#define   B_QNC_RCRB_SPIC_COP                         (BIT6+BIT5+BIT4)          // SPI Cycle Opcode Pointer
+#define   B_QNC_RCRB_SPIC_SPOP                        (BIT3)     // Sequence Prefix Opcode Pointer
+#define   B_QNC_RCRB_SPIC_ACS                         (BIT2)     // SPI Atomic Cycle Sequence
+#define   B_QNC_RCRB_SPIC_SCGO                        (BIT1)     // SPI Cycle Go
+
+#define R_QNC_RCRB_SPIA                             (R_QNC_RCRB_SPIBASE + 0x04)  // SPI Address
+#define   B_QNC_RCRB_SPIA_MASK                      0x00FFFFFF     // SPI Address mask
+#define R_QNC_RCRB_SPID0                            (R_QNC_RCRB_SPIBASE + 0x08)  // SPI Data 0
+#define R_QNC_RCRB_SPIPREOP                         (R_QNC_RCRB_SPIBASE + 0x54)  // Prefix Opcode Configuration
+#define R_QNC_RCRB_SPIOPTYPE                        (R_QNC_RCRB_SPIBASE + 0x56)  // Opcode Type Configuration
+#define   B_QNC_RCRB_SPIOPTYPE_NOADD_READ             0
+#define   B_QNC_RCRB_SPIOPTYPE_NOADD_WRITE            (BIT0)
+#define   B_QNC_RCRB_SPIOPTYPE_ADD_READ               (BIT1)
+#define   B_QNC_RCRB_SPIOPTYPE_ADD_WRITE              (BIT0 + BIT1)
+#define R_QNC_RCRB_SPIOPMENU                        (R_QNC_RCRB_SPIBASE + 0x58)  // Opcode Menu Configuration //R_OPMENU
+
+#define R_QNC_RCRB_SPIPBR0                          (R_QNC_RCRB_SPIBASE + 0x60)  // Protected BIOS Range 0.
+#define R_QNC_RCRB_SPIPBR1                          (R_QNC_RCRB_SPIBASE + 0x64)  // Protected BIOS Range 1.
+#define R_QNC_RCRB_SPIPBR2                          (R_QNC_RCRB_SPIBASE + 0x68)  // Protected BIOS Range 2.
+#define   B_QNC_RCRB_SPIPBRn_WPE                      (BIT31)                    // Write Protection Enable for above 3 registers.
+
+#define R_QNC_RCRB_AGENT0IR                         0x3140   // AGENT0 interrupt route
+#define R_QNC_RCRB_AGENT1IR                         0x3142   // AGENT1 interrupt route
+#define R_QNC_RCRB_AGENT2IR                         0x3144   // AGENT2 interrupt route
+#define R_QNC_RCRB_AGENT3IR                         0x3146   // AGENT3 interrupt route
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/CommonHeader.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/CommonHeader.h
new file mode 100644
index 0000000000..0024218afc
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/CommonHeader.h
@@ -0,0 +1,32 @@
+/** @file
+Common header file shared by all source files.
+
+This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+
+
+#include <PiPei.h>
+#include <IntelQNCBase.h>
+
+#include <Library/IntelQNCLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/CpuLib.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+#include <Library/QNCAccessLib.h>
+#include <IndustryStandard/Pci22.h>
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNCLib.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNCLib.c
new file mode 100644
index 0000000000..fbb89f9904
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNCLib.c
@@ -0,0 +1,771 @@
+/** @file
+Lib function for Pei QNC.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "CommonHeader.h"
+
+/**
+  This function provides the necessary SOC initialization
+  before MRC running. It sets RCBA, GPIO, PMBASE
+  and some parts of SOC through SOC message method.
+  If the function cannot complete it'll ASSERT().
+**/
+VOID
+EFIAPI
+PeiQNCPreMemInit (
+  VOID
+  )
+{
+  UINT32                            RegValue;
+
+  // QNCPortWrite(Port#, Offset, Value)
+
+  //
+  // Set the fixed PRI Status encodings config.
+  //
+  QNCPortWrite (
+    QUARK_NC_MEMORY_ARBITER_SB_PORT_ID,
+    QUARK_NC_MEMORY_ARBITER_REG_ASTATUS,
+    QNC_FIXED_CONFIG_ASTATUS
+    );
+
+  // Sideband register write to Remote Management Unit
+  QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QNC_MSG_TMPM_REG_PMBA, (BIT31 | PcdGet16 (PcdPmbaIoBaseAddress)));
+
+  // Configurable I/O address in iLB (legacy block)
+
+  LpcPciCfg32 (R_QNC_LPC_SMBUS_BASE) = BIT31 | PcdGet16 (PcdSmbaIoBaseAddress);
+  LpcPciCfg32 (R_QNC_LPC_GBA_BASE) = BIT31 | PcdGet16 (PcdGbaIoBaseAddress);
+  LpcPciCfg32 (R_QNC_LPC_PM1BLK) = BIT31 | PcdGet16 (PcdPm1blkIoBaseAddress);
+  LpcPciCfg32 (R_QNC_LPC_GPE0BLK) = BIT31 | PcdGet16 (PcdGpe0blkIoBaseAddress);
+  LpcPciCfg32 (R_QNC_LPC_WDTBA) = BIT31 | PcdGet16 (PcdWdtbaIoBaseAddress);
+
+  //
+  // Program RCBA Base Address
+  //
+  LpcPciCfg32AndThenOr (R_QNC_LPC_RCBA, (~B_QNC_LPC_RCBA_MASK), (((UINT32)(PcdGet64 (PcdRcbaMmioBaseAddress))) | B_QNC_LPC_RCBA_EN));
+
+  //
+  // Program Memory Manager fixed config values.
+  //
+
+  RegValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_BTHCTRL);
+  RegValue &= ~(DRAM_NON_HOST_RQ_LIMIT_MASK);
+  RegValue |= (V_DRAM_NON_HOST_RQ_LIMIT << DRAM_NON_HOST_RQ_LIMIT_BP);
+  QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_BTHCTRL, RegValue);
+
+  //
+  // Program iCLK fixed config values.
+  //
+  QncIClkAndThenOr (
+    QUARK_ICLK_MUXTOP,
+    (UINT32) ~(B_MUXTOP_FLEX2_MASK | B_MUXTOP_FLEX1_MASK),
+    (V_MUXTOP_FLEX2 << B_MUXTOP_FLEX2_BP) | (V_MUXTOP_FLEX1 << B_MUXTOP_FLEX1_BP)
+    );
+  QncIClkAndThenOr (
+    QUARK_ICLK_REF2_DBUFF0,
+    (UINT32) ~(BIT0), // bit[0] cleared
+    0
+    );
+  QncIClkOr (
+    QUARK_ICLK_SSC1,
+    BIT0              // bit[0] set
+    );
+  QncIClkOr (
+    QUARK_ICLK_SSC2,
+    BIT0              // bit[0] set
+    );
+  QncIClkOr (
+    QUARK_ICLK_SSC3,
+    BIT0              // bit[0] set
+    );
+
+  //
+  // Set RMU DMA disable bit post boot.
+  //
+  RegValue = QNCPortRead (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_RMU_REG_OPTIONS_1);
+  RegValue |= OPTIONS_1_DMA_DISABLE;
+  QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_RMU_REG_OPTIONS_1, RegValue);
+}
+
+/**
+  Do north cluster init which needs to be done AFTER MRC init.
+
+  @param   VOID
+
+  @retval  VOID
+**/
+
+VOID
+EFIAPI
+PeiQNCPostMemInit (
+  VOID
+  )
+{
+  //
+  // Program SVID/SID the same as VID/DID for all devices except root ports.
+  //
+  QNCMmPci32(0, MC_BUS, MC_DEV, MC_FUN, R_EFI_PCI_SVID) = QNCMmPci32(0, MC_BUS, MC_DEV, MC_FUN, PCI_VENDOR_ID_OFFSET);
+  QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, PCI_FUNCTION_NUMBER_QNC_LPC, R_EFI_PCI_SVID) = QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, PCI_FUNCTION_NUMBER_QNC_LPC, PCI_VENDOR_ID_OFFSET);
+  QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_IOSF2AHB_0, PCI_FUNCTION_NUMBER_QNC_IOSF2AHB, R_EFI_PCI_SVID) = QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_IOSF2AHB_0, PCI_FUNCTION_NUMBER_QNC_IOSF2AHB, PCI_VENDOR_ID_OFFSET);
+  QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_IOSF2AHB_1, PCI_FUNCTION_NUMBER_QNC_IOSF2AHB, R_EFI_PCI_SVID) = QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_IOSF2AHB_1, PCI_FUNCTION_NUMBER_QNC_IOSF2AHB, PCI_VENDOR_ID_OFFSET);
+  return;
+}
+
+/**
+  Used to check QNC if it's S3 state.  Clear the register state after query.
+
+  @retval TRUE if it's S3 state.
+  @retval FALSE if it's not S3 state.
+
+**/
+BOOLEAN
+EFIAPI
+QNCCheckS3AndClearState (
+   VOID
+  )
+{
+  BOOLEAN       S3WakeEventFound;
+  UINT16        Pm1Sts;
+  UINT16        Pm1En;
+  UINT16        Pm1Cnt;
+  UINT32        Gpe0Sts;
+  UINT32        Gpe0En;
+  UINT32        NewValue;
+  CHAR8         *EventDescStr;
+
+  S3WakeEventFound = FALSE;
+  EventDescStr = NULL;
+
+  //
+  // Read the ACPI registers,
+  //
+  Pm1Sts  = IoRead16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1S);
+  Pm1En   = IoRead16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1E);
+  Pm1Cnt  = IoRead16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C);
+  Gpe0Sts = IoRead32 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_GPE0S);
+  Gpe0En  = IoRead32 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_GPE0E);
+
+  //
+  // Clear Power Management 1 Enable Register and
+  // General Purpost Event 0 Enables Register
+  //
+  IoWrite16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1E, 0);
+  IoWrite32 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_GPE0E, 0);
+
+  if ((Pm1Sts & B_QNC_PM1BLK_PM1S_WAKE) != 0 && (Pm1Cnt & B_QNC_PM1BLK_PM1C_SLPTP) == V_S3) {
+
+    //
+    // Detect the actual WAKE event
+    //
+    if ((Pm1Sts & B_QNC_PM1BLK_PM1S_RTC) && (Pm1En & B_QNC_PM1BLK_PM1E_RTC)) {
+      EventDescStr = "RTC Alarm";
+      S3WakeEventFound = TRUE;
+    }
+    if ((Pm1Sts & B_QNC_PM1BLK_PM1S_PCIEWSTS) && !(Pm1En & B_QNC_PM1BLK_PM1E_PWAKED)) {
+      EventDescStr = "PCIe WAKE";
+      S3WakeEventFound = TRUE;
+    }
+    if ((Gpe0Sts & B_QNC_GPE0BLK_GPE0S_PCIE) && (Gpe0En & B_QNC_GPE0BLK_GPE0E_PCIE)) {
+      EventDescStr = "PCIe";
+      S3WakeEventFound = TRUE;
+    }
+    if ((Gpe0Sts & B_QNC_GPE0BLK_GPE0S_GPIO) && (Gpe0En & B_QNC_GPE0BLK_GPE0E_GPIO)) {
+      EventDescStr = "GPIO";
+      S3WakeEventFound = TRUE;
+    }
+    if ((Gpe0Sts & B_QNC_GPE0BLK_GPE0S_EGPE) && (Gpe0En & B_QNC_GPE0BLK_GPE0E_EGPE)) {
+      EventDescStr = "Ext. GPE";
+      S3WakeEventFound = TRUE;
+    }
+    if (S3WakeEventFound == FALSE) {
+      EventDescStr = "Unknown";
+    }
+    DEBUG ((EFI_D_INFO, "S3 Wake Event - %a\n", EventDescStr));
+
+    //
+    // If no Power Button Override event occurs and one enabled wake event occurs,
+    // just do S3 resume and clear the state.
+    //
+    IoWrite16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C, (Pm1Cnt & (~B_QNC_PM1BLK_PM1C_SLPTP)));
+
+    //
+    // Set EOS to de Assert SMI
+    //
+    IoWrite32 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_SMIS,  B_QNC_GPE0BLK_SMIS_EOS);
+
+    //
+    // Enable SMI globally
+    //
+    NewValue = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);
+    NewValue |= SMI_EN;
+    QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, NewValue);
+
+    return  TRUE;
+  }
+
+  return  FALSE;
+}
+
+/**
+  Used to check QNC if system wakes up from power on reset. Clear the register state after query.
+
+  @retval TRUE  if system wakes up from power on reset
+  @retval FALSE if system does not wake up from power on reset
+
+**/
+BOOLEAN
+EFIAPI
+QNCCheckPowerOnResetAndClearState (
+   VOID
+  )
+{
+  UINT16                Pm1Sts;
+  UINT16                Pm1Cnt;
+
+  //
+  // Read the ACPI registers,
+  // PM1_STS information cannot be lost after power down, unless CMOS is cleared.
+  //
+  Pm1Sts  = IoRead16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1S);
+  Pm1Cnt  = IoRead16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C);
+
+  //
+  // If B_SLP_TYP is S5
+  //
+  if ((Pm1Sts & B_QNC_PM1BLK_PM1S_WAKE) != 0 && (Pm1Cnt & B_QNC_PM1BLK_PM1C_SLPTP) == V_S5) {
+    IoWrite16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C, (Pm1Cnt & (~B_QNC_PM1BLK_PM1C_SLPTP)));
+    return  TRUE;
+  }
+
+  return  FALSE;
+}
+
+/**
+  This function is used to clear SMI and wake status.
+
+**/
+VOID
+EFIAPI
+QNCClearSmiAndWake (
+  VOID
+  )
+{
+  UINT32    Gpe0Sts;
+  UINT32    SmiSts;
+
+  //
+  // Read the ACPI registers
+  //
+  Gpe0Sts = IoRead32 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_GPE0S);
+  SmiSts  = IoRead32 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_SMIS);
+
+  //
+  // Clear any SMI or wake state from the boot
+  //
+  Gpe0Sts |= B_QNC_GPE0BLK_GPE0S_ALL;
+  SmiSts  |= B_QNC_GPE0BLK_SMIS_ALL;
+
+  //
+  // Write them back
+  //
+  IoWrite32 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_GPE0S, Gpe0Sts);
+  IoWrite32 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_SMIS,  SmiSts);
+}
+
+/** Send DRAM Ready opcode.
+
+  @param[in]       OpcodeParam  Parameter to DRAM ready opcode.
+
+  @retval          VOID
+**/
+VOID
+EFIAPI
+QNCSendOpcodeDramReady (
+  IN UINT32   OpcodeParam
+  )
+{
+
+  //
+  // Before sending DRAM ready place invalid value in Scrub Config.
+  //
+  QNCPortWrite (
+    QUARK_NC_RMU_SB_PORT_ID,
+    QUARK_NC_ECC_SCRUB_CONFIG_REG,
+    SCRUB_CFG_INVALID
+    );
+
+  //
+  // Send opcode and use param to notify HW of new RMU firmware location.
+  //
+  McD0PciCfg32 (QNC_ACCESS_PORT_MDR) = OpcodeParam;
+  McD0PciCfg32 (QNC_ACCESS_PORT_MCR) = MESSAGE_SHADOW_DW (QUARK_NC_RMU_SB_PORT_ID, 0);
+
+  //
+  // HW completed tasks on DRAM ready when scrub config read back as zero.
+  //
+  while (QNCPortRead (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_ECC_SCRUB_CONFIG_REG) != 0) {
+    MicroSecondDelay (10);
+  }
+}
+
+/**
+
+  Relocate RMU Main binary to memory after MRC to improve performance.
+
+  @param[in]  DestBaseAddress  - Specify the new memory address for the RMU Main binary.
+  @param[in]  SrcBaseAddress   - Specify the current memory address for the RMU Main binary.
+  @param[in]  Size             - Specify size of the RMU Main binary.
+
+  @retval     VOID
+
+**/
+VOID
+EFIAPI
+RmuMainRelocation (
+  IN CONST UINT32   DestBaseAddress,
+  IN CONST UINT32   SrcBaseAddress,
+  IN CONST UINTN    Size
+  )
+{
+  //
+  // Shadow RMU Main binary into main memory.
+  //
+  CopyMem ((VOID *)(UINTN)DestBaseAddress,(VOID *)(UINTN) SrcBaseAddress, Size);
+}
+
+
+/**
+  Get the total memory size
+
+**/
+UINT32
+EFIAPI
+QNCGetTotalMemorysize (
+  VOID
+  )
+{
+  return  QNCPortRead(QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QUARK_NC_HOST_BRIDGE_HMBOUND_REG) & HMBOUND_MASK;
+}
+
+
+/**
+  Get the memory range of TSEG.
+  The TSEG's memory is below TOLM.
+
+  @param[out] BaseAddress The base address of TSEG's memory range
+  @param[out] MemorySize  The size of TSEG's memory range
+
+**/
+VOID
+EFIAPI
+QNCGetTSEGMemoryRange (
+  OUT UINT64  *BaseAddress,
+  OUT UINT64  *MemorySize
+  )
+{
+  UINT64 Register = 0;
+  UINT64 SMMAddress = 0;
+
+  Register = QncHsmmcRead ();
+
+  //
+  // Get the SMRAM Base address
+  //
+  SMMAddress = Register & SMM_START_MASK;
+  *BaseAddress = LShift16 (SMMAddress);
+
+  //
+  // Get the SMRAM size
+  //
+  SMMAddress = ((Register & SMM_END_MASK) | (~SMM_END_MASK)) + 1;
+  *MemorySize = SMMAddress - (*BaseAddress);
+
+  DEBUG ((
+    EFI_D_INFO,
+    "TSEG's memory range: BaseAddress = 0x%x, Size = 0x%x\n",
+    (UINT32)*BaseAddress,
+    (UINT32)*MemorySize
+    ));
+}
+
+/**
+  Updates the PAM registers in the MCH for the requested range and mode.
+
+  @param   Start        The start address of the memory region
+  @param   Length       The length, in bytes, of the memory region
+  @param   ReadEnable   Pointer to the boolean variable on whether to enable read for legacy memory section.
+                        If NULL, then read attribute will not be touched by this call.
+  @param   ReadEnable   Pointer to the boolean variable on whether to enable write for legacy memory section.
+                        If NULL, then write attribute will not be touched by this call.
+  @param   Granularity  A pointer to granularity, in bytes, that the PAM registers support
+
+  @retval  RETURN_SUCCESS            The PAM registers in the MCH were updated
+  @retval  RETURN_INVALID_PARAMETER  The memory range is not valid in legacy region.
+
+**/
+EFI_STATUS
+EFIAPI
+QNCLegacyRegionManipulation (
+  IN  UINT32                  Start,
+  IN  UINT32                  Length,
+  IN  BOOLEAN                 *ReadEnable,
+  IN  BOOLEAN                 *WriteEnable,
+  OUT UINT32                  *Granularity
+  )
+{
+  //
+  // Do nothing cos no such support on QNC
+  //
+  return RETURN_SUCCESS;
+}
+
+/**
+  Determine if QNC is supported.
+
+  @retval FALSE  QNC is not supported.
+  @retval TRUE   QNC is supported.
+**/
+BOOLEAN
+EFIAPI
+IsQncSupported (
+  VOID
+  )
+{
+  UINT16  SocVendorId;
+  UINT16  SocDeviceId;
+
+  SocVendorId = MmioRead16 (
+                  PciDeviceMmBase (MC_BUS,
+                  MC_DEV,
+                  MC_FUN) + PCI_VENDOR_ID_OFFSET
+                  );
+
+  SocDeviceId = QncGetSocDeviceId();
+
+  //
+  // Verify that this is a supported chipset
+  //
+  if ((SocVendorId != QUARK_MC_VENDOR_ID) || ((SocDeviceId != QUARK_MC_DEVICE_ID) && (SocDeviceId != QUARK2_MC_DEVICE_ID))) {
+    DEBUG ((DEBUG_ERROR, "QNC code doesn't support the Soc VendorId:0x%04x Soc DeviceId:0x%04x!\n", SocVendorId, SocDeviceId));
+    return FALSE;
+  }
+  return TRUE;
+}
+
+/**
+  Get the DeviceId of the SoC
+
+  @retval PCI DeviceId of the SoC
+**/
+UINT16
+EFIAPI
+QncGetSocDeviceId (
+  VOID
+  )
+{
+  UINT16  SocDeviceId;
+
+  SocDeviceId = MmioRead16 (
+                  PciDeviceMmBase (
+                    MC_BUS,
+                    MC_DEV,
+                    MC_FUN
+                    ) + PCI_DEVICE_ID_OFFSET
+                  );
+
+  return SocDeviceId;
+}
+
+/**
+  Enable SMI detection of legacy flash access violations.
+**/
+VOID
+EFIAPI
+QncEnableLegacyFlashAccessViolationSmi (
+  VOID
+  )
+{
+  UINT32  BcValue;
+
+  BcValue = LpcPciCfg32 (R_QNC_LPC_BIOS_CNTL);
+
+  //
+  // Clear BIOSWE & set BLE.
+  //
+  BcValue &= (~B_QNC_LPC_BIOS_CNTL_BIOSWE);
+  BcValue |= (B_QNC_LPC_BIOS_CNTL_BLE);
+
+  LpcPciCfg32 (R_QNC_LPC_BIOS_CNTL) = BcValue;
+
+  DEBUG ((EFI_D_INFO, "BIOS Control Lock Enabled!\n"));
+}
+
+/**
+  Setup RMU Thermal sensor registers for Vref mode.
+**/
+VOID
+EFIAPI
+QNCThermalSensorSetVRefMode (
+  VOID
+  )
+{
+  UINT32                             Tscgf1Config;
+  UINT32                             Tscgf2Config;
+  UINT32                             Tscgf2Config2;
+
+  Tscgf1Config = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF1_CONFIG);
+  Tscgf2Config = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF2_CONFIG);
+  Tscgf2Config2 = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF2_CONFIG2);
+
+  Tscgf1Config &= ~(B_TSCGF1_CONFIG_ISNSCURRENTSEL_MASK);
+  Tscgf1Config |= (V_TSCGF1_CONFIG_ISNSCURRENTSEL_VREF_MODE << B_TSCGF1_CONFIG_ISNSCURRENTSEL_BP);
+
+  Tscgf1Config &= ~(B_TSCGF1_CONFIG_IBGEN);
+  Tscgf1Config |= (V_TSCGF1_CONFIG_IBGEN_VREF_MODE << B_TSCGF1_CONFIG_IBGEN_BP);
+
+  Tscgf2Config2 &= ~(B_TSCGF2_CONFIG2_ISPARECTRL_MASK);
+  Tscgf2Config2 |= (V_TSCGF2_CONFIG2_ISPARECTRL_VREF_MODE << B_TSCGF2_CONFIG2_ISPARECTRL_BP);
+
+  Tscgf2Config2 &= ~(B_TSCGF2_CONFIG2_ICALCOARSETUNE_MASK);
+  Tscgf2Config2 |= (V_TSCGF2_CONFIG2_ICALCOARSETUNE_VREF_MODE << B_TSCGF2_CONFIG2_ICALCOARSETUNE_BP);
+
+  Tscgf2Config &= ~(B_TSCGF2_CONFIG_IDSCONTROL_MASK);
+  Tscgf2Config |= (V_TSCGF2_CONFIG_IDSCONTROL_VREF_MODE << B_TSCGF2_CONFIG_IDSCONTROL_BP);
+
+  QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF1_CONFIG, Tscgf1Config);
+  QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF2_CONFIG, Tscgf2Config);
+  QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF2_CONFIG2, Tscgf2Config2);
+}
+
+/**
+  Setup RMU Thermal sensor registers for Ratiometric mode.
+**/
+VOID
+EFIAPI
+QNCThermalSensorSetRatiometricMode (
+  VOID
+  )
+{
+  UINT32                             Tscgf1Config;
+  UINT32                             Tscgf2Config;
+  UINT32                             Tscgf2Config2;
+  UINT32                             Tscgf3Config;
+
+  Tscgf1Config = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF1_CONFIG);
+  Tscgf2Config = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF2_CONFIG);
+  Tscgf2Config2 = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF2_CONFIG2);
+  Tscgf3Config = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF3_CONFIG);
+
+  Tscgf1Config &= ~(B_TSCGF1_CONFIG_ISNSCURRENTSEL_MASK);
+  Tscgf1Config |= (V_TSCGF1_CONFIG_ISNSCURRENTSEL_RATIO_MODE << B_TSCGF1_CONFIG_ISNSCURRENTSEL_BP);
+
+  Tscgf1Config &= ~(B_TSCGF1_CONFIG_ISNSCHOPSEL_MASK);
+  Tscgf1Config |= (V_TSCGF1_CONFIG_ISNSCHOPSEL_RATIO_MODE  << B_TSCGF1_CONFIG_ISNSCHOPSEL_BP);
+
+  Tscgf1Config &= ~(B_TSCGF1_CONFIG_ISNSINTERNALVREFEN);
+  Tscgf1Config |= (V_TSCGF1_CONFIG_ISNSINTERNALVREFEN_RATIO_MODE << B_TSCGF1_CONFIG_ISNSINTERNALVREFEN_BP);
+
+  Tscgf1Config &= ~(B_TSCGF1_CONFIG_IBGEN);
+  Tscgf1Config |= (V_TSCGF1_CONFIG_IBGEN_RATIO_MODE << B_TSCGF1_CONFIG_IBGEN_BP);
+
+  Tscgf1Config &= ~(B_TSCGF1_CONFIG_IBGCHOPEN);
+  Tscgf1Config |= (V_TSCGF1_CONFIG_IBGCHOPEN_RATIO_MODE << B_TSCGF1_CONFIG_IBGCHOPEN_BP);
+
+  Tscgf2Config2 &= ~(B_TSCGF2_CONFIG2_ICALCONFIGSEL_MASK);
+  Tscgf2Config2 |= (V_TSCGF2_CONFIG2_ICALCONFIGSEL_RATIO_MODE << B_TSCGF2_CONFIG2_ICALCONFIGSEL_BP);
+
+  Tscgf2Config2 &= ~(B_TSCGF2_CONFIG2_ISPARECTRL_MASK);
+  Tscgf2Config2 |= (V_TSCGF2_CONFIG2_ISPARECTRL_RATIO_MODE << B_TSCGF2_CONFIG2_ISPARECTRL_BP);
+
+  Tscgf2Config2 &= ~(B_TSCGF2_CONFIG2_ICALCOARSETUNE_MASK);
+  Tscgf2Config2 |= (V_TSCGF2_CONFIG2_ICALCOARSETUNE_RATIO_MODE << B_TSCGF2_CONFIG2_ICALCOARSETUNE_BP);
+
+  Tscgf2Config &= ~(B_TSCGF2_CONFIG_IDSCONTROL_MASK);
+  Tscgf2Config |= (V_TSCGF2_CONFIG_IDSCONTROL_RATIO_MODE << B_TSCGF2_CONFIG_IDSCONTROL_BP);
+
+  Tscgf2Config &= ~(B_TSCGF2_CONFIG_IDSTIMING_MASK);
+  Tscgf2Config |= (V_TSCGF2_CONFIG_IDSTIMING_RATIO_MODE << B_TSCGF2_CONFIG_IDSTIMING_BP);
+
+  Tscgf3Config &= ~(B_TSCGF3_CONFIG_ITSGAMMACOEFF_MASK);
+  Tscgf3Config |= (V_TSCGF3_CONFIG_ITSGAMMACOEFF_RATIO_MODE << B_TSCGF3_CONFIG_ITSGAMMACOEFF_BP);
+
+  QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF1_CONFIG, Tscgf1Config);
+  QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF2_CONFIG, Tscgf2Config);
+  QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF2_CONFIG2, Tscgf2Config2);
+  QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF3_CONFIG, Tscgf3Config);
+}
+
+/**
+  Setup RMU Thermal sensor trip point values.
+
+  @param[in]  CatastrophicTripOnDegreesCelsius  - Catastrophic set trip point threshold.
+  @param[in]  HotTripOnDegreesCelsius           - Hot set trip point threshold.
+  @param[in]  HotTripOffDegreesCelsius          - Hot clear trip point threshold.
+
+  @retval  EFI_SUCCESS            Trip points setup.
+  @retval  EFI_INVALID_PARAMETER  Invalid trip point value.
+
+**/
+EFI_STATUS
+EFIAPI
+QNCThermalSensorSetTripValues (
+  IN  CONST UINTN             CatastrophicTripOnDegreesCelsius,
+  IN  CONST UINTN             HotTripOnDegreesCelsius,
+  IN  CONST UINTN             HotTripOffDegreesCelsius
+  )
+{
+  UINT32 RegisterValue;
+
+  //
+  // Register fields are 8-bit temperature values of granularity 1 degree C
+  // where 0x00 corresponds to -50 degrees C
+  // and 0xFF corresponds to 205 degrees C.
+  //
+  // User passes unsigned values in degrees Celsius so trips < 0 not supported.
+  //
+  // Add 50 to user values to get values for register fields.
+  //
+
+  if ((CatastrophicTripOnDegreesCelsius > 205) || (HotTripOnDegreesCelsius > 205) || (HotTripOffDegreesCelsius > 205)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Set new values.
+  //
+  RegisterValue =
+    ((0 + 50) << TS_CAT_TRIP_CLEAR_THOLD_BP) | // Cat Trip Clear value must be less than Cat Trip Set Value.
+    ((CatastrophicTripOnDegreesCelsius + 50) << TS_CAT_TRIP_SET_THOLD_BP) |
+    ((HotTripOnDegreesCelsius + 50) << TS_HOT_TRIP_SET_THOLD_BP) |
+    ((HotTripOffDegreesCelsius + 50) << TS_HOT_TRIP_CLEAR_THOLD_BP)
+    ;
+
+  QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_RMU_REG_TS_TRIP, RegisterValue);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Enable RMU Thermal sensor with a Catastrophic Trip point.
+
+  @retval  EFI_SUCCESS            Trip points setup.
+  @retval  EFI_INVALID_PARAMETER  Invalid trip point value.
+
+**/
+EFI_STATUS
+EFIAPI
+QNCThermalSensorEnableWithCatastrophicTrip (
+  IN  CONST UINTN             CatastrophicTripOnDegreesCelsius
+  )
+{
+  UINT32                             Tscgf3Config;
+  UINT32                             TsModeReg;
+  UINT32                             TsTripReg;
+
+  //
+  // Trip Register fields are 8-bit temperature values of granularity 1 degree C
+  // where 0x00 corresponds to -50 degrees C
+  // and 0xFF corresponds to 205 degrees C.
+  //
+  // User passes unsigned values in degrees Celsius so trips < 0 not supported.
+  //
+  // Add 50 to user values to get values for register fields.
+  //
+
+  if (CatastrophicTripOnDegreesCelsius > 205) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Tscgf3Config = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF3_CONFIG);
+  TsModeReg = QNCPortRead (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_RMU_REG_TS_MODE);
+  TsTripReg = QNCPortRead (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_RMU_REG_TS_TRIP);
+
+  //
+  // Setup Catastrophic Trip point.
+  //
+  TsTripReg &= ~(TS_CAT_TRIP_SET_THOLD_MASK);
+  TsTripReg |= ((CatastrophicTripOnDegreesCelsius + 50) << TS_CAT_TRIP_SET_THOLD_BP);
+  TsTripReg &= ~(TS_CAT_TRIP_CLEAR_THOLD_MASK);
+  TsTripReg |= ((0 + 50) << TS_CAT_TRIP_CLEAR_THOLD_BP);  // Cat Trip Clear value must be less than Cat Trip Set Value.
+  QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_RMU_REG_TS_TRIP, TsTripReg);
+
+  //
+  // To enable the TS do the following:
+  //    1)  Take the TS out of reset by setting itsrst to 0x0.
+  //    2)  Enable the TS using RMU Thermal sensor mode register.
+  //
+
+  Tscgf3Config &= ~(B_TSCGF3_CONFIG_ITSRST);
+  TsModeReg |= TS_ENABLE;
+
+  QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF3_CONFIG, Tscgf3Config);
+  QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_RMU_REG_TS_MODE, TsModeReg);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Lock all RMU Thermal sensor control & trip point registers.
+
+**/
+VOID
+EFIAPI
+QNCThermalSensorLockAllRegisters (
+  VOID
+  )
+{
+  UINT32                             RegValue;
+  UINT32                             LockMask;
+
+  LockMask = TS_LOCK_THRM_CTRL_REGS_ENABLE | TS_LOCK_AUX_TRIP_PT_REGS_ENABLE;
+
+  RegValue = QNCPortRead (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_RMU_REG_CONFIG);
+  RegValue |= LockMask;
+  QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_RMU_REG_CONFIG, RegValue);
+
+  ASSERT ((LockMask == (QNCPortRead (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_RMU_REG_CONFIG) & LockMask)));
+}
+
+/**
+  Set chipset policy for double bit ECC error.
+
+  @param[in]       PolicyValue  Policy to config on double bit ECC error.
+
+**/
+VOID
+EFIAPI
+QNCPolicyDblEccBitErr (
+  IN  CONST UINT32                        PolicyValue
+  )
+{
+  UINT32 Register;
+  Register = QNCPortRead (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_RMU_REG_WDT_CONTROL);
+  Register &= ~(B_WDT_CONTROL_DBL_ECC_BIT_ERR_MASK);
+  Register |= PolicyValue;
+  QNCPortWrite (
+    QUARK_NC_RMU_SB_PORT_ID,
+    QUARK_NC_RMU_REG_WDT_CONTROL,
+    Register
+    );
+}
+
+/**
+  Determine if running on secure Quark hardware Sku.
+
+  @retval FALSE  Base Quark Sku or unprovisioned Secure Sku running.
+  @retval TRUE   Provisioned SecureSku hardware running.
+**/
+BOOLEAN
+EFIAPI
+QncIsSecureProvisionedSku (
+  VOID
+  )
+{
+  // Read QUARK Secure SKU Fuse
+  return ((QNCAltPortRead (QUARK_SCSS_FUSE_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_SPI_ROM_FUSE) & BIT6) == BIT6);
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNCLib.inf b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNCLib.inf
new file mode 100644
index 0000000000..b3e8fbf2d2
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNCLib.inf
@@ -0,0 +1,57 @@
+## @file
+# Intel QNC Library Instance
+#
+# Intel QNC Library Instance
+#
+# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = IntelQNCLib
+  FILE_GUID                      = F5B2EA6C-8148-4a4e-88EA-38A4A51F389F
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = IntelQNCLib
+
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  PciExpress.c
+  IntelQNCLib.c
+  CommonHeader.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  TimerLib
+  DebugLib
+  PcdLib
+  PciLib
+  IoLib
+  PciCf8Lib
+  BaseLib
+  CpuLib
+  QNCAccessLib
+
+[Pcd]
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPm1blkIoBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdGbaIoBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdGpe0blkIoBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPmbaIoBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdSmbaIoBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdWdtbaIoBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdRcbaMmioBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdDeviceEnables
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPcieRootPortConfiguration
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/PciExpress.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/PciExpress.c
new file mode 100644
index 0000000000..ac00572ce4
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/PciExpress.c
@@ -0,0 +1,932 @@
+/** @file
+QNC PCI Express initialization entry
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CommonHeader.h"
+
+#define PCIEXP_ROOT_PORT_URE_ENABLE    BIT0   //  unsupported request reporting enable
+#define PCIEXP_ROOT_PORT_FEE_ENABLE    BIT1   //  Fatal Error Reporting Enable
+#define PCIEXP_ROOT_PORT_NFE_ENABLE    BIT2   //  Non-Fatal Error Reporting Enable
+#define PCIEXP_ROOT_PORT_CEE_ENABLE    BIT3   //  Correctable Error Reporting Enable
+#define PCIEXP_ROOT_PORT_SFE_ENABLE    BIT4   //  System Error on Fatal Error Enable
+#define PCIEXP_ROOT_PORT_SNE_ENABLE    BIT5   //  System Error on Non-Fatal Error Enable
+#define PCIEXP_ROOT_PORT_SCE_ENABLE    BIT6   //  System Error on Correctable Error Enable
+
+EFI_STATUS
+PcieStall (
+  IN UINTN              Microseconds
+  )
+{
+  MicroSecondDelay (Microseconds);
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Find the Offset to a given Capabilities ID
+    CAPID list:
+      0x01 = PCI Power Management Interface
+      0x04 = Slot Identification
+      0x05 = MSI Capability
+      0x10 = PCI Express Capability
+
+  @param[in]  Bus                     Bus number of the interested device
+  @param[in]  Device                  Device number of the interested device
+  @param[in]  Function                Function number of the interested device
+  @param[in]  CapId                   Capability ID to be scanned
+
+  @retval Offset of desired CAPID
+
+**/
+UINT32
+PcieFindCapId (
+  UINT8   Bus,
+  UINT8   Device,
+  UINT8   Function,
+  UINT8   CapId
+  )
+{
+  UINT8    CapHeader;
+
+  //
+  // Always start at Offset 0x34
+  //
+  CapHeader = QNCMmPci8 (0, Bus, Device, Function, R_QNC_PCIE_CAP_PTR);
+
+  if (CapHeader == 0xFF) {
+     return 0;
+  }
+
+  while (CapHeader != 0) {
+    if (QNCMmPci8 (0, Bus, Device, Function, CapHeader) == CapId) {
+      return CapHeader;
+    }
+    CapHeader = QNCMmPci8 (0, Bus, Device, Function, CapHeader + 1);
+  }
+  return 0;
+}
+
+/**
+
+  Search and return the offset of desired Pci Express Capability ID
+    CAPID list:
+      0x0001 = Advanced Error Rreporting Capability
+      0x0002 = Virtual Channel Capability
+      0x0003 = Device Serial Number Capability
+      0x0004 = Power Budgeting Capability
+
+  @param[in]  Bus                     Bus number of the interested device
+  @param[in]  Device                  Device number of the interested device
+  @param[in]  Function                Function number of the interested device
+  @param[in]  CapId                   Capability ID to be scanned
+
+  @retval Offset of desired CAPID
+
+**/
+UINT32
+PcieFindExtendedCapId (
+  UINT8   Bus,
+  UINT8   Device,
+  UINT8   Function,
+  UINT16  CapId
+  )
+{
+  UINT16    CapHeaderOffset;
+  UINT16    CapHeaderId;
+
+  // Start to search at Offset 0x100
+  // Get Capability Header
+  CapHeaderId = 0;
+  CapHeaderOffset = PCIE_CAP_EXT_HEARDER_OFFSET;
+
+  while (CapHeaderOffset != 0 && CapHeaderId != 0xFFFF) {
+    CapHeaderId = QNCMmPci16 (0, Bus, Device, Function, CapHeaderOffset);
+    if (CapHeaderId == CapId) {
+      return CapHeaderOffset;
+    }
+    CapHeaderOffset = (QNCMmPci16 (0, Bus, Device, Function, CapHeaderOffset + 2) >> 4);
+  }
+  return 0;
+}
+
+/**
+
+  Map Vc on both root port and downstream device
+
+  @param[in]  Bus1                    Bus number of the root port
+  @param[in]  Device1                 Device number of the root port
+  @param[in]  Function1               Function number of the root port
+  @param[in]  Bus2                    Bus number of the downstream device
+  @param[in]  Device2                 Device number of the downstream device
+  @param[in]  Function2               Function number of the downstream device
+
+  @retval EFI_SUCCESS    Map Vc successful
+
+**/
+EFI_STATUS
+PcieInitTcxVc0 (
+  IN UINT8   Bus1,
+  IN UINT8   Device1,
+  IN UINT8   Function1,
+  IN UINT8   Bus2,
+  IN UINT8   Device2,
+  IN UINT8   Function2
+  )
+{
+  UINT32  Offset;
+
+  //
+  // Initialize TCx-VC0 value on the port to only use TC0
+  //
+  Offset = PcieFindExtendedCapId (Bus1, Device1, Function1, 2);
+  if (Offset == 0) {
+    return EFI_UNSUPPORTED;
+  }
+  QNCMmPci8AndThenOr (0, Bus1, Device1, Function1, (Offset + PCIE_SLOT_CAP_OFFSET), ~0xF, 1);
+
+  // Set TCx-VC0 value on the Endpoint
+
+  Offset = PcieFindExtendedCapId (Bus2, Device2, Function2, 2);
+  if (Offset == 0) {
+    return EFI_UNSUPPORTED;
+  }
+  QNCMmPci8AndThenOr (0, Bus2, Device2, Function2, (Offset + PCIE_SLOT_CAP_OFFSET), ~0xF, 1);
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Map Traffic Class x to Vc0 on both root port and downstream device
+
+  @param[in]  Bus1                    Bus number of the root port
+  @param[in]  Device1                 Device number of the root port
+  @param[in]  Function1               Function number of the root port
+  @param[in]  Bus2                    Bus number of the downstream device
+  @param[in]  Device2                 Device number of the downstream device
+  @param[in]  Function2               Function number of the downstream device
+  @param[in]  TCx                     Traffic Class to be mapped to vc0
+
+  @retval EFI_SUCCESS    Map Tcx to Vc0 successful
+
+**/
+EFI_STATUS
+PcieMapTcxVc0 (
+  IN UINT8   Bus1,
+  IN UINT8   Device1,
+  IN UINT8   Function1,
+  IN UINT8   Bus2,
+  IN UINT8   Device2,
+  IN UINT8   Function2,
+  IN UINT8   TCx
+  )
+{
+  UINT32  Offset;
+
+  //
+  // Set TCx-VC0 value on the port
+  //
+
+  Offset = PcieFindExtendedCapId (Bus1, Device1, Function1, 2);
+  if (Offset == 0) {
+    return EFI_UNSUPPORTED;
+  }
+  QNCMmPci8 (0, Bus1, Device1, Function1, (Offset + PCIE_SLOT_CAP_OFFSET)) = (UINT8)(1 << TCx);
+
+  // Set TCx-VC0 value on the Endpoint
+
+  Offset = PcieFindExtendedCapId (Bus2, Device2, Function2, 2);
+  if (Offset == 0) {
+    return EFI_UNSUPPORTED;
+  }
+  QNCMmPci8 (0, Bus2, Device2, Function2, (Offset + PCIE_SLOT_CAP_OFFSET)) = (UINT8)(1 << TCx);
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Set common clock for both root port and downstream device.
+
+  @param[in]  Bus1                    Bus number of the root port
+  @param[in]  Device1                 Device number of the root port
+  @param[in]  Function1               Function number of the root port
+  @param[in]  Bus2                    Device number of the downstream device
+  @param[in]  Device2                 Function number of the downstream device
+
+  @retval EFI_SUCCESS    Set common clock successful
+
+**/
+EFI_STATUS
+PcieSetCommonClock (
+  IN UINT8   Bus1,
+  IN UINT8   Device1,
+  IN UINT8   Function1,
+  IN UINT8   Bus2,
+  IN UINT8   Device2
+ )
+{
+  UINT32      CapOffset1;
+  UINT32      CapOffset2;
+  UINT8       Function2;
+  UINT8       CommonClock;
+  EFI_STATUS  Status;
+
+  //
+  // Get the pointer to the Port PCI Express Capability Structure.
+  //
+  CommonClock = 0;
+  CapOffset1 = PcieFindCapId (Bus1, Device1, Function1, PCIE_CAPID);
+  if (CapOffset1 == 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Step 1
+  // Read the Slot Clock Configuration bit of the Link status register of the root port and the endpoint device connected to the port
+  // If both components have this bit set to 1, then System BIOS should set the "Common Clock Configuration" bit in the Link Control Registers
+  // for both components at both sides of the link to indicate that components at both ends
+  // of the link use a common clock source
+  //
+
+  //
+  // Check the Port Slot Clock Configuration Bit.
+  //
+  if ((QNCMmPci16 (0, Bus1, Device1, Function1, (CapOffset1 + PCIE_LINK_STS_OFFSET)) & B_QNC_PCIE_LSTS_SCC) == 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Function2 = 0; Function2 < 8; Function2++) {
+    //
+    // Check the Endpoint Slot Clock Configuration Bit.
+    //
+    CapOffset2 = PcieFindCapId (Bus2, Device2, Function2, PCIE_CAPID);
+    if ((CapOffset2 != 0) &&
+       ((QNCMmPci16 (0, Bus2, Device2, Function2, (CapOffset2 + PCIE_LINK_STS_OFFSET)) & B_QNC_PCIE_LSTS_SCC) != 0)) {
+
+      //
+      // Common clock is supported, set common clock bit on root port
+      // and the endpoint
+      //
+      if (CommonClock == 0) {
+        QNCMmPci8Or (0, Bus1, Device1, Function1, (CapOffset1 + PCIE_LINK_CNT_OFFSET), B_QNC_PCIE_LCTL_CCC);
+        CommonClock++;
+      }
+      QNCMmPci8Or (0, Bus2, Device2, Function2, (CapOffset2 + PCIE_LINK_CNT_OFFSET), B_QNC_PCIE_LCTL_CCC);
+    }
+  }
+
+  //
+  // Step 2   If the Common Clock Configuration bit was changed by BIOS in step 1,
+  // System BIOS should initiate a link training by setting the Retrain Link bit
+  // in the Link Control register of the root port (D28:F0/F1 offset
+  // 50h [5]) to "1b" and then poll the Link Training bit in the Link Status
+  // register of the root port (D28:F0/F1/F2/F3/F4/F5 offset 52h [11]) until it is
+  // "0b".
+  //
+  if (CommonClock == 0) {
+    Status = EFI_UNSUPPORTED;
+  } else {
+    //
+    // Retrain the Link per PCI Express Specification.
+    //
+    QNCMmPci8Or (0, Bus1, Device1, Function1, (CapOffset1 + PCIE_LINK_CNT_OFFSET), B_QNC_PCIE_LCTL_RL);
+
+    //
+    // Wait until Re-Training has completed.
+    //
+    while ((QNCMmPci16 (0, Bus1, Device1, Function1, (CapOffset1 + PCIE_LINK_STS_OFFSET)) & B_QNC_PCIE_LSTS_LT) != 0);
+    Status = EFI_SUCCESS;
+  }
+
+  return Status;
+}
+
+/**
+
+  Enables the CLKREQ# PM on all the end point functions
+
+  @param[in]  Bus                Bus number of the downstream device
+  @param[in]  Device             Device number of the downstream device
+
+  @retval None
+
+**/
+VOID
+PcieSetClkreq (
+  IN  UINT8   Bus,
+  IN  UINT8   Device
+ )
+{
+  UINT8  Function;
+  UINT32 CapOffset;
+
+  //
+  // Parse thro all the functions of the endpoint and find the PCIe Cap ID (offset 10h) and if
+  // exists then enable the CLKREQ# bit (BIT8) on that function
+  //
+  for (Function = 0; Function < 8; Function++) {
+    //
+    // Find the PCIe Cap Id (offset 10h)
+    //
+    CapOffset = PcieFindCapId (Bus, Device, Function, PCIE_CAPID);
+    if (CapOffset == 0) {
+       continue;
+    }
+
+    //
+    // Check if CLKREQ# is supported by the endpoints
+    //
+    if ((QNCMmPci32 (0, Bus, Device, Function, (CapOffset + PCIE_LINK_CAP_OFFSET))
+      & B_QNC_PCIE_LCAP_CPM) != B_QNC_PCIE_LCAP_CPM) {
+      //
+      // CLKREQ# is not supported so dont do anything
+      //
+      return;
+    }
+  }
+
+  //
+  // Now enable the CLKREQ#
+  //
+  for (Function = 0; Function < 8; Function++) {
+    //
+    // Find the PCIe Cap Id (offset 10h)
+    //
+    CapOffset = PcieFindCapId (Bus, Device, Function, PCIE_CAPID);
+    if (CapOffset == 0) {
+       continue;
+    }
+
+    QNCMmPci16Or (0, Bus, Device, Function, (CapOffset + PCIE_LINK_CNT_OFFSET), BIT8);
+  }
+}
+
+/**
+
+  Configure ASPM automatically for both root port and downstream device.
+
+  @param[in]  RootBus                    Bus number of the root port
+  @param[in]  RootDevice                 Device number of the root port
+  @param[in]  RootFunction               Function number of the root port
+  @param[in]  EndpointBus                Bus number of the downstream device
+  @param[in]  EndpointDevice             Device number of the downstream device
+  @param[in]  EndpointFunction           Function number of the downstream device
+  @param[in]  LinkAspmVal                Currently used ASPM setting
+
+  @retval EFI_SUCCESS    Configure ASPM successful
+
+**/
+EFI_STATUS
+PcieSetAspmAuto (
+  IN  UINT8   RootBus,
+  IN  UINT8   RootDevice,
+  IN  UINT8   RootFunction,
+  IN  UINT8   EndpointBus,
+  IN  UINT8   EndpointDevice,
+  IN  UINT8   EndpointFunction,
+  OUT UINT16  *LinkAspmVal
+ )
+{
+  UINT32    RootPcieCapOffset;
+  UINT32    EndpointPcieCapOffset;
+  UINT16    RootPortAspm;
+  UINT16    EndPointAspm;
+  UINT16    AspmVal;
+  UINT32    PortLxLat;
+  UINT32    EndPointLxLat;
+  UINT32    LxLat;
+
+  //
+  // Get the pointer to the Port PCI Express Capability Structure.
+  //
+  RootPcieCapOffset = PcieFindCapId (RootBus, RootDevice, RootFunction, PCIE_CAPID);
+  if (RootPcieCapOffset == 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Get the pointer to the Endpoint PCI Express Capability Structure.
+  //
+  EndpointPcieCapOffset = PcieFindCapId (EndpointBus, EndpointDevice, EndpointFunction, PCIE_CAPID);
+  if (EndpointPcieCapOffset == 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Obtain initial ASPM settings from respective port capability registers.
+  //
+  RootPortAspm  = (QNCMmPci16 (0, RootBus, RootDevice, RootFunction, (RootPcieCapOffset + PCIE_LINK_CAP_OFFSET)) & B_QNC_PCIE_LCAP_APMS_MASK) >> V_QNC_PCIE_LCAP_APMS_OFFSET;
+
+  //
+  // Configure downstream device if present.
+  //
+  EndPointAspm  = (QNCMmPci16 (0, EndpointBus, EndpointDevice, EndpointFunction, (EndpointPcieCapOffset + PCIE_LINK_CAP_OFFSET)) & B_QNC_PCIE_LCAP_APMS_MASK) >> V_QNC_PCIE_LCAP_APMS_OFFSET;
+
+  //
+  // TODO: Mask APMC with values from lookup table.
+  // RevID of 0xFF applies to all steppings.
+  //
+
+  // TODO: Mask with latency/acceptable latency comparison results.
+
+  AspmVal = RootPortAspm;
+  if (RootPortAspm > EndPointAspm) {
+    AspmVal = EndPointAspm;
+  }
+
+  //
+  // Check if L1 should be enabled based on port and endpoint L1 exit latency.
+  //
+  if(AspmVal & BIT1) {
+    PortLxLat      = QNCMmPci32 (0, RootBus, RootDevice, RootFunction, (RootPcieCapOffset + PCIE_LINK_CAP_OFFSET)) & B_QNC_PCIE_LCAP_EL1_MASK;
+    EndPointLxLat  = QNCMmPci32 (0, EndpointBus, EndpointDevice, EndpointFunction, (EndpointPcieCapOffset + PCIE_LINK_CAP_OFFSET)) & B_QNC_PCIE_LCAP_EL1_MASK;
+
+    LxLat = PortLxLat;
+    if(PortLxLat < EndPointLxLat) {
+      LxLat = EndPointLxLat;
+    }
+
+    //
+    // check if the value is bigger than endpoint L1 acceptable exit latency, if it is
+    // larger than accepted value, then we should disable L1
+    //
+    LxLat >>= 6;
+    if(LxLat > (QNCMmPci32 (0, EndpointBus, EndpointDevice, EndpointFunction, (EndpointPcieCapOffset + PCIE_DEV_CAP_OFFSET)) & B_QNC_PCIE_DCAP_E1AL)) {
+      AspmVal &= ~BIT1;
+    }
+  }
+
+  //
+  // Check if L0s should be enabled based on port and endpoint L0s exit latency.
+  //
+  if(AspmVal & BIT0) {
+    PortLxLat      = QNCMmPci32 (0, RootBus, RootDevice, RootFunction, (RootPcieCapOffset+ PCIE_LINK_CAP_OFFSET)) & B_QNC_PCIE_LCAP_EL0_MASK;
+    EndPointLxLat  = QNCMmPci32 (0, EndpointBus, EndpointDevice, EndpointFunction, (EndpointPcieCapOffset + PCIE_LINK_CAP_OFFSET)) & B_QNC_PCIE_LCAP_EL0_MASK;
+
+    LxLat = PortLxLat;
+    if(PortLxLat < EndPointLxLat) {
+      LxLat = EndPointLxLat;
+    }
+
+    //
+    // check if the value is bigger than endpoint L0s acceptable exit latency, if it is
+    // larger than accepted value, then we should disable L0s
+    //
+    LxLat >>= 6;
+    if(LxLat > (QNCMmPci32 (0, EndpointBus, EndpointDevice, EndpointFunction, (EndpointPcieCapOffset + PCIE_DEV_CAP_OFFSET)) & B_QNC_PCIE_DCAP_E0AL)) {
+      AspmVal &= ~BIT0;
+    }
+  }
+
+  RootPortAspm = AspmVal;
+
+  *LinkAspmVal = AspmVal;
+  //
+  // Set Endpoint Aspm
+  //
+  QNCMmPci16AndThenOr (0, EndpointBus, EndpointDevice, EndpointFunction, (EndpointPcieCapOffset + PCIE_LINK_CNT_OFFSET), 0xFFFC, AspmVal);
+
+
+  //
+  // Set Root Port Aspm
+  //
+  QNCMmPci16AndThenOr (0, RootBus, RootDevice, RootFunction, (RootPcieCapOffset + PCIE_LINK_CNT_OFFSET), 0xFFFC, RootPortAspm);
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Configure ASPM based on the given setting for the interested device.
+
+  @param[in]  Bus                    Bus number of the interested device
+  @param[in]  Device                 Device number of the interested device
+  @param[in]  Function               Function number of the interested device
+  @param[in]  AspmSetting            Aspm setting
+  @param[in]  LinkAspmVal            Currently used ASPM setting
+
+  @retval EFI_SUCCESS    Configure ASPM successful
+
+**/
+EFI_STATUS
+PcieSetAspmManual (
+  IN  UINT8   Bus,
+  IN  UINT8   Device,
+  IN  UINT8   Function,
+  IN  UINT8   AspmSetting,
+  OUT UINT16  *LinkAspmVal
+ )
+{
+  UINT32    PcieCapOffset;
+  UINT16    PortAspm;
+
+  //
+  // Get the pointer to the Port PCI Express Capability Structure.
+  //
+  PcieCapOffset = PcieFindCapId (Bus, Device, Function, PCIE_CAPID);
+  if (PcieCapOffset == 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  // Read the Link Capability register's ASPM setting
+  PortAspm = (QNCMmPci16 (0, Bus, Device, Function, (PcieCapOffset + PCIE_LINK_CAP_OFFSET)) & B_QNC_PCIE_LCAP_APMS_MASK) >> V_QNC_PCIE_LCAP_APMS_OFFSET;
+  // Mask it with the Setup selection
+  PortAspm &= AspmSetting;
+
+  *LinkAspmVal = PortAspm;
+  // Write it to the Link Control register
+  QNCMmPci16AndThenOr (0, Bus, Device, Function, (PcieCapOffset + PCIE_LINK_CNT_OFFSET), 0xFFFC, PortAspm);
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Perform Initialization on one PCI Express root port.
+
+  @param[in]  RootPortIndex          Index of PCI Express root port
+  @param[in]  RootPortConfig         Pointer to the given pcie root port configuration
+  @param[in]  PciExpressBar          Base address of pcie space
+  @param[in]  QNCRootComplexBar       Base address of root complex
+  @param[in]  QNCPmioBase             Base address of PM IO space
+  @param[in]  QNCGpeBase              Base address of gpe IO space
+
+  @retval EFI_SUCCESS    Initialization successful
+
+**/
+EFI_STATUS
+QNCRootPortInit (
+  IN UINT32                                    RootPortIndex,
+  IN PCIEXP_ROOT_PORT_CONFIGURATION            *RootPortConfig,
+  IN UINT64                                    PciExpressBar,
+  IN UINT32                                    QNCRootComplexBar,
+  IN UINT32                                    QNCPmioBase,
+  IN UINT32                                    QNCGpeBase
+  )
+{
+  UINT64            RPBase;
+  UINT64            EndPointBase;
+  UINT16            AspmVal;
+  UINT16            SlotStatus;
+  UINTN             Index;
+  UINT32            CapOffset;
+  UINT32            DwordReg;
+
+  RPBase = PciExpressBar + (((PCI_BUS_NUMBER_QNC << 8) + ((PCI_DEVICE_NUMBER_PCIE_ROOTPORT) << 3) + ((PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0 + RootPortIndex) << 0)) << 12);
+  CapOffset = PcieFindCapId (PCI_BUS_NUMBER_QNC, (UINT8)(PCI_DEVICE_NUMBER_PCIE_ROOTPORT), (UINT8)(PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0 + RootPortIndex), PCIE_CAPID);
+
+  if (CapOffset == 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Initialize "Slot Implmemented Bit" for this root port
+  //
+  if (RootPortConfig[RootPortIndex].Bits.SlotImplemented) {
+    QNCMmio16Or (RPBase, R_QNC_PCIE_XCAP, B_QNC_PCIE_XCAP_SI);
+  }
+
+  //
+  // For Root Port Slots Numbering on the CRBs.
+  //  Root Port 0 = Slot 1
+  //  Root Port 1 = Slot 2
+  //  Root Port 2 = Slot 3
+  //  Root Port 3 = Slot 4
+  //
+  DwordReg = QNCMmio32 (RPBase, R_QNC_PCIE_SLCAP);
+  DwordReg &= B_QNC_PCIE_SLCAP_MASK_RSV_VALUE;
+  DwordReg |= (V_QNC_PCIE_SLCAP_SLV << V_QNC_PCIE_SLCAP_SLV_OFFSET);
+  DwordReg |= ((RootPortConfig[RootPortIndex].Bits.PhysicalSlotNumber) << V_QNC_PCIE_SLCAP_PSN_OFFSET) ;
+  QNCMmio32 (RPBase, R_QNC_PCIE_SLCAP) = DwordReg;
+
+  //
+  // Check for a Presence Detect Change.
+  //
+  SlotStatus = QNCMmio16 (RPBase, R_QNC_PCIE_SLSTS);
+  if ((SlotStatus & (B_QNC_PCIE_SLSTS_PDS + B_QNC_PCIE_SLSTS_PDC)) == 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Temporarily Hardcode the Root Port Bridge Number to 2.
+  //
+  // This Endpoint check should immediately pass.  Howerver, a 900ms delay
+  // has been added to match the timing requirements of the PCI Express Base
+  // Specification, Revision 1.0A, Section 6.6 ("...software must allow 1.0s
+  // after a reset of a device, before it may determine that a device which
+  // fails to return a Successful Completion status for a valid Configuration
+  // Request is a broken device").  Note that a 100ms delay was already added
+  // after the Root Ports were first taken out of reset.
+  //
+  QNCMmio32AndThenOr (RPBase, R_QNC_PCIE_BNUM, 0xFF0000FF, 0x00020200);
+  //
+  // Only do this when a downstream device is present
+  //
+  EndPointBase = PciExpressBar + (((2 << 8) + (0 << 3) + (0 << 0)) << 12);
+  if ((SlotStatus & B_QNC_PCIE_SLSTS_PDS) != 0) {
+    for (Index = 0; Index < V_PCIE_MAX_TRY_TIMES; Index++){
+      if (QNCMmio16 (EndPointBase, 0x0) != 0xFFFF) {
+        break;
+      }
+      PcieStall (15);
+    }
+    if (Index >= V_PCIE_MAX_TRY_TIMES) {
+      //
+      // Clear Bus Numbers.
+      //
+      QNCMmio32And (RPBase, R_QNC_PCIE_BNUM, 0xFF0000FF);
+      return EFI_NOT_FOUND;
+    }
+  }
+
+  //
+  // PCI Express* Virtual Channels
+  // Clear TC1-7 Traffic classes.
+  // Map TC0-VC0
+  //
+  PcieInitTcxVc0 (PCI_BUS_NUMBER_QNC, (UINT8)(PCI_DEVICE_NUMBER_PCIE_ROOTPORT), (UINT8)(PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0 + RootPortIndex), 2, 0, 0);
+  PcieMapTcxVc0 (PCI_BUS_NUMBER_QNC, (UINT8)(PCI_DEVICE_NUMBER_PCIE_ROOTPORT), (UINT8)(PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0 + RootPortIndex), 2, 0, 0, 0x0);
+
+  //
+  // Set Common Clock for inserted cards
+  //
+  if ((SlotStatus & B_QNC_PCIE_SLSTS_PDS) != 0) {
+    PcieSetCommonClock (PCI_BUS_NUMBER_QNC, (UINT8)(PCI_DEVICE_NUMBER_PCIE_ROOTPORT), (UINT8)(PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0 + RootPortIndex), 2, 0);
+  }
+
+  //
+  // Flow for Enabling ASPM
+  //
+  if (RootPortConfig[RootPortIndex].Bits.AspmEnable) {
+    if (RootPortConfig[RootPortIndex].Bits.AspmAutoEnable) {
+      PcieSetAspmAuto (PCI_BUS_NUMBER_QNC, (UINT8)(PCI_DEVICE_NUMBER_PCIE_ROOTPORT), (UINT8)(PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0 + RootPortIndex), 2, 0, 0, &AspmVal);
+    } else {
+      //
+      // Set ASPM values according to setup selections, masked by capabilities
+      //
+      PcieSetAspmManual (
+        PCI_BUS_NUMBER_QNC,
+        (UINT8) (PCI_DEVICE_NUMBER_PCIE_ROOTPORT),
+        (UINT8) (PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0 + RootPortIndex),
+        (UINT8) ((RootPortConfig[RootPortIndex].Bits.AspmL0sEnable & 0x01) | (RootPortConfig[RootPortIndex].Bits.AspmL1Enable << 1)),
+        &AspmVal
+        );
+    }
+  }
+
+  //
+  // Enable the PCIe CLKREQ#
+  //
+  if ((SlotStatus & B_QNC_PCIE_SLSTS_PDS) != 0) {
+    PcieSetClkreq (2, 0);
+  }
+
+  //
+  // Clear Bus Numbers
+  //
+  QNCMmio32And (RPBase, R_QNC_PCIE_BNUM, 0xFF0000FF);
+
+  //
+  // Additional configurations
+  //
+
+  //
+  // PCI-E Unsupported Request Reporting Enable
+  //
+  if (RootPortConfig[RootPortIndex].Bits.PortErrorMask & PCIEXP_ROOT_PORT_URE_ENABLE) {
+    QNCMmio16Or (RPBase, R_QNC_PCIE_DCTL, B_QNC_PCIE_DCTL_URE);
+  }
+
+  //
+  // Device Fatal Error Reporting Enable
+  //
+  if (RootPortConfig[RootPortIndex].Bits.PortErrorMask & PCIEXP_ROOT_PORT_FEE_ENABLE) {
+    QNCMmio16Or (RPBase, R_QNC_PCIE_DCTL, B_QNC_PCIE_DCTL_FEE);
+  }
+
+  //
+  // Device Non Fatal Error Reporting Enable
+  //
+  if (RootPortConfig[RootPortIndex].Bits.PortErrorMask & PCIEXP_ROOT_PORT_NFE_ENABLE) {
+    QNCMmio16Or (RPBase, R_QNC_PCIE_DCTL, B_QNC_PCIE_DCTL_NFE);
+  }
+
+  //
+  // Device Correctable Error Reporting Enable
+  //
+  if (RootPortConfig[RootPortIndex].Bits.PortErrorMask & PCIEXP_ROOT_PORT_CEE_ENABLE) {
+    QNCMmio16Or (RPBase, R_QNC_PCIE_DCTL, B_QNC_PCIE_DCTL_CEE);
+  }
+  //
+  // Root PCI-E PME Interrupt Enable
+  //
+  if (RootPortConfig[RootPortIndex].Bits.PmeInterruptEnable) {
+    QNCMmio16Or (RPBase, R_QNC_PCIE_RCTL, B_QNC_PCIE_RCTL_PIE);
+  }
+  //
+  // Root PCI-E System Error on Fatal Error Enable
+  //
+  if (RootPortConfig[RootPortIndex].Bits.PortErrorMask & PCIEXP_ROOT_PORT_SFE_ENABLE) {
+    QNCMmio16Or (RPBase, R_QNC_PCIE_RCTL, B_QNC_PCIE_RCTL_SFE);
+  }
+
+  //
+  // Root PCI-E System Error on Non-Fatal Error Enable
+  //
+  if (RootPortConfig[RootPortIndex].Bits.PortErrorMask & PCIEXP_ROOT_PORT_SNE_ENABLE) {
+    QNCMmio16Or (RPBase, R_QNC_PCIE_RCTL, B_QNC_PCIE_RCTL_SNE);
+  }
+
+  //
+  // Root PCI-E System Error on Correctable Error Enable
+  //
+  if (RootPortConfig[RootPortIndex].Bits.PortErrorMask & PCIEXP_ROOT_PORT_SCE_ENABLE) {
+    QNCMmio16Or (RPBase, R_QNC_PCIE_RCTL, B_QNC_PCIE_RCTL_SCE);
+  }
+
+  //
+  // Root PCI-E Powermanagement SCI Enabled
+  //
+  if (RootPortConfig[RootPortIndex].Bits.PmSciEnable) {
+    //
+    // Make sure that PME Interrupt Enable bit of Root Control register
+    // of PCI Express Capability struceture is cleared
+    //
+    QNCMmio32And (RPBase, R_QNC_PCIE_RCTL, (~B_QNC_PCIE_RCTL_PIE));
+    QNCMmio32AndThenOr (RPBase, R_QNC_PCIE_MPC, (~B_QNC_PCIE_MPC_PMME), B_QNC_PCIE_MPC_PMCE);
+
+    //
+    // Make sure GPE0 Stutus RW1C Bit is clear.
+    //
+    DwordReg = IoRead32 (QNCGpeBase + R_QNC_GPE0BLK_GPE0S);
+    if ((DwordReg & B_QNC_GPE0BLK_GPE0S_PCIE) != 0) {
+      IoWrite32 (QNCGpeBase + R_QNC_GPE0BLK_GPE0S, B_QNC_GPE0BLK_GPE0S_PCIE);
+    }
+  }
+
+  //
+  // PCIe Hot Plug SCI Enable
+  //
+  if (RootPortConfig[RootPortIndex].Bits.HotplugSciEnable) {
+    //
+    // Write clear for :
+    // Attention Button Pressed (bit0)
+    // Presence Detect Changed (bit3)
+    //
+    QNCMmio32Or (RPBase, R_QNC_PCIE_SLSTS, (B_QNC_PCIE_SLSTS_PDC | B_QNC_PCIE_SLSTS_ABP));
+
+    //
+    // Sequence 2: Program the following bits in Slot Control register at offset 18h
+    // of PCI Express* Capability structure:
+    // Attention Button Pressed Enable (bit0) = 1b
+    // Presence Detect Changed Enable (bit3) = 1b
+    // Hot Plug Interrupt Enable (bit5) = 0b
+    //
+    QNCMmio32AndThenOr (RPBase, R_QNC_PCIE_SLCTL, (~B_QNC_PCIE_SLCTL_HPE), (B_QNC_PCIE_SLCTL_PDE | B_QNC_PCIE_SLCTL_ABE));
+
+    //
+    // Sequence 3: Program Misc Port Config (MPC) register at PCI config space offset
+    // D8h as follows:
+    // Hot Plug SCI Enable (HPCE, bit30) = 1b
+    // Hot Plug SMI Enable (HPME, bit1) = 0b
+    //
+    QNCMmio32AndThenOr (RPBase, R_QNC_PCIE_MPC, (~B_QNC_PCIE_MPC_HPME), B_QNC_PCIE_MPC_HPCE);
+  }
+
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Perform Initialization of the Downstream Root Ports
+**/
+VOID
+QNCDownStreamPortsInit (
+  IN PCIEXP_ROOT_PORT_CONFIGURATION             *RootPortConfig,
+  IN QNC_DEVICE_ENABLES                      *QNCDeviceEnables,
+  IN UINT64                                     PciExpressBar,
+  IN UINT32                                     QNCRootComplexBar,
+  IN UINT32                                     QNCPmioBase,
+  IN UINT32                                     QNCGpeBase,
+  OUT UINTN                                     *RpEnableMask
+  )
+{
+  EFI_STATUS     Status;
+  UINT32         Index;
+
+  //
+  // Initialize every root port and downstream device
+  //
+  for (Index = 0;Index < MAX_PCI_EXPRESS_ROOT_PORTS;Index++) {
+    if ((QNCDeviceEnables->Uint32 & (1 << Index)) != 0) {
+      Status = QNCRootPortInit (
+               Index,
+               RootPortConfig,
+               PciExpressBar,
+               QNCRootComplexBar,
+               QNCPmioBase,
+               QNCGpeBase
+               );
+
+      if (!EFI_ERROR (Status)) {
+        (*RpEnableMask) |= LShiftU64(1, Index);
+        DEBUG ((EFI_D_INFO, " Root Port %x device found, enabled. RpEnableMask: 0x%x\n", Index + 1, *RpEnableMask));
+      }
+    }
+  }
+}
+
+/**
+  Do early init of pci express rootports on Soc.
+
+**/
+
+VOID
+EFIAPI
+PciExpressEarlyInit (
+  VOID
+  )
+{
+  //
+  // Setup Message Bus Idle Counter (SBIC) values.
+  //
+  QNCMmPci8(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0, R_QNC_PCIE_IOSFSBCTL) = QNCMmPci8AndThenOr(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0, R_QNC_PCIE_IOSFSBCTL, (~B_QNC_PCIE_IOSFSBCTL_SBIC_MASK), V_PCIE_ROOT_PORT_SBIC_VALUE);
+  QNCMmPci8(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_1, R_QNC_PCIE_IOSFSBCTL) = QNCMmPci8AndThenOr(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_1, R_QNC_PCIE_IOSFSBCTL, (~B_QNC_PCIE_IOSFSBCTL_SBIC_MASK), V_PCIE_ROOT_PORT_SBIC_VALUE);
+
+  //
+  // Program SVID/SID the same as VID/DID for Root ports.
+  //
+  QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0, R_QNC_PCIE_SVID) = QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0, PCI_VENDOR_ID_OFFSET);
+  QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_1, R_QNC_PCIE_SVID) = QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_1, PCI_VENDOR_ID_OFFSET);
+
+  //
+  // Set the IPF bit in MCR2
+  //
+  QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0, R_QNC_PCIE_MPC2) = QNCMmPci32Or(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0, R_QNC_PCIE_MPC2, B_QNC_PCIE_MPC2_IPF);
+  QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_1, R_QNC_PCIE_MPC2) = QNCMmPci32Or(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_1, R_QNC_PCIE_MPC2, B_QNC_PCIE_MPC2_IPF);
+
+  //
+  // Set up the Posted and Non Posted Request sizes for PCIe
+  //
+  QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0, R_QNC_PCIE_CCFG) = QNCMmPci32AndThenOr(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0, R_QNC_PCIE_CCFG, ~B_QNC_PCIE_CCFG_UPSD, (B_QNC_PCIE_CCFG_UNRS | B_QNC_PCIE_CCFG_UPRS));
+
+  return;
+}
+
+
+/**
+  Complete initialization all the pci express rootports on Soc.
+**/
+EFI_STATUS
+EFIAPI
+PciExpressInit (
+  )
+{
+  UINT64                            PciExpressBar;
+  UINT32                            QNCRootComplexBar;
+  UINT32                            QNCPmioBase;
+  UINT32                            QNCGpeBase;
+  UINTN                             RpEnableMask;
+  PCIEXP_ROOT_PORT_CONFIGURATION    *mRootPortConfig;
+  QNC_DEVICE_ENABLES                mQNCDeviceEnables;
+
+  //
+  // Get BAR registers
+  //
+  QNCRootComplexBar  = QNC_RCRB_BASE;
+  QNCPmioBase        = LpcPciCfg32 (R_QNC_LPC_PM1BLK) & B_QNC_LPC_PM1BLK_MASK;
+  QNCGpeBase         = LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & B_QNC_LPC_GPE0BLK_MASK;
+  RpEnableMask = 0;                 // assume all root ports are disabled
+
+  PciExpressBar = PcdGet64 (PcdPciExpressBaseAddress);
+
+  //
+  // Get platform information from PCD entries
+  //
+  mQNCDeviceEnables.Uint32 = PcdGet32 (PcdDeviceEnables);
+  mRootPortConfig = (PCIEXP_ROOT_PORT_CONFIGURATION*) PcdGetPtr (PcdPcieRootPortConfiguration);
+
+  DEBUG ((EFI_D_INFO, " mRootPortConfig: 0x%x,  value1: 0x%x, value2: 0x%x, value3: 0x%x, value4: 0x%x\n",
+          mRootPortConfig, mRootPortConfig[0].Uint32, mRootPortConfig[1].Uint32,
+          mRootPortConfig[2].Uint32, mRootPortConfig[3].Uint32));
+
+  QNCDownStreamPortsInit (
+                         mRootPortConfig,
+                         &mQNCDeviceEnables,
+                         PciExpressBar,
+                         QNCRootComplexBar,
+                         QNCPmioBase,
+                         QNCGpeBase,
+                         &RpEnableMask
+                         );
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.c
new file mode 100644
index 0000000000..7df1c15f5b
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.c
@@ -0,0 +1,2112 @@
+/** @file
+MTRR setting library
+
+Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+
+#include <Library/MtrrLib.h>
+#include <Library/BaseLib.h>
+#include <Library/CpuLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/QNCAccessLib.h>
+
+#define QUARK_SOC_CPUID_FAMILY_MODEL_STEPPING         0x590
+
+#define CACHE_MTRR_ENABLED                            0x800
+#define CACHE_FIXED_MTRR_ENABLED                      0x400
+#define IA32_MTRR_CAP_VCNT_MASK                       0xFF
+
+//
+// Context to save and restore when MTRRs are programmed
+//
+typedef struct {
+  UINTN    Cr4;
+  BOOLEAN  InterruptState;
+} MTRR_CONTEXT;
+
+//
+// This table defines the offset, base and length of the fixed MTRRs
+//
+CONST FIXED_MTRR  mMtrrLibFixedMtrrTable[] = {
+  { QUARK_NC_HOST_BRIDGE_MTRR_FIX64K_00000, 0,       SIZE_64KB },
+  { QUARK_NC_HOST_BRIDGE_MTRR_FIX16K_80000, 0x80000, SIZE_16KB },
+  { QUARK_NC_HOST_BRIDGE_MTRR_FIX16K_A0000, 0xA0000, SIZE_16KB },
+  { QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_C0000,  0xC0000, SIZE_4KB  },
+  { QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_C8000,  0xC8000, SIZE_4KB  },
+  { QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_D0000,  0xD0000, SIZE_4KB  },
+  { QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_D8000,  0xD8000, SIZE_4KB  },
+  { QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_E0000,  0xE0000, SIZE_4KB  },
+  { QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_E8000,  0xE8000, SIZE_4KB  },
+  { QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_F0000,  0xF0000, SIZE_4KB  },
+  { QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_F8000,  0xF8000, SIZE_4KB  }
+};
+
+//
+// Lookup table used to print MTRRs
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mMtrrMemoryCacheTypeShortName[] = {
+  "UC",  // CacheUncacheable
+  "WC",  // CacheWriteCombining
+  "R*",  // Invalid
+  "R*",  // Invalid
+  "WT",  // CacheWriteThrough
+  "WP",  // CacheWriteProtected
+  "WB",  // CacheWriteBack
+  "R*"   // Invalid
+};
+
+UINT64
+MtrrRegisterRead (
+  IN  UINT32  MtrrRegister
+  )
+{
+  UINT64  Result;
+
+  Result = (UINT64)QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, MtrrRegister);
+  if (MtrrRegister >= QUARK_NC_HOST_BRIDGE_MTRR_FIX64K_00000 && MtrrRegister <= QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_F8000) {
+    Result = Result | LShiftU64 ((UINT64)QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, MtrrRegister + 1), 32);
+  }
+  return Result;
+}
+
+UINT64
+MtrrRegisterWrite (
+  IN  UINT32  MtrrRegister,
+  IN  UINT64  Value
+  )
+{
+  QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, MtrrRegister, (UINT32)Value);
+  if (MtrrRegister >= QUARK_NC_HOST_BRIDGE_MTRR_FIX64K_00000 && MtrrRegister <= QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_F8000) {
+    QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, MtrrRegister + 1, (UINT32)RShiftU64 (Value, 32));
+  }
+  return Value;
+}
+
+UINT64
+MtrrRegisterBitFieldWrite (
+  IN  UINT32  MtrrRegister,
+  IN  UINTN   StartBit,
+  IN  UINTN   EndBit,
+  IN  UINT64  Value
+  )
+{
+  return MtrrRegisterWrite (
+           MtrrRegister,
+           BitFieldWrite64 (
+             MtrrRegisterRead (MtrrRegister),
+             StartBit,
+             EndBit,
+             Value
+             )
+           );
+}
+
+/**
+  Worker function returns the variable MTRR count for the CPU.
+
+  @return Variable MTRR count
+
+**/
+UINT32
+GetVariableMtrrCountWorker (
+  VOID
+  )
+{
+  UINT32  VariableMtrrCount;
+
+  VariableMtrrCount = (UINT32)(MtrrRegisterRead (QUARK_NC_HOST_BRIDGE_IA32_MTRR_CAP) & IA32_MTRR_CAP_VCNT_MASK);
+  ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);
+  return VariableMtrrCount;
+}
+
+/**
+  Returns the variable MTRR count for the CPU.
+
+  @return Variable MTRR count
+
+**/
+UINT32
+EFIAPI
+GetVariableMtrrCount (
+  VOID
+  )
+{
+  if (!IsMtrrSupported ()) {
+    return 0;
+  }
+  return GetVariableMtrrCountWorker ();
+}
+
+/**
+  Worker function returns the firmware usable variable MTRR count for the CPU.
+
+  @return Firmware usable variable MTRR count
+
+**/
+UINT32
+GetFirmwareVariableMtrrCountWorker (
+  VOID
+  )
+{
+  UINT32  VariableMtrrCount;
+  UINT32  ReservedMtrrNumber;
+
+  VariableMtrrCount = GetVariableMtrrCountWorker ();
+  ReservedMtrrNumber = PcdGet32 (PcdCpuNumberOfReservedVariableMtrrs);
+  if (VariableMtrrCount < ReservedMtrrNumber) {
+    return 0;
+  }
+
+  return VariableMtrrCount - ReservedMtrrNumber;
+}
+
+/**
+  Returns the firmware usable variable MTRR count for the CPU.
+
+  @return Firmware usable variable MTRR count
+
+**/
+UINT32
+EFIAPI
+GetFirmwareVariableMtrrCount (
+  VOID
+  )
+{
+  if (!IsMtrrSupported ()) {
+    return 0;
+  }
+  return GetFirmwareVariableMtrrCountWorker ();
+}
+
+/**
+  Worker function returns the default MTRR cache type for the system.
+
+  If MtrrSetting is not NULL, returns the default MTRR cache type from input
+  MTRR settings buffer.
+  If MtrrSetting is NULL, returns the default MTRR cache type from MSR.
+
+  @param[in]  MtrrSetting    A buffer holding all MTRRs content.
+
+  @return  The default MTRR cache type.
+
+**/
+MTRR_MEMORY_CACHE_TYPE
+MtrrGetDefaultMemoryTypeWorker (
+  IN MTRR_SETTINGS      *MtrrSetting
+  )
+{
+  if (MtrrSetting == NULL) {
+    return (MTRR_MEMORY_CACHE_TYPE) (MtrrRegisterRead (QUARK_NC_HOST_BRIDGE_IA32_MTRR_DEF_TYPE) & 0x7);
+  } else {
+    return (MTRR_MEMORY_CACHE_TYPE) (MtrrSetting->MtrrDefType & 0x7);
+  }
+}
+
+
+/**
+  Returns the default MTRR cache type for the system.
+
+  @return  The default MTRR cache type.
+
+**/
+MTRR_MEMORY_CACHE_TYPE
+EFIAPI
+MtrrGetDefaultMemoryType (
+  VOID
+  )
+{
+  if (!IsMtrrSupported ()) {
+    return CacheUncacheable;
+  }
+  return MtrrGetDefaultMemoryTypeWorker (NULL);
+}
+
+/**
+  Preparation before programming MTRR.
+
+  This function will do some preparation for programming MTRRs:
+  disable cache, invalid cache and disable MTRR caching functionality
+
+  @param[out] MtrrContext  Pointer to context to save
+
+**/
+VOID
+PreMtrrChange (
+  OUT MTRR_CONTEXT  *MtrrContext
+  )
+{
+  //
+  // Disable interrupts and save current interrupt state
+  //
+  MtrrContext->InterruptState = SaveAndDisableInterrupts();
+
+  //
+  // Enter no fill cache mode, CD=1(Bit30), NW=0 (Bit29)
+  //
+  AsmDisableCache ();
+
+  //
+  // Save original CR4 value and clear PGE flag (Bit 7)
+  //
+  MtrrContext->Cr4 = AsmReadCr4 ();
+  AsmWriteCr4 (MtrrContext->Cr4 & (~BIT7));
+
+  //
+  // Flush all TLBs
+  //
+  CpuFlushTlb ();
+
+  //
+  // Disable MTRRs
+  //
+  MtrrRegisterBitFieldWrite (QUARK_NC_HOST_BRIDGE_IA32_MTRR_DEF_TYPE, 10, 11, 0);
+}
+
+/**
+  Cleaning up after programming MTRRs.
+
+  This function will do some clean up after programming MTRRs:
+  Flush all TLBs,  re-enable caching, restore CR4.
+
+  @param[in] MtrrContext  Pointer to context to restore
+
+**/
+VOID
+PostMtrrChangeEnableCache (
+  IN MTRR_CONTEXT  *MtrrContext
+  )
+{
+  //
+  // Flush all TLBs
+  //
+  CpuFlushTlb ();
+
+  //
+  // Enable Normal Mode caching CD=NW=0, CD(Bit30), NW(Bit29)
+  //
+  AsmEnableCache ();
+
+  //
+  // Restore original CR4 value
+  //
+  AsmWriteCr4 (MtrrContext->Cr4);
+
+  //
+  // Restore original interrupt state
+  //
+  SetInterruptState (MtrrContext->InterruptState);
+}
+
+/**
+  Cleaning up after programming MTRRs.
+
+  This function will do some clean up after programming MTRRs:
+  enable MTRR caching functionality, and enable cache
+
+  @param[in] MtrrContext  Pointer to context to restore
+
+**/
+VOID
+PostMtrrChange (
+  IN MTRR_CONTEXT  *MtrrContext
+  )
+{
+  //
+  // Enable Cache MTRR
+  //
+  MtrrRegisterBitFieldWrite (QUARK_NC_HOST_BRIDGE_IA32_MTRR_DEF_TYPE, 10, 11, 3);
+
+  PostMtrrChangeEnableCache (MtrrContext);
+}
+
+/**
+  Worker function gets the content in fixed MTRRs
+
+  @param[out]  FixedSettings  A buffer to hold fixed MTRRs content.
+
+  @retval The pointer of FixedSettings
+
+**/
+MTRR_FIXED_SETTINGS*
+MtrrGetFixedMtrrWorker (
+  OUT MTRR_FIXED_SETTINGS         *FixedSettings
+  )
+{
+  UINT32  Index;
+
+  for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
+      FixedSettings->Mtrr[Index] =
+        MtrrRegisterRead (mMtrrLibFixedMtrrTable[Index].Msr);
+  }
+
+  return FixedSettings;
+}
+
+
+/**
+  This function gets the content in fixed MTRRs
+
+  @param[out]  FixedSettings  A buffer to hold fixed MTRRs content.
+
+  @retval The pointer of FixedSettings
+
+**/
+MTRR_FIXED_SETTINGS*
+EFIAPI
+MtrrGetFixedMtrr (
+  OUT MTRR_FIXED_SETTINGS         *FixedSettings
+  )
+{
+  if (!IsMtrrSupported ()) {
+    return FixedSettings;
+  }
+
+  return MtrrGetFixedMtrrWorker (FixedSettings);
+}
+
+
+/**
+  Worker function will get the raw value in variable MTRRs
+
+  If MtrrSetting is not NULL, gets the variable MTRRs raw value from input
+  MTRR settings buffer.
+  If MtrrSetting is NULL, gets the variable MTRRs raw value from MTRRs.
+
+  @param[in]  MtrrSetting        A buffer holding all MTRRs content.
+  @param[in]  VariableMtrrCount  Number of variable MTRRs.
+  @param[out] VariableSettings   A buffer to hold variable MTRRs content.
+
+  @return The VariableSettings input pointer
+
+**/
+MTRR_VARIABLE_SETTINGS*
+MtrrGetVariableMtrrWorker (
+  IN  MTRR_SETTINGS           *MtrrSetting,
+  IN  UINT32                  VariableMtrrCount,
+  OUT MTRR_VARIABLE_SETTINGS  *VariableSettings
+  )
+{
+  UINT32  Index;
+
+  ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);
+
+  for (Index = 0; Index < VariableMtrrCount; Index++) {
+    if (MtrrSetting == NULL) {
+      VariableSettings->Mtrr[Index].Base =
+        MtrrRegisterRead (QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE0 + (Index << 1));
+      VariableSettings->Mtrr[Index].Mask =
+        MtrrRegisterRead (QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE0 + (Index << 1) + 1);
+    } else {
+      VariableSettings->Mtrr[Index].Base = MtrrSetting->Variables.Mtrr[Index].Base;
+      VariableSettings->Mtrr[Index].Mask = MtrrSetting->Variables.Mtrr[Index].Mask;
+    }
+  }
+
+  return  VariableSettings;
+}
+
+/**
+  This function will get the raw value in variable MTRRs
+
+  @param[out]  VariableSettings   A buffer to hold variable MTRRs content.
+
+  @return The VariableSettings input pointer
+
+**/
+MTRR_VARIABLE_SETTINGS*
+EFIAPI
+MtrrGetVariableMtrr (
+  OUT MTRR_VARIABLE_SETTINGS         *VariableSettings
+  )
+{
+  if (!IsMtrrSupported ()) {
+    return VariableSettings;
+  }
+
+  return MtrrGetVariableMtrrWorker (
+           NULL,
+           GetVariableMtrrCountWorker (),
+           VariableSettings
+           );
+}
+
+/**
+  Programs fixed MTRRs registers.
+
+  @param[in]      MemoryCacheType  The memory type to set.
+  @param[in, out] Base             The base address of memory range.
+  @param[in, out] Length           The length of memory range.
+  @param[out]     ReturnMsrNum     The index of the fixed MTRR MSR to program.
+  @param[out]     ReturnClearMask  The bits to clear in the fixed MTRR MSR.
+  @param[out]     ReturnOrMask     The bits to set in the fixed MTRR MSR.
+
+  @retval RETURN_SUCCESS      The cache type was updated successfully
+  @retval RETURN_UNSUPPORTED  The requested range or cache type was invalid
+                              for the fixed MTRRs.
+
+**/
+RETURN_STATUS
+ProgramFixedMtrr (
+  IN     UINT64               MemoryCacheType,
+  IN OUT UINT64               *Base,
+  IN OUT UINT64               *Length,
+  OUT    UINT32               *ReturnMsrNum,
+  OUT    UINT64               *ReturnClearMask,
+  OUT    UINT64               *ReturnOrMask
+  )
+{
+  UINT32  MsrNum;
+  UINT32  ByteShift;
+  UINT64  OrMask;
+  UINT64  ClearMask;
+
+  OrMask    = 0;
+  ClearMask = 0;
+
+  for (MsrNum = 0; MsrNum < MTRR_NUMBER_OF_FIXED_MTRR; MsrNum++) {
+    if ((*Base >= mMtrrLibFixedMtrrTable[MsrNum].BaseAddress) &&
+        (*Base <
+            (
+              mMtrrLibFixedMtrrTable[MsrNum].BaseAddress +
+              (8 * mMtrrLibFixedMtrrTable[MsrNum].Length)
+            )
+          )
+        ) {
+      break;
+    }
+  }
+
+  if (MsrNum == MTRR_NUMBER_OF_FIXED_MTRR) {
+    return RETURN_UNSUPPORTED;
+  }
+
+  //
+  // We found the fixed MTRR to be programmed
+  //
+  for (ByteShift = 0; ByteShift < 8; ByteShift++) {
+    if (*Base ==
+         (
+           mMtrrLibFixedMtrrTable[MsrNum].BaseAddress +
+           (ByteShift * mMtrrLibFixedMtrrTable[MsrNum].Length)
+         )
+       ) {
+      break;
+    }
+  }
+
+  if (ByteShift == 8) {
+    return RETURN_UNSUPPORTED;
+  }
+
+  for (
+        ;
+        ((ByteShift < 8) && (*Length >= mMtrrLibFixedMtrrTable[MsrNum].Length));
+        ByteShift++
+      ) {
+    OrMask |= LShiftU64 ((UINT64) MemoryCacheType, (UINT32) (ByteShift * 8));
+    ClearMask |= LShiftU64 ((UINT64) 0xFF, (UINT32) (ByteShift * 8));
+    *Length -= mMtrrLibFixedMtrrTable[MsrNum].Length;
+    *Base += mMtrrLibFixedMtrrTable[MsrNum].Length;
+  }
+
+  if (ByteShift < 8 && (*Length != 0)) {
+    return RETURN_UNSUPPORTED;
+  }
+
+  *ReturnMsrNum    = MsrNum;
+  *ReturnClearMask = ClearMask;
+  *ReturnOrMask    = OrMask;
+
+  return RETURN_SUCCESS;
+}
+
+
+/**
+  Worker function gets the attribute of variable MTRRs.
+
+  This function shadows the content of variable MTRRs into an
+  internal array: VariableMtrr.
+
+  @param[in]   VariableSettings           The variable MTRR values to shadow
+  @param[in]   FirmwareVariableMtrrCount  The number of variable MTRRs available to firmware
+  @param[in]   MtrrValidBitsMask          The mask for the valid bit of the MTRR
+  @param[in]   MtrrValidAddressMask       The valid address mask for MTRR
+  @param[out]  VariableMtrr               The array to shadow variable MTRRs content
+
+  @return                       The return value of this parameter indicates the
+                                number of MTRRs which has been used.
+
+**/
+UINT32
+MtrrGetMemoryAttributeInVariableMtrrWorker (
+  IN  MTRR_VARIABLE_SETTINGS  *VariableSettings,
+  IN  UINTN                   FirmwareVariableMtrrCount,
+  IN  UINT64                  MtrrValidBitsMask,
+  IN  UINT64                  MtrrValidAddressMask,
+  OUT VARIABLE_MTRR           *VariableMtrr
+  )
+{
+  UINTN   Index;
+  UINT32  UsedMtrr;
+
+  ZeroMem (VariableMtrr, sizeof (VARIABLE_MTRR) * MTRR_NUMBER_OF_VARIABLE_MTRR);
+  for (Index = 0, UsedMtrr = 0; Index < FirmwareVariableMtrrCount; Index++) {
+    if ((VariableSettings->Mtrr[Index].Mask & CACHE_MTRR_ENABLED) != 0) {
+      VariableMtrr[Index].Msr         = (UINT32)Index;
+      VariableMtrr[Index].BaseAddress = (VariableSettings->Mtrr[Index].Base & MtrrValidAddressMask);
+      VariableMtrr[Index].Length      = ((~(VariableSettings->Mtrr[Index].Mask & MtrrValidAddressMask)) & MtrrValidBitsMask) + 1;
+      VariableMtrr[Index].Type        = (VariableSettings->Mtrr[Index].Base & 0x0ff);
+      VariableMtrr[Index].Valid       = TRUE;
+      VariableMtrr[Index].Used        = TRUE;
+      UsedMtrr++;
+    }
+  }
+  return UsedMtrr;
+}
+
+
+/**
+  Gets the attribute of variable MTRRs.
+
+  This function shadows the content of variable MTRRs into an
+  internal array: VariableMtrr.
+
+  @param[in]   MtrrValidBitsMask     The mask for the valid bit of the MTRR
+  @param[in]   MtrrValidAddressMask  The valid address mask for MTRR
+  @param[out]  VariableMtrr          The array to shadow variable MTRRs content
+
+  @return                       The return value of this parameter indicates the
+                                number of MTRRs which has been used.
+
+**/
+UINT32
+EFIAPI
+MtrrGetMemoryAttributeInVariableMtrr (
+  IN  UINT64                    MtrrValidBitsMask,
+  IN  UINT64                    MtrrValidAddressMask,
+  OUT VARIABLE_MTRR             *VariableMtrr
+  )
+{
+  MTRR_VARIABLE_SETTINGS  VariableSettings;
+
+  if (!IsMtrrSupported ()) {
+    return 0;
+  }
+
+  MtrrGetVariableMtrrWorker (
+    NULL,
+    GetVariableMtrrCountWorker (),
+    &VariableSettings
+    );
+
+  return MtrrGetMemoryAttributeInVariableMtrrWorker (
+           &VariableSettings,
+           GetFirmwareVariableMtrrCountWorker (),
+           MtrrValidBitsMask,
+           MtrrValidAddressMask,
+           VariableMtrr
+           );
+}
+
+
+/**
+  Checks overlap between given memory range and MTRRs.
+
+  @param[in]  FirmwareVariableMtrrCount  The number of variable MTRRs available
+                                         to firmware.
+  @param[in]  Start                      The start address of memory range.
+  @param[in]  End                        The end address of memory range.
+  @param[in]  VariableMtrr               The array to shadow variable MTRRs content
+
+  @retval TRUE             Overlap exists.
+  @retval FALSE            No overlap.
+
+**/
+BOOLEAN
+CheckMemoryAttributeOverlap (
+  IN UINTN             FirmwareVariableMtrrCount,
+  IN PHYSICAL_ADDRESS  Start,
+  IN PHYSICAL_ADDRESS  End,
+  IN VARIABLE_MTRR     *VariableMtrr
+  )
+{
+  UINT32  Index;
+
+  for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) {
+    if (
+         VariableMtrr[Index].Valid &&
+         !(
+           (Start > (VariableMtrr[Index].BaseAddress +
+                     VariableMtrr[Index].Length - 1)
+           ) ||
+           (End < VariableMtrr[Index].BaseAddress)
+         )
+       ) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
+
+/**
+  Marks a variable MTRR as non-valid.
+
+  @param[in]   Index         The index of the array VariableMtrr to be invalidated
+  @param[in]   VariableMtrr  The array to shadow variable MTRRs content
+  @param[out]  UsedMtrr      The number of MTRRs which has already been used
+
+**/
+VOID
+InvalidateShadowMtrr (
+  IN   UINTN              Index,
+  IN   VARIABLE_MTRR      *VariableMtrr,
+  OUT  UINT32             *UsedMtrr
+  )
+{
+  VariableMtrr[Index].Valid = FALSE;
+  *UsedMtrr = *UsedMtrr - 1;
+}
+
+
+/**
+  Combines memory attributes.
+
+  If overlap exists between given memory range and MTRRs, try to combine them.
+
+  @param[in]       FirmwareVariableMtrrCount  The number of variable MTRRs
+                                              available to firmware.
+  @param[in]       Attributes                 The memory type to set.
+  @param[in, out]  Base                       The base address of memory range.
+  @param[in, out]  Length                     The length of memory range.
+  @param[in]       VariableMtrr               The array to shadow variable MTRRs content
+  @param[in, out]  UsedMtrr                   The number of MTRRs which has already been used
+  @param[out]      OverwriteExistingMtrr      Returns whether an existing MTRR was used
+
+  @retval EFI_SUCCESS            Memory region successfully combined.
+  @retval EFI_ACCESS_DENIED      Memory region cannot be combined.
+
+**/
+RETURN_STATUS
+CombineMemoryAttribute (
+  IN     UINT32             FirmwareVariableMtrrCount,
+  IN     UINT64             Attributes,
+  IN OUT UINT64             *Base,
+  IN OUT UINT64             *Length,
+  IN     VARIABLE_MTRR      *VariableMtrr,
+  IN OUT UINT32             *UsedMtrr,
+  OUT    BOOLEAN            *OverwriteExistingMtrr
+  )
+{
+  UINT32  Index;
+  UINT64  CombineStart;
+  UINT64  CombineEnd;
+  UINT64  MtrrEnd;
+  UINT64  EndAddress;
+  BOOLEAN CoveredByExistingMtrr;
+
+  *OverwriteExistingMtrr = FALSE;
+  CoveredByExistingMtrr = FALSE;
+  EndAddress = *Base +*Length - 1;
+
+  for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) {
+
+    MtrrEnd = VariableMtrr[Index].BaseAddress + VariableMtrr[Index].Length - 1;
+    if (
+         !VariableMtrr[Index].Valid ||
+         (
+           *Base > (MtrrEnd) ||
+           (EndAddress < VariableMtrr[Index].BaseAddress)
+         )
+       ) {
+      continue;
+    }
+
+    //
+    // Combine same attribute MTRR range
+    //
+    if (Attributes == VariableMtrr[Index].Type) {
+      //
+      // if the MTRR range contain the request range, set a flag, then continue to
+      // invalidate any MTRR of the same request range with higher priority cache type.
+      //
+      if (VariableMtrr[Index].BaseAddress <= *Base && MtrrEnd >= EndAddress) {
+        CoveredByExistingMtrr = TRUE;
+        continue;
+      }
+      //
+      // invalid this MTRR, and program the combine range
+      //
+      CombineStart  =
+        (*Base) < VariableMtrr[Index].BaseAddress ?
+          (*Base) :
+          VariableMtrr[Index].BaseAddress;
+      CombineEnd    = EndAddress > MtrrEnd ? EndAddress : MtrrEnd;
+
+      //
+      // Record the MTRR usage status in VariableMtrr array.
+      //
+      InvalidateShadowMtrr (Index, VariableMtrr, UsedMtrr);
+      *Base       = CombineStart;
+      *Length     = CombineEnd - CombineStart + 1;
+      EndAddress  = CombineEnd;
+      *OverwriteExistingMtrr = TRUE;
+      continue;
+    } else {
+      //
+      // The cache type is different, but the range is convered by one MTRR
+      //
+      if (VariableMtrr[Index].BaseAddress == *Base && MtrrEnd == EndAddress) {
+        InvalidateShadowMtrr (Index, VariableMtrr, UsedMtrr);
+        continue;
+      }
+
+    }
+
+    if ((Attributes== MTRR_CACHE_WRITE_THROUGH &&
+         VariableMtrr[Index].Type == MTRR_CACHE_WRITE_BACK) ||
+        (Attributes == MTRR_CACHE_WRITE_BACK &&
+         VariableMtrr[Index].Type == MTRR_CACHE_WRITE_THROUGH) ||
+        (Attributes == MTRR_CACHE_UNCACHEABLE) ||
+        (VariableMtrr[Index].Type == MTRR_CACHE_UNCACHEABLE)
+     ) {
+      *OverwriteExistingMtrr = TRUE;
+      continue;
+    }
+    //
+    // Other type memory overlap is invalid
+    //
+    return RETURN_ACCESS_DENIED;
+  }
+
+  if (CoveredByExistingMtrr) {
+    *Length = 0;
+  }
+
+  return RETURN_SUCCESS;
+}
+
+
+/**
+  Calculates the maximum value which is a power of 2, but less the MemoryLength.
+
+  @param[in]  MemoryLength        The number to pass in.
+
+  @return The maximum value which is align to power of 2 and less the MemoryLength
+
+**/
+UINT64
+Power2MaxMemory (
+  IN UINT64                     MemoryLength
+  )
+{
+  UINT64  Result;
+
+  if (RShiftU64 (MemoryLength, 32) != 0) {
+    Result = LShiftU64 (
+               (UINT64) GetPowerOfTwo32 (
+                          (UINT32) RShiftU64 (MemoryLength, 32)
+                          ),
+               32
+               );
+  } else {
+    Result = (UINT64) GetPowerOfTwo32 ((UINT32) MemoryLength);
+  }
+
+  return Result;
+}
+
+
+/**
+  Determines the MTRR numbers used to program a memory range.
+
+  This function first checks the alignment of the base address.
+  If the alignment of the base address <= Length, cover the memory range
+ (BaseAddress, alignment) by a MTRR, then BaseAddress += alignment and
+  Length -= alignment. Repeat the step until alignment > Length.
+
+  Then this function determines which direction of programming the variable
+  MTRRs for the remaining length will use fewer MTRRs.
+
+  @param[in]  BaseAddress Length of Memory to program MTRR
+  @param[in]  Length      Length of Memory to program MTRR
+  @param[in]  MtrrNumber  Pointer to the number of necessary MTRRs
+
+  @retval TRUE        Positive direction is better.
+          FALSE       Negative direction is better.
+
+**/
+BOOLEAN
+GetMtrrNumberAndDirection (
+  IN UINT64      BaseAddress,
+  IN UINT64      Length,
+  IN UINTN       *MtrrNumber
+  )
+{
+  UINT64  TempQword;
+  UINT64  Alignment;
+  UINT32  Positive;
+  UINT32  Subtractive;
+
+  *MtrrNumber = 0;
+
+  if (BaseAddress != 0) {
+    do {
+      //
+      // Calculate the alignment of the base address.
+      //
+      Alignment = LShiftU64 (1, (UINTN)LowBitSet64 (BaseAddress));
+
+      if (Alignment > Length) {
+        break;
+      }
+
+      (*MtrrNumber)++;
+      BaseAddress += Alignment;
+      Length -= Alignment;
+    } while (TRUE);
+
+    if (Length == 0) {
+      return TRUE;
+    }
+  }
+
+  TempQword   = Length;
+  Positive    = 0;
+  Subtractive = 0;
+
+  do {
+    TempQword -= Power2MaxMemory (TempQword);
+    Positive++;
+  } while (TempQword != 0);
+
+  TempQword = Power2MaxMemory (LShiftU64 (Length, 1)) - Length;
+  Subtractive++;
+  do {
+    TempQword -= Power2MaxMemory (TempQword);
+    Subtractive++;
+  } while (TempQword != 0);
+
+  if (Positive <= Subtractive) {
+    *MtrrNumber += Positive;
+    return TRUE;
+  } else {
+    *MtrrNumber += Subtractive;
+    return FALSE;
+  }
+}
+
+/**
+  Invalid variable MTRRs according to the value in the shadow array.
+
+  This function programs MTRRs according to the values specified
+  in the shadow array.
+
+  @param[in, out]  VariableSettings   Variable MTRR settings
+  @param[in]       VariableMtrrCount  Number of variable MTRRs
+  @param[in, out]  VariableMtrr       Shadow of variable MTRR contents
+
+**/
+VOID
+InvalidateMtrr (
+  IN OUT MTRR_VARIABLE_SETTINGS  *VariableSettings,
+  IN     UINTN                   VariableMtrrCount,
+  IN OUT VARIABLE_MTRR           *VariableMtrr
+  )
+{
+  UINTN         Index;
+
+  for (Index = 0; Index < VariableMtrrCount; Index++) {
+    if (!VariableMtrr[Index].Valid && VariableMtrr[Index].Used) {
+       VariableSettings->Mtrr[Index].Base = 0;
+       VariableSettings->Mtrr[Index].Mask = 0;
+       VariableMtrr[Index].Used = FALSE;
+    }
+  }
+}
+
+
+/**
+  Programs variable MTRRs
+
+  This function programs variable MTRRs
+
+  @param[in, out]  VariableSettings      Variable MTRR settings.
+  @param[in]       MtrrNumber            Index of MTRR to program.
+  @param[in]       BaseAddress           Base address of memory region.
+  @param[in]       Length                Length of memory region.
+  @param[in]       MemoryCacheType       Memory type to set.
+  @param[in]       MtrrValidAddressMask  The valid address mask for MTRR
+
+**/
+VOID
+ProgramVariableMtrr (
+  IN OUT MTRR_VARIABLE_SETTINGS  *VariableSettings,
+  IN     UINTN                   MtrrNumber,
+  IN     PHYSICAL_ADDRESS        BaseAddress,
+  IN     UINT64                  Length,
+  IN     UINT64                  MemoryCacheType,
+  IN     UINT64                  MtrrValidAddressMask
+  )
+{
+  UINT64        TempQword;
+
+  //
+  // MTRR Physical Base
+  //
+  TempQword = (BaseAddress & MtrrValidAddressMask) | MemoryCacheType;
+  VariableSettings->Mtrr[MtrrNumber].Base = TempQword;
+
+  //
+  // MTRR Physical Mask
+  //
+  TempQword = ~(Length - 1);
+  VariableSettings->Mtrr[MtrrNumber].Mask = (TempQword & MtrrValidAddressMask) | CACHE_MTRR_ENABLED;
+}
+
+
+/**
+  Converts the Memory attribute value to MTRR_MEMORY_CACHE_TYPE.
+
+  If MtrrSetting is not NULL, gets the default memory attribute from input
+  MTRR settings buffer.
+  If MtrrSetting is NULL, gets the default memory attribute from MSR.
+
+  @param[in]  MtrrSetting        A buffer holding all MTRRs content.
+  @param[in]  MtrrType           MTRR memory type
+
+  @return The enum item in MTRR_MEMORY_CACHE_TYPE
+
+**/
+MTRR_MEMORY_CACHE_TYPE
+GetMemoryCacheTypeFromMtrrType (
+  IN MTRR_SETTINGS         *MtrrSetting,
+  IN UINT64                MtrrType
+  )
+{
+  switch (MtrrType) {
+  case MTRR_CACHE_UNCACHEABLE:
+    return CacheUncacheable;
+  case MTRR_CACHE_WRITE_COMBINING:
+    return CacheWriteCombining;
+  case MTRR_CACHE_WRITE_THROUGH:
+    return CacheWriteThrough;
+  case MTRR_CACHE_WRITE_PROTECTED:
+    return CacheWriteProtected;
+  case MTRR_CACHE_WRITE_BACK:
+    return CacheWriteBack;
+  default:
+    //
+    // MtrrType is MTRR_CACHE_INVALID_TYPE, that means
+    // no MTRR covers the range
+    //
+    return MtrrGetDefaultMemoryTypeWorker (MtrrSetting);
+  }
+}
+
+/**
+  Initializes the valid bits mask and valid address mask for MTRRs.
+
+  This function initializes the valid bits mask and valid address mask for MTRRs.
+
+  @param[out]  MtrrValidBitsMask     The mask for the valid bit of the MTRR
+  @param[out]  MtrrValidAddressMask  The valid address mask for the MTRR
+
+**/
+VOID
+MtrrLibInitializeMtrrMask (
+  OUT UINT64 *MtrrValidBitsMask,
+  OUT UINT64 *MtrrValidAddressMask
+  )
+{
+  UINT32  RegEax;
+  UINT8   PhysicalAddressBits;
+
+  AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+
+  if (RegEax >= 0x80000008) {
+    AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
+
+    PhysicalAddressBits = (UINT8) RegEax;
+  } else {
+    PhysicalAddressBits = 36;
+  }
+
+  *MtrrValidBitsMask    = LShiftU64 (1, PhysicalAddressBits) - 1;
+  *MtrrValidAddressMask = *MtrrValidBitsMask & 0xfffffffffffff000ULL;
+}
+
+
+/**
+  Determines the real attribute of a memory range.
+
+  This function is to arbitrate the real attribute of the memory when
+  there are 2 MTRRs covers the same memory range.  For further details,
+  please refer the IA32 Software Developer's Manual, Volume 3,
+  Section 10.11.4.1.
+
+  @param[in]  MtrrType1    The first kind of Memory type
+  @param[in]  MtrrType2    The second kind of memory type
+
+**/
+UINT64
+MtrrPrecedence (
+  IN UINT64    MtrrType1,
+  IN UINT64    MtrrType2
+  )
+{
+  UINT64 MtrrType;
+
+  MtrrType = MTRR_CACHE_INVALID_TYPE;
+  switch (MtrrType1) {
+  case MTRR_CACHE_UNCACHEABLE:
+    MtrrType = MTRR_CACHE_UNCACHEABLE;
+    break;
+  case MTRR_CACHE_WRITE_COMBINING:
+    if (
+         MtrrType2==MTRR_CACHE_WRITE_COMBINING ||
+         MtrrType2==MTRR_CACHE_UNCACHEABLE
+       ) {
+      MtrrType = MtrrType2;
+    }
+    break;
+  case MTRR_CACHE_WRITE_THROUGH:
+    if (
+         MtrrType2==MTRR_CACHE_WRITE_THROUGH ||
+         MtrrType2==MTRR_CACHE_WRITE_BACK
+       ) {
+      MtrrType = MTRR_CACHE_WRITE_THROUGH;
+    } else if(MtrrType2==MTRR_CACHE_UNCACHEABLE) {
+      MtrrType = MTRR_CACHE_UNCACHEABLE;
+    }
+    break;
+  case MTRR_CACHE_WRITE_PROTECTED:
+    if (MtrrType2 == MTRR_CACHE_WRITE_PROTECTED ||
+        MtrrType2 == MTRR_CACHE_UNCACHEABLE) {
+      MtrrType = MtrrType2;
+    }
+    break;
+  case MTRR_CACHE_WRITE_BACK:
+    if (
+         MtrrType2== MTRR_CACHE_UNCACHEABLE ||
+         MtrrType2==MTRR_CACHE_WRITE_THROUGH ||
+         MtrrType2== MTRR_CACHE_WRITE_BACK
+       ) {
+      MtrrType = MtrrType2;
+    }
+    break;
+  case MTRR_CACHE_INVALID_TYPE:
+    MtrrType = MtrrType2;
+    break;
+  default:
+    break;
+  }
+
+  if (MtrrType2 == MTRR_CACHE_INVALID_TYPE) {
+    MtrrType = MtrrType1;
+  }
+  return MtrrType;
+}
+
+/**
+  Worker function will get the memory cache type of the specific address.
+
+  If MtrrSetting is not NULL, gets the memory cache type from input
+  MTRR settings buffer.
+  If MtrrSetting is NULL, gets the memory cache type from MTRRs.
+
+  @param[in]  MtrrSetting        A buffer holding all MTRRs content.
+  @param[in]  Address            The specific address
+
+  @return Memory cache type of the specific address
+
+**/
+MTRR_MEMORY_CACHE_TYPE
+MtrrGetMemoryAttributeByAddressWorker (
+  IN MTRR_SETTINGS      *MtrrSetting,
+  IN PHYSICAL_ADDRESS   Address
+  )
+{
+  UINT64                  TempQword;
+  UINTN                   Index;
+  UINTN                   SubIndex;
+  UINT64                  MtrrType;
+  UINT64                  TempMtrrType;
+  MTRR_MEMORY_CACHE_TYPE  CacheType;
+  VARIABLE_MTRR           VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];
+  UINT64                  MtrrValidBitsMask;
+  UINT64                  MtrrValidAddressMask;
+  UINTN                   VariableMtrrCount;
+  MTRR_VARIABLE_SETTINGS  VariableSettings;
+
+  //
+  // Check if MTRR is enabled, if not, return UC as attribute
+  //
+  if (MtrrSetting == NULL) {
+    TempQword = MtrrRegisterRead (QUARK_NC_HOST_BRIDGE_IA32_MTRR_DEF_TYPE);
+  } else {
+    TempQword = MtrrSetting->MtrrDefType;
+  }
+  MtrrType = MTRR_CACHE_INVALID_TYPE;
+
+  if ((TempQword & CACHE_MTRR_ENABLED) == 0) {
+    return CacheUncacheable;
+  }
+
+  //
+  // If address is less than 1M, then try to go through the fixed MTRR
+  //
+  if (Address < BASE_1MB) {
+    if ((TempQword & CACHE_FIXED_MTRR_ENABLED) != 0) {
+      //
+      // Go through the fixed MTRR
+      //
+      for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
+         if (Address >= mMtrrLibFixedMtrrTable[Index].BaseAddress &&
+             Address  < (
+                          mMtrrLibFixedMtrrTable[Index].BaseAddress +
+                          (mMtrrLibFixedMtrrTable[Index].Length * 8)
+                        )
+            ) {
+           SubIndex =
+             ((UINTN)Address - mMtrrLibFixedMtrrTable[Index].BaseAddress) /
+               mMtrrLibFixedMtrrTable[Index].Length;
+           if (MtrrSetting == NULL) {
+             TempQword = MtrrRegisterRead (mMtrrLibFixedMtrrTable[Index].Msr);
+           } else {
+             TempQword = MtrrSetting->Fixed.Mtrr[Index];
+           }
+           MtrrType =  RShiftU64 (TempQword, SubIndex * 8) & 0xFF;
+           return GetMemoryCacheTypeFromMtrrType (MtrrSetting, MtrrType);
+         }
+      }
+    }
+  }
+  MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask);
+
+  MtrrGetVariableMtrrWorker (
+    MtrrSetting,
+    GetVariableMtrrCountWorker (),
+    &VariableSettings
+    );
+
+  MtrrGetMemoryAttributeInVariableMtrrWorker (
+           &VariableSettings,
+           GetFirmwareVariableMtrrCountWorker (),
+           MtrrValidBitsMask,
+           MtrrValidAddressMask,
+           VariableMtrr
+           );
+
+  //
+  // Go through the variable MTRR
+  //
+  VariableMtrrCount = GetVariableMtrrCountWorker ();
+  ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);
+
+  for (Index = 0; Index < VariableMtrrCount; Index++) {
+    if (VariableMtrr[Index].Valid) {
+      if (Address >= VariableMtrr[Index].BaseAddress &&
+          Address < VariableMtrr[Index].BaseAddress+VariableMtrr[Index].Length) {
+        TempMtrrType = VariableMtrr[Index].Type;
+        MtrrType = MtrrPrecedence (MtrrType, TempMtrrType);
+      }
+    }
+  }
+  CacheType = GetMemoryCacheTypeFromMtrrType (MtrrSetting, MtrrType);
+
+  return CacheType;
+}
+
+
+/**
+  This function will get the memory cache type of the specific address.
+
+  This function is mainly for debug purpose.
+
+  @param[in]  Address   The specific address
+
+  @return Memory cache type of the specific address
+
+**/
+MTRR_MEMORY_CACHE_TYPE
+EFIAPI
+MtrrGetMemoryAttribute (
+  IN PHYSICAL_ADDRESS   Address
+  )
+{
+  if (!IsMtrrSupported ()) {
+    return CacheUncacheable;
+  }
+
+  return MtrrGetMemoryAttributeByAddressWorker (NULL, Address);
+}
+
+/**
+  Worker function prints all MTRRs for debugging.
+
+  If MtrrSetting is not NULL, print MTRR settings from from input MTRR
+  settings buffer.
+  If MtrrSetting is NULL, print MTRR settings from MTRRs.
+
+  @param  MtrrSetting    A buffer holding all MTRRs content.
+**/
+VOID
+MtrrDebugPrintAllMtrrsWorker (
+  IN MTRR_SETTINGS    *MtrrSetting
+  )
+{
+  DEBUG_CODE (
+    MTRR_SETTINGS  LocalMtrrs;
+    MTRR_SETTINGS  *Mtrrs;
+    UINTN          Index;
+    UINTN          Index1;
+    UINTN          VariableMtrrCount;
+    UINT64         Base;
+    UINT64         Limit;
+    UINT64         MtrrBase;
+    UINT64         MtrrLimit;
+    UINT64         RangeBase;
+    UINT64         RangeLimit;
+    UINT64         NoRangeBase;
+    UINT64         NoRangeLimit;
+    UINT32         RegEax;
+    UINTN          MemoryType;
+    UINTN          PreviousMemoryType;
+    BOOLEAN        Found;
+
+    if (!IsMtrrSupported ()) {
+      return;
+    }
+
+    DEBUG((DEBUG_CACHE, "MTRR Settings\n"));
+    DEBUG((DEBUG_CACHE, "=============\n"));
+
+    if (MtrrSetting != NULL) {
+      Mtrrs = MtrrSetting;
+    } else {
+      MtrrGetAllMtrrs (&LocalMtrrs);
+      Mtrrs = &LocalMtrrs;
+    }
+
+    DEBUG((DEBUG_CACHE, "MTRR Default Type: %016lx\n", Mtrrs->MtrrDefType));
+    for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
+      DEBUG((DEBUG_CACHE, "Fixed MTRR[%02d]   : %016lx\n", Index, Mtrrs->Fixed.Mtrr[Index]));
+    }
+
+    VariableMtrrCount = GetVariableMtrrCount ();
+    for (Index = 0; Index < VariableMtrrCount; Index++) {
+      DEBUG((DEBUG_CACHE, "Variable MTRR[%02d]: Base=%016lx Mask=%016lx\n",
+        Index,
+        Mtrrs->Variables.Mtrr[Index].Base,
+        Mtrrs->Variables.Mtrr[Index].Mask
+        ));
+    }
+    DEBUG((DEBUG_CACHE, "\n"));
+    DEBUG((DEBUG_CACHE, "MTRR Ranges\n"));
+    DEBUG((DEBUG_CACHE, "====================================\n"));
+
+    Base = 0;
+    PreviousMemoryType = MTRR_CACHE_INVALID_TYPE;
+    for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
+      Base = mMtrrLibFixedMtrrTable[Index].BaseAddress;
+      for (Index1 = 0; Index1 < 8; Index1++) {
+      MemoryType = (UINTN)(RShiftU64 (Mtrrs->Fixed.Mtrr[Index], Index1 * 8) & 0xff);
+        if (MemoryType > CacheWriteBack) {
+          MemoryType = MTRR_CACHE_INVALID_TYPE;
+        }
+        if (MemoryType != PreviousMemoryType) {
+          if (PreviousMemoryType != MTRR_CACHE_INVALID_TYPE) {
+            DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1));
+          }
+          PreviousMemoryType = MemoryType;
+          DEBUG((DEBUG_CACHE, "%a:%016lx-", mMtrrMemoryCacheTypeShortName[MemoryType], Base));
+        }
+        Base += mMtrrLibFixedMtrrTable[Index].Length;
+      }
+    }
+    DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1));
+
+    VariableMtrrCount = GetVariableMtrrCount ();
+
+    Limit        = BIT36 - 1;
+    AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+    if (RegEax >= 0x80000008) {
+      AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
+      Limit = LShiftU64 (1, RegEax & 0xff) - 1;
+    }
+    Base = BASE_1MB;
+    PreviousMemoryType = MTRR_CACHE_INVALID_TYPE;
+    do {
+      MemoryType = MtrrGetMemoryAttributeByAddressWorker (Mtrrs, Base);
+      if (MemoryType > CacheWriteBack) {
+        MemoryType = MTRR_CACHE_INVALID_TYPE;
+      }
+
+      if (MemoryType != PreviousMemoryType) {
+        if (PreviousMemoryType != MTRR_CACHE_INVALID_TYPE) {
+          DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1));
+        }
+        PreviousMemoryType = MemoryType;
+        DEBUG((DEBUG_CACHE, "%a:%016lx-", mMtrrMemoryCacheTypeShortName[MemoryType], Base));
+      }
+
+      RangeBase    = BASE_1MB;
+      NoRangeBase  = BASE_1MB;
+      RangeLimit   = Limit;
+      NoRangeLimit = Limit;
+
+      for (Index = 0, Found = FALSE; Index < VariableMtrrCount; Index++) {
+        if ((Mtrrs->Variables.Mtrr[Index].Mask & BIT11) == 0) {
+          //
+          // If mask is not valid, then do not display range
+          //
+          continue;
+        }
+        MtrrBase  = (Mtrrs->Variables.Mtrr[Index].Base & (~(SIZE_4KB - 1)));
+        MtrrLimit = MtrrBase + ((~(Mtrrs->Variables.Mtrr[Index].Mask & (~(SIZE_4KB - 1)))) & Limit);
+
+        if (Base >= MtrrBase && Base < MtrrLimit) {
+          Found = TRUE;
+        }
+
+        if (Base >= MtrrBase && MtrrBase > RangeBase) {
+          RangeBase = MtrrBase;
+        }
+        if (Base > MtrrLimit && MtrrLimit > RangeBase) {
+          RangeBase = MtrrLimit + 1;
+        }
+        if (Base < MtrrBase && MtrrBase < RangeLimit) {
+          RangeLimit = MtrrBase - 1;
+        }
+        if (Base < MtrrLimit && MtrrLimit <= RangeLimit) {
+          RangeLimit = MtrrLimit;
+        }
+
+        if (Base > MtrrLimit && NoRangeBase < MtrrLimit) {
+          NoRangeBase = MtrrLimit + 1;
+        }
+        if (Base < MtrrBase && NoRangeLimit > MtrrBase) {
+          NoRangeLimit = MtrrBase - 1;
+        }
+      }
+
+      if (Found) {
+        Base = RangeLimit + 1;
+      } else {
+        Base = NoRangeLimit + 1;
+      }
+    } while (Base < Limit);
+    DEBUG((DEBUG_CACHE, "%016lx\n\n", Base - 1));
+  );
+}
+
+
+/**
+  This function prints all MTRRs for debugging.
+**/
+VOID
+EFIAPI
+MtrrDebugPrintAllMtrrs (
+  VOID
+  )
+{
+  MtrrDebugPrintAllMtrrsWorker (NULL);
+}
+
+
+/**
+  Worker function attempts to set the attributes for a memory range.
+
+  If MtrrSettings is not NULL, set the attributes into the input MTRR
+  settings buffer.
+  If MtrrSettings is NULL, set the attributes into MTRRs registers.
+
+  @param[in, out]  MtrrSetting       A buffer holding all MTRRs content.
+  @param[in]       BaseAddress       The physical address that is the start
+                                     address of a memory region.
+  @param[in]       Length            The size in bytes of the memory region.
+  @param[in]       Attribute         The bit mask of attributes to set for the
+                                     memory region.
+
+  @retval RETURN_SUCCESS            The attributes were set for the memory
+                                    region.
+  @retval RETURN_INVALID_PARAMETER  Length is zero.
+  @retval RETURN_UNSUPPORTED        The processor does not support one or
+                                    more bytes of the memory resource range
+                                    specified by BaseAddress and Length.
+  @retval RETURN_UNSUPPORTED        The bit mask of attributes is not support
+                                    for the memory resource range specified
+                                    by BaseAddress and Length.
+  @retval RETURN_ACCESS_DENIED      The attributes for the memory resource
+                                    range specified by BaseAddress and Length
+                                    cannot be modified.
+  @retval RETURN_OUT_OF_RESOURCES   There are not enough system resources to
+                                    modify the attributes of the memory
+                                    resource range.
+
+**/
+RETURN_STATUS
+MtrrSetMemoryAttributeWorker (
+  IN OUT MTRR_SETTINGS           *MtrrSetting,
+  IN PHYSICAL_ADDRESS            BaseAddress,
+  IN UINT64                      Length,
+  IN MTRR_MEMORY_CACHE_TYPE      Attribute
+  )
+{
+  UINT64                    TempQword;
+  RETURN_STATUS             Status;
+  UINT64                    MemoryType;
+  UINT64                    Alignment;
+  BOOLEAN                   OverLap;
+  BOOLEAN                   Positive;
+  UINT32                    MsrNum;
+  UINTN                     MtrrNumber;
+  VARIABLE_MTRR             VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];
+  UINT32                    UsedMtrr;
+  UINT64                    MtrrValidBitsMask;
+  UINT64                    MtrrValidAddressMask;
+  BOOLEAN                   OverwriteExistingMtrr;
+  UINT32                    FirmwareVariableMtrrCount;
+  MTRR_CONTEXT              MtrrContext;
+  BOOLEAN                   MtrrContextValid;
+  BOOLEAN                   FixedSettingsValid[MTRR_NUMBER_OF_FIXED_MTRR];
+  BOOLEAN                   FixedSettingsModified[MTRR_NUMBER_OF_FIXED_MTRR];
+  MTRR_FIXED_SETTINGS       WorkingFixedSettings;
+  UINT32                    VariableMtrrCount;
+  MTRR_VARIABLE_SETTINGS    OriginalVariableSettings;
+  BOOLEAN                   ProgramVariableSettings;
+  MTRR_VARIABLE_SETTINGS    WorkingVariableSettings;
+  UINT32                    Index;
+  UINT64                    ClearMask;
+  UINT64                    OrMask;
+  UINT64                    NewValue;
+  MTRR_VARIABLE_SETTINGS    *VariableSettings;
+
+  MtrrContextValid  = FALSE;
+  VariableMtrrCount = 0;
+  ZeroMem (&WorkingFixedSettings, sizeof (WorkingFixedSettings));
+  for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
+    FixedSettingsValid[Index]    = FALSE;
+    FixedSettingsModified[Index] = FALSE;
+  }
+  ProgramVariableSettings = FALSE;
+
+  if (!IsMtrrSupported ()) {
+    Status = RETURN_UNSUPPORTED;
+    goto Done;
+  }
+
+  MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask);
+
+  TempQword = 0;
+  MemoryType = (UINT64)Attribute;
+  OverwriteExistingMtrr = FALSE;
+
+  //
+  // Check for an invalid parameter
+  //
+  if (Length == 0) {
+    Status = RETURN_INVALID_PARAMETER;
+    goto Done;
+  }
+
+  if (
+       (BaseAddress & ~MtrrValidAddressMask) != 0 ||
+       (Length & ~MtrrValidAddressMask) != 0
+     ) {
+    Status = RETURN_UNSUPPORTED;
+    goto Done;
+  }
+
+  //
+  // Check if Fixed MTRR
+  //
+  Status = RETURN_SUCCESS;
+  if (BaseAddress < BASE_1MB) {
+    while ((BaseAddress < BASE_1MB) && (Length > 0) && Status == RETURN_SUCCESS) {
+      Status = ProgramFixedMtrr (MemoryType, &BaseAddress, &Length, &MsrNum, &ClearMask, &OrMask);
+      if (RETURN_ERROR (Status)) {
+        goto Done;
+      }
+      if (MtrrSetting != NULL) {
+        MtrrSetting->Fixed.Mtrr[MsrNum] = (MtrrSetting->Fixed.Mtrr[MsrNum] & ~ClearMask) | OrMask;
+        MtrrSetting->MtrrDefType |= CACHE_FIXED_MTRR_ENABLED;
+      } else {
+        if (!FixedSettingsValid[MsrNum]) {
+          WorkingFixedSettings.Mtrr[MsrNum] = MtrrRegisterRead (mMtrrLibFixedMtrrTable[MsrNum].Msr);
+          FixedSettingsValid[MsrNum] = TRUE;
+        }
+        NewValue = (WorkingFixedSettings.Mtrr[MsrNum] & ~ClearMask) | OrMask;
+        if (WorkingFixedSettings.Mtrr[MsrNum] != NewValue) {
+          WorkingFixedSettings.Mtrr[MsrNum] = NewValue;
+          FixedSettingsModified[MsrNum] = TRUE;
+        }
+      }
+    }
+
+    if (Length == 0) {
+      //
+      // A Length of 0 can only make sense for fixed MTTR ranges.
+      // Since we just handled the fixed MTRRs, we can skip the
+      // variable MTRR section.
+      //
+      goto Done;
+    }
+  }
+
+  //
+  // Since memory ranges below 1MB will be overridden by the fixed MTRRs,
+  // we can set the base to 0 to save variable MTRRs.
+  //
+  if (BaseAddress == BASE_1MB) {
+    BaseAddress = 0;
+    Length += SIZE_1MB;
+  }
+
+  //
+  // Read all variable MTRRs
+  //
+  VariableMtrrCount = GetVariableMtrrCountWorker ();
+  FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCountWorker ();
+  if (MtrrSetting != NULL) {
+    VariableSettings = &MtrrSetting->Variables;
+  } else {
+    MtrrGetVariableMtrrWorker (NULL, VariableMtrrCount, &OriginalVariableSettings);
+    CopyMem (&WorkingVariableSettings, &OriginalVariableSettings, sizeof (WorkingVariableSettings));
+    ProgramVariableSettings = TRUE;
+    VariableSettings = &WorkingVariableSettings;
+  }
+
+  //
+  // Check for overlap
+  //
+  UsedMtrr = MtrrGetMemoryAttributeInVariableMtrrWorker (
+               VariableSettings,
+               FirmwareVariableMtrrCount,
+               MtrrValidBitsMask,
+               MtrrValidAddressMask,
+               VariableMtrr
+               );
+  OverLap = CheckMemoryAttributeOverlap (
+              FirmwareVariableMtrrCount,
+              BaseAddress,
+              BaseAddress + Length - 1,
+              VariableMtrr
+              );
+  if (OverLap) {
+    Status = CombineMemoryAttribute (
+               FirmwareVariableMtrrCount,
+               MemoryType,
+               &BaseAddress,
+               &Length,
+               VariableMtrr,
+               &UsedMtrr,
+               &OverwriteExistingMtrr
+               );
+    if (RETURN_ERROR (Status)) {
+      goto Done;
+    }
+
+    if (Length == 0) {
+      //
+      // Combined successfully, invalidate the now-unused MTRRs
+      //
+      InvalidateMtrr (VariableSettings, VariableMtrrCount, VariableMtrr);
+      Status = RETURN_SUCCESS;
+      goto Done;
+    }
+  }
+
+  //
+  // The memory type is the same with the type specified by
+  // MTRR_LIB_IA32_MTRR_DEF_TYPE.
+  //
+  if ((!OverwriteExistingMtrr) && (Attribute == MtrrGetDefaultMemoryType ())) {
+    //
+    // Invalidate the now-unused MTRRs
+    //
+    InvalidateMtrr (VariableSettings, VariableMtrrCount, VariableMtrr);
+    goto Done;
+  }
+
+  Positive = GetMtrrNumberAndDirection (BaseAddress, Length, &MtrrNumber);
+
+  if ((UsedMtrr + MtrrNumber) > FirmwareVariableMtrrCount) {
+    Status = RETURN_OUT_OF_RESOURCES;
+    goto Done;
+  }
+
+  //
+  // Invalidate the now-unused MTRRs
+  //
+  InvalidateMtrr (VariableSettings, VariableMtrrCount, VariableMtrr);
+
+  //
+  // Find first unused MTRR
+  //
+  for (MsrNum = 0; MsrNum < VariableMtrrCount; MsrNum++) {
+    if ((VariableSettings->Mtrr[MsrNum].Mask & CACHE_MTRR_ENABLED) == 0) {
+      break;
+    }
+  }
+
+  if (BaseAddress != 0) {
+    do {
+      //
+      // Calculate the alignment of the base address.
+      //
+      Alignment = LShiftU64 (1, (UINTN)LowBitSet64 (BaseAddress));
+
+      if (Alignment > Length) {
+        break;
+      }
+
+      //
+      // Find unused MTRR
+      //
+      for (; MsrNum < VariableMtrrCount; MsrNum++) {
+        if ((VariableSettings->Mtrr[MsrNum].Mask & CACHE_MTRR_ENABLED) == 0) {
+          break;
+        }
+      }
+
+      ProgramVariableMtrr (
+        VariableSettings,
+        MsrNum,
+        BaseAddress,
+        Alignment,
+        MemoryType,
+        MtrrValidAddressMask
+        );
+      BaseAddress += Alignment;
+      Length -= Alignment;
+    } while (TRUE);
+
+    if (Length == 0) {
+      goto Done;
+    }
+  }
+
+  TempQword = Length;
+
+  if (!Positive) {
+    Length = Power2MaxMemory (LShiftU64 (TempQword, 1));
+
+    //
+    // Find unused MTRR
+    //
+    for (; MsrNum < VariableMtrrCount; MsrNum++) {
+      if ((VariableSettings->Mtrr[MsrNum].Mask & CACHE_MTRR_ENABLED) == 0) {
+        break;
+      }
+    }
+
+    ProgramVariableMtrr (
+      VariableSettings,
+      MsrNum,
+      BaseAddress,
+      Length,
+      MemoryType,
+      MtrrValidAddressMask
+      );
+    BaseAddress += Length;
+    TempQword   = Length - TempQword;
+    MemoryType  = MTRR_CACHE_UNCACHEABLE;
+  }
+
+  do {
+    //
+    // Find unused MTRR
+    //
+    for (; MsrNum < VariableMtrrCount; MsrNum++) {
+      if ((VariableSettings->Mtrr[MsrNum].Mask & CACHE_MTRR_ENABLED) == 0) {
+        break;
+      }
+    }
+
+    Length = Power2MaxMemory (TempQword);
+    if (!Positive) {
+      BaseAddress -= Length;
+    }
+
+    ProgramVariableMtrr (
+      VariableSettings,
+      MsrNum,
+      BaseAddress,
+      Length,
+      MemoryType,
+      MtrrValidAddressMask
+      );
+
+    if (Positive) {
+      BaseAddress += Length;
+    }
+    TempQword -= Length;
+
+  } while (TempQword > 0);
+
+Done:
+
+  //
+  // Write fixed MTRRs that have been modified
+  //
+  for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
+    if (FixedSettingsModified[Index]) {
+      if (!MtrrContextValid) {
+        PreMtrrChange (&MtrrContext);
+        MtrrContextValid = TRUE;
+      }
+      MtrrRegisterWrite (
+        mMtrrLibFixedMtrrTable[Index].Msr,
+        WorkingFixedSettings.Mtrr[Index]
+        );
+    }
+  }
+
+  //
+  // Write variable MTRRs
+  //
+  if (ProgramVariableSettings) {
+    for (Index = 0; Index < VariableMtrrCount; Index++) {
+      if (WorkingVariableSettings.Mtrr[Index].Base != OriginalVariableSettings.Mtrr[Index].Base ||
+          WorkingVariableSettings.Mtrr[Index].Mask != OriginalVariableSettings.Mtrr[Index].Mask    ) {
+        if (!MtrrContextValid) {
+          PreMtrrChange (&MtrrContext);
+          MtrrContextValid = TRUE;
+        }
+        MtrrRegisterWrite (
+          QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE0 + (Index << 1),
+          WorkingVariableSettings.Mtrr[Index].Base
+          );
+        MtrrRegisterWrite (
+          QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE0 + (Index << 1) + 1,
+          WorkingVariableSettings.Mtrr[Index].Mask
+          );
+      }
+    }
+  }
+  if (MtrrContextValid) {
+    PostMtrrChange (&MtrrContext);
+  }
+
+  DEBUG((DEBUG_CACHE, "  Status = %r\n", Status));
+  if (!RETURN_ERROR (Status)) {
+    if (MtrrSetting != NULL) {
+      MtrrSetting->MtrrDefType |= CACHE_MTRR_ENABLED;
+    }
+    MtrrDebugPrintAllMtrrsWorker (MtrrSetting);
+  }
+
+  return Status;
+}
+
+/**
+  This function attempts to set the attributes for a memory range.
+
+  @param[in]  BaseAddress        The physical address that is the start
+                                 address of a memory region.
+  @param[in]  Length             The size in bytes of the memory region.
+  @param[in]  Attributes         The bit mask of attributes to set for the
+                                 memory region.
+
+  @retval RETURN_SUCCESS            The attributes were set for the memory
+                                    region.
+  @retval RETURN_INVALID_PARAMETER  Length is zero.
+  @retval RETURN_UNSUPPORTED        The processor does not support one or
+                                    more bytes of the memory resource range
+                                    specified by BaseAddress and Length.
+  @retval RETURN_UNSUPPORTED        The bit mask of attributes is not support
+                                    for the memory resource range specified
+                                    by BaseAddress and Length.
+  @retval RETURN_ACCESS_DENIED      The attributes for the memory resource
+                                    range specified by BaseAddress and Length
+                                    cannot be modified.
+  @retval RETURN_OUT_OF_RESOURCES   There are not enough system resources to
+                                    modify the attributes of the memory
+                                    resource range.
+
+**/
+RETURN_STATUS
+EFIAPI
+MtrrSetMemoryAttribute (
+  IN PHYSICAL_ADDRESS        BaseAddress,
+  IN UINT64                  Length,
+  IN MTRR_MEMORY_CACHE_TYPE  Attribute
+  )
+{
+  DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a:%016lx-%016lx\n", mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length));
+  return MtrrSetMemoryAttributeWorker (
+           NULL,
+           BaseAddress,
+           Length,
+           Attribute
+           );
+}
+
+/**
+  This function attempts to set the attributes into MTRR setting buffer for a memory range.
+
+  @param[in, out]  MtrrSetting  MTRR setting buffer to be set.
+  @param[in]       BaseAddress  The physical address that is the start address
+                                of a memory region.
+  @param[in]       Length       The size in bytes of the memory region.
+  @param[in]       Attribute    The bit mask of attributes to set for the
+                                memory region.
+
+  @retval RETURN_SUCCESS            The attributes were set for the memory region.
+  @retval RETURN_INVALID_PARAMETER  Length is zero.
+  @retval RETURN_UNSUPPORTED        The processor does not support one or more bytes of the
+                                    memory resource range specified by BaseAddress and Length.
+  @retval RETURN_UNSUPPORTED        The bit mask of attributes is not support for the memory resource
+                                    range specified by BaseAddress and Length.
+  @retval RETURN_ACCESS_DENIED      The attributes for the memory resource range specified by
+                                    BaseAddress and Length cannot be modified.
+  @retval RETURN_OUT_OF_RESOURCES   There are not enough system resources to modify the attributes of
+                                    the memory resource range.
+
+**/
+RETURN_STATUS
+EFIAPI
+MtrrSetMemoryAttributeInMtrrSettings (
+  IN OUT MTRR_SETTINGS       *MtrrSetting,
+  IN PHYSICAL_ADDRESS        BaseAddress,
+  IN UINT64                  Length,
+  IN MTRR_MEMORY_CACHE_TYPE  Attribute
+  )
+{
+  DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttributeMtrrSettings(%p) %a:%016lx-%016lx\n", MtrrSetting, mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length));
+  return MtrrSetMemoryAttributeWorker (
+           MtrrSetting,
+           BaseAddress,
+           Length,
+           Attribute
+           );
+}
+
+/**
+  Worker function setting variable MTRRs
+
+  @param[in]  VariableSettings   A buffer to hold variable MTRRs content.
+
+**/
+VOID
+MtrrSetVariableMtrrWorker (
+  IN MTRR_VARIABLE_SETTINGS         *VariableSettings
+  )
+{
+  UINT32  Index;
+  UINT32  VariableMtrrCount;
+
+  VariableMtrrCount = GetVariableMtrrCountWorker ();
+  ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);
+
+  for (Index = 0; Index < VariableMtrrCount; Index++) {
+    MtrrRegisterWrite (
+      QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE0 + (Index << 1),
+      VariableSettings->Mtrr[Index].Base
+      );
+    MtrrRegisterWrite (
+      QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE0 + (Index << 1) + 1,
+      VariableSettings->Mtrr[Index].Mask
+      );
+  }
+}
+
+
+/**
+  This function sets variable MTRRs
+
+  @param[in]  VariableSettings   A buffer to hold variable MTRRs content.
+
+  @return The pointer of VariableSettings
+
+**/
+MTRR_VARIABLE_SETTINGS*
+EFIAPI
+MtrrSetVariableMtrr (
+  IN MTRR_VARIABLE_SETTINGS         *VariableSettings
+  )
+{
+  MTRR_CONTEXT  MtrrContext;
+
+  if (!IsMtrrSupported ()) {
+    return VariableSettings;
+  }
+
+  PreMtrrChange (&MtrrContext);
+  MtrrSetVariableMtrrWorker (VariableSettings);
+  PostMtrrChange (&MtrrContext);
+  MtrrDebugPrintAllMtrrs ();
+
+  return  VariableSettings;
+}
+
+/**
+  Worker function setting fixed MTRRs
+
+  @param[in]  FixedSettings  A buffer to hold fixed MTRRs content.
+
+**/
+VOID
+MtrrSetFixedMtrrWorker (
+  IN MTRR_FIXED_SETTINGS          *FixedSettings
+  )
+{
+  UINT32  Index;
+
+  for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
+     MtrrRegisterWrite (
+       mMtrrLibFixedMtrrTable[Index].Msr,
+       FixedSettings->Mtrr[Index]
+       );
+  }
+}
+
+
+/**
+  This function sets fixed MTRRs
+
+  @param[in]  FixedSettings  A buffer to hold fixed MTRRs content.
+
+  @retval The pointer of FixedSettings
+
+**/
+MTRR_FIXED_SETTINGS*
+EFIAPI
+MtrrSetFixedMtrr (
+  IN MTRR_FIXED_SETTINGS          *FixedSettings
+  )
+{
+  MTRR_CONTEXT  MtrrContext;
+
+  if (!IsMtrrSupported ()) {
+    return FixedSettings;
+  }
+
+  PreMtrrChange (&MtrrContext);
+  MtrrSetFixedMtrrWorker (FixedSettings);
+  PostMtrrChange (&MtrrContext);
+  MtrrDebugPrintAllMtrrs ();
+
+  return FixedSettings;
+}
+
+
+/**
+  This function gets the content in all MTRRs (variable and fixed)
+
+  @param[out]  MtrrSetting  A buffer to hold all MTRRs content.
+
+  @retval the pointer of MtrrSetting
+
+**/
+MTRR_SETTINGS *
+EFIAPI
+MtrrGetAllMtrrs (
+  OUT MTRR_SETTINGS                *MtrrSetting
+  )
+{
+  if (!IsMtrrSupported ()) {
+    return MtrrSetting;
+  }
+
+  //
+  // Get fixed MTRRs
+  //
+  MtrrGetFixedMtrrWorker (&MtrrSetting->Fixed);
+
+  //
+  // Get variable MTRRs
+  //
+  MtrrGetVariableMtrrWorker (
+    NULL,
+    GetVariableMtrrCountWorker (),
+    &MtrrSetting->Variables
+    );
+
+  //
+  // Get MTRR_DEF_TYPE value
+  //
+  MtrrSetting->MtrrDefType = MtrrRegisterRead (QUARK_NC_HOST_BRIDGE_IA32_MTRR_DEF_TYPE);
+
+  return MtrrSetting;
+}
+
+
+/**
+  This function sets all MTRRs (variable and fixed)
+
+  @param[in]  MtrrSetting  A buffer holding all MTRRs content.
+
+  @retval The pointer of MtrrSetting
+
+**/
+MTRR_SETTINGS *
+EFIAPI
+MtrrSetAllMtrrs (
+  IN MTRR_SETTINGS                *MtrrSetting
+  )
+{
+  MTRR_CONTEXT  MtrrContext;
+
+  if (!IsMtrrSupported ()) {
+    return MtrrSetting;
+  }
+
+  PreMtrrChange (&MtrrContext);
+
+  //
+  // Set fixed MTRRs
+  //
+  MtrrSetFixedMtrrWorker (&MtrrSetting->Fixed);
+
+  //
+  // Set variable MTRRs
+  //
+  MtrrSetVariableMtrrWorker (&MtrrSetting->Variables);
+
+  //
+  // Set MTRR_DEF_TYPE value
+  //
+  MtrrRegisterWrite (QUARK_NC_HOST_BRIDGE_IA32_MTRR_DEF_TYPE, MtrrSetting->MtrrDefType);
+
+  PostMtrrChangeEnableCache (&MtrrContext);
+
+  MtrrDebugPrintAllMtrrs ();
+
+  return MtrrSetting;
+}
+
+
+/**
+  Checks if MTRR is supported.
+
+  @retval TRUE  MTRR is supported.
+  @retval FALSE MTRR is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+IsMtrrSupported (
+  VOID
+  )
+{
+  UINT32  RegEax;
+
+  //
+  // Check CPUID(1).EAX[0..11] for Quark SoC
+  //
+  AsmCpuid (1, &RegEax, NULL, NULL, NULL);
+  if ((RegEax & 0xfff) == QUARK_SOC_CPUID_FAMILY_MODEL_STEPPING) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.inf b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.inf
new file mode 100644
index 0000000000..72e83510d5
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.inf
@@ -0,0 +1,42 @@
+## @file
+#  MTRR library provides APIs for MTRR operation.
+#
+#  Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = MtrrLib
+  MODULE_UNI_FILE                = MtrrLib.uni
+  FILE_GUID                      = 6826b408-f4f3-47ee-917f-af7047f9d937
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = MtrrLib
+
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  MtrrLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  BaseLib
+  CpuLib
+  DebugLib
+  QNCAccessLib
+
+[Pcd]
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuNumberOfReservedVariableMtrrs   ## SOMETIMES_CONSUMES
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.uni b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.uni
new file mode 100644
index 0000000000..b564c8af74
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.uni
@@ -0,0 +1,18 @@
+// /** @file
+// MtrrLib Module Localized Abstract and Description Content
+//
+// Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT
+#language en-US
+"MTRR library provides APIs for MTRR operation"
+
+#string STR_MODULE_DESCRIPTION
+#language en-US
+"MTRR library provides APIs for MTRR operation."
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/BaseAccess.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/BaseAccess.c
new file mode 100644
index 0000000000..da364c7b7c
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/BaseAccess.c
@@ -0,0 +1,28 @@
+/** @file
+Base Lib function for QNC internal network access.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <Uefi.h>
+
+/**
+  Gets the base address of PCI Express for Quark North Cluster.
+
+  @return The base address of PCI Express for Quark North Cluster.
+
+**/
+UINTN
+EFIAPI
+QncGetPciExpressBaseAddress (
+  VOID
+  )
+{
+  return (UINTN) PcdGet64(PcdPciExpressBaseAddress);
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/QNCAccessLib.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/QNCAccessLib.c
new file mode 100644
index 0000000000..b9b1e258a0
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/QNCAccessLib.c
@@ -0,0 +1,327 @@
+/** @file
+Common Lib function for QNC internal network access.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <Uefi.h>
+
+#include <IntelQNCRegs.h>
+#include <Library/QNCAccessLib.h>
+#include <Library/DebugLib.h>
+#include <IndustryStandard/Pci22.h>
+
+UINT32
+EFIAPI
+QNCPortRead(
+  UINT8 Port,
+  UINT32 RegAddress
+  )
+{
+  McD0PciCfg32 (QNC_ACCESS_PORT_MEA) = (RegAddress & 0xFFFFFF00);
+  McD0PciCfg32 (QNC_ACCESS_PORT_MCR) = MESSAGE_READ_DW (Port, RegAddress);
+  return McD0PciCfg32 (QNC_ACCESS_PORT_MDR);
+}
+
+VOID
+EFIAPI
+QNCPortWrite (
+  UINT8 Port,
+  UINT32 RegAddress,
+  UINT32 WriteValue
+  )
+{
+  McD0PciCfg32 (QNC_ACCESS_PORT_MDR) = WriteValue;
+  McD0PciCfg32 (QNC_ACCESS_PORT_MEA) = (RegAddress & 0xFFFFFF00);
+  McD0PciCfg32 (QNC_ACCESS_PORT_MCR) = MESSAGE_WRITE_DW (Port, RegAddress);
+}
+
+UINT32
+EFIAPI
+QNCAltPortRead (
+  UINT8 Port,
+  UINT32 RegAddress
+  )
+{
+  McD0PciCfg32 (QNC_ACCESS_PORT_MEA) = (RegAddress & 0xFFFFFF00);
+  McD0PciCfg32 (QNC_ACCESS_PORT_MCR) = ALT_MESSAGE_READ_DW (Port, RegAddress);
+  return McD0PciCfg32 (QNC_ACCESS_PORT_MDR);
+}
+
+VOID
+EFIAPI
+QNCAltPortWrite (
+  UINT8 Port,
+  UINT32 RegAddress,
+  UINT32 WriteValue
+  )
+{
+  McD0PciCfg32 (QNC_ACCESS_PORT_MDR) = WriteValue;
+  McD0PciCfg32 (QNC_ACCESS_PORT_MEA) = (RegAddress & 0xFFFFFF00);
+  McD0PciCfg32 (QNC_ACCESS_PORT_MCR) = ALT_MESSAGE_WRITE_DW (Port, RegAddress);
+}
+
+UINT32
+EFIAPI
+QNCPortIORead(
+  UINT8 Port,
+  UINT32 RegAddress
+  )
+{
+  McD0PciCfg32 (QNC_ACCESS_PORT_MEA) = (RegAddress & 0xFFFFFF00);
+  McD0PciCfg32 (QNC_ACCESS_PORT_MCR) = MESSAGE_IO_READ_DW (Port, RegAddress);
+  return McD0PciCfg32 (QNC_ACCESS_PORT_MDR);
+}
+
+VOID
+EFIAPI
+QNCPortIOWrite (
+  UINT8 Port,
+  UINT32 RegAddress,
+  UINT32 WriteValue
+  )
+{
+  McD0PciCfg32 (QNC_ACCESS_PORT_MDR) = WriteValue;
+  McD0PciCfg32 (QNC_ACCESS_PORT_MEA) = (RegAddress & 0xFFFFFF00);
+  McD0PciCfg32 (QNC_ACCESS_PORT_MCR) = MESSAGE_IO_WRITE_DW (Port, RegAddress);
+}
+
+RETURN_STATUS
+EFIAPI
+QNCMmIoWrite (
+  UINT32             MmIoAddress,
+  QNC_MEM_IO_WIDTH    Width,
+  UINT32             DataNumber,
+  VOID               *pData
+  )
+/*++
+
+Routine Description:
+
+  This is for the special consideration for QNC MMIO write, as required by FWG, a reading must be performed after MMIO writing
+to ensure the expected write is processed and data is flushed into chipset
+
+Arguments:
+
+  Row -- row number to be cleared ( start from 1 )
+
+Returns:
+
+  EFI_SUCCESS
+
+--*/
+{
+  RETURN_STATUS  Status;
+  UINTN          Index;
+
+  Status = RETURN_SUCCESS;
+
+  for (Index =0; Index < DataNumber; Index++) {
+    switch (Width) {
+      case QNCMmioWidthUint8:
+        QNCMmio8 (MmIoAddress, 0) = ((UINT8 *)pData)[Index];
+        if (QNCMmio8 (MmIoAddress, 0) != ((UINT8*)pData)[Index]) {
+          Status = RETURN_DEVICE_ERROR;
+          break;
+        }
+        break;
+
+      case QNCMmioWidthUint16:
+        QNCMmio16 (MmIoAddress, 0) = ((UINT16 *)pData)[Index];
+        if (QNCMmio16 (MmIoAddress, 0) != ((UINT16 *)pData)[Index]) {
+          Status = RETURN_DEVICE_ERROR;
+          break;
+        }
+        break;
+
+      case QNCMmioWidthUint32:
+        QNCMmio32 (MmIoAddress, 0) = ((UINT32 *)pData)[Index];
+        if (QNCMmio32 (MmIoAddress, 0) != ((UINT32 *)pData)[Index]) {
+          Status = RETURN_DEVICE_ERROR;
+          break;
+        }
+        break;
+
+      case QNCMmioWidthUint64:
+        QNCMmio64 (MmIoAddress, 0) = ((UINT64 *)pData)[Index];
+        if (QNCMmio64 (MmIoAddress, 0) != ((UINT64 *)pData)[Index]) {
+          Status = RETURN_DEVICE_ERROR;
+          break;
+        }
+        break;
+
+      default:
+        break;
+    }
+  }
+
+  return Status;
+}
+
+UINT32
+EFIAPI
+QncHsmmcRead (
+  VOID
+  )
+{
+  return QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HSMMC);
+}
+
+VOID
+EFIAPI
+QncHsmmcWrite (
+  UINT32 WriteValue
+  )
+{
+  UINT16  DeviceId;
+  UINT32  Data32;
+
+  //
+  // Check what Soc we are running on (read Host bridge DeviceId)
+  //
+  DeviceId = QNCMmPci16(0, MC_BUS, MC_DEV, MC_FUN, PCI_DEVICE_ID_OFFSET);
+
+  if (DeviceId == QUARK2_MC_DEVICE_ID) {
+    //
+    // Disable HSMMC configuration
+    //
+    Data32 = QncHsmmcRead ();
+    Data32 &= ~SMM_CTL_EN;
+    QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HSMMC, Data32);
+
+    //
+    // Validate HSMMC configuration is disabled
+    //
+    Data32 = QncHsmmcRead ();
+    ASSERT((Data32 & SMM_CTL_EN) == 0);
+
+    //
+    // Enable HSMMC configuration
+    //
+    WriteValue |= SMM_CTL_EN;
+  }
+
+  //
+  // Write the register value
+  //
+  QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HSMMC, WriteValue);
+
+  if (DeviceId == QUARK2_MC_DEVICE_ID) {
+    //
+    // Validate HSMMC configuration is enabled
+    //
+    Data32 = QncHsmmcRead ();
+    ASSERT((Data32 & SMM_CTL_EN) != 0);
+  }
+}
+
+VOID
+EFIAPI
+QncImrWrite (
+  UINT32 ImrBaseOffset,
+  UINT32 ImrLow,
+  UINT32 ImrHigh,
+  UINT32 ImrReadMask,
+  UINT32 ImrWriteMask
+  )
+{
+  UINT16  DeviceId;
+  UINT32  Data32;
+
+  //
+  // Check what Soc we are running on (read Host bridge DeviceId)
+  //
+  DeviceId = QNCMmPci16(0, MC_BUS, MC_DEV, MC_FUN, PCI_DEVICE_ID_OFFSET);
+
+  //
+  // Disable IMR protection
+  //
+  if (DeviceId == QUARK2_MC_DEVICE_ID) {
+    //
+    // Disable IMR protection
+    //
+    Data32 = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, ImrBaseOffset+QUARK_NC_MEMORY_MANAGER_IMRXL);
+    Data32 &= ~IMR_EN;
+    QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, ImrBaseOffset+QUARK_NC_MEMORY_MANAGER_IMRXL, Data32);
+
+    //
+    // Validate IMR protection is disabled
+    //
+    Data32 = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, ImrBaseOffset+QUARK_NC_MEMORY_MANAGER_IMRXL);
+    ASSERT((Data32 & IMR_EN) == 0);
+
+    //
+    // Update the IMR (IMRXL must be last as it may enable IMR violation checking)
+    //
+    QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, ImrBaseOffset+QUARK_NC_MEMORY_MANAGER_IMRXRM, ImrReadMask);
+    QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, ImrBaseOffset+QUARK_NC_MEMORY_MANAGER_IMRXWM, ImrWriteMask);
+    QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, ImrBaseOffset+QUARK_NC_MEMORY_MANAGER_IMRXH, ImrHigh);
+    QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, ImrBaseOffset+QUARK_NC_MEMORY_MANAGER_IMRXL, ImrLow);
+
+    //
+    // Validate IMR protection is enabled/disabled
+    //
+    Data32 = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, ImrBaseOffset+QUARK_NC_MEMORY_MANAGER_IMRXL);
+    ASSERT((Data32 & IMR_EN) == (ImrLow & IMR_EN));
+  } else {
+    //
+    // Disable IMR protection (allow all access)
+    //
+    QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, ImrBaseOffset+QUARK_NC_MEMORY_MANAGER_IMRXRM, (UINT32)IMRX_ALL_ACCESS);
+    QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, ImrBaseOffset+QUARK_NC_MEMORY_MANAGER_IMRXWM, (UINT32)IMRX_ALL_ACCESS);
+
+    //
+    // Update the IMR (IMRXRM/IMRXWM must be last as they restrict IMR access)
+    //
+    QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, ImrBaseOffset+QUARK_NC_MEMORY_MANAGER_IMRXL, (ImrLow & ~IMR_EN));
+    QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, ImrBaseOffset+QUARK_NC_MEMORY_MANAGER_IMRXH, ImrHigh);
+    QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, ImrBaseOffset+QUARK_NC_MEMORY_MANAGER_IMRXRM, ImrReadMask);
+    QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, ImrBaseOffset+QUARK_NC_MEMORY_MANAGER_IMRXWM, ImrWriteMask);
+  }
+}
+
+VOID
+EFIAPI
+QncIClkAndThenOr (
+  UINT32 RegAddress,
+  UINT32 AndValue,
+  UINT32 OrValue
+  )
+{
+  UINT32 RegValue;
+  //
+  // Whenever an iCLK SB register (Endpoint 32h) is being programmed the access
+  // should always consist of a READ from the address followed by 2 identical
+  // WRITEs to that address.
+  //
+  RegValue = QNCAltPortRead (QUARK_ICLK_SB_PORT_ID, RegAddress);
+  RegValue &= AndValue;
+  RegValue |= OrValue;
+  QNCAltPortWrite (QUARK_ICLK_SB_PORT_ID, RegAddress, RegValue);
+  QNCAltPortWrite (QUARK_ICLK_SB_PORT_ID, RegAddress, RegValue);
+}
+
+VOID
+EFIAPI
+QncIClkOr (
+  UINT32 RegAddress,
+  UINT32 OrValue
+  )
+{
+  UINT32 RegValue;
+  //
+  // Whenever an iCLK SB register (Endpoint 32h) is being programmed the access
+  // should always consist of a READ from the address followed by 2 identical
+  // WRITEs to that address.
+  //
+  RegValue = QNCAltPortRead (QUARK_ICLK_SB_PORT_ID, RegAddress);
+  RegValue |= OrValue;
+  QNCAltPortWrite (QUARK_ICLK_SB_PORT_ID, RegAddress, RegValue);
+  QNCAltPortWrite (QUARK_ICLK_SB_PORT_ID, RegAddress, RegValue);
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/QNCAccessLib.inf b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/QNCAccessLib.inf
new file mode 100644
index 0000000000..5489c1aa46
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/QNCAccessLib.inf
@@ -0,0 +1,37 @@
+## @file
+# Base Intel QNC Library Instance
+#
+# Intel QNC internal network access Library Instance
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = QNCAccessLib
+  FILE_GUID                      = CC13B9FB-DAF5-4b42-907F-122216787C05
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = QNCAccessLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  QNCAccessLib.c
+  BaseAccess.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  DebugLib
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/RuntimeAccess.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/RuntimeAccess.c
new file mode 100644
index 0000000000..65af27c305
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/RuntimeAccess.c
@@ -0,0 +1,142 @@
+/** @file
+Runtime Lib function for QNC internal network access.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include <PiDxe.h>
+
+#include <Guid/EventGroup.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Library/QNCAccessLib.h>
+
+///
+/// Set Virtual Address Map Event
+///
+EFI_EVENT                               mDxeRuntimeQncAccessLibVirtualNotifyEvent = NULL;
+
+///
+/// Module global that contains the base physical address of the PCI Express MMIO range.
+///
+UINTN                                   mDxeRuntimeQncAccessLibPciExpressBaseAddress = 0;
+
+/**
+  Convert the physical PCI Express MMIO address to a virtual address.
+
+  @param[in]    Event   The event that is being processed.
+  @param[in]    Context The Event Context.
+**/
+VOID
+EFIAPI
+DxeRuntimeQncAccessLibVirtualNotify (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  EFI_STATUS                       Status;
+
+  //
+  // Convert the physical PCI Express MMIO address to a virtual address.
+  //
+  Status = EfiConvertPointer (0, (VOID **) &mDxeRuntimeQncAccessLibPciExpressBaseAddress);
+
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+  The constructor function to setup globals and goto virtual mode notify.
+
+  @param  ImageHandle   The firmware allocated handle for the EFI image.
+  @param  SystemTable   A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS   The constructor completed successfully.
+  @retval Other value   The constructor did not complete successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+DxeRuntimeQncAccessLibConstructor (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // Cache the physical address of the PCI Express MMIO range into a module global variable
+  //
+  mDxeRuntimeQncAccessLibPciExpressBaseAddress = (UINTN) PcdGet64(PcdPciExpressBaseAddress);
+
+  //
+  // Register SetVirtualAddressMap () notify function
+  //
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  DxeRuntimeQncAccessLibVirtualNotify,
+                  NULL,
+                  &gEfiEventVirtualAddressChangeGuid,
+                  &mDxeRuntimeQncAccessLibVirtualNotifyEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+/**
+  The destructor function frees any allocated buffers and closes the Set Virtual
+  Address Map event.
+
+  @param  ImageHandle   The firmware allocated handle for the EFI image.
+  @param  SystemTable   A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS   The destructor completed successfully.
+  @retval Other value   The destructor did not complete successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+DxeRuntimeQncAccessLibDestructor (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // Close the Set Virtual Address Map event
+  //
+  Status = gBS->CloseEvent (mDxeRuntimeQncAccessLibVirtualNotifyEvent);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+/**
+  Gets the base address of PCI Express for Quark North Cluster.
+
+  @return The base address of PCI Express for Quark North Cluster.
+
+**/
+UINTN
+EFIAPI
+QncGetPciExpressBaseAddress (
+  VOID
+  )
+{
+  //
+  // If system goes to virtual mode then virtual notify callback will update
+  // mDxeRuntimeQncAccessLibPciExpressBaseAddress with virtual address of
+  // PCIe memory base.
+  //
+  return mDxeRuntimeQncAccessLibPciExpressBaseAddress;
+}
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/RuntimeQNCAccessLib.inf b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/RuntimeQNCAccessLib.inf
new file mode 100644
index 0000000000..0e6aa4cd97
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/RuntimeQNCAccessLib.inf
@@ -0,0 +1,43 @@
+## @file
+# DXE Runtime Intel QNC Library Instance
+#
+# Intel QNC internal network access Library Instance.
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = RuntimeQNCAccessLib
+  FILE_GUID                      = E6B51D93-E4C8-4425-9FA9-9DED814220F9
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = QNCAccessLib|DXE_RUNTIME_DRIVER
+  CONSTRUCTOR                    = DxeRuntimeQncAccessLibConstructor
+  DESTRUCTOR                     = DxeRuntimeQncAccessLibDestructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32
+#
+
+[Sources]
+  QNCAccessLib.c
+  RuntimeAccess.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  PcdLib
+  UefiBootServicesTableLib
+  UefiRuntimeLib
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCSmmLib/QNCSmmLib.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCSmmLib/QNCSmmLib.c
new file mode 100644
index 0000000000..d6bba0bc1c
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCSmmLib/QNCSmmLib.c
@@ -0,0 +1,313 @@
+/** @file
+QNC Smm Library Services that implements SMM Region access, S/W SMI generation and detection.
+
+Copyright (c) 2013-2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include <Base.h>
+#include <IntelQNCRegs.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/QNCAccessLib.h>
+
+#define BOOT_SERVICE_SOFTWARE_SMI_DATA          0
+#define RUNTIME_SOFTWARE_SMI_DATA               1
+
+/**
+  Triggers a run time or boot time SMI.
+
+  This function triggers a software SMM interrupt and set the APMC status with an 8-bit Data.
+
+  @param  Data                 The value to set the APMC status.
+
+**/
+VOID
+InternalTriggerSmi (
+  IN UINT8                     Data
+  )
+{
+  UINT16        GPE0BLK_Base;
+  UINT32        NewValue;
+
+  //
+  // Get GPE0BLK_Base
+  //
+  GPE0BLK_Base = (UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF);
+
+
+  //
+  // Enable APM SMI
+  //
+  IoOr32 ((GPE0BLK_Base + R_QNC_GPE0BLK_SMIE), B_QNC_GPE0BLK_SMIE_APM);
+
+  //
+  // Enable SMI globally
+  //
+  NewValue = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);
+  NewValue |= SMI_EN;
+  QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, NewValue);
+
+  //
+  // Set APM_STS
+  //
+  IoWrite8 (PcdGet16 (PcdSmmDataPort), Data);
+
+  //
+  // Generate the APM SMI
+  //
+  IoWrite8 (PcdGet16 (PcdSmmActivationPort), PcdGet8 (PcdSmmActivationData));
+
+  //
+  // Clear the APM SMI Status Bit
+  //
+  IoWrite32 ((GPE0BLK_Base + R_QNC_GPE0BLK_SMIS), B_QNC_GPE0BLK_SMIS_APM);
+
+  //
+  // Set the EOS Bit
+  //
+  IoOr32 ((GPE0BLK_Base + R_QNC_GPE0BLK_SMIS), B_QNC_GPE0BLK_SMIS_EOS);
+}
+
+
+/**
+  Triggers an SMI at boot time.
+
+  This function triggers a software SMM interrupt at boot time.
+
+**/
+VOID
+EFIAPI
+TriggerBootServiceSoftwareSmi (
+  VOID
+  )
+{
+  InternalTriggerSmi (BOOT_SERVICE_SOFTWARE_SMI_DATA);
+}
+
+
+/**
+  Triggers an SMI at run time.
+
+  This function triggers a software SMM interrupt at run time.
+
+**/
+VOID
+EFIAPI
+TriggerRuntimeSoftwareSmi (
+  VOID
+  )
+{
+  InternalTriggerSmi (RUNTIME_SOFTWARE_SMI_DATA);
+}
+
+
+/**
+  Gets the software SMI data.
+
+  This function tests if a software SMM interrupt happens. If a software SMI happens,
+  it retrieves the SMM data and returns it as a non-negative value; otherwise a negative
+  value is returned.
+
+  @return Data                 The data retrieved from SMM data port in case of a software SMI;
+                               otherwise a negative value.
+
+**/
+INTN
+InternalGetSwSmiData (
+  VOID
+  )
+{
+  UINT8                        SmiStatus;
+  UINT8                        Data;
+
+  SmiStatus = IoRead8 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_SMIS);
+  if (((SmiStatus & B_QNC_GPE0BLK_SMIS_APM) != 0) &&
+       (IoRead8 (PcdGet16 (PcdSmmActivationPort)) == PcdGet8 (PcdSmmActivationData))) {
+    Data = IoRead8 (PcdGet16 (PcdSmmDataPort));
+    return (INTN)(UINTN)Data;
+  }
+
+  return -1;
+}
+
+
+/**
+  Test if a boot time software SMI happened.
+
+  This function tests if a software SMM interrupt happened. If a software SMM interrupt happened and
+  it was triggered at boot time, it returns TRUE. Otherwise, it returns FALSE.
+
+  @retval TRUE   A software SMI triggered at boot time happened.
+  @retval FLASE  No software SMI happened or the software SMI was triggered at run time.
+
+**/
+BOOLEAN
+EFIAPI
+IsBootServiceSoftwareSmi (
+  VOID
+  )
+{
+  return (BOOLEAN) (InternalGetSwSmiData () == BOOT_SERVICE_SOFTWARE_SMI_DATA);
+}
+
+
+/**
+  Test if a run time software SMI happened.
+
+  This function tests if a software SMM interrupt happened. If a software SMM interrupt happened and
+  it was triggered at run time, it returns TRUE. Otherwise, it returns FALSE.
+
+  @retval TRUE   A software SMI triggered at run time happened.
+  @retval FLASE  No software SMI happened or the software SMI was triggered at boot time.
+
+**/
+BOOLEAN
+EFIAPI
+IsRuntimeSoftwareSmi (
+  VOID
+  )
+{
+  return (BOOLEAN) (InternalGetSwSmiData () == RUNTIME_SOFTWARE_SMI_DATA);
+}
+
+
+
+/**
+
+  Clear APM SMI Status Bit; Set the EOS bit.
+
+**/
+VOID
+EFIAPI
+ClearSmi (
+  VOID
+  )
+{
+
+  UINT16                       GPE0BLK_Base;
+
+  //
+  // Get GpeBase
+  //
+  GPE0BLK_Base = (UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF);
+
+  //
+  // Clear the APM SMI Status Bit
+  //
+  IoOr16 (GPE0BLK_Base + R_QNC_GPE0BLK_SMIS, B_QNC_GPE0BLK_SMIS_APM);
+
+  //
+  // Set the EOS Bit
+  //
+  IoOr32 (GPE0BLK_Base + R_QNC_GPE0BLK_SMIS, B_QNC_GPE0BLK_SMIS_EOS);
+}
+
+/**
+  This routine is the chipset code that accepts a request to "open" a region of SMRAM.
+  The region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
+  The use of "open" means that the memory is visible from all boot-service
+  and SMM agents.
+
+  @retval FALSE  Cannot open a locked SMRAM region
+  @retval TRUE   Success to open SMRAM region.
+**/
+BOOLEAN
+EFIAPI
+QNCOpenSmramRegion (
+  VOID
+  )
+{
+  UINT32                     Smram;
+
+  // Read the SMRAM register
+  Smram = QncHsmmcRead ();
+
+  //
+  //  Is the platform locked?
+  //
+  if (Smram & SMM_LOCKED) {
+    // Cannot Open a locked region
+    DEBUG ((EFI_D_WARN, "Cannot open a locked SMRAM region\n"));
+    return FALSE;
+  }
+
+  //
+  // Open all SMRAM regions for Host access only
+  //
+  Smram |= (SMM_WRITE_OPEN | SMM_READ_OPEN);  // Open for Host.
+  Smram &= ~(NON_HOST_SMM_WR_OPEN | NON_HOST_SMM_RD_OPEN);  // Not for others.
+
+  //
+  // Write the SMRAM register
+  //
+  QncHsmmcWrite (Smram);
+
+  return TRUE;
+}
+
+/**
+  This routine is the chipset code that accepts a request to "close" a region of SMRAM.
+  The region could be legacy AB or TSEG near top of physical memory.
+  The use of "close" means that the memory is only visible from SMM agents,
+  not from BS or RT code.
+
+  @retval FALSE  Cannot open a locked SMRAM region
+  @retval TRUE   Success to open SMRAM region.
+**/
+BOOLEAN
+EFIAPI
+QNCCloseSmramRegion (
+  VOID
+  )
+{
+  UINT32                    Smram;
+
+  // Read the SMRAM register.
+  Smram = QncHsmmcRead ();
+
+  //
+  //  Is the platform locked?
+  //
+  if(Smram & SMM_LOCKED) {
+    // Cannot Open a locked region
+    DEBUG ((EFI_D_WARN, "Cannot close a locked SMRAM region\n"));
+    return FALSE;
+  }
+
+  Smram &= (~(SMM_WRITE_OPEN | SMM_READ_OPEN | NON_HOST_SMM_WR_OPEN | NON_HOST_SMM_RD_OPEN));
+
+  QncHsmmcWrite (Smram);
+
+  return TRUE;
+}
+
+/**
+  This routine is the chipset code that accepts a request to "lock" SMRAM.
+  The region could be legacy AB or TSEG near top of physical memory.
+  The use of "lock" means that the memory can no longer be opened
+  to BS state.
+**/
+VOID
+EFIAPI
+QNCLockSmramRegion (
+  VOID
+  )
+{
+  UINT32                    Smram;
+
+  // Read the SMRAM register.
+  Smram = QncHsmmcRead ();
+  if(Smram & SMM_LOCKED) {
+    DEBUG ((EFI_D_WARN, "SMRAM region already locked!\n"));
+  }
+  Smram |= SMM_LOCKED;
+
+  QncHsmmcWrite (Smram);
+
+  return;
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCSmmLib/QNCSmmLib.inf b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCSmmLib/QNCSmmLib.inf
new file mode 100644
index 0000000000..5383580f3b
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCSmmLib/QNCSmmLib.inf
@@ -0,0 +1,44 @@
+## @file
+# Component description file for Intel QNC SMM Library.
+#
+# QNC SMM Library that layers on top of the I/O Library to directly
+# access SMM power management registers.
+#
+# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = QNCSmmLib
+  FILE_GUID                      = 8A9A62F5-758B-4965-A28B-0AAC292FBD89
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SmmLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  QNCSmmLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  IoLib
+  DebugLib
+  QNCAccessLib
+
+[Pcd]
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdGpe0blkIoBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdSmmDataPort
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdSmmActivationPort
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdSmmActivationData
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/ResetSystemLib.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/ResetSystemLib.c
new file mode 100644
index 0000000000..d730f62ce0
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/ResetSystemLib.c
@@ -0,0 +1,379 @@
+/** @file
+System reset Library Services.  This library class provides a set of
+methods to reset whole system with manipulate QNC.
+
+Copyright (c) 2013-2019 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <IntelQNCBase.h>
+#include <QNCAccess.h>
+
+#include <Uefi/UefiBaseType.h>
+
+#include <Library/ResetSystemLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/CpuLib.h>
+#include <Library/QNCAccessLib.h>
+
+//
+// Amount of time (seconds) before RTC alarm fires
+// This must be < BCD_BASE
+//
+#define PLATFORM_WAKE_SECONDS_BUFFER 0x06
+
+//
+// RTC 'seconds' above which we will not read to avoid potential rollover
+//
+#define PLATFORM_RTC_ROLLOVER_LIMIT 0x47
+
+//
+// BCD is base 10
+//
+#define BCD_BASE 0x0A
+
+#define PCAT_RTC_ADDRESS_REGISTER 0x70
+#define PCAT_RTC_DATA_REGISTER    0x71
+
+//
+// Dallas DS12C887 Real Time Clock
+//
+#define RTC_ADDRESS_SECONDS           0   // R/W  Range 0..59
+#define RTC_ADDRESS_SECONDS_ALARM     1   // R/W  Range 0..59
+#define RTC_ADDRESS_MINUTES           2   // R/W  Range 0..59
+#define RTC_ADDRESS_MINUTES_ALARM     3   // R/W  Range 0..59
+#define RTC_ADDRESS_HOURS             4   // R/W  Range 1..12 or 0..23 Bit 7 is AM/PM
+#define RTC_ADDRESS_HOURS_ALARM       5   // R/W  Range 1..12 or 0..23 Bit 7 is AM/PM
+#define RTC_ADDRESS_DAY_OF_THE_WEEK   6   // R/W  Range 1..7
+#define RTC_ADDRESS_DAY_OF_THE_MONTH  7   // R/W  Range 1..31
+#define RTC_ADDRESS_MONTH             8   // R/W  Range 1..12
+#define RTC_ADDRESS_YEAR              9   // R/W  Range 0..99
+#define RTC_ADDRESS_REGISTER_A        10  // R/W[0..6]  R0[7]
+#define RTC_ADDRESS_REGISTER_B        11  // R/W
+#define RTC_ADDRESS_REGISTER_C        12  // RO
+#define RTC_ADDRESS_REGISTER_D        13  // RO
+#define RTC_ADDRESS_CENTURY           50  // R/W  Range 19..20 Bit 8 is R/W
+
+/**
+  Wait for an RTC update to happen
+
+**/
+VOID
+EFIAPI
+WaitForRTCUpdate (
+VOID
+)
+{
+  UINT8   Data8;
+
+  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_A);
+  Data8 = IoRead8 (PCAT_RTC_DATA_REGISTER);
+  if ((Data8 & BIT7) == BIT7) {
+    while ((Data8 & BIT7) == BIT7) {
+      IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_A);
+      Data8 = IoRead8 (PCAT_RTC_DATA_REGISTER);
+    }
+
+  } else {
+    while ((Data8 & BIT7) == 0) {
+      IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_A);
+      Data8 = IoRead8 (PCAT_RTC_DATA_REGISTER);
+    }
+
+    while ((Data8 & BIT7) == BIT7) {
+      IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_A);
+      Data8 = IoRead8 (PCAT_RTC_DATA_REGISTER);
+    }
+  }
+}
+
+/**
+  Calling this function causes a system-wide reset. This sets
+  all circuitry within the system to its initial state. This type of reset
+  is asynchronous to system operation and operates without regard to
+  cycle boundaries.
+
+  System reset should not return, if it returns, it means the system does
+  not support cold reset.
+**/
+VOID
+EFIAPI
+ResetCold (
+VOID
+)
+{
+  //
+  // Reference to QuarkNcSocId BWG
+  // Setting bit 1 will generate a warm reset, driving only RSTRDY# low
+  //
+  IoWrite8 (RST_CNT, B_RST_CNT_COLD_RST);
+}
+
+/**
+  Calling this function causes a system-wide initialization. The processors
+  are set to their initial state, and pending cycles are not corrupted.
+
+  System reset should not return, if it returns, it means the system does
+  not support warm reset.
+**/
+VOID
+EFIAPI
+ResetWarm (
+VOID
+)
+{
+  //
+  // Reference to QuarkNcSocId BWG
+  // Setting bit 1 will generate a warm reset, driving only RSTRDY# low
+  //
+  IoWrite8 (RST_CNT, B_RST_CNT_WARM_RST);
+}
+
+/**
+  Calling this function causes the system to enter a power state equivalent
+  to the ACPI G2/S5 or G3 states.
+
+  System shutdown should not return, if it returns, it means the system does
+  not support shut down reset.
+**/
+VOID
+EFIAPI
+ResetShutdown (
+VOID
+)
+{
+  //
+  // Reference to QuarkNcSocId BWG
+  //  Disable RTC Alarm :  (RTC Enable at PM1BLK + 02h[10]))
+  //
+  IoWrite16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1E, 0);
+
+  //
+  // Firstly, GPE0_EN should be disabled to
+  // avoid any GPI waking up the system from S5
+  //
+  IoWrite32 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_GPE0E, 0);
+
+  //
+  // Reference to QuarkNcSocId BWG
+  //  Disable Resume Well GPIO :  (GPIO bits in GPIOBASE + 34h[8:0])
+  //
+  IoWrite32 (PcdGet16 (PcdGbaIoBaseAddress) + R_QNC_GPIO_RGGPE_RESUME_WELL, 0);
+
+  //
+  // No power button status bit to clear for our platform, go to next step.
+  //
+
+  //
+  // Finally, transform system into S5 sleep state
+  //
+  IoAndThenOr32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C, 0xffffc3ff, B_QNC_PM1BLK_PM1C_SLPEN | V_S5);
+}
+
+/**
+  Calling this function causes the system to enter a power state for capsule
+  update.
+
+  Reset update should not return, if it returns, it means the system does
+  not support capsule update.
+
+**/
+VOID
+EFIAPI
+EnterS3WithImmediateWake (
+VOID
+)
+{
+  UINT8     Data8;
+  UINT16    Data16;
+  UINT32    Data32;
+  UINTN     Eflags;
+  UINTN     RegCr0;
+  EFI_TIME  EfiTime;
+  UINT32    SmiEnSave;
+
+  Eflags  = AsmReadEflags ();
+  if ( (Eflags & 0x200) ) {
+     DisableInterrupts ();
+  }
+
+  //
+  //  Write all cache data to memory because processor will lost power
+  //
+  AsmWbinvd();
+  RegCr0 = AsmReadCr0();
+  AsmWriteCr0 (RegCr0 | 0x060000000);
+
+  SmiEnSave = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);
+  QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, (SmiEnSave & ~SMI_EN));
+
+  //
+  // Pogram RTC alarm for immediate WAKE
+  //
+
+  //
+  // Disable SMI sources
+  //
+  IoWrite16 (PcdGet16 (PcdGpe0blkIoBaseAddress) + R_QNC_GPE0BLK_SMIE, 0);
+
+  //
+  // Disable RTC alarm interrupt
+  //
+  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_B);
+  Data8 = IoRead8 (PCAT_RTC_DATA_REGISTER);
+  IoWrite8 (PCAT_RTC_DATA_REGISTER, (Data8 & ~BIT5));
+
+  //
+  // Clear RTC alarm if already set
+  //
+  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_C);
+  Data8 = IoRead8 (PCAT_RTC_DATA_REGISTER);              // Read clears alarm status
+
+  //
+  // Disable all WAKE events
+  //
+  IoWrite16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1E, B_QNC_PM1BLK_PM1E_PWAKED);
+
+  //
+  // Clear all WAKE status bits
+  //
+  IoWrite16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1S, B_QNC_PM1BLK_PM1S_ALL);
+
+  //
+  // Avoid RTC rollover
+  //
+  do {
+    WaitForRTCUpdate();
+    IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_SECONDS);
+    EfiTime.Second = IoRead8 (PCAT_RTC_DATA_REGISTER);
+  } while (EfiTime.Second > PLATFORM_RTC_ROLLOVER_LIMIT);
+
+  //
+  // Read RTC time
+  //
+  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_HOURS);
+  EfiTime.Hour = IoRead8 (PCAT_RTC_DATA_REGISTER);
+  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_MINUTES);
+  EfiTime.Minute = IoRead8 (PCAT_RTC_DATA_REGISTER);
+  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_SECONDS);
+  EfiTime.Second = IoRead8 (PCAT_RTC_DATA_REGISTER);
+
+  //
+  // Set RTC alarm
+  //
+
+  //
+  // Add PLATFORM_WAKE_SECONDS_BUFFER to current EfiTime.Second
+  // The maths is to allow for the fact we are adding to a BCD number and require the answer to be BCD (EfiTime.Second)
+  //
+  if ((BCD_BASE - (EfiTime.Second & 0x0F)) <= PLATFORM_WAKE_SECONDS_BUFFER) {
+    Data8 = (((EfiTime.Second & 0xF0) + 0x10) + (PLATFORM_WAKE_SECONDS_BUFFER - (BCD_BASE - (EfiTime.Second & 0x0F))));
+  } else {
+    Data8 = EfiTime.Second + PLATFORM_WAKE_SECONDS_BUFFER;
+  }
+
+  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_HOURS_ALARM);
+  IoWrite8 (PCAT_RTC_DATA_REGISTER, EfiTime.Hour);
+  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_MINUTES_ALARM);
+  IoWrite8 (PCAT_RTC_DATA_REGISTER, EfiTime.Minute);
+  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_SECONDS_ALARM);
+  IoWrite8 (PCAT_RTC_DATA_REGISTER, Data8);
+
+  //
+  // Enable RTC alarm interrupt
+  //
+  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_B);
+  Data8 = IoRead8 (PCAT_RTC_DATA_REGISTER);
+  IoWrite8 (PCAT_RTC_DATA_REGISTER, (Data8 | BIT5));
+
+  //
+  // Enable RTC alarm as WAKE event
+  //
+  Data16 = IoRead16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1E);
+  IoWrite16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1E, (Data16 | B_QNC_PM1BLK_PM1E_RTC));
+
+  //
+  // Enter S3
+  //
+  Data32 = IoRead32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C);
+  Data32  = (UINT32) ((Data32 & 0xffffc3fe) | V_S3 | B_QNC_PM1BLK_PM1C_SCIEN);
+  IoWrite32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C, Data32);
+  Data32 = Data32 | B_QNC_PM1BLK_PM1C_SLPEN;
+  IoWrite32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C, Data32);
+
+  //
+  // Enable Interrupt if it's enabled before
+  //
+  if ( (Eflags & 0x200) ) {
+     EnableInterrupts ();
+  }
+}
+
+/**
+  This function causes a systemwide reset. The exact type of the reset is
+  defined by the EFI_GUID that follows the Null-terminated Unicode string passed
+  into ResetData. If the platform does not recognize the EFI_GUID in ResetData
+  the platform must pick a supported reset type to perform.The platform may
+  optionally log the parameters from any non-normal reset that occurs.
+
+  @param[in]  DataSize   The size, in bytes, of ResetData.
+  @param[in]  ResetData  The data buffer starts with a Null-terminated string,
+                         followed by the EFI_GUID.
+**/
+VOID
+EFIAPI
+ResetPlatformSpecific (
+  IN UINTN   DataSize,
+  IN VOID    *ResetData
+  )
+{
+  ResetCold ();
+}
+
+/**
+  The ResetSystem function resets the entire platform.
+
+  @param[in] ResetType      The type of reset to perform.
+  @param[in] ResetStatus    The status code for the reset.
+  @param[in] DataSize       The size, in bytes, of ResetData.
+  @param[in] ResetData      For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown
+                            the data buffer starts with a Null-terminated string, optionally
+                            followed by additional binary data. The string is a description
+                            that the caller may use to further indicate the reason for the
+                            system reset.
+**/
+VOID
+EFIAPI
+ResetSystem (
+  IN EFI_RESET_TYPE               ResetType,
+  IN EFI_STATUS                   ResetStatus,
+  IN UINTN                        DataSize,
+  IN VOID                         *ResetData OPTIONAL
+  )
+{
+  switch (ResetType) {
+  case EfiResetWarm:
+    ResetWarm ();
+    break;
+
+  case EfiResetCold:
+    ResetCold ();
+    break;
+
+  case EfiResetShutdown:
+    ResetShutdown ();
+    return;
+
+  case EfiResetPlatformSpecific:
+    ResetPlatformSpecific (DataSize, ResetData);
+    return;
+
+  default:
+    return;
+  }
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/ResetSystemLib.inf b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/ResetSystemLib.inf
new file mode 100644
index 0000000000..b849259b7f
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/ResetSystemLib.inf
@@ -0,0 +1,46 @@
+## @file
+# Component description file for Intel QuarkNcSocId Reset System Library.
+#
+# Reset System Library implementation that bases on QNC.
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = ResetSystemLib
+  FILE_GUID                      = AD33A56E-3AAD-40ac-91B1-FA861E8D9D85
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ResetSystemLib
+
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  ResetSystemLib.c
+
+
+[Packages]
+  QuarkSocPkg/QuarkSocPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+  PcdLib
+  IoLib
+  BaseLib
+  CpuLib
+  QNCAccessLib
+
+[Pcd]
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdGbaIoBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPm1blkIoBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdGpe0blkIoBaseAddress
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/CommonHeader.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/CommonHeader.h
new file mode 100644
index 0000000000..8968aa8931
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/CommonHeader.h
@@ -0,0 +1,25 @@
+/** @file
+Common header file shared by all source files.
+
+This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+
+#include <Uefi.h>
+#include <Base.h>
+
+#include <Library/SmbusLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/QNCAccessLib.h>
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/SmbusLib.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/SmbusLib.c
new file mode 100644
index 0000000000..319e103cf4
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/SmbusLib.c
@@ -0,0 +1,797 @@
+/** @file
+Intel QNC SMBUS library implementation built upon I/O library.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// Include common header file for this module.
+//
+#include "CommonHeader.h"
+
+/**
+  Gets Io port base address of Smbus Host Controller.
+
+  This internal function depends on a feature flag named PcdIchSmbusFixedIoPortBaseAddress
+  to retrieve Smbus Io port base. If that feature flag is true, it will get Smbus Io port base
+  address from a preset Pcd entry named PcdIchSmbusIoPortBaseAddress; otherwise, it will always
+  read Pci configuration space to get that value in each Smbus bus transaction.
+
+  @return The Io port base address of Smbus host controller.
+
+**/
+UINTN
+InternalGetSmbusIoPortBaseAddress (
+  VOID
+  )
+{
+  UINTN     IoPortBaseAddress;
+
+  if (FeaturePcdGet (PcdSmbaIoBaseAddressFixed)) {
+    IoPortBaseAddress = (UINTN) PcdGet16 (PcdSmbaIoBaseAddress);
+  } else {
+    IoPortBaseAddress = (UINTN) LpcPciCfg32 (R_QNC_LPC_SMBUS_BASE) & B_QNC_LPC_SMBUS_BASE_MASK;
+  }
+
+  //
+  // Make sure that the IO port base address has been properly set.
+  //
+  ASSERT (IoPortBaseAddress != 0);
+
+  return IoPortBaseAddress;
+}
+
+
+/**
+  Acquires the ownership of SMBUS.
+
+  This internal function reads the host state register.
+  If the SMBUS is not available, RETURN_TIMEOUT is returned;
+  Otherwise, it performs some basic initializations and returns
+  RETURN_SUCCESS.
+
+  @param  IoPortBaseAddress The Io port base address of Smbus Host controller.
+
+  @retval RETURN_SUCCESS    The SMBUS command was executed successfully.
+  @retval RETURN_TIMEOUT    A timeout occurred while executing the SMBUS command.
+
+**/
+RETURN_STATUS
+InternalSmBusAcquire (
+  UINTN                     IoPortBaseAddress
+  )
+{
+
+  //
+  // Clear host status register and exit.
+  //
+  IoWrite8 (IoPortBaseAddress + R_QNC_SMBUS_HCTL, 0);
+  IoWrite8 (IoPortBaseAddress + R_QNC_SMBUS_HD0, 0);
+  IoWrite8 (IoPortBaseAddress + R_QNC_SMBUS_HD1, 0);
+  IoWrite8 (IoPortBaseAddress + R_QNC_SMBUS_HSTS, B_QNC_SMBUS_HSTS_ALL);
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Starts the SMBUS transaction and waits until the end.
+
+  This internal function start the SMBUS transaction and waits until the transaction
+  of SMBUS is over by polling the INTR bit of Host status register.
+  If the SMBUS is not available, RETURN_TIMEOUT is returned;
+  Otherwise, it performs some basic initializations and returns
+  RETURN_SUCCESS.
+
+  @param  IoPortBaseAddress   The Io port base address of Smbus Host controller.
+  @param  HostControl         The Host control command to start SMBUS transaction.
+
+  @retval RETURN_SUCCESS      The SMBUS command was executed successfully.
+  @retval RETURN_CRC_ERROR    The checksum is not correct (PEC is incorrect).
+  @retval RETURN_DEVICE_ERROR The request was not completed because a failure reflected
+                              in the Host Status Register bit.  Device errors are
+                              a result of a transaction collision, illegal command field,
+                              unclaimed cycle (host initiated), or bus errors (collisions).
+
+**/
+RETURN_STATUS
+InternalSmBusStart (
+  IN  UINTN                   IoPortBaseAddress,
+  IN  UINT8                   HostControl
+  )
+{
+  UINT8   HostStatus;
+
+  //
+  // Set Host Control Register (Initiate Operation, Interrupt disabled).
+  //
+  IoWrite8 (IoPortBaseAddress + R_QNC_SMBUS_HCTL, HostControl + B_QNC_SMBUS_START);
+
+  do {
+    //
+    // Poll INTR bit of Host Status Register.
+    //
+    HostStatus = IoRead8 (IoPortBaseAddress + R_QNC_SMBUS_HSTS);
+  } while ((HostStatus & (B_QNC_SMBUS_BYTE_DONE_STS | B_QNC_SMBUS_DERR | B_QNC_SMBUS_BERR)) == 0);
+
+  if ((HostStatus & (B_QNC_SMBUS_DERR | B_QNC_SMBUS_BERR)) == 0) {
+    return RETURN_SUCCESS;
+  }
+  //
+  // Clear error bits of Host Status Register.
+  //
+  IoWrite8 (IoPortBaseAddress + R_QNC_SMBUS_HSTS, (B_QNC_SMBUS_DERR | B_QNC_SMBUS_BERR));
+
+  return RETURN_DEVICE_ERROR;
+}
+
+/**
+  Executes an SMBUS quick, byte or word command.
+
+  This internal function executes an SMBUS quick, byte or word commond.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+
+  @param  HostControl     The value of Host Control Register to set.
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Value           The byte/word write to the SMBUS.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+  @return The byte/word read from the SMBUS.
+
+**/
+UINT16
+InternalSmBusNonBlock (
+  IN  UINT8                     HostControl,
+  IN  UINTN                     SmBusAddress,
+  IN  UINT16                    Value,
+  OUT RETURN_STATUS             *Status
+  )
+{
+  RETURN_STATUS                 ReturnStatus;
+  UINTN                         IoPortBaseAddress;
+
+  IoPortBaseAddress = InternalGetSmbusIoPortBaseAddress ();
+
+  //
+  // Try to acquire the ownership of QNC SMBUS.
+  //
+  ReturnStatus = InternalSmBusAcquire (IoPortBaseAddress);
+  if (RETURN_ERROR (ReturnStatus)) {
+    goto Done;
+  }
+
+  //
+  // Set Host Commond Register.
+  //
+  IoWrite8 (IoPortBaseAddress + R_QNC_SMBUS_HCMD, (UINT8) SMBUS_LIB_COMMAND (SmBusAddress));
+  //
+  // Write value to Host Data 0 and Host Data 1 Registers.
+  //
+  IoWrite8 (IoPortBaseAddress + R_QNC_SMBUS_HD0, (UINT8) Value);
+  IoWrite8 (IoPortBaseAddress + R_QNC_SMBUS_HD1, (UINT8) (Value >> 8));
+
+
+  //
+  // Set SMBUS slave address for the device to send/receive from.
+  //
+  IoWrite8 (IoPortBaseAddress + R_QNC_SMBUS_TSA, (UINT8) SmBusAddress);
+  //
+  // Start the SMBUS transaction and wait for the end.
+  //
+  ReturnStatus = InternalSmBusStart (IoPortBaseAddress, HostControl);
+  //
+  // Read value from Host Data 0 and Host Data 1 Registers.
+  //
+  Value = (UINT16)(IoRead8 (IoPortBaseAddress + R_QNC_SMBUS_HD1) << 8);
+  Value = (UINT16)(Value | IoRead8 (IoPortBaseAddress + R_QNC_SMBUS_HD0));
+
+  //
+  // Clear Host Status Register and Auxiliary Status Register.
+  //
+  IoWrite8 (IoPortBaseAddress + R_QNC_SMBUS_HSTS, B_QNC_SMBUS_HSTS_ALL);
+
+Done:
+  if (Status != NULL) {
+    *Status = ReturnStatus;
+  }
+
+  return Value;
+}
+
+/**
+  Executes an SMBUS quick read command.
+
+  Executes an SMBUS quick read command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address field of SmBusAddress is required.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If PEC is set in SmBusAddress, then ASSERT().
+  If Command in SmBusAddress is not zero, then ASSERT().
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+**/
+VOID
+EFIAPI
+SmBusQuickRead (
+  IN  UINTN                     SmBusAddress,
+  OUT RETURN_STATUS             *Status       OPTIONAL
+  )
+{
+  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));
+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  InternalSmBusNonBlock (
+    V_QNC_SMBUS_HCTL_CMD_QUICK,
+    SmBusAddress | V_QNC_SMBUS_RW_SEL_READ,
+    0,
+    Status
+    );
+
+}
+
+/**
+  Executes an SMBUS quick write command.
+
+  Executes an SMBUS quick write command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address field of SmBusAddress is required.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If PEC is set in SmBusAddress, then ASSERT().
+  If Command in SmBusAddress is not zero, then ASSERT().
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+**/
+VOID
+EFIAPI
+SmBusQuickWrite (
+  IN  UINTN                     SmBusAddress,
+  OUT RETURN_STATUS             *Status       OPTIONAL
+  )
+{
+  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));
+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  InternalSmBusNonBlock (
+    V_QNC_SMBUS_HCTL_CMD_QUICK,
+    SmBusAddress & V_QNC_SMBUS_RW_SEL_WRITE,
+    0,
+    Status
+    );
+
+}
+
+/**
+  Executes an SMBUS receive byte command.
+
+  Executes an SMBUS receive byte command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address field of SmBusAddress is required.
+  The byte received from the SMBUS is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Command in SmBusAddress is not zero, then ASSERT().
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+  @return The byte received from the SMBUS.
+
+**/
+UINT8
+EFIAPI
+SmBusReceiveByte (
+  IN  UINTN          SmBusAddress,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  return (UINT8) InternalSmBusNonBlock (
+                   V_QNC_SMBUS_HCTL_CMD_BYTE,
+                   SmBusAddress | V_QNC_SMBUS_RW_SEL_READ,
+                   0,
+                   Status
+                   );
+
+}
+
+/**
+  Executes an SMBUS send byte command.
+
+  Executes an SMBUS send byte command on the SMBUS device specified by SmBusAddress.
+  The byte specified by Value is sent.
+  Only the SMBUS slave address field of SmBusAddress is required.  Value is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Command in SmBusAddress is not zero, then ASSERT().
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Value           The 8-bit value to send.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+  @return The parameter of Value.
+
+**/
+UINT8
+EFIAPI
+SmBusSendByte (
+  IN  UINTN          SmBusAddress,
+  IN  UINT8          Value,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  return (UINT8) InternalSmBusNonBlock (
+                   V_QNC_SMBUS_HCTL_CMD_BYTE,
+                   SmBusAddress & V_QNC_SMBUS_RW_SEL_WRITE,
+                   Value,
+                   Status
+                   );
+
+}
+
+/**
+  Executes an SMBUS read data byte command.
+
+  Executes an SMBUS read data byte command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  The 8-bit value read from the SMBUS is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+  @return The byte read from the SMBUS.
+
+**/
+UINT8
+EFIAPI
+SmBusReadDataByte (
+  IN  UINTN          SmBusAddress,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  return (UINT8) InternalSmBusNonBlock (
+                   V_QNC_SMBUS_HCTL_CMD_BYTE_DATA,
+                   SmBusAddress | V_QNC_SMBUS_RW_SEL_READ,
+                   0,
+                   Status
+                   );
+}
+
+/**
+  Executes an SMBUS write data byte command.
+
+  Executes an SMBUS write data byte command on the SMBUS device specified by SmBusAddress.
+  The 8-bit value specified by Value is written.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  Value is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Value           The 8-bit value to write.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+  @return The parameter of Value.
+
+**/
+UINT8
+EFIAPI
+SmBusWriteDataByte (
+  IN  UINTN          SmBusAddress,
+  IN  UINT8          Value,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  return (UINT8) InternalSmBusNonBlock (
+                   V_QNC_SMBUS_HCTL_CMD_BYTE_DATA,
+                   SmBusAddress | V_QNC_SMBUS_RW_SEL_WRITE,
+                   Value,
+                   Status
+                   );
+}
+
+/**
+  Executes an SMBUS read data word command.
+
+  Executes an SMBUS read data word command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  The 16-bit value read from the SMBUS is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+  @return The byte read from the SMBUS.
+
+**/
+UINT16
+EFIAPI
+SmBusReadDataWord (
+  IN  UINTN          SmBusAddress,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 2);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  return InternalSmBusNonBlock (
+           V_QNC_SMBUS_HCTL_CMD_WORD_DATA,
+           SmBusAddress | V_QNC_SMBUS_RW_SEL_READ,
+           0,
+           Status
+           );
+
+}
+
+/**
+  Executes an SMBUS write data word command.
+
+  Executes an SMBUS write data word command on the SMBUS device specified by SmBusAddress.
+  The 16-bit value specified by Value is written.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  Value is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Value           The 16-bit value to write.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+  @return The parameter of Value.
+
+**/
+UINT16
+EFIAPI
+SmBusWriteDataWord (
+  IN  UINTN          SmBusAddress,
+  IN  UINT16         Value,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 2);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  return InternalSmBusNonBlock (
+         V_QNC_SMBUS_HCTL_CMD_WORD_DATA,
+         SmBusAddress | V_QNC_SMBUS_RW_SEL_WRITE,
+         Value,
+         Status
+         );
+}
+
+/**
+  Executes an SMBUS process call command.
+
+  Executes an SMBUS process call command on the SMBUS device specified by SmBusAddress.
+  The 16-bit value specified by Value is written.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  The 16-bit value returned by the process call command is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Value           The 16-bit value to write.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+  @return The 16-bit value returned by the process call command.
+
+**/
+UINT16
+EFIAPI
+SmBusProcessCall (
+  IN  UINTN          SmBusAddress,
+  IN  UINT16         Value,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  return InternalSmBusNonBlock (
+           V_QNC_SMBUS_HCTL_CMD_PROCESS_CALL,
+           SmBusAddress & V_QNC_SMBUS_RW_SEL_WRITE,
+           Value,
+           Status
+           );
+
+}
+
+/**
+  Executes an SMBUS block command.
+
+  Executes an SMBUS block read, block write and block write-block read command
+  on the SMBUS device specified by SmBusAddress.
+  Bytes are read from the SMBUS and stored in Buffer.
+  The number of bytes read is returned, and will never return a value larger than 32-bytes.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.
+
+  @param  HostControl     The value of Host Control Register to set.
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  WriteBuffer     Pointer to the buffer of bytes to write to the SMBUS.
+  @param  ReadBuffer      Pointer to the buffer of bytes to read from the SMBUS.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+  @return The number of bytes read from the SMBUS.
+
+**/
+UINTN
+InternalSmBusBlock (
+  IN  UINT8                     HostControl,
+  IN  UINTN                     SmBusAddress,
+  IN  UINT8                     *WriteBuffer,
+  OUT UINT8                     *ReadBuffer,
+  OUT RETURN_STATUS             *Status
+  )
+{
+  RETURN_STATUS                 ReturnStatus;
+  UINTN                         Index;
+  UINTN                         BytesCount;
+  UINTN                         IoPortBaseAddress;
+
+  IoPortBaseAddress = InternalGetSmbusIoPortBaseAddress ();
+
+  BytesCount = SMBUS_LIB_LENGTH (SmBusAddress);
+
+  //
+  // Try to acquire the ownership of ICH SMBUS.
+  //
+  ReturnStatus = InternalSmBusAcquire (IoPortBaseAddress);
+  if (RETURN_ERROR (ReturnStatus)) {
+    goto Done;
+  }
+
+  //
+  // Set Host Command Register.
+  //
+  IoWrite8 (IoPortBaseAddress + R_QNC_SMBUS_HCMD, (UINT8) SMBUS_LIB_COMMAND (SmBusAddress));
+
+  //
+  // Clear byte pointer of 32-byte buffer.
+  //
+  IoRead8 (IoPortBaseAddress + R_QNC_SMBUS_HCTL);
+
+  if (WriteBuffer != NULL) {
+    //
+    // Write the number of block to Host Block Data Byte Register.
+    //
+    IoWrite8 (IoPortBaseAddress + R_QNC_SMBUS_HD0, (UINT8) BytesCount);
+    //
+    // Write data block to Host Block Data Register.
+    //
+    for (Index = 0; Index < BytesCount; Index++) {
+      IoWrite8 (IoPortBaseAddress + R_QNC_SMBUS_HBD + (UINT8)Index, WriteBuffer[Index]);
+    }
+  }
+  //
+  // Set SMBUS slave address for the device to send/receive from.
+  //
+  IoWrite8 (IoPortBaseAddress + R_QNC_SMBUS_TSA, (UINT8) SmBusAddress);
+  //
+  // Start the SMBUS transaction and wait for the end.
+  //
+  ReturnStatus = InternalSmBusStart (IoPortBaseAddress, HostControl);
+  if (RETURN_ERROR (ReturnStatus)) {
+    goto Done;
+  }
+
+  if (ReadBuffer != NULL) {
+    //
+    // Read the number of block from host block data byte register.
+    //
+    BytesCount = IoRead8 (IoPortBaseAddress + R_QNC_SMBUS_HD0);
+    //
+    // Write data block from Host Block Data Register.
+    //
+    for (Index = 0; Index < BytesCount; Index++) {
+      ReadBuffer[Index] = IoRead8 (IoPortBaseAddress + R_QNC_SMBUS_HBD + (UINT8)Index);
+    }
+  }
+
+Done:
+  //
+  // Clear Host Status Register and Auxiliary Status Register.
+  //
+  IoWrite8 (IoPortBaseAddress + R_QNC_SMBUS_HSTS, B_QNC_SMBUS_HSTS_ALL);
+
+  if (Status != NULL) {
+    *Status = ReturnStatus;
+  }
+
+  return BytesCount;
+}
+
+/**
+  Executes an SMBUS read block command.
+
+  Executes an SMBUS read block command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  Bytes are read from the SMBUS and stored in Buffer.
+  The number of bytes read is returned, and will never return a value larger than 32-bytes.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If Buffer is NULL, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Buffer          Pointer to the buffer to store the bytes read from the SMBUS.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+  @return The number of bytes read.
+
+**/
+UINTN
+EFIAPI
+SmBusReadBlock (
+  IN  UINTN          SmBusAddress,
+  OUT VOID           *Buffer,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (Buffer != NULL);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  return InternalSmBusBlock (
+           V_QNC_SMBUS_HCTL_CMD_BLOCK,
+           SmBusAddress | V_QNC_SMBUS_RW_SEL_READ,
+           NULL,
+           Buffer,
+           Status
+           );
+}
+
+/**
+  Executes an SMBUS write block command.
+
+  Executes an SMBUS write block command on the SMBUS device specified by SmBusAddress.
+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.
+  Bytes are written to the SMBUS from Buffer.
+  The number of bytes written is returned, and will never return a value larger than 32-bytes.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is zero or greater than 32, then ASSERT().
+  If Buffer is NULL, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Buffer          Pointer to the buffer to store the bytes read from the SMBUS.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+  @return The number of bytes written.
+
+**/
+UINTN
+EFIAPI
+SmBusWriteBlock (
+  IN  UINTN          SmBusAddress,
+  OUT VOID           *Buffer,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (Buffer != NULL);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  return InternalSmBusBlock (
+           V_QNC_SMBUS_HCTL_CMD_BLOCK,
+           SmBusAddress | V_QNC_SMBUS_RW_SEL_WRITE,
+           Buffer,
+           NULL,
+           Status
+           );
+}
+
+/**
+  Executes an SMBUS block process call command.
+
+  Executes an SMBUS block process call command on the SMBUS device specified by SmBusAddress.
+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.
+  Bytes are written to the SMBUS from WriteBuffer.  Bytes are then read from the SMBUS into ReadBuffer.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  It is the caller's responsibility to make sure ReadBuffer is large enough for the total number of bytes read.
+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.
+  If Length in SmBusAddress is zero or greater than 32, then ASSERT().
+  If WriteBuffer is NULL, then ASSERT().
+  If ReadBuffer is NULL, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress  Address that encodes the SMBUS Slave Address,
+                        SMBUS Command, SMBUS Data Length, and PEC.
+  @param  WriteBuffer   Pointer to the buffer of bytes to write to the SMBUS.
+  @param  ReadBuffer    Pointer to the buffer of bytes to read from the SMBUS.
+  @param  Status        Return status for the executed command.
+                        This is an optional parameter and may be NULL.
+                        RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.
+                        RETURN_DEVICE_ERROR  The request was not completed because a failure
+                        reflected in the Host Status Register bit.  Device errors are a result
+                        of a transaction collision, illegal command field, unclaimed cycle
+                        (host initiated), or bus errors (collisions).
+                        RETURN_CRC_ERROR  The checksum is not correct (PEC is incorrect)
+                        RETURN_UNSUPPORTED  The SMBus operation is not supported.
+
+  @return The number of bytes written.
+
+**/
+UINTN
+EFIAPI
+SmBusBlockProcessCall (
+  IN  UINTN          SmBusAddress,
+  IN  VOID           *WriteBuffer,
+  OUT VOID           *ReadBuffer,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (WriteBuffer != NULL);
+  ASSERT (ReadBuffer  != NULL);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+  if (Status != NULL) {
+    *Status = RETURN_UNSUPPORTED;
+  }
+  return 0;
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/SmbusLib.inf b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/SmbusLib.inf
new file mode 100644
index 0000000000..6cf4c569ed
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/SmbusLib.inf
@@ -0,0 +1,47 @@
+## @file
+# Component description file for Intel QNC Smbus Library.
+#
+# SMBUS Library that layers on top of the I/O Library to directly
+# access a standard SMBUS host controller.
+#
+# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SmbusLib
+  FILE_GUID                      = 6F2F36B3-936B-4eb2-83C7-2987B4F9D4EB
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SmbusLib
+
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  SmbusLib.c
+  CommonHeader.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  DebugLib
+  PciLib
+  IoLib
+  QNCAccessLib
+
+[FeaturePcd]
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdSmbaIoBaseAddressFixed
+
+[Pcd]
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdSmbaIoBaseAddress
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c
new file mode 100644
index 0000000000..f9a7af0449
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c
@@ -0,0 +1,446 @@
+/** @file
+The Quark CPU specific programming for PiSmmCpuDxeSmm module.
+
+Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiSmm.h>
+#include <Library/SmmCpuFeaturesLib.h>
+#include <Register/SmramSaveStateMap.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/QNCAccessLib.h>
+
+#define  EFI_MSR_SMRR_PHYS_MASK_VALID          BIT11
+#define  EFI_MSR_SMRR_MASK                     0xFFFFF000
+
+/**
+  Called during the very first SMI into System Management Mode to initialize
+  CPU features, including SMBASE, for the currently executing CPU.  Since this
+  is the first SMI, the SMRAM Save State Map is at the default address of
+  SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET.  The currently executing
+  CPU is specified by CpuIndex and CpuIndex can be used to access information
+  about the currently executing CPU in the ProcessorInfo array and the
+  HotPlugCpuData data structure.
+
+  @param[in] CpuIndex        The index of the CPU to initialize.  The value
+                             must be between 0 and the NumberOfCpus field in
+                             the System Management System Table (SMST).
+  @param[in] IsMonarch       TRUE if the CpuIndex is the index of the CPU that
+                             was elected as monarch during System Management
+                             Mode initialization.
+                             FALSE if the CpuIndex is not the index of the CPU
+                             that was elected as monarch during System
+                             Management Mode initialization.
+  @param[in] ProcessorInfo   Pointer to an array of EFI_PROCESSOR_INFORMATION
+                             structures.  ProcessorInfo[CpuIndex] contains the
+                             information for the currently executing CPU.
+  @param[in] CpuHotPlugData  Pointer to the CPU_HOT_PLUG_DATA structure that
+                             contains the ApidId and SmBase arrays.
+**/
+VOID
+EFIAPI
+SmmCpuFeaturesInitializeProcessor (
+  IN UINTN                      CpuIndex,
+  IN BOOLEAN                    IsMonarch,
+  IN EFI_PROCESSOR_INFORMATION  *ProcessorInfo,
+  IN CPU_HOT_PLUG_DATA          *CpuHotPlugData
+  )
+{
+  SMRAM_SAVE_STATE_MAP  *CpuState;
+
+  //
+  // Configure SMBASE.
+  //
+  CpuState = (SMRAM_SAVE_STATE_MAP *)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET);
+  CpuState->x86.SMBASE = CpuHotPlugData->SmBase[CpuIndex];
+
+  //
+  // SMRR size cannot be less than 4-KBytes
+  // SMRR size must be of length 2^n
+  // SMRR base alignment cannot be less than SMRR length
+  //
+  if ((CpuHotPlugData->SmrrSize < SIZE_4KB) ||
+      (CpuHotPlugData->SmrrSize != GetPowerOfTwo32 (CpuHotPlugData->SmrrSize)) ||
+      ((CpuHotPlugData->SmrrBase & ~(CpuHotPlugData->SmrrSize - 1)) != CpuHotPlugData->SmrrBase)) {
+    DEBUG ((EFI_D_ERROR, "SMM Base/Size does not meet alignment/size requirement!\n"));
+    CpuDeadLoop ();
+  }
+
+  //
+  // Use QNC to initialize SMRR on Quark
+  //
+  QNCPortWrite(QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QUARK_NC_HOST_BRIDGE_IA32_MTRR_SMRR_PHYSBASE, CpuHotPlugData->SmrrBase);
+  QNCPortWrite(QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QUARK_NC_HOST_BRIDGE_IA32_MTRR_SMRR_PHYSMASK, (~(CpuHotPlugData->SmrrSize - 1) & EFI_MSR_SMRR_MASK) | EFI_MSR_SMRR_PHYS_MASK_VALID);
+}
+
+/**
+  This function updates the SMRAM save state on the currently executing CPU
+  to resume execution at a specific address after an RSM instruction.  This
+  function must evaluate the SMRAM save state to determine the execution mode
+  the RSM instruction resumes and update the resume execution address with
+  either NewInstructionPointer32 or NewInstructionPoint.  The auto HALT restart
+  flag in the SMRAM save state must always be cleared.  This function returns
+  the value of the instruction pointer from the SMRAM save state that was
+  replaced.  If this function returns 0, then the SMRAM save state was not
+  modified.
+
+  This function is called during the very first SMI on each CPU after
+  SmmCpuFeaturesInitializeProcessor() to set a flag in normal execution mode
+  to signal that the SMBASE of each CPU has been updated before the default
+  SMBASE address is used for the first SMI to the next CPU.
+
+  @param[in] CpuIndex                 The index of the CPU to hook.  The value
+                                      must be between 0 and the NumberOfCpus
+                                      field in the System Management System Table
+                                      (SMST).
+  @param[in] CpuState                 Pointer to SMRAM Save State Map for the
+                                      currently executing CPU.
+  @param[in] NewInstructionPointer32  Instruction pointer to use if resuming to
+                                      32-bit execution mode from 64-bit SMM.
+  @param[in] NewInstructionPointer    Instruction pointer to use if resuming to
+                                      same execution mode as SMM.
+
+  @retval 0    This function did modify the SMRAM save state.
+  @retval > 0  The original instruction pointer value from the SMRAM save state
+               before it was replaced.
+**/
+UINT64
+EFIAPI
+SmmCpuFeaturesHookReturnFromSmm (
+  IN UINTN                 CpuIndex,
+  IN SMRAM_SAVE_STATE_MAP  *CpuState,
+  IN UINT64                NewInstructionPointer32,
+  IN UINT64                NewInstructionPointer
+  )
+{
+  return 0;
+}
+
+/**
+  Hook point in normal execution mode that allows the one CPU that was elected
+  as monarch during System Management Mode initialization to perform additional
+  initialization actions immediately after all of the CPUs have processed their
+  first SMI and called SmmCpuFeaturesInitializeProcessor() relocating SMBASE
+  into a buffer in SMRAM and called SmmCpuFeaturesHookReturnFromSmm().
+**/
+VOID
+EFIAPI
+SmmCpuFeaturesSmmRelocationComplete (
+  VOID
+  )
+{
+}
+
+/**
+  Return the size, in bytes, of a custom SMI Handler in bytes.  If 0 is
+  returned, then a custom SMI handler is not provided by this library,
+  and the default SMI handler must be used.
+
+  @retval 0    Use the default SMI handler.
+  @retval > 0  Use the SMI handler installed by SmmCpuFeaturesInstallSmiHandler()
+               The caller is required to allocate enough SMRAM for each CPU to
+               support the size of the custom SMI handler.
+**/
+UINTN
+EFIAPI
+SmmCpuFeaturesGetSmiHandlerSize (
+  VOID
+  )
+{
+  return 0;
+}
+
+/**
+  Install a custom SMI handler for the CPU specified by CpuIndex.  This function
+  is only called if SmmCpuFeaturesGetSmiHandlerSize() returns a size is greater
+  than zero and is called by the CPU that was elected as monarch during System
+  Management Mode initialization.
+
+  @param[in] CpuIndex   The index of the CPU to install the custom SMI handler.
+                        The value must be between 0 and the NumberOfCpus field
+                        in the System Management System Table (SMST).
+  @param[in] SmBase     The SMBASE address for the CPU specified by CpuIndex.
+  @param[in] SmiStack   The stack to use when an SMI is processed by the
+                        the CPU specified by CpuIndex.
+  @param[in] StackSize  The size, in bytes, if the stack used when an SMI is
+                        processed by the CPU specified by CpuIndex.
+  @param[in] GdtBase    The base address of the GDT to use when an SMI is
+                        processed by the CPU specified by CpuIndex.
+  @param[in] GdtSize    The size, in bytes, of the GDT used when an SMI is
+                        processed by the CPU specified by CpuIndex.
+  @param[in] IdtBase    The base address of the IDT to use when an SMI is
+                        processed by the CPU specified by CpuIndex.
+  @param[in] IdtSize    The size, in bytes, of the IDT used when an SMI is
+                        processed by the CPU specified by CpuIndex.
+  @param[in] Cr3        The base address of the page tables to use when an SMI
+                        is processed by the CPU specified by CpuIndex.
+**/
+VOID
+EFIAPI
+SmmCpuFeaturesInstallSmiHandler (
+  IN UINTN   CpuIndex,
+  IN UINT32  SmBase,
+  IN VOID    *SmiStack,
+  IN UINTN   StackSize,
+  IN UINTN   GdtBase,
+  IN UINTN   GdtSize,
+  IN UINTN   IdtBase,
+  IN UINTN   IdtSize,
+  IN UINT32  Cr3
+  )
+{
+}
+
+/**
+  Determines if MTRR registers must be configured to set SMRAM cache-ability
+  when executing in System Management Mode.
+
+  @retval TRUE   MTRR registers must be configured to set SMRAM cache-ability.
+  @retval FALSE  MTRR registers do not need to be configured to set SMRAM
+                   cache-ability.
+**/
+BOOLEAN
+EFIAPI
+SmmCpuFeaturesNeedConfigureMtrrs (
+  VOID
+  )
+{
+  return TRUE;
+}
+
+/**
+  Disable SMRR register if SMRR is supported and SmmCpuFeaturesNeedConfigureMtrrs()
+  returns TRUE.
+**/
+VOID
+EFIAPI
+SmmCpuFeaturesDisableSmrr (
+  VOID
+  )
+{
+  //
+  // Use QNC to disable SMRR on Quark
+  //
+  QNCPortWrite(
+    QUARK_NC_HOST_BRIDGE_SB_PORT_ID,
+    QUARK_NC_HOST_BRIDGE_IA32_MTRR_SMRR_PHYSMASK,
+    QNCPortRead(QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QUARK_NC_HOST_BRIDGE_IA32_MTRR_SMRR_PHYSMASK) & ~EFI_MSR_SMRR_PHYS_MASK_VALID
+    );
+}
+
+/**
+  Enable SMRR register if SMRR is supported and SmmCpuFeaturesNeedConfigureMtrrs()
+  returns TRUE.
+**/
+VOID
+EFIAPI
+SmmCpuFeaturesReenableSmrr (
+  VOID
+  )
+{
+  //
+  // Use QNC to enable SMRR on Quark
+  //
+  QNCPortWrite(
+    QUARK_NC_HOST_BRIDGE_SB_PORT_ID,
+    QUARK_NC_HOST_BRIDGE_IA32_MTRR_SMRR_PHYSMASK,
+    QNCPortRead(QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QUARK_NC_HOST_BRIDGE_IA32_MTRR_SMRR_PHYSMASK) | EFI_MSR_SMRR_PHYS_MASK_VALID
+    );
+}
+
+/**
+  Processor specific hook point each time a CPU enters System Management Mode.
+
+  @param[in] CpuIndex  The index of the CPU that has entered SMM.  The value
+                       must be between 0 and the NumberOfCpus field in the
+                       System Management System Table (SMST).
+**/
+VOID
+EFIAPI
+SmmCpuFeaturesRendezvousEntry (
+  IN UINTN  CpuIndex
+  )
+{
+}
+
+/**
+  Processor specific hook point each time a CPU exits System Management Mode.
+
+  @param[in] CpuIndex  The index of the CPU that is exiting SMM.  The value must
+                       be between 0 and the NumberOfCpus field in the System
+                       Management System Table (SMST).
+**/
+VOID
+EFIAPI
+SmmCpuFeaturesRendezvousExit (
+  IN UINTN  CpuIndex
+  )
+{
+}
+
+/**
+  Check to see if an SMM register is supported by a specified CPU.
+
+  @param[in] CpuIndex  The index of the CPU to check for SMM register support.
+                       The value must be between 0 and the NumberOfCpus field
+                       in the System Management System Table (SMST).
+  @param[in] RegName   Identifies the SMM register to check for support.
+
+  @retval TRUE   The SMM register specified by RegName is supported by the CPU
+                 specified by CpuIndex.
+  @retval FALSE  The SMM register specified by RegName is not supported by the
+                 CPU specified by CpuIndex.
+**/
+BOOLEAN
+EFIAPI
+SmmCpuFeaturesIsSmmRegisterSupported (
+  IN UINTN         CpuIndex,
+  IN SMM_REG_NAME  RegName
+  )
+{
+  return FALSE;
+}
+
+/**
+  Returns the current value of the SMM register for the specified CPU.
+  If the SMM register is not supported, then 0 is returned.
+
+  @param[in] CpuIndex  The index of the CPU to read the SMM register.  The
+                       value must be between 0 and the NumberOfCpus field in
+                       the System Management System Table (SMST).
+  @param[in] RegName   Identifies the SMM register to read.
+
+  @return  The value of the SMM register specified by RegName from the CPU
+           specified by CpuIndex.
+**/
+UINT64
+EFIAPI
+SmmCpuFeaturesGetSmmRegister (
+  IN UINTN         CpuIndex,
+  IN SMM_REG_NAME  RegName
+  )
+{
+  return 0;
+}
+
+/**
+  Sets the value of an SMM register on a specified CPU.
+  If the SMM register is not supported, then no action is performed.
+
+  @param[in] CpuIndex  The index of the CPU to write the SMM register.  The
+                       value must be between 0 and the NumberOfCpus field in
+                       the System Management System Table (SMST).
+  @param[in] RegName   Identifies the SMM register to write.
+                       registers are read-only.
+  @param[in] Value     The value to write to the SMM register.
+**/
+VOID
+EFIAPI
+SmmCpuFeaturesSetSmmRegister (
+  IN UINTN         CpuIndex,
+  IN SMM_REG_NAME  RegName,
+  IN UINT64        Value
+  )
+{
+}
+
+/**
+  Read an SMM Save State register on the target processor.  If this function
+  returns EFI_UNSUPPORTED, then the caller is responsible for reading the
+  SMM Save Sate register.
+
+  @param[in]  CpuIndex  The index of the CPU to read the SMM Save State.  The
+                        value must be between 0 and the NumberOfCpus field in
+                        the System Management System Table (SMST).
+  @param[in]  Register  The SMM Save State register to read.
+  @param[in]  Width     The number of bytes to read from the CPU save state.
+  @param[out] Buffer    Upon return, this holds the CPU register value read
+                        from the save state.
+
+  @retval EFI_SUCCESS           The register was read from Save State.
+  @retval EFI_INVALID_PARAMTER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED       This function does not support reading Register.
+
+**/
+EFI_STATUS
+EFIAPI
+SmmCpuFeaturesReadSaveStateRegister (
+  IN  UINTN                        CpuIndex,
+  IN  EFI_SMM_SAVE_STATE_REGISTER  Register,
+  IN  UINTN                        Width,
+  OUT VOID                         *Buffer
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Writes an SMM Save State register on the target processor.  If this function
+  returns EFI_UNSUPPORTED, then the caller is responsible for writing the
+  SMM Save Sate register.
+
+  @param[in] CpuIndex  The index of the CPU to write the SMM Save State.  The
+                       value must be between 0 and the NumberOfCpus field in
+                       the System Management System Table (SMST).
+  @param[in] Register  The SMM Save State register to write.
+  @param[in] Width     The number of bytes to write to the CPU save state.
+  @param[in] Buffer    Upon entry, this holds the new CPU register value.
+
+  @retval EFI_SUCCESS           The register was written to Save State.
+  @retval EFI_INVALID_PARAMTER  Buffer is NULL.
+  @retval EFI_UNSUPPORTED       This function does not support writing Register.
+**/
+EFI_STATUS
+EFIAPI
+SmmCpuFeaturesWriteSaveStateRegister (
+  IN UINTN                        CpuIndex,
+  IN EFI_SMM_SAVE_STATE_REGISTER  Register,
+  IN UINTN                        Width,
+  IN CONST VOID                   *Buffer
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  This function is hook point called after the gEfiSmmReadyToLockProtocolGuid
+  notification is completely processed.
+**/
+VOID
+EFIAPI
+SmmCpuFeaturesCompleteSmmReadyToLock (
+  VOID
+  )
+{
+}
+
+/**
+  This API provides a method for a CPU to allocate a specific region for storing page tables.
+
+  This API can be called more once to allocate memory for page tables.
+
+  Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
+  allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
+  is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
+  returned.
+
+  This function can also return NULL if there is no preference on where the page tables are allocated in SMRAM.
+
+  @param  Pages                 The number of 4 KB pages to allocate.
+
+  @return A pointer to the allocated buffer for page tables.
+  @retval NULL      Fail to allocate a specific region for storing page tables,
+                    Or there is no preference on where the page tables are allocated in SMRAM.
+
+**/
+VOID *
+EFIAPI
+SmmCpuFeaturesAllocatePageTableMemory (
+  IN UINTN           Pages
+  )
+{
+  return NULL;
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
new file mode 100644
index 0000000000..a45c857910
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
@@ -0,0 +1,30 @@
+## @file
+#  The CPU specific programming for PiSmmCpuDxeSmm module.
+#
+#  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SmmCpuFeaturesLib
+  MODULE_UNI_FILE                = SmmCpuFeaturesLib.uni
+  FILE_GUID                      = 34001BF4-1E93-4e08-B90E-52F2418A5026
+  MODULE_TYPE                    = DXE_SMM_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SmmCpuFeaturesLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[Sources]
+  SmmCpuFeaturesLib.c
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  QNCAccessLib
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.uni b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.uni
new file mode 100644
index 0000000000..6ee54e9254
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.uni
@@ -0,0 +1,12 @@
+// /** @file
+// The CPU specific programming for PiSmmCpuDxeSmm module.
+//
+// Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT             #language en-US "The CPU specific programming for PiSmmCpuDxeSmm module."
+
+#string STR_MODULE_DESCRIPTION          #language en-US "The CPU specific programming for PiSmmCpuDxeSmm module."
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInit.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInit.c
new file mode 100644
index 0000000000..1d91360ec3
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInit.c
@@ -0,0 +1,59 @@
+/** @file
+Framework PEIM to initialize memory on a QuarkNcSocId Memory Controller.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// Include common header file for this module.
+//
+#include "MemoryInit.h"
+
+static PEI_QNC_MEMORY_INIT_PPI mPeiQNCMemoryInitPpi =
+{ MrcStart };
+
+static EFI_PEI_PPI_DESCRIPTOR PpiListPeiQNCMemoryInit =
+{
+    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+    &gQNCMemoryInitPpiGuid,
+    &mPeiQNCMemoryInitPpi
+};
+
+void Mrc( MRCParams_t *MrcData);
+
+/**
+
+ Do memory initialization for QuarkNcSocId DDR3 SDRAM Controller
+
+ @param  FfsHeader    Not used.
+ @param  PeiServices  General purpose services available to every PEIM.
+
+ @return EFI_SUCCESS  Memory initialization completed successfully.
+ All other error conditions encountered result in an ASSERT.
+
+ **/
+EFI_STATUS
+PeimMemoryInit(
+    IN EFI_PEI_FILE_HANDLE FileHandle,
+    IN CONST EFI_PEI_SERVICES **PeiServices
+    )
+{
+  EFI_STATUS Status;
+
+  Status = (**PeiServices).InstallPpi(PeiServices, &PpiListPeiQNCMemoryInit);
+
+  return Status;
+}
+
+VOID
+EFIAPI
+MrcStart(
+    IN OUT MRCParams_t *MrcData
+    )
+{
+
+  Mrc(MrcData);
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInit.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInit.h
new file mode 100644
index 0000000000..0cea554e0e
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInit.h
@@ -0,0 +1,35 @@
+/** @file
+Framework PEIM to initialize memory on an DDR2 SDRAM Memory Controller.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef _PEI_QNC_MEMORY_INIT_H_
+#define _PEI_QNC_MEMORY_INIT_H_
+
+//
+// The package level header files this module uses
+//
+#include <PiPei.h>
+#include <IntelQNCPeim.h>
+//
+// The protocols, PPI and GUID defintions for this module
+//
+#include <Ppi/QNCMemoryInit.h>
+//
+// The Library classes this module consumes
+//
+#include <Library/DebugLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/BaseMemoryLib.h>
+
+
+VOID
+EFIAPI
+MrcStart (
+  IN OUT MRCParams_t  *MrcData
+  );
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInitPei.inf b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInitPei.inf
new file mode 100644
index 0000000000..7a1ba522bf
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInitPei.inf
@@ -0,0 +1,70 @@
+## @file
+# This is the Memory Initialization Driver for Quark
+#
+# Copyright (c) 2013 - 2018, 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                      = MemoryInitPei
+  FILE_GUID                      = D2C69B26-82E1-4a1b-AD35-ED0261B9F347
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = PeimMemoryInit
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[BuildOptions]
+  GCC:DEBUG_*_*_CC_FLAGS               = -DGCC -Wno-unused-function
+  GCC:RELEASE_*_*_CC_FLAGS             = -DNDEBUG -DGCC -Wno-unused-function
+  INTEL:RELEASE_*_*_CC_FLAGS           = /D NDEBUG
+  MSFT:RELEASE_*_*_CC_FLAGS            = /D NDEBUG
+
+[Sources]
+  memory_options.h
+  platform.c
+  lprint.c
+  meminit.h
+  meminit.c
+  meminit_utils.h
+  meminit_utils.c
+  gen5_iosf_sb_definitions.h
+  general_definitions.h
+  io.h
+  core_types.h
+  prememinit.h
+  prememinit.c
+  mrc.h
+  mrc.c
+  hte.c
+  hte.h
+  MemoryInit.h
+  MemoryInit.c
+
+[Packages]
+  QuarkSocPkg/QuarkSocPkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  PeimEntryPoint
+  DebugLib
+  BaseMemoryLib
+
+[Ppis]
+  gQNCMemoryInitPpiGuid                        # PPI ALWAYS_PRODUCED
+
+[Depex]
+  TRUE
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/core_types.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/core_types.h
new file mode 100644
index 0000000000..eef3c3f8ae
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/core_types.h
@@ -0,0 +1,43 @@
+/** @file
+Core types used in Mrc.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef __MRC_CORE_TYPES_H
+#define __MRC_CORE_TYPES_H
+
+typedef char char_t;
+typedef unsigned char uint8_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+typedef int int32_t;
+typedef unsigned int uint32_t;
+typedef unsigned char bool;
+typedef unsigned int size_t;
+
+#ifdef ASM_INC
+// Unfortunately h2inc has issue with long long
+typedef struct uint64_s
+{
+  uint32_t lo;
+  uint32_t hi;
+}uint64_t;
+#else
+typedef unsigned long long uint64_t;
+#endif
+
+#ifdef SIM
+// Native word length is 64bit in simulation environment
+typedef uint64_t uintn_t;
+#else
+// Quark is 32bit
+typedef uint32_t uintn_t;
+#endif
+
+#define PTR32(a)  ((volatile uint32_t*)(uintn_t)(a))
+
+#endif
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/gen5_iosf_sb_definitions.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/gen5_iosf_sb_definitions.h
new file mode 100644
index 0000000000..dea2a9ad05
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/gen5_iosf_sb_definitions.h
@@ -0,0 +1,738 @@
+/************************************************************************
+ *
+ * Copyright (c) 2013-2015 Intel Corporation.
+ *
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ * MCU register definition
+ *
+ ************************************************************************/
+#ifndef __IOSF_DEFINITIONS_H
+#define __IOSF_DEFINITIONS_H
+
+// Define each of the IOSF-SB register offsets used by MRC.
+
+
+// MCU registers (DUNIT):
+// ====
+#define DRP                 0x0000
+#define DTR0                0x0001
+#define DTR1                0x0002
+#define DTR2                0x0003
+#define DTR3                0x0004
+#define DTR4                0x0005
+#define DPMC0               0x0006
+#define DPMC1               0x0007
+#define DRFC                0x0008
+#define DSCH                0x0009
+#define DCAL                0x000A
+#define DRMC                0x000B
+#define PMSTS               0x000C
+#define DCO                 0x000F
+#define DSTAT               0x0020
+#define DECCCTRL            0x0060
+#define DFUSESTAT           0x0070
+#define SCRMSEED            0x0080
+#define SCRMLO              0x0081
+#define SCRMHI              0x0082
+
+#define MCU_CH_OFFSET       0x0040
+#define MCU_RK_OFFSET       0x0020
+
+////
+//
+// BEGIN DUnit register definition
+//
+#pragma pack(1)
+typedef union {
+    uint32_t    raw;
+    struct {
+        uint32_t rank0Enabled       :1;             /**< BIT [0]   Rank 0 Enable */
+        uint32_t rank1Enabled       :1;             /**< BIT [1]   Rank 1 Enable */
+        uint32_t reserved0          :2;
+        uint32_t dimm0DevWidth      :2;             /**< BIT [5:4] DIMM 0 Device Width (Rank0&1)  */
+        uint32_t dimm0DevDensity    :2;             /**< BIT [7:6] DIMM 0 Device Density          */
+        uint32_t reserved1          :1;
+        uint32_t dimm1DevWidth      :2;             /**< BIT [10:9]  DIMM 1 Device Width (Rank2&3)  */
+        uint32_t dimm1DevDensity    :2;             /**< BIT [12:11] DIMM 1 Device Density          */
+        uint32_t split64            :1;             /**< BIT [13] split 64B transactions */
+        uint32_t addressMap         :2;             /**< BIT [15:14] Address Map select */
+        uint32_t reserved3          :14;
+        uint32_t mode32             :1;             /**< BIT [30] Select 32bit data interface*/
+        uint32_t reserved4          :1;
+    } field;
+} RegDRP;                                           /**< DRAM Rank Population and Interface Register */
+#pragma pack()
+
+
+#pragma pack(1)
+typedef union {
+    uint32_t    raw;
+    struct {
+        uint32_t dramFrequency      :2;             /**< DRAM Frequency (000=800,001=1033,010=1333) */
+        uint32_t reserved1          :2;
+        uint32_t tRP                :4;             /**< bit [7:4]   Precharge to Activate Delay  */
+        uint32_t tRCD               :4;             /**< bit [11:8]  Activate to CAS Delay  */
+        uint32_t tCL                :3;             /**< bit [14:12] CAS Latency  */
+        uint32_t reserved4          :1;
+        uint32_t tXS                :1;             /**< SRX Delay  */
+        uint32_t reserved5          :1;
+        uint32_t tXSDLL             :1;             /**< SRX To DLL Delay  */
+        uint32_t reserved6          :1;
+        uint32_t tZQCS              :1;             /**< bit [20] ZQTS recovery Latncy  */
+        uint32_t reserved7          :1;
+        uint32_t tZQCL              :1;             /**< bit [22] ZQCL recovery Latncy  */
+        uint32_t reserved8          :1;
+        uint32_t pmeDelay           :2;             /**< bit [25:24] Power mode entry delay  */
+        uint32_t reserved9          :2;
+        uint32_t CKEDLY             :4;               /**< bit [31:28]  */
+    } field;
+} RegDTR0;                                          /**< DRAM Timing Register 0 */
+#pragma pack()
+
+#pragma pack(1)
+typedef union {
+    uint32_t    raw;
+    struct {
+        uint32_t tWCL               :3;             /**< bit [2:0] CAS Write Latency */
+        uint32_t reserved1          :1;
+        uint32_t tCMD               :2;             /**< bit [5:4] Command transport duration */
+        uint32_t reserved2          :2;
+        uint32_t tWTP               :4;             /**< Write to Precharge */
+        uint32_t tCCD               :2;             /**< CAS to CAS delay */
+        uint32_t reserved4          :2;
+        uint32_t tFAW               :4;             /**< Four bank Activation Window*/
+        uint32_t tRAS               :4;             /**< Row Activation Period: */
+        uint32_t tRRD               :2;             /**<Row activation to Row activation Delay */
+        uint32_t reserved5          :2;
+        uint32_t tRTP               :3;             /**<Read to Precharge Delay */
+        uint32_t reserved6          :1;
+    } field;
+} RegDTR1;                                          /**< DRAM Timing Register 1 */
+#pragma pack()
+
+#pragma pack(1)
+typedef union {
+    uint32_t    raw;
+    struct {
+        uint32_t tRRDR              :3;             /**< RD to RD from different ranks, same DIMM */
+        uint32_t reserved1          :5;
+        uint32_t tWWDR              :3;             /**< WR to WR from different ranks, same DIMM. */
+        uint32_t reserved3          :5;
+        uint32_t tRWDR              :4;             /**< bit [19:16] RD to WR from different ranks, same DIMM. */
+        uint32_t reserved5          :12;
+    } field;
+} RegDTR2;                                          /**< DRAM Timing Register 2 */
+#pragma pack()
+
+#pragma pack(1)
+typedef union {
+    uint32_t    raw;
+    struct {
+        uint32_t tWRDR              :3;             /**< WR to RD from different ranks, same DIMM. */
+        uint32_t reserved1          :1;
+        uint32_t tWRDD              :3;             /**< WR to RD from different DIMM. */
+        uint32_t reserved2          :1;
+        uint32_t tRWSR              :4;             /**< RD to WR Same Rank. */
+        uint32_t reserved3          :1;
+        uint32_t tWRSR              :4;             /**< WR to RD Same Rank. */
+        uint32_t reserved4          :5;
+        uint32_t tXP                :2;             /**< Time from CKE set on to any command. */
+        uint32_t PWD_DLY            :4;             /**< Extended Power-Down Delay. */
+        uint32_t EnDeRate           :1;
+        uint32_t DeRateOvr          :1;
+        uint32_t DeRateStat         :1;
+        uint32_t reserved5          :1;
+    } field;
+} RegDTR3;                                          /**< DRAM Timing Register 3 */
+#pragma pack()
+
+
+#pragma pack(1)
+typedef union {
+    uint32_t    raw;
+    struct {
+        uint32_t WRODTSTRT          :2;             /**< WR command to ODT assert delay */
+        uint32_t reserved1          :2;
+        uint32_t WRODTSTOP          :3;             /**< Write command to ODT de-assert delay. */
+        uint32_t reserved2          :1;
+        uint32_t RDODTSTRT          :3;             /**< Read command to ODT assert delay */
+        uint32_t reserved3          :1;
+        uint32_t RDODTSTOP          :3;             /**< Read command to ODT de-assert delay */
+        uint32_t ODTDIS             :1;             /**< ODT disable */
+        uint32_t TRGSTRDIS          :1;             /**< Write target rank is not stretched */
+        uint32_t RDODTDIS           :1;             /**< Disable Read ODT */
+        uint32_t WRBODTDIS          :1;             /**< Disable Write ODT */
+        uint32_t reserved5          :13;
+    } field;
+} RegDTR4;                                          /**< DRAM Timing Register 3 */
+#pragma pack()
+
+#pragma pack(1)
+typedef union {
+    uint32_t    raw;
+    struct {
+        uint32_t SREntryDelay       :8;             /**< Self-Refresh Entry Delay: */
+        uint32_t powerModeOpCode    :5;             /**< SPID Power Mode Opcode */
+        uint32_t reserved1          :3;
+        uint32_t PCLSTO             :3;             /**< Page Close Timeout Period */
+        uint32_t reserved2          :1;
+        uint32_t PCLSWKOK           :1;             /**< Wake Allowed For Page Close Timeout */
+        uint32_t PREAPWDEN          :1;             /**< Send Precharge All to rank before entering Power-Down mode. */
+        uint32_t reserved3          :1;
+        uint32_t DYNSREN            :1;             /**< Dynamic Self-Refresh */
+        uint32_t CLKGTDIS           :1;             /**< Clock Gating Disabled*/
+        uint32_t DISPWRDN           :1;             /**< Disable Power Down*/
+        uint32_t reserved4          :2;
+        uint32_t REUTCLKGTDIS       :1;
+        uint32_t ENPHYCLKGATE       :1;
+        uint32_t reserved5          :2;
+    } field;
+} RegDPMC0;                                           /**< DRAM Power Management Control Register 0 */
+#pragma pack()
+
+#pragma pack(1)
+typedef union {
+    uint32_t    raw;
+    struct {
+        uint32_t REFWMLO            :4;             /**< Refresh Opportunistic Watermark */
+        uint32_t REFWMHI            :4;             /**< Refresh High Watermark*/
+        uint32_t REFWMPNC           :4;             /**< Refresh Panic Watermark */
+        uint32_t tREFI              :3;             /**< bit [14:12] Refresh Period */
+        uint32_t reserved1          :1;
+        uint32_t REFCNTMAX          :2;             /**< Refresh Max tREFI Interval */
+        uint32_t reserved2          :2;
+        uint32_t REFSKEWDIS         :1;             /**< tREFI counters */
+        uint32_t REFDBTCLR          :1;
+        uint32_t reserved3          :2;
+        uint32_t CuRefRate          :3;
+        uint32_t DisRefBW           :1;
+        uint32_t reserved4          :4;
+    } field;
+} RegDRCF;                                           /**< DRAM Refresh Control Register*/
+#pragma pack()
+
+#pragma pack(1)
+typedef union {
+    uint32_t    raw;
+    struct {
+        uint32_t reserved1          :8;
+        uint32_t ZQCINT             :3;             /**< ZQ Calibration Short Interval: */
+        uint32_t reserved2          :1;
+        uint32_t SRXZQCL            :2;             /** < ZQ Calibration Length */
+        uint32_t ZQCalType          :1;
+        uint32_t ZQCalStart         :1;
+        uint32_t TQPollStart        :1;
+        uint32_t TQPollRS           :2;
+        uint32_t reserved3          :5;
+        uint32_t MRRData            :8;             /**< bit[31:24] */
+    } field;
+} RegDCAL;                                          /**< DRAM Calibration Control*/
+#pragma pack()
+
+#pragma pack(1)
+typedef union {
+    uint32_t    raw;
+    struct {
+        uint32_t OOOAGETRH          :5;             /**< Out-of-Order Aging Threshold */
+        uint32_t reserved1          :3;
+        uint32_t OOODIS             :1;             /**< Out-of-Order Disable */
+        uint32_t OOOST3DIS          :1;             /**< Out-of-Order Disabled when RequestBD_Status is 3. */
+        uint32_t reserved2          :2;
+        uint32_t NEWBYPDIS          :1;
+        uint32_t reserved3          :3;
+        uint32_t IPREQMAX           :3;             /** < Max In-Progress Requests stored in MC */
+        uint32_t reserved4          :13;
+    } field;
+} RegDSCH;                                           /**< DRAM Scheduler Control Register */
+#pragma pack()
+
+#pragma pack(1)
+typedef union {
+    uint32_t    raw;
+    struct {
+        uint32_t DRPLOCK            :1;             /**< DRP lock bit */
+        uint32_t reserved1          :7;
+        uint32_t REUTLOCK           :1;             /**< REUT lock bit */
+        uint32_t reserved2          :19;
+        uint32_t PMICTL             :1;             /**< PRI Control Select: 0-memory_manager, 1-hte */
+        uint32_t PMIDIS             :1;             /**< PMIDIS Should be set is using IOSF-SB RW */
+        uint32_t DIOIC              :1;             /**< DDRIO initialization is complete */
+        uint32_t IC                 :1;             /**< D-unit Initialization Complete */
+    } field;
+} RegDCO;                                           /**< DRAM Controller Operation Register*/
+#pragma pack()
+
+#pragma pack(1)
+typedef union {
+    uint32_t    raw;
+    struct {
+        uint32_t SBEEN       :1;             /**< Enable Single Bit Error Detection and Correction */
+        uint32_t DBEEN       :1;             /**< Enable Double Bit Error Detection */
+        uint32_t CBOEN       :3;             /**< Enable ECC Check Bits Override */
+        uint32_t SYNSEL      :2;             /**< ECC Syndrome Bits Select for Observation */
+    uint32_t CLRSBECNT   :1;             /**< Clear ECC Single Bit Error Count */
+        uint32_t CBOV        :8;             /**< ECC Check Bits Override Value */
+        uint32_t reserved1   :1;             /**<  */
+        uint32_t ENCBGEN     :1;             /**< Enable Generation of ECC Check Bits */
+        uint32_t ENCBGESWIZ  :1;             /**< Enable Same Chip ECC Byte Lane Swizzle */
+
+    } field;
+} RegDECCCTRL;                                      /**< DRAM ECC Control Register */
+#pragma pack()
+
+
+#pragma pack(1)
+typedef union {
+    uint32_t    raw;
+    struct {
+        uint32_t FUS_DUN_ECC_DIS              :1;
+    uint32_t FUS_DUN_MAX_SUPPORTED_MEMORY :3;
+    uint32_t FUS_DUN_MAX_DEVDEN           :2;
+    uint32_t RESERVED1                    :1;
+    uint32_t FUS_DUN_RANK2_DIS            :1;
+    uint32_t FUS_DUN_OOO_DIS              :1;
+    uint32_t FUS_DUN_MEMX8_DIS            :1;
+    uint32_t FUS_DUN_MEMX16_DIS           :1;
+    uint32_t RESERVED2                    :1;
+    uint32_t FUS_DUN_1N_DIS               :1;
+    uint32_t FUS_DUN_DQ_SCRAMBLER_DIS     :1;
+    uint32_t RESERVED3                    :1;
+    uint32_t FUS_DUN_32BIT_DRAM_IFC       :1;
+    } field;
+} RegDFUSESTAT;
+#pragma pack()
+
+//
+// END DUnit register definition
+//
+////
+
+
+
+////
+//
+// DRAM Initialization Structures used in JEDEC Message Bus Commands
+//
+
+#pragma pack(1)
+typedef union {
+        uint32_t      raw;
+    struct {
+        unsigned    command         :3;             /**< Command: 000-MRS,001-Refresh,010-Pre-charge,011-Activate,110-ZQ,111-NOP */
+        unsigned    bankAddress     :3;             /**< Bank Address (BA[2:0]) */
+        unsigned    BL              :2;             /**< Burst Length, CDV:1*/
+        unsigned    CL              :1;             /**< CL Reserved CDV:0 */
+        unsigned    RBT             :1;             /**< Read Burst Type */
+        unsigned    casLatency      :3;             /**< cas Latency */
+        unsigned    TM              :1;             /**< Test mode */
+        unsigned    dllReset        :1;             /**< DLL Reset */
+        unsigned    writeRecovery   :3;             /**< Write Recovery for Auto Pre-Charge: 001=2,010=3,011=4,100=5,101=6 */
+        unsigned    PPD             :1;             /**< DLL Control for Precharge Power-Down CDV:1 */
+        unsigned    reserved1       :3;
+        unsigned    rankSelect      :4;             /**< Rank Select */
+        unsigned    reserved2       :6;
+    } field;
+} DramInitDDR3MRS0;                                 /**< DDR3 Mode Register Set (MRS) Command */
+#pragma pack()
+
+#pragma pack(1)
+typedef union {
+        uint32_t      raw;
+    struct {
+        unsigned    command         :3;             /**< Command: 000-MRS,001-Refresh,010-Pre-charge,011-Activate,110-ZQ,111-NOP */
+        unsigned    bankAddress     :3;             /**< Bank Address (BA[2:0]) */
+        unsigned    dllEnabled      :1;             /**< CDV=0 */
+        unsigned    DIC0            :1;             /**< Output Driver Impedance Control */
+        unsigned    rttNom0         :1;             /**< RTT_nom[0] */
+        unsigned    MRC_AL          :2;             /**< Additive Latency = 0 */
+        unsigned    DIC1            :1;             /**< Reserved */
+        unsigned    rttNom1         :1;             /**< RTT_nom[1] */
+        unsigned    wlEnabled       :1;             /**< Write Leveling Enable */
+        unsigned    reserved1       :1;
+        unsigned    rttNom2         :1;             /** < RTT_nom[2] */
+        unsigned    reserved2       :1;
+        unsigned    TDQS            :1;             /**< TDQS Enable */
+        unsigned    Qoff            :1;             /**< Output Buffers Disabled */
+        unsigned    reserved3       :3;
+        unsigned    rankSelect      :4;             /**< Rank Select */
+        unsigned    reserved4       :6;
+    } field;
+} DramInitDDR3EMR1;                                 /**< DDR3 Extended Mode Register 1 Set (EMRS1) Command */
+#pragma pack()
+
+#pragma pack(1)
+typedef union {
+        uint32_t      raw;
+    struct {
+        uint32_t    command         :3;             /**< Command: 000-MRS,001-Refresh,010-Pre-charge,011-Activate,110-ZQ,111-NOP */
+        uint32_t    bankAddress     :3;             /**< Bank Address (BA[2:0]) */
+        uint32_t    PASR            :3;             /**< Partial Array Self-Refresh */
+        uint32_t    CWL             :3;             /**< CAS Write Latency */
+        uint32_t    ASR             :1;             /**< Auto Self-Refresh */
+        uint32_t    SRT             :1;             /**< SR Temperature Range = 0*/
+        uint32_t    reserved1       :1;
+        uint32_t    rtt_WR          :2;             /**< Rtt_WR */
+        uint32_t    reserved2       :5;
+        uint32_t    rankSelect      :4;             /**< Rank Select */
+        uint32_t    reserved3       :6;
+    } field;
+} DramInitDDR3EMR2;                                 /**< DDR3 Extended Mode Register 2 Set (EMRS2) Command */
+#pragma pack()
+
+#pragma pack(1)
+typedef union {
+        uint32_t      raw;
+    struct {
+        uint32_t    command         :3;             /**< Command: 000-MRS,001-Refresh,010-Pre-charge,011-Activate,110-ZQ,111-NOP */
+        uint32_t    bankAddress     :3;             /**< Bank Address (BA[2:0]) */
+        uint32_t    MPR_Location    :2;             /**< MPR Location */
+        uint32_t    MPR             :1;             /**< MPR: Multi Purpose Register */
+        uint32_t    reserved1       :13;
+        uint32_t    rankSelect      :4;             /**< Rank Select */
+        uint32_t    reserved2       :6;
+    } field;
+} DramInitDDR3EMR3;                                 /**< DDR3 Extended Mode Register 2 Set (EMRS2) Command */
+#pragma pack()
+
+#pragma pack(1)
+typedef union {
+    uint32_t    raw;
+    struct {
+        uint32_t    command         :3;             /**< Command: 000-MRS,001-Refresh,010-Pre-charge,011-Activate,110 - ZQ Calibration,111-NOP */
+        uint32_t    bankAddress     :3;             /**< Bank Address (BA[2:0]) */
+        uint32_t    multAddress     :16;            /**< Multiplexed Address (MA[14:0]) */
+        uint32_t    rankSelect      :2;             /**< Rank Select */
+        uint32_t    reserved3       :8;
+    } field;
+} DramInitMisc;                                     /**< Miscellaneous DDRx Initialization Command */
+#pragma pack()
+
+//
+// Construct DRAM init command using DramInitXxxx pattern
+//
+#define DCMD_MRS1(rnk,dat) (0 | ((rnk)<<22) | (1<<3) | ((dat)<<6))
+#define DCMD_REF(rnk)      (1 | ((rnk)<<22))
+#define DCMD_PRE(rnk)      (2 | ((rnk)<<22))
+#define DCMD_PREA(rnk)     (2 | ((rnk)<<22) | (BIT10<<6))
+#define DCMD_ACT(rnk,row)  (3 | ((rnk)<<22) | ((row)<<6))
+#define DCMD_WR(rnk,col)   (4 | ((rnk)<<22) | ((col)<<6))
+#define DCMD_RD(rnk,col)   (5 | ((rnk)<<22) | ((col)<<6))
+#define DCMD_ZQCS(rnk)     (6 | ((rnk)<<22))
+#define DCMD_ZQCL(rnk)     (6 | ((rnk)<<22) | (BIT10<<6))
+#define DCMD_NOP(rnk)      (7 | ((rnk)<<22))
+
+
+
+
+#define DDR3_EMRS1_DIC_40       (0)
+#define DDR3_EMRS1_DIC_34       (1)
+
+#define DDR3_EMRS2_RTTWR_60     (BIT9)
+#define DDR3_EMRS2_RTTWR_120    (BIT10)
+
+#define DDR3_EMRS1_RTTNOM_0     (0)
+#define DDR3_EMRS1_RTTNOM_60    (BIT2)
+#define DDR3_EMRS1_RTTNOM_120   (BIT6)
+#define DDR3_EMRS1_RTTNOM_40    (BIT6|BIT2)
+#define DDR3_EMRS1_RTTNOM_20    (BIT9)
+#define DDR3_EMRS1_RTTNOM_30    (BIT9|BIT2)
+
+
+//
+// END DRAM Init...
+//
+////
+
+
+// HOST_BRIDGE registers:
+#define HMBOUND             0x0020  //ok
+
+// MEMORY_MANAGER registers:
+#define BCTRL               0x0004
+#define BWFLUSH             0x0008
+#define BDEBUG1             0x00C4
+
+////
+//
+// BEGIN DDRIO registers
+//
+
+// DDR IOs & COMPs:
+#define DDRIODQ_BL_OFFSET   0x0800
+#define DDRIODQ_CH_OFFSET   ((NUM_BYTE_LANES/2) * DDRIODQ_BL_OFFSET)
+#define DDRIOCCC_CH_OFFSET  0x0800
+#define DDRCOMP_CH_OFFSET   0x0100
+
+// CH0-BL01-DQ
+#define DQOBSCKEBBCTL       0x0000
+#define DQDLLTXCTL          0x0004
+#define DQDLLRXCTL          0x0008
+#define DQMDLLCTL           0x000C
+#define B0RXIOBUFCTL        0x0010
+#define B0VREFCTL           0x0014
+#define B0RXOFFSET1         0x0018
+#define B0RXOFFSET0         0x001C
+#define B1RXIOBUFCTL        0x0020
+#define B1VREFCTL           0x0024
+#define B1RXOFFSET1         0x0028
+#define B1RXOFFSET0         0x002C
+#define DQDFTCTL            0x0030
+#define DQTRAINSTS          0x0034
+#define B1DLLPICODER0       0x0038
+#define B0DLLPICODER0       0x003C
+#define B1DLLPICODER1       0x0040
+#define B0DLLPICODER1       0x0044
+#define B1DLLPICODER2       0x0048
+#define B0DLLPICODER2       0x004C
+#define B1DLLPICODER3       0x0050
+#define B0DLLPICODER3       0x0054
+#define B1RXDQSPICODE       0x0058
+#define B0RXDQSPICODE       0x005C
+#define B1RXDQPICODER32     0x0060
+#define B1RXDQPICODER10     0x0064
+#define B0RXDQPICODER32     0x0068
+#define B0RXDQPICODER10     0x006C
+#define B01PTRCTL0          0x0070
+#define B01PTRCTL1          0x0074
+#define B01DBCTL0           0x0078
+#define B01DBCTL1           0x007C
+#define B0LATCTL0           0x0080
+#define B1LATCTL0           0x0084
+#define B01LATCTL1          0x0088
+#define B0ONDURCTL          0x008C
+#define B1ONDURCTL          0x0090
+#define B0OVRCTL            0x0094
+#define B1OVRCTL            0x0098
+#define DQCTL               0x009C
+#define B0RK2RKCHGPTRCTRL   0x00A0
+#define B1RK2RKCHGPTRCTRL   0x00A4
+#define DQRK2RKCTL          0x00A8
+#define DQRK2RKPTRCTL       0x00AC
+#define B0RK2RKLAT          0x00B0
+#define B1RK2RKLAT          0x00B4
+#define DQCLKALIGNREG0      0x00B8
+#define DQCLKALIGNREG1      0x00BC
+#define DQCLKALIGNREG2      0x00C0
+#define DQCLKALIGNSTS0      0x00C4
+#define DQCLKALIGNSTS1      0x00C8
+#define DQCLKGATE           0x00CC
+#define B0COMPSLV1          0x00D0
+#define B1COMPSLV1          0x00D4
+#define B0COMPSLV2          0x00D8
+#define B1COMPSLV2          0x00DC
+#define B0COMPSLV3          0x00E0
+#define B1COMPSLV3          0x00E4
+#define DQVISALANECR0TOP    0x00E8
+#define DQVISALANECR1TOP    0x00EC
+#define DQVISACONTROLCRTOP  0x00F0
+#define DQVISALANECR0BL     0x00F4
+#define DQVISALANECR1BL     0x00F8
+#define DQVISACONTROLCRBL   0x00FC
+#define DQTIMINGCTRL        0x010C
+// CH0-ECC
+#define ECCDLLTXCTL         0x2004
+#define ECCDLLRXCTL         0x2008
+#define ECCMDLLCTL          0x200C
+#define ECCB1DLLPICODER0    0x2038
+#define ECCB1DLLPICODER1    0x2040
+#define ECCB1DLLPICODER2    0x2048
+#define ECCB1DLLPICODER3    0x2050
+#define ECCB01DBCTL0        0x2078
+#define ECCB01DBCTL1        0x207C
+#define ECCCLKALIGNREG0     0x20B8
+#define ECCCLKALIGNREG1     0x20BC
+#define ECCCLKALIGNREG2     0x20C0
+// CH0-CMD
+#define CMDOBSCKEBBCTL      0x4800
+#define CMDDLLTXCTL         0x4808
+#define CMDDLLRXCTL         0x480C
+#define CMDMDLLCTL          0x4810
+#define CMDRCOMPODT         0x4814
+#define CMDDLLPICODER0      0x4820
+#define CMDDLLPICODER1      0x4824
+#define CMDCFGREG0          0x4840
+#define CMDPTRREG           0x4844
+#define CMDCLKALIGNREG0     0x4850
+#define CMDCLKALIGNREG1     0x4854
+#define CMDCLKALIGNREG2     0x4858
+#define CMDPMCONFIG0        0x485C
+#define CMDPMDLYREG0        0x4860
+#define CMDPMDLYREG1        0x4864
+#define CMDPMDLYREG2        0x4868
+#define CMDPMDLYREG3        0x486C
+#define CMDPMDLYREG4        0x4870
+#define CMDCLKALIGNSTS0     0x4874
+#define CMDCLKALIGNSTS1     0x4878
+#define CMDPMSTS0           0x487C
+#define CMDPMSTS1           0x4880
+#define CMDCOMPSLV          0x4884
+#define CMDBONUS0           0x488C
+#define CMDBONUS1           0x4890
+#define CMDVISALANECR0      0x4894
+#define CMDVISALANECR1      0x4898
+#define CMDVISACONTROLCR    0x489C
+#define CMDCLKGATE          0x48A0
+#define CMDTIMINGCTRL       0x48A4
+// CH0-CLK-CTL
+#define CCOBSCKEBBCTL       0x5800
+#define CCRCOMPIO           0x5804
+#define CCDLLTXCTL          0x5808
+#define CCDLLRXCTL          0x580C
+#define CCMDLLCTL           0x5810
+#define CCRCOMPODT          0x5814
+#define CCDLLPICODER0       0x5820
+#define CCDLLPICODER1       0x5824
+#define CCDDR3RESETCTL      0x5830
+#define CCCFGREG0           0x5838
+#define CCCFGREG1           0x5840
+#define CCPTRREG            0x5844
+#define CCCLKALIGNREG0      0x5850
+#define CCCLKALIGNREG1      0x5854
+#define CCCLKALIGNREG2      0x5858
+#define CCPMCONFIG0         0x585C
+#define CCPMDLYREG0         0x5860
+#define CCPMDLYREG1         0x5864
+#define CCPMDLYREG2         0x5868
+#define CCPMDLYREG3         0x586C
+#define CCPMDLYREG4         0x5870
+#define CCCLKALIGNSTS0      0x5874
+#define CCCLKALIGNSTS1      0x5878
+#define CCPMSTS0            0x587C
+#define CCPMSTS1            0x5880
+#define CCCOMPSLV1          0x5884
+#define CCCOMPSLV2          0x5888
+#define CCCOMPSLV3          0x588C
+#define CCBONUS0            0x5894
+#define CCBONUS1            0x5898
+#define CCVISALANECR0       0x589C
+#define CCVISALANECR1       0x58A0
+#define CCVISACONTROLCR     0x58A4
+#define CCCLKGATE           0x58A8
+#define CCTIMINGCTL         0x58AC
+// COMP
+#define CMPCTRL             0x6800
+#define SOFTRSTCNTL         0x6804
+#define MSCNTR              0x6808
+#define NMSCNTRL            0x680C
+#define LATCH1CTL           0x6814
+#define COMPVISALANECR0     0x681C
+#define COMPVISALANECR1     0x6820
+#define COMPVISACONTROLCR   0x6824
+#define COMPBONUS0          0x6830
+#define TCOCNTCTRL          0x683C
+#define DQANAODTPUCTL       0x6840
+#define DQANAODTPDCTL       0x6844
+#define DQANADRVPUCTL       0x6848
+#define DQANADRVPDCTL       0x684C
+#define DQANADLYPUCTL       0x6850
+#define DQANADLYPDCTL       0x6854
+#define DQANATCOPUCTL       0x6858
+#define DQANATCOPDCTL       0x685C
+#define CMDANADRVPUCTL      0x6868
+#define CMDANADRVPDCTL      0x686C
+#define CMDANADLYPUCTL      0x6870
+#define CMDANADLYPDCTL      0x6874
+#define CLKANAODTPUCTL      0x6880
+#define CLKANAODTPDCTL      0x6884
+#define CLKANADRVPUCTL      0x6888
+#define CLKANADRVPDCTL      0x688C
+#define CLKANADLYPUCTL      0x6890
+#define CLKANADLYPDCTL      0x6894
+#define CLKANATCOPUCTL      0x6898
+#define CLKANATCOPDCTL      0x689C
+#define DQSANAODTPUCTL      0x68A0
+#define DQSANAODTPDCTL      0x68A4
+#define DQSANADRVPUCTL      0x68A8
+#define DQSANADRVPDCTL      0x68AC
+#define DQSANADLYPUCTL      0x68B0
+#define DQSANADLYPDCTL      0x68B4
+#define DQSANATCOPUCTL      0x68B8
+#define DQSANATCOPDCTL      0x68BC
+#define CTLANADRVPUCTL      0x68C8
+#define CTLANADRVPDCTL      0x68CC
+#define CTLANADLYPUCTL      0x68D0
+#define CTLANADLYPDCTL      0x68D4
+#define CHNLBUFSTATIC       0x68F0
+#define COMPOBSCNTRL        0x68F4
+#define COMPBUFFDBG0        0x68F8
+#define COMPBUFFDBG1        0x68FC
+#define CFGMISCCH0          0x6900
+#define COMPEN0CH0          0x6904
+#define COMPEN1CH0          0x6908
+#define COMPEN2CH0          0x690C
+#define STATLEGEN0CH0       0x6910
+#define STATLEGEN1CH0       0x6914
+#define DQVREFCH0           0x6918
+#define CMDVREFCH0          0x691C
+#define CLKVREFCH0          0x6920
+#define DQSVREFCH0          0x6924
+#define CTLVREFCH0          0x6928
+#define TCOVREFCH0          0x692C
+#define DLYSELCH0           0x6930
+#define TCODRAMBUFODTCH0    0x6934
+#define CCBUFODTCH0         0x6938
+#define RXOFFSETCH0         0x693C
+#define DQODTPUCTLCH0       0x6940
+#define DQODTPDCTLCH0       0x6944
+#define DQDRVPUCTLCH0       0x6948
+#define DQDRVPDCTLCH0       0x694C
+#define DQDLYPUCTLCH0       0x6950
+#define DQDLYPDCTLCH0       0x6954
+#define DQTCOPUCTLCH0       0x6958
+#define DQTCOPDCTLCH0       0x695C
+#define CMDDRVPUCTLCH0      0x6968
+#define CMDDRVPDCTLCH0      0x696C
+#define CMDDLYPUCTLCH0      0x6970
+#define CMDDLYPDCTLCH0      0x6974
+#define CLKODTPUCTLCH0      0x6980
+#define CLKODTPDCTLCH0      0x6984
+#define CLKDRVPUCTLCH0      0x6988
+#define CLKDRVPDCTLCH0      0x698C
+#define CLKDLYPUCTLCH0      0x6990
+#define CLKDLYPDCTLCH0      0x6994
+#define CLKTCOPUCTLCH0      0x6998
+#define CLKTCOPDCTLCH0      0x699C
+#define DQSODTPUCTLCH0      0x69A0
+#define DQSODTPDCTLCH0      0x69A4
+#define DQSDRVPUCTLCH0      0x69A8
+#define DQSDRVPDCTLCH0      0x69AC
+#define DQSDLYPUCTLCH0      0x69B0
+#define DQSDLYPDCTLCH0      0x69B4
+#define DQSTCOPUCTLCH0      0x69B8
+#define DQSTCOPDCTLCH0      0x69BC
+#define CTLDRVPUCTLCH0      0x69C8
+#define CTLDRVPDCTLCH0      0x69CC
+#define CTLDLYPUCTLCH0      0x69D0
+#define CTLDLYPDCTLCH0      0x69D4
+#define FNLUPDTCTLCH0       0x69F0
+// PLL
+#define MPLLCTRL0           0x7800
+#define MPLLCTRL1           0x7808
+#define MPLLCSR0            0x7810
+#define MPLLCSR1            0x7814
+#define MPLLCSR2            0x7820
+#define MPLLDFT             0x7828
+#define MPLLMON0CTL         0x7830
+#define MPLLMON1CTL         0x7838
+#define MPLLMON2CTL         0x783C
+#define SFRTRIM             0x7850
+#define MPLLDFTOUT0         0x7858
+#define MPLLDFTOUT1         0x785C
+#define MASTERRSTN          0x7880
+#define PLLLOCKDEL          0x7884
+#define SFRDEL              0x7888
+#define CRUVISALANECR0      0x78F0
+#define CRUVISALANECR1      0x78F4
+#define CRUVISACONTROLCR    0x78F8
+#define IOSFVISALANECR0     0x78FC
+#define IOSFVISALANECR1     0x7900
+#define IOSFVISACONTROLCR   0x7904
+
+//
+// END DDRIO registers
+//
+////
+
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/general_definitions.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/general_definitions.h
new file mode 100644
index 0000000000..1b79ecab2e
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/general_definitions.h
@@ -0,0 +1,84 @@
+/************************************************************************
+ *
+ * Copyright (c) 2013-2015 Intel Corporation.
+ *
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ ************************************************************************/
+#ifndef __GENERAL_DEFINITIONS_H
+#define __GENERAL_DEFINITIONS_H
+
+#undef BIT0
+#undef BIT1
+#undef BIT2
+#undef BIT3
+#undef BIT4
+#undef BIT5
+#undef BIT6
+#undef BIT7
+#undef BIT8
+#undef BIT9
+#undef BIT10
+#undef BIT11
+#undef BIT12
+#undef BIT13
+#undef BIT14
+#undef BIT15
+#undef BIT16
+#undef BIT17
+#undef BIT18
+#undef BIT19
+#undef BIT20
+#undef BIT21
+#undef BIT22
+#undef BIT23
+#undef BIT24
+#undef BIT25
+#undef BIT26
+#undef BIT27
+#undef BIT28
+#undef BIT29
+#undef BIT30
+#undef BIT31
+
+
+
+// defines
+#define BIT0  0x00000001U
+#define BIT1  0x00000002U
+#define BIT2  0x00000004U
+#define BIT3  0x00000008U
+#define BIT4  0x00000010U
+#define BIT5  0x00000020U
+#define BIT6  0x00000040U
+#define BIT7  0x00000080U
+#define BIT8  0x00000100U
+#define BIT9  0x00000200U
+#define BIT10 0x00000400U
+#define BIT11 0x00000800U
+#define BIT12 0x00001000U
+#define BIT13 0x00002000U
+#define BIT14 0x00004000U
+#define BIT15 0x00008000U
+#define BIT16 0x00010000U
+#define BIT17 0x00020000U
+#define BIT18 0x00040000U
+#define BIT19 0x00080000U
+#define BIT20 0x00100000U
+#define BIT21 0x00200000U
+#define BIT22 0x00400000U
+#define BIT23 0x00800000U
+#define BIT24 0x01000000U
+#define BIT25 0x02000000U
+#define BIT26 0x04000000U
+#define BIT27 0x08000000U
+#define BIT28 0x10000000U
+#define BIT29 0x20000000U
+#define BIT30 0x40000000U
+#define BIT31 0x80000000U
+
+
+#define true  0x01
+#define false 0x00
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/hte.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/hte.c
new file mode 100644
index 0000000000..718fac12b8
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/hte.c
@@ -0,0 +1,536 @@
+/** @file
+HTE handling routines for MRC use.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "mrc.h"
+#include "memory_options.h"
+#include "io.h"
+
+#include "hte.h"
+
+
+#ifdef SIM
+VOID delay_n(UINT32 nanoseconds);
+#define MySimStall(a)   delay_n(a/1000)
+#endif
+
+STATIC VOID EnableAllHteErrors(
+    UINT8 Mask)
+/*++
+
+ Routine Description:
+
+ This function enables to HTE to detect all possible errors for
+ the given training parameters (per-bit or full byte lane).
+
+ Returns:
+
+ None
+
+ --*/
+{
+  isbW32m(HTE, 0x000200A2, 0xFFFFFFFF);
+  isbW32m(HTE, 0x000200A3, 0x000000FF);
+  isbW32m(HTE, 0x000200A4, 0x00000000);
+}
+
+STATIC UINT32 CheckHteErrors(
+    VOID)
+/*++
+
+ Routine Description:
+
+ This function goes and reads the HTE register in order to find any error
+
+ Returns:
+
+ The errors detected in the HTE status register
+
+ --*/
+{
+  return isbR32m(HTE, 0x000200A7);
+}
+
+STATIC VOID WaitForHteComplete(
+    VOID)
+/*++
+
+ Routine Description:
+
+ This function waits until HTE finishes
+
+ Returns:
+
+ None
+
+ --*/
+{
+  UINT32 Tmp;
+
+  ENTERFN();
+
+  //
+  // Is the test done?
+  //
+  do
+  {
+#ifdef SIM
+    MySimStall (35000); // 35 ns delay
+#endif
+  } while (0 != (isbR32m(HTE, 0x00020012) & BIT30));
+
+  Tmp = isbR32m(HTE, 0x00020011);
+  Tmp = Tmp | BIT9;
+  Tmp = Tmp & ~(BIT13 | BIT12);
+  isbW32m(HTE, 0x00020011, Tmp);
+
+  LEAVEFN();
+}
+
+STATIC VOID ClearHteErrorRegisters(
+    VOID)
+/*++
+
+ Routine Description:
+
+ Clears registers related with errors in the HTE.
+
+ Returns:
+
+ None
+
+ --*/
+{
+  UINT32 Tmp;
+
+  //
+  // Clear all HTE errors and enable error checking
+  // for burst and chunk.
+  //
+  Tmp = isbR32m(HTE, 0x000200A1);
+  Tmp |= BIT8;
+  isbW32m(HTE, 0x000200A1, Tmp);
+}
+
+UINT32 HteMemInit(
+    MRC_PARAMS *CurrentMrcData,
+    UINT8 MemInitFlag,
+    UINT8 HaltHteEngineOnError)
+
+/*++
+
+ Routine Description:
+
+ Uses HW HTE engine to initialize or test all memory attached to a given DUNIT.
+ If MemInitFlag is 1, this routine writes 0s to all memory locations to initialize
+ ECC.
+ If MemInitFlag is 0, this routine will send an 5AA55AA5 pattern to all memory
+ locations on the RankMask and then read it back.  Then it sends an A55AA55A
+ pattern to all memory locations on the RankMask and reads it back.
+
+ Arguments:
+
+ CurrentMrcData: Host struture for all MRC global data.
+ MemInitFlag: 0 for memtest, 1 for meminit.
+ HaltHteEngineOnError:  Halt the HTE engine on first error observed, or keep
+ running to see how many errors are found.
+
+ Returns:
+ Errors register showing HTE failures.
+ Also prints out which rank failed the HTE test if failure occurs.
+ For rank detection to work, the address map must be left in its default
+ state.  If MRC changes the address map, this function must be modified
+ to change it back to default at the beginning, then restore it at the end.
+
+ --*/
+{
+  UINT32 Offset;
+  UINT8 TestNum;
+  UINT8 i;
+
+  //
+  // Clear out the error registers at the start of each memory
+  // init or memory test run.
+  //
+  ClearHteErrorRegisters();
+
+  isbW32m(HTE, 0x00020062, 0x00000015);
+
+  for (Offset = 0x80; Offset <= 0x8F; Offset++)
+  {
+    isbW32m(HTE, Offset, ((Offset & 1) ? 0xA55A : 0x5AA5));
+  }
+
+  isbW32m(HTE, 0x00020021, 0x00000000);
+#ifdef QUICKSIM
+  // Just do 4 cache lines for simulation memtest to save time.
+  isbW32m(HTE, 0x00020022, 4-1);
+#else
+  isbW32m(HTE, 0x00020022, (CurrentMrcData->mem_size >> 6) - 1);
+#endif
+
+  isbW32m(HTE, 0x00020063, 0xAAAAAAAA);
+  isbW32m(HTE, 0x00020064, 0xCCCCCCCC);
+  isbW32m(HTE, 0x00020065, 0xF0F0F0F0);
+  isbW32m(HTE, 0x00020066, 0x03000000);
+
+  switch (MemInitFlag)
+  {
+  case MrcMemInit:
+    TestNum = 1; // Only 1 write pass through memory is needed to initialize ECC.
+    break;
+  case MrcMemTest:
+    TestNum = 4; // Write/read then write/read with inverted pattern.
+    break;
+  default:
+    DPF(D_INFO, "Unknown parameter for MemInitFlag: %d\n", MemInitFlag);
+    return 0xFFFFFFFF;
+    break;
+  }
+
+  DPF(D_INFO, "HteMemInit");
+  for (i = 0; i < TestNum; i++)
+  {
+    DPF(D_INFO, ".");
+
+    if (i == 0)
+    {
+      isbW32m(HTE, 0x00020061, 0x00000000);
+      isbW32m(HTE, 0x00020020, 0x00110010);
+    }
+    else if (i == 1)
+    {
+      isbW32m(HTE, 0x00020061, 0x00000000);
+      isbW32m(HTE, 0x00020020, 0x00010010);
+    }
+    else if (i == 2)
+    {
+      isbW32m(HTE, 0x00020061, 0x00010100);
+      isbW32m(HTE, 0x00020020, 0x00110010);
+    }
+    else
+    {
+      isbW32m(HTE, 0x00020061, 0x00010100);
+      isbW32m(HTE, 0x00020020, 0x00010010);
+    }
+
+    isbW32m(HTE, 0x00020011, 0x00111000);
+    isbW32m(HTE, 0x00020011, 0x00111100);
+
+    WaitForHteComplete();
+
+    //
+    // If this is a READ pass, check for errors at the end.
+    //
+    if ((i % 2) == 1)
+    {
+      //
+      // Return immediately if  error.
+      //
+      if (CheckHteErrors())
+      {
+        break;
+      }
+    }
+  }
+
+  DPF(D_INFO, "done\n", i);
+  return CheckHteErrors();
+}
+
+STATIC UINT16 BasicDataCompareHte(
+    MRC_PARAMS *CurrentMrcData,
+    UINT32 Address,
+    UINT8 FirstRun,
+    UINT8 Mode)
+/*++
+
+ Routine Description:
+
+ Execute basic single cache line memory write/read/verify test using simple constant
+ pattern (different for READ_RAIN and WRITE_TRAIN modes.
+ See BasicWriteReadHTE which is external visible wrapper.
+
+ Arguments:
+
+ CurrentMrcData: Host struture for all MRC global data.
+ Address: memory adress being tested (must hit specific channel/rank)
+ FirstRun: If set then hte registers are configured, otherwise
+ it is assumed configuration is done and just re-run the test.
+ Mode: READ_TRAIN or WRITE_TRAIN (the difference is in the pattern)
+
+ Returns:
+ Returns byte lane failure on each bit (for Quark only bit0 and bit1)
+
+ --*/
+{
+  UINT32 Pattern;
+  UINT32 Offset;
+
+  if (FirstRun)
+  {
+    isbW32m(HTE, 0x00020020, 0x01B10021);
+    isbW32m(HTE, 0x00020021, 0x06000000);
+    isbW32m(HTE, 0x00020022, Address >> 6);
+    isbW32m(HTE, 0x00020062, 0x00800015);
+    isbW32m(HTE, 0x00020063, 0xAAAAAAAA);
+    isbW32m(HTE, 0x00020064, 0xCCCCCCCC);
+    isbW32m(HTE, 0x00020065, 0xF0F0F0F0);
+    isbW32m(HTE, 0x00020061, 0x00030008);
+
+    if (Mode == WRITE_TRAIN)
+    {
+      Pattern = 0xC33C0000;
+    }
+    else // READ_TRAIN
+    {
+      Pattern = 0xAA5555AA;
+    }
+
+    for (Offset = 0x80; Offset <= 0x8F; Offset++)
+    {
+      isbW32m(HTE, Offset, Pattern);
+    }
+  }
+
+  isbW32m(HTE, 0x000200A1, 0xFFFF1000);
+
+  isbW32m(HTE, 0x00020011, 0x00011000);
+  isbW32m(HTE, 0x00020011, 0x00011100);
+
+  WaitForHteComplete();
+
+  //
+  // Return bits 15:8 of HTE_CH0_ERR_XSTAT to check for any bytelane errors.
+  //
+  return ((CheckHteErrors() >> 8) & 0xFF);
+}
+
+STATIC UINT16 ReadWriteDataCompareHte(
+    MRC_PARAMS *CurrentMrcData,
+    UINT32 Address,
+    UINT8 LoopCount,
+    UINT32 LfsrSeedVictim,
+    UINT32 LfsrSeedAggressor,
+    UINT8 VictimBit,
+    UINT8 FirstRun)
+/*++
+
+ Routine Description:
+
+ Examines single cache line memory with write/read/verify test using
+ multiple data patterns (victim-aggressor algorithm).
+ See WriteStressBitLanesHTE which is external visible wrapper.
+
+ Arguments:
+
+ CurrentMrcData: host struture for all MRC global data.
+ Address: memory adress being tested (must hit specific channel/rank)
+ LoopCount: number of test iterations
+ LfsrSeedXxx: victim aggressor data pattern seed
+ VictimBit: should be 0 as auto rotate feature is in use.
+ FirstRun: If set then hte registers are configured, otherwise
+ it is assumed configuration is done and just re-run the test.
+
+ Returns:
+ Returns byte lane failure on each bit (for Quark only bit0 and bit1)
+
+ --*/
+{
+  UINT32 Offset;
+  UINT32 Tmp;
+
+  if (FirstRun)
+  {
+    isbW32m(HTE, 0x00020020, 0x00910024);
+    isbW32m(HTE, 0x00020023, 0x00810024);
+    isbW32m(HTE, 0x00020021, 0x06070000);
+    isbW32m(HTE, 0x00020024, 0x06070000);
+    isbW32m(HTE, 0x00020022, Address >> 6);
+    isbW32m(HTE, 0x00020025, Address >> 6);
+    isbW32m(HTE, 0x00020062, 0x0000002A);
+    isbW32m(HTE, 0x00020063, LfsrSeedVictim);
+    isbW32m(HTE, 0x00020064, LfsrSeedAggressor);
+    isbW32m(HTE, 0x00020065, LfsrSeedVictim);
+
+    //
+    // Write the pattern buffers to select the victim bit. Start with bit0.
+    //
+    for (Offset = 0x80; Offset <= 0x8F; Offset++)
+    {
+      if ((Offset % 8) == VictimBit)
+      {
+        isbW32m(HTE, Offset, 0x55555555);
+      }
+      else
+      {
+        isbW32m(HTE, Offset, 0xCCCCCCCC);
+      }
+    }
+
+    isbW32m(HTE, 0x00020061, 0x00000000);
+    isbW32m(HTE, 0x00020066, 0x03440000);
+    isbW32m(HTE, 0x000200A1, 0xFFFF1000);
+  }
+
+  Tmp = 0x10001000 | (LoopCount << 16);
+  isbW32m(HTE, 0x00020011, Tmp);
+  isbW32m(HTE, 0x00020011, Tmp | BIT8);
+
+  WaitForHteComplete();
+
+  return (CheckHteErrors() >> 8) & 0xFF;
+}
+
+UINT16 BasicWriteReadHTE(
+    MRC_PARAMS *CurrentMrcData,
+    UINT32 Address,
+    UINT8 FirstRun,
+    UINT8 Mode)
+/*++
+
+ Routine Description:
+
+ Execute basic single cache line memory write/read/verify test using simple constant
+ pattern (different for READ_RAIN and WRITE_TRAIN modes.
+
+ Arguments:
+
+ CurrentMrcData: Host struture for all MRC global data.
+ Address: memory adress being tested (must hit specific channel/rank)
+ FirstRun: If set then hte registers are configured, otherwise
+ it is assumed configuration is done and just re-run the test.
+ Mode: READ_TRAIN or WRITE_TRAIN (the difference is in the pattern)
+
+ Returns:
+ Returns byte lane failure on each bit (for Quark only bit0 and bit1)
+
+ --*/
+{
+  UINT16 ByteLaneErrors;
+
+  ENTERFN();
+
+  //
+  // Enable all error reporting in preparation for HTE test.
+  //
+  EnableAllHteErrors(0xFF);
+  ClearHteErrorRegisters();
+
+  ByteLaneErrors = BasicDataCompareHte(CurrentMrcData, Address, FirstRun,
+      Mode);
+
+  LEAVEFN();
+  return ByteLaneErrors;
+}
+
+UINT16 WriteStressBitLanesHTE(
+    MRC_PARAMS *CurrentMrcData,
+    UINT32 Address,
+    UINT8 FirstRun)
+/*++
+
+ Routine Description:
+
+ Examines single cache line memory with write/read/verify test using
+ multiple data patterns (victim-aggressor algorithm).
+
+ Arguments:
+
+ CurrentMrcData: host struture for all MRC global data.
+ Address: memory adress being tested (must hit specific channel/rank)
+ FirstRun: If set then hte registers are configured, otherwise
+ it is assumed configuration is done and just re-run the test.
+
+ Returns:
+ Returns byte lane failure on each bit (for Quark only bit0 and bit1)
+
+ --*/
+{
+  UINT16 ByteLaneErrors;
+  UINT8 VictimBit = 0;
+
+  ENTERFN();
+
+  //
+  // Enable all error reporting in preparation for HTE test.
+  //
+  EnableAllHteErrors(0xFF);
+  ClearHteErrorRegisters();
+
+  //
+  // Loop through each bit in the bytelane.  Each pass creates a victim bit
+  // while keeping all other bits the same - as aggressors.
+  // AVN HTE adds an auto-rotate feature which allows us to program the entire victim/aggressor
+  // sequence in 1 step. The victim bit rotates on each pass so no need to have software implement
+  // a victim bit loop like on VLV.
+  //
+  ByteLaneErrors = ReadWriteDataCompareHte(CurrentMrcData, Address,
+      HTE_LOOP_CNT, HTE_LFSR_VICTIM_SEED, HTE_LFSR_AGRESSOR_SEED, VictimBit,
+      FirstRun);
+
+  LEAVEFN();
+  return ByteLaneErrors;
+}
+
+VOID HteMemOp(
+    UINT32 Address,
+    UINT8 FirstRun,
+    UINT8 IsWrite)
+/*++
+
+ Routine Description:
+
+ Execute basic single cache line memory write or read.
+ This is just for receive enable / fine write levelling purpose.
+
+ Arguments:
+
+ CurrentMrcData: Host structure for all MRC global data.
+ Address: memory address used (must hit specific channel/rank)
+ FirstRun: If set then hte registers are configured, otherwise
+ it is assumed configuration is done and just re-run the test.
+ IsWrite: When non-zero memory write operation executed, otherwise read
+
+ Returns:
+ None
+
+ --*/
+{
+  UINT32 Offset;
+  UINT32 Tmp;
+
+  EnableAllHteErrors(0xFF);
+  ClearHteErrorRegisters();
+
+  if (FirstRun)
+  {
+    Tmp = IsWrite ? 0x01110021 : 0x01010021;
+    isbW32m(HTE, 0x00020020, Tmp);
+
+    isbW32m(HTE, 0x00020021, 0x06000000);
+    isbW32m(HTE, 0x00020022, Address >> 6);
+    isbW32m(HTE, 0x00020062, 0x00800015);
+    isbW32m(HTE, 0x00020063, 0xAAAAAAAA);
+    isbW32m(HTE, 0x00020064, 0xCCCCCCCC);
+    isbW32m(HTE, 0x00020065, 0xF0F0F0F0);
+    isbW32m(HTE, 0x00020061, 0x00030008);
+
+    for (Offset = 0x80; Offset <= 0x8F; Offset++)
+    {
+      isbW32m(HTE, Offset, 0xC33C0000);
+    }
+  }
+
+  isbW32m(HTE, 0x000200A1, 0xFFFF1000);
+  isbW32m(HTE, 0x00020011, 0x00011000);
+  isbW32m(HTE, 0x00020011, 0x00011100);
+
+  WaitForHteComplete();
+}
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/hte.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/hte.h
new file mode 100644
index 0000000000..1ad13342af
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/hte.h
@@ -0,0 +1,66 @@
+/** @file
+HTE handling routines for MRC use.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef __HTE_H
+#define __HTE_H
+
+#define STATIC   static
+#define VOID     void
+
+#if !defined(__GNUC__) && (__STDC_VERSION__ < 199901L)
+typedef uint32_t UINT32;
+typedef uint16_t UINT16;
+typedef uint8_t UINT8;
+#endif
+
+typedef enum
+{
+  MrcNoHaltSystemOnError,
+  MrcHaltSystemOnError,
+  MrcHaltHteEngineOnError,
+  MrcNoHaltHteEngineOnError
+} HALT_TYPE;
+
+typedef enum
+{
+  MrcMemInit, MrcMemTest
+} MEM_INIT_OR_TEST;
+
+#define READ_TRAIN      1
+#define WRITE_TRAIN     2
+
+#define HTE_MEMTEST_NUM                 2
+#define HTE_LOOP_CNT                    5  // EXP_LOOP_CNT field of HTE_CMD_CTL. This CANNOT be less than 4
+#define HTE_LFSR_VICTIM_SEED   0xF294BA21  // Random seed for victim.
+#define HTE_LFSR_AGRESSOR_SEED 0xEBA7492D  // Random seed for aggressor.
+UINT32
+HteMemInit(
+    MRC_PARAMS *CurrentMrcData,
+    UINT8 MemInitFlag,
+    UINT8 HaltHteEngineOnError);
+
+UINT16
+BasicWriteReadHTE(
+    MRC_PARAMS *CurrentMrcData,
+    UINT32 Address,
+    UINT8 FirstRun,
+    UINT8 Mode);
+
+UINT16
+WriteStressBitLanesHTE(
+    MRC_PARAMS *CurrentMrcData,
+    UINT32 Address,
+    UINT8 FirstRun);
+
+VOID
+HteMemOp(
+    UINT32 Address,
+    UINT8 FirstRun,
+    UINT8 IsWrite);
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/io.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/io.h
new file mode 100644
index 0000000000..e2f7916014
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/io.h
@@ -0,0 +1,132 @@
+/** @file
+Declaration of IO handling routines.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef __IO_H
+#define __IO_H
+
+#include "core_types.h"
+
+#include "general_definitions.h"
+#include "gen5_iosf_sb_definitions.h"
+
+// Instruction not present on Quark
+#define SFENCE()
+
+#define DEAD_LOOP()   for(;;);
+
+////
+// Define each of the IOSF_SB ports used by MRC
+//
+
+//
+// Has to be 0 because of emulation static data
+// initialisation:
+//   Space_t EmuSpace[ SPACE_COUNT] = {0};
+//
+#define FREE                0x000
+
+// Pseudo side-band ports for access abstraction
+// See Wr32/Rd32 functions
+#define MEM                 0x101
+#define MMIO                0x102
+#define DCMD                0x0A0
+
+// Real side-band ports
+// See Wr32/Rd32 functions
+#define MCU                 0x001
+#define HOST_BRIDGE               0x003
+#define MEMORY_MANAGER               0x005
+#define HTE                0x011
+#define DDRPHY              0x012
+#define FUSE                0x033
+
+// End of IOSF_SB ports
+////
+
+// Pciexbar address
+#define EC_BASE          0xE0000000
+
+#define PCIADDR(bus,dev,fn,reg) ( \
+        (EC_BASE) + \
+    ((bus) << 20) + \
+    ((dev) << 15) + \
+    ((fn)  << 12) + \
+    (reg))
+
+// Various offsets used in the building sideband commands.
+#define SB_OPCODE_OFFSET      24
+#define SB_PORT_OFFSET        16
+#define SB_REG_OFFEST          8
+
+// Sideband opcodes
+#define SB_REG_READ_OPCODE        0x10
+#define SB_REG_WRITE_OPCODE       0x11
+
+#define SB_FUSE_REG_READ_OPCODE    0x06
+#define SB_FUSE_REG_WRITE_OPCODE  0x07
+
+#define SB_DDRIO_REG_READ_OPCODE  0x06
+#define SB_DDRIO_REG_WRITE_OPCODE 0x07
+
+#define SB_DRAM_CMND_OPCODE       0x68
+#define SB_WAKE_CMND_OPCODE       0xCA
+#define SB_SUSPEND_CMND_OPCODE    0xCC
+
+// Register addresses for sideband command and data.
+#define SB_PACKET_REG        0x00D0
+#define SB_DATA_REG          0x00D4
+#define SB_HADR_REG          0x00D8
+
+// We always flag all 4 bytes in the register reads/writes as required.
+#define SB_ALL_BYTES_ENABLED  0xF0
+
+#define SB_COMMAND(Opcode, Port, Reg)  \
+ ((Opcode << SB_OPCODE_OFFSET) |  \
+  (Port   << SB_PORT_OFFSET) |  \
+  (Reg    << SB_REG_OFFEST) |  \
+   SB_ALL_BYTES_ENABLED)
+
+// iosf
+#define isbM32m   WrMask32
+#define isbW32m   Wr32
+#define isbR32m   Rd32
+
+// pci
+
+void pciwrite32(
+    uint32_t bus,
+    uint32_t dev,
+    uint32_t fn,
+    uint32_t reg,
+    uint32_t data);
+
+uint32_t pciread32(
+    uint32_t bus,
+    uint32_t dev,
+    uint32_t fn,
+    uint32_t reg);
+
+// general
+
+uint32_t Rd32(
+    uint32_t unit,
+    uint32_t addr);
+
+void Wr32(
+    uint32_t unit,
+    uint32_t addr,
+    uint32_t data);
+
+void WrMask32(
+    uint32_t unit,
+    uint32_t addr,
+    uint32_t data,
+    uint32_t mask);
+
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/lprint.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/lprint.c
new file mode 100644
index 0000000000..21d935bc65
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/lprint.c
@@ -0,0 +1,382 @@
+/** @file
+Serial conole output and string formating.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "memory_options.h"
+#include "general_definitions.h"
+
+// Resource programmed to PCI bridge, 1MB bound alignment is needed.
+// The default value is overwritten by MRC parameter, assuming code
+// relocated to eSRAM.
+uint32_t UartMmioBase = 0;
+
+// Serial port registers based on SerialPortLib.c
+#define R_UART_BAUD_THR       0
+#define R_UART_LSR            20
+
+#define   B_UART_LSR_RXRDY    BIT0
+#define   B_UART_LSR_TXRDY    BIT5
+#define   B_UART_LSR_TEMT     BIT6
+
+// Print mask see DPF and D_Xxxx
+#define DPF_MASK  DpfPrintMask
+
+// Select class of messages enabled for printing
+uint32_t DpfPrintMask =
+    D_ERROR |
+    D_INFO |
+    // D_REGRD |
+    // D_REGWR |
+    // D_FCALL |
+    // D_TRN |
+    0;
+
+#ifdef NDEBUG
+// Don't generate debug code
+void dpf( uint32_t mask, char_t* bla, ...)
+{
+  return;
+}
+
+uint8_t mgetc(void)
+{
+  return 0;
+}
+
+uint8_t mgetch(void)
+{
+  return 0;
+}
+
+#else
+
+#ifdef SIM
+// Use Vpi console in simulation environment
+#include <vpi_user.h>
+
+void dpf( uint32_t mask, char_t* bla, ...)
+{
+  va_list va;
+
+  if( 0 == (mask & DPF_MASK)) return;
+
+  va_start( va, bla);
+  vpi_vprintf( bla, va);
+  va_end(va);
+}
+
+#else
+
+#ifdef EMU
+// Use standard console in windows environment
+#include <stdio.h>
+#endif
+
+// Read character from serial port
+uint8_t mgetc(void)
+{
+#ifdef EMU
+
+  // Emulation in Windows environment uses console
+  getchar();
+
+#else
+  uint8_t c;
+
+  while ((*(volatile uint8_t*) (UartMmioBase + R_UART_LSR) & B_UART_LSR_RXRDY) == 0);
+  c = *(volatile uint8_t*) (UartMmioBase + R_UART_BAUD_THR);
+
+  return c;
+#endif
+}
+
+
+uint8_t mgetch(void)
+{
+#ifdef EMU
+  return 0;
+#else
+  uint8_t c = 0;
+
+  if((*(volatile uint8_t*) (UartMmioBase + R_UART_LSR) & B_UART_LSR_RXRDY) != 0)
+  {
+    c = *(volatile uint8_t*) (UartMmioBase + R_UART_BAUD_THR);
+  }
+
+  return c;
+#endif
+}
+
+// Print single character
+static void printc(
+    uint8_t c)
+{
+#ifdef EMU
+
+  // Emulation in Windows environment uses console output
+  putchar(c);
+
+#else
+
+  //
+  // Use MMIO access to serial port on PCI
+  //   while( 0 == (0x20 & inp(0x3f8 + 5)));
+  //   outp(0x3f8 + 0, c);
+  //
+  while (0
+      == (B_UART_LSR_TEMT & *((volatile uint8_t*) (UartMmioBase + R_UART_LSR))))
+    ;
+  *((volatile uint8_t*) (UartMmioBase + R_UART_BAUD_THR)) = c;
+#endif
+}
+
+// Print 0 terminated string on serial console
+static void printstr(
+    char_t *str)
+{
+  while (*str)
+  {
+    printc(*str++);
+  }
+}
+// Print 64bit number as hex string on serial console
+// the width parameters allows skipping leading zeros
+static void printhexx(
+    uint64_t val,
+    uint32_t width)
+{
+  uint32_t i;
+  uint8_t c;
+  uint8_t empty = 1;
+
+  // 64bit number has 16 characters in hex representation
+  for (i = 16; i > 0; i--)
+  {
+    c = *(((uint8_t *)&val) + ((i - 1) >> 1));
+    if (((i - 1) & 1) != 0)
+      c = c >> 4;
+    c = c & 0x0F;
+
+    if (c > 9)
+      c += 'A' - 10;
+    else
+      c += '0';
+
+    if (c != '0')
+    {
+      // end of leading zeros
+      empty = 0;
+    }
+
+    // don't print leading zero
+    if (!empty || i <= width)
+    {
+      printc(c);
+    }
+  }
+}
+// Print 32bit number as hex string on serial console
+// the width parameters allows skipping leading zeros
+static void printhex(
+    uint32_t val,
+    uint32_t width)
+{
+  uint32_t i;
+  uint8_t c;
+  uint8_t empty = 1;
+
+  // 32bit number has 8 characters in hex representation
+  for (i = 8; i > 0; i--)
+  {
+    c = (uint8_t) ((val >> 28) & 0x0F);
+    if (c > 9)
+      c += 'A' - 10;
+    else
+      c += '0';
+
+    val = val << 4;
+
+    if (c != '0')
+    {
+      // end of leading zeros
+      empty = 0;
+    }
+
+    // don't print leading zero
+    if (!empty || i <= width)
+    {
+      printc(c);
+    }
+  }
+}
+// Print 32bit number as decimal string on serial console
+// the width parameters allows skipping leading zeros
+static void printdec(
+    uint32_t val,
+    uint32_t width)
+{
+  uint32_t i;
+  uint8_t c = 0;
+  uint8_t empty = 1;
+
+  // Ten digits is enough for 32bit number in decimal
+  uint8_t buf[10];
+
+  for (i = 0; i < sizeof(buf); i++)
+  {
+    c = (uint8_t) (val % 10);
+    buf[i] = c + '0';
+    val = val / 10;
+  }
+
+  while (i > 0)
+  {
+    c = buf[--i];
+
+    if (c != '0')
+    {
+      // end of leading zeros
+      empty = 0;
+    }
+
+    // don't print leading zero
+    if (!empty || i < width)
+    {
+      printc(c);
+    }
+  }
+}
+
+// Consume numeric substring leading the given string
+// Return pointer to the first non-numeric character
+// Buffer reference by width is updated with number
+// converted from the numeric substring.
+static char_t *getwidth(
+    char_t *bla,
+    uint32_t *width)
+{
+  uint32_t val = 0;
+
+  while (*bla >= '0' && *bla <= '9')
+  {
+    val = val * 10 + *bla - '0';
+    bla += 1;
+  }
+
+  if (val > 0)
+  {
+    *width = val;
+  }
+  return bla;
+}
+
+// Consume print format designator from the head of given string
+// Return pointer to first character after format designator
+// input fmt
+// ----- ---
+//  s   -> s
+//  d   -> d
+//  X   -> X
+//  llX -> L
+static char_t *getformat(
+    char_t *bla,
+    uint8_t *fmt)
+{
+  if (bla[0] == 's')
+  {
+    bla += 1;
+    *fmt = 's';
+  }
+  else if (bla[0] == 'd')
+  {
+    bla += 1;
+    *fmt = 'd';
+  }
+  else if (bla[0] == 'X' || bla[0] == 'x')
+  {
+    bla += 1;
+    *fmt = 'X';
+  }
+  else if (bla[0] == 'l' && bla[1] == 'l' && bla[2] == 'X')
+  {
+    bla += 3;
+    *fmt = 'L';
+  }
+
+  return bla;
+}
+
+// Simplified implementation of standard printf function
+// The output is directed to serial console. Only selected
+// class of messages is printed (mask has to match DpfPrintMask)
+// Supported print formats: %[n]s,%[n]d,%[n]X,,%[n]llX
+// The width is ignored for %s format.
+void dpf(
+    uint32_t mask,
+    char_t* bla,
+    ...)
+{
+  uint32_t* arg = (uint32_t*) (&bla + 1);
+
+  // Check UART MMIO base configured
+  if (0 == UartMmioBase)
+    return;
+
+  // Check event not masked
+  if (0 == (mask & DPF_MASK))
+    return;
+
+  for (;;)
+  {
+    uint8_t x = *bla++;
+    if (x == 0)
+      break;
+
+    if (x == '\n')
+    {
+      printc('\r');
+      printc('\n');
+    }
+    else if (x == '%')
+    {
+      uint8_t fmt = 0;
+      uint32_t width = 1;
+
+      bla = getwidth(bla, &width);
+      bla = getformat(bla, &fmt);
+
+      // Print value
+      if (fmt == 'd')
+      {
+        printdec(*arg, width);
+        arg += 1;
+      }
+      else if (fmt == 'X')
+      {
+        printhex(*arg, width);
+        arg += 1;
+      }
+      else if (fmt == 'L')
+      {
+        printhexx(*(uint64_t*) arg, width);
+        arg += 2;
+      }
+      else if (fmt == 's')
+      {
+        printstr(*(char**) arg);
+        arg += 1;
+      }
+    }
+    else
+    {
+      printc(x);
+    }
+  }
+}
+
+#endif  //SIM
+#endif  //NDEBUG
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit.c
new file mode 100644
index 0000000000..64f0a1130e
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit.c
@@ -0,0 +1,2638 @@
+/************************************************************************
+ *
+ * Copyright (c) 2013-2015 Intel Corporation.
+ *
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ * This file contains all of the Cat Mountain Memory Reference Code (MRC).
+ *
+ * These functions are generic and should work for any Cat Mountain config.
+ *
+ * MRC requires two data structures to be passed in which are initialised by "PreMemInit()".
+ *
+ * The basic flow is as follows:
+ * 01) Check for supported DDR speed configuration
+ * 02) Set up MEMORY_MANAGER buffer as pass-through (POR)
+ * 03) Set Channel Interleaving Mode and Channel Stride to the most aggressive setting possible
+ * 04) Set up the MCU logic
+ * 05) Set up the DDR_PHY logic
+ * 06) Initialise the DRAMs (JEDEC)
+ * 07) Perform the Receive Enable Calibration algorithm
+ * 08) Perform the Write Leveling algorithm
+ * 09) Perform the Read Training algorithm (includes internal Vref)
+ * 10) Perform the Write Training algorithm
+ * 11) Set Channel Interleaving Mode and Channel Stride to the desired settings
+ *
+ * Dunit configuration based on Valleyview MRC.
+ *
+ ***************************************************************************/
+
+#include "mrc.h"
+#include "memory_options.h"
+
+#include "meminit.h"
+#include "meminit_utils.h"
+#include "hte.h"
+#include "io.h"
+
+// Override ODT to off state if requested
+#define DRMC_DEFAULT    (mrc_params->rd_odt_value==0?BIT12:0)
+
+
+// tRFC values (in picoseconds) per density
+const uint32_t tRFC[5] =
+{
+    90000,  // 512Mb
+    110000, // 1Gb
+    160000, // 2Gb
+    300000, // 4Gb
+    350000, // 8Gb
+    };
+
+// tCK clock period in picoseconds per speed index 800, 1066, 1333
+const uint32_t tCK[3] =
+{
+    2500,
+    1875,
+    1500
+};
+
+#ifdef SIM
+// Select static timings specific to simulation environment
+#define PLATFORM_ID    0
+#else
+// Select static timings specific to ClantonPeek platform
+#define PLATFORM_ID    1
+#endif
+
+
+// Global variables
+const uint16_t ddr_wclk[] =
+    {193, 158};
+
+const uint16_t ddr_wctl[] =
+    {  1, 217};
+
+const uint16_t ddr_wcmd[] =
+    {  1, 220};
+
+
+#ifdef BACKUP_RCVN
+const uint16_t ddr_rcvn[] =
+    {129, 498};
+#endif // BACKUP_RCVN
+
+#ifdef BACKUP_WDQS
+const uint16_t ddr_wdqs[] =
+    { 65, 289};
+#endif // BACKUP_WDQS
+
+#ifdef BACKUP_RDQS
+const uint8_t ddr_rdqs[] =
+    { 32,  24};
+#endif // BACKUP_RDQS
+
+#ifdef BACKUP_WDQ
+const uint16_t ddr_wdq[] =
+    { 32, 257};
+#endif // BACKUP_WDQ
+
+
+
+// Select MEMORY_MANAGER as the source for PRI interface
+static void select_memory_manager(
+    MRCParams_t *mrc_params)
+{
+  RegDCO Dco;
+
+  ENTERFN();
+
+  Dco.raw = isbR32m(MCU, DCO);
+  Dco.field.PMICTL = 0;          //0 - PRI owned by MEMORY_MANAGER
+  isbW32m(MCU, DCO, Dco.raw);
+
+  LEAVEFN();
+}
+
+// Select HTE as the source for PRI interface
+void select_hte(
+    MRCParams_t *mrc_params)
+{
+  RegDCO Dco;
+
+  ENTERFN();
+
+  Dco.raw = isbR32m(MCU, DCO);
+  Dco.field.PMICTL = 1;          //1 - PRI owned by HTE
+  isbW32m(MCU, DCO, Dco.raw);
+
+  LEAVEFN();
+}
+
+// Send DRAM command, data should be formated
+// using DCMD_Xxxx macro or emrsXCommand structure.
+static void dram_init_command(
+    uint32_t data)
+{
+  Wr32(DCMD, 0, data);
+}
+
+// Send DRAM wake command using special MCU side-band WAKE opcode
+static void dram_wake_command(
+    void)
+{
+  ENTERFN();
+
+  Wr32(MMIO, PCIADDR(0,0,0,SB_PACKET_REG),
+      (uint32_t) SB_COMMAND(SB_WAKE_CMND_OPCODE, MCU, 0));
+
+  LEAVEFN();
+}
+
+// Stop self refresh driven by MCU
+static void clear_self_refresh(
+    MRCParams_t *mrc_params)
+{
+  ENTERFN();
+
+  // clear the PMSTS Channel Self Refresh bits
+  isbM32m(MCU, PMSTS, BIT0, BIT0);
+
+  LEAVEFN();
+}
+
+// Configure MCU before jedec init sequence
+static void prog_decode_before_jedec(
+    MRCParams_t *mrc_params)
+{
+  RegDRP Drp;
+  RegDRCF Drfc;
+  RegDCAL Dcal;
+  RegDSCH Dsch;
+  RegDPMC0 Dpmc0;
+
+  ENTERFN();
+
+  // Disable power saving features
+  Dpmc0.raw = isbR32m(MCU, DPMC0);
+  Dpmc0.field.CLKGTDIS = 1;
+  Dpmc0.field.DISPWRDN = 1;
+  Dpmc0.field.DYNSREN = 0;
+  Dpmc0.field.PCLSTO = 0;
+  isbW32m(MCU, DPMC0, Dpmc0.raw);
+
+  // Disable out of order transactions
+  Dsch.raw = isbR32m(MCU, DSCH);
+  Dsch.field.OOODIS = 1;
+  Dsch.field.NEWBYPDIS = 1;
+  isbW32m(MCU, DSCH, Dsch.raw);
+
+  // Disable issuing the REF command
+  Drfc.raw = isbR32m(MCU, DRFC);
+  Drfc.field.tREFI = 0;
+  isbW32m(MCU, DRFC, Drfc.raw);
+
+  // Disable ZQ calibration short
+  Dcal.raw = isbR32m(MCU, DCAL);
+  Dcal.field.ZQCINT = 0;
+  Dcal.field.SRXZQCL = 0;
+  isbW32m(MCU, DCAL, Dcal.raw);
+
+  // Training performed in address mode 0, rank population has limited impact, however
+  // simulator complains if enabled non-existing rank.
+  Drp.raw = 0;
+  if (mrc_params->rank_enables & 1)
+    Drp.field.rank0Enabled = 1;
+  if (mrc_params->rank_enables & 2)
+    Drp.field.rank1Enabled = 1;
+  isbW32m(MCU, DRP, Drp.raw);
+
+  LEAVEFN();
+}
+
+// After Cold Reset, BIOS should set COLDWAKE bit to 1 before
+// sending the WAKE message to the Dunit.
+// For Standby Exit, or any other mode in which the DRAM is in
+// SR, this bit must be set to 0.
+static void perform_ddr_reset(
+    MRCParams_t *mrc_params)
+{
+  ENTERFN();
+
+  // Set COLDWAKE bit before sending the WAKE message
+  isbM32m(MCU, DRMC, BIT16, BIT16);
+
+  // Send wake command to DUNIT (MUST be done before JEDEC)
+  dram_wake_command();
+
+  // Set default value
+  isbW32m(MCU, DRMC, DRMC_DEFAULT);
+
+  LEAVEFN();
+}
+
+// Dunit Initialisation Complete.
+// Indicates that initialisation of the Dunit has completed.
+// Memory accesses are permitted and maintenance operation
+// begins. Until this bit is set to a 1, the memory controller will
+// not accept DRAM requests from the MEMORY_MANAGER or HTE.
+static void set_ddr_init_complete(
+    MRCParams_t *mrc_params)
+{
+  RegDCO Dco;
+
+  ENTERFN();
+
+  Dco.raw = isbR32m(MCU, DCO);
+  Dco.field.PMICTL = 0;          //0 - PRI owned by MEMORY_MANAGER
+  Dco.field.IC = 1;              //1 - initialisation complete
+  isbW32m(MCU, DCO, Dco.raw);
+
+  LEAVEFN();
+}
+
+static void prog_page_ctrl(
+    MRCParams_t *mrc_params)
+{
+  RegDPMC0 Dpmc0;
+
+  ENTERFN();
+
+  Dpmc0.raw = isbR32m(MCU, DPMC0);
+
+  Dpmc0.field.PCLSTO = 0x4;
+  Dpmc0.field.PREAPWDEN = 1;
+
+  isbW32m(MCU, DPMC0, Dpmc0.raw);
+}
+
+// Configure MCU Power Management Control Register
+// and Scheduler Control Register.
+static void prog_ddr_control(
+    MRCParams_t *mrc_params)
+{
+  RegDSCH Dsch;
+  RegDPMC0 Dpmc0;
+
+  ENTERFN();
+
+  Dpmc0.raw = isbR32m(MCU, DPMC0);
+  Dsch.raw = isbR32m(MCU, DSCH);
+
+  Dpmc0.field.DISPWRDN = mrc_params->power_down_disable;
+  Dpmc0.field.CLKGTDIS = 0;
+  Dpmc0.field.PCLSTO = 4;
+  Dpmc0.field.PREAPWDEN = 1;
+
+  Dsch.field.OOODIS = 0;
+  Dsch.field.OOOST3DIS = 0;
+  Dsch.field.NEWBYPDIS = 0;
+
+  isbW32m(MCU, DSCH, Dsch.raw);
+  isbW32m(MCU, DPMC0, Dpmc0.raw);
+
+  // CMDTRIST = 2h - CMD/ADDR are tristated when no valid command
+  isbM32m(MCU, DPMC1, 2 << 4, BIT5|BIT4);
+
+  LEAVEFN();
+}
+
+// After training complete configure MCU Rank Population Register
+// specifying: ranks enabled, device width, density, address mode.
+static void prog_dra_drb(
+    MRCParams_t *mrc_params)
+{
+  RegDRP Drp;
+  RegDCO Dco;
+
+  ENTERFN();
+
+  Dco.raw = isbR32m(MCU, DCO);
+  Dco.field.IC = 0;
+  isbW32m(MCU, DCO, Dco.raw);
+
+  Drp.raw = 0;
+  if (mrc_params->rank_enables & 1)
+    Drp.field.rank0Enabled = 1;
+  if (mrc_params->rank_enables & 2)
+    Drp.field.rank1Enabled = 1;
+  if (mrc_params->dram_width == x16)
+  {
+    Drp.field.dimm0DevWidth = 1;
+    Drp.field.dimm1DevWidth = 1;
+  }
+  // Density encoding in DRAMParams_t 0=512Mb, 1=Gb, 2=2Gb, 3=4Gb
+  // has to be mapped RANKDENSx encoding (0=1Gb)
+  Drp.field.dimm0DevDensity = mrc_params->params.DENSITY - 1;
+  Drp.field.dimm1DevDensity = mrc_params->params.DENSITY - 1;
+
+  // Address mode can be overwritten if ECC enabled
+  Drp.field.addressMap = mrc_params->address_mode;
+
+  isbW32m(MCU, DRP, Drp.raw);
+
+  Dco.field.PMICTL = 0;          //0 - PRI owned by MEMORY_MANAGER
+  Dco.field.IC = 1;              //1 - initialisation complete
+  isbW32m(MCU, DCO, Dco.raw);
+
+  LEAVEFN();
+}
+
+// Configure refresh rate and short ZQ calibration interval.
+// Activate dynamic self refresh.
+static void change_refresh_period(
+    MRCParams_t *mrc_params)
+{
+  RegDRCF Drfc;
+  RegDCAL Dcal;
+  RegDPMC0 Dpmc0;
+
+  ENTERFN();
+
+  Drfc.raw = isbR32m(MCU, DRFC);
+  Drfc.field.tREFI = mrc_params->refresh_rate;
+  Drfc.field.REFDBTCLR = 1;
+  isbW32m(MCU, DRFC, Drfc.raw);
+
+  Dcal.raw = isbR32m(MCU, DCAL);
+  Dcal.field.ZQCINT = 3; // 63ms
+  isbW32m(MCU, DCAL, Dcal.raw);
+
+  Dpmc0.raw = isbR32m(MCU, DPMC0);
+  Dpmc0.field.ENPHYCLKGATE = 1;
+  Dpmc0.field.DYNSREN = 1;
+  isbW32m(MCU, DPMC0, Dpmc0.raw);
+
+  LEAVEFN();
+}
+
+// Send DRAM wake command
+static void perform_wake(
+    MRCParams_t *mrc_params)
+{
+  ENTERFN();
+
+  dram_wake_command();
+
+  LEAVEFN();
+}
+
+// prog_ddr_timing_control (aka mcu_init):
+// POST_CODE[major] == 0x02
+//
+// It will initialise timing registers in the MCU (DTR0..DTR4).
+static void prog_ddr_timing_control(
+    MRCParams_t *mrc_params)
+{
+  uint8_t TCL, WL;
+  uint8_t TRP, TRCD, TRAS, TWR, TWTR, TRRD, TRTP, TFAW;
+  uint32_t TCK;
+
+  RegDTR0 Dtr0;
+  RegDTR1 Dtr1;
+  RegDTR2 Dtr2;
+  RegDTR3 Dtr3;
+  RegDTR4 Dtr4;
+
+  ENTERFN();
+
+  // mcu_init starts
+  post_code(0x02, 0x00);
+
+  Dtr0.raw = isbR32m(MCU, DTR0);
+  Dtr1.raw = isbR32m(MCU, DTR1);
+  Dtr2.raw = isbR32m(MCU, DTR2);
+  Dtr3.raw = isbR32m(MCU, DTR3);
+  Dtr4.raw = isbR32m(MCU, DTR4);
+
+  TCK = tCK[mrc_params->ddr_speed];  // Clock in picoseconds
+  TCL = mrc_params->params.tCL;      // CAS latency in clocks
+  TRP = TCL;  // Per CAT MRC
+  TRCD = TCL;  // Per CAT MRC
+  TRAS = MCEIL(mrc_params->params.tRAS, TCK);
+  TWR = MCEIL(15000, TCK);   // Per JEDEC: tWR=15000ps DDR2/3 from 800-1600
+
+  TWTR = MCEIL(mrc_params->params.tWTR, TCK);
+  TRRD = MCEIL(mrc_params->params.tRRD, TCK);
+  TRTP = 4;  // Valid for 800 and 1066, use 5 for 1333
+  TFAW = MCEIL(mrc_params->params.tFAW, TCK);
+
+  WL = 5 + mrc_params->ddr_speed;
+
+  Dtr0.field.dramFrequency = mrc_params->ddr_speed;
+
+  Dtr0.field.tCL = TCL - 5;            //Convert from TCL (DRAM clocks) to VLV indx
+  Dtr0.field.tRP = TRP - 5;            //5 bit DRAM Clock
+  Dtr0.field.tRCD = TRCD - 5;          //5 bit DRAM Clock
+
+  Dtr1.field.tWCL = WL - 3;            //Convert from WL (DRAM clocks)  to VLV indx
+  Dtr1.field.tWTP = WL + 4 + TWR - 14;  //Change to tWTP
+  Dtr1.field.tRTP = MMAX(TRTP, 4) - 3;  //4 bit DRAM Clock
+  Dtr1.field.tRRD = TRRD - 4;        //4 bit DRAM Clock
+  Dtr1.field.tCMD = 1;             //2N
+  Dtr1.field.tRAS = TRAS - 14;      //6 bit DRAM Clock
+
+  Dtr1.field.tFAW = ((TFAW + 1) >> 1) - 5;    //4 bit DRAM Clock
+  Dtr1.field.tCCD = 0;                        //Set 4 Clock CAS to CAS delay (multi-burst)
+  Dtr2.field.tRRDR = 1;
+  Dtr2.field.tWWDR = 2;
+  Dtr2.field.tRWDR = 2;
+  Dtr3.field.tWRDR = 2;
+  Dtr3.field.tWRDD = 2;
+
+  if (mrc_params->ddr_speed == DDRFREQ_800)
+  {
+     // Extended RW delay (+1)
+     Dtr3.field.tRWSR = TCL - 5 + 1;
+  }
+  else if(mrc_params->ddr_speed == DDRFREQ_1066)
+  {
+     // Extended RW delay (+1)
+     Dtr3.field.tRWSR = TCL - 5 + 1;
+  }
+
+  Dtr3.field.tWRSR = 4 + WL + TWTR - 11;
+
+  if (mrc_params->ddr_speed == DDRFREQ_800)
+  {
+    Dtr3.field.tXP = MMAX(0, 1 - Dtr1.field.tCMD);
+  }
+  else
+  {
+    Dtr3.field.tXP = MMAX(0, 2 - Dtr1.field.tCMD);
+  }
+
+  Dtr4.field.WRODTSTRT = Dtr1.field.tCMD;
+  Dtr4.field.WRODTSTOP = Dtr1.field.tCMD;
+  Dtr4.field.RDODTSTRT = Dtr1.field.tCMD + Dtr0.field.tCL - Dtr1.field.tWCL + 2; //Convert from WL (DRAM clocks)  to VLV indx
+  Dtr4.field.RDODTSTOP = Dtr1.field.tCMD + Dtr0.field.tCL - Dtr1.field.tWCL + 2;
+  Dtr4.field.TRGSTRDIS = 0;
+  Dtr4.field.ODTDIS = 0;
+
+  isbW32m(MCU, DTR0, Dtr0.raw);
+  isbW32m(MCU, DTR1, Dtr1.raw);
+  isbW32m(MCU, DTR2, Dtr2.raw);
+  isbW32m(MCU, DTR3, Dtr3.raw);
+  isbW32m(MCU, DTR4, Dtr4.raw);
+
+  LEAVEFN();
+}
+
+// ddrphy_init:
+// POST_CODE[major] == 0x03
+//
+// This function performs some initialisation on the DDRIO unit.
+// This function is dependent on BOARD_ID, DDR_SPEED, and CHANNEL_ENABLES.
+static void ddrphy_init(MRCParams_t *mrc_params)
+{
+  uint32_t tempD; // temporary DWORD
+  uint8_t channel_i; // channel counter
+  uint8_t rank_i; // rank counter
+  uint8_t bl_grp_i; // byte lane group counter (2 BLs per module)
+
+  uint8_t bl_divisor = /*(mrc_params->channel_width==x16)?2:*/1; // byte lane divisor
+  uint8_t speed = mrc_params->ddr_speed & (BIT1|BIT0); // For DDR3 --> 0 == 800, 1 == 1066, 2 == 1333
+  uint8_t tCAS;
+  uint8_t tCWL;
+
+  ENTERFN();
+
+  tCAS = mrc_params->params.tCL;
+  tCWL = 5 + mrc_params->ddr_speed;
+
+  // ddrphy_init starts
+  post_code(0x03, 0x00);
+
+  // HSD#231531
+  // Make sure IOBUFACT is deasserted before initialising the DDR PHY.
+  // HSD#234845
+  // Make sure WRPTRENABLE is deasserted before initialising the DDR PHY.
+  for (channel_i=0; channel_i<NUM_CHANNELS; channel_i++) {
+    if (mrc_params->channel_enables & (1<<channel_i)) {
+      // Deassert DDRPHY Initialisation Complete
+      isbM32m(DDRPHY, (CMDPMCONFIG0 + (channel_i * DDRIOCCC_CH_OFFSET)), ~BIT20, BIT20); // SPID_INIT_COMPLETE=0
+      // Deassert IOBUFACT
+      isbM32m(DDRPHY, (CMDCFGREG0 + (channel_i * DDRIOCCC_CH_OFFSET)), ~BIT2, BIT2); // IOBUFACTRST_N=0
+      // Disable WRPTR
+      isbM32m(DDRPHY, (CMDPTRREG + (channel_i * DDRIOCCC_CH_OFFSET)), ~BIT0, BIT0); // WRPTRENABLE=0
+    } // if channel enabled
+  } // channel_i loop
+
+  // Put PHY in reset
+  isbM32m(DDRPHY, MASTERRSTN, 0, BIT0); // PHYRSTN=0
+
+  // Initialise DQ01,DQ23,CMD,CLK-CTL,COMP modules
+  // STEP0:
+  post_code(0x03, 0x10);
+  for (channel_i=0; channel_i<NUM_CHANNELS; channel_i++) {
+    if (mrc_params->channel_enables & (1<<channel_i)) {
+
+      // DQ01-DQ23
+      for (bl_grp_i=0; bl_grp_i<((NUM_BYTE_LANES/bl_divisor)/2); bl_grp_i++) {
+        isbM32m(DDRPHY, (DQOBSCKEBBCTL + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), ((bl_grp_i) ? (0x00) : (BIT22)), (BIT22)); // Analog MUX select - IO2xCLKSEL
+
+        // ODT Strength
+        switch (mrc_params->rd_odt_value) {
+          case 1: tempD = 0x3; break; // 60 ohm
+          case 2: tempD = 0x3; break; // 120 ohm
+          case 3: tempD = 0x3; break; // 180 ohm
+          default: tempD = 0x3; break; // 120 ohm
+        }
+        isbM32m(DDRPHY, (B0RXIOBUFCTL + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), (tempD<<5), (BIT6|BIT5)); // ODT strength
+        isbM32m(DDRPHY, (B1RXIOBUFCTL + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), (tempD<<5), (BIT6|BIT5)); // ODT strength
+        // Dynamic ODT/DIFFAMP
+        tempD = (((tCAS)<<24)|((tCAS)<<16)|((tCAS)<<8)|((tCAS)<<0));
+        switch (speed) {
+          case 0: tempD -= 0x01010101; break; // 800
+          case 1: tempD -= 0x02020202; break; // 1066
+          case 2: tempD -= 0x03030303; break; // 1333
+          case 3: tempD -= 0x04040404; break; // 1600
+        }
+        isbM32m(DDRPHY, (B01LATCTL1 + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), tempD, ((BIT28|BIT27|BIT26|BIT25|BIT24)|(BIT20|BIT19|BIT18|BIT17|BIT16)|(BIT12|BIT11|BIT10|BIT9|BIT8)|(BIT4|BIT3|BIT2|BIT1|BIT0))); // Launch Time: ODT, DIFFAMP, ODT, DIFFAMP
+        switch (speed) {
+          // HSD#234715
+          case 0: tempD = ((0x06<<16)|(0x07<<8)); break; // 800
+          case 1: tempD = ((0x07<<16)|(0x08<<8)); break; // 1066
+          case 2: tempD = ((0x09<<16)|(0x0A<<8)); break; // 1333
+          case 3: tempD = ((0x0A<<16)|(0x0B<<8)); break; // 1600
+        }
+        isbM32m(DDRPHY, (B0ONDURCTL + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), tempD, ((BIT21|BIT20|BIT19|BIT18|BIT17|BIT16)|(BIT13|BIT12|BIT11|BIT10|BIT9|BIT8))); // On Duration: ODT, DIFFAMP
+        isbM32m(DDRPHY, (B1ONDURCTL + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), tempD, ((BIT21|BIT20|BIT19|BIT18|BIT17|BIT16)|(BIT13|BIT12|BIT11|BIT10|BIT9|BIT8))); // On Duration: ODT, DIFFAMP
+
+        switch (mrc_params->rd_odt_value) {
+          case 0:  tempD = ((0x3F<<16)|(0x3f<<10)); break; // override DIFFAMP=on, ODT=off
+          default: tempD = ((0x3F<<16)|(0x2A<<10)); break; // override DIFFAMP=on, ODT=on
+        }
+        isbM32m(DDRPHY, (B0OVRCTL + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), tempD, ((BIT21|BIT20|BIT19|BIT18|BIT17|BIT16)|(BIT15|BIT14|BIT13|BIT12|BIT11|BIT10))); // Override: DIFFAMP, ODT
+        isbM32m(DDRPHY, (B1OVRCTL + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), tempD, ((BIT21|BIT20|BIT19|BIT18|BIT17|BIT16)|(BIT15|BIT14|BIT13|BIT12|BIT11|BIT10))); // Override: DIFFAMP, ODT
+
+        // DLL Setup
+        // 1xCLK Domain Timings: tEDP,RCVEN,WDQS (PO)
+        isbM32m(DDRPHY, (B0LATCTL0 + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), (((tCAS+7)<<16)|((tCAS-4)<<8)|((tCWL-2)<<0)), ((BIT21|BIT20|BIT19|BIT18|BIT17|BIT16)|(BIT12|BIT11|BIT10|BIT9|BIT8)|(BIT4|BIT3|BIT2|BIT1|BIT0))); // 1xCLK: tEDP, RCVEN, WDQS
+        isbM32m(DDRPHY, (B1LATCTL0 + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), (((tCAS+7)<<16)|((tCAS-4)<<8)|((tCWL-2)<<0)), ((BIT21|BIT20|BIT19|BIT18|BIT17|BIT16)|(BIT12|BIT11|BIT10|BIT9|BIT8)|(BIT4|BIT3|BIT2|BIT1|BIT0))); // 1xCLK: tEDP, RCVEN, WDQS
+
+        // RCVEN Bypass (PO)
+        isbM32m(DDRPHY, (B0RXIOBUFCTL + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), ((0x0<<7)|(0x0<<0)), (BIT7|BIT0)); // AFE Bypass, RCVEN DIFFAMP
+        isbM32m(DDRPHY, (B1RXIOBUFCTL + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), ((0x0<<7)|(0x0<<0)), (BIT7|BIT0)); // AFE Bypass, RCVEN DIFFAMP
+        // TX
+        isbM32m(DDRPHY, (DQCTL + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), (BIT16), (BIT16)); // 0 means driving DQ during DQS-preamble
+        isbM32m(DDRPHY, (B01PTRCTL1 + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), (BIT8), (BIT8)); // WR_LVL mode disable
+        // RX (PO)
+        isbM32m(DDRPHY, (B0VREFCTL + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), ((0x03<<2)|(0x0<<1)|(0x0<<0)), ((BIT7|BIT6|BIT5|BIT4|BIT3|BIT2)|BIT1|BIT0)); // Internal Vref Code, Enable#, Ext_or_Int (1=Ext)
+        isbM32m(DDRPHY, (B1VREFCTL + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), ((0x03<<2)|(0x0<<1)|(0x0<<0)), ((BIT7|BIT6|BIT5|BIT4|BIT3|BIT2)|BIT1|BIT0)); // Internal Vref Code, Enable#, Ext_or_Int (1=Ext)
+        isbM32m(DDRPHY, (B0RXIOBUFCTL + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), (0), (BIT4)); // Per-Bit De-Skew Enable
+        isbM32m(DDRPHY, (B1RXIOBUFCTL + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), (0), (BIT4)); // Per-Bit De-Skew Enable
+      }
+      // CLKEBB
+      isbM32m(DDRPHY, (CMDOBSCKEBBCTL + (channel_i * DDRIOCCC_CH_OFFSET)), 0, (BIT23));
+
+      // Enable tristate control of cmd/address bus
+      isbM32m(DDRPHY, (CMDCFGREG0 + (channel_i * DDRIOCCC_CH_OFFSET)), 0, (BIT1|BIT0));
+
+      // ODT RCOMP
+      isbM32m(DDRPHY, (CMDRCOMPODT + (channel_i * DDRIOCCC_CH_OFFSET)), ((0x03<<5)|(0x03<<0)), ((BIT9|BIT8|BIT7|BIT6|BIT5)|(BIT4|BIT3|BIT2|BIT1|BIT0)));
+
+      // CMDPM* registers must be programmed in this order...
+      isbM32m(DDRPHY, (CMDPMDLYREG4 + (channel_i * DDRIOCCC_CH_OFFSET)), ((0xFFFFU<<16)|(0xFFFF<<0)), ((BIT31|BIT30|BIT29|BIT28|BIT27|BIT26|BIT25|BIT24|BIT23|BIT22|BIT21|BIT20|BIT19|BIT18|BIT17|BIT16)|(BIT15|BIT14|BIT13|BIT12|BIT11|BIT10|BIT9|BIT8|BIT7|BIT6|BIT5|BIT4|BIT3|BIT2|BIT1|BIT0))); // Turn On Delays: SFR (regulator), MPLL
+      isbM32m(DDRPHY, (CMDPMDLYREG3 + (channel_i * DDRIOCCC_CH_OFFSET)), ((0xFU<<28)|(0xFFF<<16)|(0xF<<12)|(0x616<<0)), ((BIT31|BIT30|BIT29|BIT28)|(BIT27|BIT26|BIT25|BIT24|BIT23|BIT22|BIT21|BIT20|BIT19|BIT18|BIT17|BIT16)|(BIT15|BIT14|BIT13|BIT12)|(BIT11|BIT10|BIT9|BIT8|BIT7|BIT6|BIT5|BIT4|BIT3|BIT2|BIT1|BIT0))); // Delays: ASSERT_IOBUFACT_to_ALLON0_for_PM_MSG_3, VREG (MDLL) Turn On, ALLON0_to_DEASSERT_IOBUFACT_for_PM_MSG_gt0, MDLL Turn On
+      isbM32m(DDRPHY, (CMDPMDLYREG2 + (channel_i * DDRIOCCC_CH_OFFSET)), ((0xFFU<<24)|(0xFF<<16)|(0xFF<<8)|(0xFF<<0)), ((BIT31|BIT30|BIT29|BIT28|BIT27|BIT26|BIT25|BIT24)|(BIT23|BIT22|BIT21|BIT20|BIT19|BIT18|BIT17|BIT16)|(BIT15|BIT14|BIT13|BIT12|BIT11|BIT10|BIT9|BIT8)|(BIT7|BIT6|BIT5|BIT4|BIT3|BIT2|BIT1|BIT0))); // MPLL Divider Reset Delays
+      isbM32m(DDRPHY, (CMDPMDLYREG1 + (channel_i * DDRIOCCC_CH_OFFSET)), ((0xFFU<<24)|(0xFF<<16)|(0xFF<<8)|(0xFF<<0)), ((BIT31|BIT30|BIT29|BIT28|BIT27|BIT26|BIT25|BIT24)|(BIT23|BIT22|BIT21|BIT20|BIT19|BIT18|BIT17|BIT16)|(BIT15|BIT14|BIT13|BIT12|BIT11|BIT10|BIT9|BIT8)|(BIT7|BIT6|BIT5|BIT4|BIT3|BIT2|BIT1|BIT0))); // Turn Off Delays: VREG, Staggered MDLL, MDLL, PI
+      isbM32m(DDRPHY, (CMDPMDLYREG0 + (channel_i * DDRIOCCC_CH_OFFSET)), ((0xFFU<<24)|(0xFF<<16)|(0xFF<<8)|(0xFF<<0)), ((BIT31|BIT30|BIT29|BIT28|BIT27|BIT26|BIT25|BIT24)|(BIT23|BIT22|BIT21|BIT20|BIT19|BIT18|BIT17|BIT16)|(BIT15|BIT14|BIT13|BIT12|BIT11|BIT10|BIT9|BIT8)|(BIT7|BIT6|BIT5|BIT4|BIT3|BIT2|BIT1|BIT0))); // Turn On Delays: MPLL, Staggered MDLL, PI, IOBUFACT
+      isbM32m(DDRPHY, (CMDPMCONFIG0 + (channel_i * DDRIOCCC_CH_OFFSET)), ((0x6<<8)|BIT6|(0x4<<0)), (BIT31|BIT30|BIT29|BIT28|BIT27|BIT26|BIT25|BIT24|BIT23|BIT22|BIT21|(BIT11|BIT10|BIT9|BIT8)|BIT6|(BIT3|BIT2|BIT1|BIT0))); // Allow PUnit signals
+      isbM32m(DDRPHY, (CMDMDLLCTL +   (channel_i * DDRIOCCC_CH_OFFSET)), ((0x3<<4)|(0x7<<0)), ((BIT6|BIT5|BIT4)|(BIT3|BIT2|BIT1|BIT0))); // DLL_VREG Bias Trim, VREF Tuning for DLL_VREG
+      // CLK-CTL
+      isbM32m(DDRPHY, (CCOBSCKEBBCTL + (channel_i * DDRIOCCC_CH_OFFSET)), 0, (BIT24)); // CLKEBB
+      isbM32m(DDRPHY, (CCCFGREG0 +     (channel_i * DDRIOCCC_CH_OFFSET)), ((0x0<<16)|(0x0<<12)|(0x0<<8)|(0xF<<4)|BIT0), ((BIT19|BIT18|BIT17|BIT16)|(BIT15|BIT14|BIT13|BIT12)|(BIT11|BIT10|BIT9|BIT8)|(BIT7|BIT6|BIT5|BIT4)|BIT0)); // Buffer Enable: CS,CKE,ODT,CLK
+      isbM32m(DDRPHY, (CCRCOMPODT +    (channel_i * DDRIOCCC_CH_OFFSET)), ((0x03<<8)|(0x03<<0)), ((BIT12|BIT11|BIT10|BIT9|BIT8)|(BIT4|BIT3|BIT2|BIT1|BIT0))); // ODT RCOMP
+      isbM32m(DDRPHY, (CCMDLLCTL +     (channel_i * DDRIOCCC_CH_OFFSET)), ((0x3<<4)|(0x7<<0)), ((BIT6|BIT5|BIT4)|(BIT3|BIT2|BIT1|BIT0))); // DLL_VREG Bias Trim, VREF Tuning for DLL_VREG
+
+      // COMP (RON channel specific)
+      // - DQ/DQS/DM RON: 32 Ohm
+      // - CTRL/CMD RON: 27 Ohm
+      // - CLK RON: 26 Ohm
+      isbM32m(DDRPHY, (DQVREFCH0 +  (channel_i * DDRCOMP_CH_OFFSET)), ((0x08<<24)|(0x03<<16)), ((BIT29|BIT28|BIT27|BIT26|BIT25|BIT24)|(BIT21|BIT20|BIT19|BIT18|BIT17|BIT16)));  // RCOMP Vref PU/PD
+      isbM32m(DDRPHY, (CMDVREFCH0 + (channel_i * DDRCOMP_CH_OFFSET)), ((0x0C<<24)|(0x03<<16)), ((BIT29|BIT28|BIT27|BIT26|BIT25|BIT24)|(BIT21|BIT20|BIT19|BIT18|BIT17|BIT16)));  // RCOMP Vref PU/PD
+      isbM32m(DDRPHY, (CLKVREFCH0 + (channel_i * DDRCOMP_CH_OFFSET)), ((0x0F<<24)|(0x03<<16)), ((BIT29|BIT28|BIT27|BIT26|BIT25|BIT24)|(BIT21|BIT20|BIT19|BIT18|BIT17|BIT16)));  // RCOMP Vref PU/PD
+      isbM32m(DDRPHY, (DQSVREFCH0 + (channel_i * DDRCOMP_CH_OFFSET)), ((0x08<<24)|(0x03<<16)), ((BIT29|BIT28|BIT27|BIT26|BIT25|BIT24)|(BIT21|BIT20|BIT19|BIT18|BIT17|BIT16)));  // RCOMP Vref PU/PD
+      isbM32m(DDRPHY, (CTLVREFCH0 + (channel_i * DDRCOMP_CH_OFFSET)), ((0x0C<<24)|(0x03<<16)), ((BIT29|BIT28|BIT27|BIT26|BIT25|BIT24)|(BIT21|BIT20|BIT19|BIT18|BIT17|BIT16)));  // RCOMP Vref PU/PD
+
+      // DQS Swapped Input Enable
+      isbM32m(DDRPHY, (COMPEN1CH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT19|BIT17),           ((BIT31|BIT30)|BIT19|BIT17|(BIT15|BIT14)));
+
+      // ODT VREF = 1.5 x 274/360+274 = 0.65V (code of ~50)
+      isbM32m(DDRPHY, (DQVREFCH0 +  (channel_i * DDRCOMP_CH_OFFSET)), ((0x32<<8)|(0x03<<0)),   ((BIT13|BIT12|BIT11|BIT10|BIT9|BIT8)|(BIT5|BIT4|BIT3|BIT2|BIT1|BIT0))); // ODT Vref PU/PD
+      isbM32m(DDRPHY, (DQSVREFCH0 + (channel_i * DDRCOMP_CH_OFFSET)), ((0x32<<8)|(0x03<<0)),   ((BIT13|BIT12|BIT11|BIT10|BIT9|BIT8)|(BIT5|BIT4|BIT3|BIT2|BIT1|BIT0))); // ODT Vref PU/PD
+      isbM32m(DDRPHY, (CLKVREFCH0 + (channel_i * DDRCOMP_CH_OFFSET)), ((0x0E<<8)|(0x05<<0)),   ((BIT13|BIT12|BIT11|BIT10|BIT9|BIT8)|(BIT5|BIT4|BIT3|BIT2|BIT1|BIT0))); // ODT Vref PU/PD
+
+      // Slew rate settings are frequency specific, numbers below are for 800Mhz (speed == 0)
+      // - DQ/DQS/DM/CLK SR: 4V/ns,
+      // - CTRL/CMD SR: 1.5V/ns
+      tempD = (0x0E<<16)|(0x0E<<12)|(0x08<<8)|(0x0B<<4)|(0x0B<<0);
+      isbM32m(DDRPHY, (DLYSELCH0 +   (channel_i * DDRCOMP_CH_OFFSET)), (tempD), ((BIT19|BIT18|BIT17|BIT16)|(BIT15|BIT14|BIT13|BIT12)|(BIT11|BIT10|BIT9|BIT8)|(BIT7|BIT6|BIT5|BIT4)|(BIT3|BIT2|BIT1|BIT0))); // DCOMP Delay Select: CTL,CMD,CLK,DQS,DQ
+      isbM32m(DDRPHY, (TCOVREFCH0 +  (channel_i * DDRCOMP_CH_OFFSET)), ((0x05<<16)|(0x05<<8)|(0x05<<0)), ((BIT21|BIT20|BIT19|BIT18|BIT17|BIT16)|(BIT13|BIT12|BIT11|BIT10|BIT9|BIT8)|(BIT5|BIT4|BIT3|BIT2|BIT1|BIT0))); // TCO Vref CLK,DQS,DQ
+      isbM32m(DDRPHY, (CCBUFODTCH0 + (channel_i * DDRCOMP_CH_OFFSET)), ((0x03<<8)|(0x03<<0)), ((BIT12|BIT11|BIT10|BIT9|BIT8)|(BIT4|BIT3|BIT2|BIT1|BIT0))); // ODTCOMP CMD/CTL PU/PD
+      isbM32m(DDRPHY, (COMPEN0CH0 +  (channel_i * DDRCOMP_CH_OFFSET)), (0), ((BIT31|BIT30)|BIT8)); // COMP
+
+      #ifdef BACKUP_COMPS
+      // DQ COMP Overrides
+      isbM32m(DDRPHY, (DQDRVPUCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x0A<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // RCOMP PU
+      isbM32m(DDRPHY, (DQDRVPDCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x0A<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // RCOMP PD
+      isbM32m(DDRPHY, (DQDLYPUCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x10<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // DCOMP PU
+      isbM32m(DDRPHY, (DQDLYPDCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x10<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // DCOMP PD
+      isbM32m(DDRPHY, (DQODTPUCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x0B<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // ODTCOMP PU
+      isbM32m(DDRPHY, (DQODTPDCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x0B<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // ODTCOMP PD
+      isbM32m(DDRPHY, (DQTCOPUCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31), (BIT31)); // TCOCOMP PU
+      isbM32m(DDRPHY, (DQTCOPDCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31), (BIT31)); // TCOCOMP PD
+      // DQS COMP Overrides
+      isbM32m(DDRPHY, (DQSDRVPUCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x0A<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // RCOMP PU
+      isbM32m(DDRPHY, (DQSDRVPDCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x0A<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // RCOMP PD
+      isbM32m(DDRPHY, (DQSDLYPUCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x10<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // DCOMP PU
+      isbM32m(DDRPHY, (DQSDLYPDCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x10<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // DCOMP PD
+      isbM32m(DDRPHY, (DQSODTPUCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x0B<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // ODTCOMP PU
+      isbM32m(DDRPHY, (DQSODTPDCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x0B<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // ODTCOMP PD
+      isbM32m(DDRPHY, (DQSTCOPUCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31), (BIT31)); // TCOCOMP PU
+      isbM32m(DDRPHY, (DQSTCOPDCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31), (BIT31)); // TCOCOMP PD
+      // CLK COMP Overrides
+      isbM32m(DDRPHY, (CLKDRVPUCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x0C<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // RCOMP PU
+      isbM32m(DDRPHY, (CLKDRVPDCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x0C<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // RCOMP PD
+      isbM32m(DDRPHY, (CLKDLYPUCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x07<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // DCOMP PU
+      isbM32m(DDRPHY, (CLKDLYPDCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x07<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // DCOMP PD
+      isbM32m(DDRPHY, (CLKODTPUCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x0B<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // ODTCOMP PU
+      isbM32m(DDRPHY, (CLKODTPDCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x0B<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // ODTCOMP PD
+      isbM32m(DDRPHY, (CLKTCOPUCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31), (BIT31)); // TCOCOMP PU
+      isbM32m(DDRPHY, (CLKTCOPDCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31), (BIT31)); // TCOCOMP PD
+      // CMD COMP Overrides
+      isbM32m(DDRPHY, (CMDDRVPUCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x0D<<16)), (BIT31|(BIT21|BIT20|BIT19|BIT18|BIT17|BIT16))); // RCOMP PU
+      isbM32m(DDRPHY, (CMDDRVPDCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x0D<<16)), (BIT31|(BIT21|BIT20|BIT19|BIT18|BIT17|BIT16))); // RCOMP PD
+      isbM32m(DDRPHY, (CMDDLYPUCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x0A<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // DCOMP PU
+      isbM32m(DDRPHY, (CMDDLYPDCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x0A<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // DCOMP PD
+      // CTL COMP Overrides
+      isbM32m(DDRPHY, (CTLDRVPUCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x0D<<16)), (BIT31|(BIT21|BIT20|BIT19|BIT18|BIT17|BIT16))); // RCOMP PU
+      isbM32m(DDRPHY, (CTLDRVPDCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x0D<<16)), (BIT31|(BIT21|BIT20|BIT19|BIT18|BIT17|BIT16))); // RCOMP PD
+      isbM32m(DDRPHY, (CTLDLYPUCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x0A<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // DCOMP PU
+      isbM32m(DDRPHY, (CTLDLYPDCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x0A<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // DCOMP PD
+      #else
+      // DQ TCOCOMP Overrides
+      isbM32m(DDRPHY, (DQTCOPUCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x1F<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // TCOCOMP PU
+      isbM32m(DDRPHY, (DQTCOPDCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x1F<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // TCOCOMP PD
+      // DQS TCOCOMP Overrides
+      isbM32m(DDRPHY, (DQSTCOPUCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x1F<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // TCOCOMP PU
+      isbM32m(DDRPHY, (DQSTCOPDCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x1F<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // TCOCOMP PD
+      // CLK TCOCOMP Overrides
+      isbM32m(DDRPHY, (CLKTCOPUCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x1F<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // TCOCOMP PU
+      isbM32m(DDRPHY, (CLKTCOPDCTLCH0 + (channel_i * DDRCOMP_CH_OFFSET)), (BIT31|(0x1F<<16)), (BIT31|(BIT20|BIT19|BIT18|BIT17|BIT16))); // TCOCOMP PD
+      #endif // BACKUP_COMPS
+      // program STATIC delays
+      #ifdef BACKUP_WCMD
+      set_wcmd(channel_i, ddr_wcmd[PLATFORM_ID]);
+      #else
+      set_wcmd(channel_i, ddr_wclk[PLATFORM_ID] + HALF_CLK);
+      #endif // BACKUP_WCMD
+      for (rank_i=0; rank_i<NUM_RANKS; rank_i++) {
+        if (mrc_params->rank_enables & (1<<rank_i)) {
+          set_wclk(channel_i, rank_i, ddr_wclk[PLATFORM_ID]);
+          #ifdef BACKUP_WCTL
+          set_wctl(channel_i, rank_i, ddr_wctl[PLATFORM_ID]);
+          #else
+          set_wctl(channel_i, rank_i, ddr_wclk[PLATFORM_ID] + HALF_CLK);
+          #endif // BACKUP_WCTL
+        }
+      }
+    }
+  }
+  // COMP (non channel specific)
+  //isbM32m(DDRPHY, (), (), ());
+  isbM32m(DDRPHY, (DQANADRVPUCTL), (BIT30), (BIT30)); // RCOMP: Dither PU Enable
+  isbM32m(DDRPHY, (DQANADRVPDCTL), (BIT30), (BIT30)); // RCOMP: Dither PD Enable
+  isbM32m(DDRPHY, (CMDANADRVPUCTL), (BIT30), (BIT30)); // RCOMP: Dither PU Enable
+  isbM32m(DDRPHY, (CMDANADRVPDCTL), (BIT30), (BIT30)); // RCOMP: Dither PD Enable
+  isbM32m(DDRPHY, (CLKANADRVPUCTL), (BIT30), (BIT30)); // RCOMP: Dither PU Enable
+  isbM32m(DDRPHY, (CLKANADRVPDCTL), (BIT30), (BIT30)); // RCOMP: Dither PD Enable
+  isbM32m(DDRPHY, (DQSANADRVPUCTL), (BIT30), (BIT30)); // RCOMP: Dither PU Enable
+  isbM32m(DDRPHY, (DQSANADRVPDCTL), (BIT30), (BIT30)); // RCOMP: Dither PD Enable
+  isbM32m(DDRPHY, (CTLANADRVPUCTL), (BIT30), (BIT30)); // RCOMP: Dither PU Enable
+  isbM32m(DDRPHY, (CTLANADRVPDCTL), (BIT30), (BIT30)); // RCOMP: Dither PD Enable
+  isbM32m(DDRPHY, (DQANAODTPUCTL), (BIT30), (BIT30)); // ODT: Dither PU Enable
+  isbM32m(DDRPHY, (DQANAODTPDCTL), (BIT30), (BIT30)); // ODT: Dither PD Enable
+  isbM32m(DDRPHY, (CLKANAODTPUCTL), (BIT30), (BIT30)); // ODT: Dither PU Enable
+  isbM32m(DDRPHY, (CLKANAODTPDCTL), (BIT30), (BIT30)); // ODT: Dither PD Enable
+  isbM32m(DDRPHY, (DQSANAODTPUCTL), (BIT30), (BIT30)); // ODT: Dither PU Enable
+  isbM32m(DDRPHY, (DQSANAODTPDCTL), (BIT30), (BIT30)); // ODT: Dither PD Enable
+  isbM32m(DDRPHY, (DQANADLYPUCTL), (BIT30), (BIT30)); // DCOMP: Dither PU Enable
+  isbM32m(DDRPHY, (DQANADLYPDCTL), (BIT30), (BIT30)); // DCOMP: Dither PD Enable
+  isbM32m(DDRPHY, (CMDANADLYPUCTL), (BIT30), (BIT30)); // DCOMP: Dither PU Enable
+  isbM32m(DDRPHY, (CMDANADLYPDCTL), (BIT30), (BIT30)); // DCOMP: Dither PD Enable
+  isbM32m(DDRPHY, (CLKANADLYPUCTL), (BIT30), (BIT30)); // DCOMP: Dither PU Enable
+  isbM32m(DDRPHY, (CLKANADLYPDCTL), (BIT30), (BIT30)); // DCOMP: Dither PD Enable
+  isbM32m(DDRPHY, (DQSANADLYPUCTL), (BIT30), (BIT30)); // DCOMP: Dither PU Enable
+  isbM32m(DDRPHY, (DQSANADLYPDCTL), (BIT30), (BIT30)); // DCOMP: Dither PD Enable
+  isbM32m(DDRPHY, (CTLANADLYPUCTL), (BIT30), (BIT30)); // DCOMP: Dither PU Enable
+  isbM32m(DDRPHY, (CTLANADLYPDCTL), (BIT30), (BIT30)); // DCOMP: Dither PD Enable
+  isbM32m(DDRPHY, (DQANATCOPUCTL), (BIT30), (BIT30)); // TCO: Dither PU Enable
+  isbM32m(DDRPHY, (DQANATCOPDCTL), (BIT30), (BIT30)); // TCO: Dither PD Enable
+  isbM32m(DDRPHY, (CLKANATCOPUCTL), (BIT30), (BIT30)); // TCO: Dither PU Enable
+  isbM32m(DDRPHY, (CLKANATCOPDCTL), (BIT30), (BIT30)); // TCO: Dither PD Enable
+  isbM32m(DDRPHY, (DQSANATCOPUCTL), (BIT30), (BIT30)); // TCO: Dither PU Enable
+  isbM32m(DDRPHY, (DQSANATCOPDCTL), (BIT30), (BIT30)); // TCO: Dither PD Enable
+  isbM32m(DDRPHY, (TCOCNTCTRL), (0x1<<0), (BIT1|BIT0)); // TCOCOMP: Pulse Count
+  isbM32m(DDRPHY, (CHNLBUFSTATIC), ((0x03<<24)|(0x03<<16)), ((BIT28|BIT27|BIT26|BIT25|BIT24)|(BIT20|BIT19|BIT18|BIT17|BIT16))); // ODT: CMD/CTL PD/PU
+  isbM32m(DDRPHY, (MSCNTR), (0x64<<0), (BIT7|BIT6|BIT5|BIT4|BIT3|BIT2|BIT1|BIT0)); // Set 1us counter
+  isbM32m(DDRPHY, (LATCH1CTL), (0x1<<28), (BIT30|BIT29|BIT28)); // ???
+
+  // Release PHY from reset
+  isbM32m(DDRPHY, MASTERRSTN, BIT0, BIT0); // PHYRSTN=1
+
+  // STEP1:
+  post_code(0x03, 0x11);
+  for (channel_i=0; channel_i<NUM_CHANNELS; channel_i++) {
+    if (mrc_params->channel_enables & (1<<channel_i)) {
+      // DQ01-DQ23
+      for (bl_grp_i=0; bl_grp_i<((NUM_BYTE_LANES/bl_divisor)/2); bl_grp_i++) {
+        isbM32m(DDRPHY, (DQMDLLCTL + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), (BIT13), (BIT13)); // Enable VREG
+        delay_n(3);
+      }
+      // ECC
+      isbM32m(DDRPHY, (ECCMDLLCTL), (BIT13), (BIT13)); // Enable VREG
+      delay_n(3);
+      // CMD
+      isbM32m(DDRPHY, (CMDMDLLCTL + (channel_i * DDRIOCCC_CH_OFFSET)), (BIT13), (BIT13)); // Enable VREG
+      delay_n(3);
+      // CLK-CTL
+      isbM32m(DDRPHY, (CCMDLLCTL + (channel_i * DDRIOCCC_CH_OFFSET)), (BIT13), (BIT13)); // Enable VREG
+      delay_n(3);
+    }
+  }
+
+  // STEP2:
+  post_code(0x03, 0x12);
+  delay_n(200);
+  for (channel_i=0; channel_i<NUM_CHANNELS; channel_i++) {
+    if (mrc_params->channel_enables & (1<<channel_i)) {
+      // DQ01-DQ23
+      for (bl_grp_i=0; bl_grp_i<((NUM_BYTE_LANES/bl_divisor)/2); bl_grp_i++) {
+        isbM32m(DDRPHY, (DQMDLLCTL + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), (BIT17), (BIT17)); // Enable MCDLL
+        delay_n(50);
+      }
+      // ECC
+      isbM32m(DDRPHY, (ECCMDLLCTL), (BIT17), (BIT17)); // Enable MCDLL
+      delay_n(50);
+      // CMD
+      isbM32m(DDRPHY, (CMDMDLLCTL + (channel_i * DDRIOCCC_CH_OFFSET)), (BIT18), (BIT18)); // Enable MCDLL
+      delay_n(50);
+      // CLK-CTL
+      isbM32m(DDRPHY, (CCMDLLCTL + (channel_i * DDRIOCCC_CH_OFFSET)), (BIT18), (BIT18)); // Enable MCDLL
+      delay_n(50);
+    }
+  }
+
+  // STEP3:
+  post_code(0x03, 0x13);
+  delay_n(100);
+  for (channel_i=0; channel_i<NUM_CHANNELS; channel_i++) {
+    if (mrc_params->channel_enables & (1<<channel_i)) {
+      // DQ01-DQ23
+      for (bl_grp_i=0; bl_grp_i<((NUM_BYTE_LANES/bl_divisor)/2); bl_grp_i++) {
+#ifdef FORCE_16BIT_DDRIO
+        tempD = ((bl_grp_i) && (mrc_params->channel_width == x16)) ? ((0x1<<12)|(0x1<<8)|(0xF<<4)|(0xF<<0)) : ((0xF<<12)|(0xF<<8)|(0xF<<4)|(0xF<<0));
+#else
+        tempD = ((0xF<<12)|(0xF<<8)|(0xF<<4)|(0xF<<0));
+#endif
+        isbM32m(DDRPHY, (DQDLLTXCTL + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), (tempD), ((BIT15|BIT14|BIT13|BIT12)|(BIT11|BIT10|BIT9|BIT8)|(BIT7|BIT6|BIT5|BIT4)|(BIT3|BIT2|BIT1|BIT0))); // Enable TXDLL
+        delay_n(3);
+        isbM32m(DDRPHY, (DQDLLRXCTL + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), (BIT3|BIT2|BIT1|BIT0), (BIT3|BIT2|BIT1|BIT0)); // Enable RXDLL
+        delay_n(3);
+        isbM32m(DDRPHY, (B0OVRCTL + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), (BIT3|BIT2|BIT1|BIT0), (BIT3|BIT2|BIT1|BIT0)); // Enable RXDLL Overrides BL0
+      }
+
+      // ECC
+      tempD = ((0xF<<12)|(0xF<<8)|(0xF<<4)|(0xF<<0));
+      isbM32m(DDRPHY, (ECCDLLTXCTL), (tempD), ((BIT15|BIT14|BIT13|BIT12)|(BIT11|BIT10|BIT9|BIT8)|(BIT7|BIT6|BIT5|BIT4)|(BIT3|BIT2|BIT1|BIT0))); // Enable TXDLL
+      delay_n(3);
+
+      // CMD (PO)
+      isbM32m(DDRPHY, (CMDDLLTXCTL + (channel_i * DDRIOCCC_CH_OFFSET)), ((0xF<<12)|(0xF<<8)|(0xF<<4)|(0xF<<0)), ((BIT15|BIT14|BIT13|BIT12)|(BIT11|BIT10|BIT9|BIT8)|(BIT7|BIT6|BIT5|BIT4)|(BIT3|BIT2|BIT1|BIT0))); // Enable TXDLL
+      delay_n(3);
+    }
+  }
+
+
+  // STEP4:
+  post_code(0x03, 0x14);
+  for (channel_i=0; channel_i<NUM_CHANNELS; channel_i++) {
+    if (mrc_params->channel_enables & (1<<channel_i)) {
+      // Host To Memory Clock Alignment (HMC) for 800/1066
+      for (bl_grp_i=0; bl_grp_i<((NUM_BYTE_LANES/bl_divisor)/2); bl_grp_i++) {
+        isbM32m(DDRPHY, (DQCLKALIGNREG2 + (bl_grp_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), ((bl_grp_i)?(0x3):(0x1)), (BIT3|BIT2|BIT1|BIT0)); // CLK_ALIGN_MOD_ID
+      }
+      isbM32m(DDRPHY, (ECCCLKALIGNREG2 + (channel_i * DDRIODQ_CH_OFFSET)), 0x2, (BIT3|BIT2|BIT1|BIT0)); // CLK_ALIGN_MOD_ID
+      isbM32m(DDRPHY, (CMDCLKALIGNREG2 + (channel_i * DDRIODQ_CH_OFFSET)), 0x0, (BIT3|BIT2|BIT1|BIT0)); // CLK_ALIGN_MOD_ID
+      isbM32m(DDRPHY, (CCCLKALIGNREG2 + (channel_i * DDRIODQ_CH_OFFSET)), 0x2, (BIT3|BIT2|BIT1|BIT0)); // CLK_ALIGN_MOD_ID
+      isbM32m(DDRPHY, (CMDCLKALIGNREG0 + (channel_i * DDRIOCCC_CH_OFFSET)), (0x2<<4), (BIT5|BIT4)); // CLK_ALIGN_MODE
+      isbM32m(DDRPHY, (CMDCLKALIGNREG1 + (channel_i * DDRIOCCC_CH_OFFSET)), ((0x18<<16)|(0x10<<8)|(0x8<<2)|(0x1<<0)), ((BIT22|BIT21|BIT20|BIT19|BIT18|BIT17|BIT16)|(BIT14|BIT13|BIT12|BIT11|BIT10|BIT9|BIT8)|(BIT7|BIT6|BIT5|BIT4|BIT3|BIT2)|(BIT1|BIT0))); // NUM_SAMPLES, MAX_SAMPLES, MACRO_PI_STEP, MICRO_PI_STEP
+      isbM32m(DDRPHY, (CMDCLKALIGNREG2 + (channel_i * DDRIOCCC_CH_OFFSET)), ((0x10<<16)|(0x4<<8)|(0x2<<4)), ((BIT20|BIT19|BIT18|BIT17|BIT16)|(BIT11|BIT10|BIT9|BIT8)|(BIT7|BIT6|BIT5|BIT4))); // ???, TOTAL_NUM_MODULES, FIRST_U_PARTITION
+      #ifdef HMC_TEST
+      isbM32m(DDRPHY, (CMDCLKALIGNREG0 + (channel_i * DDRIOCCC_CH_OFFSET)), BIT24, BIT24); // START_CLK_ALIGN=1
+      while (isbR32m(DDRPHY, (CMDCLKALIGNREG0 + (channel_i * DDRIOCCC_CH_OFFSET))) & BIT24); // wait for START_CLK_ALIGN=0
+      #endif // HMC_TEST
+
+      // Set RD/WR Pointer Seperation & COUNTEN & FIFOPTREN
+      isbM32m(DDRPHY, (CMDPTRREG + (channel_i * DDRIOCCC_CH_OFFSET)), BIT0, BIT0); // WRPTRENABLE=1
+
+
+#ifdef SIM
+      // comp is not working on simulator
+#else
+      // COMP initial
+      isbM32m(DDRPHY, (COMPEN0CH0 + (channel_i * DDRCOMP_CH_OFFSET)), BIT5, BIT5); // enable bypass for CLK buffer (PO)
+      isbM32m(DDRPHY, (CMPCTRL), (BIT0), (BIT0)); // Initial COMP Enable
+      while (isbR32m(DDRPHY, (CMPCTRL)) & BIT0); // wait for Initial COMP Enable = 0
+      isbM32m(DDRPHY, (COMPEN0CH0 + (channel_i * DDRCOMP_CH_OFFSET)), ~BIT5, BIT5); // disable bypass for CLK buffer (PO)
+#endif
+
+      // IOBUFACT
+      // STEP4a
+      isbM32m(DDRPHY, (CMDCFGREG0 + (channel_i * DDRIOCCC_CH_OFFSET)), BIT2, BIT2); // IOBUFACTRST_N=1
+
+      // DDRPHY initialisation complete
+      isbM32m(DDRPHY, (CMDPMCONFIG0 + (channel_i * DDRIOCCC_CH_OFFSET)), BIT20, BIT20); // SPID_INIT_COMPLETE=1
+    }
+  }
+
+  LEAVEFN();
+  return;
+}
+
+// jedec_init (aka PerformJedecInit):
+// This function performs JEDEC initialisation on all enabled channels.
+static void jedec_init(
+    MRCParams_t *mrc_params,
+    uint32_t silent)
+{
+  uint8_t TWR, WL, Rank;
+  uint32_t TCK;
+
+  RegDTR0 DTR0reg;
+
+  DramInitDDR3MRS0 mrs0Command;
+  DramInitDDR3EMR1 emrs1Command;
+  DramInitDDR3EMR2 emrs2Command;
+  DramInitDDR3EMR3 emrs3Command;
+
+  ENTERFN();
+
+  // jedec_init starts
+  if (!silent)
+  {
+    post_code(0x04, 0x00);
+  }
+
+  // Assert RESET# for 200us
+  isbM32m(DDRPHY, CCDDR3RESETCTL, BIT1, (BIT8|BIT1)); // DDR3_RESET_SET=0, DDR3_RESET_RESET=1
+#ifdef QUICKSIM
+      // Don't waste time during simulation
+      delay_u(2);
+#else
+  delay_u(200);
+#endif
+  isbM32m(DDRPHY, CCDDR3RESETCTL, BIT8, (BIT8|BIT1)); // DDR3_RESET_SET=1, DDR3_RESET_RESET=0
+
+  DTR0reg.raw = isbR32m(MCU, DTR0);
+
+  // Set CKEVAL for populated ranks
+  // then send NOP to each rank (#4550197)
+  {
+    uint32_t DRPbuffer;
+    uint32_t DRMCbuffer;
+
+    DRPbuffer = isbR32m(MCU, DRP);
+    DRPbuffer &= 0x3;
+    DRMCbuffer = isbR32m(MCU, DRMC);
+    DRMCbuffer &= 0xFFFFFFFC;
+    DRMCbuffer |= (BIT4 | DRPbuffer);
+
+    isbW32m(MCU, DRMC, DRMCbuffer);
+
+    for (Rank = 0; Rank < NUM_RANKS; Rank++)
+    {
+      // Skip to next populated rank
+      if ((mrc_params->rank_enables & (1 << Rank)) == 0)
+      {
+        continue;
+      }
+
+      dram_init_command(DCMD_NOP(Rank));
+    }
+
+    isbW32m(MCU, DRMC, DRMC_DEFAULT);
+  }
+
+  // setup for emrs 2
+  // BIT[15:11] --> Always "0"
+  // BIT[10:09] --> Rtt_WR: want "Dynamic ODT Off" (0)
+  // BIT[08]    --> Always "0"
+  // BIT[07]    --> SRT: use sr_temp_range
+  // BIT[06]    --> ASR: want "Manual SR Reference" (0)
+  // BIT[05:03] --> CWL: use oem_tCWL
+  // BIT[02:00] --> PASR: want "Full Array" (0)
+  emrs2Command.raw = 0;
+  emrs2Command.field.bankAddress = 2;
+
+  WL = 5 + mrc_params->ddr_speed;
+  emrs2Command.field.CWL = WL - 5;
+  emrs2Command.field.SRT = mrc_params->sr_temp_range;
+
+  // setup for emrs 3
+  // BIT[15:03] --> Always "0"
+  // BIT[02]    --> MPR: want "Normal Operation" (0)
+  // BIT[01:00] --> MPR_Loc: want "Predefined Pattern" (0)
+  emrs3Command.raw = 0;
+  emrs3Command.field.bankAddress = 3;
+
+  // setup for emrs 1
+  // BIT[15:13]     --> Always "0"
+  // BIT[12:12]     --> Qoff: want "Output Buffer Enabled" (0)
+  // BIT[11:11]     --> TDQS: want "Disabled" (0)
+  // BIT[10:10]     --> Always "0"
+  // BIT[09,06,02]  --> Rtt_nom: use rtt_nom_value
+  // BIT[08]        --> Always "0"
+  // BIT[07]        --> WR_LVL: want "Disabled" (0)
+  // BIT[05,01]     --> DIC: use ron_value
+  // BIT[04:03]     --> AL: additive latency want "0" (0)
+  // BIT[00]        --> DLL: want "Enable" (0)
+  //
+  // (BIT5|BIT1) set Ron value
+  // 00 --> RZQ/6 (40ohm)
+  // 01 --> RZQ/7 (34ohm)
+  // 1* --> RESERVED
+  //
+  // (BIT9|BIT6|BIT2) set Rtt_nom value
+  // 000 --> Disabled
+  // 001 --> RZQ/4 ( 60ohm)
+  // 010 --> RZQ/2 (120ohm)
+  // 011 --> RZQ/6 ( 40ohm)
+  // 1** --> RESERVED
+  emrs1Command.raw = 0;
+  emrs1Command.field.bankAddress = 1;
+  emrs1Command.field.dllEnabled = 0; // 0 = Enable , 1 = Disable
+
+  if (mrc_params->ron_value == 0)
+  {
+    emrs1Command.field.DIC0 = DDR3_EMRS1_DIC_34;
+  }
+  else
+  {
+    emrs1Command.field.DIC0 = DDR3_EMRS1_DIC_40;
+  }
+
+
+  if (mrc_params->rtt_nom_value == 0)
+  {
+    emrs1Command.raw |= (DDR3_EMRS1_RTTNOM_40 << 6);
+  }
+  else if (mrc_params->rtt_nom_value == 1)
+  {
+    emrs1Command.raw |= (DDR3_EMRS1_RTTNOM_60 << 6);
+  }
+  else if (mrc_params->rtt_nom_value == 2)
+  {
+    emrs1Command.raw |= (DDR3_EMRS1_RTTNOM_120 << 6);
+  }
+
+  // save MRS1 value (excluding control fields)
+  mrc_params->mrs1 = emrs1Command.raw >> 6;
+
+  // setup for mrs 0
+  // BIT[15:13]     --> Always "0"
+  // BIT[12]        --> PPD: for Quark (1)
+  // BIT[11:09]     --> WR: use oem_tWR
+  // BIT[08]        --> DLL: want "Reset" (1, self clearing)
+  // BIT[07]        --> MODE: want "Normal" (0)
+  // BIT[06:04,02]  --> CL: use oem_tCAS
+  // BIT[03]        --> RD_BURST_TYPE: want "Interleave" (1)
+  // BIT[01:00]     --> BL: want "8 Fixed" (0)
+  // WR:
+  // 0 --> 16
+  // 1 --> 5
+  // 2 --> 6
+  // 3 --> 7
+  // 4 --> 8
+  // 5 --> 10
+  // 6 --> 12
+  // 7 --> 14
+  // CL:
+  // BIT[02:02] "0" if oem_tCAS <= 11 (1866?)
+  // BIT[06:04] use oem_tCAS-4
+  mrs0Command.raw = 0;
+  mrs0Command.field.bankAddress = 0;
+  mrs0Command.field.dllReset = 1;
+  mrs0Command.field.BL = 0;
+  mrs0Command.field.PPD = 1;
+  mrs0Command.field.casLatency = DTR0reg.field.tCL + 1;
+
+  TCK = tCK[mrc_params->ddr_speed];
+  TWR = MCEIL(15000, TCK);   // Per JEDEC: tWR=15000ps DDR2/3 from 800-1600
+  mrs0Command.field.writeRecovery = TWR - 4;
+
+  for (Rank = 0; Rank < NUM_RANKS; Rank++)
+  {
+    // Skip to next populated rank
+    if ((mrc_params->rank_enables & (1 << Rank)) == 0)
+    {
+      continue;
+    }
+
+    emrs2Command.field.rankSelect = Rank;
+    dram_init_command(emrs2Command.raw);
+
+    emrs3Command.field.rankSelect = Rank;
+    dram_init_command(emrs3Command.raw);
+
+    emrs1Command.field.rankSelect = Rank;
+    dram_init_command(emrs1Command.raw);
+
+    mrs0Command.field.rankSelect = Rank;
+    dram_init_command(mrs0Command.raw);
+
+    dram_init_command(DCMD_ZQCL(Rank));
+  }
+
+  LEAVEFN();
+  return;
+}
+
+// rcvn_cal:
+// POST_CODE[major] == 0x05
+//
+// This function will perform our RCVEN Calibration Algorithm.
+// We will only use the 2xCLK domain timings to perform RCVEN Calibration.
+// All byte lanes will be calibrated "simultaneously" per channel per rank.
+static void rcvn_cal(
+    MRCParams_t *mrc_params)
+{
+  uint8_t channel_i; // channel counter
+  uint8_t rank_i; // rank counter
+  uint8_t bl_i; // byte lane counter
+  uint8_t bl_divisor = (mrc_params->channel_width == x16) ? 2 : 1; // byte lane divisor
+
+#ifdef R2R_SHARING
+  uint32_t final_delay[NUM_CHANNELS][NUM_BYTE_LANES]; // used to find placement for rank2rank sharing configs
+#ifndef BACKUP_RCVN
+  uint32_t num_ranks_enabled = 0; // used to find placement for rank2rank sharing configs
+#endif // BACKUP_RCVN
+#endif // R2R_SHARING
+
+#ifdef BACKUP_RCVN
+#else
+  uint32_t tempD; // temporary DWORD
+  uint32_t delay[NUM_BYTE_LANES]; // absolute PI value to be programmed on the byte lane
+  RegDTR1 dtr1;
+  RegDTR1 dtr1save;
+#endif // BACKUP_RCVN
+  ENTERFN();
+
+  // rcvn_cal starts
+  post_code(0x05, 0x00);
+
+#ifndef BACKUP_RCVN
+  // need separate burst to sample DQS preamble
+  dtr1.raw = dtr1save.raw = isbR32m(MCU, DTR1);
+  dtr1.field.tCCD = 1;
+  isbW32m(MCU, DTR1, dtr1.raw);
+#endif
+
+#ifdef R2R_SHARING
+  // need to set "final_delay[][]" elements to "0"
+  memset((void *) (final_delay), 0x00, (size_t) sizeof(final_delay));
+#endif // R2R_SHARING
+
+  // loop through each enabled channel
+  for (channel_i = 0; channel_i < NUM_CHANNELS; channel_i++)
+  {
+    if (mrc_params->channel_enables & (1 << channel_i))
+    {
+      // perform RCVEN Calibration on a per rank basis
+      for (rank_i = 0; rank_i < NUM_RANKS; rank_i++)
+      {
+        if (mrc_params->rank_enables & (1 << rank_i))
+        {
+          // POST_CODE here indicates the current channel and rank being calibrated
+          post_code(0x05, (0x10 + ((channel_i << 4) | rank_i)));
+
+#ifdef BACKUP_RCVN
+          // set hard-coded timing values
+          for (bl_i=0; bl_i<(NUM_BYTE_LANES/bl_divisor); bl_i++)
+          {
+            set_rcvn(channel_i, rank_i, bl_i, ddr_rcvn[PLATFORM_ID]);
+          }
+#else
+          // enable FIFORST
+          for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i += 2)
+          {
+            isbM32m(DDRPHY, (B01PTRCTL1 + ((bl_i >> 1) * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), 0,
+                BIT8); // 0 is enabled
+          } // bl_i loop
+          // initialise the starting delay to 128 PI (tCAS +1 CLK)
+          for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++)
+          {
+#ifdef SIM
+            // Original value was late at the end of DQS sequence
+            delay[bl_i] = 3 * FULL_CLK;
+#else
+            delay[bl_i] = (4 + 1) * FULL_CLK; // 1x CLK domain timing is tCAS-4
+#endif
+
+            set_rcvn(channel_i, rank_i, bl_i, delay[bl_i]);
+          } // bl_i loop
+
+          // now find the rising edge
+          find_rising_edge(mrc_params, delay, channel_i, rank_i, true);
+          // Now increase delay by 32 PI (1/4 CLK) to place in center of high pulse.
+          for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++)
+          {
+            delay[bl_i] += QRTR_CLK;
+            set_rcvn(channel_i, rank_i, bl_i, delay[bl_i]);
+          } // bl_i loop
+          // Now decrement delay by 128 PI (1 CLK) until we sample a "0"
+          do
+          {
+
+            tempD = sample_dqs(mrc_params, channel_i, rank_i, true);
+            for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++)
+            {
+              if (tempD & (1 << bl_i))
+              {
+                if (delay[bl_i] >= FULL_CLK)
+                {
+                  delay[bl_i] -= FULL_CLK;
+                  set_rcvn(channel_i, rank_i, bl_i, delay[bl_i]);
+                }
+                else
+                {
+                  // not enough delay
+                  training_message(channel_i, rank_i, bl_i);
+                  post_code(0xEE, 0x50);
+                }
+              }
+            } // bl_i loop
+          } while (tempD & 0xFF);
+
+#ifdef R2R_SHARING
+          // increment "num_ranks_enabled"
+          num_ranks_enabled++;
+          // Finally increment delay by 32 PI (1/4 CLK) to place in center of preamble.
+          for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++)
+          {
+            delay[bl_i] += QRTR_CLK;
+            // add "delay[]" values to "final_delay[][]" for rolling average
+            final_delay[channel_i][bl_i] += delay[bl_i];
+            // set timing based on rolling average values
+            set_rcvn(channel_i, rank_i, bl_i, ((final_delay[channel_i][bl_i]) / num_ranks_enabled));
+          } // bl_i loop
+#else
+          // Finally increment delay by 32 PI (1/4 CLK) to place in center of preamble.
+          for (bl_i=0; bl_i<(NUM_BYTE_LANES/bl_divisor); bl_i++)
+          {
+            delay[bl_i] += QRTR_CLK;
+            set_rcvn(channel_i, rank_i, bl_i, delay[bl_i]);
+          } // bl_i loop
+
+#endif // R2R_SHARING
+
+          // disable FIFORST
+          for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i += 2)
+          {
+            isbM32m(DDRPHY, (B01PTRCTL1 + ((bl_i >> 1) * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)), BIT8,
+                BIT8); // 1 is disabled
+          } // bl_i loop
+
+#endif // BACKUP_RCVN
+
+        } // if rank is enabled
+      } // rank_i loop
+    } // if channel is enabled
+  } // channel_i loop
+
+#ifndef BACKUP_RCVN
+  // restore original
+  isbW32m(MCU, DTR1, dtr1save.raw);
+#endif
+
+#ifdef MRC_SV
+  if (mrc_params->tune_rcvn)
+  {
+    uint32_t rcven, val;
+    uint32_t rdcmd2rcven;
+
+    /*
+     Formulas for RDCMD2DATAVALID & DIFFAMP dynamic timings
+
+     1. Set after RCVEN training
+
+     //Tune RDCMD2DATAVALID
+
+     x80/x84[21:16]
+     MAX OF 2 RANKS : round up (rdcmd2rcven (rcven 1x) + 2x x 2 + PI/128) + 5
+
+     //rdcmd2rcven x80/84[12:8]
+     //rcven 2x x70[23:20] & [11:8]
+
+     //Tune DIFFAMP Timings
+
+     //diffampen launch x88[20:16] & [4:0]  -- B01LATCTL1
+     MIN OF 2 RANKS : round down (rcven 1x + 2x x 2 + PI/128) - 1
+
+     //diffampen length x8C/x90 [13:8]   -- B0ONDURCTL B1ONDURCTL
+     MAX OF 2 RANKS : roundup (rcven 1x + 2x x 2 + PI/128) + 5
+
+
+     2. need to do a fiforst after settings these values
+    */
+
+    DPF(D_INFO, "BEFORE\n");
+    DPF(D_INFO, "### %x\n", isbR32m(DDRPHY, B0LATCTL0));
+    DPF(D_INFO, "### %x\n", isbR32m(DDRPHY, B01LATCTL1));
+    DPF(D_INFO, "### %x\n", isbR32m(DDRPHY, B0ONDURCTL));
+
+    DPF(D_INFO, "### %x\n", isbR32m(DDRPHY, B1LATCTL0));
+    DPF(D_INFO, "### %x\n", isbR32m(DDRPHY, B1ONDURCTL));
+
+    rcven = get_rcvn(0, 0, 0) / 128;
+    rdcmd2rcven = (isbR32m(DDRPHY, B0LATCTL0) >> 8) & 0x1F;
+    val = rdcmd2rcven + rcven + 6;
+    isbM32m(DDRPHY, B0LATCTL0, val << 16, (BIT21|BIT20|BIT19|BIT18|BIT17|BIT16));
+
+    val = rdcmd2rcven + rcven - 1;
+    isbM32m(DDRPHY, B01LATCTL1, val << 0, (BIT4|BIT3|BIT2|BIT1|BIT0));
+
+    val = rdcmd2rcven + rcven + 5;
+    isbM32m(DDRPHY, B0ONDURCTL, val << 8, (BIT13|BIT12|BIT11|BIT10|BIT9|BIT8));
+
+    rcven = get_rcvn(0, 0, 1) / 128;
+    rdcmd2rcven = (isbR32m(DDRPHY, B1LATCTL0) >> 8) & 0x1F;
+    val = rdcmd2rcven + rcven + 6;
+    isbM32m(DDRPHY, B1LATCTL0, val << 16, (BIT21|BIT20|BIT19|BIT18|BIT17|BIT16));
+
+    val = rdcmd2rcven + rcven - 1;
+    isbM32m(DDRPHY, B01LATCTL1, val << 16, (BIT20|BIT19|BIT18|BIT17|BIT16));
+
+    val = rdcmd2rcven + rcven + 5;
+    isbM32m(DDRPHY, B1ONDURCTL, val << 8, (BIT13|BIT12|BIT11|BIT10|BIT9|BIT8));
+
+    DPF(D_INFO, "AFTER\n");
+    DPF(D_INFO, "### %x\n", isbR32m(DDRPHY, B0LATCTL0));
+    DPF(D_INFO, "### %x\n", isbR32m(DDRPHY, B01LATCTL1));
+    DPF(D_INFO, "### %x\n", isbR32m(DDRPHY, B0ONDURCTL));
+
+    DPF(D_INFO, "### %x\n", isbR32m(DDRPHY, B1LATCTL0));
+    DPF(D_INFO, "### %x\n", isbR32m(DDRPHY, B1ONDURCTL));
+
+    DPF(D_INFO, "\nPress a key\n");
+    mgetc();
+
+    // fifo reset
+    isbM32m(DDRPHY, B01PTRCTL1, 0, BIT8); // 0 is enabled
+    delay_n(3);
+    isbM32m(DDRPHY, B01PTRCTL1, BIT8, BIT8); // 1 is disabled
+  }
+#endif
+
+  LEAVEFN();
+  return;
+}
+
+// Check memory executing write/read/verify of many data patterns
+// at the specified address. Bits in the result indicate failure
+// on specific byte lane.
+static uint32_t check_bls_ex(
+    MRCParams_t *mrc_params,
+    uint32_t address)
+{
+  uint32_t result;
+  uint8_t first_run = 0;
+
+  if (mrc_params->hte_setup)
+  {
+    mrc_params->hte_setup = 0;
+
+    first_run = 1;
+    select_hte(mrc_params);
+  }
+
+  result = WriteStressBitLanesHTE(mrc_params, address, first_run);
+
+  DPF(D_TRN, "check_bls_ex result is %x\n", result);
+  return result;
+}
+
+// Check memory executing simple write/read/verify at
+// the specified address. Bits in the result indicate failure
+// on specific byte lane.
+static uint32_t check_rw_coarse(
+    MRCParams_t *mrc_params,
+    uint32_t address)
+{
+  uint32_t result = 0;
+  uint8_t first_run = 0;
+
+  if (mrc_params->hte_setup)
+  {
+    mrc_params->hte_setup = 0;
+
+    first_run = 1;
+    select_hte(mrc_params);
+  }
+
+  result = BasicWriteReadHTE(mrc_params, address, first_run, WRITE_TRAIN);
+
+  DPF(D_TRN, "check_rw_coarse result is %x\n", result);
+  return result;
+}
+
+// wr_level:
+// POST_CODE[major] == 0x06
+//
+// This function will perform the Write Levelling algorithm (align WCLK and WDQS).
+// This algorithm will act on each rank in each channel separately.
+static void wr_level(
+    MRCParams_t *mrc_params)
+{
+  uint8_t channel_i; // channel counter
+  uint8_t rank_i; // rank counter
+  uint8_t bl_i; // byte lane counter
+  uint8_t bl_divisor = (mrc_params->channel_width == x16) ? 2 : 1; // byte lane divisor
+
+#ifdef R2R_SHARING
+  uint32_t final_delay[NUM_CHANNELS][NUM_BYTE_LANES]; // used to find placement for rank2rank sharing configs
+#ifndef BACKUP_WDQS
+  uint32_t num_ranks_enabled = 0; // used to find placement for rank2rank sharing configs
+#endif // BACKUP_WDQS
+#endif // R2R_SHARING
+
+#ifdef BACKUP_WDQS
+#else
+  bool all_edges_found; // determines stop condition for CRS_WR_LVL
+  uint32_t delay[NUM_BYTE_LANES]; // absolute PI value to be programmed on the byte lane
+  // static makes it so the data is loaded in the heap once by shadow(), where
+  // non-static copies the data onto the stack every time this function is called.
+
+  uint32_t address; // address to be checked during COARSE_WR_LVL
+  RegDTR4 dtr4;
+  RegDTR4 dtr4save;
+#endif // BACKUP_WDQS
+
+  ENTERFN();
+
+  // wr_level starts
+  post_code(0x06, 0x00);
+
+#ifdef R2R_SHARING
+  // need to set "final_delay[][]" elements to "0"
+  memset((void *) (final_delay), 0x00, (size_t) sizeof(final_delay));
+#endif // R2R_SHARING
+  // loop through each enabled channel
+  for (channel_i = 0; channel_i < NUM_CHANNELS; channel_i++)
+  {
+    if (mrc_params->channel_enables & (1 << channel_i))
+    {
+      // perform WRITE LEVELING algorithm on a per rank basis
+      for (rank_i = 0; rank_i < NUM_RANKS; rank_i++)
+      {
+        if (mrc_params->rank_enables & (1 << rank_i))
+        {
+          // POST_CODE here indicates the current rank and channel being calibrated
+          post_code(0x06, (0x10 + ((channel_i << 4) | rank_i)));
+
+#ifdef BACKUP_WDQS
+          for (bl_i=0; bl_i<(NUM_BYTE_LANES/bl_divisor); bl_i++)
+          {
+            set_wdqs(channel_i, rank_i, bl_i, ddr_wdqs[PLATFORM_ID]);
+            set_wdq(channel_i, rank_i, bl_i, (ddr_wdqs[PLATFORM_ID] - QRTR_CLK));
+          }
+#else
+
+          { // Begin product specific code
+
+            // perform a single PRECHARGE_ALL command to make DRAM state machine go to IDLE state
+            dram_init_command(DCMD_PREA(rank_i));
+
+            // enable Write Levelling Mode (EMRS1 w/ Write Levelling Mode Enable)
+            dram_init_command(DCMD_MRS1(rank_i,0x0082));
+
+            // set ODT DRAM Full Time Termination disable in MCU
+            dtr4.raw = dtr4save.raw = isbR32m(MCU, DTR4);
+            dtr4.field.ODTDIS = 1;
+            isbW32m(MCU, DTR4, dtr4.raw);
+
+            for (bl_i = 0; bl_i < ((NUM_BYTE_LANES / bl_divisor) / 2); bl_i++)
+            {
+              isbM32m(DDRPHY, DQCTL + (DDRIODQ_BL_OFFSET * bl_i) + (DDRIODQ_CH_OFFSET * channel_i),
+                  (BIT28 | (0x1 << 8) | (0x1 << 6) | (0x1 << 4) | (0x1 << 2)),
+                  (BIT28 | (BIT9|BIT8) | (BIT7|BIT6) | (BIT5|BIT4) | (BIT3|BIT2))); // Enable Sandy Bridge Mode (WDQ Tri-State) & Ensure 5 WDQS pulses during Write Leveling
+            }
+
+            isbM32m(DDRPHY, CCDDR3RESETCTL + (DDRIOCCC_CH_OFFSET * channel_i), (BIT16), (BIT16)); // Write Leveling Mode enabled in IO
+          } // End product specific code
+          // Initialise the starting delay to WCLK
+          for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++)
+          {
+            { // Begin product specific code
+              // CLK0 --> RK0
+              // CLK1 --> RK1
+              delay[bl_i] = get_wclk(channel_i, rank_i);
+            } // End product specific code
+            set_wdqs(channel_i, rank_i, bl_i, delay[bl_i]);
+          } // bl_i loop
+          // now find the rising edge
+          find_rising_edge(mrc_params, delay, channel_i, rank_i, false);
+          { // Begin product specific code
+            // disable Write Levelling Mode
+            isbM32m(DDRPHY, CCDDR3RESETCTL + (DDRIOCCC_CH_OFFSET * channel_i), (0), (BIT16)); // Write Leveling Mode disabled in IO
+
+            for (bl_i = 0; bl_i < ((NUM_BYTE_LANES / bl_divisor) / 2); bl_i++)
+            {
+              isbM32m(DDRPHY, DQCTL + (DDRIODQ_BL_OFFSET * bl_i) + (DDRIODQ_CH_OFFSET * channel_i),
+                  ((0x1 << 8) | (0x1 << 6) | (0x1 << 4) | (0x1 << 2)),
+                  (BIT28 | (BIT9|BIT8) | (BIT7|BIT6) | (BIT5|BIT4) | (BIT3|BIT2))); // Disable Sandy Bridge Mode & Ensure 4 WDQS pulses during normal operation
+            } // bl_i loop
+
+            // restore original DTR4
+            isbW32m(MCU, DTR4, dtr4save.raw);
+
+            // restore original value (Write Levelling Mode Disable)
+            dram_init_command(DCMD_MRS1(rank_i, mrc_params->mrs1));
+
+            // perform a single PRECHARGE_ALL command to make DRAM state machine go to IDLE state
+            dram_init_command(DCMD_PREA(rank_i));
+          } // End product specific code
+
+          post_code(0x06, (0x30 + ((channel_i << 4) | rank_i)));
+
+          // COARSE WRITE LEVEL:
+          // check that we're on the correct clock edge
+
+          // hte reconfiguration request
+          mrc_params->hte_setup = 1;
+
+          // start CRS_WR_LVL with WDQS = WDQS + 128 PI
+          for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++)
+          {
+            delay[bl_i] = get_wdqs(channel_i, rank_i, bl_i) + FULL_CLK;
+            set_wdqs(channel_i, rank_i, bl_i, delay[bl_i]);
+            // program WDQ timings based on WDQS (WDQ = WDQS - 32 PI)
+            set_wdq(channel_i, rank_i, bl_i, (delay[bl_i] - QRTR_CLK));
+          } // bl_i loop
+
+          // get an address in the targeted channel/rank
+          address = get_addr(mrc_params, channel_i, rank_i);
+          do
+          {
+            uint32_t coarse_result = 0x00;
+            uint32_t coarse_result_mask = byte_lane_mask(mrc_params);
+            all_edges_found = true; // assume pass
+
+#ifdef SIM
+            // need restore memory to idle state as write can be in bad sync
+            dram_init_command (DCMD_PREA(rank_i));
+#endif
+
+            mrc_params->hte_setup = 1;
+            coarse_result = check_rw_coarse(mrc_params, address);
+
+            // check for failures and margin the byte lane back 128 PI (1 CLK)
+            for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++)
+            {
+              if (coarse_result & (coarse_result_mask << bl_i))
+              {
+                all_edges_found = false;
+                delay[bl_i] -= FULL_CLK;
+                set_wdqs(channel_i, rank_i, bl_i, delay[bl_i]);
+                // program WDQ timings based on WDQS (WDQ = WDQS - 32 PI)
+                set_wdq(channel_i, rank_i, bl_i, (delay[bl_i] - QRTR_CLK));
+              }
+            } // bl_i loop
+
+          } while (!all_edges_found);
+
+#ifdef R2R_SHARING
+          // increment "num_ranks_enabled"
+          num_ranks_enabled++;
+          // accumulate "final_delay[][]" values from "delay[]" values for rolling average
+          for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++)
+          {
+            final_delay[channel_i][bl_i] += delay[bl_i];
+            set_wdqs(channel_i, rank_i, bl_i, ((final_delay[channel_i][bl_i]) / num_ranks_enabled));
+            // program WDQ timings based on WDQS (WDQ = WDQS - 32 PI)
+            set_wdq(channel_i, rank_i, bl_i, ((final_delay[channel_i][bl_i]) / num_ranks_enabled) - QRTR_CLK);
+          } // bl_i loop
+#endif // R2R_SHARING
+#endif // BACKUP_WDQS
+
+        } // if rank is enabled
+      } // rank_i loop
+    } // if channel is enabled
+  } // channel_i loop
+
+  LEAVEFN();
+  return;
+}
+
+// rd_train:
+// POST_CODE[major] == 0x07
+//
+// This function will perform the READ TRAINING Algorithm on all channels/ranks/byte_lanes simultaneously to minimize execution time.
+// The idea here is to train the VREF and RDQS (and eventually RDQ) values to achieve maximum READ margins.
+// The algorithm will first determine the X coordinate (RDQS setting).
+// This is done by collapsing the VREF eye until we find a minimum required RDQS eye for VREF_MIN and VREF_MAX.
+// Then we take the averages of the RDQS eye at VREF_MIN and VREF_MAX, then average those; this will be the final X coordinate.
+// The algorithm will then determine the Y coordinate (VREF setting).
+// This is done by collapsing the RDQS eye until we find a minimum required VREF eye for RDQS_MIN and RDQS_MAX.
+// Then we take the averages of the VREF eye at RDQS_MIN and RDQS_MAX, then average those; this will be the final Y coordinate.
+// NOTE: this algorithm assumes the eye curves have a one-to-one relationship, meaning for each X the curve has only one Y and vice-a-versa.
+static void rd_train(
+    MRCParams_t *mrc_params)
+{
+
+#define MIN_RDQS_EYE 10 // in PI Codes
+#define MIN_VREF_EYE 10 // in VREF Codes
+#define RDQS_STEP 1     // how many RDQS codes to jump while margining
+#define VREF_STEP 1     // how many VREF codes to jump while margining
+#define VREF_MIN (0x00) // offset into "vref_codes[]" for minimum allowed VREF setting
+#define VREF_MAX (0x3F) // offset into "vref_codes[]" for maximum allowed VREF setting
+#define RDQS_MIN (0x00) // minimum RDQS delay value
+#define RDQS_MAX (0x3F) // maximum RDQS delay value
+#define B 0 // BOTTOM VREF
+#define T 1 // TOP VREF
+#define L 0 // LEFT RDQS
+#define R 1 // RIGHT RDQS
+
+  uint8_t channel_i; // channel counter
+  uint8_t rank_i; // rank counter
+  uint8_t bl_i; // byte lane counter
+  uint8_t bl_divisor = (mrc_params->channel_width == x16) ? 2 : 1; // byte lane divisor
+#ifdef BACKUP_RDQS
+#else
+  uint8_t side_x; // tracks LEFT/RIGHT approach vectors
+  uint8_t side_y; // tracks BOTTOM/TOP approach vectors
+  uint8_t x_coordinate[2/*side_x*/][2/*side_y*/][NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES]; // X coordinate data (passing RDQS values) for approach vectors
+  uint8_t y_coordinate[2/*side_x*/][2/*side_y*/][NUM_CHANNELS][NUM_BYTE_LANES]; // Y coordinate data (passing VREF values) for approach vectors
+  uint8_t x_center[NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES]; // centered X (RDQS)
+  uint8_t y_center[NUM_CHANNELS][NUM_BYTE_LANES]; // centered Y (VREF)
+  uint32_t address; // target address for "check_bls_ex()"
+  uint32_t result; // result of "check_bls_ex()"
+  uint32_t bl_mask; // byte lane mask for "result" checking
+#ifdef R2R_SHARING
+  uint32_t final_delay[NUM_CHANNELS][NUM_BYTE_LANES]; // used to find placement for rank2rank sharing configs
+  uint32_t num_ranks_enabled = 0; // used to find placement for rank2rank sharing configs
+#endif // R2R_SHARING
+#endif // BACKUP_RDQS
+  // rd_train starts
+  post_code(0x07, 0x00);
+
+  ENTERFN();
+
+#ifdef BACKUP_RDQS
+  for (channel_i=0; channel_i<NUM_CHANNELS; channel_i++)
+  {
+    if (mrc_params->channel_enables & (1<<channel_i))
+    {
+      for (rank_i=0; rank_i<NUM_RANKS; rank_i++)
+      {
+        if (mrc_params->rank_enables & (1<<rank_i))
+        {
+          for (bl_i=0; bl_i<(NUM_BYTE_LANES/bl_divisor); bl_i++)
+          {
+            set_rdqs(channel_i, rank_i, bl_i, ddr_rdqs[PLATFORM_ID]);
+          } // bl_i loop
+        } // if rank is enabled
+      } // rank_i loop
+    } // if channel is enabled
+  } // channel_i loop
+#else
+  // initialise x/y_coordinate arrays
+  for (channel_i = 0; channel_i < NUM_CHANNELS; channel_i++)
+  {
+    if (mrc_params->channel_enables & (1 << channel_i))
+    {
+      for (rank_i = 0; rank_i < NUM_RANKS; rank_i++)
+      {
+        if (mrc_params->rank_enables & (1 << rank_i))
+        {
+          for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++)
+          {
+            // x_coordinate:
+            x_coordinate[L][B][channel_i][rank_i][bl_i] = RDQS_MIN;
+            x_coordinate[R][B][channel_i][rank_i][bl_i] = RDQS_MAX;
+            x_coordinate[L][T][channel_i][rank_i][bl_i] = RDQS_MIN;
+            x_coordinate[R][T][channel_i][rank_i][bl_i] = RDQS_MAX;
+            // y_coordinate:
+            y_coordinate[L][B][channel_i][bl_i] = VREF_MIN;
+            y_coordinate[R][B][channel_i][bl_i] = VREF_MIN;
+            y_coordinate[L][T][channel_i][bl_i] = VREF_MAX;
+            y_coordinate[R][T][channel_i][bl_i] = VREF_MAX;
+          } // bl_i loop
+        } // if rank is enabled
+      } // rank_i loop
+    } // if channel is enabled
+  } // channel_i loop
+
+  // initialise other variables
+  bl_mask = byte_lane_mask(mrc_params);
+  address = get_addr(mrc_params, 0, 0);
+
+#ifdef R2R_SHARING
+  // need to set "final_delay[][]" elements to "0"
+  memset((void *) (final_delay), 0x00, (size_t) sizeof(final_delay));
+#endif // R2R_SHARING
+
+  // look for passing coordinates
+  for (side_y = B; side_y <= T; side_y++)
+  {
+    for (side_x = L; side_x <= R; side_x++)
+    {
+
+      post_code(0x07, (0x10 + (side_y * 2) + (side_x)));
+
+      // find passing values
+      for (channel_i = 0; channel_i < NUM_CHANNELS; channel_i++)
+      {
+        if (mrc_params->channel_enables & (0x1 << channel_i))
+        {
+          for (rank_i = 0; rank_i < NUM_RANKS; rank_i++)
+          {
+
+            if (mrc_params->rank_enables & (0x1 << rank_i))
+            {
+              // set x/y_coordinate search starting settings
+              for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++)
+              {
+                set_rdqs(channel_i, rank_i, bl_i, x_coordinate[side_x][side_y][channel_i][rank_i][bl_i]);
+                set_vref(channel_i, bl_i, y_coordinate[side_x][side_y][channel_i][bl_i]);
+              } // bl_i loop
+              // get an address in the target channel/rank
+              address = get_addr(mrc_params, channel_i, rank_i);
+
+              // request HTE reconfiguration
+              mrc_params->hte_setup = 1;
+
+              // test the settings
+              do
+              {
+
+                // result[07:00] == failing byte lane (MAX 8)
+                result = check_bls_ex( mrc_params, address);
+
+                // check for failures
+                if (result & 0xFF)
+                {
+                  // at least 1 byte lane failed
+                  for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++)
+                  {
+                    if (result & (bl_mask << bl_i))
+                    {
+                      // adjust the RDQS values accordingly
+                      if (side_x == L)
+                      {
+                        x_coordinate[L][side_y][channel_i][rank_i][bl_i] += RDQS_STEP;
+                      }
+                      else
+                      {
+                        x_coordinate[R][side_y][channel_i][rank_i][bl_i] -= RDQS_STEP;
+                      }
+                      // check that we haven't closed the RDQS_EYE too much
+                      if ((x_coordinate[L][side_y][channel_i][rank_i][bl_i] > (RDQS_MAX - MIN_RDQS_EYE)) ||
+                          (x_coordinate[R][side_y][channel_i][rank_i][bl_i] < (RDQS_MIN + MIN_RDQS_EYE))
+                          ||
+                          (x_coordinate[L][side_y][channel_i][rank_i][bl_i]
+                              == x_coordinate[R][side_y][channel_i][rank_i][bl_i]))
+                      {
+                        // not enough RDQS margin available at this VREF
+                        // update VREF values accordingly
+                        if (side_y == B)
+                        {
+                          y_coordinate[side_x][B][channel_i][bl_i] += VREF_STEP;
+                        }
+                        else
+                        {
+                          y_coordinate[side_x][T][channel_i][bl_i] -= VREF_STEP;
+                        }
+                        // check that we haven't closed the VREF_EYE too much
+                        if ((y_coordinate[side_x][B][channel_i][bl_i] > (VREF_MAX - MIN_VREF_EYE)) ||
+                            (y_coordinate[side_x][T][channel_i][bl_i] < (VREF_MIN + MIN_VREF_EYE)) ||
+                            (y_coordinate[side_x][B][channel_i][bl_i] == y_coordinate[side_x][T][channel_i][bl_i]))
+                        {
+                          // VREF_EYE collapsed below MIN_VREF_EYE
+                          training_message(channel_i, rank_i, bl_i);
+                          post_code(0xEE, (0x70 + (side_y * 2) + (side_x)));
+                        }
+                        else
+                        {
+                          // update the VREF setting
+                          set_vref(channel_i, bl_i, y_coordinate[side_x][side_y][channel_i][bl_i]);
+                          // reset the X coordinate to begin the search at the new VREF
+                          x_coordinate[side_x][side_y][channel_i][rank_i][bl_i] =
+                              (side_x == L) ? (RDQS_MIN) : (RDQS_MAX);
+                        }
+                      }
+                      // update the RDQS setting
+                      set_rdqs(channel_i, rank_i, bl_i, x_coordinate[side_x][side_y][channel_i][rank_i][bl_i]);
+                    } // if bl_i failed
+                  } // bl_i loop
+                } // at least 1 byte lane failed
+              } while (result & 0xFF);
+            } // if rank is enabled
+          } // rank_i loop
+        } // if channel is enabled
+      } // channel_i loop
+    } // side_x loop
+  } // side_y loop
+
+  post_code(0x07, 0x20);
+
+  // find final RDQS (X coordinate) & final VREF (Y coordinate)
+  for (channel_i = 0; channel_i < NUM_CHANNELS; channel_i++)
+  {
+    if (mrc_params->channel_enables & (1 << channel_i))
+    {
+      for (rank_i = 0; rank_i < NUM_RANKS; rank_i++)
+      {
+        if (mrc_params->rank_enables & (1 << rank_i))
+        {
+          for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++)
+          {
+            uint32_t tempD1;
+            uint32_t tempD2;
+
+            // x_coordinate:
+            DPF(D_INFO, "RDQS T/B eye rank%d lane%d : %d-%d %d-%d\n", rank_i, bl_i,
+                x_coordinate[L][T][channel_i][rank_i][bl_i],
+                x_coordinate[R][T][channel_i][rank_i][bl_i],
+                x_coordinate[L][B][channel_i][rank_i][bl_i],
+                x_coordinate[R][B][channel_i][rank_i][bl_i]);
+
+            tempD1 = (x_coordinate[R][T][channel_i][rank_i][bl_i] + x_coordinate[L][T][channel_i][rank_i][bl_i]) / 2; // average the TOP side LEFT & RIGHT values
+            tempD2 = (x_coordinate[R][B][channel_i][rank_i][bl_i] + x_coordinate[L][B][channel_i][rank_i][bl_i]) / 2; // average the BOTTOM side LEFT & RIGHT values
+            x_center[channel_i][rank_i][bl_i] = (uint8_t) ((tempD1 + tempD2) / 2); // average the above averages
+
+            // y_coordinate:
+            DPF(D_INFO, "VREF R/L eye lane%d : %d-%d %d-%d\n", bl_i,
+                y_coordinate[R][B][channel_i][bl_i],
+                y_coordinate[R][T][channel_i][bl_i],
+                y_coordinate[L][B][channel_i][bl_i],
+                y_coordinate[L][T][channel_i][bl_i]);
+
+            tempD1 = (y_coordinate[R][T][channel_i][bl_i] + y_coordinate[R][B][channel_i][bl_i]) / 2; // average the RIGHT side TOP & BOTTOM values
+            tempD2 = (y_coordinate[L][T][channel_i][bl_i] + y_coordinate[L][B][channel_i][bl_i]) / 2; // average the LEFT side TOP & BOTTOM values
+            y_center[channel_i][bl_i] = (uint8_t) ((tempD1 + tempD2) / 2); // average the above averages
+          } // bl_i loop
+        } // if rank is enabled
+      } // rank_i loop
+    } // if channel is enabled
+  } // channel_i loop
+
+#ifdef RX_EYE_CHECK
+  // perform an eye check
+  for (side_y=B; side_y<=T; side_y++)
+  {
+    for (side_x=L; side_x<=R; side_x++)
+    {
+
+      post_code(0x07, (0x30 + (side_y * 2) + (side_x)));
+
+      // update the settings for the eye check
+      for (channel_i=0; channel_i<NUM_CHANNELS; channel_i++)
+      {
+        if (mrc_params->channel_enables & (1<<channel_i))
+        {
+          for (rank_i=0; rank_i<NUM_RANKS; rank_i++)
+          {
+            if (mrc_params->rank_enables & (1<<rank_i))
+            {
+              for (bl_i=0; bl_i<(NUM_BYTE_LANES/bl_divisor); bl_i++)
+              {
+                if (side_x == L)
+                {
+                  set_rdqs(channel_i, rank_i, bl_i, (x_center[channel_i][rank_i][bl_i] - (MIN_RDQS_EYE / 2)));
+                }
+                else
+                {
+                  set_rdqs(channel_i, rank_i, bl_i, (x_center[channel_i][rank_i][bl_i] + (MIN_RDQS_EYE / 2)));
+                }
+                if (side_y == B)
+                {
+                  set_vref(channel_i, bl_i, (y_center[channel_i][bl_i] - (MIN_VREF_EYE / 2)));
+                }
+                else
+                {
+                  set_vref(channel_i, bl_i, (y_center[channel_i][bl_i] + (MIN_VREF_EYE / 2)));
+                }
+              } // bl_i loop
+            } // if rank is enabled
+          } // rank_i loop
+        } // if channel is enabled
+      } // channel_i loop
+
+      // request HTE reconfiguration
+      mrc_params->hte_setup = 1;
+
+      // check the eye
+      if (check_bls_ex( mrc_params, address) & 0xFF)
+      {
+        // one or more byte lanes failed
+        post_code(0xEE, (0x74 + (side_x * 2) + (side_y)));
+      }
+    } // side_x loop
+  } // side_y loop
+#endif // RX_EYE_CHECK
+
+  post_code(0x07, 0x40);
+
+  // set final placements
+  for (channel_i = 0; channel_i < NUM_CHANNELS; channel_i++)
+  {
+    if (mrc_params->channel_enables & (1 << channel_i))
+    {
+      for (rank_i = 0; rank_i < NUM_RANKS; rank_i++)
+      {
+        if (mrc_params->rank_enables & (1 << rank_i))
+        {
+#ifdef R2R_SHARING
+          // increment "num_ranks_enabled"
+          num_ranks_enabled++;
+#endif // R2R_SHARING
+          for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++)
+          {
+            // x_coordinate:
+#ifdef R2R_SHARING
+            final_delay[channel_i][bl_i] += x_center[channel_i][rank_i][bl_i];
+            set_rdqs(channel_i, rank_i, bl_i, ((final_delay[channel_i][bl_i]) / num_ranks_enabled));
+#else
+            set_rdqs(channel_i, rank_i, bl_i, x_center[channel_i][rank_i][bl_i]);
+#endif // R2R_SHARING
+            // y_coordinate:
+            set_vref(channel_i, bl_i, y_center[channel_i][bl_i]);
+          } // bl_i loop
+        } // if rank is enabled
+      } // rank_i loop
+    } // if channel is enabled
+  } // channel_i loop
+#endif // BACKUP_RDQS
+  LEAVEFN();
+  return;
+}
+
+// wr_train:
+// POST_CODE[major] == 0x08
+//
+// This function will perform the WRITE TRAINING Algorithm on all channels/ranks/byte_lanes simultaneously to minimize execution time.
+// The idea here is to train the WDQ timings to achieve maximum WRITE margins.
+// The algorithm will start with WDQ at the current WDQ setting (tracks WDQS in WR_LVL) +/- 32 PIs (+/- 1/4 CLK) and collapse the eye until all data patterns pass.
+// This is because WDQS will be aligned to WCLK by the Write Leveling algorithm and WDQ will only ever have a 1/2 CLK window of validity.
+static void wr_train(
+    MRCParams_t *mrc_params)
+{
+
+#define WDQ_STEP 1 // how many WDQ codes to jump while margining
+#define L 0 // LEFT side loop value definition
+#define R 1 // RIGHT side loop value definition
+
+  uint8_t channel_i; // channel counter
+  uint8_t rank_i; // rank counter
+  uint8_t bl_i; // byte lane counter
+  uint8_t bl_divisor = (mrc_params->channel_width == x16) ? 2 : 1; // byte lane divisor
+#ifdef BACKUP_WDQ
+#else
+  uint8_t side_i; // LEFT/RIGHT side indicator (0=L, 1=R)
+  uint32_t tempD; // temporary DWORD
+  uint32_t delay[2/*side_i*/][NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES]; // 2 arrays, for L & R side passing delays
+  uint32_t address; // target address for "check_bls_ex()"
+  uint32_t result; // result of "check_bls_ex()"
+  uint32_t bl_mask; // byte lane mask for "result" checking
+#ifdef R2R_SHARING
+  uint32_t final_delay[NUM_CHANNELS][NUM_BYTE_LANES]; // used to find placement for rank2rank sharing configs
+  uint32_t num_ranks_enabled = 0; // used to find placement for rank2rank sharing configs
+#endif // R2R_SHARING
+#endif // BACKUP_WDQ
+
+  // wr_train starts
+  post_code(0x08, 0x00);
+
+  ENTERFN();
+
+#ifdef BACKUP_WDQ
+  for (channel_i=0; channel_i<NUM_CHANNELS; channel_i++)
+  {
+    if (mrc_params->channel_enables & (1<<channel_i))
+    {
+      for (rank_i=0; rank_i<NUM_RANKS; rank_i++)
+      {
+        if (mrc_params->rank_enables & (1<<rank_i))
+        {
+          for (bl_i=0; bl_i<(NUM_BYTE_LANES/bl_divisor); bl_i++)
+          {
+            set_wdq(channel_i, rank_i, bl_i, ddr_wdq[PLATFORM_ID]);
+          } // bl_i loop
+        } // if rank is enabled
+      } // rank_i loop
+    } // if channel is enabled
+  } // channel_i loop
+#else
+  // initialise "delay"
+  for (channel_i = 0; channel_i < NUM_CHANNELS; channel_i++)
+  {
+    if (mrc_params->channel_enables & (1 << channel_i))
+    {
+      for (rank_i = 0; rank_i < NUM_RANKS; rank_i++)
+      {
+        if (mrc_params->rank_enables & (1 << rank_i))
+        {
+          for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++)
+          {
+            // want to start with WDQ = (WDQS - QRTR_CLK) +/- QRTR_CLK
+            tempD = get_wdqs(channel_i, rank_i, bl_i) - QRTR_CLK;
+            delay[L][channel_i][rank_i][bl_i] = tempD - QRTR_CLK;
+            delay[R][channel_i][rank_i][bl_i] = tempD + QRTR_CLK;
+          } // bl_i loop
+        } // if rank is enabled
+      } // rank_i loop
+    } // if channel is enabled
+  } // channel_i loop
+
+  // initialise other variables
+  bl_mask = byte_lane_mask(mrc_params);
+  address = get_addr(mrc_params, 0, 0);
+
+#ifdef R2R_SHARING
+  // need to set "final_delay[][]" elements to "0"
+  memset((void *) (final_delay), 0x00, (size_t) sizeof(final_delay));
+#endif // R2R_SHARING
+
+  // start algorithm on the LEFT side and train each channel/bl until no failures are observed, then repeat for the RIGHT side.
+  for (side_i = L; side_i <= R; side_i++)
+  {
+    post_code(0x08, (0x10 + (side_i)));
+
+    // set starting values
+    for (channel_i = 0; channel_i < NUM_CHANNELS; channel_i++)
+    {
+      if (mrc_params->channel_enables & (1 << channel_i))
+      {
+        for (rank_i = 0; rank_i < NUM_RANKS; rank_i++)
+        {
+          if (mrc_params->rank_enables & (1 << rank_i))
+          {
+            for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++)
+            {
+              set_wdq(channel_i, rank_i, bl_i, delay[side_i][channel_i][rank_i][bl_i]);
+            } // bl_i loop
+          } // if rank is enabled
+        } // rank_i loop
+      } // if channel is enabled
+    } // channel_i loop
+
+    // find passing values
+    for (channel_i = 0; channel_i < NUM_CHANNELS; channel_i++)
+    {
+      if (mrc_params->channel_enables & (0x1 << channel_i))
+      {
+        for (rank_i = 0; rank_i < NUM_RANKS; rank_i++)
+        {
+          if (mrc_params->rank_enables & (0x1 << rank_i))
+          {
+            // get an address in the target channel/rank
+            address = get_addr(mrc_params, channel_i, rank_i);
+
+            // request HTE reconfiguration
+            mrc_params->hte_setup = 1;
+
+            // check the settings
+            do
+            {
+
+#ifdef SIM
+              // need restore memory to idle state as write can be in bad sync
+              dram_init_command (DCMD_PREA(rank_i));
+#endif
+
+              // result[07:00] == failing byte lane (MAX 8)
+              result = check_bls_ex( mrc_params, address);
+              // check for failures
+              if (result & 0xFF)
+              {
+                // at least 1 byte lane failed
+                for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++)
+                {
+                  if (result & (bl_mask << bl_i))
+                  {
+                    if (side_i == L)
+                    {
+                      delay[L][channel_i][rank_i][bl_i] += WDQ_STEP;
+                    }
+                    else
+                    {
+                      delay[R][channel_i][rank_i][bl_i] -= WDQ_STEP;
+                    }
+                    // check for algorithm failure
+                    if (delay[L][channel_i][rank_i][bl_i] != delay[R][channel_i][rank_i][bl_i])
+                    {
+                      // margin available, update delay setting
+                      set_wdq(channel_i, rank_i, bl_i, delay[side_i][channel_i][rank_i][bl_i]);
+                    }
+                    else
+                    {
+                      // no margin available, notify the user and halt
+                      training_message(channel_i, rank_i, bl_i);
+                      post_code(0xEE, (0x80 + side_i));
+                    }
+                  } // if bl_i failed
+                } // bl_i loop
+              } // at least 1 byte lane failed
+            } while (result & 0xFF); // stop when all byte lanes pass
+          } // if rank is enabled
+        } // rank_i loop
+      } // if channel is enabled
+    } // channel_i loop
+  } // side_i loop
+
+  // program WDQ to the middle of passing window
+  for (channel_i = 0; channel_i < NUM_CHANNELS; channel_i++)
+  {
+    if (mrc_params->channel_enables & (1 << channel_i))
+    {
+      for (rank_i = 0; rank_i < NUM_RANKS; rank_i++)
+      {
+        if (mrc_params->rank_enables & (1 << rank_i))
+        {
+#ifdef R2R_SHARING
+          // increment "num_ranks_enabled"
+          num_ranks_enabled++;
+#endif // R2R_SHARING
+          for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++)
+          {
+
+            DPF(D_INFO, "WDQ eye rank%d lane%d : %d-%d\n", rank_i, bl_i,
+                delay[L][channel_i][rank_i][bl_i],
+                delay[R][channel_i][rank_i][bl_i]);
+
+            tempD = (delay[R][channel_i][rank_i][bl_i] + delay[L][channel_i][rank_i][bl_i]) / 2;
+
+#ifdef R2R_SHARING
+            final_delay[channel_i][bl_i] += tempD;
+            set_wdq(channel_i, rank_i, bl_i, ((final_delay[channel_i][bl_i]) / num_ranks_enabled));
+#else
+            set_wdq(channel_i, rank_i, bl_i, tempD);
+#endif // R2R_SHARING
+
+          } // bl_i loop
+        } // if rank is enabled
+      } // rank_i loop
+    } // if channel is enabled
+  } // channel_i loop
+#endif // BACKUP_WDQ
+  LEAVEFN();
+  return;
+}
+
+// Wrapper for jedec initialisation routine
+static void perform_jedec_init(
+    MRCParams_t *mrc_params)
+{
+  jedec_init(mrc_params, 0);
+}
+
+// Configure DDRPHY for Auto-Refresh, Periodic Compensations,
+// Dynamic Diff-Amp, ZQSPERIOD, Auto-Precharge, CKE Power-Down
+static void set_auto_refresh(
+    MRCParams_t *mrc_params)
+{
+  uint32_t channel_i;
+  uint32_t rank_i;
+  uint32_t bl_i;
+  uint32_t bl_divisor = /*(mrc_params->channel_width==x16)?2:*/1;
+  uint32_t tempD;
+
+  ENTERFN();
+
+  // enable Auto-Refresh, Periodic Compensations, Dynamic Diff-Amp, ZQSPERIOD, Auto-Precharge, CKE Power-Down
+  for (channel_i = 0; channel_i < NUM_CHANNELS; channel_i++)
+  {
+    if (mrc_params->channel_enables & (1 << channel_i))
+    {
+      // Enable Periodic RCOMPS
+      isbM32m(DDRPHY, CMPCTRL, (BIT1), (BIT1));
+
+
+      // Enable Dynamic DiffAmp & Set Read ODT Value
+      switch (mrc_params->rd_odt_value)
+      {
+        case 0: tempD = 0x3F; break;  // OFF
+        default: tempD = 0x00; break; // Auto
+      } // rd_odt_value switch
+
+      for (bl_i=0; bl_i<((NUM_BYTE_LANES/bl_divisor)/2); bl_i++)
+      {
+        isbM32m(DDRPHY, (B0OVRCTL + (bl_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)),
+            ((0x00<<16)|(tempD<<10)),
+            ((BIT21|BIT20|BIT19|BIT18|BIT17|BIT16)|(BIT15|BIT14|BIT13|BIT12|BIT11|BIT10))); // Override: DIFFAMP, ODT
+
+        isbM32m(DDRPHY, (B1OVRCTL + (bl_i * DDRIODQ_BL_OFFSET) + (channel_i * DDRIODQ_CH_OFFSET)),
+            ((0x00<<16)|(tempD<<10)),
+            ((BIT21|BIT20|BIT19|BIT18|BIT17|BIT16)|(BIT15|BIT14|BIT13|BIT12|BIT11|BIT10)));// Override: DIFFAMP, ODT
+      } // bl_i loop
+
+      // Issue ZQCS command
+      for (rank_i = 0; rank_i < NUM_RANKS; rank_i++)
+      {
+        if (mrc_params->rank_enables & (1 << rank_i))
+        {
+          dram_init_command(DCMD_ZQCS(rank_i));
+        } // if rank_i enabled
+      } // rank_i loop
+
+    } // if channel_i enabled
+  } // channel_i loop
+
+  clear_pointers();
+
+  LEAVEFN();
+  return;
+}
+
+// Depending on configuration enables ECC support.
+// Available memory size is decresed, and updated with 0s
+// in order to clear error status. Address mode 2 forced.
+static void ecc_enable(
+    MRCParams_t *mrc_params)
+{
+  RegDRP Drp;
+  RegDSCH Dsch;
+  RegDECCCTRL Ctr;
+
+  if (mrc_params->ecc_enables == 0) return;
+
+  ENTERFN();
+
+  // Configuration required in ECC mode
+  Drp.raw = isbR32m(MCU, DRP);
+  Drp.field.addressMap = 2;
+  Drp.field.split64 = 1;
+  isbW32m(MCU, DRP, Drp.raw);
+
+  // Disable new request bypass
+  Dsch.raw = isbR32m(MCU, DSCH);
+  Dsch.field.NEWBYPDIS = 1;
+  isbW32m(MCU, DSCH, Dsch.raw);
+
+  // Enable ECC
+  Ctr.raw = 0;
+  Ctr.field.SBEEN = 1;
+  Ctr.field.DBEEN = 1;
+  Ctr.field.ENCBGEN = 1;
+  isbW32m(MCU, DECCCTRL, Ctr.raw);
+
+#ifdef SIM
+  // Read back to be sure writing took place
+  Ctr.raw = isbR32m(MCU, DECCCTRL);
+#endif
+
+  // Assume 8 bank memory, one bank is gone for ECC
+  mrc_params->mem_size -= mrc_params->mem_size / 8;
+
+  // For S3 resume memory content has to be preserved
+  if (mrc_params->boot_mode != bmS3)
+  {
+    select_hte(mrc_params);
+    HteMemInit(mrc_params, MrcMemInit, MrcHaltHteEngineOnError);
+    select_memory_manager(mrc_params);
+  }
+
+  LEAVEFN();
+  return;
+}
+
+// Lock MCU registers at the end of initialisation sequence.
+static void lock_registers(
+    MRCParams_t *mrc_params)
+{
+  RegDCO Dco;
+
+  ENTERFN();
+
+  Dco.raw = isbR32m(MCU, DCO);
+  Dco.field.PMIDIS = 0;          //0 - PRI enabled
+  Dco.field.PMICTL = 0;          //0 - PRI owned by MEMORY_MANAGER
+  Dco.field.DRPLOCK = 1;
+  Dco.field.REUTLOCK = 1;
+  isbW32m(MCU, DCO, Dco.raw);
+
+  LEAVEFN();
+
+}
+
+#ifdef MRC_SV
+
+// cache write back invalidate
+static void asm_wbinvd(void)
+{
+#if defined (SIM) || defined (GCC)
+  asm(
+    "wbinvd;"
+  );
+#else
+  __asm wbinvd;
+#endif
+}
+
+// cache invalidate
+static void asm_invd(void)
+{
+#if defined (SIM) || defined (GCC)
+  asm(
+      "invd;"
+  );
+#else
+  __asm invd;
+#endif
+}
+
+
+static void cpu_read(void)
+{
+  uint32_t adr, dat, limit;
+
+  asm_invd();
+
+  limit = 8 * 1024;
+  for (adr = 0; adr < limit; adr += 4)
+  {
+    dat = *(uint32_t*) adr;
+    if ((adr & 0x0F) == 0)
+    {
+      DPF(D_INFO, "\n%x : ", adr);
+    }
+    DPF(D_INFO, "%x ", dat);
+  }
+  DPF(D_INFO, "\n");
+
+  DPF(D_INFO, "CPU read done\n");
+}
+
+
+static void cpu_write(void)
+{
+  uint32_t adr, limit;
+
+  limit = 8 * 1024;
+  for (adr = 0; adr < limit; adr += 4)
+  {
+    *(uint32_t*) adr = 0xDEAD0000 + adr;
+  }
+
+  asm_wbinvd();
+
+  DPF(D_INFO, "CPU write done\n");
+}
+
+
+static void cpu_memory_test(
+    MRCParams_t *mrc_params)
+{
+  uint32_t result = 0;
+  uint32_t val, dat, adr, adr0, step, limit;
+  uint64_t my_tsc;
+
+  ENTERFN();
+
+  asm_invd();
+
+  adr0 = 1 * 1024 * 1024;
+  limit = 256 * 1024 * 1024;
+
+  for (step = 0; step <= 4; step++)
+  {
+    DPF(D_INFO, "Mem test step %d starting from %xh\n", step, adr0);
+
+    my_tsc = read_tsc();
+    for (adr = adr0; adr < limit; adr += sizeof(uint32_t))
+    {
+      if (step == 0)      dat = adr;
+      else if (step == 1) dat = (1 << ((adr >> 2) & 0x1f));
+      else if (step == 2) dat = ~(1 << ((adr >> 2) & 0x1f));
+      else if (step == 3) dat = 0x5555AAAA;
+      else if (step == 4) dat = 0xAAAA5555;
+
+      *(uint32_t*) adr = dat;
+    }
+    DPF(D_INFO, "Write time %llXh\n", read_tsc() - my_tsc);
+
+    my_tsc = read_tsc();
+    for (adr = adr0; adr < limit; adr += sizeof(uint32_t))
+    {
+      if (step == 0)      dat = adr;
+      else if (step == 1) dat = (1 << ((adr >> 2) & 0x1f));
+      else if (step == 2) dat = ~(1 << ((adr >> 2) & 0x1f));
+      else if (step == 3) dat = 0x5555AAAA;
+      else if (step == 4) dat = 0xAAAA5555;
+
+      val = *(uint32_t*) adr;
+
+      if (val != dat)
+      {
+        DPF(D_INFO, "%x vs. %x@%x\n", dat, val, adr);
+        result = adr|BIT31;
+      }
+    }
+    DPF(D_INFO, "Read time %llXh\n", read_tsc() - my_tsc);
+  }
+
+  DPF( D_INFO, "Memory test result %x\n", result);
+  LEAVEFN();
+}
+#endif // MRC_SV
+
+
+// Execute memory test, if error dtected it is
+// indicated in mrc_params->status.
+static void memory_test(
+  MRCParams_t *mrc_params)
+{
+  uint32_t result = 0;
+
+  ENTERFN();
+
+  select_hte(mrc_params);
+  result = HteMemInit(mrc_params, MrcMemTest, MrcHaltHteEngineOnError);
+  select_memory_manager(mrc_params);
+
+  DPF(D_INFO, "Memory test result %x\n", result);
+  mrc_params->status = ((result == 0) ? MRC_SUCCESS : MRC_E_MEMTEST);
+  LEAVEFN();
+}
+
+
+// Force same timings as with backup settings
+static void static_timings(
+  MRCParams_t *mrc_params)
+
+{
+  uint8_t ch, rk, bl;
+
+  for (ch = 0; ch < NUM_CHANNELS; ch++)
+  {
+    for (rk = 0; rk < NUM_RANKS; rk++)
+    {
+      for (bl = 0; bl < NUM_BYTE_LANES; bl++)
+      {
+        set_rcvn(ch, rk, bl, 498);  // RCVN
+        set_rdqs(ch, rk, bl,  24);  // RDQS
+        set_wdqs(ch, rk, bl, 292);  // WDQS
+        set_wdq( ch, rk, bl, 260);  // WDQ
+        if (rk == 0)
+        {
+          set_vref(ch, bl, 32); // VREF (RANK0 only)
+        }
+      }
+      set_wctl(ch, rk, 217); // WCTL
+    }
+    set_wcmd(ch, 220); // WCMD
+  }
+
+  return;
+}
+
+//
+// Initialise system memory.
+//
+void MemInit(
+  MRCParams_t *mrc_params)
+{
+  static const MemInit_t init[] =
+  {
+    { 0x0101, bmCold|bmFast|bmWarm|bmS3, clear_self_refresh       }, //0
+    { 0x0200, bmCold|bmFast|bmWarm|bmS3, prog_ddr_timing_control  }, //1  initialise the MCU
+    { 0x0103, bmCold|bmFast            , prog_decode_before_jedec }, //2
+    { 0x0104, bmCold|bmFast            , perform_ddr_reset        }, //3
+    { 0x0300, bmCold|bmFast       |bmS3, ddrphy_init              }, //4  initialise the DDRPHY
+    { 0x0400, bmCold|bmFast            , perform_jedec_init       }, //5  perform JEDEC initialisation of DRAMs
+    { 0x0105, bmCold|bmFast            , set_ddr_init_complete    }, //6
+    { 0x0106,        bmFast|bmWarm|bmS3, restore_timings          }, //7
+    { 0x0106, bmCold                   , default_timings          }, //8
+    { 0x0500, bmCold                   , rcvn_cal                 }, //9  perform RCVN_CAL algorithm
+    { 0x0600, bmCold                   , wr_level                 }, //10  perform WR_LEVEL algorithm
+    { 0x0120, bmCold                   , prog_page_ctrl           }, //11
+    { 0x0700, bmCold                   , rd_train                 }, //12  perform RD_TRAIN algorithm
+    { 0x0800, bmCold                   , wr_train                 }, //13  perform WR_TRAIN algorithm
+    { 0x010B, bmCold                   , store_timings            }, //14
+    { 0x010C, bmCold|bmFast|bmWarm|bmS3, enable_scrambling        }, //15
+    { 0x010D, bmCold|bmFast|bmWarm|bmS3, prog_ddr_control         }, //16
+    { 0x010E, bmCold|bmFast|bmWarm|bmS3, prog_dra_drb             }, //17
+    { 0x010F,               bmWarm|bmS3, perform_wake             }, //18
+    { 0x0110, bmCold|bmFast|bmWarm|bmS3, change_refresh_period    }, //19
+    { 0x0111, bmCold|bmFast|bmWarm|bmS3, set_auto_refresh         }, //20
+    { 0x0112, bmCold|bmFast|bmWarm|bmS3, ecc_enable               }, //21
+    { 0x0113, bmCold|bmFast            , memory_test              }, //22
+    { 0x0114, bmCold|bmFast|bmWarm|bmS3, lock_registers           }  //23 set init done
+  };
+
+  uint32_t i;
+
+  ENTERFN();
+
+  DPF(D_INFO, "Meminit build %s %s\n", __DATE__, __TIME__);
+
+  // MRC started
+  post_code(0x01, 0x00);
+
+  if (mrc_params->boot_mode != bmCold)
+  {
+    if (mrc_params->ddr_speed != mrc_params->timings.ddr_speed)
+    {
+      // full training required as frequency changed
+      mrc_params->boot_mode = bmCold;
+    }
+  }
+
+  for (i = 0; i < MCOUNT(init); i++)
+  {
+    uint64_t my_tsc;
+
+#ifdef MRC_SV
+    if (mrc_params->menu_after_mrc && i > 14)
+    {
+      uint8_t ch;
+
+      mylop:
+
+      DPF(D_INFO, "-- c - continue --\n");
+      DPF(D_INFO, "-- j - move to jedec init --\n");
+      DPF(D_INFO, "-- m - memory test --\n");
+      DPF(D_INFO, "-- r - cpu read --\n");
+      DPF(D_INFO, "-- w - cpu write --\n");
+      DPF(D_INFO, "-- b - hte base test --\n");
+      DPF(D_INFO, "-- g - hte extended test --\n");
+
+      ch = mgetc();
+      switch (ch)
+      {
+      case 'c':
+        break;
+      case 'j':  //move to jedec init
+        i = 5;
+        break;
+
+      case 'M':
+      case 'N':
+        {
+    uint32_t n, res, cnt=0;
+
+    for(n=0; mgetch()==0; n++)
+    {
+      if( ch == 'M' || n % 256 == 0)
+      {
+        DPF(D_INFO, "n=%d e=%d\n", n, cnt);
+      }
+
+      res = 0;
+
+      if( ch == 'M')
+      {
+        memory_test(mrc_params);
+        res |= mrc_params->status;
+            }
+
+      mrc_params->hte_setup = 1;
+            res |= check_bls_ex(mrc_params, 0x00000000);
+            res |= check_bls_ex(mrc_params, 0x00000000);
+            res |= check_bls_ex(mrc_params, 0x00000000);
+            res |= check_bls_ex(mrc_params, 0x00000000);
+
+      if( mrc_params->rank_enables & 2)
+      {
+        mrc_params->hte_setup = 1;
+              res |= check_bls_ex(mrc_params, 0x40000000);
+              res |= check_bls_ex(mrc_params, 0x40000000);
+              res |= check_bls_ex(mrc_params, 0x40000000);
+              res |= check_bls_ex(mrc_params, 0x40000000);
+      }
+
+      if( res != 0)
+      {
+              DPF(D_INFO, "###########\n");
+              DPF(D_INFO, "#\n");
+              DPF(D_INFO, "# Error count %d\n", ++cnt);
+              DPF(D_INFO, "#\n");
+              DPF(D_INFO, "###########\n");
+      }
+
+    } // for
+
+          select_memory_manager(mrc_params);
+  }
+        goto mylop;
+      case 'm':
+        memory_test(mrc_params);
+        goto mylop;
+      case 'n':
+        cpu_memory_test(mrc_params);
+        goto mylop;
+
+      case 'l':
+        ch = mgetc();
+        if (ch <= '9') DpfPrintMask ^= (ch - '0') << 3;
+        DPF(D_INFO, "Log mask %x\n", DpfPrintMask);
+        goto mylop;
+      case 'p':
+        print_timings(mrc_params);
+        goto mylop;
+      case 'R':
+        rd_train(mrc_params);
+        goto mylop;
+      case 'W':
+        wr_train(mrc_params);
+        goto mylop;
+
+      case 'r':
+        cpu_read();
+        goto mylop;
+      case 'w':
+        cpu_write();
+        goto mylop;
+
+      case 'g':
+        {
+        uint32_t result;
+        select_hte(mrc_params);
+        mrc_params->hte_setup = 1;
+        result = check_bls_ex(mrc_params, 0);
+        DPF(D_INFO, "Extended test result %x\n", result);
+        select_memory_manager(mrc_params);
+        }
+        goto mylop;
+      case 'b':
+        {
+        uint32_t result;
+        select_hte(mrc_params);
+        mrc_params->hte_setup = 1;
+        result = check_rw_coarse(mrc_params, 0);
+        DPF(D_INFO, "Base test result %x\n", result);
+        select_memory_manager(mrc_params);
+        }
+        goto mylop;
+      case 'B':
+        select_hte(mrc_params);
+        HteMemOp(0x2340, 1, 1);
+        select_memory_manager(mrc_params);
+        goto mylop;
+
+      case '3':
+        {
+        RegDPMC0 DPMC0reg;
+
+        DPF( D_INFO, "===>> Start suspend\n");
+        isbR32m(MCU, DSTAT);
+
+        DPMC0reg.raw = isbR32m(MCU, DPMC0);
+        DPMC0reg.field.DYNSREN = 0;
+        DPMC0reg.field.powerModeOpCode = 0x05;    // Disable Master DLL
+        isbW32m(MCU, DPMC0, DPMC0reg.raw);
+
+        // Should be off for negative test case verification
+        #if 1
+        Wr32(MMIO, PCIADDR(0,0,0,SB_PACKET_REG),
+            (uint32_t)SB_COMMAND(SB_SUSPEND_CMND_OPCODE, MCU, 0));
+        #endif
+
+        DPF( D_INFO, "press key\n");
+        mgetc();
+        DPF( D_INFO, "===>> Start resume\n");
+        isbR32m(MCU, DSTAT);
+
+        mrc_params->boot_mode = bmS3;
+        i = 0;
+        }
+
+      } // switch
+
+    } // if( menu
+#endif //MRC_SV
+
+    if (mrc_params->boot_mode & init[i].boot_path)
+    {
+      uint8_t major = init[i].post_code >> 8 & 0xFF;
+      uint8_t minor = init[i].post_code >> 0 & 0xFF;
+      post_code(major, minor);
+
+      my_tsc = read_tsc();
+      init[i].init_fn(mrc_params);
+      DPF(D_TIME, "Execution time %llX", read_tsc() - my_tsc);
+    }
+  }
+
+  // display the timings
+  print_timings(mrc_params);
+
+  // MRC is complete.
+  post_code(0x01, 0xFF);
+
+  LEAVEFN();
+  return;
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit.h
new file mode 100644
index 0000000000..961bbef9c7
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit.h
@@ -0,0 +1,22 @@
+/************************************************************************
+ *
+ * Copyright (c) 2013-2015 Intel Corporation.
+ *
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ ************************************************************************/
+#ifndef _MEMINIT_H_
+#define _MEMINIT_H_
+
+// function prototypes
+void MemInit(MRCParams_t *mrc_params);
+
+typedef void (*MemInitFn_t)(MRCParams_t *mrc_params);
+
+typedef struct MemInit_s {
+  uint16_t    post_code;
+  uint16_t    boot_path;
+  MemInitFn_t init_fn;
+} MemInit_t;
+
+#endif // _MEMINIT_H_
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit_utils.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit_utils.c
new file mode 100644
index 0000000000..84de65955f
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit_utils.c
@@ -0,0 +1,1574 @@
+/************************************************************************
+ *
+ * Copyright (c) 2013-2015 Intel Corporation.
+ *
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ ***************************************************************************/
+
+#include "mrc.h"
+#include "memory_options.h"
+
+#include "meminit_utils.h"
+#include "hte.h"
+#include "io.h"
+
+void select_hte(
+    MRCParams_t *mrc_params);
+
+static uint8_t first_run = 0;
+
+const uint8_t vref_codes[64] =
+{ // lowest to highest
+    0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, // 00 - 15
+    0x2F, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, // 16 - 31
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, // 32 - 47
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F  // 48 - 63
+};
+
+#ifdef EMU
+// Track current post code for debugging purpose
+uint32_t PostCode;
+#endif
+
+// set_rcvn:
+//
+// This function will program the RCVEN delays.
+// (currently doesn't comprehend rank)
+void set_rcvn(
+    uint8_t channel,
+    uint8_t rank,
+    uint8_t byte_lane,
+    uint32_t pi_count)
+{
+  uint32_t reg;
+  uint32_t msk;
+  uint32_t tempD;
+
+  ENTERFN();
+  DPF(D_TRN, "Rcvn ch%d rnk%d ln%d : pi=%03X\n", channel, rank, byte_lane, pi_count);
+
+  // RDPTR (1/2 MCLK, 64 PIs)
+  // BL0 -> B01PTRCTL0[11:08] (0x0-0xF)
+  // BL1 -> B01PTRCTL0[23:20] (0x0-0xF)
+  reg = B01PTRCTL0 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET);
+  msk = (byte_lane & BIT0) ? (BIT23 | BIT22 | BIT21 | BIT20) : (BIT11 | BIT10 | BIT9 | BIT8);
+  tempD = (byte_lane & BIT0) ? ((pi_count / HALF_CLK) << 20) : ((pi_count / HALF_CLK) << 8);
+  isbM32m(DDRPHY, reg, tempD, msk);
+
+  // Adjust PI_COUNT
+  pi_count -= ((pi_count / HALF_CLK) & 0xF) * HALF_CLK;
+
+  // PI (1/64 MCLK, 1 PIs)
+  // BL0 -> B0DLLPICODER0[29:24] (0x00-0x3F)
+  // BL1 -> B1DLLPICODER0[29:24] (0x00-0x3F)
+  reg = (byte_lane & BIT0) ? (B1DLLPICODER0) : (B0DLLPICODER0);
+  reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET));
+  msk = (BIT29 | BIT28 | BIT27 | BIT26 | BIT25 | BIT24);
+  tempD = pi_count << 24;
+  isbM32m(DDRPHY, reg, tempD, msk);
+
+  // DEADBAND
+  // BL0/1 -> B01DBCTL1[08/11] (+1 select)
+  // BL0/1 -> B01DBCTL1[02/05] (enable)
+  reg = B01DBCTL1 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET);
+  msk = 0x00;
+  tempD = 0x00;
+  // enable
+  msk |= (byte_lane & BIT0) ? (BIT5) : (BIT2);
+  if ((pi_count < EARLY_DB) || (pi_count > LATE_DB))
+  {
+    tempD |= msk;
+  }
+  // select
+  msk |= (byte_lane & BIT0) ? (BIT11) : (BIT8);
+  if (pi_count < EARLY_DB)
+  {
+    tempD |= msk;
+  }
+  isbM32m(DDRPHY, reg, tempD, msk);
+
+  // error check
+  if (pi_count > 0x3F)
+  {
+    training_message(channel, rank, byte_lane);
+    post_code(0xEE, 0xE0);
+  }
+
+  LEAVEFN();
+  return;
+}
+
+// get_rcvn:
+//
+// This function will return the current RCVEN delay on the given channel, rank, byte_lane as an absolute PI count.
+// (currently doesn't comprehend rank)
+uint32_t get_rcvn(
+    uint8_t channel,
+    uint8_t rank,
+    uint8_t byte_lane)
+{
+  uint32_t reg;
+  uint32_t tempD;
+  uint32_t pi_count;
+
+  ENTERFN();
+
+  // RDPTR (1/2 MCLK, 64 PIs)
+  // BL0 -> B01PTRCTL0[11:08] (0x0-0xF)
+  // BL1 -> B01PTRCTL0[23:20] (0x0-0xF)
+  reg = B01PTRCTL0 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET);
+  tempD = isbR32m(DDRPHY, reg);
+  tempD >>= (byte_lane & BIT0) ? (20) : (8);
+  tempD &= 0xF;
+
+  // Adjust PI_COUNT
+  pi_count = tempD * HALF_CLK;
+
+  // PI (1/64 MCLK, 1 PIs)
+  // BL0 -> B0DLLPICODER0[29:24] (0x00-0x3F)
+  // BL1 -> B1DLLPICODER0[29:24] (0x00-0x3F)
+  reg = (byte_lane & BIT0) ? (B1DLLPICODER0) : (B0DLLPICODER0);
+  reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET));
+  tempD = isbR32m(DDRPHY, reg);
+  tempD >>= 24;
+  tempD &= 0x3F;
+
+  // Adjust PI_COUNT
+  pi_count += tempD;
+
+  LEAVEFN();
+  return pi_count;
+}
+
+// set_rdqs:
+//
+// This function will program the RDQS delays based on an absolute amount of PIs.
+// (currently doesn't comprehend rank)
+void set_rdqs(
+    uint8_t channel,
+    uint8_t rank,
+    uint8_t byte_lane,
+    uint32_t pi_count)
+{
+  uint32_t reg;
+  uint32_t msk;
+  uint32_t tempD;
+
+  ENTERFN();
+  DPF(D_TRN, "Rdqs ch%d rnk%d ln%d : pi=%03X\n", channel, rank, byte_lane, pi_count);
+
+  // PI (1/128 MCLK)
+  // BL0 -> B0RXDQSPICODE[06:00] (0x00-0x47)
+  // BL1 -> B1RXDQSPICODE[06:00] (0x00-0x47)
+  reg = (byte_lane & BIT0) ? (B1RXDQSPICODE) : (B0RXDQSPICODE);
+  reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET));
+  msk = (BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0);
+  tempD = pi_count << 0;
+  isbM32m(DDRPHY, reg, tempD, msk);
+
+  // error check (shouldn't go above 0x3F)
+  if (pi_count > 0x47)
+  {
+    training_message(channel, rank, byte_lane);
+    post_code(0xEE, 0xE1);
+  }
+
+  LEAVEFN();
+  return;
+}
+
+// get_rdqs:
+//
+// This function will return the current RDQS delay on the given channel, rank, byte_lane as an absolute PI count.
+// (currently doesn't comprehend rank)
+uint32_t get_rdqs(
+    uint8_t channel,
+    uint8_t rank,
+    uint8_t byte_lane)
+{
+  uint32_t reg;
+  uint32_t tempD;
+  uint32_t pi_count;
+
+  ENTERFN();
+
+  // PI (1/128 MCLK)
+  // BL0 -> B0RXDQSPICODE[06:00] (0x00-0x47)
+  // BL1 -> B1RXDQSPICODE[06:00] (0x00-0x47)
+  reg = (byte_lane & BIT0) ? (B1RXDQSPICODE) : (B0RXDQSPICODE);
+  reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET));
+  tempD = isbR32m(DDRPHY, reg);
+
+  // Adjust PI_COUNT
+  pi_count = tempD & 0x7F;
+
+  LEAVEFN();
+  return pi_count;
+}
+
+// set_wdqs:
+//
+// This function will program the WDQS delays based on an absolute amount of PIs.
+// (currently doesn't comprehend rank)
+void set_wdqs(
+    uint8_t channel,
+    uint8_t rank,
+    uint8_t byte_lane,
+    uint32_t pi_count)
+{
+  uint32_t reg;
+  uint32_t msk;
+  uint32_t tempD;
+
+  ENTERFN();
+  DPF(D_TRN, "Wdqs ch%d rnk%d ln%d : pi=%03X\n", channel, rank, byte_lane, pi_count);
+
+  // RDPTR (1/2 MCLK, 64 PIs)
+  // BL0 -> B01PTRCTL0[07:04] (0x0-0xF)
+  // BL1 -> B01PTRCTL0[19:16] (0x0-0xF)
+  reg = B01PTRCTL0 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET);
+  msk = (byte_lane & BIT0) ? (BIT19 | BIT18 | BIT17 | BIT16) : (BIT7 | BIT6 | BIT5 | BIT4);
+  tempD = pi_count / HALF_CLK;
+  tempD <<= (byte_lane & BIT0) ? (16) : (4);
+  isbM32m(DDRPHY, reg, tempD, msk);
+
+  // Adjust PI_COUNT
+  pi_count -= ((pi_count / HALF_CLK) & 0xF) * HALF_CLK;
+
+  // PI (1/64 MCLK, 1 PIs)
+  // BL0 -> B0DLLPICODER0[21:16] (0x00-0x3F)
+  // BL1 -> B1DLLPICODER0[21:16] (0x00-0x3F)
+  reg = (byte_lane & BIT0) ? (B1DLLPICODER0) : (B0DLLPICODER0);
+  reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET));
+  msk = (BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | BIT16);
+  tempD = pi_count << 16;
+  isbM32m(DDRPHY, reg, tempD, msk);
+
+  // DEADBAND
+  // BL0/1 -> B01DBCTL1[07/10] (+1 select)
+  // BL0/1 -> B01DBCTL1[01/04] (enable)
+  reg = B01DBCTL1 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET);
+  msk = 0x00;
+  tempD = 0x00;
+  // enable
+  msk |= (byte_lane & BIT0) ? (BIT4) : (BIT1);
+  if ((pi_count < EARLY_DB) || (pi_count > LATE_DB))
+  {
+    tempD |= msk;
+  }
+  // select
+  msk |= (byte_lane & BIT0) ? (BIT10) : (BIT7);
+  if (pi_count < EARLY_DB)
+  {
+    tempD |= msk;
+  }
+  isbM32m(DDRPHY, reg, tempD, msk);
+
+  // error check
+  if (pi_count > 0x3F)
+  {
+    training_message(channel, rank, byte_lane);
+    post_code(0xEE, 0xE2);
+  }
+
+  LEAVEFN();
+  return;
+}
+
+// get_wdqs:
+//
+// This function will return the amount of WDQS delay on the given channel, rank, byte_lane as an absolute PI count.
+// (currently doesn't comprehend rank)
+uint32_t get_wdqs(
+    uint8_t channel,
+    uint8_t rank,
+    uint8_t byte_lane)
+{
+  uint32_t reg;
+  uint32_t tempD;
+  uint32_t pi_count;
+
+  ENTERFN();
+
+  // RDPTR (1/2 MCLK, 64 PIs)
+  // BL0 -> B01PTRCTL0[07:04] (0x0-0xF)
+  // BL1 -> B01PTRCTL0[19:16] (0x0-0xF)
+  reg = B01PTRCTL0 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET);
+  tempD = isbR32m(DDRPHY, reg);
+  tempD >>= (byte_lane & BIT0) ? (16) : (4);
+  tempD &= 0xF;
+
+  // Adjust PI_COUNT
+  pi_count = (tempD * HALF_CLK);
+
+  // PI (1/64 MCLK, 1 PIs)
+  // BL0 -> B0DLLPICODER0[21:16] (0x00-0x3F)
+  // BL1 -> B1DLLPICODER0[21:16] (0x00-0x3F)
+  reg = (byte_lane & BIT0) ? (B1DLLPICODER0) : (B0DLLPICODER0);
+  reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET));
+  tempD = isbR32m(DDRPHY, reg);
+  tempD >>= 16;
+  tempD &= 0x3F;
+
+  // Adjust PI_COUNT
+  pi_count += tempD;
+
+  LEAVEFN();
+  return pi_count;
+}
+
+// set_wdq:
+//
+// This function will program the WDQ delays based on an absolute number of PIs.
+// (currently doesn't comprehend rank)
+void set_wdq(
+    uint8_t channel,
+    uint8_t rank,
+    uint8_t byte_lane,
+    uint32_t pi_count)
+{
+  uint32_t reg;
+  uint32_t msk;
+  uint32_t tempD;
+
+  ENTERFN();
+  DPF(D_TRN, "Wdq ch%d rnk%d ln%d : pi=%03X\n", channel, rank, byte_lane, pi_count);
+
+  // RDPTR (1/2 MCLK, 64 PIs)
+  // BL0 -> B01PTRCTL0[03:00] (0x0-0xF)
+  // BL1 -> B01PTRCTL0[15:12] (0x0-0xF)
+  reg = B01PTRCTL0 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET);
+  msk = (byte_lane & BIT0) ? (BIT15 | BIT14 | BIT13 | BIT12) : (BIT3 | BIT2 | BIT1 | BIT0);
+  tempD = pi_count / HALF_CLK;
+  tempD <<= (byte_lane & BIT0) ? (12) : (0);
+  isbM32m(DDRPHY, reg, tempD, msk);
+
+  // Adjust PI_COUNT
+  pi_count -= ((pi_count / HALF_CLK) & 0xF) * HALF_CLK;
+
+  // PI (1/64 MCLK, 1 PIs)
+  // BL0 -> B0DLLPICODER0[13:08] (0x00-0x3F)
+  // BL1 -> B1DLLPICODER0[13:08] (0x00-0x3F)
+  reg = (byte_lane & BIT0) ? (B1DLLPICODER0) : (B0DLLPICODER0);
+  reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET));
+  msk = (BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8);
+  tempD = pi_count << 8;
+  isbM32m(DDRPHY, reg, tempD, msk);
+
+  // DEADBAND
+  // BL0/1 -> B01DBCTL1[06/09] (+1 select)
+  // BL0/1 -> B01DBCTL1[00/03] (enable)
+  reg = B01DBCTL1 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET);
+  msk = 0x00;
+  tempD = 0x00;
+  // enable
+  msk |= (byte_lane & BIT0) ? (BIT3) : (BIT0);
+  if ((pi_count < EARLY_DB) || (pi_count > LATE_DB))
+  {
+    tempD |= msk;
+  }
+  // select
+  msk |= (byte_lane & BIT0) ? (BIT9) : (BIT6);
+  if (pi_count < EARLY_DB)
+  {
+    tempD |= msk;
+  }
+  isbM32m(DDRPHY, reg, tempD, msk);
+
+  // error check
+  if (pi_count > 0x3F)
+  {
+    training_message(channel, rank, byte_lane);
+    post_code(0xEE, 0xE3);
+  }
+
+  LEAVEFN();
+  return;
+}
+
+// get_wdq:
+//
+// This function will return the amount of WDQ delay on the given channel, rank, byte_lane as an absolute PI count.
+// (currently doesn't comprehend rank)
+uint32_t get_wdq(
+    uint8_t channel,
+    uint8_t rank,
+    uint8_t byte_lane)
+{
+  uint32_t reg;
+  uint32_t tempD;
+  uint32_t pi_count;
+
+  ENTERFN();
+
+  // RDPTR (1/2 MCLK, 64 PIs)
+  // BL0 -> B01PTRCTL0[03:00] (0x0-0xF)
+  // BL1 -> B01PTRCTL0[15:12] (0x0-0xF)
+  reg = B01PTRCTL0 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET);
+  tempD = isbR32m(DDRPHY, reg);
+  tempD >>= (byte_lane & BIT0) ? (12) : (0);
+  tempD &= 0xF;
+
+  // Adjust PI_COUNT
+  pi_count = (tempD * HALF_CLK);
+
+  // PI (1/64 MCLK, 1 PIs)
+  // BL0 -> B0DLLPICODER0[13:08] (0x00-0x3F)
+  // BL1 -> B1DLLPICODER0[13:08] (0x00-0x3F)
+  reg = (byte_lane & BIT0) ? (B1DLLPICODER0) : (B0DLLPICODER0);
+  reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET));
+  tempD = isbR32m(DDRPHY, reg);
+  tempD >>= 8;
+  tempD &= 0x3F;
+
+  // Adjust PI_COUNT
+  pi_count += tempD;
+
+  LEAVEFN();
+  return pi_count;
+}
+
+// set_wcmd:
+//
+// This function will program the WCMD delays based on an absolute number of PIs.
+void set_wcmd(
+    uint8_t channel,
+    uint32_t pi_count)
+{
+  uint32_t reg;
+  uint32_t msk;
+  uint32_t tempD;
+
+  ENTERFN();
+  // RDPTR (1/2 MCLK, 64 PIs)
+  // CMDPTRREG[11:08] (0x0-0xF)
+  reg = CMDPTRREG + (channel * DDRIOCCC_CH_OFFSET);
+  msk = (BIT11 | BIT10 | BIT9 | BIT8);
+  tempD = pi_count / HALF_CLK;
+  tempD <<= 8;
+  isbM32m(DDRPHY, reg, tempD, msk);
+
+  // Adjust PI_COUNT
+  pi_count -= ((pi_count / HALF_CLK) & 0xF) * HALF_CLK;
+
+  // PI (1/64 MCLK, 1 PIs)
+  // CMDDLLPICODER0[29:24] -> CMDSLICE R3 (unused)
+  // CMDDLLPICODER0[21:16] -> CMDSLICE L3 (unused)
+  // CMDDLLPICODER0[13:08] -> CMDSLICE R2 (unused)
+  // CMDDLLPICODER0[05:00] -> CMDSLICE L2 (unused)
+  // CMDDLLPICODER1[29:24] -> CMDSLICE R1 (unused)
+  // CMDDLLPICODER1[21:16] -> CMDSLICE L1 (0x00-0x3F)
+  // CMDDLLPICODER1[13:08] -> CMDSLICE R0 (unused)
+  // CMDDLLPICODER1[05:00] -> CMDSLICE L0 (unused)
+  reg = CMDDLLPICODER1 + (channel * DDRIOCCC_CH_OFFSET);
+
+  msk = (BIT29 | BIT28 | BIT27 | BIT26 | BIT25 | BIT24) | (BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | BIT16)
+      | (BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8) | (BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0);
+
+  tempD = (pi_count << 24) | (pi_count << 16) | (pi_count << 8) | (pi_count << 0);
+
+  isbM32m(DDRPHY, reg, tempD, msk);
+  reg = CMDDLLPICODER0 + (channel * DDRIOCCC_CH_OFFSET); // PO
+  isbM32m(DDRPHY, reg, tempD, msk);
+
+  // DEADBAND
+  // CMDCFGREG0[17] (+1 select)
+  // CMDCFGREG0[16] (enable)
+  reg = CMDCFGREG0 + (channel * DDRIOCCC_CH_OFFSET);
+  msk = 0x00;
+  tempD = 0x00;
+  // enable
+  msk |= BIT16;
+  if ((pi_count < EARLY_DB) || (pi_count > LATE_DB))
+  {
+    tempD |= msk;
+  }
+  // select
+  msk |= BIT17;
+  if (pi_count < EARLY_DB)
+  {
+    tempD |= msk;
+  }
+  isbM32m(DDRPHY, reg, tempD, msk);
+
+  // error check
+  if (pi_count > 0x3F)
+  {
+    post_code(0xEE, 0xE4);
+  }
+
+  LEAVEFN();
+  return;
+}
+
+// get_wcmd:
+//
+// This function will return the amount of WCMD delay on the given channel as an absolute PI count.
+uint32_t get_wcmd(
+    uint8_t channel)
+{
+  uint32_t reg;
+  uint32_t tempD;
+  uint32_t pi_count;
+
+  ENTERFN();
+  // RDPTR (1/2 MCLK, 64 PIs)
+  // CMDPTRREG[11:08] (0x0-0xF)
+  reg = CMDPTRREG + (channel * DDRIOCCC_CH_OFFSET);
+  tempD = isbR32m(DDRPHY, reg);
+  tempD >>= 8;
+  tempD &= 0xF;
+
+  // Adjust PI_COUNT
+  pi_count = tempD * HALF_CLK;
+
+  // PI (1/64 MCLK, 1 PIs)
+  // CMDDLLPICODER0[29:24] -> CMDSLICE R3 (unused)
+  // CMDDLLPICODER0[21:16] -> CMDSLICE L3 (unused)
+  // CMDDLLPICODER0[13:08] -> CMDSLICE R2 (unused)
+  // CMDDLLPICODER0[05:00] -> CMDSLICE L2 (unused)
+  // CMDDLLPICODER1[29:24] -> CMDSLICE R1 (unused)
+  // CMDDLLPICODER1[21:16] -> CMDSLICE L1 (0x00-0x3F)
+  // CMDDLLPICODER1[13:08] -> CMDSLICE R0 (unused)
+  // CMDDLLPICODER1[05:00] -> CMDSLICE L0 (unused)
+  reg = CMDDLLPICODER1 + (channel * DDRIOCCC_CH_OFFSET);
+  tempD = isbR32m(DDRPHY, reg);
+  tempD >>= 16;
+  tempD &= 0x3F;
+
+  // Adjust PI_COUNT
+  pi_count += tempD;
+
+  LEAVEFN();
+  return pi_count;
+}
+
+// set_wclk:
+//
+// This function will program the WCLK delays based on an absolute number of PIs.
+void set_wclk(
+    uint8_t channel,
+    uint8_t rank,
+    uint32_t pi_count)
+{
+  uint32_t reg;
+  uint32_t msk;
+  uint32_t tempD;
+
+  ENTERFN();
+  // RDPTR (1/2 MCLK, 64 PIs)
+  // CCPTRREG[15:12] -> CLK1 (0x0-0xF)
+  // CCPTRREG[11:08] -> CLK0 (0x0-0xF)
+  reg = CCPTRREG + (channel * DDRIOCCC_CH_OFFSET);
+  msk = (BIT15 | BIT14 | BIT13 | BIT12) | (BIT11 | BIT10 | BIT9 | BIT8);
+  tempD = ((pi_count / HALF_CLK) << 12) | ((pi_count / HALF_CLK) << 8);
+  isbM32m(DDRPHY, reg, tempD, msk);
+
+  // Adjust PI_COUNT
+  pi_count -= ((pi_count / HALF_CLK) & 0xF) * HALF_CLK;
+
+  // PI (1/64 MCLK, 1 PIs)
+  // ECCB1DLLPICODER0[13:08] -> CLK0 (0x00-0x3F)
+  // ECCB1DLLPICODER0[21:16] -> CLK1 (0x00-0x3F)
+  reg = (rank) ? (ECCB1DLLPICODER0) : (ECCB1DLLPICODER0);
+  reg += (channel * DDRIOCCC_CH_OFFSET);
+  msk = (BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | BIT16) | (BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8);
+  tempD = (pi_count << 16) | (pi_count << 8);
+  isbM32m(DDRPHY, reg, tempD, msk);
+  reg = (rank) ? (ECCB1DLLPICODER1) : (ECCB1DLLPICODER1);
+  reg += (channel * DDRIOCCC_CH_OFFSET);
+  isbM32m(DDRPHY, reg, tempD, msk);
+  reg = (rank) ? (ECCB1DLLPICODER2) : (ECCB1DLLPICODER2);
+  reg += (channel * DDRIOCCC_CH_OFFSET);
+  isbM32m(DDRPHY, reg, tempD, msk);
+  reg = (rank) ? (ECCB1DLLPICODER3) : (ECCB1DLLPICODER3);
+  reg += (channel * DDRIOCCC_CH_OFFSET);
+  isbM32m(DDRPHY, reg, tempD, msk);
+
+  // DEADBAND
+  // CCCFGREG1[11:08] (+1 select)
+  // CCCFGREG1[03:00] (enable)
+  reg = CCCFGREG1 + (channel * DDRIOCCC_CH_OFFSET);
+  msk = 0x00;
+  tempD = 0x00;
+  // enable
+  msk |= (BIT3 | BIT2 | BIT1 | BIT0); // only ??? matters
+  if ((pi_count < EARLY_DB) || (pi_count > LATE_DB))
+  {
+    tempD |= msk;
+  }
+  // select
+  msk |= (BIT11 | BIT10 | BIT9 | BIT8); // only ??? matters
+  if (pi_count < EARLY_DB)
+  {
+    tempD |= msk;
+  }
+  isbM32m(DDRPHY, reg, tempD, msk);
+
+  // error check
+  if (pi_count > 0x3F)
+  {
+    post_code(0xEE, 0xE5);
+  }
+
+  LEAVEFN();
+  return;
+}
+
+// get_wclk:
+//
+// This function will return the amout of WCLK delay on the given channel, rank as an absolute PI count.
+uint32_t get_wclk(
+    uint8_t channel,
+    uint8_t rank)
+{
+  uint32_t reg;
+  uint32_t tempD;
+  uint32_t pi_count;
+
+  ENTERFN();
+  // RDPTR (1/2 MCLK, 64 PIs)
+  // CCPTRREG[15:12] -> CLK1 (0x0-0xF)
+  // CCPTRREG[11:08] -> CLK0 (0x0-0xF)
+  reg = CCPTRREG + (channel * DDRIOCCC_CH_OFFSET);
+  tempD = isbR32m(DDRPHY, reg);
+  tempD >>= (rank) ? (12) : (8);
+  tempD &= 0xF;
+
+  // Adjust PI_COUNT
+  pi_count = tempD * HALF_CLK;
+
+  // PI (1/64 MCLK, 1 PIs)
+  // ECCB1DLLPICODER0[13:08] -> CLK0 (0x00-0x3F)
+  // ECCB1DLLPICODER0[21:16] -> CLK1 (0x00-0x3F)
+  reg = (rank) ? (ECCB1DLLPICODER0) : (ECCB1DLLPICODER0);
+  reg += (channel * DDRIOCCC_CH_OFFSET);
+  tempD = isbR32m(DDRPHY, reg);
+  tempD >>= (rank) ? (16) : (8);
+  tempD &= 0x3F;
+
+  pi_count += tempD;
+
+  LEAVEFN();
+  return pi_count;
+}
+
+// set_wctl:
+//
+// This function will program the WCTL delays based on an absolute number of PIs.
+// (currently doesn't comprehend rank)
+void set_wctl(
+    uint8_t channel,
+    uint8_t rank,
+    uint32_t pi_count)
+{
+  uint32_t reg;
+  uint32_t msk;
+  uint32_t tempD;
+
+  ENTERFN();
+
+  // RDPTR (1/2 MCLK, 64 PIs)
+  // CCPTRREG[31:28] (0x0-0xF)
+  // CCPTRREG[27:24] (0x0-0xF)
+  reg = CCPTRREG + (channel * DDRIOCCC_CH_OFFSET);
+  msk = (BIT31 | BIT30 | BIT29 | BIT28) | (BIT27 | BIT26 | BIT25 | BIT24);
+  tempD = ((pi_count / HALF_CLK) << 28) | ((pi_count / HALF_CLK) << 24);
+  isbM32m(DDRPHY, reg, tempD, msk);
+
+  // Adjust PI_COUNT
+  pi_count -= ((pi_count / HALF_CLK) & 0xF) * HALF_CLK;
+
+  // PI (1/64 MCLK, 1 PIs)
+  // ECCB1DLLPICODER?[29:24] (0x00-0x3F)
+  // ECCB1DLLPICODER?[29:24] (0x00-0x3F)
+  reg = ECCB1DLLPICODER0 + (channel * DDRIOCCC_CH_OFFSET);
+  msk = (BIT29 | BIT28 | BIT27 | BIT26 | BIT25 | BIT24);
+  tempD = (pi_count << 24);
+  isbM32m(DDRPHY, reg, tempD, msk);
+  reg = ECCB1DLLPICODER1 + (channel * DDRIOCCC_CH_OFFSET);
+  isbM32m(DDRPHY, reg, tempD, msk);
+  reg = ECCB1DLLPICODER2 + (channel * DDRIOCCC_CH_OFFSET);
+  isbM32m(DDRPHY, reg, tempD, msk);
+  reg = ECCB1DLLPICODER3 + (channel * DDRIOCCC_CH_OFFSET);
+  isbM32m(DDRPHY, reg, tempD, msk);
+
+  // DEADBAND
+  // CCCFGREG1[13:12] (+1 select)
+  // CCCFGREG1[05:04] (enable)
+  reg = CCCFGREG1 + (channel * DDRIOCCC_CH_OFFSET);
+  msk = 0x00;
+  tempD = 0x00;
+  // enable
+  msk |= (BIT5 | BIT4); // only ??? matters
+  if ((pi_count < EARLY_DB) || (pi_count > LATE_DB))
+  {
+    tempD |= msk;
+  }
+  // select
+  msk |= (BIT13 | BIT12); // only ??? matters
+  if (pi_count < EARLY_DB)
+  {
+    tempD |= msk;
+  }
+  isbM32m(DDRPHY, reg, tempD, msk);
+
+  // error check
+  if (pi_count > 0x3F)
+  {
+    post_code(0xEE, 0xE6);
+  }
+
+  LEAVEFN();
+  return;
+}
+
+// get_wctl:
+//
+// This function will return the amount of WCTL delay on the given channel, rank as an absolute PI count.
+// (currently doesn't comprehend rank)
+uint32_t get_wctl(
+    uint8_t channel,
+    uint8_t rank)
+{
+  uint32_t reg;
+  uint32_t tempD;
+  uint32_t pi_count;
+
+  ENTERFN();
+
+  // RDPTR (1/2 MCLK, 64 PIs)
+  // CCPTRREG[31:28] (0x0-0xF)
+  // CCPTRREG[27:24] (0x0-0xF)
+  reg = CCPTRREG + (channel * DDRIOCCC_CH_OFFSET);
+  tempD = isbR32m(DDRPHY, reg);
+  tempD >>= 24;
+  tempD &= 0xF;
+
+  // Adjust PI_COUNT
+  pi_count = tempD * HALF_CLK;
+
+  // PI (1/64 MCLK, 1 PIs)
+  // ECCB1DLLPICODER?[29:24] (0x00-0x3F)
+  // ECCB1DLLPICODER?[29:24] (0x00-0x3F)
+  reg = ECCB1DLLPICODER0 + (channel * DDRIOCCC_CH_OFFSET);
+  tempD = isbR32m(DDRPHY, reg);
+  tempD >>= 24;
+  tempD &= 0x3F;
+
+  // Adjust PI_COUNT
+  pi_count += tempD;
+
+  LEAVEFN();
+  return pi_count;
+}
+
+// set_vref:
+//
+// This function will program the internal Vref setting in a given byte lane in a given channel.
+void set_vref(
+    uint8_t channel,
+    uint8_t byte_lane,
+    uint32_t setting)
+{
+  uint32_t reg = (byte_lane & 0x1) ? (B1VREFCTL) : (B0VREFCTL);
+
+  ENTERFN();
+  DPF(D_TRN, "Vref ch%d ln%d : val=%03X\n", channel, byte_lane, setting);
+
+  isbM32m(DDRPHY, (reg + (channel * DDRIODQ_CH_OFFSET) + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET)),
+      (vref_codes[setting] << 2), (BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2));
+  //isbM32m(DDRPHY, (reg + (channel * DDRIODQ_CH_OFFSET) + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET)), (setting<<2), (BIT7|BIT6|BIT5|BIT4|BIT3|BIT2));
+  // need to wait ~300ns for Vref to settle (check that this is necessary)
+  delay_n(300);
+  // ??? may need to clear pointers ???
+  LEAVEFN();
+  return;
+}
+
+// get_vref:
+//
+// This function will return the internal Vref setting for the given channel, byte_lane;
+uint32_t get_vref(
+    uint8_t channel,
+    uint8_t byte_lane)
+{
+  uint8_t j;
+  uint32_t ret_val = sizeof(vref_codes) / 2;
+  uint32_t reg = (byte_lane & 0x1) ? (B1VREFCTL) : (B0VREFCTL);
+
+  uint32_t tempD;
+
+  ENTERFN();
+  tempD = isbR32m(DDRPHY, (reg + (channel * DDRIODQ_CH_OFFSET) + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET)));
+  tempD >>= 2;
+  tempD &= 0x3F;
+  for (j = 0; j < sizeof(vref_codes); j++)
+  {
+    if (vref_codes[j] == tempD)
+    {
+      ret_val = j;
+      break;
+    }
+  }
+  LEAVEFN();
+  return ret_val;
+}
+
+// clear_pointers:
+//
+// This function will be used to clear the pointers in a given byte lane in a given channel.
+void clear_pointers(
+    void)
+{
+  uint8_t channel_i;
+  uint8_t bl_i;
+
+  ENTERFN();
+  for (channel_i = 0; channel_i < NUM_CHANNELS; channel_i++)
+  {
+    for (bl_i = 0; bl_i < NUM_BYTE_LANES; bl_i++)
+    {
+      isbM32m(DDRPHY, (B01PTRCTL1 + (channel_i * DDRIODQ_CH_OFFSET) + ((bl_i >> 1) * DDRIODQ_BL_OFFSET)), ~(BIT8),
+          (BIT8));
+      //delay_m(1); // DEBUG
+      isbM32m(DDRPHY, (B01PTRCTL1 + (channel_i * DDRIODQ_CH_OFFSET) + ((bl_i >> 1) * DDRIODQ_BL_OFFSET)), (BIT8),
+          (BIT8));
+    }
+  }
+  LEAVEFN();
+  return;
+}
+
+// void enable_cache:
+void enable_cache(
+    void)
+{
+  // Cache control not used in Quark MRC
+  return;
+}
+
+// void disable_cache:
+void disable_cache(
+    void)
+{
+  // Cache control not used in Quark MRC
+  return;
+}
+
+// Send DRAM command, data should be formated
+// using DCMD_Xxxx macro or emrsXCommand structure.
+static void dram_init_command(
+    uint32_t data)
+{
+  Wr32(DCMD, 0, data);
+}
+
+// find_rising_edge:
+//
+// This function will find the rising edge transition on RCVN or WDQS.
+void find_rising_edge(
+    MRCParams_t *mrc_params,
+    uint32_t delay[],
+    uint8_t channel,
+    uint8_t rank,
+    bool rcvn)
+{
+
+#define SAMPLE_CNT 3   // number of sample points
+#define SAMPLE_DLY 26  // number of PIs to increment per sample
+#define FORWARD true   // indicates to increase delays when looking for edge
+#define BACKWARD false // indicates to decrease delays when looking for edge
+
+  bool all_edges_found; // determines stop condition
+  bool direction[NUM_BYTE_LANES]; // direction indicator
+  uint8_t sample_i; // sample counter
+  uint8_t bl_i; // byte lane counter
+  uint8_t bl_divisor = (mrc_params->channel_width == x16) ? 2 : 1; // byte lane divisor
+  uint32_t sample_result[SAMPLE_CNT]; // results of "sample_dqs()"
+  uint32_t tempD; // temporary DWORD
+  uint32_t transition_pattern;
+
+  ENTERFN();
+
+  // select hte and request initial configuration
+  select_hte(mrc_params);
+  first_run = 1;
+
+  // Take 3 sample points (T1,T2,T3) to obtain a transition pattern.
+  for (sample_i = 0; sample_i < SAMPLE_CNT; sample_i++)
+  {
+    // program the desired delays for sample
+    for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++)
+    {
+      // increase sample delay by 26 PI (0.2 CLK)
+      if (rcvn)
+      {
+        set_rcvn(channel, rank, bl_i, delay[bl_i] + (sample_i * SAMPLE_DLY));
+      }
+      else
+      {
+        set_wdqs(channel, rank, bl_i, delay[bl_i] + (sample_i * SAMPLE_DLY));
+      }
+    } // bl_i loop
+    // take samples (Tsample_i)
+    sample_result[sample_i] = sample_dqs(mrc_params, channel, rank, rcvn);
+
+    DPF(D_TRN, "Find rising edge %s ch%d rnk%d: #%d dly=%d dqs=%02X\n",
+        (rcvn ? "RCVN" : "WDQS"), channel, rank,
+        sample_i, sample_i * SAMPLE_DLY, sample_result[sample_i]);
+
+  } // sample_i loop
+
+  // This pattern will help determine where we landed and ultimately how to place RCVEN/WDQS.
+  for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++)
+  {
+    // build "transition_pattern" (MSB is 1st sample)
+    transition_pattern = 0x00;
+    for (sample_i = 0; sample_i < SAMPLE_CNT; sample_i++)
+    {
+      transition_pattern |= ((sample_result[sample_i] & (1 << bl_i)) >> bl_i) << (SAMPLE_CNT - 1 - sample_i);
+    } // sample_i loop
+
+    DPF(D_TRN, "=== transition pattern %d\n", transition_pattern);
+
+    // set up to look for rising edge based on "transition_pattern"
+    switch (transition_pattern)
+    {
+    case 0x00: // sampled 0->0->0
+      // move forward from T3 looking for 0->1
+      delay[bl_i] += 2 * SAMPLE_DLY;
+      direction[bl_i] = FORWARD;
+      break;
+    case 0x01: // sampled 0->0->1
+    case 0x05: // sampled 1->0->1 (bad duty cycle) *HSD#237503*
+      // move forward from T2 looking for 0->1
+      delay[bl_i] += 1 * SAMPLE_DLY;
+      direction[bl_i] = FORWARD;
+      break;
+// HSD#237503
+//      case 0x02: // sampled 0->1->0 (bad duty cycle)
+//        training_message(channel, rank, bl_i);
+//        post_code(0xEE, 0xE8);
+//        break;
+    case 0x02: // sampled 0->1->0 (bad duty cycle) *HSD#237503*
+    case 0x03: // sampled 0->1->1
+      // move forward from T1 looking for 0->1
+      delay[bl_i] += 0 * SAMPLE_DLY;
+      direction[bl_i] = FORWARD;
+      break;
+    case 0x04: // sampled 1->0->0 (assumes BL8, HSD#234975)
+      // move forward from T3 looking for 0->1
+      delay[bl_i] += 2 * SAMPLE_DLY;
+      direction[bl_i] = FORWARD;
+      break;
+// HSD#237503
+//      case 0x05: // sampled 1->0->1 (bad duty cycle)
+//        training_message(channel, rank, bl_i);
+//        post_code(0xEE, 0xE9);
+//        break;
+    case 0x06: // sampled 1->1->0
+    case 0x07: // sampled 1->1->1
+      // move backward from T1 looking for 1->0
+      delay[bl_i] += 0 * SAMPLE_DLY;
+      direction[bl_i] = BACKWARD;
+      break;
+    default:
+      post_code(0xEE, 0xEE);
+      break;
+    } // transition_pattern switch
+    // program delays
+    if (rcvn)
+    {
+      set_rcvn(channel, rank, bl_i, delay[bl_i]);
+    }
+    else
+    {
+      set_wdqs(channel, rank, bl_i, delay[bl_i]);
+    }
+  } // bl_i loop
+
+  // Based on the observed transition pattern on the byte lane,
+  // begin looking for a rising edge with single PI granularity.
+  do
+  {
+    all_edges_found = true; // assume all byte lanes passed
+    tempD = sample_dqs(mrc_params, channel, rank, rcvn); // take a sample
+    // check all each byte lane for proper edge
+    for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++)
+    {
+      if (tempD & (1 << bl_i))
+      {
+        // sampled "1"
+        if (direction[bl_i] == BACKWARD)
+        {
+          // keep looking for edge on this byte lane
+          all_edges_found = false;
+          delay[bl_i] -= 1;
+          if (rcvn)
+          {
+            set_rcvn(channel, rank, bl_i, delay[bl_i]);
+          }
+          else
+          {
+            set_wdqs(channel, rank, bl_i, delay[bl_i]);
+          }
+        }
+      }
+      else
+      {
+        // sampled "0"
+        if (direction[bl_i] == FORWARD)
+        {
+          // keep looking for edge on this byte lane
+          all_edges_found = false;
+          delay[bl_i] += 1;
+          if (rcvn)
+          {
+            set_rcvn(channel, rank, bl_i, delay[bl_i]);
+          }
+          else
+          {
+            set_wdqs(channel, rank, bl_i, delay[bl_i]);
+          }
+        }
+      }
+    } // bl_i loop
+  } while (!all_edges_found);
+
+  // restore DDR idle state
+  dram_init_command(DCMD_PREA(rank));
+
+  DPF(D_TRN, "Delay %03X %03X %03X %03X\n",
+      delay[0], delay[1], delay[2], delay[3]);
+
+  LEAVEFN();
+  return;
+}
+
+// sample_dqs:
+//
+// This function will sample the DQTRAINSTS registers in the given channel/rank SAMPLE_SIZE times looking for a valid '0' or '1'.
+// It will return an encoded DWORD in which each bit corresponds to the sampled value on the byte lane.
+uint32_t sample_dqs(
+    MRCParams_t *mrc_params,
+    uint8_t channel,
+    uint8_t rank,
+    bool rcvn)
+{
+  uint8_t j; // just a counter
+  uint8_t bl_i; // which BL in the module (always 2 per module)
+  uint8_t bl_grp; // which BL module
+  uint8_t bl_divisor = (mrc_params->channel_width == x16) ? 2 : 1; // byte lane divisor
+  uint32_t msk[2]; // BLx in module
+  uint32_t sampled_val[SAMPLE_SIZE]; // DQTRAINSTS register contents for each sample
+  uint32_t num_0s; // tracks the number of '0' samples
+  uint32_t num_1s; // tracks the number of '1' samples
+  uint32_t ret_val = 0x00; // assume all '0' samples
+  uint32_t address = get_addr(mrc_params, channel, rank);
+
+  // initialise "msk[]"
+  msk[0] = (rcvn) ? (BIT1) : (BIT9); // BL0
+  msk[1] = (rcvn) ? (BIT0) : (BIT8); // BL1
+
+
+  // cycle through each byte lane group
+  for (bl_grp = 0; bl_grp < (NUM_BYTE_LANES / bl_divisor) / 2; bl_grp++)
+  {
+    // take SAMPLE_SIZE samples
+    for (j = 0; j < SAMPLE_SIZE; j++)
+    {
+      HteMemOp(address, first_run, rcvn?0:1);
+      first_run = 0;
+
+      // record the contents of the proper DQTRAINSTS register
+      sampled_val[j] = isbR32m(DDRPHY, (DQTRAINSTS + (bl_grp * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET)));
+    }
+    // look for a majority value ( (SAMPLE_SIZE/2)+1 ) on the byte lane
+    // and set that value in the corresponding "ret_val" bit
+    for (bl_i = 0; bl_i < 2; bl_i++)
+    {
+      num_0s = 0x00; // reset '0' tracker for byte lane
+      num_1s = 0x00; // reset '1' tracker for byte lane
+      for (j = 0; j < SAMPLE_SIZE; j++)
+      {
+        if (sampled_val[j] & msk[bl_i])
+        {
+          num_1s++;
+        }
+        else
+        {
+          num_0s++;
+        }
+      }
+      if (num_1s > num_0s)
+      {
+        ret_val |= (1 << (bl_i + (bl_grp * 2)));
+      }
+    }
+  }
+
+  // "ret_val.0" contains the status of BL0
+  // "ret_val.1" contains the status of BL1
+  // "ret_val.2" contains the status of BL2
+  // etc.
+  return ret_val;
+}
+
+// get_addr:
+//
+// This function will return a 32 bit address in the desired channel and rank.
+uint32_t get_addr(
+    MRCParams_t *mrc_params,
+    uint8_t channel,
+    uint8_t rank)
+{
+  uint32_t offset = 0x02000000; // 32MB
+
+  // Begin product specific code
+  if (channel > 0)
+  {
+    DPF(D_ERROR, "ILLEGAL CHANNEL\n");
+    DEAD_LOOP();
+  }
+
+  if (rank > 1)
+  {
+    DPF(D_ERROR, "ILLEGAL RANK\n");
+    DEAD_LOOP();
+  }
+
+  // use 256MB lowest density as per DRP == 0x0003
+  offset += rank * (256 * 1024 * 1024);
+
+  return offset;
+}
+
+// byte_lane_mask:
+//
+// This function will return a 32 bit mask that will be used to check for byte lane failures.
+uint32_t byte_lane_mask(
+    MRCParams_t *mrc_params)
+{
+  uint32_t j;
+  uint32_t ret_val = 0x00;
+
+  // set "ret_val" based on NUM_BYTE_LANES such that you will check only BL0 in "result"
+  // (each bit in "result" represents a byte lane)
+  for (j = 0; j < MAX_BYTE_LANES; j += NUM_BYTE_LANES)
+  {
+    ret_val |= (1 << ((j / NUM_BYTE_LANES) * NUM_BYTE_LANES));
+  }
+
+  // HSD#235037
+  // need to adjust the mask for 16-bit mode
+  if (mrc_params->channel_width == x16)
+  {
+    ret_val |= (ret_val << 2);
+  }
+
+  return ret_val;
+}
+
+
+// read_tsc:
+//
+// This function will do some assembly to return TSC register contents as a uint64_t.
+uint64_t read_tsc(
+    void)
+{
+  volatile uint64_t tsc;  // EDX:EAX
+
+#if defined (SIM) || defined (GCC)
+  volatile uint32_t tscH; // EDX
+  volatile uint32_t tscL;// EAX
+
+  asm("rdtsc":"=a"(tscL),"=d"(tscH));
+  tsc = tscH;
+  tsc = (tsc<<32)|tscL;
+#else
+  tsc = __rdtsc();
+#endif
+
+  return tsc;
+}
+
+// get_tsc_freq:
+//
+// This function returns the TSC frequency in MHz
+uint32_t get_tsc_freq(
+    void)
+{
+  static uint32_t freq[] =
+  { 533, 400, 200, 100 };
+  uint32_t fuse;
+#if 0
+  fuse = (isbR32m(FUSE, 0) >> 12) & (BIT1|BIT0);
+#else
+  // todo!!! Fixed 533MHz for emulation or debugging
+  fuse = 0;
+#endif
+  return freq[fuse];
+}
+
+#ifndef SIM
+// delay_n:
+//
+// This is a simple delay function.
+// It takes "nanoseconds" as a parameter.
+void delay_n(
+    uint32_t nanoseconds)
+{
+  // 1000 MHz clock has 1ns period --> no conversion required
+  uint64_t final_tsc = read_tsc();
+  final_tsc += ((get_tsc_freq() * (nanoseconds)) / 1000);
+
+  while (read_tsc() < final_tsc)
+    ;
+  return;
+}
+#endif
+
+// delay_u:
+//
+// This is a simple delay function.
+// It takes "microseconds as a parameter.
+void delay_u(
+    uint32_t microseconds)
+{
+  // 64 bit math is not an option, just use loops
+  while (microseconds--)
+  {
+    delay_n(1000);
+  }
+  return;
+}
+
+// delay_m:
+//
+// This is a simple delay function.
+// It takes "milliseconds" as a parameter.
+void delay_m(
+    uint32_t milliseconds)
+{
+  // 64 bit math is not an option, just use loops
+  while (milliseconds--)
+  {
+    delay_u(1000);
+  }
+  return;
+}
+
+// delay_s:
+//
+// This is a simple delay function.
+// It takes "seconds" as a parameter.
+void delay_s(
+    uint32_t seconds)
+{
+  // 64 bit math is not an option, just use loops
+  while (seconds--)
+  {
+    delay_m(1000);
+  }
+  return;
+}
+
+// post_code:
+//
+// This function will output the POST CODE to the four 7-Segment LED displays.
+void post_code(
+    uint8_t major,
+    uint8_t minor)
+{
+#ifdef EMU
+  // Update global variable for execution tracking in debug env
+  PostCode = ((major << 8) | minor);
+#endif
+
+  // send message to UART
+  DPF(D_INFO, "POST: 0x%01X%02X\n", major, minor);
+
+  // error check:
+  if (major == 0xEE)
+  {
+    // todo!!! Consider updating error status and exit MRC
+#ifdef SIM
+    // enable Ctrl-C handling
+    for(;;) delay_n(100);
+#else
+    DEAD_LOOP();
+#endif
+  }
+}
+
+void training_message(
+    uint8_t channel,
+    uint8_t rank,
+    uint8_t byte_lane)
+{
+  // send message to UART
+  DPF(D_INFO, "CH%01X RK%01X BL%01X\n", channel, rank, byte_lane);
+  return;
+}
+
+void print_timings(
+    MRCParams_t *mrc_params)
+{
+  uint8_t algo_i;
+  uint8_t channel_i;
+  uint8_t rank_i;
+  uint8_t bl_i;
+  uint8_t bl_divisor = (mrc_params->channel_width == x16) ? 2 : 1;
+
+  DPF(D_INFO, "\n---------------------------");
+  DPF(D_INFO, "\nALGO[CH:RK] BL0 BL1 BL2 BL3");
+  DPF(D_INFO, "\n===========================");
+  for (algo_i = 0; algo_i < eMAX_ALGOS; algo_i++)
+  {
+    for (channel_i = 0; channel_i < NUM_CHANNELS; channel_i++)
+    {
+      if (mrc_params->channel_enables & (1 << channel_i))
+      {
+        for (rank_i = 0; rank_i < NUM_RANKS; rank_i++)
+        {
+          if (mrc_params->rank_enables & (1 << rank_i))
+          {
+            switch (algo_i)
+            {
+            case eRCVN:
+              DPF(D_INFO, "\nRCVN[%02d:%02d]", channel_i, rank_i);
+              break;
+            case eWDQS:
+              DPF(D_INFO, "\nWDQS[%02d:%02d]", channel_i, rank_i);
+              break;
+            case eWDQx:
+              DPF(D_INFO, "\nWDQx[%02d:%02d]", channel_i, rank_i);
+              break;
+            case eRDQS:
+              DPF(D_INFO, "\nRDQS[%02d:%02d]", channel_i, rank_i);
+              break;
+            case eVREF:
+              DPF(D_INFO, "\nVREF[%02d:%02d]", channel_i, rank_i);
+              break;
+            case eWCMD:
+              DPF(D_INFO, "\nWCMD[%02d:%02d]", channel_i, rank_i);
+              break;
+            case eWCTL:
+              DPF(D_INFO, "\nWCTL[%02d:%02d]", channel_i, rank_i);
+              break;
+            case eWCLK:
+              DPF(D_INFO, "\nWCLK[%02d:%02d]", channel_i, rank_i);
+              break;
+            default:
+              break;
+            } // algo_i switch
+            for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++)
+            {
+              switch (algo_i)
+              {
+              case eRCVN:
+                DPF(D_INFO, " %03d", get_rcvn(channel_i, rank_i, bl_i));
+                break;
+              case eWDQS:
+                DPF(D_INFO, " %03d", get_wdqs(channel_i, rank_i, bl_i));
+                break;
+              case eWDQx:
+                DPF(D_INFO, " %03d", get_wdq(channel_i, rank_i, bl_i));
+                break;
+              case eRDQS:
+                DPF(D_INFO, " %03d", get_rdqs(channel_i, rank_i, bl_i));
+                break;
+              case eVREF:
+                DPF(D_INFO, " %03d", get_vref(channel_i, bl_i));
+                break;
+              case eWCMD:
+                DPF(D_INFO, " %03d", get_wcmd(channel_i));
+                break;
+              case eWCTL:
+                DPF(D_INFO, " %03d", get_wctl(channel_i, rank_i));
+                break;
+              case eWCLK:
+                DPF(D_INFO, " %03d", get_wclk(channel_i, rank_i));
+                break;
+              default:
+                break;
+              } // algo_i switch
+            } // bl_i loop
+          } // if rank_i enabled
+        } // rank_i loop
+      } // if channel_i enabled
+    } // channel_i loop
+  } // algo_i loop
+  DPF(D_INFO, "\n---------------------------");
+  DPF(D_INFO, "\n");
+  return;
+}
+
+// 32 bit LFSR with characteristic polynomial:  X^32 + X^22 +X^2 + X^1
+// The function takes pointer to previous 32 bit value and modifies it to next value.
+void lfsr32(
+    uint32_t *lfsr_ptr)
+{
+  uint32_t bit;
+  uint32_t lfsr;
+  uint32_t i;
+
+  lfsr = *lfsr_ptr;
+
+  for (i = 0; i < 32; i++)
+  {
+    bit = 1 ^ (lfsr & BIT0);
+    bit = bit ^ ((lfsr & BIT1) >> 1);
+    bit = bit ^ ((lfsr & BIT2) >> 2);
+    bit = bit ^ ((lfsr & BIT22) >> 22);
+
+    lfsr = ((lfsr >> 1) | (bit << 31));
+  }
+
+  *lfsr_ptr = lfsr;
+  return;
+}
+
+// The purpose of this function is to ensure the SEC comes out of reset
+// and IA initiates the SEC enabling Memory Scrambling.
+void enable_scrambling(
+    MRCParams_t *mrc_params)
+{
+  uint32_t lfsr = 0;
+  uint8_t i;
+
+  if (mrc_params->scrambling_enables == 0)
+    return;
+
+  ENTERFN();
+
+  // 32 bit seed is always stored in BIOS NVM.
+  lfsr = mrc_params->timings.scrambler_seed;
+
+  if (mrc_params->boot_mode == bmCold)
+  {
+    // factory value is 0 and in first boot, a clock based seed is loaded.
+    if (lfsr == 0)
+    {
+      lfsr = read_tsc() & 0x0FFFFFFF; // get seed from system clock and make sure it is not all 1's
+    }
+    // need to replace scrambler
+    // get next 32bit LFSR 16 times which is the last part of the previous scrambler vector.
+    else
+    {
+      for (i = 0; i < 16; i++)
+      {
+        lfsr32(&lfsr);
+      }
+    }
+    mrc_params->timings.scrambler_seed = lfsr;  // save new seed.
+  } // if (cold_boot)
+
+  // In warm boot or S3 exit, we have the previous seed.
+  // In cold boot, we have the last 32bit LFSR which is the new seed.
+  lfsr32(&lfsr); // shift to next value
+  isbW32m(MCU, SCRMSEED, (lfsr & 0x0003FFFF));
+  for (i = 0; i < 2; i++)
+  {
+    isbW32m(MCU, SCRMLO + i, (lfsr & 0xAAAAAAAA));
+  }
+
+  LEAVEFN();
+  return;
+}
+
+// This function will store relevant timing data
+// This data will be used on subsequent boots to speed up boot times
+// and is required for Suspend To RAM capabilities.
+void store_timings(
+    MRCParams_t *mrc_params)
+{
+  uint8_t ch, rk, bl;
+  MrcTimings_t *mt = &mrc_params->timings;
+
+  for (ch = 0; ch < NUM_CHANNELS; ch++)
+  {
+    for (rk = 0; rk < NUM_RANKS; rk++)
+    {
+      for (bl = 0; bl < NUM_BYTE_LANES; bl++)
+      {
+        mt->rcvn[ch][rk][bl] = get_rcvn(ch, rk, bl); // RCVN
+        mt->rdqs[ch][rk][bl] = get_rdqs(ch, rk, bl); // RDQS
+        mt->wdqs[ch][rk][bl] = get_wdqs(ch, rk, bl); // WDQS
+        mt->wdq[ch][rk][bl] = get_wdq(ch, rk, bl);  // WDQ
+        if (rk == 0)
+        {
+          mt->vref[ch][bl] = get_vref(ch, bl);  // VREF (RANK0 only)
+        }
+      }
+      mt->wctl[ch][rk] = get_wctl(ch, rk); // WCTL
+    }
+    mt->wcmd[ch] = get_wcmd(ch); // WCMD
+  }
+
+  // need to save for a case of changing frequency after warm reset
+  mt->ddr_speed = mrc_params->ddr_speed;
+
+  return;
+}
+
+// This function will retrieve relevant timing data
+// This data will be used on subsequent boots to speed up boot times
+// and is required for Suspend To RAM capabilities.
+void restore_timings(
+    MRCParams_t *mrc_params)
+{
+  uint8_t ch, rk, bl;
+  const MrcTimings_t *mt = &mrc_params->timings;
+
+  for (ch = 0; ch < NUM_CHANNELS; ch++)
+  {
+    for (rk = 0; rk < NUM_RANKS; rk++)
+    {
+      for (bl = 0; bl < NUM_BYTE_LANES; bl++)
+      {
+        set_rcvn(ch, rk, bl, mt->rcvn[ch][rk][bl]); // RCVN
+        set_rdqs(ch, rk, bl, mt->rdqs[ch][rk][bl]); // RDQS
+        set_wdqs(ch, rk, bl, mt->wdqs[ch][rk][bl]); // WDQS
+        set_wdq(ch, rk, bl, mt->wdq[ch][rk][bl]);  // WDQ
+        if (rk == 0)
+        {
+          set_vref(ch, bl, mt->vref[ch][bl]); // VREF (RANK0 only)
+        }
+      }
+      set_wctl(ch, rk, mt->wctl[ch][rk]); // WCTL
+    }
+    set_wcmd(ch, mt->wcmd[ch]); // WCMD
+  }
+
+  return;
+}
+
+// Configure default settings normally set as part of read training
+// Some defaults have to be set earlier as they may affect earlier
+// training steps.
+void default_timings(
+    MRCParams_t *mrc_params)
+{
+  uint8_t ch, rk, bl;
+
+  for (ch = 0; ch < NUM_CHANNELS; ch++)
+  {
+    for (rk = 0; rk < NUM_RANKS; rk++)
+    {
+      for (bl = 0; bl < NUM_BYTE_LANES; bl++)
+      {
+        set_rdqs(ch, rk, bl, 24); // RDQS
+        if (rk == 0)
+        {
+          set_vref(ch, bl, 32); // VREF (RANK0 only)
+        }
+      }
+    }
+  }
+
+  return;
+}
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit_utils.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit_utils.h
new file mode 100644
index 0000000000..af7b8c8951
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit_utils.h
@@ -0,0 +1,95 @@
+/************************************************************************
+ *
+ * Copyright (c) 2013-2017 Intel Corporation.
+ *
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ ***************************************************************************/
+#ifndef _MEMINIT_UTILS_H_
+#define _MEMINIT_UTILS_H_
+
+// General Definitions:
+#ifdef QUICKSIM
+#define SAMPLE_SIZE     4   // reduce number of training samples in simulation env
+#else
+#define SAMPLE_SIZE     6   // must be odd number
+#endif
+
+#define EARLY_DB    (0x12)  // must be less than this number to enable early deadband
+#define LATE_DB     (0x34)  // must be greater than this number to enable late deadband
+#define CHX_REGS    (11*4)
+#define FULL_CLK      128
+#define HALF_CLK       64
+#define QRTR_CLK       32
+
+
+
+#define MCEIL(num,den) ((uint8_t)((num+den-1)/den))
+#define MMAX(a,b)      ((((int32_t)(a))>((int32_t)(b)))?(a):(b))
+#define MCOUNT(a)      (sizeof(a)/sizeof(*a))
+
+typedef enum ALGOS_enum {
+  eRCVN = 0,
+  eWDQS,
+  eWDQx,
+  eRDQS,
+  eVREF,
+  eWCMD,
+  eWCTL,
+  eWCLK,
+  eMAX_ALGOS,
+} ALGOs_t;
+
+
+// Prototypes:
+void set_rcvn(uint8_t channel, uint8_t rank, uint8_t byte_lane, uint32_t pi_count);
+void set_rdqs(uint8_t channel, uint8_t rank, uint8_t byte_lane, uint32_t pi_count);
+void set_wdqs(uint8_t channel, uint8_t rank, uint8_t byte_lane, uint32_t pi_count);
+void set_wdq(uint8_t channel, uint8_t rank, uint8_t byte_lane, uint32_t pi_count);
+void set_wcmd(uint8_t channel, uint32_t pi_count);
+void set_wclk(uint8_t channel, uint8_t grp, uint32_t pi_count);
+void set_wctl(uint8_t channel, uint8_t rank, uint32_t pi_count);
+void set_vref(uint8_t channel, uint8_t byte_lane, uint32_t setting);
+uint32_t get_rcvn(uint8_t channel, uint8_t rank, uint8_t byte_lane);
+uint32_t get_rdqs(uint8_t channel, uint8_t rank, uint8_t byte_lane);
+uint32_t get_wdqs(uint8_t channel, uint8_t rank, uint8_t byte_lane);
+uint32_t get_wdq(uint8_t channel, uint8_t rank, uint8_t byte_lane);
+uint32_t get_wcmd(uint8_t channel);
+uint32_t get_wclk(uint8_t channel, uint8_t group);
+uint32_t get_wctl(uint8_t channel, uint8_t rank);
+uint32_t get_vref(uint8_t channel, uint8_t byte_lane);
+
+void clear_pointers(void);
+void enable_cache(void);
+void disable_cache(void);
+void find_rising_edge(MRCParams_t *mrc_params, uint32_t delay[], uint8_t channel, uint8_t rank, bool rcvn);
+uint32_t sample_dqs(MRCParams_t *mrc_params, uint8_t channel, uint8_t rank, bool rcvn);
+uint32_t get_addr(MRCParams_t *mrc_params, uint8_t channel, uint8_t rank);
+uint32_t byte_lane_mask(MRCParams_t *mrc_params);
+
+uint64_t read_tsc(void);
+uint32_t get_tsc_freq(void);
+void delay_n(uint32_t nanoseconds);
+void delay_u(uint32_t microseconds);
+void delay_m(uint32_t milliseconds);
+void delay_s(uint32_t seconds);
+
+void post_code(uint8_t major, uint8_t minor);
+void training_message(uint8_t channel, uint8_t rank, uint8_t byte_lane);
+void print_timings(MRCParams_t *mrc_params);
+
+void enable_scrambling(MRCParams_t *mrc_params);
+void store_timings(MRCParams_t *mrc_params);
+void restore_timings(MRCParams_t *mrc_params);
+void default_timings(MRCParams_t *mrc_params);
+
+#ifndef SIM
+//
+// Map memset() and memcpy() to BaseMemoryLib functions
+//
+#include <Library/BaseMemoryLib.h>
+#define memset(d,c,n) ((c) == 0) ? ZeroMem ((d), (n)) : SetMem ((d), (n), (c))
+#define memcpy(d,s,n) CopyMem ((d), (s), (n))
+#endif
+
+#endif // _MEMINIT_UTILS_H_
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/memory_options.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/memory_options.h
new file mode 100644
index 0000000000..b96d06908e
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/memory_options.h
@@ -0,0 +1,77 @@
+/** @file
+Common definitions and compilation switches for MRC
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef __MEMORY_OPTIONS_H
+#define __MEMORY_OPTIONS_H
+
+#include "core_types.h"
+
+// MRC COMPILE TIME SWITCHES:
+// ==========================
+
+
+
+//#define MRC_SV              // enable some validation opitons
+
+#if defined (SIM) || defined(EMU)
+#define QUICKSIM              // reduce execution time using shorter rd/wr sequences
+#endif
+
+#define CLT                   // required for Quark project
+
+
+
+//#define BACKUP_RCVN           // enable STATIC timing settings for RCVN (BACKUP_MODE)
+//#define BACKUP_WDQS           // enable STATIC timing settings for WDQS (BACKUP_MODE)
+//#define BACKUP_RDQS           // enable STATIC timing settings for RDQS (BACKUP_MODE)
+//#define BACKUP_WDQ            // enable STATIC timing settings for WDQ (BACKUP_MODE)
+
+
+
+//#define BACKUP_COMPS          // enable *COMP overrides (BACKUP_MODE)
+//#define RX_EYE_CHECK          // enable the RD_TRAIN eye check
+#define HMC_TEST              // enable Host to Memory Clock Alignment
+#define R2R_SHARING           // enable multi-rank support via rank2rank sharing
+
+#define FORCE_16BIT_DDRIO     // disable signals not used in 16bit mode of DDRIO
+
+
+
+//
+// Debug support
+//
+
+#ifdef NDEBUG
+#define DPF        if(0) dpf
+#else
+#define DPF        dpf
+#endif
+
+void dpf( uint32_t mask, char_t *bla, ...);
+
+
+uint8_t mgetc(void);
+uint8_t mgetch(void);
+
+
+// Debug print type
+#define D_ERROR      0x0001
+#define D_INFO       0x0002
+#define D_REGRD      0x0004
+#define D_REGWR      0x0008
+#define D_FCALL      0x0010
+#define D_TRN        0x0020
+#define D_TIME       0x0040
+
+#define ENTERFN()     DPF(D_FCALL, "<%s>\n", __FUNCTION__)
+#define LEAVEFN()     DPF(D_FCALL, "</%s>\n", __FUNCTION__)
+#define REPORTFN()    DPF(D_FCALL, "<%s/>\n", __FUNCTION__)
+
+extern uint32_t DpfPrintMask;
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/mrc.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/mrc.c
new file mode 100644
index 0000000000..f9b0e7050d
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/mrc.c
@@ -0,0 +1,40 @@
+/************************************************************************
+ *
+ * Copyright (c) 2013-2015 Intel Corporation.
+ *
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ ************************************************************************/
+#include "mrc.h"
+#include "memory_options.h"
+
+#include "meminit.h"
+#include "meminit_utils.h"
+#include "prememinit.h"
+#include "io.h"
+
+// Base address for UART registers
+extern uint32_t UartMmioBase;
+
+//
+// Memory Reference Code entry point when executing from BIOS
+//
+void Mrc( MRCParams_t *mrc_params)
+{
+  // configure uart base address assuming code relocated to eSRAM
+  UartMmioBase = mrc_params->uart_mmio_base;
+
+  ENTERFN();
+
+  DPF(D_INFO, "MRC Version %04X %s %s\n", MRC_VERSION, __DATE__, __TIME__);
+
+  // this will set up the data structures used by MemInit()
+  PreMemInit(mrc_params);
+
+  // this will initialize system memory
+  MemInit(mrc_params);
+
+  LEAVEFN();
+  return;
+}
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/mrc.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/mrc.h
new file mode 100644
index 0000000000..dfcfe58a9d
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/mrc.h
@@ -0,0 +1,160 @@
+/************************************************************************
+ *
+ * Copyright (c) 2013-2015 Intel Corporation.
+ *
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ ************************************************************************/
+#ifndef _MRC_H_
+#define _MRC_H_
+
+#include "core_types.h"
+
+// define the MRC Version
+#define MRC_VERSION 0x0112
+
+
+// architectural definitions
+#define NUM_CHANNELS   1 // number of channels
+#define NUM_RANKS      2 // number of ranks per channel
+#define NUM_BYTE_LANES 4 // number of byte lanes per channel
+
+// software limitations
+#define MAX_CHANNELS   1
+#define MAX_RANKS      2
+#define MAX_BYTE_LANES 4
+
+// only to mock MrcWrapper
+#define MAX_SOCKETS    1
+#define MAX_SIDES      1
+#define MAX_ROWS       (MAX_SIDES * MAX_SOCKETS)
+// end
+
+
+// Specify DRAM of nenory channel width
+enum {
+  x8,   // DRAM width
+  x16,  // DRAM width & Channel Width
+  x32   // Channel Width
+};
+
+// Specify DRAM speed
+enum {
+  DDRFREQ_800,
+  DDRFREQ_1066
+};
+
+// Specify DRAM type
+enum {
+  DDR3,
+  DDR3L
+};
+
+// Delay configuration for individual signals
+// Vref setting
+// Scrambler seed
+typedef struct MrcTimings_s
+{
+  uint32_t rcvn[NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES];
+  uint32_t rdqs[NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES];
+  uint32_t wdqs[NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES];
+  uint32_t wdq [NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES];
+  uint32_t vref[NUM_CHANNELS][NUM_BYTE_LANES];
+  uint32_t wctl[NUM_CHANNELS][NUM_RANKS];
+  uint32_t wcmd[NUM_CHANNELS];
+
+  uint32_t scrambler_seed;
+  uint8_t  ddr_speed;            // need to save for the case of frequency change
+} MrcTimings_t;
+
+
+// DENSITY: 0=512Mb, 1=Gb, 2=2Gb, 3=4Gb
+// tCL is DRAM CAS Latency in clocks.
+// All other timings are in picoseconds.
+// Refer to JEDEC spec (or DRAM datasheet) when changing these values.
+typedef struct DRAMParams_s {
+  uint8_t  DENSITY;
+  uint8_t  tCL;   // CAS latency in clocks
+  uint32_t tRAS;  // ACT to PRE command period
+  uint32_t tWTR;  // Delay from start of internal write transaction to internal read command
+  uint32_t tRRD;  // ACT to ACT command period (JESD79 specific to page size 1K/2K)
+  uint32_t tFAW;  // Four activate window (JESD79 specific to page size 1K/2K)
+} DRAMParams_t;
+
+
+// Boot mode defined as bit mask (1<<n)
+#define bmCold     1    // full training
+#define bmFast     2    // restore timing parameters
+#define bmS3       4    // resume from S3
+#define bmWarm     8
+#define bmUnknown  0
+
+
+// MRC execution status
+#define MRC_SUCCESS     0      // initialization ok
+#define MRC_E_MEMTEST   1      // memtest failed
+
+
+//
+// Input/output/context parameters for Memory Reference Code
+//
+typedef struct MRCParams_s
+{
+  //
+  // Global settings
+  //
+
+  uint32_t boot_mode;           // bmCold, bmFast, bmWarm, bmS3
+  uint32_t uart_mmio_base;      // pcie serial port base address (force 0 to disable debug)
+
+  uint8_t  dram_width;          // x8, x16
+  uint8_t  ddr_speed;           // DDRFREQ_800, DDRFREQ_1066
+  uint8_t  ddr_type;            // DDR3, DDR3L
+  uint8_t  ecc_enables;         // 0, 1 (memory size reduced to 7/8)
+  uint8_t  scrambling_enables;  // 0, 1
+  uint32_t rank_enables;        // 1, 3 (1'st rank has to be populated if 2'nd rank present)
+  uint32_t channel_enables;     // 1 only
+  uint32_t channel_width;       // x16 only
+  uint32_t address_mode;        // 0, 1, 2 (mode 2 forced if ecc enabled)
+
+  // memConfig_t begin
+  uint8_t refresh_rate;         // REFRESH_RATE       : 1=1.95us, 2=3.9us, 3=7.8us, others=RESERVED
+  uint8_t sr_temp_range;        // SR_TEMP_RANGE      : 0=normal, 1=extended, others=RESERVED
+  uint8_t ron_value;            // RON_VALUE          : 0=34ohm, 1=40ohm, others=RESERVED (select MRS1.DIC driver impedance control)
+  uint8_t rtt_nom_value;        // RTT_NOM_VALUE      : 0=40ohm, 1=60ohm, 2=120ohm, others=RESERVED
+  uint8_t rd_odt_value;         // RD_ODT_VALUE       : 0=off, 1=60ohm, 2=120ohm, 3=180ohm, others=RESERVED
+  // memConfig_t end
+
+  DRAMParams_t params;
+
+  //
+  // Internally used
+  //
+
+  uint32_t board_id;            // internally used for board layout (use x8 or x16 memory)
+  uint32_t hte_setup : 1;       // when set hte reconfiguration requested
+  uint32_t menu_after_mrc : 1;
+  uint32_t power_down_disable :1;
+  uint32_t tune_rcvn :1;
+
+  uint32_t channel_size[NUM_CHANNELS];
+  uint32_t column_bits[NUM_CHANNELS];
+  uint32_t row_bits[NUM_CHANNELS];
+
+  uint32_t mrs1;                // register content saved during training
+
+  //
+  // Output
+  //
+
+  uint32_t status;              // initialization result (non zero specifies error code)
+  uint32_t mem_size;            // total memory size in bytes (excludes ECC banks)
+
+  MrcTimings_t timings;         // training results (also used on input)
+
+} MRCParams_t;
+
+// Alternative type name for consistent naming convention
+#define MRC_PARAMS    MRCParams_t
+
+#endif // _MRC_H_
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/platform.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/platform.c
new file mode 100644
index 0000000000..7d0c14119d
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/platform.c
@@ -0,0 +1,186 @@
+/** @file
+The interface layer for memory controller access.
+It is supporting both real hardware platform and simulation environment.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "mrc.h"
+#include "memory_options.h"
+#include "meminit_utils.h"
+#include "io.h"
+
+#ifdef SIM
+
+void SimMmio32Write (
+    uint32_t be,
+    uint32_t address,
+    uint32_t data );
+
+void SimMmio32Read (
+    uint32_t be,
+    uint32_t address,
+    uint32_t *data );
+
+void SimDelayClk (
+    uint32_t x2clk );
+
+// This is a simple delay function.
+// It takes "nanoseconds" as a parameter.
+void delay_n(uint32_t nanoseconds)
+{
+  SimDelayClk( 800*nanoseconds/1000);
+}
+#endif
+
+/****
+ *
+ ***/
+uint32_t Rd32(
+    uint32_t unit,
+    uint32_t addr)
+{
+  uint32_t data;
+
+  switch (unit)
+  {
+  case MEM:
+    case MMIO:
+#ifdef SIM
+    SimMmio32Read( 1, addr, &data);
+#else
+    data = *PTR32(addr);
+#endif
+    break;
+
+  case MCU:
+    case HOST_BRIDGE:
+    case MEMORY_MANAGER:
+    case HTE:
+    // Handle case addr bigger than 8bit
+    pciwrite32(0, 0, 0, SB_HADR_REG, addr & 0xFFF00);
+    addr &= 0x00FF;
+
+    pciwrite32(0, 0, 0, SB_PACKET_REG,
+        SB_COMMAND(SB_REG_READ_OPCODE, unit, addr));
+    data = pciread32(0, 0, 0, SB_DATA_REG);
+    break;
+
+  case DDRPHY:
+    // Handle case addr bigger than 8bit
+    pciwrite32(0, 0, 0, SB_HADR_REG, addr & 0xFFF00);
+    addr &= 0x00FF;
+
+    pciwrite32(0, 0, 0, SB_PACKET_REG,
+        SB_COMMAND(SB_DDRIO_REG_READ_OPCODE, unit, addr));
+    data = pciread32(0, 0, 0, SB_DATA_REG);
+    break;
+
+  default:
+    DEAD_LOOP()
+    ;
+  }
+
+  if (unit < MEM)
+    DPF(D_REGRD, "RD32 %03X %08X %08X\n", unit, addr, data);
+
+  return data;
+}
+
+/****
+ *
+ ***/
+void Wr32(
+    uint32_t unit,
+    uint32_t addr,
+    uint32_t data)
+{
+  if (unit < MEM)
+    DPF(D_REGWR, "WR32 %03X %08X %08X\n", unit, addr, data);
+
+  switch (unit)
+  {
+  case MEM:
+    case MMIO:
+#ifdef SIM
+    SimMmio32Write( 1, addr, data);
+#else
+    *PTR32(addr) = data;
+#endif
+    break;
+
+  case MCU:
+    case HOST_BRIDGE:
+    case MEMORY_MANAGER:
+    case HTE:
+    // Handle case addr bigger than 8bit
+    pciwrite32(0, 0, 0, SB_HADR_REG, addr & 0xFFF00);
+    addr &= 0x00FF;
+
+    pciwrite32(0, 0, 0, SB_DATA_REG, data);
+    pciwrite32(0, 0, 0, SB_PACKET_REG,
+        SB_COMMAND(SB_REG_WRITE_OPCODE, unit, addr));
+    break;
+
+  case DDRPHY:
+    // Handle case addr bigger than 8bit
+    pciwrite32(0, 0, 0, SB_HADR_REG, addr & 0xFFF00);
+    addr &= 0x00FF;
+
+    pciwrite32(0, 0, 0, SB_DATA_REG, data);
+    pciwrite32(0, 0, 0, SB_PACKET_REG,
+        SB_COMMAND(SB_DDRIO_REG_WRITE_OPCODE, unit, addr));
+    break;
+
+  case DCMD:
+    pciwrite32(0, 0, 0, SB_HADR_REG, 0);
+    pciwrite32(0, 0, 0, SB_DATA_REG, data);
+    pciwrite32(0, 0, 0, SB_PACKET_REG,
+        SB_COMMAND(SB_DRAM_CMND_OPCODE, MCU, 0));
+    break;
+
+  default:
+    DEAD_LOOP()
+    ;
+  }
+}
+
+/****
+ *
+ ***/
+void WrMask32(
+    uint32_t unit,
+    uint32_t addr,
+    uint32_t data,
+    uint32_t mask)
+{
+  Wr32(unit, addr, ((Rd32(unit, addr) & ~mask) | (data & mask)));
+}
+
+/****
+ *
+ ***/
+void pciwrite32(
+    uint32_t bus,
+    uint32_t dev,
+    uint32_t fn,
+    uint32_t reg,
+    uint32_t data)
+{
+  Wr32(MMIO, PCIADDR(bus,dev,fn,reg), data);
+}
+
+/****
+ *
+ ***/
+uint32_t pciread32(
+    uint32_t bus,
+    uint32_t dev,
+    uint32_t fn,
+    uint32_t reg)
+{
+  return Rd32(MMIO, PCIADDR(bus,dev,fn,reg));
+}
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/prememinit.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/prememinit.c
new file mode 100644
index 0000000000..ebc03efa05
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/prememinit.c
@@ -0,0 +1,187 @@
+/************************************************************************
+ *
+ * Copyright (c) 2013-2015 Intel Corporation.
+ *
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ ************************************************************************/
+
+#include "mrc.h"
+#include "memory_options.h"
+
+#include "meminit_utils.h"
+#include "prememinit.h"
+#include "io.h"
+
+// Read character from serial console
+uint8_t mgetc(void);
+
+extern uint32_t DpfPrintMask;
+
+// Adjust configuration parameters before initialisation
+// sequence.
+void PreMemInit(
+    MRCParams_t *mrc_params)
+{
+  const DRAMParams_t *dram_params;
+
+  uint8_t dram_width;
+  uint32_t dram_cfg_index;
+  uint32_t channel_i;
+
+  ENTERFN();
+
+#ifdef MRC_SV
+  {
+    uint8_t ch;
+
+    myloop:
+
+    DPF(D_INFO, "- c - continue\n");
+    DPF(D_INFO, "- f - boot mode [%d]\n", mrc_params->boot_mode);
+    DPF(D_INFO, "- r - rank enable [%d]\n", mrc_params->rank_enables);
+    DPF(D_INFO, "- e - ecc switch [%d]\n", mrc_params->ecc_enables);
+    DPF(D_INFO, "- b - scrambling switch [%d]\n", mrc_params->scrambling_enables);
+    DPF(D_INFO, "- a - adr mode [%d]\n", mrc_params->address_mode);
+    DPF(D_INFO, "- m - menu after mrc [%d]\n", mrc_params->menu_after_mrc);
+    DPF(D_INFO, "- t - tune to rcvn [%d]\n", mrc_params->tune_rcvn);
+    DPF(D_INFO, "- o - odt switch [%d]\n", mrc_params->rd_odt_value);
+    DPF(D_INFO, "- d - dram density [%d]\n", mrc_params->params.DENSITY);
+    DPF(D_INFO, "- p - power down disable [%d]\n", mrc_params->power_down_disable);
+    DPF(D_INFO, "- l - log switch 0x%x\n", DpfPrintMask);
+    ch = mgetc();
+
+    switch (ch)
+    {
+    case 'f':
+      mrc_params->boot_mode >>= 1;
+      if(mrc_params->boot_mode == bmUnknown)
+      {
+         mrc_params->boot_mode = bmWarm;
+      }
+      DPF(D_INFO, "Boot mode %d\n", mrc_params->boot_mode);
+      break;
+
+    case 'p':
+      mrc_params->power_down_disable ^= 1;
+      DPF(D_INFO, "Power down disable %d\n", mrc_params->power_down_disable);
+      break;
+
+    case 'r':
+      mrc_params->rank_enables ^= 2;
+      DPF(D_INFO, "Rank enable %d\n", mrc_params->rank_enables);
+      break;
+
+    case 'e':
+      mrc_params->ecc_enables ^= 1;
+      DPF(D_INFO, "Ecc enable %d\n", mrc_params->ecc_enables);
+      break;
+
+    case 'b':
+      mrc_params->scrambling_enables ^= 1;
+      DPF(D_INFO, "Scrambler enable %d\n", mrc_params->scrambling_enables);
+      break;
+
+    case 'a':
+      mrc_params->address_mode = (mrc_params->address_mode + 1) % 3;
+      DPF(D_INFO, "Adr mode %d\n", mrc_params->address_mode);
+      break;
+
+    case 'm':
+       mrc_params->menu_after_mrc ^= 1;
+      DPF(D_INFO, "Menu after mrc %d\n", mrc_params->menu_after_mrc);
+      break;
+
+    case 't':
+      mrc_params->tune_rcvn ^= 1;
+      DPF(D_INFO, "Tune to rcvn %d\n", mrc_params->tune_rcvn);
+      break;
+
+    case 'o':
+      mrc_params->rd_odt_value = (mrc_params->rd_odt_value + 1) % 4;
+      DPF(D_INFO, "Rd_odt_value %d\n", mrc_params->rd_odt_value);
+      break;
+
+    case 'd':
+      mrc_params->params.DENSITY = (mrc_params->params.DENSITY + 1) % 4;
+      DPF(D_INFO, "Dram density %d\n", mrc_params->params.DENSITY);
+      break;
+
+    case 'l':
+      DpfPrintMask ^= 0x30;
+      DPF(D_INFO, "Log mask %x\n", DpfPrintMask);
+      break;
+
+    default:
+      break;
+    }
+
+    if (ch != 'c')
+      goto myloop;
+
+  }
+#endif
+
+  // initially expect success
+  mrc_params->status = MRC_SUCCESS;
+
+  // todo!!! Setup board layout (must be reviewed as is selecting static timings)
+  // 0 == R0 (DDR3 x16), 1 == R1 (DDR3 x16), 2 == DV (DDR3 x8), 3 == SV (DDR3 x8)
+  if (mrc_params->dram_width == x8)
+  {
+    mrc_params->board_id = 2;  // select x8 layout
+  }
+  else
+  {
+    mrc_params->board_id = 0;  // select x16 layout
+  }
+
+  // initially no memory
+  mrc_params->mem_size = 0;
+  channel_i = 0;
+
+  // begin of channel settings
+  dram_width = mrc_params->dram_width;
+  dram_params = &mrc_params->params;
+  dram_cfg_index = 0;
+
+  // Determine Column & Row Bits:
+  // Column:
+  // 11 for 8Gbx8, else 10
+  mrc_params->column_bits[channel_i] = ((dram_params[dram_cfg_index].DENSITY == 4) && (dram_width == x8)) ? (11) : (10);
+
+  // Row:
+  // 512Mbx16=12 512Mbx8=13
+  //   1Gbx16=13   1Gbx8=14
+  //   2Gbx16=14   2Gbx8=15
+  //   4Gbx16=15   4Gbx8=16
+  //   8Gbx16=16   8Gbx8=16
+  mrc_params->row_bits[channel_i] = 12 + (dram_params[dram_cfg_index].DENSITY)
+      + (((dram_params[dram_cfg_index].DENSITY < 4) && (dram_width == x8)) ? (1) : (0));
+
+  // Determine Per Channel Memory Size:
+  // (For 2 RANKs, multiply by 2)
+  // (For 16 bit data bus, divide by 2)
+  // DENSITY  WIDTH   MEM_AVAILABLE
+  // 512Mb    x16     0x008000000 ( 128MB)
+  // 512Mb    x8      0x010000000 ( 256MB)
+  // 1Gb      x16     0x010000000 ( 256MB)
+  // 1Gb      x8      0x020000000 ( 512MB)
+  // 2Gb      x16     0x020000000 ( 512MB)
+  // 2Gb      x8      0x040000000 (1024MB)
+  // 4Gb      x16     0x040000000 (1024MB)
+  // 4Gb      x8      0x080000000 (2048MB)
+  mrc_params->channel_size[channel_i] = (1 << dram_params[dram_cfg_index].DENSITY);
+  mrc_params->channel_size[channel_i] *= ((dram_width == x8) ? (2) : (1));
+  mrc_params->channel_size[channel_i] *= (mrc_params->rank_enables == 0x3) ? (2) : (1);
+  mrc_params->channel_size[channel_i] *= (mrc_params->channel_width == x16) ? (1) : (2);
+
+  // Determine memory size (convert number of 64MB/512Mb units)
+  mrc_params->mem_size += mrc_params->channel_size[channel_i] << 26;
+
+  // end of channel settings
+
+  LEAVEFN();
+  return;
+}
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/prememinit.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/prememinit.h
new file mode 100644
index 0000000000..13853fdaa2
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/prememinit.h
@@ -0,0 +1,15 @@
+/************************************************************************
+ *
+ * Copyright (c) 2013-2015 Intel Corporation.
+ *
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ ************************************************************************/
+#ifndef __PREMEMINIT_H_
+#define __PREMEMINIT_H_
+
+// Function prototypes
+void PreMemInit(MRCParams_t *mrc_params);
+
+
+#endif // _PREMEMINIT_H_
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/CommonHeader.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/CommonHeader.h
new file mode 100644
index 0000000000..20bea9277a
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/CommonHeader.h
@@ -0,0 +1,49 @@
+/** @file
+Common header file shared by all source files.
+
+This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+//
+// The package level header files this module uses
+//
+#include <PiDxe.h>
+#include <IntelQNCDxe.h>
+
+//
+// The protocols, PPI and GUID definitions for this module
+//
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Protocol/LegacyRegion2.h>
+#include <Protocol/SmbusHc.h>
+#include <Protocol/QncS3Support.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/BaseLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MtrrLib.h>
+#include <Library/IoLib.h>
+#include <Library/SmbusLib.h>
+#include <Library/S3IoLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/IntelQNCLib.h>
+#include <Library/QNCAccessLib.h>
+#include <AcpiCpuData.h>
+
+extern EFI_HANDLE gQNCInitImageHandle;
+extern QNC_DEVICE_ENABLES mQNCDeviceEnables;
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.c
new file mode 100644
index 0000000000..2731bfe136
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.c
@@ -0,0 +1,612 @@
+/** @file
+Implementation for SMBus DXE driver entry point and SMBus Host
+Controller protocol.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "CommonHeader.h"
+
+#include "DxeQNCSmbus.h"
+
+//
+// Interface defintion of SMBUS Host Controller Protocol.
+//
+EFI_SMBUS_HC_PROTOCOL mSmbusHc = {
+  SmbusExecute,
+  SmbusArpDevice,
+  SmbusGetArpMap,
+  SmbusNotify
+};
+
+//
+// Handle to install SMBus Host Controller protocol.
+//
+EFI_HANDLE                   mSmbusHcHandle = NULL;
+UINT8                        mDeviceMapEntries = 0;
+EFI_SMBUS_DEVICE_MAP         mDeviceMap[MAX_SMBUS_DEVICES];
+UINT8                        mPlatformNumRsvd = 0;
+UINT8                        *mPlatformAddrRsvd = NULL;
+
+//
+// These addresses are reserved by the SMBus 2.0 specification
+//
+UINT8    mReservedAddress[SMBUS_NUM_RESERVED] = {
+  0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x18, 0x50, 0x6E, 0xC2,
+  0xF0, 0xF2, 0xF4, 0xF6, 0xF8, 0xFA, 0xFC, 0xFE
+};
+
+
+/**
+  Gets Io port base address of Smbus Host Controller.
+
+  This internal function depends on a feature flag named PcdIchSmbusFixedIoPortBaseAddress
+  to retrieve Smbus Io port base. If that feature flag is true, it will get Smbus Io port base
+  address from a preset Pcd entry named PcdIchSmbusIoPortBaseAddress; otherwise, it will always
+  read Pci configuration space to get that value in each Smbus bus transaction.
+
+  @return The Io port base address of Smbus host controller.
+
+**/
+UINTN
+GetSmbusIoPortBaseAddress (
+  VOID
+  )
+{
+  UINTN     IoPortBaseAddress;
+
+  if (FeaturePcdGet (PcdSmbaIoBaseAddressFixed)) {
+    IoPortBaseAddress = (UINTN) PcdGet16 (PcdSmbaIoBaseAddress);
+  } else {
+    IoPortBaseAddress = (UINTN) LpcPciCfg32 (R_QNC_LPC_SMBUS_BASE) & B_QNC_LPC_SMBUS_BASE_MASK;
+  }
+
+  //
+  // Make sure that the IO port base address has been properly set.
+  //
+  ASSERT (IoPortBaseAddress != 0);
+
+  return IoPortBaseAddress;
+}
+
+
+VOID
+InitializeInternal (
+  )
+{
+  UINTN     IoPortBaseAddress;
+
+  IoPortBaseAddress = GetSmbusIoPortBaseAddress ();
+
+  //
+  // Step1: Enable QNC SMBUS I/O space.
+  //
+  LpcPciCfg32Or(R_QNC_LPC_SMBUS_BASE, B_QNC_LPC_SMBUS_BASE_EN);
+
+  //
+  // Step2: Clear Status Register before anyone uses the interfaces.
+  //
+  IoWrite8 (IoPortBaseAddress + R_QNC_SMBUS_HSTS, B_QNC_SMBUS_HSTS_ALL);
+
+  //
+  // Step3: Program the correct smbus clock
+  //
+  IoWrite8 (IoPortBaseAddress + R_QNC_SMBUS_HCLK, V_QNC_SMBUS_HCLK_100KHZ);
+}
+
+
+
+
+BOOLEAN
+IsAddressAvailable (
+  IN      EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress
+  )
+{
+  UINT8         Index;
+
+  //
+  // See if we have already assigned this address to a device
+  //
+  for (Index = 0; Index < mDeviceMapEntries; Index++) {
+    if (SlaveAddress.SmbusDeviceAddress ==
+         mDeviceMap[Index].SmbusDeviceAddress.SmbusDeviceAddress) {
+      return FALSE;
+    }
+  }
+
+  //
+  // See if this address is claimed by a platform non-ARP-capable device
+  //
+  for (Index = 0; Index < mPlatformNumRsvd; Index++) {
+    if ((SlaveAddress.SmbusDeviceAddress << 1) == mPlatformAddrRsvd[Index]) {
+      return FALSE;
+    }
+  }
+
+  //
+  // See if this is a reserved address
+  //
+  for (Index = 0; Index < SMBUS_NUM_RESERVED; Index++) {
+    if (SlaveAddress.SmbusDeviceAddress == (UINTN) mReservedAddress[Index]) {
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
+
+EFI_STATUS
+GetNextAvailableAddress (
+  IN EFI_SMBUS_DEVICE_ADDRESS  *SlaveAddress
+  )
+{
+  for (SlaveAddress->SmbusDeviceAddress = 0x03;
+    SlaveAddress->SmbusDeviceAddress < 0x7F;
+    SlaveAddress->SmbusDeviceAddress++
+    ) {
+    if (IsAddressAvailable (*SlaveAddress)) {
+      return EFI_SUCCESS;
+    }
+  }
+
+  return EFI_OUT_OF_RESOURCES;
+}
+
+EFI_STATUS
+SmbusPrepareToArp (
+  )
+{
+  EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress;
+  EFI_STATUS                Status;
+  UINTN                     Length;
+  UINT8                     Buffer;
+
+  SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP;
+  Length = 1;
+  Buffer = SMBUS_DATA_PREPARE_TO_ARP;
+
+  Status = Execute (
+             SlaveAddress,
+             0,
+             EfiSmbusSendByte,
+             TRUE,
+             &Length,
+             &Buffer
+             );
+  return Status;
+}
+
+EFI_STATUS
+SmbusGetUdidGeneral (
+  IN OUT  EFI_SMBUS_DEVICE_MAP  *DeviceMap
+  )
+{
+  EFI_SMBUS_DEVICE_ADDRESS      SlaveAddress;
+  EFI_STATUS                    Status;
+  UINTN                         Length;
+  UINT8                         Buffer[SMBUS_GET_UDID_LENGTH];
+
+  SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP;
+  Length = SMBUS_GET_UDID_LENGTH;
+
+  Status = Execute (
+             SlaveAddress,
+             SMBUS_DATA_GET_UDID_GENERAL,
+             EfiSmbusReadBlock,
+             TRUE,
+             &Length,
+             Buffer
+             );
+
+  if (!EFI_ERROR(Status)) {
+    if (Length == SMBUS_GET_UDID_LENGTH) {
+      DeviceMap->SmbusDeviceUdid.DeviceCapabilities = Buffer[0];
+      DeviceMap->SmbusDeviceUdid.VendorRevision = Buffer[1];
+      DeviceMap->SmbusDeviceUdid.VendorId = (UINT16)((Buffer[2] << 8) + Buffer[3]);
+      DeviceMap->SmbusDeviceUdid.DeviceId = (UINT16)((Buffer[4] << 8) + Buffer[5]);
+      DeviceMap->SmbusDeviceUdid.Interface = (UINT16)((Buffer[6] << 8) + Buffer[7]);
+      DeviceMap->SmbusDeviceUdid.SubsystemVendorId = (UINT16)((Buffer[8] << 8) + Buffer[9]);
+      DeviceMap->SmbusDeviceUdid.SubsystemDeviceId = (UINT16)((Buffer[10] << 8) + Buffer[11]);
+      DeviceMap->SmbusDeviceUdid.VendorSpecificId = (UINT32)((Buffer[12] << 24) + (Buffer[13] << 16) + (Buffer[14] << 8) + Buffer[15]);
+      DeviceMap->SmbusDeviceAddress.SmbusDeviceAddress = (UINT8)(Buffer[16] >> 1);
+    } else {
+      Status = EFI_DEVICE_ERROR;
+    }
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+SmbusAssignAddress (
+  IN OUT  EFI_SMBUS_DEVICE_MAP  *DeviceMap
+  )
+{
+  EFI_SMBUS_DEVICE_ADDRESS      SlaveAddress;
+  EFI_STATUS                    Status;
+  UINTN                         Length;
+  UINT8                         Buffer[SMBUS_GET_UDID_LENGTH];
+
+  Buffer[0] = DeviceMap->SmbusDeviceUdid.DeviceCapabilities;
+  Buffer[1] = DeviceMap->SmbusDeviceUdid.VendorRevision;
+  Buffer[2] = (UINT8)(DeviceMap->SmbusDeviceUdid.VendorId >> 8);
+  Buffer[3] = (UINT8)(DeviceMap->SmbusDeviceUdid.VendorId);
+  Buffer[4] = (UINT8)(DeviceMap->SmbusDeviceUdid.DeviceId >> 8);
+  Buffer[5] = (UINT8)(DeviceMap->SmbusDeviceUdid.DeviceId);
+  Buffer[6] = (UINT8)(DeviceMap->SmbusDeviceUdid.Interface >> 8);
+  Buffer[7] = (UINT8)(DeviceMap->SmbusDeviceUdid.Interface);
+  Buffer[8] = (UINT8)(DeviceMap->SmbusDeviceUdid.SubsystemVendorId >> 8);
+  Buffer[9] = (UINT8)(DeviceMap->SmbusDeviceUdid.SubsystemVendorId);
+  Buffer[10] = (UINT8)(DeviceMap->SmbusDeviceUdid.SubsystemDeviceId >> 8);
+  Buffer[11] = (UINT8)(DeviceMap->SmbusDeviceUdid.SubsystemDeviceId);
+  Buffer[12] = (UINT8)(DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 24);
+  Buffer[13] = (UINT8)(DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 16);
+  Buffer[14] = (UINT8)(DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 8);
+  Buffer[15] = (UINT8)(DeviceMap->SmbusDeviceUdid.VendorSpecificId);
+  Buffer[16] = (UINT8)(DeviceMap->SmbusDeviceAddress.SmbusDeviceAddress << 1);
+
+  SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP;
+  Length = SMBUS_GET_UDID_LENGTH;
+
+  Status = Execute (
+             SlaveAddress,
+             SMBUS_DATA_ASSIGN_ADDRESS,
+             EfiSmbusWriteBlock,
+             TRUE,
+             &Length,
+             Buffer
+             );
+  return Status;
+}
+
+
+EFI_STATUS
+SmbusFullArp (
+  )
+{
+  EFI_STATUS              Status;
+  EFI_SMBUS_DEVICE_MAP    *CurrentDeviceMap;
+
+  Status = SmbusPrepareToArp ();
+  if (EFI_ERROR(Status)) {
+    if (Status == EFI_DEVICE_ERROR) {
+      //
+      //  ARP is complete
+      //
+      return EFI_SUCCESS;
+    } else {
+      return Status;
+    }
+  }
+
+  //
+  //  Main loop to ARP all ARP-capable devices
+  //
+  do {
+    CurrentDeviceMap = &mDeviceMap[mDeviceMapEntries];
+    Status = SmbusGetUdidGeneral (CurrentDeviceMap);
+    if (EFI_ERROR(Status)) {
+      break;
+    }
+
+    if (CurrentDeviceMap->SmbusDeviceAddress.SmbusDeviceAddress == (0xFF >> 1)) {
+      //
+      // If address is unassigned, assign it
+      //
+      Status = GetNextAvailableAddress (
+                 &CurrentDeviceMap->SmbusDeviceAddress
+                 );
+      if (EFI_ERROR(Status)) {
+        return EFI_OUT_OF_RESOURCES;
+      }
+    } else if (((CurrentDeviceMap->SmbusDeviceUdid.DeviceCapabilities) & 0xC0) != 0) {
+      //
+      // if address is not fixed, check if the current address is available
+      //
+      if (!IsAddressAvailable (
+             CurrentDeviceMap->SmbusDeviceAddress
+             )) {
+        //
+        // if currently assigned address is already used, get a new one
+        //
+        Status = GetNextAvailableAddress (
+                   &CurrentDeviceMap->SmbusDeviceAddress
+                   );
+        if (EFI_ERROR(Status)) {
+          return EFI_OUT_OF_RESOURCES;
+        }
+      }
+    }
+
+    Status = SmbusAssignAddress (CurrentDeviceMap);
+    if (EFI_ERROR(Status)) {
+      //
+      // If there was a device error, just continue on and try again.
+      // Other errors should be reported.
+      //
+      if (Status != EFI_DEVICE_ERROR) {
+        return Status;
+      }
+    } else {
+      //
+      // If there was no error, the address was assigned and we must update our
+      // records.
+      //
+      mDeviceMapEntries++;
+    }
+
+  } while (mDeviceMapEntries < MAX_SMBUS_DEVICES);
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+SmbusDirectedArp (
+  IN      EFI_SMBUS_UDID            *SmbusUdid,
+  IN OUT  EFI_SMBUS_DEVICE_ADDRESS  *SlaveAddress
+  )
+{
+  EFI_STATUS                        Status;
+  EFI_SMBUS_DEVICE_MAP              *CurrentDeviceMap;
+
+  if (mDeviceMapEntries >= MAX_SMBUS_DEVICES) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  CurrentDeviceMap = &mDeviceMap[mDeviceMapEntries];
+
+  //
+  // Find an available address to assign
+  //
+  Status = GetNextAvailableAddress (
+             &CurrentDeviceMap->SmbusDeviceAddress
+             );
+  if (EFI_ERROR(Status)) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  CurrentDeviceMap->SmbusDeviceUdid.DeviceCapabilities  = SmbusUdid->DeviceCapabilities;
+  CurrentDeviceMap->SmbusDeviceUdid.DeviceId            = SmbusUdid->DeviceId;
+  CurrentDeviceMap->SmbusDeviceUdid.Interface           = SmbusUdid->Interface;
+  CurrentDeviceMap->SmbusDeviceUdid.SubsystemDeviceId   = SmbusUdid->SubsystemDeviceId;
+  CurrentDeviceMap->SmbusDeviceUdid.SubsystemVendorId   = SmbusUdid->SubsystemVendorId;
+  CurrentDeviceMap->SmbusDeviceUdid.VendorId            = SmbusUdid->VendorId;
+  CurrentDeviceMap->SmbusDeviceUdid.VendorRevision      = SmbusUdid->VendorRevision;
+  CurrentDeviceMap->SmbusDeviceUdid.VendorSpecificId    = SmbusUdid->VendorSpecificId;
+
+  Status = SmbusAssignAddress (CurrentDeviceMap);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  mDeviceMapEntries++;
+  SlaveAddress->SmbusDeviceAddress = CurrentDeviceMap->SmbusDeviceAddress.SmbusDeviceAddress;
+
+  return EFI_SUCCESS;
+}
+
+
+
+/**
+  Executes an SMBus operation to an SMBus controller. Returns when either the command has been
+  executed or an error is encountered in doing the operation.
+
+  The Execute() function provides a standard way to execute an operation as defined in the System
+  Management Bus (SMBus) Specification. The resulting transaction will be either that the SMBus
+  slave devices accept this transaction or that this function returns with error.
+
+  @param  This                    A pointer to the EFI_SMBUS_HC_PROTOCOL instance.
+  @param  SlaveAddress            The SMBus slave address of the device with which to communicate.
+  @param  Command                 This command is transmitted by the SMBus host controller to the
+                                  SMBus slave device and the interpretation is SMBus slave device
+                                  specific. It can mean the offset to a list of functions inside an
+                                  SMBus slave device. Not all operations or slave devices support
+                                  this command's registers.
+  @param  Operation               Signifies which particular SMBus hardware protocol instance that
+                                  it will use to execute the SMBus transactions. This SMBus
+                                  hardware protocol is defined by the SMBus Specification and is
+                                  not related to EFI.
+  @param  PecCheck                Defines if Packet Error Code (PEC) checking is required for this
+                                  operation.
+  @param  Length                  Signifies the number of bytes that this operation will do. The
+                                  maximum number of bytes can be revision specific and operation
+                                  specific. This field will contain the actual number of bytes that
+                                  are executed for this operation. Not all operations require this
+                                  argument.
+  @param  Buffer                  Contains the value of data to execute to the SMBus slave device.
+                                  Not all operations require this argument. The length of this
+                                  buffer is identified by Length.
+
+  @retval EFI_SUCCESS             The last data that was returned from the access matched the poll
+                                  exit criteria.
+  @retval EFI_CRC_ERROR           Checksum is not correct (PEC is incorrect).
+  @retval EFI_TIMEOUT             Timeout expired before the operation was completed. Timeout is
+                                  determined by the SMBus host controller device.
+  @retval EFI_OUT_OF_RESOURCES    The request could not be completed due to a lack of resources.
+  @retval EFI_DEVICE_ERROR        The request was not completed because a failure that was
+                                  reflected in the Host Status Register bit. Device errors are a
+                                  result of a transaction collision, illegal command field,
+                                  unclaimed cycle (host initiated), or bus errors (collisions).
+  @retval EFI_INVALID_PARAMETER   Operation is not defined in EFI_SMBUS_OPERATION.
+  @retval EFI_INVALID_PARAMETER   Length/Buffer is NULL for operations except for EfiSmbusQuickRead
+                                  and EfiSmbusQuickWrite. Length is outside the range of valid
+                                  values.
+  @retval EFI_UNSUPPORTED         The SMBus operation or PEC is not supported.
+  @retval EFI_BUFFER_TOO_SMALL    Buffer is not sufficient for this operation.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusExecute (
+  IN CONST  EFI_SMBUS_HC_PROTOCOL     *This,
+  IN CONST  EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress,
+  IN CONST  EFI_SMBUS_DEVICE_COMMAND  Command,
+  IN CONST  EFI_SMBUS_OPERATION       Operation,
+  IN CONST  BOOLEAN                   PecCheck,
+  IN OUT    UINTN                     *Length,
+  IN OUT    VOID                      *Buffer
+  )
+{
+  InitializeInternal ();
+  return Execute (
+           SlaveAddress,
+           Command,
+           Operation,
+           PecCheck,
+           Length,
+           Buffer
+           );
+}
+
+/**
+  Sets the SMBus slave device addresses for the device with a given unique ID or enumerates the
+  entire bus.
+
+  The ArpDevice() function provides a standard way for a device driver to enumerate the entire
+  SMBus or specific devices on the bus.
+
+  @param  This                    A pointer to the EFI_SMBUS_HC_PROTOCOL instance.
+  @param  ArpAll                  A Boolean expression that indicates if the host drivers need to
+                                  enumerate all the devices or enumerate only the device that is
+                                  identified by SmbusUdid. If ArpAll is TRUE, SmbusUdid and
+                                  SlaveAddress are optional. If ArpAll is FALSE, ArpDevice will
+                                  enumerate SmbusUdid and the address will be at SlaveAddress.
+  @param  SmbusUdid               The Unique Device Identifier (UDID) that is associated with this
+                                  device.
+  @param  SlaveAddress            The SMBus slave address that is associated with an SMBus UDID.
+
+  @retval EFI_SUCCESS             The last data that was returned from the access matched the poll
+                                  exit criteria.
+  @retval EFI_CRC_ERROR           Checksum is not correct (PEC is incorrect).
+  @retval EFI_TIMEOUT             Timeout expired before the operation was completed. Timeout is
+                                  determined by the SMBus host controller device.
+  @retval EFI_OUT_OF_RESOURCES    The request could not be completed due to a lack of resources.
+  @retval EFI_DEVICE_ERROR        The request was not completed because a failure that was
+                                  reflected in the Host Status Register bit. Device errors are a
+                                  result of a transaction collision, illegal command field,
+                                  unclaimed cycle (host initiated), or bus errors (collisions).
+  @retval EFI_UNSUPPORTED         The corresponding SMBus operation is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusArpDevice (
+  IN CONST  EFI_SMBUS_HC_PROTOCOL     *This,
+  IN        BOOLEAN                   ArpAll,
+  IN        EFI_SMBUS_UDID            *SmbusUdid,   OPTIONAL
+  IN OUT    EFI_SMBUS_DEVICE_ADDRESS  *SlaveAddress OPTIONAL
+  )
+{
+    InitializeInternal ();
+
+    if (ArpAll) {
+    return SmbusFullArp ();
+  } else {
+    if ((SmbusUdid == NULL) || (SlaveAddress == NULL)) {
+      return EFI_INVALID_PARAMETER;
+    }
+    return SmbusDirectedArp ((EFI_SMBUS_UDID *)SmbusUdid, SlaveAddress);
+  }
+}
+
+/**
+  Returns a pointer to the Address Resolution Protocol (ARP) map that contains the ID/address pair
+  of the slave devices that were enumerated by the SMBus host controller driver.
+
+  The GetArpMap() function returns the mapping of all the SMBus devices that were enumerated by the
+  SMBus host driver.
+
+  @param  This                    A pointer to the EFI_SMBUS_HC_PROTOCOL instance.
+  @param  Length                  Size of the buffer that contains the SMBus device map.
+  @param  SmbusDeviceMap          The pointer to the device map as enumerated by the SMBus
+                                  controller driver.
+
+  @retval EFI_SUCCESS             The SMBus returned the current device map.
+  @retval EFI_UNSUPPORTED         The corresponding operation is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusGetArpMap (
+  IN CONST  EFI_SMBUS_HC_PROTOCOL   *This,
+  IN OUT    UINTN                   *Length,
+  IN OUT    EFI_SMBUS_DEVICE_MAP    **SmbusDeviceMap
+  )
+{
+  *Length = mDeviceMapEntries;
+  *SmbusDeviceMap = mDeviceMap;
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Allows a device driver to register for a callback when the bus driver detects a state that it
+  needs to propagate to other drivers that are registered for a callback.
+
+  The Notify() function registers all the callback functions to allow the bus driver to call these
+  functions when the SlaveAddress/Data pair happens.
+  If NotifyFunction is NULL, then ASSERT ().
+
+  @param  This                    A pointer to the EFI_SMBUS_HC_PROTOCOL instance.
+  @param  SlaveAddress            The SMBUS hardware address to which the SMBUS device is
+                                  preassigned or allocated.
+  @param  Data                    Data of the SMBus host notify command that the caller wants to be
+                                  called.
+  @param  NotifyFunction          The function to call when the bus driver detects the SlaveAddress
+                                  and Data pair.
+
+  @retval EFI_SUCCESS             NotifyFunction was registered.
+  @retval EFI_UNSUPPORTED         The corresponding operation is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusNotify (
+  IN CONST  EFI_SMBUS_HC_PROTOCOL     *This,
+  IN CONST  EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress,
+  IN CONST  UINTN                     Data,
+  IN CONST  EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Entry point to the DXE Driver that produces the SMBus Host Controller Protocol.
+
+  @param  ImageHandle      ImageHandle of the loaded driver.
+  @param  SystemTable      Pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS      The entry point of SMBus DXE driver is executed successfully.
+  @retval !EFI_SUCESS      Some error occurs in the entry point of SMBus DXE driver.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeQNCSmbus (
+  IN EFI_HANDLE            ImageHandle,
+  IN EFI_SYSTEM_TABLE      *SystemTable
+  )
+{
+  EFI_STATUS    Status;
+
+  mPlatformNumRsvd = (UINT8)PcdGet32 (PcdPlatformSmbusAddrNum);
+  mPlatformAddrRsvd = (UINT8 *)(UINTN) PcdGet64 (PcdPlatformSmbusAddrTable);
+
+  //
+  // Install SMBus Host Controller protocol interface.
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mSmbusHcHandle,
+                  &gEfiSmbusHcProtocolGuid,
+                  &mSmbusHc,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.h
new file mode 100644
index 0000000000..6a302ce838
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.h
@@ -0,0 +1,205 @@
+/** @file
+Header file for the defintions used in SMBus DXE driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#ifndef _DXE_QNC_SMBUS_H_
+#define _DXE_QNC_SMBUS_H_
+#include "CommonHeader.h"
+
+#include "QNCSmbus.h"
+
+#define MAX_SMBUS_DEVICES   107     // Max number of SMBus devices (7 bit
+                                    //   address yields 128 combinations but 21
+                                    //   of those are reserved)
+
+#define MICROSECOND     10
+#define MILLISECOND     (1000 * MICROSECOND)
+#define ONESECOND       (1000 * MILLISECOND)
+
+#define STALL_TIME          1000000 // 1,000,000 microseconds = 1 second
+#define BUS_TRIES           3       // How many times to retry on Bus Errors
+#define SMBUS_NUM_RESERVED  21      // Number of device addresses that are
+                                    //   reserved by the SMBus spec.
+#define SMBUS_ADDRESS_ARP   0xC2 >> 1
+#define   SMBUS_DATA_PREPARE_TO_ARP   0x01
+#define   SMBUS_DATA_RESET_DEVICE     0x02
+#define   SMBUS_DATA_GET_UDID_GENERAL 0x03
+#define   SMBUS_DATA_ASSIGN_ADDRESS   0x04
+#define SMBUS_GET_UDID_LENGTH 17    // 16 byte UDID + 1 byte address
+
+/**
+  Executes an SMBus operation to an SMBus controller. Returns when either the command has been
+  executed or an error is encountered in doing the operation.
+
+  The Execute() function provides a standard way to execute an operation as defined in the System
+  Management Bus (SMBus) Specification. The resulting transaction will be either that the SMBus
+  slave devices accept this transaction or that this function returns with error.
+
+  @param  This                    A pointer to the EFI_SMBUS_HC_PROTOCOL instance.
+  @param  SlaveAddress            The SMBus slave address of the device with which to communicate.
+  @param  Command                 This command is transmitted by the SMBus host controller to the
+                                  SMBus slave device and the interpretation is SMBus slave device
+                                  specific. It can mean the offset to a list of functions inside an
+                                  SMBus slave device. Not all operations or slave devices support
+                                  this command's registers.
+  @param  Operation               Signifies which particular SMBus hardware protocol instance that
+                                  it will use to execute the SMBus transactions. This SMBus
+                                  hardware protocol is defined by the SMBus Specification and is
+                                  not related to EFI.
+  @param  PecCheck                Defines if Packet Error Code (PEC) checking is required for this
+                                  operation.
+  @param  Length                  Signifies the number of bytes that this operation will do. The
+                                  maximum number of bytes can be revision specific and operation
+                                  specific. This field will contain the actual number of bytes that
+                                  are executed for this operation. Not all operations require this
+                                  argument.
+  @param  Buffer                  Contains the value of data to execute to the SMBus slave device.
+                                  Not all operations require this argument. The length of this
+                                  buffer is identified by Length.
+
+  @retval EFI_SUCCESS             The last data that was returned from the access matched the poll
+                                  exit criteria.
+  @retval EFI_CRC_ERROR           Checksum is not correct (PEC is incorrect).
+  @retval EFI_TIMEOUT             Timeout expired before the operation was completed. Timeout is
+                                  determined by the SMBus host controller device.
+  @retval EFI_OUT_OF_RESOURCES    The request could not be completed due to a lack of resources.
+  @retval EFI_DEVICE_ERROR        The request was not completed because a failure that was
+                                  reflected in the Host Status Register bit. Device errors are a
+                                  result of a transaction collision, illegal command field,
+                                  unclaimed cycle (host initiated), or bus errors (collisions).
+  @retval EFI_INVALID_PARAMETER   Operation is not defined in EFI_SMBUS_OPERATION.
+  @retval EFI_INVALID_PARAMETER   Length/Buffer is NULL for operations except for EfiSmbusQuickRead
+                                  and EfiSmbusQuickWrite. Length is outside the range of valid
+                                  values.
+  @retval EFI_UNSUPPORTED         The SMBus operation or PEC is not supported.
+  @retval EFI_BUFFER_TOO_SMALL    Buffer is not sufficient for this operation.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusExecute (
+  IN CONST  EFI_SMBUS_HC_PROTOCOL     *This,
+  IN CONST  EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress,
+  IN CONST  EFI_SMBUS_DEVICE_COMMAND  Command,
+  IN CONST  EFI_SMBUS_OPERATION       Operation,
+  IN CONST  BOOLEAN                   PecCheck,
+  IN OUT    UINTN                     *Length,
+  IN OUT    VOID                      *Buffer
+  );
+
+/**
+  Sets the SMBus slave device addresses for the device with a given unique ID or enumerates the
+  entire bus.
+
+  The ArpDevice() function provides a standard way for a device driver to enumerate the entire
+  SMBus or specific devices on the bus.
+
+  @param  This                    A pointer to the EFI_SMBUS_HC_PROTOCOL instance.
+  @param  ArpAll                  A Boolean expression that indicates if the host drivers need to
+                                  enumerate all the devices or enumerate only the device that is
+                                  identified by SmbusUdid. If ArpAll is TRUE, SmbusUdid and
+                                  SlaveAddress are optional. If ArpAll is FALSE, ArpDevice will
+                                  enumerate SmbusUdid and the address will be at SlaveAddress.
+  @param  SmbusUdid               The Unique Device Identifier (UDID) that is associated with this
+                                  device.
+  @param  SlaveAddress            The SMBus slave address that is associated with an SMBus UDID.
+
+  @retval EFI_SUCCESS             The last data that was returned from the access matched the poll
+                                  exit criteria.
+  @retval EFI_CRC_ERROR           Checksum is not correct (PEC is incorrect).
+  @retval EFI_TIMEOUT             Timeout expired before the operation was completed. Timeout is
+                                  determined by the SMBus host controller device.
+  @retval EFI_OUT_OF_RESOURCES    The request could not be completed due to a lack of resources.
+  @retval EFI_DEVICE_ERROR        The request was not completed because a failure that was
+                                  reflected in the Host Status Register bit. Device errors are a
+                                  result of a transaction collision, illegal command field,
+                                  unclaimed cycle (host initiated), or bus errors (collisions).
+  @retval EFI_UNSUPPORTED         The corresponding operation is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusArpDevice (
+  IN CONST  EFI_SMBUS_HC_PROTOCOL     *This,
+  IN        BOOLEAN                   ArpAll,
+  IN        EFI_SMBUS_UDID            *SmbusUdid,   OPTIONAL
+  IN OUT    EFI_SMBUS_DEVICE_ADDRESS  *SlaveAddress OPTIONAL
+  );
+
+/**
+  Returns a pointer to the Address Resolution Protocol (ARP) map that contains the ID/address pair
+  of the slave devices that were enumerated by the SMBus host controller driver.
+
+  The GetArpMap() function returns the mapping of all the SMBus devices that were enumerated by the
+  SMBus host driver.
+
+  @param  This                    A pointer to the EFI_SMBUS_HC_PROTOCOL instance.
+  @param  Length                  Size of the buffer that contains the SMBus device map.
+  @param  SmbusDeviceMap          The pointer to the device map as enumerated by the SMBus
+                                  controller driver.
+
+  @retval EFI_SUCCESS             The SMBus returned the current device map.
+  @retval EFI_UNSUPPORTED         The corresponding operation is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusGetArpMap (
+  IN CONST  EFI_SMBUS_HC_PROTOCOL   *This,
+  IN OUT    UINTN                   *Length,
+  IN OUT    EFI_SMBUS_DEVICE_MAP    **SmbusDeviceMap
+  );
+
+/**
+  Allows a device driver to register for a callback when the bus driver detects a state that it
+  needs to propagate to other drivers that are registered for a callback.
+
+  The Notify() function registers all the callback functions to allow the bus driver to call these
+  functions when the SlaveAddress/Data pair happens.
+  If NotifyFunction is NULL, then ASSERT ().
+
+  @param  This                    A pointer to the EFI_SMBUS_HC_PROTOCOL instance.
+  @param  SlaveAddress            The SMBUS hardware address to which the SMBUS device is
+                                  preassigned or allocated.
+  @param  Data                    Data of the SMBus host notify command that the caller wants to be
+                                  called.
+  @param  NotifyFunction          The function to call when the bus driver detects the SlaveAddress
+                                  and Data pair.
+
+  @retval EFI_SUCCESS             NotifyFunction was registered.
+  @retval EFI_UNSUPPORTED         The corresponding operation is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusNotify (
+  IN CONST  EFI_SMBUS_HC_PROTOCOL     *This,
+  IN CONST  EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress,
+  IN CONST  UINTN                     Data,
+  IN CONST  EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction
+  );
+
+/**
+  Entry point to the DXE Driver that produces the SMBus Host Controller Protocol.
+
+  @param  ImageHandle      ImageHandle of the loaded driver.
+  @param  SystemTable      Pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS      The entry point of SMBus DXE driver is executed successfully.
+  @retval !EFI_SUCESS      Some error occurs in the entry point of SMBus DXE driver.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeQNCSmbus (
+  IN EFI_HANDLE            ImageHandle,
+  IN EFI_SYSTEM_TABLE      *SystemTable
+  );
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.c
new file mode 100644
index 0000000000..db9c6f29e5
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.c
@@ -0,0 +1,237 @@
+/** @file
+QNC Legacy Region Driver
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CommonHeader.h"
+#include "LegacyRegion.h"
+
+//
+// Handle used to install the Legacy Region Protocol
+//
+EFI_HANDLE  mLegacyRegion2Handle = NULL;
+
+//
+// Instance of the Legacy Region Protocol to install into the handle database
+//
+EFI_LEGACY_REGION2_PROTOCOL  mLegacyRegion2 = {
+  LegacyRegion2Decode,
+  LegacyRegion2Lock,
+  LegacyRegion2BootLock,
+  LegacyRegion2Unlock,
+  LegacyRegionGetInfo
+};
+
+
+/**
+  Modify the hardware to allow (decode) or disallow (not decode) memory reads in a region.
+
+  If the On parameter evaluates to TRUE, this function enables memory reads in the address range
+  Start to (Start + Length - 1).
+  If the On parameter evaluates to FALSE, this function disables memory reads in the address range
+  Start to (Start + Length - 1).
+
+  @param  This[in]              Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
+  @param  Start[in]             The beginning of the physical address of the region whose attributes
+                                should be modified.
+  @param  Length[in]            The number of bytes of memory whose attributes should be modified.
+                                The actual number of bytes modified may be greater than the number
+                                specified.
+  @param  Granularity[out]      The number of bytes in the last region affected. This may be less
+                                than the total number of bytes affected if the starting address
+                                was not aligned to a region's starting address or if the length
+                                was greater than the number of bytes in the first region.
+  @param  On[in]                Decode / Non-Decode flag.
+
+  @retval EFI_SUCCESS           The region's attributes were successfully modified.
+  @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacyRegion2Decode (
+  IN  EFI_LEGACY_REGION2_PROTOCOL  *This,
+  IN  UINT32                       Start,
+  IN  UINT32                       Length,
+  OUT UINT32                       *Granularity,
+  IN  BOOLEAN                      *On
+  )
+{
+  return QNCLegacyRegionManipulation (Start, Length, On, NULL, Granularity);
+}
+
+
+/**
+  Modify the hardware to disallow memory attribute changes in a region.
+
+  This function makes the attributes of a region read only. Once a region is boot-locked with this
+  function, the read and write attributes of that region cannot be changed until a power cycle has
+  reset the boot-lock attribute. Calls to Decode(), Lock() and Unlock() will have no effect.
+
+  @param  This[in]              Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
+  @param  Start[in]             The beginning of the physical address of the region whose
+                                attributes should be modified.
+  @param  Length[in]            The number of bytes of memory whose attributes should be modified.
+                                The actual number of bytes modified may be greater than the number
+                                specified.
+  @param  Granularity[out]      The number of bytes in the last region affected. This may be less
+                                than the total number of bytes affected if the starting address was
+                                not aligned to a region's starting address or if the length was
+                                greater than the number of bytes in the first region.
+
+  @retval EFI_SUCCESS           The region's attributes were successfully modified.
+  @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
+  @retval EFI_UNSUPPORTED       The chipset does not support locking the configuration registers in
+                                a way that will not affect memory regions outside the legacy memory
+                                region.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacyRegion2BootLock (
+  IN  EFI_LEGACY_REGION2_PROTOCOL         *This,
+  IN  UINT32                              Start,
+  IN  UINT32                              Length,
+  OUT UINT32                              *Granularity
+  )
+{
+  if ((Start < 0xC0000) || ((Start + Length - 1) > 0xFFFFF)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return EFI_UNSUPPORTED;
+}
+
+
+/**
+  Modify the hardware to disallow memory writes in a region.
+
+  This function changes the attributes of a memory range to not allow writes.
+
+  @param  This[in]              Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
+  @param  Start[in]             The beginning of the physical address of the region whose
+                                attributes should be modified.
+  @param  Length[in]            The number of bytes of memory whose attributes should be modified.
+                                The actual number of bytes modified may be greater than the number
+                                specified.
+  @param  Granularity[out]      The number of bytes in the last region affected. This may be less
+                                than the total number of bytes affected if the starting address was
+                                not aligned to a region's starting address or if the length was
+                                greater than the number of bytes in the first region.
+
+  @retval EFI_SUCCESS           The region's attributes were successfully modified.
+  @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacyRegion2Lock (
+  IN  EFI_LEGACY_REGION2_PROTOCOL *This,
+  IN  UINT32                      Start,
+  IN  UINT32                      Length,
+  OUT UINT32                      *Granularity
+  )
+{
+  BOOLEAN  WriteEnable;
+
+  WriteEnable = FALSE;
+  return QNCLegacyRegionManipulation (Start, Length, NULL, &WriteEnable, Granularity);
+}
+
+
+/**
+  Modify the hardware to allow memory writes in a region.
+
+  This function changes the attributes of a memory range to allow writes.
+
+  @param  This[in]              Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
+  @param  Start[in]             The beginning of the physical address of the region whose
+                                attributes should be modified.
+  @param  Length[in]            The number of bytes of memory whose attributes should be modified.
+                                The actual number of bytes modified may be greater than the number
+                                specified.
+  @param  Granularity[out]      The number of bytes in the last region affected. This may be less
+                                than the total number of bytes affected if the starting address was
+                                not aligned to a region's starting address or if the length was
+                                greater than the number of bytes in the first region.
+
+  @retval EFI_SUCCESS           The region's attributes were successfully modified.
+  @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacyRegion2Unlock (
+  IN  EFI_LEGACY_REGION2_PROTOCOL  *This,
+  IN  UINT32                       Start,
+  IN  UINT32                       Length,
+  OUT UINT32                       *Granularity
+  )
+{
+  BOOLEAN  WriteEnable;
+
+  WriteEnable = TRUE;
+  return QNCLegacyRegionManipulation (Start, Length, NULL, &WriteEnable, Granularity);
+}
+
+/**
+  Get region information for the attributes of the Legacy Region.
+
+  This function is used to discover the granularity of the attributes for the memory in the legacy
+  region. Each attribute may have a different granularity and the granularity may not be the same
+  for all memory ranges in the legacy region.
+
+  @param  This[in]              Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
+  @param  DescriptorCount[out]  The number of region descriptor entries returned in the Descriptor
+                                buffer.
+  @param  Descriptor[out]       A pointer to a pointer used to return a buffer where the legacy
+                                region information is deposited. This buffer will contain a list of
+                                DescriptorCount number of region descriptors.  This function will
+                                provide the memory for the buffer.
+
+  @retval EFI_SUCCESS           The region's attributes were successfully modified.
+  @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacyRegionGetInfo (
+  IN  EFI_LEGACY_REGION2_PROTOCOL   *This,
+  OUT UINT32                        *DescriptorCount,
+  OUT EFI_LEGACY_REGION_DESCRIPTOR  **Descriptor
+  )
+{
+
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Entry point to the DXE Driver that produces the Legacy Region Protocol.
+
+  @retval  EFI_SUCCESS One or more of the drivers returned a success code.
+  @retval  !EFI_SUCESS The return status from the last driver entry point in the list.
+
+**/
+EFI_STATUS
+LegacyRegionInit (
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // Install the Legacy Region Protocol on a new handle
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mLegacyRegion2Handle,
+                  &gEfiLegacyRegion2ProtocolGuid, &mLegacyRegion2,
+                  NULL
+                  );
+
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.h
new file mode 100644
index 0000000000..8afe23f02f
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.h
@@ -0,0 +1,198 @@
+/** @file
+The header file legacy region initialization in QNC DXE component.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _LEGACY_REGION_H_
+#define _LEGACY_REGION_H_
+#include "CommonHeader.h"
+
+#include <IndustryStandard/Pci.h>
+
+#define LEGACY_REGION_INSTANCE_SIGNATURE   SIGNATURE_32('R','E','G','N')
+
+typedef struct {
+  UINT32                          Signature;
+
+  EFI_HANDLE                      Handle;
+  EFI_LEGACY_REGION2_PROTOCOL     LegacyRegion2;
+  EFI_HANDLE                      ImageHandle;
+
+  //
+  // Protocol for PAM register access
+  //
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *PciRootBridgeIo;
+} LEGACY_REGION_INSTANCE;
+
+#define LEGACY_REGION_INSTANCE_FROM_THIS(this) \
+  CR(this, LEGACY_REGION_INSTANCE, LegacyRegion2, LEGACY_REGION_INSTANCE_SIGNATURE)
+
+
+EFI_STATUS
+LegacyRegionManipluateRegion (
+  IN  LEGACY_REGION_INSTANCE    *Private
+  );
+
+EFI_STATUS
+LegacyRegionInit (
+  VOID
+  );
+
+/**
+  Modify the hardware to allow (decode) or disallow (not decode) memory reads in a region.
+
+  If the On parameter evaluates to TRUE, this function enables memory reads in the address range
+  Start to (Start + Length - 1).
+  If the On parameter evaluates to FALSE, this function disables memory reads in the address range
+  Start to (Start + Length - 1).
+
+  @param  This[in]              Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
+  @param  Start[in]             The beginning of the physical address of the region whose attributes
+                                should be modified.
+  @param  Length[in]            The number of bytes of memory whose attributes should be modified.
+                                The actual number of bytes modified may be greater than the number
+                                specified.
+  @param  Granularity[out]      The number of bytes in the last region affected. This may be less
+                                than the total number of bytes affected if the starting address
+                                was not aligned to a region's starting address or if the length
+                                was greater than the number of bytes in the first region.
+  @param  On[in]                Decode / Non-Decode flag.
+
+  @retval EFI_SUCCESS           The region's attributes were successfully modified.
+  @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacyRegion2Decode (
+  IN  EFI_LEGACY_REGION2_PROTOCOL  *This,
+  IN  UINT32                       Start,
+  IN  UINT32                       Length,
+  OUT UINT32                       *Granularity,
+  IN  BOOLEAN                      *On
+  );
+
+/**
+  Modify the hardware to disallow memory writes in a region.
+
+  This function changes the attributes of a memory range to not allow writes.
+
+  @param  This[in]              Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
+  @param  Start[in]             The beginning of the physical address of the region whose
+                                attributes should be modified.
+  @param  Length[in]            The number of bytes of memory whose attributes should be modified.
+                                The actual number of bytes modified may be greater than the number
+                                specified.
+  @param  Granularity[out]      The number of bytes in the last region affected. This may be less
+                                than the total number of bytes affected if the starting address was
+                                not aligned to a region's starting address or if the length was
+                                greater than the number of bytes in the first region.
+
+  @retval EFI_SUCCESS           The region's attributes were successfully modified.
+  @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacyRegion2Lock (
+  IN  EFI_LEGACY_REGION2_PROTOCOL *This,
+  IN  UINT32                      Start,
+  IN  UINT32                      Length,
+  OUT UINT32                      *Granularity
+  );
+
+/**
+  Modify the hardware to disallow memory attribute changes in a region.
+
+  This function makes the attributes of a region read only. Once a region is boot-locked with this
+  function, the read and write attributes of that region cannot be changed until a power cycle has
+  reset the boot-lock attribute. Calls to Decode(), Lock() and Unlock() will have no effect.
+
+  @param  This[in]              Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
+  @param  Start[in]             The beginning of the physical address of the region whose
+                                attributes should be modified.
+  @param  Length[in]            The number of bytes of memory whose attributes should be modified.
+                                The actual number of bytes modified may be greater than the number
+                                specified.
+  @param  Granularity[out]      The number of bytes in the last region affected. This may be less
+                                than the total number of bytes affected if the starting address was
+                                not aligned to a region's starting address or if the length was
+                                greater than the number of bytes in the first region.
+
+  @retval EFI_SUCCESS           The region's attributes were successfully modified.
+  @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
+  @retval EFI_UNSUPPORTED       The chipset does not support locking the configuration registers in
+                                a way that will not affect memory regions outside the legacy memory
+                                region.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacyRegion2BootLock (
+  IN EFI_LEGACY_REGION2_PROTOCOL          *This,
+  IN  UINT32                              Start,
+  IN  UINT32                              Length,
+  OUT UINT32                              *Granularity
+  );
+
+/**
+  Modify the hardware to allow memory writes in a region.
+
+  This function changes the attributes of a memory range to allow writes.
+
+  @param  This[in]              Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
+  @param  Start[in]             The beginning of the physical address of the region whose
+                                attributes should be modified.
+  @param  Length[in]            The number of bytes of memory whose attributes should be modified.
+                                The actual number of bytes modified may be greater than the number
+                                specified.
+  @param  Granularity[out]      The number of bytes in the last region affected. This may be less
+                                than the total number of bytes affected if the starting address was
+                                not aligned to a region's starting address or if the length was
+                                greater than the number of bytes in the first region.
+
+  @retval EFI_SUCCESS           The region's attributes were successfully modified.
+  @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacyRegion2Unlock (
+  IN  EFI_LEGACY_REGION2_PROTOCOL  *This,
+  IN  UINT32                       Start,
+  IN  UINT32                       Length,
+  OUT UINT32                       *Granularity
+  );
+
+/**
+  Get region information for the attributes of the Legacy Region.
+
+  This function is used to discover the granularity of the attributes for the memory in the legacy
+  region. Each attribute may have a different granularity and the granularity may not be the same
+  for all memory ranges in the legacy region.
+
+  @param  This[in]              Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
+  @param  DescriptorCount[out]  The number of region descriptor entries returned in the Descriptor
+                                buffer.
+  @param  Descriptor[out]       A pointer to a pointer used to return a buffer where the legacy
+                                region information is deposited. This buffer will contain a list of
+                                DescriptorCount number of region descriptors.  This function will
+                                provide the memory for the buffer.
+
+  @retval EFI_SUCCESS           The region's attributes were successfully modified.
+  @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacyRegionGetInfo (
+  IN  EFI_LEGACY_REGION2_PROTOCOL   *This,
+  OUT UINT32                        *DescriptorCount,
+  OUT EFI_LEGACY_REGION_DESCRIPTOR  **Descriptor
+  );
+
+#endif //_QNC_LEGACY_REGION_H_
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.c
new file mode 100644
index 0000000000..b0751a6362
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.c
@@ -0,0 +1,518 @@
+/** @file
+QuarkNcSocId module initialization module
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "CommonHeader.h"
+
+#include "LegacyRegion.h"
+#include "DxeQNCSmbus.h"
+
+#include "QNCInit.h"
+
+//
+// Definitions
+//
+#define QNC_RESERVED_ITEM_IO         0
+#define QNC_RESERVED_ITEM_MEMORYIO   1
+#define DXE_DEVICE_DISABLED 0
+#define DXE_DEVICE_ENABLED 1
+
+typedef struct _QNC_SPACE_TABLE_ITEM {
+   UINTN                   IoOrMemory;
+   UINTN                   Type;
+   EFI_PHYSICAL_ADDRESS    BaseAddress;
+   UINT64                  Length;
+   UINTN                   Alignment;
+   BOOLEAN                 RuntimeOrNot;
+} QNC_SPACE_TABLE_ITEM;
+
+typedef struct {
+  ACPI_CPU_DATA       AcpuCpuData;
+  MTRR_SETTINGS       MtrrTable;
+  IA32_DESCRIPTOR     GdtrProfile;
+  IA32_DESCRIPTOR     IdtrProfile;
+  CPU_REGISTER_TABLE  RegisterTable;
+  CPU_REGISTER_TABLE  PreSmmInitRegisterTable;
+} ACPI_CPU_DATA_EX;
+
+//
+// Spaces to be reserved in GCD
+// Expand it to add more
+//
+const QNC_SPACE_TABLE_ITEM  mQNCReservedSpaceTable[] = {
+  {
+    QNC_RESERVED_ITEM_MEMORYIO,
+    EfiGcdMemoryTypeMemoryMappedIo,
+    FixedPcdGet64 (PcdIoApicBaseAddress),
+    FixedPcdGet64 (PcdIoApicSize),
+    0,
+    FALSE
+  },
+  {
+    QNC_RESERVED_ITEM_MEMORYIO,
+    EfiGcdMemoryTypeMemoryMappedIo,
+    FixedPcdGet64 (PcdHpetBaseAddress),
+    FixedPcdGet64 (PcdHpetSize),
+    0,
+    FALSE
+  }
+};
+
+//
+// Global variable for ImageHandle of QNCInit driver
+//
+EFI_HANDLE gQNCInitImageHandle;
+QNC_DEVICE_ENABLES    mQNCDeviceEnables;
+
+
+VOID
+QNCInitializeResource (
+  VOID
+  );
+
+EFI_STATUS
+InitializeQNCPolicy (
+  VOID
+  );
+
+/**
+  Allocate EfiACPIMemoryNVS below 4G memory address.
+
+  This function allocates EfiACPIMemoryNVS below 4G memory address.
+
+  @param Size   Size of memory to allocate.
+
+  @return       Allocated address for output.
+
+**/
+VOID *
+AllocateAcpiNvsMemoryBelow4G (
+  IN UINTN  Size
+  )
+{
+  UINTN                 Pages;
+  EFI_PHYSICAL_ADDRESS  Address;
+  EFI_STATUS            Status;
+  VOID*                 Buffer;
+
+  Pages = EFI_SIZE_TO_PAGES (Size);
+  Address = 0xffffffff;
+
+  Status  = gBS->AllocatePages (
+                   AllocateMaxAddress,
+                   EfiACPIMemoryNVS,
+                   Pages,
+                   &Address
+                   );
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+
+  Buffer = (VOID *) (UINTN) Address;
+  ZeroMem (Buffer, Size);
+
+  return Buffer;
+}
+
+/**
+  Prepare ACPI NVS memory below 4G memory for use of S3 resume.
+
+  This function allocates ACPI NVS memory below 4G memory for use of S3 resume,
+  and saves data into the memory region.
+
+**/
+VOID
+SaveCpuS3Data (
+  VOID
+  )
+{
+  EFI_STATUS        Status;
+  ACPI_CPU_DATA_EX  *AcpiCpuDataEx;
+  ACPI_CPU_DATA     *AcpiCpuData;
+  UINTN             GdtSize;
+  UINTN             IdtSize;
+  VOID              *Gdt;
+  VOID              *Idt;
+
+  //
+  // Allocate ACPI NVS memory below 4G memory for use of S3 resume.
+  //
+  AcpiCpuDataEx = AllocateAcpiNvsMemoryBelow4G (sizeof (ACPI_CPU_DATA_EX));
+  AcpiCpuData = &AcpiCpuDataEx->AcpuCpuData;
+
+  //
+  //
+  //
+  AcpiCpuData->NumberOfCpus              = 1;
+  AcpiCpuData->StackSize                 = PcdGet32 (PcdCpuApStackSize);
+  AcpiCpuData->ApMachineCheckHandlerBase = 0;
+  AcpiCpuData->ApMachineCheckHandlerSize = 0;
+  AcpiCpuData->GdtrProfile               = (EFI_PHYSICAL_ADDRESS) (UINTN) &AcpiCpuDataEx->GdtrProfile;
+  AcpiCpuData->IdtrProfile               = (EFI_PHYSICAL_ADDRESS) (UINTN) &AcpiCpuDataEx->IdtrProfile;
+  AcpiCpuData->MtrrTable                 = (EFI_PHYSICAL_ADDRESS) (UINTN) &AcpiCpuDataEx->MtrrTable;
+  AcpiCpuData->RegisterTable             = (EFI_PHYSICAL_ADDRESS) (UINTN) &AcpiCpuDataEx->RegisterTable;
+  AcpiCpuData->PreSmmInitRegisterTable   = (EFI_PHYSICAL_ADDRESS) (UINTN) &AcpiCpuDataEx->PreSmmInitRegisterTable;
+
+  //
+  // Allocate stack space for all CPUs
+  //
+  AcpiCpuData->StackAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) AllocateAcpiNvsMemoryBelow4G (AcpiCpuData->NumberOfCpus * AcpiCpuData->StackSize);
+
+  //
+  // Get MTRR settings from currently executing CPU
+  //
+  MtrrGetAllMtrrs (&AcpiCpuDataEx->MtrrTable);
+
+  //
+  // Get the BSP's data of GDT and IDT
+  //
+  AsmReadGdtr ((IA32_DESCRIPTOR *) &AcpiCpuDataEx->GdtrProfile);
+  AsmReadIdtr ((IA32_DESCRIPTOR *) &AcpiCpuDataEx->IdtrProfile);
+
+  //
+  // Allocate GDT and IDT in ACPI NVS and copy in current GDT and IDT contents
+  //
+  GdtSize = AcpiCpuDataEx->GdtrProfile.Limit + 1;
+  IdtSize = AcpiCpuDataEx->IdtrProfile.Limit + 1;
+  Gdt = AllocateAcpiNvsMemoryBelow4G (GdtSize + IdtSize);
+  Idt = (VOID *)((UINTN)Gdt + GdtSize);
+  CopyMem (Gdt, (VOID *)AcpiCpuDataEx->GdtrProfile.Base, GdtSize);
+  CopyMem (Idt, (VOID *)AcpiCpuDataEx->IdtrProfile.Base, IdtSize);
+  AcpiCpuDataEx->GdtrProfile.Base = (UINTN)Gdt;
+  AcpiCpuDataEx->IdtrProfile.Base = (UINTN)Idt;
+
+  //
+  // No RegisterTable entries
+  //
+  AcpiCpuDataEx->RegisterTable.TableLength = 0;
+
+  //
+  // No PreSmmInitRegisterTable entries
+  //
+  AcpiCpuDataEx->PreSmmInitRegisterTable.TableLength = 0;
+
+  //
+  // Set the base address of CPU S3 data to PcdCpuS3DataAddress
+  //
+  Status = PcdSet64S (PcdCpuS3DataAddress, (UINT64)(UINTN)AcpiCpuData);
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+   The entry function for QNCInit driver.
+
+   This function just call initialization function for PciHostBridge,
+   LegacyRegion and QNCSmmAccess module.
+
+   @param ImageHandle   The driver image handle for GmchInit driver
+   @param SystemTable   The pointer to System Table
+
+   @retval EFI_SUCCESS  Success to initialize every module for GMCH driver.
+   @return EFI_STATUS   The status of initialization work.
+
+**/
+EFI_STATUS
+EFIAPI
+QNCInit (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  S3BootScriptSaveInformationAsciiString (
+    "QNCInitDxeEntryBegin"
+    );
+
+  gQNCInitImageHandle = ImageHandle;
+
+  mQNCDeviceEnables.Uint32 = PcdGet32 (PcdDeviceEnables);
+
+
+  //
+  // Initialize PCIE root ports
+  //
+  Status = QncInitRootPorts ();
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "QNC Root Port initialization is failed!\n"));
+    return Status;
+  }
+
+  Status = LegacyRegionInit ();
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "QNC LegacyRegion initialization is failed!\n"));
+    return Status;
+  }
+
+
+  Status = InitializeQNCPolicy ();
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "QNC Policy initialization is failed!\n"));
+    return Status;
+  }
+
+  Status = InitializeQNCSmbus (ImageHandle,SystemTable);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "QNC Smbus driver is failed!\n"));
+    return Status;
+  }
+
+  QNCInitializeResource ();
+
+  SaveCpuS3Data ();
+
+  S3BootScriptSaveInformationAsciiString (
+    "QNCInitDxeEntryEnd"
+    );
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Reserve I/O or memory space in GCD
+
+  @param  IoOrMemory    Switch of I/O or memory.
+  @param  GcdType       Type of the space.
+  @param  BaseAddress   Base address of the space.
+  @param  Length        Length of the space.
+  @param  Alignment     Align with 2^Alignment
+  @param  RuntimeOrNot  For runtime usage or not
+  @param  ImageHandle   Handle for the image of this driver.
+
+  @retval EFI_SUCCESS   Reserve successful
+**/
+EFI_STATUS
+QNCReserveSpaceInGcd(
+  IN UINTN                 IoOrMemory,
+  IN UINTN                 GcdType,
+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,
+  IN UINT64                Length,
+  IN UINTN                 Alignment,
+  IN BOOLEAN               RuntimeOrNot,
+  IN EFI_HANDLE            ImageHandle
+  )
+{
+  EFI_STATUS               Status;
+
+  if (IoOrMemory == QNC_RESERVED_ITEM_MEMORYIO) {
+    Status = gDS->AddMemorySpace (
+                    GcdType,
+                    BaseAddress,
+                    Length,
+                    EFI_MEMORY_UC
+                    );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((
+        EFI_D_ERROR,
+        "Failed to add memory space :0x%x 0x%x\n",
+        BaseAddress,
+        Length
+        ));
+    }
+    ASSERT_EFI_ERROR (Status);
+    Status = gDS->AllocateMemorySpace (
+                    EfiGcdAllocateAddress,
+                    GcdType,
+                    Alignment,
+                    Length,
+                    &BaseAddress,
+                    ImageHandle,
+                    NULL
+                    );
+    ASSERT_EFI_ERROR (Status);
+    if (RuntimeOrNot) {
+      Status = gDS->SetMemorySpaceAttributes (
+                      BaseAddress,
+                      Length,
+                      EFI_MEMORY_RUNTIME | EFI_MEMORY_UC
+                     );
+      ASSERT_EFI_ERROR (Status);
+    }
+  } else {
+    Status = gDS->AddIoSpace (
+                    GcdType,
+                    BaseAddress,
+                    Length
+                    );
+    ASSERT_EFI_ERROR (Status);
+    Status = gDS->AllocateIoSpace (
+                    EfiGcdAllocateAddress,
+                    GcdType,
+                    Alignment,
+                    Length,
+                    &BaseAddress,
+                    ImageHandle,
+                    NULL
+                    );
+    ASSERT_EFI_ERROR (Status);
+  }
+  return Status;
+}
+
+
+/**
+  Initialize the memory and io resource which belong to QNC.
+  1) Report and allocate all BAR's memory to GCD.
+  2) Report PCI memory and I/O space to GCD.
+  3) Set memory attribute for <1M memory space.
+**/
+VOID
+QNCInitializeResource (
+  )
+{
+  EFI_PHYSICAL_ADDRESS            BaseAddress;
+  EFI_STATUS                      Status;
+  UINT64                          ExtraRegionLength;
+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
+  UINTN                           Index;
+
+  // Report TSEG range
+  // This range maybe has been reportted in PEI phase via Resource Hob.
+  //
+  QNCGetTSEGMemoryRange (&BaseAddress, &ExtraRegionLength);
+  if (ExtraRegionLength != 0) {
+    Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &Descriptor);
+    if (Status == EFI_NOT_FOUND) {
+      Status = gDS->AddMemorySpace (
+                      EfiGcdMemoryTypeReserved,
+                      BaseAddress,
+                      ExtraRegionLength,
+                      EFI_MEMORY_UC
+                      );
+    }
+  }
+
+  //
+  // < 1M resource setting. The memory ranges <1M has been added into GCD via
+  // resource hob produced by PEI phase. Here will set memory attribute of these
+  // ranges for DXE phase.
+  //
+
+  //
+  // Dos Area (0 ~ 0x9FFFFh)
+  //
+  Status = gDS->GetMemorySpaceDescriptor (0, &Descriptor);
+  DEBUG ((
+    EFI_D_INFO,
+    "DOS Area Memory: base = 0x%x, length = 0x%x, attribute = 0x%x\n",
+    Descriptor.BaseAddress,
+    Descriptor.Length,
+    Descriptor.Attributes
+    ));
+  ASSERT_EFI_ERROR (Status);
+  Status = gDS->SetMemorySpaceAttributes(
+                  0,
+                  0xA0000,
+                  EFI_MEMORY_WB
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Default SMRAM UnCachable until SMBASE relocated.
+  //
+  Status = gDS->SetMemorySpaceAttributes(
+                  0x30000,
+                  0x10000,
+                  EFI_MEMORY_UC
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Default SMM ABSEG area. (0xA0000 ~ 0xBFFFF)
+  //
+  Status = gDS->GetMemorySpaceDescriptor (0xA0000, &Descriptor);
+  DEBUG ((
+    EFI_D_INFO,
+    "ABSEG Memory: base = 0x%x, length = 0x%x, attribute = 0x%x\n",
+    Descriptor.BaseAddress,
+    Descriptor.Length,
+    Descriptor.Attributes
+    ));
+  ASSERT_EFI_ERROR (Status);
+  Status = gDS->SetMemorySpaceAttributes(
+                  0xA0000,
+                  0x20000,
+                  EFI_MEMORY_UC
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Expansion BIOS area.
+  //
+  Status = gDS->GetMemorySpaceDescriptor (0xC0000, &Descriptor);
+  DEBUG ((
+    EFI_D_INFO,
+    "Memory base = 0x%x, length = 0x%x, attribute = 0x%x\n",
+    Descriptor.BaseAddress,
+    Descriptor.Length,
+    Descriptor.Attributes
+    ));
+  ASSERT_EFI_ERROR (Status);
+  Status = gDS->SetMemorySpaceAttributes(
+                  0xC0000,
+                  0x30000,
+                  EFI_MEMORY_UC
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Report other IO resources from mQNCReservedSpaceTable in GCD
+  //
+  for (Index = 0; Index < sizeof (mQNCReservedSpaceTable) / sizeof (QNC_SPACE_TABLE_ITEM); Index++) {
+    Status = QNCReserveSpaceInGcd (
+               mQNCReservedSpaceTable[Index].IoOrMemory,
+               mQNCReservedSpaceTable[Index].Type,
+               mQNCReservedSpaceTable[Index].BaseAddress,
+               mQNCReservedSpaceTable[Index].Length,
+               mQNCReservedSpaceTable[Index].Alignment,
+               mQNCReservedSpaceTable[Index].RuntimeOrNot,
+               gQNCInitImageHandle
+               );
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  //
+  // Report unused PCIe config space as reserved.
+  //
+  if (PcdGet64 (PcdPciExpressSize) < SIZE_256MB) {
+    Status = QNCReserveSpaceInGcd (
+               QNC_RESERVED_ITEM_MEMORYIO,
+               EfiGcdMemoryTypeMemoryMappedIo,
+               (PcdGet64(PcdPciExpressBaseAddress) + PcdGet64(PcdPciExpressSize)),
+               (SIZE_256MB - PcdGet64(PcdPciExpressSize)),
+               0,
+               FALSE,
+               gQNCInitImageHandle
+               );
+    ASSERT_EFI_ERROR (Status);
+  }
+}
+
+/**
+  Use the platform PCD to initialize devices in the QNC
+
+  @param  ImageHandle   Handle for the image of this driver.
+  @retval EFI_SUCCESS   Initialize successful
+**/
+EFI_STATUS
+InitializeQNCPolicy (
+  )
+{
+  UINT32       PciD31F0RegBase;  // LPC
+
+  PciD31F0RegBase = PciDeviceMmBase (PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, PCI_FUNCTION_NUMBER_QNC_LPC);
+
+  //
+  // Disable for smbus
+  //
+  if (mQNCDeviceEnables.Bits.Smbus == DXE_DEVICE_DISABLED) {
+    S3MmioAnd32 (PciD31F0RegBase + R_QNC_LPC_SMBUS_BASE, (~B_QNC_LPC_SMBUS_BASE_EN));
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.h
new file mode 100644
index 0000000000..c5d1ffad40
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.h
@@ -0,0 +1,49 @@
+/** @file
+Header file for QNC Initialization Driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+#ifndef _QNC_INITIALIZATION_DRIVER_H_
+#define _QNC_INITIALIZATION_DRIVER_H_
+
+EFI_STATUS
+QncInitRootPorts (
+  )
+/*++
+
+Routine Description:
+
+  Perform Initialization of the Downstream Root Ports.
+
+Arguments:
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+;
+
+EFI_STATUS
+SetInitRootPortDownstreamS3Item (
+  )
+/*++
+
+Routine Description:
+
+  Set an Init Root Port Downstream devices S3 dispatch item, this function may assert if any error happend
+
+Arguments:
+
+Returns:
+
+  EFI_SUCCESS             The function completed successfully
+
+--*/
+;
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInitDxe.inf b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInitDxe.inf
new file mode 100644
index 0000000000..b250602cf4
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInitDxe.inf
@@ -0,0 +1,92 @@
+## @file
+# Component description file for QNCInit driver.
+#
+# QNCInit driver implement QuarkNcSocId related drivers, includes:
+# PciHostBridge, PciExpress, SmmAccess driver and LegacyRegion driver.
+#
+# This driver mainly do full initialization for the QNC chipet includes:
+# 1. Initialize the PCI Express device.
+# 2. Initialize the PciHostBridge, and allocate the I/O and memory space from GCD service.
+# 3. Initialize the SmmAccess module and install EFI_SMM_ACCESS_PROTOCOL
+# 4. Initialize the LegacyRegion module, install EFI_LEGACY_REGION_PROTOCOL and set below 1M
+#    memory attribute from MTRR.
+#
+# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = QNCInitDxe
+  FILE_GUID                      = 74D3B506-EE9C-47ed-B749-41261401DA78
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = QNCInit
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  LegacyRegion.h
+  LegacyRegion.c
+  DxeQNCSmbus.c
+  DxeQNCSmbus.h
+  QNCSmbusExec.c
+  QNCSmbus.h
+  QNCInit.c
+  QNCInit.h
+  CommonHeader.h
+  QNCRootPorts.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  BaseLib
+  UefiBootServicesTableLib
+  DxeServicesTableLib
+  BaseMemoryLib
+  DebugLib
+  PcdLib
+  MtrrLib
+  IoLib
+  SmbusLib
+  S3IoLib
+  S3BootScriptLib
+  IntelQNCLib
+  QNCAccessLib
+
+[Protocols]
+  gEfiLegacyRegion2ProtocolGuid                 # PROTOCOL ALWAYS_PRODUCED
+  gEfiSmbusHcProtocolGuid                       # PROTOCOL ALWAYS_PRODUCED
+  gEfiQncS3SupportProtocolGuid                  # PROTOCOL ALWAYS_CONSUMED
+
+[FeaturePcd]
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdSmbaIoBaseAddressFixed
+
+[FixedPcd]
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdIoApicBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdIoApicSize
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdHpetBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdHpetSize
+
+[Pcd]
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize                           ## CONSUMES
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuS3DataAddress|0x0|UINT64|0x60000010   ## PRODUCES
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress                     ## CONSUMES
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciExpressSize                      ## CONSUMES
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdSmbaIoBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdDeviceEnables
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPlatformSmbusAddrNum
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPlatformSmbusAddrTable
+
+[Depex]
+  gEfiPlatformPolicyProtocolGuid AND gEfiQncS3SupportProtocolGuid
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCRootPorts.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCRootPorts.c
new file mode 100644
index 0000000000..7c3f18efc7
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCRootPorts.c
@@ -0,0 +1,76 @@
+/** @file
+PciHostBridge driver module, part of QNC module.
+
+Provides the basic interfaces to abstract a PCI Host Bridge Resource Allocation.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "CommonHeader.h"
+#include "QNCInit.h"
+
+UINT32  mS3ParameterRootPortDownstream = 0;
+EFI_QNC_S3_DISPATCH_ITEM  mS3DispatchItem = {
+    QncS3ItemTypeInitPcieRootPortDownstream,
+    &mS3ParameterRootPortDownstream
+  };
+
+EFI_STATUS
+QncInitRootPorts (
+  )
+/*++
+
+Routine Description:
+
+  Perform Initialization of the Downstream Root Ports
+
+Arguments:
+
+Returns:
+
+  EFI_SUCCESS             The function completed successfully
+
+--*/
+{
+  EFI_STATUS                   Status;
+  EFI_QNC_S3_SUPPORT_PROTOCOL  *QncS3Support;
+  VOID                         *Context;
+  VOID                         *S3DispatchEntryPoint;
+
+  Status = PciExpressInit ();
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Get the QNC S3 Support Protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiQncS3SupportProtocolGuid,
+                  NULL,
+                  (VOID **) &QncS3Support
+                  );
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Get the QNC S3 Support Protocol
+  //
+  Status = QncS3Support->SetDispatchItem (
+                          QncS3Support,
+                          &mS3DispatchItem,
+                          &S3DispatchEntryPoint,
+                          &Context
+                          );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Save the script dispatch item in the Boot Script
+  //
+  Status = S3BootScriptSaveDispatch2 (S3DispatchEntryPoint, Context);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbus.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbus.h
new file mode 100644
index 0000000000..fbd1859dea
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbus.h
@@ -0,0 +1,80 @@
+/** @file
+Common definitons for SMBus PEIM/DXE driver. Smbus PEI and DXE
+modules share the same version of this file.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _QNC_SMBUS_H_
+#define _QNC_SMBUS_H_
+
+#include "CommonHeader.h"
+
+//
+// Minimum and maximum length for SMBus bus block protocols defined in SMBus spec 2.0.
+//
+#define MIN_SMBUS_BLOCK_LEN               1
+#define MAX_SMBUS_BLOCK_LEN               32
+#define ADD_LENGTH(SmbusAddress, Length)  ((SmbusAddress) + SMBUS_LIB_ADDRESS (0, 0, (Length), FALSE))
+
+/**
+  Executes an SMBus operation to an SMBus controller. Returns when either the command has been
+  executed or an error is encountered in doing the operation.
+
+  The internal worker function provides a standard way to execute an operation as defined in the
+  System Management Bus (SMBus) Specification. The resulting transaction will be either that the
+  SMBus slave devices accept this transaction or that this function returns with error.
+
+  @param  SlaveAddress            The SMBus slave address of the device with which to communicate.
+  @param  Command                 This command is transmitted by the SMBus host controller to the
+                                  SMBus slave device and the interpretation is SMBus slave device
+                                  specific. It can mean the offset to a list of functions inside an
+                                  SMBus slave device. Not all operations or slave devices support
+                                  this command's registers.
+  @param  Operation               Signifies which particular SMBus hardware protocol instance that
+                                  it will use to execute the SMBus transactions. This SMBus
+                                  hardware protocol is defined by the SMBus Specification and is
+                                  not related to EFI.
+  @param  PecCheck                Defines if Packet Error Code (PEC) checking is required for this
+                                  operation.
+  @param  Length                  Signifies the number of bytes that this operation will do. The
+                                  maximum number of bytes can be revision specific and operation
+                                  specific. This field will contain the actual number of bytes that
+                                  are executed for this operation. Not all operations require this
+                                  argument.
+  @param  Buffer                  Contains the value of data to execute to the SMBus slave device.
+                                  Not all operations require this argument. The length of this
+                                  buffer is identified by Length.
+
+  @retval EFI_SUCCESS             The last data that was returned from the access matched the poll
+                                  exit criteria.
+  @retval EFI_CRC_ERROR           Checksum is not correct (PEC is incorrect).
+  @retval EFI_TIMEOUT             Timeout expired before the operation was completed. Timeout is
+                                  determined by the SMBus host controller device.
+  @retval EFI_OUT_OF_RESOURCES    The request could not be completed due to a lack of resources.
+  @retval EFI_DEVICE_ERROR        The request was not completed because a failure that was
+                                  reflected in the Host Status Register bit. Device errors are a
+                                  result of a transaction collision, illegal command field,
+                                  unclaimed cycle (host initiated), or bus errors (collisions).
+  @retval EFI_INVALID_PARAMETER   Operation is not defined in EFI_SMBUS_OPERATION.
+  @retval EFI_INVALID_PARAMETER   Length/Buffer is NULL for operations except for EfiSmbusQuickRead
+                                  and EfiSmbusQuickWrite. Length is outside the range of valid
+                                  values.
+  @retval EFI_UNSUPPORTED         The SMBus operation or PEC is not supported.
+  @retval EFI_BUFFER_TOO_SMALL    Buffer is not sufficient for this operation.
+
+**/
+EFI_STATUS
+Execute (
+  IN     EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+  IN     EFI_SMBUS_DEVICE_COMMAND Command,
+  IN     EFI_SMBUS_OPERATION      Operation,
+  IN     BOOLEAN                  PecCheck,
+  IN OUT UINTN                    *Length,
+  IN OUT VOID                     *Buffer
+  );
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbusExec.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbusExec.c
new file mode 100644
index 0000000000..dbd3566496
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbusExec.c
@@ -0,0 +1,246 @@
+/** @file
+Common code to implement SMBus bus protocols. Smbus PEI and DXE modules
+share the same version of this file.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "CommonHeader.h"
+
+#include "QNCSmbus.h"
+
+/**
+  Checks the parameter of SmbusExecute().
+
+  This function checks the input parameters of SmbusExecute().  If the input parameters are valid
+  for certain SMBus bus protocol, it will return EFI_SUCCESS; otherwise, it will return certain
+  error code based on the input SMBus bus protocol.
+
+  @param  SlaveAddress            The SMBus slave address of the device with which to communicate.
+  @param  Command                 This command is transmitted by the SMBus host controller to the
+                                  SMBus slave device and the interpretation is SMBus slave device
+                                  specific. It can mean the offset to a list of functions inside an
+                                  SMBus slave device. Not all operations or slave devices support
+                                  this command's registers.
+  @param  Operation               Signifies which particular SMBus hardware protocol instance that
+                                  it will use to execute the SMBus transactions. This SMBus
+                                  hardware protocol is defined by the SMBus Specification and is
+                                  not related to EFI.
+  @param  PecCheck                Defines if Packet Error Code (PEC) checking is required for this
+                                  operation.
+  @param  Length                  Signifies the number of bytes that this operation will do. The
+                                  maximum number of bytes can be revision specific and operation
+                                  specific. This field will contain the actual number of bytes that
+                                  are executed for this operation. Not all operations require this
+                                  argument.
+  @param  Buffer                  Contains the value of data to execute to the SMBus slave device.
+                                  Not all operations require this argument. The length of this
+                                  buffer is identified by Length.
+
+  @retval EFI_SUCCESS             All the parameters are valid for the corresponding SMBus bus
+                                  protocol.
+  @retval EFI_INVALID_PARAMETER   Operation is not defined in EFI_SMBUS_OPERATION.
+  @retval EFI_INVALID_PARAMETER   Length/Buffer is NULL for operations except for EfiSmbusQuickRead
+                                  and EfiSmbusQuickWrite. Length is outside the range of valid
+                                  values.
+  @retval EFI_UNSUPPORTED         The SMBus operation or PEC is not supported.
+  @retval EFI_BUFFER_TOO_SMALL    Buffer is not sufficient for this operation.
+
+**/
+EFI_STATUS
+QncSmbusExecCheckParameters (
+  IN     EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+  IN     EFI_SMBUS_DEVICE_COMMAND Command,
+  IN     EFI_SMBUS_OPERATION      Operation,
+  IN     BOOLEAN                  PecCheck,
+  IN OUT UINTN                    *Length,
+  IN OUT VOID                     *Buffer
+  )
+{
+  EFI_STATUS  Status;
+  UINTN       RequiredLen;
+
+  //
+  // Set default value to be 2:
+  // for SmbusReadWord, SmbusWriteWord and SmbusProcessCall.
+  //
+  RequiredLen = 2;
+  Status      = EFI_SUCCESS;
+  switch (Operation) {
+  case EfiSmbusQuickRead:
+  case EfiSmbusQuickWrite:
+    if (PecCheck || Command != 0) {
+      return EFI_UNSUPPORTED;
+    }
+    break;
+  case EfiSmbusReceiveByte:
+  case EfiSmbusSendByte:
+    if (Command != 0) {
+      return EFI_UNSUPPORTED;
+    }
+    //
+    // Cascade to check length parameter.
+    //
+  case EfiSmbusReadByte:
+  case EfiSmbusWriteByte:
+    RequiredLen = 1;
+    //
+    // Cascade to check length parameter.
+    //
+  case EfiSmbusReadWord:
+  case EfiSmbusWriteWord:
+  case EfiSmbusProcessCall:
+    if (Buffer == NULL || Length == NULL) {
+      return EFI_INVALID_PARAMETER;
+    } else if (*Length < RequiredLen) {
+      Status = EFI_BUFFER_TOO_SMALL;
+    }
+    *Length = RequiredLen;
+    break;
+  case EfiSmbusReadBlock:
+  case EfiSmbusWriteBlock:
+    if ((Buffer == NULL) ||
+        (Length == NULL) ||
+        (*Length < MIN_SMBUS_BLOCK_LEN) ||
+        (*Length > MAX_SMBUS_BLOCK_LEN)) {
+      return EFI_INVALID_PARAMETER;
+    }
+    break;
+  case EfiSmbusBWBRProcessCall:
+    return EFI_UNSUPPORTED;
+  default:
+    return EFI_INVALID_PARAMETER;
+  }
+  return Status;
+}
+
+/**
+  Executes an SMBus operation to an SMBus controller. Returns when either the command has been
+  executed or an error is encountered in doing the operation.
+
+  The internal worker function provides a standard way to execute an operation as defined in the
+  System Management Bus (SMBus) Specification. The resulting transaction will be either that the
+  SMBus slave devices accept this transaction or that this function returns with error.
+
+  @param  SlaveAddress            The SMBus slave address of the device with which to communicate.
+  @param  Command                 This command is transmitted by the SMBus host controller to the
+                                  SMBus slave device and the interpretation is SMBus slave device
+                                  specific. It can mean the offset to a list of functions inside an
+                                  SMBus slave device. Not all operations or slave devices support
+                                  this command's registers.
+  @param  Operation               Signifies which particular SMBus hardware protocol instance that
+                                  it will use to execute the SMBus transactions. This SMBus
+                                  hardware protocol is defined by the SMBus Specification and is
+                                  not related to EFI.
+  @param  PecCheck                Defines if Packet Error Code (PEC) checking is required for this
+                                  operation.
+  @param  Length                  Signifies the number of bytes that this operation will do. The
+                                  maximum number of bytes can be revision specific and operation
+                                  specific. This field will contain the actual number of bytes that
+                                  are executed for this operation. Not all operations require this
+                                  argument.
+  @param  Buffer                  Contains the value of data to execute to the SMBus slave device.
+                                  Not all operations require this argument. The length of this
+                                  buffer is identified by Length.
+
+  @retval EFI_SUCCESS             The last data that was returned from the access matched the poll
+                                  exit criteria.
+  @retval EFI_CRC_ERROR           Checksum is not correct (PEC is incorrect).
+  @retval EFI_TIMEOUT             Timeout expired before the operation was completed. Timeout is
+                                  determined by the SMBus host controller device.
+  @retval EFI_OUT_OF_RESOURCES    The request could not be completed due to a lack of resources.
+  @retval EFI_DEVICE_ERROR        The request was not completed because a failure that was
+                                  reflected in the Host Status Register bit. Device errors are a
+                                  result of a transaction collision, illegal command field,
+                                  unclaimed cycle (host initiated), or bus errors (collisions).
+  @retval EFI_INVALID_PARAMETER   Operation is not defined in EFI_SMBUS_OPERATION.
+  @retval EFI_INVALID_PARAMETER   Length/Buffer is NULL for operations except for EfiSmbusQuickRead
+                                  and EfiSmbusQuickWrite. Length is outside the range of valid
+                                  values.
+  @retval EFI_UNSUPPORTED         The SMBus operation or PEC is not supported.
+  @retval EFI_BUFFER_TOO_SMALL    Buffer is not sufficient for this operation.
+
+**/
+EFI_STATUS
+Execute (
+  IN     EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+  IN     EFI_SMBUS_DEVICE_COMMAND Command,
+  IN     EFI_SMBUS_OPERATION      Operation,
+  IN     BOOLEAN                  PecCheck,
+  IN OUT UINTN                    *Length,
+  IN OUT VOID                     *Buffer
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           SmbusAddress;
+  UINTN                           WorkBufferLen;
+  UINT8                           WorkBuffer[MAX_SMBUS_BLOCK_LEN];
+
+  Status = QncSmbusExecCheckParameters (
+             SlaveAddress,
+             Command,
+             Operation,
+             PecCheck,
+             Length,
+             Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  SmbusAddress = SMBUS_LIB_ADDRESS (SlaveAddress.SmbusDeviceAddress, Command, *Length, PecCheck);
+
+  switch (Operation) {
+  case EfiSmbusQuickRead:
+    SmBusQuickRead (SmbusAddress, &Status);
+    break;
+  case EfiSmbusQuickWrite:
+    SmBusQuickWrite (SmbusAddress, &Status);
+    break;
+  case EfiSmbusReceiveByte:
+    *(UINT8 *) Buffer = SmBusReceiveByte (SmbusAddress, &Status);
+    break;
+  case EfiSmbusSendByte:
+    SmBusSendByte (SmbusAddress, *(UINT8 *) Buffer, &Status);
+    break;
+  case EfiSmbusReadByte:
+    *(UINT8 *) Buffer = SmBusReadDataByte (SmbusAddress, &Status);
+    break;
+  case EfiSmbusWriteByte:
+    SmBusWriteDataByte (SmbusAddress, *(UINT8 *) Buffer, &Status);
+    break;
+  case EfiSmbusReadWord:
+    *(UINT16 *) Buffer = SmBusReadDataWord (SmbusAddress, &Status);
+    break;
+  case EfiSmbusWriteWord:
+    SmBusWriteDataWord (SmbusAddress, *(UINT16 *) Buffer, &Status);
+    break;
+  case EfiSmbusProcessCall:
+    *(UINT16 *) Buffer = SmBusProcessCall (SmbusAddress, *(UINT16 *) Buffer, &Status);
+    break;
+  case EfiSmbusReadBlock:
+    WorkBufferLen = SmBusReadBlock (SmbusAddress, WorkBuffer, &Status);
+    if (!EFI_ERROR (Status)) {
+      //
+      // Read block transaction is complete successfully, and then
+      // check whether the output buffer is large enough.
+      //
+      if (*Length >= WorkBufferLen) {
+        CopyMem (Buffer, WorkBuffer, WorkBufferLen);
+      } else {
+        Status = EFI_BUFFER_TOO_SMALL;
+      }
+      *Length = WorkBufferLen;
+    }
+    break;
+  case EfiSmbusWriteBlock:
+    SmBusWriteBlock (ADD_LENGTH (SmbusAddress, *Length), Buffer, &Status);
+    break;
+  default:
+    break;
+  }
+
+  return Status;
+}
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.c
new file mode 100644
index 0000000000..a4617ccca2
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.c
@@ -0,0 +1,417 @@
+/** @file
+This is the driver that implements the QNC S3 Support protocol
+
+Copyright (c) 2013-2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "QncS3Support.h"
+
+//
+// Global Variables
+//
+EFI_QNC_S3_SUPPORT_PROTOCOL mQncS3SupportProtocol;
+QNC_S3_PARAMETER_HEADER     *mS3Parameter;
+UINT32                      mQncS3ImageEntryPoint;
+VOID                        *mQncS3ImageAddress;
+UINTN                       mQncS3ImageSize;
+
+extern EFI_GUID gQncS3CodeInLockBoxGuid;
+extern EFI_GUID gQncS3ContextInLockBoxGuid;
+
+/**
+
+    Create a buffer that is used to store context information for use with
+    dispatch functions.
+
+    @retval EFI_SUCCESS - Buffer allocated and initialized.
+
+**/
+EFI_STATUS
+CreateContextBuffer (
+  VOID
+  )
+{
+  EFI_STATUS            Status;
+  EFI_PHYSICAL_ADDRESS  Address;
+  UINT32                ContextStoreSize;
+
+  ContextStoreSize = EFI_PAGE_SIZE;
+
+  //
+  // Allcoate <4G EfiReservedMemory
+  //
+  Address = 0xFFFFFFFF;
+  Status = gBS->AllocatePages (AllocateMaxAddress, EfiReservedMemoryType, EFI_SIZE_TO_PAGES (ContextStoreSize), &Address);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  mS3Parameter  = (QNC_S3_PARAMETER_HEADER *) (UINTN) Address;
+
+  //
+  // Determine the maximum number of context entries that can be stored in this
+  // table.
+  //
+  mS3Parameter->MaxContexts = ((ContextStoreSize - sizeof(QNC_S3_PARAMETER_HEADER)) / sizeof(EFI_DISPATCH_CONTEXT_UNION)) + 1;
+  mS3Parameter->StorePosition = 0;
+
+  return Status;
+}
+
+//
+// Functions
+//
+EFI_STATUS
+EFIAPI
+QncS3SupportEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+/*++
+
+  Routine Description:
+
+    QNC S3 support driver entry point
+
+  Arguments:
+
+    ImageHandle     - Handle for the image of this driver
+    SystemTable     - Pointer to the EFI System Table
+
+  Returns:
+
+    EFI_STATUS
+
+--*/
+{
+  EFI_STATUS  Status;
+  VOID        *TmpPtr;
+  EFI_EVENT   Event;
+
+  //
+  // If the protocol is found execution is happening in ACPI NVS memory.  If it
+  // is not found copy the driver into ACPI NVS memory and pass control to it.
+  //
+  Status = gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, &TmpPtr);
+
+  //
+  // Load the QNC S3 image
+  //
+  if (EFI_ERROR (Status)) {
+    Status = LoadQncS3Image (SystemTable);
+    ASSERT_EFI_ERROR (Status);
+
+  } else {
+    DEBUG ((DEBUG_INFO, "QncS3SupportEntryPoint() in reserved memory - Begin\n"));
+    //
+    // Allocate and initialize context buffer.
+    //
+    Status = CreateContextBuffer ();
+
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    //
+    // Install the QNC S3 Support protocol
+    //
+    mQncS3SupportProtocol.SetDispatchItem = QncS3SetDispatchItem;
+    Status = gBS->InstallMultipleProtocolInterfaces (
+                    &ImageHandle,
+                    &gEfiQncS3SupportProtocolGuid,
+                    &mQncS3SupportProtocol,
+                    NULL
+                    );
+
+    mQncS3ImageAddress = (VOID *)(UINTN)PcdGet64(PcdQncS3CodeInLockBoxAddress);
+    mQncS3ImageSize    = (UINTN)PcdGet64(PcdQncS3CodeInLockBoxSize);
+    DEBUG ((DEBUG_INFO, "QncS3SupportEntry Code = %08x, Size = %08x\n", (UINTN)mQncS3ImageAddress, mQncS3ImageSize));
+    DEBUG ((DEBUG_INFO, "QncS3SupportEntry Contex = %08x, Size = %08x\n", (UINTN)mS3Parameter, EFI_PAGE_SIZE));
+    ASSERT (mQncS3ImageAddress != 0);
+
+    //
+    // Register EFI_END_OF_DXE_EVENT_GROUP_GUID event.
+    //
+    Status = gBS->CreateEventEx (
+                    EVT_NOTIFY_SIGNAL,
+                    TPL_CALLBACK,
+                    QncS3BootEvent,
+                    NULL,
+                    &gEfiEndOfDxeEventGroupGuid,
+                    &Event
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    DEBUG ((DEBUG_INFO, "QncS3SupportEntryPoint() in reserved memory - End\n"));
+  }
+
+
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+QncS3SetDispatchItem (
+  IN     EFI_QNC_S3_SUPPORT_PROTOCOL   *This,
+  IN     EFI_QNC_S3_DISPATCH_ITEM      *DispatchItem,
+  OUT  VOID                            **S3DispatchEntryPoint,
+  OUT  VOID                            **Context
+  )
+/*++
+
+Routine Description:
+
+  Set an item to be dispatched at S3 resume time. At the same time, the entry point
+  of the QNC S3 support image is returned to be used in subsequent boot script save
+  call
+
+Arguments:
+
+  This                    - Pointer to the protocol instance.
+  DispatchItem            - The item to be dispatched.
+  S3DispatchEntryPoint    - The entry point of the QNC S3 support image.
+
+Returns:
+
+  EFI_STATUS              - Successfully completed.
+  EFI_OUT_OF_RESOURCES    - Out of resources.
+
+--*/
+{
+
+  DEBUG ((DEBUG_INFO, "QncS3SetDispatchItem() Start\n"));
+
+  //
+  // Set default values.
+  //
+  *S3DispatchEntryPoint = NULL;
+  *Context = NULL;
+
+  //
+  // Determine if this entry will fit.
+  //
+  if (mS3Parameter->StorePosition >= mS3Parameter->MaxContexts) {
+    DEBUG ((DEBUG_INFO, "QncS3SetDispatchItem exceeds max length - 0x%08x\n", (UINTN)mS3Parameter->MaxContexts));
+    return EFI_OUT_OF_RESOURCES;
+  }
+  //
+  // Calculate the size required;
+  // ** Always round up to be 8 byte aligned
+  //
+  switch (DispatchItem->Type) {
+    case QncS3ItemTypeInitPcieRootPortDownstream:
+      *S3DispatchEntryPoint = (VOID*) (UINTN)QncS3InitPcieRootPortDownstream;
+      *Context = &mS3Parameter->Contexts[mS3Parameter->StorePosition];
+       CopyMem (&mS3Parameter->Contexts[mS3Parameter->StorePosition], DispatchItem->Parameter, sizeof(UINT32));
+      DEBUG ((DEBUG_INFO, "QncS3InitPcieRootPortDownstream @ 0x%08x - context  0x%08x\n", (UINTN)*S3DispatchEntryPoint, (UINTN)*Context));
+       break;
+
+    default:
+      return EFI_UNSUPPORTED;
+
+  }
+
+  mS3Parameter->StorePosition ++;
+  DEBUG ((DEBUG_INFO, "QncS3SetDispatchItem() End\n"));
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+LoadQncS3Image (
+  IN  EFI_SYSTEM_TABLE   *SystemTable
+  )
+/*++
+
+Routine Description:
+
+  Load the QNC S3 Image into Efi Reserved Memory below 4G.
+
+Arguments:
+
+  ImageEntryPoint     the ImageEntryPoint after success loading
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+{
+  EFI_STATUS                                    Status;
+  UINT8                                         *Buffer;
+  UINTN                                         BufferSize;
+  VOID                                          *FfsBuffer;
+  PE_COFF_LOADER_IMAGE_CONTEXT                  ImageContext;
+  EFI_HANDLE                                    NewImageHandle;
+
+  //
+  // Install NULL protocol on module file handle to indicate that the entry point
+  // has been called for the first time.
+  //
+  NewImageHandle = NULL;
+  Status = gBS->InstallProtocolInterface (
+    &NewImageHandle,
+    &gEfiCallerIdGuid,
+    EFI_NATIVE_INTERFACE,
+    NULL
+    );
+
+
+  //
+  // Find this module so it can be loaded again.
+  //
+  Status = GetSectionFromAnyFv  (
+             &gEfiCallerIdGuid,
+             EFI_SECTION_PE32,
+             0,
+             (VOID**) &Buffer,
+             &BufferSize
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+
+  //
+  // Get information about the image being loaded.
+  //
+  ImageContext.Handle = Buffer;
+  ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
+
+  //
+  // Get information about the image being loaded
+  //
+  Status = PeCoffLoaderGetImageInfo (&ImageContext);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = gBS->AllocatePool (
+                EfiReservedMemoryType,
+                BufferSize + ImageContext.SectionAlignment,
+                &FfsBuffer
+                );
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "LoadQncS3Image failed for no enough space! \n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  mQncS3ImageAddress = FfsBuffer;
+  mQncS3ImageSize    = BufferSize + ImageContext.SectionAlignment;
+  Status = PcdSet64S (PcdQncS3CodeInLockBoxAddress, (UINT64)(UINTN)mQncS3ImageAddress);
+  ASSERT_EFI_ERROR (Status);
+  Status = PcdSet64S (PcdQncS3CodeInLockBoxSize, (UINT64)mQncS3ImageSize);
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Align buffer on section boundary
+  //
+  ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer;
+  if (ImageContext.SectionAlignment != 0) {
+    ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
+    ImageContext.ImageAddress &= ~(ImageContext.SectionAlignment - 1);
+  }
+
+  //
+  // Load the image to our new buffer
+  //
+  Status = PeCoffLoaderLoadImage (&ImageContext);
+  if (EFI_ERROR (Status)) {
+    gBS->FreePool (FfsBuffer);
+    DEBUG ((DEBUG_INFO, "LoadQncS3Image failed for PeCoffLoaderLoadImage failure! \n"));
+    return Status;
+  }
+
+  //
+  // Relocate the image in our new buffer
+  //
+  Status = PeCoffLoaderRelocateImage (&ImageContext);
+  if (EFI_ERROR (Status)) {
+    PeCoffLoaderUnloadImage (&ImageContext);
+    gBS->FreePool (FfsBuffer);
+    DEBUG ((DEBUG_INFO, "LoadQncS3Image failed for PeCoffLoaderRelocateImage failure! \n"));
+    return Status;
+  }
+
+  //
+  // Invalidate instruction cache and pass control to the image.  This will perform
+  // the initialization of the module and publish the supporting protocols.
+  //
+  InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
+  Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint)) (NewImageHandle, SystemTable);
+  if (EFI_ERROR (Status)) {
+    gBS->FreePool (FfsBuffer);
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+
+}
+
+EFI_STATUS
+QncS3InitPcieRootPortDownstream (
+  IN EFI_HANDLE ImageHandle,
+  IN VOID       *Context
+  )
+/*++
+
+  Routine Description:
+    Perform Init Root Port Downstream devices on S3 resume
+
+  Arguments:
+    Parameter         Parameters passed in from DXE
+
+  Returns:
+    EFI_STATUS
+
+--*/
+{
+  EFI_STATUS  Status;
+
+  DEBUG ((DEBUG_INFO, "QncS3InitPcieRootPortDownstream() Begin\n"));
+
+  //
+  // Initialize the device behind the root port.
+  //
+  Status = PciExpressInit ();
+
+  //
+  // Not checking the error status here - downstream device not present does not
+  // mean an error of this root port. Our return status of EFI_SUCCESS means this
+  // port is enabled and outer function depends on this return status to do
+  // subsequent initializations.
+  //
+
+  if (Status != EFI_SUCCESS){
+    DEBUG ((DEBUG_INFO, "QncS3InitPcieRootPortDownstream() failed\n"));
+  }
+
+  DEBUG ((DEBUG_INFO, "QncS3InitPcieRootPortDownstream() End\n"));
+  return Status;
+}
+
+VOID
+EFIAPI
+QncS3BootEvent (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // These 2 boxes will be restored by RestoreAllLockBoxInPlace in S3Resume automatically
+  //
+  DEBUG ((DEBUG_INFO, "SaveLockBox QncS3Code = %08x, Size = %08x\n", (UINTN)mQncS3ImageAddress, mQncS3ImageSize));
+  SaveLockBox(&gQncS3CodeInLockBoxGuid, mQncS3ImageAddress, mQncS3ImageSize);
+  Status = SetLockBoxAttributes (&gQncS3CodeInLockBoxGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "SaveLockBox QncS3Context = %08x, Size = %08x\n", (UINTN)mS3Parameter, EFI_PAGE_SIZE));
+  SaveLockBox(&gQncS3ContextInLockBoxGuid, (VOID *)mS3Parameter, EFI_PAGE_SIZE);
+  Status = SetLockBoxAttributes (&gQncS3ContextInLockBoxGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
+  ASSERT_EFI_ERROR (Status);
+}
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.h
new file mode 100644
index 0000000000..a126e38b7f
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.h
@@ -0,0 +1,117 @@
+/** @file
+Header file for QNC S3 Support driver
+
+This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _QNC_S3_SUPPORT_H_
+#define _QNC_S3_SUPPORT_H_
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+//
+// Driver Consumed Protocol Prototypes
+//
+#include <Protocol/FirmwareVolume2.h>
+#include <Library/UefiLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeCoffLib.h>
+#include <Library/LockBoxLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+//
+// Driver Produced Protocol Prototypes
+//
+#include <Protocol/LoadedImage.h>
+#include <Protocol/QncS3Support.h>
+
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/IntelQNCLib.h>
+//
+// Define the header of the context region.
+//
+typedef struct {
+  UINT32                      MaxContexts;
+  UINT32                      StorePosition;
+  EFI_DISPATCH_CONTEXT_UNION  Contexts[1];
+} QNC_S3_PARAMETER_HEADER;
+//
+// Function prototypes
+//
+EFI_STATUS
+EFIAPI
+QncS3SetDispatchItem (
+  IN     EFI_QNC_S3_SUPPORT_PROTOCOL   *This,
+  IN     EFI_QNC_S3_DISPATCH_ITEM      *DispatchItem,
+  OUT    VOID                          **S3DispatchEntryPoint,
+  OUT    VOID                          **Context
+  )
+/*++
+
+Routine Description:
+
+  Set an item to be dispatched at S3 resume time. At the same time, the entry point
+  of the QNC S3 support image is returned to be used in subsequent boot script save
+  call
+
+Arguments:
+
+  This                    - Pointer to the protocol instance.
+  DispatchItem            - The item to be dispatched.
+  S3DispatchEntryPoint    - The entry point of the QNC S3 support image.
+
+Returns:
+
+  EFI_STATUS              - Successfully completed.
+  EFI_OUT_OF_RESOURCES    - Out of resources.
+
+--*/
+;
+
+EFI_STATUS
+LoadQncS3Image (
+  IN  EFI_SYSTEM_TABLE   *SystemTable
+  )
+/*++
+
+Routine Description:
+
+  Load the QNC S3 Image into Efi Reserved Memory below 4G.
+
+Arguments:
+
+  ImageEntryPoint     the ImageEntryPoint after success loading
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+;
+
+EFI_STATUS
+QncS3InitPcieRootPortDownstream (
+  IN EFI_HANDLE ImageHandle,
+  IN VOID       *Context
+  );
+
+VOID
+EFIAPI
+QncS3BootEvent (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  );
+
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.inf b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.inf
new file mode 100644
index 0000000000..0e12a2c594
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.inf
@@ -0,0 +1,64 @@
+## @file
+#    Component description file for Qnc Initialization driver
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = QncS3Support
+  FILE_GUID                      = C7EA9787-CA0A-43b4-B1E5-25EF87391F8D
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = QncS3SupportEntryPoint
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  QncS3Support.h
+  QncS3Support.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  IoLib
+  DebugLib
+  DxeServicesLib
+  BaseMemoryLib
+  UefiDriverEntryPoint
+  PeCoffLib
+  LockBoxLib
+  S3BootScriptLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  CacheMaintenanceLib
+  IntelQNCLib
+
+[Protocols]
+  gEfiQncS3SupportProtocolGuid     ## PRODUCES
+  gEfiLoadPeImageProtocolGuid      ## CONSUMES
+  gEfiFirmwareVolume2ProtocolGuid  ## CONSUMES
+
+[Guids]
+  gQncS3CodeInLockBoxGuid
+  gQncS3ContextInLockBoxGuid
+  gEfiEndOfDxeEventGroupGuid
+
+[Pcd]
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdQncS3CodeInLockBoxAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdQncS3CodeInLockBoxSize
+
+[Depex]
+  gEfiFirmwareVolume2ProtocolGuid AND
+  gEfiVariableArchProtocolGuid AND
+  gEfiVariableWriteArchProtocolGuid
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/SmmAccess.inf b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/SmmAccess.inf
new file mode 100644
index 0000000000..405e9eb7fd
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/SmmAccess.inf
@@ -0,0 +1,49 @@
+## @file
+# Component description file for SmmAccess module
+#
+# Copyright (c) 2013-2019 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SmmAccess
+  FILE_GUID                      = 274F0C8F-9E57-41d8-9966-29CCD48D31C2
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = SmmAccessDriverEntryPoint
+
+[Sources]
+  SmmAccessDriver.h
+  SmmAccessDriver.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  HobLib
+  DebugLib
+  UefiLib
+  BaseLib
+  BaseMemoryLib
+  S3BootScriptLib
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  DxeServicesTableLib
+  PcdLib
+  SmmLib
+
+[Protocols]
+  gEfiPciRootBridgeIoProtocolGuid
+  gEfiSmmAccess2ProtocolGuid
+
+[Guids]
+  gEfiSmmPeiSmramMemoryReserveGuid
+
+[Depex]
+  gEfiPciRootBridgeIoProtocolGuid
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/SmmAccessDriver.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/SmmAccessDriver.c
new file mode 100644
index 0000000000..830f8b83c3
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/SmmAccessDriver.c
@@ -0,0 +1,405 @@
+/** @file
+This is the driver that publishes the SMM Access Protocol
+instance for the Tylersburg chipset.
+
+Copyright (c) 2013-2019 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SmmAccessDriver.h"
+
+
+
+SMM_ACCESS_PRIVATE_DATA  mSmmAccess;
+
+VOID
+SmmAccessOnBoot (
+  IN EFI_EVENT                          Event,
+  IN VOID                               *Context
+);
+
+EFI_STATUS
+EFIAPI
+SmmAccessDriverEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+/*++
+
+Routine Description:
+
+  Installs an SMM Access Protocol.
+
+Arguments:
+
+  ImageHandle  -  Handle for the image of this driver.
+  SystemTable  -  Pointer to the EFI System Table.
+
+Returns:
+
+  EFI_SUCCESS     -  Protocol successfully started and installed.
+  EFI_UNSUPPORTED -  Protocol can't be started.
+  EFI_NOT_FOUND   -  Protocol not found.
+--*/
+{
+
+  EFI_STATUS                      Status;
+  EFI_EVENT                       BootEvent;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+  UINTN                           Index;
+  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *DescriptorBlock;
+  EFI_HOB_GUID_TYPE               *GuidHob;
+
+
+  //
+  // Initialize private data
+  //
+  ZeroMem (&mSmmAccess, sizeof (mSmmAccess));
+
+  Status = gBS->LocateProtocol (
+                  &gEfiPciRootBridgeIoProtocolGuid,
+                  NULL,
+                  (VOID **) &PciRootBridgeIo
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Build SMM related information
+  //
+  mSmmAccess.Signature        = SMM_ACCESS_PRIVATE_DATA_SIGNATURE;
+  mSmmAccess.Handle           = NULL;
+  mSmmAccess.PciRootBridgeIo  = PciRootBridgeIo;
+
+  //
+  // Get Hob list
+  //
+  GuidHob    = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid);
+  DescriptorBlock = GET_GUID_HOB_DATA (GuidHob);
+  ASSERT (DescriptorBlock);
+
+
+  //
+  // Get CPU Max bus number
+  //
+  mSmmAccess.MaxBusNumber         = PCI_BUS_NUMBER_QNC;
+  for (Index = 0; Index < MAX_CPU_SOCKET; Index++) {
+    mSmmAccess.SocketPopulated[Index] = TRUE;
+  }
+
+  //
+  // Use the hob to publish SMRAM capabilities
+  //
+  ASSERT (DescriptorBlock->NumberOfSmmReservedRegions <= MAX_SMRAM_RANGES);
+  for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
+    mSmmAccess.SmramDesc[Index].PhysicalStart = DescriptorBlock->Descriptor[Index].PhysicalStart;
+    mSmmAccess.SmramDesc[Index].CpuStart      = DescriptorBlock->Descriptor[Index].CpuStart;
+    mSmmAccess.SmramDesc[Index].PhysicalSize  = DescriptorBlock->Descriptor[Index].PhysicalSize;
+    mSmmAccess.SmramDesc[Index].RegionState   = DescriptorBlock->Descriptor[Index].RegionState;
+    DEBUG ((EFI_D_INFO, "SM RAM index[%d] startaddr:%08X Size :%08X\n", Index, mSmmAccess.SmramDesc[Index].CpuStart,
+      mSmmAccess.SmramDesc[Index].PhysicalSize));
+  }
+
+  mSmmAccess.NumberRegions              = Index;
+  mSmmAccess.SmmAccess.Open             = Open;
+  mSmmAccess.SmmAccess.Close            = Close;
+  mSmmAccess.SmmAccess.Lock             = Lock;
+  mSmmAccess.SmmAccess.GetCapabilities  = GetCapabilities;
+  mSmmAccess.SmmAccess.LockState        = FALSE;
+  mSmmAccess.SmmAccess.OpenState        = FALSE;
+  mSmmAccess.SMMRegionState             = EFI_SMRAM_CLOSED;
+
+  //
+  // Install our protocol interfaces on the device's handle
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                &mSmmAccess.Handle,
+                &gEfiSmmAccess2ProtocolGuid,
+                &mSmmAccess.SmmAccess,
+                NULL
+                );
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((EFI_D_INFO, "SMM  Base: %08X\n", (UINT32)(mSmmAccess.SmramDesc[mSmmAccess.NumberRegions-1].PhysicalStart)));
+  DEBUG ((EFI_D_INFO, "SMM  Size: %08X\n", (UINT32)(mSmmAccess.SmramDesc[mSmmAccess.NumberRegions-1].PhysicalSize)));
+
+  mSmmAccess.TsegSize = (UINT8)(mSmmAccess.SmramDesc[mSmmAccess.NumberRegions-1].PhysicalSize);
+  //
+  // T Seg setting done in QPI RC
+  //
+
+  //
+  // Prior ReadyToBoot, lock CSEG
+  //
+  Status = EfiCreateEventReadyToBootEx(
+           TPL_NOTIFY,
+           SmmAccessOnBoot,
+           NULL,
+           &BootEvent );
+  ASSERT (!EFI_ERROR (Status));
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+Open (
+  IN EFI_SMM_ACCESS2_PROTOCOL    *This
+  )
+/*++
+
+Routine Description:
+
+  This routine accepts a request to "open" a region of SMRAM.  The
+  region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
+  The use of "open" means that the memory is visible from all boot-service
+  and SMM agents.
+
+Arguments:
+
+  This             -  Pointer to the SMM Access Interface.
+  DescriptorIndex  -  Region of SMRAM to Open.
+
+Returns:
+
+  EFI_SUCCESS            -  The region was successfully opened.
+  EFI_DEVICE_ERROR       -  The region could not be opened because locked by
+                            chipset.
+  EFI_INVALID_PARAMETER  -  The descriptor index was out of bounds.
+
+--*/
+{
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+
+  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+
+  if (mSmmAccess.SMMRegionState & EFI_SMRAM_LOCKED) {
+    DEBUG ((EFI_D_ERROR, "Cannot open a locked SMRAM region\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Open TSEG
+  //
+  if (!QNCOpenSmramRegion ()) {
+    mSmmAccess.SMMRegionState |= EFI_SMRAM_LOCKED;
+    return EFI_DEVICE_ERROR;
+  }
+
+  mSmmAccess.SMMRegionState &= ~(EFI_SMRAM_CLOSED | EFI_ALLOCATED);
+  SyncRegionState2SmramDesc(FALSE, (UINT64)(UINTN)(~(EFI_SMRAM_CLOSED | EFI_ALLOCATED)));
+  mSmmAccess.SMMRegionState |= EFI_SMRAM_OPEN;
+  SyncRegionState2SmramDesc(TRUE, EFI_SMRAM_OPEN);
+  SmmAccess->SmmAccess.OpenState = TRUE;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+Close (
+  IN EFI_SMM_ACCESS2_PROTOCOL *This
+  )
+/*++
+
+Routine Description:
+
+  This routine accepts a request to "close" a region of SMRAM.  This is valid for
+  compatible SMRAM region.
+
+Arguments:
+
+  This             -  Pointer to the SMM Access Interface.
+  DescriptorIndex  -  Region of SMRAM to Close.
+
+Returns:
+
+  EFI_SUCCESS            -  The region was successfully closed.
+  EFI_DEVICE_ERROR       -  The region could not be closed because locked by
+                            chipset.
+  EFI_INVALID_PARAMETER  -  The descriptor index was out of bounds.
+
+--*/
+{
+  EFI_STATUS              Status;
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+  BOOLEAN                 OpenState;
+  UINTN                   Index;
+
+  SmmAccess     = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+
+  if (mSmmAccess.SMMRegionState & EFI_SMRAM_LOCKED) {
+    //
+    // Cannot close a "locked" region
+    //
+    DEBUG ((EFI_D_WARN, "Cannot close the locked SMRAM Region\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (mSmmAccess.SMMRegionState & EFI_SMRAM_CLOSED) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Reset SMRAM cacheability to UC
+  //
+  for (Index = 0; Index < mSmmAccess.NumberRegions; Index++) {
+    DEBUG ((DEBUG_INFO, "SmmAccess->Close: Set to UC Base=%016lx  Size=%016lx\n", SmmAccess->SmramDesc[Index].CpuStart, SmmAccess->SmramDesc[Index].PhysicalSize));
+    Status = gDS->SetMemorySpaceAttributes(
+                    SmmAccess->SmramDesc[Index].CpuStart,
+                    SmmAccess->SmramDesc[Index].PhysicalSize,
+                    EFI_MEMORY_UC
+                    );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_WARN, "SmmAccess: Failed to reset SMRAM window to EFI_MEMORY_UC\n"));
+    }
+  }
+
+  //
+  // Close TSEG
+  //
+  if (!QNCCloseSmramRegion ()) {
+    mSmmAccess.SMMRegionState |= EFI_SMRAM_LOCKED;
+    return EFI_DEVICE_ERROR;
+  }
+
+  mSmmAccess.SMMRegionState &= ~EFI_SMRAM_OPEN;
+  SyncRegionState2SmramDesc(FALSE, (UINT64)(UINTN)(~EFI_SMRAM_OPEN));
+  mSmmAccess.SMMRegionState |= (EFI_SMRAM_CLOSED | EFI_ALLOCATED);
+  SyncRegionState2SmramDesc(TRUE, EFI_SMRAM_CLOSED | EFI_ALLOCATED);
+
+  //
+  // Find out if any regions are still open
+  //
+  OpenState = FALSE;
+  for (Index = 0; Index < mSmmAccess.NumberRegions; Index++) {
+    if ((SmmAccess->SmramDesc[Index].RegionState & EFI_SMRAM_OPEN) == EFI_SMRAM_OPEN) {
+      OpenState = TRUE;
+    }
+  }
+
+  SmmAccess->SmmAccess.OpenState = OpenState;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+Lock (
+  IN EFI_SMM_ACCESS2_PROTOCOL   *This
+  )
+/*++
+
+Routine Description:
+
+  This routine accepts a request to "lock" SMRAM.  The
+  region could be legacy AB or TSEG near top of physical memory.
+  The use of "lock" means that the memory can no longer be opened
+  to BS state..
+
+Arguments:
+
+  This             -  Pointer to the SMM Access Interface.
+  DescriptorIndex  -  Region of SMRAM to Lock.
+
+Returns:
+
+  EFI_SUCCESS            -  The region was successfully locked.
+  EFI_DEVICE_ERROR       -  The region could not be locked because at least
+                            one range is still open.
+  EFI_INVALID_PARAMETER  -  The descriptor index was out of bounds.
+
+--*/
+{
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+
+  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+
+  if (SmmAccess->SmmAccess.OpenState) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  mSmmAccess.SMMRegionState |= EFI_SMRAM_LOCKED;
+  SyncRegionState2SmramDesc(TRUE, EFI_SMRAM_LOCKED);
+  SmmAccess->SmmAccess.LockState                     = TRUE;
+
+  //
+  // Lock TSEG
+  //
+  QNCLockSmramRegion ();
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+GetCapabilities (
+  IN CONST  EFI_SMM_ACCESS2_PROTOCOL *This,
+  IN OUT UINTN                       *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
+  )
+/*++
+
+Routine Description:
+
+  This routine services a user request to discover the SMRAM
+  capabilities of this platform.  This will report the possible
+  ranges that are possible for SMRAM access, based upon the
+  memory controller capabilities.
+
+Arguments:
+
+  This          -  Pointer to the SMRAM Access Interface.
+  SmramMapSize  -  Pointer to the variable containing size of the
+                   buffer to contain the description information.
+  SmramMap      -  Buffer containing the data describing the Smram
+                   region descriptors.
+Returns:
+
+  EFI_BUFFER_TOO_SMALL  -  The user did not provide a sufficient buffer.
+  EFI_SUCCESS           -  The user provided a sufficiently-sized buffer.
+
+--*/
+{
+  EFI_STATUS                Status;
+  SMM_ACCESS_PRIVATE_DATA  *SmmAccess;
+  UINTN                     BufferSize;
+
+  SmmAccess           = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+  BufferSize          = SmmAccess->NumberRegions * sizeof (EFI_SMRAM_DESCRIPTOR);
+
+  if (*SmramMapSize < BufferSize) {
+    Status = EFI_BUFFER_TOO_SMALL;
+  } else {
+    CopyMem (SmramMap, SmmAccess->SmramDesc, *SmramMapSize);
+    Status = EFI_SUCCESS;
+  }
+  *SmramMapSize = BufferSize;
+
+  return Status;
+}
+
+VOID
+SmmAccessOnBoot (
+  IN EFI_EVENT                          Event,
+  IN VOID                               *Context
+)
+{
+
+}
+VOID
+SyncRegionState2SmramDesc(
+  IN BOOLEAN  OrAnd,
+  IN UINT64   Value
+  )
+{
+  UINT32 Index;
+
+  for (Index = 0; Index < mSmmAccess.NumberRegions; Index++) {
+    if (OrAnd) {
+      mSmmAccess.SmramDesc[Index].RegionState |= Value;
+    } else {
+      mSmmAccess.SmramDesc[Index].RegionState &= Value;
+    }
+  }
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/SmmAccessDriver.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/SmmAccessDriver.h
new file mode 100644
index 0000000000..aca169d3e2
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/SmmAccessDriver.h
@@ -0,0 +1,230 @@
+/** @file
+Header file for SMM Access Driver.
+
+This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+Copyright (c) 2013-2019 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SMM_ACCESS_DRIVER_H
+#define _SMM_ACCESS_DRIVER_H
+
+#include <PiDxe.h>
+#include <IndustryStandard/Pci.h>
+
+#include <Library/HobLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/PcdLib.h>
+
+//
+// Driver Consumed Protocol Prototypes
+//
+#include <Protocol/PciRootBridgeIo.h>
+
+//
+// Driver Consumed GUID Prototypes
+//
+#include <Guid/SmramMemoryReserve.h>
+
+//
+// Driver produced protocol
+//
+#include <Protocol/SmmAccess2.h>
+
+#include <Library/QNCSmmLib.h>
+#include <QNCAccess.h>
+
+#define MAX_CPU_SOCKET      1
+#define MAX_SMRAM_RANGES    4
+
+//
+// Private data structure
+//
+#define  SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('i', 's', 'm', 'a')
+
+typedef struct {
+  UINTN                            Signature;
+  EFI_HANDLE                       Handle;
+  EFI_SMM_ACCESS2_PROTOCOL          SmmAccess;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo;
+  UINTN                            NumberRegions;
+  EFI_SMRAM_DESCRIPTOR             SmramDesc[MAX_SMRAM_RANGES];
+  UINT8                            TsegSize;
+  UINT8                            MaxBusNumber;
+  UINT8                            SocketPopulated[MAX_CPU_SOCKET];
+  UINT64                           SMMRegionState;
+  UINT8                            ActualNLIioBusNumber;
+} SMM_ACCESS_PRIVATE_DATA;
+
+
+#define SMM_ACCESS_PRIVATE_DATA_FROM_THIS(a) \
+  CR ( \
+  a, \
+  SMM_ACCESS_PRIVATE_DATA, \
+  SmmAccess, \
+  SMM_ACCESS_PRIVATE_DATA_SIGNATURE \
+  )
+
+
+//
+// Prototypes
+// Driver model protocol interface
+//
+EFI_STATUS
+EFIAPI
+SmmAccessDriverEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+/*++
+
+Routine Description:
+
+  This is the standard EFI driver point that detects
+  whether there is an proper chipset in the system
+  and if so, installs an SMM Access Protocol.
+
+Arguments:
+
+  ImageHandle  -  Handle for the image of this driver.
+  SystemTable  -  Pointer to the EFI System Table.
+
+Returns:
+
+  EFI_SUCCESS      -  Protocol successfully started and installed.
+  EFI_UNSUPPORTED  -  Protocol can't be started.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+Open (
+  IN EFI_SMM_ACCESS2_PROTOCOL *This
+  )
+/*++
+
+Routine Description:
+
+  This routine accepts a request to "open" a region of SMRAM.  The
+  region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
+  The use of "open" means that the memory is visible from all boot-service
+  and SMM agents.
+
+Arguments:
+
+  This             -  Pointer to the SMM Access Interface.
+  DescriptorIndex  -  Region of SMRAM to Open.
+
+Returns:
+
+  EFI_SUCCESS            -  The region was successfully opened.
+  EFI_DEVICE_ERROR       -  The region could not be opened because locked by
+                            chipset.
+  EFI_INVALID_PARAMETER  -  The descriptor index was out of bounds.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+Close (
+  IN EFI_SMM_ACCESS2_PROTOCOL *This
+  )
+/*++
+
+Routine Description:
+
+  This routine accepts a request to "close" a region of SMRAM.  This is valid for
+  compatible SMRAM region.
+
+Arguments:
+
+  This             -  Pointer to the SMM Access Interface.
+  DescriptorIndex  -  Region of SMRAM to Close.
+
+Returns:
+
+  EFI_SUCCESS            -  The region was successfully closed.
+  EFI_DEVICE_ERROR       -  The region could not be closed because locked by
+                            chipset.
+  EFI_INVALID_PARAMETER  -  The descriptor index was out of bounds.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+Lock (
+  IN EFI_SMM_ACCESS2_PROTOCOL *This
+  )
+/*++
+
+Routine Description:
+
+  This routine accepts a request to "lock" SMRAM.  The
+  region could be legacy AB or TSEG near top of physical memory.
+  The use of "lock" means that the memory can no longer be opened
+  to BS state..
+
+Arguments:
+
+  This             -  Pointer to the SMM Access Interface.
+  DescriptorIndex  -  Region of SMRAM to Lock.
+
+Returns:
+
+  EFI_SUCCESS            -  The region was successfully locked.
+  EFI_DEVICE_ERROR       -  The region could not be locked because at least
+                            one range is still open.
+  EFI_INVALID_PARAMETER  -  The descriptor index was out of bounds.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+GetCapabilities (
+  IN CONST EFI_SMM_ACCESS2_PROTOCOL     *This,
+  IN OUT UINTN                   *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR    *SmramMap
+  )
+/*++
+
+Routine Description:
+
+  This routine services a user request to discover the SMRAM
+  capabilities of this platform.  This will report the possible
+  ranges that are possible for SMRAM access, based upon the
+  memory controller capabilities.
+
+Arguments:
+
+  This          -  Pointer to the SMRAM Access Interface.
+  SmramMapSize  -  Pointer to the variable containing size of the
+                   buffer to contain the description information.
+  SmramMap      -  Buffer containing the data describing the Smram
+                   region descriptors.
+
+Returns:
+
+  EFI_BUFFER_TOO_SMALL  -  The user did not provide a sufficient buffer.
+  EFI_SUCCESS           -  The user provided a sufficiently-sized buffer.
+
+--*/
+;
+VOID
+SyncRegionState2SmramDesc(
+  IN BOOLEAN  OrAnd,
+  IN UINT64    Value
+  );
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmControlDxe/SmmControlDriver.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmControlDxe/SmmControlDriver.c
new file mode 100644
index 0000000000..a3e992848f
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmControlDxe/SmmControlDriver.c
@@ -0,0 +1,358 @@
+/** @file
+This module produces the SMM COntrol2 Protocol for QNC
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <Protocol/SmmControl2.h>
+#include <IndustryStandard/Pci.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <IntelQNCDxe.h>
+#include <Library/QNCAccessLib.h>
+#include <Uefi/UefiBaseType.h>
+
+#define EFI_INTERNAL_POINTER  0x00000004
+
+extern EFI_GUID gEfiEventVirtualAddressChangeGuid;
+
+/**
+  Generates an SMI using the parameters passed in.
+
+  @param  This                A pointer to an instance of
+                              EFI_SMM_CONTROL2_PROTOCOL
+  @param  ArgumentBuffer      The argument buffer
+  @param  ArgumentBufferSize  The size of the argument buffer
+  @param  Periodic            TRUE to indicate a periodical SMI
+  @param  ActivationInterval  Interval of the periodical SMI
+
+  @retval EFI_INVALID_PARAMETER Periodic is TRUE or ArgumentBufferSize > 1
+  @return Return value from SmmTrigger().
+
+**/
+EFI_STATUS
+EFIAPI
+Activate (
+  IN CONST EFI_SMM_CONTROL2_PROTOCOL     *This,
+  IN OUT  UINT8                          *CommandPort       OPTIONAL,
+  IN OUT  UINT8                          *DataPort          OPTIONAL,
+  IN      BOOLEAN                        Periodic           OPTIONAL,
+  IN      EFI_SMM_PERIOD                 ActivationInterval OPTIONAL
+                  );
+
+/**
+  Clears an SMI.
+
+  @param  This      Pointer to an instance of EFI_SMM_CONTROL2_PROTOCOL
+  @param  Periodic  TRUE to indicate a periodical SMI
+
+  @return Return value from SmmClear()
+
+**/
+EFI_STATUS
+EFIAPI
+Deactivate (
+  IN CONST     EFI_SMM_CONTROL2_PROTOCOL  *This,
+  IN      BOOLEAN                         Periodic OPTIONAL
+  );
+
+///
+/// Handle for the SMM Control2 Protocol
+///
+EFI_HANDLE  mSmmControl2Handle = NULL;
+
+///
+/// SMM COntrol2 Protocol instance
+///
+EFI_SMM_CONTROL2_PROTOCOL mSmmControl2 = {
+  Activate,
+  Deactivate,
+  0
+};
+
+VOID
+EFIAPI
+SmmControlVirtualddressChangeEvent (
+  IN EFI_EVENT                  Event,
+  IN VOID                       *Context
+  )
+/*++
+
+Routine Description:
+
+  Fixup internal data pointers so that the services can be called in virtual mode.
+
+Arguments:
+
+  Event                         The event registered.
+  Context                       Event context.
+
+Returns:
+
+  None.
+
+--*/
+{
+  gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSmmControl2.Trigger));
+  gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSmmControl2.Clear));
+}
+
+/**
+  Clear SMI related chipset status and re-enable SMI by setting the EOS bit.
+
+  @retval EFI_SUCCESS The requested operation has been carried out successfully
+  @retval EFI_DEVICE_ERROR  The EOS bit could not be set.
+
+**/
+EFI_STATUS
+SmmClear (
+  VOID
+  )
+{
+  UINT16                       GPE0BLK_Base;
+
+  //
+  // Get GPE0BLK_Base
+  //
+  GPE0BLK_Base = PcdGet16 (PcdGpe0blkIoBaseAddress);
+
+  //
+  // Clear the Power Button Override Status Bit, it gates EOS from being set.
+  // In QuarkNcSocId - Bit is read only. Handled by external SMC, do nothing.
+  //
+
+  //
+  // Clear the APM SMI Status Bit
+  //
+  IoWrite32 ((GPE0BLK_Base + R_QNC_GPE0BLK_SMIS), B_QNC_GPE0BLK_SMIS_APM);
+
+  //
+  // Set the EOS Bit
+  //
+  IoOr32 ((GPE0BLK_Base + R_QNC_GPE0BLK_SMIS), B_QNC_GPE0BLK_SMIS_EOS);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Generates an SMI using the parameters passed in.
+
+  @param  This                A pointer to an instance of
+                              EFI_SMM_CONTROL_PROTOCOL
+  @param  ArgumentBuffer      The argument buffer
+  @param  ArgumentBufferSize  The size of the argument buffer
+  @param  Periodic            TRUE to indicate a periodical SMI
+  @param  ActivationInterval  Interval of the periodical SMI
+
+  @retval EFI_INVALID_PARAMETER Periodic is TRUE or ArgumentBufferSize > 1
+  @retval EFI_SUCCESS            SMI generated
+
+**/
+EFI_STATUS
+EFIAPI
+Activate (
+  IN CONST EFI_SMM_CONTROL2_PROTOCOL     *This,
+  IN OUT  UINT8                          *CommandPort       OPTIONAL,
+  IN OUT  UINT8                          *DataPort          OPTIONAL,
+  IN      BOOLEAN                        Periodic           OPTIONAL,
+  IN      EFI_SMM_PERIOD                 ActivationInterval OPTIONAL
+  )
+{
+  UINT16        GPE0BLK_Base;
+  UINT32        NewValue;
+
+  //
+  // Get GPE0BLK_Base
+  //
+  GPE0BLK_Base = PcdGet16 (PcdGpe0blkIoBaseAddress);
+
+  if (Periodic) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Clear any pending the APM SMI
+  //
+  if (EFI_ERROR (SmmClear())) {
+    return EFI_DEVICE_ERROR;
+    }
+
+  //
+  // Enable the APMC SMI
+  //
+  IoOr32 (GPE0BLK_Base + R_QNC_GPE0BLK_SMIE, B_QNC_GPE0BLK_SMIE_APM);
+
+  //
+  // Enable SMI globally
+  //
+  NewValue = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);
+  NewValue |= SMI_EN;
+  QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, NewValue);
+
+
+  //
+  // Set APMC_STS
+  //
+  if (DataPort == NULL) {
+    IoWrite8 (PcdGet16 (PcdSmmDataPort), 0xFF);
+  } else {
+    IoWrite8 (PcdGet16 (PcdSmmDataPort), *DataPort);
+  }
+
+  //
+  // Generate the APMC SMI
+  //
+  if (CommandPort == NULL) {
+    IoWrite8 (PcdGet16 (PcdSmmActivationPort), 0xFF);
+  } else {
+    IoWrite8 (PcdGet16 (PcdSmmActivationPort), *CommandPort);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Clears an SMI.
+
+  @param  This      Pointer to an instance of EFI_SMM_CONTROL_PROTOCOL
+  @param  Periodic  TRUE to indicate a periodical SMI
+
+  @return Return value from SmmClear()
+
+**/
+EFI_STATUS
+EFIAPI
+Deactivate (
+  IN CONST EFI_SMM_CONTROL2_PROTOCOL     *This,
+  IN      BOOLEAN                   Periodic
+  )
+{
+  if (Periodic) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return SmmClear();
+}
+
+/**
+  This is the constructor for the SMM Control protocol.
+
+  This function installs EFI_SMM_CONTROL2_PROTOCOL.
+
+  @param  ImageHandle Handle for the image of this driver
+  @param  SystemTable Pointer to the EFI System Table
+
+  @retval EFI_UNSUPPORTED There's no Intel ICH on this platform
+  @return The status returned from InstallProtocolInterface().
+
+--*/
+EFI_STATUS
+SmmControl2Init (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+  EFI_EVENT   Event;
+  UINT16      PM1BLK_Base;
+  UINT16      GPE0BLK_Base;
+  BOOLEAN     SciEn;
+  UINT32      NewValue;
+
+  //
+  // Get PM1BLK_Base & GPE0BLK_Base
+  //
+  PM1BLK_Base  = PcdGet16 (PcdPm1blkIoBaseAddress);
+  GPE0BLK_Base = PcdGet16 (PcdGpe0blkIoBaseAddress);
+
+  //
+  // Install our protocol interfaces on the device's handle
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mSmmControl2Handle,
+                  &gEfiSmmControl2ProtocolGuid,  &mSmmControl2,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Determine whether an ACPI OS is present (via the SCI_EN bit)
+  //
+  SciEn = (BOOLEAN)((IoRead16 (PM1BLK_Base + R_QNC_PM1BLK_PM1C) & B_QNC_PM1BLK_PM1C_SCIEN) != 0);
+  if (!SciEn) {
+    //
+    // Clear any SMIs that double as SCIs (when SCI_EN==0)
+    //
+    IoWrite16 ((PM1BLK_Base + R_QNC_PM1BLK_PM1S), B_QNC_PM1BLK_PM1S_ALL);
+    IoWrite16 ((PM1BLK_Base + R_QNC_PM1BLK_PM1E), 0x00000000);
+    IoWrite32 ((PM1BLK_Base + R_QNC_PM1BLK_PM1C),  0x00000000);
+    IoWrite32 ((GPE0BLK_Base + R_QNC_GPE0BLK_GPE0S), B_QNC_GPE0BLK_GPE0S_ALL);
+    IoWrite32 ((GPE0BLK_Base + R_QNC_GPE0BLK_GPE0E), 0x00000000);
+  }
+
+  //
+  // Clear and disable all SMIs that are unaffected by SCI_EN
+  // Set EOS
+  //
+  IoWrite32 ((GPE0BLK_Base + R_QNC_GPE0BLK_SMIE), 0x00000000);
+  IoWrite32 ((GPE0BLK_Base + R_QNC_GPE0BLK_SMIS), (B_QNC_GPE0BLK_SMIS_EOS + B_QNC_GPE0BLK_SMIS_ALL));
+
+  //
+  // Enable SMI globally
+  //
+  NewValue = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);
+  NewValue |= SMI_EN;
+  QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, NewValue);
+
+  //
+  // Make sure to write this register last -- EOS re-enables SMIs for the QNC
+  //
+  IoAndThenOr32 (
+    GPE0BLK_Base + R_QNC_GPE0BLK_SMIE,
+    (UINT32)(~B_QNC_GPE0BLK_SMIE_ALL),
+    B_QNC_GPE0BLK_SMIE_APM
+    );
+
+  //
+  // Make sure EOS bit cleared
+  //
+  DEBUG_CODE_BEGIN ();
+  if (IoRead32 (GPE0BLK_Base + R_QNC_GPE0BLK_SMIS) & B_QNC_GPE0BLK_SMIS_EOS) {
+    DEBUG ((
+      EFI_D_ERROR,
+      "******************************************************************************\n"
+      "BIG ERROR: SmmControl constructor couldn't properly initialize the ACPI table.\n"
+      "           SmmControl->Clear will probably hang.                              \n"
+      "              NOTE: SCI_EN = %d                                               \n"
+      "******************************************************************************\n",
+      SciEn
+      ));
+
+    //
+    // If we want the system to stop, then keep the ASSERT(FALSE).
+    // Otherwise, comment it out.
+    //
+    ASSERT (FALSE);
+  }
+  DEBUG_CODE_END ();
+
+  Status = gBS->CreateEventEx (
+                EVT_NOTIFY_SIGNAL,
+                TPL_NOTIFY,
+                SmmControlVirtualddressChangeEvent,
+                NULL,
+                &gEfiEventVirtualAddressChangeGuid,
+                &Event
+                );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmControlDxe/SmmControlDxe.inf b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmControlDxe/SmmControlDxe.inf
new file mode 100644
index 0000000000..1367f0a1f4
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmControlDxe/SmmControlDxe.inf
@@ -0,0 +1,55 @@
+## @file
+# QNC SmmControl driver to install EFI_SMM_CONTROL_PROTOCOL.
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SmmControlDxe
+  FILE_GUID                      = A03A9429-C570-4ef9-9E00-C7A673976E5F
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = SmmControl2Init
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  SmmControlDriver.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  DebugLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  PcdLib
+  IoLib
+  PciLib
+  QNCAccessLib
+
+[Protocols]
+  gEfiSmmControl2ProtocolGuid             # PROTOCOL ALWAYS_PRODUCED
+
+[Pcd]
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPm1blkIoBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdGpe0blkIoBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdSmmDataPort
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdSmmActivationPort
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdGbaIoBaseAddress
+
+[Guids]
+  gEfiEventVirtualAddressChangeGuid
+
+[Depex]
+  TRUE
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/CommonHeader.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/CommonHeader.h
new file mode 100644
index 0000000000..c8bead8081
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/CommonHeader.h
@@ -0,0 +1,45 @@
+/** @file
+Common header file shared by all source files.
+
+This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+
+
+#include <PiSmm.h>
+#include <IntelQNCDxe.h>
+
+#include <Protocol/SmmUsbDispatch2.h>
+#include <Protocol/SmmPeriodicTimerDispatch2.h>
+#include <Protocol/SmmIchnDispatch2.h>
+#include <Protocol/SmmPowerButtonDispatch2.h>
+#include <Protocol/SmmGpiDispatch2.h>
+#include <Protocol/SmmSxDispatch2.h>
+#include <Protocol/SmmSwDispatch2.h>
+#include <Protocol/SmmIoTrapDispatch2.h>
+#include <Protocol/SmmCpu.h>
+
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/IoLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/S3IoLib.h>
+#include <Library/QNCAccessLib.h>
+
+#include <Uefi/UefiBaseType.h>
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmGpi.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmGpi.c
new file mode 100644
index 0000000000..98c9c0690c
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmGpi.c
@@ -0,0 +1,32 @@
+/** @file
+File to contain all the hardware specific stuff for the Smm Gpi dispatch protocol.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+//
+// Include common header file for this module.
+//
+#include "CommonHeader.h"
+
+#include "QNCSmmHelpers.h"
+
+CONST QNC_SMM_SOURCE_DESC GPI_SOURCE_DESC = {
+  QNC_SMM_NO_FLAGS,
+  {
+    {
+      {GPE_ADDR_TYPE, {R_QNC_GPE0BLK_SMIE}}, S_QNC_GPE0BLK_SMIE, N_QNC_GPE0BLK_SMIE_GPIO
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {GPE_ADDR_TYPE, {R_QNC_GPE0BLK_SMIS}}, S_QNC_GPE0BLK_SMIS, N_QNC_GPE0BLK_SMIS_GPIO
+  }
+  }
+};
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmHelpers.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmHelpers.c
new file mode 100644
index 0000000000..5d01c9ef3d
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmHelpers.c
@@ -0,0 +1,549 @@
+/** @file
+
+This driver is responsible for the registration of child drivers
+and the abstraction of the QNC SMI sources.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// Include common header file for this module.
+//
+#include "CommonHeader.h"
+
+#include "QNCSmmHelpers.h"
+
+//
+// Help handle porting bit shifts to IA-64.
+//
+#define BIT_ZERO 0x00000001
+
+
+VOID
+QNCSmmPublishDispatchProtocols(
+  VOID
+  )
+{
+  UINTN      Index;
+  EFI_STATUS Status;
+
+  //
+  // Install protocol interfaces.
+  //
+  for (Index = 0; Index < NUM_PROTOCOLS; Index++) {
+    Status = gSmst->SmmInstallProtocolInterface (
+                 &mPrivateData.InstallMultProtHandle,
+                      mPrivateData.Protocols[Index].Guid,
+                      EFI_NATIVE_INTERFACE,
+                      &mPrivateData.Protocols[Index].Protocols.Generic
+                 );
+
+  ASSERT_EFI_ERROR (Status);
+}
+}
+
+EFI_STATUS
+QNCSmmInitHardware(
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Initialize bits that aren't necessarily related to an SMI source.
+
+Dependencies:
+
+  gSmst - SMM System Table; contains an entry for SMM CPU IO
+
+Returns:
+
+  EFI_SUCCESS.  Asserts, otherwise.
+
+--*/
+{
+  EFI_STATUS Status;
+
+  //
+  // Clear all SMIs
+  //
+  QNCSmmClearSmi();
+
+  Status = QNCSmmEnableGlobalSmiBit ();
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Be *really* sure to clear all SMIs
+  //
+  QNCSmmClearSmi ();
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+QNCSmmEnableGlobalSmiBit (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Enables the QNC to generate SMIs. Note that no SMIs will be generated
+  if no SMI sources are enabled. Conversely, no enabled SMI source will
+  generate SMIs if SMIs are not globally enabled. This is the main
+  switchbox for SMI generation.
+
+Arguments:
+
+  None
+
+Returns:
+
+  EFI_SUCCESS.
+  Asserts, otherwise.
+
+--*/
+{
+  UINT32        NewValue;
+
+  //
+  // Enable SMI globally
+  //
+  NewValue = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);
+  NewValue |= SMI_EN;
+  QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, NewValue);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+QNCSmmClearSmi(
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Clears the SMI after all SMI source have been processed.
+  Note that this function will not work correctly (as it is
+  written) unless all SMI sources have been processed.
+  A revision of this function could manually clear all SMI
+  status bits to guarantee success.
+
+Returns:
+
+  EFI_SUCCESS.
+  Asserts, otherwise.
+
+--*/
+{
+  BOOLEAN EosSet;
+  BOOLEAN SciEn;
+
+  UINT32 Pm1Cnt = 0;
+  UINT16 Pm1Sts = 0;
+  UINT32 Gpe0Sts = 0;
+  UINT32 SmiSts  = 0;
+
+  //
+  // Determine whether an ACPI OS is present (via the SCI_EN bit)
+  //
+  Pm1Cnt = IoRead32(PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C);
+  SciEn = (BOOLEAN)((Pm1Cnt & B_QNC_PM1BLK_PM1C_SCIEN) == B_QNC_PM1BLK_PM1C_SCIEN);
+
+  if (SciEn == FALSE) {
+
+    //
+    // Clear any SMIs that double as SCIs (when SCI_EN==0)
+    //
+    Pm1Sts = (B_QNC_PM1BLK_PM1S_WAKE | B_QNC_PM1BLK_PM1S_PCIEWSTS | B_QNC_PM1BLK_PM1S_RTC | B_QNC_PM1BLK_PM1S_GLOB | B_QNC_PM1BLK_PM1S_TO);
+
+    Gpe0Sts = B_QNC_GPE0BLK_GPE0S_ALL;
+
+    IoOr16((PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1S), Pm1Sts);
+    IoOr32(((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_GPE0S), Gpe0Sts);
+  }
+
+  //
+  // Clear all SMIs that are unaffected by SCI_EN
+  //
+  SmiSts = IoRead32((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_SMIS);
+  SmiSts |= B_QNC_GPE0BLK_SMIS_ALL;
+  IoWrite32(((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_SMIS), SmiSts);
+
+  //
+  // Try to clear the EOS bit. ASSERT on an error
+  //
+  EosSet = QNCSmmSetAndCheckEos();
+  ASSERT (EosSet);
+
+  return EFI_SUCCESS;
+}
+
+BOOLEAN
+QNCSmmSetAndCheckEos(
+  VOID
+  )
+{
+  //
+  // Reset the QNC to generate subsequent SMIs
+  //
+  IoOr32(((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_SMIS), B_QNC_GPE0BLK_SMIS_EOS);
+    return TRUE;
+}
+
+BOOLEAN
+QNCSmmGetSciEn(
+  )
+{
+  BOOLEAN SciEn;
+  UINT32 Pm1Cnt;
+
+  //
+  // Determine whether an ACPI OS is present (via the SCI_EN bit)
+  //
+  Pm1Cnt = IoRead32(PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C);
+
+  SciEn = (BOOLEAN)((Pm1Cnt & B_QNC_PM1BLK_PM1C_SCIEN) == B_QNC_PM1BLK_PM1C_SCIEN);
+
+  return SciEn;
+}
+
+//
+// These may or may not need to change w/ the QNC version; they're highly IA-32 dependent, though.
+//
+
+BOOLEAN
+ReadBitDesc (
+  CONST QNC_SMM_BIT_DESC  *BitDesc
+  )
+{
+  UINT64           Register;
+  UINT32           PciBus;
+  UINT32           PciDev;
+  UINT32           PciFun;
+  UINT32           PciReg;
+  BOOLEAN          BitWasOne;
+
+  ASSERT (BitDesc != NULL );
+  ASSERT (!IS_BIT_DESC_NULL( *BitDesc ) );
+
+  Register  = 0;
+  BitWasOne = FALSE;
+
+  switch (BitDesc->Reg.Type) {
+
+  case ACPI_ADDR_TYPE:
+    //
+    // Double check that we correctly read in the acpi base address
+    //
+    ASSERT ((PcdGet16 (PcdPm1blkIoBaseAddress) != 0x0) && ((PcdGet16 (PcdPm1blkIoBaseAddress) & 0x1) != 0x1) );
+
+    switch (BitDesc->SizeInBytes) {
+
+    case 0:
+      //
+      // Chances are that this field didn't get initialized.
+      // Check your assignments to bit descriptions.
+      //
+      ASSERT (FALSE );
+      break;
+
+      case 1:
+      Register = (UINT64) IoRead8 (PcdGet16 (PcdPm1blkIoBaseAddress) + BitDesc->Reg.Data.acpi);
+        break;
+
+      case 2:
+      Register = (UINT64) IoRead16 (PcdGet16 (PcdPm1blkIoBaseAddress) + BitDesc->Reg.Data.acpi);
+        break;
+
+      case 4:
+      Register = (UINT64) IoRead32 (PcdGet16 (PcdPm1blkIoBaseAddress) + BitDesc->Reg.Data.acpi);
+        break;
+
+      default:
+        //
+        // Unsupported or invalid register size
+        //
+        ASSERT (FALSE );
+        break;
+      };
+
+    if ((Register & LShiftU64 (BIT_ZERO, BitDesc->Bit)) != 0) {
+        BitWasOne = TRUE;
+      } else {
+        BitWasOne = FALSE;
+      }
+    break;
+
+  case GPE_ADDR_TYPE:
+      //
+    // Double check that we correctly read in the gpe base address
+      //
+    ASSERT (((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) != 0x0) && (((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) & 0x1) != 0x1) );
+
+    switch (BitDesc->SizeInBytes) {
+
+    case 0:
+      //
+      // Chances are that this field didn't get initialized.
+      // Check your assignments to bit descriptions.
+      //
+      ASSERT (FALSE );
+      break;
+
+    case 1:
+      Register = (UINT64) IoRead8 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + BitDesc->Reg.Data.gpe);
+      break;
+
+    case 2:
+      Register = (UINT64) IoRead16 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + BitDesc->Reg.Data.gpe);
+      break;
+
+    case 4:
+      Register = (UINT64) IoRead32 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + BitDesc->Reg.Data.gpe);
+      break;
+
+    default:
+      //
+      // Unsupported or invalid register size
+      //
+      ASSERT (FALSE );
+      break;
+    };
+
+    if ((Register & LShiftU64 (BIT_ZERO, BitDesc->Bit)) != 0) {
+        BitWasOne = TRUE;
+      } else {
+        BitWasOne = FALSE;
+      }
+    break;
+
+  case MEMORY_MAPPED_IO_ADDRESS_TYPE:
+    //
+    // Read the register, and it with the bit to read
+    //
+
+    //
+    // This code does not support reads greater then 64 bits
+    //
+    ASSERT (BitDesc->SizeInBytes <= 8);
+    CopyMem (&Register, BitDesc->Reg.Data.Mmio, BitDesc->SizeInBytes);
+    Register &= LShiftU64 (BIT0, BitDesc->Bit);
+    if (Register) {
+      BitWasOne = TRUE;
+    } else {
+      BitWasOne = FALSE;
+    }
+    break;
+
+  case PCI_ADDR_TYPE:
+    PciBus = BitDesc->Reg.Data.pci.Fields.Bus;
+    PciDev = BitDesc->Reg.Data.pci.Fields.Dev;
+    PciFun = BitDesc->Reg.Data.pci.Fields.Fnc;
+    PciReg = BitDesc->Reg.Data.pci.Fields.Reg;
+    switch (BitDesc->SizeInBytes) {
+
+    case 0:
+      //
+      // Chances are that this field didn't get initialized.
+      // Check your assignments to bit descriptions.
+      ASSERT (FALSE );
+      break;
+
+    case 1:
+      Register = (UINT64) PciRead8 (PCI_LIB_ADDRESS (PciBus, PciDev, PciFun, PciReg));
+      break;
+
+    case 2:
+      Register = (UINT64) PciRead16 (PCI_LIB_ADDRESS (PciBus, PciDev, PciFun, PciReg));
+      break;
+
+    case 4:
+      Register = (UINT64) PciRead32 (PCI_LIB_ADDRESS (PciBus, PciDev, PciFun, PciReg));
+      break;
+
+    default:
+      //
+      // Unsupported or invalid register size
+      //
+      ASSERT (FALSE );
+      break;
+    };
+
+    if ((Register & LShiftU64 (BIT_ZERO, BitDesc->Bit)) != 0) {
+        BitWasOne = TRUE;
+    } else {
+      BitWasOne = FALSE;
+    }
+    break;
+
+  default:
+    //
+    // This address type is not yet implemented
+    //
+    ASSERT (FALSE );
+    break;
+  };
+
+  return BitWasOne;
+}
+
+VOID
+WriteBitDesc (
+  CONST QNC_SMM_BIT_DESC   *BitDesc,
+  CONST BOOLEAN           ValueToWrite
+  )
+{
+  UINT64           Register;
+  UINT64           AndVal;
+  UINT64           OrVal;
+  UINT32           PciBus;
+  UINT32           PciDev;
+  UINT32           PciFun;
+  UINT32           PciReg;
+
+  ASSERT (BitDesc != NULL);
+  ASSERT (!IS_BIT_DESC_NULL(*BitDesc));
+
+  AndVal = ~(BIT_ZERO << (BitDesc->Bit));
+  OrVal  = ((UINT32)ValueToWrite) << (BitDesc->Bit);
+
+  switch (BitDesc->Reg.Type) {
+
+  case ACPI_ADDR_TYPE:
+    //
+    // Double check that we correctly read in the acpi base address
+    //
+    ASSERT ((PcdGet16 (PcdPm1blkIoBaseAddress) != 0x0) && ((PcdGet16 (PcdPm1blkIoBaseAddress) & 0x1) != 0x1));
+
+    switch (BitDesc->SizeInBytes) {
+
+    case 0:
+      //
+      // Chances are that this field didn't get initialized.
+      // Check your assignments to bit descriptions.
+      //
+      ASSERT (FALSE );
+      break;
+
+    case 1:
+      IoAndThenOr8 (PcdGet16 (PcdPm1blkIoBaseAddress) + BitDesc->Reg.Data.acpi, (UINT8)AndVal, (UINT8)OrVal);
+      break;
+
+    case 2:
+      IoAndThenOr16 (PcdGet16 (PcdPm1blkIoBaseAddress) + BitDesc->Reg.Data.acpi, (UINT16)AndVal, (UINT16)OrVal);
+      break;
+
+    case 4:
+      IoAndThenOr32 (PcdGet16 (PcdPm1blkIoBaseAddress) + BitDesc->Reg.Data.acpi, (UINT32)AndVal, (UINT32)OrVal);
+      break;
+
+    default:
+      //
+      // Unsupported or invalid register size
+      //
+      ASSERT (FALSE );
+      break;
+    };
+    break;
+
+  case GPE_ADDR_TYPE:
+    //
+    // Double check that we correctly read in the gpe base address
+    //
+    ASSERT (((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) != 0x0) && (((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) & 0x1) != 0x1));
+
+    switch (BitDesc->SizeInBytes) {
+
+    case 0:
+      //
+      // Chances are that this field didn't get initialized.
+      // Check your assignments to bit descriptions.
+      //
+      ASSERT (FALSE );
+      break;
+
+    case 1:
+      IoAndThenOr8 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + BitDesc->Reg.Data.gpe, (UINT8)AndVal, (UINT8)OrVal);
+      break;
+
+    case 2:
+      IoAndThenOr16 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + BitDesc->Reg.Data.gpe, (UINT16)AndVal, (UINT16)OrVal);
+      break;
+
+    case 4:
+      IoAndThenOr32 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + BitDesc->Reg.Data.gpe, (UINT32)AndVal, (UINT32)OrVal);
+      break;
+
+    default:
+      //
+      // Unsupported or invalid register size
+      //
+      ASSERT (FALSE );
+      break;
+    };
+      break;
+
+  case MEMORY_MAPPED_IO_ADDRESS_TYPE:
+    //
+    // Read the register, or it with the bit to set, then write it back.
+    //
+
+    //
+    // This code does not support writes greater then 64 bits
+    //
+    ASSERT (BitDesc->SizeInBytes <= 8);
+    CopyMem (&Register, BitDesc->Reg.Data.Mmio, BitDesc->SizeInBytes);
+    Register &= AndVal;
+    Register |= OrVal;
+    CopyMem (BitDesc->Reg.Data.Mmio, &Register, BitDesc->SizeInBytes);
+    break;
+
+  case PCI_ADDR_TYPE:
+    PciBus = BitDesc->Reg.Data.pci.Fields.Bus;
+    PciDev = BitDesc->Reg.Data.pci.Fields.Dev;
+    PciFun = BitDesc->Reg.Data.pci.Fields.Fnc;
+    PciReg = BitDesc->Reg.Data.pci.Fields.Reg;
+    switch (BitDesc->SizeInBytes) {
+
+    case 0:
+      //
+      // Chances are that this field didn't get initialized -- check your assignments
+      // to bit descriptions.
+      //
+      ASSERT (FALSE );
+      break;
+
+    case 1:
+      PciAndThenOr8 (PCI_LIB_ADDRESS (PciBus, PciDev, PciFun, PciReg), (UINT8) AndVal, (UINT8) OrVal);
+      break;
+
+    case 2:
+      PciAndThenOr16 (PCI_LIB_ADDRESS (PciBus, PciDev, PciFun, PciReg), (UINT16) AndVal, (UINT16) OrVal);
+      break;
+
+    case 4:
+      PciAndThenOr32 (PCI_LIB_ADDRESS (PciBus, PciDev, PciFun, PciReg), (UINT32) AndVal, (UINT32) OrVal);
+      break;
+
+    default:
+      //
+      // Unsupported or invalid register size
+      //
+      ASSERT (FALSE );
+      break;
+    };
+    break;
+
+    default:
+    //
+    // This address type is not yet implemented
+    //
+    ASSERT (FALSE );
+    break;
+  };
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmPeriodicTimer.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmPeriodicTimer.c
new file mode 100644
index 0000000000..b0825bde9d
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmPeriodicTimer.c
@@ -0,0 +1,424 @@
+/** @file
+File to contain all the hardware specific stuff for the Periodical Timer dispatch protocol.
+
+Copyright (c) 2013-2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+//
+// Include common header file for this module.
+//
+#include "CommonHeader.h"
+
+#include "QNCSmmHelpers.h"
+
+typedef enum {
+  PERIODIC_TIMER = 0,
+  NUM_TIMERS
+} SUPPORTED_TIMER;
+
+typedef struct _TIMER_INTERVAL
+{
+  UINT64    Interval;
+  UINT8     AssociatedTimer;
+} TIMER_INTERVAL;
+
+//
+// Time constants, in 100 nano-second units
+//
+#define TIME_64s   640000000 /* 64   s  */
+#define TIME_32s   320000000 /* 32   s  */
+#define TIME_16s   160000000 /* 16   s  */
+#define TIME_8s     80000000 /*  8   s  */
+#define TIME_64ms     640000 /* 64   ms */
+#define TIME_32ms     320000 /* 32   ms */
+#define TIME_16ms     160000 /* 16   ms */
+#define TIME_1_5ms     15000 /*  1.5 ms */
+
+// PMCW (GPE+28h) [2:0] Periodic SMI Rate selection
+// 000 1.5ms
+// 001 16ms
+// 010 32ms
+// 011 64ms
+// 100 8s
+// 101 16s
+// 110 32s
+// 111 64s
+
+typedef enum {
+  INDEX_TIME_1_5ms = 0,
+  INDEX_TIME_16ms,
+  INDEX_TIME_32ms,
+  INDEX_TIME_64ms,
+  INDEX_TIME_8s,
+  INDEX_TIME_16s,
+  INDEX_TIME_32s,
+  INDEX_TIME_64s,
+  INDEX_TIME_MAX
+} TIMER_INTERVAL_INDEX;
+
+TIMER_INTERVAL mSmmPeriodicTimerIntervals[INDEX_TIME_MAX] = {
+  {TIME_1_5ms, PERIODIC_TIMER},
+  {TIME_16ms,  PERIODIC_TIMER},
+  {TIME_32ms,  PERIODIC_TIMER},
+  {TIME_64ms,  PERIODIC_TIMER},
+  { TIME_8s,    PERIODIC_TIMER },
+  {TIME_16s,   PERIODIC_TIMER},
+  {TIME_32s,   PERIODIC_TIMER},
+  {TIME_64s,   PERIODIC_TIMER}
+};
+
+typedef struct _TIMER_INFO {
+  UINTN     NumChildren;      // number of children using this timer
+  UINT64    MinReqInterval;   // minimum interval required by children
+  UINTN     CurrentSetting;   // interval this timer is set at right now (index into interval table)
+} TIMER_INFO;
+
+TIMER_INFO  mTimers[NUM_TIMERS];
+
+QNC_SMM_SOURCE_DESC mTIMER_SOURCE_DESCS[NUM_TIMERS] = {
+  {
+    QNC_SMM_NO_FLAGS,
+    {
+      {{GPE_ADDR_TYPE, {R_QNC_GPE0BLK_SMIE}}, S_QNC_GPE0BLK_SMIE, N_QNC_GPE0BLK_SMIE_SWT},
+      NULL_BIT_DESC_INITIALIZER
+    },
+    {
+      {{GPE_ADDR_TYPE, {R_QNC_GPE0BLK_SMIS}}, S_QNC_GPE0BLK_SMIS, N_QNC_GPE0BLK_SMIS_SWT}
+    }
+  }
+};
+
+VOID
+QNCSmmPeriodicTimerProgramTimers(
+  VOID
+  );
+
+
+TIMER_INTERVAL *
+ContextToTimerInterval (
+  IN  QNC_SMM_CONTEXT     *RegisterContext
+  )
+{
+  UINTN loopvar;
+
+  //
+  // Determine which timer this child is using
+  //
+  for (loopvar = 0; loopvar < INDEX_TIME_MAX; loopvar++) {
+    if (((RegisterContext->PeriodicTimer.SmiTickInterval == 0) && (RegisterContext->PeriodicTimer.Period >= mSmmPeriodicTimerIntervals[loopvar].Interval)) ||
+        (RegisterContext->PeriodicTimer.SmiTickInterval == mSmmPeriodicTimerIntervals[loopvar].Interval)
+       ) {
+        return &mSmmPeriodicTimerIntervals[loopvar];
+      }
+  }
+
+  //
+  // If this assertion fires, then either:
+  //    (1) the context contains an invalid interval
+  //    (2) the timer interval table is corrupt
+  //
+  // ASSERT (FALSE);
+
+  return NULL;
+}
+
+EFI_STATUS
+MapPeriodicTimerToSrcDesc (
+  IN  QNC_SMM_CONTEXT             *RegisterContext,
+  OUT QNC_SMM_SOURCE_DESC         *SrcDesc
+  )
+{
+  TIMER_INTERVAL  *TimerInterval;
+
+  //
+  // Figure out which timer the child is requesting and
+  // send back the source description
+  //
+  TimerInterval = ContextToTimerInterval (RegisterContext);
+  if (TimerInterval == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  CopyMem (SrcDesc, &mTIMER_SOURCE_DESCS[TimerInterval->AssociatedTimer], sizeof (QNC_SMM_SOURCE_DESC));;
+
+  //
+  // Program the value of the interval into hardware
+  //
+  QNCSmmPeriodicTimerProgramTimers ();
+
+  return EFI_SUCCESS;
+}
+
+VOID
+PeriodicTimerGetContext (
+  IN  DATABASE_RECORD    *Record,
+  OUT QNC_SMM_CONTEXT    *HwContext
+  )
+{
+  TIMER_INTERVAL    *TimerInterval;
+
+  ASSERT (Record->ProtocolType == PeriodicTimerType);
+
+  TimerInterval = ContextToTimerInterval (&Record->ChildContext);
+
+  if (TimerInterval != NULL) {
+    //
+    // Ignore the hardware context. It's not required for this protocol.
+    // Instead, just increment the child's context.
+    // Update the elapsed time w/ the data from our tables
+    //
+    Record->CommBuffer.PeriodicTimer.ElapsedTime += TimerInterval->Interval;
+    CopyMem (HwContext, &Record->ChildContext, sizeof (QNC_SMM_CONTEXT));
+  }
+}
+
+BOOLEAN
+PeriodicTimerCmpContext (
+  IN QNC_SMM_CONTEXT     *HwContext,
+  IN QNC_SMM_CONTEXT     *ChildContext
+  )
+{
+  DATABASE_RECORD    *Record;
+
+  Record = DATABASE_RECORD_FROM_CONTEXT (ChildContext);
+
+  if (Record->CommBuffer.PeriodicTimer.ElapsedTime >= ChildContext->PeriodicTimer.Period) {
+    //
+    // This child should be dispatched
+    // The timer will be restarted on the "ClearSource" call.
+    //
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
+
+VOID
+PeriodicTimerGetBuffer (
+  IN  DATABASE_RECORD     * Record
+  )
+{
+  //
+  // CommBuffer has been updated by PeriodicTimerGetContext, so return directly
+  //
+  return;
+}
+
+VOID
+QNCSmmPeriodicTimerProgramTimers (
+  VOID
+  )
+{
+  UINT32            GpePmcwValue;
+  SUPPORTED_TIMER   Timer;
+  DATABASE_RECORD   *RecordInDb;
+  LIST_ENTRY        *LinkInDb;
+  TIMER_INTERVAL    *TimerInterval;
+
+  //
+  // Find the minimum required interval for each timer
+  //
+  for (Timer = (SUPPORTED_TIMER)0; Timer < NUM_TIMERS; Timer++) {
+    mTimers[Timer].MinReqInterval = ~(UINT64)0x0;
+    mTimers[Timer].NumChildren = 0;
+  }
+  LinkInDb = GetFirstNode (&mPrivateData.CallbackDataBase);
+  while (!IsNull (&mPrivateData.CallbackDataBase, LinkInDb)) {
+    RecordInDb = DATABASE_RECORD_FROM_LINK (LinkInDb);
+    if (RecordInDb->ProtocolType == PeriodicTimerType) {
+      //
+      // This child is registerd with the PeriodicTimer protocol
+      //
+      TimerInterval = ContextToTimerInterval (&RecordInDb->ChildContext);
+
+      if(TimerInterval != NULL) {
+        Timer = (SUPPORTED_TIMER)((TIMER_INTERVAL *) (TimerInterval))->AssociatedTimer;
+
+        ASSERT (Timer >= 0 && Timer < NUM_TIMERS);
+
+        if (mTimers[Timer].MinReqInterval > RecordInDb->ChildContext.PeriodicTimer.SmiTickInterval) {
+          mTimers[Timer].MinReqInterval = RecordInDb->ChildContext.PeriodicTimer.SmiTickInterval;
+        }
+        mTimers[Timer].NumChildren++;
+      }
+    }
+    LinkInDb = GetNextNode (&mPrivateData.CallbackDataBase, &RecordInDb->Link);
+  }
+
+  //
+  // Program the hardware
+  //
+  GpePmcwValue = 0;
+  if (mTimers[PERIODIC_TIMER].NumChildren > 0) {
+    switch (mTimers[PERIODIC_TIMER].MinReqInterval) {
+
+    case TIME_64s:
+      GpePmcwValue = INDEX_TIME_64s;
+      mTimers[PERIODIC_TIMER].CurrentSetting = INDEX_TIME_64s;
+      break;
+
+    case TIME_32s:
+      GpePmcwValue = INDEX_TIME_32s;
+      mTimers[PERIODIC_TIMER].CurrentSetting = INDEX_TIME_32s;
+      break;
+
+    case TIME_16s:
+      GpePmcwValue = INDEX_TIME_16s;
+      mTimers[PERIODIC_TIMER].CurrentSetting = INDEX_TIME_16s;
+      break;
+
+    case TIME_8s:
+      GpePmcwValue = INDEX_TIME_8s;
+      mTimers[PERIODIC_TIMER].CurrentSetting = INDEX_TIME_8s;
+      break;
+
+    case TIME_64ms:
+      GpePmcwValue = INDEX_TIME_64ms;
+      mTimers[PERIODIC_TIMER].CurrentSetting = INDEX_TIME_64ms;
+      break;
+
+    case TIME_32ms:
+      GpePmcwValue = INDEX_TIME_32ms;
+      mTimers[PERIODIC_TIMER].CurrentSetting = INDEX_TIME_32ms;
+      break;
+
+    case TIME_16ms:
+      GpePmcwValue = INDEX_TIME_16ms;
+      mTimers[PERIODIC_TIMER].CurrentSetting = INDEX_TIME_16ms;
+      break;
+
+    case TIME_1_5ms:
+      GpePmcwValue = INDEX_TIME_1_5ms;
+      mTimers[PERIODIC_TIMER].CurrentSetting = INDEX_TIME_1_5ms;
+      break;
+
+    default:
+      ASSERT (FALSE);
+      break;
+    };
+
+    GpePmcwValue |= B_QNC_GPE0BLK_PMCW_PSE;
+
+    IoOr32(((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_PMCW), GpePmcwValue);
+
+    //
+    // Restart the timer here, just need to clear the SMI
+    //
+    QNCSmmClearSource (&mTIMER_SOURCE_DESCS[PERIODIC_TIMER]);
+  } else {
+    QNCSmmDisableSource (&mTIMER_SOURCE_DESCS[PERIODIC_TIMER]);
+  }
+}
+
+EFI_STATUS
+QNCSmmPeriodicTimerDispatchGetNextShorterInterval (
+  IN CONST EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL  *This,
+  IN OUT   UINT64                                    **SmiTickInterval
+  )
+/*++
+
+Routine Description:
+
+  This services returns the next SMI tick period that is supported by the chipset.
+  The order returned is from longest to shortest interval period.
+
+Arguments:
+
+  This              - Pointer to the EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL instance.
+  SmiTickInterval   - Pointer to pointer of the next shorter SMI interval period that is supported by the child.
+
+Returns:
+
+  EFI_SUCCESS              - The service returned successfully.
+  EFI_INVALID_PARAMETER   - The parameter SmiTickInterval is invalid.
+
+--*/
+{
+  TIMER_INTERVAL    *IntervalPointer;
+
+  ASSERT (SmiTickInterval != NULL);
+
+  IntervalPointer = (TIMER_INTERVAL*)*SmiTickInterval;
+
+  if (IntervalPointer == NULL) {
+    //
+    // The first time child requesting an interval
+    //
+    IntervalPointer = &mSmmPeriodicTimerIntervals[0];
+  } else if (IntervalPointer == &mSmmPeriodicTimerIntervals[INDEX_TIME_MAX - 1]) {
+    //
+    // At end of the list
+    //
+    IntervalPointer = NULL;
+  } else {
+    if ((IntervalPointer >= &mSmmPeriodicTimerIntervals[0]) &&
+        (IntervalPointer < &mSmmPeriodicTimerIntervals[INDEX_TIME_MAX - 1])) {
+      //
+      // Get the next interval in the list
+      //
+      IntervalPointer++;
+    } else {
+      //
+      // Input is out of range
+      //
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  if (IntervalPointer != NULL) {
+  *SmiTickInterval = &IntervalPointer->Interval;
+  } else {
+    *SmiTickInterval = NULL;
+  }
+
+  return EFI_SUCCESS;
+}
+
+VOID
+QNCSmmPeriodicTimerClearSource (
+  IN QNC_SMM_SOURCE_DESC     *SrcDesc
+  )
+/*++
+
+Routine Description:
+
+  This function is responsible for calculating and enabling any timers that are required
+  to dispatch messages to children. The SrcDesc argument isn't acutally used.
+
+Arguments:
+
+  SrcDesc - Pointer to the QNC_SMM_SOURCE_DESC instance.
+
+Returns:
+
+  None.
+
+--*/
+{
+  DATABASE_RECORD   *RecordInDb;
+  LIST_ENTRY        *LinkInDb;
+
+  QNCSmmPeriodicTimerProgramTimers ();
+
+  //
+  // Reset Elapsed time
+  //
+  LinkInDb = GetFirstNode (&mPrivateData.CallbackDataBase);
+  while (!IsNull (&mPrivateData.CallbackDataBase, LinkInDb)) {
+    RecordInDb = DATABASE_RECORD_FROM_LINK (LinkInDb);
+    if (RecordInDb->ProtocolType == PeriodicTimerType) {
+      //
+      // This child is registerd with the PeriodicTimer protocol and Callback
+      // has been invoked, so reset the ElapsedTime to 0
+      //
+      if (RecordInDb->CommBuffer.PeriodicTimer.ElapsedTime >= RecordInDb->ChildContext.PeriodicTimer.Period) {
+        RecordInDb->CommBuffer.PeriodicTimer.ElapsedTime = 0;
+      }
+    }
+    LinkInDb = GetNextNode (&mPrivateData.CallbackDataBase, &RecordInDb->Link);
+  }
+}
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmQncn.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmQncn.c
new file mode 100644
index 0000000000..2ce0499975
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmQncn.c
@@ -0,0 +1,211 @@
+/** @file
+File to contain all the hardware specific stuff for the Smm QNCn dispatch protocol.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+//
+// Include common header file for this module.
+//
+#include "CommonHeader.h"
+
+#include "QNCSmmHelpers.h"
+
+QNC_SMM_SOURCE_DESC QNCN_SOURCE_DESCS[NUM_ICHN_TYPES] = {
+
+  // QNCnMch (0)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnPme (1)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnRtcAlarm (2)
+  {
+    QNC_SMM_NO_FLAGS,
+    {
+      {{ACPI_ADDR_TYPE, {R_QNC_PM1BLK_PM1E}}, S_QNC_PM1BLK_PM1E, N_QNC_PM1BLK_PM1E_RTC},
+      NULL_BIT_DESC_INITIALIZER
+    },
+    {
+      {{ACPI_ADDR_TYPE, {R_QNC_PM1BLK_PM1S}}, S_QNC_PM1BLK_PM1S, N_QNC_PM1BLK_PM1S_RTC}
+    }
+  },
+
+  // QNCnRingIndicate (3)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnAc97Wake (4)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnSerialIrq (5)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnY2KRollover (6)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnTcoTimeout (7)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnOsTco (8)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnNmi (9)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnIntruderDetect (10)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnBiosWp (11)
+  {
+    QNC_SMM_CLEAR_WITH_ZERO,
+    {
+      {
+        {
+          PCI_ADDR_TYPE,
+          {
+            (
+              (PCI_BUS_NUMBER_QNC << 24) |
+              (PCI_DEVICE_NUMBER_QNC_LPC << 16) |
+              (PCI_FUNCTION_NUMBER_QNC_LPC << 8) |
+              R_QNC_LPC_BIOS_CNTL
+            )
+          }
+        },
+        S_QNC_LPC_BIOS_CNTL,
+        N_QNC_LPC_BIOS_CNTL_BLE
+      },
+      NULL_BIT_DESC_INITIALIZER
+    },
+    {
+      {
+        {
+          PCI_ADDR_TYPE,
+          {
+            (
+              (PCI_BUS_NUMBER_QNC << 24) |
+              (PCI_DEVICE_NUMBER_QNC_LPC << 16) |
+              (PCI_FUNCTION_NUMBER_QNC_LPC << 8) |
+              R_QNC_LPC_BIOS_CNTL
+            )
+          }
+        },
+        S_QNC_LPC_BIOS_CNTL,
+        N_QNC_LPC_BIOS_CNTL_BIOSWE
+      }
+    }
+  },
+
+  // QNCnMcSmi (12)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnPmeB0 (13)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnThrmSts (14)
+  {
+    QNC_SMM_SCI_EN_DEPENDENT,
+    {
+      {{GPE_ADDR_TYPE, {R_QNC_GPE0BLK_GPE0E}}, S_QNC_GPE0BLK_GPE0E, N_QNC_GPE0BLK_GPE0E_THRM},
+      NULL_BIT_DESC_INITIALIZER
+    },
+    {
+      {{GPE_ADDR_TYPE, {R_QNC_GPE0BLK_GPE0S}}, S_QNC_GPE0BLK_GPE0S, N_QNC_GPE0BLK_GPE0S_THRM}
+    }
+  },
+
+  // QNCnSmBus (15)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnIntelUsb2 (16)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnMonSmi7 (17)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnMonSmi6 (18)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnMonSmi5 (19)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnMonSmi4 (20)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnDevTrap13 (21)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnDevTrap12 (22)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnDevTrap11 (23)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnDevTrap10 (24)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnDevTrap9 (25)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnDevTrap8 (26)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnDevTrap7 (27)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnDevTrap6 (28)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnDevTrap5 (29)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnDevTrap3 (30)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnDevTrap2 (31)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnDevTrap1 (32)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnDevTrap0 (33)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnIoTrap3 (34)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnIoTrap2 (35)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnIoTrap1 (36)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnIoTrap0 (37)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnPciExpress (38)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnMonitor (39)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnSpi (40)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnQRT (41)
+  NULL_SOURCE_DESC_INITIALIZER,
+
+  // QNCnGpioUnlock (42)
+  NULL_SOURCE_DESC_INITIALIZER
+};
+
+VOID
+QNCSmmQNCnClearSource(
+  QNC_SMM_SOURCE_DESC   *SrcDesc
+  )
+{
+    QNCSmmClearSource (SrcDesc);
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmSw.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmSw.c
new file mode 100644
index 0000000000..c820df8067
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmSw.c
@@ -0,0 +1,90 @@
+/** @file
+File to contain all the hardware specific stuff for the Smm Sw dispatch protocol.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+//
+// Include common header file for this module.
+//
+#include "CommonHeader.h"
+
+#include "QNCSmmHelpers.h"
+
+EFI_SMM_CPU_PROTOCOL  *mSmmCpu = NULL;
+
+CONST QNC_SMM_SOURCE_DESC SW_SOURCE_DESC = {
+  QNC_SMM_NO_FLAGS,
+  {
+    {
+      {GPE_ADDR_TYPE, {R_QNC_GPE0BLK_SMIE}}, S_QNC_GPE0BLK_SMIE, N_QNC_GPE0BLK_SMIE_APM
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {GPE_ADDR_TYPE, {R_QNC_GPE0BLK_SMIS}}, S_QNC_GPE0BLK_SMIS, N_QNC_GPE0BLK_SMIS_APM
+    }
+  }
+};
+
+VOID
+SwGetContext(
+  IN  DATABASE_RECORD    *Record,
+  OUT QNC_SMM_CONTEXT    *Context
+  )
+{
+  Context->Sw.SwSmiInputValue = IoRead8 (R_APM_CNT);
+}
+
+BOOLEAN
+SwCmpContext (
+  IN QNC_SMM_CONTEXT     *Context1,
+  IN QNC_SMM_CONTEXT     *Context2
+  )
+{
+  return (BOOLEAN)( Context1->Sw.SwSmiInputValue == Context2->Sw.SwSmiInputValue );
+}
+
+VOID
+SwGetBuffer (
+  IN  DATABASE_RECORD     * Record
+  )
+{
+  EFI_STATUS                 Status;
+  UINTN                      Index;
+  UINTN                      CpuIndex;
+  EFI_SMM_SAVE_STATE_IO_INFO IoState;
+
+  //
+  // Locate SMM CPU protocol to retrieve the CPU save state
+  //
+  if (mSmmCpu == NULL) {
+    Status = gSmst->SmmLocateProtocol (&gEfiSmmCpuProtocolGuid, NULL, (VOID **) &mSmmCpu);
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  //
+  // Find the CPU which generated the software SMI
+  //
+  CpuIndex = 0;
+  for (Index = 0; Index < gSmst->NumberOfCpus; Index++) {
+    Status = mSmmCpu->ReadSaveState (
+                        mSmmCpu,
+                        sizeof (EFI_SMM_SAVE_STATE_IO_INFO),
+                        EFI_SMM_SAVE_STATE_REGISTER_IO,
+                        Index,
+                        &IoState
+                        );
+    if (!EFI_ERROR (Status) && (IoState.IoPort == R_APM_CNT)) {
+      CpuIndex = Index;
+      break;
+    }
+  }
+
+  Record->CommBuffer.Sw.SwSmiCpuIndex = CpuIndex;
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmSx.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmSx.c
new file mode 100644
index 0000000000..6381a2c598
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmSx.c
@@ -0,0 +1,147 @@
+/** @file
+File to contain all the hardware specific stuff for the Smm Sx dispatch protocol.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+//
+// Include common header file for this module.
+//
+#include "CommonHeader.h"
+
+#include "QNCSmmHelpers.h"
+
+CONST QNC_SMM_SOURCE_DESC SX_SOURCE_DESC = {
+  QNC_SMM_NO_FLAGS,
+  {
+    {
+      {GPE_ADDR_TYPE, {R_QNC_GPE0BLK_SMIE}}, S_QNC_GPE0BLK_SMIE, N_QNC_GPE0BLK_SMIE_SLP
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {GPE_ADDR_TYPE, {R_QNC_GPE0BLK_SMIS}}, S_QNC_GPE0BLK_SMIS, N_QNC_GPE0BLK_SMIS_SLP
+    }
+  }
+};
+
+VOID
+SxGetContext(
+  IN  DATABASE_RECORD    *Record,
+  OUT QNC_SMM_CONTEXT    *Context
+  )
+{
+  UINT32        Pm1Cnt;
+
+  Pm1Cnt = IoRead32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C);
+
+  //
+  // By design, the context phase will always be ENTRY
+  //
+  Context->Sx.Phase = SxEntry;
+
+  //
+  // Map the PM1_CNT register's SLP_TYP bits to the context type
+  //
+  switch (Pm1Cnt & B_QNC_PM1BLK_PM1C_SLPTP) {
+
+  case V_S0:
+    Context->Sx.Type = SxS0;
+    break;
+
+  case V_S3:
+    Context->Sx.Type = SxS3;
+    break;
+
+  case V_S4:
+    Context->Sx.Type = SxS4;
+    break;
+
+  case V_S5:
+    Context->Sx.Type = SxS5;
+    break;
+
+  default:
+    ASSERT (FALSE);
+    break;
+  };
+}
+
+BOOLEAN
+SxCmpContext (
+  IN QNC_SMM_CONTEXT     *Context1,
+  IN QNC_SMM_CONTEXT     *Context2
+  )
+{
+  return (BOOLEAN)(Context1->Sx.Type == Context2->Sx.Type);
+}
+
+VOID
+QNCSmmSxGoToSleep(
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  When we get an SMI that indicates that we are transitioning to a sleep state,
+  we need to actually transition to that state.  We do this by disabling the
+  "SMI on sleep enable" feature, which generates an SMI when the operating system
+  tries to put the system to sleep, and then physically putting the system to sleep.
+
+Returns:
+
+  None.
+
+--*/
+{
+  UINT32        Pm1Cnt;
+
+  //
+  // Flush cache into memory before we go to sleep. It is necessary for S3 sleep
+  // because we may update memory in SMM Sx sleep handlers -- the updates are in cache now
+  //
+  AsmWbinvd();
+
+  //
+  // Disable SMIs
+  //
+  QNCSmmClearSource (&SX_SOURCE_DESC );
+  QNCSmmDisableSource (&SX_SOURCE_DESC);
+
+  //
+  // Clear Sleep Type Enable
+  //
+  IoAnd16 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_SMIE, (UINT16)(~B_QNC_GPE0BLK_SMIE_SLP));
+
+  // clear sleep SMI status
+  IoAnd16 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_SMIS, (UINT16)(S_QNC_GPE0BLK_SMIS));
+
+  //
+  // Now that SMIs are disabled, write to the SLP_EN bit again to trigger the sleep
+  //
+  Pm1Cnt = IoOr32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C, B_QNC_PM1BLK_PM1C_SLPEN);
+
+  //
+  // The system just went to sleep. If the sleep state was S1, then code execution will resume
+  // here when the system wakes up.
+  //
+  Pm1Cnt = IoRead32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C);
+  if ((Pm1Cnt & B_QNC_PM1BLK_PM1C_SCIEN) == 0) {
+    //
+    // An ACPI OS isn't present, clear the sleep information
+    //
+    Pm1Cnt &= ~B_QNC_PM1BLK_PM1C_SLPTP;
+    Pm1Cnt |= V_S0;
+
+    IoWrite32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C, Pm1Cnt);
+  }
+
+  QNCSmmClearSource (&SX_SOURCE_DESC);
+  QNCSmmEnableSource (&SX_SOURCE_DESC);
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmm.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmm.h
new file mode 100644
index 0000000000..ae3529f679
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmm.h
@@ -0,0 +1,868 @@
+/** @file
+Prototypes and defines for the QNC SMM Dispatcher.
+
+Copyright (c) 2013-2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef QNC_SMM_H
+#define QNC_SMM_H
+
+//
+// Include common header file for this module.
+//
+#include "CommonHeader.h"
+
+#include "QNCSmmRegisters.h"
+
+extern EFI_HANDLE  mQNCSmmDispatcherImageHandle;
+
+
+//
+// /////////////////////////////////////////////////////////////////////////////
+// SUPPORTED PROTOCOLS
+//
+
+//
+// Define an enumeration for all the supported protocols
+//
+typedef enum {
+  // UsbType,    DELETE:on QuarkNcSocId, there is no usb smi supported
+  SxType,
+  SwType,
+  GpiType,
+  QNCnType,
+  PowerButtonType,
+  PeriodicTimerType,
+  NUM_PROTOCOLS
+} QNC_SMM_PROTOCOL_TYPE;
+
+//
+// /////////////////////////////////////////////////////////////////////////////
+// SPECIFYING A REGISTER
+// We want a general way of referring to addresses.  For this case, we'll only
+// need addresses in the ACPI table (and the TCO entries within the ACPI table).
+// However, it's interesting to consider what it would take to support other types
+// of addresses.  To address Will's concern, I think it prudent to accommodate it
+// early on in the design.
+//
+// Addresses we need to consider:
+//
+//  Type:                           Required:
+//  I/O                             Yes
+//    ACPI (special case of I/O)    Only if we want to
+//    TCO  (special case of ACPI)   Only if we want to
+//  Memory (or Memory Mapped I/O)   Only if we want to
+//  PCI                             Yes, for BiosWp
+//
+typedef enum {
+  //
+  //  IO_ADDR_TYPE, // unimplemented
+  //
+  ACPI_ADDR_TYPE,
+  GPE_ADDR_TYPE,
+  //
+  //  MEMORY_ADDR_TYPE, // unimplemented
+  //
+  MEMORY_MAPPED_IO_ADDRESS_TYPE,
+  PCI_ADDR_TYPE,
+  NUM_ADDR_TYPES,                     // count of items in this enum
+  QNC_SMM_ADDR_TYPE_NULL        = -1  // sentinel to indicate NULL or to signal end of arrays
+} ADDR_TYPE;
+
+//
+// Assumption: 32-bits -- enum's evaluate to integer
+// Assumption: This code will only run on IA-32.  Justification: IA-64 doesn't have SMIs.
+// We don't have to worry about 64-bit addresses.
+// Typedef the size of addresses in case the numbers I'm using are wrong or in case
+// this changes.  This is a good idea because PCI_ADDR will change, for example, when
+// we add support for PciExpress.
+//
+typedef UINT16 IO_ADDR;
+typedef IO_ADDR ACPI_ADDR;  // can omit
+typedef IO_ADDR GPE_ADDR;  // can omit
+typedef IO_ADDR TCO_ADDR;   // can omit
+typedef VOID *MEM_ADDR;
+typedef MEM_ADDR MEMORY_MAPPED_IO_ADDRESS;
+typedef union {
+  UINT32  Raw;
+  struct {
+    UINT8 Reg;
+    UINT8 Fnc;
+    UINT8 Dev;
+    UINT8 Bus;
+  } Fields;
+} PCI_ADDR;
+
+typedef struct {
+  ADDR_TYPE Type;
+  union {
+    //
+    // used to initialize during declaration/definition
+    //
+    UINTN                     raw;
+
+    //
+    // used to access useful data
+    //
+    IO_ADDR                   io;
+    ACPI_ADDR                 acpi;
+    GPE_ADDR                  gpe;
+    TCO_ADDR                  tco;
+    MEM_ADDR                  mem;
+    MEMORY_MAPPED_IO_ADDRESS  Mmio;
+    PCI_ADDR                  pci;
+
+  } Data;
+
+} QNC_SMM_ADDRESS;
+//
+// Assumption: total size is 64 bits (32 for type and 32 for data) or 8 bytes
+//
+#define EFI_PCI_ADDRESS_PORT  0xcf8
+#define EFI_PCI_DATA_PORT     0xcfc
+
+//
+// /////////////////////////////////////////////////////////////////////////////
+// SPECIFYING BITS WITHIN A REGISTER
+// Here's a struct that helps us specify a source or enable bit.
+//
+typedef struct {
+  QNC_SMM_ADDRESS Reg;
+  UINT8           SizeInBytes;  // of the register
+  UINT8           Bit;
+} QNC_SMM_BIT_DESC;
+
+//
+// Sometimes, we'll have bit descriptions that are unused.  It'd be great to have a
+// way to easily identify them:
+//
+#define IS_BIT_DESC_NULL(BitDesc)   ((BitDesc).Reg.Type == QNC_SMM_ADDR_TYPE_NULL)  // "returns" true when BitDesc is NULL
+#define NULL_THIS_BIT_DESC(BitDesc) ((BitDesc).Reg.Type = QNC_SMM_ADDR_TYPE_NULL)   // will "return" an integer w/ value of 0
+#define NULL_BIT_DESC_INITIALIZER \
+  { \
+    { \
+      QNC_SMM_ADDR_TYPE_NULL, \
+      { \
+        0 \
+      } \
+    }, \
+    0, 0 \
+  }
+//
+// I'd like a type to specify the callback's Sts & En bits because they'll
+// be commonly used together:
+//
+#define NUM_EN_BITS   2
+#define NUM_STS_BITS  1
+
+//
+// Flags
+//
+typedef UINT8 QNC_SMM_SOURCE_FLAGS;
+
+//
+// Flags required today
+//
+#define QNC_SMM_NO_FLAGS               0
+#define QNC_SMM_SCI_EN_DEPENDENT      (BIT0)
+#define QNC_SMM_CLEAR_WITH_ZERO       (BIT6)
+
+//
+// Flags that might be required tomorrow
+// #define QNC_SMM_CLEAR_WITH_ONE 2 // may need to support bits that clear by writing 0
+// #define QNC_SMM_MULTIBIT_FIELD 3 // may need to support status/enable fields 2 bits wide
+//
+typedef struct {
+  QNC_SMM_SOURCE_FLAGS  Flags;
+  QNC_SMM_BIT_DESC      En[NUM_EN_BITS];
+  QNC_SMM_BIT_DESC      Sts[NUM_STS_BITS];
+} QNC_SMM_SOURCE_DESC;
+//
+// 31 bytes, I think
+//
+#define NULL_SOURCE_DESC_INITIALIZER \
+  { \
+    QNC_SMM_NO_FLAGS, \
+    { \
+      NULL_BIT_DESC_INITIALIZER, NULL_BIT_DESC_INITIALIZER \
+    }, \
+    { \
+      NULL_BIT_DESC_INITIALIZER \
+    } \
+  }
+
+//
+// /////////////////////////////////////////////////////////////////////////////
+// CHILD CONTEXTS
+// To keep consistent w/ the architecture, we'll need to provide the context
+// to the child when we call its callback function.  After talking with Will,
+// we agreed that we'll need functions to "dig" the context out of the hardware
+// in many cases (Sx, Trap, Gpi, etc), and we'll need a function to compare those
+// contexts to prevent unnecessary dispatches.  I'd like a general type for these
+// "GetContext" functions, so I'll need a union of all the protocol contexts for
+// our internal use:
+//
+typedef union {
+  //
+  // (in no particular order)
+  //
+  EFI_SMM_ICHN_REGISTER_CONTEXT           QNCn;
+  EFI_SMM_SX_REGISTER_CONTEXT             Sx;
+  EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT PeriodicTimer;
+  EFI_SMM_SW_REGISTER_CONTEXT             Sw;
+  EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT   PowerButton;
+  // EFI_SMM_USB_REGISTER_CONTEXT            Usb; DELETE:on QuarkNcSocId, there is no usb smi supported
+  EFI_SMM_GPI_REGISTER_CONTEXT            Gpi;
+} QNC_SMM_CONTEXT;
+
+typedef union {
+  //
+  // (in no particular order)
+  //
+  EFI_SMM_SW_CONTEXT                      Sw;
+  EFI_SMM_PERIODIC_TIMER_CONTEXT          PeriodicTimer;
+} QNC_SMM_BUFFER;
+
+//
+// Assumption: PeriodicTimer largest at 3x64-bits or 24 bytes
+//
+typedef struct _DATABASE_RECORD DATABASE_RECORD;
+
+typedef
+VOID
+(EFIAPI *GET_CONTEXT) (
+  IN  DATABASE_RECORD    * Record,
+  OUT QNC_SMM_CONTEXT    * Context
+  );
+//
+// Assumption: the GET_CONTEXT function will be as small and simple as possible.
+// Assumption: We don't need to pass in an enumeration for the protocol because each
+//    GET_CONTEXT function is written for only one protocol.
+// We also need a function to compare contexts to see if the child should be dispatched
+//
+typedef
+BOOLEAN
+(EFIAPI *CMP_CONTEXT) (
+  IN QNC_SMM_CONTEXT     * Context1,
+  IN QNC_SMM_CONTEXT     * Context2
+  );
+
+/*
+    Returns: True when contexts are equivalent; False otherwise
+*/
+
+//
+// This function is used to get the content of CommBuffer that will be passed
+// to Callback function
+//
+typedef
+VOID
+(EFIAPI *GET_BUFFER) (
+  IN  DATABASE_RECORD     * Record
+  );
+
+//
+// Finally, every protocol will require a "Get Context", "Compare Context"
+// and "Get CommBuffer" call, so we may as well wrap that up in a table, too.
+//
+typedef struct {
+  GET_CONTEXT GetContext;
+  CMP_CONTEXT CmpContext;
+  GET_BUFFER  GetBuffer;
+} CONTEXT_FUNCTIONS;
+
+extern CONTEXT_FUNCTIONS          ContextFunctions[NUM_PROTOCOLS];
+
+//
+// /////////////////////////////////////////////////////////////////////////////
+// MAPPING CONTEXT TO BIT DESCRIPTIONS
+// I'd like to have a general approach to mapping contexts to bit descriptions.
+// Sometimes, we'll find that we can use table lookups or CONSTant assignments;
+// other times, we'll find that we'll need to use a function to perform the mapping.
+// If we define a macro to mask that process, we'll never have to change the code.
+// I don't know if this is desirable or not -- if it isn't, then we can get rid
+// of the macros and just use function calls or variable assignments.  Doesn't matter
+// to me.
+// Mapping complex contexts requires a function
+//
+// DELETE:on QuarkNcSocId, there is no usb smi supported
+//EFI_STATUS
+//EFIAPI
+//MapUsbToSrcDesc (
+//  IN  QNC_SMM_CONTEXT                                          *RegisterContext,
+//  OUT QNC_SMM_SOURCE_DESC                                      *SrcDesc
+//  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  RegisterContext - GC_TODO: add argument description
+  SrcDesc         - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+MapPeriodicTimerToSrcDesc (
+  IN  QNC_SMM_CONTEXT                                          *RegisterContext,
+  OUT QNC_SMM_SOURCE_DESC                                     *SrcDesc
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  RegisterContext - GC_TODO: add argument description
+  SrcDesc         - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+//
+// Mapping simple contexts can be done by assignment or lookup table
+//
+extern CONST QNC_SMM_SOURCE_DESC  SW_SOURCE_DESC;
+extern CONST QNC_SMM_SOURCE_DESC  SX_SOURCE_DESC;
+
+//
+// With the changes we've made to the protocols, we can now use table
+// lookups for the following protocols:
+//
+extern CONST QNC_SMM_SOURCE_DESC  GPI_SOURCE_DESC;
+
+extern QNC_SMM_SOURCE_DESC        QNCN_SOURCE_DESCS[NUM_ICHN_TYPES];
+
+
+//
+// For QNCx, APMC is UINT8 port, so the MAX SWI Value is 0xFF.
+//
+#define MAXIMUM_SWI_VALUE   0xFF
+
+
+//
+// Open: Need to make sure this kind of type cast will actually work.
+//   May need an intermediate form w/ two VOID* arguments.  I'll figure
+//   that out when I start compiling.
+
+///////////////////////////////////////////////////////////////////////////////
+//
+typedef
+VOID
+(EFIAPI *QNC_SMM_CLEAR_SOURCE) (
+  QNC_SMM_SOURCE_DESC * SrcDesc
+  );
+
+//
+// /////////////////////////////////////////////////////////////////////////////
+// "DATABASE" RECORD
+// Linked list data structures
+//
+#define DATABASE_RECORD_SIGNATURE SIGNATURE_32 ('D', 'B', 'R', 'C')
+
+struct _DATABASE_RECORD {
+  UINT32                Signature;
+  LIST_ENTRY            Link;
+
+  BOOLEAN               Processed;
+
+  //
+  // Status and Enable bit description
+  //
+  QNC_SMM_SOURCE_DESC   SrcDesc;
+
+  //
+  // Callback function
+  //
+  EFI_SMM_HANDLER_ENTRY_POINT2      Callback;
+  QNC_SMM_CONTEXT                   ChildContext;
+  VOID                              *CallbackContext;
+  QNC_SMM_BUFFER                    CommBuffer;
+  UINTN                             BufferSize;
+
+  //
+  // Special handling hooks -- init them to NULL if unused/unneeded
+  //
+  QNC_SMM_CLEAR_SOURCE  ClearSource;  // needed for SWSMI timer
+  // Functions required to make callback code general
+  //
+  CONTEXT_FUNCTIONS     ContextFunctions;
+
+  //
+  // The protocol that this record dispatches
+  //
+  QNC_SMM_PROTOCOL_TYPE ProtocolType;
+
+};
+
+#define DATABASE_RECORD_FROM_LINK(_record)  CR (_record, DATABASE_RECORD, Link, DATABASE_RECORD_SIGNATURE)
+#define DATABASE_RECORD_FROM_CONTEXT(_record)  CR (_record, DATABASE_RECORD, ChildContext, DATABASE_RECORD_SIGNATURE)
+
+//
+// /////////////////////////////////////////////////////////////////////////////
+// HOOKING INTO THE ARCHITECTURE
+//
+typedef
+EFI_STATUS
+(EFIAPI *QNC_SMM_GENERIC_REGISTER) (
+  IN  VOID                                    **This,
+  IN  VOID                                    *DispatchFunction,
+  IN  VOID                                    *RegisterContext,
+  OUT EFI_HANDLE                              * DispatchHandle
+  );
+typedef
+EFI_STATUS
+(EFIAPI *QNC_SMM_GENERIC_UNREGISTER) (
+  IN  VOID                                    **This,
+  IN  EFI_HANDLE                              DispatchHandle
+  );
+
+//
+// Define a memory "stamp" equivalent in size and function to most of the protocols
+//
+typedef struct {
+  QNC_SMM_GENERIC_REGISTER    Register;
+  QNC_SMM_GENERIC_UNREGISTER  Unregister;
+  UINTN                       Extra1;
+  UINTN                       Extra2; // may not need this one
+} QNC_SMM_GENERIC_PROTOCOL;
+
+EFI_STATUS
+QNCSmmCoreRegister (
+  IN  QNC_SMM_GENERIC_PROTOCOL                          *This,
+  IN  EFI_SMM_HANDLER_ENTRY_POINT2                      DispatchFunction,
+  IN  QNC_SMM_CONTEXT                                    *RegisterContext,
+  OUT EFI_HANDLE                                        *DispatchHandle
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  This              - GC_TODO: add argument description
+  DispatchFunction  - GC_TODO: add argument description
+  RegisterContext   - GC_TODO: add argument description
+  DispatchHandle    - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+EFI_STATUS
+QNCSmmCoreUnRegister (
+  IN  QNC_SMM_GENERIC_PROTOCOL                         *This,
+  IN EFI_HANDLE                                        DispatchHandle
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  This            - GC_TODO: add argument description
+  DispatchHandle  - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+typedef union {
+  QNC_SMM_GENERIC_PROTOCOL                  Generic;
+
+  // EFI_SMM_USB_DISPATCH2_PROTOCOL             Usb;  DELETE:on QuarkNcSocId, there is no usb smi supported
+  EFI_SMM_SX_DISPATCH2_PROTOCOL              Sx;
+  EFI_SMM_SW_DISPATCH2_PROTOCOL              Sw;
+  EFI_SMM_GPI_DISPATCH2_PROTOCOL             Gpi;
+  EFI_SMM_ICHN_DISPATCH2_PROTOCOL            QNCn;
+  EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL    PowerButton;
+  EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL  PeriodicTimer;
+} QNC_SMM_PROTOCOL;
+
+//
+// Define a structure to help us identify the generic protocol
+//
+#define PROTOCOL_SIGNATURE  SIGNATURE_32 ('P', 'R', 'O', 'T')
+
+typedef struct {
+  UINTN                 Signature;
+
+  QNC_SMM_PROTOCOL_TYPE Type;
+  EFI_GUID              *Guid;
+  QNC_SMM_PROTOCOL      Protocols;
+} QNC_SMM_QUALIFIED_PROTOCOL;
+
+#define QUALIFIED_PROTOCOL_FROM_GENERIC(_generic) \
+  CR (_generic, \
+      QNC_SMM_QUALIFIED_PROTOCOL, \
+      Protocols, \
+      PROTOCOL_SIGNATURE \
+      )
+
+//
+// Create private data for the protocols that we'll publish
+//
+typedef struct {
+  LIST_ENTRY                  CallbackDataBase;
+  EFI_HANDLE                  SmiHandle;
+  EFI_HANDLE                  InstallMultProtHandle;
+  QNC_SMM_QUALIFIED_PROTOCOL  Protocols[NUM_PROTOCOLS];
+} PRIVATE_DATA;
+
+extern PRIVATE_DATA           mPrivateData;
+
+//
+// /////////////////////////////////////////////////////////////////////////////
+//
+VOID
+EFIAPI
+SwGetContext (
+  IN  DATABASE_RECORD    *Record,
+  OUT QNC_SMM_CONTEXT    *Context
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  Record  - GC_TODO: add argument description
+  Context - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+EFIAPI
+SwCmpContext (
+  IN QNC_SMM_CONTEXT     *Context1,
+  IN QNC_SMM_CONTEXT     *Context2
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  Context1  - GC_TODO: add argument description
+  Context2  - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+VOID
+SwGetBuffer (
+  IN  DATABASE_RECORD     * Record
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  Record  - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+VOID
+EFIAPI
+SxGetContext (
+  IN  DATABASE_RECORD    *Record,
+  OUT QNC_SMM_CONTEXT    *Context
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  Record  - GC_TODO: add argument description
+  Context - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+EFIAPI
+SxCmpContext (
+  IN QNC_SMM_CONTEXT     *Context1,
+  IN QNC_SMM_CONTEXT     *Context2
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  Context1  - GC_TODO: add argument description
+  Context2  - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+VOID
+EFIAPI
+PeriodicTimerGetContext (
+  IN  DATABASE_RECORD    *Record,
+  OUT QNC_SMM_CONTEXT    *Context
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  Record  - GC_TODO: add argument description
+  Context - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+EFIAPI
+PeriodicTimerCmpContext (
+  IN QNC_SMM_CONTEXT     *Context1,
+  IN QNC_SMM_CONTEXT     *Context2
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  Context1  - GC_TODO: add argument description
+  Context2  - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+VOID
+PeriodicTimerGetBuffer (
+  IN  DATABASE_RECORD     * Record
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  Record  - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+VOID
+EFIAPI
+PowerButtonGetContext (
+  IN  DATABASE_RECORD    *Record,
+  OUT QNC_SMM_CONTEXT     *Context
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  Record  - GC_TODO: add argument description
+  Context - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+EFIAPI
+PowerButtonCmpContext (
+  IN QNC_SMM_CONTEXT     *Context1,
+  IN QNC_SMM_CONTEXT     *Context2
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  Context1  - GC_TODO: add argument description
+  Context2  - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+//
+// /////////////////////////////////////////////////////////////////////////////
+//
+VOID
+EFIAPI
+QNCSmmPeriodicTimerClearSource (
+  QNC_SMM_SOURCE_DESC *SrcDesc
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  SrcDesc - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+QNCSmmPeriodicTimerDispatchGetNextShorterInterval (
+  IN CONST EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL    *This,
+  IN OUT UINT64                                         **SmiTickInterval
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  This            - GC_TODO: add argument description
+  SmiTickInterval - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+VOID
+QNCSmmSxGoToSleep (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  None
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+VOID
+EFIAPI
+QNCSmmQNCnClearSource (
+  QNC_SMM_SOURCE_DESC *SrcDesc
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  SrcDesc - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmCore.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmCore.c
new file mode 100644
index 0000000000..6e6d48fe02
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmCore.c
@@ -0,0 +1,825 @@
+/** @file
+This driver is responsible for the registration of child drivers
+and the abstraction of the QNC SMI sources.
+
+Copyright (c) 2013-2017 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+//
+// Include common header file for this module.
+//
+#include "CommonHeader.h"
+
+#include "QNCSmm.h"
+#include "QNCSmmHelpers.h"
+
+//
+// /////////////////////////////////////////////////////////////////////////////
+// MODULE / GLOBAL DATA
+//
+// Module variables used by the both the main dispatcher and the source dispatchers
+// Declared in QNCSmmSources.h
+//
+UINT32                    mPciData;
+UINT32                    mPciAddress;
+
+PRIVATE_DATA              mPrivateData = {  // for the structure
+  {
+    NULL
+  },                                        // CallbackDataBase linked list head
+  NULL,                                     // Handler returned whan calling SmiHandlerRegister
+  NULL,                                     // EFI handle returned when calling InstallMultipleProtocolInterfaces
+  {                                         // protocol arrays
+    // elements within the array
+    //
+    {
+      PROTOCOL_SIGNATURE,
+      SxType,
+      &gEfiSmmSxDispatch2ProtocolGuid,
+      {
+        {
+          (QNC_SMM_GENERIC_REGISTER) QNCSmmCoreRegister,
+          (QNC_SMM_GENERIC_UNREGISTER) QNCSmmCoreUnRegister
+        }
+      }
+    },
+    {
+      PROTOCOL_SIGNATURE,
+      SwType,
+      &gEfiSmmSwDispatch2ProtocolGuid,
+      {
+        {
+          (QNC_SMM_GENERIC_REGISTER) QNCSmmCoreRegister,
+          (QNC_SMM_GENERIC_UNREGISTER) QNCSmmCoreUnRegister,
+          (UINTN) MAXIMUM_SWI_VALUE
+        }
+      }
+    },
+    {
+      PROTOCOL_SIGNATURE,
+      GpiType,
+      &gEfiSmmGpiDispatch2ProtocolGuid,
+      {
+        {
+          (QNC_SMM_GENERIC_REGISTER) QNCSmmCoreRegister,
+          (QNC_SMM_GENERIC_UNREGISTER) QNCSmmCoreUnRegister,
+          (UINTN) 1
+        }
+      }
+    },
+    {
+      PROTOCOL_SIGNATURE,
+      QNCnType,
+      &gEfiSmmIchnDispatch2ProtocolGuid,
+      {
+        {
+          (QNC_SMM_GENERIC_REGISTER) QNCSmmCoreRegister,
+          (QNC_SMM_GENERIC_UNREGISTER) QNCSmmCoreUnRegister
+        }
+      }
+    },
+    {
+      PROTOCOL_SIGNATURE,
+      PowerButtonType,
+      &gEfiSmmPowerButtonDispatch2ProtocolGuid,
+      {
+        {
+          (QNC_SMM_GENERIC_REGISTER) QNCSmmCoreRegister,
+          (QNC_SMM_GENERIC_UNREGISTER) QNCSmmCoreUnRegister
+        }
+      }
+    },
+    {
+      PROTOCOL_SIGNATURE,
+      PeriodicTimerType,
+      &gEfiSmmPeriodicTimerDispatch2ProtocolGuid,
+      {
+        {
+          (QNC_SMM_GENERIC_REGISTER) QNCSmmCoreRegister,
+          (QNC_SMM_GENERIC_UNREGISTER) QNCSmmCoreUnRegister,
+          (UINTN) QNCSmmPeriodicTimerDispatchGetNextShorterInterval
+        }
+      }
+    },
+  }
+};
+
+CONTEXT_FUNCTIONS         mContextFunctions[NUM_PROTOCOLS] = {
+  {
+    SxGetContext,
+    SxCmpContext,
+    NULL
+  },
+  {
+    SwGetContext,
+    SwCmpContext,
+    SwGetBuffer
+  },
+  {
+    NULL,
+    NULL,
+    NULL
+  },
+  {
+    NULL,
+    NULL,
+    NULL
+  },
+  {
+    NULL,
+    NULL,
+    NULL
+  },
+  {
+    PeriodicTimerGetContext,
+    PeriodicTimerCmpContext,
+    PeriodicTimerGetBuffer,
+  },
+};
+
+//
+// /////////////////////////////////////////////////////////////////////////////
+// PROTOTYPES
+//
+// Functions use only in this file
+//
+EFI_STATUS
+QNCSmmCoreDispatcher (
+  IN     EFI_HANDLE               DispatchHandle,
+  IN     CONST VOID               *Context,        OPTIONAL
+  IN OUT VOID                     *CommBuffer,     OPTIONAL
+  IN OUT UINTN                    *CommBufferSize  OPTIONAL
+  );
+
+
+UINTN
+DevicePathSize (
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  );
+
+//
+// /////////////////////////////////////////////////////////////////////////////
+// FUNCTIONS
+//
+// Driver entry point
+//
+EFI_STATUS
+EFIAPI
+InitializeQNCSmmDispatcher (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+/*++
+
+Routine Description:
+
+  Initializes the QNC SMM Dispatcher
+
+Arguments:
+
+  ImageHandle   - Pointer to the loaded image protocol for this driver
+  SystemTable   - Pointer to the EFI System Table
+
+Returns:
+  Status        - EFI_SUCCESS
+
+--*/
+{
+  EFI_STATUS                Status;
+
+  QNCSmmPublishDispatchProtocols ();
+
+  //
+  // Register a callback function to handle subsequent SMIs.  This callback
+  // will be called by SmmCoreDispatcher.
+  //
+  Status = gSmst->SmiHandlerRegister (QNCSmmCoreDispatcher, NULL, &mPrivateData.SmiHandle);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Initialize Callback DataBase
+  //
+  InitializeListHead (&mPrivateData.CallbackDataBase);
+
+  //
+  // Enable SMIs on the QNC now that we have a callback
+  //
+  QNCSmmInitHardware ();
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SaveState (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Save Index registers to avoid corrupting the foreground environment
+
+Arguments:
+  None
+
+Returns:
+  Status - EFI_SUCCESS
+
+--*/
+{
+  mPciAddress = IoRead32 (EFI_PCI_ADDRESS_PORT);
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+RestoreState (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Restore Index registers to avoid corrupting the foreground environment
+
+Arguments:
+  None
+
+Returns:
+  Status - EFI_SUCCESS
+
+--*/
+{
+  IoWrite32 (EFI_PCI_ADDRESS_PORT, mPciAddress);
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SmiInputValueDuplicateCheck (
+  UINTN           FedSwSmiInputValue
+  )
+/*++
+
+Routine Description:
+
+  Check the Fed SwSmiInputValue to see if there is a duplicated one in the database
+
+Arguments:
+  None
+
+Returns:
+  Status - EFI_SUCCESS, EFI_INVALID_PARAMETER
+
+--*/
+// GC_TODO:    FedSwSmiInputValue - add argument and description to function comment
+{
+
+  DATABASE_RECORD *RecordInDb;
+  LIST_ENTRY      *LinkInDb;
+
+  LinkInDb = GetFirstNode (&mPrivateData.CallbackDataBase);
+  while (!IsNull (&mPrivateData.CallbackDataBase, LinkInDb)) {
+    RecordInDb = DATABASE_RECORD_FROM_LINK (LinkInDb);
+
+    if (RecordInDb->ProtocolType == SwType) {
+      if (RecordInDb->ChildContext.Sw.SwSmiInputValue == FedSwSmiInputValue) {
+        return EFI_INVALID_PARAMETER;
+      }
+    }
+
+    LinkInDb = GetNextNode (&mPrivateData.CallbackDataBase, &RecordInDb->Link);
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+QNCSmmCoreRegister (
+  IN  QNC_SMM_GENERIC_PROTOCOL                          *This,
+  IN  EFI_SMM_HANDLER_ENTRY_POINT2                      DispatchFunction,
+  IN  QNC_SMM_CONTEXT                                    *RegisterContext,
+  OUT EFI_HANDLE                                        *DispatchHandle
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+// GC_TODO:    This - add argument and description to function comment
+// GC_TODO:    DispatchFunction - add argument and description to function comment
+// GC_TODO:    RegisterContext - add argument and description to function comment
+// GC_TODO:    DispatchHandle - add argument and description to function comment
+// GC_TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment
+// GC_TODO:    EFI_INVALID_PARAMETER - add return value to function comment
+// GC_TODO:    EFI_SUCCESS - add return value to function comment
+// GC_TODO:    EFI_INVALID_PARAMETER - add return value to function comment
+{
+  EFI_STATUS                  Status;
+  DATABASE_RECORD             *Record;
+  QNC_SMM_QUALIFIED_PROTOCOL  *Qualified;
+  INTN                        Index;
+
+  //
+  // Check for invalid parameter
+  //
+  if (This == NULL || RegisterContext == NULL || DispatchHandle == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Create database record and add to database
+  //
+  Record = (DATABASE_RECORD *) AllocateZeroPool (sizeof (DATABASE_RECORD));
+  if (Record == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Gather information about the registration request
+  //
+  Record->Callback          = DispatchFunction;
+  Record->CallbackContext   = RegisterContext;
+  CopyMem (&Record->ChildContext, RegisterContext, sizeof (QNC_SMM_CONTEXT));
+
+  Qualified                 = QUALIFIED_PROTOCOL_FROM_GENERIC (This);
+
+  Record->ProtocolType      = Qualified->Type;
+
+  CopyMem (&Record->ContextFunctions, &mContextFunctions[Qualified->Type], sizeof (Record->ContextFunctions));
+  //
+  // Perform linked list housekeeping
+  //
+  Record->Signature = DATABASE_RECORD_SIGNATURE;
+
+  switch (Qualified->Type) {
+  //
+  // By the end of this switch statement, we'll know the
+  // source description the child is registering for
+  //
+  case SxType:
+    //
+    // Check the validity of Context Type and Phase
+    //
+    if ((Record->ChildContext.Sx.Type < SxS0) ||
+        (Record->ChildContext.Sx.Type >= EfiMaximumSleepType) ||
+        (Record->ChildContext.Sx.Phase < SxEntry) ||
+        (Record->ChildContext.Sx.Phase >= EfiMaximumPhase)
+        ) {
+      goto Error;
+    }
+
+    InsertTailList (&mPrivateData.CallbackDataBase, &Record->Link);
+    CopyMem (&Record->SrcDesc, &SX_SOURCE_DESC, sizeof (Record->SrcDesc));
+    //
+    // use default clear source function
+    //
+    break;
+
+  case SwType:
+    if (RegisterContext->Sw.SwSmiInputValue == (UINTN)-1) {
+      //
+      // If SwSmiInputValue is set to (UINTN) -1 then a unique value will be assigned and returned in the structure.
+      //
+      Status = EFI_NOT_FOUND;
+      for (Index = 1; Index < MAXIMUM_SWI_VALUE; Index++) {
+        Status = SmiInputValueDuplicateCheck (Index);
+        if (!EFI_ERROR (Status)) {
+          RegisterContext->Sw.SwSmiInputValue = Index;
+          break;
+        }
+      }
+      if (RegisterContext->Sw.SwSmiInputValue == (UINTN)-1) {
+        Status = gSmst->SmmFreePool (Record);
+        return EFI_OUT_OF_RESOURCES;
+      }
+      //
+      // Update ChildContext again as SwSmiInputValue has been changed
+      //
+      CopyMem (&Record->ChildContext, RegisterContext, sizeof (QNC_SMM_CONTEXT));
+    }
+
+    //
+    // Check the validity of Context Value
+    //
+    if (Record->ChildContext.Sw.SwSmiInputValue > MAXIMUM_SWI_VALUE) {
+      goto Error;
+    }
+
+    if (EFI_ERROR (SmiInputValueDuplicateCheck (Record->ChildContext.Sw.SwSmiInputValue))) {
+      goto Error;
+    }
+
+    InsertTailList (&mPrivateData.CallbackDataBase, &Record->Link);
+    CopyMem (&Record->SrcDesc, &SW_SOURCE_DESC, sizeof (Record->SrcDesc));
+    Record->BufferSize = sizeof (EFI_SMM_SW_REGISTER_CONTEXT);
+    //
+    // use default clear source function
+    //
+    break;
+
+  case GpiType:
+
+    InsertTailList (&mPrivateData.CallbackDataBase, &Record->Link);
+    CopyMem (&Record->SrcDesc, &GPI_SOURCE_DESC, sizeof (Record->SrcDesc));
+    //
+    // use default clear source function
+    //
+    break;
+
+  case QNCnType:
+    //
+    // Check the validity of Context Type
+    //
+    if ((Record->ChildContext.QNCn.Type < IchnMch) || (Record->ChildContext.QNCn.Type >= NUM_ICHN_TYPES)) {
+      goto Error;
+    }
+
+    InsertTailList (&mPrivateData.CallbackDataBase, &Record->Link);
+    CopyMem (&Record->SrcDesc, &QNCN_SOURCE_DESCS[Record->ChildContext.QNCn.Type], sizeof (Record->SrcDesc));
+    Record->ClearSource = QNCSmmQNCnClearSource;
+    break;
+
+  case PeriodicTimerType:
+
+    Status = MapPeriodicTimerToSrcDesc (RegisterContext, &(Record->SrcDesc));
+    if (EFI_ERROR (Status)) {
+      goto Error;
+    }
+
+    InsertTailList (&mPrivateData.CallbackDataBase, &Record->Link);
+    Record->BufferSize = sizeof (EFI_SMM_PERIODIC_TIMER_CONTEXT);
+    Record->ClearSource = QNCSmmPeriodicTimerClearSource;
+    break;
+
+  default:
+    goto Error;
+    break;
+  };
+
+  if (Record->ClearSource == NULL) {
+    //
+    // Clear the SMI associated w/ the source using the default function
+    //
+    QNCSmmClearSource (&Record->SrcDesc);
+  } else {
+    //
+    // This source requires special handling to clear
+    //
+    Record->ClearSource (&Record->SrcDesc);
+  }
+
+  QNCSmmEnableSource (&Record->SrcDesc);
+
+  //
+  // Child's handle will be the address linked list link in the record
+  //
+  *DispatchHandle = (EFI_HANDLE) (&Record->Link);
+
+  return EFI_SUCCESS;
+
+Error:
+  FreePool (Record);
+  //
+  // DEBUG((EFI_D_ERROR,"Free pool status %d\n", Status ));
+  //
+  return EFI_INVALID_PARAMETER;
+}
+
+EFI_STATUS
+QNCSmmCoreUnRegister (
+  IN QNC_SMM_GENERIC_PROTOCOL                         *This,
+  IN EFI_HANDLE                                        DispatchHandle
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+// GC_TODO:    This - add argument and description to function comment
+// GC_TODO:    DispatchHandle - add argument and description to function comment
+// GC_TODO:    EFI_INVALID_PARAMETER - add return value to function comment
+// GC_TODO:    EFI_INVALID_PARAMETER - add return value to function comment
+// GC_TODO:    EFI_SUCCESS - add return value to function comment
+{
+  BOOLEAN         SafeToDisable;
+  DATABASE_RECORD *RecordToDelete;
+  DATABASE_RECORD *RecordInDb;
+  LIST_ENTRY      *LinkInDb;
+
+  if (DispatchHandle == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (BASE_CR (DispatchHandle, DATABASE_RECORD, Link)->Signature != DATABASE_RECORD_SIGNATURE) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  RecordToDelete = DATABASE_RECORD_FROM_LINK (DispatchHandle);
+
+  RemoveEntryList (&RecordToDelete->Link);
+  RecordToDelete->Signature = 0;
+
+  //
+  // See if we can disable the source, reserved for future use since this might
+  //  not be the only criteria to disable
+  //
+  SafeToDisable = TRUE;
+  LinkInDb = GetFirstNode (&mPrivateData.CallbackDataBase);
+  while(!IsNull (&mPrivateData.CallbackDataBase, LinkInDb)) {
+    RecordInDb = DATABASE_RECORD_FROM_LINK (LinkInDb);
+    if (CompareEnables (&RecordToDelete->SrcDesc, &RecordInDb->SrcDesc)) {
+      SafeToDisable = FALSE;
+      break;
+    }
+    LinkInDb = GetNextNode (&mPrivateData.CallbackDataBase, &RecordInDb->Link);
+  }
+  if (SafeToDisable) {
+    QNCSmmDisableSource( &RecordToDelete->SrcDesc );
+}
+
+  FreePool (RecordToDelete);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function is the main entry point for an SMM handler dispatch
+  or communicate-based callback.
+
+  @param  DispatchHandle  The unique handle assigned to this handler by SmiHandlerRegister().
+  @param  RegisterContext Points to an optional handler context which was specified when the handler was registered.
+  @param  CommBuffer      A pointer to a collection of data in memory that will
+                          be conveyed from a non-SMM environment into an SMM environment.
+  @param  CommBufferSize  The size of the CommBuffer.
+
+  @return Status Code
+
+**/
+EFI_STATUS
+QNCSmmCoreDispatcher (
+  IN     EFI_HANDLE               DispatchHandle,
+  IN     CONST VOID               *RegisterContext,
+  IN OUT VOID                     *CommBuffer,
+  IN OUT UINTN                    *CommBufferSize
+  )
+{
+  //
+  // Used to prevent infinite loops
+  //
+  UINTN               EscapeCount;
+
+  BOOLEAN             ContextsMatch;
+  BOOLEAN             ResetListSearch;
+  BOOLEAN             EosSet;
+  BOOLEAN             SxChildWasDispatched;
+  BOOLEAN             ChildWasDispatched;
+
+  DATABASE_RECORD     *RecordInDb;
+  DATABASE_RECORD     ActiveRecordInDb;
+  LIST_ENTRY          *LinkInDb;
+  DATABASE_RECORD     *RecordToExhaust;
+  LIST_ENTRY          *LinkToExhaust;
+
+  QNC_SMM_CONTEXT     Context;
+  VOID                *CommunicationBuffer;
+  UINTN               BufferSize;
+
+  EFI_STATUS          Status;
+  UINT32              NewValue;
+
+  QNC_SMM_SOURCE_DESC ActiveSource = NULL_SOURCE_DESC_INITIALIZER;
+
+  EscapeCount           = 100;
+  ContextsMatch         = FALSE;
+  ResetListSearch       = FALSE;
+  EosSet                = FALSE;
+  SxChildWasDispatched  = FALSE;
+  Status                = EFI_WARN_INTERRUPT_SOURCE_PENDING;
+  ChildWasDispatched    = FALSE;
+
+  //
+  // Mark all child handlers as not processed
+  //
+  LinkInDb = GetFirstNode (&mPrivateData.CallbackDataBase);
+  while (!IsNull (&mPrivateData.CallbackDataBase, LinkInDb)) {
+    RecordInDb = DATABASE_RECORD_FROM_LINK (LinkInDb);
+    RecordInDb->Processed = FALSE;
+    LinkInDb = GetNextNode (&mPrivateData.CallbackDataBase, LinkInDb);
+  }
+
+  //
+  // Preserve Index registers
+  //
+  SaveState ();
+
+  if (!IsListEmpty (&mPrivateData.CallbackDataBase)) {
+    //
+    // We have children registered w/ us -- continue
+    //
+    while ((!EosSet) && (EscapeCount > 0)) {
+      EscapeCount--;
+
+      //
+      // Reset this flag in order to be able to process multiple SMI Sources in one loop.
+      //
+      ResetListSearch = FALSE;
+
+      LinkInDb = GetFirstNode (&mPrivateData.CallbackDataBase);
+
+      while ((!IsNull (&mPrivateData.CallbackDataBase, LinkInDb)) && (ResetListSearch == FALSE)) {
+        RecordInDb = DATABASE_RECORD_FROM_LINK (LinkInDb);
+        //
+        // Make a copy of the record that contains an active SMI source,
+        // because un-register maybe invoked in callback function and
+        // RecordInDb maybe released
+        //
+        CopyMem (&ActiveRecordInDb, RecordInDb, sizeof (ActiveRecordInDb));
+
+        //
+        // look for the first active source
+        //
+        if (!SourceIsActive (&RecordInDb->SrcDesc)) {
+          //
+          // Didn't find the source yet, keep looking
+          //
+          LinkInDb = GetNextNode (&mPrivateData.CallbackDataBase, &RecordInDb->Link);
+
+        } else {
+          //
+          // We found a source. If this is a sleep type, we have to go to
+          // appropriate sleep state anyway.No matter there is sleep child or not
+          //
+          if (RecordInDb->ProtocolType == SxType) {
+            SxChildWasDispatched = TRUE;
+          }
+          //
+          // "cache" the source description and don't query I/O anymore
+          //
+          CopyMem (&ActiveSource, &RecordInDb->SrcDesc, sizeof (ActiveSource));
+          LinkToExhaust = LinkInDb;
+
+          //
+          // exhaust the rest of the queue looking for the same source
+          //
+          while (!IsNull (&mPrivateData.CallbackDataBase, LinkToExhaust)) {
+            RecordToExhaust = DATABASE_RECORD_FROM_LINK (LinkToExhaust);
+            LinkToExhaust = GetNextNode (&mPrivateData.CallbackDataBase, LinkToExhaust);
+            if (RecordToExhaust->Processed) {
+              //
+              // Record has already been processed.  Continue with next child handler.
+              //
+              continue;
+            }
+
+            if (CompareSources (&RecordToExhaust->SrcDesc, &ActiveSource)) {
+              //
+              // These source descriptions are equal, so this callback should be
+              // dispatched.
+              //
+              if (RecordToExhaust->ContextFunctions.GetContext != NULL) {
+                //
+                // This child requires that we get a calling context from
+                // hardware and compare that context to the one supplied
+                // by the child.
+                //
+                ASSERT (RecordToExhaust->ContextFunctions.CmpContext != NULL);
+
+                //
+                // Make sure contexts match before dispatching event to child
+                //
+                RecordToExhaust->ContextFunctions.GetContext (RecordToExhaust, &Context);
+                ContextsMatch = RecordToExhaust->ContextFunctions.CmpContext (&Context, &RecordToExhaust->ChildContext);
+
+              } else {
+                //
+                // This child doesn't require any more calling context beyond what
+                // it supplied in registration.  Simply pass back what it gave us.
+                //
+                ASSERT (RecordToExhaust->Callback != NULL);
+                ContextsMatch = TRUE;
+              }
+
+              //
+              // Mark this child handler so it will not be processed again
+              //
+              RecordToExhaust->Processed = TRUE;
+
+              if (ContextsMatch) {
+
+                if (RecordToExhaust->BufferSize != 0) {
+                  ASSERT (RecordToExhaust->ContextFunctions.GetBuffer != NULL);
+
+                  RecordToExhaust->ContextFunctions.GetBuffer (RecordToExhaust);
+
+                  CommunicationBuffer = &RecordToExhaust->CommBuffer;
+                  BufferSize = RecordToExhaust->BufferSize;
+                } else {
+                  CommunicationBuffer = NULL;
+                  BufferSize = 0;
+                }
+
+                ASSERT (RecordToExhaust->Callback != NULL);
+
+                RecordToExhaust->Callback (
+                                   (EFI_HANDLE) & RecordToExhaust->Link,
+                                   RecordToExhaust->CallbackContext,
+                                   CommunicationBuffer,
+                                   &BufferSize
+                                   );
+
+                ChildWasDispatched = TRUE;
+                if (RecordToExhaust->ProtocolType == SxType) {
+                  SxChildWasDispatched = TRUE;
+                }
+              }
+              //
+              // Can not use RecordInDb after this point because Callback may have unregistered RecordInDb
+              // Restart processing of SMI handlers from the begining of the linked list because the
+              // state of the linked listed may have been modified due to unregister actions in the Callback.
+              //
+              LinkToExhaust = GetFirstNode (&mPrivateData.CallbackDataBase);
+            }
+          }
+
+          if (ActiveRecordInDb.ClearSource == NULL) {
+            //
+            // Clear the SMI associated w/ the source using the default function
+            //
+            QNCSmmClearSource (&ActiveSource);
+          } else {
+            //
+            // This source requires special handling to clear
+            //
+            ActiveRecordInDb.ClearSource (&ActiveSource);
+          }
+
+          if (ChildWasDispatched) {
+            //
+            // The interrupt was handled and quiesced
+            //
+            Status = EFI_SUCCESS;
+          } else {
+            //
+            // The interrupt was not handled but quiesced
+            //
+            Status = EFI_WARN_INTERRUPT_SOURCE_QUIESCED;
+          }
+
+          //
+          // Queue is empty, reset the search
+          //
+          ResetListSearch = TRUE;
+
+        }
+      }
+      EosSet = QNCSmmSetAndCheckEos ();
+    }
+  }
+  //
+  // If you arrive here, there are two possible reasons:
+  // (1) you've got problems with clearing the SMI status bits in the
+  // ACPI table.  If you don't properly clear the SMI bits, then you won't be able to set the
+  // EOS bit.  If this happens too many times, the loop exits.
+  // (2) there was a SMM communicate for callback messages that was received prior
+  // to this driver.
+  // If there is an asynchronous SMI that occurs while processing the Callback, let
+  // all of the drivers (including this one) have an opportunity to scan for the SMI
+  // and handle it.
+  // If not, we don't want to exit and have the foreground app. clear EOS without letting
+  // these other sources get serviced.
+  //
+  ASSERT (EscapeCount > 0);
+
+  //
+  // Restore Index registers
+  //
+  RestoreState ();
+
+  if (SxChildWasDispatched) {
+    //
+    // A child of the SmmSxDispatch protocol was dispatched during this call;
+    // put the system to sleep.
+    //
+    QNCSmmSxGoToSleep ();
+  }
+
+  //
+  // Ensure that SMI signal pin indicator is clear at the end of SMM handling.
+  //
+  NewValue = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QUARK_NC_HOST_BRIDGE_HLEGACY_REG);
+  NewValue &= ~(HLEGACY_SMI_PIN_VALUE);
+  QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QUARK_NC_HOST_BRIDGE_HLEGACY_REG, NewValue);
+
+  return Status;
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmDispatcher.inf b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmDispatcher.inf
new file mode 100644
index 0000000000..dec3c5043a
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmDispatcher.inf
@@ -0,0 +1,81 @@
+## @file
+# Component description file for QuarkNcSocId SmmDispatcher module.
+#
+# This driver is responsible for the registration of child drivers
+#  and the abstraction of the ICH SMI sources.
+# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = QNCSmmDispatcher
+  FILE_GUID                      = 2480271C-09C6-4f36-AD75-5E1390BD9929
+  MODULE_TYPE                    = DXE_SMM_DRIVER
+  VERSION_STRING                 = 1.0
+  PI_SPECIFICATION_VERSION       = 0x0001000A
+  ENTRY_POINT                    = InitializeQNCSmmDispatcher
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  QNC/QNCSmmPeriodicTimer.c
+  QNC/QNCSmmQncn.c
+  QNC/QNCSmmSx.c
+  QNC/QNCSmmSw.c
+  QNC/QNCSmmGpi.c
+  QNC/QNCSmmHelpers.c
+  QNCSmmHelpers.c
+  QNCSmmCore.c
+  QNCSmmHelpers.h
+  QNCxSmmHelpers.h
+  QNCSmmRegisters.h
+  QNCSmm.h
+  CommonHeader.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  SmmServicesTableLib
+  UefiBootServicesTableLib
+  DxeServicesTableLib
+  MemoryAllocationLib
+  PciLib
+  PcdLib
+  BaseMemoryLib
+  DebugLib
+  BaseLib
+  IoLib
+  DevicePathLib
+  S3IoLib
+  QNCAccessLib
+
+[Protocols]
+  gEfiSmmCpuProtocolGuid                        # PROTOCOL ALWAYS_CONSUMED
+  gEfiSmmReadyToLockProtocolGuid                # PROTOCOL ALWAYS_CONSUMED
+  gEfiSmmPeriodicTimerDispatch2ProtocolGuid     # PROTOCOL ALWAYS_PRODUCED
+  gEfiSmmPowerButtonDispatch2ProtocolGuid       # PROTOCOL ALWAYS_PRODUCED
+  gEfiSmmIchnDispatch2ProtocolGuid              # PROTOCOL ALWAYS_PRODUCED
+  gEfiSmmGpiDispatch2ProtocolGuid               # PROTOCOL ALWAYS_PRODUCED
+  gEfiSmmSwDispatch2ProtocolGuid                # PROTOCOL ALWAYS_PRODUCED
+  gEfiSmmSxDispatch2ProtocolGuid                # PROTOCOL ALWAYS_PRODUCED
+  gEfiSmmUsbDispatch2ProtocolGuid               # PROTOCOL ALWAYS_PRODUCED
+  gEfiSmmIoTrapDispatch2ProtocolGuid            # PROTOCOL ALWAYS_PRODUCED
+
+[Pcd]
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPm1blkIoBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdGpe0blkIoBaseAddress
+
+[Depex]
+  gEfiSmmCpuProtocolGuid AND gEfiPciRootBridgeIoProtocolGuid
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmHelpers.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmHelpers.c
new file mode 100644
index 0000000000..38729c94ca
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmHelpers.c
@@ -0,0 +1,367 @@
+/** @file
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+//
+// Include common header file for this module.
+//
+#include "CommonHeader.h"
+
+#include "QNCSmm.h"
+#include "QNCSmmHelpers.h"
+
+//
+// #define BIT_ZERO 0x00000001
+//
+CONST UINT32  BIT_ZERO = 0x00000001;
+
+//
+// /////////////////////////////////////////////////////////////////////////////
+// SUPPORT / HELPER FUNCTIONS (QNC version-independent)
+//
+BOOLEAN
+CompareEnables (
+  CONST IN QNC_SMM_SOURCE_DESC *Src1,
+  CONST IN QNC_SMM_SOURCE_DESC *Src2
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  Src1  - GC_TODO: add argument description
+  Src2  - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+{
+  BOOLEAN IsEqual;
+  UINTN   loopvar;
+
+  IsEqual = TRUE;
+  for (loopvar = 0; loopvar < NUM_EN_BITS; loopvar++) {
+    //
+    // It's okay to compare a NULL bit description to a non-NULL bit description.
+    // They are unequal and these tests will generate the correct result.
+    //
+    if (Src1->En[loopvar].Bit != Src2->En[loopvar].Bit ||
+        Src1->En[loopvar].Reg.Type != Src2->En[loopvar].Reg.Type ||
+        Src1->En[loopvar].Reg.Data.raw != Src2->En[loopvar].Reg.Data.raw
+        ) {
+      IsEqual = FALSE;
+      break;
+      //
+      // out of for loop
+      //
+    }
+  }
+
+  return IsEqual;
+}
+
+BOOLEAN
+CompareStatuses (
+  CONST IN QNC_SMM_SOURCE_DESC *Src1,
+  CONST IN QNC_SMM_SOURCE_DESC *Src2
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  Src1  - GC_TODO: add argument description
+  Src2  - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+{
+  BOOLEAN IsEqual;
+  UINTN   loopvar;
+
+  IsEqual = TRUE;
+
+  for (loopvar = 0; loopvar < NUM_STS_BITS; loopvar++) {
+    //
+    // It's okay to compare a NULL bit description to a non-NULL bit description.
+    // They are unequal and these tests will generate the correct result.
+    //
+    if (Src1->Sts[loopvar].Bit != Src2->Sts[loopvar].Bit ||
+        Src1->Sts[loopvar].Reg.Type != Src2->Sts[loopvar].Reg.Type ||
+        Src1->Sts[loopvar].Reg.Data.raw != Src2->Sts[loopvar].Reg.Data.raw
+        ) {
+      IsEqual = FALSE;
+      break;
+      //
+      // out of for loop
+      //
+    }
+  }
+
+  return IsEqual;
+}
+
+BOOLEAN
+CompareSources (
+  CONST IN QNC_SMM_SOURCE_DESC *Src1,
+  CONST IN QNC_SMM_SOURCE_DESC *Src2
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  Src1  - GC_TODO: add argument description
+  Src2  - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+{
+  return (BOOLEAN) (CompareEnables (Src1, Src2) && CompareStatuses (Src1, Src2));
+}
+
+BOOLEAN
+SourceIsActive (
+  CONST IN QNC_SMM_SOURCE_DESC *Src
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  Src - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+{
+  BOOLEAN IsActive;
+  UINTN   loopvar;
+
+  BOOLEAN SciEn;
+
+  IsActive  = TRUE;
+
+  SciEn     = QNCSmmGetSciEn ();
+
+  if ((Src->Flags & QNC_SMM_SCI_EN_DEPENDENT) && (SciEn)) {
+    //
+    // This source is dependent on SciEn, and SciEn == 1.  An ACPI OS is present,
+    // so we shouldn't do anything w/ this source until SciEn == 0.
+    //
+    IsActive = FALSE;
+
+  } else {
+    //
+    // Read each bit desc from hardware and make sure it's a one
+    //
+    for (loopvar = 0; loopvar < NUM_EN_BITS; loopvar++) {
+
+      if (!IS_BIT_DESC_NULL (Src->En[loopvar])) {
+
+        if (ReadBitDesc (&Src->En[loopvar]) == 0) {
+          IsActive = FALSE;
+          break;
+          //
+          // out of for loop
+          //
+        }
+
+      }
+    }
+
+    if (IsActive) {
+      //
+      // Read each bit desc from hardware and make sure it's a one
+      //
+      for (loopvar = 0; loopvar < NUM_STS_BITS; loopvar++) {
+
+        if (!IS_BIT_DESC_NULL (Src->Sts[loopvar])) {
+
+          if (ReadBitDesc (&Src->Sts[loopvar]) == 0) {
+            IsActive = FALSE;
+            break;
+            //
+            // out of for loop
+            //
+          }
+
+        }
+      }
+    }
+  }
+
+  return IsActive;
+}
+
+VOID
+QNCSmmEnableSource (
+  CONST QNC_SMM_SOURCE_DESC *SrcDesc
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  SrcDesc - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+{
+  UINTN loopvar;
+
+  //
+  // Set enables to 1 by writing a 1
+  //
+  for (loopvar = 0; loopvar < NUM_EN_BITS; loopvar++) {
+    if (!IS_BIT_DESC_NULL (SrcDesc->En[loopvar])) {
+      WriteBitDesc (&SrcDesc->En[loopvar], 1);
+    }
+  }
+
+  QNCSmmClearSource (SrcDesc);
+
+}
+
+VOID
+QNCSmmDisableSource (
+  CONST QNC_SMM_SOURCE_DESC *SrcDesc
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  SrcDesc - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+{
+  UINTN loopvar;
+
+  for (loopvar = 0; loopvar < NUM_EN_BITS; loopvar++) {
+    if (!IS_BIT_DESC_NULL (SrcDesc->En[loopvar])) {
+      WriteBitDesc (&SrcDesc->En[loopvar], 0);
+    }
+  }
+}
+
+VOID
+QNCSmmClearSource (
+  CONST QNC_SMM_SOURCE_DESC *SrcDesc
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  SrcDesc - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+{
+  UINTN loopvar;
+  BOOLEAN ValueToWrite;
+
+  ValueToWrite =
+    ((SrcDesc->Flags & QNC_SMM_CLEAR_WITH_ZERO) == 0) ? TRUE : FALSE;
+
+  for (loopvar = 0; loopvar < NUM_STS_BITS; loopvar++) {
+    if (!IS_BIT_DESC_NULL (SrcDesc->Sts[loopvar])) {
+      WriteBitDesc (&SrcDesc->Sts[loopvar], ValueToWrite);
+    }
+  }
+}
+
+VOID
+QNCSmmClearSourceAndBlock (
+  CONST QNC_SMM_SOURCE_DESC *SrcDesc
+  )
+// GC_TODO: function comment should start with '/*++'
+/*
+  Sets the source to a 1 or 0 and then waits for it to clear.
+  Be very careful when calling this function -- it will not
+  ASSERT.  An acceptable case to call the function is when
+  waiting for the NEWCENTURY_STS bit to clear (which takes
+  3 RTCCLKs).
+*/
+// GC_TODO: function comment should end with '--*/'
+// GC_TODO: function comment is missing 'Routine Description:'
+// GC_TODO: function comment is missing 'Arguments:'
+// GC_TODO: function comment is missing 'Returns:'
+// GC_TODO:    SrcDesc - add argument and description to function comment
+{
+  UINTN   loopvar;
+  BOOLEAN IsSet;
+  BOOLEAN ValueToWrite;
+
+  ValueToWrite =
+    ((SrcDesc->Flags & QNC_SMM_CLEAR_WITH_ZERO) == 0) ? TRUE : FALSE;
+
+  for (loopvar = 0; loopvar < NUM_STS_BITS; loopvar++) {
+
+    if (!IS_BIT_DESC_NULL (SrcDesc->Sts[loopvar])) {
+      //
+      // Write the bit
+      //
+      WriteBitDesc (&SrcDesc->Sts[loopvar], ValueToWrite);
+
+      //
+      // Don't return until the bit actually clears.
+      //
+      IsSet = TRUE;
+      while (IsSet) {
+        IsSet = ReadBitDesc (&SrcDesc->Sts[loopvar]);
+        //
+        // IsSet will eventually clear -- or else we'll have
+        // an infinite loop.
+        //
+      }
+    }
+  }
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmHelpers.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmHelpers.h
new file mode 100644
index 0000000000..0cd26da904
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmHelpers.h
@@ -0,0 +1,219 @@
+/** @file
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef QNC_SMM_HELPERS_H
+#define QNC_SMM_HELPERS_H
+
+//
+// Include common header file for this module.
+//
+#include "CommonHeader.h"
+
+#include "QNCSmm.h"
+#include "QNCxSmmHelpers.h"
+
+//
+// /////////////////////////////////////////////////////////////////////////////
+// SUPPORT / HELPER FUNCTIONS (QNC version-independent)
+//
+VOID
+QNCSmmPublishDispatchProtocols (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  None
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+CompareEnables (
+  CONST IN QNC_SMM_SOURCE_DESC *Src1,
+  CONST IN QNC_SMM_SOURCE_DESC *Src2
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  Src1  - GC_TODO: add argument description
+  Src2  - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+CompareStatuses (
+  CONST IN QNC_SMM_SOURCE_DESC *Src1,
+  CONST IN QNC_SMM_SOURCE_DESC *Src2
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  Src1  - GC_TODO: add argument description
+  Src2  - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+CompareSources (
+  CONST IN QNC_SMM_SOURCE_DESC *Src1,
+  CONST IN QNC_SMM_SOURCE_DESC *Src2
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  Src1  - GC_TODO: add argument description
+  Src2  - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+SourceIsActive (
+  CONST IN QNC_SMM_SOURCE_DESC *Src
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  Src - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+VOID
+QNCSmmEnableSource (
+  CONST QNC_SMM_SOURCE_DESC *SrcDesc
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  SrcDesc - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+VOID
+QNCSmmDisableSource (
+  CONST QNC_SMM_SOURCE_DESC *SrcDesc
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  SrcDesc - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+VOID
+QNCSmmClearSource (
+  CONST QNC_SMM_SOURCE_DESC *SrcDesc
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  SrcDesc - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+VOID
+QNCSmmClearSourceAndBlock (
+  CONST QNC_SMM_SOURCE_DESC *SrcDesc
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  SrcDesc - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmRegisters.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmRegisters.h
new file mode 100644
index 0000000000..aec0c70283
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmRegisters.h
@@ -0,0 +1,13 @@
+/** @file
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef QNC_SMM_REGISTERS_H
+#define QNC_SMM_REGISTERS_H
+#include "CommonHeader.h"
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCxSmmHelpers.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCxSmmHelpers.h
new file mode 100644
index 0000000000..3f89b6411f
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCxSmmHelpers.h
@@ -0,0 +1,178 @@
+/** @file
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef QNCX_SMM_HELPERS_H
+#define QNCX_SMM_HELPERS_H
+
+//
+// Include common header file for this module.
+//
+#include "CommonHeader.h"
+
+#include "QNCSmm.h"
+
+EFI_STATUS
+QNCSmmInitHardware (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  None
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+QNCSmmEnableGlobalSmiBit (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Enables the QNC to generate SMIs. Note that no SMIs will be generated
+  if no SMI sources are enabled. Conversely, no enabled SMI source will
+  generate SMIs if SMIs are not globally enabled. This is the main
+  switchbox for SMI generation.
+
+Arguments:
+
+  None
+
+Returns:
+
+  EFI_SUCCESS.
+  Asserts, otherwise.
+
+--*/
+;
+
+EFI_STATUS
+QNCSmmClearSmi (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  None
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+QNCSmmSetAndCheckEos (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  None
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+QNCSmmGetSciEn (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  None
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+//
+// ///////////////////////////////////////////////////////////////////////////
+//
+// These may or may not need to change w/ the QNC version;
+// they're here because they're highly IA-32 dependent.
+//
+BOOLEAN
+ReadBitDesc (
+  CONST QNC_SMM_BIT_DESC *BitDesc
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  BitDesc - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+VOID
+WriteBitDesc (
+  CONST QNC_SMM_BIT_DESC  *BitDesc,
+  CONST BOOLEAN          ValueToWrite
+  )
+/*++
+
+Routine Description:
+
+  GC_TODO: Add function description
+
+Arguments:
+
+  BitDesc       - GC_TODO: add argument description
+  ValueToWrite  - GC_TODO: add argument description
+
+Returns:
+
+  GC_TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmAccessPei/SmmAccessPei.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmAccessPei/SmmAccessPei.c
new file mode 100644
index 0000000000..637792d147
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmAccessPei/SmmAccessPei.c
@@ -0,0 +1,376 @@
+/** @file
+This is the driver that publishes the SMM Access Ppi
+instance for the Quark SOC.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <PiPei.h>
+#include <Ppi/SmmAccess.h>
+#include <Guid/SmramMemoryReserve.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PciLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/QNCSmmLib.h>
+#include <QNCAccess.h>
+
+#define SMM_ACCESS_PRIVATE_DATA_FROM_THIS(a) \
+  CR ( \
+  a, \
+  SMM_ACCESS_PRIVATE_DATA, \
+  SmmAccess, \
+  SMM_ACCESS_PRIVATE_DATA_SIGNATURE \
+  )
+
+#define MAX_CPU_SOCKET      1
+#define MAX_SMRAM_RANGES    4
+
+typedef struct {
+  UINTN                            Signature;
+  EFI_HANDLE                       Handle;
+  PEI_SMM_ACCESS_PPI               SmmAccess;
+  UINTN                            NumberRegions;
+  EFI_SMRAM_DESCRIPTOR             SmramDesc[MAX_SMRAM_RANGES];
+  UINT8                            TsegSize;
+  UINT8                            MaxBusNumber;
+  UINT8                            SocketPopulated[MAX_CPU_SOCKET];
+  UINT8                            SocketBusNum[MAX_CPU_SOCKET];
+} SMM_ACCESS_PRIVATE_DATA;
+
+#define  SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('i', 's', 'm', 'a')
+
+
+EFI_STATUS
+EFIAPI
+Open (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN PEI_SMM_ACCESS_PPI         *This,
+  IN UINTN                      DescriptorIndex
+  )
+/*++
+
+Routine Description:
+
+  This routine accepts a request to "open" a region of SMRAM.  The
+  region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
+  The use of "open" means that the memory is visible from all PEIM
+  and SMM agents.
+
+Arguments:
+
+  PeiServices      - General purpose services available to every PEIM.
+  This             -  Pointer to the SMM Access Interface.
+  DescriptorIndex  -  Region of SMRAM to Open.
+
+Returns:
+
+  EFI_SUCCESS            -  The region was successfully opened.
+  EFI_DEVICE_ERROR       -  The region could not be opened because locked by
+                            chipset.
+  EFI_INVALID_PARAMETER  -  The descriptor index was out of bounds.
+
+--*/
+{
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+
+  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+
+  if (DescriptorIndex >= SmmAccess->NumberRegions) {
+    return EFI_INVALID_PARAMETER;
+  } else if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_LOCKED) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Open TSEG
+  //
+  if (!QNCOpenSmramRegion ()) {
+    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_LOCKED;
+    return EFI_DEVICE_ERROR;
+  }
+
+  SmmAccess->SmramDesc[DescriptorIndex].RegionState &= ~(EFI_SMRAM_CLOSED | EFI_ALLOCATED);
+  SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_OPEN;
+  SmmAccess->SmmAccess.OpenState = TRUE;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+Close (
+  IN EFI_PEI_SERVICES        **PeiServices,
+  IN PEI_SMM_ACCESS_PPI      *This,
+  IN UINTN                   DescriptorIndex
+  )
+/*++
+
+Routine Description:
+
+  This routine accepts a request to "close" a region of SMRAM.  This is valid for
+  compatible SMRAM region.
+
+Arguments:
+
+  PeiServices      - General purpose services available to every PEIM.
+  This             -  Pointer to the SMM Access Interface.
+  DescriptorIndex  -  Region of SMRAM to Close.
+
+Returns:
+
+  EFI_SUCCESS            -  The region was successfully closed.
+  EFI_DEVICE_ERROR       -  The region could not be closed because locked by
+                            chipset.
+  EFI_INVALID_PARAMETER  -  The descriptor index was out of bounds.
+
+--*/
+{
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+  BOOLEAN                 OpenState;
+  UINTN                   Index;
+
+
+  SmmAccess     = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+
+  if (DescriptorIndex >= SmmAccess->NumberRegions) {
+    return EFI_INVALID_PARAMETER;
+  } else if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_LOCKED) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_CLOSED) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Close TSEG
+  //
+  if (!QNCCloseSmramRegion ()) {
+    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_LOCKED;
+    return EFI_DEVICE_ERROR;
+  }
+
+  SmmAccess->SmramDesc[DescriptorIndex].RegionState &= ~EFI_SMRAM_OPEN;
+  SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (EFI_SMRAM_CLOSED | EFI_ALLOCATED);
+
+  //
+  // Find out if any regions are still open
+  //
+  OpenState = FALSE;
+  for (Index = 0; Index < SmmAccess->NumberRegions; Index++) {
+    if ((SmmAccess->SmramDesc[Index].RegionState & EFI_SMRAM_OPEN) == EFI_SMRAM_OPEN) {
+      OpenState = TRUE;
+    }
+  }
+
+  SmmAccess->SmmAccess.OpenState = OpenState;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+Lock (
+  IN EFI_PEI_SERVICES          **PeiServices,
+  IN PEI_SMM_ACCESS_PPI        *This,
+  IN UINTN                     DescriptorIndex
+  )
+/*++
+
+Routine Description:
+
+  This routine accepts a request to "lock" SMRAM.  The
+  region could be legacy AB or TSEG near top of physical memory.
+  The use of "lock" means that the memory can no longer be opened
+  to PEIM.
+
+Arguments:
+
+  PeiServices      - General purpose services available to every PEIM.
+  This             -  Pointer to the SMM Access Interface.
+  DescriptorIndex  -  Region of SMRAM to Lock.
+
+Returns:
+
+  EFI_SUCCESS            -  The region was successfully locked.
+  EFI_DEVICE_ERROR       -  The region could not be locked because at least
+                            one range is still open.
+  EFI_INVALID_PARAMETER  -  The descriptor index was out of bounds.
+
+--*/
+{
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+
+  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+
+  if (DescriptorIndex >= SmmAccess->NumberRegions) {
+    return EFI_INVALID_PARAMETER;
+  } else if (SmmAccess->SmmAccess.OpenState) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_LOCKED;
+  SmmAccess->SmmAccess.LockState                     = TRUE;
+
+  //
+  // Lock TSEG
+  //
+  QNCLockSmramRegion ();
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+GetCapabilities (
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN PEI_SMM_ACCESS_PPI              *This,
+  IN OUT UINTN                       *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
+  )
+/*++
+
+Routine Description:
+
+  This routine services a user request to discover the SMRAM
+  capabilities of this platform.  This will report the possible
+  ranges that are possible for SMRAM access, based upon the
+  memory controller capabilities.
+
+Arguments:
+
+  PeiServices   - General purpose services available to every PEIM.
+  This          -  Pointer to the SMRAM Access Interface.
+  SmramMapSize  -  Pointer to the variable containing size of the
+                   buffer to contain the description information.
+  SmramMap      -  Buffer containing the data describing the Smram
+                   region descriptors.
+Returns:
+
+  EFI_BUFFER_TOO_SMALL  -  The user did not provide a sufficient buffer.
+  EFI_SUCCESS           -  The user provided a sufficiently-sized buffer.
+
+--*/
+{
+  EFI_STATUS                Status;
+  SMM_ACCESS_PRIVATE_DATA  *SmmAccess;
+  UINTN                     BufferSize;
+
+  SmmAccess           = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+  BufferSize          = SmmAccess->NumberRegions * sizeof (EFI_SMRAM_DESCRIPTOR);
+
+  if (*SmramMapSize < BufferSize) {
+    Status = EFI_BUFFER_TOO_SMALL;
+  } else {
+    CopyMem (SmramMap, SmmAccess->SmramDesc, *SmramMapSize);
+    Status = EFI_SUCCESS;
+  }
+
+  *SmramMapSize = BufferSize;
+
+  return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+SmmAccessPeiEntryPoint (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+/*++
+
+Routine Description:
+
+    This is the constructor for the SMM Access Ppi
+
+Arguments:
+
+    FfsHeader       - FfsHeader.
+    PeiServices     - General purpose services available to every PEIM.
+
+Returns:
+
+  EFI_SUCCESS     -  Protocol successfully started and installed.
+  EFI_UNSUPPORTED -  Protocol can't be started.
+--*/
+{
+
+  EFI_STATUS                      Status;
+  UINTN                           Index;
+  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *DescriptorBlock;
+  SMM_ACCESS_PRIVATE_DATA         *SmmAccessPrivate;
+  EFI_PEI_PPI_DESCRIPTOR          *PpiList;
+  EFI_HOB_GUID_TYPE               *GuidHob;
+
+  //
+  // Initialize private data
+  //
+  SmmAccessPrivate = AllocatePool (sizeof(*SmmAccessPrivate));
+  ASSERT(SmmAccessPrivate);
+
+  PpiList = AllocatePool (sizeof(*PpiList));
+  ASSERT (PpiList);
+
+  //
+  // Build SMM related information
+  //
+  SmmAccessPrivate->Signature = SMM_ACCESS_PRIVATE_DATA_SIGNATURE;
+
+  //
+  // Get Hob list
+  //
+  GuidHob    = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid);
+  DescriptorBlock = GET_GUID_HOB_DATA (GuidHob);
+  ASSERT (DescriptorBlock);
+
+  // Get CPU Max bus number
+
+  SmmAccessPrivate->MaxBusNumber = PCI_BUS_NUMBER_QNC;
+  for (Index = 0; Index < MAX_CPU_SOCKET; Index++) {
+    SmmAccessPrivate->SocketPopulated[Index] = TRUE;
+    SmmAccessPrivate->SocketBusNum[Index]    = PCI_BUS_NUMBER_QNC;
+  }
+
+  //
+  // Use the hob to publish SMRAM capabilities
+  //
+  ASSERT (DescriptorBlock->NumberOfSmmReservedRegions <= MAX_SMRAM_RANGES);
+  for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
+    SmmAccessPrivate->SmramDesc[Index].PhysicalStart = DescriptorBlock->Descriptor[Index].PhysicalStart;
+    SmmAccessPrivate->SmramDesc[Index].CpuStart      = DescriptorBlock->Descriptor[Index].CpuStart;
+    SmmAccessPrivate->SmramDesc[Index].PhysicalSize  = DescriptorBlock->Descriptor[Index].PhysicalSize;
+    SmmAccessPrivate->SmramDesc[Index].RegionState   = DescriptorBlock->Descriptor[Index].RegionState;
+  }
+
+  SmmAccessPrivate->NumberRegions              = Index;
+  SmmAccessPrivate->SmmAccess.Open             = Open;
+  SmmAccessPrivate->SmmAccess.Close            = Close;
+  SmmAccessPrivate->SmmAccess.Lock             = Lock;
+  SmmAccessPrivate->SmmAccess.GetCapabilities  = GetCapabilities;
+  SmmAccessPrivate->SmmAccess.LockState        = FALSE;
+  SmmAccessPrivate->SmmAccess.OpenState        = FALSE;
+
+  PpiList->Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
+  PpiList->Guid  = &gPeiSmmAccessPpiGuid;
+  PpiList->Ppi   = &SmmAccessPrivate->SmmAccess;
+
+  Status      = (**PeiServices).InstallPpi (PeiServices, PpiList);
+  ASSERT_EFI_ERROR(Status);
+
+  DEBUG (
+    (EFI_D_INFO, "SMM Base:Size %08X:%08X\n",
+    (UINTN)(SmmAccessPrivate->SmramDesc[SmmAccessPrivate->NumberRegions-1].PhysicalStart),
+    (UINTN)(SmmAccessPrivate->SmramDesc[SmmAccessPrivate->NumberRegions-1].PhysicalSize)
+    ));
+
+  SmmAccessPrivate->TsegSize = (UINT8)(SmmAccessPrivate->SmramDesc[SmmAccessPrivate->NumberRegions-1].PhysicalSize);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmAccessPei/SmmAccessPei.inf b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmAccessPei/SmmAccessPei.inf
new file mode 100644
index 0000000000..34d90b26ea
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmAccessPei/SmmAccessPei.inf
@@ -0,0 +1,45 @@
+## @file
+# Component description file for SmmAccessPei module
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION          = 0x00010005
+BASE_NAME            = SmmAccessPei
+FILE_GUID            = B4E0CDFC-30CD-4b29-A445-B0AA95A532E4
+MODULE_TYPE          = PEIM
+VERSION_STRING       = 1.0
+ENTRY_POINT          = SmmAccessPeiEntryPoint
+
+[Sources]
+  SmmAccessPei.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  PeimEntryPoint
+  BaseMemoryLib
+  MemoryAllocationLib
+  DebugLib
+  HobLib
+  PeiServicesLib
+  PciLib
+  SmmLib
+
+[Guids]
+  gEfiSmmPeiSmramMemoryReserveGuid             # ALWAYS_CONSUMED
+
+[Ppis]
+  gPeiSmmAccessPpiGuid                         # ALWAYS_PRODUCED
+  gEfiPeiMemoryDiscoveredPpiGuid               # ALWAYS_CONSUMED
+
+[Depex]
+  gEfiPeiMemoryDiscoveredPpiGuid
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/SmmControlPei.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/SmmControlPei.c
new file mode 100644
index 0000000000..243e4c9e99
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/SmmControlPei.c
@@ -0,0 +1,274 @@
+/** @file
+This module provides an implementation of the SMM Control PPI for use with
+the QNC.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+#include <Ppi/SmmControl.h>
+
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+
+#include <IntelQNCPeim.h>
+#include <Library/QNCAccessLib.h>
+#include <Uefi/UefiBaseType.h>
+
+/**
+  Generates an SMI using the parameters passed in.
+
+  @param  PeiServices         Describes the list of possible PEI Services.
+  @param  This                A pointer to an instance of
+                              EFI_SMM_CONTROL_PPI
+  @param  ArgumentBuffer      The argument buffer
+  @param  ArgumentBufferSize  The size of the argument buffer
+  @param  Periodic            TRUE to indicate a periodical SMI
+  @param  ActivationInterval  Interval of the periodical SMI
+
+  @retval EFI_INVALID_PARAMETER  Periodic is TRUE or ArgumentBufferSize > 1
+  @retval EFI_SUCCESS            SMI generated
+
+**/
+EFI_STATUS
+EFIAPI
+PeiActivate (
+  IN      EFI_PEI_SERVICES           **PeiServices,
+  IN      PEI_SMM_CONTROL_PPI        *This,
+  IN OUT  INT8                       *ArgumentBuffer OPTIONAL,
+  IN OUT  UINTN                      *ArgumentBufferSize OPTIONAL,
+  IN      BOOLEAN                    Periodic OPTIONAL,
+  IN      UINTN                      ActivationInterval OPTIONAL
+  );
+
+/**
+  Clears an SMI.
+
+  @param  PeiServices         Describes the list of possible PEI Services.
+  @param  This                Pointer to an instance of EFI_SMM_CONTROL_PPI
+  @param  Periodic            TRUE to indicate a periodical SMI
+
+  @return Return value from SmmClear()
+
+**/
+EFI_STATUS
+EFIAPI
+PeiDeactivate (
+  IN  EFI_PEI_SERVICES            **PeiServices,
+  IN  PEI_SMM_CONTROL_PPI         *This,
+  IN  BOOLEAN                     Periodic OPTIONAL
+  );
+
+PEI_SMM_CONTROL_PPI      mSmmControlPpi = {
+  PeiActivate,
+  PeiDeactivate
+};
+
+EFI_PEI_PPI_DESCRIPTOR   mPpiList = {
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gPeiSmmControlPpiGuid,
+  &mSmmControlPpi
+};
+
+/**
+  Clear SMI related chipset status and re-enable SMI by setting the EOS bit.
+
+  @retval EFI_SUCCESS       The requested operation has been carried out successfully
+  @retval EFI_DEVICE_ERROR  The EOS bit could not be set.
+
+**/
+EFI_STATUS
+SmmClear (
+  VOID
+  )
+{
+  UINT16                       GPE0BLK_Base;
+
+  //
+  // Get GPE0BLK_Base
+  //
+  GPE0BLK_Base = PcdGet16 (PcdGpe0blkIoBaseAddress);
+
+  //
+  // Clear the Power Button Override Status Bit, it gates EOS from being set.
+  // In QuarkNcSocId - Bit is read only. Handled by external SMC, do nothing.
+  //
+
+  //
+  // Clear the APM SMI Status Bit
+  //
+  IoWrite32 ((GPE0BLK_Base + R_QNC_GPE0BLK_SMIS), B_QNC_GPE0BLK_SMIS_APM);
+
+  //
+  // Set the EOS Bit
+  //
+  IoOr32 ((GPE0BLK_Base + R_QNC_GPE0BLK_SMIS), B_QNC_GPE0BLK_SMIS_EOS);
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+SmmTrigger (
+  IN UINT8   Data
+  )
+/*++
+
+Routine Description:
+
+  Trigger the software SMI
+
+Arguments:
+
+  Data                          The value to be set on the software SMI data port
+
+Returns:
+
+  EFI_SUCCESS                   Function completes successfully
+
+--*/
+{
+  UINT16        GPE0BLK_Base;
+  UINT32        NewValue;
+
+  //
+  // Get GPE0BLK_Base
+  //
+  GPE0BLK_Base = PcdGet16 (PcdGpe0blkIoBaseAddress);
+
+  //
+  // Enable the APMC SMI
+  //
+  IoOr32 (GPE0BLK_Base + R_QNC_GPE0BLK_SMIE, B_QNC_GPE0BLK_SMIE_APM);
+
+  //
+  // Enable SMI globally
+  //
+  NewValue = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);
+  NewValue |= SMI_EN;
+  QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, NewValue);
+
+
+  //
+  // Generate the APMC SMI
+  //
+  IoWrite8 (PcdGet16 (PcdSmmActivationPort), Data);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Generates an SMI using the parameters passed in.
+
+  @param  PeiServices         Describes the list of possible PEI Services.
+  @param  This                A pointer to an instance of
+                              EFI_SMM_CONTROL_PPI
+  @param  ArgumentBuffer      The argument buffer
+  @param  ArgumentBufferSize  The size of the argument buffer
+  @param  Periodic            TRUE to indicate a periodical SMI
+  @param  ActivationInterval  Interval of the periodical SMI
+
+  @retval EFI_INVALID_PARAMETER  Periodic is TRUE or ArgumentBufferSize > 1
+  @retval EFI_SUCCESS            SMI generated
+
+**/
+EFI_STATUS
+EFIAPI
+PeiActivate (
+  IN      EFI_PEI_SERVICES           **PeiServices,
+  IN      PEI_SMM_CONTROL_PPI        *This,
+  IN OUT  INT8                       *ArgumentBuffer OPTIONAL,
+  IN OUT  UINTN                      *ArgumentBufferSize OPTIONAL,
+  IN      BOOLEAN                    Periodic OPTIONAL,
+  IN      UINTN                      ActivationInterval OPTIONAL
+  )
+{
+  INT8       Data;
+  EFI_STATUS Status;
+  //
+  // Periodic SMI not supported.
+  //
+  if (Periodic) {
+    DEBUG ((DEBUG_WARN, "Invalid parameter\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (ArgumentBuffer == NULL) {
+    Data = 0xFF;
+  } else {
+    if (ArgumentBufferSize == NULL || *ArgumentBufferSize != 1) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    Data = *ArgumentBuffer;
+  }
+  //
+  // Clear any pending the APM SMI
+  //
+  Status = SmmClear ();
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  return SmmTrigger (Data);
+}
+
+/**
+  Clears an SMI.
+
+  @param  PeiServices         Describes the list of possible PEI Services.
+  @param  This                Pointer to an instance of EFI_SMM_CONTROL_PPI
+  @param  Periodic            TRUE to indicate a periodical SMI
+
+  @return Return value from SmmClear()
+
+**/
+EFI_STATUS
+EFIAPI
+PeiDeactivate (
+  IN  EFI_PEI_SERVICES            **PeiServices,
+  IN  PEI_SMM_CONTROL_PPI         *This,
+  IN  BOOLEAN                     Periodic OPTIONAL
+  )
+{
+  if (Periodic) {
+    return EFI_INVALID_PARAMETER;
+  }
+  return SmmClear ();
+}
+
+/**
+  This is the constructor for the SMM Control Ppi.
+
+  This function installs EFI_SMM_CONTROL_PPI.
+
+  @param   FileHandle       Handle of the file being invoked.
+  @param   PeiServices      Describes the list of possible PEI Services.
+
+  @retval EFI_UNSUPPORTED There's no Intel ICH on this platform
+  @return The status returned from InstallPpi().
+
+--*/
+EFI_STATUS
+EFIAPI
+SmmControlPeiEntry (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  EFI_STATUS  Status;
+
+  Status      = (**PeiServices).InstallPpi (PeiServices, &mPpiList);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/SmmControlPei.inf b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/SmmControlPei.inf
new file mode 100644
index 0000000000..a790641013
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/SmmControlPei.inf
@@ -0,0 +1,51 @@
+## @file
+# Component description file for SmmControlPei module.
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SmmControlPei
+  FILE_GUID                      = 60EC7720-512B-4490-9FD1-A336769AE01F
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = SmmControlPeiEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  SmmControlPei.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  PeimEntryPoint
+  DebugLib
+  PeiServicesLib
+  PcdLib
+  IoLib
+  PciLib
+  QNCAccessLib
+
+[Ppis]
+  gPeiSmmControlPpiGuid                        # ALWAYS_PRODUCED
+
+[Pcd]
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPm1blkIoBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdGpe0blkIoBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdSmmActivationPort
+
+[Depex]
+  TRUE
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Common/SpiCommon.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Common/SpiCommon.c
new file mode 100644
index 0000000000..cbcd63c036
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Common/SpiCommon.c
@@ -0,0 +1,927 @@
+/** @file
+PCH SPI Common Driver implements the SPI Host Controller Compatibility Interface.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PchSpi.h"
+
+VOID
+FillOutPublicInfoStruct (
+  SPI_INSTANCE          *SpiInstance
+  )
+/*++
+
+Routine Description:
+
+  Fillout SpiInstance->InitInfo;
+
+Arguments:
+
+  SpiInstance   - Pointer to SpiInstance to initialize
+
+Returns:
+
+  NONE
+
+--*/
+{
+  UINT8         Index;
+
+  SpiInstance->InitInfo.InitTable = &SpiInstance->SpiInitTable;
+
+  //
+  // Give invalid index in case operation not supported.
+  //
+  SpiInstance->InitInfo.JedecIdOpcodeIndex = 0xff;
+  SpiInstance->InitInfo.OtherOpcodeIndex = 0xff;
+  SpiInstance->InitInfo.WriteStatusOpcodeIndex = 0xff;
+  SpiInstance->InitInfo.ProgramOpcodeIndex = 0xff;
+  SpiInstance->InitInfo.ReadOpcodeIndex = 0xff;
+  SpiInstance->InitInfo.EraseOpcodeIndex = 0xff;
+  SpiInstance->InitInfo.ReadStatusOpcodeIndex = 0xff;
+  SpiInstance->InitInfo.FullChipEraseOpcodeIndex = 0xff;
+  for (Index = 0; Index < SPI_NUM_OPCODE; Index++) {
+    if (SpiInstance->SpiInitTable.OpcodeMenu[Index].Operation == EnumSpiOperationJedecId) {
+      SpiInstance->InitInfo.JedecIdOpcodeIndex = Index;
+    }
+    if (SpiInstance->SpiInitTable.OpcodeMenu[Index].Operation == EnumSpiOperationOther) {
+      SpiInstance->InitInfo.OtherOpcodeIndex = Index;
+    }
+    if (SpiInstance->SpiInitTable.OpcodeMenu[Index].Operation == EnumSpiOperationWriteStatus) {
+      SpiInstance->InitInfo.WriteStatusOpcodeIndex = Index;
+    }
+    if (SpiInstance->SpiInitTable.OpcodeMenu[Index].Operation == EnumSpiOperationProgramData_1_Byte ||
+        SpiInstance->SpiInitTable.OpcodeMenu[Index].Operation == EnumSpiOperationProgramData_64_Byte) {
+      SpiInstance->InitInfo.ProgramOpcodeIndex = Index;
+    }
+    if (SpiInstance->SpiInitTable.OpcodeMenu[Index].Operation == EnumSpiOperationReadData ||
+        SpiInstance->SpiInitTable.OpcodeMenu[Index].Operation == EnumSpiOperationFastRead ||
+        SpiInstance->SpiInitTable.OpcodeMenu[Index].Operation == EnumSpiOperationDualOutputFastRead) {
+      SpiInstance->InitInfo.ReadOpcodeIndex = Index;
+    }
+    if (SpiInstance->SpiInitTable.OpcodeMenu[Index].Operation == EnumSpiOperationErase_256_Byte ||
+        SpiInstance->SpiInitTable.OpcodeMenu[Index].Operation == EnumSpiOperationErase_4K_Byte ||
+        SpiInstance->SpiInitTable.OpcodeMenu[Index].Operation == EnumSpiOperationErase_8K_Byte ||
+        SpiInstance->SpiInitTable.OpcodeMenu[Index].Operation == EnumSpiOperationErase_64K_Byte) {
+      SpiInstance->InitInfo.EraseOpcodeIndex = Index;
+    }
+    if (SpiInstance->SpiInitTable.OpcodeMenu[Index].Operation == EnumSpiOperationReadStatus) {
+      SpiInstance->InitInfo.ReadStatusOpcodeIndex = Index;
+    }
+    if (SpiInstance->SpiInitTable.OpcodeMenu[Index].Operation == EnumSpiOperationFullChipErase) {
+      SpiInstance->InitInfo.FullChipEraseOpcodeIndex = Index;
+    }
+  }
+}
+
+EFI_STATUS
+SpiProtocolConstructor (
+  SPI_INSTANCE          *SpiInstance
+  )
+/*++
+
+Routine Description:
+
+  Initialize an SPI protocol instance.
+  The function will assert in debug if PCH RCBA has not been initialized
+
+Arguments:
+
+  SpiInstance   - Pointer to SpiInstance to initialize
+
+Returns:
+
+  EFI_SUCCESS     The protocol instance was properly initialized
+  EFI_UNSUPPORTED The PCH is not supported by this module
+
+--*/
+{
+  SpiInstance->InitDone = FALSE;  // Indicate NOT READY.
+
+  //
+  // Check if the current PCH is known and supported by this code
+  //
+  if (!IsQncSupported ()) {
+    DEBUG ((DEBUG_ERROR, "PCH SPI Protocol not supported due to no proper QNC LPC found!\n"));
+    return EFI_UNSUPPORTED;
+  }
+  //
+  // Initialize the SPI protocol instance
+  //
+  SpiInstance->Signature            = PCH_SPI_PRIVATE_DATA_SIGNATURE;
+  SpiInstance->Handle               = NULL;
+  SpiInstance->SpiProtocol.Init     = SpiProtocolInit;
+  SpiInstance->SpiProtocol.Lock     = SpiProtocolLock;
+  SpiInstance->SpiProtocol.Execute  = SpiProtocolExecute;
+  SpiInstance->SpiProtocol.Info     = SpiProtocolInfo;
+
+  //
+  // Sanity check to ensure PCH RCBA initialization has occurred previously.
+  //
+  SpiInstance->PchRootComplexBar = MmioRead32 (
+                                    PciDeviceMmBase (PCI_BUS_NUMBER_QNC,
+                                    PCI_DEVICE_NUMBER_QNC_LPC,
+                                    PCI_FUNCTION_NUMBER_QNC_LPC) + R_QNC_LPC_RCBA
+                                    ) & B_QNC_LPC_RCBA_MASK;
+  ASSERT (SpiInstance->PchRootComplexBar != 0);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+UnlockFlashComponents (
+  IN      EFI_SPI_PROTOCOL      *This,
+  IN      UINT8                 UnlockCmdOpcodeIndex
+  )
+/*++
+
+Routine Description:
+
+  Issue unlock command to disable block protection, this only needs to be done once per SPI power on
+
+Arguments:
+
+  This                      A pointer to "EFI_SPI_PROTOCOL" for issuing commands
+  UnlockCmdOpcodeIndex      The index of the Unlock command
+
+Returns:
+
+  EFI_SUCCESS               UnLock operation succeed.
+  EFI_DEVICE_ERROR          Device error, operation failed.
+
+--*/
+{
+  EFI_STATUS    Status;
+  SPI_INSTANCE  *SpiInstance;
+  UINT8         SpiStatus;
+
+  if (UnlockCmdOpcodeIndex >= SPI_NUM_OPCODE) {
+    return EFI_UNSUPPORTED;
+  }
+
+  SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+
+  //
+  // Issue unlock command to disable block protection, this only needs to be done once per SPI power on
+  //
+  SpiStatus = 0;
+  //
+  // Issue unlock command to the flash component 1 at first
+  //
+  Status = SpiProtocolExecute (
+            This,
+            UnlockCmdOpcodeIndex,
+            SpiInstance->SpiInitTable.PrefixOpcode[0] == PCH_SPI_COMMAND_WRITE_ENABLE ? 0 : 1,
+            TRUE,
+            TRUE,
+            TRUE,
+            (UINTN) 0,
+            sizeof (SpiStatus),
+            &SpiStatus,
+            EnumSpiRegionAll
+            );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Unlock flash component 1 fail!\n"));
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+SpiProtocolInit (
+  IN EFI_SPI_PROTOCOL       *This,
+  IN SPI_INIT_TABLE         *InitTable
+  )
+/*++
+
+Routine Description:
+
+  Initialize the host controller to execute SPI command.
+
+Arguments:
+
+  This                    Pointer to the EFI_SPI_PROTOCOL instance.
+  InitTable               Initialization data to be programmed into the SPI host controller.
+
+Returns:
+
+  EFI_SUCCESS             Initialization completed.
+  EFI_ACCESS_DENIED       The SPI static configuration interface has been locked-down.
+  EFI_INVALID_PARAMETER   Bad input parameters.
+  EFI_UNSUPPORTED         Can't get Descriptor mode VSCC values
+--*/
+{
+  EFI_STATUS    Status;
+  UINT8         Index;
+  UINT16        OpcodeType;
+  SPI_INSTANCE  *SpiInstance;
+  UINTN         PchRootComplexBar;
+  UINT8         UnlockCmdOpcodeIndex;
+  UINT8         FlashPartId[3];
+
+  SpiInstance       = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+  PchRootComplexBar = SpiInstance->PchRootComplexBar;
+
+  if (InitTable != NULL) {
+    //
+    // Copy table into SPI driver Private data structure
+    //
+    CopyMem (
+      &SpiInstance->SpiInitTable,
+      InitTable,
+      sizeof (SPI_INIT_TABLE)
+      );
+  } else {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Check if the SPI interface has been locked-down.
+  //
+  if ((MmioRead16 (PchRootComplexBar + R_QNC_RCRB_SPIS) & B_QNC_RCRB_SPIS_SCL) != 0) {
+    ASSERT_EFI_ERROR (EFI_ACCESS_DENIED);
+    return EFI_ACCESS_DENIED;
+  }
+  //
+  // Clear all the status bits for status regs.
+  //
+  MmioOr16 (
+    (UINTN) (PchRootComplexBar + R_QNC_RCRB_SPIS),
+    (UINT16) ((B_QNC_RCRB_SPIS_CDS | B_QNC_RCRB_SPIS_BAS))
+    );
+  MmioRead16 (PchRootComplexBar + R_QNC_RCRB_SPIS);
+
+  //
+  // Set the Prefix Opcode registers.
+  //
+  MmioWrite16 (
+    PchRootComplexBar + R_QNC_RCRB_SPIPREOP,
+    (SpiInstance->SpiInitTable.PrefixOpcode[1] << 8) | InitTable->PrefixOpcode[0]
+    );
+  MmioRead16 (PchRootComplexBar + R_QNC_RCRB_SPIPREOP);
+
+  //
+  // Set Opcode Type Configuration registers.
+  //
+  for (Index = 0, OpcodeType = 0; Index < SPI_NUM_OPCODE; Index++) {
+    switch (SpiInstance->SpiInitTable.OpcodeMenu[Index].Type) {
+    case EnumSpiOpcodeRead:
+      OpcodeType |= (UINT16) (B_QNC_RCRB_SPIOPTYPE_ADD_READ << (Index * 2));
+      break;
+    case EnumSpiOpcodeWrite:
+      OpcodeType |= (UINT16) (B_QNC_RCRB_SPIOPTYPE_ADD_WRITE << (Index * 2));
+      break;
+    case EnumSpiOpcodeWriteNoAddr:
+      OpcodeType |= (UINT16) (B_QNC_RCRB_SPIOPTYPE_NOADD_WRITE << (Index * 2));
+      break;
+    default:
+      OpcodeType |= (UINT16) (B_QNC_RCRB_SPIOPTYPE_NOADD_READ << (Index * 2));
+      break;
+    }
+  }
+  MmioWrite16 (PchRootComplexBar + R_QNC_RCRB_SPIOPTYPE, OpcodeType);
+  MmioRead16 (PchRootComplexBar + R_QNC_RCRB_SPIOPTYPE);
+
+  //
+  // Setup the Opcode Menu registers.
+  //
+  UnlockCmdOpcodeIndex = SPI_NUM_OPCODE;
+  for (Index = 0; Index < SPI_NUM_OPCODE; Index++) {
+    MmioWrite8 (
+      PchRootComplexBar + R_QNC_RCRB_SPIOPMENU + Index,
+      SpiInstance->SpiInitTable.OpcodeMenu[Index].Code
+      );
+    MmioRead8 (PchRootComplexBar + R_QNC_RCRB_SPIOPMENU + Index);
+    if (SpiInstance->SpiInitTable.OpcodeMenu[Index].Operation == EnumSpiOperationJedecId) {
+      Status = SpiProtocolExecute (
+                This,
+                Index,
+                0,
+                TRUE,
+                TRUE,
+                FALSE,
+                (UINTN) 0,
+                3,
+                FlashPartId,
+                EnumSpiRegionDescriptor
+                );
+      if (EFI_ERROR (Status)) {
+        return Status;
+      }
+      if (FlashPartId[0] != SpiInstance->SpiInitTable.VendorId  ||
+          FlashPartId[1] != SpiInstance->SpiInitTable.DeviceId0 ||
+          FlashPartId[2] != SpiInstance->SpiInitTable.DeviceId1) {
+        return EFI_INVALID_PARAMETER;
+      }
+    }
+
+    if (SpiInstance->SpiInitTable.OpcodeMenu[Index].Operation == EnumSpiOperationWriteStatus) {
+      UnlockCmdOpcodeIndex = Index;
+    }
+  }
+
+  Status = UnlockFlashComponents (
+            This,
+            UnlockCmdOpcodeIndex
+            );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Unlock flash components fail!\n"));
+  }
+
+  SpiPhaseInit ();
+  FillOutPublicInfoStruct (SpiInstance);
+  SpiInstance->InitDone = TRUE;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+SpiProtocolLock (
+  IN EFI_SPI_PROTOCOL     *This
+  )
+/*++
+
+Routine Description:
+
+  Lock the SPI Static Configuration Interface.
+  Once locked, the interface can not be changed and can only be clear by system reset.
+
+Arguments:
+
+  This      Pointer to the EFI_SPI_PROTOCOL instance.
+
+Returns:
+
+  EFI_SUCCESS             Lock operation succeed.
+  EFI_DEVICE_ERROR        Device error, operation failed.
+  EFI_ACCESS_DENIED       The interface has already been locked.
+
+--*/
+{
+  SPI_INSTANCE  *SpiInstance;
+  UINTN         PchRootComplexBar;
+
+  SpiInstance       = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+  PchRootComplexBar = SpiInstance->PchRootComplexBar;
+
+  //
+  // Check if the SPI interface has been locked-down.
+  //
+  if ((MmioRead16 (PchRootComplexBar + R_QNC_RCRB_SPIS) & B_QNC_RCRB_SPIS_SCL) != 0) {
+    return EFI_ACCESS_DENIED;
+  }
+
+  //
+  // Lock-down the configuration interface.
+  //
+  MmioOr16 ((UINTN) (PchRootComplexBar + R_QNC_RCRB_SPIS), (UINT16) (B_QNC_RCRB_SPIS_SCL));
+
+  //
+  // Verify if it's really locked.
+  //
+  if ((MmioRead16 (PchRootComplexBar + R_QNC_RCRB_SPIS) & B_QNC_RCRB_SPIS_SCL) == 0) {
+    return EFI_DEVICE_ERROR;
+  } else {
+    //
+    // Save updated register in S3 Boot script.
+    //
+    S3BootScriptSaveMemWrite (
+      S3BootScriptWidthUint16,
+        (UINTN) (PchRootComplexBar + R_QNC_RCRB_SPIS),
+        1,
+        (VOID *) (UINTN) (PchRootComplexBar + R_QNC_RCRB_SPIS)
+        );
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+SpiProtocolExecute (
+  IN     EFI_SPI_PROTOCOL   *This,
+  IN     UINT8              OpcodeIndex,
+  IN     UINT8              PrefixOpcodeIndex,
+  IN     BOOLEAN            DataCycle,
+  IN     BOOLEAN            Atomic,
+  IN     BOOLEAN            ShiftOut,
+  IN     UINTN              Address,
+  IN     UINT32             DataByteCount,
+  IN OUT UINT8              *Buffer,
+  IN     SPI_REGION_TYPE    SpiRegionType
+  )
+/*++
+
+Routine Description:
+
+  Execute SPI commands from the host controller.
+  This function would be called by runtime driver, please do not use any MMIO marco here
+
+Arguments:
+
+  This              Pointer to the EFI_SPI_PROTOCOL instance.
+  OpcodeIndex       Index of the command in the OpCode Menu.
+  PrefixOpcodeIndex Index of the first command to run when in an atomic cycle sequence.
+  DataCycle         TRUE if the SPI cycle contains data
+  Atomic            TRUE if the SPI cycle is atomic and interleave cycles are not allowed.
+  ShiftOut          If DataByteCount is not zero, TRUE to shift data out and FALSE to shift data in.
+  Address           In Descriptor Mode, for Descriptor Region, GbE Region, ME Region and Platform
+                    Region, this value specifies the offset from the Region Base; for BIOS Region,
+                    this value specifies the offset from the start of the BIOS Image. In Non
+                    Descriptor Mode, this value specifies the offset from the start of the BIOS Image.
+                    Please note BIOS Image size may be smaller than BIOS Region size (in Descriptor
+                    Mode) or the flash size (in Non Descriptor Mode), and in this case, BIOS Image is
+                    supposed to be placed at the top end of the BIOS Region (in Descriptor Mode) or
+                    the flash (in Non Descriptor Mode)
+  DataByteCount     Number of bytes in the data portion of the SPI cycle. This function may break the
+                    data transfer into multiple operations. This function ensures each operation does
+                    not cross 256 byte flash address boundary.
+                    *NOTE: if there is some SPI chip that has a stricter address boundary requirement
+                    (e.g., its write page size is < 256 byte), then the caller cannot rely on this
+                    function to cut the data transfer at proper address boundaries, and it's the
+                    caller's reponsibility to pass in a properly cut DataByteCount parameter.
+  Buffer            Pointer to caller-allocated buffer containing the dada received or sent during the
+                    SPI cycle.
+  SpiRegionType     SPI Region type. Values EnumSpiRegionBios, EnumSpiRegionGbE, EnumSpiRegionMe,
+                    EnumSpiRegionDescriptor, and EnumSpiRegionPlatformData are only applicable in
+                    Descriptor mode. Value EnumSpiRegionAll is applicable to both Descriptor Mode
+                    and Non Descriptor Mode, which indicates "SpiRegionOffset" is actually relative
+                    to base of the 1st flash device (i.e., it is a Flash Linear Address).
+
+Returns:
+
+  EFI_SUCCESS             Command succeed.
+  EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  EFI_UNSUPPORTED         Command not supported.
+  EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+
+--*/
+{
+  EFI_STATUS  Status;
+  UINT16      BiosCtlSave;
+  UINT32      SmiEnSave;
+
+  BiosCtlSave = 0;
+  SmiEnSave   = 0;
+
+  //
+  // Check if the parameters are valid.
+  //
+  if ((OpcodeIndex >= SPI_NUM_OPCODE) || (PrefixOpcodeIndex >= SPI_NUM_PREFIX_OPCODE)) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Make sure it's safe to program the command.
+  //
+  if (!WaitForSpiCycleComplete (This, FALSE)) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Acquire access to the SPI interface is not required any more.
+  //
+  //
+  // Disable SMIs to make sure normal mode flash access is not interrupted by an SMI
+  // whose SMI handler accesses flash (e.g. for error logging)
+  //
+  SmiEnSave = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);
+  QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, (SmiEnSave & ~SMI_EN));
+
+  //
+  // Save BIOS Ctrl register
+  //
+  BiosCtlSave = PciRead16 (
+                  PCI_LIB_ADDRESS (PCI_BUS_NUMBER_QNC,
+                  PCI_DEVICE_NUMBER_QNC_LPC,
+                  PCI_FUNCTION_NUMBER_QNC_LPC,
+                  R_QNC_LPC_BIOS_CNTL)
+                  ) & (B_QNC_LPC_BIOS_CNTL_BCD | B_QNC_LPC_BIOS_CNTL_PFE | B_QNC_LPC_BIOS_CNTL_BIOSWE | B_QNC_LPC_BIOS_CNTL_SMM_BWP);
+
+  //
+  // Enable flash writing
+  //
+  PciOr16 (
+    PCI_LIB_ADDRESS (PCI_BUS_NUMBER_QNC,
+    PCI_DEVICE_NUMBER_QNC_LPC,
+    PCI_FUNCTION_NUMBER_QNC_LPC,
+    R_QNC_LPC_BIOS_CNTL),
+    (UINT16) (B_QNC_LPC_BIOS_CNTL_BIOSWE | B_QNC_LPC_BIOS_CNTL_SMM_BWP)
+    );
+
+  //
+  // If shifts the data out, disable Prefetching and Caching.
+  //
+  if (ShiftOut) {
+    PciAndThenOr16 (
+      PCI_LIB_ADDRESS (PCI_BUS_NUMBER_QNC,
+      PCI_DEVICE_NUMBER_QNC_LPC,
+      PCI_FUNCTION_NUMBER_QNC_LPC,
+      R_QNC_LPC_BIOS_CNTL),
+      (UINT16) (~(B_QNC_LPC_BIOS_CNTL_BCD | B_QNC_LPC_BIOS_CNTL_PFE)),
+      (UINT16) ((B_QNC_LPC_BIOS_CNTL_BCD))
+      );
+  }
+  //
+  // Sends the command to the SPI interface to execute.
+  //
+  Status = SendSpiCmd (
+            This,
+            OpcodeIndex,
+            PrefixOpcodeIndex,
+            DataCycle,
+            Atomic,
+            ShiftOut,
+            Address,
+            DataByteCount,
+            Buffer,
+            SpiRegionType
+            );
+
+  //
+  // Restore BIOS Ctrl register
+  //
+  PciAndThenOr16 (
+    PCI_LIB_ADDRESS (PCI_BUS_NUMBER_QNC,
+    PCI_DEVICE_NUMBER_QNC_LPC,
+    PCI_FUNCTION_NUMBER_QNC_LPC,
+    R_QNC_LPC_BIOS_CNTL),
+    (UINT16) (~(B_QNC_LPC_BIOS_CNTL_BCD | B_QNC_LPC_BIOS_CNTL_PFE | B_QNC_LPC_BIOS_CNTL_BIOSWE | B_QNC_LPC_BIOS_CNTL_SMM_BWP)),
+    (UINT16) (BiosCtlSave)
+      );
+  //
+  // Restore SMIs.
+  //
+  QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, SmiEnSave);
+
+  return Status;
+}
+
+VOID
+SpiOffset2Physical (
+  IN      EFI_SPI_PROTOCOL  *This,
+  IN      UINTN             SpiRegionOffset,
+  IN      SPI_REGION_TYPE   SpiRegionType,
+  OUT     UINTN             *HardwareSpiAddress,
+  OUT     UINTN             *BaseAddress,
+  OUT     UINTN             *LimitAddress
+  )
+/*++
+
+Routine Description:
+
+  Convert SPI offset to Physical address of SPI hardware
+
+Arguments:
+
+  This               Pointer to the EFI_SPI_PROTOCOL instance.
+  SpiRegionOffset    In Descriptor Mode, for Descriptor Region, GbE Region, ME Region and Platform
+                     Region, this value specifies the offset from the Region Base; for BIOS Region,
+                     this value specifies the offset from the start of the BIOS Image. In Non
+                     Descriptor Mode, this value specifies the offset from the start of the BIOS Image.
+                     Please note BIOS Image size may be smaller than BIOS Region size (in Descriptor
+                     Mode) or the flash size (in Non Descriptor Mode), and in this case, BIOS Image is
+                     supposed to be placed at the top end of the BIOS Region (in Descriptor Mode) or
+                     the flash (in Non Descriptor Mode)
+  BaseAddress        Base Address of the region.
+  SpiRegionType      SPI Region type. Values EnumSpiRegionBios, EnumSpiRegionGbE, EnumSpiRegionMe,
+                     EnumSpiRegionDescriptor, and EnumSpiRegionPlatformData are only applicable in
+                     Descriptor mode. Value EnumSpiRegionAll is applicable to both Descriptor Mode
+                     and Non Descriptor Mode, which indicates "SpiRegionOffset" is actually relative
+                     to base of the 1st flash device (i.e., it is a Flash Linear Address).
+  HardwareSpiAddress Return absolution SPI address (i.e., Flash Linear Address)
+  BaseAddress        Return base address of the region type
+  LimitAddress       Return limit address of the region type
+
+Returns:
+
+  EFI_SUCCESS             Command succeed.
+
+--*/
+{
+  SPI_INSTANCE  *SpiInstance;
+
+  SpiInstance       = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+
+  if (SpiRegionType == EnumSpiRegionAll) {
+    //
+    // EnumSpiRegionAll indicates address is relative to flash device (i.e., address is Flash
+    // Linear Address)
+    //
+    *HardwareSpiAddress = SpiRegionOffset;
+  } else {
+    //
+    // Otherwise address is relative to BIOS image
+    //
+    *HardwareSpiAddress = SpiRegionOffset + SpiInstance->SpiInitTable.BiosStartOffset;
+  }
+}
+
+EFI_STATUS
+SendSpiCmd (
+  IN     EFI_SPI_PROTOCOL   *This,
+  IN     UINT8              OpcodeIndex,
+  IN     UINT8              PrefixOpcodeIndex,
+  IN     BOOLEAN            DataCycle,
+  IN     BOOLEAN            Atomic,
+  IN     BOOLEAN            ShiftOut,
+  IN     UINTN              Address,
+  IN     UINT32             DataByteCount,
+  IN OUT UINT8              *Buffer,
+  IN     SPI_REGION_TYPE    SpiRegionType
+  )
+/*++
+
+Routine Description:
+
+  This function sends the programmed SPI command to the slave device.
+
+Arguments:
+
+  OpcodeIndex       Index of the command in the OpCode Menu.
+  PrefixOpcodeIndex Index of the first command to run when in an atomic cycle sequence.
+  DataCycle         TRUE if the SPI cycle contains data
+  Atomic            TRUE if the SPI cycle is atomic and interleave cycles are not allowed.
+  ShiftOut          If DataByteCount is not zero, TRUE to shift data out and FALSE to shift data in.
+  Address           In Descriptor Mode, for Descriptor Region, GbE Region, ME Region and Platform
+                    Region, this value specifies the offset from the Region Base; for BIOS Region,
+                    this value specifies the offset from the start of the BIOS Image. In Non
+                    Descriptor Mode, this value specifies the offset from the start of the BIOS Image.
+                    Please note BIOS Image size may be smaller than BIOS Region size (in Descriptor
+                    Mode) or the flash size (in Non Descriptor Mode), and in this case, BIOS Image is
+                    supposed to be placed at the top end of the BIOS Region (in Descriptor Mode) or
+                    the flash (in Non Descriptor Mode)
+  DataByteCount     Number of bytes in the data portion of the SPI cycle. This function may break the
+                    data transfer into multiple operations. This function ensures each operation does
+                    not cross 256 byte flash address boundary.
+                    *NOTE: if there is some SPI chip that has a stricter address boundary requirement
+                    (e.g., its write page size is < 256 byte), then the caller cannot rely on this
+                    function to cut the data transfer at proper address boundaries, and it's the
+                    caller's reponsibility to pass in a properly cut DataByteCount parameter.
+  Buffer            Data received or sent during the SPI cycle.
+  SpiRegionType     SPI Region type. Values EnumSpiRegionBios, EnumSpiRegionGbE, EnumSpiRegionMe,
+                    EnumSpiRegionDescriptor, and EnumSpiRegionPlatformData are only applicable in
+                    Descriptor mode. Value EnumSpiRegionAll is applicable to both Descriptor Mode
+                    and Non Descriptor Mode, which indicates "SpiRegionOffset" is actually relative
+                    to base of the 1st flash device (i.e., it is a Flash Linear Address).
+
+Returns:
+
+  EFI_SUCCESS             SPI command completes successfully.
+  EFI_DEVICE_ERROR        Device error, the command aborts abnormally.
+  EFI_ACCESS_DENIED       Some unrecognized command encountered in hardware sequencing mode
+  EFI_INVALID_PARAMETER   The parameters specified are not valid.
+
+--*/
+{
+  UINT32        Index;
+  SPI_INSTANCE  *SpiInstance;
+  UINTN         HardwareSpiAddr;
+  UINTN         SpiBiosSize;
+  UINTN         BaseAddress;
+  UINTN         LimitAddress;
+  UINT32        SpiDataCount;
+  UINT8         OpCode;
+  UINTN         PchRootComplexBar;
+
+  SpiInstance       = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+  PchRootComplexBar = SpiInstance->PchRootComplexBar;
+  SpiBiosSize       = SpiInstance->SpiInitTable.BiosSize;
+  OpCode            = MmioRead8 (PchRootComplexBar + R_QNC_RCRB_SPIOPMENU + OpcodeIndex);
+
+  //
+  // Check if the value of opcode register is 0 or the BIOS Size of SpiInitTable is 0
+  //
+  if (OpCode == 0 || SpiBiosSize == 0) {
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  SpiOffset2Physical (This, Address, SpiRegionType, &HardwareSpiAddr, &BaseAddress, &LimitAddress);
+  //
+  // Have direct access to BIOS region in Descriptor mode,
+  //
+  if (SpiInstance->SpiInitTable.OpcodeMenu[OpcodeIndex].Type == EnumSpiOpcodeRead &&
+      SpiRegionType == EnumSpiRegionBios) {
+    CopyMem (
+      Buffer,
+      (UINT8 *) ((HardwareSpiAddr - BaseAddress) + (UINT32) (~(SpiBiosSize - 1))),
+      DataByteCount
+      );
+    return EFI_SUCCESS;
+  }
+  //
+  // DEBUG((EFI_D_ERROR, "SPIADDR %x, %x, %x, %x\n", Address, HardwareSpiAddr, BaseAddress,
+  // LimitAddress));
+  //
+  if ((DataCycle == FALSE) && (DataByteCount > 0)) {
+    DataByteCount = 0;
+  }
+
+  do {
+    //
+    // Trim at 256 byte boundary per operation,
+    // - PCH SPI controller requires trimming at 4KB boundary
+    // - Some SPI chips require trimming at 256 byte boundary for write operation
+    // - Trimming has limited performance impact as we can read / write atmost 64 byte
+    //   per operation
+    //
+    if (HardwareSpiAddr + DataByteCount > ((HardwareSpiAddr + BIT8) &~(BIT8 - 1))) {
+      SpiDataCount = (((UINT32) (HardwareSpiAddr) + BIT8) &~(BIT8 - 1)) - (UINT32) (HardwareSpiAddr);
+    } else {
+      SpiDataCount = DataByteCount;
+    }
+    //
+    // Calculate the number of bytes to shift in/out during the SPI data cycle.
+    // Valid settings for the number of bytes duing each data portion of the
+    // PCH SPI cycles are: 0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 24, 32, 40, 48, 56, 64
+    //
+    if (SpiDataCount >= 64) {
+      SpiDataCount = 64;
+    } else if ((SpiDataCount &~0x07) != 0) {
+      SpiDataCount = SpiDataCount &~0x07;
+    }
+    //
+    // If shifts data out, load data into the SPI data buffer.
+    //
+    if (ShiftOut) {
+      for (Index = 0; Index < SpiDataCount; Index++) {
+        MmioWrite8 (PchRootComplexBar + R_QNC_RCRB_SPID0 + Index, Buffer[Index]);
+        MmioRead8 (PchRootComplexBar + R_QNC_RCRB_SPID0 + Index);
+      }
+    }
+
+    MmioWrite32 (
+      (PchRootComplexBar + R_QNC_RCRB_SPIA),
+      (UINT32) (HardwareSpiAddr & B_QNC_RCRB_SPIA_MASK)
+      );
+    MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIA);
+
+    //
+    // Execute the command on the SPI compatible mode
+    //
+
+    //
+    // Clear error flags
+    //
+    MmioOr16 ((PchRootComplexBar + R_QNC_RCRB_SPIS), B_QNC_RCRB_SPIS_BAS);
+
+    //
+    // Initialte the SPI cycle
+    //
+    if (DataCycle) {
+      MmioWrite16 (
+        (PchRootComplexBar + R_QNC_RCRB_SPIC),
+        ( (UINT16) (B_QNC_RCRB_SPIC_DC) | (UINT16) (((SpiDataCount - 1) << 8) & B_QNC_RCRB_SPIC_DBC) |
+          (UINT16) ((OpcodeIndex << 4) & B_QNC_RCRB_SPIC_COP) |
+          (UINT16) ((PrefixOpcodeIndex << 3) & B_QNC_RCRB_SPIC_SPOP) |
+          (UINT16) (Atomic ? B_QNC_RCRB_SPIC_ACS : 0) |
+          (UINT16) (B_QNC_RCRB_SPIC_SCGO)));
+    } else {
+      MmioWrite16 (
+        (PchRootComplexBar + R_QNC_RCRB_SPIC),
+        ( (UINT16) ((OpcodeIndex << 4) & B_QNC_RCRB_SPIC_COP) |
+          (UINT16) ((PrefixOpcodeIndex << 3) & B_QNC_RCRB_SPIC_SPOP) |
+          (UINT16) (Atomic ? B_QNC_RCRB_SPIC_ACS : 0) |
+          (UINT16) (B_QNC_RCRB_SPIC_SCGO)));
+    }
+
+    MmioRead16 (PchRootComplexBar + R_QNC_RCRB_SPIC);
+
+    //
+    // end of command execution
+    //
+    // Wait the SPI cycle to complete.
+    //
+    if (!WaitForSpiCycleComplete (This, TRUE)) {
+      return EFI_DEVICE_ERROR;
+    }
+    //
+    // If shifts data in, get data from the SPI data buffer.
+    //
+    if (!ShiftOut) {
+      for (Index = 0; Index < SpiDataCount; Index++) {
+        Buffer[Index] = MmioRead8 (PchRootComplexBar + R_QNC_RCRB_SPID0 + Index);
+      }
+    }
+
+    HardwareSpiAddr += SpiDataCount;
+    Buffer += SpiDataCount;
+    DataByteCount -= SpiDataCount;
+  } while (DataByteCount > 0);
+
+  return EFI_SUCCESS;
+}
+
+BOOLEAN
+WaitForSpiCycleComplete (
+  IN     EFI_SPI_PROTOCOL   *This,
+  IN     BOOLEAN            ErrorCheck
+  )
+/*++
+
+Routine Description:
+
+  Wait execution cycle to complete on the SPI interface. Check both Hardware
+  and Software Sequencing status registers
+
+Arguments:
+
+  This                - The SPI protocol instance
+  UseSoftwareSequence - TRUE if this is a Hardware Sequencing operation
+  ErrorCheck          - TRUE if the SpiCycle needs to do the error check
+
+Returns:
+
+  TRUE       SPI cycle completed on the interface.
+  FALSE      Time out while waiting the SPI cycle to complete.
+             It's not safe to program the next command on the SPI interface.
+
+--*/
+{
+  UINT64        WaitTicks;
+  UINT64        WaitCount;
+  UINT16        Data16;
+  SPI_INSTANCE  *SpiInstance;
+  UINTN         PchRootComplexBar;
+
+  SpiInstance       = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+  PchRootComplexBar = SpiInstance->PchRootComplexBar;
+
+  //
+  // Convert the wait period allowed into to tick count
+  //
+  WaitCount = WAIT_TIME / WAIT_PERIOD;
+
+  //
+  // Wait for the SPI cycle to complete.
+  //
+  for (WaitTicks = 0; WaitTicks < WaitCount; WaitTicks++) {
+    Data16 = MmioRead16 (PchRootComplexBar + R_QNC_RCRB_SPIS);
+    if ((Data16 & B_QNC_RCRB_SPIS_SCIP) == 0) {
+      MmioWrite16 (PchRootComplexBar + R_QNC_RCRB_SPIS, (B_QNC_RCRB_SPIS_BAS | B_QNC_RCRB_SPIS_CDS));
+      if ((Data16 & B_QNC_RCRB_SPIS_BAS) && (ErrorCheck == TRUE)) {
+        return FALSE;
+      } else {
+        return TRUE;
+      }
+    }
+
+    MicroSecondDelay (WAIT_PERIOD);
+  }
+
+  return FALSE;
+}
+
+EFI_STATUS
+EFIAPI
+SpiProtocolInfo (
+  IN EFI_SPI_PROTOCOL     *This,
+  OUT SPI_INIT_INFO      **InitInfoPtr
+  )
+/*++
+
+Routine Description:
+
+  Return info about SPI host controller, to help callers usage of Execute
+  service.
+
+  If 0xff is returned as an opcode index in init info struct
+  then device does not support the operation.
+
+Arguments:
+
+  This                    Pointer to the EFI_SPI_PROTOCOL instance.
+  InitInfoPtr             Pointer to init info written to this memory location.
+
+Returns:
+
+  EFI_SUCCESS             Information returned.
+  EFI_INVALID_PARAMETER   Invalid parameter.
+  EFI_NOT_READY           Required resources not setup.
+  Others                  Unexpected error happened.
+
+--*/
+{
+  SPI_INSTANCE  *SpiInstance;
+
+  if (This == NULL || InitInfoPtr == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  SpiInstance       = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+  if (SpiInstance->Signature != PCH_SPI_PRIVATE_DATA_SIGNATURE) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!SpiInstance->InitDone) {
+    *InitInfoPtr = NULL;
+    return EFI_NOT_READY;
+  }
+  *InitInfoPtr = &SpiInstance->InitInfo;
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Common/SpiCommon.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Common/SpiCommon.h
new file mode 100644
index 0000000000..1e3a50d30c
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Common/SpiCommon.h
@@ -0,0 +1,317 @@
+/** @file
+Header file for the PCH SPI Common Driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef _SPI_COMMON_H_
+#define _SPI_COMMON_H_
+
+#include "Protocol/Spi.h"
+#include <Library/PciLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IntelQNCLib.h>
+#include <Library/QNCAccessLib.h>
+#include <Uefi/UefiBaseType.h>
+
+//
+// Maximum time allowed while waiting the SPI cycle to complete
+//  Wait Time = 6 seconds = 6000000 microseconds
+//  Wait Period = 10 microseconds
+//
+#define WAIT_TIME   6000000
+#define WAIT_PERIOD 10
+//
+// PCH Required SPI Commands -------- COMMAND SET I ------------
+// SPI flash device must support in order to be compatible with PCH
+//
+#define PCH_SPI_COMMAND_PROGRAM_BYTE          0x02
+#define PCH_SPI_COMMAND_READ_DATA             0x03
+#define PCH_SPI_COMMAND_WRITE_DISABLE         0x04
+#define PCH_SPI_COMMAND_READ_STATUS           0x05
+#define PCH_SPI_COMMAND_WRITE_ENABLE          0x06
+#define PCH_SPI_COMMAND_FAST_READ             0x0B
+#define PCH_SPI_COMMAND_READ_ID               0x9F
+#define PCH_SPI_COMMAND_DUAL_FAST_READ        0x3B  // Dual Output Fast Read
+
+//
+// Need to support at least one of the following two kinds of size of sector for erasing
+//
+#define PCH_SPI_COMMAND_4KB_ERASE   0x20
+#define PCH_SPI_COMMAND_64KB_ERASE  0xD8
+//
+// Recommended SPI Commands -------- COMMAND SET II ------------
+// SPI flash device best to support
+//
+#define PCH_SPI_COMMAND_WRITE_STATUS    0x01
+#define PCH_SPI_COMMAND_FULL_CHIP_ERASE 0xC7
+
+//
+// Private data structure definitions for the driver
+//
+#define PCH_SPI_PRIVATE_DATA_SIGNATURE  SIGNATURE_32 ('P', 'S', 'P', 'I')
+
+typedef struct {
+  UINTN             Signature;
+  EFI_HANDLE        Handle;
+  EFI_SPI_PROTOCOL  SpiProtocol;
+  SPI_INIT_TABLE    SpiInitTable;
+  UINTN             PchRootComplexBar;
+  BOOLEAN           InitDone; // Set to TRUE on SpiProtocolInit SUCCESS.
+  SPI_INIT_INFO     InitInfo;
+} SPI_INSTANCE;
+
+#define SPI_INSTANCE_FROM_SPIPROTOCOL(a)  CR (a, SPI_INSTANCE, SpiProtocol, PCH_SPI_PRIVATE_DATA_SIGNATURE)
+
+//
+// Function prototypes used by the SPI protocol.
+//
+EFI_STATUS
+SpiProtocolConstructor (
+  SPI_INSTANCE          *SpiInstance
+  )
+/*++
+
+Routine Description:
+
+  Initialize an SPI protocol instance.
+  The function will assert in debug if PCH RCBA has not been initialized
+
+Arguments:
+
+  SpiInstance   - Pointer to SpiInstance to initialize
+
+Returns:
+
+  EFI_SUCCESS     The protocol instance was properly initialized
+  EFI_UNSUPPORTED The PCH is not supported by this module
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+SpiProtocolInit (
+  IN EFI_SPI_PROTOCOL       *This,
+  IN SPI_INIT_TABLE         *InitTable
+  )
+/*++
+
+Routine Description:
+
+  Initialize the host controller to execute SPI command.
+
+Arguments:
+
+  This                    Pointer to the EFI_SPI_PROTOCOL instance.
+  InitTable               Initialization data to be programmed into the SPI host controller.
+
+Returns:
+
+  EFI_SUCCESS             Initialization completed.
+  EFI_ACCESS_DENIED       The SPI static configuration interface has been locked-down.
+  EFI_INVALID_PARAMETER   Bad input parameters.
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+SpiProtocolLock (
+  IN EFI_SPI_PROTOCOL       *This
+  )
+/*++
+
+Routine Description:
+
+  Lock the SPI Static Configuration Interface.
+  Once locked, the interface can not be changed and can only be clear by system reset.
+
+Arguments:
+
+  This      Pointer to the EFI_SPI_PROTOCOL instance.
+
+Returns:
+
+  EFI_SUCCESS             Lock operation succeed.
+  EFI_DEVICE_ERROR        Device error, operation failed.
+  EFI_ACCESS_DENIED       The interface has already been locked.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+SpiProtocolExecute (
+  IN     EFI_SPI_PROTOCOL   *This,
+  IN     UINT8              OpcodeIndex,
+  IN     UINT8              PrefixOpcodeIndex,
+  IN     BOOLEAN            DataCycle,
+  IN     BOOLEAN            Atomic,
+  IN     BOOLEAN            ShiftOut,
+  IN     UINTN              Address,
+  IN     UINT32             DataByteCount,
+  IN OUT UINT8              *Buffer,
+  IN     SPI_REGION_TYPE    SpiRegionType
+  )
+/*++
+
+Routine Description:
+
+  Execute SPI commands from the host controller.
+
+Arguments:
+
+  This                    Pointer to the EFI_SPI_PROTOCOL instance.
+  OpcodeIndex             Index of the command in the OpCode Menu.
+  PrefixOpcodeIndex       Index of the first command to run when in an atomic cycle sequence.
+  DataCycle               TRUE if the SPI cycle contains data
+  Atomic                  TRUE if the SPI cycle is atomic and interleave cycles are not allowed.
+  ShiftOut                If DataByteCount is not zero, TRUE to shift data out and FALSE to shift data in.
+  Address                 In Descriptor Mode, for Descriptor Region, GbE Region, ME Region and Platform
+                          Region, this value specifies the offset from the Region Base; for BIOS Region,
+                          this value specifies the offset from the start of the BIOS Image. In Non
+                          Descriptor Mode, this value specifies the offset from the start of the BIOS Image.
+                          Please note BIOS Image size may be smaller than BIOS Region size (in Descriptor
+                          Mode) or the flash size (in Non Descriptor Mode), and in this case, BIOS Image is
+                          supposed to be placed at the top end of the BIOS Region (in Descriptor Mode) or
+                          the flash (in Non Descriptor Mode)
+  DataByteCount           Number of bytes in the data portion of the SPI cycle.
+  Buffer                  Pointer to caller-allocated buffer containing the dada received or sent during the SPI cycle.
+  SpiRegionType           SPI Region type. Values EnumSpiRegionBios, EnumSpiRegionGbE, EnumSpiRegionMe,
+                          EnumSpiRegionDescriptor, and EnumSpiRegionPlatformData are only applicable in
+                          Descriptor mode. Value EnumSpiRegionAll is applicable to both Descriptor Mode
+                          and Non Descriptor Mode, which indicates "SpiRegionOffset" is actually relative
+                          to base of the 1st flash device (i.e., it is a Flash Linear Address).
+
+Returns:
+
+  EFI_SUCCESS             Command succeed.
+  EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  EFI_UNSUPPORTED         Command not supported.
+  EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+
+--*/
+;
+
+EFI_STATUS
+SendSpiCmd (
+  IN     EFI_SPI_PROTOCOL   *This,
+  IN     UINT8              OpcodeIndex,
+  IN     UINT8              PrefixOpcodeIndex,
+  IN     BOOLEAN            DataCycle,
+  IN     BOOLEAN            Atomic,
+  IN     BOOLEAN            ShiftOut,
+  IN     UINTN              Address,
+  IN     UINT32             DataByteCount,
+  IN OUT UINT8              *Buffer,
+  IN     SPI_REGION_TYPE    SpiRegionType
+  )
+/*++
+
+Routine Description:
+
+  This function sends the programmed SPI command to the slave device.
+
+Arguments:
+
+  OpcodeIndex       Index of the command in the OpCode Menu.
+  PrefixOpcodeIndex Index of the first command to run when in an atomic cycle sequence.
+  DataCycle         TRUE if the SPI cycle contains data
+  Atomic            TRUE if the SPI cycle is atomic and interleave cycles are not allowed.
+  ShiftOut          If DataByteCount is not zero, TRUE to shift data out and FALSE to shift data in.
+  Address           In Descriptor Mode, for Descriptor Region, GbE Region, ME Region and Platform
+                    Region, this value specifies the offset from the Region Base; for BIOS Region,
+                    this value specifies the offset from the start of the BIOS Image. In Non
+                    Descriptor Mode, this value specifies the offset from the start of the BIOS Image.
+                    Please note BIOS Image size may be smaller than BIOS Region size (in Descriptor
+                    Mode) or the flash size (in Non Descriptor Mode), and in this case, BIOS Image is
+                    supposed to be placed at the top end of the BIOS Region (in Descriptor Mode) or
+                    the flash (in Non Descriptor Mode)
+  DataByteCount     Number of bytes in the data portion of the SPI cycle. This function may break the
+                    data transfer into multiple operations. This function ensures each operation does
+                    not cross 256 byte flash address boundary.
+                    *NOTE: if there is some SPI chip that has a stricter address boundary requirement
+                    (e.g., its write page size is < 256 byte), then the caller cannot rely on this
+                    function to cut the data transfer at proper address boundaries, and it's the
+                    caller's reponsibility to pass in a properly cut DataByteCount parameter.
+  Buffer            Data received or sent during the SPI cycle.
+  SpiRegionType     SPI Region type. Values EnumSpiRegionBios, EnumSpiRegionGbE, EnumSpiRegionMe,
+                    EnumSpiRegionDescriptor, and EnumSpiRegionPlatformData are only applicable in
+                    Descriptor mode. Value EnumSpiRegionAll is applicable to both Descriptor Mode
+                    and Non Descriptor Mode, which indicates "SpiRegionOffset" is actually relative
+                    to base of the 1st flash device (i.e., it is a Flash Linear Address).
+
+Returns:
+
+  EFI_SUCCESS             SPI command completes successfully.
+  EFI_DEVICE_ERROR        Device error, the command aborts abnormally.
+  EFI_ACCESS_DENIED       Some unrecognized command encountered in hardware sequencing mode
+  EFI_INVALID_PARAMETER   The parameters specified are not valid.
+
+--*/
+;
+
+BOOLEAN
+WaitForSpiCycleComplete (
+  IN     EFI_SPI_PROTOCOL   *This,
+  IN     BOOLEAN            ErrorCheck
+  )
+/*++
+
+Routine Description:
+
+  Wait execution cycle to complete on the SPI interface. Check both Hardware
+  and Software Sequencing status registers
+
+Arguments:
+
+  This                - The SPI protocol instance
+  UseSoftwareSequence - TRUE if this is a Hardware Sequencing operation
+  ErrorCheck          - TRUE if the SpiCycle needs to do the error check
+
+Returns:
+
+  TRUE       SPI cycle completed on the interface.
+  FALSE      Time out while waiting the SPI cycle to complete.
+             It's not safe to program the next command on the SPI interface.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+SpiProtocolInfo (
+  IN EFI_SPI_PROTOCOL     *This,
+  OUT SPI_INIT_INFO      **InitInfoPtr
+  )
+/*++
+
+Routine Description:
+
+  Return info about SPI host controller, to help callers usage of Execute
+  service.
+
+  If 0xff is returned as an opcode index in init info struct
+  then device does not support the operation.
+
+Arguments:
+
+  This                    Pointer to the EFI_SPI_PROTOCOL instance.
+  InitInfoPtr             Pointer to init info written to this memory location.
+
+Returns:
+
+  EFI_SUCCESS             Information returned.
+  EFI_INVALID_PARAMETER   Invalid parameter.
+  EFI_NOT_READY           Required resources not setup.
+  Others                  Unexpected error happened.
+
+--*/
+;
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiRuntime.inf b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiRuntime.inf
new file mode 100644
index 0000000000..c20c12c91d
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiRuntime.inf
@@ -0,0 +1,84 @@
+## @file
+#    Component description file for the SPI Runtime driver.
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PchSpiRuntime
+  FILE_GUID                      = C194C6EA-B68C-4981-B64B-9BD271474B20
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = InstallPchSpi
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+################################################################################
+#
+# Sources Section - list of files that are required for the build to succeed.
+#
+################################################################################
+[Sources]
+  RuntimeDxe/PchSpi.h
+  RuntimeDxe/PchSpi.c
+  Common/SpiCommon.c
+  Common/SpiCommon.h
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+#                              this module.
+#
+################################################################################
+[Packages]
+  MdePkg/MdePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+################################################################################
+#
+# Library Class Section - list of Library Classes that are required for
+#                         this module.
+#
+################################################################################
+[LibraryClasses]
+  UefiRuntimeServicesTableLib
+  UefiRuntimeLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  IntelQNCLib
+  QNCAccessLib
+  TimerLib
+  DxeServicesTableLib
+  UefiLib
+  DebugLib
+  MemoryAllocationLib
+  S3BootScriptLib
+  PciExpressLib
+
+################################################################################
+#
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names
+#                           that this module uses or produces.
+#
+################################################################################
+[Protocols]
+  gEfiSpiProtocolGuid
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdRcbaMmioSize
+
+[Depex]
+  TRUE
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiSmm.inf b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiSmm.inf
new file mode 100644
index 0000000000..13b2f77e0a
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiSmm.inf
@@ -0,0 +1,50 @@
+## @file
+# Spi smm driver
+#
+# Component description file for the SPI SMM driver.
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[defines]
+  INF_VERSION                 = 0x00010005
+  BASE_NAME                       = PchSpiSmm
+  FILE_GUID                       = 27F4917B-A707-4aad-9676-26DF168CBF0D
+  MODULE_TYPE                     = DXE_SMM_DRIVER
+  VERSION_STRING                  = 1.0
+  PI_SPECIFICATION_VERSION        = 0x0001000A
+  ENTRY_POINT                     = InstallPchSpi
+
+[Sources]
+  Smm/PchSpi.h
+  Smm/PchSpi.c
+  Common/SpiCommon.c
+  Common/SpiCommon.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  IoLib
+  IntelQNCLib
+  QNCAccessLib
+  TimerLib
+  S3BootScriptLib
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  BaseLib
+  SmmServicesTableLib
+
+[Protocols]
+  gEfiSmmSpiProtocolGuid      # PRODUCES
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+[Depex]
+  gEfiSmmBase2ProtocolGuid
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.c
new file mode 100644
index 0000000000..393d60b29e
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.c
@@ -0,0 +1,205 @@
+/** @file
+PCH SPI Runtime Driver implements the SPI Host Controller Compatibility Interface.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "PchSpi.h"
+
+extern EFI_GUID gEfiEventVirtualAddressChangeGuid;
+
+//
+// Global variables
+//
+SPI_INSTANCE  *mSpiInstance;
+CONST UINT32 mSpiRegister[] = {
+  R_QNC_RCRB_SPIS,
+  R_QNC_RCRB_SPIPREOP,
+  R_QNC_RCRB_SPIOPMENU,
+  R_QNC_RCRB_SPIOPMENU + 4
+  };
+
+//
+// Function implementations
+//
+VOID
+PchSpiVirtualddressChangeEvent (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  )
+/*++
+
+Routine Description:
+
+  Fixup internal data pointers so that the services can be called in virtual mode.
+
+Arguments:
+
+  Event     The event registered.
+  Context   Event context. Not used in this event handler.
+
+Returns:
+
+  None.
+
+--*/
+{
+  gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSpiInstance->PchRootComplexBar));
+  gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSpiInstance->SpiProtocol.Init));
+  gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSpiInstance->SpiProtocol.Lock));
+  gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSpiInstance->SpiProtocol.Execute));
+  gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSpiInstance));
+}
+
+EFI_STATUS
+EFIAPI
+InstallPchSpi (
+  IN EFI_HANDLE            ImageHandle,
+  IN EFI_SYSTEM_TABLE      *SystemTable
+  )
+/*++
+
+Routine Description:
+
+  Entry point for the SPI host controller driver.
+
+Arguments:
+
+  ImageHandle       Image handle of this driver.
+  SystemTable       Global system service table.
+
+Returns:
+
+  EFI_SUCCESS           Initialization complete.
+  EFI_UNSUPPORTED       The chipset is unsupported by this driver.
+  EFI_OUT_OF_RESOURCES  Do not have enough resources to initialize the driver.
+  EFI_DEVICE_ERROR      Device error, driver exits abnormally.
+
+--*/
+{
+  EFI_STATUS                      Status;
+  UINT64                          BaseAddress;
+  UINT64                          Length;
+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdMemorySpaceDescriptor;
+  UINT64                          Attributes;
+  EFI_EVENT                       Event;
+
+  DEBUG ((DEBUG_INFO, "InstallPchSpi() Start\n"));
+
+  //
+  // Allocate Runtime memory for the SPI protocol instance.
+  //
+  mSpiInstance = AllocateRuntimeZeroPool (sizeof (SPI_INSTANCE));
+  if (mSpiInstance == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  //
+  // Initialize the SPI protocol instance
+  //
+  Status = SpiProtocolConstructor (mSpiInstance);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Install the EFI_SPI_PROTOCOL interface
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &(mSpiInstance->Handle),
+                  &gEfiSpiProtocolGuid,
+                  &(mSpiInstance->SpiProtocol),
+                  NULL
+                  );
+  if (EFI_ERROR (Status)) {
+    FreePool (mSpiInstance);
+    return EFI_DEVICE_ERROR;
+  }
+  //
+  // Set RCBA space in GCD to be RUNTIME so that the range will be supported in
+  // virtual address mode in EFI aware OS runtime.
+  // It will assert if RCBA Memory Space is not allocated
+  // The caller is responsible for the existence and allocation of the RCBA Memory Spaces
+  //
+  BaseAddress = (EFI_PHYSICAL_ADDRESS) (mSpiInstance->PchRootComplexBar);
+  Length      = PcdGet64 (PcdRcbaMmioSize);
+
+  Status      = gDS->GetMemorySpaceDescriptor (BaseAddress, &GcdMemorySpaceDescriptor);
+  ASSERT_EFI_ERROR (Status);
+
+  Attributes = GcdMemorySpaceDescriptor.Attributes | EFI_MEMORY_RUNTIME;
+
+  Status = gDS->AddMemorySpace (
+                  EfiGcdMemoryTypeMemoryMappedIo,
+                  BaseAddress,
+                  Length,
+                  EFI_MEMORY_RUNTIME | EFI_MEMORY_UC
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+  Status = gDS->SetMemorySpaceAttributes (
+                  BaseAddress,
+                  Length,
+                  Attributes
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  PchSpiVirtualddressChangeEvent,
+                  NULL,
+                  &gEfiEventVirtualAddressChangeGuid,
+                  &Event
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "InstallPchSpi() End\n"));
+
+  return EFI_SUCCESS;
+}
+
+VOID
+EFIAPI
+SpiPhaseInit (
+  VOID
+  )
+/*++
+Routine Description:
+
+  This function is a a hook for Spi Dxe phase specific initialization
+
+Arguments:
+
+  None
+
+Returns:
+
+  None
+
+--*/
+{
+  UINTN  Index;
+
+  //
+  // Disable SMM BIOS write protect if it's not a SMM protocol
+  //
+  MmioAnd8 (
+    PciDeviceMmBase (PCI_BUS_NUMBER_QNC,
+    PCI_DEVICE_NUMBER_QNC_LPC,
+    PCI_FUNCTION_NUMBER_QNC_LPC) + R_QNC_LPC_BIOS_CNTL,
+    (UINT8) (~B_QNC_LPC_BIOS_CNTL_SMM_BWP)
+    );
+
+    //
+    // Save SPI Registers for S3 resume usage
+    //
+    for (Index = 0; Index < sizeof (mSpiRegister) / sizeof (UINT32); Index++) {
+    S3BootScriptSaveMemWrite (
+      S3BootScriptWidthUint32,
+        (UINTN) (mSpiInstance->PchRootComplexBar + mSpiRegister[Index]),
+        1,
+        (VOID *) (UINTN) (mSpiInstance->PchRootComplexBar + mSpiRegister[Index])
+        );
+    }
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.h
new file mode 100644
index 0000000000..33d64297f5
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.h
@@ -0,0 +1,79 @@
+/** @file
+Header file for the PCH SPI Runtime Driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _PCH_SPI_H_
+#define _PCH_SPI_H_
+
+#include <Library/PcdLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/Spi.h>
+#include "SpiCommon.h"
+#include <Library/PciExpressLib.h>
+#include <IntelQNCRegs.h>
+#include <Library/IntelQNCLib.h>
+#include <Library/QNCAccessLib.h>
+#include <Library/TimerLib.h>
+
+#define EFI_INTERNAL_POINTER  0x00000004
+
+
+//
+// Function prototypes used by the SPI protocol.
+//
+VOID
+PchSpiVirtualddressChangeEvent (
+  IN EFI_EVENT              Event,
+  IN VOID                   *Context
+  )
+/*++
+
+Routine Description:
+
+  Fixup internal data pointers so that the services can be called in virtual mode.
+
+Arguments:
+
+  Event     The event registered.
+  Context   Event context. Not used in this event handler.
+
+Returns:
+
+  None.
+
+--*/
+;
+
+VOID
+EFIAPI
+SpiPhaseInit (
+  VOID
+  )
+/*++
+Routine Description:
+
+  This function is a hook for Spi Dxe phase specific initialization
+
+Arguments:
+
+  None
+
+Returns:
+
+  None
+
+--*/
+;
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchSpi.c b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchSpi.c
new file mode 100644
index 0000000000..fe5cde3de7
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchSpi.c
@@ -0,0 +1,123 @@
+/** @file
+
+PCH SPI SMM Driver implements the SPI Host Controller Compatibility Interface.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+#include "PchSpi.h"
+
+SPI_INSTANCE          *mSpiInstance;
+
+CONST UINT32  mSpiRegister[] = {
+    R_QNC_RCRB_SPIS,
+    R_QNC_RCRB_SPIPREOP,
+    R_QNC_RCRB_SPIOPMENU,
+    R_QNC_RCRB_SPIOPMENU + 4
+  };
+
+EFI_STATUS
+EFIAPI
+InstallPchSpi (
+  IN EFI_HANDLE            ImageHandle,
+  IN EFI_SYSTEM_TABLE      *SystemTable
+  )
+/*++
+
+Routine Description:
+
+  Entry point for the SPI host controller driver.
+
+Arguments:
+
+  ImageHandle       Image handle of this driver.
+  SystemTable       Global system service table.
+
+Returns:
+
+  EFI_SUCCESS           Initialization complete.
+  EFI_UNSUPPORTED       The chipset is unsupported by this driver.
+  EFI_OUT_OF_RESOURCES  Do not have enough resources to initialize the driver.
+  EFI_DEVICE_ERROR      Device error, driver exits abnormally.
+
+--*/
+{
+  EFI_STATUS    Status;
+
+  //
+  // Allocate pool for SPI protocol instance
+  //
+  Status = gSmst->SmmAllocatePool (
+                    EfiRuntimeServicesData, // MemoryType don't care
+                    sizeof (SPI_INSTANCE),
+                    (VOID **) &mSpiInstance
+                    );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  if (mSpiInstance == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  ZeroMem ((VOID *) mSpiInstance, sizeof (SPI_INSTANCE));
+  //
+  // Initialize the SPI protocol instance
+  //
+  Status = SpiProtocolConstructor (mSpiInstance);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Install the SMM EFI_SPI_PROTOCOL interface
+  //
+  Status = gSmst->SmmInstallProtocolInterface (
+            &(mSpiInstance->Handle),
+            &gEfiSmmSpiProtocolGuid,
+            EFI_NATIVE_INTERFACE,
+            &(mSpiInstance->SpiProtocol)
+            );
+  if (EFI_ERROR (Status)) {
+    gSmst->SmmFreePool (mSpiInstance);
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+VOID
+EFIAPI
+SpiPhaseInit (
+  VOID
+  )
+/*++
+Routine Description:
+
+  This function is a a hook for Spi Smm phase specific initialization
+
+Arguments:
+
+  None
+
+Returns:
+
+  None
+
+--*/
+{
+  UINTN  Index;
+
+  //
+  // Save SPI Registers for S3 resume usage
+  //
+  for (Index = 0; Index < sizeof (mSpiRegister) / sizeof (UINT32); Index++) {
+    S3BootScriptSaveMemWrite (
+      S3BootScriptWidthUint32,
+      (UINTN) (mSpiInstance->PchRootComplexBar + mSpiRegister[Index]),
+      1,
+      (VOID *) (UINTN) (mSpiInstance->PchRootComplexBar + mSpiRegister[Index])
+      );
+  }
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchSpi.h b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchSpi.h
new file mode 100644
index 0000000000..a016a0e7c4
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchSpi.h
@@ -0,0 +1,47 @@
+/** @file
+Header file for the PCH SPI SMM Driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _PCH_SPI_H_
+#define _PCH_SPI_H_
+
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Protocol/Spi.h>
+#include "SpiCommon.h"
+#include <Library/SmmServicesTableLib.h>
+#include <IntelQNCRegs.h>
+#include <Library/IntelQNCLib.h>
+#include <Library/QNCAccessLib.h>
+#include <Library/TimerLib.h>
+
+VOID
+EFIAPI
+SpiPhaseInit (
+  VOID
+  )
+/*++
+Routine Description:
+
+  This function is a hook for Spi Smm phase specific initialization
+
+Arguments:
+
+  None
+
+Returns:
+
+  None
+
+--*/
+;
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dec b/Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dec
new file mode 100644
index 0000000000..22cb0a2d79
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dec
@@ -0,0 +1,234 @@
+## @file
+# INTEL Quark SoC Module Package Reference Implementations
+#
+# This Module provides FRAMEWORK reference implementation for INTEL Quark SoC.
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+
+[Defines]
+  DEC_SPECIFICATION              = 0x00010005
+  PACKAGE_NAME                   = QuarkSocPkg
+  PACKAGE_GUID                   = 28DECF17-6C75-448f-87DC-BDE4BD579919
+  PACKAGE_VERSION                = 0.1
+
+
+
+################################################################################
+#
+# Include Section - list of Include Paths that are provided by this package.
+#                   Comments are used for Keywords and Module Types.
+#
+# Supported Module Types:
+#  SEC PEIM DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER BASE
+#
+################################################################################
+[Includes]
+  #
+  # North Cluster
+  #
+  QuarkNorthCluster/Include
+  QuarkNorthCluster/MemoryInit/Pei
+
+  #
+  # South Cluster
+  #
+  QuarkSouthCluster/Include
+
+################################################################################
+#
+# Library Class Header section - list of Library Class header files that are
+#                                provided by this package.
+#
+################################################################################
+[LibraryClasses]
+  #
+  # North Cluster
+  #
+  QNCAccessLib|QuarkNorthCluster/Include/Library/QNCAccessLib.h
+  IntelQNCLib|QuarkNorthCluster/Include/Library/IntelQNCLib.h
+  IohLib|QuarkSouthCluster/Include/Library/IohLib.h
+  I2cLib|QuarkSouthCluster/Include/Library/I2cLib.h
+
+################################################################################
+#
+# Global Guid Definition section - list of Global Guid C Name Data Structures
+#                                  that are provided by this package.
+#
+################################################################################
+[Guids]
+  #
+  # North Cluster
+  #
+  gEfiQuarkNcSocIdTokenSpaceGuid  = { 0xca452c6a, 0xdf0c, 0x4dc9, { 0x82, 0xfb, 0xea, 0xe2, 0xab, 0x31, 0x29, 0x46 }}
+  gQncS3CodeInLockBoxGuid   =  { 0x1f18c5b3, 0x29ed, 0x4d9e, {0xa5, 0x4, 0x6d, 0x97, 0x8e, 0x7e, 0xd5, 0x69}}
+  gQncS3ContextInLockBoxGuid = { 0xe5769ea9, 0xe706, 0x454b, {0x95, 0x7f, 0xaf, 0xc6, 0xdb, 0x4b, 0x8a, 0xd}}
+
+  #
+  # South Cluster
+  #
+  gEfiQuarkSCSocIdTokenSpaceGuid  = { 0xef251b71, 0xceed, 0x484e, { 0x82, 0xe3, 0x3a, 0x1f, 0x34, 0xf5, 0x12, 0xe2 }}
+
+################################################################################
+#
+# Global Ppi Definition section - list of Global Ppi C Name Data Structures
+#                                  that are provided by this package.
+#
+################################################################################
+[Ppis]
+  #
+  # North Cluster
+  #
+  gQNCMemoryInitPpiGuid = { 0x21ff1fee, 0xd33a, 0x4fce, { 0xa6, 0x5e, 0x95, 0x5e, 0xa3, 0xc4, 0x1f, 0x40}}
+
+################################################################################
+#
+# Global Protocols Definition section - list of Global Protocols C Name Data
+#                                  Structures that are provided by this package.
+#
+################################################################################
+[Protocols]
+  #
+  # North Cluster
+  #
+  gEfiPlatformPolicyProtocolGuid = { 0x2977064F, 0xAB96, 0x4FA9, { 0x85, 0x45, 0xF9, 0xC4, 0x02, 0x51, 0xE0, 0x7F }}
+  gEfiSmmIchnDispatch2ProtocolGuid = { 0xadf3a128, 0x416d, 0x4060, { 0x8d, 0xdf, 0x30, 0xa1, 0xd7, 0xaa, 0xb6, 0x99 }}
+  gEfiSpiProtocolGuid = { 0x1156efc6, 0xea32, 0x4396, { 0xb5, 0xd5, 0x26, 0x93, 0x2e, 0x83, 0xc3, 0x13 }}
+  gEfiSmmSpiProtocolGuid  = { 0xD9072C35, 0xEB8F, 0x43ad, { 0xA2, 0x20, 0x34, 0xD4, 0x0E, 0x2A, 0x82, 0x85 }}
+  gEfiQncS3SupportProtocolGuid  = { 0xe287d20b, 0xd897, 0x4e1e, { 0xa5, 0xd9, 0x97, 0x77, 0x63, 0x93, 0x6a, 0x4 }}
+
+  #
+  # South Cluster
+  #
+  gEfiSDHostIoProtocolGuid = {0xb63f8ec7, 0xa9c9, 0x4472, {0xa4, 0xc0, 0x4d, 0x8b, 0xf3, 0x65, 0xcc, 0x51}}
+
+################################################################################
+#
+# PCD Declarations section - list of all PCDs Declared by this Package
+#                            Only this package should be providing the
+#                            declaration, other packages should not.
+#
+################################################################################
+
+[PcdsFeatureFlag]
+  #
+  # North Cluster
+  #
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdSmbaIoBaseAddressFixed|TRUE|BOOLEAN|0x10000001
+
+  #
+  # South Cluster
+  #
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdEhciRecoveryEnabled|FALSE|BOOLEAN|0x10000003
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdI2CFastModeEnabled|FALSE|BOOLEAN|0x10000005
+
+  #
+  # Feature Flag equivalent to linux SDHCI_QUIRK_NO_HISPD_BIT to stop
+  # setting of SD HCI hi_spd_en bit in HOST_CTL register.
+  #
+  # Alway TRUE ie high speed enable bit must never
+  # be set so we stay within SD interface Setup/Hold time.
+  #
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdSdHciQuirkNoHiSpd|TRUE|BOOLEAN|0x10000004
+
+[PcdsFixedAtBuild]
+  #
+  # North Cluster
+  #
+
+  # Values of Io Port Base Address, MMIO base address and space size.
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPm1blkIoBaseAddress|0x1000|UINT16|0x10000200
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPmbaIoBaseAddress|0x1010|UINT16|0x10000201
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPmbaIoLVL2|0x1014|UINT16|0x10000202
+
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdGbaIoBaseAddress|0x1080|UINT16|0x10000205
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdGpe0blkIoBaseAddress|0x1100|UINT16|0x10000206
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdSmbaIoBaseAddress|0x1040|UINT16|0x10000207
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdWdtbaIoBaseAddress|0x1140|UINT16|0x10000209
+
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdRcbaMmioBaseAddress|0xFED1C000|UINT64|0x1000020B
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdIoApicBaseAddress|0xFEC00000|UINT64|0x1000020C
+
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdIoApicSize|0x1000|UINT64|0x1000020D
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdRcbaMmioSize|0x4000|UINT64|0x1000020E
+
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciExpressSize|0x02000000|UINT64|0x1000020F
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdHpetBaseAddress|0xFED00000|UINT64|0x10000210
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdHpetSize|0x400|UINT64|0x10000211
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdTSegSize|0x200000|UINT32|0x10000212
+
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeIoBase|0x2000|UINT16|0x10000214
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeIoSize|0xE000|UINT16|0x10000215
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeMemory32Base|0x90000000|UINT32|0x1000021B
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeMemory32Size|0x20000000|UINT32|0x1000021C
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeMemory64Base|0xB0000000|UINT64|0x1000021D
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeMemory64Size|0x30000000|UINT64|0x1000021E
+
+  # Values for programming Interrupt Route Configuration Registers:
+  # Indicates which interrupt routing is connected to the INTA/B/C/D pins reported in the
+  # "DxIP" register fields. This will be the internal routing, the device interrupt is connected
+  # to the interrupt controller.
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdQuarkAgent0IR|0x0000|UINT16|0x10000223
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdQuarkAgent1IR|0x7654|UINT16|0x10000224
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdQuarkAgent2IR|0x0000|UINT16|0x10000225
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdQuarkAgent3IR|0x3210|UINT16|0x10000226
+
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdSmmActivationPort|0xb2|UINT16|0x10000232
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdSmmDataPort|0xb3|UINT16|0x10000233
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdSmmActivationData|0x55|UINT8|0x10000234
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPlatformSmbusAddrNum|0x0|UINT32|0x10000235
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPlatformSmbusAddrTable|0x0|UINT64|0x10000236
+
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdESramMemorySize|0x00080000|UINT32|0x10000240
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdDeviceEnables|0x03|UINT32|0x10000237
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPcieRootPortConfiguration|{0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00}|VOID*|0x10000239
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdQuarkMicrocodeFile |{ 0x8B, 0xEA, 0x5E, 0xD7, 0xD2, 0x23, 0xD4, 0x4E, 0xBC, 0x4F, 0x57, 0x51, 0xD4, 0xA1, 0x8D, 0xCF }|VOID*|0x1000023A
+
+  #
+  # South Cluster
+  #
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohI2cMmioBase|0xA001F000|UINT64|0x20000005
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdPeiP2PMemoryBaseAddress|0xA0000000|UINT32|0x20000006
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdPeiQNCUsbControllerMemoryBaseAddress|0xA0010000|UINT32|0x20000007
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioMmioBase|0xA0020000|UINT64|0x20000008
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohMac0MmioBase|0xA0024000|UINT64|0x20000009
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohMac1MmioBase|0xA0028000|UINT64|0x2000000A
+
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohUartBusNumber|0x00|UINT8|0x20000013
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohUartDevNumber|0x14|UINT8|0x20000014
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohUartFunctionNumber|0x5|UINT8|0x20000001
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioBusNumber|0x00|UINT8|0x20000029
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioDevNumber|0x15|UINT8|0x2000002A
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioFunctionNumber|0x2|UINT8|0x2000002B
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioBarRegister|0x14|UINT8|0x2000002D
+
+[PcdsDynamic, PcdsDynamicEx]
+  #
+  # North Cluster
+  #
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdQncS3CodeInLockBoxAddress|0|UINT64|0x30000026
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdQncS3CodeInLockBoxSize|0|UINT64|0x30000027
+
+  ## Intel(R) Quark(TM) Soc X1000 processor MRC Parameters.  Default is for Galileo Gen 2 platform.<BR><BR>
+  # @Prompt Intel(R) Quark(TM) Soc X1000 processor MRC Parameters.
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdMrcParameters|{0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x7c, 0x92, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x40, 0x9c, 0x00, 0x00, 0x06}|VOID*|0x40000001
+
+  #
+  # South Cluster
+  #
+  ## MAC0 address for the Ethernet Controller in Intel(R) Quark(TM) Soc X1000 processor.  Default is 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff.<BR><BR>
+  # @Prompt Ethernet MAC 0 Address.
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohEthernetMac0|{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}|VOID*|0x50000001
+
+  ## MAC1 address for the Ethernet Controller in Intel(R) Quark(TM) Soc X1000 processor.  Default is 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff.<BR><BR>
+  # @Prompt Ethernet MAC 1 Address.
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohEthernetMac1|{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}|VOID*|0x50000002
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dsc b/Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dsc
new file mode 100644
index 0000000000..e743a5e272
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dsc
@@ -0,0 +1,254 @@
+## @file
+# INTEL Quark SoC Module Package Reference Implementations
+#
+# This DSC file is used for Package Level build.
+#
+# This Module provides FRAMEWORK reference implementation for INTEL Quark SoC.
+#   Copyright (c) 2013-2016 Intel Corporation.
+#
+#   SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  PLATFORM_NAME                  = QuarkSocPkg
+  PLATFORM_GUID                  = 5F9864F4-EAFB-4ded-A41A-CA501EE50502
+  PLATFORM_VERSION               = 0.1
+  DSC_SPECIFICATION              = 0x00010005
+  OUTPUT_DIRECTORY               = Build/QuarkSocPkg
+  SUPPORTED_ARCHITECTURES        = IA32
+  BUILD_TARGETS                  = DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+
+################################################################################
+#
+# SKU Identification section - list of all SKU IDs supported by this
+#                              Platform.
+#
+################################################################################
+[SkuIds]
+  0|DEFAULT              # The entry: 0|DEFAULT is reserved and always required.
+
+################################################################################
+#
+# Library Class section - list of all Library Classes needed by this Platform.
+#
+################################################################################
+[LibraryClasses]
+  #
+  # Entry point
+  #
+  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+  #
+  # Basic
+  #
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+  PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
+  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
+  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
+  CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+!if $(CFG_SOURCE_DEBUG) == 1
+  PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
+!else
+  PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+!endif
+  #
+  # UEFI & PI
+  #
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+  UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
+  #
+  # Framework
+  #
+  S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
+  S3IoLib|MdePkg/Library/BaseS3IoLib/BaseS3IoLib.inf
+  S3PciLib|MdePkg/Library/BaseS3PciLib/BaseS3PciLib.inf
+  #
+  # Generic Modules
+  #
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+
+  #
+  # CPU
+  #
+  MtrrLib|QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.inf
+  #
+  # Quark North Cluster
+  #
+  SmmLib|QuarkSocPkg/QuarkNorthCluster/Library/QNCSmmLib/QNCSmmLib.inf
+  SmbusLib|QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/SmbusLib.inf
+  TimerLib|PcAtChipsetPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
+  ResetSystemLib|QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/ResetSystemLib.inf
+  IntelQNCLib|QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNCLib.inf
+  QNCAccessLib|QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/QNCAccessLib.inf
+  #
+  # Quark South Cluster
+  #
+  IohLib|QuarkSocPkg/QuarkSouthCluster/Library/IohLib/IohLib.inf
+  SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
+  PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf
+  #
+  # Misc
+  #
+  DebugLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+!if $(CFG_SOURCE_DEBUG) == TRUE
+  DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf
+!else
+  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+!endif
+
+[LibraryClasses.IA32.PEIM,LibraryClasses.IA32.PEI_CORE]
+  #
+  # SEC and PEI phase common
+  #
+  PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+  LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf
+  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+!if $(CFG_SOURCE_DEBUG) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
+!endif
+  TimerLib|PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
+
+[LibraryClasses.IA32.SEC]
+  #
+  # SEC specific phase
+  #
+  ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  TimerLib|PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
+
+[LibraryClasses.IA32]
+  #
+  # DXE phase common
+  #
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+  LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf
+!if $(CFG_SOURCE_DEBUG) == 1
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+
+[LibraryClasses.IA32.DXE_SMM_DRIVER]
+  SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/SmmReportStatusCodeLib.inf
+  MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf
+  LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf
+!if $(CFG_SOURCE_DEBUG) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf
+!endif
+
+[LibraryClasses.IA32.SMM_CORE]
+  ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/SmmReportStatusCodeLib.inf
+
+[LibraryClasses.IA32.DXE_RUNTIME_DRIVER]
+  ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf
+
+[LibraryClasses.IA32.UEFI_DRIVER,LibraryClasses.IA32.UEFI_APPLICATION]
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsFixedAtBuild]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialLineControl|0x03
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialFifoControl|0x07
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialDetectCable|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate|44236800
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialPciDeviceInfo|{0x14, 0x05, 0x84, 0x00, 0xFF}
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride|4
+
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBusNumber           |0
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciDeviceNumber        |31
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciFunctionNumber      |0
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciEnableRegisterOffset|0x4b
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoBarEnableMask          |0x80
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBarRegisterOffset   |0x48
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddress        |0x1000
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiPm1TmrOffset             |0x0008
+
+[PcdsFeatureFlag]
+
+################################################################################
+#
+# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsDynamicDefault.common.DEFAULT]
+
+###################################################################################################
+#
+# Components Section - list of the modules and components that will be processed by compilation
+#                      tools and the EDK II tools to generate PE32/PE32+/Coff image files.
+#
+# Note: The EDK II DSC file is not used to specify how compiled binary images get placed
+#       into firmware volume images. This section is just a list of modules to compile from
+#       source into UEFI-compliant binaries.
+#       It is the FDF file that contains information on combining binary files into firmware
+#       volume images, whose concept is beyond UEFI and is described in PI specification.
+#       Binary modules do not need to be listed in this section, as they should be
+#       specified in the FDF file. For example: Shell binary (Shell_Full.efi), FAT binary (Fat.efi),
+#       Logo (Logo.bmp), and etc.
+#       There may also be modules listed in this section that are not required in the FDF file,
+#       When a module listed here is excluded from FDF file, then UEFI-compliant binary will be
+#       generated for it, but the binary will not be put into any firmware volume.
+#
+###################################################################################################
+
+[Components]
+  QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInitPei.inf
+  QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmAccessPei/SmmAccessPei.inf
+  QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/SmmControlPei.inf
+  QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInitDxe.inf
+  QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/SmmAccess.inf
+  QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiRuntime.inf {
+    <LibraryClasses>
+      PciExpressLib|MdePkg/Library/DxeRuntimePciExpressLib/DxeRuntimePciExpressLib.inf
+  }
+  QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiSmm.inf
+  QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.inf {
+    <LibraryClasses>
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+  QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmControlDxe/SmmControlDxe.inf
+  QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmDispatcher.inf
+
+  QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.inf
+  QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciPei.inf
+  QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohInitDxe.inf
+  QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDxe.inf
+  QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SDControllerDxe.inf
+  QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/SDMediaDeviceDxe.inf
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/CEATA.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/CEATA.h
new file mode 100644
index 0000000000..f038c34238
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/CEATA.h
@@ -0,0 +1,114 @@
+/** @file
+
+Header file for chipset CE-AT spec.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _CE_ATA_H
+#define _CE_ATA_H
+
+#pragma pack(1)
+
+
+#define  DATA_UNIT_SIZE       512
+
+
+#define  CMD60                60
+#define  CMD61                61
+
+
+#define RW_MULTIPLE_REGISTER  CMD60
+#define RW_MULTIPLE_BLOCK     CMD61
+
+
+#define CE_ATA_SIG_CE         0xCE
+#define CE_ATA_SIG_AA         0xAA
+
+
+#define Reg_Features_Exp      01
+#define Reg_SectorCount_Exp   02
+#define Reg_LBALow_Exp        03
+#define Reg_LBAMid_Exp        04
+#define Reg_LBAHigh_Exp       05
+#define Reg_Control           06
+#define Reg_Features_Error    09
+#define Reg_SectorCount       10
+#define Reg_LBALow            11
+#define Reg_LBAMid            12
+#define Reg_LBAHigh           13
+#define Reg_Device_Head       14
+#define Reg_Command_Status    15
+
+#define Reg_scrTempC          0x80
+#define Reg_scrTempMaxP       0x84
+#define Reg_scrTempMinP       0x88
+#define Reg_scrStatus         0x8C
+#define Reg_scrReallocsA      0x90
+#define Reg_scrERetractsA     0x94
+#define Reg_scrCapabilities   0x98
+#define Reg_scrControl        0xC0
+
+
+
+typedef struct {
+  UINT8  Reserved0;
+  UINT8  Features_Exp;
+  UINT8  SectorCount_Exp;
+  UINT8  LBALow_Exp;
+  UINT8  LBAMid_Exp;
+  UINT8  LBAHigh_Exp;
+  UINT8  Control;
+  UINT8  Reserved1[2];
+  UINT8  Features_Error;
+  UINT8  SectorCount;
+  UINT8  LBALow;
+  UINT8  LBAMid;
+  UINT8  LBAHigh;
+  UINT8  Device_Head;
+  UINT8  Command_Status;
+}TASK_FILE;
+
+
+//
+//Reduced ATA command set
+//
+#define IDENTIFY_DEVICE       0xEC
+#define READ_DMA_EXT          0x25
+#define WRITE_DMA_EXT         0x35
+#define STANDBY_IMMEDIATE     0xE0
+#define FLUSH_CACHE_EXT       0xEA
+
+
+
+typedef struct {
+  UINT16  Reserved0[10];
+  UINT16  SerialNumber[10];
+  UINT16  Reserved1[3];
+  UINT16  FirmwareRevision[4];
+  UINT16  ModelNumber[20];
+  UINT16  Reserved2[33];
+  UINT16  MajorVersion;
+  UINT16  Reserved3[19];
+  UINT16  MaximumLBA[4];
+  UINT16  Reserved4[2];
+  UINT16  Sectorsize;
+  UINT16  Reserved5;
+  UINT16  DeviceGUID[4];
+  UINT16  Reserved6[94];
+  UINT16  Features;
+  UINT16  MaxWritesPerAddress;
+  UINT16  Reserved7[47];
+  UINT16  IntegrityWord;
+}IDENTIFY_DEVICE_DATA;
+
+
+
+
+
+#pragma pack()
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/I2cRegs.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/I2cRegs.h
new file mode 100644
index 0000000000..e2a3c313fc
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/I2cRegs.h
@@ -0,0 +1,95 @@
+/** @file
+Include file for I2C DXE Driver register definitions (PCIe config. space and memory space).
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _I2C_REGS_H_
+#define _I2C_REGS_H_
+
+
+//----------------------------------------------------------------------------
+/// I2C Device Address
+//----------------------------------------------------------------------------
+typedef struct {
+  ///
+  /// The I2C hardware address to which the I2C device is preassigned or allocated.
+  ///
+  UINTN I2CDeviceAddress : 10;
+} EFI_I2C_DEVICE_ADDRESS;
+
+//----------------------------------------------------------------------------
+/// I2C Addressing Mode (7-bit or 10 bit)
+//----------------------------------------------------------------------------
+typedef enum _EFI_I2C_ADDR_MODE {
+  EfiI2CSevenBitAddrMode,
+  EfiI2CTenBitAddrMode,
+} EFI_I2C_ADDR_MODE;
+
+
+//----------------------------------------------------------------------------
+// I2C Controller B:D:F
+//----------------------------------------------------------------------------
+#define I2C_Bus     0x00
+#define I2C_Device  0x15
+#define I2C_Func    0x02
+
+//----------------------------------------------------------------------------
+// Memory Mapped Registers
+//----------------------------------------------------------------------------
+#define I2C_REG_CON                        0x00          // Control Register
+#define   B_I2C_REG_CON_SPEED                (BIT2+BIT1)   // standard mode (01) or fast mode (10)
+#define   B_I2C_REG_CON_10BITADD_MASTER      (BIT4)        // 7-bit addressing (0) or 10-bit addressing (1)
+#define I2C_REG_TAR                        0x04          // Master Target Address Register
+#define   B_I2C_REG_TAR                      (BIT9+BIT8+BIT7+BIT6+BIT5+BIT4+BIT3+BIT2+BIT1+BIT0) // Master Target Address bits
+#define I2C_REG_DATA_CMD                   0x10          // Data Buffer and Command Register
+#define   B_I2C_REG_DATA_CMD_RW              (BIT8)      // Data Buffer and Command Register Read/Write bit
+#define   B_I2C_REG_DATA_CMD_STOP            (BIT9)      // Data Buffer and Command Register STOP bit
+#define   B_I2C_REG_DATA_CMD_RESTART         (BIT10)     // Data Buffer and Command Register RESTART bit
+#define I2C_REG_SS_SCL_HCNT                0x14          // Standard Speed Clock SCL High Count Register
+#define I2C_REG_SS_SCL_LCNT                0x18          // Standard Speed Clock SCL Low Count Register
+#define I2C_REG_FS_SCL_HCNT                0x1C          // Fast Speed Clock SCL High Count Register
+#define I2C_REG_FS_SCL_LCNT                0x20          // Fast Speed Clock SCL Low Count Register
+#define I2C_REG_INTR_STAT                  0x2C          // Interrupt Status Register
+#define   B_I2C_REG_INTR_STAT_STOP_DET       (BIT9)        // Interrupt Status Register STOP_DET signal status
+#define I2C_REG_INTR_MASK                  0x30          // Interrupt Status Mask Register
+#define I2C_REG_RAW_INTR_STAT              0x34          // Raw Interrupt Status Register
+#define   I2C_REG_RAW_INTR_STAT_STOP_DET    (BIT9)         // Raw Interrupt Status Register STOP_DET signal status.
+#define   I2C_REG_RAW_INTR_STAT_TX_ABRT     (BIT6)         // Raw Interrupt Status Register TX Abort status.
+#define   I2C_REG_RAW_INTR_STAT_TX_OVER     (BIT3)         // Raw Interrupt Status Register TX Overflow signal status.
+#define   I2C_REG_RAW_INTR_STAT_RX_OVER     (BIT1)         // Raw Interrupt Status Register RX Overflow signal status.
+#define   I2C_REG_RAW_INTR_STAT_RX_UNDER    (BIT0)         // Raw Interrupt Status Register RX Underflow signal status.
+#define I2C_REG_RX_TL                      0x38          // Receive FIFO Threshold Level Register
+#define I2C_REG_TX_TL                      0x3C          // Transmit FIFO Threshold Level Register
+#define I2C_REG_CLR_INT                    0x40          // Clear Combined and Individual Interrupt Register
+#define I2C_REG_CLR_RX_UNDER               0x44          // Clear RX Under Interrupt Register
+#define I2C_REG_CLR_RX_OVER                0x48          // Clear RX Over Interrupt Register
+#define I2C_REG_CLR_TX_OVER                0x4C          // Clear TX Over Interrupt Register
+#define I2C_REG_CLR_RD_REQ                 0x50          // Clear RD REQ Interrupt Register
+#define I2C_REG_CLR_TX_ABRT                0x54          // Clear TX ABRT Interrupt Register
+#define I2C_REG_CLR_ACTIVITY               0x5C          // Clear Activity Interrupt Register
+#define I2C_REG_CLR_STOP_DET               0x60          // Clear STOP DET Interrupt Register
+#define   B_I2C_REG_CLR_STOP_DET             (BIT0)        // Clear STOP DET Interrupt Register
+#define I2C_REG_CLR_START_DET              0x64          // Clear START DET Interrupt Register
+#define   B_I2C_REG_CLR_START_DET          (BIT0)          // Clear START DET Interrupt Register
+#define I2C_REG_ENABLE                     0x6C          // Enable Register
+#define   B_I2C_REG_ENABLE                   (BIT0)        // Enable (1) or disable (0) I2C Controller
+#define I2C_REG_STATUS                     0x70          // Status Register
+#define I2C_REG_TXFLR                      0x74          // Transmit FIFO Level Register
+#define   B_I2C_REG_TXFLR                   (BIT3+BIT2+BIT1+BIT0)  // Transmit FIFO Level Register bits
+#define I2C_REG_RXFLR                      0x78          // Receive FIFO Level Register
+#define   B_I2C_REG_RXFLR                   (BIT3+BIT2+BIT1+BIT0)  // Receive FIFO Level Register bits
+#define I2C_REG_SDA_HOLD                   0x7C          // SDA HOLD Register
+#define I2C_REG_TX_ABRT_SOURCE             0x80          // Transmit Abort Source Register
+#define I2C_REG_ENABLE_STATUS              0x9C          // Enable Status Register
+#define I2C_REG_FS_SPKLEN                  0xA0          // SS and FS Spike Suppression Limit Register
+
+//
+// Features.
+//
+#define I2C_FIFO_SIZE                      16
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Ioh.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Ioh.h
new file mode 100644
index 0000000000..f6066e8d10
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Ioh.h
@@ -0,0 +1,248 @@
+/** @file
+Header file for QuarkSCSocId Ioh.
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+#ifndef _IOH_H_
+#define _IOH_H_
+
+#ifndef BIT0
+#define BIT0    0x01
+#define BIT1    0x02
+#define BIT2    0x04
+#define BIT3    0x08
+#define BIT4    0x10
+#define BIT5    0x20
+#define BIT6    0x40
+#define BIT7    0x80
+#define BIT8    0x100
+#define BIT9    0x200
+#define BIT00   0x00000001
+#define BIT01   0x00000002
+#define BIT02   0x00000004
+#define BIT03   0x00000008
+#define BIT04   0x00000010
+#define BIT05   0x00000020
+#define BIT06   0x00000040
+#define BIT07   0x00000080
+#define BIT08   0x00000100
+#define BIT09   0x00000200
+#define BIT10   0x00000400
+#define BIT11   0x00000800
+#define BIT12   0x00001000
+#define BIT13   0x00002000
+#define BIT14   0x00004000
+#define BIT15   0x00008000
+#define BIT16   0x00010000
+#define BIT17   0x00020000
+#define BIT18   0x00040000
+#define BIT19   0x00080000
+#define BIT20   0x00100000
+#define BIT21   0x00200000
+#define BIT22   0x00400000
+#define BIT23   0x00800000
+#define BIT24   0x01000000
+#define BIT25   0x02000000
+#define BIT26   0x04000000
+#define BIT27   0x08000000
+#define BIT28   0x10000000
+#define BIT29   0x20000000
+#define BIT30   0x40000000
+#define BIT31   0x80000000
+#endif
+
+#define IOH_PCI_CFG_ADDRESS(bus,dev,func,reg) \
+    ((UINT32) ( (((UINTN)bus) << 24) + (((UINTN)dev) << 16) + \
+    (((UINTN)func) << 8) + ((UINTN)reg) ))& 0x00000000ffffffff
+
+//----------------------------------------------------------------------------
+
+#define INTEL_VENDOR_ID         0x8086  // Intel Vendor ID
+
+//----------------------------------------------------------------------------
+// Pci Configuration Map Register Offsets
+//----------------------------------------------------------------------------
+#define PCI_REG_VID             0x00    // Vendor ID Register
+#define PCI_REG_DID             0x02    // Device ID Register
+#define PCI_REG_PCICMD          0x04    // PCI Command Register
+#define PCI_REG_PCISTS          0x06    // PCI Status Register
+#define PCI_REG_RID             0x08    // PCI Revision ID Register
+#define PCI_REG_PI              0x09    // Programming Interface
+#define PCI_REG_SCC             0x0a    // Sub Class Code Register
+#define PCI_REG_BCC             0x0b    // Base Class Code Register
+#define PCI_REG_PMLT            0x0d    // Primary Master Latnecy Timer
+#define PCI_REG_HDR             0x0e    // Header Type Register
+#define PCI_REG_PBUS            0x18    // Primary Bus Number Register
+#define PCI_REG_SBUS            0x19    // Secondary Bus Number Register
+#define PCI_REG_SUBUS           0x1a    // Subordinate Bus Number Register
+#define PCI_REG_SMLT            0x1b    // Secondary Master Latnecy Timer
+#define PCI_REG_IOBASE          0x1c    // I/O base Register
+#define PCI_REG_IOLIMIT         0x1d    // I/O Limit Register
+#define PCI_REG_SECSTATUS       0x1e    // Secondary Status Register
+#define PCI_REG_MEMBASE         0x20    // Memory Base Register
+#define PCI_REG_MEMLIMIT        0x22    // Memory Limit Register
+#define PCI_REG_PRE_MEMBASE     0x24    // Prefretchable memory Base register
+#define PCI_REG_PRE_MEMLIMIT    0x26    // Prefretchable memory Limit register
+#define PCI_REG_SVID0           0x2c    // Subsystem Vendor ID low byte
+#define PCI_REG_SVID1           0x2d    // Subsystem Vendor ID high byte
+#define PCI_REG_SID0            0x2e    // Subsystem ID low byte
+#define PCI_REG_SID1            0x2f    // Subsystem ID high byte
+#define PCI_REG_IOBASE_U        0x30    // I/O base Upper Register
+#define PCI_REG_IOLIMIT_U       0x32    // I/O Limit Upper Register
+#define PCI_REG_INTLINE         0x3c    // Interrupt Line Register
+#define PCI_REG_BRIDGE_CNTL     0x3e    // Bridge Control Register
+
+//---------------------------------------------------------------------------
+// QuarkSCSocId Packet Hub definitions
+//---------------------------------------------------------------------------
+
+#define PCIE_BRIDGE_VID_DID     0x88008086
+
+//---------------------------------------------------------------------------
+// Quark South Cluster definitions.
+//---------------------------------------------------------------------------
+
+#define IOH_BUS                           0
+#define IOH_PCI_IOSF2AHB_0_DEV_NUM        0x14
+#define IOH_PCI_IOSF2AHB_0_MAX_FUNCS      7
+#define IOH_PCI_IOSF2AHB_1_DEV_NUM        0x15
+#define IOH_PCI_IOSF2AHB_1_MAX_FUNCS      3
+
+//---------------------------------------------------------------------------
+// Quark South Cluster USB definitions.
+//---------------------------------------------------------------------------
+
+#define IOH_USB_BUS_NUMBER                IOH_BUS
+#define IOH_USB_CONTROLLER_MMIO_RANGE     0x1000
+#define IOH_MAX_OHCI_USB_CONTROLLERS      1
+#define IOH_MAX_EHCI_USB_CONTROLLERS      1
+#define IOH_MAX_USBDEVICE_USB_CONTROLLERS 1
+
+#define R_IOH_USB_VENDOR_ID               0x00
+#define   V_IOH_USB_VENDOR_ID               INTEL_VENDOR_ID
+#define R_IOH_USB_DEVICE_ID               0x02
+#define R_IOH_USB_COMMAND                 0x04
+#define   B_IOH_USB_COMMAND_BME             BIT2
+#define   B_IOH_USB_COMMAND_MSE             BIT1
+#define   B_IOH_USB_COMMAND_ISE             BIT0
+#define R_IOH_USB_MEMBAR                  0x10
+#define   B_IOH_USB_MEMBAR_ADDRESS_MASK     0xFFFFF000  // [31:12].
+#define R_IOH_USB_OHCI_HCCABAR            0x18
+
+//---------------------------------------------------------------------------
+// Quark South Cluster OHCI definitions
+//---------------------------------------------------------------------------
+#define IOH_USB_OHCI_DEVICE_NUMBER        IOH_PCI_IOSF2AHB_0_DEV_NUM
+#define IOH_OHCI_FUNCTION_NUMBER          0x04
+
+//---------------------------------------------------------------------------
+// Quark South Cluster EHCI definitions
+//---------------------------------------------------------------------------
+#define IOH_USB_EHCI_DEVICE_NUMBER        IOH_PCI_IOSF2AHB_0_DEV_NUM
+#define IOH_EHCI_FUNCTION_NUMBER          0x03
+
+//
+// EHCI memory mapped registers offset from memory BAR0.
+//
+#define R_IOH_EHCI_CAPLENGTH              0x00
+#define R_IOH_EHCI_INSNREG01              0x94
+#define   B_IOH_EHCI_INSNREG01_OUT_THRESHOLD_BP    (16)
+#define   B_IOH_EHCI_INSNREG01_OUT_THRESHOLD_MASK  (0xff << B_IOH_EHCI_INSNREG01_OUT_THRESHOLD_BP)
+#define   B_IOH_EHCI_INSNREG01_IN_THRESHOLD_BP     (0)
+#define   B_IOH_EHCI_INSNREG01_IN_THRESHOLD_MASK   (0xff << B_IOH_EHCI_INSNREG01_IN_THRESHOLD_BP)
+
+//
+// EHCI memory mapped registers offset from memory BAR0 + Cap length value.
+//
+#define R_IOH_EHCI_CONFIGFLAGS            0x40
+
+//---------------------------------------------------------------------------
+// Quark South Cluster USB Device definitions
+//---------------------------------------------------------------------------
+#define IOH_USBDEVICE_DEVICE_NUMBER       IOH_PCI_IOSF2AHB_0_DEV_NUM
+#define IOH_USBDEVICE_FUNCTION_NUMBER     0x02
+
+//
+// USB Device memory mapped registers offset from memory BAR0.
+//
+#define R_IOH_USBDEVICE_D_INTR_UDC_REG                      0x40c
+#define R_IOH_USBDEVICE_D_INTR_MSK_UDC_REG                  0x410
+#define   B_IOH_USBDEVICE_D_INTR_MSK_UDC_REG_MASK1_MASK       0xff
+#define R_IOH_USBDEVICE_EP_INTR_UDC_REG                     0x414
+#define R_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG                 0x418
+#define   B_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG_OUT_EP_MASK     0x000f0000
+#define   B_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG_IN_EP_MASK      0x0000000f
+
+//---------------------------------------------------------------------------
+// Quark South Cluster 10/100 Mbps Ethernet Device definitions.
+//---------------------------------------------------------------------------
+#define IOH_MAC0_BUS_NUMBER                                 IOH_BUS
+#define IOH_MAC0_DEVICE_NUMBER                              IOH_PCI_IOSF2AHB_0_DEV_NUM
+#define IOH_MAC0_FUNCTION_NUMBER                            0x06
+#define IOH_MAC1_BUS_NUMBER                                 IOH_BUS
+#define IOH_MAC1_DEVICE_NUMBER                              IOH_PCI_IOSF2AHB_0_DEV_NUM
+#define IOH_MAC1_FUNCTION_NUMBER                            0x07
+
+//
+// MAC Device PCI config registers.
+//
+#define R_IOH_MAC_DEVICE_ID                                 0x02
+#define   V_IOH_MAC_VENDOR_ID                                 INTEL_VENDOR_ID
+#define R_IOH_MAC_DEVICE_ID                                 0x02
+#define   V_IOH_MAC_DEVICE_ID                                 0x0937
+#define R_IOH_MAC_COMMAND                                   0x04
+#define   B_IOH_MAC_COMMAND_BME                               BIT2
+#define   B_IOH_MAC_COMMAND_MSE                               BIT1
+#define   B_IOH_MAC_COMMAND_ISE                               BIT0
+#define R_IOH_MAC_MEMBAR                                    0x10
+#define   B_IOH_MAC_MEMBAR_ADDRESS_MASK                       0xFFFFF000
+
+//
+// LAN Device memory mapped registers offset from memory BAR0.
+//
+#define R_IOH_MAC_GMAC_REG_8                                0x20
+#define   B_IOH_MAC_USERVER_MASK                              0x0000FF00
+#define   B_IOH_MAC_SNPSVER_MASK                              0x000000FF
+#define R_IOH_MAC_GMAC_REG_16                               0x40
+#define   B_IOH_MAC_ADDRHI_MASK                               0x0000FFFF
+#define   B_IOH_MAC_AE                                        BIT31
+#define R_IOH_MAC_GMAC_REG_17                               0x44
+#define   B_IOH_MAC_ADDRLO_MASK                               0xFFFFFFFF
+
+//---------------------------------------------------------------------------
+// Quark I2C / GPIO definitions
+//---------------------------------------------------------------------------
+
+#define   V_IOH_I2C_GPIO_VENDOR_ID          INTEL_VENDOR_ID
+#define   V_IOH_I2C_GPIO_DEVICE_ID          0x0934
+
+#define R_IOH_I2C_MEMBAR                  0x10
+#define   B_IOH_I2C_GPIO_MEMBAR_ADDR_MASK   0xFFFFF000  // [31:12].
+
+#define GPIO_SWPORTA_DR                   0x00
+#define GPIO_SWPORTA_DDR                  0x04
+#define GPIO_INTEN                        0x30
+#define GPIO_INTMASK                      0x34
+#define GPIO_INTTYPE_LEVEL                0x38
+#define GPIO_INT_POLARITY                 0x3C
+#define GPIO_INTSTATUS                    0x40
+#define GPIO_RAW_INTSTATUS                0x44
+#define GPIO_DEBOUNCE                     0x48
+#define GPIO_PORTA_EOI                    0x4C
+#define GPIO_EXT_PORTA                    0x50
+#define GPIO_EXT_PORTB                    0x54
+#define GPIO_LS_SYNC                      0x60
+#define GPIO_CONFIG_REG2                  0x70
+#define GPIO_CONFIG_REG1                  0x74
+
+//---------------------------------------------------------------------------
+// Quark South Cluster UART definitions.
+//---------------------------------------------------------------------------
+
+#define R_IOH_UART_MEMBAR                 0x10
+#define   B_IOH_UART_MEMBAR_ADDRESS_MASK    0xFFFFF000  // [31:12].
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/IohAccess.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/IohAccess.h
new file mode 100644
index 0000000000..a259dd8df7
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/IohAccess.h
@@ -0,0 +1,18 @@
+/** @file
+Macros to simplify and abstract the interface to PCI configuration.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#ifndef _IOH_ACCESS_H_
+#define _IOH_ACCESS_H_
+
+#include "Ioh.h"
+#include "IohCommonDefinitions.h"
+
+#endif
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/IohCommonDefinitions.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/IohCommonDefinitions.h
new file mode 100644
index 0000000000..09f13e2f2a
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/IohCommonDefinitions.h
@@ -0,0 +1,342 @@
+/** @file
+This header file provides common definitions just for MCH using to avoid including extra module's file.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _IOH_COMMON_DEFINITIONS_H_
+#define _IOH_COMMON_DEFINITIONS_H_
+
+//
+// PCI CONFIGURATION MAP REGISTER OFFSETS
+//
+#ifndef PCI_VID
+#define PCI_VID             0x0000        // Vendor ID Register
+#define PCI_DID             0x0002        // Device ID Register
+#define PCI_CMD             0x0004        // PCI Command Register
+#define PCI_STS             0x0006        // PCI Status Register
+#define PCI_RID             0x0008        // Revision ID Register
+#define PCI_IFT             0x0009        // Interface Type
+#define PCI_SCC             0x000A        // Sub Class Code Register
+#define PCI_BCC             0x000B        // Base Class Code Register
+#define PCI_CLS             0x000C        // Cache Line Size
+#define PCI_PMLT            0x000D        // Primary Master Latency Timer
+#define PCI_HDR             0x000E        // Header Type Register
+#define PCI_BIST            0x000F        // Built in Self Test Register
+#define PCI_BAR0            0x0010        // Base Address Register 0
+#define PCI_BAR1            0x0014        // Base Address Register 1
+#define PCI_BAR2            0x0018        // Base Address Register 2
+#define PCI_PBUS            0x0018        // Primary Bus Number Register
+#define PCI_SBUS            0x0019        // Secondary Bus Number Register
+#define PCI_SUBUS           0x001A        // Subordinate Bus Number Register
+#define PCI_SMLT            0x001B        // Secondary Master Latency Timer
+#define PCI_BAR3            0x001C        // Base Address Register 3
+#define PCI_IOBASE          0x001C        // I/O base Register
+#define PCI_IOLIMIT         0x001D        // I/O Limit Register
+#define PCI_SECSTATUS       0x001E        // Secondary Status Register
+#define PCI_BAR4            0x0020        // Base Address Register 4
+#define PCI_MEMBASE         0x0020        // Memory Base Register
+#define PCI_MEMLIMIT        0x0022        // Memory Limit Register
+#define PCI_BAR5            0x0024        // Base Address Register 5
+#define PCI_PRE_MEMBASE     0x0024        // Prefetchable memory Base register
+#define PCI_PRE_MEMLIMIT    0x0026        // Prefetchable memory Limit register
+#define PCI_PRE_MEMBASE_U   0x0028        // Prefetchable memory base upper 32 bits
+#define PCI_PRE_MEMLIMIT_U  0x002C        // Prefetchable memory limit upper 32 bits
+#define PCI_SVID            0x002C        // Subsystem Vendor ID
+#define PCI_SID             0x002E        // Subsystem ID
+#define PCI_IOBASE_U        0x0030        // I/O base Upper Register
+#define PCI_IOLIMIT_U       0x0032        // I/O Limit Upper Register
+#define PCI_CAPP            0x0034        // Capabilities Pointer
+#define PCI_EROM            0x0038        // Expansion ROM Base Address
+#define PCI_INTLINE         0x003C        // Interrupt Line Register
+#define PCI_INTPIN          0x003D        // Interrupt Pin Register
+#define PCI_MAXGNT          0x003E        // Max Grant Register
+#define PCI_BRIDGE_CNTL     0x003E        // Bridge Control Register
+#define PCI_MAXLAT          0x003F        // Max Latency Register
+#endif
+//
+// Bit Difinitions
+//
+#ifndef BIT0
+#define BIT0                     0x0001
+#define BIT1                     0x0002
+#define BIT2                     0x0004
+#define BIT3                     0x0008
+#define BIT4                     0x0010
+#define BIT5                     0x0020
+#define BIT6                     0x0040
+#define BIT7                     0x0080
+#define BIT8                     0x0100
+#define BIT9                     0x0200
+#define BIT10                    0x0400
+#define BIT11                    0x0800
+#define BIT12                    0x1000
+#define BIT13                    0x2000
+#define BIT14                    0x4000
+#define BIT15                    0x8000
+#define BIT16                0x00010000
+#define BIT17                0x00020000
+#define BIT18                0x00040000
+#define BIT19                0x00080000
+#define BIT20                0x00100000
+#define BIT21                0x00200000
+#define BIT22                0x00400000
+#define BIT23                0x00800000
+#define BIT24                0x01000000
+#define BIT25                0x02000000
+#define BIT26                0x04000000
+#define BIT27                0x08000000
+#define BIT28                0x10000000
+#define BIT29                0x20000000
+#define BIT30                0x40000000
+#define BIT31                0x80000000
+#endif
+
+
+//
+//  Common Memory mapped Io access macros ------------------------------------------
+//
+#define IohMmioAddress( BaseAddr, Register ) \
+    ( (UINTN)BaseAddr + \
+      (UINTN)(Register) \
+    )
+
+//
+// UINT64
+//
+#define IohMmio64Ptr( BaseAddr, Register ) \
+    ( (volatile UINT64 *)IohMmioAddress( BaseAddr, Register ) )
+
+#define IohMmio64( BaseAddr, Register ) \
+    *IohMmio64Ptr( BaseAddr, Register )
+
+#define IohMmio64Or( BaseAddr, Register, OrData ) \
+    IohMmio64( BaseAddr, Register ) = \
+      (UINT64) ( \
+        IohMmio64( BaseAddr, Register ) | \
+        (UINT64)(OrData) \
+      )
+
+#define IohMmio64And( BaseAddr, Register, AndData ) \
+    IohMmio64( BaseAddr, Register ) = \
+      (UINT64) ( \
+        IohMmio64( BaseAddr, Register ) & \
+        (UINT64)(AndData) \
+      )
+
+#define IohMmio64AndThenOr( BaseAddr, Register, AndData, OrData ) \
+    IohMmio64( BaseAddr, Register ) = \
+      (UINT64) ( \
+        ( IohMmio64( BaseAddr, Register ) & \
+            (UINT64)(AndData) \
+        ) | \
+        (UINT64)(OrData) \
+      )
+
+//
+// UINT32
+//
+#define IohMmio32Ptr( BaseAddr, Register ) \
+    ( (volatile UINT32 *)IohMmioAddress( BaseAddr, Register ) )
+
+#define IohMmio32( BaseAddr, Register ) \
+    *IohMmio32Ptr( BaseAddr, Register )
+
+#define IohMmio32Or( BaseAddr, Register, OrData ) \
+    IohMmio32( BaseAddr, Register ) = \
+      (UINT32) ( \
+        IohMmio32( BaseAddr, Register ) | \
+        (UINT32)(OrData) \
+      )
+
+#define IohMmio32And( BaseAddr, Register, AndData ) \
+    IohMmio32( BaseAddr, Register ) = \
+      (UINT32) ( \
+        IohMmio32( BaseAddr, Register ) & \
+        (UINT32)(AndData) \
+      )
+
+#define IohMmio32AndThenOr( BaseAddr, Register, AndData, OrData ) \
+    IohMmio32( BaseAddr, Register ) = \
+      (UINT32) ( \
+        ( IohMmio32( BaseAddr, Register ) & \
+            (UINT32)(AndData) \
+        ) | \
+        (UINT32)(OrData) \
+      )
+//
+// UINT16
+//
+
+#define IohMmio16Ptr( BaseAddr, Register ) \
+    ( (volatile UINT16 *)IohMmioAddress( BaseAddr, Register ) )
+
+#define IohMmio16( BaseAddr, Register ) \
+    *IohMmio16Ptr( BaseAddr, Register )
+
+#define IohMmio16Or( BaseAddr, Register, OrData ) \
+    IohMmio16( BaseAddr, Register ) = \
+      (UINT16) ( \
+        IohMmio16( BaseAddr, Register ) | \
+        (UINT16)(OrData) \
+      )
+
+#define IohMmio16And( BaseAddr, Register, AndData ) \
+    IohMmio16( BaseAddr, Register ) = \
+      (UINT16) ( \
+        IohMmio16( BaseAddr, Register ) & \
+        (UINT16)(AndData) \
+      )
+
+#define IohMmio16AndThenOr( BaseAddr, Register, AndData, OrData ) \
+    IohMmio16( BaseAddr, Register ) = \
+      (UINT16) ( \
+        ( IohMmio16( BaseAddr, Register ) & \
+            (UINT16)(AndData) \
+        ) | \
+        (UINT16)(OrData) \
+      )
+//
+// UINT8
+//
+#define IohMmio8Ptr( BaseAddr, Register ) \
+    ( (volatile UINT8 *)IohMmioAddress( BaseAddr, Register ) )
+
+#define IohMmio8( BaseAddr, Register ) \
+    *IohMmio8Ptr( BaseAddr, Register )
+
+#define IohMmio8Or( BaseAddr, Register, OrData ) \
+    IohMmio8( BaseAddr, Register ) = \
+      (UINT8) ( \
+        IohMmio8( BaseAddr, Register ) | \
+        (UINT8)(OrData) \
+      )
+
+#define IohMmio8And( BaseAddr, Register, AndData ) \
+    IohMmio8( BaseAddr, Register ) = \
+      (UINT8) ( \
+        IohMmio8( BaseAddr, Register ) & \
+        (UINT8)(AndData) \
+      )
+
+#define IohMmio8AndThenOr( BaseAddr, Register, AndData, OrData ) \
+    IohMmio8( BaseAddr, Register ) = \
+      (UINT8) ( \
+        ( IohMmio8( BaseAddr, Register ) & \
+            (UINT8)(AndData) \
+          ) | \
+        (UINT8)(OrData) \
+      )
+
+//
+//  Common Memory mapped Pci access macros ------------------------------------------
+//
+#define Ioh_PCI_EXPRESS_BASE_ADDRESS  0xE0000000
+
+
+#define IohMmPciAddress( Segment, Bus, Device, Function, Register ) \
+  ( (UINTN)Ioh_PCI_EXPRESS_BASE_ADDRESS + \
+    (UINTN)(Bus << 20) + \
+    (UINTN)(Device << 15) + \
+    (UINTN)(Function << 12) + \
+    (UINTN)(Register) \
+  )
+
+//
+// UINT32
+//
+#define IohMmPci32Ptr( Segment, Bus, Device, Function, Register ) \
+  ( (volatile UINT32 *)IohMmPciAddress( Segment, Bus, Device, Function, Register ) )
+
+#define IohMmPci32( Segment, Bus, Device, Function, Register ) \
+  *IohMmPci32Ptr( Segment, Bus, Device, Function, Register )
+
+#define IohMmPci32Or( Segment, Bus, Device, Function, Register, OrData ) \
+  IohMmPci32( Segment, Bus, Device, Function, Register ) = \
+    (UINT32) ( \
+      IohMmPci32( Segment, Bus, Device, Function, Register ) | \
+      (UINT32)(OrData) \
+    )
+
+#define IohMmPci32And( Segment, Bus, Device, Function, Register, AndData ) \
+  IohMmPci32( Segment, Bus, Device, Function, Register ) = \
+    (UINT32) ( \
+      IohMmPci32( Segment, Bus, Device, Function, Register ) & \
+      (UINT32)(AndData) \
+    )
+
+#define IohMmPci32AndThenOr( Segment, Bus, Device, Function, Register, AndData, OrData ) \
+  IohMmPci32( Segment, Bus, Device, Function, Register ) = \
+    (UINT32) ( \
+      ( IohMmPci32( Segment, Bus, Device, Function, Register ) & \
+          (UINT32)(AndData) \
+      ) | \
+      (UINT32)(OrData) \
+    )
+//
+// UINT16
+//
+#define IohMmPci16Ptr( Segment, Bus, Device, Function, Register ) \
+  ( (volatile UINT16 *)IohMmPciAddress( Segment, Bus, Device, Function, Register ) )
+
+#define IohMmPci16( Segment, Bus, Device, Function, Register ) \
+  *IohMmPci16Ptr( Segment, Bus, Device, Function, Register )
+
+#define IohMmPci16Or( Segment, Bus, Device, Function, Register, OrData ) \
+  IohMmPci16( Segment, Bus, Device, Function, Register ) = \
+    (UINT16) ( \
+      IohMmPci16( Segment, Bus, Device, Function, Register ) | \
+      (UINT16)(OrData) \
+    )
+
+#define IohMmPci16And( Segment, Bus, Device, Function, Register, AndData ) \
+  IohMmPci16( Segment, Bus, Device, Function, Register ) = \
+    (UINT16) ( \
+      IohMmPci16( Segment, Bus, Device, Function, Register ) & \
+      (UINT16)(AndData) \
+    )
+
+#define IohMmPci16AndThenOr( Segment, Bus, Device, Function, Register, AndData, OrData ) \
+  IohMmPci16( Segment, Bus, Device, Function, Register ) = \
+    (UINT16) ( \
+      ( IohMmPci16( Segment, Bus, Device, Function, Register ) & \
+          (UINT16)(AndData) \
+      ) | \
+      (UINT16)(OrData) \
+    )
+//
+// UINT8
+//
+#define IohMmPci8Ptr( Segment, Bus, Device, Function, Register ) \
+  ( (volatile UINT8 *)IohMmPciAddress( Segment, Bus, Device, Function, Register ) )
+
+#define IohMmPci8( Segment, Bus, Device, Function, Register ) \
+  *IohMmPci8Ptr( Segment, Bus, Device, Function, Register )
+
+#define IohMmPci8Or( Segment, Bus, Device, Function, Register, OrData ) \
+  IohMmPci8( Segment, Bus, Device, Function, Register ) = \
+    (UINT8) ( \
+      IohMmPci8( Segment, Bus, Device, Function, Register ) | \
+      (UINT8)(OrData) \
+    )
+
+#define IohMmPci8And( Segment, Bus, Device, Function, Register, AndData ) \
+  IohMmPci8( Segment, Bus, Device, Function, Register ) = \
+    (UINT8) ( \
+      IohMmPci8( Segment, Bus, Device, Function, Register ) & \
+      (UINT8)(AndData) \
+    )
+
+#define IohMmPci8AndThenOr( Segment, Bus, Device, Function, Register, AndData, OrData ) \
+  IohMmPci8( Segment, Bus, Device, Function, Register ) = \
+    (UINT8) ( \
+      ( IohMmPci8( Segment, Bus, Device, Function, Register ) & \
+          (UINT8)(AndData) \
+        ) | \
+      (UINT8)(OrData) \
+    )
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Library/I2cLib.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Library/I2cLib.h
new file mode 100644
index 0000000000..d401c6b43e
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Library/I2cLib.h
@@ -0,0 +1,152 @@
+/** @file
+
+Intel I2C library implementation built upon I/O library
+
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _I2C_LIB_H_
+#define _I2C_LIB_H_
+
+#include "I2cRegs.h"
+
+/**
+
+  The I2cWriteByte() function is a wrapper function for the WriteByte() function.
+  Provides a standard way to execute a standard single byte write to an IC2 device
+  (without accessing sub-addresses), as defined in the I2C Specification.
+
+  @param SlaveAddress The I2C slave address of the device
+                      with which to communicate.
+
+  @param AddrMode     I2C Addressing Mode: 7-bit or 10-bit address.
+
+  @param Buffer       Contains the value of byte data to execute to the
+                      I2C slave device.
+
+
+  @retval EFI_SUCCESS           Transfer success.
+  @retval EFI_INVALID_PARAMETER  This or Buffer pointers are invalid.
+  @retval EFI_TIMEOUT           Timeout while waiting xfer.
+  @retval EFI_ABORTED           Controller aborted xfer.
+  @retval EFI_DEVICE_ERROR      Device error detected by controller.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cWriteByte (
+  IN        EFI_I2C_DEVICE_ADDRESS  SlaveAddress,
+  IN        EFI_I2C_ADDR_MODE       AddrMode,
+  IN OUT VOID                       *Buffer
+  );
+
+/**
+
+  The I2cReadByte() function is a wrapper function for the ReadByte() function.
+  Provides a standard way to execute a standard single byte read to an I2C device
+  (without accessing sub-addresses), as defined in the I2C Specification.
+
+  @param SlaveAddress The I2C slave address of the device
+                      with which to communicate.
+
+  @param AddrMode     I2C Addressing Mode: 7-bit or 10-bit address.
+
+  @param Buffer       Contains the value of byte data read from the
+                      I2C slave device.
+
+
+  @retval EFI_SUCCESS           Transfer success.
+  @retval EFI_INVALID_PARAMETER This or Buffer pointers are invalid.
+  @retval EFI_TIMEOUT           Timeout while waiting xfer.
+  @retval EFI_ABORTED           Controller aborted xfer.
+  @retval EFI_DEVICE_ERROR      Device error detected by controller.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cReadByte (
+  IN        EFI_I2C_DEVICE_ADDRESS  SlaveAddress,
+  IN        EFI_I2C_ADDR_MODE       AddrMode,
+  IN OUT VOID                       *Buffer
+  );
+
+/**
+
+  The I2cWriteMultipleByte() function is a wrapper function for the WriteMultipleByte()
+  function. Provides a standard way to execute multiple byte writes to an I2C device (e.g. when
+  accessing sub-addresses or writing block of data), as defined in the I2C Specification.
+
+  @param SlaveAddress The I2C slave address of the device
+                      with which to communicate.
+
+  @param AddrMode     I2C Addressing Mode: 7-bit or 10-bit address.
+
+  @param Length       No. of bytes to be written.
+
+  @param Buffer       Contains the value of byte to be written to the
+                      I2C slave device.
+
+  @retval EFI_SUCCESS            Transfer success.
+  @retval EFI_INVALID_PARAMETER  This, Length or Buffer pointers are invalid.
+  @retval EFI_UNSUPPORTED        Unsupported input param.
+  @retval EFI_TIMEOUT            Timeout while waiting xfer.
+  @retval EFI_ABORTED            Controller aborted xfer.
+  @retval EFI_DEVICE_ERROR       Device error detected by controller.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cWriteMultipleByte (
+  IN        EFI_I2C_DEVICE_ADDRESS  SlaveAddress,
+  IN        EFI_I2C_ADDR_MODE       AddrMode,
+  IN UINTN                          *Length,
+  IN OUT VOID                       *Buffer
+  );
+
+/**
+
+  The I2cReadMultipleByte() function is a wrapper function for the ReadMultipleByte
+  function. Provides a standard way to execute multiple byte writes to an IC2 device
+  (e.g. when accessing sub-addresses or when reading block of data), as defined
+  in the I2C Specification (I2C combined write/read protocol).
+
+  @param SlaveAddress The I2C slave address of the device
+                      with which to communicate.
+
+  @param AddrMode     I2C Addressing Mode: 7-bit or 10-bit address.
+
+  @param WriteLength  No. of bytes to be written. In this case data
+                      written typically contains sub-address or sub-addresses
+                      in Hi-Lo format, that need to be read (I2C combined
+                      write/read protocol).
+
+  @param ReadLength   No. of bytes to be read from I2C slave device.
+                      need to be read.
+
+  @param Buffer       Contains the value of byte data read from the
+                      I2C slave device.
+
+  @retval EFI_SUCCESS            Transfer success.
+  @retval EFI_INVALID_PARAMETER  This, WriteLength, ReadLength or Buffer
+                                 pointers are invalid.
+  @retval EFI_UNSUPPORTED        Unsupported input param.
+  @retval EFI_TIMEOUT            Timeout while waiting xfer.
+  @retval EFI_ABORTED            Controller aborted xfer.
+  @retval EFI_DEVICE_ERROR       Device error detected by controller.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cReadMultipleByte (
+  IN        EFI_I2C_DEVICE_ADDRESS  SlaveAddress,
+  IN        EFI_I2C_ADDR_MODE       AddrMode,
+  IN UINTN                          *WriteLength,
+  IN UINTN                          *ReadLength,
+  IN OUT VOID                       *Buffer
+  );
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Library/IohLib.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Library/IohLib.h
new file mode 100644
index 0000000000..a3aa071ef5
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Library/IohLib.h
@@ -0,0 +1,36 @@
+/** @file
+Library that provides Soc specific library services for SouthCluster devices.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __IOH_LIB_H__
+#define __IOH_LIB_H__
+
+#include "Ioh.h"
+
+EFI_STATUS
+EFIAPI
+InitializeIohSsvidSsid (
+   IN UINT8   Bus,
+   IN UINT8   Device,
+   IN UINT8   Func
+   );
+
+VOID
+EFIAPI
+EnableUsbMemIoBusMaster (
+   IN UINT8   UsbBusNumber
+  );
+
+UINT32
+EFIAPI
+ReadIohGpioValues (
+  VOID
+  );
+
+#endif
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/MMC.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/MMC.h
new file mode 100644
index 0000000000..549171e53e
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/MMC.h
@@ -0,0 +1,274 @@
+/** @file
+
+Header file for Industry MMC 4.2 spec.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _MMC_H
+#define _MMC_H
+
+#pragma pack(1)
+//
+//Command definition
+//
+
+#define  CMD0              0
+#define  CMD1              1
+#define  CMD2              2
+#define  CMD3              3
+#define  CMD4              4
+#define  CMD6              6
+#define  CMD7              7
+#define  CMD8              8
+#define  CMD9              9
+#define  CMD10             10
+#define  CMD11             11
+#define  CMD12             12
+#define  CMD13             13
+#define  CMD14             14
+#define  CMD15             15
+#define  CMD16             16
+#define  CMD17             17
+#define  CMD18             18
+#define  CMD19             19
+#define  CMD20             20
+#define  CMD23             23
+#define  CMD24             24
+#define  CMD25             25
+#define  CMD26             26
+#define  CMD27             27
+#define  CMD28             28
+#define  CMD29             29
+#define  CMD30             30
+#define  CMD35             35
+#define  CMD36             36
+#define  CMD38             38
+#define  CMD39             39
+#define  CMD40             40
+#define  CMD42             42
+#define  CMD55             55
+#define  CMD56             56
+
+
+
+#define  GO_IDLE_STATE           CMD0
+#define  SEND_OP_COND            CMD1
+#define  ALL_SEND_CID            CMD2
+#define  SET_RELATIVE_ADDR       CMD3
+#define  SET_DSR                 CMD4
+#define  SWITCH                  CMD6
+#define  SELECT_DESELECT_CARD    CMD7
+#define  SEND_EXT_CSD            CMD8
+#define  SEND_CSD                CMD9
+#define  SEND_CID                CMD10
+#define  READ_DAT_UNTIL_STOP     CMD11
+#define  STOP_TRANSMISSION       CMD12
+#define  SEND_STATUS             CMD13
+#define  BUSTEST_R               CMD14
+#define  GO_INACTIVE_STATE       CMD15
+#define  SET_BLOCKLEN            CMD16
+#define  READ_SINGLE_BLOCK       CMD17
+#define  READ_MULTIPLE_BLOCK     CMD18
+#define  BUSTEST_W               CMD19
+#define  WRITE_DAT_UNTIL_STOP    CMD20
+#define  SET_BLOCK_COUNT         CMD23
+#define  WRITE_BLOCK             CMD24
+#define  WRITE_MULTIPLE_BLOCK    CMD25
+#define  PROGRAM_CID             CMD26
+#define  PROGRAM_CSD             CMD27
+#define  SET_WRITE_PROT          CMD28
+#define  CLR_WRITE_PROT          CMD29
+#define  SEND_WRITE_PROT         CMD30
+#define  ERASE_GROUP_START       CMD35
+#define  ERASE_GROUP_END         CMD36
+#define  ERASE                   CMD38
+#define  FAST_IO                 CMD39
+#define  GO_IRQ_STATE            CMD40
+#define  LOCK_UNLOCK             CMD42
+#define  APP_CMD                 CMD55
+#define  GEN_CMD                 CMD56
+
+
+#define CMD_INDEX_MASK           0x3F
+#define AUTO_CMD12_ENABLE        BIT6
+#define AUTO_CMD23_ENABLE        BIT7
+
+#define FREQUENCY_OD            (400 * 1000)
+#define FREQUENCY_MMC_PP        (26 * 1000 * 1000)
+#define FREQUENCY_MMC_PP_HIGH   (52 * 1000 * 1000)
+
+#define DEFAULT_DSR_VALUE        0x404
+
+//
+//Registers definition
+//
+
+typedef struct {
+  UINT32  Reserved0:   7;  // 0
+  UINT32  V170_V195:   1;  // 1.70V - 1.95V
+  UINT32  V200_V260:   7;  // 2.00V - 2.60V
+  UINT32  V270_V360:   9;  // 2.70V - 3.60V
+  UINT32  Reserved1:   5;  // 0
+  UINT32  AccessMode:  2;  // 00b (byte mode), 10b (sector mode)
+  UINT32  Busy:        1;  // This bit is set to LOW if the card has not finished the power up routine
+}OCR;
+
+
+typedef struct {
+  UINT8   NotUsed:     1; //  1
+  UINT8   CRC:         7; //  CRC7 checksum
+  UINT8   MDT;            //  Manufacturing date
+  UINT32  PSN;            //  Product serial number
+  UINT8   PRV;            //  Product revision
+  UINT8   PNM[6];         //  Product name
+  UINT16  OID;            //  OEM/Application ID
+  UINT8   MID;            //  Manufacturer ID
+}CID;
+
+
+typedef struct {
+  UINT8   NotUsed:            1; //  1 [0:0]
+  UINT8   CRC:                7; //  CRC [7:1]
+  UINT8   ECC:                2; //  ECC code [9:8]
+  UINT8   FILE_FORMAT:        2; //  File format [11:10]
+  UINT8   TMP_WRITE_PROTECT:  1; //  Temporary write protection [12:12]
+  UINT8   PERM_WRITE_PROTECT: 1; //  Permanent write protection [13:13]
+  UINT8   COPY:               1; //  Copy flag (OTP) [14:14]
+  UINT8   FILE_FORMAT_GRP:    1; //  File format group [15:15]
+  UINT16  CONTENT_PROT_APP:   1; //  Content protection application [16:16]
+  UINT16  Reserved0:          4; //  0 [20:17]
+  UINT16  WRITE_BL_PARTIAL:   1; //  Partial blocks for write allowed [21:21]
+  UINT16  WRITE_BL_LEN:       4; //  Max. write data block length [25:22]
+  UINT16  R2W_FACTOR:         3; //  Write speed factor [28:26]
+  UINT16  DEFAULT_ECC:        2; //  Manufacturer default ECC [30:29]
+  UINT16  WP_GRP_ENABLE:      1; //  Write protect group enable [31:31]
+  UINT32  WP_GRP_SIZE:        5; //  Write protect group size [36:32]
+  UINT32  ERASE_GRP_MULT:     5; //  Erase group size multiplier [41:37]
+  UINT32  ERASE_GRP_SIZE:     5; //  Erase group size [46:42]
+  UINT32  C_SIZE_MULT:        3; //  Device size multiplier [49:47]
+  UINT32  VDD_W_CURR_MAX:     3; //  Max. write current @ VDD max [52:50]
+  UINT32  VDD_W_CURR_MIN:     3; //  Max. write current @ VDD min [55:53]
+  UINT32  VDD_R_CURR_MAX:     3; //  Max. read current @ VDD max [58:56]
+  UINT32  VDD_R_CURR_MIN:     3; //  Max. read current @ VDD min [61:59]
+  UINT32  C_SIZELow2:         2;//  Device size [73:62]
+  UINT32  C_SIZEHigh10:       10;//  Device size [73:62]
+  UINT32  Reserved1:          2; //  0 [75:74]
+  UINT32  DSR_IMP:            1; //  DSR implemented [76:76]
+  UINT32  READ_BLK_MISALIGN:  1; //  Read block misalignment [77:77]
+  UINT32  WRITE_BLK_MISALIGN: 1; //  Write block misalignment [78:78]
+  UINT32  READ_BL_PARTIAL:    1; //  Partial blocks for read allowed [79:79]
+  UINT32  READ_BL_LEN:        4; //  Max. read data block length [83:80]
+  UINT32  CCC:                12;//  Card command classes [95:84]
+  UINT8   TRAN_SPEED          ; //  Max. bus clock frequency [103:96]
+  UINT8   NSAC                ; //  Data read access-time 2 in CLK cycles (NSAC*100) [111:104]
+  UINT8   TAAC                ; //  Data read access-time 1 [119:112]
+  UINT8   Reserved2:          2; //  0 [121:120]
+  UINT8   SPEC_VERS:          4; //  System specification version [125:122]
+  UINT8   CSD_STRUCTURE:      2; //  CSD structure [127:126]
+}CSD;
+
+typedef struct {
+  UINT8  Reserved0[181];         //  0 [0:180]
+  UINT8  ERASED_MEM_CONT;        //  Erased Memory Content [181]
+  UINT8  Reserved2;              //  Erased Memory Content [182]
+  UINT8  BUS_WIDTH;              //  Bus Width Mode [183]
+  UINT8  Reserved3;              //  0 [184]
+  UINT8  HS_TIMING;              //  High Speed Interface Timing [185]
+  UINT8  Reserved4;              //  0 [186]
+  UINT8  POWER_CLASS;            //  Power Class [187]
+  UINT8  Reserved5;              //  0 [188]
+  UINT8  CMD_SET_REV;            //  Command Set Revision [189]
+  UINT8  Reserved6;              //  0 [190]
+  UINT8  CMD_SET;                //  Command Set [191]
+  UINT8  EXT_CSD_REV;            //  Extended CSD Revision [192]
+  UINT8  Reserved7;              //  0 [193]
+  UINT8  CSD_STRUCTURE;          //  CSD Structure Version [194]
+  UINT8  Reserved8;              //  0 [195]
+  UINT8  CARD_TYPE;              //  Card Type [196]
+  UINT8  Reserved9[3];           //  0 [199:197]
+  UINT8  PWR_CL_52_195;          //  Power Class for 52MHz @ 1.95V [200]
+  UINT8  PWR_CL_26_195;          //  Power Class for 26MHz @ 1.95V [201]
+  UINT8  PWR_CL_52_360;          //  Power Class for 52MHz @ 3.6V [202]
+  UINT8  PWR_CL_26_360;          //  Power Class for 26MHz @ 3.6V [203]
+  UINT8  Reserved10;             //  0 [204]
+  UINT8  MIN_PERF_R_4_26;        //  Minimum Read Performance for 4bit @26MHz [205]
+  UINT8  MIN_PERF_W_4_26;        //  Minimum Write Performance for 4bit @26MHz [206]
+  UINT8  MIN_PERF_R_8_26_4_52;   //  Minimum Read Performance for 8bit @26MHz/4bit @52MHz [207]
+  UINT8  MIN_PERF_W_8_26_4_52;   //  Minimum Write Performance for 8bit @26MHz/4bit @52MHz [208]
+  UINT8  MIN_PERF_R_8_52;        //  Minimum Read Performance for 8bit @52MHz [209]
+  UINT8  MIN_PERF_W_8_52;        //  Minimum Write Performance for 8bit @52MHz [210]
+  UINT8  Reserved11;             //  0 [211]
+  UINT8  SEC_COUNT[4];           //  Sector Count [215:212]
+  UINT8  Reserved12[288];        //  0 [503:216]
+  UINT8  S_CMD_SET;              //  Sector Count [504]
+  UINT8  Reserved13[7];          //  Sector Count [511:505]
+}EXT_CSD;
+
+
+//
+//Card Status definition
+//
+typedef struct {
+  UINT32  Reserved0:           2; //Reserved for Manufacturer Test Mode
+  UINT32  Reserved1:           2; //Reserved for Application Specific commands
+  UINT32  Reserved2:           1; //
+  UINT32  SAPP_CMD:            1; //
+  UINT32  Reserved3:           1; //Reserved
+  UINT32  SWITCH_ERROR:        1; //
+  UINT32  READY_FOR_DATA:      1; //
+  UINT32  CURRENT_STATE:       4; //
+  UINT32  ERASE_RESET:         1; //
+  UINT32  Reserved4:           1; //Reserved
+  UINT32  WP_ERASE_SKIP:       1; //
+  UINT32  CID_CSD_OVERWRITE:   1; //
+  UINT32  OVERRUN:             1; //
+  UINT32  UNDERRUN:            1; //
+  UINT32  ERROR:               1; //
+  UINT32  CC_ERROR:            1; //
+  UINT32  CARD_ECC_FAILED:     1; //
+  UINT32  ILLEGAL_COMMAND:     1; //
+  UINT32  COM_CRC_ERROR:       1; //
+  UINT32  LOCK_UNLOCK_FAILED:  1; //
+  UINT32  CARD_IS_LOCKED:      1; //
+  UINT32  WP_VIOLATION:        1; //
+  UINT32  ERASE_PARAM:         1; //
+  UINT32  ERASE_SEQ_ERROR:     1; //
+  UINT32  BLOCK_LEN_ERROR:     1; //
+  UINT32  ADDRESS_MISALIGN:    1; //
+  UINT32  ADDRESS_OUT_OF_RANGE:1; //
+}CARD_STATUS;
+
+typedef struct {
+  UINT32  CmdSet:              3;
+  UINT32  Reserved0:           5;
+  UINT32  Value:               8;
+  UINT32  Index:               8;
+  UINT32  Access:              2;
+  UINT32  Reserved1:           6;
+}SWITCH_ARGUMENT;
+
+#define CommandSet_Mode          0
+#define SetBits_Mode             1
+#define ClearBits_Mode           2
+#define WriteByte_Mode           3
+
+
+#define  Idle_STATE              0
+#define  Ready_STATE             1
+#define  Ident_STATE             2
+#define  Stby_STATE              3
+#define  Tran_STATE              4
+#define  Data_STATE              5
+#define  Rcv_STATE               6
+#define  Prg_STATE               7
+#define  Dis_STATE               8
+#define  Btst_STATE              9
+
+
+
+#pragma pack()
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/SDCard.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/SDCard.h
new file mode 100644
index 0000000000..93db8d248a
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/SDCard.h
@@ -0,0 +1,146 @@
+/** @file
+
+Header file for Industry SD Card 2.0 spec.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _SD_CARD_H
+#define _SD_CARD_H
+
+#include "MMC.h"
+
+#pragma pack(1)
+
+#define CHECK_PATTERN     0xAA  ///< Physical Layer Simplified Specification Version 3.01 recommended 0xAA
+
+#define ACMD6             6
+#define ACMD13            13
+#define ACMD23            23
+#define ACMD41            41
+#define ACMD42            42
+#define ACMD51            51
+
+
+#define SWITCH_FUNC              CMD6
+#define SEND_IF_COND             CMD8
+
+
+#define SET_BUS_WIDTH            ACMD6
+#define SD_STATUS                ACMD13
+#define SET_WR_BLK_ERASE_COUNT   ACMD23
+#define SD_SEND_OP_COND          ACMD41
+#define SET_CLR_CARD_DETECT      ACMD42
+#define SEND_SCR                 ACMD51
+
+
+
+#define SD_BUS_WIDTH_1              0
+#define SD_BUS_WIDTH_4              2
+
+
+
+#define FREQUENCY_SD_PP        (25 * 1000 * 1000)
+#define FREQUENCY_SD_PP_HIGH   (50 * 1000 * 1000)
+
+
+#define SD_SPEC_10                  0
+#define SD_SPEC_11                  1
+#define SD_SPEC_20                  2
+
+
+#define VOLTAGE_27_36               0x1
+
+typedef struct {
+  UINT8   NotUsed:            1; //  1 [0:0]
+  UINT8   CRC:                7; //  CRC [7:1]
+  UINT8   ECC:                2; //  ECC code [9:8]
+  UINT8   FILE_FORMAT:        2; //  File format [11:10]
+  UINT8   TMP_WRITE_PROTECT:  1; //  Temporary write protection [12:12]
+  UINT8   PERM_WRITE_PROTECT: 1; //  Permanent write protection [13:13]
+  UINT8   COPY:               1; //  Copy flag (OTP) [14:14]
+  UINT8   FILE_FORMAT_GRP:    1; //  File format group [15:15]
+  UINT16  Reserved0:          5; //  0 [20:16]
+  UINT16  WRITE_BL_PARTIAL:   1; //  Partial blocks for write allowed [21:21]
+  UINT16  WRITE_BL_LEN:       4; //  Max. write data block length [25:22]
+  UINT16  R2W_FACTOR:         3; //  Write speed factor [28:26]
+  UINT16  DEFAULT_ECC:        2; //  Manufacturer default ECC [30:29]
+  UINT16  WP_GRP_ENABLE:      1; //  Write protect group enable [31:31]
+  UINT16  WP_GRP_SIZE:        7; //  Write protect group size [38:32]
+  UINT16  SECTOR_SIZE:        7; //  Erase sector size [45:39]
+  UINT16  ERASE_BLK_EN:       1; //  Erase single block enable [46:46]
+  UINT16  Reserved1:          1; //  0 [47:47]
+
+  UINT32  C_SIZE:             22; //  Device size [69:48]
+  UINT32  Reserved2:          6;  //  0 [75:70]
+  UINT32  DSR_IMP:            1;  //  DSR implemented [76:76]
+  UINT32  READ_BLK_MISALIGN:  1;  //  Read block misalignment [77:77]
+  UINT32  WRITE_BLK_MISALIGN: 1;  //  Write block misalignment [78:78]
+  UINT32  READ_BL_PARTIAL:    1;  //  Partial blocks for read allowed [79:79]
+
+  UINT16  READ_BL_LEN:        4;  //  Max. read data block length [83:80]
+  UINT16  CCC:                12; //  Card command classes [95:84]
+  UINT8   TRAN_SPEED          ;   //  Max. bus clock frequency [103:96]
+  UINT8   NSAC                ;   //  Data read access-time 2 in CLK cycles (NSAC*100) [111:104]
+  UINT8   TAAC                ;   //  Data read access-time 1 [119:112]
+  UINT8   Reserved3:          6;  //  0 [125:120]
+  UINT8   CSD_STRUCTURE:      2;  //  CSD structure [127:126]
+}CSD_SDV2;
+
+typedef struct {
+  UINT32  Reserved0;
+  UINT32  Reserved1:               16;
+  UINT32  SD_BUS_WIDTH:            4;
+  UINT32  SD_SECURITY:             3;
+  UINT32  DATA_STAT_AFTER_ERASE:   1;
+  UINT32  SD_SPEC:                 4;
+  UINT32  SCR_STRUCT:              4;
+}SCR;
+
+
+typedef struct {
+  UINT8   Reserved0[50];
+  UINT8   ERASE_OFFSET:               2;
+  UINT8   ERASE_TIMEOUT:              6;
+  UINT16  ERASE_SIZE;
+  UINT8   Reserved1:                  4;
+  UINT8   AU_SIZE:                    4;
+  UINT8   PERFORMANCE_MOVE;
+  UINT8   SPEED_CLASS;
+  UINT32  SIZE_OF_PROTECTED_AREA;
+  UINT32  SD_CARD_TYPE:              16;
+  UINT32  Reserved2:                 13;
+  UINT32  SECURED_MODE:               1;
+  UINT32  DAT_BUS_WIDTH:              2;
+}SD_STATUS_REG;
+
+
+
+typedef struct {
+  UINT8   Reserved0[34];
+  UINT16  Group1BusyStatus;
+  UINT16  Group2BusyStatus;
+  UINT16  Group3BusyStatus;
+  UINT16  Group4BusyStatus;
+  UINT16  Group5BusyStatus;
+  UINT16  Group6BusyStatus;
+  UINT8   DataStructureVersion;
+  UINT8   Group21Status;
+  UINT8   Group43Status;
+  UINT8   Group65Status;
+  UINT16  Group1Function;
+  UINT16  Group2Function;
+  UINT16  Group3Function;
+  UINT16  Group4Function;
+  UINT16  Group5Function;
+  UINT16  Group6Function;
+  UINT16  MaxCurrent;
+}SWITCH_STATUS;
+
+
+#pragma pack()
+#endif
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/SDHostIo.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/SDHostIo.h
new file mode 100644
index 0000000000..7ce0793390
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/SDHostIo.h
@@ -0,0 +1,333 @@
+/** @file
+
+Interface definition for EFI_SD_HOST_IO_PROTOCOL.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _SD_HOST_IO_H
+#define _SD_HOST_IO_H
+
+#include "SDCard.h"
+#include "CEATA.h"
+
+
+#define EFI_SD_HOST_IO_PROTOCOL_GUID  \
+  { \
+    0xb63f8ec7, 0xa9c9, 0x4472, {0xa4, 0xc0, 0x4d, 0x8b, 0xf3, 0x65, 0xcc, 0x51} \
+  }
+
+///
+/// Forward reference for pure ANSI compatability
+///
+typedef struct _EFI_SD_HOST_IO_PROTOCOL EFI_SD_HOST_IO_PROTOCOL;
+
+
+
+typedef enum {
+  ResponseNo = 0,
+  ResponseR1,
+  ResponseR1b,
+  ResponseR2,
+  ResponseR3,
+  ResponseR4,
+  ResponseR5,
+  ResponseR5b,
+  ResponseR6,
+  ResponseR7
+}RESPONSE_TYPE;
+
+typedef enum {
+  NoData = 0,
+  InData,
+  OutData
+}TRANSFER_TYPE;
+
+typedef enum {
+  Reset_Auto = 0,
+  Reset_DAT,
+  Reset_CMD,
+  Reset_DAT_CMD,
+  Reset_All
+}RESET_TYPE;
+
+#define PCI_SUBCLASS_SD_HOST_CONTROLLER           0x05
+#define PCI_IF_STANDARD_HOST_NO_DMA               0x00
+#define PCI_IF_STANDARD_HOST_SUPPORT_DMA          0x01
+
+#define   SDHCI_SPEC_100                          0
+#define   SDHCI_SPEC_200                          1
+#define   SDHCI_SPEC_300                          2
+
+//
+//MMIO Registers definition for MMC/SDIO controller
+//
+#define  MMIO_DMAADR                              0x00
+#define  MMIO_BLKSZ                               0x04
+#define  MMIO_BLKCNT                              0x06
+#define  MMIO_CMDARG                              0x08
+#define  MMIO_XFRMODE                             0x0C
+#define  MMIO_SDCMD                               0x0E
+#define  MMIO_RESP                                0x10
+#define  MMIO_BUFDATA                             0x20
+#define  MMIO_PSTATE                              0x24
+#define  MMIO_HOSTCTL                             0x28
+#define  MMIO_PWRCTL                              0x29
+#define  MMIO_BLKGAPCTL                           0x2A
+#define  MMIO_WAKECTL                             0x2B
+#define  MMIO_CLKCTL                              0x2C
+#define   V_MMIO_CLKCTL_MAX_8BIT_FREQ_SEL           0x80
+#define   V_MMIO_CLKCTL_MAX_10BIT_FREQ_SEL          0x3FF
+#define   B_MMIO_CLKCTL_UPR_SDCLK_FREQ_SEL_MASK     0xC0
+
+#define  MMIO_TOCTL                               0x2E
+#define  MMIO_SWRST                               0x2F
+#define  MMIO_NINTSTS                             0x30
+#define  MMIO_ERINTSTS                            0x32
+#define  MMIO_NINTEN                              0x34
+#define  MMIO_ERINTEN                             0x36
+#define  MMIO_NINTSIGEN                           0x38
+#define  MMIO_ERINTSIGEN                          0x3A
+#define  MMIO_AC12ERRSTS                          0x3C
+#define  MMIO_HOSTCTL2                            0x3E
+#define  MMIO_CAP                                 0x40
+#define  MMIO_MCCAP                               0x48
+#define  MMIO_SLTINTSTS                           0xFC
+#define  MMIO_CTRLRVER                            0xFE
+#define  MMIO_SRST                                0x1FC
+
+//
+// Protocol definitions
+//
+
+/**
+  The main function used to send the command to the card inserted into the SD host slot.
+  It will assemble the arguments to set the command register and wait for the command
+  and transfer completed until timeout. Then it will read the response register to fill
+  the ResponseData.
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  CommandIndex          The command index to set the command index field of command register.
+  @param  Argument              Command argument to set the argument field of command register.
+  @param  DataType              TRANSFER_TYPE, indicates no data, data in or data out.
+  @param  Buffer                Contains the data read from / write to the device.
+  @param  BufferSize            The size of the buffer.
+  @param  ResponseType          RESPONSE_TYPE.
+  @param  TimeOut               Time out value in 1 ms unit.
+  @param  ResponseData          Depending on the ResponseType, such as CSD or card status.
+
+  @retval EFI_SUCCESS
+  @retval EFI_INVALID_PARAMETER
+  @retval EFI_OUT_OF_RESOURCES
+  @retval EFI_TIMEOUT
+  @retval EFI_DEVICE_ERROR
+
+**/
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SEND_COMMAND) (
+  IN   EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN   UINT16                     CommandIndex,
+  IN   UINT32                     Argument,
+  IN   TRANSFER_TYPE              DataType,
+  IN   UINT8                      *Buffer, OPTIONAL
+  IN   UINT32                     BufferSize,
+  IN   RESPONSE_TYPE              ResponseType,
+  IN   UINT32                     TimeOut,
+  OUT  UINT32                     *ResponseData OPTIONAL
+  );
+
+/**
+  Set max clock frequency of the host, the actual frequency may not be the same as MaxFrequency.
+  It depends on the max frequency the host can support, divider, and host speed mode.
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  MaxFrequency          Max frequency in HZ.
+
+  @retval EFI_SUCCESS
+  @retval EFI_TIMEOUT
+
+**/
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SET_CLOCK_FREQUENCY) (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  UINT32                     MaxFrequency
+  );
+
+
+/**
+  Set bus width of the host controller
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  BusWidth              Bus width in 1, 4, 8 bits.
+
+  @retval EFI_SUCCESS
+  @retval EFI_INVALID_PARAMETER
+
+**/
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SET_BUS_WIDTH) (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  UINT32                     BusWidth
+  );
+
+/**
+  Set voltage which could supported by the host controller.
+  Support 0(Power off the host), 1.8V, 3.0V, 3.3V
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  Voltage               Units in 0.1 V.
+
+  @retval EFI_SUCCESS
+  @retval EFI_INVALID_PARAMETER
+
+**/
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SET_HOST_VOLTAGE) (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  UINT32                     Voltage
+  );
+
+/**
+  Reset the host controller.
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  ResetAll              TRUE to reset all.
+
+  @retval EFI_SUCCESS
+  @retval EFI_TIMEOUT
+
+**/
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_RESET_SD_HOST) (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  RESET_TYPE                 ResetType
+  );
+
+/**
+  Enable auto stop on the host controller.
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  Enable                TRUE to enable, FALSE to disable.
+
+  @retval EFI_SUCCESS
+  @retval EFI_TIMEOUT
+
+**/
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_ENABLE_AUTO_STOP_CMD) (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  BOOLEAN                    Enable
+  );
+
+/**
+  Find whether these is a card inserted into the slot. If so init the host.
+  If not, return EFI_NOT_FOUND.
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+
+  @retval EFI_SUCCESS
+  @retval EFI_NOT_FOUND
+
+**/
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_DETECT_CARD_AND_INIT_HOST) (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This
+  );
+
+/**
+  Set the Block length on the host controller.
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  BlockLength           card supportes block length.
+
+  @retval EFI_SUCCESS
+  @retval EFI_TIMEOUT
+
+**/
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SET_BLOCK_LENGTH) (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  UINT32                     BlockLength
+  );
+
+/**
+  Enable/Disable High Speed transfer mode
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  Enable                TRUE to Enable, FALSE to Disable
+
+  @return EFI_SUCCESS
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_HIGH_SPEED_MODE) (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  BOOLEAN                    Enable
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_DUAL_DATARATE_MODE) (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  BOOLEAN                    Enable
+  );
+
+
+
+#define EFI_SD_HOST_IO_PROTOCOL_REVISION_01          0x02
+
+
+typedef struct {
+  UINT32  HighSpeedSupport:    1;  //High speed supported
+  UINT32  V18Support:          1;  //1.8V supported
+  UINT32  V30Support:          1;  //3.0V supported
+  UINT32  V33Support:          1;  //3.3V supported
+  UINT32  Reserved0:           4;
+  UINT32  HostVersion:         8;
+  UINT32  BusWidth4:           1;  // 4 bit width
+  UINT32  BusWidth8:           1;  // 8 bit width
+  UINT32  Reserved1:           14;
+  UINT32  BoundarySize;
+}HOST_CAPABILITY;
+
+
+//
+// Interface structure for the SD HOST I/O Protocol
+//
+struct _EFI_SD_HOST_IO_PROTOCOL {
+  UINT32                                             Revision;
+  HOST_CAPABILITY                                    HostCapability;
+  EFI_SD_HOST_IO_PROTOCOL_SEND_COMMAND               SendCommand;
+  EFI_SD_HOST_IO_PROTOCOL_SET_CLOCK_FREQUENCY        SetClockFrequency;
+  EFI_SD_HOST_IO_PROTOCOL_SET_BUS_WIDTH              SetBusWidth;
+  EFI_SD_HOST_IO_PROTOCOL_SET_HOST_VOLTAGE           SetHostVoltage;
+  EFI_SD_HOST_IO_PROTOCOL_RESET_SD_HOST              ResetSDHost;
+  EFI_SD_HOST_IO_PROTOCOL_ENABLE_AUTO_STOP_CMD       EnableAutoStopCmd;
+  EFI_SD_HOST_IO_PROTOCOL_DETECT_CARD_AND_INIT_HOST  DetectCardAndInitHost;
+  EFI_SD_HOST_IO_PROTOCOL_SET_BLOCK_LENGTH           SetBlockLength;
+  EFI_SD_HOST_IO_PROTOCOL_HIGH_SPEED_MODE            SetHighSpeedMode;
+  EFI_SD_HOST_IO_PROTOCOL_DUAL_DATARATE_MODE         SetDDRMode;
+};
+
+extern EFI_GUID gEfiSDHostIoProtocolGuid;
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/CommonHeader.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/CommonHeader.h
new file mode 100644
index 0000000000..dfc8a244c5
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/CommonHeader.h
@@ -0,0 +1,55 @@
+/** @file
+Common header file shared by all source files.
+
+This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+//
+// The package level header files this module uses
+//
+#include <PiDxe.h>
+#include <Ioh.h>
+#include <IohCommonDefinitions.h>
+
+//
+// The protocols, PPI and GUID defintions for this module
+//
+#include <Protocol/PciRootBridgeIo.h>
+
+#include <Protocol/PciIo.h>
+#include <Protocol/DevicePath.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/BaseLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/S3PciLib.h>
+#include <Library/S3IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PciLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/TimerLib.h>
+#include <Library/IoLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IohLib.h>
+
+#include <Library/MemoryAllocationLib.h>
+#include <IndustryStandard/Pci.h>
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohBds.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohBds.h
new file mode 100644
index 0000000000..1212ab86fd
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohBds.h
@@ -0,0 +1,83 @@
+/** @file
+Head file for BDS Platform specific code
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _IOH_BDS_H
+#define _IOH_BDS_H
+
+#include <Ioh.h>
+#include <Protocol/DevicePath.h>
+#include <Library/DevicePathLib.h>
+
+extern EFI_DEVICE_PATH_PROTOCOL  *gDeviceConnectOption [];
+
+#define PCI_DEVICE_PATH_NODE(Func, Dev) \
+  { \
+    { \
+      HARDWARE_DEVICE_PATH, \
+      HW_PCI_DP, \
+      { \
+        (UINT8) (sizeof (PCI_DEVICE_PATH)), \
+        (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) \
+      } \
+    }, \
+    (Func), \
+    (Dev) \
+  }
+
+#define PNPID_DEVICE_PATH_NODE(PnpId) \
+  { \
+    { \
+      ACPI_DEVICE_PATH, \
+      ACPI_DP, \
+      { \
+        (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \
+        (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \
+      } \
+    }, \
+    EISA_PNP_ID((PnpId)), \
+    0 \
+  }
+
+
+
+#define gEndEntire \
+  { \
+    END_DEVICE_PATH_TYPE, \
+    END_ENTIRE_DEVICE_PATH_SUBTYPE, \
+    { \
+      END_DEVICE_PATH_LENGTH, \
+      0 \
+    } \
+  }
+
+#define gPciRootBridge \
+  PNPID_DEVICE_PATH_NODE(0x0A03)
+
+
+//
+// Platform Root Bridge
+//
+typedef struct {
+  ACPI_HID_DEVICE_PATH      PciRootBridge;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} PLATFORM_ROOT_BRIDGE_DEVICE_PATH;
+
+
+typedef struct {
+  ACPI_HID_DEVICE_PATH      PciRootBridge;
+  PCI_DEVICE_PATH           IohDevice;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} IOH_PCI_USB_DEVICE_PATH;
+
+//
+// Ioh BDS Functions
+//
+
+
+#endif // _IOH_BDS_H
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohData.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohData.c
new file mode 100644
index 0000000000..cf6006626b
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohData.c
@@ -0,0 +1,42 @@
+/** @file
+Defined the Ioh device path which will be used by
+platform Bbd to perform the platform policy connect.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "IohBds.h"
+
+//
+// Predefined platform root bridge
+//
+PLATFORM_ROOT_BRIDGE_DEVICE_PATH gPlatformRootBridge0 = {
+  gPciRootBridge,
+  gEndEntire
+};
+
+EFI_DEVICE_PATH_PROTOCOL* gPlatformRootBridges [] = {
+  (EFI_DEVICE_PATH_PROTOCOL*)&gPlatformRootBridge0,
+  NULL
+};
+
+//
+// Ioh USB EHCI controller device path
+//
+IOH_PCI_USB_DEVICE_PATH gIohUsbDevicePath0 = {
+  gPciRootBridge,
+  PCI_DEVICE_PATH_NODE(IOH_EHCI_FUNCTION_NUMBER, IOH_USB_EHCI_DEVICE_NUMBER),
+  gEndEntire
+};
+
+//
+// Ioh predefined device connecting option
+//
+EFI_DEVICE_PATH_PROTOCOL* gDeviceConnectOption [] = {
+  //  (EFI_DEVICE_PATH_PROTOCOL*)&gIohUsbDevicePath0,
+  NULL
+};
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohInit.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohInit.c
new file mode 100644
index 0000000000..8ea791a88c
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohInit.c
@@ -0,0 +1,37 @@
+/** @file
+QuarkSCSocId module initialization module
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "CommonHeader.h"
+#include "IohBds.h"
+
+/**
+   The entry function for IohInit driver.
+
+   This function just call initialization function.
+
+   @param ImageHandle   The driver image handle for GmchInit driver
+   @param SystemTable   The pointer to System Table
+
+   @retval EFI_SUCCESS  Success to initialize every module.
+   @return EFI_STATUS   The status of initialization work.
+
+**/
+EFI_STATUS
+EFIAPI
+IohInit (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+
+  InitializeIohSsvidSsid(IOH_BUS, IOH_PCI_IOSF2AHB_0_DEV_NUM, 0);
+
+  InitializeIohSsvidSsid(IOH_BUS, IOH_PCI_IOSF2AHB_1_DEV_NUM, 0);
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohInitDxe.inf b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohInitDxe.inf
new file mode 100644
index 0000000000..264a9eea7d
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohInitDxe.inf
@@ -0,0 +1,76 @@
+## @file
+# Component description file for Quark South Cluster Init driver.
+#
+# IohInit driver implement QuarkSCSocId related drivers, includes:
+# PciHostBridge, PciExpress, SmmAccess driver and LegacyRegion driver.
+#
+# This driver mainly do full initialization for the Soc chipet includes:
+# 1. Initialize the PCI Express device.
+# 2. Initialize the PciHostBridge, and allocate the I/O and memory space from GCD service.
+# 3. Initialize the SmmAccess module and install EFI_SMM_ACCESS_PROTOCOL
+# 4. Initialize the LegacyRegion module, install EFI_LEGACY_REGION_PROTOCOL and set below 1M
+#    memory attribute from MTRR.
+#
+# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = IohInitDxe
+  FILE_GUID                      = 3FE2A8A3-C400-48F8-832F-7881A394C250
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = IohInit
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  IohInit.c
+  IohBds.h
+  IohData.c
+  CommonHeader.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  S3BootScriptLib
+  PcdLib
+  HobLib
+  PciLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  S3PciLib
+  UefiLib
+  DebugLib
+  UefiRuntimeServicesTableLib
+  UefiBootServicesTableLib
+  DxeServicesTableLib
+  UefiDriverEntryPoint
+  BaseLib
+  S3IoLib
+  IoLib
+  DevicePathLib
+  IohLib
+
+[Protocols]
+  gEfiPciRootBridgeIoProtocolGuid               # PROTOCOL ALWAYS_PRODUCED
+  gEfiDevicePathProtocolGuid                    # PROTOCOL ALWAYS_CONSUMED
+  gEfiPciIoProtocolGuid
+
+[Pcd]
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohUartBusNumber
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohUartDevNumber
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohUartFunctionNumber
+
+[Depex]
+  TRUE
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/CommonHeader.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/CommonHeader.h
new file mode 100644
index 0000000000..67c66ff4ac
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/CommonHeader.h
@@ -0,0 +1,214 @@
+/** @file
+Provides definition of entry point to the common I2C module that produces
+common I2C Controller functions used by I2C library services.
+
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#ifndef _I2CCOMMON_H_
+#define _I2CCOMMON_H_
+
+#include <Uefi.h>
+#include <Base.h>
+
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+#include <Library/I2cLib.h>
+#include <IohAccess.h>
+#include <IohCommonDefinitions.h>
+#include "I2cRegs.h"
+
+//
+// Constants that define I2C Controller timeout and max. polling time.
+//
+#define MAX_T_POLL_COUNT         100
+#define TI2C_POLL                25  // microseconds
+#define MAX_STOP_DET_POLL_COUNT ((1000 * 1000) / TI2C_POLL)  // Extreme for expected Stop detect.
+
+/**
+  The GetI2CIoPortBaseAddress() function gets IO port base address of I2C Controller.
+
+  Always reads PCI configuration space to get MMIO base address of I2C Controller.
+
+  @return The IO port base address of I2C controller.
+
+**/
+UINTN
+GetI2CIoPortBaseAddress (
+  VOID
+  );
+
+/**
+  The EnableI2CMmioSpace() function enables access to I2C MMIO space.
+
+**/
+VOID
+EnableI2CMmioSpace (
+  VOID
+  );
+
+/**
+  The DisableI2CController() functions disables I2C Controller.
+
+**/
+VOID
+DisableI2CController (
+  VOID
+  );
+
+/**
+  The EnableI2CController() function enables the I2C Controller.
+
+**/
+VOID
+EnableI2CController (
+  VOID
+  );
+
+/**
+  The WaitForStopDet() function waits until I2C STOP Condition occurs,
+  indicating transfer completion.
+
+  @retval EFI_SUCCESS           Stop detected.
+  @retval EFI_TIMEOUT           Timeout while waiting for stop condition.
+  @retval EFI_ABORTED           Tx abort signaled in HW status register.
+  @retval EFI_DEVICE_ERROR      Tx or Rx overflow detected.
+
+**/
+EFI_STATUS
+WaitForStopDet (
+  VOID
+  );
+
+/**
+
+  The InitializeInternal() function initialises internal I2C Controller
+  register values that are commonly required for I2C Write and Read transfers.
+
+  @param AddrMode     I2C Addressing Mode: 7-bit or 10-bit address.
+
+  @retval EFI_SUCCESS           I2C Operation completed successfully.
+
+**/
+EFI_STATUS
+InitializeInternal (
+  IN EFI_I2C_ADDR_MODE  AddrMode
+  );
+
+/**
+
+  The WriteByte() function provides a standard way to execute a
+  standard single byte write to an IC2 device (without accessing
+  sub-addresses), as defined in the I2C Specification.
+
+  @param  I2CAddress      I2C Slave device address
+  @param  Value           The 8-bit value to write.
+
+  @retval EFI_SUCCESS           Transfer success.
+  @retval EFI_UNSUPPORTED       Unsupported input param.
+  @retval EFI_TIMEOUT           Timeout while waiting xfer.
+  @retval EFI_ABORTED           Controller aborted xfer.
+  @retval EFI_DEVICE_ERROR      Device error detected by controller.
+
+**/
+EFI_STATUS
+EFIAPI
+WriteByte (
+  IN  UINTN          I2CAddress,
+  IN  UINT8          Value
+  );
+
+/**
+
+  The ReadByte() function provides a standard way to execute a
+  standard single byte read to an IC2 device (without accessing
+  sub-addresses), as defined in the I2C Specification.
+
+  @param  I2CAddress      I2C Slave device address
+  @param  ReturnDataPtr   Pointer to location to receive read byte.
+
+  @retval EFI_SUCCESS           Transfer success.
+  @retval EFI_UNSUPPORTED       Unsupported input param.
+  @retval EFI_TIMEOUT           Timeout while waiting xfer.
+  @retval EFI_ABORTED           Controller aborted xfer.
+  @retval EFI_DEVICE_ERROR      Device error detected by controller.
+
+**/
+EFI_STATUS
+EFIAPI
+ReadByte (
+  IN  UINTN          I2CAddress,
+  OUT UINT8          *ReturnDataPtr
+  );
+
+/**
+
+  The WriteMultipleByte() function provides a standard way to execute
+  multiple byte writes to an IC2 device (e.g. when accessing sub-addresses or
+  when writing block of data), as defined in the I2C Specification.
+
+  @param I2CAddress   The I2C slave address of the device
+                      with which to communicate.
+
+  @param WriteBuffer  Contains the value of byte to be written to the
+                      I2C slave device.
+
+  @param Length       No. of bytes to be written.
+
+  @retval EFI_SUCCESS           Transfer success.
+  @retval EFI_UNSUPPORTED       Unsupported input param.
+  @retval EFI_TIMEOUT           Timeout while waiting xfer.
+  @retval EFI_ABORTED           Tx abort signaled in HW status register.
+  @retval EFI_DEVICE_ERROR      Tx overflow detected.
+
+**/
+EFI_STATUS
+EFIAPI
+WriteMultipleByte (
+  IN  UINTN          I2CAddress,
+  IN  UINT8          *WriteBuffer,
+  IN  UINTN          Length
+  );
+
+/**
+
+  The ReadMultipleByte() function provides a standard way to execute
+  multiple byte writes to an IC2 device (e.g. when accessing sub-addresses or
+  when reading block of data), as defined in the I2C Specification (I2C combined
+  write/read protocol).
+
+  @param I2CAddress   The I2C slave address of the device
+                      with which to communicate.
+
+  @param Buffer       Contains the value of byte data written or read from the
+                      I2C slave device.
+
+  @param WriteLength  No. of bytes to be written. In this case data
+                      written typically contains sub-address or sub-addresses
+                      in Hi-Lo format, that need to be read (I2C combined
+                      write/read protocol).
+
+  @param ReadLength   No. of bytes to be read from I2C slave device.
+
+  @retval EFI_SUCCESS           Transfer success.
+  @retval EFI_UNSUPPORTED       Unsupported input param.
+  @retval EFI_TIMEOUT           Timeout while waiting xfer.
+  @retval EFI_ABORTED           Tx abort signaled in HW status register.
+  @retval EFI_DEVICE_ERROR      Rx underflow or Rx/Tx overflow detected.
+
+**/
+EFI_STATUS
+EFIAPI
+ReadMultipleByte (
+  IN  UINTN          I2CAddress,
+  IN  OUT UINT8      *Buffer,
+  IN  UINTN          WriteLength,
+  IN  UINTN          ReadLength
+  );
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/I2cLib.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/I2cLib.c
new file mode 100644
index 0000000000..de99361f46
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/I2cLib.c
@@ -0,0 +1,998 @@
+/** @file
+I2C Library for Quark I2C Controller.
+Follows I2C Controller setup instructions as detailed in
+Quark DataSheet (doc id: 329676) Section 19.1/19.1.3.
+
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CommonHeader.h"
+
+/**
+  The Called to Common Service Entry.
+
+  @return None.
+
+**/
+
+VOID
+I2cCommonServiceEntry  (
+  OUT UINT16 *SaveCmdPtr,
+  OUT UINT32 *SaveBar0Ptr
+  )
+{
+  *SaveBar0Ptr = IohMmPci32 (0, I2C_Bus, I2C_Device, I2C_Func, PCI_BAR0);
+  if (((*SaveBar0Ptr) & B_IOH_I2C_GPIO_MEMBAR_ADDR_MASK) == 0) {
+
+    IohMmPci32(0, I2C_Bus, I2C_Device, I2C_Func, PCI_BAR0) =
+      FixedPcdGet32 (PcdIohI2cMmioBase) & B_IOH_I2C_GPIO_MEMBAR_ADDR_MASK;
+
+    //
+    // also Save Cmd Register, Setup by InitializeInternal later during xfers.
+    //
+    *SaveCmdPtr = IohMmPci16 (0, I2C_Bus, I2C_Device, I2C_Func, PCI_CMD);
+  }
+}
+
+/**
+  The Called on Common Service Exit.
+
+  @return None.
+
+**/
+VOID
+I2cCommonServiceExit  (
+  IN CONST UINT16 SaveCmd,
+  IN CONST UINT32 SaveBar0
+
+  )
+{
+  if ((SaveBar0 & B_IOH_I2C_GPIO_MEMBAR_ADDR_MASK) == 0) {
+    IohMmPci16 (0, I2C_Bus, I2C_Device, I2C_Func, PCI_CMD) = SaveCmd;
+    IohMmPci32 (0, I2C_Bus, I2C_Device, I2C_Func, PCI_BAR0) = SaveBar0;
+  }
+}
+
+
+/**
+  The GetI2CIoPortBaseAddress() function gets IO port base address of I2C Controller.
+
+  Always reads PCI configuration space to get MMIO base address of I2C Controller.
+
+  @return The IO port base address of I2C controller.
+
+**/
+UINTN
+GetI2CIoPortBaseAddress (
+  VOID
+  )
+{
+  UINTN     I2CIoPortBaseAddress;
+
+  //
+  // Get I2C Memory Mapped registers base address.
+  //
+  I2CIoPortBaseAddress = IohMmPci32(0, I2C_Bus, I2C_Device, I2C_Func, PCI_BAR0);
+
+  //
+  // Make sure that the IO port base address has been properly set.
+  //
+  ASSERT (I2CIoPortBaseAddress != 0);
+  ASSERT (I2CIoPortBaseAddress != 0xFF);
+
+  return I2CIoPortBaseAddress;
+}
+
+
+/**
+  The EnableI2CMmioSpace() function enables access to I2C MMIO space.
+
+**/
+VOID
+EnableI2CMmioSpace (
+  VOID
+  )
+{
+  UINT8 PciCmd;
+
+  //
+  // Read PCICMD.  Bus=0, Dev=0, Func=0, Reg=0x4
+  //
+  PciCmd = IohMmPci8(0, I2C_Bus, I2C_Device, I2C_Func, PCI_REG_PCICMD);
+
+  //
+  // Enable Bus Master(Bit2), MMIO Space(Bit1) & I/O Space(Bit0)
+  //
+  PciCmd |= 0x7;
+  IohMmPci8(0, I2C_Bus, I2C_Device, I2C_Func, PCI_REG_PCICMD) = PciCmd;
+
+}
+
+/**
+  The DisableI2CController() functions disables I2C Controller.
+
+**/
+VOID
+DisableI2CController (
+  VOID
+  )
+{
+  UINTN       I2CIoPortBaseAddress;
+  UINT32      Addr;
+  UINT32      Data;
+  UINT8       PollCount;
+
+  PollCount = 0;
+
+  //
+  // Get I2C Memory Mapped registers base address.
+  //
+  I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
+
+  //
+  // Disable the I2C Controller by setting IC_ENABLE.ENABLE to zero
+  //
+  Addr = I2CIoPortBaseAddress + I2C_REG_ENABLE;
+  Data = *((volatile UINT32 *) (UINTN)(Addr));
+  Data &= ~B_I2C_REG_ENABLE;
+  *((volatile UINT32 *) (UINTN)(Addr)) = Data;
+
+  //
+  // Read the IC_ENABLE_STATUS.IC_EN Bit to check if Controller is disabled
+  //
+  Data = 0xFF;
+  Addr = I2CIoPortBaseAddress + I2C_REG_ENABLE_STATUS;
+  Data = *((volatile UINT32 *) (UINTN)(Addr)) & I2C_REG_ENABLE_STATUS;
+  while (Data != 0) {
+    //
+    // Poll the IC_ENABLE_STATUS.IC_EN Bit to check if Controller is disabled, until timeout (TI2C_POLL*MAX_T_POLL_COUNT).
+    //
+    PollCount++;
+    if (PollCount >= MAX_T_POLL_COUNT) {
+      break;
+    }
+    MicroSecondDelay(TI2C_POLL);
+    Data = *((volatile UINT32 *) (UINTN)(Addr));
+    Data &= I2C_REG_ENABLE_STATUS;
+  }
+
+  //
+  // Asset if controller does not enter Disabled state.
+  //
+  ASSERT (PollCount < MAX_T_POLL_COUNT);
+
+  //
+  // Read IC_CLR_INTR register to automatically clear the combined interrupt,
+  // all individual interrupts and the IC_TX_ABRT_SOURCE register.
+  //
+  Addr = I2CIoPortBaseAddress + I2C_REG_CLR_INT;
+  Data = *((volatile UINT32 *) (UINTN)(Addr));
+
+}
+
+/**
+  The EnableI2CController() function enables the I2C Controller.
+
+**/
+VOID
+EnableI2CController (
+  VOID
+  )
+{
+  UINTN   I2CIoPortBaseAddress;
+  UINT32  Addr;
+  UINT32  Data;
+
+  //
+  // Get I2C Memory Mapped registers base address.
+  //
+  I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
+
+  //
+  // Enable the I2C Controller by setting IC_ENABLE.ENABLE to 1
+  //
+  Addr = I2CIoPortBaseAddress + I2C_REG_ENABLE;
+  Data = *((volatile UINT32 *) (UINTN)(Addr));
+  Data |= B_I2C_REG_ENABLE;
+  *((volatile UINT32 *) (UINTN)(Addr)) = Data;
+
+  //
+  // Clear overflow and abort error status bits before transactions.
+  //
+  Addr = I2CIoPortBaseAddress + I2C_REG_CLR_RX_OVER;
+  Data = *((volatile UINT32 *) (UINTN)(Addr));
+  Addr = I2CIoPortBaseAddress + I2C_REG_CLR_TX_OVER;
+  Data = *((volatile UINT32 *) (UINTN)(Addr));
+  Addr = I2CIoPortBaseAddress + I2C_REG_CLR_TX_ABRT;
+  Data = *((volatile UINT32 *) (UINTN)(Addr));
+
+}
+
+/**
+  The WaitForStopDet() function waits until I2C STOP Condition occurs,
+  indicating transfer completion.
+
+  @retval EFI_SUCCESS           Stop detected.
+  @retval EFI_TIMEOUT           Timeout while waiting for stop condition.
+  @retval EFI_ABORTED           Tx abort signaled in HW status register.
+  @retval EFI_DEVICE_ERROR      Tx or Rx overflow detected.
+
+**/
+EFI_STATUS
+WaitForStopDet (
+  VOID
+  )
+{
+  UINTN       I2CIoPortBaseAddress;
+  UINT32      Addr;
+  UINT32      Data;
+  UINT32      PollCount;
+  EFI_STATUS  Status;
+
+  Status = EFI_SUCCESS;
+
+  PollCount = 0;
+
+  //
+  // Get I2C Memory Mapped registers base address.
+  //
+  I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
+
+  //
+  // Wait for STOP Detect.
+  //
+  Addr = I2CIoPortBaseAddress + I2C_REG_RAW_INTR_STAT;
+
+  do {
+    Data = *((volatile UINT32 *) (UINTN)(Addr));
+    if ((Data & I2C_REG_RAW_INTR_STAT_TX_ABRT) != 0) {
+      Status = EFI_ABORTED;
+      break;
+    }
+    if ((Data & I2C_REG_RAW_INTR_STAT_TX_OVER) != 0) {
+      Status = EFI_DEVICE_ERROR;
+      break;
+    }
+    if ((Data & I2C_REG_RAW_INTR_STAT_RX_OVER) != 0) {
+      Status = EFI_DEVICE_ERROR;
+      break;
+    }
+    if ((Data & I2C_REG_RAW_INTR_STAT_STOP_DET) != 0) {
+      Status = EFI_SUCCESS;
+      break;
+    }
+    MicroSecondDelay(TI2C_POLL);
+    PollCount++;
+    if (PollCount >= MAX_STOP_DET_POLL_COUNT) {
+      Status = EFI_TIMEOUT;
+      break;
+    }
+
+  } while (TRUE);
+
+  return Status;
+}
+
+/**
+
+  The InitializeInternal() function initialises internal I2C Controller
+  register values that are commonly required for I2C Write and Read transfers.
+
+  @param AddrMode     I2C Addressing Mode: 7-bit or 10-bit address.
+
+  @retval EFI_SUCCESS           I2C Operation completed successfully.
+
+**/
+EFI_STATUS
+InitializeInternal (
+  IN  EFI_I2C_ADDR_MODE  AddrMode
+  )
+{
+  UINTN       I2CIoPortBaseAddress;
+  UINTN       Addr;
+  UINT32      Data;
+  EFI_STATUS  Status;
+
+  Status = EFI_SUCCESS;
+
+  //
+  // Enable access to I2C Controller MMIO space.
+  //
+  EnableI2CMmioSpace ();
+
+  //
+  // Disable I2C Controller initially
+  //
+  DisableI2CController ();
+
+  //
+  // Get I2C Memory Mapped registers base address.
+  //
+  I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
+
+  //
+  // Clear START_DET
+  //
+  Addr = I2CIoPortBaseAddress + I2C_REG_CLR_START_DET;
+  Data = *((volatile UINT32 *) (UINTN)(Addr));
+  Data &= ~B_I2C_REG_CLR_START_DET;
+  *((volatile UINT32 *) (UINTN)(Addr)) = Data;
+
+  //
+  // Clear STOP_DET
+  //
+  Addr = I2CIoPortBaseAddress + I2C_REG_CLR_STOP_DET;
+  Data = *((volatile UINT32 *) (UINTN)(Addr));
+  Data &= ~B_I2C_REG_CLR_STOP_DET;
+  *((volatile UINT32 *) (UINTN)(Addr)) = Data;
+
+  //
+  // Set addressing mode to user defined (7 or 10 bit) and
+  // speed mode to that defined by PCD (standard mode default).
+  //
+  Addr = I2CIoPortBaseAddress + I2C_REG_CON;
+  Data = *((volatile UINT32 *) (UINTN)(Addr));
+  // Set Addressing Mode
+  if (AddrMode == EfiI2CSevenBitAddrMode) {
+    Data &= ~B_I2C_REG_CON_10BITADD_MASTER;
+  } else {
+    Data |= B_I2C_REG_CON_10BITADD_MASTER;
+  }
+  // Set Speed Mode
+  Data &= ~B_I2C_REG_CON_SPEED;
+  if (FeaturePcdGet (PcdI2CFastModeEnabled)) {
+    Data |= BIT2;
+  } else {
+    Data |= BIT1;
+  }
+  *((volatile UINT32 *) (UINTN)(Addr)) = Data;
+
+  Data = *((volatile UINT32 *) (UINTN)(Addr));
+
+  return Status;
+
+}
+
+/**
+
+  The WriteByte() function provides a standard way to execute a
+  standard single byte write to an IC2 device (without accessing
+  sub-addresses), as defined in the I2C Specification.
+
+  @param  I2CAddress      I2C Slave device address
+  @param  Value           The 8-bit value to write.
+
+  @retval EFI_SUCCESS           Transfer success.
+  @retval EFI_UNSUPPORTED       Unsupported input param.
+  @retval EFI_TIMEOUT           Timeout while waiting xfer.
+  @retval EFI_ABORTED           Controller aborted xfer.
+  @retval EFI_DEVICE_ERROR      Device error detected by controller.
+
+**/
+EFI_STATUS
+EFIAPI
+WriteByte (
+  IN  UINTN          I2CAddress,
+  IN  UINT8          Value
+  )
+{
+  UINTN       I2CIoPortBaseAddress;
+  UINTN       Addr;
+  UINT32      Data;
+  EFI_STATUS  Status;
+
+  //
+  // Get I2C Memory Mapped registers base address
+  //
+  I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
+
+  //
+  // Write to the IC_TAR register the address of the slave device to be addressed
+  //
+  Addr = I2CIoPortBaseAddress + I2C_REG_TAR;
+  Data = *((volatile UINT32 *) (UINTN)(Addr));
+  Data &= ~B_I2C_REG_TAR;
+  Data |= I2CAddress;
+  *((volatile UINT32 *) (UINTN)(Addr)) = Data;
+
+  //
+  // Enable the I2C Controller
+  //
+  EnableI2CController ();
+
+  //
+  // Write the data and transfer direction to the IC_DATA_CMD register.
+  // Also specify that transfer should be terminated by STOP condition.
+  //
+  Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD;
+  Data = *((volatile UINT32 *) (UINTN)(Addr));
+  Data &= 0xFFFFFF00;
+  Data |= (UINT8)Value;
+  Data &= ~B_I2C_REG_DATA_CMD_RW;
+  Data |= B_I2C_REG_DATA_CMD_STOP;
+  *((volatile UINT32 *) (UINTN)(Addr)) = Data;
+
+  //
+  // Wait for transfer completion.
+  //
+  Status = WaitForStopDet ();
+
+  //
+  // Ensure I2C Controller disabled.
+  //
+  DisableI2CController();
+
+  return Status;
+}
+
+/**
+
+  The ReadByte() function provides a standard way to execute a
+  standard single byte read to an IC2 device (without accessing
+  sub-addresses), as defined in the I2C Specification.
+
+  @param  I2CAddress      I2C Slave device address
+  @param  ReturnDataPtr   Pointer to location to receive read byte.
+
+  @retval EFI_SUCCESS           Transfer success.
+  @retval EFI_UNSUPPORTED       Unsupported input param.
+  @retval EFI_TIMEOUT           Timeout while waiting xfer.
+  @retval EFI_ABORTED           Controller aborted xfer.
+  @retval EFI_DEVICE_ERROR      Device error detected by controller.
+
+**/
+EFI_STATUS
+EFIAPI
+ReadByte (
+  IN  UINTN          I2CAddress,
+  OUT UINT8          *ReturnDataPtr
+  )
+{
+  UINTN       I2CIoPortBaseAddress;
+  UINTN       Addr;
+  UINT32      Data;
+  EFI_STATUS  Status;
+
+  //
+  // Get I2C Memory Mapped registers base address.
+  //
+  I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
+
+  //
+  // Write to the IC_TAR register the address of the slave device to be addressed
+  //
+  Addr = I2CIoPortBaseAddress + I2C_REG_TAR;
+  Data = *((volatile UINT32 *) (UINTN)(Addr));
+  Data &= ~B_I2C_REG_TAR;
+  Data |= I2CAddress;
+  *((volatile UINT32 *) (UINTN)(Addr)) = Data;
+
+  //
+  // Enable the I2C Controller
+  //
+  EnableI2CController ();
+
+  //
+  // Write transfer direction to the IC_DATA_CMD register and
+  // specify that transfer should be terminated by STOP condition.
+  //
+  Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD;
+  Data = *((volatile UINT32 *) (UINTN)(Addr));
+  Data &= 0xFFFFFF00;
+  Data |= B_I2C_REG_DATA_CMD_RW;
+  Data |= B_I2C_REG_DATA_CMD_STOP;
+  *((volatile UINT32 *) (UINTN)(Addr)) = Data;
+
+  //
+  // Wait for transfer completion
+  //
+  Status = WaitForStopDet ();
+  if (!EFI_ERROR(Status)) {
+
+    //
+    // Clear RX underflow before reading IC_DATA_CMD.
+    //
+    Addr = I2CIoPortBaseAddress + I2C_REG_CLR_RX_UNDER;
+    Data = *((volatile UINT32 *) (UINTN)(Addr));
+
+    //
+    // Obtain and return read data byte from RX buffer (IC_DATA_CMD[7:0]).
+    //
+    Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD;
+    Data = *((volatile UINT32 *) (UINTN)(Addr));
+    Data &= 0x000000FF;
+    *ReturnDataPtr = (UINT8) Data;
+
+    Addr = I2CIoPortBaseAddress + I2C_REG_RAW_INTR_STAT;
+    Data = *((volatile UINT32 *) (UINTN)(Addr));
+    Data &= I2C_REG_RAW_INTR_STAT_RX_UNDER;
+    if (Data != 0) {
+      Status = EFI_DEVICE_ERROR;
+    }
+  }
+
+  //
+  // Ensure I2C Controller disabled.
+  //
+  DisableI2CController ();
+
+  return Status;
+}
+
+/**
+
+  The WriteMultipleByte() function provides a standard way to execute
+  multiple byte writes to an IC2 device (e.g. when accessing sub-addresses or
+  when writing block of data), as defined in the I2C Specification.
+
+  @param I2CAddress   The I2C slave address of the device
+                      with which to communicate.
+
+  @param WriteBuffer  Contains the value of byte to be written to the
+                      I2C slave device.
+
+  @param Length       No. of bytes to be written.
+
+  @retval EFI_SUCCESS           Transfer success.
+  @retval EFI_UNSUPPORTED       Unsupported input param.
+  @retval EFI_TIMEOUT           Timeout while waiting xfer.
+  @retval EFI_ABORTED           Tx abort signaled in HW status register.
+  @retval EFI_DEVICE_ERROR      Tx overflow detected.
+
+**/
+EFI_STATUS
+EFIAPI
+WriteMultipleByte (
+  IN  UINTN          I2CAddress,
+  IN  UINT8          *WriteBuffer,
+  IN  UINTN          Length
+  )
+{
+  UINTN       I2CIoPortBaseAddress;
+  UINTN       Index;
+  UINTN       Addr;
+  UINT32      Data;
+  EFI_STATUS  Status;
+
+  if (Length > I2C_FIFO_SIZE) {
+    return EFI_UNSUPPORTED;  // Routine does not handle xfers > fifo size.
+  }
+
+  I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
+
+  //
+  // Write to the IC_TAR register the address of the slave device to be addressed
+  //
+  Addr = I2CIoPortBaseAddress + I2C_REG_TAR;
+  Data = *((volatile UINT32 *) (UINTN)(Addr));
+  Data &= ~B_I2C_REG_TAR;
+  Data |= I2CAddress;
+  *((volatile UINT32 *) (UINTN)(Addr)) = Data;
+
+  //
+  // Enable the I2C Controller
+  //
+  EnableI2CController ();
+
+  //
+  // Write the data and transfer direction to the IC_DATA_CMD register.
+  // Also specify that transfer should be terminated by STOP condition.
+  //
+  Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD;
+  for (Index = 0; Index < Length; Index++) {
+    Data = *((volatile UINT32 *) (UINTN)(Addr));
+    Data &= 0xFFFFFF00;
+    Data |= (UINT8)WriteBuffer[Index];
+    Data &= ~B_I2C_REG_DATA_CMD_RW;
+    if (Index == (Length-1)) {
+      Data |= B_I2C_REG_DATA_CMD_STOP;
+    }
+    *((volatile UINT32 *) (UINTN)(Addr)) = Data;
+  }
+
+  //
+  // Wait for transfer completion
+  //
+  Status = WaitForStopDet ();
+
+  //
+  // Ensure I2C Controller disabled.
+  //
+  DisableI2CController ();
+  return Status;
+}
+
+/**
+
+  The ReadMultipleByte() function provides a standard way to execute
+  multiple byte writes to an IC2 device (e.g. when accessing sub-addresses or
+  when reading block of data), as defined in the I2C Specification (I2C combined
+  write/read protocol).
+
+  @param I2CAddress   The I2C slave address of the device
+                      with which to communicate.
+
+  @param Buffer       Contains the value of byte data written or read from the
+                      I2C slave device.
+
+  @param WriteLength  No. of bytes to be written. In this case data
+                      written typically contains sub-address or sub-addresses
+                      in Hi-Lo format, that need to be read (I2C combined
+                      write/read protocol).
+
+  @param ReadLength   No. of bytes to be read from I2C slave device.
+
+  @retval EFI_SUCCESS           Transfer success.
+  @retval EFI_UNSUPPORTED       Unsupported input param.
+  @retval EFI_TIMEOUT           Timeout while waiting xfer.
+  @retval EFI_ABORTED           Tx abort signaled in HW status register.
+  @retval EFI_DEVICE_ERROR      Rx underflow or Rx/Tx overflow detected.
+
+**/
+EFI_STATUS
+EFIAPI
+ReadMultipleByte (
+  IN  UINTN          I2CAddress,
+  IN  OUT UINT8      *Buffer,
+  IN  UINTN          WriteLength,
+  IN  UINTN          ReadLength
+  )
+{
+  UINTN       I2CIoPortBaseAddress;
+  UINTN       Index;
+  UINTN       Addr;
+  UINT32      Data;
+  UINT8       PollCount;
+  EFI_STATUS  Status;
+
+  if (WriteLength > I2C_FIFO_SIZE || ReadLength > I2C_FIFO_SIZE) {
+    return EFI_UNSUPPORTED;  // Routine does not handle xfers > fifo size.
+  }
+
+  I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
+
+  //
+  // Write to the IC_TAR register the address of the slave device to be addressed
+  //
+  Addr = I2CIoPortBaseAddress + I2C_REG_TAR;
+  Data = *((volatile UINT32 *) (UINTN)(Addr));
+  Data &= ~B_I2C_REG_TAR;
+  Data |= I2CAddress;
+  *((volatile UINT32 *) (UINTN)(Addr)) = Data;
+
+  //
+  // Enable the I2C Controller
+  //
+  EnableI2CController ();
+
+  //
+  // Write the data (sub-addresses) to the IC_DATA_CMD register.
+  //
+  Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD;
+  for (Index = 0; Index < WriteLength; Index++) {
+    Data = *((volatile UINT32 *) (UINTN)(Addr));
+    Data &= 0xFFFFFF00;
+    Data |= (UINT8)Buffer[Index];
+    Data &= ~B_I2C_REG_DATA_CMD_RW;
+    *((volatile UINT32 *) (UINTN)(Addr)) = Data;
+  }
+
+  //
+  // Issue Read Transfers for each byte (Restart issued when write/read bit changed).
+  //
+  for (Index = 0; Index < ReadLength; Index++) {
+    Data = *((volatile UINT32 *) (UINTN)(Addr));
+    Data |= B_I2C_REG_DATA_CMD_RW;
+    // Issue a STOP for last read transfer.
+    if (Index == (ReadLength-1)) {
+      Data |= B_I2C_REG_DATA_CMD_STOP;
+    }
+    *((volatile UINT32 *) (UINTN)(Addr)) = Data;
+  }
+
+  //
+  // Wait for STOP condition.
+  //
+  Status = WaitForStopDet ();
+  if (!EFI_ERROR(Status)) {
+
+    //
+    // Poll Receive FIFO Buffer Level register until valid (upto MAX_T_POLL_COUNT times).
+    //
+    Data = 0;
+    PollCount = 0;
+    Addr = I2CIoPortBaseAddress + I2C_REG_RXFLR;
+    Data = *((volatile UINT32 *) (UINTN)(Addr));
+    while ((Data != ReadLength) && (PollCount < MAX_T_POLL_COUNT)) {
+      MicroSecondDelay(TI2C_POLL);
+      PollCount++;
+      Data = *((volatile UINT32 *) (UINTN)(Addr));
+    }
+
+    Addr = I2CIoPortBaseAddress + I2C_REG_RAW_INTR_STAT;
+    Data = *((volatile UINT32 *) (UINTN)(Addr));
+
+    //
+    // If no timeout or device error then read rx data.
+    //
+    if (PollCount == MAX_T_POLL_COUNT) {
+      Status = EFI_TIMEOUT;
+    } else if ((Data & I2C_REG_RAW_INTR_STAT_RX_OVER) != 0) {
+      Status = EFI_DEVICE_ERROR;
+    } else {
+
+      //
+      // Clear RX underflow before reading IC_DATA_CMD.
+      //
+      Addr = I2CIoPortBaseAddress + I2C_REG_CLR_RX_UNDER;
+      Data = *((volatile UINT32 *) (UINTN)(Addr));
+
+      //
+      // Read data.
+      //
+      Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD;
+      for (Index = 0; Index < ReadLength; Index++) {
+        Data = *((volatile UINT32 *) (UINTN)(Addr));
+        Data &= 0x000000FF;
+        *(Buffer+Index) = (UINT8)Data;
+      }
+      Addr = I2CIoPortBaseAddress + I2C_REG_RAW_INTR_STAT;
+      Data = *((volatile UINT32 *) (UINTN)(Addr));
+      Data &= I2C_REG_RAW_INTR_STAT_RX_UNDER;
+      if (Data != 0) {
+        Status = EFI_DEVICE_ERROR;
+      } else {
+        Status = EFI_SUCCESS;
+      }
+    }
+  }
+
+  //
+  // Ensure I2C Controller disabled.
+  //
+  DisableI2CController ();
+
+  return Status;
+}
+
+/**
+
+  The I2cWriteByte() function is a wrapper function for the WriteByte function.
+  Provides a standard way to execute a standard single byte write to an IC2 device
+  (without accessing sub-addresses), as defined in the I2C Specification.
+
+  @param SlaveAddress The I2C slave address of the device
+                      with which to communicate.
+
+  @param AddrMode     I2C Addressing Mode: 7-bit or 10-bit address.
+
+  @param Buffer       Contains the value of byte data to execute to the
+                      I2C slave device.
+
+
+  @retval EFI_SUCCESS           Transfer success.
+  @retval EFI_INVALID_PARAMETER  This or Buffer pointers are invalid.
+  @retval EFI_UNSUPPORTED       Unsupported input param.
+  @retval EFI_TIMEOUT           Timeout while waiting xfer.
+  @retval EFI_ABORTED           Controller aborted xfer.
+  @retval EFI_DEVICE_ERROR      Device error detected by controller.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cWriteByte (
+  IN        EFI_I2C_DEVICE_ADDRESS  SlaveAddress,
+  IN        EFI_I2C_ADDR_MODE       AddrMode,
+  IN OUT VOID                       *Buffer
+  )
+{
+  EFI_STATUS Status;
+  UINTN      I2CAddress;
+  UINT16            SaveCmd;
+  UINT32            SaveBar0;
+
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  SaveCmd = 0;
+  SaveBar0 = 0;
+
+  I2cCommonServiceEntry (&SaveCmd, &SaveBar0);
+
+  Status = EFI_SUCCESS;
+
+  I2CAddress = SlaveAddress.I2CDeviceAddress;
+  Status = InitializeInternal (AddrMode);
+  if (!EFI_ERROR(Status)) {
+    Status = WriteByte (I2CAddress, *(UINT8 *) Buffer);
+  }
+
+  I2cCommonServiceExit (SaveCmd, SaveBar0);
+  return Status;
+}
+
+/**
+
+  The I2cReadByte() function is a wrapper function for the ReadByte function.
+  Provides a standard way to execute a standard single byte read to an I2C device
+  (without accessing sub-addresses), as defined in the I2C Specification.
+
+  @param SlaveAddress The I2C slave address of the device
+                      with which to communicate.
+
+  @param AddrMode     I2C Addressing Mode: 7-bit or 10-bit address.
+
+  @param Buffer       Contains the value of byte data read from the
+                      I2C slave device.
+
+
+  @retval EFI_SUCCESS           Transfer success.
+  @retval EFI_INVALID_PARAMETER This or Buffer pointers are invalid.
+  @retval EFI_TIMEOUT           Timeout while waiting xfer.
+  @retval EFI_ABORTED           Controller aborted xfer.
+  @retval EFI_DEVICE_ERROR      Device error detected by controller.
+
+
+**/
+EFI_STATUS
+EFIAPI
+I2cReadByte (
+  IN        EFI_I2C_DEVICE_ADDRESS  SlaveAddress,
+  IN        EFI_I2C_ADDR_MODE       AddrMode,
+  IN OUT    VOID                    *Buffer
+  )
+{
+  EFI_STATUS Status;
+  UINTN      I2CAddress;
+  UINT16     SaveCmd;
+  UINT32     SaveBar0;
+
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  SaveCmd = 0;
+  SaveBar0 =0;
+
+  I2cCommonServiceEntry (&SaveCmd, &SaveBar0);
+
+  Status = EFI_SUCCESS;
+
+  I2CAddress = SlaveAddress.I2CDeviceAddress;
+
+  Status = InitializeInternal (AddrMode);
+  if (!EFI_ERROR(Status)) {
+    Status = ReadByte (I2CAddress, (UINT8 *) Buffer);
+  }
+  I2cCommonServiceExit (SaveCmd, SaveBar0);
+  return Status;
+}
+
+/**
+
+  The I2cWriteMultipleByte() function is a wrapper function for the
+  WriteMultipleByte() function. Provides a standard way to execute multiple
+  byte writes to an I2C device (e.g. when accessing sub-addresses or writing
+  block of data), as defined in the I2C Specification.
+
+  @param SlaveAddress The I2C slave address of the device
+                      with which to communicate.
+
+  @param AddrMode     I2C Addressing Mode: 7-bit or 10-bit address.
+
+  @param Length       No. of bytes to be written.
+
+  @param Buffer       Contains the value of byte to be written to the
+                      I2C slave device.
+
+  @retval EFI_SUCCESS            Transfer success.
+  @retval EFI_INVALID_PARAMETER  This, Length or Buffer pointers are invalid.
+  @retval EFI_UNSUPPORTED        Unsupported input param.
+  @retval EFI_TIMEOUT            Timeout while waiting xfer.
+  @retval EFI_ABORTED            Controller aborted xfer.
+  @retval EFI_DEVICE_ERROR       Device error detected by controller.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cWriteMultipleByte (
+  IN        EFI_I2C_DEVICE_ADDRESS  SlaveAddress,
+  IN        EFI_I2C_ADDR_MODE       AddrMode,
+  IN UINTN                          *Length,
+  IN OUT    VOID                    *Buffer
+  )
+{
+  EFI_STATUS Status;
+  UINTN      I2CAddress;
+  UINT16     SaveCmd;
+  UINT32     SaveBar0;
+
+    if (Buffer == NULL || Length == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  SaveCmd = 0;
+  SaveBar0 =0;
+
+  I2cCommonServiceEntry (&SaveCmd, &SaveBar0);
+  Status = EFI_SUCCESS;
+
+  I2CAddress = SlaveAddress.I2CDeviceAddress;
+
+  Status = InitializeInternal (AddrMode);
+  if (!EFI_ERROR(Status)) {
+    Status = WriteMultipleByte (I2CAddress, Buffer, (*Length));
+  }
+
+  I2cCommonServiceExit (SaveCmd, SaveBar0);
+  return Status;
+}
+
+/**
+
+  The I2cReadMultipleByte() function is a wrapper function for the ReadMultipleByte() function.
+  Provides a standard way to execute multiple byte writes to an I2C device
+  (e.g. when accessing sub-addresses or when reading block of data), as defined
+  in the I2C Specification (I2C combined write/read protocol).
+
+  @param SlaveAddress The I2C slave address of the device
+                      with which to communicate.
+
+  @param AddrMode     I2C Addressing Mode: 7-bit or 10-bit address.
+
+  @param WriteLength  No. of bytes to be written. In this case data
+                      written typically contains sub-address or sub-addresses
+                      in Hi-Lo format, that need to be read (I2C combined
+                      write/read protocol).
+
+  @param ReadLength   No. of bytes to be read from I2C slave device.
+
+  @param Buffer       Contains the value of byte data read from the
+                      I2C slave device.
+
+  @retval EFI_SUCCESS            Transfer success.
+  @retval EFI_INVALID_PARAMETER  This, WriteLength, ReadLength or Buffer
+                                 pointers are invalid.
+  @retval EFI_UNSUPPORTED        Unsupported input param.
+  @retval EFI_TIMEOUT            Timeout while waiting xfer.
+  @retval EFI_ABORTED            Controller aborted xfer.
+  @retval EFI_DEVICE_ERROR       Device error detected by controller.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cReadMultipleByte (
+  IN        EFI_I2C_DEVICE_ADDRESS  SlaveAddress,
+  IN        EFI_I2C_ADDR_MODE       AddrMode,
+  IN UINTN                          *WriteLength,
+  IN UINTN                          *ReadLength,
+  IN OUT    VOID                    *Buffer
+  )
+{
+  EFI_STATUS        Status;
+  UINTN             I2CAddress;
+  UINT16            SaveCmd;
+  UINT32            SaveBar0;
+
+  if (Buffer == NULL || WriteLength == NULL || ReadLength == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  SaveCmd = 0;
+  SaveBar0 =0;
+
+  I2cCommonServiceEntry (&SaveCmd, &SaveBar0);
+
+  Status = EFI_SUCCESS;
+
+  I2CAddress = SlaveAddress.I2CDeviceAddress;
+  Status = InitializeInternal (AddrMode);
+  if (!EFI_ERROR(Status)) {
+    Status = ReadMultipleByte (I2CAddress, Buffer, (*WriteLength), (*ReadLength));
+  }
+  I2cCommonServiceExit (SaveCmd, SaveBar0);
+  return Status;
+}
+
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/I2cLib.inf b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/I2cLib.inf
new file mode 100644
index 0000000000..243582fcae
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/I2cLib.inf
@@ -0,0 +1,62 @@
+## @file
+# Component description file for Quark South Cluster I2C library.
+#
+# I2C library implement QuarkSCSocId related drivers, includes:
+# PciHostBridge, PciExpress, SmmAccess driver and LegacyRegion driver.
+#
+# This driver contains I2C bus access routines:
+# 1. I2C Read (byte, multi-byte)
+# 2. I2C Write (byte, multi-byte)
+#
+# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = I2cLib
+  FILE_GUID                      = 462d127a-c143-469e-8449-b6e36beb04a8
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = I2cLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  CommonHeader.h
+  I2cLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  PciLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  DebugLib
+  BaseLib
+  TimerLib
+  IoLib
+  IohLib
+
+[FeaturePcd]
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdI2CFastModeEnabled
+
+[FixedPcd]
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohI2cMmioBase
+
+[Pcd]
+
+[Depex]
+  TRUE
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/CommonHeader.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/CommonHeader.h
new file mode 100644
index 0000000000..bcb7f593a6
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/CommonHeader.h
@@ -0,0 +1,29 @@
+/** @file
+Common header file shared by all source files.
+
+This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+#include <PiPei.h>
+#include <Ioh.h>
+#include <IohCommonDefinitions.h>
+
+#include <Library/IohLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/CpuLib.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <IndustryStandard/Pci22.h>
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/IohLib.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/IohLib.c
new file mode 100644
index 0000000000..9e7e6b7c35
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/IohLib.c
@@ -0,0 +1,99 @@
+/** @file
+Lib function for Pei Quark South Cluster.
+
+Copyright (c) 2013-2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "CommonHeader.h"
+
+/**
+  Program SVID/SID the same as VID/DID*
+**/
+EFI_STATUS
+EFIAPI
+InitializeIohSsvidSsid (
+   IN UINT8   Bus,
+   IN UINT8   Device,
+   IN UINT8   Func
+   )
+{
+  UINTN       Index;
+
+  for (Index = 0; Index <= IOH_PCI_IOSF2AHB_0_MAX_FUNCS; Index++) {
+    if (((Device == IOH_PCI_IOSF2AHB_1_DEV_NUM) && (Index >= IOH_PCI_IOSF2AHB_1_MAX_FUNCS))) {
+      continue;
+    }
+
+    IohMmPci32(0, Bus, Device, Index, PCI_REG_SVID0) = IohMmPci32(0, Bus, Device, Index, PCI_REG_VID);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/* Enable memory, io, and bus master for USB controller */
+VOID
+EFIAPI
+EnableUsbMemIoBusMaster (
+  IN UINT8   UsbBusNumber
+  )
+{
+  UINT16 CmdReg;
+
+  CmdReg = PciRead16 (PCI_LIB_ADDRESS (UsbBusNumber, IOH_USB_OHCI_DEVICE_NUMBER, IOH_OHCI_FUNCTION_NUMBER, PCI_REG_PCICMD));
+  CmdReg = (UINT16) (CmdReg | EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND_BUS_MASTER);
+  PciWrite16 (PCI_LIB_ADDRESS (UsbBusNumber, IOH_USB_OHCI_DEVICE_NUMBER, IOH_OHCI_FUNCTION_NUMBER, PCI_REG_PCICMD), CmdReg);
+
+  CmdReg = PciRead16 (PCI_LIB_ADDRESS (UsbBusNumber, IOH_USB_EHCI_DEVICE_NUMBER, IOH_EHCI_FUNCTION_NUMBER, PCI_REG_PCICMD));
+  CmdReg = (UINT16) (CmdReg | EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND_BUS_MASTER);
+  PciWrite16 (PCI_LIB_ADDRESS (UsbBusNumber, IOH_USB_EHCI_DEVICE_NUMBER, IOH_EHCI_FUNCTION_NUMBER, PCI_REG_PCICMD), CmdReg);
+}
+
+/**
+  Read south cluster GPIO input from Port A.
+
+**/
+UINT32
+EFIAPI
+ReadIohGpioValues (
+  VOID
+  )
+{
+  UINT32  GipData;
+  UINT32  GipAddr;
+  UINT32  TempBarAddr;
+  UINT16  SaveCmdReg;
+  UINT32  SaveBarReg;
+
+  TempBarAddr = (UINT32) PcdGet64(PcdIohGpioMmioBase);
+
+  GipAddr = PCI_LIB_ADDRESS(
+      PcdGet8 (PcdIohGpioBusNumber),
+      PcdGet8 (PcdIohGpioDevNumber),
+      PcdGet8 (PcdIohGpioFunctionNumber), 0);
+
+  //
+  // Save current settings for PCI CMD/BAR registers.
+  //
+  SaveCmdReg = PciRead16 (GipAddr + PCI_COMMAND_OFFSET);
+  SaveBarReg = PciRead32 (GipAddr + PcdGet8 (PcdIohGpioBarRegister));
+
+  DEBUG ((EFI_D_INFO, "SC GPIO temporary enable  at %08X\n", TempBarAddr));
+
+  // Use predefined temporary memory resource.
+  PciWrite32 ( GipAddr + PcdGet8 (PcdIohGpioBarRegister), TempBarAddr);
+  PciWrite8 ( GipAddr + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
+
+  // Read GPIO configuration
+  GipData = MmioRead32(TempBarAddr + GPIO_EXT_PORTA);
+
+  //
+  // Restore settings for PCI CMD/BAR registers.
+  //
+  PciWrite32 ((GipAddr + PcdGet8 (PcdIohGpioBarRegister)), SaveBarReg);
+  PciWrite16 (GipAddr + PCI_COMMAND_OFFSET, SaveCmdReg);
+
+  // Only 8 bits valid.
+  return GipData & 0x000000FF;
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/IohLib.inf b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/IohLib.inf
new file mode 100644
index 0000000000..0fc506ba1e
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/IohLib.inf
@@ -0,0 +1,49 @@
+## @file
+# Intel Soc Library Instance
+#
+# Intel Soc Library Instance
+#
+# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = IohLib
+  FILE_GUID                      = B4C12297-7B19-4523-B165-81374D96716B
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = IohLib
+
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  IohLib.c
+  CommonHeader.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  PciLib
+  IoLib
+  PciCf8Lib
+  BaseLib
+  CpuLib
+
+[Pcd]
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioBusNumber
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioBusNumber
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioDevNumber
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioFunctionNumber
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioBarRegister
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioMmioBase
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/ComponentName.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/ComponentName.c
new file mode 100644
index 0000000000..85db4cd104
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/ComponentName.c
@@ -0,0 +1,227 @@
+/** @file
+
+UEFI Component Name(2) protocol implementation for SD controller driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SDController.h"
+
+
+//
+// EFI Component Name Protocol
+//
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gSDControllerName = {
+  SDControllerGetDriverName,
+  SDControllerGetControllerName,
+  "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gSDControllerName2 = {
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) SDControllerGetDriverName,
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) SDControllerGetControllerName,
+  "en"
+};
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mSDControllerDriverNameTable[] = {
+  { "eng;en", L"EFI SD Host Controller Driver" },
+  { NULL, NULL }
+};
+
+
+//
+// EFI Component Name Functions
+//
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 3066 or ISO 639-2 language code format.
+
+  @param  DriverName[out]       A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+SDControllerGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **DriverName
+  )
+{
+  return LookupUnicodeString2 (
+           Language,
+           This->SupportedLanguages,
+           mSDControllerDriverNameTable,
+           DriverName,
+           (BOOLEAN)(This == &gSDControllerName)
+           );
+}
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  ControllerHandle[in]  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+
+  @param  ChildHandle[in]       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 3066 or ISO 639-2 language code format.
+
+  @param  ControllerName[out]   A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                controller specified by ControllerHandle and
+                                ChildHandle in the language specified by
+                                Language from the point of view of the driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+SDControllerGetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
+  IN  EFI_HANDLE                                      ControllerHandle,
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
+  IN  CHAR8                                           *Language,
+  OUT CHAR16                                          **ControllerName
+  )
+{
+  EFI_STATUS           Status;
+  EFI_SD_HOST_IO_PROTOCOL  *SDHostIo;
+  SDHOST_DATA              *SDHostData;
+
+  //
+  // This is a device driver, so ChildHandle must be NULL.
+  //
+  if (ChildHandle != NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Make sure this driver is currently managing ControllerHandle
+  //
+  Status = EfiTestManagedDevice (
+             ControllerHandle,
+             gSDControllerDriverBinding.DriverBindingHandle,
+             &gEfiPciIoProtocolGuid
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Get the device context
+  //
+  Status = gBS->OpenProtocol (
+                  ControllerHandle,
+                  &gEfiSDHostIoProtocolGuid,
+                  (VOID **) &SDHostIo,
+                  gSDControllerDriverBinding.DriverBindingHandle,
+                  ControllerHandle,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  SDHostData  = SDHOST_DATA_FROM_THIS(SDHostIo);
+
+  return LookupUnicodeString2 (
+           Language,
+           This->SupportedLanguages,
+           SDHostData->ControllerNameTable,
+           ControllerName,
+           (BOOLEAN)(This == &gSDControllerName)
+           );
+
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/ComponentName.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/ComponentName.h
new file mode 100644
index 0000000000..91cc4725ec
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/ComponentName.h
@@ -0,0 +1,141 @@
+/** @file
+
+This file contains the delarations for componet name routines.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#ifndef _COMPONENT_NAME_H_
+#define _COMPONENT_NAME_H_
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 3066 or ISO 639-2 language code format.
+
+  @param  DriverName[out]       A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+SDControllerGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **DriverName
+  );
+
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  ControllerHandle[in]  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+
+  @param  ChildHandle[in]       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 3066 or ISO 639-2 language code format.
+
+  @param  ControllerName[out]   A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                controller specified by ControllerHandle and
+                                ChildHandle in the language specified by
+                                Language from the point of view of the driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+SDControllerGetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
+  IN  EFI_HANDLE                                      ControllerHandle,
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
+  IN  CHAR8                                           *Language,
+  OUT CHAR16                                          **ControllerName
+  );
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SDController.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SDController.c
new file mode 100644
index 0000000000..7d97b90b92
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SDController.c
@@ -0,0 +1,1784 @@
+/** @file
+
+The SD host controller driver model and HC protocol routines.
+
+Copyright (c) 2013-2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+
+#include "SDController.h"
+
+
+EFI_DRIVER_BINDING_PROTOCOL gSDControllerDriverBinding = {
+  SDControllerSupported,
+  SDControllerStart,
+  SDControllerStop,
+  0x20,
+  NULL,
+  NULL
+};
+
+
+EFI_SD_HOST_IO_PROTOCOL  mSDHostIo = {
+  EFI_SD_HOST_IO_PROTOCOL_REVISION_01,
+  {
+    0, // HighSpeedSupport
+    0, // V18Support
+    0, // V30Support
+    0, // V33Support
+    0, // Reserved0
+    0, // BusWidth4
+    0, // BusWidth8
+    0, // Reserved1
+    0, // Reserved1
+    (512 * 1024) //BoundarySize
+  },
+  SendCommand,
+  SetClockFrequency,
+  SetBusWidth,
+  SetHostVoltage,
+  ResetSDHost,
+  EnableAutoStopCmd,
+  DetectCardAndInitHost,
+  SetBlockLength,
+  SetHighSpeedMode,
+  SetDDRMode
+};
+
+/**
+  Find sdclk_freq_sel and upr_sdclk_freq_sel bits
+  for Clock Control Register (CLK_CTL)Offset 2Ch when using 8bit or 10bit
+  divided clock mode.
+
+  @param  BaseClockFreg        Base Clock Frequency in Hz For SD Clock in the
+                               Capabilities register.
+  @param  TargetFreq           Target Frequency in Hz to reach.
+  @param  Is8BitMode           True if 8-bit Divided Clock Mode else 10bit mode.
+  @param  Bits                 sdclk_freq_sel and upr_sdclk_freq_sel bits for
+                               TargetFreq.
+
+  @return EFI_SUCCESS          // Bits setup.
+  @return EFI_UNSUPPORTED      // Cannot divide base clock to reach target clock.
+**/
+EFI_STATUS
+DividedClockModeBits (
+  IN CONST UINTN                          BaseClockFreg,
+  IN CONST UINTN                          TargetFreq,
+  IN CONST BOOLEAN                        Is8BitMode,
+  OUT UINT16                              *Bits
+  )
+{
+  UINTN                             N;
+  UINTN                             CurrFreq;
+
+ *Bits = 0;
+  CurrFreq = BaseClockFreg;
+  N = 0;
+  //
+  // N == 0 same for 8bit & 10bit mode i.e. BaseClockFreg of controller.
+  //
+  if (TargetFreq < CurrFreq) {
+    if (Is8BitMode) {
+      N = 1;
+      do {
+        //
+        // N values for 8bit mode when N > 0.
+        //  Bit[15:8] SDCLK Frequency Select at offset 2Ch
+        //    80h - base clock divided by 256
+        //    40h - base clock divided by 128
+        //    20h - base clock divided by 64
+        //    10h - base clock divided by 32
+        //    08h - base clock divided by 16
+        //    04h - base clock divided by 8
+        //    02h - base clock divided by 4
+        //    01h - base clock divided by 2
+        //
+        CurrFreq = BaseClockFreg / (2 * N);
+        if (TargetFreq >= CurrFreq) {
+          break;
+        }
+        N *= 2;
+        if (N > V_MMIO_CLKCTL_MAX_8BIT_FREQ_SEL) {
+          return EFI_UNSUPPORTED;
+        }
+      } while (TRUE);
+    } else {
+      N = 1;
+      CurrFreq = BaseClockFreg / (2 * N);
+      //
+      // (try N = 0 or 1 first since don't want divide by 0).
+      //
+      if (TargetFreq < CurrFreq) {
+        //
+        // If still no match then calculate it for 10bit.
+        // N values for 10bit mode.
+        // N 1/2N Divided Clock (Duty 50%).
+        // from Spec "The length of divider is extended to 10 bits and all
+        // divider values shall be supported.
+        //
+        N = (BaseClockFreg / TargetFreq) / 2;
+
+        //
+        // Can only be N or N+1;
+        //
+        CurrFreq = BaseClockFreg / (2 * N);
+        if (TargetFreq < CurrFreq) {
+          N++;
+          CurrFreq = BaseClockFreg / (2 * N);
+        }
+
+        if (N > V_MMIO_CLKCTL_MAX_10BIT_FREQ_SEL) {
+          return EFI_UNSUPPORTED;
+        }
+
+        //
+        // Set upper bits of SDCLK Frequency Select (bits 7:6 of reg 0x2c).
+        //
+        *Bits |= ((UINT16) ((N >> 2) & B_MMIO_CLKCTL_UPR_SDCLK_FREQ_SEL_MASK));
+      }
+    }
+  }
+
+  //
+  // Set lower bits of SDCLK Frequency Select (bits 15:8 of reg 0x2c).
+  //
+  *Bits |= ((UINT16) ((UINT8) N) << 8);
+  DEBUG (
+    (EFI_D_INFO,
+    "SDIO:DividedClockModeBits: %dbit mode Want %dHz Got %dHz bits = %04x\r\n",
+    (Is8BitMode) ? 8 : 10,
+    TargetFreq,
+    CurrFreq,
+    (UINTN) *Bits
+     ));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Print type of error and command index
+
+  @param  CommandIndex         Command index to set the command index field of command register.
+  @param  ErrorCode            Error interrupt status read from host controller
+
+  @return EFI_DEVICE_ERROR
+  @return EFI_TIMEOUT
+  @return EFI_CRC_ERROR
+
+**/
+EFI_STATUS
+GetErrorReason (
+  IN  UINT16    CommandIndex,
+  IN  UINT16    ErrorCode
+  )
+{
+  EFI_STATUS    Status;
+
+  Status = EFI_DEVICE_ERROR;
+
+  DEBUG((EFI_D_ERROR, "[%2d] -- ", CommandIndex));
+
+  if (ErrorCode & BIT0) {
+    Status = EFI_TIMEOUT;
+    DEBUG((EFI_D_ERROR, "Command Timeout Erro"));
+  }
+
+  if (ErrorCode & BIT1) {
+    Status = EFI_CRC_ERROR;
+    DEBUG((EFI_D_ERROR, "Command CRC Error"));
+  }
+
+  if (ErrorCode & BIT2) {
+    DEBUG((EFI_D_ERROR, "Command End Bit Error"));
+  }
+
+  if (ErrorCode & BIT3) {
+    DEBUG((EFI_D_ERROR, "Command Index Error"));
+  }
+  if (ErrorCode & BIT4) {
+    Status = EFI_TIMEOUT;
+    DEBUG((EFI_D_ERROR, "Data Timeout Error"));
+  }
+
+  if (ErrorCode & BIT5) {
+    Status = EFI_CRC_ERROR;
+    DEBUG((EFI_D_ERROR, "Data CRC Error"));
+  }
+
+  if (ErrorCode & BIT6) {
+    DEBUG((EFI_D_ERROR, "Data End Bit Error"));
+  }
+
+  if (ErrorCode & BIT7) {
+    DEBUG((EFI_D_ERROR, "Current Limit Error"));
+  }
+
+  if (ErrorCode & BIT8) {
+    DEBUG((EFI_D_ERROR, "Auto CMD12 Error"));
+  }
+
+  if (ErrorCode & BIT9) {
+    DEBUG((EFI_D_ERROR, "ADMA Error"));
+  }
+
+  DEBUG((EFI_D_ERROR, "\n"));
+
+  return Status;
+}
+/**
+  Enable/Disable High Speed transfer mode
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  Enable                TRUE to Enable, FALSE to Disable
+
+  @return EFI_SUCCESS
+**/
+EFI_STATUS
+EFIAPI
+SetHighSpeedMode (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  BOOLEAN                    Enable
+  )
+{
+  UINT32                 Data;
+  SDHOST_DATA            *SDHostData;
+  EFI_PCI_IO_PROTOCOL    *PciIo;
+
+  SDHostData = SDHOST_DATA_FROM_THIS (This);
+  PciIo      = SDHostData->PciIo;
+
+  PciIo->Mem.Read (
+               PciIo,
+               EfiPciIoWidthUint8,
+               0,
+               (UINT64)MMIO_HOSTCTL,
+               1,
+               &Data
+               );
+
+  if (Enable) {
+    if (PcdGetBool(PcdSdHciQuirkNoHiSpd)) {
+      DEBUG ((EFI_D_INFO, "SDIO: Quirk never set High Speed Enable bit\r\n"));
+      return EFI_SUCCESS;
+    }
+    DEBUG ((EFI_D_INFO, "Enable High Speed transfer mode ... \r\n"));
+    Data |= BIT2;
+  } else {
+    Data &= ~BIT2;
+  }
+  PciIo->Mem.Write (
+               PciIo,
+               EfiPciIoWidthUint8,
+               0,
+              (UINT64)MMIO_HOSTCTL,
+               1,
+               &Data
+              );
+  return EFI_SUCCESS;
+}
+EFI_STATUS
+EFIAPI
+SetDDRMode (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  BOOLEAN                    Enable
+  )
+{
+  UINT16                 Data;
+  SDHOST_DATA            *SDHostData;
+  EFI_PCI_IO_PROTOCOL    *PciIo;
+  SDHostData = SDHOST_DATA_FROM_THIS (This);
+  PciIo      = SDHostData->PciIo;
+  PciIo->Mem.Read (
+               PciIo,
+               EfiPciIoWidthUint16,
+               0,
+               (UINT64)MMIO_HOSTCTL2,
+               1,
+               &Data
+               );
+  Data &= 0xFFF0;
+  if (Enable) {
+    Data |= 0x0004; // Enable DDR50 by default, later should enable other mode like HS200/400
+    Data |= BIT3;   // Enable 1.8V Signaling
+  }
+  PciIo->Mem.Write (
+               PciIo,
+               EfiPciIoWidthUint16,
+               0,
+              (UINT64)MMIO_HOSTCTL2,
+               1,
+               &Data
+              );
+  return EFI_SUCCESS;
+}
+/**
+  Power on/off the LED associated with the slot
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  Enable                TRUE to set LED on, FALSE to set LED off
+
+  @return EFI_SUCCESS
+**/
+EFI_STATUS
+HostLEDEnable (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  BOOLEAN                    Enable
+  )
+{
+  SDHOST_DATA            *SDHostData;
+  EFI_PCI_IO_PROTOCOL    *PciIo;
+  UINT32                 Data;
+
+  SDHostData = SDHOST_DATA_FROM_THIS (This);
+  PciIo      = SDHostData->PciIo;
+
+  PciIo->Mem.Read (
+               PciIo,
+               EfiPciIoWidthUint8,
+               0,
+               (UINT64)MMIO_HOSTCTL,
+               1,
+               &Data
+               );
+
+  if (Enable) {
+    //
+    //LED On
+    //
+    Data |= BIT0;
+  } else {
+    //
+    //LED Off
+    //
+    Data &= ~BIT0;
+  }
+
+  PciIo->Mem.Write (
+               PciIo,
+               EfiPciIoWidthUint8,
+               0,
+               (UINT64)MMIO_HOSTCTL,
+               1,
+               &Data
+               );
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  The main function used to send the command to the card inserted into the SD host slot.
+  It will assemble the arguments to set the command register and wait for the command
+  and transfer completed until timeout. Then it will read the response register to fill
+  the ResponseData.
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  CommandIndex          The command index to set the command index field of command register.
+  @param  Argument              Command argument to set the argument field of command register.
+  @param  DataType              TRANSFER_TYPE, indicates no data, data in or data out.
+  @param  Buffer                Contains the data read from / write to the device.
+  @param  BufferSize            The size of the buffer.
+  @param  ResponseType          RESPONSE_TYPE.
+  @param  TimeOut               Time out value in 1 ms unit.
+  @param  ResponseData          Depending on the ResponseType, such as CSD or card status.
+
+  @retval EFI_SUCCESS
+  @retval EFI_INVALID_PARAMETER
+  @retval EFI_OUT_OF_RESOURCES
+  @retval EFI_TIMEOUT
+  @retval EFI_DEVICE_ERROR
+
+**/
+
+EFI_STATUS
+EFIAPI
+SendCommand (
+  IN   EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN   UINT16                     CommandIndex,
+  IN   UINT32                     Argument,
+  IN   TRANSFER_TYPE              DataType,
+  IN   UINT8                      *Buffer, OPTIONAL
+  IN   UINT32                     BufferSize,
+  IN   RESPONSE_TYPE              ResponseType,
+  IN   UINT32                     TimeOut,
+  OUT  UINT32                     *ResponseData OPTIONAL
+  )
+/*++
+
+  Routine Description:
+    The main function used to send the command to the card inserted into the SD host
+    slot.
+    It will assemble the arguments to set the command register and wait for the command
+    and transfer completed until timeout. Then it will read the response register to fill
+    the ResponseData
+
+  Arguments:
+    This           - Pointer to EFI_SD_HOST_IO_PROTOCOL
+    CommandIndex   - The command index to set the command index field of command register
+    Argument       - Command argument to set the argument field of command register
+    DataType       - TRANSFER_TYPE, indicates no data, data in or data out
+    Buffer         - Contains the data read from / write to the device
+    BufferSize     - The size of the buffer
+    ResponseType   - RESPONSE_TYPE
+    TimeOut        - Time out value in 1 ms unit
+    ResponseData   - Depending on the ResponseType, such as CSD or card status
+
+  Returns:
+    EFI_SUCCESS
+    EFI_INVALID_PARAMETER
+    EFI_OUT_OF_RESOURCES
+    EFI_TIMEOUT
+    EFI_DEVICE_ERROR
+
+--*/
+{
+  EFI_STATUS            Status;
+  SDHOST_DATA           *SDHostData;
+  EFI_PCI_IO_PROTOCOL   *PciIo;
+  UINT32                ResponseDataCount;
+  UINT32                Data;
+  UINT64                Data64;
+  UINT8                 Index;
+  INTN                  TimeOut2;
+  BOOLEAN               AutoCMD12Enable = FALSE;
+
+
+  Status             = EFI_SUCCESS;
+  ResponseDataCount  = 1;
+  SDHostData         = SDHOST_DATA_FROM_THIS (This);
+  PciIo              = SDHostData->PciIo;
+  AutoCMD12Enable    =  (CommandIndex & AUTO_CMD12_ENABLE) ? TRUE : FALSE;
+  CommandIndex       = CommandIndex & CMD_INDEX_MASK;
+
+  if (Buffer != NULL && DataType == NoData) {
+    Status = EFI_INVALID_PARAMETER;
+    DEBUG ((EFI_D_ERROR, "SendCommand: invalid parameter \r\n"));
+    goto Exit;
+  }
+
+  if (((UINTN)Buffer & (This->HostCapability.BoundarySize - 1)) != (UINTN)NULL) {
+    Status = EFI_INVALID_PARAMETER;
+    DEBUG ((EFI_D_ERROR, "SendCommand: invalid parameter \r\n"));
+    goto Exit;
+  }
+
+  DEBUG ((EFI_D_INFO, "SendCommand: Command Index = %d \r\n", CommandIndex));
+  //
+  TimeOut2 = 1000; // 10 ms
+  do {
+    PciIo->Mem.Read (
+                 PciIo,
+                 EfiPciIoWidthUint32,
+                 0,
+                 (UINT64)MMIO_PSTATE,
+                 1,
+                 &Data
+                 );
+     gBS->Stall (10);
+  }while ((TimeOut2-- > 0) && (Data & BIT0));
+  TimeOut2 = 1000; // 10 ms
+  do {
+    PciIo->Mem.Read (
+                 PciIo,
+                 EfiPciIoWidthUint32,
+                 0,
+                 (UINT64)MMIO_PSTATE,
+                 1,
+                 &Data
+                 );
+    gBS->Stall (10);
+  }while ((TimeOut2-- > 0) && (Data & BIT1));
+  //Clear status bits
+  //
+  Data = 0xFFFF;
+  PciIo->Mem.Write (
+               PciIo,
+               EfiPciIoWidthUint16,
+               0,
+               (UINT64)MMIO_NINTSTS,
+               1,
+               &Data
+               );
+
+  Data = 0xFFFF;
+  PciIo->Mem.Write (
+               PciIo,
+               EfiPciIoWidthUint16,
+               0,
+               (UINT64)MMIO_ERINTSTS,
+               1,
+               &Data
+               );
+
+
+  if (Buffer != NULL) {
+     PciIo->Mem.Write (
+                  PciIo,
+                  EfiPciIoWidthUint32,
+                  0,
+                  (UINT64)MMIO_DMAADR,
+                  1,
+                  &Buffer
+                  );
+
+     PciIo->Mem.Read (
+                  PciIo,
+                  EfiPciIoWidthUint16,
+                  0,
+                  (UINT64)MMIO_BLKSZ,
+                  1,
+                  &Data
+                  );
+     Data &= ~(0xFFF);
+     if (BufferSize <= SDHostData->BlockLength) {
+       Data |= (BufferSize | 0x7000);
+     } else {
+       Data |= (SDHostData->BlockLength | 0x7000);
+     }
+
+
+     PciIo->Mem.Write (
+                  PciIo,
+                  EfiPciIoWidthUint16,
+                  0,
+                  (UINT64)MMIO_BLKSZ,
+                  1,
+                  &Data
+                  );
+     if (BufferSize <= SDHostData->BlockLength) {
+       Data = 1;
+     } else {
+       Data = BufferSize / SDHostData->BlockLength;
+     }
+     PciIo->Mem.Write (
+                  PciIo,
+                  EfiPciIoWidthUint16,
+                  0,
+                  (UINT64)MMIO_BLKCNT,
+                  1,
+                  &Data
+                  );
+
+  } else {
+    Data = 0;
+    PciIo->Mem.Write (
+                  PciIo,
+                  EfiPciIoWidthUint16,
+                  0,
+                  (UINT64)MMIO_BLKSZ,
+                  1,
+                  &Data
+                  );
+    PciIo->Mem.Write (
+                  PciIo,
+                  EfiPciIoWidthUint16,
+                  0,
+                  (UINT64)MMIO_BLKCNT,
+                  1,
+                  &Data
+                  );
+  }
+
+  //
+  //Argument
+  //
+  Data = Argument;
+  PciIo->Mem.Write (
+               PciIo,
+               EfiPciIoWidthUint32,
+               0,
+               (UINT64)MMIO_CMDARG,
+               1,
+               &Data
+               );
+
+
+  PciIo->Mem.Read (
+               PciIo,
+               EfiPciIoWidthUint16,
+               0,
+               (UINT64)MMIO_XFRMODE,
+               1,
+               &Data
+               );
+
+
+  DEBUG ((EFI_D_INFO, "Transfer mode read  = 0x%x \r\n", (Data & 0xFFFF)));
+  //
+  //BIT0 - DMA Enable
+  //BIT2 - Auto Cmd12
+  //
+  if (DataType == InData) {
+    Data |= BIT4 | BIT0;
+  } else if (DataType == OutData){
+    Data &= ~BIT4;
+    Data |= BIT0;
+  } else {
+    Data &= ~(BIT4 | BIT0);
+  }
+
+  if (BufferSize <= SDHostData->BlockLength) {
+    Data &= ~ (BIT5 | BIT1 | BIT2);
+    Data |= BIT1; // Enable block count always
+  } else {
+     if (SDHostData->IsAutoStopCmd && AutoCMD12Enable) {
+      Data |= (BIT5 | BIT1 | BIT2);
+     } else {
+      Data |= (BIT5 | BIT1);
+     }
+  }
+
+  DEBUG ((EFI_D_INFO, "Transfer mode write = 0x%x \r\n", (Data & 0xffff)));
+  PciIo->Mem.Write (
+               PciIo,
+               EfiPciIoWidthUint16,
+               0,
+               (UINT64)MMIO_XFRMODE,
+               1,
+               &Data
+               );
+  //
+  //Command
+  //
+  //ResponseTypeSelect    IndexCheck    CRCCheck    ResponseType
+  //  00                     0            0           NoResponse
+  //  01                     0            1           R2
+  //  10                     0            0           R3, R4
+  //  10                     1            1           R1, R5, R6, R7
+  //  11                     1            1           R1b, R5b
+  //
+  switch (ResponseType) {
+    case ResponseNo:
+      Data = (CommandIndex << 8);
+      ResponseDataCount = 0;
+      break;
+
+    case ResponseR1:
+    case ResponseR5:
+    case ResponseR6:
+    case ResponseR7:
+      Data = (CommandIndex << 8) | BIT1 | BIT4| BIT3;
+      ResponseDataCount = 1;
+      break;
+
+    case ResponseR1b:
+    case ResponseR5b:
+      Data = (CommandIndex << 8) | BIT0 | BIT1 | BIT4| BIT3;
+      ResponseDataCount = 1;
+      break;
+
+    case ResponseR2:
+      Data = (CommandIndex << 8) | BIT0 | BIT3;
+      ResponseDataCount = 4;
+      break;
+
+    case ResponseR3:
+    case ResponseR4:
+      Data = (CommandIndex << 8) | BIT1;
+      ResponseDataCount = 1;
+      break;
+
+    default:
+      ASSERT (0);
+      Status = EFI_INVALID_PARAMETER;
+      DEBUG ((EFI_D_ERROR, "SendCommand: invalid parameter \r\n"));
+      goto Exit;
+  }
+
+  if (DataType != NoData) {
+    Data |= BIT5;
+  }
+
+  HostLEDEnable (This, TRUE);
+
+
+  PciIo->Mem.Write (
+               PciIo,
+               EfiPciIoWidthUint16,
+               0,
+               (UINT64)MMIO_SDCMD,
+               1,
+               &Data
+               );
+
+
+  Data = 0;
+  do {
+    PciIo->Mem.Read (
+                 PciIo,
+                 EfiPciIoWidthUint16,
+                 0,
+                 (UINT64)MMIO_ERINTSTS,
+                 1,
+                 &Data
+                 );
+
+    if ((Data & 0x07FF) != 0) {
+      Status = GetErrorReason (CommandIndex, (UINT16)Data);
+      DEBUG ((EFI_D_ERROR, "SendCommand: Error happens \r\n"));
+      goto Exit;
+    }
+
+    PciIo->Mem.Read (
+                 PciIo,
+                 EfiPciIoWidthUint16,
+                 0,
+                 (UINT64)MMIO_NINTSTS,
+                 1,
+                 &Data
+                 );
+
+    if ((Data & BIT0) == BIT0) {
+       //
+       //Command completed, can read response
+       //
+       if (DataType == NoData) {
+         break;
+       } else {
+         //
+         //Transfer completed
+         //
+         if ((Data & BIT1) == BIT1) {
+           break;
+         }
+       }
+    }
+
+    gBS->Stall (1 * 1000);
+
+    TimeOut --;
+
+  } while (TimeOut > 0);
+
+  if (TimeOut == 0) {
+    Status = EFI_TIMEOUT;
+    DEBUG ((EFI_D_ERROR, "SendCommand: Time out \r\n"));
+    goto Exit;
+  }
+
+  if (ResponseData != NULL) {
+    PciIo->Mem.Read (
+                 PciIo,
+                 EfiPciIoWidthUint32,
+                 0,
+                 (UINT64)MMIO_RESP,
+                 ResponseDataCount,
+                 ResponseData
+                 );
+    if (ResponseType == ResponseR2) {
+      //
+      // Adjustment for R2 response
+      //
+      Data = 1;
+      for (Index = 0; Index < ResponseDataCount; Index++) {
+        Data64 = LShiftU64(*ResponseData, 8);
+        *ResponseData = (UINT32)((Data64 & 0xFFFFFFFF) | Data);
+        Data =  (UINT32)RShiftU64 (Data64, 32);
+        ResponseData++;
+      }
+    }
+  }
+
+Exit:
+  HostLEDEnable (This, FALSE);
+  return Status;
+}
+
+/**
+  Set max clock frequency of the host, the actual frequency may not be the same as MaxFrequency.
+  It depends on the max frequency the host can support, divider, and host speed mode.
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  MaxFrequency          Max frequency in HZ.
+
+  @retval EFI_SUCCESS
+  @retval EFI_TIMEOUT
+
+**/
+EFI_STATUS
+EFIAPI
+SetClockFrequency (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  UINT32                     MaxFrequency
+  )
+{
+  UINT32                 Data;
+  UINT16                 FreqSelBits;
+  EFI_STATUS             Status;
+  SDHOST_DATA            *SDHostData;
+  EFI_PCI_IO_PROTOCOL    *PciIo;
+  UINT32                 TimeOutCount;
+  UINT32                 Revision;
+
+  SDHostData = SDHOST_DATA_FROM_THIS (This);
+  PciIo      = SDHostData->PciIo;
+  Data = 0;
+  PciIo->Mem.Write (
+               PciIo,
+               EfiPciIoWidthUint16,
+               0,
+               (UINT64)MMIO_CLKCTL,
+               1,
+               &Data
+               );
+
+  PciIo->Mem.Read (
+                PciIo,
+                EfiPciIoWidthUint8,
+                0,
+                (UINT64)MMIO_CTRLRVER,
+                1,
+                &Revision
+                );
+  Revision &= 0x000000FF;
+
+  Status = DividedClockModeBits (
+             SDHostData->BaseClockInMHz * 1000 * 1000,
+             MaxFrequency,
+             (Revision < SDHCI_SPEC_300),
+             &FreqSelBits
+             );
+
+  if (EFI_ERROR (Status)) {
+    //
+    // Cannot reach MaxFrequency with SDHostData->BaseClockInMHz.
+    //
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  Data = 0;
+
+  //
+  //Enable internal clock and Stop Clock Enable
+  //
+  Data = BIT0;
+  PciIo->Mem.Write (
+               PciIo,
+               EfiPciIoWidthUint16,
+               0,
+               (UINT64)MMIO_CLKCTL,
+               1,
+               &Data
+               );
+
+  TimeOutCount = TIME_OUT_1S;
+  do {
+    PciIo->Mem.Read (
+                 PciIo,
+                 EfiPciIoWidthUint16,
+                 0,
+                 (UINT64)MMIO_CLKCTL,
+                 1,
+                 &Data
+                 );
+    gBS->Stall (1 * 1000);
+    TimeOutCount --;
+    if (TimeOutCount == 0) {
+      DEBUG ((EFI_D_ERROR, "SetClockFrequency: Time out \r\n"));
+      return EFI_TIMEOUT;
+    }
+  } while ((Data & BIT1) != BIT1);
+
+  DEBUG ((EFI_D_INFO, "Base Clock In MHz: %d\r\n", SDHostData->BaseClockInMHz));
+
+  Data = (BIT0 | ((UINT32) FreqSelBits));
+  DEBUG ((EFI_D_INFO, "Data write to MMIO_CLKCTL: 0x%04x \r\n", Data));
+  PciIo->Mem.Write (
+               PciIo,
+               EfiPciIoWidthUint16,
+               0,
+               (UINT64)MMIO_CLKCTL,
+               1,
+               &Data
+               );
+
+  TimeOutCount = TIME_OUT_1S;
+  do {
+    PciIo->Mem.Read (
+                 PciIo,
+                 EfiPciIoWidthUint16,
+                 0,
+                 (UINT64)MMIO_CLKCTL,
+                 1,
+                 &Data
+                 );
+    gBS->Stall (1 * 1000);
+    TimeOutCount --;
+    if (TimeOutCount == 0) {
+      DEBUG ((EFI_D_ERROR, "SetClockFrequency: Time out \r\n"));
+      return EFI_TIMEOUT;
+    }
+  } while ((Data & BIT1) != BIT1);
+  gBS->Stall (20 * 1000);
+  Data |= BIT2;
+  PciIo->Mem.Write (
+               PciIo,
+               EfiPciIoWidthUint16,
+               0,
+               (UINT64)MMIO_CLKCTL,
+               1,
+               &Data
+               );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Set bus width of the host controller
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  BusWidth              Bus width in 1, 4, 8 bits.
+
+  @retval EFI_SUCCESS
+  @retval EFI_INVALID_PARAMETER
+
+**/
+EFI_STATUS
+EFIAPI
+SetBusWidth (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  UINT32                     BusWidth
+  )
+{
+  SDHOST_DATA            *SDHostData;
+  EFI_PCI_IO_PROTOCOL    *PciIo;
+  UINT8                  Data;
+
+  SDHostData = SDHOST_DATA_FROM_THIS (This);
+
+
+  if ((BusWidth != 1) && (BusWidth != 4) && (BusWidth != 8)) {
+    DEBUG ((EFI_D_ERROR, "SetBusWidth: Invalid parameter \r\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((SDHostData->SDHostIo.HostCapability.BusWidth8 == FALSE) && (BusWidth == 8)) {
+     DEBUG ((EFI_D_ERROR, "SetBusWidth: Invalid parameter \r\n"));
+     return EFI_INVALID_PARAMETER;
+  }
+
+  PciIo      = SDHostData->PciIo;
+
+  PciIo->Mem.Read (
+               PciIo,
+               EfiPciIoWidthUint8,
+               0,
+               (UINT64)MMIO_HOSTCTL,
+               1,
+               &Data
+               );
+  //
+  // BIT5 8-bit MMC Support (MMC8):
+  // If set, IOH supports 8-bit MMC. When cleared, IOH does not support this feature
+  //
+  if (BusWidth == 8) {
+    DEBUG ((EFI_D_INFO, "Bus Width is 8-bit ... \r\n"));
+    Data |= BIT5;
+  } else if (BusWidth == 4) {
+    DEBUG ((EFI_D_INFO, "Bus Width is 4-bit ... \r\n"));
+    Data &= ~BIT5;
+    Data |= BIT1;
+  } else {
+    DEBUG ((EFI_D_INFO, "Bus Width is 1-bit ... \r\n"));
+    Data &= ~BIT5;
+    Data &= ~BIT1;
+  }
+
+  PciIo->Mem.Write (
+               PciIo,
+               EfiPciIoWidthUint8,
+               0,
+               (UINT64)MMIO_HOSTCTL,
+               1,
+               &Data
+               );
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Set voltage which could supported by the host controller.
+  Support 0(Power off the host), 1.8V, 3.0V, 3.3V
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  Voltage               Units in 0.1 V.
+
+  @retval EFI_SUCCESS
+  @retval EFI_INVALID_PARAMETER
+
+**/
+EFI_STATUS
+EFIAPI
+SetHostVoltage (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  UINT32                     Voltage
+  )
+{
+  SDHOST_DATA            *SDHostData;
+  EFI_PCI_IO_PROTOCOL    *PciIo;
+  UINT8                  Data;
+  EFI_STATUS             Status;
+
+  SDHostData = SDHOST_DATA_FROM_THIS (This);
+  PciIo      = SDHostData->PciIo;
+  Status     = EFI_SUCCESS;
+
+  PciIo->Mem.Read (
+               PciIo,
+               EfiPciIoWidthUint8,
+               0,
+               (UINT64)MMIO_PWRCTL,
+               1,
+               &Data
+               );
+
+  if (Voltage == 0) {
+    //
+    //Power Off the host
+    //
+    Data &= ~BIT0;
+  } else if (Voltage <= 18 && This->HostCapability.V18Support) {
+     //
+     //1.8V
+     //
+     Data |= (BIT1 | BIT3 | BIT0);
+  } else if (Voltage > 18 &&  Voltage <= 30 && This->HostCapability.V30Support) {
+     //
+     //3.0V
+     //
+     Data |= (BIT2 | BIT3 | BIT0);
+  } else if (Voltage > 30 && Voltage <= 33 && This->HostCapability.V33Support) {
+     //
+     //3.3V
+     //
+     Data |= (BIT1 | BIT2 | BIT3 | BIT0);
+  } else {
+     Status = EFI_UNSUPPORTED;
+     goto Exit;
+  }
+
+  PciIo->Mem.Write (
+               PciIo,
+               EfiPciIoWidthUint8,
+               0,
+               (UINT64)MMIO_PWRCTL,
+               1,
+               &Data
+               );
+  gBS->Stall (10 * 1000);
+
+Exit:
+  return Status;
+}
+
+
+
+/**
+  Reset the host controller.
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  ResetAll              TRUE to reset all.
+
+  @retval EFI_SUCCESS
+  @retval EFI_TIMEOUT
+
+**/
+EFI_STATUS
+EFIAPI
+ResetSDHost (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  RESET_TYPE                 ResetType
+  )
+{
+  SDHOST_DATA            *SDHostData;
+  EFI_PCI_IO_PROTOCOL    *PciIo;
+  UINT32                 Data;
+  UINT16                 ErrStatus;
+  UINT32                 Mask;
+  UINT32                 TimeOutCount;
+  UINT16                 SaveClkCtl;
+  UINT16                 ZeroClkCtl;
+
+  SDHostData = SDHOST_DATA_FROM_THIS (This);
+  PciIo      = SDHostData->PciIo;
+  Mask       = 0;
+  ErrStatus  = 0;
+
+  if (ResetType == Reset_Auto) {
+    PciIo->Mem.Read (
+                 PciIo,
+                 EfiPciIoWidthUint16,
+                 0,
+                 (UINT64)MMIO_ERINTSTS,
+                 1,
+                 &ErrStatus
+                 );
+    if ((ErrStatus & 0xF) != 0) {
+      //
+      //Command Line
+      //
+      Mask |= BIT1;
+    }
+    if ((ErrStatus & 0x70) != 0) {
+      //
+      //Data Line
+      //
+      Mask |= BIT2;
+    }
+  }
+
+
+  if (ResetType == Reset_DAT || ResetType == Reset_DAT_CMD) {
+    Mask |= BIT2;
+  }
+  if (ResetType == Reset_CMD || ResetType == Reset_DAT_CMD) {
+    Mask |= BIT1;
+  }
+  if (ResetType == Reset_All) {
+    Mask = BIT0;
+  }
+
+  if (Mask == 0) {
+    return EFI_SUCCESS;
+  }
+
+  //
+  // To improve SD stability, we zero the MMIO_CLKCTL register and
+  // stall for 50 microseconds before resetting the controller.  We
+  // restore the register setting following the reset operation.
+  //
+  PciIo->Mem.Read (
+               PciIo,
+               EfiPciIoWidthUint16,
+               0,
+               (UINT64)MMIO_CLKCTL,
+               1,
+               &SaveClkCtl
+               );
+
+  ZeroClkCtl = (UINT16) 0;
+  PciIo->Mem.Write (
+               PciIo,
+               EfiPciIoWidthUint16,
+               0,
+               (UINT64)MMIO_CLKCTL,
+               1,
+               &ZeroClkCtl
+               );
+
+  gBS->Stall (50);
+
+  //
+  // Reset the SD host controller
+  //
+  PciIo->Mem.Write (
+               PciIo,
+               EfiPciIoWidthUint8,
+               0,
+               (UINT64)MMIO_SWRST,
+               1,
+               &Mask
+               );
+
+  Data          = 0;
+  TimeOutCount  = TIME_OUT_1S;
+  do {
+
+    gBS->Stall (1 * 1000);
+
+    TimeOutCount --;
+
+    PciIo->Mem.Read (
+                 PciIo,
+                 EfiPciIoWidthUint8,
+                 0,
+                 (UINT64)MMIO_SWRST,
+                 1,
+                 &Data
+                 );
+    if ((Data & Mask) == 0) {
+      break;
+    }
+  } while (TimeOutCount > 0);
+
+  //
+  // We now restore the MMIO_CLKCTL register which we set to 0 above.
+  //
+  PciIo->Mem.Write (
+               PciIo,
+               EfiPciIoWidthUint16,
+               0,
+               (UINT64)MMIO_CLKCTL,
+               1,
+               &SaveClkCtl
+               );
+
+  if (TimeOutCount == 0) {
+    DEBUG ((EFI_D_ERROR, "ResetSDHost: Time out \r\n"));
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Enable auto stop on the host controller.
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  Enable                TRUE to enable, FALSE to disable.
+
+  @retval EFI_SUCCESS
+  @retval EFI_TIMEOUT
+
+**/
+EFI_STATUS
+EFIAPI
+EnableAutoStopCmd (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  BOOLEAN                    Enable
+  )
+{
+  SDHOST_DATA            *SDHostData;
+
+  SDHostData = SDHOST_DATA_FROM_THIS (This);
+
+  SDHostData->IsAutoStopCmd = Enable;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Set the Block length on the host controller.
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  BlockLength           card supportes block length.
+
+  @retval EFI_SUCCESS
+  @retval EFI_TIMEOUT
+
+**/
+EFI_STATUS
+EFIAPI
+SetBlockLength (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  UINT32                     BlockLength
+  )
+{
+  SDHOST_DATA            *SDHostData;
+
+  SDHostData = SDHOST_DATA_FROM_THIS (This);
+
+  DEBUG ((EFI_D_INFO, "Block length on the host controller: %d \r\n", BlockLength));
+  SDHostData->BlockLength = BlockLength;
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Find whether these is a card inserted into the slot. If so init the host.
+  If not, return EFI_NOT_FOUND.
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+
+  @retval EFI_SUCCESS
+  @retval EFI_NOT_FOUND
+
+**/
+EFI_STATUS
+EFIAPI
+DetectCardAndInitHost (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This
+  )
+{
+  SDHOST_DATA            *SDHostData;
+  EFI_PCI_IO_PROTOCOL    *PciIo;
+  UINT32                 Data;
+  EFI_STATUS             Status;
+  UINT8                  Voltages[] = { 33, 30, 18 };
+  UINTN                  Loop;
+
+  SDHostData = SDHOST_DATA_FROM_THIS (This);
+  PciIo      = SDHostData->PciIo;
+  Status     = EFI_NOT_FOUND;
+
+  Data = 0;
+  PciIo->Mem.Read (
+               PciIo,
+               EfiPciIoWidthUint32,
+               0,
+               (UINT64)MMIO_PSTATE,
+               1,
+               &Data
+               );
+
+  if ((Data & (BIT16 | BIT17 | BIT18)) != (BIT16 | BIT17 | BIT18)) {
+    //
+    // Has no card inserted
+    //
+    DEBUG ((EFI_D_INFO, "DetectCardAndInitHost: No Cards \r\n"));
+    Status =  EFI_NOT_FOUND;
+    goto Exit;
+  }
+  DEBUG ((EFI_D_INFO, "DetectCardAndInitHost: Find Cards \r\n"));
+
+  Status =  EFI_NOT_FOUND;
+  for (Loop = 0; Loop < sizeof (Voltages); Loop++) {
+    DEBUG ((
+      EFI_D_INFO,
+      "DetectCardAndInitHost: SetHostVoltage %d.%dV \r\n",
+      Voltages[Loop] / 10,
+      Voltages[Loop] % 10
+      ));
+    Status = SetHostVoltage (This, Voltages[Loop]);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((EFI_D_INFO, "DetectCardAndInitHost set voltages: [failed]\n"));
+    } else {
+      DEBUG ((EFI_D_INFO, "DetectCardAndInitHost set voltages: [success]\n"));
+      break;
+    }
+  }
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "DetectCardAndInitHost: Fail to set voltage \r\n"));
+    goto Exit;
+  }
+
+  Status = SetClockFrequency (This, FREQUENCY_OD);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "DetectCardAndInitHost: Fail to set frequency \r\n"));
+    goto Exit;
+  }
+  SetBusWidth (This, 1);
+
+  //
+  //Enable normal status change
+  //
+
+  Data = (BIT0 | BIT1);
+
+  PciIo->Mem.Write (
+               PciIo,
+               EfiPciIoWidthUint16,
+               0,
+               (UINT64)MMIO_NINTEN,
+               1,
+               &Data
+               );
+
+  //
+  //Enable error status change
+  //
+  PciIo->Mem.Read (
+               PciIo,
+               EfiPciIoWidthUint16,
+               0,
+               (UINT64)MMIO_ERINTEN,
+               1,
+               &Data
+               );
+
+  Data |= (BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6 | BIT7 | BIT8);
+
+  PciIo->Mem.Write (
+               PciIo,
+               EfiPciIoWidthUint16,
+               0,
+               (UINT64)MMIO_ERINTEN,
+               1,
+               &Data
+               );
+
+  //
+  //Data transfer Timeout control
+  //
+  Data = 0x0E;
+
+  PciIo->Mem.Write (
+               PciIo,
+               EfiPciIoWidthUint8,
+               0,
+               (UINT64)MMIO_TOCTL,
+               1,
+               &Data
+               );
+  //
+  //Set Default Bus width as 1 bit
+  //
+
+Exit:
+  return Status;
+
+}
+
+/**
+  Entry point for EFI drivers.
+
+  @param  ImageHandle      EFI_HANDLE.
+  @param  SystemTable      EFI_SYSTEM_TABLE.
+
+  @retval EFI_SUCCESS      Driver is successfully loaded.
+  @return Others           Failed.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeSDController (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+  return EfiLibInstallDriverBindingComponentName2 (
+           ImageHandle,
+           SystemTable,
+           &gSDControllerDriverBinding,
+           ImageHandle,
+           &gSDControllerName,
+           &gSDControllerName2
+           );
+}
+
+
+/**
+  Test to see if this driver supports ControllerHandle. Any
+  ControllerHandle that has SDHostIoProtocol installed will be supported.
+
+  @param  This                 Protocol instance pointer.
+  @param  Controller           Handle of device to test.
+  @param  RemainingDevicePath  Not used.
+
+  @return EFI_SUCCESS          This driver supports this device.
+  @return EFI_UNSUPPORTED      This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+SDControllerSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,
+  IN EFI_HANDLE                      Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
+  )
+{
+  EFI_STATUS            OpenStatus;
+  EFI_STATUS            Status;
+  EFI_PCI_IO_PROTOCOL   *PciIo;
+  PCI_CLASSC            PciClass;
+  EFI_SD_HOST_IO_PROTOCOL   *SdHostIo;
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiSDHostIoProtocolGuid,
+                  (VOID **)&SdHostIo,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (!EFI_ERROR (Status)) {
+    DEBUG (( DEBUG_INFO, "SdHost controller is already started\n"));
+    return EFI_ALREADY_STARTED;
+  }
+
+  //
+  // Test whether there is PCI IO Protocol attached on the controller handle.
+  //
+  OpenStatus = gBS->OpenProtocol (
+                      Controller,
+                      &gEfiPciIoProtocolGuid,
+                      (VOID **) &PciIo,
+                      This->DriverBindingHandle,
+                      Controller,
+                      EFI_OPEN_PROTOCOL_BY_DRIVER
+                      );
+
+  if (EFI_ERROR (OpenStatus)) {
+    return OpenStatus;
+  }
+
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint8,
+                        PCI_CLASSCODE_OFFSET,
+                        sizeof (PCI_CLASSC) / sizeof (UINT8),
+                        &PciClass
+                        );
+
+  if (EFI_ERROR (Status)) {
+    Status = EFI_UNSUPPORTED;
+    goto ON_EXIT;
+  }
+
+  //
+  // Test whether the controller belongs to SD type
+  //
+  if ((PciClass.BaseCode != PCI_CLASS_SYSTEM_PERIPHERAL) ||
+      (PciClass.SubClassCode != PCI_SUBCLASS_SD_HOST_CONTROLLER) ||
+      ((PciClass.PI != PCI_IF_STANDARD_HOST_NO_DMA) && (PciClass.PI != PCI_IF_STANDARD_HOST_SUPPORT_DMA))
+      ) {
+
+    Status = EFI_UNSUPPORTED;
+  }
+
+ON_EXIT:
+  gBS->CloseProtocol (
+         Controller,
+         &gEfiPciIoProtocolGuid,
+         This->DriverBindingHandle,
+         Controller
+         );
+
+  return Status;
+}
+/**
+  Starting the SD Host Controller Driver.
+
+  @param  This                 Protocol instance pointer.
+  @param  Controller           Handle of device to test.
+  @param  RemainingDevicePath  Not used.
+
+  @retval EFI_SUCCESS          This driver supports this device.
+  @retval EFI_UNSUPPORTED      This driver does not support this device.
+  @retval EFI_DEVICE_ERROR     This driver cannot be started due to device Error.
+                               EFI_OUT_OF_RESOURCES- Failed due to resource shortage.
+
+**/
+EFI_STATUS
+EFIAPI
+SDControllerStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,
+  IN EFI_HANDLE                      Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
+  )
+{
+  EFI_STATUS            Status;
+  EFI_PCI_IO_PROTOCOL   *PciIo;
+  SDHOST_DATA           *SDHostData;
+  UINT32                Data;
+
+
+  SDHostData = NULL;
+  Data       = 0;
+
+  //
+  // Open PCI I/O Protocol and save pointer to open protocol
+  // in private data area.
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **) &PciIo,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  //
+  // Enable the SD Host Controller MMIO space
+  //
+  Status = PciIo->Attributes (
+                    PciIo,
+                    EfiPciIoAttributeOperationEnable,
+                    EFI_PCI_DEVICE_ENABLE,
+                    NULL
+                    );
+  if (EFI_ERROR (Status)) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Exit;
+  }
+
+
+  SDHostData = (SDHOST_DATA*)AllocateZeroPool(sizeof (SDHOST_DATA));
+  if (SDHostData == NULL) {
+    Status =  EFI_OUT_OF_RESOURCES;
+    goto Exit;
+  }
+
+  SDHostData->Signature   = SDHOST_DATA_SIGNATURE;
+  SDHostData->PciIo       = PciIo;
+
+  CopyMem (&SDHostData->SDHostIo, &mSDHostIo, sizeof (EFI_SD_HOST_IO_PROTOCOL));
+
+  ResetSDHost (&SDHostData->SDHostIo, Reset_All);
+
+  PciIo->Mem.Read (
+              PciIo,
+              EfiPciIoWidthUint16,
+              0,
+              (UINT64)MMIO_CTRLRVER,
+              1,
+              &Data
+              );
+  SDHostData->SDHostIo.HostCapability.HostVersion = Data & 0xFF;
+  DEBUG ((EFI_D_INFO, "SdHostDriverBindingStart: HostVersion 0x%x \r\n", SDHostData->SDHostIo.HostCapability.HostVersion));
+
+  PciIo->Mem.Read (
+               PciIo,
+               EfiPciIoWidthUint32,
+               0,
+               (UINT64)MMIO_CAP,
+               1,
+               &Data
+               );
+  DEBUG ((EFI_D_INFO, "SdHostDriverBindingStart: MMIO_CAP 0x%x \r\n", Data));
+  if ((Data & BIT18) != 0) {
+    SDHostData->SDHostIo.HostCapability.BusWidth8 = TRUE;
+  }
+
+  if ((Data & BIT21) != 0) {
+    SDHostData->SDHostIo.HostCapability.HighSpeedSupport = TRUE;
+  }
+
+  if ((Data & BIT24) != 0) {
+    SDHostData->SDHostIo.HostCapability.V33Support = TRUE;
+  }
+
+  if ((Data & BIT25) != 0) {
+    SDHostData->SDHostIo.HostCapability.V30Support = TRUE;
+  }
+
+  if ((Data & BIT26) != 0) {
+    SDHostData->SDHostIo.HostCapability.V18Support = TRUE;
+  }
+
+  SDHostData->SDHostIo.HostCapability.BusWidth4 = TRUE;
+
+  if(SDHostData->SDHostIo.HostCapability.HostVersion < SDHCI_SPEC_300) {
+
+
+
+      SDHostData->BaseClockInMHz = (Data >> 8) & 0x3F;
+   }
+   else {
+      SDHostData->BaseClockInMHz = (Data >> 8) & 0xFF;
+
+   }
+
+  SDHostData->BlockLength = 512 << ((Data >> 16) & 0x03);
+  DEBUG ((EFI_D_INFO, "SdHostDriverBindingStart: BlockLength 0x%x \r\n", SDHostData->BlockLength));
+  SDHostData->IsAutoStopCmd  = TRUE;
+
+  Status = gBS->InstallProtocolInterface (
+                  &Controller,
+                  &gEfiSDHostIoProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &SDHostData->SDHostIo
+                  );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  //
+  // Install the component name protocol
+  //
+  SDHostData->ControllerNameTable = NULL;
+
+  AddUnicodeString2 (
+    "eng",
+    gSDControllerName.SupportedLanguages,
+    &SDHostData->ControllerNameTable,
+    L"SD Host Controller",
+    TRUE
+    );
+  AddUnicodeString2 (
+    "en",
+    gSDControllerName2.SupportedLanguages,
+    &SDHostData->ControllerNameTable,
+    L"SD Host Controller",
+    FALSE
+    );
+
+Exit:
+  if (EFI_ERROR (Status)) {
+    if (SDHostData != NULL) {
+      FreePool (SDHostData);
+    }
+  }
+
+  return Status;
+}
+
+
+/**
+  Stop this driver on ControllerHandle. Support stopping any child handles
+  created by this driver.
+
+  @param  This                 Protocol instance pointer.
+  @param  Controller           Handle of device to stop driver on.
+  @param  NumberOfChildren     Number of Children in the ChildHandleBuffer.
+  @param  ChildHandleBuffer    List of handles for the children we need to stop.
+
+  @return EFI_SUCCESS
+  @return others
+
+**/
+EFI_STATUS
+EFIAPI
+SDControllerStop (
+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,
+  IN EFI_HANDLE                      Controller,
+  IN UINTN                           NumberOfChildren,
+  IN EFI_HANDLE                      *ChildHandleBuffer
+  )
+{
+  EFI_STATUS               Status;
+  EFI_SD_HOST_IO_PROTOCOL  *SDHostIo;
+  SDHOST_DATA              *SDHostData;
+
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiSDHostIoProtocolGuid,
+                  (VOID **) &SDHostIo,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+
+  //
+  // Test whether the Controller handler passed in is a valid
+  // Usb controller handle that should be supported, if not,
+  // return the error status directly
+  //
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  SetHostVoltage (SDHostIo, 0);
+
+  SDHostData  = SDHOST_DATA_FROM_THIS(SDHostIo);
+
+  //
+  // Uninstall Block I/O protocol from the device handle
+  //
+  Status = gBS->UninstallProtocolInterface (
+                  Controller,
+                  &gEfiSDHostIoProtocolGuid,
+                  SDHostIo
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  FreeUnicodeStringTable (SDHostData->ControllerNameTable);
+
+  FreePool (SDHostData);
+
+  gBS->CloseProtocol (
+         Controller,
+         &gEfiPciIoProtocolGuid,
+         This->DriverBindingHandle,
+         Controller
+         );
+
+  return EFI_SUCCESS;
+}
+
+
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SDController.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SDController.h
new file mode 100644
index 0000000000..025c80c263
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SDController.h
@@ -0,0 +1,316 @@
+/** @file
+
+The definition for SD host controller driver model and HC protocol routines.
+
+Copyright (c) 2013-2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _SD_CONTROLLER_H_
+#define _SD_CONTROLLER_H_
+
+
+#include <Uefi.h>
+
+
+#include <Protocol/PciIo.h>
+
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <IndustryStandard/Pci22.h>
+
+
+#include "ComponentName.h"
+#include "SDHostIo.h"
+
+
+extern EFI_DRIVER_BINDING_PROTOCOL   gSDControllerDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL   gSDControllerName;
+extern EFI_COMPONENT_NAME2_PROTOCOL  gSDControllerName2;
+
+
+#define SDHOST_DATA_SIGNATURE  SIGNATURE_32 ('s', 'd', 'h', 's')
+
+#define BLOCK_SIZE   0x200
+#define TIME_OUT_1S  1000
+
+#pragma pack(1)
+//
+// PCI Class Code structure
+//
+typedef struct {
+  UINT8 PI;
+  UINT8 SubClassCode;
+  UINT8 BaseCode;
+} PCI_CLASSC;
+
+#pragma pack()
+
+
+typedef struct {
+  UINTN                      Signature;
+  EFI_SD_HOST_IO_PROTOCOL    SDHostIo;
+  EFI_PCI_IO_PROTOCOL        *PciIo;
+  BOOLEAN                    IsAutoStopCmd;
+  UINT32                     BaseClockInMHz;
+  UINT32                     CurrentClockInKHz;
+  UINT32                     BlockLength;
+  EFI_UNICODE_STRING_TABLE   *ControllerNameTable;
+}SDHOST_DATA;
+
+#define SDHOST_DATA_FROM_THIS(a) \
+    CR(a, SDHOST_DATA, SDHostIo, SDHOST_DATA_SIGNATURE)
+
+/**
+  Test to see if this driver supports ControllerHandle. Any
+  ControllerHandle that has SDHostIoProtocol installed will be supported.
+
+  @param  This                 Protocol instance pointer.
+  @param  Controller           Handle of device to test.
+  @param  RemainingDevicePath  Not used.
+
+  @return EFI_SUCCESS          This driver supports this device.
+  @return EFI_UNSUPPORTED      This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+SDControllerSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,
+  IN EFI_HANDLE                      Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
+  );
+
+/**
+  Starting the SD Host Controller Driver.
+
+  @param  This                 Protocol instance pointer.
+  @param  Controller           Handle of device to test.
+  @param  RemainingDevicePath  Not used.
+
+  @retval EFI_SUCCESS          This driver supports this device.
+  @retval EFI_UNSUPPORTED      This driver does not support this device.
+  @retval EFI_DEVICE_ERROR     This driver cannot be started due to device Error.
+                               EFI_OUT_OF_RESOURCES- Failed due to resource shortage.
+
+**/
+EFI_STATUS
+EFIAPI
+SDControllerStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,
+  IN EFI_HANDLE                      Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
+  );
+
+/**
+  Stop this driver on ControllerHandle. Support stopping any child handles
+  created by this driver.
+
+  @param  This                 Protocol instance pointer.
+  @param  Controller           Handle of device to stop driver on.
+  @param  NumberOfChildren     Number of Children in the ChildHandleBuffer.
+  @param  ChildHandleBuffer    List of handles for the children we need to stop.
+
+  @return EFI_SUCCESS
+  @return others
+
+**/
+EFI_STATUS
+EFIAPI
+SDControllerStop (
+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,
+  IN EFI_HANDLE                      Controller,
+  IN UINTN                           NumberOfChildren,
+  IN EFI_HANDLE                      *ChildHandleBuffer
+  );
+
+/**
+  The main function used to send the command to the card inserted into the SD host slot.
+  It will assemble the arguments to set the command register and wait for the command
+  and transfer completed until timeout. Then it will read the response register to fill
+  the ResponseData.
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  CommandIndex          The command index to set the command index field of command register.
+  @param  Argument              Command argument to set the argument field of command register.
+  @param  DataType              TRANSFER_TYPE, indicates no data, data in or data out.
+  @param  Buffer                Contains the data read from / write to the device.
+  @param  BufferSize            The size of the buffer.
+  @param  ResponseType          RESPONSE_TYPE.
+  @param  TimeOut               Time out value in 1 ms unit.
+  @param  ResponseData          Depending on the ResponseType, such as CSD or card status.
+
+  @retval EFI_SUCCESS
+  @retval EFI_INVALID_PARAMETER
+  @retval EFI_OUT_OF_RESOURCES
+  @retval EFI_TIMEOUT
+  @retval EFI_DEVICE_ERROR
+
+**/
+EFI_STATUS
+EFIAPI
+SendCommand (
+  IN   EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN   UINT16                     CommandIndex,
+  IN   UINT32                     Argument,
+  IN   TRANSFER_TYPE              DataType,
+  IN   UINT8                      *Buffer, OPTIONAL
+  IN   UINT32                     BufferSize,
+  IN   RESPONSE_TYPE              ResponseType,
+  IN   UINT32                     TimeOut,
+  OUT  UINT32                     *ResponseData OPTIONAL
+  );
+
+/**
+  Set max clock frequency of the host, the actual frequency may not be the same as MaxFrequency.
+  It depends on the max frequency the host can support, divider, and host speed mode.
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  MaxFrequency          Max frequency in HZ.
+
+  @retval EFI_SUCCESS
+  @retval EFI_TIMEOUT
+
+**/
+EFI_STATUS
+EFIAPI
+SetClockFrequency (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  UINT32                     MaxFrequencyInKHz
+  );
+
+/**
+  Set bus width of the host controller
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  BusWidth              Bus width in 1, 4, 8 bits.
+
+  @retval EFI_SUCCESS
+  @retval EFI_INVALID_PARAMETER
+
+**/
+EFI_STATUS
+EFIAPI
+SetBusWidth (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  UINT32                     BusWidth
+  );
+
+
+/**
+  Set voltage which could supported by the host controller.
+  Support 0(Power off the host), 1.8V, 3.0V, 3.3V
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  Voltage               Units in 0.1 V.
+
+  @retval EFI_SUCCESS
+  @retval EFI_INVALID_PARAMETER
+
+**/
+EFI_STATUS
+EFIAPI
+SetHostVoltage (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  UINT32                     Voltage
+  );
+
+
+/**
+  Reset the host controller.
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  ResetAll              TRUE to reset all.
+
+  @retval EFI_SUCCESS
+  @retval EFI_TIMEOUT
+
+**/
+EFI_STATUS
+EFIAPI
+ResetSDHost (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  RESET_TYPE                 ResetType
+  );
+
+
+/**
+  Enable auto stop on the host controller.
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  Enable                TRUE to enable, FALSE to disable.
+
+  @retval EFI_SUCCESS
+  @retval EFI_TIMEOUT
+
+**/
+EFI_STATUS
+EFIAPI
+EnableAutoStopCmd (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  BOOLEAN                    Enable
+  );
+
+/**
+  Find whether these is a card inserted into the slot. If so init the host.
+  If not, return EFI_NOT_FOUND.
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+
+  @retval EFI_SUCCESS
+  @retval EFI_NOT_FOUND
+
+**/
+EFI_STATUS
+EFIAPI
+DetectCardAndInitHost (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This
+  );
+
+/**
+  Set the Block length on the host controller.
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  BlockLength           card supportes block length.
+
+  @retval EFI_SUCCESS
+  @retval EFI_TIMEOUT
+
+**/
+EFI_STATUS
+EFIAPI
+SetBlockLength (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  UINT32                     BlockLength
+  );
+
+/**
+  Enable/Disable High Speed transfer mode
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  Enable                TRUE to Enable, FALSE to Disable
+
+  @return EFI_SUCCESS
+**/
+EFI_STATUS
+EFIAPI
+SetHighSpeedMode (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  BOOLEAN                    Enable
+  );
+
+EFI_STATUS
+EFIAPI
+SetDDRMode (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  BOOLEAN                    Enable
+  );
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SDControllerDxe.inf b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SDControllerDxe.inf
new file mode 100644
index 0000000000..c5fb51d006
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SDControllerDxe.inf
@@ -0,0 +1,56 @@
+## @file
+#
+#  Component Description File For SDControllerDxe Module.
+#
+#  Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SDController
+  FILE_GUID                      = 90A330BD-6F89-4900-933A-C25EB4356348
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = InitializeSDController
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+#  DRIVER_BINDING                =  gSDControllerDriverBinding
+#  COMPONENT_NAME                =  gSDControllerName
+#  COMPONENT_NAME2               =  gSDControllerName2
+#
+
+[Sources]
+  SDController.c
+  SDController.h
+  ComponentName.c
+  ComponentName.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  MemoryAllocationLib
+  BaseLib
+  UefiLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  BaseMemoryLib
+  DebugLib
+  PcdLib
+
+[Protocols]
+  gEfiPciIoProtocolGuid                         ## TO_START
+  gEfiSDHostIoProtocolGuid                      ## BY_START
+
+[FeaturePcd]
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdSdHciQuirkNoHiSpd
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/CEATA.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/CEATA.c
new file mode 100644
index 0000000000..41a3065b5c
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/CEATA.c
@@ -0,0 +1,647 @@
+/** @file
+
+CEATA specific functions implementation
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SDMediaDevice.h"
+
+/**
+  Send RW_MULTIPLE_REGISTER command
+
+  @param  CardData             Pointer to CARD_DATA.
+  @param  Address              Register address.
+  @param  ByteCount            Buffer size.
+  @param  Write                TRUE means write, FALSE means read.
+  @param  Buffer               Buffer pointer.
+
+  @retval EFI_SUCCESS                Success
+  @retval EFI_DEVICE_ERROR           Hardware Error
+  @retval EFI_INVALID_PARAMETER      Parameter is error
+  @retval EFI_NO_MEDIA               No media
+  @retval EFI_MEDIA_CHANGED          Media Change
+  @retval EFI_BAD_BUFFER_SIZE        Buffer size is bad
+
+**/
+EFI_STATUS
+ReadWriteMultipleRegister (
+  IN  CARD_DATA   *CardData,
+  IN  UINT16      Address,
+  IN  UINT8       ByteCount,
+  IN  BOOLEAN     Write,
+  IN  UINT8       *Buffer
+  )
+{
+  EFI_STATUS                 Status;
+  UINT32                     Argument;
+
+  Status   = EFI_SUCCESS;
+
+  if ((Address % 4 != 0) || (ByteCount % 4 != 0)) {
+    Status = EFI_INVALID_PARAMETER;
+    goto Exit;
+  }
+
+  Argument = (Address << 16) | ByteCount;
+  if (Write) {
+    Argument |= BIT31;
+  }
+
+
+  if (Write) {
+    CopyMem (CardData->AlignedBuffer, Buffer, ByteCount);
+
+    Status = SendCommand (
+               CardData,
+               RW_MULTIPLE_REGISTER,
+               Argument,
+               OutData,
+               CardData->AlignedBuffer,
+               ByteCount,
+               ResponseR1b,
+               TIMEOUT_DATA,
+               (UINT32*)&(CardData->CardStatus)
+               );
+  } else {
+    Status = SendCommand (
+               CardData,
+               RW_MULTIPLE_REGISTER,
+               Argument,
+               InData,
+               CardData->AlignedBuffer,
+               ByteCount,
+               ResponseR1,
+               TIMEOUT_DATA,
+               (UINT32*)&(CardData->CardStatus)
+               );
+    if (!EFI_ERROR (Status)) {
+      CopyMem (Buffer, CardData->AlignedBuffer, ByteCount);
+    }
+
+  }
+Exit:
+  return Status;
+}
+
+/**
+  Send ReadWriteMultipleBlock command with RW_MULTIPLE_REGISTER command
+
+  @param  CardData             Pointer to CARD_DATA.
+  @param  DataUnitCount        Buffer size in 512 bytes unit.
+  @param  Write                TRUE means write, FALSE means read.
+  @param  Buffer               Buffer pointer.
+
+  @retval EFI_SUCCESS                Success
+  @retval EFI_DEVICE_ERROR           Hardware Error
+  @retval EFI_INVALID_PARAMETER      Parameter is error
+  @retval EFI_NO_MEDIA               No media
+  @retval EFI_MEDIA_CHANGED          Media Change
+  @retval EFI_BAD_BUFFER_SIZE        Buffer size is bad
+
+**/
+EFI_STATUS
+ReadWriteMultipleBlock (
+  IN  CARD_DATA   *CardData,
+  IN  UINT16      DataUnitCount,
+  IN  BOOLEAN     Write,
+  IN  UINT8       *Buffer
+  )
+{
+  EFI_STATUS                 Status;
+  EFI_SD_HOST_IO_PROTOCOL    *SDHostIo;
+  UINT32                     TransferLength;
+
+  Status   = EFI_SUCCESS;
+  SDHostIo = CardData->SDHostIo;
+
+  TransferLength = DataUnitCount * DATA_UNIT_SIZE;
+  if (TransferLength > SDHostIo->HostCapability.BoundarySize) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Write) {
+    CopyMem (CardData->AlignedBuffer, Buffer, TransferLength);
+
+    Status = SendCommand (
+               CardData,
+               RW_MULTIPLE_BLOCK,
+               (DataUnitCount | BIT31),
+               OutData,
+               CardData->AlignedBuffer,
+               TransferLength,
+               ResponseR1b,
+               TIMEOUT_DATA,
+               (UINT32*)&(CardData->CardStatus)
+               );
+   } else {
+      Status = SendCommand (
+                 CardData,
+                 RW_MULTIPLE_BLOCK,
+                 DataUnitCount,
+                 InData,
+                 CardData->AlignedBuffer,
+                 TransferLength,
+                 ResponseR1,
+                 TIMEOUT_DATA,
+                 (UINT32*)&(CardData->CardStatus)
+                 );
+      if (!EFI_ERROR (Status)) {
+        CopyMem (Buffer, CardData->AlignedBuffer, TransferLength);
+      }
+  }
+
+  return Status;
+}
+
+/**
+  Send software reset
+
+  @param  CardData             Pointer to CARD_DATA.
+
+  @retval EFI_SUCCESS                Success
+  @retval EFI_DEVICE_ERROR           Hardware Error
+  @retval EFI_INVALID_PARAMETER      Parameter is error
+  @retval EFI_NO_MEDIA               No media
+  @retval EFI_MEDIA_CHANGED          Media Change
+  @retval EFI_BAD_BUFFER_SIZE        Buffer size is bad
+
+**/
+EFI_STATUS
+SoftwareReset (
+  IN  CARD_DATA    *CardData
+  )
+{
+  EFI_STATUS    Status;
+  UINT8         Data;
+  UINT32        TimeOut;
+
+  Data = BIT2;
+
+  Status = FastIO (CardData, Reg_Control, &Data, TRUE);
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  TimeOut = 5 * 1000;
+
+  do {
+    gBS->Stall (1 * 1000);
+    Status = FastIO (CardData, Reg_Control, &Data, FALSE);
+    if (EFI_ERROR (Status)) {
+      goto Exit;
+    }
+    if ((Data & BIT2) == BIT2) {
+      break;
+    }
+
+    TimeOut--;
+  } while (TimeOut > 0);
+
+  if (TimeOut == 0) {
+   Status = EFI_TIMEOUT;
+   goto Exit;
+  }
+
+  Data &= ~BIT2;
+  Status = FastIO (CardData, Reg_Control, &Data, TRUE);
+
+  TimeOut = 5 * 1000;
+
+  do {
+    gBS->Stall (1 * 1000);
+    Status = FastIO (CardData, Reg_Control, &Data, FALSE);
+    if (EFI_ERROR (Status)) {
+      goto Exit;
+    }
+    if ((Data & BIT2) != BIT2) {
+      break;
+    }
+
+    TimeOut--;
+  } while (TimeOut > 0);
+
+
+  if (TimeOut == 0) {
+   Status = EFI_TIMEOUT;
+   goto Exit;
+  }
+
+
+Exit:
+  return Status;
+}
+
+
+/**
+  SendATACommand specificed in Taskfile
+
+  @param  CardData             Pointer to CARD_DATA.
+  @param  TaskFile             Pointer to TASK_FILE.
+  @param  Write                TRUE means write, FALSE means read.
+  @param  Buffer               If NULL, means no data transfer, neither read nor write.
+  @param  SectorCount          Buffer size in 512 bytes unit.
+
+  @retval EFI_SUCCESS                Success
+  @retval EFI_DEVICE_ERROR           Hardware Error
+  @retval EFI_INVALID_PARAMETER      Parameter is error
+  @retval EFI_NO_MEDIA               No media
+  @retval EFI_MEDIA_CHANGED          Media Change
+  @retval EFI_BAD_BUFFER_SIZE        Buffer size is bad
+
+**/
+EFI_STATUS
+SendATACommand (
+  IN  CARD_DATA   *CardData,
+  IN  TASK_FILE   *TaskFile,
+  IN  BOOLEAN     Write,
+  IN  UINT8       *Buffer,
+  IN  UINT16      SectorCount
+  )
+{
+  EFI_STATUS                 Status;
+  UINT8                      Data;
+  UINT32                     TimeOut;
+
+  //
+  //Write register
+  //
+  Status = ReadWriteMultipleRegister (
+             CardData,
+             0,
+             sizeof (TASK_FILE),
+             TRUE,
+             (UINT8*)TaskFile
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG((EFI_D_ERROR, "ReadWriteMultipleRegister 0x%x\n", Status));
+    goto Exit;
+  }
+
+  TimeOut = 5000;
+  do {
+    gBS->Stall (1 * 1000);
+    Data = 0;
+    Status = FastIO (
+               CardData,
+               Reg_Command_Status,
+               &Data,
+               FALSE
+               );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    if (((Data & BIT7) == 0) && ((Data & BIT6) == BIT6)) {
+      break;
+    }
+
+    TimeOut --;
+  } while (TimeOut > 0);
+
+  if (TimeOut == 0) {
+    DEBUG((EFI_D_ERROR, "ReadWriteMultipleRegister FastIO EFI_TIMEOUT 0x%x\n", Data));
+    Status = EFI_TIMEOUT;
+    goto Exit;
+  }
+
+
+  if (Buffer != NULL) {
+    Status = ReadWriteMultipleBlock (
+               CardData,
+               SectorCount,
+               Write,
+               (UINT8*)Buffer
+               );
+    if (EFI_ERROR (Status)) {
+      DEBUG((EFI_D_ERROR, "ReadWriteMultipleBlock EFI_TIMEOUT 0x%x\n", Status));
+      goto Exit;
+    }
+
+    TimeOut = 5 * 1000;
+    do {
+      gBS->Stall (1 * 1000);
+
+      Data = 0;
+      Status = FastIO (
+                 CardData,
+                 Reg_Command_Status,
+                 &Data,
+                 FALSE
+                 );
+      if (EFI_ERROR (Status)) {
+        return Status;
+      }
+
+      if (((Data & BIT7) == 0) && ((Data & BIT3) == 0)) {
+        break;
+      }
+
+      TimeOut --;
+    } while (TimeOut > 0);
+    if (TimeOut == 0) {
+      DEBUG((EFI_D_ERROR, "ReadWriteMultipleBlock FastIO EFI_TIMEOUT 0x%x\n", Data));
+      Status = EFI_TIMEOUT;
+      goto Exit;
+    }
+
+
+    if (((Data & BIT6) == BIT6) && (Data & BIT0) == 0) {
+      Status = EFI_SUCCESS;
+    } else {
+      Status = EFI_DEVICE_ERROR;
+    }
+  }
+
+Exit:
+  if (EFI_ERROR (Status)) {
+    SoftwareReset (CardData);
+  }
+
+  return Status;
+}
+
+/**
+  IDENTIFY_DEVICE command
+
+  @param  CardData             Pointer to CARD_DATA.
+
+  @retval EFI_SUCCESS                Success
+  @retval EFI_DEVICE_ERROR           Hardware Error
+  @retval EFI_INVALID_PARAMETER      Parameter is error
+  @retval EFI_NO_MEDIA               No media
+  @retval EFI_MEDIA_CHANGED          Media Change
+  @retval EFI_BAD_BUFFER_SIZE        Buffer size is bad
+
+**/
+EFI_STATUS
+IndentifyDevice (
+  IN  CARD_DATA    *CardData
+  )
+{
+  EFI_STATUS                 Status;
+
+  ZeroMem (&CardData->TaskFile, sizeof (TASK_FILE));
+
+  //
+  //The host only supports nIEN = 0
+  //
+  CardData->TaskFile.Command_Status = IDENTIFY_DEVICE;
+
+
+  Status = SendATACommand (
+             CardData,
+             &CardData->TaskFile,
+             FALSE,
+             (UINT8*)&(CardData->IndentifyDeviceData),
+             1
+             );
+
+
+  return Status;
+}
+
+/**
+  FLUSH_CACHE_EXT command
+
+  @param  CardData             Pointer to CARD_DATA.
+
+  @retval EFI_SUCCESS                Success
+  @retval EFI_DEVICE_ERROR           Hardware Error
+  @retval EFI_INVALID_PARAMETER      Parameter is error
+  @retval EFI_NO_MEDIA               No media
+  @retval EFI_MEDIA_CHANGED          Media Change
+  @retval EFI_BAD_BUFFER_SIZE        Buffer size is bad
+
+**/
+EFI_STATUS
+FlushCache (
+  IN  CARD_DATA    *CardData
+  )
+{
+
+  //
+  //Hitachi CE-ATA will always make the busy high after
+  //receving this command
+  //
+/*
+  EFI_STATUS  Status;
+  ZeroMem (&CardData->TaskFile, sizeof (TASK_FILE));
+  //
+  //The host only supports nIEN = 0
+  //
+  CardData->TaskFile.Command_Status = FLUSH_CACHE_EXT;
+
+  Status = SendATACommand (
+             CardData,
+             &CardData->TaskFile,
+             FALSE,
+             NULL,
+             0
+             );
+*/
+  return EFI_SUCCESS;
+}
+
+/**
+  STANDBY_IMMEDIATE command
+
+  @param  CardData             Pointer to CARD_DATA.
+
+  @retval EFI_SUCCESS                Success
+  @retval EFI_DEVICE_ERROR           Hardware Error
+  @retval EFI_INVALID_PARAMETER      Parameter is error
+  @retval EFI_NO_MEDIA               No media
+  @retval EFI_MEDIA_CHANGED          Media Change
+  @retval EFI_BAD_BUFFER_SIZE        Buffer size is bad
+
+**/
+EFI_STATUS
+StandByImmediate (
+  IN  CARD_DATA    *CardData
+  )
+{
+  EFI_STATUS  Status;
+
+  ZeroMem (&CardData->TaskFile, sizeof (TASK_FILE));
+  //
+  //The host only supports nIEN = 0
+  //
+  CardData->TaskFile.Command_Status = STANDBY_IMMEDIATE;
+
+
+  Status = SendATACommand (
+             CardData,
+             &CardData->TaskFile,
+             FALSE,
+             NULL,
+             0
+             );
+  return Status;
+}
+
+/**
+  READ_DMA_EXT command
+
+  @param  CardData             Pointer to CARD_DATA.
+  @param  LBA                  The starting logical block address to read from on the device.
+  @param  Buffer               A pointer to the destination buffer for the data. The caller
+                               is responsible for either having implicit or explicit ownership
+                               of the buffer.
+  @param  SectorCount          Size in 512 bytes unit.
+
+  @retval EFI_SUCCESS                Success
+  @retval EFI_DEVICE_ERROR           Hardware Error
+  @retval EFI_INVALID_PARAMETER      Parameter is error
+  @retval EFI_NO_MEDIA               No media
+  @retval EFI_MEDIA_CHANGED          Media Change
+  @retval EFI_BAD_BUFFER_SIZE        Buffer size is bad
+
+**/
+EFI_STATUS
+ReadDMAExt (
+  IN  CARD_DATA   *CardData,
+  IN  EFI_LBA     LBA,
+  IN  UINT8       *Buffer,
+  IN  UINT16      SectorCount
+  )
+{
+
+  EFI_STATUS  Status;
+
+  ZeroMem (&CardData->TaskFile, sizeof (TASK_FILE));
+  //
+  //The host only supports nIEN = 0
+  //
+  CardData->TaskFile.Command_Status = READ_DMA_EXT;
+
+  CardData->TaskFile.SectorCount     = (UINT8)SectorCount;
+  CardData->TaskFile.SectorCount_Exp = (UINT8)(SectorCount >> 8);
+
+  CardData->TaskFile.LBALow          = (UINT8)LBA;
+  CardData->TaskFile.LBAMid          = (UINT8)RShiftU64(LBA, 8);
+  CardData->TaskFile.LBAHigh         = (UINT8)RShiftU64(LBA, 16);
+
+  CardData->TaskFile.LBALow_Exp      = (UINT8)RShiftU64(LBA, 24);
+  CardData->TaskFile.LBAMid_Exp      = (UINT8)RShiftU64(LBA, 32);
+  CardData->TaskFile.LBAHigh_Exp     = (UINT8)RShiftU64(LBA, 40);
+
+  Status = SendATACommand (
+             CardData,
+             &CardData->TaskFile,
+             FALSE,
+             Buffer,
+             SectorCount
+             );
+  return Status;
+
+}
+
+/**
+  WRITE_DMA_EXT command
+
+  @param  CardData             Pointer to CARD_DATA.
+  @param  LBA                  The starting logical block address to read from on the device.
+  @param  Buffer               A pointer to the destination buffer for the data. The caller
+                               is responsible for either having implicit or explicit ownership
+                               of the buffer.
+  @param  SectorCount          Size in 512 bytes unit.
+
+  @retval EFI_SUCCESS                Success
+  @retval EFI_DEVICE_ERROR           Hardware Error
+  @retval EFI_INVALID_PARAMETER      Parameter is error
+  @retval EFI_NO_MEDIA               No media
+  @retval EFI_MEDIA_CHANGED          Media Change
+  @retval EFI_BAD_BUFFER_SIZE        Buffer size is bad
+
+**/
+EFI_STATUS
+WriteDMAExt (
+  IN  CARD_DATA   *CardData,
+  IN  EFI_LBA     LBA,
+  IN  UINT8       *Buffer,
+  IN  UINT16      SectorCount
+  )
+{
+
+  EFI_STATUS  Status;
+
+  ZeroMem (&CardData->TaskFile, sizeof (TASK_FILE));
+  //
+  //The host only supports nIEN = 0
+  //
+  CardData->TaskFile.Command_Status = WRITE_DMA_EXT;
+
+  CardData->TaskFile.SectorCount     = (UINT8)SectorCount;
+  CardData->TaskFile.SectorCount_Exp = (UINT8)(SectorCount >> 8);
+
+  CardData->TaskFile.LBALow          = (UINT8)LBA;
+  CardData->TaskFile.LBAMid          = (UINT8)RShiftU64(LBA, 8);
+  CardData->TaskFile.LBAHigh         = (UINT8)RShiftU64(LBA, 16);
+
+  CardData->TaskFile.LBALow_Exp      = (UINT8)RShiftU64(LBA, 24);
+  CardData->TaskFile.LBAMid_Exp      = (UINT8)RShiftU64(LBA, 32);
+  CardData->TaskFile.LBAHigh_Exp     = (UINT8)RShiftU64(LBA, 40);
+
+  Status = SendATACommand (
+             CardData,
+             &CardData->TaskFile,
+             TRUE,
+             Buffer,
+             SectorCount
+             );
+  return Status;
+
+}
+
+
+/**
+  Judge whether it is CE-ATA device or not.
+
+  @param  CardData             Pointer to CARD_DATA.
+
+  @retval TRUE
+  @retval FALSE
+
+**/
+BOOLEAN
+IsCEATADevice (
+  IN  CARD_DATA    *CardData
+  )
+{
+  EFI_STATUS                 Status;
+
+  Status = ReadWriteMultipleRegister (
+             CardData,
+             0,
+             sizeof (TASK_FILE),
+             FALSE,
+             (UINT8*)&CardData->TaskFile
+             );
+  if (EFI_ERROR (Status)) {
+    //
+    //To bring back the normal MMC card to work
+    //
+    CardData->SDHostIo->ResetSDHost (CardData->SDHostIo, Reset_DAT_CMD);
+    return FALSE;
+  }
+
+  if (CardData->TaskFile.LBAMid == CE_ATA_SIG_CE &&
+      CardData->TaskFile.LBAHigh == CE_ATA_SIG_AA
+    ) {
+    //
+    //Disable Auto CMD for CE-ATA
+    //
+    CardData->SDHostIo->EnableAutoStopCmd (CardData->SDHostIo, FALSE);
+
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/CEATABlockIo.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/CEATABlockIo.c
new file mode 100644
index 0000000000..eb48baa75c
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/CEATABlockIo.c
@@ -0,0 +1,389 @@
+/** @file
+
+Block I/O protocol for CE-ATA device
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SDMediaDevice.h"
+
+/**
+  Implements EFI_BLOCK_IO_PROTOCOL.Reset() function.
+
+  @param  This                   The EFI_BLOCK_IO_PROTOCOL instance.
+  @param  ExtendedVerification   Indicates that the driver may perform a more exhaustive.
+                                 verification operation of the device during reset.
+                                 (This parameter is ingored in this driver.)
+
+  @retval EFI_SUCCESS                Success
+**/
+EFI_STATUS
+EFIAPI
+CEATABlockReset (
+  IN  EFI_BLOCK_IO_PROTOCOL   *This,
+  IN  BOOLEAN                 ExtendedVerification
+  )
+{
+  EFI_STATUS                 Status;
+  CARD_DATA                  *CardData;
+  EFI_SD_HOST_IO_PROTOCOL    *SDHostIo;
+
+  CardData  = CARD_DATA_FROM_THIS(This);
+  SDHostIo = CardData->SDHostIo;
+
+  if (!ExtendedVerification) {
+    Status = SoftwareReset (CardData);
+  } else {
+    Status = SDHostIo->ResetSDHost (SDHostIo, Reset_DAT_CMD);
+    if (EFI_ERROR (Status)) {
+    DEBUG((EFI_D_ERROR, "CEATABlockReset: Fail to ResetSDHost\n" ));
+      return Status;
+    }
+    Status = MMCSDCardInit (CardData);
+  }
+
+
+  return Status;
+
+ }
+
+/**
+  Implements EFI_BLOCK_IO_PROTOCOL.ReadBlocks() function.
+
+  @param  This                   The EFI_BLOCK_IO_PROTOCOL instance.
+  @param  MediaId                The media id that the write request is for.
+  @param  LBA                    The starting logical block address to read from on the device.
+                                 The caller is responsible for writing to only legitimate locations.
+  @param  BufferSize             The size of the Buffer in bytes. This must be a multiple of the
+                                 intrinsic block size of the device.
+  @param  Buffer                 A pointer to the destination buffer for the data. The caller
+                                 is responsible for either having implicit or explicit ownership
+                                 of the buffer.
+
+  @retval EFI_SUCCESS                Success
+  @retval EFI_DEVICE_ERROR           Hardware Error
+  @retval EFI_INVALID_PARAMETER      Parameter is error
+  @retval EFI_NO_MEDIA               No media
+  @retval EFI_MEDIA_CHANGED          Media Change
+  @retval EFI_BAD_BUFFER_SIZE        Buffer size is bad
+**/
+EFI_STATUS
+EFIAPI
+CEATABlockReadBlocks (
+  IN  EFI_BLOCK_IO_PROTOCOL   *This,
+  IN  UINT32                  MediaId,
+  IN  EFI_LBA                 LBA,
+  IN  UINTN                   BufferSize,
+  OUT VOID                    *Buffer
+  )
+{
+  EFI_STATUS                  Status;
+  CARD_DATA                   *CardData;
+  UINT32                      TransferSize;
+  UINT8                       *pBuf;
+  UINT32                      Index;
+  UINT64                      Address;
+  UINT32                      Remainder;
+  UINT64                      CEATALBA;
+  UINT32                      BoundarySize;
+
+  Status       = EFI_SUCCESS;
+  CardData     = CARD_DATA_FROM_THIS(This);
+  pBuf         = Buffer;
+  Index        = 0;
+  Address      = MultU64x32(LBA, CardData->BlockIoMedia.BlockSize);
+  BoundarySize = CardData->SDHostIo->HostCapability.BoundarySize;
+
+  if (!Buffer) {
+    Status = EFI_INVALID_PARAMETER;
+    DEBUG((EFI_D_ERROR, "CEATABlockReadBlocks:Invalid parameter\n" ));
+    goto Exit;
+  }
+
+  if (MediaId != CardData->BlockIoMedia.MediaId) {
+    Status = EFI_MEDIA_CHANGED;
+  DEBUG((EFI_D_ERROR, "CEATABlockReadBlocks:Media changed\n" ));
+    goto Exit;
+  }
+
+  if ((BufferSize % CardData->BlockIoMedia.BlockSize) != 0) {
+    Status = EFI_BAD_BUFFER_SIZE;
+  DEBUG((EFI_D_ERROR, "CEATABlockReadBlocks:Bad buffer size\n" ));
+    goto Exit;
+  }
+
+  if (BufferSize == 0) {
+    Status = EFI_SUCCESS;
+    goto Exit;
+  }
+
+  if ((Address + BufferSize) > MultU64x32 (CardData->BlockIoMedia.LastBlock + 1, CardData->BlockIoMedia.BlockSize)) {
+    Status = EFI_INVALID_PARAMETER;
+    DEBUG((EFI_D_ERROR, "CEATABlockReadBlocks:Invalid parameter\n" ));
+    goto Exit;
+  }
+
+
+  do {
+    if (BufferSize < BoundarySize) {
+      TransferSize = (UINT32)BufferSize;
+    } else {
+      TransferSize = BoundarySize;
+    }
+
+    Address += Index * TransferSize;
+    CEATALBA = DivU64x32Remainder (Address, DATA_UNIT_SIZE, &Remainder);
+    ASSERT(Remainder == 0);
+
+    Status = ReadDMAExt (
+               CardData,
+               CEATALBA,
+               pBuf,
+               (UINT16)(TransferSize / DATA_UNIT_SIZE)
+               );
+    if (EFI_ERROR (Status)) {
+     DEBUG((EFI_D_ERROR, "Read Failed at 0x%x, Index %d, Size 0x%x\n", Address, Index, TransferSize));
+     This->Reset (This, TRUE);
+     goto Exit;
+    }
+    BufferSize -= TransferSize;
+    pBuf       += TransferSize;
+    Index ++;
+  } while (BufferSize != 0);
+
+
+Exit:
+  return Status;
+}
+
+/**
+  Implements EFI_BLOCK_IO_PROTOCOL.WriteBlocks() function.
+
+  @param  This                   The EFI_BLOCK_IO_PROTOCOL instance.
+  @param  MediaId                The media id that the write request is for.
+  @param  LBA                    The starting logical block address to read from on the device.
+                                 The caller is responsible for writing to only legitimate locations.
+  @param  BufferSize             The size of the Buffer in bytes. This must be a multiple of the
+                                 intrinsic block size of the device.
+  @param  Buffer                 A pointer to the destination buffer for the data. The caller
+                                 is responsible for either having implicit or explicit ownership
+                                 of the buffer.
+
+  @retval EFI_SUCCESS                Success
+  @retval EFI_DEVICE_ERROR           Hardware Error
+  @retval EFI_INVALID_PARAMETER      Parameter is error
+  @retval EFI_NO_MEDIA               No media
+  @retval EFI_MEDIA_CHANGED          Media Change
+  @retval EFI_BAD_BUFFER_SIZE        Buffer size is bad
+**/
+EFI_STATUS
+EFIAPI
+CEATABlockWriteBlocks (
+  IN  EFI_BLOCK_IO_PROTOCOL   *This,
+  IN  UINT32                  MediaId,
+  IN  EFI_LBA                 LBA,
+  IN  UINTN                   BufferSize,
+  IN  VOID                    *Buffer
+  )
+{
+  EFI_STATUS                  Status;
+  CARD_DATA                   *CardData;
+  UINT32                      TransferSize;
+  UINT8                       *pBuf;
+  UINT32                      Index;
+  UINT64                      Address;
+  UINT32                      Remainder;
+  UINT64                      CEATALBA;
+  UINT32                      BoundarySize;
+
+
+  Status       = EFI_SUCCESS;
+  CardData     = CARD_DATA_FROM_THIS(This);
+  pBuf         = Buffer;
+  Index        = 0;
+  Address      = MultU64x32(LBA, CardData->BlockIoMedia.BlockSize);
+  BoundarySize = CardData->SDHostIo->HostCapability.BoundarySize;
+
+
+  if (!Buffer) {
+    Status = EFI_INVALID_PARAMETER;
+    goto Exit;
+  }
+
+  if (MediaId != CardData->BlockIoMedia.MediaId) {
+    Status = EFI_MEDIA_CHANGED;
+    goto Exit;
+  }
+
+  if ((BufferSize % CardData->BlockIoMedia.BlockSize) != 0) {
+    Status = EFI_BAD_BUFFER_SIZE;
+    goto Exit;
+  }
+
+  if (BufferSize == 0) {
+    Status = EFI_SUCCESS;
+    goto Exit;
+  }
+
+  if (CardData->BlockIoMedia.ReadOnly) {
+    Status = EFI_WRITE_PROTECTED;
+    goto Exit;
+  }
+
+  if ((Address + BufferSize) > MultU64x32 (CardData->BlockIoMedia.LastBlock + 1, CardData->BlockIoMedia.BlockSize)) {
+    Status = EFI_INVALID_PARAMETER;
+    goto Exit;
+  }
+
+  CardData->NeedFlush = TRUE;
+
+  do {
+    if (BufferSize < BoundarySize) {
+      TransferSize = (UINT32)BufferSize;
+    } else {
+      TransferSize = BoundarySize;
+    }
+
+    Address += Index * TransferSize;
+    CEATALBA = DivU64x32Remainder (Address, DATA_UNIT_SIZE, &Remainder);
+    ASSERT(Remainder == 0);
+
+    Status = WriteDMAExt (
+               CardData,
+               CEATALBA,
+               pBuf,
+               (UINT16)(TransferSize / DATA_UNIT_SIZE)
+               );
+    if (EFI_ERROR (Status)) {
+     DEBUG((EFI_D_ERROR, "Write Failed at 0x%x, Index %d, Size 0x%x\n", Address, Index, TransferSize));
+     This->Reset (This, TRUE);
+     goto Exit;
+    }
+    BufferSize -= TransferSize;
+    pBuf       += TransferSize;
+    Index ++;
+  } while (BufferSize != 0);
+
+
+Exit:
+  return Status;
+}
+
+/**
+  Implements EFI_BLOCK_IO_PROTOCOL.FlushBlocks() function.
+    (In this driver, this function just returns EFI_SUCCESS.)
+
+  @param  This                   The EFI_BLOCK_IO_PROTOCOL instance.
+
+  @retval EFI_SUCCESS
+  @retval Others
+**/
+EFI_STATUS
+EFIAPI
+CEATABlockFlushBlocks (
+  IN  EFI_BLOCK_IO_PROTOCOL   *This
+  )
+{
+
+  CARD_DATA                   *CardData;
+
+  CardData  = CARD_DATA_FROM_THIS(This);
+
+  if (CardData->NeedFlush) {
+    CardData->NeedFlush = FALSE;
+    FlushCache (CardData);
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  CEATA card BlockIo init function.
+
+  @param  CardData               Pointer to CARD_DATA.
+
+  @retval EFI_SUCCESS
+  @retval Others
+**/
+EFI_STATUS
+CEATABlockIoInit (
+  IN  CARD_DATA    *CardData
+  )
+/*++
+
+  Routine Description:
+    CEATA card BlockIo init function
+
+  Arguments:
+    CardData  -   Pointer to CARD_DATA
+
+  Returns:
+    EFI_SUCCESS - Success
+--*/
+{
+  EFI_STATUS   Status;
+  UINT64       MaxSize;
+  UINT32       Remainder;
+  //
+  //BlockIO protocol
+  //
+  CardData->BlockIo.Revision    = EFI_BLOCK_IO_PROTOCOL_REVISION;
+  CardData->BlockIo.Media       = &(CardData->BlockIoMedia);
+  CardData->BlockIo.Reset       = CEATABlockReset;
+  CardData->BlockIo.ReadBlocks  = CEATABlockReadBlocks ;
+  CardData->BlockIo.WriteBlocks = CEATABlockWriteBlocks;
+  CardData->BlockIo.FlushBlocks = CEATABlockFlushBlocks;
+
+  CardData->BlockIoMedia.MediaId          = 0;
+  CardData->BlockIoMedia.RemovableMedia   = FALSE;
+  CardData->BlockIoMedia.MediaPresent     = TRUE;
+  CardData->BlockIoMedia.LogicalPartition = FALSE;
+
+  if (CardData->CSDRegister.PERM_WRITE_PROTECT | CardData->CSDRegister.TMP_WRITE_PROTECT) {
+    CardData->BlockIoMedia.ReadOnly       = TRUE;
+  } else {
+    CardData->BlockIoMedia.ReadOnly       = FALSE;
+  }
+
+
+  CardData->BlockIoMedia.WriteCaching     = FALSE;
+  CardData->BlockIoMedia.IoAlign          = 1;
+
+  Status = IndentifyDevice (CardData);
+  if (EFI_ERROR (Status)) {
+   goto Exit;
+  }
+
+  //
+  //Some device does not support this feature
+  //
+
+  if (CardData->IndentifyDeviceData.MaxWritesPerAddress == 0) {
+    CardData->BlockIoMedia.ReadOnly       = TRUE;
+  }
+
+  CardData->BlockIoMedia.BlockSize        = (1 << CardData->IndentifyDeviceData.Sectorsize);
+  ASSERT(CardData->BlockIoMedia.BlockSize >= 12);
+
+
+  MaxSize = *(UINT64*)(CardData->IndentifyDeviceData.MaximumLBA);
+  MaxSize = MultU64x32 (MaxSize, 512);
+
+  Remainder = 0;
+  CardData->BlockNumber = DivU64x32Remainder (MaxSize, CardData->BlockIoMedia.BlockSize, &Remainder);
+  ASSERT(Remainder == 0);
+
+  CardData->BlockIoMedia.LastBlock        = (EFI_LBA)(CardData->BlockNumber - 1);
+
+
+Exit:
+  return Status;
+
+}
+
+
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/ComponentName.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/ComponentName.c
new file mode 100644
index 0000000000..0f95968406
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/ComponentName.c
@@ -0,0 +1,215 @@
+/** @file
+
+UEFI Component Name(2) protocol implementation for SD media device driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SDMediaDevice.h"
+
+
+//
+// EFI Component Name Protocol
+//
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gSDMediaDeviceName = {
+  SDMediaDeviceGetDriverName,
+  SDMediaDeviceGetControllerName,
+  "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gSDMediaDeviceName2 = {
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) SDMediaDeviceGetDriverName,
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) SDMediaDeviceGetControllerName,
+  "en"
+};
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mSDMediaDeviceDriverNameTable[] = {
+  { "eng;en", L"UEFI MMC/SD Media Device Driver" },
+  { NULL, NULL }
+};
+
+
+//
+// EFI Component Name Functions
+//
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 3066 or ISO 639-2 language code format.
+
+  @param  DriverName[out]       A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+SDMediaDeviceGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **DriverName
+  )
+{
+  return LookupUnicodeString2 (
+           Language,
+           This->SupportedLanguages,
+           mSDMediaDeviceDriverNameTable,
+           DriverName,
+           (BOOLEAN)(This == &gSDMediaDeviceName)
+           );
+}
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  ControllerHandle[in]  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+
+  @param  ChildHandle[in]       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 3066 or ISO 639-2 language code format.
+
+  @param  ControllerName[out]   A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                controller specified by ControllerHandle and
+                                ChildHandle in the language specified by
+                                Language from the point of view of the driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+SDMediaDeviceGetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
+  IN  EFI_HANDLE                                      ControllerHandle,
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
+  IN  CHAR8                                           *Language,
+  OUT CHAR16                                          **ControllerName
+  )
+{
+  EFI_STATUS           Status;
+  EFI_BLOCK_IO_PROTOCOL    *BlockIo;
+  CARD_DATA                *CardData;
+
+  //
+  // This is a device driver, so ChildHandle must be NULL.
+  //
+  if (ChildHandle != NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Get the device context
+  //
+  Status = gBS->OpenProtocol (
+                  ControllerHandle,
+                  &gEfiBlockIoProtocolGuid,
+                  (VOID **) &BlockIo,
+                  gSDMediaDeviceDriverBinding.DriverBindingHandle,
+                  ControllerHandle,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  CardData  = CARD_DATA_FROM_THIS (BlockIo);
+
+  return LookupUnicodeString2 (
+           Language,
+           This->SupportedLanguages,
+           CardData->ControllerNameTable,
+           ControllerName,
+           (BOOLEAN)(This == &gSDMediaDeviceName)
+           );
+
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/ComponentName.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/ComponentName.h
new file mode 100644
index 0000000000..69eb4d7a73
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/ComponentName.h
@@ -0,0 +1,139 @@
+/** @file
+
+This file contains the delarations for componet name routines.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _COMPONENT_NAME_H_
+#define _COMPONENT_NAME_H_
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 3066 or ISO 639-2 language code format.
+
+  @param  DriverName[out]       A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+SDMediaDeviceGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **DriverName
+  );
+
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  ControllerHandle[in]  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+
+  @param  ChildHandle[in]       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 3066 or ISO 639-2 language code format.
+
+  @param  ControllerName[out]   A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                controller specified by ControllerHandle and
+                                ChildHandle in the language specified by
+                                Language from the point of view of the driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+SDMediaDeviceGetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
+  IN  EFI_HANDLE                                      ControllerHandle,
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
+  IN  CHAR8                                           *Language,
+  OUT CHAR16                                          **ControllerName
+  );
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/MMCSDBlockIo.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/MMCSDBlockIo.c
new file mode 100644
index 0000000000..da6202983b
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/MMCSDBlockIo.c
@@ -0,0 +1,538 @@
+/** @file
+
+Block I/O protocol for MMC/SD device
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SDMediaDevice.h"
+
+/**
+  Implements EFI_BLOCK_IO_PROTOCOL.Reset() function.
+
+  @param  This                   The EFI_BLOCK_IO_PROTOCOL instance.
+  @param  ExtendedVerification   Indicates that the driver may perform a more exhaustive.
+                                 verification operation of the device during reset.
+                                 (This parameter is ingored in this driver.)
+
+  @retval EFI_SUCCESS                Success
+**/
+EFI_STATUS
+EFIAPI
+MMCSDBlockReset (
+  IN  EFI_BLOCK_IO_PROTOCOL   *This,
+  IN  BOOLEAN                 ExtendedVerification
+  )
+{
+  CARD_DATA                  *CardData;
+  EFI_SD_HOST_IO_PROTOCOL    *SDHostIo;
+
+  CardData  = CARD_DATA_FROM_THIS(This);
+  SDHostIo = CardData->SDHostIo;
+
+  return SDHostIo->ResetSDHost (SDHostIo, Reset_DAT_CMD);
+ }
+
+/**
+  Implements EFI_BLOCK_IO_PROTOCOL.ReadBlocks() function.
+
+  @param  This                   The EFI_BLOCK_IO_PROTOCOL instance.
+  @param  MediaId                The media id that the write request is for.
+  @param  LBA                    The starting logical block address to read from on the device.
+                                 The caller is responsible for writing to only legitimate locations.
+  @param  BufferSize             The size of the Buffer in bytes. This must be a multiple of the
+                                 intrinsic block size of the device.
+  @param  Buffer                 A pointer to the destination buffer for the data. The caller
+                                 is responsible for either having implicit or explicit ownership
+                                 of the buffer.
+
+  @retval EFI_SUCCESS                Success
+  @retval EFI_DEVICE_ERROR           Hardware Error
+  @retval EFI_INVALID_PARAMETER      Parameter is error
+  @retval EFI_NO_MEDIA               No media
+  @retval EFI_MEDIA_CHANGED          Media Change
+  @retval EFI_BAD_BUFFER_SIZE        Buffer size is bad
+**/
+EFI_STATUS
+EFIAPI
+MMCSDBlockReadBlocks (
+  IN  EFI_BLOCK_IO_PROTOCOL   *This,
+  IN  UINT32                  MediaId,
+  IN  EFI_LBA                 LBA,
+  IN  UINTN                   BufferSize,
+  OUT VOID                    *Buffer
+  )
+{
+  EFI_STATUS                  Status;
+  UINT32                      Address;
+  CARD_DATA                   *CardData;
+  EFI_SD_HOST_IO_PROTOCOL     *SDHostIo;
+  UINT32                      RemainingLength;
+  UINT32                      TransferLength;
+  UINT8                       *BufferPointer;
+  BOOLEAN                     SectorAddressing;
+  UINTN                       TotalBlock;
+
+  DEBUG((EFI_D_INFO, "Read(LBA=%08lx, Buffer=%08x, Size=%08x)\n", LBA, Buffer, BufferSize));
+  Status   = EFI_SUCCESS;
+  CardData  = CARD_DATA_FROM_THIS(This);
+  SDHostIo = CardData->SDHostIo;
+  if (MediaId != CardData->BlockIoMedia.MediaId) {
+    return EFI_MEDIA_CHANGED;
+  }
+
+  if (ModU64x32 (BufferSize,CardData->BlockIoMedia.BlockSize) != 0) {
+    return EFI_BAD_BUFFER_SIZE;
+  }
+  if ((CardData->CardType == SDMemoryCard2High) || (CardData->CardType == MMCCardHighCap)) {
+    SectorAddressing = TRUE;
+  } else {
+    SectorAddressing = FALSE;
+  }
+  if (SectorAddressing) {
+    //
+    //Block Address
+    //
+    Address = (UINT32)DivU64x32 (MultU64x32 (LBA, CardData->BlockIoMedia.BlockSize), 512);
+  } else {
+    //
+    //Byte Address
+    //
+    Address  = (UINT32)MultU64x32 (LBA, CardData->BlockIoMedia.BlockSize);
+  }
+  TotalBlock = (UINTN) DivU64x32 (BufferSize, CardData->BlockIoMedia.BlockSize);
+  if (LBA + TotalBlock > CardData->BlockIoMedia.LastBlock + 1) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+
+  if (!Buffer) {
+    Status = EFI_INVALID_PARAMETER;
+    DEBUG ((EFI_D_ERROR, "MMCSDBlockReadBlocks:Invalid parameter \r\n"));
+    goto Done;
+  }
+
+  if ((BufferSize % CardData->BlockIoMedia.BlockSize) != 0) {
+    Status = EFI_BAD_BUFFER_SIZE;
+    DEBUG ((EFI_D_ERROR, "MMCSDBlockReadBlocks: Bad buffer size \r\n"));
+    goto Done;
+  }
+
+  if (BufferSize == 0) {
+    Status = EFI_SUCCESS;
+    goto Done;
+  }
+
+
+
+
+    BufferPointer   = Buffer;
+    RemainingLength = (UINT32)BufferSize;
+
+    while (RemainingLength > 0) {
+    if ((BufferSize > CardData->BlockIoMedia.BlockSize)) {
+      if (RemainingLength > SDHostIo->HostCapability.BoundarySize) {
+        TransferLength = SDHostIo->HostCapability.BoundarySize;
+      } else {
+        TransferLength = RemainingLength;
+      }
+
+      if (CardData->CardType == MMCCard || CardData->CardType == MMCCardHighCap) {
+        if (!(CardData->ExtCSDRegister.CARD_TYPE & (BIT2 | BIT3))) {
+      Status = SendCommand (
+                     CardData,
+                     SET_BLOCKLEN,
+                     CardData->BlockIoMedia.BlockSize,
+                     NoData,
+                     NULL,
+                     0,
+                     ResponseR1,
+                     TIMEOUT_COMMAND,
+                     (UINT32*)&(CardData->CardStatus)
+                     );
+          if (EFI_ERROR (Status)) {
+            break;
+          }
+        }
+        Status = SendCommand (
+                   CardData,
+                   SET_BLOCK_COUNT,
+                   TransferLength / CardData->BlockIoMedia.BlockSize,
+                   NoData,
+                   NULL,
+                   0,
+                   ResponseR1,
+                   TIMEOUT_COMMAND,
+                   (UINT32*)&(CardData->CardStatus)
+                   );
+        if (EFI_ERROR (Status)) {
+          break;
+        }
+      }
+      Status = SendCommand (
+                 CardData,
+                 READ_MULTIPLE_BLOCK,
+                 Address,
+                 InData,
+                 CardData->AlignedBuffer,
+                 TransferLength,
+                 ResponseR1,
+                 TIMEOUT_DATA,
+                 (UINT32*)&(CardData->CardStatus)
+                 );
+
+      if (EFI_ERROR (Status)) {
+        DEBUG ((EFI_D_ERROR, "MMCSDBlockReadBlocks: READ_MULTIPLE_BLOCK -> Fail\n"));
+        break;
+      }
+    } else {
+      if (RemainingLength > CardData->BlockIoMedia.BlockSize) {
+        TransferLength = CardData->BlockIoMedia.BlockSize;
+      } else {
+        TransferLength = RemainingLength;
+      }
+
+      Status = SendCommand (
+                 CardData,
+                 READ_SINGLE_BLOCK,
+                 Address,
+                 InData,
+                 CardData->AlignedBuffer,
+                 (UINT32)TransferLength,
+                 ResponseR1,
+                 TIMEOUT_DATA,
+                 (UINT32*)&(CardData->CardStatus)
+                 );
+      if (EFI_ERROR (Status)) {
+        DEBUG ((EFI_D_ERROR, "MMCSDBlockReadBlocks: READ_SINGLE_BLOCK -> Fail\n"));
+        break;
+      }
+    }
+      CopyMem (BufferPointer, CardData->AlignedBuffer, TransferLength);
+
+    if (SectorAddressing) {
+        //
+        //Block Address
+        //
+        Address += TransferLength / 512;
+      } else {
+        //
+        //Byte Address
+        //
+        Address += TransferLength;
+      }
+      BufferPointer   += TransferLength;
+      RemainingLength -= TransferLength;
+   }
+
+
+  if (EFI_ERROR (Status)) {
+    if ((CardData->CardType == SDMemoryCard) ||
+        (CardData->CardType == SDMemoryCard2)||
+        (CardData->CardType == SDMemoryCard2High)) {
+         SendCommand (
+           CardData,
+           STOP_TRANSMISSION,
+           0,
+           NoData,
+           NULL,
+           0,
+           ResponseR1b,
+           TIMEOUT_COMMAND,
+           (UINT32*)&(CardData->CardStatus)
+           );
+    } else {
+       SendCommand (
+         CardData,
+         STOP_TRANSMISSION,
+         0,
+         NoData,
+         NULL,
+         0,
+         ResponseR1,
+         TIMEOUT_COMMAND,
+         (UINT32*)&(CardData->CardStatus)
+         );
+    }
+
+  }
+
+
+Done:
+  DEBUG((EFI_D_INFO, "MMCSDBlockReadBlocks: Status = %r\n", Status));
+  return Status;
+}
+
+/**
+  Implements EFI_BLOCK_IO_PROTOCOL.WriteBlocks() function.
+
+  @param  This                   The EFI_BLOCK_IO_PROTOCOL instance.
+  @param  MediaId                The media id that the write request is for.
+  @param  LBA                    The starting logical block address to read from on the device.
+                                 The caller is responsible for writing to only legitimate locations.
+  @param  BufferSize             The size of the Buffer in bytes. This must be a multiple of the
+                                 intrinsic block size of the device.
+  @param  Buffer                 A pointer to the destination buffer for the data. The caller
+                                 is responsible for either having implicit or explicit ownership
+                                 of the buffer.
+
+  @retval EFI_SUCCESS                Success
+  @retval EFI_DEVICE_ERROR           Hardware Error
+  @retval EFI_INVALID_PARAMETER      Parameter is error
+  @retval EFI_NO_MEDIA               No media
+  @retval EFI_MEDIA_CHANGED          Media Change
+  @retval EFI_BAD_BUFFER_SIZE        Buffer size is bad
+**/
+EFI_STATUS
+EFIAPI
+MMCSDBlockWriteBlocks (
+  IN  EFI_BLOCK_IO_PROTOCOL   *This,
+  IN  UINT32                  MediaId,
+  IN  EFI_LBA                 LBA,
+  IN  UINTN                   BufferSize,
+  IN  VOID                    *Buffer
+  )
+{
+  EFI_STATUS                  Status;
+  UINT32                      Address;
+  CARD_DATA                   *CardData;
+  EFI_SD_HOST_IO_PROTOCOL     *SDHostIo;
+  UINT32                      RemainingLength;
+  UINT32                      TransferLength;
+  UINT8                       *BufferPointer;
+  BOOLEAN                     SectorAddressing;
+
+  DEBUG((EFI_D_INFO, "Write(LBA=%08lx, Buffer=%08x, Size=%08x)\n", LBA, Buffer, BufferSize));
+  Status   = EFI_SUCCESS;
+  CardData  = CARD_DATA_FROM_THIS(This);
+  SDHostIo = CardData->SDHostIo;
+  if ((CardData->CardType == SDMemoryCard2High) || (CardData->CardType == MMCCardHighCap)) {
+    SectorAddressing = TRUE;
+  } else {
+    SectorAddressing = FALSE;
+  }
+  if (SectorAddressing) {
+    //
+    //Block Address
+    //
+    Address = (UINT32)DivU64x32 (MultU64x32 (LBA, CardData->BlockIoMedia.BlockSize), 512);
+  } else {
+    //
+    //Byte Address
+    //
+    Address = (UINT32)MultU64x32 (LBA, CardData->BlockIoMedia.BlockSize);
+  }
+
+  if (!Buffer) {
+    Status = EFI_INVALID_PARAMETER;
+    DEBUG ((EFI_D_ERROR, "MMCSDBlockWriteBlocks: Invalid parameter \r\n"));
+    goto Done;
+  }
+
+  if ((BufferSize % CardData->BlockIoMedia.BlockSize) != 0) {
+    Status = EFI_BAD_BUFFER_SIZE;
+    DEBUG ((EFI_D_ERROR, "MMCSDBlockWriteBlocks: Bad buffer size \r\n"));
+    goto Done;
+  }
+
+  if (BufferSize == 0) {
+    Status = EFI_SUCCESS;
+    goto Done;
+  }
+
+  if (This->Media->ReadOnly == TRUE) {
+    Status = EFI_WRITE_PROTECTED;
+    DEBUG ((EFI_D_ERROR, "MMCSDBlockWriteBlocks: Write protected \r\n"));
+    goto Done;
+  }
+
+
+
+    BufferPointer   = Buffer;
+    RemainingLength = (UINT32)BufferSize;
+
+    while (RemainingLength > 0) {
+    if ((BufferSize > CardData->BlockIoMedia.BlockSize) ) {
+      if (RemainingLength > SDHostIo->HostCapability.BoundarySize) {
+        TransferLength = SDHostIo->HostCapability.BoundarySize;
+      } else {
+        TransferLength = RemainingLength;
+      }
+
+      if (CardData->CardType == MMCCard || CardData->CardType == MMCCardHighCap) {
+
+        if (!(CardData->ExtCSDRegister.CARD_TYPE & (BIT2 | BIT3)))  {
+            Status = SendCommand (
+                       CardData,
+                       SET_BLOCKLEN,
+                       CardData->BlockIoMedia.BlockSize,
+                       NoData,
+                       NULL,
+                       0,
+                       ResponseR1,
+                       TIMEOUT_COMMAND,
+                       (UINT32*)&(CardData->CardStatus)
+                       );
+            if (EFI_ERROR (Status)) {
+              break;
+            }
+        }
+        Status = SendCommand (
+                      CardData,
+                   SET_BLOCK_COUNT,
+                   TransferLength / CardData->BlockIoMedia.BlockSize,
+                      NoData,
+                      NULL,
+                      0,
+                      ResponseR1,
+                      TIMEOUT_COMMAND,
+                      (UINT32*)&(CardData->CardStatus)
+                      );
+        if (EFI_ERROR (Status)) {
+          break;
+        }
+      }
+
+      CopyMem (CardData->AlignedBuffer, BufferPointer, TransferLength);
+
+      Status = SendCommand (
+                 CardData,
+                 WRITE_MULTIPLE_BLOCK,
+                 Address,
+                 OutData,
+                 CardData->AlignedBuffer,
+                 (UINT32)TransferLength,
+                 ResponseR1,
+                 TIMEOUT_DATA,
+                 (UINT32*)&(CardData->CardStatus)
+                 );
+      if (EFI_ERROR (Status)) {
+        DEBUG ((EFI_D_ERROR, "MMCSDBlockWriteBlocks: WRITE_MULTIPLE_BLOCK -> Fail\n"));
+        break;
+      }
+    } else {
+      if (RemainingLength > CardData->BlockIoMedia.BlockSize) {
+        TransferLength = CardData->BlockIoMedia.BlockSize;
+      } else {
+        TransferLength = RemainingLength;
+      }
+
+      CopyMem (CardData->AlignedBuffer, BufferPointer, TransferLength);
+
+      Status = SendCommand (
+                 CardData,
+                 WRITE_BLOCK,
+                 Address,
+                 OutData,
+                 CardData->AlignedBuffer,
+                 (UINT32)TransferLength,
+                 ResponseR1,
+                 TIMEOUT_DATA,
+                 (UINT32*)&(CardData->CardStatus)
+                 );
+    }
+    if (SectorAddressing) {
+        //
+        //Block Address
+        //
+        Address += TransferLength / 512;
+      } else {
+        //
+        //Byte Address
+        //
+        Address += TransferLength;
+      }
+      BufferPointer   += TransferLength;
+      RemainingLength -= TransferLength;
+
+  }
+
+  if (EFI_ERROR (Status)) {
+    SendCommand (
+      CardData,
+      STOP_TRANSMISSION,
+      0,
+      NoData,
+      NULL,
+      0,
+      ResponseR1b,
+      TIMEOUT_COMMAND,
+      (UINT32*)&(CardData->CardStatus)
+      );
+
+  }
+
+
+Done:
+  return EFI_SUCCESS;
+}
+
+/**
+  Implements EFI_BLOCK_IO_PROTOCOL.FlushBlocks() function.
+    (In this driver, this function just returns EFI_SUCCESS.)
+
+  @param  This                   The EFI_BLOCK_IO_PROTOCOL instance.
+
+  @retval EFI_SUCCESS
+  @retval Others
+**/
+EFI_STATUS
+EFIAPI
+MMCSDBlockFlushBlocks (
+  IN  EFI_BLOCK_IO_PROTOCOL   *This
+  )
+{
+  return EFI_SUCCESS;
+}
+
+
+/**
+  MMC/SD card BlockIo init function.
+
+  @param  CardData               Pointer to CARD_DATA.
+
+  @retval EFI_SUCCESS
+  @retval Others
+**/
+EFI_STATUS
+MMCSDBlockIoInit (
+  IN  CARD_DATA    *CardData
+  )
+{
+  //
+  //BlockIO protocol
+  //
+  CardData->BlockIo.Revision    = EFI_BLOCK_IO_PROTOCOL_REVISION;
+  CardData->BlockIo.Media       = &(CardData->BlockIoMedia);
+  CardData->BlockIo.Reset       = MMCSDBlockReset;
+  CardData->BlockIo.ReadBlocks  = MMCSDBlockReadBlocks ;
+  CardData->BlockIo.WriteBlocks = MMCSDBlockWriteBlocks;
+  CardData->BlockIo.FlushBlocks = MMCSDBlockFlushBlocks;
+
+  CardData->BlockIoMedia.MediaId          = 0;
+  CardData->BlockIoMedia.RemovableMedia   = FALSE;
+  CardData->BlockIoMedia.MediaPresent     = TRUE;
+  CardData->BlockIoMedia.LogicalPartition = FALSE;
+
+  if (CardData->CSDRegister.PERM_WRITE_PROTECT || CardData->CSDRegister.TMP_WRITE_PROTECT) {
+    CardData->BlockIoMedia.ReadOnly         = TRUE;
+  } else {
+    CardData->BlockIoMedia.ReadOnly         = FALSE;
+  }
+
+
+  CardData->BlockIoMedia.WriteCaching     = FALSE;
+  CardData->BlockIoMedia.BlockSize        = CardData->BlockLen;
+  CardData->BlockIoMedia.IoAlign          = 1;
+  CardData->BlockIoMedia.LastBlock        = (EFI_LBA)(CardData->BlockNumber - 1);
+
+
+  return EFI_SUCCESS;
+
+}
+
+
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/MMCSDTransfer.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/MMCSDTransfer.c
new file mode 100644
index 0000000000..65b71a008c
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/MMCSDTransfer.c
@@ -0,0 +1,1708 @@
+/** @file
+
+MMC/SD transfer specific functions
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SDMediaDevice.h"
+
+/**
+  Check card status, print the debug info and check the error
+
+  @param  Status                Status got from card status register.
+
+  @retval EFI_SUCCESS
+  @retval EFI_DEVICE_ERROR
+
+**/
+EFI_STATUS
+CheckCardStatus (
+  IN  UINT32    Status
+  )
+{
+  CARD_STATUS    *CardStatus;
+  CardStatus = (CARD_STATUS*)(&Status);
+
+  if (CardStatus->ADDRESS_OUT_OF_RANGE) {
+    DEBUG ((EFI_D_ERROR, "CardStatus: ADDRESS_OUT_OF_RANGE\n"));
+  }
+
+  if (CardStatus->ADDRESS_MISALIGN) {
+    DEBUG ((EFI_D_ERROR, "CardStatus: ADDRESS_MISALIGN\n"));
+  }
+
+  if (CardStatus->BLOCK_LEN_ERROR) {
+    DEBUG ((EFI_D_ERROR, "CardStatus: BLOCK_LEN_ERROR\n"));
+  }
+
+  if (CardStatus->ERASE_SEQ_ERROR) {
+    DEBUG ((EFI_D_ERROR, "CardStatus: ERASE_SEQ_ERROR\n"));
+  }
+
+  if (CardStatus->ERASE_PARAM) {
+    DEBUG ((EFI_D_ERROR, "CardStatus: ERASE_PARAM\n"));
+  }
+
+  if (CardStatus->WP_VIOLATION) {
+    DEBUG ((EFI_D_ERROR, "CardStatus: WP_VIOLATION\n"));
+  }
+
+  if (CardStatus->CARD_IS_LOCKED) {
+    DEBUG ((EFI_D_ERROR, "CardStatus: CARD_IS_LOCKED\n"));
+  }
+
+  if (CardStatus->LOCK_UNLOCK_FAILED) {
+    DEBUG ((EFI_D_ERROR, "CardStatus: LOCK_UNLOCK_FAILED\n"));
+  }
+
+  if (CardStatus->COM_CRC_ERROR) {
+    DEBUG ((EFI_D_ERROR, "CardStatus: COM_CRC_ERROR\n"));
+  }
+
+  if (CardStatus->ILLEGAL_COMMAND) {
+    DEBUG ((EFI_D_ERROR, "CardStatus: ILLEGAL_COMMAND\n"));
+  }
+
+  if (CardStatus->CARD_ECC_FAILED) {
+    DEBUG ((EFI_D_ERROR, "CardStatus: CARD_ECC_FAILED\n"));
+  }
+
+  if (CardStatus->CC_ERROR) {
+    DEBUG ((EFI_D_ERROR, "CardStatus: CC_ERROR\n"));
+  }
+
+  if (CardStatus->ERROR) {
+    DEBUG ((EFI_D_ERROR, "CardStatus: ERROR\n"));
+  }
+
+  if (CardStatus->UNDERRUN) {
+    DEBUG ((EFI_D_ERROR, "CardStatus: UNDERRUN\n"));
+  }
+
+  if (CardStatus->OVERRUN) {
+    DEBUG ((EFI_D_ERROR, "CardStatus: OVERRUN\n"));
+  }
+
+  if (CardStatus->CID_CSD_OVERWRITE) {
+    DEBUG ((EFI_D_ERROR, "CardStatus: CID_CSD_OVERWRITE\n"));
+  }
+
+  if (CardStatus->WP_ERASE_SKIP) {
+    DEBUG ((EFI_D_ERROR, "CardStatus: WP_ERASE_SKIP\n"));
+  }
+
+  if (CardStatus->ERASE_RESET) {
+    DEBUG ((EFI_D_ERROR, "CardStatus: ERASE_RESET\n"));
+  }
+
+  if (CardStatus->SWITCH_ERROR) {
+    DEBUG ((EFI_D_ERROR, "CardStatus: SWITCH_ERROR\n"));
+  }
+
+  if ((Status & 0xFCFFA080) != 0) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Send command by using Host IO protocol
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  CommandIndex          The command index to set the command index field of command register.
+  @param  Argument              Command argument to set the argument field of command register.
+  @param  DataType              TRANSFER_TYPE, indicates no data, data in or data out.
+  @param  Buffer                Contains the data read from / write to the device.
+  @param  BufferSize            The size of the buffer.
+  @param  ResponseType          RESPONSE_TYPE.
+  @param  TimeOut               Time out value in 1 ms unit.
+  @param  ResponseData          Depending on the ResponseType, such as CSD or card status.
+
+  @retval EFI_SUCCESS
+  @retval EFI_INVALID_PARAMETER
+  @retval EFI_UNSUPPORTED
+  @retval EFI_DEVICE_ERROR
+
+**/
+EFI_STATUS
+SendCommand (
+  IN   CARD_DATA                  *CardData,
+  IN   UINT16                     CommandIndex,
+  IN   UINT32                     Argument,
+  IN   TRANSFER_TYPE              DataType,
+  IN   UINT8                      *Buffer, OPTIONAL
+  IN   UINT32                     BufferSize,
+  IN   RESPONSE_TYPE              ResponseType,
+  IN   UINT32                     TimeOut,
+  OUT  UINT32                     *ResponseData
+  )
+{
+
+  EFI_STATUS    Status;
+  EFI_SD_HOST_IO_PROTOCOL    *SDHostIo;
+  SDHostIo = CardData->SDHostIo;
+  if (CardData->CardType != MMCCard && CardData->CardType != MMCCardHighCap) {
+    CommandIndex |= AUTO_CMD12_ENABLE;
+  }
+
+  Status = SDHostIo->SendCommand (
+                   SDHostIo,
+                   CommandIndex,
+                   Argument,
+                   DataType,
+                   Buffer,
+                   BufferSize,
+                   ResponseType,
+                   TimeOut,
+                   ResponseData
+                   );
+  if (!EFI_ERROR (Status)) {
+    if (ResponseType == ResponseR1 || ResponseType == ResponseR1b) {
+      ASSERT(ResponseData != NULL);
+      Status = CheckCardStatus (*ResponseData);
+    }
+  } else {
+    SDHostIo->ResetSDHost (SDHostIo, Reset_DAT_CMD);
+  }
+
+  return Status;
+}
+
+/**
+  Send the card APP_CMD command with the following command indicated by CommandIndex
+
+  @param  CardData              Pointer to CARD_DATA.
+  @param  CommandIndex          The command index to set the command index field of command register.
+  @param  Argument              Command argument to set the argument field of command register.
+  @param  DataType              TRANSFER_TYPE, indicates no data, data in or data out.
+  @param  Buffer                Contains the data read from / write to the device.
+  @param  BufferSize            The size of the buffer.
+  @param  ResponseType          RESPONSE_TYPE.
+  @param  TimeOut               Time out value in 1 ms unit.
+  @param  ResponseData          Depending on the ResponseType, such as CSD or card status.
+
+  @retval EFI_SUCCESS
+  @retval EFI_INVALID_PARAMETER
+  @retval EFI_UNSUPPORTED
+  @retval EFI_DEVICE_ERROR
+
+**/
+EFI_STATUS
+SendAppCommand (
+  IN   CARD_DATA                  *CardData,
+  IN   UINT16                     CommandIndex,
+  IN   UINT32                     Argument,
+  IN   TRANSFER_TYPE              DataType,
+  IN   UINT8                      *Buffer, OPTIONAL
+  IN   UINT32                     BufferSize,
+  IN   RESPONSE_TYPE              ResponseType,
+  IN   UINT32                     TimeOut,
+  OUT  UINT32                     *ResponseData
+  )
+{
+
+  EFI_STATUS                 Status;
+  EFI_SD_HOST_IO_PROTOCOL    *SDHostIo;
+  UINT8                      Index;
+
+  SDHostIo = CardData->SDHostIo;
+  Status = EFI_SUCCESS;
+
+  for (Index = 0; Index < 2; Index++) {
+    Status = SDHostIo->SendCommand (
+                         SDHostIo,
+                         APP_CMD,
+                         (CardData->Address << 16),
+                         NoData,
+                         NULL,
+                         0,
+                         ResponseR1,
+                         TIMEOUT_COMMAND,
+                         (UINT32*)&(CardData->CardStatus)
+                         );
+    if (!EFI_ERROR (Status)) {
+        Status = CheckCardStatus (*(UINT32*)&(CardData->CardStatus));
+        if (CardData->CardStatus.SAPP_CMD != 1) {
+          Status = EFI_DEVICE_ERROR;
+        }
+        if (!EFI_ERROR (Status)) {
+           break;
+        }
+    } else {
+       SDHostIo->ResetSDHost (SDHostIo, Reset_Auto);
+    }
+  }
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  if (CardData->CardType != MMCCard && CardData->CardType != MMCCardHighCap) {
+    CommandIndex |= AUTO_CMD12_ENABLE;
+  }
+
+  Status = SDHostIo->SendCommand (
+                       SDHostIo,
+                       CommandIndex,
+                       Argument,
+                       DataType,
+                       Buffer,
+                       BufferSize,
+                       ResponseType,
+                       TimeOut,
+                       ResponseData
+                       );
+  if (!EFI_ERROR (Status)) {
+    if (ResponseType == ResponseR1 || ResponseType == ResponseR1b) {
+      ASSERT(ResponseData != NULL);
+      Status = CheckCardStatus (*ResponseData);
+    }
+  } else {
+    SDHostIo->ResetSDHost (SDHostIo, Reset_Auto);
+  }
+
+  return Status;
+}
+
+
+/**
+  Send the card FAST_IO command
+
+  @param  CardData               Pointer to CARD_DATA.
+  @param  RegisterAddress        Register Address.
+  @param  RegisterData           Pointer to register Data.
+  @param  Write                  TRUE for write, FALSE for read.
+
+  @retval EFI_SUCCESS
+  @retval EFI_UNSUPPORTED
+  @retval EFI_INVALID_PARAMETER
+  @retval EFI_DEVICE_ERROR
+
+**/
+EFI_STATUS
+FastIO (
+  IN      CARD_DATA   *CardData,
+  IN      UINT8       RegisterAddress,
+  IN  OUT UINT8       *RegisterData,
+  IN      BOOLEAN     Write
+  )
+{
+  EFI_STATUS                 Status;
+  UINT32                     Argument;
+  UINT32                     Data;
+
+  Status   = EFI_SUCCESS;
+
+  if (RegisterData == NULL) {
+    Status = EFI_INVALID_PARAMETER;
+    goto Exit;
+  }
+
+  Argument = (CardData->Address << 16) | (RegisterAddress << 8);
+  if (Write) {
+    Argument |= BIT15 | (*RegisterData);
+  }
+
+  Status = SendCommand (
+             CardData,
+             FAST_IO,
+             Argument,
+             NoData,
+             NULL,
+             0,
+             ResponseR4,
+             TIMEOUT_COMMAND,
+             &Data
+             );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  if ((Data & BIT15) == 0) {
+    Status = EFI_DEVICE_ERROR;
+    goto Exit;
+  }
+
+  if (!Write) {
+   *RegisterData = (UINT8)Data;
+  }
+
+Exit:
+  return Status;
+}
+
+/**
+  Send the card GO_INACTIVE_STATE command.
+
+  @param  CardData             Pointer to CARD_DATA.
+
+  @return EFI_SUCCESS
+  @return others
+
+**/
+EFI_STATUS
+PutCardInactive (
+  IN  CARD_DATA   *CardData
+  )
+{
+  EFI_STATUS                 Status;
+
+
+  Status = SendCommand (
+             CardData,
+             GO_INACTIVE_STATE,
+             (CardData->Address << 16),
+             NoData,
+             NULL,
+             0,
+             ResponseNo,
+             TIMEOUT_COMMAND,
+             NULL
+             );
+
+  return Status;
+
+}
+
+/**
+  Get card interested information for CSD rergister
+
+  @param  CardData               Pointer to CARD_DATA.
+
+  @retval EFI_SUCCESS
+  @retval EFI_UNSUPPORTED
+  @retval EFI_INVALID_PARAMETER
+
+**/
+EFI_STATUS
+CaculateCardParameter (
+  IN  CARD_DATA    *CardData
+  )
+{
+  EFI_STATUS     Status;
+  UINT32         Frequency;
+  UINT32         Multiple;
+  UINT32         CSize;
+  CSD_SDV2       *CsdSDV2;
+
+  Status = EFI_SUCCESS;
+
+  switch (CardData->CSDRegister.TRAN_SPEED & 0x7) {
+    case 0:
+      Frequency = 100 * 1000;
+      break;
+
+    case 1:
+      Frequency = 1 * 1000 * 1000;
+      break;
+
+    case 2:
+      Frequency = 10 * 1000 * 1000;
+      break;
+
+    case 3:
+      Frequency = 100 * 1000 * 1000;
+      break;
+
+    default:
+      Status = EFI_INVALID_PARAMETER;
+      goto Exit;
+  }
+
+  switch ((CardData->CSDRegister.TRAN_SPEED >> 3) & 0xF) {
+    case 1:
+      Multiple = 10;
+      break;
+
+    case 2:
+      Multiple = 12;
+      break;
+
+    case 3:
+      Multiple = 13;
+      break;
+
+    case 4:
+      Multiple = 15;
+      break;
+
+    case 5:
+      Multiple = 20;
+      break;
+
+    case 6:
+      if (CardData->CardType == MMCCard  || CardData->CardType == MMCCardHighCap) {
+        Multiple = 26;
+      } else {
+        Multiple = 25;
+      }
+      break;
+
+    case 7:
+      Multiple = 30;
+      break;
+
+    case 8:
+      Multiple = 35;
+      break;
+
+    case 9:
+      Multiple = 40;
+      break;
+
+    case 10:
+      Multiple = 45;
+      break;
+
+    case 11:
+      if (CardData->CardType == MMCCard  || CardData->CardType == MMCCardHighCap) {
+        Multiple = 52;
+      } else {
+        Multiple = 50;
+      }
+      break;
+
+    case 12:
+      Multiple = 55;
+      break;
+
+    case 13:
+      Multiple = 60;
+      break;
+
+    case 14:
+      Multiple = 70;
+      break;
+
+    case 15:
+      Multiple = 80;
+      break;
+
+    default:
+      Status = EFI_INVALID_PARAMETER;
+      goto Exit;
+  }
+
+  Frequency = Frequency * Multiple / 10;
+  CardData->MaxFrequency = Frequency;
+
+  CardData->BlockLen = 1 << CardData->CSDRegister.READ_BL_LEN;
+
+  if (CardData->CardType == SDMemoryCard2High) {
+    ASSERT(CardData->CSDRegister.CSD_STRUCTURE == 1);
+    CsdSDV2 = (CSD_SDV2*)&CardData->CSDRegister;
+    //
+    // The SD Spec 2.0 says (CSize + 1) * 512K is the total size, so block numbber is (CSize + 1) * 1K
+    // the K here means 1024 not 1000
+    //
+    CardData->BlockNumber = DivU64x32 (MultU64x32 (CsdSDV2->C_SIZE + 1, 512 * 1024) , CardData->BlockLen);
+  } else {
+    //
+    // For MMC card > 2G, the block number will be recaculate later
+    //
+    CSize = CardData->CSDRegister.C_SIZELow2 | (CardData->CSDRegister.C_SIZEHigh10 << 2);
+    CardData->BlockNumber = MultU64x32 (LShiftU64 (1, CardData->CSDRegister.C_SIZE_MULT + 2), CSize + 1);
+  }
+
+  //
+  //For >= 2G card, BlockLen may be 1024, but the transfer size is still 512 bytes
+  //
+  if (CardData->BlockLen > 512) {
+    CardData->BlockNumber = DivU64x32 (MultU64x32 (CardData->BlockNumber, CardData->BlockLen), 512);
+    CardData->BlockLen    = 512;
+  }
+
+  DEBUG((
+    EFI_D_INFO,
+          "CalculateCardParameter: Card Size: 0x%lx\n", MultU64x32 (CardData->BlockNumber, CardData->BlockLen)
+    ));
+
+Exit:
+  return Status;
+}
+
+/**
+  Test the bus width setting for MMC card.It is used only for verification purpose.
+
+  @param  CardData               Pointer to CARD_DATA.
+  @param  Width                  1, 4, 8 bits.
+
+  @retval EFI_SUCCESS
+  @retval EFI_UNSUPPORTED
+  @retval EFI_INVALID_PARAMETER
+
+**/
+EFI_STATUS
+MMCCardBusWidthTest (
+  IN  CARD_DATA             *CardData,
+  IN  UINT32                Width
+  )
+{
+  EFI_STATUS                 Status;
+  UINT64                     Data;
+  UINT64                     Value;
+
+  ASSERT(CardData != NULL);
+
+
+  Value = 0;
+
+  switch (Width) {
+    case 1:
+      Data = 0x80;
+      break;
+
+    case 4:
+      Data = 0x5A;
+      break;
+
+    case 8:
+      Data = 0xAA55;
+      break;
+
+    default:
+      Status = EFI_INVALID_PARAMETER;
+      goto Exit;
+  }
+
+  CopyMem (CardData->AlignedBuffer, &Data, Width);
+  Status  = SendCommand (
+              CardData,
+              BUSTEST_W,
+              0,
+              OutData,
+              CardData->AlignedBuffer,
+              Width,
+              ResponseR1,
+              TIMEOUT_COMMAND,
+              (UINT32*)&(CardData->CardStatus)
+              );
+  if (EFI_ERROR (Status)) {
+    DEBUG((EFI_D_ERROR, "MMCCardBusWidthTest:SendCommand BUSTEST_W 0x%x\n", *(UINT32*)&(CardData->CardStatus)));
+    goto Exit;
+  }
+
+  gBS->Stall (10 * 1000);
+
+  Data = 0;
+
+  Status  = SendCommand (
+              CardData,
+              BUSTEST_R,
+              0,
+              InData,
+              CardData->AlignedBuffer,
+              Width,
+              ResponseR1,
+              TIMEOUT_COMMAND,
+              (UINT32*)&(CardData->CardStatus)
+              );
+  if (EFI_ERROR (Status)) {
+    DEBUG((EFI_D_ERROR, "MMCCardBusWidthTest:SendCommand BUSTEST_R 0x%x\n", *(UINT32*)&(CardData->CardStatus)));
+    goto Exit;
+  }
+  CopyMem (&Data, CardData->AlignedBuffer, Width);
+
+  switch (Width) {
+    case 1:
+      Value = (~(Data ^ 0x80)) & 0xC0;
+      break;
+    case 4:
+      Value = (~(Data ^ 0x5A)) & 0xFF;
+      break;
+    case 8:
+      Value = (~(Data ^ 0xAA55)) & 0xFFFF;
+      break;
+  }
+
+  if (Value == 0) {
+    Status = EFI_SUCCESS;
+  } else {
+    Status = EFI_UNSUPPORTED;
+  }
+
+
+Exit:
+  return Status;
+}
+
+/**
+  This function can detect these card types:
+    1. MMC card
+    2. SD 1.1 card
+    3. SD 2.0 standard card
+    3. SD 2.0 high capacity card
+
+  @param  CardData             Pointer to CARD_DATA.
+
+  @return EFI_SUCCESS
+  @return others
+
+**/
+EFI_STATUS
+GetCardType (
+  IN  CARD_DATA              *CardData
+  )
+{
+  EFI_STATUS                 Status;
+  EFI_SD_HOST_IO_PROTOCOL    *SDHostIo;
+  UINT32                     Argument;
+  UINT32                     ResponseData;
+  UINT32                     Count;
+  BOOLEAN                    SDCommand8Support;
+
+
+  SDHostIo = CardData->SDHostIo;
+
+  //
+  // Reset the card
+  //
+  Status  = SendCommand (
+              CardData,
+              GO_IDLE_STATE,
+              0,
+              NoData,
+              NULL,
+              0,
+              ResponseNo,
+              TIMEOUT_COMMAND,
+              NULL
+              );
+  if (EFI_ERROR (Status)) {
+    DEBUG((EFI_D_ERROR, "GO_IDLE_STATE Fail Status = 0x%x\n", Status));
+    goto Exit;
+  }
+
+  //
+  //No spec requirment, can be adjusted
+  //
+  gBS->Stall (10 * 1000);
+
+
+  //
+  // Only 2.7V - 3.6V is supported for SD2.0, only SD 2.0 card can pass
+  // MMC and SD1.1 card will fail this command
+  //
+  Argument          = (VOLTAGE_27_36 << 8) | CHECK_PATTERN;
+  ResponseData      = 0;
+  SDCommand8Support = FALSE;
+
+  Status  = SendCommand (
+              CardData,
+              SEND_IF_COND,
+              Argument,
+              NoData,
+              NULL,
+              0,
+              ResponseR7,
+              TIMEOUT_COMMAND,
+              &ResponseData
+              );
+
+  if (EFI_ERROR (Status)) {
+    if (Status != EFI_TIMEOUT) {
+       DEBUG((EFI_D_ERROR, "SEND_IF_COND Fail, none time out error\n"));
+       goto Exit;
+    }
+  } else {
+     if (ResponseData != Argument) {
+       DEBUG((EFI_D_ERROR, "SEND_IF_COND Fail, respond data does not match send data\n"));
+       Status = EFI_DEVICE_ERROR;
+       goto Exit;
+    }
+    SDCommand8Support = TRUE;
+  }
+
+
+  Argument = 0;
+  if (SDHostIo->HostCapability.V30Support == TRUE) {
+    Argument |= BIT17 | BIT18;
+  } else if (SDHostIo->HostCapability.V33Support == TRUE) {
+    Argument |= BIT20 | BIT21;
+  }
+
+  if (SDCommand8Support) {
+    //
+    //If command SD_SEND_OP_COND sucessed, it should be set.
+    // SD 1.1 card will ignore it
+    // SD 2.0 standard card will repsond with CCS 0, SD high capacity card will respond with CCS 1
+    // CCS is BIT30 of OCR
+    Argument |= BIT30;
+  }
+
+
+  Count        = 20;
+  //
+  //Only SD card will respond to this command, and spec says the card only checks condition at first ACMD41 command
+  //
+  do {
+    Status  = SendAppCommand (
+                CardData,
+                SD_SEND_OP_COND,
+                Argument,
+                NoData,
+                NULL,
+                0,
+                ResponseR3,
+                TIMEOUT_COMMAND,
+                (UINT32*)&(CardData->OCRRegister)
+                );
+    if (EFI_ERROR (Status)) {
+      if ((Status == EFI_TIMEOUT) && (!SDCommand8Support)) {
+        CardData->CardType = MMCCard;
+        Status = EFI_SUCCESS;
+        DEBUG((EFI_D_INFO, "SD_SEND_OP_COND, MMC card was identified\n"));
+      } else {
+        //
+        // Not as expected, MMC card should has no response, which means timeout.
+        // SD card should pass this command
+        //
+        DEBUG((EFI_D_ERROR, "SD_SEND_OP_COND Fail, check whether it is neither a MMC card nor a SD card\n"));
+      }
+      goto Exit;
+    }
+    //
+    //Avoid waiting if sucess. Busy bit 0 means not ready
+    //
+    if (CardData->OCRRegister.Busy == 1) {
+      break;
+    }
+
+    gBS->Stall (50 * 1000);
+    Count--;
+    if (Count == 0) {
+      DEBUG((EFI_D_ERROR, "Card is always in busy state\n"));
+      Status = EFI_TIMEOUT;
+      goto Exit;
+    }
+  } while (1);
+
+  //
+  //Check supported voltage
+  //
+  Argument = 0;
+  if (SDHostIo->HostCapability.V30Support == TRUE) {
+    if ((CardData->OCRRegister.V270_V360 & BIT2) == BIT2) {
+      Argument |= BIT17;
+    } else if ((CardData->OCRRegister.V270_V360 & BIT3) == BIT3) {
+      Argument |= BIT18;
+    }
+  } else if (SDHostIo->HostCapability.V33Support == TRUE) {
+     if ((CardData->OCRRegister.V270_V360 & BIT5) == BIT5) {
+       Argument |= BIT20;
+     } else if ((CardData->OCRRegister.V270_V360 & BIT6) == BIT6) {
+       Argument |= BIT21;
+     }
+  }
+
+  if (Argument == 0) {
+     //
+     //No matched support voltage
+     //
+     PutCardInactive (CardData);
+     DEBUG((EFI_D_ERROR, "No matched voltage for this card\n"));
+     Status = EFI_UNSUPPORTED;
+     goto Exit;
+  }
+
+  CardData->CardType = SDMemoryCard;
+  if (SDCommand8Support == TRUE) {
+   CardData->CardType = SDMemoryCard2;
+   DEBUG((EFI_D_INFO, "SD_SEND_OP_COND, SD 2.0 or above standard card was identified\n"));
+  }
+
+  if ((CardData->OCRRegister.AccessMode & BIT1) == BIT1) {
+    CardData->CardType = SDMemoryCard2High;
+    DEBUG((EFI_D_INFO, "SD_SEND_OP_COND, SD 2.0 or above high capacity card was identified\n"));
+  }
+
+
+
+Exit:
+  return Status;
+}
+
+/**
+  MMC card high/low voltage selection function
+
+  @param  CardData               Pointer to CARD_DATA.
+
+  @retval EFI_SUCCESS
+  @retval EFI_INVALID_PARAMETER
+  @retval EFI_UNSUPPORTED
+  @retval EFI_BAD_BUFFER_SIZE
+
+**/
+EFI_STATUS
+MMCCardVoltageSelection (
+  IN  CARD_DATA              *CardData
+  )
+{
+  EFI_STATUS                 Status;
+  UINT8                      Retry;
+  UINT32                     TimeOut;
+
+  Status   = EFI_SUCCESS;
+  //
+  //First try the high voltage, then if supported choose the low voltage
+  //
+
+    for (Retry = 0; Retry < 3; Retry++) {
+      //
+      // To bring back the normal MMC card to work
+      // after sending the SD command. Otherwise some
+      // card could not work
+
+      Status  = SendCommand (
+                CardData,
+                  GO_IDLE_STATE,
+                  0,
+                  NoData,
+                  NULL,
+                  0,
+                  ResponseNo,
+                  TIMEOUT_COMMAND,
+                  NULL
+                  );
+      if (EFI_ERROR (Status)) {
+        DEBUG((EFI_D_ERROR, "GO_IDLE_STATE Fail Status = 0x%x\n", Status));
+        continue;
+      }
+      //
+      //CE-ATA device needs long delay
+      //
+      gBS->Stall ((Retry + 1) * 50 * 1000);
+
+      //
+      //Get OCR register to check voltage support, first time the OCR is 0
+      //
+      Status  = SendCommand (
+                CardData,
+                  SEND_OP_COND,
+                  0,
+                  NoData,
+                  NULL,
+                  0,
+                  ResponseR3,
+                  TIMEOUT_COMMAND,
+                  (UINT32*)&(CardData->OCRRegister)
+                  );
+      if (!EFI_ERROR (Status)) {
+        break;
+      }
+    }
+
+    if (Retry == 3) {
+      DEBUG((EFI_D_ERROR, "SEND_OP_COND Fail Status = 0x%x\n", Status));
+      Status = EFI_DEVICE_ERROR;
+      goto Exit;
+    }
+
+    //
+    //TimeOut Value, 5000 * 100 * 1000 = 5 s
+    //
+    TimeOut = 5000;
+
+    do {
+      Status  = SendCommand (
+                CardData,
+                  SEND_OP_COND,
+                  0x40300000,
+                  NoData,
+                  NULL,
+                  0,
+                  ResponseR3,
+                  TIMEOUT_COMMAND,
+                  (UINT32*)&(CardData->OCRRegister)
+                  );
+      if (EFI_ERROR (Status)) {
+        DEBUG((EFI_D_ERROR, "SEND_OP_COND Fail Status = 0x%x\n", Status));
+        goto Exit;
+      }
+
+      gBS->Stall (1 * 1000);
+      TimeOut--;
+      if (TimeOut == 0) {
+        Status = EFI_TIMEOUT;
+      DEBUG((EFI_D_ERROR, "Card is always in busy state\n"));
+        goto Exit;
+      }
+    } while (CardData->OCRRegister.Busy != 1);
+
+  if (CardData->OCRRegister.AccessMode == 2) // eMMC Card uses Sector Addressing - High Capacity
+    {
+    DEBUG((EFI_D_INFO, "eMMC Card is High Capacity\n"));
+    CardData->CardType = MMCCardHighCap;
+  }
+
+Exit:
+  return Status;
+
+}
+
+/**
+  This function set the bus and device width for MMC card
+
+  @param  CardData               Pointer to CARD_DATA.
+  @param  Width                  1, 4, 8 bits.
+
+  @retval EFI_SUCCESS
+  @retval EFI_UNSUPPORTED
+  @retval EFI_INVALID_PARAMETER
+
+**/
+EFI_STATUS
+MMCCardSetBusWidth (
+  IN  CARD_DATA              *CardData,
+  IN  UINT8                  BusWidth,
+  IN  BOOLEAN                EnableDDRMode
+  )
+{
+  EFI_STATUS                 Status;
+  EFI_SD_HOST_IO_PROTOCOL    *SDHostIo;
+  SWITCH_ARGUMENT            SwitchArgument;
+  UINT8                      Value;
+
+  SDHostIo = CardData->SDHostIo;
+  Value = 0;
+  switch (BusWidth) {
+    case 8:
+      if (EnableDDRMode)
+        Value = 6;
+      else
+      Value = 2;
+      break;
+
+    case 4:
+      if (EnableDDRMode)
+        Value = 5;
+      else
+      Value = 1;
+      break;
+
+    case 1:
+      if (EnableDDRMode)    // Bus width 1 is not supported in ddr mode
+        return EFI_UNSUPPORTED;
+      Value = 0;
+      break;
+
+    default:
+     ASSERT(0);
+  }
+
+
+  ZeroMem(&SwitchArgument, sizeof (SWITCH_ARGUMENT));
+  SwitchArgument.CmdSet = 0;
+  SwitchArgument.Value  = Value;
+  SwitchArgument.Index  = (UINT32)((UINTN)
+  (&(CardData->ExtCSDRegister.BUS_WIDTH)) - (UINTN)(&(CardData->ExtCSDRegister)));
+  SwitchArgument.Access = WriteByte_Mode;
+  Status  = SendCommand (
+              CardData,
+              SWITCH,
+              *(UINT32*)&SwitchArgument,
+              NoData,
+              NULL,
+              0,
+              ResponseR1b,
+              TIMEOUT_COMMAND,
+              (UINT32*)&(CardData->CardStatus)
+              );
+  if (!EFI_ERROR (Status)) {
+     Status  = SendCommand (
+                 CardData,
+                 SEND_STATUS,
+                 (CardData->Address << 16),
+                 NoData,
+                 NULL,
+                 0,
+                 ResponseR1,
+                 TIMEOUT_COMMAND,
+                 (UINT32*)&(CardData->CardStatus)
+                 );
+    if (EFI_ERROR (Status)) {
+      DEBUG((EFI_D_ERROR, "SWITCH %d bits Fail\n", BusWidth));
+      goto Exit;
+    } else {
+      DEBUG((EFI_D_ERROR, "MMCCardSetBusWidth:SWITCH Card Status:0x%x\n", *(UINT32*)&(CardData->CardStatus)));
+      Status = SDHostIo->SetBusWidth (SDHostIo, BusWidth);
+      if (EFI_ERROR (Status)) {
+         DEBUG((EFI_D_ERROR, "SWITCH set %d bits Fail\n", BusWidth));
+         goto Exit;
+      }
+      gBS->Stall (5 * 1000);
+    }
+  }
+
+  if (!EnableDDRMode) {     // CMD19 and CMD14 are illegal commands in ddr mode
+  //if (EFI_ERROR (Status)) {
+  //  DEBUG((EFI_D_ERROR, "MMCCardBusWidthTest: Fail to enable high speed mode\n"));
+  //  goto Exit;
+  //}
+
+  Status = MMCCardBusWidthTest (CardData, BusWidth);
+  if (EFI_ERROR (Status)) {
+    DEBUG((EFI_D_ERROR, "MMCCardBusWidthTest %d bit Fail\n", BusWidth));
+    goto Exit;
+    }
+  }
+
+  CardData->CurrentBusWidth = BusWidth;
+
+Exit:
+  return Status;
+}
+
+
+/**
+  MMC/SD card init function
+
+  @param  CardData             Pointer to CARD_DATA.
+
+  @return EFI_SUCCESS
+  @return others
+
+**/
+EFI_STATUS
+MMCSDCardInit (
+  IN  CARD_DATA              *CardData
+  )
+{
+  EFI_STATUS                 Status;
+  EFI_SD_HOST_IO_PROTOCOL    *SDHostIo;
+  SWITCH_ARGUMENT            SwitchArgument;
+  UINT32                     Data;
+  UINT32                     Argument;
+  UINT32                     nIndex;
+  UINT8                      PowerValue;
+  BOOLEAN                    EnableDDRMode;
+
+  ASSERT(CardData != NULL);
+  SDHostIo                  = CardData->SDHostIo;
+  EnableDDRMode             = FALSE;
+
+  CardData->CardType = UnknownCard;
+  Status = GetCardType (CardData);
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+  DEBUG((DEBUG_INFO, "CardData->CardType  0x%x\n", CardData->CardType));
+
+  ASSERT (CardData->CardType != UnknownCard);
+  //
+  //MMC, SD card need host auto stop command support
+  //
+  SDHostIo->EnableAutoStopCmd (SDHostIo, TRUE);
+
+  if (CardData->CardType == MMCCard) {
+    Status = MMCCardVoltageSelection (CardData);
+    if (EFI_ERROR(Status)) {
+      goto Exit;
+    }
+  }
+
+  //
+  // Get CID Register
+  //
+  Status  = SendCommand (
+              CardData,
+              ALL_SEND_CID,
+              0,
+              NoData,
+              NULL,
+              0,
+              ResponseR2,
+              TIMEOUT_COMMAND,
+              (UINT32*)&(CardData->CIDRegister)
+              );
+  if (EFI_ERROR (Status)) {
+    DEBUG((EFI_D_ERROR, "ALL_SEND_CID Fail Status = 0x%x\n", Status));
+    goto Exit;
+  } else {
+    // Dump out the Card ID data
+    DEBUG((EFI_D_INFO, "Product Name: "));
+    for ( nIndex=0; nIndex<6; nIndex++ ) {
+      DEBUG((EFI_D_INFO, "%c", CardData->CIDRegister.PNM[nIndex]));
+    }
+    DEBUG((EFI_D_INFO, "\nApplication ID : %d\n", CardData->CIDRegister.OID));
+    DEBUG((EFI_D_INFO, "Manufacturer ID: %d\n", CardData->CIDRegister.MID));
+    DEBUG((EFI_D_INFO, "Revision ID    : %d\n", CardData->CIDRegister.PRV));
+    DEBUG((EFI_D_INFO, "Serial Number  : %d\n", CardData->CIDRegister.PSN));
+  }
+
+  //
+  //SET_RELATIVE_ADDR
+  //
+  if (CardData->CardType == MMCCard  || CardData->CardType == MMCCardHighCap) {
+    //
+    //Hard code the RCA address
+    //
+    CardData->Address = 1;
+
+    //
+    // Set RCA Register
+    //
+    Status  = SendCommand (
+                CardData,
+                SET_RELATIVE_ADDR,
+                (CardData->Address << 16),
+                NoData,
+                NULL,
+                0,
+                ResponseR1,
+                TIMEOUT_COMMAND,
+                (UINT32*)&(CardData->CardStatus)
+                );
+    if (EFI_ERROR (Status)) {
+      DEBUG((EFI_D_ERROR, "SET_RELATIVE_ADDR Fail Status = 0x%x\n", Status));
+      goto Exit;
+    }
+  } else {
+    Data = 0;
+    Status  = SendCommand (
+                CardData,
+                SET_RELATIVE_ADDR,
+                0,
+                NoData,
+                NULL,
+                0,
+                ResponseR6,
+                TIMEOUT_COMMAND,
+                &Data
+                );
+    if (EFI_ERROR (Status)) {
+      DEBUG((EFI_D_ERROR, "SET_RELATIVE_ADDR Fail Status = 0x%x\n", Status));
+      goto Exit;
+    }
+
+    CardData->Address = (UINT16)(Data >> 16);
+    *(UINT32*)&CardData->CardStatus      = Data & 0x1FFF;
+    CardData->CardStatus.ERROR           = (Data >> 13) & 0x1;
+    CardData->CardStatus.ILLEGAL_COMMAND = (Data >> 14) & 0x1;
+    CardData->CardStatus.COM_CRC_ERROR   = (Data >> 15) & 0x1;
+    Status = CheckCardStatus (*(UINT32*)&CardData->CardStatus);
+    if (EFI_ERROR (Status)) {
+      DEBUG((EFI_D_ERROR, "SET_RELATIVE_ADDR Fail Status = 0x%x\n", Status));
+      goto Exit;
+    }
+  }
+
+  //
+  // Get CSD Register
+  //
+  Status  = SendCommand (
+              CardData,
+              SEND_CSD,
+              (CardData->Address << 16),
+              NoData,
+              NULL,
+              0,
+              ResponseR2,
+              TIMEOUT_COMMAND,
+              (UINT32*)&(CardData->CSDRegister)
+              );
+  if (EFI_ERROR (Status)) {
+    DEBUG((EFI_D_ERROR, "SEND_CSD Fail Status = 0x%x\n", Status));
+    goto Exit;
+  }
+
+  DEBUG((EFI_D_INFO, "CardData->CSDRegister.SPEC_VERS = 0x%x\n", CardData->CSDRegister.SPEC_VERS));
+  DEBUG((EFI_D_INFO, "CardData->CSDRegister.CSD_STRUCTURE = 0x%x\n", CardData->CSDRegister.CSD_STRUCTURE));
+
+  Status = CaculateCardParameter (CardData);
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+
+  //
+  // It is platform and hardware specific, need hadrware engineer input
+  //
+  if (CardData->CSDRegister.DSR_IMP == 1) {
+    //
+    // Default is 0x404
+    //
+    Status  = SendCommand (
+                CardData,
+                SET_DSR,
+                (DEFAULT_DSR_VALUE << 16),
+                NoData,
+                NULL,
+                0,
+                ResponseNo,
+                TIMEOUT_COMMAND,
+                NULL
+                );
+    if (EFI_ERROR (Status)) {
+      DEBUG((EFI_D_ERROR, "SET_DSR Fail Status = 0x%x\n", Status));
+      //
+      // Assume can operate even fail
+      //
+    }
+  }
+  //
+  //Change clock frequency from 400KHz to max supported when not in high speed mode
+  //
+  Status = SDHostIo->SetClockFrequency (SDHostIo, CardData->MaxFrequency);
+  if (EFI_ERROR (Status)) {
+  DEBUG((EFI_D_ERROR, "MMCSDCardInit:Fail to SetClockFrequency \n"));
+  goto Exit;
+  }
+
+  //
+  //Put the card into tran state
+  //
+  Status = SendCommand (
+             CardData,
+             SELECT_DESELECT_CARD,
+             (CardData->Address << 16),
+             NoData,
+             NULL,
+             0,
+             ResponseR1,
+             TIMEOUT_COMMAND,
+             (UINT32*)&(CardData->CardStatus)
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG((EFI_D_ERROR, "SELECT_DESELECT_CARD Fail Status = 0x%x\n", Status));
+    goto Exit;
+  }
+
+  //
+  // No spec requirment, can be adjusted
+  //
+  gBS->Stall (5 * 1000);
+  //
+  // No need to do so
+  //
+  //
+  Status  = SendCommand (
+              CardData,
+              SEND_STATUS,
+              (CardData->Address << 16),
+              NoData,
+              NULL,
+              0,
+              ResponseR1,
+              TIMEOUT_COMMAND,
+              (UINT32*)&(CardData->CardStatus)
+              );
+  if (EFI_ERROR (Status)) {
+     DEBUG((EFI_D_ERROR, "SELECT_DESELECT_CARD SEND_STATUS Fail Status = 0x%x\n", Status));
+     goto Exit;
+  }
+  //
+  //if the SPEC_VERS indicates a version 4.0 or higher
+  //The card is a high speed card and support Switch
+  //and Send_ext_csd command
+  //otherwise it is an old card
+  //
+
+  if (CardData->CardType == MMCCard  || CardData->CardType == MMCCardHighCap) {
+    //
+    //Only V4.0 and above supports more than 1 bits and high speed
+    //
+    if (CardData->CSDRegister.SPEC_VERS >= 4) {
+    //
+      //Get ExtCSDRegister
+      //
+      Status  = SendCommand (
+                  CardData,
+                  SEND_EXT_CSD,
+                  0x0,
+                  InData,
+                  CardData->AlignedBuffer,
+                  sizeof (EXT_CSD),
+                  ResponseR1,
+                  TIMEOUT_DATA,
+                  (UINT32*)&(CardData->CardStatus)
+                  );
+      if (EFI_ERROR (Status)) {
+        DEBUG((EFI_D_ERROR, "SEND_EXT_CSD Fail Status = 0x%x\n", Status));
+        goto Exit;
+      }
+
+      CopyMem (&(CardData->ExtCSDRegister), CardData->AlignedBuffer, sizeof (EXT_CSD));
+
+      //
+      // Recaculate the block number for >2G MMC card
+      //
+      Data  = (CardData->ExtCSDRegister.SEC_COUNT[0]) |
+              (CardData->ExtCSDRegister.SEC_COUNT[1] << 8) |
+              (CardData->ExtCSDRegister.SEC_COUNT[2] << 16) |
+              (CardData->ExtCSDRegister.SEC_COUNT[3] << 24);
+
+      if (Data != 0) {
+        CardData->BlockNumber = Data;
+      }
+      DEBUG((DEBUG_INFO, "CardData->BlockNumber  %d\n", Data));
+      DEBUG((EFI_D_ERROR, "CardData->ExtCSDRegister.CARD_TYPE -> %d\n", (UINTN)CardData->ExtCSDRegister.CARD_TYPE));
+      if ((CardData->ExtCSDRegister.CARD_TYPE & BIT2)||
+          (CardData->ExtCSDRegister.CARD_TYPE & BIT3)) {
+          //DEBUG((DEBUG_INFO, "To enable DDR mode\n"));
+          //EnableDDRMode = TRUE;
+      }
+      //
+      // Check current chipset capability and the plugged-in card
+      // whether supports HighSpeed
+      //
+      if (SDHostIo->HostCapability.HighSpeedSupport) {
+
+        //
+        //Change card timing to high speed interface timing
+        //
+        ZeroMem(&SwitchArgument, sizeof (SWITCH_ARGUMENT));
+        SwitchArgument.CmdSet = 0;
+        SwitchArgument.Value  = 1;
+        SwitchArgument.Index  = (UINT32)((UINTN)
+        (&(CardData->ExtCSDRegister.HS_TIMING)) - (UINTN)(&(CardData->ExtCSDRegister)));
+        SwitchArgument.Access = WriteByte_Mode;
+        Status  = SendCommand (
+                    CardData,
+                    SWITCH,
+                    *(UINT32*)&SwitchArgument,
+                    NoData,
+                    NULL,
+                    0,
+                    ResponseR1b,
+                    TIMEOUT_COMMAND,
+                    (UINT32*)&(CardData->CardStatus)
+                    );
+        if (EFI_ERROR (Status)) {
+          DEBUG((EFI_D_ERROR, "MMCSDCardInit:SWITCH frequency Fail Status = 0x%x\n", Status));
+        }
+
+        gBS->Stall (5 * 1000);
+
+
+        if (!EFI_ERROR (Status)) {
+          Status  = SendCommand (
+                      CardData,
+                      SEND_STATUS,
+                      (CardData->Address << 16),
+                      NoData,
+                      NULL,
+                      0,
+                      ResponseR1,
+                      TIMEOUT_COMMAND,
+                      (UINT32*)&(CardData->CardStatus)
+                      );
+          if (!EFI_ERROR (Status)) {
+            if (EnableDDRMode) {
+              DEBUG((EFI_D_ERROR, "Enable ddr mode on host controller\n"));
+              SDHostIo->SetDDRMode (SDHostIo, TRUE);
+            } else  {
+              DEBUG((EFI_D_ERROR, "Enable high speed mode on host controller\n"));
+              SDHostIo->SetHighSpeedMode (SDHostIo, TRUE);
+            }
+          //
+          // Change host clock to support high speed and enable chispet to
+          // support speed
+          //
+            if ((CardData->ExtCSDRegister.CARD_TYPE & BIT1) != 0) {
+              Status = SDHostIo->SetClockFrequency (SDHostIo, FREQUENCY_MMC_PP_HIGH);
+            } else if ((CardData->ExtCSDRegister.CARD_TYPE & BIT0) != 0) {
+              Status = SDHostIo->SetClockFrequency (SDHostIo, FREQUENCY_MMC_PP);
+            } else {
+              Status = EFI_UNSUPPORTED;
+            }
+            if (EFI_ERROR (Status)) {
+              DEBUG((EFI_D_ERROR, "MMCSDCardInit:Fail to SetClockFrequency \n"));
+              goto Exit;
+            }
+            //
+            // It seems no need to stall after changing bus freqeuncy.
+            // It is said that the freqeuncy can be changed at any time. Just appends 8 clocks after command.
+            // But SetClock alreay has delay.
+            //
+          }
+        }
+
+      }
+
+
+
+      //
+      // Prefer wide bus width for performance
+      //
+      //
+      // Set to BusWidth bits mode, only version 4.0 or above support more than 1 bits
+      //
+      if (SDHostIo->HostCapability.BusWidth8 == TRUE) {
+         Status = MMCCardSetBusWidth (CardData, 8, EnableDDRMode);
+         if (EFI_ERROR (Status)) {
+            //
+            // CE-ATA may support 8 bits and 4 bits, but has no software method for detection
+            //
+            Status = MMCCardSetBusWidth (CardData, 4, EnableDDRMode);
+            if (EFI_ERROR (Status)) {
+              goto Exit;
+            }
+         }
+      } else if (SDHostIo->HostCapability.BusWidth4 == TRUE) {
+         Status = MMCCardSetBusWidth (CardData, 4, EnableDDRMode);
+         if (EFI_ERROR (Status)) {
+           goto Exit;
+         }
+      }
+
+      PowerValue = 0;
+
+      if (CardData->CurrentBusWidth == 8) {
+        if ((CardData->ExtCSDRegister.CARD_TYPE & BIT1) != 0) {
+          PowerValue = CardData->ExtCSDRegister.PWR_CL_52_360;
+          PowerValue = PowerValue >> 4;
+        } else if ((CardData->ExtCSDRegister.CARD_TYPE & BIT0) != 0) {
+          PowerValue = CardData->ExtCSDRegister.PWR_CL_26_360;
+          PowerValue = PowerValue >> 4;
+        }
+      } else if (CardData->CurrentBusWidth == 4) {
+         if ((CardData->ExtCSDRegister.CARD_TYPE & BIT1) != 0) {
+          PowerValue = CardData->ExtCSDRegister.PWR_CL_52_360;
+          PowerValue = PowerValue & 0xF;
+         } else if ((CardData->ExtCSDRegister.CARD_TYPE & BIT0) != 0) {
+           PowerValue = CardData->ExtCSDRegister.PWR_CL_26_360;
+           PowerValue = PowerValue & 0xF;
+         }
+      }
+
+      if (PowerValue != 0) {
+        //
+        //Update Power Class
+        //
+        ZeroMem(&SwitchArgument, sizeof (SWITCH_ARGUMENT));
+        SwitchArgument.CmdSet = 0;
+        SwitchArgument.Value  = PowerValue;
+        SwitchArgument.Index  = (UINT32)((UINTN)
+        (&(CardData->ExtCSDRegister.POWER_CLASS)) - (UINTN)(&(CardData->ExtCSDRegister)));
+        SwitchArgument.Access = WriteByte_Mode;
+        Status  = SendCommand (
+                    CardData,
+                    SWITCH,
+                    *(UINT32*)&SwitchArgument,
+                    NoData,
+                    NULL,
+                    0,
+                    ResponseR1b,
+                    TIMEOUT_COMMAND,
+                    (UINT32*)&(CardData->CardStatus)
+                    );
+         if (!EFI_ERROR (Status)) {
+           Status  = SendCommand (
+                       CardData,
+                       SEND_STATUS,
+                       (CardData->Address << 16),
+                       NoData,
+                       NULL,
+                       0,
+                       ResponseR1,
+                       TIMEOUT_COMMAND,
+                       (UINT32*)&(CardData->CardStatus)
+                       );
+           if (EFI_ERROR (Status)) {
+             DEBUG((EFI_D_ERROR, "SWITCH Power Class Fail Status = 0x%x\n", Status));
+           }
+           //gBS->Stall (10 * 1000);
+         }
+      }
+
+
+
+    } else {
+
+
+      DEBUG((EFI_D_ERROR, "MMC Card version %d only supportes 1 bits at lower transfer speed\n",CardData->CSDRegister.SPEC_VERS));
+    }
+  } else {
+      //
+      // Pin 1, at power up this line has a 50KOhm pull up enabled in the card.
+      // This pull-up should be disconnected by the user, during regular data transfer,
+      // with SET_CLR_CARD_DETECT (ACMD42) command
+      //
+      Status  = SendAppCommand (
+                  CardData,
+                  SET_CLR_CARD_DETECT,
+                  0,
+                  NoData,
+                  NULL,
+                  0,
+                  ResponseR1,
+                  TIMEOUT_COMMAND,
+                  (UINT32*)&(CardData->CardStatus)
+                  );
+      if (EFI_ERROR (Status)) {
+        DEBUG((EFI_D_ERROR, "SET_CLR_CARD_DETECT Fail Status = 0x%x\n", Status));
+        goto Exit;
+      }
+
+      /*
+      //
+      // Don't rely on SCR and SD status, some cards have unexpected SCR.
+      // It only sets private section, the other bits are 0
+      // such as Sandisk Ultra II 4.0G, KinSton mini SD 128M, Toshiba 2.0GB
+      // Some card even fail this command, KinSton SD 4GB
+      //
+      Status  = SendAppCommand (
+                  CardData,
+                  SEND_SCR,
+                  0,
+                  InData,
+                  (UINT8*)&(CardData->SCRRegister),
+                  sizeof(SCR),
+                  ResponseR1,
+                  TIMEOUT_COMMAND,
+                  (UINT32*)&(CardData->CardStatus)
+                  );
+      if (EFI_ERROR (Status)) {
+        goto Exit;
+      }
+
+      //
+      // SD memory card at least supports 1 and 4 bits.
+      //
+      // ASSERT ((CardData->SCRRegister.SD_BUS_WIDTH & (BIT0 | BIT2)) == (BIT0 | BIT2));
+      */
+
+      //
+      // Set Bus Width to 4
+      //
+      Status  = SendAppCommand (
+                  CardData,
+                  SET_BUS_WIDTH,
+                  SD_BUS_WIDTH_4,
+                  NoData,
+                  NULL,
+                  0,
+                  ResponseR1,
+                  TIMEOUT_COMMAND,
+                  (UINT32*)&(CardData->CardStatus)
+                  );
+      if (EFI_ERROR (Status)) {
+        DEBUG((EFI_D_ERROR, "SET_BUS_WIDTH 4 bits Fail Status = 0x%x\n", Status));
+        goto Exit;
+      }
+
+      Status = SDHostIo->SetBusWidth (SDHostIo, 4);
+      if (EFI_ERROR (Status)) {
+        goto Exit;
+      }
+      CardData->CurrentBusWidth = 4;
+
+
+      if ((SDHostIo->HostCapability.HighSpeedSupport == FALSE) ||
+          ((CardData->CSDRegister.CCC & BIT10) != BIT10)) {
+        //
+        // Host must support high speed
+        // Card must support Switch function
+        //
+        goto Exit;
+      }
+
+      //
+      //Mode = 0, group 1, function 1, check operation
+      //
+      Argument    = 0xFFFF01;
+      ZeroMem (&CardData->SwitchStatus, sizeof (SWITCH_STATUS));
+
+      Status  = SendCommand (
+                  CardData,
+                  SWITCH_FUNC,
+                  Argument,
+                  InData,
+                  CardData->AlignedBuffer,
+                  sizeof (SWITCH_STATUS),
+                  ResponseR1,
+                  TIMEOUT_COMMAND,
+                  (UINT32*)&(CardData->CardStatus)
+                  );
+      if (EFI_ERROR (Status)) {
+        goto Exit;
+      }
+      CopyMem (&(CardData->SwitchStatus), CardData->AlignedBuffer, sizeof (SWITCH_STATUS));
+
+      if ((CardData->SwitchStatus.DataStructureVersion == 0x0) ||
+          ((CardData->SwitchStatus.Group1BusyStatus & BIT1) != BIT1)) {
+        //
+        // 1. SD 1.1 card does not suppport busy bit
+        // 2. Ready state
+        //
+        //
+
+        //
+        //Mode = 1, group 1, function 1, BIT31 set means set mode
+        //
+        Argument = 0xFFFF01 | BIT31;
+        ZeroMem (&CardData->SwitchStatus, sizeof (SWITCH_STATUS));
+
+        Status  = SendCommand (
+                    CardData,
+                    SWITCH_FUNC,
+                    Argument,
+                    InData,
+                    CardData->AlignedBuffer,
+                    sizeof (SWITCH_STATUS),
+                    ResponseR1,
+                    TIMEOUT_COMMAND,
+                   (UINT32*)&(CardData->CardStatus)
+                   );
+         if (EFI_ERROR (Status)) {
+            goto Exit;
+         }
+         CopyMem (&(CardData->SwitchStatus), CardData->AlignedBuffer, sizeof (SWITCH_STATUS));
+
+         if ((CardData->SwitchStatus.DataStructureVersion == 0x0) ||
+            ((CardData->SwitchStatus.Group1BusyStatus & BIT1) != BIT1)) {
+          //
+          // 1. SD 1.1 card does not suppport busy bit
+          // 2. Ready state
+          //
+
+          //
+          // 8 clocks, (1/ 25M) * 8 ==> 320 us, so 1ms > 0.32 ms
+          //
+          gBS->Stall (1000);
+
+          //
+          //Change host clock
+          //
+          Status = SDHostIo->SetClockFrequency (SDHostIo, FREQUENCY_SD_PP_HIGH);
+          if (EFI_ERROR (Status)) {
+            goto Exit;
+          }
+
+         }
+      }
+  }
+  if (!((CardData->ExtCSDRegister.CARD_TYPE & BIT2) ||
+      (CardData->ExtCSDRegister.CARD_TYPE & BIT3))) {
+
+  //
+  // Set Block Length, to improve compatibility in case of some cards
+  //
+  Status  = SendCommand (
+                CardData,
+              SET_BLOCKLEN,
+              512,
+              NoData,
+              NULL,
+              0,
+              ResponseR1,
+              TIMEOUT_COMMAND,
+              (UINT32*)&(CardData->CardStatus)
+              );
+  if (EFI_ERROR (Status)) {
+    DEBUG((EFI_D_ERROR, "SET_BLOCKLEN Fail Status = 0x%x\n", Status));
+    goto Exit;
+  }
+  }
+  SDHostIo->SetBlockLength (SDHostIo, 512);
+
+
+Exit:
+  return Status;
+}
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.c
new file mode 100644
index 0000000000..400f041526
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.c
@@ -0,0 +1,317 @@
+/** @file
+
+The definition for SD media device driver model and blkio protocol routines.
+
+Copyright (c) 2013-2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "SDMediaDevice.h"
+
+
+EFI_DRIVER_BINDING_PROTOCOL gSDMediaDeviceDriverBinding = {
+  SDMediaDeviceSupported,
+  SDMediaDeviceStart,
+  SDMediaDeviceStop,
+  0x20,
+  NULL,
+  NULL
+};
+
+/**
+  Entry point for EFI drivers.
+
+  @param  ImageHandle      EFI_HANDLE.
+  @param  SystemTable      EFI_SYSTEM_TABLE.
+
+  @retval EFI_SUCCESS      Driver is successfully loaded.
+  @return Others           Failed.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeSDMediaDevice (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+  return EfiLibInstallDriverBindingComponentName2 (
+           ImageHandle,
+           SystemTable,
+           &gSDMediaDeviceDriverBinding,
+           ImageHandle,
+           &gSDMediaDeviceName,
+           &gSDMediaDeviceName2
+           );
+}
+
+
+/**
+  Test to see if this driver supports ControllerHandle. Any
+  ControllerHandle that has BlockIoProtocol installed will be supported.
+
+  @param  This                 Protocol instance pointer.
+  @param  Controller           Handle of device to test.
+  @param  RemainingDevicePath  Not used.
+
+  @return EFI_SUCCESS          This driver supports this device.
+  @return EFI_UNSUPPORTED      This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+SDMediaDeviceSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,
+  IN EFI_HANDLE                      Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
+  )
+{
+  EFI_STATUS                Status;
+  EFI_SD_HOST_IO_PROTOCOL   *SDHostIo;
+
+  //
+  // Test whether there is PCI IO Protocol attached on the controller handle.
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiSDHostIoProtocolGuid,
+                  (VOID **)&SDHostIo,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  gBS->CloseProtocol (
+         Controller,
+         &gEfiSDHostIoProtocolGuid,
+         This->DriverBindingHandle,
+         Controller
+         );
+
+Exit:
+  return Status;
+}
+
+/**
+  Starting the SD Media Device Driver.
+
+  @param  This                 Protocol instance pointer.
+  @param  Controller           Handle of device to test.
+  @param  RemainingDevicePath  Not used.
+
+  @retval EFI_SUCCESS          This driver supports this device.
+  @retval EFI_UNSUPPORTED      This driver does not support this device.
+  @retval EFI_DEVICE_ERROR     This driver cannot be started due to device Error.
+                               EFI_OUT_OF_RESOURCES- Failed due to resource shortage.
+
+**/
+EFI_STATUS
+EFIAPI
+SDMediaDeviceStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,
+  IN EFI_HANDLE                      Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
+  )
+{
+  EFI_STATUS                Status;
+  EFI_SD_HOST_IO_PROTOCOL   *SDHostIo;
+  CARD_DATA                 *CardData;
+
+  CardData = NULL;
+
+  //
+  // Open PCI I/O Protocol and save pointer to open protocol
+  // in private data area.
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiSDHostIoProtocolGuid,
+                  (VOID **) &SDHostIo,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to open gEfiSDHostIoProtocolGuid \r\n"));
+    goto Exit;
+  }
+
+  Status = SDHostIo->DetectCardAndInitHost (SDHostIo);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_INFO, "SDMediaDeviceStart: Fail to DetectCardAndInitHost \r\n"));
+    goto Exit;
+  }
+
+  CardData = (CARD_DATA*)AllocateZeroPool(sizeof (CARD_DATA));
+  if (CardData == NULL) {
+    Status =  EFI_OUT_OF_RESOURCES;
+    DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to AllocateZeroPool(CARD_DATA) \r\n"));
+    goto Exit;
+  }
+
+  ASSERT (SDHostIo->HostCapability.BoundarySize >= 4 * 1024);
+  CardData->RawBufferPointer = (UINT8*)((UINTN)DMA_MEMORY_TOP);
+  Status = gBS->AllocatePages (
+                  AllocateMaxAddress,
+                  EfiBootServicesData,
+                  EFI_SIZE_TO_PAGES (2 * SDHostIo->HostCapability.BoundarySize),
+                  (EFI_PHYSICAL_ADDRESS *)(&CardData->RawBufferPointer)
+                  );
+
+  if (CardData->RawBufferPointer == NULL) {
+    DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to AllocateZeroPool(2*x) \r\n"));
+    Status =  EFI_OUT_OF_RESOURCES;
+    goto Exit;
+  }
+  CardData->AlignedBuffer = CardData->RawBufferPointer - ((UINTN)(CardData->RawBufferPointer) & (SDHostIo->HostCapability.BoundarySize - 1)) + SDHostIo->HostCapability.BoundarySize;
+
+  CardData->Signature = CARD_DATA_SIGNATURE;
+  CardData->SDHostIo  = SDHostIo;
+
+  Status = MMCSDCardInit (CardData);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to MMCSDCardInit \r\n"));
+    goto Exit;
+  }
+  DEBUG ((EFI_D_INFO, "SDMediaDeviceStart: MMCSDCardInit SuccessFul\n"));
+
+  if (CardData->CardType == CEATACard) {
+    Status = CEATABlockIoInit (CardData);
+  } else {
+    Status = MMCSDBlockIoInit (CardData);
+  }
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to BlockIoInit \r\n"));
+    goto Exit;
+  }
+  DEBUG ((EFI_D_INFO, "SDMediaDeviceStart: BlockIo is successfully installed\n"));
+
+
+  Status = gBS->InstallProtocolInterface (
+                  &Controller,
+                  &gEfiBlockIoProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &CardData->BlockIo
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to install gEfiBlockIoProtocolGuid \r\n"));
+    goto Exit;
+  }
+
+  //
+  // Install the component name protocol
+  //
+  CardData->ControllerNameTable = NULL;
+
+  AddUnicodeString2 (
+    "eng",
+    gSDMediaDeviceName.SupportedLanguages,
+    &CardData->ControllerNameTable,
+    L"MMC/SD Media Device",
+    TRUE
+    );
+  AddUnicodeString2 (
+    "en",
+    gSDMediaDeviceName2.SupportedLanguages,
+    &CardData->ControllerNameTable,
+    L"MMC/SD Media Device",
+    FALSE
+    );
+
+Exit:
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_INFO, "SDMediaDeviceStart: End with failure\r\n"));
+    if (CardData != NULL) {
+      if (CardData->RawBufferPointer != NULL) {
+        gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) CardData->RawBufferPointer, EFI_SIZE_TO_PAGES (2 * SDHostIo->HostCapability.BoundarySize));
+      }
+      FreePool (CardData);
+    }
+  }
+
+  return Status;
+}
+
+
+/**
+  Stop this driver on ControllerHandle. Support stopping any child handles
+  created by this driver.
+
+  @param  This                 Protocol instance pointer.
+  @param  Controller           Handle of device to stop driver on.
+  @param  NumberOfChildren     Number of Children in the ChildHandleBuffer.
+  @param  ChildHandleBuffer    List of handles for the children we need to stop.
+
+  @return EFI_SUCCESS
+  @return others
+
+**/
+EFI_STATUS
+EFIAPI
+SDMediaDeviceStop (
+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,
+  IN EFI_HANDLE                      Controller,
+  IN UINTN                           NumberOfChildren,
+  IN EFI_HANDLE                      *ChildHandleBuffer
+  )
+{
+  EFI_STATUS                Status;
+  CARD_DATA                 *CardData;
+  EFI_BLOCK_IO_PROTOCOL     *BlockIo;
+
+  //
+  // First find BlockIo Protocol
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiBlockIoProtocolGuid,
+                  (VOID **)&BlockIo,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  CardData  = CARD_DATA_FROM_THIS(BlockIo);
+
+  //
+  // Uninstall Block I/O protocol from the device handle
+  //
+  Status = gBS->UninstallProtocolInterface (
+                  Controller,
+                  &gEfiBlockIoProtocolGuid,
+                  BlockIo
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if (CardData != NULL) {
+    if (CardData->RawBufferPointer != NULL) {
+      gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) CardData->RawBufferPointer, EFI_SIZE_TO_PAGES (2 * CardData->SDHostIo->HostCapability.BoundarySize));
+    }
+    FreeUnicodeStringTable (CardData->ControllerNameTable);
+    FreePool (CardData);
+  }
+
+  gBS->CloseProtocol (
+         Controller,
+         &gEfiSDHostIoProtocolGuid,
+         This->DriverBindingHandle,
+         Controller
+         );
+
+  return EFI_SUCCESS;
+}
+
+
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.h
new file mode 100644
index 0000000000..ac70f5a8bf
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.h
@@ -0,0 +1,462 @@
+/** @file
+
+The definition for SD media device driver model and blkio protocol routines.
+
+Copyright (c) 2013-2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _SD_MEDIA_DEVICE_H_
+#define _SD_MEDIA_DEVICE_H_
+
+
+#include <Uefi.h>
+
+#include <Protocol/PciIo.h>
+#include <Protocol/BlockIo.h>
+
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <IndustryStandard/Pci22.h>
+
+#include "ComponentName.h"
+#include "SDHostIo.h"
+
+
+extern EFI_DRIVER_BINDING_PROTOCOL   gSDMediaDeviceDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL   gSDMediaDeviceName;
+extern EFI_COMPONENT_NAME2_PROTOCOL  gSDMediaDeviceName2;
+
+//
+// Define the region of memory used for DMA memory
+//
+#define DMA_MEMORY_TOP          0x0000000001FFFFFFULL
+
+#define CARD_DATA_SIGNATURE  SIGNATURE_32 ('c', 'a', 'r', 'd')
+
+//
+// Command timeout will be max 100 ms
+//
+#define  TIMEOUT_COMMAND     100
+#define  TIMEOUT_DATA        5000
+
+typedef enum{
+  UnknownCard = 0,
+  MMCCard,                // MMC card
+  MMCCardHighCap,          // MMC Card High Capacity
+  CEATACard,              // CE-ATA device
+  SDMemoryCard,           // SD 1.1 card
+  SDMemoryCard2,          // SD 2.0 or above standard card
+  SDMemoryCard2High       // SD 2.0 or above high capacity card
+}CARD_TYPE;
+
+
+typedef struct {
+  //
+  //BlockIO
+  //
+  UINTN                     Signature;
+  EFI_BLOCK_IO_PROTOCOL     BlockIo;
+
+  EFI_BLOCK_IO_MEDIA        BlockIoMedia;
+
+  EFI_SD_HOST_IO_PROTOCOL   *SDHostIo;
+  EFI_UNICODE_STRING_TABLE  *ControllerNameTable;
+  CARD_TYPE                 CardType;
+
+  UINT8                     CurrentBusWidth;
+  BOOLEAN                   DualVoltage;
+  BOOLEAN                   NeedFlush;
+  UINT8                     Reserved[3];
+
+  UINT16                    Address;
+  UINT32                    BlockLen;
+  UINT32                    MaxFrequency;
+  UINT64                    BlockNumber;
+  //
+  //Common used
+  //
+  CARD_STATUS               CardStatus;
+  OCR                       OCRRegister;
+  CID                       CIDRegister;
+  CSD                       CSDRegister;
+  EXT_CSD                   ExtCSDRegister;
+  UINT8                     *RawBufferPointer;
+  UINT8                     *AlignedBuffer;
+  //
+  //CE-ATA specific
+  //
+  TASK_FILE                 TaskFile;
+  IDENTIFY_DEVICE_DATA      IndentifyDeviceData;
+  //
+  //SD specific
+  //
+  SCR                       SCRRegister;
+  SD_STATUS_REG             SDSattus;
+  SWITCH_STATUS             SwitchStatus;
+}CARD_DATA;
+
+#define CARD_DATA_FROM_THIS(a) \
+    CR(a, CARD_DATA, BlockIo, CARD_DATA_SIGNATURE)
+
+/**
+  Test to see if this driver supports ControllerHandle. Any
+  ControllerHandle that has BlockIoProtocol installed will be supported.
+
+  @param  This                 Protocol instance pointer.
+  @param  Controller           Handle of device to test.
+  @param  RemainingDevicePath  Not used.
+
+  @return EFI_SUCCESS          This driver supports this device.
+  @return EFI_UNSUPPORTED      This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+SDMediaDeviceSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,
+  IN EFI_HANDLE                      Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
+  );
+
+/**
+  Starting the SD Media Device Driver.
+
+  @param  This                 Protocol instance pointer.
+  @param  Controller           Handle of device to test.
+  @param  RemainingDevicePath  Not used.
+
+  @retval EFI_SUCCESS          This driver supports this device.
+  @retval EFI_UNSUPPORTED      This driver does not support this device.
+  @retval EFI_DEVICE_ERROR     This driver cannot be started due to device Error.
+                               EFI_OUT_OF_RESOURCES- Failed due to resource shortage.
+
+**/
+EFI_STATUS
+EFIAPI
+SDMediaDeviceStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,
+  IN EFI_HANDLE                      Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
+  );
+
+/**
+  Stop this driver on ControllerHandle. Support stopping any child handles
+  created by this driver.
+
+  @param  This                 Protocol instance pointer.
+  @param  Controller           Handle of device to stop driver on.
+  @param  NumberOfChildren     Number of Children in the ChildHandleBuffer.
+  @param  ChildHandleBuffer    List of handles for the children we need to stop.
+
+  @return EFI_SUCCESS
+  @return others
+
+**/
+EFI_STATUS
+EFIAPI
+SDMediaDeviceStop (
+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,
+  IN EFI_HANDLE                      Controller,
+  IN UINTN                           NumberOfChildren,
+  IN EFI_HANDLE                      *ChildHandleBuffer
+  );
+
+/**
+  MMC/SD card init function
+
+  @param  CardData             Pointer to CARD_DATA.
+
+  @return EFI_SUCCESS
+  @return others
+
+**/
+EFI_STATUS
+MMCSDCardInit (
+  IN  CARD_DATA    *CardData
+  );
+
+/**
+  Send command by using Host IO protocol
+
+  @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
+  @param  CommandIndex          The command index to set the command index field of command register.
+  @param  Argument              Command argument to set the argument field of command register.
+  @param  DataType              TRANSFER_TYPE, indicates no data, data in or data out.
+  @param  Buffer                Contains the data read from / write to the device.
+  @param  BufferSize            The size of the buffer.
+  @param  ResponseType          RESPONSE_TYPE.
+  @param  TimeOut               Time out value in 1 ms unit.
+  @param  ResponseData          Depending on the ResponseType, such as CSD or card status.
+
+  @retval EFI_SUCCESS
+  @retval EFI_INVALID_PARAMETER
+  @retval EFI_UNSUPPORTED
+  @retval EFI_DEVICE_ERROR
+
+**/
+EFI_STATUS
+SendCommand (
+  IN   CARD_DATA                  *CardData,
+  IN   UINT16                     CommandIndex,
+  IN   UINT32                     Argument,
+  IN   TRANSFER_TYPE              DataType,
+  IN   UINT8                      *Buffer, OPTIONAL
+  IN   UINT32                     BufferSize,
+  IN   RESPONSE_TYPE              ResponseType,
+  IN   UINT32                     TimeOut,
+  OUT  UINT32                     *ResponseData
+  );
+
+/**
+  Send the card APP_CMD command with the following command indicated by CommandIndex
+
+  @param  CardData              Pointer to CARD_DATA.
+  @param  CommandIndex          The command index to set the command index field of command register.
+  @param  Argument              Command argument to set the argument field of command register.
+  @param  DataType              TRANSFER_TYPE, indicates no data, data in or data out.
+  @param  Buffer                Contains the data read from / write to the device.
+  @param  BufferSize            The size of the buffer.
+  @param  ResponseType          RESPONSE_TYPE.
+  @param  TimeOut               Time out value in 1 ms unit.
+  @param  ResponseData          Depending on the ResponseType, such as CSD or card status.
+
+  @retval EFI_SUCCESS
+  @retval EFI_INVALID_PARAMETER
+  @retval EFI_UNSUPPORTED
+  @retval EFI_DEVICE_ERROR
+
+**/
+EFI_STATUS
+SendAppCommand (
+  IN   CARD_DATA                  *CardData,
+  IN   UINT16                     CommandIndex,
+  IN   UINT32                     Argument,
+  IN   TRANSFER_TYPE              DataType,
+  IN   UINT8                      *Buffer, OPTIONAL
+  IN   UINT32                     BufferSize,
+  IN   RESPONSE_TYPE              ResponseType,
+  IN   UINT32                     TimeOut,
+  OUT  UINT32                     *ResponseData
+  );
+
+/**
+  Send the card FAST_IO command
+
+  @param  CardData               Pointer to CARD_DATA.
+  @param  RegisterAddress        Register Address.
+  @param  RegisterData           Pointer to register Data.
+  @param  Write                  TRUE for write, FALSE for read.
+
+  @retval EFI_SUCCESS
+  @retval EFI_UNSUPPORTED
+  @retval EFI_INVALID_PARAMETER
+  @retval EFI_DEVICE_ERROR
+
+**/
+EFI_STATUS
+FastIO (
+  IN      CARD_DATA   *CardData,
+  IN      UINT8       RegisterAddress,
+  IN  OUT UINT8       *RegisterData,
+  IN      BOOLEAN     Write
+  );
+
+/**
+  Judge whether it is CE-ATA device or not.
+
+  @param  CardData             Pointer to CARD_DATA.
+
+  @retval TRUE
+  @retval FALSE
+
+**/
+BOOLEAN
+IsCEATADevice (
+  IN  CARD_DATA    *CardData
+  );
+
+/**
+  Send software reset
+
+  @param  CardData             Pointer to CARD_DATA.
+
+  @retval EFI_SUCCESS                Success
+  @retval EFI_DEVICE_ERROR           Hardware Error
+  @retval EFI_INVALID_PARAMETER      Parameter is error
+  @retval EFI_NO_MEDIA               No media
+  @retval EFI_MEDIA_CHANGED          Media Change
+  @retval EFI_BAD_BUFFER_SIZE        Buffer size is bad
+
+**/
+EFI_STATUS
+SoftwareReset (
+  IN  CARD_DATA    *CardData
+  );
+
+/**
+  SendATACommand specificed in Taskfile
+
+  @param  CardData             Pointer to CARD_DATA.
+  @param  TaskFile             Pointer to TASK_FILE.
+  @param  Write                TRUE means write, FALSE means read.
+  @param  Buffer               If NULL, means no data transfer, neither read nor write.
+  @param  SectorCount          Buffer size in 512 bytes unit.
+
+  @retval EFI_SUCCESS                Success
+  @retval EFI_DEVICE_ERROR           Hardware Error
+  @retval EFI_INVALID_PARAMETER      Parameter is error
+  @retval EFI_NO_MEDIA               No media
+  @retval EFI_MEDIA_CHANGED          Media Change
+  @retval EFI_BAD_BUFFER_SIZE        Buffer size is bad
+
+**/
+EFI_STATUS
+SendATACommand (
+  IN  CARD_DATA   *CardData,
+  IN  TASK_FILE   *TaskFile,
+  IN  BOOLEAN     Write,
+  IN  UINT8       *Buffer,
+  IN  UINT16      SectorCount
+  );
+
+/**
+  IDENTIFY_DEVICE command
+
+  @param  CardData             Pointer to CARD_DATA.
+
+  @retval EFI_SUCCESS                Success
+  @retval EFI_DEVICE_ERROR           Hardware Error
+  @retval EFI_INVALID_PARAMETER      Parameter is error
+  @retval EFI_NO_MEDIA               No media
+  @retval EFI_MEDIA_CHANGED          Media Change
+  @retval EFI_BAD_BUFFER_SIZE        Buffer size is bad
+
+**/
+EFI_STATUS
+IndentifyDevice (
+  IN  CARD_DATA    *CardData
+  );
+
+/**
+  FLUSH_CACHE_EXT command
+
+  @param  CardData             Pointer to CARD_DATA.
+
+  @retval EFI_SUCCESS                Success
+  @retval EFI_DEVICE_ERROR           Hardware Error
+  @retval EFI_INVALID_PARAMETER      Parameter is error
+  @retval EFI_NO_MEDIA               No media
+  @retval EFI_MEDIA_CHANGED          Media Change
+  @retval EFI_BAD_BUFFER_SIZE        Buffer size is bad
+
+**/
+EFI_STATUS
+FlushCache (
+  IN  CARD_DATA    *CardData
+  );
+
+/**
+  STANDBY_IMMEDIATE command
+
+  @param  CardData             Pointer to CARD_DATA.
+
+  @retval EFI_SUCCESS                Success
+  @retval EFI_DEVICE_ERROR           Hardware Error
+  @retval EFI_INVALID_PARAMETER      Parameter is error
+  @retval EFI_NO_MEDIA               No media
+  @retval EFI_MEDIA_CHANGED          Media Change
+  @retval EFI_BAD_BUFFER_SIZE        Buffer size is bad
+
+**/
+EFI_STATUS
+StandByImmediate (
+  IN  CARD_DATA    *CardData
+  );
+
+/**
+  READ_DMA_EXT command
+
+  @param  CardData             Pointer to CARD_DATA.
+  @param  LBA                  The starting logical block address to read from on the device.
+  @param  Buffer               A pointer to the destination buffer for the data. The caller
+                               is responsible for either having implicit or explicit ownership
+                               of the buffer.
+  @param  SectorCount          Size in 512 bytes unit.
+
+  @retval EFI_SUCCESS                Success
+  @retval EFI_DEVICE_ERROR           Hardware Error
+  @retval EFI_INVALID_PARAMETER      Parameter is error
+  @retval EFI_NO_MEDIA               No media
+  @retval EFI_MEDIA_CHANGED          Media Change
+  @retval EFI_BAD_BUFFER_SIZE        Buffer size is bad
+
+**/
+EFI_STATUS
+ReadDMAExt (
+  IN  CARD_DATA   *CardData,
+  IN  EFI_LBA     LBA,
+  IN  UINT8       *Buffer,
+  IN  UINT16      SectorCount
+  );
+
+/**
+  WRITE_DMA_EXT command
+
+  @param  CardData             Pointer to CARD_DATA.
+  @param  LBA                  The starting logical block address to read from on the device.
+  @param  Buffer               A pointer to the destination buffer for the data. The caller
+                               is responsible for either having implicit or explicit ownership
+                               of the buffer.
+  @param  SectorCount          Size in 512 bytes unit.
+
+  @retval EFI_SUCCESS                Success
+  @retval EFI_DEVICE_ERROR           Hardware Error
+  @retval EFI_INVALID_PARAMETER      Parameter is error
+  @retval EFI_NO_MEDIA               No media
+  @retval EFI_MEDIA_CHANGED          Media Change
+  @retval EFI_BAD_BUFFER_SIZE        Buffer size is bad
+
+**/
+EFI_STATUS
+WriteDMAExt (
+  IN  CARD_DATA   *CardData,
+  IN  EFI_LBA     LBA,
+  IN  UINT8       *Buffer,
+  IN  UINT16      SectorCount
+  );
+
+/**
+  CEATA card BlockIo init function.
+
+  @param  CardData               Pointer to CARD_DATA.
+
+  @retval EFI_SUCCESS
+  @retval Others
+**/
+EFI_STATUS
+CEATABlockIoInit (
+  IN  CARD_DATA    *CardData
+  );
+
+/**
+  MMC/SD card BlockIo init function.
+
+  @param  CardData               Pointer to CARD_DATA.
+
+  @retval EFI_SUCCESS
+  @retval Others
+**/
+EFI_STATUS
+MMCSDBlockIoInit (
+  IN  CARD_DATA    *CardData
+  );
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/SDMediaDeviceDxe.inf b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/SDMediaDeviceDxe.inf
new file mode 100644
index 0000000000..eb85b9c0a6
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/SDMediaDeviceDxe.inf
@@ -0,0 +1,60 @@
+## @file
+#
+#  Component Description File For SDMediaDeviceDxe Module.
+#
+#  Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SDMediaDevice
+  FILE_GUID                      = 80897901-91F6-4efe-9579-3353A0C02DAB
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = InitializeSDMediaDevice
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+#  DRIVER_BINDING                =  gSDMediaDeviceDriverBinding
+#  COMPONENT_NAME                =  gSDMediaDeviceName
+#  COMPONENT_NAME2               =  gSDMediaDeviceName2
+#
+
+[Sources]
+  SDMediaDevice.c
+  SDMediaDevice.h
+  MMCSDTransfer.c
+  CEATA.c
+  CEATABlockIo.c
+  MMCSDBlockIo.c
+  ComponentName.c
+  ComponentName.h
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  MemoryAllocationLib
+  BaseLib
+  UefiLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  BaseMemoryLib
+  DebugLib
+  PcdLib
+
+[Protocols]
+  gEfiPciIoProtocolGuid                         ## TO_START
+  gEfiSDHostIoProtocolGuid                      ## TO_START
+  gEfiBlockIoProtocolGuid                       ## BY_START
+
+[Pcd.common]
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.c
new file mode 100644
index 0000000000..f393aa8643
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.c
@@ -0,0 +1,320 @@
+/** @file
+Implementation of Usb Controller PPI.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Ppi/UsbController.h>
+#include <Library/DebugLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/IoLib.h>
+
+#include "UsbPei.h"
+
+//
+// Globals
+//
+//
+
+EFI_PEI_PPI_DESCRIPTOR mPpiList = {
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gPeiUsbControllerPpiGuid,
+  NULL
+};
+
+UINTN mIohOhciPciReg[IOH_MAX_OHCI_USB_CONTROLLERS] = {
+  PCI_LIB_ADDRESS (IOH_USB_BUS_NUMBER, IOH_USB_OHCI_DEVICE_NUMBER, IOH_OHCI_FUNCTION_NUMBER, 0)
+};
+
+UINTN mIohEhciPciReg[IOH_MAX_EHCI_USB_CONTROLLERS] = {
+  PCI_LIB_ADDRESS (IOH_USB_BUS_NUMBER, IOH_USB_EHCI_DEVICE_NUMBER, IOH_EHCI_FUNCTION_NUMBER, 0),
+};
+
+/**
+  When EHCI get started in DXE, OHCI couldn't get the ownership
+  of roothub after warm reset because CF@EHCI hasn't been cleared.
+  We should clear that reg before UpdateBootMode. But Reg@EHCI is
+  memory-mapped, so need assume a range of space without conflict
+  in PCI memory space.
+
+  @param[in]  PeiServices     The pointer of EFI_PEI_SERVICES
+
+**/
+
+VOID
+SwitchConfigFlag (
+  IN EFI_PEI_SERVICES          **PeiServices
+  )
+{
+  UINT32             SavBaseAddr;
+  UINT32             UsbBaseAddr;
+  UINT16             SaveCmdData;
+  UINT8              EhciCapLen;
+  UINT8              Index;
+  UsbBaseAddr = 0;
+
+  for (Index = 0; Index < IOH_MAX_EHCI_USB_CONTROLLERS; Index++) {
+    UsbBaseAddr = PcdGet32(PcdPeiQNCUsbControllerMemoryBaseAddress);
+    //
+    // Manage EHCI on IOH, set UsbBaseAddr
+    //
+    SavBaseAddr = PciRead32 (mIohEhciPciReg[Index] | R_IOH_USB_MEMBAR);
+    PciWrite32 (mIohEhciPciReg[Index] | R_IOH_USB_MEMBAR, UsbBaseAddr);
+    //
+    // Save Cmd register
+    //
+    SaveCmdData = PciRead16 (mIohEhciPciReg[Index] | R_IOH_USB_COMMAND);
+    //
+    // Enable EHCI on IOH
+    //
+    PciOr16 (mIohEhciPciReg[Index] | R_IOH_USB_COMMAND, B_IOH_USB_COMMAND_BME | B_IOH_USB_COMMAND_MSE );
+    //
+    // Clear CF register on EHCI
+    //
+    EhciCapLen = MmioRead8 (UsbBaseAddr + R_IOH_EHCI_CAPLENGTH);
+    MmioWrite32 (UsbBaseAddr + EhciCapLen + R_IOH_EHCI_CONFIGFLAGS, 0);
+
+    DEBUG ((EFI_D_INFO, "CF@EHCI = %x \n", UsbBaseAddr + EhciCapLen + R_IOH_EHCI_CONFIGFLAGS));
+    //
+    // Restore EHCI UsbBaseAddr in PCI space
+    //
+    PciWrite32 (mIohEhciPciReg[Index] | R_IOH_USB_MEMBAR, SavBaseAddr);
+    //
+    // Restore EHCI Command register in PCI space
+    //
+    PciWrite16(mIohEhciPciReg[Index] | R_IOH_USB_COMMAND, SaveCmdData);
+  }
+}
+/**
+  Retrieved specified the USB controller information.
+
+  @param  PeiServices           The pointer of EFI_PEI_SERVICES.
+  @param  This                  This PEI_USB_CONTROLLER_PPI instance.
+  @param  UsbControllerId       Indicate which usb controller information will be retrieved.
+  @param  ControllerType        Indicate the controller is Ehci, Ohci, OHCI
+  @param  BaseAddress           Indicate the memory bar of the controller
+
+  @retval EFI_SUCCESS           The reset operation succeeded.
+  @retval EFI_INVALID_PARAMETER Attributes is not valid.
+
+**/
+
+EFI_STATUS
+GetOhciController (
+  IN EFI_PEI_SERVICES               **PeiServices,
+  IN PEI_USB_CONTROLLER_PPI         *This,
+  IN UINT8                          UsbControllerId,
+  IN UINTN                          *ControllerType,
+  IN UINTN                          *BaseAddress
+  )
+{
+  IOH_OHCI_DEVICE         *PeiIohOhciDev;
+
+  PeiIohOhciDev = IOH_OHCI_DEVICE_FROM_THIS (This);
+
+  if (UsbControllerId >= IOH_MAX_OHCI_USB_CONTROLLERS) {
+    return EFI_INVALID_PARAMETER;
+  }
+  *ControllerType = PEI_OHCI_CONTROLLER;
+  *BaseAddress = PeiIohOhciDev->MmioBase[UsbControllerId];
+
+  return EFI_SUCCESS;
+}
+/**
+  Retrieved specified the USB controller information.
+
+  @param  PeiServices           The pointer of EFI_PEI_SERVICES.
+  @param  This                  This PEI_USB_CONTROLLER_PPI instance.
+  @param  UsbControllerId       Indicate which usb controller information will be retrieved.
+  @param  ControllerType        Indicate the controller is Ehci, Ohci, OHCI
+  @param  BaseAddress           Indicate the memory bar of the controller
+
+  @retval EFI_SUCCESS           The reset operation succeeded.
+  @retval EFI_INVALID_PARAMETER Attributes is not valid.
+
+**/
+
+EFI_STATUS
+GetEhciController (
+  IN EFI_PEI_SERVICES               **PeiServices,
+  IN PEI_USB_CONTROLLER_PPI         *This,
+  IN UINT8                          UsbControllerId,
+  IN UINTN                          *ControllerType,
+  IN UINTN                          *BaseAddress
+  )
+{
+  IOH_EHCI_DEVICE         *PeiIohEhciDev;
+
+  PeiIohEhciDev = IOH_EHCI_DEVICE_FROM_THIS (This);
+
+  if (UsbControllerId >= IOH_MAX_EHCI_USB_CONTROLLERS) {
+    return EFI_INVALID_PARAMETER;
+  }
+  *ControllerType = PEI_EHCI_CONTROLLER;
+  *BaseAddress = PeiIohEhciDev->MmioBase[UsbControllerId];
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Retrieved specified the USB controller information.
+
+  @param  IohOhciPciReg         Ohci device address list.
+  @param  OhciCount             The count of the OHCI
+  @param  IohEhciPciReg         Ehci device address list.
+  @param  EhciCount             The count of the EHCI
+
+**/
+
+VOID
+EnableBusMaster (
+  IN UINTN IohOhciPciReg[],
+  IN UINT8 OhciCount,
+  IN UINTN IohEhciPciReg[],
+  IN UINT8 EhciCount
+  )
+{
+  UINT8  Index;
+  UINT16 CmdReg;
+  for (Index = 0; Index < OhciCount; Index ++) {
+    CmdReg = PciRead16 (IohOhciPciReg[Index] | R_IOH_USB_COMMAND);
+    CmdReg = (UINT16) (CmdReg | B_IOH_USB_COMMAND_BME );
+    PciWrite16 (IohOhciPciReg[Index] | R_IOH_USB_COMMAND, CmdReg);
+  }
+  for (Index = 0; Index < EhciCount; Index ++) {
+    CmdReg = PciRead16 (IohEhciPciReg[Index] | R_IOH_USB_COMMAND);
+    CmdReg = (UINT16) (CmdReg | B_IOH_USB_COMMAND_BME );
+    PciWrite16 (IohEhciPciReg[Index] | R_IOH_USB_COMMAND, CmdReg);
+  }
+}
+
+PEI_USB_CONTROLLER_PPI mUsbControllerPpi[2] = { {GetOhciController}, {GetEhciController}};
+
+/**
+  @param  FileHandle  Handle of the file being invoked.
+  @param  PeiServices Describes the list of possible PEI Services.
+
+  @retval EFI_SUCCESS            PPI successfully installed
+
+**/
+EFI_STATUS
+PeimInitializeIchUsb (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  EFI_STATUS              Status;
+  UINTN                   i;
+  EFI_PHYSICAL_ADDRESS    AllocateAddress;
+  IOH_OHCI_DEVICE         *PeiIohOhciDev;
+  IOH_EHCI_DEVICE         *PeiIohEhciDev;
+  UINT16                  CmdReg;
+
+  Status = PeiServicesAllocatePages (
+             EfiBootServicesCode,
+             1,
+             &AllocateAddress
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  EnableBusMaster (
+    mIohOhciPciReg,
+    IOH_MAX_OHCI_USB_CONTROLLERS,
+    mIohEhciPciReg,
+    IOH_MAX_EHCI_USB_CONTROLLERS
+    );
+
+  if (FeaturePcdGet (PcdEhciRecoveryEnabled)) {
+    DEBUG ((EFI_D_INFO, "UsbPei:EHCI is used for recovery\n"));
+    //
+    // EHCI recovery is enabled
+    //
+    PeiIohEhciDev = (IOH_EHCI_DEVICE *)((UINTN)AllocateAddress);
+    ZeroMem (PeiIohEhciDev, sizeof(IOH_EHCI_DEVICE));
+
+    PeiIohEhciDev->Signature            = PEI_IOH_EHCI_SIGNATURE;
+    CopyMem(&(PeiIohEhciDev->UsbControllerPpi), &mUsbControllerPpi[1], sizeof(PEI_USB_CONTROLLER_PPI));
+    CopyMem(&(PeiIohEhciDev->PpiList), &mPpiList, sizeof(mPpiList));
+    PeiIohEhciDev->PpiList.Ppi          = &PeiIohEhciDev->UsbControllerPpi;
+
+    //
+    // Assign resources and enable Ehci controllers
+    //
+    for (i = 0; i < IOH_MAX_EHCI_USB_CONTROLLERS; i++) {
+      DEBUG ((EFI_D_INFO, "UsbPei:Enable the %dth EHCI controller for recovery\n", i));
+      PeiIohEhciDev->MmioBase[i] = PcdGet32(PcdPeiQNCUsbControllerMemoryBaseAddress) + IOH_USB_CONTROLLER_MMIO_RANGE * i;
+      //
+      // Assign base address register, Enable Bus Master and Memory Io
+      //
+      PciWrite32 (mIohEhciPciReg[i] | R_IOH_USB_MEMBAR, PeiIohEhciDev->MmioBase[i]);
+      CmdReg = PciRead16 (mIohEhciPciReg[i] | R_IOH_USB_COMMAND);
+      CmdReg = (UINT16) (CmdReg | B_IOH_USB_COMMAND_MSE | B_IOH_USB_COMMAND_BME );
+      PciWrite16 (mIohEhciPciReg[i] | R_IOH_USB_COMMAND, CmdReg);
+    }
+    //
+    // Install USB Controller PPI
+    //
+    Status = (**PeiServices).InstallPpi (
+                               PeiServices,
+                               &PeiIohEhciDev->PpiList
+                               );
+
+    ASSERT_EFI_ERROR (Status);
+  } else {
+    DEBUG ((EFI_D_INFO, "UsbPei:OHCI is used for recovery\n"));
+    //
+    // OHCI recovery is enabled
+    //
+    SwitchConfigFlag ((EFI_PEI_SERVICES**)PeiServices);
+    PeiIohOhciDev = (IOH_OHCI_DEVICE *)((UINTN)AllocateAddress);
+    ZeroMem (PeiIohOhciDev, sizeof(IOH_OHCI_DEVICE));
+
+    PeiIohOhciDev->Signature            = PEI_IOH_OHCI_SIGNATURE;
+    CopyMem(&(PeiIohOhciDev->UsbControllerPpi), &mUsbControllerPpi[0], sizeof(PEI_USB_CONTROLLER_PPI));
+    CopyMem(&(PeiIohOhciDev->PpiList), &mPpiList, sizeof(mPpiList));
+    PeiIohOhciDev->PpiList.Ppi          = &PeiIohOhciDev->UsbControllerPpi;
+    //
+    // Assign resources and enable OHCI controllers
+    //
+    for (i = 0; i < IOH_MAX_OHCI_USB_CONTROLLERS; i++) {
+      DEBUG ((EFI_D_INFO, "UsbPei:Enable the %dth OHCI controller for recovery\n", i));
+      PeiIohOhciDev->MmioBase[i] = PcdGet32(PcdPeiQNCUsbControllerMemoryBaseAddress) + IOH_USB_CONTROLLER_MMIO_RANGE * i;
+      //
+      // Assign base address register, Enable Bus Master and Memory Io
+      //
+      PciWrite32 (mIohOhciPciReg[i] | R_IOH_USB_MEMBAR, PeiIohOhciDev->MmioBase[i]);
+
+      Status = PeiServicesAllocatePages (
+                 EfiBootServicesCode,
+                 1,
+                 &AllocateAddress
+                 );
+      ASSERT_EFI_ERROR (Status);
+      MmioWrite32(PeiIohOhciDev->MmioBase[i] + R_IOH_USB_OHCI_HCCABAR, (UINT32)AllocateAddress);
+
+      CmdReg = PciRead16 (mIohOhciPciReg[i] | R_IOH_USB_COMMAND);
+      CmdReg = (UINT16) (CmdReg | B_IOH_USB_COMMAND_MSE | B_IOH_USB_COMMAND_BME );
+      PciWrite16 (mIohOhciPciReg[i] | R_IOH_USB_COMMAND, CmdReg);
+    }
+    //
+    // Install USB Controller PPI
+    //
+    Status = (**PeiServices).InstallPpi (
+                               PeiServices,
+                               &PeiIohOhciDev->PpiList
+                               );
+
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  return Status;
+}
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.h
new file mode 100644
index 0000000000..c270fea46e
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.h
@@ -0,0 +1,38 @@
+/** @file
+Define private data structure for UHCI and EHCI.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _USB_PEI_H
+#define _USB_PEI_H
+
+#include "Ioh.h"
+
+#define PEI_IOH_OHCI_SIGNATURE          SIGNATURE_32 ('O', 'H', 'C', 'I')
+#define PEI_IOH_EHCI_SIGNATURE          SIGNATURE_32 ('E', 'H', 'C', 'I')
+
+typedef struct {
+  UINTN                   Signature;
+  PEI_USB_CONTROLLER_PPI  UsbControllerPpi;
+  EFI_PEI_PPI_DESCRIPTOR  PpiList;
+  UINTN                   MmioBase[IOH_MAX_OHCI_USB_CONTROLLERS];
+} IOH_OHCI_DEVICE;
+
+typedef struct {
+  UINTN                   Signature;
+  PEI_USB_CONTROLLER_PPI  UsbControllerPpi;
+  EFI_PEI_PPI_DESCRIPTOR  PpiList;
+  UINTN                   MmioBase[IOH_MAX_EHCI_USB_CONTROLLERS];
+} IOH_EHCI_DEVICE;
+
+#define IOH_OHCI_DEVICE_FROM_THIS(a) \
+  CR(a, IOH_OHCI_DEVICE, UsbControllerPpi, PEI_IOH_OHCI_SIGNATURE)
+
+#define IOH_EHCI_DEVICE_FROM_THIS(a) \
+  CR (a, IOH_EHCI_DEVICE, UsbControllerPpi, PEI_IOH_EHCI_SIGNATURE)
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.inf b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.inf
new file mode 100644
index 0000000000..ab57ff87d3
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.inf
@@ -0,0 +1,53 @@
+## @file
+# Component description file for UsbPei module.
+#
+# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = UsbPei
+  FILE_GUID                      = 73E6F6B4-D029-4e87-8405-6067C8BD02A6
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = PeimInitializeIchUsb
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  UsbPei.c
+  UsbPei.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  IoLib
+  PciLib
+  PcdLib
+  BaseMemoryLib
+  PeimEntryPoint
+  DebugLib
+
+[Ppis]
+  gPeiUsbControllerPpiGuid                      # PPI ALWAYS_PRODUCED
+
+[FeaturePcd]
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdEhciRecoveryEnabled
+
+[Pcd]
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdPeiQNCUsbControllerMemoryBaseAddress
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdPeiP2PMemoryBaseAddress
+
+[Depex]
+  gEfiPeiMemoryDiscoveredPpiGuid AND gEfiPeiBootInRecoveryModePpiGuid
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/ComponentName.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/ComponentName.c
new file mode 100644
index 0000000000..3c2ba51ad4
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/ComponentName.c
@@ -0,0 +1,219 @@
+/** @file
+UEFI Component Name and Name2 protocol for OHCI driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "Ohci.h"
+
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gOhciComponentName = {
+  OhciComponentNameGetDriverName,
+  OhciComponentNameGetControllerName,
+  "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gOhciComponentName2 = {
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) OhciComponentNameGetDriverName,
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) OhciComponentNameGetControllerName,
+  "en"
+};
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mOhciDriverNameTable[] = {
+  { "eng;en", L"Usb Ohci Driver" },
+  { NULL, NULL }
+};
+
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 4646 or ISO 639-2 language code format.
+
+  @param  DriverName[out]       A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+OhciComponentNameGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **DriverName
+  )
+{
+  return LookupUnicodeString2 (
+           Language,
+           This->SupportedLanguages,
+           mOhciDriverNameTable,
+           DriverName,
+           (BOOLEAN)(This == &gOhciComponentName)
+           );
+}
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  ControllerHandle[in]  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+
+  @param  ChildHandle[in]       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 4646 or ISO 639-2 language code format.
+
+  @param  ControllerName[out]   A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                controller specified by ControllerHandle and
+                                ChildHandle in the language specified by
+                                Language from the point of view of the driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+OhciComponentNameGetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
+  IN  EFI_HANDLE                                      ControllerHandle,
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
+  IN  CHAR8                                           *Language,
+  OUT CHAR16                                          **ControllerName
+  )
+{
+  EFI_STATUS           Status;
+  USB_OHCI_HC_DEV      *OhciDev;
+  EFI_USB_HC_PROTOCOL  *UsbHc;
+
+  //
+  // This is a device driver, so ChildHandle must be NULL.
+  //
+  if (ChildHandle != NULL) {
+    return EFI_UNSUPPORTED;
+  }
+  //
+  // Make sure this driver is currently managing ControllerHandle
+  //
+  Status = EfiTestManagedDevice (
+             ControllerHandle,
+             gOhciDriverBinding.DriverBindingHandle,
+             &gEfiPciIoProtocolGuid
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Get the device context
+  //
+  Status = gBS->OpenProtocol (
+                  ControllerHandle,
+                  &gEfiUsbHcProtocolGuid,
+                  (VOID **) &UsbHc,
+                  gOhciDriverBinding.DriverBindingHandle,
+                  ControllerHandle,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  OhciDev = USB_OHCI_HC_DEV_FROM_THIS (UsbHc);
+
+  return LookupUnicodeString2 (
+           Language,
+           This->SupportedLanguages,
+           OhciDev->ControllerNameTable,
+           ControllerName,
+           (BOOLEAN)(This == &gOhciComponentName)
+           );
+
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/ComponentName.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/ComponentName.h
new file mode 100644
index 0000000000..c54cd6356c
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/ComponentName.h
@@ -0,0 +1,141 @@
+/** @file
+This file contains the delarations for componet name routines.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _COMPONENT_NAME_H_
+#define _COMPONENT_NAME_H_
+
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 4646 or ISO 639-2 language code format.
+
+  @param  DriverName[out]       A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+OhciComponentNameGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **DriverName
+  );
+
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  ControllerHandle[in]  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+
+  @param  ChildHandle[in]       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 4646 or ISO 639-2 language code format.
+
+  @param  ControllerName[out]   A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                controller specified by ControllerHandle and
+                                ChildHandle in the language specified by
+                                Language from the point of view of the driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+OhciComponentNameGetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
+  IN  EFI_HANDLE                                      ControllerHandle,
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
+  IN  CHAR8                                           *Language,
+  OUT CHAR16                                          **ControllerName
+  );
+
+#endif
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Descriptor.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Descriptor.h
new file mode 100644
index 0000000000..14a619bb3f
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Descriptor.h
@@ -0,0 +1,132 @@
+/** @file
+This file contains the descriptor definination of OHCI spec
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+
+#ifndef _DESCRIPTOR_H
+#define _DESCRIPTOR_H
+
+#define ED_FUNC_ADD     0x0001
+#define ED_ENDPT_NUM    0x0002
+#define ED_DIR          0x0004
+#define ED_SPEED        0x0008
+#define ED_SKIP         0x0010
+#define ED_FORMAT       0x0020
+#define ED_MAX_PACKET   0x0040
+#define ED_TDTAIL_PTR   0x0080
+#define ED_HALTED       0x0100
+#define ED_DTTOGGLE     0x0200
+#define ED_TDHEAD_PTR   0x0400
+#define ED_NEXT_EDPTR   0x0800
+#define ED_PDATA        0x1000
+#define ED_ZERO         0x2000
+
+#define TD_BUFFER_ROUND     0x0001
+#define TD_DIR_PID          0x0002
+#define TD_DELAY_INT        0x0004
+#define TD_DT_TOGGLE        0x0008
+#define TD_ERROR_CNT        0x0010
+#define TD_COND_CODE        0x0020
+#define TD_CURR_BUFFER_PTR  0x0040
+#define TD_NEXT_PTR         0x0080
+#define TD_BUFFER_END_PTR   0x0100
+#define TD_PDATA            0x0200
+
+#define ED_FROM_TD_DIR        0x0
+#define ED_OUT_DIR            0x1
+#define ED_IN_DIR             0x2
+#define ED_FROM_TD_ALSO_DIR   0x3
+
+#define TD_SETUP_PID          0x00
+#define TD_OUT_PID            0x01
+#define TD_IN_PID             0x02
+#define TD_NODATA_PID         0x03
+
+#define HI_SPEED              0
+#define LO_SPEED              1
+
+#define TD_NO_ERROR           0x00
+#define TD_CRC_ERROR          0x01
+#define TD_BITSTUFFING_ERROR  0x02
+#define TD_TOGGLE_ERROR       0x03
+#define TD_DEVICE_STALL       0x04
+#define TD_NO_RESPONSE        0x05
+#define TD_PIDCHK_FAIL        0x06
+#define TD_PID_UNEXPECTED     0x07
+#define TD_DATA_OVERRUN       0x08
+#define TD_DATA_UNDERRUN      0x09
+#define TD_BUFFER_OVERRUN     0x0C
+#define TD_BUFFER_UNDERRUN    0x0D
+#define TD_TOBE_PROCESSED     0x0E
+#define TD_TOBE_PROCESSED_2   0x0F
+
+#define TD_NO_DELAY           0x7
+
+#define TD_INT                0x1
+#define TD_CTL                0x2
+#define TD_BLK                0x3
+
+typedef struct {
+  UINT32 Reserved:18;
+  UINT32 BufferRounding:1;
+  UINT32 DirPID:2;
+  UINT32 DelayInterrupt:3;
+  UINT32 DataToggle:2;
+  UINT32 ErrorCount:2;
+  UINT32 ConditionCode:4;
+} TD_DESCRIPTOR_WORD0;
+
+typedef struct _TD_DESCRIPTOR {
+  TD_DESCRIPTOR_WORD0     Word0;
+  UINT32                  CurrBufferPointer;          // 32-bit Physical Address of buffer
+  UINT32                  NextTD;                     // 32-bit Physical Address of TD_DESCRIPTOR
+  UINT32                  BufferEndPointer;           // 32-bit Physical Address of buffer
+  UINT32                  NextTDPointer;              // 32-bit Physical Address of TD_DESCRIPTOR
+  UINT32                  DataBuffer;                 // 32-bit Physical Address of buffer
+  UINT32                  ActualSendLength;
+  UINT32                  Reserved;
+} TD_DESCRIPTOR;
+
+typedef struct {
+  UINT32 FunctionAddress:7;
+  UINT32 EndPointNum:4;
+  UINT32 Direction:2;
+  UINT32 Speed:1;
+  UINT32 Skip:1;
+  UINT32 Format:1;
+  UINT32 MaxPacketSize:11;
+  UINT32 FreeSpace:5;
+} ED_DESCRIPTOR_WORD0;
+
+typedef struct {
+  UINT32 Halted:1;
+  UINT32 ToggleCarry:1;
+  UINT32 Zero:2;
+  UINT32 TdHeadPointer:28;
+} ED_DESCRIPTOR_WORD2;
+
+typedef struct _ED_DESCRIPTOR {
+  ED_DESCRIPTOR_WORD0     Word0;
+  UINT32                  TdTailPointer;    // 32-bit Physical Address of TD_DESCRIPTOR
+  ED_DESCRIPTOR_WORD2     Word2;
+  UINT32                  NextED;           // 32-bit Physical Address of ED_DESCRIPTOR
+} ED_DESCRIPTOR;
+
+#define TD_PTR(p)            ((TD_DESCRIPTOR *)(UINTN)((p) << 4))
+#define ED_PTR(p)            ((ED_DESCRIPTOR *)(UINTN)((p) << 4))
+#define RIGHT_SHIFT_4(p)     ((UINT32)(p) >> 4)
+
+typedef enum {
+  CONTROL_LIST,
+  BULK_LIST,
+  INTERRUPT_LIST,
+  ISOCHRONOUS_LIST
+} DESCRIPTOR_LIST_TYPE;
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.c
new file mode 100644
index 0000000000..dbff8f1fcb
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.c
@@ -0,0 +1,2473 @@
+/** @file
+This file contains the implementation of Usb Hc Protocol.
+
+Copyright (c) 2013-2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "Ohci.h"
+
+/**
+  Provides software reset for the USB host controller.
+
+  @param  This                  This EFI_USB_HC_PROTOCOL instance.
+  @param  Attributes            A bit mask of the reset operation to perform.
+
+  @retval EFI_SUCCESS           The reset operation succeeded.
+  @retval EFI_INVALID_PARAMETER Attributes is not valid.
+  @retval EFI_UNSUPPOURTED      The type of reset specified by Attributes is
+                                not currently supported by the host controller.
+  @retval EFI_DEVICE_ERROR      Host controller isn't halted to reset.
+
+**/
+EFI_STATUS
+EFIAPI
+OhciReset (
+  IN EFI_USB_HC_PROTOCOL  *This,
+  IN UINT16               Attributes
+  )
+{
+  EFI_STATUS              Status;
+  USB_OHCI_HC_DEV         *Ohc;
+  UINT8                   Index;
+  UINT8                   NumOfPorts;
+  UINT32                  PowerOnGoodTime;
+  UINT32                  Data32;
+  BOOLEAN                 Flag = FALSE;
+
+  if ((Attributes & ~(EFI_USB_HC_RESET_GLOBAL | EFI_USB_HC_RESET_HOST_CONTROLLER)) != 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = EFI_SUCCESS;
+  Ohc = USB_OHCI_HC_DEV_FROM_THIS (This);
+
+  if ((Attributes & EFI_USB_HC_RESET_HOST_CONTROLLER) != 0) {
+    gBS->Stall (50 * 1000);
+    Status = OhciSetHcCommandStatus (Ohc, HC_RESET, HC_RESET);
+    if (EFI_ERROR (Status)) {
+      return EFI_DEVICE_ERROR;
+    }
+    gBS->Stall (50 * 1000);
+    //
+    // Wait for host controller reset.
+    //
+    PowerOnGoodTime = 50;
+    do {
+      gBS->Stall (1 * 1000);
+      Data32 = OhciGetOperationalReg (Ohc->PciIo, HC_COMMAND_STATUS );
+      if (EFI_ERROR (Status)) {
+        return EFI_DEVICE_ERROR;
+      }
+      if ((Data32 & HC_RESET) == 0) {
+        Flag = TRUE;
+        break;
+      }
+    }while(PowerOnGoodTime--);
+    if (!Flag){
+      return EFI_DEVICE_ERROR;
+    }
+  }
+  OhciFreeIntTransferMemory (Ohc);
+  Status = OhciInitializeInterruptList (Ohc);
+  OhciSetFrameInterval (Ohc, FRAME_INTERVAL, 0x2edf);
+  if ((Attributes &  EFI_USB_HC_RESET_GLOBAL) != 0) {
+    Status = OhciSetHcControl (Ohc, HC_FUNCTIONAL_STATE, HC_STATE_RESET);
+    if (EFI_ERROR (Status)) {
+      return EFI_DEVICE_ERROR;
+    }
+    gBS->Stall (50 * 1000);
+  }
+  //
+  // Initialize host controller operational registers
+  //
+  OhciSetFrameInterval (Ohc, FS_LARGEST_DATA_PACKET, 0x2778);
+  OhciSetFrameInterval (Ohc, FRAME_INTERVAL, 0x2edf);
+  OhciSetPeriodicStart (Ohc, 0x2a2f);
+  OhciSetHcControl (Ohc, CONTROL_BULK_RATIO, 0x3);
+  OhciSetHcCommandStatus (Ohc, CONTROL_LIST_FILLED | BULK_LIST_FILLED, 0);
+  OhciSetRootHubDescriptor (Ohc, RH_PSWITCH_MODE, 0);
+  OhciSetRootHubDescriptor (Ohc, RH_NO_PSWITCH | RH_NOC_PROT, 1);
+  //OhciSetRootHubDescriptor (Hc, RH_PSWITCH_MODE | RH_NO_PSWITCH, 0);
+  //OhciSetRootHubDescriptor (Hc, RH_PSWITCH_MODE | RH_NOC_PROT, 1);
+
+  OhciSetRootHubDescriptor (Ohc, RH_DEV_REMOVABLE, 0);
+  OhciSetRootHubDescriptor (Ohc, RH_PORT_PWR_CTRL_MASK, 0xffff);
+  OhciSetRootHubStatus (Ohc, RH_LOCAL_PSTAT_CHANGE);
+  OhciSetRootHubPortStatus (Ohc, 0, RH_SET_PORT_POWER);
+  OhciGetRootHubNumOfPorts (This, &NumOfPorts);
+  for (Index = 0; Index < NumOfPorts; Index++) {
+    if (!EFI_ERROR (OhciSetRootHubPortFeature (This, Index, EfiUsbPortReset))) {
+      gBS->Stall (200 * 1000);
+      OhciClearRootHubPortFeature (This, Index, EfiUsbPortReset);
+      gBS->Stall (1000);
+      OhciSetRootHubPortFeature (This, Index, EfiUsbPortEnable);
+      gBS->Stall (1000);
+    }
+  }
+  OhciSetMemoryPointer (Ohc, HC_HCCA, Ohc->HccaMemoryBlock);
+  OhciSetMemoryPointer (Ohc, HC_CONTROL_HEAD, NULL);
+  OhciSetMemoryPointer (Ohc, HC_BULK_HEAD, NULL);
+  OhciSetHcControl (Ohc, PERIODIC_ENABLE | CONTROL_ENABLE | BULK_ENABLE, 1); /*ISOCHRONOUS_ENABLE*/
+  OhciSetHcControl (Ohc, HC_FUNCTIONAL_STATE, HC_STATE_OPERATIONAL);
+  gBS->Stall (50*1000);
+  //
+  // Wait till first SOF occurs, and then clear it
+  //
+  while (OhciGetHcInterruptStatus (Ohc, START_OF_FRAME) == 0);
+  OhciClearInterruptStatus (Ohc, START_OF_FRAME);
+  gBS->Stall (1000);
+
+  return Status;
+}
+
+/**
+  Retrieve the current state of the USB host controller.
+
+  @param  This                  This EFI_USB_HC_PROTOCOL instance.
+  @param  State                 Variable to return the current host controller
+                                state.
+
+  @retval EFI_SUCCESS           Host controller state was returned in State.
+  @retval EFI_INVALID_PARAMETER State is NULL.
+  @retval EFI_DEVICE_ERROR      An error was encountered while attempting to
+                                retrieve the host controller's current state.
+
+**/
+
+EFI_STATUS
+EFIAPI
+OhciGetState (
+  IN  EFI_USB_HC_PROTOCOL  *This,
+  OUT EFI_USB_HC_STATE     *State
+  )
+{
+  USB_OHCI_HC_DEV         *Ohc;
+  UINT32                  FuncState;
+
+  if (State == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Ohc = USB_OHCI_HC_DEV_FROM_THIS (This);
+
+  FuncState = OhciGetHcControl (Ohc, HC_FUNCTIONAL_STATE);
+
+  switch (FuncState) {
+    case HC_STATE_RESET:
+    case HC_STATE_RESUME:
+      *State = EfiUsbHcStateHalt;
+      break;
+
+    case HC_STATE_OPERATIONAL:
+      *State = EfiUsbHcStateOperational;
+      break;
+
+    case HC_STATE_SUSPEND:
+      *State = EfiUsbHcStateSuspend;
+      break;
+
+    default:
+      ASSERT (FALSE);
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  Sets the USB host controller to a specific state.
+
+  @param  This                  This EFI_USB_HC_PROTOCOL instance.
+  @param  State                 The state of the host controller that will be set.
+
+  @retval EFI_SUCCESS           The USB host controller was successfully placed
+                                in the state specified by State.
+  @retval EFI_INVALID_PARAMETER State is invalid.
+  @retval EFI_DEVICE_ERROR      Failed to set the state due to device error.
+
+**/
+
+EFI_STATUS
+EFIAPI
+OhciSetState(
+  IN EFI_USB_HC_PROTOCOL  *This,
+  IN EFI_USB_HC_STATE     State
+  )
+{
+  EFI_STATUS              Status;
+  USB_OHCI_HC_DEV         *Ohc;
+
+  Ohc = USB_OHCI_HC_DEV_FROM_THIS(This);
+
+  switch (State) {
+    case EfiUsbHcStateHalt:
+      Status = OhciSetHcControl (Ohc, HC_FUNCTIONAL_STATE, HC_STATE_RESET);
+      break;
+
+    case EfiUsbHcStateOperational:
+      Status = OhciSetHcControl (Ohc, HC_FUNCTIONAL_STATE, HC_STATE_OPERATIONAL);
+      break;
+
+    case EfiUsbHcStateSuspend:
+      Status = OhciSetHcControl (Ohc, HC_FUNCTIONAL_STATE, HC_STATE_SUSPEND);
+      break;
+
+    default:
+      Status = EFI_INVALID_PARAMETER;
+  }
+
+  gBS->Stall (1000);
+
+  return Status;
+}
+
+/**
+
+  Submits control transfer to a target USB device.
+
+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
+  @param  DeviceAddress         Represents the address of the target device on the USB,
+                                which is assigned during USB enumeration.
+  @param  IsSlowDevice          Indicates whether the target device is slow device
+                                or full-speed device.
+  @param  MaxPaketLength        Indicates the maximum packet size that the
+                                default control transfer endpoint is capable of
+                                sending or receiving.
+  @param  Request               A pointer to the USB device request that will be sent
+                                to the USB device.
+  @param  TransferDirection     Specifies the data direction for the transfer.
+                                There are three values available, DataIn, DataOut
+                                and NoData.
+  @param  Data                  A pointer to the buffer of data that will be transmitted
+                                to USB device or received from USB device.
+  @param  DataLength            Indicates the size, in bytes, of the data buffer
+                                specified by Data.
+  @param  TimeOut               Indicates the maximum time, in microseconds,
+                                which the transfer is allowed to complete.
+  @param  TransferResult        A pointer to the detailed result information generated
+                                by this control transfer.
+
+  @retval EFI_SUCCESS           The control transfer was completed successfully.
+  @retval EFI_OUT_OF_RESOURCES  The control transfer could not be completed due to a lack of resources.
+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
+  @retval EFI_TIMEOUT           The control transfer failed due to timeout.
+  @retval EFI_DEVICE_ERROR      The control transfer failed due to host controller or device error.
+                                Caller should check TranferResult for detailed error information.
+
+--*/
+
+
+EFI_STATUS
+EFIAPI
+OhciControlTransfer (
+  IN     EFI_USB_HC_PROTOCOL     *This,
+  IN     UINT8                   DeviceAddress,
+  IN     BOOLEAN                 IsSlowDevice,
+  IN     UINT8                   MaxPacketLength,
+  IN     EFI_USB_DEVICE_REQUEST  *Request,
+  IN     EFI_USB_DATA_DIRECTION  TransferDirection,
+  IN OUT VOID                    *Data                 OPTIONAL,
+  IN OUT UINTN                   *DataLength           OPTIONAL,
+  IN     UINTN                   TimeOut,
+  OUT    UINT32                  *TransferResult
+  )
+{
+  USB_OHCI_HC_DEV                *Ohc;
+  ED_DESCRIPTOR                  *HeadEd;
+  ED_DESCRIPTOR                  *Ed;
+  TD_DESCRIPTOR                  *HeadTd;
+  TD_DESCRIPTOR                  *SetupTd;
+  TD_DESCRIPTOR                  *DataTd;
+  TD_DESCRIPTOR                  *StatusTd;
+  TD_DESCRIPTOR                  *EmptyTd;
+  EFI_STATUS                     Status;
+  UINT32                         DataPidDir;
+  UINT32                         StatusPidDir;
+  UINTN                          TimeCount;
+  OHCI_ED_RESULT                 EdResult;
+
+  EFI_PCI_IO_PROTOCOL_OPERATION  MapOp;
+
+  UINTN                          ActualSendLength;
+  UINTN                          LeftLength;
+  UINT8                          DataToggle;
+
+  VOID                           *ReqMapping = NULL;
+  UINTN                          ReqMapLength = 0;
+  EFI_PHYSICAL_ADDRESS           ReqMapPhyAddr = 0;
+
+  VOID                           *DataMapping = NULL;
+  UINTN                          DataMapLength = 0;
+  EFI_PHYSICAL_ADDRESS           DataMapPhyAddr = 0;
+
+  HeadTd = NULL;
+  DataTd = NULL;
+
+  if ((TransferDirection != EfiUsbDataOut && TransferDirection != EfiUsbDataIn &&
+       TransferDirection != EfiUsbNoData) ||
+      Request == NULL || DataLength == NULL || TransferResult == NULL ||
+      (TransferDirection == EfiUsbNoData && (*DataLength != 0 || Data != NULL)) ||
+      (TransferDirection != EfiUsbNoData && (*DataLength == 0 || Data == NULL)) ||
+      (IsSlowDevice && MaxPacketLength != 8) ||
+      (MaxPacketLength != 8 && MaxPacketLength != 16 &&
+       MaxPacketLength != 32 && MaxPacketLength != 64)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (*DataLength > MAX_BYTES_PER_TD) {
+    DEBUG ((EFI_D_ERROR, "OhciControlTransfer: Request data size is too large\r\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Ohc = USB_OHCI_HC_DEV_FROM_THIS(This);
+
+  if (TransferDirection == EfiUsbDataIn) {
+    DataPidDir = TD_IN_PID;
+    StatusPidDir = TD_OUT_PID;
+  } else {
+    DataPidDir = TD_OUT_PID;
+    StatusPidDir = TD_IN_PID;
+  }
+
+  Status = OhciSetHcControl (Ohc, CONTROL_ENABLE, 0);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_INFO, "OhciControlTransfer: fail to disable CONTROL_ENABLE\r\n"));
+    *TransferResult = EFI_USB_ERR_SYSTEM;
+    return EFI_DEVICE_ERROR;
+  }
+  Status = OhciSetHcCommandStatus (Ohc, CONTROL_LIST_FILLED, 0);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_INFO, "OhciControlTransfer: fail to disable CONTROL_LIST_FILLED\r\n"));
+    *TransferResult = EFI_USB_ERR_SYSTEM;
+    return EFI_DEVICE_ERROR;
+  }
+  gBS->Stall(20 * 1000);
+
+  OhciSetMemoryPointer (Ohc, HC_CONTROL_HEAD, NULL);
+  Ed = OhciCreateED (Ohc);
+  if (Ed == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    DEBUG ((EFI_D_INFO, "OhciControlTransfer: Fail to allocate ED buffer\r\n"));
+    goto CTRL_EXIT;
+  }
+  OhciSetEDField (Ed, ED_SKIP, 1);
+  OhciSetEDField (Ed, ED_FUNC_ADD, DeviceAddress);
+  OhciSetEDField (Ed, ED_ENDPT_NUM, 0);
+  OhciSetEDField (Ed, ED_DIR, ED_FROM_TD_DIR);
+  OhciSetEDField (Ed, ED_SPEED, IsSlowDevice);
+  OhciSetEDField (Ed, ED_FORMAT | ED_HALTED | ED_DTTOGGLE, 0);
+  OhciSetEDField (Ed, ED_MAX_PACKET, MaxPacketLength);
+  OhciSetEDField (Ed, ED_PDATA, 0);
+  OhciSetEDField (Ed, ED_ZERO, 0);
+  OhciSetEDField (Ed, ED_TDHEAD_PTR, 0);
+  OhciSetEDField (Ed, ED_TDTAIL_PTR, 0);
+  OhciSetEDField (Ed, ED_NEXT_EDPTR, 0);
+  HeadEd = OhciAttachEDToList (Ohc, CONTROL_LIST, Ed, NULL);
+  //
+  // Setup Stage
+  //
+  if(Request != NULL) {
+    ReqMapLength = sizeof(EFI_USB_DEVICE_REQUEST);
+    MapOp = EfiPciIoOperationBusMasterRead;
+    Status = Ohc->PciIo->Map (Ohc->PciIo, MapOp, (UINT8 *)Request, &ReqMapLength, &ReqMapPhyAddr, &ReqMapping);
+    if (EFI_ERROR(Status)) {
+      DEBUG ((EFI_D_INFO, "OhciControlTransfer: Fail to Map Request Buffer\r\n"));
+      goto FREE_ED_BUFF;
+    }
+  }
+  SetupTd = OhciCreateTD (Ohc);
+  if (SetupTd == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    DEBUG ((EFI_D_INFO, "OhciControlTransfer: Fail to allocate Setup TD buffer\r\n"));
+    goto UNMAP_SETUP_BUFF;
+  }
+  HeadTd = SetupTd;
+  OhciSetTDField (SetupTd, TD_PDATA, 0);
+  OhciSetTDField (SetupTd, TD_BUFFER_ROUND, 1);
+  OhciSetTDField (SetupTd, TD_DIR_PID, TD_SETUP_PID);
+  OhciSetTDField (SetupTd, TD_DELAY_INT, TD_NO_DELAY);
+  OhciSetTDField (SetupTd, TD_DT_TOGGLE, 2);
+  OhciSetTDField (SetupTd, TD_ERROR_CNT, 0);
+  OhciSetTDField (SetupTd, TD_COND_CODE, TD_TOBE_PROCESSED);
+  OhciSetTDField (SetupTd, TD_CURR_BUFFER_PTR, (UINT32)ReqMapPhyAddr);
+  OhciSetTDField (SetupTd, TD_NEXT_PTR, 0);
+  OhciSetTDField (SetupTd, TD_BUFFER_END_PTR, (UINT32)(ReqMapPhyAddr + sizeof (EFI_USB_DEVICE_REQUEST) - 1));
+  SetupTd->ActualSendLength = sizeof (EFI_USB_DEVICE_REQUEST);
+  SetupTd->DataBuffer = (UINT32)ReqMapPhyAddr;
+  SetupTd->NextTDPointer = 0;
+
+  if (TransferDirection == EfiUsbDataIn) {
+    MapOp = EfiPciIoOperationBusMasterWrite;
+  } else {
+    MapOp = EfiPciIoOperationBusMasterRead;
+  }
+  DataMapLength = *DataLength;
+  if ((Data != NULL) && (DataMapLength != 0)) {
+    Status = Ohc->PciIo->Map (Ohc->PciIo, MapOp, Data, &DataMapLength, &DataMapPhyAddr, &DataMapping);
+    if (EFI_ERROR(Status)) {
+      DEBUG ((EFI_D_INFO, "OhciControlTransfer: Fail To Map Data Buffer\r\n"));
+      goto FREE_TD_BUFF;
+    }
+  }
+  //
+  //Data Stage
+  //
+  LeftLength = DataMapLength;
+  ActualSendLength = DataMapLength;
+  DataToggle = 1;
+  while (LeftLength > 0) {
+    ActualSendLength = LeftLength;
+    if (LeftLength > MaxPacketLength) {
+      ActualSendLength = MaxPacketLength;
+    }
+    DataTd = OhciCreateTD (Ohc);
+    if (DataTd == NULL) {
+      DEBUG ((EFI_D_INFO, "OhciControlTransfer: Fail to allocate buffer for Data Stage TD\r\n"));
+      Status = EFI_OUT_OF_RESOURCES;
+      goto UNMAP_DATA_BUFF;
+    }
+    OhciSetTDField (DataTd, TD_PDATA, 0);
+    OhciSetTDField (DataTd, TD_BUFFER_ROUND, 1);
+    OhciSetTDField (DataTd, TD_DIR_PID, DataPidDir);
+    OhciSetTDField (DataTd, TD_DELAY_INT, TD_NO_DELAY);
+    OhciSetTDField (DataTd, TD_DT_TOGGLE, DataToggle);
+    OhciSetTDField (DataTd, TD_ERROR_CNT, 0);
+    OhciSetTDField (DataTd, TD_COND_CODE, TD_TOBE_PROCESSED);
+    OhciSetTDField (DataTd, TD_CURR_BUFFER_PTR, (UINT32) DataMapPhyAddr);
+    OhciSetTDField (DataTd, TD_BUFFER_END_PTR, (UINT32)(DataMapPhyAddr + ActualSendLength - 1));
+    OhciSetTDField (DataTd, TD_NEXT_PTR, 0);
+    DataTd->ActualSendLength = (UINT32)ActualSendLength;
+    DataTd->DataBuffer = (UINT32)DataMapPhyAddr;
+    DataTd->NextTDPointer = 0;
+    OhciLinkTD (HeadTd, DataTd);
+    DataToggle ^= 1;
+    DataMapPhyAddr += ActualSendLength;
+    LeftLength -= ActualSendLength;
+  }
+  //
+  // Status Stage
+  //
+  StatusTd = OhciCreateTD (Ohc);
+  if (StatusTd == NULL) {
+    DEBUG ((EFI_D_INFO, "OhciControlTransfer: Fail to allocate buffer for Status Stage TD\r\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto UNMAP_DATA_BUFF;
+  }
+  OhciSetTDField (StatusTd, TD_PDATA, 0);
+  OhciSetTDField (StatusTd, TD_BUFFER_ROUND, 1);
+  OhciSetTDField (StatusTd, TD_DIR_PID, StatusPidDir);
+  OhciSetTDField (StatusTd, TD_DELAY_INT, 7);
+  OhciSetTDField (StatusTd, TD_DT_TOGGLE, 3);
+  OhciSetTDField (StatusTd, TD_ERROR_CNT, 0);
+  OhciSetTDField (StatusTd, TD_COND_CODE, TD_TOBE_PROCESSED);
+  OhciSetTDField (StatusTd, TD_CURR_BUFFER_PTR, 0);
+  OhciSetTDField (StatusTd, TD_NEXT_PTR, 0);
+  OhciSetTDField (StatusTd, TD_BUFFER_END_PTR, 0);
+  StatusTd->ActualSendLength = 0;
+  StatusTd->DataBuffer = 0;
+  StatusTd->NextTDPointer = 0;
+  OhciLinkTD (HeadTd, StatusTd);
+  //
+  // Empty Stage
+  //
+  EmptyTd = OhciCreateTD (Ohc);
+  if (EmptyTd == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto UNMAP_DATA_BUFF;
+  }
+  OhciSetTDField (EmptyTd, TD_PDATA, 0);
+  OhciSetTDField (EmptyTd, TD_BUFFER_ROUND, 0);
+  OhciSetTDField (EmptyTd, TD_DIR_PID, 0);
+  OhciSetTDField (EmptyTd, TD_DELAY_INT, 0);
+  //OhciSetTDField (EmptyTd, TD_DT_TOGGLE, CurrentToggle);
+  EmptyTd->Word0.DataToggle = 0;
+  OhciSetTDField (EmptyTd, TD_ERROR_CNT, 0);
+  OhciSetTDField (EmptyTd, TD_COND_CODE, 0);
+  OhciSetTDField (EmptyTd, TD_CURR_BUFFER_PTR, 0);
+  OhciSetTDField (EmptyTd, TD_BUFFER_END_PTR, 0);
+  OhciSetTDField (EmptyTd, TD_NEXT_PTR, 0);
+  EmptyTd->ActualSendLength = 0;
+  EmptyTd->DataBuffer = 0;
+  EmptyTd->NextTDPointer = 0;
+  OhciLinkTD (HeadTd, EmptyTd);
+  Ed->TdTailPointer = (UINT32)(UINTN)EmptyTd;
+  OhciAttachTDListToED (Ed, HeadTd);
+  //
+  // For debugging,  dump ED & TD buffer befor transferring
+  //
+  //
+  //OhciDumpEdTdInfo (Ohc, Ed, HeadTd, TRUE);
+  //
+  OhciSetEDField (Ed, ED_SKIP, 0);
+  Status = OhciSetHcControl (Ohc, CONTROL_ENABLE, 1);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_INFO, "OhciControlTransfer: fail to enable CONTROL_ENABLE\r\n"));
+    *TransferResult = EFI_USB_ERR_SYSTEM;
+    Status = EFI_DEVICE_ERROR;
+    goto UNMAP_DATA_BUFF;
+  }
+  Status = OhciSetHcCommandStatus (Ohc, CONTROL_LIST_FILLED, 1);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_INFO, "OhciControlTransfer: fail to enable CONTROL_LIST_FILLED\r\n"));
+    *TransferResult = EFI_USB_ERR_SYSTEM;
+    Status = EFI_DEVICE_ERROR;
+    goto UNMAP_DATA_BUFF;
+  }
+  gBS->Stall(20 * 1000);
+
+
+  TimeCount = 0;
+  Status = CheckIfDone (Ohc, CONTROL_LIST, Ed, HeadTd, &EdResult);
+
+  while (Status == EFI_NOT_READY && TimeCount <= TimeOut) {
+    gBS->Stall (1000);
+    TimeCount++;
+    Status = CheckIfDone (Ohc, CONTROL_LIST, Ed, HeadTd, &EdResult);
+  }
+  //
+  // For debugging, dump ED & TD buffer after transferring
+  //
+  //OhciDumpEdTdInfo (Ohc, Ed, HeadTd, FALSE);
+  //
+  *TransferResult = ConvertErrorCode (EdResult.ErrorCode);
+
+  if (EdResult.ErrorCode != TD_NO_ERROR) {
+    if (EdResult.ErrorCode == TD_TOBE_PROCESSED) {
+      DEBUG ((EFI_D_INFO, "Control pipe timeout, > %d mS\r\n", TimeOut));
+    } else {
+      DEBUG ((EFI_D_INFO, "Control pipe broken\r\n"));
+    }
+    *DataLength = 0;
+  } else {
+    DEBUG ((EFI_D_INFO, "Control transfer successed\r\n"));
+  }
+
+UNMAP_DATA_BUFF:
+  OhciSetEDField (Ed, ED_SKIP, 1);
+  if (HeadEd == Ed) {
+    OhciSetMemoryPointer (Ohc, HC_CONTROL_HEAD, NULL);
+  } else {
+    HeadEd->NextED = Ed->NextED;
+  }
+  if(DataMapping != NULL) {
+    Ohc->PciIo->Unmap(Ohc->PciIo, DataMapping);
+  }
+
+FREE_TD_BUFF:
+  while (HeadTd) {
+    DataTd = HeadTd;
+    HeadTd = (TD_DESCRIPTOR *)(UINTN)(HeadTd->NextTDPointer);
+    UsbHcFreeMem(Ohc->MemPool, DataTd, sizeof(TD_DESCRIPTOR));
+  }
+
+UNMAP_SETUP_BUFF:
+  if(ReqMapping != NULL) {
+    Ohc->PciIo->Unmap(Ohc->PciIo, ReqMapping);
+  }
+
+FREE_ED_BUFF:
+  UsbHcFreeMem(Ohc->MemPool, Ed, sizeof(ED_DESCRIPTOR));
+
+CTRL_EXIT:
+  return Status;
+}
+
+/**
+
+  Submits bulk transfer to a bulk endpoint of a USB device.
+
+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
+  @param  DeviceAddress         Represents the address of the target device on the USB,
+                                which is assigned during USB enumeration.
+  @param  EndPointAddress       The combination of an endpoint number and an
+                                endpoint direction of the target USB device.
+                                Each endpoint address supports data transfer in
+                                one direction except the control endpoint
+                                (whose default endpoint address is 0).
+                                It is the caller's responsibility to make sure that
+                                the EndPointAddress represents a bulk endpoint.
+  @param  MaximumPacketLength   Indicates the maximum packet size the target endpoint
+                                is capable of sending or receiving.
+  @param  Data                  A pointer to the buffer of data that will be transmitted
+                                to USB device or received from USB device.
+  @param  DataLength            When input, indicates the size, in bytes, of the data buffer
+                                specified by Data. When output, indicates the actually
+                                transferred data size.
+  @param  DataToggle            A pointer to the data toggle value. On input, it indicates
+                                the initial data toggle value the bulk transfer should adopt;
+                                on output, it is updated to indicate the data toggle value
+                                of the subsequent bulk transfer.
+  @param  TimeOut               Indicates the maximum time, in microseconds, which the
+                                transfer is allowed to complete.
+  TransferResult                A pointer to the detailed result information of the
+                                bulk transfer.
+
+  @retval EFI_SUCCESS           The bulk transfer was completed successfully.
+  @retval EFI_OUT_OF_RESOURCES  The bulk transfer could not be submitted due to lack of resource.
+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
+  @retval EFI_TIMEOUT           The bulk transfer failed due to timeout.
+  @retval EFI_DEVICE_ERROR      The bulk transfer failed due to host controller or device error.
+                                Caller should check TranferResult for detailed error information.
+
+**/
+
+
+EFI_STATUS
+EFIAPI
+OhciBulkTransfer(
+  IN     EFI_USB_HC_PROTOCOL  *This,
+  IN     UINT8                DeviceAddress,
+  IN     UINT8                EndPointAddress,
+  IN     UINT8                MaxPacketLength,
+  IN OUT VOID                 *Data,
+  IN OUT UINTN                *DataLength,
+  IN OUT UINT8                *DataToggle,
+  IN     UINTN                TimeOut,
+  OUT    UINT32               *TransferResult
+  )
+{
+  USB_OHCI_HC_DEV                *Ohc;
+  ED_DESCRIPTOR                  *HeadEd;
+  ED_DESCRIPTOR                  *Ed;
+  UINT32                         DataPidDir;
+  TD_DESCRIPTOR                  *HeadTd;
+  TD_DESCRIPTOR                  *DataTd;
+  TD_DESCRIPTOR                  *EmptyTd;
+  EFI_STATUS                     Status;
+  UINT8                          EndPointNum;
+  UINTN                          TimeCount;
+  OHCI_ED_RESULT                 EdResult;
+
+  EFI_PCI_IO_PROTOCOL_OPERATION  MapOp;
+  VOID                           *Mapping;
+  UINTN                          MapLength;
+  EFI_PHYSICAL_ADDRESS           MapPyhAddr;
+  UINTN                          LeftLength;
+  UINTN                          ActualSendLength;
+  BOOLEAN                        FirstTD;
+
+  Mapping = NULL;
+  MapLength = 0;
+  MapPyhAddr = 0;
+  LeftLength = 0;
+  Status = EFI_SUCCESS;
+
+  if (Data == NULL || DataLength == NULL || DataToggle == NULL || TransferResult == NULL ||
+      *DataLength == 0 || (*DataToggle != 0 && *DataToggle != 1) ||
+      (MaxPacketLength != 8 && MaxPacketLength != 16 &&
+       MaxPacketLength != 32 && MaxPacketLength != 64)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Ohc = USB_OHCI_HC_DEV_FROM_THIS (This);
+
+  if ((EndPointAddress & 0x80) != 0) {
+    DataPidDir = TD_IN_PID;
+    MapOp = EfiPciIoOperationBusMasterWrite;
+  } else {
+    DataPidDir = TD_OUT_PID;
+    MapOp = EfiPciIoOperationBusMasterRead;
+  }
+
+  EndPointNum = (EndPointAddress & 0xF);
+  EdResult.NextToggle = *DataToggle;
+
+  Status = OhciSetHcControl (Ohc, BULK_ENABLE, 0);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_INFO, "OhciControlTransfer: fail to disable BULK_ENABLE\r\n"));
+    *TransferResult = EFI_USB_ERR_SYSTEM;
+    return EFI_DEVICE_ERROR;
+  }
+  Status = OhciSetHcCommandStatus (Ohc, BULK_LIST_FILLED, 0);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_INFO, "OhciControlTransfer: fail to disable BULK_LIST_FILLED\r\n"));
+    *TransferResult = EFI_USB_ERR_SYSTEM;
+    return EFI_DEVICE_ERROR;
+  }
+  gBS->Stall(20 * 1000);
+
+  OhciSetMemoryPointer (Ohc, HC_BULK_HEAD, NULL);
+
+  Ed = OhciCreateED (Ohc);
+  if (Ed == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  OhciSetEDField (Ed, ED_SKIP, 1);
+  OhciSetEDField (Ed, ED_FUNC_ADD, DeviceAddress);
+  OhciSetEDField (Ed, ED_ENDPT_NUM, EndPointNum);
+  OhciSetEDField (Ed, ED_DIR, ED_FROM_TD_DIR);
+  OhciSetEDField (Ed, ED_SPEED, HI_SPEED);
+  OhciSetEDField (Ed, ED_FORMAT | ED_HALTED | ED_DTTOGGLE, 0);
+  OhciSetEDField (Ed, ED_MAX_PACKET, MaxPacketLength);
+  OhciSetEDField (Ed, ED_PDATA, 0);
+  OhciSetEDField (Ed, ED_ZERO, 0);
+  OhciSetEDField (Ed, ED_TDHEAD_PTR, 0);
+  OhciSetEDField (Ed, ED_TDTAIL_PTR, 0);
+  OhciSetEDField (Ed, ED_NEXT_EDPTR, 0);
+  HeadEd = OhciAttachEDToList (Ohc, BULK_LIST, Ed, NULL);
+
+  if(Data != NULL) {
+    MapLength = *DataLength;
+    Status = Ohc->PciIo->Map (Ohc->PciIo, MapOp, (UINT8 *)Data, &MapLength, &MapPyhAddr, &Mapping);
+    if (EFI_ERROR(Status)) {
+      DEBUG ((EFI_D_INFO, "OhciBulkTransfer: Fail to Map Data Buffer for Bulk\r\n"));
+      goto FREE_ED_BUFF;
+    }
+  }
+  //
+  //Data Stage
+  //
+  LeftLength = MapLength;
+  ActualSendLength = MapLength;
+  HeadTd = NULL;
+  FirstTD = TRUE;
+  while (LeftLength > 0) {
+    ActualSendLength = LeftLength;
+    if (LeftLength > MaxPacketLength) {
+      ActualSendLength = MaxPacketLength;
+    }
+    DataTd = OhciCreateTD (Ohc);
+    if (DataTd == NULL) {
+      DEBUG ((EFI_D_INFO, "OhciBulkTransfer: Fail to allocate buffer for Data Stage TD\r\n"));
+      Status = EFI_OUT_OF_RESOURCES;
+      goto FREE_OHCI_TDBUFF;
+    }
+    OhciSetTDField (DataTd, TD_PDATA, 0);
+    OhciSetTDField (DataTd, TD_BUFFER_ROUND, 1);
+    OhciSetTDField (DataTd, TD_DIR_PID, DataPidDir);
+    OhciSetTDField (DataTd, TD_DELAY_INT, TD_NO_DELAY);
+    OhciSetTDField (DataTd, TD_DT_TOGGLE, *DataToggle);
+    OhciSetTDField (DataTd, TD_ERROR_CNT, 0);
+    OhciSetTDField (DataTd, TD_COND_CODE, TD_TOBE_PROCESSED);
+    OhciSetTDField (DataTd, TD_CURR_BUFFER_PTR, (UINT32) MapPyhAddr);
+    OhciSetTDField (DataTd, TD_BUFFER_END_PTR, (UINT32)(MapPyhAddr + ActualSendLength - 1));
+    OhciSetTDField (DataTd, TD_NEXT_PTR, 0);
+    DataTd->ActualSendLength = (UINT32)ActualSendLength;
+    DataTd->DataBuffer = (UINT32)MapPyhAddr;
+    DataTd->NextTDPointer = 0;
+    if (FirstTD) {
+      HeadTd = DataTd;
+      FirstTD = FALSE;
+    } else {
+      OhciLinkTD (HeadTd, DataTd);
+    }
+    *DataToggle ^= 1;
+    MapPyhAddr += ActualSendLength;
+    LeftLength -= ActualSendLength;
+  }
+  //
+  // Empty Stage
+  //
+  EmptyTd = OhciCreateTD (Ohc);
+  if (EmptyTd == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    DEBUG ((EFI_D_INFO, "OhciBulkTransfer: Fail to allocate buffer for Empty TD\r\n"));
+    goto FREE_OHCI_TDBUFF;
+  }
+  OhciSetTDField (EmptyTd, TD_PDATA, 0);
+  OhciSetTDField (EmptyTd, TD_BUFFER_ROUND, 0);
+  OhciSetTDField (EmptyTd, TD_DIR_PID, 0);
+  OhciSetTDField (EmptyTd, TD_DELAY_INT, 0);
+  //OhciSetTDField (EmptyTd, TD_DT_TOGGLE, CurrentToggle);
+  EmptyTd->Word0.DataToggle = 0;
+  OhciSetTDField (EmptyTd, TD_ERROR_CNT, 0);
+  OhciSetTDField (EmptyTd, TD_COND_CODE, 0);
+  OhciSetTDField (EmptyTd, TD_CURR_BUFFER_PTR, 0);
+  OhciSetTDField (EmptyTd, TD_BUFFER_END_PTR, 0);
+  OhciSetTDField (EmptyTd, TD_NEXT_PTR, 0);
+  EmptyTd->ActualSendLength = 0;
+  EmptyTd->DataBuffer = 0;
+  EmptyTd->NextTDPointer = 0;
+  OhciLinkTD (HeadTd, EmptyTd);
+  Ed->TdTailPointer = (UINT32)(UINTN)EmptyTd;
+  OhciAttachTDListToED (Ed, HeadTd);
+
+  OhciSetEDField (Ed, ED_SKIP, 0);
+  Status = OhciSetHcCommandStatus (Ohc, BULK_LIST_FILLED, 1);
+  if (EFI_ERROR(Status)) {
+    *TransferResult = EFI_USB_ERR_SYSTEM;
+    Status = EFI_DEVICE_ERROR;
+    DEBUG ((EFI_D_INFO, "OhciControlTransfer: Fail to enable BULK_LIST_FILLED\r\n"));
+    goto FREE_OHCI_TDBUFF;
+  }
+  Status = OhciSetHcControl (Ohc, BULK_ENABLE, 1);
+  if (EFI_ERROR(Status)) {
+    *TransferResult = EFI_USB_ERR_SYSTEM;
+    Status = EFI_DEVICE_ERROR;
+    DEBUG ((EFI_D_INFO, "OhciControlTransfer: Fail to enable BULK_ENABLE\r\n"));
+    goto FREE_OHCI_TDBUFF;
+  }
+  gBS->Stall(20 * 1000);
+
+  TimeCount = 0;
+  Status = CheckIfDone (Ohc, BULK_LIST, Ed, HeadTd, &EdResult);
+  while (Status == EFI_NOT_READY && TimeCount <= TimeOut) {
+    gBS->Stall (1000);
+    TimeCount++;
+    Status = CheckIfDone (Ohc, BULK_LIST, Ed, HeadTd, &EdResult);
+  }
+
+  *TransferResult = ConvertErrorCode (EdResult.ErrorCode);
+
+  if (EdResult.ErrorCode != TD_NO_ERROR) {
+    if (EdResult.ErrorCode == TD_TOBE_PROCESSED) {
+      DEBUG ((EFI_D_INFO, "Bulk pipe timeout, > %d mS\r\n", TimeOut));
+    } else {
+      DEBUG ((EFI_D_INFO, "Bulk pipe broken\r\n"));
+      *DataToggle = EdResult.NextToggle;
+    }
+    *DataLength = 0;
+  } else {
+    DEBUG ((EFI_D_INFO, "Bulk transfer successed\r\n"));
+  }
+  //*DataToggle = (UINT8) OhciGetEDField (Ed, ED_DTTOGGLE);
+
+FREE_OHCI_TDBUFF:
+  OhciSetEDField (Ed, ED_SKIP, 1);
+  if (HeadEd == Ed) {
+    OhciSetMemoryPointer (Ohc, HC_BULK_HEAD, NULL);
+  }else {
+    HeadEd->NextED = Ed->NextED;
+  }
+  while (HeadTd) {
+    DataTd = HeadTd;
+    HeadTd = (TD_DESCRIPTOR *)(UINTN)(HeadTd->NextTDPointer);
+    UsbHcFreeMem(Ohc->MemPool, DataTd, sizeof(TD_DESCRIPTOR));
+  }
+
+  if(Mapping != NULL) {
+    Ohc->PciIo->Unmap(Ohc->PciIo, Mapping);
+  }
+
+FREE_ED_BUFF:
+  UsbHcFreeMem(Ohc->MemPool, Ed, sizeof(ED_DESCRIPTOR));
+
+  return Status;
+}
+/**
+
+  Submits an interrupt transfer to an interrupt endpoint of a USB device.
+
+  @param  Ohc                   Device private data
+  @param  DeviceAddress         Represents the address of the target device on the USB,
+                                which is assigned during USB enumeration.
+  @param  EndPointAddress       The combination of an endpoint number and an endpoint
+                                direction of the target USB device. Each endpoint address
+                                supports data transfer in one direction except the
+                                control endpoint (whose default endpoint address is 0).
+                                It is the caller's responsibility to make sure that
+                                the EndPointAddress represents an interrupt endpoint.
+  @param  IsSlowDevice          Indicates whether the target device is slow device
+                                or full-speed device.
+  @param  MaxPacketLength       Indicates the maximum packet size the target endpoint
+                                is capable of sending or receiving.
+  @param  IsNewTransfer         If TRUE, an asynchronous interrupt pipe is built between
+                                the host and the target interrupt endpoint.
+                                If FALSE, the specified asynchronous interrupt pipe
+                                is canceled.
+  @param  DataToggle            A pointer to the data toggle value.  On input, it is valid
+                                when IsNewTransfer is TRUE, and it indicates the initial
+                                data toggle value the asynchronous interrupt transfer
+                                should adopt.
+                                On output, it is valid when IsNewTransfer is FALSE,
+                                and it is updated to indicate the data toggle value of
+                                the subsequent asynchronous interrupt transfer.
+  @param  PollingInterval       Indicates the interval, in milliseconds, that the
+                                asynchronous interrupt transfer is polled.
+                                This parameter is required when IsNewTransfer is TRUE.
+  @param  UCBuffer              Uncacheable buffer
+  @param  DataLength            Indicates the length of data to be received at the
+                                rate specified by PollingInterval from the target
+                                asynchronous interrupt endpoint.  This parameter
+                                is only required when IsNewTransfer is TRUE.
+  @param  CallBackFunction      The Callback function.This function is called at the
+                                rate specified by PollingInterval.This parameter is
+                                only required when IsNewTransfer is TRUE.
+  @param  Context               The context that is passed to the CallBackFunction.
+                                This is an optional parameter and may be NULL.
+  @param  IsPeriodic            Periodic interrupt or not
+  @param  OutputED              The correspoding ED carried out
+  @param  OutputTD              The correspoding TD carried out
+
+
+  @retval EFI_SUCCESS           The asynchronous interrupt transfer request has been successfully
+                                submitted or canceled.
+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
+
+**/
+
+EFI_STATUS
+OhciInterruptTransfer (
+  IN     USB_OHCI_HC_DEV                  *Ohc,
+  IN     UINT8                            DeviceAddress,
+  IN     UINT8                            EndPointAddress,
+  IN     BOOLEAN                          IsSlowDevice,
+  IN     UINT8                            MaxPacketLength,
+  IN     BOOLEAN                          IsNewTransfer,
+  IN OUT UINT8                            *DataToggle        OPTIONAL,
+  IN     UINTN                            PollingInterval    OPTIONAL,
+  IN     VOID                             *UCBuffer          OPTIONAL,
+  IN     UINTN                            DataLength         OPTIONAL,
+  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK  CallBackFunction   OPTIONAL,
+  IN     VOID                             *Context           OPTIONAL,
+  IN     BOOLEAN                          IsPeriodic         OPTIONAL,
+  OUT    ED_DESCRIPTOR                    **OutputED         OPTIONAL,
+  OUT    TD_DESCRIPTOR                    **OutputTD         OPTIONAL
+  )
+{
+  ED_DESCRIPTOR            *Ed;
+  UINT8                    EdDir;
+  ED_DESCRIPTOR            *HeadEd;
+  TD_DESCRIPTOR            *HeadTd;
+  TD_DESCRIPTOR            *DataTd;
+  TD_DESCRIPTOR            *EmptTd;
+  UINTN                    Depth;
+  UINTN                    Index;
+  EFI_STATUS               Status;
+  UINT8                    EndPointNum;
+  UINT32                   DataPidDir;
+  INTERRUPT_CONTEXT_ENTRY  *Entry;
+  EFI_TPL                  OldTpl;
+  BOOLEAN                  FirstTD;
+
+ VOID                      *Mapping;
+ UINTN                     MapLength;
+ EFI_PHYSICAL_ADDRESS      MapPyhAddr;
+ UINTN                     LeftLength;
+ UINTN                     ActualSendLength;
+
+
+  if (DataLength > MAX_BYTES_PER_TD) {
+    DEBUG ((EFI_D_ERROR, "OhciInterruptTransfer: Error param\r\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((EndPointAddress & 0x80) != 0) {
+    EdDir = ED_IN_DIR;
+    DataPidDir = TD_IN_PID;
+  } else {
+    EdDir = ED_OUT_DIR;
+    DataPidDir = TD_OUT_PID;
+  }
+
+  EndPointNum = (EndPointAddress & 0xF);
+
+  if (!IsNewTransfer) {
+    OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+    OhciSetHcControl (Ohc, PERIODIC_ENABLE, 0);
+    OhciFreeInterruptContext (Ohc, DeviceAddress, EndPointAddress, DataToggle);
+    Status = OhciFreeInterruptEdByAddr (Ohc, DeviceAddress, EndPointNum);
+    OhciSetHcControl (Ohc, PERIODIC_ENABLE, 1);
+    gBS->RestoreTPL (OldTpl);
+    return Status;
+  }
+  MapLength = DataLength;
+  Status = Ohc->PciIo->Map(
+                         Ohc->PciIo,
+                         EfiPciIoOperationBusMasterWrite,
+                         UCBuffer,
+                         &MapLength,
+                         &MapPyhAddr,
+                         &Mapping
+                         );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "OhciInterruptTransfer: Failt to PciIo->Map buffer \r\n"));
+    goto EXIT;
+  }
+  Depth = 5;
+  Index = 1;
+  while (PollingInterval >= Index * 2 && Depth > 0) {
+    Index *= 2;
+    Depth--;
+  }
+  //
+  //ED Stage
+  //
+  HeadEd = OhciFindMinInterruptEDList (Ohc, (UINT32)Depth);
+  if ((Ed = OhciFindWorkingEd (HeadEd, DeviceAddress, EndPointNum, EdDir)) != NULL) {
+    OhciSetEDField (Ed, ED_SKIP, 1);
+  } else {
+    Ed = OhciCreateED (Ohc);
+    if (Ed == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      DEBUG ((EFI_D_ERROR, "OhciInterruptTransfer: Fail to allocate buffer for ED\r\n"));
+      goto UNMAP_OHCI_XBUFF;
+    }
+    OhciSetEDField (Ed, ED_SKIP, 1);
+    OhciSetEDField (Ed, ED_FUNC_ADD, DeviceAddress);
+    OhciSetEDField (Ed, ED_ENDPT_NUM, EndPointNum);
+    OhciSetEDField (Ed, ED_DIR, ED_FROM_TD_DIR);
+    OhciSetEDField (Ed, ED_SPEED, IsSlowDevice);
+    OhciSetEDField (Ed, ED_FORMAT, 0);
+    OhciSetEDField (Ed, ED_MAX_PACKET, MaxPacketLength);
+    OhciSetEDField (Ed, ED_PDATA | ED_ZERO | ED_HALTED | ED_DTTOGGLE, 0);
+    OhciSetEDField (Ed, ED_TDHEAD_PTR, 0);
+    OhciSetEDField (Ed, ED_TDTAIL_PTR, 0);
+    OhciSetEDField (Ed, ED_NEXT_EDPTR, 0);
+    OhciAttachEDToList (Ohc, INTERRUPT_LIST, Ed, HeadEd);
+  }
+  //
+  //Data Stage
+  //
+  LeftLength = MapLength;
+  ActualSendLength = MapLength;
+  HeadTd = NULL;
+  FirstTD = TRUE;
+  while (LeftLength > 0) {
+    ActualSendLength = LeftLength;
+    if (LeftLength > MaxPacketLength) {
+      ActualSendLength = MaxPacketLength;
+    }
+    DataTd = OhciCreateTD (Ohc);
+    if (DataTd == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      DEBUG ((EFI_D_ERROR, "OhciInterruptTransfer: Fail to allocate buffer for Data Stage TD\r\n"));
+      goto FREE_OHCI_TDBUFF;
+    }
+    OhciSetTDField (DataTd, TD_PDATA, 0);
+    OhciSetTDField (DataTd, TD_BUFFER_ROUND, 1);
+    OhciSetTDField (DataTd, TD_DIR_PID, DataPidDir);
+    OhciSetTDField (DataTd, TD_DELAY_INT, TD_NO_DELAY);
+    OhciSetTDField (DataTd, TD_DT_TOGGLE, *DataToggle);
+    OhciSetTDField (DataTd, TD_ERROR_CNT, 0);
+    OhciSetTDField (DataTd, TD_COND_CODE, TD_TOBE_PROCESSED);
+    OhciSetTDField (DataTd, TD_CURR_BUFFER_PTR, (UINT32) MapPyhAddr);
+    OhciSetTDField (DataTd, TD_BUFFER_END_PTR, (UINT32)(MapPyhAddr + ActualSendLength - 1));
+    OhciSetTDField (DataTd, TD_NEXT_PTR, 0);
+    DataTd->ActualSendLength = (UINT32)ActualSendLength;
+    DataTd->DataBuffer = (UINT32)MapPyhAddr;
+    DataTd->NextTDPointer = 0;
+    if (FirstTD) {
+      HeadTd = DataTd;
+      FirstTD = FALSE;
+    } else {
+      OhciLinkTD (HeadTd, DataTd);
+    }
+    *DataToggle ^= 1;
+    MapPyhAddr += ActualSendLength;
+    LeftLength -= ActualSendLength;
+  }
+
+  EmptTd = OhciCreateTD (Ohc);
+  if (EmptTd == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    DEBUG ((EFI_D_ERROR, "OhciInterruptTransfer: Fail to allocate buffer for Empty Stage TD\r\n"));
+    goto FREE_OHCI_TDBUFF;
+  }
+  OhciSetTDField (EmptTd, TD_PDATA, 0);
+  OhciSetTDField (EmptTd, TD_BUFFER_ROUND, 0);
+  OhciSetTDField (EmptTd, TD_DIR_PID, 0);
+  OhciSetTDField (EmptTd, TD_DELAY_INT, 0);
+  //OhciSetTDField (EmptTd, TD_DT_TOGGLE, CurrentToggle);
+  EmptTd->Word0.DataToggle = 0;
+  OhciSetTDField (EmptTd, TD_ERROR_CNT, 0);
+  OhciSetTDField (EmptTd, TD_COND_CODE, 0);
+  OhciSetTDField (EmptTd, TD_CURR_BUFFER_PTR, 0);
+  OhciSetTDField (EmptTd, TD_BUFFER_END_PTR, 0);
+  OhciSetTDField (EmptTd, TD_NEXT_PTR, 0);
+  EmptTd->ActualSendLength = 0;
+  EmptTd->DataBuffer = 0;
+  EmptTd->NextTDPointer = 0;
+  OhciLinkTD (HeadTd, EmptTd);
+  Ed->TdTailPointer = (UINT32)(UINTN)EmptTd;
+  OhciAttachTDListToED (Ed, HeadTd);
+
+  if (OutputED != NULL) {
+    *OutputED = Ed;
+  }
+  if (OutputTD != NULL) {
+    *OutputTD = HeadTd;
+  }
+
+  if (CallBackFunction != NULL) {
+    Entry = AllocatePool (sizeof (INTERRUPT_CONTEXT_ENTRY));
+    if (Entry == NULL) {
+      goto FREE_OHCI_TDBUFF;
+    }
+
+    Entry->DeviceAddress = DeviceAddress;
+    Entry->EndPointAddress = EndPointAddress;
+    Entry->Ed = Ed;
+    Entry->DataTd = HeadTd;
+    Entry->IsSlowDevice = IsSlowDevice;
+    Entry->MaxPacketLength = MaxPacketLength;
+    Entry->PollingInterval = PollingInterval;
+    Entry->CallBackFunction = CallBackFunction;
+    Entry->Context = Context;
+    Entry->IsPeriodic = IsPeriodic;
+    Entry->UCBuffer = UCBuffer;
+    Entry->UCBufferMapping = Mapping;
+    Entry->DataLength = DataLength;
+    Entry->Toggle = DataToggle;
+    Entry->NextEntry = NULL;
+    OhciAddInterruptContextEntry (Ohc, Entry);
+  }
+  OhciSetEDField (Ed, ED_SKIP, 0);
+
+  if (OhciGetHcControl (Ohc, PERIODIC_ENABLE) == 0) {
+    Status = OhciSetHcControl (Ohc, PERIODIC_ENABLE, 1);
+    gBS->Stall (1000);
+  }
+
+  return EFI_SUCCESS;
+
+FREE_OHCI_TDBUFF:
+  while (HeadTd) {
+    DataTd = HeadTd;
+    HeadTd = (TD_DESCRIPTOR *)(UINTN)(HeadTd->NextTDPointer);
+    UsbHcFreeMem(Ohc->MemPool, DataTd, sizeof(TD_DESCRIPTOR));
+  }
+
+//FREE_OHCI_EDBUFF:
+  if ((HeadEd != Ed) && HeadEd && Ed) {
+    while(HeadEd->NextED != (UINT32)(UINTN)Ed) {
+      HeadEd = (ED_DESCRIPTOR *)(UINTN)(HeadEd->NextED);
+    }
+  HeadEd->NextED = Ed->NextED;
+    UsbHcFreeMem(Ohc->MemPool, Ed, sizeof(ED_DESCRIPTOR));
+  }
+
+UNMAP_OHCI_XBUFF:
+  Ohc->PciIo->Unmap(Ohc->PciIo, Mapping);
+
+EXIT:
+  return Status;
+}
+
+/**
+
+  Submits an asynchronous interrupt transfer to an interrupt endpoint of a USB device.
+
+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
+  @param  DeviceAddress         Represents the address of the target device on the USB,
+                                which is assigned during USB enumeration.
+  @param  EndPointAddress       The combination of an endpoint number and an endpoint
+                                direction of the target USB device. Each endpoint address
+                                supports data transfer in one direction except the
+                                control endpoint (whose default endpoint address is 0).
+                                It is the caller's responsibility to make sure that
+                                the EndPointAddress represents an interrupt endpoint.
+  @param  IsSlowDevice          Indicates whether the target device is slow device
+                                or full-speed device.
+  @param  MaxiumPacketLength    Indicates the maximum packet size the target endpoint
+                                is capable of sending or receiving.
+  @param  IsNewTransfer         If TRUE, an asynchronous interrupt pipe is built between
+                                the host and the target interrupt endpoint.
+                                If FALSE, the specified asynchronous interrupt pipe
+                                is canceled.
+  @param  DataToggle            A pointer to the data toggle value.  On input, it is valid
+                                when IsNewTransfer is TRUE, and it indicates the initial
+                                data toggle value the asynchronous interrupt transfer
+                                should adopt.
+                                On output, it is valid when IsNewTransfer is FALSE,
+                                and it is updated to indicate the data toggle value of
+                                the subsequent asynchronous interrupt transfer.
+  @param  PollingInterval       Indicates the interval, in milliseconds, that the
+                                asynchronous interrupt transfer is polled.
+                                This parameter is required when IsNewTransfer is TRUE.
+  @param  DataLength            Indicates the length of data to be received at the
+                                rate specified by PollingInterval from the target
+                                asynchronous interrupt endpoint.  This parameter
+                                is only required when IsNewTransfer is TRUE.
+  @param  CallBackFunction      The Callback function.This function is called at the
+                                rate specified by PollingInterval.This parameter is
+                                only required when IsNewTransfer is TRUE.
+  @param  Context               The context that is passed to the CallBackFunction.
+                                This is an optional parameter and may be NULL.
+
+  @retval EFI_SUCCESS           The asynchronous interrupt transfer request has been successfully
+                                submitted or canceled.
+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
+
+**/
+
+
+EFI_STATUS
+EFIAPI
+OhciAsyncInterruptTransfer (
+  IN     EFI_USB_HC_PROTOCOL              *This,
+  IN     UINT8                            DeviceAddress,
+  IN     UINT8                            EndPointAddress,
+  IN     BOOLEAN                          IsSlowDevice,
+  IN     UINT8                            MaxPacketLength,
+  IN     BOOLEAN                          IsNewTransfer,
+  IN OUT UINT8                            *DataToggle        OPTIONAL,
+  IN     UINTN                            PollingInterval    OPTIONAL,
+  IN     UINTN                            DataLength         OPTIONAL,
+  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK  CallBackFunction   OPTIONAL,
+  IN     VOID                             *Context           OPTIONAL
+  )
+{
+  EFI_STATUS              Status;
+  USB_OHCI_HC_DEV         *Ohc;
+  VOID                    *UCBuffer;
+
+  if (DataToggle == NULL || (EndPointAddress & 0x80) == 0 ||
+    (IsNewTransfer && (DataLength == 0 ||
+    (*DataToggle != 0 && *DataToggle != 1) || (PollingInterval < 1 || PollingInterval > 255)))) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Ohc = USB_OHCI_HC_DEV_FROM_THIS (This);
+  if ( IsNewTransfer ) {
+    UCBuffer = AllocatePool(DataLength);
+    if (UCBuffer == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+  } else {
+    UCBuffer = NULL;
+  }
+  Status = OhciInterruptTransfer (
+             Ohc,
+             DeviceAddress,
+             EndPointAddress,
+             IsSlowDevice,
+             MaxPacketLength,
+             IsNewTransfer,
+             DataToggle,
+             PollingInterval,
+             UCBuffer,
+             DataLength,
+             CallBackFunction,
+             Context,
+             TRUE,
+             NULL,
+             NULL
+             );
+  if ( IsNewTransfer ) {
+    if (EFI_ERROR(Status)) {
+      gBS->FreePool (UCBuffer);
+    }
+  }
+  return Status;
+}
+
+
+/**
+
+  Submits synchronous interrupt transfer to an interrupt endpoint
+  of a USB device.
+
+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
+  @param  DeviceAddress         Represents the address of the target device on the USB,
+                                which is assigned during USB enumeration.
+  @param  EndPointAddress       The combination of an endpoint number and an endpoint
+                                direction of the target USB device. Each endpoint
+                                address supports data transfer in one direction
+                                except the control endpoint (whose default
+                                endpoint address is 0). It is the caller's responsibility
+                                to make sure that the EndPointAddress represents
+                                an interrupt endpoint.
+  @param  IsSlowDevice          Indicates whether the target device is slow device
+                                or full-speed device.
+  @param  MaxPacketLength       Indicates the maximum packet size the target endpoint
+                                is capable of sending or receiving.
+  @param  Data                  A pointer to the buffer of data that will be transmitted
+                                to USB device or received from USB device.
+  @param  DataLength            On input, the size, in bytes, of the data buffer specified
+                                by Data. On output, the number of bytes transferred.
+  @param  DataToggle            A pointer to the data toggle value. On input, it indicates
+                                the initial data toggle value the synchronous interrupt
+                                transfer should adopt;
+                                on output, it is updated to indicate the data toggle value
+                                of the subsequent synchronous interrupt transfer.
+  @param  TimeOut               Indicates the maximum time, in microseconds, which the
+                                transfer is allowed to complete.
+  @param  TransferResult        A pointer to the detailed result information from
+                                the synchronous interrupt transfer.
+
+  @retval EFI_UNSUPPORTED       This interface not available.
+  @retval EFI_INVALID_PARAMETER Parameters not follow spec
+
+**/
+
+
+EFI_STATUS
+EFIAPI
+OhciSyncInterruptTransfer (
+  IN     EFI_USB_HC_PROTOCOL  *This,
+  IN     UINT8                DeviceAddress,
+  IN     UINT8                EndPointAddress,
+  IN     BOOLEAN              IsSlowDevice,
+  IN     UINT8                MaxPacketLength,
+  IN OUT VOID                 *Data,
+  IN OUT UINTN                *DataLength,
+  IN OUT UINT8                *DataToggle,
+  IN     UINTN                TimeOut,
+  OUT    UINT32               *TransferResult
+  )
+{
+  USB_OHCI_HC_DEV         *Ohc;
+  EFI_STATUS              Status;
+  ED_DESCRIPTOR           *Ed;
+  TD_DESCRIPTOR           *HeadTd;
+  OHCI_ED_RESULT          EdResult;
+  VOID                    *UCBuffer;
+
+  if ((EndPointAddress & 0x80) == 0 || Data == NULL || DataLength == NULL || *DataLength == 0 ||
+      (IsSlowDevice && MaxPacketLength > 8) || (!IsSlowDevice && MaxPacketLength > 64) ||
+      DataToggle == NULL || (*DataToggle != 0 && *DataToggle != 1) || TransferResult == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Ohc = USB_OHCI_HC_DEV_FROM_THIS (This);
+  UCBuffer = AllocatePool (*DataLength);
+  if (UCBuffer == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  Status = OhciInterruptTransfer (
+             Ohc,
+             DeviceAddress,
+             EndPointAddress,
+             IsSlowDevice,
+             MaxPacketLength,
+             TRUE,
+             DataToggle,
+             1,
+             UCBuffer,
+             *DataLength,
+             NULL,
+             NULL,
+             FALSE,
+             &Ed,
+             &HeadTd
+             );
+
+  if (!EFI_ERROR (Status)) {
+    Status = CheckIfDone (Ohc, INTERRUPT_LIST, Ed, HeadTd, &EdResult);
+    while (Status == EFI_NOT_READY && TimeOut > 0) {
+      gBS->Stall (1000);
+      TimeOut--;
+      Status = CheckIfDone (Ohc, INTERRUPT_LIST, Ed, HeadTd, &EdResult);
+    }
+
+    *TransferResult = ConvertErrorCode (EdResult.ErrorCode);
+  }
+  CopyMem(Data, UCBuffer, *DataLength);
+  Status = OhciInterruptTransfer (
+             Ohc,
+             DeviceAddress,
+             EndPointAddress,
+             IsSlowDevice,
+             MaxPacketLength,
+             FALSE,
+             DataToggle,
+             0,
+             NULL,
+             0,
+             NULL,
+             NULL,
+             FALSE,
+             NULL,
+             NULL
+             );
+
+  return Status;
+}
+/**
+
+  Submits isochronous transfer to a target USB device.
+
+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
+  @param  DeviceAddress         Represents the address of the target device on the USB,
+                                which is assigned during USB enumeration.
+  @param  EndPointAddress       End point address
+  @param  MaximumPacketLength   Indicates the maximum packet size that the
+                                default control transfer endpoint is capable of
+                                sending or receiving.
+  @param  Data                  A pointer to the buffer of data that will be transmitted
+                                to USB device or received from USB device.
+  @param  DataLength            Indicates the size, in bytes, of the data buffer
+                                specified by Data.
+  @param  TransferResult        A pointer to the detailed result information generated
+                                by this control transfer.
+
+  @retval EFI_UNSUPPORTED       This interface not available
+  @retval EFI_INVALID_PARAMETER Data is NULL or DataLength is 0 or TransferResult is NULL
+
+**/
+
+
+EFI_STATUS
+EFIAPI
+OhciIsochronousTransfer (
+  IN     EFI_USB_HC_PROTOCOL  *This,
+  IN     UINT8                DeviceAddress,
+  IN     UINT8                EndPointAddress,
+  IN     UINT8                MaximumPacketLength,
+  IN OUT VOID                 *Data,
+  IN OUT UINTN                DataLength,
+  OUT    UINT32               *TransferResult
+  )
+{
+  if (Data == NULL || DataLength == 0 || TransferResult == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return EFI_UNSUPPORTED;
+}
+
+/**
+
+  Submits Async isochronous transfer to a target USB device.
+
+  @param  his                   A pointer to the EFI_USB_HC_PROTOCOL instance.
+  @param  DeviceAddress         Represents the address of the target device on the USB,
+                                which is assigned during USB enumeration.
+  @param  EndPointAddress       End point address
+  @param  MaximumPacketLength   Indicates the maximum packet size that the
+                                default control transfer endpoint is capable of
+                                sending or receiving.
+  @param  Data                  A pointer to the buffer of data that will be transmitted
+                                to USB device or received from USB device.
+  @param  IsochronousCallBack   When the transfer complete, the call back function will be called
+  @param  Context               Pass to the call back function as parameter
+
+  @retval EFI_UNSUPPORTED       This interface not available
+  @retval EFI_INVALID_PARAMETER Data is NULL or Datalength is 0
+
+**/
+
+EFI_STATUS
+EFIAPI
+OhciAsyncIsochronousTransfer (
+  IN     EFI_USB_HC_PROTOCOL                *This,
+  IN     UINT8                              DeviceAddress,
+  IN     UINT8                              EndPointAddress,
+  IN     UINT8                              MaximumPacketLength,
+  IN OUT VOID                               *Data,
+  IN OUT UINTN                              DataLength,
+  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK    IsochronousCallBack,
+  IN     VOID                               *Context OPTIONAL
+  )
+{
+
+  if (Data == NULL || DataLength == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return EFI_UNSUPPORTED;
+}
+
+/**
+
+  Retrieves the number of root hub ports.
+
+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
+  @param  NumOfPorts            A pointer to the number of the root hub ports.
+
+  @retval EFI_SUCCESS           The port number was retrieved successfully.
+**/
+EFI_STATUS
+EFIAPI
+OhciGetRootHubNumOfPorts (
+  IN  EFI_USB_HC_PROTOCOL  *This,
+  OUT UINT8                *NumOfPorts
+  )
+{
+  USB_OHCI_HC_DEV  *Ohc;
+  Ohc = USB_OHCI_HC_DEV_FROM_THIS (This);
+
+  if (NumOfPorts == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *NumOfPorts = (UINT8)OhciGetRootHubDescriptor(Ohc, RH_NUM_DS_PORTS);
+
+  return EFI_SUCCESS;
+}
+/**
+
+  Retrieves the current status of a USB root hub port.
+
+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL.
+  @param  PortNumber            Specifies the root hub port from which the status
+                                is to be retrieved.  This value is zero-based. For example,
+                                if a root hub has two ports, then the first port is numbered 0,
+                                and the second port is numbered 1.
+  @param  PortStatus            A pointer to the current port status bits and
+                                port status change bits.
+
+  @retval EFI_SUCCESS           The status of the USB root hub port specified by PortNumber
+                                was returned in PortStatus.
+  @retval EFI_INVALID_PARAMETER Port number not valid
+**/
+
+
+EFI_STATUS
+EFIAPI
+OhciGetRootHubPortStatus (
+  IN  EFI_USB_HC_PROTOCOL  *This,
+  IN  UINT8                PortNumber,
+  OUT EFI_USB_PORT_STATUS  *PortStatus
+  )
+{
+  USB_OHCI_HC_DEV  *Ohc;
+  UINT8            NumOfPorts;
+
+  Ohc = USB_OHCI_HC_DEV_FROM_THIS (This);
+
+  OhciGetRootHubNumOfPorts (This, &NumOfPorts);
+  if (PortNumber >= NumOfPorts) {
+    return EFI_INVALID_PARAMETER;
+  }
+  PortStatus->PortStatus = 0;
+  PortStatus->PortChangeStatus = 0;
+
+  if (OhciReadRootHubPortStatus (Ohc,PortNumber, RH_CURR_CONNECT_STAT)) {
+    PortStatus->PortStatus |= USB_PORT_STAT_CONNECTION;
+  }
+  if (OhciReadRootHubPortStatus (Ohc,PortNumber, RH_PORT_ENABLE_STAT)) {
+    PortStatus->PortStatus |= USB_PORT_STAT_ENABLE;
+  }
+  if (OhciReadRootHubPortStatus (Ohc,PortNumber, RH_PORT_SUSPEND_STAT)) {
+    PortStatus->PortStatus |= USB_PORT_STAT_SUSPEND;
+  }
+  if (OhciReadRootHubPortStatus (Ohc,PortNumber, RH_PORT_OC_INDICATOR)) {
+    PortStatus->PortStatus |= USB_PORT_STAT_OVERCURRENT;
+  }
+  if (OhciReadRootHubPortStatus (Ohc,PortNumber, RH_PORT_RESET_STAT)) {
+    PortStatus->PortStatus |= USB_PORT_STAT_RESET;
+  }
+  if (OhciReadRootHubPortStatus (Ohc,PortNumber, RH_PORT_POWER_STAT)) {
+    PortStatus->PortStatus |= USB_PORT_STAT_POWER;
+  }
+  if (OhciReadRootHubPortStatus (Ohc,PortNumber, RH_LSDEVICE_ATTACHED)) {
+    PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;
+  }
+  if (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_ENABLE_STAT_CHANGE)) {
+    PortStatus->PortChangeStatus |= USB_PORT_STAT_C_ENABLE;
+  }
+  if (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_CONNECT_STATUS_CHANGE)) {
+    PortStatus->PortChangeStatus |= USB_PORT_STAT_C_CONNECTION;
+  }
+  if (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_SUSPEND_STAT_CHANGE)) {
+    PortStatus->PortChangeStatus |= USB_PORT_STAT_C_SUSPEND;
+  }
+  if (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_OC_INDICATOR_CHANGE)) {
+    PortStatus->PortChangeStatus |= USB_PORT_STAT_C_OVERCURRENT;
+  }
+  if (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_RESET_STAT_CHANGE)) {
+    PortStatus->PortChangeStatus |= USB_PORT_STAT_C_RESET;
+  }
+
+  return EFI_SUCCESS;
+}
+/**
+
+  Sets a feature for the specified root hub port.
+
+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL.
+  @param  PortNumber            Specifies the root hub port whose feature
+                                is requested to be set.
+  @param  PortFeature           Indicates the feature selector associated
+                                with the feature set request.
+
+  @retval EFI_SUCCESS           The feature specified by PortFeature was set for the
+                                USB root hub port specified by PortNumber.
+  @retval EFI_DEVICE_ERROR      Set feature failed because of hardware issue
+  @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
+**/
+EFI_STATUS
+EFIAPI
+OhciSetRootHubPortFeature (
+  IN EFI_USB_HC_PROTOCOL   *This,
+  IN UINT8                 PortNumber,
+  IN EFI_USB_PORT_FEATURE  PortFeature
+  )
+{
+  USB_OHCI_HC_DEV         *Ohc;
+  EFI_STATUS              Status;
+  UINT8                   NumOfPorts;
+  UINTN                   RetryTimes;
+
+  OhciGetRootHubNumOfPorts (This, &NumOfPorts);
+  if (PortNumber >= NumOfPorts) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Ohc = USB_OHCI_HC_DEV_FROM_THIS (This);
+
+  Status = EFI_SUCCESS;
+
+
+  switch (PortFeature) {
+    case EfiUsbPortPower:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_SET_PORT_POWER);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        gBS->Stall (1000);
+        RetryTimes++;
+      } while (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_POWER_STAT) == 0 &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+      break;
+
+    case EfiUsbPortReset:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_SET_PORT_RESET);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        gBS->Stall (1000);
+        RetryTimes++;
+      } while ((OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_RESET_STAT_CHANGE) == 0 ||
+                OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_RESET_STAT) == 1) &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+
+      OhciSetRootHubPortStatus (Ohc, PortNumber, RH_PORT_RESET_STAT_CHANGE);
+      break;
+
+    case EfiUsbPortEnable:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_SET_PORT_ENABLE);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        gBS->Stall (1000);
+        RetryTimes++;
+      } while (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_ENABLE_STAT) == 0 &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+      break;
+
+
+    case EfiUsbPortSuspend:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_SET_PORT_SUSPEND);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        gBS->Stall (1000);
+        RetryTimes++;
+      } while (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_SUSPEND_STAT) == 0 &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+      break;
+
+    default:
+      return EFI_INVALID_PARAMETER;
+  }
+
+  return Status;
+}
+
+/**
+
+  Clears a feature for the specified root hub port.
+
+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
+  @param  PortNumber            Specifies the root hub port whose feature
+                                is requested to be cleared.
+  @param  PortFeature           Indicates the feature selector associated with the
+                                feature clear request.
+
+  @retval EFI_SUCCESS           The feature specified by PortFeature was cleared for the
+                                USB root hub port specified by PortNumber.
+  @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
+  @retval EFI_DEVICE_ERROR      Some error happened when clearing feature
+**/
+EFI_STATUS
+EFIAPI
+OhciClearRootHubPortFeature (
+  IN EFI_USB_HC_PROTOCOL   *This,
+  IN UINT8                 PortNumber,
+  IN EFI_USB_PORT_FEATURE  PortFeature
+  )
+{
+  USB_OHCI_HC_DEV         *Ohc;
+  EFI_STATUS              Status;
+  UINT8                   NumOfPorts;
+  UINTN                   RetryTimes;
+
+
+  OhciGetRootHubNumOfPorts (This, &NumOfPorts);
+  if (PortNumber >= NumOfPorts) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Ohc = USB_OHCI_HC_DEV_FROM_THIS (This);
+
+  Status = EFI_SUCCESS;
+
+  switch (PortFeature) {
+    case EfiUsbPortEnable:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_CLEAR_PORT_ENABLE);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        gBS->Stall (1000);
+        RetryTimes++;
+      } while (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_ENABLE_STAT) == 1 &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+      break;
+
+    case EfiUsbPortSuspend:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_CLEAR_SUSPEND_STATUS);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        gBS->Stall (1000);
+        RetryTimes++;
+      } while (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_SUSPEND_STAT) == 1 &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+      break;
+
+    case EfiUsbPortReset:
+      break;
+
+    case EfiUsbPortPower:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_CLEAR_PORT_POWER);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        gBS->Stall (1000);
+        RetryTimes++;
+      } while (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_POWER_STAT) == 1 &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+      break;
+
+    case EfiUsbPortConnectChange:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_CONNECT_STATUS_CHANGE);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        gBS->Stall (1000);
+        RetryTimes++;
+      } while (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_CONNECT_STATUS_CHANGE) == 1 &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+      break;
+
+    case EfiUsbPortResetChange:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_PORT_RESET_STAT_CHANGE);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        gBS->Stall (1000);
+        RetryTimes++;
+      } while (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_RESET_STAT_CHANGE) == 1 &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+      break;
+
+
+    case EfiUsbPortEnableChange:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_PORT_ENABLE_STAT_CHANGE);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        gBS->Stall (1000);
+        RetryTimes++;
+      } while (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_ENABLE_STAT_CHANGE) == 1 &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+      break;
+
+    case EfiUsbPortSuspendChange:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_PORT_SUSPEND_STAT_CHANGE);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        gBS->Stall (1000);
+        RetryTimes++;
+      } while (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_SUSPEND_STAT_CHANGE) == 1 &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+      break;
+
+    case EfiUsbPortOverCurrentChange:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_OC_INDICATOR_CHANGE);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        gBS->Stall (1000);
+        RetryTimes++;
+      } while (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_OC_INDICATOR_CHANGE) == 1 &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+      break;
+
+    default:
+      return EFI_INVALID_PARAMETER;
+  }
+
+  return Status;
+}
+
+EFI_DRIVER_BINDING_PROTOCOL gOhciDriverBinding = {
+  OHCIDriverBindingSupported,
+  OHCIDriverBindingStart,
+  OHCIDriverBindingStop,
+  0x10,
+  NULL,
+  NULL
+};
+
+
+/**
+  Entry point for EFI drivers.
+
+  @param  ImageHandle           EFI_HANDLE.
+  @param  SystemTable           EFI_SYSTEM_TABLE.
+
+  @retval EFI_SUCCESS           Driver is successfully loaded.
+  @return Others                Failed.
+
+**/
+EFI_STATUS
+EFIAPI
+OHCIDriverEntryPoint (
+  IN EFI_HANDLE          ImageHandle,
+  IN EFI_SYSTEM_TABLE    *SystemTable
+  )
+{
+  return EfiLibInstallDriverBindingComponentName2 (
+           ImageHandle,
+           SystemTable,
+           &gOhciDriverBinding,
+           ImageHandle,
+           &gOhciComponentName,
+           &gOhciComponentName2
+           );
+}
+
+
+/**
+  Test to see if this driver supports ControllerHandle. Any
+  ControllerHandle that has UsbHcProtocol installed will be supported.
+
+  @param  This                 Protocol instance pointer.
+  @param  Controller           Handle of device to test.
+  @param  RemainingDevicePath  Not used.
+
+  @return EFI_SUCCESS          This driver supports this device.
+  @return EFI_UNSUPPORTED      This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+OHCIDriverBindingSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  )
+{
+  EFI_STATUS              Status;
+  EFI_PCI_IO_PROTOCOL     *PciIo;
+  USB_CLASSC              UsbClassCReg;
+  //
+  // Test whether there is PCI IO Protocol attached on the controller handle.
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **) &PciIo,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint8,
+                        PCI_CLASSCODE_OFFSET,
+                        sizeof (USB_CLASSC) / sizeof (UINT8),
+                        &UsbClassCReg
+                        );
+
+  if (EFI_ERROR (Status)) {
+    Status = EFI_UNSUPPORTED;
+    goto ON_EXIT;
+  }
+  //
+  // Test whether the controller belongs to OHCI type
+  //
+  if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) ||
+      (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) ||
+      (UsbClassCReg.ProgInterface != PCI_IF_OHCI)
+      ) {
+
+    Status = EFI_UNSUPPORTED;
+  }
+ON_EXIT:
+  gBS->CloseProtocol (
+         Controller,
+         &gEfiPciIoProtocolGuid,
+         This->DriverBindingHandle,
+         Controller
+         );
+
+  return Status;
+
+}
+
+/**
+
+  Allocate and initialize the empty OHCI device.
+
+  @param  PciIo                  The PCIIO to use.
+  @param  OriginalPciAttributes  The original PCI attributes.
+
+  @return Allocated OHCI device  If err, return NULL.
+
+**/
+
+USB_OHCI_HC_DEV *
+OhciAllocateDev (
+  IN EFI_PCI_IO_PROTOCOL  *PciIo,
+  IN UINT64               OriginalPciAttributes
+  )
+{
+  USB_OHCI_HC_DEV         *Ohc;
+  EFI_STATUS              Status;
+  VOID                    *Buf;
+  EFI_PHYSICAL_ADDRESS    PhyAddr;
+  VOID                    *Map;
+  UINTN                   Pages;
+  UINTN                   Bytes;
+
+  Ohc = AllocateZeroPool (sizeof (USB_OHCI_HC_DEV));
+  if (Ohc == NULL) {
+    return NULL;
+  }
+
+  Ohc->Signature                      = USB_OHCI_HC_DEV_SIGNATURE;
+  Ohc->PciIo                          = PciIo;
+
+  Ohc->UsbHc.Reset                    = OhciReset;
+  Ohc->UsbHc.GetState                 = OhciGetState;
+  Ohc->UsbHc.SetState                 = OhciSetState;
+  Ohc->UsbHc.ControlTransfer          = OhciControlTransfer;
+  Ohc->UsbHc.BulkTransfer             = OhciBulkTransfer;
+  Ohc->UsbHc.AsyncInterruptTransfer   = OhciAsyncInterruptTransfer;
+  Ohc->UsbHc.SyncInterruptTransfer    = OhciSyncInterruptTransfer;
+  Ohc->UsbHc.IsochronousTransfer      = OhciIsochronousTransfer;
+  Ohc->UsbHc.AsyncIsochronousTransfer = OhciAsyncIsochronousTransfer;
+  Ohc->UsbHc.GetRootHubPortNumber     = OhciGetRootHubNumOfPorts;
+  Ohc->UsbHc.GetRootHubPortStatus     = OhciGetRootHubPortStatus;
+  Ohc->UsbHc.SetRootHubPortFeature    = OhciSetRootHubPortFeature;
+  Ohc->UsbHc.ClearRootHubPortFeature  = OhciClearRootHubPortFeature;
+  Ohc->UsbHc.MajorRevision            = 0x1;
+  Ohc->UsbHc.MinorRevision            = 0x1;
+
+  Ohc->OriginalPciAttributes = OriginalPciAttributes;
+
+  Ohc->HccaMemoryBlock = NULL;
+  Ohc->HccaMemoryMapping   = NULL;
+  Ohc->HccaMemoryBuf = NULL;
+  Ohc->HccaMemoryPages = 0;
+  Ohc->InterruptContextList = NULL;
+  Ohc->ControllerNameTable = NULL;
+  Ohc->HouseKeeperTimer = NULL;
+
+  Ohc->MemPool = UsbHcInitMemPool(PciIo, TRUE, 0);
+  if(Ohc->MemPool == NULL) {
+    goto FREE_DEV_BUFFER;
+  }
+
+  Bytes = 4096;
+  Pages = EFI_SIZE_TO_PAGES (Bytes);
+
+  Status = PciIo->AllocateBuffer (
+                    PciIo,
+                    AllocateAnyPages,
+                    EfiBootServicesData,
+                    Pages,
+                    &Buf,
+                    0
+                    );
+
+  if (EFI_ERROR (Status)) {
+    goto FREE_MEM_POOL;
+  }
+
+  Status = PciIo->Map (
+                    PciIo,
+                    EfiPciIoOperationBusMasterCommonBuffer,
+                    Buf,
+                    &Bytes,
+                    &PhyAddr,
+                    &Map
+                    );
+
+  if (EFI_ERROR (Status) || (Bytes != 4096)) {
+    goto FREE_MEM_PAGE;
+  }
+
+  Ohc->HccaMemoryBlock = (HCCA_MEMORY_BLOCK *)(UINTN)PhyAddr;
+  Ohc->HccaMemoryMapping = Map;
+  Ohc->HccaMemoryBuf = (VOID *)(UINTN)Buf;
+  Ohc->HccaMemoryPages = Pages;
+
+  return Ohc;
+
+FREE_MEM_PAGE:
+  PciIo->FreeBuffer (PciIo, Pages, Buf);
+FREE_MEM_POOL:
+  UsbHcFreeMemPool (Ohc->MemPool);
+FREE_DEV_BUFFER:
+  FreePool(Ohc);
+
+  return NULL;
+}
+/**
+
+  Free the OHCI device and release its associated resources.
+
+  @param  Ohc                   The OHCI device to release.
+
+**/
+VOID
+OhciFreeDev (
+  IN USB_OHCI_HC_DEV      *Ohc
+  )
+{
+  OhciFreeFixedIntMemory (Ohc);
+
+  if (Ohc->HouseKeeperTimer != NULL) {
+    gBS->CloseEvent (Ohc->HouseKeeperTimer);
+  }
+
+  if (Ohc->ExitBootServiceEvent != NULL) {
+    gBS->CloseEvent (Ohc->ExitBootServiceEvent);
+  }
+
+  if (Ohc->MemPool != NULL) {
+    UsbHcFreeMemPool (Ohc->MemPool);
+  }
+
+  if (Ohc->HccaMemoryMapping != NULL ) {
+    Ohc->PciIo->FreeBuffer (Ohc->PciIo, Ohc->HccaMemoryPages, Ohc->HccaMemoryBuf);
+  }
+
+  if (Ohc->ControllerNameTable != NULL) {
+    FreeUnicodeStringTable (Ohc->ControllerNameTable);
+  }
+
+  FreePool (Ohc);
+}
+/**
+
+  Uninstall all Ohci Interface.
+
+  @param  Controller            Controller handle.
+  @param  This                  Protocol instance pointer.
+
+**/
+VOID
+OhciCleanDevUp (
+  IN  EFI_HANDLE           Controller,
+  IN  EFI_USB_HC_PROTOCOL  *This
+  )
+{
+  USB_OHCI_HC_DEV  *Ohc;
+
+  //
+  // Retrieve private context structure
+  //
+  Ohc = USB_OHCI_HC_DEV_FROM_THIS (This);
+
+  //
+  // Uninstall the USB_HC and USB_HC2 protocol
+  //
+  gBS->UninstallProtocolInterface (
+         Controller,
+         &gEfiUsbHcProtocolGuid,
+         &Ohc->UsbHc
+         );
+
+  //
+  // Cancel the timer event
+  //
+  gBS->SetTimer (Ohc->HouseKeeperTimer, TimerCancel, 0);
+
+  //
+  // Stop the host controller
+  //
+  OhciSetHcControl (Ohc, PERIODIC_ENABLE | CONTROL_ENABLE | ISOCHRONOUS_ENABLE | BULK_ENABLE, 0);
+  This->Reset (This, EFI_USB_HC_RESET_GLOBAL);
+  This->SetState (This, EfiUsbHcStateHalt);
+
+  //
+  // Free resources
+  //
+  OhciFreeDynamicIntMemory (Ohc);
+
+  //
+  // Restore original PCI attributes
+  //
+  Ohc->PciIo->Attributes (
+                Ohc->PciIo,
+                EfiPciIoAttributeOperationSet,
+                Ohc->OriginalPciAttributes,
+                NULL
+                );
+
+  //
+  // Free the private context structure
+  //
+  OhciFreeDev (Ohc);
+}
+
+/**
+
+  One notified function to stop the Host Controller when gBS->ExitBootServices() called.
+
+  @param  Event                 Pointer to this event
+  @param  Context               Event handler private data
+**/
+VOID
+EFIAPI
+OhcExitBootService (
+  EFI_EVENT                      Event,
+  VOID                           *Context
+  )
+{
+  USB_OHCI_HC_DEV           *Ohc;
+  EFI_USB_HC_PROTOCOL       *UsbHc;
+  Ohc = (USB_OHCI_HC_DEV *) Context;
+
+  UsbHc = &Ohc->UsbHc;
+  //
+  // Stop the Host Controller
+  //
+  //OhciStopHc (Ohc, OHC_GENERIC_TIMEOUT);
+  OhciSetHcControl (Ohc, PERIODIC_ENABLE | CONTROL_ENABLE | ISOCHRONOUS_ENABLE | BULK_ENABLE, 0);
+  UsbHc->Reset (UsbHc, EFI_USB_HC_RESET_GLOBAL);
+  UsbHc->SetState (UsbHc, EfiUsbHcStateHalt);
+
+  return;
+}
+
+
+/**
+  Starting the Usb OHCI Driver.
+
+  @param  This                  Protocol instance pointer.
+  @param  Controller            Handle of device to test.
+  @param  RemainingDevicePath   Not used.
+
+  @retval EFI_SUCCESS           This driver supports this device.
+  @retval EFI_UNSUPPORTED       This driver does not support this device.
+  @retval EFI_DEVICE_ERROR      This driver cannot be started due to device Error.
+                                EFI_OUT_OF_RESOURCES- Failed due to resource shortage.
+
+**/
+EFI_STATUS
+EFIAPI
+OHCIDriverBindingStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  )
+{
+  EFI_STATUS              Status;
+  EFI_PCI_IO_PROTOCOL     *PciIo;
+  USB_OHCI_HC_DEV         *Ohc;
+  UINT64                  Supports;
+  UINT64                  OriginalPciAttributes;
+  BOOLEAN                 PciAttributesSaved;
+
+  //
+  // Open PCIIO, then enable the HC device and turn off emulation
+  //
+  Ohc = NULL;
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **) &PciIo,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  PciAttributesSaved = FALSE;
+  //
+  // Save original PCI attributes
+  //
+  Status = PciIo->Attributes (
+                    PciIo,
+                    EfiPciIoAttributeOperationGet,
+                    0,
+                    &OriginalPciAttributes
+                    );
+
+  if (EFI_ERROR (Status)) {
+    goto CLOSE_PCIIO;
+  }
+  PciAttributesSaved = TRUE;
+
+  //
+  // Robustnesss improvement such as for UoL
+  // Default is not required.
+  //
+  //if (FeaturePcdGet (PcdTurnOffUsbLegacySupport)) {
+  //  OhciTurnOffUsbEmulation (PciIo);
+  //}
+
+  Status = PciIo->Attributes (
+                    PciIo,
+                    EfiPciIoAttributeOperationSupported,
+                    0,
+                    &Supports
+                    );
+  if (!EFI_ERROR (Status)) {
+    Supports &= EFI_PCI_DEVICE_ENABLE;
+    Status = PciIo->Attributes (
+                      PciIo,
+                      EfiPciIoAttributeOperationEnable,
+                      Supports,
+                      NULL
+                      );
+  }
+
+  if (EFI_ERROR (Status)) {
+    goto CLOSE_PCIIO;
+  }
+  //
+  //Allocate memory for OHC private data structure
+  //
+  Ohc = OhciAllocateDev(PciIo, OriginalPciAttributes);
+  if (Ohc == NULL){
+    Status = EFI_OUT_OF_RESOURCES;
+    goto CLOSE_PCIIO;
+  }
+
+  //Status = OhciInitializeInterruptList ( Uhc );
+  //if (EFI_ERROR (Status)) {
+  //  goto FREE_OHC;
+  //}
+
+  //
+  // Set 0.01 s timer
+  //
+  Status = gBS->CreateEvent (
+                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  OhciHouseKeeper,
+                  Ohc,
+                  &Ohc->HouseKeeperTimer
+                  );
+  if (EFI_ERROR (Status)) {
+    goto FREE_OHC;
+  }
+
+  Status = gBS->SetTimer (Ohc->HouseKeeperTimer, TimerPeriodic, 10 * 1000 * 10);
+  if (EFI_ERROR (Status)) {
+    goto FREE_OHC;
+  }
+
+  //
+  //Install Host Controller Protocol
+  //
+  Status = gBS->InstallProtocolInterface (
+                  &Controller,
+                  &gEfiUsbHcProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &Ohc->UsbHc
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_INFO, "Install protocol error"));
+    goto FREE_OHC;
+  }
+  //
+  // Create event to stop the HC when exit boot service.
+  //
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  OhcExitBootService,
+                  Ohc,
+                  &gEfiEventExitBootServicesGuid,
+                  &Ohc->ExitBootServiceEvent
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_INFO, "Create exit boot event error"));
+    goto UNINSTALL_USBHC;
+  }
+  AddUnicodeString2 (
+    "eng",
+    gOhciComponentName.SupportedLanguages,
+    &Ohc->ControllerNameTable,
+    L"Usb Universal Host Controller",
+    TRUE
+    );
+  AddUnicodeString2 (
+    "en",
+    gOhciComponentName2.SupportedLanguages,
+    &Ohc->ControllerNameTable,
+    L"Usb Universal Host Controller",
+    FALSE
+    );
+
+  return EFI_SUCCESS;
+
+UNINSTALL_USBHC:
+  gBS->UninstallMultipleProtocolInterfaces (
+         Controller,
+         &gEfiUsbHcProtocolGuid,
+         &Ohc->UsbHc,
+         NULL
+         );
+
+FREE_OHC:
+  OhciFreeDev (Ohc);
+
+CLOSE_PCIIO:
+  if (PciAttributesSaved) {
+  //
+  // Restore original PCI attributes
+  //
+    PciIo->Attributes (
+             PciIo,
+             EfiPciIoAttributeOperationSet,
+             OriginalPciAttributes,
+             NULL
+             );
+  }
+
+  gBS->CloseProtocol (
+         Controller,
+         &gEfiPciIoProtocolGuid,
+         This->DriverBindingHandle,
+         Controller
+         );
+  return Status;
+}
+
+/**
+  Stop this driver on ControllerHandle. Support stopping any child handles
+  created by this driver.
+
+  @param  This                  Protocol instance pointer.
+  @param  Controller            Handle of device to stop driver on.
+  @param  NumberOfChildren      Number of Children in the ChildHandleBuffer.
+  @param  ChildHandleBuffer     List of handles for the children we need to stop.
+
+  @return EFI_SUCCESS
+  @return others
+
+**/
+EFI_STATUS
+EFIAPI
+OHCIDriverBindingStop (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN UINTN                        NumberOfChildren,
+  IN EFI_HANDLE                   *ChildHandleBuffer
+  )
+{
+  EFI_STATUS           Status;
+  EFI_USB_HC_PROTOCOL  *UsbHc;
+
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiUsbHcProtocolGuid,
+                  (VOID **)&UsbHc,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  OhciCleanDevUp(Controller, UsbHc);
+
+  gBS->CloseProtocol (
+         Controller,
+         &gEfiPciIoProtocolGuid,
+         This->DriverBindingHandle,
+         Controller
+         );
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.h
new file mode 100644
index 0000000000..4c374ab9e2
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.h
@@ -0,0 +1,663 @@
+/** @file
+Provides the definition of Usb Hc Protocol and OHCI controller
+private data structure.
+
+Copyright (c) 2013-2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+
+#ifndef _OHCI_H
+#define _OHCI_H
+
+
+#include <Uefi.h>
+
+#include <Protocol/UsbHostController.h>
+#include <Protocol/PciIo.h>
+
+#include <Guid/EventGroup.h>
+
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <IndustryStandard/Pci.h>
+
+
+typedef struct _USB_OHCI_HC_DEV USB_OHCI_HC_DEV;
+
+#include "UsbHcMem.h"
+#include "OhciReg.h"
+#include "OhciSched.h"
+#include "OhciUrb.h"
+#include "Descriptor.h"
+#include "ComponentName.h"
+#include "OhciDebug.h"
+
+extern EFI_DRIVER_BINDING_PROTOCOL   gOhciDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL   gOhciComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL  gOhciComponentName2;
+
+#define USB_OHCI_HC_DEV_SIGNATURE     SIGNATURE_32('o','h','c','i')
+
+typedef struct _HCCA_MEMORY_BLOCK{
+  UINT32                    HccaInterruptTable[32];    // 32-bit Physical Address to ED_DESCRIPTOR
+  UINT16                    HccaFrameNumber;
+  UINT16                    HccaPad;
+  UINT32                    HccaDoneHead;              // 32-bit Physical Address to TD_DESCRIPTOR
+  UINT8                     Reserved[116];
+} HCCA_MEMORY_BLOCK;
+
+
+struct _USB_OHCI_HC_DEV {
+  UINTN                     Signature;
+  EFI_USB_HC_PROTOCOL       UsbHc;
+  EFI_USB2_HC_PROTOCOL      Usb2Hc;
+  EFI_PCI_IO_PROTOCOL       *PciIo;
+  UINT64                    OriginalPciAttributes;
+
+  HCCA_MEMORY_BLOCK         *HccaMemoryBlock;
+  VOID                      *HccaMemoryBuf;
+  VOID                      *HccaMemoryMapping;
+  UINTN                     HccaMemoryPages;
+
+  ED_DESCRIPTOR             *IntervalList[6][32];
+  INTERRUPT_CONTEXT_ENTRY   *InterruptContextList;
+  VOID                      *MemPool;
+
+  UINT32                    ToggleFlag;
+
+  EFI_EVENT                 HouseKeeperTimer;
+  //
+  // ExitBootServicesEvent is used to stop the OHC DMA operation
+  // after exit boot service.
+  //
+  EFI_EVENT                  ExitBootServiceEvent;
+
+  EFI_UNICODE_STRING_TABLE  *ControllerNameTable;
+};
+
+#define USB_OHCI_HC_DEV_FROM_THIS(a)    CR(a, USB_OHCI_HC_DEV, UsbHc, USB_OHCI_HC_DEV_SIGNATURE)
+#define USB2_OHCI_HC_DEV_FROM_THIS(a)    CR(a, USB_OHCI_HC_DEV, Usb2Hc, USB_OHCI_HC_DEV_SIGNATURE)
+
+//
+// Func List
+//
+
+/**
+  Provides software reset for the USB host controller.
+
+  @param  This                  This EFI_USB_HC_PROTOCOL instance.
+  @param  Attributes            A bit mask of the reset operation to perform.
+
+  @retval EFI_SUCCESS           The reset operation succeeded.
+  @retval EFI_INVALID_PARAMETER Attributes is not valid.
+  @retval EFI_UNSUPPOURTED      The type of reset specified by Attributes is
+                                not currently supported by the host controller.
+  @retval EFI_DEVICE_ERROR      Host controller isn't halted to reset.
+
+**/
+EFI_STATUS
+EFIAPI
+OhciReset (
+  IN EFI_USB_HC_PROTOCOL  *This,
+  IN UINT16               Attributes
+  );
+/**
+  Retrieve the current state of the USB host controller.
+
+  @param  This                  This EFI_USB_HC_PROTOCOL instance.
+  @param  State                 Variable to return the current host controller
+                                state.
+
+  @retval EFI_SUCCESS           Host controller state was returned in State.
+  @retval EFI_INVALID_PARAMETER State is NULL.
+  @retval EFI_DEVICE_ERROR      An error was encountered while attempting to
+                                retrieve the host controller's current state.
+
+**/
+
+EFI_STATUS
+EFIAPI
+OhciGetState (
+  IN  EFI_USB_HC_PROTOCOL  *This,
+  OUT EFI_USB_HC_STATE     *State
+  );
+/**
+  Sets the USB host controller to a specific state.
+
+  @param  This                  This EFI_USB_HC_PROTOCOL instance.
+  @param  State                 The state of the host controller that will be set.
+
+  @retval EFI_SUCCESS           The USB host controller was successfully placed
+                                in the state specified by State.
+  @retval EFI_INVALID_PARAMETER State is invalid.
+  @retval EFI_DEVICE_ERROR      Failed to set the state due to device error.
+
+**/
+
+EFI_STATUS
+EFIAPI
+OhciSetState(
+  IN EFI_USB_HC_PROTOCOL  *This,
+  IN EFI_USB_HC_STATE     State
+  );
+/**
+
+  Submits control transfer to a target USB device.
+
+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
+  @param  DeviceAddress         Represents the address of the target device on the USB,
+                                which is assigned during USB enumeration.
+  @param  IsSlowDevice          Indicates whether the target device is slow device
+                                or full-speed device.
+  @param  MaxPaketLength        Indicates the maximum packet size that the
+                                default control transfer endpoint is capable of
+                                sending or receiving.
+  @param  Request               A pointer to the USB device request that will be sent
+                                to the USB device.
+  @param  TransferDirection     Specifies the data direction for the transfer.
+                                There are three values available, DataIn, DataOut
+                                and NoData.
+  @param  Data                  A pointer to the buffer of data that will be transmitted
+                                to USB device or received from USB device.
+  @param  DataLength            Indicates the size, in bytes, of the data buffer
+                                specified by Data.
+  @param  TimeOut               Indicates the maximum time, in microseconds,
+                                which the transfer is allowed to complete.
+  @param  TransferResult        A pointer to the detailed result information generated
+                                by this control transfer.
+
+  @retval EFI_SUCCESS           The control transfer was completed successfully.
+  @retval EFI_OUT_OF_RESOURCES  The control transfer could not be completed due to a lack of resources.
+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
+  @retval EFI_TIMEOUT           The control transfer failed due to timeout.
+  @retval EFI_DEVICE_ERROR      The control transfer failed due to host controller or device error.
+                                Caller should check TranferResult for detailed error information.
+
+--*/
+
+
+EFI_STATUS
+EFIAPI
+OhciControlTransfer (
+  IN     EFI_USB_HC_PROTOCOL     *This,
+  IN     UINT8                   DeviceAddress,
+  IN     BOOLEAN                 IsSlowDevice,
+  IN     UINT8                   MaxPacketLength,
+  IN     EFI_USB_DEVICE_REQUEST  *Request,
+  IN     EFI_USB_DATA_DIRECTION  TransferDirection,
+  IN OUT VOID                    *Data                 OPTIONAL,
+  IN OUT UINTN                   *DataLength           OPTIONAL,
+  IN     UINTN                   TimeOut,
+  OUT    UINT32                  *TransferResult
+  );
+/**
+
+  Submits bulk transfer to a bulk endpoint of a USB device.
+
+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
+  @param  DeviceAddress         Represents the address of the target device on the USB,
+                                which is assigned during USB enumeration.
+  @param  EndPointAddress       The combination of an endpoint number and an
+                                endpoint direction of the target USB device.
+                                Each endpoint address supports data transfer in
+                                one direction except the control endpoint
+                                (whose default endpoint address is 0).
+                                It is the caller's responsibility to make sure that
+                                the EndPointAddress represents a bulk endpoint.
+  @param  MaximumPacketLength   Indicates the maximum packet size the target endpoint
+                                is capable of sending or receiving.
+  @param  Data                  A pointer to the buffer of data that will be transmitted
+                                to USB device or received from USB device.
+  @param  DataLength            When input, indicates the size, in bytes, of the data buffer
+                                specified by Data. When output, indicates the actually
+                                transferred data size.
+  @param  DataToggle            A pointer to the data toggle value. On input, it indicates
+                                the initial data toggle value the bulk transfer should adopt;
+                                on output, it is updated to indicate the data toggle value
+                                of the subsequent bulk transfer.
+  @param  TimeOut               Indicates the maximum time, in microseconds, which the
+                                transfer is allowed to complete.
+  TransferResult                A pointer to the detailed result information of the
+                                bulk transfer.
+
+  @retval EFI_SUCCESS           The bulk transfer was completed successfully.
+  @retval EFI_OUT_OF_RESOURCES  The bulk transfer could not be submitted due to lack of resource.
+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
+  @retval EFI_TIMEOUT           The bulk transfer failed due to timeout.
+  @retval EFI_DEVICE_ERROR      The bulk transfer failed due to host controller or device error.
+                                Caller should check TranferResult for detailed error information.
+
+**/
+
+
+EFI_STATUS
+EFIAPI
+OhciBulkTransfer(
+  IN     EFI_USB_HC_PROTOCOL  *This,
+  IN     UINT8                DeviceAddress,
+  IN     UINT8                EndPointAddress,
+  IN     UINT8                MaxPacketLength,
+  IN OUT VOID                 *Data,
+  IN OUT UINTN                *DataLength,
+  IN OUT UINT8                *DataToggle,
+  IN     UINTN                TimeOut,
+  OUT    UINT32               *TransferResult
+  );
+/**
+
+  Submits an interrupt transfer to an interrupt endpoint of a USB device.
+
+  @param  Ohc                   Device private data
+  @param  DeviceAddress         Represents the address of the target device on the USB,
+                                which is assigned during USB enumeration.
+  @param  EndPointAddress       The combination of an endpoint number and an endpoint
+                                direction of the target USB device. Each endpoint address
+                                supports data transfer in one direction except the
+                                control endpoint (whose default endpoint address is 0).
+                                It is the caller's responsibility to make sure that
+                                the EndPointAddress represents an interrupt endpoint.
+  @param  IsSlowDevice          Indicates whether the target device is slow device
+                                or full-speed device.
+  @param  MaxPacketLength       Indicates the maximum packet size the target endpoint
+                                is capable of sending or receiving.
+  @param  IsNewTransfer         If TRUE, an asynchronous interrupt pipe is built between
+                                the host and the target interrupt endpoint.
+                                If FALSE, the specified asynchronous interrupt pipe
+                                is canceled.
+  @param  DataToggle            A pointer to the data toggle value.  On input, it is valid
+                                when IsNewTransfer is TRUE, and it indicates the initial
+                                data toggle value the asynchronous interrupt transfer
+                                should adopt.
+                                On output, it is valid when IsNewTransfer is FALSE,
+                                and it is updated to indicate the data toggle value of
+                                the subsequent asynchronous interrupt transfer.
+  @param  PollingInterval       Indicates the interval, in milliseconds, that the
+                                asynchronous interrupt transfer is polled.
+                                This parameter is required when IsNewTransfer is TRUE.
+  @param  UCBuffer              Uncacheable buffer
+  @param  DataLength            Indicates the length of data to be received at the
+                                rate specified by PollingInterval from the target
+                                asynchronous interrupt endpoint.  This parameter
+                                is only required when IsNewTransfer is TRUE.
+  @param  CallBackFunction      The Callback function.This function is called at the
+                                rate specified by PollingInterval.This parameter is
+                                only required when IsNewTransfer is TRUE.
+  @param  Context               The context that is passed to the CallBackFunction.
+                                This is an optional parameter and may be NULL.
+  @param  IsPeriodic            Periodic interrupt or not
+  @param  OutputED              The correspoding ED carried out
+  @param  OutputTD              The correspoding TD carried out
+
+
+  @retval EFI_SUCCESS           The asynchronous interrupt transfer request has been successfully
+                                submitted or canceled.
+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
+
+**/
+
+EFI_STATUS
+OhciInterruptTransfer (
+  IN     USB_OHCI_HC_DEV                  *Ohc,
+  IN     UINT8                            DeviceAddress,
+  IN     UINT8                            EndPointAddress,
+  IN     BOOLEAN                          IsSlowDevice,
+  IN     UINT8                            MaxPacketLength,
+  IN     BOOLEAN                          IsNewTransfer,
+  IN OUT UINT8                            *DataToggle        OPTIONAL,
+  IN     UINTN                            PollingInterval    OPTIONAL,
+  IN     VOID                             *UCBuffer          OPTIONAL,
+  IN     UINTN                            DataLength         OPTIONAL,
+  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK  CallBackFunction   OPTIONAL,
+  IN     VOID                             *Context           OPTIONAL,
+  IN     BOOLEAN                          IsPeriodic         OPTIONAL,
+  OUT    ED_DESCRIPTOR                    **OutputED         OPTIONAL,
+  OUT    TD_DESCRIPTOR                    **OutputTD         OPTIONAL
+  );
+/**
+
+  Submits an asynchronous interrupt transfer to an interrupt endpoint of a USB device.
+
+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
+  @param  DeviceAddress         Represents the address of the target device on the USB,
+                                which is assigned during USB enumeration.
+  @param  EndPointAddress       The combination of an endpoint number and an endpoint
+                                direction of the target USB device. Each endpoint address
+                                supports data transfer in one direction except the
+                                control endpoint (whose default endpoint address is 0).
+                                It is the caller's responsibility to make sure that
+                                the EndPointAddress represents an interrupt endpoint.
+  @param  IsSlowDevice          Indicates whether the target device is slow device
+                                or full-speed device.
+  @param  MaxiumPacketLength    Indicates the maximum packet size the target endpoint
+                                is capable of sending or receiving.
+  @param  IsNewTransfer         If TRUE, an asynchronous interrupt pipe is built between
+                                the host and the target interrupt endpoint.
+                                If FALSE, the specified asynchronous interrupt pipe
+                                is canceled.
+  @param  DataToggle            A pointer to the data toggle value.  On input, it is valid
+                                when IsNewTransfer is TRUE, and it indicates the initial
+                                data toggle value the asynchronous interrupt transfer
+                                should adopt.
+                                On output, it is valid when IsNewTransfer is FALSE,
+                                and it is updated to indicate the data toggle value of
+                                the subsequent asynchronous interrupt transfer.
+  @param  PollingInterval       Indicates the interval, in milliseconds, that the
+                                asynchronous interrupt transfer is polled.
+                                This parameter is required when IsNewTransfer is TRUE.
+  @param  DataLength            Indicates the length of data to be received at the
+                                rate specified by PollingInterval from the target
+                                asynchronous interrupt endpoint.  This parameter
+                                is only required when IsNewTransfer is TRUE.
+  @param  CallBackFunction      The Callback function.This function is called at the
+                                rate specified by PollingInterval.This parameter is
+                                only required when IsNewTransfer is TRUE.
+  @param  Context               The context that is passed to the CallBackFunction.
+                                This is an optional parameter and may be NULL.
+
+  @retval EFI_SUCCESS           The asynchronous interrupt transfer request has been successfully
+                                submitted or canceled.
+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
+
+**/
+
+
+EFI_STATUS
+EFIAPI
+OhciAsyncInterruptTransfer (
+  IN     EFI_USB_HC_PROTOCOL              *This,
+  IN     UINT8                            DeviceAddress,
+  IN     UINT8                            EndPointAddress,
+  IN     BOOLEAN                          IsSlowDevice,
+  IN     UINT8                            MaxPacketLength,
+  IN     BOOLEAN                          IsNewTransfer,
+  IN OUT UINT8                            *DataToggle        OPTIONAL,
+  IN     UINTN                            PollingInterval    OPTIONAL,
+  IN     UINTN                            DataLength         OPTIONAL,
+  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK  CallBackFunction   OPTIONAL,
+  IN     VOID                             *Context           OPTIONAL
+  );
+/**
+
+  Submits synchronous interrupt transfer to an interrupt endpoint
+  of a USB device.
+
+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
+  @param  DeviceAddress         Represents the address of the target device on the USB,
+                                which is assigned during USB enumeration.
+  @param  EndPointAddress       The combination of an endpoint number and an endpoint
+                                direction of the target USB device. Each endpoint
+                                address supports data transfer in one direction
+                                except the control endpoint (whose default
+                                endpoint address is 0). It is the caller's responsibility
+                                to make sure that the EndPointAddress represents
+                                an interrupt endpoint.
+  @param  IsSlowDevice          Indicates whether the target device is slow device
+                                or full-speed device.
+  @param  MaxPacketLength       Indicates the maximum packet size the target endpoint
+                                is capable of sending or receiving.
+  @param  Data                  A pointer to the buffer of data that will be transmitted
+                                to USB device or received from USB device.
+  @param  DataLength            On input, the size, in bytes, of the data buffer specified
+                                by Data. On output, the number of bytes transferred.
+  @param  DataToggle            A pointer to the data toggle value. On input, it indicates
+                                the initial data toggle value the synchronous interrupt
+                                transfer should adopt;
+                                on output, it is updated to indicate the data toggle value
+                                of the subsequent synchronous interrupt transfer.
+  @param  TimeOut               Indicates the maximum time, in microseconds, which the
+                                transfer is allowed to complete.
+  @param  TransferResult        A pointer to the detailed result information from
+                                the synchronous interrupt transfer.
+
+  @retval EFI_UNSUPPORTED       This interface not available.
+  @retval EFI_INVALID_PARAMETER Parameters not follow spec
+
+**/
+
+
+EFI_STATUS
+EFIAPI
+OhciSyncInterruptTransfer (
+  IN     EFI_USB_HC_PROTOCOL  *This,
+  IN     UINT8                DeviceAddress,
+  IN     UINT8                EndPointAddress,
+  IN     BOOLEAN              IsSlowDevice,
+  IN     UINT8                MaxPacketLength,
+  IN OUT VOID                 *Data,
+  IN OUT UINTN                *DataLength,
+  IN OUT UINT8                *DataToggle,
+  IN     UINTN                TimeOut,
+  OUT    UINT32               *TransferResult
+  );
+/**
+
+  Submits isochronous transfer to a target USB device.
+
+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
+  @param  DeviceAddress         Represents the address of the target device on the USB,
+                                which is assigned during USB enumeration.
+  @param  EndPointAddress       End point address
+  @param  MaximumPacketLength   Indicates the maximum packet size that the
+                                default control transfer endpoint is capable of
+                                sending or receiving.
+  @param  Data                  A pointer to the buffer of data that will be transmitted
+                                to USB device or received from USB device.
+  @param  DataLength            Indicates the size, in bytes, of the data buffer
+                                specified by Data.
+  @param  TransferResult        A pointer to the detailed result information generated
+                                by this control transfer.
+
+  @retval EFI_UNSUPPORTED       This interface not available
+  @retval EFI_INVALID_PARAMETER Data is NULL or DataLength is 0 or TransferResult is NULL
+
+**/
+
+
+EFI_STATUS
+EFIAPI
+OhciIsochronousTransfer (
+  IN     EFI_USB_HC_PROTOCOL  *This,
+  IN     UINT8                DeviceAddress,
+  IN     UINT8                EndPointAddress,
+  IN     UINT8                MaximumPacketLength,
+  IN OUT VOID                 *Data,
+  IN OUT UINTN                DataLength,
+  OUT    UINT32               *TransferResult
+  );
+/**
+
+  Submits Async isochronous transfer to a target USB device.
+
+  @param  his                   A pointer to the EFI_USB_HC_PROTOCOL instance.
+  @param  DeviceAddress         Represents the address of the target device on the USB,
+                                which is assigned during USB enumeration.
+  @param  EndPointAddress       End point address
+  @param  MaximumPacketLength   Indicates the maximum packet size that the
+                                default control transfer endpoint is capable of
+                                sending or receiving.
+  @param  Data                  A pointer to the buffer of data that will be transmitted
+                                to USB device or received from USB device.
+  @param  IsochronousCallBack   When the transfer complete, the call back function will be called
+  @param  Context               Pass to the call back function as parameter
+
+  @retval EFI_UNSUPPORTED       This interface not available
+  @retval EFI_INVALID_PARAMETER Data is NULL or Datalength is 0
+
+**/
+
+EFI_STATUS
+EFIAPI
+OhciAsyncIsochronousTransfer (
+  IN     EFI_USB_HC_PROTOCOL                *This,
+  IN     UINT8                              DeviceAddress,
+  IN     UINT8                              EndPointAddress,
+  IN     UINT8                              MaximumPacketLength,
+  IN OUT VOID                               *Data,
+  IN OUT UINTN                              DataLength,
+  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK    IsochronousCallBack,
+  IN     VOID                               *Context OPTIONAL
+  );
+
+/**
+
+  Retrieves the number of root hub ports.
+
+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
+  @param  NumOfPorts            A pointer to the number of the root hub ports.
+
+  @retval EFI_SUCCESS           The port number was retrieved successfully.
+**/
+EFI_STATUS
+EFIAPI
+OhciGetRootHubNumOfPorts (
+  IN  EFI_USB_HC_PROTOCOL  *This,
+  OUT UINT8                *NumOfPorts
+  );
+/**
+
+  Retrieves the current status of a USB root hub port.
+
+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL.
+  @param  PortNumber            Specifies the root hub port from which the status
+                                is to be retrieved.  This value is zero-based. For example,
+                                if a root hub has two ports, then the first port is numbered 0,
+                                and the second port is numbered 1.
+  @param  PortStatus            A pointer to the current port status bits and
+                                port status change bits.
+
+  @retval EFI_SUCCESS           The status of the USB root hub port specified by PortNumber
+                                was returned in PortStatus.
+  @retval EFI_INVALID_PARAMETER Port number not valid
+**/
+
+
+EFI_STATUS
+EFIAPI
+OhciGetRootHubPortStatus (
+  IN  EFI_USB_HC_PROTOCOL  *This,
+  IN  UINT8                PortNumber,
+  OUT EFI_USB_PORT_STATUS  *PortStatus
+  );
+
+/**
+
+  Sets a feature for the specified root hub port.
+
+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL.
+  @param  PortNumber            Specifies the root hub port whose feature
+                                is requested to be set.
+  @param  PortFeature           Indicates the feature selector associated
+                                with the feature set request.
+
+  @retval EFI_SUCCESS           The feature specified by PortFeature was set for the
+                                USB root hub port specified by PortNumber.
+  @retval EFI_DEVICE_ERROR      Set feature failed because of hardware issue
+  @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
+**/
+EFI_STATUS
+EFIAPI
+OhciSetRootHubPortFeature (
+  IN EFI_USB_HC_PROTOCOL   *This,
+  IN UINT8                 PortNumber,
+  IN EFI_USB_PORT_FEATURE  PortFeature
+  );
+/**
+
+  Clears a feature for the specified root hub port.
+
+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
+  @param  PortNumber            Specifies the root hub port whose feature
+                                is requested to be cleared.
+  @param  PortFeature           Indicates the feature selector associated with the
+                                feature clear request.
+
+  @retval EFI_SUCCESS           The feature specified by PortFeature was cleared for the
+                                USB root hub port specified by PortNumber.
+  @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
+  @retval EFI_DEVICE_ERROR      Some error happened when clearing feature
+**/
+EFI_STATUS
+EFIAPI
+OhciClearRootHubPortFeature (
+  IN EFI_USB_HC_PROTOCOL   *This,
+  IN UINT8                 PortNumber,
+  IN EFI_USB_PORT_FEATURE  PortFeature
+  );
+
+
+/**
+  Test to see if this driver supports ControllerHandle. Any
+  ControllerHandle that has UsbHcProtocol installed will be supported.
+
+  @param  This                 Protocol instance pointer.
+  @param  Controller           Handle of device to test.
+  @param  RemainingDevicePath  Not used.
+
+  @return EFI_SUCCESS          This driver supports this device.
+  @return EFI_UNSUPPORTED      This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+
+OHCIDriverBindingSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  );
+
+/**
+  Starting the Usb OHCI Driver.
+
+  @param  This                  Protocol instance pointer.
+  @param  Controller            Handle of device to test.
+  @param  RemainingDevicePath   Not used.
+
+  @retval EFI_SUCCESS           This driver supports this device.
+  @retval EFI_UNSUPPORTED       This driver does not support this device.
+  @retval EFI_DEVICE_ERROR      This driver cannot be started due to device Error.
+                                EFI_OUT_OF_RESOURCES- Failed due to resource shortage.
+
+**/
+EFI_STATUS
+EFIAPI
+OHCIDriverBindingStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  );
+
+/**
+  Stop this driver on ControllerHandle. Support stopping any child handles
+  created by this driver.
+
+  @param  This                  Protocol instance pointer.
+  @param  Controller            Handle of device to stop driver on.
+  @param  NumberOfChildren      Number of Children in the ChildHandleBuffer.
+  @param  ChildHandleBuffer     List of handles for the children we need to stop.
+
+  @return EFI_SUCCESS
+  @return others
+
+**/
+EFI_STATUS
+EFIAPI
+OHCIDriverBindingStop (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN UINTN                        NumberOfChildren,
+  IN EFI_HANDLE                   *ChildHandleBuffer
+  );
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDebug.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDebug.c
new file mode 100644
index 0000000000..cf60794a99
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDebug.c
@@ -0,0 +1,78 @@
+/** @file
+This file provides the information dump support for OHCI when in debug mode.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "Ohci.h"
+
+
+/*++
+
+  Print the data of ED and the TDs attached to the ED
+
+  @param  Uhc                   Pointer to OHCI private data
+  @param  Ed                    Pointer to a ED to free
+  @param  Td                    Pointer to the Td head
+
+  @retval EFI_SUCCESS           ED
+
+**/
+EFI_STATUS
+OhciDumpEdTdInfo (
+  IN USB_OHCI_HC_DEV      *Uhc,
+  IN ED_DESCRIPTOR        *Ed,
+  IN TD_DESCRIPTOR        *Td,
+  BOOLEAN                 Stage
+  )
+{
+  UINT32                  Index;
+
+  if (Stage) {
+    DEBUG ((EFI_D_INFO, "\n Before executing command\n"));
+  }else{
+    DEBUG ((EFI_D_INFO, "\n after executing command\n"));
+  }
+  if (Ed != NULL) {
+    DEBUG ((EFI_D_INFO, "\nED Address:%p, ED buffer:\n", Ed));
+    DEBUG ((EFI_D_INFO, "DWord0  :TD Tail :TD Head :Next ED\n"));
+    for (Index = 0; Index < sizeof (ED_DESCRIPTOR)/4; Index ++) {
+      DEBUG ((EFI_D_INFO, "%8x ", *((UINT32*)(Ed) + Index)  ));
+    }
+    DEBUG ((EFI_D_INFO, "\nNext TD buffer:%p\n", Td));
+  }
+  while (Td != NULL) {
+    if (Td->Word0.DirPID == TD_SETUP_PID) {
+      DEBUG ((EFI_D_INFO, "\nSetup PID "));
+    }else if (Td->Word0.DirPID == TD_OUT_PID) {
+      DEBUG ((EFI_D_INFO, "\nOut PID "));
+    }else if (Td->Word0.DirPID == TD_IN_PID) {
+      DEBUG ((EFI_D_INFO, "\nIn PID "));
+    }else if (Td->Word0.DirPID == TD_NODATA_PID) {
+      DEBUG ((EFI_D_INFO, "\nNo data PID "));
+    }
+    DEBUG ((EFI_D_INFO, "TD Address:%p, TD buffer:\n", Td));
+    DEBUG ((EFI_D_INFO, "DWord0  :CuBuffer:Next TD :Buff End:Next TD :DataBuff:ActLength\n"));
+    for (Index = 0; Index < sizeof (TD_DESCRIPTOR)/4; Index ++) {
+      DEBUG ((EFI_D_INFO, "%8x ", *((UINT32*)(Td) + Index)  ));
+    }
+    DEBUG ((EFI_D_INFO, "\nCurrent TD Data buffer(size%d)\n", (UINT32)Td->ActualSendLength));
+    for (Index = 0; Index < Td->ActualSendLength; Index ++) {
+      DEBUG ((EFI_D_INFO, "%2x ", *(UINT8 *)(UINTN)(Td->DataBuffer + Index) ));
+    }
+  Td = (TD_DESCRIPTOR *)(UINTN)(Td->NextTDPointer);
+  }
+  DEBUG ((EFI_D_INFO, "\n TD buffer End\n"));
+
+  return EFI_SUCCESS;
+}
+
+
+
+
+
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDebug.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDebug.h
new file mode 100644
index 0000000000..a2d79ff7e5
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDebug.h
@@ -0,0 +1,42 @@
+/** @file
+This file contains the definination for host controller
+debug support routines.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+
+/*++
+
+Routine Description:
+
+  Print the data of ED and the TDs attached to the ED
+
+  @param  Uhc                   Pointer to OHCI private data
+  @param  Ed                    Pointer to a ED to free
+  @param  Td                    Pointer to the Td head
+
+  @retval EFI_SUCCESS           ED
+
+**/
+EFI_STATUS
+OhciDumpEdTdInfo (
+  IN USB_OHCI_HC_DEV          *Uhc,
+  IN ED_DESCRIPTOR     *Ed,
+  IN TD_DESCRIPTOR     *Td,
+  BOOLEAN Stage
+  );
+
+
+
+
+
+
+
+
+
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDxe.inf b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDxe.inf
new file mode 100644
index 0000000000..9b8f455969
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDxe.inf
@@ -0,0 +1,71 @@
+## @file
+# OHCI USB Host Controller UEFI Driver
+#
+# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = OhciDxe
+  FILE_GUID                      = 4ACA697E-F883-446f-98F7-096416FFFFFF
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = OHCIDriverEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+#  DRIVER_BINDING                =  gOhciDriverBinding
+#  COMPONENT_NAME                =  gOhciComponentName
+#  COMPONENT_NAME2               =  gOhciComponentName2
+#
+[Sources]
+  Descriptor.h
+  Ohci.c
+  Ohci.h
+  OhciSched.c
+  OhciSched.h
+  OhciReg.c
+  OhciReg.h
+  OhciUrb.c
+  OhciUrb.h
+  OhciDebug.c
+  OhciDebug.h
+  ComponentName.c
+  ComponentName.h
+  UsbHcMem.c
+  UsbHcMem.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  MemoryAllocationLib
+  BaseLib
+  UefiLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  BaseMemoryLib
+  DebugLib
+
+[Guids]
+  gEfiEventExitBootServicesGuid                 ## SOMETIMES_CONSUMES   ## Event
+
+[Protocols]
+  gEfiPciIoProtocolGuid                         ## TO_START
+  gEfiUsbHcProtocolGuid                         ## BY_START
+
+#
+# [Event]
+#   ##
+#   # Periodic timer event for checking the result of interrupt transfer execution.
+#   #
+#   EVENT_TYPE_PERIODIC_TIMER                   ## CONSUMES
+#
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.c
new file mode 100644
index 0000000000..f9cdd049be
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.c
@@ -0,0 +1,1390 @@
+/** @file
+The OHCI register operation routines.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "Ohci.h"
+
+/**
+
+  Get OHCI operational reg value
+
+  @param  PciIo                 PciIo protocol instance
+  @param  Offset                Offset of the operational reg
+
+  @retval                       Value of the register
+
+**/
+UINT32
+OhciGetOperationalReg (
+  IN EFI_PCI_IO_PROTOCOL  *PciIo,
+  IN UINT32               Offset
+  )
+{
+  UINT32                  Value;
+
+  PciIo->Mem.Read(PciIo, EfiPciIoWidthUint32, OHC_BAR_INDEX, Offset, 1, &Value);
+
+  return Value;
+}
+/**
+
+  Set OHCI operational reg value
+
+  @param  PciIo                  PCI Bus Io protocol instance
+  @param  Offset                 Offset of the operational reg
+  @param  Value                  Value to set
+
+  @retval EFI_SUCCESS            Value set to the reg
+
+**/
+
+
+EFI_STATUS
+OhciSetOperationalReg (
+  IN EFI_PCI_IO_PROTOCOL  *PciIo,
+  IN UINT32               Offset,
+  IN VOID                 *Value
+  )
+{
+  EFI_STATUS Status;
+
+  Status = PciIo->Mem.Write(PciIo, EfiPciIoWidthUint32, OHC_BAR_INDEX, Offset, 1, Value);
+
+  return Status;
+}
+/**
+
+  Get HcRevision reg value
+
+  @param  PciIo                 PCI Bus Io protocol instance
+
+  @retval                       Value of the register
+
+**/
+
+
+UINT32
+OhciGetHcRevision (
+  IN EFI_PCI_IO_PROTOCOL  *PciIo
+  )
+{
+  return OhciGetOperationalReg (PciIo, HC_REVISION);
+}
+/**
+
+  Set HcReset reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval EFI_SUCCESS           Value set
+
+**/
+
+EFI_STATUS
+OhciSetHcReset (
+  IN USB_OHCI_HC_DEV            *Ohc,
+  IN UINT32                     Field,
+  IN UINT32                     Value
+  )
+{
+  HcRESET                       Reset;
+
+  *(UINT32 *) &Reset = OhciGetOperationalReg (Ohc->PciIo, USBHOST_OFFSET_UHCHR);
+
+  if (Field & RESET_SYSTEM_BUS) {
+    Reset.FSBIR = Value;
+  }
+
+  if (Field & RESET_HOST_CONTROLLER) {
+    Reset.FHR = Value;
+  }
+
+  if (Field & RESET_CLOCK_GENERATION) {
+    Reset.CGR = Value;
+  }
+
+  if (Field & RESET_SSE_GLOBAL) {
+    Reset.SSE = Value;
+  }
+
+  if (Field & RESET_PSPL) {
+    Reset.PSPL = Value;
+  }
+
+  if (Field & RESET_PCPL) {
+    Reset.PCPL = Value;
+  }
+
+  if (Field & RESET_SSEP1) {
+    Reset.SSEP1 = Value;
+  }
+
+  if (Field & RESET_SSEP2) {
+    Reset.SSEP2 = Value;
+  }
+
+  if (Field & RESET_SSEP3) {
+    Reset.SSEP3 = Value;
+  }
+
+  OhciSetOperationalReg (Ohc->PciIo, USBHOST_OFFSET_UHCHR, &Reset);
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Get specific field of HcReset reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetHcReset (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Field
+  )
+{
+  HcRESET                 Reset;
+  UINT32                  Value;
+
+
+  *(UINT32 *) &Reset = OhciGetOperationalReg (Ohc->PciIo, USBHOST_OFFSET_UHCHR);
+  Value = 0;
+
+  switch (Field) {
+  case RESET_SYSTEM_BUS:
+    Value = Reset.FSBIR;
+    break;
+
+  case RESET_HOST_CONTROLLER:
+    Value = Reset.FHR;
+    break;
+
+  case RESET_CLOCK_GENERATION:
+    Value = Reset.CGR;
+    break;
+
+  case RESET_SSE_GLOBAL:
+    Value = Reset.SSE;
+    break;
+
+  case RESET_PSPL:
+    Value = Reset.PSPL;
+    break;
+
+  case RESET_PCPL:
+    Value = Reset.PCPL;
+    break;
+
+  case RESET_SSEP1:
+    Value = Reset.SSEP1;
+    break;
+
+  case RESET_SSEP2:
+    Value = Reset.SSEP2;
+    break;
+
+  case RESET_SSEP3:
+    Value = Reset.SSEP3;
+    break;
+
+  default:
+    ASSERT (FALSE);
+  }
+
+
+  return Value;
+}
+
+/**
+
+  Set HcControl reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetHcControl (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field,
+  IN UINT32               Value
+  )
+{
+  EFI_STATUS              Status;
+  HcCONTROL               Control;
+
+
+
+  *(UINT32 *) &Control = OhciGetOperationalReg (Ohc->PciIo, HC_CONTROL);
+
+  if (Field & CONTROL_BULK_RATIO) {
+    Control.ControlBulkRatio = Value;
+  }
+
+  if (Field & HC_FUNCTIONAL_STATE) {
+    Control.FunctionalState = Value;
+  }
+
+  if (Field & PERIODIC_ENABLE) {
+    Control.PeriodicEnable = Value;
+  }
+
+  if (Field & CONTROL_ENABLE) {
+    Control.ControlEnable = Value;
+  }
+
+  if (Field & ISOCHRONOUS_ENABLE) {
+    Control.IsochronousEnable = Value;
+  }
+
+  if (Field & BULK_ENABLE) {
+    Control.BulkEnable = Value;
+  }
+
+  if (Field & INTERRUPT_ROUTING) {
+    Control.InterruptRouting = Value;
+  }
+
+  Status = OhciSetOperationalReg (Ohc->PciIo, HC_CONTROL, &Control);
+
+  return Status;
+}
+
+
+/**
+
+  Get specific field of HcControl reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+
+UINT32
+OhciGetHcControl (
+  IN USB_OHCI_HC_DEV   *Ohc,
+  IN UINTN             Field
+  )
+{
+  HcCONTROL     Control;
+
+  *(UINT32 *) &Control = OhciGetOperationalReg (Ohc->PciIo, HC_CONTROL);
+
+  switch (Field) {
+  case CONTROL_BULK_RATIO:
+    return Control.ControlBulkRatio;
+    break;
+  case PERIODIC_ENABLE:
+    return Control.PeriodicEnable;
+    break;
+  case CONTROL_ENABLE:
+    return Control.ControlEnable;
+    break;
+  case BULK_ENABLE:
+    return Control.BulkEnable;
+    break;
+  case ISOCHRONOUS_ENABLE:
+    return Control.IsochronousEnable;
+    break;
+  case HC_FUNCTIONAL_STATE:
+    return Control.FunctionalState;
+    break;
+  case INTERRUPT_ROUTING:
+    return Control.InterruptRouting;
+    break;
+  default:
+    ASSERT (FALSE);
+  }
+
+  return 0;
+}
+
+/**
+
+  Set HcCommand reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval EFI_SUCCESS           Value set
+
+**/
+
+EFI_STATUS
+OhciSetHcCommandStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field,
+  IN UINT32               Value
+  )
+{
+  EFI_STATUS              Status;
+  HcCOMMAND_STATUS        CommandStatus;
+
+  ZeroMem (&CommandStatus, sizeof (HcCOMMAND_STATUS));
+
+  if(Field & HC_RESET){
+    CommandStatus.HcReset = Value;
+  }
+
+  if(Field & CONTROL_LIST_FILLED){
+    CommandStatus.ControlListFilled = Value;
+  }
+
+  if(Field & BULK_LIST_FILLED){
+    CommandStatus.BulkListFilled = Value;
+  }
+
+  if(Field & CHANGE_OWNER_REQUEST){
+    CommandStatus.ChangeOwnerRequest = Value;
+  }
+
+  if(Field & SCHEDULE_OVERRUN_COUNT){
+    CommandStatus.ScheduleOverrunCount = Value;
+  }
+
+  Status = OhciSetOperationalReg (Ohc->PciIo, HC_COMMAND_STATUS, &CommandStatus);
+
+  return Status;
+}
+
+/**
+
+  Get specific field of HcCommand reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetHcCommandStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  )
+{
+  HcCOMMAND_STATUS        CommandStatus;
+
+  *(UINT32 *) &CommandStatus = OhciGetOperationalReg (Ohc->PciIo, HC_COMMAND_STATUS);
+
+  switch (Field){
+  case HC_RESET:
+    return CommandStatus.HcReset;
+    break;
+  case CONTROL_LIST_FILLED:
+    return CommandStatus.ControlListFilled;
+    break;
+  case BULK_LIST_FILLED:
+    return CommandStatus.BulkListFilled;
+    break;
+  case CHANGE_OWNER_REQUEST:
+    return CommandStatus.ChangeOwnerRequest;
+    break;
+  case SCHEDULE_OVERRUN_COUNT:
+    return CommandStatus.ScheduleOverrunCount;
+    break;
+  default:
+    ASSERT (FALSE);
+  }
+
+  return 0;
+}
+
+/**
+
+  Clear specific fields of Interrupt Status
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to clear
+
+  @retval EFI_SUCCESS           Fields cleared
+
+**/
+
+EFI_STATUS
+OhciClearInterruptStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  )
+{
+  EFI_STATUS              Status;
+  HcINTERRUPT_STATUS      InterruptStatus;
+
+  ZeroMem (&InterruptStatus, sizeof (HcINTERRUPT_STATUS));
+
+  if(Field & SCHEDULE_OVERRUN){
+    InterruptStatus.SchedulingOverrun = 1;
+  }
+
+  if(Field & WRITEBACK_DONE_HEAD){
+    InterruptStatus.WriteBackDone = 1;
+  }
+  if(Field & START_OF_FRAME){
+    InterruptStatus.Sof = 1;
+  }
+
+  if(Field & RESUME_DETECT){
+    InterruptStatus.ResumeDetected = 1;
+  }
+
+  if(Field & UNRECOVERABLE_ERROR){
+    InterruptStatus.UnrecoverableError = 1;
+  }
+
+  if(Field & FRAME_NUMBER_OVERFLOW){
+    InterruptStatus.FrameNumOverflow = 1;
+  }
+
+  if(Field & ROOTHUB_STATUS_CHANGE){
+    InterruptStatus.RHStatusChange = 1;
+  }
+
+  if(Field & OWNERSHIP_CHANGE){
+    InterruptStatus.OwnerChange = 1;
+  }
+
+  Status = OhciSetOperationalReg (Ohc->PciIo, HC_INTERRUPT_STATUS, &InterruptStatus);
+
+  return Status;
+}
+
+/**
+
+  Get fields of HcInterrupt reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetHcInterruptStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  )
+{
+  HcINTERRUPT_STATUS      InterruptStatus;
+
+  *(UINT32 *) &InterruptStatus = OhciGetOperationalReg (Ohc->PciIo, HC_INTERRUPT_STATUS);
+
+  switch (Field){
+  case SCHEDULE_OVERRUN:
+    return InterruptStatus.SchedulingOverrun;
+    break;
+
+  case  WRITEBACK_DONE_HEAD:
+    return InterruptStatus.WriteBackDone;
+    break;
+
+  case START_OF_FRAME:
+    return InterruptStatus.Sof;
+    break;
+
+  case RESUME_DETECT:
+    return InterruptStatus.ResumeDetected;
+    break;
+
+  case UNRECOVERABLE_ERROR:
+    return InterruptStatus.UnrecoverableError;
+    break;
+
+  case FRAME_NUMBER_OVERFLOW:
+    return InterruptStatus.FrameNumOverflow;
+    break;
+
+  case ROOTHUB_STATUS_CHANGE:
+    return InterruptStatus.RHStatusChange;
+    break;
+
+  case OWNERSHIP_CHANGE:
+    return InterruptStatus.OwnerChange;
+    break;
+
+  default:
+    ASSERT (FALSE);
+  }
+
+  return 0;
+}
+
+/**
+
+  Set Interrupt Control reg value
+
+  @param  Ohc                   UHC private data
+  @param  StatEnable            Enable or Disable
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval EFI_SUCCESS           Value set
+
+**/
+
+EFI_STATUS
+OhciSetInterruptControl (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN BOOLEAN              StatEnable,
+  IN UINTN                Field,
+  IN UINT32               Value
+  )
+{
+  EFI_STATUS              Status;
+  HcINTERRUPT_CONTROL     InterruptState;
+
+
+  ZeroMem (&InterruptState, sizeof (HcINTERRUPT_CONTROL));
+
+  if(Field & SCHEDULE_OVERRUN) {
+    InterruptState.SchedulingOverrunInt = Value;
+  }
+
+  if(Field & WRITEBACK_DONE_HEAD) {
+    InterruptState.WriteBackDoneInt = Value;
+  }
+  if(Field & START_OF_FRAME) {
+    InterruptState.SofInt = Value;
+  }
+
+  if(Field & RESUME_DETECT) {
+    InterruptState.ResumeDetectedInt = Value;
+  }
+
+  if(Field & UNRECOVERABLE_ERROR) {
+    InterruptState.UnrecoverableErrorInt = Value;
+  }
+
+  if(Field & FRAME_NUMBER_OVERFLOW) {
+    InterruptState.FrameNumOverflowInt = Value;
+  }
+
+  if(Field & ROOTHUB_STATUS_CHANGE) {
+    InterruptState.RHStatusChangeInt = Value;
+  }
+
+  if(Field & OWNERSHIP_CHANGE) {
+    InterruptState.OwnerChangedInt = Value;
+  }
+
+  if(Field & MASTER_INTERRUPT) {
+    InterruptState.MasterInterruptEnable = Value;
+  }
+
+  if (StatEnable) {
+    Status = OhciSetOperationalReg (Ohc->PciIo, HC_INTERRUPT_ENABLE, &InterruptState);
+  } else {
+    Status = OhciSetOperationalReg (Ohc->PciIo, HC_INTERRUPT_DISABLE, &InterruptState);
+  }
+
+  return Status;
+}
+
+/**
+
+  Get field of HcInterruptControl reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetHcInterruptControl (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  )
+{
+  HcINTERRUPT_CONTROL     InterruptState;
+
+  *(UINT32 *) &InterruptState = OhciGetOperationalReg (Ohc->PciIo, HC_INTERRUPT_ENABLE);
+
+  switch (Field){
+    case SCHEDULE_OVERRUN:
+      return InterruptState.SchedulingOverrunInt;
+      break;
+
+    case WRITEBACK_DONE_HEAD:
+      return InterruptState.WriteBackDoneInt;
+      break;
+
+    case START_OF_FRAME:
+      return InterruptState.SofInt;
+      break;
+
+    case RESUME_DETECT:
+      return InterruptState.ResumeDetectedInt;
+      break;
+
+    case UNRECOVERABLE_ERROR:
+      return InterruptState.UnrecoverableErrorInt;
+      break;
+
+    case FRAME_NUMBER_OVERFLOW:
+      return InterruptState.FrameNumOverflowInt;
+      break;
+
+    case ROOTHUB_STATUS_CHANGE:
+      return InterruptState.RHStatusChangeInt;
+      break;
+
+    case OWNERSHIP_CHANGE:
+      return InterruptState.OwnerChangedInt;
+      break;
+
+    case MASTER_INTERRUPT:
+      return InterruptState.MasterInterruptEnable;
+      break;
+
+    default:
+      ASSERT (FALSE);
+  }
+
+  return 0;
+}
+
+/**
+
+  Set memory pointer of specific type
+
+  @param  Ohc                   UHC private data
+  @param  PointerType           Type of the pointer to set
+  @param  Value                 Value to set
+
+  @retval EFI_SUCCESS           Memory pointer set
+
+**/
+
+EFI_STATUS
+OhciSetMemoryPointer(
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               PointerType,
+  IN VOID                 *Value
+  )
+{
+  EFI_STATUS              Status;
+  UINT32                  Verify;
+
+  Status = OhciSetOperationalReg (Ohc->PciIo, PointerType, &Value);
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Verify = OhciGetOperationalReg (Ohc->PciIo, PointerType);
+
+  while (Verify != (UINT32)(UINTN) Value) {
+    gBS->Stall(1000);
+    Verify = OhciGetOperationalReg (Ohc->PciIo, PointerType);
+  };
+
+
+  return Status;
+}
+
+/**
+
+  Get memory pointer of specific type
+
+  @param  Ohc                   UHC private data
+  @param  PointerType           Type of pointer
+
+  @retval                       Memory pointer of the specific type
+
+**/
+
+VOID *
+OhciGetMemoryPointer (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               PointerType
+  )
+{
+
+  return (VOID *)(UINTN) OhciGetOperationalReg (Ohc->PciIo, PointerType);
+}
+
+
+/**
+
+  Set Frame Interval value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetFrameInterval (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field,
+  IN UINT32               Value
+  )
+{
+  EFI_STATUS              Status;
+  HcFRM_INTERVAL          FrameInterval;
+
+
+  *(UINT32 *) &FrameInterval = OhciGetOperationalReg(Ohc->PciIo, HC_FRM_INTERVAL);
+
+  if (Field & FRAME_INTERVAL) {
+    FrameInterval.FrmIntervalToggle = !FrameInterval.FrmIntervalToggle;
+    FrameInterval.FrameInterval = Value;
+  }
+
+  if (Field & FS_LARGEST_DATA_PACKET) {
+    FrameInterval.FSMaxDataPacket = Value;
+  }
+
+  if (Field & FRMINT_TOGGLE) {
+    FrameInterval.FrmIntervalToggle = Value;
+  }
+
+  Status = OhciSetOperationalReg (
+             Ohc->PciIo,
+             HC_FRM_INTERVAL,
+             &FrameInterval
+             );
+
+  return Status;
+}
+
+
+/**
+
+  Get field of frame interval reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetFrameInterval (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  )
+{
+  HcFRM_INTERVAL          FrameInterval;
+
+  *(UINT32 *) &FrameInterval = OhciGetOperationalReg (Ohc->PciIo, HC_FRM_INTERVAL);
+
+  switch (Field){
+    case FRAME_INTERVAL:
+      return FrameInterval.FrameInterval;
+      break;
+
+    case FS_LARGEST_DATA_PACKET:
+      return FrameInterval.FSMaxDataPacket;
+      break;
+
+    case FRMINT_TOGGLE:
+      return FrameInterval.FrmIntervalToggle;
+      break;
+
+    default:
+      ASSERT (FALSE);
+  }
+
+  return 0;
+}
+
+/**
+
+  Set Frame Remaining reg value
+
+  @param  Ohc                   UHC private data
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetFrameRemaining (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Value
+  )
+{
+  EFI_STATUS              Status;
+  HcFRAME_REMAINING       FrameRemaining;
+
+
+  *(UINT32 *) &FrameRemaining = OhciGetOperationalReg (Ohc->PciIo, HC_FRM_REMAINING);
+
+  FrameRemaining.FrameRemaining = Value;
+  FrameRemaining.FrameRemainingToggle = !FrameRemaining.FrameRemainingToggle;
+
+  Status = OhciSetOperationalReg (Ohc->PciIo, HC_FRM_REMAINING, &FrameRemaining);
+
+  return Status;
+}
+/**
+
+  Get value of frame remaining reg
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of frame remaining reg
+
+**/
+UINT32
+OhciGetFrameRemaining (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  )
+
+{
+  HcFRAME_REMAINING       FrameRemaining;
+
+
+  *(UINT32 *) &FrameRemaining = OhciGetOperationalReg (Ohc->PciIo, HC_FRM_REMAINING);
+
+  switch (Field){
+    case FRAME_REMAINING:
+      return FrameRemaining.FrameRemaining;
+      break;
+
+    case FRAME_REMAIN_TOGGLE:
+      return FrameRemaining.FrameRemainingToggle;
+      break;
+
+    default:
+      ASSERT (FALSE);
+  }
+
+  return 0;
+}
+
+/**
+
+  Set frame number reg value
+
+  @param  Ohc                   UHC private data
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetFrameNumber(
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Value
+  )
+{
+  EFI_STATUS              Status;
+
+  Status = OhciSetOperationalReg (Ohc->PciIo, HC_FRM_NUMBER, &Value);
+
+  return Status;
+}
+
+/**
+
+  Get frame number reg value
+
+  @param  Ohc                   UHC private data
+
+  @retval                       Value of frame number reg
+
+**/
+
+UINT32
+OhciGetFrameNumber (
+  IN USB_OHCI_HC_DEV      *Ohc
+  )
+{
+  return OhciGetOperationalReg(Ohc->PciIo, HC_FRM_NUMBER);
+}
+
+/**
+
+  Set period start reg value
+
+  @param  Ohc                   UHC private data
+  @param  Value                 Value to set
+
+  @retval EFI_SUCCESS           Value set
+
+**/
+
+EFI_STATUS
+OhciSetPeriodicStart (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Value
+  )
+{
+  EFI_STATUS              Status;
+
+
+  Status = OhciSetOperationalReg (Ohc->PciIo, HC_PERIODIC_START, &Value);
+
+  return Status;
+}
+
+
+/**
+
+  Get periodic start reg value
+
+  @param  Ohc                   UHC private data
+
+  @param                        Value of periodic start reg
+
+**/
+
+UINT32
+OhciGetPeriodicStart (
+  IN USB_OHCI_HC_DEV      *Ohc
+  )
+{
+  return OhciGetOperationalReg(Ohc->PciIo, HC_PERIODIC_START);
+}
+
+
+/**
+
+  Set Ls Threshold reg value
+
+  @param  Ohc                   UHC private data
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetLsThreshold (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Value
+  )
+{
+  EFI_STATUS              Status;
+
+
+  Status = OhciSetOperationalReg (Ohc->PciIo, HC_LS_THREASHOLD, &Value);
+
+  return Status;
+}
+
+
+/**
+
+  Get Ls Threshold reg value
+
+  @param  Ohc                   UHC private data
+
+  @retval                       Value of Ls Threshold reg
+
+**/
+
+UINT32
+OhciGetLsThreshold (
+  IN USB_OHCI_HC_DEV      *Ohc
+  )
+{
+  return OhciGetOperationalReg(Ohc->PciIo, HC_LS_THREASHOLD);
+}
+
+/**
+
+  Set Root Hub Descriptor reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+EFI_STATUS
+OhciSetRootHubDescriptor (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field,
+  IN UINT32               Value
+  )
+{
+  EFI_STATUS              Status;
+  HcRH_DESC_A             DescriptorA;
+  HcRH_DESC_B             DescriptorB;
+
+
+  if (Field & (RH_DEV_REMOVABLE | RH_PORT_PWR_CTRL_MASK)) {
+    *(UINT32 *) &DescriptorB = OhciGetOperationalReg (Ohc->PciIo, HC_RH_DESC_B);
+
+    if(Field & RH_DEV_REMOVABLE) {
+      DescriptorB.DeviceRemovable = Value;
+    }
+    if(Field & RH_PORT_PWR_CTRL_MASK) {
+      DescriptorB.PortPowerControlMask = Value;
+    }
+
+    Status = OhciSetOperationalReg (Ohc->PciIo, HC_RH_DESC_B, &DescriptorB);
+
+    return Status;
+  }
+
+  *(UINT32 *)&DescriptorA = OhciGetOperationalReg (Ohc->PciIo, HC_RH_DESC_A);
+
+  if(Field & RH_NUM_DS_PORTS) {
+    DescriptorA.NumDownStrmPorts = Value;
+  }
+  if(Field & RH_NO_PSWITCH) {
+    DescriptorA.NoPowerSwitch = Value;
+  }
+  if(Field & RH_PSWITCH_MODE) {
+    DescriptorA.PowerSwitchMode = Value;
+  }
+  if(Field & RH_DEVICE_TYPE) {
+    DescriptorA.DeviceType = Value;
+  }
+  if(Field & RH_OC_PROT_MODE) {
+    DescriptorA.OverCurrentProtMode = Value;
+  }
+  if(Field & RH_NOC_PROT) {
+    DescriptorA.NoOverCurrentProtMode = Value;
+  }
+  if(Field & RH_NO_POTPGT) {
+    DescriptorA.PowerOnToPowerGoodTime = Value;
+  }
+
+  Status = OhciSetOperationalReg (Ohc->PciIo, HC_RH_DESC_A, &DescriptorA);
+
+  return Status;
+}
+
+
+/**
+
+  Get Root Hub Descriptor reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetRootHubDescriptor (
+  IN USB_OHCI_HC_DEV     *Ohc,
+  IN UINTN               Field
+  )
+{
+  HcRH_DESC_A             DescriptorA;
+  HcRH_DESC_B             DescriptorB;
+
+
+  *(UINT32 *) &DescriptorA = OhciGetOperationalReg (Ohc->PciIo, HC_RH_DESC_A);
+  *(UINT32 *) &DescriptorB = OhciGetOperationalReg (Ohc->PciIo, HC_RH_DESC_B);
+
+  switch (Field){
+    case RH_DEV_REMOVABLE:
+      return DescriptorB.DeviceRemovable;
+      break;
+
+    case RH_PORT_PWR_CTRL_MASK:
+      return DescriptorB.PortPowerControlMask;
+      break;
+
+    case RH_NUM_DS_PORTS:
+      return DescriptorA.NumDownStrmPorts;
+      break;
+
+    case RH_NO_PSWITCH:
+      return DescriptorA.NoPowerSwitch;
+      break;
+
+    case RH_PSWITCH_MODE:
+      return DescriptorA.PowerSwitchMode;
+      break;
+
+    case RH_DEVICE_TYPE:
+      return DescriptorA.DeviceType;
+      break;
+
+    case RH_OC_PROT_MODE:
+      return DescriptorA.OverCurrentProtMode;
+      break;
+
+    case RH_NOC_PROT:
+      return DescriptorA.NoOverCurrentProtMode;
+      break;
+
+    case RH_NO_POTPGT:
+      return DescriptorA.PowerOnToPowerGoodTime;
+      break;
+
+    default:
+      ASSERT (FALSE);
+  }
+
+  return 0;
+}
+
+
+/**
+
+  Set Root Hub Status reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetRootHubStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  )
+{
+  EFI_STATUS              Status;
+  HcRH_STATUS             RootHubStatus;
+
+
+  ZeroMem (&RootHubStatus, sizeof(HcRH_STATUS));
+
+  if(Field & RH_LOCAL_PSTAT){
+    RootHubStatus.LocalPowerStat = 1;
+  }
+  if(Field & RH_OC_ID){
+    RootHubStatus.OverCurrentIndicator = 1;
+  }
+  if(Field & RH_REMOTE_WK_ENABLE){
+    RootHubStatus.DevRemoteWakeupEnable = 1;
+  }
+  if(Field & RH_LOCAL_PSTAT_CHANGE){
+    RootHubStatus.LocalPowerStatChange = 1;
+  }
+  if(Field & RH_OC_ID_CHANGE){
+    RootHubStatus.OverCurrentIndicatorChange = 1;
+  }
+  if(Field & RH_CLR_RMT_WK_ENABLE){
+    RootHubStatus.ClearRemoteWakeupEnable = 1;
+  }
+
+  Status = OhciSetOperationalReg (Ohc->PciIo, HC_RH_STATUS, &RootHubStatus);
+
+  return Status;
+}
+
+
+/**
+
+  Get Root Hub Status reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetRootHubStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  )
+{
+  HcRH_STATUS             RootHubStatus;
+
+
+  *(UINT32 *) &RootHubStatus = OhciGetOperationalReg (Ohc->PciIo, HC_RH_STATUS);
+
+  switch (Field) {
+    case RH_LOCAL_PSTAT:
+      return RootHubStatus.LocalPowerStat;
+      break;
+    case RH_OC_ID:
+      return RootHubStatus.OverCurrentIndicator;
+      break;
+    case RH_REMOTE_WK_ENABLE:
+      return RootHubStatus.DevRemoteWakeupEnable;
+      break;
+    case RH_LOCAL_PSTAT_CHANGE:
+      return RootHubStatus.LocalPowerStatChange;
+      break;
+    case RH_OC_ID_CHANGE:
+      return RootHubStatus.OverCurrentIndicatorChange;
+      break;
+    case RH_CLR_RMT_WK_ENABLE:
+      return RootHubStatus.ClearRemoteWakeupEnable;
+      break;
+    default:
+      ASSERT (FALSE);
+  }
+
+  return 0;
+}
+
+
+/**
+
+  Set Root Hub Port Status reg value
+
+  @param  Ohc                   UHC private data
+  @param  Index                 Index of the port
+  @param  Field                 Field to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetRootHubPortStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Index,
+  IN UINTN                Field
+  )
+{
+  EFI_STATUS              Status;
+  HcRHPORT_STATUS         PortStatus;
+
+
+  ZeroMem (&PortStatus, sizeof(HcRHPORT_STATUS));
+
+  if (Field & RH_CLEAR_PORT_ENABLE) {
+    PortStatus.CurrentConnectStat = 1;
+  }
+  if (Field & RH_SET_PORT_ENABLE) {
+    PortStatus.EnableStat = 1;
+  }
+  if (Field & RH_SET_PORT_SUSPEND) {
+    PortStatus.SuspendStat = 1;
+  }
+  if (Field & RH_CLEAR_SUSPEND_STATUS) {
+    PortStatus.OCIndicator = 1;
+  }
+  if (Field & RH_SET_PORT_RESET) {
+    PortStatus.ResetStat = 1;
+  }
+  if (Field & RH_SET_PORT_POWER) {
+    PortStatus.PowerStat = 1;
+  }
+  if (Field & RH_CLEAR_PORT_POWER) {
+    PortStatus.LsDeviceAttached = 1;
+  }
+  if (Field & RH_CONNECT_STATUS_CHANGE) {
+    PortStatus.ConnectStatChange = 1;
+  }
+  if (Field & RH_PORT_ENABLE_STAT_CHANGE) {
+    PortStatus.EnableStatChange = 1;
+  }
+  if (Field & RH_PORT_SUSPEND_STAT_CHANGE) {
+    PortStatus.SuspendStatChange = 1;
+  }
+  if (Field & RH_OC_INDICATOR_CHANGE) {
+    PortStatus.OCIndicatorChange = 1;
+  }
+  if (Field & RH_PORT_RESET_STAT_CHANGE ) {
+    PortStatus.ResetStatChange = 1;
+  }
+
+  Status = OhciSetOperationalReg (Ohc->PciIo, HC_RH_PORT_STATUS + (Index * 4), &PortStatus);
+
+  return Status;
+}
+
+
+/**
+
+  Get Root Hub Port Status reg value
+
+  @param  Ohc                   UHC private data
+  @param  Index                 Index of the port
+  @param  Field                 Field to get
+
+  @retval                       Value of the field and index
+
+**/
+
+UINT32
+OhciReadRootHubPortStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Index,
+  IN UINTN                Field
+  )
+{
+  HcRHPORT_STATUS         PortStatus;
+
+  *(UINT32 *) &PortStatus = OhciGetOperationalReg (
+                              Ohc->PciIo,
+                              HC_RH_PORT_STATUS + (Index * 4)
+                              );
+
+  switch (Field){
+  case RH_CURR_CONNECT_STAT:
+    return PortStatus.CurrentConnectStat;
+    break;
+  case RH_PORT_ENABLE_STAT:
+    return PortStatus.EnableStat;
+    break;
+  case RH_PORT_SUSPEND_STAT:
+    return PortStatus.SuspendStat;
+    break;
+  case RH_PORT_OC_INDICATOR:
+    return PortStatus.OCIndicator;
+    break;
+  case RH_PORT_RESET_STAT:
+    return PortStatus.ResetStat;
+    break;
+  case RH_PORT_POWER_STAT:
+    return PortStatus.PowerStat;
+    break;
+  case RH_LSDEVICE_ATTACHED:
+    return PortStatus.LsDeviceAttached;
+    break;
+  case RH_CONNECT_STATUS_CHANGE:
+    return PortStatus.ConnectStatChange;
+    break;
+  case RH_PORT_ENABLE_STAT_CHANGE:
+    return PortStatus.EnableStatChange;
+    break;
+  case RH_PORT_SUSPEND_STAT_CHANGE:
+    return PortStatus.SuspendStatChange;
+    break;
+  case RH_OC_INDICATOR_CHANGE:
+    return PortStatus.OCIndicatorChange;
+    break;
+  case RH_PORT_RESET_STAT_CHANGE:
+    return PortStatus.ResetStatChange;
+    break;
+  default:
+    ASSERT (FALSE);
+  }
+
+  return 0;
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.h
new file mode 100644
index 0000000000..e4d1008053
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.h
@@ -0,0 +1,920 @@
+/** @file
+This file contains the definination for host controller
+register operation routines.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+
+#ifndef   _OHCI_REG_H
+#define   _OHCI_REG_H
+
+#define   HC_STATE_RESET         0x0
+#define   HC_STATE_RESUME        0x1
+#define   HC_STATE_OPERATIONAL   0x2
+#define   HC_STATE_SUSPEND       0x3
+
+#define   PERIODIC_ENABLE               0x01
+#define   ISOCHRONOUS_ENABLE            0x02
+#define   CONTROL_ENABLE                0x04
+#define   BULK_ENABLE                   0x08
+#define   CONTROL_BULK_RATIO            0x10
+
+#define   HC_FUNCTIONAL_STATE    0x20
+#define   INTERRUPT_ROUTING      0x40
+
+#define   HC_RESET               0x01
+#define   CONTROL_LIST_FILLED    0x02
+#define   BULK_LIST_FILLED       0x04
+#define   CHANGE_OWNER_REQUEST   0x08
+
+#define   SCHEDULE_OVERRUN_COUNT 0x10
+
+#define   SCHEDULE_OVERRUN       0x00001
+#define   WRITEBACK_DONE_HEAD    0x00002
+#define   START_OF_FRAME         0x00004
+#define   RESUME_DETECT          0x00008
+#define   UNRECOVERABLE_ERROR    0x00010
+#define   FRAME_NUMBER_OVERFLOW  0x00020
+#define   ROOTHUB_STATUS_CHANGE  0x00040
+#define   OWNERSHIP_CHANGE       0x00080
+
+#define   MASTER_INTERRUPT       0x00400
+
+#define   CONTROL_HEAD           0x001
+#define   BULK_HEAD              0x002
+#define   DONE_HEAD              0x004
+
+#define   Hc_HCCA                0x001
+#define   Hc_PERIODIC_CURRENT    0x002
+#define   Hc_CONTOL_HEAD         0x004
+#define   Hc_CONTROL_CURRENT_PTR 0x008
+#define   Hc_BULK_HEAD           0x010
+#define   Hc_BULK_CURRENT_PTR    0x020
+#define   Hc_DONE_HEAD           0x040
+
+#define   FRAME_INTERVAL         0x008
+#define   FS_LARGEST_DATA_PACKET 0x010
+#define   FRMINT_TOGGLE          0x020
+#define   FRAME_REMAINING        0x040
+#define   FRAME_REMAIN_TOGGLE    0x080
+
+#define   RH_DESC_A              0x00001
+#define   RH_DESC_B              0x00002
+#define   RH_NUM_DS_PORTS        0x00004
+#define   RH_NO_PSWITCH          0x00008
+#define   RH_PSWITCH_MODE        0x00010
+#define   RH_DEVICE_TYPE         0x00020
+#define   RH_OC_PROT_MODE        0x00040
+#define   RH_NOC_PROT            0x00080
+#define   RH_POTPGT              0x00100
+#define   RH_NO_POTPGT           0x00200
+#define   RH_DEV_REMOVABLE       0x00400
+#define   RH_PORT_PWR_CTRL_MASK  0x00800
+
+#define   RH_LOCAL_PSTAT         0x00001
+#define   RH_OC_ID               0x00002
+#define   RH_REMOTE_WK_ENABLE    0x00004
+#define   RH_LOCAL_PSTAT_CHANGE  0x00008
+#define   RH_OC_ID_CHANGE        0x00010
+#define   RH_CLR_RMT_WK_ENABLE   0x00020
+
+#define   RH_CLEAR_PORT_ENABLE        0x0001
+#define   RH_SET_PORT_ENABLE          0x0002
+#define   RH_SET_PORT_SUSPEND         0x0004
+#define   RH_CLEAR_SUSPEND_STATUS     0x0008
+#define   RH_SET_PORT_RESET           0x0010
+#define   RH_SET_PORT_POWER           0x0020
+#define   RH_CLEAR_PORT_POWER         0x0040
+#define   RH_CONNECT_STATUS_CHANGE    0x10000
+#define   RH_PORT_ENABLE_STAT_CHANGE  0x20000
+#define   RH_PORT_SUSPEND_STAT_CHANGE 0x40000
+#define   RH_OC_INDICATOR_CHANGE      0x80000
+#define   RH_PORT_RESET_STAT_CHANGE   0x100000
+
+#define   RH_CURR_CONNECT_STAT        0x0001
+#define   RH_PORT_ENABLE_STAT         0x0002
+#define   RH_PORT_SUSPEND_STAT        0x0004
+#define   RH_PORT_OC_INDICATOR        0x0008
+#define   RH_PORT_RESET_STAT          0x0010
+#define   RH_PORT_POWER_STAT          0x0020
+#define   RH_LSDEVICE_ATTACHED        0x0040
+
+#define   RESET_SYSTEM_BUS            (1 << 0)
+#define   RESET_HOST_CONTROLLER       (1 << 1)
+#define   RESET_CLOCK_GENERATION      (1 << 2)
+#define   RESET_SSE_GLOBAL            (1 << 5)
+#define   RESET_PSPL                  (1 << 6)
+#define   RESET_PCPL                  (1 << 7)
+#define   RESET_SSEP1                 (1 << 9)
+#define   RESET_SSEP2                 (1 << 10)
+#define   RESET_SSEP3                 (1 << 11)
+
+#define ONE_SECOND                      1000000
+#define ONE_MILLI_SEC                   1000
+#define MAX_BYTES_PER_TD                0x1000
+#define MAX_RETRY_TIMES                 100
+#define PORT_NUMBER_ON_MAINSTONE2       1
+
+
+//
+// Operational Register Offsets
+//
+
+//
+// Command & Status Registers Offsets
+//
+#define HC_REVISION             0x00
+#define HC_CONTROL              0x04
+#define HC_COMMAND_STATUS       0x08
+#define HC_INTERRUPT_STATUS     0x0C
+#define HC_INTERRUPT_ENABLE     0x10
+#define HC_INTERRUPT_DISABLE    0x14
+
+//
+// Memory Pointer Offsets
+//
+#define HC_HCCA                 0x18
+#define HC_PERIODIC_CURRENT     0x1C
+#define HC_CONTROL_HEAD         0x20
+#define HC_CONTROL_CURRENT_PTR  0x24
+#define HC_BULK_HEAD            0x28
+#define HC_BULK_CURRENT_PTR     0x2C
+#define HC_DONE_HEAD            0x30
+
+//
+// Frame Register Offsets
+//
+#define HC_FRM_INTERVAL         0x34
+#define HC_FRM_REMAINING        0x38
+#define HC_FRM_NUMBER           0x3C
+#define HC_PERIODIC_START       0x40
+#define HC_LS_THREASHOLD        0x44
+
+//
+// Root Hub Register Offsets
+//
+#define HC_RH_DESC_A            0x48
+#define HC_RH_DESC_B            0x4C
+#define HC_RH_STATUS            0x50
+#define HC_RH_PORT_STATUS       0x54
+
+#define USBHOST_OFFSET_UHCHR         0x64         // Usb Host reset register
+
+#define OHC_BAR_INDEX               0
+
+//
+// Usb Host controller register offset
+//
+#define USBHOST_OFFSET_UHCREV        0x0          // Usb Host revision register
+#define USBHOST_OFFSET_UHCHCON       0x4          // Usb Host control register
+#define USBHOST_OFFSET_UHCCOMS       0x8          // Usb Host Command Status register
+#define USBHOST_OFFSET_UHCINTS       0xC          // Usb Host Interrupt Status register
+#define USBHOST_OFFSET_UHCINTE       0x10         // Usb Host Interrupt Enable register
+#define USBHOST_OFFSET_UHCINTD       0x14         // Usb Host Interrupt Disable register
+#define USBHOST_OFFSET_UHCHCCA       0x18         // Usb Host Controller Communication Area
+#define USBHOST_OFFSET_UHCPCED       0x1C         // Usb Host Period Current Endpoint Descriptor
+#define USBHOST_OFFSET_UHCCHED       0x20         // Usb Host Control Head Endpoint Descriptor
+#define USBHOST_OFFSET_UHCCCED       0x24         // Usb Host Control Current Endpoint Descriptor
+#define USBHOST_OFFSET_UHCBHED       0x28         // Usb Host Bulk Head Endpoint Descriptor
+#define USBHOST_OFFSET_UHCBCED       0x2C         // Usb Host Bulk Current Endpoint Descriptor
+#define USBHOST_OFFSET_UHCDHEAD      0x30         // Usb Host Done Head register
+#define USBHOST_OFFSET_UHCFMI        0x34         // Usb Host Frame Interval register
+#define USBHOST_OFFSET_UHCFMR        0x38         // Usb Host Frame Remaining register
+#define USBHOST_OFFSET_UHCFMN        0x3C         // Usb Host Frame Number register
+#define USBHOST_OFFSET_UHCPERS       0x40         // Usb Host Periodic Start register
+#define USBHOST_OFFSET_UHCLST        0x44         // Usb Host Low-Speed Threshold register
+#define USBHOST_OFFSET_UHCRHDA       0x48         // Usb Host Root Hub Descriptor A register
+#define USBHOST_OFFSET_UHCRHDB       0x4C         // Usb Host Root Hub Descriptor B register
+#define USBHOST_OFFSET_UHCRHS        0x50         // Usb Host Root Hub Status register
+#define USBHOST_OFFSET_UHCRHPS1      0x54         // Usb Host Root Hub Port Status 1 register
+
+//
+// Usb Host controller register bit fields
+//
+#pragma pack(1)
+
+typedef struct {
+  UINT8                   ProgInterface;
+  UINT8                   SubClassCode;
+  UINT8                   BaseCode;
+} USB_CLASSC;
+
+typedef struct {
+    UINT32 Revision:8;
+    UINT32 Rsvd:24;
+} HcREVISION;
+
+typedef struct {
+    UINT32 ControlBulkRatio:2;
+    UINT32 PeriodicEnable:1;
+    UINT32 IsochronousEnable:1;
+    UINT32 ControlEnable:1;
+    UINT32 BulkEnable:1;
+    UINT32 FunctionalState:2;
+    UINT32 InterruptRouting:1;
+    UINT32 RemoteWakeup:1;
+    UINT32 RemoteWakeupEnable:1;
+    UINT32 Reserved:21;
+} HcCONTROL;
+
+typedef struct {
+    UINT32 HcReset:1;
+    UINT32 ControlListFilled:1;
+    UINT32 BulkListFilled:1;
+    UINT32 ChangeOwnerRequest:1;
+    UINT32 Reserved1:12;
+    UINT32 ScheduleOverrunCount:2;
+    UINT32 Reserved:14;
+} HcCOMMAND_STATUS;
+
+typedef struct {
+    UINT32 SchedulingOverrun:1;
+    UINT32 WriteBackDone:1;
+    UINT32 Sof:1;
+    UINT32 ResumeDetected:1;
+    UINT32 UnrecoverableError:1;
+    UINT32 FrameNumOverflow:1;
+    UINT32 RHStatusChange:1;
+    UINT32 Reserved1:23;
+    UINT32 OwnerChange:1;
+    UINT32 Reserved2:1;
+} HcINTERRUPT_STATUS;
+
+typedef struct {
+    UINT32 SchedulingOverrunInt:1;
+    UINT32 WriteBackDoneInt:1;
+    UINT32 SofInt:1;
+    UINT32 ResumeDetectedInt:1;
+    UINT32 UnrecoverableErrorInt:1;
+    UINT32 FrameNumOverflowInt:1;
+    UINT32 RHStatusChangeInt:1;
+    UINT32 Reserved:23;
+    UINT32 OwnerChangedInt:1;
+    UINT32 MasterInterruptEnable:1;
+} HcINTERRUPT_CONTROL;
+
+typedef struct {
+    UINT32 Rerserved:8;
+    UINT32 Hcca:24;
+} HcHCCA;
+
+typedef struct {
+    UINT32 Reserved:4;
+    UINT32 MemoryPtr:28;
+} HcMEMORY_PTR;
+
+typedef struct {
+    UINT32 FrameInterval:14;
+    UINT32 Reserved:2;
+    UINT32 FSMaxDataPacket:15;
+    UINT32 FrmIntervalToggle:1;
+} HcFRM_INTERVAL;
+
+typedef struct {
+    UINT32 FrameRemaining:14;
+    UINT32 Reserved:17;
+    UINT32 FrameRemainingToggle:1;
+} HcFRAME_REMAINING;
+
+typedef struct {
+    UINT32 FrameNumber:16;
+    UINT32 Reserved:16;
+} HcFRAME_NUMBER;
+
+typedef struct {
+    UINT32 PeriodicStart:14;
+    UINT32 Reserved:18;
+} HcPERIODIC_START;
+
+typedef struct {
+    UINT32 LsThreshold:12;
+    UINT32 Reserved:20;
+} HcLS_THRESHOLD;
+
+typedef struct {
+    UINT32 NumDownStrmPorts:8;
+    UINT32 PowerSwitchMode:1;
+    UINT32 NoPowerSwitch:1;
+    UINT32 DeviceType:1;
+    UINT32 OverCurrentProtMode:1;
+    UINT32 NoOverCurrentProtMode:1;
+    UINT32 Reserved:11;
+    UINT32 PowerOnToPowerGoodTime:8;
+} HcRH_DESC_A;
+
+typedef struct {
+    UINT32 DeviceRemovable:16;
+    UINT32 PortPowerControlMask:16;
+} HcRH_DESC_B;
+
+typedef struct {
+    UINT32 LocalPowerStat:1;
+    UINT32 OverCurrentIndicator:1;
+    UINT32 Reserved1:13;
+    UINT32 DevRemoteWakeupEnable:1;
+    UINT32 LocalPowerStatChange:1;
+    UINT32 OverCurrentIndicatorChange:1;
+    UINT32 Reserved2:13;
+    UINT32 ClearRemoteWakeupEnable:1;
+} HcRH_STATUS;
+
+typedef struct {
+    UINT32 CurrentConnectStat:1;
+    UINT32 EnableStat:1;
+    UINT32 SuspendStat:1;
+    UINT32 OCIndicator:1;
+    UINT32 ResetStat:1;
+    UINT32 Reserved1:3;
+    UINT32 PowerStat:1;
+    UINT32 LsDeviceAttached:1;
+    UINT32 Reserved2:6;
+    UINT32 ConnectStatChange:1;
+    UINT32 EnableStatChange:1;
+    UINT32 SuspendStatChange:1;
+    UINT32 OCIndicatorChange:1;
+    UINT32 ResetStatChange:1;
+    UINT32 Reserved3:11;
+} HcRHPORT_STATUS;
+
+typedef struct {
+    UINT32 FSBIR:1;
+    UINT32 FHR:1;
+    UINT32 CGR:1;
+    UINT32 SSDC:1;
+    UINT32 UIT:1;
+    UINT32 SSE:1;
+    UINT32 PSPL:1;
+    UINT32 PCPL:1;
+    UINT32 Reserved0:1;
+    UINT32 SSEP1:1;
+    UINT32 SSEP2:1;
+    UINT32 SSEP3:1;
+    UINT32 Reserved1:20;
+} HcRESET;
+
+
+#pragma pack()
+
+//
+// Func List
+//
+
+
+/**
+
+  Get OHCI operational reg value
+
+  @param  PciIo                 PciIo protocol instance
+  @param  Offset                Offset of the operational reg
+
+  @retval                       Value of the register
+
+**/
+UINT32
+OhciGetOperationalReg (
+  IN EFI_PCI_IO_PROTOCOL  *PciIo,
+  IN UINT32               Offset
+  );
+
+/**
+
+  Set OHCI operational reg value
+
+  @param  PciIo                  PCI Bus Io protocol instance
+  @param  Offset                 Offset of the operational reg
+  @param  Value                  Value to set
+
+  @retval EFI_SUCCESS            Value set to the reg
+
+**/
+
+
+EFI_STATUS
+OhciSetOperationalReg (
+  IN EFI_PCI_IO_PROTOCOL  *PciIo,
+  IN UINT32               Offset,
+  IN VOID                 *Value
+  );
+
+
+/**
+
+  Get HcRevision reg value
+
+  @param  PciIo                 PCI Bus Io protocol instance
+
+  @retval                       Value of the register
+
+**/
+
+
+UINT32
+OhciGetHcRevision (
+  IN EFI_PCI_IO_PROTOCOL  *PciIo
+  );
+
+/**
+
+  Set HcReset reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval EFI_SUCCESS           Value set
+
+**/
+
+EFI_STATUS
+OhciSetHcReset (
+  IN USB_OHCI_HC_DEV            *Ohc,
+  IN UINT32                     Field,
+  IN UINT32                     Value
+  );
+/**
+
+  Get specific field of HcReset reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetHcReset (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Field
+  );
+/**
+
+  Set HcControl reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetHcControl (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field,
+  IN UINT32               Value
+  );
+
+
+/**
+
+  Get specific field of HcControl reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+
+UINT32
+OhciGetHcControl (
+  IN USB_OHCI_HC_DEV   *Ohc,
+  IN UINTN             Field
+  );
+
+
+/**
+
+  Set HcCommand reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval EFI_SUCCESS           Value set
+
+**/
+
+EFI_STATUS
+OhciSetHcCommandStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field,
+  IN UINT32               Value
+  );
+
+/**
+
+  Get specific field of HcCommand reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetHcCommandStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  );
+
+/**
+
+  Clear specific fields of Interrupt Status
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to clear
+
+  @retval EFI_SUCCESS           Fields cleared
+
+**/
+
+EFI_STATUS
+OhciClearInterruptStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  );
+
+/**
+
+  Get fields of HcInterrupt reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetHcInterruptStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  );
+
+/**
+
+  Set Interrupt Control reg value
+
+  @param  Ohc                   UHC private data
+  @param  StatEnable            Enable or Disable
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval EFI_SUCCESS           Value set
+
+**/
+
+EFI_STATUS
+OhciSetInterruptControl (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN BOOLEAN              StatEnable,
+  IN UINTN                Field,
+  IN UINT32               Value
+  );
+
+/**
+
+  Get field of HcInterruptControl reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetHcInterruptControl (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  );
+
+
+/**
+
+  Set memory pointer of specific type
+
+  @param  Ohc                   UHC private data
+  @param  PointerType           Type of the pointer to set
+  @param  Value                 Value to set
+
+  @retval EFI_SUCCESS           Memory pointer set
+
+**/
+
+EFI_STATUS
+OhciSetMemoryPointer(
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               PointerType,
+  IN VOID                 *Value
+  );
+
+/**
+
+  Get memory pointer of specific type
+
+  @param  Ohc                   UHC private data
+  @param  PointerType           Type of pointer
+
+  @retval                       Memory pointer of the specific type
+
+**/
+
+VOID *
+OhciGetMemoryPointer (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               PointerType
+  );
+
+/**
+
+  Set Frame Interval value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetFrameInterval (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field,
+  IN UINT32               Value
+  );
+
+
+/**
+
+  Get field of frame interval reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetFrameInterval (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  );
+
+
+/**
+
+  Set Frame Remaining reg value
+
+  @param  Ohc                   UHC private data
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetFrameRemaining (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Value
+  );
+
+/**
+
+  Get value of frame remaining reg
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of frame remaining reg
+
+**/
+UINT32
+OhciGetFrameRemaining (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  );
+
+/**
+
+  Set frame number reg value
+
+  @param  Ohc                   UHC private data
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetFrameNumber(
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Value
+  );
+
+/**
+
+  Get frame number reg value
+
+  @param  Ohc                   UHC private data
+
+  @retval                       Value of frame number reg
+
+**/
+
+UINT32
+OhciGetFrameNumber (
+  IN USB_OHCI_HC_DEV      *Ohc
+  );
+
+
+/**
+
+  Set period start reg value
+
+  @param  Ohc                   UHC private data
+  @param  Value                 Value to set
+
+  @retval EFI_SUCCESS           Value set
+
+**/
+
+EFI_STATUS
+OhciSetPeriodicStart (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Value
+  );
+
+
+/**
+
+  Get periodic start reg value
+
+  @param  Ohc                   UHC private data
+
+  @param                        Value of periodic start reg
+
+**/
+
+UINT32
+OhciGetPeriodicStart (
+  IN USB_OHCI_HC_DEV      *Ohc
+  );
+
+
+/**
+
+  Set Ls Threshold reg value
+
+  @param  Ohc                   UHC private data
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetLsThreshold (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Value
+  );
+
+/**
+
+  Get Ls Threshold reg value
+
+  @param  Ohc                   UHC private data
+
+  @retval                       Value of Ls Threshold reg
+
+**/
+
+UINT32
+OhciGetLsThreshold (
+  IN USB_OHCI_HC_DEV      *Ohc
+  );
+
+/**
+
+  Set Root Hub Descriptor reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+EFI_STATUS
+OhciSetRootHubDescriptor (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field,
+  IN UINT32               Value
+  );
+
+
+/**
+
+  Get Root Hub Descriptor reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetRootHubDescriptor (
+  IN USB_OHCI_HC_DEV     *Ohc,
+  IN UINTN               Field
+  );
+
+/**
+
+  Set Root Hub Status reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetRootHubStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  );
+
+
+/**
+
+  Get Root Hub Status reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetRootHubStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  );
+
+
+/**
+
+  Set Root Hub Port Status reg value
+
+  @param  Ohc                   UHC private data
+  @param  Index                 Index of the port
+  @param  Field                 Field to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetRootHubPortStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Index,
+  IN UINTN                Field
+  );
+
+
+/**
+
+  Get Root Hub Port Status reg value
+
+  @param  Ohc                   UHC private data
+  @param  Index                 Index of the port
+  @param  Field                 Field to get
+
+  @retval                       Value of the field and index
+
+**/
+
+UINT32
+OhciReadRootHubPortStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Index,
+  IN UINTN                Field
+  );
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciSched.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciSched.c
new file mode 100644
index 0000000000..d49b5ec9ad
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciSched.c
@@ -0,0 +1,528 @@
+/** @file
+OHCI transfer scheduling routines.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "Ohci.h"
+
+/**
+
+  Add an item of interrupt context
+
+  @param  Ohc                   UHC private data
+  @param  NewEntry              New entry to add
+
+  @retval EFI_SUCCESS           Item successfully added
+
+**/
+EFI_STATUS
+OhciAddInterruptContextEntry (
+  IN  USB_OHCI_HC_DEV          *Ohc,
+  IN  INTERRUPT_CONTEXT_ENTRY  *NewEntry
+  )
+{
+  INTERRUPT_CONTEXT_ENTRY  *Entry;
+  EFI_TPL                  OriginalTPL;
+
+  OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);
+
+  if (Ohc->InterruptContextList == NULL) {
+    Ohc->InterruptContextList = NewEntry;
+  } else {
+    Entry = Ohc->InterruptContextList;
+    while (Entry->NextEntry != NULL) {
+      Entry = Entry->NextEntry;
+    }
+    Entry->NextEntry = NewEntry;
+  }
+
+  gBS->RestoreTPL (OriginalTPL);
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+
+  Free a interrupt context entry
+
+  @param  Ohc                   UHC private data
+  @param  Entry                 Pointer to an interrupt context entry
+
+  @retval EFI_SUCCESS           Entry freed
+  @retval EFI_INVALID_PARAMETER Entry is NULL
+
+**/
+EFI_STATUS
+OhciFreeInterruptContextEntry (
+  IN USB_OHCI_HC_DEV          *Ohc,
+  IN INTERRUPT_CONTEXT_ENTRY  *Entry
+  )
+{
+  TD_DESCRIPTOR           *Td;
+  if (Entry == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  if (Entry->UCBufferMapping != NULL) {
+    Ohc->PciIo->Unmap(Ohc->PciIo, Entry->UCBufferMapping);
+  }
+  if (Entry->UCBuffer != NULL) {
+    FreePool(Entry->UCBuffer);
+  }
+  while (Entry->DataTd) {
+    Td = Entry->DataTd;
+    Entry->DataTd = (TD_DESCRIPTOR *)(UINTN)(Entry->DataTd->NextTDPointer);
+    UsbHcFreeMem(Ohc->MemPool, Td, sizeof(TD_DESCRIPTOR));
+  }
+  FreePool(Entry);
+  return EFI_SUCCESS;
+}
+
+
+/**
+
+  Free entries match the device address and endpoint address
+
+  @Param  Ohc                   UHC private date
+  @Param  DeviceAddress         Item to free must match this device address
+  @Param  EndPointAddress       Item to free must match this end point address
+  @Param  DataToggle            DataToggle for output
+
+  @retval  EFI_SUCCESS          Items match the requirement removed
+
+**/
+EFI_STATUS
+OhciFreeInterruptContext(
+  IN  USB_OHCI_HC_DEV     *Ohc,
+  IN  UINT8               DeviceAddress,
+  IN  UINT8               EndPointAddress,
+  OUT UINT8               *DataToggle
+  )
+{
+  INTERRUPT_CONTEXT_ENTRY  *Entry;
+  INTERRUPT_CONTEXT_ENTRY  *TempEntry;
+  EFI_TPL                  OriginalTPL;
+
+
+  OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);
+
+  while (Ohc->InterruptContextList != NULL &&
+    Ohc->InterruptContextList->DeviceAddress == DeviceAddress &&
+    Ohc->InterruptContextList->EndPointAddress == EndPointAddress) {
+    TempEntry = Ohc->InterruptContextList;
+    Ohc->InterruptContextList = Ohc->InterruptContextList->NextEntry;
+    if (DataToggle != NULL) {
+      *DataToggle = (UINT8) (TempEntry->DataTd->Word0.DataToggle & 0x1);
+    }
+    OhciFreeInterruptContextEntry (Ohc, TempEntry);
+  }
+
+  Entry = Ohc->InterruptContextList;
+  if (Entry == NULL) {
+    gBS->RestoreTPL (OriginalTPL);
+    return EFI_SUCCESS;
+  }
+  while (Entry->NextEntry != NULL) {
+    if (Entry->NextEntry->DeviceAddress == DeviceAddress &&
+      Entry->NextEntry->EndPointAddress == EndPointAddress) {
+      TempEntry = Entry->NextEntry;
+      Entry->NextEntry = Entry->NextEntry->NextEntry;
+      if (DataToggle != NULL) {
+        *DataToggle = (UINT8) (TempEntry->DataTd->Word0.DataToggle & 0x1);
+      }
+      OhciFreeInterruptContextEntry (Ohc, TempEntry);
+    } else {
+      Entry = Entry->NextEntry;
+    }
+  }
+
+  gBS->RestoreTPL (OriginalTPL);
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+
+  Convert Error code from OHCI format to EFI format
+
+  @Param  ErrorCode             ErrorCode in OHCI format
+
+  @retval                       ErrorCode in EFI format
+
+**/
+UINT32
+ConvertErrorCode (
+  IN  UINT32              ErrorCode
+  )
+{
+  UINT32                  TransferResult;
+
+  switch (ErrorCode) {
+    case TD_NO_ERROR:
+      TransferResult = EFI_USB_NOERROR;
+      break;
+
+    case TD_TOBE_PROCESSED:
+    case TD_TOBE_PROCESSED_2:
+      TransferResult = EFI_USB_ERR_NOTEXECUTE;
+      break;
+
+    case TD_DEVICE_STALL:
+      TransferResult = EFI_USB_ERR_STALL;
+      break;
+
+    case TD_BUFFER_OVERRUN:
+    case TD_BUFFER_UNDERRUN:
+      TransferResult = EFI_USB_ERR_BUFFER;
+      break;
+
+    case TD_CRC_ERROR:
+      TransferResult = EFI_USB_ERR_CRC;
+      break;
+
+    case TD_NO_RESPONSE:
+      TransferResult = EFI_USB_ERR_TIMEOUT;
+      break;
+
+    case TD_BITSTUFFING_ERROR:
+      TransferResult = EFI_USB_ERR_BITSTUFF;
+      break;
+
+    default:
+      TransferResult = EFI_USB_ERR_SYSTEM;
+  }
+
+  return TransferResult;
+}
+
+
+/**
+
+  Check TDs Results
+
+  @Param  Ohc                   UHC private data
+  @Param  Td                    TD_DESCRIPTOR
+  @Param  Result                Result to return
+
+  @retval TRUE                  means OK
+  @retval FLASE                 means Error or Short packet
+
+**/
+BOOLEAN
+OhciCheckTDsResults (
+  IN  USB_OHCI_HC_DEV     *Ohc,
+  IN  TD_DESCRIPTOR       *Td,
+  OUT UINT32              *Result
+  )
+{
+  UINT32                  TdCompletionCode;
+
+  *Result   = EFI_USB_NOERROR;
+
+  while (Td) {
+    TdCompletionCode = Td->Word0.ConditionCode;
+
+    *Result |= ConvertErrorCode(TdCompletionCode);
+    //
+    // if any error encountered, stop processing the left TDs.
+    //
+    if (*Result) {
+      return FALSE;
+    }
+
+    Td = (TD_DESCRIPTOR *)(UINTN)(Td->NextTDPointer);
+  }
+  return TRUE;
+
+}
+
+
+/**
+
+  Check the task status on an ED
+
+  @Param  Ed                    Pointer to the ED task that TD hooked on
+  @Param  HeadTd                TD header for current transaction
+
+  @retval                       Task Status Code
+
+**/
+
+UINT32
+CheckEDStatus (
+  IN  ED_DESCRIPTOR       *Ed,
+  IN  TD_DESCRIPTOR       *HeadTd,
+  OUT OHCI_ED_RESULT      *EdResult
+  )
+{
+  while(HeadTd != NULL) {
+    if (HeadTd->NextTDPointer == 0) {
+      return TD_NO_ERROR;
+    }
+    if (HeadTd->Word0.ConditionCode != 0) {
+      return HeadTd->Word0.ConditionCode;
+    }
+    EdResult->NextToggle = ((UINT8)(HeadTd->Word0.DataToggle) & BIT0) ^ BIT0;
+    HeadTd = (TD_DESCRIPTOR *)(UINTN)(HeadTd->NextTDPointer);
+  }
+  if (OhciGetEDField (Ed, ED_TDHEAD_PTR) != OhciGetEDField (Ed, ED_TDTAIL_PTR)) {
+    return TD_TOBE_PROCESSED;
+  }
+  return TD_NO_ERROR;
+}
+
+/**
+
+  Check the task status
+
+  @Param  Ohc                   UHC private data
+  @Param  ListType              Pipe type
+  @Param  Ed                    Pointer to the ED task hooked on
+  @Param  HeadTd                Head of TD corresponding to the task
+  @Param  ErrorCode             return the ErrorCode
+
+  @retval  EFI_SUCCESS          Task done
+  @retval  EFI_NOT_READY        Task on processing
+  @retval  EFI_DEVICE_ERROR     Some error occured
+
+**/
+EFI_STATUS
+CheckIfDone (
+  IN  USB_OHCI_HC_DEV       *Ohc,
+  IN  DESCRIPTOR_LIST_TYPE  ListType,
+  IN  ED_DESCRIPTOR         *Ed,
+  IN  TD_DESCRIPTOR         *HeadTd,
+  OUT OHCI_ED_RESULT        *EdResult
+  )
+{
+  EdResult->ErrorCode = TD_TOBE_PROCESSED;
+
+  switch (ListType) {
+    case CONTROL_LIST:
+      if (OhciGetHcCommandStatus (Ohc, CONTROL_LIST_FILLED) != 0) {
+        return EFI_NOT_READY;
+      }
+      break;
+    case BULK_LIST:
+      if (OhciGetHcCommandStatus (Ohc, BULK_LIST_FILLED) != 0) {
+        return EFI_NOT_READY;
+      }
+      break;
+    default:
+      break;
+  }
+
+  EdResult->ErrorCode = CheckEDStatus (Ed, HeadTd, EdResult);
+
+  if (EdResult->ErrorCode == TD_NO_ERROR) {
+    return EFI_SUCCESS;
+  } else if (EdResult->ErrorCode == TD_TOBE_PROCESSED) {
+    return EFI_NOT_READY;
+  } else {
+    return EFI_DEVICE_ERROR;
+  }
+}
+
+
+/**
+
+  Convert TD condition code to Efi Status
+
+  @Param  ConditionCode         Condition code to convert
+
+  @retval  EFI_SUCCESS          No error occured
+  @retval  EFI_NOT_READY        TD still on processing
+  @retval  EFI_DEVICE_ERROR     Error occured in processing TD
+
+**/
+
+EFI_STATUS
+OhciTDConditionCodeToStatus (
+  IN  UINT32              ConditionCode
+  )
+{
+  if (ConditionCode == TD_NO_ERROR) {
+    return EFI_SUCCESS;
+  }
+
+  if (ConditionCode == TD_TOBE_PROCESSED) {
+    return EFI_NOT_READY;
+  }
+
+  return EFI_DEVICE_ERROR;
+}
+
+/**
+
+  Invoke callbacks hooked on done TDs
+
+  @Param  Entry                 Interrupt transfer transaction information data structure
+  @Param  Context               Ohc private data
+
+**/
+
+VOID
+OhciInvokeInterruptCallBack(
+  IN  INTERRUPT_CONTEXT_ENTRY  *Entry,
+  IN  UINT32                   Result
+)
+{
+  //Generally speaking, Keyboard driver should not
+  //check the Keyboard buffer if an error happens, it will be robust
+  //if we NULLed the buffer once error happens
+  if (Result) {
+    Entry->CallBackFunction (
+             NULL,
+             0,
+             Entry->Context,
+             Result
+             );
+  }else{
+    Entry->CallBackFunction (
+             (VOID *)(UINTN)(Entry->DataTd->DataBuffer),
+             Entry->DataTd->ActualSendLength,
+             Entry->Context,
+             Result
+             );
+  }
+}
+
+
+/**
+
+  Timer to submit periodic interrupt transfer, and invoke callbacks hooked on done TDs
+
+  @param  Event                 Event handle
+  @param  Context               Device private data
+
+**/
+
+VOID
+EFIAPI
+OhciHouseKeeper (
+  IN  EFI_EVENT           Event,
+  IN  VOID                *Context
+  )
+{
+
+  USB_OHCI_HC_DEV          *Ohc;
+  INTERRUPT_CONTEXT_ENTRY  *Entry;
+  INTERRUPT_CONTEXT_ENTRY  *PreEntry;
+  ED_DESCRIPTOR            *Ed;
+  TD_DESCRIPTOR            *DataTd;
+  TD_DESCRIPTOR            *HeadTd;
+
+  UINT8                    Toggle;
+  EFI_TPL                  OriginalTPL;
+  UINT32                   Result;
+
+  Ohc = (USB_OHCI_HC_DEV *) Context;
+  OriginalTPL = gBS->RaiseTPL(TPL_NOTIFY);
+
+  Entry = Ohc->InterruptContextList;
+  PreEntry = NULL;
+
+  while(Entry != NULL) {
+
+    OhciCheckTDsResults(Ohc, Entry->DataTd, &Result );
+    if (((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) ||
+      ((Result & EFI_USB_ERR_NOTEXECUTE) == EFI_USB_ERR_NOTEXECUTE)) {
+      PreEntry = Entry;
+      Entry = Entry->NextEntry;
+      continue;
+    }
+
+    if (Entry->CallBackFunction != NULL) {
+      OhciInvokeInterruptCallBack (Entry, Result);
+      if (Ohc->InterruptContextList == NULL) {
+        gBS->RestoreTPL (OriginalTPL);
+        return;
+      }
+    }
+    if (Entry->IsPeriodic) {
+
+      Ed = Entry->Ed;
+      HeadTd = Entry->DataTd;
+      DataTd = HeadTd;
+      Toggle = 0;
+      if (Result == EFI_USB_NOERROR) {
+        //
+        // Update toggle if there is no error, and re-submit the interrupt Ed&Tds
+        //
+        if ((Ed != NULL) && (DataTd != NULL)) {
+          Ed->Word0.Skip = 1;
+        }
+        //
+        // From hcir1_0a.pdf 4.2.2
+        // ToggleCarry:This bit is the data toggle carry bit,
+        // Whenever a TD is retired, this bit is written to
+        // contain the last data toggle value(LSb of data Toggel
+        // file) from the retired TD.
+        // This field is not used for Isochronous Endpoints
+        //
+        if (Ed == NULL) {
+          return;
+        }
+        Toggle = (UINT8) OhciGetEDField (Ed, ED_DTTOGGLE);
+        while(DataTd != NULL) {
+          if (DataTd->NextTDPointer == 0) {
+            DataTd->Word0.DataToggle = 0;
+            break;
+          } else {
+            OhciSetTDField (DataTd, TD_DT_TOGGLE, Toggle);
+          }
+          DataTd = (TD_DESCRIPTOR *)(UINTN)(DataTd->NextTDPointer);
+          Toggle ^= 1;
+        }
+        //
+        // HC will only update DataToggle, ErrorCount, ConditionCode
+        // CurrentBufferPointer & NextTD, so we only need to update
+        // them once we want to active them again
+        //
+        DataTd = HeadTd;
+        while (DataTd != NULL) {
+          if (DataTd->NextTDPointer == 0) {
+            OhciSetTDField (DataTd, TD_ERROR_CNT | TD_COND_CODE | TD_CURR_BUFFER_PTR | TD_NEXT_PTR, 0);
+            break;
+          }
+          OhciSetTDField (DataTd, TD_ERROR_CNT, 0);
+          OhciSetTDField (DataTd, TD_COND_CODE, TD_TOBE_PROCESSED);
+          DataTd->NextTD = DataTd->NextTDPointer;
+          DataTd->CurrBufferPointer = DataTd->DataBuffer;
+          DataTd = (TD_DESCRIPTOR *)(UINTN)(DataTd->NextTDPointer);
+        }
+        //
+        // Active current Ed,Td
+        //
+        // HC will only update Halted, ToggleCarry & TDQueueHeadPointer,
+        // So we only need to update them once we want to active them again.
+        //
+        if ((Ed != NULL) && (DataTd != NULL)) {
+          Ed->Word2.TdHeadPointer = (UINT32)((UINTN)HeadTd>>4);
+          OhciSetEDField (Ed, ED_HALTED | ED_DTTOGGLE, 0);
+          Ed->Word0.Skip = 0;
+        }
+      }
+    } else {
+      if (PreEntry == NULL) {
+        Ohc->InterruptContextList = Entry->NextEntry;
+      } else {
+        PreEntry = Entry;
+        PreEntry->NextEntry = Entry->NextEntry;
+      }
+      OhciFreeInterruptContextEntry (Ohc, PreEntry);
+      gBS->RestoreTPL (OriginalTPL);
+      return;
+    }
+    PreEntry = Entry;
+    Entry = Entry->NextEntry;
+  }
+  gBS->RestoreTPL (OriginalTPL);
+}
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciSched.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciSched.h
new file mode 100644
index 0000000000..1c4114cb00
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciSched.h
@@ -0,0 +1,225 @@
+/** @file
+This file contains the definination for host controller schedule routines.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+
+#ifndef _OHCI_SCHED_H
+#define _OHCI_SCHED_H
+
+#include "Descriptor.h"
+
+#define HCCA_MEM_SIZE     256
+#define GRID_SIZE         16
+#define GRID_SHIFT        4
+
+typedef struct _INTERRUPT_CONTEXT_ENTRY INTERRUPT_CONTEXT_ENTRY;
+
+struct _INTERRUPT_CONTEXT_ENTRY{
+  UINT8                               DeviceAddress;
+  UINT8                               EndPointAddress;
+  ED_DESCRIPTOR                       *Ed;
+  TD_DESCRIPTOR                       *DataTd;
+  BOOLEAN                             IsSlowDevice;
+  UINT8                               MaxPacketLength;
+  UINTN                               PollingInterval;
+  EFI_ASYNC_USB_TRANSFER_CALLBACK     CallBackFunction;
+  VOID                                *Context;
+  BOOLEAN                             IsPeriodic;
+  VOID                                *Buffer;
+  UINTN                               DataLength;
+  VOID                                *UCBuffer;
+  VOID                                *UCBufferMapping;
+  UINT8                               *Toggle;
+  INTERRUPT_CONTEXT_ENTRY      *NextEntry;
+};
+
+
+typedef struct {
+  UINT32                  ErrorCode;
+  UINT8                   NextToggle;
+} OHCI_ED_RESULT;
+
+/**
+
+  Add an item of interrupt context
+
+  @param  Ohc                   UHC private data
+  @param  NewEntry              New entry to add
+
+  @retval EFI_SUCCESS           Item successfully added
+
+**/
+EFI_STATUS
+OhciAddInterruptContextEntry (
+  IN  USB_OHCI_HC_DEV          *Ohc,
+  IN  INTERRUPT_CONTEXT_ENTRY  *NewEntry
+  );
+
+/**
+
+  Free a interrupt context entry
+
+  @param  Ohc                   UHC private data
+  @param  Entry                 Pointer to an interrupt context entry
+
+  @retval EFI_SUCCESS           Entry freed
+  @retval EFI_INVALID_PARAMETER Entry is NULL
+
+**/
+EFI_STATUS
+OhciFreeInterruptContextEntry (
+  IN USB_OHCI_HC_DEV          *Ohc,
+  IN INTERRUPT_CONTEXT_ENTRY  *Entry
+  );
+
+/**
+
+  Free entries match the device address and endpoint address
+
+  @Param  Ohc                   UHC private date
+  @Param  DeviceAddress         Item to free must match this device address
+  @Param  EndPointAddress       Item to free must match this end point address
+  @Param  DataToggle            DataToggle for output
+
+  @retval  EFI_SUCCESS          Items match the requirement removed
+
+**/
+EFI_STATUS
+OhciFreeInterruptContext(
+  IN  USB_OHCI_HC_DEV     *Ohc,
+  IN  UINT8               DeviceAddress,
+  IN  UINT8               EndPointAddress,
+  OUT UINT8               *DataToggle
+  );
+
+
+/**
+
+  Convert Error code from OHCI format to EFI format
+
+  @Param  ErrorCode             ErrorCode in OHCI format
+
+  @retval                       ErrorCode in EFI format
+
+**/
+UINT32
+ConvertErrorCode (
+  IN  UINT32              ErrorCode
+  );
+
+
+/**
+
+  Check TDs Results
+
+  @Param  Ohc                   UHC private data
+  @Param  Td                    TD_DESCRIPTOR
+  @Param  Result                Result to return
+
+  @retval TRUE                  means OK
+  @retval FLASE                 means Error or Short packet
+
+**/
+BOOLEAN
+OhciCheckTDsResults (
+  IN  USB_OHCI_HC_DEV     *Ohc,
+  IN  TD_DESCRIPTOR       *Td,
+  OUT UINT32              *Result
+  );
+/**
+
+  Check the task status on an ED
+
+  @Param  Ed                    Pointer to the ED task that TD hooked on
+  @Param  HeadTd                TD header for current transaction
+
+  @retval                       Task Status Code
+
+**/
+
+UINT32
+CheckEDStatus (
+  IN  ED_DESCRIPTOR       *Ed,
+  IN  TD_DESCRIPTOR       *HeadTd,
+  OUT OHCI_ED_RESULT      *EdResult
+  );
+/**
+
+  Check the task status
+
+  @Param  Ohc                   UHC private data
+  @Param  ListType              Pipe type
+  @Param  Ed                    Pointer to the ED task hooked on
+  @Param  HeadTd                Head of TD corresponding to the task
+  @Param  ErrorCode             return the ErrorCode
+
+  @retval  EFI_SUCCESS          Task done
+  @retval  EFI_NOT_READY        Task on processing
+  @retval  EFI_DEVICE_ERROR     Some error occured
+
+**/
+EFI_STATUS
+CheckIfDone (
+  IN  USB_OHCI_HC_DEV       *Ohc,
+  IN  DESCRIPTOR_LIST_TYPE  ListType,
+  IN  ED_DESCRIPTOR         *Ed,
+  IN  TD_DESCRIPTOR         *HeadTd,
+  OUT OHCI_ED_RESULT        *EdResult
+  );
+
+/**
+
+  Convert TD condition code to Efi Status
+
+  @Param  ConditionCode         Condition code to convert
+
+  @retval  EFI_SUCCESS          No error occured
+  @retval  EFI_NOT_READY        TD still on processing
+  @retval  EFI_DEVICE_ERROR     Error occured in processing TD
+
+**/
+
+EFI_STATUS
+OhciTDConditionCodeToStatus (
+  IN  UINT32              ConditionCode
+  );
+
+/**
+
+  Invoke callbacks hooked on done TDs
+
+  @Param  Entry                 Interrupt transfer transaction information data structure
+  @Param  Context               Ohc private data
+
+**/
+
+VOID
+OhciInvokeInterruptCallBack(
+  IN  INTERRUPT_CONTEXT_ENTRY  *Entry,
+  IN  UINT32                   Result
+);
+
+
+/**
+
+  Timer to submit periodic interrupt transfer, and invoke callbacks hooked on done TDs
+
+  @param  Event                 Event handle
+  @param  Context               Device private data
+
+**/
+
+VOID
+EFIAPI
+OhciHouseKeeper (
+  IN  EFI_EVENT           Event,
+  IN  VOID                *Context
+  );
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.c
new file mode 100644
index 0000000000..ccf4c96de4
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.c
@@ -0,0 +1,889 @@
+/** @file
+This file contains URB request, each request is warpped in a
+URB (Usb Request Block).
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+
+#include "Ohci.h"
+
+
+/**
+
+  Create a TD
+
+  @Param  Ohc                   UHC private data
+
+  @retval                       TD structure pointer
+
+**/
+TD_DESCRIPTOR *
+OhciCreateTD (
+  IN USB_OHCI_HC_DEV      *Ohc
+  )
+{
+  TD_DESCRIPTOR           *Td;
+
+  Td = UsbHcAllocateMem(Ohc->MemPool, sizeof(TD_DESCRIPTOR));
+  if (Td == NULL) {
+    DEBUG ((EFI_D_INFO, "STV allocate TD fail !\r\n"));
+    return NULL;
+  }
+  Td->CurrBufferPointer = 0;
+  Td->NextTD = 0;
+  Td->BufferEndPointer = 0;
+  Td->NextTDPointer = 0;
+
+  return Td;
+}
+
+
+/**
+
+  Free a TD
+
+  @Param  Ohc                   UHC private data
+  @Param  Td                    Pointer to a TD to free
+
+  @retval  EFI_SUCCESS          TD freed
+
+**/
+EFI_STATUS
+OhciFreeTD (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN TD_DESCRIPTOR        *Td
+  )
+{
+  if (Td == NULL) {
+    return EFI_SUCCESS;
+  }
+  UsbHcFreeMem(Ohc->MemPool, Td, sizeof(TD_DESCRIPTOR));
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+
+  Create a ED
+
+  @Param   Ohc                  Device private data
+
+  @retval  ED                   descriptor pointer
+
+**/
+ED_DESCRIPTOR *
+OhciCreateED (
+  USB_OHCI_HC_DEV          *Ohc
+  )
+{
+  ED_DESCRIPTOR   *Ed;
+  Ed = UsbHcAllocateMem(Ohc->MemPool, sizeof (ED_DESCRIPTOR));
+  if (Ed == NULL) {
+    DEBUG ((EFI_D_INFO, "STV allocate ED fail !\r\n"));
+    return NULL;
+  }
+  Ed->Word0.Skip = 1;
+  Ed->TdTailPointer = 0;
+  Ed->Word2.TdHeadPointer = 0;
+  Ed->NextED = 0;
+
+  return Ed;
+}
+
+/**
+
+  Free a ED
+
+  @Param  Ohc                   UHC private data
+  @Param  Ed                    Pointer to a ED to free
+
+  @retval  EFI_SUCCESS          ED freed
+
+**/
+
+EFI_STATUS
+OhciFreeED (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN ED_DESCRIPTOR        *Ed
+  )
+{
+  if (Ed == NULL) {
+    return EFI_SUCCESS;
+  }
+  UsbHcFreeMem(Ohc->MemPool, Ed, sizeof(ED_DESCRIPTOR));
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Free  ED
+
+  @Param  Ohc                    Device private data
+  @Param  Ed                     Pointer to a ED to free
+
+  @retval  EFI_SUCCESS           ED freed
+
+**/
+EFI_STATUS
+OhciFreeAllTDFromED (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN ED_DESCRIPTOR        *Ed
+  )
+{
+  TD_DESCRIPTOR           *HeadTd;
+  TD_DESCRIPTOR           *TailTd;
+  TD_DESCRIPTOR           *Td;
+  TD_DESCRIPTOR           *TempTd;
+
+  if (Ed == NULL) {
+    return EFI_SUCCESS;
+  }
+
+  HeadTd = TD_PTR (Ed->Word2.TdHeadPointer);
+  TailTd = (TD_DESCRIPTOR *)(UINTN)(Ed->TdTailPointer);
+
+  Td = HeadTd;
+  while (Td != TailTd) {
+    TempTd = Td;
+    Td = (TD_DESCRIPTOR *)(UINTN)(Td->NextTDPointer);
+    OhciFreeTD (Ohc, TempTd);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Find a working ED match the requirement
+
+  @Param  EdHead                Head of the ED list
+  @Param  DeviceAddress         Device address to search
+  @Param  EndPointNum           End point num to search
+  @Param  EdDir                 ED Direction to search
+
+  @retval   ED descriptor searched
+
+**/
+
+ED_DESCRIPTOR *
+OhciFindWorkingEd (
+  IN ED_DESCRIPTOR       *EdHead,
+  IN UINT8               DeviceAddress,
+  IN UINT8               EndPointNum,
+  IN UINT8               EdDir
+  )
+{
+  ED_DESCRIPTOR           *Ed;
+
+  for (Ed = EdHead; Ed != NULL; Ed = (ED_DESCRIPTOR *)(UINTN)(Ed->NextED)) {
+    if (Ed->Word2.Halted == 0 && Ed->Word0.Skip == 0 &&
+        Ed->Word0.FunctionAddress == DeviceAddress && Ed->Word0.EndPointNum == EndPointNum &&
+        Ed->Word0.Direction == EdDir) {
+      break;
+    }
+  }
+
+  return Ed;
+}
+
+
+/**
+
+  Initialize interrupt list.
+
+  @Param Ohc                    Device private data
+
+  @retval  EFI_SUCCESS          Initialization done
+
+**/
+EFI_STATUS
+OhciInitializeInterruptList (
+  USB_OHCI_HC_DEV          *Ohc
+  )
+{
+  static UINT32     Leaf[32] = {0, 16, 8, 24, 4, 20, 12, 28, 2, 18, 10, 26, 6, 22, 14, 30, 1, 17,
+                                9, 25, 5, 21, 13, 29, 3, 19, 11, 27, 7, 23, 15, 31};
+  UINT32            *HccaInterruptTable;
+  UINTN             Index;
+  UINTN             Level;
+  UINTN             Count;
+  ED_DESCRIPTOR     *NewEd;
+
+  HccaInterruptTable = Ohc->HccaMemoryBlock->HccaInterruptTable;
+
+  for (Index = 0; Index < 32; Index++) {
+    NewEd = OhciCreateED (Ohc);
+    if (NewEd == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+    HccaInterruptTable[Index] = (UINT32)(UINTN)NewEd;
+  }
+
+  for (Index = 0; Index < 32; Index++) {
+    Ohc->IntervalList[0][Index] = (ED_DESCRIPTOR *)(UINTN)HccaInterruptTable[Leaf[Index]];
+  }
+
+  Count = 32;
+  for (Level = 1; Level <= 5; Level++) {
+    Count = Count >> 1;
+
+    for (Index = 0; Index < Count; Index++) {
+      Ohc->IntervalList[Level][Index] = OhciCreateED (Ohc);
+      if (HccaInterruptTable[Index] == 0) {
+        return EFI_OUT_OF_RESOURCES;
+      }
+      Ohc->IntervalList[Level - 1][Index * 2    ]->NextED = (UINT32)(UINTN)Ohc->IntervalList[Level][Index];
+      Ohc->IntervalList[Level - 1][Index * 2 + 1]->NextED = (UINT32)(UINTN)Ohc->IntervalList[Level][Index];
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Attach an ED
+
+  @Param  Ed                    Ed to be attached
+  @Param  NewEd                 Ed to attach
+
+  @retval EFI_SUCCESS           NewEd attached to Ed
+  @retval EFI_INVALID_PARAMETER Ed is NULL
+
+**/
+EFI_STATUS
+OhciAttachED (
+  IN ED_DESCRIPTOR        *Ed,
+  IN ED_DESCRIPTOR        *NewEd
+  )
+{
+  ED_DESCRIPTOR           *Temp;
+
+  if (Ed == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Ed->NextED == 0){
+    Ed->NextED = (UINT32)(UINTN)NewEd;
+  } else {
+    Temp = (ED_DESCRIPTOR *)(UINTN)(Ed->NextED);
+    Ed->NextED = (UINT32)(UINTN)NewEd;
+    NewEd->NextED = (UINT32)(UINTN)Temp;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+
+  Count ED number on a ED chain
+
+  @Param  Ed                    Head of the ED chain
+
+  @retval                       ED number on the chain
+
+**/
+
+UINTN
+CountEdNum (
+  IN ED_DESCRIPTOR      *Ed
+  )
+{
+  UINTN     Count;
+
+  Count = 0;
+
+  while (Ed) {
+    Ed = (ED_DESCRIPTOR *)(UINTN)(Ed->NextED);
+    Count++;
+  }
+
+  return Count;
+}
+
+/**
+
+  Find the minimal burn ED list on a specific depth level
+
+  @Param  Ohc                   Device private data
+  @Param  Depth                 Depth level
+
+  @retval                       ED list found
+
+**/
+
+ED_DESCRIPTOR *
+OhciFindMinInterruptEDList (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Depth
+  )
+{
+  UINTN                   EdNum;
+  UINTN                   MinEdNum;
+  ED_DESCRIPTOR           *TempEd;
+  ED_DESCRIPTOR           *HeadEd;
+  UINTN                   Index;
+
+  if (Depth > 5) {
+    return NULL;
+  }
+
+  MinEdNum = 0xFFFFFFFF;
+  TempEd = NULL;
+  for (Index = 0; Index < (UINTN)(32 >> Depth); Index++) {
+    HeadEd = Ohc->IntervalList[Depth][Index];
+    EdNum = CountEdNum (HeadEd);
+    if (EdNum < MinEdNum) {
+      MinEdNum = EdNum;
+      TempEd = HeadEd;
+    }
+  }
+
+  ASSERT (TempEd != NULL);
+
+  return TempEd;
+}
+
+
+/**
+
+  Attach an ED to an ED list
+
+  @Param  OHC                   UHC private data
+  @Param  ListType              Type of the ED list
+  @Param  Ed                    ED to attach
+  @Param  EdList                ED list to be attached
+
+  @retval  EFI_SUCCESS          ED attached to ED list
+
+**/
+ED_DESCRIPTOR *
+OhciAttachEDToList (
+  IN USB_OHCI_HC_DEV       *Ohc,
+  IN DESCRIPTOR_LIST_TYPE  ListType,
+  IN ED_DESCRIPTOR         *Ed,
+  IN ED_DESCRIPTOR         *EdList
+  )
+{
+  ED_DESCRIPTOR            *HeadEd;
+
+  HeadEd = NULL;
+  switch(ListType) {
+    case CONTROL_LIST:
+      HeadEd = (ED_DESCRIPTOR *) OhciGetMemoryPointer (Ohc, HC_CONTROL_HEAD);
+      if (HeadEd == NULL) {
+        OhciSetMemoryPointer (Ohc, HC_CONTROL_HEAD, Ed);
+        HeadEd = Ed;
+      } else {
+        OhciAttachED (HeadEd, Ed);
+      }
+    break;
+
+    case BULK_LIST:
+      HeadEd = (ED_DESCRIPTOR *) OhciGetMemoryPointer (Ohc, HC_BULK_HEAD);
+      if (HeadEd == NULL) {
+        OhciSetMemoryPointer (Ohc, HC_BULK_HEAD, Ed);
+        HeadEd = Ed;
+      } else {
+        OhciAttachED (HeadEd, Ed);
+      }
+    break;
+
+    case INTERRUPT_LIST:
+      OhciAttachED (EdList, Ed);
+      break;
+
+    default:
+      ASSERT (FALSE);
+  }
+
+  return HeadEd;
+}
+
+/**
+
+  Remove interrupt EDs that match requirement
+
+  @Param  Ohc                   UHC private data
+  @Param  IntEd                 The address of Interrupt endpoint
+
+  @retval  EFI_SUCCESS          EDs match requirement removed
+
+**/
+
+EFI_STATUS
+OhciFreeInterruptEdByEd (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN ED_DESCRIPTOR        *IntEd
+  )
+{
+  ED_DESCRIPTOR           *Ed;
+  ED_DESCRIPTOR           *TempEd;
+  UINTN                   Index;
+
+  if (IntEd == NULL)
+    return EFI_SUCCESS;
+
+  for (Index = 0; Index < 32; Index++) {
+    Ed = (ED_DESCRIPTOR *)(UINTN)Ohc->HccaMemoryBlock->HccaInterruptTable[Index];
+    if (Ed == NULL) {
+      continue;
+    }
+    while (Ed->NextED != 0) {
+      if (Ed->NextED == (UINT32)(UINTN)IntEd ) {
+        TempEd = (ED_DESCRIPTOR *)(UINTN)(Ed->NextED);
+        Ed->NextED = TempEd->NextED;
+        OhciFreeED (Ohc, TempEd);
+      } else {
+        Ed = (ED_DESCRIPTOR *)(UINTN)(Ed->NextED);
+      }
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Remove interrupt EDs that match requirement
+
+  @Param  Ohc                   UHC private data
+  @Param  FunctionAddress       Requirement on function address
+  @Param  EndPointNum           Requirement on end point number
+
+  @retval  EFI_SUCCESS          EDs match requirement removed
+
+**/
+EFI_STATUS
+OhciFreeInterruptEdByAddr (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT8                FunctionAddress,
+  IN UINT8                EndPointNum
+  )
+{
+  ED_DESCRIPTOR           *Ed;
+  ED_DESCRIPTOR           *TempEd;
+  UINTN                   Index;
+
+  for (Index = 0; Index < 32; Index++) {
+    Ed = (ED_DESCRIPTOR *)(UINTN)Ohc->HccaMemoryBlock->HccaInterruptTable[Index];
+    if (Ed == NULL) {
+      continue;
+    }
+
+    while (Ed->NextED != 0) {
+      TempEd = (ED_DESCRIPTOR *)(UINTN)(Ed->NextED);
+      if (TempEd->Word0.FunctionAddress == FunctionAddress &&
+          TempEd->Word0.EndPointNum     == EndPointNum        ) {
+        Ed->NextED = TempEd->NextED;
+        OhciFreeED (Ohc, TempEd);
+      } else {
+        Ed = (ED_DESCRIPTOR *)(UINTN)(Ed->NextED);
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+
+  Link Td2 to the end of Td1
+
+  @Param Td1                    TD to be linked
+  @Param Td2                    TD to link
+
+  @retval EFI_SUCCESS           TD successfully linked
+  @retval EFI_INVALID_PARAMETER Td1 is NULL
+
+**/
+EFI_STATUS
+OhciLinkTD (
+  IN TD_DESCRIPTOR        *Td1,
+  IN TD_DESCRIPTOR        *Td2
+  )
+{
+  TD_DESCRIPTOR           *TempTd;
+
+  if (Td1 == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Td1 == Td2) {
+    return EFI_SUCCESS;
+  }
+
+  TempTd = Td1;
+  while (TempTd->NextTD != 0) {
+    TempTd = (TD_DESCRIPTOR *)(UINTN)(TempTd->NextTD);
+  }
+
+  TempTd->NextTD = (UINT32)(UINTN)Td2;
+  TempTd->NextTDPointer = (UINT32)(UINTN)Td2;
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+
+  Attach TD list to ED
+
+  @Param  Ed                    ED which TD list attach on
+  @Param  HeadTd                Head of the TD list to attach
+
+  @retval  EFI_SUCCESS          TD list attached on the ED
+
+**/
+EFI_STATUS
+OhciAttachTDListToED (
+  IN ED_DESCRIPTOR        *Ed,
+  IN TD_DESCRIPTOR        *HeadTd
+  )
+{
+  TD_DESCRIPTOR           *TempTd;
+
+  TempTd = TD_PTR (Ed->Word2.TdHeadPointer);
+
+  if (TempTd != NULL) {
+    while (TempTd->NextTD != 0) {
+      TempTd = (TD_DESCRIPTOR *)(UINTN)(TempTd->NextTD);
+    }
+    TempTd->NextTD = (UINT32)(UINTN)HeadTd;
+    TempTd->NextTDPointer = (UINT32)(UINTN)HeadTd;
+  } else {
+    Ed->Word2.TdHeadPointer = RIGHT_SHIFT_4 ((UINT32)(UINTN)HeadTd);
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+
+  Set value to ED specific field
+
+  @Param  Ed                    ED to be set
+  @Param  Field                 Field to be set
+  @Param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+EFI_STATUS
+OhciSetEDField (
+  IN ED_DESCRIPTOR        *Ed,
+  IN UINT32               Field,
+  IN UINT32               Value
+  )
+{
+  if (Field & ED_FUNC_ADD) {
+    Ed->Word0.FunctionAddress = Value;
+  }
+  if (Field & ED_ENDPT_NUM) {
+    Ed->Word0.EndPointNum = Value;
+  }
+  if (Field & ED_DIR) {
+    Ed->Word0.Direction = Value;
+  }
+  if (Field & ED_SPEED) {
+    Ed->Word0.Speed = Value;
+  }
+  if (Field & ED_SKIP) {
+    Ed->Word0.Skip = Value;
+  }
+  if (Field & ED_FORMAT) {
+    Ed->Word0.Format = Value;
+  }
+  if (Field & ED_MAX_PACKET) {
+    Ed->Word0.MaxPacketSize = Value;
+  }
+  if (Field & ED_PDATA) {
+    Ed->Word0.FreeSpace = Value;
+  }
+  if (Field & ED_ZERO) {
+    Ed->Word2.Zero = Value;
+  }
+  if (Field & ED_TDTAIL_PTR) {
+    Ed->TdTailPointer = Value;
+  }
+
+  if (Field & ED_HALTED) {
+    Ed->Word2.Halted = Value;
+  }
+  if (Field & ED_DTTOGGLE) {
+    Ed->Word2.ToggleCarry = Value;
+  }
+  if (Field & ED_TDHEAD_PTR) {
+    Ed->Word2.TdHeadPointer = RIGHT_SHIFT_4 (Value);
+  }
+
+  if (Field & ED_NEXT_EDPTR) {
+    Ed->NextED = Value;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Get value from an ED's specific field
+
+  @Param  Ed                    ED pointer
+  @Param  Field                 Field to get value from
+
+  @retval                       Value of the field
+
+**/
+UINT32
+OhciGetEDField (
+  IN ED_DESCRIPTOR        *Ed,
+  IN UINT32               Field
+  )
+{
+  switch (Field) {
+    case ED_FUNC_ADD:
+      return Ed->Word0.FunctionAddress;
+      break;
+    case ED_ENDPT_NUM:
+      return Ed->Word0.EndPointNum;
+      break;
+    case ED_DIR:
+      return Ed->Word0.Direction;
+      break;
+    case ED_SPEED:
+      return Ed->Word0.Speed;
+      break;
+    case ED_SKIP:
+      return Ed->Word0.Skip;
+      break;
+    case ED_FORMAT:
+      return Ed->Word0.Format;
+      break;
+    case ED_MAX_PACKET:
+      return Ed->Word0.MaxPacketSize;
+      break;
+
+    case ED_TDTAIL_PTR:
+      return Ed->TdTailPointer;
+      break;
+
+    case ED_HALTED:
+      return Ed->Word2.Halted;
+      break;
+
+    case ED_DTTOGGLE:
+      return Ed->Word2.ToggleCarry;
+      break;
+
+    case ED_TDHEAD_PTR:
+      return Ed->Word2.TdHeadPointer << 4;
+      break;
+
+    case ED_NEXT_EDPTR:
+      return Ed->NextED;
+      break;
+
+    default:
+      ASSERT (FALSE);
+  }
+
+  return 0;
+}
+
+
+/**
+
+  Set value to TD specific field
+
+  @Param  Td                    TD to be set
+  @Param  Field                 Field to be set
+  @Param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+EFI_STATUS
+OhciSetTDField (
+  IN TD_DESCRIPTOR        *Td,
+  IN UINT32               Field,
+  IN UINT32               Value
+  )
+{
+  if (Field & TD_PDATA) {
+    Td->Word0.Reserved = Value;
+  }
+  if (Field & TD_BUFFER_ROUND) {
+    Td->Word0.BufferRounding = Value;
+  }
+  if (Field & TD_DIR_PID) {
+    Td->Word0.DirPID = Value;
+  }
+  if (Field & TD_DELAY_INT) {
+    Td->Word0.DelayInterrupt = Value;
+  }
+  if (Field & TD_DT_TOGGLE) {
+    Td->Word0.DataToggle = Value | 0x2;
+  }
+  if (Field & TD_ERROR_CNT) {
+    Td->Word0.ErrorCount = Value;
+  }
+  if (Field & TD_COND_CODE) {
+    Td->Word0.ConditionCode = Value;
+  }
+
+  if (Field & TD_CURR_BUFFER_PTR) {
+    Td->CurrBufferPointer = Value;
+  }
+
+
+  if (Field & TD_NEXT_PTR) {
+    Td->NextTD = Value;
+  }
+
+  if (Field & TD_BUFFER_END_PTR) {
+    Td->BufferEndPointer = Value;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+
+  Get value from ED specific field
+
+  @Param  Td                    TD pointer
+  @Param  Field                 Field to get value from
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetTDField (
+  IN TD_DESCRIPTOR      *Td,
+  IN UINT32             Field
+  )
+{
+  switch (Field){
+    case TD_BUFFER_ROUND:
+      return Td->Word0.BufferRounding;
+      break;
+    case TD_DIR_PID:
+      return Td->Word0.DirPID;
+      break;
+    case TD_DELAY_INT:
+      return Td->Word0.DelayInterrupt;
+      break;
+    case TD_DT_TOGGLE:
+      return Td->Word0.DataToggle;
+      break;
+    case TD_ERROR_CNT:
+      return Td->Word0.ErrorCount;
+      break;
+    case TD_COND_CODE:
+      return Td->Word0.ConditionCode;
+      break;
+    case TD_CURR_BUFFER_PTR:
+      return Td->CurrBufferPointer;
+      break;
+
+    case TD_NEXT_PTR:
+      return Td->NextTD;
+      break;
+
+    case TD_BUFFER_END_PTR:
+      return Td->BufferEndPointer;
+      break;
+
+    default:
+      ASSERT (FALSE);
+  }
+
+  return 0;
+}
+
+/**
+
+  Free the Ed,Td,buffer that were created during transferring
+
+  @Param  Ohc                   Device private data
+**/
+
+VOID
+OhciFreeDynamicIntMemory(
+  IN USB_OHCI_HC_DEV      *Ohc
+  )
+{
+  INTERRUPT_CONTEXT_ENTRY *Entry;
+  if (Ohc != NULL) {
+    while (Ohc->InterruptContextList != NULL) {
+      Entry = Ohc->InterruptContextList;
+      Ohc->InterruptContextList = Ohc->InterruptContextList->NextEntry;
+      OhciFreeInterruptEdByEd (Ohc, Entry->Ed);
+      OhciFreeInterruptContextEntry (Ohc, Entry);
+    }
+  }
+}
+/**
+
+  Free the Ed that were initilized during driver was starting,
+  those memory were used as interrupt ED head
+
+  @Param  Ohc                   Device private data
+
+
+**/
+VOID
+OhciFreeFixedIntMemory (
+  IN USB_OHCI_HC_DEV      *Ohc
+  )
+{
+  static UINT32           Leaf[] = {32,16,8,4,2,1};
+  UINTN                   Index;
+  UINTN                   Level;
+
+  for (Level = 0; Level < 6; Level++) {
+    for (Index = 0; Index < Leaf[Level]; Index++) {
+      if (Ohc->IntervalList[Level][Index] != NULL) {
+        UsbHcFreeMem(Ohc->MemPool, Ohc->IntervalList[Level][Index], sizeof(ED_DESCRIPTOR));
+      }
+    }
+  }
+}
+/**
+
+  Release all OHCI used memory when OHCI going to quit
+
+  @Param  Ohc                   Device private data
+
+  @retval EFI_SUCCESS          Memory released
+
+**/
+
+EFI_STATUS
+OhciFreeIntTransferMemory (
+  IN USB_OHCI_HC_DEV           *Ohc
+  )
+{
+  //
+  // Free the Ed,Td,buffer that were created during transferring
+  //
+  OhciFreeDynamicIntMemory (Ohc);
+  //
+  // Free the Ed that were initilized during driver was starting
+  //
+  OhciFreeFixedIntMemory (Ohc);
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.h
new file mode 100644
index 0000000000..6bf2fe7e54
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.h
@@ -0,0 +1,387 @@
+/** @file
+Provides some data struct used by OHCI controller driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#ifndef _OHCI_URB_H
+#define _OHCI_URB_H
+
+#include "Descriptor.h"
+
+
+//
+// Func List
+//
+
+
+/**
+
+  Create a TD
+
+  @Param  Ohc                   UHC private data
+
+  @retval                       TD structure pointer
+
+**/
+TD_DESCRIPTOR *
+OhciCreateTD (
+  IN USB_OHCI_HC_DEV      *Ohc
+  );
+
+/**
+
+  Free a TD
+
+  @Param  Ohc                   UHC private data
+  @Param  Td                    Pointer to a TD to free
+
+  @retval  EFI_SUCCESS          TD freed
+
+**/
+EFI_STATUS
+OhciFreeTD (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN TD_DESCRIPTOR        *Td
+  );
+
+/**
+
+  Create a ED
+
+  @Param   Ohc                  Device private data
+
+  @retval  ED                   descriptor pointer
+
+**/
+ED_DESCRIPTOR *
+OhciCreateED (
+  USB_OHCI_HC_DEV          *Ohc
+  );
+
+
+/**
+
+  Free a ED
+
+  @Param  Ohc                   UHC private data
+  @Param  Ed                    Pointer to a ED to free
+
+  @retval  EFI_SUCCESS          ED freed
+
+**/
+
+EFI_STATUS
+OhciFreeED (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN ED_DESCRIPTOR        *Ed
+  );
+
+/**
+
+  Free  ED
+
+  @Param  Ohc                    Device private data
+  @Param  Ed                     Pointer to a ED to free
+
+  @retval  EFI_SUCCESS           ED freed
+
+**/
+EFI_STATUS
+OhciFreeAllTDFromED (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN ED_DESCRIPTOR        *Ed
+  );
+
+/**
+
+  Find a working ED match the requirement
+
+  @Param  EdHead                Head of the ED list
+  @Param  DeviceAddress         Device address to search
+  @Param  EndPointNum           End point num to search
+  @Param  EdDir                 ED Direction to search
+
+  @retval   ED descriptor searched
+
+**/
+
+ED_DESCRIPTOR *
+OhciFindWorkingEd (
+  IN ED_DESCRIPTOR       *EdHead,
+  IN UINT8               DeviceAddress,
+  IN UINT8               EndPointNum,
+  IN UINT8               EdDir
+  );
+
+
+/**
+
+  Initialize interrupt list.
+
+  @Param Ohc                    Device private data
+
+  @retval  EFI_SUCCESS          Initialization done
+
+**/
+EFI_STATUS
+OhciInitializeInterruptList (
+  USB_OHCI_HC_DEV          *Ohc
+  );
+
+/**
+
+  Attach an ED
+
+  @Param  Ed                    Ed to be attached
+  @Param  NewEd                 Ed to attach
+
+  @retval EFI_SUCCESS           NewEd attached to Ed
+  @retval EFI_INVALID_PARAMETER Ed is NULL
+
+**/
+EFI_STATUS
+OhciAttachED (
+  IN ED_DESCRIPTOR        *Ed,
+  IN ED_DESCRIPTOR        *NewEd
+  );
+
+/**
+
+  Count ED number on a ED chain
+
+  @Param  Ed                    Head of the ED chain
+
+  @retval                       ED number on the chain
+
+**/
+
+UINTN
+CountEdNum (
+  IN ED_DESCRIPTOR      *Ed
+  );
+
+/**
+
+  Find the minimal burn ED list on a specific depth level
+
+  @Param  Ohc                   Device private data
+  @Param  Depth                 Depth level
+
+  @retval                       ED list found
+
+**/
+
+ED_DESCRIPTOR *
+OhciFindMinInterruptEDList (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Depth
+  );
+
+/**
+
+  Attach an ED to an ED list
+
+  @Param  OHC                   UHC private data
+  @Param  ListType              Type of the ED list
+  @Param  Ed                    ED to attach
+  @Param  EdList                ED list to be attached
+
+  @retval  EFI_SUCCESS          ED attached to ED list
+
+**/
+ED_DESCRIPTOR *
+OhciAttachEDToList (
+  IN USB_OHCI_HC_DEV       *Ohc,
+  IN DESCRIPTOR_LIST_TYPE  ListType,
+  IN ED_DESCRIPTOR         *Ed,
+  IN ED_DESCRIPTOR         *EdList
+  );
+
+/**
+
+  Remove interrupt EDs that match requirement
+
+  @Param  Ohc                   UHC private data
+  @Param  IntEd                 The address of Interrupt endpoint
+
+  @retval  EFI_SUCCESS          EDs match requirement removed
+
+**/
+
+EFI_STATUS
+OhciFreeInterruptEdByEd (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN ED_DESCRIPTOR        *IntEd
+  );
+
+/**
+
+  Remove interrupt EDs that match requirement
+
+  @Param  Ohc                   UHC private data
+  @Param  FunctionAddress       Requirement on function address
+  @Param  EndPointNum           Requirement on end point number
+
+  @retval  EFI_SUCCESS          EDs match requirement removed
+
+**/
+EFI_STATUS
+OhciFreeInterruptEdByAddr (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT8                FunctionAddress,
+  IN UINT8                EndPointNum
+  );
+
+
+/**
+
+  Link Td2 to the end of Td1
+
+  @Param Td1                    TD to be linked
+  @Param Td2                    TD to link
+
+  @retval EFI_SUCCESS           TD successfully linked
+  @retval EFI_INVALID_PARAMETER Td1 is NULL
+
+**/
+EFI_STATUS
+OhciLinkTD (
+  IN TD_DESCRIPTOR        *Td1,
+  IN TD_DESCRIPTOR        *Td2
+  );
+
+
+/**
+
+  Attach TD list to ED
+
+  @Param  Ed                    ED which TD list attach on
+  @Param  HeadTd                Head of the TD list to attach
+
+  @retval  EFI_SUCCESS          TD list attached on the ED
+
+**/
+EFI_STATUS
+OhciAttachTDListToED (
+  IN ED_DESCRIPTOR        *Ed,
+  IN TD_DESCRIPTOR        *HeadTd
+  );
+
+
+/**
+
+  Set value to ED specific field
+
+  @Param  Ed                    ED to be set
+  @Param  Field                 Field to be set
+  @Param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+EFI_STATUS
+OhciSetEDField (
+  IN ED_DESCRIPTOR        *Ed,
+  IN UINT32               Field,
+  IN UINT32               Value
+  );
+
+
+/**
+
+  Get value from an ED's specific field
+
+  @Param  Ed                    ED pointer
+  @Param  Field                 Field to get value from
+
+  @retval                       Value of the field
+
+**/
+UINT32
+OhciGetEDField (
+  IN ED_DESCRIPTOR        *Ed,
+  IN UINT32               Field
+  );
+
+
+/**
+
+  Set value to TD specific field
+
+  @Param  Td                    TD to be set
+  @Param  Field                 Field to be set
+  @Param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+EFI_STATUS
+OhciSetTDField (
+  IN TD_DESCRIPTOR        *Td,
+  IN UINT32               Field,
+  IN UINT32               Value
+  );
+
+
+/**
+
+  Get value from ED specific field
+
+  @Param  Td                    TD pointer
+  @Param  Field                 Field to get value from
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetTDField (
+  IN TD_DESCRIPTOR      *Td,
+  IN UINT32             Field
+  );
+/**
+
+  Free the Ed,Td,buffer that were created during transferring
+
+  @Param  Ohc                   Device private data
+**/
+
+VOID
+OhciFreeDynamicIntMemory(
+  IN USB_OHCI_HC_DEV      *Ohc
+  );
+
+/**
+
+  Free the Ed that were initilized during driver was starting,
+  those memory were used as interrupt ED head
+
+  @Param  Ohc                   Device private data
+
+
+**/
+VOID
+OhciFreeFixedIntMemory (
+  IN USB_OHCI_HC_DEV      *Ohc
+  );
+/**
+
+  Release all OHCI used memory when OHCI going to quit
+
+  @Param  Ohc                   Device private data
+
+  @retval EFI_SUCCESS          Memory released
+
+**/
+
+EFI_STATUS
+OhciFreeIntTransferMemory (
+  IN USB_OHCI_HC_DEV           *Ohc
+  );
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.c
new file mode 100644
index 0000000000..e2709a25d4
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.c
@@ -0,0 +1,560 @@
+/** @file
+Routine procedures for memory allocate/free.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "Ohci.h"
+
+
+/**
+  Allocate a block of memory to be used by the buffer pool.
+
+  @param  Pool           The buffer pool to allocate memory for.
+  @param  Pages          How many pages to allocate.
+
+  @return The allocated memory block or NULL if failed.
+
+**/
+USBHC_MEM_BLOCK *
+UsbHcAllocMemBlock (
+  IN  USBHC_MEM_POOL      *Pool,
+  IN  UINTN               Pages
+  )
+{
+  USBHC_MEM_BLOCK         *Block;
+  EFI_PCI_IO_PROTOCOL     *PciIo;
+  VOID                    *BufHost;
+  VOID                    *Mapping;
+  EFI_PHYSICAL_ADDRESS    MappedAddr;
+  UINTN                   Bytes;
+  EFI_STATUS              Status;
+
+  PciIo = Pool->PciIo;
+
+  Block = AllocateZeroPool (sizeof (USBHC_MEM_BLOCK));
+  if (Block == NULL) {
+    return NULL;
+  }
+
+  //
+  // each bit in the bit array represents USBHC_MEM_UNIT
+  // bytes of memory in the memory block.
+  //
+  ASSERT (USBHC_MEM_UNIT * 8 <= EFI_PAGE_SIZE);
+
+  Block->BufLen   = EFI_PAGES_TO_SIZE (Pages);
+  Block->BitsLen  = Block->BufLen / (USBHC_MEM_UNIT * 8);
+  Block->Bits     = AllocateZeroPool (Block->BitsLen);
+
+  if (Block->Bits == NULL) {
+    gBS->FreePool (Block);
+    return NULL;
+  }
+
+  //
+  // Allocate the number of Pages of memory, then map it for
+  // bus master read and write.
+  //
+  Status = PciIo->AllocateBuffer (
+                    PciIo,
+                    AllocateAnyPages,
+                    EfiBootServicesData,
+                    Pages,
+                    &BufHost,
+                    0
+                    );
+
+  if (EFI_ERROR (Status)) {
+    goto FREE_BITARRAY;
+  }
+
+  Bytes = EFI_PAGES_TO_SIZE (Pages);
+  Status = PciIo->Map (
+                    PciIo,
+                    EfiPciIoOperationBusMasterCommonBuffer,
+                    BufHost,
+                    &Bytes,
+                    &MappedAddr,
+                    &Mapping
+                    );
+
+  if (EFI_ERROR (Status) || (Bytes != EFI_PAGES_TO_SIZE (Pages))) {
+    goto FREE_BUFFER;
+  }
+
+  //
+  // Check whether the data structure used by the host controller
+  // should be restricted into the same 4G
+  //
+  if (Pool->Check4G && (Pool->Which4G != USB_HC_HIGH_32BIT (MappedAddr))) {
+    PciIo->Unmap (PciIo, Mapping);
+    goto FREE_BUFFER;
+  }
+
+  Block->BufHost  = BufHost;
+  Block->Buf      = (UINT8 *) ((UINTN) MappedAddr);
+  Block->Mapping  = Mapping;
+
+  return Block;
+
+FREE_BUFFER:
+  PciIo->FreeBuffer (PciIo, Pages, BufHost);
+
+FREE_BITARRAY:
+  gBS->FreePool (Block->Bits);
+  gBS->FreePool (Block);
+  return NULL;
+}
+
+
+/**
+  Free the memory block from the memory pool.
+
+  @param  Pool           The memory pool to free the block from.
+  @param  Block          The memory block to free.
+
+**/
+VOID
+UsbHcFreeMemBlock (
+  IN USBHC_MEM_POOL       *Pool,
+  IN USBHC_MEM_BLOCK      *Block
+  )
+{
+  EFI_PCI_IO_PROTOCOL     *PciIo;
+
+  ASSERT ((Pool != NULL) && (Block != NULL));
+
+  PciIo = Pool->PciIo;
+
+  //
+  // Unmap the common buffer then free the structures
+  //
+  PciIo->Unmap (PciIo, Block->Mapping);
+  PciIo->FreeBuffer (PciIo, EFI_SIZE_TO_PAGES (Block->BufLen), Block->BufHost);
+
+  gBS->FreePool (Block->Bits);
+  gBS->FreePool (Block);
+}
+
+
+/**
+  Alloc some memory from the block.
+
+  @param  Block          The memory block to allocate memory from.
+  @param  Units          Number of memory units to allocate.
+
+  @return The pointer to the allocated memory. If couldn't allocate the needed memory,
+          the return value is NULL.
+
+**/
+VOID *
+UsbHcAllocMemFromBlock (
+  IN  USBHC_MEM_BLOCK     *Block,
+  IN  UINTN               Units
+  )
+{
+  UINTN                   Byte;
+  UINT8                   Bit;
+  UINTN                   StartByte;
+  UINT8                   StartBit;
+  UINTN                   Available;
+  UINTN                   Count;
+
+  ASSERT ((Block != 0) && (Units != 0));
+
+  StartByte  = 0;
+  StartBit   = 0;
+  Available  = 0;
+
+  for (Byte = 0, Bit = 0; Byte < Block->BitsLen;) {
+    //
+    // If current bit is zero, the corresponding memory unit is
+    // available, otherwise we need to restart our searching.
+    // Available counts the consective number of zero bit.
+    //
+    if (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)) {
+      Available++;
+
+      if (Available >= Units) {
+        break;
+      }
+
+      NEXT_BIT (Byte, Bit);
+
+    } else {
+      NEXT_BIT (Byte, Bit);
+
+      Available  = 0;
+      StartByte  = Byte;
+      StartBit   = Bit;
+    }
+  }
+
+  if (Available < Units) {
+    return NULL;
+  }
+
+  //
+  // Mark the memory as allocated
+  //
+  Byte  = StartByte;
+  Bit   = StartBit;
+
+  for (Count = 0; Count < Units; Count++) {
+    ASSERT (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit));
+
+    Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] | USB_HC_BIT (Bit));
+    NEXT_BIT (Byte, Bit);
+  }
+
+  return Block->BufHost + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT;
+}
+
+/**
+  Calculate the corresponding pci bus address according to the Mem parameter.
+
+  @param  Pool           The memory pool of the host controller.
+  @param  Mem            The pointer to host memory.
+  @param  Size           The size of the memory region.
+
+  @return the pci memory address
+**/
+EFI_PHYSICAL_ADDRESS
+UsbHcGetPciAddressForHostMem (
+  IN USBHC_MEM_POOL       *Pool,
+  IN VOID                 *Mem,
+  IN UINTN                Size
+  )
+{
+  USBHC_MEM_BLOCK         *Head;
+  USBHC_MEM_BLOCK         *Block;
+  UINTN                   AllocSize;
+  EFI_PHYSICAL_ADDRESS    PhyAddr;
+  UINTN                   Offset;
+
+  Head      = Pool->Head;
+  AllocSize = USBHC_MEM_ROUND (Size);
+
+  if (Mem == NULL) {
+    return 0;
+  }
+
+  for (Block = Head; Block != NULL; Block = Block->Next) {
+    //
+    // scan the memory block list for the memory block that
+    // completely contains the allocated memory.
+    //
+    if ((Block->BufHost <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= (Block->BufHost + Block->BufLen))) {
+      break;
+    }
+  }
+
+  ASSERT ((Block != NULL));
+  //
+  // calculate the pci memory address for host memory address.
+  //
+  Offset = (UINT8 *)Mem - Block->BufHost;
+  PhyAddr = (EFI_PHYSICAL_ADDRESS)(UINTN) (Block->Buf + Offset);
+  return PhyAddr;
+}
+
+
+/**
+  Insert the memory block to the pool's list of the blocks.
+
+  @param  Head           The head of the memory pool's block list.
+  @param  Block          The memory block to insert.
+
+**/
+VOID
+UsbHcInsertMemBlockToPool (
+  IN USBHC_MEM_BLOCK      *Head,
+  IN USBHC_MEM_BLOCK      *Block
+  )
+{
+  ASSERT ((Head != NULL) && (Block != NULL));
+  Block->Next = Head->Next;
+  Head->Next  = Block;
+}
+
+
+/**
+  Is the memory block empty?
+
+  @param  Block   The memory block to check.
+
+  @retval TRUE    The memory block is empty.
+  @retval FALSE   The memory block isn't empty.
+
+**/
+BOOLEAN
+UsbHcIsMemBlockEmpty (
+  IN USBHC_MEM_BLOCK     *Block
+  )
+{
+  UINTN                   Index;
+
+  for (Index = 0; Index < Block->BitsLen; Index++) {
+    if (Block->Bits[Index] != 0) {
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
+
+/**
+  Unlink the memory block from the pool's list.
+
+  @param  Head           The block list head of the memory's pool.
+  @param  BlockToUnlink  The memory block to unlink.
+
+**/
+VOID
+UsbHcUnlinkMemBlock (
+  IN USBHC_MEM_BLOCK      *Head,
+  IN USBHC_MEM_BLOCK      *BlockToUnlink
+  )
+{
+  USBHC_MEM_BLOCK         *Block;
+
+  ASSERT ((Head != NULL) && (BlockToUnlink != NULL));
+
+  for (Block = Head; Block != NULL; Block = Block->Next) {
+    if (Block->Next == BlockToUnlink) {
+      Block->Next         = BlockToUnlink->Next;
+      BlockToUnlink->Next = NULL;
+      break;
+    }
+  }
+}
+
+
+/**
+  Initialize the memory management pool for the host controller.
+
+  @param  PciIo                The PciIo that can be used to access the host controller.
+  @param  Check4G              Whether the host controller requires allocated memory
+                               from one 4G address space.
+  @param  Which4G              The 4G memory area each memory allocated should be from.
+
+  @retval EFI_SUCCESS          The memory pool is initialized.
+  @retval EFI_OUT_OF_RESOURCE  Fail to init the memory pool.
+
+**/
+USBHC_MEM_POOL *
+UsbHcInitMemPool (
+  IN EFI_PCI_IO_PROTOCOL  *PciIo,
+  IN BOOLEAN              Check4G,
+  IN UINT32               Which4G
+  )
+{
+  USBHC_MEM_POOL          *Pool;
+
+  Pool = AllocatePool (sizeof (USBHC_MEM_POOL));
+
+  if (Pool == NULL) {
+    return Pool;
+  }
+
+  Pool->PciIo   = PciIo;
+  Pool->Check4G = Check4G;
+  Pool->Which4G = Which4G;
+  Pool->Head    = UsbHcAllocMemBlock (Pool, USBHC_MEM_DEFAULT_PAGES);
+
+  if (Pool->Head == NULL) {
+    gBS->FreePool (Pool);
+    Pool = NULL;
+  }
+
+  return Pool;
+}
+
+
+/**
+  Release the memory management pool.
+
+  @param  Pool              The USB memory pool to free.
+
+  @retval EFI_SUCCESS       The memory pool is freed.
+  @retval EFI_DEVICE_ERROR  Failed to free the memory pool.
+
+**/
+EFI_STATUS
+UsbHcFreeMemPool (
+  IN USBHC_MEM_POOL       *Pool
+  )
+{
+  USBHC_MEM_BLOCK *Block;
+
+  ASSERT (Pool->Head != NULL);
+
+  //
+  // Unlink all the memory blocks from the pool, then free them.
+  // UsbHcUnlinkMemBlock can't be used to unlink and free the
+  // first block.
+  //
+  for (Block = Pool->Head->Next; Block != NULL; Block = Pool->Head->Next) {
+    UsbHcUnlinkMemBlock (Pool->Head, Block);
+    UsbHcFreeMemBlock (Pool, Block);
+  }
+
+  UsbHcFreeMemBlock (Pool, Pool->Head);
+  gBS->FreePool (Pool);
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Allocate some memory from the host controller's memory pool
+  which can be used to communicate with host controller.
+
+  @param  Pool           The host controller's memory pool.
+  @param  Size           Size of the memory to allocate.
+
+  @return The allocated memory or NULL.
+
+**/
+VOID *
+UsbHcAllocateMem (
+  IN  USBHC_MEM_POOL      *Pool,
+  IN  UINTN               Size
+  )
+{
+  USBHC_MEM_BLOCK         *Head;
+  USBHC_MEM_BLOCK         *Block;
+  USBHC_MEM_BLOCK         *NewBlock;
+  VOID                    *Mem;
+  UINTN                   AllocSize;
+  UINTN                   Pages;
+
+  Mem       = NULL;
+  AllocSize = USBHC_MEM_ROUND (Size);
+  Head      = Pool->Head;
+  ASSERT (Head != NULL);
+
+  //
+  // First check whether current memory blocks can satisfy the allocation.
+  //
+  for (Block = Head; Block != NULL; Block = Block->Next) {
+    Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT);
+
+    if (Mem != NULL) {
+      ZeroMem (Mem, Size);
+      break;
+    }
+  }
+
+  if (Mem != NULL) {
+    return Mem;
+  }
+
+  //
+  // Create a new memory block if there is not enough memory
+  // in the pool. If the allocation size is larger than the
+  // default page number, just allocate a large enough memory
+  // block. Otherwise allocate default pages.
+  //
+  if (AllocSize > EFI_PAGES_TO_SIZE (USBHC_MEM_DEFAULT_PAGES)) {
+    Pages = EFI_SIZE_TO_PAGES (AllocSize) + 1;
+  } else {
+    Pages = USBHC_MEM_DEFAULT_PAGES;
+  }
+
+  NewBlock = UsbHcAllocMemBlock (Pool, Pages);
+
+  if (NewBlock == NULL) {
+    DEBUG ((EFI_D_INFO, "UsbHcAllocateMem: failed to allocate block\n"));
+    return NULL;
+  }
+
+  //
+  // Add the new memory block to the pool, then allocate memory from it
+  //
+  UsbHcInsertMemBlockToPool (Head, NewBlock);
+  Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT);
+
+  if (Mem != NULL) {
+    ZeroMem (Mem, Size);
+  }
+
+  return Mem;
+}
+
+
+/**
+  Free the allocated memory back to the memory pool.
+
+  @param  Pool           The memory pool of the host controller.
+  @param  Mem            The memory to free.
+  @param  Size           The size of the memory to free.
+
+**/
+VOID
+UsbHcFreeMem (
+  IN USBHC_MEM_POOL       *Pool,
+  IN VOID                 *Mem,
+  IN UINTN                Size
+  )
+{
+  USBHC_MEM_BLOCK         *Head;
+  USBHC_MEM_BLOCK         *Block;
+  UINT8                   *ToFree;
+  UINTN                   AllocSize;
+  UINTN                   Byte;
+  UINTN                   Bit;
+  UINTN                   Count;
+
+  Head      = Pool->Head;
+  AllocSize = USBHC_MEM_ROUND (Size);
+  ToFree    = (UINT8 *) Mem;
+
+  for (Block = Head; Block != NULL; Block = Block->Next) {
+    //
+    // scan the memory block list for the memory block that
+    // completely contains the memory to free.
+    //
+    if ((Block->BufHost <= ToFree) && ((ToFree + AllocSize) <= (Block->BufHost + Block->BufLen))) {
+      //
+      // compute the start byte and bit in the bit array
+      //
+      Byte  = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) / 8;
+      Bit   = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) % 8;
+
+      //
+      // reset associated bits in bit arry
+      //
+      for (Count = 0; Count < (AllocSize / USBHC_MEM_UNIT); Count++) {
+        ASSERT (USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit));
+
+        Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] ^ USB_HC_BIT (Bit));
+        NEXT_BIT (Byte, Bit);
+      }
+
+      break;
+    }
+  }
+
+  //
+  // If Block == NULL, it means that the current memory isn't
+  // in the host controller's pool. This is critical because
+  // the caller has passed in a wrong memory point
+  //
+  ASSERT (Block != NULL);
+
+  //
+  // Release the current memory block if it is empty and not the head
+  //
+  if ((Block != Head) && UsbHcIsMemBlockEmpty (Block)) {
+    UsbHcUnlinkMemBlock (Head, Block);
+    UsbHcFreeMemBlock (Pool, Block);
+  }
+
+  return ;
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.h
new file mode 100644
index 0000000000..e2973bfe49
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.h
@@ -0,0 +1,152 @@
+/** @file
+This file contains the definination for host controller memory
+management routines.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _USB_HC_MEM_H_
+#define _USB_HC_MEM_H_
+
+#define USB_HC_BIT(a)                  ((UINTN)(1 << (a)))
+
+#define USB_HC_BIT_IS_SET(Data, Bit)   \
+          ((BOOLEAN)(((Data) & USB_HC_BIT(Bit)) == USB_HC_BIT(Bit)))
+
+#define USB_HC_HIGH_32BIT(Addr64)    \
+          ((UINT32)(RShiftU64((UINTN)(Addr64), 32) & 0XFFFFFFFF))
+
+typedef struct _USBHC_MEM_BLOCK USBHC_MEM_BLOCK;
+struct _USBHC_MEM_BLOCK {
+  UINT8                   *Bits;    // Bit array to record which unit is allocated
+  UINTN                   BitsLen;
+  UINT8                   *Buf;
+  UINT8                   *BufHost;
+  UINTN                   BufLen;   // Memory size in bytes
+  VOID                    *Mapping;
+  USBHC_MEM_BLOCK         *Next;
+};
+
+//
+// USBHC_MEM_POOL is used to manage the memory used by USB
+// host controller. EHCI requires the control memory and transfer
+// data to be on the same 4G memory.
+//
+typedef struct _USBHC_MEM_POOL {
+  EFI_PCI_IO_PROTOCOL     *PciIo;
+  BOOLEAN                 Check4G;
+  UINT32                  Which4G;
+  USBHC_MEM_BLOCK         *Head;
+} USBHC_MEM_POOL;
+
+//
+// Memory allocation unit, must be 2^n, n>4
+//
+#define USBHC_MEM_UNIT           64
+
+#define USBHC_MEM_UNIT_MASK      (USBHC_MEM_UNIT - 1)
+#define USBHC_MEM_DEFAULT_PAGES  16
+
+#define USBHC_MEM_ROUND(Len)  (((Len) + USBHC_MEM_UNIT_MASK) & (~USBHC_MEM_UNIT_MASK))
+
+//
+// Advance the byte and bit to the next bit, adjust byte accordingly.
+//
+#define NEXT_BIT(Byte, Bit)   \
+          do {                \
+            (Bit)++;          \
+            if ((Bit) > 7) {  \
+              (Byte)++;       \
+              (Bit) = 0;      \
+            }                 \
+          } while (0)
+
+
+
+/**
+  Initialize the memory management pool for the host controller.
+
+  @param  PciIo               The PciIo that can be used to access the host controller.
+  @param  Check4G             Whether the host controller requires allocated memory
+                              from one 4G address space.
+  @param  Which4G             The 4G memory area each memory allocated should be from.
+
+  @retval EFI_SUCCESS         The memory pool is initialized.
+  @retval EFI_OUT_OF_RESOURCE Fail to init the memory pool.
+
+**/
+USBHC_MEM_POOL *
+UsbHcInitMemPool (
+  IN EFI_PCI_IO_PROTOCOL  *PciIo,
+  IN BOOLEAN              Check4G,
+  IN UINT32               Which4G
+  );
+
+
+/**
+  Release the memory management pool.
+
+  @param   Pool               The USB memory pool to free.
+
+  @retval EFI_SUCCESS       The memory pool is freed.
+  @retval EFI_DEVICE_ERROR  Failed to free the memory pool.
+
+**/
+EFI_STATUS
+UsbHcFreeMemPool (
+  IN USBHC_MEM_POOL       *Pool
+  );
+
+
+/**
+  Allocate some memory from the host controller's memory pool
+  which can be used to communicate with host controller.
+
+  @param  Pool  The host controller's memory pool.
+  @param  Size  Size of the memory to allocate.
+
+  @return The allocated memory or NULL.
+
+**/
+VOID *
+UsbHcAllocateMem (
+  IN  USBHC_MEM_POOL      *Pool,
+  IN  UINTN               Size
+  );
+
+
+/**
+  Free the allocated memory back to the memory pool.
+
+  @param  Pool  The memory pool of the host controller.
+  @param  Mem   The memory to free.
+  @param  Size  The size of the memory to free.
+
+**/
+VOID
+UsbHcFreeMem (
+  IN USBHC_MEM_POOL       *Pool,
+  IN VOID                 *Mem,
+  IN UINTN                Size
+  );
+
+/**
+  Calculate the corresponding pci bus address according to the Mem parameter.
+
+  @param  Pool           The memory pool of the host controller.
+  @param  Mem            The pointer to host memory.
+  @param  Size           The size of the memory region.
+
+  @return the pci memory address
+**/
+EFI_PHYSICAL_ADDRESS
+UsbHcGetPciAddressForHostMem (
+  IN USBHC_MEM_POOL       *Pool,
+  IN VOID                 *Mem,
+  IN UINTN                Size
+  );
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/Descriptor.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/Descriptor.h
new file mode 100644
index 0000000000..4ec60a07a7
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/Descriptor.h
@@ -0,0 +1,131 @@
+/** @file
+This file contains the descriptor definination of OHCI spec
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+
+#ifndef _DESCRIPTOR_H
+#define _DESCRIPTOR_H
+
+#define ED_FUNC_ADD     0x0001
+#define ED_ENDPT_NUM    0x0002
+#define ED_DIR          0x0004
+#define ED_SPEED        0x0008
+#define ED_SKIP         0x0010
+#define ED_FORMAT       0x0020
+#define ED_MAX_PACKET   0x0040
+#define ED_TDTAIL_PTR   0x0080
+#define ED_HALTED       0x0100
+#define ED_DTTOGGLE     0x0200
+#define ED_TDHEAD_PTR   0x0400
+#define ED_NEXT_EDPTR   0x0800
+#define ED_PDATA        0x1000
+#define ED_ZERO         0x2000
+
+#define TD_BUFFER_ROUND     0x0001
+#define TD_DIR_PID          0x0002
+#define TD_DELAY_INT        0x0004
+#define TD_DT_TOGGLE        0x0008
+#define TD_ERROR_CNT        0x0010
+#define TD_COND_CODE        0x0020
+#define TD_CURR_BUFFER_PTR  0x0040
+#define TD_NEXT_PTR         0x0080
+#define TD_BUFFER_END_PTR   0x0100
+#define TD_PDATA            0x0200
+
+#define ED_FROM_TD_DIR        0x0
+#define ED_OUT_DIR            0x1
+#define ED_IN_DIR             0x2
+#define ED_FROM_TD_ALSO_DIR   0x3
+
+#define TD_SETUP_PID          0x00
+#define TD_OUT_PID            0x01
+#define TD_IN_PID             0x02
+#define TD_NODATA_PID         0x03
+
+#define HI_SPEED              0
+#define LO_SPEED              1
+
+#define TD_NO_ERROR           0x00
+#define TD_CRC_ERROR          0x01
+#define TD_BITSTUFFING_ERROR  0x02
+#define TD_TOGGLE_ERROR       0x03
+#define TD_DEVICE_STALL       0x04
+#define TD_NO_RESPONSE        0x05
+#define TD_PIDCHK_FAIL        0x06
+#define TD_PID_UNEXPECTED     0x07
+#define TD_DATA_OVERRUN       0x08
+#define TD_DATA_UNDERRUN      0x09
+#define TD_BUFFER_OVERRUN     0x0C
+#define TD_BUFFER_UNDERRUN    0x0D
+#define TD_TOBE_PROCESSED     0x0E
+#define TD_TOBE_PROCESSED_2   0x0F
+
+#define TD_NO_DELAY           0x7
+
+#define TD_INT                0x1
+#define TD_CTL                0x2
+#define TD_BLK                0x3
+
+typedef struct {
+  UINT32 Reserved:18;
+  UINT32 BufferRounding:1;
+  UINT32 DirPID:2;
+  UINT32 DelayInterrupt:3;
+  UINT32 DataToggle:2;
+  UINT32 ErrorCount:2;
+  UINT32 ConditionCode:4;
+} TD_DESCRIPTOR_WORD0;
+
+typedef struct _TD_DESCRIPTOR {
+  TD_DESCRIPTOR_WORD0     Word0;
+  VOID                    *CurrBufferPointer;
+  struct _TD_DESCRIPTOR   *NextTD;
+  VOID                    *BufferEndPointer;
+  struct _TD_DESCRIPTOR   *NextTDPointer;
+  UINT8                   *DataBuffer;
+  UINT32                  ActualSendLength;
+} TD_DESCRIPTOR;
+
+typedef struct {
+  UINT32 FunctionAddress:7;
+  UINT32 EndPointNum:4;
+  UINT32 Direction:2;
+  UINT32 Speed:1;
+  UINT32 Skip:1;
+  UINT32 Format:1;
+  UINT32 MaxPacketSize:11;
+  UINT32 FreeSpace:5;
+} ED_DESCRIPTOR_WORD0;
+
+typedef struct {
+  UINT32 Halted:1;
+  UINT32 ToggleCarry:1;
+  UINT32 Zero:2;
+  UINT32 TdHeadPointer:28;
+} ED_DESCRIPTOR_WORD2;
+
+typedef struct _ED_DESCRIPTOR {
+  ED_DESCRIPTOR_WORD0     Word0;
+  TD_DESCRIPTOR           *TdTailPointer;
+  ED_DESCRIPTOR_WORD2     Word2;
+  struct _ED_DESCRIPTOR   *NextED;
+} ED_DESCRIPTOR;
+
+#define TD_PTR(p)            ((TD_DESCRIPTOR *)((p) << 4))
+#define ED_PTR(p)            ((ED_DESCRIPTOR *)((p) << 4))
+#define RIGHT_SHIFT_4(p)     ((UINT32)(p) >> 4)
+
+typedef enum {
+  CONTROL_LIST,
+  BULK_LIST,
+  INTERRUPT_LIST,
+  ISOCHRONOUS_LIST
+} DESCRIPTOR_LIST_TYPE;
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.c
new file mode 100644
index 0000000000..6997e6e387
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.c
@@ -0,0 +1,1386 @@
+/** @file
+This file contains the implementation of Usb Hc Protocol.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "OhcPeim.h"
+
+/**
+  Submits control transfer to a target USB device.
+
+  @param  PeiServices            The pointer of EFI_PEI_SERVICES.
+  @param  This                   The pointer of PEI_USB_HOST_CONTROLLER_PPI.
+  @param  DeviceAddress          The target device address.
+  @param  DeviceSpeed            Target device speed.
+  @param  MaximumPacketLength    Maximum packet size the default control transfer
+                                 endpoint is capable of sending or receiving.
+  @param  Request                USB device request to send.
+  @param  TransferDirection      Specifies the data direction for the data stage.
+  @param  Data                   Data buffer to be transmitted or received from USB device.
+  @param  DataLength             The size (in bytes) of the data buffer.
+  @param  TimeOut                Indicates the maximum timeout, in millisecond.
+  @param  TransferResult         Return the result of this control transfer.
+
+  @retval EFI_SUCCESS            Transfer was completed successfully.
+  @retval EFI_OUT_OF_RESOURCES   The transfer failed due to lack of resources.
+  @retval EFI_INVALID_PARAMETER  Some parameters are invalid.
+  @retval EFI_TIMEOUT            Transfer failed due to timeout.
+  @retval EFI_DEVICE_ERROR       Transfer failed due to host controller or device error.
+
+**/
+EFI_STATUS
+EFIAPI
+OhciControlTransfer (
+  IN  EFI_PEI_SERVICES             **PeiServices,
+  IN  PEI_USB_HOST_CONTROLLER_PPI  *This,
+  IN  UINT8                        DeviceAddress,
+  IN  UINT8                        DeviceSpeed,
+  IN  UINT8                        MaxPacketLength,
+  IN  EFI_USB_DEVICE_REQUEST       *Request,
+  IN  EFI_USB_DATA_DIRECTION       TransferDirection,
+  IN  OUT VOID                     *Data,
+  IN  OUT UINTN                    *DataLength,
+  IN  UINTN                        TimeOut,
+  OUT UINT32                       *TransferResult
+  )
+{
+  USB_OHCI_HC_DEV               *Ohc;
+  ED_DESCRIPTOR                 *Ed;
+  TD_DESCRIPTOR                 *HeadTd;
+  TD_DESCRIPTOR                 *SetupTd;
+  TD_DESCRIPTOR                 *DataTd;
+  TD_DESCRIPTOR                 *StatusTd;
+  TD_DESCRIPTOR                 *EmptyTd;
+  EFI_STATUS                    Status;
+  UINT32                        DataPidDir;
+  UINT32                        StatusPidDir;
+  UINTN                         TimeCount;
+  UINT32                        ErrorCode;
+
+  UINTN                         ActualSendLength;
+  UINTN                         LeftLength;
+  UINT8                         DataToggle;
+
+  EFI_PHYSICAL_ADDRESS          ReqMapPhyAddr = 0;
+
+  UINTN                         DataMapLength = 0;
+  EFI_PHYSICAL_ADDRESS          DataMapPhyAddr = 0;
+
+  HeadTd = NULL;
+  DataTd = NULL;
+
+  if ((TransferDirection != EfiUsbDataOut && TransferDirection != EfiUsbDataIn &&
+       TransferDirection != EfiUsbNoData) ||
+      Request == NULL || DataLength == NULL || TransferResult == NULL ||
+      (TransferDirection == EfiUsbNoData && (*DataLength != 0 || Data != NULL)) ||
+      (TransferDirection != EfiUsbNoData && (*DataLength == 0 || Data == NULL)) ||
+      (DeviceSpeed != EFI_USB_SPEED_LOW && DeviceSpeed != EFI_USB_SPEED_FULL) ||
+      (MaxPacketLength != 8 && MaxPacketLength != 16 &&
+       MaxPacketLength != 32 && MaxPacketLength != 64)) {
+    DEBUG ((EFI_D_INFO, "OhciControlTransfer: EFI_INVALID_PARAMETER\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (*DataLength > MAX_BYTES_PER_TD) {
+    DEBUG ((EFI_D_ERROR, "OhciControlTransfer: Request data size is too large\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Ohc = PEI_RECOVERY_USB_OHC_DEV_FROM_EHCI_THIS(This);
+
+  if (TransferDirection == EfiUsbDataIn) {
+    DataPidDir = TD_IN_PID;
+    StatusPidDir = TD_OUT_PID;
+  } else {
+    DataPidDir = TD_OUT_PID;
+    StatusPidDir = TD_IN_PID;
+  }
+
+  OhciSetHcControl (Ohc, CONTROL_ENABLE, 0);
+  if (OhciGetHcControl (Ohc, CONTROL_ENABLE) != 0) {
+    MicroSecondDelay (HC_1_MILLISECOND);
+    if (OhciGetHcControl (Ohc, CONTROL_ENABLE) != 0) {
+      *TransferResult = EFI_USB_ERR_SYSTEM;
+      DEBUG ((EFI_D_INFO, "OhciControlTransfer: Fail to disable CONTROL transfer\n"));
+      return EFI_DEVICE_ERROR;
+    }
+  }
+  OhciSetMemoryPointer (Ohc, HC_CONTROL_HEAD, NULL);
+  Ed = OhciCreateED (Ohc);
+  if (Ed == NULL) {
+    DEBUG ((EFI_D_INFO, "OhciControlTransfer: Fail to allocate ED buffer\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+  OhciSetEDField (Ed, ED_SKIP, 1);
+  OhciSetEDField (Ed, ED_FUNC_ADD, DeviceAddress);
+  OhciSetEDField (Ed, ED_ENDPT_NUM, 0);
+  OhciSetEDField (Ed, ED_DIR, ED_FROM_TD_DIR);
+  OhciSetEDField (Ed, ED_SPEED, DeviceSpeed);
+  OhciSetEDField (Ed, ED_FORMAT | ED_HALTED | ED_DTTOGGLE, 0);
+  OhciSetEDField (Ed, ED_MAX_PACKET, MaxPacketLength);
+  OhciSetEDField (Ed, ED_PDATA, 0);
+  OhciSetEDField (Ed, ED_ZERO, 0);
+  OhciSetEDField (Ed, ED_TDHEAD_PTR, (UINT32) NULL);
+  OhciSetEDField (Ed, ED_TDTAIL_PTR, (UINT32) NULL);
+  OhciSetEDField (Ed, ED_NEXT_EDPTR, (UINT32) NULL);
+  OhciAttachEDToList (Ohc, CONTROL_LIST, Ed, NULL);
+  //
+  // Setup Stage
+  //
+  if(Request != NULL) {
+    ReqMapPhyAddr = (EFI_PHYSICAL_ADDRESS)(UINTN)Request;
+  }
+  SetupTd = OhciCreateTD (Ohc);
+  if (SetupTd == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    DEBUG ((EFI_D_INFO, "OhciControlTransfer: Fail to allocate Setup TD buffer\n"));
+    goto FREE_ED_BUFF;
+  }
+  HeadTd = SetupTd;
+  OhciSetTDField (SetupTd, TD_PDATA, 0);
+  OhciSetTDField (SetupTd, TD_BUFFER_ROUND, 1);
+  OhciSetTDField (SetupTd, TD_DIR_PID, TD_SETUP_PID);
+  OhciSetTDField (SetupTd, TD_DELAY_INT, TD_NO_DELAY);
+  OhciSetTDField (SetupTd, TD_DT_TOGGLE, 2);
+  OhciSetTDField (SetupTd, TD_ERROR_CNT, 0);
+  OhciSetTDField (SetupTd, TD_COND_CODE, TD_TOBE_PROCESSED);
+  OhciSetTDField (SetupTd, TD_CURR_BUFFER_PTR, (UINTN)ReqMapPhyAddr);
+  OhciSetTDField (SetupTd, TD_NEXT_PTR, (UINT32) NULL);
+  OhciSetTDField (SetupTd, TD_BUFFER_END_PTR, (UINTN)ReqMapPhyAddr + sizeof (EFI_USB_DEVICE_REQUEST) - 1);
+  SetupTd->ActualSendLength = 0;
+  SetupTd->DataBuffer = NULL;
+  SetupTd->NextTDPointer = NULL;
+
+  DataMapLength = *DataLength;
+  if ((Data != NULL) && (DataMapLength != 0)) {
+    DataMapPhyAddr = (EFI_PHYSICAL_ADDRESS)(UINTN)Data;
+  }
+  //
+  //Data Stage
+  //
+  LeftLength = DataMapLength;
+  ActualSendLength = DataMapLength;
+  DataToggle = 1;
+  while (LeftLength > 0) {
+    ActualSendLength = LeftLength;
+    if (LeftLength > MaxPacketLength) {
+      ActualSendLength = MaxPacketLength;
+    }
+    DataTd = OhciCreateTD (Ohc);
+    if (DataTd == NULL) {
+      DEBUG ((EFI_D_INFO, "OhciControlTransfer: Fail to allocate Data TD buffer\n"));
+      Status = EFI_OUT_OF_RESOURCES;
+      goto FREE_TD_BUFF;
+    }
+    OhciSetTDField (DataTd, TD_PDATA, 0);
+    OhciSetTDField (DataTd, TD_BUFFER_ROUND, 1);
+    OhciSetTDField (DataTd, TD_DIR_PID, DataPidDir);
+    OhciSetTDField (DataTd, TD_DELAY_INT, TD_NO_DELAY);
+    OhciSetTDField (DataTd, TD_DT_TOGGLE, DataToggle);
+    OhciSetTDField (DataTd, TD_ERROR_CNT, 0);
+    OhciSetTDField (DataTd, TD_COND_CODE, TD_TOBE_PROCESSED);
+    OhciSetTDField (DataTd, TD_CURR_BUFFER_PTR, (UINT32) DataMapPhyAddr);
+    OhciSetTDField (DataTd, TD_BUFFER_END_PTR, (UINT32) DataMapPhyAddr + ActualSendLength - 1);
+    OhciSetTDField (DataTd, TD_NEXT_PTR, (UINT32) NULL);
+    DataTd->ActualSendLength = ActualSendLength;
+    DataTd->DataBuffer = (UINT8 *)(UINTN)DataMapPhyAddr;
+    DataTd->NextTDPointer = 0;
+    OhciLinkTD (HeadTd, DataTd);
+    DataToggle ^= 1;
+    DataMapPhyAddr += ActualSendLength;
+    LeftLength -= ActualSendLength;
+  }
+  //
+  // Status Stage
+  //
+  StatusTd = OhciCreateTD (Ohc);
+  if (StatusTd == NULL) {
+    DEBUG ((EFI_D_INFO, "OhciControlTransfer: Fail to allocate Status TD buffer\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto FREE_TD_BUFF;
+  }
+  OhciSetTDField (StatusTd, TD_PDATA, 0);
+  OhciSetTDField (StatusTd, TD_BUFFER_ROUND, 1);
+  OhciSetTDField (StatusTd, TD_DIR_PID, StatusPidDir);
+  OhciSetTDField (StatusTd, TD_DELAY_INT, 7);
+  OhciSetTDField (StatusTd, TD_DT_TOGGLE, 3);
+  OhciSetTDField (StatusTd, TD_ERROR_CNT, 0);
+  OhciSetTDField (StatusTd, TD_COND_CODE, TD_TOBE_PROCESSED);
+  OhciSetTDField (StatusTd, TD_CURR_BUFFER_PTR, (UINT32) NULL);
+  OhciSetTDField (StatusTd, TD_NEXT_PTR, (UINT32) NULL);
+  OhciSetTDField (StatusTd, TD_BUFFER_END_PTR, (UINT32) NULL);
+  StatusTd->ActualSendLength = 0;
+  StatusTd->DataBuffer = NULL;
+  StatusTd->NextTDPointer = NULL;
+  OhciLinkTD (HeadTd, StatusTd);
+  //
+  // Empty Stage
+  //
+  EmptyTd = OhciCreateTD (Ohc);
+  if (EmptyTd == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    DEBUG ((EFI_D_INFO, "OhciControlTransfer: Fail to allocate Empty TD buffer\n"));
+    goto FREE_TD_BUFF;
+  }
+  OhciSetTDField (EmptyTd, TD_PDATA, 0);
+  OhciSetTDField (EmptyTd, TD_BUFFER_ROUND, 0);
+  OhciSetTDField (EmptyTd, TD_DIR_PID, 0);
+  OhciSetTDField (EmptyTd, TD_DELAY_INT, 0);
+  //OhciSetTDField (EmptyTd, TD_DT_TOGGLE, CurrentToggle);
+  EmptyTd->Word0.DataToggle = 0;
+  OhciSetTDField (EmptyTd, TD_ERROR_CNT, 0);
+  OhciSetTDField (EmptyTd, TD_COND_CODE, 0);
+  OhciSetTDField (EmptyTd, TD_CURR_BUFFER_PTR, 0);
+  OhciSetTDField (EmptyTd, TD_BUFFER_END_PTR, 0);
+  OhciSetTDField (EmptyTd, TD_NEXT_PTR, 0);
+  EmptyTd->ActualSendLength = 0;
+  EmptyTd->DataBuffer = NULL;
+  EmptyTd->NextTDPointer = NULL;
+  OhciLinkTD (HeadTd, EmptyTd);
+  Ed->TdTailPointer = EmptyTd;
+  OhciAttachTDListToED (Ed, HeadTd);
+  //
+  OhciSetEDField (Ed, ED_SKIP, 0);
+  MicroSecondDelay (20 * HC_1_MILLISECOND);
+  OhciSetHcCommandStatus (Ohc, CONTROL_LIST_FILLED, 1);
+  OhciSetHcControl (Ohc, CONTROL_ENABLE, 1);
+  MicroSecondDelay (20 * HC_1_MILLISECOND);
+  if (OhciGetHcControl (Ohc, CONTROL_ENABLE) != 1) {
+  MicroSecondDelay (HC_1_MILLISECOND);
+    if (OhciGetHcControl (Ohc, CONTROL_ENABLE) != 1) {
+      *TransferResult = EFI_USB_ERR_SYSTEM;
+      Status = EFI_DEVICE_ERROR;
+      DEBUG ((EFI_D_INFO, "OhciControlTransfer: Fail to enable CONTROL transfer\n"));
+      goto FREE_TD_BUFF;
+    }
+  }
+
+  TimeCount = 0;
+  Status = CheckIfDone (Ohc, CONTROL_LIST, Ed, HeadTd, &ErrorCode);
+
+  while (Status == EFI_NOT_READY && TimeCount <= TimeOut) {
+    MicroSecondDelay (HC_1_MILLISECOND);
+    TimeCount++;
+    Status = CheckIfDone (Ohc, CONTROL_LIST, Ed, HeadTd, &ErrorCode);
+  }
+  //
+  *TransferResult = ConvertErrorCode (ErrorCode);
+
+  if (ErrorCode != TD_NO_ERROR) {
+    if (ErrorCode == TD_TOBE_PROCESSED) {
+      DEBUG ((EFI_D_INFO, "Control pipe timeout, > %d mS\r\n", TimeOut));
+    } else {
+      DEBUG ((EFI_D_INFO, "Control pipe broken\r\n"));
+    }
+
+    *DataLength = 0;
+  }
+
+  OhciSetHcControl (Ohc, CONTROL_ENABLE, 0);
+  if (OhciGetHcControl (Ohc, CONTROL_ENABLE) != 0) {
+  MicroSecondDelay (HC_1_MILLISECOND);
+    if (OhciGetHcControl (Ohc, CONTROL_ENABLE) != 0) {
+      *TransferResult = EFI_USB_ERR_SYSTEM;
+      DEBUG ((EFI_D_INFO, "OhciControlTransfer: Cannot disable CONTROL_ENABLE transfer\n"));
+      goto FREE_TD_BUFF;
+    }
+  }
+
+FREE_TD_BUFF:
+  while (HeadTd) {
+    DataTd = HeadTd;
+    HeadTd = HeadTd->NextTDPointer;
+    UsbHcFreeMem(Ohc->MemPool, DataTd, sizeof(TD_DESCRIPTOR));
+  }
+
+FREE_ED_BUFF:
+  UsbHcFreeMem(Ohc->MemPool, Ed, sizeof(ED_DESCRIPTOR));
+
+  return Status;
+}
+
+/**
+  Submits bulk transfer to a bulk endpoint of a USB device.
+
+  @param  PeiServices           The pointer of EFI_PEI_SERVICES.
+  @param  This                  The pointer of PEI_USB_HOST_CONTROLLER_PPI.
+  @param  DeviceAddress         Target device address.
+  @param  EndPointAddress       Endpoint number and its direction in bit 7.
+  @param  MaxiPacketLength      Maximum packet size the endpoint is capable of
+                                sending or receiving.
+  @param  Data                  A pointers to the buffers of data to transmit
+                                from or receive into.
+  @param  DataLength            The lenght of the data buffer.
+  @param  DataToggle            On input, the initial data toggle for the transfer;
+                                On output, it is updated to to next data toggle to use of
+                                the subsequent bulk transfer.
+  @param  TimeOut               Indicates the maximum time, in millisecond, which the
+                                transfer is allowed to complete.
+  @param  TransferResult        A pointer to the detailed result information of the
+                                bulk transfer.
+
+  @retval EFI_SUCCESS           The transfer was completed successfully.
+  @retval EFI_OUT_OF_RESOURCES  The transfer failed due to lack of resource.
+  @retval EFI_INVALID_PARAMETER Parameters are invalid.
+  @retval EFI_TIMEOUT           The transfer failed due to timeout.
+  @retval EFI_DEVICE_ERROR      The transfer failed due to host controller error.
+
+**/
+EFI_STATUS
+EFIAPI
+OhciBulkTransfer (
+  IN EFI_PEI_SERVICES             **PeiServices,
+  IN PEI_USB_HOST_CONTROLLER_PPI  *This,
+  IN  UINT8                       DeviceAddress,
+  IN  UINT8                       EndPointAddress,
+  IN  UINT8                       MaxPacketLength,
+  IN  OUT VOID                    *Data,
+  IN  OUT UINTN                   *DataLength,
+  IN  OUT UINT8                   *DataToggle,
+  IN  UINTN                       TimeOut,
+  OUT UINT32                      *TransferResult
+  )
+{
+  USB_OHCI_HC_DEV                *Ohc;
+  ED_DESCRIPTOR                  *Ed;
+  UINT32                         DataPidDir;
+  TD_DESCRIPTOR                  *HeadTd;
+  TD_DESCRIPTOR                  *DataTd;
+  TD_DESCRIPTOR                  *EmptyTd;
+  EFI_STATUS                     Status;
+  UINT8                          EndPointNum;
+  UINTN                          TimeCount;
+  UINT32                         ErrorCode;
+
+  UINT8                          CurrentToggle;
+  UINTN                          MapLength;
+  EFI_PHYSICAL_ADDRESS           MapPyhAddr;
+  UINTN                          LeftLength;
+  UINTN                          ActualSendLength;
+  BOOLEAN                        FirstTD;
+
+  MapLength = 0;
+  MapPyhAddr = 0;
+  LeftLength = 0;
+  Status = EFI_SUCCESS;
+
+  if (Data == NULL || DataLength == NULL || DataToggle == NULL || TransferResult == NULL ||
+      *DataLength == 0 || (*DataToggle != 0 && *DataToggle != 1) ||
+      (MaxPacketLength != 8 && MaxPacketLength != 16 &&
+       MaxPacketLength != 32 && MaxPacketLength != 64)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Ohc = PEI_RECOVERY_USB_OHC_DEV_FROM_EHCI_THIS (This);
+
+  if ((EndPointAddress & 0x80) != 0) {
+    DataPidDir = TD_IN_PID;
+  } else {
+    DataPidDir = TD_OUT_PID;
+  }
+
+  EndPointNum = (EndPointAddress & 0xF);
+
+  OhciSetHcControl (Ohc, BULK_ENABLE, 0);
+  if (OhciGetHcControl (Ohc, BULK_ENABLE) != 0) {
+    MicroSecondDelay (HC_1_MILLISECOND);
+    if (OhciGetHcControl (Ohc, BULK_ENABLE) != 0) {
+      *TransferResult = EFI_USB_ERR_SYSTEM;
+      return EFI_DEVICE_ERROR;
+    }
+  }
+
+  OhciSetMemoryPointer (Ohc, HC_BULK_HEAD, NULL);
+
+  Ed = OhciCreateED (Ohc);
+  if (Ed == NULL) {
+    DEBUG ((EFI_D_INFO, "OhcBulkTransfer: Fail to allocate ED buffer\r\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+  OhciSetEDField (Ed, ED_SKIP, 1);
+  OhciSetEDField (Ed, ED_FUNC_ADD, DeviceAddress);
+  OhciSetEDField (Ed, ED_ENDPT_NUM, EndPointNum);
+  OhciSetEDField (Ed, ED_DIR, ED_FROM_TD_DIR);
+  OhciSetEDField (Ed, ED_SPEED, HI_SPEED);
+  OhciSetEDField (Ed, ED_FORMAT | ED_HALTED | ED_DTTOGGLE, 0);
+  OhciSetEDField (Ed, ED_MAX_PACKET, MaxPacketLength);
+  OhciSetEDField (Ed, ED_PDATA, 0);
+  OhciSetEDField (Ed, ED_ZERO, 0);
+  OhciSetEDField (Ed, ED_TDHEAD_PTR, (UINT32) NULL);
+  OhciSetEDField (Ed, ED_TDTAIL_PTR, (UINT32) NULL);
+  OhciSetEDField (Ed, ED_NEXT_EDPTR, (UINT32) NULL);
+  OhciAttachEDToList (Ohc, BULK_LIST, Ed, NULL);
+
+  if(Data != NULL) {
+    MapLength = *DataLength;
+    MapPyhAddr = (EFI_PHYSICAL_ADDRESS)(UINTN)Data;
+  }
+  //
+  //Data Stage
+  //
+  LeftLength = MapLength;
+  ActualSendLength = MapLength;
+  CurrentToggle = *DataToggle;
+  HeadTd = NULL;
+  FirstTD = TRUE;
+  while (LeftLength > 0) {
+    ActualSendLength = LeftLength;
+    if (LeftLength > MaxPacketLength) {
+      ActualSendLength = MaxPacketLength;
+    }
+    DataTd = OhciCreateTD (Ohc);
+    if (DataTd == NULL) {
+      DEBUG ((EFI_D_INFO, "OhcBulkTransfer: Fail to allocate Data TD buffer\r\n"));
+      Status = EFI_OUT_OF_RESOURCES;
+      goto FREE_TD_BUFF;
+    }
+    OhciSetTDField (DataTd, TD_PDATA, 0);
+    OhciSetTDField (DataTd, TD_BUFFER_ROUND, 1);
+    OhciSetTDField (DataTd, TD_DIR_PID, DataPidDir);
+    OhciSetTDField (DataTd, TD_DELAY_INT, TD_NO_DELAY);
+    OhciSetTDField (DataTd, TD_DT_TOGGLE, CurrentToggle);
+    OhciSetTDField (DataTd, TD_ERROR_CNT, 0);
+    OhciSetTDField (DataTd, TD_COND_CODE, TD_TOBE_PROCESSED);
+    OhciSetTDField (DataTd, TD_CURR_BUFFER_PTR, (UINT32) MapPyhAddr);
+    OhciSetTDField (DataTd, TD_BUFFER_END_PTR, (UINT32) MapPyhAddr + ActualSendLength - 1);
+    OhciSetTDField (DataTd, TD_NEXT_PTR, (UINT32) NULL);
+    DataTd->ActualSendLength = ActualSendLength;
+    DataTd->DataBuffer = (UINT8 *)(UINTN)MapPyhAddr;
+    DataTd->NextTDPointer = 0;
+    if (FirstTD) {
+      HeadTd = DataTd;
+      FirstTD = FALSE;
+    } else {
+      OhciLinkTD (HeadTd, DataTd);
+    }
+    CurrentToggle ^= 1;
+    MapPyhAddr += ActualSendLength;
+    LeftLength -= ActualSendLength;
+  }
+  //
+  // Empty Stage
+  //
+  EmptyTd = OhciCreateTD (Ohc);
+  if (EmptyTd == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+      DEBUG ((EFI_D_INFO, "OhcBulkTransfer: Fail to allocate Empty TD buffer\r\n"));
+    goto FREE_TD_BUFF;
+  }
+  OhciSetTDField (EmptyTd, TD_PDATA, 0);
+  OhciSetTDField (EmptyTd, TD_BUFFER_ROUND, 0);
+  OhciSetTDField (EmptyTd, TD_DIR_PID, 0);
+  OhciSetTDField (EmptyTd, TD_DELAY_INT, 0);
+  //OhciSetTDField (EmptyTd, TD_DT_TOGGLE, CurrentToggle);
+  EmptyTd->Word0.DataToggle = 0;
+  OhciSetTDField (EmptyTd, TD_ERROR_CNT, 0);
+  OhciSetTDField (EmptyTd, TD_COND_CODE, 0);
+  OhciSetTDField (EmptyTd, TD_CURR_BUFFER_PTR, 0);
+  OhciSetTDField (EmptyTd, TD_BUFFER_END_PTR, 0);
+  OhciSetTDField (EmptyTd, TD_NEXT_PTR, 0);
+  EmptyTd->ActualSendLength = 0;
+  EmptyTd->DataBuffer = NULL;
+  EmptyTd->NextTDPointer = NULL;
+  OhciLinkTD (HeadTd, EmptyTd);
+  Ed->TdTailPointer = EmptyTd;
+  OhciAttachTDListToED (Ed, HeadTd);
+
+  OhciSetEDField (Ed, ED_SKIP, 0);
+  OhciSetHcCommandStatus (Ohc, BULK_LIST_FILLED, 1);
+  OhciSetHcControl (Ohc, BULK_ENABLE, 1);
+  if (OhciGetHcControl (Ohc, BULK_ENABLE) != 1) {
+    MicroSecondDelay (HC_1_MILLISECOND);
+    if (OhciGetHcControl (Ohc, BULK_ENABLE) != 1) {
+      *TransferResult = EFI_USB_ERR_SYSTEM;
+      goto FREE_TD_BUFF;
+    }
+  }
+
+  TimeCount = 0;
+  Status = CheckIfDone (Ohc, BULK_LIST, Ed, HeadTd, &ErrorCode);
+
+  while (Status == EFI_NOT_READY && TimeCount <= TimeOut) {
+    MicroSecondDelay (HC_1_MILLISECOND);
+    TimeCount++;
+    Status = CheckIfDone (Ohc, BULK_LIST, Ed, HeadTd, &ErrorCode);
+  }
+
+  *TransferResult = ConvertErrorCode (ErrorCode);
+
+  if (ErrorCode != TD_NO_ERROR) {
+    if (ErrorCode == TD_TOBE_PROCESSED) {
+      DEBUG ((EFI_D_INFO, "Bulk pipe timeout, > %d mS\r\n", TimeOut));
+    } else {
+      DEBUG ((EFI_D_INFO, "Bulk pipe broken\r\n"));
+    }
+    *DataLength = 0;
+  }
+    *DataToggle = (UINT8) OhciGetEDField (Ed, ED_DTTOGGLE);
+
+FREE_TD_BUFF:
+  while (HeadTd) {
+    DataTd = HeadTd;
+    HeadTd = HeadTd->NextTDPointer;
+    UsbHcFreeMem(Ohc->MemPool, DataTd, sizeof(TD_DESCRIPTOR));
+  }
+  UsbHcFreeMem(Ohc->MemPool, Ed, sizeof(ED_DESCRIPTOR));
+
+  return Status;
+}
+/**
+  Retrieves the number of root hub ports.
+
+  @param[in]  PeiServices       The pointer to the PEI Services Table.
+  @param[in]  This              The pointer to this instance of the
+                                PEI_USB_HOST_CONTROLLER_PPI.
+  @param[out] NumOfPorts        The pointer to the number of the root hub ports.
+
+  @retval EFI_SUCCESS           The port number was retrieved successfully.
+  @retval EFI_INVALID_PARAMETER PortNumber is NULL.
+
+**/
+
+EFI_STATUS
+EFIAPI
+OhciGetRootHubNumOfPorts (
+  IN EFI_PEI_SERVICES             **PeiServices,
+  IN PEI_USB_HOST_CONTROLLER_PPI  *This,
+  OUT UINT8                       *NumOfPorts
+  )
+{
+  USB_OHCI_HC_DEV                *Ohc;
+  if (NumOfPorts == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  Ohc = PEI_RECOVERY_USB_OHC_DEV_FROM_EHCI_THIS (This);
+  *NumOfPorts = (UINT8)OhciGetRootHubDescriptor(Ohc, RH_NUM_DS_PORTS);
+
+  return EFI_SUCCESS;
+}
+/**
+  Retrieves the current status of a USB root hub port.
+
+  @param  PeiServices            The pointer of EFI_PEI_SERVICES.
+  @param  This                   The pointer of PEI_USB_HOST_CONTROLLER_PPI.
+  @param  PortNumber             The root hub port to retrieve the state from.
+  @param  PortStatus             Variable to receive the port state.
+
+  @retval EFI_SUCCESS            The status of the USB root hub port specified.
+                                 by PortNumber was returned in PortStatus.
+  @retval EFI_INVALID_PARAMETER  PortNumber is invalid.
+
+**/
+
+EFI_STATUS
+EFIAPI
+OhciGetRootHubPortStatus (
+  IN  EFI_PEI_SERVICES             **PeiServices,
+  IN  PEI_USB_HOST_CONTROLLER_PPI  *This,
+  IN  UINT8                        PortNumber,
+  OUT EFI_USB_PORT_STATUS          *PortStatus
+  )
+{
+  USB_OHCI_HC_DEV  *Ohc;
+  UINT8            NumOfPorts;
+
+  Ohc = PEI_RECOVERY_USB_OHC_DEV_FROM_EHCI_THIS (This);
+
+  OhciGetRootHubNumOfPorts (PeiServices, This, &NumOfPorts);
+  if (PortNumber >= NumOfPorts) {
+    return EFI_INVALID_PARAMETER;
+  }
+  PortStatus->PortStatus = 0;
+  PortStatus->PortChangeStatus = 0;
+
+  if (OhciReadRootHubPortStatus (Ohc,PortNumber, RH_CURR_CONNECT_STAT)) {
+    PortStatus->PortStatus |= USB_PORT_STAT_CONNECTION;
+  }
+  if (OhciReadRootHubPortStatus (Ohc,PortNumber, RH_PORT_ENABLE_STAT)) {
+    PortStatus->PortStatus |= USB_PORT_STAT_ENABLE;
+  }
+  if (OhciReadRootHubPortStatus (Ohc,PortNumber, RH_PORT_SUSPEND_STAT)) {
+    PortStatus->PortStatus |= USB_PORT_STAT_SUSPEND;
+  }
+  if (OhciReadRootHubPortStatus (Ohc,PortNumber, RH_PORT_OC_INDICATOR)) {
+    PortStatus->PortStatus |= USB_PORT_STAT_OVERCURRENT;
+  }
+  if (OhciReadRootHubPortStatus (Ohc,PortNumber, RH_PORT_RESET_STAT)) {
+    PortStatus->PortStatus |= USB_PORT_STAT_RESET;
+  }
+  if (OhciReadRootHubPortStatus (Ohc,PortNumber, RH_PORT_POWER_STAT)) {
+    PortStatus->PortStatus |= USB_PORT_STAT_POWER;
+  }
+  if (OhciReadRootHubPortStatus (Ohc,PortNumber, RH_LSDEVICE_ATTACHED)) {
+    PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;
+  }
+  if (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_ENABLE_STAT_CHANGE)) {
+    PortStatus->PortChangeStatus |= USB_PORT_STAT_C_ENABLE;
+  }
+  if (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_CONNECT_STATUS_CHANGE)) {
+    PortStatus->PortChangeStatus |= USB_PORT_STAT_C_CONNECTION;
+  }
+  if (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_SUSPEND_STAT_CHANGE)) {
+    PortStatus->PortChangeStatus |= USB_PORT_STAT_C_SUSPEND;
+  }
+  if (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_OC_INDICATOR_CHANGE)) {
+    PortStatus->PortChangeStatus |= USB_PORT_STAT_C_OVERCURRENT;
+  }
+  if (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_RESET_STAT_CHANGE)) {
+    PortStatus->PortChangeStatus |= USB_PORT_STAT_C_RESET;
+  }
+
+  return EFI_SUCCESS;
+}
+/**
+  Sets a feature for the specified root hub port.
+
+  @param  PeiServices           The pointer of EFI_PEI_SERVICES
+  @param  This                  The pointer of PEI_USB_HOST_CONTROLLER_PPI
+  @param  PortNumber            Root hub port to set.
+  @param  PortFeature           Feature to set.
+
+  @retval EFI_SUCCESS            The feature specified by PortFeature was set.
+  @retval EFI_INVALID_PARAMETER  PortNumber is invalid or PortFeature is invalid.
+  @retval EFI_TIMEOUT            The time out occurred.
+
+**/
+
+EFI_STATUS
+EFIAPI
+OhciSetRootHubPortFeature (
+  IN EFI_PEI_SERVICES             **PeiServices,
+  IN PEI_USB_HOST_CONTROLLER_PPI  *This,
+  IN UINT8                        PortNumber,
+  IN EFI_USB_PORT_FEATURE         PortFeature
+  )
+{
+  USB_OHCI_HC_DEV         *Ohc;
+  EFI_STATUS              Status;
+  UINT8                   NumOfPorts;
+  UINTN                   RetryTimes;
+
+  OhciGetRootHubNumOfPorts (PeiServices, This, &NumOfPorts);
+  if (PortNumber >= NumOfPorts) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Ohc = PEI_RECOVERY_USB_OHC_DEV_FROM_EHCI_THIS (This);
+
+  Status = EFI_SUCCESS;
+
+
+  switch (PortFeature) {
+    case EfiUsbPortPower:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_SET_PORT_POWER);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        MicroSecondDelay (HC_1_MILLISECOND);
+        RetryTimes++;
+      } while (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_POWER_STAT) == 0 &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+      break;
+
+    case EfiUsbPortReset:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_SET_PORT_RESET);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        MicroSecondDelay (HC_1_MILLISECOND);
+        RetryTimes++;
+      } while ((OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_RESET_STAT_CHANGE) == 0 ||
+                OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_RESET_STAT) == 1) &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+
+      OhciSetRootHubPortStatus (Ohc, PortNumber, RH_PORT_RESET_STAT_CHANGE);
+      break;
+
+    case EfiUsbPortEnable:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_SET_PORT_ENABLE);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        MicroSecondDelay (HC_1_MILLISECOND);;
+        RetryTimes++;
+      } while (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_ENABLE_STAT) == 0 &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+      break;
+
+
+    case EfiUsbPortSuspend:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_SET_PORT_SUSPEND);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        MicroSecondDelay (HC_1_MILLISECOND);;
+        RetryTimes++;
+      } while (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_SUSPEND_STAT) == 0 &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+      break;
+
+    default:
+      return EFI_INVALID_PARAMETER;
+  }
+
+  return Status;
+}
+
+/**
+  Clears a feature for the specified root hub port.
+
+  @param  PeiServices           The pointer of EFI_PEI_SERVICES.
+  @param  This                  The pointer of PEI_USB_HOST_CONTROLLER_PPI.
+  @param  PortNumber            Specifies the root hub port whose feature
+                                is requested to be cleared.
+  @param  PortFeature           Indicates the feature selector associated with the
+                                feature clear request.
+
+  @retval EFI_SUCCESS            The feature specified by PortFeature was cleared
+                                 for the USB root hub port specified by PortNumber.
+  @retval EFI_INVALID_PARAMETER  PortNumber is invalid or PortFeature is invalid.
+
+**/
+
+EFI_STATUS
+EFIAPI
+OhciClearRootHubPortFeature (
+  IN EFI_PEI_SERVICES             **PeiServices,
+  IN PEI_USB_HOST_CONTROLLER_PPI  *This,
+  IN UINT8                        PortNumber,
+  IN EFI_USB_PORT_FEATURE         PortFeature
+  )
+{
+  USB_OHCI_HC_DEV         *Ohc;
+  EFI_STATUS              Status;
+  UINT8                   NumOfPorts;
+  UINTN                   RetryTimes;
+
+
+  OhciGetRootHubNumOfPorts (PeiServices, This, &NumOfPorts);
+  if (PortNumber >= NumOfPorts) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Ohc = PEI_RECOVERY_USB_OHC_DEV_FROM_EHCI_THIS (This);
+
+  Status = EFI_SUCCESS;
+
+  switch (PortFeature) {
+    case EfiUsbPortEnable:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_CLEAR_PORT_ENABLE);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        MicroSecondDelay (HC_1_MILLISECOND);
+        RetryTimes++;
+      } while (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_ENABLE_STAT) == 1 &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+      break;
+
+    case EfiUsbPortSuspend:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_CLEAR_SUSPEND_STATUS);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        MicroSecondDelay (HC_1_MILLISECOND);
+        RetryTimes++;
+      } while (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_SUSPEND_STAT) == 1 &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+      break;
+
+    case EfiUsbPortReset:
+      break;
+
+    case EfiUsbPortPower:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_CLEAR_PORT_POWER);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        MicroSecondDelay (HC_1_MILLISECOND);
+        RetryTimes++;
+      } while (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_POWER_STAT) == 1 &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+      break;
+
+    case EfiUsbPortConnectChange:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_CONNECT_STATUS_CHANGE);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        MicroSecondDelay (HC_1_MILLISECOND);
+        RetryTimes++;
+      } while (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_CONNECT_STATUS_CHANGE) == 1 &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+      break;
+
+    case EfiUsbPortResetChange:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_PORT_RESET_STAT_CHANGE);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        MicroSecondDelay (HC_1_MILLISECOND);
+        RetryTimes++;
+      } while (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_RESET_STAT_CHANGE) == 1 &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+      break;
+
+
+    case EfiUsbPortEnableChange:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_PORT_ENABLE_STAT_CHANGE);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        MicroSecondDelay (HC_1_MILLISECOND);
+        RetryTimes++;
+      } while (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_ENABLE_STAT_CHANGE) == 1 &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+      break;
+
+    case EfiUsbPortSuspendChange:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_PORT_SUSPEND_STAT_CHANGE);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        MicroSecondDelay (HC_1_MILLISECOND);
+        RetryTimes++;
+      } while (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_PORT_SUSPEND_STAT_CHANGE) == 1 &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+      break;
+
+    case EfiUsbPortOverCurrentChange:
+      Status = OhciSetRootHubPortStatus (Ohc, PortNumber, RH_OC_INDICATOR_CHANGE);
+
+      //
+      // Verify the state
+      //
+      RetryTimes = 0;
+      do {
+        MicroSecondDelay (HC_1_MILLISECOND);
+        RetryTimes++;
+      } while (OhciReadRootHubPortStatus (Ohc, PortNumber, RH_OC_INDICATOR_CHANGE) == 1 &&
+               RetryTimes < MAX_RETRY_TIMES);
+
+      if (RetryTimes >= MAX_RETRY_TIMES) {
+        return EFI_DEVICE_ERROR;
+      }
+      break;
+
+    default:
+      return EFI_INVALID_PARAMETER;
+  }
+
+  return Status;
+}
+/**
+  Provides software reset for the USB host controller.
+
+  @param  This                  This EFI_USB_HC_PROTOCOL instance.
+  @param  Attributes            A bit mask of the reset operation to perform.
+
+  @retval EFI_SUCCESS           The reset operation succeeded.
+  @retval EFI_INVALID_PARAMETER Attributes is not valid.
+  @retval EFI_UNSUPPOURTED      The type of reset specified by Attributes is
+                                not currently supported by the host controller.
+  @retval EFI_DEVICE_ERROR      Host controller isn't halted to reset.
+
+**/
+EFI_STATUS
+InitializeUsbHC (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN USB_OHCI_HC_DEV            *Ohc,
+  IN UINT16                     Attributes
+  )
+{
+  EFI_STATUS              Status;
+  UINT8                   Index;
+  UINT8                   NumOfPorts;
+  UINT32                  PowerOnGoodTime;
+  UINT32                  Data32;
+  BOOLEAN                 Flag = FALSE;
+
+  if ((Attributes & ~(EFI_USB_HC_RESET_GLOBAL | EFI_USB_HC_RESET_HOST_CONTROLLER)) != 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+  Status = EFI_SUCCESS;
+
+  if ((Attributes & EFI_USB_HC_RESET_HOST_CONTROLLER) != 0) {
+    MicroSecondDelay (50 * HC_1_MILLISECOND);
+    Status = OhciSetHcCommandStatus (Ohc, HC_RESET, HC_RESET);
+    if (EFI_ERROR (Status)) {
+      return EFI_DEVICE_ERROR;
+    }
+    MicroSecondDelay (50 * HC_1_MILLISECOND);
+    //
+    // Wait for host controller reset.
+    //
+    PowerOnGoodTime = 50;
+    do {
+      MicroSecondDelay (HC_1_MILLISECOND);
+      Data32 = OhciGetOperationalReg (Ohc, HC_COMMAND_STATUS );
+      if ((Data32 & HC_RESET) == 0) {
+        Flag = TRUE;
+        break;
+      }
+    }while(PowerOnGoodTime--);
+    if (!Flag){
+      return EFI_DEVICE_ERROR;
+    }
+  }
+
+  OhciSetFrameInterval (Ohc, FRAME_INTERVAL, 0x2edf);
+  if ((Attributes &  EFI_USB_HC_RESET_GLOBAL) != 0) {
+    Status = OhciSetHcControl (Ohc, HC_FUNCTIONAL_STATE, HC_STATE_RESET);
+    if (EFI_ERROR (Status)) {
+      return EFI_DEVICE_ERROR;
+    }
+    MicroSecondDelay (50 * HC_1_MILLISECOND);
+  }
+  //
+  // Initialize host controller operational registers
+  //
+  OhciSetFrameInterval (Ohc, FS_LARGEST_DATA_PACKET, 0x2778);
+  OhciSetFrameInterval (Ohc, FRAME_INTERVAL, 0x2edf);
+  OhciSetPeriodicStart (Ohc, 0x2a2f);
+  OhciSetHcControl (Ohc, CONTROL_BULK_RATIO, 0x0);
+  OhciSetHcCommandStatus (Ohc, CONTROL_LIST_FILLED | BULK_LIST_FILLED, 0);
+  OhciSetRootHubDescriptor (Ohc, RH_PSWITCH_MODE, 0);
+  OhciSetRootHubDescriptor (Ohc, RH_NO_PSWITCH | RH_NOC_PROT, 1);
+  //OhciSetRootHubDescriptor (Hc, RH_PSWITCH_MODE | RH_NO_PSWITCH, 0);
+  //OhciSetRootHubDescriptor (Hc, RH_PSWITCH_MODE | RH_NOC_PROT, 1);
+
+  OhciSetRootHubDescriptor (Ohc, RH_DEV_REMOVABLE, 0);
+  OhciSetRootHubDescriptor (Ohc, RH_PORT_PWR_CTRL_MASK, 0xffff);
+  OhciSetRootHubStatus (Ohc, RH_LOCAL_PSTAT_CHANGE);
+  OhciSetRootHubPortStatus (Ohc, 0, RH_SET_PORT_POWER);
+  OhciGetRootHubNumOfPorts (PeiServices, &Ohc->UsbHostControllerPpi, &NumOfPorts);
+  for (Index = 0; Index < NumOfPorts; Index++) {
+    if (!EFI_ERROR (OhciSetRootHubPortFeature (PeiServices, &Ohc->UsbHostControllerPpi, Index, EfiUsbPortReset))) {
+      MicroSecondDelay (200 * HC_1_MILLISECOND);
+      OhciClearRootHubPortFeature (PeiServices, &Ohc->UsbHostControllerPpi, Index, EfiUsbPortReset);
+      MicroSecondDelay (HC_1_MILLISECOND);
+      OhciSetRootHubPortFeature (PeiServices, &Ohc->UsbHostControllerPpi, Index, EfiUsbPortEnable);
+      MicroSecondDelay (HC_1_MILLISECOND);
+    }
+  }
+
+  Ohc->MemPool = UsbHcInitMemPool(TRUE, 0);
+  if(Ohc->MemPool == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  OhciSetMemoryPointer (Ohc, HC_CONTROL_HEAD, NULL);
+  OhciSetMemoryPointer (Ohc, HC_BULK_HEAD, NULL);
+  OhciSetHcControl (Ohc, CONTROL_ENABLE | BULK_ENABLE, 1);
+  OhciSetHcControl (Ohc, HC_FUNCTIONAL_STATE, HC_STATE_OPERATIONAL);
+  MicroSecondDelay (50 * HC_1_MILLISECOND);
+  //
+  // Wait till first SOF occurs, and then clear it
+  //
+  while (OhciGetHcInterruptStatus (Ohc, START_OF_FRAME) == 0);
+  OhciClearInterruptStatus (Ohc, START_OF_FRAME);
+  MicroSecondDelay (HC_1_MILLISECOND);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Submits control transfer to a target USB device.
+
+  Calls underlying OhciControlTransfer to do work. This wrapper routine required
+  on Quark so that USB DMA transfers do not cause an IMR violation.
+
+  @param  PeiServices            The pointer of EFI_PEI_SERVICES.
+  @param  This                   The pointer of PEI_USB_HOST_CONTROLLER_PPI.
+  @param  DeviceAddress          The target device address.
+  @param  DeviceSpeed            Target device speed.
+  @param  MaximumPacketLength    Maximum packet size the default control transfer
+                                 endpoint is capable of sending or receiving.
+  @param  Request                USB device request to send.
+  @param  TransferDirection      Specifies the data direction for the data stage.
+  @param  Data                   Data buffer to be transmitted or received from USB device.
+  @param  DataLength             The size (in bytes) of the data buffer.
+  @param  TimeOut                Indicates the maximum timeout, in millisecond.
+  @param  TransferResult         Return the result of this control transfer.
+
+  @retval EFI_SUCCESS            Transfer was completed successfully.
+  @retval EFI_OUT_OF_RESOURCES   The transfer failed due to lack of resources.
+  @retval EFI_INVALID_PARAMETER  Some parameters are invalid.
+  @retval EFI_TIMEOUT            Transfer failed due to timeout.
+  @retval EFI_DEVICE_ERROR       Transfer failed due to host controller or device error.
+
+**/
+EFI_STATUS
+EFIAPI
+RedirectOhciControlTransfer (
+  IN  EFI_PEI_SERVICES             **PeiServices,
+  IN  PEI_USB_HOST_CONTROLLER_PPI  *This,
+  IN  UINT8                        DeviceAddress,
+  IN  UINT8                        DeviceSpeed,
+  IN  UINT8                        MaxPacketLength,
+  IN  EFI_USB_DEVICE_REQUEST       *Request,
+  IN  EFI_USB_DATA_DIRECTION       TransferDirection,
+  IN  OUT VOID                     *Data,
+  IN  OUT UINTN                    *DataLength,
+  IN  UINTN                        TimeOut,
+  OUT UINT32                       *TransferResult
+  )
+{
+  EFI_STATUS              Status;
+  EFI_USB_DEVICE_REQUEST  *NewRequest;
+  VOID                    *NewData;
+  UINT8                   *Alloc;
+
+  //
+  // Allocate memory external to IMR protected region for transfer data.
+  //
+  Status = PeiServicesAllocatePool (
+                             sizeof(EFI_USB_DEVICE_REQUEST) + *DataLength,
+                             (VOID **) &Alloc
+                             );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Setup pointers to transfer buffers.
+  //
+  NewRequest = (EFI_USB_DEVICE_REQUEST *) Alloc;
+  Alloc += sizeof(EFI_USB_DEVICE_REQUEST);
+  NewData = (VOID *) Alloc;
+
+  //
+  // Copy callers request packet into transfer request packet.
+  //
+  if (Request != NULL) {
+    CopyMem (NewRequest,Request,sizeof(EFI_USB_DEVICE_REQUEST));
+  } else {
+    NewRequest = NULL;
+  }
+  //
+  // Copy callers data into transfer data buffer.
+  //
+  if (Data != NULL) {
+    if (DataLength > 0) {
+      CopyMem (NewData,Data,*DataLength);
+    }
+  } else {
+    NewData = NULL;
+  }
+
+  //
+  // Call underlying OhciControlTransfer to do work.
+  //
+  Status = OhciControlTransfer (
+             PeiServices,
+             This,
+             DeviceAddress,
+             DeviceSpeed,
+             MaxPacketLength,
+             NewRequest,
+             TransferDirection,
+             NewData,
+             DataLength,
+             TimeOut,
+             TransferResult
+             );
+
+  //
+  // Copy transfer buffer back into callers buffer.
+  //
+  if (Data != NULL && *DataLength > 0) {
+    CopyMem (Data, NewData, *DataLength);
+  }
+
+  return Status;
+}
+
+/**
+  Submits bulk transfer to a bulk endpoint of a USB device.
+
+  Calls underlying OhciBulkTransfer to do work. This wrapper routine required
+  on Quark so that USB DMA transfers do not cause an IMR violation.
+
+  @param  PeiServices           The pointer of EFI_PEI_SERVICES.
+  @param  This                  The pointer of PEI_USB_HOST_CONTROLLER_PPI.
+  @param  DeviceAddress         Target device address.
+  @param  EndPointAddress       Endpoint number and its direction in bit 7.
+  @param  MaxiPacketLength      Maximum packet size the endpoint is capable of
+                                sending or receiving.
+  @param  Data                  A pointers to the buffers of data to transmit
+                                from or receive into.
+  @param  DataLength            The lenght of the data buffer.
+  @param  DataToggle            On input, the initial data toggle for the transfer;
+                                On output, it is updated to to next data toggle to use of
+                                the subsequent bulk transfer.
+  @param  TimeOut               Indicates the maximum time, in millisecond, which the
+                                transfer is allowed to complete.
+  @param  TransferResult        A pointer to the detailed result information of the
+                                bulk transfer.
+
+  @retval EFI_SUCCESS           The transfer was completed successfully.
+  @retval EFI_OUT_OF_RESOURCES  The transfer failed due to lack of resource.
+  @retval EFI_INVALID_PARAMETER Parameters are invalid.
+  @retval EFI_TIMEOUT           The transfer failed due to timeout.
+  @retval EFI_DEVICE_ERROR      The transfer failed due to host controller error.
+
+**/
+EFI_STATUS
+EFIAPI
+RedirectOhciBulkTransfer (
+  IN EFI_PEI_SERVICES             **PeiServices,
+  IN PEI_USB_HOST_CONTROLLER_PPI  *This,
+  IN  UINT8                       DeviceAddress,
+  IN  UINT8                       EndPointAddress,
+  IN  UINT8                       MaxPacketLength,
+  IN  OUT VOID                    *Data,
+  IN  OUT UINTN                   *DataLength,
+  IN  OUT UINT8                   *DataToggle,
+  IN  UINTN                       TimeOut,
+  OUT UINT32                      *TransferResult
+  )
+{
+  EFI_STATUS              Status;
+  UINT8                   *NewData;
+
+  //
+  // Allocate memory external to IMR protected region for transfer data.
+  //
+  Status = PeiServicesAllocatePool (
+                             *DataLength,
+                             (VOID **) &NewData
+                             );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Copy callers data into transfer buffer.
+  //
+  if (Data != NULL) {
+    if (DataLength > 0) {
+      CopyMem (NewData,Data,*DataLength);
+    }
+  } else {
+    NewData = NULL;
+  }
+
+  //
+  // Call underlying OhciBulkTransfer to do work.
+  //
+  Status = OhciBulkTransfer (
+             PeiServices,
+             This,
+             DeviceAddress,
+             EndPointAddress,
+             MaxPacketLength,
+             NewData,
+             DataLength,
+             DataToggle,
+             TimeOut,
+             TransferResult
+             );
+
+  //
+  // Copy transfer buffer back into callers buffer.
+  //
+  if (Data != NULL && *DataLength > 0) {
+    CopyMem (Data, NewData, *DataLength);
+  }
+
+  return Status;
+}
+
+/**
+  @param  FileHandle  Handle of the file being invoked.
+  @param  PeiServices Describes the list of possible PEI Services.
+
+  @retval EFI_SUCCESS            PPI successfully installed.
+
+**/
+EFI_STATUS
+OhcPeimEntry (
+  IN EFI_PEI_FILE_HANDLE        FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+
+  PEI_USB_CONTROLLER_PPI  *ChipSetUsbControllerPpi;
+  EFI_STATUS              Status;
+  UINT8                   Index;
+  UINTN                   ControllerType;
+  UINTN                   BaseAddress;
+  UINTN                   MemPages;
+  USB_OHCI_HC_DEV         *Ohc;
+  EFI_PHYSICAL_ADDRESS    TempPtr;
+
+
+  //
+  // Shadow this PEIM to run from memory
+  //
+  if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) {
+    return EFI_SUCCESS;
+  }
+  Status = PeiServicesLocatePpi (
+             &gPeiUsbControllerPpiGuid,
+             0,
+             NULL,
+             (VOID **) &ChipSetUsbControllerPpi
+             );
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Index = 0;
+  while (TRUE) {
+    Status = ChipSetUsbControllerPpi->GetUsbController (
+                                        (EFI_PEI_SERVICES **) PeiServices,
+                                        ChipSetUsbControllerPpi,
+                                        Index,
+                                        &ControllerType,
+                                        &BaseAddress
+                                        );
+    //
+    // When status is error, meant no controller is found
+    //
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+    //
+    // This PEIM is for OHC type controller.
+    //
+    if (ControllerType != PEI_OHCI_CONTROLLER) {
+      Index++;
+      continue;
+    }
+
+    MemPages = sizeof (USB_OHCI_HC_DEV) / PAGESIZE + 1;
+    Status = PeiServicesAllocatePages (
+               EfiBootServicesCode,
+               MemPages,
+               &TempPtr
+               );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((EFI_D_INFO, "OhcPeimEntry: Fail to allocate buffer for the %dth OHCI ControllerPpi\n", Index));
+      return EFI_OUT_OF_RESOURCES;
+    }
+    ZeroMem((VOID *)(UINTN)TempPtr, MemPages*PAGESIZE);
+    Ohc = (USB_OHCI_HC_DEV *) ((UINTN) TempPtr);
+
+    Ohc->Signature = USB_OHCI_HC_DEV_SIGNATURE;
+
+    Ohc->UsbHostControllerBaseAddress = (UINT32) BaseAddress;
+
+    //
+    // Initialize Uhc's hardware
+    //
+    Status = InitializeUsbHC (
+               (EFI_PEI_SERVICES **)PeiServices,
+               Ohc,
+               EFI_USB_HC_RESET_GLOBAL
+               );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((EFI_D_INFO, "OhcPeimEntry: Fail to init %dth OHCI ControllerPpi\n", Index));
+      return Status;
+    }
+    //
+    // Control & Bulk transfer services are accessed via their Redirect
+    // routine versions on Quark so that USB DMA transfers do not cause an
+    // IMR violation.
+    //
+    Ohc->UsbHostControllerPpi.ControlTransfer          = RedirectOhciControlTransfer;
+    Ohc->UsbHostControllerPpi.BulkTransfer             = RedirectOhciBulkTransfer;
+    Ohc->UsbHostControllerPpi.GetRootHubPortNumber     = OhciGetRootHubNumOfPorts;
+    Ohc->UsbHostControllerPpi.GetRootHubPortStatus     = OhciGetRootHubPortStatus;
+    Ohc->UsbHostControllerPpi.SetRootHubPortFeature    = OhciSetRootHubPortFeature;
+    Ohc->UsbHostControllerPpi.ClearRootHubPortFeature  = OhciClearRootHubPortFeature;
+
+    Ohc->PpiDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
+    Ohc->PpiDescriptor.Guid  = &gPeiUsbHostControllerPpiGuid;
+    Ohc->PpiDescriptor.Ppi   = &Ohc->UsbHostControllerPpi;
+
+    Status = PeiServicesInstallPpi (&Ohc->PpiDescriptor);
+    if (EFI_ERROR (Status)) {
+      Index++;
+      continue;
+    }
+    Index++;
+  }
+  return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.h
new file mode 100644
index 0000000000..c34f94cdd7
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.h
@@ -0,0 +1,252 @@
+/** @file
+Provides the definition of Usb Hc Protocol and OHCI controller
+private data structure.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+
+#ifndef _OHCI_PEIM_H
+#define _OHCI_PEIM_H
+
+#include <PiPei.h>
+
+#include <Ppi/UsbController.h>
+#include <Ppi/UsbHostController.h>
+
+#include <Library/DebugLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/TimerLib.h>
+#include <Library/IoLib.h>
+
+typedef struct _USB_OHCI_HC_DEV USB_OHCI_HC_DEV;
+
+#include "UsbHcMem.h"
+#include "OhciReg.h"
+#include "OhciSched.h"
+#include "OhciUrb.h"
+#include "Descriptor.h"
+
+#define EFI_USB_SPEED_FULL 0x0000
+#define EFI_USB_SPEED_LOW  0x0001
+#define EFI_USB_SPEED_HIGH 0x0002
+
+#define PAGESIZE                    4096
+
+#define HC_1_MICROSECOND            1
+#define HC_1_MILLISECOND            (1000 * HC_1_MICROSECOND)
+#define HC_1_SECOND                 (1000 * HC_1_MILLISECOND)
+
+
+#define USB_OHCI_HC_DEV_SIGNATURE   SIGNATURE_32('o','h','c','i')
+
+struct _USB_OHCI_HC_DEV {
+  UINTN                        Signature;
+  PEI_USB_HOST_CONTROLLER_PPI  UsbHostControllerPpi;
+  EFI_PEI_PPI_DESCRIPTOR       PpiDescriptor;
+  UINT32                       UsbHostControllerBaseAddress;
+  VOID                         *MemPool;
+};
+
+#define PEI_RECOVERY_USB_OHC_DEV_FROM_EHCI_THIS(a)  CR (a, USB_OHCI_HC_DEV, UsbHostControllerPpi, USB_OHCI_HC_DEV_SIGNATURE)
+
+//
+// Func List
+//
+
+/**
+  Provides software reset for the USB host controller.
+
+  @param  PeiServices           The pointer of EFI_PEI_SERVICES.
+  @param  This                  The pointer of PEI_USB_HOST_CONTROLLER_PPI.
+  @param  Attributes            A bit mask of the reset operation to perform.
+
+  @retval EFI_SUCCESS           The reset operation succeeded.
+  @retval EFI_INVALID_PARAMETER Attributes is not valid.
+  @retval EFI_UNSUPPOURTED      The type of reset specified by Attributes is
+                                not currently supported by the host controller.
+  @retval EFI_DEVICE_ERROR      Host controller isn't halted to reset.
+
+**/
+EFI_STATUS
+InitializeUsbHC (
+  IN EFI_PEI_SERVICES   **PeiServices,
+  IN USB_OHCI_HC_DEV    *Ohc,
+  IN UINT16             Attributes
+  );
+
+/**
+  Submits control transfer to a target USB device.
+
+  @param  PeiServices            The pointer of EFI_PEI_SERVICES.
+  @param  This                   The pointer of PEI_USB_HOST_CONTROLLER_PPI.
+  @param  DeviceAddress          The target device address.
+  @param  DeviceSpeed            Target device speed.
+  @param  MaximumPacketLength    Maximum packet size the default control transfer
+                                 endpoint is capable of sending or receiving.
+  @param  Request                USB device request to send.
+  @param  TransferDirection      Specifies the data direction for the data stage.
+  @param  Data                   Data buffer to be transmitted or received from USB device.
+  @param  DataLength             The size (in bytes) of the data buffer.
+  @param  TimeOut                Indicates the maximum timeout, in millisecond.
+  @param  TransferResult         Return the result of this control transfer.
+
+  @retval EFI_SUCCESS            Transfer was completed successfully.
+  @retval EFI_OUT_OF_RESOURCES   The transfer failed due to lack of resources.
+  @retval EFI_INVALID_PARAMETER  Some parameters are invalid.
+  @retval EFI_TIMEOUT            Transfer failed due to timeout.
+  @retval EFI_DEVICE_ERROR       Transfer failed due to host controller or device error.
+
+**/
+EFI_STATUS
+EFIAPI
+OhciControlTransfer (
+  IN  EFI_PEI_SERVICES                    **PeiServices,
+  IN  PEI_USB_HOST_CONTROLLER_PPI         *This,
+  IN  UINT8                               DeviceAddress,
+  IN  UINT8                               DeviceSpeed,
+  IN  UINT8                               MaxPacketLength,
+  IN  EFI_USB_DEVICE_REQUEST              *Request,
+  IN  EFI_USB_DATA_DIRECTION              TransferDirection,
+  IN  OUT VOID                            *Data,
+  IN  OUT UINTN                           *DataLength,
+  IN  UINTN                               TimeOut,
+  OUT UINT32                              *TransferResult
+  );
+/**
+  Submits bulk transfer to a bulk endpoint of a USB device.
+
+  @param  PeiServices           The pointer of EFI_PEI_SERVICES.
+  @param  This                  The pointer of PEI_USB_HOST_CONTROLLER_PPI.
+  @param  DeviceAddress         Target device address.
+  @param  EndPointAddress       Endpoint number and its direction in bit 7.
+  @param  MaxiPacketLength      Maximum packet size the endpoint is capable of
+                                sending or receiving.
+  @param  Data                  A pointers to the buffers of data to transmit
+                                from or receive into.
+  @param  DataLength            The lenght of the data buffer.
+  @param  DataToggle            On input, the initial data toggle for the transfer;
+                                On output, it is updated to to next data toggle to use of
+                                the subsequent bulk transfer.
+  @param  TimeOut               Indicates the maximum time, in millisecond, which the
+                                transfer is allowed to complete.
+  @param  TransferResult        A pointer to the detailed result information of the
+                                bulk transfer.
+
+  @retval EFI_SUCCESS           The transfer was completed successfully.
+  @retval EFI_OUT_OF_RESOURCES  The transfer failed due to lack of resource.
+  @retval EFI_INVALID_PARAMETER Parameters are invalid.
+  @retval EFI_TIMEOUT           The transfer failed due to timeout.
+  @retval EFI_DEVICE_ERROR      The transfer failed due to host controller error.
+
+**/
+EFI_STATUS
+EFIAPI
+OhciBulkTransfer (
+  IN EFI_PEI_SERVICES                     **PeiServices,
+  IN PEI_USB_HOST_CONTROLLER_PPI          *This,
+  IN  UINT8                               DeviceAddress,
+  IN  UINT8                               EndPointAddress,
+  IN  UINT8                               MaxPacketLength,
+  IN  OUT VOID                            *Data,
+  IN  OUT UINTN                           *DataLength,
+  IN  OUT UINT8                           *DataToggle,
+  IN  UINTN                               TimeOut,
+  OUT UINT32                              *TransferResult
+  );
+/**
+  Retrieves the number of root hub ports.
+
+  @param[in]  PeiServices       The pointer to the PEI Services Table.
+  @param[in]  This              The pointer to this instance of the
+                                PEI_USB_HOST_CONTROLLER_PPI.
+  @param[out] NumOfPorts        The pointer to the number of the root hub ports.
+
+  @retval EFI_SUCCESS           The port number was retrieved successfully.
+  @retval EFI_INVALID_PARAMETER PortNumber is NULL.
+
+**/
+
+EFI_STATUS
+EFIAPI
+OhciGetRootHubNumOfPorts (
+  IN EFI_PEI_SERVICES                       **PeiServices,
+  IN PEI_USB_HOST_CONTROLLER_PPI           *This,
+  OUT UINT8                *NumOfPorts
+  );
+/**
+  Retrieves the current status of a USB root hub port.
+
+  @param  PeiServices            The pointer of EFI_PEI_SERVICES.
+  @param  This                   The pointer of PEI_USB_HOST_CONTROLLER_PPI.
+  @param  PortNumber             The root hub port to retrieve the state from.
+  @param  PortStatus             Variable to receive the port state.
+
+  @retval EFI_SUCCESS            The status of the USB root hub port specified.
+                                 by PortNumber was returned in PortStatus.
+  @retval EFI_INVALID_PARAMETER  PortNumber is invalid.
+
+**/
+
+EFI_STATUS
+EFIAPI
+OhciGetRootHubPortStatus (
+  IN  EFI_PEI_SERVICES             **PeiServices,
+  IN  PEI_USB_HOST_CONTROLLER_PPI  *This,
+  IN  UINT8                        PortNumber,
+  OUT EFI_USB_PORT_STATUS          *PortStatus
+  );
+/**
+
+  Sets a feature for the specified root hub port.
+
+  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL.
+  @param  PortNumber            Specifies the root hub port whose feature
+                                is requested to be set.
+  @param  PortFeature           Indicates the feature selector associated
+                                with the feature set request.
+
+  @retval EFI_SUCCESS           The feature specified by PortFeature was set for the
+                                USB root hub port specified by PortNumber.
+  @retval EFI_DEVICE_ERROR      Set feature failed because of hardware issue
+  @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
+**/
+EFI_STATUS
+EFIAPI
+OhciSetRootHubPortFeature (
+  IN EFI_PEI_SERVICES             **PeiServices,
+  IN PEI_USB_HOST_CONTROLLER_PPI  *This,
+  IN UINT8                        PortNumber,
+  IN EFI_USB_PORT_FEATURE         PortFeature
+  );
+/**
+  Clears a feature for the specified root hub port.
+
+  @param  PeiServices           The pointer of EFI_PEI_SERVICES.
+  @param  This                  The pointer of PEI_USB_HOST_CONTROLLER_PPI.
+  @param  PortNumber            Specifies the root hub port whose feature
+                                is requested to be cleared.
+  @param  PortFeature           Indicates the feature selector associated with the
+                                feature clear request.
+
+  @retval EFI_SUCCESS            The feature specified by PortFeature was cleared
+                                 for the USB root hub port specified by PortNumber.
+  @retval EFI_INVALID_PARAMETER  PortNumber is invalid or PortFeature is invalid.
+
+**/
+
+EFI_STATUS
+EFIAPI
+OhciClearRootHubPortFeature (
+  IN EFI_PEI_SERVICES             **PeiServices,
+  IN PEI_USB_HOST_CONTROLLER_PPI  *This,
+  IN UINT8                        PortNumber,
+  IN EFI_USB_PORT_FEATURE         PortFeature
+  );
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciPei.inf b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciPei.inf
new file mode 100644
index 0000000000..b1060d527d
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciPei.inf
@@ -0,0 +1,56 @@
+## @file
+# OHCI USB Host Controller PEIM
+#
+# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = OhciPei
+  FILE_GUID                      = 332A0926-429B-4624-9211-A36B23DF0389
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = OhcPeimEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  Descriptor.h
+  OhcPeim.c
+  OhcPeim.h
+  OhciSched.c
+  OhciSched.h
+  OhciReg.c
+  OhciReg.h
+  OhciUrb.c
+  OhciUrb.h
+  UsbHcMem.c
+  UsbHcMem.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  IoLib
+  TimerLib
+  BaseMemoryLib
+  PeimEntryPoint
+  PeiServicesLib
+
+[Ppis]
+  gPeiUsbHostControllerPpiGuid                 # PPI ALWAYS_PRODUCED
+  gPeiUsbControllerPpiGuid                      # PPI ALWAYS_CONSUMED
+
+[Depex]
+  gEfiPeiMemoryDiscoveredPpiGuid AND gPeiUsbControllerPpiGuid AND gEfiPeiBootInRecoveryModePpiGuid
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.c
new file mode 100644
index 0000000000..b291cdafa6
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.c
@@ -0,0 +1,1386 @@
+/** @file
+The OHCI register operation routines.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "OhcPeim.h"
+
+/**
+
+  Get OHCI operational reg value
+
+  @param  Ohc                   UHC private data
+  @param  Offset                Offset of the operational reg
+
+  @retval                       Value of the register
+
+**/
+UINT32
+OhciGetOperationalReg (
+  IN USB_OHCI_HC_DEV         *Ohc,
+  IN UINT32                  Offset
+  )
+{
+
+  return MmioRead32 (Ohc->UsbHostControllerBaseAddress + Offset);
+
+}
+/**
+
+  Set OHCI operational reg value
+
+  @param  Ohc                   UHC private data
+  @param  Offset                 Offset of the operational reg
+  @param  Value                  Value to set
+
+  @retval EFI_SUCCESS            Value set to the reg
+
+**/
+
+
+EFI_STATUS
+OhciSetOperationalReg (
+  USB_OHCI_HC_DEV         *Ohc,
+  IN UINT32               Offset,
+  IN UINT32               *Value
+  )
+{
+  MmioWrite32(Ohc->UsbHostControllerBaseAddress + Offset, *Value);
+  return EFI_SUCCESS;
+}
+/**
+
+  Get HcRevision reg value
+
+  @param  Ohc                   UHC private data
+
+  @retval                       Value of the register
+
+**/
+
+
+UINT32
+OhciGetHcRevision (
+  USB_OHCI_HC_DEV         *Ohc
+  )
+{
+  return OhciGetOperationalReg (Ohc, HC_REVISION);
+}
+/**
+
+  Set HcReset reg value
+
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval EFI_SUCCESS           Value set
+
+**/
+
+EFI_STATUS
+OhciSetHcReset (
+  IN USB_OHCI_HC_DEV            *Ohc,
+  IN UINT32                     Field,
+  IN UINT32                     Value
+  )
+{
+  HcRESET                       Reset;
+
+  *(UINT32 *) &Reset = OhciGetOperationalReg (Ohc, USBHOST_OFFSET_UHCHR);
+
+  if (Field & RESET_SYSTEM_BUS) {
+    Reset.FSBIR = Value;
+  }
+
+  if (Field & RESET_HOST_CONTROLLER) {
+    Reset.FHR = Value;
+  }
+
+  if (Field & RESET_CLOCK_GENERATION) {
+    Reset.CGR = Value;
+  }
+
+  if (Field & RESET_SSE_GLOBAL) {
+    Reset.SSE = Value;
+  }
+
+  if (Field & RESET_PSPL) {
+    Reset.PSPL = Value;
+  }
+
+  if (Field & RESET_PCPL) {
+    Reset.PCPL = Value;
+  }
+
+  if (Field & RESET_SSEP1) {
+    Reset.SSEP1 = Value;
+  }
+
+  if (Field & RESET_SSEP2) {
+    Reset.SSEP2 = Value;
+  }
+
+  if (Field & RESET_SSEP3) {
+    Reset.SSEP3 = Value;
+  }
+
+  OhciSetOperationalReg (Ohc, USBHOST_OFFSET_UHCHR, (UINT32*)&Reset);
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Get specific field of HcReset reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetHcReset (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Field
+  )
+{
+  HcRESET                 Reset;
+  UINT32                  Value;
+
+
+  *(UINT32 *) &Reset = OhciGetOperationalReg (Ohc, USBHOST_OFFSET_UHCHR);
+  Value = 0;
+
+  switch (Field) {
+  case RESET_SYSTEM_BUS:
+    Value = Reset.FSBIR;
+    break;
+
+  case RESET_HOST_CONTROLLER:
+    Value = Reset.FHR;
+    break;
+
+  case RESET_CLOCK_GENERATION:
+    Value = Reset.CGR;
+    break;
+
+  case RESET_SSE_GLOBAL:
+    Value = Reset.SSE;
+    break;
+
+  case RESET_PSPL:
+    Value = Reset.PSPL;
+    break;
+
+  case RESET_PCPL:
+    Value = Reset.PCPL;
+    break;
+
+  case RESET_SSEP1:
+    Value = Reset.SSEP1;
+    break;
+
+  case RESET_SSEP2:
+    Value = Reset.SSEP2;
+    break;
+
+  case RESET_SSEP3:
+    Value = Reset.SSEP3;
+    break;
+
+  default:
+    ASSERT (FALSE);
+  }
+
+
+  return Value;
+}
+
+/**
+
+  Set HcControl reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetHcControl (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field,
+  IN UINT32               Value
+  )
+{
+  EFI_STATUS              Status;
+  HcCONTROL               Control;
+
+
+
+  *(UINT32 *) &Control = OhciGetOperationalReg (Ohc, HC_CONTROL);
+
+  if (Field & CONTROL_BULK_RATIO) {
+    Control.ControlBulkRatio = Value;
+  }
+
+  if (Field & HC_FUNCTIONAL_STATE) {
+    Control.FunctionalState = Value;
+  }
+
+  if (Field & PERIODIC_ENABLE) {
+    Control.PeriodicEnable = Value;
+  }
+
+  if (Field & CONTROL_ENABLE) {
+    Control.ControlEnable = Value;
+  }
+
+  if (Field & ISOCHRONOUS_ENABLE) {
+    Control.IsochronousEnable = Value;
+  }
+
+  if (Field & BULK_ENABLE) {
+    Control.BulkEnable = Value;
+  }
+
+  if (Field & INTERRUPT_ROUTING) {
+    Control.InterruptRouting = Value;
+  }
+
+  Status = OhciSetOperationalReg (Ohc, HC_CONTROL, (UINT32*)&Control);
+
+  return Status;
+}
+
+
+/**
+
+  Get specific field of HcControl reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+
+UINT32
+OhciGetHcControl (
+  IN USB_OHCI_HC_DEV   *Ohc,
+  IN UINTN             Field
+  )
+{
+  HcCONTROL     Control;
+
+  *(UINT32 *) &Control = OhciGetOperationalReg (Ohc, HC_CONTROL);
+
+  switch (Field) {
+  case CONTROL_BULK_RATIO:
+    return Control.ControlBulkRatio;
+    break;
+  case PERIODIC_ENABLE:
+    return Control.PeriodicEnable;
+    break;
+  case CONTROL_ENABLE:
+    return Control.ControlEnable;
+    break;
+  case BULK_ENABLE:
+    return Control.BulkEnable;
+    break;
+  case ISOCHRONOUS_ENABLE:
+    return Control.IsochronousEnable;
+    break;
+  case HC_FUNCTIONAL_STATE:
+    return Control.FunctionalState;
+    break;
+  case INTERRUPT_ROUTING:
+    return Control.InterruptRouting;
+    break;
+  default:
+    ASSERT (FALSE);
+  }
+
+  return 0;
+}
+
+/**
+
+  Set HcCommand reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval EFI_SUCCESS           Value set
+
+**/
+
+EFI_STATUS
+OhciSetHcCommandStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field,
+  IN UINT32               Value
+  )
+{
+  EFI_STATUS              Status;
+  HcCOMMAND_STATUS        CommandStatus;
+
+  ZeroMem (&CommandStatus, sizeof (HcCOMMAND_STATUS));
+
+  if(Field & HC_RESET){
+    CommandStatus.HcReset = Value;
+  }
+
+  if(Field & CONTROL_LIST_FILLED){
+    CommandStatus.ControlListFilled = Value;
+  }
+
+  if(Field & BULK_LIST_FILLED){
+    CommandStatus.BulkListFilled = Value;
+  }
+
+  if(Field & CHANGE_OWNER_REQUEST){
+    CommandStatus.ChangeOwnerRequest = Value;
+  }
+
+  if(Field & SCHEDULE_OVERRUN_COUNT){
+    CommandStatus.ScheduleOverrunCount = Value;
+  }
+
+  Status = OhciSetOperationalReg (Ohc, HC_COMMAND_STATUS, (UINT32*)&CommandStatus);
+
+  return Status;
+}
+
+/**
+
+  Get specific field of HcCommand reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetHcCommandStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  )
+{
+  HcCOMMAND_STATUS        CommandStatus;
+
+  *(UINT32 *) &CommandStatus = OhciGetOperationalReg (Ohc, HC_COMMAND_STATUS);
+
+  switch (Field){
+  case HC_RESET:
+    return CommandStatus.HcReset;
+    break;
+  case CONTROL_LIST_FILLED:
+    return CommandStatus.ControlListFilled;
+    break;
+  case BULK_LIST_FILLED:
+    return CommandStatus.BulkListFilled;
+    break;
+  case CHANGE_OWNER_REQUEST:
+    return CommandStatus.ChangeOwnerRequest;
+    break;
+  case SCHEDULE_OVERRUN_COUNT:
+    return CommandStatus.ScheduleOverrunCount;
+    break;
+  default:
+    ASSERT (FALSE);
+  }
+
+  return 0;
+}
+
+/**
+
+  Clear specific fields of Interrupt Status
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to clear
+
+  @retval EFI_SUCCESS           Fields cleared
+
+**/
+
+EFI_STATUS
+OhciClearInterruptStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  )
+{
+  EFI_STATUS              Status;
+  HcINTERRUPT_STATUS      InterruptStatus;
+
+  ZeroMem (&InterruptStatus, sizeof (HcINTERRUPT_STATUS));
+
+  if(Field & SCHEDULE_OVERRUN){
+    InterruptStatus.SchedulingOverrun = 1;
+  }
+
+  if(Field & WRITEBACK_DONE_HEAD){
+    InterruptStatus.WriteBackDone = 1;
+  }
+  if(Field & START_OF_FRAME){
+    InterruptStatus.Sof = 1;
+  }
+
+  if(Field & RESUME_DETECT){
+    InterruptStatus.ResumeDetected = 1;
+  }
+
+  if(Field & UNRECOVERABLE_ERROR){
+    InterruptStatus.UnrecoverableError = 1;
+  }
+
+  if(Field & FRAME_NUMBER_OVERFLOW){
+    InterruptStatus.FrameNumOverflow = 1;
+  }
+
+  if(Field & ROOTHUB_STATUS_CHANGE){
+    InterruptStatus.RHStatusChange = 1;
+  }
+
+  if(Field & OWNERSHIP_CHANGE){
+    InterruptStatus.OwnerChange = 1;
+  }
+
+  Status = OhciSetOperationalReg (Ohc, HC_INTERRUPT_STATUS, (UINT32*)&InterruptStatus);
+
+  return Status;
+}
+
+/**
+
+  Get fields of HcInterrupt reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetHcInterruptStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  )
+{
+  HcINTERRUPT_STATUS      InterruptStatus;
+
+  *(UINT32 *) &InterruptStatus = OhciGetOperationalReg (Ohc, HC_INTERRUPT_STATUS);
+
+  switch (Field){
+  case SCHEDULE_OVERRUN:
+    return InterruptStatus.SchedulingOverrun;
+    break;
+
+  case  WRITEBACK_DONE_HEAD:
+    return InterruptStatus.WriteBackDone;
+    break;
+
+  case START_OF_FRAME:
+    return InterruptStatus.Sof;
+    break;
+
+  case RESUME_DETECT:
+    return InterruptStatus.ResumeDetected;
+    break;
+
+  case UNRECOVERABLE_ERROR:
+    return InterruptStatus.UnrecoverableError;
+    break;
+
+  case FRAME_NUMBER_OVERFLOW:
+    return InterruptStatus.FrameNumOverflow;
+    break;
+
+  case ROOTHUB_STATUS_CHANGE:
+    return InterruptStatus.RHStatusChange;
+    break;
+
+  case OWNERSHIP_CHANGE:
+    return InterruptStatus.OwnerChange;
+    break;
+
+  default:
+    ASSERT (FALSE);
+  }
+
+  return 0;
+}
+
+/**
+
+  Set Interrupt Control reg value
+
+  @param  Ohc                   UHC private data
+  @param  StatEnable            Enable or Disable
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval EFI_SUCCESS           Value set
+
+**/
+
+EFI_STATUS
+OhciSetInterruptControl (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN BOOLEAN              StatEnable,
+  IN UINTN                Field,
+  IN UINT32               Value
+  )
+{
+  EFI_STATUS              Status;
+  HcINTERRUPT_CONTROL     InterruptState;
+
+
+  ZeroMem (&InterruptState, sizeof (HcINTERRUPT_CONTROL));
+
+  if(Field & SCHEDULE_OVERRUN) {
+    InterruptState.SchedulingOverrunInt = Value;
+  }
+
+  if(Field & WRITEBACK_DONE_HEAD) {
+    InterruptState.WriteBackDoneInt = Value;
+  }
+  if(Field & START_OF_FRAME) {
+    InterruptState.SofInt = Value;
+  }
+
+  if(Field & RESUME_DETECT) {
+    InterruptState.ResumeDetectedInt = Value;
+  }
+
+  if(Field & UNRECOVERABLE_ERROR) {
+    InterruptState.UnrecoverableErrorInt = Value;
+  }
+
+  if(Field & FRAME_NUMBER_OVERFLOW) {
+    InterruptState.FrameNumOverflowInt = Value;
+  }
+
+  if(Field & ROOTHUB_STATUS_CHANGE) {
+    InterruptState.RHStatusChangeInt = Value;
+  }
+
+  if(Field & OWNERSHIP_CHANGE) {
+    InterruptState.OwnerChangedInt = Value;
+  }
+
+  if(Field & MASTER_INTERRUPT) {
+    InterruptState.MasterInterruptEnable = Value;
+  }
+
+  if (StatEnable) {
+    Status = OhciSetOperationalReg (Ohc, HC_INTERRUPT_ENABLE, (UINT32*)&InterruptState);
+  } else {
+    Status = OhciSetOperationalReg (Ohc, HC_INTERRUPT_DISABLE, (UINT32*)&InterruptState);
+  }
+
+  return Status;
+}
+
+/**
+
+  Get field of HcInterruptControl reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetHcInterruptControl (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  )
+{
+  HcINTERRUPT_CONTROL     InterruptState;
+
+  *(UINT32 *) &InterruptState = OhciGetOperationalReg (Ohc, HC_INTERRUPT_ENABLE);
+
+  switch (Field){
+    case SCHEDULE_OVERRUN:
+      return InterruptState.SchedulingOverrunInt;
+      break;
+
+    case WRITEBACK_DONE_HEAD:
+      return InterruptState.WriteBackDoneInt;
+      break;
+
+    case START_OF_FRAME:
+      return InterruptState.SofInt;
+      break;
+
+    case RESUME_DETECT:
+      return InterruptState.ResumeDetectedInt;
+      break;
+
+    case UNRECOVERABLE_ERROR:
+      return InterruptState.UnrecoverableErrorInt;
+      break;
+
+    case FRAME_NUMBER_OVERFLOW:
+      return InterruptState.FrameNumOverflowInt;
+      break;
+
+    case ROOTHUB_STATUS_CHANGE:
+      return InterruptState.RHStatusChangeInt;
+      break;
+
+    case OWNERSHIP_CHANGE:
+      return InterruptState.OwnerChangedInt;
+      break;
+
+    case MASTER_INTERRUPT:
+      return InterruptState.MasterInterruptEnable;
+      break;
+
+    default:
+      ASSERT (FALSE);
+  }
+
+  return 0;
+}
+
+/**
+
+  Set memory pointer of specific type
+
+  @param  Ohc                   UHC private data
+  @param  PointerType           Type of the pointer to set
+  @param  Value                 Value to set
+
+  @retval EFI_SUCCESS           Memory pointer set
+
+**/
+
+EFI_STATUS
+OhciSetMemoryPointer(
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                PointerType,
+  IN VOID                 *Value
+  )
+{
+  EFI_STATUS              Status;
+  UINT32                  Verify;
+
+  Status = OhciSetOperationalReg (Ohc, PointerType, (UINT32*)&Value);
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Verify = OhciGetOperationalReg (Ohc, PointerType);
+
+  while (Verify != (UINT32) Value) {
+    MicroSecondDelay (HC_1_MILLISECOND);
+    Verify = OhciGetOperationalReg (Ohc, PointerType);
+  };
+
+
+  return Status;
+}
+
+/**
+
+  Get memory pointer of specific type
+
+  @param  Ohc                   UHC private data
+  @param  PointerType           Type of pointer
+
+  @retval                       Memory pointer of the specific type
+
+**/
+
+VOID *
+OhciGetMemoryPointer (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                PointerType
+  )
+{
+
+  return (VOID *) OhciGetOperationalReg (Ohc, PointerType);
+}
+
+
+/**
+
+  Set Frame Interval value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetFrameInterval (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field,
+  IN UINT32               Value
+  )
+{
+  EFI_STATUS              Status;
+  HcFRM_INTERVAL          FrameInterval;
+
+
+  *(UINT32 *) &FrameInterval = OhciGetOperationalReg(Ohc, HC_FRM_INTERVAL);
+
+  if (Field & FRAME_INTERVAL) {
+    FrameInterval.FrmIntervalToggle = !FrameInterval.FrmIntervalToggle;
+    FrameInterval.FrameInterval = Value;
+  }
+
+  if (Field & FS_LARGEST_DATA_PACKET) {
+    FrameInterval.FSMaxDataPacket = Value;
+  }
+
+  if (Field & FRMINT_TOGGLE) {
+    FrameInterval.FrmIntervalToggle = Value;
+  }
+
+  Status = OhciSetOperationalReg (
+             Ohc,
+             HC_FRM_INTERVAL,
+             (UINT32*)&FrameInterval
+             );
+
+  return Status;
+}
+
+
+/**
+
+  Get field of frame interval reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetFrameInterval (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  )
+{
+  HcFRM_INTERVAL          FrameInterval;
+
+  *(UINT32 *) &FrameInterval = OhciGetOperationalReg (Ohc, HC_FRM_INTERVAL);
+
+  switch (Field){
+    case FRAME_INTERVAL:
+      return FrameInterval.FrameInterval;
+      break;
+
+    case FS_LARGEST_DATA_PACKET:
+      return FrameInterval.FSMaxDataPacket;
+      break;
+
+    case FRMINT_TOGGLE:
+      return FrameInterval.FrmIntervalToggle;
+      break;
+
+    default:
+      ASSERT (FALSE);
+  }
+
+  return 0;
+}
+
+/**
+
+  Set Frame Remaining reg value
+
+  @param  Ohc                   UHC private data
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetFrameRemaining (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Value
+  )
+{
+  EFI_STATUS              Status;
+  HcFRAME_REMAINING       FrameRemaining;
+
+
+  *(UINT32 *) &FrameRemaining = OhciGetOperationalReg (Ohc, HC_FRM_REMAINING);
+
+  FrameRemaining.FrameRemaining = Value;
+  FrameRemaining.FrameRemainingToggle = !FrameRemaining.FrameRemainingToggle;
+
+  Status = OhciSetOperationalReg (Ohc, HC_FRM_REMAINING, (UINT32*)&FrameRemaining);
+
+  return Status;
+}
+/**
+
+  Get value of frame remaining reg
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of frame remaining reg
+
+**/
+UINT32
+OhciGetFrameRemaining (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  )
+
+{
+  HcFRAME_REMAINING       FrameRemaining;
+
+
+  *(UINT32 *) &FrameRemaining = OhciGetOperationalReg (Ohc, HC_FRM_REMAINING);
+
+  switch (Field){
+    case FRAME_REMAINING:
+      return FrameRemaining.FrameRemaining;
+      break;
+
+    case FRAME_REMAIN_TOGGLE:
+      return FrameRemaining.FrameRemainingToggle;
+      break;
+
+    default:
+      ASSERT (FALSE);
+  }
+
+  return 0;
+}
+
+/**
+
+  Set frame number reg value
+
+  @param  Ohc                   UHC private data
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetFrameNumber(
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Value
+  )
+{
+  EFI_STATUS              Status;
+
+  Status = OhciSetOperationalReg (Ohc, HC_FRM_NUMBER, &Value);
+
+  return Status;
+}
+
+/**
+
+  Get frame number reg value
+
+  @param  Ohc                   UHC private data
+
+  @retval                       Value of frame number reg
+
+**/
+
+UINT32
+OhciGetFrameNumber (
+  IN USB_OHCI_HC_DEV      *Ohc
+  )
+{
+  return OhciGetOperationalReg(Ohc, HC_FRM_NUMBER);
+}
+
+/**
+
+  Set period start reg value
+
+  @param  Ohc                   UHC private data
+  @param  Value                 Value to set
+
+  @retval EFI_SUCCESS           Value set
+
+**/
+
+EFI_STATUS
+OhciSetPeriodicStart (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Value
+  )
+{
+  EFI_STATUS              Status;
+
+
+  Status = OhciSetOperationalReg (Ohc, HC_PERIODIC_START, &Value);
+
+  return Status;
+}
+
+
+/**
+
+  Get periodic start reg value
+
+  @param  Ohc                   UHC private data
+
+  @param                        Value of periodic start reg
+
+**/
+
+UINT32
+OhciGetPeriodicStart (
+  IN USB_OHCI_HC_DEV      *Ohc
+  )
+{
+  return OhciGetOperationalReg(Ohc, HC_PERIODIC_START);
+}
+
+
+/**
+
+  Set Ls Threshold reg value
+
+  @param  Ohc                   UHC private data
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetLsThreshold (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Value
+  )
+{
+  EFI_STATUS              Status;
+
+
+  Status = OhciSetOperationalReg (Ohc, HC_LS_THREASHOLD, &Value);
+
+  return Status;
+}
+
+
+/**
+
+  Get Ls Threshold reg value
+
+  @param  Ohc                   UHC private data
+
+  @retval                       Value of Ls Threshold reg
+
+**/
+
+UINT32
+OhciGetLsThreshold (
+  IN USB_OHCI_HC_DEV      *Ohc
+  )
+{
+  return OhciGetOperationalReg(Ohc, HC_LS_THREASHOLD);
+}
+
+/**
+
+  Set Root Hub Descriptor reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+EFI_STATUS
+OhciSetRootHubDescriptor (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field,
+  IN UINT32               Value
+  )
+{
+  EFI_STATUS              Status;
+  HcRH_DESC_A             DescriptorA;
+  HcRH_DESC_B             DescriptorB;
+
+
+  if (Field & (RH_DEV_REMOVABLE || RH_PORT_PWR_CTRL_MASK)) {
+    *(UINT32 *) &DescriptorB = OhciGetOperationalReg (Ohc, HC_RH_DESC_B);
+
+    if(Field & RH_DEV_REMOVABLE) {
+      DescriptorB.DeviceRemovable = Value;
+    }
+    if(Field & RH_PORT_PWR_CTRL_MASK) {
+      DescriptorB.PortPowerControlMask = Value;
+    }
+
+    Status = OhciSetOperationalReg (Ohc, HC_RH_DESC_B, (UINT32*)&DescriptorB);
+
+    return Status;
+  }
+
+  *(UINT32 *)&DescriptorA = OhciGetOperationalReg (Ohc, HC_RH_DESC_A);
+
+  if(Field & RH_NUM_DS_PORTS) {
+    DescriptorA.NumDownStrmPorts = Value;
+  }
+  if(Field & RH_NO_PSWITCH) {
+    DescriptorA.NoPowerSwitch = Value;
+  }
+  if(Field & RH_PSWITCH_MODE) {
+    DescriptorA.PowerSwitchMode = Value;
+  }
+  if(Field & RH_DEVICE_TYPE) {
+    DescriptorA.DeviceType = Value;
+  }
+  if(Field & RH_OC_PROT_MODE) {
+    DescriptorA.OverCurrentProtMode = Value;
+  }
+  if(Field & RH_NOC_PROT) {
+    DescriptorA.NoOverCurrentProtMode = Value;
+  }
+  if(Field & RH_NO_POTPGT) {
+    DescriptorA.PowerOnToPowerGoodTime = Value;
+  }
+
+  Status = OhciSetOperationalReg (Ohc, HC_RH_DESC_A, (UINT32*)&DescriptorA);
+
+  return Status;
+}
+
+
+/**
+
+  Get Root Hub Descriptor reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetRootHubDescriptor (
+  IN USB_OHCI_HC_DEV     *Ohc,
+  IN UINTN               Field
+  )
+{
+  HcRH_DESC_A             DescriptorA;
+  HcRH_DESC_B             DescriptorB;
+
+
+  *(UINT32 *) &DescriptorA = OhciGetOperationalReg (Ohc, HC_RH_DESC_A);
+  *(UINT32 *) &DescriptorB = OhciGetOperationalReg (Ohc, HC_RH_DESC_B);
+
+  switch (Field){
+    case RH_DEV_REMOVABLE:
+      return DescriptorB.DeviceRemovable;
+      break;
+
+    case RH_PORT_PWR_CTRL_MASK:
+      return DescriptorB.PortPowerControlMask;
+      break;
+
+    case RH_NUM_DS_PORTS:
+      return DescriptorA.NumDownStrmPorts;
+      break;
+
+    case RH_NO_PSWITCH:
+      return DescriptorA.NoPowerSwitch;
+      break;
+
+    case RH_PSWITCH_MODE:
+      return DescriptorA.PowerSwitchMode;
+      break;
+
+    case RH_DEVICE_TYPE:
+      return DescriptorA.DeviceType;
+      break;
+
+    case RH_OC_PROT_MODE:
+      return DescriptorA.OverCurrentProtMode;
+      break;
+
+    case RH_NOC_PROT:
+      return DescriptorA.NoOverCurrentProtMode;
+      break;
+
+    case RH_NO_POTPGT:
+      return DescriptorA.PowerOnToPowerGoodTime;
+      break;
+
+    default:
+      ASSERT (FALSE);
+  }
+
+  return 0;
+}
+
+
+/**
+
+  Set Root Hub Status reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetRootHubStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  )
+{
+  EFI_STATUS              Status;
+  HcRH_STATUS             RootHubStatus;
+
+
+  ZeroMem (&RootHubStatus, sizeof(HcRH_STATUS));
+
+  if(Field & RH_LOCAL_PSTAT){
+    RootHubStatus.LocalPowerStat = 1;
+  }
+  if(Field & RH_OC_ID){
+    RootHubStatus.OverCurrentIndicator = 1;
+  }
+  if(Field & RH_REMOTE_WK_ENABLE){
+    RootHubStatus.DevRemoteWakeupEnable = 1;
+  }
+  if(Field & RH_LOCAL_PSTAT_CHANGE){
+    RootHubStatus.LocalPowerStatChange = 1;
+  }
+  if(Field & RH_OC_ID_CHANGE){
+    RootHubStatus.OverCurrentIndicatorChange = 1;
+  }
+  if(Field & RH_CLR_RMT_WK_ENABLE){
+    RootHubStatus.ClearRemoteWakeupEnable = 1;
+  }
+
+  Status = OhciSetOperationalReg (Ohc, HC_RH_STATUS, (UINT32*)&RootHubStatus);
+
+  return Status;
+}
+
+
+/**
+
+  Get Root Hub Status reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetRootHubStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  )
+{
+  HcRH_STATUS             RootHubStatus;
+
+
+  *(UINT32 *) &RootHubStatus = OhciGetOperationalReg (Ohc, HC_RH_STATUS);
+
+  switch (Field) {
+    case RH_LOCAL_PSTAT:
+      return RootHubStatus.LocalPowerStat;
+      break;
+    case RH_OC_ID:
+      return RootHubStatus.OverCurrentIndicator;
+      break;
+    case RH_REMOTE_WK_ENABLE:
+      return RootHubStatus.DevRemoteWakeupEnable;
+      break;
+    case RH_LOCAL_PSTAT_CHANGE:
+      return RootHubStatus.LocalPowerStatChange;
+      break;
+    case RH_OC_ID_CHANGE:
+      return RootHubStatus.OverCurrentIndicatorChange;
+      break;
+    case RH_CLR_RMT_WK_ENABLE:
+      return RootHubStatus.ClearRemoteWakeupEnable;
+      break;
+    default:
+      ASSERT (FALSE);
+  }
+
+  return 0;
+}
+
+
+/**
+
+  Set Root Hub Port Status reg value
+
+  @param  Ohc                   UHC private data
+  @param  Index                 Index of the port
+  @param  Field                 Field to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetRootHubPortStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Index,
+  IN UINTN                Field
+  )
+{
+  EFI_STATUS              Status;
+  HcRHPORT_STATUS         PortStatus;
+
+
+  ZeroMem (&PortStatus, sizeof(HcRHPORT_STATUS));
+
+  if (Field & RH_CLEAR_PORT_ENABLE) {
+    PortStatus.CurrentConnectStat = 1;
+  }
+  if (Field & RH_SET_PORT_ENABLE) {
+    PortStatus.EnableStat = 1;
+  }
+  if (Field & RH_SET_PORT_SUSPEND) {
+    PortStatus.SuspendStat = 1;
+  }
+  if (Field & RH_CLEAR_SUSPEND_STATUS) {
+    PortStatus.OCIndicator = 1;
+  }
+  if (Field & RH_SET_PORT_RESET) {
+    PortStatus.ResetStat = 1;
+  }
+  if (Field & RH_SET_PORT_POWER) {
+    PortStatus.PowerStat = 1;
+  }
+  if (Field & RH_CLEAR_PORT_POWER) {
+    PortStatus.LsDeviceAttached = 1;
+  }
+  if (Field & RH_CONNECT_STATUS_CHANGE) {
+    PortStatus.ConnectStatChange = 1;
+  }
+  if (Field & RH_PORT_ENABLE_STAT_CHANGE) {
+    PortStatus.EnableStatChange = 1;
+  }
+  if (Field & RH_PORT_SUSPEND_STAT_CHANGE) {
+    PortStatus.SuspendStatChange = 1;
+  }
+  if (Field & RH_OC_INDICATOR_CHANGE) {
+    PortStatus.OCIndicatorChange = 1;
+  }
+  if (Field & RH_PORT_RESET_STAT_CHANGE ) {
+    PortStatus.ResetStatChange = 1;
+  }
+
+  Status = OhciSetOperationalReg (Ohc, HC_RH_PORT_STATUS + (Index * 4), (UINT32*)&PortStatus);
+
+  return Status;
+}
+
+
+/**
+
+  Get Root Hub Port Status reg value
+
+  @param  Ohc                   UHC private data
+  @param  Index                 Index of the port
+  @param  Field                 Field to get
+
+  @retval                       Value of the field and index
+
+**/
+
+UINT32
+OhciReadRootHubPortStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Index,
+  IN UINTN                Field
+  )
+{
+  HcRHPORT_STATUS         PortStatus;
+
+  *(UINT32 *) &PortStatus = OhciGetOperationalReg (
+                              Ohc,
+                              HC_RH_PORT_STATUS + (Index * 4)
+                              );
+
+  switch (Field){
+  case RH_CURR_CONNECT_STAT:
+    return PortStatus.CurrentConnectStat;
+    break;
+  case RH_PORT_ENABLE_STAT:
+    return PortStatus.EnableStat;
+    break;
+  case RH_PORT_SUSPEND_STAT:
+    return PortStatus.SuspendStat;
+    break;
+  case RH_PORT_OC_INDICATOR:
+    return PortStatus.OCIndicator;
+    break;
+  case RH_PORT_RESET_STAT:
+    return PortStatus.ResetStat;
+    break;
+  case RH_PORT_POWER_STAT:
+    return PortStatus.PowerStat;
+    break;
+  case RH_LSDEVICE_ATTACHED:
+    return PortStatus.LsDeviceAttached;
+    break;
+  case RH_CONNECT_STATUS_CHANGE:
+    return PortStatus.ConnectStatChange;
+    break;
+  case RH_PORT_ENABLE_STAT_CHANGE:
+    return PortStatus.EnableStatChange;
+    break;
+  case RH_PORT_SUSPEND_STAT_CHANGE:
+    return PortStatus.SuspendStatChange;
+    break;
+  case RH_OC_INDICATOR_CHANGE:
+    return PortStatus.OCIndicatorChange;
+    break;
+  case RH_PORT_RESET_STAT_CHANGE:
+    return PortStatus.ResetStatChange;
+    break;
+  default:
+    ASSERT (FALSE);
+  }
+
+  return 0;
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.h
new file mode 100644
index 0000000000..9b31bf53ee
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.h
@@ -0,0 +1,875 @@
+/** @file
+This file contains the definination for host controller
+register operation routines.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+
+#ifndef   _OHCI_REGS_H
+#define   _OHCI_REGS_H
+
+#define   HC_STATE_RESET         0x0
+#define   HC_STATE_RESUME        0x1
+#define   HC_STATE_OPERATIONAL   0x2
+#define   HC_STATE_SUSPEND       0x3
+
+#define   PERIODIC_ENABLE               0x01
+#define   ISOCHRONOUS_ENABLE            0x02
+#define   CONTROL_ENABLE                0x04
+#define   BULK_ENABLE                   0x08
+#define   CONTROL_BULK_RATIO            0x10
+
+#define   HC_FUNCTIONAL_STATE    0x20
+#define   INTERRUPT_ROUTING      0x40
+
+#define   HC_RESET               0x01
+#define   CONTROL_LIST_FILLED    0x02
+#define   BULK_LIST_FILLED       0x04
+#define   CHANGE_OWNER_REQUEST   0x08
+
+#define   SCHEDULE_OVERRUN_COUNT 0x10
+
+#define   SCHEDULE_OVERRUN       0x00001
+#define   WRITEBACK_DONE_HEAD    0x00002
+#define   START_OF_FRAME         0x00004
+#define   RESUME_DETECT          0x00008
+#define   UNRECOVERABLE_ERROR    0x00010
+#define   FRAME_NUMBER_OVERFLOW  0x00020
+#define   ROOTHUB_STATUS_CHANGE  0x00040
+#define   OWNERSHIP_CHANGE       0x00080
+
+#define   MASTER_INTERRUPT       0x00400
+
+#define   CONTROL_HEAD           0x001
+#define   BULK_HEAD              0x002
+#define   DONE_HEAD              0x004
+
+#define   Hc_HCCA                0x001
+#define   Hc_PERIODIC_CURRENT    0x002
+#define   Hc_CONTOL_HEAD         0x004
+#define   Hc_CONTROL_CURRENT_PTR 0x008
+#define   Hc_BULK_HEAD           0x010
+#define   Hc_BULK_CURRENT_PTR    0x020
+#define   Hc_DONE_HEAD           0x040
+
+#define   FRAME_INTERVAL         0x008
+#define   FS_LARGEST_DATA_PACKET 0x010
+#define   FRMINT_TOGGLE          0x020
+#define   FRAME_REMAINING        0x040
+#define   FRAME_REMAIN_TOGGLE    0x080
+
+#define   RH_DESC_A              0x00001
+#define   RH_DESC_B              0x00002
+#define   RH_NUM_DS_PORTS        0x00004
+#define   RH_NO_PSWITCH          0x00008
+#define   RH_PSWITCH_MODE        0x00010
+#define   RH_DEVICE_TYPE         0x00020
+#define   RH_OC_PROT_MODE        0x00040
+#define   RH_NOC_PROT            0x00080
+#define   RH_POTPGT              0x00100
+#define   RH_NO_POTPGT           0x00200
+#define   RH_DEV_REMOVABLE       0x00400
+#define   RH_PORT_PWR_CTRL_MASK  0x00800
+
+#define   RH_LOCAL_PSTAT         0x00001
+#define   RH_OC_ID               0x00002
+#define   RH_REMOTE_WK_ENABLE    0x00004
+#define   RH_LOCAL_PSTAT_CHANGE  0x00008
+#define   RH_OC_ID_CHANGE        0x00010
+#define   RH_CLR_RMT_WK_ENABLE   0x00020
+
+#define   RH_CLEAR_PORT_ENABLE        0x0001
+#define   RH_SET_PORT_ENABLE          0x0002
+#define   RH_SET_PORT_SUSPEND         0x0004
+#define   RH_CLEAR_SUSPEND_STATUS     0x0008
+#define   RH_SET_PORT_RESET           0x0010
+#define   RH_SET_PORT_POWER           0x0020
+#define   RH_CLEAR_PORT_POWER         0x0040
+#define   RH_CONNECT_STATUS_CHANGE    0x10000
+#define   RH_PORT_ENABLE_STAT_CHANGE  0x20000
+#define   RH_PORT_SUSPEND_STAT_CHANGE 0x40000
+#define   RH_OC_INDICATOR_CHANGE      0x80000
+#define   RH_PORT_RESET_STAT_CHANGE   0x100000
+
+#define   RH_CURR_CONNECT_STAT        0x0001
+#define   RH_PORT_ENABLE_STAT         0x0002
+#define   RH_PORT_SUSPEND_STAT        0x0004
+#define   RH_PORT_OC_INDICATOR        0x0008
+#define   RH_PORT_RESET_STAT          0x0010
+#define   RH_PORT_POWER_STAT          0x0020
+#define   RH_LSDEVICE_ATTACHED        0x0040
+
+#define   RESET_SYSTEM_BUS            (1 << 0)
+#define   RESET_HOST_CONTROLLER       (1 << 1)
+#define   RESET_CLOCK_GENERATION      (1 << 2)
+#define   RESET_SSE_GLOBAL            (1 << 5)
+#define   RESET_PSPL                  (1 << 6)
+#define   RESET_PCPL                  (1 << 7)
+#define   RESET_SSEP1                 (1 << 9)
+#define   RESET_SSEP2                 (1 << 10)
+#define   RESET_SSEP3                 (1 << 11)
+
+#define ONE_SECOND                      1000000
+#define ONE_MILLI_SEC                   1000
+#define MAX_BYTES_PER_TD                0x1000
+#define MAX_RETRY_TIMES                 100
+#define PORT_NUMBER_ON_MAINSTONE2       1
+
+
+//
+// Operational Register Offsets
+//
+
+//
+// Command & Status Registers Offsets
+//
+#define HC_REVISION             0x00
+#define HC_CONTROL              0x04
+#define HC_COMMAND_STATUS       0x08
+#define HC_INTERRUPT_STATUS     0x0C
+#define HC_INTERRUPT_ENABLE     0x10
+#define HC_INTERRUPT_DISABLE    0x14
+
+//
+// Memory Pointer Offsets
+//
+#define HC_HCCA                 0x18
+#define HC_PERIODIC_CURRENT     0x1C
+#define HC_CONTROL_HEAD         0x20
+#define HC_CONTROL_CURRENT_PTR  0x24
+#define HC_BULK_HEAD            0x28
+#define HC_BULK_CURRENT_PTR     0x2C
+#define HC_DONE_HEAD            0x30
+
+//
+// Frame Register Offsets
+//
+#define HC_FRM_INTERVAL         0x34
+#define HC_FRM_REMAINING        0x38
+#define HC_FRM_NUMBER           0x3C
+#define HC_PERIODIC_START       0x40
+#define HC_LS_THREASHOLD        0x44
+
+//
+// Root Hub Register Offsets
+//
+#define HC_RH_DESC_A            0x48
+#define HC_RH_DESC_B            0x4C
+#define HC_RH_STATUS            0x50
+#define HC_RH_PORT_STATUS       0x54
+
+#define USBHOST_OFFSET_UHCHR         0x64         // Usb Host reset register
+
+#define OHC_BAR_INDEX               0
+
+//
+// Usb Host controller register offset
+//
+#define USBHOST_OFFSET_UHCREV        0x0          // Usb Host revision register
+#define USBHOST_OFFSET_UHCHCON       0x4          // Usb Host control register
+#define USBHOST_OFFSET_UHCCOMS       0x8          // Usb Host Command Status register
+#define USBHOST_OFFSET_UHCINTS       0xC          // Usb Host Interrupt Status register
+#define USBHOST_OFFSET_UHCINTE       0x10         // Usb Host Interrupt Enable register
+#define USBHOST_OFFSET_UHCINTD       0x14         // Usb Host Interrupt Disable register
+#define USBHOST_OFFSET_UHCHCCA       0x18         // Usb Host Controller Communication Area
+#define USBHOST_OFFSET_UHCPCED       0x1C         // Usb Host Period Current Endpoint Descriptor
+#define USBHOST_OFFSET_UHCCHED       0x20         // Usb Host Control Head Endpoint Descriptor
+#define USBHOST_OFFSET_UHCCCED       0x24         // Usb Host Control Current Endpoint Descriptor
+#define USBHOST_OFFSET_UHCBHED       0x28         // Usb Host Bulk Head Endpoint Descriptor
+#define USBHOST_OFFSET_UHCBCED       0x2C         // Usb Host Bulk Current Endpoint Descriptor
+#define USBHOST_OFFSET_UHCDHEAD      0x30         // Usb Host Done Head register
+#define USBHOST_OFFSET_UHCFMI        0x34         // Usb Host Frame Interval register
+#define USBHOST_OFFSET_UHCFMR        0x38         // Usb Host Frame Remaining register
+#define USBHOST_OFFSET_UHCFMN        0x3C         // Usb Host Frame Number register
+#define USBHOST_OFFSET_UHCPERS       0x40         // Usb Host Periodic Start register
+#define USBHOST_OFFSET_UHCLST        0x44         // Usb Host Low-Speed Threshold register
+#define USBHOST_OFFSET_UHCRHDA       0x48         // Usb Host Root Hub Descriptor A register
+#define USBHOST_OFFSET_UHCRHDB       0x4C         // Usb Host Root Hub Descriptor B register
+#define USBHOST_OFFSET_UHCRHS        0x50         // Usb Host Root Hub Status register
+#define USBHOST_OFFSET_UHCRHPS1      0x54         // Usb Host Root Hub Port Status 1 register
+
+//
+// Usb Host controller register bit fields
+//
+#pragma pack(1)
+
+typedef struct {
+  UINT8                   ProgInterface;
+  UINT8                   SubClassCode;
+  UINT8                   BaseCode;
+} USB_CLASSC;
+
+typedef struct {
+    UINT32 Revision:8;
+    UINT32 Rsvd:24;
+} HcREVISION;
+
+typedef struct {
+    UINT32 ControlBulkRatio:2;
+    UINT32 PeriodicEnable:1;
+    UINT32 IsochronousEnable:1;
+    UINT32 ControlEnable:1;
+    UINT32 BulkEnable:1;
+    UINT32 FunctionalState:2;
+    UINT32 InterruptRouting:1;
+    UINT32 RemoteWakeup:1;
+    UINT32 RemoteWakeupEnable:1;
+    UINT32 Reserved:21;
+} HcCONTROL;
+
+typedef struct {
+    UINT32 HcReset:1;
+    UINT32 ControlListFilled:1;
+    UINT32 BulkListFilled:1;
+    UINT32 ChangeOwnerRequest:1;
+    UINT32 Reserved1:12;
+    UINT32 ScheduleOverrunCount:2;
+    UINT32 Reserved:14;
+} HcCOMMAND_STATUS;
+
+typedef struct {
+    UINT32 SchedulingOverrun:1;
+    UINT32 WriteBackDone:1;
+    UINT32 Sof:1;
+    UINT32 ResumeDetected:1;
+    UINT32 UnrecoverableError:1;
+    UINT32 FrameNumOverflow:1;
+    UINT32 RHStatusChange:1;
+    UINT32 Reserved1:23;
+    UINT32 OwnerChange:1;
+    UINT32 Reserved2:1;
+} HcINTERRUPT_STATUS;
+
+typedef struct {
+    UINT32 SchedulingOverrunInt:1;
+    UINT32 WriteBackDoneInt:1;
+    UINT32 SofInt:1;
+    UINT32 ResumeDetectedInt:1;
+    UINT32 UnrecoverableErrorInt:1;
+    UINT32 FrameNumOverflowInt:1;
+    UINT32 RHStatusChangeInt:1;
+    UINT32 Reserved:23;
+    UINT32 OwnerChangedInt:1;
+    UINT32 MasterInterruptEnable:1;
+} HcINTERRUPT_CONTROL;
+
+typedef struct {
+    UINT32 Rerserved:8;
+    UINT32 Hcca:24;
+} HcHCCA;
+
+typedef struct {
+    UINT32 Reserved:4;
+    UINT32 MemoryPtr:28;
+} HcMEMORY_PTR;
+
+typedef struct {
+    UINT32 FrameInterval:14;
+    UINT32 Reserved:2;
+    UINT32 FSMaxDataPacket:15;
+    UINT32 FrmIntervalToggle:1;
+} HcFRM_INTERVAL;
+
+typedef struct {
+    UINT32 FrameRemaining:14;
+    UINT32 Reserved:17;
+    UINT32 FrameRemainingToggle:1;
+} HcFRAME_REMAINING;
+
+typedef struct {
+    UINT32 FrameNumber:16;
+    UINT32 Reserved:16;
+} HcFRAME_NUMBER;
+
+typedef struct {
+    UINT32 PeriodicStart:14;
+    UINT32 Reserved:18;
+} HcPERIODIC_START;
+
+typedef struct {
+    UINT32 LsThreshold:12;
+    UINT32 Reserved:20;
+} HcLS_THRESHOLD;
+
+typedef struct {
+    UINT32 NumDownStrmPorts:8;
+    UINT32 PowerSwitchMode:1;
+    UINT32 NoPowerSwitch:1;
+    UINT32 DeviceType:1;
+    UINT32 OverCurrentProtMode:1;
+    UINT32 NoOverCurrentProtMode:1;
+    UINT32 Reserved:11;
+    UINT32 PowerOnToPowerGoodTime:8;
+} HcRH_DESC_A;
+
+typedef struct {
+    UINT32 DeviceRemovable:16;
+    UINT32 PortPowerControlMask:16;
+} HcRH_DESC_B;
+
+typedef struct {
+    UINT32 LocalPowerStat:1;
+    UINT32 OverCurrentIndicator:1;
+    UINT32 Reserved1:13;
+    UINT32 DevRemoteWakeupEnable:1;
+    UINT32 LocalPowerStatChange:1;
+    UINT32 OverCurrentIndicatorChange:1;
+    UINT32 Reserved2:13;
+    UINT32 ClearRemoteWakeupEnable:1;
+} HcRH_STATUS;
+
+typedef struct {
+    UINT32 CurrentConnectStat:1;
+    UINT32 EnableStat:1;
+    UINT32 SuspendStat:1;
+    UINT32 OCIndicator:1;
+    UINT32 ResetStat:1;
+    UINT32 Reserved1:3;
+    UINT32 PowerStat:1;
+    UINT32 LsDeviceAttached:1;
+    UINT32 Reserved2:6;
+    UINT32 ConnectStatChange:1;
+    UINT32 EnableStatChange:1;
+    UINT32 SuspendStatChange:1;
+    UINT32 OCIndicatorChange:1;
+    UINT32 ResetStatChange:1;
+    UINT32 Reserved3:11;
+} HcRHPORT_STATUS;
+
+typedef struct {
+    UINT32 FSBIR:1;
+    UINT32 FHR:1;
+    UINT32 CGR:1;
+    UINT32 SSDC:1;
+    UINT32 UIT:1;
+    UINT32 SSE:1;
+    UINT32 PSPL:1;
+    UINT32 PCPL:1;
+    UINT32 Reserved0:1;
+    UINT32 SSEP1:1;
+    UINT32 SSEP2:1;
+    UINT32 SSEP3:1;
+    UINT32 Reserved1:20;
+} HcRESET;
+
+#pragma pack()
+
+//
+// Func List
+//
+/**
+
+  Get OHCI operational reg value
+
+  @param  Ohc                   UHC private data
+  @param  Offset                Offset of the operational reg
+
+  @retval                       Value of the register
+
+**/
+UINT32
+OhciGetOperationalReg (
+  IN USB_OHCI_HC_DEV         *Ohc,
+  IN UINT32                  Offset
+  );
+/**
+
+  Set OHCI operational reg value
+
+  @param  Ohc                   UHC private data
+  @param  Offset                 Offset of the operational reg
+  @param  Value                  Value to set
+
+  @retval EFI_SUCCESS            Value set to the reg
+
+**/
+EFI_STATUS
+OhciSetOperationalReg (
+  USB_OHCI_HC_DEV         *Ohc,
+  IN UINT32               Offset,
+  IN UINT32               *Value
+  );
+/**
+
+  Get HcRevision reg value
+
+  @param  Ohc                   UHC private data
+
+  @retval                       Value of the register
+
+**/
+
+
+UINT32
+OhciGetHcRevision (
+  USB_OHCI_HC_DEV         *Ohc
+  );
+
+/**
+
+  Set HcReset reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval EFI_SUCCESS           Value set
+
+**/
+
+EFI_STATUS
+OhciSetHcReset (
+  IN USB_OHCI_HC_DEV            *Ohc,
+  IN UINT32                     Field,
+  IN UINT32                     Value
+  );
+/**
+
+  Get specific field of HcReset reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetHcReset (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Field
+  );
+/**
+
+  Set HcControl reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetHcControl (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field,
+  IN UINT32               Value
+  );
+/**
+
+  Get specific field of HcControl reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+
+UINT32
+OhciGetHcControl (
+  IN USB_OHCI_HC_DEV   *Ohc,
+  IN UINTN             Field
+  );
+/**
+
+  Set HcCommand reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval EFI_SUCCESS           Value set
+
+**/
+
+EFI_STATUS
+OhciSetHcCommandStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field,
+  IN UINT32               Value
+  );
+/**
+
+  Get specific field of HcCommand reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetHcCommandStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  );
+/**
+
+  Clear specific fields of Interrupt Status
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to clear
+
+  @retval EFI_SUCCESS           Fields cleared
+
+**/
+
+EFI_STATUS
+OhciClearInterruptStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  );
+/**
+
+  Get fields of HcInterrupt reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetHcInterruptStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  );
+/**
+
+  Set Interrupt Control reg value
+
+  @param  Ohc                   UHC private data
+  @param  StatEnable            Enable or Disable
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval EFI_SUCCESS           Value set
+
+**/
+
+EFI_STATUS
+OhciSetInterruptControl (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN BOOLEAN              StatEnable,
+  IN UINTN                Field,
+  IN UINT32               Value
+  );
+/**
+
+  Get field of HcInterruptControl reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetHcInterruptControl (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  );
+/**
+
+  Set memory pointer of specific type
+
+  @param  Ohc                   UHC private data
+  @param  PointerType           Type of the pointer to set
+  @param  Value                 Value to set
+
+  @retval EFI_SUCCESS           Memory pointer set
+
+**/
+
+EFI_STATUS
+OhciSetMemoryPointer(
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                PointerType,
+  IN VOID                 *Value
+  );
+/**
+
+  Get memory pointer of specific type
+
+  @param  Ohc                   UHC private data
+  @param  PointerType           Type of pointer
+
+  @retval                       Memory pointer of the specific type
+
+**/
+
+VOID *
+OhciGetMemoryPointer (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                PointerType
+  );
+/**
+
+  Set Frame Interval value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetFrameInterval (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field,
+  IN UINT32               Value
+  );
+/**
+
+  Get field of frame interval reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetFrameInterval (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  );
+/**
+
+  Set Frame Remaining reg value
+
+  @param  Ohc                   UHC private data
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetFrameRemaining (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Value
+  );
+/**
+
+  Get value of frame remaining reg
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of frame remaining reg
+
+**/
+UINT32
+OhciGetFrameRemaining (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  );
+/**
+
+  Set frame number reg value
+
+  @param  Ohc                   UHC private data
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetFrameNumber(
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Value
+  );
+/**
+
+  Get frame number reg value
+
+  @param  Ohc                   UHC private data
+
+  @retval                       Value of frame number reg
+
+**/
+
+UINT32
+OhciGetFrameNumber (
+  IN USB_OHCI_HC_DEV      *Ohc
+  );
+/**
+
+  Set period start reg value
+
+  @param  Ohc                   UHC private data
+  @param  Value                 Value to set
+
+  @retval EFI_SUCCESS           Value set
+
+**/
+
+EFI_STATUS
+OhciSetPeriodicStart (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Value
+  );
+/**
+
+  Get periodic start reg value
+
+  @param  Ohc                   UHC private data
+
+  @param                        Value of periodic start reg
+
+**/
+
+UINT32
+OhciGetPeriodicStart (
+  IN USB_OHCI_HC_DEV      *Ohc
+  );
+/**
+
+  Set Ls Threshold reg value
+
+  @param  Ohc                   UHC private data
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetLsThreshold (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Value
+  );
+/**
+
+  Get Ls Threshold reg value
+
+  @param  Ohc                   UHC private data
+
+  @retval                       Value of Ls Threshold reg
+
+**/
+
+UINT32
+OhciGetLsThreshold (
+  IN USB_OHCI_HC_DEV      *Ohc
+  );
+/**
+
+  Set Root Hub Descriptor reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+  @param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+EFI_STATUS
+OhciSetRootHubDescriptor (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field,
+  IN UINT32               Value
+  );
+/**
+
+  Get Root Hub Descriptor reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetRootHubDescriptor (
+  IN USB_OHCI_HC_DEV     *Ohc,
+  IN UINTN               Field
+  );
+/**
+
+  Set Root Hub Status reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetRootHubStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  );
+/**
+
+  Get Root Hub Status reg value
+
+  @param  Ohc                   UHC private data
+  @param  Field                 Field to get
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetRootHubStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINTN                Field
+  );
+/**
+
+  Set Root Hub Port Status reg value
+
+  @param  Ohc                   UHC private data
+  @param  Index                 Index of the port
+  @param  Field                 Field to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+
+EFI_STATUS
+OhciSetRootHubPortStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Index,
+  IN UINTN                Field
+  );
+/**
+
+  Get Root Hub Port Status reg value
+
+  @param  Ohc                   UHC private data
+  @param  Index                 Index of the port
+  @param  Field                 Field to get
+
+  @retval                       Value of the field and index
+
+**/
+
+UINT32
+OhciReadRootHubPortStatus (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN UINT32               Index,
+  IN UINTN                Field
+  );
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciSched.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciSched.c
new file mode 100644
index 0000000000..2ba0133e51
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciSched.c
@@ -0,0 +1,223 @@
+/** @file
+OHCI transfer scheduling routines.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "OhcPeim.h"
+
+/**
+
+  Convert Error code from OHCI format to EFI format
+
+  @Param  ErrorCode             ErrorCode in OHCI format
+
+  @retval                       ErrorCode in EFI format
+
+**/
+UINT32
+ConvertErrorCode (
+  IN  UINT32              ErrorCode
+  )
+{
+  UINT32                  TransferResult;
+
+  switch (ErrorCode) {
+    case TD_NO_ERROR:
+      TransferResult = EFI_USB_NOERROR;
+      break;
+
+    case TD_TOBE_PROCESSED:
+    case TD_TOBE_PROCESSED_2:
+      TransferResult = EFI_USB_ERR_NOTEXECUTE;
+      break;
+
+    case TD_DEVICE_STALL:
+      TransferResult = EFI_USB_ERR_STALL;
+      break;
+
+    case TD_BUFFER_OVERRUN:
+    case TD_BUFFER_UNDERRUN:
+      TransferResult = EFI_USB_ERR_BUFFER;
+      break;
+
+    case TD_CRC_ERROR:
+      TransferResult = EFI_USB_ERR_CRC;
+      break;
+
+    case TD_NO_RESPONSE:
+      TransferResult = EFI_USB_ERR_TIMEOUT;
+      break;
+
+    case TD_BITSTUFFING_ERROR:
+      TransferResult = EFI_USB_ERR_BITSTUFF;
+      break;
+
+    default:
+      TransferResult = EFI_USB_ERR_SYSTEM;
+  }
+
+  return TransferResult;
+}
+
+
+/**
+
+  Check TDs Results
+
+  @Param  Ohc                   UHC private data
+  @Param  Td                    TD_DESCRIPTOR
+  @Param  Result                Result to return
+
+  @retval TRUE                  means OK
+  @retval FLASE                 means Error or Short packet
+
+**/
+BOOLEAN
+OhciCheckTDsResults (
+  IN  USB_OHCI_HC_DEV     *Ohc,
+  IN  TD_DESCRIPTOR       *Td,
+  OUT UINT32              *Result
+  )
+{
+  UINT32                  TdCompletionCode;
+
+  *Result   = EFI_USB_NOERROR;
+
+  while (Td) {
+    TdCompletionCode = Td->Word0.ConditionCode;
+
+    *Result |= ConvertErrorCode(TdCompletionCode);
+    //
+    // if any error encountered, stop processing the left TDs.
+    //
+    if (*Result) {
+      return FALSE;
+    }
+
+    Td = Td->NextTDPointer;
+  }
+  return TRUE;
+
+}
+
+
+/**
+
+  Check the task status on an ED
+
+  @Param  Ed                    Pointer to the ED task that TD hooked on
+  @Param  HeadTd                TD header for current transaction
+
+  @retval                       Task Status Code
+
+**/
+
+UINT32
+CheckEDStatus (
+  IN  ED_DESCRIPTOR       *Ed,
+  IN  TD_DESCRIPTOR       *HeadTd
+  )
+{
+  while(HeadTd != NULL) {
+    if (HeadTd->Word0.ConditionCode != 0) {
+      return HeadTd->Word0.ConditionCode;
+    }
+    HeadTd = HeadTd->NextTDPointer;
+  }
+
+  if (OhciGetEDField (Ed, ED_TDHEAD_PTR) != OhciGetEDField (Ed, ED_TDTAIL_PTR)) {
+    return TD_TOBE_PROCESSED;
+  }
+
+  return TD_NO_ERROR;
+}
+
+/**
+
+  Check the task status
+
+  @Param  Ohc                   UHC private data
+  @Param  ListType              Pipe type
+  @Param  Ed                    Pointer to the ED task hooked on
+  @Param  HeadTd                Head of TD corresponding to the task
+  @Param  ErrorCode             return the ErrorCode
+
+  @retval  EFI_SUCCESS          Task done
+  @retval  EFI_NOT_READY        Task on processing
+  @retval  EFI_DEVICE_ERROR     Some error occured
+
+**/
+EFI_STATUS
+CheckIfDone (
+  IN  USB_OHCI_HC_DEV       *Ohc,
+  IN  DESCRIPTOR_LIST_TYPE  ListType,
+  IN  ED_DESCRIPTOR         *Ed,
+  IN  TD_DESCRIPTOR         *HeadTd,
+  OUT UINT32                *ErrorCode
+  )
+{
+  *ErrorCode = TD_TOBE_PROCESSED;
+
+  switch (ListType) {
+    case CONTROL_LIST:
+      if (OhciGetHcCommandStatus (Ohc, CONTROL_LIST_FILLED) != 0) {
+        return EFI_NOT_READY;
+      }
+      break;
+
+    case BULK_LIST:
+      if (OhciGetHcCommandStatus (Ohc, BULK_LIST_FILLED) != 0) {
+        return EFI_NOT_READY;
+      }
+      break;
+
+    default:
+      break;
+  }
+
+  *ErrorCode = CheckEDStatus (Ed, HeadTd);
+
+
+  if (*ErrorCode == TD_NO_ERROR) {
+    return EFI_SUCCESS;
+  } else if (*ErrorCode == TD_TOBE_PROCESSED) {
+    return EFI_NOT_READY;
+  } else {
+    return EFI_DEVICE_ERROR;
+  }
+}
+
+
+/**
+
+  Convert TD condition code to Efi Status
+
+  @Param  ConditionCode         Condition code to convert
+
+  @retval  EFI_SUCCESS          No error occured
+  @retval  EFI_NOT_READY        TD still on processing
+  @retval  EFI_DEVICE_ERROR     Error occured in processing TD
+
+**/
+
+EFI_STATUS
+OhciTDConditionCodeToStatus (
+  IN  UINT32              ConditionCode
+  )
+{
+  if (ConditionCode == TD_NO_ERROR) {
+    return EFI_SUCCESS;
+  }
+
+  if (ConditionCode == TD_TOBE_PROCESSED) {
+    return EFI_NOT_READY;
+  }
+
+  return EFI_DEVICE_ERROR;
+}
+
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciSched.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciSched.h
new file mode 100644
index 0000000000..53b4b38d45
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciSched.h
@@ -0,0 +1,108 @@
+/** @file
+This file contains the definination for host controller schedule routines.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+
+#ifndef _OHCI_SCHED_H
+#define _OHCI_SCHED_H
+
+#include "Descriptor.h"
+
+#define HCCA_MEM_SIZE     256
+#define GRID_SIZE         16
+#define GRID_SHIFT        4
+
+/**
+
+  Convert Error code from OHCI format to EFI format
+
+  @Param  ErrorCode             ErrorCode in OHCI format
+
+  @retval                       ErrorCode in EFI format
+
+**/
+UINT32
+ConvertErrorCode (
+  IN  UINT32              ErrorCode
+  );
+/**
+
+  Check TDs Results
+
+  @Param  Ohc                   UHC private data
+  @Param  Td                    TD_DESCRIPTOR
+  @Param  Result                Result to return
+
+  @retval TRUE                  means OK
+  @retval FLASE                 means Error or Short packet
+
+**/
+BOOLEAN
+OhciCheckTDsResults (
+  IN  USB_OHCI_HC_DEV     *Ohc,
+  IN  TD_DESCRIPTOR       *Td,
+  OUT UINT32              *Result
+  );
+/**
+
+  Check the task status on an ED
+
+  @Param  Ed                    Pointer to the ED task that TD hooked on
+  @Param  HeadTd                TD header for current transaction
+
+  @retval                       Task Status Code
+
+**/
+
+UINT32
+CheckEDStatus (
+  IN  ED_DESCRIPTOR       *Ed,
+  IN  TD_DESCRIPTOR       *HeadTd
+  );
+/**
+
+  Check the task status
+
+  @Param  Ohc                   UHC private data
+  @Param  ListType              Pipe type
+  @Param  Ed                    Pointer to the ED task hooked on
+  @Param  HeadTd                Head of TD corresponding to the task
+  @Param  ErrorCode             return the ErrorCode
+
+  @retval  EFI_SUCCESS          Task done
+  @retval  EFI_NOT_READY        Task on processing
+  @retval  EFI_DEVICE_ERROR     Some error occured
+
+**/
+EFI_STATUS
+CheckIfDone (
+  IN  USB_OHCI_HC_DEV       *Ohc,
+  IN  DESCRIPTOR_LIST_TYPE  ListType,
+  IN  ED_DESCRIPTOR         *Ed,
+  IN  TD_DESCRIPTOR         *HeadTd,
+  OUT UINT32                *ErrorCode
+  );
+/**
+
+  Convert TD condition code to Efi Status
+
+  @Param  ConditionCode         Condition code to convert
+
+  @retval  EFI_SUCCESS          No error occured
+  @retval  EFI_NOT_READY        TD still on processing
+  @retval  EFI_DEVICE_ERROR     Error occured in processing TD
+
+**/
+
+EFI_STATUS
+OhciTDConditionCodeToStatus (
+  IN  UINT32              ConditionCode
+  );
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.c
new file mode 100644
index 0000000000..96d036c706
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.c
@@ -0,0 +1,560 @@
+/** @file
+This file contains URB request, each request is warpped in a
+URB (Usb Request Block).
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+
+#include "OhcPeim.h"
+
+
+/**
+
+  Create a TD
+
+  @Param  Ohc                   UHC private data
+
+  @retval                       TD structure pointer
+
+**/
+TD_DESCRIPTOR *
+OhciCreateTD (
+  IN USB_OHCI_HC_DEV      *Ohc
+  )
+{
+  TD_DESCRIPTOR           *Td;
+
+  Td = UsbHcAllocateMem(Ohc->MemPool, sizeof(TD_DESCRIPTOR));
+  if (Td == NULL) {
+    return NULL;
+  }
+  Td->CurrBufferPointer = NULL;
+  Td->NextTD = NULL;
+  Td->BufferEndPointer = NULL;
+  Td->NextTDPointer = NULL;
+
+  return Td;
+}
+
+
+/**
+
+  Free a TD
+
+  @Param  Ohc                   UHC private data
+  @Param  Td                    Pointer to a TD to free
+
+  @retval  EFI_SUCCESS          TD freed
+
+**/
+EFI_STATUS
+OhciFreeTD (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN TD_DESCRIPTOR        *Td
+  )
+{
+  if (Td == NULL) {
+    return EFI_SUCCESS;
+  }
+  UsbHcFreeMem(Ohc->MemPool, Td, sizeof(TD_DESCRIPTOR));
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+
+  Create a ED
+
+  @Param   Ohc                  Device private data
+
+  @retval  ED                   descriptor pointer
+
+**/
+ED_DESCRIPTOR *
+OhciCreateED (
+  USB_OHCI_HC_DEV          *Ohc
+  )
+{
+  ED_DESCRIPTOR   *Ed;
+  Ed = UsbHcAllocateMem(Ohc->MemPool, sizeof (ED_DESCRIPTOR));
+  if (Ed == NULL) {
+    return NULL;
+  }
+  Ed->Word0.Skip = 1;
+  Ed->TdTailPointer = NULL;
+  Ed->Word2.TdHeadPointer = RIGHT_SHIFT_4 ((UINT32) NULL);
+  Ed->NextED = NULL;
+
+  return Ed;
+}
+
+/**
+
+  Free a ED
+
+  @Param  Ohc                   UHC private data
+  @Param  Ed                    Pointer to a ED to free
+
+  @retval  EFI_SUCCESS          ED freed
+
+**/
+
+EFI_STATUS
+OhciFreeED (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN ED_DESCRIPTOR        *Ed
+  )
+{
+  if (Ed == NULL) {
+    return EFI_SUCCESS;
+  }
+  UsbHcFreeMem(Ohc->MemPool, Ed, sizeof(ED_DESCRIPTOR));
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Free  ED
+
+  @Param  Ohc                    Device private data
+  @Param  Ed                     Pointer to a ED to free
+
+  @retval  EFI_SUCCESS           ED freed
+
+**/
+EFI_STATUS
+OhciFreeAllTDFromED (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN ED_DESCRIPTOR        *Ed
+  )
+{
+  TD_DESCRIPTOR           *HeadTd;
+  TD_DESCRIPTOR           *TailTd;
+  TD_DESCRIPTOR           *Td;
+  TD_DESCRIPTOR           *TempTd;
+
+  if (Ed == NULL) {
+    return EFI_SUCCESS;
+  }
+
+  HeadTd = TD_PTR (Ed->Word2.TdHeadPointer);
+  TailTd = Ed->TdTailPointer;
+
+  Td = HeadTd;
+  while (Td != TailTd) {
+    TempTd = Td;
+    Td = Td->NextTDPointer;
+    OhciFreeTD (Ohc, TempTd);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Attach an ED
+
+  @Param  Ed                    Ed to be attached
+  @Param  NewEd                 Ed to attach
+
+  @retval EFI_SUCCESS           NewEd attached to Ed
+  @retval EFI_INVALID_PARAMETER Ed is NULL
+
+**/
+EFI_STATUS
+OhciAttachED (
+  IN ED_DESCRIPTOR        *Ed,
+  IN ED_DESCRIPTOR        *NewEd
+  )
+{
+  ED_DESCRIPTOR           *Temp;
+
+  if (Ed == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Ed->NextED == NULL){
+    Ed->NextED = NewEd;
+  } else {
+    Temp = Ed->NextED;
+    Ed->NextED = NewEd;
+    NewEd->NextED = Temp;
+  }
+
+  return EFI_SUCCESS;
+}
+/**
+
+  Attach an ED to an ED list
+
+  @Param  OHC                   UHC private data
+  @Param  ListType              Type of the ED list
+  @Param  Ed                    ED to attach
+  @Param  EdList                ED list to be attached
+
+  @retval  EFI_SUCCESS          ED attached to ED list
+
+**/
+EFI_STATUS
+OhciAttachEDToList (
+  IN USB_OHCI_HC_DEV       *Ohc,
+  IN DESCRIPTOR_LIST_TYPE  ListType,
+  IN ED_DESCRIPTOR         *Ed,
+  IN ED_DESCRIPTOR         *EdList
+  )
+{
+  ED_DESCRIPTOR            *HeadEd;
+
+  switch(ListType) {
+    case CONTROL_LIST:
+      HeadEd = (ED_DESCRIPTOR *) OhciGetMemoryPointer (Ohc, HC_CONTROL_HEAD);
+      if (HeadEd == NULL) {
+        OhciSetMemoryPointer (Ohc, HC_CONTROL_HEAD, Ed);
+      } else {
+        OhciAttachED (HeadEd, Ed);
+      }
+    break;
+
+    case BULK_LIST:
+      HeadEd = (ED_DESCRIPTOR *) OhciGetMemoryPointer (Ohc, HC_BULK_HEAD);
+      if (HeadEd == NULL) {
+        OhciSetMemoryPointer (Ohc, HC_BULK_HEAD, Ed);
+      } else {
+        OhciAttachED (HeadEd, Ed);
+      }
+    break;
+
+    case INTERRUPT_LIST:
+      OhciAttachED (EdList, Ed);
+      break;
+
+    default:
+      ASSERT (FALSE);
+  }
+
+  return EFI_SUCCESS;
+}
+/**
+
+  Link Td2 to the end of Td1
+
+  @Param Td1                    TD to be linked
+  @Param Td2                    TD to link
+
+  @retval EFI_SUCCESS           TD successfully linked
+  @retval EFI_INVALID_PARAMETER Td1 is NULL
+
+**/
+EFI_STATUS
+OhciLinkTD (
+  IN TD_DESCRIPTOR        *Td1,
+  IN TD_DESCRIPTOR        *Td2
+  )
+{
+  TD_DESCRIPTOR           *TempTd;
+
+  if (Td1 == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Td1 == Td2) {
+    return EFI_SUCCESS;
+  }
+
+  TempTd = Td1;
+  while (TempTd->NextTD != NULL) {
+    TempTd = TempTd->NextTD;
+  }
+
+  TempTd->NextTD = Td2;
+  TempTd->NextTDPointer = Td2;
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+
+  Attach TD list to ED
+
+  @Param  Ed                    ED which TD list attach on
+  @Param  HeadTd                Head of the TD list to attach
+
+  @retval  EFI_SUCCESS          TD list attached on the ED
+
+**/
+EFI_STATUS
+OhciAttachTDListToED (
+  IN ED_DESCRIPTOR        *Ed,
+  IN TD_DESCRIPTOR        *HeadTd
+  )
+{
+  TD_DESCRIPTOR           *TempTd;
+
+  TempTd = TD_PTR (Ed->Word2.TdHeadPointer);
+
+  if (TempTd != NULL) {
+    while (TempTd->NextTD != NULL) {
+      TempTd = TempTd->NextTD;
+    }
+    TempTd->NextTD = HeadTd;
+    TempTd->NextTDPointer = HeadTd;
+  } else {
+    Ed->Word2.TdHeadPointer = RIGHT_SHIFT_4 ((UINT32) HeadTd);
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+
+  Set value to ED specific field
+
+  @Param  Ed                    ED to be set
+  @Param  Field                 Field to be set
+  @Param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+EFI_STATUS
+OhciSetEDField (
+  IN ED_DESCRIPTOR        *Ed,
+  IN UINT32               Field,
+  IN UINT32               Value
+  )
+{
+  if (Field & ED_FUNC_ADD) {
+    Ed->Word0.FunctionAddress = Value;
+  }
+  if (Field & ED_ENDPT_NUM) {
+    Ed->Word0.EndPointNum = Value;
+  }
+  if (Field & ED_DIR) {
+    Ed->Word0.Direction = Value;
+  }
+  if (Field & ED_SPEED) {
+    Ed->Word0.Speed = Value;
+  }
+  if (Field & ED_SKIP) {
+    Ed->Word0.Skip = Value;
+  }
+  if (Field & ED_FORMAT) {
+    Ed->Word0.Format = Value;
+  }
+  if (Field & ED_MAX_PACKET) {
+    Ed->Word0.MaxPacketSize = Value;
+  }
+  if (Field & ED_PDATA) {
+    Ed->Word0.FreeSpace = Value;
+  }
+  if (Field & ED_ZERO) {
+    Ed->Word2.Zero = Value;
+  }
+  if (Field & ED_TDTAIL_PTR) {
+    Ed->TdTailPointer = (VOID *) Value;
+  }
+
+  if (Field & ED_HALTED) {
+    Ed->Word2.Halted = Value;
+  }
+  if (Field & ED_DTTOGGLE) {
+    Ed->Word2.ToggleCarry = Value;
+  }
+  if (Field & ED_TDHEAD_PTR) {
+    Ed->Word2.TdHeadPointer = RIGHT_SHIFT_4 (Value);
+  }
+
+  if (Field & ED_NEXT_EDPTR) {
+    Ed->NextED = (VOID *) Value;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Get value from an ED's specific field
+
+  @Param  Ed                    ED pointer
+  @Param  Field                 Field to get value from
+
+  @retval                       Value of the field
+
+**/
+UINT32
+OhciGetEDField (
+  IN ED_DESCRIPTOR        *Ed,
+  IN UINT32               Field
+  )
+{
+  switch (Field) {
+    case ED_FUNC_ADD:
+      return Ed->Word0.FunctionAddress;
+      break;
+    case ED_ENDPT_NUM:
+      return Ed->Word0.EndPointNum;
+      break;
+    case ED_DIR:
+      return Ed->Word0.Direction;
+      break;
+    case ED_SPEED:
+      return Ed->Word0.Speed;
+      break;
+    case ED_SKIP:
+      return Ed->Word0.Skip;
+      break;
+    case ED_FORMAT:
+      return Ed->Word0.Format;
+      break;
+    case ED_MAX_PACKET:
+      return Ed->Word0.MaxPacketSize;
+      break;
+
+    case ED_TDTAIL_PTR:
+      return (UINT32) Ed->TdTailPointer;
+      break;
+
+    case ED_HALTED:
+      return Ed->Word2.Halted;
+      break;
+
+    case ED_DTTOGGLE:
+      return Ed->Word2.ToggleCarry;
+      break;
+
+    case ED_TDHEAD_PTR:
+      return Ed->Word2.TdHeadPointer << 4;
+      break;
+
+    case ED_NEXT_EDPTR:
+      return (UINT32) Ed->NextED;
+      break;
+
+    default:
+      ASSERT (FALSE);
+  }
+
+  return 0;
+}
+
+
+/**
+
+  Set value to TD specific field
+
+  @Param  Td                    TD to be set
+  @Param  Field                 Field to be set
+  @Param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+EFI_STATUS
+OhciSetTDField (
+  IN TD_DESCRIPTOR        *Td,
+  IN UINT32               Field,
+  IN UINT32               Value
+  )
+{
+  if (Field & TD_PDATA) {
+    Td->Word0.Reserved = Value;
+  }
+  if (Field & TD_BUFFER_ROUND) {
+    Td->Word0.BufferRounding = Value;
+  }
+  if (Field & TD_DIR_PID) {
+    Td->Word0.DirPID = Value;
+  }
+  if (Field & TD_DELAY_INT) {
+    Td->Word0.DelayInterrupt = Value;
+  }
+  if (Field & TD_DT_TOGGLE) {
+    Td->Word0.DataToggle = Value | 0x2;
+  }
+  if (Field & TD_ERROR_CNT) {
+    Td->Word0.ErrorCount = Value;
+  }
+  if (Field & TD_COND_CODE) {
+    Td->Word0.ConditionCode = Value;
+  }
+
+  if (Field & TD_CURR_BUFFER_PTR) {
+    Td->CurrBufferPointer = (VOID *) Value;
+  }
+
+
+  if (Field & TD_NEXT_PTR) {
+    Td->NextTD = (VOID *) Value;
+  }
+
+  if (Field & TD_BUFFER_END_PTR) {
+    Td->BufferEndPointer = (VOID *) Value;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+
+  Get value from ED specific field
+
+  @Param  Td                    TD pointer
+  @Param  Field                 Field to get value from
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetTDField (
+  IN TD_DESCRIPTOR      *Td,
+  IN UINT32             Field
+  )
+{
+  switch (Field){
+    case TD_BUFFER_ROUND:
+      return Td->Word0.BufferRounding;
+      break;
+    case TD_DIR_PID:
+      return Td->Word0.DirPID;
+      break;
+    case TD_DELAY_INT:
+      return Td->Word0.DelayInterrupt;
+      break;
+    case TD_DT_TOGGLE:
+      return Td->Word0.DataToggle;
+      break;
+    case TD_ERROR_CNT:
+      return Td->Word0.ErrorCount;
+      break;
+    case TD_COND_CODE:
+      return Td->Word0.ConditionCode;
+      break;
+    case TD_CURR_BUFFER_PTR:
+      return (UINT32) Td->CurrBufferPointer;
+      break;
+
+    case TD_NEXT_PTR:
+      return (UINT32) Td->NextTD;
+      break;
+
+    case TD_BUFFER_END_PTR:
+      return (UINT32) Td->BufferEndPointer;
+      break;
+
+    default:
+      ASSERT (FALSE);
+  }
+
+  return 0;
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.h
new file mode 100644
index 0000000000..5172fbd1b5
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.h
@@ -0,0 +1,231 @@
+/** @file
+Provides some data struct used by OHCI controller driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#ifndef _OHCI_URB_H
+#define _OHCI_URB_H
+
+#include "Descriptor.h"
+
+
+//
+// Func List
+//
+
+
+/**
+
+  Create a TD
+
+  @Param  Ohc                   UHC private data
+
+  @retval                       TD structure pointer
+
+**/
+TD_DESCRIPTOR *
+OhciCreateTD (
+  IN USB_OHCI_HC_DEV      *Ohc
+  );
+
+/**
+
+  Free a TD
+
+  @Param  Ohc                   UHC private data
+  @Param  Td                    Pointer to a TD to free
+
+  @retval  EFI_SUCCESS          TD freed
+
+**/
+EFI_STATUS
+OhciFreeTD (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN TD_DESCRIPTOR        *Td
+  );
+
+/**
+
+  Create a ED
+
+  @Param   Ohc                  Device private data
+
+  @retval  ED                   descriptor pointer
+
+**/
+ED_DESCRIPTOR *
+OhciCreateED (
+  USB_OHCI_HC_DEV          *Ohc
+  );
+
+
+/**
+
+  Free a ED
+
+  @Param  Ohc                   UHC private data
+  @Param  Ed                    Pointer to a ED to free
+
+  @retval  EFI_SUCCESS          ED freed
+
+**/
+
+EFI_STATUS
+OhciFreeED (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN ED_DESCRIPTOR        *Ed
+  );
+
+/**
+
+  Free  ED
+
+  @Param  Ohc                    Device private data
+  @Param  Ed                     Pointer to a ED to free
+
+  @retval  EFI_SUCCESS           ED freed
+
+**/
+EFI_STATUS
+OhciFreeAllTDFromED (
+  IN USB_OHCI_HC_DEV      *Ohc,
+  IN ED_DESCRIPTOR        *Ed
+  );
+
+/**
+
+  Attach an ED
+
+  @Param  Ed                    Ed to be attached
+  @Param  NewEd                 Ed to attach
+
+  @retval EFI_SUCCESS           NewEd attached to Ed
+  @retval EFI_INVALID_PARAMETER Ed is NULL
+
+**/
+EFI_STATUS
+OhciAttachED (
+  IN ED_DESCRIPTOR        *Ed,
+  IN ED_DESCRIPTOR        *NewEd
+  );
+/**
+
+  Attach an ED to an ED list
+
+  @Param  OHC                   UHC private data
+  @Param  ListType              Type of the ED list
+  @Param  Ed                    ED to attach
+  @Param  EdList                ED list to be attached
+
+  @retval  EFI_SUCCESS          ED attached to ED list
+
+**/
+EFI_STATUS
+OhciAttachEDToList (
+  IN USB_OHCI_HC_DEV       *Ohc,
+  IN DESCRIPTOR_LIST_TYPE  ListType,
+  IN ED_DESCRIPTOR         *Ed,
+  IN ED_DESCRIPTOR         *EdList
+  );
+EFI_STATUS
+OhciLinkTD (
+  IN TD_DESCRIPTOR        *Td1,
+  IN TD_DESCRIPTOR        *Td2
+  );
+
+
+/**
+
+  Attach TD list to ED
+
+  @Param  Ed                    ED which TD list attach on
+  @Param  HeadTd                Head of the TD list to attach
+
+  @retval  EFI_SUCCESS          TD list attached on the ED
+
+**/
+EFI_STATUS
+OhciAttachTDListToED (
+  IN ED_DESCRIPTOR        *Ed,
+  IN TD_DESCRIPTOR        *HeadTd
+  );
+
+
+/**
+
+  Set value to ED specific field
+
+  @Param  Ed                    ED to be set
+  @Param  Field                 Field to be set
+  @Param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+EFI_STATUS
+OhciSetEDField (
+  IN ED_DESCRIPTOR        *Ed,
+  IN UINT32               Field,
+  IN UINT32               Value
+  );
+
+
+/**
+
+  Get value from an ED's specific field
+
+  @Param  Ed                    ED pointer
+  @Param  Field                 Field to get value from
+
+  @retval                       Value of the field
+
+**/
+UINT32
+OhciGetEDField (
+  IN ED_DESCRIPTOR        *Ed,
+  IN UINT32               Field
+  );
+
+
+/**
+
+  Set value to TD specific field
+
+  @Param  Td                    TD to be set
+  @Param  Field                 Field to be set
+  @Param  Value                 Value to set
+
+  @retval  EFI_SUCCESS          Value set
+
+**/
+EFI_STATUS
+OhciSetTDField (
+  IN TD_DESCRIPTOR        *Td,
+  IN UINT32               Field,
+  IN UINT32               Value
+  );
+
+
+/**
+
+  Get value from ED specific field
+
+  @Param  Td                    TD pointer
+  @Param  Field                 Field to get value from
+
+  @retval                       Value of the field
+
+**/
+
+UINT32
+OhciGetTDField (
+  IN TD_DESCRIPTOR      *Td,
+  IN UINT32             Field
+  );
+
+#endif
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.c b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.c
new file mode 100644
index 0000000000..a9c05523b4
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.c
@@ -0,0 +1,491 @@
+/** @file
+Routine procedures for memory allocate/free.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "OhcPeim.h"
+
+
+/**
+  Allocate a block of memory to be used by the buffer pool.
+
+  Use Redirect memory services to allocate memmory so that USB DMA transfers do
+  not cause IMR violations on Quark.
+
+  @param  Pool           The buffer pool to allocate memory for.
+  @param  Pages          How many pages to allocate.
+
+  @return The allocated memory block or NULL if failed.
+
+**/
+USBHC_MEM_BLOCK *
+UsbHcAllocMemBlock (
+  IN  USBHC_MEM_POOL      *Pool,
+  IN  UINTN               Pages
+  )
+{
+  USBHC_MEM_BLOCK         *Block;
+  VOID                    *BufHost;
+  VOID                    *Mapping;
+  EFI_PHYSICAL_ADDRESS    MappedAddr;
+  EFI_STATUS              Status;
+  UINTN                   PageNumber;
+  EFI_PHYSICAL_ADDRESS    TempPtr;
+
+  Mapping = NULL;
+  PageNumber =  sizeof(USBHC_MEM_BLOCK)/PAGESIZE +1;
+  Status = PeiServicesAllocatePages (
+             EfiBootServicesCode,
+             PageNumber,
+             &TempPtr
+             );
+
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+  ZeroMem ((VOID   *)(UINTN)TempPtr, PageNumber*EFI_PAGE_SIZE);
+
+  //
+  // each bit in the bit array represents USBHC_MEM_UNIT
+  // bytes of memory in the memory block.
+  //
+  ASSERT (USBHC_MEM_UNIT * 8 <= EFI_PAGE_SIZE);
+
+  Block = (USBHC_MEM_BLOCK*)(UINTN)TempPtr;
+  Block->BufLen   = EFI_PAGES_TO_SIZE (Pages);
+  Block->BitsLen  = Block->BufLen / (USBHC_MEM_UNIT * 8);
+
+  PageNumber =  (Block->BitsLen)/PAGESIZE +1;
+  Status = PeiServicesAllocatePages (
+             EfiBootServicesCode,
+             PageNumber,
+             &TempPtr
+             );
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+  ZeroMem ((VOID   *)(UINTN)TempPtr, PageNumber*EFI_PAGE_SIZE);
+
+  Block->Bits  = (UINT8 *)(UINTN)TempPtr;
+
+  Status = PeiServicesAllocatePages (
+             EfiBootServicesCode,
+             Pages,
+             &TempPtr
+             );
+  ZeroMem ((VOID   *)(UINTN)TempPtr, Pages*EFI_PAGE_SIZE);
+
+  BufHost  = (VOID *)(UINTN)TempPtr;
+  MappedAddr = (EFI_PHYSICAL_ADDRESS) (UINTN) BufHost;
+  //
+  // Check whether the data structure used by the host controller
+  // should be restricted into the same 4G
+  //
+  if (Pool->Check4G && (Pool->Which4G != USB_HC_HIGH_32BIT (MappedAddr))) {
+    return NULL;
+  }
+
+  Block->BufHost  = BufHost;
+  Block->Buf      = (UINT8 *) ((UINTN) MappedAddr);
+  Block->Mapping  = Mapping;
+  Block->Next     = NULL;
+
+  return Block;
+
+}
+
+
+/**
+  Free the memory block from the memory pool.
+
+  @param  Pool           The memory pool to free the block from.
+  @param  Block          The memory block to free.
+
+**/
+VOID
+UsbHcFreeMemBlock (
+  IN USBHC_MEM_POOL       *Pool,
+  IN USBHC_MEM_BLOCK      *Block
+  )
+{
+
+  ASSERT ((Pool != NULL) && (Block != NULL));
+}
+
+
+/**
+  Alloc some memory from the block.
+
+  @param  Block          The memory block to allocate memory from.
+  @param  Units          Number of memory units to allocate.
+
+  @return The pointer to the allocated memory. If couldn't allocate the needed memory,
+          the return value is NULL.
+
+**/
+VOID *
+UsbHcAllocMemFromBlock (
+  IN  USBHC_MEM_BLOCK     *Block,
+  IN  UINTN               Units
+  )
+{
+  UINTN                   Byte;
+  UINT8                   Bit;
+  UINTN                   StartByte;
+  UINT8                   StartBit;
+  UINTN                   Available;
+  UINTN                   Count;
+
+  ASSERT ((Block != 0) && (Units != 0));
+
+  StartByte  = 0;
+  StartBit   = 0;
+  Available  = 0;
+
+  for (Byte = 0, Bit = 0; Byte < Block->BitsLen;) {
+    //
+    // If current bit is zero, the corresponding memory unit is
+    // available, otherwise we need to restart our searching.
+    // Available counts the consective number of zero bit.
+    //
+    if (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)) {
+      Available++;
+
+      if (Available >= Units) {
+        break;
+      }
+
+      NEXT_BIT (Byte, Bit);
+
+    } else {
+      NEXT_BIT (Byte, Bit);
+
+      Available  = 0;
+      StartByte  = Byte;
+      StartBit   = Bit;
+    }
+  }
+
+  if (Available < Units) {
+    return NULL;
+  }
+
+  //
+  // Mark the memory as allocated
+  //
+  Byte  = StartByte;
+  Bit   = StartBit;
+
+  for (Count = 0; Count < Units; Count++) {
+    ASSERT (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit));
+
+    Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] | (UINT8) USB_HC_BIT (Bit));
+    NEXT_BIT (Byte, Bit);
+  }
+
+  return Block->BufHost + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT;
+}
+
+/**
+  Insert the memory block to the pool's list of the blocks.
+
+  @param  Head           The head of the memory pool's block list.
+  @param  Block          The memory block to insert.
+
+**/
+VOID
+UsbHcInsertMemBlockToPool (
+  IN USBHC_MEM_BLOCK      *Head,
+  IN USBHC_MEM_BLOCK      *Block
+  )
+{
+  ASSERT ((Head != NULL) && (Block != NULL));
+  Block->Next = Head->Next;
+  Head->Next  = Block;
+}
+
+
+/**
+  Is the memory block empty?
+
+  @param  Block   The memory block to check.
+
+  @retval TRUE    The memory block is empty.
+  @retval FALSE   The memory block isn't empty.
+
+**/
+BOOLEAN
+UsbHcIsMemBlockEmpty (
+  IN USBHC_MEM_BLOCK     *Block
+  )
+{
+  UINTN                   Index;
+
+  for (Index = 0; Index < Block->BitsLen; Index++) {
+    if (Block->Bits[Index] != 0) {
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
+
+/**
+  Unlink the memory block from the pool's list.
+
+  @param  Head           The block list head of the memory's pool.
+  @param  BlockToUnlink  The memory block to unlink.
+
+**/
+VOID
+UsbHcUnlinkMemBlock (
+  IN USBHC_MEM_BLOCK      *Head,
+  IN USBHC_MEM_BLOCK      *BlockToUnlink
+  )
+{
+  USBHC_MEM_BLOCK         *Block;
+
+  ASSERT ((Head != NULL) && (BlockToUnlink != NULL));
+
+  for (Block = Head; Block != NULL; Block = Block->Next) {
+    if (Block->Next == BlockToUnlink) {
+      Block->Next         = BlockToUnlink->Next;
+      BlockToUnlink->Next = NULL;
+      break;
+    }
+  }
+}
+
+
+/**
+  Initialize the memory management pool for the host controller.
+
+  @param  PciIo                The PciIo that can be used to access the host controller.
+  @param  Check4G              Whether the host controller requires allocated memory
+                               from one 4G address space.
+  @param  Which4G              The 4G memory area each memory allocated should be from.
+
+  @retval EFI_SUCCESS          The memory pool is initialized.
+  @retval EFI_OUT_OF_RESOURCE  Fail to init the memory pool.
+
+**/
+USBHC_MEM_POOL *
+UsbHcInitMemPool (
+  IN BOOLEAN              Check4G,
+  IN UINT32               Which4G
+  )
+{
+  USBHC_MEM_POOL          *Pool;
+  UINTN                   PageNumber;
+  EFI_STATUS              Status;
+  EFI_PHYSICAL_ADDRESS    TempPtr;
+
+  PageNumber =  sizeof(USBHC_MEM_POOL)/PAGESIZE +1;
+  Status = PeiServicesAllocatePages (
+             EfiBootServicesCode,
+             PageNumber,
+             &TempPtr
+             );
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+  ZeroMem ((VOID   *)(UINTN)TempPtr, PageNumber*EFI_PAGE_SIZE);
+
+  Pool = (USBHC_MEM_POOL *) ((UINTN) TempPtr);
+  Pool->Check4G = Check4G;
+  Pool->Which4G = Which4G;
+  Pool->Head    = UsbHcAllocMemBlock (Pool, USBHC_MEM_DEFAULT_PAGES);
+
+  if (Pool->Head == NULL) {
+    Pool = NULL;
+  }
+
+  return Pool;
+}
+
+
+/**
+  Release the memory management pool.
+
+  @param  Pool              The USB memory pool to free.
+
+  @retval EFI_SUCCESS       The memory pool is freed.
+  @retval EFI_DEVICE_ERROR  Failed to free the memory pool.
+
+**/
+EFI_STATUS
+UsbHcFreeMemPool (
+  IN USBHC_MEM_POOL       *Pool
+  )
+{
+  USBHC_MEM_BLOCK *Block;
+
+  ASSERT (Pool->Head != NULL);
+
+  //
+  // Unlink all the memory blocks from the pool, then free them.
+  // UsbHcUnlinkMemBlock can't be used to unlink and free the
+  // first block.
+  //
+  for (Block = Pool->Head->Next; Block != NULL; Block = Pool->Head->Next) {
+    UsbHcFreeMemBlock (Pool, Block);
+  }
+
+  UsbHcFreeMemBlock (Pool, Pool->Head);
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Allocate some memory from the host controller's memory pool
+  which can be used to communicate with host controller.
+
+  @param  Pool           The host controller's memory pool.
+  @param  Size           Size of the memory to allocate.
+
+  @return The allocated memory or NULL.
+
+**/
+VOID *
+UsbHcAllocateMem (
+  IN  USBHC_MEM_POOL      *Pool,
+  IN  UINTN               Size
+  )
+{
+  USBHC_MEM_BLOCK         *Head;
+  USBHC_MEM_BLOCK         *Block;
+  USBHC_MEM_BLOCK         *NewBlock;
+  VOID                    *Mem;
+  UINTN                   AllocSize;
+  UINTN                   Pages;
+
+  Mem       = NULL;
+  AllocSize = USBHC_MEM_ROUND (Size);
+  Head      = Pool->Head;
+  ASSERT (Head != NULL);
+
+  //
+  // First check whether current memory blocks can satisfy the allocation.
+  //
+  for (Block = Head; Block != NULL; Block = Block->Next) {
+    Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT);
+
+    if (Mem != NULL) {
+      ZeroMem (Mem, Size);
+      break;
+    }
+  }
+
+  if (Mem != NULL) {
+    return Mem;
+  }
+
+  //
+  // Create a new memory block if there is not enough memory
+  // in the pool. If the allocation size is larger than the
+  // default page number, just allocate a large enough memory
+  // block. Otherwise allocate default pages.
+  //
+  if (AllocSize > EFI_PAGES_TO_SIZE (USBHC_MEM_DEFAULT_PAGES)) {
+    Pages = EFI_SIZE_TO_PAGES (AllocSize) + 1;
+  } else {
+    Pages = USBHC_MEM_DEFAULT_PAGES;
+  }
+
+  NewBlock = UsbHcAllocMemBlock (Pool, Pages);
+
+  if (NewBlock == NULL) {
+    DEBUG ((EFI_D_INFO, "UsbHcAllocateMem: failed to allocate block\n"));
+    return NULL;
+  }
+
+  //
+  // Add the new memory block to the pool, then allocate memory from it
+  //
+  UsbHcInsertMemBlockToPool (Head, NewBlock);
+  Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT);
+
+  if (Mem != NULL) {
+    ZeroMem (Mem, Size);
+  }
+
+  return Mem;
+}
+
+
+/**
+  Free the allocated memory back to the memory pool.
+
+  @param  Pool           The memory pool of the host controller.
+  @param  Mem            The memory to free.
+  @param  Size           The size of the memory to free.
+
+**/
+VOID
+UsbHcFreeMem (
+  IN USBHC_MEM_POOL       *Pool,
+  IN VOID                 *Mem,
+  IN UINTN                Size
+  )
+{
+  USBHC_MEM_BLOCK         *Head;
+  USBHC_MEM_BLOCK         *Block;
+  UINT8                   *ToFree;
+  UINTN                   AllocSize;
+  UINTN                   Byte;
+  UINTN                   Bit;
+  UINTN                   Count;
+
+  Head      = Pool->Head;
+  AllocSize = USBHC_MEM_ROUND (Size);
+  ToFree    = (UINT8 *) Mem;
+
+  for (Block = Head; Block != NULL; Block = Block->Next) {
+    //
+    // scan the memory block list for the memory block that
+    // completely contains the memory to free.
+    //
+    if ((Block->BufHost <= ToFree) && ((ToFree + AllocSize) <= (Block->BufHost + Block->BufLen))) {
+      //
+      // compute the start byte and bit in the bit array
+      //
+      Byte  = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) / 8;
+      Bit   = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) % 8;
+
+      //
+      // reset associated bits in bit arry
+      //
+      for (Count = 0; Count < (AllocSize / USBHC_MEM_UNIT); Count++) {
+        ASSERT (USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit));
+
+        Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] ^ USB_HC_BIT (Bit));
+        NEXT_BIT (Byte, Bit);
+      }
+
+      break;
+    }
+  }
+
+  //
+  // If Block == NULL, it means that the current memory isn't
+  // in the host controller's pool. This is critical because
+  // the caller has passed in a wrong memory point
+  //
+  ASSERT (Block != NULL);
+
+  //
+  // Release the current memory block if it is empty and not the head
+  //
+  if ((Block != Head) && UsbHcIsMemBlockEmpty (Block)) {
+    UsbHcFreeMemBlock (Pool, Block);
+  }
+
+  return ;
+}
diff --git a/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.h b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.h
new file mode 100644
index 0000000000..ad0d73e64d
--- /dev/null
+++ b/Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.h
@@ -0,0 +1,134 @@
+/** @file
+This file contains the definination for host controller memory
+management routines.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _USB_HC_MEM_H_
+#define _USB_HC_MEM_H_
+
+#define USB_HC_BIT(a)                  ((UINTN)(1 << (a)))
+
+#define USB_HC_BIT_IS_SET(Data, Bit)   \
+          ((BOOLEAN)(((Data) & USB_HC_BIT(Bit)) == USB_HC_BIT(Bit)))
+
+#define USB_HC_HIGH_32BIT(Addr64)    \
+          ((UINT32)(RShiftU64((UINTN)(Addr64), 32) & 0XFFFFFFFF))
+
+typedef struct _USBHC_MEM_BLOCK USBHC_MEM_BLOCK;
+struct _USBHC_MEM_BLOCK {
+  UINT8                   *Bits;    // Bit array to record which unit is allocated
+  UINTN                   BitsLen;
+  UINT8                   *Buf;
+  UINT8                   *BufHost;
+  UINTN                   BufLen;   // Memory size in bytes
+  VOID                    *Mapping;
+  USBHC_MEM_BLOCK         *Next;
+};
+
+//
+// USBHC_MEM_POOL is used to manage the memory used by USB
+// host controller. EHCI requires the control memory and transfer
+// data to be on the same 4G memory.
+//
+typedef struct _USBHC_MEM_POOL {
+  BOOLEAN                 Check4G;
+  UINT32                  Which4G;
+  USBHC_MEM_BLOCK         *Head;
+} USBHC_MEM_POOL;
+
+//
+// Memory allocation unit, must be 2^n, n>4
+//
+#define USBHC_MEM_UNIT           64
+
+#define USBHC_MEM_UNIT_MASK      (USBHC_MEM_UNIT - 1)
+#define USBHC_MEM_DEFAULT_PAGES  16
+
+#define USBHC_MEM_ROUND(Len)  (((Len) + USBHC_MEM_UNIT_MASK) & (~USBHC_MEM_UNIT_MASK))
+
+//
+// Advance the byte and bit to the next bit, adjust byte accordingly.
+//
+#define NEXT_BIT(Byte, Bit)   \
+          do {                \
+            (Bit)++;          \
+            if ((Bit) > 7) {  \
+              (Byte)++;       \
+              (Bit) = 0;      \
+            }                 \
+          } while (0)
+
+
+
+/**
+  Initialize the memory management pool for the host controller.
+
+  @param  PciIo               The PciIo that can be used to access the host controller.
+  @param  Check4G             Whether the host controller requires allocated memory
+                              from one 4G address space.
+  @param  Which4G             The 4G memory area each memory allocated should be from.
+
+  @retval EFI_SUCCESS         The memory pool is initialized.
+  @retval EFI_OUT_OF_RESOURCE Fail to init the memory pool.
+
+**/
+USBHC_MEM_POOL *
+UsbHcInitMemPool (
+  IN BOOLEAN              Check4G,
+  IN UINT32               Which4G
+  );
+
+
+/**
+  Release the memory management pool.
+
+  @param   Pool               The USB memory pool to free.
+
+  @retval EFI_SUCCESS       The memory pool is freed.
+  @retval EFI_DEVICE_ERROR  Failed to free the memory pool.
+
+**/
+EFI_STATUS
+UsbHcFreeMemPool (
+  IN USBHC_MEM_POOL       *Pool
+  );
+
+
+/**
+  Allocate some memory from the host controller's memory pool
+  which can be used to communicate with host controller.
+
+  @param  Pool  The host controller's memory pool.
+  @param  Size  Size of the memory to allocate.
+
+  @return The allocated memory or NULL.
+
+**/
+VOID *
+UsbHcAllocateMem (
+  IN  USBHC_MEM_POOL      *Pool,
+  IN  UINTN               Size
+  );
+
+
+/**
+  Free the allocated memory back to the memory pool.
+
+  @param  Pool  The memory pool of the host controller.
+  @param  Mem   The memory to free.
+  @param  Size  The size of the memory to free.
+
+**/
+VOID
+UsbHcFreeMem (
+  IN USBHC_MEM_POOL       *Pool,
+  IN VOID                 *Mem,
+  IN UINTN                Size
+  );
+
+#endif
-- 
2.21.0.windows.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [edk2-platforms: Patch 4/8] Platform/QuarkPlatformPkg: Import QuarkPlatformPkg from edk2
  2019-05-10  3:34 [edk2-platforms: Patch 0/8] Add packages from edk2 Michael D Kinney
                   ` (2 preceding siblings ...)
  2019-05-10  3:34 ` [edk2-platforms: Patch 3/8] Silicon/Intel: Import QuarkSocPkg " Michael D Kinney
@ 2019-05-10  3:34 ` Michael D Kinney
  2019-05-10  3:34 ` [edk2-platforms: Patch 5/8] Platform/Vlv2DeviceRefCodePkg: Import Vlv2DeviceRefCodePkg " Michael D Kinney
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 23+ messages in thread
From: Michael D Kinney @ 2019-05-10  3:34 UTC (permalink / raw)
  To: devel; +Cc: Kelly Steele, Michael Kubacki, Leif Lindholm, Ard Biesheuvel

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

Import QuarkPlatformPkg from edk2/master.

Cc: Kelly Steele <kelly.steele@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>
---
 .../Acpi/AcpiTables/AcpiTables.inf            |   42 +
 .../Acpi/AcpiTables/Cpu0Cst/Cpu0Cst.asl       |  399 ++++
 .../Acpi/AcpiTables/Cpu0Ist/Cpu0Ist.asl       |  159 ++
 .../Acpi/AcpiTables/Cpu0Tst/Cpu0Tst.asl       |  133 ++
 .../Acpi/AcpiTables/CpuPm/CpuPm.asl           |   73 +
 .../Acpi/AcpiTables/Dsdt/AD7298.asi           |   38 +
 .../Acpi/AcpiTables/Dsdt/ADC108S102.asi       |   33 +
 .../Acpi/AcpiTables/Dsdt/CAT24C08.asi         |   34 +
 .../Acpi/AcpiTables/Dsdt/CY8C9540A.asi        |   47 +
 .../Acpi/AcpiTables/Dsdt/GpioClient.asi       |   89 +
 .../Acpi/AcpiTables/Dsdt/LpcDev.asi           |  248 ++
 .../Acpi/AcpiTables/Dsdt/PCA9685.asi          |   34 +
 .../Acpi/AcpiTables/Dsdt/PCAL9555A.asi        |   90 +
 .../Acpi/AcpiTables/Dsdt/PciHostBridge.asi    |  195 ++
 .../Acpi/AcpiTables/Dsdt/PciIrq.asi           |  552 +++++
 .../Acpi/AcpiTables/Dsdt/PcieExpansionPrt.asi |  127 +
 .../Acpi/AcpiTables/Dsdt/Platform.asl         |  347 +++
 .../Acpi/AcpiTables/Dsdt/QNC.asi              |   49 +
 .../Acpi/AcpiTables/Dsdt/QNCApic.asi          |   32 +
 .../Acpi/AcpiTables/Dsdt/QNCLpc.asi           |   23 +
 .../AcpiTables/Dsdt/QuarkSouthCluster.asi     |  110 +
 .../Acpi/AcpiTables/Dsdt/Tpm.asi              |   45 +
 .../Acpi/AcpiTables/Facs/Facs.aslc            |   74 +
 .../Acpi/AcpiTables/Facs/Facs.h               |   29 +
 .../Acpi/AcpiTables/Fadt/Fadt.h               |  102 +
 .../Acpi/AcpiTables/Fadt/Fadt1.0.aslc         |   76 +
 .../Acpi/AcpiTables/Fadt/Fadt2.0.aslc         |  157 ++
 .../Acpi/AcpiTables/Hpet/Hpet.aslc            |   68 +
 .../Acpi/AcpiTables/Hpet/Hpet.h               |   45 +
 .../Acpi/AcpiTables/Mcfg/Mcfg.aslc            |   75 +
 .../Acpi/AcpiTables/Mcfg/Mcfg.h               |   56 +
 .../Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.c     | 1402 +++++++++++
 .../Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.h     |  316 +++
 .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.c      |  805 +++++++
 .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.h      |  120 +
 .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.inf    |  196 ++
 .../Acpi/Dxe/AcpiPlatform/Madt.h              |  207 ++
 .../Acpi/Dxe/AcpiPlatform/MadtPlatform.c      |  300 +++
 .../BootScriptExecutorDxe.inf                 |   77 +
 .../Dxe/BootScriptExecutorDxe/IA32/S3Asm.S    |   44 +
 .../Dxe/BootScriptExecutorDxe/IA32/S3Asm.asm  |   51 +
 .../BootScriptExecutorDxe/IA32/SetIdtEntry.c  |   57 +
 .../Dxe/BootScriptExecutorDxe/ScriptExecute.c |  379 +++
 .../Dxe/BootScriptExecutorDxe/ScriptExecute.h |   70 +
 .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.c     | 1011 ++++++++
 .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.h     |  167 ++
 .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.inf   |   78 +
 .../Acpi/DxeSmm/SmmPowerManagement/Ppm.c      |  372 +++
 .../Acpi/DxeSmm/SmmPowerManagement/Ppm.h      |  150 ++
 .../SmmPowerManagement/SmmPowerManagement.c   |  113 +
 .../SmmPowerManagement/SmmPowerManagement.h   |   52 +
 .../SmmPowerManagement/SmmPowerManagement.inf |   74 +
 .../Application/ForceRecovery/ForceRecovery.c |   47 +
 .../ForceRecovery/ForceRecovery.inf           |   34 +
 .../PlatformFlashAccessLibDxe.c               |  262 +++
 .../PlatformFlashAccessLibDxe.inf             |   47 +
 .../PlatformFlashAccessLib/SpiFlashDevice.c   |  330 +++
 .../PlatformFlashAccessLib/SpiFlashDevice.h   |  180 ++
 .../SystemFirmwareDescriptor.aslc             |   83 +
 .../SystemFirmwareDescriptor.inf              |   40 +
 .../SystemFirmwareDescriptorPei.c             |   60 +
 .../SystemFirmwareUpdateConfig.ini            |   57 +
 .../Include/Guid/CapsuleOnDataCD.h            |   23 +
 .../Include/Guid/CapsuleOnFatFloppyDisk.h     |   23 +
 .../Include/Guid/CapsuleOnFatIdeDisk.h        |   24 +
 .../Include/Guid/CapsuleOnFatUsbDisk.h        |   24 +
 .../Include/Guid/MemoryConfigData.h           |   23 +
 .../Include/Guid/QuarkCapsuleGuid.h           |   46 +
 .../Include/Guid/QuarkVariableLock.h          |   23 +
 .../Include/Guid/SystemNvDataHobGuid.h        |   29 +
 .../Include/Library/PlatformHelperLib.h       |  266 +++
 .../Include/Library/PlatformPcieHelperLib.h   |   56 +
 .../Intel/QuarkPlatformPkg/Include/Pcal9555.h |   24 +
 .../Intel/QuarkPlatformPkg/Include/Platform.h |  119 +
 .../QuarkPlatformPkg/Include/PlatformBoards.h |  166 ++
 .../Include/Protocol/GlobalNvsArea.h          |   82 +
 .../Include/Protocol/PlatformSmmSpiReady.h    |   23 +
 .../PlatformBootManager.c                     |  472 ++++
 .../PlatformBootManager.h                     |   49 +
 .../PlatformBootManagerLib.inf                |   83 +
 .../PlatformBootManagerLib/PlatformData.c     |  275 +++
 .../Library/PlatformHelperLib/CommonHeader.h  |   51 +
 .../DxePlatformHelperLib.inf                  |   70 +
 .../PeiPlatformHelperLib.inf                  |   45 +
 .../PlatformHelperLib/PlatformHelperDxe.c     |  337 +++
 .../PlatformHelperLib/PlatformHelperLib.c     |  481 ++++
 .../PlatformHelperLib/PlatformHelperPei.c     |  159 ++
 .../Library/PlatformHelperLib/PlatformLeds.c  |  146 ++
 .../PlatformPcieHelperLib/CommonHeader.h      |   55 +
 .../PlatformPcieHelperLib.c                   |  114 +
 .../PlatformPcieHelperLib.inf                 |   41 +
 .../Library/PlatformPcieHelperLib/SocUnit.c   |  125 +
 .../Library/PlatformSecLib/Ia32/Flat32.S      |  796 +++++++
 .../Library/PlatformSecLib/Ia32/Flat32.asm    |  685 ++++++
 .../Library/PlatformSecLib/Ia32/Platform.inc  |  134 ++
 .../Library/PlatformSecLib/PlatformSecLib.c   |  207 ++
 .../Library/PlatformSecLib/PlatformSecLib.inf |   54 +
 .../PlatformSecLib/PlatformSecLibModStrs.uni  |   18 +
 .../PlatformSecureLib/PlatformSecureLib.c     |  164 ++
 .../PlatformSecureLib/PlatformSecureLib.inf   |   41 +
 .../Library/Tpm12DeviceLibAtmelI2c/TisPc.c    |  408 ++++
 .../Tpm12DeviceLibAtmelI2c.inf                |   39 +
 .../Tpm12DeviceLibAtmelI2c.uni                |   16 +
 .../Library/Tpm12DeviceLibInfineonI2c/TisPc.c |  612 +++++
 .../Tpm12DeviceLibInfineonI2c.inf             |   39 +
 .../Tpm12DeviceLibInfineonI2c.uni             |   16 +
 .../Pci/Dxe/PciHostBridge/PciHostBridge.c     | 1397 +++++++++++
 .../Pci/Dxe/PciHostBridge/PciHostBridge.h     |  389 ++++
 .../Pci/Dxe/PciHostBridge/PciHostBridge.inf   |   61 +
 .../Dxe/PciHostBridge/PciHostBridgeSupport.c  |  140 ++
 .../Pci/Dxe/PciHostBridge/PciHostResource.h   |   60 +
 .../Pci/Dxe/PciHostBridge/PciRootBridge.h     |  693 ++++++
 .../Pci/Dxe/PciHostBridge/PciRootBridgeIo.c   | 1610 +++++++++++++
 .../Pci/Dxe/PciPlatform/CommonHeader.h        |   31 +
 .../Pci/Dxe/PciPlatform/PciPlatform.c         |  194 ++
 .../Pci/Dxe/PciPlatform/PciPlatform.h         |   82 +
 .../Pci/Dxe/PciPlatform/PciPlatform.inf       |   54 +
 .../Dxe/MemorySubClass/MemorySubClass.c       |  435 ++++
 .../Dxe/MemorySubClass/MemorySubClass.h       |   65 +
 .../Dxe/MemorySubClass/MemorySubClass.inf     |   60 +
 .../MemorySubClass/MemorySubClassStrings.uni  |   29 +
 .../Dxe/PlatformInit/PlatformConfig.c         |  443 ++++
 .../Dxe/PlatformInit/PlatformInitDxe.c        |   87 +
 .../Dxe/PlatformInit/PlatformInitDxe.h        |   58 +
 .../Dxe/PlatformInit/PlatformInitDxe.inf      |   56 +
 .../Dxe/SaveMemoryConfig/SaveMemoryConfig.c   |  118 +
 .../Dxe/SaveMemoryConfig/SaveMemoryConfig.inf |   44 +
 .../Platform/Dxe/Setup/CommonHeader.h         |   55 +
 .../Platform/Dxe/Setup/DxePlatform.inf        |   76 +
 .../Platform/Dxe/Setup/KeyboardLayout.c       |  262 +++
 .../Platform/Dxe/Setup/QNCRegTable.c          |   80 +
 .../Platform/Dxe/Setup/SetupPlatform.c        |   97 +
 .../Platform/Dxe/Setup/SetupPlatform.h        |   71 +
 .../Platform/Dxe/Setup/Strings.uni            |   47 +
 .../Platform/Dxe/Setup/processor.c            |   40 +
 .../Platform/Dxe/SmbiosMiscDxe/CommonHeader.h |   34 +
 .../MiscBaseBoardManufacturer.uni             |   19 +
 .../MiscBaseBoardManufacturerData.c           |   45 +
 .../MiscBaseBoardManufacturerFunction.c       |  181 ++
 .../Dxe/SmbiosMiscDxe/MiscBiosVendor.uni      |   18 +
 .../Dxe/SmbiosMiscDxe/MiscBiosVendorData.c    |   92 +
 .../SmbiosMiscDxe/MiscBiosVendorFunction.c    |  222 ++
 .../SmbiosMiscDxe/MiscBootInformationData.c   |   24 +
 .../MiscBootInformationFunction.c             |   71 +
 .../SmbiosMiscDxe/MiscChassisManufacturer.uni |   17 +
 .../MiscChassisManufacturerData.c             |   36 +
 .../MiscChassisManufacturerFunction.c         |  168 ++
 .../Dxe/SmbiosMiscDxe/MiscDevicePath.h        |   42 +
 .../MiscNumberOfInstallableLanguagesData.c    |   28 +
 ...MiscNumberOfInstallableLanguagesFunction.c |  240 ++
 .../Dxe/SmbiosMiscDxe/MiscOemString.uni       |   12 +
 .../Dxe/SmbiosMiscDxe/MiscOemStringData.c     |   20 +
 .../Dxe/SmbiosMiscDxe/MiscOemStringFunction.c |   78 +
 .../Dxe/SmbiosMiscDxe/MiscOnboardDevice.uni   |   18 +
 .../Dxe/SmbiosMiscDxe/MiscOnboardDeviceData.c |   49 +
 .../SmbiosMiscDxe/MiscOnboardDeviceFunction.c |  105 +
 .../MiscPortInternalConnectorDesignator.uni   |   53 +
 .../MiscPortInternalConnectorDesignatorData.c |  184 ++
 ...cPortInternalConnectorDesignatorFunction.c |  292 +++
 .../SmbiosMiscDxe/MiscSystemManufacturer.uni  |   20 +
 .../MiscSystemManufacturerData.c              |   32 +
 .../MiscSystemManufacturerFunction.c          |  198 ++
 .../SmbiosMiscDxe/MiscSystemOptionString.uni  |   14 +
 .../MiscSystemOptionStringData.c              |   23 +
 .../MiscSystemOptionStringFunction.c          |   81 +
 .../MiscSystemSlotDesignation.uni             |   27 +
 .../MiscSystemSlotDesignationData.c           |  357 +++
 .../MiscSystemSlotDesignationFunction.c       |  285 +++
 .../MiscSystemSlotOnboardDevices.uni          |   23 +
 .../Platform/Dxe/SmbiosMiscDxe/SmbiosMisc.h   |  137 ++
 .../Dxe/SmbiosMiscDxe/SmbiosMiscDataTable.c   |  109 +
 .../Dxe/SmbiosMiscDxe/SmbiosMiscDxe.inf       |  308 +++
 .../Dxe/SmbiosMiscDxe/SmbiosMiscEntryPoint.c  |   82 +
 .../Dxe/SmbiosMiscDxe/SmbiosMiscStrings.uni   |   26 +
 .../Pei/PlatformConfig/PlatformConfigPei.c    |   81 +
 .../Pei/PlatformConfig/PlatformConfigPei.inf  |   45 +
 .../Platform/Pei/PlatformInit/BootMode.c      |  218 ++
 .../Platform/Pei/PlatformInit/CommonHeader.h  |   81 +
 .../Pei/PlatformInit/Generic/Recovery.c       |  467 ++++
 .../Pei/PlatformInit/MemoryCallback.c         |  279 +++
 .../Platform/Pei/PlatformInit/MrcWrapper.c    | 1565 +++++++++++++
 .../Platform/Pei/PlatformInit/MrcWrapper.h    |  225 ++
 .../Platform/Pei/PlatformInit/PeiFvSecurity.c |  111 +
 .../Platform/Pei/PlatformInit/PeiFvSecurity.h |   67 +
 .../Pei/PlatformInit/PlatformEarlyInit.c      | 1227 ++++++++++
 .../Pei/PlatformInit/PlatformEarlyInit.h      |  301 +++
 .../Pei/PlatformInit/PlatformEarlyInit.inf    |  193 ++
 .../Pei/PlatformInit/PlatformErratas.c        |  178 ++
 .../Platform/SpiFvbServices/FvbInfo.c         |  332 +++
 .../Platform/SpiFvbServices/FwBlockService.c  | 2053 +++++++++++++++++
 .../Platform/SpiFvbServices/FwBlockService.h  |  308 +++
 .../Platform/SpiFvbServices/PlatformSmmSpi.c  |   31 +
 .../SpiFvbServices/PlatformSmmSpi.inf         |   80 +
 .../Platform/SpiFvbServices/PlatformSpi.inf   |   79 +
 .../Platform/SpiFvbServices/SpiFlashDevice.c  |  331 +++
 .../Platform/SpiFvbServices/SpiFlashDevice.h  |  181 ++
 Platform/Intel/QuarkPlatformPkg/Quark.dsc     |  948 ++++++++
 Platform/Intel/QuarkPlatformPkg/Quark.fdf     |  907 ++++++++
 Platform/Intel/QuarkPlatformPkg/QuarkMin.dsc  |  648 ++++++
 Platform/Intel/QuarkPlatformPkg/QuarkMin.fdf  |  608 +++++
 .../QuarkPlatformPkg/QuarkPlatformPkg.dec     |  933 ++++++++
 Platform/Intel/QuarkPlatformPkg/Readme.md     |  685 ++++++
 202 files changed, 41211 insertions(+)
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/AcpiTables.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Cst/Cpu0Cst.asl
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Ist/Cpu0Ist.asl
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Tst/Cpu0Tst.asl
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/CpuPm/CpuPm.asl
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/AD7298.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/ADC108S102.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/CAT24C08.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/CY8C9540A.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/GpioClient.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/LpcDev.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PCA9685.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PCAL9555A.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PciHostBridge.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PciIrq.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PcieExpansionPrt.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Platform.asl
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNC.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNCApic.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNCLpc.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QuarkSouthCluster.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Tpm.asi
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Facs/Facs.aslc
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Facs/Facs.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt1.0.aslc
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt2.0.aslc
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.aslc
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Mcfg/Mcfg.aslc
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Mcfg/Mcfg.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Madt.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/MadtPlatform.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/S3Asm.S
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/S3Asm.asm
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/SetIdtEntry.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/ScriptExecute.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/ScriptExecute.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/Ppm.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/Ppm.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/SmmPowerManagement.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/SmmPowerManagement.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/SmmPowerManagement.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Application/ForceRecovery/ForceRecovery.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Application/ForceRecovery/ForceRecovery.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLibDxe.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLibDxe.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAccessLib/SpiFlashDevice.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAccessLib/SpiFlashDevice.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptor.aslc
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptor.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptorPei.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareUpdateConfig/SystemFirmwareUpdateConfig.ini
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnDataCD.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatFloppyDisk.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatIdeDisk.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatUsbDisk.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Guid/MemoryConfigData.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Guid/QuarkCapsuleGuid.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Guid/QuarkVariableLock.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Guid/SystemNvDataHobGuid.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Library/PlatformHelperLib.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Library/PlatformPcieHelperLib.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Pcal9555.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Platform.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/PlatformBoards.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Protocol/GlobalNvsArea.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Protocol/PlatformSmmSpiReady.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManager.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManager.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/CommonHeader.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/DxePlatformHelperLib.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PeiPlatformHelperLib.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperDxe.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperLib.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperPei.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformLeds.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/CommonHeader.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPcieHelperLib.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPcieHelperLib.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/SocUnit.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Flat32.S
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Flat32.asm
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Platform.inc
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLibModStrs.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecureLib.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/TisPc.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/TisPc.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/Tpm12DeviceLibInfineonI2c.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/Tpm12DeviceLibInfineonI2c.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridgeSupport.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostResource.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridge.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridgeIo.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/CommonHeader.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClassStrings.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformConfig.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveMemoryConfig.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveMemoryConfig.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/CommonHeader.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/DxePlatform.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/KeyboardLayout.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/QNCRegTable.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/Strings.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/processor.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/CommonHeader.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturer.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturerData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturerFunction.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendor.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendorData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendorFunction.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootInformationData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootInformationFunction.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturer.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturerData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturerFunction.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscDevicePath.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumberOfInstallableLanguagesData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumberOfInstallableLanguagesFunction.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemString.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemStringData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemStringFunction.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDevice.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDeviceData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDeviceFunction.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignator.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignatorData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignatorFunction.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturer.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturerData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturerFunction.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionString.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionStringData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionStringFunction.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignation.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignationData.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignationFunction.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotOnboardDevices.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMisc.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscDataTable.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscDxe.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscEntryPoint.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscStrings.uni
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/BootMode.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/CommonHeader.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/Generic/Recovery.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MemoryCallback.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformErratas.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FvbInfo.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSpi.inf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.c
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.h
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Quark.dsc
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Quark.fdf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/QuarkMin.dsc
 create mode 100644 Platform/Intel/QuarkPlatformPkg/QuarkMin.fdf
 create mode 100644 Platform/Intel/QuarkPlatformPkg/QuarkPlatformPkg.dec
 create mode 100644 Platform/Intel/QuarkPlatformPkg/Readme.md

diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/AcpiTables.inf b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/AcpiTables.inf
new file mode 100644
index 0000000000..73c26c2532
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/AcpiTables.inf
@@ -0,0 +1,42 @@
+## @file
+# Component description file for PlatformAcpiTable module.
+#
+# Build acpi table data required by system boot.
+# All .asi files tagged with "ToolCode="DUMMY"" in following
+# file list are device description and are included by top
+# level ASL file which will be dealed with by asl.exe application.
+#
+# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = AcpiTables
+  FILE_GUID                      = 7E374E25-8E01-4FEE-87F2-390C23C606CD
+  MODULE_TYPE                    = USER_DEFINED
+  VERSION_STRING                 = 1.0
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  Facs/Facs.aslc
+  Fadt/Fadt2.0.aslc
+  Hpet/Hpet.aslc
+  Mcfg/Mcfg.aslc
+  Dsdt/Platform.asl
+  CpuPm/CpuPm.asl
+  Cpu0Cst/Cpu0Cst.asl
+  Cpu0Ist/Cpu0Ist.asl
+  Cpu0Tst/Cpu0Tst.asl
+
+[Packages]
+  MdePkg/MdePkg.dec
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Cst/Cpu0Cst.asl b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Cst/Cpu0Cst.asl
new file mode 100644
index 0000000000..444f1ac988
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Cst/Cpu0Cst.asl
@@ -0,0 +1,399 @@
+/** @file
+CPU C State control methods
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+DefinitionBlock (
+    "Cpu0Cst.aml",
+    "SSDT",
+    0x01,
+    "SsgPmm",
+    "Cpu0Cst",
+    0x0011
+    )
+{
+    External(\_PR.CPU0, DeviceObj)
+    External (PDC0, IntObj)
+    External (CFGD, FieldUnitObj)
+
+    Scope(\_PR.CPU0)
+    {
+        Method (_CST, 0)
+        {
+            // If CMP is supported, and OSPM is not capable of independent C1, P, T state
+            // support for each processor for multi-processor configuration, we will just report
+            // C1 halt
+            //
+            // PDCx[4] = Indicates whether OSPM is not capable of independent C1, P, T state
+            // support for each processor for multi-processor configuration.
+            //
+            If(LAnd(And(CFGD,0x01000000), LNot(And(PDC0,0x10))))
+            {
+              Return(Package() {
+                1,
+                Package()
+                { // C1 halt
+                  ResourceTemplate(){Register(FFixedHW, 0, 0, 0)},
+                  1,
+                  157,
+                  1000
+                }
+              })
+            }
+
+            //
+            // If MWAIT extensions is supported and OSPM is capable of performing
+            // native C state instructions for the C2/C3 in multi-processor configuration,
+            // we report every c state with MWAIT extensions.
+            //
+            // PDCx[9] = Indicates whether OSPM is capable of performing native C state instructions
+            // for the C2/C3 in multi-processor configuration
+            //
+            If(LAnd(And(CFGD, 0x200000), And(PDC0,0x200)))
+            {
+              //
+              // If C6 is supported, we report MWAIT C1,C2,C4,C6
+              //
+              If(And(CFGD,0x200))
+              {
+                Return( Package()
+                {
+                  4,
+                  Package()
+                  { // MWAIT C1, hardware coordinated with no bus master avoidance
+                    ResourceTemplate(){Register(FFixedHW, 1, 2, 0x00, 1)},
+                    1,
+                    1,
+                    1000
+                  },
+                  Package()
+                  { // MWAIT C2, hardware coordinated with no bus master avoidance
+                    ResourceTemplate(){Register(FFixedHW, 1, 2, 0x10, 1)},
+                    2,
+                    20,
+                    500
+                  },
+                  Package()
+                  { // MWAIT C4, hardware coordinated with bus master avoidance enabled
+                    ResourceTemplate(){Register(FFixedHW, 1, 2, 0x30, 3)},
+                    3,
+                    100,
+                    100
+                  },
+                  Package()
+                  { // MWAIT C6, hardware coordinated with bus master avoidance enabled
+                    ResourceTemplate(){Register(FFixedHW, 1, 2, 0x50, 3)},
+                    3,
+                    140,
+                    10
+                  }
+                })
+              }
+              //
+              // If C4 is supported, we report MWAIT C1,C2,C4
+              //
+              If(And(CFGD,0x080))
+              {
+                Return( Package()
+                {
+                  3,
+                  Package()
+                  { // MWAIT C1, hardware coordinated with no bus master avoidance
+                    ResourceTemplate(){Register(FFixedHW, 1, 2, 0x00, 1)},
+                    1,
+                    1,
+                    1000
+                  },
+                  Package()
+                  { // MWAIT C2, hardware coordinated with no bus master avoidance
+                    ResourceTemplate(){Register(FFixedHW, 1, 2, 0x10, 1)},
+                    2,
+                    20,
+                    500
+                  },
+                  Package()
+                  { // MWAIT C4, hardware coordinated with bus master avoidance enabled
+                    ResourceTemplate(){Register(FFixedHW, 1, 2, 0x30, 3)},
+                    3,
+                    100,
+                    100
+                  }
+                })
+              }
+              //
+              // If C2 is supported, we report MWAIT C1,C2
+              //
+              If(And(CFGD,0x020))
+              {
+                Return( Package()
+                {
+                  2,
+                  Package()
+                  { // MWAIT C1, hardware coordinated with no bus master avoidance
+                    ResourceTemplate(){Register(FFixedHW, 1, 2, 0x00, 1)},
+                    1,
+                    1,
+                    1000
+                  },
+                  Package()
+                  { // MWAIT C2, hardware coordinated with no bus master avoidance
+                    ResourceTemplate(){Register(FFixedHW, 1, 2, 0x10, 1)},
+                    2,
+                    20,
+                    500
+                  }
+                })
+              }
+              //
+              // Else we only report MWAIT C1.
+              //
+              Return(Package()
+              {
+                1,
+                Package()
+                { // MWAIT C1, hardware coordinated with no bus master avoidance
+                  ResourceTemplate () {Register(FFixedHW, 1, 2, 0x00, 1)},
+                  1,
+                  1,
+                  1000
+                }
+              })
+            }
+
+            // If OSPM is only capable of performing native C state instructions for
+            // the C1 in multi-processor configuration, we report C1 with MWAIT, other
+            // C states with IO method.
+            //
+            // PDCx[8] = Indicates whether OSPM is capable of performing native C state instructions
+            // for the C1 in multi-processor configuration
+            //
+            If(LAnd(And(CFGD, 0x200000), And(PDC0,0x100)))
+            {
+              //
+              // If C6 is supported, we report MWAIT C1, IO C2,C4,C6
+              //
+              If(And(CFGD,0x200))
+              {
+                Return( Package()
+                {
+                  4,
+                  Package()
+                  { // MWAIT C1, hardware coordinated with no bus master avoidance
+                    ResourceTemplate () {Register(FFixedHW, 1, 2, 0x00, 1)},
+                    1,
+                    1,
+                    1000
+                  },
+                  Package()
+                  { // IO C2 ("PMBALVL2" will be updated at runtime)
+                    ResourceTemplate () {Register(SystemIO, 8, 0, 0x324C564C41424D50)},
+                    2,
+                    20,
+                    500
+                    },
+                  Package()
+                  { // IO C4 ("PMBALVL4" will be updated at runtime)
+                    ResourceTemplate () {Register(SystemIO, 8, 0, 0x344C564C41424D50)},
+                    3,
+                    100,
+                    100
+                  },
+                  Package()
+                  { // IO C6 ("PMBALVL6" will be updated at runtime)
+                    ResourceTemplate () {Register(SystemIO, 8, 0, 0x364C564C41424D50)},
+                    3,
+                    140,
+                    10
+                  }
+                })
+              }
+              //
+              // If C4 is supported, we report MWAIT C1, IO C2,C4
+              //
+              If(And(CFGD,0x080))
+              {
+                Return( Package()
+                {
+                  3,
+                  Package()
+                  { // MWAIT C1, hardware coordinated with no bus master avoidance
+                    ResourceTemplate () {Register(FFixedHW, 1, 2, 0x00, 1)},
+                    1,
+                    1,
+                    1000
+                  },
+                  Package()
+                  { // IO C2 ("PMBALVL2" will be updated at runtime)
+                    ResourceTemplate () {Register(SystemIO, 8, 0, 0x324C564C41424D50)},
+                    2,
+                    20,
+                    500
+                    },
+                  Package()
+                  { // IO C4 ("PMBALVL4" will be updated at runtime)
+                    ResourceTemplate () {Register(SystemIO, 8, 0, 0x344C564C41424D50)},
+                    3,
+                    100,
+                    100
+                  }
+                })
+              }
+              //
+              // If C2 is supported, we report MWAIT C1, IO C2
+              //
+              If(And(CFGD,0x020))
+              {
+                Return( Package()
+                {
+                  2,
+                  Package()
+                  { // MWAIT C1, hardware coordinated with no bus master avoidance
+                    ResourceTemplate () {Register(FFixedHW, 1, 2, 0x00, 1)},
+                    1,
+                    1,
+                    1000
+                  },
+                  Package()
+                  { // IO C2 ("PMBALVL2" will be updated at runtime)
+                    ResourceTemplate () {Register(SystemIO, 8, 0, 0x324C564C41424D50)},
+                    2,
+                    20,
+                    500
+                  }
+                })
+              }
+              //
+              // Else we only report MWAIT C1.
+              //
+              Return(Package()
+              {
+                1,
+                Package()
+                { // MWAIT C1, hardware coordinated with no bus master avoidance
+                  ResourceTemplate () {Register(FFixedHW, 1, 2, 0x00, 1)},
+                  1,
+                  1,
+                  1000
+                }
+              })
+            }
+
+            //
+            // If MWAIT is not supported, we report all the c states with IO method
+            //
+
+            //
+            // If C6 is supported, we report C1 halt, IO C2,C4,C6
+            //
+            If(And(CFGD,0x200))
+            {
+              Return(Package()
+              {
+                4,
+                Package()
+                { // C1 Halt
+                  ResourceTemplate () {Register(FFixedHW, 0, 0, 0)},
+                  1,
+                  1,
+                  1000
+                },
+                Package()
+                { // IO C2 ("PMBALVL2" will be updated at runtime)
+                  ResourceTemplate () {Register(SystemIO, 8, 0, 0x324C564C41424D50)},
+                  2,
+                  20,
+                  500
+                },
+                Package()
+                { // IO C4 ("PMBALVL4" will be updated at runtime)
+                  ResourceTemplate () {Register(SystemIO, 8, 0, 0x344C564C41424D50)},
+                  3,
+                  100,
+                  100
+                },
+                Package()
+                { // IO C6 ("PMBALVL6" will be updated at runtime)
+                  ResourceTemplate () {Register(SystemIO, 8, 0, 0x364C564C41424D50)},
+                  3,
+                  140,
+                  10
+                }
+              })
+            }
+            //
+            // If C4 is supported, we report C1 halt, IO C2,C4
+            //
+            If(And(CFGD,0x080))
+            {
+              Return(Package()
+              {
+                3,
+                Package()
+                { // C1 halt
+                  ResourceTemplate () {Register(FFixedHW, 0, 0, 0)},
+                  1,
+                  1,
+                  1000
+                },
+                Package()
+                { // IO C2 ("PMBALVL2" will be updated at runtime)
+                  ResourceTemplate () {Register(SystemIO, 8, 0, 0x324C564C41424D50)},
+                  2,
+                  20,
+                  500
+                },
+                Package()
+                { // IO C4 ("PMBALVL4" will be updated at runtime)
+                  ResourceTemplate () {Register(SystemIO, 8, 0, 0x344C564C41424D50)},
+                  3,
+                  100,
+                  100
+                }
+              })
+            }
+
+            //
+            // If C2 is supported, we report C1 halt, IO C2
+            //
+            If(And(CFGD,0x020))
+            {
+              Return(Package()
+              {
+                2,
+                Package()
+                { // C1 halt
+                  ResourceTemplate () {Register(FFixedHW, 0, 0, 0)},
+                  1,
+                  1,
+                  1000
+                },
+                Package()
+                { // IO C2 ("PMBALVL2" will be updated at runtime)
+                  ResourceTemplate () {Register(SystemIO, 8, 0, 0x324C564C41424D50)},
+                  2,
+                  20,
+                  500
+                }
+              })
+            }
+            //
+            // Else we only report C1 halt.
+            //
+            Return(Package()
+            {
+              1,
+              Package()
+              { // C1 halt
+                ResourceTemplate () {Register(FFixedHW, 0, 0, 0)},
+                1,
+                1,
+                1000
+              }
+            })
+        }
+    }
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Ist/Cpu0Ist.asl b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Ist/Cpu0Ist.asl
new file mode 100644
index 0000000000..68f2e7cccb
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Ist/Cpu0Ist.asl
@@ -0,0 +1,159 @@
+/** @file
+CPU EIST control methods
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+DefinitionBlock (
+    "CPU0IST.aml",
+    "SSDT",
+    0x01,
+    "SsgPmm",
+    "Cpu0Ist",
+    0x0012
+    )
+{
+    External (PDC0, IntObj)
+    External (CFGD, FieldUnitObj)
+    External(\_PR.CPU0, DeviceObj)
+
+    Scope(\_PR.CPU0)
+    {
+        Method(_PPC,0)
+        {
+            Return(ZERO)   // Return All States Available.
+        }
+
+        Method(_PCT,0)
+        {
+            //
+            // If GV3 is supported and OSPM is capable of direct access to
+            // performance state MSR, we use MSR method
+            //
+            //
+            // PDCx[0] = Indicates whether OSPM is capable of direct access to
+            // performance state MSR.
+            //
+            If(LAnd(And(CFGD,0x0001), And(PDC0,0x0001)))
+            {
+                Return(Package()    // MSR Method
+                {
+                    ResourceTemplate(){Register(FFixedHW, 0, 0, 0)},
+                    ResourceTemplate(){Register(FFixedHW, 0, 0, 0)}
+                })
+
+            }
+
+            //
+            // Otherwise, we use smi method
+            //
+            Return(Package()    // SMI Method
+                {
+                  ResourceTemplate(){Register(SystemIO,16,0,0xB2)},
+                  ResourceTemplate(){Register(SystemIO, 8,0,0xB3)}
+                })
+        }
+
+        Method(_PSS,0)
+        {
+            //
+            // If OSPM is capable of direct access to performance state MSR,
+            // we report NPSS, otherwise, we report SPSS.
+            If (And(PDC0,0x0001))
+            {
+                Return(NPSS)
+            }
+
+            Return(SPSS)
+        }
+
+        Name(SPSS,Package()
+        {
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000}
+        })
+
+        Name(NPSS,Package()
+        {
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000}
+        })
+
+        Method(_PSD,0)
+        {
+          //
+          // If CMP is suppored, we report the dependency with two processors
+          //
+          If(And(CFGD,0x1000000))
+          {
+            //
+            // If OSPM is capable of hardware coordination of P-states, we report
+            // the dependency with hardware coordination.
+            //
+            // PDCx[11] = Indicates whether OSPM is capable of hardware coordination of P-states
+            //
+            If(And(PDC0,0x0800))
+            {
+              Return(Package(){
+                Package(){
+                  5,  // # entries.
+                  0,  // Revision.
+                  0,  // Domain #.
+                  0xFE,  // Coord Type- HW_ALL.
+                  2  // # processors.
+                }
+              })
+            }
+
+            //
+            // Otherwise, the dependency with OSPM coordination
+            //
+            Return(Package(){
+              Package(){
+                5,    // # entries.
+                0,    // Revision.
+                0,    // Domain #.
+                0xFC, // Coord Type- SW_ALL.
+                2     // # processors.
+              }
+            })
+          }
+
+          //
+          //  Otherwise, we report the dependency with one processor
+          //
+          Return(Package(){
+            Package(){
+              5,      // # entries.
+              0,      // Revision.
+              0,      // Domain #.
+              0xFC,   // Coord Type- SW_ALL.
+              1       // # processors.
+            }
+          })
+        }
+    }
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Tst/Cpu0Tst.asl b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Tst/Cpu0Tst.asl
new file mode 100644
index 0000000000..9af10a1c60
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Tst/Cpu0Tst.asl
@@ -0,0 +1,133 @@
+/** @file
+CPU T-state control methods
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+DefinitionBlock (
+    "CPU0TST.aml",
+    "SSDT",
+    0x01,
+    "SsgPmm",
+    "Cpu0Tst",
+    0x0013
+    )
+{
+    External (PDC0, IntObj)
+    External (CFGD, FieldUnitObj)
+    External(\_PR.CPU0, DeviceObj)
+    External(_PSS)
+
+    Scope(\_PR.CPU0)
+    {
+        Method(_TPC,0)
+        {
+            Return(ZERO)   // Return All States Available.
+        }
+
+        Name(TPTC, ResourceTemplate()
+        {
+            Memory32Fixed(ReadOnly, 0, 0, FIX1) // IO APIC
+        })
+
+        //
+        // If OSPM is capable of direct access to on demand throttling MSR,
+        // we use MSR method;otherwise we use IO method.
+        //
+        //
+        // PDCx[2] = Indicates whether OSPM is capable of direct access to
+        // on demand throttling MSR.
+        //
+        Method(_PTC, 0)
+        {
+          If(And(PDC0, 0x0004))
+          {
+            Return(Package() // MSR Method
+            {
+              ResourceTemplate(){Register(FFixedHW, 0, 0, 0)},
+              ResourceTemplate(){Register(FFixedHW, 0, 0, 0)}
+            }
+            )
+          }
+          Return(Package() // IO Method
+          {
+            //
+            // PM IO base ("PMBALVL0" will be updated at runtime)
+            //
+            ResourceTemplate(){Register(SystemIO, 4, 1, 0x304C564C41424D50)},
+            ResourceTemplate(){Register(SystemIO, 4, 1, 0x304C564C41424D50)}
+          }
+          )
+        }
+
+        //
+        // _TSS returned package for IO Method
+        //
+        Name(TSSI, Package()
+        {
+          Package(){100, 1000, 0, 0x00, 0}
+        }
+        )
+        //
+        // _TSS returned package for MSR Method
+        //
+        Name(TSSM, Package()
+        {
+          Package(){100, 1000, 0, 0x00, 0}
+        }
+        )
+
+        Method(_TSS, 0)
+        {
+          //
+          // If OSPM is capable of direct access to on demand throttling MSR,
+          // we report TSSM;otherwise report TSSI.
+          //
+          If(And(PDC0, 0x0004))
+          {
+            Return(TSSM)
+          }
+          Return(TSSI)
+        }
+
+        Method(_TSD, 0)
+        {
+          //
+          // If CMP is suppored, we report the dependency with two processors
+          //
+          If(LAnd(And(CFGD, 0x1000000), LNot(And(PDC0, 4))))
+          {
+            Return(Package()
+            {
+              Package()
+              {
+                5,    // # entries.
+                0,    // Revision.
+                0,    // Domain #.
+                0xFD, // Coord Type- SW_ANY
+                2     // # processors.
+              }
+            }
+            )
+          }
+          //
+          // Otherwise, we report the dependency with one processor
+          //
+          Return(Package()
+          {
+            Package()
+            {
+              5,        // # entries.
+              0,        // Revision.
+              0,        // Domain #.
+              0xFC,     // Coord Type- SW_ALL
+              1         // # processors.
+            }
+          }
+          )
+        }
+    }
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/CpuPm/CpuPm.asl b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/CpuPm/CpuPm.asl
new file mode 100644
index 0000000000..7cecb8311c
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/CpuPm/CpuPm.asl
@@ -0,0 +1,73 @@
+/** @file
+CPU power management control methods
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+DefinitionBlock (
+    "CPUPM.aml",
+    "SSDT",
+    0x01,
+    "SsgPmm",
+    "CpuPm",
+    0x0010
+    )
+{
+    External(\_PR.CPU0, DeviceObj)
+    External(CFGD, FieldUnitObj)
+
+    Scope(\)
+    {
+        // Config DWord, modified during POST
+        // Bit definitions are the same as PPMFlags:
+        //     CFGD[0] = PPM_GV3     = GV3
+        //     CFGD[1] = PPM_TURBO   = Turbo Mode
+        //     CFGD[2] = PPM_SUPER_LFM = N/2 Ratio
+        //     CFGD[4] = PPM_C1      = C1 Capable, Enabled
+        //     CFGD[5] = PPM_C2      = C2 Capable, Enabled
+        //     CFGD[6] = PPM_C3      = C3 Capable, Enabled
+        //     CFGD[7] = PPM_C4      = C4 Capable, Enabled
+        //     CFGD[8] = PPM_C5      = C5/Deep C4 Capable, Enabled
+        //     CFGD[9] = PPM_C6      = C6 Capable, Enabled
+        //     CFGD[10] = PPM_C1E    = C1E Enabled
+        //     CFGD[11] = PPM_C2E    = C2E Enabled
+        //     CFGD[12] = PPM_C3E    = C3E Enabled
+        //     CFGD[13] = PPM_C4E    = C4E Enabled
+        //     CFGD[14] = PPM_HARD_C4E = Hard C4E Capable, Enabled
+        //     CFGD[16] = PPM_TM1    = Thermal Monitor 1
+        //     CFGD[17] = PPM_TM2    = Thermal Monitor 2
+        //     CFGD[19] = PPM_PHOT   = Bi-directional ProcHot
+        //     CFGD[21] = PPM_MWAIT_EXT = MWAIT extensions supported
+        //     CFGD[24] = PPM_CMP    = CMP supported, Enabled
+        //     CFGD[28] = PPM_TSTATE = CPU T states supported
+        //
+        // Name(CFGD, 0x80000000)
+        // External Defined in GNVS
+
+        Name(PDC0,0x80000000)   // CPU0 _PDC Flags.
+
+        // We load it in AcpiPlatform
+        //Name(SSDT,Package()
+        //{
+        //    "CPU0IST ", 0x80000000, 0x80000000,
+        //    "CPU1IST ", 0x80000000, 0x80000000,
+        //    "CPU0CST ", 0x80000000, 0x80000000,
+        //    "CPU1CST ", 0x80000000, 0x80000000,
+        //})
+    }
+    Scope(\_PR.CPU0)
+    {
+        Method(_PDC, 1)
+        {
+          //
+          // Store result of PDC.
+          //
+          CreateDWordField(Arg0,8,CAP0)   // Point to 3rd DWORD.
+          Store(CAP0,PDC0)                // Store It in PDC0.
+        }
+    }
+
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/AD7298.asi b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/AD7298.asi
new file mode 100644
index 0000000000..ea59fb0860
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/AD7298.asi
@@ -0,0 +1,38 @@
+/** @file
+Analog devices AD7298 ADC.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+Device(ADC1)
+{
+    Name(_HID, "INT3494") // Galileo Version 1 Low-Speed ADC.
+    Name(_CID, "INT3494")
+    Name(RBUF, ResourceTemplate()
+    {
+        // SPI0: mode 2, 4Mhz, 16-bit data length
+        SpiSerialBus (0x0000, PolarityLow, FourWireMode, 16, ControllerInitiated, 4000000, ClockPolarityHigh, ClockPhaseFirst, "\\_SB_.PCI0.SPI0",0x00, ResourceConsumer, ,)
+
+        // GPIO<0> is SPI0_CS_N
+        GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.PCI0.GIP0.GPO_", 0, ResourceConsumer, , ) {QUARK_GPIO0_MAPPING}
+    })
+    Method(_CRS, 0x0, NotSerialized)
+    {
+        Return(RBUF)
+    }
+    Method(_STA, 0x0, NotSerialized)
+    {
+        //
+        // Only Galileo platform has this device.
+        // EFI_PLATFORM_TYPE enum value Galileo = 6.
+        //
+        If(LNotEqual(PTYP, 6))
+        {
+          return (0)
+        }
+        Return(0xf)
+    }
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/ADC108S102.asi b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/ADC108S102.asi
new file mode 100644
index 0000000000..de651576b8
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/ADC108S102.asi
@@ -0,0 +1,33 @@
+/** @file
+TI ADC108S102 ADC.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+Device(ADC2)
+{
+    Name(_HID, "INT3495") // GalileoGen2 Low-Speed ADC.
+    Name(_CID, "INT3495")
+    Name(RBUF, ResourceTemplate()
+    {
+        SPISerialBus(0x0000, PolarityLow, ThreeWireMode, 0x10, ControllerInitiated, 0x1E8480, ClockPolarityLow, ClockPhaseFirst, "\\_SB.PCI0.SPI0", 0x00, ResourceConsumer, ,)
+    })
+    Method(_CRS, 0x0, NotSerialized)
+    {
+        Return(RBUF)
+    }
+    Method(_STA, 0x0, NotSerialized)
+    {
+        //
+        // Only Platform Type / Id 8 has this device.
+        //
+        If(LNotEqual(PTYP, 8))
+        {
+          return (0)
+        }
+        Return(0xf)
+    }
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/CAT24C08.asi b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/CAT24C08.asi
new file mode 100644
index 0000000000..ac6df50ae5
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/CAT24C08.asi
@@ -0,0 +1,34 @@
+/** @file
+ONSEMI CAT24C08 I2C 8KB EEPROM.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+Device(EEP2)
+{
+    Name(_HID, "INT3499") // ONSEMI CAT24C08 I2C 8KB EEPROM.
+    Name(_CID, "INT3499")
+
+    Name(RBUF, ResourceTemplate()
+    {
+        I2CSerialBus(0x54, ControllerInitiated, 400000, AddressingMode7Bit, "\\_SB.PCI0.GIP0.I2C_", 0, ResourceConsumer, , )
+    })
+    Method(_CRS, 0x0, NotSerialized)
+    {
+        Return(RBUF)
+    }
+    Method(_STA, 0x0, NotSerialized)
+    {
+        //
+        // Only Platform Type / Id 8 has this device.
+        //
+        If(LNotEqual(PTYP, 8))
+        {
+          return (0)
+        }
+        Return(0xf)
+    }
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/CY8C9540A.asi b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/CY8C9540A.asi
new file mode 100644
index 0000000000..b5a5f3b680
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/CY8C9540A.asi
@@ -0,0 +1,47 @@
+/** @file
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+CY8C9540A 40 Bit I/O Expander with EEPROM.
+
+**/
+
+Device(CY8C)
+{
+    Name(_HID, "INT3490") // Cypress CY8C9540A Io Expander Function.
+    Name(_CID, "INT3490")
+
+    Name(RBUF, ResourceTemplate()
+    {
+        I2CSerialBus(0x20, ControllerInitiated, 100000, AddressingMode7Bit, "\\_SB.PCI0.GIP0.I2C_", 0, ResourceConsumer, , )
+        GpioInt (Level, ActiveLow, Exclusive, PullDefault, , "\\_SB.PCI0.GIP0.GPO", 0, ResourceConsumer, , ) {QUARK_GPIO5_MAPPING} /* GPIO<5> is INT_S0 */
+    })
+    Method(_CRS, 0x0, NotSerialized)
+    {
+        CreateByteField(RBUF, 16, OB1)
+        if (LEqual (ALTS, 0))
+        {
+            Store(0x20, OB1)
+        }
+        Else
+        {
+            Store(0x21, OB1)
+        }
+        Return(RBUF)
+    }
+    Method(_STA, 0x0, NotSerialized)
+    {
+        //
+        // Only Galileo platform has this device.
+        // EFI_PLATFORM_TYPE enum value Galileo = 6.
+        //
+        If(LNotEqual(PTYP, 6))
+        {
+          return (0)
+        }
+        Return(0xf)
+    }
+}
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/GpioClient.asi b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/GpioClient.asi
new file mode 100644
index 0000000000..9a5812d068
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/GpioClient.asi
@@ -0,0 +1,89 @@
+/** @file
+Expose GPIO resources to usermode through client driver.
+
+Copyright (c) 2013-2019 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+Device(GPOT)
+{
+    Name(_HID, "INT349A")
+    Name(_CID, "INT349A")
+    Method(_CRS, 0x0, Serialized)
+    {
+        Name(RBUF, ResourceTemplate()
+        {
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.PCI0.GIP0.GPO_", 0, ResourceConsumer, , ) {0}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.PCI0.GIP0.GPO_", 0, ResourceConsumer, , ) {0x1}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.PCI0.GIP0.GPO_", 0, ResourceConsumer, , ) {0x2}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.PCI0.GIP0.GPO_", 0, ResourceConsumer, , ) {0x3}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.PCI0.GIP0.GPO_", 0, ResourceConsumer, , ) {0x4}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.PCI0.GIP0.GPO_", 0, ResourceConsumer, , ) {0x5}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.PCI0.GIP0.GPO_", 0, ResourceConsumer, , ) {0x6}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.PCI0.GIP0.GPO_", 0, ResourceConsumer, , ) {0x7}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.PCI0.GIP0.GPO_", 0, ResourceConsumer, , ) {0x8}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.PCI0.GIP0.GPO_", 0, ResourceConsumer, , ) {0x9}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.PCI0.GIP0.GPO_", 0, ResourceConsumer, , ) {0xa}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.PCI0.GIP0.GPO_", 0, ResourceConsumer, , ) {0xb}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.PCI0.GIP0.GPO_", 0, ResourceConsumer, , ) {0xc}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.PCI0.GIP0.GPO_", 0, ResourceConsumer, , ) {0xd}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.PCI0.GIP0.GPO_", 0, ResourceConsumer, , ) {0xe}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.PCI0.GIP0.GPO_", 0, ResourceConsumer, , ) {0xf}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x1}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x2}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x3}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x4}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x5}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x6}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x7}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x8}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x9}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0xa}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0xb}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0xc}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0xd}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0xe}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0xf}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x10}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x11}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x12}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x13}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x14}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x15}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x16}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x17}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x18}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x19}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x1a}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x1b}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x1c}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x1d}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x1e}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x1f}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x20}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x21}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x22}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x23}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x24}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x25}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x26}
+            GpioIO(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.CY8C", 0, ResourceConsumer, , ) {0x27}
+        })
+        Return(RBUF)
+    }
+    Method(_STA, 0x0, NotSerialized)
+    {
+        //
+        // Only Galileo platform has this device.
+        // EFI_PLATFORM_TYPE enum value Galileo = 6.
+        //
+        If(LNotEqual(PTYP, 6))
+        {
+          return (0)
+        }
+        Return(0xf)
+    }
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/LpcDev.asi b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/LpcDev.asi
new file mode 100644
index 0000000000..8df07a70a3
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/LpcDev.asi
@@ -0,0 +1,248 @@
+/** @file
+Legacy resource template
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef LPC_DEV_ASI
+#define LPC_DEV_ASI
+
+Device(RTC)
+{
+    Name(_HID,EISAID("PNP0B00"))
+    Name(BUF0,ResourceTemplate() {
+        IO(Decode16,0x70,0x70,0x01,0x04)
+        IO(Decode16,0x74,0x74,0x01,0x04)
+    })
+    Name(BUF1,ResourceTemplate() {
+        IO(Decode16,0x70,0x70,0x01,0x04)
+        IO(Decode16,0x74,0x74,0x01,0x04)
+        IRQNoFlags(){8}
+    })
+    Method(_CRS,0,Serialized)
+    {
+        If (HPEA)
+        {
+            return (BUF0)
+        }
+        Else
+        {
+            return (BUF1)
+        }
+    }
+}
+
+Device(PIC)
+{
+    Name(_HID,EISAID("PNP0000"))
+
+    Name(_CRS,ResourceTemplate() {
+        IO(Decode16,0x20,0x20,0x01,0x1E)        // length of 1Eh includes all aliases
+        IO(Decode16,0xA0,0xA0,0x01,0x1E)
+        IO(Decode16,0x4D0,0x4D0,0x01,0x02)
+    })
+}
+
+Device(TMR)
+{
+    Name(_HID,EISAID("PNP0100"))
+
+    Name(BUF0,ResourceTemplate() {
+        IO(Decode16,0x40,0x40,0x01,0x04)
+        IO(Decode16,0x50,0x50,0x01,0x04)        // alias
+    })
+    Name(BUF1,ResourceTemplate() {
+        IO(Decode16,0x40,0x40,0x01,0x04)
+        IO(Decode16,0x50,0x50,0x01,0x04)        // alias
+        IRQNoFlags(){0}
+    })
+    Method(_CRS,0,Serialized)
+    {
+        If (HPEA)
+        {
+            return (BUF0)
+        }
+        Else
+        {
+            return (BUF1)
+        }
+    }
+}
+
+Device(SPKR)
+{
+    Name(_HID,EISAID("PNP0800"))
+
+    Name(_CRS,ResourceTemplate() {
+        IO(Decode16,0x61,0x61,0x01,0x01)
+    })
+}
+
+Device(XTRA)    // all "PNP0C02" devices- pieces that don't fit anywhere else
+{
+    Name(_HID,EISAID("PNP0C02"))        // Generic motherboard devices
+
+    Name(CRS,
+        ResourceTemplate()
+        {
+            IO(Decode16,0x2E,0x2E,0x01,0x02)
+            IO(Decode16,0x4E,0x2E,0x01,0x02)
+            IO(Decode16,0x63,0x61,0x01,0x01)
+            IO(Decode16,0x65,0x61,0x01,0x01)
+            IO(Decode16,0x67,0x61,0x01,0x01)
+            IO(Decode16,0x80,0x80,0x01,0x01)
+            IO(Decode16,0x84,0x84,0x01,0x04)
+            IO(Decode16,0x88,0x88,0x01,0x01)
+            IO(Decode16,0x8c,0x8c,0x01,0x03)
+            IO(Decode16,0x92,0x92,0x01,0x01)
+
+            IO(
+              Decode16,
+              0,
+              0,
+              0x01,
+              0x10,
+              FIX1
+              )
+
+            IO(
+              Decode16,
+              0,
+              0,
+              0x01,
+              0x10,
+              FIX2
+              )
+
+            IO(
+              Decode16,
+              0,
+              0,
+              0x01,
+              0x40,
+              FIX3
+              )
+
+           IO(
+              Decode16,
+              0,
+              0,
+              0x01,
+              0x40,
+              FIX5
+              )
+
+            IO(
+              Decode16,
+              0,
+              0,
+              0x01,
+              0x40,
+              FIX6
+              )
+
+        }
+    )
+
+    Method (_CRS, 0, NotSerialized) {
+      CreateWordField (CRS, ^FIX1._MIN, MBR0)
+      Store(\P1BB, MBR0)
+      CreateWordField (CRS, ^FIX1._MAX, MBR1)
+      Store(\P1BB, MBR1)
+      CreateWordField (CRS, ^FIX2._MIN, MBR2)
+      Store(\PBAB, MBR2)
+      CreateWordField (CRS, ^FIX2._MAX, MBR3)
+      Store(\PBAB, MBR3)
+      CreateWordField (CRS, ^FIX3._MIN, MBR4)
+      Store(\GP0B, MBR4)
+      CreateWordField (CRS, ^FIX3._MAX, MBR5)
+      Store(\GP0B, MBR5)
+      CreateWordField (CRS, ^FIX5._MIN, MBR8)
+      Store(\SMBB, MBR8)
+      CreateWordField (CRS, ^FIX5._MAX, MBR9)
+      Store(\SMBB, MBR9)
+      CreateWordField (CRS, ^FIX6._MIN, MBRA)
+      Store(\WDTB, MBRA)
+      CreateWordField (CRS, ^FIX6._MAX, MBRB)
+      Store(\WDTB, MBRB)
+      return (CRS)
+    }
+}
+
+Device(LGIO)  // Legacy GPIO.
+{
+    Name(_HID, "INT3488")
+    Name(_CID, "INT3488")
+
+    Name(CRS,
+        ResourceTemplate()
+        {
+            IO(
+              Decode16,
+              0,
+              0,
+              0x01,
+              0x48,
+              FIX4
+              )
+        }
+    )
+
+    Method (_CRS, 0, NotSerialized) {
+      CreateWordField (CRS, ^FIX4._MIN, MBR6)
+      Store(\GPAB, MBR6)
+      CreateWordField (CRS, ^FIX4._MAX, MBR7)
+      Store(\GPAB, MBR7)
+      return (CRS)
+    }
+}
+
+Device(HPET)  // High Performance Event Timer
+{
+  Name(_HID,EISAID("PNP0103"))
+
+  Name(BUF0,ResourceTemplate()
+  {
+    IRQNoFlags() {0}
+    IRQNoFlags() {8}
+    Memory32Fixed(ReadOnly, 0, 0, FIX1)
+  })
+
+  Method(_STA,0)
+  {
+    // Show this Device only if the OS is WINXP or beyond.
+
+    If(LGreaterEqual(OSTP,WINDOWS_XP))
+    {
+      If(HPEA)
+      {
+        Return(0x000F)  // Enabled, do Display.
+      }
+    }
+    Else
+    {
+      // OS = WIN98, WINME, or WIN2000.
+
+      If(HPEA)
+      {
+        Return(0x000B)  // Enabled, don't Display.
+      }
+    }
+
+    Return(0x0000)      // Return Nothing.
+  }
+
+  Method(_CRS,0,Serialized)
+  {
+    CreateDWordField (BUF0, ^FIX1._BAS, MBR0)
+    Store(\HPTB, MBR0)
+    CreateDWordField (BUF0, ^FIX1._LEN, MBR1)
+    Store(\HPTS, MBR1)
+    Return(BUF0)
+  }
+}
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PCA9685.asi b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PCA9685.asi
new file mode 100644
index 0000000000..44fafbe999
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PCA9685.asi
@@ -0,0 +1,34 @@
+/** @file
+NXP PCA9685 i2c-accessible PWM/LED controller.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+Device(PWM1)
+{
+    Name(_HID, "INT3492") // NXP PCA9685 i2c-accessible PWM/LED controller.
+    Name(_CID, "INT3492")
+
+    Name(RBUF, ResourceTemplate()
+    {
+        I2CSerialBus(0x47, ControllerInitiated, 400000, AddressingMode7Bit, "\\_SB.PCI0.GIP0.I2C_", 0, ResourceConsumer, , )
+    })
+    Method(_CRS, 0x0, NotSerialized)
+    {
+        Return(RBUF)
+    }
+    Method(_STA, 0x0, NotSerialized)
+    {
+        //
+        // Only Platform Type / Id 8 has this device.
+        //
+        If(LNotEqual(PTYP, 8))
+        {
+          return (0)
+        }
+        Return(0xf)
+    }
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PCAL9555A.asi b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PCAL9555A.asi
new file mode 100644
index 0000000000..06517a7804
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PCAL9555A.asi
@@ -0,0 +1,90 @@
+/** @file
+NXP PCAL9555A i2c-accessible I/O expander.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+Device(NIO1)
+{
+    Name(_HID, "INT3491") // NXP PCAL9555A i2c-accessible I/O expander.
+    Name(_CID, "INT3491")
+    Name(_UID, 1)
+
+    Name(RBUF, ResourceTemplate()
+    {
+        I2CSerialBus(0x25, ControllerInitiated, 400000, AddressingMode7Bit, "\\_SB.PCI0.GIP0.I2C_", 0, ResourceConsumer, , )
+    })
+    Method(_CRS, 0x0, NotSerialized)
+    {
+        Return(RBUF)
+    }
+    Method(_STA, 0x0, NotSerialized)
+    {
+        //
+        // Only Platform Type / Id 8 has this device.
+        //
+        If(LNotEqual(PTYP, 8))
+        {
+          return (0)
+        }
+        Return(0xf)
+    }
+}
+
+Device(NIO2)
+{
+    Name(_HID, "INT3491") // NXP PCAL9555A i2c-accessible I/O expander.
+    Name(_CID, "INT3491")
+    Name(_UID, 2)
+
+    Name(RBUF, ResourceTemplate()
+    {
+        I2CSerialBus(0x26, ControllerInitiated, 400000, AddressingMode7Bit, "\\_SB.PCI0.GIP0.I2C_", 0, ResourceConsumer, , )
+    })
+    Method(_CRS, 0x0, NotSerialized)
+    {
+        Return(RBUF)
+    }
+    Method(_STA, 0x0, NotSerialized)
+    {
+        //
+        // Only Platform Type / Id 8 has this device.
+        //
+        If(LNotEqual(PTYP, 8))
+        {
+          return (0)
+        }
+        Return(0xf)
+    }
+}
+
+Device(NIO3)
+{
+    Name(_HID, "INT3491") // NXP PCAL9555A i2c-accessible I/O expander.
+    Name(_CID, "INT3491")
+    Name(_UID, 3)
+
+    Name(RBUF, ResourceTemplate()
+    {
+        I2CSerialBus(0x27, ControllerInitiated, 400000, AddressingMode7Bit, "\\_SB.PCI0.GIP0.I2C_", 0, ResourceConsumer, , )
+        GpioInt (Level, ActiveLow, Exclusive, PullDefault, , "\\_SB.PCI0.GIP0.GPO", 0, ResourceConsumer, , ) {QUARK_GPIO1_MAPPING} /* GPIO<1> is EXP2_INT */
+    })
+    Method(_CRS, 0x0, NotSerialized)
+    {
+        Return(RBUF)
+    }
+    Method(_STA, 0x0, NotSerialized)
+    {
+        //
+        // Only Platform Type / Id 8 has this device.
+        //
+        If(LNotEqual(PTYP, 8))
+        {
+          return (0)
+        }
+        Return(0xf)
+    }
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PciHostBridge.asi b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PciHostBridge.asi
new file mode 100644
index 0000000000..0535d479e5
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PciHostBridge.asi
@@ -0,0 +1,195 @@
+/** @file
+PCI Host Bridge Definitions
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+Name(PBRS, ResourceTemplate() {
+   WORDBusNumber(            //Bus number resource (0); the bridge produces bus numbers for its subsequent buses
+      ResourceProducer,      // bit 0 of general flags is 1
+      MinFixed,              // Range is fixed
+      MaxFixed,              // Range is fixed
+      PosDecode,             // PosDecode
+      0x0000,                // Granularity
+      0x0000,                // Min
+      0x001f,                // Max
+      0x0000,                // Translation
+      0x0020                 // Range Length = Max-Min+1
+   )
+
+   WORDIO(                   //Consumed-and-produced resource (all I/O below CF8)
+      ResourceProducer,      // bit 0 of general flags is 0
+      MinFixed,              // Range is fixed
+      MaxFixed,              // Range is fixed
+      PosDecode,
+      EntireRange,
+      0x0000,                // Granularity
+      0x0000,                // Min
+      0x0cf7,                // Max
+      0x0000,                // Translation
+      0x0cf8                 // Range Length
+   )
+
+   IO(                       //Consumed resource (CF8-CFF)
+      Decode16,
+      0x0cf8,
+      0xcf8,
+      1,
+      8
+   )
+
+   WORDIO(                   //Consumed-and-produced resource (all I/O above CFF)
+      ResourceProducer,      // bit 0 of general flags is 0
+      MinFixed,              // Range is fixed
+      MaxFixed,              // Range is fixed
+      PosDecode,
+      EntireRange,
+      0x0000,                // Granularity
+      0x0d00,                // Min
+      0xffff,                // Max
+      0x0000,                // Translation
+      0xf300                 // Range Length
+   )
+
+   DWORDMEMORY(              // descriptor for dos area(0->0xa0000)
+      ResourceProducer,      // bit 0 of general flags is 0
+      PosDecode,
+      MinFixed,              // Range is fixed
+      MaxFixed,              // Range is Fixed
+      Cacheable,
+      ReadWrite,
+      0x00000000,            // Granularity
+      0x000a0000,            // Min
+      0x000bffff,            // Max
+      0x00000000,            // Translation
+      0x00020000             // Range Length
+   )
+
+   DWORDMemory(              // Consumed-and-produced resource for pci memory mapped memory
+      ResourceProducer,      // bit 0 of general flags is 0
+      PosDecode,             // positive Decode
+      MinFixed,              // Range is fixed
+      MaxFixed,              // Range is fixed
+      Cacheable,
+      ReadWrite,
+      0x00000000,            // Granularity
+      0x00000000,            // Min (calculated dynamically)
+
+      0xfebfffff,            // Max = IO Apic base address - 1
+      0x00000000,            // Translation
+      0xfec00000,            // Range Length (calculated dynamically)
+      ,                      // Optional field left blank
+      ,                      // Optional field left blank
+      MEM1                   // Name declaration for this descriptor
+   )
+
+})          // end of CRES Buffer
+
+
+Method(_CRS, 0x0, NotSerialized)
+{
+    CreateDWordField(PBRS, \_SB.PCI0.MEM1._MIN, MMIN)
+    CreateDWordField(PBRS, \_SB.PCI0.MEM1._MAX, MMAX)
+    CreateDWordField(PBRS, \_SB.PCI0.MEM1._LEN, MLEN)
+
+    // HMBOUND is PCI memory base
+    And(MNRD(0x03, 0x08), 0xFFFFF000, MMIN)
+    Add(Subtract(MMAX, MMIN), 1, MLEN)
+
+    Return(PBRS)
+}
+
+// Message Nework Registers
+OperationRegion(MNR, PCI_Config, 0xD0, 0x10)
+Field(MNR, DWordAcc, NoLock, Preserve)
+{
+    MCR, 32,           // Message Control Register
+    MDR, 32            // Message Data Register
+}
+
+// Message Nework Read Method
+// Arg0 = Port
+// Arg1 = RegAddress
+// return 32 bit register value
+Method(MNRD, 2, Serialized)
+{
+    Or(ShiftLeft(Arg0, 16), ShiftLeft(Arg1, 8), Local0)
+    Or(Local0, 0x100000F0, Local0)
+    Store(Local0, MCR)
+    Return(MDR)
+}
+
+// Message Nework Write Method
+// Arg0 = Port
+// Arg1 = RegAddress
+// Arg2 = 32 bit write value
+Method(MNWR, 3, Serialized)
+{
+    Store(Arg2, MDR)
+    Or(ShiftLeft(Arg0, 16), ShiftLeft(Arg1, 8), Local0)
+    Or(Local0, 0x110000F0, Local0)
+    Store(Local0, MCR)
+}
+
+Method(_PRT, 0, NotSerialized)
+{
+  If (LEqual(\GPIC, Zero)) // 8259 Interrupt Routing
+  {
+    Return (
+      Package()
+      {
+        // Bus 0, Device 20 - IOSFAHB Bridge
+        Package() {0x0014ffff, 0, \_SB.PCI0.LPC.LNKA, 0}, // INTA
+        Package() {0x0014ffff, 1, \_SB.PCI0.LPC.LNKB, 0}, // INTB
+        Package() {0x0014ffff, 2, \_SB.PCI0.LPC.LNKC, 0}, // INTC
+        Package() {0x0014ffff, 3, \_SB.PCI0.LPC.LNKD, 0}, // INTD
+
+        // Bus 0, Device 21 - IOSFAHB Bridge
+        Package() {0x0015ffff, 0, \_SB.PCI0.LPC.LNKA, 0}, // INTA
+        Package() {0x0015ffff, 1, \_SB.PCI0.LPC.LNKB, 0}, // INTB
+        Package() {0x0015ffff, 2, \_SB.PCI0.LPC.LNKC, 0}, // INTC
+        Package() {0x0015ffff, 3, \_SB.PCI0.LPC.LNKD, 0}, // INTD
+
+        // Bus 0, Device 23 - PCIe port 0
+        Package() {0x0017ffff, 0, \_SB.PCI0.LPC.LNKE, 0}, // INTA
+        Package() {0x0017ffff, 1, \_SB.PCI0.LPC.LNKF, 0}, // INTB
+        Package() {0x0017ffff, 2, \_SB.PCI0.LPC.LNKG, 0}, // INTC
+        Package() {0x0017ffff, 3, \_SB.PCI0.LPC.LNKH, 0}, // INTD
+
+        // Bus 0, Device 31
+        Package() {0x001fffff, 0, \_SB.PCI0.LPC.LNKA, 0}, // LPC Bridge
+      }
+    )
+  }
+  else {
+    Return (
+      Package()
+      {
+        // Bus 0, Device 20 - IOSFAHB Bridge
+        Package() {0x0014ffff, 0, 0, 16}, // INTA
+        Package() {0x0014ffff, 1, 0, 17}, // INTB
+        Package() {0x0014ffff, 2, 0, 18}, // INTC
+        Package() {0x0014ffff, 3, 0, 19}, // INTD
+
+        // Bus 0, Device 21 - IOSFAHB Bridge
+        Package() {0x0015ffff, 0, 0, 16}, // INTA
+        Package() {0x0015ffff, 1, 0, 17}, // INTB
+        Package() {0x0015ffff, 2, 0, 18}, // INTC
+        Package() {0x0015ffff, 3, 0, 19}, // INTD
+
+        // Bus 0, Device 23 - PCIe port 0
+        Package() {0x0017ffff, 0, 0, 20}, // INTA
+        Package() {0x0017ffff, 1, 0, 21}, // INTB
+        Package() {0x0017ffff, 2, 0, 22}, // INTC
+        Package() {0x0017ffff, 3, 0, 23}, // INTD
+
+        // Bus 0, Device 31
+        Package() {0x001fffff, 0, 0, 16}, // LPC Bridge
+      }
+    )
+  }
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PciIrq.asi b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PciIrq.asi
new file mode 100644
index 0000000000..c030047666
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PciIrq.asi
@@ -0,0 +1,552 @@
+/** @file
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+// Interrupts can be DEB8=all except 13,8,6,2,1,0
+
+#ifndef PCIIRQ_ASI
+#define PCIIRQ_ASI
+
+OperationRegion(PRR0, PCI_Config, 0x60, 0x08)
+Field(PRR0, ANYACC, NOLOCK, PRESERVE)
+{
+    PIRA, 8,
+    PIRB, 8,
+    PIRC, 8,
+    PIRD, 8,
+    PIRE, 8,
+    PIRF, 8,
+    PIRG, 8,
+    PIRH, 8
+}
+
+Device(LNKA)            // PCI IRQ link A
+{
+    Name(_HID,EISAID("PNP0C0F"))
+
+    Name(_UID, 1)
+
+    Method(_STA,0,NotSerialized)
+    {
+        If(And(PIRA, 0x80))
+        {
+          Return(0x9)
+        }
+        Else
+        {
+          Return(0xB)
+        }    // Don't display
+    }
+
+    Method(_DIS,0,NotSerialized)
+    {
+        Or(PIRA, 0x80, PIRA)
+    }
+
+    Method(_CRS,0,Serialized)
+    {
+        Name(BUF0,
+            ResourceTemplate()
+            {IRQ(Level,ActiveLow,Shared){0}})
+
+                                // Define references to buffer elements
+        CreateWordField (BUF0, 0x01, IRQW)  // IRQ low
+                                // Write current settings into IRQ descriptor
+        If (And(PIRA, 0x80))
+        {
+            Store(Zero, Local0)
+        }
+        Else
+        {
+            Store(One,Local0)
+        }
+                                                    // Shift 1 by value in register 70
+        ShiftLeft(Local0,And(PIRA,0x0F),IRQW)       // Save in buffer
+        Return(BUF0)                                // Return Buf0
+    }                                               // End of _CRS method
+
+    Name(_PRS,
+        ResourceTemplate()
+        {IRQ(Level,ActiveLow,Shared){12,11,10,9,7,5,4,3}})
+
+    Method(_SRS,1,NotSerialized)
+    {
+        CreateWordField (ARG0, 0x01, IRQW)  // IRQ low
+
+        FindSetRightBit(IRQW,Local0)          // Set IRQ
+        If (LNotEqual(IRQW,Zero))
+        {
+            And(Local0, 0x7F,Local0)
+            Decrement(Local0)
+        }
+        Else
+        {
+            Or(Local0, 0x80,Local0)
+        }
+        store(Local0, PIRA)
+    }                                                  // End of _SRS Method
+}
+
+Device(LNKB)            // PCI IRQ link B
+{
+    Name(_HID,EISAID("PNP0C0F"))
+
+    Name(_UID, 2)
+
+    Method(_STA,0,NotSerialized)
+    {
+        If(And(PIRB, 0x80))
+        {
+          Return(0x9)
+        }
+        Else
+        {
+          Return(0xB)
+        }    // Don't display
+    }
+
+    Method(_DIS,0,NotSerialized)
+    {
+        Or(PIRB, 0x80,PIRB)
+    }
+
+    Method(_CRS,0,Serialized)
+    {
+        Name(BUF0,
+            ResourceTemplate()
+            {IRQ(Level,ActiveLow,Shared){0}})
+                                            // Define references to buffer elements
+        CreateWordField (BUF0, 0x01, IRQW)  // IRQ low
+                                            // Write current settings into IRQ descriptor
+        If (And(PIRB, 0x80))
+        {
+            Store(Zero, Local0)
+        }
+        Else
+        {
+                Store(One,Local0)
+        }
+                                               // Shift 1 by value in register 70
+        ShiftLeft(Local0,And(PIRB,0x0F),IRQW)  // Save in buffer
+        Return(BUF0)                           // Return Buf0
+    }                                          // End of _CRS method
+
+    Name(_PRS,
+        ResourceTemplate()
+        {IRQ(Level,ActiveLow,Shared){12,11,10,9,7,5,4,3}})
+
+    Method(_SRS,1,NotSerialized)
+    {
+        CreateWordField (ARG0, 0x01, IRQW)      // IRQ low
+
+        FindSetRightBit(IRQW,Local0)            // Set IRQ
+        If (LNotEqual(IRQW,Zero))
+        {
+            And(Local0, 0x7F,Local0)
+            Decrement(Local0)
+        }
+        Else
+        {
+            Or(Local0, 0x80,Local0)
+        }
+        Store(Local0, PIRB)
+    }                                           // End of _SRS Method
+}
+
+Device(LNKC)                                    // PCI IRQ link C
+{
+    Name(_HID,EISAID("PNP0C0F"))
+
+    Name(_UID, 3)
+
+    Method(_STA,0,NotSerialized)
+    {
+        If(And(PIRC, 0x80))
+        {
+          Return(0x9)
+        }
+        Else
+        {
+          Return(0xB)
+        }    // Don't display
+    }
+
+    Method(_DIS,0,NotSerialized)
+    {
+        Or(PIRC, 0x80,PIRC)
+    }
+
+    Method(_CRS,0,Serialized)
+    {
+        Name(BUF0,
+            ResourceTemplate()
+            {IRQ(Level,ActiveLow,Shared){0}})
+                                            // Define references to buffer elements
+        CreateWordField (BUF0, 0x01, IRQW)  // IRQ low
+                                            // Write current settings into IRQ descriptor
+        If (And(PIRC, 0x80))
+        {
+            Store(Zero, Local0)
+        }
+        Else
+        {
+            Store(One,Local0)
+        }                                      // Shift 1 by value in register 70
+        ShiftLeft(Local0,And(PIRC,0x0F),IRQW)  // Save in buffer
+        Return(BUF0)                           // Return Buf0
+    }                                          // End of _CRS method
+
+    Name(_PRS,
+        ResourceTemplate()
+        {IRQ(Level,ActiveLow,Shared){12,11,10,9,7,5,4,3}})
+
+    Method(_SRS,1,NotSerialized)
+    {
+        CreateWordField (ARG0, 0x01, IRQW)  // IRQ low
+
+        FindSetRightBit(IRQW,Local0)        // Set IRQ
+        If (LNotEqual(IRQW,Zero))
+        {
+            And(Local0, 0x7F,Local0)
+            Decrement(Local0)
+        }
+        Else {
+            Or(Local0, 0x80,Local0)
+        }
+        Store(Local0, PIRC)
+    }                                               // End of _SRS Method
+}
+
+Device(LNKD)                                        // PCI IRQ link D
+{
+    Name(_HID,EISAID("PNP0C0F"))
+
+    Name(_UID, 4)
+
+    Method(_STA,0,NotSerialized)
+    {
+        If(And(PIRD, 0x80))
+        {
+          Return(0x9)
+        }
+        Else
+        {
+          Return(0xB)
+        }    // Don't display
+    }
+
+    Method(_DIS,0,NotSerialized)
+    {
+        Or(PIRD, 0x80,PIRD)
+    }
+
+    Method(_CRS,0,Serialized)
+    {
+        Name(BUF0,
+            ResourceTemplate()
+            {IRQ(Level,ActiveLow,Shared){0}})
+        // Define references to buffer elements
+        CreateWordField (BUF0, 0x01, IRQW)  // IRQ low
+        // Write current settings into IRQ descriptor
+        If (And(PIRD, 0x80))
+        {
+            Store(Zero, Local0)
+        }
+        Else
+        {
+            Store(One,Local0)
+        }  // Shift 1 by value in register 70
+        ShiftLeft(Local0,And(PIRD,0x0F),IRQW)  // Save in buffer
+        Return(BUF0)        // Return Buf0
+    }                  // End of _CRS method
+
+    Name(_PRS,
+        ResourceTemplate()
+        {IRQ(Level,ActiveLow,Shared){12,11,10,9,7,5,4,3}})
+
+    Method(_SRS,1,NotSerialized)
+    {
+        CreateWordField (ARG0, 0x01, IRQW)  // IRQ low
+
+        FindSetRightBit(IRQW,Local0)// Set IRQ
+        If (LNotEqual(IRQW,Zero))
+        {
+            And(Local0, 0x7F,Local0)
+            Decrement(Local0)
+        }
+        Else
+        {
+            Or(Local0, 0x80,Local0)
+        }
+        Store(Local0, PIRD)
+    }                  // End of _SRS Method
+}
+
+Device(LNKE)           // PCI IRQ link E
+{
+    Name(_HID,EISAID("PNP0C0F"))
+
+    Name(_UID, 5)
+
+    Method(_STA,0,NotSerialized)
+    {
+        If(And(PIRE, 0x80))
+        {
+          Return(0x9)
+        }
+        Else
+        {
+          Return(0xB)
+        }    // Don't display
+    }
+
+    Method(_DIS,0,NotSerialized)
+    {
+        Or(PIRE, 0x80, PIRE)
+    }
+
+    Method(_CRS,0,Serialized)
+    {
+        Name(BUF0,
+            ResourceTemplate()
+            {IRQ(Level,ActiveLow,Shared){0}})
+
+                                // Define references to buffer elements
+        CreateWordField (BUF0, 0x01, IRQW)  // IRQ low
+                                // Write current settings into IRQ descriptor
+        If (And(PIRE, 0x80))
+        {
+            Store(Zero, Local0)
+        }
+        Else
+        {
+            Store(One,Local0)
+        }
+                                                    // Shift 1 by value in register 70
+        ShiftLeft(Local0,And(PIRE,0x0F),IRQW)       // Save in buffer
+        Return(BUF0)                                // Return Buf0
+    }                                               // End of _CRS method
+
+    Name(_PRS,
+        ResourceTemplate()
+        {IRQ(Level,ActiveLow,Shared){12,11,10,9,7,5,4,3}})
+
+    Method(_SRS,1,NotSerialized)
+    {
+        CreateWordField (ARG0, 0x01, IRQW)  // IRQ low
+
+        FindSetRightBit(IRQW,Local0)          // Set IRQ
+        If (LNotEqual(IRQW,Zero))
+        {
+            And(Local0, 0x7F,Local0)
+            Decrement(Local0)
+        }
+        Else
+        {
+            Or(Local0, 0x80,Local0)
+        }
+        store(Local0, PIRE)
+    }                                                  // End of _SRS Method
+}
+
+Device(LNKF)            // PCI IRQ link F
+{
+    Name(_HID,EISAID("PNP0C0F"))
+
+    Name(_UID, 6)
+
+    Method(_STA,0,NotSerialized)
+    {
+        If(And(PIRF, 0x80))
+        {
+          Return(0x9)
+        }
+        Else
+        {
+          Return(0xB)
+        }    // Don't display
+    }
+
+    Method(_DIS,0,NotSerialized)
+    {
+        Or(PIRB, 0x80,PIRF)
+    }
+
+    Method(_CRS,0,Serialized)
+    {
+        Name(BUF0,
+            ResourceTemplate()
+            {IRQ(Level,ActiveLow,Shared){0}})
+                                            // Define references to buffer elements
+        CreateWordField (BUF0, 0x01, IRQW)  // IRQ low
+                                            // Write current settings into IRQ descriptor
+        If (And(PIRF, 0x80))
+        {
+            Store(Zero, Local0)
+        }
+        Else
+        {
+                Store(One,Local0)
+        }
+                                               // Shift 1 by value in register 70
+        ShiftLeft(Local0,And(PIRF,0x0F),IRQW)  // Save in buffer
+        Return(BUF0)                           // Return Buf0
+    }                                          // End of _CRS method
+
+    Name(_PRS,
+        ResourceTemplate()
+        {IRQ(Level,ActiveLow,Shared){12,11,10,9,7,5,4,3}})
+
+    Method(_SRS,1,NotSerialized)
+    {
+        CreateWordField (ARG0, 0x01, IRQW)      // IRQ low
+
+        FindSetRightBit(IRQW,Local0)            // Set IRQ
+        If (LNotEqual(IRQW,Zero))
+        {
+            And(Local0, 0x7F,Local0)
+            Decrement(Local0)
+        }
+        Else
+        {
+            Or(Local0, 0x80,Local0)
+        }
+        Store(Local0, PIRF)
+    }                                                   // End of _SRS Method
+}
+
+Device(LNKG)                                            // PCI IRQ link G
+{
+    Name(_HID,EISAID("PNP0C0F"))
+
+    Name(_UID, 7)
+
+    Method(_STA,0,NotSerialized)
+    {
+        If(And(PIRG, 0x80))
+        {
+          Return(0x9)
+        }
+        Else
+        {
+          Return(0xB)
+        }    // Don't display
+    }
+
+    Method(_DIS,0,NotSerialized)
+    {
+        Or(PIRG, 0x80,PIRG)
+    }
+
+    Method(_CRS,0,Serialized)
+    {
+        Name(BUF0,
+            ResourceTemplate()
+            {IRQ(Level,ActiveLow,Shared){0}})
+                                            // Define references to buffer elements
+        CreateWordField (BUF0, 0x01, IRQW)  // IRQ low
+                                            // Write current settings into IRQ descriptor
+        If (And(PIRG, 0x80))
+        {
+            Store(Zero, Local0)
+        }
+        Else
+        {
+            Store(One,Local0)
+        }                                      // Shift 1 by value in register 70
+        ShiftLeft(Local0,And(PIRG,0x0F),IRQW)  // Save in buffer
+        Return(BUF0)                           // Return Buf0
+    }                                          // End of _CRS method
+
+    Name(_PRS,
+        ResourceTemplate()
+        {IRQ(Level,ActiveLow,Shared){12,11,10,9,7,5,4,3}})
+
+    Method(_SRS,1,NotSerialized)
+    {
+        CreateWordField (ARG0, 0x01, IRQW)  // IRQ low
+
+        FindSetRightBit(IRQW,Local0)          // Set IRQ
+        If (LNotEqual(IRQW,Zero))
+        {
+            And(Local0, 0x7F,Local0)
+            Decrement(Local0)
+        }
+        Else {
+            Or(Local0, 0x80,Local0)
+        }
+        Store(Local0, PIRG)
+    }                                               // End of _SRS Method
+}
+
+Device(LNKH)                                        // PCI IRQ link H
+{
+    Name(_HID,EISAID("PNP0C0F"))
+
+    Name(_UID, 8)
+
+    Method(_STA,0,NotSerialized)
+    {
+        If(And(PIRH, 0x80))
+        {
+          Return(0x9)
+        }
+        Else
+        {
+          Return(0xB)
+        }    // Don't display
+    }
+
+    Method(_DIS,0,NotSerialized)
+    {
+        Or(PIRH, 0x80,PIRH)
+    }
+
+    Method(_CRS,0,Serialized)
+    {
+        Name(BUF0,
+            ResourceTemplate()
+            {IRQ(Level,ActiveLow,Shared){0}})
+        // Define references to buffer elements
+        CreateWordField (BUF0, 0x01, IRQW)  // IRQ low
+        // Write current settings into IRQ descriptor
+        If (And(PIRH, 0x80))
+        {
+            Store(Zero, Local0)
+        }
+        Else
+        {
+            Store(One,Local0)
+        }  // Shift 1 by value in register 70
+        ShiftLeft(Local0,And(PIRH,0x0F),IRQW)  // Save in buffer
+        Return(BUF0)   // Return Buf0
+    }                  // End of _CRS method
+
+    Name(_PRS,
+        ResourceTemplate()
+        {IRQ(Level,ActiveLow,Shared){12,11,10,9,7,5,4,3}})
+
+    Method(_SRS,1,NotSerialized)
+    {
+        CreateWordField (ARG0, 0x01, IRQW)  // IRQ low
+
+        FindSetRightBit(IRQW,Local0)// Set IRQ
+        If (LNotEqual(IRQW,Zero))
+        {
+            And(Local0, 0x7F,Local0)
+            Decrement(Local0)
+        }
+        Else
+        {
+            Or(Local0, 0x80,Local0)
+        }
+        Store(Local0, PIRH)
+    }                  // End of _SRS Method
+}
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PcieExpansionPrt.asi b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PcieExpansionPrt.asi
new file mode 100644
index 0000000000..e41230867e
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PcieExpansionPrt.asi
@@ -0,0 +1,127 @@
+/** @file
+PCI express expansion ports
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PcieExpansionPrt_asi
+#define PcieExpansionPrt_asi
+
+Device (PEX0)    // PCI express bus bridged from [Bus 0, Device 23, Function 0]
+{
+    Name(_ADR,0x00170000)            // Device (HI WORD)=23, Func (LO WORD)=0
+    Name(_PRW,Package(){0x11,0x03})  // GPE pin 0x11, Wake from S3 -- PCI PME#
+
+    OperationRegion (PES0,PCI_Config,0x40,0xA0)
+    Field (PES0, AnyAcc, NoLock, Preserve)
+    {
+    Offset(0x1A),              // SLSTS - Slot Status Register
+    ABP0,  1,                  // Bit 0, Attention Button Pressed
+    ,  2,
+    PDC0,  1,                  // Bit 3, Presence Detect Changed
+    ,  2,
+    PDS0,  1,                  // Bit 6, Presence Detect State
+    , 1,
+    LSC0,  1,                  // Bit 8, Link Active State Changed
+    offset (0x20),
+    , 16,
+    PMS0, 1,                   // Bit 16, PME Status
+    offset (0x98),
+    , 30,
+    HPE0, 1,                   // Bit 30, Hot Plug SCI Enable
+    PCE0, 1,                   // Bit 31, Power Management SCI Enable.
+    , 30,
+    HPS0, 1,                   // Bit 30, Hot Plug SCI Status
+    PCS0, 1,                   // Bit 31, Power Management SCI Status.
+    }
+
+    Method(_PRT,0,NotSerialized) {
+        If (LEqual(\GPIC, Zero)) // 8259 Interrupt Routing
+        {
+            Return (
+                Package()
+                {
+                    // Port 0: INTA->PIRQE,INTB->PIRQF,INTC->PIRQG,INTD->PIRQH
+                    Package() {0x0000ffff, 0, \_SB_.PCI0.LPC.LNKE, 0}, // PCI Slot 1
+                    Package() {0x0000ffff, 1, \_SB_.PCI0.LPC.LNKF, 0},
+                    Package() {0x0000ffff, 2, \_SB_.PCI0.LPC.LNKG, 0},
+                    Package() {0x0000ffff, 3, \_SB_.PCI0.LPC.LNKH, 0},
+                }
+            )
+        }
+        else    // IOAPIC Routing
+        {
+            Return (
+                Package()
+                {
+                    // Port 0: INTA->PIRQE,INTB->PIRQF,INTC->PIRQG,INTD->PIRQH
+                    Package() {0x0000ffff, 0, 0, 20}, // PCI Slot 1
+                    Package() {0x0000ffff, 1, 0, 21},
+                    Package() {0x0000ffff, 2, 0, 22},
+                    Package() {0x0000ffff, 3, 0, 23},
+                }
+            )
+        }
+    }
+}
+
+Device (PEX1)    // PCI express bus bridged from [Bus 0, Device 23, Function 1]
+{
+    Name(_ADR,0x00170001)            // Device (HI WORD)=23, Func (LO WORD)=1
+    Name(_PRW,Package(){0x11,0x03})  // GPE pin 0x11, Wake from S3 -- PCI PME#
+    OperationRegion (PES1,PCI_Config,0x40,0xA0)
+    Field (PES1, AnyAcc, NoLock, Preserve)
+    {
+    Offset(0x1A),              // SLSTS - Slot Status Register
+    ABP1,  1,                  // Bit 0, Attention Button Pressed
+    ,  2,
+    PDC1,  1,                  // Bit 3, Presence Detect Changed
+    ,  2,
+    PDS1,  1,                  // Bit 6, Presence Detect State
+    , 1,
+    LSC1,  1,                  // Bit 8, Link Active State Changed
+    offset (0x20),
+    , 16,
+    PMS1, 1,                   // Bit 16, PME Status
+    offset (0x98),
+    , 30,
+    HPE1, 1,                   // Bit 30, Hot Plug SCI Enable
+    PCE1, 1,                   // Bit 31, Power Management SCI Enable.
+    , 30,
+    HPS1, 1,                   // Bit 30, Hot Plug SCI Status
+    PCS1, 1,                   // Bit 31, Power Management SCI Status.
+    }
+    Method(_PRT,0,NotSerialized) {
+        If (LEqual(\GPIC, Zero)) // 8259 Interrupt Routing
+        {
+            Return (
+                Package()
+                {
+                    // Port 1: INTA->PIRQF,INTB->PIRQG,INTC->PIRQH,INTD->PIRQE
+                    Package() {0x0000ffff, 0, \_SB_.PCI0.LPC.LNKF, 0},
+                    Package() {0x0000ffff, 1, \_SB_.PCI0.LPC.LNKG, 0},
+                    Package() {0x0000ffff, 2, \_SB_.PCI0.LPC.LNKH, 0},
+                    Package() {0x0000ffff, 3, \_SB_.PCI0.LPC.LNKE, 0},
+                }
+            )
+        }
+        else    // IOAPIC Routing
+        {
+            Return (
+                Package()
+                {
+                    // Port 1: INTA->PIRQF,INTB->PIRQG,INTC->PIRQH,INTD->PIRQE
+                    Package() {0x0000ffff, 0, 0, 21},
+                    Package() {0x0000ffff, 1, 0, 22},
+                    Package() {0x0000ffff, 2, 0, 23},
+                    Package() {0x0000ffff, 3, 0, 20},
+                }
+            )
+        }
+    }
+}
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Platform.asl b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Platform.asl
new file mode 100644
index 0000000000..35bae8248a
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Platform.asl
@@ -0,0 +1,347 @@
+/** @file
+Contains root level name space objects for the platform
+
+Copyright (c) 2013-2019 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// OS TYPE DEFINITION
+//
+#define WINDOWS_XP          0x01
+#define WINDOWS_XP_SP1      0x02
+#define WINDOWS_XP_SP2      0x04
+#define WINDOWS_2003        0x08
+#define WINDOWS_Vista       0x10
+#define WINDOWS_WIN7        0x11
+#define WINDOWS_WIN8        0x12
+#define WINDOWS_WIN8_1      0x13
+#define LINUX               0xF0
+
+//
+// GPIO Interrupt Connection Resource Descriptor (GpioInt) usage.
+// GpioInt() descriptors maybe used in this file and included .asi files.
+//
+// The mapping below was provided by the first OS user that requested
+// GpioInt() support.
+// Other OS users that need GpioInt() support must use the following mapping.
+//
+#define QUARK_GPIO8_MAPPING         0x00
+#define QUARK_GPIO9_MAPPING         0x01
+#define QUARK_GPIO_SUS0_MAPPING     0x02
+#define QUARK_GPIO_SUS1_MAPPING     0x03
+#define QUARK_GPIO_SUS2_MAPPING     0x04
+#define QUARK_GPIO_SUS3_MAPPING     0x05
+#define QUARK_GPIO_SUS4_MAPPING     0x06
+#define QUARK_GPIO_SUS5_MAPPING     0x07
+#define QUARK_GPIO0_MAPPING         0x08
+#define QUARK_GPIO1_MAPPING         0x09
+#define QUARK_GPIO2_MAPPING         0x0A
+#define QUARK_GPIO3_MAPPING         0x0B
+#define QUARK_GPIO4_MAPPING         0x0C
+#define QUARK_GPIO5_MAPPING         0x0D
+#define QUARK_GPIO6_MAPPING         0x0E
+#define QUARK_GPIO7_MAPPING         0x0F
+
+DefinitionBlock (
+  "Platform.aml",
+  "DSDT",
+  1,
+  "INTEL ",
+  "QuarkNcS",
+  3)
+{
+    //
+    // Global Variables
+    //
+    Name(\GPIC, 0x0)
+
+    //
+    // Port 80
+    //
+    OperationRegion (DBG0, SystemIO, 0x80, 1)
+    Field (DBG0, ByteAcc, NoLock, Preserve)
+    { IO80,8 }
+
+    //
+    // Access CMOS range
+    //
+    OperationRegion (ACMS, SystemIO, 0x72, 2)
+    Field (ACMS, ByteAcc, NoLock, Preserve)
+    { INDX, 8, DATA, 8 }
+
+    //
+    // Global NVS Memory Block
+    //
+    OperationRegion (MNVS, SystemMemory, 0xFFFF0000, 512)
+    Field (MNVS, ByteAcc, NoLock, Preserve)
+    {
+      OSTP, 32,
+      CFGD, 32,
+      HPEA, 32,  // HPET Enabled ?
+
+      P1BB, 32,  // Pm1blkIoBaseAddress;
+      PBAB, 32,  // PmbaIoBaseAddress;
+      GP0B, 32,  // Gpe0blkIoBaseAddress;
+      GPAB, 32,  // GbaIoBaseAddress;
+
+      SMBB, 32,  // SmbaIoBaseAddress;
+      NRV1, 32,  // GNVS reserved field 1.
+      WDTB, 32,  // WdtbaIoBaseAddress;
+
+      HPTB, 32,  // HpetBaseAddress;
+      HPTS, 32,  // HpetSize;
+      PEXB, 32,  // PciExpressBaseAddress;
+      PEXS, 32,  // PciExpressSize;
+
+      RCBB, 32,  // RcbaMmioBaseAddress;
+      RCBS, 32,  // RcbaMmioSize;
+      APCB, 32,  // IoApicBaseAddress;
+      APCS, 32,  // IoApicSize;
+
+      TPMP, 32,  // TpmPresent ?
+      DBGP, 32,  // DBG2 Present?
+      PTYP, 32,  // Set to one of EFI_PLATFORM_TYPE enums.
+      ALTS, 32,  // Use alternate I2c SLA addresses.
+    }
+
+    OperationRegion (GPEB, SystemIO, 0x1100, 0x40)  //GPE Block
+    Field (GPEB, AnyAcc, NoLock, Preserve)
+    {
+      Offset(0x10),
+      SMIE, 32,                 // SMI Enable
+      SMIS, 32,                 // SMI Status
+    }
+
+    //
+    //  Processor Objects
+    //
+    Scope(\_PR) {
+        //
+        // IO base will be updated at runtime with search key "PRIO"
+        //
+        Processor (CPU0, 0x01, 0x4F495250, 0x06) {}
+    }
+
+    //
+    // System Sleep States
+    //
+    Name (\_S0,Package (){0,0,0,0})
+    Name (\_S3,Package (){5,0,0,0})
+    Name (\_S4,Package (){6,0,0,0})
+    Name (\_S5,Package (){7,0,0,0})
+
+    //
+    //  General Purpose Event
+    //
+    Scope(\_GPE)
+    {
+        //
+        // EGPE generated GPE
+        //
+        Method(_L0D, 0x0, NotSerialized)
+        {
+            //
+            // Check EGPE for this wake event
+            //
+            Notify (\_SB.SLPB, 0x02)
+
+        }
+
+        //
+        // GPIO generated GPE
+        //
+        Method(_L0E, 0x0, NotSerialized)
+        {
+            //
+            // Check GPIO for this wake event
+            //
+            Notify (\_SB.PWRB, 0x02)
+
+        }
+
+        //
+        // SCLT generated GPE
+        //
+        Method(_L0F, 0x0, NotSerialized)
+        {
+            //
+            // Check SCLT for this wake event
+            //
+            Notify (\_SB.PCI0.SDIO, 0x02)
+            Notify (\_SB.PCI0.URT0, 0x02)
+            Notify (\_SB.PCI0.USBD, 0x02)
+            Notify (\_SB.PCI0.EHCI, 0x02)
+            Notify (\_SB.PCI0.OHCI, 0x02)
+            Notify (\_SB.PCI0.URT1, 0x02)
+            Notify (\_SB.PCI0.ENT0, 0x02)
+            Notify (\_SB.PCI0.ENT1, 0x02)
+            Notify (\_SB.PCI0.SPI0, 0x02)
+            Notify (\_SB.PCI0.SPI1, 0x02)
+            Notify (\_SB.PCI0.GIP0, 0x02)
+
+        }
+
+        //
+        // Remote Management Unit generated GPE
+        //
+        Method(_L10, 0x0, NotSerialized)
+        {
+            //
+            // Check Remote Management Unit for this wake event.
+            //
+        }
+
+        //
+        // PCIE generated GPE
+        //
+        Method(_L11, 0x0, NotSerialized)
+        {
+            //
+            // Check PCIE for this wake event
+            //
+            Notify (\_SB.PCI0.PEX0, 0x02)
+            Notify (\_SB.PCI0.PEX1, 0x02)
+        }
+    }
+
+    //
+    // define Sleeping button as mentioned in ACPI spec 2.0
+    //
+    Device (\_SB.SLPB)
+    {
+        Name (_HID, EISAID ("PNP0C0E"))
+        Method (_PRW, 0, NotSerialized)
+        {
+            Return (Package (0x02) {0x0D,0x04})
+        }
+    }
+
+    //
+    // define Power Button
+    //
+     Device (\_SB.PWRB)
+    {
+        Name (_HID, EISAID ("PNP0C0C"))
+        Method (_PRW, 0, NotSerialized)
+        {
+            Return (Package (0x02) {0x0E,0x04})
+        }
+    }
+    //
+    // System Wake up
+    //
+    Method(_WAK, 1, Serialized)
+    {
+       // Do nothing here
+       Return (0)
+    }
+
+    //
+    // System sleep down
+    //
+    Method (_PTS, 1, NotSerialized)
+    {
+        // Get ready for S3 sleep
+        if (Lequal(Arg0,3))
+        {
+                Store(0xffffffff,SMIS)     // clear SMI status
+                Store(SMIE, Local0)        // SMI Enable
+                Or(Local0,0x4,SMIE)        // Generate SMI on sleep
+        }
+    }
+
+    //
+    // Determing PIC mode
+    //
+    Method(\_PIC, 1, NotSerialized)
+    {
+        Store(Arg0,\GPIC)
+    }
+
+    //
+    //  System Bus
+    //
+    Scope(\_SB)
+    {
+        Device(PCI0)
+        {
+            Name(_HID,EISAID ("PNP0A08"))          // PCI Express Root Bridge
+            Name(_CID,EISAID ("PNP0A03"))          // Compatible PCI Root Bridge
+
+            Name(_ADR,0x00000000)                  // Device (HI WORD)=0, Func (LO WORD)=0
+            Method (_INI)
+            {
+                Store(LINUX, OSTP)                 // Set the default os is Linux
+                If (CondRefOf (_OSI))
+                {
+                    //
+                    //_OSI is supported, so it is WinXp or Win2003Server
+                    //
+                    If (\_OSI("Windows 2001"))
+                    {
+                        Store (WINDOWS_XP, OSTP)
+                    }
+                    If (\_OSI("Windows 2001 SP1"))
+                    {
+                        Store (WINDOWS_XP_SP1, OSTP)
+                    }
+                    If (\_OSI("Windows 2001 SP2"))
+                    {
+                        Store (WINDOWS_XP_SP2, OSTP)
+                    }
+                    If (\_OSI("Windows 2001.1"))
+                    {
+                        Store (WINDOWS_2003, OSTP)
+                    }
+                    If (\_OSI("Windows 2006"))
+                    {
+                        Store (WINDOWS_Vista, OSTP)
+                    }
+                    If (\_OSI("Windows 2009"))
+                    {
+                        Store (WINDOWS_WIN7, OSTP)
+                    }
+                    If (\_OSI("Windows 2012"))
+                    {
+                        Store (WINDOWS_WIN8, OSTP)
+                    }
+                    If (\_OSI("Windows 2013"))
+                    {
+                        Store (WINDOWS_WIN8_1, OSTP)
+                    }
+                    If (\_OSI("Linux"))
+                    {
+                      Store (LINUX, OSTP)
+                    }
+                }
+            }
+
+            Include ("PciHostBridge.asi")     // PCI0 Host bridge
+            Include ("QNC.asi")               // QNC miscellaneous
+            Include ("PcieExpansionPrt.asi")  // PCIe expansion bridges/devices
+            Include ("QuarkSouthCluster.asi") // Quark South Cluster devices
+            Include ("QNCLpc.asi")            // LPC bridge device
+            Include ("QNCApic.asi")           // QNC I/O Apic device
+
+        }
+
+        //
+        // Include asi files for I2C and SPI onboard devices.
+        // Devices placed here instead of below relevant controllers.
+        // Hardware topology information is maintained by the
+        // ResourceSource arg to the I2CSerialBus/SPISerialBus macros
+        // within the device asi files.
+        //
+        Include ("Tpm.asi")          // TPM device.
+        Include ("CY8C9540A.asi")    // CY8C9540A 40Bit I/O Expander & EEPROM
+        Include ("PCAL9555A.asi")    // NXP PCAL9555A I/O expander.
+        Include ("PCA9685.asi")      // NXP PCA9685 PWM/LED controller.
+        Include ("CAT24C08.asi")     // ONSEMI CAT24C08 I2C 8KB EEPROM.
+        Include ("AD7298.asi")       // Analog devices AD7298 ADC.
+        Include ("ADC108S102.asi")   // TI ADC108S102 ADC.
+        Include ("GpioClient.asi")   // Software device to expose GPIO
+    }
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNC.asi b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNC.asi
new file mode 100644
index 0000000000..12ec4fab83
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNC.asi
@@ -0,0 +1,49 @@
+/** @file
+QNC devices
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef QNC_ASI
+#define QNC_ASI
+
+Device(IOCM) // I/O controller miscellaneous
+{
+    Name(_HID,EISAID("PNP0C02"))   // System board resources device node ID
+
+    Name(CRS, ResourceTemplate()
+        {
+
+            // PCIEXBAR memory range
+            Memory32Fixed(ReadOnly, 0, 0, FIX1)
+
+            // RCRB memory range
+            Memory32Fixed(ReadOnly, 0, 0, FIX2)
+
+            // Option ROM shadow memory range
+            Memory32Fixed(ReadOnly, 0x000C0000, 0x20000)
+
+            // BIOS ROM shadow memory range
+            Memory32Fixed(ReadOnly, 0x000E0000, 0x20000)
+
+            // BIOS Firmware just below 4GByte of memory 8MBytes
+            Memory32Fixed(ReadOnly, 0xFF800000, 0x800000)
+        }
+    )
+
+    Method (_CRS, 0, NotSerialized) {
+        CreateDWordField (CRS, ^FIX1._BAS, MBR0)
+        Store(\PEXB, MBR0)
+        CreateDWordField (CRS, ^FIX1._LEN, MBR1)
+        Store(\PEXS, MBR1)
+        CreateDWordField (CRS, ^FIX2._BAS, MBR2)
+        Store(\RCBB, MBR2)
+        CreateDWordField (CRS, ^FIX2._LEN, MBR3)
+        Store(\RCBS, MBR3)
+        Return (CRS)
+    }
+}
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNCApic.asi b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNCApic.asi
new file mode 100644
index 0000000000..717972a8ac
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNCApic.asi
@@ -0,0 +1,32 @@
+/** @file
+QNC I/O Apic devices
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef QNC_APIC_ASI
+#define QNC_APIC_ASI
+
+Device(APIC)
+{
+    Name(_HID,EISAID("PNP0003"))        // APIC resources
+
+    Name(CRS, ResourceTemplate()
+        {
+            Memory32Fixed(ReadOnly, 0, 0, FIX1) // IO APIC
+        }
+    )
+
+    Method (_CRS, 0, NotSerialized) {
+        CreateDWordField (CRS, ^FIX1._BAS, MBR0)
+        Store(\APCB, MBR0)
+        CreateDWordField (CRS, ^FIX1._LEN, MBR1)
+        Store(\APCS, MBR1)
+        Return (CRS)
+    }
+}
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNCLpc.asi b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNCLpc.asi
new file mode 100644
index 0000000000..7f5fe0a87e
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNCLpc.asi
@@ -0,0 +1,23 @@
+/** @file
+Lpc devices and control methods
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#ifndef QNC_LPC_ASI
+#define QNC_LPC_ASI
+
+Device(LPC)
+{
+    Name(_ADR,0x001f0000)        // Device (HI WORD)=31, Func (LO WORD)=0
+
+    Include ("PciIrq.asi")       // PCI routing control methods
+    Include ("LpcDev.asi")       // Static Lpc device resource declaration
+}
+
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QuarkSouthCluster.asi b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QuarkSouthCluster.asi
new file mode 100644
index 0000000000..2c59285eb4
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QuarkSouthCluster.asi
@@ -0,0 +1,110 @@
+/** @file
+Quark South Cluster Devices.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef QuarkSouthCluster_asi
+#define QuarkSouthCluster_asi
+
+Device (SDIO)    // SDIO [Bus 0, Device 20, Function 0]
+{
+    Name(_ADR,0x00140000)            // Device (HI WORD)=20, Func (LO WORD)=0
+    Name(_STA,0xF)                   // Enabled, do Display
+    Name(_PRW,Package(){0x0F,0x03})  // GPE pin 0x0F, Wake from S3 -- PCI PME#
+}
+
+Device (URT0)    // UART0 [Bus 0, Device 20, Function 1]
+{
+    Name(_ADR,0x00140001)            // Device (HI WORD)=20, Func (LO WORD)=1
+    Name(_STA,0xF)                   // Enabled, do Display
+    Name(_PRW,Package(){0x0F,0x03})  // GPE pin 0x0F, Wake from S3 -- PCI PME#
+}
+
+Device (USBD)    // USB Device [Bus 0, Device 20, Function 2]
+{
+    Name(_ADR,0x00140002)            // Device (HI WORD)=20, Func (LO WORD)=2
+    Name(_STA,0xF)                   // Enabled, do Display
+    Name(_PRW,Package(){0x0F,0x03})  // GPE pin 0x0F, Wake from S3 -- PCI PME#
+}
+
+Device (EHCI)    // EHCI [Bus 0, Device 20, Function 3]
+{
+    Name(_ADR,0x00140003)            // Device (HI WORD)=20, Func (LO WORD)=3
+    Name(_STA,0xF)                   // Enabled, do Display
+    Name(_PRW,Package(){0x0F,0x03})  // GPE pin 0x0F, Wake from S3 -- PCI PME#
+}
+
+Device (OHCI)    // OHCI [Bus 0, Device 20, Function 4]
+{
+    Name(_ADR,0x00140004)            // Device (HI WORD)=20, Func (LO WORD)=4
+    Name(_STA,0xF)                   // Enabled, do Display
+    Name(_PRW,Package(){0x0F,0x03})  // GPE pin 0x0F, Wake from S3 -- PCI PME#
+}
+
+Device (URT1)    // UART1 [Bus 0, Device 20, Function 5]
+{
+    Name(_ADR,0x00140005)            // Device (HI WORD)=20, Func (LO WORD)=5
+    Name(_STA,0xF)                   // Enabled, do Display
+    Name(_PRW,Package(){0x0F,0x03})  // GPE pin 0x0F, Wake from S3 -- PCI PME#
+}
+
+Device (ENT0)    // Ethernet0 [Bus 0, Device 20, Function 6]
+{
+    Name(_ADR,0x00140006)            // Device (HI WORD)=20, Func (LO WORD)=6
+    Name(_STA,0xF)                   // Enabled, do Display
+    Name(_PRW,Package(){0x0F,0x03})  // GPE pin 0x0F, Wake from S3 -- PCI PME#
+}
+
+Device (ENT1)    // Ethernet1 [Bus 0, Device 20, Function 7]
+{
+    Name(_ADR,0x00140007)            // Device (HI WORD)=20, Func (LO WORD)=7
+    Name(_STA,0xF)                   // Enabled, do Display
+    Name(_PRW,Package(){0x0F,0x03})  // GPE pin 0x0F, Wake from S3 -- PCI PME#
+}
+
+Device (SPI0)    // SPI0 [Bus 0, Device 21, Function 0]
+{
+    Name(_ADR,0x00150000)            // Device (HI WORD)=21, Func (LO WORD)=0
+    Name(_STA,0xF)                   // Enabled, do Display
+    Name(_PRW,Package(){0x0F,0x03})  // GPE pin 0x0F, Wake from S3 -- PCI PME#
+}
+
+Device (SPI1)    // SPI1 [Bus 0, Device 21, Function 1]
+{
+    Name(_ADR,0x00150001)            // Device (HI WORD)=21, Func (LO WORD)=1
+    Name(_STA,0xF)                   // Enabled, do Display
+    Name(_PRW,Package(){0x0F,0x03})  // GPE pin 0x0F, Wake from S3 -- PCI PME#
+}
+
+Device (GIP0)    // I2C/GPIO [Bus 0, Device 21, Function 2]
+{
+    Name(_ADR,0x00150002)            // Device (HI WORD)=21, Func (LO WORD)=2
+    Name(_STA,0xF)                   // Enabled, do Display
+    Name(_PRW,Package(){0x0F,0x03})  // GPE pin 0x0F, Wake from S3 -- PCI PME#
+
+    Device(GPO_)  // GPIO Virtual Child Device- for BAR0 resources
+    {
+        Name(_ADR, 0)
+        Name(_STA, 0xf)
+        Name(_PRW, Package(0x2)
+        {
+            0xf,
+            0x3
+        })
+    }
+    Device(I2C_)  // I2C Controller Virtual Child Device- for BAR1 resources
+    {
+        Name(_ADR, 1)
+        Name(_STA, 0xf)
+        Name(_PRW, Package(0x2)
+        {
+            0xf,
+            0x3
+        })
+    }
+}
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Tpm.asi b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Tpm.asi
new file mode 100644
index 0000000000..716265596d
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Tpm.asi
@@ -0,0 +1,45 @@
+/** @file
+
+The Infineon SLB9645 TPM ACPI definition block.
+Provides TPM device info. and TPM presence check only.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+Device (TPM)
+{
+  //
+  // Define _HID as Infineon TPM Device, _CID as "PNP0C31" (defined in
+  // "Secure Startup-FVE and TPM Admin BIOS and Platform Requirements").
+  //
+  Name(_HID ,EISAID("INT3493"))
+  Name(_CID, EISAID("PNP0C31"))
+
+  //
+  // Readable name of this device.
+  //
+  Name (_STR, Unicode ("Infineon TPM 1.2 Device (SLB9645TT1.2)"))
+
+  //
+  // Return the resource consumed by TPM device.
+  //
+  Name (_CRS, ResourceTemplate () {
+    I2cSerialBus (0x20, ControllerInitiated, 0x00061A80, AddressingMode7Bit, "\\_SB.PCI0.GIP0.I2C_", 0, ResourceConsumer,,)
+  })
+
+  //
+  // Check if TPM present.
+  //
+  Method (_STA, 0)
+  {
+    if (LEqual (TPMP, 0))
+    {
+      return (0)
+    }
+    Return (0x0f)
+  }
+
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Facs/Facs.aslc b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Facs/Facs.aslc
new file mode 100644
index 0000000000..a11fde1d6b
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Facs/Facs.aslc
@@ -0,0 +1,74 @@
+/** @file
+This file contains the FACS structure definition.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// Statements that include other files
+//
+#include "Facs.h"
+
+EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE FACS = {
+  EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE,
+  sizeof (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE),
+
+  //
+  // Hardware Signature will be updated at runtime
+  //
+  0x00000000,
+  EFI_ACPI_FIRMWARE_WAKING_VECTOR,
+  EFI_ACPI_GLOBAL_LOCK,
+  EFI_ACPI_FIRMWARE_CONTROL_STRUCTURE_FLAGS,
+  EFI_ACPI_X_FIRMWARE_WAKING_VECTOR,
+  EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION,
+  {
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE
+  }
+};
+
+VOID*
+ReferenceAcpiTable (
+  VOID
+  )
+
+{
+  //
+  // Reference the table being generated to prevent the optimizer from removing the
+  // data structure from the exeutable
+  //
+  return (VOID*)&FACS;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Facs/Facs.h b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Facs/Facs.h
new file mode 100644
index 0000000000..3110ca0eb9
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Facs/Facs.h
@@ -0,0 +1,29 @@
+/** @file
+This file describes the contents of the ACPI Firmware ACPI Control Structure (FACS)
+.  Some additional ACPI values are defined in Acpi10.h, Acpi20.h, and Acpi30.h
+All changes to the FACS contents should be done in this file.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _FACS_H_
+#define _FACS_H_
+
+//
+// Statements that include other files
+//
+#include <IndustryStandard/Acpi.h>
+
+//
+// FACS Definitions
+//
+#define EFI_ACPI_FIRMWARE_WAKING_VECTOR 0x00000000
+#define EFI_ACPI_GLOBAL_LOCK 0x00000000
+
+#define EFI_ACPI_FIRMWARE_CONTROL_STRUCTURE_FLAGS 0x00000000
+#define EFI_ACPI_X_FIRMWARE_WAKING_VECTOR 0x0000000000000000
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.h b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.h
new file mode 100644
index 0000000000..0876ea355e
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.h
@@ -0,0 +1,102 @@
+/** @file
+This file describes the contents of the ACPI Fixed ACPI Description Table (FADT)
+.  Some additional ACPI values are defined in Acpi10.h, Acpi20.h, and Acpi30.h
+All changes to the FADT contents should be done in this file.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _FADT_H_
+#define _FADT_H_
+
+//
+// Statements that include other files
+//
+#include <IndustryStandard/Acpi.h>
+
+//
+// ACPI table information used to initialize tables.
+//
+#define EFI_ACPI_OEM_ID           'I','N','T','E','L',' '   // OEMID 6 bytes long
+#define EFI_ACPI_OEM_TABLE_ID     SIGNATURE_64('T','I','A','N','O',' ',' ',' ') // OEM table id 8 bytes long
+#define EFI_ACPI_OEM_REVISION     0x00000004
+#define EFI_ACPI_CREATOR_ID       SIGNATURE_32('I','N','T','L')
+#define EFI_ACPI_CREATOR_REVISION 0x0100000D
+
+//
+// FADT Definitions
+//
+#define PM_PROFILE      0x01
+#define INT_MODEL       0x01
+#define SCI_INT_VECTOR  0x0009
+#define ACPI_ENABLE     0x0a0
+#define ACPI_DISABLE    0x0a1
+#define S4BIOS_REQ      0x00
+#define PM1_EVT_LEN     0x04
+#define PM1_CNT_LEN     0x02
+#define PM2_CNT_LEN     0x00
+#define PM_TM_LEN       0x04
+#define GPE0_BLK_LEN    0x08
+#define GPE1_BLK_LEN    0x00
+#define GPE1_BASE       0x00
+#define RESERVED        0x00
+#define P_LVL2_LAT      0x0065
+#define P_LVL3_LAT      0x03e9
+#define FLUSH_SIZE      0x0400
+#define FLUSH_STRIDE    0x0010
+#define DUTY_OFFSET     0x01
+#define DUTY_WIDTH      0x03
+#define DAY_ALRM        0x00
+#define MON_ALRM        0x00
+#define CENTURY         0x00
+#define IAPC_BOOT_ARCH  EFI_ACPI_2_0_LEGACY_DEVICES
+#define FLAG            (EFI_ACPI_1_0_WBINVD | EFI_ACPI_1_0_PROC_C1 | EFI_ACPI_1_0_SLP_BUTTON | EFI_ACPI_1_0_RTC_S4)
+#define FLAG2           (EFI_ACPI_2_0_WBINVD | EFI_ACPI_2_0_PROC_C1 | EFI_ACPI_2_0_PWR_BUTTON | EFI_ACPI_2_0_SLP_BUTTON | EFI_ACPI_2_0_RTC_S4 | EFI_ACPI_2_0_RESET_REG_SUP | EFI_ACPI_3_0_USE_PLATFORM_CLOCK)
+
+#define RESET_REG_ADDRESS_SPACE_ID     EFI_ACPI_2_0_SYSTEM_IO
+#define RESET_REG_BIT_WIDTH            0x08
+#define RESET_REG_BIT_OFFSET           0x00
+#define RESET_REG_ADDRESS              0x0000000000000CF9
+#define RESET_VALUE                    0x02
+
+#define ACPI_RUNTIME_UPDATE            0x00
+
+#define PM1a_EVT_BLK_ADDRESS_SPACE_ID  EFI_ACPI_2_0_SYSTEM_IO
+#define PM1a_EVT_BLK_BIT_WIDTH         0x20
+#define PM1a_EVT_BLK_BIT_OFFSET        0x00
+
+#define PM1b_EVT_BLK_ADDRESS_SPACE_ID  EFI_ACPI_2_0_SYSTEM_IO
+#define PM1b_EVT_BLK_BIT_WIDTH         0x00
+#define PM1b_EVT_BLK_BIT_OFFSET        0x00
+#define PM1b_EVT_BLK_ADDRESS           0x0000000000000000
+
+#define PM1a_CNT_BLK_ADDRESS_SPACE_ID  EFI_ACPI_2_0_SYSTEM_IO
+#define PM1a_CNT_BLK_BIT_WIDTH         0x10
+#define PM1a_CNT_BLK_BIT_OFFSET        0x00
+
+#define PM1b_CNT_BLK_ADDRESS_SPACE_ID  EFI_ACPI_2_0_SYSTEM_IO
+#define PM1b_CNT_BLK_BIT_WIDTH         0x00
+#define PM1b_CNT_BLK_BIT_OFFSET        0x00
+#define PM1b_CNT_BLK_ADDRESS           0x0000000000000000
+
+#define PM2_CNT_BLK_ADDRESS_SPACE_ID   EFI_ACPI_2_0_SYSTEM_IO
+#define PM2_CNT_BLK_BIT_WIDTH          0x00
+#define PM2_CNT_BLK_BIT_OFFSET         0x00
+#define PM2_CNT_BLK_ADDRESS            0x0000000000000000
+
+#define PM_TMR_BLK_ADDRESS_SPACE_ID    EFI_ACPI_2_0_SYSTEM_IO
+#define PM_TMR_BLK_BIT_WIDTH           0x20
+#define PM_TMR_BLK_BIT_OFFSET          0x00
+
+#define GPE0_BLK_ADDRESS_SPACE_ID      EFI_ACPI_2_0_SYSTEM_IO
+#define GPE0_BLK_BIT_WIDTH             0x40
+#define GPE0_BLK_BIT_OFFSET            0x00
+
+#define GPE1_BLK_ADDRESS_SPACE_ID      EFI_ACPI_2_0_SYSTEM_IO
+#define GPE1_BLK_BIT_WIDTH             0x00
+#define GPE1_BLK_BIT_OFFSET            0x00
+#define GPE1_BLK_ADDRESS               0x0000000000000000
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt1.0.aslc b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt1.0.aslc
new file mode 100644
index 0000000000..75214a25e4
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt1.0.aslc
@@ -0,0 +1,76 @@
+/** @file
+This file describes the contents of the ACPI Fixed ACPI Description Table
+(FADT).  Some additional ACPI values are defined in Acpi1_0.h and Acpi2_0.h.
+All changes to the FADT contents should be done in this file.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Fadt.h"
+
+EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE FADT = {
+  EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
+  sizeof (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE),
+  EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION,
+  0,                          // to make sum of entire table == 0
+  EFI_ACPI_OEM_ID,            // OEMID is a 6 bytes long field
+  EFI_ACPI_OEM_TABLE_ID,      // OEM table identification(8 bytes long)
+  EFI_ACPI_OEM_REVISION,      // OEM revision number
+  EFI_ACPI_CREATOR_ID,        // ASL compiler vendor ID
+  EFI_ACPI_CREATOR_REVISION,  // ASL compiler revision number
+  0,                     // Physical addesss of FACS
+  0,                     // Physical address of DSDT
+  INT_MODEL,             // System Interrupt Model
+  RESERVED,              // reserved
+  SCI_INT_VECTOR,        // System vector of SCI interrupt
+  SMI_CMD_IO_PORT,       // Port address of SMI command port
+  ACPI_ENABLE,           // value to write to port smi_cmd to enable ACPI
+  ACPI_DISABLE,          // value to write to port smi_cmd to disable ACPI
+  S4BIOS_REQ,            // Value to write to SMI CMD port to enter the S4BIOS state
+  RESERVED,              // reserved - must be zero
+  PM1a_EVT_BLK_ADDRESS,  // Port address of Power Mgt 1a Event Reg Blk
+  PM1b_EVT_BLK_ADDRESS,  // Port address of Power Mgt 1b Event Reg Blk
+  PM1a_CNT_BLK_ADDRESS,  // Port address of Power Mgt 1a Ctrl Reg Blk
+  PM1b_CNT_BLK_ADDRESS,  // Port address of Power Mgt 1b Ctrl Reg Blk
+  PM2_CNT_BLK_ADDRESS,   // Port address of Power Mgt 2  Ctrl Reg Blk
+  PM_TMR_BLK_ADDRESS,    // Port address of Power Mgt Timer Ctrl Reg Blk
+  GPE0_BLK_ADDRESS,      // Port addr of General Purpose Event 0 Reg Blk
+  GPE1_BLK_ADDRESS,      // Port addr of General Purpose Event 1 Reg Blk
+  PM1_EVT_LEN,           // Byte Length of ports at pm1X_evt_blk
+  PM1_CNT_LEN,           // Byte Length of ports at pm1X_cnt_blk
+  PM2_CNT_LEN,           // Byte Length of ports at pm2_cnt_blk
+  PM_TM_LEN,             // Byte Length of ports at pm_tm_blk
+  GPE0_BLK_LEN,          // Byte Length of ports at gpe0_blk
+  GPE1_BLK_LEN,          // Byte Length of ports at gpe1_blk
+  GPE1_BASE,             // offset in gpe model where gpe1 events start
+  RESERVED,              // reserved
+  P_LVL2_LAT,            // worst case HW latency to enter/exit C2 state
+  P_LVL3_LAT,            // worst case HW latency to enter/exit C3 state
+  FLUSH_SIZE,            // Size of area read to flush caches
+  FLUSH_STRIDE,          // Stride used in flushing caches
+  DUTY_OFFSET,           // bit location of duty cycle field in p_cnt reg
+  DUTY_WIDTH,            // bit width of duty cycle field in p_cnt reg
+  DAY_ALRM,              // index to day-of-month alarm in RTC CMOS RAM
+  MON_ALRM,              // index to month-of-year alarm in RTC CMOS RAM
+  CENTURY,               // index to century in RTC CMOS RAM
+  RESERVED,              // reserved
+  RESERVED,              // reserved
+  RESERVED,              // reserved
+  FLAG
+};
+
+VOID*
+ReferenceAcpiTable (
+  VOID
+  )
+
+{
+  //
+  // Reference the table being generated to prevent the optimizer from removing the
+  // data structure from the exeutable
+  //
+  return (VOID*)&FADT;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt2.0.aslc b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt2.0.aslc
new file mode 100644
index 0000000000..fca60af740
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt2.0.aslc
@@ -0,0 +1,157 @@
+/** @file
+This file describes the contents of the ACPI Fixed ACPI Description Table
+(FADT).  Some additional ACPI values are defined in Acpi1_0.h and Acpi2_0.h.
+All changes to the FADT contents should be done in this file.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Fadt.h"
+
+EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE FADT = {
+  {
+    EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
+    sizeof (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE),
+    EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION,
+    0,                    // to make sum of entire table == 0
+    {EFI_ACPI_OEM_ID},    // OEMID is a 6 bytes long field
+    EFI_ACPI_OEM_TABLE_ID,// OEM table identification(8 bytes long)
+    EFI_ACPI_OEM_REVISION,// OEM revision number
+    EFI_ACPI_CREATOR_ID,  // ASL compiler vendor ID
+    EFI_ACPI_CREATOR_REVISION  // ASL compiler revision number
+  },
+  0,                    // Physical addesss of FACS
+  0,                    // Physical address of DSDT
+  RESERVED,             // reserved
+  PM_PROFILE,           // Preferred powermanagement profile
+  SCI_INT_VECTOR,       // System vector of SCI interrupt
+  ACPI_RUNTIME_UPDATE,  // Port address of SMI command port
+  ACPI_ENABLE,          // value to write to port smi_cmd to enable ACPI
+  ACPI_DISABLE,         // value to write to port smi_cmd to disable ACPI
+  S4BIOS_REQ,           // Value to write to SMI CMD port to enter the S4BIOS state
+  RESERVED,             // reserved - must be zero
+  ACPI_RUNTIME_UPDATE,  // Port address of Power Mgt 1a Event Reg Blk
+  PM1b_EVT_BLK_ADDRESS, // Port address of Power Mgt 1b Event Reg Blk
+  ACPI_RUNTIME_UPDATE,  // Port address of Power Mgt 1a Ctrl Reg Blk
+  PM1b_CNT_BLK_ADDRESS, // Port address of Power Mgt 1b Ctrl Reg Blk
+  ACPI_RUNTIME_UPDATE,  // Port address of Power Mgt 2  Ctrl Reg Blk
+  ACPI_RUNTIME_UPDATE,  // Port address of Power Mgt Timer Ctrl Reg Blk
+  ACPI_RUNTIME_UPDATE,  // Port addr of General Purpose Event 0 Reg Blk
+  GPE1_BLK_ADDRESS,     // Port addr of General Purpose Event 1 Reg Blk
+  PM1_EVT_LEN,          // Byte Length of ports at pm1X_evt_blk
+  PM1_CNT_LEN,          // Byte Length of ports at pm1X_cnt_blk
+  PM2_CNT_LEN,          // Byte Length of ports at pm2_cnt_blk
+  PM_TM_LEN,            // Byte Length of ports at pm_tm_blk
+  GPE0_BLK_LEN,         // Byte Length of ports at gpe0_blk
+  GPE1_BLK_LEN,         // Byte Length of ports at gpe1_blk
+  GPE1_BASE,            // offset in gpe model where gpe1 events start
+  RESERVED,             // reserved
+  P_LVL2_LAT,           // worst case HW latency to enter/exit C2 state
+  P_LVL3_LAT,           // worst case HW latency to enter/exit C3 state
+  FLUSH_SIZE,           // Size of area read to flush caches
+  FLUSH_STRIDE,         // Stride used in flushing caches
+  DUTY_OFFSET,          // bit location of duty cycle field in p_cnt reg
+  DUTY_WIDTH,           // bit width of duty cycle field in p_cnt reg
+  DAY_ALRM,             // index to day-of-month alarm in RTC CMOS RAM
+  MON_ALRM,             // index to month-of-year alarm in RTC CMOS RAM
+  CENTURY,              // index to century in RTC CMOS RAM
+  IAPC_BOOT_ARCH,       // IA-PC Boot Architecture Flags
+  RESERVED,             // reserved
+  FLAG2,                // Fixed feature flags
+
+  {
+    RESET_REG_ADDRESS_SPACE_ID,  // Address of the reset register
+    RESET_REG_BIT_WIDTH,
+    RESET_REG_BIT_OFFSET,
+    RESERVED,
+    RESET_REG_ADDRESS
+  },
+  RESET_VALUE,          // Value to write to the RESET_REG port
+  {
+    RESERVED,
+    RESERVED,
+    RESERVED
+  },
+  0,                // 64Bit physical addesss of FACS
+  0,                // 64Bit physical address of DSDT
+
+  {
+    PM1a_EVT_BLK_ADDRESS_SPACE_ID, // Extended Port address of Power Mgt 1a Event Reg Blk
+    PM1a_EVT_BLK_BIT_WIDTH,
+    PM1a_EVT_BLK_BIT_OFFSET,
+    RESERVED,
+    ACPI_RUNTIME_UPDATE
+  },
+
+  {
+    PM1b_EVT_BLK_ADDRESS_SPACE_ID, // Extended Port address of Power Mgt 1b Event Reg Blk
+    PM1b_EVT_BLK_BIT_WIDTH,
+    PM1b_EVT_BLK_BIT_OFFSET,
+    RESERVED,
+    PM1b_EVT_BLK_ADDRESS
+  },
+
+  {
+    PM1a_CNT_BLK_ADDRESS_SPACE_ID, // Extended Port address of Power Mgt 1a Ctrl Reg Blk
+    PM1a_CNT_BLK_BIT_WIDTH,
+    PM1a_CNT_BLK_BIT_OFFSET,
+    RESERVED,
+    ACPI_RUNTIME_UPDATE
+  },
+
+  {
+    PM1b_CNT_BLK_ADDRESS_SPACE_ID, // Extended Port address of Power Mgt 1b Ctrl Reg Blk
+    PM1b_CNT_BLK_BIT_WIDTH,
+    PM1b_CNT_BLK_BIT_OFFSET,
+    RESERVED,
+    PM1b_CNT_BLK_ADDRESS
+  },
+
+  {
+    PM2_CNT_BLK_ADDRESS_SPACE_ID,  // Extended Port address of Power Mgt 2  Ctrl Reg Blk
+    PM2_CNT_BLK_BIT_WIDTH,
+    PM2_CNT_BLK_BIT_OFFSET,
+    RESERVED,
+    ACPI_RUNTIME_UPDATE
+  },
+
+  {
+    PM_TMR_BLK_ADDRESS_SPACE_ID,   // Extended Port address of Power Mgt Timer Ctrl Reg Blk
+    PM_TMR_BLK_BIT_WIDTH,
+    PM_TMR_BLK_BIT_OFFSET,
+    RESERVED,
+    ACPI_RUNTIME_UPDATE
+  },
+
+  {
+    GPE0_BLK_ADDRESS_SPACE_ID,   // Extended Port address of General Purpose Event 0 Reg Blk
+    GPE0_BLK_BIT_WIDTH,
+    GPE0_BLK_BIT_OFFSET,
+    RESERVED,
+    ACPI_RUNTIME_UPDATE
+  },
+
+  {
+    GPE1_BLK_ADDRESS_SPACE_ID,   // Extended Port address of General Purpose Event 1 Reg Blk
+    GPE1_BLK_BIT_WIDTH,
+    GPE1_BLK_BIT_OFFSET,
+    RESERVED,
+    GPE1_BLK_ADDRESS
+  }
+};
+
+VOID*
+ReferenceAcpiTable (
+  VOID
+  )
+
+{
+  //
+  // Reference the table being generated to prevent the optimizer from removing the
+  // data structure from the exeutable
+  //
+  return (VOID*)&FADT;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.aslc b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.aslc
new file mode 100644
index 0000000000..7834174d28
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.aslc
@@ -0,0 +1,68 @@
+/** @file
+This file contains a structure definition for the ACPI 1.0 High Precision Event Timer
+Description Table (HPET).  The contents of this file should only be modified
+for bug fixes, no porting is required.  The table layout is defined in
+HighPrecisionEventTimerTable.h and the table contents are defined in Acpi1.0.h and Hpet.h.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// Statements that include other files
+//
+
+#include "Hpet.h"
+
+//
+// High Precision Event Timer Table
+// Please modify all values in Hpet.h only.
+//
+
+EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER Hpet = {
+  {
+    EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE,
+    sizeof (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER),
+    EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_REVISION,
+
+    //
+    // Checksum will be updated at runtime
+    //
+    0x00,
+
+    //
+    // It is expected that these values will be updated at runtime
+    //
+    {' ', ' ', ' ', ' ', ' ', ' '},
+
+    0,
+    EFI_ACPI_OEM_HPET_REVISION,
+    0,
+    0
+  },
+  EFI_ACPI_EVENT_TIMER_BLOCK_ID,
+  {
+    EFI_ACPI_EVENT_TIMER_BLOCK_ADDRESS_SPACE_ID,
+    EFI_ACPI_EVENT_TIMER_BLOCK_BIT_WIDTH,
+    EFI_ACPI_EVENT_TIMER_BLOCK_BIT_OFFSET,
+    EFI_ACPI_EVENT_TIMER_ACCESS_SIZE,
+    ACPI_RUNTIME_UPDATE
+  },
+  EFI_ACPI_HPET_NUMBER,
+  EFI_ACPI_MIN_CLOCK_TICK,
+  EFI_ACPI_HPET_ATTRIBUTES
+};
+
+VOID*
+ReferenceAcpiTable (
+  VOID
+  )
+{
+  //
+  // Reference the table being generated to prevent the optimizer from removing the
+  // data structure from the exeutable
+  //
+  return (VOID*)&Hpet;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.h b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.h
new file mode 100644
index 0000000000..b1695436a3
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.h
@@ -0,0 +1,45 @@
+/** @file
+This file describes the contents of the ACPI High Precision Event Timer Description Table
+(HPET).  Some additional ACPI values are defined in Acpi10.h, Acpi20.h, and Acpi30.h
+All changes to the HPET contents should be done in this file.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _HPET_H_
+#define _HPET_H_
+
+//
+// Statements that include other files
+//
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/HighPrecisionEventTimerTable.h>
+
+//
+// HPET Definitions
+//
+
+#define EFI_ACPI_OEM_HPET_REVISION                      0x00000001
+
+#define EFI_ACPI_EVENT_TIMER_BLOCK_ID                   0x8086A201
+
+#define ACPI_RUNTIME_UPDATE                             0x00
+
+//
+// Event Timer Block Base Address Information
+//
+#define EFI_ACPI_EVENT_TIMER_BLOCK_ADDRESS_SPACE_ID     EFI_ACPI_3_0_SYSTEM_MEMORY
+#define EFI_ACPI_EVENT_TIMER_BLOCK_BIT_WIDTH            0x00
+#define EFI_ACPI_EVENT_TIMER_BLOCK_BIT_OFFSET           0x00
+#define EFI_ACPI_EVENT_TIMER_ACCESS_SIZE                0x00
+
+#define EFI_ACPI_HPET_NUMBER                            0x00
+
+#define EFI_ACPI_MIN_CLOCK_TICK                         0x0080
+
+#define EFI_ACPI_HPET_ATTRIBUTES                        0x00
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Mcfg/Mcfg.aslc b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Mcfg/Mcfg.aslc
new file mode 100644
index 0000000000..bef7b12cf9
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Mcfg/Mcfg.aslc
@@ -0,0 +1,75 @@
+/** @file
+This file contains a structure definition for the ACPI Memory Mapped Configuration
+Address Space table (MCFG).  Any changes to the number of entries in the table require
+updating the structure count in Mcfg.h and then adding the structure to the
+MCFG defined in this file.  The table layout is defined in Mcfg.h and the
+table contents are defined in the MemoryMappedConfigurationSpaceAccessTable.h.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// Statements that include other files
+//
+
+#include "Mcfg.h"
+
+//
+// Multiple APIC Description Table
+//
+
+EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_DESCRIPTION_TABLE Mcfg = {
+  {
+    EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
+    sizeof (EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_DESCRIPTION_TABLE),
+    EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION,
+
+    //
+    // Checksum will be updated at runtime
+    //
+    0x00,
+
+    //
+    // It is expected that these values will be programmed at runtime
+    //
+    {' ', ' ', ' ', ' ', ' ', ' '},
+
+    0,
+    EFI_ACPI_OEM_MCFG_REVISION,
+    0,
+    0
+  },
+  //
+  // Reserved
+  //
+  0x0000000000000000,
+
+  //
+  // MCFG specific fields
+  //
+
+  {
+    {
+      0x00000000,                                                   // BaseAddress (will be updated at runtime)
+      0x0000,                                                       // PciSegmentGroupNumber
+      0x00,                                                         // StartBusNumber
+      0x1F,                                                         // EndBusNumber
+      0x00000000                                                    // Reserved
+    }
+  }
+};
+
+VOID*
+ReferenceAcpiTable (
+  VOID
+  )
+{
+  //
+  // Reference the table being generated to prevent the optimizer from removing the
+  // data structure from the exeutable
+  //
+  return (VOID*)&Mcfg;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Mcfg/Mcfg.h b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Mcfg/Mcfg.h
new file mode 100644
index 0000000000..3703132a9a
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Mcfg/Mcfg.h
@@ -0,0 +1,56 @@
+/** @file
+This file describes the contents of the ACPI Memory Mapped Configuration
+Space Access Table (MCFG).  Some additional ACPI values are defined in Acpi10.h,
+Acpi20.h, and Acpi30.h.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _MCFG_H_
+#define _MCFG_H_
+
+//
+// Statements that include other files
+//
+
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
+
+//
+// MCFG Definitions
+//
+
+#define EFI_ACPI_OEM_MCFG_REVISION 0x00000001
+
+//
+// Define the number of allocation structures so that we can build the table structure.
+//
+
+#define EFI_ACPI_ALLOCATION_STRUCTURE_COUNT           1
+
+//
+// MCFG structure
+//
+
+//
+// Ensure proper structure formats
+//
+#pragma pack (1)
+
+//
+// MCFG Table structure
+//
+typedef struct {
+  EFI_ACPI_DESCRIPTION_HEADER                                                            Header;
+  UINT64                                                                                 Reserved;
+#if EFI_ACPI_ALLOCATION_STRUCTURE_COUNT > 0
+  EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE  AllocationStructure[EFI_ACPI_ALLOCATION_STRUCTURE_COUNT];
+#endif
+} EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_DESCRIPTION_TABLE;
+
+#pragma pack ()
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.c b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.c
new file mode 100644
index 0000000000..02738621e5
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.c
@@ -0,0 +1,1402 @@
+/** @file
+Update the _PRT and _PRW method for pci devices
+
+Copyright (c) 2013-2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+#include "AcpiPlatform.h"
+
+PCI_DEVICE_INFO *mQNCPciInfo = NULL;
+
+/**
+  Init Pci Device Structure
+  @param mConfigData    - Pointer of Pci Device information Structure
+
+**/
+VOID
+InitPciDeviceInfoStructure (
+  PCI_DEVICE_SETTING            *mConfigData
+  )
+{
+  //
+  // Return 0 given that function unsupported.
+  // Would need to parse ACPI tables and build mQNCPciInfo above
+  // with found _PRT & _PRW methods for PCI devices.
+  //
+  mConfigData->PciDeviceInfoNumber = 0;
+}
+
+/**
+  return Integer value.
+
+  @param Data    - AML data buffer
+  @param Integer - integer value.
+
+  @return Data size processed.
+**/
+UINTN
+SdtGetInteger (
+  IN  UINT8  *Data,
+  OUT UINT64 *Integer
+  )
+{
+  *Integer = 0;
+  switch (*Data) {
+  case AML_ZERO_OP:
+    return 1;
+  case AML_ONE_OP:
+    *Integer = 1;
+    return 1;
+  case AML_ONES_OP:
+    *Integer = (UINTN)-1;
+    return 1;
+  case AML_BYTE_PREFIX:
+    CopyMem (Integer, Data + 1, sizeof(UINT8));
+    return 1 + sizeof(UINT8);
+  case AML_WORD_PREFIX:
+    CopyMem (Integer, Data + 1, sizeof(UINT16));
+    return 1 + sizeof(UINT16);
+  case AML_DWORD_PREFIX:
+    CopyMem (Integer, Data + 1, sizeof(UINT32));
+    return 1 + sizeof(UINT32);
+  case AML_QWORD_PREFIX:
+    CopyMem (Integer, Data + 1, sizeof(UINT64));
+    return 1 + sizeof(UINT64);
+  default:
+    // Something wrong
+    ASSERT (FALSE);
+    return 1;
+  }
+}
+
+
+/**
+  Check if this handle has expected opcode.
+
+  @param AcpiSdt    Pointer to Acpi SDT protocol
+  @param Handle     ACPI handle
+  @param OpCode     Expected OpCode
+  @param SubOpCode  Expected SubOpCode
+
+  @retval TRUE  This handle has expected opcode
+  @retval FALSE This handle does not have expected opcode
+**/
+BOOLEAN
+SdtIsThisTypeObject (
+  IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt,
+  IN EFI_ACPI_HANDLE Handle,
+  IN UINT8           OpCode,
+  IN UINT8           SubOpCode
+  )
+{
+  EFI_STATUS         Status;
+  EFI_ACPI_DATA_TYPE DataType;
+  UINT8              *Data;
+  UINTN              DataSize;
+
+  Status = AcpiSdt->GetOption (Handle, 0, &DataType, (CONST VOID **)&Data, &DataSize);
+  ASSERT_EFI_ERROR (Status);
+  ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);
+
+  if (OpCode == AML_EXT_OP) {
+    if (Data[1] == SubOpCode) {
+      return TRUE;
+    }
+  } else {
+    if (Data[0] == OpCode) {
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+/**
+  Check if this handle has expected name and name value.
+
+  @param AcpiSdt    Pointer to Acpi SDT protocol
+  @param Handle     ACPI handle
+  @param Name       Expected name
+  @param Value      Expected name value
+
+  @retval TRUE  This handle has expected name and name value.
+  @retval FALSE This handle does not have expected name and name value.
+**/
+BOOLEAN
+SdtIsNameIntegerValueEqual (
+  IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt,
+  IN EFI_ACPI_HANDLE Handle,
+  IN CHAR8           *Name,
+  IN UINT64          Value
+  )
+{
+  EFI_STATUS         Status;
+  EFI_ACPI_DATA_TYPE DataType;
+  UINT8              *Data;
+  UINTN              DataSize;
+  UINT64             Integer;
+
+  Status = AcpiSdt->GetOption (Handle, 1, &DataType, (CONST VOID **)&Data, &DataSize);
+  ASSERT_EFI_ERROR (Status);
+  ASSERT (DataType == EFI_ACPI_DATA_TYPE_NAME_STRING);
+
+  if (CompareMem (Data, Name, 4) != 0) {
+    return FALSE;
+  }
+
+  //
+  // Name match check object
+  //
+  Status = AcpiSdt->GetOption (Handle, 2, &DataType, (CONST VOID **)&Data, &DataSize);
+  ASSERT_EFI_ERROR (Status);
+
+  Integer = 0;
+  SdtGetInteger (Data, &Integer);
+  if (Integer != Value) {
+    return FALSE;
+  }
+
+  // All match
+  return TRUE;
+}
+
+/**
+  Check if this handle's children has expected name and name value.
+
+  @param AcpiSdt          Pointer to Acpi SDT protocol
+  @param ParentHandle     ACPI parent handle
+  @param Name             Expected name
+  @param Value            Expected name value
+
+  @retval TRUE  This handle's children has expected name and name value.
+  @retval FALSE This handle's children does not have expected name and name value.
+**/
+BOOLEAN
+SdtCheckNameIntegerValue (
+  IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt,
+  IN EFI_ACPI_HANDLE ParentHandle,
+  IN CHAR8           *Name,
+  IN UINT64          Value
+  )
+{
+  EFI_ACPI_HANDLE PreviousHandle;
+  EFI_ACPI_HANDLE Handle;
+  EFI_STATUS      Status;
+
+  Handle = NULL;
+  while (TRUE) {
+    PreviousHandle = Handle;
+    Status = AcpiSdt->GetChild (ParentHandle, &Handle);
+    ASSERT_EFI_ERROR (Status);
+
+    if (PreviousHandle != NULL) {
+      Status = AcpiSdt->Close (PreviousHandle);
+      ASSERT_EFI_ERROR (Status);
+    }
+
+    //
+    // Done
+    //
+    if (Handle == NULL) {
+      return FALSE;
+    }
+
+    //
+    // Check this name
+    //
+    if (SdtIsThisTypeObject (AcpiSdt, Handle, AML_NAME_OP, 0)) {
+      if (SdtIsNameIntegerValueEqual (AcpiSdt, Handle, Name, Value)) {
+        return TRUE;
+      }
+    }
+  }
+
+  //
+  // Should not run here
+  //
+}
+
+/**
+  Convert the pci address from VPD (bus,dev,fun) into the address that acpi table
+  can recognize.
+
+  @param PciAddress    Pci address from VPD
+
+  @retval return the address that acpi table can recognize
+**/
+UINT32
+SdtConvertToAcpiPciAdress (
+  IN UINT32 PciAddress
+  )
+{
+  UINT32 ReturnAddress;
+
+  ReturnAddress = ((PciAddress & 0x0000FF00) << 8) | (PciAddress & 0x000000FF);
+
+  if ((PciAddress & 0x000000FF) == 0x000000FF)
+    ReturnAddress |= 0x0000FFFF;
+
+  return ReturnAddress;
+}
+
+/**
+  return AML NameString size.
+
+  @param Buffer - AML name string
+
+  @return AML name string size
+**/
+UINTN
+SdtGetNameStringSize (
+  IN UINT8              *Buffer
+  )
+{
+  UINTN                 SegCount;
+  UINTN                 Length;
+
+  Length = 0;
+
+  //
+  // Parse root or prefix
+  //
+  if (*Buffer == AML_ROOT_CHAR) {
+    //
+    // RootChar
+    //
+    Buffer ++;
+    Length ++;
+  } else if (*Buffer == AML_PARENT_PREFIX_CHAR) {
+    //
+    // ParentPrefixChar
+    //
+    Buffer ++;
+    Length ++;
+    while (*Buffer == AML_PARENT_PREFIX_CHAR) {
+      Buffer ++;
+      Length ++;
+    }
+  }
+
+  //
+  // Parse name segment
+  //
+  if (*Buffer == AML_DUAL_NAME_PREFIX) {
+    //
+    // DualName
+    //
+    Buffer ++;
+    Length ++;
+    SegCount = 2;
+  } else if (*Buffer == AML_MULTI_NAME_PREFIX) {
+    //
+    // MultiName
+    //
+    Buffer ++;
+    Length ++;
+    SegCount = *Buffer;
+    Buffer ++;
+    Length ++;
+  } else if (*Buffer == 0) {
+    //
+    // NULL Name
+    //
+    SegCount = 0;
+    Length ++;
+  } else {
+    //
+    // NameSeg
+    //
+    SegCount = 1;
+  }
+
+  Buffer += 4 * SegCount;
+  Length += 4 * SegCount;
+
+  return Length;
+}
+
+/**
+  The routine to check if this device is PCI root bridge.
+
+  @param AcpiSdt       Pointer to Acpi SDT protocol
+  @param DeviceHandle  ACPI device handle
+  @param Context       Context info - not used here
+
+  @retval TRUE  This is PCI root bridge
+  @retval FALSE This is not PCI root bridge
+**/
+BOOLEAN
+SdtFindRootBridgeHandle (
+  IN EFI_ACPI_SDT_PROTOCOL  *AcpiSdt,
+  IN EFI_ACPI_HANDLE        CheckHandle,
+  IN VOID                   *Context
+  )
+{
+  BOOLEAN            Result;
+  EFI_ACPI_DATA_TYPE DataType;
+  UINT8              *Data;
+  UINTN              DataSize;
+  EFI_STATUS         Status;
+
+  if (!SdtIsThisTypeObject (AcpiSdt, CheckHandle, AML_EXT_OP, AML_EXT_DEVICE_OP))
+    return FALSE;
+
+  Result = SdtCheckNameIntegerValue (AcpiSdt,CheckHandle, "_HID", (UINT64)0x080AD041); // PNP0A08
+  if (!Result) {
+    Result = SdtCheckNameIntegerValue (AcpiSdt, CheckHandle, "_CID", (UINT64)0x030AD041); // PNP0A03
+    if (!Result) {
+      return Result;
+    }
+  }
+
+  //
+  // Found
+  //
+  Status = AcpiSdt->GetOption (CheckHandle, 1, &DataType, (CONST VOID **)&Data, &DataSize);
+  ASSERT_EFI_ERROR (Status);
+  ASSERT (DataType == EFI_ACPI_DATA_TYPE_NAME_STRING);
+
+  return Result;
+}
+
+
+/**
+  The routine to check if this device is wanted.
+
+  @param AcpiSdt       Pointer to Acpi SDT protocol
+  @param DeviceHandle  ACPI device handle
+  @param Context       Context info - not used here
+
+  @retval TRUE  This is PCI device wanted
+  @retval FALSE This is not PCI device wanted
+**/
+BOOLEAN
+SdtFindPciDeviceHandle (
+  IN EFI_ACPI_SDT_PROTOCOL  *AcpiSdt,
+  IN EFI_ACPI_HANDLE        CheckHandle,
+  IN VOID                   *Context
+  )
+{
+  BOOLEAN            Result;
+  EFI_ACPI_DATA_TYPE DataType;
+  UINT8              *Data;
+  UINTN              DataSize;
+  EFI_STATUS         Status;
+
+  if (!SdtIsThisTypeObject (AcpiSdt, CheckHandle, AML_EXT_OP, AML_EXT_DEVICE_OP))
+    return FALSE;
+
+  Result = SdtCheckNameIntegerValue (AcpiSdt,CheckHandle, "_ADR", (UINT64)*(UINT32 *)Context);
+  if (!Result) {
+    return Result;
+  }
+
+  //
+  // Found
+  //
+  Status = AcpiSdt->GetOption (CheckHandle, 1, &DataType, (CONST VOID **)&Data, &DataSize);
+  ASSERT_EFI_ERROR (Status);
+  ASSERT (DataType == EFI_ACPI_DATA_TYPE_NAME_STRING);
+
+  return Result;
+}
+
+/**
+  Go through the parent handle and find the handle which pass CheckHandleInfo.
+
+  @param AcpiSdt          Pointer to Acpi SDT protocol
+  @param ParentHandle     ACPI parent handle
+  @param CheckHandleInfo  The callback routine to check if this handle meet the requirement
+  @param Context          The context of CheckHandleInfo
+
+  @return the handle which is first one can pass CheckHandleInfo.
+**/
+EFI_ACPI_HANDLE
+SdtGetHandleByScanAllChilds (
+  IN EFI_ACPI_SDT_PROTOCOL  *AcpiSdt,
+  IN EFI_ACPI_HANDLE        ParentHandle,
+  IN CHECK_HANDLE_INFO      CheckHandleInfo,
+  IN VOID                   *Context
+  )
+{
+  EFI_ACPI_HANDLE    PreviousHandle;
+  EFI_ACPI_HANDLE    Handle;
+  EFI_STATUS         Status;
+  EFI_ACPI_HANDLE    ReturnHandle;
+
+  //
+  // Use deep first algo to enumerate all ACPI object
+  //
+  Handle = NULL;
+  while (TRUE) {
+    PreviousHandle = Handle;
+    Status = AcpiSdt->GetChild (ParentHandle, &Handle);
+    ASSERT_EFI_ERROR (Status);
+
+    if (PreviousHandle != NULL) {
+      Status = AcpiSdt->Close (PreviousHandle);
+      ASSERT_EFI_ERROR (Status);
+    }
+
+    //
+    // Done
+    //
+    if (Handle == NULL) {
+      return NULL;
+    }
+
+    //
+    // Check this handle
+    //
+    if (CheckHandleInfo (AcpiSdt, Handle, Context)) {
+      return Handle;
+    }
+
+    //
+    // Enumerate
+    //
+    ReturnHandle = SdtGetHandleByScanAllChilds (AcpiSdt, Handle, CheckHandleInfo, Context);
+    if (ReturnHandle != NULL) {
+      return ReturnHandle;
+    }
+  }
+
+  //
+  // Should not run here
+  //
+}
+
+
+/**
+  Check whether the INTx package is matched
+
+  @param AcpiSdt          Pointer to Acpi SDT protocol
+  @param INTxPkgHandle    ACPI INTx package handle
+  @param PciAddress       Acpi pci address
+  @param INTx             Index of INTx pin
+  @param IsAPIC           Tell whether the returned INTx package is for APIC or not
+
+  @retval       TRUE      the INTx package is matched
+  @retval       FALSE     the INTx package is not matched
+
+**/
+BOOLEAN
+SdtCheckINTxPkgIsMatch (
+  IN EFI_ACPI_SDT_PROTOCOL  *AcpiSdt,
+  IN EFI_ACPI_HANDLE        INTxPkgHandle,
+  IN UINT32                 PciAddress,
+  IN UINT8                  INTx,
+  IN BOOLEAN                *IsAPIC
+  )
+{
+  EFI_ACPI_HANDLE    PreviousHandle;
+  EFI_STATUS         Status;
+  EFI_ACPI_HANDLE    MemberHandle;
+  EFI_ACPI_DATA_TYPE DataType;
+  UINT8              *Data;
+  UINTN              DataSize;
+  UINT64             CurrentPciAddress;
+  UINT64             CurrentINTx;
+  UINTN              ChildSize;
+
+
+  //
+  // Check the pci address
+  //
+  MemberHandle = NULL;
+  Status = AcpiSdt->GetChild (INTxPkgHandle, &MemberHandle);
+  ASSERT_EFI_ERROR (Status);
+  ASSERT (MemberHandle != NULL);
+
+  Status = AcpiSdt->GetOption (MemberHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize);
+  ASSERT_EFI_ERROR (Status);
+  ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);
+
+  CurrentPciAddress = 0;
+  SdtGetInteger (Data, &CurrentPciAddress);
+
+  if (CurrentPciAddress != PciAddress) {
+
+    Status = AcpiSdt->Close (MemberHandle);
+    ASSERT_EFI_ERROR (Status);
+    return FALSE;
+  }
+
+  //
+  // Check the pci interrupt pin
+  //
+  PreviousHandle = MemberHandle;
+  Status = AcpiSdt->GetChild (INTxPkgHandle, &MemberHandle);
+  ASSERT_EFI_ERROR (Status);
+  ASSERT (MemberHandle != NULL);
+
+  if (PreviousHandle != NULL) {
+    Status = AcpiSdt->Close (PreviousHandle);
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  Status = AcpiSdt->GetOption (MemberHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize);
+  ASSERT_EFI_ERROR (Status);
+  ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);
+
+  CurrentINTx = 0;
+  ChildSize = SdtGetInteger (Data, &CurrentINTx);
+
+  Status = AcpiSdt->Close (MemberHandle);
+  ASSERT_EFI_ERROR (Status);
+
+  if (CurrentINTx != INTx)
+    return FALSE;
+
+  Data += ChildSize;
+
+  if (*Data == AML_BYTE_PREFIX)
+    Data += 1;
+
+  //
+  // Check the pci interrupt source
+  //
+  if (*Data  != 0)
+    *IsAPIC = FALSE;
+  else
+    *IsAPIC = TRUE;
+
+  return TRUE;
+}
+
+
+
+
+/**
+  Get the wanted INTx package inside the parent package
+
+  @param AcpiSdt          Pointer to Acpi SDT protocol
+  @param ParentPkgHandle  ACPI parent package handle
+  @param PciAddress       Acpi pci address
+  @param INTx             Index of INTx pin
+  @param INTxPkgHandle    ACPI INTx package handle
+  @param IsAPIC           Tell whether the returned INTx package is for APIC or not
+
+**/
+VOID
+SdtGetINTxPkgHandle (
+  IN EFI_ACPI_SDT_PROTOCOL  *AcpiSdt,
+  IN EFI_ACPI_HANDLE        ParentPkgHandle,
+  IN UINT32                 PciAddress,
+  IN UINT8                  INTx,
+  IN EFI_ACPI_HANDLE        *INTxPkgHandle,
+  IN BOOLEAN                *IsAPIC
+  )
+{
+  EFI_ACPI_HANDLE    PreviousHandle;
+  EFI_STATUS         Status;
+  EFI_ACPI_HANDLE    ChildPkgHandle;
+
+  ChildPkgHandle = NULL;
+  while (TRUE) {
+    PreviousHandle = ChildPkgHandle;
+    Status = AcpiSdt->GetChild (ParentPkgHandle, &ChildPkgHandle);
+    ASSERT_EFI_ERROR (Status);
+
+    if (PreviousHandle != NULL) {
+      Status = AcpiSdt->Close (PreviousHandle);
+      ASSERT_EFI_ERROR (Status);
+    }
+
+    if (ChildPkgHandle == NULL) {
+      break;
+    }
+
+    if (SdtCheckINTxPkgIsMatch(AcpiSdt, ChildPkgHandle, PciAddress, INTx, IsAPIC)) {
+      *INTxPkgHandle = ChildPkgHandle;
+      return;
+    }
+  }
+
+  return;
+}
+
+/**
+  Update the INTx package with the correct pirq value
+
+  @param AcpiSdt          Pointer to Acpi SDT protocol
+  @param INTxPkgHandle    ACPI INTx package handle
+  @param PirqValue        Correct pirq value
+  @param IsAPIC           Tell whether the INTx package is for APIC or not
+
+**/
+VOID
+SdtUpdateINTxPkg (
+  IN EFI_ACPI_SDT_PROTOCOL  *AcpiSdt,
+  IN EFI_ACPI_HANDLE        INTxPkgHandle,
+  IN UINT8                  PirqValue,
+  IN BOOLEAN                IsAPIC
+  )
+{
+  EFI_ACPI_HANDLE    PreviousHandle;
+  EFI_STATUS         Status;
+  EFI_ACPI_HANDLE    MemberHandle;
+  EFI_ACPI_DATA_TYPE DataType;
+  UINT8              *Data;
+  UINTN              DataSize;
+  UINT64             TempValue;
+  UINTN              ChildSize;
+
+
+  //
+  // Check the pci address
+  //
+  MemberHandle = NULL;
+  Status = AcpiSdt->GetChild (INTxPkgHandle, &MemberHandle);
+  ASSERT_EFI_ERROR (Status);
+  ASSERT (MemberHandle != NULL);
+
+  //
+  // Check the pci interrupt pin
+  //
+  PreviousHandle = MemberHandle;
+  Status = AcpiSdt->GetChild (INTxPkgHandle, &MemberHandle);
+  ASSERT_EFI_ERROR (Status);
+  ASSERT (MemberHandle != NULL);
+
+  if (PreviousHandle != NULL) {
+    Status = AcpiSdt->Close (PreviousHandle);
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  Status = AcpiSdt->GetOption (MemberHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize);
+  ASSERT_EFI_ERROR (Status);
+  ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);
+
+  ChildSize = SdtGetInteger (Data, &TempValue);
+
+  Status = AcpiSdt->Close (MemberHandle);
+  ASSERT_EFI_ERROR (Status);
+
+  Data += ChildSize;
+
+  //
+  // update the pci interrupt source or source index
+  //
+  if (!IsAPIC) {
+    ChildSize = SdtGetNameStringSize (Data);
+    Data += (ChildSize - 1);
+
+    PirqValue += 0x40;   // change to ascii char
+    if (*Data != PirqValue)
+      *Data = PirqValue;
+  } else {
+
+    ChildSize = SdtGetInteger (Data, &TempValue);
+    Data += ChildSize;
+
+    Data += 1;
+
+    if (*Data != PirqValue)
+      *Data = PirqValue;
+  }
+}
+
+/**
+  Check every child package inside this interested parent package for update PRT
+
+  @param AcpiSdt          Pointer to Acpi SDT protocol
+  @param ParentPkgHandle  ACPI parent package handle
+  @param PciDeviceInfo    Pointer to PCI_DEVICE_INFO
+
+**/
+VOID
+SdtCheckParentPackage (
+  IN EFI_ACPI_SDT_PROTOCOL  *AcpiSdt,
+  IN EFI_ACPI_HANDLE        ParentPkgHandle,
+  IN PCI_DEVICE_INFO        *PciDeviceInfo
+  )
+{
+  EFI_ACPI_HANDLE    INTAPkgHandle;
+  EFI_ACPI_HANDLE    INTBPkgHandle;
+  EFI_ACPI_HANDLE    INTCPkgHandle;
+  EFI_ACPI_HANDLE    INTDPkgHandle;
+  UINT32             PciAddress = 0;
+  BOOLEAN            IsAllFunctions = FALSE;
+  UINT8              IsAPIC = 0;
+  EFI_STATUS         Status;
+
+  INTAPkgHandle = INTBPkgHandle = INTCPkgHandle = INTDPkgHandle = NULL;
+
+  PciAddress   = SdtConvertToAcpiPciAdress(PciDeviceInfo->DeviceAddress);
+
+  if ((PciAddress & 0xFFFF) == 0xFFFF) {
+    IsAllFunctions = TRUE;
+  } else {
+    IsAllFunctions = FALSE;
+    PciAddress = (PciAddress | 0xFFFF);
+  }
+
+  SdtGetINTxPkgHandle (AcpiSdt, ParentPkgHandle, PciAddress, 0, &INTAPkgHandle, (BOOLEAN *)&IsAPIC);
+  SdtGetINTxPkgHandle (AcpiSdt, ParentPkgHandle, PciAddress, 1, &INTBPkgHandle, (BOOLEAN *)&IsAPIC);
+  SdtGetINTxPkgHandle (AcpiSdt, ParentPkgHandle, PciAddress, 2, &INTCPkgHandle, (BOOLEAN *)&IsAPIC);
+  SdtGetINTxPkgHandle (AcpiSdt, ParentPkgHandle, PciAddress, 3, &INTDPkgHandle, (BOOLEAN *)&IsAPIC);
+
+  //
+  // Check INTA
+  //
+  if ((PciDeviceInfo->INTA[IsAPIC] != 0xFF) && (INTAPkgHandle != NULL)) {
+    //
+    // Find INTA package and there is valid INTA update item, update it
+    //
+    SdtUpdateINTxPkg (AcpiSdt, INTAPkgHandle, (PciDeviceInfo->INTA[IsAPIC]), IsAPIC);
+  } else if ((PciDeviceInfo->INTA[IsAPIC] != 0xFF) && (INTAPkgHandle == NULL)) {
+    //
+    // There is valid INTA update item, but no INA package exist, should add it
+    //
+    DEBUG ((EFI_D_ERROR, "\n\nShould add INTA item for this device(0x%x)\n\n", PciAddress));
+
+  } else if ((PciDeviceInfo->INTA[IsAPIC] == 0xFF) && (INTAPkgHandle != NULL) && IsAllFunctions) {
+    //
+    // For all functions senario, if there is invalid INTA update item, but INTA package does exist, should delete it
+    //
+    DEBUG ((EFI_D_ERROR, "\n\nShould remove INTA item for this device(0x%x)\n\n", PciAddress));
+
+  }
+
+  //
+  // Check INTB
+  //
+  if ((PciDeviceInfo->INTB[IsAPIC] != 0xFF) && (INTBPkgHandle != NULL)) {
+    //
+    // Find INTB package and there is valid INTB update item, update it
+    //
+    SdtUpdateINTxPkg (AcpiSdt, INTBPkgHandle, (PciDeviceInfo->INTB[IsAPIC]), IsAPIC);
+  } else if ((PciDeviceInfo->INTB[IsAPIC] != 0xFF) && (INTBPkgHandle == NULL)) {
+    //
+    // There is valid INTB update item, but no INTB package exist, should add it
+    //
+    DEBUG ((EFI_D_ERROR, "\n\nShould add INTB item for this device(0x%x)\n\n", PciAddress));
+
+  } else if ((PciDeviceInfo->INTB[IsAPIC] == 0xFF) && (INTBPkgHandle != NULL) && IsAllFunctions) {
+    //
+    // For all functions senario, if there is invalid INTB update item, but INTB package does exist, should delete it
+    //
+    DEBUG ((EFI_D_ERROR, "\n\nShould remove INTB item for this device(0x%x)\n\n", PciAddress));
+
+  }
+
+  //
+  // Check INTC
+  //
+  if ((PciDeviceInfo->INTC[IsAPIC] != 0xFF) && (INTCPkgHandle != NULL)) {
+    //
+    // Find INTC package and there is valid INTC update item, update it
+    //
+    SdtUpdateINTxPkg (AcpiSdt, INTCPkgHandle, (PciDeviceInfo->INTC[IsAPIC]), IsAPIC);
+  } else if ((PciDeviceInfo->INTC[IsAPIC] != 0xFF) && (INTCPkgHandle == NULL)) {
+    //
+    // There is valid INTC update item, but no INTC package exist, should add it
+    //
+    DEBUG ((EFI_D_ERROR, "\n\nShould add INTC item for this device(0x%x)\n\n", PciAddress));
+
+  } else if ((PciDeviceInfo->INTC[IsAPIC] == 0xFF) && (INTCPkgHandle != NULL) && IsAllFunctions) {
+    //
+    // For all functions senario, if there is invalid INTC update item, but INTC package does exist, should delete it
+    //
+    DEBUG ((EFI_D_ERROR, "\n\nShould remove INTC item for this device(0x%x)\n\n", PciAddress));
+  }
+
+  //
+  // Check INTD
+  //
+  if ((PciDeviceInfo->INTD[IsAPIC] != 0xFF) && (INTDPkgHandle != NULL)) {
+    //
+    // Find INTD package and there is valid INTD update item, update it
+    //
+    SdtUpdateINTxPkg (AcpiSdt, INTDPkgHandle, (PciDeviceInfo->INTD[IsAPIC]), IsAPIC);
+  } else if ((PciDeviceInfo->INTD[IsAPIC] != 0xFF) && (INTDPkgHandle == NULL)) {
+    //
+    // There is valid INTD update item, but no INTD package exist, should add it
+    //
+    DEBUG ((EFI_D_ERROR, "\n\nShould add INTD item for this device(0x%x)\n\n", PciAddress));
+
+  }  else if ((PciDeviceInfo->INTD[IsAPIC] == 0xFF) && (INTDPkgHandle != NULL) && IsAllFunctions) {
+    //
+    // For all functions senario, if there is invalid INTD update item, but INTD package does exist, should delete it
+    //
+    DEBUG ((EFI_D_ERROR, "\n\nShould remove INTD item for this device(0x%x)\n\n", PciAddress));
+  }
+
+
+  if (INTAPkgHandle != NULL) {
+    Status = AcpiSdt->Close (INTAPkgHandle);
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  if (INTBPkgHandle != NULL) {
+    Status = AcpiSdt->Close (INTBPkgHandle);
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  if (INTCPkgHandle != NULL) {
+    Status = AcpiSdt->Close (INTCPkgHandle);
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  if (INTDPkgHandle != NULL) {
+    Status = AcpiSdt->Close (INTDPkgHandle);
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  return;
+}
+
+/**
+  Check every return package for update PRT
+
+  @param AcpiSdt          Pointer to Acpi SDT protocol
+  @param ParentHandle     ACPI pci device handle
+  @param PciDeviceInfo    Pointer to PCI_DEVICE_INFO
+
+**/
+VOID
+SdtCheckReturnPackage (
+  IN EFI_ACPI_SDT_PROTOCOL  *AcpiSdt,
+  IN EFI_ACPI_HANDLE        MethodHandle,
+  IN PCI_DEVICE_INFO        *PciDeviceInfo
+  )
+{
+  EFI_ACPI_HANDLE    PreviousHandle;
+  EFI_ACPI_HANDLE    ReturnHandle;
+  EFI_ACPI_HANDLE    PackageHandle;
+  EFI_ACPI_HANDLE    NamePkgHandle;
+  EFI_STATUS         Status;
+  EFI_ACPI_DATA_TYPE DataType;
+  UINT8              *Data;
+  UINTN              DataSize;
+  CHAR8              NameStr[128];
+
+  ReturnHandle = NULL;
+  while (TRUE) {
+    PreviousHandle = ReturnHandle;
+    Status = AcpiSdt->GetChild (MethodHandle, &ReturnHandle);
+    ASSERT_EFI_ERROR (Status);
+
+    if (PreviousHandle != NULL) {
+      Status = AcpiSdt->Close (PreviousHandle);
+      ASSERT_EFI_ERROR (Status);
+    }
+
+    if (ReturnHandle == NULL) {
+      break;
+    }
+
+    Status = AcpiSdt->GetOption (ReturnHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize);
+    ASSERT_EFI_ERROR (Status);
+    ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);
+
+    if (*Data == AML_RETURN_OP) {
+      //
+      // Find the return method handle, then look for the returned package data
+      //
+      Status = AcpiSdt->GetOption (ReturnHandle, 1, &DataType, (CONST VOID **)&Data, &DataSize);
+      ASSERT_EFI_ERROR (Status);
+
+
+      if (DataType == EFI_ACPI_DATA_TYPE_NAME_STRING) {
+        ZeroMem (NameStr, 128);
+        AsciiStrCpy (NameStr, "\\_SB.");
+        DataSize = SdtGetNameStringSize (Data);
+        AsciiStrnCat (NameStr, (CHAR8 *)Data, DataSize);
+
+        NamePkgHandle = NULL;
+        Status = AcpiSdt->FindPath (mDsdtHandle, NameStr, &NamePkgHandle);
+        ASSERT_EFI_ERROR (Status);
+        ASSERT (NamePkgHandle != NULL);
+
+        Status = AcpiSdt->GetOption (NamePkgHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize);
+        ASSERT_EFI_ERROR (Status);
+        ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);
+        ASSERT (*Data == AML_NAME_OP);
+
+        Status = AcpiSdt->GetOption (NamePkgHandle, 2, &DataType, (CONST VOID **)&Data, &DataSize);
+        ASSERT_EFI_ERROR (Status);
+        ASSERT (DataType == EFI_ACPI_DATA_TYPE_CHILD);
+      }
+
+      ASSERT (DataType == EFI_ACPI_DATA_TYPE_CHILD);
+
+      //
+      // Get the parent package handle
+      //
+      PackageHandle = NULL;
+      Status = AcpiSdt->Open (Data, &PackageHandle);
+      ASSERT_EFI_ERROR (Status);
+
+      //
+      // Check the parent package for update pci routing
+      //
+      SdtCheckParentPackage (AcpiSdt, PackageHandle, PciDeviceInfo);
+
+      Status = AcpiSdt->Close (PackageHandle);
+      ASSERT_EFI_ERROR (Status);
+
+      Status = AcpiSdt->Close (ReturnHandle);
+      ASSERT_EFI_ERROR (Status);
+
+      break;
+    }
+
+    //
+    // Not ReturnOp, search it as parent
+    //
+    SdtCheckReturnPackage (AcpiSdt, ReturnHandle, PciDeviceInfo);
+  }
+
+  //
+  // Done
+  //
+  return;
+
+}
+
+/**
+  update interrupt info inside the PRT method for the given pci device handle
+
+  @param AcpiSdt       Pointer to Acpi SDT protocol
+  @param PciHandle     ACPI pci device handle
+  @param PciDeviceInfo Pointer to PCI_DEVICE_INFO
+
+**/
+EFI_STATUS
+SdtUpdatePrtMethod (
+  IN EFI_ACPI_SDT_PROTOCOL  *AcpiSdt,
+  IN EFI_ACPI_HANDLE        PciHandle,
+  IN PCI_DEVICE_INFO        *PciDeviceInfo
+  )
+{
+  EFI_STATUS         Status;
+  EFI_ACPI_HANDLE    PrtMethodHandle;
+
+  //
+  // Find the PRT method under this pci device
+  //
+  PrtMethodHandle = NULL;
+  Status = AcpiSdt->FindPath (PciHandle, "_PRT", &PrtMethodHandle);
+
+  if (EFI_ERROR (Status)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (PrtMethodHandle == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  SdtCheckReturnPackage(AcpiSdt, PrtMethodHandle, PciDeviceInfo);
+
+  Status = AcpiSdt->Close (PrtMethodHandle);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+
+/**
+  Update the package inside name op with correct wakeup resources
+
+  @param AcpiSdt          Pointer to Acpi SDT protocol
+  @param InPkgHandle      ACPI inside package handle
+  @param GPEPin           Correct gpe pin
+  @param SxNum            Correct system state the device can wake up from
+
+**/
+VOID
+SdtUpdatePackageInName (
+  IN EFI_ACPI_SDT_PROTOCOL  *AcpiSdt,
+  IN EFI_ACPI_HANDLE        INTxPkgHandle,
+  IN UINT8                  GPEPin,
+  IN UINT8                  SxNum
+  )
+{
+  EFI_ACPI_HANDLE    PreviousHandle;
+  EFI_STATUS         Status;
+  EFI_ACPI_HANDLE    MemberHandle;
+  EFI_ACPI_DATA_TYPE DataType;
+  UINT8              *Data;
+  UINTN              DataSize;
+
+  //
+  // Check the gpe pin
+  //
+  MemberHandle = NULL;
+  Status = AcpiSdt->GetChild (INTxPkgHandle, &MemberHandle);
+  ASSERT_EFI_ERROR (Status);
+  ASSERT (MemberHandle != NULL);
+
+  Status = AcpiSdt->GetOption (MemberHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize);
+  ASSERT_EFI_ERROR (Status);
+  ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);
+
+  //
+  // Skip byte prefix
+  //
+  Data += 1;
+
+  if (*Data != GPEPin) {
+
+    *Data = GPEPin;
+  }
+
+  //
+  // Check the sx number
+  //
+  PreviousHandle = MemberHandle;
+  Status = AcpiSdt->GetChild (INTxPkgHandle, &MemberHandle);
+  ASSERT_EFI_ERROR (Status);
+  ASSERT (MemberHandle != NULL);
+
+  if (PreviousHandle != NULL) {
+    Status = AcpiSdt->Close (PreviousHandle);
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  Status = AcpiSdt->GetOption (MemberHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize);
+  ASSERT_EFI_ERROR (Status);
+  ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);
+
+  //
+  // Skip byte prefix
+  //
+  Data += 1;
+
+  if (*Data != SxNum) {
+
+    *Data = SxNum;
+  }
+
+  Status = AcpiSdt->Close (MemberHandle);
+  ASSERT_EFI_ERROR (Status);
+
+}
+
+/**
+  Check the name package belonged to PRW
+
+  @param AcpiSdt          Pointer to Acpi SDT protocol
+  @param PrwPkgHandle     ACPI PRW package handle
+  @param PciDeviceInfo    Pointer to PCI_DEVICE_INFO
+
+**/
+VOID
+SdtCheckNamePackage (
+  IN EFI_ACPI_SDT_PROTOCOL  *AcpiSdt,
+  IN EFI_ACPI_HANDLE        PrwPkgHandle,
+  IN PCI_DEVICE_INFO        *PciDeviceInfo
+  )
+{
+  EFI_ACPI_HANDLE    InPkgHandle;
+  EFI_STATUS         Status;
+  EFI_ACPI_DATA_TYPE DataType;
+  UINT8              *Data;
+  UINTN              DataSize;
+
+  Status = AcpiSdt->GetOption (PrwPkgHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize);
+  ASSERT_EFI_ERROR (Status);
+  ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);
+  ASSERT (*Data == AML_NAME_OP);
+
+  Status = AcpiSdt->GetOption (PrwPkgHandle, 2, &DataType, (CONST VOID **)&Data, &DataSize);
+  ASSERT_EFI_ERROR (Status);
+  ASSERT (DataType == EFI_ACPI_DATA_TYPE_CHILD);
+
+  //
+  // Get the inside package handle
+  //
+  InPkgHandle = NULL;
+  Status = AcpiSdt->Open (Data, &InPkgHandle);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // update the package in name op for wakeup info
+  //
+  if ((PciDeviceInfo->GPEPin != 0xFF) && (PciDeviceInfo->SxNum != 0xFF))
+    SdtUpdatePackageInName (AcpiSdt, InPkgHandle, PciDeviceInfo->GPEPin, PciDeviceInfo->SxNum);
+
+  Status = AcpiSdt->Close (InPkgHandle);
+  ASSERT_EFI_ERROR (Status);
+
+  return;
+
+}
+
+/**
+  update wakeup info inside the PRW method for the given pci device handle
+
+  @param AcpiSdt       Pointer to Acpi SDT protocol
+  @param PciHandle     ACPI pci device handle
+  @param PciDeviceInfo Pointer to PCI_DEVICE_INFO
+
+**/
+EFI_STATUS
+SdtUpdatePrwPackage (
+  IN EFI_ACPI_SDT_PROTOCOL  *AcpiSdt,
+  IN EFI_ACPI_HANDLE        PciHandle,
+  IN PCI_DEVICE_INFO        *PciDeviceInfo
+  )
+{
+  EFI_STATUS         Status;
+  EFI_ACPI_HANDLE    PrwPkgHandle;
+
+  //
+  // Find the PRT method under this pci device
+  //
+  PrwPkgHandle = NULL;
+  Status = AcpiSdt->FindPath (PciHandle, "_PRW", &PrwPkgHandle);
+
+  if (EFI_ERROR (Status)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (PrwPkgHandle == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  SdtCheckNamePackage(AcpiSdt, PrwPkgHandle, PciDeviceInfo);
+
+  Status = AcpiSdt->Close (PrwPkgHandle);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+/**
+  update pci routing information in acpi table based on pcd settings
+
+  @param AcpiSdt          Pointer to Acpi SDT protocol
+  @param PciRootHandle       ACPI root bridge handle
+  @param PciDeviceInfo    Pointer to PCI_DEVICE_INFO
+
+**/
+EFI_STATUS
+SdtUpdatePciRouting (
+  IN EFI_ACPI_SDT_PROTOCOL  *AcpiSdt,
+  IN EFI_ACPI_HANDLE        PciRootHandle,
+  IN PCI_DEVICE_INFO        *PciDeviceInfo
+  )
+{
+  EFI_STATUS         Status;
+  EFI_ACPI_HANDLE    PciBridgeHandle;
+  UINT32             PciAddress;
+
+
+  PciBridgeHandle = NULL;
+  if (PciDeviceInfo->BridgeAddress == 0x00000000) {
+    //
+    // Its bridge is the host root bridge
+    //
+    PciBridgeHandle = PciRootHandle;
+
+  } else {
+
+    //
+    // Its bridge is just a pci device under the host bridge
+    //
+
+    //
+    // Conver the bridge address into one that acpi table can recognize
+    //
+    PciAddress = SdtConvertToAcpiPciAdress (PciDeviceInfo->BridgeAddress);
+
+    //
+    // Scan the whole table to find the pci device
+    //
+    PciBridgeHandle = SdtGetHandleByScanAllChilds(AcpiSdt, PciRootHandle, SdtFindPciDeviceHandle, &PciAddress);
+    if (PciBridgeHandle == NULL) {
+
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  Status = SdtUpdatePrtMethod(AcpiSdt, PciBridgeHandle, PciDeviceInfo);
+
+  if (PciDeviceInfo->BridgeAddress != 0x00000000) {
+    Status = AcpiSdt->Close (PciBridgeHandle);
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  return Status;
+}
+
+
+/**
+  update power resource wake up information in acpi table based on pcd settings
+
+  @param AcpiSdt          Pointer to Acpi SDT protocol
+  @param PciRootHandle    ACPI root bridge handle
+  @param PciDeviceInfo    Pointer to PCI_DEVICE_INFO
+
+**/
+EFI_STATUS
+SdtUpdatePowerWake (
+  IN EFI_ACPI_SDT_PROTOCOL  *AcpiSdt,
+  IN EFI_ACPI_HANDLE        PciRootHandle,
+  IN PCI_DEVICE_INFO        *PciDeviceInfo
+  )
+{
+  EFI_STATUS         Status;
+  EFI_ACPI_HANDLE    PciBridgeHandle;
+  EFI_ACPI_HANDLE    PciDeviceHandle;
+  UINT32             PciAddress;
+
+  PciBridgeHandle = NULL;
+  if (PciDeviceInfo->BridgeAddress == 0x00000000) {
+    //
+    // Its bridge is the host root bridge
+    //
+    PciBridgeHandle = PciRootHandle;
+
+  } else {
+
+    //
+    // Its bridge is just a pci device under the host bridge
+    //
+
+    //
+    // Conver the bridge address into one that acpi table can recognize
+    //
+    PciAddress = SdtConvertToAcpiPciAdress (PciDeviceInfo->BridgeAddress);
+
+    //
+    // Scan the whole table to find the pci device
+    //
+    PciBridgeHandle = SdtGetHandleByScanAllChilds(AcpiSdt, PciRootHandle, SdtFindPciDeviceHandle, &PciAddress);
+
+    if (PciBridgeHandle == NULL) {
+
+      Status = AcpiSdt->Close (PciRootHandle);
+      ASSERT_EFI_ERROR (Status);
+
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  PciDeviceHandle = NULL;
+
+  //
+  // Conver the device address into one that acpi table can recognize
+  //
+  PciAddress = SdtConvertToAcpiPciAdress (PciDeviceInfo->DeviceAddress);
+
+  //
+  // Scan the whole table to find the pci device
+  //
+  PciDeviceHandle = SdtGetHandleByScanAllChilds(AcpiSdt, PciBridgeHandle, SdtFindPciDeviceHandle, &PciAddress);
+
+  if (PciDeviceHandle == NULL) {
+    if (PciDeviceInfo->BridgeAddress != 0x00000000) {
+      Status = AcpiSdt->Close (PciBridgeHandle);
+      ASSERT_EFI_ERROR (Status);
+    }
+
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = SdtUpdatePrwPackage(AcpiSdt, PciDeviceHandle, PciDeviceInfo);
+
+  Status = AcpiSdt->Close (PciDeviceHandle);
+  ASSERT_EFI_ERROR (Status);
+
+  if (PciDeviceInfo->BridgeAddress != 0x00000000) {
+    Status = AcpiSdt->Close (PciBridgeHandle);
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  return Status;
+}
+
+
+/**
+  Get the root bridge handle by scanning the acpi table
+
+  @param AcpiSdt          Pointer to Acpi SDT protocol
+  @param DsdtHandle       ACPI root handle
+
+  @retval EFI_ACPI_HANDLE the handle of the root bridge
+**/
+EFI_ACPI_HANDLE
+SdtGetRootBridgeHandle (
+  IN EFI_ACPI_SDT_PROTOCOL  *AcpiSdt,
+  IN EFI_ACPI_HANDLE        DsdtHandle
+  )
+{
+  EFI_ACPI_HANDLE    PciRootHandle;
+
+  //
+  // Scan the whole table to find the root bridge
+  //
+  PciRootHandle = NULL;
+  PciRootHandle = SdtGetHandleByScanAllChilds(AcpiSdt, DsdtHandle, SdtFindRootBridgeHandle, NULL);
+  ASSERT (PciRootHandle != NULL);
+
+  return PciRootHandle;
+}
+
+
+/**
+  Check input Pci device info is changed from the default values
+  @param PciDeviceInfo    Pointer to PCI_DEVICE_INFO
+  @param UpdatePRT        Pointer to BOOLEAN
+  @param UpdatePRW        Pointer to BOOLEAN
+
+**/
+VOID
+SdtCheckPciDeviceInfoChanged (
+  IN PCI_DEVICE_INFO        *PciDeviceInfo,
+  IN BOOLEAN                *UpdatePRT,
+  IN BOOLEAN                *UpdatePRW
+  )
+{
+  UINTN Index = 0;
+
+  if (mQNCPciInfo == NULL) {
+    *UpdatePRT = FALSE;
+    *UpdatePRW = FALSE;
+    return;
+  }
+
+  *UpdatePRT = TRUE;
+  *UpdatePRW = TRUE;
+
+  for (Index = 0;Index < CURRENT_PCI_DEVICE_NUM; Index++) {
+    if ((mQNCPciInfo[Index].BridgeAddress == PciDeviceInfo->BridgeAddress)
+      && (mQNCPciInfo[Index].DeviceAddress == PciDeviceInfo->DeviceAddress)) {
+      //
+      // Find one matched entry
+      //
+      if (CompareMem (&(mQNCPciInfo[Index].INTA[0]), &PciDeviceInfo->INTA[0], 10) == 0) {
+        *UpdatePRT = FALSE;
+        *UpdatePRW = FALSE;
+        //DEBUG ((EFI_D_ERROR, "Find one matched entry[%d] and no change\n", Index));
+      } else {
+        if (CompareMem (&(mQNCPciInfo[Index].INTA[0]), &PciDeviceInfo->INTA[0], 8) == 0)
+          *UpdatePRT = FALSE;
+
+        if (CompareMem (&(mQNCPciInfo[Index].GPEPin), &PciDeviceInfo->GPEPin, 2) == 0)
+          *UpdatePRW = FALSE;
+
+        if (*(UINT64 *)(&PciDeviceInfo->INTA[0]) == 0xFFFFFFFFFFFFFFFFULL)
+          *UpdatePRT = FALSE;
+
+        if (*(UINT16 *)(&PciDeviceInfo->GPEPin) == 0xFFFF)
+          *UpdatePRW = FALSE;
+
+        //DEBUG ((EFI_D_ERROR, "Find one matched entry[%d] and but need update PRT:0x%x PRW:0x%x\n", Index, *UpdatePRT, *UpdatePRW));
+      }
+      break;
+    }
+  }
+
+  //if (Index == 42) {
+  //  DEBUG ((EFI_D_ERROR, "Find No matched entry\n"));
+  //}
+
+  return;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.h b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.h
new file mode 100644
index 0000000000..7d16dc47b9
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.h
@@ -0,0 +1,316 @@
+/** @file
+Update the _PRT and _PRW method for pci devices
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+#ifndef _ACPI_PCI_UPDATE_H_
+#define _ACPI_PCI_UPDATE_H_
+
+
+//
+// Primary OpCode
+//
+#define AML_ZERO_OP                  0x00
+#define AML_ONE_OP                   0x01
+#define AML_ALIAS_OP                 0x06
+#define AML_NAME_OP                  0x08
+#define AML_BYTE_PREFIX              0x0a
+#define AML_WORD_PREFIX              0x0b
+#define AML_DWORD_PREFIX             0x0c
+#define AML_STRING_PREFIX            0x0d
+#define AML_QWORD_PREFIX             0x0e
+#define AML_SCOPE_OP                 0x10
+#define AML_BUFFER_OP                0x11
+#define AML_PACKAGE_OP               0x12
+#define AML_VAR_PACKAGE_OP           0x13
+#define AML_METHOD_OP                0x14
+#define AML_DUAL_NAME_PREFIX         0x2e
+#define AML_MULTI_NAME_PREFIX        0x2f
+#define AML_NAME_CHAR_A              0x41
+#define AML_NAME_CHAR_B              0x42
+#define AML_NAME_CHAR_C              0x43
+#define AML_NAME_CHAR_D              0x44
+#define AML_NAME_CHAR_E              0x45
+#define AML_NAME_CHAR_F              0x46
+#define AML_NAME_CHAR_G              0x47
+#define AML_NAME_CHAR_H              0x48
+#define AML_NAME_CHAR_I              0x49
+#define AML_NAME_CHAR_J              0x4a
+#define AML_NAME_CHAR_K              0x4b
+#define AML_NAME_CHAR_L              0x4c
+#define AML_NAME_CHAR_M              0x4d
+#define AML_NAME_CHAR_N              0x4e
+#define AML_NAME_CHAR_O              0x4f
+#define AML_NAME_CHAR_P              0x50
+#define AML_NAME_CHAR_Q              0x51
+#define AML_NAME_CHAR_R              0x52
+#define AML_NAME_CHAR_S              0x53
+#define AML_NAME_CHAR_T              0x54
+#define AML_NAME_CHAR_U              0x55
+#define AML_NAME_CHAR_V              0x56
+#define AML_NAME_CHAR_W              0x57
+#define AML_NAME_CHAR_X              0x58
+#define AML_NAME_CHAR_Y              0x59
+#define AML_NAME_CHAR_Z              0x5a
+#define AML_ROOT_CHAR                0x5c
+#define AML_PARENT_PREFIX_CHAR       0x5e
+#define AML_NAME_CHAR__              0x5f
+#define AML_LOCAL0                   0x60
+#define AML_LOCAL1                   0x61
+#define AML_LOCAL2                   0x62
+#define AML_LOCAL3                   0x63
+#define AML_LOCAL4                   0x64
+#define AML_LOCAL5                   0x65
+#define AML_LOCAL6                   0x66
+#define AML_LOCAL7                   0x67
+#define AML_ARG0                     0x68
+#define AML_ARG1                     0x69
+#define AML_ARG2                     0x6a
+#define AML_ARG3                     0x6b
+#define AML_ARG4                     0x6c
+#define AML_ARG5                     0x6d
+#define AML_ARG6                     0x6e
+#define AML_STORE_OP                 0x70
+#define AML_REF_OF_OP                0x71
+#define AML_ADD_OP                   0x72
+#define AML_CONCAT_OP                0x73
+#define AML_SUBTRACT_OP              0x74
+#define AML_INCREMENT_OP             0x75
+#define AML_DECREMENT_OP             0x76
+#define AML_MULTIPLY_OP              0x77
+#define AML_DIVIDE_OP                0x78
+#define AML_SHIFT_LEFT_OP            0x79
+#define AML_SHIFT_RIGHT_OP           0x7a
+#define AML_AND_OP                   0x7b
+#define AML_NAND_OP                  0x7c
+#define AML_OR_OP                    0x7d
+#define AML_NOR_OP                   0x7e
+#define AML_XOR_OP                   0x7f
+#define AML_NOT_OP                   0x80
+#define AML_FIND_SET_LEFT_BIT_OP     0x81
+#define AML_FIND_SET_RIGHT_BIT_OP    0x82
+#define AML_DEREF_OF_OP              0x83
+#define AML_CONCAT_RES_OP            0x84
+#define AML_MOD_OP                   0x85
+#define AML_NOTIFY_OP                0x86
+#define AML_SIZE_OF_OP               0x87
+#define AML_INDEX_OP                 0x88
+#define AML_MATCH_OP                 0x89
+#define AML_CREATE_DWORD_FIELD_OP    0x8a
+#define AML_CREATE_WORD_FIELD_OP     0x8b
+#define AML_CREATE_BYTE_FIELD_OP     0x8c
+#define AML_CREATE_BIT_FIELD_OP      0x8d
+#define AML_OBJECT_TYPE_OP           0x8e
+#define AML_CREATE_QWORD_FIELD_OP    0x8f
+#define AML_LAND_OP                  0x90
+#define AML_LOR_OP                   0x91
+#define AML_LNOT_OP                  0x92
+#define AML_LEQUAL_OP                0x93
+#define AML_LGREATER_OP              0x94
+#define AML_LLESS_OP                 0x95
+#define AML_TO_BUFFER_OP             0x96
+#define AML_TO_DEC_STRING_OP         0x97
+#define AML_TO_HEX_STRING_OP         0x98
+#define AML_TO_INTEGER_OP            0x99
+#define AML_TO_STRING_OP             0x9c
+#define AML_COPY_OBJECT_OP           0x9d
+#define AML_MID_OP                   0x9e
+#define AML_CONTINUE_OP              0x9f
+#define AML_IF_OP                    0xa0
+#define AML_ELSE_OP                  0xa1
+#define AML_WHILE_OP                 0xa2
+#define AML_NOOP_OP                  0xa3
+#define AML_RETURN_OP                0xa4
+#define AML_BREAK_OP                 0xa5
+#define AML_BREAK_POINT_OP           0xcc
+#define AML_ONES_OP                  0xff
+
+//
+// Extended OpCode
+//
+#define AML_EXT_OP                   0x5b
+
+#define AML_EXT_MUTEX_OP             0x01
+#define AML_EXT_EVENT_OP             0x02
+#define AML_EXT_COND_REF_OF_OP       0x12
+#define AML_EXT_CREATE_FIELD_OP      0x13
+#define AML_EXT_LOAD_TABLE_OP        0x1f
+#define AML_EXT_LOAD_OP              0x20
+#define AML_EXT_STALL_OP             0x21
+#define AML_EXT_SLEEP_OP             0x22
+#define AML_EXT_ACQUIRE_OP           0x23
+#define AML_EXT_SIGNAL_OP            0x24
+#define AML_EXT_WAIT_OP              0x25
+#define AML_EXT_RESET_OP             0x26
+#define AML_EXT_RELEASE_OP           0x27
+#define AML_EXT_FROM_BCD_OP          0x28
+#define AML_EXT_TO_BCD_OP            0x29
+#define AML_EXT_UNLOAD_OP            0x2a
+#define AML_EXT_REVISION_OP          0x30
+#define AML_EXT_DEBUG_OP             0x31
+#define AML_EXT_FATAL_OP             0x32
+#define AML_EXT_TIMER_OP             0x33
+#define AML_EXT_REGION_OP            0x80
+#define AML_EXT_FIELD_OP             0x81
+#define AML_EXT_DEVICE_OP            0x82
+#define AML_EXT_PROCESSOR_OP         0x83
+#define AML_EXT_POWER_RES_OP         0x84
+#define AML_EXT_THERMAL_ZONE_OP      0x85
+#define AML_EXT_INDEX_FIELD_OP       0x86
+#define AML_EXT_BANK_FIELD_OP        0x87
+#define AML_EXT_DATA_REGION_OP       0x88
+
+#pragma pack(1)
+
+typedef struct {
+  UINT32    BridgeAddress;
+  UINT32    DeviceAddress;
+  UINT8     INTA[2];    // the first member record the 8259 link, the second member record the io apic irq number
+  UINT8     INTB[2];
+  UINT8     INTC[2];
+  UINT8     INTD[2];
+
+  UINT8     GPEPin;
+  UINT8     SxNum;
+} PCI_DEVICE_INFO;
+
+#pragma pack()
+
+#define PCI_DEVICE_INFO_MAX_NUM  50
+#define CURRENT_PCI_DEVICE_NUM   13
+
+#define  PIRQ_LINKA       1
+#define  PIRQ_LINKB       2
+#define  PIRQ_LINKC       3
+#define  PIRQ_LINKD       4
+#define  PIRQ_LINKE       5
+#define  PIRQ_LINKF       6
+#define  PIRQ_LINKG       7
+#define  PIRQ_LINKH       8
+#define  PIRQ_INVALID  0xFF
+
+typedef struct _PCI_DEVICE_SETTING{
+  UINT8    PciDeviceInfoNumber;
+  PCI_DEVICE_INFO PciDeviceInfo[PCI_DEVICE_INFO_MAX_NUM];
+}PCI_DEVICE_SETTING;
+
+typedef struct _AML_BYTE_ENCODING AML_BYTE_ENCODING;
+
+//
+// AML Handle Entry definition.
+//
+//  Signature must be set to EFI_AML_HANDLE_SIGNATURE or EFI_AML_ROOT_HANDLE_SIGNATURE
+//  Buffer is the ACPI node buffer pointer, the first/second bytes are opcode.
+//         This buffer should not be freed.
+//  Size is the total size of this ACPI node buffer.
+//
+typedef struct {
+  UINT32                  Signature;
+  UINT8                   *Buffer;
+  UINTN                   Size;
+  AML_BYTE_ENCODING       *AmlByteEncoding;
+  BOOLEAN                 Modified;
+} EFI_AML_HANDLE;
+
+typedef UINT32 AML_OP_PARSE_INDEX;
+
+typedef UINT32 AML_OP_PARSE_FORMAT;
+
+typedef UINT32 AML_OP_ATTRIBUTE;
+
+struct _AML_BYTE_ENCODING {
+  UINT8                      OpCode;
+  UINT8                      SubOpCode;
+  AML_OP_PARSE_INDEX         MaxIndex;
+  AML_OP_PARSE_FORMAT        Format[6];
+  AML_OP_ATTRIBUTE           Attribute;
+};
+
+
+//
+// Check device info fucntion prototype
+//
+typedef
+BOOLEAN
+(* CHECK_HANDLE_INFO) (
+  IN EFI_ACPI_SDT_PROTOCOL  *AcpiSdt,
+  IN EFI_ACPI_HANDLE        CheckHandle,
+  IN VOID                   *Context
+  );
+
+extern EFI_ACPI_HANDLE mDsdtHandle;
+extern EFI_ACPI_SDT_PROTOCOL *mAcpiSdt;
+
+/**
+  Init Pci Device Structure
+
+  @param mConfigData    - Pointer of Pci Device information Structure
+
+**/
+VOID
+InitPciDeviceInfoStructure (
+  PCI_DEVICE_SETTING            *mConfigData
+  );
+/**
+  update pci routing information in acpi table based on pcd settings
+
+  @param AcpiSdt          Pointer to Acpi SDT protocol
+  @param DsdtHandle       ACPI root handle
+  @param PciDeviceInfo    Pointer to PCI_DEVICE_INFO
+
+**/
+EFI_STATUS
+SdtUpdatePciRouting (
+  IN EFI_ACPI_SDT_PROTOCOL  *AcpiSdt,
+  IN EFI_ACPI_HANDLE        DsdtHandle,
+  IN PCI_DEVICE_INFO        *PciDeviceInfo
+  );
+
+
+/**
+  update power resource wake up information in acpi table based on pcd settings
+
+  @param AcpiSdt          Pointer to Acpi SDT protocol
+  @param DsdtHandle       ACPI root handle
+  @param PciDeviceInfo    Pointer to PCI_DEVICE_INFO
+
+**/
+EFI_STATUS
+SdtUpdatePowerWake (
+  IN EFI_ACPI_SDT_PROTOCOL  *AcpiSdt,
+  IN EFI_ACPI_HANDLE        DsdtHandle,
+  IN PCI_DEVICE_INFO        *PciDeviceInfo
+  );
+
+/**
+  Get the root bridge handle by scanning the acpi table
+
+  @param AcpiSdt          Pointer to Acpi SDT protocol
+  @param DsdtHandle       ACPI root handle
+
+  @retval EFI_ACPI_HANDLE the handle of the root bridge
+**/
+EFI_ACPI_HANDLE
+SdtGetRootBridgeHandle (
+  IN EFI_ACPI_SDT_PROTOCOL  *AcpiSdt,
+  IN EFI_ACPI_HANDLE        DsdtHandle
+  );
+
+/**
+  Check input Pci device info is changed from the default values
+  @param PciDeviceInfo    Pointer to PCI_DEVICE_INFO
+  @param UpdatePRT        Pointer to BOOLEAN
+  @param UpdatePRW        Pointer to BOOLEAN
+
+**/
+VOID
+SdtCheckPciDeviceInfoChanged (
+  IN PCI_DEVICE_INFO        *PciDeviceInfo,
+  IN BOOLEAN                *UpdatePRT,
+  IN BOOLEAN                *UpdatePRW
+  );
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.c b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.c
new file mode 100644
index 0000000000..bb7cc92212
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.c
@@ -0,0 +1,805 @@
+/** @file
+ACPI Platform Driver
+
+Copyright (c) 2013-2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Protocol/AcpiTable.h>
+#include <IndustryStandard/Pci22.h>
+#include "AcpiPlatform.h"
+
+//
+// Global Variable
+//
+EFI_GLOBAL_NVS_AREA_PROTOCOL  mGlobalNvsArea;
+EFI_ACPI_SDT_PROTOCOL         *mAcpiSdt;
+
+EFI_ACPI_HANDLE mDsdtHandle = NULL;
+
+
+EFI_STATUS
+LocateSupportProtocol (
+  IN  EFI_GUID                       *Protocol,
+  OUT VOID                           **Instance,
+  IN  UINT32                         Type
+  )
+/*++
+
+Routine Description:
+
+  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.
+
+Arguments:
+
+  Protocol      The protocol to find.
+  Instance      Return pointer to the first instance of the protocol
+
+Returns:
+
+  EFI_SUCCESS           The function completed successfully.
+  EFI_NOT_FOUND         The protocol could not be located.
+  EFI_OUT_OF_RESOURCES  There are not enough resources to find the protocol.
+
+--*/
+{
+  EFI_STATUS              Status;
+  EFI_HANDLE              *HandleBuffer;
+  UINTN                   NumberOfHandles;
+  EFI_FV_FILETYPE         FileType;
+  UINT32                  FvStatus;
+  EFI_FV_FILE_ATTRIBUTES  Attributes;
+  UINTN                   Size;
+  UINTN                   i;
+
+  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 (i = 0; i < NumberOfHandles; i++) {
+    //
+    // Get the protocol on this handle
+    // This should not fail because of LocateHandleBuffer
+    //
+    Status = gBS->HandleProtocol (
+                     HandleBuffer[i],
+                     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_VOLUME2_PROTOCOL*) (*Instance))->ReadFile (*Instance,
+                                                              (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),
+                                                              NULL,
+                                                              &Size,
+                                                              &FileType,
+                                                              &Attributes,
+                                                              &FvStatus
+                                                              );
+
+    //
+    // If we found it, then we are done
+    //
+    if (Status == EFI_SUCCESS) {
+      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;
+}
+
+
+VOID
+DsdtTableUpdate (
+  IN OUT   EFI_ACPI_DESCRIPTION_HEADER  *TableHeader,
+  IN OUT   EFI_ACPI_TABLE_VERSION       *Version
+  )
+/*++
+
+  Routine Description:
+
+    Update the DSDT table
+
+  Arguments:
+
+    Table   - The table to be set
+    Version - Version to publish
+
+  Returns:
+
+    None
+
+--*/
+{
+
+  UINT8      *CurrPtr;
+  UINT8      *DsdtPointer;
+  UINT32     *Signature;
+  UINT8      *Operation;
+  UINT32     *Address;
+  UINT16     *Size;
+  //
+  // 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) {
+    //
+    // MNVS operation region
+    //
+    case (SIGNATURE_32 ('M', '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;
+
+    //
+    // Update processor PBLK register I/O base address
+    //
+    case (SIGNATURE_32 ('P', 'R', 'I', 'O')):
+      //
+      // Conditional match. Update the following ASL code:
+      // Processor (CPU0, 0x01, 0x4F495250, 0x06) {}
+      // The 3rd parameter will be updated to the actual PBLK I/O base address.
+      // the Operator.
+      //
+      Operation = DsdtPointer - 8;
+      if ((*Operation == AML_EXT_OP) && (*(Operation + 1) == AML_EXT_PROCESSOR_OP)) {
+        *(UINT32 *)DsdtPointer = PcdGet16(PcdPmbaIoBaseAddress);
+      }
+      break;
+    default:
+      break;
+    }
+  }
+}
+
+
+VOID
+ApicTableUpdate (
+  IN OUT   EFI_ACPI_DESCRIPTION_HEADER  *TableHeader,
+  IN OUT   EFI_ACPI_TABLE_VERSION       *Version
+  )
+/*++
+
+  Routine Description:
+
+    Update the processors information in the APIC table
+
+  Arguments:
+
+    Table   - The table to be set
+    Version - Version to publish
+
+  Returns:
+
+    None
+
+--*/
+{
+  EFI_STATUS                 Status;
+  EFI_MP_SERVICES_PROTOCOL   *MpService;
+  UINT8                      *CurrPtr;
+  UINT8                      *EndPtr;
+  UINT8                      CurrIoApic;
+  UINT8                      CurrProcessor;
+  UINTN                      NumberOfCPUs;
+  UINTN                      NumberOfEnabledCPUs;
+  EFI_PROCESSOR_INFORMATION  MpContext;
+  ACPI_APIC_STRUCTURE_PTR    *ApicPtr;
+
+  CurrIoApic    = 0;
+  CurrProcessor = 0;
+  //
+  // 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)) {
+    //
+    // Failed to get MP information, doesn't publish the invalid table
+    //
+    *Version = EFI_ACPI_TABLE_VERSION_NONE;
+    return;
+  }
+
+  //
+  // Determine the number of processors
+  //
+  MpService->GetNumberOfProcessors (
+              MpService,
+              &NumberOfCPUs,
+              &NumberOfEnabledCPUs
+              );
+
+  CurrPtr = (UINT8*) &(TableHeader[1]);
+  CurrPtr = CurrPtr + 8; // Size of Local APIC Address & Flag
+  EndPtr  = (UINT8*) TableHeader;
+  EndPtr  = EndPtr + TableHeader->Length;
+
+  while (CurrPtr < EndPtr) {
+
+    ApicPtr = (ACPI_APIC_STRUCTURE_PTR*) CurrPtr;
+    switch (ApicPtr->AcpiApicCommon.Type) {
+
+      case EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC:
+        ApicPtr->AcpiLocalApic.Flags = 0;
+        ApicPtr->AcpiLocalApic.ApicId = 0;
+        Status = MpService->GetProcessorInfo (
+                              MpService,
+                              CurrProcessor,
+                              &MpContext
+                              );
+
+        if (!EFI_ERROR (Status)) {
+          if (MpContext.StatusFlag & PROCESSOR_ENABLED_BIT) {
+            ApicPtr->AcpiLocalApic.Flags = EFI_ACPI_3_0_LOCAL_APIC_ENABLED;
+          }
+          ApicPtr->AcpiLocalApic.ApicId = (UINT8)MpContext.ProcessorId;
+        }
+        CurrProcessor++;
+        break;
+
+      case EFI_ACPI_1_0_IO_APIC:
+        //
+        // IO APIC entries can be patched here
+        //
+        if (CurrIoApic == 0) {
+          //
+          // Update SOC internel IOAPIC base
+          //
+          ApicPtr->AcpiIoApic.IoApicId      =  PcdGet8 (PcdIoApicSettingIoApicId);
+          ApicPtr->AcpiIoApic.IoApicAddress =  (UINT32)PcdGet64(PcdIoApicBaseAddress);
+          ApicPtr->AcpiIoApic.GlobalSystemInterruptBase = 0;
+        } else {
+          //
+          // Porting is required to update other IOAPIC entries if available
+          //
+          ASSERT (0);
+        }
+        CurrIoApic++;
+        break;
+
+      default:
+        break;
+      };
+    CurrPtr = CurrPtr + ApicPtr->AcpiApicCommon.Length;
+  }
+}
+
+VOID
+AcpiUpdateTable (
+  IN OUT   EFI_ACPI_DESCRIPTION_HEADER  *TableHeader,
+  IN OUT   EFI_ACPI_TABLE_VERSION       *Version
+  )
+/*++
+
+  Routine Description:
+
+    Set the correct table revision upon the setup value
+
+  Arguments:
+
+    Table   - The table to be set
+    Version - Version to publish
+
+  Returns:
+
+    None
+
+--*/
+
+{
+  EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader1;
+  EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader2;
+  EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader3;
+  EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE *AllocationStructurePtr;
+
+  if (TableHeader != NULL && Version != NULL) {
+
+    *Version = EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0;
+    //
+    // Here we use all 3.0 signature because all version use same signature if they supported
+    //
+    switch (TableHeader->Signature) {
+    //
+    // "APIC" Multiple APIC Description Table
+    //
+    case EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
+      ApicTableUpdate (TableHeader, Version);
+      break;
+    //
+    // "DSDT" Differentiated System Description Table
+    //
+    case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
+      DsdtTableUpdate (TableHeader, Version);
+      break;
+
+    //
+    // "FACP" Fixed ACPI Description Table (FADT)
+    //
+    case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
+      *Version = EFI_ACPI_TABLE_VERSION_NONE;
+      if (TableHeader->Revision == EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {
+        *Version = EFI_ACPI_TABLE_VERSION_1_0B;
+        FadtHeader1 = (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *) TableHeader;
+        FadtHeader1->SmiCmd     = PcdGet16(PcdSmmActivationPort);
+        FadtHeader1->Pm1aEvtBlk = PcdGet16(PcdPm1blkIoBaseAddress);
+        FadtHeader1->Pm1aCntBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C;
+        FadtHeader1->PmTmrBlk   = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1T;
+        FadtHeader1->Gpe0Blk    = PcdGet16(PcdGpe0blkIoBaseAddress);
+      } else if (TableHeader->Revision == EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {
+        *Version = EFI_ACPI_TABLE_VERSION_2_0;
+        FadtHeader2 = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *) TableHeader;
+        FadtHeader2->SmiCmd     = PcdGet16(PcdSmmActivationPort);
+        FadtHeader2->Pm1aEvtBlk = PcdGet16(PcdPm1blkIoBaseAddress);
+        FadtHeader2->Pm1aCntBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C;
+        FadtHeader2->PmTmrBlk   = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1T;
+        FadtHeader2->Gpe0Blk    = PcdGet16(PcdGpe0blkIoBaseAddress);
+        FadtHeader2->XPm1aEvtBlk.Address = FadtHeader2->Pm1aEvtBlk;
+        FadtHeader2->XPm1aCntBlk.Address = FadtHeader2->Pm1aCntBlk;
+        FadtHeader2->XPmTmrBlk.Address   = FadtHeader2->PmTmrBlk;
+        FadtHeader2->XGpe0Blk.Address    = FadtHeader2->Gpe0Blk;
+      } else if (TableHeader->Revision == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {
+        *Version = EFI_ACPI_TABLE_VERSION_3_0;
+        FadtHeader3 = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) TableHeader;
+        FadtHeader3->SmiCmd     = PcdGet16(PcdSmmActivationPort);
+        FadtHeader3->Pm1aEvtBlk = PcdGet16(PcdPm1blkIoBaseAddress);
+        FadtHeader3->Pm1aCntBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C;
+        FadtHeader3->PmTmrBlk   = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1T;
+        FadtHeader3->Gpe0Blk    = PcdGet16(PcdGpe0blkIoBaseAddress);
+        FadtHeader3->XPm1aEvtBlk.Address = FadtHeader3->Pm1aEvtBlk;
+        FadtHeader3->XPm1aCntBlk.Address = FadtHeader3->Pm1aCntBlk;
+        FadtHeader3->XPmTmrBlk.Address   = FadtHeader3->PmTmrBlk;
+        FadtHeader3->XGpe0Blk.Address    = FadtHeader3->Gpe0Blk;
+      }
+      break;
+    //
+    // "FACS" Firmware ACPI Control Structure
+    //
+    case EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE:
+      break;
+    //
+    // "SSDT" Secondary System Description Table
+    //
+    case EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
+    break;
+    //
+    // "HPET" IA-PC High Precision Event Timer Table
+    //
+    case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE:
+      //
+      // If HPET is disabled in setup, don't publish the table.
+      //
+      if (mGlobalNvsArea.Area->HpetEnable == 0) {
+        *Version = EFI_ACPI_TABLE_VERSION_NONE;
+      }
+      ((EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *) TableHeader)->BaseAddressLower32Bit.Address
+        = PcdGet64 (PcdHpetBaseAddress);
+      break;
+    //
+    // "SPCR" Serial Port Concole Redirection Table
+    //
+    case EFI_ACPI_3_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE:
+      break;
+    //
+    // "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table
+    //
+    case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE:
+      AllocationStructurePtr = (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE *)
+        ((UINT8 *)TableHeader + sizeof(EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER));
+      AllocationStructurePtr->BaseAddress = PcdGet64(PcdPciExpressBaseAddress);
+      break;
+    // Lakeport platform doesn't support the following table
+    /*
+      //
+    // "ECDT" Embedded Controller Boot Resources Table
+        //
+    case EFI_ACPI_3_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE:
+      break;
+        //
+    // "PSDT" Persistent System Description Table
+          //
+    case EFI_ACPI_3_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
+      break;
+          //
+    // "SBST" Smart Battery Specification Table
+    //
+    case EFI_ACPI_3_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE:
+          break;
+    //
+    // "SLIT" System Locality Information Table
+    //
+    case EFI_ACPI_3_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE:
+          break;
+    //
+    // "SRAT" Static Resource Affinity Table
+    //
+    case EFI_ACPI_3_0_STATIC_RESOURCE_AFFINITY_TABLE_SIGNATURE:
+    break;
+  //
+    // "XSDT" Extended System Description Table
+  //
+    case EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
+      break;
+  //
+    // "BOOT" MS Simple Boot Spec
+  //
+    case EFI_ACPI_3_0_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE:
+      break;
+  //
+    // "CPEP" Corrected Platform Error Polling Table
+  //
+    case EFI_ACPI_3_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE:
+      break;
+  //
+    // "DBGP" MS Debug Port Spec
+  //
+    case EFI_ACPI_3_0_DEBUG_PORT_TABLE_SIGNATURE:
+      break;
+    //
+    // "ETDT" Event Timer Description Table
+    //
+    case EFI_ACPI_3_0_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE:
+      break;
+    //
+    // "SPMI" Server Platform Management Interface Table
+    //
+    case EFI_ACPI_3_0_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE:
+      break;
+    //
+    // "TCPA" Trusted Computing Platform Alliance Capabilities Table
+    //
+    case EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE:
+      break;
+    */
+    default:
+      break;
+    }
+  }
+}
+
+//
+// Description:
+//    Entrypoint of Acpi Platform driver
+// In:
+//    ImageHandle
+//    SystemTable
+// Out:
+//    EFI_SUCCESS
+//    EFI_LOAD_ERROR
+//    EFI_OUT_OF_RESOURCES
+//
+
+EFI_STATUS
+AcpiPlatformEntryPoint (
+  IN EFI_HANDLE     ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_ACPI_TABLE_PROTOCOL       *AcpiTable;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
+  INTN                          Instance;
+  EFI_ACPI_COMMON_HEADER        *CurrentTable;
+  UINTN                         TableHandle;
+  UINT32                        FvStatus;
+  UINTN                         Size;
+  EFI_ACPI_TABLE_VERSION        Version;
+  EFI_HANDLE                    Handle;
+  UINTN                         Index;
+  PCI_DEVICE_INFO               *PciDeviceInfo;
+  EFI_ACPI_HANDLE               PciRootHandle;
+  BOOLEAN                       UpdatePRT;
+  BOOLEAN                       UpdatePRW;
+  PCI_DEVICE_SETTING            *mConfigData;
+
+  DEBUG((DEBUG_INFO, "ACPI Platform start...\n"));
+
+  Instance = 0;
+  TableHandle = 0;
+  CurrentTable = NULL;
+  mConfigData  = NULL;
+
+  //
+  // Initialize the EFI Driver Library
+  //
+
+  ASSERT (sizeof (EFI_GLOBAL_NVS_AREA) == 512);
+
+  Status = gBS->AllocatePool (
+                   EfiACPIMemoryNVS,
+                   sizeof (EFI_GLOBAL_NVS_AREA),
+                   (VOID**)&mGlobalNvsArea.Area
+                   );
+
+  Handle = NULL;
+  Status = gBS->InstallProtocolInterface (
+                  &Handle,
+                  &gEfiGlobalNvsAreaProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &mGlobalNvsArea
+                  );
+
+  ASSERT_EFI_ERROR (Status);
+  if (!EFI_ERROR (Status)) {
+    SetMem (
+      mGlobalNvsArea.Area,
+      sizeof (EFI_GLOBAL_NVS_AREA),
+      0
+      );
+  }
+
+  //
+  // Initialize the data.  Eventually, this will be controlled by setup options.
+  //
+  mGlobalNvsArea.Area->HpetEnable           =  PcdGetBool (PcdHpetEnable);
+  mGlobalNvsArea.Area->Pm1blkIoBaseAddress  =  PcdGet16(PcdPm1blkIoBaseAddress);
+  mGlobalNvsArea.Area->PmbaIoBaseAddress    =  PcdGet16(PcdPmbaIoBaseAddress);
+  mGlobalNvsArea.Area->Gpe0blkIoBaseAddress =  PcdGet16(PcdGpe0blkIoBaseAddress);
+  mGlobalNvsArea.Area->GbaIoBaseAddress     =  PcdGet16(PcdGbaIoBaseAddress);
+  mGlobalNvsArea.Area->SmbaIoBaseAddress    =  PcdGet16(PcdSmbaIoBaseAddress);
+  mGlobalNvsArea.Area->WdtbaIoBaseAddress   =  PcdGet16(PcdWdtbaIoBaseAddress);
+  mGlobalNvsArea.Area->HpetBaseAddress      =  (UINT32)PcdGet64(PcdHpetBaseAddress);
+  mGlobalNvsArea.Area->HpetSize             =  (UINT32)PcdGet64(PcdHpetSize);
+  mGlobalNvsArea.Area->PciExpressBaseAddress=  (UINT32)PcdGet64(PcdPciExpressBaseAddress);
+  mGlobalNvsArea.Area->PciExpressSize       =  (UINT32)PcdGet64(PcdPciExpressSize);
+  mGlobalNvsArea.Area->RcbaMmioBaseAddress  =  (UINT32)PcdGet64(PcdRcbaMmioBaseAddress);
+  mGlobalNvsArea.Area->RcbaMmioSize         =  (UINT32)PcdGet64(PcdRcbaMmioSize);
+  mGlobalNvsArea.Area->IoApicBaseAddress    =  (UINT32)PcdGet64(PcdIoApicBaseAddress);
+  mGlobalNvsArea.Area->IoApicSize           =  (UINT32)PcdGet64(PcdIoApicSize);
+  mGlobalNvsArea.Area->TpmPresent           =  (UINT32)(FALSE);
+  mGlobalNvsArea.Area->DBG2Present          =  (UINT32)(FALSE);
+  mGlobalNvsArea.Area->PlatformType         =  (UINT32)PcdGet16 (PcdPlatformType);
+
+  //
+  // Configure platform IO expander I2C Slave Address.
+  //
+  if (mGlobalNvsArea.Area->PlatformType == Galileo) {
+    if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) {
+      mGlobalNvsArea.Area->AlternateSla = FALSE;
+    } else {
+      mGlobalNvsArea.Area->AlternateSla = TRUE;
+    }
+  }
+
+  //
+  // Find the AcpiTable protocol
+  //
+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable);
+  if (EFI_ERROR (Status)) {
+    return EFI_ABORTED;
+  }
+
+  //
+  // Initialize MADT table
+  //
+  Status = MadtTableInitialize (&CurrentTable, &Size);
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Perform any table specific updates.
+  //
+  AcpiUpdateTable ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable, &Version);
+
+  //
+  // Update the check sum
+  // It needs to be zeroed before the checksum calculation
+  //
+  ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 0;
+  ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum =
+    CalculateCheckSum8 ((VOID *)CurrentTable, CurrentTable->Length);
+
+  //
+  // Add the table
+  //
+  TableHandle = 0;
+  Status = AcpiTable->InstallAcpiTable (
+                            AcpiTable,
+                            CurrentTable,
+                            CurrentTable->Length,
+                          &TableHandle
+                          );
+  ASSERT_EFI_ERROR (Status);
+  CurrentTable = NULL;
+
+  //
+  // Init Pci Device PRT PRW information structure from PCD
+  //
+  mConfigData = (PCI_DEVICE_SETTING *)AllocateZeroPool (sizeof (PCI_DEVICE_SETTING));
+  ASSERT (mConfigData != NULL);
+  InitPciDeviceInfoStructure (mConfigData);
+  //
+  // Get the Acpi SDT protocol for manipulation on acpi table
+  //
+  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&mAcpiSdt);
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Locate the firmware volume protocol
+  //
+  Status = LocateSupportProtocol (&gEfiFirmwareVolume2ProtocolGuid, (VOID**)&FwVol, 1);
+  if (EFI_ERROR (Status)) {
+    return EFI_ABORTED;
+  }
+  //
+  // Read tables from the storage file.
+  //
+
+  while (Status == EFI_SUCCESS) {
+
+    Status = FwVol->ReadSection (
+                      FwVol,
+                      (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),
+                      EFI_SECTION_RAW,
+                      Instance,
+                      (VOID**)&CurrentTable,
+                      &Size,
+                      &FvStatus
+                      );
+
+    if (!EFI_ERROR(Status)) {
+      //
+      // Perform any table specific updates.
+      //
+      AcpiUpdateTable ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable, &Version);
+
+      //
+      // Update the check sum
+      // It needs to be zeroed before the checksum calculation
+      //
+      ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 0;
+      ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum =
+        CalculateCheckSum8 ((VOID *)CurrentTable, CurrentTable->Length);
+
+      //
+      // Add the table
+      //
+      TableHandle = 0;
+      Status = AcpiTable->InstallAcpiTable (
+                            AcpiTable,
+                              CurrentTable,
+                            ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length,
+                              &TableHandle
+                              );
+      if (EFI_ERROR(Status)) {
+        return EFI_ABORTED;
+      }
+      //
+      // If this table is the DSDT table, then update the _PRT and _PRW based on
+      // the settings from pcds
+      //
+      if (CurrentTable->Signature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
+        //
+        // Create the root handle for DSDT table
+        //
+        Status = mAcpiSdt->OpenSdt (TableHandle, &mDsdtHandle);
+        ASSERT_EFI_ERROR (Status);
+
+        PciRootHandle = NULL;
+        PciRootHandle = SdtGetRootBridgeHandle (mAcpiSdt, mDsdtHandle);
+        ASSERT (PciRootHandle != NULL);
+
+        PciDeviceInfo = NULL;
+        for (Index = 0; Index < mConfigData->PciDeviceInfoNumber; Index++) {
+          PciDeviceInfo = &(mConfigData->PciDeviceInfo[Index]);
+
+          //
+          // Check whether this is a valid item
+          //
+          if ((PciDeviceInfo->BridgeAddress != 0xFFFFFFFF) && (PciDeviceInfo->DeviceAddress != 0xFFFFFFFF)) {
+
+            //DEBUG ((EFI_D_ERROR, "Valid pci info structure: bridge address:0x%x, device address:0x%x\n", PciDeviceInfo->BridgeAddress, PciDeviceInfo->DeviceAddress));
+
+            UpdatePRT = FALSE;
+            UpdatePRW = FALSE;
+
+            SdtCheckPciDeviceInfoChanged (PciDeviceInfo, &UpdatePRT, &UpdatePRW);
+            //
+            // Check whether there is any valid pci routing item
+            //
+            if (UpdatePRT) {
+              //
+              // Update the pci routing information
+              //
+              //DEBUG ((EFI_D_ERROR, "Update _PRT\n"));
+              SdtUpdatePciRouting (mAcpiSdt, PciRootHandle, PciDeviceInfo);
+            }
+            //
+            // Check whether there is any valid pci routing item
+            //
+            if (UpdatePRW) {
+              //
+              // Update the pci wakeup information
+              //
+              //DEBUG ((EFI_D_ERROR, "Update _PRW\n"));
+              SdtUpdatePowerWake (mAcpiSdt, PciRootHandle, PciDeviceInfo);
+            }
+          }
+        }
+        Status = mAcpiSdt->Close (PciRootHandle);
+        ASSERT_EFI_ERROR (Status);
+        //
+        // Mark the root handle as modified , let SDT protocol recaculate the checksum
+        //
+        ((EFI_AML_HANDLE *)mDsdtHandle)->Modified = TRUE;
+        Status = mAcpiSdt->Close (mDsdtHandle);
+        ASSERT_EFI_ERROR (Status);
+      }
+      //
+      // Increment the instance
+      //
+      Instance++;
+      CurrentTable = NULL;
+    }
+  }
+
+  gBS->FreePool (mConfigData);
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.h b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.h
new file mode 100644
index 0000000000..920c7ef3a9
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.h
@@ -0,0 +1,120 @@
+/** @file
+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.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#ifndef _ACPI_PLATFORM_H_
+#define _ACPI_PLATFORM_H_
+
+//
+// Statements that include other header files
+//
+
+#include <PiDxe.h>
+#include <IntelQNCDxe.h>
+#include <Platform.h>
+#include <PlatformBoards.h>
+#include <Ioh.h>
+#include <QNCCommonDefinitions.h>
+
+#include <Protocol/GlobalNvsArea.h>
+#include <Protocol/MpService.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Protocol/FirmwareVolume2.h>
+
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DxeServicesLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/QNCAccessLib.h>
+#include <Library/PlatformHelperLib.h>
+
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/HighPrecisionEventTimerTable.h>
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
+
+#include "Madt.h"
+#include "AcpiPciUpdate.h"
+
+#pragma pack(1)
+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;
+#pragma pack()
+
+
+#define AML_NAME_OP               0x08
+#define AML_METHOD_OP             0x14
+#define AML_OPREGION_OP           0x80
+#define AML_PACKAGE_OP            0x12    // Package operator.
+
+//
+// ACPI table information used to initialize tables.
+//
+#define EFI_ACPI_OEM_ID           "INTEL "
+#define EFI_ACPI_OEM_TABLE_ID     0x2020204F4E414954ULL  // "TIANO   "
+#define EFI_ACPI_OEM_REVISION     0x00000002
+#define EFI_ACPI_CREATOR_ID       0x5446534D          // "MSFT"
+#define EFI_ACPI_CREATOR_REVISION 0x01000013
+
+#define ACPI_COMPATIBLE_1_0       0
+#define ACPI_COMPATIBLE_2_0       1
+#define ACPI_COMPATIBLE_3_0       2
+
+
+
+
+//
+// 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;
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.inf b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.inf
new file mode 100644
index 0000000000..5cbfd14ae6
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.inf
@@ -0,0 +1,196 @@
+## @file
+# Component description file for AcpiPlatform module.
+#
+# This is an implementation of the ACPI platform driver,
+# whose requirements are from ACPI External Product Specification.
+# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = AcpiPlatform
+  FILE_GUID                      = 368B3649-F204-4cd0-89A8-091077C070FA
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = AcpiPlatformEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  AcpiPlatform.c
+  AcpiPlatform.h
+  MadtPlatform.c
+  Madt.h
+  AcpiPciUpdate.c
+  AcpiPciUpdate.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+  UefiLib
+  DxeServicesLib
+  PcdLib
+  IoLib
+  BaseMemoryLib
+  DebugLib
+  UefiRuntimeServicesTableLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  DevicePathLib
+  PlatformHelperLib
+
+[Protocols]
+  gEfiGlobalNvsAreaProtocolGuid                 # PROTOCOL ALWAYS_CONSUMED
+  gEfiMpServiceProtocolGuid                     # PROTOCOL SOMETIMES_CONSUMED
+  gEfiAcpiSdtProtocolGuid                       # PROTOCOL ALWAYS_CONSUMED
+  gEfiAcpiTableProtocolGuid                     # PROTOCOL ALWAYS_CONSUMED
+
+[Pcd]
+  gQuarkPlatformTokenSpaceGuid.PcdPlatformType
+
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress
+
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable0Enable
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable0SourceIrq
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable0Polarity
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable0TrigerMode
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable0GlobalIrq
+
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable1Enable
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable1SourceIrq
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable1Polarity
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable1TrigerMode
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable1GlobalIrq
+
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable2Enable
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable2SourceIrq
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable2Polarity
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable2TrigerMode
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable2GlobalIrq
+
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable3Enable
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable3SourceIrq
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable3Polarity
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable3TrigerMode
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable3GlobalIrq
+
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable4Enable
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable4SourceIrq
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable4Polarity
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable4TrigerMode
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable4GlobalIrq
+
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable5Enable
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable5SourceIrq
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable5Polarity
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable5TrigerMode
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable5GlobalIrq
+
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable6Enable
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable6SourceIrq
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable6Polarity
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable6TrigerMode
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable6GlobalIrq
+
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable7Enable
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable7SourceIrq
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable7Polarity
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable7TrigerMode
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable7GlobalIrq
+
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable8Enable
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable8SourceIrq
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable8Polarity
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable8TrigerMode
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable8GlobalIrq
+
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable9Enable
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable9SourceIrq
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable9Polarity
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable9TrigerMode
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable9GlobalIrq
+
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable10Enable
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable10SourceIrq
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable10Polarity
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable10TrigerMode
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable10GlobalIrq
+
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable11Enable
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable11SourceIrq
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable11Polarity
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable11TrigerMode
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable11GlobalIrq
+
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable12Enable
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable12SourceIrq
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable12Polarity
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable12TrigerMode
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable12GlobalIrq
+
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable13Enable
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable13SourceIrq
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable13Polarity
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable13TrigerMode
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable13GlobalIrq
+
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable14Enable
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable14SourceIrq
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable14Polarity
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable14TrigerMode
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable14GlobalIrq
+
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable15Enable
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable15SourceIrq
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable15Polarity
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable15TrigerMode
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable15GlobalIrq
+
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdIoApicBaseAddress
+  gQuarkPlatformTokenSpaceGuid.PcdIoApicSettingIoApicAddress
+  gQuarkPlatformTokenSpaceGuid.PcdIoApicSettingGlobalInterruptBase
+  gQuarkPlatformTokenSpaceGuid.PcdIoApicSettingIoApicId
+  gQuarkPlatformTokenSpaceGuid.PcdIoApicSettingNmiEnable
+  gQuarkPlatformTokenSpaceGuid.PcdIoApicSettingNmiSource
+  gQuarkPlatformTokenSpaceGuid.PcdIoApicSettingPolarity
+  gQuarkPlatformTokenSpaceGuid.PcdIoApicSettingTrigerMode
+  gQuarkPlatformTokenSpaceGuid.PcdLocalApicSettingNmiEnabelApicIdMask
+  gQuarkPlatformTokenSpaceGuid.PcdLocalApicSettingAddressOverrideEnable
+  gQuarkPlatformTokenSpaceGuid.PcdLocalApicSettingPolarity
+  gQuarkPlatformTokenSpaceGuid.PcdLocalApicSettingTrigerMode
+  gQuarkPlatformTokenSpaceGuid.PcdLocalApicSettingLocalApicLint
+  gQuarkPlatformTokenSpaceGuid.PcdLocalApicAddressOverride
+
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdSmmActivationPort
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPm1blkIoBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdGpe0blkIoBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPmbaIoBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdGbaIoBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdSmbaIoBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdHpetBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdHpetSize
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdIoApicBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdIoApicSize
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciExpressSize
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdRcbaMmioBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdRcbaMmioSize
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdWdtbaIoBaseAddress
+  gQuarkPlatformTokenSpaceGuid.PcdHpetEnable
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdDeviceEnables
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiTableStorageFile
+
+[Depex]
+  gEfiMpServiceProtocolGuid AND gEfiAcpiTableProtocolGuid
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Madt.h b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Madt.h
new file mode 100644
index 0000000000..7c67056944
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Madt.h
@@ -0,0 +1,207 @@
+/** @file
+This file describes the contents of the ACPI Multiple APIC Description
+Table (MADT).  Some additional ACPI values are defined in Acpi10.h and
+Acpi20.h.
+To make changes to the MADT, it is necessary to update the count for the
+APIC structure being updated, and to modify table found in Madt.c.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#ifndef _MADT_H
+#define _MADT_H
+
+
+//
+// Statements that include other files
+//
+
+#include <IndustryStandard/Acpi.h>
+#include <Library/PcdLib.h>
+
+//
+// MADT Definitions
+//
+
+#define EFI_ACPI_OEM_MADT_REVISION 0x00000001
+
+//
+// Local APIC address
+//
+
+#define EFI_ACPI_LOCAL_APIC_ADDRESS 0xFEE00000
+
+//
+// Multiple APIC Flags are defined in AcpiX.0.h
+//
+#define EFI_ACPI_1_0_MULTIPLE_APIC_FLAGS (EFI_ACPI_1_0_PCAT_COMPAT)
+#define EFI_ACPI_2_0_MULTIPLE_APIC_FLAGS (EFI_ACPI_2_0_PCAT_COMPAT)
+
+//
+// Define the number of each table type.
+// This is where the table layout is modified.
+//
+
+#define EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT           2
+#define EFI_ACPI_IO_APIC_COUNT                        1
+#define EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT      2
+#define EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT  0
+#define EFI_ACPI_LOCAL_APIC_NMI_COUNT                 2
+#define EFI_ACPI_LOCAL_APIC_ADDRESS_OVERRIDE_COUNT    0
+#define EFI_ACPI_IO_SAPIC_COUNT                       0
+#define EFI_ACPI_PROCESSOR_LOCAL_SAPIC_COUNT          0
+#define EFI_ACPI_PLATFORM_INTERRUPT_SOURCES_COUNT     0
+
+#define EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT_MAX  16
+
+//
+// MADT structure
+//
+
+//
+// Ensure proper structure formats
+//
+#pragma pack (1)
+
+//
+// ACPI 1.0 Table structure
+//
+typedef struct {
+  EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER   Header;
+
+#if EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT > 0
+  EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC_STRUCTURE           LocalApic[EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT];
+#endif
+
+#if EFI_ACPI_IO_APIC_COUNT > 0
+  EFI_ACPI_1_0_IO_APIC_STRUCTURE                        IoApic[EFI_ACPI_IO_APIC_COUNT];
+#endif
+
+#if EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT > 0
+  EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE      Iso[EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT];
+#endif
+
+#if EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT > 0
+  EFI_ACPI_1_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE  NmiSource[EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT];
+#endif
+
+#if EFI_ACPI_LOCAL_APIC_NMI_COUNT > 0
+  EFI_ACPI_1_0_LOCAL_APIC_NMI_STRUCTURE                 LocalApicNmi[EFI_ACPI_LOCAL_APIC_NMI_COUNT];
+#endif
+
+#if EFI_ACPI_LOCAL_APIC_ADDRESS_OVERRIDE_COUNT > 0
+  EFI_ACPI_1_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE    LocalApicOverride[EFI_ACPI_LOCAL_APIC_OVERRIDE_COUNT];
+#endif
+
+} EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE;
+
+//
+// ACPI 2.0 Table structure
+//
+typedef struct {
+  EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER   Header;
+
+#if EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT > 0
+  EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE           LocalApic[EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT];
+#endif
+
+#if EFI_ACPI_IO_APIC_COUNT > 0
+  EFI_ACPI_2_0_IO_APIC_STRUCTURE                        IoApic[EFI_ACPI_IO_APIC_COUNT];
+#endif
+
+#if EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT > 0
+  EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE      Iso[EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT];
+#endif
+
+#if EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT > 0
+  EFI_ACPI_2_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE  NmiSource[EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT];
+#endif
+
+#if EFI_ACPI_LOCAL_APIC_NMI_COUNT > 0
+  EFI_ACPI_2_0_LOCAL_APIC_NMI_STRUCTURE                 LocalApicNmi[EFI_ACPI_LOCAL_APIC_NMI_COUNT];
+#endif
+
+#if EFI_ACPI_LOCAL_APIC_ADDRESS_OVERRIDE_COUNT > 0
+  EFI_ACPI_2_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE    LocalApicOverride[EFI_ACPI_LOCAL_APIC_ADDRESS_OVERRIDE_COUNT];
+#endif
+
+#if EFI_ACPI_IO_SAPIC_COUNT > 0
+  EFI_ACPI_2_0_IO_SAPIC_STRUCTURE                       IoSapic[EFI_ACPI_IO_SAPIC_COUNT];
+#endif
+
+#if EFI_ACPI_PROCESSOR_LOCAL_SAPIC_COUNT > 0
+  EFI_ACPI_2_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE          LocalSapic[EFI_ACPI_PROCESSOR_LOCAL_SAPIC_COUNT];
+#endif
+
+#if EFI_ACPI_PLATFORM_INTERRUPT_SOURCES_COUNT > 0
+  EFI_ACPI_2_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE     PlatformInterruptSources[EFI_ACPI_PLATFORM_INTERRUPT_SOURCES_COUNT];
+#endif
+
+} EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE;
+
+#define _PcdIntSettingTblEnable(x)       PcdGet8 (PcdInterruptOverrideSettingTable##x##Enable)
+#define PcdIntSettingTblEnable(x)        _PcdIntSettingTblEnable(x)
+
+#define _PcdIntSettingTblSourceIrq(x)    PcdGet8 (PcdInterruptOverrideSettingTable##x##Enable)
+#define PcdIntSettingTblSourceIrq(x)     _PcdIntSettingTblSourceIrq(x)
+
+#define _PcdIntSettingTblPolarity(x)     PcdGet8 (PcdInterruptOverrideSettingTable##x##Polarity)
+#define PcdIntSettingTblPolarity(x)      _PcdIntSettingTblPolarity(x)
+
+#define _PcdIntSettingTableTrigerMode(x) PcdGet8 (PcdInterruptOverrideSettingTable##x##TrigerMode)
+#define PcdIntSettingTableTrigerMode(x)  _PcdIntSettingTableTrigerMode(x)
+
+#define _PcdIntSettingTableGlobalIrq(x)  PcdGet32 (PcdInterruptOverrideSettingTable##x##GlobalIrq)
+#define PcdIntSettingTableGlobalIrq(x)   _PcdIntSettingTableGlobalIrq(x)
+
+typedef struct {
+  UINT8     Enable;
+  UINT8     SourceIrq;
+  UINT8     Polarity;
+  UINT8     TrigerMode;
+  UINT32    GlobalIrq;
+} INTERRUPT_OVERRIDE_SETTING;
+
+
+typedef struct {
+  UINT32    IoApicAddress;
+  UINT32    GlobalInterruptBase;
+  UINT8     IoApicId;
+  UINT8     NmiEnable;
+  UINT8     NmiSource;
+  UINT8     Polarity;
+  UINT8     TrigerMode;
+} IO_APIC_SETTING;
+
+typedef struct {
+  UINT8     NmiEnabelApicIdMask;
+  UINT8     AddressOverrideEnable;
+  UINT8     Polarity;
+  UINT8     TrigerMode;
+  UINT8     LocalApicLint;
+  UINT8     Reserve[3];
+  UINT32    LocalApicAddress;
+  UINT64    LocalApicAddressOverride;
+} LOCAL_APIC_SETTING;
+
+typedef struct _MADT_CONFIG_DATA {
+  INTERRUPT_OVERRIDE_SETTING MadtInterruptSetting[EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT_MAX];
+  IO_APIC_SETTING        MadtIoApicSetting;
+  LOCAL_APIC_SETTING       MadtLocalApicSetting;
+}MADT_CONFIG_DATA;
+
+#pragma pack ()
+
+EFI_STATUS
+EFIAPI
+MadtTableInitialize (
+  OUT   EFI_ACPI_COMMON_HEADER  **MadtTable,
+  OUT   UINTN                   *Size
+  );
+
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/MadtPlatform.c b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/MadtPlatform.c
new file mode 100644
index 0000000000..a7d24b013b
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/MadtPlatform.c
@@ -0,0 +1,300 @@
+/** @file
+This file contains Madt Talbe initialized work.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+//
+// Statements that include other files
+//
+
+#include "AcpiPlatform.h"
+
+VOID
+InitMadtConfigData (MADT_CONFIG_DATA *mConfigData)
+{
+  mConfigData->MadtInterruptSetting[0].Enable     = PcdGet8 (PcdInterruptOverrideSettingTable0Enable);
+  mConfigData->MadtInterruptSetting[0].SourceIrq  = PcdGet8 (PcdInterruptOverrideSettingTable0SourceIrq);
+  mConfigData->MadtInterruptSetting[0].Polarity   = PcdGet8 (PcdInterruptOverrideSettingTable0Polarity);
+  mConfigData->MadtInterruptSetting[0].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable0TrigerMode);
+  mConfigData->MadtInterruptSetting[0].GlobalIrq  = PcdGet32 (PcdInterruptOverrideSettingTable0GlobalIrq);
+
+  mConfigData->MadtInterruptSetting[1].Enable     = PcdGet8 (PcdInterruptOverrideSettingTable1Enable);
+  mConfigData->MadtInterruptSetting[1].SourceIrq  = PcdGet8 (PcdInterruptOverrideSettingTable1SourceIrq);
+  mConfigData->MadtInterruptSetting[1].Polarity   = PcdGet8 (PcdInterruptOverrideSettingTable1Polarity);
+  mConfigData->MadtInterruptSetting[1].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable1TrigerMode);
+  mConfigData->MadtInterruptSetting[1].GlobalIrq  = PcdGet32 (PcdInterruptOverrideSettingTable1GlobalIrq);
+
+  mConfigData->MadtInterruptSetting[2].Enable     = PcdGet8 (PcdInterruptOverrideSettingTable2Enable);
+  mConfigData->MadtInterruptSetting[2].SourceIrq  = PcdGet8 (PcdInterruptOverrideSettingTable2SourceIrq);
+  mConfigData->MadtInterruptSetting[2].Polarity   = PcdGet8 (PcdInterruptOverrideSettingTable2Polarity);
+  mConfigData->MadtInterruptSetting[2].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable2TrigerMode);
+  mConfigData->MadtInterruptSetting[2].GlobalIrq  = PcdGet32 (PcdInterruptOverrideSettingTable2GlobalIrq);
+
+  mConfigData->MadtInterruptSetting[3].Enable     = PcdGet8 (PcdInterruptOverrideSettingTable3Enable);
+  mConfigData->MadtInterruptSetting[3].SourceIrq  = PcdGet8 (PcdInterruptOverrideSettingTable3SourceIrq);
+  mConfigData->MadtInterruptSetting[3].Polarity   = PcdGet8 (PcdInterruptOverrideSettingTable3Polarity);
+  mConfigData->MadtInterruptSetting[3].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable3TrigerMode);
+  mConfigData->MadtInterruptSetting[3].GlobalIrq  = PcdGet32 (PcdInterruptOverrideSettingTable3GlobalIrq);
+
+  mConfigData->MadtInterruptSetting[4].Enable     = PcdGet8 (PcdInterruptOverrideSettingTable4Enable);
+  mConfigData->MadtInterruptSetting[4].SourceIrq  = PcdGet8 (PcdInterruptOverrideSettingTable4SourceIrq);
+  mConfigData->MadtInterruptSetting[4].Polarity   = PcdGet8 (PcdInterruptOverrideSettingTable4Polarity);
+  mConfigData->MadtInterruptSetting[4].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable4TrigerMode);
+  mConfigData->MadtInterruptSetting[4].GlobalIrq  = PcdGet32 (PcdInterruptOverrideSettingTable4GlobalIrq);
+
+  mConfigData->MadtInterruptSetting[5].Enable     = PcdGet8 (PcdInterruptOverrideSettingTable5Enable);
+  mConfigData->MadtInterruptSetting[5].SourceIrq  = PcdGet8 (PcdInterruptOverrideSettingTable5SourceIrq);
+  mConfigData->MadtInterruptSetting[5].Polarity   = PcdGet8 (PcdInterruptOverrideSettingTable5Polarity);
+  mConfigData->MadtInterruptSetting[5].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable5TrigerMode);
+  mConfigData->MadtInterruptSetting[5].GlobalIrq  = PcdGet32 (PcdInterruptOverrideSettingTable5GlobalIrq);
+
+  mConfigData->MadtInterruptSetting[6].Enable     = PcdGet8 (PcdInterruptOverrideSettingTable6Enable);
+  mConfigData->MadtInterruptSetting[6].SourceIrq  = PcdGet8 (PcdInterruptOverrideSettingTable6SourceIrq);
+  mConfigData->MadtInterruptSetting[6].Polarity   = PcdGet8 (PcdInterruptOverrideSettingTable6Polarity);
+  mConfigData->MadtInterruptSetting[6].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable6TrigerMode);
+  mConfigData->MadtInterruptSetting[6].GlobalIrq  = PcdGet32 (PcdInterruptOverrideSettingTable6GlobalIrq);
+
+  mConfigData->MadtInterruptSetting[7].Enable     = PcdGet8 (PcdInterruptOverrideSettingTable7Enable);
+  mConfigData->MadtInterruptSetting[7].SourceIrq  = PcdGet8 (PcdInterruptOverrideSettingTable7SourceIrq);
+  mConfigData->MadtInterruptSetting[7].Polarity   = PcdGet8 (PcdInterruptOverrideSettingTable7Polarity);
+  mConfigData->MadtInterruptSetting[7].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable7TrigerMode);
+  mConfigData->MadtInterruptSetting[7].GlobalIrq  = PcdGet32 (PcdInterruptOverrideSettingTable7GlobalIrq);
+
+  mConfigData->MadtInterruptSetting[8].Enable     = PcdGet8 (PcdInterruptOverrideSettingTable8Enable);
+  mConfigData->MadtInterruptSetting[8].SourceIrq  = PcdGet8 (PcdInterruptOverrideSettingTable8SourceIrq);
+  mConfigData->MadtInterruptSetting[8].Polarity   = PcdGet8 (PcdInterruptOverrideSettingTable8Polarity);
+  mConfigData->MadtInterruptSetting[8].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable8TrigerMode);
+  mConfigData->MadtInterruptSetting[8].GlobalIrq  = PcdGet32 (PcdInterruptOverrideSettingTable8GlobalIrq);
+
+  mConfigData->MadtInterruptSetting[9].Enable     = PcdGet8 (PcdInterruptOverrideSettingTable9Enable);
+  mConfigData->MadtInterruptSetting[9].SourceIrq  = PcdGet8 (PcdInterruptOverrideSettingTable9SourceIrq);
+  mConfigData->MadtInterruptSetting[9].Polarity   = PcdGet8 (PcdInterruptOverrideSettingTable9Polarity);
+  mConfigData->MadtInterruptSetting[9].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable9TrigerMode);
+  mConfigData->MadtInterruptSetting[9].GlobalIrq  = PcdGet32 (PcdInterruptOverrideSettingTable9GlobalIrq);
+
+  mConfigData->MadtInterruptSetting[10].Enable     = PcdGet8 (PcdInterruptOverrideSettingTable10Enable);
+  mConfigData->MadtInterruptSetting[10].SourceIrq  = PcdGet8 (PcdInterruptOverrideSettingTable10SourceIrq);
+  mConfigData->MadtInterruptSetting[10].Polarity   = PcdGet8 (PcdInterruptOverrideSettingTable10Polarity);
+  mConfigData->MadtInterruptSetting[10].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable10TrigerMode);
+  mConfigData->MadtInterruptSetting[10].GlobalIrq  = PcdGet32 (PcdInterruptOverrideSettingTable10GlobalIrq);
+
+  mConfigData->MadtInterruptSetting[11].Enable     = PcdGet8 (PcdInterruptOverrideSettingTable11Enable);
+  mConfigData->MadtInterruptSetting[11].SourceIrq  = PcdGet8 (PcdInterruptOverrideSettingTable11SourceIrq);
+  mConfigData->MadtInterruptSetting[11].Polarity   = PcdGet8 (PcdInterruptOverrideSettingTable11Polarity);
+  mConfigData->MadtInterruptSetting[11].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable11TrigerMode);
+  mConfigData->MadtInterruptSetting[11].GlobalIrq  = PcdGet32 (PcdInterruptOverrideSettingTable11GlobalIrq);
+
+  mConfigData->MadtInterruptSetting[12].Enable     = PcdGet8 (PcdInterruptOverrideSettingTable12Enable);
+  mConfigData->MadtInterruptSetting[12].SourceIrq  = PcdGet8 (PcdInterruptOverrideSettingTable12SourceIrq);
+  mConfigData->MadtInterruptSetting[12].Polarity   = PcdGet8 (PcdInterruptOverrideSettingTable12Polarity);
+  mConfigData->MadtInterruptSetting[12].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable12TrigerMode);
+  mConfigData->MadtInterruptSetting[12].GlobalIrq  = PcdGet32 (PcdInterruptOverrideSettingTable12GlobalIrq);
+
+  mConfigData->MadtInterruptSetting[13].Enable     = PcdGet8 (PcdInterruptOverrideSettingTable13Enable);
+  mConfigData->MadtInterruptSetting[13].SourceIrq  = PcdGet8 (PcdInterruptOverrideSettingTable13SourceIrq);
+  mConfigData->MadtInterruptSetting[13].Polarity   = PcdGet8 (PcdInterruptOverrideSettingTable13Polarity);
+  mConfigData->MadtInterruptSetting[13].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable13TrigerMode);
+  mConfigData->MadtInterruptSetting[13].GlobalIrq  = PcdGet32 (PcdInterruptOverrideSettingTable13GlobalIrq);
+
+  mConfigData->MadtInterruptSetting[14].Enable     = PcdGet8 (PcdInterruptOverrideSettingTable14Enable);
+  mConfigData->MadtInterruptSetting[14].SourceIrq  = PcdGet8 (PcdInterruptOverrideSettingTable14SourceIrq);
+  mConfigData->MadtInterruptSetting[14].Polarity   = PcdGet8 (PcdInterruptOverrideSettingTable14Polarity);
+  mConfigData->MadtInterruptSetting[14].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable14TrigerMode);
+  mConfigData->MadtInterruptSetting[14].GlobalIrq  = PcdGet32 (PcdInterruptOverrideSettingTable14GlobalIrq);
+
+  mConfigData->MadtInterruptSetting[15].Enable     = PcdGet8 (PcdInterruptOverrideSettingTable15Enable);
+  mConfigData->MadtInterruptSetting[15].SourceIrq  = PcdGet8 (PcdInterruptOverrideSettingTable15SourceIrq);
+  mConfigData->MadtInterruptSetting[15].Polarity   = PcdGet8 (PcdInterruptOverrideSettingTable15Polarity);
+  mConfigData->MadtInterruptSetting[15].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable15TrigerMode);
+  mConfigData->MadtInterruptSetting[15].GlobalIrq  = PcdGet32 (PcdInterruptOverrideSettingTable15GlobalIrq);
+
+  mConfigData->MadtIoApicSetting.IoApicAddress       = (UINT32)PcdGet64(PcdIoApicBaseAddress);
+  mConfigData->MadtIoApicSetting.GlobalInterruptBase = PcdGet32 (PcdIoApicSettingGlobalInterruptBase);
+  mConfigData->MadtIoApicSetting.IoApicId            = PcdGet8 (PcdIoApicSettingIoApicId);
+  mConfigData->MadtIoApicSetting.NmiEnable           = PcdGet8 (PcdIoApicSettingNmiEnable);
+  mConfigData->MadtIoApicSetting.NmiSource           = PcdGet8 (PcdIoApicSettingNmiSource);
+  mConfigData->MadtIoApicSetting.Polarity            = PcdGet8 (PcdIoApicSettingPolarity);
+  mConfigData->MadtIoApicSetting.TrigerMode          = PcdGet8 (PcdIoApicSettingTrigerMode);
+
+  mConfigData->MadtLocalApicSetting.NmiEnabelApicIdMask   = PcdGet8 (PcdLocalApicSettingNmiEnabelApicIdMask);
+  mConfigData->MadtLocalApicSetting.AddressOverrideEnable = PcdGet8 (PcdLocalApicSettingAddressOverrideEnable);
+  mConfigData->MadtLocalApicSetting.Polarity              = PcdGet8 (PcdLocalApicSettingPolarity);
+  mConfigData->MadtLocalApicSetting.TrigerMode            = PcdGet8 (PcdLocalApicSettingTrigerMode);
+  mConfigData->MadtLocalApicSetting.LocalApicLint         = PcdGet8 (PcdLocalApicSettingLocalApicLint);
+  mConfigData->MadtLocalApicSetting.LocalApicAddressOverride      = PcdGet64 (PcdLocalApicAddressOverride);
+  mConfigData->MadtLocalApicSetting.LocalApicAddress              = PcdGet32 (PcdCpuLocalApicBaseAddress);
+}
+UINT32
+GetAcutalMadtTableSize (
+  IN MADT_CONFIG_DATA * MadtConfigData,
+  IN INTN               NumberOfCPUs
+  )
+{
+  UINT32 MadtSize;
+  UINT8  Index;
+  MadtSize = (UINT32)(sizeof (EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER) +
+             sizeof (EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE) * NumberOfCPUs +
+             sizeof (EFI_ACPI_2_0_IO_APIC_STRUCTURE) +
+             sizeof (EFI_ACPI_2_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE) * (MadtConfigData->MadtLocalApicSetting.AddressOverrideEnable != 0?1:0)
+             );
+  for (Index = 0; Index < EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT_MAX; Index ++ ) {
+    if (MadtConfigData->MadtInterruptSetting[Index].Enable != 0) {
+      MadtSize += sizeof (EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE);
+    }
+  }
+  for (Index = 0; Index < NumberOfCPUs; Index ++ ) {
+    if (0 != (MadtConfigData->MadtLocalApicSetting.NmiEnabelApicIdMask & (1 << Index))) {
+      MadtSize += sizeof (EFI_ACPI_2_0_LOCAL_APIC_NMI_STRUCTURE);
+    }
+  }
+  if (0 != MadtConfigData->MadtIoApicSetting.NmiEnable) {
+    MadtSize += sizeof (EFI_ACPI_2_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE);
+  }
+  return MadtSize;
+}
+
+//
+// Init Multiple APIC Description Table
+//
+EFI_STATUS
+MadtTableInitialize (
+  OUT   EFI_ACPI_COMMON_HEADER  **MadtTable,
+  OUT   UINTN                   *Size
+  )
+{
+  EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *Madt;
+  EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE         *ProcLocalApic;
+  EFI_ACPI_2_0_IO_APIC_STRUCTURE                      *IoApic;
+  EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE    *InterruptSourceOverride;
+  EFI_ACPI_2_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE  *IoApicNmiSource;
+  EFI_ACPI_2_0_LOCAL_APIC_NMI_STRUCTURE                 *LocalApicNmiSource;
+  EFI_ACPI_2_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE    *LocalApicAddressOverride;
+
+  EFI_MP_SERVICES_PROTOCOL                            *MpService;
+  UINTN                                               NumberOfCPUs;
+  UINTN                                               NumberOfEnabledCPUs;
+  MADT_CONFIG_DATA                                    MadtConfigData;
+
+  UINT32      MadtSize;
+  UINTN       Index;
+  EFI_STATUS  Status;
+
+
+  ASSERT (NULL != MadtTable);
+  ASSERT (NULL != Size);
+  //
+  // Init Madt table data
+  //
+  InitMadtConfigData (&MadtConfigData);
+  //
+  // Find the MP Protocol. This is an MP platform, so MP protocol must be
+  // there.
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiMpServiceProtocolGuid,
+                  NULL,
+                  (VOID **)&MpService
+                  );
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Determine the number of processors
+  //
+  MpService->GetNumberOfProcessors (
+              MpService,
+              &NumberOfCPUs,
+              &NumberOfEnabledCPUs
+              );
+  //ASSERT (NumberOfCPUs <= 2 && NumberOfCPUs > 0);
+  MadtSize = GetAcutalMadtTableSize (&MadtConfigData, NumberOfCPUs);
+  Madt = (EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *)AllocateZeroPool (MadtSize);
+  ASSERT (Madt != NULL);
+  //
+  // Initialize MADT Header information
+  //
+  Madt->Header.Signature    = EFI_ACPI_2_0_MULTIPLE_SAPIC_DESCRIPTION_TABLE_SIGNATURE;
+  Madt->Header.Length       = MadtSize;
+  Madt->Header.Revision     = EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION;
+  Madt->Header.OemTableId   = EFI_ACPI_OEM_TABLE_ID;
+  Madt->Header.OemRevision  = EFI_ACPI_OEM_MADT_REVISION;
+  Madt->Header.CreatorId    = EFI_ACPI_CREATOR_ID;
+  Madt->LocalApicAddress    = MadtConfigData.MadtLocalApicSetting.LocalApicAddress;
+  Madt->Flags               = EFI_ACPI_2_0_MULTIPLE_APIC_FLAGS;
+  CopyMem (Madt->Header.OemId, EFI_ACPI_OEM_ID, 6);
+
+  ProcLocalApic = (EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE *) (Madt + 1);
+  //
+  // Initialization of Processor's local APICs
+  //
+  for (Index = 0;Index < NumberOfCPUs; Index++) {
+    ProcLocalApic[Index].Type             = EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC;
+    ProcLocalApic[Index].Length           = sizeof (EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE);
+    ProcLocalApic[Index].AcpiProcessorId  = (UINT8)(Index + 1);
+    ProcLocalApic[Index].ApicId           = 0xff;
+    ProcLocalApic[Index].Flags            = 0;
+  }
+  //
+  // Initialization of IO APIC.
+  // Note: Here assumes that there must be one and only one IO APIC in platform.
+  //
+  IoApic = (EFI_ACPI_2_0_IO_APIC_STRUCTURE *) (&ProcLocalApic[Index]);
+  IoApic->Type                      = EFI_ACPI_2_0_IO_APIC;
+  IoApic->Length                    = sizeof (EFI_ACPI_2_0_IO_APIC_STRUCTURE);
+  IoApic->IoApicId                  = MadtConfigData.MadtIoApicSetting.IoApicId;
+  IoApic->IoApicAddress             = MadtConfigData.MadtIoApicSetting.IoApicAddress;
+  IoApic->GlobalSystemInterruptBase = MadtConfigData.MadtIoApicSetting.GlobalInterruptBase;
+
+  InterruptSourceOverride = (EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE *) (IoApic + 1);
+  for (Index = 0;Index < EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT_MAX; Index++ ){
+    if (MadtConfigData.MadtInterruptSetting[Index].Enable) {
+      InterruptSourceOverride->Type   = EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE;
+      InterruptSourceOverride->Length = sizeof (EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE);
+      InterruptSourceOverride->Bus    = 0;
+      InterruptSourceOverride->Source = MadtConfigData.MadtInterruptSetting[Index].SourceIrq;
+      InterruptSourceOverride->Flags  = ((MadtConfigData.MadtInterruptSetting[Index].TrigerMode & 0x03) << 2) | (MadtConfigData.MadtInterruptSetting[Index].Polarity & 0x03);
+      InterruptSourceOverride->GlobalSystemInterrupt  = MadtConfigData.MadtInterruptSetting[Index].GlobalIrq;
+      InterruptSourceOverride++;
+    }
+  }
+  //
+  // support NMI source configuration.
+  //
+  IoApicNmiSource = (EFI_ACPI_2_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE *) InterruptSourceOverride;
+  if ((BOOLEAN) MadtConfigData.MadtIoApicSetting.NmiEnable) {
+    IoApicNmiSource->Type   = EFI_ACPI_2_0_NON_MASKABLE_INTERRUPT_SOURCE;
+    IoApicNmiSource->Length = sizeof (EFI_ACPI_2_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE);
+    IoApicNmiSource->Flags  = ((MadtConfigData.MadtIoApicSetting.TrigerMode & 0x03) << 2) | (MadtConfigData.MadtIoApicSetting.Polarity & 0x03);
+    IoApicNmiSource->GlobalSystemInterrupt = MadtConfigData.MadtIoApicSetting.NmiSource;
+    IoApicNmiSource ++;
+  }
+  //
+  // Assume each processor has same NMI interrupt source.
+  //
+  LocalApicNmiSource = (EFI_ACPI_2_0_LOCAL_APIC_NMI_STRUCTURE *) IoApicNmiSource;
+  for (Index = 0;Index < NumberOfCPUs; Index++) {
+    if (0 != (MadtConfigData.MadtLocalApicSetting.NmiEnabelApicIdMask & (1 << Index))){
+      LocalApicNmiSource->Type          = EFI_ACPI_2_0_LOCAL_APIC_NMI;
+      LocalApicNmiSource->Length        = sizeof (EFI_ACPI_2_0_LOCAL_APIC_NMI_STRUCTURE);
+      LocalApicNmiSource->LocalApicLint = MadtConfigData.MadtLocalApicSetting.LocalApicLint;
+      LocalApicNmiSource->Flags         = ((MadtConfigData.MadtLocalApicSetting.TrigerMode & 0x03) << 2) | (MadtConfigData.MadtLocalApicSetting.Polarity & 0x03);
+      LocalApicNmiSource->AcpiProcessorId = (UINT8)(Index + 1);
+      LocalApicNmiSource++;
+    }
+  }
+
+  LocalApicAddressOverride = (EFI_ACPI_2_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE *) LocalApicNmiSource;
+  if ((BOOLEAN) MadtConfigData.MadtLocalApicSetting.AddressOverrideEnable) {
+    LocalApicAddressOverride->Type    = EFI_ACPI_2_0_LOCAL_APIC_ADDRESS_OVERRIDE;
+    LocalApicAddressOverride->Length  = sizeof (EFI_ACPI_2_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE);
+    LocalApicAddressOverride->LocalApicAddress = MadtConfigData.MadtLocalApicSetting.LocalApicAddressOverride;
+    LocalApicAddressOverride++;
+  }
+  *Size       = MadtSize;
+  *MadtTable  = (EFI_ACPI_COMMON_HEADER *) Madt;
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/BootScriptExecutorDxe.inf b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
new file mode 100644
index 0000000000..a89cba774a
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
@@ -0,0 +1,77 @@
+## @file
+# Boot Script Executor Module
+#
+# This is a standalone Boot Script Executor. Standalone means it does not
+# depends on any PEI or DXE service.
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BootScriptExecutorDxe
+  FILE_GUID                      = FA20568B-548B-4b2b-81EF-1BA08D4A3CEC
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = BootScriptExecutorEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  ScriptExecute.h
+  ScriptExecute.c
+
+[Sources.Ia32]
+  IA32/SetIdtEntry.c
+  IA32/S3Asm.asm
+  IA32/S3Asm.S
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  TimerLib
+  PcdLib
+  BaseMemoryLib
+  SmbusLib
+  UefiDriverEntryPoint
+  BaseLib
+  PciLib
+  IoLib
+  S3BootScriptLib
+  PeCoffLib
+  DxeServicesLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  CacheMaintenanceLib
+  UefiLib
+  DebugAgentLib
+  LockBoxLib
+  IntelQNCLib
+  QNCAccessLib
+
+[Guids]
+  gEfiBootScriptExecutorVariableGuid
+  gEfiBootScriptExecutorContextGuid
+  gPerformanceProtocolGuid
+  gEfiEventExitBootServicesGuid
+
+[FeaturePcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable
+
+[Depex]
+  gEfiLockBoxProtocolGuid
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/S3Asm.S b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/S3Asm.S
new file mode 100644
index 0000000000..1cb7b86fc3
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/S3Asm.S
@@ -0,0 +1,44 @@
+## @file
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+#-----------------------------------------
+#VOID
+#AsmTransferControl (
+#  IN   UINT32           S3WakingVector,
+#  IN   UINT32           AcpiLowMemoryBase
+#  );
+#-----------------------------------------
+
+ASM_GLOBAL ASM_PFX(AsmTransferControl)
+ASM_PFX(AsmTransferControl):
+    # S3WakingVector    :DWORD
+    # AcpiLowMemoryBase :DWORD
+    pushl %ebp
+    movl  %esp,%ebp
+    leal  LABLE, %eax
+    pushl $0x28             # CS
+    pushl %eax
+    movl  8(%ebp),%ecx
+    shrdl $20,%ecx,%ebx
+    andl  $0xf,%ecx
+    movw  %cx,%bx
+    movl  %ebx, jmp_addr
+    lret
+LABLE:
+    .byte 0xb8,0x30,0       # mov ax, 30h as selector
+    movw  %ax,%ds
+    movw  %ax,%es
+    movw  %ax,%fs
+    movw  %ax,%gs
+    movw  %ax,%ss
+    movl  %cr0, %eax        # Get control register 0
+    .byte 0x66
+    .byte 0x83,0xe0,0xfe    # and    eax, 0fffffffeh  ; Clear PE bit (bit #0)
+    .byte 0xf,0x22,0xc0     # mov    cr0, eax         ; Activate real mode
+    .byte 0xea              # jmp far @jmp_addr
+jmp_addr:
+    .long    0
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/S3Asm.asm b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/S3Asm.asm
new file mode 100644
index 0000000000..e932200c89
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/S3Asm.asm
@@ -0,0 +1,51 @@
+;; @file
+;   This is the assembly code for transferring to control to OS S3 waking vector
+;   for IA32 platform
+;
+; Copyright (c) 2013-2015 Intel Corporation.
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+
+    .586P
+    .model  flat,C
+    .code
+
+;-----------------------------------------
+;VOID
+;AsmTransferControl (
+;  IN   UINT32           S3WakingVector,
+;  IN   UINT32           AcpiLowMemoryBase
+;  );
+;-----------------------------------------
+
+AsmTransferControl  PROC
+    ; S3WakingVector    :DWORD
+    ; AcpiLowMemoryBase :DWORD
+    push  ebp
+    mov   ebp, esp
+    lea   eax, @F
+    push  28h               ; CS
+    push  eax
+    mov   ecx, [ebp + 8]
+    shrd  ebx, ecx, 20
+    and   ecx, 0fh
+    mov   bx, cx
+    mov   @jmp_addr, ebx
+    retf
+@@:
+    DB    0b8h, 30h, 0      ; mov ax, 30h as selector
+    mov   ds, ax
+    mov   es, ax
+    mov   fs, ax
+    mov   gs, ax
+    mov   ss, ax
+    mov   eax, cr0          ; Get control register 0
+    DB    66h
+    DB    83h, 0e0h, 0feh   ; and    eax, 0fffffffeh  ; Clear PE bit (bit #0)
+    DB    0fh, 22h, 0c0h    ; mov    cr0, eax         ; Activate real mode
+    DB    0eah              ; jmp far @jmp_addr
+@jmp_addr DD  ?
+
+AsmTransferControl  ENDP
+
+    END
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/SetIdtEntry.c b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/SetIdtEntry.c
new file mode 100644
index 0000000000..e234c16f01
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/SetIdtEntry.c
@@ -0,0 +1,57 @@
+/** @file
+Set a IDT entry for debug purpose
+
+Set a IDT entry for interrupt vector 3 for debug purpose for IA32 platform
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "ScriptExecute.h"
+//
+// INTERRUPT_GATE_DESCRIPTOR and SetIdtEntry () are used to setup IDT to do debug
+//
+
+#pragma pack(1)
+
+typedef struct {
+  UINT16  OffsetLow;
+  UINT16  SegmentSelector;
+  UINT16  Attributes;
+  UINT16  OffsetHigh;
+} INTERRUPT_GATE_DESCRIPTOR;
+
+#define INTERRUPT_GATE_ATTRIBUTE   0x8e00
+
+#pragma pack()
+/**
+  Set a IDT entry for interrupt vector 3 for debug purpose.
+
+  @param  AcpiS3Context  a pointer to a structure of ACPI_S3_CONTEXT
+
+**/
+VOID
+SetIdtEntry (
+  IN ACPI_S3_CONTEXT     *AcpiS3Context
+  )
+{
+  INTERRUPT_GATE_DESCRIPTOR                     *IdtEntry;
+  IA32_DESCRIPTOR                               *IdtDescriptor;
+  UINTN                                         S3DebugBuffer;
+
+  //
+  // Restore IDT for debug
+  //
+  IdtDescriptor = (IA32_DESCRIPTOR *) (UINTN) (AcpiS3Context->IdtrProfile);
+  IdtEntry = (INTERRUPT_GATE_DESCRIPTOR *)(IdtDescriptor->Base + (3 * sizeof (INTERRUPT_GATE_DESCRIPTOR)));
+  S3DebugBuffer = (UINTN) (AcpiS3Context->S3DebugBufferAddress);
+
+  IdtEntry->OffsetLow       = (UINT16)S3DebugBuffer;
+  IdtEntry->SegmentSelector = (UINT16)AsmReadCs ();
+  IdtEntry->Attributes      = (UINT16)INTERRUPT_GATE_ATTRIBUTE;
+  IdtEntry->OffsetHigh      = (UINT16)(S3DebugBuffer >> 16);
+
+  AsmWriteIdtr (IdtDescriptor);
+}
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/ScriptExecute.c b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/ScriptExecute.c
new file mode 100644
index 0000000000..bfd273f142
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/ScriptExecute.c
@@ -0,0 +1,379 @@
+/** @file
+This is the code for Boot Script Executer module.
+
+This driver is dispatched by Dxe core and the driver will reload itself to ACPI NVS memory
+in the entry point. The functionality is to interpret and restore the S3 boot script
+
+Copyright (c) 2013-2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "ScriptExecute.h"
+
+#pragma pack(1)
+typedef union {
+  struct {
+    UINT32  LimitLow    : 16;
+    UINT32  BaseLow     : 16;
+    UINT32  BaseMid     : 8;
+    UINT32  Type        : 4;
+    UINT32  System      : 1;
+    UINT32  Dpl         : 2;
+    UINT32  Present     : 1;
+    UINT32  LimitHigh   : 4;
+    UINT32  Software    : 1;
+    UINT32  Reserved    : 1;
+    UINT32  DefaultSize : 1;
+    UINT32  Granularity : 1;
+    UINT32  BaseHigh    : 8;
+  } Bits;
+  UINT64  Uint64;
+} IA32_GDT;
+
+#pragma pack()
+
+EFI_GUID              mBootScriptExecutorImageGuid = {
+  0x9a8d3433, 0x9fe8, 0x42b6, {0x87, 0xb, 0x1e, 0x31, 0xc8, 0x4e, 0xbe, 0x3b}
+};
+
+//
+// Global Descriptor Table (GDT)
+//
+GLOBAL_REMOVE_IF_UNREFERENCED IA32_GDT mGdtEntries[] = {
+/* selector { Global Segment Descriptor                              } */
+/* 0x00 */  {{0,      0,  0,  0,    0,  0,  0,  0,    0,  0, 0,  0,  0}},
+/* 0x08 */  {{0,      0,  0,  0,    0,  0,  0,  0,    0,  0, 0,  0,  0}},
+/* 0x10 */  {{0xFFFF, 0,  0,  0xB,  1,  0,  1,  0xF,  0,  0, 1,  1,  0}},
+/* 0x18 */  {{0xFFFF, 0,  0,  0x3,  1,  0,  1,  0xF,  0,  0, 1,  1,  0}},
+/* 0x20 */  {{0,      0,  0,  0,    0,  0,  0,  0,    0,  0, 0,  0,  0}},
+/* 0x28 */  {{0xFFFF, 0,  0,  0xB,  1,  0,  1,  0xF,  0,  0, 0,  1,  0}},
+/* 0x30 */  {{0xFFFF, 0,  0,  0x3,  1,  0,  1,  0xF,  0,  0, 0,  1,  0}},
+/* 0x38 */  {{0xFFFF, 0,  0,  0xB,  1,  0,  1,  0xF,  0,  1, 0,  1,  0}},
+/* 0x40 */  {{0,      0,  0,  0,    0,  0,  0,  0,    0,  0, 0,  0,  0}},
+};
+
+//
+// IA32 Gdt register
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST IA32_DESCRIPTOR mGdt = {
+  sizeof (mGdtEntries) - 1,
+  (UINTN) mGdtEntries
+  };
+
+/**
+  Entry function of Boot script exector. This function will be executed in
+  S3 boot path.
+  This function should not return, because it is invoked by switch stack.
+
+  @param  AcpiS3Context    a pointer to a structure of ACPI_S3_CONTEXT
+  @param  PeiS3ResumeState a pointer to a structure of PEI_S3_RESUME_STATE
+
+  @retval EFI_INVALID_PARAMETER - OS waking vector not found
+  @retval EFI_UNSUPPORTED - something wrong when we resume to OS
+**/
+EFI_STATUS
+EFIAPI
+S3BootScriptExecutorEntryFunction (
+  IN ACPI_S3_CONTEXT       *AcpiS3Context,
+  IN PEI_S3_RESUME_STATE   *PeiS3ResumeState
+  )
+{
+  EFI_STATUS                                    Status;
+
+  //
+  // Disable interrupt of Debug timer, since new IDT table cannot handle it.
+  //
+  SaveAndSetDebugTimerInterrupt (FALSE);
+
+  //
+  // Restore IDT for debug
+  //
+  SetIdtEntry (AcpiS3Context);
+
+  //
+  // Initialize Debug Agent to support source level debug in S3 path.
+  //
+  InitializeDebugAgent (DEBUG_AGENT_INIT_S3, NULL, NULL);
+
+  //
+  // Because not install BootScriptExecute PPI(used just in this module), So just pass NULL
+  // for that parameter.
+  //
+  Status = S3BootScriptExecute ();
+
+  AsmWbinvd ();
+
+  //
+  // We need turn back to S3Resume - install boot script done ppi and report status code on S3resume.
+  //
+  if (PeiS3ResumeState != 0) {
+    //
+    // Need report status back to S3ResumePeim.
+    // If boot script execution is failed, S3ResumePeim wil report the error status code.
+    //
+    PeiS3ResumeState->ReturnStatus = (UINT64)(UINTN)Status;
+    //
+    // IA32 S3 Resume
+    //
+    DEBUG ((EFI_D_INFO, "Call SwitchStack() to return to S3 Resume in PEI Phase\n"));
+    PeiS3ResumeState->AsmTransferControl = (EFI_PHYSICAL_ADDRESS)(UINTN)PlatformTransferControl16;
+
+    SwitchStack (
+      (SWITCH_STACK_ENTRY_POINT)(UINTN)PeiS3ResumeState->ReturnEntryPoint,
+      (VOID *)(UINTN)AcpiS3Context,
+      (VOID *)(UINTN)PeiS3ResumeState,
+      (VOID *)(UINTN)PeiS3ResumeState->ReturnStackPointer
+      );
+
+    //
+    // Never run to here
+    //
+    CpuDeadLoop();
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Never run to here
+  //
+  CpuDeadLoop();
+  return EFI_UNSUPPORTED;
+}
+/**
+  Entrypoint of Boot script exector driver, this function will be executed in
+  normal boot phase and invoked by DXE dispatch.
+
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
+  @param[in] SystemTable    A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS       The entry point is executed successfully.
+  @retval other             Some error occurs when executing this entry point.
+**/
+EFI_STATUS
+EFIAPI
+BootScriptExecutorEntryPoint (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+  UINT8                                         *Buffer;
+  UINTN                                         BufferSize;
+  UINTN                                         Pages;
+  EFI_PHYSICAL_ADDRESS                          FfsBuffer;
+  PE_COFF_LOADER_IMAGE_CONTEXT                  ImageContext;
+  BOOT_SCRIPT_EXECUTOR_VARIABLE                 *EfiBootScriptExecutorVariable;
+  EFI_PHYSICAL_ADDRESS                          BootScriptExecutorBuffer;
+  EFI_STATUS                                    Status;
+  VOID                                          *DevicePath;
+  EFI_HANDLE                                    NewImageHandle;
+
+  //
+  // Test if the gEfiCallerIdGuid of this image is already installed. if not, the entry
+  // point is loaded by DXE code which is the first time loaded. or else, it is already
+  // be reloaded be itself.This is a work-around
+  //
+  Status = gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, &DevicePath);
+  if (EFI_ERROR (Status)) {
+
+      //
+      // This is the first-time loaded by DXE core. reload itself to NVS mem
+      //
+      //
+      // A workarouond: Here we install a dummy handle
+      //
+      NewImageHandle = NULL;
+      Status = gBS->InstallProtocolInterface (
+                  &NewImageHandle,
+                  &gEfiCallerIdGuid,
+                  EFI_NATIVE_INTERFACE,
+                  NULL
+                  );
+
+      Status = GetSectionFromAnyFv  (
+                 &gEfiCallerIdGuid,
+                 EFI_SECTION_PE32,
+                 0,
+                 (VOID **) &Buffer,
+                 &BufferSize
+                 );
+      ImageContext.Handle    = Buffer;
+      ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
+      //
+      // Get information about the image being loaded
+      //
+      Status = PeCoffLoaderGetImageInfo (&ImageContext);
+      if (EFI_ERROR (Status)) {
+        return Status;
+      }
+      Pages = EFI_SIZE_TO_PAGES(BufferSize + ImageContext.SectionAlignment);
+      FfsBuffer = 0xFFFFFFFF;
+      Status = gBS->AllocatePages (
+                    AllocateMaxAddress,
+                    EfiACPIMemoryNVS,
+                    Pages,
+                    &FfsBuffer
+                    );
+      if (EFI_ERROR (Status)) {
+        return EFI_OUT_OF_RESOURCES;
+      }
+      ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer;
+      //
+      // Align buffer on section boundary
+      //
+      ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
+      ImageContext.ImageAddress &= ~(ImageContext.SectionAlignment - 1);
+      //
+      // Load the image to our new buffer
+      //
+      Status = PeCoffLoaderLoadImage (&ImageContext);
+      if (EFI_ERROR (Status)) {
+        gBS->FreePages (FfsBuffer, Pages);
+        return Status;
+      }
+
+      //
+      // Relocate the image in our new buffer
+      //
+      Status = PeCoffLoaderRelocateImage (&ImageContext);
+
+      if (EFI_ERROR (Status)) {
+        PeCoffLoaderUnloadImage (&ImageContext);
+        gBS->FreePages (FfsBuffer, Pages);
+        return Status;
+      }
+      //
+      // Flush the instruction cache so the image data is written before we execute it
+      //
+      InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
+      Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint)) (NewImageHandle, SystemTable);
+      if (EFI_ERROR (Status)) {
+        gBS->FreePages (FfsBuffer, Pages);
+        return Status;
+      }
+      //
+      // Additional step for BootScript integrity
+      // Save BootScriptExecutor image
+      //
+      Status = SaveLockBox (
+                 &mBootScriptExecutorImageGuid,
+                 (VOID *)(UINTN)ImageContext.ImageAddress,
+                 (UINTN)ImageContext.ImageSize
+                 );
+      ASSERT_EFI_ERROR (Status);
+
+      Status = SetLockBoxAttributes (&mBootScriptExecutorImageGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
+      ASSERT_EFI_ERROR (Status);
+
+    } else {
+      //
+      // the entry point is invoked after reloading. following code only run in  ACPI NVS
+      //
+      BufferSize = sizeof (BOOT_SCRIPT_EXECUTOR_VARIABLE);
+
+      BootScriptExecutorBuffer = 0xFFFFFFFF;
+      Pages = EFI_SIZE_TO_PAGES(BufferSize);
+      Status = gBS->AllocatePages (
+                      AllocateMaxAddress,
+                      EfiACPIMemoryNVS,
+                      Pages,
+                      &BootScriptExecutorBuffer
+                      );
+      if (EFI_ERROR (Status)) {
+        return EFI_OUT_OF_RESOURCES;
+      }
+
+      EfiBootScriptExecutorVariable = (BOOT_SCRIPT_EXECUTOR_VARIABLE *)(UINTN)BootScriptExecutorBuffer;
+      EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint = (UINTN) S3BootScriptExecutorEntryFunction ;
+
+      Status = SaveLockBox (
+                 &gEfiBootScriptExecutorVariableGuid,
+                 &BootScriptExecutorBuffer,
+                 sizeof(BootScriptExecutorBuffer)
+                 );
+      ASSERT_EFI_ERROR (Status);
+
+      //
+      // Additional step for BootScript integrity
+      // Save BootScriptExecutor context
+      //
+      Status = SaveLockBox (
+                 &gEfiBootScriptExecutorContextGuid,
+                 EfiBootScriptExecutorVariable,
+                 sizeof(*EfiBootScriptExecutorVariable)
+                 );
+      ASSERT_EFI_ERROR (Status);
+
+      Status = SetLockBoxAttributes (&gEfiBootScriptExecutorContextGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
+      ASSERT_EFI_ERROR (Status);
+
+    }
+
+    return EFI_SUCCESS;
+}
+
+/**
+  Platform specific mechanism to transfer control to 16bit OS waking vector
+
+  @param[in] AcpiWakingVector    The 16bit OS waking vector
+  @param[in] AcpiLowMemoryBase   A buffer under 1M which could be used during the transfer
+
+**/
+VOID
+PlatformTransferControl16 (
+  IN UINT32       AcpiWakingVector,
+  IN UINT32       AcpiLowMemoryBase
+  )
+{
+  UINT32      NewValue;
+  UINT64      BaseAddress;
+  UINT64      SmramLength;
+  UINTN       Index;
+
+  DEBUG (( EFI_D_INFO, "PlatformTransferControl - Entry\r\n"));
+
+  //
+  // Need to make sure the GDT is loaded with values that support long mode and real mode.
+  //
+  AsmWriteGdtr (&mGdt);
+
+  //
+  // Disable eSram block (this will also clear/zero eSRAM)
+  // We only use eSRAM in the PEI phase. Disable now that we are resuming the OS
+  //
+  NewValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_ESRAMPGCTRL_BLOCK);
+  NewValue |= BLOCK_DISABLE_PG;
+  QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_ESRAMPGCTRL_BLOCK, NewValue);
+
+  //
+  // Update HMBOUND to top of DDR3 memory and LOCK
+  // We disabled eSRAM so now we move HMBOUND down to top of DDR3
+  //
+  QNCGetTSEGMemoryRange (&BaseAddress, &SmramLength);
+  NewValue = (UINT32)(BaseAddress + SmramLength);
+  DEBUG ((EFI_D_INFO,"Locking HMBOUND at: = 0x%8x\n",NewValue));
+  QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QUARK_NC_HOST_BRIDGE_HMBOUND_REG, (NewValue | HMBOUND_LOCK));
+
+  //
+  // Lock all IMR regions now that HMBOUND is locked
+  //
+  for (Index = (QUARK_NC_MEMORY_MANAGER_IMR0+QUARK_NC_MEMORY_MANAGER_IMRXL); Index <= (QUARK_NC_MEMORY_MANAGER_IMR7+QUARK_NC_MEMORY_MANAGER_IMRXL); Index += 4) {
+    NewValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, Index);
+    NewValue |= IMR_LOCK;
+    QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, Index, NewValue);
+  }
+
+  //
+  // Call ASM routine to switch to real mode and jump to 16bit OS waking vector
+  //
+  AsmTransferControl(AcpiWakingVector, 0);
+
+  //
+  // Never run to here
+  //
+  CpuDeadLoop();
+}
+
+
+
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/ScriptExecute.h b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/ScriptExecute.h
new file mode 100644
index 0000000000..f2d83b2687
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/ScriptExecute.h
@@ -0,0 +1,70 @@
+/** @file
+The header file for Boot Script Executer module.
+
+This driver is dispatched by Dxe core and the driver will reload itself to ACPI NVS memory
+in the entry point. The functionality is to interpret and restore the S3 boot script
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef _SCRIPT_EXECUTE_H_
+#define _SCRIPT_EXECUTE_H_
+
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/PeCoffLib.h>
+#include <Library/DxeServicesLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/PcdLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/TimerLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugAgentLib.h>
+#include <Library/LockBoxLib.h>
+#include <Library/IntelQNCLib.h>
+#include <Library/QNCAccessLib.h>
+
+#include <Guid/AcpiS3Context.h>
+#include <Guid/BootScriptExecutorVariable.h>
+#include <Guid/EventGroup.h>
+#include <IndustryStandard/Acpi.h>
+
+/**
+  a ASM function to transfer control to OS.
+
+  @param  S3WakingVector  The S3 waking up vector saved in ACPI Facs table
+  @param  AcpiLowMemoryBase a buffer under 1M which could be used during the transfer
+**/
+VOID
+AsmTransferControl (
+  IN   UINT32           S3WakingVector,
+  IN   UINT32           AcpiLowMemoryBase
+  );
+
+VOID
+SetIdtEntry (
+  IN ACPI_S3_CONTEXT     *AcpiS3Context
+  );
+
+/**
+  Platform specific mechanism to transfer control to 16bit OS waking vector
+
+  @param[in] AcpiWakingVector    The 16bit OS waking vector
+  @param[in] AcpiLowMemoryBase   A buffer under 1M which could be used during the transfer
+
+**/
+VOID
+PlatformTransferControl16 (
+  IN UINT32       AcpiWakingVector,
+  IN UINT32       AcpiLowMemoryBase
+  );
+
+#endif //_SCRIPT_EXECUTE_H_
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.c b/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.c
new file mode 100644
index 0000000000..f7f7ca3196
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.c
@@ -0,0 +1,1011 @@
+/** @file
+ACPISMM Driver implementation file.
+
+This is QNC Smm platform driver
+
+Copyright (c) 2013-2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#include <AcpiSmmPlatform.h>
+
+#define PCILIB_TO_COMMON_ADDRESS(Address) \
+        ((UINT64) ((((UINTN) ((Address>>20) & 0xff)) << 24) + (((UINTN) ((Address>>15) & 0x1f)) << 16) + (((UINTN) ((Address>>12) & 0x07)) << 8) + ((UINTN) (Address & 0xfff ))))
+
+//
+// Modular variables needed by this driver
+//
+EFI_ACPI_SMM_DEV                 mAcpiSmm;
+
+UINT8  mPciCfgRegTable[] = {
+  //
+  // Logic to decode the table masks to arrive at the registers saved
+  // Dword Registers are saved. For a given mask, the Base+offset register
+  // will be saved as in the table below.
+  // (example) To save register 0x24, 0x28 the mask at the Base 0x20 will be 0x06
+  //     Base      0x00   0x20   0x40  0x60  0x80  0xA0  0xC0  0xE0
+  // Mask  offset
+  // 0x01   0x00
+  // 0x02   0x04
+  // 0x04   0x08
+  // 0x08   0x0C
+  // 0x10   0x10
+  // 0x20   0x14
+  // 0x40   0x18
+  // 0x80   0x1C
+  //
+
+  //
+  // Bus,   Dev,  Func,
+  // 00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+  // Only Bus 0 device is supported now
+  //
+
+  //
+  // Quark South Cluster devices
+  //
+  PCI_DEVICE   (0, 20, 0),
+  PCI_REG_MASK (0x18, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
+
+  PCI_DEVICE   (0, 20, 1),
+  PCI_REG_MASK (0x38, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
+
+  PCI_DEVICE   (0, 20, 2),
+  PCI_REG_MASK (0x18, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
+
+  PCI_DEVICE   (0, 20, 3),
+  PCI_REG_MASK (0x18, 0x98, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00),
+
+  PCI_DEVICE   (0, 20, 4),
+  PCI_REG_MASK (0x18, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
+
+  PCI_DEVICE   (0, 20, 5),
+  PCI_REG_MASK (0x38, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
+
+  PCI_DEVICE   (0, 20, 6),
+  PCI_REG_MASK (0x18, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
+
+  PCI_DEVICE   (0, 20, 7),
+  PCI_REG_MASK (0x18, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
+
+  PCI_DEVICE   (0, 21, 0),
+  PCI_REG_MASK (0x18, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
+
+  PCI_DEVICE   (0, 21, 1),
+  PCI_REG_MASK (0x18, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
+
+  PCI_DEVICE   (0, 21, 2),
+  PCI_REG_MASK (0x38, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
+
+  //
+  // Quark North Cluster devices
+  //
+  PCI_DEVICE   (0, 0, 0),
+  PCI_REG_MASK (0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
+
+  PCI_DEVICE   (0, 23, 0),
+  PCI_REG_MASK (0xC0, 0x8F, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00),
+
+  PCI_DEVICE   (0, 23, 1),
+  PCI_REG_MASK (0xC0, 0x8F, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00),
+
+  PCI_DEVICE   (0, 31, 0),
+  PCI_REG_MASK (0x00, 0x08, 0x4E, 0x03, 0x02, 0x00, 0x60, 0x10),
+
+  PCI_DEVICE_END
+};
+
+EFI_PLATFORM_TYPE                         mPlatformType;
+
+  // These registers have to set in byte order
+const UINT8  QNCS3SaveExtReg[] = {
+    QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HSMMC, // SMRAM settings
+
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR0+QUARK_NC_MEMORY_MANAGER_IMRXL,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR0+QUARK_NC_MEMORY_MANAGER_IMRXH,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR0+QUARK_NC_MEMORY_MANAGER_IMRXRM,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR0+QUARK_NC_MEMORY_MANAGER_IMRXWM,
+
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR1+QUARK_NC_MEMORY_MANAGER_IMRXL,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR1+QUARK_NC_MEMORY_MANAGER_IMRXH,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR1+QUARK_NC_MEMORY_MANAGER_IMRXRM,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR1+QUARK_NC_MEMORY_MANAGER_IMRXWM,
+
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR2+QUARK_NC_MEMORY_MANAGER_IMRXL,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR2+QUARK_NC_MEMORY_MANAGER_IMRXH,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR2+QUARK_NC_MEMORY_MANAGER_IMRXRM,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR2+QUARK_NC_MEMORY_MANAGER_IMRXWM,
+
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR3+QUARK_NC_MEMORY_MANAGER_IMRXL,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR3+QUARK_NC_MEMORY_MANAGER_IMRXH,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR3+QUARK_NC_MEMORY_MANAGER_IMRXRM,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR3+QUARK_NC_MEMORY_MANAGER_IMRXWM,
+
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR4+QUARK_NC_MEMORY_MANAGER_IMRXL,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR4+QUARK_NC_MEMORY_MANAGER_IMRXH,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR4+QUARK_NC_MEMORY_MANAGER_IMRXRM,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR4+QUARK_NC_MEMORY_MANAGER_IMRXWM,
+
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR5+QUARK_NC_MEMORY_MANAGER_IMRXL,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR5+QUARK_NC_MEMORY_MANAGER_IMRXH,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR5+QUARK_NC_MEMORY_MANAGER_IMRXRM,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR5+QUARK_NC_MEMORY_MANAGER_IMRXWM,
+
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR6+QUARK_NC_MEMORY_MANAGER_IMRXL,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR6+QUARK_NC_MEMORY_MANAGER_IMRXH,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR6+QUARK_NC_MEMORY_MANAGER_IMRXRM,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR6+QUARK_NC_MEMORY_MANAGER_IMRXWM,
+
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR7+QUARK_NC_MEMORY_MANAGER_IMRXL,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR7+QUARK_NC_MEMORY_MANAGER_IMRXH,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR7+QUARK_NC_MEMORY_MANAGER_IMRXRM,
+    QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR7+QUARK_NC_MEMORY_MANAGER_IMRXWM,
+
+    QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_ECC_SCRUB_END_MEM_REG, // ECC Scrub settings
+    QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_ECC_SCRUB_START_MEM_REG,
+    QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_ECC_SCRUB_NEXT_READ_REG,
+    QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_ECC_SCRUB_CONFIG_REG,
+
+    0xFF
+    };
+
+/**
+  Allocate EfiACPIMemoryNVS below 4G memory address.
+
+  This function allocates EfiACPIMemoryNVS below 4G memory address.
+
+  @param Size   Size of memory to allocate.
+
+  @return       Allocated address for output.
+
+**/
+VOID*
+AllocateAcpiNvsMemoryBelow4G (
+  IN UINTN  Size
+  )
+{
+  UINTN                 Pages;
+  EFI_PHYSICAL_ADDRESS  Address;
+  EFI_STATUS            Status;
+  VOID*                 Buffer;
+
+  Pages = EFI_SIZE_TO_PAGES (Size);
+  Address = 0xffffffff;
+
+  Status  = gBS->AllocatePages (
+                   AllocateMaxAddress,
+                   EfiACPIMemoryNVS,
+                   Pages,
+                   &Address
+                   );
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+
+  Buffer = (VOID *) (UINTN) Address;
+  ZeroMem (Buffer, Size);
+
+  return Buffer;
+}
+
+EFI_STATUS
+EFIAPI
+ReservedS3Memory (
+  UINTN  SystemMemoryLength
+
+  )
+/*++
+
+Routine Description:
+
+  Reserved S3 memory for InstallS3Memory
+
+Arguments:
+
+
+Returns:
+
+  EFI_OUT_OF_RESOURCES  -  Insufficient resources to complete function.
+  EFI_SUCCESS           -  Function has completed successfully.
+
+--*/
+{
+
+  VOID                                      *GuidHob;
+  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK            *DescriptorBlock;
+  VOID                                      *AcpiReservedBase;
+
+  UINTN                                     TsegIndex;
+  UINTN                                     TsegSize;
+  UINTN                                     TsegBase;
+  RESERVED_ACPI_S3_RANGE                    *AcpiS3Range;
+  //
+  // Get Hob list for SMRAM desc
+  //
+  GuidHob    = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid);
+  ASSERT (GuidHob);
+  DescriptorBlock = GET_GUID_HOB_DATA (GuidHob);
+  ASSERT (DescriptorBlock);
+
+  //
+  // Use the hob to get SMRAM capabilities
+  //
+  TsegIndex = DescriptorBlock->NumberOfSmmReservedRegions - 1;
+  ASSERT (TsegIndex <= (MAX_SMRAM_RANGES - 1));
+  TsegBase  = (UINTN)DescriptorBlock->Descriptor[TsegIndex].PhysicalStart;
+  TsegSize  = (UINTN)DescriptorBlock->Descriptor[TsegIndex].PhysicalSize;
+
+  DEBUG ((EFI_D_INFO, "SMM  Base: %08X\n", TsegBase));
+  DEBUG ((EFI_D_INFO, "SMM  Size: %08X\n", TsegSize));
+
+  //
+  // Now find the location of the data structure that is used to store the address
+  // of the S3 reserved memory.
+  //
+  AcpiS3Range = (RESERVED_ACPI_S3_RANGE*) (UINTN) (TsegBase + RESERVED_ACPI_S3_RANGE_OFFSET);
+
+  //
+  // Allocate reserved ACPI memory for S3 resume.  Pointer to this region is
+  // stored in SMRAM in the first page of TSEG.
+  //
+  AcpiReservedBase = AllocateAcpiNvsMemoryBelow4G (PcdGet32 (PcdS3AcpiReservedMemorySize));
+  if (AcpiReservedBase != NULL) {
+    AcpiS3Range->AcpiReservedMemoryBase = (UINT32)(UINTN) AcpiReservedBase;
+    AcpiS3Range->AcpiReservedMemorySize = PcdGet32 (PcdS3AcpiReservedMemorySize);
+  }
+  AcpiS3Range->SystemMemoryLength = (UINT32)SystemMemoryLength;
+
+  DEBUG ((EFI_D_INFO, "S3 Memory  Base:    %08X\n", AcpiS3Range->AcpiReservedMemoryBase));
+  DEBUG ((EFI_D_INFO, "S3 Memory  Size:    %08X\n", AcpiS3Range->AcpiReservedMemorySize));
+  DEBUG ((EFI_D_INFO, "S3 SysMemoryLength: %08X\n", AcpiS3Range->SystemMemoryLength));
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+InitAcpiSmmPlatform (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+/*++
+
+Routine Description:
+
+  Initializes the SMM S3 Handler Driver.
+
+Arguments:
+
+  ImageHandle  -  The image handle of Sleep State Wake driver.
+  SystemTable  -  The starndard EFI system table.
+
+Returns:
+
+  EFI_OUT_OF_RESOURCES  -  Insufficient resources to complete function.
+  EFI_SUCCESS           -  Function has completed successfully.
+  Other                 -  Error occured during execution.
+
+--*/
+{
+  EFI_STATUS                      Status;
+  EFI_GLOBAL_NVS_AREA_PROTOCOL    *AcpiNvsProtocol = NULL;
+  UINTN                           MemoryLength;
+  EFI_PEI_HOB_POINTERS            Hob;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiGlobalNvsAreaProtocolGuid,
+                  NULL,
+                  (VOID **) &AcpiNvsProtocol
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  mAcpiSmm.BootScriptSaved  = 0;
+
+  mPlatformType = (EFI_PLATFORM_TYPE)PcdGet16 (PcdPlatformType);
+
+  //
+  // Calculate the system memory length by memory hobs
+  //
+  MemoryLength  = 0x100000;
+  Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
+  ASSERT (Hob.Raw != NULL);
+  while ((Hob.Raw != NULL) && (!END_OF_HOB_LIST (Hob))) {
+    if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
+      //
+      // Skip the memory region below 1MB
+      //
+      if (Hob.ResourceDescriptor->PhysicalStart >= 0x100000) {
+        MemoryLength += (UINTN)Hob.ResourceDescriptor->ResourceLength;
+      }
+    }
+    Hob.Raw = GET_NEXT_HOB (Hob);
+    Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
+  }
+
+  ReservedS3Memory(MemoryLength);
+
+  //
+  // Locate and Register to Parent driver
+  //
+  Status = RegisterToDispatchDriver ();
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+RegisterToDispatchDriver (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Register to dispatch driver.
+
+Arguments:
+
+  None.
+
+Returns:
+
+  EFI_SUCCESS  -  Successfully init the device.
+  Other        -  Error occured whening calling Dxe lib functions.
+
+--*/
+{
+  UINTN                         Length;
+  EFI_STATUS                    Status;
+  EFI_SMM_SX_DISPATCH2_PROTOCOL  *SxDispatch;
+  EFI_SMM_SW_DISPATCH2_PROTOCOL  *SwDispatch;
+  EFI_SMM_SX_REGISTER_CONTEXT   *EntryDispatchContext;
+  EFI_SMM_SX_REGISTER_CONTEXT   *EntryS1DispatchContext;
+  EFI_SMM_SX_REGISTER_CONTEXT   *EntryS3DispatchContext;
+  EFI_SMM_SX_REGISTER_CONTEXT   *EntryS4DispatchContext;
+  EFI_SMM_SX_REGISTER_CONTEXT   *EntryS5DispatchContext;
+  EFI_SMM_SW_REGISTER_CONTEXT   *SwContext;
+  EFI_SMM_SW_REGISTER_CONTEXT   *AcpiDisableSwContext;
+  EFI_SMM_SW_REGISTER_CONTEXT   *AcpiEnableSwContext;
+
+  Status = gSmst->SmmLocateProtocol (
+                  &gEfiSmmSxDispatch2ProtocolGuid,
+                  NULL,
+                  (VOID **) &SxDispatch
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = gSmst->SmmLocateProtocol (
+                  &gEfiSmmSwDispatch2ProtocolGuid,
+                  NULL,
+                  (VOID **) &SwDispatch
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Length = sizeof (EFI_SMM_SX_REGISTER_CONTEXT) * 4 + sizeof (EFI_SMM_SW_REGISTER_CONTEXT) * 2;
+  Status = gSmst->SmmAllocatePool (
+                      EfiRuntimeServicesData,
+                      Length,
+                      (VOID **) &EntryDispatchContext
+                      );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  SetMem (EntryDispatchContext, Length, 0);
+
+  EntryS1DispatchContext  = EntryDispatchContext++;
+  EntryS3DispatchContext  = EntryDispatchContext++;
+  EntryS4DispatchContext  = EntryDispatchContext++;
+  EntryS5DispatchContext  = EntryDispatchContext++;
+
+  SwContext = (EFI_SMM_SW_REGISTER_CONTEXT *)EntryDispatchContext;
+  AcpiDisableSwContext = SwContext++;
+  AcpiEnableSwContext  = SwContext++;
+
+  //
+  // Register the enable handler
+  //
+  AcpiEnableSwContext->SwSmiInputValue = EFI_ACPI_ACPI_ENABLE;
+  Status = SwDispatch->Register (
+                        SwDispatch,
+                        EnableAcpiCallback,
+                        AcpiEnableSwContext,
+                        &(mAcpiSmm.DisableAcpiHandle)
+                        );
+
+  //
+  // Register the disable handler
+  //
+  AcpiDisableSwContext->SwSmiInputValue = EFI_ACPI_ACPI_DISABLE;
+  Status = SwDispatch->Register (
+                        SwDispatch,
+                        DisableAcpiCallback,
+                        AcpiDisableSwContext,
+                        &(mAcpiSmm.EnableAcpiHandle)
+                        );
+
+
+  //
+  // Register entry phase call back function for S1
+  //
+  EntryS1DispatchContext->Type  = SxS1;
+  EntryS1DispatchContext->Phase = SxEntry;
+  Status = SxDispatch->Register (
+                        SxDispatch,
+                        SxSleepEntryCallBack,
+                        EntryS1DispatchContext,
+                        &(mAcpiSmm.S1SleepEntryHandle)
+                        );
+
+  //
+  // Register entry phase call back function
+  //
+  EntryS3DispatchContext->Type  = SxS3;
+  EntryS3DispatchContext->Phase = SxEntry;
+  Status = SxDispatch->Register (
+                        SxDispatch,
+                        SxSleepEntryCallBack,
+                        EntryS3DispatchContext,
+                        &(mAcpiSmm.S3SleepEntryHandle)
+                        );
+
+  //
+  // Register entry phase call back function for S4
+  //
+  EntryS4DispatchContext->Type  = SxS4;
+  EntryS4DispatchContext->Phase = SxEntry;
+  Status = SxDispatch->Register (
+                        SxDispatch,
+                        SxSleepEntryCallBack,
+                        EntryS4DispatchContext,
+                        &(mAcpiSmm.S4SleepEntryHandle)
+                        );
+
+  //
+  // Register callback for S5 in order to workaround the LAN shutdown issue
+  //
+  EntryS5DispatchContext->Type  = SxS5;
+  EntryS5DispatchContext->Phase = SxEntry;
+  Status = SxDispatch->Register (
+                        SxDispatch,
+                        SxSleepEntryCallBack,
+                        EntryS5DispatchContext,
+                        &(mAcpiSmm.S5SoftOffEntryHandle)
+                        );
+
+  return Status;
+}
+
+
+EFI_STATUS
+RestoreQncS3SwCallback (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  CONST VOID                    *DispatchContext,
+  IN  OUT VOID                      *CommBuffer,
+  IN  OUT UINTN                     *CommBufferSize
+  )
+/*++
+
+Routine Description:
+  SMI handler to restore QncS3 code & context for S3 path
+  This will be only triggered when BootScript got executed during resume
+
+Arguments:
+  DispatchHandle  - EFI Handle
+  DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT
+
+Returns:
+  Nothing
+
+--*/
+{
+  //
+  // Restore to original address by default
+  //
+  RestoreLockBox(&gQncS3CodeInLockBoxGuid, NULL, NULL);
+  RestoreLockBox(&gQncS3ContextInLockBoxGuid, NULL, NULL);
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DisableAcpiCallback (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  CONST VOID                    *DispatchContext,
+  IN  OUT VOID                      *CommBuffer,
+  IN  OUT UINTN                     *CommBufferSize
+  )
+/*++
+
+Routine Description:
+  SMI handler to disable ACPI mode
+
+  Dispatched on reads from APM port with value 0xA1
+
+  ACPI events are disabled and ACPI event status is cleared.
+  SCI mode is then disabled.
+   Clear all ACPI event status and disable all ACPI events
+   Disable PM sources except power button
+   Clear status bits
+   Disable GPE0 sources
+   Clear status bits
+   Disable GPE1 sources
+   Clear status bits
+   Disable SCI
+
+Arguments:
+  DispatchHandle  - EFI Handle
+  DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT
+
+Returns:
+  Nothing
+
+--*/
+{
+  EFI_STATUS  Status;
+  UINT16      Pm1Cnt;
+
+  Status = GetAllQncPmBase (gSmst);
+  ASSERT_EFI_ERROR (Status);
+  Pm1Cnt = IoRead16 (mAcpiSmm.QncPmBase + R_QNC_PM1BLK_PM1C);
+
+  //
+  // Disable SCI
+  //
+  Pm1Cnt &= ~B_QNC_PM1BLK_PM1C_SCIEN;
+
+  IoWrite16 (mAcpiSmm.QncPmBase + R_QNC_PM1BLK_PM1C, Pm1Cnt);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EnableAcpiCallback (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  CONST VOID                    *DispatchContext,
+  IN  OUT VOID                      *CommBuffer,
+  IN  OUT UINTN                     *CommBufferSize
+  )
+/*++
+
+Routine Description:
+  SMI handler to enable ACPI mode
+
+  Dispatched on reads from APM port with value 0xA0
+
+  Disables the SW SMI Timer.
+  ACPI events are disabled and ACPI event status is cleared.
+  SCI mode is then enabled.
+
+   Disable SW SMI Timer
+
+   Clear all ACPI event status and disable all ACPI events
+   Disable PM sources except power button
+   Clear status bits
+
+   Disable GPE0 sources
+   Clear status bits
+
+   Disable GPE1 sources
+   Clear status bits
+
+   Guarantee day-of-month alarm is invalid (ACPI 1.0 section 4.7.2.4)
+
+   Enable SCI
+
+Arguments:
+  DispatchHandle  - EFI Handle
+  DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT
+
+Returns:
+  Nothing
+
+--*/
+{
+  EFI_STATUS  Status;
+  UINT32      SmiEn;
+  UINT16      Pm1Cnt;
+  UINT8       Data8;
+
+  Status  = GetAllQncPmBase (gSmst);
+  ASSERT_EFI_ERROR (Status);
+
+  SmiEn = IoRead32 (mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_SMIE);
+
+  //
+  // Disable SW SMI Timer
+  //
+  SmiEn &= ~(B_QNC_GPE0BLK_SMIE_SWT);
+  IoWrite32 (mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_SMIE, SmiEn);
+
+  //
+  // Guarantee day-of-month alarm is invalid (ACPI 1.0 section 4.7.2.4)
+  //
+  Data8 = RTC_ADDRESS_REGISTER_D;
+  IoWrite8 (R_IOPORT_CMOS_STANDARD_INDEX, Data8);
+  Data8 = 0x0;
+  IoWrite8 (R_IOPORT_CMOS_STANDARD_DATA, Data8);
+
+  //
+  // Enable SCI
+  //
+  Pm1Cnt = IoRead16 (mAcpiSmm.QncPmBase + R_QNC_PM1BLK_PM1C);
+  Pm1Cnt |= B_QNC_PM1BLK_PM1C_SCIEN;
+  IoWrite16 (mAcpiSmm.QncPmBase + R_QNC_PM1BLK_PM1C, Pm1Cnt);
+
+  //
+  // Do platform specific stuff for ACPI enable SMI
+  //
+
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SxSleepEntryCallBack (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  CONST VOID                    *DispatchContext,
+  IN  OUT VOID                      *CommBuffer,
+  IN  OUT UINTN                     *CommBufferSize
+  )
+/*++
+
+Routine Description:
+
+  Callback function entry for Sx sleep state.
+
+Arguments:
+
+  DispatchHandle   -  The handle of this callback, obtained when registering.
+  DispatchContext  -  The predefined context which contained sleep type and phase.
+
+Returns:
+
+  EFI_SUCCESS            -  Operation successfully performed.
+  EFI_INVALID_PARAMETER  -  Invalid parameter passed in.
+
+--*/
+{
+  EFI_STATUS  Status;
+  UINT8       Data8;
+  UINT16      Data16;
+  UINT32      Data32;
+
+  REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeS3SuspendStart));
+
+  //
+  // Reget QNC power mgmr regs base in case of OS changing it at runtime
+  //
+  Status  = GetAllQncPmBase (gSmst);
+
+  //
+  // Clear RTC Alarm (if set)
+  //
+  Data8 = RTC_ADDRESS_REGISTER_C;
+  IoWrite8 (R_IOPORT_CMOS_STANDARD_INDEX, Data8);
+  Data8 = IoRead8 (R_IOPORT_CMOS_STANDARD_DATA);
+
+  //
+  // Clear all ACPI status bits
+  //
+  Data32 = B_QNC_GPE0BLK_GPE0S_ALL;
+  Status = gSmst->SmmIo.Io.Write( &gSmst->SmmIo, SMM_IO_UINT32, mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_GPE0S, 1, &Data32 );
+  Data16 = B_QNC_PM1BLK_PM1S_ALL;
+  Status = gSmst->SmmIo.Io.Write( &gSmst->SmmIo, SMM_IO_UINT16, mAcpiSmm.QncPmBase + R_QNC_PM1BLK_PM1S, 1, &Data16 );
+
+  //
+  // Handling S1 - setting appropriate wake bits in GPE0_EN
+  //
+  if ((DispatchHandle == mAcpiSmm.S1SleepEntryHandle) && (((EFI_SMM_SX_REGISTER_CONTEXT *)DispatchContext)->Type == SxS1)) {
+    //
+    // Enable bit13 (EGPE), 14 (GPIO) ,17 (PCIE) in GPE0_EN
+    //
+    Status = gSmst->SmmIo.Io.Read( &gSmst->SmmIo, SMM_IO_UINT32, mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_GPE0E, 1, &Data32 );
+    Data32 |= (B_QNC_GPE0BLK_GPE0E_EGPE | B_QNC_GPE0BLK_GPE0E_GPIO | B_QNC_GPE0BLK_GPE0E_PCIE);
+    Status = gSmst->SmmIo.Io.Write( &gSmst->SmmIo, SMM_IO_UINT32, mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_GPE0E, 1, &Data32 );
+
+    //
+    // Enable bit10 (RTC) in PM1E
+    //
+    Status = gSmst->SmmIo.Io.Read( &gSmst->SmmIo, SMM_IO_UINT16, mAcpiSmm.QncPmBase + R_QNC_PM1BLK_PM1E, 1, &Data16 );
+    Data16 |= B_QNC_PM1BLK_PM1E_RTC;
+    Status = gSmst->SmmIo.Io.Write( &gSmst->SmmIo, SMM_IO_UINT16, mAcpiSmm.QncPmBase + R_QNC_PM1BLK_PM1E, 1, &Data16 );
+
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Handling S4, S5 and WOL - setting appropriate wake bits in GPE0_EN
+  //
+  if (((DispatchHandle == mAcpiSmm.S4SleepEntryHandle) && (((EFI_SMM_SX_REGISTER_CONTEXT *)DispatchContext)->Type == SxS4)) ||
+      ((DispatchHandle == mAcpiSmm.S5SoftOffEntryHandle) && (((EFI_SMM_SX_REGISTER_CONTEXT *)DispatchContext)->Type == SxS5))
+     ) {
+    //
+    // Enable bit13 (EGPE), 14 (GPIO) ,17 (PCIE) in GPE0_EN
+    // Enable the WOL bits in GPE0_EN reg here for PME
+    //
+    Status = gSmst->SmmIo.Io.Read( &gSmst->SmmIo, SMM_IO_UINT32, mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_GPE0E, 1, &Data32 );
+    Data32 |= (B_QNC_GPE0BLK_GPE0E_EGPE | B_QNC_GPE0BLK_GPE0E_GPIO | B_QNC_GPE0BLK_GPE0E_PCIE);
+    Status = gSmst->SmmIo.Io.Write( &gSmst->SmmIo, SMM_IO_UINT32, mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_GPE0E, 1, &Data32 );
+
+    //
+    // Enable bit10 (RTC) in PM1E
+    //
+    Status = gSmst->SmmIo.Io.Read( &gSmst->SmmIo, SMM_IO_UINT16, mAcpiSmm.QncPmBase + R_QNC_PM1BLK_PM1E, 1, &Data16 );
+    Data16 |= B_QNC_PM1BLK_PM1E_RTC;
+    Status = gSmst->SmmIo.Io.Write( &gSmst->SmmIo, SMM_IO_UINT16, mAcpiSmm.QncPmBase + R_QNC_PM1BLK_PM1E, 1, &Data16 );
+
+  } else {
+
+    if ((DispatchHandle != mAcpiSmm.S3SleepEntryHandle) || (((EFI_SMM_SX_REGISTER_CONTEXT *)DispatchContext)->Type != SxS3)) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    Status  = SaveRuntimeScriptTable (gSmst);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    //
+    // Enable bit13 (EGPE), 14 (GPIO), 17 (PCIE) in GPE0_EN
+    // Enable the WOL bits in GPE0_EN reg here for PME
+    //
+    Status = gSmst->SmmIo.Io.Read( &gSmst->SmmIo, SMM_IO_UINT32, mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_GPE0E, 1, &Data32 );
+    Data32 |= (B_QNC_GPE0BLK_GPE0E_EGPE | B_QNC_GPE0BLK_GPE0E_GPIO | B_QNC_GPE0BLK_GPE0E_PCIE);
+    Status = gSmst->SmmIo.Io.Write( &gSmst->SmmIo, SMM_IO_UINT32, mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_GPE0E, 1, &Data32 );
+
+    //
+    // Enable bit10 (RTC) in PM1E
+    //
+    Status = gSmst->SmmIo.Io.Read( &gSmst->SmmIo, SMM_IO_UINT16, mAcpiSmm.QncPmBase + R_QNC_PM1BLK_PM1E, 1, &Data16 );
+    Data16 |= B_QNC_PM1BLK_PM1E_RTC;
+    Status = gSmst->SmmIo.Io.Write( &gSmst->SmmIo, SMM_IO_UINT16, mAcpiSmm.QncPmBase + R_QNC_PM1BLK_PM1E, 1, &Data16 );
+  }
+
+  //
+  // When entering a power-managed state like S3,
+  // PERST# must be asserted in advance of power-off.
+  //
+  PlatformPERSTAssert (mPlatformType);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetAllQncPmBase (
+  IN EFI_SMM_SYSTEM_TABLE2       *Smst
+  )
+/*++
+
+Routine Description:
+
+  Get QNC chipset LPC Power Management I/O Base at runtime.
+
+Arguments:
+
+  Smst  -  The standard SMM system table.
+
+Returns:
+
+  EFI_SUCCESS  -  Successfully init the device.
+  Other        -  Error occured whening calling Dxe lib functions.
+
+--*/
+{
+  mAcpiSmm.QncPmBase    = PciRead16 (PCI_LIB_ADDRESS(PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, R_QNC_LPC_PM1BLK)) & B_QNC_LPC_PM1BLK_MASK;
+  mAcpiSmm.QncGpe0Base  = PciRead16 (PCI_LIB_ADDRESS(PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, R_QNC_LPC_GPE0BLK)) & B_QNC_LPC_GPE0BLK_MASK;
+
+  //
+  // Quark does not support Changing Primary SoC IOBARs from what was
+  // setup in SEC/PEI UEFI stages.
+  //
+  ASSERT (mAcpiSmm.QncPmBase == (UINT32) PcdGet16 (PcdPm1blkIoBaseAddress));
+  ASSERT (mAcpiSmm.QncGpe0Base == (UINT32) PcdGet16 (PcdGpe0blkIoBaseAddress));
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SaveRuntimeScriptTable (
+  IN EFI_SMM_SYSTEM_TABLE2       *Smst
+  )
+{
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS  PciAddress;
+  UINT32                Data32;
+  UINT16                Data16;
+  UINT8                 Mask;
+  UINTN                 Index;
+  UINTN                 Offset;
+  UINT16                DeviceId;
+
+  //
+  // Check what Soc we are running on (read Host bridge DeviceId)
+  //
+  DeviceId = QncGetSocDeviceId();
+
+  //
+  // Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by CSM
+  // and vital to S3 resume. That's why we put save code here
+  //
+  Index = 0;
+  while (mPciCfgRegTable[Index] != PCI_DEVICE_END) {
+
+    PciAddress.Bus              = mPciCfgRegTable[Index++];
+    PciAddress.Device           = mPciCfgRegTable[Index++];
+    PciAddress.Function         = mPciCfgRegTable[Index++];
+    PciAddress.Register         = 0;
+    PciAddress.ExtendedRegister = 0;
+
+    Data16 = PciRead16 (PCI_LIB_ADDRESS(PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register));
+    if (Data16 == 0xFFFF) {
+      Index += 8;
+      continue;
+    }
+
+    for (Offset = 0, Mask = 0x01; Offset < 256; Offset += 4, Mask <<= 1) {
+
+      if (Mask == 0x00) {
+        Mask = 0x01;
+      }
+
+      if (mPciCfgRegTable[Index + Offset / 32] & Mask) {
+
+        PciAddress.Register = (UINT8) Offset;
+        Data32 = PciRead32 (PCI_LIB_ADDRESS(PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register));
+
+
+        //
+        // Save latest settings to runtime script table
+        //
+        S3BootScriptSavePciCfgWrite (
+             S3BootScriptWidthUint32,
+             PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register)),
+             1,
+             &Data32
+             );
+      }
+    }
+
+    Index += 8;
+
+  }
+
+  //
+  // Save message bus registers
+  //
+  Index = 0;
+  while (QNCS3SaveExtReg[Index] != 0xFF) {
+    Data32 = QNCPortRead (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]);
+
+    //
+    // Save IMR settings with IMR protection disabled initially
+    // HMBOUND and IMRs will be locked just before jumping to the OS waking vector
+    //
+    if (QNCS3SaveExtReg[Index] == QUARK_NC_MEMORY_MANAGER_SB_PORT_ID) {
+      if ((QNCS3SaveExtReg[Index + 1] >= (QUARK_NC_MEMORY_MANAGER_IMR0+QUARK_NC_MEMORY_MANAGER_IMRXL)) && (QNCS3SaveExtReg[Index + 1] <= (QUARK_NC_MEMORY_MANAGER_IMR7+QUARK_NC_MEMORY_MANAGER_IMRXWM)) && ((QNCS3SaveExtReg[Index + 1] & 0x03) == QUARK_NC_MEMORY_MANAGER_IMRXL)) {
+        Data32 &= ~IMR_LOCK;
+        if (DeviceId == QUARK2_MC_DEVICE_ID) {
+          Data32 &= ~IMR_EN;
+        }
+      }
+      if ((QNCS3SaveExtReg[Index + 1] >= (QUARK_NC_MEMORY_MANAGER_IMR0+QUARK_NC_MEMORY_MANAGER_IMRXRM)) && (QNCS3SaveExtReg[Index + 1] <= (QUARK_NC_MEMORY_MANAGER_IMR7+QUARK_NC_MEMORY_MANAGER_IMRXWM)) && ((QNCS3SaveExtReg[Index + 1] & 0x03) >= QUARK_NC_MEMORY_MANAGER_IMRXRM)) {
+        Data32 = (UINT32)IMRX_ALL_ACCESS;
+      }
+    }
+
+    //
+    // Save latest settings to runtime script table
+    //
+    S3BootScriptSavePciCfgWrite (
+      S3BootScriptWidthUint32,
+      PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MDR)),
+      1,
+      &Data32
+     );
+
+    Data32 = MESSAGE_WRITE_DW (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]);
+
+    S3BootScriptSavePciCfgWrite (
+      S3BootScriptWidthUint32,
+      PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MCR)),
+      1,
+      &Data32
+     );
+    Index += 2;
+  }
+
+  Index = 0;
+  while (QNCS3SaveExtReg[Index] != 0xFF) {
+    //
+    // Save IMR settings with IMR protection enabled (above script was to handle restoring all settings first - now we want to enable)
+    //
+    if (QNCS3SaveExtReg[Index] == QUARK_NC_MEMORY_MANAGER_SB_PORT_ID) {
+      if (DeviceId == QUARK2_MC_DEVICE_ID) {
+        if ((QNCS3SaveExtReg[Index + 1] >= (QUARK_NC_MEMORY_MANAGER_IMR0+QUARK_NC_MEMORY_MANAGER_IMRXL)) && (QNCS3SaveExtReg[Index + 1] <= (QUARK_NC_MEMORY_MANAGER_IMR7+QUARK_NC_MEMORY_MANAGER_IMRXWM)) && ((QNCS3SaveExtReg[Index + 1] & 0x03) == QUARK_NC_MEMORY_MANAGER_IMRXL)) {
+          Data32 = QNCPortRead (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]);
+          Data32 &= ~IMR_LOCK;
+
+          //
+          // Save latest settings to runtime script table
+          //
+          S3BootScriptSavePciCfgWrite (
+            S3BootScriptWidthUint32,
+            PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MDR)),
+            1,
+            &Data32
+          );
+
+          Data32 = MESSAGE_WRITE_DW (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]);
+
+          S3BootScriptSavePciCfgWrite (
+            S3BootScriptWidthUint32,
+            PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MCR)),
+            1,
+            &Data32
+          );
+        }
+      } else {
+        if ((QNCS3SaveExtReg[Index + 1] >= (QUARK_NC_MEMORY_MANAGER_IMR0+QUARK_NC_MEMORY_MANAGER_IMRXRM)) && (QNCS3SaveExtReg[Index + 1] <= (QUARK_NC_MEMORY_MANAGER_IMR7+QUARK_NC_MEMORY_MANAGER_IMRXWM)) && ((QNCS3SaveExtReg[Index + 1] & 0x03) >= QUARK_NC_MEMORY_MANAGER_IMRXRM)) {
+          Data32 = QNCPortRead (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]);
+
+          //
+          // Save latest settings to runtime script table
+          //
+          S3BootScriptSavePciCfgWrite (
+            S3BootScriptWidthUint32,
+            PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MDR)),
+            1,
+            &Data32
+          );
+
+          Data32 = MESSAGE_WRITE_DW (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]);
+
+          S3BootScriptSavePciCfgWrite (
+            S3BootScriptWidthUint32,
+            PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MCR)),
+            1,
+            &Data32
+          );
+        }
+      }
+    }
+    Index += 2;
+  }
+
+  // Check if ECC scrub enabled and need re-enabling on resume
+  // All scrub related configuration registers are saved on suspend
+  // as part of QNCS3SaveExtReg configuration table script.
+  // The code below extends the S3 resume script with scrub reactivation
+  // message (if needed only)
+  Data32 = QNCPortRead (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_ECC_SCRUB_CONFIG_REG);
+  if( 0 != (Data32 & SCRUB_CFG_ACTIVE)) {
+
+      Data32 = SCRUB_RESUME_MSG();
+
+      S3BootScriptSavePciCfgWrite (
+        S3BootScriptWidthUint32,
+        PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MCR)),
+        1,
+        &Data32
+       );
+  }
+
+  //
+  // Save I/O ports to S3 script table
+  //
+
+  //
+  // Important to trap Sx for SMM
+  //
+  Data32 = IoRead32 (mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_SMIE);
+  S3BootScriptSaveIoWrite(S3BootScriptWidthUint32, (mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_SMIE), 1, &Data32);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.h b/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.h
new file mode 100644
index 0000000000..1a218cd143
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.h
@@ -0,0 +1,167 @@
+/** @file
+Header file for SMM S3 Handler Driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#ifndef _ACPI_SMM_DRIVER_H
+#define _ACPI_SMM_DRIVER_H
+//
+// Include files
+//
+//
+// Driver Consumed Protocol Prototypes
+//
+#include <Protocol/SmmSxDispatch2.h>
+#include <Protocol/SmmSwDispatch2.h>
+#include <Protocol/FirmwareVolume.h>
+#include <Protocol/GlobalNvsArea.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Protocol/Spi.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/PcdLib.h>
+#include <Library/LockBoxLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/S3IoLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Guid/Acpi.h>
+#include <Guid/GlobalVariable.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Guid/SmramMemoryReserve.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/HobLib.h>
+#include <QNCAccess.h>
+#include <Library/QNCAccessLib.h>
+#include <Library/IntelQNCLib.h>
+#include <Library/PlatformHelperLib.h>
+#include <Library/PlatformPcieHelperLib.h>
+#include "Platform.h"
+#include <IndustryStandard/Pci22.h>
+
+#define EFI_ACPI_ACPI_ENABLE          0xA0
+#define EFI_ACPI_ACPI_DISABLE         0xA1
+
+#define R_IOPORT_CMOS_STANDARD_INDEX            0x70
+#define R_IOPORT_CMOS_STANDARD_DATA             0x71
+#define RTC_ADDRESS_REGISTER_C    12
+#define RTC_ADDRESS_REGISTER_D    13
+
+#define PCI_DEVICE(Bus, Dev, Func)  \
+          Bus, Dev, Func
+
+#define PCI_REG_MASK(Byte0, Byte1, Byte2, Byte3, Byte4, Byte5, Byte6, Byte7) \
+          Byte0, Byte1, Byte2, Byte3, Byte4, Byte5, Byte6, Byte7
+
+#define PCI_DEVICE_END    0xFF
+
+//
+// Related data structures definition
+//
+typedef struct _EFI_ACPI_SMM_DEV {
+
+  //
+  // Parent dispatch driver returned sleep handle
+  //
+  EFI_HANDLE  S3SleepEntryHandle;
+
+  EFI_HANDLE  S4SleepEntryHandle;
+
+  EFI_HANDLE  S1SleepEntryHandle;
+
+  EFI_HANDLE  S5SoftOffEntryHandle;
+
+  EFI_HANDLE  EnableAcpiHandle;
+
+  EFI_HANDLE  DisableAcpiHandle;
+
+  EFI_HANDLE  PpCallbackHandle;
+
+  EFI_HANDLE  MorCallbackHandle;
+
+  //
+  // QNC Power Management I/O register base
+  //
+  UINT32      QncPmBase;
+
+  //
+  // QNC General Purpose Event0 register base
+  //
+  UINT32      QncGpe0Base;
+
+  UINT32      BootScriptSaved;
+
+} EFI_ACPI_SMM_DEV;
+
+//
+// Prototypes
+//
+EFI_STATUS
+InitPlatformAcpiSmm (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable,
+  IN  OUT VOID            *CommBuffer,
+  IN  OUT UINTN           *CommBufferSize
+  );
+
+EFI_STATUS
+SxSleepEntryCallBack (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  CONST VOID                    *DispatchContext,
+
+  IN  OUT VOID                      *CommBuffer,
+  IN  OUT UINTN                     *CommBufferSize
+  );
+
+EFI_STATUS
+DisableAcpiCallback (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  CONST VOID                    *DispatchContext,
+  IN  OUT VOID                      *CommBuffer,
+  IN  OUT UINTN                     *CommBufferSize
+  );
+
+EFI_STATUS
+EnableAcpiCallback (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  CONST VOID                    *DispatchContext,
+  IN  OUT VOID                      *CommBuffer,
+  IN  OUT UINTN                     *CommBufferSize
+  );
+
+EFI_STATUS
+RegisterToDispatchDriver (
+  VOID
+  );
+
+EFI_STATUS
+GetAllQncPmBase (
+  IN EFI_SMM_SYSTEM_TABLE2       *Smst
+  );
+
+EFI_STATUS
+SaveRuntimeScriptTable (
+  IN EFI_SMM_SYSTEM_TABLE2       *Smst
+  );
+
+EFI_STATUS
+RestoreQncS3SwCallback (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  CONST VOID                    *DispatchContext,
+  IN  OUT VOID                      *CommBuffer,
+  IN  OUT UINTN                     *CommBufferSize
+  );
+
+extern EFI_GUID gQncS3CodeInLockBoxGuid;
+extern EFI_GUID gQncS3ContextInLockBoxGuid;
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.inf b/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.inf
new file mode 100644
index 0000000000..0a83bd14bb
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.inf
@@ -0,0 +1,78 @@
+## @file
+# Component description file for ACPI SMM Platform handler module
+#
+# This is QNC Smm platform driver .
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+  INF_VERSION                 = 0x00010005
+  BASE_NAME                   = AcpiSmmPlatform
+  FILE_GUID                   = F5AC7057-5650-466e-B692-76A47223EFB0
+  MODULE_TYPE                 = DXE_SMM_DRIVER
+  VERSION_STRING              = 1.0
+  PI_SPECIFICATION_VERSION    = 0x0001000A
+  ENTRY_POINT                 = InitAcpiSmmPlatform
+
+[Sources]
+  AcpiSmmPlatform.c
+  AcpiSmmPlatform.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  ReportStatusCodeLib
+  UefiDriverEntryPoint
+  DebugLib
+  IoLib
+  PciLib
+  BaseMemoryLib
+  BaseLib
+  SmmServicesTableLib
+  PcdLib
+  HobLib
+  S3BootScriptLib
+  LockBoxLib
+  PlatformHelperLib
+  IntelQNCLib
+  PlatformPcieHelperLib
+
+[Protocols]
+  gEfiSmmSxDispatch2ProtocolGuid
+  gEfiPciRootBridgeIoProtocolGuid
+  gEfiVariableArchProtocolGuid
+  gEfiVariableWriteArchProtocolGuid
+  gEfiGlobalNvsAreaProtocolGuid
+  gEfiSmmSwDispatch2ProtocolGuid
+
+[Guids]
+  gEfiSmmPeiSmramMemoryReserveGuid
+  gQncS3CodeInLockBoxGuid
+  gQncS3ContextInLockBoxGuid
+
+[Pcd]
+  gQuarkPlatformTokenSpaceGuid.PcdPlatformType
+  gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeS3SuspendStart
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemorySize
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdGpe0blkIoBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPm1blkIoBaseAddress
+
+[Depex]
+  gEfiSmmSxDispatch2ProtocolGuid AND
+  gEfiPciRootBridgeIoProtocolGuid AND
+  gEfiVariableArchProtocolGuid AND
+  gEfiVariableWriteArchProtocolGuid AND
+  gEfiGlobalNvsAreaProtocolGuid AND
+  gEfiQncS3SupportProtocolGuid
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/Ppm.c b/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/Ppm.c
new file mode 100644
index 0000000000..708ff74cb9
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/Ppm.c
@@ -0,0 +1,372 @@
+/** @file
+
+Processor power management initialization code.
+
+Copyright (c) 2013-2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#include "SmmPowerManagement.h"
+
+//
+// Global variables
+//
+extern EFI_ACPI_SDT_PROTOCOL   *mAcpiSdt;
+extern EFI_ACPI_TABLE_PROTOCOL *mAcpiTable;
+
+extern EFI_GUID gPowerManagementAcpiTableStorageGuid;
+
+/**
+  This function is the entry of processor power management initialization code.
+  It initializes the processor's power management features based on the user
+  configurations and hardware capabilities.
+**/
+VOID
+PpmInit (
+  VOID
+  )
+{
+  //
+  // Processor Power Management Flags
+  //
+  mGlobalNvsAreaPtr->Cfgd = PcdGet32(PcdPpmFlags);
+
+  //
+  // Patch and publish power management related acpi tables
+  //
+  PpmPatchAndPublishAcpiTables();
+}
+
+/**
+  This function is to patch and publish power management related acpi tables.
+**/
+VOID
+PpmPatchAndPublishAcpiTables (
+  VOID
+  )
+{
+    //
+    // Patch FADT table to enable C2,C3
+    //
+  PpmPatchFadtTable();
+
+  //
+    // Load all the power management acpi tables and patch IST table
+    //
+    PpmLoadAndPatchPMTables();
+}
+
+/**
+  This function is to patch PLvl2Lat and PLvl3Lat to enable C2, C3 support in OS.
+**/
+VOID
+PpmPatchFadtTable (
+  VOID
+  )
+{
+    EFI_STATUS                    Status;
+  EFI_ACPI_DESCRIPTION_HEADER   *Table;
+  EFI_ACPI_SDT_HEADER           *CurrentTable;
+  EFI_ACPI_TABLE_VERSION        Version;
+  UINTN                         Index;
+  UINTN                         Handle;
+
+  //
+  // Scan all the acpi tables to find FADT 2.0
+  //
+  Index = 0;
+  do {
+    Status = mAcpiSdt->GetAcpiTable (
+                       Index,
+                       &CurrentTable,
+                       &Version,
+                       &Handle
+                       );
+    if (Status == EFI_NOT_FOUND) {
+      break;
+    }
+    ASSERT_EFI_ERROR (Status);
+    Index++;
+  } while (CurrentTable->Signature != EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE || CurrentTable->Revision != 0x03);
+
+  ASSERT (CurrentTable->Signature == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE);
+
+  Table  = NULL;
+  Status = gBS->AllocatePool (EfiBootServicesData, CurrentTable->Length, (VOID **) &Table);
+  ASSERT (Table != NULL);
+  CopyMem (Table, CurrentTable, CurrentTable->Length);
+
+  //
+  // Update the ACPI table and recalculate checksum
+  //
+  Status = mAcpiTable->UninstallAcpiTable (mAcpiTable, Handle);
+  if (EFI_ERROR (Status)) {
+     //
+     // Should not get an error here ever, but abort if we do.
+     //
+     return ;
+  }
+
+  //
+  // Update the check sum
+  // It needs to be zeroed before the checksum calculation
+  //
+  ((EFI_ACPI_SDT_HEADER *)Table)->Checksum = 0;
+  ((EFI_ACPI_SDT_HEADER *)Table)->Checksum =
+    CalculateCheckSum8 ((VOID *)Table, Table->Length);
+
+  //
+  // Add the table
+  //
+  Status = mAcpiTable->InstallAcpiTable (
+                            mAcpiTable,
+                            Table,
+                            Table->Length,
+                            &Handle
+                            );
+  ASSERT_EFI_ERROR (Status);
+  gBS->FreePool (Table);
+}
+
+VOID
+SsdtTableUpdate (
+  IN OUT   EFI_ACPI_DESCRIPTION_HEADER  *TableHeader
+  )
+/*++
+
+  Routine Description:
+
+    Update the SSDT table
+
+  Arguments:
+
+    Table   - The SSDT table to be patched
+
+  Returns:
+
+    None
+
+--*/
+{
+  UINT8      *CurrPtr;
+  UINT8      *SsdtPointer;
+  UINT32     *Signature;
+
+  //
+  // Loop through the ASL looking for values that we must fix up.
+  //
+  CurrPtr = (UINT8 *) TableHeader;
+  for (SsdtPointer = CurrPtr;
+       SsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length);
+       SsdtPointer++
+      )
+  {
+    Signature = (UINT32 *) SsdtPointer;
+    if ((*Signature) == SIGNATURE_32 ('P', 'M', 'B', 'A')) {
+      switch (*(Signature+1)) {
+      case (SIGNATURE_32 ('L', 'V', 'L', '0')):
+        Signature[0] = PcdGet16(PcdPmbaIoBaseAddress);
+        Signature[1] = 0;
+        break;
+      case (SIGNATURE_32 ('L', 'V', 'L', '2')):
+        Signature[0] = PcdGet16(PcdPmbaIoLVL2);
+        Signature[1] = 0;
+        break;
+      }
+    }
+  }
+}
+
+EFI_STATUS
+LocateSupportProtocol (
+  IN  EFI_GUID                       *Protocol,
+  OUT VOID                           **Instance,
+  IN  UINT32                         Type
+  )
+/*++
+
+Routine Description:
+
+  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.
+
+Arguments:
+
+  Protocol      The protocol to find.
+  Instance      Return pointer to the first instance of the protocol
+
+Returns:
+
+  EFI_SUCCESS           The function completed successfully.
+  EFI_NOT_FOUND         The protocol could not be located.
+  EFI_OUT_OF_RESOURCES  There are not enough resources to find the protocol.
+
+--*/
+{
+  EFI_STATUS              Status;
+  EFI_HANDLE              *HandleBuffer;
+  UINTN                   NumberOfHandles;
+  EFI_FV_FILETYPE         FileType;
+  UINT32                  FvStatus;
+  EFI_FV_FILE_ATTRIBUTES  Attributes;
+  UINTN                   Size;
+  UINTN                   i;
+
+  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 (i = 0; i < NumberOfHandles; i++) {
+    //
+    // Get the protocol on this handle
+    // This should not fail because of LocateHandleBuffer
+    //
+    Status = gBS->HandleProtocol (
+                     HandleBuffer[i],
+                     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_VOLUME2_PROTOCOL*) (*Instance))->ReadFile (*Instance,
+                                                              &gPowerManagementAcpiTableStorageGuid,
+                                                              NULL,
+                                                              &Size,
+                                                              &FileType,
+                                                              &Attributes,
+                                                              &FvStatus
+                                                              );
+
+    //
+    // If we found it, then we are done
+    //
+    if (Status == EFI_SUCCESS) {
+      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 is to load all the power management acpi tables and patch IST table.
+**/
+VOID
+PpmLoadAndPatchPMTables (
+  VOID
+  )
+{
+    EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
+    EFI_STATUS                    Status;
+    INTN                          Instance;
+  EFI_ACPI_COMMON_HEADER        *CurrentTable;
+  UINTN                         TableHandle;
+  UINT32                        FvStatus;
+  UINTN                         Size;
+
+    Status = LocateSupportProtocol (&gEfiFirmwareVolume2ProtocolGuid, (VOID**)&FwVol, 1);
+    if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  //
+  // Read tables from the storage file.
+  //
+  Instance = 0;
+  CurrentTable = NULL;
+
+  while (Status == EFI_SUCCESS) {
+
+    Status = FwVol->ReadSection (
+                      FwVol,
+                      &gPowerManagementAcpiTableStorageGuid,
+                      EFI_SECTION_RAW,
+                      Instance,
+                      (VOID**)&CurrentTable,
+                      &Size,
+                      &FvStatus
+                      );
+
+    if (!EFI_ERROR(Status)) {
+      SsdtTableUpdate ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable);
+
+      //
+      // Update the check sum
+      // It needs to be zeroed before the checksum calculation
+      //
+      ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 0;
+      ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = (UINT8)
+        CalculateCheckSum8 ((VOID *)CurrentTable, CurrentTable->Length);
+
+      //
+      // Add the table
+      //
+      TableHandle = 0;
+      Status = mAcpiTable->InstallAcpiTable (
+                              mAcpiTable,
+                              CurrentTable,
+                              CurrentTable->Length,
+                              &TableHandle
+                              );
+
+      ASSERT_EFI_ERROR (Status);
+
+      //
+      // Increment the instance
+      //
+      Instance++;
+      CurrentTable = NULL;
+    }
+  }
+
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/Ppm.h b/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/Ppm.h
new file mode 100644
index 0000000000..cc7bb3c382
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/Ppm.h
@@ -0,0 +1,150 @@
+/** @file
+
+Processor power management initialization code.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#ifndef _PPM_H
+#define _PPM_H
+
+//
+// Bit definitions of PPMFlags
+//
+#define PPM_GV3         (1 << 0)  // Geyserville 3
+#define PPM_TURBO       (1 << 1)  // Turbo Mode
+#define PPM_SUPER_LFM   (1 << 2)  // N/2 Ratio
+#define PPM_C1          (1 << 4)  // C1 Capable, Enabled
+#define PPM_C2          (1 << 5)  // C2 Capable, Enabled
+#define PPM_C3          (1 << 6)  // C3 Capable, Enabled
+#define PPM_C4          (1 << 7)  // C4 Capable, Enabled
+#define PPM_C5          (1 << 8)  // C5/Deep C4 Capable, Enabled
+#define PPM_C6          (1 << 9)  // C6 Capable, Enabled
+#define PPM_C1E         (1 << 10) // C1E Enabled
+#define PPM_C2E         (1 << 11) // C2E Enabled
+#define PPM_C3E         (1 << 12) // C3E Enabled
+#define PPM_C4E         (1 << 13) // C4E Enabled
+#define PPM_HARD_C4E    (1 << 14) // Hard C4E Capable, Enabled
+#define PPM_TM1         (1 << 16) // Thermal Monitor 1
+#define PPM_TM2         (1 << 17) // Thermal Monitor 2
+#define PPM_PHOT        (1 << 19) // Bi-directional ProcHot
+#define PPM_MWAIT_EXT   (1 << 21) // MWAIT extensions supported
+#define PPM_CMP         (1 << 24) // CMP supported, Enabled
+#define PPM_TSTATE      (1 << 28) // CPU T states supported
+
+#define PPM_C_STATES    (PPM_C1 + PPM_C2 + PPM_C3 + PPM_C4 + PPM_C5 + PPM_C6)
+#define PPM_CE_STATES   (PPM_C1E + PPM_C2E + PPM_C3E + PPM_C4E + PPM_HARD_C4E)
+
+
+#define MAX_P_STATES_NUM    12
+
+#define AML_NAME_OP         0x08
+#define AML_SCOPE_OP        0x10
+#define AML_PACKAGE_OP      0x12
+#define AML_METHOD_OP       0x14
+
+#define S3_CPU_REGISTER_TABLE_GUID \
+  { \
+    0xc4ef988d, 0xe5e, 0x4403, { 0xbe, 0xeb, 0xf1, 0xbb, 0x6, 0x79, 0x6e, 0xdf } \
+  }
+
+#pragma pack(1)
+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;
+#pragma pack()
+
+typedef struct {
+  UINT32  Index;
+  UINT64  Value;
+} S3_CPU_REGISTER;
+
+//
+// Function prototypes
+//
+
+/**
+  This function is the entry of processor power management initialization code.
+  It initializes the processor's power management features based on the user
+  configurations and hardware capablities.
+**/
+VOID
+PpmInit (
+  VOID
+  );
+
+/**
+  This function is to determine the Processor Power Management Flags
+  based on the hardware capability.
+**/
+VOID
+PpmDetectCapability (
+  VOID
+  );
+
+/**
+  This function is to determine the user configuration mask
+**/
+VOID
+PpmGetUserConfigurationMask (
+  VOID
+  );
+
+/**
+  This function is to patch and publish power management related acpi tables.
+**/
+VOID
+PpmPatchAndPublishAcpiTables (
+  VOID
+  );
+
+/**
+  This function is to patch PLvl2Lat and PLvl3Lat to enable C2, C3 support in OS.
+**/
+VOID
+PpmPatchFadtTable (
+  VOID
+  );
+
+/**
+  This function is to load all the power management acpi tables and patch IST table.
+**/
+VOID
+PpmLoadAndPatchPMTables (
+  VOID
+  );
+
+/**
+  This function is to save cpu registers for s3 resume.
+**/
+VOID
+PpmS3SaveRegisters (
+  VOID
+  );
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/SmmPowerManagement.c b/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/SmmPowerManagement.c
new file mode 100644
index 0000000000..3a63223c14
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/SmmPowerManagement.c
@@ -0,0 +1,113 @@
+/** @file
+
+This is QNC Smm Power Management driver
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#include "SmmPowerManagement.h"
+
+//
+// Global variables
+//
+EFI_SMM_CPU_PROTOCOL                    *mSmmCpu = NULL;
+EFI_GLOBAL_NVS_AREA                     *mGlobalNvsAreaPtr = NULL;
+EFI_MP_SERVICES_PROTOCOL                *mMpService = NULL;
+EFI_ACPI_SDT_PROTOCOL                   *mAcpiSdt = NULL;
+EFI_ACPI_TABLE_PROTOCOL                 *mAcpiTable = NULL;
+
+EFI_GUID    mS3CpuRegisterTableGuid = S3_CPU_REGISTER_TABLE_GUID;
+
+EFI_STATUS
+EFIAPI
+InitializePowerManagement (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+/*++
+
+Routine Description:
+
+  Initializes the SMM Handler Driver
+
+Arguments:
+
+  ImageHandle -
+
+  SystemTable -
+
+Returns:
+
+  None
+
+--*/
+{
+  EFI_STATUS                                Status;
+  EFI_SMM_SW_DISPATCH2_PROTOCOL             *SwDispatch;
+  EFI_GLOBAL_NVS_AREA_PROTOCOL              *GlobalNvsAreaProtocol;
+
+  //
+  // Get SMM CPU protocol
+  //
+  Status = gSmst->SmmLocateProtocol (
+                    &gEfiSmmCpuProtocolGuid,
+                    NULL,
+                    (VOID **)&mSmmCpu
+                    );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  //  Get the Sw dispatch protocol
+  //
+  Status = gSmst->SmmLocateProtocol (
+                    &gEfiSmmSwDispatch2ProtocolGuid,
+                    NULL,
+                    (VOID**)&SwDispatch
+                    );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Get Global NVS Area Protocol
+  //
+  Status = gBS->LocateProtocol (&gEfiGlobalNvsAreaProtocolGuid, NULL, (VOID **)&GlobalNvsAreaProtocol);
+  ASSERT_EFI_ERROR (Status);
+  mGlobalNvsAreaPtr = GlobalNvsAreaProtocol->Area;
+
+  //
+  // Locate and cache PI AcpiSdt Protocol.
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiAcpiSdtProtocolGuid,
+                  NULL,
+                  (VOID **) &mAcpiSdt
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+
+  //
+  // Locate and cache PI AcpiSdt Protocol.
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiAcpiTableProtocolGuid,
+                  NULL,
+                  (VOID **) &mAcpiTable
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+
+  //
+  // Get MpService protocol
+  //
+  Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&mMpService);
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Initialize power management features on processors
+  //
+  PpmInit();
+
+  return Status;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/SmmPowerManagement.h b/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/SmmPowerManagement.h
new file mode 100644
index 0000000000..30d30d9cda
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/SmmPowerManagement.h
@@ -0,0 +1,52 @@
+/** @file
+Header file for  QNC Smm Power Management driver
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _SMM_POWER_MANAGEMENT_H_
+#define _SMM_POWER_MANAGEMENT_H_
+
+#include <PiSmm.h>
+#include <IntelQNCDxe.h>
+
+#include <Protocol/AcpiTable.h>
+#include <Protocol/SmmCpu.h>
+#include <Protocol/SmmSwDispatch2.h>
+#include <Protocol/GlobalNvsArea.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/MpService.h>
+
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <IndustryStandard/Acpi.h>
+
+#include <AcpiCpuData.h>
+
+#include "Ppm.h"
+
+//
+// Module global variable
+//
+extern EFI_SMM_CPU_PROTOCOL                    *mSmmCpu;
+extern EFI_GLOBAL_NVS_AREA                     *mGlobalNvsAreaPtr;
+extern EFI_MP_SERVICES_PROTOCOL                *mMpService;
+
+//
+// Function prototypes
+//
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/SmmPowerManagement.inf b/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/SmmPowerManagement.inf
new file mode 100644
index 0000000000..a9ba170ca7
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/SmmPowerManagement.inf
@@ -0,0 +1,74 @@
+## @file
+# Component description file for SMM Power Management module
+#
+# This is QNC Smm Power Management driver .
+# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SmmPowerManagement
+  FILE_GUID                      = 271F1343-20D6-4e14-9B62-3C0297F56F07
+  MODULE_TYPE                    = DXE_SMM_DRIVER
+  VERSION_STRING                 = 1.0
+  PI_SPECIFICATION_VERSION       = 0x0001000A
+  ENTRY_POINT                    = InitializePowerManagement
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  SmmPowerManagement.c
+  SmmPowerManagement.h
+  Ppm.c
+  Ppm.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  DebugLib
+  PcdLib
+  IoLib
+  PciLib
+  BaseLib
+  BaseMemoryLib
+  SmmServicesTableLib
+  UefiBootServicesTableLib
+  S3BootScriptLib
+  MemoryAllocationLib
+
+[Protocols]
+  gEfiSmmCpuProtocolGuid                        # PROTOCOL ALWAYS_CONSUMED
+  gEfiSmmSwDispatch2ProtocolGuid                # PROTOCOL ALWAYS_CONSUMED
+  gEfiGlobalNvsAreaProtocolGuid                 # PROTOCOL ALWAYS_CONSUMED
+  gEfiFirmwareVolume2ProtocolGuid               # PROTOCOL ALWAYS_CONSUMED
+  gEfiMpServiceProtocolGuid                     # PROTOCOL ALWAYS_CONSUMED
+  gEfiAcpiSdtProtocolGuid                       # PROTOCOL ALWAYS_CONSUMED
+  gEfiAcpiTableProtocolGuid                     # PROTOCOL ALWAYS_CONSUMED
+
+[Guids]
+  gPowerManagementAcpiTableStorageGuid
+
+[Pcd]
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPmbaIoBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPmbaIoLVL2
+  gQuarkPlatformTokenSpaceGuid.PcdPpmFlags
+
+[Depex]
+  gEfiSmmCpuProtocolGuid AND
+  gEfiSmmSwDispatch2ProtocolGuid AND
+  gEfiGlobalNvsAreaProtocolGuid AND
+  gEfiAcpiTableProtocolGuid AND
+  gEfiMpServiceProtocolGuid
diff --git a/Platform/Intel/QuarkPlatformPkg/Application/ForceRecovery/ForceRecovery.c b/Platform/Intel/QuarkPlatformPkg/Application/ForceRecovery/ForceRecovery.c
new file mode 100644
index 0000000000..7132ec9dbf
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Application/ForceRecovery/ForceRecovery.c
@@ -0,0 +1,47 @@
+/** @file
+  Application that sets a sticky bit to force recovery on next reset.
+
+  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/QNCAccessLib.h>
+
+/**
+  The user Entry Point for Application. The user code starts with this function
+  as the real entry point for the application.
+
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
+  @param[in] SystemTable    A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS       The entry point is executed successfully.
+  @retval other             Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+UefiMain (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  //
+  // Set 'B_CFG_STICKY_RW_FORCE_RECOVERY' sticky bit so we know we need to do a recovery following warm reset
+  //
+  QNCAltPortWrite (
+    QUARK_SCSS_SOC_UNIT_SB_PORT_ID,
+    QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW,
+    QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW) | B_CFG_STICKY_RW_FORCE_RECOVERY
+    );
+
+  //
+  // Do a warm reset
+  //
+  gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Application/ForceRecovery/ForceRecovery.inf b/Platform/Intel/QuarkPlatformPkg/Application/ForceRecovery/ForceRecovery.inf
new file mode 100644
index 0000000000..f5401e9d8a
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Application/ForceRecovery/ForceRecovery.inf
@@ -0,0 +1,34 @@
+## @file
+#  Application that sets a sticky bit to force recovery on next reset.
+#
+#  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = ForceRecovery
+  FILE_GUID                      = 3A61FD45-69A0-42AD-B261-24DA451BF442
+  MODULE_TYPE                    = UEFI_APPLICATION
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = UefiMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32
+#
+
+[Sources]
+  ForceRecovery.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  UefiApplicationEntryPoint
+  UefiRuntimeServicesTableLib
+  QNCAccessLib
diff --git a/Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLibDxe.c b/Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLibDxe.c
new file mode 100644
index 0000000000..0a6f5405c1
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLibDxe.c
@@ -0,0 +1,262 @@
+/** @file
+  Platform Flash Access library.
+
+  Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#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/UefiBootServicesTableLib.h>
+#include <Protocol/Spi.h>
+
+//
+// SPI default opcode slots
+//
+#define SPI_OPCODE_JEDEC_ID_INDEX        0
+#define SPI_OPCODE_READ_ID_INDEX         1
+#define SPI_OPCODE_WRITE_S_INDEX         2
+#define SPI_OPCODE_WRITE_INDEX           3
+#define SPI_OPCODE_READ_INDEX            4
+#define SPI_OPCODE_ERASE_INDEX           5
+#define SPI_OPCODE_READ_S_INDEX          6
+#define SPI_OPCODE_CHIP_ERASE_INDEX      7
+
+#define SPI_ERASE_SECTOR_SIZE            SIZE_4KB  //This is the chipset requirement
+
+STATIC EFI_PHYSICAL_ADDRESS     mInternalFdAddress;
+EFI_SPI_PROTOCOL                *mSpiProtocol;
+
+/**
+  Writes specified number of bytes from the input buffer to the address
+
+  @param[in]      WriteAddress  The flash address to be written.
+  @param[in, out] NumBytes      The number of bytes.
+  @param[in]      Buffer        The data buffer to be written.
+
+  @return The status of flash write.
+**/
+EFI_STATUS
+FlashFdWrite (
+  IN  UINTN                               WriteAddress,
+  IN OUT UINTN                            *NumBytes,
+  IN  UINT8                               *Buffer
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = EFI_SUCCESS;
+
+  Status = mSpiProtocol->Execute (
+                           mSpiProtocol,
+                           SPI_OPCODE_WRITE_INDEX, // OpcodeIndex
+                           0,                      // PrefixOpcodeIndex
+                           TRUE,                   // DataCycle
+                           TRUE,                   // Atomic
+                           TRUE,                   // ShiftOut
+                           WriteAddress,           // Address
+                           (UINT32) (*NumBytes),   // Data Number
+                           Buffer,
+                           EnumSpiRegionBios
+                           );
+  DEBUG((DEBUG_INFO, "FlashFdWrite - 0x%x - %r\n", (UINTN)WriteAddress, Status));
+
+  AsmWbinvd ();
+
+  return Status;
+}
+
+/**
+  Erase a certain block from address LbaWriteAddress
+
+  @param[in] WriteAddress  The flash address to be erased.
+
+  @return The status of flash erase.
+**/
+EFI_STATUS
+FlashFdErase (
+  IN UINTN                                WriteAddress
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = mSpiProtocol->Execute (
+                           mSpiProtocol,
+                           SPI_OPCODE_ERASE_INDEX, // OpcodeIndex
+                           0,                      // PrefixOpcodeIndex
+                           FALSE,                  // DataCycle
+                           TRUE,                   // Atomic
+                           FALSE,                  // ShiftOut
+                           WriteAddress,           // Address
+                           0,                      // Data Number
+                           NULL,
+                           EnumSpiRegionBios       // SPI_REGION_TYPE
+                           );
+  DEBUG((DEBUG_INFO, "FlashFdErase - 0x%x - %r\n", (UINTN)WriteAddress, Status));
+
+  AsmWbinvd ();
+
+  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;
+  UINTN               SectorNum;
+  UINTN               Index;
+  UINTN               NumBytes;
+
+  DEBUG((DEBUG_INFO, "PerformFlashWrite - 0x%x(%x) - 0x%x\n", (UINTN)FlashAddress, (UINTN)FlashAddressType, Length));
+  if (FlashAddressType == FlashAddressTypeAbsoluteAddress) {
+    FlashAddress = FlashAddress - mInternalFdAddress;
+  }
+
+  //
+  // Erase & Write
+  //
+  SectorNum = Length / SPI_ERASE_SECTOR_SIZE;
+  for (Index = 0; Index < SectorNum; Index++){
+    if (Progress != NULL) {
+      Progress (StartPercentage + ((Index * (EndPercentage - StartPercentage)) / SectorNum));
+    }
+
+    if (CompareMem(
+          (UINT8 *)(UINTN)(FlashAddress + mInternalFdAddress) + Index * SPI_ERASE_SECTOR_SIZE,
+          (UINT8 *)Buffer + Index * SPI_ERASE_SECTOR_SIZE,
+          SPI_ERASE_SECTOR_SIZE) == 0) {
+      DEBUG((DEBUG_INFO, "Sector - 0x%x - skip\n", Index));
+      continue;
+    }
+    DEBUG((DEBUG_INFO, "Sector - 0x%x - update...\n", Index));
+
+    Status = FlashFdErase (
+               (UINTN)FlashAddress + Index * SPI_ERASE_SECTOR_SIZE
+               );
+    if (Status != EFI_SUCCESS){
+      break;
+    }
+    NumBytes = SPI_ERASE_SECTOR_SIZE;
+    Status = FlashFdWrite (
+               (UINTN)FlashAddress + Index * SPI_ERASE_SECTOR_SIZE,
+               &NumBytes,
+               (UINT8 *)Buffer + Index * SPI_ERASE_SECTOR_SIZE
+               );
+    if (Status != EFI_SUCCESS){
+      break;
+    }
+  }
+  if (Progress != NULL) {
+    Progress (EndPercentage);
+  }
+
+  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
+           );
+}
+
+/**
+  Platform Flash Access Lib Constructor.
+
+  @param[in]  ImageHandle       The firmware allocated handle for the EFI image.
+  @param[in]  SystemTable       A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS  Constructor returns successfully.
+**/
+EFI_STATUS
+EFIAPI
+PerformFlashAccessLibConstructor (
+  IN EFI_HANDLE                         ImageHandle,
+  IN EFI_SYSTEM_TABLE                   *SystemTable
+  )
+{
+  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;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLibDxe.inf b/Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLibDxe.inf
new file mode 100644
index 0000000000..3d0e6c6b35
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLibDxe.inf
@@ -0,0 +1,47 @@
+## @file
+#  Platform Flash Access library.
+#
+#  Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformFlashAccessLibDxe
+  FILE_GUID                      = 9168384A-5F66-4CF7-AEB6-845BDEBD3012
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformFlashAccessLib|DXE_DRIVER DXE_RUNTIME_DRIVER
+  CONSTRUCTOR                    = PerformFlashAccessLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  PlatformFlashAccessLibDxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  SignedCapsulePkg/SignedCapsulePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  PcdLib
+  DebugLib
+  UefiBootServicesTableLib
+
+[Protocols]
+  gEfiSpiProtocolGuid
+
+[Pcd]
+  gQuarkPlatformTokenSpaceGuid.PcdFlashAreaBaseAddress
+
+[Depex]
+  gEfiSpiProtocolGuid
diff --git a/Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAccessLib/SpiFlashDevice.c b/Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAccessLib/SpiFlashDevice.c
new file mode 100644
index 0000000000..70cb3467f9
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAccessLib/SpiFlashDevice.c
@@ -0,0 +1,330 @@
+/** @file
+  SPI flash device description.
+
+  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#include "SpiFlashDevice.h"
+
+#define FLASH_SIZE  (FixedPcdGet32 (PcdFlashAreaSize))
+
+SPI_INIT_TABLE  mSpiInitTable[] = {
+  //
+  // Macronix 32Mbit part
+  //
+  {
+    SPI_MX25L3205_ID1,
+    SPI_MX25L3205_ID2,
+    SPI_MX25L3205_ID3,
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle33MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle33MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle33MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle33MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle20MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_BLOCK_ERASE, EnumSpiCycle33MHz, EnumSpiOperationErase_64K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle33MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle33MHz, EnumSpiOperationFullChipErase}
+    },
+    (UINTN)(0x400000 - FLASH_SIZE), // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+  //
+  // Winbond 32Mbit part
+  //
+  {
+    SPI_W25X32_ID1,
+    SF_DEVICE_ID0_W25QXX,
+    SF_DEVICE_ID1_W25Q32,
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle50MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle50MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_ERASE,       EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+    },
+    (UINTN)(0x400000 - FLASH_SIZE), // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+  //
+  // Winbond 32Mbit part
+  //
+  {
+    SPI_W25X32_ID1,
+    SPI_W25X32_ID2,
+    SPI_W25X32_ID3,
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle33MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle33MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle33MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle33MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle33MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_ERASE,       EnumSpiCycle33MHz, EnumSpiOperationErase_4K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle33MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle33MHz, EnumSpiOperationFullChipErase}
+    },
+    (UINTN)(0x400000 - FLASH_SIZE), // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+  //
+  // Atmel 32Mbit part
+  //
+  {
+    SPI_AT26DF321_ID1,
+    SPI_AT26DF321_ID2,  // issue: byte 2 identifies family/density for Atmel
+    SPI_AT26DF321_ID3,
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle33MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle33MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle33MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle33MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle33MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_BLOCK_ERASE, EnumSpiCycle33MHz, EnumSpiOperationErase_64K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle33MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle33MHz, EnumSpiOperationFullChipErase}
+    },
+    (UINTN)(0x400000 - FLASH_SIZE), // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+
+  //
+  // Intel 32Mbit part bottom boot
+  //
+  {
+    SPI_QH25F320_ID1,
+    SPI_QH25F320_ID2,
+    SPI_QH25F320_ID3,
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_ENABLE
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle33MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle33MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle33MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle33MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle33MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_BLOCK_ERASE, EnumSpiCycle33MHz, EnumSpiOperationErase_64K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle33MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle33MHz, EnumSpiOperationFullChipErase}
+    },
+    0,           // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+  //
+  // SST 64Mbit part
+  //
+  {
+    SPI_SST25VF080B_ID1,      // VendorId
+    SF_DEVICE_ID0_25VF064C,   // DeviceId 0
+    SF_DEVICE_ID1_25VF064C,   // DeviceId 1
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle50MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle50MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_ERASE,       EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+    },
+    0x800000 - FLASH_SIZE,          // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+  //
+  // NUMONYX 64Mbit part
+  //
+  {
+    SF_VENDOR_ID_NUMONYX,     // VendorId
+    SF_DEVICE_ID0_M25PX64,    // DeviceId 0
+    SF_DEVICE_ID1_M25PX64,    // DeviceId 1
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle50MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle50MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_ERASE,       EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+    },
+    0x800000 - FLASH_SIZE,          // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+  //
+  // Atmel 64Mbit part
+  //
+  {
+    SF_VENDOR_ID_ATMEL,       // VendorId
+    SF_DEVICE_ID0_AT25DF641,  // DeviceId 0
+    SF_DEVICE_ID1_AT25DF641,  // DeviceId 1
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle50MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle50MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_ERASE,       EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+    },
+    0x800000 - FLASH_SIZE,          // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+
+  //
+  // Spansion 64Mbit part
+  //
+  {
+    SF_VENDOR_ID_SPANSION,       // VendorId
+    SF_DEVICE_ID0_S25FL064K,  // DeviceId 0
+    SF_DEVICE_ID1_S25FL064K,  // DeviceId 1
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle50MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle50MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_ERASE,       EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+    },
+    0x800000 - FLASH_SIZE,          // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+
+  //
+  // Macronix 64Mbit part bottom boot
+  //
+  {
+    SF_VENDOR_ID_MX,          // VendorId
+    SF_DEVICE_ID0_25L6405D,   // DeviceId 0
+    SF_DEVICE_ID1_25L6405D,   // DeviceId 1
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle50MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle50MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_BLOCK_ERASE, EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+    },
+    0x800000 - FLASH_SIZE,          // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+  //
+  // Winbond 64Mbit part bottom boot
+  //
+  {
+    SPI_W25X64_ID1,
+    SF_DEVICE_ID0_W25QXX,
+    SF_DEVICE_ID1_W25Q64,
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle50MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle50MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_ERASE,       EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+    },
+    0x800000 - FLASH_SIZE,          // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+  //
+  // Winbond 64Mbit part bottom boot
+  //
+  {
+    SPI_W25X64_ID1,
+    SPI_W25X64_ID2,
+    SPI_W25X64_ID3,
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle50MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle50MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_ERASE,       EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+    },
+    0x800000 - FLASH_SIZE,          // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+  //
+  // Intel 64Mbit part bottom boot
+  //
+  {
+    SPI_QH25F640_ID1,
+    SPI_QH25F640_ID2,
+    SPI_QH25F640_ID3,
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle33MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle33MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle33MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle33MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle33MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_BLOCK_ERASE, EnumSpiCycle33MHz, EnumSpiOperationErase_64K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle33MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle33MHz, EnumSpiOperationFullChipErase}
+    },
+    0x800000 - FLASH_SIZE,          // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  }
+};
diff --git a/Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAccessLib/SpiFlashDevice.h b/Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAccessLib/SpiFlashDevice.h
new file mode 100644
index 0000000000..fdf305d727
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAccessLib/SpiFlashDevice.h
@@ -0,0 +1,180 @@
+/** @file
+  SPI flash device header file.
+
+  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _SPI_FLASH_DEVICE_H_
+#define _SPI_FLASH_DEVICE_H_
+
+#include <PiDxe.h>
+#include <Protocol/Spi.h>
+#include <Protocol/FirmwareVolumeBlock.h>
+
+//
+// Supported SPI Flash Devices
+//
+typedef enum {
+  EnumSpiFlash25L3205D,   // Macronix 32Mbit part
+  EnumSpiFlashW25Q32,     // Winbond 32Mbit part
+  EnumSpiFlashW25X32,     // Winbond 32Mbit part
+  EnumSpiFlashAT25DF321,  // Atmel 32Mbit part
+  EnumSpiFlashQH25F320,   // Intel 32Mbit part
+  EnumSpiFlash25VF064C,   // SST 64Mbit part
+  EnumSpiFlashM25PX64,    // NUMONYX 64Mbit part
+  EnumSpiFlashAT25DF641,  // Atmel 64Mbit part
+  EnumSpiFlashS25FL064K,  // Spansion 64Mbit part
+  EnumSpiFlash25L6405D,   // Macronix 64Mbit part
+  EnumSpiFlashW25Q64,     // Winbond 64Mbit part
+  EnumSpiFlashW25X64,     // Winbond 64Mbit part
+  EnumSpiFlashQH25F640,   // Intel 64Mbit part
+  EnumSpiFlashMax
+} SPI_FLASH_TYPES_SUPPORTED;
+
+//
+// Flash Device commands
+//
+// If a supported device uses a command different from the list below, a device specific command
+// will be defined just below it's JEDEC id section.
+//
+#define SPI_COMMAND_WRITE                 0x02
+#define SPI_COMMAND_WRITE_AAI             0xAD
+#define SPI_COMMAND_READ                  0x03
+#define SPI_COMMAND_ERASE                 0x20
+#define SPI_COMMAND_WRITE_DISABLE         0x04
+#define SPI_COMMAND_READ_S                0x05
+#define SPI_COMMAND_WRITE_ENABLE          0x06
+#define SPI_COMMAND_READ_ID               0xAB
+#define SPI_COMMAND_JEDEC_ID              0x9F
+#define SPI_COMMAND_WRITE_S_EN            0x50
+#define SPI_COMMAND_WRITE_S               0x01
+#define SPI_COMMAND_CHIP_ERASE            0xC7
+#define SPI_COMMAND_BLOCK_ERASE           0xD8
+
+//
+// Flash JEDEC device ids
+//
+// SST 8Mbit part
+//
+#define SPI_SST25VF080B_ID1               0xBF
+#define SPI_SST25VF080B_ID2               0x25
+#define SPI_SST25VF080B_ID3               0x8E
+//
+// SST 16Mbit part
+//
+#define SPI_SST25VF016B_ID1               0xBF
+#define SPI_SST25VF016B_ID2               0x25
+#define SPI_SST25V016BF_ID3               0x41
+//
+// Macronix 32Mbit part
+//
+// MX25 part does not support WRITE_AAI comand (0xAD)
+//
+#define SPI_MX25L3205_ID1                 0xC2
+#define SPI_MX25L3205_ID2                 0x20
+#define SPI_MX25L3205_ID3                 0x16
+//
+// Intel 32Mbit part bottom boot
+//
+#define SPI_QH25F320_ID1                  0x89
+#define SPI_QH25F320_ID2                  0x89
+#define SPI_QH25F320_ID3                  0x12  // 32Mbit bottom boot
+//
+// Intel 64Mbit part bottom boot
+//
+#define SPI_QH25F640_ID1                  0x89
+#define SPI_QH25F640_ID2                  0x89
+#define SPI_QH25F640_ID3                  0x13  // 64Mbit bottom boot
+//
+// QH part does not support command 0x20 for erase; only 0xD8 (sector erase)
+// QH part has 0x40 command for erase of parameter block (8 x 8K blocks at bottom of part)
+// 0x40 command ignored if address outside of parameter block range
+//
+#define SPI_QH25F320_COMMAND_PBLOCK_ERASE 0x40
+//
+// Winbond 32Mbit part
+//
+#define SPI_W25X32_ID1                    0xEF
+#define SPI_W25X32_ID2                    0x30  // Memory Type
+#define SPI_W25X32_ID3                    0x16  // Capacity
+#define SF_DEVICE_ID1_W25Q32              0x16
+
+//
+// Winbond 64Mbit part
+//
+#define SPI_W25X64_ID1                    0xEF
+#define SPI_W25X64_ID2                    0x30  // Memory Type
+#define SPI_W25X64_ID3                    0x17  // Capacity
+#define SF_DEVICE_ID0_W25QXX              0x40
+#define SF_DEVICE_ID1_W25Q64              0x17
+//
+// Winbond 128Mbit part
+//
+#define SF_DEVICE_ID0_W25Q128             0x40
+#define SF_DEVICE_ID1_W25Q128             0x18
+
+//
+// Atmel 32Mbit part
+//
+#define SPI_AT26DF321_ID1                 0x1F
+#define SPI_AT26DF321_ID2                 0x47  // [7:5]=Family, [4:0]=Density
+#define SPI_AT26DF321_ID3                 0x00
+
+#define SF_VENDOR_ID_ATMEL                0x1F
+#define SF_DEVICE_ID0_AT25DF641           0x48
+#define SF_DEVICE_ID1_AT25DF641           0x00
+
+//
+// SST 8Mbit part
+//
+#define SPI_SST25VF080B_ID1               0xBF
+#define SPI_SST25VF080B_ID2               0x25
+#define SPI_SST25VF080B_ID3               0x8E
+#define SF_DEVICE_ID0_25VF064C            0x25
+#define SF_DEVICE_ID1_25VF064C            0x4B
+
+//
+// SST 16Mbit part
+//
+#define SPI_SST25VF016B_ID1               0xBF
+#define SPI_SST25VF016B_ID2               0x25
+#define SPI_SST25V016BF_ID3               0x41
+
+//
+// Winbond 32Mbit part
+//
+#define SPI_W25X32_ID1                    0xEF
+#define SPI_W25X32_ID2                    0x30  // Memory Type
+#define SPI_W25X32_ID3                    0x16  // Capacity
+
+#define  SF_VENDOR_ID_MX             0xC2
+#define  SF_DEVICE_ID0_25L6405D      0x20
+#define  SF_DEVICE_ID1_25L6405D      0x17
+
+#define  SF_VENDOR_ID_NUMONYX        0x20
+#define  SF_DEVICE_ID0_M25PX64       0x71
+#define  SF_DEVICE_ID1_M25PX64       0x17
+
+//
+// Spansion 64Mbit part
+//
+#define SF_VENDOR_ID_SPANSION             0xEF
+#define SF_DEVICE_ID0_S25FL064K           0x40
+#define SF_DEVICE_ID1_S25FL064K           0x00
+
+//
+// index for prefix opcodes
+//
+#define SPI_WREN_INDEX                    0   // Prefix Opcode 0: SPI_COMMAND_WRITE_ENABLE
+#define SPI_EWSR_INDEX                    1   // Prefix Opcode 1: SPI_COMMAND_WRITE_S_EN
+#define BIOS_CTRL                         0xDC
+
+#define PFAB_CARD_DEVICE_ID               0x5150
+#define PFAB_CARD_VENDOR_ID               0x8086
+#define PFAB_CARD_SETUP_REGISTER          0x40
+#define PFAB_CARD_SETUP_BYTE              0x0d
+
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptor.aslc b/Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptor.aslc
new file mode 100644
index 0000000000..ae2c24510e
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/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('Q', 'U', 'A', 'R', 'K', '_', 'F', 'd')
+#define IMAGE_ID_STRING                     L"QuarkPlatformFd"
+
+// PcdSystemFmpCapsuleImageTypeIdGuid
+#define IMAGE_TYPE_ID_GUID                  { 0x62af20c0, 0x7016, 0x424a, { 0x9b, 0xf8, 0x9c, 0xcc, 0x86, 0x58, 0x40, 0x90 } }
+
+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;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptor.inf b/Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptor.inf
new file mode 100644
index 0000000000..5d243e5008
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/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
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  PeiServicesLib
+  DebugLib
+  PeimEntryPoint
+
+[FixedPcd]
+  gQuarkPlatformTokenSpaceGuid.PcdFlashAreaSize
+
+[Pcd]
+  gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareImageDescriptor
+
+[Depex]
+  TRUE
diff --git a/Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptorPei.c b/Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptorPei.c
new file mode 100644
index 0000000000..d21ee52184
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/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;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareUpdateConfig/SystemFirmwareUpdateConfig.ini b/Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareUpdateConfig/SystemFirmwareUpdateConfig.ini
new file mode 100644
index 0000000000..ab46869873
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareUpdateConfig/SystemFirmwareUpdateConfig.ini
@@ -0,0 +1,57 @@
+## @file
+#
+#  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Head]
+NumOfUpdate = 4
+NumOfRecovery = 2
+Update0 = QuarkFvMain
+Update1 = QuarkFvBinary
+Update2 = QuarkFvRecovery
+Update3 = QuarkFvNvRam
+Recovery0 = QuarkFvMain
+Recovery1 = QuarkFvPayload
+
+[QuarkFvPayload]
+FirmwareType = 0            # SystemFirmware
+AddressType = 0             # 0 - relative address, 1 - absolute address.
+BaseAddress = 0x00400000    # Base address offset on flash
+Length      = 0x00100000    # Length
+ImageOffset = 0x00400000    # Image offset of this SystemFirmware image
+FileGuid    = 14D83A59-A810-4556-8192-1C0A593C065C  # PcdEdkiiSystemFirmwareFileGuid
+
+[QuarkFvMain]
+FirmwareType = 0            # SystemFirmware
+AddressType = 0             # 0 - relative address, 1 - absolute address.
+BaseAddress = 0x00500000    # Base address offset on flash
+Length      = 0x001E0000    # Length
+ImageOffset = 0x00500000    # Image offset of this SystemFirmware image
+FileGuid    = 14D83A59-A810-4556-8192-1C0A593C065C  # PcdEdkiiSystemFirmwareFileGuid
+
+[QuarkFvNvRam]
+FirmwareType = 1            # NvRam
+AddressType = 0             # 0 - relative address, 1 - absolute address.
+BaseAddress = 0x006E0000    # Base address offset on flash
+Length      = 0x00020000    # Length
+ImageOffset = 0x006E0000    # Image offset of this SystemFirmware image
+FileGuid    = 14D83A59-A810-4556-8192-1C0A593C065C  # PcdEdkiiSystemFirmwareFileGuid
+
+[QuarkFvBinary]
+FirmwareType = 0            # SystemFirmware
+AddressType = 0             # 0 - relative address, 1 - absolute address.
+BaseAddress = 0x00700000    # Base address offset on flash
+Length      = 0x00010000    # Length
+ImageOffset = 0x00700000    # Image offset of this SystemFirmware image
+FileGuid    = 14D83A59-A810-4556-8192-1C0A593C065C  # PcdEdkiiSystemFirmwareFileGuid
+
+[QuarkFvRecovery]
+FirmwareType = 0            # SystemFirmware
+AddressType = 0             # 0 - relative address, 1 - absolute address.
+BaseAddress = 0x00710000    # Base address offset on flash
+Length      = 0x000F0000    # Length
+ImageOffset = 0x00710000    # Image offset of this SystemFirmware image
+FileGuid    = 14D83A59-A810-4556-8192-1C0A593C065C  # PcdEdkiiSystemFirmwareFileGuid
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnDataCD.h b/Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnDataCD.h
new file mode 100644
index 0000000000..d97caced1e
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnDataCD.h
@@ -0,0 +1,23 @@
+/** @file
+Capsule on Data CD GUID.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+This is the contract between the recovery module and device recovery module
+in order to convey the name of a given recovery module type
+
+**/
+
+#ifndef _CAPSULE_ON_DATA_CD_H
+#define _CAPSULE_ON_DATA_CD_H
+
+#define PEI_CAPSULE_ON_DATA_CD_GUID \
+  { \
+  0x5cac0099, 0x0dc9, 0x48e5, {0x80, 0x68, 0xbb, 0x95, 0xf5, 0x40, 0x0a, 0x9f } \
+  };
+
+extern EFI_GUID gPeiCapsuleOnDataCDGuid;
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatFloppyDisk.h b/Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatFloppyDisk.h
new file mode 100644
index 0000000000..a6a92e0f69
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatFloppyDisk.h
@@ -0,0 +1,23 @@
+/** @file
+Capsule on Fat Floppy Disk GUID.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+This is the contract between the recovery module and device recovery module
+in order to convey the name of a given recovery module type
+
+**/
+
+#ifndef _CAPSULE_ON_FAT_FLOPPY_DISK_H
+#define _CAPSULE_ON_FAT_FLOPPY_DISK_H
+
+#define PEI_CAPSULE_ON_FAT_FLOPPY_DISK_GUID \
+  { \
+  0x2e3d2e75, 0x9b2e, 0x412d, {0xb4, 0xb1, 0x70, 0x41, 0x6b, 0x87, 0x0, 0xff }\
+  };
+
+extern EFI_GUID gPeiCapsuleOnFatFloppyDiskGuid;
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatIdeDisk.h b/Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatIdeDisk.h
new file mode 100644
index 0000000000..34c633048c
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatIdeDisk.h
@@ -0,0 +1,24 @@
+/** @file
+Capsule on Fat Ide Disk GUID.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+This is the contract between the recovery module and device recovery module
+in order to convey the name of a given recovery module type
+
+**/
+
+#ifndef _CAPSULE_ON_FAT_IDE_DISK_H
+#define _CAPSULE_ON_FAT_IDE_DISK_H
+
+#define PEI_CAPSULE_ON_FAT_IDE_DISK_GUID \
+  { \
+  0xb38573b6, 0x6200, 0x4ac5, {0xb5, 0x1d, 0x82, 0xe6, 0x59, 0x38, 0xd7, 0x83 }\
+  };
+
+extern EFI_GUID gPeiCapsuleOnFatIdeDiskGuid;
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatUsbDisk.h b/Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatUsbDisk.h
new file mode 100644
index 0000000000..61ffc5b65e
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatUsbDisk.h
@@ -0,0 +1,24 @@
+/** @file
+Capsule on Fat Usb Disk GUID.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+This is the contract between the recovery module and device recovery module
+in order to convey the name of a given recovery module type
+
+**/
+
+#ifndef _PEI_CAPSULE_ON_FAT_USB_DISK_H
+#define _PEI_CAPSULE_ON_FAT_USB_DISK_H
+
+#define PEI_CAPSULE_ON_FAT_USB_DISK_GUID \
+  { \
+  0x0ffbce19, 0x324c, 0x4690, {0xa0, 0x09, 0x98, 0xc6, 0xae, 0x2e, 0xb1, 0x86 } \
+  };
+
+extern EFI_GUID gPeiCapsuleOnFatUsbDiskGuid;
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Include/Guid/MemoryConfigData.h b/Platform/Intel/QuarkPlatformPkg/Include/Guid/MemoryConfigData.h
new file mode 100644
index 0000000000..885a4beb28
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Include/Guid/MemoryConfigData.h
@@ -0,0 +1,23 @@
+/** @file
+Define a GUID name for GUID HOB which is used to pass Memory
+Configuration Data information to different modules.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _MEMORY_CONFIG_DATA_H_
+#define _MEMORY_CONFIG_DATA_H_
+
+#define EFI_MEMORY_CONFIG_DATA_GUID \
+  { \
+    0x80dbd530, 0xb74c, 0x4f11, {0x8c, 0x03, 0x41, 0x86, 0x65, 0x53, 0x28, 0x31 } \
+  }
+
+#define EFI_MEMORY_CONFIG_DATA_NAME  L"MemoryConfig"
+
+extern EFI_GUID gEfiMemoryConfigDataGuid;
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Include/Guid/QuarkCapsuleGuid.h b/Platform/Intel/QuarkPlatformPkg/Include/Guid/QuarkCapsuleGuid.h
new file mode 100644
index 0000000000..22d455f851
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Include/Guid/QuarkCapsuleGuid.h
@@ -0,0 +1,46 @@
+/** @file
+
+Capsule format guid for Quark capsule image.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _QUARK_CAPSULE_GUID_H_
+#define _QUARK_CAPSULE_GUID_H_
+
+#define QUARK_CAPSULE_GUID \
+  { 0xd400d1e4, 0xa314, 0x442b, { 0x89, 0xed, 0xa9, 0x2e, 0x4c, 0x81, 0x97, 0xcb } }
+
+#define SMI_INPUT_UPDATE_CAP 0x27
+#define SMI_INPUT_GET_CAP    0x28
+
+#define SMI_CAP_FUNCTION     0xEF
+
+#pragma pack(1)
+typedef struct {
+   UINT64  Address;
+   UINT32  BufferOffset;
+   UINT32  Size;
+   UINT32  Flags;
+   UINT32  Reserved;
+} CAPSULE_FRAGMENT;
+
+typedef struct {
+  UINTN         CapsuleLocation;  // Top of the capsule that point to structure CAPSULE_FRAGMENT
+  UINTN         CapsuleSize;    // Size of the capsule
+  EFI_STATUS   Status;      // Returned status
+} CAPSULE_INFO_PACKET;
+
+typedef struct {
+  UINTN           BlocksCompleted;  // # of blocks processed
+  UINTN           TotalBlocks;      // Total # of blocks to be processed
+  EFI_STATUS      Status;            // returned status
+} UPDATE_STATUS_PACKET;
+#pragma pack()
+
+extern EFI_GUID gEfiQuarkCapsuleGuid;
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Include/Guid/QuarkVariableLock.h b/Platform/Intel/QuarkPlatformPkg/Include/Guid/QuarkVariableLock.h
new file mode 100644
index 0000000000..5f346d3bd6
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Include/Guid/QuarkVariableLock.h
@@ -0,0 +1,23 @@
+/** @file
+
+Guid and variable name used to trigger quark lock of specific UEFI variables.
+
+Copyright (c) 2013 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _QUARK_VARIABLE_LOCK_GUID_H_
+#define _QUARK_VARIABLE_LOCK_GUID_H_
+
+#define QUARK_VARIABLE_LOCK_GUID \
+  { \
+    0xeef749c2, 0xc047, 0x4d6e, { 0xb1, 0xbc, 0xd3, 0x6e, 0xb3, 0xa5, 0x55, 0x9c } \
+  }
+
+#define QUARK_VARIABLE_LOCK_NAME  L"QuarkVariableLock"
+
+extern EFI_GUID gQuarkVariableLockGuid;
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Include/Guid/SystemNvDataHobGuid.h b/Platform/Intel/QuarkPlatformPkg/Include/Guid/SystemNvDataHobGuid.h
new file mode 100644
index 0000000000..b26da9a108
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Include/Guid/SystemNvDataHobGuid.h
@@ -0,0 +1,29 @@
+/** @file
+GUIDs used for System Non Volatile HOB entries in the in the HOB list and FV Guids carrying
+the System specific information.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _SYSTEM_NV_DATA_HOB_GUID_H_
+#define _SYSTEM_NV_DATA_HOB_GUID_H_
+
+#define EFI_SYSTEM_NV_DATA_HOB_GUID \
+  {0xd6e5092d, 0xc7b2, 0x4872, {0xaf, 0x66, 0xfd, 0xc0, 0xe6, 0xf9, 0x5e, 0x78}}
+
+typedef struct {
+  EFI_GUID                  SystemNvDataHobGuid;
+  EFI_GUID                  SystemNvDataFvGuid;
+  EFI_LBA                   StartLba;
+  UINTN                     StartLbaOffset;
+  EFI_LBA                   EndLba;
+  UINTN                     EndLbaOffset;
+  UINT32                    DataTypeSignature;
+} NV_SYSTEM_DATA_GUID_TYPE;
+
+extern EFI_GUID gEfiSystemNvDataHobGuid;
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Include/Library/PlatformHelperLib.h b/Platform/Intel/QuarkPlatformPkg/Include/Library/PlatformHelperLib.h
new file mode 100644
index 0000000000..65429626c8
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Include/Library/PlatformHelperLib.h
@@ -0,0 +1,266 @@
+/** @file
+PlatformHelperLib function prototype definitions.
+
+Copyright (c) 2013 - 2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __PLATFORM_HELPER_LIB_H__
+#define __PLATFORM_HELPER_LIB_H__
+
+#include "Platform.h"
+
+//
+// Function prototypes for routines exported by this library.
+//
+
+/**
+  Find pointer to RAW data in Firmware volume file.
+
+  @param   FvNameGuid       Firmware volume to search. If == NULL search all.
+  @param   FileNameGuid     Firmware volume file to search for.
+  @param   SectionData      Pointer to RAW data section of found file.
+  @param   SectionDataSize  Pointer to UNITN to get size of RAW data.
+
+  @retval  EFI_SUCCESS            Raw Data found.
+  @retval  EFI_INVALID_PARAMETER  FileNameGuid == NULL.
+  @retval  EFI_NOT_FOUND          Firmware volume file not found.
+  @retval  EFI_UNSUPPORTED        Unsupported in current enviroment (PEI or DXE).
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformFindFvFileRawDataSection (
+  IN CONST EFI_GUID                 *FvNameGuid OPTIONAL,
+  IN CONST EFI_GUID                 *FileNameGuid,
+  OUT VOID                          **SectionData,
+  OUT UINTN                         *SectionDataSize
+  );
+
+/**
+  Find free spi protect register and write to it to protect a flash region.
+
+  @param   DirectValue      Value to directly write to register.
+                            if DirectValue == 0 the use Base & Length below.
+  @param   BaseAddress      Base address of region in Flash Memory Map.
+  @param   Length           Length of region to protect.
+
+  @retval  EFI_SUCCESS      Free spi protect register found & written.
+  @retval  EFI_NOT_FOUND    Free Spi protect register not found.
+  @retval  EFI_DEVICE_ERROR Unable to write to spi protect register.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformWriteFirstFreeSpiProtect (
+  IN CONST UINT32                         DirectValue,
+  IN CONST UINT32                         BaseAddress,
+  IN CONST UINT32                         Length
+  );
+
+/**
+  Lock legacy SPI static configuration information.
+
+  Function will assert if unable to lock config.
+
+**/
+VOID
+EFIAPI
+PlatformFlashLockConfig (
+  VOID
+  );
+
+/**
+  Lock regions and config of SPI flash given the policy for this platform.
+
+  Function will assert if unable to lock regions or config.
+
+  @param   PreBootPolicy    If TRUE do Pre Boot Flash Lock Policy.
+
+**/
+VOID
+EFIAPI
+PlatformFlashLockPolicy (
+  IN CONST BOOLEAN                        PreBootPolicy
+  );
+
+/** Check if System booted with recovery Boot Stage1 image.
+
+  @retval  TRUE    If system booted with recovery Boot Stage1 image.
+  @retval  FALSE   If system booted with normal stage1 image.
+
+**/
+BOOLEAN
+EFIAPI
+PlatformIsBootWithRecoveryStage1 (
+  VOID
+  );
+
+/**
+  Clear SPI Protect registers.
+
+  @retval EFI_SUCESS         SPI protect registers cleared.
+  @retval EFI_ACCESS_DENIED  Unable to clear SPI protect registers.
+**/
+
+EFI_STATUS
+EFIAPI
+PlatformClearSpiProtect (
+  VOID
+  );
+
+/**
+  Determine if an SPI address range is protected.
+
+  @param  SpiBaseAddress  Base of SPI range.
+  @param  Length          Length of SPI range.
+
+  @retval TRUE       Range is protected.
+  @retval FALSE      Range is not protected.
+**/
+BOOLEAN
+EFIAPI
+PlatformIsSpiRangeProtected (
+  IN CONST UINT32                         SpiBaseAddress,
+  IN CONST UINT32                         Length
+  );
+
+/**
+  Set Legacy GPIO Level
+
+  @param  LevelRegOffset      GPIO level register Offset from GPIO Base Address.
+  @param  GpioNum             GPIO bit to change.
+  @param  HighLevel           If TRUE set GPIO High else Set GPIO low.
+
+**/
+VOID
+EFIAPI
+PlatformLegacyGpioSetLevel (
+  IN CONST UINT32       LevelRegOffset,
+  IN CONST UINT32       GpioNum,
+  IN CONST BOOLEAN      HighLevel
+  );
+
+/**
+  Get Legacy GPIO Level
+
+  @param  LevelRegOffset      GPIO level register Offset from GPIO Base Address.
+  @param  GpioNum             GPIO bit to check.
+
+  @retval TRUE       If bit is SET.
+  @retval FALSE      If bit is CLEAR.
+
+**/
+BOOLEAN
+EFIAPI
+PlatformLegacyGpioGetLevel (
+  IN CONST UINT32       LevelRegOffset,
+  IN CONST UINT32       GpioNum
+  );
+
+/**
+  Set the direction of Pcal9555 IO Expander GPIO pin.
+
+  @param  Pcal9555SlaveAddr  I2c Slave address of Pcal9555 Io Expander.
+  @param  GpioNum            Gpio direction to configure - values 0-7 for Port0
+                             and 8-15 for Port1.
+  @param  CfgAsInput         If TRUE set pin direction as input else set as output.
+
+**/
+VOID
+EFIAPI
+PlatformPcal9555GpioSetDir (
+  IN CONST UINT32                         Pcal9555SlaveAddr,
+  IN CONST UINT32                         GpioNum,
+  IN CONST BOOLEAN                        CfgAsInput
+  );
+
+/**
+  Set the level of Pcal9555 IO Expander GPIO high or low.
+
+  @param  Pcal9555SlaveAddr  I2c Slave address of Pcal9555 Io Expander.
+  @param  GpioNum            Gpio to change values 0-7 for Port0 and 8-15
+                             for Port1.
+  @param  HighLevel          If TRUE set pin high else set pin low.
+
+**/
+VOID
+EFIAPI
+PlatformPcal9555GpioSetLevel (
+  IN CONST UINT32                         Pcal9555SlaveAddr,
+  IN CONST UINT32                         GpioNum,
+  IN CONST BOOLEAN                        HighLevel
+  );
+
+/**
+
+  Enable pull-up/pull-down resistors of Pcal9555 GPIOs.
+
+  @param  Pcal9555SlaveAddr  I2c Slave address of Pcal9555 Io Expander.
+  @param  GpioNum            Gpio to change values 0-7 for Port0 and 8-15
+                             for Port1.
+
+**/
+VOID
+EFIAPI
+PlatformPcal9555GpioEnablePull (
+  IN CONST UINT32                         Pcal9555SlaveAddr,
+  IN CONST UINT32                         GpioNum
+  );
+
+/**
+
+  Disable pull-up/pull-down resistors of Pcal9555 GPIOs.
+
+  @param  Pcal9555SlaveAddr  I2c Slave address of Pcal9555 Io Expander.
+  @param  GpioNum            Gpio to change values 0-7 for Port0 and 8-15
+                             for Port1.
+
+**/
+VOID
+EFIAPI
+PlatformPcal9555GpioDisablePull (
+  IN CONST UINT32                         Pcal9555SlaveAddr,
+  IN CONST UINT32                         GpioNum
+  );
+
+BOOLEAN
+EFIAPI
+PlatformPcal9555GpioGetState (
+  IN CONST UINT32                         Pcal9555SlaveAddr,
+  IN CONST UINT32                         GpioNum
+  );
+
+/**
+  Init platform LEDs into known state.
+
+  @param   PlatformType     Executing platform type.
+
+  @retval  EFI_SUCCESS      Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformLedInit (
+  IN CONST EFI_PLATFORM_TYPE              Type
+  );
+
+/**
+  Turn on or off platform flash update LED.
+
+  @param   PlatformType     Executing platform type.
+  @param   TurnOn           If TRUE turn on else turn off.
+
+  @retval  EFI_SUCCESS      Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformFlashUpdateLed (
+  IN CONST EFI_PLATFORM_TYPE              Type,
+  IN CONST BOOLEAN                        TurnOn
+  );
+
+#endif // #ifndef __PLATFORM_HELPER_LIB_H__
diff --git a/Platform/Intel/QuarkPlatformPkg/Include/Library/PlatformPcieHelperLib.h b/Platform/Intel/QuarkPlatformPkg/Include/Library/PlatformPcieHelperLib.h
new file mode 100644
index 0000000000..2f848537a0
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Include/Library/PlatformPcieHelperLib.h
@@ -0,0 +1,56 @@
+/** @file
+PlatformPcieHelperLib function prototype definitions.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __PLATFORM_PCIE_HELPER_LIB_H__
+#define __PLATFORM_PCIE_HELPER_LIB_H__
+
+#include "Platform.h"
+
+//
+// Function prototypes for routines exported by this library.
+//
+
+/**
+  Platform assert PCI express PERST# signal.
+
+  @param   PlatformType     See EFI_PLATFORM_TYPE enum definitions.
+
+**/
+VOID
+EFIAPI
+PlatformPERSTAssert (
+  IN CONST EFI_PLATFORM_TYPE              PlatformType
+  );
+
+/**
+  Platform de assert PCI express PERST# signal.
+
+  @param   PlatformType     See EFI_PLATFORM_TYPE enum definitions.
+
+**/
+VOID
+EFIAPI
+PlatformPERSTDeAssert (
+  IN CONST EFI_PLATFORM_TYPE              PlatformType
+  );
+
+/** Early initialisation of the PCIe controller.
+
+  @param   PlatformType     See EFI_PLATFORM_TYPE enum definitions.
+
+  @retval   EFI_SUCCESS               Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformPciExpressEarlyInit (
+  IN CONST EFI_PLATFORM_TYPE              PlatformType
+  );
+
+#endif // #ifndef __PLATFORM_PCIE_HELPER_LIB_H__
diff --git a/Platform/Intel/QuarkPlatformPkg/Include/Pcal9555.h b/Platform/Intel/QuarkPlatformPkg/Include/Pcal9555.h
new file mode 100644
index 0000000000..a9aded7b31
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Include/Pcal9555.h
@@ -0,0 +1,24 @@
+/** @file
+Definition for Pcal9555 I2c IO Expander.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#ifndef __PCAL9555_H__
+#define __PCAL9555_H__
+
+#define PCAL9555_REG_IN_PORT0                        0x00
+#define PCAL9555_REG_IN_PORT1                        0x01
+#define PCAL9555_REG_OUT_PORT0                       0x02
+#define PCAL9555_REG_OUT_PORT1                       0x03
+#define PCAL9555_REG_CFG_PORT0                       0x06
+#define PCAL9555_REG_CFG_PORT1                       0x07
+
+#define PCAL9555_REG_PULL_EN_PORT0                   0x46
+#define PCAL9555_REG_PULL_EN_PORT1                   0x47
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Include/Platform.h b/Platform/Intel/QuarkPlatformPkg/Include/Platform.h
new file mode 100644
index 0000000000..1ffb7f7e4a
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Include/Platform.h
@@ -0,0 +1,119 @@
+/** @file
+Quark platform specific information.
+
+Copyright (c) 2013 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+#include "Uefi.h"
+
+#ifndef __PLATFORM_H__
+#define __PLATFORM_H__
+
+//
+// Constant definition
+//
+#define MAX_SMRAM_RANGES                    4
+#define MAX_NODE                            1
+
+#define QUARK_STAGE1_IMAGE_TYPE_MASK      0xF0
+#define QUARK_STAGE1_BOOT_IMAGE_TYPE      0x00  // Stage1 Boot images 0x00 -> 0x0F.
+#define QUARK_STAGE1_RECOVERY_IMAGE_TYPE  0x10  // Stage1 Recovery images 0x10 -> 0x1F.
+
+#define QUARK_BOOTROM_BASE_ADDRESS        0xFFFE0000  // Base address of Quark ROM in memory map.
+#define QUARK_BOOTROM_SIZE_BYTES          0x20000     // Quark ROM is 128KB.
+#define SMM_DEFAULT_SMBASE                  0x30000     // Default SMBASE address.
+#define SMM_DEFAULT_SMBASE_SIZE_BYTES       0x10000     // Size in bytes of default SMRAM.
+
+//
+// Gpio to be used to assert / deassert PCI express PERST# signal.
+//
+#define PCIEXP_PERST_RESUMEWELL_GPIO        3
+
+//
+// Minimum time in microseconds for assertion of PERST# signal.
+//
+#define PCIEXP_PERST_MIN_ASSERT_US          100
+
+//
+// Microsecond delay post issueing common lane reset.
+//
+#define PCIEXP_DELAY_US_POST_CMNRESET_RESET 1
+
+//
+// Microsecond delay to wait for PLL to lock.
+//
+#define PCIEXP_DELAY_US_WAIT_PLL_LOCK       80
+
+//
+// Microsecond delay post issueing sideband interface reset.
+//
+#define PCIEXP_DELAY_US_POST_SBI_RESET      20
+
+//
+// Microsecond delay post deasserting PERST#.
+//
+#define PCIEXP_DELAY_US_POST_PERST_DEASSERT 10
+
+//
+// Catastrophic Trip point in degrees Celsius for this platform.
+//
+#define PLATFORM_CATASTROPHIC_TRIP_CELSIUS  105
+
+//
+// Platform flash update LED common definitions.
+//
+#define PLATFORM_FLASH_UPDATE_LED_TOGGLE_COUNT   7
+#define PLATFORM_FLASH_UPDATE_LED_TOGGLE_DELTA   (1000 * 1000)  // In Microseconds for EFI_STALL.
+
+//
+// This structure stores the base and size of the ACPI reserved memory used when
+// resuming from S3.  This region must be allocated by the platform code.
+//
+typedef struct {
+  UINT32  AcpiReservedMemoryBase;
+  UINT32  AcpiReservedMemorySize;
+  UINT32  SystemMemoryLength;
+} RESERVED_ACPI_S3_RANGE;
+
+#define RESERVED_ACPI_S3_RANGE_OFFSET (EFI_PAGE_SIZE - sizeof (RESERVED_ACPI_S3_RANGE))
+
+//
+// Define valid platform types.
+// First add value before TypePlatformMax in EFI_PLATFORM_TYPE definition
+// and then add string description to end of EFI_PLATFORM_TYPE_NAME_TABLE_DEFINITION.
+// Value shown for supported platforms to help sanity checking with build tools
+// and ACPI method usage.
+//
+typedef enum {
+  TypeUnknown = 0,      // !!! SHOULD BE THE FIRST ENTRY !!!
+  QuarkEmulation = 1,
+  ClantonPeakSVP = 2,
+  KipsBay = 3,
+  CrossHill = 4,
+  ClantonHill = 5,
+  Galileo = 6,
+  TypePlatformRsv7 = 7,
+  GalileoGen2 = 8,
+  TypePlatformMax       // !!! SHOULD BE THE LAST ENTRY !!!
+} EFI_PLATFORM_TYPE;
+
+#define EFI_PLATFORM_TYPE_NAME_TABLE_DEFINITION \
+  L"TypeUnknown",\
+  L"QuarkEmulation",\
+  L"ClantonPeakSVP",\
+  L"KipsBay",\
+  L"CrossHill",\
+  L"ClantonHill",\
+  L"Galileo",\
+  L"TypePlatformRsv7",\
+  L"GalileoGen2",\
+
+typedef struct {
+  UINT32  EntryOffset;
+  UINT8   ImageIndex;
+} QUARK_EDKII_STAGE1_HEADER;
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Include/PlatformBoards.h b/Platform/Intel/QuarkPlatformPkg/Include/PlatformBoards.h
new file mode 100644
index 0000000000..9b0ef88804
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Include/PlatformBoards.h
@@ -0,0 +1,166 @@
+/** @file
+Board config definitions for each of the boards supported by this platform
+package.
+
+Copyright (c) 2013 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+#include "Platform.h"
+
+#ifndef __PLATFORM_BOARDS_H__
+#define __PLATFORM_BOARDS_H__
+
+//
+// Constant definition
+//
+
+//
+// Default resume well TPM reset.
+//
+#define PLATFORM_RESUMEWELL_TPM_RST_GPIO                5
+
+//
+// Basic Configs for GPIO table definitions.
+//
+#define NULL_LEGACY_GPIO_INITIALIZER                    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+#define ALL_INPUT_LEGACY_GPIO_INITIALIZER               {0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x3f,0x3f,0x00,0x00,0x00,0x00,0x00,0x3f,0x00}
+#define QUARK_EMULATION_LEGACY_GPIO_INITIALIZER         ALL_INPUT_LEGACY_GPIO_INITIALIZER
+#define CLANTON_PEAK_SVP_LEGACY_GPIO_INITIALIZER        {0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x3f,0x3f,0x00,0x00,0x3f,0x3f,0x00,0x3f,0x00}
+#define KIPS_BAY_LEGACY_GPIO_INITIALIZER                {0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x3f,0x25,0x10,0x00,0x00,0x00,0x00,0x3f,0x00}
+#define CROSS_HILL_LEGACY_GPIO_INITIALIZER              {0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x3f,0x03,0x10,0x00,0x03,0x03,0x00,0x3f,0x00}
+#define CLANTON_HILL_LEGACY_GPIO_INITIALIZER            {0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x3f,0x06,0x10,0x00,0x04,0x04,0x00,0x3f,0x00}
+#define GALILEO_LEGACY_GPIO_INITIALIZER                 {0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x3f,0x21,0x14,0x00,0x00,0x00,0x00,0x3f,0x00}
+#define GALILEO_GEN2_LEGACY_GPIO_INITIALIZER            {0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x3f,0x1c,0x02,0x00,0x00,0x00,0x00,0x3f,0x00}
+
+#define NULL_GPIO_CONTROLLER_INITIALIZER                {0,0,0,0,0,0,0,0}
+#define ALL_INPUT_GPIO_CONTROLLER_INITIALIZER           NULL_GPIO_CONTROLLER_INITIALIZER
+#define QUARK_EMULATION_GPIO_CONTROLLER_INITIALIZER     NULL_GPIO_CONTROLLER_INITIALIZER
+#define CLANTON_PEAK_SVP_GPIO_CONTROLLER_INITIALIZER    NULL_GPIO_CONTROLLER_INITIALIZER
+#define KIPS_BAY_GPIO_CONTROLLER_INITIALIZER            {0x05,0x05,0,0,0,0,0,0}
+#define CROSS_HILL_GPIO_CONTROLLER_INITIALIZER          {0x0D,0x2D,0,0,0,0,0,0}
+#define CLANTON_HILL_GPIO_CONTROLLER_INITIALIZER        {0x01,0x39,0,0,0,0,0,0}
+#define GALILEO_GPIO_CONTROLLER_INITIALIZER             {0x05,0x15,0,0,0,0,0,0}
+#define GALILEO_GEN2_GPIO_CONTROLLER_INITIALIZER        {0x05,0x05,0,0,0,0,0,0}
+
+//
+// Legacy Gpio to be used to assert / deassert PCI express PERST# signal
+// on Galileo Gen 2 platform.
+//
+#define GALILEO_GEN2_PCIEXP_PERST_RESUMEWELL_GPIO       0
+
+//
+// Io expander slave address.
+//
+
+//
+// On Galileo value of Jumper J2 determines slave address of io expander.
+//
+#define GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO     5
+#define GALILEO_IOEXP_J2HI_7BIT_SLAVE_ADDR              0x20
+#define GALILEO_IOEXP_J2LO_7BIT_SLAVE_ADDR              0x21
+
+//
+// Three IO Expmanders at fixed addresses on Galileo Gen2.
+//
+#define GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR             0x25
+#define GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR             0x26
+#define GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR             0x27
+
+//
+// Led GPIOs for flash update / recovery.
+//
+#define GALILEO_FLASH_UPDATE_LED_RESUMEWELL_GPIO        1
+#define GALILEO_GEN2_FLASH_UPDATE_LED_RESUMEWELL_GPIO   5
+
+//
+// Legacy GPIO config struct for each element in PLATFORM_LEGACY_GPIO_TABLE_DEFINITION.
+//
+typedef struct {
+  UINT32  CoreWellEnable;               ///< Value for QNC NC Reg R_QNC_GPIO_CGEN_CORE_WELL.
+  UINT32  CoreWellIoSelect;             ///< Value for QNC NC Reg R_QNC_GPIO_CGIO_CORE_WELL.
+  UINT32  CoreWellLvlForInputOrOutput;  ///< Value for QNC NC Reg R_QNC_GPIO_CGLVL_CORE_WELL.
+  UINT32  CoreWellTriggerPositiveEdge;  ///< Value for QNC NC Reg R_QNC_GPIO_CGTPE_CORE_WELL.
+  UINT32  CoreWellTriggerNegativeEdge;  ///< Value for QNC NC Reg R_QNC_GPIO_CGTNE_CORE_WELL.
+  UINT32  CoreWellGPEEnable;            ///< Value for QNC NC Reg R_QNC_GPIO_CGGPE_CORE_WELL.
+  UINT32  CoreWellSMIEnable;            ///< Value for QNC NC Reg R_QNC_GPIO_CGSMI_CORE_WELL.
+  UINT32  CoreWellTriggerStatus;        ///< Value for QNC NC Reg R_QNC_GPIO_CGTS_CORE_WELL.
+  UINT32  CoreWellNMIEnable;            ///< Value for QNC NC Reg R_QNC_GPIO_CGNMIEN_CORE_WELL.
+  UINT32  ResumeWellEnable;             ///< Value for QNC NC Reg R_QNC_GPIO_RGEN_RESUME_WELL.
+  UINT32  ResumeWellIoSelect;           ///< Value for QNC NC Reg R_QNC_GPIO_RGIO_RESUME_WELL.
+  UINT32  ResumeWellLvlForInputOrOutput;///< Value for QNC NC Reg R_QNC_GPIO_RGLVL_RESUME_WELL.
+  UINT32  ResumeWellTriggerPositiveEdge;///< Value for QNC NC Reg R_QNC_GPIO_RGTPE_RESUME_WELL.
+  UINT32  ResumeWellTriggerNegativeEdge;///< Value for QNC NC Reg R_QNC_GPIO_RGTNE_RESUME_WELL.
+  UINT32  ResumeWellGPEEnable;          ///< Value for QNC NC Reg R_QNC_GPIO_RGGPE_RESUME_WELL.
+  UINT32  ResumeWellSMIEnable;          ///< Value for QNC NC Reg R_QNC_GPIO_RGSMI_RESUME_WELL.
+  UINT32  ResumeWellTriggerStatus;      ///< Value for QNC NC Reg R_QNC_GPIO_RGTS_RESUME_WELL.
+  UINT32  ResumeWellNMIEnable;          ///< Value for QNC NC Reg R_QNC_GPIO_RGNMIEN_RESUME_WELL.
+} BOARD_LEGACY_GPIO_CONFIG;
+
+//
+// GPIO controller config struct for each element in PLATFORM_GPIO_CONTROLLER_CONFIG_DEFINITION.
+//
+typedef struct {
+  UINT32  PortADR;                      ///< Value for IOH REG GPIO_SWPORTA_DR.
+  UINT32  PortADir;                     ///< Value for IOH REG GPIO_SWPORTA_DDR.
+  UINT32  IntEn;                        ///< Value for IOH REG GPIO_INTEN.
+  UINT32  IntMask;                      ///< Value for IOH REG GPIO_INTMASK.
+  UINT32  IntType;                      ///< Value for IOH REG GPIO_INTTYPE_LEVEL.
+  UINT32  IntPolarity;                  ///< Value for IOH REG GPIO_INT_POLARITY.
+  UINT32  Debounce;                     ///< Value for IOH REG GPIO_DEBOUNCE.
+  UINT32  LsSync;                       ///< Value for IOH REG GPIO_LS_SYNC.
+} BOARD_GPIO_CONTROLLER_CONFIG;
+
+///
+/// Table of BOARD_LEGACY_GPIO_CONFIG structures for each board supported
+/// by this platform package.
+/// Table indexed with EFI_PLATFORM_TYPE enum value.
+///
+#define PLATFORM_LEGACY_GPIO_TABLE_DEFINITION \
+  /* EFI_PLATFORM_TYPE - TypeUnknown*/\
+  NULL_LEGACY_GPIO_INITIALIZER,\
+  /* EFI_PLATFORM_TYPE - QuarkEmulation*/\
+  QUARK_EMULATION_LEGACY_GPIO_INITIALIZER,\
+  /* EFI_PLATFORM_TYPE - ClantonPeakSVP*/\
+  CLANTON_PEAK_SVP_LEGACY_GPIO_INITIALIZER,\
+  /* EFI_PLATFORM_TYPE - KipsBay*/\
+  KIPS_BAY_LEGACY_GPIO_INITIALIZER,\
+  /* EFI_PLATFORM_TYPE - CrossHill*/\
+  CROSS_HILL_LEGACY_GPIO_INITIALIZER,\
+  /* EFI_PLATFORM_TYPE - ClantonHill*/\
+  CLANTON_HILL_LEGACY_GPIO_INITIALIZER,\
+  /* EFI_PLATFORM_TYPE - Galileo*/\
+  GALILEO_LEGACY_GPIO_INITIALIZER,\
+  /* EFI_PLATFORM_TYPE - TypePlatformRsv7*/\
+  NULL_LEGACY_GPIO_INITIALIZER,\
+  /* EFI_PLATFORM_TYPE - GalileoGen2*/\
+  GALILEO_GEN2_LEGACY_GPIO_INITIALIZER,\
+
+///
+/// Table of BOARD_GPIO_CONTROLLER_CONFIG structures for each board
+/// supported by this platform package.
+/// Table indexed with EFI_PLATFORM_TYPE enum value.
+///
+#define PLATFORM_GPIO_CONTROLLER_CONFIG_DEFINITION \
+  /* EFI_PLATFORM_TYPE - TypeUnknown*/\
+  NULL_GPIO_CONTROLLER_INITIALIZER,\
+  /* EFI_PLATFORM_TYPE - QuarkEmulation*/\
+  QUARK_EMULATION_GPIO_CONTROLLER_INITIALIZER,\
+  /* EFI_PLATFORM_TYPE - ClantonPeakSVP*/\
+  CLANTON_PEAK_SVP_GPIO_CONTROLLER_INITIALIZER,\
+  /* EFI_PLATFORM_TYPE - KipsBay*/\
+  KIPS_BAY_GPIO_CONTROLLER_INITIALIZER,\
+  /* EFI_PLATFORM_TYPE - CrossHill*/\
+  CROSS_HILL_GPIO_CONTROLLER_INITIALIZER,\
+  /* EFI_PLATFORM_TYPE - ClantonHill*/\
+  CLANTON_HILL_GPIO_CONTROLLER_INITIALIZER,\
+  /* EFI_PLATFORM_TYPE - Galileo*/\
+  GALILEO_GPIO_CONTROLLER_INITIALIZER,\
+  /* EFI_PLATFORM_TYPE - TypePlatformRsv7 */\
+  NULL_GPIO_CONTROLLER_INITIALIZER,\
+  /* EFI_PLATFORM_TYPE - GalileoGen2*/\
+  GALILEO_GEN2_GPIO_CONTROLLER_INITIALIZER,\
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Include/Protocol/GlobalNvsArea.h b/Platform/Intel/QuarkPlatformPkg/Include/Protocol/GlobalNvsArea.h
new file mode 100644
index 0000000000..fca6ad7067
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Include/Protocol/GlobalNvsArea.h
@@ -0,0 +1,82 @@
+/** @file
+Definition of the global NVS area protocol.  This protocol
+publishes the address and format of a global ACPI NVS buffer
+used as a communications buffer between SMM code and ASL code.
+The format is derived from the ACPI reference code, version 0.95.
+Note:  Data structures defined in this protocol are not naturally aligned.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _GLOBAL_NVS_AREA_H_
+#define _GLOBAL_NVS_AREA_H_
+
+//
+// Forward reference for pure ANSI compatability
+//
+
+typedef struct _EFI_GLOBAL_NVS_AREA_PROTOCOL EFI_GLOBAL_NVS_AREA_PROTOCOL;
+
+//
+// Global NVS Area Protocol GUID
+//
+#define EFI_GLOBAL_NVS_AREA_PROTOCOL_GUID \
+{ 0x74e1e48, 0x8132, 0x47a1, {0x8c, 0x2c, 0x3f, 0x14, 0xad, 0x9a, 0x66, 0xdc} }
+
+
+//
+// Global NVS Area definition
+//
+#pragma pack (1)
+typedef struct {
+  //
+  // Miscellaneous Dynamic Values
+  //
+  UINT32      OperatingSystemType;    // Os type indicator
+  UINT32      Cfgd;                   // System configuration description
+  UINT32      HpetEnable;
+
+  UINT32      Pm1blkIoBaseAddress;
+  UINT32      PmbaIoBaseAddress;
+  UINT32      Gpe0blkIoBaseAddress;
+  UINT32      GbaIoBaseAddress;
+
+  UINT32      SmbaIoBaseAddress;
+  UINT32      Reserved1;
+  UINT32      WdtbaIoBaseAddress;
+
+  UINT32      HpetBaseAddress;
+  UINT32      HpetSize;
+  UINT32      PciExpressBaseAddress;
+  UINT32      PciExpressSize;
+
+  UINT32      RcbaMmioBaseAddress;
+  UINT32      RcbaMmioSize;
+  UINT32      IoApicBaseAddress;
+  UINT32      IoApicSize;
+
+  UINT32      TpmPresent;
+  UINT32      DBG2Present;
+  UINT32      PlatformType;           // Set to one of EFI_PLATFORM_TYPE enums.
+  UINT32      AlternateSla;           // If TRUE use alternate I2C Slave addresses.
+
+  UINT8       Reserved[512 - 4 * 22]; // Total 512 Bytes
+} EFI_GLOBAL_NVS_AREA;
+#pragma pack ()
+
+//
+// Global NVS Area Protocol
+//
+struct _EFI_GLOBAL_NVS_AREA_PROTOCOL {
+  EFI_GLOBAL_NVS_AREA     *Area;
+};
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gEfiGlobalNvsAreaProtocolGuid;
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Include/Protocol/PlatformSmmSpiReady.h b/Platform/Intel/QuarkPlatformPkg/Include/Protocol/PlatformSmmSpiReady.h
new file mode 100644
index 0000000000..5913e4467b
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Include/Protocol/PlatformSmmSpiReady.h
@@ -0,0 +1,23 @@
+/** @file
+This protocol indicates that the platform SPI interface is ready for use.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#ifndef _PLATFORM_SPI_READY_H_
+#define _PLATFORM_SPI_READY_H_
+
+// {7A5DBC75-5B2B-4e67-BDE1-D48EEE761562}
+#define EFI_SMM_SPI_READY_PROTOCOL_GUID  \
+  { 0x7a5dbc75, 0x5b2b, 0x4e67, 0xbd, 0xe1, 0xd4, 0x8e, 0xee, 0x76, 0x15, 0x62 }
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID                     gEfiSmmSpiReadyProtocolGuid;
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManager.c b/Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManager.c
new file mode 100644
index 0000000000..c00284c262
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManager.c
@@ -0,0 +1,472 @@
+/** @file
+This file include all platform action which can be customized
+by IBV/OEM.
+
+Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PlatformBootManager.h"
+
+/**
+  Return the index of the load option in the load option array.
+
+  The function consider two load options are equal when the
+  OptionType, Attributes, Description, FilePath and OptionalData are equal.
+
+  @param Key    Pointer to the load option to be found.
+  @param Array  Pointer to the array of load options to be found.
+  @param Count  Number of entries in the Array.
+
+  @retval -1          Key wasn't found in the Array.
+  @retval 0 ~ Count-1 The index of the Key in the Array.
+**/
+INTN
+PlatformFindLoadOption (
+  IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Key,
+  IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Array,
+  IN UINTN                              Count
+  )
+{
+  UINTN                             Index;
+
+  for (Index = 0; Index < Count; Index++) {
+    if ((Key->OptionType == Array[Index].OptionType) &&
+        (Key->Attributes == Array[Index].Attributes) &&
+        (StrCmp (Key->Description, Array[Index].Description) == 0) &&
+        (CompareMem (Key->FilePath, Array[Index].FilePath, GetDevicePathSize (Key->FilePath)) == 0) &&
+        (Key->OptionalDataSize == Array[Index].OptionalDataSize) &&
+        (CompareMem (Key->OptionalData, Array[Index].OptionalData, Key->OptionalDataSize) == 0)) {
+      return (INTN) Index;
+    }
+  }
+
+  return -1;
+}
+
+VOID
+PlatformRegisterFvBootOption (
+  EFI_GUID  *FileGuid,
+  CHAR16    *Description,
+  UINT32    Attributes
+  )
+{
+  EFI_STATUS                        Status;
+  EFI_HANDLE                        *HandleBuffer;
+  UINTN                             HandleCount;
+  UINTN                             IndexFv;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL     *Fv;
+  CHAR16                            *UiSection;
+  UINTN                             UiSectionLength;
+  UINT32                            AuthenticationStatus;
+  EFI_HANDLE                        FvHandle;
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;
+  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;
+  EFI_BOOT_MANAGER_LOAD_OPTION      *BootOptions;
+  UINTN                             BootOptionCount;
+  UINTN                             OptionIndex;
+  EFI_BOOT_MANAGER_LOAD_OPTION      NewOption;
+
+  //
+  // Locate all available FVs.
+  //
+  HandleBuffer = NULL;
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiFirmwareVolume2ProtocolGuid,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer
+                  );
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  //
+  // Go through FVs one by one to find the required FFS file
+  //
+  for (IndexFv = 0, FvHandle = NULL; IndexFv < HandleCount && FvHandle == NULL; IndexFv++) {
+    Status = gBS->HandleProtocol (
+                    HandleBuffer[IndexFv],
+                    &gEfiFirmwareVolume2ProtocolGuid,
+                    (VOID **)&Fv
+                    );
+    if (EFI_ERROR (Status)) {
+      continue;
+    }
+
+    //
+    // Attempt to read a EFI_SECTION_USER_INTERFACE section from the required FFS file
+    //
+    UiSection = NULL;
+    Status = Fv->ReadSection (
+                   Fv,
+                   FileGuid,
+                   EFI_SECTION_USER_INTERFACE,
+                   0,
+                   (VOID **) &UiSection,
+                   &UiSectionLength,
+                   &AuthenticationStatus
+                   );
+    if (EFI_ERROR (Status)) {
+      continue;
+    }
+    FreePool (UiSection);
+
+    //
+    // Save the handle of the FV where the FFS file was found
+    //
+    FvHandle = HandleBuffer[IndexFv];
+  }
+
+  //
+  // Free the buffer of FV handles
+  //
+  FreePool (HandleBuffer);
+
+  //
+  // If the FFS file was not found, then return
+  //
+  if (FvHandle == NULL) {
+    return;
+  }
+
+  //
+  // Create a device path for the FFS file that was found
+  //
+  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
+  DevicePath = AppendDevicePathNode (
+                 DevicePathFromHandle (FvHandle),
+                 (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
+                 );
+
+  //
+  // Create and add a new load option for the FFS file that was found
+  //
+  Status = EfiBootManagerInitializeLoadOption (
+             &NewOption,
+             LoadOptionNumberUnassigned,
+             LoadOptionTypeBoot,
+             Attributes,
+             Description,
+             DevicePath,
+             NULL,
+             0
+             );
+  if (!EFI_ERROR (Status)) {
+    BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
+
+    OptionIndex = PlatformFindLoadOption (&NewOption, BootOptions, BootOptionCount);
+
+    if (OptionIndex == -1) {
+      Status = EfiBootManagerAddLoadOptionVariable (&NewOption, (UINTN) -1);
+      ASSERT_EFI_ERROR (Status);
+    }
+    EfiBootManagerFreeLoadOption (&NewOption);
+    EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
+  }
+}
+
+VOID
+EFIAPI
+InternalBdsEmptyCallbackFuntion (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  return;
+}
+
+/**
+  Do the platform specific action before the console is connected.
+
+  Such as:
+    Update console variable;
+    Register new Driver#### or Boot####;
+    Signal ReadyToLock event.
+**/
+VOID
+EFIAPI
+PlatformBootManagerBeforeConsole (
+  VOID
+  )
+{
+  EFI_STATUS                    Status;
+  UINTN                         Index;
+  EFI_INPUT_KEY                 Enter;
+  EFI_INPUT_KEY                 F2;
+  EFI_BOOT_MANAGER_LOAD_OPTION  BootOption;
+  ESRT_MANAGEMENT_PROTOCOL      *EsrtManagement;
+  EFI_BOOT_MODE                 BootMode;
+  EFI_ACPI_S3_SAVE_PROTOCOL     *AcpiS3Save;
+  EFI_HANDLE                    Handle;
+  EFI_EVENT                     EndOfDxeEvent;
+
+  //
+  // Update the console variables.
+  //
+  for (Index = 0; gPlatformConsole[Index].DevicePath != NULL; Index++) {
+    if ((gPlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
+      EfiBootManagerUpdateConsoleVariable (ConIn, gPlatformConsole[Index].DevicePath, NULL);
+    }
+
+    if ((gPlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
+      EfiBootManagerUpdateConsoleVariable (ConOut, gPlatformConsole[Index].DevicePath, NULL);
+    }
+
+    if ((gPlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
+      EfiBootManagerUpdateConsoleVariable (ErrOut, gPlatformConsole[Index].DevicePath, NULL);
+    }
+  }
+
+  //
+  // Register ENTER as CONTINUE key
+  //
+  Enter.ScanCode    = SCAN_NULL;
+  Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
+  EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
+
+  //
+  // Map F2 to Boot Manager Menu
+  //
+  F2.ScanCode    = SCAN_F2;
+  F2.UnicodeChar = CHAR_NULL;
+  EfiBootManagerGetBootManagerMenu (&BootOption);
+  EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL);
+
+  //
+  // Register UEFI Shell
+  //
+  PlatformRegisterFvBootOption (&gUefiShellFileGuid, L"UEFI Shell", LOAD_OPTION_ACTIVE);
+
+  Status = gBS->LocateProtocol(&gEsrtManagementProtocolGuid, NULL, (VOID **)&EsrtManagement);
+  if (EFI_ERROR(Status)) {
+    EsrtManagement = NULL;
+  }
+
+  BootMode = GetBootModeHob();
+  switch (BootMode) {
+  case BOOT_ON_FLASH_UPDATE:
+    DEBUG((DEBUG_INFO, "ProcessCapsules Before EndOfDxe ......\n"));
+    Status = ProcessCapsules ();
+    DEBUG((DEBUG_INFO, "ProcessCapsules %r\n", Status));
+    break;
+  case BOOT_IN_RECOVERY_MODE:
+    break;
+  case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
+  case BOOT_WITH_MINIMAL_CONFIGURATION:
+  case BOOT_ON_S4_RESUME:
+    if (EsrtManagement != NULL) {
+      //
+      // Lock ESRT cache repository before EndofDxe if ESRT sync is not needed
+      //
+      EsrtManagement->LockEsrtRepository();
+    }
+    break;
+  default:
+    //
+    // Require to sync ESRT from FMP in a new boot
+    //
+    if (EsrtManagement != NULL) {
+      EsrtManagement->SyncEsrtFmp();
+    }
+    break;
+  }
+
+  //
+  // Prepare for S3
+  //
+  Status = gBS->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid, NULL, (VOID **)&AcpiS3Save);
+  if (!EFI_ERROR (Status)) {
+    AcpiS3Save->S3Save (AcpiS3Save, NULL);
+  }
+
+  //
+  // Inform PI SMM drivers that BDS may run 3rd party code
+  // Create and signal End of DXE event group
+  //
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  InternalBdsEmptyCallbackFuntion,
+                  NULL,
+                  &gEfiEndOfDxeEventGroupGuid,
+                  &EndOfDxeEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+  gBS->SignalEvent (EndOfDxeEvent);
+  gBS->CloseEvent (EndOfDxeEvent);
+
+  DEBUG((EFI_D_INFO,"All EndOfDxe callbacks have returned successfully\n"));
+
+  //
+  // Install SMM Ready To Lock protocol so all resources can be locked down
+  // before BDS runs 3rd party code.  This action must be done last so all
+  // other SMM driver signals are processed before this final lock down action.
+  //
+  Handle = NULL;
+  Status = gBS->InstallProtocolInterface (
+                  &Handle,
+                  &gEfiDxeSmmReadyToLockProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Dispatch deferred images after EndOfDxe event and ReadyToLock installation.
+  //
+  EfiBootManagerDispatchDeferredImages ();
+}
+
+/**
+  Do the platform specific action after the console is connected.
+
+  Such as:
+    Dynamically switch output mode;
+    Signal console ready platform customized event;
+    Run diagnostics like memory testing;
+    Connect certain devices;
+    Dispatch additional option ROMs
+**/
+VOID
+EFIAPI
+PlatformBootManagerAfterConsole (
+  VOID
+  )
+{
+  EFI_STATUS                     Status;
+  EFI_BOOT_MODE                  BootMode;
+  ESRT_MANAGEMENT_PROTOCOL       *EsrtManagement;
+  VOID                           *Buffer;
+  UINTN                          Size;
+
+  Status = gBS->LocateProtocol(&gEsrtManagementProtocolGuid, NULL, (VOID **)&EsrtManagement);
+  if (EFI_ERROR(Status)) {
+    EsrtManagement = NULL;
+  }
+
+  BootMode = GetBootModeHob();
+
+  DEBUG((DEBUG_INFO, "PlatformBootManagerAfterConsole(): BootMode = %02x\n", BootMode));
+
+  switch (BootMode) {
+  case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
+  case BOOT_WITH_MINIMAL_CONFIGURATION:
+  case BOOT_ON_S4_RESUME:
+    EfiBootManagerRefreshAllBootOption ();
+    break;
+
+  case BOOT_ON_FLASH_UPDATE:
+    if (FeaturePcdGet(PcdSupportUpdateCapsuleReset)) {
+      EfiBootManagerConnectAll ();
+      EfiBootManagerRefreshAllBootOption ();
+
+      //
+      // Always sync ESRT Cache from FMP Instances after connect all and before capsule process
+      //
+      if (EsrtManagement != NULL) {
+        EsrtManagement->SyncEsrtFmp();
+      }
+
+      DEBUG((DEBUG_INFO, "ProcessCapsules After ConnectAll ......\n"));
+      Status = ProcessCapsules();
+      DEBUG((DEBUG_INFO, "ProcessCapsules %r\n", Status));
+    }
+    break;
+
+  default:
+    EfiBootManagerConnectAll ();
+    EfiBootManagerRefreshAllBootOption ();
+
+    //
+    // Sync ESRT Cache from FMP Instance on demand after Connect All
+    //
+    if (EsrtManagement != NULL) {
+      EsrtManagement->SyncEsrtFmp();
+    }
+    break;
+  }
+
+  Print (
+    L"\n"
+    L"F2      to enter Boot Manager Menu.\n"
+    L"ENTER   to boot directly.\n"
+    L"\n"
+    );
+
+  //
+  // Check if the platform is using test key.
+  //
+  Status = GetSectionFromAnyFv(
+             PcdGetPtr(PcdEdkiiRsa2048Sha256TestPublicKeyFileGuid),
+             EFI_SECTION_RAW,
+             0,
+             &Buffer,
+             &Size
+             );
+  if (!EFI_ERROR(Status)) {
+    if ((Size == PcdGetSize(PcdRsa2048Sha256PublicKeyBuffer)) &&
+        (CompareMem(Buffer, PcdGetPtr(PcdRsa2048Sha256PublicKeyBuffer), Size) == 0)) {
+      Print(L"WARNING: Recovery Test Key is used.\n");
+      PcdSetBoolS(PcdTestKeyUsed, TRUE);
+    }
+    FreePool(Buffer);
+  }
+  Status = GetSectionFromAnyFv(
+             PcdGetPtr(PcdEdkiiPkcs7TestPublicKeyFileGuid),
+             EFI_SECTION_RAW,
+             0,
+             &Buffer,
+             &Size
+             );
+  if (!EFI_ERROR(Status)) {
+    if ((Size == PcdGetSize(PcdPkcs7CertBuffer)) &&
+        (CompareMem(Buffer, PcdGetPtr(PcdPkcs7CertBuffer), Size) == 0)) {
+      Print(L"WARNING: Capsule Test Key is used.\n");
+      PcdSetBoolS(PcdTestKeyUsed, TRUE);
+    }
+    FreePool(Buffer);
+  }
+
+  //
+  // Use a DynamicHii type pcd to save the boot status, which is used to
+  // control configuration mode, such as FULL/MINIMAL/NO_CHANGES configuration.
+  //
+  if (PcdGetBool(PcdBootState)) {
+    Status = PcdSetBoolS (PcdBootState, FALSE);
+    ASSERT_EFI_ERROR (Status);
+  }
+}
+
+/**
+  This function is called each second during the boot manager waits the timeout.
+
+  @param TimeoutRemain  The remaining timeout.
+**/
+VOID
+EFIAPI
+PlatformBootManagerWaitCallback (
+  UINT16  TimeoutRemain
+  )
+{
+  Print (L"\r%-2d seconds remained...", TimeoutRemain);
+}
+
+/**
+  The function is called when no boot option could be launched,
+  including platform recovery options and options pointing to applications
+  built into firmware volumes.
+
+  If this function returns, BDS attempts to enter an infinite loop.
+**/
+VOID
+EFIAPI
+PlatformBootManagerUnableToBoot (
+  VOID
+  )
+{
+  return;
+}
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManager.h b/Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManager.h
new file mode 100644
index 0000000000..bd4f224783
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManager.h
@@ -0,0 +1,49 @@
+/** @file
+Head file for BDS Platform specific code
+
+Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_BOOT_MANAGER_H
+#define _PLATFORM_BOOT_MANAGER_H
+
+#include <PiDxe.h>
+
+#include <Library/PlatformBootManagerLib.h>
+
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/AcpiS3Save.h>
+#include <Protocol/DxeSmmReadyToLock.h>
+#include <Protocol/EsrtManagement.h>
+#include <Guid/DebugAgentGuid.h>
+#include <Guid/EventGroup.h>
+#include <Guid/PcAnsi.h>
+#include <Guid/TtyTerm.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootManagerLib.h>
+#include <Library/PrintLib.h>
+#include <Library/HobLib.h>
+#include <Library/CapsuleLib.h>
+#include <Library/DxeServicesLib.h>
+
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  UINTN                     ConnectType;
+} PLATFORM_CONSOLE_CONNECT_ENTRY;
+
+extern PLATFORM_CONSOLE_CONNECT_ENTRY  gPlatformConsole[];
+
+#define CONSOLE_OUT BIT0
+#define CONSOLE_IN  BIT1
+#define STD_ERROR   BIT2
+
+#endif // _PLATFORM_BOOT_MANAGER_H
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
new file mode 100644
index 0000000000..d58c243357
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
@@ -0,0 +1,83 @@
+## @file
+#  Include all platform action which can be customized by IBV/OEM.
+#
+#  Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformBootManagerLib
+  FILE_GUID                      = EC67889B-9E62-4c81-8CA0-86E6A6EEE61A
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformBootManagerLib|DXE_DRIVER
+  CONSTRUCTOR                    = InitializePlatformBootManagerLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  PlatformData.c
+  PlatformBootManager.c
+  PlatformBootManager.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+  SourceLevelDebugPkg/SourceLevelDebugPkg.dec
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+  SecurityPkg/SecurityPkg.dec
+  ShellPkg/ShellPkg.dec
+  SignedCapsulePkg/SignedCapsulePkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  PcdLib
+  DebugLib
+  DevicePathLib
+  MemoryAllocationLib
+  UefiBootServicesTableLib
+  UefiLib
+  UefiBootManagerLib
+  PrintLib
+  HobLib
+  CapsuleLib
+  DxeServicesLib
+
+[Protocols]
+  gEfiFirmwareVolume2ProtocolGuid
+  gEfiAcpiS3SaveProtocolGuid
+  gEfiDxeSmmReadyToLockProtocolGuid
+  gEsrtManagementProtocolGuid
+
+[Guids]
+  gEfiPcAnsiGuid
+  gEfiVT100Guid
+  gEfiVT100PlusGuid
+  gEfiVTUTF8Guid
+  gEfiTtyTermGuid
+  gEfiEndOfDxeEventGroupGuid
+  gUefiShellFileGuid
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits
+  gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBootState
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset
+  gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiRsa2048Sha256TestPublicKeyFileGuid
+  gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiPkcs7TestPublicKeyFileGuid
+  gEfiSecurityPkgTokenSpaceGuid.PcdRsa2048Sha256PublicKeyBuffer
+  gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer
+  gEfiMdeModulePkgTokenSpaceGuid.PcdTestKeyUsed
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformData.c b/Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformData.c
new file mode 100644
index 0000000000..a62fc34ead
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformData.c
@@ -0,0 +1,275 @@
+/** @file
+Defined the platform specific device path which will be filled to
+ConIn/ConOut variables.
+
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PlatformBootManager.h"
+
+///
+/// the short form device path for Usb keyboard
+///
+#define CLASS_HID           3
+#define SUBCLASS_BOOT       1
+#define PROTOCOL_KEYBOARD   1
+
+///
+/// PcdDefaultTerminalType values
+///
+#define PCANSITYPE                0
+#define VT100TYPE                 1
+#define VT100PLUSTYPE             2
+#define VTUTF8TYPE                3
+#define TTYTERMTYPE               4
+
+//
+// Below is the platform console device path
+//
+typedef struct {
+  ACPI_HID_DEVICE_PATH            PciRootBridge;
+  PCI_DEVICE_PATH                 PciUart;
+  UART_DEVICE_PATH                Uart;
+  VENDOR_DEVICE_PATH              TerminalType;
+  EFI_DEVICE_PATH_PROTOCOL        End;
+} PCI_UART_DEVICE_PATH;
+
+typedef struct {
+  VENDOR_DEVICE_PATH        VendorHardware;
+  UART_DEVICE_PATH          Uart;
+  VENDOR_DEVICE_PATH        TerminalType;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} VENDOR_UART_DEVICE_PATH;
+
+typedef struct {
+  USB_CLASS_DEVICE_PATH           UsbClass;
+  EFI_DEVICE_PATH_PROTOCOL        End;
+} USB_CLASS_FORMAT_DEVICE_PATH;
+
+#define PNPID_DEVICE_PATH_NODE(PnpId) \
+  { \
+    { \
+      ACPI_DEVICE_PATH, \
+      ACPI_DP, \
+      { \
+        (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \
+        (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \
+      } \
+    }, \
+    EISA_PNP_ID((PnpId)), \
+    0 \
+  }
+
+#define PCI_DEVICE_PATH_NODE(Func, Dev) \
+  { \
+    { \
+      HARDWARE_DEVICE_PATH, \
+      HW_PCI_DP, \
+      { \
+        (UINT8) (sizeof (PCI_DEVICE_PATH)), \
+        (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) \
+      }, \
+    }, \
+    (Func), \
+    (Dev) \
+  }
+
+#define gEndEntire \
+  { \
+    END_DEVICE_PATH_TYPE, \
+    END_ENTIRE_DEVICE_PATH_SUBTYPE, \
+    { \
+      END_DEVICE_PATH_LENGTH, \
+      0 \
+    } \
+  }
+
+//
+// Platform specific serial device path
+//
+PCI_UART_DEVICE_PATH   gPciUartDevicePath0 = {
+  PNPID_DEVICE_PATH_NODE(0x0A03),
+  PCI_DEVICE_PATH_NODE(1, 20),
+  {
+    {
+      MESSAGING_DEVICE_PATH,
+      MSG_UART_DP,
+      {
+        (UINT8)(sizeof (UART_DEVICE_PATH)),
+        (UINT8)((sizeof (UART_DEVICE_PATH)) >> 8)
+      }
+    },
+    0,         // Reserved
+    921600,    // BaudRate
+    8,         // DataBits
+    1,         // Parity
+    1          // StopBits
+  },
+  {
+    {
+      MESSAGING_DEVICE_PATH,
+      MSG_VENDOR_DP,
+      {
+        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
+        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+      },
+    },
+    DEVICE_PATH_MESSAGING_PC_ANSI
+  },
+  gEndEntire
+};
+
+PCI_UART_DEVICE_PATH   gPciUartDevicePath1 = {
+  PNPID_DEVICE_PATH_NODE(0x0A03),
+  PCI_DEVICE_PATH_NODE(5, 20),
+  {
+    {
+      MESSAGING_DEVICE_PATH,
+      MSG_UART_DP,
+      {
+        (UINT8)(sizeof (UART_DEVICE_PATH)),
+        (UINT8)((sizeof (UART_DEVICE_PATH)) >> 8)
+      }
+    },
+    0,         // Reserved
+    921600,    // BaudRate
+    8,         // DataBits
+    1,         // Parity
+    1          // StopBits
+  },
+  {
+    {
+      MESSAGING_DEVICE_PATH,
+      MSG_VENDOR_DP,
+      {
+        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
+        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+      }
+    },
+    DEVICE_PATH_MESSAGING_PC_ANSI
+  },
+  gEndEntire
+};
+
+VENDOR_UART_DEVICE_PATH gDebugAgentUartDevicePath = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      {
+        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+      }
+    },
+    EFI_DEBUG_AGENT_GUID,
+  },
+  {
+    {
+      MESSAGING_DEVICE_PATH,
+      MSG_UART_DP,
+      {
+        (UINT8) (sizeof (UART_DEVICE_PATH)),
+        (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8)
+      }
+    },
+    0,  // Reserved
+    0,  // BaudRate - Default
+    0,  // DataBits - Default
+    0,  // Parity   - Default
+    0,  // StopBits - Default
+  },
+  {
+    {
+      MESSAGING_DEVICE_PATH,
+      MSG_VENDOR_DP,
+      {
+        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
+        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+      }
+    },
+    DEVICE_PATH_MESSAGING_PC_ANSI
+  },
+  gEndEntire
+};
+
+USB_CLASS_FORMAT_DEVICE_PATH gUsbClassKeyboardDevicePath = {
+  {
+    {
+      MESSAGING_DEVICE_PATH,
+      MSG_USB_CLASS_DP,
+      {
+        (UINT8)(sizeof (USB_CLASS_DEVICE_PATH)),
+        (UINT8)((sizeof (USB_CLASS_DEVICE_PATH)) >> 8)
+      }
+    },
+    0xffff,              // VendorId  - Match any vendor
+    0xffff,              // ProductId - Match any product
+    CLASS_HID,           // DeviceClass
+    SUBCLASS_BOOT,       // DeviceSubClass
+    PROTOCOL_KEYBOARD    // DeviceProtocol
+  },
+  gEndEntire
+};
+
+//
+// Predefined platform default console device path
+//
+PLATFORM_CONSOLE_CONNECT_ENTRY   gPlatformConsole[] = {
+  { (EFI_DEVICE_PATH_PROTOCOL *) &gPciUartDevicePath0,         (CONSOLE_OUT | CONSOLE_IN) },
+  { (EFI_DEVICE_PATH_PROTOCOL *) &gPciUartDevicePath1,         (CONSOLE_OUT | CONSOLE_IN) },
+  { (EFI_DEVICE_PATH_PROTOCOL *) &gDebugAgentUartDevicePath,   (CONSOLE_OUT | CONSOLE_IN) },
+  { (EFI_DEVICE_PATH_PROTOCOL *) &gUsbClassKeyboardDevicePath, (CONSOLE_IN)               },
+  { NULL, 0 }
+};
+
+EFI_STATUS
+EFIAPI
+InitializePlatformBootManagerLib (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_GUID  *TerminalTypeGuid;
+
+  //
+  // Update UART device path nodes based on UART PCD settings
+  //
+  gPciUartDevicePath0.Uart.BaudRate = PcdGet64 (PcdUartDefaultBaudRate);
+  gPciUartDevicePath0.Uart.DataBits = PcdGet8 (PcdUartDefaultDataBits);
+  gPciUartDevicePath0.Uart.Parity   = PcdGet8 (PcdUartDefaultParity);
+  gPciUartDevicePath0.Uart.StopBits = PcdGet8 (PcdUartDefaultStopBits);
+  gPciUartDevicePath1.Uart.BaudRate = PcdGet64 (PcdUartDefaultBaudRate);
+  gPciUartDevicePath1.Uart.DataBits = PcdGet8 (PcdUartDefaultDataBits);
+  gPciUartDevicePath1.Uart.Parity   = PcdGet8 (PcdUartDefaultParity);
+  gPciUartDevicePath1.Uart.StopBits = PcdGet8 (PcdUartDefaultStopBits);
+
+  //
+  // Update Vendor device path nodes based on terminal type PCD settings
+  //
+  switch (PcdGet8 (PcdDefaultTerminalType)) {
+  case PCANSITYPE:
+    TerminalTypeGuid = &gEfiPcAnsiGuid;
+    break;
+  case VT100TYPE:
+    TerminalTypeGuid = &gEfiVT100Guid;
+    break;
+  case VT100PLUSTYPE:
+    TerminalTypeGuid = &gEfiVT100PlusGuid;
+    break;
+  case VTUTF8TYPE:
+    TerminalTypeGuid = &gEfiVTUTF8Guid;
+    break;
+  case TTYTERMTYPE:
+    TerminalTypeGuid = &gEfiTtyTermGuid;
+    break;
+  default:
+    TerminalTypeGuid = &gEfiPcAnsiGuid;
+    break;
+  }
+  CopyGuid (&gPciUartDevicePath0.TerminalType.Guid, TerminalTypeGuid);
+  CopyGuid (&gPciUartDevicePath1.TerminalType.Guid, TerminalTypeGuid);
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/CommonHeader.h b/Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/CommonHeader.h
new file mode 100644
index 0000000000..8016309f57
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/CommonHeader.h
@@ -0,0 +1,51 @@
+/** @file
+Common header file shared by all source files in this component.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/CapsuleLib.h>
+#include <Library/IntelQNCLib.h>
+#include <Platform.h>
+#include <PlatformBoards.h>
+#include <Pcal9555.h>
+#include <QNCAccess.h>
+#include <Library/QNCAccessLib.h>
+#include <IohAccess.h>
+
+#include <Library/PlatformHelperLib.h>
+
+//
+// Routines shared between souce modules in this component.
+//
+
+EFI_STATUS
+WriteFirstFreeSpiProtect (
+  IN CONST UINT32                         PchRootComplexBar,
+  IN CONST UINT32                         DirectValue,
+  IN CONST UINT32                         BaseAddress,
+  IN CONST UINT32                         Length,
+  OUT UINT32                              *OffsetPtr
+  );
+
+VOID
+Pcal9555SetPortRegBit (
+  IN CONST UINT32                         Pcal9555SlaveAddr,
+  IN CONST UINT32                         GpioNum,
+  IN CONST UINT8                          RegBase,
+  IN CONST BOOLEAN                        LogicOne
+  );
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/DxePlatformHelperLib.inf b/Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/DxePlatformHelperLib.inf
new file mode 100644
index 0000000000..6272b33cfd
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/DxePlatformHelperLib.inf
@@ -0,0 +1,70 @@
+## @file
+# Library producing helper routines for this platform.
+#
+# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = DxePlatformHelperLib
+  FILE_GUID                      = 02805010-2591-4ed3-827B-A218F34AE0D7
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformHelperLib|DXE_DRIVER DXE_RUNTIME_DRIVER SMM_CORE DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32
+#
+
+[Sources]
+  PlatformHelperLib.c
+  PlatformHelperDxe.c
+  PlatformLeds.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  PcdLib
+  BaseMemoryLib
+  SerialPortLib
+  S3BootScriptLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  DxeServicesLib
+  HobLib
+  IntelQNCLib
+  I2cLib
+
+[Protocols]
+  gEfiSpiProtocolGuid
+  gEfiSmmSpiProtocolGuid
+  gEfiSmmBase2ProtocolGuid
+  gEdkiiVariableLockProtocolGuid                ## CONSUMES
+
+[Guids]
+  gEfiGlobalVariableGuid
+  gEfiImageSecurityDatabaseGuid
+  gEfiQuarkCapsuleGuid
+  gQuarkVariableLockGuid                        ## CONSUMES
+  gEfiMemoryConfigDataGuid                      ## CONSUMES
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+  gQuarkPlatformTokenSpaceGuid.PcdFlashAreaBaseAddress
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoveryBase
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoverySize
+  gQuarkPlatformTokenSpaceGuid.PcdPkX509File
+  gQuarkPlatformTokenSpaceGuid.PcdKekX509File
+  gQuarkPlatformTokenSpaceGuid.PcdKekRsa2048File
+  gQuarkPlatformTokenSpaceGuid.PcdSpiFlashDeviceSize
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PeiPlatformHelperLib.inf b/Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PeiPlatformHelperLib.inf
new file mode 100644
index 0000000000..0c78f9b3d2
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PeiPlatformHelperLib.inf
@@ -0,0 +1,45 @@
+## @file
+# Library producing helper routines for this platform.
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiPlatformHelperLib
+  FILE_GUID                      = 024D3127-7B60-48f4-A6FE-726E19CD4CEB
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformHelperLib|PEIM PEI_CORE SEC
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32
+#
+
+[Sources]
+  PlatformHelperLib.c
+  PlatformHelperPei.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  PcdLib
+  BaseMemoryLib
+  PeiServicesTablePointerLib
+  PeiServicesLib
+  SerialPortLib
+  QNCAccessLib
+  I2cLib
+
+[Pcd]
+  gQuarkPlatformTokenSpaceGuid.PcdEsramStage1Base
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperDxe.c b/Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperDxe.c
new file mode 100644
index 0000000000..a0acf88c2b
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperDxe.c
@@ -0,0 +1,337 @@
+/** @file
+Implementation of helper routines for DXE environment.
+
+Copyright (c) 2013 - 2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/DxeServicesLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Protocol/SmmBase2.h>
+#include <Protocol/Spi.h>
+#include <Protocol/VariableLock.h>
+
+#include <Guid/MemoryConfigData.h>
+#include <Guid/QuarkVariableLock.h>
+
+#include "CommonHeader.h"
+
+#define FLASH_BLOCK_SIZE            SIZE_4KB
+
+//
+// Global variables.
+//
+EFI_SPI_PROTOCOL                    *mPlatHelpSpiProtocolRef = NULL;
+
+//
+// Routines defined in other source modules of this component.
+//
+
+//
+// Routines local to this component.
+//
+
+//
+// Routines shared with other souce modules in this component.
+//
+
+EFI_SPI_PROTOCOL *
+LocateSpiProtocol (
+  IN  EFI_SMM_SYSTEM_TABLE2             *Smst
+  )
+{
+  if (mPlatHelpSpiProtocolRef == NULL) {
+    if (Smst != NULL) {
+      Smst->SmmLocateProtocol (
+              &gEfiSmmSpiProtocolGuid,
+              NULL,
+              (VOID **) &mPlatHelpSpiProtocolRef
+              );
+    } else {
+      gBS->LocateProtocol (
+             &gEfiSpiProtocolGuid,
+             NULL,
+             (VOID **) &mPlatHelpSpiProtocolRef
+             );
+    }
+    ASSERT (mPlatHelpSpiProtocolRef != NULL);
+  }
+  return mPlatHelpSpiProtocolRef;
+}
+
+//
+// Routines exported by this source module.
+//
+
+/**
+  Find pointer to RAW data in Firmware volume file.
+
+  @param   FvNameGuid       Firmware volume to search. If == NULL search all.
+  @param   FileNameGuid     Firmware volume file to search for.
+  @param   SectionData      Pointer to RAW data section of found file.
+  @param   SectionDataSize  Pointer to UNITN to get size of RAW data.
+
+  @retval  EFI_SUCCESS            Raw Data found.
+  @retval  EFI_INVALID_PARAMETER  FileNameGuid == NULL.
+  @retval  EFI_NOT_FOUND          Firmware volume file not found.
+  @retval  EFI_UNSUPPORTED        Unsupported in current enviroment (PEI or DXE).
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformFindFvFileRawDataSection (
+  IN CONST EFI_GUID                 *FvNameGuid OPTIONAL,
+  IN CONST EFI_GUID                 *FileNameGuid,
+  OUT VOID                          **SectionData,
+  OUT UINTN                         *SectionDataSize
+  )
+{
+  if (FileNameGuid == NULL || SectionData == NULL || SectionDataSize == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  if (FvNameGuid != NULL) {
+    return EFI_UNSUPPORTED;  // Searching in specific FV unsupported in DXE.
+  }
+
+  return GetSectionFromAnyFv (FileNameGuid, EFI_SECTION_RAW, 0, SectionData, SectionDataSize);
+}
+
+/**
+  Find free spi protect register and write to it to protect a flash region.
+
+  @param   DirectValue      Value to directly write to register.
+                            if DirectValue == 0 the use Base & Length below.
+  @param   BaseAddress      Base address of region in Flash Memory Map.
+  @param   Length           Length of region to protect.
+
+  @retval  EFI_SUCCESS      Free spi protect register found & written.
+  @retval  EFI_NOT_FOUND    Free Spi protect register not found.
+  @retval  EFI_DEVICE_ERROR Unable to write to spi protect register.
+**/
+EFI_STATUS
+EFIAPI
+PlatformWriteFirstFreeSpiProtect (
+  IN CONST UINT32                         DirectValue,
+  IN CONST UINT32                         BaseAddress,
+  IN CONST UINT32                         Length
+  )
+{
+  UINT32                            FreeOffset;
+  UINT32                            PchRootComplexBar;
+  EFI_STATUS                        Status;
+
+  PchRootComplexBar = QNC_RCRB_BASE;
+
+  Status = WriteFirstFreeSpiProtect (
+             PchRootComplexBar,
+             DirectValue,
+             BaseAddress,
+             Length,
+             &FreeOffset
+             );
+
+  if (!EFI_ERROR (Status)) {
+    S3BootScriptSaveMemWrite (
+      S3BootScriptWidthUint32,
+        (UINTN) (PchRootComplexBar + FreeOffset),
+        1,
+        (VOID *) (UINTN) (PchRootComplexBar + FreeOffset)
+        );
+  }
+
+  return Status;
+}
+
+/**
+  Lock legacy SPI static configuration information.
+
+  Function will assert if unable to lock config.
+
+**/
+VOID
+EFIAPI
+PlatformFlashLockConfig (
+  VOID
+  )
+{
+  EFI_STATUS        Status;
+  EFI_SPI_PROTOCOL  *SpiProtocol;
+
+  //
+  // Enable lock of legacy SPI static configuration information.
+  //
+
+  SpiProtocol = LocateSpiProtocol (NULL);  // This routine will not be called in SMM.
+  ASSERT (SpiProtocol != NULL);
+  if (SpiProtocol != NULL) {
+    Status = SpiProtocol->Lock (SpiProtocol);
+
+    if (!EFI_ERROR (Status)) {
+      DEBUG ((EFI_D_INFO, "Platform: Spi Config Locked Down\n"));
+    } else if (Status == EFI_ACCESS_DENIED) {
+      DEBUG ((EFI_D_INFO, "Platform: Spi Config already locked down\n"));
+    } else {
+      ASSERT_EFI_ERROR (Status);
+    }
+  }
+}
+
+/**
+  Platform Variable Lock.
+
+  @retval EFI_SUCCESS           Platform Variable Lock successful.
+  @retval EFI_NOT_FOUND         No protocol instances were found that match Protocol and
+                                Registration.
+
+**/
+VOID
+EFIAPI
+PlatformVariableLock (
+  )
+{
+  EFI_STATUS                        Status;
+  EDKII_VARIABLE_LOCK_PROTOCOL      *VariableLockProtocol;
+
+  Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = VariableLockProtocol->RequestToLock (
+                                   VariableLockProtocol,
+                                   QUARK_VARIABLE_LOCK_NAME,
+                                   &gQuarkVariableLockGuid
+                                   );
+  ASSERT_EFI_ERROR (Status);
+
+  // Memory Config Data shouldn't be writable when Quark Variable Lock is enabled.
+  Status = VariableLockProtocol->RequestToLock (
+                                   VariableLockProtocol,
+                                   EFI_MEMORY_CONFIG_DATA_NAME,
+                                   &gEfiMemoryConfigDataGuid
+                                   );
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+  Lock regions and config of SPI flash given the policy for this platform.
+
+  Function will assert if unable to lock regions or config.
+
+  @param   PreBootPolicy    If TRUE do Pre Boot Flash Lock Policy.
+
+**/
+VOID
+EFIAPI
+PlatformFlashLockPolicy (
+  IN CONST BOOLEAN                        PreBootPolicy
+  )
+{
+  EFI_STATUS                        Status;
+  UINT64                            CpuAddressNvStorage;
+  UINT64                            CpuAddressFlashDevice;
+  UINT64                            SpiAddress;
+  EFI_BOOT_MODE                     BootMode;
+  UINTN                             SpiFlashDeviceSize;
+
+  BootMode = GetBootModeHob ();
+
+  SpiFlashDeviceSize = (UINTN) PcdGet32 (PcdSpiFlashDeviceSize);
+  CpuAddressFlashDevice = SIZE_4GB - SpiFlashDeviceSize;
+  DEBUG (
+      (EFI_D_INFO,
+      "Platform:FlashDeviceSize = 0x%08x Bytes\n",
+      SpiFlashDeviceSize)
+      );
+
+  //
+  // If not in update or recovery mode, lock stuff down
+  //
+  if ((BootMode != BOOT_IN_RECOVERY_MODE) && (BootMode != BOOT_ON_FLASH_UPDATE)) {
+
+    //
+    // Lock regions
+    //
+    CpuAddressNvStorage = (UINT64) PcdGet32 (PcdFlashNvStorageVariableBase);
+
+    //
+    // Lock from start of flash device up to Smi writable flash storage areas.
+    //
+    SpiAddress = 0;
+    if (!PlatformIsSpiRangeProtected ((UINT32) SpiAddress, (UINT32) (CpuAddressNvStorage - CpuAddressFlashDevice))) {
+      DEBUG (
+        (EFI_D_INFO,
+        "Platform: Protect Region Base:Len 0x%08x:0x%08x\n",
+        (UINTN) SpiAddress, (UINTN)(CpuAddressNvStorage - CpuAddressFlashDevice))
+        );
+      Status = PlatformWriteFirstFreeSpiProtect (
+                  0,
+                  (UINT32) SpiAddress,
+                  (UINT32) (CpuAddressNvStorage - CpuAddressFlashDevice)
+                  );
+
+      ASSERT_EFI_ERROR (Status);
+    }
+    //
+    // Move Spi Address to after Smi writable flash storage areas.
+    //
+    SpiAddress = CpuAddressNvStorage - CpuAddressFlashDevice;
+    SpiAddress += ((UINT64) PcdGet32 (PcdFlashNvStorageVariableSize));
+
+    //
+    // Lock from end of OEM area to end of flash part.
+    //
+    if (!PlatformIsSpiRangeProtected ((UINT32) SpiAddress, SpiFlashDeviceSize - ((UINT32) SpiAddress))) {
+      DEBUG (
+        (EFI_D_INFO,
+        "Platform: Protect Region Base:Len 0x%08x:0x%08x\n",
+        (UINTN) SpiAddress,
+        (UINTN) (SpiFlashDeviceSize - ((UINT32) SpiAddress)))
+        );
+      ASSERT (SpiAddress < ((UINT64) SpiFlashDeviceSize));
+      Status = PlatformWriteFirstFreeSpiProtect (
+                  0,
+                  (UINT32) SpiAddress,
+                  SpiFlashDeviceSize - ((UINT32) SpiAddress)
+                  );
+
+      ASSERT_EFI_ERROR (Status);
+    }
+  }
+
+  //
+  // Always Lock flash config registers if about to boot a boot option
+  // else lock depending on boot mode.
+  //
+  if (PreBootPolicy || (BootMode != BOOT_ON_FLASH_UPDATE)) {
+    PlatformFlashLockConfig ();
+  }
+
+  //
+  // Enable Quark Variable lock if PreBootPolicy.
+  //
+  if (PreBootPolicy) {
+    PlatformVariableLock ();
+  }
+}
+
+/** Check if System booted with recovery Boot Stage1 image.
+
+  @retval  TRUE    If system booted with recovery Boot Stage1 image.
+  @retval  FALSE   If system booted with normal stage1 image.
+
+**/
+BOOLEAN
+EFIAPI
+PlatformIsBootWithRecoveryStage1 (
+  VOID
+  )
+{
+  ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
+  return FALSE;
+}
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperLib.c b/Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperLib.c
new file mode 100644
index 0000000000..c7f707c8df
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperLib.c
@@ -0,0 +1,481 @@
+/** @file
+Helper routines with common PEI / DXE implementation.
+
+Copyright (c) 2013-2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CommonHeader.h"
+#include <Library/I2cLib.h>
+
+CHAR16 *mPlatTypeNameTable[]  = { EFI_PLATFORM_TYPE_NAME_TABLE_DEFINITION };
+UINTN mPlatTypeNameTableLen  = ((sizeof(mPlatTypeNameTable)) / sizeof (CHAR16 *));
+
+//
+// Routines defined in other source modules of this component.
+//
+
+//
+// Routines local to this source module.
+//
+
+//
+// Routines shared with other souce modules in this component.
+//
+
+EFI_STATUS
+WriteFirstFreeSpiProtect (
+  IN CONST UINT32                         PchRootComplexBar,
+  IN CONST UINT32                         DirectValue,
+  IN CONST UINT32                         BaseAddress,
+  IN CONST UINT32                         Length,
+  OUT UINT32                              *OffsetPtr
+  )
+{
+  UINT32                            RegVal;
+  UINT32                            Offset;
+  UINT32                            StepLen;
+
+  ASSERT (PchRootComplexBar > 0);
+
+  Offset = 0;
+  if (OffsetPtr != NULL) {
+    *OffsetPtr = Offset;
+  }
+  if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0) == 0) {
+    Offset = R_QNC_RCRB_SPIPBR0;
+  } else {
+    if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR1) == 0) {
+      Offset = R_QNC_RCRB_SPIPBR1;
+    } else {
+      if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR2) == 0) {
+        Offset = R_QNC_RCRB_SPIPBR2;
+      }
+    }
+  }
+  if (Offset != 0) {
+    if (DirectValue == 0) {
+      StepLen = ALIGN_VALUE (Length,SIZE_4KB);   // Bring up to 4K boundary.
+      RegVal = BaseAddress + StepLen - 1;
+      RegVal &= 0x00FFF000;                     // Set EDS Protected Range Limit (PRL).
+      RegVal |= ((BaseAddress >> 12) & 0xfff);  // or in EDS Protected Range Base (PRB).
+    } else {
+      RegVal = DirectValue;
+    }
+    //
+    // Enable protection.
+    //
+    RegVal |= B_QNC_RCRB_SPIPBRn_WPE;
+    MmioWrite32 (PchRootComplexBar + Offset, RegVal);
+    if (RegVal == MmioRead32 (PchRootComplexBar + Offset)) {
+      if (OffsetPtr != NULL) {
+        *OffsetPtr = Offset;
+      }
+      return EFI_SUCCESS;
+    }
+    return EFI_DEVICE_ERROR;
+  }
+  return EFI_NOT_FOUND;
+}
+
+//
+// Routines exported by this component.
+//
+
+/**
+  Clear SPI Protect registers.
+
+  @retval EFI_SUCCESS        SPI protect registers cleared.
+  @retval EFI_ACCESS_DENIED  Unable to clear SPI protect registers.
+**/
+
+EFI_STATUS
+EFIAPI
+PlatformClearSpiProtect (
+  VOID
+  )
+{
+  UINT32                            PchRootComplexBar;
+
+  PchRootComplexBar = QNC_RCRB_BASE;
+  //
+  // Check if the SPI interface has been locked-down.
+  //
+  if ((MmioRead16 (PchRootComplexBar + R_QNC_RCRB_SPIS) & B_QNC_RCRB_SPIS_SCL) != 0) {
+    return EFI_ACCESS_DENIED;
+  }
+  MmioWrite32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0, 0);
+  if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0) != 0) {
+    return EFI_ACCESS_DENIED;
+  }
+  MmioWrite32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR1, 0);
+  if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0) != 0) {
+    return EFI_ACCESS_DENIED;
+  }
+  MmioWrite32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR2, 0);
+  if (MmioRead32 (PchRootComplexBar + R_QNC_RCRB_SPIPBR0) != 0) {
+    return EFI_ACCESS_DENIED;
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  Determine if an SPI address range is protected.
+
+  @param  SpiBaseAddress  Base of SPI range.
+  @param  Length          Length of SPI range.
+
+  @retval TRUE       Range is protected.
+  @retval FALSE      Range is not protected.
+**/
+BOOLEAN
+EFIAPI
+PlatformIsSpiRangeProtected (
+  IN CONST UINT32                         SpiBaseAddress,
+  IN CONST UINT32                         Length
+  )
+{
+  UINT32                            RegVal;
+  UINT32                            Offset;
+  UINT32                            Limit;
+  UINT32                            ProtectedBase;
+  UINT32                            ProtectedLimit;
+  UINT32                            PchRootComplexBar;
+
+  PchRootComplexBar = QNC_RCRB_BASE;
+
+  if (Length > 0) {
+    Offset = R_QNC_RCRB_SPIPBR0;
+    Limit = SpiBaseAddress + (Length - 1);
+    do {
+      RegVal = MmioRead32 (PchRootComplexBar + Offset);
+      if ((RegVal & B_QNC_RCRB_SPIPBRn_WPE) != 0) {
+        ProtectedBase = (RegVal & 0xfff) << 12;
+        ProtectedLimit = (RegVal & 0x00fff000) + 0xfff;
+        if (SpiBaseAddress >= ProtectedBase && Limit <= ProtectedLimit) {
+          return TRUE;
+        }
+      }
+      if (Offset == R_QNC_RCRB_SPIPBR0) {
+        Offset = R_QNC_RCRB_SPIPBR1;
+      } else if (Offset == R_QNC_RCRB_SPIPBR1) {
+        Offset = R_QNC_RCRB_SPIPBR2;
+      } else {
+        break;
+      }
+    } while (TRUE);
+  }
+  return FALSE;
+}
+
+/**
+  Set Legacy GPIO Level
+
+  @param  LevelRegOffset      GPIO level register Offset from GPIO Base Address.
+  @param  GpioNum             GPIO bit to change.
+  @param  HighLevel           If TRUE set GPIO High else Set GPIO low.
+
+**/
+VOID
+EFIAPI
+PlatformLegacyGpioSetLevel (
+  IN CONST UINT32       LevelRegOffset,
+  IN CONST UINT32       GpioNum,
+  IN CONST BOOLEAN      HighLevel
+  )
+{
+  UINT32  RegValue;
+  UINT32  GpioBaseAddress;
+  UINT32  GpioNumMask;
+
+  GpioBaseAddress =  LpcPciCfg32 (R_QNC_LPC_GBA_BASE) & B_QNC_LPC_GPA_BASE_MASK;
+  ASSERT (GpioBaseAddress > 0);
+
+  RegValue = IoRead32 (GpioBaseAddress + LevelRegOffset);
+  GpioNumMask = (1 << GpioNum);
+  if (HighLevel) {
+    RegValue |= (GpioNumMask);
+  } else {
+    RegValue &= ~(GpioNumMask);
+  }
+  IoWrite32 (GpioBaseAddress + LevelRegOffset, RegValue);
+}
+
+/**
+  Get Legacy GPIO Level
+
+  @param  LevelRegOffset      GPIO level register Offset from GPIO Base Address.
+  @param  GpioNum             GPIO bit to check.
+
+  @retval TRUE       If bit is SET.
+  @retval FALSE      If bit is CLEAR.
+
+**/
+BOOLEAN
+EFIAPI
+PlatformLegacyGpioGetLevel (
+  IN CONST UINT32       LevelRegOffset,
+  IN CONST UINT32       GpioNum
+  )
+{
+  UINT32  RegValue;
+  UINT32  GpioBaseAddress;
+  UINT32  GpioNumMask;
+
+  GpioBaseAddress =  LpcPciCfg32 (R_QNC_LPC_GBA_BASE) & B_QNC_LPC_GPA_BASE_MASK;
+  RegValue = IoRead32 (GpioBaseAddress + LevelRegOffset);
+  GpioNumMask = (1 << GpioNum);
+  return ((RegValue & GpioNumMask) != 0);
+}
+
+
+BOOLEAN
+Pcal9555GetPortRegBit (
+  IN CONST UINT32                         Pcal9555SlaveAddr,
+  IN CONST UINT32                         GpioNum,
+  IN CONST UINT8                          RegBase
+  )
+{
+  EFI_STATUS                        Status;
+  UINTN                             ReadLength;
+  UINTN                             WriteLength;
+  UINT8                             Data[2];
+  EFI_I2C_DEVICE_ADDRESS            I2cDeviceAddr;
+  EFI_I2C_ADDR_MODE                 I2cAddrMode;
+  UINT8                             *RegValuePtr;
+  UINT8                             GpioNumMask;
+  UINT8                             SubAddr;
+
+  I2cDeviceAddr.I2CDeviceAddress = (UINTN)Pcal9555SlaveAddr;
+  I2cAddrMode = EfiI2CSevenBitAddrMode;
+
+  if (GpioNum < 8) {
+    SubAddr = RegBase;
+    GpioNumMask = (UINT8)(1 << GpioNum);
+  } else {
+    SubAddr = RegBase + 1;
+    GpioNumMask = (UINT8)(1 << (GpioNum - 8));
+  }
+
+  //
+  // Output port value always at 2nd byte in Data variable.
+  //
+  RegValuePtr = &Data[1];
+
+  //
+  // On read entry sub address at 2nd byte, on read exit output
+  // port value in 2nd byte.
+  //
+  Data[1] = SubAddr;
+  WriteLength = 1;
+  ReadLength = 1;
+  Status = I2cReadMultipleByte (
+    I2cDeviceAddr,
+    I2cAddrMode,
+    &WriteLength,
+    &ReadLength,
+    &Data[1]
+    );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Adjust output port bit given callers request.
+  //
+  return ((*RegValuePtr & GpioNumMask) != 0);
+}
+
+VOID
+Pcal9555SetPortRegBit (
+  IN CONST UINT32                         Pcal9555SlaveAddr,
+  IN CONST UINT32                         GpioNum,
+  IN CONST UINT8                          RegBase,
+  IN CONST BOOLEAN                        LogicOne
+  )
+{
+  EFI_STATUS                        Status;
+  UINTN                             ReadLength;
+  UINTN                             WriteLength;
+  UINT8                             Data[2];
+  EFI_I2C_DEVICE_ADDRESS            I2cDeviceAddr;
+  EFI_I2C_ADDR_MODE                 I2cAddrMode;
+  UINT8                             *RegValuePtr;
+  UINT8                             GpioNumMask;
+  UINT8                             SubAddr;
+
+  I2cDeviceAddr.I2CDeviceAddress = (UINTN)Pcal9555SlaveAddr;
+  I2cAddrMode = EfiI2CSevenBitAddrMode;
+
+  if (GpioNum < 8) {
+    SubAddr = RegBase;
+    GpioNumMask = (UINT8)(1 << GpioNum);
+  } else {
+    SubAddr = RegBase + 1;
+    GpioNumMask = (UINT8)(1 << (GpioNum - 8));
+  }
+
+  //
+  // Output port value always at 2nd byte in Data variable.
+  //
+  RegValuePtr = &Data[1];
+
+  //
+  // On read entry sub address at 2nd byte, on read exit output
+  // port value in 2nd byte.
+  //
+  Data[1] = SubAddr;
+  WriteLength = 1;
+  ReadLength = 1;
+  Status = I2cReadMultipleByte (
+    I2cDeviceAddr,
+    I2cAddrMode,
+    &WriteLength,
+    &ReadLength,
+    &Data[1]
+    );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Adjust output port bit given callers request.
+  //
+  if (LogicOne) {
+    *RegValuePtr = *RegValuePtr | GpioNumMask;
+  } else {
+    *RegValuePtr = *RegValuePtr & ~(GpioNumMask);
+  }
+
+  //
+  // Update register. Sub address at 1st byte, value at 2nd byte.
+  //
+  WriteLength = 2;
+  Data[0] = SubAddr;
+  Status = I2cWriteMultipleByte (
+    I2cDeviceAddr,
+    I2cAddrMode,
+    &WriteLength,
+    Data
+    );
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+Set the direction of Pcal9555 IO Expander GPIO pin.
+
+@param  Pcal9555SlaveAddr  I2c Slave address of Pcal9555 Io Expander.
+@param  GpioNum            Gpio direction to configure - values 0-7 for Port0
+and 8-15 for Port1.
+@param  CfgAsInput         If TRUE set pin direction as input else set as output.
+
+**/
+VOID
+EFIAPI
+PlatformPcal9555GpioSetDir (
+  IN CONST UINT32                         Pcal9555SlaveAddr,
+  IN CONST UINT32                         GpioNum,
+  IN CONST BOOLEAN                        CfgAsInput
+  )
+{
+  Pcal9555SetPortRegBit (
+    Pcal9555SlaveAddr,
+    GpioNum,
+    PCAL9555_REG_CFG_PORT0,
+    CfgAsInput
+    );
+}
+
+/**
+Set the level of Pcal9555 IO Expander GPIO high or low.
+
+@param  Pcal9555SlaveAddr  I2c Slave address of Pcal9555 Io Expander.
+@param  GpioNum            Gpio to change values 0-7 for Port0 and 8-15
+for Port1.
+@param  HighLevel          If TRUE set pin high else set pin low.
+
+**/
+VOID
+EFIAPI
+PlatformPcal9555GpioSetLevel (
+  IN CONST UINT32                         Pcal9555SlaveAddr,
+  IN CONST UINT32                         GpioNum,
+  IN CONST BOOLEAN                        HighLevel
+  )
+{
+  Pcal9555SetPortRegBit (
+    Pcal9555SlaveAddr,
+    GpioNum,
+    PCAL9555_REG_OUT_PORT0,
+    HighLevel
+    );
+}
+
+/**
+
+Enable pull-up/pull-down resistors of Pcal9555 GPIOs.
+
+@param  Pcal9555SlaveAddr  I2c Slave address of Pcal9555 Io Expander.
+@param  GpioNum            Gpio to change values 0-7 for Port0 and 8-15
+for Port1.
+
+**/
+VOID
+EFIAPI
+PlatformPcal9555GpioEnablePull (
+  IN CONST UINT32                         Pcal9555SlaveAddr,
+  IN CONST UINT32                         GpioNum
+  )
+{
+  Pcal9555SetPortRegBit (
+    Pcal9555SlaveAddr,
+    GpioNum,
+    PCAL9555_REG_PULL_EN_PORT0,
+    TRUE
+    );
+}
+
+/**
+
+Disable pull-up/pull-down resistors of Pcal9555 GPIOs.
+
+@param  Pcal9555SlaveAddr  I2c Slave address of Pcal9555 Io Expander.
+@param  GpioNum            Gpio to change values 0-7 for Port0 and 8-15
+for Port1.
+
+**/
+VOID
+EFIAPI
+PlatformPcal9555GpioDisablePull (
+  IN CONST UINT32                         Pcal9555SlaveAddr,
+  IN CONST UINT32                         GpioNum
+  )
+{
+  Pcal9555SetPortRegBit (
+    Pcal9555SlaveAddr,
+    GpioNum,
+    PCAL9555_REG_PULL_EN_PORT0,
+    FALSE
+    );
+}
+
+/**
+
+Get state of Pcal9555 GPIOs.
+
+@param  Pcal9555SlaveAddr  I2c Slave address of Pcal9555 Io Expander.
+@param  GpioNum            Gpio to change values 0-7 for Port0 and 8-15
+for Port1.
+
+@retval TRUE               GPIO pin is high
+@retval FALSE              GPIO pin is low
+**/
+BOOLEAN
+EFIAPI
+PlatformPcal9555GpioGetState (
+  IN CONST UINT32                         Pcal9555SlaveAddr,
+  IN CONST UINT32                         GpioNum
+  )
+{
+  return Pcal9555GetPortRegBit (Pcal9555SlaveAddr, GpioNum, PCAL9555_REG_IN_PORT0);
+}
+
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperPei.c b/Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperPei.c
new file mode 100644
index 0000000000..9de3f613e0
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperPei.c
@@ -0,0 +1,159 @@
+/** @file
+Implementation of Helper routines for PEI enviroment.
+
+Copyright (c) 2013-2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/I2cLib.h>
+
+#include "CommonHeader.h"
+
+//
+// Routines defined in other source modules of this component.
+//
+
+//
+// Routines local to this source module.
+//
+
+//
+// Routines exported by this source module.
+//
+
+/**
+  Find pointer to RAW data in Firmware volume file.
+
+  @param   FvNameGuid       Firmware volume to search. If == NULL search all.
+  @param   FileNameGuid     Firmware volume file to search for.
+  @param   SectionData      Pointer to RAW data section of found file.
+  @param   SectionDataSize  Pointer to UNITN to get size of RAW data.
+
+  @retval  EFI_SUCCESS            Raw Data found.
+  @retval  EFI_INVALID_PARAMETER  FileNameGuid == NULL.
+  @retval  EFI_NOT_FOUND          Firmware volume file not found.
+  @retval  EFI_UNSUPPORTED        Unsupported in current enviroment (PEI or DXE).
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformFindFvFileRawDataSection (
+  IN CONST EFI_GUID                 *FvNameGuid OPTIONAL,
+  IN CONST EFI_GUID                 *FileNameGuid,
+  OUT VOID                          **SectionData,
+  OUT UINTN                         *SectionDataSize
+  )
+{
+  EFI_STATUS                        Status;
+  UINTN                             Instance;
+  EFI_PEI_FV_HANDLE                 VolumeHandle;
+  EFI_PEI_FILE_HANDLE               FileHandle;
+  EFI_SECTION_TYPE                  SearchType;
+  EFI_FV_INFO                       VolumeInfo;
+  EFI_FV_FILE_INFO                  FileInfo;
+
+  if (FileNameGuid == NULL || SectionData == NULL || SectionDataSize == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  *SectionData = NULL;
+  *SectionDataSize = 0;
+
+  SearchType = EFI_SECTION_RAW;
+  for (Instance = 0; !EFI_ERROR((PeiServicesFfsFindNextVolume (Instance, &VolumeHandle))); Instance++) {
+    if (FvNameGuid != NULL) {
+      Status = PeiServicesFfsGetVolumeInfo (VolumeHandle, &VolumeInfo);
+      if (EFI_ERROR (Status)) {
+        continue;
+      }
+      if (!CompareGuid (FvNameGuid, &VolumeInfo.FvName)) {
+        continue;
+      }
+    }
+    Status = PeiServicesFfsFindFileByName (FileNameGuid, VolumeHandle, &FileHandle);
+    if (!EFI_ERROR (Status)) {
+      Status = PeiServicesFfsGetFileInfo (FileHandle, &FileInfo);
+      if (EFI_ERROR (Status)) {
+        continue;
+      }
+      if (IS_SECTION2(FileInfo.Buffer)) {
+        *SectionDataSize = SECTION2_SIZE(FileInfo.Buffer) - sizeof(EFI_COMMON_SECTION_HEADER2);
+      } else {
+        *SectionDataSize = SECTION_SIZE(FileInfo.Buffer) - sizeof(EFI_COMMON_SECTION_HEADER);
+      }
+      Status = PeiServicesFfsFindSectionData (SearchType, FileHandle, SectionData);
+      if (!EFI_ERROR (Status)) {
+        return Status;
+      }
+    }
+  }
+  return EFI_NOT_FOUND;
+}
+
+/**
+  Find free spi protect register and write to it to protect a flash region.
+
+  @param   DirectValue      Value to directly write to register.
+                            if DirectValue == 0 the use Base & Length below.
+  @param   BaseAddress      Base address of region in Flash Memory Map.
+  @param   Length           Length of region to protect.
+
+  @retval  EFI_SUCCESS      Free spi protect register found & written.
+  @retval  EFI_NOT_FOUND    Free Spi protect register not found.
+  @retval  EFI_DEVICE_ERROR Unable to write to spi protect register.
+**/
+EFI_STATUS
+EFIAPI
+PlatformWriteFirstFreeSpiProtect (
+  IN CONST UINT32                         DirectValue,
+  IN CONST UINT32                         BaseAddress,
+  IN CONST UINT32                         Length
+  )
+{
+  return WriteFirstFreeSpiProtect (
+           QNC_RCRB_BASE,
+           DirectValue,
+           BaseAddress,
+           Length,
+           NULL
+           );
+}
+
+/** Check if System booted with recovery Boot Stage1 image.
+
+  @retval  TRUE    If system booted with recovery Boot Stage1 image.
+  @retval  FALSE   If system booted with normal stage1 image.
+
+**/
+BOOLEAN
+EFIAPI
+PlatformIsBootWithRecoveryStage1 (
+  VOID
+  )
+{
+  BOOLEAN                           IsRecoveryBoot;
+  QUARK_EDKII_STAGE1_HEADER         *Edk2ImageHeader;
+
+  Edk2ImageHeader = (QUARK_EDKII_STAGE1_HEADER *) PcdGet32 (PcdEsramStage1Base);
+  switch ((UINT8)Edk2ImageHeader->ImageIndex & QUARK_STAGE1_IMAGE_TYPE_MASK) {
+  case QUARK_STAGE1_RECOVERY_IMAGE_TYPE:
+    //
+    // Recovery Boot
+    //
+    IsRecoveryBoot = TRUE;
+    break;
+  default:
+    //
+    // Normal Boot
+    //
+    IsRecoveryBoot = FALSE;
+    break;
+  }
+
+  return IsRecoveryBoot;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformLeds.c b/Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformLeds.c
new file mode 100644
index 0000000000..8846f3cd02
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformLeds.c
@@ -0,0 +1,146 @@
+/** @file
+Platform helper LED routines.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+
+#include "CommonHeader.h"
+
+//
+// Routines defined in other source modules of this component.
+//
+
+//
+// Routines local to this source module.
+//
+
+VOID
+GalileoGen2RouteOutFlashUpdateLed (
+  VOID
+  )
+{
+  //
+  // For GpioNums below values 0 to 7 are for Port0 ie P0-0 - P0-7 and
+  // values 8 to 15 are for Port1 ie P1-0 - P1-7.
+  //
+
+  //
+  // Disable Pull-ups / pull downs on EXP0 pin for LVL_B_PU7 signal.
+  //
+  PlatformPcal9555GpioDisablePull (
+    GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR,  // IO Expander 0.
+    15                                   // P1-7.
+    );
+
+  //
+  // Make LVL_B_OE7_N an output pin.
+  //
+  PlatformPcal9555GpioSetDir (
+    GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR,  // IO Expander 0.
+    14,                                   // P1-6.
+    FALSE
+    );
+
+  //
+  // Set level of LVL_B_OE7_N to low.
+  //
+  PlatformPcal9555GpioSetLevel (
+    GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR,
+    14,
+    FALSE
+    );
+
+  //
+  // Make MUX8_SEL an output pin.
+  //
+  PlatformPcal9555GpioSetDir (
+    GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR,  // IO Expander 1.
+    14,                                   // P1-6.
+    FALSE
+    );
+
+  //
+  // Set level of MUX8_SEL to low to route GPIO_SUS<5> to LED.
+  //
+  PlatformPcal9555GpioSetLevel (
+    GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR,  // IO Expander 1.
+    14,                                   // P1-6.
+    FALSE
+    );
+}
+
+//
+// Routines exported by this source module.
+//
+
+/**
+  Init platform LEDs into known state.
+
+  @param   PlatformType     Executing platform type.
+  @param   I2cBus           Pointer to I2c Host controller protocol.
+
+  @retval  EFI_SUCCESS      Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformLedInit (
+  IN CONST EFI_PLATFORM_TYPE              Type
+  )
+{
+  EFI_BOOT_MODE             BootMode;
+
+  BootMode = GetBootModeHob ();
+
+  //
+  // Init Flash update / recovery LED in OFF state.
+  //
+  if (BootMode == BOOT_ON_FLASH_UPDATE || BootMode == BOOT_IN_RECOVERY_MODE) {
+    if (Type == GalileoGen2) {
+      PlatformLegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_GEN2_FLASH_UPDATE_LED_RESUMEWELL_GPIO, FALSE);
+      GalileoGen2RouteOutFlashUpdateLed ();
+    } else if (Type == Galileo) {
+      PlatformLegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_FLASH_UPDATE_LED_RESUMEWELL_GPIO, FALSE);
+    } else {
+      //
+      // These platforms have no flash update LED.
+      //
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Turn on or off platform flash update LED.
+
+  @param   PlatformType     Executing platform type.
+  @param   TurnOn           If TRUE turn on else turn off.
+
+  @retval  EFI_SUCCESS      Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformFlashUpdateLed (
+  IN CONST EFI_PLATFORM_TYPE              Type,
+  IN CONST BOOLEAN                        TurnOn
+  )
+{
+  if (Type == GalileoGen2) {
+    PlatformLegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_GEN2_FLASH_UPDATE_LED_RESUMEWELL_GPIO, TurnOn);
+  } else if (Type == Galileo) {
+    PlatformLegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_FLASH_UPDATE_LED_RESUMEWELL_GPIO, TurnOn);
+  } else {
+    //
+    // These platforms have no flash update LED.
+    //
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/CommonHeader.h b/Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/CommonHeader.h
new file mode 100644
index 0000000000..339baac186
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/CommonHeader.h
@@ -0,0 +1,55 @@
+/** @file
+Common header file shared by all source files in this component.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Library/QNCAccessLib.h>
+#include <Library/IntelQNCLib.h>
+#include <IntelQNCRegs.h>
+#include <IntelQNCConfig.h>
+#include <Pcal9555.h>
+#include <Platform.h>
+#include <PlatformBoards.h>
+
+#include <Library/PlatformPcieHelperLib.h>
+
+//
+// Routines shared between souce modules in this component.
+//
+
+VOID
+EFIAPI
+PlatformPcieErratas (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+SocUnitEarlyInitialisation (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+SocUnitReleasePcieControllerPreWaitPllLock (
+  IN CONST EFI_PLATFORM_TYPE              PlatformType
+  );
+
+EFI_STATUS
+EFIAPI
+SocUnitReleasePcieControllerPostPllLock (
+  IN CONST EFI_PLATFORM_TYPE              PlatformType
+  );
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPcieHelperLib.c b/Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPcieHelperLib.c
new file mode 100644
index 0000000000..8aaeb73342
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPcieHelperLib.c
@@ -0,0 +1,114 @@
+/** @file
+Platform Pcie Helper Lib.
+
+Copyright (c) 2013 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CommonHeader.h"
+
+//
+// Routines local to this source module.
+//
+VOID
+LegacyGpioSetLevel (
+  IN CONST UINT32                         LevelRegOffset,
+  IN CONST UINT32                         GpioNum,
+  IN CONST BOOLEAN                        HighLevel
+  )
+{
+  UINT32                            RegValue;
+  UINT32                            GpioBaseAddress;
+  UINT32                            GpioNumMask;
+
+  GpioBaseAddress =  LpcPciCfg32 (R_QNC_LPC_GBA_BASE) & B_QNC_LPC_GPA_BASE_MASK;
+  ASSERT (GpioBaseAddress > 0);
+
+  RegValue = IoRead32 (GpioBaseAddress + LevelRegOffset);
+  GpioNumMask = (1 << GpioNum);
+  if (HighLevel) {
+    RegValue |= (GpioNumMask);
+  } else {
+    RegValue &= ~(GpioNumMask);
+  }
+  IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGLVL_RESUME_WELL, RegValue);
+}
+
+//
+// Routines exported by this component.
+//
+
+/**
+  Platform assert PCI express PERST# signal.
+
+  @param   PlatformType     See EFI_PLATFORM_TYPE enum definitions.
+
+**/
+VOID
+EFIAPI
+PlatformPERSTAssert (
+  IN CONST EFI_PLATFORM_TYPE              PlatformType
+  )
+{
+  if (PlatformType == GalileoGen2) {
+    LegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_GEN2_PCIEXP_PERST_RESUMEWELL_GPIO, FALSE);
+  } else {
+    LegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, PCIEXP_PERST_RESUMEWELL_GPIO, FALSE);
+  }
+}
+
+/**
+  Platform de assert PCI express PERST# signal.
+
+  @param   PlatformType     See EFI_PLATFORM_TYPE enum definitions.
+
+**/
+VOID
+EFIAPI
+PlatformPERSTDeAssert (
+  IN CONST EFI_PLATFORM_TYPE              PlatformType
+  )
+{
+  if (PlatformType == GalileoGen2) {
+    LegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_GEN2_PCIEXP_PERST_RESUMEWELL_GPIO, TRUE);
+  } else {
+    LegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, PCIEXP_PERST_RESUMEWELL_GPIO, TRUE);
+  }
+}
+
+/** Early initialisation of the PCIe controller.
+
+  @param   PlatformType     See EFI_PLATFORM_TYPE enum definitions.
+
+  @retval   EFI_SUCCESS               Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformPciExpressEarlyInit (
+  IN CONST EFI_PLATFORM_TYPE              PlatformType
+  )
+{
+
+  //
+  // Release and wait for PCI controller to come out of reset.
+  //
+  SocUnitReleasePcieControllerPreWaitPllLock (PlatformType);
+  MicroSecondDelay (PCIEXP_DELAY_US_WAIT_PLL_LOCK);
+  SocUnitReleasePcieControllerPostPllLock (PlatformType);
+
+  //
+  // Early PCIe initialisation
+  //
+  SocUnitEarlyInitialisation ();
+
+  //
+  // Do North cluster early PCIe init.
+  //
+  PciExpressEarlyInit ();
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPcieHelperLib.inf b/Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPcieHelperLib.inf
new file mode 100644
index 0000000000..0fdaf22494
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPcieHelperLib.inf
@@ -0,0 +1,41 @@
+## @file
+# Library producing Pci Express Helper routines.
+#
+# Copyright (c) 2013 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformPcieHelperLib
+  FILE_GUID                      = C153F460-5D8A-4d44-83BB-A8AF5CEF132C
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformPcieHelperLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32
+#
+
+[Sources]
+  PlatformPcieHelperLib.c
+  SocUnit.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  PcdLib
+  IoLib
+  DebugLib
+  TimerLib
+  QNCAccessLib
+  IntelQNCLib
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/SocUnit.c b/Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/SocUnit.c
new file mode 100644
index 0000000000..8babbe869a
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/SocUnit.c
@@ -0,0 +1,125 @@
+/** @file
+System On Chip Unit (SOCUnit) routines.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CommonHeader.h"
+
+/** Early initialisation of the SOC Unit
+
+  @retval   EFI_SUCCESS               Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+SocUnitEarlyInitialisation (
+  VOID
+  )
+{
+  UINT32      NewValue;
+
+  //
+  // Set the mixer load resistance
+  //
+  NewValue = QNCPortIORead (QUARK_SC_PCIE_AFE_SB_PORT_ID, QUARK_PCIE_AFE_PCIE_RXPICTRL0_L0);
+  NewValue &= OCFGPIMIXLOAD_1_0_MASK;
+  QNCPortIOWrite (QUARK_SC_PCIE_AFE_SB_PORT_ID, QUARK_PCIE_AFE_PCIE_RXPICTRL0_L0, NewValue);
+
+  NewValue = QNCPortIORead (QUARK_SC_PCIE_AFE_SB_PORT_ID, QUARK_PCIE_AFE_PCIE_RXPICTRL0_L1);
+  NewValue &= OCFGPIMIXLOAD_1_0_MASK;
+  QNCPortIOWrite (QUARK_SC_PCIE_AFE_SB_PORT_ID, QUARK_PCIE_AFE_PCIE_RXPICTRL0_L1, NewValue);
+
+  return EFI_SUCCESS;
+}
+
+/** Tasks to release PCI controller from reset pre wait for PLL Lock.
+
+  @retval   EFI_SUCCESS               Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+SocUnitReleasePcieControllerPreWaitPllLock (
+  IN CONST EFI_PLATFORM_TYPE              PlatformType
+  )
+{
+  UINT32      NewValue;
+
+  //
+  // Assert PERST# and validate time assertion time.
+  //
+  PlatformPERSTAssert (PlatformType);
+  ASSERT (PCIEXP_PERST_MIN_ASSERT_US <= (PCIEXP_DELAY_US_POST_CMNRESET_RESET + PCIEXP_DELAY_US_WAIT_PLL_LOCK + PCIEXP_DELAY_US_POST_SBI_RESET));
+
+  //
+  // PHY Common lane reset.
+  //
+  NewValue = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_SOCCLKEN_CONFIG);
+  NewValue |= SOCCLKEN_CONFIG_PHY_I_CMNRESET_L;
+  QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_SOCCLKEN_CONFIG, NewValue);
+
+  //
+  // Wait post common lane reset.
+  //
+  MicroSecondDelay (PCIEXP_DELAY_US_POST_CMNRESET_RESET);
+
+  //
+  // PHY Sideband interface reset.
+  // Controller main reset
+  //
+  NewValue = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_SOCCLKEN_CONFIG);
+  NewValue |= (SOCCLKEN_CONFIG_SBI_RST_100_CORE_B | SOCCLKEN_CONFIG_PHY_I_SIDE_RST_L);
+  QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_SOCCLKEN_CONFIG, NewValue);
+
+  return EFI_SUCCESS;
+}
+
+/** Tasks to release PCI controller from reset after PLL has locked
+
+  @retval   EFI_SUCCESS               Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+SocUnitReleasePcieControllerPostPllLock (
+  IN CONST EFI_PLATFORM_TYPE              PlatformType
+  )
+{
+  UINT32 NewValue;
+
+  //
+  // Controller sideband interface reset.
+  //
+  NewValue = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_SOCCLKEN_CONFIG);
+  NewValue |= SOCCLKEN_CONFIG_SBI_BB_RST_B;
+  QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_SOCCLKEN_CONFIG, NewValue);
+
+  //
+  // Wait post sideband interface reset.
+  //
+  MicroSecondDelay (PCIEXP_DELAY_US_POST_SBI_RESET);
+
+  //
+  // Deassert PERST#.
+  //
+  PlatformPERSTDeAssert (PlatformType);
+
+  //
+  // Wait post de assert PERST#.
+  //
+  MicroSecondDelay (PCIEXP_DELAY_US_POST_PERST_DEASSERT);
+
+  //
+  // Controller primary interface reset.
+  //
+  NewValue = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_SOCCLKEN_CONFIG);
+  NewValue |= SOCCLKEN_CONFIG_BB_RST_B;
+  QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_SOCCLKEN_CONFIG, NewValue);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Flat32.S b/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Flat32.S
new file mode 100644
index 0000000000..1ba63abd7b
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Flat32.S
@@ -0,0 +1,796 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2013 - 2016 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+# Module Name:
+#
+#  Flat32.S
+#
+# Abstract:
+#
+#  This is the code that goes from real-mode to protected mode.
+#  It consumes the reset vector, configures the stack.
+#
+#
+#------------------------------------------------------------------------------
+
+.macro RET32
+    jmp    *%esp
+.endm
+
+#
+# ROM/SPI/MEMORY Definitions
+#
+.equ  QUARK_DDR3_MEM_BASE_ADDRESS, (0x000000000)    # Memory Base Address = 0
+.equ  QUARK_MAX_DDR3_MEM_SIZE_BYTES, (0x80000000)    # DDR3 Memory Size = 2GB
+.equ  QUARK_ESRAM_MEM_SIZE_BYTES, (0x00080000)    # eSRAM Memory Size = 512K
+.equ  QUARK_STACK_SIZE_BYTES, (0x008000)      # Quark stack size = 32K
+
+#
+# RTC/CMOS definitions
+#
+.equ  RTC_INDEX, (0x70)
+.equ    NMI_DISABLE, (0x80)  # Bit7=1 disables NMI
+.equ    NMI_ENABLE, (0x00)  # Bit7=0 disables NMI
+.equ  RTC_DATA, (0x71)
+
+#
+# PCI Configuration definitions
+#
+.equ  PCI_CFG, (0x80000000) # PCI configuration access mechanism
+.equ  PCI_ADDRESS_PORT, (0xCF8)
+.equ  PCI_DATA_PORT, (0xCFC)
+
+#
+# Quark PCI devices
+#
+.equ  HOST_BRIDGE_PFA, (0x0000)   # B0:D0:F0 (Host Bridge)
+.equ  ILB_PFA, (0x00F8)      # B0:D31:F0 (Legacy Block)
+
+#
+# ILB PCI Config Registers
+#
+.equ  BDE, (0x0D4)                                # BIOS Decode Enable register
+.equ    DECODE_ALL_REGIONS_ENABLE, (0xFF000000)    # Decode all BIOS decode ranges
+
+#
+# iLB Reset Register
+#
+.equ  ILB_RESET_REG, (0x0CF9)
+.equ    CF9_WARM_RESET, (0x02)
+.equ    CF9_COLD_RESET, (0x08)
+
+#
+# Host Bridge PCI Config Registers
+#
+.equ  MESSAGE_BUS_CONTROL_REG, (0xD0)       # Message Bus Control Register
+.equ    SB_OPCODE_FIELD, (0x18)              # Bit location of Opcode field
+.equ      OPCODE_SIDEBAND_REG_READ, (0x10)  # Read opcode
+.equ      OPCODE_SIDEBAND_REG_WRITE, (0x11) # Write opcode
+.equ      OPCODE_SIDEBAND_ALT_REG_READ, (0x06)  # Alternate Read opcode
+.equ      OPCODE_SIDEBAND_ALT_REG_WRITE, (0x07) # Alternate Write opcode
+.equ      OPCODE_WARM_RESET_REQUEST, (0xF4)  # Reset Warm
+.equ      OPCODE_COLD_RESET_REQUEST, (0xF5) # Reset Cold
+.equ    SB_PORT_FIELD, (0x10)               # Bit location of Port ID field
+.equ      MEMORY_ARBITER_PORT_ID, (0x00)
+.equ      HOST_BRIDGE_PORT_ID, (0x03)
+.equ      RMU_PORT_ID, (0x04)
+.equ      MEMORY_MANAGER_PORT_ID, (0x05)
+.equ      SOC_UNIT_PORT_ID, (0x31)
+.equ    SB_ADDR_FIELD, (0x08)               # Bit location of Register field
+.equ    SB_BE_FIELD, (0x04)                  # Bit location of Byte Enables field
+.equ      ALL_BYTE_EN, (0x0F)                # All Byte Enables
+.equ  MESSAGE_DATA_REG, (0xD4)              # Message Data Register
+
+#
+# Memory Arbiter Config Registers
+#
+.equ  AEC_CTRL_OFFSET, (0x00)
+
+#
+# Host Bridge Config Registers
+#
+.equ  HMISC2_OFFSET, (0x03) # PCI configuration access mechanism
+.equ    OR_PM_FIELD, (0x10)
+.equ      SMI_EN, (0x00080000)
+
+.equ  HMBOUND_OFFSET, (0x08)
+.equ    HMBOUND_ADDRESS, (QUARK_DDR3_MEM_BASE_ADDRESS + QUARK_MAX_DDR3_MEM_SIZE_BYTES + QUARK_ESRAM_MEM_SIZE_BYTES)
+.equ    HMBOUND_LOCK, (0x01)
+.equ  HECREG_OFFSET, (0x09)
+.equ    EC_BASE, (0xE0000000)
+.equ    EC_ENABLE, (0x01)
+.equ  HLEGACY_OFFSET, (0x0A)
+.equ    NMI, (0x00004000)
+.equ    SMI, (0x00001000)
+.equ    INTR, (0x00000400)
+
+#
+# Memory Manager Config Registers
+#
+.equ  ESRAMPGCTRL_BLOCK_OFFSET, (0x82)
+.equ    BLOCK_ENABLE_PG, (0x10000000)
+.equ  BIMRVCTL_OFFSET, (0x19)
+.equ    ENABLE_IMR_INTERRUPT, (0x80000000)
+
+#
+# SOC UNIT Debug Registers
+#
+.equ  CFGSTICKY_W1_OFFSET, (0x50)
+.equ    FORCE_COLD_RESET, (0x00000001)
+.equ  CFGSTICKY_RW_OFFSET, (0x51)
+.equ    RESET_FOR_ESRAM_LOCK, (0x00000020)
+.equ    RESET_FOR_HMBOUND_LOCK, (0x00000040)
+.equ  CFGNONSTICKY_W1_OFFSET, (0x52)
+.equ    FORCE_WARM_RESET, (0x00000001)
+
+#
+# CR0 cache control bit definition
+#
+.equ                    CR0_CACHE_DISABLE, 0x040000000
+.equ                    CR0_NO_WRITE,      0x020000000
+
+ASM_GLOBAL  ASM_PFX(PcdGet32(PcdEsramStage1Base))
+
+
+#
+# Contrary to the name, this file contains 16 bit code as well.
+#
+.text
+#----------------------------------------------------------------------------
+#
+# 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
+#
+#----------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+
+  #
+  # Warm Reset (INIT#) check.
+  #
+  .byte   0xbe,0x00,0xf0   #movw    $0xF000, %si
+  .byte   0x8e,0xde        #movw    %si, %ds
+  .byte   0xbe,0xf0,0xff   #movw    $0xFFF0, %si
+  .byte   0x80,0x3c,0xea   #cmpb    $0xEA, (%si)          # Is it warm reset ?
+  jne     NotWarmReset     # Jump if not.
+  .byte   0xb0,0x08        #movb    $0x08, %al
+  .byte   0xba,0xf9,0x0c   #movw    $0xcf9, %dx
+  .byte   0xee             #outb    %al, %dx
+  .byte   0xb0,0x55        #movb    $0x55, %al
+  .byte   0xe6,0x80        #outb    %al, $0x80
+  jmp     .
+NotWarmReset:
+  .byte   0x66,0x8b,0xe8   #movl    %eax, %ebp
+
+  #
+  # Load the GDT table in GdtDesc
+  #
+  .byte   0x66,0xbe        #movl    $GdtDesc, %esi
+  .long   GdtDesc
+
+  .byte   0x66,0x2e,0x0f,0x01,0x14   #lgdt    %cs:(%si)
+
+  #
+  # Transition to 16 bit protected mode
+  #
+  .byte   0x0f,0x20,0xc0       #movl    %cr0, %eax                  # Get control register 0
+  .byte   0x66,0x83,0xc8,0x03  #orl     $0x0000003, %eax           # Set PE bit (bit #0) & MP bit (bit #1)
+  .byte   0x0f,0x22,0xc0       #movl    %eax, %cr0                  # Activate protected mode
+
+  #
+  # Now we're in 16 bit protected mode
+  # Set up the selectors for 32 bit protected mode entry
+  #
+  .byte   0xb8                 #movw    SYS_DATA_SEL, %ax
+  .word   SYS_DATA_SEL
+
+  .byte   0x8e,0xd8            #movw    %ax, %ds
+  .byte   0x8e,0xc0            #movw    %ax, %es
+  .byte   0x8e,0xe0            #movw    %ax, %fs
+  .byte   0x8e,0xe8            #movw    %ax, %gs
+  .byte   0x8e,0xd0            #movw    %ax, %ss
+
+  #
+  # Transition to Flat 32 bit protected mode
+  # The jump to a far pointer causes the transition to 32 bit mode
+  #
+  .byte   0x66,0xbe            #movl   ProtectedModeEntryLinearAddress, %esi
+  .long   ProtectedModeEntryLinearAddress
+  .byte   0x66,0x2e,0xff,0x2c  #jmp    %cs:(%esi)
+
+#
+# Protected mode portion initializes stack, configures cache, and calls C entry point
+#
+
+#----------------------------------------------------------------------------
+#
+# Procedure:    ProtectedModeEntryPoint
+#
+# Input:        Executing in 32 Bit Protected (flat) mode
+#                cs: 0-4GB
+#                ds: 0-4GB
+#                es: 0-4GB
+#                fs: 0-4GB
+#                gs: 0-4GB
+#                ss: 0-4GB
+#
+# Output:       This function never returns
+#
+# Destroys:
+#               ecx
+#               edi
+#                esi
+#                esp
+#
+# Description:
+#                Perform any essential early platform initilaisation
+#               Setup a stack
+#               Transfer control to EDKII code in eSRAM
+#
+#----------------------------------------------------------------------------
+ProtectedModeEntryPoint:
+  leal  L0, %esp
+  jmp  stackless_EarlyPlatformInit
+L0:
+
+  #
+  # Set up stack pointer
+  #
+  movl    ASM_PFX(PcdGet32(PcdEsramStage1Base)), %esp
+  movl    $QUARK_ESRAM_MEM_SIZE_BYTES, %esi
+  addl    %esi, %esp                          # ESP = top of stack (stack grows downwards).
+
+  #
+  # Store the the BIST value in EBP
+  #
+  movl    $0, %ebp    # No processor BIST on Quark
+
+  #
+  # Push processor count to stack first, then BIST status (AP then BSP)
+  #
+  movl    $1, %eax
+  cpuid
+  shrl    $16, %ebx
+  andl    $0x000000FF, %ebx
+  cmpb    $1, %bl
+  jae     PushProcessorCount
+
+  #
+  # Some processors report 0 logical processors.  Effectively 0 = 1.
+  # So we fix up the processor count
+  #
+  incl    %ebx
+
+PushProcessorCount:
+  pushl   %ebx
+
+  #
+  # We need to implement a long-term solution for BIST capture.  For now, we just copy BSP BIST
+  # for all processor threads
+  #
+  xorl    %ecx, %ecx
+  movb    %bl, %cl
+
+PushBist:
+  pushl   %ebp
+  loop    PushBist
+
+  #
+  # Pass Control into the PEI Core
+  #
+  call PlatformSecLibStartup
+
+  #
+  # PEI Core should never return to here, this is just to capture an invalid return.
+  #
+  jmp     .
+
+#----------------------------------------------------------------------------
+#
+# Procedure:    stackless_EarlyPlatformInit
+#
+# Input:        esp - Return address
+#
+# Output:       None
+#
+# Destroys:     Assume all registers
+#
+# Description:
+#        Any early platform initialisation required
+#
+# Return:
+#      None
+#
+#----------------------------------------------------------------------------
+stackless_EarlyPlatformInit:
+
+  #
+  # Save return address
+  #
+  movl  %esp, %ebp
+
+  #
+  # Ensure cache is disabled.
+  #
+  movl %cr0, %eax
+  orl $(CR0_CACHE_DISABLE + CR0_NO_WRITE), %eax
+  invd
+  movl    %eax, %cr0
+
+  #
+  # Disable NMI operation
+  # Good convention suggests you should read back RTC data port after
+  # accessing the RTC index port.
+  #
+  movb $(NMI_DISABLE), %al
+  movw $(RTC_INDEX), %dx
+  outb %al, %dx
+  movw $(RTC_DATA), %dx
+  inb  %dx, %al
+
+  #
+  # Disable SMI (Disables SMI wire, not SMI messages)
+  #
+  movl  $((OPCODE_SIDEBAND_REG_READ << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HMISC2_OFFSET << SB_ADDR_FIELD)), %ecx
+  leal  L1, %esp
+  jmp  stackless_SideBand_Read
+L1:
+  andl $(~SMI_EN), %eax
+  movl  $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HMISC2_OFFSET << SB_ADDR_FIELD)), %ecx
+  leal  L2, %esp
+  jmp  stackless_SideBand_Write
+L2:
+
+  #
+  # Before we get going, check SOC Unit Registers to see if we are required to issue a warm/cold reset
+  #
+  movl  $((OPCODE_SIDEBAND_ALT_REG_READ << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGNONSTICKY_W1_OFFSET << SB_ADDR_FIELD)), %ecx
+  leal  L3, %esp
+  jmp  stackless_SideBand_Read
+L3:
+  andl $(FORCE_WARM_RESET), %eax
+  jz TestForceColdReset    # Zero means bit clear, we're not requested to warm reset so continue as normal
+  jmp IssueWarmReset
+
+TestForceColdReset:
+  movl  $((OPCODE_SIDEBAND_ALT_REG_READ << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGNONSTICKY_W1_OFFSET << SB_ADDR_FIELD)), %ecx
+  leal  L4, %esp
+  jmp  stackless_SideBand_Read
+L4:
+  andl $(FORCE_COLD_RESET), %eax
+  jz TestHmboundLock    # Zero means bit clear, we're not requested to cold reset so continue as normal
+  jmp IssueColdReset
+
+  #
+  # Before setting HMBOUND, check it's not locked
+  #
+TestHmboundLock:
+  movl  $((OPCODE_SIDEBAND_REG_READ << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HMBOUND_OFFSET << SB_ADDR_FIELD)), %ecx
+  leal  L5, %esp
+  jmp  stackless_SideBand_Read
+L5:
+  andl $(HMBOUND_LOCK), %eax
+  jz ConfigHmbound  # Zero means bit clear, we have the config we want so continue as normal
+  #
+  # Failed to config - store sticky bit debug
+  #
+  movl  $((OPCODE_SIDEBAND_ALT_REG_READ << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGSTICKY_RW_OFFSET << SB_ADDR_FIELD)), %ecx
+  leal  L6, %esp
+  jmp  stackless_SideBand_Read
+L6:
+  orl $(RESET_FOR_HMBOUND_LOCK), %eax
+  movl  $((OPCODE_SIDEBAND_ALT_REG_WRITE << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGSTICKY_RW_OFFSET << SB_ADDR_FIELD)), %ecx
+  leal  L7, %esp
+  jmp  stackless_SideBand_Write
+L7:
+  jmp IssueWarmReset
+
+  #
+  # Set up the HMBOUND register
+  #
+ConfigHmbound:
+  movl $(HMBOUND_ADDRESS), %eax      # Data (Set HMBOUND location)
+  movl  $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HMBOUND_OFFSET << SB_ADDR_FIELD)), %ecx
+  leal  L8, %esp
+  jmp  stackless_SideBand_Write
+L8:
+
+  #
+  # Enable interrupts to Remote Management Unit when a IMR/SMM/HMBOUND violation occurs.
+  #
+  movl $(ENABLE_IMR_INTERRUPT), %eax      # Data (Set interrupt enable mask)
+  movl  $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (MEMORY_MANAGER_PORT_ID << SB_PORT_FIELD) | (BIMRVCTL_OFFSET << SB_ADDR_FIELD)), %ecx
+  leal  L9, %esp
+  jmp  stackless_SideBand_Write
+L9:
+
+  #
+  # Set eSRAM address
+  #
+  movl    ASM_PFX(PcdGet32(PcdEsramStage1Base)), %eax   # Data (Set eSRAM location)
+  shr   $(0x18), %eax
+  addl  $(BLOCK_ENABLE_PG), %eax
+  movl  $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (MEMORY_MANAGER_PORT_ID << SB_PORT_FIELD) | (ESRAMPGCTRL_BLOCK_OFFSET << SB_ADDR_FIELD)), %ecx
+  leal  L10, %esp
+  jmp  stackless_SideBand_Write
+L10:
+
+  #
+  # Check that we're not blocked from setting the config that we want.
+  #
+  movl  $((OPCODE_SIDEBAND_REG_READ << SB_OPCODE_FIELD) | (MEMORY_MANAGER_PORT_ID << SB_PORT_FIELD) | (ESRAMPGCTRL_BLOCK_OFFSET << SB_ADDR_FIELD)), %ecx
+  leal  L11, %esp
+  jmp  stackless_SideBand_Read
+L11:
+  andl $(BLOCK_ENABLE_PG), %eax
+  jnz ConfigPci  # Non-zero means bit set, we have the config we want so continue as normal
+  #
+  # Failed to config - store sticky bit debug
+  #
+  movl  $((OPCODE_SIDEBAND_ALT_REG_READ << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGSTICKY_RW_OFFSET << SB_ADDR_FIELD)), %ecx
+  leal  L12, %esp
+  jmp  stackless_SideBand_Read
+L12:
+  orl $(RESET_FOR_ESRAM_LOCK), %eax     # Set the bit we're interested in
+  movl  $((OPCODE_SIDEBAND_ALT_REG_WRITE << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGSTICKY_RW_OFFSET << SB_ADDR_FIELD)), %ecx
+  leal  L13, %esp
+  jmp  stackless_SideBand_Write
+L13:
+  jmp IssueWarmReset
+
+  #
+  # Enable PCIEXBAR
+  #
+ConfigPci:
+  movl $(EC_BASE + EC_ENABLE), %eax      # Data
+  movl  $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (MEMORY_ARBITER_PORT_ID << SB_PORT_FIELD) | (AEC_CTRL_OFFSET << SB_ADDR_FIELD)), %ecx
+  leal  L14, %esp
+  jmp  stackless_SideBand_Write
+L14:
+
+  movl $(EC_BASE + EC_ENABLE), %eax      # Data
+  movl  $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HECREG_OFFSET << SB_ADDR_FIELD)), %ecx
+  leal  L15, %esp
+  jmp  stackless_SideBand_Write
+L15:
+
+  #
+  #  Open up full 8MB SPI decode
+  #
+  movl  $(PCI_CFG | (ILB_PFA << 8) | BDE), %ebx  # PCI Configuration address
+  movl $(DECODE_ALL_REGIONS_ENABLE), %eax
+  leal  L16, %esp
+  jmp  stackless_PCIConfig_Write
+L16:
+
+  #
+  # Enable NMI operation
+  # Good convention suggests you should read back RTC data port after
+  # accessing the RTC index port.
+  #
+  movb $(NMI_ENABLE), %al
+  movw $(RTC_INDEX), %dx
+  outb %al, %dx
+  movw $(RTC_DATA), %dx
+  inb  %dx, %al
+
+  #
+  # Clear Host Bridge SMI, NMI, INTR fields
+  #
+  movl  $((OPCODE_SIDEBAND_REG_READ << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HLEGACY_OFFSET << SB_ADDR_FIELD)), %ecx
+  leal  L21, %esp
+  jmp  stackless_SideBand_Read
+L21:
+  andl $~(NMI + SMI + INTR), %eax      # Clear NMI, SMI, INTR fields
+  movl  $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HLEGACY_OFFSET << SB_ADDR_FIELD)), %ecx
+  leal  L22, %esp
+  jmp  stackless_SideBand_Write
+L22:
+
+  #
+  # Restore return address
+  #
+  movl  %ebp, %esp
+  RET32
+
+IssueWarmReset:
+  #
+  # Issue Warm Reset request to Remote Management Unit via iLB
+  #
+  movw  $(CF9_WARM_RESET), %ax
+  movw  $(ILB_RESET_REG), %dx
+  outw  %ax, %dx
+  jmp  .  # Stay here until we are reset.
+
+IssueColdReset:
+  #
+  # Issue Cold Reset request to Remote Management Unit via iLB
+  #
+  movw  $(CF9_COLD_RESET), %ax
+  movw  $(ILB_RESET_REG), %dx
+  outw  %ax, %dx
+  jmp  .  # Stay here until we are reset.
+
+#----------------------------------------------------------------------------
+#
+# Procedure:    stackless_SideBand_Read
+#
+# Input:        esp - return address
+#                ecx[15:8] - Register offset
+#                ecx[23:16] - Port ID
+#                ecx[31:24] - Opcode
+#
+# Output:       eax - Data read
+#
+# Destroys:
+#                eax
+#                ebx
+#                cl
+#                esi
+#
+# Description:
+#        Perform requested sideband read
+#
+#----------------------------------------------------------------------------
+stackless_SideBand_Read:
+
+  movl  %esp, %esi      # Save the return address
+
+  #
+  # Load the SideBand Packet Register to generate the transaction
+  #
+  movl  $((PCI_CFG) | (HOST_BRIDGE_PFA << 8) | (MESSAGE_BUS_CONTROL_REG)), %ebx   # PCI Configuration address
+  movb  $(ALL_BYTE_EN << SB_BE_FIELD), %cl      # Set all Byte Enable bits
+  xchgl  %ecx, %eax
+  leal  L17, %esp
+  jmp  stackless_PCIConfig_Write
+L17:
+  xchgl  %ecx, %eax
+
+  #
+  # Read the SideBand Data Register
+  #
+  movl  $((PCI_CFG) | (HOST_BRIDGE_PFA << 8) | (MESSAGE_DATA_REG)), %ebx   # PCI Configuration address
+  leal  L18, %esp
+  jmp  stackless_PCIConfig_Read
+L18:
+
+  movl  %esi, %esp      # Restore the return address
+  RET32
+
+
+#----------------------------------------------------------------------------
+#
+# Procedure:    stackless_SideBand_Write
+#
+# Input:        esp - return address
+#                eax - Data
+#                ecx[15:8] - Register offset
+#                ecx[23:16] - Port ID
+#                ecx[31:24] - Opcode
+#
+# Output:       None
+#
+# Destroys:
+#                ebx
+#                cl
+#                esi
+#
+# Description:
+#        Perform requested sideband write
+#
+#
+#----------------------------------------------------------------------------
+stackless_SideBand_Write:
+
+  movl  %esp, %esi      # Save the return address
+
+  #
+  # Load the SideBand Data Register with the data
+  #
+  movl  $((PCI_CFG) | (HOST_BRIDGE_PFA << 8) | (MESSAGE_DATA_REG)), %ebx   # PCI Configuration address
+  leal  L19, %esp
+  jmp  stackless_PCIConfig_Write
+L19:
+
+  #
+  # Load the SideBand Packet Register to generate the transaction
+  #
+  movl  $((PCI_CFG) | (HOST_BRIDGE_PFA << 8) | (MESSAGE_BUS_CONTROL_REG)), %ebx   # PCI Configuration address
+  movb  $(ALL_BYTE_EN << SB_BE_FIELD), %cl      # Set all Byte Enable bits
+  xchgl  %ecx, %eax
+  leal  L20, %esp
+  jmp  stackless_PCIConfig_Write
+L20:
+  xchgl  %ecx, %eax
+
+  movl  %esi, %esp      # Restore the return address
+  RET32
+
+
+#----------------------------------------------------------------------------
+#
+# Procedure:    stackless_PCIConfig_Write
+#
+# Input:        esp - return address
+#                eax - Data to write
+#                ebx - PCI Config Address
+#
+# Output:       None
+#
+# Destroys:
+#                dx
+#
+# Description:
+#        Perform a DWORD PCI Configuration write
+#
+#----------------------------------------------------------------------------
+stackless_PCIConfig_Write:
+
+  #
+  # Write the PCI Config Address to the address port
+  #
+  xchgl  %ebx, %eax
+  movw  $(PCI_ADDRESS_PORT), %dx
+  outl  %eax, %dx
+  xchgl  %ebx, %eax
+
+  #
+  # Write the PCI DWORD Data to the data port
+  #
+  movw  $(PCI_DATA_PORT), %dx
+  outl  %eax, %dx
+
+  RET32
+
+
+#----------------------------------------------------------------------------
+#
+# Procedure:    stackless_PCIConfig_Read
+#
+# Input:        esp - return address
+#                ebx - PCI Config Address
+#
+# Output:       eax - Data read
+#
+# Destroys:
+#                eax
+#                dx
+#
+# Description:
+#        Perform a DWORD PCI Configuration read
+#
+#----------------------------------------------------------------------------
+stackless_PCIConfig_Read:
+
+  #
+  # Write the PCI Config Address to the address port
+  #
+  xchgl  %ebx, %eax
+  movw  $(PCI_ADDRESS_PORT), %dx
+  outl  %eax, %dx
+  xchgl  %ebx, %eax
+
+  #
+  # Read the PCI DWORD Data from the data port
+  #
+  movw  $(PCI_DATA_PORT), %dx
+  inl  %dx, %eax
+
+  RET32
+
+
+#
+# ROM-based Global-Descriptor Table for the Tiano PEI Phase
+#
+.align 16
+#
+# GDT[0]: 000h: Null entry, never used.
+#
+
+GDT_BASE:
+BootGdtTable:
+# null descriptor
+.equ                NULL_SEL, . - GDT_BASE # Selector [0]
+        .word 0         # limit 15:0
+        .word 0         # base 15:0
+        .byte 0         # base 23:16
+        .byte 0         # type
+        .byte 0         # limit 19:16, flags
+        .byte 0         # base 31:24
+
+# linear data segment descriptor
+.equ            LINEAR_SEL, . - GDT_BASE # Selector [0x8]
+        .word 0xFFFF    # limit 0xFFFFF
+        .word 0         # base 0
+        .byte 0
+        .byte 0x92      # present, ring 0, data, expand-up, writable
+        .byte 0xCF              # page-granular, 32-bit
+        .byte 0
+
+# linear code segment descriptor
+.equ            LINEAR_CODE_SEL, . - GDT_BASE # Selector [0x10]
+        .word 0xFFFF    # limit 0xFFFFF
+        .word 0         # base 0
+        .byte 0
+        .byte 0x9A      # present, ring 0, data, expand-up, writable
+        .byte 0xCF              # page-granular, 32-bit
+        .byte 0
+
+# system data segment descriptor
+.equ            SYS_DATA_SEL, . - GDT_BASE # Selector [0x18]
+        .word 0xFFFF    # limit 0xFFFFF
+        .word 0         # base 0
+        .byte 0
+        .byte 0x92      # present, ring 0, data, expand-up, writable
+        .byte 0xCF              # page-granular, 32-bit
+        .byte 0
+
+# system code segment descriptor
+.equ            SYS_CODE_SEL, . - GDT_BASE
+        .word 0xFFFF    # limit 0xFFFFF
+        .word 0         # base 0
+        .byte 0
+        .byte 0x9A      # present, ring 0, data, expand-up, writable
+        .byte 0xCF              # page-granular, 32-bit
+        .byte 0
+
+# spare segment descriptor
+.equ        SYS16_CODE_SEL, . - GDT_BASE
+        .word 0xffff    # limit 0xFFFFF
+        .word 0         # base 0
+        .byte 0x0f
+        .byte 0x9b      # present, ring 0, data, expand-up, writable
+        .byte 0         # page-granular, 32-bit
+        .byte 0
+
+# spare segment descriptor
+.equ        SYS16_DATA_SEL, . - GDT_BASE
+        .word 0xffff    # limit 0xFFFFF
+        .word 0         # base 0
+        .byte 0
+        .byte 0x93      # present, ring 0, data, expand-up, not-writable
+        .byte 0         # page-granular, 32-bit
+        .byte 0
+
+# spare segment descriptor
+.equ        SPARE5_SEL, . - GDT_BASE
+        .word 0         # limit 0xFFFFF
+        .word 0         # base 0
+        .byte 0
+        .byte 0         # present, ring 0, data, expand-up, writable
+        .byte 0         # page-granular, 32-bit
+        .byte 0
+.equ        GDT_SIZE, . - GDT_BASE
+
+#
+# GDT Descriptor
+#
+GdtDesc:                                     # GDT descriptor
+       .word    GDT_SIZE - 1
+       .long    BootGdtTable
+
+ProtectedModeEntryLinearAddress:
+ProtectedModeEntryLinearOffset:
+       .long    ProtectedModeEntryPoint
+       .word    LINEAR_CODE_SEL
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Flat32.asm b/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Flat32.asm
new file mode 100644
index 0000000000..45e9e6a84a
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Flat32.asm
@@ -0,0 +1,685 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2013-2015 Intel Corporation.
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+;  Flat32.asm
+;
+; Abstract:
+;
+;  This is the code that goes from real-mode to protected mode.
+;  It consumes the reset vector, configures the stack.
+;
+;
+;------------------------------------------------------------------------------
+
+
+;
+; Define assembler characteristics
+;
+.586p
+.model flat, c
+
+;
+; Include processor definitions
+;
+
+INCLUDE Platform.inc
+
+
+;
+; CR0 cache control bit definition
+;
+CR0_CACHE_DISABLE       EQU 040000000h
+CR0_NO_WRITE            EQU 020000000h
+
+;
+; External and public declarations
+;  TopOfStack is used by C code
+;  SecStartup is the entry point to the C code
+; Neither of these names can be modified without
+; updating the C code.
+;
+EXTRN   PlatformSecLibStartup: NEAR
+EXTERNDEF   C   PcdGet32 (PcdEsramStage1Base):DWORD
+
+;
+; Contrary to the name, this file contains 16 bit code as well.
+;
+_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
+;
+;----------------------------------------------------------------------------
+align 16
+_ModuleEntryPoint      PROC C PUBLIC
+
+  ;
+  ; Warm Reset (INIT#) check.
+  ;
+  mov     si, 0F000h
+  mov     ds, si
+  mov     si, 0FFF0h
+  cmp     BYTE PTR [si], 0EAh   ; Is it warm reset ?
+  jne     NotWarmReset          ; JIf not.
+
+  mov     al, 08
+  mov     dx, 0cf9h
+  out     dx, al
+  mov     al, 055h
+  out     080h, al;
+  jmp $
+NotWarmReset:
+
+  ;
+  ; 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
+
+  ;
+  ; 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
+
+.code
+;
+; Protected mode portion initializes stack, configures cache, and calls C entry point
+;
+
+;----------------------------------------------------------------------------
+;
+; Procedure:    ProtectedModeEntryPoint
+;
+; Input:        Executing in 32 Bit Protected (flat) mode
+;                cs: 0-4GB
+;                ds: 0-4GB
+;                es: 0-4GB
+;                fs: 0-4GB
+;                gs: 0-4GB
+;                ss: 0-4GB
+;
+; Output:       This function never returns
+;
+; Destroys:
+;               ecx
+;               edi
+;                esi
+;                esp
+;
+; Description:
+;                Perform any essential early platform initilaisation
+;               Setup a stack
+;               Call the main EDKII Sec C code
+;
+;----------------------------------------------------------------------------
+
+ProtectedModeEntryPoint PROC NEAR C PUBLIC
+
+  JMP32  stackless_EarlyPlatformInit
+
+  ;
+  ; Set up stack pointer
+  ;
+  mov     esp, PcdGet32(PcdEsramStage1Base)
+  mov     esi, QUARK_ESRAM_MEM_SIZE_BYTES
+  add     esp, esi                         ; ESP = top of stack (stack grows downwards).
+
+  ;
+  ; Store the the BIST value in EBP
+  ;
+  mov     ebp, 00h        ; No processor BIST on Quark
+
+  ;
+  ; 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:
+  push    ebp
+  loop    PushBist
+
+  ;
+  ; Pass Control into the PEI Core
+  ;
+  call PlatformSecLibStartup
+
+  ;
+  ; PEI Core should never return to here, this is just to capture an invalid return.
+  ;
+  jmp     $
+
+ProtectedModeEntryPoint ENDP
+
+;----------------------------------------------------------------------------
+;
+; Procedure:    stackless_EarlyPlatformInit
+;
+; Input:        esp - Return address
+;
+; Output:       None
+;
+; Destroys:
+;                eax
+;                ecx
+;                dx
+;                ebp
+;
+; Description:
+;        Any essential early platform initialisation required:
+;        (1) Disable Cache
+;        (2) Disable NMI's/SMI's
+;        (3) Setup HMBOUND (defines what memory accesses go to MMIO/RAM)
+;        (4) Setup eSRAM (provide early memory to the system)
+;        (5) Setup PCIEXBAR access mechanism
+;        (6) Open up full SPI flash decode
+;
+;----------------------------------------------------------------------------
+stackless_EarlyPlatformInit  PROC NEAR C PUBLIC
+
+  ;
+  ; Save return address
+  ;
+  mov  ebp, esp
+
+  ;
+  ; Ensure cache is disabled.
+  ;
+  mov     eax, cr0
+  or      eax, CR0_CACHE_DISABLE + CR0_NO_WRITE
+  invd
+  mov     cr0, eax
+
+  ;
+  ; Disable NMI
+  ; Good convention suggests you should read back RTC data port after
+  ; accessing the RTC index port.
+  ;
+  mov  al, NMI_DISABLE
+  mov  dx, RTC_INDEX
+  out  dx, al
+  mov  dx, RTC_DATA
+  in  al, dx
+
+  ;
+  ; Disable SMI (Disables SMI wire, not SMI messages)
+  ;
+  mov  ecx, (OPCODE_SIDEBAND_REG_READ SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HMISC2_OFFSET SHL SB_ADDR_FIELD)
+  JMP32  stackless_SideBand_Read
+  and  eax, NOT (SMI_EN)
+  mov  ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HMISC2_OFFSET SHL SB_ADDR_FIELD)
+  JMP32  stackless_SideBand_Write
+
+  ;
+  ; Before we get going, check SOC Unit Registers to see if we are required to issue a warm/cold reset
+  ;
+  mov  ecx, (OPCODE_SIDEBAND_ALT_REG_READ SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGNONSTICKY_W1_OFFSET SHL SB_ADDR_FIELD)
+  JMP32  stackless_SideBand_Read
+  and  eax, FORCE_WARM_RESET
+  jz TestForceColdReset    ; Zero means bit clear, we're not requested to warm reset so continue as normal
+  jmp IssueWarmReset
+
+TestForceColdReset:
+  mov  ecx, (OPCODE_SIDEBAND_ALT_REG_READ SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_W1_OFFSET SHL SB_ADDR_FIELD)
+  JMP32  stackless_SideBand_Read
+  and  eax, FORCE_COLD_RESET
+  jz TestHmboundLock    ; Zero means bit clear, we're not requested to cold reset so continue as normal
+  jmp IssueColdReset
+
+  ;
+  ; Before setting HMBOUND, check it's not locked
+  ;
+TestHmboundLock:
+  mov  ecx, (OPCODE_SIDEBAND_REG_READ SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HMBOUND_OFFSET SHL SB_ADDR_FIELD)
+  JMP32  stackless_SideBand_Read
+  and  eax, HMBOUND_LOCK
+  jz ConfigHmbound  ; Zero means bit clear, we have the config we want so continue as normal
+  ;
+  ; Failed to config - store sticky bit debug
+  ;
+  mov  ecx, (OPCODE_SIDEBAND_ALT_REG_READ SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_RW_OFFSET SHL SB_ADDR_FIELD)
+  JMP32  stackless_SideBand_Read
+  or  eax, RESET_FOR_HMBOUND_LOCK  ; Set the bit we're interested in
+  mov  ecx, (OPCODE_SIDEBAND_ALT_REG_WRITE SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_RW_OFFSET SHL SB_ADDR_FIELD)
+  JMP32  stackless_SideBand_Write
+  jmp IssueWarmReset
+
+  ;
+  ; Set up the HMBOUND register
+  ;
+ConfigHmbound:
+  mov  eax, HMBOUND_ADDRESS    ; Data (Set HMBOUND location)
+  mov  ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HMBOUND_OFFSET SHL SB_ADDR_FIELD)
+  JMP32  stackless_SideBand_Write
+
+  ;
+  ; Enable interrupts to Remote Management Unit when a IMR/SMM/HMBOUND violation occurs.
+  ;
+  mov  eax, ENABLE_IMR_INTERRUPT        ; Data (Set interrupt enable mask)
+  mov  ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (MEMORY_MANAGER_PORT_ID SHL SB_PORT_FIELD) OR (BIMRVCTL_OFFSET SHL SB_ADDR_FIELD)
+  JMP32  stackless_SideBand_Write
+
+  ;
+  ; Set eSRAM address
+  ;
+  mov  eax, PcdGet32 (PcdEsramStage1Base)        ; Data (Set eSRAM location)
+  shr  eax, 18h        ; Data (Set eSRAM location)
+  add eax, BLOCK_ENABLE_PG
+  mov  ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (MEMORY_MANAGER_PORT_ID SHL SB_PORT_FIELD) OR (ESRAMPGCTRL_BLOCK_OFFSET SHL SB_ADDR_FIELD)
+  JMP32  stackless_SideBand_Write
+  ;
+  ; Check that we're not blocked from setting the config that we want.
+  ;
+  mov  ecx, (OPCODE_SIDEBAND_REG_READ SHL SB_OPCODE_FIELD) OR (MEMORY_MANAGER_PORT_ID SHL SB_PORT_FIELD) OR (ESRAMPGCTRL_BLOCK_OFFSET SHL SB_ADDR_FIELD)
+  JMP32  stackless_SideBand_Read
+  and  eax, BLOCK_ENABLE_PG
+  jnz ConfigPci  ; Non-zero means bit set, we have the config we want so continue as normal
+  ;
+  ; Failed to config - store sticky bit debug
+  ;
+  mov  ecx, (OPCODE_SIDEBAND_ALT_REG_READ SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_RW_OFFSET SHL SB_ADDR_FIELD)
+  JMP32  stackless_SideBand_Read
+  or  eax, RESET_FOR_ESRAM_LOCK  ; Set the bit we're interested in
+  mov  ecx, (OPCODE_SIDEBAND_ALT_REG_WRITE SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_RW_OFFSET SHL SB_ADDR_FIELD)
+  JMP32  stackless_SideBand_Write
+  jmp IssueWarmReset
+
+  ;
+  ; Enable PCIEXBAR
+  ;
+ConfigPci:
+  mov  eax, (EC_BASE + EC_ENABLE)      ; Data
+  mov  ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (MEMORY_ARBITER_PORT_ID SHL SB_PORT_FIELD) OR (AEC_CTRL_OFFSET SHL SB_ADDR_FIELD)
+  JMP32  stackless_SideBand_Write
+
+  mov  eax, (EC_BASE + EC_ENABLE)      ; Data
+  mov  ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HECREG_OFFSET SHL SB_ADDR_FIELD)
+  JMP32  stackless_SideBand_Write
+
+  ;
+  ;  Open up full 8MB SPI decode
+  ;
+  mov  ebx, PCI_CFG OR (ILB_PFA SHL 8) OR BDE  ; PCI Configuration address
+  mov eax, DECODE_ALL_REGIONS_ENABLE
+  JMP32  stackless_PCIConfig_Write
+
+  ;
+  ; Enable NMI operation
+  ; Good convention suggests you should read back RTC data port after
+  ; accessing the RTC index port.
+  ;
+  mov al, NMI_ENABLE
+  mov dx, RTC_INDEX
+  out dx, al
+  mov dx, RTC_DATA
+  in  al, dx
+
+  ;
+  ; Clear Host Bridge SMI, NMI, INTR fields
+  ;
+  mov  ecx, (OPCODE_SIDEBAND_REG_READ SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HLEGACY_OFFSET SHL SB_ADDR_FIELD)
+  JMP32  stackless_SideBand_Read
+  and  eax, NOT(NMI + SMI + INTR)  ; Clear NMI, SMI, INTR fields
+  mov  ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HLEGACY_OFFSET SHL SB_ADDR_FIELD)
+  JMP32  stackless_SideBand_Write
+
+  ;
+  ; Restore return address
+  ;
+  mov  esp, ebp
+  RET32
+
+IssueWarmReset:
+  ;
+  ; Issue Warm Reset request to Remote Management Unit via iLB
+  ;
+  mov ax, CF9_WARM_RESET
+  mov  dx, ILB_RESET_REG
+  out  dx, ax
+  jmp  $  ; Stay here until we are reset.
+
+IssueColdReset:
+  ;
+  ; Issue Cold Reset request to Remote Management Unit via iLB
+  ;
+  mov ax, CF9_COLD_RESET
+  mov  dx, ILB_RESET_REG
+  out  dx, ax
+  jmp  $  ; Stay here until we are reset.
+
+stackless_EarlyPlatformInit ENDP
+
+;----------------------------------------------------------------------------
+;
+; Procedure:    stackless_SideBand_Read
+;
+; Input:        esp - return address
+;                ecx[15:8] - Register offset
+;                ecx[23:16] - Port ID
+;                ecx[31:24] - Opcode
+;
+; Output:       eax - Data read
+;
+; Destroys:
+;                eax
+;                ebx
+;                cl
+;                esi
+;
+; Description:
+;        Perform requested sideband read
+;
+;----------------------------------------------------------------------------
+stackless_SideBand_Read  PROC NEAR C PUBLIC
+
+  mov  esi, esp        ; Save the return address
+
+  ;
+  ; Load the SideBand Packet Register to generate the transaction
+  ;
+  mov  ebx, PCI_CFG OR (HOST_BRIDGE_PFA SHL 8) OR MESSAGE_BUS_CONTROL_REG  ; PCI Configuration address
+  mov  cl, (ALL_BYTE_EN SHL SB_BE_FIELD)    ; Set all Byte Enable bits
+  xchg  eax, ecx
+  JMP32  stackless_PCIConfig_Write
+  xchg  eax, ecx
+
+  ;
+  ; Read the SideBand Data Register
+  ;
+  mov  ebx, PCI_CFG OR (HOST_BRIDGE_PFA SHL 8) OR MESSAGE_DATA_REG    ; PCI Configuration address
+  JMP32  stackless_PCIConfig_Read
+
+  mov  esp, esi        ; Restore the return address
+  RET32
+
+stackless_SideBand_Read ENDP
+
+;----------------------------------------------------------------------------
+;
+; Procedure:    stackless_SideBand_Write
+;
+; Input:        esp - return address
+;                eax - Data
+;                ecx[15:8] - Register offset
+;                ecx[23:16] - Port ID
+;                ecx[31:24] - Opcode
+;
+; Output:       None
+;
+; Destroys:
+;                ebx
+;                cl
+;                esi
+;
+; Description:
+;        Perform requested sideband write
+;
+;
+;----------------------------------------------------------------------------
+stackless_SideBand_Write  PROC NEAR C PUBLIC
+
+  mov  esi, esp        ; Save the return address
+
+  ;
+  ; Load the SideBand Data Register with the data
+  ;
+  mov  ebx, PCI_CFG OR (HOST_BRIDGE_PFA SHL 8) OR MESSAGE_DATA_REG  ; PCI Configuration address
+  JMP32  stackless_PCIConfig_Write
+
+  ;
+  ; Load the SideBand Packet Register to generate the transaction
+  ;
+  mov  ebx, PCI_CFG OR (HOST_BRIDGE_PFA SHL 8) OR MESSAGE_BUS_CONTROL_REG  ; PCI Configuration address
+  mov  cl, (ALL_BYTE_EN SHL SB_BE_FIELD)    ; Set all Byte Enable bits
+  xchg  eax, ecx
+  JMP32  stackless_PCIConfig_Write
+  xchg  eax, ecx
+
+  mov  esp, esi        ; Restore the return address
+  RET32
+
+stackless_SideBand_Write ENDP
+
+;----------------------------------------------------------------------------
+;
+; Procedure:    stackless_PCIConfig_Write
+;
+; Input:        esp - return address
+;                eax - Data to write
+;                ebx - PCI Config Address
+;
+; Output:       None
+;
+; Destroys:
+;                dx
+;
+; Description:
+;        Perform a DWORD PCI Configuration write
+;
+;----------------------------------------------------------------------------
+stackless_PCIConfig_Write  PROC NEAR C PUBLIC
+
+  ;
+  ; Write the PCI Config Address to the address port
+  ;
+  xchg  eax, ebx
+  mov  dx, PCI_ADDRESS_PORT
+  out  dx, eax
+  xchg  eax, ebx
+
+  ;
+  ; Write the PCI DWORD Data to the data port
+  ;
+  mov  dx, PCI_DATA_PORT
+  out  dx, eax
+
+  RET32
+
+stackless_PCIConfig_Write ENDP
+
+;----------------------------------------------------------------------------
+;
+; Procedure:    stackless_PCIConfig_Read
+;
+; Input:        esp - return address
+;                ebx - PCI Config Address
+;
+; Output:       eax - Data read
+;
+; Destroys:
+;                eax
+;                dx
+;
+; Description:
+;        Perform a DWORD PCI Configuration read
+;
+;----------------------------------------------------------------------------
+stackless_PCIConfig_Read  PROC NEAR C PUBLIC
+
+  ;
+  ; Write the PCI Config Address to the address port
+  ;
+  xchg  eax, ebx
+  mov  dx, PCI_ADDRESS_PORT
+  out  dx, eax
+  xchg  eax, ebx
+
+  ;
+  ; Read the PCI DWORD Data from the data port
+  ;
+  mov  dx, PCI_DATA_PORT
+  in  eax, dx
+
+  RET32
+
+stackless_PCIConfig_Read 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 0xFFFF
+        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 0xFFFF
+        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 0xFFFF
+        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 0xFFFF
+        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 0xFFFF
+        DW      0                           ; base 0
+        DB      0Fh
+        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 0xFFFF
+        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
+
+END
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Platform.inc b/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Platform.inc
new file mode 100644
index 0000000000..d3ba5f0cea
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Platform.inc
@@ -0,0 +1,134 @@
+;
+; Copyright (c) 2013-2015 Intel Corporation.
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;------------------------------------------------------------------------------
+;
+; Module Name:
+;
+;   Platform.inc
+;
+; Abstract:
+;
+;   Quark A0 Platform Specific Definitions
+;
+;------------------------------------------------------------------------------
+
+JMP32 MACRO FunctionName
+  lea  esp, @F
+  jmp  FunctionName
+@@:
+ENDM
+
+RET32 MACRO
+    jmp    esp
+ENDM
+
+;
+; ROM/SPI/MEMORY Definitions
+;
+QUARK_DDR3_MEM_BASE_ADDRESS    EQU 000000000h    ; Memory Base Address = 0
+QUARK_MAX_DDR3_MEM_SIZE_BYTES    EQU 080000000h    ; DDR3 Memory Size = 2GB
+QUARK_ESRAM_MEM_SIZE_BYTES    EQU 000080000h    ; eSRAM Memory Size = 512K
+QUARK_STACK_SIZE_BYTES      EQU 008000h      ; Quark stack size = 32K
+
+;
+; RTC/CMOS definitions
+;
+RTC_INDEX      EQU 070h
+  NMI_DISABLE  EQU 080h    ; Bit7=1 disables NMI
+  NMI_ENABLE  EQU 000h    ; Bit7=0 disables NMI
+RTC_DATA      EQU 071h
+
+;
+; PCI Configuration definitions
+;
+PCI_CFG            EQU 1 SHL 01Fh  ; PCI configuration access mechanism
+PCI_ADDRESS_PORT  EQU 0CF8h
+PCI_DATA_PORT      EQU 0CFCh
+
+;
+; Quark PCI devices
+;
+HOST_BRIDGE_PFA        EQU 0000h          ; B0:D0:F0 (Host Bridge)
+ILB_PFA          EQU 00F8h          ; B0:D31:F0 (Legacy Block)
+
+;
+; ILB PCI Config Registers
+;
+BDE                              EQU 0D4h        ; BIOS Decode Enable register
+  DECODE_ALL_REGIONS_ENABLE      EQU 0FF000000h  ; Decode all BIOS decode ranges
+
+
+;
+; iLB Reset Register
+;
+ILB_RESET_REG      EQU 0CF9h
+  CF9_WARM_RESET    EQU  02h
+  CF9_COLD_RESET    EQU  08h
+
+;
+; Host Bridge PCI Config Registers
+;
+MESSAGE_BUS_CONTROL_REG                    EQU 0D0h  ; Message Bus Control Register
+  SB_OPCODE_FIELD                EQU 018h  ; Bit location of Opcode field
+    OPCODE_SIDEBAND_REG_READ    EQU 010h  ; Read opcode
+    OPCODE_SIDEBAND_REG_WRITE    EQU 011h  ; Write opcode
+    OPCODE_SIDEBAND_ALT_REG_READ  EQU 06h    ; Alternate Read opcode
+    OPCODE_SIDEBAND_ALT_REG_WRITE  EQU 07h    ; Alternate Write opcode
+    OPCODE_WARM_RESET_REQUEST    EQU 0F4h  ; Reset Warm
+    OPCODE_COLD_RESET_REQUEST    EQU 0F5h  ; Reset Cold
+  SB_PORT_FIELD                  EQU 010h  ; Bit location of Port ID field
+    MEMORY_ARBITER_PORT_ID                EQU 00h
+    HOST_BRIDGE_PORT_ID                EQU 03h
+    RMU_PORT_ID                EQU 04h
+    MEMORY_MANAGER_PORT_ID                EQU 05h
+    SOC_UNIT_PORT_ID              EQU  031h
+  SB_ADDR_FIELD                  EQU 008h  ; Bit location of Register field
+  SB_BE_FIELD                    EQU  004h  ; Bit location of Byte Enables field
+    ALL_BYTE_EN                  EQU  00Fh  ; All Byte Enables
+MESSAGE_DATA_REG                      EQU 0D4h  ; Message Data Register
+
+;
+; Memory Arbiter Config Registers
+;
+AEC_CTRL_OFFSET    EQU 00h
+
+;
+; Host Bridge Config Registers
+;
+HMISC2_OFFSET      EQU 03h
+  OR_PM_FIELD      EQU 010h
+    SMI_EN        EQU 1 SHL 13h
+
+HMBOUND_OFFSET    EQU 08h
+  HMBOUND_ADDRESS  EQU (QUARK_DDR3_MEM_BASE_ADDRESS + QUARK_MAX_DDR3_MEM_SIZE_BYTES + QUARK_ESRAM_MEM_SIZE_BYTES)
+  HMBOUND_LOCK  EQU 00000001h
+HECREG_OFFSET    EQU 09h
+  EC_BASE      EQU 0E0000000h
+  EC_ENABLE    EQU 01h
+HLEGACY_OFFSET    EQU 0Ah
+  NMI              EQU 1 SHL 0Eh  ; Pin 14
+  SMI              EQU 1 SHL 0Ch  ; Pin 12
+  INTR             EQU 1 SHL 0Ah  ; Pin 10
+
+
+;
+; Memory Manager Config Registers
+;
+ESRAMPGCTRL_BLOCK_OFFSET  EQU 082h
+  BLOCK_ENABLE_PG      EQU 010000000h
+BIMRVCTL_OFFSET        EQU 019h
+  ENABLE_IMR_INTERRUPT  EQU 080000000h
+
+;
+; SOC UNIT Debug Registers
+;
+CFGSTICKY_W1_OFFSET          EQU 050h
+  FORCE_COLD_RESET      EQU  00000001h
+CFGSTICKY_RW_OFFSET            EQU 051h
+  RESET_FOR_ESRAM_LOCK    EQU  00000020h
+  RESET_FOR_HMBOUND_LOCK    EQU  00000040h
+CFGNONSTICKY_W1_OFFSET        EQU 052h
+  FORCE_WARM_RESET      EQU  00000001h
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.c b/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.c
new file mode 100644
index 0000000000..9383d3dfbf
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.c
@@ -0,0 +1,207 @@
+/** @file
+Platform SEC Library for Quark.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#include <PiPei.h>
+
+#include <Ppi/SecPlatformInformation.h>
+#include <Ppi/TemporaryRamSupport.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/MtrrLib.h>
+
+/**
+
+  Entry point to the C language phase of SEC. After the SEC assembly
+  code has initialized some temporary memory and set up the stack,
+  the control is transferred to this function.
+
+  @param SizeOfRam           Size of the temporary memory available for use.
+  @param TempRamBase         Base address of temporary ram
+  @param BootFirmwareVolume  Base address of the Boot Firmware Volume.
+
+**/
+VOID
+EFIAPI
+SecStartup (
+  IN UINT32                   SizeOfRam,
+  IN UINT32                   TempRamBase,
+  IN VOID                     *BootFirmwareVolume
+  );
+
+/**
+  Auto-generated function that calls the library constructors for all of the module's
+  dependent libraries.  This function must be called by the SEC Core once a stack has
+  been established.
+
+**/
+VOID
+EFIAPI
+ProcessLibraryConstructorList (
+  VOID
+  );
+
+/**
+
+  Entry point to the C language phase of PlatformSecLib.  After the SEC assembly
+  code has initialized some temporary memory and set up the stack, control is
+  transferred to this function.
+
+**/
+VOID
+EFIAPI
+PlatformSecLibStartup (
+  VOID
+  )
+{
+  //
+  // Process all library constructor functions linked to SecCore.
+  // This function must be called before any library functions are called
+  //
+  ProcessLibraryConstructorList ();
+
+  //
+  // Set write back cache attribute for SPI FLASH
+  //
+  MtrrSetMemoryAttribute (
+    PcdGet32 (PcdFlashAreaBaseAddress),
+    PcdGet32 (PcdFlashAreaSize),
+    CacheWriteBack
+    );
+
+  //
+  // Set write back cache attribute for 512KB Embedded SRAM
+  //
+  MtrrSetMemoryAttribute (
+    PcdGet32 (PcdEsramStage1Base),
+    SIZE_512KB,
+    CacheWriteBack
+    );
+
+  //
+  // Pass control to SecCore module passing in the size of the temporary RAM in
+  // Embedded SRAM, the base address of the temporary RAM in Embedded SRAM, and
+  // the base address of the boot firmware volume.  The top 32KB of the 512 KB
+  // embedded SRAM are used as temporary RAM.
+  //
+  SecStartup (
+    SIZE_32KB,
+    PcdGet32 (PcdEsramStage1Base) + SIZE_512KB - SIZE_32KB,
+    (VOID *)(UINTN)PcdGet32 (PcdFlashFvRecoveryBase)
+    );
+}
+
+/**
+  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 and PPI list that is
+  passed to PEI Core.
+
+  @param  SecCoreData           The same parameter as passing to PEI core. It
+                                could be overridden by this function.
+  @param  PpiList               The default PPI list passed from generic SEC
+                                part.
+
+  @return The final PPI list that platform wishes to passed to PEI core.
+
+**/
+EFI_PEI_PPI_DESCRIPTOR *
+EFIAPI
+SecPlatformMain (
+  IN OUT   EFI_SEC_PEI_HAND_OFF        *SecCoreData,
+  IN       EFI_PEI_PPI_DESCRIPTOR      *PpiList
+  )
+{
+  return NULL;
+}
+
+/**
+  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;
+  EFI_HOB_GUID_TYPE  *GuidHob;
+  UINT32             *TopOfStack;
+
+  //
+  // Top of the stack is the top of the 512KB Embedded SRAM region
+  //
+  TopOfStack = (UINT32 *)(UINTN)(PcdGet32 (PcdEsramStage1Base) + SIZE_512KB);
+
+  GuidHob = GetFirstGuidHob (&gEfiSecPlatformInformationPpiGuid);
+  if (GuidHob != NULL) {
+    Size = GET_GUID_HOB_DATA_SIZE (GuidHob);
+    BIST = GET_GUID_HOB_DATA (GuidHob);
+  } else {
+    //
+    // 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.
+    //
+    Count = *(TopOfStack - 1);
+    Size  = Count * sizeof (IA32_HANDOFF_STATUS);
+    BIST  = (UINT32 *) ((UINT32) TopOfStack - sizeof (UINT32) - Size);
+
+    //
+    // Copy Data from Stack to Hob to avoid data is lost after memory is ready.
+    //
+    BuildGuidDataHob (
+      &gEfiSecPlatformInformationPpiGuid,
+      BIST,
+      (UINTN)Size
+    );
+    GuidHob = GetFirstGuidHob (&gEfiSecPlatformInformationPpiGuid);
+    Size = GET_GUID_HOB_DATA_SIZE (GuidHob);
+    BIST = GET_GUID_HOB_DATA (GuidHob);
+  }
+
+  if ((*StructureSize) < (UINT64) Size) {
+    *StructureSize = Size;
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  *StructureSize  = Size;
+  CopyMem (PlatformInformationRecord, BIST, Size);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This interface disables temporary memory in SEC Phase.
+**/
+VOID
+EFIAPI
+SecPlatformDisableTemporaryMemory (
+  VOID
+  )
+{
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.inf b/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.inf
new file mode 100644
index 0000000000..a246a38564
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.inf
@@ -0,0 +1,54 @@
+#/** @file
+# Platform SEC Library for Quark.
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformSecLib
+  FILE_GUID                      = 8DE4221F-A9CC-4c78-85B9-D863681F0C01
+  MODULE_TYPE                    = SEC
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformSecLib
+  MODULE_UNI_FILE                = PlatformSecLibModStrs.uni
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32
+#
+
+[Sources]
+  PlatformSecLib.c
+
+[Sources.IA32]
+  Ia32/Flat32.asm | MSFT
+  Ia32/Flat32.asm | INTEL
+  Ia32/Flat32.S   | GCC
+
+[Packages]
+  MdePkg/MdePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  BaseLib
+  BaseMemoryLib
+  PciLib
+  PcdLib
+  HobLib
+  MtrrLib
+
+[Pcd]
+  gQuarkPlatformTokenSpaceGuid.PcdEsramStage1Base         ## CONSUMES
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoveryBase     ## CONSUMES
+  gQuarkPlatformTokenSpaceGuid.PcdFlashAreaBaseAddress    ## CONSUMES
+  gQuarkPlatformTokenSpaceGuid.PcdFlashAreaSize           ## CONSUMES
+
+[Ppis]
+  gEfiSecPlatformInformationPpiGuid   ## UNDEFINED # it is used as GUIDED HOB
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLibModStrs.uni b/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLibModStrs.uni
new file mode 100644
index 0000000000..fb16f0f320
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLibModStrs.uni
@@ -0,0 +1,18 @@
+// /** @file
+// PlatformSecLib Localized Abstract and Description Content
+//
+// Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT
+#language en-US
+"SEC Platform Library "
+
+#string STR_MODULE_DESCRIPTION
+#language en-US
+"Provides a platform-specific function to be used during the SEC stage of POST. "
+
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecureLib.c b/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecureLib.c
new file mode 100644
index 0000000000..8105a11d52
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecureLib.c
@@ -0,0 +1,164 @@
+/** @file
+Provides a secure platform-specific method to detect physically present user.
+
+Copyright (c) 2013 - 2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <Library/PlatformHelperLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/I2cLib.h>
+
+#include <PlatformBoards.h>
+#include <Pcal9555.h>
+#include <QNCAccess.h>
+
+//
+// Global variable to cache pointer to I2C protocol.
+//
+EFI_PLATFORM_TYPE mPlatformType = TypeUnknown;
+
+BOOLEAN
+CheckResetButtonState (
+  VOID
+  )
+{
+  EFI_STATUS              Status;
+  EFI_I2C_DEVICE_ADDRESS  I2CSlaveAddress;
+  UINTN                   Length;
+  UINTN                   ReadLength;
+  UINT8                   Buffer[2];
+
+  DEBUG ((EFI_D_INFO, "CheckResetButtonState(): mPlatformType == %d\n", mPlatformType));
+  if (mPlatformType == GalileoGen2) {
+    //
+    // Read state of Reset Button - EXP2.P1_7
+    // This GPIO is pulled high when the button is not pressed
+    // This GPIO reads low when button is pressed
+    //
+    return PlatformPcal9555GpioGetState (
+      GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR,  // IO Expander 2.
+      15                                    // P1-7.
+      );
+  }
+  if (mPlatformType == Galileo) {
+    //
+    // Detect the I2C Slave Address of the GPIO Expander
+    //
+    if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) {
+      I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2HI_7BIT_SLAVE_ADDR;
+    } else {
+      I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2LO_7BIT_SLAVE_ADDR;
+    }
+    DEBUG ((EFI_D_INFO, "Galileo GPIO Expender Slave Address = %02x\n", I2CSlaveAddress.I2CDeviceAddress));
+
+    //
+    // Read state of RESET_N_SHLD (GPORT5_BIT0)
+    //
+    Buffer[1] = 5;
+    Length = 1;
+    ReadLength = 1;
+    Status = I2cReadMultipleByte (
+               I2CSlaveAddress,
+               EfiI2CSevenBitAddrMode,
+               &Length,
+               &ReadLength,
+               &Buffer[1]
+               );
+    ASSERT_EFI_ERROR (Status);
+
+    //
+    // Return the state of GPORT5_BIT0
+    //
+    return ((Buffer[1] & BIT0) != 0);
+  }
+  return TRUE;
+}
+
+/**
+
+  This function provides a platform-specific method to detect whether the platform
+  is operating by a physically present user.
+
+  Programmatic changing of platform security policy (such as disable Secure Boot,
+  or switch between Standard/Custom Secure Boot mode) MUST NOT be possible during
+  Boot Services or after exiting EFI Boot Services. Only a physically present user
+  is allowed to perform these operations.
+
+  NOTE THAT: This function cannot depend on any EFI Variable Service since they are
+  not available when this function is called in AuthenticateVariable driver.
+
+  @retval  TRUE       The platform is operated by a physically present user.
+  @retval  FALSE      The platform is NOT operated by a physically present user.
+
+**/
+BOOLEAN
+EFIAPI
+UserPhysicalPresent (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // If user has already been detected as present, then return TRUE
+  //
+  if (PcdGetBool (PcdUserIsPhysicallyPresent)) {
+    return TRUE;
+  }
+
+  //
+  // Check to see if user is present now
+  //
+  if (CheckResetButtonState ()) {
+    //
+    // User is still not present, then return FALSE
+    //
+    return FALSE;
+  }
+
+  //
+  // User has gone from not present to present state, so set
+  // PcdUserIsPhysicallyPresent to TRUE
+  //
+  Status = PcdSetBoolS (PcdUserIsPhysicallyPresent, TRUE);
+  ASSERT_EFI_ERROR (Status);
+
+  return TRUE;
+}
+
+/**
+  Determines if a user is physically present by reading the reset button state.
+
+  @param  ImageHandle  The image handle of this driver.
+  @param  SystemTable  A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS   Install the Secure Boot Helper Protocol successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformSecureLibInitialize (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // Get the platform type
+  //
+  mPlatformType = (EFI_PLATFORM_TYPE)PcdGet16 (PcdPlatformType);
+
+  //
+  // Read the state of the reset button when the library is initialized
+  //
+  Status = PcdSetBoolS (PcdUserIsPhysicallyPresent, !CheckResetButtonState ());
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecureLib.inf b/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
new file mode 100644
index 0000000000..ef7b21faf5
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
@@ -0,0 +1,41 @@
+## @file
+# Provides a secure platform-specific method to detect physically present user.
+#
+# Copyright (c) 2013 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformSecureLib
+  FILE_GUID                      = 38BB5221-F685-469f-846E-F1C508FC5F4A
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformSecureLib|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_DRIVER
+  CONSTRUCTOR                    = PlatformSecureLibInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32
+#
+
+[Sources]
+  PlatformSecureLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  PlatformHelperLib
+  UefiBootServicesTableLib
+  I2cLib
+
+[Pcd]
+  gQuarkPlatformTokenSpaceGuid.PcdPlatformType
+  gQuarkPlatformTokenSpaceGuid.PcdUserIsPhysicallyPresent
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/TisPc.c b/Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/TisPc.c
new file mode 100644
index 0000000000..dcec86aa83
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/TisPc.c
@@ -0,0 +1,408 @@
+/** @file
+  Basic TIS (TPM Interface Specification) functions for Atmel I2C TPM.
+
+  Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/Tpm12DeviceLib.h>
+#include <Library/BaseLib.h>
+#include <Library/TimerLib.h>
+#include <Library/DebugLib.h>
+#include <Library/I2cLib.h>
+
+//
+// Atmel I2C TPM slave address
+//
+#define ATMEL_I2C_TPM_SLAVE_ADDRESS      0x29
+
+//
+// Maximum I2C transfer size for Atmel I2C TPM
+//
+#define ATMEL_I2C_TPM_MAX_TRANSFER_SIZE  0x10
+
+//
+// Default TimeOut values in microseconds
+//
+#define TIS_TIMEOUT_A  ( 750 * 1000)  // 750ms
+#define TIS_TIMEOUT_B  (2000 * 1000)  // 2s
+#define TIS_TIMEOUT_C  ( 750 * 1000)  // 750ms
+#define TIS_TIMEOUT_D  ( 750 * 1000)  // 750ms
+
+/**
+  Send command to Atmel I2c TPM breaking request up into multiple I2C transfers
+  if required.
+
+  @param[in] Buffer  Pointer to TPM command data.
+  @param[in] Length  Number of bytes of TPM command data.
+
+  @retval EFI_SUCCESS    TPM command sent.
+  @retval EFI_NOT_FOUND  TPM chip doesn't exit.
+  @retval EFI_TIMEOUT    Can't get the TPM control in time.
+**/
+EFI_STATUS
+WriteTpmBufferMultiple (
+  IN UINT8  *Buffer,
+  IN UINTN  Length
+  )
+{
+  EFI_STATUS              Status;
+  EFI_I2C_DEVICE_ADDRESS  I2CDeviceAddr;
+  UINTN                   Index;
+  UINTN                   PartialLength;
+
+  Status = EFI_SUCCESS;
+
+  I2CDeviceAddr.I2CDeviceAddress = ATMEL_I2C_TPM_SLAVE_ADDRESS;
+
+  DEBUG ((EFI_D_VERBOSE, "WriteTpmBufferMultiple: Addr=%02x  Length=%02x\n", I2CDeviceAddr.I2CDeviceAddress, Length));
+
+  for (PartialLength = 0; Length > 0; Length -= PartialLength, Buffer += PartialLength) {
+    //
+    // Write data to TPM.
+    //
+    PartialLength = MIN (Length, ATMEL_I2C_TPM_MAX_TRANSFER_SIZE);
+    Status = I2cWriteMultipleByte (
+      I2CDeviceAddr,
+      EfiI2CSevenBitAddrMode,
+      &PartialLength,
+      Buffer
+      );
+    DEBUG ((EFI_D_VERBOSE, "  "));
+    for (Index = 0; Index < PartialLength; Index++) {
+      DEBUG ((EFI_D_VERBOSE, "%02x ", Buffer[Index]));
+    }
+    DEBUG ((EFI_D_VERBOSE, "\n"));
+    if (EFI_ERROR (Status)) {
+      DEBUG ((EFI_D_VERBOSE, "  Status = %r\n", Status));
+      return Status;
+    }
+  }
+
+  DEBUG ((EFI_D_VERBOSE, "  Status = %r\n", Status));
+  return Status;
+}
+
+/**
+  Receive a response to a command from Atmel I2c TPM breaking response into
+  multiple I2C transfers if required.
+
+  @param[out] Buffer  Pointer to TPM response data.
+  @param[in]  Length  Maximum number of bytes to receive.
+
+  @retval EFI_SUCCESS    TPM response received.
+  @retval EFI_NOT_FOUND  TPM chip doesn't exit.
+  @retval EFI_TIMEOUT    Can't get the TPM control in time.
+**/
+EFI_STATUS
+ReadTpmBufferMultiple (
+  OUT UINT8  *Buffer,
+  IN  UINTN  Length
+  )
+{
+  EFI_STATUS              Status;
+  EFI_I2C_DEVICE_ADDRESS  I2CDeviceAddr;
+  UINTN                   WriteLength;
+  UINTN                   Index;
+  UINTN                   PartialLength;
+
+  Status = EFI_SUCCESS;
+
+  I2CDeviceAddr.I2CDeviceAddress = ATMEL_I2C_TPM_SLAVE_ADDRESS;
+  WriteLength = 0;
+
+  DEBUG ((EFI_D_VERBOSE, "ReadTpmBufferMultiple: Addr=%02x  Length=%02x\n", I2CDeviceAddr.I2CDeviceAddress, Length));
+
+  for (PartialLength = 0; Length > 0; Length -= PartialLength, Buffer += PartialLength) {
+    //
+    // Read data from TPM.
+    //
+    PartialLength = MIN (Length, ATMEL_I2C_TPM_MAX_TRANSFER_SIZE);
+    Status = I2cReadMultipleByte (
+      I2CDeviceAddr,
+      EfiI2CSevenBitAddrMode,
+      &WriteLength,
+      &PartialLength,
+      Buffer
+      );
+    if (!EFI_ERROR (Status)) {
+      DEBUG ((EFI_D_VERBOSE, "  "));
+      for (Index = 0; Index < PartialLength; Index++) {
+        DEBUG ((EFI_D_VERBOSE, "%02x ", Buffer[Index]));
+      }
+      DEBUG ((EFI_D_VERBOSE, "\n"));
+    }
+    if (EFI_ERROR (Status)) {
+      DEBUG ((EFI_D_VERBOSE, "  Status = %r\n", Status));
+      return Status;
+    }
+  }
+
+  DEBUG ((EFI_D_VERBOSE, "  Status = %r\n", Status));
+  return Status;
+}
+
+/**
+  This service requests use TPM12.
+
+  @retval EFI_SUCCESS       Get the control of TPM12 chip.
+  @retval EFI_NOT_FOUND     TPM12 not found.
+  @retval EFI_DEVICE_ERROR  Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+Tpm12RequestUseTpm (
+  VOID
+  )
+{
+  EFI_STATUS                 Status;
+  UINT8                      Data;
+  UINT64                     Current;
+  UINT64                     Previous;
+  UINT64                     Total;
+  UINT64                     Start;
+  UINT64                     End;
+  UINT64                     Timeout;
+  INT64                      Cycle;
+  INT64                      Delta;
+
+  //
+  // Get the current timer value
+  //
+  Current = GetPerformanceCounter();
+
+  //
+  // Initialize local variables
+  //
+  Start = 0;
+  End   = 0;
+  Total = 0;
+
+  //
+  // Retrieve the performance counter properties and compute the number of
+  // performance counter ticks required to reach the maximum TIS timeout of
+  // TIS_TIMEOUT_A.  TIS_TIMEOUT_A is in microseconds.
+  //
+  Timeout = DivU64x32 (
+              MultU64x32 (
+                GetPerformanceCounterProperties (&Start, &End),
+                TIS_TIMEOUT_A
+                ),
+              1000000
+              );
+  Cycle = End - Start;
+  if (Cycle < 0) {
+    Cycle = -Cycle;
+  }
+  Cycle++;
+
+  //
+  // Attempt to read a byte from the Atmel I2C TPM
+  //
+  do {
+    Status = ReadTpmBufferMultiple (&Data, sizeof(Data));
+
+    Previous = Current;
+    Current  = GetPerformanceCounter();
+    Delta = (INT64) (Current - Previous);
+    if (Start > End) {
+      Delta = -Delta;
+    }
+    if (Delta < 0) {
+      Delta += Cycle;
+    }
+    Total += Delta;
+    if (Total >= Timeout) {
+      Status = EFI_TIMEOUT;
+      DEBUG ((EFI_D_ERROR, "Atmel I2C TPM failed to read: %r\n", Status));
+      return Status;
+    }
+  } while (EFI_ERROR (Status));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This service enables the sending of commands to the TPM12.
+
+  @param[in]     InputParameterBlockSize   Size of the TPM12 input parameter block.
+  @param[in]     InputParameterBlock       Pointer to the TPM12 input parameter block.
+  @param[in,out] OutputParameterBlockSize  Size of the TPM12 output parameter block.
+  @param[in]     OutputParameterBlock      Pointer to the TPM12 output parameter block.
+
+  @retval EFI_SUCCESS           The command byte stream was successfully sent to
+                                the device and a response was successfully received.
+  @retval EFI_DEVICE_ERROR      The command was not successfully sent to the
+                                device or a response was not successfully received
+                                from the device.
+  @retval EFI_BUFFER_TOO_SMALL  The output parameter block is too small.
+**/
+EFI_STATUS
+EFIAPI
+Tpm12SubmitCommand (
+  IN UINT32      InputParameterBlockSize,
+  IN UINT8       *InputParameterBlock,
+  IN OUT UINT32  *OutputParameterBlockSize,
+  IN UINT8       *OutputParameterBlock
+  )
+{
+  EFI_STATUS           Status;
+  UINT32               TpmOutSize;
+  TPM_RSP_COMMAND_HDR  *ResponseHeader;
+  UINT64               Current;
+  UINT64               Previous;
+  UINT64               Total;
+  UINT64               Start;
+  UINT64               End;
+  UINT64               Timeout;
+  INT64                Cycle;
+  INT64                Delta;
+
+  //
+  // Initialize local variables
+  //
+  Start   = 0;
+  End     = 0;
+  Total   = 0;
+
+  //
+  // Make sure response buffer is big enough to hold a response header
+  //
+  if (*OutputParameterBlockSize < sizeof (TPM_RSP_COMMAND_HDR)) {
+    Status = EFI_BUFFER_TOO_SMALL;
+    goto Done;
+  }
+
+  //
+  // Get the current timer value
+  //
+  Current = GetPerformanceCounter();
+
+  //
+  // Retrieve the performance counter properties and compute the number of
+  // performance counter ticks required to reach the maximum TIS timeout of
+  // TIS_TIMEOUT_A.  TIS_TIMEOUT_A is in microseconds.
+  //
+  Timeout = DivU64x32 (
+              MultU64x32 (
+                GetPerformanceCounterProperties (&Start, &End),
+                TIS_TIMEOUT_A
+                ),
+              1000000
+              );
+  Cycle = End - Start;
+  if (Cycle < 0) {
+    Cycle = -Cycle;
+  }
+  Cycle++;
+
+  //
+  // Send command
+  //
+  do {
+    Status = WriteTpmBufferMultiple (InputParameterBlock, InputParameterBlockSize);
+
+    Previous = Current;
+    Current  = GetPerformanceCounter();
+    Delta = (INT64) (Current - Previous);
+    if (Start > End) {
+      Delta = -Delta;
+    }
+    if (Delta < 0) {
+      Delta += Cycle;
+    }
+    Total += Delta;
+    if (Total >= Timeout) {
+      Status = EFI_TIMEOUT;
+      goto Done;
+    }
+  } while (EFI_ERROR (Status));
+
+  //
+  // Receive response header
+  //
+  do {
+    Status = ReadTpmBufferMultiple (OutputParameterBlock, sizeof (TPM_RSP_COMMAND_HDR));
+
+    Previous = Current;
+    Current  = GetPerformanceCounter();
+    Delta = (INT64) (Current - Previous);
+    if (Start > End) {
+      Delta = -Delta;
+    }
+    if (Delta < 0) {
+      Delta += Cycle;
+    }
+    Total += Delta;
+    if (Total >= Timeout) {
+      Status = EFI_TIMEOUT;
+      goto Done;
+    }
+  } while (EFI_ERROR (Status));
+
+  //
+  // Check the response data header (tag, parasize and returncode)
+  //
+  ResponseHeader = (TPM_RSP_COMMAND_HDR *)OutputParameterBlock;
+  if (SwapBytes16 (ReadUnaligned16 (&ResponseHeader->tag)) != TPM_TAG_RSP_COMMAND) {
+    Status = EFI_DEVICE_ERROR;
+    goto Done;
+  }
+
+  TpmOutSize = SwapBytes32 (ReadUnaligned32 (&ResponseHeader->paramSize));
+  if (TpmOutSize == sizeof (TPM_RSP_COMMAND_HDR)) {
+    *OutputParameterBlockSize = TpmOutSize;
+    Status = EFI_SUCCESS;
+    goto Done;
+  }
+  if (TpmOutSize < sizeof (TPM_RSP_COMMAND_HDR)) {
+    Status = EFI_DEVICE_ERROR;
+    goto Done;
+  }
+  if (*OutputParameterBlockSize < TpmOutSize) {
+    Status = EFI_BUFFER_TOO_SMALL;
+    goto Done;
+  }
+  *OutputParameterBlockSize = TpmOutSize;
+
+  //
+  // Receive the remaining data in the response header
+  //
+  do {
+    Status = ReadTpmBufferMultiple (
+               OutputParameterBlock + sizeof (TPM_RSP_COMMAND_HDR),
+               TpmOutSize - sizeof (TPM_RSP_COMMAND_HDR)
+               );
+
+    Previous = Current;
+    Current  = GetPerformanceCounter();
+    Delta = (INT64) (Current - Previous);
+    if (Start > End) {
+      Delta = -Delta;
+    }
+    if (Delta < 0) {
+      Delta += Cycle;
+    }
+    Total += Delta;
+    if (Total >= Timeout) {
+      Status = EFI_TIMEOUT;
+      goto Done;
+    }
+  } while (EFI_ERROR (Status));
+
+Done:
+  DEBUG ((
+    EFI_D_VERBOSE,
+    "Tpm12SubmitCommand() Status = %r  Time = %ld ms\n",
+    Status,
+    DivU64x64Remainder (
+      MultU64x32 (Total, 1000),
+      GetPerformanceCounterProperties (NULL, NULL),
+      NULL
+      )
+    ));
+
+  return Status;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.inf b/Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.inf
new file mode 100644
index 0000000000..99117064bf
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.inf
@@ -0,0 +1,39 @@
+## @file
+#  Provides some common functions for the TCG feature for Atmel I2C TPM.
+#
+#  This instance provides basic TPM Interface Specification (TIS) functions
+#  or Atmel I2C TPM.
+#
+# Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = Tpm12DeviceLibAtmelI2c
+  MODULE_UNI_FILE                = Tpm12DeviceLibAtmelI2c.uni
+  FILE_GUID                      = A0C0B7EF-99FF-417F-8B9F-5AD4701D90D6
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = Tpm12DeviceLib|PEIM DXE_DRIVER DXE_SMM_DRIVER UEFI_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  TisPc.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  TimerLib
+  DebugLib
+  I2cLib
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.uni b/Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.uni
new file mode 100644
index 0000000000..7eb8b1d945
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.uni
@@ -0,0 +1,16 @@
+// /** @file
+// Provides some common functions for the TCG feature for Atmel I2C TPM.
+//
+// This instance provides basic TPM Interface Specification (TIS) functions
+// for Atmel I2C TPM.
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT             #language en-US "Provides some common functions for the TCG feature for Atmel I2C TPM."
+
+#string STR_MODULE_DESCRIPTION          #language en-US "This instance provides basic TPM Interface Specification (TIS) functions for Atmel I2C TPM."
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/TisPc.c b/Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/TisPc.c
new file mode 100644
index 0000000000..c7862a0def
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/TisPc.c
@@ -0,0 +1,612 @@
+/** @file
+  Basic TIS (TPM Interface Specification) functions for Infineon I2C TPM.
+
+  Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/Tpm12DeviceLib.h>
+#include <Library/BaseLib.h>
+#include <Library/TimerLib.h>
+#include <Library/DebugLib.h>
+#include <Library/I2cLib.h>
+
+//
+// Default TPM (Infineon SLB9645) I2C Slave Device Address on Crosshill board.
+//
+#define TPM_I2C_SLAVE_DEVICE_ADDRESS              0x20
+
+//
+// Default Infineon SLB9645 TPM I2C mapped registers (SLB9645 I2C Comm. Protocol Application Note).
+//
+#define INFINEON_TPM_ACCESS_0_ADDRESS_DEFAULT     0x0
+#define INFINEON_TPM_STS_0_ADDRESS_DEFAULT        0x01
+#define INFINEON_TPM_BURST0_COUNT_0_DEFAULT       0x02
+#define INFINEON_TPM_BURST1_COUNT_0_DEFAULT       0x03
+#define INFINEON_TPM_DATA_FIFO_0_ADDRESS_DEFAULT  0x05
+#define INFINEON_TPM_DID_VID_0_DEFAULT            0x09
+
+//
+// Max. retry count for read transfers (as recommended by Infineon).
+//
+#define READ_RETRY  3
+
+//
+// Guard time of 250us between I2C read and next I2C write transfer (as recommended by Infineon).
+//
+#define GUARD_TIME  250
+
+//
+// Define bits of ACCESS and STATUS registers
+//
+
+///
+/// This bit is a 1 to indicate that the other bits in this register are valid.
+///
+#define TIS_PC_VALID                BIT7
+///
+/// Indicate that this locality is active.
+///
+#define TIS_PC_ACC_ACTIVE           BIT5
+///
+/// Set to 1 to indicate that this locality had the TPM taken away while
+/// this locality had the TIS_PC_ACC_ACTIVE bit set.
+///
+#define TIS_PC_ACC_SEIZED           BIT4
+///
+/// Set to 1 to indicate that TPM MUST reset the
+/// TIS_PC_ACC_ACTIVE bit and remove ownership for localities less than the
+/// locality that is writing this bit.
+///
+#define TIS_PC_ACC_SEIZE            BIT3
+///
+/// When this bit is 1, another locality is requesting usage of the TPM.
+///
+#define TIS_PC_ACC_PENDIND          BIT2
+///
+/// Set to 1 to indicate that this locality is requesting to use TPM.
+///
+#define TIS_PC_ACC_RQUUSE           BIT1
+///
+/// A value of 1 indicates that a T/OS has not been established on the platform
+///
+#define TIS_PC_ACC_ESTABLISH        BIT0
+
+///
+/// When this bit is 1, TPM is in the Ready state,
+/// indicating it is ready to receive a new command.
+///
+#define TIS_PC_STS_READY            BIT6
+///
+/// Write a 1 to this bit to cause the TPM to execute that command.
+///
+#define TIS_PC_STS_GO               BIT5
+///
+/// This bit indicates that the TPM has data available as a response.
+///
+#define TIS_PC_STS_DATA             BIT4
+///
+/// The TPM sets this bit to a value of 1 when it expects another byte of data for a command.
+///
+#define TIS_PC_STS_EXPECT           BIT3
+///
+/// Writes a 1 to this bit to force the TPM to re-send the response.
+///
+#define TIS_PC_STS_RETRY            BIT1
+
+//
+// Default TimeOut values in microseconds
+//
+#define TIS_TIMEOUT_A               (750  * 1000)  // 750ms
+#define TIS_TIMEOUT_B               (2000 * 1000)  // 2s
+#define TIS_TIMEOUT_C               (750  * 1000)  // 750ms
+#define TIS_TIMEOUT_D               (750  * 1000)  // 750ms
+
+//
+// Global variable to indicate if TPM I2C Read Transfer has previously occurred.
+// NOTE: Given the GUARD_TIME requirement (TpmAccess.h), if this library loaded
+// by PEI Drivers this global variable required to be resident in R/W memory
+//
+BOOLEAN mI2CPrevReadTransfer = FALSE;
+
+/**
+  Writes single byte data to TPM specified by I2C register address.
+
+  @param[in]  TpmAddress  The register to write.
+  @param[in]  Data        The data to write to the register.
+
+**/
+VOID
+TpmWriteByte (
+  IN UINTN  TpmAddress,
+  IN UINT8  Data
+  )
+{
+  EFI_STATUS              Status;
+  UINTN                   WriteLength;
+  UINT8                   WriteData[2];
+  EFI_I2C_DEVICE_ADDRESS  I2CDeviceAddr;
+
+  //
+  // Setup I2C Slave device address and address mode (7-bit).
+  //
+  I2CDeviceAddr.I2CDeviceAddress = TPM_I2C_SLAVE_DEVICE_ADDRESS;
+
+  //
+  // As recommended by Infineon (SLB9645 I2C Communication protocol application
+  // note revision 1.0) wait 250 microseconds between a read and a write transfer.
+  //
+  if (mI2CPrevReadTransfer) {
+    MicroSecondDelay (GUARD_TIME);
+  }
+
+  //
+  // Write to TPM register.
+  //
+  WriteLength = 2;
+  WriteData[0] = (UINT8)TpmAddress;
+  WriteData[1] = Data;
+
+  Status = I2cWriteMultipleByte (
+             I2CDeviceAddr,
+             EfiI2CSevenBitAddrMode,
+             &WriteLength,
+             &WriteData
+             );
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "TpmWriteByte(): I2C Write to TPM address %0x failed (%r)\n", TpmAddress, Status));
+    ASSERT (FALSE);  // Writes to TPM should always succeed.
+  }
+
+  mI2CPrevReadTransfer = FALSE;
+}
+
+/**
+  Reads single byte data from TPM specified by I2C register address.
+
+  Due to stability issues when using I2C combined write/read transfers (with
+  RESTART) to TPM (specifically read from status register), a single write is
+  performed followed by single read (with STOP condition in between).
+
+  @param[in] TpmAddress  Address of register  to read.
+
+  @return  The value register read.
+
+**/
+UINT8
+TpmReadByte (
+  IN UINTN  TpmAddress
+  )
+{
+  UINT8                   Data[1];
+  UINT8                   ReadData;
+  UINT8                   ReadCount;
+
+  EFI_I2C_DEVICE_ADDRESS  I2CDeviceAddr;
+  EFI_I2C_ADDR_MODE       I2CAddrMode;
+
+  EFI_STATUS              Status;
+
+  Status = EFI_SUCCESS;
+  ReadData  = 0xFF;
+  ReadCount = 0;
+
+  //
+  // Locate I2C protocol for TPM I2C access.
+  //
+  I2CDeviceAddr.I2CDeviceAddress = TPM_I2C_SLAVE_DEVICE_ADDRESS;
+  I2CAddrMode = EfiI2CSevenBitAddrMode;
+
+  //
+  // As recommended by Infineon (SLB9645 I2C Communication protocol application
+  // note revision 1.0) retry up to 3 times if TPM status, access or burst count
+  // registers return 0xFF.
+  //
+  while ((ReadData == 0xFF) && (ReadCount < READ_RETRY)) {
+    //
+    // As recommended by Infineon (SLB9645 I2C Communication protocol application
+    // note revision 1.0) wait 250 microseconds between a read and a write transfer.
+    //
+    if (mI2CPrevReadTransfer) {
+      MicroSecondDelay (GUARD_TIME);
+    }
+
+    //
+    // Write address to TPM.
+    //
+    Data[0] = (UINT8)TpmAddress;
+    Status = I2cWriteByte (
+               I2CDeviceAddr,
+               I2CAddrMode,
+               &Data
+               );
+
+    if (EFI_ERROR(Status)) {
+      DEBUG ((EFI_D_INFO, "TpmReadByte(): write to TPM address %0x failed (%r)\n", TpmAddress, Status));
+    }
+
+    mI2CPrevReadTransfer = FALSE;
+
+    //
+    // Read data from TPM.
+    //
+    Data[0] = (UINT8)TpmAddress;
+    Status = I2cReadByte (
+               I2CDeviceAddr,
+               I2CAddrMode,
+               &Data
+               );
+
+    if (EFI_ERROR(Status)) {
+      DEBUG ((EFI_D_INFO, "TpmReadByte(): read from TPM address %0x failed (%r)\n", TpmAddress, Status));
+      ReadData = 0xFF;
+    } else {
+      ReadData = Data[0];
+    }
+
+    //
+    // Only need to retry 3 times for TPM status, access, and burst count registers.
+    // If read transfer is to TPM Data FIFO, do not retry, exit loop.
+    //
+    if (TpmAddress == INFINEON_TPM_DATA_FIFO_0_ADDRESS_DEFAULT) {
+      ReadCount = READ_RETRY;
+    } else {
+      ReadCount++;
+    }
+
+    mI2CPrevReadTransfer = TRUE;
+  }
+
+  if (EFI_ERROR(Status)) {
+    //
+    //  Only reads to access register allowed to fail.
+    //
+    if (TpmAddress != INFINEON_TPM_ACCESS_0_ADDRESS_DEFAULT) {
+      DEBUG ((EFI_D_ERROR, "TpmReadByte(): read from TPM address %0x failed\n", TpmAddress));
+      ASSERT_EFI_ERROR (Status);
+    }
+  }
+  return ReadData;
+}
+
+/**
+  Check whether the value of a TPM chip register satisfies the input BIT setting.
+
+  @param[in] Register  TPM register to be checked.
+  @param[in] BitSet    Check these data bits are set.
+  @param[in] BitClear  Check these data bits are clear.
+  @param[in] TimeOut   The max wait time (unit MicroSecond) when checking register.
+
+  @retval EFI_SUCCESS  The register satisfies the check bit.
+  @retval EFI_TIMEOUT  The register can't run into the expected status in time.
+**/
+EFI_STATUS
+TisPcWaitRegisterBits (
+  IN UINTN   Register,
+  IN UINT8   BitSet,
+  IN UINT8   BitClear,
+  IN UINT32  TimeOut
+  )
+{
+  UINT8   RegRead;
+  UINT32  WaitTime;
+
+  for (WaitTime = 0; WaitTime < TimeOut; WaitTime += 30){
+    RegRead = TpmReadByte (Register);
+    if ((RegRead & BitSet) == BitSet && (RegRead & BitClear) == 0)
+      return EFI_SUCCESS;
+    MicroSecondDelay (30);
+  }
+  return EFI_TIMEOUT;
+}
+
+/**
+  Get BurstCount by reading the burstCount field of a TIS register
+  in the time of default TIS_TIMEOUT_D.
+
+  @param[out] BurstCount  Pointer to a buffer to store the got BurstConut.
+
+  @retval EFI_SUCCESS            Get BurstCount.
+  @retval EFI_INVALID_PARAMETER  BurstCount is NULL.
+  @retval EFI_TIMEOUT            BurstCount can't be got in time.
+**/
+EFI_STATUS
+TisPcReadBurstCount (
+  OUT UINT16  *BurstCount
+  )
+{
+  UINT32  WaitTime;
+  UINT8   DataByte0;
+  UINT8   DataByte1;
+
+  if (BurstCount == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  WaitTime = 0;
+  do {
+    //
+    // BurstCount is UINT16, but it is not 2bytes aligned,
+    // so it needs to use TpmReadByte to read two times
+    //
+    DataByte0   = TpmReadByte (INFINEON_TPM_BURST0_COUNT_0_DEFAULT);
+    DataByte1   = TpmReadByte (INFINEON_TPM_BURST1_COUNT_0_DEFAULT);
+    *BurstCount = (UINT16)((DataByte1 << 8) + DataByte0);
+    if (*BurstCount != 0) {
+      return EFI_SUCCESS;
+    }
+    MicroSecondDelay (30);
+    WaitTime += 30;
+  } while (WaitTime < TIS_TIMEOUT_D);
+
+  return EFI_TIMEOUT;
+}
+
+/**
+  Set TPM chip to ready state by sending ready command TIS_PC_STS_READY
+  to Status Register in time.
+
+  @retval EFI_SUCCESS  TPM chip enters into ready state.
+  @retval EFI_TIMEOUT  TPM chip can't be set to ready state in time.
+**/
+EFI_STATUS
+TisPcPrepareCommand (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  TpmWriteByte (INFINEON_TPM_STS_0_ADDRESS_DEFAULT, TIS_PC_STS_READY);
+  Status = TisPcWaitRegisterBits (
+             INFINEON_TPM_STS_0_ADDRESS_DEFAULT,
+             TIS_PC_STS_READY,
+             0,
+             TIS_TIMEOUT_B
+             );
+  return Status;
+}
+
+/**
+  This service requests use TPM12.
+
+  @retval EFI_SUCCESS      Get the control of TPM12 chip.
+  @retval EFI_NOT_FOUND    TPM12 not found.
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+Tpm12RequestUseTpm (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // Check to see if TPM exists
+  //
+  if (TpmReadByte (INFINEON_TPM_ACCESS_0_ADDRESS_DEFAULT) == 0xFF) {
+    return EFI_NOT_FOUND;
+  }
+
+  TpmWriteByte (INFINEON_TPM_ACCESS_0_ADDRESS_DEFAULT, TIS_PC_ACC_RQUUSE);
+
+  //
+  // No locality set before, ACCESS_X.activeLocality MUST be valid within TIMEOUT_A
+  //
+  Status = TisPcWaitRegisterBits (
+             INFINEON_TPM_ACCESS_0_ADDRESS_DEFAULT,
+             (UINT8)(TIS_PC_ACC_ACTIVE |TIS_PC_VALID),
+             0,
+             TIS_TIMEOUT_A
+             );
+  return Status;
+}
+
+/**
+  Send command to TPM for execution.
+
+  @param[in] TpmBuffer   Buffer for TPM command data.
+  @param[in] DataLength  TPM command data length.
+
+  @retval EFI_SUCCESS  Operation completed successfully.
+  @retval EFI_TIMEOUT  The register can't run into the expected status in time.
+
+**/
+EFI_STATUS
+TisPcSend (
+  IN UINT8   *TpmBuffer,
+  IN UINT32  DataLength
+  )
+{
+  UINT16      BurstCount;
+  UINT32      Index;
+  EFI_STATUS  Status;
+
+  Status = TisPcPrepareCommand ();
+  if (EFI_ERROR (Status)){
+    DEBUG ((DEBUG_ERROR, "The TPM is not ready!\n"));
+    goto Done;
+  }
+  Index = 0;
+  while (Index < DataLength) {
+    Status = TisPcReadBurstCount (&BurstCount);
+    if (EFI_ERROR (Status)) {
+      Status = EFI_TIMEOUT;
+      goto Done;
+    }
+    for (; BurstCount > 0 && Index < DataLength; BurstCount--) {
+      TpmWriteByte (INFINEON_TPM_DATA_FIFO_0_ADDRESS_DEFAULT, *(TpmBuffer + Index));
+      Index++;
+    }
+  }
+  //
+  // Ensure the TPM status STS_EXPECT change from 1 to 0
+  //
+  Status = TisPcWaitRegisterBits (
+             INFINEON_TPM_STS_0_ADDRESS_DEFAULT,
+             (UINT8) TIS_PC_VALID,
+             TIS_PC_STS_EXPECT,
+             TIS_TIMEOUT_C
+             );
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  //
+  // Start the command
+  //
+  TpmWriteByte (INFINEON_TPM_STS_0_ADDRESS_DEFAULT, TIS_PC_STS_GO);
+
+Done:
+  if (EFI_ERROR (Status))  {
+    //
+    // Ensure the TPM state change from "Reception" to "Idle/Ready"
+    //
+    TpmWriteByte (INFINEON_TPM_STS_0_ADDRESS_DEFAULT, TIS_PC_STS_READY);
+  }
+
+  return Status;
+}
+
+/**
+  Receive response data of last command from TPM.
+
+  @param[out] TpmBuffer  Buffer for response data.
+  @param[out] RespSize   Response data length.
+
+  @retval EFI_SUCCESS           Operation completed successfully.
+  @retval EFI_TIMEOUT           The register can't run into the expected status in time.
+  @retval EFI_DEVICE_ERROR      Unexpected device status.
+  @retval EFI_BUFFER_TOO_SMALL  Response data is too long.
+
+**/
+EFI_STATUS
+TisPcReceive (
+  OUT UINT8   *TpmBuffer,
+  OUT UINT32  *RespSize
+  )
+{
+  EFI_STATUS           Status;
+  UINT16               BurstCount;
+  UINT32               Index;
+  UINT32               ResponseSize;
+  TPM_RSP_COMMAND_HDR  *ResponseHeader;
+
+  //
+  // Wait for the command completion
+  //
+  Status = TisPcWaitRegisterBits (
+             INFINEON_TPM_STS_0_ADDRESS_DEFAULT,
+             (UINT8) (TIS_PC_VALID | TIS_PC_STS_DATA),
+             0,
+             TIS_TIMEOUT_B
+             );
+  if (EFI_ERROR (Status)) {
+    Status = EFI_TIMEOUT;
+    goto Done;
+  }
+  //
+  // Read the response data header and check it
+  //
+  Index = 0;
+  BurstCount = 0;
+  while (Index < sizeof (TPM_RSP_COMMAND_HDR)) {
+    Status = TisPcReadBurstCount (&BurstCount);
+    if (EFI_ERROR (Status)) {
+      Status = EFI_TIMEOUT;
+      goto Done;
+    }
+    for (; BurstCount > 0 ; BurstCount--) {
+      *(TpmBuffer + Index) = TpmReadByte (INFINEON_TPM_DATA_FIFO_0_ADDRESS_DEFAULT);
+      Index++;
+      if (Index == sizeof (TPM_RSP_COMMAND_HDR))
+        break;
+    }
+  }
+
+  //
+  // Check the response data header (tag, parasize and returncode)
+  //
+  ResponseHeader = (TPM_RSP_COMMAND_HDR *)TpmBuffer;
+  if (SwapBytes16 (ReadUnaligned16 (&ResponseHeader->tag)) != TPM_TAG_RSP_COMMAND) {
+    Status = EFI_DEVICE_ERROR;
+    goto Done;
+  }
+
+  ResponseSize = SwapBytes32 (ReadUnaligned32 (&ResponseHeader->paramSize));
+  if (ResponseSize == sizeof (TPM_RSP_COMMAND_HDR)) {
+    Status = EFI_SUCCESS;
+    goto Done;
+  }
+  if (ResponseSize < sizeof (TPM_RSP_COMMAND_HDR)) {
+    Status = EFI_DEVICE_ERROR;
+    goto Done;
+  }
+  if (*RespSize < ResponseSize) {
+    Status = EFI_BUFFER_TOO_SMALL;
+    goto Done;
+  }
+  *RespSize = ResponseSize;
+
+  //
+  // Continue reading the remaining data
+  //
+  while (Index < ResponseSize) {
+    for (; BurstCount > 0 ; BurstCount--) {
+      *(TpmBuffer + Index) = TpmReadByte (INFINEON_TPM_DATA_FIFO_0_ADDRESS_DEFAULT);
+      Index++;
+      if (Index == ResponseSize) {
+        Status = EFI_SUCCESS;
+        goto Done;
+      }
+    }
+    Status = TisPcReadBurstCount (&BurstCount);
+    if (EFI_ERROR (Status) && (Index < ResponseSize)) {
+      Status = EFI_DEVICE_ERROR;
+      goto Done;
+    }
+  }
+
+Done:
+  //
+  // Ensure the TPM state change from "Execution" or "Completion" to "Idle/Ready"
+  //
+  TpmWriteByte (INFINEON_TPM_STS_0_ADDRESS_DEFAULT, TIS_PC_STS_READY);
+
+  return Status;
+}
+
+/**
+  This service enables the sending of commands to the TPM12.
+
+  @param[in]     InputParameterBlockSize   Size of the TPM12 input parameter block.
+  @param[in]     InputParameterBlock       Pointer to the TPM12 input parameter block.
+  @param[in,out] OutputParameterBlockSize  Size of the TPM12 output parameter block.
+  @param[in]     OutputParameterBlock      Pointer to the TPM12 output parameter block.
+
+  @retval EFI_SUCCESS           The command byte stream was successfully sent to
+                                the device and a response was successfully received.
+  @retval EFI_DEVICE_ERROR      The command was not successfully sent to the
+                                device or a response was not successfully received
+                                from the device.
+  @retval EFI_BUFFER_TOO_SMALL  The output parameter block is too small.
+**/
+EFI_STATUS
+EFIAPI
+Tpm12SubmitCommand (
+  IN UINT32      InputParameterBlockSize,
+  IN UINT8       *InputParameterBlock,
+  IN OUT UINT32  *OutputParameterBlockSize,
+  IN UINT8       *OutputParameterBlock
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = TisPcSend (InputParameterBlock, InputParameterBlockSize);
+  if (!EFI_ERROR (Status)) {
+    Status = TisPcReceive (OutputParameterBlock, OutputParameterBlockSize);
+  }
+  return Status;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/Tpm12DeviceLibInfineonI2c.inf b/Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/Tpm12DeviceLibInfineonI2c.inf
new file mode 100644
index 0000000000..26c12a4b6d
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/Tpm12DeviceLibInfineonI2c.inf
@@ -0,0 +1,39 @@
+## @file
+#  Provides some common functions for the TCG feature for Infineon I2C TPM.
+#
+#  This instance provides basic TPM Interface Specification (TIS) functions
+#  for Infineon I2C TPM.
+#
+# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = Tpm12DeviceLibInfineonI2c
+  MODULE_UNI_FILE                = Tpm12DeviceLibInfineonI2c.uni
+  FILE_GUID                      = DBE37563-AFEF-4B41-BDCE-B01B6D1E8690
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = Tpm12DeviceLib|PEIM DXE_DRIVER DXE_SMM_DRIVER UEFI_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  TisPc.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  TimerLib
+  DebugLib
+  I2cLib
diff --git a/Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/Tpm12DeviceLibInfineonI2c.uni b/Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/Tpm12DeviceLibInfineonI2c.uni
new file mode 100644
index 0000000000..efc07ea39d
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/Tpm12DeviceLibInfineonI2c.uni
@@ -0,0 +1,16 @@
+// /** @file
+// Provides some common functions for the TCG feature for Infineon I2C TPM.
+//
+// This instance provides basic TPM Interface Specification (TIS) functions
+// for Infineon I2C TPM.
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT             #language en-US "Provides some common functions for the TCG feature for Infineon I2C TPM"
+
+#string STR_MODULE_DESCRIPTION          #language en-US "This instance provides basic TPM Interface Specification (TIS) functions for Infineon I2C TPM."
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.c b/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.c
new file mode 100644
index 0000000000..be41a8595c
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.c
@@ -0,0 +1,1397 @@
+/** @file
+Pci Host Bridge driver for a simple IIO. There is only one PCI Root Bridge in the system.
+Provides the basic interfaces to abstract a PCI Host Bridge Resource Allocation.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#include "PciHostBridge.h"
+#include <IntelQNCRegs.h>
+
+//
+// We can hardcode the following for a Simple IIO -
+// Root Bridge Count within the host bridge
+// Root Bridge's device path
+// Root Bridge's resource appeture
+//
+EFI_PCI_ROOT_BRIDGE_DEVICE_PATH    mEfiPciRootBridgeDevicePath[ROOT_BRIDGE_COUNT] = {
+  {
+    {
+      {
+        ACPI_DEVICE_PATH,
+        ACPI_DP,
+        {
+          (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)),
+          (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
+        }
+      },
+      EISA_PNP_ID (0x0A03),
+      0
+    },
+    {
+      END_DEVICE_PATH_TYPE,
+      END_ENTIRE_DEVICE_PATH_SUBTYPE,
+      {
+        END_DEVICE_PATH_LENGTH,
+        0
+      }
+    }
+  }
+};
+
+EFI_HANDLE                         mDriverImageHandle;
+PCI_ROOT_BRIDGE_RESOURCE_APERTURE  *mResAperture;
+
+//
+// Implementation
+//
+EFI_STATUS
+EFIAPI
+InitializePciHostBridge (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+/*++
+
+Routine Description:
+
+  Entry point of this driver.
+
+Arguments:
+
+  ImageHandle  -  Image handle of this driver.
+  SystemTable  -  Pointer to standard EFI system table.
+
+Returns:
+
+  EFI_SUCCESS       -  Succeed.
+  EFI_DEVICE_ERROR  -  Fail to install PCI_ROOT_BRIDGE_IO protocol.
+
+--*/
+{
+  EFI_STATUS                  Status;
+  UINTN                       TotalRootBridgeFound;
+  PCI_HOST_BRIDGE_INSTANCE    *HostBridge;
+  PCI_ROOT_BRIDGE_INSTANCE    *PrivateData;
+  UINT64                      AllocAttributes;
+  EFI_PHYSICAL_ADDRESS        BaseAddress;
+
+  PrivateData = NULL;
+
+  mDriverImageHandle = ImageHandle;
+
+  //
+  // Most systems in the world including complex servers
+  // have only one Host Bridge. Create Host Bridge Device Handle
+  //
+  Status = gBS->AllocatePool(EfiBootServicesData, sizeof(PCI_HOST_BRIDGE_INSTANCE), (VOID **) &HostBridge);
+  ASSERT_EFI_ERROR (Status);
+  ZeroMem (HostBridge, sizeof (PCI_HOST_BRIDGE_INSTANCE));
+
+  HostBridge->Signature         = PCI_HOST_BRIDGE_SIGNATURE;
+  HostBridge->RootBridgeCount   = 1;
+  HostBridge->ResourceSubmited  = FALSE;
+  HostBridge->CanRestarted      = TRUE;
+  //
+  // InitializeListHead (&HostBridge->Head);
+  //
+  HostBridge->ResAlloc.NotifyPhase          = NotifyPhase;
+  HostBridge->ResAlloc.GetNextRootBridge    = GetNextRootBridge;
+  HostBridge->ResAlloc.GetAllocAttributes   = GetAttributes;
+  HostBridge->ResAlloc.StartBusEnumeration  = StartBusEnumeration;
+  HostBridge->ResAlloc.SetBusNumbers        = SetBusNumbers;
+  HostBridge->ResAlloc.SubmitResources      = SubmitResources;
+  HostBridge->ResAlloc.GetProposedResources = GetProposedResources;
+  HostBridge->ResAlloc.PreprocessController = PreprocessController;
+
+  Status = gBS->InstallProtocolInterface (
+                    &HostBridge->HostBridgeHandle,
+                    &gEfiPciHostBridgeResourceAllocationProtocolGuid,
+                    EFI_NATIVE_INTERFACE,
+                    &HostBridge->ResAlloc
+                    );
+  if (EFI_ERROR (Status)) {
+    gBS->FreePool (HostBridge);
+    return EFI_DEVICE_ERROR;
+  }
+
+  Status = gBS->AllocatePool (EfiBootServicesData,
+                HostBridge->RootBridgeCount * sizeof(PCI_ROOT_BRIDGE_RESOURCE_APERTURE),
+                (VOID **) &mResAperture);
+  ASSERT_EFI_ERROR (Status);
+  ZeroMem (mResAperture, HostBridge->RootBridgeCount * sizeof(PCI_ROOT_BRIDGE_RESOURCE_APERTURE));
+
+  DEBUG ((EFI_D_INFO, "Address of resource Aperture:  %x\n", mResAperture));
+
+  //
+  // Create Root Bridge Device Handle in this Host Bridge
+  //
+  InitializeListHead (&HostBridge->Head);
+
+  TotalRootBridgeFound = 0;
+
+  Status = gBS->AllocatePool ( EfiBootServicesData,sizeof (PCI_ROOT_BRIDGE_INSTANCE), (VOID **) &PrivateData);
+  ASSERT_EFI_ERROR (Status);
+  ZeroMem (PrivateData, sizeof (PCI_ROOT_BRIDGE_INSTANCE));
+
+  PrivateData->Signature  = PCI_ROOT_BRIDGE_SIGNATURE;
+  PrivateData->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) &mEfiPciRootBridgeDevicePath[TotalRootBridgeFound];
+  AllocAttributes         = GetAllocAttributes (TotalRootBridgeFound);
+
+  SimpleIioRootBridgeConstructor (
+      &PrivateData->Io,
+      HostBridge->HostBridgeHandle,
+      &(mResAperture[TotalRootBridgeFound]),
+      AllocAttributes
+      );
+  //
+  // Update Root Bridge with UDS resource information
+  //
+  PrivateData->Aperture.BusBase    = QNC_PCI_HOST_BRIDGE_RESOURCE_APPETURE_BUSBASE;
+  PrivateData->Aperture.BusLimit   = QNC_PCI_HOST_BRIDGE_RESOURCE_APPETURE_BUSLIMIT;
+  PrivateData->Aperture.Mem32Base  = PcdGet32 (PcdPciHostBridgeMemory32Base);
+  PrivateData->Aperture.Mem32Limit = PcdGet32 (PcdPciHostBridgeMemory32Base) + (PcdGet32 (PcdPciHostBridgeMemory32Size) - 1);
+  PrivateData->Aperture.IoBase  = PcdGet16 (PcdPciHostBridgeIoBase);
+  PrivateData->Aperture.IoLimit = PcdGet16 (PcdPciHostBridgeIoBase) + (PcdGet16 (PcdPciHostBridgeIoSize) - 1);
+
+  DEBUG ((EFI_D_INFO, "PCI Host Bridge BusBase:               %x\n",  QNC_PCI_HOST_BRIDGE_RESOURCE_APPETURE_BUSBASE));
+  DEBUG ((EFI_D_INFO, "PCI Host Bridge BusLimit:              %x\n",  QNC_PCI_HOST_BRIDGE_RESOURCE_APPETURE_BUSLIMIT));
+  DEBUG ((EFI_D_INFO, "PCI Host Bridge PciResourceMem32Base:  %x\n",  PcdGet32 (PcdPciHostBridgeMemory32Base)));
+  DEBUG ((EFI_D_INFO, "PCI Host Bridge PciResourceMem32Limit: %x\n",  PcdGet32 (PcdPciHostBridgeMemory32Base) + (PcdGet32 (PcdPciHostBridgeMemory32Size) - 1)));
+  DEBUG ((EFI_D_INFO, "PCI Host Bridge PciResourceMem64Base:  %lX\n", PcdGet64 (PcdPciHostBridgeMemory64Base)));
+  DEBUG ((EFI_D_INFO, "PCI Host Bridge PciResourceMem64Limit: %lX\n", PcdGet64 (PcdPciHostBridgeMemory64Base) + (PcdGet64 (PcdPciHostBridgeMemory64Size) - 1)));
+  DEBUG ((EFI_D_INFO, "PCI Host Bridge PciResourceIoBase:     %x\n",  PcdGet16 (PcdPciHostBridgeIoBase)));
+  DEBUG ((EFI_D_INFO, "PCI Host Bridge PciResourceIoLimit:    %x\n",  PcdGet16 (PcdPciHostBridgeIoBase) + (PcdGet16 (PcdPciHostBridgeIoSize) - 1)));
+
+  PrivateData->Handle = NULL;
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &PrivateData->Handle,
+                  &gEfiDevicePathProtocolGuid,
+                  PrivateData->DevicePath,
+                  &gEfiPciRootBridgeIoProtocolGuid,
+                  &PrivateData->Io,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  InsertTailList (&HostBridge->Head, &PrivateData->Link);
+  TotalRootBridgeFound++;           // This is a valid rootbridge so imcrement total root bridges found
+
+  //
+  // Add PCIE base into Runtime memory so that it can be reported in E820 table
+  //
+  Status = gDS->AddMemorySpace (
+                  EfiGcdMemoryTypeMemoryMappedIo,
+                  PcdGet64 (PcdPciExpressBaseAddress),
+                  PcdGet64 (PcdPciExpressSize),
+                  EFI_MEMORY_RUNTIME | EFI_MEMORY_UC
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+  BaseAddress = PcdGet64 (PcdPciExpressBaseAddress);
+
+  Status = gDS->AllocateMemorySpace (
+                  EfiGcdAllocateAddress,
+                  EfiGcdMemoryTypeMemoryMappedIo,
+                  0,
+                  PcdGet64 (PcdPciExpressSize),
+                  &BaseAddress,
+                  ImageHandle,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+  Status = gDS->SetMemorySpaceAttributes (
+                  PcdGet64 (PcdPciExpressBaseAddress),
+                  PcdGet64 (PcdPciExpressSize),
+                  EFI_MEMORY_RUNTIME
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  if (PcdGet16 (PcdPciHostBridgeIoSize) > 0) {
+    //
+    // At present, we use up the first 4k for fixed ranges like
+    // ICH GPIO, ACPI and ISA devices. The first 4k is not
+    // tracked through GCD. It should be.
+    //
+    Status = gDS->AddIoSpace (
+                    EfiGcdIoTypeIo,
+                    PcdGet16(PcdPciHostBridgeIoBase),
+                    PcdGet16(PcdPciHostBridgeIoSize)
+                    );
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  if (PcdGet32(PcdPciHostBridgeMemory32Size) > 0) {
+    //
+    // Shouldn't the capabilities be UC?
+    //
+    Status = gDS->AddMemorySpace (
+                    EfiGcdMemoryTypeMemoryMappedIo,
+                    PcdGet32(PcdPciHostBridgeMemory32Base),
+                    PcdGet32(PcdPciHostBridgeMemory32Size),
+                    0
+                    );
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+NotifyPhase (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE    Phase
+  )
+/*++
+
+Routine Description:
+
+  Enter a certain phase of the PCI enumeration process.
+
+Arguments:
+
+  This   -  The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
+  Phase  -  The phase during enumeration.
+
+Returns:
+
+  EFI_SUCCESS            -  Succeed.
+  EFI_INVALID_PARAMETER  -  Wrong phase parameter passed in.
+  EFI_NOT_READY          -  Resources have not been submitted yet.
+
+--*/
+{
+  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
+  PCI_RESOURCE_TYPE                     Index;
+  EFI_LIST_ENTRY                        *List;
+  EFI_PHYSICAL_ADDRESS                  BaseAddress;
+  UINT64                                AddrLen;
+  UINTN                                 BitsOfAlignment;
+  UINT64                                Alignment;
+  EFI_STATUS                            Status;
+  EFI_STATUS                            ReturnStatus;
+  PCI_RESOURCE_TYPE                     Index1;
+  PCI_RESOURCE_TYPE                     Index2;
+  BOOLEAN                               ResNodeHandled[TypeMax];
+  UINT64                                MaxAlignment;
+
+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+
+  switch (Phase) {
+    case EfiPciHostBridgeBeginEnumeration:
+        if (HostBridgeInstance->CanRestarted) {
+          //
+          // Reset Root Bridge
+          //
+          List = HostBridgeInstance->Head.ForwardLink;
+
+          while (List != &HostBridgeInstance->Head) {
+            RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+            for (Index = TypeIo; Index < TypeMax; Index++) {
+              RootBridgeInstance->ResAllocNode[Index].Type    = Index;
+              RootBridgeInstance->ResAllocNode[Index].Base    = 0;
+              RootBridgeInstance->ResAllocNode[Index].Length  = 0;
+              RootBridgeInstance->ResAllocNode[Index].Status  = ResNone;
+            } // for
+
+            List = List->ForwardLink;
+          } // while
+
+          HostBridgeInstance->ResourceSubmited  = FALSE;
+          HostBridgeInstance->CanRestarted      = TRUE;
+        } else {
+          //
+          // Can not restart
+          //
+          return EFI_NOT_READY;
+        } // if
+        break;
+
+    case EfiPciHostBridgeEndEnumeration:
+        return EFI_SUCCESS;
+        break;
+
+    case EfiPciHostBridgeBeginBusAllocation:
+        //
+        // No specific action is required here, can perform any chipset specific programing
+        //
+        HostBridgeInstance->CanRestarted = FALSE;
+        return EFI_SUCCESS;
+        break;
+
+    case EfiPciHostBridgeEndBusAllocation:
+        //
+        // No specific action is required here, can perform any chipset specific programing
+        //
+        // HostBridgeInstance->CanRestarted = FALSE;
+        //
+        return EFI_SUCCESS;
+        break;
+
+    case EfiPciHostBridgeBeginResourceAllocation:
+        //
+        // No specific action is required here, can perform any chipset specific programing
+        //
+        // HostBridgeInstance->CanRestarted = FALSE;
+        //
+        return EFI_SUCCESS;
+        break;
+
+    case EfiPciHostBridgeAllocateResources:
+        ReturnStatus = EFI_SUCCESS;
+        if (HostBridgeInstance->ResourceSubmited) {
+          List = HostBridgeInstance->Head.ForwardLink;
+          while (List != &HostBridgeInstance->Head) {
+            for (Index1 = TypeIo; Index1 < TypeBus; Index1++) {
+              ResNodeHandled[Index1] = FALSE;
+            }
+
+            RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+            DEBUG ((EFI_D_INFO, "Address of RootBridgeInstance:   %x)\n", RootBridgeInstance));
+            DEBUG ((EFI_D_INFO, "  Signature:              %x\n", RootBridgeInstance->Signature));
+            DEBUG ((EFI_D_INFO, "  Bus Number Assigned:    %x\n", RootBridgeInstance->BusNumberAssigned));
+            DEBUG ((EFI_D_INFO, "  Bus Scan Count:         %x\n", RootBridgeInstance->BusScanCount));
+
+            for (Index1 = TypeIo; Index1 < TypeBus; Index1++) {
+              if (RootBridgeInstance->ResAllocNode[Index1].Status == ResNone) {
+                ResNodeHandled[Index1] = TRUE;
+              } else {
+                //
+                // Allocate the resource node with max alignment at first
+                //
+                MaxAlignment = 0;
+                Index        = TypeMax;
+                for (Index2 = TypeIo; Index2 < TypeBus; Index2++) {
+                  if (ResNodeHandled[Index2]) {
+                    continue;
+                  }
+                  if (MaxAlignment <= RootBridgeInstance->ResAllocNode[Index2].Alignment) {
+                    MaxAlignment = RootBridgeInstance->ResAllocNode[Index2].Alignment;
+                    Index = Index2;
+                  }
+                } // for
+
+                if (Index < TypeMax) {
+                  ResNodeHandled[Index] = TRUE;
+                } else {
+                  ASSERT (FALSE);
+                }
+
+                Alignment = RootBridgeInstance->ResAllocNode[Index].Alignment;
+
+                //
+                // Get the number of '1' in Alignment.
+                //
+                for (BitsOfAlignment = 0; Alignment != 0; BitsOfAlignment++) {
+                  Alignment = RShiftU64 (Alignment, 1);
+                }
+
+                AddrLen   = RootBridgeInstance->ResAllocNode[Index].Length;
+                Alignment = RootBridgeInstance->ResAllocNode[Index].Alignment;
+
+                DEBUG ((EFI_D_INFO, "\n\nResource Type to assign :   %x\n", Index));
+                DEBUG ((EFI_D_INFO, "  Length to allocate:       %x\n", RootBridgeInstance->ResAllocNode[Index].Length));
+                DEBUG ((EFI_D_INFO, "  Aligment:                 %x\n", Alignment));
+
+                switch (Index) {
+                  case TypeIo:
+                      if (RootBridgeInstance->Aperture.IoBase < RootBridgeInstance->Aperture.IoLimit) {
+                        //
+                        // It is impossible for 0xFFFF Alignment for IO16
+                        //
+                        if (BitsOfAlignment >= 16)
+                          Alignment = 0;
+
+                        BaseAddress = RootBridgeInstance->Aperture.IoBase;
+
+                        //
+                        // Have to make sure Aligment is handled seeing we are doing direct address allocation
+                        //
+                        if ((BaseAddress & ~(Alignment)) != BaseAddress)
+                          BaseAddress = ((BaseAddress + Alignment) & ~(Alignment));
+
+                        while((BaseAddress + AddrLen) <= RootBridgeInstance->Aperture.IoLimit + 1) {
+
+                          Status = gDS->AllocateIoSpace ( EfiGcdAllocateAddress, EfiGcdIoTypeIo, BitsOfAlignment,
+                                                          AddrLen, &BaseAddress, mDriverImageHandle, NULL );
+
+                          if (!EFI_ERROR (Status)) {
+                            RootBridgeInstance->ResAllocNode[Index].Base    = (UINT64) BaseAddress;
+                            RootBridgeInstance->ResAllocNode[Index].Status  = ResAllocated;
+                            goto TypeIoFound;
+                          }
+
+                          BaseAddress += (Alignment + 1);
+                        } // while
+
+                      } // if
+
+                      TypeIoFound:
+                      if (RootBridgeInstance->ResAllocNode[Index].Status  != ResAllocated) {
+                        //
+                        // No Room at the Inn for this resources request
+                        //
+                        ReturnStatus = EFI_OUT_OF_RESOURCES;
+                      } // if
+
+                      break;
+
+                  case TypeMem32:
+                      if (RootBridgeInstance->Aperture.Mem32Base < RootBridgeInstance->Aperture.Mem32Limit) {
+
+                        BaseAddress = RootBridgeInstance->Aperture.Mem32Base;
+                        //
+                        // Have to make sure Aligment is handled seeing we are doing direct address allocation
+                        //
+                        if ((BaseAddress & ~(Alignment)) != BaseAddress)
+                          BaseAddress = ((BaseAddress + Alignment) & ~(Alignment));
+
+                        while((BaseAddress + AddrLen) <= RootBridgeInstance->Aperture.Mem32Limit + 1) {
+
+                          Status = gDS->AllocateMemorySpace ( EfiGcdAllocateAddress, EfiGcdMemoryTypeMemoryMappedIo,
+                                                            BitsOfAlignment, AddrLen, &BaseAddress, mDriverImageHandle, NULL);
+
+                          if (!EFI_ERROR (Status)) {
+                            RootBridgeInstance->ResAllocNode[Index].Base    = (UINT64) BaseAddress;
+                            RootBridgeInstance->ResAllocNode[Index].Status  = ResAllocated;
+                            goto TypeMem32Found;
+                          } // if
+
+                          BaseAddress += (Alignment + 1);
+                        } // while
+                      } // if
+
+                      TypeMem32Found:
+                      if (RootBridgeInstance->ResAllocNode[Index].Status  != ResAllocated) {
+                        //
+                        // No Room at the Inn for this resources request
+                        //
+                        ReturnStatus = EFI_OUT_OF_RESOURCES;
+                      }
+
+                      break;
+
+                  case TypePMem32:
+                      StartTypePMem32:
+                      if (RootBridgeInstance->Aperture.Mem32Base < RootBridgeInstance->Aperture.Mem32Limit) {
+
+                        BaseAddress = RootBridgeInstance->Aperture.Mem32Limit + 1;
+                        BaseAddress -= AddrLen;
+
+                        //
+                        // Have to make sure Aligment is handled seeing we are doing direct address allocation
+                        //
+                        if ((BaseAddress & ~(Alignment)) != BaseAddress)
+                          BaseAddress = ((BaseAddress) & ~(Alignment));
+
+                        while(RootBridgeInstance->Aperture.Mem32Base <= BaseAddress) {
+
+                          DEBUG ((EFI_D_INFO, "      Attempting %x allocation at 0x%lx .....", Index, BaseAddress));
+                          Status = gDS->AllocateMemorySpace ( EfiGcdAllocateAddress, EfiGcdMemoryTypeMemoryMappedIo,
+                                                  BitsOfAlignment, AddrLen, &BaseAddress, mDriverImageHandle, NULL);
+
+                          if (!EFI_ERROR (Status)) {
+                            RootBridgeInstance->ResAllocNode[Index].Base    = (UINT64) BaseAddress;
+                            RootBridgeInstance->ResAllocNode[Index].Status  = ResAllocated;
+                            DEBUG ((EFI_D_INFO, "... Passed!!\n"));
+                            goto TypePMem32Found;
+                          }
+                          DEBUG ((EFI_D_INFO, "... Failed!!\n"));
+                          BaseAddress -= (Alignment + 1);
+                        } // while
+                      } // if
+
+                      TypePMem32Found:
+                      if (RootBridgeInstance->ResAllocNode[Index].Status  != ResAllocated) {
+                        //
+                        // No Room at the Inn for this resources request
+                        //
+                        ReturnStatus = EFI_OUT_OF_RESOURCES;
+                      }
+
+                      break;
+
+                  case TypeMem64:
+                  case TypePMem64:
+                      if (RootBridgeInstance->ResAllocNode[Index].Status  != ResAllocated) {
+                        //
+                        // If 64-bit resourcing is not available, then try as PMem32
+                        //
+                        goto StartTypePMem32;
+                      }
+
+                      break;
+
+                  default:
+                      break;
+                } // End switch (Index)
+
+                DEBUG ((EFI_D_INFO, "Resource Type Assigned:   %x\n", Index));
+                if (RootBridgeInstance->ResAllocNode[Index].Status == ResAllocated) {
+                  DEBUG ((EFI_D_INFO, "  Base Address Assigned: %x\n", RootBridgeInstance->ResAllocNode[Index].Base));
+                  DEBUG ((EFI_D_INFO, "  Length Assigned:       %x\n", RootBridgeInstance->ResAllocNode[Index].Length));
+                } else {
+                  DEBUG ((DEBUG_ERROR, "  Resource Allocation failed!  There was no room at the inn\n"));
+                }
+
+              }
+            }
+
+            List = List->ForwardLink;
+          }
+
+          if (ReturnStatus == EFI_OUT_OF_RESOURCES) {
+            DEBUG ((DEBUG_ERROR, "Resource allocation Failed. Continue booting the system.\n"));
+          }
+
+          //
+          // Set resource to zero for nodes where allocation fails
+          //
+          List = HostBridgeInstance->Head.ForwardLink;
+          while (List != &HostBridgeInstance->Head) {
+            RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+            for (Index = TypeIo; Index < TypeBus; Index++) {
+              if (RootBridgeInstance->ResAllocNode[Index].Status != ResAllocated) {
+                RootBridgeInstance->ResAllocNode[Index].Length = 0;
+              }
+            }
+            List = List->ForwardLink;
+          }
+          return ReturnStatus;
+        } else {
+          return EFI_NOT_READY;
+        }
+        //
+        // HostBridgeInstance->CanRestarted = FALSE;
+        //
+        break;
+
+    case EfiPciHostBridgeSetResources:
+        //
+        // HostBridgeInstance->CanRestarted = FALSE;
+        //
+        break;
+
+    case EfiPciHostBridgeFreeResources:
+        //
+        // HostBridgeInstance->CanRestarted = FALSE;
+        //
+        ReturnStatus  = EFI_SUCCESS;
+        List          = HostBridgeInstance->Head.ForwardLink;
+        while (List != &HostBridgeInstance->Head) {
+          RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+          for (Index = TypeIo; Index < TypeBus; Index++) {
+            if (RootBridgeInstance->ResAllocNode[Index].Status == ResAllocated) {
+              AddrLen     = RootBridgeInstance->ResAllocNode[Index].Length;
+              BaseAddress = (EFI_PHYSICAL_ADDRESS) RootBridgeInstance->ResAllocNode[Index].Base;
+              switch (Index) {
+                case TypeIo:
+                    Status = gDS->FreeIoSpace (BaseAddress, AddrLen);
+                    if (EFI_ERROR (Status)) {
+                      ReturnStatus = Status;
+                    }
+                    break;
+
+                case TypeMem32:
+                    Status = gDS->FreeMemorySpace (BaseAddress, AddrLen);
+                    if (EFI_ERROR (Status)) {
+                      ReturnStatus = Status;
+                    }
+                    break;
+
+                case TypePMem32:
+                    break;
+
+                case TypeMem64:
+                    break;
+
+                case TypePMem64:
+                    Status = gDS->FreeMemorySpace (BaseAddress, AddrLen);
+                    if (EFI_ERROR (Status)) {
+                      ReturnStatus = Status;
+                    }
+                    break;
+
+                default:
+                    break;
+              } // end switch (Index)
+
+              RootBridgeInstance->ResAllocNode[Index].Type    = Index;
+              RootBridgeInstance->ResAllocNode[Index].Base    = 0;
+              RootBridgeInstance->ResAllocNode[Index].Length  = 0;
+              RootBridgeInstance->ResAllocNode[Index].Status  = ResNone;
+            }
+          }
+
+          List = List->ForwardLink;
+        }
+
+        HostBridgeInstance->ResourceSubmited  = FALSE;
+        HostBridgeInstance->CanRestarted      = TRUE;
+        return ReturnStatus;
+        break;
+
+    case EfiPciHostBridgeEndResourceAllocation:
+        //
+        // Resource enumeration is done. Perform any activities that
+        // must wait until that time.
+        //
+        break;
+
+    default:
+        return EFI_INVALID_PARAMETER;
+  } // End switch (Phase)
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+GetNextRootBridge (
+  IN     EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN OUT EFI_HANDLE                                       *RootBridgeHandle
+  )
+/*++
+
+Routine Description:
+  Return the device handle of the next PCI root bridge that is associated with
+  this Host Bridge.
+
+Arguments:
+
+  This              -  The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+  RootBridgeHandle  -  Returns the device handle of the next PCI Root Bridge.
+                       On input, it holds the RootBridgeHandle returned by the most
+                       recent call to GetNextRootBridge().The handle for the first
+                       PCI Root Bridge is returned if RootBridgeHandle is NULL on input.
+
+Returns:
+
+  EFI_SUCCESS            -  Succeed.
+  EFI_NOT_FOUND          -  Next PCI root bridge not found.
+  EFI_INVALID_PARAMETER  -  Wrong parameter passed in.
+
+--*/
+{
+  BOOLEAN                   NoRootBridge;
+  EFI_LIST_ENTRY            *List;
+  PCI_HOST_BRIDGE_INSTANCE  *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE  *RootBridgeInstance;
+
+  NoRootBridge        = TRUE;
+  HostBridgeInstance  = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+  List                = HostBridgeInstance->Head.ForwardLink;
+
+  while (List != &HostBridgeInstance->Head) {
+    NoRootBridge        = FALSE;
+    RootBridgeInstance  = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+    if (*RootBridgeHandle == NULL) {
+      //
+      // Return the first Root Bridge Handle of the Host Bridge
+      //
+      *RootBridgeHandle = RootBridgeInstance->Handle;
+      return EFI_SUCCESS;
+    } else {
+      if (*RootBridgeHandle == RootBridgeInstance->Handle) {
+        //
+        // Get next if have
+        //
+        List = List->ForwardLink;
+        if (List != &HostBridgeInstance->Head) {
+          RootBridgeInstance  = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+          *RootBridgeHandle   = RootBridgeInstance->Handle;
+          return EFI_SUCCESS;
+        } else {
+          return EFI_NOT_FOUND;
+        }
+      }
+    }
+
+    List = List->ForwardLink;
+    //
+    // end while
+    //
+  }
+
+  if (NoRootBridge) {
+    return EFI_NOT_FOUND;
+  } else {
+    return EFI_INVALID_PARAMETER;
+  }
+}
+
+EFI_STATUS
+EFIAPI
+GetAttributes (
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN  EFI_HANDLE                                       RootBridgeHandle,
+  OUT UINT64                                           *Attributes
+  )
+/*++
+
+Routine Description:
+  Returns the attributes of a PCI Root Bridge.
+
+Arguments:
+
+  This              -  The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+  RootBridgeHandle  -  The device handle of the PCI Root Bridge
+                       that the caller is interested in.
+  Attributes        -  The pointer to attributes of the PCI Root Bridge.
+
+Returns:
+
+  EFI_SUCCESS            -  Succeed.
+  EFI_INVALID_PARAMETER  -  Attributes parameter passed in is NULL or
+                            RootBridgeHandle is not an EFI_HANDLE
+                            that was returned on a previous call to
+                            GetNextRootBridge().
+
+--*/
+{
+  EFI_LIST_ENTRY            *List;
+  PCI_HOST_BRIDGE_INSTANCE  *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE  *RootBridgeInstance;
+
+  if (Attributes == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  HostBridgeInstance  = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+  List                = HostBridgeInstance->Head.ForwardLink;
+
+  while (List != &HostBridgeInstance->Head) {
+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+    if (RootBridgeHandle == RootBridgeInstance->Handle) {
+      *Attributes = RootBridgeInstance->RootBridgeAllocAttrib;
+      return EFI_SUCCESS;
+    }
+
+    List = List->ForwardLink;
+  }
+  //
+  // RootBridgeHandle is not an EFI_HANDLE
+  // that was returned on a previous call to GetNextRootBridge()
+  //
+  return EFI_INVALID_PARAMETER;
+}
+
+EFI_STATUS
+EFIAPI
+StartBusEnumeration (
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN  EFI_HANDLE                                       RootBridgeHandle,
+  OUT VOID                                             **Configuration
+  )
+/*++
+
+Routine Description:
+  This is the request from the PCI enumerator to set up
+  the specified PCI Root Bridge for bus enumeration process.
+
+Arguments:
+
+  This              -  The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+  RootBridgeHandle  -  The PCI Root Bridge to be set up.
+  Configuration     -  Pointer to the pointer to the PCI bus resource descriptor.
+
+Returns:
+
+  EFI_SUCCESS            -  Succeed.
+  EFI_OUT_OF_RESOURCES   -  Not enough pool to be allocated.
+  EFI_INVALID_PARAMETER  -  RootBridgeHandle is not a valid handle.
+
+--*/
+{
+  EFI_LIST_ENTRY            *List;
+  PCI_HOST_BRIDGE_INSTANCE  *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE  *RootBridgeInstance;
+  VOID                      *Buffer;
+  UINT8                     *Temp;
+  EFI_STATUS                Status;
+  UINTN                     BusStart;
+  UINTN                     BusEnd;
+  UINT64                    BusReserve;
+
+  HostBridgeInstance  = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+  List                = HostBridgeInstance->Head.ForwardLink;
+
+  while (List != &HostBridgeInstance->Head) {
+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+    if (RootBridgeHandle == RootBridgeInstance->Handle) {
+      //
+      // Set up the Root Bridge for Bus Enumeration
+      //
+      BusStart  = RootBridgeInstance->Aperture.BusBase;
+      BusEnd    = RootBridgeInstance->Aperture.BusLimit;
+      BusReserve = RootBridgeInstance->Aperture.BusReserve;
+      //
+      // Program the Hardware(if needed) if error return EFI_DEVICE_ERROR
+      //
+      Status = gBS->AllocatePool (
+                      EfiBootServicesData,
+                      sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR),
+                      &Buffer
+                      );
+      if (EFI_ERROR (Status)) {
+        return EFI_OUT_OF_RESOURCES;
+      }
+
+      Temp  = (UINT8 *) Buffer;
+
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp)->Desc                  = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp)->Len                   = 0x2B;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp)->ResType               = ACPI_ADDRESS_SPACE_TYPE_BUS;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp)->GenFlag               = 0;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp)->SpecificFlag          = 0;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp)->AddrSpaceGranularity  = 0;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp)->AddrRangeMin          = BusStart;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp)->AddrRangeMax          = BusReserve;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp)->AddrTranslationOffset = 0;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp)->AddrLen               = BusEnd - BusStart + 1;
+
+      Temp = Temp + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
+      ((EFI_ACPI_END_TAG_DESCRIPTOR *) Temp)->Desc = ACPI_END_TAG_DESCRIPTOR;
+      ((EFI_ACPI_END_TAG_DESCRIPTOR *) Temp)->Checksum = 0x0;
+
+      *Configuration = Buffer;
+      return EFI_SUCCESS;
+    }
+
+    List = List->ForwardLink;
+  }
+
+  return EFI_INVALID_PARAMETER;
+}
+
+EFI_STATUS
+EFIAPI
+SetBusNumbers (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_HANDLE                                       RootBridgeHandle,
+  IN VOID                                             *Configuration
+  )
+/*++
+
+Routine Description:
+  This function programs the PCI Root Bridge hardware so that
+  it decodes the specified PCI bus range.
+
+Arguments:
+
+  This              -  The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+  RootBridgeHandle  -  The PCI Root Bridge whose bus range is to be programmed.
+  Configuration     -  The pointer to the PCI bus resource descriptor.
+
+Returns:
+
+  EFI_SUCCESS            -  Succeed.
+  EFI_INVALID_PARAMETER  -  Wrong parameters passed in.
+
+--*/
+{
+  EFI_LIST_ENTRY            *List;
+  PCI_HOST_BRIDGE_INSTANCE  *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE  *RootBridgeInstance;
+  UINT8                     *Ptr;
+  UINTN                     BusStart;
+  UINTN                     BusEnd;
+  UINTN                     BusLen;
+
+  if (Configuration == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Ptr = Configuration;
+
+  //
+  // Check the Configuration is valid
+  //
+  if (*Ptr != ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Ptr)->ResType != ACPI_ADDRESS_SPACE_TYPE_BUS) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Ptr += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
+  if (*Ptr != ACPI_END_TAG_DESCRIPTOR) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  HostBridgeInstance  = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+  List                = HostBridgeInstance->Head.ForwardLink;
+
+  Ptr                 = Configuration;
+
+  while (List != &HostBridgeInstance->Head) {
+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+    if (RootBridgeHandle == RootBridgeInstance->Handle) {
+      BusStart  = (UINTN) ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Ptr)->AddrRangeMin;
+      BusLen    = (UINTN) ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Ptr)->AddrLen;
+      BusEnd    = BusStart + BusLen - 1;
+
+      if (BusStart > BusEnd) {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      if ((BusStart < RootBridgeInstance->Aperture.BusBase) || (BusEnd > RootBridgeInstance->Aperture.BusLimit)) {
+        return EFI_INVALID_PARAMETER;
+      }
+      //
+      // Update the Bus Range
+      //
+      RootBridgeInstance->ResAllocNode[TypeBus].Base    = BusStart;
+      RootBridgeInstance->ResAllocNode[TypeBus].Length  = BusLen;
+      RootBridgeInstance->ResAllocNode[TypeBus].Status  = ResAllocated;
+      RootBridgeInstance->BusScanCount++;
+      if (RootBridgeInstance->BusScanCount > 0) {
+        //
+        // Only care about the 2nd PCI bus scanning
+        //
+        RootBridgeInstance->BusNumberAssigned = TRUE;
+      }
+
+      return EFI_SUCCESS;
+    }
+
+    List = List->ForwardLink;
+  }
+
+  return EFI_INVALID_PARAMETER;
+}
+
+EFI_STATUS
+EFIAPI
+SubmitResources (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_HANDLE                                       RootBridgeHandle,
+  IN VOID                                             *Configuration
+  )
+/*++
+
+Routine Description:
+
+  Submits the I/O and memory resource requirements for the specified PCI Root Bridge.
+
+Arguments:
+  This              -  The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+  RootBridgeHandle  -  The PCI Root Bridge whose I/O and memory resource requirements.
+                       are being submitted.
+  Configuration     -  The pointer to the PCI I/O and PCI memory resource descriptor.
+
+Returns:
+
+  EFI_SUCCESS            -  Succeed.
+  EFI_INVALID_PARAMETER  -  Wrong parameters passed in.
+
+--*/
+{
+  EFI_LIST_ENTRY                    *List;
+  PCI_HOST_BRIDGE_INSTANCE          *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE          *RootBridgeInstance;
+  UINT8                             *Temp;
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ptr;
+  UINT64                            AddrLen;
+  UINT64                            Alignment;
+  UINT64                            Value;
+
+  //
+  // Check the input parameter: Configuration
+  //
+  if (Configuration == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  HostBridgeInstance  = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+  List                = HostBridgeInstance->Head.ForwardLink;
+
+  Temp = (UINT8 *) Configuration;
+  while (List != &HostBridgeInstance->Head) {
+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+    if (RootBridgeHandle == RootBridgeInstance->Handle) {
+      //
+      // Check the resource descriptors.
+      // If the Configuration includes one or more invalid resource descriptors, all the resource
+      // descriptors are ignored and the function returns EFI_INVALID_PARAMETER.
+      //
+      while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+        ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;
+        DEBUG ((EFI_D_INFO, " ptr->ResType:%x \n",ptr->ResType));
+        DEBUG ((EFI_D_INFO, "  ptr->AddrLen:0x%lx AddrRangeMin:0x%lx AddrRangeMax:0x%lx\n\n",ptr->AddrLen,ptr->AddrRangeMin,ptr->AddrRangeMax));
+
+        switch (ptr->ResType) {
+          case ACPI_ADDRESS_SPACE_TYPE_MEM:
+            if (ptr->AddrSpaceGranularity != 32 && ptr->AddrSpaceGranularity != 64) {
+              return EFI_INVALID_PARAMETER;
+            }
+            if (ptr->AddrSpaceGranularity == 32 && ptr->AddrLen > 0xffffffff) {
+              return EFI_INVALID_PARAMETER;
+            }
+            //
+            // If the PCI root bridge does not support separate windows for nonprefetchable and
+            // prefetchable memory, then the PCI bus driver needs to include requests for
+            // prefetchable memory in the nonprefetchable memory pool.
+            //
+            if ((RootBridgeInstance->RootBridgeAllocAttrib & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) != 0 &&
+                ((ptr->SpecificFlag & (BIT2 | BIT1)) != 0)) {
+              return EFI_INVALID_PARAMETER;
+            }
+          case ACPI_ADDRESS_SPACE_TYPE_IO:
+            //
+            // Check aligment, it should be of the form 2^n-1
+            //
+            Value = Power2MaxMemory (ptr->AddrRangeMax + 1);
+            if (Value != (ptr->AddrRangeMax + 1)) {
+              CpuDeadLoop();
+              return EFI_INVALID_PARAMETER;
+            }
+            break;
+          case ACPI_ADDRESS_SPACE_TYPE_BUS:
+          default:
+            return EFI_INVALID_PARAMETER;
+        }
+        Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) ;
+      }
+      if (*Temp != ACPI_END_TAG_DESCRIPTOR) {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      Temp = (UINT8 *) Configuration;
+      while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+        ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;
+
+        switch (ptr->ResType) {
+        case ACPI_ADDRESS_SPACE_TYPE_MEM:
+          AddrLen   = (UINT64) ptr->AddrLen;
+          Alignment = (UINT64) ptr->AddrRangeMax;
+          if (ptr->AddrSpaceGranularity == 32) {
+            if (ptr->SpecificFlag == 0x06) {
+              //
+              // Apply from GCD
+              //
+              RootBridgeInstance->ResAllocNode[TypePMem32].Status = ResSubmitted;
+            } else {
+              RootBridgeInstance->ResAllocNode[TypeMem32].Length    = AddrLen;
+              RootBridgeInstance->ResAllocNode[TypeMem32].Alignment = Alignment;
+              RootBridgeInstance->ResAllocNode[TypeMem32].Status    = ResRequested;
+              HostBridgeInstance->ResourceSubmited                  = TRUE;
+            }
+          }
+
+          if (ptr->AddrSpaceGranularity == 64) {
+            if (ptr->SpecificFlag == 0x06) {
+              RootBridgeInstance->ResAllocNode[TypePMem64].Status = ResSubmitted;
+            } else {
+              RootBridgeInstance->ResAllocNode[TypeMem64].Length    = AddrLen;
+              RootBridgeInstance->ResAllocNode[TypeMem64].Alignment = Alignment;
+              RootBridgeInstance->ResAllocNode[TypeMem64].Status    = ResSubmitted;
+              HostBridgeInstance->ResourceSubmited                  = TRUE;
+            }
+          }
+          break;
+
+        case ACPI_ADDRESS_SPACE_TYPE_IO:
+          AddrLen   = (UINT64) ptr->AddrLen;
+          Alignment = (UINT64) ptr->AddrRangeMax;
+          RootBridgeInstance->ResAllocNode[TypeIo].Length     = AddrLen;
+          RootBridgeInstance->ResAllocNode[TypeIo].Alignment  = Alignment;
+          RootBridgeInstance->ResAllocNode[TypeIo].Status     = ResRequested;
+          HostBridgeInstance->ResourceSubmited                = TRUE;
+          break;
+
+        default:
+          break;
+        }
+
+        Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
+      }
+
+      return EFI_SUCCESS;
+    }
+
+    List = List->ForwardLink;
+  }
+
+  return EFI_INVALID_PARAMETER;
+}
+
+EFI_STATUS
+EFIAPI
+GetProposedResources (
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN  EFI_HANDLE                                       RootBridgeHandle,
+  OUT VOID                                             **Configuration
+  )
+/*++
+
+Routine Description:
+  This function returns the proposed resource settings for the specified
+  PCI Root Bridge.
+
+Arguments:
+
+  This              -  The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+  RootBridgeHandle  -  The PCI Root Bridge handle.
+  Configuration     -  The pointer to the pointer to the PCI I/O
+                       and memory resource descriptor.
+
+Returns:
+
+  EFI_SUCCESS            -  Succeed.
+  EFI_OUT_OF_RESOURCES   -  Not enough pool to be allocated.
+  EFI_INVALID_PARAMETER  -  RootBridgeHandle is not a valid handle.
+
+--*/
+{
+  EFI_LIST_ENTRY                    *List;
+  PCI_HOST_BRIDGE_INSTANCE          *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE          *RootBridgeInstance;
+  UINTN                             Index;
+  UINTN                             Number;
+  VOID                              *Buffer;
+  UINT8                             *Temp;
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ptr;
+  EFI_STATUS                        Status;
+  UINT64                            ResStatus;
+
+  Buffer  = NULL;
+  Number  = 0;
+  //
+  // Get the Host Bridge Instance from the resource allocation protocol
+  //
+  HostBridgeInstance  = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+  List                = HostBridgeInstance->Head.ForwardLink;
+
+  //
+  // Enumerate the root bridges in this host bridge
+  //
+  while (List != &HostBridgeInstance->Head) {
+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+    if (RootBridgeHandle == RootBridgeInstance->Handle) {
+      for (Index = 0; Index < TypeBus; Index++) {
+        if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {
+          Number++;
+        }
+      }
+
+      if (Number > 0) {
+        Status = gBS->AllocatePool (
+                        EfiBootServicesData,
+                        Number * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR),
+                        &Buffer
+                        );
+
+        if (EFI_ERROR (Status)) {
+          return EFI_OUT_OF_RESOURCES;
+        }
+
+        ZeroMem (Buffer, sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * Number + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
+      }
+
+      ASSERT (Buffer != NULL);
+      Temp = Buffer;
+      for (Index = 0; Index < TypeBus; Index++) {
+        if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {
+          ptr       = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;
+          ResStatus = RootBridgeInstance->ResAllocNode[Index].Status;
+
+          switch (Index) {
+
+          case TypeIo:
+            //
+            // Io
+            //
+            ptr->Desc                   = 0x8A;
+            ptr->Len                    = 0x2B;
+            ptr->ResType                = 1;
+            ptr->GenFlag                = 0;
+            ptr->SpecificFlag           = 0;
+            ptr->AddrRangeMin           = RootBridgeInstance->ResAllocNode[Index].Base;
+            ptr->AddrRangeMax           = 0;
+            ptr->AddrTranslationOffset  = (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
+            ptr->AddrLen                = RootBridgeInstance->ResAllocNode[Index].Length;
+            break;
+
+          case TypeMem32:
+            //
+            // Memory 32
+            //
+            ptr->Desc                   = 0x8A;
+            ptr->Len                    = 0x2B;
+            ptr->ResType                = 0;
+            ptr->GenFlag                = 0;
+            ptr->SpecificFlag           = 0;
+            ptr->AddrSpaceGranularity   = 32;
+            ptr->AddrRangeMin           = RootBridgeInstance->ResAllocNode[Index].Base;
+            ptr->AddrRangeMax           = 0;
+            ptr->AddrTranslationOffset  = (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
+            ptr->AddrLen                = RootBridgeInstance->ResAllocNode[Index].Length;
+            break;
+
+          case TypePMem32:
+            //
+            // Prefetch memory 32
+            //
+            ptr->Desc                   = 0x8A;
+            ptr->Len                    = 0x2B;
+            ptr->ResType                = 0;
+            ptr->GenFlag                = 0;
+            ptr->SpecificFlag           = 6;
+            ptr->AddrSpaceGranularity   = 32;
+            ptr->AddrRangeMin           = 0;
+            ptr->AddrRangeMax           = 0;
+            ptr->AddrTranslationOffset  = EFI_RESOURCE_NONEXISTENT;
+            ptr->AddrLen                = 0;
+            break;
+
+          case TypeMem64:
+            //
+            // Memory 64
+            //
+            ptr->Desc                   = 0x8A;
+            ptr->Len                    = 0x2B;
+            ptr->ResType                = 0;
+            ptr->GenFlag                = 0;
+            ptr->SpecificFlag           = 0;
+            ptr->AddrSpaceGranularity   = 64;
+            ptr->AddrRangeMin           = RootBridgeInstance->ResAllocNode[Index].Base;
+            ptr->AddrRangeMax           = 0;
+            ptr->AddrTranslationOffset  = (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
+            ptr->AddrLen                = RootBridgeInstance->ResAllocNode[Index].Length;
+            break;
+
+          case TypePMem64:
+            //
+            // Prefetch memory 64
+            //
+            ptr->Desc                   = 0x8A;
+            ptr->Len                    = 0x2B;
+            ptr->ResType                = 0;
+            ptr->GenFlag                = 0;
+            ptr->SpecificFlag           = 6;
+            ptr->AddrSpaceGranularity   = 64;
+            ptr->AddrRangeMin           = 0;
+            ptr->AddrRangeMax           = 0;
+            ptr->AddrTranslationOffset  = EFI_RESOURCE_NONEXISTENT;
+            ptr->AddrLen                = 0;
+            break;
+          }
+
+          Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
+        }
+      }
+
+      ((EFI_ACPI_END_TAG_DESCRIPTOR *) Temp)->Desc      = 0x79;
+      ((EFI_ACPI_END_TAG_DESCRIPTOR *) Temp)->Checksum  = 0x0;
+
+      *Configuration = Buffer;
+
+      return EFI_SUCCESS;
+    }
+
+    List = List->ForwardLink;
+  }
+
+  return EFI_INVALID_PARAMETER;
+}
+
+EFI_STATUS
+EFIAPI
+PreprocessController (
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL          *This,
+  IN  EFI_HANDLE                                                RootBridgeHandle,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS               PciAddress,
+  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE              Phase
+  )
+/*++
+
+Routine Description:
+  This function is called for all the PCI controllers that the PCI
+  bus driver finds. Can be used to Preprogram the controller.
+
+Arguments:
+
+  This              -  The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+  RootBridgeHandle  -  The PCI Root Bridge handle.
+  PciAddress        -  Address of the controller on the PCI bus.
+  Phase             -  The Phase during resource allocation.
+
+Returns:
+
+  EFI_SUCCESS            -  Succeed.
+  EFI_INVALID_PARAMETER  -  RootBridgeHandle is not a valid handle.
+
+--*/
+{
+  BOOLEAN                   RootBridgeFound;
+  EFI_LIST_ENTRY            *List;
+  PCI_HOST_BRIDGE_INSTANCE  *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE  *RootBridgeInstance;
+
+  if (RootBridgeHandle == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  RootBridgeFound     = FALSE;
+  HostBridgeInstance  = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+  List                = HostBridgeInstance->Head.ForwardLink;
+
+  while (List != &HostBridgeInstance->Head) {
+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+
+    if (RootBridgeHandle == RootBridgeInstance->Handle) {
+      RootBridgeFound = TRUE;
+      break;
+    }
+    //
+    // Get next if have
+    //
+    List = List->ForwardLink;
+  }
+
+  if (RootBridgeFound == FALSE) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return EFI_SUCCESS;
+}
+
+UINT64
+Power2MaxMemory (
+  IN UINT64                     MemoryLength
+  )
+/*++
+
+Routine Description:
+
+  Calculate maximum memory length that can be fit to a mtrr.
+
+Arguments:
+
+  MemoryLength  -  Input memory length.
+
+Returns:
+
+  Returned Maximum length.
+
+--*/
+{
+  UINT64  Result;
+
+  if (RShiftU64 (MemoryLength, 32)) {
+    Result = LShiftU64 ((UINT64) GetPowerOfTwo64 ((UINT32) RShiftU64 (MemoryLength, 32)), 32);
+  } else {
+    Result = (UINT64) GetPowerOfTwo64 ((UINT32) MemoryLength);
+  }
+
+  return Result;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.h b/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.h
new file mode 100644
index 0000000000..3dddca2d26
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.h
@@ -0,0 +1,389 @@
+/** @file
+The Header file of the Pci Host Bridge Driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#ifndef _PCI_HOST_BRIDGE_H_
+#define _PCI_HOST_BRIDGE_H_
+
+
+#include <PiDxe.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/Pci.h>
+#include <PciRootBridge.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/UefiLib.h>
+#include <Guid/HobList.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+
+#define PCI_HOST_BRIDGE_SIGNATURE SIGNATURE_32 ('e', 'h', 's', 't')
+typedef struct {
+  UINTN                                             Signature;
+  EFI_HANDLE                                        HostBridgeHandle;
+  UINTN                                             RootBridgeCount;
+  EFI_LIST_ENTRY                                    Head;
+  BOOLEAN                                           ResourceSubmited;
+  BOOLEAN                                           CanRestarted;
+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  ResAlloc;
+} PCI_HOST_BRIDGE_INSTANCE;
+
+#define INSTANCE_FROM_RESOURCE_ALLOCATION_THIS(a) CR (a, PCI_HOST_BRIDGE_INSTANCE, ResAlloc, PCI_HOST_BRIDGE_SIGNATURE)
+
+typedef enum {
+  SocketResourceRatioChanged,
+  SocketResourceRatioNotChanged,
+  SocketResourceAdjustMax
+} SOCKET_RESOURCE_ADJUSTMENT_RESULT;
+
+//
+// Driver Entry Point
+//
+EFI_STATUS
+EFIAPI
+InitializePciHostBridge (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+/*++
+
+Routine Description:
+
+  Entry point of this driver.
+
+Arguments:
+
+  ImageHandle  -  Image handle of this driver.
+  SystemTable  -  Pointer to standard EFI system table.
+
+Returns:
+
+  EFI_SUCCESS       -  Succeed.
+  EFI_DEVICE_ERROR  -  Fail to install PCI_ROOT_BRIDGE_IO protocol.
+
+--*/
+;
+
+//
+//  HostBridge Resource Allocation interface
+//
+EFI_STATUS
+EFIAPI
+NotifyPhase (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL   *This,
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE      Phase
+  )
+/*++
+
+Routine Description:
+
+  Enter a certain phase of the PCI enumeration process.
+
+Arguments:
+
+  This   -  The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
+  Phase  -  The phase during enumeration.
+
+Returns:
+
+  EFI_SUCCESS            -  Succeed.
+  EFI_INVALID_PARAMETER  -  Wrong phase parameter passed in.
+  EFI_NOT_READY          -  Resources have not been submitted yet.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+GetNextRootBridge (
+  IN     EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN OUT EFI_HANDLE                                       *RootBridgeHandle
+  )
+/*++
+
+Routine Description:
+
+  Return the device handle of the next PCI root bridge that is associated with
+  this Host Bridge.
+
+Arguments:
+
+  This              - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+  RootBridgeHandle  -  Returns the device handle of the next PCI Root Bridge.
+                       On input, it holds the RootBridgeHandle returned by the most
+                       recent call to GetNextRootBridge().The handle for the first
+                       PCI Root Bridge is returned if RootBridgeHandle is NULL on input.
+
+Returns:
+
+  EFI_SUCCESS            -  Succeed.
+  EFI_NOT_FOUND          -  Next PCI root bridge not found.
+  EFI_INVALID_PARAMETER  -  Wrong parameter passed in.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+GetAttributes (
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN  EFI_HANDLE                                       RootBridgeHandle,
+  OUT UINT64                                           *Attributes
+  )
+/*++
+
+Routine Description:
+
+  Returns the attributes of a PCI Root Bridge.
+
+Arguments:
+
+  This              -  The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
+  RootBridgeHandle  -  The device handle of the PCI Root Bridge
+                       that the caller is interested in
+  Attributes        -  The pointer to attributes of the PCI Root Bridge
+
+Returns:
+
+  EFI_SUCCESS            -  Succeed.
+  EFI_INVALID_PARAMETER  -  Attributes parameter passed in is NULL or
+                            RootBridgeHandle is not an EFI_HANDLE
+                            that was returned on a previous call to
+                            GetNextRootBridge().
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+StartBusEnumeration (
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN  EFI_HANDLE                                       RootBridgeHandle,
+  OUT VOID                                             **Configuration
+  )
+/*++
+
+Routine Description:
+
+  This is the request from the PCI enumerator to set up
+  the specified PCI Root Bridge for bus enumeration process.
+
+Arguments:
+
+  This              -  The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+  RootBridgeHandle  -  The PCI Root Bridge to be set up.
+  Configuration     -  Pointer to the pointer to the PCI bus resource descriptor.
+
+Returns:
+
+  EFI_SUCCESS            -  Succeed.
+  EFI_OUT_OF_RESOURCES   -  Not enough pool to be allocated.
+  EFI_INVALID_PARAMETER  -  RootBridgeHandle is not a valid handle.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+SetBusNumbers (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_HANDLE                                       RootBridgeHandle,
+  IN VOID                                             *Configuration
+  )
+/*++
+
+Routine Description:
+
+  This function programs the PCI Root Bridge hardware so that
+  it decodes the specified PCI bus range.
+
+Arguments:
+
+  This              -  The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+  RootBridgeHandle  -  The PCI Root Bridge whose bus range is to be programmed.
+  Configuration     -  The pointer to the PCI bus resource descriptor.
+
+Returns:
+
+  EFI_SUCCESS            -  Succeed.
+  EFI_INVALID_PARAMETER  -  Wrong parameters passed in.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+SubmitResources (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_HANDLE                                       RootBridgeHandle,
+  IN VOID                                             *Configuration
+  )
+/*++
+
+Routine Description:
+
+  Submits the I/O and memory resource requirements for the specified PCI Root Bridge.
+
+Arguments:
+
+  This              -  The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
+  RootBridgeHandle  -  The PCI Root Bridge whose I/O and memory resource requirements
+                       are being submitted
+  Configuration     -  The pointer to the PCI I/O and PCI memory resource descriptor
+
+Returns:
+
+  EFI_SUCCESS            -  Succeed.
+  EFI_INVALID_PARAMETER  -  Wrong parameters passed in.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+GetProposedResources (
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN  EFI_HANDLE                                       RootBridgeHandle,
+  OUT VOID                                             **Configuration
+  )
+/*++
+
+Routine Description:
+
+  This function returns the proposed resource settings for the specified
+  PCI Root Bridge.
+
+Arguments:
+
+  This              -  The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+  RootBridgeHandle  -  The PCI Root Bridge handle.
+  Configuration     -  The pointer to the pointer to the PCI I/O
+                       and memory resource descriptor.
+
+Returns:
+
+  EFI_SUCCESS            -  Succeed.
+  EFI_OUT_OF_RESOURCES   -  Not enough pool to be allocated.
+  EFI_INVALID_PARAMETER  -  RootBridgeHandle is not a valid handle.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PreprocessController (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL          *This,
+  IN EFI_HANDLE                                                RootBridgeHandle,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS               PciAddress,
+  IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE              Phase
+  )
+/*++
+
+Routine Description:
+
+  This function is called for all the PCI controllers that the PCI
+  bus driver finds. Can be used to Preprogram the controller.
+
+Arguments:
+
+  This              -  The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+  RootBridgeHandle  -  The PCI Root Bridge handle.
+  PciAddress        -  Address of the controller on the PCI bus.
+  Phase             -  The Phase during resource allocation.
+
+Returns:
+
+  EFI_SUCCESS            -  Succeed.
+  EFI_INVALID_PARAMETER  -  RootBridgeHandle is not a valid handle.
+
+--*/
+;
+
+//
+// Host Bridge Silicon specific hooks
+//
+UINT64
+GetAllocAttributes (
+  IN  UINTN        RootBridgeIndex
+  )
+/*++
+
+Routine Description:
+
+  Returns the Allocation attributes for the BNB Root Bridge.
+
+Arguments:
+
+  RootBridgeIndex  -  The root bridge number. 0 based.
+
+Returns:
+
+  EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | EFI_PCI_HOST_BRIDGE_MEM64_DECODE
+
+--*/
+;
+
+EFI_STATUS
+GetHostBridgeMemApertures (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL               *PciRootBridgeIo,
+  OUT UINT32                                        *Mem32Base,
+  OUT UINT32                                        *Mem32Limit,
+  OUT UINT64                                        *Mem64Base,
+  OUT UINT64                                        *Mem64Limit
+  )
+/*++
+
+Routine Description:
+
+  Returns memory apertures for the BNB Root Bridge.
+
+Arguments:
+
+  PciRootBridgeIo  -  Pointer to Efi Pci root bridge Io protocol interface instance.
+  Mem32Base        -  Pointer to 32 bit memory base. This is the lowest 32 bit memory address
+                      that is decoded by the Host Bridge.
+  Mem32Limit       -  Pointer to 32 bit memory limit.This is the highest 32 bit memory address
+                      that is decoded by the Host Bridge. The size of the 32 bit window is
+                      (Mem32Limit - Mem32base + 1).
+  Mem64Base        -  Pointer to 64 bit memory base. This is the lowest 64 bit memory address
+                      that is decoded by the Host Bridge.
+  Mem64Limit       -  Pointer to 64 bit memory limit.This is the highest 64 bit memory address
+                      that is decoded by the Host Bridge. The size of the 64 bit window is
+                      (Mem64Limit - Mem64base + 1). Set Mem64Limit < Mem64Base if the host bridge
+                      does not support 64 bit memory addresses.
+
+Returns:
+
+  EFI_SUCCESS  -  Success.
+
+--*/
+;
+
+UINT64
+Power2MaxMemory (
+  IN UINT64         MemoryLength
+  )
+/*++
+
+Routine Description:
+
+  Calculate maximum memory length that can be fit to a mtrr.
+
+Arguments:
+
+  MemoryLength  -  Input memory length.
+
+Returns:
+
+  Returned Maximum length.
+
+--*/
+;
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.inf b/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.inf
new file mode 100644
index 0000000000..adf36f6632
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.inf
@@ -0,0 +1,61 @@
+## @file
+# Component description file for PciHostBridge module
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PciHostBridge
+  FILE_GUID                      = D58EBCE1-AF26-488d-BE66-C164417F8C13
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = InitializePciHostBridge
+
+[Sources]
+  PciHostBridge.h
+  PciRootBridge.h
+  PciHostBridge.c
+  PciRootBridgeIo.c
+  PciHostBridgeSupport.c
+  PciHostResource.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  DebugLib
+  UefiLib
+  DxeServicesTableLib
+  UefiRuntimeServicesTableLib
+  DevicePathLib
+  BaseMemoryLib
+  BaseLib
+
+[Protocols]
+  gEfiMetronomeArchProtocolGuid
+  gEfiCpuIo2ProtocolGuid
+  gEfiDevicePathProtocolGuid
+  gEfiPciRootBridgeIoProtocolGuid
+  gEfiPciHostBridgeResourceAllocationProtocolGuid
+
+[Pcd]
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeIoBase
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeIoSize
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeMemory32Base
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeMemory32Size
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeMemory64Base
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeMemory64Size
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciExpressSize
+
+[Depex]
+  gEfiCpuIo2ProtocolGuid AND gEfiMetronomeArchProtocolGuid
diff --git a/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridgeSupport.c b/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridgeSupport.c
new file mode 100644
index 0000000000..774d658f3a
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridgeSupport.c
@@ -0,0 +1,140 @@
+/** @file
+Do platform initialization for PCI bridge.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#include "PciHostBridge.h"
+
+EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *mPciRootBridgeIo;
+
+EFI_STATUS
+ChipsetPreprocessController (
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL          *This,
+  IN  EFI_HANDLE                                                RootBridgeHandle,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS               PciAddress,
+  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE              Phase
+  )
+/*++
+
+Routine Description:
+  This function is called for all the PCI controllers that the PCI
+  bus driver finds. Can be used to Preprogram the controller.
+
+Arguments:
+  This             -- The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
+  RootBridgeHandle -- The PCI Root Bridge handle
+  PciBusAddress    -- Address of the controller on the PCI bus
+  Phase            -- The Phase during resource allocation
+
+Returns:
+  EFI_SUCCESS
+
+--*/
+
+// GC_TODO:    PciAddress - add argument and description to function comment
+//
+// GC_TODO:    PciAddress - add argument and description to function comment
+//
+// GC_TODO:    PciAddress - add argument and description to function comment
+//
+// GC_TODO:    PciAddress - add argument and description to function comment
+//
+{
+
+  EFI_STATUS  Status;
+  UINT8       Latency;
+  UINT8       CacheLineSize;
+
+  if (mPciRootBridgeIo == NULL) {
+    //
+    // Get root bridge in the system.
+    //
+    Status = gBS->HandleProtocol (RootBridgeHandle, &gEfiPciRootBridgeIoProtocolGuid, (VOID **) &mPciRootBridgeIo);
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  if (Phase == EfiPciBeforeResourceCollection) {
+    //
+    // Program the latency register, CLS register
+    //
+    PciAddress.Register = PCI_LATENCY_TIMER_OFFSET;
+    mPciRootBridgeIo->Pci.Read (
+                            mPciRootBridgeIo,
+                            EfiPciWidthUint8,
+                            *((UINT64 *) &PciAddress),
+                            1,
+                            &Latency
+                            );
+
+    //
+    // PCI-x cards come up with a default latency of 0x40. Don't touch them.
+    //
+    if (Latency == 0) {
+      Latency = DEFAULT_PCI_LATENCY;
+      mPciRootBridgeIo->Pci.Write (
+                              mPciRootBridgeIo,
+                              EfiPciWidthUint8,
+                              *((UINT64 *) &PciAddress),
+                              1,
+                              &Latency
+                              );
+    }
+    //
+    // Program Cache Line Size as 64bytes
+    // 16 of DWORDs = 64bytes (0x10)
+    //
+    PciAddress.Register = PCI_CACHELINE_SIZE_OFFSET;
+    CacheLineSize       = 0x10;
+    mPciRootBridgeIo->Pci.Write (
+                            mPciRootBridgeIo,
+                            EfiPciWidthUint8,
+                            *((UINT64 *) &PciAddress),
+                            1,
+                            &CacheLineSize
+                            );
+
+  }
+
+  return EFI_SUCCESS;
+}
+
+UINT64
+GetAllocAttributes (
+  IN  UINTN        RootBridgeIndex
+  )
+/*++
+
+Routine Description:
+
+  Returns the Allocation attributes for the BNB Root Bridge.
+
+Arguments:
+
+  RootBridgeIndex  -  The root bridge number. 0 based.
+
+Returns:
+
+  EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | EFI_PCI_HOST_BRIDGE_MEM64_DECODE
+
+--*/
+{
+  //
+  // Cannot have more than one Root bridge
+  //
+  //ASSERT (RootBridgeIndex == 0);
+
+  //
+  // PCI Root Bridge does not support separate windows for Non-prefetchable
+  // and Prefetchable memory. A PCI bus driver needs to include requests for
+  // Prefetchable memory in the Non-prefetchable memory pool.
+  // Further TNB does not support 64 bit memory apertures for PCI. BNB
+  // can only have system memory above 4 GB,
+  //
+
+    return EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | EFI_PCI_HOST_BRIDGE_MEM64_DECODE;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostResource.h b/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostResource.h
new file mode 100644
index 0000000000..da7d55d503
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostResource.h
@@ -0,0 +1,60 @@
+/** @file
+The Header file of the Pci Host Bridge Driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#ifndef _PCI_HOST_RESOURCE_H_
+#define _PCI_HOST_RESOURCE_H_
+
+#include <PiDxe.h>
+
+#define EFI_RESOURCE_NONEXISTENT  0xFFFFFFFFFFFFFFFFULL
+#define EFI_RESOURCE_LESS         0xFFFFFFFFFFFFFFFEULL
+
+typedef struct {
+  UINTN   BusBase;
+  UINTN   BusLimit;
+  UINTN   BusReserve;
+
+  UINT32  Mem32Base;
+  UINT32  Mem32Limit;
+
+  UINT64  Mem64Base;
+  UINT64  Mem64Limit;
+
+  UINTN   IoBase;
+  UINTN   IoLimit;
+} PCI_ROOT_BRIDGE_RESOURCE_APERTURE;
+
+typedef enum {
+  TypeIo    = 0,
+  TypeMem32,
+  TypePMem32,
+  TypeMem64,
+  TypePMem64,
+  TypeBus,
+  TypeMax
+} PCI_RESOURCE_TYPE;
+
+typedef enum {
+  ResNone     = 0,
+  ResSubmitted,
+  ResRequested,
+  ResAllocated,
+  ResStatusMax
+} RES_STATUS;
+
+typedef struct {
+  PCI_RESOURCE_TYPE Type;
+  UINT64            Base;
+  UINT64            Length;
+  UINT64            Alignment;
+  RES_STATUS        Status;
+} PCI_RES_NODE;
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridge.h b/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridge.h
new file mode 100644
index 0000000000..613265d2ff
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridge.h
@@ -0,0 +1,693 @@
+/** @file
+The PCI Root Bridge header file.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#ifndef _PCI_ROOT_BRIDGE_H_
+#define _PCI_ROOT_BRIDGE_H_
+
+#include <PiDxe.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/Pci.h>
+#include <PciHostResource.h>
+
+//
+// Driver Consumed Protocol Prototypes
+//
+#include <Protocol/Metronome.h>
+#include <Protocol/CpuIo2.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/Runtime.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
+
+
+//
+// Define the region of memory used for DMA memory
+//
+#define DMA_MEMORY_TOP          0x0000000001FFFFFFULL
+
+//
+// The number of PCI root bridges
+//
+#define ROOT_BRIDGE_COUNT  1
+
+//
+// The default latency for controllers
+//
+#define DEFAULT_PCI_LATENCY 0x20
+
+//
+// Define resource status constant
+//
+typedef struct {
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation;
+  UINTN                                     NumberOfBytes;
+  UINTN                                     NumberOfPages;
+  EFI_PHYSICAL_ADDRESS                      HostAddress;
+  EFI_PHYSICAL_ADDRESS                      MappedHostAddress;
+} MAP_INFO;
+
+typedef struct {
+  ACPI_HID_DEVICE_PATH      AcpiDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  EndDevicePath;
+} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
+
+#define PCI_ROOT_BRIDGE_SIGNATURE SIGNATURE_32 ('e', '2', 'p', 'b')
+
+typedef struct {
+  UINT32                            Signature;
+  EFI_LIST_ENTRY                    Link;
+  EFI_HANDLE                        Handle;
+  UINT64                            RootBridgeAllocAttrib;
+  UINT64                            Attributes;
+  UINT64                            Supports;
+  PCI_RES_NODE                      ResAllocNode[6];
+  PCI_ROOT_BRIDGE_RESOURCE_APERTURE Aperture;
+  EFI_LOCK                          PciLock;
+  UINTN                             PciAddress;
+  UINTN                             PciData;
+  UINT32                            HecBase;
+  UINT32                            HecLen;
+  UINTN                             BusScanCount;
+  BOOLEAN                           BusNumberAssigned;
+  VOID                              *ConfigBuffer;
+  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL   Io;
+} PCI_ROOT_BRIDGE_INSTANCE;
+
+//
+// Driver Instance Data Macros
+//
+#define DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(a) CR (a, PCI_ROOT_BRIDGE_INSTANCE, Io, PCI_ROOT_BRIDGE_SIGNATURE)
+
+#define DRIVER_INSTANCE_FROM_LIST_ENTRY(a)              CR (a, PCI_ROOT_BRIDGE_INSTANCE, Link, PCI_ROOT_BRIDGE_SIGNATURE)
+
+EFI_STATUS
+SimpleIioRootBridgeConstructor (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL    *Protocol,
+  IN EFI_HANDLE                         HostBridgeHandle,
+  IN PCI_ROOT_BRIDGE_RESOURCE_APERTURE  *ResAppeture,
+  IN UINT64                             AllocAttributes
+  )
+/*++
+
+Routine Description:
+
+  Construct the Pci Root Bridge Io protocol.
+
+Arguments:
+
+  Protocol          -  Protocol to initialize.
+  HostBridgeHandle  -  Handle to the HostBridge.
+  ResAppeture       -  Resource apperture of the root bridge.
+  AllocAttributes   -  Attribute of resouce allocated.
+
+Returns:
+
+  EFI_SUCCESS  -  Success.
+  Others       -  Fail.
+
+--*/
+;
+
+//
+// Protocol Member Function Prototypes
+//
+EFI_STATUS
+EFIAPI
+RootBridgeIoPollMem (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN  UINT64                                 Address,
+  IN  UINT64                                 Mask,
+  IN  UINT64                                 Value,
+  IN  UINT64                                 Delay,
+  OUT UINT64                                 *Result
+  )
+/*++
+
+Routine Description:
+
+  Poll an address in memory mapped space until an exit condition is met
+  or a timeout occurs.
+
+Arguments:
+
+  This     -  Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+  Width    -  Width of the memory operation.
+  Address  -  The base address of the memory operation.
+  Mask     -  Mask used for polling criteria.
+  Value    -  Comparison value used for polling exit criteria.
+  Delay    -  Number of 100ns units to poll.
+  Result   -  Pointer to the last value read from memory location.
+
+Returns:
+
+  EFI_SUCCESS            -  Success.
+  EFI_INVALID_PARAMETER  -  Invalid parameter found.
+  EFI_TIMEOUT            -  Delay expired before a match occurred.
+  EFI_OUT_OF_RESOURCES   -  Fail due to lack of resources.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoPollIo (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN  UINT64                                 Address,
+  IN  UINT64                                 Mask,
+  IN  UINT64                                 Value,
+  IN  UINT64                                 Delay,
+  OUT UINT64                                 *Result
+  )
+/*++
+
+Routine Description:
+
+  Poll an address in I/O space until an exit condition is met
+  or a timeout occurs.
+
+Arguments:
+
+  This     -  Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+  Width    -  Width of I/O operation.
+  Address  -  The base address of the I/O operation.
+  Mask     -  Mask used for polling criteria.
+  Value    -  Comparison value used for polling exit criteria.
+  Delay    -  Number of 100ns units to poll.
+  Result   -  Pointer to the last value read from memory location.
+
+Returns:
+
+  EFI_SUCCESS            -  Success.
+  EFI_INVALID_PARAMETER  -  Invalid parameter found.
+  EFI_TIMEOUT            -  Delay expired before a match occurred.
+  EFI_OUT_OF_RESOURCES   -  Fail due to lack of resources.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoMemRead (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 Address,
+  IN     UINTN                                  Count,
+  IN OUT VOID                                   *Buffer
+  )
+/*++
+
+Routine Description:
+
+  Allow read from memory mapped I/O space.
+
+Arguments:
+
+  This     -  Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+  Width    -  The width of memory operation.
+  Address  -  Base address of the memory operation.
+  Count    -  Number of memory opeartion to perform.
+  Buffer   -  The destination buffer to store data.
+
+Returns:
+
+  EFI_SUCCESS            -  Success.
+  EFI_INVALID_PARAMETER  -  Invalid parameter found.
+  EFI_OUT_OF_RESOURCES   -  Fail due to lack of resources.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoMemWrite (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 Address,
+  IN     UINTN                                  Count,
+  IN OUT VOID                                   *Buffer
+  )
+/*++
+
+Routine Description:
+
+  Allow write to memory mapped I/O space.
+
+Arguments:
+
+  This     -  Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+  Width    -  The width of memory operation.
+  Address  -  Base address of the memory operation.
+  Count    -  Number of memory opeartion to perform.
+  Buffer   -  The source buffer to write data from.
+
+Returns:
+
+  EFI_SUCCESS            -  Success.
+  EFI_INVALID_PARAMETER  -  Invalid parameter found.
+  EFI_OUT_OF_RESOURCES   -  Fail due to lack of resources.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoIoRead (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 UserAddress,
+  IN     UINTN                                  Count,
+  IN OUT VOID                                   *UserBuffer
+  )
+/*++
+
+Routine Description:
+
+  Enable a PCI driver to read PCI controller registers in the
+  PCI root bridge I/O space.
+
+Arguments:
+
+  This         -  A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+  Width        -  Signifies the width of the memory operation.
+  UserAddress  -  The base address of the I/O operation.
+  Count        -  The number of I/O operations to perform.
+  UserBuffer   -  The destination buffer to store the results.
+
+Returns:
+
+  EFI_SUCCESS            -  The data was read from the PCI root bridge.
+  EFI_INVALID_PARAMETER  -  Invalid parameters found.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to a lack of
+                            resources.
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoIoWrite (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 UserAddress,
+  IN     UINTN                                  Count,
+  IN OUT VOID                                   *UserBuffer
+  )
+/*++
+
+Routine Description:
+
+  Enable a PCI driver to write to PCI controller registers in the
+  PCI root bridge I/O space.
+
+Arguments:
+
+  This         -  A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+  Width        -  Signifies the width of the memory operation.
+  UserAddress  -  The base address of the I/O operation.
+  Count        -  The number of I/O operations to perform.
+  UserBuffer   -  The source buffer to write data from.
+
+Returns:
+
+  EFI_SUCCESS            -  The data was written to the PCI root bridge.
+  EFI_INVALID_PARAMETER  -  Invalid parameters found.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to a lack of
+                            resources.
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoCopyMem (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL          *This,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
+  IN UINT64                                   DestAddress,
+  IN UINT64                                   SrcAddress,
+  IN UINTN                                    Count
+  )
+/*++
+
+Routine Description:
+
+  Copy one region of PCI root bridge memory space to be copied to
+  another region of PCI root bridge memory space.
+
+Arguments:
+
+  This         -  A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+  Width        -  Signifies the width of the memory operation.
+  DestAddress  -  Destination address of the memory operation.
+  SrcAddress   -  Source address of the memory operation.
+  Count        -  Number of memory operations to perform.
+
+Returns:
+
+  EFI_SUCCESS            -  The data was copied successfully.
+  EFI_INVALID_PARAMETER  -  Invalid parameters found.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to a lack of
+                            resources.
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoPciRead (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 Address,
+  IN     UINTN                                  Count,
+  IN OUT VOID                                   *Buffer
+  )
+/*++
+
+Routine Description:
+
+  Allows read from PCI configuration space.
+
+Arguments:
+
+  This     -  A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+  Width    -  Signifies the width of the memory operation.
+  Address  -  The address within the PCI configuration space
+              for the PCI controller.
+  Count    -  The number of PCI configuration operations
+              to perform.
+  Buffer   -  The destination buffer to store the results.
+
+Returns:
+
+  EFI_SUCCESS            -  The data was read from the PCI root bridge.
+  EFI_INVALID_PARAMETER  -  Invalid parameters found.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to a lack of
+                            resources.
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoPciWrite (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 Address,
+  IN     UINTN                                  Count,
+  IN OUT VOID                                   *Buffer
+  )
+/*++
+
+Routine Description:
+
+  Allows write to PCI configuration space.
+
+Arguments:
+
+  This     -  A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+  Width    -  Signifies the width of the memory operation.
+  Address  -  The address within the PCI configuration space
+              for the PCI controller.
+  Count    -  The number of PCI configuration operations
+              to perform.
+  Buffer   -  The source buffer to get the results.
+
+Returns:
+
+  EFI_SUCCESS            -  The data was written to the PCI root bridge.
+  EFI_INVALID_PARAMETER  -  Invalid parameters found.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to a lack of
+                            resources.
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoMap (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL            *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION  Operation,
+  IN     VOID                                       *HostAddress,
+  IN OUT UINTN                                      *NumberOfBytes,
+  OUT    EFI_PHYSICAL_ADDRESS                       *DeviceAddress,
+  OUT    VOID                                       **Mapping
+  )
+/*++
+
+Routine Description:
+
+  Provides the PCI controller-specific address needed to access
+  system memory for DMA.
+
+Arguments:
+
+  This           -  A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+  Operation      -  Indicate if the bus master is going to read or write
+                    to system memory.
+  HostAddress    -  The system memory address to map on the PCI controller.
+  NumberOfBytes  -  On input the number of bytes to map.
+                    On output the number of bytes that were mapped.
+  DeviceAddress  -  The resulting map address for the bus master PCI
+                    controller to use to access the system memory's HostAddress.
+  Mapping        -  The value to pass to Unmap() when the bus master DMA
+                    operation is complete.
+
+Returns:
+
+  EFI_SUCCESS            -  Success.
+  EFI_INVALID_PARAMETER  -  Invalid parameters found.
+  EFI_UNSUPPORTED        -  The HostAddress cannot be mapped as a common
+                            buffer.
+  EFI_DEVICE_ERROR       -  The System hardware could not map the requested
+                            address.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to
+                            lack of resources.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoUnmap (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
+  IN  VOID                             *Mapping
+  )
+/*++
+
+Routine Description:
+
+  Completes the Map() operation and releases any corresponding resources.
+
+Arguments:
+
+  This     -  Pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+  Mapping  -  The value returned from Map() operation.
+
+Returns:
+
+  EFI_SUCCESS            -  The range was unmapped successfully.
+  EFI_INVALID_PARAMETER  -  Mapping is not a value that was returned
+                            by Map operation.
+  EFI_DEVICE_ERROR       -  The data was not committed to the target
+                            system memory.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoAllocateBuffer (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
+  IN  EFI_ALLOCATE_TYPE                Type,
+  IN  EFI_MEMORY_TYPE                  MemoryType,
+  IN  UINTN                            Pages,
+  OUT VOID                             **HostAddress,
+  IN  UINT64                           Attributes
+  )
+/*++
+
+Routine Description:
+
+  Allocates pages that are suitable for a common buffer mapping.
+
+Arguments:
+
+  This         -  Pointer to EFI_ROOT_BRIDGE_IO_PROTOCOL instance.
+  Type         -  Not used and can be ignored.
+  MemoryType   -  Type of memory to allocate.
+  Pages        -  Number of pages to allocate.
+  HostAddress  -  Pointer to store the base system memory address
+                  of the allocated range.
+  Attributes   -  Requested bit mask of attributes of the allocated
+                  range.
+
+Returns:
+
+  EFI_SUCCESS            -  The requested memory range were allocated.
+  EFI_INVALID_PARAMETER  -  Invalid parameter found.
+  EFI_UNSUPPORTED        -  Attributes is unsupported.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoFreeBuffer (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
+  IN  UINTN                            Pages,
+  OUT VOID                             *HostAddress
+  )
+/*++
+
+Routine Description:
+
+  Free memory allocated in AllocateBuffer.
+
+Arguments:
+
+  This         -  Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+                  instance.
+  Pages        -  Number of pages to free.
+  HostAddress  -  The base system memory address of the
+                  allocated range.
+
+Returns:
+
+  EFI_SUCCESS            -  Requested memory pages were freed.
+  EFI_INVALID_PARAMETER  -  Invalid parameter found.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoFlush (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This
+  )
+/*++
+
+Routine Description:
+
+  Flushes all PCI posted write transactions from a PCI host
+  bridge to system memory.
+
+Arguments:
+
+  This  - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+
+Returns:
+
+  EFI_SUCCESS       -  PCI posted write transactions were flushed
+                       from PCI host bridge to system memory.
+  EFI_DEVICE_ERROR  -  Fail due to hardware error.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoGetAttributes (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
+  OUT UINT64                           *Supported,
+  OUT UINT64                           *Attributes
+  )
+/*++
+
+Routine Description:
+
+  Get the attributes that a PCI root bridge supports and
+  the attributes the PCI root bridge is currently using.
+
+Arguments:
+
+  This        -  Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+                 instance.
+  Supports    -  A pointer to the mask of attributes that
+                 this PCI root bridge supports.
+  Attributes  -  A pointer to the mask of attributes that
+                 this PCI root bridge is currently using.
+Returns:
+
+  EFI_SUCCESS            -  Success.
+  EFI_INVALID_PARAMETER  -  Invalid parameter found.
+
+--*/
+
+// GC_TODO:    Supported - add argument and description to function comment
+//
+// GC_TODO:    Supported - add argument and description to function comment
+//
+// GC_TODO:    Supported - add argument and description to function comment
+//
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoSetAttributes (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
+  IN     UINT64                           Attributes,
+  IN OUT UINT64                           *ResourceBase,
+  IN OUT UINT64                           *ResourceLength
+  )
+/*++
+
+Routine Description:
+
+  Sets the attributes for a resource range on a PCI root bridge.
+
+Arguments:
+
+  This            -  Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+  Attributes      -  The mask of attributes to set.
+  ResourceBase    -  Pointer to the base address of the resource range
+                     to be modified by the attributes specified by Attributes.
+  ResourceLength  -  Pointer to the length of the resource range to be modified.
+
+Returns:
+  EFI_SUCCESS            -  Success.
+  EFI_INVALID_PARAMETER  -  Invalid parameter found.
+  EFI_OUT_OF_RESOURCES   -  Not enough resources to set the attributes upon.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoConfiguration (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
+  OUT VOID                             **Resources
+  )
+/*++
+
+Routine Description:
+
+  Retrieves the current resource settings of this PCI root bridge
+  in the form of a set of ACPI 2.0 resource descriptor.
+
+Arguments:
+
+  This       -  Pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+  Resources  -  Pointer to the ACPI 2.0 resource descriptor that
+                describe the current configuration of this PCI root
+                bridge.
+
+Returns:
+
+  EFI_SUCCESS      -  Success.
+  EFI_UNSUPPORTED  -  Current configuration of the PCI root bridge
+                      could not be retrieved.
+
+--*/
+;
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridgeIo.c b/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridgeIo.c
new file mode 100644
index 0000000000..12b2e18720
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridgeIo.c
@@ -0,0 +1,1610 @@
+/** @file
+IIO PCI Root Bridge Io Protocol code. Generic enough to work for all IIOs.
+Does not support configuration accesses to the extended PCI Express registers yet.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#include "PciRootBridge.h"
+
+//
+// Define PCI express offse
+//
+#define PCIE_OFF(Bus, Device, Function, Register) \
+    ((UINT64) ((UINTN) (Bus << 20) + (UINTN) (Device << 15) + (UINTN) (Function << 12) + (UINTN) (Register)))
+
+//
+// Pci Root Bridge Io Module Variables
+//
+EFI_METRONOME_ARCH_PROTOCOL *mMetronome;
+EFI_CPU_IO2_PROTOCOL        *mCpuIo;
+
+EFI_STATUS
+SimpleIioRootBridgeConstructor (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *Protocol,
+  IN EFI_HANDLE                            HostBridgeHandle,
+  IN PCI_ROOT_BRIDGE_RESOURCE_APERTURE     *ResAperture,
+  UINT64                                   AllocAttributes
+  )
+/*++
+
+Routine Description:
+
+  Construct the Pci Root Bridge Io protocol.
+
+Arguments:
+
+  Protocol          -  Protocol to initialize.
+  HostBridgeHandle  -  Handle to the HostBridge.
+  ResAperture       -  Resource apperture of the root bridge.
+  AllocAttributes   -  Attribute of resouce allocated.
+
+Returns:
+
+  EFI_SUCCESS  -  Success.
+  Others       -  Fail.
+
+--*/
+{
+  EFI_STATUS                Status;
+  PCI_ROOT_BRIDGE_INSTANCE  *PrivateData;
+  PCI_RESOURCE_TYPE         Index;
+  UINT32                    HecBase;
+  UINT32                    HecSize;
+
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (Protocol);
+
+  //
+  // Initialize the apertures with default values
+  //
+  CopyMem (
+    &PrivateData->Aperture,
+    ResAperture,
+    sizeof (PCI_ROOT_BRIDGE_RESOURCE_APERTURE)
+    );
+
+  for (Index = TypeIo; Index < TypeMax; Index++) {
+    PrivateData->ResAllocNode[Index].Type   = Index;
+    PrivateData->ResAllocNode[Index].Base   = 0;
+    PrivateData->ResAllocNode[Index].Length = 0;
+    PrivateData->ResAllocNode[Index].Status = ResNone;
+  }
+
+  EfiInitializeLock (&PrivateData->PciLock, TPL_HIGH_LEVEL);
+  PrivateData->PciAddress             = 0xCF8;
+  PrivateData->PciData                = 0xCFC;
+
+  PrivateData->RootBridgeAllocAttrib  = AllocAttributes;
+  PrivateData->Attributes             = 0;
+  PrivateData->Supports = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO |
+    EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO |
+    EFI_PCI_ATTRIBUTE_ISA_IO_16         |
+    EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16 |
+    EFI_PCI_ATTRIBUTE_VGA_MEMORY |
+    EFI_PCI_ATTRIBUTE_VGA_IO_16;
+
+  //
+  // Don't support BASE above 4GB currently
+  // Position to bit 39:28
+  //
+  HecBase = (UINT32) PcdGet64 (PcdPciExpressBaseAddress);
+  HecSize = (UINT32) PcdGet64 (PcdPciExpressSize);
+
+  ASSERT ((HecBase & (HecSize - 1)) == 0);
+  ASSERT (HecBase != 0);
+
+  PrivateData->HecBase            = HecBase;
+  PrivateData->HecLen             = HecSize;
+
+  PrivateData->BusNumberAssigned  = FALSE;
+  PrivateData->BusScanCount       = 0;
+
+  Protocol->ParentHandle          = HostBridgeHandle;
+
+  Protocol->PollMem               = RootBridgeIoPollMem;
+  Protocol->PollIo                = RootBridgeIoPollIo;
+
+  Protocol->Mem.Read              = RootBridgeIoMemRead;
+  Protocol->Mem.Write             = RootBridgeIoMemWrite;
+
+  Protocol->Io.Read               = RootBridgeIoIoRead;
+  Protocol->Io.Write              = RootBridgeIoIoWrite;
+
+  Protocol->CopyMem               = RootBridgeIoCopyMem;
+
+  Protocol->Pci.Read              = RootBridgeIoPciRead;
+  Protocol->Pci.Write             = RootBridgeIoPciWrite;
+
+  Protocol->Map                   = RootBridgeIoMap;
+  Protocol->Unmap                 = RootBridgeIoUnmap;
+
+  Protocol->AllocateBuffer        = RootBridgeIoAllocateBuffer;
+  Protocol->FreeBuffer            = RootBridgeIoFreeBuffer;
+
+  Protocol->Flush                 = RootBridgeIoFlush;
+
+  Protocol->GetAttributes         = RootBridgeIoGetAttributes;
+  Protocol->SetAttributes         = RootBridgeIoSetAttributes;
+
+  Protocol->Configuration         = RootBridgeIoConfiguration;
+
+  Protocol->SegmentNumber         = 0;
+
+  Status                          = gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (VOID **) &mMetronome);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gBS->LocateProtocol (
+                  &gEfiCpuIo2ProtocolGuid,
+                  NULL,
+                  (VOID **) &mCpuIo
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoPollMem (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN  UINT64                                 Address,
+  IN  UINT64                                 Mask,
+  IN  UINT64                                 Value,
+  IN  UINT64                                 Delay,
+  OUT UINT64                                 *Result
+  )
+/*++
+
+Routine Description:
+
+  Poll an address in memory mapped space until an exit condition is met
+  or a timeout occurs.
+
+Arguments:
+
+  This     -  Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+  Width    -  Width of the memory operation.
+  Address  -  The base address of the memory operation.
+  Mask     -  Mask used for polling criteria.
+  Value    -  Comparison value used for polling exit criteria.
+  Delay    -  Number of 100ns units to poll.
+  Result   -  Pointer to the last value read from memory location.
+
+Returns:
+
+  EFI_SUCCESS            -  Success.
+  EFI_INVALID_PARAMETER  -  Invalid parameter found.
+  EFI_TIMEOUT            -  Delay expired before a match occurred.
+  EFI_OUT_OF_RESOURCES   -  Fail due to lack of resources.
+
+--*/
+{
+  EFI_STATUS  Status;
+  UINT64      NumberOfTicks;
+  UINT32       Remainder;
+
+  if (Result == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width < 0 || Width > EfiPciWidthUint64) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // No matter what, always do a single poll.
+  //
+  Status = This->Mem.Read (
+                      This,
+                      Width,
+                      Address,
+                      1,
+                      Result
+                      );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if ((*Result & Mask) == Value) {
+    return EFI_SUCCESS;
+  }
+
+  if (Delay != 0) {
+    //
+    // Determine the proper # of metronome ticks to wait for polling the
+    // location.  The nuber of ticks is Roundup (Delay / mMetronome->TickPeriod)+1
+    // The "+1" to account for the possibility of the first tick being short
+    // because we started in the middle of a tick.
+    //
+    // BugBug: overriding mMetronome->TickPeriod with UINT32 until Metronome
+    // protocol definition is updated.
+    //
+    NumberOfTicks = DivU64x32Remainder (
+                      Delay,
+                      (UINT32) mMetronome->TickPeriod,
+                      &Remainder
+                      );
+    if (Remainder != 0) {
+      NumberOfTicks += 1;
+    }
+
+    NumberOfTicks += 1;
+
+    while (NumberOfTicks) {
+
+      mMetronome->WaitForTick (mMetronome, 1);
+
+      Status = This->Mem.Read (
+                          This,
+                          Width,
+                          Address,
+                          1,
+                          Result
+                          );
+      if (EFI_ERROR (Status)) {
+        return Status;
+      }
+
+      if ((*Result & Mask) == Value) {
+        return EFI_SUCCESS;
+      }
+
+      NumberOfTicks -= 1;
+    }
+  }
+
+  return EFI_TIMEOUT;
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoPollIo (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN  UINT64                                 Address,
+  IN  UINT64                                 Mask,
+  IN  UINT64                                 Value,
+  IN  UINT64                                 Delay,
+  OUT UINT64                                 *Result
+  )
+/*++
+
+Routine Description:
+
+  Poll an address in I/O space until an exit condition is met
+  or a timeout occurs.
+
+Arguments:
+
+  This     -  Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+  Width    -  Width of I/O operation.
+  Address  -  The base address of the I/O operation.
+  Mask     -  Mask used for polling criteria.
+  Value    -  Comparison value used for polling exit criteria.
+  Delay    -  Number of 100ns units to poll.
+  Result   -  Pointer to the last value read from memory location.
+
+Returns:
+
+  EFI_SUCCESS            -  Success.
+  EFI_INVALID_PARAMETER  -  Invalid parameter found.
+  EFI_TIMEOUT            -  Delay expired before a match occurred.
+  EFI_OUT_OF_RESOURCES   -  Fail due to lack of resources.
+
+--*/
+{
+  EFI_STATUS  Status;
+  UINT64      NumberOfTicks;
+  UINT32       Remainder;
+
+  //
+  // No matter what, always do a single poll.
+  //
+  if (Result == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width < 0 || Width > EfiPciWidthUint64) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = This->Io.Read (
+                      This,
+                      Width,
+                      Address,
+                      1,
+                      Result
+                      );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if ((*Result & Mask) == Value) {
+    return EFI_SUCCESS;
+  }
+
+  if (Delay != 0) {
+    //
+    // Determine the proper # of metronome ticks to wait for polling the
+    // location.  The number of ticks is Roundup (Delay / mMetronome->TickPeriod)+1
+    // The "+1" to account for the possibility of the first tick being short
+    // because we started in the middle of a tick.
+    //
+    NumberOfTicks = DivU64x32Remainder (
+                      Delay,
+                      (UINT32) mMetronome->TickPeriod,
+                      &Remainder
+                      );
+    if (Remainder != 0) {
+      NumberOfTicks += 1;
+    }
+
+    NumberOfTicks += 1;
+
+    while (NumberOfTicks) {
+
+      mMetronome->WaitForTick (mMetronome, 1);
+
+      Status = This->Io.Read (
+                          This,
+                          Width,
+                          Address,
+                          1,
+                          Result
+                          );
+      if (EFI_ERROR (Status)) {
+        return Status;
+      }
+
+      if ((*Result & Mask) == Value) {
+        return EFI_SUCCESS;
+      }
+
+      NumberOfTicks -= 1;
+    }
+  }
+
+  return EFI_TIMEOUT;
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoMemRead (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 Address,
+  IN     UINTN                                  Count,
+  IN OUT VOID                                   *Buffer
+  )
+/*++
+
+Routine Description:
+
+  Allow read from memory mapped I/O space.
+
+Arguments:
+
+  This     -  Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+  Width    -  The width of memory operation.
+  Address  -  Base address of the memory operation.
+  Count    -  Number of memory opeartion to perform.
+  Buffer   -  The destination buffer to store data.
+
+Returns:
+
+  EFI_SUCCESS            -  Success.
+  EFI_INVALID_PARAMETER  -  Invalid parameter found.
+  EFI_OUT_OF_RESOURCES   -  Fail due to lack of resources.
+
+--*/
+{
+  PCI_ROOT_BRIDGE_INSTANCE  *PrivateData;
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width < 0 ||
+      Width == EfiPciWidthUint64 ||
+      Width == EfiPciWidthFifoUint64 ||
+      Width == EfiPciWidthFillUint64 ||
+      Width >= EfiPciWidthMaximum
+      ) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+  //
+  // Check memory access limit
+  //
+  if (PrivateData->Aperture.Mem64Limit > PrivateData->Aperture.Mem64Base) {
+      if (Address > PrivateData->Aperture.Mem64Limit) {
+        return EFI_INVALID_PARAMETER;
+      }
+  } else {
+      if (Address > PrivateData->Aperture.Mem32Limit) {
+        return EFI_INVALID_PARAMETER;
+      }
+  }
+
+  return mCpuIo->Mem.Read (
+                      mCpuIo,
+                      (EFI_CPU_IO_PROTOCOL_WIDTH) Width,
+                      Address,
+                      Count,
+                      Buffer
+                      );
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoMemWrite (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 Address,
+  IN     UINTN                                  Count,
+  IN OUT VOID                                   *Buffer
+  )
+/*++
+
+Routine Description:
+
+  Allow write to memory mapped I/O space.
+
+Arguments:
+
+  This     -  Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+  Width    -  The width of memory operation.
+  Address  -  Base address of the memory operation.
+  Count    -  Number of memory opeartion to perform.
+  Buffer   -  The source buffer to write data from.
+
+Returns:
+
+  EFI_SUCCESS            -  Success.
+  EFI_INVALID_PARAMETER  -  Invalid parameter found.
+  EFI_OUT_OF_RESOURCES   -  Fail due to lack of resources.
+
+--*/
+{
+  PCI_ROOT_BRIDGE_INSTANCE  *PrivateData;
+
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width < 0 ||
+      Width == EfiPciWidthUint64 ||
+      Width == EfiPciWidthFifoUint64 ||
+      Width == EfiPciWidthFillUint64 ||
+      Width >= EfiPciWidthMaximum
+      ) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+  //
+  // Check memory access limit
+  //
+  if (PrivateData->Aperture.Mem64Limit > PrivateData->Aperture.Mem64Base) {
+      if (Address > PrivateData->Aperture.Mem64Limit) {
+        return EFI_INVALID_PARAMETER;
+      }
+  } else {
+      if (Address > PrivateData->Aperture.Mem32Limit) {
+        return EFI_INVALID_PARAMETER;
+      }
+  }
+
+  return mCpuIo->Mem.Write (
+                      mCpuIo,
+                      (EFI_CPU_IO_PROTOCOL_WIDTH) Width,
+                      Address,
+                      Count,
+                      Buffer
+                      );
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoIoRead (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN     UINT64                                 Address,
+  IN     UINTN                                  Count,
+  IN OUT VOID                                   *Buffer
+  )
+/*++
+
+Routine Description:
+
+  Enable a PCI driver to read PCI controller registers in the
+  PCI root bridge I/O space.
+
+Arguments:
+
+  This     -  A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+  Width    -  Signifies the width of the memory operation.
+  Address  -  The base address of the I/O operation.
+  Count    -  The number of I/O operations to perform.
+  Buffer   -  The destination buffer to store the results.
+
+Returns:
+
+  EFI_SUCCESS            -  The data was read from the PCI root bridge.
+  EFI_INVALID_PARAMETER  -  Invalid parameters found.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to a lack of
+                            resources.
+--*/
+{
+
+  UINTN                     AlignMask;
+  PCI_ROOT_BRIDGE_INSTANCE  *PrivateData;
+
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width < 0 ||
+      Width == EfiPciWidthUint64 ||
+      Width == EfiPciWidthFifoUint64 ||
+      Width == EfiPciWidthFillUint64 ||
+      Width >= EfiPciWidthMaximum
+      ) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+  //
+  // AlignMask = (1 << Width) - 1;
+  //
+  AlignMask = (1 << (Width & 0x03)) - 1;
+
+  //
+  // check Io access limit
+  //
+  if (Address > PrivateData->Aperture.IoLimit) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Address & AlignMask) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return mCpuIo->Io.Read (
+                      mCpuIo,
+                      (EFI_CPU_IO_PROTOCOL_WIDTH) Width,
+                      Address,
+                      Count,
+                      Buffer
+                      );
+
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoIoWrite (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL          *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
+  IN     UINT64                                   Address,
+  IN     UINTN                                    Count,
+  IN OUT VOID                                     *Buffer
+  )
+/*++
+
+Routine Description:
+
+  Enable a PCI driver to write to PCI controller registers in the
+  PCI root bridge I/O space.
+
+Arguments:
+
+  This     -  A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+  Width    -  Signifies the width of the memory operation.
+  Address  -  The base address of the I/O operation.
+  Count    -  The number of I/O operations to perform.
+  Buffer   -  The source buffer to write data from.
+
+Returns:
+
+  EFI_SUCCESS            -  The data was written to the PCI root bridge.
+  EFI_INVALID_PARAMETER  -  Invalid parameters found.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to a lack of
+                            resources.
+--*/
+{
+  UINTN                     AlignMask;
+  PCI_ROOT_BRIDGE_INSTANCE  *PrivateData;
+
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width < 0 ||
+      Width == EfiPciWidthUint64 ||
+      Width == EfiPciWidthFifoUint64 ||
+      Width == EfiPciWidthFillUint64 ||
+      Width >= EfiPciWidthMaximum
+      ) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+  //
+  // AlignMask = (1 << Width) - 1;
+  //
+  AlignMask = (1 << (Width & 0x03)) - 1;
+
+  //
+  // Check Io access limit
+  //
+  if (Address > PrivateData->Aperture.IoLimit) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Address & AlignMask) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return mCpuIo->Io.Write (
+                      mCpuIo,
+                      (EFI_CPU_IO_PROTOCOL_WIDTH) Width,
+                      Address,
+                      Count,
+                      Buffer
+                      );
+
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoCopyMem (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH     Width,
+  IN UINT64                                    DestAddress,
+  IN UINT64                                    SrcAddress,
+  IN UINTN                                     Count
+  )
+/*++
+
+Routine Description:
+
+  Copy one region of PCI root bridge memory space to be copied to
+  another region of PCI root bridge memory space.
+
+Arguments:
+
+  This         -  A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+  Width        -  Signifies the width of the memory operation.
+  DestAddress  -  Destination address of the memory operation.
+  SrcAddress   -  Source address of the memory operation.
+  Count        -  Number of memory operations to perform.
+
+Returns:
+
+  EFI_SUCCESS            -  The data was copied successfully.
+  EFI_INVALID_PARAMETER  -  Invalid parameters found.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to a lack of
+                            resources.
+--*/
+{
+  EFI_STATUS  Status;
+  BOOLEAN     Direction;
+  UINTN       Stride;
+  UINTN       Index;
+  UINT64      Result;
+
+  if (Width < 0 || Width > EfiPciWidthUint64) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (DestAddress == SrcAddress) {
+    return EFI_SUCCESS;
+  }
+
+  Stride    = (UINTN)1 << Width;
+
+  Direction = TRUE;
+  if ((DestAddress > SrcAddress) && (DestAddress < (SrcAddress + Count * Stride))) {
+    Direction   = FALSE;
+    SrcAddress  = SrcAddress + (Count - 1) * Stride;
+    DestAddress = DestAddress + (Count - 1) * Stride;
+  }
+
+  for (Index = 0; Index < Count; Index++) {
+    Status = RootBridgeIoMemRead (
+              This,
+              Width,
+              SrcAddress,
+              1,
+              &Result
+              );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    Status = RootBridgeIoMemWrite (
+              This,
+              Width,
+              DestAddress,
+              1,
+              &Result
+              );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    if (Direction) {
+      SrcAddress += Stride;
+      DestAddress += Stride;
+    } else {
+      SrcAddress -= Stride;
+      DestAddress -= Stride;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+RootBridgeIoPciRW (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
+  IN BOOLEAN                                Write,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
+  IN UINT64                                 UserAddress,
+  IN UINTN                                  Count,
+  IN OUT VOID                              *UserBuffer
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+{
+  PCI_CONFIG_ACCESS_CF8             Pci;
+  PCI_CONFIG_ACCESS_CF8             PciAligned;
+  UINT32                            Stride;
+  UINTN                             PciData;
+  UINTN                             PciDataStride;
+  PCI_ROOT_BRIDGE_INSTANCE         *PrivateData;
+
+  if (Width >= EfiPciWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
+
+  ASSERT (((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*)&UserAddress)->ExtendedRegister == 0x00);
+
+  Stride = 1 << Width;
+
+  Pci.Bits.Reg = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &UserAddress)->Register;
+  Pci.Bits.Func = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &UserAddress)->Function;
+  Pci.Bits.Dev = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &UserAddress)->Device;
+  Pci.Bits.Bus = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &UserAddress)->Bus;
+  Pci.Bits.Reserved = 0;
+  Pci.Bits.Enable = 1;
+
+  //
+  // PCI Configure access are all 32-bit aligned, but by accessing the
+  //  CONFIG_DATA_REGISTER (0xcfc) with different widths more cycle types
+  //  are possible on PCI.
+  //
+  // To read a byte of PCI configuration space you load 0xcf8 and
+  //  read 0xcfc, 0xcfd, 0xcfe, 0xcff
+  //
+  PciDataStride = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &UserAddress)->Register & 0x03;
+
+  while (Count) {
+    PciAligned = Pci;
+    PciAligned.Bits.Reg &= 0xfc;
+    PciData = PrivateData->PciData + PciDataStride;
+    EfiAcquireLock(&PrivateData->PciLock);
+    This->Io.Write (This, EfiPciWidthUint32, \
+                    PrivateData->PciAddress, 1, &PciAligned);
+    if (Write) {
+      This->Io.Write (This, Width, PciData, 1, UserBuffer);
+    } else {
+      This->Io.Read (This, Width, PciData, 1, UserBuffer);
+    }
+    EfiReleaseLock(&PrivateData->PciLock);
+    UserBuffer = ((UINT8 *)UserBuffer) + Stride;
+    PciDataStride = (PciDataStride + Stride) % 4;
+    Count -= 1;
+
+    //
+    // Only increment the PCI address if Width is not a FIFO.
+    //
+    if (Width >= EfiPciWidthUint8 && Width <= EfiPciWidthUint64) {
+      Pci.Bits.Reg += Stride;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoPciRead (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL          *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
+  IN     UINT64                                   Address,
+  IN     UINTN                                    Count,
+  IN OUT VOID                                     *Buffer
+  )
+/*++
+
+Routine Description:
+
+  Allows read from PCI configuration space.
+
+Arguments:
+
+  This     -  A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+  Width    -  Signifies the width of the memory operation.
+  Address  -  The address within the PCI configuration space
+              for the PCI controller.
+  Count    -  The number of PCI configuration operations
+              to perform.
+  Buffer   -  The destination buffer to store the results.
+
+Returns:
+
+  EFI_SUCCESS            -  The data was read from the PCI root bridge.
+  EFI_INVALID_PARAMETER  -  Invalid parameters found.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to a lack of
+                            resources.
+--*/
+{
+  PCI_ROOT_BRIDGE_INSTANCE  *PrivateData;
+  UINT32                    PciBus;
+  UINT32                    PciDev;
+  UINT32                    PciFn;
+  UINT32                    PciExtReg;
+  UINT64                    ExtConfigAdd;
+
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width < 0 ||
+      Width == EfiPciWidthUint64 ||
+      Width == EfiPciWidthFifoUint64 ||
+      Width == EfiPciWidthFillUint64 ||
+      Width >= EfiPciWidthMaximum
+      ) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Read Pci configuration space
+  //
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+  if (PrivateData->HecBase == 0) {
+    return RootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);
+  }
+
+  if (!((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->ExtendedRegister) {
+    PciExtReg = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Register;
+  } else {
+    PciExtReg = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->ExtendedRegister & 0x0FFF;
+  }
+
+  PciBus        = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Bus;
+  PciDev        = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Device;
+  PciFn         = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Function;
+
+  ExtConfigAdd  = (UINT64) PrivateData->HecBase + PCIE_OFF (PciBus, PciDev, PciFn, PciExtReg);
+
+  return mCpuIo->Mem.Read (
+                      mCpuIo,
+                      (EFI_CPU_IO_PROTOCOL_WIDTH) Width,
+                      ExtConfigAdd,
+                      Count,
+                      Buffer
+                      );
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoPciWrite (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL          *This,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    Width,
+  IN UINT64                                   Address,
+  IN UINTN                                    Count,
+  IN OUT VOID                                 *Buffer
+  )
+/*++
+
+Routine Description:
+
+  Allows write to PCI configuration space.
+
+Arguments:
+
+  This     -  A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+  Width    -  Signifies the width of the memory operation.
+  Address  -  The address within the PCI configuration space
+              for the PCI controller.
+  Count    -  The number of PCI configuration operations
+              to perform.
+  Buffer   -  The source buffer to get the results.
+
+Returns:
+
+  EFI_SUCCESS            -  The data was written to the PCI root bridge.
+  EFI_INVALID_PARAMETER  -  Invalid parameters found.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to a lack of
+                            resources.
+--*/
+{
+  PCI_ROOT_BRIDGE_INSTANCE  *PrivateData;
+  UINT32                    PciBus;
+  UINT32                    PciDev;
+  UINT32                    PciFn;
+  UINT32                    PciExtReg;
+  UINT64                    ExtConfigAdd;
+
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width < 0 || Width >= EfiPciWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Write Pci configuration space
+  //
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+  if (PrivateData->HecBase == 0) {
+    return RootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);
+  }
+
+  if (!((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->ExtendedRegister) {
+    PciExtReg = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Register;
+  } else {
+    PciExtReg = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->ExtendedRegister & 0x0FFF;
+  }
+
+  PciBus        = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Bus;
+  PciDev        = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Device;
+  PciFn         = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Function;
+
+  ExtConfigAdd  = (UINT64) PrivateData->HecBase + PCIE_OFF (PciBus, PciDev, PciFn, PciExtReg);
+
+  return mCpuIo->Mem.Write (
+                      mCpuIo,
+                      (EFI_CPU_IO_PROTOCOL_WIDTH) Width,
+                      ExtConfigAdd,
+                      Count,
+                      Buffer
+                      );
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoMap (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL            *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION  Operation,
+  IN     VOID                                       *HostAddress,
+  IN OUT UINTN                                      *NumberOfBytes,
+  OUT    EFI_PHYSICAL_ADDRESS                       *DeviceAddress,
+  OUT    VOID                                       **Mapping
+  )
+/*++
+
+Routine Description:
+
+  Provides the PCI controller-specific address needed to access
+  system memory for DMA.
+
+Arguments:
+
+  This           -  A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+  Operation      -  Indicate if the bus master is going to read or write
+                    to system memory.
+  HostAddress    -  The system memory address to map on the PCI controller.
+  NumberOfBytes  -  On input the number of bytes to map.
+                    On output the number of bytes that were mapped.
+  DeviceAddress  -  The resulting map address for the bus master PCI
+                    controller to use to access the system memory's HostAddress.
+  Mapping        -  The value to pass to Unmap() when the bus master DMA
+                    operation is complete.
+
+Returns:
+
+  EFI_SUCCESS            -  Success.
+  EFI_INVALID_PARAMETER  -  Invalid parameters found.
+  EFI_UNSUPPORTED        -  The HostAddress cannot be mapped as a common
+                            buffer.
+  EFI_DEVICE_ERROR       -  The System hardware could not map the requested
+                            address.
+  EFI_OUT_OF_RESOURCES   -  The request could not be completed due to
+                            lack of resources.
+
+--*/
+{
+  EFI_STATUS            Status;
+  EFI_PHYSICAL_ADDRESS  PhysicalAddress;
+  MAP_INFO              *MapInfo;
+
+  if (NumberOfBytes == NULL || Mapping == NULL || DeviceAddress == NULL || HostAddress == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Initialize the return values to their defaults
+  //
+  *Mapping = NULL;
+
+  //
+  // Make sure that Operation is valid
+  //
+  if ((Operation < 0) || (Operation > EfiPciOperationBusMasterCommonBuffer64)) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Most PCAT like chipsets can not handle performing DMA above 4GB.
+  // If any part of the DMA transfer being mapped is above 4GB, then
+  // map the DMA transfer to a buffer below 4GB.
+  //
+  PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
+  if ((PhysicalAddress +*NumberOfBytes) > 0x100000000ULL) {
+    //
+    // Common Buffer operations can not be remapped.  If the common buffer
+    // if above 4GB, then it is not possible to generate a mapping, so return
+    // an error.
+    //
+    if (Operation == EfiPciOperationBusMasterCommonBuffer || Operation == EfiPciOperationBusMasterCommonBuffer64) {
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  if ((PhysicalAddress + *NumberOfBytes) > (DMA_MEMORY_TOP+1)) {
+
+    //
+    // Common Buffer operations can not be remapped.
+    //
+    if (Operation == EfiPciOperationBusMasterCommonBuffer || Operation == EfiPciOperationBusMasterCommonBuffer64) {
+      *DeviceAddress = PhysicalAddress;
+      return EFI_SUCCESS;
+    }
+    //
+    // Allocate a MAP_INFO structure to remember the mapping when Unmap() is
+    // called later.
+    //
+    Status = gBS->AllocatePool (
+                    EfiBootServicesData,
+                    sizeof (MAP_INFO),
+                    (VOID **) &MapInfo
+                    );
+    if (EFI_ERROR (Status)) {
+      *NumberOfBytes = 0;
+      return Status;
+    }
+    //
+    // Return a pointer to the MAP_INFO structure in Mapping
+    //
+    *Mapping = MapInfo;
+
+    //
+    // Initialize the MAP_INFO structure
+    //
+    MapInfo->Operation          = Operation;
+    MapInfo->NumberOfBytes      = *NumberOfBytes;
+    MapInfo->NumberOfPages      = EFI_SIZE_TO_PAGES (*NumberOfBytes);
+    MapInfo->HostAddress        = PhysicalAddress;
+    MapInfo->MappedHostAddress  = DMA_MEMORY_TOP;
+
+    //
+    // Allocate a buffer below DMA_MEMORY_TOP to map the transfer to.
+    //
+    Status = gBS->AllocatePages (
+                    AllocateMaxAddress,
+                    EfiBootServicesData,
+                    MapInfo->NumberOfPages,
+                    &MapInfo->MappedHostAddress
+                    );
+    if (EFI_ERROR (Status)) {
+      gBS->FreePool (MapInfo);
+      *NumberOfBytes = 0;
+      return Status;
+    }
+    //
+    // If this is a read operation from the Bus Master's point of view,
+    // then copy the contents of the real buffer into the mapped buffer
+    // so the Bus Master can read the contents of the real buffer.
+    //
+    if (Operation == EfiPciOperationBusMasterRead || Operation == EfiPciOperationBusMasterRead64) {
+      CopyMem (
+        (VOID *) (UINTN) MapInfo->MappedHostAddress,
+        (VOID *) (UINTN) MapInfo->HostAddress,
+        MapInfo->NumberOfBytes
+        );
+    }
+    //
+    // The DeviceAddress is the address of the maped buffer below DMA_MEMORY_TOP
+    //
+    *DeviceAddress = MapInfo->MappedHostAddress;
+  } else {
+    //
+    // The transfer is below DMA_MEMORY_TOP, so the DeviceAddress is simply the HostAddress
+    //
+    *DeviceAddress = PhysicalAddress;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoUnmap (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
+  IN VOID                             *Mapping
+  )
+/*++
+
+Routine Description:
+
+  Completes the Map() operation and releases any corresponding resources.
+
+Arguments:
+
+  This     -  Pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+  Mapping  -  The value returned from Map() operation.
+
+Returns:
+
+  EFI_SUCCESS            -  The range was unmapped successfully.
+  EFI_INVALID_PARAMETER  -  Mapping is not a value that was returned
+                            by Map operation.
+  EFI_DEVICE_ERROR       -  The data was not committed to the target
+                            system memory.
+
+--*/
+{
+  MAP_INFO  *MapInfo;
+
+  //
+  // See if the Map() operation associated with this Unmap() required a mapping buffer.
+  // If a mapping buffer was not required, then this function simply returns EFI_SUCCESS.
+  //
+  if (Mapping != NULL) {
+    //
+    // Get the MAP_INFO structure from Mapping
+    //
+    MapInfo = (MAP_INFO *) Mapping;
+
+    //
+    // If this is a write operation from the Bus Master's point of view,
+    // then copy the contents of the mapped buffer into the real buffer
+    // so the processor can read the contents of the real buffer.
+    //
+    if ((MapInfo->Operation == EfiPciOperationBusMasterWrite) ||
+        (MapInfo->Operation == EfiPciOperationBusMasterWrite64)
+        ) {
+      CopyMem (
+        (VOID *) (UINTN) MapInfo->HostAddress,
+        (VOID *) (UINTN) MapInfo->MappedHostAddress,
+        MapInfo->NumberOfBytes
+        );
+    }
+    //
+    // Free the mapped buffer and the MAP_INFO structure.
+    //
+    gBS->FreePages (MapInfo->MappedHostAddress, MapInfo->NumberOfPages);
+    gBS->FreePool (Mapping);
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoAllocateBuffer (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
+  IN  EFI_ALLOCATE_TYPE                Type,
+  IN  EFI_MEMORY_TYPE                  MemoryType,
+  IN  UINTN                            Pages,
+  OUT VOID                             **HostAddress,
+  IN  UINT64                           Attributes
+  )
+/*++
+
+Routine Description:
+
+  Allocates pages that are suitable for a common buffer mapping.
+
+Arguments:
+
+  This         -  Pointer to EFI_ROOT_BRIDGE_IO_PROTOCOL instance.
+  Type         -  Not used and can be ignored.
+  MemoryType   -  Type of memory to allocate.
+  Pages        -  Number of pages to allocate.
+  HostAddress  -  Pointer to store the base system memory address
+                  of the allocated range.
+  Attributes   -  Requested bit mask of attributes of the allocated
+                  range.
+
+Returns:
+
+  EFI_SUCCESS            -  The requested memory range were allocated.
+  EFI_INVALID_PARAMETER  -  Invalid parameter found.
+  EFI_UNSUPPORTED        -  Attributes is unsupported.
+
+--*/
+{
+  EFI_STATUS            Status;
+  EFI_PHYSICAL_ADDRESS  PhysicalAddress;
+
+  //
+  // Validate Attributes
+  //
+  if ((Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) {
+    return EFI_UNSUPPORTED;
+  }
+  //
+  // Check for invalid inputs
+  //
+  if (HostAddress == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData
+  //
+  if ((MemoryType != EfiBootServicesData) && (MemoryType != EfiRuntimeServicesData)) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Limit allocations to memory below DMA_MEMORY_TOP
+  //
+  PhysicalAddress = DMA_MEMORY_TOP;
+
+  Status = gBS->AllocatePages (
+                  AllocateMaxAddress,
+                  MemoryType,
+                  Pages,
+                  &PhysicalAddress
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  *HostAddress = (VOID *) (UINTN) PhysicalAddress;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoFreeBuffer (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
+  IN  UINTN                            Pages,
+  OUT VOID                             *HostAddress
+  )
+/*++
+
+Routine Description:
+
+  Free memory allocated in AllocateBuffer.
+
+Arguments:
+
+  This         -  Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+                  instance.
+  Pages        -  Number of pages to free.
+  HostAddress  -  The base system memory address of the
+                  allocated range.
+
+Returns:
+
+  EFI_SUCCESS            -  Requested memory pages were freed.
+  EFI_INVALID_PARAMETER  -  Invalid parameter found.
+
+--*/
+{
+  return gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress, Pages);
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoFlush (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This
+  )
+/*++
+
+Routine Description:
+
+  Flushes all PCI posted write transactions from a PCI host
+  bridge to system memory.
+
+Arguments:
+
+  This  - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+
+Returns:
+
+  EFI_SUCCESS       -  PCI posted write transactions were flushed
+                       from PCI host bridge to system memory.
+  EFI_DEVICE_ERROR  -  Fail due to hardware error.
+
+--*/
+{
+  //
+  // not supported yet
+  //
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoGetAttributes (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
+  OUT UINT64                           *Supported,
+  OUT UINT64                           *Attributes
+  )
+/*++
+
+Routine Description:
+
+  Get the attributes that a PCI root bridge supports and
+  the attributes the PCI root bridge is currently using.
+
+Arguments:
+
+  This        -  Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+                 instance.
+  Supports    -  A pointer to the mask of attributes that
+                 this PCI root bridge supports.
+  Attributes  -  A pointer to the mask of attributes that
+                 this PCI root bridge is currently using.
+Returns:
+
+  EFI_SUCCESS            -  Success.
+  EFI_INVALID_PARAMETER  -  Invalid parameter found.
+
+--*/
+
+// GC_TODO:    Supported - add argument and description to function comment
+//
+// GC_TODO:    Supported - add argument and description to function comment
+//
+// GC_TODO:    Supported - add argument and description to function comment
+//
+{
+  PCI_ROOT_BRIDGE_INSTANCE  *PrivateData;
+
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+  if (Attributes == NULL && Supported == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Set the return value for Supported and Attributes
+  //
+  if (Supported) {
+    *Supported = PrivateData->Supports;
+  }
+
+  if (Attributes) {
+    *Attributes = PrivateData->Attributes;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoSetAttributes (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
+  IN     UINT64                           Attributes,
+  IN OUT UINT64                           *ResourceBase,
+  IN OUT UINT64                           *ResourceLength
+  )
+/*++
+
+Routine Description:
+
+  Sets the attributes for a resource range on a PCI root bridge.
+
+Arguments:
+
+  This            -  Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+  Attributes      -  The mask of attributes to set.
+  ResourceBase    -  Pointer to the base address of the resource range
+                     to be modified by the attributes specified by Attributes.
+  ResourceLength  -  Pointer to the length of the resource range to be modified.
+
+Returns:
+  EFI_SUCCESS            -  Success.
+  EFI_INVALID_PARAMETER  -  Invalid parameter found.
+  EFI_OUT_OF_RESOURCES   -  Not enough resources to set the attributes upon.
+
+--*/
+
+//
+// GC_TODO:    EFI_UNSUPPORTED - add return value to function comment
+//
+{
+  PCI_ROOT_BRIDGE_INSTANCE  *PrivateData;
+
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+  if (Attributes != 0) {
+    Attributes &= (PrivateData->Supports);
+    if (Attributes == 0) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  if (Attributes == PrivateData->Attributes) {
+    return EFI_SUCCESS;
+  }
+  //
+  // It is just a trick for some attribute can only be enabled or disabled
+  // otherwise it can impact on other devices
+  //
+  PrivateData->Attributes = Attributes;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoConfiguration (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,
+  OUT VOID                             **Resources
+  )
+/*++
+
+Routine Description:
+
+  Retrieves the current resource settings of this PCI root bridge
+  in the form of a set of ACPI 2.0 resource descriptor.
+
+Arguments:
+
+  This       -  Pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+  Resources  -  Pointer to the ACPI 2.0 resource descriptor that
+                describe the current configuration of this PCI root
+                bridge.
+
+Returns:
+
+  EFI_SUCCESS      -  Success.
+  EFI_UNSUPPORTED  -  Current configuration of the PCI root bridge
+                      could not be retrieved.
+
+--*/
+
+//
+// GC_TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment
+//
+{
+  EFI_STATUS                        Status;
+  UINTN                             Idx;
+
+  PCI_ROOT_BRIDGE_INSTANCE          *RbPrivateData;
+  PCI_RES_NODE                      *ResAllocNode;
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Config;
+
+  //
+  // Get this instance of the Root Bridge.
+  //
+  RbPrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+  //
+  // If the pointer is not NULL, it points to a buffer already allocated.
+  //
+  if (RbPrivateData->ConfigBuffer == NULL) {
+    Status = gBS->AllocatePool (
+                    EfiBootServicesData,
+                    TypeMax * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR),
+                    &RbPrivateData->ConfigBuffer
+                    );
+    if (EFI_ERROR (Status)) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+  }
+
+  Config = RbPrivateData->ConfigBuffer;
+
+  ZeroMem (Config, TypeMax * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
+
+  for (Idx = 0; Idx < TypeMax; Idx++) {
+
+    ResAllocNode = &RbPrivateData->ResAllocNode[Idx];
+
+    if (ResAllocNode->Status != ResAllocated) {
+      continue;
+    }
+
+    switch (ResAllocNode->Type) {
+
+    case TypeIo:
+      Config->Desc          = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+      Config->Len           = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
+      Config->ResType       = ACPI_ADDRESS_SPACE_TYPE_IO;
+      Config->AddrRangeMin  = ResAllocNode->Base;
+      Config->AddrRangeMax  = ResAllocNode->Base + ResAllocNode->Length - 1;
+      Config->AddrLen       = ResAllocNode->Length;
+      break;
+
+    case TypeMem32:
+      Config->Desc                  = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+      Config->Len                   = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
+      Config->ResType               = ACPI_ADDRESS_SPACE_TYPE_MEM;
+      Config->AddrSpaceGranularity  = 32;
+      Config->AddrRangeMin          = ResAllocNode->Base;
+      Config->AddrRangeMax          = ResAllocNode->Base + ResAllocNode->Length - 1;
+      Config->AddrLen               = ResAllocNode->Length;
+      break;
+
+    case TypePMem32:
+      Config->Desc                  = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+      Config->Len                   = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
+      Config->ResType               = ACPI_ADDRESS_SPACE_TYPE_MEM;
+      Config->SpecificFlag          = 6;
+      Config->AddrSpaceGranularity  = 32;
+      Config->AddrRangeMin          = ResAllocNode->Base;
+      Config->AddrRangeMax          = ResAllocNode->Base + ResAllocNode->Length - 1;
+      Config->AddrLen               = ResAllocNode->Length;
+      break;
+
+    case TypeMem64:
+      Config->Desc                  = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+      Config->Len                   = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
+      Config->ResType               = ACPI_ADDRESS_SPACE_TYPE_MEM;
+      Config->SpecificFlag          = 6;
+      Config->AddrSpaceGranularity  = 64;
+      Config->AddrRangeMin          = ResAllocNode->Base;
+      Config->AddrRangeMax          = ResAllocNode->Base + ResAllocNode->Length - 1;
+      Config->AddrLen               = ResAllocNode->Length;
+      break;
+
+    case TypePMem64:
+      Config->Desc                  = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+      Config->Len                   = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
+      Config->ResType               = ACPI_ADDRESS_SPACE_TYPE_MEM;
+      Config->SpecificFlag          = 6;
+      Config->AddrSpaceGranularity  = 64;
+      Config->AddrRangeMin          = ResAllocNode->Base;
+      Config->AddrRangeMax          = ResAllocNode->Base + ResAllocNode->Length - 1;
+      Config->AddrLen               = ResAllocNode->Length;
+      break;
+
+    case TypeBus:
+      Config->Desc          = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+      Config->Len           = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
+      Config->ResType       = ACPI_ADDRESS_SPACE_TYPE_BUS;
+      Config->AddrRangeMin  = ResAllocNode->Base;
+      Config->AddrRangeMax  = ResAllocNode->Base + ResAllocNode->Length - 1;
+      Config->AddrLen       = ResAllocNode->Length;
+      break;
+
+    default:
+      break;
+    }
+
+    Config++;
+  }
+  //
+  // Terminate the entries.
+  //
+  ((EFI_ACPI_END_TAG_DESCRIPTOR *) Config)->Desc      = ACPI_END_TAG_DESCRIPTOR;
+  ((EFI_ACPI_END_TAG_DESCRIPTOR *) Config)->Checksum  = 0x0;
+
+  *Resources = RbPrivateData->ConfigBuffer;
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/CommonHeader.h b/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/CommonHeader.h
new file mode 100644
index 0000000000..2ca6dc8eef
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/CommonHeader.h
@@ -0,0 +1,31 @@
+/** @file
+Common header file shared by all source files.
+
+This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+
+
+#include <PiDxe.h>
+#include <IntelQNCDxe.h>
+
+#include <Protocol/PciPlatform.h>
+#include <Protocol/PciIo.h>
+
+#include <Library/DxeServicesLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/IohLib.h>
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.c b/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.c
new file mode 100644
index 0000000000..bb993fc9d3
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.c
@@ -0,0 +1,194 @@
+/** @file
+Registers onboard PCI ROMs with PCI.IO
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#include "CommonHeader.h"
+
+#include "PciPlatform.h"
+
+
+PCI_OPTION_ROM_TABLE mPciOptionRomTable[] = {
+  { NULL_ROM_FILE_GUID,                    0, 0, 0, 0, 0xffff, 0xffff }
+};
+EFI_PCI_PLATFORM_PROTOCOL mPciPlatform = {
+  PhaseNotify,
+  PlatformPrepController,
+  GetPlatformPolicy,
+  GetPciRom
+};
+
+EFI_HANDLE mPciPlatformHandle = NULL;
+EFI_HANDLE mImageHandle       = NULL;
+
+
+EFI_STATUS
+PhaseNotify (
+  IN EFI_PCI_PLATFORM_PROTOCOL                      *This,
+  IN EFI_HANDLE                                     HostBridge,
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE  Phase,
+  IN EFI_PCI_CHIPSET_EXECUTION_PHASE                ChipsetPhase
+  )
+{
+  UINT8                  UsbHostBusNumber = IOH_BUS;
+  if (Phase == EfiPciHostBridgeEndResourceAllocation) {
+    // Required for QuarkSouthCluster.
+    // Enable USB controller memory, io and bus master before Ehci driver.
+    EnableUsbMemIoBusMaster (UsbHostBusNumber);
+    return EFI_SUCCESS;
+  }
+  return EFI_UNSUPPORTED;
+}
+
+
+EFI_STATUS
+PlatformPrepController (
+  IN  EFI_PCI_PLATFORM_PROTOCOL                      *This,
+  IN  EFI_HANDLE                                     HostBridge,
+  IN  EFI_HANDLE                                     RootBridge,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS    PciAddress,
+  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE   Phase,
+  IN  EFI_PCI_CHIPSET_EXECUTION_PHASE                ChipsetPhase
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+GetPlatformPolicy (
+  IN  CONST EFI_PCI_PLATFORM_PROTOCOL                     *This,
+  OUT       EFI_PCI_PLATFORM_POLICY                       *PciPolicy
+  )
+{
+  if (PciPolicy == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+GetPciRom (
+  IN  CONST EFI_PCI_PLATFORM_PROTOCOL                   *This,
+  IN        EFI_HANDLE                                  PciHandle,
+  OUT       VOID                                        **RomImage,
+  OUT       UINTN                                       *RomSize
+  )
+/*++
+
+  Routine Description:
+    Return a PCI ROM image for the onboard device represented by PciHandle
+
+  Arguments:
+    This      - Protocol instance pointer.
+    PciHandle - PCI device to return the ROM image for.
+    RomImage  - PCI Rom Image for onboard device
+    RomSize   - Size of RomImage in bytes
+
+  Returns:
+    EFI_SUCCESS   - RomImage is valid
+    EFI_NOT_FOUND - No RomImage
+
+--*/
+{
+  EFI_STATUS                    Status;
+  EFI_PCI_IO_PROTOCOL           *PciIo;
+  UINTN                         Segment;
+  UINTN                         Bus;
+  UINTN                         Device;
+  UINTN                         Function;
+  UINT16                        VendorId;
+  UINT16                        DeviceId;
+  UINT16                        DeviceClass;
+  UINTN                         TableIndex;
+
+  Status = gBS->HandleProtocol (
+                  PciHandle,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **) &PciIo
+                  );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);
+
+  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, 0x0A, 1, &DeviceClass);
+
+  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, 0, 1, &VendorId);
+
+  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, 2, 1, &DeviceId);
+
+  //
+  // Loop through table of video option rom descriptions
+  //
+  for (TableIndex = 0; mPciOptionRomTable[TableIndex].VendorId != 0xffff; TableIndex++) {
+
+    //
+    // See if the PCI device specified by PciHandle matches at device in mPciOptionRomTable
+    //
+    if (VendorId != mPciOptionRomTable[TableIndex].VendorId ||
+        DeviceId != mPciOptionRomTable[TableIndex].DeviceId ||
+        Segment != mPciOptionRomTable[TableIndex].Segment ||
+        Bus != mPciOptionRomTable[TableIndex].Bus ||
+        Device != mPciOptionRomTable[TableIndex].Device ||
+        Function != mPciOptionRomTable[TableIndex].Function) {
+      continue;
+    }
+
+    Status = GetSectionFromFv (
+               &mPciOptionRomTable[TableIndex].FileName,
+               EFI_SECTION_RAW,
+               0,
+               RomImage,
+               RomSize
+               );
+
+    if (EFI_ERROR (Status)) {
+      continue;
+    }
+
+    return EFI_SUCCESS;
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+PciPlatformDriverEntry (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
+
+Returns:
+  EFI_STATUS
+
+--*/
+{
+  EFI_STATUS  Status;
+
+  mImageHandle = ImageHandle;
+
+  //
+  // Install on a new handle
+  //
+  Status = gBS->InstallProtocolInterface (
+                  &mPciPlatformHandle,
+                  &gEfiPciPlatformProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &mPciPlatform
+                  );
+
+  return Status;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.h b/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.h
new file mode 100644
index 0000000000..baa5d48d22
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.h
@@ -0,0 +1,82 @@
+/** @file
+This code supports a the private implementation
+of the Legacy BIOS Platform protocol
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#ifndef PCI_PLATFORM_H_
+#define PCI_PLATFORM_H_
+
+#include <IndustryStandard/Pci.h>
+#include <Library/PcdLib.h>
+//
+// Global variables for Option ROMs
+//
+#define NULL_ROM_FILE_GUID \
+{ 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}
+
+#define ONBOARD_VIDEO_OPTION_ROM_FILE_GUID \
+{ 0x8dfae5d4, 0xb50e, 0x4c10, {0x96, 0xe6, 0xf2, 0xc2, 0x66, 0xca, 0xcb, 0xb6 }}
+
+#define IDE_RAID_OPTION_ROM_FILE_GUID \
+{ 0x3392A8E1, 0x1881, 0x4398, {0x83, 0xa6, 0x53, 0xd3, 0x87, 0xdb, 0x20, 0x20 }}
+
+#define TANX_UNDI_OPTION_ROM_FILE_GUID \
+{ 0x84c24ab0, 0x124e, 0x4aed, {0x8e, 0xfe, 0xf9, 0x1b, 0xb9, 0x73, 0x69, 0xf4 }}
+
+#define PXE_UNDI_OPTION_ROM_FILE_GUID \
+{ 0xea34cd48, 0x5fdf, 0x46f0, {0xb5, 0xfa, 0xeb, 0xe0, 0x76, 0xa4, 0xf1, 0x2c }}
+
+
+typedef struct {
+  EFI_GUID  FileName;
+  UINTN     Segment;
+  UINTN     Bus;
+  UINTN     Device;
+  UINTN     Function;
+  UINT16    VendorId;
+  UINT16    DeviceId;
+} PCI_OPTION_ROM_TABLE;
+
+
+EFI_STATUS
+PhaseNotify (
+  IN EFI_PCI_PLATFORM_PROTOCOL                        *This,
+  IN EFI_HANDLE                                       HostBridge,
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE    Phase,
+  IN EFI_PCI_CHIPSET_EXECUTION_PHASE                  ChipsetPhase
+  );
+
+
+EFI_STATUS
+PlatformPrepController (
+  IN  EFI_PCI_PLATFORM_PROTOCOL                      *This,
+  IN  EFI_HANDLE                                     HostBridge,
+  IN  EFI_HANDLE                                     RootBridge,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS    PciAddress,
+  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE   Phase,
+  IN  EFI_PCI_CHIPSET_EXECUTION_PHASE                ChipsetPhase
+  );
+
+EFI_STATUS
+GetPlatformPolicy (
+  IN  CONST EFI_PCI_PLATFORM_PROTOCOL            *This,
+  OUT       EFI_PCI_PLATFORM_POLICY             *PciPolicy
+  );
+
+EFI_STATUS
+GetPciRom (
+  IN CONST EFI_PCI_PLATFORM_PROTOCOL            *This,
+  IN       EFI_HANDLE                           PciHandle,
+  OUT      VOID                               **RomImage,
+  OUT      UINTN                              *RomSize
+  );
+
+#endif
+
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.inf b/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.inf
new file mode 100644
index 0000000000..02cde7d431
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.inf
@@ -0,0 +1,54 @@
+## @file
+# Component description file for PciPlatform module.
+#
+# This driver installs pciplatform protocol to provide access interfaces to the onboard pci roms.
+# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PciPlatform
+  FILE_GUID                      = 2E8CD01A-BDB7-40b4-8376-E7C26EAC21FF
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = PciPlatformDriverEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  PciPlatform.c
+  PciPlatform.h
+  CommonHeader.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  PciLib
+  PcdLib
+  IohLib
+  DebugLib
+  UefiRuntimeServicesTableLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  DxeServicesLib
+
+[Guids]
+
+[Protocols]
+  gEfiPciIoProtocolGuid                         # PROTOCOL ALWAYS_CONSUMED
+  gEfiPciPlatformProtocolGuid                   # PROTOCOL ALWAYS_PRODUCED
+
+[Pcd]
+
+[Depex]
+  TRUE
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.c
new file mode 100644
index 0000000000..fb11f5f8c4
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.c
@@ -0,0 +1,435 @@
+/** @file
+This is the driver that locates the MemoryConfigurationData Variable, if it
+exists, and reports the data to the DataHub.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MemorySubClass.h"
+
+extern UINT8 MemorySubClassStrings[];
+
+EFI_GUID  gEfiMemorySubClassDriverGuid = EFI_MEMORY_SUBCLASS_DRIVER_GUID;
+
+EFI_STATUS
+MemorySubClassEntryPoint (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+/*++
+
+  Routine Description:
+    This is the standard EFI driver point that detects whether there is a
+    MemoryConfigurationData Variable and, if so, reports memory configuration info
+    to the DataHub.
+
+  Arguments:
+    ImageHandle   - Handle for the image of this driver
+    SystemTable   - Pointer to the EFI System Table
+
+  Returns:
+    EFI_SUCCESS if the data is successfully reported
+    EFI_NOT_FOUND if the HOB list could not be located.
+
+--*/
+{
+//  UINT8                           Index;
+  UINTN                           DataSize;
+  UINT8                           Dimm;
+  UINTN                           StringBufferSize;
+  UINT8                           NumSlots;
+  UINTN                           DevLocStrLen;
+  UINTN                           BankLocStrLen;
+  UINTN                           ManuStrLen;
+  UINTN                           SerialNumStrLen;
+  UINTN                           AssertTagStrLen;
+  UINTN                           PartNumStrLen;
+  UINTN                           MemoryDeviceSize;
+  CHAR8*                          OptionalStrStart;
+  UINT16                          ArrayInstance;
+  UINT64                          DimmMemorySize;
+  UINT64                          TotalMemorySize;
+  UINT32                          Data;
+  UINT32                          MemoryCapacity;
+  BOOLEAN                         MemoryDeviceSizeUnitMega;
+  EFI_STATUS                      Status;
+  EFI_STRING                      StringBuffer;
+  EFI_STRING                      DevLocStr;
+  EFI_STRING                      BankLocStr;
+  EFI_STRING                      ManuStr;
+  EFI_STRING                      SerialNumStr;
+  EFI_STRING                      AssertTagStr;
+  EFI_STRING                      PartNumStr;
+  EFI_HII_HANDLE                  HiiHandle;
+  EFI_SMBIOS_HANDLE               MemArraySmbiosHandle;
+  EFI_SMBIOS_HANDLE               MemArrayMappedAddrSmbiosHandle;
+  EFI_SMBIOS_HANDLE               MemDevSmbiosHandle;
+  EFI_SMBIOS_HANDLE               MemDevMappedAddrSmbiosHandle;
+  EFI_SMBIOS_HANDLE               MemModuleInfoSmbiosHandle;
+  SMBIOS_TABLE_TYPE6              *Type6Record;
+  SMBIOS_TABLE_TYPE16             *Type16Record;
+  SMBIOS_TABLE_TYPE17             *Type17Record;
+  SMBIOS_TABLE_TYPE19              *Type19Record;
+  SMBIOS_TABLE_TYPE20             *Type20Record;
+  EFI_SMBIOS_PROTOCOL             *Smbios;
+  EFI_MEMORY_ARRAY_LINK_DATA      ArrayLink;
+  EFI_MEMORY_ARRAY_LOCATION_DATA  ArrayLocationData;
+  EFI_MEMORY_DEVICE_START_ADDRESS_DATA  DeviceStartAddress;
+
+
+  DataSize = 0;
+  Dimm = 0;
+
+
+  //
+  // Allocate Buffers
+  //
+  StringBufferSize = (sizeof (CHAR16)) * 100;
+  StringBuffer = AllocateZeroPool (StringBufferSize);
+  ASSERT (StringBuffer != NULL);
+
+  //
+  // Locate dependent protocols
+  //
+  Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios);
+  ASSERT_EFI_ERROR (Status);
+
+
+  //
+  // Add our default strings to the HII database. They will be modified later.
+  //
+  HiiHandle = HiiAddPackages (
+                &gEfiMemorySubClassDriverGuid,
+                NULL,
+                MemorySubClassStrings,
+                NULL
+                );
+  ASSERT (HiiHandle != NULL);
+
+  //
+  // Create physical array and associated data for all mainboard memory
+  // This will translate into a Type 16 SMBIOS Record
+  //
+  ArrayInstance = 1;
+
+  McD0PciCfg32 (QNC_ACCESS_PORT_MCR) = MESSAGE_READ_DW (0x3, 0x8);
+  TotalMemorySize =     McD0PciCfg32 (QNC_ACCESS_PORT_MDR);
+
+  ArrayLocationData.MemoryArrayLocation = EfiMemoryArrayLocationSystemBoard;
+  ArrayLocationData.MemoryArrayUse = EfiMemoryArrayUseSystemMemory;
+
+  ArrayLocationData.MemoryErrorCorrection = EfiMemoryErrorCorrectionNone;
+
+  Data = 0x40000000;//(UINT32) RShiftU64(MemConfigData->RowInfo.MaxMemory, 10);
+
+  ArrayLocationData.MaximumMemoryCapacity.Exponent = (UINT16) LowBitSet32 (Data);
+  ArrayLocationData.MaximumMemoryCapacity.Value    = (UINT16) (Data >> ArrayLocationData.MaximumMemoryCapacity.Exponent);
+
+  NumSlots = 2;// (UINT8)(MemConfigData->RowInfo.MaxRows >> 1);
+  ArrayLocationData.NumberMemoryDevices = (UINT16)(NumSlots);
+
+  //
+  // Report top level physical array to Type 16 SMBIOS Record
+  //
+  Type16Record = AllocatePool(sizeof(SMBIOS_TABLE_TYPE16) + 1 + 1);
+  ZeroMem(Type16Record, sizeof(SMBIOS_TABLE_TYPE16) + 1 + 1);
+
+  Type16Record->Hdr.Type = EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY;
+  Type16Record->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE16);
+  Type16Record->Hdr.Handle = 0;
+
+  Type16Record->Location = (UINT8)ArrayLocationData.MemoryArrayLocation;
+
+  Type16Record->Use = (UINT8)ArrayLocationData.MemoryArrayUse;
+
+  Type16Record->MemoryErrorCorrection = (UINT8)ArrayLocationData.MemoryErrorCorrection;
+
+  MemoryCapacity = (UINT32) ArrayLocationData.MaximumMemoryCapacity.Value * (1 << ((UINT32) ArrayLocationData.MaximumMemoryCapacity.Exponent - 10));
+  Type16Record->MaximumCapacity = MemoryCapacity;
+
+  Type16Record->MemoryErrorInformationHandle = 0xfffe;
+
+  Type16Record->NumberOfMemoryDevices = ArrayLocationData.NumberMemoryDevices;
+  //
+  // Don't change it. This handle will be referenced by type 17 records
+  //
+  MemArraySmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios->Add (Smbios, NULL, &MemArraySmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*) Type16Record);
+  FreePool(Type16Record);
+  ASSERT_EFI_ERROR (Status);
+
+  // Do  associated data for each DIMM
+  //RowConfArray = &MemConfigData->RowConfArray;
+
+  //
+  // Get total memory size for the construction of smbios record type 19
+  //
+  //TotalMemorySize = 0;// MSG_BUS_READ(0x0208);
+
+  //
+  // Generate Memory Array Mapped Address info
+  //
+  Type19Record = AllocatePool(sizeof (SMBIOS_TABLE_TYPE19));
+  ZeroMem(Type19Record, sizeof(SMBIOS_TABLE_TYPE19));
+  Type19Record->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS;
+  Type19Record->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE19);
+  Type19Record->Hdr.Handle = 0;
+  Type19Record->StartingAddress = 0;
+  Type19Record->EndingAddress = (UINT32)RShiftU64(TotalMemorySize, 10) - 1;
+  Type19Record->MemoryArrayHandle = MemArraySmbiosHandle;
+  Type19Record->PartitionWidth = (UINT8)(NumSlots);
+
+  //
+  // Generate Memory Array Mapped Address info (TYPE 19)
+  //
+  MemArrayMappedAddrSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios->Add (Smbios, NULL, &MemArrayMappedAddrSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*) Type19Record);
+  FreePool(Type19Record);
+  ASSERT_EFI_ERROR (Status);
+
+
+  // Use SPD data to generate Device Type info
+  ZeroMem (&ArrayLink, sizeof (EFI_MEMORY_ARRAY_LINK_DATA));
+  ArrayLink.MemoryDeviceLocator = STRING_TOKEN(STR_MEMORY_SUBCLASS_DEVICE_LOCATOR_0);
+  ArrayLink.MemoryBankLocator = STRING_TOKEN(STR_MEMORY_SUBCLASS_DEVICE_LOCATOR_0);
+  ArrayLink.MemoryAssetTag = STRING_TOKEN(STR_MEMORY_SUBCLASS_UNKNOWN);
+  ArrayLink.MemoryArrayLink.ProducerName = gEfiMemorySubClassDriverGuid;
+  ArrayLink.MemoryArrayLink.Instance = ArrayInstance;
+  ArrayLink.MemoryArrayLink.SubInstance = EFI_SUBCLASS_INSTANCE_NON_APPLICABLE;
+  ArrayLink.MemorySubArrayLink.ProducerName = gEfiMemorySubClassDriverGuid;
+  ArrayLink.MemorySubArrayLink.SubInstance = EFI_SUBCLASS_INSTANCE_NON_APPLICABLE;
+  ArrayLink.MemoryFormFactor = EfiMemoryFormFactorChip;
+  ArrayLink.MemoryType = EfiMemoryTypeDdr2;
+
+
+  StrCpy (StringBuffer, L"NO DIMM,MEMROY DOWN");
+  ArrayLink.MemoryManufacturer = HiiSetString (
+                                   HiiHandle,
+                                   0,
+                                   StringBuffer,
+                                   NULL
+                                   );
+  ArrayLink.MemorySerialNumber = HiiSetString (
+                                   HiiHandle,
+                                   0,
+                                   StringBuffer,
+                                   NULL
+                                   );
+
+  ArrayLink.MemoryPartNumber = HiiSetString (
+                                 HiiHandle,
+                                 0,
+                                 StringBuffer,
+                                 NULL
+                                 );
+
+  //
+  // Hardcode value. Need to revise for different configuration.
+  //
+  ArrayLink.MemoryTotalWidth = 64;
+  ArrayLink.MemoryDataWidth = 64;
+
+  DimmMemorySize = TotalMemorySize;// MSG_BUS_READ(0x0208);
+
+  ArrayLink.MemoryDeviceSize.Exponent = (UINT16) LowBitSet64 (DimmMemorySize);
+  ArrayLink.MemoryDeviceSize.Value    = (UINT16) RShiftU64(DimmMemorySize, ArrayLink.MemoryDeviceSize.Exponent);
+  ArrayLink.MemoryTypeDetail.Synchronous  = 1;
+  Data = 800;
+  ArrayLink.MemorySpeed = *((EFI_EXP_BASE10_DATA *) &Data);
+
+
+
+  DevLocStr = HiiGetPackageString(&gEfiMemorySubClassDriverGuid, ArrayLink.MemoryDeviceLocator, NULL);
+  DevLocStrLen = StrLen(DevLocStr);
+  ASSERT(DevLocStrLen <= SMBIOS_STRING_MAX_LENGTH);
+
+  BankLocStr = HiiGetPackageString(&gEfiMemorySubClassDriverGuid, ArrayLink.MemoryBankLocator, NULL);
+  BankLocStrLen = StrLen(BankLocStr);
+  ASSERT(BankLocStrLen <= SMBIOS_STRING_MAX_LENGTH);
+
+  ManuStr = HiiGetPackageString(&gEfiMemorySubClassDriverGuid, ArrayLink.MemoryManufacturer, NULL);
+  ManuStrLen = StrLen(ManuStr);
+  ASSERT(ManuStrLen <= SMBIOS_STRING_MAX_LENGTH);
+
+  SerialNumStr = HiiGetPackageString(&gEfiMemorySubClassDriverGuid, ArrayLink.MemorySerialNumber, NULL);
+  SerialNumStrLen = StrLen(SerialNumStr);
+  ASSERT(SerialNumStrLen <= SMBIOS_STRING_MAX_LENGTH);
+
+  AssertTagStr = HiiGetPackageString(&gEfiMemorySubClassDriverGuid, ArrayLink.MemoryAssetTag, NULL);
+  AssertTagStrLen = StrLen(AssertTagStr);
+  ASSERT(AssertTagStrLen <= SMBIOS_STRING_MAX_LENGTH);
+
+  PartNumStr = HiiGetPackageString(&gEfiMemorySubClassDriverGuid, ArrayLink.MemoryPartNumber, NULL);
+  PartNumStrLen = StrLen(PartNumStr);
+  ASSERT(PartNumStrLen <= SMBIOS_STRING_MAX_LENGTH);
+
+  //
+  // Report DIMM level memory module information to smbios (Type 6)
+  //
+  DataSize = sizeof(SMBIOS_TABLE_TYPE6) + DevLocStrLen + 1 + 1;
+  Type6Record = AllocatePool(DataSize);
+  ZeroMem(Type6Record, DataSize);
+  Type6Record->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_MODULE_INFORMATON;
+  Type6Record->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE6);
+  Type6Record->Hdr.Handle = 0;
+  Type6Record->SocketDesignation = 1;
+  if (ArrayLink.MemorySpeed.Value == 0) {
+    Type6Record->CurrentSpeed = 0;
+  } else {
+    //
+    // Memory speed is in ns unit
+    //
+    Type6Record->CurrentSpeed = (UINT8)(1000 / (ArrayLink.MemorySpeed.Value));
+  }
+  //
+  // Device Size
+  //
+  MemoryDeviceSize = (UINTN)(ArrayLink.MemoryDeviceSize.Value) * (UINTN)(1 << ArrayLink.MemoryDeviceSize.Exponent);
+  if (MemoryDeviceSize == 0) {
+    *(UINT8*)&(Type6Record->InstalledSize) = 0x7F;
+    *(UINT8*)&(Type6Record->EnabledSize)   = 0x7F;
+  } else {
+    MemoryDeviceSize = (UINTN) RShiftU64 ((UINT64) MemoryDeviceSize, 21);
+    while (MemoryDeviceSize != 0) {
+      (*(UINT8*)&(Type6Record->InstalledSize))++;
+      (*(UINT8*)&(Type6Record->EnabledSize))++;
+      MemoryDeviceSize = (UINTN) RShiftU64 ((UINT64) MemoryDeviceSize,1);
+    }
+  }
+
+  if (ArrayLink.MemoryFormFactor == EfiMemoryFormFactorDimm ||
+    ArrayLink.MemoryFormFactor == EfiMemoryFormFactorFbDimm) {
+    *(UINT16*)&Type6Record->CurrentMemoryType |= 1<<8;
+  }
+  if (ArrayLink.MemoryFormFactor == EfiMemoryFormFactorSimm) {
+    *(UINT16*)&Type6Record->CurrentMemoryType |= 1<<7;
+  }
+  if (ArrayLink.MemoryType == EfiMemoryTypeSdram) {
+    *(UINT16*)&Type6Record->CurrentMemoryType |= 1<<10;
+  }
+  if (ArrayLink.MemoryTypeDetail.Edo == 1) {
+    *(UINT16*)&Type6Record->CurrentMemoryType |= 1<<4;
+  }
+  if (ArrayLink.MemoryTypeDetail.FastPaged == 1) {
+    *(UINT16*)&Type6Record->CurrentMemoryType |= 1<<3;
+  }
+  OptionalStrStart = (CHAR8 *)(Type6Record + 1);
+  UnicodeStrToAsciiStr(DevLocStr, OptionalStrStart);
+  MemModuleInfoSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios->Add (Smbios, NULL, &MemModuleInfoSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*) Type6Record);
+  FreePool(Type6Record);
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Report DIMM level Device Type to smbios (Type 17)
+  //
+  DataSize = sizeof (SMBIOS_TABLE_TYPE17) + DevLocStrLen + 1 + BankLocStrLen + 1 + ManuStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1 + PartNumStrLen + 1 + 1;
+  Type17Record = AllocatePool(DataSize);
+  ZeroMem(Type17Record, DataSize);
+  Type17Record->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_DEVICE;
+  Type17Record->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE17);
+  Type17Record->Hdr.Handle = 0;
+
+  Type17Record->MemoryArrayHandle = MemArraySmbiosHandle;
+  Type17Record->MemoryErrorInformationHandle = 0xfffe;
+  Type17Record->TotalWidth = ArrayLink.MemoryTotalWidth;
+  Type17Record->DataWidth = ArrayLink.MemoryDataWidth;
+  //
+  // Device Size
+  //
+  MemoryDeviceSize          = ((UINTN) ArrayLink.MemoryDeviceSize.Value) << (ArrayLink.MemoryDeviceSize.Exponent - 10);
+  MemoryDeviceSizeUnitMega  = FALSE;
+  //
+  // kilo as unit
+  //
+  if (MemoryDeviceSize > 0xffff) {
+    MemoryDeviceSize = MemoryDeviceSize >> 10;
+    //
+    // Mega as unit
+    //
+    MemoryDeviceSizeUnitMega = TRUE;
+  }
+
+  MemoryDeviceSize = MemoryDeviceSize & 0x7fff;
+  if (MemoryDeviceSize != 0 && MemoryDeviceSizeUnitMega == FALSE) {
+    MemoryDeviceSize |= 0x8000;
+  }
+  Type17Record->Size = (UINT16)MemoryDeviceSize;
+
+  Type17Record->FormFactor = (UINT8)ArrayLink.MemoryFormFactor;
+  Type17Record->DeviceLocator = 1;
+  Type17Record->BankLocator = 2;
+  Type17Record->MemoryType = (UINT8)ArrayLink.MemoryType;
+  CopyMem (
+    (UINT8 *) &Type17Record->TypeDetail,
+    &ArrayLink.MemoryTypeDetail,
+    2
+  );
+
+  Type17Record->Speed = ArrayLink.MemorySpeed.Value;
+  Type17Record->Manufacturer = 3;
+  Type17Record->SerialNumber = 4;
+  Type17Record->AssetTag = 5;
+  Type17Record->PartNumber = 6;
+  //
+  // temporary solution for save device label information.
+  //
+  Type17Record->Attributes = (UINT8)(Dimm + 1);
+
+  OptionalStrStart = (CHAR8 *)(Type17Record + 1);
+  UnicodeStrToAsciiStr(DevLocStr, OptionalStrStart);
+  UnicodeStrToAsciiStr(BankLocStr, OptionalStrStart + DevLocStrLen + 1);
+  UnicodeStrToAsciiStr(ManuStr, OptionalStrStart + DevLocStrLen + 1 + BankLocStrLen + 1);
+  UnicodeStrToAsciiStr(SerialNumStr, OptionalStrStart + DevLocStrLen + 1 + BankLocStrLen + 1 + ManuStrLen + 1);
+  UnicodeStrToAsciiStr(AssertTagStr, OptionalStrStart + DevLocStrLen + 1 + BankLocStrLen + 1 + ManuStrLen + 1 + SerialNumStrLen + 1);
+  UnicodeStrToAsciiStr(PartNumStr, OptionalStrStart + DevLocStrLen + 1 + BankLocStrLen + 1 + ManuStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1);
+  MemDevSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios->Add (Smbios, NULL, &MemDevSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*) Type17Record);
+  FreePool(Type17Record);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Generate Memory Device Mapped Address info
+  //
+  ZeroMem(&DeviceStartAddress, sizeof(EFI_MEMORY_DEVICE_START_ADDRESS_DATA));
+  DeviceStartAddress.MemoryDeviceStartAddress = 0;
+  DeviceStartAddress.MemoryDeviceEndAddress = DeviceStartAddress.MemoryDeviceStartAddress + DimmMemorySize-1;
+  DeviceStartAddress.PhysicalMemoryDeviceLink.ProducerName = gEfiMemorySubClassDriverGuid;
+  DeviceStartAddress.PhysicalMemoryDeviceLink.Instance = ArrayInstance;
+  DeviceStartAddress.PhysicalMemoryDeviceLink.SubInstance = (UINT16)(Dimm + 1);
+  DeviceStartAddress.PhysicalMemoryArrayLink.ProducerName = gEfiMemorySubClassDriverGuid;
+  DeviceStartAddress.PhysicalMemoryArrayLink.Instance = ArrayInstance;
+  DeviceStartAddress.PhysicalMemoryArrayLink.SubInstance = EFI_SUBCLASS_INSTANCE_NON_APPLICABLE;
+
+  //
+  // Single channel mode
+  //
+  DeviceStartAddress.MemoryDevicePartitionRowPosition = 0x01;
+  DeviceStartAddress.MemoryDeviceInterleavePosition = 0x00;
+  DeviceStartAddress.MemoryDeviceInterleaveDataDepth = 0x00;
+
+  //
+  // Generate Memory Device Mapped Address info (TYPE 20)
+  //
+  Type20Record = AllocatePool(sizeof (SMBIOS_TABLE_TYPE20));
+  ZeroMem(Type20Record, sizeof (SMBIOS_TABLE_TYPE20));
+  Type20Record->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_DEVICE_MAPPED_ADDRESS;
+  Type20Record->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE20);
+  Type20Record->Hdr.Handle = 0;
+
+  Type20Record->StartingAddress = (UINT32)RShiftU64 (DeviceStartAddress.MemoryDeviceStartAddress, 10);
+  Type20Record->EndingAddress = (UINT32)RShiftU64 (DeviceStartAddress.MemoryDeviceEndAddress, 10);
+  Type20Record->MemoryDeviceHandle = MemDevSmbiosHandle;
+  Type20Record->MemoryArrayMappedAddressHandle = MemArrayMappedAddrSmbiosHandle;
+  Type20Record->PartitionRowPosition = DeviceStartAddress.MemoryDevicePartitionRowPosition;
+  Type20Record->InterleavePosition = DeviceStartAddress.MemoryDeviceInterleavePosition;
+  Type20Record->InterleavedDataDepth = DeviceStartAddress.MemoryDeviceInterleaveDataDepth;
+  MemDevMappedAddrSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios->Add (Smbios, NULL, &MemDevMappedAddrSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*) Type20Record);
+  FreePool(Type20Record);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.h b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.h
new file mode 100644
index 0000000000..2343070707
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.h
@@ -0,0 +1,65 @@
+/** @file
+Header file for MemorySubClass Driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _MEMORY_SUB_CLASS_H
+#define _MEMORY_SUB_CLASS_H
+
+//
+// The package level header files this module uses
+//
+#include <FrameworkDxe.h>
+//
+// The protocols, PPI and GUID definitions for this module
+//
+#include <IndustryStandard/SmBios.h>
+#include <Protocol/Smbios.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/SmbusHc.h>
+#include <Guid/DataHubRecords.h>
+#include <Guid/MemoryConfigData.h>
+#include <Protocol/HiiDatabase.h>
+#include <Guid/MdeModuleHii.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/BaseLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PrintLib.h>
+#include <Library/HiiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PciLib.h>
+#include <Library/QNCAccessLib.h>
+
+#include "QNCAccess.h"
+
+
+
+//
+// This is the generated header file which includes whatever needs to be exported (strings + IFR)
+//
+
+#define EFI_MEMORY_SUBCLASS_DRIVER_GUID \
+  { 0xef17cee7, 0x267d, 0x4bfd, { 0xa2, 0x57, 0x4a, 0x6a, 0xb3, 0xee, 0x85, 0x91 }}
+
+//
+// Prototypes
+//
+EFI_STATUS
+MemorySubClassEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  );
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.inf b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.inf
new file mode 100644
index 0000000000..720dfc15f9
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.inf
@@ -0,0 +1,60 @@
+## @file
+# Component description file for MemorySubClass module.
+#
+# This is the driver that locates the MemoryConfigurationData Variable, if it
+#  exists, and reports the data to the DataHub.
+# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = MemorySubClass
+  FILE_GUID                      = EF17CEE7-267D-4BFD-A257-4A6AB3EE8591
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = MemorySubClassEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  MemorySubClass.c
+  MemorySubClass.h
+  MemorySubClassStrings.uni
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+  MemoryAllocationLib
+  HiiLib
+  PrintLib
+  BaseMemoryLib
+  DebugLib
+  UefiRuntimeServicesTableLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  BaseLib
+  HobLib
+  PciLib
+  QNCAccessLib
+
+[Guids]
+  gEfiMemoryConfigDataGuid                      # ALWAYS_CONSUMED
+
+[Protocols]
+  gEfiSmbiosProtocolGuid                        # PROTOCOL ALWAYS_CONSUMED
+  gEfiSmbusHcProtocolGuid                       # PROTOCOL ALWAYS_CONSUMED
+
+[Depex]
+  gEfiVariableArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid AND gEfiSmbiosProtocolGuid AND gEfiSmbusHcProtocolGuid
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClassStrings.uni b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClassStrings.uni
new file mode 100644
index 0000000000..29ba9df8d8
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClassStrings.uni
@@ -0,0 +1,29 @@
+// /** @file
+// String definitions for Smbios Memory SubClass data.
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+// **/
+
+
+/=#
+
+#langdef en-US "English"
+
+//
+// Begin English Language Strings
+//
+#string STR_MEMORY_SUBCLASS_UNKNOWN          #language en-US  "Unknown"
+#string STR_MEMORY_SUBCLASS_DEVICE_LOCATOR_0 #language en-US  "SOLDER DOWN"
+#string STR_MEMORY_SUBCLASS_MANUFACTURER     #language en-US  "Manufacturer: "
+#string STR_MEMORY_SUBCLASS_SERIAL_NUMBER    #language en-US  "Serial Number: "
+#string STR_MEMORY_SUBCLASS_ASSET_TAG        #language en-US  "Asset Tag: "
+#string STR_MEMORY_SUBCLASS_PART_NUMBER      #language en-US  "PartNumber: "
+//
+// End English Language Strings
+//
+
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformConfig.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformConfig.c
new file mode 100644
index 0000000000..a0642fe31a
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformConfig.c
@@ -0,0 +1,443 @@
+/** @file
+Essential platform configuration.
+
+Copyright (c) 2013 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#include "PlatformInitDxe.h"
+
+//
+// The protocols, PPI and GUID defintions for this module
+//
+
+//
+// The Library classes this module consumes
+//
+
+//
+// RTC:28208 - System hang/crash when entering probe mode(ITP) when relocating SMBASE
+//             Workaround to make default SMRAM UnCachable
+//
+#define SMM_DEFAULT_SMBASE                  0x30000     // Default SMBASE address
+#define SMM_DEFAULT_SMBASE_SIZE_BYTES       0x10000     // Size in bytes of default SMRAM
+
+BOOLEAN                       mMemCfgDone = FALSE;
+UINT8                         ChipsetDefaultMac [6] = {0xff,0xff,0xff,0xff,0xff,0xff};
+
+VOID
+EFIAPI
+PlatformInitializeUart0MuxGalileo (
+  VOID
+  )
+/*++
+
+
+Routine Description:
+
+  This is the routine to initialize UART0 for DBG2 support. The hardware used in this process is a
+  Legacy Bridge (Legacy GPIO), I2C controller, a bi-directional MUX and a Cypress CY8C9540A chip.
+
+Arguments:
+
+  None.
+
+Returns:
+
+  None.
+
+--*/
+{
+  EFI_STATUS                        Status;
+  EFI_I2C_DEVICE_ADDRESS            I2CSlaveAddress;
+  UINTN                             Length;
+  UINT8                             Buffer[2];
+
+  if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) {
+    I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2HI_7BIT_SLAVE_ADDR;
+  } else {
+    I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2LO_7BIT_SLAVE_ADDR;
+  }
+
+  //
+  // Set GPIO_SUS<2> as an output, raise voltage to Vdd.
+  //
+  PlatformLegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, 2, TRUE);
+
+  //
+  // Select Port 3
+  //
+  Length = 2;
+  Buffer[0] = 0x18; //sub-address
+  Buffer[1] = 0x03; //data
+
+  Status = I2cWriteMultipleByte (
+              I2CSlaveAddress,
+              EfiI2CSevenBitAddrMode,
+              &Length,
+              &Buffer
+              );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Set "Pin Direction" bit4 and bit5 as outputs
+  //
+  Length = 2;
+  Buffer[0] = 0x1C; //sub-address
+  Buffer[1] = 0xCF; //data
+
+  Status = I2cWriteMultipleByte (
+              I2CSlaveAddress,
+              EfiI2CSevenBitAddrMode,
+              &Length,
+              &Buffer
+              );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Lower GPORT3 bit4 and bit5 to Vss
+  //
+  Length = 2;
+  Buffer[0] = 0x0B; //sub-address
+  Buffer[1] = 0xCF; //data
+
+  Status = I2cWriteMultipleByte (
+              I2CSlaveAddress,
+              EfiI2CSevenBitAddrMode,
+              &Length,
+              &Buffer
+              );
+  ASSERT_EFI_ERROR (Status);
+}
+
+VOID
+EFIAPI
+PlatformInitializeUart0MuxGalileoGen2 (
+  VOID
+  )
+/*++
+
+
+Routine Description:
+
+  This is the routine to initialize UART0 on GalileoGen2. The hardware used in this process is
+  I2C controller and the configuring the following IO Expander signal.
+
+  EXP1.P1_5 should be configured as an output & driven high.
+  EXP1.P0_0 should be configured as an output & driven high.
+  EXP0.P1_4 should be configured as an output, driven low.
+  EXP1.P0_1 pullup should be disabled.
+  EXP0.P1_5 Pullup should be disabled.
+
+Arguments:
+
+  None.
+
+Returns:
+
+  None.
+
+--*/
+
+{
+  //
+  //  EXP1.P1_5 should be configured as an output & driven high.
+  //
+  PlatformPcal9555GpioSetDir (
+    GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR,  // IO Expander 1.
+    13,                                   // P1-5.
+    TRUE
+    );
+  PlatformPcal9555GpioSetLevel (
+    GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR,  // IO Expander 1.
+    13,                                   // P1-5.
+    TRUE
+    );
+
+  //
+  // EXP1.P0_0 should be configured as an output & driven high.
+  //
+  PlatformPcal9555GpioSetDir (
+    GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR,  // IO Expander 0.
+    0,                                    // P0_0.
+    TRUE
+    );
+  PlatformPcal9555GpioSetLevel (
+    GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR,  // IO Expander 0.
+    0,                                    // P0_0.
+    TRUE
+    );
+
+  //
+  //  EXP0.P1_4 should be configured as an output, driven low.
+  //
+  PlatformPcal9555GpioSetDir (
+    GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR,  // IO Expander 0.
+    12,                                   // P1-4.
+    FALSE
+    );
+  PlatformPcal9555GpioSetLevel (          // IO Expander 0.
+    GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR,  // P1-4
+    12,
+    FALSE
+    );
+
+  //
+  // EXP1.P0_1 pullup should be disabled.
+  //
+  PlatformPcal9555GpioDisablePull (
+    GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR,  // IO Expander 1.
+    1                                     // P0-1.
+    );
+
+  //
+  // EXP0.P1_5 Pullup should be disabled.
+  //
+  PlatformPcal9555GpioDisablePull (
+    GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR,  // IO Expander 0.
+    13                                    // P1-5.
+    );
+}
+
+VOID
+EFIAPI
+PlatformConfigOnSmmConfigurationProtocol (
+  IN  EFI_EVENT Event,
+  IN  VOID      *Context
+  )
+/*++
+
+Routine Description:
+
+  Function runs in PI-DXE to perform platform specific config when
+  SmmConfigurationProtocol is installed.
+
+Arguments:
+  Event       - The event that occured.
+  Context     - For EFI compatiblity.  Not used.
+
+Returns:
+  None.
+--*/
+
+{
+  EFI_STATUS            Status;
+  UINT32                NewValue;
+  UINT64                BaseAddress;
+  UINT64                SmramLength;
+  VOID                  *SmmCfgProt;
+
+  Status = gBS->LocateProtocol (&gEfiSmmConfigurationProtocolGuid, NULL, &SmmCfgProt);
+  if (Status != EFI_SUCCESS){
+    DEBUG ((DEBUG_INFO, "gEfiSmmConfigurationProtocolGuid triggered but not valid.\n"));
+    return;
+  }
+  if (mMemCfgDone) {
+    DEBUG ((DEBUG_INFO, "Platform DXE Mem config already done.\n"));
+    return;
+  }
+
+  //
+  // Disable eSram block (this will also clear/zero eSRAM)
+  // We only use eSRAM in the PEI phase. Disable now that we are in the DXE phase
+  //
+  NewValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_ESRAMPGCTRL_BLOCK);
+  NewValue |= BLOCK_DISABLE_PG;
+  QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_ESRAMPGCTRL_BLOCK, NewValue);
+
+  //
+  // Update HMBOUND to top of DDR3 memory and LOCK
+  // We disabled eSRAM so now we move HMBOUND down to top of DDR3
+  //
+  QNCGetTSEGMemoryRange (&BaseAddress, &SmramLength);
+  NewValue = (UINT32)(BaseAddress + SmramLength);
+  DEBUG ((EFI_D_INFO,"Locking HMBOUND at: = 0x%8x\n",NewValue));
+  QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QUARK_NC_HOST_BRIDGE_HMBOUND_REG, (NewValue | HMBOUND_LOCK));
+
+  //
+  // Lock IMR5 now that HMBOUND is locked (legacy S3 region)
+  //
+  NewValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR5+QUARK_NC_MEMORY_MANAGER_IMRXL);
+  NewValue |= IMR_LOCK;
+  QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR5+QUARK_NC_MEMORY_MANAGER_IMRXL, NewValue);
+
+  //
+  // Lock IMR6 now that HMBOUND is locked (ACPI Reclaim/ACPI/Runtime services/Reserved)
+  //
+  NewValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR6+QUARK_NC_MEMORY_MANAGER_IMRXL);
+  NewValue |= IMR_LOCK;
+  QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR6+QUARK_NC_MEMORY_MANAGER_IMRXL, NewValue);
+
+  //
+  // Disable IMR2 memory protection (RMU Main Binary)
+  //
+  QncImrWrite (
+            QUARK_NC_MEMORY_MANAGER_IMR2,
+            (UINT32)(IMRL_RESET & ~IMR_EN),
+            (UINT32)IMRH_RESET,
+            (UINT32)IMRX_ALL_ACCESS,
+            (UINT32)IMRX_ALL_ACCESS
+        );
+
+  //
+  // Disable IMR3 memory protection (Default SMRAM)
+  //
+  QncImrWrite (
+            QUARK_NC_MEMORY_MANAGER_IMR3,
+            (UINT32)(IMRL_RESET & ~IMR_EN),
+            (UINT32)IMRH_RESET,
+            (UINT32)IMRX_ALL_ACCESS,
+            (UINT32)IMRX_ALL_ACCESS
+        );
+
+  //
+  // Disable IMR4 memory protection (eSRAM).
+  //
+  QncImrWrite (
+            QUARK_NC_MEMORY_MANAGER_IMR4,
+            (UINT32)(IMRL_RESET & ~IMR_EN),
+            (UINT32)IMRH_RESET,
+            (UINT32)IMRX_ALL_ACCESS,
+            (UINT32)IMRX_ALL_ACCESS
+        );
+
+  //
+  // RTC:28208 - System hang/crash when entering probe mode(ITP) when relocating SMBASE
+  //             Workaround to make default SMRAM UnCachable
+  //
+  Status = gDS->SetMemorySpaceAttributes (
+                  (EFI_PHYSICAL_ADDRESS) SMM_DEFAULT_SMBASE,
+                  SMM_DEFAULT_SMBASE_SIZE_BYTES,
+                  EFI_MEMORY_WB
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  mMemCfgDone = TRUE;
+}
+
+VOID
+EFIAPI
+PlatformConfigOnSpiReady (
+  IN  EFI_EVENT Event,
+  IN  VOID      *Context
+  )
+/*++
+
+Routine Description:
+
+  Function runs in PI-DXE to perform platform specific config when SPI
+  interface is ready.
+
+Arguments:
+  Event       - The event that occured.
+  Context     - For EFI compatiblity.  Not used.
+
+Returns:
+  None.
+
+--*/
+{
+  EFI_STATUS                        Status;
+  VOID                              *SpiReadyProt = NULL;
+  EFI_PLATFORM_TYPE                 Type;
+  EFI_BOOT_MODE                      BootMode;
+
+  BootMode = GetBootModeHob ();
+
+  Status = gBS->LocateProtocol (&gEfiSmmSpiReadyProtocolGuid, NULL, &SpiReadyProt);
+  if (Status != EFI_SUCCESS){
+    DEBUG ((DEBUG_INFO, "gEfiSmmSpiReadyProtocolGuid triggered but not valid.\n"));
+    return;
+  }
+
+  //
+  // Lock regions SPI flash.
+  //
+  PlatformFlashLockPolicy (FALSE);
+
+  //
+  // Configurations and checks to be done when DXE tracing available.
+  //
+
+  //
+  // Platform specific Signal routing.
+  //
+
+  //
+  // Skip any signal not needed for recovery and flash update.
+  //
+  if (BootMode != BOOT_ON_FLASH_UPDATE && BootMode != BOOT_IN_RECOVERY_MODE) {
+
+    //
+    // Galileo Platform UART0 support.
+    //
+    Type = (EFI_PLATFORM_TYPE)PcdGet16 (PcdPlatformType);
+    if (Type == Galileo) {
+      //
+      // Use MUX to connect out UART0 pins.
+      //
+      PlatformInitializeUart0MuxGalileo ();
+    }
+
+    //
+    // GalileoGen2 Platform UART0 support.
+    //
+    if (Type == GalileoGen2) {
+      //
+      // Use route out UART0 pins.
+      //
+      PlatformInitializeUart0MuxGalileoGen2 ();
+    }
+  }
+}
+
+EFI_STATUS
+EFIAPI
+CreateConfigEvents (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+  None
+
+Returns:
+  EFI_STATUS
+
+--*/
+{
+  EFI_EVENT   EventSmmCfg;
+  EFI_EVENT   EventSpiReady;
+  VOID        *RegistrationSmmCfg;
+  VOID        *RegistrationSpiReady;
+
+  //
+  // Schedule callback for when SmmConfigurationProtocol installed.
+  //
+  EventSmmCfg = EfiCreateProtocolNotifyEvent (
+                  &gEfiSmmConfigurationProtocolGuid,
+                  TPL_CALLBACK,
+                  PlatformConfigOnSmmConfigurationProtocol,
+                  NULL,
+                  &RegistrationSmmCfg
+                  );
+  ASSERT (EventSmmCfg != NULL);
+
+  //
+  // Schedule callback to setup SPI Flash Policy when SPI interface ready.
+  //
+  EventSpiReady = EfiCreateProtocolNotifyEvent (
+                    &gEfiSmmSpiReadyProtocolGuid,
+                    TPL_CALLBACK,
+                    PlatformConfigOnSpiReady,
+                    NULL,
+                    &RegistrationSpiReady
+                    );
+  ASSERT (EventSpiReady != NULL);
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.c
new file mode 100644
index 0000000000..c0cde2c32c
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.c
@@ -0,0 +1,87 @@
+/** @file
+Platform init DXE driver for this platform.
+
+Copyright (c) 2013 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// Statements that include other files
+//
+#include "PlatformInitDxe.h"
+#include <Library/PciLib.h>
+#include <IndustryStandard/Pci.h>
+
+VOID
+GetQncName (
+  VOID
+  )
+{
+  DEBUG  ((EFI_D_INFO, "QNC Name: "));
+  switch (PciRead16 (PCI_LIB_ADDRESS (MC_BUS, MC_DEV, MC_FUN, PCI_DEVICE_ID_OFFSET))) {
+  case QUARK_MC_DEVICE_ID:
+    DEBUG  ((EFI_D_INFO, "Quark"));
+    break;
+  case QUARK2_MC_DEVICE_ID:
+    DEBUG  ((EFI_D_INFO, "Quark2"));
+    break;
+  default:
+    DEBUG  ((EFI_D_INFO, "Unknown"));
+  }
+
+  //
+  // Revision
+  //
+  switch (PciRead8 (PCI_LIB_ADDRESS (MC_BUS, MC_DEV, MC_FUN, PCI_REVISION_ID_OFFSET))) {
+  case QNC_MC_REV_ID_A0:
+    DEBUG  ((EFI_D_INFO, " - A0 stepping\n"));
+    break;
+  default:
+    DEBUG  ((EFI_D_INFO, " - xx\n"));
+  }
+
+  return;
+}
+
+EFI_STATUS
+EFIAPI
+PlatformInit (
+  IN EFI_HANDLE                         ImageHandle,
+  IN EFI_SYSTEM_TABLE                   *SystemTable
+  )
+/*++
+
+Routine Description:
+  Entry point for the driver.
+
+Arguments:
+
+  ImageHandle  -  Image Handle.
+  SystemTable  -  EFI System Table.
+
+Returns:
+
+  EFI_SUCCESS  -  Function has completed successfully.
+
+--*/
+{
+  EFI_STATUS  Status;
+
+  GetQncName();
+
+  //
+  // Create events for configuration callbacks.
+  //
+  CreateConfigEvents ();
+
+  //
+  // Init Platform LEDs.
+  //
+  Status = PlatformLedInit ((EFI_PLATFORM_TYPE)PcdGet16 (PcdPlatformType));
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.h b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.h
new file mode 100644
index 0000000000..603d6050f2
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.h
@@ -0,0 +1,58 @@
+/** @file
+Platform init DXE driver header file.
+
+Copyright (c) 2013 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _PLATFORM_TYPES_H_
+#define _PLATFORM_TYPES_H_
+
+#include <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/PlatformHelperLib.h>
+#include <Library/PlatformPcieHelperLib.h>
+#include <Library/IntelQNCLib.h>
+#include <Library/QNCAccessLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/I2cLib.h>
+#include <Protocol/Variable.h>
+#include <Protocol/Cpu.h>
+#include <Protocol/PciEnumerationComplete.h>
+#include <Protocol/Spi.h>
+#include <Protocol/PlatformSmmSpiReady.h>
+#include <Protocol/SmmConfiguration.h>
+#include <Guid/HobList.h>
+#include <IntelQNCRegs.h>
+#include <Platform.h>
+#include <Pcal9555.h>
+#include <PlatformBoards.h>
+#include <IohAccess.h>
+
+#define BLOCK_SIZE_32KB                             0x8000
+#define BLOCK_SIZE_64KB                             0x10000
+
+//
+// Function prototypes for routines private to this driver.
+//
+EFI_STATUS
+EFIAPI
+CreateConfigEvents (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+PlatformPcal9555Config (
+  IN CONST EFI_PLATFORM_TYPE              PlatformType
+  );
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.inf b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.inf
new file mode 100644
index 0000000000..2605050612
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.inf
@@ -0,0 +1,56 @@
+## @file
+# Component description file for Quark Platform Init DXE module.
+#
+# Copyright (c) 2013 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformInitDxe
+  FILE_GUID                      = 2E6A521C-F697-402d-9774-98B2B7E140F3
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = PlatformInit
+
+[Sources]
+  PlatformInitDxe.h
+  PlatformInitDxe.c
+  PlatformConfig.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  HobLib
+  DebugLib
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  DxeServicesTableLib
+  PlatformHelperLib
+  PlatformPcieHelperLib
+  DxeServicesLib
+  IntelQNCLib
+  QNCAccessLib
+  BaseMemoryLib
+  I2cLib
+
+[Protocols]
+  gEfiFirmwareVolumeBlockProtocolGuid
+  gEfiCpuArchProtocolGuid
+  gEfiSmmConfigurationProtocolGuid
+  gEfiSmmSpiReadyProtocolGuid
+
+[Pcd]
+  gQuarkPlatformTokenSpaceGuid.PcdPlatformType
+
+[Depex]
+  TRUE
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveMemoryConfig.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveMemoryConfig.c
new file mode 100644
index 0000000000..e6455acd63
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveMemoryConfig.c
@@ -0,0 +1,118 @@
+/** @file
+This is the driver that locates the MemoryConfigurationData HOB, if it
+exists, and saves the data to nvRAM.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+
+#include <Guid/MemoryConfigData.h>
+#include <Guid/DebugMask.h>
+
+EFI_STATUS
+EFIAPI
+SaveMemoryConfigEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+/*++
+
+  Routine Description:
+    This is the standard EFI driver point that detects whether there is a
+    MemoryConfigurationData HOB and, if so, saves its data to nvRAM.
+
+  Arguments:
+    ImageHandle   - Handle for the image of this driver
+    SystemTable   - Pointer to the EFI System Table
+
+  Returns:
+    EFI_SUCCESS   - if the data is successfully saved or there was no data
+    EFI_NOT_FOUND - if the HOB list could not be located.
+    EFI_UNLOAD_IMAGE - It is not success
+
+--*/
+{
+  EFI_STATUS  Status;
+  VOID        *HobList;
+  EFI_HOB_GUID_TYPE *GuidHob;
+  VOID        *HobData;
+  VOID        *VariableData;
+  UINTN       DataSize;
+  UINTN       BufferSize;
+
+  DataSize      = 0;
+  VariableData  = NULL;
+  GuidHob = NULL;
+  HobList = NULL;
+  HobData = NULL;
+  Status  = EFI_UNSUPPORTED;
+
+  //
+  // Get the HOB list.  If it is not present, then ASSERT.
+  //
+  HobList = GetHobList ();
+  ASSERT (HobList != NULL);
+
+  //
+  // 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.
+  //
+  GuidHob = GetNextGuidHob (&gEfiMemoryConfigDataGuid, HobList);
+  if (GuidHob != NULL) {
+    HobData = GET_GUID_HOB_DATA (GuidHob);
+    DataSize = GET_GUID_HOB_DATA_SIZE (GuidHob);
+    //
+    // Use the HOB to save Memory Configuration Data
+    //
+    BufferSize = DataSize;
+    VariableData = AllocatePool (BufferSize);
+    ASSERT (VariableData != NULL);
+    Status = gRT->GetVariable (
+                    EFI_MEMORY_CONFIG_DATA_NAME,
+                    &gEfiMemoryConfigDataGuid,
+                    NULL,
+                    &BufferSize,
+                    VariableData
+                    );
+    if (Status == EFI_BUFFER_TOO_SMALL) {
+      gBS->FreePool (VariableData);
+      VariableData = AllocatePool (BufferSize);
+      ASSERT (VariableData != NULL);
+      Status = gRT->GetVariable (
+                      EFI_MEMORY_CONFIG_DATA_NAME,
+                      &gEfiMemoryConfigDataGuid,
+                      NULL,
+                      &BufferSize,
+                      VariableData
+                      );
+    }
+
+    if (EFI_ERROR(Status) || BufferSize != DataSize || CompareMem (HobData, VariableData, DataSize) != 0) {
+      Status = gRT->SetVariable (
+                      EFI_MEMORY_CONFIG_DATA_NAME,
+                      &gEfiMemoryConfigDataGuid,
+                      (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS),
+                      DataSize,
+                      HobData
+                      );
+      ASSERT((Status == EFI_SUCCESS) || (Status == EFI_OUT_OF_RESOURCES));
+    }
+
+    gBS->FreePool (VariableData);
+  }
+
+  //
+  // This driver does not produce any protocol services, so always unload it.
+  //
+  return Status;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveMemoryConfig.inf b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveMemoryConfig.inf
new file mode 100644
index 0000000000..c980a3cd8c
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveMemoryConfig.inf
@@ -0,0 +1,44 @@
+## @file
+# Component description file for SaveMemoryConfig module
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION            = 0x00010005
+  BASE_NAME              = SaveMemoryConfig
+  FILE_GUID              = 0F99E33C-CA0C-4aa2-887D-B57EC9050278
+  MODULE_TYPE            = DXE_DRIVER
+  VERSION_STRING         = 1.0
+  ENTRY_POINT            = SaveMemoryConfigEntryPoint
+
+[sources]
+  SaveMemoryConfig.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  MemoryAllocationLib
+  BaseMemoryLib
+  UefiRuntimeServicesTableLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  HobLib
+
+[Protocols]
+
+[Guids]
+  gEfiGenericVariableGuid
+  gEfiMemoryConfigDataGuid
+
+[Depex]
+  gEdkiiVariableLockProtocolGuid  AND
+  gEfiVariableArchProtocolGuid  AND
+  gEfiVariableWriteArchProtocolGuid
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/CommonHeader.h b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/CommonHeader.h
new file mode 100644
index 0000000000..e863a41ff4
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/CommonHeader.h
@@ -0,0 +1,55 @@
+/** @file
+Common header file shared by all source files.
+
+This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+
+
+#include <PiDxe.h>
+#include <IntelQNCDxe.h>
+#include <IndustryStandard/Pci22.h>
+
+#include <Guid/MdeModuleHii.h>
+#include <Protocol/Smbios.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/DiskInfo.h>
+#include <Protocol/PlatformPolicy.h>
+#include <Protocol/MpService.h>
+
+#include <Protocol/HiiString.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/HiiConfigRouting.h>
+#include <Protocol/HiiConfigAccess.h>
+
+#include <Protocol/IdeControllerInit.h>
+#include <Protocol/PciIo.h>
+
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HiiLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IntelQNCLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/S3IoLib.h>
+#include <Library/S3PciLib.h>
+#include <Library/DevicePathLib.h>
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/DxePlatform.inf b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/DxePlatform.inf
new file mode 100644
index 0000000000..fb59706c70
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/DxePlatform.inf
@@ -0,0 +1,76 @@
+## @file
+# Component description file for DxePlatform module.
+#
+# This driver initializes platform configuration setting and installs several platform policy potocols.
+# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = DxePlatform
+  FILE_GUID                      = DAA55048-BC3F-4dd9-999B-F58ABF2BBFCC
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = DxePlatformDriverEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  KeyboardLayout.c
+  QNCRegTable.c
+  processor.c
+  SetupPlatform.c
+  SetupPlatform.h
+  Strings.uni
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  IoLib
+  IntelQNCLib
+  PcdLib
+  PrintLib
+  MemoryAllocationLib
+  BaseMemoryLib
+  S3BootScriptLib
+  DebugLib
+  UefiRuntimeServicesTableLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  BaseLib
+  S3IoLib
+  S3PciLib
+  HiiLib
+  HobLib
+  PciLib
+  UefiLib
+
+[Guids]
+
+[Protocols]
+  gEfiPlatformPolicyProtocolGuid                # PROTOCOL ALWAYS_PRODUCED
+  gEfiHiiDatabaseProtocolGuid                   # PROTOCOL ALWAYS_CONSUMED
+  gEfiHiiConfigAccessProtocolGuid               # PROTOCOL ALWAYS_CONSUMED
+  gEfiHiiConfigRoutingProtocolGuid              # PROTOCOL ALWAYS_CONSUMED
+
+[Pcd]
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdRcbaMmioBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdQuarkAgent0IR
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdQuarkAgent1IR
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdQuarkAgent2IR
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdQuarkAgent3IR
+
+[Depex]
+  # AND EFI_SDRAM_MEMORY_SETUP_PROTOCOL_GUID AND
+  gEfiVariableArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid AND gEfiHiiDatabaseProtocolGuid AND gPcdProtocolGuid
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/KeyboardLayout.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/KeyboardLayout.c
new file mode 100644
index 0000000000..01dad5d34b
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/KeyboardLayout.c
@@ -0,0 +1,262 @@
+/** @file
+Example code to register customized keyboard layout to HII database.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CommonHeader.h"
+
+//
+// Define "`" as Non-spacing key to switch "a","u","i","o","e"
+//
+#define ENABLE_NS_KEY           1
+
+#ifdef ENABLE_NS_KEY
+#define KEYBOARD_KEY_COUNT       (104 + 5)
+#else
+#define KEYBOARD_KEY_COUNT       104
+#endif
+
+#pragma pack (1)
+typedef struct {
+  //
+  // This 4-bytes total array length is required by PreparePackageList()
+  //
+  UINT32                 Length;
+
+  //
+  // Keyboard Layout package definition
+  //
+  EFI_HII_PACKAGE_HEADER PackageHeader;
+  UINT16                 LayoutCount;
+
+  //
+  // EFI_HII_KEYBOARD_LAYOUT
+  //
+  UINT16                 LayoutLength;
+  EFI_GUID               Guid;
+  UINT32                 LayoutDescriptorStringOffset;
+  UINT8                  DescriptorCount;
+  EFI_KEY_DESCRIPTOR     KeyDescriptor[KEYBOARD_KEY_COUNT];
+  UINT16                 DescriptionCount;      // EFI_DESCRIPTION_STRING_BUNDLE
+  CHAR16                 Language[5];        // RFC4646 Language Code: "en-US"
+  CHAR16                 Space;
+  CHAR16                 DescriptionString[17]; // Description: "English Keyboard"
+} KEYBOARD_LAYOUT_PACK_BIN;
+#pragma pack()
+
+#define KEYBOARD_LAYOUT_PACKAGE_GUID \
+  { \
+    0xd66f7b7a, 0x5e06, 0x49f3, { 0xa1, 0xcf, 0x12, 0x8d, 0x4, 0x86, 0xc2, 0x7c } \
+  }
+
+#define KEYBOARD_LAYOUT_KEY_GUID \
+  { \
+    0xd9db96f4, 0xff47, 0x4eb6, { 0x8a, 0x4, 0x79, 0x5b, 0x56, 0x87, 0xb, 0x4e } \
+  }
+
+EFI_GUID  mKeyboardLayoutPackageGuid = KEYBOARD_LAYOUT_PACKAGE_GUID;
+EFI_GUID  mKeyboardLayoutKeyGuid = KEYBOARD_LAYOUT_KEY_GUID;
+
+KEYBOARD_LAYOUT_PACK_BIN  mKeyboardLayoutBin = {
+  sizeof (KEYBOARD_LAYOUT_PACK_BIN),   // Binary size
+
+  //
+  // EFI_HII_PACKAGE_HEADER
+  //
+  {
+    sizeof (KEYBOARD_LAYOUT_PACK_BIN) - sizeof (UINT32),
+    EFI_HII_PACKAGE_KEYBOARD_LAYOUT
+  },
+  1,  // LayoutCount
+  sizeof (KEYBOARD_LAYOUT_PACK_BIN) - sizeof (UINT32) - sizeof (EFI_HII_PACKAGE_HEADER) - sizeof (UINT16), // LayoutLength
+  KEYBOARD_LAYOUT_KEY_GUID,  // KeyGuid
+  sizeof (UINT16) + sizeof (EFI_GUID) + sizeof (UINT32) + sizeof (UINT8) + (KEYBOARD_KEY_COUNT * sizeof (EFI_KEY_DESCRIPTOR)), // LayoutDescriptorStringOffset
+  KEYBOARD_KEY_COUNT, // DescriptorCount
+  {
+    //
+    // EFI_KEY_DESCRIPTOR
+    //
+    {EfiKeyC1,         'a',      'A',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyB5,         'b',      'B',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyB3,         'c',      'C',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyC3,         'd',      'D',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyD3,         'e',      'E',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyC4,         'f',      'F',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyC5,         'g',      'G',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyC6,         'h',      'H',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyD8,         'i',      'I',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyC7,         'j',      'J',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyC8,         'k',      'K',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyC9,         'l',      'L',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyB7,         'm',      'M',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyB6,         'n',      'N',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyD9,         'o',      'O',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyD10,        'p',      'P',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyD1,         'q',      'Q',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyD4,         'r',      'R',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyC2,         's',      'S',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyD5,         't',      'T',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyD7,         'u',      'U',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyB4,         'v',      'V',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyD2,         'w',      'W',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyB2,         'x',      'X',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyD6,         'y',      'Y',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyB1,         'z',      'Z',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyE1,         '1',      '!',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},
+    {EfiKeyE2,         '2',      '@',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},
+    {EfiKeyE3,         '3',      '#',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},
+    {EfiKeyE4,         '4',      '$',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},
+    {EfiKeyE5,         '5',      '%',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},
+    {EfiKeyE6,         '6',      '^',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},
+    {EfiKeyE7,         '7',      '&',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},
+    {EfiKeyE8,         '8',      '*',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},
+    {EfiKeyE9,         '9',      '(',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},
+    {EfiKeyE10,        '0',      ')',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},
+    {EfiKeyEnter,      0x0d,     0x0d, 0, 0,  EFI_NULL_MODIFIER,   0},
+    {EfiKeyEsc,        0x1b,     0x1b, 0, 0,  EFI_NULL_MODIFIER,   0},
+    {EfiKeyBackSpace,  0x08,     0x08, 0, 0,  EFI_NULL_MODIFIER,   0},
+    {EfiKeyTab,        0x09,     0x09, 0, 0,  EFI_NULL_MODIFIER,   0},
+    {EfiKeySpaceBar,   ' ',      ' ',  0, 0,  EFI_NULL_MODIFIER,   0},
+    {EfiKeyE11,        '-',      '_',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},
+    {EfiKeyE12,        '=',      '+',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},
+    {EfiKeyD11,        '[',      '{',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},
+    {EfiKeyD12,        ']',      '}',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},
+    {EfiKeyD13,        '\\',     '|',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},
+    {EfiKeyC10,        ';',      ':',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},
+    {EfiKeyC11,        '\'',     '"',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},
+
+#ifdef ENABLE_NS_KEY
+    //
+    // Non-Spacing key example
+    //
+    {EfiKeyE0,         0,      0,      0, 0, EFI_NS_KEY_MODIFIER, 0},
+    {EfiKeyC1,         0x00E2, 0x00C2, 0, 0, EFI_NS_KEY_DEPENDENCY_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyD3,         0x00EA, 0x00CA, 0, 0, EFI_NS_KEY_DEPENDENCY_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyD8,         0x00EC, 0x00CC, 0, 0, EFI_NS_KEY_DEPENDENCY_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyD9,         0x00F4, 0x00D4, 0, 0, EFI_NS_KEY_DEPENDENCY_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+    {EfiKeyD7,         0x00FB, 0x00CB, 0, 0, EFI_NS_KEY_DEPENDENCY_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+#else
+    {EfiKeyE0,         '`',      '~',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},
+#endif
+
+    {EfiKeyB8,         ',',      '<',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},
+    {EfiKeyB9,         '.',      '>',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},
+    {EfiKeyB10,        '/',      '?',  0, 0,  EFI_NULL_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT},
+    {EfiKeyCapsLock,   0x00,     0x00, 0, 0,  EFI_CAPS_LOCK_MODIFIER,            0},
+    {EfiKeyF1,         0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_ONE_MODIFIER,     0},
+    {EfiKeyF2,         0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_TWO_MODIFIER,     0},
+    {EfiKeyF3,         0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_THREE_MODIFIER,   0},
+    {EfiKeyF4,         0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_FOUR_MODIFIER,    0},
+    {EfiKeyF5,         0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_FIVE_MODIFIER,    0},
+    {EfiKeyF6,         0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_SIX_MODIFIER,     0},
+    {EfiKeyF7,         0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_SEVEN_MODIFIER,   0},
+    {EfiKeyF8,         0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_EIGHT_MODIFIER,   0},
+    {EfiKeyF9,         0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_NINE_MODIFIER,    0},
+    {EfiKeyF10,        0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_TEN_MODIFIER,     0},
+    {EfiKeyF11,        0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_ELEVEN_MODIFIER,  0},
+    {EfiKeyF12,        0x00,     0x00, 0, 0,  EFI_FUNCTION_KEY_TWELVE_MODIFIER,  0},
+    {EfiKeyPrint,      0x00,     0x00, 0, 0,  EFI_PRINT_MODIFIER,                0},
+    {EfiKeySLck,       0x00,     0x00, 0, 0,  EFI_SCROLL_LOCK_MODIFIER,          0},
+    {EfiKeyPause,      0x00,     0x00, 0, 0,  EFI_PAUSE_MODIFIER,                0},
+    {EfiKeyIns,        0x00,     0x00, 0, 0,  EFI_INSERT_MODIFIER,               0},
+    {EfiKeyHome,       0x00,     0x00, 0, 0,  EFI_HOME_MODIFIER,                 0},
+    {EfiKeyPgUp,       0x00,     0x00, 0, 0,  EFI_PAGE_UP_MODIFIER,              0},
+    {EfiKeyDel,        0x00,     0x00, 0, 0,  EFI_DELETE_MODIFIER,               0},
+    {EfiKeyEnd,        0x00,     0x00, 0, 0,  EFI_END_MODIFIER,                  0},
+    {EfiKeyPgDn,       0x00,     0x00, 0, 0,  EFI_PAGE_DOWN_MODIFIER,            0},
+    {EfiKeyRightArrow, 0x00,     0x00, 0, 0,  EFI_RIGHT_ARROW_MODIFIER,          0},
+    {EfiKeyLeftArrow,  0x00,     0x00, 0, 0,  EFI_LEFT_ARROW_MODIFIER,           0},
+    {EfiKeyDownArrow,  0x00,     0x00, 0, 0,  EFI_DOWN_ARROW_MODIFIER,           0},
+    {EfiKeyUpArrow,    0x00,     0x00, 0, 0,  EFI_UP_ARROW_MODIFIER,             0},
+    {EfiKeyNLck,       0x00,     0x00, 0, 0,  EFI_NUM_LOCK_MODIFIER,             0},
+    {EfiKeySlash,      '/',      '/',  0, 0,  EFI_NULL_MODIFIER,                 0},
+    {EfiKeyAsterisk,   '*',      '*',  0, 0,  EFI_NULL_MODIFIER,                 0},
+    {EfiKeyMinus,      '-',      '-',  0, 0,  EFI_NULL_MODIFIER,                 0},
+    {EfiKeyPlus,       '+',      '+',  0, 0,  EFI_NULL_MODIFIER,                 0},
+    {EfiKeyEnter,      0x0d,     0x0d, 0, 0,  EFI_NULL_MODIFIER,                 0},
+    {EfiKeyOne,        '1',      '1',  0, 0,  EFI_END_MODIFIER,         EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
+    {EfiKeyTwo,        '2',      '2',  0, 0,  EFI_DOWN_ARROW_MODIFIER,  EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
+    {EfiKeyThree,      '3',      '3',  0, 0,  EFI_PAGE_DOWN_MODIFIER,   EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
+    {EfiKeyFour,       '4',      '4',  0, 0,  EFI_LEFT_ARROW_MODIFIER,  EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
+    {EfiKeyFive,       '5',      '5',  0, 0,  EFI_NULL_MODIFIER,        EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
+    {EfiKeySix,        '6',      '6',  0, 0,  EFI_RIGHT_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
+    {EfiKeySeven,      '7',      '7',  0, 0,  EFI_HOME_MODIFIER,        EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
+    {EfiKeyEight,      '8',      '8',  0, 0,  EFI_UP_ARROW_MODIFIER,    EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
+    {EfiKeyNine,       '9',      '9',  0, 0,  EFI_PAGE_UP_MODIFIER,     EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
+    {EfiKeyZero,       '0',      '0',  0, 0,  EFI_INSERT_MODIFIER,      EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
+    {EfiKeyPeriod,     '.',      '.',  0, 0,  EFI_DELETE_MODIFIER,      EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
+    {EfiKeyA4,         0x00,     0x00, 0, 0,  EFI_MENU_MODIFIER,            0},
+    {EfiKeyLCtrl,      0,        0,    0, 0,  EFI_LEFT_CONTROL_MODIFIER,    0},
+    {EfiKeyLShift,     0,        0,    0, 0,  EFI_LEFT_SHIFT_MODIFIER,      0},
+    {EfiKeyLAlt,       0,        0,    0, 0,  EFI_LEFT_ALT_MODIFIER,        0},
+    {EfiKeyA0,         0,        0,    0, 0,  EFI_LEFT_LOGO_MODIFIER,       0},
+    {EfiKeyRCtrl,      0,        0,    0, 0,  EFI_RIGHT_CONTROL_MODIFIER,   0},
+    {EfiKeyRShift,     0,        0,    0, 0,  EFI_RIGHT_SHIFT_MODIFIER,     0},
+    {EfiKeyA2,         0,        0,    0, 0,  EFI_RIGHT_ALT_MODIFIER,       0},
+    {EfiKeyA3,         0,        0,    0, 0,  EFI_RIGHT_LOGO_MODIFIER,      0},
+  },
+  1,                          // DescriptionCount
+  {'e', 'n', '-', 'U', 'S'},  // RFC4646 language code
+  ' ',                        // Space
+  {'E', 'n', 'g', 'l', 'i', 's', 'h', ' ', 'K', 'e', 'y', 'b', 'o', 'a', 'r', 'd', '\0'}, // DescriptionString[17]
+};
+
+extern EFI_HANDLE mImageHandle;
+
+EFI_STATUS
+InitKeyboardLayout (
+  VOID
+  )
+/*++
+
+  Routine Description:
+    Install keyboard layout package and set current keyboard layout.
+
+  Arguments:
+    None.
+
+  Returns:
+    EFI_STATUS
+
+--*/
+{
+  EFI_STATUS                   Status;
+  EFI_HII_DATABASE_PROTOCOL    *HiiDatabase;
+  EFI_HII_HANDLE               HiiHandle;
+
+  //
+  // Locate Hii database protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiHiiDatabaseProtocolGuid,
+                  NULL,
+                  (VOID**)&HiiDatabase
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Install Keyboard Layout package to HII database
+  //
+  HiiHandle = HiiAddPackages (
+                &mKeyboardLayoutPackageGuid,
+                mImageHandle,
+                &mKeyboardLayoutBin,
+                NULL
+                );
+  if (HiiHandle == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Set current keyboard layout
+  //
+  Status = HiiDatabase->SetKeyboardLayout (HiiDatabase, &mKeyboardLayoutKeyGuid);
+
+  return Status;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/QNCRegTable.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/QNCRegTable.c
new file mode 100644
index 0000000000..cc677e896f
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/QNCRegTable.c
@@ -0,0 +1,80 @@
+/** @file
+Register initialization table for Ich.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+VOID
+PlatformInitQNCRegs (
+  VOID
+  )
+{
+  //
+  // All devices on bus 0.
+  // Device 0:
+  //    FNC 0: Host Bridge
+  // Device 20:
+  //    FNC 0: IOSF2AHB Bridge
+  // Device 21:
+  //    FNC 0: IOSF2AHB Bridge
+  // Device 23:
+  //    FNC 0: PCIe Port 0
+  // Device 24:
+  //    FNC 0: PCIe Port 1
+
+  // Device 31:
+  //    FNC 0: PCI-LPC Bridge
+  //
+  S3PciWrite32 (PCI_LIB_ADDRESS (PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, PCI_FUNCTION_NUMBER_QNC_LPC, R_QNC_LPC_FWH_BIOS_DEC),
+                B_QNC_LPC_FWH_BIOS_DEC_F0 | B_QNC_LPC_FWH_BIOS_DEC_F8 |
+                B_QNC_LPC_FWH_BIOS_DEC_E0 | B_QNC_LPC_FWH_BIOS_DEC_E8 |
+                B_QNC_LPC_FWH_BIOS_DEC_D0 | B_QNC_LPC_FWH_BIOS_DEC_D8 |
+                B_QNC_LPC_FWH_BIOS_DEC_C0 | B_QNC_LPC_FWH_BIOS_DEC_C8
+                );
+
+  //
+  // Program SCI Interrupt for IRQ9
+  //
+  S3PciWrite8 (PCI_LIB_ADDRESS (PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, PCI_FUNCTION_NUMBER_QNC_LPC, R_QNC_LPC_ACTL),
+               V_QNC_LPC_ACTL_SCIS_IRQ9
+               );
+
+  //
+  // Program Quark Interrupt Route Registers
+  //
+  S3MmioWrite16 ((UINTN)PcdGet64(PcdRcbaMmioBaseAddress) + R_QNC_RCRB_AGENT0IR,
+             PcdGet16(PcdQuarkAgent0IR)
+             );
+  S3MmioWrite16 ((UINTN)PcdGet64(PcdRcbaMmioBaseAddress) + R_QNC_RCRB_AGENT1IR,
+             PcdGet16(PcdQuarkAgent1IR)
+             );
+  S3MmioWrite16 ((UINTN)PcdGet64(PcdRcbaMmioBaseAddress) + R_QNC_RCRB_AGENT2IR,
+             PcdGet16(PcdQuarkAgent2IR)
+             );
+  S3MmioWrite16 ((UINTN)PcdGet64(PcdRcbaMmioBaseAddress) + R_QNC_RCRB_AGENT3IR,
+             PcdGet16(PcdQuarkAgent3IR)
+             );
+
+  //
+  // Program SVID and SID for QNC PCI devices. In order to boost performance, we
+  // combine two 16 bit PCI_WRITE into one 32 bit PCI_WRITE. The programmed LPC SVID
+  // will reflect on all internal devices's SVID registers
+  //
+  S3PciWrite32 (PCI_LIB_ADDRESS (PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, PCI_FUNCTION_NUMBER_QNC_LPC, R_EFI_PCI_SVID),
+                (UINT32)(V_INTEL_VENDOR_ID + (QUARK_V_LPC_DEVICE_ID_0 << 16))
+                );
+
+  //
+  // Write once on Element Self Description Register before OS boot
+  //
+  QNCMmio32And (PcdGet64(PcdRcbaMmioBaseAddress), 0x04, 0xFF00FFFF);
+
+  return;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.c
new file mode 100644
index 0000000000..7e36fdfcef
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.c
@@ -0,0 +1,97 @@
+/** @file
+Platform Initialization Driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CommonHeader.h"
+
+#include "SetupPlatform.h"
+#include <Library/HobLib.h>
+
+EFI_HANDLE            mImageHandle = NULL;
+
+EFI_HII_DATABASE_PROTOCOL        *mHiiDataBase = NULL;
+EFI_HII_CONFIG_ROUTING_PROTOCOL  *mHiiConfigRouting = NULL;
+
+UINT8                    mSmbusRsvdAddresses[PLATFORM_NUM_SMBUS_RSVD_ADDRESSES] = {
+  SMBUS_ADDR_CH_A_1,
+  SMBUS_ADDR_CK505,
+  SMBUS_ADDR_THERMAL_SENSOR1,
+  SMBUS_ADDR_THERMAL_SENSOR2
+};
+
+EFI_PLATFORM_POLICY_PROTOCOL    mPlatformPolicyData = {
+  PLATFORM_NUM_SMBUS_RSVD_ADDRESSES,
+  mSmbusRsvdAddresses
+};
+
+EFI_STATUS
+DxePlatformDriverEntry (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+/*++
+
+  Routine Description:
+    This is the standard EFI driver point for the D845GRgPlatform Driver. This
+    driver is responsible for setting up any platform specific policy or
+    initialization information.
+
+  Arguments:
+    ImageHandle     - Handle for the image of this driver
+    SystemTable     - Pointer to the EFI System Table
+
+  Returns:
+    EFI_SUCCESS     - Policy decisions set
+
+--*/
+{
+  EFI_STATUS                  Status;
+  EFI_HANDLE                  Handle;
+
+  S3BootScriptSaveInformationAsciiString (
+    "SetupDxeEntryBegin"
+    );
+
+  mImageHandle = ImageHandle;
+
+  Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID**)&mHiiDataBase);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID**)&mHiiConfigRouting);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Initialize keyboard layout
+  //
+  Status = InitKeyboardLayout ();
+
+  //
+  // Initialize ICH registers
+  //
+  PlatformInitQNCRegs();
+
+  ProducePlatformCpuData ();
+
+  //
+  // Install protocol to to allow access to this Policy.
+  //
+  Handle = NULL;
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Handle,
+                  &gEfiPlatformPolicyProtocolGuid, &mPlatformPolicyData,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+  S3BootScriptSaveInformationAsciiString (
+    "SetupDxeEntryEnd"
+    );
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.h b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.h
new file mode 100644
index 0000000000..a0ea25ca90
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.h
@@ -0,0 +1,71 @@
+/** @file
+Header file for Platform Initialization Driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _SETUP_PLATFORM_H
+#define _SETUP_PLATFORM_H
+
+//
+// Data
+//
+#define PLATFORM_NUM_SMBUS_RSVD_ADDRESSES 4
+#define VAR_OFFSET(Field)     ((UINT16) ((UINTN) &(((SYSTEM_CONFIGURATION *) 0)->Field)))
+#define QUESTION_ID(Field)    (VAR_OFFSET (Field) + 1)
+
+#define SMBUS_ADDR_CH_A_1     0xA0
+#define SMBUS_ADDR_CK505      0xD2
+#define SMBUS_ADDR_THERMAL_SENSOR1 0x4C
+#define SMBUS_ADDR_THERMAL_SENSOR2 0x4D
+
+///
+/// HII specific Vendor Device Path Node definition.
+///
+#pragma pack(1)
+
+typedef struct {
+  VENDOR_DEVICE_PATH             VendorDevicePath;
+  UINT16                         UniqueId;
+} HII_VENDOR_DEVICE_PATH_NODE;
+
+///
+/// HII specific Vendor Device Path definition.
+///
+typedef struct {
+  HII_VENDOR_DEVICE_PATH_NODE    Node;
+  EFI_DEVICE_PATH_PROTOCOL       End;
+} HII_VENDOR_DEVICE_PATH;
+
+#pragma pack()
+
+//
+// Prototypes
+//
+VOID
+ProducePlatformCpuData (
+  VOID
+  );
+
+VOID
+PlatformInitQNCRegs (
+  VOID
+  );
+
+EFI_STATUS
+InitKeyboardLayout (
+  VOID
+  );
+
+//
+// Global externs
+//
+extern UINT8 UefiSetupDxeStrings[];
+
+extern EFI_HII_DATABASE_PROTOCOL        *mHiiDataBase;
+extern EFI_HII_CONFIG_ROUTING_PROTOCOL  *mHiiConfigRouting;
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/Strings.uni b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/Strings.uni
new file mode 100644
index 0000000000..69d497d69a
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/Strings.uni
@@ -0,0 +1,47 @@
+// /** @file
+// String definitions for Sample Setup formset.
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+// **/
+
+/=#
+
+#langdef   en-US "English"
+#langdef   fr-FR "Français"
+#langdef   es-ES "Español"
+
+#string STR_LGA775                       #language en-US  "L775"
+#string STR_LGA775                       #language fr-FR  "L775"
+#string STR_LGA775                       #language es-ES  "L775"
+
+
+// Enable or Disable
+#string STR_ENABLE       #language en-US  "Enable"
+#string STR_ENABLE       #language fr-FR  "Activé"
+#string STR_ENABLE       #language es-ES  "Activada"
+
+#string STR_DISABLE      #language en-US  "Disable"
+#string STR_DISABLE      #language fr-FR  "Désactivé"
+#string STR_DISABLE      #language es-ES  "Desactivada"
+
+#string STR_AUTO         #language en-US  "Auto"
+#string STR_AUTO         #language fr-FR  "Auto"
+#string STR_AUTO         #language es-ES  "Auto"
+
+// Unknown
+#string STR_UNKNOWN      #language en-US  "Unknown"
+#string STR_UNKNOWN      #language fr-FR  "Unknown"
+#string STR_UNKNOWN      #language es-ES  "Unknown"
+
+
+// NULL String
+#string STR_NULL_STRING            #language en-US  ""
+
+#string STR_VAR_TOTAL_MEMORY_SIZE      #language en-US  "54"
+
+#string VAR_EQ_CONFIG_MODE_NAME         #language en-US  "67"
+// End of file
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/processor.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/processor.c
new file mode 100644
index 0000000000..e86901f9b6
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/processor.c
@@ -0,0 +1,40 @@
+/** @file
+Platform CPU Data
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SetupPlatform.h"
+
+
+#define NUMBER_OF_PACKAGES 1
+
+CHAR16 *SocketNames[NUMBER_OF_PACKAGES];
+CHAR16 *AssetTags[NUMBER_OF_PACKAGES];
+
+CHAR16 EmptyString[] = L" ";
+CHAR16 SocketString[] = L"LGA775";
+
+VOID
+ProducePlatformCpuData (
+  VOID
+  )
+{
+  UINTN                                      Index;
+
+  for (Index = 0; Index < NUMBER_OF_PACKAGES; Index++) {
+
+    //
+    // The String Package of a module is registered together with all IFR packages.
+    // So we just arbitrarily pick a package GUID that is always installed to get the string.
+    //
+    AssetTags[Index] = EmptyString;
+    SocketNames[Index] = SocketString;
+  }
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/CommonHeader.h b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/CommonHeader.h
new file mode 100644
index 0000000000..a21de76efd
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/CommonHeader.h
@@ -0,0 +1,34 @@
+/** @file
+Common header file shared by all source files.
+
+This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+
+
+#include <FrameworkDxe.h>
+#include <IndustryStandard/SmBios.h>
+#include <Protocol/Smbios.h>
+#include <Guid/MdeModuleHii.h>
+#include <Guid/DataHubRecords.h>
+
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/HiiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiLib.h>
+
+extern EFI_HII_HANDLE gHiiHandle;
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturer.uni b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturer.uni
new file mode 100644
index 0000000000..c51183ef4e
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturer.uni
@@ -0,0 +1,19 @@
+// /** @file
+// System Manufacturer Information
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+// **/
+
+/=#
+
+#string STR_MISC_BASE_BOARD_MANUFACTURER     #language en-US  "Intel Corp."
+#string STR_MISC_BASE_BOARD_PRODUCT_NAME     #language en-US  "QUARK"
+#string STR_MISC_BASE_BOARD_VERSION          #language en-US  "FAB-D"
+#string STR_MISC_BASE_BOARD_SERIAL_NUMBER    #language en-US  "XXXXXXXXXXXX"
+#string STR_MISC_BASE_BOARD_ASSET_TAG        #language en-US  "Base Board Asset Tag"
+#string STR_MISC_BASE_BOARD_CHASSIS_LOCATION #language en-US  "Part Component"
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturerData.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturerData.c
new file mode 100644
index 0000000000..18f4624cf9
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturerData.c
@@ -0,0 +1,45 @@
+/** @file
+Type 2: Base Board Information.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "CommonHeader.h"
+#include "SmbiosMisc.h"
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_BASE_BOARD_MANUFACTURER_DATA, MiscBaseBoardManufacturer)
+= {
+  STRING_TOKEN(STR_MISC_BASE_BOARD_MANUFACTURER),
+  STRING_TOKEN(STR_MISC_BASE_BOARD_PRODUCT_NAME),
+  STRING_TOKEN(STR_MISC_BASE_BOARD_VERSION),
+  STRING_TOKEN(STR_MISC_BASE_BOARD_SERIAL_NUMBER),
+  STRING_TOKEN(STR_MISC_BASE_BOARD_ASSET_TAG),
+  STRING_TOKEN(STR_MISC_BASE_BOARD_CHASSIS_LOCATION),
+  {                         // BaseBoardFeatureFlags
+    1,                      // Motherboard
+    0,                      // RequiresDaughterCard
+    0,                      // Removable
+    1,                      // Replaceable,
+    0,                      // HotSwappable
+    0,                      // Reserved
+  },
+  EfiBaseBoardTypeUnknown,  // BaseBoardType
+  {                         // BaseBoardChassisLink
+    EFI_MISC_SUBCLASS_GUID, // ProducerName
+    1,                      // Instance
+    1,                      // SubInstance
+  },
+  0,                        // BaseBoardNumberLinks
+  {                         // LinkN
+    EFI_MISC_SUBCLASS_GUID, // ProducerName
+    1,                      // Instance
+    1,                      // SubInstance
+  },
+};
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturerFunction.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturerFunction.c
new file mode 100644
index 0000000000..a9597ebcc2
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturerFunction.c
@@ -0,0 +1,181 @@
+/** @file
+Base Board Information boot time changes.
+Misc. subclass type 4.
+SMBIOS type 2.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "CommonHeader.h"
+#include "SmbiosMisc.h"
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscBaseBoardManufacturer (Type 2).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscBaseBoardManufacturer)
+{
+  CHAR8                           *OptionalStrStart;
+  UINTN                           ManuStrLen;
+  UINTN                           ProductStrLen;
+  UINTN                           VerStrLen;
+  UINTN                           AssertTagStrLen;
+  UINTN                           SerialNumStrLen;
+  UINTN                           ChassisStrLen;
+  EFI_STATUS                      Status;
+  EFI_STRING                      Manufacturer;
+  EFI_STRING                      Product;
+  EFI_STRING                      Version;
+  EFI_STRING                      SerialNumber;
+  EFI_STRING                      AssertTag;
+  EFI_STRING                      Chassis;
+  STRING_REF                      TokenToGet;
+  STRING_REF                        TokenToUpdate;
+  EFI_SMBIOS_HANDLE               SmbiosHandle;
+  SMBIOS_TABLE_TYPE2              *SmbiosRecord;
+  EFI_MISC_BASE_BOARD_MANUFACTURER   *ForType2InputData;
+  UINTN                              TypeStringSize;
+  CHAR16                             TypeString[SMBIOS_STRING_MAX_LENGTH];
+
+  ForType2InputData = (EFI_MISC_BASE_BOARD_MANUFACTURER *)RecordData;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_MANUFACTURER);
+  Manufacturer = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+  ManuStrLen = StrLen(Manufacturer);
+  if (ManuStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  StrCpy (TypeString, L"");
+  TypeStringSize = PcdGetSize (PcdPlatformTypeName);
+  if (TypeStringSize > 0 && TypeStringSize <= sizeof (TypeString)) {
+    CopyMem (TypeString, PcdGetPtr (PcdPlatformTypeName), TypeStringSize);
+  }
+  if (StrLen (TypeString) == 0) {
+    StrCpy (TypeString, L"Unknown");
+  }
+  TokenToUpdate = STRING_TOKEN (STR_MISC_BASE_BOARD_PRODUCT_NAME);
+  HiiSetString (mHiiHandle, TokenToUpdate, TypeString, NULL);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_PRODUCT_NAME);
+  Product = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+  ProductStrLen = StrLen(TypeString);
+  if (ProductStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_VERSION);
+  Version = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+  VerStrLen = StrLen(Version);
+  if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_SERIAL_NUMBER);
+  SerialNumber = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+  SerialNumStrLen = StrLen(SerialNumber);
+  if (SerialNumStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_ASSET_TAG);
+  AssertTag = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+  AssertTagStrLen = StrLen(AssertTag);
+  if (AssertTagStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_CHASSIS_LOCATION);
+  Chassis = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+  ChassisStrLen = StrLen(Chassis);
+  if (ChassisStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE3) + ManuStrLen + 1 + ProductStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1 + ChassisStrLen +1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE3) + ManuStrLen + 1 + ProductStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1 + ChassisStrLen +1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_BASEBOARD_INFORMATION;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE2);
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle = 0;
+  //
+  // Manu will be the 1st optional string following the formatted structure.
+  //
+  SmbiosRecord->Manufacturer = 1;
+  //
+  // ProductName will be the 2st optional string following the formatted structure.
+  //
+  SmbiosRecord->ProductName  = 2;
+  //
+  // Version will be the 3rd optional string following the formatted structure.
+  //
+  SmbiosRecord->Version = 3;
+  //
+  // SerialNumber will be the 4th optional string following the formatted structure.
+  //
+  SmbiosRecord->SerialNumber = 4;
+  //
+  // AssertTag will be the 5th optional string following the formatted structure.
+  //
+  SmbiosRecord->AssetTag = 5;
+
+  //
+  // LocationInChassis will be the 6th optional string following the formatted structure.
+  //
+  SmbiosRecord->LocationInChassis = 6;
+  SmbiosRecord->FeatureFlag = (*(BASE_BOARD_FEATURE_FLAGS*)&(ForType2InputData->BaseBoardFeatureFlags));
+  SmbiosRecord->ChassisHandle  = 0;
+  SmbiosRecord->BoardType      = (UINT8)ForType2InputData->BaseBoardType;
+  SmbiosRecord->NumberOfContainedObjectHandles = 0;
+
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  //
+  // Since we fill NumberOfContainedObjectHandles = 0 for simple, just after this filed to fill string
+  //
+  //OptionalStrStart -= 2;
+  UnicodeStrToAsciiStr(Manufacturer, OptionalStrStart);
+  UnicodeStrToAsciiStr(Product, OptionalStrStart + ManuStrLen + 1);
+  UnicodeStrToAsciiStr(Version, OptionalStrStart + ManuStrLen + 1 + ProductStrLen + 1);
+  UnicodeStrToAsciiStr(SerialNumber, OptionalStrStart + ManuStrLen + 1 + ProductStrLen + 1 + VerStrLen + 1);
+  UnicodeStrToAsciiStr(AssertTag, OptionalStrStart + ManuStrLen + 1 + ProductStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1);
+  UnicodeStrToAsciiStr(Chassis, OptionalStrStart + ManuStrLen + 1 + ProductStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1);
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+
+  FreePool(SmbiosRecord);
+  return Status;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendor.uni b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendor.uni
new file mode 100644
index 0000000000..b71b2b0947
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendor.uni
@@ -0,0 +1,18 @@
+// /** @file
+// BIOS vendor information.
+// Misc. subclass type 2.
+// SMBIOS type 0.
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+// **/
+
+
+/=#
+
+#string STR_MISC_BIOS_VENDOR           #language en-US  "Intel Corp."
+#string STR_MISC_BIOS_VERSION          #language en-US  "BIOS Version"
+#string STR_MISC_BIOS_RELEASE_DATE     #language en-US  "11/03/2015"
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendorData.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendorData.c
new file mode 100644
index 0000000000..aee8d48487
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendorData.c
@@ -0,0 +1,92 @@
+/** @file
+BIOS vendor information static data.
+Misc. subclass type 2.
+SMBIOS type 0.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_BIOS_VENDOR, MiscBiosVendor) = {
+  STRING_TOKEN (STR_MISC_BIOS_VENDOR),       // BiosVendor
+  STRING_TOKEN (STR_MISC_BIOS_VERSION),      // BiosVersion
+  STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE), // BiosReleaseDate
+  0xE0000,                    // BiosStartingAddress
+  {                           // BiosPhysicalDeviceSize
+    2,                        // Value
+    20,                       // Exponent
+  },
+  {                           // BiosCharacteristics1
+    0,                        // Reserved1                         :2
+    0,                        // Unknown                           :1
+    0,                        // BiosCharacteristicsNotSupported   :1
+    0,                        // IsaIsSupported                    :1
+    0,                        // McaIsSupported                    :1
+
+    0,                        // EisaIsSupported                   :1
+    1,                        // PciIsSupported                    :1
+    0,                        // PcmciaIsSupported                 :1
+    0,                        // PlugAndPlayIsSupported            :1
+    0,                        // ApmIsSupported                    :1
+
+    1,                        // BiosIsUpgradable                  :1
+    1,                        // BiosShadowingAllowed              :1
+    0,                        // VlVesaIsSupported                 :1
+    0,                        // EscdSupportIsAvailable            :1
+    1,                        // BootFromCdIsSupported             :1
+
+    1,                        // SelectableBootIsSupported         :1
+    0,                        // RomBiosIsSocketed                 :1
+    0,                        // BootFromPcmciaIsSupported         :1
+    1,                        // EDDSpecificationIsSupported       :1
+    0,                        // JapaneseNecFloppyIsSupported      :1
+
+    0,                        // JapaneseToshibaFloppyIsSupported  :1
+    0,                        // Floppy525_360IsSupported          :1
+    0,                        // Floppy525_12IsSupported           :1
+    0,                        // Floppy35_720IsSupported           :1
+    0,                        // Floppy35_288IsSupported           :1
+
+    1,                        // PrintScreenIsSupported            :1
+    1,                        // Keyboard8042IsSupported           :1
+    1,                        // SerialIsSupported                 :1
+    1,                        // PrinterIsSupported                :1
+    1,                        // CgaMonoIsSupported                :1
+
+    0,                        // NecPc98                           :1
+    1,                        // AcpiIsSupported                   :1
+    1,                        // UsbLegacyIsSupported              :1
+    0,                        // AgpIsSupported                    :1
+    0,                        // I20BootIsSupported                :1
+
+    0,                        // Ls120BootIsSupported              :1
+    0,                        // AtapiZipDriveBootIsSupported      :1
+    0,                        // Boot1394IsSupported               :1
+    0,                        // SmartBatteryIsSupported           :1
+    1,                        // BiosBootSpecIsSupported           :1
+
+    1,                        // FunctionKeyNetworkBootIsSupported :1
+    0                         // Reserved                          :22
+  },
+  {                           // BiosCharacteristics2
+    0,                        // BiosReserved                      :16
+    0,                        // SystemReserved                    :16
+    0                         // Reserved                          :32
+  },
+  0x1,                        // System BIOS Major Release
+  0x0,                        // System BIOS Minor Release
+  0xFF,                       // Embedded controller firmware major Release
+  0xFF,                       // Embedded controller firmware minor Release
+};
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendorFunction.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendorFunction.c
new file mode 100644
index 0000000000..a27e704302
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendorFunction.c
@@ -0,0 +1,222 @@
+/** @file
+BIOS vendor information boot time changes.
+Misc. subclass type 2.
+SMBIOS type 0.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+/**
+  This function returns the value & exponent to Base2 for a given
+  Hex value. This is used to calculate the BiosPhysicalDeviceSize.
+
+  @param Value                      The hex value which is to be converted into value-exponent form
+  @param Exponent                   The exponent out of the conversion
+
+  @retval EFI_SUCCESS               All parameters were valid and *Value & *Exponent have been set.
+  @retval EFI_INVALID_PARAMETER     Invalid parameter was found.
+
+**/
+EFI_STATUS
+GetValueExponentBase2(
+  IN OUT UINTN        *Value,
+  OUT    UINTN        *Exponent
+  )
+{
+  if ((Value == NULL) || (Exponent == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  while ((*Value % 2) == 0) {
+    *Value=*Value/2;
+    (*Exponent)++;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a byte, with '64k'
+  as the unit.
+
+  @param  Base2Data              Pointer to Base2_Data
+
+  @retval EFI_SUCCESS            Transform successfully.
+  @retval EFI_INVALID_PARAMETER  Invalid parameter was found.
+
+**/
+UINT16
+Base2ToByteWith64KUnit (
+  IN      EFI_EXP_BASE2_DATA  *Base2Data
+  )
+{
+  UINT16              Value;
+  UINT16              Exponent;
+
+  Value     = Base2Data->Value;
+  Exponent  = Base2Data->Exponent;
+  Exponent -= 16;
+  Value <<= Exponent;
+
+  return Value;
+}
+
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscBiosVendor (Type 0).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscBiosVendor)
+{
+  CHAR8                 *OptionalStrStart;
+  UINTN                 VendorStrLen;
+  UINTN                 VerStrLen;
+  UINTN                 DateStrLen;
+  UINTN                 BiosPhysicalSizeHexValue;
+  UINTN                 BiosPhysicalSizeExponent;
+  CHAR16                Version[SMBIOS_STRING_MAX_LENGTH];
+  CHAR16                Vendor[SMBIOS_STRING_MAX_LENGTH];
+  CHAR16                ReleaseDate[SMBIOS_STRING_MAX_LENGTH];
+  EFI_STRING            VersionPtr;
+  EFI_STRING            VendorPtr;
+  EFI_STRING            ReleaseDatePtr;
+  EFI_STATUS            Status;
+  STRING_REF            TokenToGet;
+  STRING_REF            TokenToUpdate;
+  SMBIOS_TABLE_TYPE0    *SmbiosRecord;
+  EFI_SMBIOS_HANDLE     SmbiosHandle;
+  EFI_MISC_BIOS_VENDOR *ForType0InputData;
+
+  BiosPhysicalSizeHexValue = 0x0;
+  BiosPhysicalSizeExponent = 0x0;
+  ForType0InputData        = (EFI_MISC_BIOS_VENDOR *)RecordData;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Now update the BiosPhysicalSize
+  //
+  BiosPhysicalSizeHexValue = PcdGet32 (PcdFlashAreaSize);
+  Status= GetValueExponentBase2 (
+            &BiosPhysicalSizeHexValue,
+            &BiosPhysicalSizeExponent
+            );
+  if(Status == EFI_SUCCESS){
+    ForType0InputData->BiosPhysicalDeviceSize.Value = (UINT16)BiosPhysicalSizeHexValue;
+    ForType0InputData->BiosPhysicalDeviceSize.Exponent = (UINT16)BiosPhysicalSizeExponent;
+  }
+  //
+  // Update strings from PCD
+  //
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr (PcdSMBIOSBiosVendor), Vendor);
+  if (StrLen (Vendor) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_VENDOR);
+    HiiSetString (mHiiHandle, TokenToUpdate, Vendor, NULL);
+  }
+  TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VENDOR);
+  VendorPtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+  VendorStrLen = StrLen(VendorPtr);
+  if (VendorStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  UnicodeSPrint (Version, sizeof (Version), L"0x%08x", PcdGet32 (PcdFirmwareRevision));
+  if (StrLen (Version) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_VERSION);
+    HiiSetString (mHiiHandle, TokenToUpdate, Version, NULL);
+  }
+  TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VERSION);
+  VersionPtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+  VerStrLen = StrLen(VersionPtr);
+  if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr (PcdSMBIOSBiosReleaseDate), ReleaseDate);
+  if (StrLen (ReleaseDate) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE);
+    HiiSetString (mHiiHandle, TokenToUpdate, ReleaseDate, NULL);
+  }
+  TokenToGet = STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE);
+  ReleaseDatePtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+  DateStrLen = StrLen(ReleaseDatePtr);
+  if (DateStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE0) + VendorStrLen + 1 + VerStrLen + 1 + DateStrLen + 1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE0) + VendorStrLen + 1 + VerStrLen + 1 + DateStrLen + 1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_BIOS_INFORMATION;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE0);
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle = 0;
+  //
+  // Vendor will be the 1st optional string following the formatted structure.
+  //
+  SmbiosRecord->Vendor = 1;
+  //
+  // Version will be the 2nd optional string following the formatted structure.
+  //
+  SmbiosRecord->BiosVersion = 2;
+  SmbiosRecord->BiosSegment = PcdGet16 (PcdSMBIOSBiosStartAddress);
+  //
+  // ReleaseDate will be the 3rd optional string following the formatted structure.
+  //
+  SmbiosRecord->BiosReleaseDate = 3;
+  SmbiosRecord->BiosSize = (UINT8)(Base2ToByteWith64KUnit(&ForType0InputData->BiosPhysicalDeviceSize) - 1);
+  *(UINT64 *)&SmbiosRecord->BiosCharacteristics = PcdGet64 (PcdSMBIOSBiosChar);
+  //
+  // CharacterExtensionBytes also store in ForType0InputData->BiosCharacteristics1 later two bytes to save size.
+  //
+  SmbiosRecord->BIOSCharacteristicsExtensionBytes[0] = PcdGet8 (PcdSMBIOSBiosCharEx1);
+  SmbiosRecord->BIOSCharacteristicsExtensionBytes[1] = PcdGet8 (PcdSMBIOSBiosCharEx2);
+
+  SmbiosRecord->SystemBiosMajorRelease = ForType0InputData->BiosMajorRelease;
+  SmbiosRecord->SystemBiosMinorRelease = ForType0InputData->BiosMinorRelease;
+  SmbiosRecord->EmbeddedControllerFirmwareMajorRelease = ForType0InputData->BiosEmbeddedFirmwareMajorRelease;
+  SmbiosRecord->EmbeddedControllerFirmwareMinorRelease = ForType0InputData->BiosEmbeddedFirmwareMinorRelease;
+
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  UnicodeStrToAsciiStr(VendorPtr, OptionalStrStart);
+  UnicodeStrToAsciiStr(VersionPtr, OptionalStrStart + VendorStrLen + 1);
+  UnicodeStrToAsciiStr(ReleaseDatePtr, OptionalStrStart + VendorStrLen + 1 + VerStrLen + 1);
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+
+  FreePool(SmbiosRecord);
+  return Status;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootInformationData.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootInformationData.c
new file mode 100644
index 0000000000..2c2c038bc8
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootInformationData.c
@@ -0,0 +1,24 @@
+/** @file
+This driver parses the mMiscSubclassDataTable structure and reports
+any generated data to the DataHub.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+
+//
+// Static (possibly build generated) Bios Vendor data. SMBIOS TYPE 32
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_BOOT_INFORMATION_STATUS, MiscBootInfoStatus) = {
+  EfiBootInformationStatusNoError,  // BootInformationStatus
+  {0}                               // BootInformationData
+};
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootInformationFunction.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootInformationFunction.c
new file mode 100644
index 0000000000..841d592314
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootInformationFunction.c
@@ -0,0 +1,71 @@
+/** @file
+boot information boot time changes.
+SMBIOS type 32.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+
+#include "CommonHeader.h"
+#include "SmbiosMisc.h"
+
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscBootInformation (Type 32).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+
+MISC_SMBIOS_TABLE_FUNCTION(MiscBootInfoStatus)
+{
+  EFI_STATUS                         Status;
+  EFI_SMBIOS_HANDLE                  SmbiosHandle;
+  SMBIOS_TABLE_TYPE32                *SmbiosRecord;
+  EFI_MISC_BOOT_INFORMATION_STATUS*  ForType32InputData;
+
+  ForType32InputData = (EFI_MISC_BOOT_INFORMATION_STATUS *)RecordData;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE32) + 1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE32) + 1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE32);
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle = 0;
+  SmbiosRecord->BootStatus = (UINT8)ForType32InputData->BootInformationStatus;
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+  FreePool(SmbiosRecord);
+  return Status;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturer.uni b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturer.uni
new file mode 100644
index 0000000000..a1b930ee22
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturer.uni
@@ -0,0 +1,17 @@
+// /** @file
+// Miscellaneous chassis manufacturer information
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+// **/
+
+
+/=#
+
+#string STR_MISC_CHASSIS_MANUFACTURER  #language en-US  "Chassis Manufacturer"
+#string STR_MISC_CHASSIS_VERSION       #language en-US  "Chassis Version"
+#string STR_MISC_CHASSIS_SERIAL_NUMBER #language en-US  "Chassis Serial Number"
+#string STR_MISC_CHASSIS_ASSET_TAG     #language en-US  "Chassis Asset Tag"
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturerData.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturerData.c
new file mode 100644
index 0000000000..527086305c
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturerData.c
@@ -0,0 +1,36 @@
+/** @file
+This driver parses the mMiscSubclassDataTable structure and reports
+any generated data to the DataHub.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+
+//
+// Static (possibly build generated) Chassis Manufacturer data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_CHASSIS_MANUFACTURER, MiscChassisManufacturer) = {
+  STRING_TOKEN(STR_MISC_CHASSIS_MANUFACTURER),  // ChassisManufactrurer
+  STRING_TOKEN(STR_MISC_CHASSIS_VERSION),       // ChassisVersion
+  STRING_TOKEN(STR_MISC_CHASSIS_SERIAL_NUMBER), // ChassisSerialNumber
+  STRING_TOKEN(STR_MISC_CHASSIS_ASSET_TAG),     // ChassisAssetTag
+  {                                             // ChassisTypeStatus
+    EfiMiscChassisTypeDeskTop,                  // ChassisType
+    0,                                          // ChassisLockPresent
+    0                                           // Reserved
+  },
+  EfiChassisStateSafe,                          // ChassisBootupState
+  EfiChassisStateSafe,                          // ChassisPowerSupplyState
+  EfiChassisStateOther,                         // ChassisThermalState
+  EfiChassisSecurityStatusOther,                // ChassisSecurityState
+  0                                             // ChassisOemDefined
+};
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturerFunction.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturerFunction.c
new file mode 100644
index 0000000000..5d6c32ef32
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturerFunction.c
@@ -0,0 +1,168 @@
+/** @file
+Chassis manufacturer information boot time changes.
+SMBIOS type 3.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscChassisManufacturer (Type 3).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscChassisManufacturer)
+{
+  CHAR8                           *OptionalStrStart;
+  UINTN                           ManuStrLen;
+  UINTN                           VerStrLen;
+  UINTN                           AssertTagStrLen;
+  UINTN                           SerialNumStrLen;
+  EFI_STATUS                      Status;
+  CHAR16                          Manufacturer[SMBIOS_STRING_MAX_LENGTH];
+  CHAR16                          Version[SMBIOS_STRING_MAX_LENGTH];
+  CHAR16                          SerialNumber[SMBIOS_STRING_MAX_LENGTH];
+  CHAR16                          AssertTag[SMBIOS_STRING_MAX_LENGTH];
+  EFI_STRING                      ManufacturerPtr;
+  EFI_STRING                      VersionPtr;
+  EFI_STRING                      SerialNumberPtr;
+  EFI_STRING                      AssertTagPtr;
+  STRING_REF                      TokenToGet;
+  STRING_REF                      TokenToUpdate;
+  EFI_SMBIOS_HANDLE               SmbiosHandle;
+  SMBIOS_TABLE_TYPE3              *SmbiosRecord;
+  EFI_MISC_CHASSIS_MANUFACTURER   *ForType3InputData;
+
+  ForType3InputData = (EFI_MISC_CHASSIS_MANUFACTURER *)RecordData;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Update strings from PCD
+  //
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSChassisManufacturer), Manufacturer);
+  if (StrLen (Manufacturer) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_CHASSIS_MANUFACTURER);
+    HiiSetString (mHiiHandle, TokenToUpdate, Manufacturer, NULL);
+  }
+  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_MANUFACTURER);
+  ManufacturerPtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+  ManuStrLen = StrLen(ManufacturerPtr);
+  if (ManuStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSChassisVersion), Version);
+  if (StrLen (Version) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_CHASSIS_VERSION);
+    HiiSetString (mHiiHandle, TokenToUpdate, Version, NULL);
+  }
+  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_VERSION);
+  VersionPtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+  VerStrLen = StrLen(VersionPtr);
+  if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSChassisSerialNumber), SerialNumber);
+  if (StrLen (SerialNumber) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_CHASSIS_SERIAL_NUMBER);
+    HiiSetString (mHiiHandle, TokenToUpdate, SerialNumber, NULL);
+  }
+  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_SERIAL_NUMBER);
+  SerialNumberPtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+  SerialNumStrLen = StrLen(SerialNumberPtr);
+  if (SerialNumStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSChassisAssetTag), AssertTag);
+  if (StrLen (AssertTag) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_CHASSIS_ASSET_TAG);
+    HiiSetString (mHiiHandle, TokenToUpdate, AssertTag, NULL);
+  }
+  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_ASSET_TAG);
+  AssertTagPtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+  AssertTagStrLen = StrLen(AssertTagPtr);
+  if (AssertTagStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE3) + ManuStrLen + 1  + VerStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE3) + ManuStrLen + 1  + VerStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_ENCLOSURE;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE3);
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle = 0;
+  //
+  // Manu will be the 1st optional string following the formatted structure.
+  //
+  SmbiosRecord->Manufacturer = 1;
+  SmbiosRecord->Type = PcdGet8 (PcdSMBIOSChassisType);
+  //
+  // Version will be the 2nd optional string following the formatted structure.
+  //
+  SmbiosRecord->Version = 2;
+  //
+  // SerialNumber will be the 3rd optional string following the formatted structure.
+  //
+  SmbiosRecord->SerialNumber = 3;
+  //
+  // AssertTag will be the 4th optional string following the formatted structure.
+  //
+  SmbiosRecord->AssetTag = 4;
+  SmbiosRecord->BootupState = PcdGet8 (PcdSMBIOSChassisBootupState);
+  SmbiosRecord->PowerSupplyState = PcdGet8 (PcdSMBIOSChassisPowerSupplyState);
+  SmbiosRecord->ThermalState = (UINT8)ForType3InputData->ChassisThermalState;
+  SmbiosRecord->SecurityStatus = PcdGet8 (PcdSMBIOSChassisSecurityState);
+  *(UINT32 *)&SmbiosRecord->OemDefined = PcdGet32 (PcdSMBIOSChassisOemDefined);
+  SmbiosRecord->Height = PcdGet8 (PcdSMBIOSChassisHeight);
+  SmbiosRecord->NumberofPowerCords = PcdGet8 (PcdSMBIOSChassisNumberPowerCords);
+  SmbiosRecord->ContainedElementCount = PcdGet8 (PcdSMBIOSChassisElementCount);
+  SmbiosRecord->ContainedElementRecordLength = PcdGet8 (PcdSMBIOSChassisElementRecordLength);
+
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  UnicodeStrToAsciiStr(ManufacturerPtr, OptionalStrStart);
+  UnicodeStrToAsciiStr(VersionPtr, OptionalStrStart + ManuStrLen + 1);
+  UnicodeStrToAsciiStr(SerialNumberPtr, OptionalStrStart + ManuStrLen + 1 + VerStrLen + 1);
+  UnicodeStrToAsciiStr(AssertTagPtr, OptionalStrStart + ManuStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1);
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+
+  FreePool(SmbiosRecord);
+  return Status;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscDevicePath.h b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscDevicePath.h
new file mode 100644
index 0000000000..8641e58fca
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscDevicePath.h
@@ -0,0 +1,42 @@
+/** @file
+Misc class required EFI Device Path definitions (Ports, slots &
+onboard devices)
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#ifndef _MISC_DEVICE_PATH_H
+#define _MISC_DEVICE_PATH_H
+
+#pragma pack(1)
+
+//USB
+/* For reference:
+#define USB1_1_STR  "ACPI(PNP0A03,0)/PCI(1D,0)."
+#define USB1_2_STR  "ACPI(PNP0A03,0)/PCI(1D,1)."
+#define USB1_3_STR  "ACPI(PNP0A03,0)/PCI(1D,2)."
+#define USB2_1_STR  "ACPI(PNP0A03,0)/PCI(1D,7)."
+*/
+
+#define DP_ACPI { ACPI_DEVICE_PATH,\
+    ACPI_DP, (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)),\
+   (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8), EISA_PNP_ID(0x0A03), 0 }
+#define DP_PCI( device,function)  { HARDWARE_DEVICE_PATH,\
+    HW_PCI_DP, (UINT8) (sizeof (PCI_DEVICE_PATH)),\
+    (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8), function, device }
+#define DP_END  { END_DEVICE_PATH_TYPE, \
+    END_ENTIRE_DEVICE_PATH_SUBTYPE, {END_DEVICE_PATH_LENGTH, 0 }}
+
+#define DP_LPC(eisaid,function ){ ACPI_DEVICE_PATH, \
+ACPI_DP,(UINT8) (sizeof (ACPI_HID_DEVICE_PATH)),\
+(UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8),EISA_PNP_ID(eisaid), function }
+
+
+#pragma pack()
+
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumberOfInstallableLanguagesData.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumberOfInstallableLanguagesData.c
new file mode 100644
index 0000000000..c1c8f61447
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumberOfInstallableLanguagesData.c
@@ -0,0 +1,28 @@
+/** @file
+This driver parses the mSmbiosMiscDataTable structure and reports
+any generated data to SMBIOS.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES, NumberOfInstallableLanguages) = {
+  2,                                  // NumberOfInstallableLanguages
+  {                                   // LanguageFlags
+    0,                                // AbbreviatedLanguageFormat
+    0                                 // Reserved
+  },
+  1,                                  // CurrentLanguageNumber
+};
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumberOfInstallableLanguagesFunction.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumberOfInstallableLanguagesFunction.c
new file mode 100644
index 0000000000..977ee57b24
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumberOfInstallableLanguagesFunction.c
@@ -0,0 +1,240 @@
+/** @file
+This driver parses the mSmbiosMiscDataTable structure and reports
+any generated data.
+
+Copyright (c) 2013-2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+/*++
+  Check whether the language is supported for given HII handle
+
+  @param   HiiHandle     The HII package list handle.
+  @param   Offset        The offest of current lanague in the supported languages.
+  @param   CurrentLang   The language code.
+
+  @retval  TRUE          Supported.
+  @retval  FALSE         Not Supported.
+
+--*/
+BOOLEAN
+EFIAPI
+CurrentLanguageMatch (
+  IN  EFI_HII_HANDLE                   HiiHandle,
+  OUT UINT16                           *Offset,
+  OUT CHAR8                            *CurrentLang
+  )
+{
+  CHAR8     *DefaultLang;
+  CHAR8     *BestLanguage;
+  CHAR8     *Languages;
+  CHAR8     *MatchLang;
+  CHAR8     *EndMatchLang;
+  UINTN     CompareLength;
+  BOOLEAN   LangMatch;
+
+  Languages = HiiGetSupportedLanguages (HiiHandle);
+  if (Languages == NULL) {
+    return FALSE;
+  }
+
+  LangMatch = FALSE;
+  CurrentLang  = GetEfiGlobalVariable (L"PlatformLang");
+  DefaultLang  = (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang);
+  BestLanguage = GetBestLanguage (
+                   Languages,
+                   FALSE,
+                   (CurrentLang != NULL) ? CurrentLang : "",
+                   DefaultLang,
+                   NULL
+                   );
+  if (BestLanguage != NULL) {
+    //
+    // Find the best matching RFC 4646 language, compute the offset.
+    //
+    LangMatch = TRUE;
+    CompareLength = AsciiStrLen (BestLanguage);
+    for (MatchLang = Languages, (*Offset) = 0; *MatchLang != '\0'; (*Offset)++) {
+      //
+      // Seek to the end of current match language.
+      //
+      for (EndMatchLang = MatchLang; *EndMatchLang != '\0' && *EndMatchLang != ';'; EndMatchLang++);
+
+      if ((EndMatchLang == MatchLang + CompareLength) && AsciiStrnCmp(MatchLang, BestLanguage, CompareLength) == 0) {
+        //
+        // Find the current best Language in the supported languages
+        //
+        break;
+      }
+      //
+      // best language match be in the supported language.
+      //
+      ASSERT (*EndMatchLang == ';');
+      MatchLang = EndMatchLang + 1;
+    }
+    FreePool (BestLanguage);
+  }
+
+  FreePool (Languages);
+  if (CurrentLang != NULL) {
+    FreePool (CurrentLang);
+  }
+  return LangMatch;
+}
+
+
+/**
+  Get next language from language code list (with separator ';').
+
+  @param  LangCode       Input: point to first language in the list. On
+                         Otput: point to next language in the list, or
+                                NULL if no more language in the list.
+  @param  Lang           The first language in the list.
+
+**/
+VOID
+EFIAPI
+GetNextLanguage (
+  IN OUT CHAR8      **LangCode,
+  OUT CHAR8         *Lang
+  )
+{
+  UINTN  Index;
+  CHAR8  *StringPtr;
+
+  ASSERT (LangCode != NULL);
+  ASSERT (*LangCode != NULL);
+  ASSERT (Lang != NULL);
+
+  Index     = 0;
+  StringPtr = *LangCode;
+  while (StringPtr[Index] != 0 && StringPtr[Index] != ';') {
+    Index++;
+  }
+
+  CopyMem (Lang, StringPtr, Index);
+  Lang[Index] = 0;
+
+  if (StringPtr[Index] == ';') {
+    Index++;
+  }
+  *LangCode = StringPtr + Index;
+}
+
+/**
+  This function returns the number of supported languages on HiiHandle.
+
+  @param   HiiHandle    The HII package list handle.
+
+  @retval  The number of supported languages.
+
+**/
+UINT16
+EFIAPI
+GetSupportedLanguageNumber (
+  IN EFI_HII_HANDLE    HiiHandle
+  )
+{
+  CHAR8   *Lang;
+  CHAR8   *Languages;
+  CHAR8   *LanguageString;
+  UINT16  LangNumber;
+
+  Languages = HiiGetSupportedLanguages (HiiHandle);
+  if (Languages == NULL) {
+    return 0;
+  }
+
+  LangNumber = 0;
+  Lang = AllocatePool (AsciiStrSize (Languages));
+  if (Lang != NULL) {
+    LanguageString = Languages;
+    while (*LanguageString != 0) {
+      GetNextLanguage (&LanguageString, Lang);
+      LangNumber++;
+    }
+    FreePool (Lang);
+  }
+  FreePool (Languages);
+  return LangNumber;
+}
+
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscNumberOfInstallableLanguages (Type 13).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(NumberOfInstallableLanguages)
+{
+  UINTN                                     LangStrLen;
+  CHAR8                                     CurrentLang[SMBIOS_STRING_MAX_LENGTH + 1];
+  CHAR8                                     *OptionalStrStart;
+  UINT16                                    Offset;
+  EFI_STATUS                                Status;
+  EFI_SMBIOS_HANDLE                         SmbiosHandle;
+  SMBIOS_TABLE_TYPE13                       *SmbiosRecord;
+  EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES  *ForType13InputData;
+
+  ForType13InputData = (EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES *)RecordData;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ForType13InputData->NumberOfInstallableLanguages = GetSupportedLanguageNumber (mHiiHandle);
+
+  //
+  // Try to check if current langcode matches with the langcodes in installed languages
+  //
+  ZeroMem(CurrentLang, SMBIOS_STRING_MAX_LENGTH + 1);
+  CurrentLanguageMatch (mHiiHandle, &Offset, CurrentLang);
+  LangStrLen = AsciiStrLen(CurrentLang);
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE13) + LangStrLen + 1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE13) + LangStrLen + 1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_BIOS_LANGUAGE_INFORMATION;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE13);
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle = 0;
+
+  SmbiosRecord->InstallableLanguages = (UINT8)ForType13InputData->NumberOfInstallableLanguages;
+  SmbiosRecord->Flags = (UINT8)ForType13InputData->LanguageFlags.AbbreviatedLanguageFormat;
+  SmbiosRecord->CurrentLanguages = 1;
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  AsciiStrCpy(OptionalStrStart, CurrentLang);
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+  FreePool(SmbiosRecord);
+  return Status;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemString.uni b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemString.uni
new file mode 100644
index 0000000000..d039948561
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemString.uni
@@ -0,0 +1,12 @@
+// /** @file
+// Unicode string used for SMBIOS type 11 record (OEM string)
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+/=#
+
+#string STR_MISC_OEM_EN_US  #language en-US  "Intel SSG"
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemStringData.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemStringData.c
new file mode 100644
index 0000000000..469a6321da
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemStringData.c
@@ -0,0 +1,20 @@
+/** @file
+This driver parses the mMiscSubclassDataTable structure and reports
+any generated data to smbios.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+//
+// Static (possibly build generated) OEM String data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_OEM_STRING, MiscOemString)
+= { {STRING_TOKEN(STR_MISC_OEM_EN_US) }};
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemStringFunction.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemStringFunction.c
new file mode 100644
index 0000000000..f3f61366fc
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemStringFunction.c
@@ -0,0 +1,78 @@
+/** @file
+boot information boot time changes.
+SMBIOS type 11.
+
+Copyright (c) 2013-2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "CommonHeader.h"
+#include "SmbiosMisc.h"
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscOemString (Type 11).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscOemString)
+{
+  UINTN                    OemStrLen;
+  CHAR8                    *OptionalStrStart;
+  EFI_STATUS               Status;
+  EFI_STRING               OemStr;
+  STRING_REF               TokenToGet;
+  EFI_SMBIOS_HANDLE        SmbiosHandle;
+  SMBIOS_TABLE_TYPE11      *SmbiosRecord;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_OEM_EN_US);
+  OemStr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+  OemStrLen = StrLen(OemStr);
+  if (OemStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE11) + OemStrLen + 1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE11) + OemStrLen + 1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_OEM_STRINGS;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE11);
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle = 0;
+  SmbiosRecord->StringCount = 1;
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  UnicodeStrToAsciiStr(OemStr, OptionalStrStart);
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+  FreePool(SmbiosRecord);
+  return Status;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDevice.uni b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDevice.uni
new file mode 100644
index 0000000000..c88dd9f57a
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDevice.uni
@@ -0,0 +1,18 @@
+// /** @file
+// Miscellaneous Onboard Device
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+//   MiscOnboardDevice.Vfr
+//
+// **/
+
+
+/=#
+
+#string STR_MISC_ONBOARD_DEVICE_VIDEO   #language en-US  "Intel(R) Extreme Graphics 3 Controller"
+#string STR_MISC_ONBOARD_DEVICE_NETWORK #language en-US  "Gigabit Ethernet"
+#string STR_MISC_ONBOARD_DEVICE_AUDIO   #language en-US  "Intel(R) High Definition Audio Device"
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDeviceData.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDeviceData.c
new file mode 100644
index 0000000000..a729ad7c9a
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDeviceData.c
@@ -0,0 +1,49 @@
+/** @file
+This driver parses the mMiscSubclassDataTable structure and reports
+any generated data to smbios.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_ONBOARD_DEVICE, MiscOnboardDeviceVideo) = {
+  STRING_TOKEN(STR_MISC_ONBOARD_DEVICE_VIDEO),    // OnBoardDeviceDescription
+  {                                               // OnBoardDeviceStatus
+    EfiOnBoardDeviceTypeVideo,                    // DeviceType
+    1,                                            // DeviceEnabled
+    0                                             // Reserved
+  },
+  {0}                                               // OnBoardDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_ONBOARD_DEVICE, MiscOnboardDeviceNetwork) = {
+  STRING_TOKEN(STR_MISC_ONBOARD_DEVICE_NETWORK),  // OnBoardDeviceDescription
+  {                                               // OnBoardDeviceStatus
+    EfiOnBoardDeviceTypeEthernet,                 // DeviceType
+    1,                                            // DeviceEnabled
+    0                                             // Reserved
+  },
+  {0}                                               // OnBoardDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_ONBOARD_DEVICE, MiscOnboardDeviceAudio) = {
+  STRING_TOKEN(STR_MISC_ONBOARD_DEVICE_AUDIO),    // OnBoardDeviceDescription
+  {                                               // OnBoardDeviceStatus
+    EfiOnBoardDeviceTypeSound,                    // DeviceType
+    1,                                            // DeviceEnabled
+    0                                             // Reserved
+  },
+  DP_END                                          // OnBoardDevicePath
+};
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDeviceFunction.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDeviceFunction.c
new file mode 100644
index 0000000000..f570184a56
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDeviceFunction.c
@@ -0,0 +1,105 @@
+/** @file
+Onboard device information boot time changes.
+SMBIOS type 10.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscOnboardDevice (Type 10).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscOnboardDevice)
+{
+  CHAR8                         *OptionalStrStart;
+  UINT8                         StatusAndType;
+  UINTN                         DescriptionStrLen;
+  EFI_STRING                    DeviceDescription;
+  STRING_REF                    TokenToGet;
+  EFI_STATUS                    Status;
+  EFI_SMBIOS_HANDLE             SmbiosHandle;
+  SMBIOS_TABLE_TYPE10           *SmbiosRecord;
+  EFI_MISC_ONBOARD_DEVICE       *ForType10InputData;
+
+  ForType10InputData = (EFI_MISC_ONBOARD_DEVICE *)RecordData;
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  TokenToGet = 0;
+  switch (ForType10InputData->OnBoardDeviceDescription) {
+    case STR_MISC_ONBOARD_DEVICE_VIDEO:
+      TokenToGet = STRING_TOKEN (STR_MISC_ONBOARD_DEVICE_VIDEO);
+      break;
+    case STR_MISC_ONBOARD_DEVICE_AUDIO:
+      TokenToGet = STRING_TOKEN (STR_MISC_ONBOARD_DEVICE_AUDIO);
+      break;
+  }
+
+  DeviceDescription = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+  DescriptionStrLen = StrLen(DeviceDescription);
+  if (DescriptionStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE10) + DescriptionStrLen + 1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE10) + DescriptionStrLen + 1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_ONBOARD_DEVICE_INFORMATION;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE10);
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle = 0;
+
+  //
+  // Status & Type: Bit 7 Devicen Status, Bits 6:0 Type of Device
+  //
+  StatusAndType = (UINT8) ForType10InputData->OnBoardDeviceStatus.DeviceType;
+  if (ForType10InputData->OnBoardDeviceStatus.DeviceEnabled != 0) {
+    StatusAndType |= 0x80;
+  } else {
+    StatusAndType &= 0x7F;
+  }
+
+  SmbiosRecord->Device[0].DeviceType = StatusAndType;
+  SmbiosRecord->Device[0].DescriptionString = 1;
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  UnicodeStrToAsciiStr(DeviceDescription, OptionalStrStart);
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+  FreePool(SmbiosRecord);
+  return Status;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignator.uni b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignator.uni
new file mode 100644
index 0000000000..165dcf2157
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignator.uni
@@ -0,0 +1,53 @@
+// /** @file
+// Miscellaneous Port Internal Connector Information
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+// **/
+/=#
+
+#string STR_MISC_PORT1_INTERNAL_DESIGN       #language en-US     "P1ICD"
+#string STR_MISC_PORT1_EXTERNAL_DESIGN       #language en-US     "P1ECD"
+#string STR_MISC_PORT2_INTERNAL_DESIGN       #language en-US     "P2ICD"
+#string STR_MISC_PORT2_EXTERNAL_DESIGN       #language en-US     "P2ECD"
+#string STR_MISC_PORT3_INTERNAL_DESIGN       #language en-US     "P3ICD"
+#string STR_MISC_PORT3_EXTERNAL_DESIGN       #language en-US     "P3ECD"
+#string STR_MISC_PORT4_INTERNAL_DESIGN       #language en-US     "P4ICD"
+#string STR_MISC_PORT4_EXTERNAL_DESIGN       #language en-US     "P4ECD"
+#string STR_MISC_PORT5_INTERNAL_DESIGN       #language en-US     "P5ICD"
+#string STR_MISC_PORT5_EXTERNAL_DESIGN       #language en-US     "P5ECD"
+#string STR_MISC_PORT6_INTERNAL_DESIGN       #language en-US     "P6ICD"
+#string STR_MISC_PORT6_EXTERNAL_DESIGN       #language en-US     "P6ECD"
+#string STR_MISC_PORT7_INTERNAL_DESIGN       #language en-US     "P7ICD"
+#string STR_MISC_PORT7_EXTERNAL_DESIGN       #language en-US     "P7ECD"
+#string STR_MISC_PORT8_INTERNAL_DESIGN       #language en-US     "P8ICD"
+#string STR_MISC_PORT8_EXTERNAL_DESIGN       #language en-US     "P8ECD"
+#string STR_MISC_PORT9_INTERNAL_DESIGN       #language en-US     "P9ICD"
+#string STR_MISC_PORT9_EXTERNAL_DESIGN       #language en-US     "P9ECD"
+#string STR_MISC_PORT10_INTERNAL_DESIGN      #language en-US     "P10ICD"
+#string STR_MISC_PORT10_EXTERNAL_DESIGN      #language en-US     "P10ECD"
+#string STR_MISC_PORT11_INTERNAL_DESIGN      #language en-US     "P11ICD"
+#string STR_MISC_PORT11_EXTERNAL_DESIGN      #language en-US     "P11ECD"
+#string STR_MISC_PORT12_INTERNAL_DESIGN      #language en-US     "P12ICD"
+#string STR_MISC_PORT12_EXTERNAL_DESIGN      #language en-US     "P12ECD"
+#string STR_MISC_PORT13_INTERNAL_DESIGN      #language en-US     "P13ICD"
+#string STR_MISC_PORT13_EXTERNAL_DESIGN      #language en-US     "P13ECD"
+#string STR_MISC_PORT14_INTERNAL_DESIGN      #language en-US     "P14ICD"
+#string STR_MISC_PORT14_EXTERNAL_DESIGN      #language en-US     "P14ECD"
+#string STR_MISC_PORT15_INTERNAL_DESIGN      #language en-US     "P15ICD"
+#string STR_MISC_PORT15_EXTERNAL_DESIGN      #language en-US     "P15ECD"
+#string STR_MISC_PORT16_INTERNAL_DESIGN      #language en-US     "P16ICD"
+#string STR_MISC_PORT16_EXTERNAL_DESIGN      #language en-US     "P16ECD"
+#string STR_MISC_PORT17_INTERNAL_DESIGN      #language en-US     "P17ICD"
+#string STR_MISC_PORT17_EXTERNAL_DESIGN      #language en-US     "P17ECD"
+#string STR_MISC_PORT18_INTERNAL_DESIGN      #language en-US     "P18ICD"
+#string STR_MISC_PORT18_EXTERNAL_DESIGN      #language en-US     "P18ECD"
+#string STR_MISC_PORT19_INTERNAL_DESIGN      #language en-US     "P19ICD"
+#string STR_MISC_PORT19_EXTERNAL_DESIGN      #language en-US     "P19ECD"
+#string STR_MISC_PORT20_INTERNAL_DESIGN      #language en-US     "P20ICD"
+#string STR_MISC_PORT20_EXTERNAL_DESIGN      #language en-US     "P20ECD"
+#string STR_MISC_PORT21_INTERNAL_DESIGN      #language en-US     "P21ICD"
+#string STR_MISC_PORT21_EXTERNAL_DESIGN      #language en-US     "P21ECD"
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignatorData.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignatorData.c
new file mode 100644
index 0000000000..c572288b0a
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignatorData.c
@@ -0,0 +1,184 @@
+/** @file
+This driver parses the mSmbiosMiscDataTable structure and reports
+any generated data to the DataHub.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector1) = {
+  STRING_TOKEN (STR_MISC_PORT1_INTERNAL_DESIGN),    // PortInternalConnectorDesignator
+  STRING_TOKEN (STR_MISC_PORT1_EXTERNAL_DESIGN),    // PortExternalConnectorDesignator
+  EfiPortConnectorTypeNone,                         // PortInternalConnectorType
+  EfiPortConnectorTypePS2,                          // PortExternalConnectorType
+  EfiPortTypeKeyboard,                              // PortType
+  //mPs2KbyboardDevicePath                          // PortPath
+  {{{{0}}}}
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector2) = {
+  STRING_TOKEN (STR_MISC_PORT2_INTERNAL_DESIGN),    // PortInternalConnectorDesignator
+  STRING_TOKEN (STR_MISC_PORT2_EXTERNAL_DESIGN),    // PortExternalConnectorDesignator
+  EfiPortConnectorTypeNone,                         // PortInternalConnectorType
+  EfiPortConnectorTypePS2,                          // PortExternalConnectorType
+  EfiPortTypeMouse,                                 // PortType
+  //mPs2MouseDevicePath                             // PortPath
+  {{{{0}}}}
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector3) = {
+  STRING_TOKEN (STR_MISC_PORT3_INTERNAL_DESIGN),
+  STRING_TOKEN (STR_MISC_PORT3_EXTERNAL_DESIGN),
+  EfiPortConnectorTypeOther,
+  EfiPortConnectorTypeNone,
+  EfiPortTypeSerial16550ACompatible,
+  //mCom1DevicePath
+  {{{{0}}}}
+};
+
+
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector4) = {
+  STRING_TOKEN (STR_MISC_PORT4_INTERNAL_DESIGN),
+  STRING_TOKEN (STR_MISC_PORT4_EXTERNAL_DESIGN),
+  EfiPortConnectorTypeNone,
+  EfiPortConnectorTypeRJ45,
+  EfiPortTypeSerial16550ACompatible,
+  //mCom2DevicePath
+  {{{{0}}}}
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector5) = {
+  STRING_TOKEN (STR_MISC_PORT5_INTERNAL_DESIGN),
+  STRING_TOKEN (STR_MISC_PORT5_EXTERNAL_DESIGN),
+  EfiPortConnectorTypeOther,
+  EfiPortConnectorTypeNone,
+  EfiPortTypeSerial16550ACompatible,
+  //mCom3DevicePath
+  {{{{0}}}}
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector6) = {
+  STRING_TOKEN (STR_MISC_PORT6_INTERNAL_DESIGN),
+  STRING_TOKEN (STR_MISC_PORT6_EXTERNAL_DESIGN),
+  EfiPortConnectorTypeNone,
+  EfiPortConnectorTypeRJ45,
+  EfiPortTypeSerial16550ACompatible,
+  //mCom3DevicePath
+  {{{{0}}}}
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector7) = {
+  STRING_TOKEN (STR_MISC_PORT7_INTERNAL_DESIGN),
+  STRING_TOKEN (STR_MISC_PORT7_EXTERNAL_DESIGN),
+  EfiPortConnectorTypeNone,
+  EfiPortConnectorTypeDB25Male,
+  EfiPortTypeParallelPortEcpEpp,
+  //mLpt1DevicePath
+  {{{{0}}}}
+};
+
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector8) = {
+  STRING_TOKEN (STR_MISC_PORT8_INTERNAL_DESIGN),
+  STRING_TOKEN (STR_MISC_PORT8_EXTERNAL_DESIGN),
+  EfiPortConnectorTypeNone,
+  EfiPortConnectorTypeUsb,
+  EfiPortTypeUsb,
+  //mUsb0DevicePath
+  {{{{0}}}}
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector9) = {
+  STRING_TOKEN (STR_MISC_PORT9_INTERNAL_DESIGN),
+  STRING_TOKEN (STR_MISC_PORT9_EXTERNAL_DESIGN),
+  EfiPortConnectorTypeNone,
+  EfiPortConnectorTypeUsb,
+  EfiPortTypeUsb,
+  //mUsb1DevicePath
+  {{{{0}}}}
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector10) = {
+  STRING_TOKEN (STR_MISC_PORT10_INTERNAL_DESIGN),
+  STRING_TOKEN (STR_MISC_PORT10_EXTERNAL_DESIGN),
+  EfiPortConnectorTypeNone,
+  EfiPortConnectorTypeUsb,
+  EfiPortTypeUsb,
+  //mUsb2DevicePath
+  {{{{0}}}}
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector11) = {
+  STRING_TOKEN (STR_MISC_PORT11_INTERNAL_DESIGN),
+  STRING_TOKEN (STR_MISC_PORT11_EXTERNAL_DESIGN),
+  EfiPortConnectorTypeNone,
+  EfiPortConnectorTypeUsb,
+  EfiPortTypeUsb,
+  //mUsb3DevicePath
+  {{{{0}}}}
+};
+
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector12) = {
+  STRING_TOKEN (STR_MISC_PORT12_INTERNAL_DESIGN),
+  STRING_TOKEN (STR_MISC_PORT12_EXTERNAL_DESIGN),
+  EfiPortConnectorTypeNone,
+  EfiPortConnectorTypeRJ45,
+  EfiPortTypeNetworkPort,
+  //mGbNicDevicePath
+  {{{{0}}}}
+};
+
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector13) = {
+  STRING_TOKEN (STR_MISC_PORT13_INTERNAL_DESIGN),
+  STRING_TOKEN (STR_MISC_PORT13_EXTERNAL_DESIGN),
+  EfiPortConnectorTypeOnboardFloppy,
+  EfiPortConnectorTypeNone,
+  EfiPortTypeOther,
+  //mFloopyADevicePath
+  {{{{0}}}}
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector14) = {
+  STRING_TOKEN (STR_MISC_PORT14_INTERNAL_DESIGN),
+  STRING_TOKEN (STR_MISC_PORT14_EXTERNAL_DESIGN),
+  EfiPortConnectorTypeOnboardIde,
+  EfiPortConnectorTypeNone,
+  EfiPortTypeOther,
+  //mIdeDevicePath
+  {{{{0}}}}
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector15) = {
+  STRING_TOKEN (STR_MISC_PORT15_INTERNAL_DESIGN),
+  STRING_TOKEN (STR_MISC_PORT15_EXTERNAL_DESIGN),
+  EfiPortConnectorTypeOnboardIde,
+  EfiPortConnectorTypeNone,
+  EfiPortTypeOther,
+  //mSataDevicePath
+  {{{{0}}}}
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector16) = {
+  STRING_TOKEN (STR_MISC_PORT16_INTERNAL_DESIGN),
+  STRING_TOKEN (STR_MISC_PORT16_EXTERNAL_DESIGN),
+  EfiPortConnectorTypeOnboardIde,
+  EfiPortConnectorTypeNone,
+  EfiPortTypeOther,
+  //mSataDevicePath
+  {{{{0}}}}
+};
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignatorFunction.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignatorFunction.c
new file mode 100644
index 0000000000..28c05efb21
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignatorFunction.c
@@ -0,0 +1,292 @@
+/** @file
+Port internal connector designator information boot time changes.
+SMBIOS type 8.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+//STATIC PS2_CONN_DEVICE_PATH       mPs2KeyboardDevicePath   = { DP_ACPI, DP_PCI( 0x1F,0x00 ),DP_LPC( 0x0303,0 ), DP_END };
+//STATIC PS2_CONN_DEVICE_PATH       mPs2MouseDevicePath      = { DP_ACPI, DP_PCI( 0x1F,0x00 ),DP_LPC( 0x0303,1 ), DP_END };
+//STATIC SERIAL_CONN_DEVICE_PATH    mCom1DevicePath          = { DP_ACPI, DP_PCI( 0x1F,0x00 ),DP_LPC( 0x0501,0 ), DP_END };
+//STATIC SERIAL_CONN_DEVICE_PATH    mCom2DevicePath          = { DP_ACPI, DP_PCI( 0x1F,0x00 ),DP_LPC( 0x0501,1 ), DP_END };
+//STATIC PARALLEL_CONN_DEVICE_PATH  mLpt1DevicePath          = { DP_ACPI, DP_PCI( 0x1F,0x00 ),DP_LPC( 0x0401,0 ), DP_END };
+//STATIC FLOOPY_CONN_DEVICE_PATH    mFloopyADevicePath       = { DP_ACPI, DP_PCI( 0x1F,0x00 ),DP_LPC( 0x0604,0 ), DP_END };
+//STATIC FLOOPY_CONN_DEVICE_PATH    mFloopyBDevicePath       = { DP_ACPI, DP_PCI( 0x1F,0x00 ),DP_LPC( 0x0604,1 ), DP_END };
+//STATIC USB_PORT_DEVICE_PATH       mUsb0DevicePath          = { DP_ACPI, DP_PCI( 0x1d,0x00 ), DP_END };
+//STATIC USB_PORT_DEVICE_PATH       mUsb1DevicePath          = { DP_ACPI, DP_PCI( 0x1d,0x01 ), DP_END };
+//STATIC USB_PORT_DEVICE_PATH       mUsb2DevicePath          = { DP_ACPI, DP_PCI( 0x1d,0x02 ), DP_END };
+//STATIC USB_PORT_DEVICE_PATH       mUsb3DevicePath          = { DP_ACPI, DP_PCI( 0x1d,0x03 ), DP_END };
+//STATIC IDE_DEVICE_PATH            mIdeDevicePath           = { DP_ACPI, DP_PCI( 0x1F,0x01 ), DP_END };
+//STATIC IDE_DEVICE_PATH            mSata1DevicePath         = { DP_ACPI, DP_PCI( 0x1F,0x02 ), DP_END };
+//STATIC GB_NIC_DEVICE_PATH         mGbNicDevicePath         = { DP_ACPI, DP_PCI( 0x03,0x00 ),DP_PCI( 0x1F,0x00 ),DP_PCI( 0x07,0x00 ), DP_END };
+EFI_DEVICE_PATH_PROTOCOL          mEndDevicePath           = DP_END;
+
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector1);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector2);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector3);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector4);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector5);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector6);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector7);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector8);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector9);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector10);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector11);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector12);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector13);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector14);
+
+
+EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR  *mMiscConnectorArray[SMBIOS_PORT_CONNECTOR_MAX_NUM] =
+{
+  MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector1),
+  MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector2),
+  MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector3),
+  MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector4),
+  MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector5),
+  MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector6),
+  MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector7),
+  MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector8),
+  MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector9),
+  MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector10),
+  MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector11),
+  MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector12),
+  MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector13),
+  MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector14),
+};
+
+BOOLEAN  PcdMiscPortIsInit = FALSE;
+SMBIOS_PORT_CONNECTOR_DESIGNATOR_COFNIG SMBIOSPortConnector = {0};
+
+
+/**
+  Get Misc Port Configuration information from PCD
+  @param  SMBIOSPortConnector                 Pointer to SMBIOSPortConnector table.
+
+**/
+
+VOID
+GetMiscPortConfigFromPcd ()
+{
+  //
+  // Type 8
+  //
+  SMBIOSPortConnector.SMBIOSConnectorNumber = PcdGet8 (PcdSMBIOSConnectorNumber);
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort1InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[0].PortInternalConnectorDesignator);
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort1ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[0].PortExternalConnectorDesignator);
+  SMBIOSPortConnector.SMBIOSPortConnector[0].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort1InternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[0].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort1ExternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[0].PortType = PcdGet8 (PcdSMBIOSPort1Type);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort2InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[1].PortInternalConnectorDesignator);
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort2ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[1].PortExternalConnectorDesignator);
+  SMBIOSPortConnector.SMBIOSPortConnector[1].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort2InternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[1].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort2ExternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[1].PortType = PcdGet8 (PcdSMBIOSPort2Type);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort3InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[2].PortInternalConnectorDesignator);
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort3ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[2].PortExternalConnectorDesignator);
+  SMBIOSPortConnector.SMBIOSPortConnector[2].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort3InternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[2].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort3ExternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[2].PortType = PcdGet8 (PcdSMBIOSPort3Type);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort4InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[3].PortInternalConnectorDesignator);
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort4ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[3].PortExternalConnectorDesignator);
+  SMBIOSPortConnector.SMBIOSPortConnector[3].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort4InternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[3].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort4ExternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[3].PortType = PcdGet8 (PcdSMBIOSPort4Type);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort5InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[4].PortInternalConnectorDesignator);
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort5ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[4].PortExternalConnectorDesignator);
+  SMBIOSPortConnector.SMBIOSPortConnector[4].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort5InternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[4].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort5ExternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[4].PortType = PcdGet8 (PcdSMBIOSPort5Type);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort6InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[5].PortInternalConnectorDesignator);
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort6ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[5].PortExternalConnectorDesignator);
+  SMBIOSPortConnector.SMBIOSPortConnector[5].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort6InternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[5].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort6ExternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[5].PortType = PcdGet8 (PcdSMBIOSPort6Type);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort7InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[6].PortInternalConnectorDesignator);
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort7ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[6].PortExternalConnectorDesignator);
+  SMBIOSPortConnector.SMBIOSPortConnector[6].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort7InternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[6].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort7ExternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[6].PortType = PcdGet8 (PcdSMBIOSPort7Type);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort8InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[7].PortInternalConnectorDesignator);
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort8ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[7].PortExternalConnectorDesignator);
+  SMBIOSPortConnector.SMBIOSPortConnector[7].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort8InternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[7].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort8ExternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[7].PortType = PcdGet8 (PcdSMBIOSPort8Type);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort9InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[8].PortInternalConnectorDesignator);
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort9ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[8].PortExternalConnectorDesignator);
+  SMBIOSPortConnector.SMBIOSPortConnector[8].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort9InternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[8].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort9ExternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[8].PortType = PcdGet8 (PcdSMBIOSPort9Type);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort10InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[9].PortInternalConnectorDesignator);
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort10ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[9].PortExternalConnectorDesignator);
+  SMBIOSPortConnector.SMBIOSPortConnector[9].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort10InternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[9].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort10ExternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[9].PortType = PcdGet8 (PcdSMBIOSPort10Type);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort11InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[10].PortInternalConnectorDesignator);
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort11ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[10].PortExternalConnectorDesignator);
+  SMBIOSPortConnector.SMBIOSPortConnector[10].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort11InternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[10].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort11ExternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[10].PortType = PcdGet8 (PcdSMBIOSPort11Type);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort12InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[11].PortInternalConnectorDesignator);
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort12ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[11].PortExternalConnectorDesignator);
+  SMBIOSPortConnector.SMBIOSPortConnector[11].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort12InternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[11].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort12ExternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[11].PortType = PcdGet8 (PcdSMBIOSPort12Type);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort13InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[12].PortInternalConnectorDesignator);
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort13ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[12].PortExternalConnectorDesignator);
+  SMBIOSPortConnector.SMBIOSPortConnector[12].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort13InternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[12].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort13ExternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[12].PortType = PcdGet8 (PcdSMBIOSPort13Type);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort14InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[13].PortInternalConnectorDesignator);
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort14ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[13].PortExternalConnectorDesignator);
+  SMBIOSPortConnector.SMBIOSPortConnector[13].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort14InternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[13].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort14ExternalConnectorType);
+  SMBIOSPortConnector.SMBIOSPortConnector[13].PortType = PcdGet8 (PcdSMBIOSPort14Type);
+}
+/**
+  This function makes boot time changes to the contents of the
+  MiscPortConnectorInformation (Type 8).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscPortInternalConnectorDesignator)
+{
+  CHAR8                                        *OptionalStrStart;
+  UINTN                                        InternalRefStrLen;
+  UINTN                                        ExternalRefStrLen;
+  EFI_STRING                                   InternalRef;
+  EFI_STRING                                   ExternalRef;
+  STRING_REF                                   TokenForInternal;
+  STRING_REF                                   TokenForExternal;
+  STRING_REF                                   TokenToUpdate;
+  UINT8                                        InternalType;
+  UINT8                                        ExternalType;
+  UINT8                                        PortType;
+  EFI_STATUS                                   Status;
+  SMBIOS_TABLE_TYPE8                           *SmbiosRecord;
+  EFI_SMBIOS_HANDLE                            SmbiosHandle;
+  EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR  *ForType8InputData;
+  UINT8                                        Index;
+
+  ForType8InputData = (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR *)RecordData;
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  TokenForInternal = 0;
+  TokenForExternal = 0;
+  InternalType     = 0;
+  ExternalType     = 0;
+  PortType         = 0;
+
+  if (!PcdMiscPortIsInit) {
+    GetMiscPortConfigFromPcd ();
+    PcdMiscPortIsInit = TRUE;
+  }
+
+  for (Index = 0; Index < SMBIOS_PORT_CONNECTOR_MAX_NUM; Index++) {
+    if (ForType8InputData->PortInternalConnectorDesignator == (mMiscConnectorArray[Index])->PortInternalConnectorDesignator) {
+      //DEBUG ((EFI_D_ERROR, "Found Port Connector Data %d : ", Index));
+      break;
+    }
+  }
+  if (Index >= SMBIOSPortConnector.SMBIOSConnectorNumber) {
+    return EFI_SUCCESS;
+  }
+
+  if (Index >= SMBIOS_PORT_CONNECTOR_MAX_NUM) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  InternalRef = SMBIOSPortConnector.SMBIOSPortConnector[Index].PortInternalConnectorDesignator;
+  if (StrLen (InternalRef) > 0) {
+    TokenToUpdate = STRING_TOKEN ((mMiscConnectorArray[Index])->PortInternalConnectorDesignator);
+    HiiSetString (mHiiHandle, TokenToUpdate, InternalRef, NULL);
+  }
+  ExternalRef = SMBIOSPortConnector.SMBIOSPortConnector[Index].PortExternalConnectorDesignator;
+  if (StrLen (ExternalRef) > 0) {
+    TokenToUpdate = STRING_TOKEN ((mMiscConnectorArray[Index])->PortExternalConnectorDesignator);
+    HiiSetString (mHiiHandle, TokenToUpdate, ExternalRef, NULL);
+  }
+  TokenForInternal = STRING_TOKEN ((mMiscConnectorArray[Index])->PortInternalConnectorDesignator);
+  TokenForExternal = STRING_TOKEN ((mMiscConnectorArray[Index])->PortExternalConnectorDesignator);
+  InternalType = SMBIOSPortConnector.SMBIOSPortConnector[Index].PortInternalConnectorType;
+  ExternalType = SMBIOSPortConnector.SMBIOSPortConnector[Index].PortExternalConnectorType;
+  PortType = SMBIOSPortConnector.SMBIOSPortConnector[Index].PortType;
+
+  InternalRef = HiiGetPackageString(&gEfiCallerIdGuid, TokenForInternal, NULL);
+  InternalRefStrLen = StrLen(InternalRef);
+  if (InternalRefStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  ExternalRef = HiiGetPackageString(&gEfiCallerIdGuid, TokenForExternal, NULL);
+  ExternalRefStrLen = StrLen(ExternalRef);
+  if (ExternalRefStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE8) + InternalRefStrLen + 1 + ExternalRefStrLen + 1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE8) + InternalRefStrLen + 1 + ExternalRefStrLen + 1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE8);
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle = 0;
+  SmbiosRecord->InternalReferenceDesignator = 1;
+  SmbiosRecord->InternalConnectorType = InternalType;
+  SmbiosRecord->ExternalReferenceDesignator = 2;
+  SmbiosRecord->ExternalConnectorType = ExternalType;
+  SmbiosRecord->PortType = PortType;
+
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  UnicodeStrToAsciiStr(InternalRef, OptionalStrStart);
+  UnicodeStrToAsciiStr(ExternalRef, OptionalStrStart + InternalRefStrLen + 1);
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+  FreePool(SmbiosRecord);
+  return Status;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturer.uni b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturer.uni
new file mode 100644
index 0000000000..bb49db5573
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturer.uni
@@ -0,0 +1,20 @@
+// /** @file
+// System Manufacturer Information
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+// **/
+
+
+/=#
+
+
+#string STR_MISC_SYSTEM_MANUFACTURER   #language en-US  "Intel Corp."
+#string STR_MISC_SYSTEM_PRODUCT_NAME   #language en-US  "QUARK"
+#string STR_MISC_SYSTEM_VERSION        #language en-US  "1.0"
+#string STR_MISC_SYSTEM_SERIAL_NUMBER  #language en-US  "Unknown"
+#string STR_MISC_SYSTEM_SKU_NUMBER     #language en-US  "System SKUNumber"
+#string STR_MISC_SYSTEM_FAMILY         #language en-US  "X1000"
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturerData.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturerData.c
new file mode 100644
index 0000000000..5a8b84b0ed
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturerData.c
@@ -0,0 +1,32 @@
+/** @file
+This driver parses the mMiscSubclassDataTable structure and reports
+any generated data using smbios protocol.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+
+//
+// Static (possibly build generated) System Manufacturer data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_MANUFACTURER, MiscSystemManufacturer) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_MANUFACTURER),   // SystemManufactrurer
+  STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME),   // SystemProductName
+  STRING_TOKEN(STR_MISC_SYSTEM_VERSION),        // SystemVersion
+  STRING_TOKEN(STR_MISC_SYSTEM_SERIAL_NUMBER),  // SystemSerialNumber
+  {                                             // SystemUuid
+    0x13ffef23, 0x8654, 0x46da, {0xa4, 0x7, 0x39, 0xc9, 0x12, 0x2, 0xd3, 0x56}
+  },
+  EfiSystemWakeupTypePowerSwitch,               // SystemWakeupType
+  STRING_TOKEN(STR_MISC_SYSTEM_SKU_NUMBER),     // SystemSKUNumber
+  STRING_TOKEN(STR_MISC_SYSTEM_FAMILY),         // SystemFamily
+};
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturerFunction.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturerFunction.c
new file mode 100644
index 0000000000..d7658f3d7c
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturerFunction.c
@@ -0,0 +1,198 @@
+/** @file
+This driver parses the mMiscSubclassDataTable structure and reports
+any generated data to smbios.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscSystemManufacturer (Type 1).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscSystemManufacturer)
+{
+  CHAR8                             *OptionalStrStart;
+  UINTN                             ManuStrLen;
+  UINTN                             VerStrLen;
+  UINTN                             PdNameStrLen;
+  UINTN                             SerialNumStrLen;
+  UINTN                             SKUNumStrLen;
+  UINTN                             FamilyStrLen;
+  EFI_STATUS                        Status;
+  CHAR16                            Manufacturer[SMBIOS_STRING_MAX_LENGTH];
+  CHAR16                            ProductName[SMBIOS_STRING_MAX_LENGTH];
+  CHAR16                            Version[SMBIOS_STRING_MAX_LENGTH];
+  CHAR16                            SerialNumber[SMBIOS_STRING_MAX_LENGTH];
+  CHAR16                            SKUNumber[SMBIOS_STRING_MAX_LENGTH];
+  CHAR16                            Family[SMBIOS_STRING_MAX_LENGTH];
+  EFI_STRING                        ManufacturerPtr;
+  EFI_STRING                        ProductNamePtr;
+  EFI_STRING                        VersionPtr;
+  EFI_STRING                        SerialNumberPtr;
+  EFI_STRING                        SKUNumberPtr;
+  EFI_STRING                        FamilyPtr;
+  STRING_REF                        TokenToGet;
+  STRING_REF                        TokenToUpdate;
+  EFI_SMBIOS_HANDLE                 SmbiosHandle;
+  SMBIOS_TABLE_TYPE1                *SmbiosRecord;
+  EFI_MISC_SYSTEM_MANUFACTURER      *ForType1InputData;
+
+  ForType1InputData = (EFI_MISC_SYSTEM_MANUFACTURER *)RecordData;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Update strings from PCD
+  //
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemManufacturer), Manufacturer);
+  if (StrLen (Manufacturer) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_SYSTEM_MANUFACTURER);
+    HiiSetString (mHiiHandle, TokenToUpdate, Manufacturer, NULL);
+  }
+  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_MANUFACTURER);
+  ManufacturerPtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+  ManuStrLen = StrLen(ManufacturerPtr);
+  if (ManuStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemProductName), ProductName);
+  if (StrLen (ProductName) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_SYSTEM_PRODUCT_NAME);
+    HiiSetString (mHiiHandle, TokenToUpdate, ProductName, NULL);
+  }
+  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_PRODUCT_NAME);
+  ProductNamePtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+  PdNameStrLen = StrLen(ProductNamePtr);
+  if (PdNameStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemVersion), Version);
+  if (StrLen (Version) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_SYSTEM_VERSION);
+    HiiSetString (mHiiHandle, TokenToUpdate, Version, NULL);
+  }
+  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_VERSION);
+  VersionPtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+  VerStrLen = StrLen(VersionPtr);
+  if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSerialNumber), SerialNumber);
+  if (StrLen (SerialNumber) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_SYSTEM_SERIAL_NUMBER);
+    HiiSetString (mHiiHandle, TokenToUpdate, SerialNumber, NULL);
+  }
+  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SERIAL_NUMBER);
+  SerialNumberPtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+  SerialNumStrLen = StrLen(SerialNumberPtr);
+  if (SerialNumStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSKUNumber), SKUNumber);
+  if (StrLen (SKUNumber) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_SYSTEM_SKU_NUMBER);
+    HiiSetString (mHiiHandle, TokenToUpdate, SKUNumber, NULL);
+  }
+  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SKU_NUMBER);
+  SKUNumberPtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+  SKUNumStrLen = StrLen(SKUNumberPtr);
+  if (SKUNumStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemFamily), Family);
+  if (StrLen (Family) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_SYSTEM_FAMILY);
+    HiiSetString (mHiiHandle, TokenToUpdate, Family, NULL);
+  }
+  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_FAMILY);
+  FamilyPtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+  FamilyStrLen = StrLen(FamilyPtr);
+  if (FamilyStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE1) + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + SKUNumStrLen + 1 + FamilyStrLen + 1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE1) + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + SKUNumStrLen + 1 + FamilyStrLen + 1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_INFORMATION;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE1);
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle = 0;
+  //
+  // Manu will be the 1st optional string following the formatted structure.
+  //
+  SmbiosRecord->Manufacturer = 1;
+  //
+  // ProductName will be the 2nd optional string following the formatted structure.
+  //
+  SmbiosRecord->ProductName = 2;
+  //
+  // Version will be the 3rd optional string following the formatted structure.
+  //
+  SmbiosRecord->Version = 3;
+  //
+  // Serial number will be the 4th optional string following the formatted structure.
+  //
+  SmbiosRecord->SerialNumber = 4;
+  //
+  // SKU number will be the 5th optional string following the formatted structure.
+  //
+  SmbiosRecord->SKUNumber = 5;
+  //
+  // Family will be the 6th optional string following the formatted structure.
+  //
+  SmbiosRecord->Family = 6;
+  CopyMem ((UINT8 *) (&SmbiosRecord->Uuid), (UINT8 *)PcdGetPtr(PcdSMBIOSSystemUuid),16);
+  SmbiosRecord->WakeUpType = (UINT8)ForType1InputData->SystemWakeupType;
+
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  UnicodeStrToAsciiStr(ManufacturerPtr, OptionalStrStart);
+  UnicodeStrToAsciiStr(ProductNamePtr, OptionalStrStart + ManuStrLen + 1);
+  UnicodeStrToAsciiStr(VersionPtr, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1);
+  UnicodeStrToAsciiStr(SerialNumberPtr, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1);
+  UnicodeStrToAsciiStr(SKUNumberPtr, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen+ 1);
+  UnicodeStrToAsciiStr(FamilyPtr, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + SKUNumStrLen+ 1);
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+  FreePool(SmbiosRecord);
+  return Status;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionString.uni b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionString.uni
new file mode 100644
index 0000000000..aa5bb6fb65
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionString.uni
@@ -0,0 +1,14 @@
+// /** @file
+// Miscellaneous System Option Strings
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+// **/
+
+
+/=#
+
+#string STR_MISC_SYSTEM_OPTION_STRING  #language en-US  "J1D4:1-2,5-6,9-10Default;2-3CMOS clr,6-7Pswd clr,10-11Recovery"
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionStringData.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionStringData.c
new file mode 100644
index 0000000000..5e6682ec7c
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionStringData.c
@@ -0,0 +1,23 @@
+/** @file
+This driver parses the mSmbiosMiscDataTable structure and reports
+any generated data to smbios.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_OPTION_STRING, SystemOptionString) = {
+  {STRING_TOKEN (STR_MISC_SYSTEM_OPTION_STRING)}
+};
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionStringFunction.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionStringFunction.c
new file mode 100644
index 0000000000..a32765f836
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionStringFunction.c
@@ -0,0 +1,81 @@
+/** @file
+BIOS system option string boot time changes.
+SMBIOS type 12.
+
+Copyright (c) 2013-2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+
+#include "CommonHeader.h"
+#include "SmbiosMisc.h"
+
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscSystemOptionString (Type 12).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(SystemOptionString)
+{
+  CHAR8                             *OptionalStrStart;
+  UINTN                             OptStrLen;
+  EFI_STRING                        OptionString;
+  EFI_STATUS                        Status;
+  STRING_REF                        TokenToGet;
+  EFI_SMBIOS_HANDLE                 SmbiosHandle;
+  SMBIOS_TABLE_TYPE12               *SmbiosRecord;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_OPTION_STRING);
+  OptionString = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+  OptStrLen = StrLen(OptionString);
+  if (OptStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE12) + OptStrLen + 1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE12) + OptStrLen + 1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_CONFIGURATION_OPTIONS;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE12);
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle = 0;
+
+  SmbiosRecord->StringCount = 1;
+  OptionalStrStart = (CHAR8*) (SmbiosRecord + 1);
+  UnicodeStrToAsciiStr(OptionString, OptionalStrStart);
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+
+  FreePool(SmbiosRecord);
+  return Status;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignation.uni b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignation.uni
new file mode 100644
index 0000000000..e7639c9f36
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignation.uni
@@ -0,0 +1,27 @@
+// /** @file
+// Miscellaneous Port Connector Information
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+// **/
+
+
+/=#
+
+#string STR_MISC_SYSTEM_SLOT1      #language en-US  "SLOT1"
+#string STR_MISC_SYSTEM_SLOT2      #language en-US  "SLOT2"
+#string STR_MISC_SYSTEM_SLOT3      #language en-US  "SLOT3"
+#string STR_MISC_SYSTEM_SLOT4      #language en-US  "SLOT4"
+#string STR_MISC_SYSTEM_SLOT5      #language en-US  "SLOT5"
+#string STR_MISC_SYSTEM_SLOT6      #language en-US  "SLOT6"
+#string STR_MISC_SYSTEM_SLOT7      #language en-US  "SLOT7"
+#string STR_MISC_SYSTEM_SLOT8      #language en-US  "SLOT8"
+#string STR_MISC_SYSTEM_SLOT9      #language en-US  "SLOT9"
+#string STR_MISC_SYSTEM_SLOT10     #language en-US  "SLOT10"
+#string STR_MISC_SYSTEM_SLOT11     #language en-US  "SLOT11"
+#string STR_MISC_SYSTEM_SLOT12     #language en-US  "SLOT12"
+#string STR_MISC_SYSTEM_SLOT13     #language en-US  "SLOT13"
+#string STR_MISC_SYSTEM_SLOT14     #language en-US  "SLOT14"
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignationData.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignationData.c
new file mode 100644
index 0000000000..e60f1f8dfa
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignationData.c
@@ -0,0 +1,357 @@
+/** @file
+This driver parses the mMiscSubclassDataTable structure and reports
+any generated data to the DataHub.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot1) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT1),        // SlotDesignation
+  EfiSlotTypePci,                             // SlotType
+  EfiSlotDataBusWidth32Bit,                   // SlotDataBusWidth
+  EfiSlotUsageAvailable,                      // SlotUsage
+  EfiSlotLengthLong ,                         // SlotLength
+  1,                                          // SlotId
+  {                                           // SlotCharacteristics
+    0,                                        // CharacteristicsUnknown  :1;
+    0,                                        // Provides50Volts         :1;
+    1,                                        // Provides33Volts         :1;
+    0,                                        // SharedSlot              :1;
+    0,                                        // PcCard16Supported       :1;
+    0,                                        // CardBusSupported        :1;
+    0,                                        // ZoomVideoSupported      :1;
+    0,                                        // ModemRingResumeSupported:1;
+    1,                                        // PmeSignalSupported      :1;
+    0,                                        // HotPlugDevicesSupported :1;
+    1,                                        // SmbusSignalSupported    :1;
+    0                                         // Reserved                :21;
+  },
+  {0}                                           // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot2) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT2),        // SlotDesignation
+  EfiSlotTypePciExpress,                      // SlotType
+  EfiSlotDataBusWidth32Bit,                   // SlotDataBusWidth
+  EfiSlotUsageAvailable,                      // SlotUsage
+  EfiSlotLengthLong ,                         // SlotLength
+  1,                                          // SlotId
+  {                                           // SlotCharacteristics
+    0,                                        // CharacteristicsUnknown  :1;
+    0,                                        // Provides50Volts         :1;
+    1,                                        // Provides33Volts         :1;
+    0,                                        // SharedSlot              :1;
+    0,                                        // PcCard16Supported       :1;
+    0,                                        // CardBusSupported        :1;
+    0,                                        // ZoomVideoSupported      :1;
+    0,                                        // ModemRingResumeSupported:1;
+    1,                                        // PmeSignalSupported      :1;
+    1,                                        // HotPlugDevicesSupported :1;
+    1,                                        // SmbusSignalSupported    :1;
+    0                                         // Reserved                :21;
+  },
+  {0}                                           // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot3) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT3),        // SlotDesignation
+  EfiSlotTypePciExpress,                      // SlotType
+  EfiSlotDataBusWidth32Bit,                   // SlotDataBusWidth
+  EfiSlotUsageAvailable,                      // SlotUsage
+  EfiSlotLengthLong ,                         // SlotLength
+  2,                                          // SlotId
+  {                                           // SlotCharacteristics
+    0,                                        // CharacteristicsUnknown  :1;
+    0,                                        // Provides50Volts         :1;
+    1,                                        // Provides33Volts         :1;
+    0,                                        // SharedSlot              :1;
+    0,                                        // PcCard16Supported       :1;
+    0,                                        // CardBusSupported        :1;
+    0,                                        // ZoomVideoSupported      :1;
+    0,                                        // ModemRingResumeSupported:1;
+    1,                                        // PmeSignalSupported      :1;
+    1,                                        // HotPlugDevicesSupported :1;
+    1,                                        // SmbusSignalSupported    :1;
+    0                                         // Reserved                :21;
+  },
+  {0}                                           // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot4) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT4),        // SlotDesignation
+  EfiSlotTypePciExpress,                      // SlotType
+  EfiSlotDataBusWidth32Bit,                   // SlotDataBusWidth
+  EfiSlotUsageAvailable,                      // SlotUsage
+  EfiSlotLengthLong ,                         // SlotLength
+  2,                                          // SlotId
+  {                                           // SlotCharacteristics
+    0,                                        // CharacteristicsUnknown  :1;
+    0,                                        // Provides50Volts         :1;
+    1,                                        // Provides33Volts         :1;
+    0,                                        // SharedSlot              :1;
+    0,                                        // PcCard16Supported       :1;
+    0,                                        // CardBusSupported        :1;
+    0,                                        // ZoomVideoSupported      :1;
+    0,                                        // ModemRingResumeSupported:1;
+    1,                                        // PmeSignalSupported      :1;
+    1,                                        // HotPlugDevicesSupported :1;
+    1,                                        // SmbusSignalSupported    :1;
+    0                                         // Reserved                :21;
+  },
+  {0}                                           // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot5) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT5),        // SlotDesignation
+  EfiSlotTypePciExpress,                      // SlotType
+  EfiSlotDataBusWidth32Bit,                   // SlotDataBusWidth
+  EfiSlotUsageAvailable,                      // SlotUsage
+  EfiSlotLengthLong ,                         // SlotLength
+  3,                                          // SlotId
+  {                                           // SlotCharacteristics
+    0,                                        // CharacteristicsUnknown  :1;
+    0,                                        // Provides50Volts         :1;
+    1,                                        // Provides33Volts         :1;
+    0,                                        // SharedSlot              :1;
+    0,                                        // PcCard16Supported       :1;
+    0,                                        // CardBusSupported        :1;
+    0,                                        // ZoomVideoSupported      :1;
+    0,                                        // ModemRingResumeSupported:1;
+    1,                                        // PmeSignalSupported      :1;
+    1,                                        // HotPlugDevicesSupported :1;
+    1,                                        // SmbusSignalSupported    :1;
+    0                                         // Reserved                :21;
+  },
+  {0}                                           // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot6) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT6),        // SlotDesignation
+  EfiSlotTypePciExpress,                      // SlotType
+  EfiSlotDataBusWidth32Bit,                   // SlotDataBusWidth
+  EfiSlotUsageAvailable,                      // SlotUsage
+  EfiSlotLengthLong ,                         // SlotLength
+  3,                                          // SlotId
+  {                                           // SlotCharacteristics
+    0,                                        // CharacteristicsUnknown  :1;
+    0,                                        // Provides50Volts         :1;
+    1,                                        // Provides33Volts         :1;
+    0,                                        // SharedSlot              :1;
+    0,                                        // PcCard16Supported       :1;
+    0,                                        // CardBusSupported        :1;
+    0,                                        // ZoomVideoSupported      :1;
+    0,                                        // ModemRingResumeSupported:1;
+    1,                                        // PmeSignalSupported      :1;
+    1,                                        // HotPlugDevicesSupported :1;
+    1,                                        // SmbusSignalSupported    :1;
+    0                                         // Reserved                :21;
+  },
+  {0}                                           // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot7) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT7),        // SlotDesignation
+  EfiSlotTypePciExpress,                      // SlotType
+  EfiSlotDataBusWidth32Bit,                   // SlotDataBusWidth
+  EfiSlotUsageAvailable,                      // SlotUsage
+  EfiSlotLengthLong ,                         // SlotLength
+  3,                                          // SlotId
+  {                                           // SlotCharacteristics
+    0,                                        // CharacteristicsUnknown  :1;
+    0,                                        // Provides50Volts         :1;
+    1,                                        // Provides33Volts         :1;
+    0,                                        // SharedSlot              :1;
+    0,                                        // PcCard16Supported       :1;
+    0,                                        // CardBusSupported        :1;
+    0,                                        // ZoomVideoSupported      :1;
+    0,                                        // ModemRingResumeSupported:1;
+    1,                                        // PmeSignalSupported      :1;
+    1,                                        // HotPlugDevicesSupported :1;
+    1,                                        // SmbusSignalSupported    :1;
+    0                                         // Reserved                :21;
+  },
+  {0}                                           // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot8) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT8),        // SlotDesignation
+  EfiSlotTypePciExpress,                      // SlotType
+  EfiSlotDataBusWidth32Bit,                   // SlotDataBusWidth
+  EfiSlotUsageAvailable,                      // SlotUsage
+  EfiSlotLengthLong ,                         // SlotLength
+  3,                                          // SlotId
+  {                                           // SlotCharacteristics
+    0,                                        // CharacteristicsUnknown  :1;
+    0,                                        // Provides50Volts         :1;
+    1,                                        // Provides33Volts         :1;
+    0,                                        // SharedSlot              :1;
+    0,                                        // PcCard16Supported       :1;
+    0,                                        // CardBusSupported        :1;
+    0,                                        // ZoomVideoSupported      :1;
+    0,                                        // ModemRingResumeSupported:1;
+    1,                                        // PmeSignalSupported      :1;
+    1,                                        // HotPlugDevicesSupported :1;
+    1,                                        // SmbusSignalSupported    :1;
+    0                                         // Reserved                :21;
+  },
+  {0}                                           // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot9) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT9),        // SlotDesignation
+  EfiSlotTypeUnknown,                         // SlotType
+  EfiSlotDataBusWidthUnknown,                 // SlotDataBusWidth
+  EfiSlotUsageUnknown,                        // SlotUsage
+  EfiSlotLengthUnknown ,                      // SlotLength
+  0,                                          // SlotId
+  {                                           // SlotCharacteristics
+    0,                                        // CharacteristicsUnknown  :1;
+    0,                                        // Provides50Volts         :1;
+    1,                                        // Provides33Volts         :1;
+    0,                                        // SharedSlot              :1;
+    0,                                        // PcCard16Supported       :1;
+    0,                                        // CardBusSupported        :1;
+    0,                                        // ZoomVideoSupported      :1;
+    0,                                        // ModemRingResumeSupported:1;
+    1,                                        // PmeSignalSupported      :1;
+    1,                                        // HotPlugDevicesSupported :1;
+    1,                                        // SmbusSignalSupported    :1;
+    0                                         // Reserved                :21;
+  },
+  {0}                                           // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot10) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT10),       // SlotDesignation
+  EfiSlotTypeUnknown,                         // SlotType
+  EfiSlotDataBusWidthUnknown,                 // SlotDataBusWidth
+  EfiSlotUsageUnknown,                        // SlotUsage
+  EfiSlotLengthUnknown ,                      // SlotLength
+  0,                                          // SlotId
+  {                                           // SlotCharacteristics
+    0,                                        // CharacteristicsUnknown  :1;
+    0,                                        // Provides50Volts         :1;
+    1,                                        // Provides33Volts         :1;
+    0,                                        // SharedSlot              :1;
+    0,                                        // PcCard16Supported       :1;
+    0,                                        // CardBusSupported        :1;
+    0,                                        // ZoomVideoSupported      :1;
+    0,                                        // ModemRingResumeSupported:1;
+    1,                                        // PmeSignalSupported      :1;
+    1,                                        // HotPlugDevicesSupported :1;
+    1,                                        // SmbusSignalSupported    :1;
+    0                                         // Reserved                :21;
+  },
+  {0}                                           // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot11) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT11),       // SlotDesignation
+  EfiSlotTypeUnknown,                         // SlotType
+  EfiSlotDataBusWidthUnknown,                 // SlotDataBusWidth
+  EfiSlotUsageUnknown,                        // SlotUsage
+  EfiSlotLengthUnknown ,                      // SlotLength
+  0,                                          // SlotId
+  {                                           // SlotCharacteristics
+    0,                                        // CharacteristicsUnknown  :1;
+    0,                                        // Provides50Volts         :1;
+    1,                                        // Provides33Volts         :1;
+    0,                                        // SharedSlot              :1;
+    0,                                        // PcCard16Supported       :1;
+    0,                                        // CardBusSupported        :1;
+    0,                                        // ZoomVideoSupported      :1;
+    0,                                        // ModemRingResumeSupported:1;
+    1,                                        // PmeSignalSupported      :1;
+    1,                                        // HotPlugDevicesSupported :1;
+    1,                                        // SmbusSignalSupported    :1;
+    0                                         // Reserved                :21;
+  },
+  {0}                                           // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot12) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT12),       // SlotDesignation
+  EfiSlotTypeUnknown,                         // SlotType
+  EfiSlotDataBusWidthUnknown,                 // SlotDataBusWidth
+  EfiSlotUsageUnknown,                        // SlotUsage
+  EfiSlotLengthUnknown ,                      // SlotLength
+  0,                                          // SlotId
+  {                                           // SlotCharacteristics
+    0,                                        // CharacteristicsUnknown  :1;
+    0,                                        // Provides50Volts         :1;
+    1,                                        // Provides33Volts         :1;
+    0,                                        // SharedSlot              :1;
+    0,                                        // PcCard16Supported       :1;
+    0,                                        // CardBusSupported        :1;
+    0,                                        // ZoomVideoSupported      :1;
+    0,                                        // ModemRingResumeSupported:1;
+    1,                                        // PmeSignalSupported      :1;
+    1,                                        // HotPlugDevicesSupported :1;
+    1,                                        // SmbusSignalSupported    :1;
+    0                                         // Reserved                :21;
+  },
+  {0}                                           // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot13) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT13),       // SlotDesignation
+  EfiSlotTypeUnknown,                         // SlotType
+  EfiSlotDataBusWidthUnknown,                 // SlotDataBusWidth
+  EfiSlotUsageUnknown,                        // SlotUsage
+  EfiSlotLengthUnknown ,                      // SlotLength
+  0,                                          // SlotId
+  {                                           // SlotCharacteristics
+    0,                                        // CharacteristicsUnknown  :1;
+    0,                                        // Provides50Volts         :1;
+    1,                                        // Provides33Volts         :1;
+    0,                                        // SharedSlot              :1;
+    0,                                        // PcCard16Supported       :1;
+    0,                                        // CardBusSupported        :1;
+    0,                                        // ZoomVideoSupported      :1;
+    0,                                        // ModemRingResumeSupported:1;
+    1,                                        // PmeSignalSupported      :1;
+    1,                                        // HotPlugDevicesSupported :1;
+    1,                                        // SmbusSignalSupported    :1;
+    0                                         // Reserved                :21;
+  },
+  {0}                                           // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot14) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT14),       // SlotDesignation
+  EfiSlotTypeUnknown,                         // SlotType
+  EfiSlotDataBusWidthUnknown,                 // SlotDataBusWidth
+  EfiSlotUsageUnknown,                        // SlotUsage
+  EfiSlotLengthUnknown ,                      // SlotLength
+  0,                                          // SlotId
+  {                                           // SlotCharacteristics
+    0,                                        // CharacteristicsUnknown  :1;
+    0,                                        // Provides50Volts         :1;
+    1,                                        // Provides33Volts         :1;
+    0,                                        // SharedSlot              :1;
+    0,                                        // PcCard16Supported       :1;
+    0,                                        // CardBusSupported        :1;
+    0,                                        // ZoomVideoSupported      :1;
+    0,                                        // ModemRingResumeSupported:1;
+    1,                                        // PmeSignalSupported      :1;
+    1,                                        // HotPlugDevicesSupported :1;
+    1,                                        // SmbusSignalSupported    :1;
+    0                                         // Reserved                :21;
+  },
+  {0}                                           // SlotDevicePath
+};
+
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignationFunction.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignationFunction.c
new file mode 100644
index 0000000000..6a7348e3df
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignationFunction.c
@@ -0,0 +1,285 @@
+/** @file
+BIOS system slot designator information boot time changes.
+SMBIOS type 9.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+MiscSystemSlotDesignatorFunction.c
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+//
+//
+//
+
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot1);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot2);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot3);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot4);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot5);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot6);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot7);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot8);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot9);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot10);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot11);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot12);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot13);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot14);
+
+EFI_MISC_SYSTEM_SLOT_DESIGNATION  *mMiscSlotArray[SMBIOS_SYSTEM_SLOT_MAX_NUM] =
+{
+  MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot1),
+  MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot2),
+  MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot3),
+  MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot4),
+  MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot5),
+  MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot6),
+  MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot7),
+  MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot8),
+  MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot9),
+  MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot10),
+  MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot11),
+  MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot12),
+  MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot13),
+  MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot14),
+};
+
+BOOLEAN  PcdMiscSlotIsInit = FALSE;
+SMBIOS_SLOT_COFNIG  SMBIOSlotConfig = {0};
+
+/**
+  Get Misc Slot Configuration information from PCD
+  @param  SMBIOSPortConnector                 Pointer to SMBIOSPortConnector table.
+
+**/
+
+VOID
+GetMiscSLotConfigFromPcd ()
+{
+  //
+  // Type 9
+  //
+  SMBIOSlotConfig.SMBIOSSystemSlotNumber = PcdGet8 (PcdSMBIOSSystemSlotNumber);
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot1Designation), SMBIOSlotConfig.SMBIOSSystemSlot[0].SlotDesignation);
+  SMBIOSlotConfig.SMBIOSSystemSlot[0].SlotType = PcdGet8(PcdSMBIOSSystemSlot1Type);
+  SMBIOSlotConfig.SMBIOSSystemSlot[0].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot1DataBusWidth);
+  SMBIOSlotConfig.SMBIOSSystemSlot[0].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot1Usage);
+  SMBIOSlotConfig.SMBIOSSystemSlot[0].SlotLength = PcdGet8(PcdSMBIOSSystemSlot1Length);
+  SMBIOSlotConfig.SMBIOSSystemSlot[0].SlotId = PcdGet16(PcdSMBIOSSystemSlot1Id);
+  SMBIOSlotConfig.SMBIOSSystemSlot[0].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot1Characteristics);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot2Designation), SMBIOSlotConfig.SMBIOSSystemSlot[1].SlotDesignation);
+  SMBIOSlotConfig.SMBIOSSystemSlot[1].SlotType = PcdGet8(PcdSMBIOSSystemSlot2Type);
+  SMBIOSlotConfig.SMBIOSSystemSlot[1].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot2DataBusWidth);
+  SMBIOSlotConfig.SMBIOSSystemSlot[1].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot2Usage);
+  SMBIOSlotConfig.SMBIOSSystemSlot[1].SlotLength = PcdGet8(PcdSMBIOSSystemSlot2Length);
+  SMBIOSlotConfig.SMBIOSSystemSlot[1].SlotId = PcdGet16(PcdSMBIOSSystemSlot2Id);
+  SMBIOSlotConfig.SMBIOSSystemSlot[1].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot2Characteristics);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot3Designation), SMBIOSlotConfig.SMBIOSSystemSlot[2].SlotDesignation);
+  SMBIOSlotConfig.SMBIOSSystemSlot[2].SlotType = PcdGet8(PcdSMBIOSSystemSlot3Type);
+  SMBIOSlotConfig.SMBIOSSystemSlot[2].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot3DataBusWidth);
+  SMBIOSlotConfig.SMBIOSSystemSlot[2].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot3Usage);
+  SMBIOSlotConfig.SMBIOSSystemSlot[2].SlotLength = PcdGet8(PcdSMBIOSSystemSlot3Length);
+  SMBIOSlotConfig.SMBIOSSystemSlot[2].SlotId = PcdGet16(PcdSMBIOSSystemSlot3Id);
+  SMBIOSlotConfig.SMBIOSSystemSlot[2].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot3Characteristics);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot4Designation), SMBIOSlotConfig.SMBIOSSystemSlot[3].SlotDesignation);
+  SMBIOSlotConfig.SMBIOSSystemSlot[3].SlotType = PcdGet8(PcdSMBIOSSystemSlot4Type);
+  SMBIOSlotConfig.SMBIOSSystemSlot[3].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot4DataBusWidth);
+  SMBIOSlotConfig.SMBIOSSystemSlot[3].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot4Usage);
+  SMBIOSlotConfig.SMBIOSSystemSlot[3].SlotLength = PcdGet8(PcdSMBIOSSystemSlot4Length);
+  SMBIOSlotConfig.SMBIOSSystemSlot[3].SlotId = PcdGet16(PcdSMBIOSSystemSlot4Id);
+  SMBIOSlotConfig.SMBIOSSystemSlot[3].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot4Characteristics);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot5Designation), SMBIOSlotConfig.SMBIOSSystemSlot[4].SlotDesignation);
+  SMBIOSlotConfig.SMBIOSSystemSlot[4].SlotType = PcdGet8(PcdSMBIOSSystemSlot5Type);
+  SMBIOSlotConfig.SMBIOSSystemSlot[4].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot5DataBusWidth);
+  SMBIOSlotConfig.SMBIOSSystemSlot[4].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot5Usage);
+  SMBIOSlotConfig.SMBIOSSystemSlot[4].SlotLength = PcdGet8(PcdSMBIOSSystemSlot5Length);
+  SMBIOSlotConfig.SMBIOSSystemSlot[4].SlotId = PcdGet16(PcdSMBIOSSystemSlot5Id);
+  SMBIOSlotConfig.SMBIOSSystemSlot[4].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot5Characteristics);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot6Designation), SMBIOSlotConfig.SMBIOSSystemSlot[5].SlotDesignation);
+  SMBIOSlotConfig.SMBIOSSystemSlot[5].SlotType = PcdGet8(PcdSMBIOSSystemSlot6Type);
+  SMBIOSlotConfig.SMBIOSSystemSlot[5].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot6DataBusWidth);
+  SMBIOSlotConfig.SMBIOSSystemSlot[5].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot6Usage);
+  SMBIOSlotConfig.SMBIOSSystemSlot[5].SlotLength = PcdGet8(PcdSMBIOSSystemSlot6Length);
+  SMBIOSlotConfig.SMBIOSSystemSlot[5].SlotId = PcdGet16(PcdSMBIOSSystemSlot6Id);
+  SMBIOSlotConfig.SMBIOSSystemSlot[5].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot6Characteristics);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot7Designation), SMBIOSlotConfig.SMBIOSSystemSlot[6].SlotDesignation);
+  SMBIOSlotConfig.SMBIOSSystemSlot[6].SlotType = PcdGet8(PcdSMBIOSSystemSlot7Type);
+  SMBIOSlotConfig.SMBIOSSystemSlot[6].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot7DataBusWidth);
+  SMBIOSlotConfig.SMBIOSSystemSlot[6].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot7Usage);
+  SMBIOSlotConfig.SMBIOSSystemSlot[6].SlotLength = PcdGet8(PcdSMBIOSSystemSlot7Length);
+  SMBIOSlotConfig.SMBIOSSystemSlot[6].SlotId = PcdGet16(PcdSMBIOSSystemSlot7Id);
+  SMBIOSlotConfig.SMBIOSSystemSlot[6].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot7Characteristics);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot8Designation), SMBIOSlotConfig.SMBIOSSystemSlot[7].SlotDesignation);
+  SMBIOSlotConfig.SMBIOSSystemSlot[7].SlotType = PcdGet8(PcdSMBIOSSystemSlot8Type);
+  SMBIOSlotConfig.SMBIOSSystemSlot[7].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot8DataBusWidth);
+  SMBIOSlotConfig.SMBIOSSystemSlot[7].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot8Usage);
+  SMBIOSlotConfig.SMBIOSSystemSlot[7].SlotLength = PcdGet8(PcdSMBIOSSystemSlot8Length);
+  SMBIOSlotConfig.SMBIOSSystemSlot[7].SlotId = PcdGet16(PcdSMBIOSSystemSlot8Id);
+  SMBIOSlotConfig.SMBIOSSystemSlot[7].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot8Characteristics);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot9Designation), SMBIOSlotConfig.SMBIOSSystemSlot[8].SlotDesignation);
+  SMBIOSlotConfig.SMBIOSSystemSlot[8].SlotType = PcdGet8(PcdSMBIOSSystemSlot9Type);
+  SMBIOSlotConfig.SMBIOSSystemSlot[8].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot9DataBusWidth);
+  SMBIOSlotConfig.SMBIOSSystemSlot[8].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot9Usage);
+  SMBIOSlotConfig.SMBIOSSystemSlot[8].SlotLength = PcdGet8(PcdSMBIOSSystemSlot9Length);
+  SMBIOSlotConfig.SMBIOSSystemSlot[8].SlotId = PcdGet16(PcdSMBIOSSystemSlot9Id);
+  SMBIOSlotConfig.SMBIOSSystemSlot[8].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot9Characteristics);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot10Designation), SMBIOSlotConfig.SMBIOSSystemSlot[9].SlotDesignation);
+  SMBIOSlotConfig.SMBIOSSystemSlot[9].SlotType = PcdGet8(PcdSMBIOSSystemSlot10Type);
+  SMBIOSlotConfig.SMBIOSSystemSlot[9].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot10DataBusWidth);
+  SMBIOSlotConfig.SMBIOSSystemSlot[9].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot10Usage);
+  SMBIOSlotConfig.SMBIOSSystemSlot[9].SlotLength = PcdGet8(PcdSMBIOSSystemSlot10Length);
+  SMBIOSlotConfig.SMBIOSSystemSlot[9].SlotId = PcdGet16(PcdSMBIOSSystemSlot10Id);
+  SMBIOSlotConfig.SMBIOSSystemSlot[9].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot10Characteristics);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot11Designation), SMBIOSlotConfig.SMBIOSSystemSlot[10].SlotDesignation);
+  SMBIOSlotConfig.SMBIOSSystemSlot[10].SlotType = PcdGet8(PcdSMBIOSSystemSlot11Type);
+  SMBIOSlotConfig.SMBIOSSystemSlot[10].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot11DataBusWidth);
+  SMBIOSlotConfig.SMBIOSSystemSlot[10].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot11Usage);
+  SMBIOSlotConfig.SMBIOSSystemSlot[10].SlotLength = PcdGet8(PcdSMBIOSSystemSlot11Length);
+  SMBIOSlotConfig.SMBIOSSystemSlot[10].SlotId = PcdGet16(PcdSMBIOSSystemSlot11Id);
+  SMBIOSlotConfig.SMBIOSSystemSlot[10].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot11Characteristics);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot12Designation), SMBIOSlotConfig.SMBIOSSystemSlot[11].SlotDesignation);
+  SMBIOSlotConfig.SMBIOSSystemSlot[11].SlotType = PcdGet8(PcdSMBIOSSystemSlot12Type);
+  SMBIOSlotConfig.SMBIOSSystemSlot[11].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot12DataBusWidth);
+  SMBIOSlotConfig.SMBIOSSystemSlot[11].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot12Usage);
+  SMBIOSlotConfig.SMBIOSSystemSlot[11].SlotLength = PcdGet8(PcdSMBIOSSystemSlot12Length);
+  SMBIOSlotConfig.SMBIOSSystemSlot[11].SlotId = PcdGet16(PcdSMBIOSSystemSlot12Id);
+  SMBIOSlotConfig.SMBIOSSystemSlot[11].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot12Characteristics);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot13Designation), SMBIOSlotConfig.SMBIOSSystemSlot[12].SlotDesignation);
+  SMBIOSlotConfig.SMBIOSSystemSlot[12].SlotType = PcdGet8(PcdSMBIOSSystemSlot13Type);
+  SMBIOSlotConfig.SMBIOSSystemSlot[12].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot13DataBusWidth);
+  SMBIOSlotConfig.SMBIOSSystemSlot[12].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot13Usage);
+  SMBIOSlotConfig.SMBIOSSystemSlot[12].SlotLength = PcdGet8(PcdSMBIOSSystemSlot13Length);
+  SMBIOSlotConfig.SMBIOSSystemSlot[12].SlotId = PcdGet16(PcdSMBIOSSystemSlot13Id);
+  SMBIOSlotConfig.SMBIOSSystemSlot[12].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot13Characteristics);
+
+  AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot14Designation), SMBIOSlotConfig.SMBIOSSystemSlot[13].SlotDesignation);
+  SMBIOSlotConfig.SMBIOSSystemSlot[13].SlotType = PcdGet8(PcdSMBIOSSystemSlot14Type);
+  SMBIOSlotConfig.SMBIOSSystemSlot[13].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot14DataBusWidth);
+  SMBIOSlotConfig.SMBIOSSystemSlot[13].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot14Usage);
+  SMBIOSlotConfig.SMBIOSSystemSlot[13].SlotLength = PcdGet8(PcdSMBIOSSystemSlot14Length);
+  SMBIOSlotConfig.SMBIOSSystemSlot[13].SlotId = PcdGet16(PcdSMBIOSSystemSlot14Id);
+  SMBIOSlotConfig.SMBIOSSystemSlot[13].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot14Characteristics);
+}
+/**
+  This function makes boot time changes to the contents of the
+  MiscSystemSlotDesignator structure (Type 9).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscSystemSlotDesignator)
+{
+  CHAR8                              *OptionalStrStart;
+  UINTN                              SlotDesignationStrLen;
+  EFI_STATUS                         Status;
+  EFI_STRING                         SlotDesignation;
+  STRING_REF                         TokenToUpdate;
+  STRING_REF                         TokenToGet;
+  SMBIOS_TABLE_TYPE9                 *SmbiosRecord;
+  EFI_SMBIOS_HANDLE                  SmbiosHandle;
+  EFI_MISC_SYSTEM_SLOT_DESIGNATION*  ForType9InputData;
+  UINT8                              Index;
+
+  ForType9InputData   = (EFI_MISC_SYSTEM_SLOT_DESIGNATION *)RecordData;
+
+  TokenToGet          = 0;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!PcdMiscSlotIsInit) {
+    GetMiscSLotConfigFromPcd ();
+    PcdMiscSlotIsInit = TRUE;
+  }
+
+  for (Index = 0; Index < SMBIOS_SYSTEM_SLOT_MAX_NUM; Index++) {
+    if (ForType9InputData->SlotDesignation == (mMiscSlotArray[Index])->SlotDesignation) {
+      //DEBUG ((EFI_D_ERROR, "Found slot Data %d : ", Index));
+      break;
+    }
+  }
+  if (Index >= SMBIOSlotConfig.SMBIOSSystemSlotNumber) {
+    return EFI_SUCCESS;
+  }
+
+  if (Index >= SMBIOS_SYSTEM_SLOT_MAX_NUM) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  SlotDesignation = SMBIOSlotConfig.SMBIOSSystemSlot[Index].SlotDesignation;
+  TokenToGet = STRING_TOKEN ((mMiscSlotArray[Index])->SlotDesignation);
+
+  if (StrLen (SlotDesignation) > 0) {
+    TokenToUpdate = STRING_TOKEN ((mMiscSlotArray[Index])->SlotDesignation);
+    HiiSetString (mHiiHandle, TokenToUpdate, SlotDesignation, NULL);
+  }
+
+  SlotDesignation = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+  SlotDesignationStrLen = StrLen(SlotDesignation);
+  if (SlotDesignationStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE9) + SlotDesignationStrLen + 1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE9) +SlotDesignationStrLen + 1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_SLOTS;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE9);
+  SmbiosRecord->Hdr.Handle = 0;
+  SmbiosRecord->SlotDesignation = 1;
+  SmbiosRecord->SlotType = SMBIOSlotConfig.SMBIOSSystemSlot[Index].SlotType;
+  SmbiosRecord->SlotDataBusWidth = SMBIOSlotConfig.SMBIOSSystemSlot[Index].SlotDataBusWidth;
+  SmbiosRecord->CurrentUsage = SMBIOSlotConfig.SMBIOSSystemSlot[Index].SlotUsage;
+  SmbiosRecord->SlotLength = SMBIOSlotConfig.SMBIOSSystemSlot[Index].SlotLength;
+  SmbiosRecord->SlotID = SMBIOSlotConfig.SMBIOSSystemSlot[Index].SlotId;
+  *(UINT16 *)&SmbiosRecord->SlotCharacteristics1 = (UINT16)(SMBIOSlotConfig.SMBIOSSystemSlot[Index].SlotCharacteristics);
+
+  //
+  // Slot Characteristics
+  //
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  UnicodeStrToAsciiStr(SlotDesignation, OptionalStrStart);
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+  FreePool(SmbiosRecord);
+  return Status;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotOnboardDevices.uni b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotOnboardDevices.uni
new file mode 100644
index 0000000000..ce1d9199d6
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotOnboardDevices.uni
@@ -0,0 +1,23 @@
+// /** @file
+// System Slot onboard devices
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+// **/
+/=#
+
+
+
+#string STR_MISC_SYSTEM_SLOT_P64_B1 #language en-US "P64B1"
+#string STR_MISC_SYSTEM_SLOT_P64_B2 #language en-US "P64B2"
+#string STR_MISC_SYSTEM_SLOT_P64_B3 #language en-US "P64B3"
+#string STR_MISC_SYSTEM_SLOT_P64_C1 #language en-US "P64C1"
+#string STR_MISC_SYSTEM_SLOT_P64_C2 #language en-US "P64C2"
+#string STR_MISC_SYSTEM_SLOT_P64_C3 #language en-US "P64C3"
+
+
+
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMisc.h b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMisc.h
new file mode 100644
index 0000000000..b59933ba3a
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMisc.h
@@ -0,0 +1,137 @@
+/** @file
+Header file for the SmbiosMisc Driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#ifndef _SMBIOS_MISC_H
+#define _SMBIOS_MISC_H
+
+#include "MiscDevicePath.h"
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/PrintLib.h>
+
+///
+/// Reference SMBIOS 2.6, chapter 3.1.3.
+/// Each text string is limited to 64 significant characters due to system MIF limitations.
+///
+#define SMBIOS_STRING_MAX_LENGTH        64
+#define SMBIOS_PORT_CONNECTOR_MAX_NUM   14
+
+typedef struct {
+  CHAR16   PortInternalConnectorDesignator[SMBIOS_STRING_MAX_LENGTH];
+  CHAR16   PortExternalConnectorDesignator[SMBIOS_STRING_MAX_LENGTH];
+  UINT8    PortInternalConnectorType;
+  UINT8    PortExternalConnectorType;
+  UINT8    PortType;
+} SMBIOS_PORT_CONNECTOR_DESIGNATOR;
+
+typedef struct {
+  UINT8                             SMBIOSConnectorNumber;
+  SMBIOS_PORT_CONNECTOR_DESIGNATOR  SMBIOSPortConnector[SMBIOS_PORT_CONNECTOR_MAX_NUM];
+} SMBIOS_PORT_CONNECTOR_DESIGNATOR_COFNIG;
+
+#define SMBIOS_SYSTEM_SLOT_MAX_NUM  14
+
+typedef struct {
+  CHAR16    SlotDesignation[SMBIOS_STRING_MAX_LENGTH];
+  UINT8     SlotType;
+  UINT8     SlotDataBusWidth;
+  UINT8     SlotUsage;
+  UINT8     SlotLength;
+  UINT16    SlotId;
+  UINT32    SlotCharacteristics;
+} SMBIOS_SLOT_DESIGNATION;
+
+typedef struct {
+  UINT8                    SMBIOSSystemSlotNumber;
+  SMBIOS_SLOT_DESIGNATION  SMBIOSSystemSlot[SMBIOS_SYSTEM_SLOT_MAX_NUM];
+} SMBIOS_SLOT_COFNIG;
+
+//
+// Data table entry update function.
+//
+typedef EFI_STATUS (EFIAPI EFI_MISC_SMBIOS_DATA_FUNCTION) (
+  IN  VOID                 *RecordData,
+  IN  EFI_SMBIOS_PROTOCOL  *Smbios
+  );
+
+
+//
+// Data table entry definition.
+//
+typedef struct {
+  //
+  // intermediat input data for SMBIOS record
+  //
+  VOID                              *RecordData;
+  EFI_MISC_SMBIOS_DATA_FUNCTION     *Function;
+} EFI_MISC_SMBIOS_DATA_TABLE;
+
+//
+// Data Table extern definitions.
+//
+#define MISC_SMBIOS_DATA_TABLE_POINTER(NAME1) \
+   & NAME1 ## Data
+
+//
+// Data Table extern definitions.
+//
+#define MISC_SMBIOS_DATA_TABLE_EXTERNS(NAME1, NAME2) \
+extern NAME1 NAME2 ## Data
+
+//
+// Data and function Table extern definitions.
+//
+#define MISC_SMBIOS_TABLE_EXTERNS(NAME1, NAME2, NAME3) \
+extern NAME1 NAME2 ## Data; \
+extern EFI_MISC_SMBIOS_DATA_FUNCTION NAME3 ## Function
+
+
+//
+// Data Table entries
+//
+
+#define MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(NAME1, NAME2) \
+{ \
+  & NAME1 ## Data, \
+  & NAME2 ## Function \
+}
+
+
+//
+// Global definition macros.
+//
+#define MISC_SMBIOS_TABLE_DATA(NAME1, NAME2) \
+  NAME1 NAME2 ## Data
+
+#define MISC_SMBIOS_TABLE_FUNCTION(NAME2) \
+  EFI_STATUS EFIAPI NAME2 ## Function( \
+  IN  VOID                  *RecordData, \
+  IN  EFI_SMBIOS_PROTOCOL   *Smbios \
+  )
+
+
+// Data Table Array
+//
+extern EFI_MISC_SMBIOS_DATA_TABLE   mSmbiosMiscDataTable[];
+
+//
+// Data Table Array Entries
+//
+extern UINTN                        mSmbiosMiscDataTableEntries;
+extern EFI_HII_HANDLE               mHiiHandle;
+//
+// Prototypes
+//
+EFI_STATUS
+PiSmbiosMiscEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  );
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscDataTable.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscDataTable.c
new file mode 100644
index 0000000000..fb57e36cd1
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscDataTable.c
@@ -0,0 +1,109 @@
+/** @file
+This driver parses the mSmbiosMiscDataTable structure and reports
+any generated data using SMBIOS protocol.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+
+//
+// External definitions referenced by Data Table entries.
+//
+
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_BIOS_VENDOR, MiscBiosVendor, MiscBiosVendor);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_MANUFACTURER, MiscSystemManufacturer, MiscSystemManufacturer);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_MANUFACTURER, MiscBaseBoardManufacturer, MiscBaseBoardManufacturer);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_CHASSIS_MANUFACTURER, MiscChassisManufacturer, MiscChassisManufacturer);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_BOOT_INFORMATION_STATUS, MiscBootInfoStatus, MiscBootInfoStatus);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES, NumberOfInstallableLanguages, NumberOfInstallableLanguages);
+MISC_SMBIOS_TABLE_EXTERNS (EFI_MISC_SYSTEM_OPTION_STRING, SystemOptionString, SystemOptionString);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_ONBOARD_DEVICE, MiscOnboardDeviceVideo, MiscOnboardDevice);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_OEM_STRING,MiscOemString, MiscOemString);
+
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector1, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector2, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector3, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector4, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector5, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector6, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector7, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector8, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector9, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector10, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector11, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector12, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector13, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector14, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot1, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot2, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot3, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot4, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot5, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot6, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot7, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot8, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot9, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot10, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot11, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot12, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot13, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot14, MiscSystemSlotDesignator);
+
+
+//
+// Data Table
+//
+EFI_MISC_SMBIOS_DATA_TABLE mSmbiosMiscDataTable[] = {
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscBiosVendor, MiscBiosVendor),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemManufacturer, MiscSystemManufacturer),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscBaseBoardManufacturer, MiscBaseBoardManufacturer),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscChassisManufacturer, MiscChassisManufacturer),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector1, MiscPortInternalConnectorDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector2, MiscPortInternalConnectorDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector3, MiscPortInternalConnectorDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector4, MiscPortInternalConnectorDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector5, MiscPortInternalConnectorDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector6, MiscPortInternalConnectorDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector7, MiscPortInternalConnectorDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector8, MiscPortInternalConnectorDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector9, MiscPortInternalConnectorDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector10, MiscPortInternalConnectorDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector11, MiscPortInternalConnectorDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector12, MiscPortInternalConnectorDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector13, MiscPortInternalConnectorDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector14, MiscPortInternalConnectorDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot1, MiscSystemSlotDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot2, MiscSystemSlotDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot3, MiscSystemSlotDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot4, MiscSystemSlotDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot5, MiscSystemSlotDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot6, MiscSystemSlotDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot7, MiscSystemSlotDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot8, MiscSystemSlotDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot9, MiscSystemSlotDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot10, MiscSystemSlotDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot11, MiscSystemSlotDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot12, MiscSystemSlotDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot13, MiscSystemSlotDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot14, MiscSystemSlotDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscOnboardDeviceVideo, MiscOnboardDevice),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscOemString, MiscOemString),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(SystemOptionString, SystemOptionString),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(NumberOfInstallableLanguages, NumberOfInstallableLanguages),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscBootInfoStatus, MiscBootInfoStatus)
+};
+
+//
+// Number of Data Table entries.
+//
+UINTN mSmbiosMiscDataTableEntries =
+  (sizeof mSmbiosMiscDataTable) / sizeof(EFI_MISC_SMBIOS_DATA_TABLE);
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscDxe.inf b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscDxe.inf
new file mode 100644
index 0000000000..d2b6123a7a
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscDxe.inf
@@ -0,0 +1,308 @@
+## @file
+# Component description file for Smbios Misc module.
+#
+# This driver parses the mSmbiosMiscDataTable structure
+# and reports any generated data using SMBIOS protocol.
+#  SmBios To Misc.Subclass Map Table.
+#  SMBIOS Type |SMBIOS Name   |Misc Subclass Record |Misc Subclass Name
+#  0  | BIOS Information  | 0x2   | BiosVendor
+#  3  | System/Chassis Enclosure | 0x5   | ChassisManufacturer
+#  8  | Port Connector Information | 0x6   | PortInternalConnectorDesignator
+#  9  | System Slot Information | 0x7   | SystemSlotDesignator
+#  10  | On Board Device Information | 0x8   | OnboardDevice
+#  12  | System Configuration Options| 0xA   | SystemOptionString
+#  13  | BIOS Language Information | 0xB   | NumberOfInstallableLanguages
+#  32  | Boot Information  | 0x1A   | BootInformationStatus
+#  The uni files tagged with "ToolCode="DUMMY"" are included by SmbiosMiscStrings.uni file which is input
+#  file for StrGather tool.
+# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SmbiosMisc
+  FILE_GUID                      = EF0C99B6-B1D3-4025-9405-BF6A560FE0E0
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = SmbiosMiscEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  MiscOemStringFunction.c
+  MiscOemStringData.c
+  SmbiosMiscEntryPoint.c
+  SmbiosMiscDataTable.c
+  MiscSystemManufacturerData.c
+  MiscSystemManufacturerFunction.c
+  MiscBaseBoardManufacturerData.c
+  MiscBaseBoardManufacturerFunction.c
+  MiscOnboardDeviceFunction.c
+  MiscOnboardDeviceData.c
+  MiscSystemSlotDesignationFunction.c
+  MiscSystemSlotDesignationData.c
+  MiscNumberOfInstallableLanguagesFunction.c
+  MiscNumberOfInstallableLanguagesData.c
+  MiscChassisManufacturerFunction.c
+  MiscChassisManufacturerData.c
+  MiscBootInformationFunction.c
+  MiscBootInformationData.c
+  MiscBiosVendorFunction.c
+  MiscBiosVendorData.c
+  MiscSystemOptionStringFunction.c
+  MiscSystemOptionStringData.c
+  MiscPortInternalConnectorDesignatorFunction.c
+  MiscPortInternalConnectorDesignatorData.c
+  SmbiosMisc.h
+  MiscDevicePath.h
+  SmbiosMiscStrings.uni
+  CommonHeader.h
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  HiiLib
+  MemoryAllocationLib
+  DevicePathLib
+  BaseMemoryLib
+  BaseLib
+  DebugLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+
+[Protocols]
+  gEfiSmbiosProtocolGuid                       # PROTOCOL ALWAYS_CONSUMED
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareRevision
+  gQuarkPlatformTokenSpaceGuid.PcdPlatformTypeName
+  gQuarkPlatformTokenSpaceGuid.PcdFlashAreaSize
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBiosVendor
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBiosReleaseDate
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBiosStartAddress
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBiosChar
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBiosCharEx1
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBiosCharEx2
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemManufacturer
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemProductName
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemVersion
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSerialNumber
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemUuid
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSKUNumber
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemFamily
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBoardManufacturer
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBoardProductName
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBoardVersion
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBoardSerialNumber
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisManufacturer
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisVersion
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisSerialNumber
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisAssetTag
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisBootupState
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisPowerSupplyState
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisSecurityState
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisOemDefined
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisHeight
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisNumberPowerCords
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisElementCount
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisElementRecordLength
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSConnectorNumber
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort1InternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort1ExternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort1InternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort1ExternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort1Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort2InternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort2ExternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort2InternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort2ExternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort2Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort3InternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort3ExternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort3InternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort3ExternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort3Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort4InternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort4ExternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort4InternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort4ExternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort4Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort5InternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort5ExternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort5InternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort5ExternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort5Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort6InternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort6ExternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort6InternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort6ExternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort6Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort7InternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort7ExternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort7InternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort7ExternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort7Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort8InternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort8ExternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort8InternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort8ExternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort8Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort9InternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort9ExternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort9InternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort9ExternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort9Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort10InternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort10ExternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort10InternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort10ExternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort10Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort11InternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort11ExternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort11InternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort11ExternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort11Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort12InternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort12ExternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort12InternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort12ExternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort12Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort13InternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort13ExternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort13InternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort13ExternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort13Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort14InternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort14ExternalConnectorDesignator
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort14InternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort14ExternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort14Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort15InternalConnectorDesignator
+
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort15InternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort15ExternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort15Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort16InternalConnectorDesignator
+
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort16InternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort16ExternalConnectorType
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort16Type
+
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlotNumber
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot1Designation
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot1Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot1DataBusWidth
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot1Usage
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot1Length
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot1Id
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot1Characteristics
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot2Designation
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot2Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot2DataBusWidth
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot2Usage
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot2Length
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot2Id
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot2Characteristics
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot3Designation
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot3Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot3DataBusWidth
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot3Usage
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot3Length
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot3Id
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot3Characteristics
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot4Designation
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot4Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot4DataBusWidth
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot4Usage
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot4Length
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot4Id
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot4Characteristics
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot5Designation
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot5Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot5DataBusWidth
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot5Usage
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot5Length
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot5Id
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot5Characteristics
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot6Designation
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot6Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot6DataBusWidth
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot6Usage
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot6Length
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot6Id
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot6Characteristics
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot7Designation
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot7Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot7DataBusWidth
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot7Usage
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot7Length
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot7Id
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot7Characteristics
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot8Designation
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot8Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot8DataBusWidth
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot8Usage
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot8Length
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot8Id
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot8Characteristics
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot9Designation
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot9Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot9DataBusWidth
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot9Usage
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot9Length
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot9Id
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot9Characteristics
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot10Designation
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot10Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot10DataBusWidth
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot10Usage
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot10Length
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot10Id
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot10Characteristics
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot11Designation
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot11Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot11DataBusWidth
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot11Usage
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot11Length
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot11Id
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot11Characteristics
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot12Designation
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot12Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot12DataBusWidth
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot12Usage
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot12Length
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot12Id
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot12Characteristics
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot13Designation
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot13Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot13DataBusWidth
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot13Usage
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot13Length
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot13Id
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot13Characteristics
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot14Designation
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot14Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot14DataBusWidth
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot14Usage
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot14Length
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot14Id
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot14Characteristics
+
+[Depex]
+  gEfiSmbiosProtocolGuid
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscEntryPoint.c b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscEntryPoint.c
new file mode 100644
index 0000000000..c8bc7ef901
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscEntryPoint.c
@@ -0,0 +1,82 @@
+/** @file
+This driver parses the mSmbiosMiscDataTable structure and reports
+any generated data using SMBIOS protocol.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+
+extern UINT8 SmbiosMiscStrings[];
+EFI_HANDLE   mImageHandle;
+
+EFI_HII_HANDLE  mHiiHandle;
+
+
+
+/**
+  Standard EFI driver point.  This driver parses the mSmbiosMiscDataTable
+  structure and reports any generated data using SMBIOS protocol.
+
+  @param  ImageHandle     Handle for the image of this driver
+  @param  SystemTable     Pointer to the EFI System Table
+
+  @retval  EFI_SUCCESS    The data was successfully stored.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbiosMiscEntryPoint(
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  UINTN                Index;
+  EFI_STATUS           EfiStatus;
+  EFI_SMBIOS_PROTOCOL  *Smbios;
+
+
+  mImageHandle = ImageHandle;
+
+  EfiStatus = gBS->LocateProtocol(&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios);
+
+  if (EFI_ERROR(EfiStatus)) {
+    DEBUG((EFI_D_ERROR, "Could not locate SMBIOS protocol.  %r\n", EfiStatus));
+    return EfiStatus;
+  }
+
+  mHiiHandle = HiiAddPackages (
+                 &gEfiCallerIdGuid,
+                 mImageHandle,
+                 SmbiosMiscStrings,
+                 NULL
+                 );
+  ASSERT (mHiiHandle != NULL);
+
+  for (Index = 0; Index < mSmbiosMiscDataTableEntries; ++Index) {
+    //
+    // If the entry have a function pointer, just log the data.
+    //
+    if (mSmbiosMiscDataTable[Index].Function != NULL) {
+      EfiStatus = (*mSmbiosMiscDataTable[Index].Function)(
+        mSmbiosMiscDataTable[Index].RecordData,
+        Smbios
+        );
+
+      if (EFI_ERROR(EfiStatus)) {
+        DEBUG((EFI_D_ERROR, "Misc smbios store error.  Index=%d, ReturnStatus=%r\n", Index, EfiStatus));
+        return EfiStatus;
+      }
+    }
+  }
+
+  return EfiStatus;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscStrings.uni b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscStrings.uni
new file mode 100644
index 0000000000..d8e6d0df78
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscStrings.uni
@@ -0,0 +1,26 @@
+// /** @file
+// SmbiosMisc formset.
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+// **/
+
+/=#
+
+#langdef en-US "English"
+
+#string STR_MISC_SUBCLASS_DRIVER_TITLE #language en-US  "SMBIOS Misc subclass driver"
+
+
+#include "MiscBiosVendor.uni"
+#include "MiscChassisManufacturer.uni"
+#include "MiscPortInternalConnectorDesignator.uni"
+#include "MiscSystemManufacturer.uni"
+#include "MiscBaseBoardManufacturer.uni"
+#include "MiscSystemOptionString.uni"
+#include "MiscSystemSlotDesignation.uni"
+#include "MiscOnboardDevice.uni"
+#include "MiscOemString.uni"
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.c b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.c
new file mode 100644
index 0000000000..024dff89df
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.c
@@ -0,0 +1,81 @@
+/** @file
+Principle source module for Clanton Peak platform config PEIM driver.
+
+Copyright (c) 2013 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/IntelQNCLib.h>
+#include <Library/PlatformHelperLib.h>
+#include <Library/QNCAccessLib.h>
+
+VOID
+EFIAPI
+LegacySpiProtect (
+  VOID
+  )
+{
+  UINT32  RegVal;
+
+  RegVal = PcdGet32 (PcdLegacyProtectedBIOSRange0Pei);
+  if (RegVal != 0) {
+    PlatformWriteFirstFreeSpiProtect (
+      RegVal,
+      0,
+      0
+      );
+  }
+  RegVal = PcdGet32 (PcdLegacyProtectedBIOSRange1Pei);
+  if (RegVal != 0) {
+    PlatformWriteFirstFreeSpiProtect (
+      RegVal,
+      0,
+      0
+      );
+  }
+  RegVal = PcdGet32 (PcdLegacyProtectedBIOSRange2Pei);
+  if (RegVal != 0) {
+    PlatformWriteFirstFreeSpiProtect (
+      RegVal,
+      0,
+      0
+      );
+  }
+
+  //
+  // Make legacy SPI READ/WRITE enabled if not a secure build
+  //
+  LpcPciCfg32And (R_QNC_LPC_BIOS_CNTL, ~B_QNC_LPC_BIOS_CNTL_BIOSWE);
+}
+
+/** PlatformConfigPei driver entry point.
+
+  Platform config in PEI stage.
+
+  @param[in]       FfsHeader    Pointer to Firmware File System file header.
+  @param[in]       PeiServices  General purpose services available to every PEIM.
+
+  @retval EFI_SUCCESS           Platform config success.
+*/
+EFI_STATUS
+EFIAPI
+PlatformConfigPeiInit (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  //
+  // Do SOC Init Pre memory init.
+  //
+  PeiQNCPreMemInit ();
+
+  //
+  // Protect areas specified by PCDs.
+  //
+  LegacySpiProtect ();
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.inf b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.inf
new file mode 100644
index 0000000000..e6c92850b2
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.inf
@@ -0,0 +1,45 @@
+## @file
+# Component description file for Clanton Peak platform config PEIM module.
+#
+# Copyright (c) 2013 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformConfigPei
+  FILE_GUID                      = 55961E20-B0D9-4553-9948-E3ECF0BE0889
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = PlatformConfigPeiInit
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32
+#
+
+[Sources]
+  PlatformConfigPei.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  PeimEntryPoint
+  PcdLib
+  IntelQNCLib
+  PlatformHelperLib
+  QNCAccessLib
+
+[Pcd]
+  gQuarkPlatformTokenSpaceGuid.PcdLegacyProtectedBIOSRange0Pei
+  gQuarkPlatformTokenSpaceGuid.PcdLegacyProtectedBIOSRange1Pei
+  gQuarkPlatformTokenSpaceGuid.PcdLegacyProtectedBIOSRange2Pei
+
+[Depex]
+  TRUE
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/BootMode.c b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/BootMode.c
new file mode 100644
index 0000000000..2e22e80c8e
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/BootMode.c
@@ -0,0 +1,218 @@
+/** @file
+This file provide the function to detect boot mode
+
+Copyright (c) 2013 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "CommonHeader.h"
+#include <Pi/PiFirmwareVolume.h>
+
+EFI_PEI_PPI_DESCRIPTOR mPpiListRecoveryBootMode = {
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEfiPeiBootInRecoveryModePpiGuid,
+  NULL
+};
+
+/**
+  If the box was opened, it's boot with full config.
+  If the box is closed, then
+    1. If it's first time to boot, it's boot with full config .
+    2. If the ChassisIntrution is selected, force to be a boot with full config
+    3. Otherwise it's boot with no change.
+
+  @param  PeiServices General purpose services available to every PEIM.
+
+  @retval TRUE  If it's boot with no change.
+
+  @retval FALSE If boot with no change.
+**/
+BOOLEAN
+IsBootWithNoChange (
+  IN EFI_PEI_SERVICES   **PeiServices
+  )
+{
+  BOOLEAN IsFirstBoot = FALSE;
+
+  BOOLEAN EnableFastBoot = FALSE;
+  IsFirstBoot = PcdGetBool(PcdBootState);
+  EnableFastBoot = PcdGetBool (PcdEnableFastBoot);
+
+  DEBUG ((EFI_D_INFO, "IsFirstBoot = %x , EnableFastBoot= %x. \n", IsFirstBoot, EnableFastBoot));
+
+  if ((!IsFirstBoot) && EnableFastBoot) {
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
+
+
+/**
+
+Routine Description:
+
+  This function is used to verify if the FV header is validate.
+
+  @param  FwVolHeader - The FV header that to be verified.
+
+  @retval EFI_SUCCESS   - The Fv header is valid.
+  @retval EFI_NOT_FOUND - The Fv header is invalid.
+
+**/
+EFI_STATUS
+ValidateFvHeader (
+  EFI_BOOT_MODE      *BootMode
+  )
+{
+  UINT16  *Ptr;
+  UINT16  HeaderLength;
+  UINT16  Checksum;
+
+  EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader;
+
+  if (BOOT_IN_RECOVERY_MODE == *BootMode) {
+    DEBUG ((EFI_D_INFO, "Boot mode recovery\n"));
+    return EFI_SUCCESS;
+  }
+  //
+  // Let's check whether FvMain header is valid, if not enter into recovery mode
+  //
+  //
+  // Verify the header revision, header signature, length
+  // Length of FvBlock cannot be 2**64-1
+  // HeaderLength cannot be an odd number
+  //
+  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32(PcdFlashFvMainBase);
+  if ((FwVolHeader->Revision != EFI_FVH_REVISION)||
+      (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||
+      (FwVolHeader->FvLength == ((UINT64) -1)) ||
+      ((FwVolHeader->HeaderLength & 0x01) != 0)
+      ) {
+    return EFI_NOT_FOUND;
+  }
+  //
+  // Verify the header checksum
+  //
+  HeaderLength  = (UINT16) (FwVolHeader->HeaderLength / 2);
+  Ptr           = (UINT16 *) FwVolHeader;
+  Checksum      = 0;
+  while (HeaderLength > 0) {
+    Checksum = Checksum +*Ptr;
+    Ptr++;
+    HeaderLength--;
+  }
+
+  if (Checksum != 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Peform the boot mode determination logic
+  If the box is closed, then
+    1. If it's first time to boot, it's boot with full config .
+    2. If the ChassisIntrution is selected, force to be a boot with full config
+    3. Otherwise it's boot with no change.
+
+  @param  PeiServices General purpose services available to every PEIM.
+
+  @param  BootMode The detected boot mode.
+
+  @retval EFI_SUCCESS if the boot mode could be set
+**/
+EFI_STATUS
+UpdateBootMode (
+  IN  EFI_PEI_SERVICES     **PeiServices,
+  OUT EFI_BOOT_MODE        *BootMode
+  )
+{
+  EFI_STATUS          Status;
+  EFI_BOOT_MODE       NewBootMode;
+  PEI_CAPSULE_PPI     *Capsule;
+  UINT32              RegValue;
+
+  NewBootMode = *BootMode;
+
+  //
+  // Read Sticky R/W Bits
+  //
+  RegValue = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW);
+  DEBUG ((EFI_D_ERROR, "RegValue = %08x\n", RegValue));
+
+  //
+  // Check if we need to boot in recovery mode
+  //
+  if ((RegValue & B_CFG_STICKY_RW_FORCE_RECOVERY) != 0) {
+    NewBootMode = BOOT_IN_RECOVERY_MODE;
+    DEBUG ((EFI_D_ERROR, "RECOVERY from sticky bit\n"));;
+
+    //
+    // Clear force recovery sticky bit
+    //
+    QNCAltPortWrite (
+      QUARK_SCSS_SOC_UNIT_SB_PORT_ID,
+      QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW,
+      RegValue &(~B_CFG_STICKY_RW_FORCE_RECOVERY)
+      );
+
+  } else if (ValidateFvHeader (BootMode) != EFI_SUCCESS) {
+    NewBootMode = BOOT_IN_RECOVERY_MODE;
+    DEBUG ((EFI_D_ERROR, "RECOVERY from corrupt FV\n"));;
+  } else if (QNCCheckS3AndClearState ()) {
+    //
+    // Determine if we're in capsule update mode
+    //
+    Status = PeiServicesLocatePpi (
+               &gPeiCapsulePpiGuid,
+               0,
+               NULL,
+               (VOID **)&Capsule
+               );
+    if (Status == EFI_SUCCESS) {
+      Status = Capsule->CheckCapsuleUpdate (PeiServices);
+      if (Status == EFI_SUCCESS) {
+        DEBUG ((EFI_D_INFO, "Boot mode Flash Update\n"));
+        NewBootMode = BOOT_ON_FLASH_UPDATE;
+      } else {
+        DEBUG ((EFI_D_INFO, "Boot mode S3 resume\n"));
+        NewBootMode = BOOT_ON_S3_RESUME;
+      }
+    } else {
+      DEBUG ((EFI_D_INFO, "Boot mode S3 resume\n"));
+      NewBootMode = BOOT_ON_S3_RESUME;
+    }
+  } else {
+    //
+    // Check if this is a power on reset
+    //
+    if (QNCCheckPowerOnResetAndClearState ()) {
+      DEBUG ((EFI_D_INFO, "Power On Reset\n"));
+    }
+    if (IsBootWithNoChange (PeiServices)) {
+      DEBUG ((EFI_D_INFO, "Boot with Minimum cfg\n"));
+      NewBootMode = BOOT_ASSUMING_NO_CONFIGURATION_CHANGES;
+    } else {
+      DEBUG ((EFI_D_INFO, "Boot with Full cfg\n"));
+      NewBootMode = BOOT_WITH_FULL_CONFIGURATION;
+    }
+  }
+
+  if (NewBootMode == BOOT_IN_RECOVERY_MODE) {
+    DEBUG ((EFI_D_INFO, "Boot mode recovery\n"));
+    Status = PeiServicesInstallPpi (&mPpiListRecoveryBootMode);
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  Status = PeiServicesSetBootMode (NewBootMode);
+  ASSERT_EFI_ERROR (Status);
+
+  *BootMode = NewBootMode;
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/CommonHeader.h b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/CommonHeader.h
new file mode 100644
index 0000000000..ce78bc1075
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/CommonHeader.h
@@ -0,0 +1,81 @@
+/** @file
+Common header file shared by all source files.
+
+This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+Copyright (c) 2013 - 2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+
+
+#include <PiPei.h>
+#include <IntelQNCPeim.h>
+#include "Ioh.h"
+#include <Platform.h>
+#include <PlatformBoards.h>
+
+#include <IndustryStandard/SmBus.h>
+#include <IndustryStandard/Pci22.h>
+
+#include <Guid/AcpiS3Context.h>
+#include <Ppi/AtaController.h>
+#include <Guid/Capsule.h>
+#include <Ppi/MasterBootMode.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/RecoveryDevice.h>
+#include <Guid/MemoryConfigData.h>
+#include <Guid/MemoryOverwriteControl.h>
+#include <Guid/CapsuleVendor.h>
+#include <Guid/QuarkCapsuleGuid.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Ppi/FvLoadFile.h>
+#include <Guid/SmramMemoryReserve.h>
+#include <Ppi/DeviceRecoveryModule.h>
+#include <Ppi/Capsule.h>
+#include <Ppi/Reset.h>
+#include <Ppi/Stall.h>
+#include <Ppi/BootInRecoveryMode.h>
+#include <Guid/FirmwareFileSystem2.h>
+#include <Ppi/MemoryDiscovered.h>
+#include <Ppi/RecoveryModule.h>
+#include <Ppi/Smbus2.h>
+#include <Ppi/FirmwareVolumeInfo.h>
+#include <Ppi/EndOfPeiPhase.h>
+
+#include <Library/DebugLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/IntelQNCLib.h>
+#include <Library/PcdLib.h>
+#include <Library/SmbusLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PrintLib.h>
+#include <Library/ResetSystemLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/MtrrLib.h>
+#include <Library/QNCAccessLib.h>
+#include <Library/PlatformHelperLib.h>
+#include <Library/PlatformPcieHelperLib.h>
+#include <Library/I2cLib.h>
+
+#include <Register/Cpuid.h>
+
+#include <Pcal9555.h>
+#include <QNCAccess.h>
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/Generic/Recovery.c b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/Generic/Recovery.c
new file mode 100644
index 0000000000..67299a68b7
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/Generic/Recovery.c
@@ -0,0 +1,467 @@
+/** @file
+Install Platform EFI_PEI_RECOVERY_MODULE_PPI and Implementation of
+EFI_PEI_LOAD_RECOVERY_CAPSULE service.
+
+Copyright (c) 2013-2019 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CommonHeader.h"
+#include "PlatformEarlyInit.h"
+
+#include <Ppi/BlockIo.h>
+
+//
+// Capsule Types supported in this platform module
+//
+#include <Guid/CapsuleOnFatFloppyDisk.h>
+#include <Guid/CapsuleOnFatIdeDisk.h>
+#include <Guid/CapsuleOnFatUsbDisk.h>
+#include <Guid/CapsuleOnDataCD.h>
+#include <Guid/QuarkCapsuleGuid.h>
+
+#include <Ppi/RecoveryModule.h>
+#include <Ppi/DeviceRecoveryModule.h>
+
+#include <Library/PeiServicesLib.h>
+
+//
+// Required Service
+//
+EFI_STATUS
+EFIAPI
+PlatformRecoveryModule (
+  IN EFI_PEI_SERVICES                       **PeiServices,
+  IN EFI_PEI_RECOVERY_MODULE_PPI          *This
+  );
+
+VOID
+AssertNoCapsulesError (
+  IN EFI_PEI_SERVICES **PeiServices
+  );
+
+VOID
+AssertMediaDeviceError (
+  IN EFI_PEI_SERVICES **PeiServices
+  );
+
+VOID
+ReportLoadCapsuleSuccess (
+  IN EFI_PEI_SERVICES **PeiServices
+  );
+
+VOID
+CheckIfMediaPresentOnBlockIoDevice (
+  IN EFI_PEI_SERVICES   **PeiServices,
+  IN OUT BOOLEAN        *MediaDeviceError,
+  IN OUT BOOLEAN        *MediaPresent
+  );
+
+//
+// Module globals
+//
+EFI_PEI_RECOVERY_MODULE_PPI  mRecoveryPpi = { PlatformRecoveryModule };
+
+EFI_PEI_PPI_DESCRIPTOR         mRecoveryPpiList = {
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEfiPeiRecoveryModulePpiGuid,
+  &mRecoveryPpi
+};
+
+EFI_STATUS
+EFIAPI
+PeimInitializeRecovery (
+  IN EFI_PEI_SERVICES     **PeiServices
+  )
+/*++
+
+Routine Description:
+
+  Provide the functionality of the Recovery Module.
+
+Arguments:
+
+  PeiServices  -  General purpose services available to every PEIM.
+
+Returns:
+
+  EFI_SUCCESS  -  If the interface could be successfully
+                  installed.
+
+--*/
+{
+  EFI_STATUS  Status;
+
+  Status = PeiServicesInstallPpi (&mRecoveryPpiList);
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PlatformRecoveryModule (
+  IN EFI_PEI_SERVICES                       **PeiServices,
+  IN EFI_PEI_RECOVERY_MODULE_PPI            *This
+  )
+/*++
+
+Routine Description:
+
+  Provide the functionality of the Platform Recovery Module.
+
+Arguments:
+
+  PeiServices  -  General purpose services available to every PEIM.
+  This         -  Pointer to EFI_PEI_RECOVERY_MODULE_PPI.
+
+Returns:
+
+  EFI_SUCCESS      -  If the interface could be successfully
+                      installed.
+  EFI_UNSUPPORTED  -  Not supported.
+
+--*/
+{
+  EFI_STATUS                            Status;
+  EFI_PEI_DEVICE_RECOVERY_MODULE_PPI    *DeviceRecoveryModule;
+  UINTN                                 NumberOfImageProviders;
+  BOOLEAN                               ProviderAvailable;
+  UINTN                                 NumberRecoveryCapsules;
+  UINTN                                 RecoveryCapsuleSize;
+  EFI_GUID                              DeviceId;
+  EFI_PHYSICAL_ADDRESS                  Address;
+  VOID                                  *Buffer;
+  EFI_CAPSULE_HEADER                    *CapsuleHeader;
+  EFI_PEI_HOB_POINTERS                  Hob;
+  BOOLEAN                               HobUpdate;
+  EFI_FIRMWARE_VOLUME_HEADER            *FvHeader;
+  UINTN                                 Index;
+  EFI_GUID                              mEfiCapsuleHeaderGuid = QUARK_CAPSULE_GUID;
+
+  Index = 0;
+
+  Status                  = EFI_SUCCESS;
+  HobUpdate               = FALSE;
+
+  ProviderAvailable       = TRUE;
+  NumberOfImageProviders  = 0;
+
+  DeviceRecoveryModule    = NULL;
+
+  DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Recovery Entry\n"));
+
+  //
+  // Search the platform for some recovery capsule if the DXE IPL
+  // discovered a recovery condition and has requested a load.
+  //
+  while (ProviderAvailable) {
+
+    Status = PeiServicesLocatePpi (
+              &gEfiPeiDeviceRecoveryModulePpiGuid,
+              Index,
+              NULL,
+              (VOID **)&DeviceRecoveryModule
+              );
+
+    if (!EFI_ERROR (Status)) {
+      DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Device Recovery PPI located\n"));
+      NumberOfImageProviders++;
+
+      Status = DeviceRecoveryModule->GetNumberRecoveryCapsules (
+                                      PeiServices,
+                                      DeviceRecoveryModule,
+                                      &NumberRecoveryCapsules
+                                      );
+
+      DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Number Of Recovery Capsules: %d\n", NumberRecoveryCapsules));
+
+      if (NumberRecoveryCapsules == 0) {
+        Index++;
+      } else {
+        break;
+      }
+    } else {
+      ProviderAvailable = FALSE;
+    }
+  }
+  //
+  // The number of recovery capsules is 0.
+  //
+  if (!ProviderAvailable) {
+    AssertNoCapsulesError (PeiServices);
+  }
+  //
+  // If there is an image provider, get the capsule ID
+  //
+  if (ProviderAvailable) {
+    RecoveryCapsuleSize = 0;
+    Status = DeviceRecoveryModule->GetRecoveryCapsuleInfo (
+                PeiServices,
+                DeviceRecoveryModule,
+                1,
+                &RecoveryCapsuleSize,
+                &DeviceId
+                );
+
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Recovery Capsule Size: %d\n", RecoveryCapsuleSize));
+
+    //
+    // Only support the 2 capsule types known
+    // Future enhancement is to rank-order the selection
+    //
+    if ((!CompareGuid (&DeviceId, &gPeiCapsuleOnFatIdeDiskGuid)) &&
+        (!CompareGuid (&DeviceId, &gPeiCapsuleOnDataCDGuid)) &&
+       (!CompareGuid (&DeviceId, &gPeiCapsuleOnFatUsbDiskGuid))
+        ) {
+      return EFI_UNSUPPORTED;
+    }
+
+    Buffer  = NULL;
+    Address = (UINTN) AllocatePages ((RecoveryCapsuleSize - 1) / 0x1000 + 1);
+    ASSERT (Address);
+
+    Buffer = (UINT8 *) (UINTN) Address;
+    Status = DeviceRecoveryModule->LoadRecoveryCapsule (
+                                     PeiServices,
+                                     DeviceRecoveryModule,
+                                     1,
+                                     Buffer
+                                     );
+
+    DEBUG ((EFI_D_INFO | EFI_D_LOAD, "LoadRecoveryCapsule Returns: %r\n", Status));
+
+    if (Status == EFI_DEVICE_ERROR) {
+      AssertMediaDeviceError (PeiServices);
+    }
+
+    if (EFI_ERROR (Status)) {
+      return Status;
+    } else {
+      ReportLoadCapsuleSuccess (PeiServices);
+    }
+
+    //
+    // Update FV Hob if found
+    //
+    Buffer  = (VOID *)((UINT8 *) Buffer);
+    Status      = PeiServicesGetHobList ((VOID **)&Hob.Raw);
+    while (!END_OF_HOB_LIST (Hob)) {
+      if (Hob.Header->HobType == EFI_HOB_TYPE_FV) {
+        DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Hob FV Length: %x\n", Hob.FirmwareVolume->Length));
+
+        if (Hob.FirmwareVolume->BaseAddress == (UINTN) PcdGet32 (PcdFlashFvMainBase)) {
+          HobUpdate = TRUE;
+          //
+          // This looks like the Hob we are interested in
+          //
+          DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Hob Updated\n"));
+          Hob.FirmwareVolume->BaseAddress = (UINTN) Buffer;
+          Hob.FirmwareVolume->Length      = RecoveryCapsuleSize;
+        }
+      }
+
+      Hob.Raw = GET_NEXT_HOB (Hob);
+    }
+    //
+    // Check if the top of the file is a firmware volume header
+    //
+    FvHeader      = (EFI_FIRMWARE_VOLUME_HEADER *) Buffer;
+    CapsuleHeader = (EFI_CAPSULE_HEADER *) Buffer;
+    if (FvHeader->Signature == EFI_FVH_SIGNATURE) {
+      //
+      // build FV Hob if it is not built before
+      //
+      if (!HobUpdate) {
+        DEBUG ((EFI_D_INFO | EFI_D_LOAD, "FV Hob is not found, Build FV Hob then..\n"));
+        BuildFvHob (
+          (UINTN) Buffer,
+          FvHeader->FvLength
+          );
+
+        DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Install FV Info PPI..\n"));
+
+        PeiServicesInstallFvInfoPpi (
+          NULL,
+          Buffer,
+          (UINT32) FvHeader->FvLength,
+          NULL,
+          NULL
+        );
+      }
+      //
+      // Point to the location immediately after the FV.
+      //
+      CapsuleHeader = (EFI_CAPSULE_HEADER *) ((UINT8 *) Buffer + FvHeader->FvLength);
+    }
+
+    //
+    // Check if pointer is still within the buffer
+    //
+    if ((UINTN) CapsuleHeader < (UINTN) ((UINT8 *) Buffer + RecoveryCapsuleSize)) {
+
+      //
+      // Check if it is a capsule
+      //
+      if (CompareGuid ((EFI_GUID *) CapsuleHeader, &mEfiCapsuleHeaderGuid)) {
+
+        //
+        // Set bootmode to capsule update so the capsule hob gets the right bootmode in the hob header.
+        //
+        Status = PeiServicesSetBootMode (BOOT_ON_FLASH_UPDATE);
+        if (EFI_ERROR (Status)) {
+          return Status;
+        }
+
+        //
+        // Build capsule hob
+        //
+        BuildCvHob ((EFI_PHYSICAL_ADDRESS)(UINTN)CapsuleHeader, (UINT64)CapsuleHeader->CapsuleImageSize);
+      }
+    }
+  }
+
+  DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Recovery Module Returning: %r\n", Status));
+  return Status;
+}
+
+/*
+  AssertNoCapsulesError:
+  There were no recovery capsules found.
+  Case 1: Report the error that no recovery block io device/media is readable and assert.
+  Case 2: Report the error that there is no media present on any recovery block io device and assert.
+  Case 3: There is media present on some recovery block io device,
+          but there is no recovery capsule on it.  Report the error and assert.
+*/
+VOID
+AssertNoCapsulesError (
+  IN EFI_PEI_SERVICES **PeiServices
+  )
+{
+  BOOLEAN MediaDeviceError;
+  BOOLEAN MediaPresent;
+
+  MediaDeviceError  = TRUE;
+  MediaPresent      = FALSE;
+
+  CheckIfMediaPresentOnBlockIoDevice (PeiServices, &MediaDeviceError, &MediaPresent);
+/*  if (MediaDeviceError) {
+    ReportStatusCode (
+      (EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED),
+      (EFI_PERIPHERAL_RECOVERY_MEDIA | EFI_P_EC_MEDIA_DEVICE_ERROR)
+      );
+
+  } else if (!MediaPresent) {
+    ReportStatusCode (
+      (EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED),
+      (EFI_PERIPHERAL_RECOVERY_MEDIA | EFI_P_EC_MEDIA_NOT_PRESENT)
+      );
+
+  } else {
+    ReportStatusCode (
+      (EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED),
+      (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEIM_EC_NO_RECOVERY_CAPSULE)
+      );
+  }*/
+  //
+  // Hang.
+  //
+  CpuDeadLoop();
+}
+
+#define MAX_BLOCK_IO_PPI  32
+
+/*
+  CheckIfMediaPresentOnBlockIoDevice:
+  Checks to see whether there was a media device error or to see if there is media present.
+*/
+VOID
+CheckIfMediaPresentOnBlockIoDevice (
+  IN EFI_PEI_SERVICES   **PeiServices,
+  IN OUT BOOLEAN        *MediaDeviceError,
+  IN OUT BOOLEAN        *MediaPresent
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           BlockIoPpiInstance;
+  EFI_PEI_RECOVERY_BLOCK_IO_PPI *BlockIoPpi;
+  UINTN                           NumberBlockDevices;
+  EFI_PEI_BLOCK_IO_MEDIA          Media;
+
+  *MediaDeviceError = TRUE;
+  *MediaPresent     = FALSE;
+
+  for (BlockIoPpiInstance = 0; BlockIoPpiInstance < MAX_BLOCK_IO_PPI; BlockIoPpiInstance++) {
+    Status = PeiServicesLocatePpi (
+              &gEfiPeiVirtualBlockIoPpiGuid,
+              BlockIoPpiInstance,
+              NULL,
+              (VOID **)&BlockIoPpi
+              );
+    if (EFI_ERROR (Status)) {
+      //
+      // Done with all Block Io Ppis
+      //
+      break;
+    }
+
+    Status = BlockIoPpi->GetNumberOfBlockDevices (
+                          PeiServices,
+                          BlockIoPpi,
+                          &NumberBlockDevices
+                          );
+    if (EFI_ERROR (Status) || (NumberBlockDevices == 0)) {
+      continue;
+    }
+    //
+    // Just retrieve the first block
+    //
+    Status = BlockIoPpi->GetBlockDeviceMediaInfo (
+                          PeiServices,
+                          BlockIoPpi,
+                          0,
+                          &Media
+                          );
+    if (!EFI_ERROR (Status)) {
+      *MediaDeviceError = FALSE;
+      if (Media.MediaPresent) {
+        *MediaPresent = TRUE;
+        break;
+      }
+    }
+  }
+}
+
+VOID
+AssertMediaDeviceError (
+  IN EFI_PEI_SERVICES **PeiServices
+  )
+{
+/*  ReportStatusCode (
+    (EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED),
+    (EFI_PERIPHERAL_RECOVERY_MEDIA | EFI_P_EC_MEDIA_DEVICE_ERROR)
+    );
+*/
+  CpuDeadLoop ();
+}
+
+VOID
+ReportLoadCapsuleSuccess (
+  IN EFI_PEI_SERVICES **PeiServices
+  )
+{
+  //
+  // EFI_SW_PEI_PC_CAPSULE_START: (from the status code spec):
+  // Loaded the recovery capsule.  About to hand off control to the capsule.
+  //
+/*  ReportStatusCode (
+    EFI_PROGRESS_CODE,
+    (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEIM_PC_CAPSULE_LOAD_SUCCESS)
+    );*/
+}
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MemoryCallback.c b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MemoryCallback.c
new file mode 100644
index 0000000000..cfdcba8e02
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MemoryCallback.c
@@ -0,0 +1,279 @@
+/** @file
+This file includes a memory call back function notified when MRC is done,
+following action is performed in this file,
+  1. ICH initialization after MRC.
+  2. SIO initialization.
+  3. Install ResetSystem and FinvFv PPI.
+  4. Set MTRR for PEI
+  5. Create FV HOB and Flash HOB
+
+Copyright (c) 2013 - 2019, Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "PlatformEarlyInit.h"
+
+extern EFI_PEI_PPI_DESCRIPTOR mPpiStall[];
+
+EFI_PEI_RESET_PPI mResetPpi = { PlatformResetSystem };
+
+EFI_PEI_PPI_DESCRIPTOR mPpiList[1] = {
+  {
+    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+    &gEfiPeiResetPpiGuid,
+    &mResetPpi
+  }
+};
+
+/**
+  This function reset the entire platform, including all processor and devices, and
+  reboots the system.
+
+  @param  PeiServices General purpose services available to every PEIM.
+
+  @retval EFI_SUCCESS if it completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+PlatformResetSystem (
+  IN CONST EFI_PEI_SERVICES          **PeiServices
+  )
+{
+  ResetCold();
+  return EFI_SUCCESS;
+}
+
+/**
+  This function provides a blocking stall for reset at least the given number of microseconds
+  stipulated in the final argument.
+
+  @param  PeiServices General purpose services available to every PEIM.
+
+  @param  this Pointer to the local data for the interface.
+
+  @param  Microseconds number of microseconds for which to stall.
+
+  @retval EFI_SUCCESS the function provided at least the required stall.
+**/
+EFI_STATUS
+EFIAPI
+Stall (
+  IN CONST EFI_PEI_SERVICES   **PeiServices,
+  IN CONST EFI_PEI_STALL_PPI  *This,
+  IN UINTN                    Microseconds
+  )
+{
+  MicroSecondDelay (Microseconds);
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This function will be called when MRC is done.
+
+  @param  PeiServices General purpose services available to every PEIM.
+
+  @param  NotifyDescriptor Information about the notify event..
+
+  @param  Ppi The notify context.
+
+  @retval EFI_SUCCESS If the function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+MemoryDiscoveredPpiNotifyCallback (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+  )
+{
+  EFI_STATUS                            Status;
+  EFI_BOOT_MODE                         BootMode;
+  UINT64                                MemoryLength;
+  EFI_SMRAM_DESCRIPTOR                  *SmramDescriptor;
+  UINTN                                 NumSmramRegions;
+  UINT32                                RmuMainBaseAddress;
+  UINT32                                RegData32;
+  UINT8                                 CpuAddressWidth;
+  UINT32                                RegEax;
+  MTRR_SETTINGS                         MtrrSettings;
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI       *VariableServices;
+  UINT8                                 MorControl;
+  UINTN                                 DataSize;
+
+  DEBUG ((EFI_D_INFO, "Platform PEIM Memory Callback\n"));
+
+  NumSmramRegions = 0;
+  SmramDescriptor = NULL;
+  RmuMainBaseAddress = 0;
+
+  PERF_START (NULL, "SetCache", NULL, 0);
+
+  InfoPostInstallMemory (&RmuMainBaseAddress, &SmramDescriptor, &NumSmramRegions);
+  ASSERT (SmramDescriptor != NULL);
+  ASSERT (RmuMainBaseAddress != 0);
+
+  MemoryLength = ((UINT64) RmuMainBaseAddress) + 0x10000;
+
+  Status = PeiServicesGetBootMode (&BootMode);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Get current MTRR settings
+  //
+  MtrrGetAllMtrrs (&MtrrSettings);
+
+  //
+  // Set all DRAM cachability to CacheWriteBack
+  //
+  Status = MtrrSetMemoryAttributeInMtrrSettings (&MtrrSettings, 0, MemoryLength, CacheWriteBack);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // RTC:28208 - System hang/crash when entering probe mode(ITP) when relocating SMBASE
+  //             Workaround to make default SMRAM UnCachable
+  //
+  Status = MtrrSetMemoryAttributeInMtrrSettings (&MtrrSettings, 0x30000, SIZE_64KB, CacheUncacheable);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Set new MTRR settings
+  //
+  MtrrSetAllMtrrs (&MtrrSettings);
+
+  PERF_END (NULL, "SetCache", NULL, 0);
+
+  //
+  // Get necessary PPI
+  //
+  Status = PeiServicesLocatePpi (
+             &gEfiPeiReadOnlyVariable2PpiGuid,           // GUID
+             0,                                          // INSTANCE
+             NULL,                                       // EFI_PEI_PPI_DESCRIPTOR
+             (VOID **)&VariableServices                  // PPI
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Detect MOR request by the OS.
+  //
+  MorControl = 0;
+  DataSize = sizeof (MorControl);
+  Status = VariableServices->GetVariable (
+                               VariableServices,
+                               MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
+                               &gEfiMemoryOverwriteControlDataGuid,
+                               NULL,
+                               &DataSize,
+                               &MorControl
+                               );
+  //
+  // If OS requested a memory overwrite perform it now for Embedded SRAM
+  //
+  if (MOR_CLEAR_MEMORY_VALUE (MorControl)) {
+    DEBUG ((EFI_D_INFO, "Clear Embedded SRAM per MOR request.\n"));
+    if (PcdGet32 (PcdESramMemorySize) > 0) {
+      if (PcdGet32 (PcdEsramStage1Base) == 0) {
+        //
+        // ZeroMem() generates an ASSERT() if Buffer parameter is NULL.
+        // Clear byte at 0 and start clear operation at address 1.
+        //
+        *(UINT8 *)(0) = 0;
+        ZeroMem ((VOID *)1, (UINTN)PcdGet32 (PcdESramMemorySize) - 1);
+      } else {
+        ZeroMem (
+          (VOID *)(UINTN)PcdGet32 (PcdEsramStage1Base),
+          (UINTN)PcdGet32 (PcdESramMemorySize)
+          );
+      }
+    }
+  }
+
+  //
+  // Install PeiReset for PeiResetSystem service
+  //
+  Status = PeiServicesInstallPpi (&mPpiList[0]);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Do QNC initialization after MRC
+  //
+  PeiQNCPostMemInit ();
+
+  Status = PeiServicesInstallPpi (&mPpiStall[0]);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Set E000/F000 Routing
+  //
+  RegData32 = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);
+  RegData32 |= (BIT2|BIT1);
+  QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, RegData32);
+
+  if (BootMode == BOOT_IN_RECOVERY_MODE) {
+    // Do nothing here. A generic RecoveryModule will handle it.
+  } else if (BootMode == BOOT_ON_S3_RESUME) {
+    return EFI_SUCCESS;
+  } else {
+    PeiServicesInstallFvInfoPpi (
+      NULL,
+      (VOID *) (UINTN) PcdGet32 (PcdFlashFvMainBase),
+      PcdGet32 (PcdFlashFvMainSize),
+      NULL,
+      NULL
+      );
+
+    //
+    // Publish the FVMAIN FV so the DXE Phase can dispatch drivers from this FV
+    // and produce Load File Protocols for UEFI Applications in this FV.
+    //
+    BuildFvHob (
+      PcdGet32 (PcdFlashFvMainBase),
+      PcdGet32 (PcdFlashFvMainSize)
+      );
+
+    //
+    // Publish the Payload FV so the DXE Phase can dispatch drivers from this FV
+    // and produce Load File Protocols for UEFI Applications in this FV.
+    //
+    BuildFvHob (
+      PcdGet32 (PcdFlashFvPayloadBase),
+      PcdGet32 (PcdFlashFvPayloadSize)
+      );
+  }
+
+  //
+  // Build flash HOB, it's going to be used by GCD and E820 building
+  // Map full SPI flash decode range (regardless of smaller SPI flash parts installed)
+  //
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_FIRMWARE_DEVICE,
+    (EFI_RESOURCE_ATTRIBUTE_PRESENT    |
+    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+    (SIZE_4GB - SIZE_8MB),
+    SIZE_8MB
+    );
+
+  //
+  // Create a CPU hand-off information
+  //
+  CpuAddressWidth = 32;
+  AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
+  if (RegEax >= CPUID_VIR_PHY_ADDRESS_SIZE) {
+    AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &RegEax, NULL, NULL, NULL);
+    CpuAddressWidth = (UINT8) (RegEax & 0xFF);
+  }
+  DEBUG ((EFI_D_INFO, "CpuAddressWidth: %d\n", CpuAddressWidth));
+
+  BuildCpuHob (CpuAddressWidth, 16);
+
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.c b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.c
new file mode 100644
index 0000000000..fcb5c79aaf
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.c
@@ -0,0 +1,1565 @@
+/** @file
+Framework PEIM to initialize memory on a Quark Memory Controller.
+
+Copyright (c) 2013 - 2016, Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CommonHeader.h"
+#include "MrcWrapper.h"
+#include <Ioh.h>
+#include "Platform.h"
+
+#include <Library/PlatformHelperLib.h>
+
+//
+// ------------------------ TSEG Base
+//
+// ------------------------ RESERVED_CPU_S3_SAVE_OFFSET
+// CPU S3 data
+// ------------------------ RESERVED_ACPI_S3_RANGE_OFFSET
+// S3 Memory base structure
+// ------------------------ TSEG + 1 page
+
+#define RESERVED_CPU_S3_SAVE_OFFSET (RESERVED_ACPI_S3_RANGE_OFFSET - sizeof (SMM_S3_RESUME_STATE))
+
+// Strap configuration register specifying DDR setup
+#define QUARK_SCSS_REG_STPDDRCFG   0x00
+
+// Macro counting array elements
+#define COUNT(a)                 (sizeof(a)/sizeof(*a))
+
+
+EFI_MEMORY_TYPE_INFORMATION mDefaultQncMemoryTypeInformation[] = {
+  { EfiReservedMemoryType,  EDKII_RESERVED_SIZE_PAGES },     // BIOS Reserved
+  { EfiACPIMemoryNVS,       ACPI_NVS_SIZE_PAGES },    // S3, SMM, etc
+  { EfiRuntimeServicesData, RUNTIME_SERVICES_DATA_SIZE_PAGES },
+  { EfiRuntimeServicesCode, RUNTIME_SERVICES_CODE_SIZE_PAGES },
+  { EfiACPIReclaimMemory,   ACPI_RECLAIM_SIZE_PAGES },     // ACPI ASL
+  { EfiMaxMemoryType,       0 }
+};
+
+/**
+  Configure Uart mmio base for MRC serial log purpose
+
+  @param  MrcData  - MRC configuration data updated
+
+**/
+VOID
+MrcUartConfig(
+  MRC_PARAMS *MrcData
+  )
+{
+  UINT8    UartIdx;
+  UINT32   RegData32;
+  UINT8    IohUartBus;
+  UINT8    IohUartDev;
+
+  UartIdx    = PcdGet8(PcdIohUartFunctionNumber);
+  IohUartBus = PcdGet8(PcdIohUartBusNumber);
+  IohUartDev = PcdGet8(PcdIohUartDevNumber);
+
+  RegData32 = PciRead32 (PCI_LIB_ADDRESS(IohUartBus,  IohUartDev, UartIdx, PCI_BASE_ADDRESSREG_OFFSET));
+  MrcData->uart_mmio_base = RegData32 & 0xFFFFFFF0;
+}
+
+/**
+  Configure MRC from memory controller fuse settings.
+
+  @param  MrcData      - MRC configuration data to be updated.
+
+  @return EFI_SUCCESS    MRC Config parameters updated from platform data.
+**/
+EFI_STATUS
+MrcConfigureFromMcFuses (
+  OUT MRC_PARAMS                          *MrcData
+  )
+{
+  UINT32                            McFuseStat;
+
+  McFuseStat = QNCPortRead (
+                 QUARK_NC_MEMORY_CONTROLLER_SB_PORT_ID,
+                 QUARK_NC_MEMORY_CONTROLLER_REG_DFUSESTAT
+                 );
+
+  DEBUG ((EFI_D_INFO, "MRC McFuseStat 0x%08x\n", McFuseStat));
+
+  if ((McFuseStat & B_DFUSESTAT_ECC_DIS) != 0) {
+    DEBUG ((EFI_D_INFO, "MRC Fuse : fus_dun_ecc_dis.\n"));
+    MrcData->ecc_enables = 0;
+  } else {
+    MrcData->ecc_enables = 1;
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  Configure MRC from platform info hob.
+
+  @param  MrcData      - MRC configuration data to be updated.
+
+  @return EFI_SUCCESS    MRC Config parameters updated from hob.
+  @return EFI_NOT_FOUND  Platform Info or MRC Config parameters not found.
+  @return EFI_INVALID_PARAMETER  Wrong params in hob.
+**/
+EFI_STATUS
+MrcConfigureFromInfoHob (
+  OUT MRC_PARAMS  *MrcData
+  )
+{
+  PDAT_MRC_ITEM  *ItemData;
+
+  ItemData = (PDAT_MRC_ITEM *)PcdGetPtr (PcdMrcParameters);
+
+  MrcData->channel_enables     = ItemData->ChanMask;
+  MrcData->channel_width       = ItemData->ChanWidth;
+  MrcData->address_mode        = ItemData->AddrMode;
+  // Enable scrambling if requested.
+  MrcData->scrambling_enables  = (ItemData->Flags & PDAT_MRC_FLAG_SCRAMBLE_EN) != 0;
+  MrcData->ddr_type            = ItemData->DramType;
+  MrcData->dram_width          = ItemData->DramWidth;
+  MrcData->ddr_speed           = ItemData->DramSpeed;
+  // Enable ECC if requested.
+  MrcData->rank_enables        = ItemData->RankMask;
+  MrcData->params.DENSITY      = ItemData->DramDensity;
+  MrcData->params.tCL          = ItemData->tCL;
+  MrcData->params.tRAS         = ItemData->tRAS;
+  MrcData->params.tWTR         = ItemData->tWTR;
+  MrcData->params.tRRD         = ItemData->tRRD;
+  MrcData->params.tFAW         = ItemData->tFAW;
+
+  MrcData->refresh_rate        = ItemData->SrInt;
+  MrcData->sr_temp_range       = ItemData->SrTemp;
+  MrcData->ron_value           = ItemData->DramRonVal;
+  MrcData->rtt_nom_value       = ItemData->DramRttNomVal;
+  MrcData->rd_odt_value        = ItemData->SocRdOdtVal;
+
+  DEBUG ((EFI_D_INFO, "MRC dram_width %d\n",  MrcData->dram_width));
+  DEBUG ((EFI_D_INFO, "MRC rank_enables %d\n",MrcData->rank_enables));
+  DEBUG ((EFI_D_INFO, "MRC ddr_speed %d\n",   MrcData->ddr_speed));
+  DEBUG ((EFI_D_INFO, "MRC flags: %s\n",
+    (MrcData->scrambling_enables) ? L"SCRAMBLE_EN" : L""
+    ));
+
+  DEBUG ((EFI_D_INFO, "MRC density=%d tCL=%d tRAS=%d tWTR=%d tRRD=%d tFAW=%d\n",
+    MrcData->params.DENSITY,
+    MrcData->params.tCL,
+    MrcData->params.tRAS,
+    MrcData->params.tWTR,
+    MrcData->params.tRRD,
+    MrcData->params.tFAW
+    ));
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Configure ECC scrub
+
+  @param MrcData - MRC configuration
+
+**/
+VOID
+EccScrubSetup(
+  const MRC_PARAMS *MrcData
+  )
+{
+  UINT32 BgnAdr = 0;
+  UINT32 EndAdr = MrcData->mem_size;
+  UINT32 BlkSize = PcdGet8(PcdEccScrubBlkSize) & SCRUB_CFG_BLOCKSIZE_MASK;
+  UINT32 Interval = PcdGet8(PcdEccScrubInterval) & SCRUB_CFG_INTERVAL_MASK;
+
+  if( MrcData->ecc_enables == 0 || MrcData->boot_mode == bmS3 || Interval == 0) {
+    // No scrub configuration needed if ECC not enabled
+    // On S3 resume reconfiguration is done as part of resume
+    // script, see SNCS3Save.c ==> SaveRuntimeScriptTable()
+    // Also if PCD disables scrub, then we do nothing.
+    return;
+  }
+
+  QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_ECC_SCRUB_END_MEM_REG, EndAdr);
+  QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_ECC_SCRUB_START_MEM_REG, BgnAdr);
+  QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_ECC_SCRUB_NEXT_READ_REG, BgnAdr);
+  QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_ECC_SCRUB_CONFIG_REG,
+    Interval << SCRUB_CFG_INTERVAL_SHIFT |
+    BlkSize << SCRUB_CFG_BLOCKSIZE_SHIFT);
+
+  McD0PciCfg32 (QNC_ACCESS_PORT_MCR) = SCRUB_RESUME_MSG();
+}
+
+/** Post InstallS3Memory / InstallEfiMemory tasks given MrcData context.
+
+  @param[in]       MrcData  MRC configuration.
+  @param[in]       IsS3     TRUE if after InstallS3Memory.
+
+**/
+VOID
+PostInstallMemory (
+  IN MRC_PARAMS                           *MrcData,
+  IN BOOLEAN                              IsS3
+  )
+{
+  UINT32                            RmuMainDestBaseAddress;
+  UINT32                            *RmuMainSrcBaseAddress;
+  UINTN                             RmuMainSize;
+  EFI_STATUS                        Status;
+
+  //
+  // Setup ECC policy (All boot modes).
+  //
+  QNCPolicyDblEccBitErr (V_WDT_CONTROL_DBL_ECC_BIT_ERR_WARM);
+
+  //
+  // Find the 64KB of memory for Rmu Main at the top of available memory.
+  //
+  InfoPostInstallMemory (&RmuMainDestBaseAddress, NULL, NULL);
+  DEBUG ((EFI_D_INFO, "RmuMain Base Address : 0x%x\n", RmuMainDestBaseAddress));
+
+  //
+  // Relocate RmuMain.
+  //
+  if (IsS3) {
+    QNCSendOpcodeDramReady (RmuMainDestBaseAddress);
+  } else {
+    Status = PlatformFindFvFileRawDataSection (NULL, PcdGetPtr(PcdQuarkMicrocodeFile), (VOID **) &RmuMainSrcBaseAddress, &RmuMainSize);
+    ASSERT_EFI_ERROR (Status);
+    if (!EFI_ERROR (Status)) {
+      DEBUG ((EFI_D_INFO, "Found Microcode ADDR:SIZE 0x%08x:0x%04x\n", (UINTN) RmuMainSrcBaseAddress, RmuMainSize));
+    }
+
+    RmuMainRelocation (RmuMainDestBaseAddress, (UINT32) RmuMainSrcBaseAddress, RmuMainSize);
+    QNCSendOpcodeDramReady (RmuMainDestBaseAddress);
+    EccScrubSetup (MrcData);
+  }
+}
+
+/**
+
+  Do memory initialisation for QNC DDR3 SDRAM Controller
+
+  @param  FfsHeader    Not used.
+  @param  PeiServices  General purpose services available to every PEIM.
+
+  @return EFI_SUCCESS  Memory initialisation completed successfully.
+          All other error conditions encountered result in an ASSERT.
+
+**/
+EFI_STATUS
+MemoryInit (
+  IN EFI_PEI_SERVICES          **PeiServices
+  )
+{
+  MRC_PARAMS                                 MrcData;
+  EFI_BOOT_MODE                               BootMode;
+  EFI_STATUS                                  Status;
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI             *VariableServices;
+  EFI_STATUS_CODE_VALUE                       ErrorCodeValue;
+  PEI_QNC_MEMORY_INIT_PPI                     *QncMemoryInitPpi;
+  UINT16                                      PmswAdr;
+
+  ErrorCodeValue  = 0;
+
+  //
+  // It is critical that both of these data structures are initialized to 0.
+  // This PEIM knows the number of DIMMs in the system and works with that
+  // information.  The MCH PEIM that consumes these data structures does not
+  // know the number of DIMMs so it expects the entire structure to be
+  // properly initialized.  By initializing these to zero, all flags indicating
+  // that the SPD is present or the row should be configured are set to false.
+  //
+  ZeroMem (&MrcData, sizeof(MrcData));
+
+  //
+  // Get necessary PPI
+  //
+  Status = PeiServicesLocatePpi (
+             &gEfiPeiReadOnlyVariable2PpiGuid,           // GUID
+             0,                                          // INSTANCE
+             NULL,                                       // EFI_PEI_PPI_DESCRIPTOR
+             (VOID **)&VariableServices                  // PPI
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Determine boot mode
+  //
+  Status = PeiServicesGetBootMode (&BootMode);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Initialize Error type for reporting status code
+  //
+  switch (BootMode) {
+  case BOOT_ON_FLASH_UPDATE:
+    ErrorCodeValue = EFI_COMPUTING_UNIT_MEMORY + EFI_CU_MEMORY_EC_UPDATE_FAIL;
+    break;
+  case BOOT_ON_S3_RESUME:
+    ErrorCodeValue = EFI_COMPUTING_UNIT_MEMORY + EFI_CU_MEMORY_EC_S3_RESUME_FAIL;
+    break;
+  default:
+    ErrorCodeValue = EFI_COMPUTING_UNIT_MEMORY;
+    break;
+  }
+
+  //
+  // Specify MRC boot mode
+  //
+  switch (BootMode) {
+  case BOOT_ON_S3_RESUME:
+  case BOOT_ON_FLASH_UPDATE:
+    MrcData.boot_mode = bmS3;
+    break;
+  case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
+    MrcData.boot_mode = bmFast;
+    break;
+  default:
+    MrcData.boot_mode = bmCold;
+    break;
+  }
+
+  //
+  // Configure MRC input parameters.
+  //
+  Status = MrcConfigureFromMcFuses (&MrcData);
+  ASSERT_EFI_ERROR (Status);
+  Status = MrcConfigureFromInfoHob (&MrcData);
+  ASSERT_EFI_ERROR (Status);
+  MrcUartConfig(&MrcData);
+
+  if (BootMode == BOOT_IN_RECOVERY_MODE) {
+    //
+    // Always do bmCold on recovery.
+    //
+    DEBUG ((DEBUG_INFO, "MemoryInit:Force bmCold on Recovery\n"));
+    MrcData.boot_mode = bmCold;
+  } else {
+
+    //
+    // Load Memory configuration data saved in previous boot from variable
+    //
+    Status = LoadConfig (
+               PeiServices,
+               VariableServices,
+               &MrcData
+               );
+
+    if (EFI_ERROR (Status)) {
+
+      switch (BootMode) {
+      case BOOT_ON_S3_RESUME:
+      case BOOT_ON_FLASH_UPDATE:
+        REPORT_STATUS_CODE (
+          EFI_ERROR_CODE + EFI_ERROR_UNRECOVERED,
+          ErrorCodeValue
+        );
+        PeiServicesResetSystem ();
+        break;
+
+      default:
+        MrcData.boot_mode = bmCold;
+        break;
+      }
+    }
+  }
+
+  //
+  // Locate Memory Reference Code PPI
+  //
+  Status = PeiServicesLocatePpi (
+             &gQNCMemoryInitPpiGuid,        // GUID
+             0,                             // INSTANCE
+             NULL,                          // EFI_PEI_PPI_DESCRIPTOR
+             (VOID **)&QncMemoryInitPpi     // PPI
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  PmswAdr = (UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_PMSW;
+  if( IoRead32 (PmswAdr) & B_QNC_GPE0BLK_PMSW_DRAM_INIT) {
+    // MRC did not complete last execution, force cold boot path
+    MrcData.boot_mode = bmCold;
+  }
+
+  // Mark MRC pending
+  IoOr32 (PmswAdr, (UINT32)B_QNC_GPE0BLK_PMSW_DRAM_INIT);
+
+  //
+  // Call Memory Reference Code's Routines
+  //
+  QncMemoryInitPpi->MrcStart (&MrcData);
+
+  // Mark MRC completed
+  IoAnd32 (PmswAdr, ~(UINT32)B_QNC_GPE0BLK_PMSW_DRAM_INIT);
+
+
+  //
+  // Note emulation platform has to read actual memory size
+  // MrcData.mem_size from PcdGet32 (PcdMemorySize);
+
+  if (BootMode == BOOT_ON_S3_RESUME) {
+
+    DEBUG ((EFI_D_INFO, "Following BOOT_ON_S3_RESUME boot path.\n"));
+
+    Status = InstallS3Memory (PeiServices, VariableServices, MrcData.mem_size);
+    if (EFI_ERROR (Status)) {
+      REPORT_STATUS_CODE (
+        EFI_ERROR_CODE + EFI_ERROR_UNRECOVERED,
+        ErrorCodeValue
+      );
+      PeiServicesResetSystem ();
+    }
+    PostInstallMemory (&MrcData, TRUE);
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Assign physical memory to PEI and DXE
+  //
+  DEBUG ((EFI_D_INFO, "InstallEfiMemory.\n"));
+
+  Status = InstallEfiMemory (
+             PeiServices,
+             VariableServices,
+             BootMode,
+             MrcData.mem_size
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  PostInstallMemory (&MrcData, FALSE);
+
+  //
+  // Save current configuration into Hob and will save into Variable later in DXE
+  //
+  DEBUG ((EFI_D_INFO, "SaveConfig.\n"));
+  Status = SaveConfig (
+             &MrcData
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((EFI_D_INFO, "MemoryInit Complete.\n"));
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  This function saves a config to a HOB.
+
+  @param  RowInfo         The MCH row configuration information.
+  @param  TimingData      Timing data to be saved.
+  @param  RowConfArray    Row configuration information for each row in the system.
+  @param  SpdData         SPD info read for each DIMM slot in the system.
+
+  @return EFI_SUCCESS:    The function completed successfully.
+
+**/
+EFI_STATUS
+SaveConfig (
+  IN MRC_PARAMS *MrcData
+  )
+{
+  //
+  // Build HOB data for Memory Config
+  // HOB data size (stored in variable) is required to be multiple of 8 bytes
+  //
+  BuildGuidDataHob (
+    &gEfiMemoryConfigDataGuid,
+    (VOID *) &MrcData->timings,
+    ((sizeof (MrcData->timings) + 0x7) & (~0x7))
+    );
+
+  DEBUG ((EFI_D_INFO, "IIO IoApicBase  = %x IoApicLimit=%x\n", IOAPIC_BASE, (IOAPIC_BASE + IOAPIC_SIZE - 1)));
+  DEBUG ((EFI_D_INFO, "IIO RcbaAddress = %x\n", (UINT32)PcdGet64 (PcdRcbaMmioBaseAddress)));
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Load a configuration stored in a variable.
+
+  @param  TimingData          Timing data to be loaded from NVRAM.
+  @param  RowConfArray        Row configuration information for each row in the system.
+
+  @return EFI_SUCCESS         The function completed successfully.
+          Other               Could not read variable.
+
+**/
+EFI_STATUS
+LoadConfig (
+  IN      EFI_PEI_SERVICES                        **PeiServices,
+  IN      EFI_PEI_READ_ONLY_VARIABLE2_PPI         *VariableServices,
+  IN OUT  MRC_PARAMS                              *MrcData
+  )
+{
+  EFI_STATUS                            Status;
+  UINTN                                 BufferSize;
+  PLATFORM_VARIABLE_MEMORY_CONFIG_DATA  VarData;
+
+  BufferSize = ((sizeof (VarData.timings) + 0x7) & (~0x7));  // HOB data size (stored in variable) is required to be multiple of 8bytes
+
+  Status = VariableServices->GetVariable (
+                               VariableServices,
+                               EFI_MEMORY_CONFIG_DATA_NAME,
+                               &gEfiMemoryConfigDataGuid,
+                               NULL,
+                               &BufferSize,
+                               &VarData.timings
+                               );
+  if (!EFI_ERROR (Status)) {
+    CopyMem (&MrcData->timings, &VarData.timings, sizeof(MrcData->timings));
+  }
+  return Status;
+}
+
+/**
+
+  This function installs memory.
+
+  @param   PeiServices    PEI Services table.
+  @param   BootMode       The specific boot path that is being followed
+  @param   Mch            Pointer to the DualChannelDdrMemoryInit PPI
+  @param   RowConfArray   Row configuration information for each row in the system.
+
+  @return  EFI_SUCCESS            The function completed successfully.
+           EFI_INVALID_PARAMETER  One of the input parameters was invalid.
+           EFI_ABORTED            An error occurred.
+
+**/
+EFI_STATUS
+InstallEfiMemory (
+  IN      EFI_PEI_SERVICES                           **PeiServices,
+  IN      EFI_PEI_READ_ONLY_VARIABLE2_PPI            *VariableServices,
+  IN      EFI_BOOT_MODE                              BootMode,
+  IN      UINT32                                     TotalMemorySize
+  )
+{
+  EFI_PHYSICAL_ADDRESS                  PeiMemoryBaseAddress;
+  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK        *SmramHobDescriptorBlock;
+  EFI_STATUS                            Status;
+  EFI_PEI_HOB_POINTERS                  Hob;
+  PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE MemoryMap[MAX_RANGES];
+  UINT8                                 Index;
+  UINT8                                 NumRanges;
+  UINT8                                 SmramIndex;
+  UINT8                                 SmramRanges;
+  UINT64                                PeiMemoryLength;
+  UINTN                                 BufferSize;
+  UINTN                                 PeiMemoryIndex;
+  EFI_RESOURCE_ATTRIBUTE_TYPE           Attribute;
+  EFI_PHYSICAL_ADDRESS                  BadMemoryAddress;
+  EFI_SMRAM_DESCRIPTOR                  DescriptorAcpiVariable;
+  VOID                                  *CapsuleBuffer;
+  UINTN                                 CapsuleBufferLength;
+  PEI_CAPSULE_PPI                       *Capsule;
+  VOID                                  *LargeMemRangeBuf;
+  UINTN                                 LargeMemRangeBufLen;
+  UINT8                                 MorControl;
+  UINTN                                 DataSize;
+
+  //
+  // Test the memory from 1M->TOM
+  //
+  if (BootMode != BOOT_ON_FLASH_UPDATE) {
+    Status = BaseMemoryTest (
+              PeiServices,
+              0x100000,
+              (TotalMemorySize - 0x100000),
+              Quick,
+              &BadMemoryAddress
+              );
+  ASSERT_EFI_ERROR (Status);
+  }
+
+
+  //
+  // Get the Memory Map
+  //
+  NumRanges = MAX_RANGES;
+
+  ZeroMem (MemoryMap, sizeof (PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE) * NumRanges);
+
+  Status = GetMemoryMap (
+             PeiServices,
+             TotalMemorySize,
+             (PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE *) MemoryMap,
+             &NumRanges
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Find the highest memory range in processor native address space to give to
+  // PEI. Then take the top.
+  //
+  PeiMemoryBaseAddress = 0;
+
+  //
+  // Query the platform for the minimum memory size
+  //
+
+  Status = GetPlatformMemorySize (
+             PeiServices,
+             BootMode,
+             &PeiMemoryLength
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Detect MOR request by the OS.
+  //
+  MorControl = 0;
+  DataSize = sizeof (MorControl);
+  Status = VariableServices->GetVariable (
+                               VariableServices,
+                               MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
+                               &gEfiMemoryOverwriteControlDataGuid,
+                               NULL,
+                               &DataSize,
+                               &MorControl
+                               );
+
+  PeiMemoryIndex = 0;
+
+  for (Index = 0; Index < NumRanges; Index++)
+  {
+    DEBUG ((EFI_D_INFO, "Found 0x%x bytes at ", MemoryMap[Index].RangeLength));
+    DEBUG ((EFI_D_INFO, "0x%x.\n", MemoryMap[Index].PhysicalAddress));
+
+    //
+    // If OS requested a memory overwrite perform it now.  Only do it for memory
+    // used by the OS.
+    //
+    if (MOR_CLEAR_MEMORY_VALUE (MorControl) && MemoryMap[Index].Type == DualChannelDdrMainMemory) {
+      DEBUG ((EFI_D_INFO, "Clear memory per MOR request.\n"));
+      if ((UINTN)MemoryMap[Index].RangeLength > 0) {
+        if ((UINTN)MemoryMap[Index].PhysicalAddress == 0) {
+          //
+          // ZeroMem() generates an ASSERT() if Buffer parameter is NULL.
+          // Clear byte at 0 and start clear operation at address 1.
+          //
+          *(UINT8 *)(0) = 0;
+          ZeroMem ((VOID *)1, (UINTN)MemoryMap[Index].RangeLength - 1);
+        } else {
+          ZeroMem (
+            (VOID *)(UINTN)MemoryMap[Index].PhysicalAddress,
+            (UINTN)MemoryMap[Index].RangeLength
+            );
+        }
+      }
+    }
+
+    if ((MemoryMap[Index].Type == DualChannelDdrMainMemory) &&
+        (MemoryMap[Index].PhysicalAddress + MemoryMap[Index].RangeLength < MAX_ADDRESS) &&
+        (MemoryMap[Index].PhysicalAddress >= PeiMemoryBaseAddress) &&
+        (MemoryMap[Index].RangeLength >= PeiMemoryLength)) {
+      PeiMemoryBaseAddress = MemoryMap[Index].PhysicalAddress +
+                             MemoryMap[Index].RangeLength -
+                             PeiMemoryLength;
+      PeiMemoryIndex = Index;
+    }
+  }
+
+  //
+  // Find the largest memory range excluding that given to PEI.
+  //
+  LargeMemRangeBuf = NULL;
+  LargeMemRangeBufLen = 0;
+  for (Index = 0; Index < NumRanges; Index++) {
+    if ((MemoryMap[Index].Type == DualChannelDdrMainMemory) &&
+        (MemoryMap[Index].PhysicalAddress + MemoryMap[Index].RangeLength < MAX_ADDRESS)) {
+          if (Index != PeiMemoryIndex) {
+            if (MemoryMap[Index].RangeLength > LargeMemRangeBufLen) {
+              LargeMemRangeBuf = (VOID *) ((UINTN) MemoryMap[Index].PhysicalAddress);
+              LargeMemRangeBufLen = (UINTN) MemoryMap[Index].RangeLength;
+            }
+          } else {
+            if ((MemoryMap[Index].RangeLength - PeiMemoryLength) >= LargeMemRangeBufLen) {
+              LargeMemRangeBuf = (VOID *) ((UINTN) MemoryMap[Index].PhysicalAddress);
+              LargeMemRangeBufLen = (UINTN) (MemoryMap[Index].RangeLength - PeiMemoryLength);
+            }
+          }
+    }
+  }
+
+  Capsule             = NULL;
+  CapsuleBuffer       = NULL;
+  CapsuleBufferLength = 0;
+  if (BootMode == BOOT_ON_FLASH_UPDATE) {
+    Status = PeiServicesLocatePpi (
+               &gPeiCapsulePpiGuid,  // GUID
+               0,                    // INSTANCE
+               NULL,                 // EFI_PEI_PPI_DESCRIPTOR
+               (VOID **)&Capsule     // PPI
+               );
+    ASSERT_EFI_ERROR (Status);
+
+    if (Status == EFI_SUCCESS) {
+      CapsuleBuffer = LargeMemRangeBuf;
+      CapsuleBufferLength = LargeMemRangeBufLen;
+
+      //
+      // Call the Capsule PPI Coalesce function to coalesce the capsule data.
+      //
+      Status = Capsule->Coalesce (
+                          PeiServices,
+                          &CapsuleBuffer,
+                          &CapsuleBufferLength
+                          );
+      //
+      // If it failed, then NULL out our capsule PPI pointer so that the capsule
+      // HOB does not get created below.
+      //
+      if (Status != EFI_SUCCESS) {
+        Capsule = NULL;
+      }
+    }
+  }
+
+  //
+  // Set up the IMR policy required for this platform
+  //
+  Status = SetPlatformImrPolicy (
+              PeiMemoryBaseAddress,
+              PeiMemoryLength
+              );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Carve out the top memory reserved for ACPI
+  //
+  Status        = PeiServicesInstallPeiMemory (PeiMemoryBaseAddress, PeiMemoryLength);
+  ASSERT_EFI_ERROR (Status);
+
+  BuildResourceDescriptorHob (
+   EFI_RESOURCE_SYSTEM_MEMORY,                       // MemoryType,
+   (
+   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
+   ),
+   PeiMemoryBaseAddress,                             // MemoryBegin
+   PeiMemoryLength                                   // MemoryLength
+   );
+
+  //
+  // Install physical memory descriptor hobs for each memory range.
+  //
+  SmramRanges = 0;
+  for (Index = 0; Index < NumRanges; Index++) {
+    Attribute = 0;
+    if (MemoryMap[Index].Type == DualChannelDdrMainMemory)
+    {
+      if (Index == PeiMemoryIndex) {
+        //
+        // This is a partially tested Main Memory range, give it to EFI
+        //
+        BuildResourceDescriptorHob (
+          EFI_RESOURCE_SYSTEM_MEMORY,
+          (
+          EFI_RESOURCE_ATTRIBUTE_PRESENT |
+          EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+          EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+          EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+          EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+          EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
+          ),
+          MemoryMap[Index].PhysicalAddress,
+          MemoryMap[Index].RangeLength - PeiMemoryLength
+          );
+      } else {
+        //
+        // This is an untested Main Memory range, give it to EFI
+        //
+        BuildResourceDescriptorHob (
+          EFI_RESOURCE_SYSTEM_MEMORY,       // MemoryType,
+          (
+          EFI_RESOURCE_ATTRIBUTE_PRESENT |
+          EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+          EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+          EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+          EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+          EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
+          ),
+          MemoryMap[Index].PhysicalAddress, // MemoryBegin
+          MemoryMap[Index].RangeLength      // MemoryLength
+          );
+      }
+    } else {
+      if ((MemoryMap[Index].Type == DualChannelDdrSmramCacheable) ||
+          (MemoryMap[Index].Type == DualChannelDdrSmramNonCacheable)) {
+        SmramRanges++;
+      }
+      if ((MemoryMap[Index].Type == DualChannelDdrSmramNonCacheable) ||
+          (MemoryMap[Index].Type == DualChannelDdrGraphicsMemoryNonCacheable)) {
+        Attribute |= EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE;
+      }
+      if ((MemoryMap[Index].Type == DualChannelDdrSmramCacheable)         ||
+          (MemoryMap[Index].Type == DualChannelDdrGraphicsMemoryCacheable)) {
+        //
+        // TSEG and HSEG can be used with a write-back(WB) cache policy; however,
+        // the specification requires that the TSEG and HSEG space be cached only
+        // inside of the SMI handler. when using HSEG or TSEG an IA-32 processor
+        // does not automatically write back and invalidate its cache before entering
+        // SMM or before existing SMM therefore any MTRR defined for the active TSEG
+        // or HSEG must be set to un-cacheable(UC) outside of SMM.
+        //
+        Attribute |= EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE;
+      }
+      if (MemoryMap[Index].Type == DualChannelDdrReservedMemory) {
+        Attribute |= EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
+                     EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE;
+      }
+      //
+      // Make sure non-system memory is marked as reserved
+      //
+      BuildResourceDescriptorHob (
+        EFI_RESOURCE_MEMORY_RESERVED,     // MemoryType,
+        Attribute,                        // MemoryAttribute
+        MemoryMap[Index].PhysicalAddress, // MemoryBegin
+        MemoryMap[Index].RangeLength      // MemoryLength
+        );
+    }
+  }
+
+  //
+  // Allocate one extra EFI_SMRAM_DESCRIPTOR to describe a page of SMRAM memory that contains a pointer
+  // to the SMM Services Table that is required on the S3 resume path
+  //
+  ASSERT (SmramRanges > 0);
+  BufferSize = sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK);
+  BufferSize += ((SmramRanges - 1) * sizeof (EFI_SMRAM_DESCRIPTOR));
+
+  Hob.Raw = BuildGuidHob (
+              &gEfiSmmPeiSmramMemoryReserveGuid,
+              BufferSize
+              );
+  ASSERT (Hob.Raw);
+
+  SmramHobDescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *) (Hob.Raw);
+  SmramHobDescriptorBlock->NumberOfSmmReservedRegions = SmramRanges;
+
+  SmramIndex = 0;
+  for (Index = 0; Index < NumRanges; Index++) {
+    if ((MemoryMap[Index].Type == DualChannelDdrSmramCacheable) ||
+        (MemoryMap[Index].Type == DualChannelDdrSmramNonCacheable)
+        ) {
+      //
+      // This is an SMRAM range, create an SMRAM descriptor
+      //
+      SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalStart = MemoryMap[Index].PhysicalAddress;
+      SmramHobDescriptorBlock->Descriptor[SmramIndex].CpuStart      = MemoryMap[Index].CpuAddress;
+      SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalSize  = MemoryMap[Index].RangeLength;
+      if (MemoryMap[Index].Type == DualChannelDdrSmramCacheable) {
+        SmramHobDescriptorBlock->Descriptor[SmramIndex].RegionState = EFI_SMRAM_CLOSED | EFI_CACHEABLE;
+      } else {
+        SmramHobDescriptorBlock->Descriptor[SmramIndex].RegionState = EFI_SMRAM_CLOSED;
+      }
+
+      SmramIndex++;
+    }
+  }
+
+  //
+  // Build a HOB with the location of the reserved memory range.
+  //
+  CopyMem(&DescriptorAcpiVariable, &SmramHobDescriptorBlock->Descriptor[SmramRanges-1], sizeof(EFI_SMRAM_DESCRIPTOR));
+  DescriptorAcpiVariable.CpuStart += RESERVED_CPU_S3_SAVE_OFFSET;
+  BuildGuidDataHob (
+    &gEfiAcpiVariableGuid,
+    &DescriptorAcpiVariable,
+    sizeof (EFI_SMRAM_DESCRIPTOR)
+    );
+
+  //
+  // If we found the capsule PPI (and we didn't have errors), then
+  // call the capsule PEIM to allocate memory for the capsule.
+  //
+  if (Capsule != NULL) {
+    Status = Capsule->CreateState (PeiServices, CapsuleBuffer, CapsuleBufferLength);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Find memory that is reserved so PEI has some to use.
+
+  @param  PeiServices      PEI Services table.
+  @param  VariableSevices  Variable PPI instance.
+
+  @return EFI_SUCCESS  The function completed successfully.
+                       Error value from LocatePpi()
+                       Error Value from VariableServices->GetVariable()
+
+**/
+EFI_STATUS
+InstallS3Memory (
+  IN      EFI_PEI_SERVICES                      **PeiServices,
+  IN      EFI_PEI_READ_ONLY_VARIABLE2_PPI       *VariableServices,
+  IN      UINT32                                TotalMemorySize
+  )
+{
+  EFI_STATUS                            Status;
+  UINTN                                 S3MemoryBase;
+  UINTN                                 S3MemorySize;
+  UINT8                                 SmramRanges;
+  UINT8                                 NumRanges;
+  UINT8                                 Index;
+  UINT8                                 SmramIndex;
+  UINTN                                 BufferSize;
+  EFI_PEI_HOB_POINTERS                  Hob;
+  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK        *SmramHobDescriptorBlock;
+  PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE MemoryMap[MAX_RANGES];
+  RESERVED_ACPI_S3_RANGE                *S3MemoryRangeData;
+  EFI_SMRAM_DESCRIPTOR                  DescriptorAcpiVariable;
+
+  //
+  // Get the Memory Map
+  //
+  NumRanges = MAX_RANGES;
+
+  ZeroMem (MemoryMap, sizeof (PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE) * NumRanges);
+
+  Status = GetMemoryMap (
+             PeiServices,
+             TotalMemorySize,
+             (PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE *) MemoryMap,
+             &NumRanges
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Install physical memory descriptor hobs for each memory range.
+  //
+  SmramRanges = 0;
+  for (Index = 0; Index < NumRanges; Index++) {
+    if ((MemoryMap[Index].Type == DualChannelDdrSmramCacheable)    ||
+       (MemoryMap[Index].Type == DualChannelDdrSmramNonCacheable)) {
+      SmramRanges++;
+    }
+  }
+
+  ASSERT (SmramRanges > 0);
+
+  //
+  // Allocate one extra EFI_SMRAM_DESCRIPTOR to describe a page of SMRAM memory that contains a pointer
+  // to the SMM Services Table that is required on the S3 resume path
+  //
+  BufferSize = sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK);
+  if (SmramRanges > 0) {
+    BufferSize += ((SmramRanges - 1) * sizeof (EFI_SMRAM_DESCRIPTOR));
+  }
+
+  Hob.Raw = BuildGuidHob (
+              &gEfiSmmPeiSmramMemoryReserveGuid,
+              BufferSize
+              );
+  ASSERT (Hob.Raw);
+
+  SmramHobDescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *) (Hob.Raw);
+  SmramHobDescriptorBlock->NumberOfSmmReservedRegions = SmramRanges;
+
+  SmramIndex = 0;
+  for (Index = 0; Index < NumRanges; Index++) {
+    if ((MemoryMap[Index].Type == DualChannelDdrSmramCacheable) ||
+        (MemoryMap[Index].Type == DualChannelDdrSmramNonCacheable)
+        ) {
+      //
+      // This is an SMRAM range, create an SMRAM descriptor
+      //
+      SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalStart = MemoryMap[Index].PhysicalAddress;
+      SmramHobDescriptorBlock->Descriptor[SmramIndex].CpuStart      = MemoryMap[Index].CpuAddress;
+      SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalSize  = MemoryMap[Index].RangeLength;
+      if (MemoryMap[Index].Type == DualChannelDdrSmramCacheable) {
+        SmramHobDescriptorBlock->Descriptor[SmramIndex].RegionState = EFI_SMRAM_CLOSED | EFI_CACHEABLE;
+      } else {
+        SmramHobDescriptorBlock->Descriptor[SmramIndex].RegionState = EFI_SMRAM_CLOSED;
+      }
+
+      SmramIndex++;
+    }
+  }
+
+  //
+  // Build a HOB with the location of the reserved memory range.
+  //
+  CopyMem(&DescriptorAcpiVariable, &SmramHobDescriptorBlock->Descriptor[SmramRanges-1], sizeof(EFI_SMRAM_DESCRIPTOR));
+  DescriptorAcpiVariable.CpuStart += RESERVED_CPU_S3_SAVE_OFFSET;
+  BuildGuidDataHob (
+    &gEfiAcpiVariableGuid,
+    &DescriptorAcpiVariable,
+    sizeof (EFI_SMRAM_DESCRIPTOR)
+    );
+
+  //
+  // Get the location and size of the S3 memory range in the reserved page and
+  // install it as PEI Memory.
+  //
+
+  DEBUG ((EFI_D_INFO, "TSEG Base = 0x%08x\n", SmramHobDescriptorBlock->Descriptor[SmramRanges-1].PhysicalStart));
+  S3MemoryRangeData = (RESERVED_ACPI_S3_RANGE*)(UINTN)
+    (SmramHobDescriptorBlock->Descriptor[SmramRanges-1].PhysicalStart + RESERVED_ACPI_S3_RANGE_OFFSET);
+
+  S3MemoryBase  = (UINTN) (S3MemoryRangeData->AcpiReservedMemoryBase);
+  DEBUG ((EFI_D_INFO, "S3MemoryBase = 0x%08x\n", S3MemoryBase));
+  S3MemorySize  = (UINTN) (S3MemoryRangeData->AcpiReservedMemorySize);
+  DEBUG ((EFI_D_INFO, "S3MemorySize = 0x%08x\n", S3MemorySize));
+
+  Status        = PeiServicesInstallPeiMemory (S3MemoryBase, S3MemorySize);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Retrieve the system memory length and build memory hob for the system
+  // memory above 1MB. So Memory Callback can set cache for the system memory
+  // correctly on S3 boot path, just like it does on Normal boot path.
+  //
+  ASSERT ((S3MemoryRangeData->SystemMemoryLength - 0x100000) > 0);
+  BuildResourceDescriptorHob (
+            EFI_RESOURCE_SYSTEM_MEMORY,
+            (
+            EFI_RESOURCE_ATTRIBUTE_PRESENT |
+            EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+            EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+            EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+            EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+            EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
+            ),
+            0x100000,
+            S3MemoryRangeData->SystemMemoryLength - 0x100000
+            );
+
+  for (Index = 0; Index < NumRanges; Index++) {
+    if ((MemoryMap[Index].Type == DualChannelDdrMainMemory) &&
+        (MemoryMap[Index].PhysicalAddress + MemoryMap[Index].RangeLength < 0x100000)) {
+      BuildResourceDescriptorHob (
+        EFI_RESOURCE_SYSTEM_MEMORY,
+        (
+        EFI_RESOURCE_ATTRIBUTE_PRESENT |
+        EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+        EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+        EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+        EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+        EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
+        ),
+        MemoryMap[Index].PhysicalAddress,
+        MemoryMap[Index].RangeLength
+        );
+      DEBUG ((EFI_D_INFO, "Build resource HOB for Legacy Region on S3 patch :"));
+      DEBUG ((EFI_D_INFO, " Memory Base:0x%lX Length:0x%lX\n", MemoryMap[Index].PhysicalAddress, MemoryMap[Index].RangeLength));
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  This function returns the memory ranges to be enabled, along with information
+  describing how the range should be used.
+
+  @param  PeiServices   PEI Services Table.
+  @param  TimingData    Detected DDR timing parameters for installed memory.
+  @param  RowConfArray  Pointer to an array of EFI_DUAL_CHANNEL_DDR_ROW_CONFIG structures. The number
+                        of items in the array must match MaxRows returned by the McGetRowInfo() function.
+  @param  MemoryMap     Buffer to record details of the memory ranges tobe enabled.
+  @param  NumRanges     On input, this contains the maximum number of memory ranges that can be described
+                        in the MemoryMap buffer.
+
+  @return MemoryMap     The buffer will be filled in
+          NumRanges     will contain the actual number of memory ranges that are to be anabled.
+          EFI_SUCCESS   The function completed successfully.
+
+**/
+EFI_STATUS
+GetMemoryMap (
+  IN     EFI_PEI_SERVICES                                    **PeiServices,
+  IN     UINT32                                              TotalMemorySize,
+  IN OUT PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE               *MemoryMap,
+  IN OUT UINT8                                               *NumRanges
+  )
+{
+  EFI_PHYSICAL_ADDRESS              MemorySize;
+  EFI_PHYSICAL_ADDRESS              RowLength;
+  EFI_STATUS                        Status;
+  PEI_MEMORY_RANGE_PCI_MEMORY       PciMemoryMask;
+  PEI_MEMORY_RANGE_OPTION_ROM       OptionRomMask;
+  PEI_MEMORY_RANGE_SMRAM            SmramMask;
+  PEI_MEMORY_RANGE_SMRAM            TsegMask;
+  UINT32                            BlockNum;
+  UINT8                             ExtendedMemoryIndex;
+  UINT32                            Register;
+
+  if ((*NumRanges) < MAX_RANGES) {
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  *NumRanges = 0;
+
+  //
+  // Find out which memory ranges to reserve on this platform
+  //
+  Status = ChooseRanges (
+             &OptionRomMask,
+             &SmramMask,
+             &PciMemoryMask
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Generate Memory ranges for the memory map.
+  //
+  MemorySize = 0;
+
+  RowLength = TotalMemorySize;
+
+  //
+  // Add memory below 640KB to the memory map. Make sure memory between
+  // 640KB and 1MB are reserved, even if not used for SMRAM
+  //
+  MemoryMap[*NumRanges].PhysicalAddress = MemorySize;
+  MemoryMap[*NumRanges].CpuAddress      = MemorySize;
+  MemoryMap[*NumRanges].RangeLength     = 0xA0000;
+  MemoryMap[*NumRanges].Type            = DualChannelDdrMainMemory;
+  (*NumRanges)++;
+
+  //
+  // Just mark this range reserved
+  //
+  MemoryMap[*NumRanges].PhysicalAddress = 0xA0000;
+  MemoryMap[*NumRanges].CpuAddress      = 0xA0000;
+  MemoryMap[*NumRanges].RangeLength     = 0x60000;
+  MemoryMap[*NumRanges].Type            = DualChannelDdrReservedMemory;
+  (*NumRanges)++;
+
+  RowLength -= (0x100000 - MemorySize);
+  MemorySize = 0x100000;
+
+  //
+  // Add remaining memory to the memory map
+  //
+  MemoryMap[*NumRanges].PhysicalAddress = MemorySize;
+  MemoryMap[*NumRanges].CpuAddress      = MemorySize;
+  MemoryMap[*NumRanges].RangeLength     = RowLength;
+  MemoryMap[*NumRanges].Type            = DualChannelDdrMainMemory;
+  (*NumRanges)++;
+  MemorySize += RowLength;
+
+  ExtendedMemoryIndex = (UINT8) (*NumRanges - 1);
+
+  // See if we need to trim TSEG out of the highest memory range
+  //
+  if (SmramMask & PEI_MR_SMRAM_TSEG_MASK) {//pcd
+    //
+    // Create the new range for TSEG and remove that range from the previous SdrDdrMainMemory range
+    //
+    TsegMask  = (SmramMask & PEI_MR_SMRAM_SIZE_MASK);
+
+    BlockNum  = 1;
+    while (TsegMask) {
+      TsegMask >>= 1;
+      BlockNum <<= 1;
+    }
+
+    BlockNum >>= 1;
+
+    if (BlockNum) {
+
+      MemoryMap[*NumRanges].RangeLength           = (BlockNum * 128 * 1024);
+      Register = (UINT32)((MemorySize - 1) & SMM_END_MASK);
+      MemorySize                                 -= MemoryMap[*NumRanges].RangeLength;
+      MemoryMap[*NumRanges].PhysicalAddress       = MemorySize;
+      MemoryMap[*NumRanges].CpuAddress            = MemorySize;
+      MemoryMap[ExtendedMemoryIndex].RangeLength -= MemoryMap[*NumRanges].RangeLength;
+
+      //
+      // Update QuarkNcSoc HSMMCTL register
+      //
+      Register |= (UINT32)(((RShiftU64(MemorySize, 16)) & SMM_START_MASK) + (SMM_WRITE_OPEN | SMM_READ_OPEN | SMM_CODE_RD_OPEN));
+      QncHsmmcWrite (Register);
+    }
+
+    //
+    // Chipset only supports cacheable SMRAM
+    //
+    MemoryMap[*NumRanges].Type = DualChannelDdrSmramCacheable;
+
+    (*NumRanges)++;
+  }
+
+  //
+  // trim 64K memory from highest memory range for Rmu Main binary shadow
+  //
+  MemoryMap[*NumRanges].RangeLength           = 0x10000;
+  MemorySize                                 -= MemoryMap[*NumRanges].RangeLength;
+  MemoryMap[*NumRanges].PhysicalAddress       = MemorySize;
+  MemoryMap[*NumRanges].CpuAddress            = MemorySize;
+  MemoryMap[ExtendedMemoryIndex].RangeLength -= MemoryMap[*NumRanges].RangeLength;
+  MemoryMap[*NumRanges].Type = DualChannelDdrReservedMemory;
+  (*NumRanges)++;
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+Routine Description:
+
+  Fill in bit masks to specify reserved memory ranges on the Lakeport platform
+
+Arguments:
+
+Returns:
+
+  OptionRomMask - Bit mask specifying memory regions reserved for Legacy option
+                  ROM use (if any)
+
+  SmramMask - Bit mask specifying memory regions reserved for SMM use (if any)
+
+**/
+EFI_STATUS
+ChooseRanges (
+  IN OUT   PEI_MEMORY_RANGE_OPTION_ROM           *OptionRomMask,
+  IN OUT   PEI_MEMORY_RANGE_SMRAM                *SmramMask,
+  IN OUT   PEI_MEMORY_RANGE_PCI_MEMORY           *PciMemoryMask
+  )
+{
+
+  //
+  // Choose regions to reserve for Option ROM use
+  //
+  *OptionRomMask = PEI_MR_OPTION_ROM_NONE;
+
+  //
+  // Choose regions to reserve for SMM use (AB/H SEG and TSEG). Size is in 128K blocks
+  //
+  *SmramMask = PEI_MR_SMRAM_CACHEABLE_MASK | PEI_MR_SMRAM_TSEG_MASK | ((PcdGet32(PcdTSegSize)) >> 17);
+
+  *PciMemoryMask = 0;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetPlatformMemorySize (
+  IN       EFI_PEI_SERVICES                       **PeiServices,
+  IN       EFI_BOOT_MODE                          BootMode,
+  IN OUT   UINT64                                 *MemorySize
+  )
+{
+  EFI_STATUS                            Status;
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI       *Variable;
+  UINTN                                 DataSize;
+  EFI_MEMORY_TYPE_INFORMATION           MemoryData [EfiMaxMemoryType + 1];
+  UINTN                                 Index;
+
+  DataSize = sizeof (MemoryData);
+
+  if (BootMode == BOOT_IN_RECOVERY_MODE) {
+
+    //
+    // // Treat recovery as if variable not found (eg 1st boot).
+    //
+    Status = EFI_NOT_FOUND;
+
+  } else {
+    Status = PeiServicesLocatePpi (
+               &gEfiPeiReadOnlyVariable2PpiGuid,
+               0,
+               NULL,
+               (VOID **)&Variable
+               );
+
+    ASSERT_EFI_ERROR (Status);
+
+    DataSize = sizeof (MemoryData);
+    Status = Variable->GetVariable (
+                         Variable,
+                         EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
+                         &gEfiMemoryTypeInformationGuid,
+                         NULL,
+                         &DataSize,
+                         &MemoryData
+                         );
+  }
+
+  //
+  // Accumulate maximum amount of memory needed
+  //
+  if (EFI_ERROR (Status)) {
+    //
+    // Start with minimum memory
+    //
+    *MemorySize = PEI_MIN_MEMORY_SIZE;
+
+    for (Index = 0; Index < sizeof(mDefaultQncMemoryTypeInformation) / sizeof (EFI_MEMORY_TYPE_INFORMATION); Index++) {
+        *MemorySize += mDefaultQncMemoryTypeInformation[Index].NumberOfPages * EFI_PAGE_SIZE;
+    }
+
+    //
+    // Build the GUID'd HOB for DXE
+    //
+    BuildGuidDataHob (
+                 &gEfiMemoryTypeInformationGuid,
+                 mDefaultQncMemoryTypeInformation,
+                 sizeof(mDefaultQncMemoryTypeInformation)
+                 );
+  } else {
+    //
+    // Start with at least PEI_MIN_MEMORY_SIZE pages of memory for the DXE Core and the DXE Stack
+    //
+
+    *MemorySize = PEI_MIN_MEMORY_SIZE;
+    for (Index = 0; Index < DataSize / sizeof (EFI_MEMORY_TYPE_INFORMATION); Index++) {
+      DEBUG ((EFI_D_INFO, "Index %d, Page: %d\n", Index, MemoryData[Index].NumberOfPages));
+      *MemorySize += MemoryData[Index].NumberOfPages * EFI_PAGE_SIZE;
+    }
+
+    //
+    // Build the GUID'd HOB for DXE
+    //
+    BuildGuidDataHob (
+                 &gEfiMemoryTypeInformationGuid,
+                 MemoryData,
+                 DataSize
+                 );
+
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+BaseMemoryTest (
+  IN  EFI_PEI_SERVICES                   **PeiServices,
+  IN  EFI_PHYSICAL_ADDRESS               BeginAddress,
+  IN  UINT64                             MemoryLength,
+  IN  PEI_MEMORY_TEST_OP                 Operation,
+  OUT EFI_PHYSICAL_ADDRESS               *ErrorAddress
+  )
+{
+  UINT32                TestPattern;
+  EFI_PHYSICAL_ADDRESS  TempAddress;
+  UINT32                SpanSize;
+
+  TestPattern = 0x5A5A5A5A;
+  SpanSize    = 0;
+
+  //
+  // Make sure we don't try and test anything above the max physical address range
+  //
+  ASSERT (BeginAddress + MemoryLength < MAX_ADDRESS);
+
+  switch (Operation) {
+  case Extensive:
+    SpanSize = 0x4;
+    break;
+
+  case Sparse:
+  case Quick:
+    SpanSize = 0x40000;
+    break;
+
+  case Ignore:
+    goto Done;
+    break;
+  }
+  //
+  // Write the test pattern into memory range
+  //
+  TempAddress = BeginAddress;
+  while (TempAddress < BeginAddress + MemoryLength) {
+    (*(UINT32 *) (UINTN) TempAddress) = TestPattern;
+    TempAddress += SpanSize;
+  }
+  //
+  // Read pattern from memory and compare it
+  //
+  TempAddress = BeginAddress;
+  while (TempAddress < BeginAddress + MemoryLength) {
+    if ((*(UINT32 *) (UINTN) TempAddress) != TestPattern) {
+      *ErrorAddress = TempAddress;
+      DEBUG ((EFI_D_ERROR, "Memory test failed at 0x%x.\n", TempAddress));
+      return EFI_DEVICE_ERROR;
+    }
+
+    TempAddress += SpanSize;
+  }
+
+Done:
+  return EFI_SUCCESS;
+}
+
+/**
+
+  This function sets up the platform specific IMR protection for the various
+  memory regions.
+
+  @param  PeiMemoryBaseAddress  Base address of memory allocated for PEI.
+  @param  PeiMemoryLength       Length in bytes of the PEI memory (includes ACPI memory).
+
+  @return EFI_SUCCESS           The function completed successfully.
+          EFI_ACCESS_DENIED     Access to IMRs failed.
+
+**/
+EFI_STATUS
+SetPlatformImrPolicy (
+  IN      EFI_PHYSICAL_ADDRESS    PeiMemoryBaseAddress,
+  IN      UINT64                  PeiMemoryLength
+  )
+{
+  UINT8         Index;
+  UINT32        Register;
+  UINT16        DeviceId;
+
+  //
+  // Check what Soc we are running on (read Host bridge DeviceId)
+  //
+  DeviceId = QNCMmPci16(0, MC_BUS, MC_DEV, MC_FUN, PCI_DEVICE_ID_OFFSET);
+
+  //
+  // If any IMR register is locked then we cannot proceed
+  //
+  for (Index = (QUARK_NC_MEMORY_MANAGER_IMR0+QUARK_NC_MEMORY_MANAGER_IMRXL); Index <=(QUARK_NC_MEMORY_MANAGER_IMR7+QUARK_NC_MEMORY_MANAGER_IMRXL); Index=Index+4)
+  {
+    Register = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, Index);
+    if (Register & IMR_LOCK) {
+      return EFI_ACCESS_DENIED;
+    }
+  }
+
+  //
+  // Add IMR2 protection for shadowed RMU binary.
+  //
+  QncImrWrite (
+            QUARK_NC_MEMORY_MANAGER_IMR2,
+            (UINT32)(((RShiftU64((PeiMemoryBaseAddress+PeiMemoryLength), 8)) & IMRH_MASK) | IMR_EN),
+            (UINT32)((RShiftU64((PeiMemoryBaseAddress+PeiMemoryLength+PcdGet32(PcdFlashQNCMicrocodeSize)-1), 8)) & IMRH_MASK),
+            (UINT32)(CPU_SNOOP + RMU + CPU0_NON_SMM),
+            (UINT32)(CPU_SNOOP + RMU + CPU0_NON_SMM)
+        );
+
+  //
+  // Add IMR3 protection for the default SMRAM.
+  //
+  QncImrWrite (
+            QUARK_NC_MEMORY_MANAGER_IMR3,
+            (UINT32)(((RShiftU64((SMM_DEFAULT_SMBASE), 8)) & IMRL_MASK) | IMR_EN),
+            (UINT32)((RShiftU64((SMM_DEFAULT_SMBASE+SMM_DEFAULT_SMBASE_SIZE_BYTES-1), 8)) & IMRH_MASK),
+            (UINT32)(CPU_SNOOP + CPU0_NON_SMM),
+            (UINT32)(CPU_SNOOP + CPU0_NON_SMM)
+        );
+
+  //
+  // Enable IMR4 protection of eSRAM.
+  //
+  QncImrWrite (
+            QUARK_NC_MEMORY_MANAGER_IMR4,
+            (UINT32)(((RShiftU64((UINTN)PcdGet32 (PcdEsramStage1Base), 8)) & IMRL_MASK) | IMR_EN),
+            (UINT32)((RShiftU64(((UINTN)PcdGet32 (PcdEsramStage1Base) + (UINTN)PcdGet32 (PcdESramMemorySize) - 1), 8)) & IMRH_MASK),
+            (UINT32)(CPU_SNOOP + CPU0_NON_SMM),
+            (UINT32)(CPU_SNOOP + CPU0_NON_SMM)
+        );
+
+  //
+  // Enable Interrupt on IMR/SMM Violation
+  //
+  QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_BIMRVCTL, (UINT32)(EnableIMRInt));
+  if (DeviceId == QUARK2_MC_DEVICE_ID) {
+    QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_BSMMVCTL, (UINT32)(EnableSMMInt));
+  }
+
+  //
+  // Disable IMR7 memory protection (eSRAM + DDR3 memory) since our policies
+  // are now setup.
+  //
+  QncImrWrite (
+            QUARK_NC_MEMORY_MANAGER_IMR7,
+            (UINT32)(IMRL_RESET & ~IMR_EN),
+            (UINT32)IMRH_RESET,
+            (UINT32)IMRX_ALL_ACCESS,
+            (UINT32)IMRX_ALL_ACCESS
+        );
+
+  return EFI_SUCCESS;
+}
+
+/** Return info derived from Installing Memory by MemoryInit.
+
+  @param[out]      RmuMainBaseAddressPtr   Return RmuMainBaseAddress to this location.
+  @param[out]      SmramDescriptorPtr  Return start of Smram descriptor list to this location.
+  @param[out]      NumSmramRegionsPtr  Return numbers of Smram regions to this location.
+
+  @return Address of RMU shadow region at the top of available memory.
+  @return List of Smram descriptors for each Smram region.
+  @return Numbers of Smram regions.
+**/
+VOID
+EFIAPI
+InfoPostInstallMemory (
+  OUT     UINT32                    *RmuMainBaseAddressPtr OPTIONAL,
+  OUT     EFI_SMRAM_DESCRIPTOR      **SmramDescriptorPtr OPTIONAL,
+  OUT     UINTN                     *NumSmramRegionsPtr OPTIONAL
+  )
+{
+  EFI_STATUS                            Status;
+  EFI_PEI_HOB_POINTERS                  Hob;
+  UINT64                                CalcLength;
+  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK        *SmramHobDescriptorBlock;
+
+  if ((RmuMainBaseAddressPtr == NULL) && (SmramDescriptorPtr == NULL) && (NumSmramRegionsPtr == NULL)) {
+    return;
+  }
+
+  SmramHobDescriptorBlock = NULL;
+  if (SmramDescriptorPtr != NULL) {
+    *SmramDescriptorPtr = NULL;
+  }
+  if (NumSmramRegionsPtr != NULL) {
+    *NumSmramRegionsPtr = 0;
+  }
+
+  //
+  // Calculate RMU shadow region base address.
+  // Set to 1 MB. Since 1MB cacheability will always be set
+  // until override by CSM.
+  //
+  CalcLength = 0x100000;
+
+  Status = PeiServicesGetHobList ((VOID **) &Hob.Raw);
+  ASSERT_EFI_ERROR (Status);
+  while (!END_OF_HOB_LIST (Hob)) {
+    if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+      if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
+        //
+        // Skip the memory region below 1MB
+        //
+        if (Hob.ResourceDescriptor->PhysicalStart >= 0x100000) {
+          CalcLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);
+        }
+      }
+    } else if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION) {
+      if (CompareGuid (&(Hob.Guid->Name), &gEfiSmmPeiSmramMemoryReserveGuid)) {
+        SmramHobDescriptorBlock = (VOID*) (Hob.Raw + sizeof (EFI_HOB_GUID_TYPE));
+        if (SmramDescriptorPtr != NULL) {
+          *SmramDescriptorPtr = SmramHobDescriptorBlock->Descriptor;
+        }
+        if (NumSmramRegionsPtr != NULL) {
+          *NumSmramRegionsPtr = SmramHobDescriptorBlock->NumberOfSmmReservedRegions;
+        }
+      }
+    }
+    Hob.Raw = GET_NEXT_HOB (Hob);
+  }
+
+  if (RmuMainBaseAddressPtr != NULL) {
+    *RmuMainBaseAddressPtr = (UINT32) CalcLength;
+  }
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.h b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.h
new file mode 100644
index 0000000000..e24eb4b475
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.h
@@ -0,0 +1,225 @@
+/** @file
+Framework PEIM to initialize memory on an DDR2 SDRAM Memory Controller.
+
+Copyright (c) 2013 - 2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _MRC_WRAPPER_H
+#define _MRC_WRAPPER_H
+
+#include <Ppi/QNCMemoryInit.h>
+#include "PlatformEarlyInit.h"
+
+//
+// Define the default memory areas required
+//
+#define EDKII_RESERVED_SIZE_PAGES         0x20
+#define ACPI_NVS_SIZE_PAGES               0x60
+#define RUNTIME_SERVICES_DATA_SIZE_PAGES  0x20
+#define RUNTIME_SERVICES_CODE_SIZE_PAGES  0x80
+#define ACPI_RECLAIM_SIZE_PAGES           0x20
+#define EDKII_DXE_MEM_SIZE_PAGES          0x20
+
+//
+// Maximum number of "Socket Sets", where a "Socket Set is a set of matching
+// DIMM's from the various channels
+//
+#define MAX_SOCKET_SETS      2
+
+//
+// Maximum number of memory ranges supported by the memory controller
+//
+#define MAX_RANGES (MAX_ROWS + 5)
+
+//
+// Min. of 48MB PEI phase
+//
+#define  PEI_MIN_MEMORY_SIZE               (6 * 0x800000)
+#define  PEI_RECOVERY_MIN_MEMORY_SIZE      (6 * 0x800000)
+
+#define PEI_MEMORY_RANGE_OPTION_ROM UINT32
+#define PEI_MR_OPTION_ROM_NONE      0x00000000
+
+//
+// SMRAM Memory Range
+//
+#define PEI_MEMORY_RANGE_SMRAM      UINT32
+#define PEI_MR_SMRAM_ALL            0xFFFFFFFF
+#define PEI_MR_SMRAM_NONE           0x00000000
+#define PEI_MR_SMRAM_CACHEABLE_MASK 0x80000000
+#define PEI_MR_SMRAM_SEGTYPE_MASK   0x00FF0000
+#define PEI_MR_SMRAM_ABSEG_MASK     0x00010000
+#define PEI_MR_SMRAM_HSEG_MASK      0x00020000
+#define PEI_MR_SMRAM_TSEG_MASK      0x00040000
+//
+// SMRAM Size is a multiple of 128KB.
+//
+#define PEI_MR_SMRAM_SIZE_MASK          0x0000FFFF
+
+//
+// Pci Memory Hole
+//
+#define PEI_MEMORY_RANGE_PCI_MEMORY       UINT32
+
+typedef enum {
+  Ignore,
+  Quick,
+  Sparse,
+  Extensive
+} PEI_MEMORY_TEST_OP;
+
+//
+// MRC Params Variable structure.
+//
+
+typedef struct {
+  MrcTimings_t timings;              // Actual MRC config values saved in variable store.
+  UINT8        VariableStorePad[8];  // Allow for data stored in variable is required to be multiple of 8bytes.
+} PLATFORM_VARIABLE_MEMORY_CONFIG_DATA;
+
+///
+/// MRC Params Platform Data Flags bits
+///
+#define PDAT_MRC_FLAG_ECC_EN            BIT0
+#define PDAT_MRC_FLAG_SCRAMBLE_EN       BIT1
+#define PDAT_MRC_FLAG_MEMTEST_EN        BIT2
+#define PDAT_MRC_FLAG_TOP_TREE_EN       BIT3  ///< 0b DDR "fly-by" topology else 1b DDR "tree" topology.
+#define PDAT_MRC_FLAG_WR_ODT_EN         BIT4  ///< If set ODR signal is asserted to DRAM devices on writes.
+
+///
+/// MRC Params Platform Data.
+///
+typedef struct {
+  UINT32       Flags;                   ///< Bitmap of PDAT_MRC_FLAG_XXX defs above.
+  UINT8        DramWidth;               ///< 0=x8, 1=x16, others=RESERVED.
+  UINT8        DramSpeed;               ///< 0=DDRFREQ_800, 1=DDRFREQ_1066, others=RESERVED. Only 533MHz SKU support 1066 memory.
+  UINT8        DramType;                ///< 0=DDR3,1=DDR3L, others=RESERVED.
+  UINT8        RankMask;                ///< bit[0] RANK0_EN, bit[1] RANK1_EN, others=RESERVED.
+  UINT8        ChanMask;                ///< bit[0] CHAN0_EN, others=RESERVED.
+  UINT8        ChanWidth;               ///< 1=x16, others=RESERVED.
+  UINT8        AddrMode;                ///< 0, 1, 2 (mode 2 forced if ecc enabled), others=RESERVED.
+  UINT8        SrInt;                   ///< 1=1.95us, 2=3.9us, 3=7.8us, others=RESERVED. REFRESH_RATE.
+  UINT8        SrTemp;                  ///< 0=normal, 1=extended, others=RESERVED.
+  UINT8        DramRonVal;              ///< 0=34ohm, 1=40ohm, others=RESERVED. RON_VALUE Select MRS1.DIC driver impedance control.
+  UINT8        DramRttNomVal;           ///< 0=40ohm, 1=60ohm, 2=120ohm, others=RESERVED.
+  UINT8        DramRttWrVal;            ///< 0=off others=RESERVED.
+  UINT8        SocRdOdtVal;             ///< 0=off, 1=60ohm, 2=120ohm, 3=180ohm, others=RESERVED.
+  UINT8        SocWrRonVal;             ///< 0=27ohm, 1=32ohm, 2=40ohm, others=RESERVED.
+  UINT8        SocWrSlewRate;           ///< 0=2.5V/ns, 1=4V/ns, others=RESERVED.
+  UINT8        DramDensity;             ///< 0=512Mb, 1=1Gb, 2=2Gb, 3=4Gb, others=RESERVED.
+  UINT32       tRAS;                    ///< ACT to PRE command period in picoseconds.
+  UINT32       tWTR;                    ///< Delay from start of internal write transaction to internal read command in picoseconds.
+  UINT32       tRRD;                    ///< ACT to ACT command period (JESD79 specific to page size 1K/2K) in picoseconds.
+  UINT32       tFAW;                    ///< Four activate window (JESD79 specific to page size 1K/2K) in picoseconds.
+  UINT8        tCL;                     ///< DRAM CAS Latency in clocks.
+} PDAT_MRC_ITEM;
+
+//
+// Memory range types
+//
+typedef enum {
+  DualChannelDdrMainMemory,
+  DualChannelDdrSmramCacheable,
+  DualChannelDdrSmramNonCacheable,
+  DualChannelDdrGraphicsMemoryCacheable,
+  DualChannelDdrGraphicsMemoryNonCacheable,
+  DualChannelDdrReservedMemory,
+  DualChannelDdrMaxMemoryRangeType
+} PEI_DUAL_CHANNEL_DDR_MEMORY_RANGE_TYPE;
+
+//
+// Memory map range information
+//
+typedef struct {
+  EFI_PHYSICAL_ADDRESS                          PhysicalAddress;
+  EFI_PHYSICAL_ADDRESS                          CpuAddress;
+  EFI_PHYSICAL_ADDRESS                          RangeLength;
+  PEI_DUAL_CHANNEL_DDR_MEMORY_RANGE_TYPE        Type;
+} PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE;
+
+//
+// Function prototypes.
+//
+
+EFI_STATUS
+InstallEfiMemory (
+  IN      EFI_PEI_SERVICES                           **PeiServices,
+  IN      EFI_PEI_READ_ONLY_VARIABLE2_PPI            *VariableServices,
+  IN      EFI_BOOT_MODE                              BootMode,
+  IN      UINT32                                     TotalMemorySize
+  );
+
+EFI_STATUS
+InstallS3Memory (
+  IN      EFI_PEI_SERVICES                      **PeiServices,
+  IN      EFI_PEI_READ_ONLY_VARIABLE2_PPI       *VariableServices,
+  IN      UINT32                                TotalMemorySize
+  );
+
+EFI_STATUS
+MemoryInit (
+  IN EFI_PEI_SERVICES                       **PeiServices
+  );
+
+
+EFI_STATUS
+LoadConfig (
+  IN      EFI_PEI_SERVICES                        **PeiServices,
+  IN      EFI_PEI_READ_ONLY_VARIABLE2_PPI         *VariableServices,
+  IN OUT  MRCParams_t                             *MrcData
+  );
+
+EFI_STATUS
+SaveConfig (
+  IN      MRCParams_t                      *MrcData
+  );
+
+EFI_STATUS
+GetMemoryMap (
+  IN     EFI_PEI_SERVICES                                    **PeiServices,
+  IN     UINT32                                              TotalMemorySize,
+  IN OUT PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE               *MemoryMap,
+  IN OUT UINT8                                               *NumRanges
+  );
+
+EFI_STATUS
+ChooseRanges (
+  IN OUT   PEI_MEMORY_RANGE_OPTION_ROM      *OptionRomMask,
+  IN OUT   PEI_MEMORY_RANGE_SMRAM           *SmramMask,
+  IN OUT   PEI_MEMORY_RANGE_PCI_MEMORY      *PciMemoryMask
+  );
+
+EFI_STATUS
+GetPlatformMemorySize (
+  IN      EFI_PEI_SERVICES                       **PeiServices,
+  IN      EFI_BOOT_MODE                          BootMode,
+  IN OUT  UINT64                                 *MemorySize
+  );
+
+EFI_STATUS
+BaseMemoryTest (
+  IN  EFI_PEI_SERVICES                   **PeiServices,
+  IN  EFI_PHYSICAL_ADDRESS               BeginAddress,
+  IN  UINT64                             MemoryLength,
+  IN  PEI_MEMORY_TEST_OP                 Operation,
+  OUT EFI_PHYSICAL_ADDRESS               *ErrorAddress
+  );
+
+EFI_STATUS
+SetPlatformImrPolicy (
+  IN      EFI_PHYSICAL_ADDRESS    PeiMemoryBaseAddress,
+  IN      UINT64                  PeiMemoryLength
+  );
+
+VOID
+EFIAPI
+InfoPostInstallMemory (
+  OUT     UINT32                  *RmuBaseAddressPtr OPTIONAL,
+  OUT     EFI_SMRAM_DESCRIPTOR    **SmramDescriptorPtr OPTIONAL,
+  OUT     UINTN                   *NumSmramRegionsPtr OPTIONAL
+  );
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.c b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.c
new file mode 100644
index 0000000000..f94d3ca567
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.c
@@ -0,0 +1,111 @@
+/** @file
+EFI PEI Platform Security services
+
+Copyright (c) 2013 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PeiFvSecurity.h"
+
+EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnFvInfoSecurityList = {
+    (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+    &gEfiPeiFirmwareVolumeInfoPpiGuid,
+    FirmwareVolmeInfoPpiNotifySecurityCallback
+};
+
+/**
+  Callback function to perform FV security checking on a FV Info PPI.
+
+  @param PeiServices       An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
+  @param NotifyDescriptor  Address of the notification descriptor data structure.
+  @param Ppi               Address of the PPI that was installed.
+
+  @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EFIAPI
+FirmwareVolmeInfoPpiNotifySecurityCallback (
+  IN EFI_PEI_SERVICES              **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR     *NotifyDescriptor,
+  IN VOID                          *Ppi
+  )
+{
+  EFI_STATUS  Status;
+  EFI_PEI_FIRMWARE_VOLUME_INFO_PPI      *FvInfoPpi;
+  EFI_PEI_FIRMWARE_VOLUME_PPI           *FvPpi;
+
+  FvInfoPpi = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *)Ppi;
+
+  //
+  // Locate the corresponding FV_PPI according to founded FV's format guid
+  //
+  Status = PeiServicesLocatePpi (
+             &FvInfoPpi->FvFormat,
+             0,
+             NULL,
+             (VOID**)&FvPpi
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Only authenticate parent Firmware Volume (child firmware volumes are covered by the parent)
+  //
+  if ((VOID *)FvInfoPpi->ParentFvName == NULL && (VOID *)FvInfoPpi->ParentFileName == NULL) {
+    Status = PeiSecurityVerifyFv ((EFI_FIRMWARE_VOLUME_HEADER*) FvInfoPpi->FvInfo);
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Authenticates the Firmware Volume
+
+  @param CurrentFvAddress   Pointer to the current Firmware Volume under consideration
+
+  @retval EFI_SUCCESS       Firmware Volume is legal
+
+**/
+EFI_STATUS
+PeiSecurityVerifyFv (
+  IN EFI_FIRMWARE_VOLUME_HEADER  *CurrentFvAddress
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // Call Security library to authenticate the Firmware Volume
+  //
+  DEBUG ((DEBUG_INFO, "PeiSecurityVerifyFv - CurrentFvAddress=0x%8x\n", (UINT32)CurrentFvAddress));
+  Status = EFI_SUCCESS;
+
+  return Status;
+}
+
+/**
+
+  Entry point for the PEI Security PEIM
+  Sets up a notification to perform PEI security checking
+
+  @param  FfsHeader    Not used.
+  @param  PeiServices  General purpose services available to every PEIM.
+
+  @return EFI_SUCCESS  PEI Security notification installed successfully.
+          All others: PEI Security notification failed to install.
+
+**/
+EFI_STATUS
+PeiInitializeFvSecurity (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = PeiServicesNotifyPpi (&mNotifyOnFvInfoSecurityList);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.h b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.h
new file mode 100644
index 0000000000..fb6c4969dd
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.h
@@ -0,0 +1,67 @@
+/** @file
+Definition of Pei Core Structures and Services
+
+Copyright (c) 2013 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _PEI_FV_SECURITY_H_
+#define _PEI_FV_SECURITY_H_
+
+#include <Ppi/FirmwareVolume.h>
+#include <Ppi/FirmwareVolumeInfo.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+/**
+  Callback function to perform FV security checking on a FV Info PPI.
+
+  @param PeiServices       An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
+  @param NotifyDescriptor  Address of the notification descriptor data structure.
+  @param Ppi               Address of the PPI that was installed.
+
+  @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EFIAPI
+FirmwareVolmeInfoPpiNotifySecurityCallback (
+  IN EFI_PEI_SERVICES              **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR     *NotifyDescriptor,
+  IN VOID                          *Ppi
+  );
+
+/**
+  Authenticates the Firmware Volume
+
+  @param CurrentFvAddress   Pointer to the current Firmware Volume under consideration
+
+  @retval EFI_SUCCESS       Firmware Volume is legal
+
+**/
+EFI_STATUS
+PeiSecurityVerifyFv (
+  IN EFI_FIRMWARE_VOLUME_HEADER  *CurrentFvAddress
+  );
+
+/**
+
+  Entry point for the PEI Security PEIM
+  Sets up a notification to perform PEI security checking
+
+  @param  FfsHeader    Not used.
+  @param  PeiServices  General purpose services available to every PEIM.
+
+  @return EFI_SUCCESS  PEI Security notification installed successfully.
+          All others: PEI Security notification failed to install.
+
+**/
+EFI_STATUS
+PeiInitializeFvSecurity (
+  VOID
+  );
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.c b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.c
new file mode 100644
index 0000000000..afc6e71d5f
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.c
@@ -0,0 +1,1227 @@
+/** @file
+This PEIM initialize platform for MRC, following action is performed,
+1. Initizluize GMCH
+2. Detect boot mode
+3. Detect video adapter to determine whether we need pre allocated memory
+4. Calls MRC to initialize memory and install a PPI notify to do post memory initialization.
+This file contains the main entrypoint of the PEIM.
+
+Copyright (c) 2013 - 2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "CommonHeader.h"
+#include "PlatformEarlyInit.h"
+#include "PeiFvSecurity.h"
+
+EFI_STATUS
+EFIAPI
+EndOfPeiSignalPpiNotifyCallback (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+  );
+
+//
+// Function prototypes to routines implemented in other source modules
+// within this component.
+//
+
+EFI_STATUS
+EFIAPI
+PlatformErratasPostMrc (
+  VOID
+  );
+
+//
+// The global indicator, the FvFileLoader callback will modify it to TRUE after loading PEIM into memory
+//
+BOOLEAN ImageInMemory = FALSE;
+
+BOARD_LEGACY_GPIO_CONFIG      mBoardLegacyGpioConfigTable[]  = { PLATFORM_LEGACY_GPIO_TABLE_DEFINITION };
+UINTN                         mBoardLegacyGpioConfigTableLen = (sizeof(mBoardLegacyGpioConfigTable) / sizeof(BOARD_LEGACY_GPIO_CONFIG));
+BOARD_GPIO_CONTROLLER_CONFIG  mBoardGpioControllerConfigTable[]  = { PLATFORM_GPIO_CONTROLLER_CONFIG_DEFINITION };
+UINTN                         mBoardGpioControllerConfigTableLen = (sizeof(mBoardGpioControllerConfigTable) / sizeof(BOARD_GPIO_CONTROLLER_CONFIG));
+UINT8                         ChipsetDefaultMac [6] = {0xff,0xff,0xff,0xff,0xff,0xff};
+
+EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[1] = {
+  {
+    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+    &gEfiPeiMasterBootModePpiGuid,
+    NULL
+  }
+};
+
+EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList[1] = {
+  {
+    (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+    &gEfiPeiMemoryDiscoveredPpiGuid,
+    MemoryDiscoveredPpiNotifyCallback
+  }
+};
+
+EFI_PEI_NOTIFY_DESCRIPTOR mEndOfPeiSignalPpiNotifyList[1] = {
+  {
+    (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+    &gEfiEndOfPeiSignalPpiGuid,
+    EndOfPeiSignalPpiNotifyCallback
+  }
+};
+
+EFI_PEI_STALL_PPI mStallPpi = {
+  PEI_STALL_RESOLUTION,
+  Stall
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPpiStall[1] = {
+  {
+    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+    &gEfiPeiStallPpiGuid,
+    &mStallPpi
+  }
+};
+
+/**
+  Set Mac address on chipset ethernet device.
+
+  @param  Bus      PCI Bus number of chipset ethernet device.
+  @param  Device   Device number of chipset ethernet device.
+  @param  Func     PCI Function number of chipset ethernet device.
+  @param  MacAddr  MAC Address to set.
+
+**/
+VOID
+EFIAPI
+SetLanControllerMacAddr (
+  IN CONST UINT8                          Bus,
+  IN CONST UINT8                          Device,
+  IN CONST UINT8                          Func,
+  IN CONST UINT8                          *MacAddr,
+  IN CONST UINT32                         Bar0
+  )
+{
+  UINT32                            Data32;
+  UINT16                            PciVid;
+  UINT16                            PciDid;
+  UINT32                            Addr;
+  UINT32                            MacVer;
+  volatile UINT8                    *Wrote;
+  UINT32                            DevPcieAddr;
+  UINT16                            SaveCmdReg;
+  UINT32                            SaveBarReg;
+
+  DevPcieAddr = PCI_LIB_ADDRESS (
+                  Bus,
+                  Device,
+                  Func,
+                  0
+                  );
+
+  //
+  // Do nothing if not a supported device.
+  //
+  PciVid = PciRead16 (DevPcieAddr + PCI_VENDOR_ID_OFFSET);
+  PciDid = PciRead16 (DevPcieAddr + PCI_DEVICE_ID_OFFSET);
+  if((PciVid != V_IOH_MAC_VENDOR_ID) || (PciDid != V_IOH_MAC_DEVICE_ID)) {
+    return;
+  }
+
+  //
+  // Save current settings for PCI CMD/BAR registers
+  //
+  SaveCmdReg = PciRead16 (DevPcieAddr + PCI_COMMAND_OFFSET);
+  SaveBarReg = PciRead32 (DevPcieAddr + R_IOH_MAC_MEMBAR);
+
+  //
+  // Use predefined temporary memory resource
+  //
+  PciWrite32 ( DevPcieAddr + R_IOH_MAC_MEMBAR, Bar0);
+  PciWrite8 ( DevPcieAddr + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
+
+  Addr =  Bar0 + R_IOH_MAC_GMAC_REG_8;
+  MacVer = *((volatile UINT32 *) (UINTN)(Addr));
+
+  DEBUG ((EFI_D_INFO, "Ioh MAC [B:%d, D:%d, F:%d] VER:%04x ADDR:",
+    (UINTN) Bus,
+    (UINTN) Device,
+    (UINTN) Func,
+    (UINTN) MacVer
+    ));
+
+  //
+  // Set MAC Address0 Low Register (GMAC_REG_17) ADDRLO bits.
+  //
+  Addr =  Bar0 + R_IOH_MAC_GMAC_REG_17;
+  Data32 = *((UINT32 *) (UINTN)(&MacAddr[0]));
+  *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+  Wrote = (volatile UINT8 *) (UINTN)(Addr);
+  DEBUG ((EFI_D_INFO, "%02x-%02x-%02x-%02x-",
+    (UINTN) Wrote[0],
+    (UINTN) Wrote[1],
+    (UINTN) Wrote[2],
+    (UINTN) Wrote[3]
+    ));
+
+  //
+  // Set MAC Address0 High Register (GMAC_REG_16) ADDRHI bits
+  // and Address Enable (AE) bit.
+  //
+  Addr =  Bar0 + R_IOH_MAC_GMAC_REG_16;
+  Data32 =
+    ((UINT32) MacAddr[4]) |
+    (((UINT32)MacAddr[5]) << 8) |
+    B_IOH_MAC_AE;
+  *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+  Wrote = (volatile UINT8 *) (UINTN)(Addr);
+
+  DEBUG ((EFI_D_INFO, "%02x-%02x\n", (UINTN) Wrote[0], (UINTN) Wrote[1]));
+
+  //
+  // Restore settings for PCI CMD/BAR registers
+  //
+  PciWrite32 ((DevPcieAddr + R_IOH_MAC_MEMBAR), SaveBarReg);
+  PciWrite16 (DevPcieAddr + PCI_COMMAND_OFFSET, SaveCmdReg);
+}
+
+/**
+  Initialize state of I2C GPIO expanders.
+
+  @param  PlatformType  Platform type for GPIO expander init.
+
+**/
+EFI_STATUS
+EarlyPlatformConfigGpioExpanders (
+  IN CONST EFI_PLATFORM_TYPE              PlatformType,
+  EFI_BOOT_MODE                           BootMode
+  )
+{
+  EFI_STATUS              Status;
+  EFI_I2C_DEVICE_ADDRESS  I2CSlaveAddress;
+  UINTN                   Length;
+  UINTN                   ReadLength;
+  UINT8                   Buffer[2];
+
+  //
+  // Configure GPIO expanders for Galileo Gen 2
+  // Route I2C pins to Arduino header
+  // Set all GPIO expander pins connected to the Reset Button as inputs
+  //
+  if (PlatformType == GalileoGen2) {
+    //
+    // Configure AMUX1_IN (EXP2.P1_4) as an output
+    //
+    PlatformPcal9555GpioSetDir (
+      GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR,  // IO Expander 2.
+      12,                                   // P1-4.
+      FALSE                                 // Configure as output
+      );
+
+    //
+    // Set AMUX1_IN(EXP2.P1_4) low to route I2C to Arduino Shield connector
+    //
+    PlatformPcal9555GpioSetLevel (
+      GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR,  // IO Expander 2.
+      12,                                   // P1-4. 
+      FALSE                                 // Set pin low
+      );
+
+    //
+    // Configure Reset Button(EXP1.P1_7) as an input
+    //
+    PlatformPcal9555GpioSetDir (
+      GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR,  // IO Expander 1.
+      15,                                   // P1-7.
+      TRUE
+      );
+
+    //
+    // Disable pullup on Reset Button(EXP1.P1_7)
+    //
+    PlatformPcal9555GpioDisablePull (
+      GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR,  // IO Expander 1.
+      15                                    // P1-7.
+      );
+
+    //
+    // Configure Reset Button(EXP2.P1_7) as an input
+    //
+    PlatformPcal9555GpioSetDir (
+      GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR,  // IO Expander 2.
+      15,                                   // P1-7.
+      TRUE
+      );
+
+    //
+    // Disable pullup on Reset Button(EXP2.P1_7)
+    //
+    PlatformPcal9555GpioDisablePull (
+      GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR,  // IO Expander 2.
+      15                                    // P1-7.
+      );
+
+    if (BootMode != BOOT_IN_RECOVERY_MODE) {
+      //
+      // Read state of Reset Button - EXP2.P1_7
+      // This GPIO is pulled high when the button is not pressed
+      // This GPIO reads low when button is pressed
+      //
+      if (!PlatformPcal9555GpioGetState (
+             GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR,  // IO Expander 2
+             15                                    // P1-7
+             )) {
+        DEBUG ((EFI_D_INFO, "  Force Recovery mode and reset\n"));
+
+        //
+        // Set 'B_CFG_STICKY_RW_FORCE_RECOVERY' sticky bit so we know we need to do a recovery following warm reset
+        //
+        QNCAltPortWrite (
+          QUARK_SCSS_SOC_UNIT_SB_PORT_ID,
+          QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW,
+          QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW) | B_CFG_STICKY_RW_FORCE_RECOVERY
+          );
+        ResetWarm();
+      }
+    }
+  }
+
+  //
+  // Configure GPIO expanders for Galileo Gen 2
+  // Set all GPIO expander pins connected to the Reset Button as inputs
+  // Route I2C pins to Arduino header
+  //
+  if (PlatformType == Galileo) {
+    //
+    // Detect the I2C Slave Address of the GPIO Expander
+    //
+    if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) {
+      I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2HI_7BIT_SLAVE_ADDR;
+    } else {
+      I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2LO_7BIT_SLAVE_ADDR;
+    }
+    DEBUG ((EFI_D_INFO, "Galileo GPIO Expender Slave Address = %02x\n", I2CSlaveAddress.I2CDeviceAddress));
+
+    //
+    // Set I2C_MUX (GPORT1_BIT5) low to route I2C to Arduino Shield connector
+    //
+
+    //
+    // Select GPIO Expander GPORT1
+    //
+    Length = 2;
+    Buffer[0] = 0x18; //sub-address
+    Buffer[1] = 0x01; //data
+    Status = I2cWriteMultipleByte (
+      I2CSlaveAddress,
+      EfiI2CSevenBitAddrMode,
+      &Length,
+      &Buffer
+      );
+    ASSERT_EFI_ERROR (Status);
+
+    //
+    // Read "Pin Direction" of GPIO Expander GPORT1
+    //
+    Length = 1;
+    ReadLength = 1;
+    Buffer[1] = 0x1C;
+    Status = I2cReadMultipleByte (
+      I2CSlaveAddress,
+      EfiI2CSevenBitAddrMode,
+      &Length,
+      &ReadLength,
+      &Buffer[1]
+      );
+    ASSERT_EFI_ERROR (Status);
+
+    //
+    // Configure GPIO Expander GPORT1_BIT5 as an output
+    //
+    Length = 2;
+    Buffer[0] = 0x1C; //sub-address
+    Buffer[1] = (UINT8)(Buffer[1] & (~BIT5)); //data
+
+    Status = I2cWriteMultipleByte (
+      I2CSlaveAddress,
+      EfiI2CSevenBitAddrMode,
+      &Length,
+      &Buffer
+      );
+    ASSERT_EFI_ERROR (Status);
+
+    //
+    // Set GPIO Expander GPORT1_BIT5 low
+    //
+    Length = 2;
+    Buffer[0] = 0x09; //sub-address
+    Buffer[1] = (UINT8)(~BIT5); //data
+
+    Status = I2cWriteMultipleByte (
+      I2CSlaveAddress,
+      EfiI2CSevenBitAddrMode,
+      &Length,
+      &Buffer
+      );
+    ASSERT_EFI_ERROR (Status);
+
+    //
+    // Configure RESET_N_SHLD (GPORT5_BIT0) and SW_RESET_N_SHLD (GPORT5_BIT1) as inputs
+    //
+
+    //
+    // Select GPIO Expander GPORT5
+    //
+    Length = 2;
+    Buffer[0] = 0x18;
+    Buffer[1] = 0x05;
+    Status = I2cWriteMultipleByte (
+      I2CSlaveAddress,
+      EfiI2CSevenBitAddrMode,
+      &Length,
+      &Buffer
+      );
+    ASSERT_EFI_ERROR (Status);
+
+    //
+    // Read "Pin Direction" of GPIO Expander GPORT5
+    //
+    Length = 1;
+    ReadLength = 1;
+    Buffer[1] = 0x1C;
+    Status = I2cReadMultipleByte (
+      I2CSlaveAddress,
+      EfiI2CSevenBitAddrMode,
+      &Length,
+      &ReadLength,
+      &Buffer[1]
+      );
+    ASSERT_EFI_ERROR (Status);
+
+    //
+    // Configure GPIO Expander GPORT5_BIT0 and GPORT5_BIT1 as inputs
+    //
+    Length = 2;
+    Buffer[0] = 0x1C;
+    Buffer[1] = Buffer[1] | BIT0 | BIT1;
+    Status = I2cWriteMultipleByte (
+      I2CSlaveAddress,
+      EfiI2CSevenBitAddrMode,
+      &Length,
+      &Buffer
+      );
+    ASSERT_EFI_ERROR (Status);
+
+    if (BootMode != BOOT_IN_RECOVERY_MODE) {
+      //
+      // Read state of RESET_N_SHLD (GPORT5_BIT0)
+      //
+      Buffer[1] = 5;
+      Length = 1;
+      ReadLength = 1;
+      Status = I2cReadMultipleByte (
+                 I2CSlaveAddress,
+                 EfiI2CSevenBitAddrMode,
+                 &Length,
+                 &ReadLength,
+                 &Buffer[1]
+                 );
+      ASSERT_EFI_ERROR (Status);
+
+      //
+      // Return the state of GPORT5_BIT0
+      //
+      if ((Buffer[1] & BIT0) == 0) {
+        DEBUG ((EFI_D_INFO, "  Force Recovery mode and reset\n"));
+
+        //
+        // Set 'B_CFG_STICKY_RW_FORCE_RECOVERY' sticky bit so we know we need to do a recovery following warm reset
+        //
+        QNCAltPortWrite (
+          QUARK_SCSS_SOC_UNIT_SB_PORT_ID,
+          QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW,
+          QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW) | B_CFG_STICKY_RW_FORCE_RECOVERY
+          );
+        ResetWarm();
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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
+PeiInitPlatform (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  EFI_STATUS                              Status;
+  EFI_BOOT_MODE                           BootMode;
+  EFI_PEI_STALL_PPI                       *StallPpi;
+  EFI_PEI_PPI_DESCRIPTOR                  *StallPeiPpiDescriptor;
+  EFI_FV_FILE_INFO                        FileInfo;
+  EFI_PLATFORM_TYPE                       PlatformType;
+
+  PlatformType = (EFI_PLATFORM_TYPE)PcdGet16 (PcdPlatformType);
+
+  //
+  // Initialize Firmware Volume security.
+  // This must be done before any firmware volume accesses (excl. BFV)
+  //
+  Status = PeiInitializeFvSecurity();
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Do any early platform specific initialization.
+  //
+  EarlyPlatformInit ();
+
+  //
+  // This is a second path on entry, in recovery boot path the Stall PPI need to be memory-based
+  // to improve recovery performance.
+  //
+  Status = PeiServicesFfsGetFileInfo (FileHandle, &FileInfo);
+  ASSERT_EFI_ERROR (Status);
+  //
+  // The follow conditional check only works for memory-mapped FFS,
+  // so we ASSERT that the file is really a MM FFS.
+  //
+  ASSERT (FileInfo.Buffer != NULL);
+  if (!(((UINTN) FileInfo.Buffer <= (UINTN) PeiInitPlatform) &&
+        ((UINTN) PeiInitPlatform <= (UINTN) FileInfo.Buffer + FileInfo.BufferSize))) {
+    //
+    // Now that module in memory, update the
+    // PPI that describes the Stall to other modules
+    //
+    Status = PeiServicesLocatePpi (
+               &gEfiPeiStallPpiGuid,
+               0,
+               &StallPeiPpiDescriptor,
+               (VOID **) &StallPpi
+               );
+
+    if (!EFI_ERROR (Status)) {
+
+      Status = PeiServicesReInstallPpi (
+                 StallPeiPpiDescriptor,
+                 &mPpiStall[0]
+                 );
+    } else {
+
+      Status = PeiServicesInstallPpi (&mPpiStall[0]);
+    }
+    return Status;
+  }
+
+  //
+  // Initialize System Phys
+  //
+
+  // Program USB Phy
+  InitializeUSBPhy();
+
+  //
+  // Do platform specific logic to create a boot mode
+  //
+  Status = UpdateBootMode ((EFI_PEI_SERVICES**)PeiServices, &BootMode);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Signal possible dependent modules that there has been a
+  // final boot mode determination
+  //
+  if (!EFI_ERROR(Status)) {
+    Status = PeiServicesInstallPpi (&mPpiBootMode[0]);
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  if (BootMode != BOOT_ON_S3_RESUME) {
+    QNCClearSmiAndWake ();
+  }
+
+  DEBUG ((EFI_D_INFO, "MRC Entry\n"));
+  MemoryInit ((EFI_PEI_SERVICES**)PeiServices);
+
+  //
+  // Do Early PCIe init.
+  //
+  DEBUG ((EFI_D_INFO, "Early PCIe controller initialization\n"));
+  PlatformPciExpressEarlyInit (PlatformType);
+
+
+  DEBUG ((EFI_D_INFO, "Platform Erratas After MRC\n"));
+  PlatformErratasPostMrc ();
+
+  //
+  //
+  //
+  DEBUG ((EFI_D_INFO, "EarlyPlatformConfigGpioExpanders ()\n"));
+  EarlyPlatformConfigGpioExpanders (PlatformType, BootMode);
+
+  //
+  // Now that all of the pre-permanent memory activities have
+  // been taken care of, post a call-back for the permanent-memory
+  // resident services, such as HOB construction.
+  // PEI Core will switch stack after this PEIM exit.  After that the MTRR
+  // can be set.
+  //
+  Status = PeiServicesNotifyPpi (&mMemoryDiscoveredNotifyList[0]);
+  ASSERT_EFI_ERROR (Status);
+/*
+
+  if (BootMode != BOOT_ON_S3_RESUME) {
+    Status = PeiServicesNotifyPpi (mEndOfPeiSignalPpiNotifyList);
+    ASSERT_EFI_ERROR (Status);
+  }
+*/
+  if (BootMode == BOOT_IN_RECOVERY_MODE) {
+    PeiServicesRegisterForShadow (FileHandle);
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+EndOfPeiSignalPpiNotifyCallback (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+  )
+{
+  EFI_STATUS                            Status;
+
+  DEBUG ((EFI_D_INFO, "End of PEI Signal Callback\n"));
+
+    //
+  // Restore the flash region to be UC
+  // for both normal boot as we build a Resource Hob to
+  // describe this region as UC to DXE core.
+  //
+  WriteBackInvalidateDataCacheRange (
+    (VOID *) (UINTN) PcdGet32 (PcdFlashAreaBaseAddress),
+    PcdGet32 (PcdFlashAreaSize)
+  );
+
+  Status = MtrrSetMemoryAttribute (PcdGet32 (PcdFlashAreaBaseAddress), PcdGet32 (PcdFlashAreaSize), CacheUncacheable);
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function will initialize USB Phy registers associated with QuarkSouthCluster.
+
+  @param  VOID                  No Argument
+
+  @retval EFI_SUCCESS           All registers have been initialized
+**/
+VOID
+EFIAPI
+InitializeUSBPhy (
+    VOID
+   )
+{
+    UINT32 RegData32;
+
+    /** In order to configure the PHY to use clk120 (ickusbcoreclk) as PLL reference clock
+     *  and Port2 as a USB device port, the following sequence must be followed
+     *
+     **/
+
+    // Sideband register write to USB AFE (Phy)
+    RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_GLOBAL_PORT);
+    RegData32 &= ~(BIT1);
+    //
+    // Sighting #4930631 PDNRESCFG [8:7] of USB2_GLOBAL_PORT = 11b.
+    // For port 0 & 1 as host and port 2 as device.
+    //
+    RegData32 |= (BIT8 | BIT7);
+    QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_GLOBAL_PORT, RegData32);
+
+    //
+    // Sighting #4930653 Required BIOS change on Disconnect vref to change to 600mV.
+    //
+    RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_COMPBG);
+    RegData32 &= ~(BIT10 | BIT9 | BIT8 | BIT7);
+    RegData32 |= (BIT10 | BIT7);
+    QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_COMPBG, RegData32);
+
+    // Sideband register write to USB AFE (Phy)
+    // (pllbypass) to bypass/Disable PLL before switch
+    RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2);
+    RegData32 |= BIT29;
+    QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2, RegData32);
+
+    // Sideband register write to USB AFE (Phy)
+    // (coreclksel) to select 120MHz (ickusbcoreclk) clk source.
+    // (Default 0 to select 96MHz (ickusbclk96_npad/ppad))
+    RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL1);
+    RegData32 |= BIT1;
+    QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL1, RegData32);
+
+    // Sideband register write to USB AFE (Phy)
+    // (divide by 8) to achieve internal 480MHz clock
+    // for 120MHz input refclk.  (Default: 4'b1000 (divide by 10) for 96MHz)
+    RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL1);
+    RegData32 &= ~(BIT5 | BIT4 | BIT3);
+    RegData32 |= BIT6;
+    QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL1, RegData32);
+
+    // Sideband register write to USB AFE (Phy)
+    // Clear (pllbypass)
+    RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2);
+    RegData32 &= ~BIT29;
+    QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2, RegData32);
+
+    // Sideband register write to USB AFE (Phy)
+    // Set (startlock) to force the PLL FSM to restart the lock
+    // sequence due to input clock/freq switch.
+    RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2);
+    RegData32 |= BIT24;
+    QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2, RegData32);
+
+    // At this point the PLL FSM and COMP FSM will complete
+
+}
+
+/**
+  This function provides early platform Thermal sensor initialisation.
+**/
+VOID
+EFIAPI
+EarlyPlatformThermalSensorInit (
+  VOID
+  )
+{
+  DEBUG ((EFI_D_INFO, "Early Platform Thermal Sensor Init\n"));
+
+  //
+  // Set Thermal sensor mode.
+  //
+  QNCThermalSensorSetRatiometricMode ();
+
+  //
+  // Enable RMU Thermal sensor with a Catastrophic Trip point.
+  //
+  QNCThermalSensorEnableWithCatastrophicTrip (PLATFORM_CATASTROPHIC_TRIP_CELSIUS);
+
+  //
+  // Lock all RMU Thermal sensor control & trip point registers.
+  //
+  QNCThermalSensorLockAllRegisters ();
+}
+
+/**
+  Print early platform info messages includeing the Stage1 module that's
+  running, MFH item list and platform data item list.
+**/
+VOID
+EFIAPI
+EarlyPlatformInfoMessages (
+  VOID
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  QUARK_EDKII_STAGE1_HEADER       *Edk2ImageHeader;
+
+  //
+  // Find which 'Stage1' image we are running and print the details
+  //
+  Edk2ImageHeader = (QUARK_EDKII_STAGE1_HEADER *) PcdGet32 (PcdEsramStage1Base);
+  DEBUG ((EFI_D_INFO, "\n************************************************************\n"));
+
+  switch ((UINT8)Edk2ImageHeader->ImageIndex & QUARK_STAGE1_IMAGE_TYPE_MASK) {
+    case QUARK_STAGE1_BOOT_IMAGE_TYPE:
+      DEBUG ((EFI_D_INFO, "****  Quark EDKII Stage 1 Boot Image %d                ****\n", ((UINT8)Edk2ImageHeader->ImageIndex & ~(QUARK_STAGE1_IMAGE_TYPE_MASK))));
+      break;
+
+    case QUARK_STAGE1_RECOVERY_IMAGE_TYPE:
+      DEBUG ((EFI_D_INFO, "****  Quark EDKII Stage 1 Recovery Image %d            ****\n", ((UINT8)Edk2ImageHeader->ImageIndex & ~(QUARK_STAGE1_IMAGE_TYPE_MASK))));
+      break;
+
+    default:
+      DEBUG ((EFI_D_INFO, "****  Quark EDKII Unknown Stage 1 Image !!!!           ****\n"));
+      break;
+  }
+  DEBUG (
+    (EFI_D_INFO,
+    "****  Quark EDKII Stage 2 Image 0x%08X:0x%08X ****\n" ,
+    (UINTN) PcdGet32 (PcdFlashFvMainBase),
+    (UINTN) PcdGet32 (PcdFlashFvMainSize)
+    ));
+
+  DEBUG (
+    (EFI_D_INFO,
+    "****  Quark EDKII Payload Image 0x%08X:0x%08X ****\n" ,
+    (UINTN) PcdGet32 (PcdFlashFvPayloadBase),
+    (UINTN) PcdGet32 (PcdFlashFvPayloadSize)
+    ));
+
+  DEBUG ((EFI_D_INFO, "************************************************************\n\n"));
+
+  DEBUG_CODE_END ();
+}
+
+/**
+  Check if system reset due to error condition.
+
+  @param  ClearErrorBits  If TRUE clear error flags and value bits.
+
+  @retval TRUE  if system reset due to error condition.
+  @retval FALSE if NO reset error conditions.
+**/
+BOOLEAN
+CheckForResetDueToErrors (
+  IN BOOLEAN                              ClearErrorBits
+  )
+{
+  UINT32                            RegValue;
+  BOOLEAN                           ResetDueToError;
+
+  ResetDueToError = FALSE;
+
+  //
+  // Check if RMU reset system due to access violations.
+  // RMU updates a SOC Unit register before resetting the system.
+  //
+  RegValue = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW);
+  if ((RegValue & B_CFG_STICKY_RW_VIOLATION) != 0) {
+    ResetDueToError = TRUE;
+
+    DEBUG (
+      (EFI_D_ERROR,
+      "\nReset due to access violation: %s %s %s %s\n",
+      ((RegValue & B_CFG_STICKY_RW_IMR_VIOLATION) != 0) ? L"'IMR'" : L".",
+      ((RegValue & B_CFG_STICKY_RW_DECC_VIOLATION) != 0) ? L"'DECC'" : L".",
+      ((RegValue & B_CFG_STICKY_RW_SMM_VIOLATION) != 0) ? L"'SMM'" : L".",
+      ((RegValue & B_CFG_STICKY_RW_HMB_VIOLATION) != 0) ? L"'HMB'" : L"."
+      ));
+
+    //
+    // Clear error bits.
+    //
+    if (ClearErrorBits) {
+      RegValue &= ~(B_CFG_STICKY_RW_VIOLATION);
+      QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW, RegValue);
+    }
+  }
+
+  return ResetDueToError;
+}
+
+/**
+  This function provides early platform initialization.
+
+  @param  PlatformInfo  Pointer to platform Info structure.
+
+**/
+VOID
+EFIAPI
+EarlyPlatformInit (
+  VOID
+  )
+{
+  EFI_PLATFORM_TYPE                 PlatformType;
+
+  PlatformType = (EFI_PLATFORM_TYPE) PcdGet16 (PcdPlatformType);
+
+  DEBUG ((EFI_D_INFO, "EarlyPlatformInit for PlatType=0x%02x\n", (UINTN) PlatformType));
+
+  //
+  // Check if system reset due to error condition.
+  //
+  if (CheckForResetDueToErrors (TRUE)) {
+    if(FeaturePcdGet (WaitIfResetDueToError)) {
+      DEBUG ((EFI_D_ERROR, "Wait 10 seconds.\n"));
+      MicroSecondDelay(10000000);
+    }
+  }
+
+  //
+  // Display platform info messages.
+  //
+  EarlyPlatformInfoMessages ();
+
+  //
+  // Early Legacy Gpio Init.
+  //
+  EarlyPlatformLegacyGpioInit (PlatformType);
+
+  //
+  // Early platform Legacy GPIO manipulation depending on GPIOs
+  // setup by EarlyPlatformLegacyGpioInit.
+  //
+  EarlyPlatformLegacyGpioManipulation (PlatformType);
+
+  //
+  // Early platform specific GPIO Controller init & manipulation.
+  // Combined for sharing of temp. memory bar.
+  //
+  EarlyPlatformGpioCtrlerInitAndManipulation (PlatformType);
+
+  //
+  // Early Thermal Sensor Init.
+  //
+  EarlyPlatformThermalSensorInit ();
+
+  //
+  // Early Lan Ethernet Mac Init.
+  //
+  EarlyPlatformMacInit (
+    PcdGetPtr (PcdIohEthernetMac0),
+    PcdGetPtr (PcdIohEthernetMac1)
+    );
+}
+
+/**
+  This function provides early platform Legacy GPIO initialisation.
+
+  @param  PlatformType  Platform type for GPIO init.
+
+**/
+VOID
+EFIAPI
+EarlyPlatformLegacyGpioInit (
+  IN CONST EFI_PLATFORM_TYPE              PlatformType
+  )
+{
+  BOARD_LEGACY_GPIO_CONFIG          *LegacyGpioConfig;
+  UINT32                            NewValue;
+  UINT32                            GpioBaseAddress;
+
+  //
+  // Assert if platform type outside table range.
+  //
+  ASSERT ((UINTN) PlatformType < mBoardLegacyGpioConfigTableLen);
+  LegacyGpioConfig = &mBoardLegacyGpioConfigTable[(UINTN) PlatformType];
+
+  GpioBaseAddress = (UINT32)PcdGet16 (PcdGbaIoBaseAddress);
+
+  NewValue     = 0x0;
+  //
+  // Program QNC GPIO Registers.
+  //
+  NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGEN_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellEnable;
+  IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGEN_CORE_WELL, NewValue );
+  NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGIO_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellIoSelect;
+  IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGIO_CORE_WELL, NewValue);
+  NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGLVL_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellLvlForInputOrOutput;
+  IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGLVL_CORE_WELL, NewValue);
+  NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGTPE_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellTriggerPositiveEdge;
+  IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGTPE_CORE_WELL, NewValue );
+  NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGTNE_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellTriggerNegativeEdge;
+  IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGTNE_CORE_WELL, NewValue);
+  NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGGPE_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellGPEEnable;
+  IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGGPE_CORE_WELL, NewValue);
+  NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGSMI_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellSMIEnable;
+  IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGSMI_CORE_WELL, NewValue );
+  NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGTS_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellTriggerStatus;
+  IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGTS_CORE_WELL, NewValue);
+  NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CNMIEN_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellNMIEnable;
+  IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CNMIEN_CORE_WELL, NewValue);
+
+  NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGEN_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellEnable;
+  IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGEN_RESUME_WELL, NewValue );
+  NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGIO_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellIoSelect;
+  IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGIO_RESUME_WELL, NewValue) ;
+  NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGLVL_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellLvlForInputOrOutput;
+  IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGLVL_RESUME_WELL, NewValue);
+  NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGTPE_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellTriggerPositiveEdge;
+  IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGTPE_RESUME_WELL, NewValue );
+  NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGTNE_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellTriggerNegativeEdge;
+  IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGTNE_RESUME_WELL, NewValue) ;
+  NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGGPE_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellGPEEnable;
+  IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGGPE_RESUME_WELL, NewValue);
+  NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGSMI_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellSMIEnable;
+  IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGSMI_RESUME_WELL, NewValue );
+  NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGTS_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellTriggerStatus;
+  IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGTS_RESUME_WELL, NewValue) ;
+  NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RNMIEN_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellNMIEnable;
+  IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RNMIEN_RESUME_WELL, NewValue);
+}
+
+/**
+  Performs any early platform specific Legacy GPIO manipulation.
+
+  @param  PlatformType  Platform type GPIO manipulation.
+
+**/
+VOID
+EFIAPI
+EarlyPlatformLegacyGpioManipulation (
+  IN CONST EFI_PLATFORM_TYPE              PlatformType
+  )
+{
+  if (PlatformType == CrossHill) {
+
+    //
+    // Pull TPM reset low for 80us (equivalent to cold reset, Table 39
+    // Infineon SLB9645 Databook), then pull TPM reset high and wait for
+    // 150ms to give time for TPM to stabilise (Section 4.7.1 Infineon
+    // SLB9645 Databook states TPM is ready to receive command after 30ms
+    // but section 4.7 states some TPM commands may take longer to execute
+    // upto 150ms after test).
+    //
+
+    PlatformLegacyGpioSetLevel (
+      R_QNC_GPIO_RGLVL_RESUME_WELL,
+      PLATFORM_RESUMEWELL_TPM_RST_GPIO,
+      FALSE
+      );
+    MicroSecondDelay (80);
+
+    PlatformLegacyGpioSetLevel (
+      R_QNC_GPIO_RGLVL_RESUME_WELL,
+      PLATFORM_RESUMEWELL_TPM_RST_GPIO,
+      TRUE
+      );
+    MicroSecondDelay (150000);
+  }
+
+}
+
+/**
+  Performs any early platform specific GPIO Controller init & manipulation.
+
+  @param  PlatformType  Platform type for GPIO init & manipulation.
+
+**/
+VOID
+EFIAPI
+EarlyPlatformGpioCtrlerInitAndManipulation (
+  IN CONST EFI_PLATFORM_TYPE              PlatformType
+  )
+{
+  UINT32                            IohGpioBase;
+  UINT32                            Data32;
+  UINT32                            Addr;
+  BOARD_GPIO_CONTROLLER_CONFIG      *GpioConfig;
+  UINT32                            DevPcieAddr;
+  UINT16                            SaveCmdReg;
+  UINT32                            SaveBarReg;
+  UINT16                            PciVid;
+  UINT16                            PciDid;
+
+  ASSERT ((UINTN) PlatformType < mBoardGpioControllerConfigTableLen);
+  GpioConfig = &mBoardGpioControllerConfigTable[(UINTN) PlatformType];
+
+  IohGpioBase = (UINT32) PcdGet64 (PcdIohGpioMmioBase);
+
+  DevPcieAddr = PCI_LIB_ADDRESS (
+                  PcdGet8 (PcdIohGpioBusNumber),
+                  PcdGet8 (PcdIohGpioDevNumber),
+                  PcdGet8 (PcdIohGpioFunctionNumber),
+                  0
+                  );
+
+  //
+  // Do nothing if not a supported device.
+  //
+  PciVid = PciRead16 (DevPcieAddr + PCI_VENDOR_ID_OFFSET);
+  PciDid = PciRead16 (DevPcieAddr + PCI_DEVICE_ID_OFFSET);
+  if((PciVid != V_IOH_I2C_GPIO_VENDOR_ID) || (PciDid != V_IOH_I2C_GPIO_DEVICE_ID)) {
+    return;
+  }
+
+  //
+  // Save current settings for PCI CMD/BAR registers.
+  //
+  SaveCmdReg = PciRead16 (DevPcieAddr + PCI_COMMAND_OFFSET);
+  SaveBarReg = PciRead32 (DevPcieAddr + PcdGet8 (PcdIohGpioBarRegister));
+
+  //
+  // Use predefined temporary memory resource.
+  //
+  PciWrite32 ( DevPcieAddr + PcdGet8 (PcdIohGpioBarRegister), IohGpioBase);
+  PciWrite8 ( DevPcieAddr + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
+
+  //
+  // Gpio Controller Init Tasks.
+  //
+
+  //
+  // IEN- Interrupt Enable Register
+  //
+  Addr =  IohGpioBase + GPIO_INTEN;
+  Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
+  Data32 |= (GpioConfig->IntEn & 0x000FFFFF);
+  *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+
+  //
+  // ISTATUS- Interrupt Status Register
+  //
+  Addr =  IohGpioBase + GPIO_INTSTATUS;
+  Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
+  *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+
+  //
+  // GPIO SWPORTA Direction Register - GPIO_SWPORTA_DR
+  //
+  Addr =  IohGpioBase + GPIO_SWPORTA_DR;
+  Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
+  Data32 |= (GpioConfig->PortADR & 0x000FFFFF);
+  *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+
+  //
+  // GPIO SWPORTA Data Direction Register - GPIO_SWPORTA_DDR - default input
+  //
+  Addr =  IohGpioBase + GPIO_SWPORTA_DDR;
+  Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
+  Data32 |= (GpioConfig->PortADir & 0x000FFFFF);
+  *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+
+  //
+  // Interrupt Mask Register - GPIO_INTMASK - default interrupts unmasked
+  //
+  Addr =  IohGpioBase + GPIO_INTMASK;
+  Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
+  Data32 |= (GpioConfig->IntMask & 0x000FFFFF);
+  *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+
+  //
+  // Interrupt Level Type Register - GPIO_INTTYPE_LEVEL - default is level sensitive
+  //
+  Addr =  IohGpioBase + GPIO_INTTYPE_LEVEL;
+  Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
+  Data32 |= (GpioConfig->IntType & 0x000FFFFF);
+  *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+
+  //
+  // Interrupt Polarity Type Register - GPIO_INT_POLARITY - default is active low
+  //
+  Addr =  IohGpioBase + GPIO_INT_POLARITY;
+  Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
+  Data32 |= (GpioConfig->IntPolarity & 0x000FFFFF);
+  *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+
+  //
+  // Interrupt Debounce Type Register - GPIO_DEBOUNCE - default no debounce
+  //
+  Addr =  IohGpioBase + GPIO_DEBOUNCE;
+  Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
+  Data32 |= (GpioConfig->Debounce & 0x000FFFFF);
+  *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+
+  //
+  // Interrupt Clock Synchronisation Register - GPIO_LS_SYNC - default no sync with pclk_intr(APB bus clk)
+  //
+  Addr =  IohGpioBase + GPIO_LS_SYNC;
+  Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
+  Data32 |= (GpioConfig->LsSync & 0x000FFFFF);
+  *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+
+  //
+  // Gpio Controller Manipulation Tasks.
+  //
+
+  if (PlatformType == (EFI_PLATFORM_TYPE) Galileo) {
+    //
+    // Reset Cypress Expander on Galileo Platform
+    //
+    Addr = IohGpioBase + GPIO_SWPORTA_DR;
+    Data32 = *((volatile UINT32 *) (UINTN)(Addr));
+    Data32 |= BIT4;                                 // Cypress Reset line controlled by GPIO<4>
+    *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+
+    Data32 = *((volatile UINT32 *) (UINTN)(Addr));
+    Data32 &= ~BIT4;                                // Cypress Reset line controlled by GPIO<4>
+    *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+
+  }
+
+  //
+  // Restore settings for PCI CMD/BAR registers
+  //
+  PciWrite32 ((DevPcieAddr + PcdGet8 (PcdIohGpioBarRegister)), SaveBarReg);
+  PciWrite16 (DevPcieAddr + PCI_COMMAND_OFFSET, SaveCmdReg);
+}
+
+/**
+  Performs any early platform init of SoC Ethernet Mac devices.
+
+  @param  IohMac0Address  Mac address to program into Mac0 device.
+  @param  IohMac1Address  Mac address to program into Mac1 device.
+
+**/
+VOID
+EFIAPI
+EarlyPlatformMacInit (
+  IN CONST UINT8                          *IohMac0Address,
+  IN CONST UINT8                          *IohMac1Address
+  )
+{
+  BOOLEAN                           SetMacAddr;
+
+  //
+  // Set chipset MAC0 address if configured.
+  //
+  SetMacAddr =
+    (CompareMem (ChipsetDefaultMac, IohMac0Address, sizeof (ChipsetDefaultMac))) != 0;
+  if (SetMacAddr) {
+    if ((*(IohMac0Address) & BIT0) != 0) {
+      DEBUG ((EFI_D_ERROR, "HALT: Multicast Mac Address configured for Ioh MAC [B:%d, D:%d, F:%d]\n",
+        (UINTN) IOH_MAC0_BUS_NUMBER,
+        (UINTN) IOH_MAC0_DEVICE_NUMBER,
+        (UINTN) IOH_MAC0_FUNCTION_NUMBER
+        ));
+      ASSERT (FALSE);
+    } else {
+      SetLanControllerMacAddr (
+        IOH_MAC0_BUS_NUMBER,
+        IOH_MAC0_DEVICE_NUMBER,
+        IOH_MAC0_FUNCTION_NUMBER,
+        IohMac0Address,
+        (UINT32) PcdGet64(PcdIohMac0MmioBase)
+        );
+    }
+  } else {
+    DEBUG ((EFI_D_WARN, "WARNING: Ioh MAC [B:%d, D:%d, F:%d] NO HW ADDR CONFIGURED!!!\n",
+      (UINTN) IOH_MAC0_BUS_NUMBER,
+      (UINTN) IOH_MAC0_DEVICE_NUMBER,
+      (UINTN) IOH_MAC0_FUNCTION_NUMBER
+      ));
+  }
+
+  //
+  // Set chipset MAC1 address if configured.
+  //
+  SetMacAddr =
+    (CompareMem (ChipsetDefaultMac, IohMac1Address, sizeof (ChipsetDefaultMac))) != 0;
+  if (SetMacAddr) {
+    if ((*(IohMac1Address) & BIT0) != 0) {
+      DEBUG ((EFI_D_ERROR, "HALT: Multicast Mac Address configured for Ioh MAC [B:%d, D:%d, F:%d]\n",
+        (UINTN) IOH_MAC1_BUS_NUMBER,
+        (UINTN) IOH_MAC1_DEVICE_NUMBER,
+        (UINTN) IOH_MAC1_FUNCTION_NUMBER
+        ));
+      ASSERT (FALSE);
+    } else {
+        SetLanControllerMacAddr (
+          IOH_MAC1_BUS_NUMBER,
+          IOH_MAC1_DEVICE_NUMBER,
+          IOH_MAC1_FUNCTION_NUMBER,
+          IohMac1Address,
+          (UINT32) PcdGet64(PcdIohMac1MmioBase)
+          );
+    }
+  } else {
+    DEBUG ((EFI_D_WARN, "WARNING: Ioh MAC [B:%d, D:%d, F:%d] NO HW ADDR CONFIGURED!!!\n",
+      (UINTN) IOH_MAC1_BUS_NUMBER,
+      (UINTN) IOH_MAC1_DEVICE_NUMBER,
+      (UINTN) IOH_MAC1_FUNCTION_NUMBER
+      ));
+  }
+}
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.h b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.h
new file mode 100644
index 0000000000..84def44717
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.h
@@ -0,0 +1,301 @@
+/** @file
+The header file of Platform PEIM.
+
+Copyright (c) 2013 - 2019 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#ifndef __PLATFORM_EARLY_INIT_H__
+#define __PLATFORM_EARLY_INIT_H__
+
+#define PEI_STALL_RESOLUTION            1
+#define STALL_PEIM_SIGNATURE   SIGNATURE_32('p','p','u','s')
+
+typedef struct {
+  UINT32                      Signature;
+  EFI_FFS_FILE_HEADER         *FfsHeader;
+  EFI_PEI_NOTIFY_DESCRIPTOR   StallNotify;
+} STALL_CALLBACK_STATE_INFORMATION;
+
+#define STALL_PEIM_FROM_THIS(a) CR (a, STALL_CALLBACK_STATE_INFORMATION, StallNotify, STALL_PEIM_SIGNATURE)
+
+//
+// USB Phy Registers
+//
+#define USB2_GLOBAL_PORT  0x4001
+#define USB2_PLL1         0x7F02
+#define USB2_PLL2         0x7F03
+#define USB2_COMPBG       0x7F04
+
+/**
+  Peform the boot mode determination logic
+  If the box is closed, then
+    1. If it's first time to boot, it's boot with full config .
+    2. If the ChassisIntrution is selected, force to be a boot with full config
+    3. Otherwise it's boot with no change.
+
+  @param  PeiServices General purpose services available to every PEIM.
+
+  @param  BootMode The detected boot mode.
+
+  @retval EFI_SUCCESS if the boot mode could be set
+**/
+EFI_STATUS
+UpdateBootMode (
+  IN  EFI_PEI_SERVICES     **PeiServices,
+  OUT EFI_BOOT_MODE        *BootMode
+  );
+
+/**
+  This function reset the entire platform, including all processor and devices, and
+  reboots the system.
+
+  @param  PeiServices General purpose services available to every PEIM.
+
+  @retval EFI_SUCCESS if it completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+PlatformResetSystem (
+  IN CONST EFI_PEI_SERVICES          **PeiServices
+  );
+
+/**
+  This function will be called when MRC is done.
+
+  @param  PeiServices General purpose services available to every PEIM.
+
+  @param  NotifyDescriptor Information about the notify event..
+
+  @param  Ppi The notify context.
+
+  @retval EFI_SUCCESS If the function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+MemoryDiscoveredPpiNotifyCallback (
+  IN EFI_PEI_SERVICES                     **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR            *NotifyDescriptor,
+  IN VOID                                 *Ppi
+  );
+
+/**
+  This is the callback function notified by FvFileLoader PPI, it depends on FvFileLoader PPI to load
+  the PEIM into memory.
+
+  @param  PeiServices General purpose services available to every PEIM.
+  @param  NotifyDescriptor The context of notification.
+  @param  Ppi The notify PPI.
+
+  @retval EFI_SUCCESS if it completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+FvFileLoaderPpiNotifyCallback (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+  );
+
+/**
+  This function provides a blocking stall for reset at least the given number of microseconds
+  stipulated in the final argument.
+
+  @param  PeiServices General purpose services available to every PEIM.
+
+  @param  this Pointer to the local data for the interface.
+
+  @param  Microseconds number of microseconds for which to stall.
+
+  @retval EFI_SUCCESS the function provided at least the required stall.
+**/
+EFI_STATUS
+EFIAPI
+Stall (
+  IN CONST EFI_PEI_SERVICES   **PeiServices,
+  IN CONST EFI_PEI_STALL_PPI  *This,
+  IN UINTN                    Microseconds
+  );
+
+/**
+  This function initialize recovery functionality by installing the recovery PPI.
+
+  @param  PeiServices General purpose services available to every PEIM.
+
+  @retval EFI_SUCCESS if the interface could be successfully installed.
+**/
+EFI_STATUS
+EFIAPI
+PeimInitializeRecovery (
+  IN EFI_PEI_SERVICES     **PeiServices
+  );
+
+/**
+  This function
+    1. Calling MRC to initialize memory.
+    2. Install EFI Memory.
+    3. Create HOB of system memory.
+
+  @param  PeiServices Pointer to the PEI Service Table
+
+  @retval EFI_SUCCESS If it completes successfully.
+
+**/
+EFI_STATUS
+MemoryInit (
+  IN EFI_PEI_SERVICES          **PeiServices
+  );
+
+/** Return info derived from Installing Memory by MemoryInit.
+
+  @param[out]      RmuMainBaseAddressPtr   Return RmuMainBaseAddress to this location.
+  @param[out]      SmramDescriptorPtr  Return start of Smram descriptor list to this location.
+  @param[out]      NumSmramRegionsPtr  Return numbers of Smram regions to this location.
+
+  @return Address of RMU shadow region at the top of available memory.
+  @return List of Smram descriptors for each Smram region.
+  @return Numbers of Smram regions.
+**/
+VOID
+EFIAPI
+InfoPostInstallMemory (
+  OUT     UINT32                    *RmuMainBaseAddressPtr OPTIONAL,
+  OUT     EFI_SMRAM_DESCRIPTOR      **SmramDescriptorPtr OPTIONAL,
+  OUT     UINTN                     *NumSmramRegionsPtr OPTIONAL
+  );
+
+/**
+  This function provides the implementation of AtaController PPI Enable Channel function.
+
+  @param  PeiServices General purpose services available to every PEIM.
+  @param  this Pointer to the local data for the interface.
+  @param  ChannelMask This parameter is used to specify primary or slavery IDE channel.
+
+  @retval EFI_SUCCESS  Procedure returned successfully.
+**/
+
+EFI_STATUS
+EnableAtaChannel (
+  IN EFI_PEI_SERVICES               **PeiServices,
+  IN PEI_ATA_CONTROLLER_PPI         *This,
+  IN UINT8                          ChannelMask
+  );
+
+/**
+  This function provides the implementation of AtaController PPI Get IDE channel Register Base Address
+
+  @param  PeiServices      General purpose services available to every PEIM.
+  @param  this             Pointer to the local data for the interface.
+  @param  IdeRegsBaseAddr  Pointer to IDE_REGS_BASE_ADDR struct, which is used to record
+                           IDE Command and Control regeisters Base Address.
+
+  @retval EFI_SUCCESS  Procedure returned successfully.
+**/
+
+EFI_STATUS
+GetIdeRegsBaseAddr (
+  IN EFI_PEI_SERVICES               **PeiServices,
+  IN PEI_ATA_CONTROLLER_PPI         *This,
+  IN IDE_REGS_BASE_ADDR             *IdeRegsBaseAddr
+  );
+
+VOID
+EFIAPI
+InitializeUSBPhy (
+    VOID
+   );
+
+/**
+  This function provides early platform initialisation.
+
+  @param  PlatformInfo  Pointer to platform Info structure.
+
+**/
+VOID
+EFIAPI
+EarlyPlatformInit (
+  VOID
+  );
+
+/**
+  This function provides early platform GPIO initialisation.
+
+  @param  PlatformType  Platform type for GPIO init.
+
+**/
+VOID
+EFIAPI
+EarlyPlatformLegacyGpioInit (
+  IN CONST EFI_PLATFORM_TYPE              PlatformType
+  );
+
+/**
+  Performs any early platform specific GPIO manipulation.
+
+  @param  PlatformType  Platform type GPIO manipulation.
+
+**/
+VOID
+EFIAPI
+EarlyPlatformLegacyGpioManipulation (
+  IN CONST EFI_PLATFORM_TYPE              PlatformType
+  );
+
+/**
+  Performs any early platform specific GPIO Controller init & manipulation.
+
+  @param  PlatformType  Platform type for GPIO init & manipulation.
+
+**/
+VOID
+EFIAPI
+EarlyPlatformGpioCtrlerInitAndManipulation (
+  IN CONST EFI_PLATFORM_TYPE              PlatformType
+  );
+
+/**
+  Performs any early platform init of SoC Ethernet Mac devices.
+
+  @param  IohMac0Address  Mac address to program into Mac0 device.
+  @param  IohMac1Address  Mac address to program into Mac1 device.
+
+**/
+VOID
+EFIAPI
+EarlyPlatformMacInit (
+  IN CONST UINT8                          *IohMac0Address,
+  IN CONST UINT8                          *IohMac1Address
+  );
+
+/**
+  Find security headers using EFI_CAPSULE_VARIABLE_NAME variables and build Hobs.
+
+  @param PeiServices  General purpose services available to every PEIM.
+
+  @retval 0 if no security headers found.
+  @return number of security header hobs built.
+**/
+UINTN
+EFIAPI
+FindCapsuleSecurityHeadersAndBuildHobs (
+  IN EFI_PEI_SERVICES                     **PeiServices
+  );
+
+/**
+  Build capsule security header hob.
+
+  @param SecHdr  Pointer to security header.
+
+  @retval NULL if failure to build HOB.
+  @return pointer to built hob.
+**/
+VOID *
+EFIAPI
+BuildCapsuleSecurityHeaderHob (
+  IN VOID                                 *SecHdr
+  );
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.inf b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.inf
new file mode 100644
index 0000000000..df8b0dd3bd
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.inf
@@ -0,0 +1,193 @@
+## @file
+# This is the Platform PEIM to initialize whole platform on PEI phase.
+#
+# This PEIM includes 3 parts, pre memory initialization, MRC
+#  wrapper and post memory initialization.
+#  On pre memory, following action is performed,
+#  1. Initizluize GMCH.
+#  2. Detect boot mode.
+#  3. Detect video adapter to determine whether we need pre allocated
+#  memory.
+#
+#  After that MRC wrapper calls MRC to initialize memory and install a PPI
+#  notify to do post memory
+#  initialization. MRC wrapper performance following actions,
+#  1. Install EFI Memory.
+#  2. Create HOB of system memory.
+#
+#  On post memory, following action is performed,
+#  1. QNC initialization after MRC.
+#  2. SIO initialization.
+#  3. Install ResetSystem and FinvFv PPI, relocate Stall to memory on
+#   recovery boot mode.
+#  4. Set MTRR for PEI
+#  5. Create FV HOB and Flash HOB
+#  6. Install RecoveryModule and AtaController PPI if on recovery boot mode.
+#
+#  This PEIM does not have any register access directly, it depends on
+#  IntelQNCLib, QNCAccess libraries to access Chipset
+#  registers.
+#
+#  Platform.c - Provide main flow and entrypoint of PEIM.
+#  MemoryCallback.c - Includes a memory call back function notified when
+#     MRC is done.
+#  Recovery.c - provides the platform recoveyr functionality.
+#  MrcWrapper.c - Contains the logic to call MRC PPI and do Framework
+#     memory specific stuff like build memory map, build
+#     resource description hob for DXE phase,etc.
+#  Bootmode.c - Detect boot mode.
+# Copyright (c) 2013 - 2019 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformEarlyInitPei
+  FILE_GUID                      = 9618C0DC-50A4-496c-994F-7241F282ED01
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = PeiInitPlatform
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  Generic/Recovery.c
+  PlatformErratas.c
+  MrcWrapper.c
+  MrcWrapper.h
+  PlatformEarlyInit.c
+  PlatformEarlyInit.h
+  MemoryCallback.c
+  BootMode.c
+  CommonHeader.h
+  PeiFvSecurity.c
+  PeiFvSecurity.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  ResetSystemLib
+  PrintLib
+  TimerLib
+  PcdLib
+  IntelQNCLib
+  ReportStatusCodeLib
+  PciLib
+  PciExpressLib
+  IoLib
+  PciCf8Lib
+  HobLib
+  BaseMemoryLib
+  PeiServicesTablePointerLib
+  PeiServicesLib
+  BaseLib
+  PeimEntryPoint
+  DebugLib
+  MemoryAllocationLib
+  PerformanceLib
+  CacheMaintenanceLib
+  MtrrLib
+  QNCAccessLib
+  PlatformHelperLib
+  PlatformPcieHelperLib
+  I2cLib
+
+[Guids]
+  gEfiMemoryConfigDataGuid                      # ALWAYS_CONSUMED L"MemoryConfig"
+  gEfiAcpiVariableGuid                          # ALWAYS_CONSUMED L"AcpiGlobalVariab"
+  gEfiMemoryTypeInformationGuid                 # ALWAYS_CONSUMED L"MemoryTypeInformation"
+  gEfiMemoryConfigDataGuid                      # SOMETIMES_PRODUCED  Hob: GUID_EXTENSION
+  gEfiSmmPeiSmramMemoryReserveGuid              # ALWAYS_PRODUCED  Hob: GUID_EXTENSION
+  gEfiFirmwareFileSystem2Guid                   # ALWAYS_CONSUMED
+  gEfiCapsuleGuid                               # ALWAYS_CONSUMED
+  gPeiCapsuleOnDataCDGuid
+  gPeiCapsuleOnFatIdeDiskGuid
+  gPeiCapsuleOnFatUsbDiskGuid
+  gEfiMemoryOverwriteControlDataGuid            # SOMETIMES_CONSUMED
+  gEfiQuarkCapsuleGuid
+
+[Ppis]
+  gQNCMemoryInitPpiGuid                         # PPI ALWAYS_CONSUMED
+  gEfiPeiMemoryDiscoveredPpiGuid                # PPI ALWAYS_PRODUCED
+  gPeiAtaControllerPpiGuid                      # PPI SOMETIMES_PRODUCED
+  gEfiPeiStallPpiGuid                           # PPI ALWAYS_PRODUCED
+  gEfiPeiDeviceRecoveryModulePpiGuid            # PPI SOMETIMES_CONSUMED
+  gEfiPeiRecoveryModulePpiGuid                  # PPI SOMETIMES_PRODUCED
+  gEfiPeiResetPpiGuid                           # PPI ALWAYS_PRODUCED
+  gEfiPeiReadOnlyVariable2PpiGuid               # PPI ALWAYS_CONSUMED
+  gEfiPeiBootInRecoveryModePpiGuid              # PPI SOMETIMES_PRODUCED
+  gEfiPeiMasterBootModePpiGuid                  # PPI ALWAYS_PRODUCED
+  gEfiPeiFirmwareVolumeInfoPpiGuid
+  gEfiEndOfPeiSignalPpiGuid
+  gEfiPeiVirtualBlockIoPpiGuid
+  gPeiCapsulePpiGuid                            # PPI ALWAYS_CONSUMED
+
+[FeaturePcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdRecoveryOnFatUsbDisk
+  gEfiMdeModulePkgTokenSpaceGuid.PcdRecoveryOnDataCD
+  gEfiMdeModulePkgTokenSpaceGuid.PcdRecoveryOnFatFloppyDisk
+  gEfiMdeModulePkgTokenSpaceGuid.PcdRecoveryOnIdeDisk
+  gQuarkPlatformTokenSpaceGuid.WaitIfResetDueToError
+
+[Pcd]
+  gQuarkPlatformTokenSpaceGuid.PcdEsramStage1Base
+  gQuarkPlatformTokenSpaceGuid.PcdFlashAreaSize
+  gQuarkPlatformTokenSpaceGuid.PcdFlashAreaBaseAddress
+  gQuarkPlatformTokenSpaceGuid.PcdEccScrubBlkSize
+  gQuarkPlatformTokenSpaceGuid.PcdEccScrubInterval
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+  gQuarkPlatformTokenSpaceGuid.PcdFlashQNCMicrocodeSize
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPmbaIoBaseAddress
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeIoBase
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeIoSize
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohUartFunctionNumber
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohUartBusNumber
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohUartDevNumber
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioBusNumber
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioDevNumber
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioFunctionNumber
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioBarRegister
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioMmioBase
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohMac0MmioBase
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohMac1MmioBase
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdPeiQNCUsbControllerMemoryBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdRcbaMmioBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeMemory32Base
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeMemory32Size
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeMemory64Base
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeMemory64Size
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciExpressSize
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdGbaIoBaseAddress
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdQuarkMicrocodeFile
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdTSegSize
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdESramMemorySize
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoverySize
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoveryBase
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvMainSize
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvMainBase
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBootState
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvPayloadBase
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvPayloadSize
+  gQuarkPlatformTokenSpaceGuid.PcdEnableFastBoot
+  gQuarkPlatformTokenSpaceGuid.PcdPlatformType
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdMrcParameters
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohEthernetMac0
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohEthernetMac1
+
+[Depex]
+  gEfiPeiReadOnlyVariable2PpiGuid AND gQNCMemoryInitPpiGuid
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformErratas.c b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformErratas.c
new file mode 100644
index 0000000000..9e013840fc
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformErratas.c
@@ -0,0 +1,178 @@
+/** @file
+Platform Erratas performed by early init PEIM driver.
+
+Copyright (c) 2013 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CommonHeader.h"
+#include "PlatformEarlyInit.h"
+
+//
+// Constants.
+//
+
+//
+// Platform EHCI Packet Buffer OUT/IN Thresholds, values in number of DWORDs.
+//
+#define EHCI_OUT_THRESHOLD_VALUE              (0x7f)
+#define EHCI_IN_THRESHOLD_VALUE               (0x7f)
+
+//
+// Platform init USB device interrupt masks.
+//
+#define V_IOH_USBDEVICE_D_INTR_MSK_UDC_REG    (0x0000007f)
+#define V_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG   (B_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG_OUT_EP_MASK | B_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG_IN_EP_MASK)
+
+//
+// Global variables defined within this source module.
+//
+
+UINTN IohEhciPciReg[IOH_MAX_EHCI_USB_CONTROLLERS] = {
+  PCI_LIB_ADDRESS (IOH_USB_BUS_NUMBER, IOH_USB_EHCI_DEVICE_NUMBER, IOH_EHCI_FUNCTION_NUMBER, 0),
+};
+
+UINTN IohUsbDevicePciReg[IOH_MAX_USBDEVICE_USB_CONTROLLERS] = {
+  PCI_LIB_ADDRESS (IOH_USB_BUS_NUMBER, IOH_USBDEVICE_DEVICE_NUMBER, IOH_USBDEVICE_FUNCTION_NUMBER, 0),
+};
+
+//
+// Routines local to this source module.
+//
+
+/** Perform USB erratas after MRC init.
+
+**/
+VOID
+PlatformUsbErratasPostMrc (
+  VOID
+  )
+{
+  UINT32                            Index;
+  UINT32                            TempBar0Addr;
+  UINT16                            SaveCmdReg;
+  UINT32                            SaveBar0Reg;
+
+  TempBar0Addr = PcdGet32(PcdPeiQNCUsbControllerMemoryBaseAddress);
+
+  //
+  // Apply EHCI controller erratas.
+  //
+  for (Index = 0; Index < IOH_MAX_EHCI_USB_CONTROLLERS; Index++, TempBar0Addr += IOH_USB_CONTROLLER_MMIO_RANGE) {
+
+    if ((PciRead16 (IohEhciPciReg[Index] + R_IOH_USB_VENDOR_ID)) != V_IOH_USB_VENDOR_ID) {
+      continue;  // Device not enabled, skip.
+    }
+
+    //
+    // Save current settings for PCI CMD/BAR0 registers
+    //
+    SaveCmdReg = PciRead16 (IohEhciPciReg[Index] + R_IOH_USB_COMMAND);
+    SaveBar0Reg = PciRead32 (IohEhciPciReg[Index] + R_IOH_USB_MEMBAR);
+
+    //
+    // Temp. assign base address register, Enable Memory Space.
+    //
+    PciWrite32 ((IohEhciPciReg[Index] + R_IOH_USB_MEMBAR), TempBar0Addr);
+    PciWrite16 (IohEhciPciReg[Index] + R_IOH_USB_COMMAND, SaveCmdReg | B_IOH_USB_COMMAND_MSE);
+
+
+    //
+    // Set packet buffer OUT/IN thresholds.
+    //
+    MmioAndThenOr32 (
+      TempBar0Addr + R_IOH_EHCI_INSNREG01,
+      (UINT32) (~(B_IOH_EHCI_INSNREG01_OUT_THRESHOLD_MASK | B_IOH_EHCI_INSNREG01_IN_THRESHOLD_MASK)),
+      (UINT32) ((EHCI_OUT_THRESHOLD_VALUE << B_IOH_EHCI_INSNREG01_OUT_THRESHOLD_BP) | (EHCI_IN_THRESHOLD_VALUE << B_IOH_EHCI_INSNREG01_IN_THRESHOLD_BP))
+      );
+
+    //
+    // Restore settings for PCI CMD/BAR0 registers
+    //
+    PciWrite32 ((IohEhciPciReg[Index] + R_IOH_USB_MEMBAR), SaveBar0Reg);
+    PciWrite16 (IohEhciPciReg[Index] + R_IOH_USB_COMMAND, SaveCmdReg);
+  }
+
+  //
+  // Apply USB device controller erratas.
+  //
+  for (Index = 0; Index < IOH_MAX_USBDEVICE_USB_CONTROLLERS; Index++, TempBar0Addr += IOH_USB_CONTROLLER_MMIO_RANGE) {
+
+    if ((PciRead16 (IohUsbDevicePciReg[Index] + R_IOH_USB_VENDOR_ID)) != V_IOH_USB_VENDOR_ID) {
+      continue;  // Device not enabled, skip.
+    }
+
+    //
+    // Save current settings for PCI CMD/BAR0 registers
+    //
+    SaveCmdReg = PciRead16 (IohUsbDevicePciReg[Index] + R_IOH_USB_COMMAND);
+    SaveBar0Reg = PciRead32 (IohUsbDevicePciReg[Index] + R_IOH_USB_MEMBAR);
+
+    //
+    // Temp. assign base address register, Enable Memory Space.
+    //
+    PciWrite32 ((IohUsbDevicePciReg[Index] + R_IOH_USB_MEMBAR), TempBar0Addr);
+    PciWrite16 (IohUsbDevicePciReg[Index] + R_IOH_USB_COMMAND, SaveCmdReg | B_IOH_USB_COMMAND_MSE);
+
+    //
+    // Erratas for USB Device interrupt registers.
+    //
+
+    //
+    // 1st Mask interrupts.
+    //
+    MmioWrite32 (
+      TempBar0Addr + R_IOH_USBDEVICE_D_INTR_MSK_UDC_REG,
+      V_IOH_USBDEVICE_D_INTR_MSK_UDC_REG
+      );
+    //
+    // 2nd RW/1C of equivalent status bits.
+    //
+    MmioWrite32 (
+      TempBar0Addr + R_IOH_USBDEVICE_D_INTR_UDC_REG,
+      V_IOH_USBDEVICE_D_INTR_MSK_UDC_REG
+      );
+
+    //
+    // 1st Mask end point interrupts.
+    //
+    MmioWrite32 (
+      TempBar0Addr + R_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG,
+      V_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG
+      );
+    //
+    // 2nd RW/1C of equivalent end point status bits.
+    //
+    MmioWrite32 (
+      TempBar0Addr + R_IOH_USBDEVICE_EP_INTR_UDC_REG,
+      V_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG
+      );
+
+    //
+    // Restore settings for PCI CMD/BAR0 registers
+    //
+    PciWrite32 ((IohUsbDevicePciReg[Index] + R_IOH_USB_MEMBAR), SaveBar0Reg);
+    PciWrite16 (IohUsbDevicePciReg[Index] + R_IOH_USB_COMMAND, SaveCmdReg);
+  }
+}
+
+//
+// Routines exported by this source module.
+//
+
+/** Perform Platform Erratas after MRC.
+
+  @retval   EFI_SUCCESS               Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformErratasPostMrc (
+  VOID
+  )
+{
+  PlatformUsbErratasPostMrc ();
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FvbInfo.c b/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FvbInfo.c
new file mode 100644
index 0000000000..8a21c5e33f
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FvbInfo.c
@@ -0,0 +1,332 @@
+/** @file
+Defines data structure that is the volume header found.These data is intent
+to decouple FVB driver with FV header.
+
+Copyright (c) 2013 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#include <PiDxe.h>
+#include "FwBlockService.h"
+
+
+//#define FVB_MEDIA_BLOCK_SIZE  PcdGet32(PcdFlashMinEraseSize)
+#define FVB_MEDIA_BLOCK_SIZE  0x1000
+
+typedef struct {
+  EFI_PHYSICAL_ADDRESS        BaseAddress;
+  EFI_FIRMWARE_VOLUME_HEADER  FvbInfo;
+  //
+  //EFI_FV_BLOCK_MAP_ENTRY    ExtraBlockMap[n];//n=0
+  //
+  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
+  //
+  {
+    0,
+    {
+      {0,}, //ZeroVector[16]
+      EFI_FIRMWARE_FILE_SYSTEM2_GUID,
+      0,
+      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, check the FD for the value.
+      0,    //ExtHeaderOffset
+      {0,}, //Reserved[1]
+      2,    //Revision
+      {
+        {
+          0,
+          0,
+        }
+      }
+    },
+    {
+      {
+        0,
+        0
+      }
+    }
+  },
+  //
+  // Systen NvStorage FVB
+  //
+  {
+    0,
+    {
+      {0,}, //ZeroVector[16]
+      EFI_SYSTEM_NV_DATA_FV_GUID,
+      0,
+      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
+      {
+        {
+          0,
+          0,
+        }
+      }
+    },
+    {
+      {
+        0,
+        0
+      }
+    }
+  },
+  //
+  // Recovery BIOS FVB
+  //
+  {
+    0,
+    {
+      {0,}, //ZeroVector[16]
+      EFI_FIRMWARE_FILE_SYSTEM2_GUID,
+      0,
+      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
+      {
+        {
+          0,
+          0,
+        }
+      }
+    },
+    {
+      {
+        0,
+        0
+      }
+    }
+  },
+  //
+  // Payload FVB
+  //
+  {
+    0,
+    {
+      {0,}, //ZeroVector[16]
+      EFI_FIRMWARE_FILE_SYSTEM2_GUID,
+      0,
+      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.
+      0x60,    //ExtHeaderOffset
+      {0,}, //Reserved[1]
+      2,    //Revision
+      {
+        {
+          0,
+          0,
+        }
+      }
+    },
+    {
+      {
+        0,
+        0
+      }
+    }
+  }
+};
+
+
+//
+// FTW working space and FTW spare space don't have FV header.
+// We need create one for them and use it for FVB protocol.
+//
+EFI_FVB2_MEDIA_INFO mPlatformFtwFvbInfo[] = {
+  //
+  // System variable FTW working FVB
+  //
+  {
+    0,
+    {
+      {0,}, //ZeroVector[16]
+      EFI_SYSTEM_NV_DATA_FV_GUID,
+      0,
+      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
+      {
+        {
+          0,
+          0,
+        }
+      }
+    },
+    {
+      {
+        0,
+        0
+      }
+    }
+  },
+  //
+  // Systen NV variable FTW spare FVB
+  //
+  {
+    0,
+    {
+      {0,}, //ZeroVector[16]
+      EFI_SYSTEM_NV_DATA_FV_GUID,
+      0,
+      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
+      {
+        {
+          0,
+          0,
+        }
+      }
+    },
+    {
+      {
+        0,
+        0
+      }
+    }
+  }
+};
+
+
+
+EFI_STATUS
+GetFtwFvbInfo (
+  IN  EFI_PHYSICAL_ADDRESS         FvBaseAddress,
+  OUT EFI_FIRMWARE_VOLUME_HEADER   **FvbInfo
+  )
+{
+  UINTN                       Index;
+  EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;
+
+  //
+  // Init Fvb data
+  //
+  mPlatformFtwFvbInfo[0].BaseAddress      = PcdGet32 (PcdFlashNvStorageFtwWorkingBase);
+  mPlatformFtwFvbInfo[0].FvbInfo.FvLength = PcdGet32 (PcdFlashNvStorageFtwWorkingSize);
+  mPlatformFtwFvbInfo[0].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashNvStorageFtwWorkingSize) / FVB_MEDIA_BLOCK_SIZE;
+  mPlatformFtwFvbInfo[0].FvbInfo.BlockMap[0].Length    = FVB_MEDIA_BLOCK_SIZE;
+  ASSERT ((PcdGet32 (PcdFlashNvStorageFtwWorkingSize) % FVB_MEDIA_BLOCK_SIZE) == 0);
+
+  mPlatformFtwFvbInfo[1].BaseAddress      = PcdGet32 (PcdFlashNvStorageFtwSpareBase);
+  mPlatformFtwFvbInfo[1].FvbInfo.FvLength = PcdGet32 (PcdFlashNvStorageFtwSpareSize);
+  mPlatformFtwFvbInfo[1].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashNvStorageFtwSpareSize) / FVB_MEDIA_BLOCK_SIZE;
+  mPlatformFtwFvbInfo[1].FvbInfo.BlockMap[0].Length    = FVB_MEDIA_BLOCK_SIZE;
+  ASSERT ((PcdGet32 (PcdFlashNvStorageFtwSpareSize) % FVB_MEDIA_BLOCK_SIZE) == 0);
+
+  for (Index=0; Index < sizeof (mPlatformFtwFvbInfo)/sizeof (mPlatformFtwFvbInfo[0]); Index += 1) {
+    if (mPlatformFtwFvbInfo[Index].BaseAddress == FvBaseAddress) {
+      FvHeader =  &mPlatformFtwFvbInfo[Index].FvbInfo;
+      //
+      // Update the checksum value of FV header.
+      //
+      FvHeader->Checksum = CalculateCheckSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
+
+      *FvbInfo = FvHeader;
+
+      DEBUG ((EFI_D_INFO, "\nFTW BaseAddr: 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;
+}
+
+
+EFI_STATUS
+GetFvbInfo (
+  IN  EFI_PHYSICAL_ADDRESS         FvBaseAddress,
+  OUT EFI_FIRMWARE_VOLUME_HEADER   **FvbInfo
+  )
+{
+  UINTN                       Index;
+  EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;
+
+  //
+  // Init Fvb data
+  //
+  mPlatformFvbMediaInfo[0].BaseAddress      = PcdGet32 (PcdFlashFvMainBase);
+  mPlatformFvbMediaInfo[0].FvbInfo.FvLength = PcdGet32 (PcdFlashFvMainSize);
+  mPlatformFvbMediaInfo[0].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashFvMainSize) / FVB_MEDIA_BLOCK_SIZE;
+  mPlatformFvbMediaInfo[0].FvbInfo.BlockMap[0].Length    = FVB_MEDIA_BLOCK_SIZE;
+  ASSERT ((PcdGet32 (PcdFlashFvMainSize) % FVB_MEDIA_BLOCK_SIZE) == 0);
+
+  mPlatformFvbMediaInfo[1].BaseAddress      = PcdGet32 (PcdFlashNvStorageVariableBase);
+  mPlatformFvbMediaInfo[1].FvbInfo.FvLength = PcdGet32 (PcdFlashNvStorageVariableSize);
+  mPlatformFvbMediaInfo[1].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashNvStorageVariableSize) / FVB_MEDIA_BLOCK_SIZE;
+  mPlatformFvbMediaInfo[1].FvbInfo.BlockMap[0].Length    = FVB_MEDIA_BLOCK_SIZE;
+  ASSERT ((PcdGet32 (PcdFlashNvStorageVariableSize) % FVB_MEDIA_BLOCK_SIZE) == 0);
+
+  mPlatformFvbMediaInfo[2].BaseAddress      = PcdGet32 (PcdFlashFvRecoveryBase);
+  mPlatformFvbMediaInfo[2].FvbInfo.FvLength = PcdGet32 (PcdFlashFvRecoverySize);
+  mPlatformFvbMediaInfo[2].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashFvRecoverySize) / FVB_MEDIA_BLOCK_SIZE;
+  mPlatformFvbMediaInfo[2].FvbInfo.BlockMap[0].Length    = FVB_MEDIA_BLOCK_SIZE;
+  ASSERT ((PcdGet32 (PcdFlashFvRecoverySize) % FVB_MEDIA_BLOCK_SIZE) == 0);
+
+  mPlatformFvbMediaInfo[3].BaseAddress      = PcdGet32 (PcdFlashFvPayloadBase);
+  mPlatformFvbMediaInfo[3].FvbInfo.FvLength = PcdGet32 (PcdFlashFvPayloadSize);
+  mPlatformFvbMediaInfo[3].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashFvPayloadSize) / FVB_MEDIA_BLOCK_SIZE;
+  mPlatformFvbMediaInfo[3].FvbInfo.BlockMap[0].Length    = FVB_MEDIA_BLOCK_SIZE;
+  ASSERT ((PcdGet32 (PcdFlashFvPayloadSize) % FVB_MEDIA_BLOCK_SIZE) == 0);
+
+  for (Index=0; Index < sizeof (mPlatformFvbMediaInfo)/sizeof (mPlatformFvbMediaInfo[0]); 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 / sizeof (UINT16));
+
+      *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;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.c b/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.c
new file mode 100644
index 0000000000..5ecb1cfdc7
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.c
@@ -0,0 +1,2053 @@
+/** @file
+
+Copyright (c) 2013-2016 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#include "FwBlockService.h"
+
+ESAL_FWB_GLOBAL         *mFvbModuleGlobal;
+
+EFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate = {
+  FVB_DEVICE_SIGNATURE,  // Signature
+  //
+  // FV_DEVICE_PATH                      FvDevicePath
+  //
+  {
+    {
+      {
+        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
+      }
+    }
+  },
+  //
+  //   UEFI_FV_DEVICE_PATH                 UefiFvDevicePath
+  //
+  {
+    {
+      {
+        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
+      }
+    }
+  },
+  0,      // Instance
+  //
+  // EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  FwVolBlockInstance
+  //
+  {
+    FvbProtocolGetAttributes,
+    FvbProtocolSetAttributes,
+    FvbProtocolGetPhysicalAddress,
+    FvbProtocolGetBlockSize,
+    FvbProtocolRead,
+    FvbProtocolWrite,
+    FvbProtocolEraseBlocks,
+    NULL
+  }
+};
+
+UINT32 mInSmmMode = 0;
+EFI_SMM_SYSTEM_TABLE2*   mSmst = NULL;
+
+VOID
+PublishFlashDeviceInfo (
+  IN SPI_INIT_TABLE   *Found
+  )
+/*++
+
+Routine Description:
+
+  Publish info on found flash device to other drivers via PcdSpiFlashDeviceSize.
+
+Arguments:
+  Found                 - Pointer to entry in mSpiInitTable for found flash part.
+
+Returns:
+  None
+
+--*/
+{
+  EFI_STATUS  Status;
+
+  //
+  // Publish Byte Size of found flash device.
+  //
+  Status = PcdSet32S (PcdSpiFlashDeviceSize, (UINT32)(Found->BiosStartOffset + Found->BiosSize));
+  ASSERT_EFI_ERROR (Status);
+}
+
+VOID
+FvbVirtualddressChangeEvent (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  )
+/*++
+
+Routine Description:
+
+  Fixup internal data so that EFI and SAL can be call in virtual mode.
+  Call the passed in Child Notify event and convert the mFvbModuleGlobal
+  date items to there virtual address.
+
+  mFvbModuleGlobal->FvInstance[FVB_PHYSICAL]  - Physical copy of instance data
+  mFvbModuleGlobal->FvInstance[FVB_VIRTUAL]   - Virtual pointer to common
+                                                instance data.
+
+Arguments:
+
+  (Standard EFI notify event - EFI_EVENT_NOTIFY)
+
+Returns:
+
+  None
+
+--*/
+{
+  EFI_FW_VOL_INSTANCE *FwhInstance;
+  UINTN               Index;
+
+  gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &mFvbModuleGlobal->FvInstance[FVB_VIRTUAL]);
+
+  //
+  // Convert the base address of all the instances
+  //
+  Index       = 0;
+  FwhInstance = mFvbModuleGlobal->FvInstance[FVB_PHYSICAL];
+  while (Index < mFvbModuleGlobal->NumFv) {
+
+  gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &FwhInstance->FvBase[FVB_VIRTUAL]);
+    //
+    // SpiWrite and SpiErase always use Physical Address instead of
+    // Virtual Address, even in Runtime. So we need not convert pointer
+    // for FvWriteBase[FVB_VIRTUAL]
+    //
+    // EfiConvertPointer (0, (VOID **) &FwhInstance->FvWriteBase[FVB_VIRTUAL]);
+    //
+    FwhInstance = (EFI_FW_VOL_INSTANCE *)
+      (
+        (UINTN) ((UINT8 *) FwhInstance) + FwhInstance->VolumeHeader.HeaderLength +
+          (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))
+      );
+    Index++;
+  }
+
+  gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &mFvbModuleGlobal->FvbScratchSpace[FVB_VIRTUAL]);
+  //
+  // Convert SPI_PROTOCOL instance for runtime
+  //
+  gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &mFvbModuleGlobal->SpiProtocol);
+  gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &mFvbModuleGlobal);
+}
+
+VOID
+FvbMemWrite8 (
+  IN  UINT64                              Dest,
+  IN  UINT8                               Byte
+  )
+{
+  MmioWrite8 ((UINTN)Dest, Byte);
+
+  return ;
+}
+
+EFI_STATUS
+GetFvbInstance (
+  IN  UINTN                               Instance,
+  IN  ESAL_FWB_GLOBAL                     *Global,
+  OUT EFI_FW_VOL_INSTANCE                 **FwhInstance,
+  IN BOOLEAN                              Virtual
+  )
+/*++
+
+Routine Description:
+  Retrieves the physical address of a memory mapped FV
+
+Arguments:
+  Instance              - The FV instance whose base address is going to be
+                          returned
+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all
+                          instance data
+  FwhInstance           - The EFI_FW_VOL_INSTANCE fimrware instance structure
+  Virtual               - Whether CPU is in virtual or physical mode
+
+Returns:
+  EFI_SUCCESS           - Successfully returns
+  EFI_INVALID_PARAMETER - Instance not found
+
+--*/
+{
+  EFI_FW_VOL_INSTANCE *FwhRecord;
+
+  if (Instance >= Global->NumFv) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Find the right instance of the FVB private data
+  //
+  FwhRecord = Global->FvInstance[Virtual];
+  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--;
+  }
+
+  *FwhInstance = FwhRecord;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FvbGetPhysicalAddress (
+  IN UINTN                                Instance,
+  OUT EFI_PHYSICAL_ADDRESS                *Address,
+  IN ESAL_FWB_GLOBAL                      *Global,
+  IN BOOLEAN                              Virtual
+  )
+/*++
+
+Routine Description:
+  Retrieves the physical address of a memory mapped FV
+
+Arguments:
+  Instance              - The FV instance whose base address is going to be
+                          returned
+  Address               - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS
+                          that on successful return, contains the base address
+                          of the firmware volume.
+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all
+                          instance data
+  Virtual               - Whether CPU is in virtual or physical mode
+
+Returns:
+  EFI_SUCCESS           - Successfully returns
+  EFI_INVALID_PARAMETER - Instance not found
+
+--*/
+{
+  EFI_FW_VOL_INSTANCE *FwhInstance;
+  EFI_STATUS          Status;
+
+  FwhInstance = NULL;
+
+  //
+  // Find the right instance of the FVB private data
+  //
+  Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);
+  ASSERT_EFI_ERROR (Status);
+  *Address = FwhInstance->FvBase[Virtual];
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FvbGetVolumeAttributes (
+  IN UINTN                                Instance,
+  OUT EFI_FVB_ATTRIBUTES_2                  *Attributes,
+  IN ESAL_FWB_GLOBAL                      *Global,
+  IN BOOLEAN                              Virtual
+  )
+/*++
+
+Routine Description:
+  Retrieves attributes, insures positive polarity of attribute bits, returns
+  resulting attributes in output parameter
+
+Arguments:
+  Instance              - The FV instance whose attributes is going to be
+                          returned
+  Attributes            - Output buffer which contains attributes
+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all
+                          instance data
+  Virtual               - Whether CPU is in virtual or physical mode
+
+Returns:
+  EFI_SUCCESS           - Successfully returns
+  EFI_INVALID_PARAMETER - Instance not found
+
+--*/
+{
+  EFI_FW_VOL_INSTANCE *FwhInstance;
+  EFI_STATUS          Status;
+
+  FwhInstance = NULL;
+
+  //
+  // Find the right instance of the FVB private data
+  //
+  Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);
+  ASSERT_EFI_ERROR (Status);
+  *Attributes = FwhInstance->VolumeHeader.Attributes;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FvbGetLbaAddress (
+  IN  UINTN                               Instance,
+  IN  EFI_LBA                             Lba,
+  OUT UINTN                               *LbaAddress,
+  OUT UINTN                               *LbaWriteAddress,
+  OUT UINTN                               *LbaLength,
+  OUT UINTN                               *NumOfBlocks,
+  IN  ESAL_FWB_GLOBAL                     *Global,
+  IN  BOOLEAN                             Virtual
+  )
+/*++
+
+Routine Description:
+  Retrieves the starting address of an LBA in an FV
+
+Arguments:
+  Instance              - The FV instance which the Lba belongs to
+  Lba                   - The logical block address
+  LbaAddress            - On output, contains the physical starting address
+                          of the Lba
+  LbaWriteAddress       - On output, contains the physical starting address
+                          of the Lba for writing
+  LbaLength             - On output, contains the length of the block
+  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
+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all
+                          instance data
+  Virtual               - Whether CPU is in virtual or physical mode
+
+Returns:
+  EFI_SUCCESS           - Successfully returns
+  EFI_INVALID_PARAMETER - Instance not found
+
+--*/
+{
+  UINT32                  NumBlocks;
+  UINT32                  BlockLength;
+  UINTN                   Offset;
+  EFI_LBA                 StartLba;
+  EFI_LBA                 NextLba;
+  EFI_FW_VOL_INSTANCE     *FwhInstance;
+  EFI_FV_BLOCK_MAP_ENTRY  *BlockMap;
+  EFI_STATUS              Status;
+
+  FwhInstance = NULL;
+
+  //
+  // Find the right instance of the FVB private data
+  //
+  Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);
+  ASSERT_EFI_ERROR (Status);
+
+  StartLba  = 0;
+  Offset    = 0;
+  BlockMap  = &(FwhInstance->VolumeHeader.BlockMap[0]);
+
+  //
+  // Parse the blockmap of the FV to find which map entry the Lba belongs to
+  //
+  while (TRUE) {
+    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) {
+        *LbaAddress = FwhInstance->FvBase[Virtual] + Offset;
+      }
+
+      if (LbaWriteAddress) {
+        *LbaWriteAddress = FwhInstance->FvWriteBase[Virtual] + Offset;
+      }
+
+      if (LbaLength) {
+        *LbaLength = BlockLength;
+      }
+
+      if (NumOfBlocks) {
+        *NumOfBlocks = (UINTN) (NextLba - Lba);
+      }
+
+      return EFI_SUCCESS;
+    }
+
+    StartLba  = NextLba;
+    Offset    = Offset + NumBlocks * BlockLength;
+    BlockMap++;
+  }
+}
+
+EFI_STATUS
+FvbReadBlock (
+  IN UINTN                                Instance,
+  IN EFI_LBA                              Lba,
+  IN UINTN                                BlockOffset,
+  IN OUT UINTN                            *NumBytes,
+  IN UINT8                                *Buffer,
+  IN ESAL_FWB_GLOBAL                      *Global,
+  IN BOOLEAN                              Virtual
+  )
+/*++
+
+Routine Description:
+  Reads specified number of bytes into a buffer from the specified block
+
+Arguments:
+  Instance              - The FV instance to be read from
+  Lba                   - The logical block address to be read from
+  BlockOffset           - Offset into the block at which to begin reading
+  NumBytes              - Pointer that on input contains the total size of
+                          the buffer. On output, it contains the total number
+                          of bytes read
+  Buffer                - Pointer to a caller allocated buffer that will be
+                          used to hold the data read
+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all
+                          instance data
+  Virtual               - Whether CPU is in virtual or physical mode
+
+Returns:
+  EFI_SUCCESS           - The firmware volume was read successfully and
+                          contents are in Buffer
+  EFI_BAD_BUFFER_SIZE   - Read attempted across a LBA boundary. On output,
+                          NumBytes contains the total number of bytes returned
+                          in Buffer
+  EFI_ACCESS_DENIED     - The firmware volume is in the ReadDisabled state
+  EFI_DEVICE_ERROR      - The block device is not functioning correctly and
+                          could not be read
+  EFI_INVALID_PARAMETER - Instance not found, or NumBytes, Buffer are NULL
+
+--*/
+{
+  EFI_FVB_ATTRIBUTES_2  Attributes;
+  UINTN               LbaAddress;
+  UINTN               LbaLength;
+  EFI_STATUS          Status;
+
+  //
+  // Check for invalid conditions
+  //
+  if ((NumBytes == NULL) || (Buffer == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (*NumBytes == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, NULL, &LbaLength, NULL, Global, Virtual);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Check if the FV is read enabled
+  //
+  FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);
+
+  if ((Attributes & EFI_FVB2_READ_STATUS) == 0) {
+    return EFI_ACCESS_DENIED;
+  }
+  //
+  // Perform boundary checks and adjust NumBytes
+  //
+  if (BlockOffset > LbaLength) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (LbaLength < (*NumBytes + BlockOffset)) {
+    *NumBytes = (UINT32) (LbaLength - BlockOffset);
+    Status    = EFI_BAD_BUFFER_SIZE;
+  }
+
+  MmioReadBuffer8 (LbaAddress + BlockOffset, (UINTN) *NumBytes, Buffer);
+
+  return Status;
+}
+
+EFI_STATUS
+FlashFdWrite (
+  IN  UINTN                               WriteAddress,
+  IN  UINTN                               Address,
+  IN OUT UINTN                            *NumBytes,
+  IN  UINT8                               *Buffer,
+  IN  UINTN                               LbaLength
+  )
+/*++
+
+Routine Description:
+  Writes specified number of bytes from the input buffer to the address
+
+Arguments:
+
+Returns:
+
+--*/
+{
+  EFI_STATUS  Status;
+
+  Status = EFI_SUCCESS;
+
+  //
+  // TODO:  Suggested that this code be "critical section"
+  //
+  WriteAddress -= ( PcdGet32 (PcdFlashAreaBaseAddress) );
+  if (mInSmmMode == 0) { // !(EfiInManagementInterrupt ())) {
+    Status = mFvbModuleGlobal->SpiProtocol->Execute (
+                                            mFvbModuleGlobal->SpiProtocol,
+                                            SPI_OPCODE_WRITE_INDEX, // OpcodeIndex
+                                            0,                      // PrefixOpcodeIndex
+                                            TRUE,                   // DataCycle
+                                            TRUE,                   // Atomic
+                                            TRUE,                   // ShiftOut
+                                            WriteAddress,           // Address
+                                            (UINT32) (*NumBytes),   // Data Number
+                                            Buffer,
+                                            EnumSpiRegionBios
+                                            );
+
+  } else {
+    Status = mFvbModuleGlobal->SmmSpiProtocol->Execute (
+                                            mFvbModuleGlobal->SmmSpiProtocol,
+                                            SPI_OPCODE_WRITE_INDEX, // OpcodeIndex
+                                            0,                      // PrefixOpcodeIndex
+                                            TRUE,                   // DataCycle
+                                            TRUE,                   // Atomic
+                                            TRUE,                   // ShiftOut
+                                            WriteAddress,           // Address
+                                            (UINT32) (*NumBytes),   // Data Number
+                                            Buffer,
+                                            EnumSpiRegionBios
+                                            );
+  }
+
+    AsmWbinvd ();
+
+  return Status;
+}
+
+EFI_STATUS
+FlashFdErase (
+  IN UINTN                                WriteAddress,
+  IN UINTN                                Address,
+  IN UINTN                                LbaLength
+  )
+/*++
+
+Routine Description:
+  Erase a certain block from address LbaWriteAddress
+
+Arguments:
+
+Returns:
+
+--*/
+{
+  EFI_STATUS  Status;
+
+  WriteAddress -= (PcdGet32 (PcdFlashAreaBaseAddress));
+  if (mInSmmMode == 0 ) { // !(EfiInManagementInterrupt ())) {
+    Status = mFvbModuleGlobal->SpiProtocol->Execute (
+                                            mFvbModuleGlobal->SpiProtocol,
+                                            SPI_OPCODE_ERASE_INDEX, // OpcodeIndex
+                                            0,                      // PrefixOpcodeIndex
+                                            FALSE,                  // DataCycle
+                                            TRUE,                   // Atomic
+                                            FALSE,                  // ShiftOut
+                                            WriteAddress,           // Address
+                                            0,                      // Data Number
+                                            NULL,
+                                            EnumSpiRegionBios       // SPI_REGION_TYPE
+                                            );
+  } else {
+    Status = mFvbModuleGlobal->SmmSpiProtocol->Execute (
+                                            mFvbModuleGlobal->SmmSpiProtocol,
+                                            SPI_OPCODE_ERASE_INDEX, // OpcodeIndex
+                                            0,                      // PrefixOpcodeIndex
+                                            FALSE,                  // DataCycle
+                                            TRUE,                   // Atomic
+                                            FALSE,                  // ShiftOut
+                                            WriteAddress,           // Address
+                                            0,                      // Data Number
+                                            NULL,
+                                            EnumSpiRegionBios       // SPI_REGION_TYPE
+                                            );
+  }
+
+  AsmWbinvd ();
+
+  return Status;
+}
+
+EFI_STATUS
+FvbWriteBlock (
+  IN UINTN                                Instance,
+  IN EFI_LBA                              Lba,
+  IN UINTN                                BlockOffset,
+  IN OUT UINTN                            *NumBytes,
+  IN UINT8                                *Buffer,
+  IN ESAL_FWB_GLOBAL                      *Global,
+  IN BOOLEAN                              Virtual
+  )
+/*++
+
+Routine Description:
+  Writes specified number of bytes from the input buffer to the block
+
+Arguments:
+  Instance              - The FV instance to be written to
+  Lba                   - The starting logical block index to write to
+  BlockOffset           - Offset into the block at which to begin writing
+  NumBytes              - Pointer that on input contains the total size of
+                          the buffer. On output, it contains the total number
+                          of bytes actually written
+  Buffer                - Pointer to a caller allocated buffer that contains
+                          the source for the write
+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all
+                          instance data
+  Virtual               - Whether CPU is in virtual or physical mode
+
+Returns:
+  EFI_SUCCESS           - The firmware volume was written successfully
+  EFI_BAD_BUFFER_SIZE   - Write attempted across a LBA boundary. On output,
+                          NumBytes contains the total number of bytes
+                          actually written
+  EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state
+  EFI_DEVICE_ERROR      - The block device is not functioning correctly and
+                          could not be written
+  EFI_INVALID_PARAMETER - Instance not found, or NumBytes, Buffer are NULL
+
+--*/
+{
+  EFI_FVB_ATTRIBUTES_2  Attributes;
+  UINTN               LbaAddress;
+  UINTN               LbaWriteAddress;
+  UINTN               LbaLength;
+  EFI_FW_VOL_INSTANCE *FwhInstance;
+  EFI_STATUS          Status;
+  EFI_STATUS          ReturnStatus;
+
+  FwhInstance = NULL;
+
+  //
+  // Find the right instance of the FVB private data
+  //
+  Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Writes are enabled in the init routine itself
+  //
+  if (!FwhInstance->WriteEnabled) {
+    return EFI_ACCESS_DENIED;
+  }
+  //
+  // Check for invalid conditions
+  //
+  if ((NumBytes == NULL) || (Buffer == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (*NumBytes == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaWriteAddress, &LbaLength, NULL, Global, Virtual);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Check if the FV is write enabled
+  //
+  FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);
+
+  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)) {
+    *NumBytes = (UINT32) (LbaLength - BlockOffset);
+    Status    = EFI_BAD_BUFFER_SIZE;
+  }
+
+  ReturnStatus = FlashFdWrite (
+                  LbaWriteAddress + BlockOffset,
+                  LbaAddress,
+                  NumBytes,
+                  Buffer,
+                  LbaLength
+                  );
+  if (EFI_ERROR (ReturnStatus)) {
+    return ReturnStatus;
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+FvbEraseBlock (
+  IN UINTN                                Instance,
+  IN EFI_LBA                              Lba,
+  IN ESAL_FWB_GLOBAL                      *Global,
+  IN BOOLEAN                              Virtual
+  )
+/*++
+
+Routine Description:
+  Erases and initializes a firmware volume block
+
+Arguments:
+  Instance              - The FV instance to be erased
+  Lba                   - The logical block index to be erased
+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all
+                          instance data
+  Virtual               - Whether CPU is in virtual or physical mode
+
+Returns:
+  EFI_SUCCESS           - The erase request was successfully completed
+  EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state
+  EFI_DEVICE_ERROR      - The block device is not functioning correctly and
+                          could not be written. Firmware device may have been
+                          partially erased
+  EFI_INVALID_PARAMETER - Instance not found
+
+--*/
+{
+
+  EFI_FVB_ATTRIBUTES_2  Attributes;
+  UINTN               LbaAddress;
+  UINTN               LbaWriteAddress;
+  EFI_FW_VOL_INSTANCE *FwhInstance;
+  UINTN               LbaLength;
+  EFI_STATUS          Status;
+  UINTN               SectorNum;
+  UINTN               Index;
+
+  FwhInstance = NULL;
+
+  //
+  // Find the right instance of the FVB private data
+  //
+  Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Writes are enabled in the init routine itself
+  //
+  if (!FwhInstance->WriteEnabled) {
+    return EFI_ACCESS_DENIED;
+  }
+  //
+  // Check if the FV is write enabled
+  //
+  FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);
+
+  if ((Attributes & EFI_FVB2_WRITE_STATUS) == 0) {
+    return EFI_ACCESS_DENIED;
+  }
+  //
+  // Get the starting address of the block for erase. For debug reasons,
+  // LbaWriteAddress may not be the same as LbaAddress.
+  //
+  Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaWriteAddress, &LbaLength, NULL, Global, Virtual);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  SectorNum = LbaLength / SPI_ERASE_SECTOR_SIZE;
+  for (Index = 0; Index < SectorNum; Index++){
+    Status = FlashFdErase (
+               LbaWriteAddress + Index * SPI_ERASE_SECTOR_SIZE,
+               LbaAddress,
+               SPI_ERASE_SECTOR_SIZE
+               );
+    if (Status != EFI_SUCCESS){
+      break;
+    }
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+FvbEraseCustomBlockRange (
+  IN UINTN                                Instance,
+  IN EFI_LBA                              StartLba,
+  IN UINTN                                OffsetStartLba,
+  IN EFI_LBA                              LastLba,
+  IN UINTN                                OffsetLastLba,
+  IN ESAL_FWB_GLOBAL                      *Global,
+  IN BOOLEAN                              Virtual
+  )
+/*++
+
+Routine Description:
+  Erases and initializes a specified range of a firmware volume
+
+Arguments:
+  Instance              - The FV instance to be erased
+  StartLba              - The starting logical block index to be erased
+  OffsetStartLba        - Offset into the starting block at which to
+                          begin erasing
+  LastLba               - The last logical block index to be erased
+  OffsetStartLba        - Offset into the last block at which to end erasing
+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all
+                          instance data
+  Virtual               - Whether CPU is in virtual or physical mode
+
+Returns:
+  EFI_SUCCESS           - The firmware volume was erased successfully
+  EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state
+  EFI_DEVICE_ERROR      - The block device is not functioning correctly and
+                          could not be written. Firmware device may have been
+                          partially erased
+  EFI_INVALID_PARAMETER - Instance not found
+
+--*/
+{
+  EFI_LBA Index;
+  UINTN   LbaSize;
+  UINTN   ScratchLbaSizeData;
+
+  //
+  // First LBA.
+  //
+  FvbGetLbaAddress (Instance, StartLba, NULL, NULL, &LbaSize, NULL, Global, Virtual);
+
+  //
+  // Use the scratch space as the intermediate buffer to transfer data
+  // Back up the first LBA in scratch space.
+  //
+  FvbReadBlock (Instance, StartLba, 0, &LbaSize, Global->FvbScratchSpace[Virtual], Global, Virtual);
+
+  //
+  // erase now
+  //
+  FvbEraseBlock (Instance, StartLba, Global, Virtual);
+  ScratchLbaSizeData = OffsetStartLba;
+
+  //
+  // write the data back to the first block
+  //
+  if (ScratchLbaSizeData > 0) {
+    FvbWriteBlock (Instance, StartLba, 0, &ScratchLbaSizeData, Global->FvbScratchSpace[Virtual], Global, Virtual);
+  }
+  //
+  // Middle LBAs
+  //
+  if (LastLba > (StartLba + 1)) {
+    for (Index = (StartLba + 1); Index <= (LastLba - 1); Index++) {
+      FvbEraseBlock (Instance, Index, Global, Virtual);
+    }
+  }
+  //
+  // Last LBAs, the same as first LBAs
+  //
+  if (LastLba > StartLba) {
+    FvbGetLbaAddress (Instance, LastLba, NULL, NULL, &LbaSize, NULL, Global, Virtual);
+    FvbReadBlock (Instance, LastLba, 0, &LbaSize, Global->FvbScratchSpace[Virtual], Global, Virtual);
+    FvbEraseBlock (Instance, LastLba, Global, Virtual);
+  }
+
+  ScratchLbaSizeData = LbaSize - (OffsetStartLba + 1);
+
+  return FvbWriteBlock (
+          Instance,
+          LastLba,
+          (OffsetLastLba + 1),
+          &ScratchLbaSizeData,
+          Global->FvbScratchSpace[Virtual],
+          Global,
+          Virtual
+          );
+}
+
+EFI_STATUS
+FvbSetVolumeAttributes (
+  IN UINTN                                Instance,
+  IN OUT EFI_FVB_ATTRIBUTES_2               *Attributes,
+  IN ESAL_FWB_GLOBAL                      *Global,
+  IN BOOLEAN                              Virtual
+  )
+/*++
+
+Routine Description:
+  Modifies the current settings of the firmware volume according to the
+  input parameter, and returns the new setting of the volume
+
+Arguments:
+  Instance              - The FV instance whose attributes is going to be
+                          modified
+  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
+  Global                - Pointer to ESAL_FWB_GLOBAL that contains all
+                          instance data
+  Virtual               - Whether CPU is in virtual or physical mode
+
+Returns:
+  EFI_SUCCESS           - Successfully returns
+  EFI_ACCESS_DENIED     - The volume setting is locked and cannot be modified
+  EFI_INVALID_PARAMETER - Instance not found, or The attributes requested are
+                          in conflict with the capabilities as declared in the
+                          firmware volume header
+
+--*/
+{
+  EFI_FW_VOL_INSTANCE *FwhInstance;
+  EFI_FVB_ATTRIBUTES_2  OldAttributes;
+  EFI_FVB_ATTRIBUTES_2  *AttribPtr;
+  UINT32              Capabilities;
+  UINT32              OldStatus;
+  UINT32              NewStatus;
+  EFI_STATUS          Status;
+
+  FwhInstance = NULL;
+
+  //
+  // Find the right instance of the FVB private data
+  //
+  Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);
+  ASSERT_EFI_ERROR (Status);
+
+  AttribPtr     = (EFI_FVB_ATTRIBUTES_2 *) &(FwhInstance->VolumeHeader.Attributes);
+  OldAttributes = *AttribPtr;
+  Capabilities  = OldAttributes & EFI_FVB2_CAPABILITIES;
+  OldStatus     = OldAttributes & EFI_FVB2_STATUS;
+  NewStatus     = *Attributes & EFI_FVB2_STATUS;
+
+  //
+  // 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
+//
+EFI_STATUS
+EFIAPI
+FvbProtocolGetPhysicalAddress (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL       *This,
+  OUT EFI_PHYSICAL_ADDRESS                          *Address
+  )
+/*++
+
+Routine Description:
+
+  Retrieves the physical address of the device.
+
+Arguments:
+
+  This                  - Calling context
+  Address               - Output buffer containing the address.
+
+Returns:
+
+Returns:
+  EFI_SUCCESS           - Successfully returns
+
+--*/
+{
+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+  return FvbGetPhysicalAddress (FvbDevice->Instance, Address, mFvbModuleGlobal, EfiGoneVirtual ());
+}
+
+EFI_STATUS
+FvbProtocolGetBlockSize (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL       *This,
+  IN  EFI_LBA                                       Lba,
+  OUT UINTN                                         *BlockSize,
+  OUT UINTN                                         *NumOfBlocks
+  )
+/*++
+
+Routine Description:
+  Retrieve the size of a logical block
+
+Arguments:
+  This                  - Calling context
+  Lba                   - Indicates which block to return the size for.
+  BlockSize             - A pointer to a caller allocated UINTN in which
+                          the size of the block is returned
+  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
+
+Returns:
+  EFI_SUCCESS           - The firmware volume was read successfully and
+                          contents are in Buffer
+
+--*/
+{
+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+  return FvbGetLbaAddress (
+          FvbDevice->Instance,
+          Lba,
+          NULL,
+          NULL,
+          BlockSize,
+          NumOfBlocks,
+          mFvbModuleGlobal,
+          EfiGoneVirtual ()
+          );
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolGetAttributes (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL       *This,
+  OUT EFI_FVB_ATTRIBUTES_2                            *Attributes
+  )
+/*++
+
+Routine Description:
+    Retrieves Volume attributes.  No polarity translations are done.
+
+Arguments:
+    This                - Calling context
+    Attributes          - output buffer which contains attributes
+
+Returns:
+  EFI_SUCCESS           - Successfully returns
+
+--*/
+{
+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+  return FvbGetVolumeAttributes (FvbDevice->Instance, Attributes, mFvbModuleGlobal, EfiGoneVirtual ());
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolSetAttributes (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL       *This,
+  IN OUT EFI_FVB_ATTRIBUTES_2                         *Attributes
+  )
+/*++
+
+Routine Description:
+  Sets Volume attributes. No polarity translations are done.
+
+Arguments:
+  This                  - Calling context
+  Attributes            - output buffer which contains attributes
+
+Returns:
+  EFI_SUCCESS           - Successfully returns
+
+--*/
+{
+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+  return FvbSetVolumeAttributes (FvbDevice->Instance, Attributes, mFvbModuleGlobal, EfiGoneVirtual ());
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolEraseBlocks (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL       *This,
+  ...
+  )
+/*++
+
+Routine Description:
+
+  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.
+
+Arguments:
+  This                  - Calling context
+  ...                   - Starting LBA followed by Number of Lba to erase.
+                          a -1 to terminate the list.
+
+Returns:
+  EFI_SUCCESS           - The erase request was successfully completed
+  EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state
+  EFI_DEVICE_ERROR      - The block device is not functioning correctly and
+                          could not be written. Firmware device may have been
+                          partially erased
+
+--*/
+{
+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+  EFI_FW_VOL_INSTANCE     *FwhInstance;
+  UINTN                   NumOfBlocks;
+  VA_LIST                 args;
+  EFI_LBA                 StartingLba;
+  UINTN                   NumOfLba;
+  EFI_STATUS              Status;
+
+  FwhInstance = NULL;
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+  Status    = GetFvbInstance (FvbDevice->Instance, mFvbModuleGlobal, &FwhInstance, EfiGoneVirtual ());
+  ASSERT_EFI_ERROR (Status);
+
+  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 (TRUE);
+
+  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, mFvbModuleGlobal, EfiGoneVirtual ());
+      if (EFI_ERROR (Status)) {
+        VA_END (args);
+        return Status;
+      }
+
+      StartingLba++;
+      NumOfLba--;
+    }
+
+  } while (TRUE);
+
+  VA_END (args);
+
+  return EFI_SUCCESS;
+}
+
+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
+  )
+/*++
+
+Routine Description:
+
+  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.
+
+Arguments:
+  This                  - Calling context
+  Lba                   - Block in which to begin write
+  Offset                - Offset in the block at which to begin write
+  NumBytes              - On input, indicates the requested write size. On
+                          output, indicates the actual number of bytes written
+  Buffer                - Buffer containing source data for the write.
+
+Returns:
+  EFI_SUCCESS           - The firmware volume was written successfully
+  EFI_BAD_BUFFER_SIZE   - Write attempted across a LBA boundary. On output,
+                          NumBytes contains the total number of bytes
+                          actually written
+  EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state
+  EFI_DEVICE_ERROR      - The block device is not functioning correctly and
+                          could not be written
+  EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL
+
+--*/
+{
+
+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+  return FvbWriteBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer, mFvbModuleGlobal, EfiGoneVirtual ());
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolRead (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL       *This,
+  IN EFI_LBA                                        Lba,
+  IN UINTN                                          Offset,
+  IN OUT UINTN                                      *NumBytes,
+  IN UINT8                                          *Buffer
+  )
+/*++
+
+Routine Description:
+
+  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.
+
+Arguments:
+  This                  - Calling context
+  Lba                   - Block in which to begin Read
+  Offset                - Offset in the block at which to begin Read
+  NumBytes              - On input, indicates the requested write size. On
+                          output, indicates the actual number of bytes Read
+  Buffer                - Buffer containing source data for the Read.
+
+Returns:
+  EFI_SUCCESS           - The firmware volume was read successfully and
+                          contents are in Buffer
+  EFI_BAD_BUFFER_SIZE   - Read attempted across a LBA boundary. On output,
+                          NumBytes contains the total number of bytes returned
+                          in Buffer
+  EFI_ACCESS_DENIED     - The firmware volume is in the ReadDisabled state
+  EFI_DEVICE_ERROR      - The block device is not functioning correctly and
+                          could not be read
+  EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL
+
+--*/
+{
+
+  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+  EFI_STATUS              Status;
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+  Status    = FvbReadBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer, mFvbModuleGlobal, EfiGoneVirtual ());
+
+  return Status;
+}
+
+EFI_STATUS
+ValidateFvHeader (
+  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader
+  )
+/*++
+
+Routine Description:
+  Check the integrity of firmware volume header
+
+Arguments:
+  FwVolHeader           - A pointer to a firmware volume header
+
+Returns:
+  EFI_SUCCESS           - The firmware volume is consistent
+  EFI_NOT_FOUND         - The firmware volume has corrupted. So it is not an FV
+
+--*/
+{
+  UINT16  *Ptr;
+  UINT16  HeaderLength;
+  UINT16  Checksum;
+
+  //
+  // Verify the header revision, header signature, length
+  // Length of FvBlock cannot be 2**64-1
+  // HeaderLength cannot be an odd number
+  //
+  #ifndef R864_BUILD
+  if (((FwVolHeader->Revision != EFI_FVH_REVISION) && (FwVolHeader->Revision != EFI_FVH_REVISION)) ||
+  #else
+  if ((FwVolHeader->Revision != EFI_FVH_REVISION) ||
+  #endif
+      (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||
+      (FwVolHeader->FvLength == ((UINTN) -1)) ||
+      ((FwVolHeader->HeaderLength & 0x01) != 0)
+      ) {
+    return EFI_NOT_FOUND;
+  }
+  //
+  // Verify the header checksum
+  //
+  HeaderLength  = (UINT16) (FwVolHeader->HeaderLength / 2);
+  Ptr           = (UINT16 *) FwVolHeader;
+  Checksum      = 0;
+  while (HeaderLength > 0) {
+    Checksum = Checksum + (*Ptr);
+    Ptr++;
+    HeaderLength--;
+  }
+
+  if (Checksum != 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetFvbHeader (
+  VOID                                **HobList,
+  OUT EFI_FIRMWARE_VOLUME_HEADER      **FwVolHeader,
+  OUT EFI_PHYSICAL_ADDRESS            *BaseAddress,
+  OUT BOOLEAN                         *WriteBack
+  )
+{
+  EFI_STATUS                Status;
+
+  Status        = EFI_SUCCESS;
+  *WriteBack    = FALSE;
+
+  if (*FwVolHeader == NULL) {
+    *BaseAddress = PcdGet32 (PcdFlashFvRecoveryBase);
+  } else if (*FwVolHeader == (VOID *)(UINTN)PcdGet32 (PcdFlashFvRecoveryBase)) {
+    *BaseAddress = PcdGet32 (PcdFlashFvMainBase);
+  } else if (*FwVolHeader == (VOID *)(UINTN)PcdGet32 (PcdFlashFvMainBase)) {
+    *BaseAddress = PcdGet32 (PcdFlashNvStorageVariableBase);
+  } else {
+    return EFI_NOT_FOUND;
+  }
+
+  DEBUG((EFI_D_INFO, "Fvb base : %08x\n",*BaseAddress));
+
+  *FwVolHeader  = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (*BaseAddress);
+  Status        = ValidateFvHeader (*FwVolHeader);
+  if (EFI_ERROR (Status)) {
+    //
+    // Get FvbInfo
+    //
+    *WriteBack  = TRUE;
+
+    Status      = GetFvbInfo (*BaseAddress, FwVolHeader);
+    DEBUG(( DEBUG_ERROR, "Through GetFvbInfo: %08x!\n",*BaseAddress));
+
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+SmmSpiInit (
+  VOID
+  )
+{
+  UINT8       SpiStatus;
+  UINT8       FlashIndex;
+  UINT8       FlashID[3];
+  EFI_STATUS  Status;
+
+  //
+  // Obtain a handle for ICH SPI Protocol
+  //
+  ASSERT(mSmst != NULL);
+  if (mFvbModuleGlobal->SmmSpiProtocol == NULL){
+    Status = mSmst->SmmLocateProtocol (&gEfiSmmSpiProtocolGuid, NULL, (VOID **) &mFvbModuleGlobal->SmmSpiProtocol);
+    ASSERT_EFI_ERROR(Status);
+  }
+  //
+  // attempt to identify flash part and initialize spi table
+  //
+  for (FlashIndex = 0; FlashIndex < EnumSpiFlashMax; FlashIndex++) {
+    Status = mFvbModuleGlobal->SmmSpiProtocol->Init (
+                                                mFvbModuleGlobal->SmmSpiProtocol,
+                                                &(mSpiInitTable[FlashIndex])
+                                                );
+    if (!EFI_ERROR (Status)) {
+      //
+      // read vendor/device IDs to check if flash device is supported
+      //
+      Status = mFvbModuleGlobal->SmmSpiProtocol->Execute (
+                                                  mFvbModuleGlobal->SmmSpiProtocol,
+                                                  SPI_OPCODE_JEDEC_ID_INDEX,
+                                                  SPI_WREN_INDEX,
+                                                  TRUE,
+                                                  FALSE,
+                                                  FALSE,
+                                                  0,
+                                                  3,
+                                                  FlashID,
+                                                  EnumSpiRegionAll
+                                                  );
+      if (!EFI_ERROR (Status)) {
+        if (((FlashID[0] == mSpiInitTable[FlashIndex].VendorId) &&
+               (FlashID[2] == mSpiInitTable[FlashIndex].DeviceId1)) ||
+              ((FlashID[0] == SPI_AT26DF321_ID1) &&
+               (FlashID[0] == mSpiInitTable[FlashIndex].VendorId) &&
+               (FlashID[1] == mSpiInitTable[FlashIndex].DeviceId0))) {
+          //
+          // Supported SPI device found
+          //
+          DEBUG (
+              ((EFI_D_INFO),
+              "Smm Mode: Supported SPI Flash device found, Vendor Id: 0x%02x, Device ID: 0x%02x%02x!\n",
+              FlashID[0],
+              FlashID[1],
+              FlashID[2])
+              );
+          break;
+        }
+      }
+    }
+  }
+
+  if (FlashIndex >= EnumSpiFlashMax) {
+    Status = EFI_UNSUPPORTED;
+    DEBUG (
+        (EFI_D_ERROR,
+        "ERROR - Unknown SPI Flash Device, Vendor Id: 0x%02x, Device ID: 0x%02x%02x!\n",
+        FlashID[0],
+        FlashID[1],
+        FlashID[2])
+        );
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  SpiStatus = 0;
+  Status = mFvbModuleGlobal->SmmSpiProtocol->Execute (
+                                            mFvbModuleGlobal->SmmSpiProtocol,
+                                            SPI_OPCODE_WRITE_S_INDEX, // OpcodeIndex
+                                            1,                        // PrefixOpcodeIndex
+                                            TRUE,                     // DataCycle
+                                            TRUE,                     // Atomic
+                                            TRUE,                     // ShiftOut
+                                            0,                        // Address
+                                            1,                        // Data Number
+                                            &SpiStatus,
+                                            EnumSpiRegionAll          // SPI_REGION_TYPE
+                                            );
+  return Status;
+}
+
+EFI_STATUS
+SmmSpiNotificationFunction (
+  IN CONST EFI_GUID  *Protocol,
+  IN VOID            *Interface,
+  IN EFI_HANDLE      Handle
+  )
+{
+  return SmmSpiInit();
+}
+
+
+VOID
+EFIAPI
+GetFullDriverPath (
+  IN  EFI_HANDLE                  ImageHandle,
+  IN  EFI_SYSTEM_TABLE            *SystemTable,
+  OUT EFI_DEVICE_PATH_PROTOCOL    **CompleteFilePath
+  )
+/*++
+
+Routine Description:
+
+  Function is used to get the full device path for this driver.
+
+Arguments:
+
+  ImageHandle        - The loaded image handle of this driver.
+  SystemTable        - The pointer of system table.
+  CompleteFilePath   - The pointer of returned full file path
+
+Returns:
+
+  none
+
+--*/
+{
+  EFI_STATUS                Status;
+  EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+  EFI_DEVICE_PATH_PROTOCOL  *ImageDevicePath;
+
+
+  Status = gBS->HandleProtocol (
+                  ImageHandle,
+                  &gEfiLoadedImageProtocolGuid,
+                  (VOID **) &LoadedImage
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gBS->HandleProtocol (
+                  LoadedImage->DeviceHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID *) &ImageDevicePath
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  *CompleteFilePath = AppendDevicePath (
+                        ImageDevicePath,
+                        LoadedImage->FilePath
+                        );
+
+  return ;
+}
+
+
+
+EFI_STATUS
+FvbInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+/*++
+
+Routine Description:
+  This function does common initialization for FVB services
+
+Arguments:
+
+Returns:
+
+--*/
+{
+  EFI_STATUS                          Status;
+  EFI_FW_VOL_INSTANCE                 *FwhInstance;
+  EFI_FIRMWARE_VOLUME_HEADER          *FwVolHeader;
+  EFI_FIRMWARE_VOLUME_HEADER          *TempFwVolHeader;
+  VOID                                *HobList;
+  VOID                                *FirmwareVolumeHobList;
+  UINT32                              BufferSize;
+  EFI_FV_BLOCK_MAP_ENTRY              *PtrBlockMapEntry;
+  BOOLEAN                             WriteEnabled;
+  BOOLEAN                             WriteLocked;
+  EFI_HANDLE                          FwbHandle;
+  EFI_FW_VOL_BLOCK_DEVICE             *FvbDevice;
+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *OldFwbInterface;
+  EFI_DEVICE_PATH_PROTOCOL            *FwbDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL            *TempFwbDevicePath;
+  UINT32                              MaxLbaSize;
+  EFI_PHYSICAL_ADDRESS                BaseAddress;
+  BOOLEAN                             WriteBack;
+  UINTN                               NumOfBlocks;
+  UINTN                               HeaderLength;
+  UINT8                               SpiStatus;
+  UINT8                               FlashIndex;
+  UINT8                               FlashID[3];
+  EFI_DEVICE_PATH_PROTOCOL            *CompleteFilePath;
+  UINT8                               PrefixOpcodeIndex;
+  BOOLEAN                             InSmm;
+  EFI_SMM_BASE2_PROTOCOL              *mSmmBase2;
+  EFI_HANDLE                          Handle;
+
+  VOID                                *Registration;
+  EFI_EVENT                           Event;
+
+  CompleteFilePath = NULL;
+  GetFullDriverPath (ImageHandle, SystemTable, &CompleteFilePath);
+
+ Status = EfiGetSystemConfigurationTable (&gEfiHobListGuid, &HobList);
+
+  //
+  // No FV HOBs found
+  //
+  ASSERT_EFI_ERROR (Status);
+
+
+  //
+  // Allocate runtime services data for global variable, which contains
+  // the private data of all firmware volume block instances
+  //
+  mFvbModuleGlobal = (ESAL_FWB_GLOBAL *)AllocateRuntimeZeroPool(sizeof (ESAL_FWB_GLOBAL  ));
+  ASSERT(mFvbModuleGlobal);
+  mSmmBase2 = NULL;
+  Status = gBS->LocateProtocol (
+                  &gEfiSmmBase2ProtocolGuid,
+                  NULL,
+                  (VOID **) &mSmmBase2
+                  );
+
+  if (mSmmBase2 == NULL) {
+    InSmm = FALSE;
+  } else {
+    mSmmBase2->InSmm (mSmmBase2, &InSmm);
+    mSmmBase2->GetSmstLocation (mSmmBase2, &mSmst);
+
+  }
+
+  if (!InSmm) {
+    mInSmmMode = 0;
+    //
+    // Obtain a handle for ICH SPI Protocol
+    //
+    Status = gBS->LocateProtocol (&gEfiSpiProtocolGuid, NULL, (VOID **) &mFvbModuleGlobal->SpiProtocol);
+    ASSERT_EFI_ERROR (Status);
+
+    //
+    // attempt to identify flash part and initialize spi table
+    //
+    for (FlashIndex = 0; FlashIndex < EnumSpiFlashMax; FlashIndex++) {
+      Status = mFvbModuleGlobal->SpiProtocol->Init (
+                                                mFvbModuleGlobal->SpiProtocol,
+                                                &(mSpiInitTable[FlashIndex])
+                                                );
+      if (!EFI_ERROR (Status)) {
+        //
+        // read vendor/device IDs to check if flash device is supported
+        //
+        Status = mFvbModuleGlobal->SpiProtocol->Execute (
+                                                  mFvbModuleGlobal->SpiProtocol,
+                                                  SPI_OPCODE_JEDEC_ID_INDEX,
+                                                  SPI_WREN_INDEX,
+                                                  TRUE,
+                                                  FALSE,
+                                                  FALSE,
+                                                  0,
+                                                  3,
+                                                  FlashID,
+                                                  EnumSpiRegionAll
+                                                  );
+        if (!EFI_ERROR (Status)) {
+          if (((FlashID[0] == mSpiInitTable[FlashIndex].VendorId) &&
+               (FlashID[2] == mSpiInitTable[FlashIndex].DeviceId1)) ||
+              ((FlashID[0] == SPI_AT26DF321_ID1) &&
+               (FlashID[0] == mSpiInitTable[FlashIndex].VendorId) &&
+               (FlashID[1] == mSpiInitTable[FlashIndex].DeviceId0))) {
+            //
+            // Supported SPI device found
+            //
+            DEBUG (
+              ((EFI_D_INFO),
+              "Supported SPI Flash device found, Vendor Id: 0x%02x, Device ID: 0x%02x%02x!\n",
+              FlashID[0],
+              FlashID[1],
+              FlashID[2])
+              );
+
+            PublishFlashDeviceInfo (&mSpiInitTable[FlashIndex]);
+            break;
+          }
+        }
+      }
+    }
+
+    if (FlashIndex >= EnumSpiFlashMax) {
+      Status = EFI_UNSUPPORTED;
+      DEBUG (
+        (DEBUG_ERROR,
+        "ERROR - Unknown SPI Flash Device, Vendor Id: 0x%02x, Device ID: 0x%02x%02x!\n",
+        FlashID[0],
+        FlashID[1],
+        FlashID[2])
+        );
+      ASSERT_EFI_ERROR (Status);
+    }
+
+    //
+    // Unlock all regions by writing to status register
+    // This could be SPI device specific, need to follow the datasheet
+    // To write to Write Status Register the Spi PrefixOpcode needs to be:
+    //   0 for Atmel parts
+    //   0 for Intel parts
+    //   0 for Macronix parts
+    //   0 for Winbond parts
+    //   1 for SST parts
+    SpiStatus = 0;
+    if (FlashID[0] == SPI_SST25VF016B_ID1) {
+      PrefixOpcodeIndex = 1;
+    } else {
+      PrefixOpcodeIndex = 0;
+    }
+    Status = mFvbModuleGlobal->SpiProtocol->Execute (
+                                              mFvbModuleGlobal->SpiProtocol,
+                                              SPI_OPCODE_WRITE_S_INDEX, // OpcodeIndex
+                                              PrefixOpcodeIndex,        // PrefixOpcodeIndex
+                                              TRUE,                     // DataCycle
+                                              TRUE,                     // Atomic
+                                              TRUE,                     // ShiftOut
+                                              0,                        // Address
+                                              1,                        // Data Number
+                                              &SpiStatus,
+                                              EnumSpiRegionAll          // SPI_REGION_TYPE
+                                              );
+
+
+  } else  {
+    mInSmmMode = 1;
+
+    Status = mSmst->SmmLocateProtocol (&gEfiSmmSpiProtocolGuid, NULL, (VOID **) &mFvbModuleGlobal->SmmSpiProtocol);
+    if (EFI_ERROR(Status)) {
+      Registration = NULL;
+      Status = mSmst->SmmRegisterProtocolNotify (
+                   &gEfiSmmSpiProtocolGuid,
+                   SmmSpiNotificationFunction,
+                   &Registration
+                   );
+    } else  {
+      Status  = SmmSpiInit();
+    }
+
+  }
+
+  //
+  // Calculate the total size for all firmware volume block instances
+  //
+  BufferSize            = 0;
+  FirmwareVolumeHobList = HobList;
+  FwVolHeader           = NULL;
+  do {
+    Status = GetFvbHeader (&FirmwareVolumeHobList, &FwVolHeader, &BaseAddress, &WriteBack);
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+
+    if (FwVolHeader) {
+      BufferSize += (FwVolHeader->HeaderLength + sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER));
+    }
+  } while (TRUE);
+
+  //
+  // Only need to allocate once. There is only one copy of physical memory for
+  // the private data of each FV instance. But in virtual mode or in physical
+  // mode, the address of the the physical memory may be different.
+  //
+  mFvbModuleGlobal->FvInstance[FVB_PHYSICAL] = (EFI_FW_VOL_INSTANCE *) AllocateRuntimeZeroPool (BufferSize);
+  ASSERT(mFvbModuleGlobal->FvInstance[FVB_PHYSICAL]);
+  //
+  // Make a virtual copy of the FvInstance pointer.
+  //
+  FwhInstance = mFvbModuleGlobal->FvInstance[FVB_PHYSICAL];
+  mFvbModuleGlobal->FvInstance[FVB_VIRTUAL] = FwhInstance;
+
+  mFvbModuleGlobal->NumFv                   = 0;
+  FirmwareVolumeHobList                     = HobList;
+  TempFwVolHeader                           = NULL;
+
+  MaxLbaSize = 0;
+
+  //
+  // Fill in the private data of each firmware volume block instance
+  //
+  // Foreach Fv HOB in the FirmwareVolumeHobList, loop
+  //
+  do {
+    Status = GetFvbHeader (&FirmwareVolumeHobList, &TempFwVolHeader, &BaseAddress, &WriteBack);
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+    FwVolHeader = TempFwVolHeader;
+
+    if (!FwVolHeader) {
+      continue;
+    }
+
+
+    CopyMem ((UINTN *) &(FwhInstance->VolumeHeader), (UINTN *) FwVolHeader, FwVolHeader->HeaderLength);
+    FwVolHeader                       = &(FwhInstance->VolumeHeader);
+
+    FwhInstance->FvBase[FVB_PHYSICAL] = (UINTN) BaseAddress;
+    FwhInstance->FvBase[FVB_VIRTUAL]  = (UINTN) BaseAddress;
+
+    //
+    // FwhInstance->FvWriteBase may not be the same as FwhInstance->FvBase
+    //
+    FwhInstance->FvWriteBase[FVB_PHYSICAL]  = (UINTN) BaseAddress;
+    WriteEnabled = TRUE;
+
+    //
+    // Every pointer should have a virtual copy.
+    //
+    FwhInstance->FvWriteBase[FVB_VIRTUAL] = FwhInstance->FvWriteBase[FVB_PHYSICAL];
+
+    FwhInstance->WriteEnabled             = WriteEnabled;
+    EfiInitializeLock (&(FwhInstance->FvbDevLock), TPL_HIGH_LEVEL);
+
+    NumOfBlocks = 0;
+    WriteLocked = FALSE;
+
+    if (WriteEnabled) {
+      for (PtrBlockMapEntry = FwVolHeader->BlockMap; PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) {
+        //
+        // Get the maximum size of a block. The size will be used to allocate
+        // buffer for Scratch space, the intermediate buffer for FVB extension
+        // protocol
+        //
+        if (MaxLbaSize < PtrBlockMapEntry->Length) {
+          MaxLbaSize = PtrBlockMapEntry->Length;
+        }
+
+        NumOfBlocks = NumOfBlocks + PtrBlockMapEntry->NumBlocks;
+      }
+      //
+      //  Write back a healthy FV header
+      //
+      if (WriteBack && (!WriteLocked)) {
+
+        Status = FlashFdErase (
+                  (UINTN) FwhInstance->FvWriteBase[0],
+                  (UINTN) BaseAddress,
+                  FwVolHeader->BlockMap->Length
+                  );
+
+        HeaderLength = (UINTN) FwVolHeader->HeaderLength;
+        Status = FlashFdWrite (
+                  (UINTN) FwhInstance->FvWriteBase[0],
+                  (UINTN) BaseAddress,
+                  &HeaderLength,
+                  (UINT8 *) FwVolHeader,
+                  FwVolHeader->BlockMap->Length
+                  );
+
+      }
+    }
+    //
+    // The total number of blocks in the FV.
+    //
+    FwhInstance->NumOfBlocks = NumOfBlocks;
+
+    //
+    // If the FV is write locked, set the appropriate attributes
+    //
+    if (WriteLocked) {
+      //
+      // write disabled
+      //
+      FwhInstance->VolumeHeader.Attributes &= ~EFI_FVB2_WRITE_STATUS;
+      //
+      // lock enabled
+      //
+      FwhInstance->VolumeHeader.Attributes |= EFI_FVB2_LOCK_STATUS;
+    }
+
+    //
+    // Allocate and initialize FVB Device in a runtime data buffer
+    //
+    FvbDevice = AllocateRuntimeCopyPool (sizeof (EFI_FW_VOL_BLOCK_DEVICE), &mFvbDeviceTemplate);
+    ASSERT (FvbDevice);
+
+    FvbDevice->Instance = mFvbModuleGlobal->NumFv;
+    mFvbModuleGlobal->NumFv++;
+
+    //
+    // FV does not contains extension header, then produce MEMMAP_DEVICE_PATH
+    //
+    if (FwVolHeader->ExtHeaderOffset == 0) {
+      FvbDevice->FvDevicePath.MemMapDevPath.StartingAddress = BaseAddress;
+      FvbDevice->FvDevicePath.MemMapDevPath.EndingAddress   = BaseAddress + (FwVolHeader->FvLength - 1);
+      FwbDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)&FvbDevice->FvDevicePath;
+    } else {
+      CopyGuid (
+        &FvbDevice->UefiFvDevicePath.FvDevPath.FvName,
+        (EFI_GUID *)(UINTN)(BaseAddress + FwVolHeader->ExtHeaderOffset)
+        );
+      FwbDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)&FvbDevice->UefiFvDevicePath;
+    }
+
+    if (!InSmm) {
+      //
+      // Find a handle with a matching device path that has supports FW Block protocol
+      //
+      TempFwbDevicePath = FwbDevicePath;
+      Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &TempFwbDevicePath, &FwbHandle);
+      if (EFI_ERROR (Status)) {
+        //
+        // LocateDevicePath fails so install a new interface and device path
+        //
+        FwbHandle = NULL;
+        Status = gBS->InstallMultipleProtocolInterfaces (
+                        &FwbHandle,
+                        &gEfiFirmwareVolumeBlockProtocolGuid,
+                        &FvbDevice->FwVolBlockInstance,
+                        &gEfiDevicePathProtocolGuid,
+                        FwbDevicePath,
+                        NULL
+                        );
+        ASSERT_EFI_ERROR (Status);
+      } else if (EfiIsDevicePathEnd (TempFwbDevicePath)) {
+        //
+        // Device already exists, so reinstall the FVB protocol
+        //
+        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);
+      }
+    } else {
+      FwbHandle = NULL;
+      Status = mSmst->SmmInstallProtocolInterface (
+                &FwbHandle,
+                &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+                EFI_NATIVE_INTERFACE,
+                &FvbDevice->FwVolBlockInstance
+                );
+      ASSERT_EFI_ERROR (Status);
+    }
+
+    FwhInstance = (EFI_FW_VOL_INSTANCE *)
+      (
+        (UINTN) ((UINT8 *) FwhInstance) + FwVolHeader->HeaderLength +
+          (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))
+      );
+  } while (TRUE);
+
+  //
+  // Allocate for scratch space, an intermediate buffer for FVB extention
+  //
+
+  mFvbModuleGlobal->FvbScratchSpace[FVB_PHYSICAL] = AllocateRuntimeZeroPool (MaxLbaSize);
+
+  ASSERT (mFvbModuleGlobal->FvbScratchSpace[FVB_PHYSICAL]);
+
+  mFvbModuleGlobal->FvbScratchSpace[FVB_VIRTUAL] = mFvbModuleGlobal->FvbScratchSpace[FVB_PHYSICAL];
+
+  if (!InSmm) {
+    Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                 FvbVirtualddressChangeEvent,
+                  NULL,
+                  &gEfiEventVirtualAddressChangeGuid,
+                  &Event
+                  );
+    ASSERT_EFI_ERROR (Status);
+  } else {
+    //
+    // Inform other platform drivers that SPI device discovered and
+    // SPI interface ready for use.
+    //
+    Handle = NULL;
+    Status = gBS->InstallProtocolInterface (
+                    &Handle,
+                    &gEfiSmmSpiReadyProtocolGuid,
+                    EFI_NATIVE_INTERFACE,
+                    NULL
+                    );
+  }
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.h b/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.h
new file mode 100644
index 0000000000..11dcf12230
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.h
@@ -0,0 +1,308 @@
+/** @file
+Firmware volume block driver for SPI device
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#ifndef _FW_BLOCK_SERVICE_H
+#define _FW_BLOCK_SERVICE_H
+
+
+#include "SpiFlashDevice.h"
+
+//
+// Statements that include other header files
+
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Guid/EventGroup.h>
+#include <Guid/HobList.h>
+#include <Guid/FirmwareFileSystem2.h>
+#include <Guid/SystemNvDataGuid.h>
+
+#include <Protocol/SmmBase2.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/PlatformSmmSpiReady.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)
+
+#define EFI_INTERNAL_POINTER  0x00000004
+#define FVB_PHYSICAL  0
+#define FVB_VIRTUAL   1
+
+typedef struct {
+  EFI_LOCK                    FvbDevLock;
+  UINTN                       FvBase[2];
+  UINTN                       FvWriteBase[2];
+  UINTN                       NumOfBlocks;
+  BOOLEAN                     WriteEnabled;
+  EFI_FIRMWARE_VOLUME_HEADER  VolumeHeader;
+} EFI_FW_VOL_INSTANCE;
+
+typedef struct {
+  UINT32                NumFv;
+  EFI_FW_VOL_INSTANCE   *FvInstance[2];
+  UINT8                 *FvbScratchSpace[2];
+  EFI_SPI_PROTOCOL      *SpiProtocol;
+  EFI_SPI_PROTOCOL      *SmmSpiProtocol;
+} ESAL_FWB_GLOBAL;
+
+//
+// SPI default opcode slots
+//
+#define SPI_OPCODE_JEDEC_ID_INDEX        0
+#define SPI_OPCODE_READ_ID_INDEX         1
+#define SPI_OPCODE_WRITE_S_INDEX         2
+#define SPI_OPCODE_WRITE_INDEX           3
+#define SPI_OPCODE_READ_INDEX            4
+#define SPI_OPCODE_ERASE_INDEX           5
+#define SPI_OPCODE_READ_S_INDEX          6
+#define SPI_OPCODE_CHIP_ERASE_INDEX      7
+
+#define SPI_ERASE_SECTOR_SIZE            SIZE_4KB  //This is the chipset requirement
+
+//
+// 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')
+//
+// Device Path
+//
+#define EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE    0xff
+#define EfiDevicePathType(a)                  (((a)->Type) & 0x7f)
+#define EfiIsDevicePathEndType(a)             (EfiDevicePathType (a) == 0x7f)
+#define EfiIsDevicePathEndSubType(a)          ((a)->SubType == EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE)
+#define EfiIsDevicePathEnd(a)                 (EfiIsDevicePathEndType (a) && EfiIsDevicePathEndSubType (a))
+
+typedef struct {
+  MEMMAP_DEVICE_PATH        MemMapDevPath;
+  EFI_DEVICE_PATH_PROTOCOL  EndDevPath;
+} FV_DEVICE_PATH;
+
+//
+// UEFI Specification define FV device path format if FV provide name GUID in extension header
+//
+typedef struct {
+  MEDIA_FW_VOL_DEVICE_PATH    FvDevPath;
+  EFI_DEVICE_PATH_PROTOCOL    EndDevPath;
+} UEFI_FV_DEVICE_PATH;
+
+typedef struct {
+  UINTN                               Signature;
+  FV_DEVICE_PATH                      FvDevicePath;
+  UEFI_FV_DEVICE_PATH                 UefiFvDevicePath;
+  UINTN                               Instance;
+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  FwVolBlockInstance;
+} EFI_FW_VOL_BLOCK_DEVICE;
+
+typedef struct {
+  EFI_PHYSICAL_ADDRESS        BaseAddress;
+  EFI_FIRMWARE_VOLUME_HEADER  FvbInfo;
+  //
+  // EFI_FV_BLOCK_MAP_ENTRY                ExtraBlockMap[n];//n=0
+  //
+  EFI_FV_BLOCK_MAP_ENTRY      End[1];
+} EFI_FVB_MEDIA_INFO;
+
+VOID
+FvbVirtualddressChangeEvent (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  );
+
+EFI_STATUS
+GetFvbInfo (
+  IN  EFI_PHYSICAL_ADDRESS              FvBaseAddress,
+  OUT EFI_FIRMWARE_VOLUME_HEADER        **FvbInfo
+  );
+
+BOOLEAN
+SetPlatformFvbLock (
+  IN UINTN                              LbaAddress
+  );
+
+EFI_STATUS
+FvbReadBlock (
+  IN UINTN                              Instance,
+  IN EFI_LBA                            Lba,
+  IN UINTN                              BlockOffset,
+  IN OUT UINTN                          *NumBytes,
+  IN UINT8                              *Buffer,
+  IN ESAL_FWB_GLOBAL                    *Global,
+  IN BOOLEAN                            Virtual
+  );
+
+EFI_STATUS
+FvbWriteBlock (
+  IN UINTN                              Instance,
+  IN EFI_LBA                            Lba,
+  IN UINTN                              BlockOffset,
+  IN OUT UINTN                          *NumBytes,
+  IN UINT8                              *Buffer,
+  IN ESAL_FWB_GLOBAL                    *Global,
+  IN BOOLEAN                            Virtual
+  );
+
+EFI_STATUS
+FvbEraseBlock (
+  IN UINTN                              Instance,
+  IN EFI_LBA                            Lba,
+  IN ESAL_FWB_GLOBAL                    *Global,
+  IN BOOLEAN                            Virtual
+  );
+
+EFI_STATUS
+FvbSetVolumeAttributes (
+  IN UINTN                              Instance,
+  IN OUT EFI_FVB_ATTRIBUTES_2             *Attributes,
+  IN ESAL_FWB_GLOBAL                    *Global,
+  IN BOOLEAN                            Virtual
+  );
+
+EFI_STATUS
+FvbGetVolumeAttributes (
+  IN UINTN                              Instance,
+  OUT EFI_FVB_ATTRIBUTES_2                *Attributes,
+  IN ESAL_FWB_GLOBAL                    *Global,
+  IN BOOLEAN                            Virtual
+  );
+
+EFI_STATUS
+FvbGetPhysicalAddress (
+  IN UINTN                              Instance,
+  OUT EFI_PHYSICAL_ADDRESS              *Address,
+  IN ESAL_FWB_GLOBAL                    *Global,
+  IN BOOLEAN                            Virtual
+  );
+
+EFI_STATUS
+FvbInitialize (
+  IN EFI_HANDLE                         ImageHandle,
+  IN EFI_SYSTEM_TABLE                   *SystemTable
+  );
+
+VOID
+FvbClassAddressChangeEvent (
+  IN EFI_EVENT                          Event,
+  IN VOID                               *Context
+  );
+
+EFI_STATUS
+FvbSpecificInitialize (
+  IN  ESAL_FWB_GLOBAL                   *mFvbModuleGlobal
+  );
+
+EFI_STATUS
+FvbGetLbaAddress (
+  IN  UINTN                             Instance,
+  IN  EFI_LBA                           Lba,
+  OUT UINTN                             *LbaAddress,
+  OUT UINTN                             *LbaWriteAddress,
+  OUT UINTN                             *LbaLength,
+  OUT UINTN                             *NumOfBlocks,
+  IN  ESAL_FWB_GLOBAL                   *Global,
+  IN  BOOLEAN                           Virtual
+  );
+
+EFI_STATUS
+FvbEraseCustomBlockRange (
+  IN UINTN                              Instance,
+  IN EFI_LBA                            StartLba,
+  IN UINTN                              OffsetStartLba,
+  IN EFI_LBA                            LastLba,
+  IN UINTN                              OffsetLastLba,
+  IN ESAL_FWB_GLOBAL                    *Global,
+  IN BOOLEAN                            Virtual
+  );
+
+//
+// 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
+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,
+  IN 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,
+  ...
+  );
+
+extern SPI_INIT_TABLE   mSpiInitTable[];
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.c b/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.c
new file mode 100644
index 0000000000..a658bc9a29
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.c
@@ -0,0 +1,31 @@
+/** @file
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#include "FwBlockService.h"
+
+
+/**
+  This function allows the caller to determine if UEFI SetVirtualAddressMap() has been called.
+
+  This function returns TRUE after all the EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE functions have
+  executed as a result of the OS calling SetVirtualAddressMap(). Prior to this time FALSE
+  is returned. This function is used by runtime code to decide it is legal to access services
+  that go away after SetVirtualAddressMap().
+
+  @retval  TRUE  The system has finished executing the EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
+  @retval  FALSE The system has not finished executing the EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
+
+**/
+BOOLEAN
+EfiGoneVirtual (
+  VOID
+  )
+{
+  return FALSE; //Hard coded to FALSE for SMM driver.
+}
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.inf b/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.inf
new file mode 100644
index 0000000000..6f263a4f19
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.inf
@@ -0,0 +1,80 @@
+## @file
+# Component description file for SpiFvbServices Module
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = FwBlockServiceSmm
+  FILE_GUID                      = A469DDBD-16D0-4535-BAE3-77274BD70B4C
+  MODULE_TYPE                    = DXE_SMM_DRIVER
+  VERSION_STRING                 = 1.0
+  PI_SPECIFICATION_VERSION       = 0x0001000A
+  ENTRY_POINT                    = FvbInitialize
+
+[Sources]
+  FwBlockService.c
+  FwBlockService.h
+  FvbInfo.c
+  SpiFlashDevice.c
+  SpiFlashDevice.h
+  PlatformSmmSpi.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+  IoLib
+  PcdLib
+  HobLib
+  UefiLib
+  BaseMemoryLib
+  UefiDriverEntryPoint
+  MemoryAllocationLib
+  UefiRuntimeServicesTableLib
+  UefiBootServicesTableLib
+  DxeServicesTableLib
+
+[Guids]
+  gEfiEventVirtualAddressChangeGuid
+  gEfiHobListGuid
+
+ [Protocols]
+  gEfiFirmwareVolumeBlockProtocolGuid  ##Produces
+  gEfiSpiProtocolGuid
+  gEfiDevicePathProtocolGuid
+  gEfiLoadedImageProtocolGuid
+  gEfiSmmBase2ProtocolGuid
+  gEfiSmmSpiProtocolGuid
+  gEfiSmmFirmwareVolumeBlockProtocolGuid
+  gEfiSmmSpiReadyProtocolGuid
+
+[FixedPcd]
+  gQuarkPlatformTokenSpaceGuid.PcdFlashAreaSize
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+  gQuarkPlatformTokenSpaceGuid.PcdFlashAreaBaseAddress
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvMainSize
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvMainBase
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoveryBase
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoverySize
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvPayloadBase
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvPayloadSize
+  gQuarkPlatformTokenSpaceGuid.PcdSpiFlashDeviceSize
+
+[Depex]
+  gEfiSpiProtocolGuid
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSpi.inf b/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSpi.inf
new file mode 100644
index 0000000000..4ac4d0754a
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSpi.inf
@@ -0,0 +1,79 @@
+## @file
+# Component description file for SpiFvbServices Module
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = FwBlockService
+  FILE_GUID                      = 4D35A5A7-622E-4955-A5D2-CDA812940D74
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = FvbInitialize
+
+[Sources]
+  FwBlockService.c
+  FwBlockService.h
+  FvbInfo.c
+  SpiFlashDevice.c
+  SpiFlashDevice.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+  QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+  IoLib
+  PcdLib
+  HobLib
+  UefiLib
+  BaseMemoryLib
+  UefiDriverEntryPoint
+  MemoryAllocationLib
+  UefiRuntimeLib
+  UefiRuntimeServicesTableLib
+  UefiBootServicesTableLib
+  DxeServicesTableLib
+
+[Guids]
+  gEfiEventVirtualAddressChangeGuid
+  gEfiHobListGuid
+
+ [Protocols]
+  gEfiFirmwareVolumeBlockProtocolGuid  ##Produces
+  gEfiSpiProtocolGuid
+  gEfiDevicePathProtocolGuid
+  gEfiLoadedImageProtocolGuid
+  gEfiSmmBase2ProtocolGuid
+  gEfiSmmSpiProtocolGuid
+  gEfiSmmFirmwareVolumeBlockProtocolGuid
+  gEfiSmmSpiReadyProtocolGuid
+
+[FixedPcd]
+  gQuarkPlatformTokenSpaceGuid.PcdFlashAreaSize
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+  gQuarkPlatformTokenSpaceGuid.PcdFlashAreaBaseAddress
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvMainSize
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvMainBase
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoveryBase
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoverySize
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvPayloadBase
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvPayloadSize
+  gQuarkPlatformTokenSpaceGuid.PcdSpiFlashDeviceSize
+
+[Depex]
+  gEfiSpiProtocolGuid
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.c b/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.c
new file mode 100644
index 0000000000..8a86fc406d
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.c
@@ -0,0 +1,331 @@
+/** @file
+Initializes Platform Specific Drivers.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#include "SpiFlashDevice.h"
+
+#define FLASH_SIZE  (FixedPcdGet32 (PcdFlashAreaSize))
+
+SPI_INIT_TABLE  mSpiInitTable[] = {
+  //
+  // Macronix 32Mbit part
+  //
+  {
+    SPI_MX25L3205_ID1,
+    SPI_MX25L3205_ID2,
+    SPI_MX25L3205_ID3,
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle33MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle33MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle33MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle33MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle20MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_BLOCK_ERASE, EnumSpiCycle33MHz, EnumSpiOperationErase_64K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle33MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle33MHz, EnumSpiOperationFullChipErase}
+    },
+    0x400000 - FLASH_SIZE, // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+  //
+  // Winbond 32Mbit part
+  //
+  {
+    SPI_W25X32_ID1,
+    SF_DEVICE_ID0_W25QXX,
+    SF_DEVICE_ID1_W25Q32,
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle50MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle50MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_ERASE,       EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+    },
+    0x400000 - FLASH_SIZE, // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+  //
+  // Winbond 32Mbit part
+  //
+  {
+    SPI_W25X32_ID1,
+    SPI_W25X32_ID2,
+    SPI_W25X32_ID3,
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle33MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle33MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle33MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle33MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle33MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_ERASE,       EnumSpiCycle33MHz, EnumSpiOperationErase_4K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle33MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle33MHz, EnumSpiOperationFullChipErase}
+    },
+    0x400000 - FLASH_SIZE, // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+  //
+  // Atmel 32Mbit part
+  //
+  {
+    SPI_AT26DF321_ID1,
+    SPI_AT26DF321_ID2,  // issue: byte 2 identifies family/density for Atmel
+    SPI_AT26DF321_ID3,
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle33MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle33MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle33MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle33MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle33MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_BLOCK_ERASE, EnumSpiCycle33MHz, EnumSpiOperationErase_64K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle33MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle33MHz, EnumSpiOperationFullChipErase}
+    },
+    0x400000 - FLASH_SIZE, // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+
+  //
+  // Intel 32Mbit part bottom boot
+  //
+  {
+    SPI_QH25F320_ID1,
+    SPI_QH25F320_ID2,
+    SPI_QH25F320_ID3,
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_ENABLE
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle33MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle33MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle33MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle33MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle33MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_BLOCK_ERASE, EnumSpiCycle33MHz, EnumSpiOperationErase_64K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle33MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle33MHz, EnumSpiOperationFullChipErase}
+    },
+    0,           // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+  //
+  // SST 64Mbit part
+  //
+  {
+    SPI_SST25VF080B_ID1,      // VendorId
+    SF_DEVICE_ID0_25VF064C,   // DeviceId 0
+    SF_DEVICE_ID1_25VF064C,   // DeviceId 1
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle50MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle50MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_ERASE,       EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+    },
+    0x800000 - FLASH_SIZE,          // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+  //
+  // NUMONYX 64Mbit part
+  //
+  {
+    SF_VENDOR_ID_NUMONYX,     // VendorId
+    SF_DEVICE_ID0_M25PX64,    // DeviceId 0
+    SF_DEVICE_ID1_M25PX64,    // DeviceId 1
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle50MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle50MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_ERASE,       EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+    },
+    0x800000 - FLASH_SIZE,          // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+  //
+  // Atmel 64Mbit part
+  //
+  {
+    SF_VENDOR_ID_ATMEL,       // VendorId
+    SF_DEVICE_ID0_AT25DF641,  // DeviceId 0
+    SF_DEVICE_ID1_AT25DF641,  // DeviceId 1
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle50MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle50MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_ERASE,       EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+    },
+    0x800000 - FLASH_SIZE,          // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+
+  //
+  // Spansion 64Mbit part
+  //
+  {
+    SF_VENDOR_ID_SPANSION,       // VendorId
+    SF_DEVICE_ID0_S25FL064K,  // DeviceId 0
+    SF_DEVICE_ID1_S25FL064K,  // DeviceId 1
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle50MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle50MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_ERASE,       EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+    },
+    0x800000 - FLASH_SIZE,          // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+
+  //
+  // Macronix 64Mbit part bottom boot
+  //
+  {
+    SF_VENDOR_ID_MX,          // VendorId
+    SF_DEVICE_ID0_25L6405D,   // DeviceId 0
+    SF_DEVICE_ID1_25L6405D,   // DeviceId 1
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle50MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle50MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_BLOCK_ERASE, EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+    },
+    0x800000 - FLASH_SIZE,          // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+  //
+  // Winbond 64Mbit part bottom boot
+  //
+  {
+    SPI_W25X64_ID1,
+    SF_DEVICE_ID0_W25QXX,
+    SF_DEVICE_ID1_W25Q64,
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle50MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle50MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_ERASE,       EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+    },
+    0x800000 - FLASH_SIZE,          // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+  //
+  // Winbond 64Mbit part bottom boot
+  //
+  {
+    SPI_W25X64_ID1,
+    SPI_W25X64_ID2,
+    SPI_W25X64_ID3,
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle50MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle50MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_ERASE,       EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+    },
+    0x800000 - FLASH_SIZE,          // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  },
+  //
+  // Intel 64Mbit part bottom boot
+  //
+  {
+    SPI_QH25F640_ID1,
+    SPI_QH25F640_ID2,
+    SPI_QH25F640_ID3,
+    {
+      SPI_COMMAND_WRITE_ENABLE,
+      SPI_COMMAND_WRITE_S_EN
+    },
+    {
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_JEDEC_ID,    EnumSpiCycle33MHz, EnumSpiOperationJedecId},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ_ID,     EnumSpiCycle33MHz, EnumSpiOperationOther},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S,     EnumSpiCycle33MHz, EnumSpiOperationWriteStatus},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_WRITE,       EnumSpiCycle33MHz, EnumSpiOperationProgramData_1_Byte},
+      {EnumSpiOpcodeRead,        SPI_COMMAND_READ,        EnumSpiCycle33MHz, EnumSpiOperationReadData},
+      {EnumSpiOpcodeWrite,       SPI_COMMAND_BLOCK_ERASE, EnumSpiCycle33MHz, EnumSpiOperationErase_64K_Byte},
+      {EnumSpiOpcodeReadNoAddr,  SPI_COMMAND_READ_S,      EnumSpiCycle33MHz, EnumSpiOperationReadStatus},
+      {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE,  EnumSpiCycle33MHz, EnumSpiOperationFullChipErase}
+    },
+    0x800000 - FLASH_SIZE,          // BIOS Start Offset
+    FLASH_SIZE   // BIOS image size in flash
+  }
+};
diff --git a/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.h b/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.h
new file mode 100644
index 0000000000..ee8d97a2bb
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.h
@@ -0,0 +1,181 @@
+/** @file
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#ifndef _SPI_FLASH_DEVICE_H_
+#define _SPI_FLASH_DEVICE_H_
+
+#include <PiDxe.h>
+#include <Protocol/Spi.h>
+#include <Protocol/FirmwareVolumeBlock.h>
+
+//
+// Supported SPI Flash Devices
+//
+typedef enum {
+  EnumSpiFlash25L3205D,   // Macronix 32Mbit part
+  EnumSpiFlashW25Q32,     // Winbond 32Mbit part
+  EnumSpiFlashW25X32,     // Winbond 32Mbit part
+  EnumSpiFlashAT25DF321,  // Atmel 32Mbit part
+  EnumSpiFlashQH25F320,   // Intel 32Mbit part
+  EnumSpiFlash25VF064C,   // SST 64Mbit part
+  EnumSpiFlashM25PX64,    // NUMONYX 64Mbit part
+  EnumSpiFlashAT25DF641,  // Atmel 64Mbit part
+  EnumSpiFlashS25FL064K,  // Spansion 64Mbit part
+  EnumSpiFlash25L6405D,   // Macronix 64Mbit part
+  EnumSpiFlashW25Q64,     // Winbond 64Mbit part
+  EnumSpiFlashW25X64,     // Winbond 64Mbit part
+  EnumSpiFlashQH25F640,   // Intel 64Mbit part
+  EnumSpiFlashMax
+} SPI_FLASH_TYPES_SUPPORTED;
+
+//
+// Flash Device commands
+//
+// If a supported device uses a command different from the list below, a device specific command
+// will be defined just below it's JEDEC id section.
+//
+#define SPI_COMMAND_WRITE                 0x02
+#define SPI_COMMAND_WRITE_AAI             0xAD
+#define SPI_COMMAND_READ                  0x03
+#define SPI_COMMAND_ERASE                 0x20
+#define SPI_COMMAND_WRITE_DISABLE         0x04
+#define SPI_COMMAND_READ_S                0x05
+#define SPI_COMMAND_WRITE_ENABLE          0x06
+#define SPI_COMMAND_READ_ID               0xAB
+#define SPI_COMMAND_JEDEC_ID              0x9F
+#define SPI_COMMAND_WRITE_S_EN            0x50
+#define SPI_COMMAND_WRITE_S               0x01
+#define SPI_COMMAND_CHIP_ERASE            0xC7
+#define SPI_COMMAND_BLOCK_ERASE           0xD8
+
+//
+// Flash JEDEC device ids
+//
+// SST 8Mbit part
+//
+#define SPI_SST25VF080B_ID1               0xBF
+#define SPI_SST25VF080B_ID2               0x25
+#define SPI_SST25VF080B_ID3               0x8E
+//
+// SST 16Mbit part
+//
+#define SPI_SST25VF016B_ID1               0xBF
+#define SPI_SST25VF016B_ID2               0x25
+#define SPI_SST25V016BF_ID3               0x41
+//
+// Macronix 32Mbit part
+//
+// MX25 part does not support WRITE_AAI comand (0xAD)
+//
+#define SPI_MX25L3205_ID1                 0xC2
+#define SPI_MX25L3205_ID2                 0x20
+#define SPI_MX25L3205_ID3                 0x16
+//
+// Intel 32Mbit part bottom boot
+//
+#define SPI_QH25F320_ID1                  0x89
+#define SPI_QH25F320_ID2                  0x89
+#define SPI_QH25F320_ID3                  0x12  // 32Mbit bottom boot
+//
+// Intel 64Mbit part bottom boot
+//
+#define SPI_QH25F640_ID1                  0x89
+#define SPI_QH25F640_ID2                  0x89
+#define SPI_QH25F640_ID3                  0x13  // 64Mbit bottom boot
+//
+// QH part does not support command 0x20 for erase; only 0xD8 (sector erase)
+// QH part has 0x40 command for erase of parameter block (8 x 8K blocks at bottom of part)
+// 0x40 command ignored if address outside of parameter block range
+//
+#define SPI_QH25F320_COMMAND_PBLOCK_ERASE 0x40
+//
+// Winbond 32Mbit part
+//
+#define SPI_W25X32_ID1                    0xEF
+#define SPI_W25X32_ID2                    0x30  // Memory Type
+#define SPI_W25X32_ID3                    0x16  // Capacity
+#define SF_DEVICE_ID1_W25Q32              0x16
+
+//
+// Winbond 64Mbit part
+//
+#define SPI_W25X64_ID1                    0xEF
+#define SPI_W25X64_ID2                    0x30  // Memory Type
+#define SPI_W25X64_ID3                    0x17  // Capacity
+#define SF_DEVICE_ID0_W25QXX              0x40
+#define SF_DEVICE_ID1_W25Q64              0x17
+//
+// Winbond 128Mbit part
+//
+#define SF_DEVICE_ID0_W25Q128             0x40
+#define SF_DEVICE_ID1_W25Q128             0x18
+
+//
+// Atmel 32Mbit part
+//
+#define SPI_AT26DF321_ID1                 0x1F
+#define SPI_AT26DF321_ID2                 0x47  // [7:5]=Family, [4:0]=Density
+#define SPI_AT26DF321_ID3                 0x00
+
+#define SF_VENDOR_ID_ATMEL                0x1F
+#define SF_DEVICE_ID0_AT25DF641           0x48
+#define SF_DEVICE_ID1_AT25DF641           0x00
+
+//
+// SST 8Mbit part
+//
+#define SPI_SST25VF080B_ID1               0xBF
+#define SPI_SST25VF080B_ID2               0x25
+#define SPI_SST25VF080B_ID3               0x8E
+#define SF_DEVICE_ID0_25VF064C            0x25
+#define SF_DEVICE_ID1_25VF064C            0x4B
+
+//
+// SST 16Mbit part
+//
+#define SPI_SST25VF016B_ID1               0xBF
+#define SPI_SST25VF016B_ID2               0x25
+#define SPI_SST25V016BF_ID3               0x41
+
+//
+// Winbond 32Mbit part
+//
+#define SPI_W25X32_ID1                    0xEF
+#define SPI_W25X32_ID2                    0x30  // Memory Type
+#define SPI_W25X32_ID3                    0x16  // Capacity
+
+#define  SF_VENDOR_ID_MX             0xC2
+#define  SF_DEVICE_ID0_25L6405D      0x20
+#define  SF_DEVICE_ID1_25L6405D      0x17
+
+#define  SF_VENDOR_ID_NUMONYX        0x20
+#define  SF_DEVICE_ID0_M25PX64       0x71
+#define  SF_DEVICE_ID1_M25PX64       0x17
+
+//
+// Spansion 64Mbit part
+//
+#define SF_VENDOR_ID_SPANSION             0xEF
+#define SF_DEVICE_ID0_S25FL064K           0x40
+#define SF_DEVICE_ID1_S25FL064K           0x00
+
+//
+// index for prefix opcodes
+//
+#define SPI_WREN_INDEX                    0   // Prefix Opcode 0: SPI_COMMAND_WRITE_ENABLE
+#define SPI_EWSR_INDEX                    1   // Prefix Opcode 1: SPI_COMMAND_WRITE_S_EN
+#define BIOS_CTRL                         0xDC
+
+#define PFAB_CARD_DEVICE_ID               0x5150
+#define PFAB_CARD_VENDOR_ID               0x8086
+#define PFAB_CARD_SETUP_REGISTER          0x40
+#define PFAB_CARD_SETUP_BYTE              0x0d
+
+
+#endif
diff --git a/Platform/Intel/QuarkPlatformPkg/Quark.dsc b/Platform/Intel/QuarkPlatformPkg/Quark.dsc
new file mode 100644
index 0000000000..e5ebeb5e09
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Quark.dsc
@@ -0,0 +1,948 @@
+## @file
+# Clanton Peak CRB platform with 32-bit DXE for 4MB/8MB flash devices.
+#
+# This package provides Clanton Peak CRB platform specific modules.
+# Copyright (c) 2013 - 2019 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  DSC_SPECIFICATION              = 0x00010005
+  PLATFORM_NAME                  = Quark
+  PLATFORM_GUID                  = F6E7730E-0C7A-4741-9DFC-6BC8B86CD865
+  PLATFORM_VERSION               = 0.1
+  FLASH_DEFINITION               = QuarkPlatformPkg/Quark.fdf
+  OUTPUT_DIRECTORY               = Build/Quark
+  SUPPORTED_ARCHITECTURES        = IA32
+  BUILD_TARGETS                  = DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+  VPD_TOOL_GUID                  = 8C3D856A-9BE6-468E-850A-24F7A8D38E08
+
+  #
+  # Platform On/Off features are defined here
+  #
+  DEFINE SECURE_BOOT_ENABLE   = FALSE
+  DEFINE MEASURED_BOOT_ENABLE = FALSE
+  DEFINE SOURCE_DEBUG_ENABLE  = FALSE
+  DEFINE PERFORMANCE_ENABLE   = FALSE
+  DEFINE LOGGING              = FALSE
+  DEFINE CAPSULE_ENABLE       = FALSE
+  DEFINE RECOVERY_ENABLE      = FALSE
+
+  #
+  # Galileo board.  Options are [GEN1, GEN2]
+  #
+  DEFINE GALILEO              = GEN2
+
+  #
+  # TPM 1.2 Hardware.  Options are [NONE, LPC, ATMEL_I2C, INFINEON_I2C]
+  #
+  DEFINE TPM_12_HARDWARE      = NONE
+
+  !if $(TARGET) == "DEBUG"
+    DEFINE LOGGING = TRUE
+  !endif
+
+  !if $(PERFORMANCE_ENABLE)
+    DEFINE SOURCE_DEBUG_ENABLE = FALSE
+    DEFINE LOGGING             = FALSE
+  !endif
+
+################################################################################
+#
+# SKU Identification section - list of all SKU IDs supported by this
+#                              Platform.
+#
+################################################################################
+[SkuIds]
+  0|DEFAULT              # The entry: 0|DEFAULT is reserved and always required.
+
+################################################################################
+#
+# Library Class section - list of all Library Classes needed by this Platform.
+#
+################################################################################
+[LibraryClasses]
+  #
+  # Entry point
+  #
+  PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
+  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+
+  #
+  # Basic
+  #
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+  PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf
+  PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
+  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
+  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
+  CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+!if $(SOURCE_DEBUG_ENABLE)
+  PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
+  DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf
+!else
+  PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+!endif
+  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+
+  #
+  # UEFI & PI
+  #
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  UefiDecompressLib|MdeModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf
+  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+  UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
+  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+
+  #
+  # Generic Modules
+  #
+  S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
+  S3IoLib|MdePkg/Library/BaseS3IoLib/BaseS3IoLib.inf
+  S3PciLib|MdePkg/Library/BaseS3PciLib/BaseS3PciLib.inf
+  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+  IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
+  UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
+  DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
+  SmmCorePlatformHookLib|MdeModulePkg/Library/SmmCorePlatformHookLibNull/SmmCorePlatformHookLibNull.inf
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+  LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf
+  VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+!if $(LOGGING)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+!endif
+!if $(PERFORMANCE_ENABLE)
+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+!else
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+!endif
+
+  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+
+!if $(SECURE_BOOT_ENABLE)
+  PlatformSecureLib|QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
+  AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
+!else
+  AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
+!endif
+
+!if $(MEASURED_BOOT_ENABLE)
+  TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
+  Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf
+!if $(TPM_12_HARDWARE) == LPC
+  Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLibDTpm.inf
+!endif
+!if $(TPM_12_HARDWARE) == ATMEL_I2C
+  Tpm12DeviceLib|QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.inf
+!endif
+!if $(TPM_12_HARDWARE) == INFINEON_I2C
+  Tpm12DeviceLib|QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/Tpm12DeviceLibInfineonI2c.inf
+!endif
+  TcgPpVendorLib|SecurityPkg/Library/TcgPpVendorLibNull/TcgPpVendorLibNull.inf
+!else
+  TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
+!endif
+
+  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+
+  #
+  # CPU
+  #
+  MtrrLib|QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.inf
+  LocalApicLib|UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf
+  MpInitLib|UefiCpuPkg/Library/MpInitLibUp/MpInitLibUp.inf
+
+  #
+  # Quark North Cluster
+  #
+  SmmLib|QuarkSocPkg/QuarkNorthCluster/Library/QNCSmmLib/QNCSmmLib.inf
+  SmbusLib|QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/SmbusLib.inf
+  TimerLib|PcAtChipsetPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
+  ResetSystemLib|QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/ResetSystemLib.inf
+  IntelQNCLib|QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNCLib.inf
+  QNCAccessLib|QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/QNCAccessLib.inf
+  IoApicLib|PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf
+
+  #
+  # Quark South Cluster
+  #
+  IohLib|QuarkSocPkg/QuarkSouthCluster/Library/IohLib/IohLib.inf
+  I2cLib|QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/I2cLib.inf
+  SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
+  PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf
+
+  #
+  # Quark Platform
+  #
+  PlatformSecLib|QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.inf
+  PlatformPcieHelperLib|QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPcieHelperLib.inf
+  PlatformHelperLib|QuarkPlatformPkg/Library/PlatformHelperLib/DxePlatformHelperLib.inf
+
+!if $(CAPSULE_ENABLE)
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf
+  BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf
+  SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
+!else
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+!endif
+
+  EdkiiSystemCapsuleLib|SignedCapsulePkg/Library/EdkiiSystemCapsuleLib/EdkiiSystemCapsuleLib.inf
+  FmpAuthenticationLib|MdeModulePkg/Library/FmpAuthenticationLibNull/FmpAuthenticationLibNull.inf
+  IniParsingLib|SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.inf
+  PlatformFlashAccessLib|QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLibDxe.inf
+  DisplayUpdateProgressLib|MdeModulePkg/Library/DisplayUpdateProgressLibText/DisplayUpdateProgressLibText.inf
+
+[LibraryClasses.common.SEC]
+  #
+  # SEC specific phase
+  #
+  ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  TimerLib|PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
+
+[LibraryClasses.IA32.PEIM,LibraryClasses.IA32.PEI_CORE]
+  #
+  # PEI phase common
+  #
+  PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+  LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf
+  TimerLib|PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
+  PlatformHelperLib|QuarkPlatformPkg/Library/PlatformHelperLib/PeiPlatformHelperLib.inf
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
+!if $(PERFORMANCE_ENABLE)
+  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+!endif
+
+[LibraryClasses.IA32.DXE_CORE]
+  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
+  MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+!if $(PERFORMANCE_ENABLE)
+  PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
+!endif
+
+[LibraryClasses.IA32.DXE_SMM_DRIVER]
+  MmServicesTableLib|MdePkg/Library/MmServicesTableLib/MmServicesTableLib.inf
+  SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/SmmReportStatusCodeLib.inf
+  MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf
+  LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf
+  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
+  SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
+!if $(PERFORMANCE_ENABLE)
+  PerformanceLib|MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.inf
+!endif
+
+[LibraryClasses.IA32.SMM_CORE]
+  SmmServicesTableLib|MdeModulePkg/Library/PiSmmCoreSmmServicesTableLib/PiSmmCoreSmmServicesTableLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/SmmReportStatusCodeLib.inf
+  MemoryAllocationLib|MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf
+  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+  SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
+!if $(SECURE_BOOT_ENABLE) || $(MEASURED_BOOT_ENABLE)
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
+!endif
+!if $(PERFORMANCE_ENABLE)
+  PerformanceLib|MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.inf
+!endif
+
+[LibraryClasses.IA32.DXE_RUNTIME_DRIVER]
+  ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf
+  QNCAccessLib|QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/RuntimeQNCAccessLib.inf
+  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+!if $(SECURE_BOOT_ENABLE) || $(MEASURED_BOOT_ENABLE)
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+!endif
+
+!if $(CAPSULE_ENABLE)
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf
+!endif
+
+[LibraryClasses.IA32.UEFI_DRIVER,LibraryClasses.IA32.UEFI_APPLICATION]
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+[PcdsFeatureFlag]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathToText|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathFromText|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
+!if $(SOURCE_DEBUG_ENABLE)
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmDebug|TRUE
+!endif
+
+!if $(TARGET) == "RELEASE"
+  gQuarkPlatformTokenSpaceGuid.WaitIfResetDueToError|FALSE
+!else
+  gQuarkPlatformTokenSpaceGuid.WaitIfResetDueToError|TRUE
+!endif
+
+[PcdsFixedAtBuild]
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|1
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemorySize|0x20000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|TRUE
+!if $(LOGGING)
+  !if $(SOURCE_DEBUG_ENABLE)
+    gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
+  !else
+    gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x27
+  !endif
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0
+  gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask|0x0
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x3
+!endif
+  gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask|0x18
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xE0000000
+!if $(GALILEO) == GEN1
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|460800
+!endif
+!if $(GALILEO) == GEN2
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|921600
+!endif
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits|8
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|1
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|1
+  gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|0
+!if $(PERFORMANCE_ENABLE)
+  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0x1
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPerformanceLogEntries|80
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0x00
+!endif
+  gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable|0
+!if $(SECURE_BOOT_ENABLE)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
+!endif
+  gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize|0x00002000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x1000
+  ## RTC Update Timeout Value, need to increase timeout since also
+  # waiting for RTC to be busy.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdRealTimeClockUpdateTimeout|500000
+
+!if $(SECURE_BOOT_ENABLE)
+  # override the default values from SecurityPkg to ensure images from all sources are verified in secure boot
+  gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x04
+  gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy|0x04
+  gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy|0x04
+!endif
+  gQuarkPlatformTokenSpaceGuid.PcdEsramStage1Base|0x80000000
+
+!if $(SOURCE_DEBUG_ENABLE)
+  gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod|0x2
+!endif
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x9000B000
+!if $(GALILEO) == GEN1
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate|460800
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl|FALSE
+!endif
+!if $(GALILEO) == GEN2
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate|921600
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl|FALSE
+!endif
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialLineControl|0x03
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialFifoControl|0x07
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialDetectCable|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate|44236800
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialPciDeviceInfo|{0x14, 0x05, 0x84, 0x00, 0xFF}
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride|4
+
+  #
+  #  typedef struct {
+  #    UINT16  VendorId;          ///< Vendor ID to match the PCI device.  The value 0xFFFF terminates the list of entries.
+  #    UINT16  DeviceId;          ///< Device ID to match the PCI device
+  #    UINT32  ClockRate;         ///< UART clock rate.  Set to 0 for default clock rate of 1843200 Hz
+  #    UINT64  Offset;            ///< The byte offset into to the BAR
+  #    UINT8   BarIndex;          ///< Which BAR to get the UART base address
+  #    UINT8   RegisterStride;    ///< UART register stride in bytes.  Set to 0 for default register stride of 1 byte.
+  #    UINT16  ReceiveFifoDepth;  ///< UART receive FIFO depth in bytes. Set to 0 for a default FIFO depth of 16 bytes.
+  #    UINT16  TransmitFifoDepth; ///< UART transmit FIFO depth in bytes. Set to 0 for a default FIFO depth of 16 bytes.
+  #    UINT8   Reserved[2];
+  #  } PCI_SERIAL_PARAMETER;
+  #
+  # Vendor 8086 Device 0936 Prog Interface 2, BAR #0, Offset 0, Stride = 4, Clock 44236800 (0x2a300000)
+  # Vendor 8086 Device 0936 Prog Interface 2, BAR #0, Offset 0, Stride = 4, Clock 44236800 (0x2a300000)
+  #
+  #                                                       [Vendor]   [Device]  [---ClockRate---]  [------------Offset-----------] [Bar] [Stride] [RxFifo] [TxFifo]   [Rsvd]   [Vendor]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPciSerialParameters|{0x86,0x80, 0x36,0x09, 0x0,0x0,0xA3,0x02, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x00,    0x04, 0x0,0x0, 0x0,0x0, 0x0,0x0, 0xff,0xff}
+
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBusNumber           |0
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciDeviceNumber        |31
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciFunctionNumber      |0
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciEnableRegisterOffset|0x4b
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoBarEnableMask          |0x80
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBarRegisterOffset   |0x48
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddress        |0x1000
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiPm1TmrOffset             |0x0008
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand|FALSE
+
+!if $(RECOVERY_ENABLE)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdRecoveryFileName|L"QUARKREC.Cap"
+!endif
+
+  #
+  # Quark does not support LFENCE.  Use CPUID as speculation barrier
+  #
+  gEfiMdePkgTokenSpaceGuid.PcdSpeculationBarrierType|0x02
+
+[PcdsPatchableInModule]
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x803000C7
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
+
+[PcdsDynamicExHii.common.DEFAULT]
+!if $(PERFORMANCE_ENABLE)
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|0
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|5
+!endif
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBootState|L"BootState"|gQuarkPlatformTokenSpaceGuid|0x0|TRUE
+
+[PcdsDynamicExDefault.common.DEFAULT]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr|0x0
+  gQuarkPlatformTokenSpaceGuid.PcdEnableFastBoot|TRUE
+  gQuarkPlatformTokenSpaceGuid.PcdUserIsPhysicallyPresent|FALSE
+  gQuarkPlatformTokenSpaceGuid.PcdSpiFlashDeviceSize|0
+
+!if $(CAPSULE_ENABLE) || $(RECOVERY_ENABLE)
+  gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareImageDescriptor|{0x0}|VOID*|0x100
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSystemFmpCapsuleImageTypeIdGuid|{0xc0, 0x20, 0xaf, 0x62, 0x16, 0x70, 0x4a, 0x42, 0x9b, 0xf8, 0x9c, 0xcc, 0x86, 0x58, 0x40, 0x90}
+  gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareFileGuid|{0x59, 0x3A, 0xD8, 0x14, 0x10, 0xA8, 0x56, 0x45, 0x81, 0x92, 0x1C, 0x0A, 0x59, 0x3C, 0x06, 0x5C}
+!endif
+
+!if $(MEASURED_BOOT_ENABLE)
+  #
+  # TPM1.2      { 0x8b01e5b6, 0x4f19, 0x46e8, { 0xab, 0x93, 0x1c, 0x53, 0x67, 0x1b, 0x90, 0xcc } }
+  # TPM2.0 DTPM { 0x286bf25a, 0xc2c3, 0x408c, { 0xb3, 0xb4, 0x25, 0xe6, 0x75, 0x8b, 0x73, 0x17 } }
+  #
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{0xb6, 0xe5, 0x01, 0x8b, 0x19, 0x4f, 0xe8, 0x46, 0xab, 0x93, 0x1c, 0x53, 0x67, 0x1b, 0x90, 0xcc}
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInitializationPolicy|1
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmScrtmPolicy|1
+!endif
+
+[PcdsDynamicExVpd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVendor|*|32|L"EDK II"
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareRevision|*|0x01000400
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|*|64|L"Galileo 1.0.4"
+
+#
+# ClantonPeakSVP
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformType|*|0x0002
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformTypeName|*|64|L"ClantonPeakSVP"
+# gEfiQuarkNcSocIdTokenSpaceGuid.PcdMrcParameters|*|40|{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x03, 0x7c, 0x92, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x40, 0x9c, 0x00, 0x00, 0x06}
+#
+# KipsBay
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformType|*|0x0003
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformTypeName|*|64|L"KipsBay"
+# gEfiQuarkNcSocIdTokenSpaceGuid.PcdMrcParameters|*|40|{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x7c, 0x92, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x40, 0x9c, 0x00, 0x00, 0x06}
+#
+# CrossHill
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformType|*|0x0004
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformTypeName|*|64|L"CrossHill"
+# gEfiQuarkNcSocIdTokenSpaceGuid.PcdMrcParameters|*|40|{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x03, 0x7c, 0x92, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x40, 0x9c, 0x00, 0x00, 0x06}
+#
+# ClantonHill
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformType|*|0x0005
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformTypeName|*|64|L"ClantonHill"
+# gEfiQuarkNcSocIdTokenSpaceGuid.PcdMrcParameters|*|40|{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x7c, 0x92, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x40, 0x9c, 0x00, 0x00, 0x06}
+#
+# Galileo
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformType|*|0x0006
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformTypeName|*|64|L"Galileo"
+# gEfiQuarkNcSocIdTokenSpaceGuid.PcdMrcParameters|*|40|{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x7c, 0x92, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x40, 0x9c, 0x00, 0x00, 0x06}
+#
+# GalileoGen2
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformType|*|0x0008
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformTypeName|*|64|L"GalileoGen2"
+# gEfiQuarkNcSocIdTokenSpaceGuid.PcdMrcParameters|*|40|{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x7c, 0x92, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x40, 0x9c, 0x00, 0x00, 0x06}
+#
+!if $(GALILEO) == GEN1
+  gQuarkPlatformTokenSpaceGuid.PcdPlatformType|*|0x0006
+  gQuarkPlatformTokenSpaceGuid.PcdPlatformTypeName|*|64|L"Galileo"
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdMrcParameters|*|40|{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x7c, 0x92, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x40, 0x9c, 0x00, 0x00, 0x06}
+!endif
+!if $(GALILEO) == GEN2
+  gQuarkPlatformTokenSpaceGuid.PcdPlatformType|*|0x0008
+  gQuarkPlatformTokenSpaceGuid.PcdPlatformTypeName|*|64|L"GalileoGen2"
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdMrcParameters|*|40|{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x7c, 0x92, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x40, 0x9c, 0x00, 0x00, 0x06}
+!endif
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohEthernetMac0|*|8|{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohEthernetMac1|*|8|{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
+
+###################################################################################################
+#
+# Components Section - list of the modules and components that will be processed by compilation
+#                      tools and the EDK II tools to generate PE32/PE32+/Coff image files.
+#
+# Note: The EDK II DSC file is not used to specify how compiled binary images get placed
+#       into firmware volume images. This section is just a list of modules to compile from
+#       source into UEFI-compliant binaries.
+#       It is the FDF file that contains information on combining binary files into firmware
+#       volume images, whose concept is beyond UEFI and is described in PI specification.
+#       Binary modules do not need to be listed in this section, as they should be
+#       specified in the FDF file. For example: Shell binary, FAT binary (Fat.efi),
+#       Logo (Logo.bmp), and etc.
+#       There may also be modules listed in this section that are not required in the FDF file,
+#       When a module listed here is excluded from FDF file, then UEFI-compliant binary will be
+#       generated for it, but the binary will not be put into any firmware volume.
+#
+###################################################################################################
+
+[Components.IA32]
+  #
+  # SEC Core
+  #
+  UefiCpuPkg/SecCore/SecCore.inf {
+    !if $(SOURCE_DEBUG_ENABLE)
+      <LibraryClasses>
+        PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+        DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
+        ResetSystemLib|QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/ResetSystemLib.inf
+    !endif
+  }
+
+!if $(CAPSULE_ENABLE) || $(RECOVERY_ENABLE)
+  # FMP image decriptor
+  QuarkPlatformPkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptor.inf
+!endif
+
+  #
+  # PEI Core
+  #
+  MdeModulePkg/Core/Pei/PeiMain.inf
+
+  #
+  # PEIM
+  #
+  MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf {
+    <LibraryClasses>
+      !if $(LOGGING)
+        DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+      !else
+        SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
+      !endif
+  }
+
+  MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
+  MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+  MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2Pei.inf
+  UefiCpuPkg/CpuMpPei/CpuMpPei.inf
+  MdeModulePkg/Universal/CapsulePei/CapsulePei.inf
+
+  QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInitPei.inf
+  QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.inf
+  QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.inf
+
+  UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
+
+  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+
+  #
+  # S3
+  #
+  QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmAccessPei/SmmAccessPei.inf
+  QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/SmmControlPei.inf
+  UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
+
+  #
+  # Trusted Platform Module
+  #
+!if $(MEASURED_BOOT_ENABLE)
+  SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
+  SecurityPkg/Tcg/TcgPei/TcgPei.inf
+!endif
+
+  #
+  # Recovery
+  #
+!if $(RECOVERY_ENABLE)
+  QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.inf
+  MdeModulePkg/Bus/Pci/EhciPei/EhciPei.inf
+  QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciPei.inf
+  MdeModulePkg/Bus/Usb/UsbBotPei/UsbBotPei.inf
+  MdeModulePkg/Bus/Usb/UsbBusPei/UsbBusPei.inf
+  FatPkg/FatPei/FatPei.inf
+  MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf
+  SignedCapsulePkg/Universal/RecoveryModuleLoadPei/RecoveryModuleLoadPei.inf {
+    <LibraryClasses>
+      FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibRsa2048Sha256/FmpAuthenticationLibRsa2048Sha256.inf
+  }
+!endif
+
+[Components.IA32]
+  #
+  # DXE Core
+  #
+  MdeModulePkg/Core/Dxe/DxeMain.inf
+
+!if $(SOURCE_DEBUG_ENABLE)
+  SourceLevelDebugPkg/DebugAgentDxe/DebugAgentDxe.inf {
+    <LibraryClasses>
+      DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+      ResetSystemLib|QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/ResetSystemLib.inf
+  }
+!endif
+
+
+  QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.inf
+
+  #
+  # Components that produce the architectural protocols
+  #
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf  {
+    <LibraryClasses>
+!if $(SECURE_BOOT_ENABLE)
+      NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
+!endif
+     NULL|SecurityPkg/Library/DxeImageAuthenticationStatusLib/DxeImageAuthenticationStatusLib.inf
+ }
+  UefiCpuPkg/CpuDxe/CpuDxe.inf
+  MdeModulePkg/Universal/Metronome/Metronome.inf
+  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf
+!if $(SECURE_BOOT_ENABLE)
+  SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+!endif
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
+      NULL|MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf
+      NULL|MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf
+  }
+
+  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
+
+  #
+  # Following are the DXE drivers (alphabetical order)
+  #
+  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+
+  QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.inf
+  QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSpi.inf
+  QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.inf
+  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
+
+  #
+  # Platform
+  #
+  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf {
+    <LibraryClasses>
+      PlatformBootManagerLib|QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+!if $(CAPSULE_ENABLE)
+      FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf
+!else
+      FmpAuthenticationLib|MdeModulePkg/Library/FmpAuthenticationLibNull/FmpAuthenticationLibNull.inf
+!endif
+  }
+  MdeModulePkg/Application/UiApp/UiApp.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
+      NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
+      NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
+
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+
+  QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInitDxe.inf
+  PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf
+  QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/SmmAccess.inf
+  QuarkPlatformPkg/Platform/Dxe/Setup/DxePlatform.inf
+  QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiRuntime.inf {
+    <LibraryClasses>
+      PciExpressLib|MdePkg/Library/DxeRuntimePciExpressLib/DxeRuntimePciExpressLib.inf
+  }
+  QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiSmm.inf
+  QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.inf
+  MdeModulePkg/Universal/SectionExtractionDxe/SectionExtractionDxe.inf
+  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf  {
+    <LibraryClasses>
+      !if $(LOGGING)
+        DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+      !else
+        SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
+      !endif
+  }
+  MdeModulePkg/Universal/ReportStatusCodeRouter/Smm/ReportStatusCodeRouterSmm.inf
+  MdeModulePkg/Universal/StatusCodeHandler/Smm/StatusCodeHandlerSmm.inf {
+    <LibraryClasses>
+      !if $(LOGGING)
+        DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+      !else
+        SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
+      !endif
+  }
+  #
+  # ACPI
+  #
+  QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveMemoryConfig.inf
+  MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
+#  MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf {
+  QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/BootScriptExecutorDxe.inf {
+    <LibraryClasses>
+      !if $(LOGGING)
+        DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+      !else
+        SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
+      !endif
+      !if $(SOURCE_DEBUG_ENABLE)
+        DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+        ResetSystemLib|QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/ResetSystemLib.inf
+      !endif
+  }
+  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+  IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3SaveDxe.inf
+  QuarkPlatformPkg/Acpi/AcpiTables/AcpiTables.inf
+  QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.inf
+
+  #
+  # SMM
+  #
+  MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
+  MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
+  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf {
+    <LibraryClasses>
+      SmmCpuFeaturesLib|QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
+      SmmCpuPlatformHookLib|UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf
+
+      !if $(LOGGING)
+        DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+      !else
+        SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
+      !endif
+      !if $(SOURCE_DEBUG_ENABLE)
+        DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf
+        ResetSystemLib|QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/ResetSystemLib.inf
+      !endif
+    <PcdsPatchableInModule>
+      #
+      # Disable DEBUG_CACHE because SMI entry/exit may change MTRRs
+      #
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x801000C7
+  }
+
+  UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
+  QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmControlDxe/SmmControlDxe.inf
+  QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmDispatcher.inf
+  QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.inf
+  QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/SmmPowerManagement.inf
+  MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
+  UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
+
+  #
+  # SMBIOS
+  #
+  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+  QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscDxe.inf
+  QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.inf
+  #
+  # PCI
+  #
+  QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.inf
+  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+  QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohInitDxe.inf
+  MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf
+
+  #
+  # USB
+  #
+  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+  QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDxe.inf
+  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+  MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+  MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
+  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+  #
+  # SDIO
+  #
+  QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SDControllerDxe.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80300087
+  }
+  QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/SDMediaDeviceDxe.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80300087
+  }
+
+  #
+  # Console
+  #
+  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf {
+    <LibraryClasses>
+      CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+  }
+  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+
+  #
+  # File System Modules
+  #
+  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+  FatPkg/EnhancedFatDxe/Fat.inf
+
+  #
+  # Capsule update
+  #
+  IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVolDxe.inf
+  IntelFrameworkModulePkg/Universal/FirmwareVolume/UpdateDriverDxe/UpdateDriverDxe.inf
+
+  #
+  # Trusted Platform Module
+  #
+!if $(MEASURED_BOOT_ENABLE)
+  SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf
+  SecurityPkg/Tcg/TcgDxe/TcgDxe.inf
+  SecurityPkg/Tcg/TcgSmm/TcgSmm.inf
+!endif
+
+  #
+  # Performance Application
+  #
+!if $(PERFORMANCE_ENABLE)
+  ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf {
+    <PcdsFixedAtBuild>
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+  }
+!endif
+
+  #
+  # Force Recovery Application
+  #
+  QuarkPlatformPkg/Application/ForceRecovery/ForceRecovery.inf
+
+  ShellPkg/Application/Shell/Shell.inf {
+    <LibraryClasses>
+      ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
+      HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+      PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+      BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+      gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
+  }
+
+!if $(CAPSULE_ENABLE)
+  MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxe.inf
+
+  SignedCapsulePkg/Universal/SystemFirmwareUpdate/SystemFirmwareReportDxe.inf {
+    <LibraryClasses>
+      FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf
+  }
+  SignedCapsulePkg/Universal/SystemFirmwareUpdate/SystemFirmwareUpdateDxe.inf {
+    <LibraryClasses>
+      FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf
+  }
+
+  MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+!endif
+
+[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
+  MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
+
+# Force PE/COFF sections to be aligned at 4KB boundaries to support page level protection of DXE_SMM_DRIVER/SMM_CORE modules
+[BuildOptions.common.EDKII.DXE_SMM_DRIVER, BuildOptions.common.EDKII.SMM_CORE]
+  MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
+  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+
diff --git a/Platform/Intel/QuarkPlatformPkg/Quark.fdf b/Platform/Intel/QuarkPlatformPkg/Quark.fdf
new file mode 100644
index 0000000000..a48a3d41f2
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Quark.fdf
@@ -0,0 +1,907 @@
+## @file
+# FDF file of Clanton Peak CRB platform with 32-bit DXE
+#
+# This package provides QuarkNcSocId platform specific modules.
+# Copyright (c) 2013 - 2018 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+#                  Address 0x100000000 (4 GB reset address)
+#                                 Base                               Size
+#                                      +---------------------------+
+#                           FLASH_BASE | FD.Quark:                 | 0x800000 (8 MB)
+#                           0xFF800000 | BaseAddress               |
+#                                      +---------------------------+
+#
+# Flash offsets are 0 based, but are relative to FD.Quark BaseAddress, e.g. Payload Base is at 0x400000, Flash Base is at 0xFF800000 for 8 MB SPI part.
+# 0xFF800000 + 0x400000 = 0xFFC00000.
+#
+#                          Address 0x0 (0xFF800000 for 8 MB SPI part)
+#                                      +---------------------------+
+#                FLASH_FV_PAYLOAD_BASE | Payload Image             | FLASH_FV_PAYLOAD_SIZE
+#                           0x00400000 |                           | 0x00100000
+#                                      +---------------------------+
+#                   FLASH_FV_MAIN_BASE | FvMain Image (Compressed) | FLASH_FV_MAIN_SIZE
+#                           0x00500000 |                           | 0x001E0000
+#                                      +---------------------------+
+#                      NVRAM_AREA_BASE | NVRAM Area=               | NVRAM_AREA_SIZE
+#                           0x006E0000 | Variable + FTW Working +  |
+#                                      | FTW Spare                 |
+#                                      +---+-------------------+---+
+#                 NVRAM_AREA_VARIABLE_BASE |                   | NVRAM_AREA_VARIABLE_SIZE
+#                                          |                   |
+#                                          +-------------------+
+#                         FTW_WORKING_BASE |                   | FTW_WORKING_SIZE
+#                                          |                   |
+#                                          +-------------------+
+#                           FTW_SPARE_BASE |                   | FTW_SPARE_SIZE
+#                                          |                   |
+#                                      +---+-------------------+---+
+#                      RMU_BINARY_BASE | RMU Binary                | RMU_BINARY_SIZE
+#                           0x00700000 |                           | 0x00008000
+#                                      +---------------------------+
+#                   PLATFORM_DATA_BASE | PlatformData Binary       | PLATFORM_DATA_SIZE
+#                           0x00710000 |                           | 0x00001000
+#                                      +---------------------------+
+#                FVRECOVERY_IMAGE_BASE | FVRECOVERY Image          | FVRECOVERY_IMAGE_SIZE
+#                             0x720000 |                           | 0x000E0000
+#                                      +---------------------------+
+
+  #
+  # Define value used to compute FLASH regions below reset vector location just below 4GB
+  #
+  DEFINE RESET_ADDRESS                           = 0x100000000       # 4 GB
+
+  #
+  # Set size of FLASH to 8MB
+  #
+  DEFINE FLASH_SIZE                              = 0x800000
+  DEFINE FLASH_BASE                              = $(RESET_ADDRESS) - $(FLASH_SIZE)                                                      # The base address of the Flash Device
+
+  #
+  # Set FLASH block size to 4KB
+  #
+  DEFINE FLASH_BLOCKSIZE                         = 0x1000            # 4 KB
+
+  #
+  # Misc settings
+  #
+  DEFINE FLASH_BLOCKSIZE_DATA                    = 0x00, 0x10, 0x00, 0x00                                                                # equivalent for DATA blocks
+
+  #
+  # Start PAYLOAD at 4MB into 8MB FLASH
+  #
+  DEFINE FLASH_FV_PAYLOAD_BASE                   = 0x00400000
+  DEFINE FLASH_FV_PAYLOAD_SIZE                   = 0x00100000
+
+  #
+  # Put FVMAIN between PAYLOAD and RMU Binary
+  #
+  DEFINE FLASH_FV_MAIN_BASE                      = 0x00500000
+  DEFINE FLASH_FV_MAIN_SIZE                      = 0x001E0000
+
+  #
+  # Place NV Storage just above Platform Data Base
+  #
+  DEFINE NVRAM_AREA_VARIABLE_BASE                = 0x006E0000
+  DEFINE NVRAM_AREA_SIZE                         = 0x00020000
+
+  DEFINE NVRAM_AREA_VARIABLE_SIZE                = 0x0000E000
+  DEFINE FTW_WORKING_BASE                        = $(NVRAM_AREA_VARIABLE_BASE) + $(NVRAM_AREA_VARIABLE_SIZE)
+  DEFINE FTW_WORKING_SIZE                        = 0x00002000
+  DEFINE FTW_SPARE_BASE                          = $(FTW_WORKING_BASE) + $(FTW_WORKING_SIZE)
+  DEFINE FTW_SPARE_SIZE                          = $(NVRAM_AREA_SIZE) - $(NVRAM_AREA_VARIABLE_SIZE) - $(FTW_WORKING_SIZE)
+
+  #
+  # RMU Binary must be at fixed address 1MB below 4GB (0xFFF00000)
+  #
+  DEFINE RMU_BINARY_BASE                         = 0x00700000  # HW fixed address
+  DEFINE RMU_BINARY_SIZE                         = 0x00008000  # HW fixed address, so fixed size
+
+  #
+  # Platform Data Base must be 64KB above RMU
+  #
+  DEFINE VPD_BASE                                = 0x00708000
+  DEFINE VPD_SIZE                                = 0x00001000
+
+  #
+  # Place FV Recovery above NV Storage
+  #
+  DEFINE FVRECOVERY_IMAGE_SIZE                   = 0x000F0000
+  DEFINE FVRECOVERY_IMAGE_BASE                   = $(FLASH_SIZE) - $(FVRECOVERY_IMAGE_SIZE)
+
+################################################################################
+#
+# FD Section
+# The [FD] Section is made up of the definition statements and a
+# description of what goes into  the Flash Device Image.  Each FD section
+# defines one flash "device" image.  A flash device image may be one of
+# the following: Removable media bootable image (like a boot floppy
+# image,) an Option ROM image (that would be "flashed" into an add-in
+# card,) a System "Flash"  image (that would be burned into a system's
+# flash) or an Update ("Capsule") image that will be used to update and
+# existing system flash.
+#
+################################################################################
+[FD.Quark]
+BaseAddress   = 0xFF800000                   #The base address of the Flash Device; set to same value as FLASH_BASE.
+Size          = 0x800000                     #The size in bytes of the Flash Device; set to same value as FLASH_SIZE.
+ErasePolarity = 1
+BlockSize     = $(FLASH_BLOCKSIZE)
+NumBlocks     = 0x800                        #The number of blocks for the Flash Device.
+
+SET gQuarkPlatformTokenSpaceGuid.PcdFlashAreaBaseAddress = $(FLASH_BASE)
+SET gQuarkPlatformTokenSpaceGuid.PcdFlashAreaSize        = $(FLASH_SIZE)
+
+################################################################################
+#
+# Following are lists of FD Region layout which correspond to the locations of different
+# images within the flash device.
+#
+# Regions must be defined in ascending order and may not overlap.
+#
+# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
+# the pipe "|" character, followed by the size of the region, also in hex with the leading
+# "0x" characters. Like:
+# Offset|Size
+# PcdOffsetCName|PcdSizeCName
+# RegionType <FV, DATA, or FILE>
+#
+################################################################################
+
+########################################################
+# Quark Payload Image
+########################################################
+$(FLASH_FV_PAYLOAD_BASE)|$(FLASH_FV_PAYLOAD_SIZE)
+gQuarkPlatformTokenSpaceGuid.PcdFlashFvPayloadBase|gQuarkPlatformTokenSpaceGuid.PcdFlashFvPayloadSize
+FV = PAYLOAD
+
+########################################################
+# Quark FVMAIN Image (Compressed)
+########################################################
+$(FLASH_FV_MAIN_BASE)|$(FLASH_FV_MAIN_SIZE)
+gQuarkPlatformTokenSpaceGuid.PcdFlashFvMainBase|gQuarkPlatformTokenSpaceGuid.PcdFlashFvMainSize
+FV = FVMAIN_COMPACT
+
+#############################################################################
+# Quark NVRAM Area
+# Quark NVRAM Area contains: Variable + FTW Working + FTW Spare
+#############################################################################
+$(NVRAM_AREA_VARIABLE_BASE)|$(NVRAM_AREA_VARIABLE_SIZE)
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+#NV_VARIABLE_STORE
+DATA = {
+  ## This is the EFI_FIRMWARE_VOLUME_HEADER
+  # ZeroVector []
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  # FileSystemGuid: gEfiSystemNvDataFvGuid         =
+  #  { 0xFFF12B8D, 0x7696, 0x4C8B, { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }}
+  0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
+  0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
+  # FvLength: 0x20000
+  0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+  #Signature "_FVH"       #Attributes
+  0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,
+  #HeaderLength #CheckSum #ExtHeaderOffset #Reserved #Revision
+  0x48, 0x00, 0x19, 0xF9, 0x00, 0x00, 0x00, 0x02,
+  #Blockmap[0]: 32 Blocks * 0x1000 Bytes / Block
+  0x20, 0x00, 0x00, 0x00, $(FLASH_BLOCKSIZE_DATA),
+  #Blockmap[1]: End
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  ## This is the VARIABLE_STORE_HEADER
+  !if $(SECURE_BOOT_ENABLE)
+    # Signature: gEfiAuthenticatedVariableGuid = { 0xaaf32c78, 0x947b, 0x439a, { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 } }
+    0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,
+    0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,
+  !else
+    #  Signature: gEfiVariableGuid = { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }}
+    0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41,
+    0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d,
+  !endif
+  #Size: 0x0E000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x0DFB8
+  # This can speed up the Variable Dispatch a bit.
+  0xB8, 0xDF, 0x00, 0x00,
+  #FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
+  0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+$(FTW_WORKING_BASE)|$(FTW_WORKING_SIZE)
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+#NV_FTW_WORKING
+DATA = {
+  # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid         =
+  #  { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95 }}
+  0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49,
+  0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95,
+  # Crc:UINT32            #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
+  0xE2, 0x33, 0xF2, 0x03, 0xFE, 0xFF, 0xFF, 0xFF,
+  # WriteQueueSize: UINT64 #Size: 0x2000 - 0x20 (FTW_WORKING_HEADER) = 0x1FE0
+  0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+$(FTW_SPARE_BASE)|$(FTW_SPARE_SIZE)
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+#NV_FTW_SPARE
+
+#########################################################
+# Quark Remote Management Unit Binary
+#########################################################
+$(RMU_BINARY_BASE)|$(RMU_BINARY_SIZE)
+INF  QuarkSocBinPkg/QuarkNorthCluster/Binary/QuarkMicrocode/QuarkMicrocode.inf
+
+#########################################################
+# PlatformData Binary, default for standalone is none built-in so user selects.
+#########################################################
+$(VPD_BASE)|$(VPD_SIZE)
+gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress
+FILE = $(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/FV/8C3D856A-9BE6-468E-850A-24F7A8D38E08.bin
+
+#######################
+# Quark FVRECOVERY Image
+#######################
+$(FVRECOVERY_IMAGE_BASE)|$(FVRECOVERY_IMAGE_SIZE)
+gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoveryBase|gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoverySize
+FV = FVRECOVERY
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file.  This section also defines order the components and modules are positioned
+# within the image.  The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+[FV.FVRECOVERY]
+BlockSize          = $(FLASH_BLOCKSIZE)
+FvAlignment        = 16         #FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 18D6D9F4-2EEF-4913-AEE6-BE61C6DA6CC8
+
+################################################################################
+#
+# The INF statements point to EDK component and EDK II module INF files, which will be placed into this FV image.
+# Parsing tools will scan the INF file to determine the type of component or module.
+# The component or module type is used to reference the standard rules
+# defined elsewhere in the FDF file.
+#
+# The format for INF statements is:
+# INF $(PathAndInfFileName)
+#
+################################################################################
+
+##
+#  PEI Apriori file example, more PEIM module added later.
+##
+APRIORI PEI {
+  INF  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+  # PlatformConfigPei should be immediately after Pcd driver.
+  INF  QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.inf
+  INF  MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2Pei.inf
+  INF  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+  INF  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+}
+
+##
+#  SEC Phase modules
+##
+INF  UefiCpuPkg/SecCore/SecCore.inf
+
+!if $(CAPSULE_ENABLE) || $(RECOVERY_ENABLE)
+  # FMP image decriptor
+INF RuleOverride = FMP_IMAGE_DESC QuarkPlatformPkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptor.inf
+!endif
+
+INF  MdeModulePkg/Core/Pei/PeiMain.inf
+
+##
+#  PEI Phase RAW Data files.
+##
+FILE FREEFORM = PCD(gEfiQuarkNcSocIdTokenSpaceGuid.PcdQuarkMicrocodeFile) {
+  SECTION RAW = QuarkSocBinPkg/QuarkNorthCluster/Binary/QuarkMicrocode/RMU.bin
+}
+
+INF  RuleOverride = NORELOC  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+INF  QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.inf
+INF  RuleOverride = NORELOC  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+INF  RuleOverride = NORELOC  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+INF  RuleOverride = NORELOC  MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
+INF  RuleOverride = NORELOC  MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+INF  RuleOverride = NORELOC  UefiCpuPkg/CpuMpPei/CpuMpPei.inf
+INF  RuleOverride = NORELOC  MdeModulePkg/Universal/CapsulePei/CapsulePei.inf
+INF  RuleOverride = NORELOC  QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInitPei.inf
+INF  RuleOverride = NORELOC  QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmAccessPei/SmmAccessPei.inf
+INF  RuleOverride = NORELOC  QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/SmmControlPei.inf
+INF  QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.inf
+INF  MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2Pei.inf
+INF  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+INF  UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
+INF  UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
+!if $(MEASURED_BOOT_ENABLE)
+INF  SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
+INF  SecurityPkg/Tcg/TcgPei/TcgPei.inf
+!endif
+
+!if $(RECOVERY_ENABLE)
+FILE FV_IMAGE = 1E9D7604-EF45-46a0-BD8A-71AC78C17AC1 {
+  SECTION PEI_DEPEX_EXP = {gEfiPeiMemoryDiscoveredPpiGuid AND gEfiPeiBootInRecoveryModePpiGuid}
+  SECTION GUIDED A31280AD-481E-41B6-95E8-127F4C984779 {    # TIANO COMPRESS GUID
+    SECTION FV_IMAGE = FVRECOVERY_COMPONENTS
+  }
+}
+!endif
+
+!if $(RECOVERY_ENABLE)
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file.  This section also defines order the components and modules are positioned
+# within the image.  The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+[FV.FVRECOVERY_COMPONENTS]
+BlockSize          = $(FLASH_BLOCKSIZE)
+FvAlignment        = 16         #FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+INF  QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.inf
+INF  MdeModulePkg/Bus/Pci/EhciPei/EhciPei.inf
+INF  QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciPei.inf
+INF  MdeModulePkg/Bus/Usb/UsbBusPei/UsbBusPei.inf
+INF  MdeModulePkg/Bus/Usb/UsbBotPei/UsbBotPei.inf
+INF  FatPkg/FatPei/FatPei.inf
+INF  MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf
+INF  SignedCapsulePkg/Universal/RecoveryModuleLoadPei/RecoveryModuleLoadPei.inf
+
+!endif
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file.  This section also defines order the components and modules are positioned
+# within the image.  The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+[FV.FVMAIN]
+BlockSize          = $(FLASH_BLOCKSIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 30D9ED01-38D2-418a-90D5-C561750BF80F
+
+##
+#  DXE Phase modules
+##
+INF  MdeModulePkg/Core/Dxe/DxeMain.inf
+INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+
+!if $(SOURCE_DEBUG_ENABLE)
+  INF  SourceLevelDebugPkg/DebugAgentDxe/DebugAgentDxe.inf
+!endif
+
+#
+# Early SoC / Platform modules
+#
+INF  QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.inf
+
+##
+#  EDK Core modules
+##
+INF  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
+INF  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+INF  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+INF  MdeModulePkg/Universal/ReportStatusCodeRouter/Smm/ReportStatusCodeRouterSmm.inf
+INF  MdeModulePkg/Universal/StatusCodeHandler/Smm/StatusCodeHandlerSmm.inf
+INF  MdeModulePkg/Universal/SectionExtractionDxe/SectionExtractionDxe.inf
+
+INF  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+INF  UefiCpuPkg/CpuDxe/CpuDxe.inf
+INF  MdeModulePkg/Universal/Metronome/Metronome.inf
+INF  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+INF  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+INF  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf
+!if $(SECURE_BOOT_ENABLE)
+  INF  SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+!endif
+INF  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
+INF  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
+INF  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+INF  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+INF  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+INF  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
+INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+INF  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+
+#
+# Platform
+#
+INF  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+INF  MdeModulePkg/Application/UiApp/UiApp.inf
+
+INF  QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.inf
+INF  QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSpi.inf
+INF  QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.inf
+INF  QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInitDxe.inf
+INF  PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf
+INF  QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/SmmAccess.inf
+INF  QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.inf
+INF  QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiRuntime.inf
+INF  QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiSmm.inf
+INF  QuarkPlatformPkg/Platform/Dxe/Setup/DxePlatform.inf
+
+#
+# ACPI
+#
+INF  QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveMemoryConfig.inf
+INF  MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
+#INF  MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
+INF  QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
+INF  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+INF  IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3SaveDxe.inf
+INF  QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.inf
+INF  RuleOverride = ACPITABLE QuarkPlatformPkg/Acpi/AcpiTables/AcpiTables.inf
+
+#
+# SMM
+#
+INF  MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
+INF  MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
+INF  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+INF  UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
+INF  QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmControlDxe/SmmControlDxe.inf
+INF  QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmDispatcher.inf
+INF  QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.inf
+INF  QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/SmmPowerManagement.inf
+INF  MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
+INF  UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
+
+#
+# SMBIOS
+#
+INF   MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+INF  QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscDxe.inf
+INF  QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.inf
+
+#
+# PCI
+#
+INF  QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.inf
+INF  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+INF  QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohInitDxe.inf
+!if $(SOURCE_DEBUG_ENABLE)
+!else
+INF  MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf
+!endif
+
+#
+# USB
+#
+!if $(PERFORMANCE_ENABLE)
+!else
+INF  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+INF  QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDxe.inf
+INF  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+INF  MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+INF  MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
+INF  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+!endif
+
+#
+# SDIO
+#
+!if $(PERFORMANCE_ENABLE)
+!else
+INF  QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SDControllerDxe.inf
+INF  QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/SDMediaDeviceDxe.inf
+!endif
+
+#
+# Console
+#
+INF  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+INF  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+INF  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+
+INF  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+INF  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+INF  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+INF  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+
+#
+# File System Modules
+#
+!if $(PERFORMANCE_ENABLE)
+!else
+INF  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+INF  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+INF  FatPkg/EnhancedFatDxe/Fat.inf
+!endif
+
+#
+# Performance Application
+#
+!if $(PERFORMANCE_ENABLE)
+INF  ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf
+!endif
+
+#
+# Trusted Platform Module
+#
+!if $(MEASURED_BOOT_ENABLE)
+INF  SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf
+INF  SecurityPkg/Tcg/TcgDxe/TcgDxe.inf
+INF  RuleOverride = DRIVER_ACPITABLE SecurityPkg/Tcg/TcgSmm/TcgSmm.inf
+!endif
+
+!if $(CAPSULE_ENABLE)
+INF  MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxe.inf
+INF  SignedCapsulePkg/Universal/SystemFirmwareUpdate/SystemFirmwareReportDxe.inf
+!endif
+
+!if $(RECOVERY_ENABLE)
+FILE FREEFORM = PCD(gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiRsa2048Sha256TestPublicKeyFileGuid) {
+     SECTION RAW = BaseTools/Source/Python/Rsa2048Sha256Sign/TestSigningPublicKey.bin
+     SECTION UI = "Rsa2048Sha256TestSigningPublicKey"
+     }
+!endif
+
+!if $(CAPSULE_ENABLE)
+FILE FREEFORM = PCD(gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiPkcs7TestPublicKeyFileGuid) {
+     SECTION RAW = BaseTools/Source/Python/Pkcs7Sign/TestRoot.cer
+     SECTION UI = "Pkcs7TestRoot"
+     }
+!endif
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file.  This section also defines order the components and modules are positioned
+# within the image.  The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+[FV.FVMAIN_COMPACT]
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+  SECTION GUIDED A31280AD-481E-41B6-95E8-127F4C984779 {    # TIANO COMPRESS GUID
+    SECTION FV_IMAGE = FVMAIN
+  }
+}
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file.  This section also defines order the components and modules are positioned
+# within the image.  The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+[FV.PAYLOAD]
+BlockSize          = $(FLASH_BLOCKSIZE)
+FvAlignment        = 16         #FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+#
+# Shell and Applications
+#
+INF  RuleOverride = TIANOCOMPRESSED ShellPkg/Application/Shell/Shell.inf
+
+!if $(CAPSULE_ENABLE) || $(RECOVERY_ENABLE)
+
+[FV.CapsuleDispatchFv]
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+!if $(CAPSULE_ENABLE)
+INF  SignedCapsulePkg/Universal/SystemFirmwareUpdate/SystemFirmwareUpdateDxe.inf
+!endif
+
+[FV.SystemFirmwareUpdateCargo]
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+FILE RAW = 14D83A59-A810-4556-8192-1C0A593C065C { # PcdEdkiiSystemFirmwareFileGuid
+    FD = Quark
+  }
+
+FILE RAW = ce57b167-b0e4-41e8-a897-5f4feb781d40 { # gEdkiiSystemFmpCapsuleDriverFvFileGuid
+    FV = CapsuleDispatchFv
+  }
+
+FILE RAW = 812136D3-4D3A-433A-9418-29BB9BF78F6E { # gEdkiiSystemFmpCapsuleConfigFileGuid
+    QuarkPlatformPkg/Feature/Capsule/SystemFirmwareUpdateConfig/SystemFirmwareUpdateConfig.ini
+  }
+
+!endif
+
+!if $(CAPSULE_ENABLE)
+[FmpPayload.FmpPayloadSystemFirmwarePkcs7]
+IMAGE_HEADER_INIT_VERSION = 0x02
+IMAGE_TYPE_ID             = 62af20c0-7016-424a-9bf8-9ccc86584090 # PcdSystemFmpCapsuleImageTypeIdGuid
+IMAGE_INDEX               = 0x1
+HARDWARE_INSTANCE         = 0x0
+MONOTONIC_COUNT           = 0x2
+CERTIFICATE_GUID          = 4AAFD29D-68DF-49EE-8AA9-347D375665A7 # PKCS7
+
+FV = SystemFirmwareUpdateCargo
+
+[Capsule.QuarkFirmwareUpdateCapsuleFmpPkcs7]
+CAPSULE_GUID                = 6dcbd5ed-e82d-4c44-bda1-7194199ad92a # gEfiFmpCapsuleGuid
+CAPSULE_FLAGS               = PersistAcrossReset,InitiateReset
+CAPSULE_HEADER_SIZE         = 0x20
+CAPSULE_HEADER_INIT_VERSION = 0x1
+
+FMP_PAYLOAD = FmpPayloadSystemFirmwarePkcs7
+!endif
+
+!if $(RECOVERY_ENABLE)
+[FmpPayload.FmpPayloadSystemFirmwareRsa2048]
+IMAGE_HEADER_INIT_VERSION = 0x02
+IMAGE_TYPE_ID             = 62af20c0-7016-424a-9bf8-9ccc86584090 # PcdSystemFmpCapsuleImageTypeIdGuid
+IMAGE_INDEX               = 0x1
+HARDWARE_INSTANCE         = 0x0
+MONOTONIC_COUNT           = 0x2
+CERTIFICATE_GUID          = A7717414-C616-4977-9420-844712A735BF # RSA2048SHA256
+
+FV = SystemFirmwareUpdateCargo
+
+[Capsule.QuarkRec]
+CAPSULE_GUID                = 6dcbd5ed-e82d-4c44-bda1-7194199ad92a # gEfiFmpCapsuleGuid
+CAPSULE_FLAGS               = PersistAcrossReset,InitiateReset
+CAPSULE_HEADER_SIZE         = 0x20
+CAPSULE_HEADER_INIT_VERSION = 0x1
+
+FMP_PAYLOAD = FmpPayloadSystemFirmwareRsa2048
+!endif
+
+################################################################################
+#
+# Rules are use with the [FV] section's module INF type to define
+# how an FFS file is created for a given INF file. The following Rule are the default
+# rules for the different module type. User can add the customized rules to define the
+# content of the FFS file.
+#
+################################################################################
+[Rule.Common.SEC]
+  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+    TE  TE    Align = 8       $(INF_OUTPUT)/$(MODULE_NAME).efi
+    RAW BIN   Align = 16      |.com
+  }
+
+[Rule.Common.PEI_CORE]
+  FILE PEI_CORE = $(NAMED_GUID)            {
+    TE       TE               $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.PEIM.NORELOC]
+  FILE PEIM = $(NAMED_GUID) RELOCS_STRIPPED  {
+     PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+     TE        TE                        $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI        STRING="$(MODULE_NAME)" Optional
+     VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.PEIM]
+  FILE PEIM = $(NAMED_GUID)               {
+     PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+     TE        TE                        $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI        STRING="$(MODULE_NAME)" Optional
+     VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_CORE]
+  FILE DXE_CORE = $(NAMED_GUID) {
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_RUNTIME_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_SMM_DRIVER]
+  FILE SMM = $(NAMED_GUID) {
+    SMM_DEPEX SMM_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_SMM_DRIVER.DRIVER_ACPITABLE]
+  FILE SMM = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    RAW ACPI  Optional                |.acpi
+    RAW ASL   Optional                |.aml
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.SMM_CORE]
+  FILE SMM_CORE = $(NAMED_GUID) {
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION]
+  FILE APPLICATION = $(NAMED_GUID) {
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION.TIANOCOMPRESSED]
+  FILE APPLICATION = $(NAMED_GUID) {
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+    SECTION GUIDED A31280AD-481E-41B6-95E8-127F4C984779 PROCESSING_REQUIRED = TRUE {  # TIANO COMPRESS GUID
+      PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    }
+  }
+
+[Rule.Common.UEFI_APPLICATION.UI]
+  FILE APPLICATION = $(NAMED_GUID) {
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="Enter Setup"
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.USER_DEFINED.ACPITABLE]
+  FILE FREEFORM = $(NAMED_GUID) {
+    RAW ACPI               |.acpi
+    RAW ASL                |.aml
+  }
+
+[Rule.Common.PEIM.FMP_IMAGE_DESC]
+  FILE PEIM = $(NAMED_GUID) {
+     RAW BIN                  |.acpi
+     PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+     PE32      PE32    Align=4K          $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI       STRING="$(MODULE_NAME)" Optional
+     VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
diff --git a/Platform/Intel/QuarkPlatformPkg/QuarkMin.dsc b/Platform/Intel/QuarkPlatformPkg/QuarkMin.dsc
new file mode 100644
index 0000000000..c95a5fcff9
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/QuarkMin.dsc
@@ -0,0 +1,648 @@
+## @file
+# Clanton Peak CRB platform with 32-bit DXE for 4MB/8MB flash devices.
+#
+# This package provides Clanton Peak CRB platform specific modules.
+# Copyright (c) 2013 - 2019 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  DSC_SPECIFICATION              = 0x00010005
+  PLATFORM_NAME                  = QuarkMin
+  PLATFORM_GUID                  = 2655F3CF-4CC7-4e17-A62D-77FE3F10AE7F
+  PLATFORM_VERSION               = 0.1
+  FLASH_DEFINITION               = QuarkPlatformPkg/QuarkMin.fdf
+  OUTPUT_DIRECTORY               = Build/QuarkMin
+  SUPPORTED_ARCHITECTURES        = IA32
+  BUILD_TARGETS                  = DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+  VPD_TOOL_GUID                  = 8C3D856A-9BE6-468E-850A-24F7A8D38E08
+
+  #
+  # Platform On/Off features are defined here
+  #
+  DEFINE GALILEO             = GEN2
+  DEFINE SECURE_BOOT_ENABLE  = FALSE
+  DEFINE SOURCE_DEBUG_ENABLE = FALSE
+  DEFINE PERFORMANCE_ENABLE  = FALSE
+  DEFINE LOGGING             = FALSE
+
+  !if $(TARGET) == "DEBUG"
+    DEFINE LOGGING = TRUE
+  !endif
+
+  !if $(PERFORMANCE_ENABLE)
+    DEFINE SOURCE_DEBUG_ENABLE = FALSE
+    DEFINE LOGGING             = FALSE
+  !endif
+
+################################################################################
+#
+# SKU Identification section - list of all SKU IDs supported by this
+#                              Platform.
+#
+################################################################################
+[SkuIds]
+  0|DEFAULT              # The entry: 0|DEFAULT is reserved and always required.
+
+################################################################################
+#
+# Library Class section - list of all Library Classes needed by this Platform.
+#
+################################################################################
+[LibraryClasses]
+  #
+  # Entry point
+  #
+  PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
+  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+
+  #
+  # Basic
+  #
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+  PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf
+  PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
+  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
+  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
+  CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+!if $(SOURCE_DEBUG_ENABLE)
+  PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
+  DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf
+!else
+  PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+!endif
+  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+
+  #
+  # UEFI & PI
+  #
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  UefiDecompressLib|MdeModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf
+  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+  UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
+  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+
+  #
+  # Generic Modules
+  #
+  S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
+  S3IoLib|MdePkg/Library/BaseS3IoLib/BaseS3IoLib.inf
+  S3PciLib|MdePkg/Library/BaseS3PciLib/BaseS3PciLib.inf
+  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+  IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
+  UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
+  DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
+  SmmCorePlatformHookLib|MdeModulePkg/Library/SmmCorePlatformHookLibNull/SmmCorePlatformHookLibNull.inf
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+  LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
+  VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+!if $(LOGGING)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+!endif
+!if $(PERFORMANCE_ENABLE)
+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+!else
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+!endif
+
+  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+
+!if $(SECURE_BOOT_ENABLE)
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+  PlatformSecureLib|QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
+  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+  TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
+  AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
+!else
+  TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
+  AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
+!endif
+
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+
+  #
+  # CPU
+  #
+  MtrrLib|QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.inf
+  LocalApicLib|UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf
+  MpInitLib|UefiCpuPkg/Library/MpInitLibUp/MpInitLibUp.inf
+
+  #
+  # Quark North Cluster
+  #
+  SmmLib|QuarkSocPkg/QuarkNorthCluster/Library/QNCSmmLib/QNCSmmLib.inf
+  SmbusLib|QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/SmbusLib.inf
+  TimerLib|PcAtChipsetPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
+  ResetSystemLib|QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/ResetSystemLib.inf
+  IntelQNCLib|QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNCLib.inf
+  QNCAccessLib|QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/QNCAccessLib.inf
+  IoApicLib|PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf
+
+  #
+  # Quark South Cluster
+  #
+  IohLib|QuarkSocPkg/QuarkSouthCluster/Library/IohLib/IohLib.inf
+  I2cLib|QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/I2cLib.inf
+  SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
+  PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf
+
+  #
+  # Quark Platform
+  #
+  PlatformSecLib|QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.inf
+  PlatformPcieHelperLib|QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPcieHelperLib.inf
+  PlatformHelperLib|QuarkPlatformPkg/Library/PlatformHelperLib/DxePlatformHelperLib.inf
+
+[LibraryClasses.common.SEC]
+  #
+  # SEC specific phase
+  #
+  ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  TimerLib|PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
+
+[LibraryClasses.IA32.PEIM,LibraryClasses.IA32.PEI_CORE]
+  #
+  # PEI phase common
+  #
+  PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
+  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+  LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
+  TimerLib|PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
+  PlatformHelperLib|QuarkPlatformPkg/Library/PlatformHelperLib/PeiPlatformHelperLib.inf
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
+!if $(SECURE_BOOT_ENABLE)
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
+!endif
+!if $(PERFORMANCE_ENABLE)
+  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+!endif
+
+[LibraryClasses.IA32.DXE_CORE]
+  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
+  MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+!if $(PERFORMANCE_ENABLE)
+  PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
+!endif
+
+[LibraryClasses.IA32.DXE_SMM_DRIVER]
+  MmServicesTableLib|MdePkg/Library/MmServicesTableLib/MmServicesTableLib.inf
+  SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf
+  ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
+  MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf
+  LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
+  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
+  SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
+!if $(SECURE_BOOT_ENABLE)
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
+!endif
+!if $(PERFORMANCE_ENABLE)
+  PerformanceLib|MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.inf
+!endif
+
+[LibraryClasses.IA32.SMM_CORE]
+  SmmServicesTableLib|MdeModulePkg/Library/PiSmmCoreSmmServicesTableLib/PiSmmCoreSmmServicesTableLib.inf
+  ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
+  MemoryAllocationLib|MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf
+  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+  SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
+!if $(SECURE_BOOT_ENABLE)
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
+!endif
+!if $(PERFORMANCE_ENABLE)
+  PerformanceLib|MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.inf
+!endif
+
+[LibraryClasses.IA32.DXE_RUNTIME_DRIVER]
+  ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
+  QNCAccessLib|QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/RuntimeQNCAccessLib.inf
+  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+!if $(SECURE_BOOT_ENABLE)
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+!endif
+
+[LibraryClasses.IA32.UEFI_DRIVER,LibraryClasses.IA32.UEFI_APPLICATION]
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+[PcdsFeatureFlag]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathToText|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathFromText|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
+!if $(SOURCE_DEBUG_ENABLE)
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmDebug|TRUE
+!endif
+
+!if $(TARGET) == "RELEASE"
+  gQuarkPlatformTokenSpaceGuid.WaitIfResetDueToError|FALSE
+!else
+  gQuarkPlatformTokenSpaceGuid.WaitIfResetDueToError|TRUE
+!endif
+
+[PcdsFixedAtBuild]
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|1
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemorySize|0x20000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+!if $(LOGGING)
+  !if $(SOURCE_DEBUG_ENABLE)
+    gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
+  !else
+    gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x27
+  !endif
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0
+  gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask|0x0
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x3
+!endif
+  gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask|0x18
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xE0000000
+!if $(GALILEO) == GEN1
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|460800
+!endif
+!if $(GALILEO) == GEN2
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|921600
+!endif
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits|8
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|1
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|1
+  gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|0
+!if $(PERFORMANCE_ENABLE)
+  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0x1
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPerformanceLogEntries|80
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0x00
+!endif
+  gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable|0
+!if $(SECURE_BOOT_ENABLE)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
+!endif
+  gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize|0x00002000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x1000
+  #
+  # Make VariableRuntimeDxe work at emulated non-volatile variable mode.
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE
+  ## RTC Update Timeout Value, need to increase timeout since also
+  # waiting for RTC to be busy.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdRealTimeClockUpdateTimeout|500000
+
+!if $(SECURE_BOOT_ENABLE)
+  # override the default values from SecurityPkg to ensure images from all sources are verified in secure boot
+  gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x04
+  gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy|0x04
+  gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy|0x04
+!endif
+  gQuarkPlatformTokenSpaceGuid.PcdEsramStage1Base|0x80000000
+
+!if $(SOURCE_DEBUG_ENABLE)
+  gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod|0x2
+!endif
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x9000B000
+!if $(GALILEO) == GEN1
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate|460800
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl|FALSE
+!endif
+!if $(GALILEO) == GEN2
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate|921600
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl|FALSE
+!endif
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialLineControl|0x03
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialFifoControl|0x07
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialDetectCable|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate|44236800
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialPciDeviceInfo|{0x14, 0x05, 0x84, 0x00, 0xFF}
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride|4
+
+  #
+  #  typedef struct {
+  #    UINT16  VendorId;          ///< Vendor ID to match the PCI device.  The value 0xFFFF terminates the list of entries.
+  #    UINT16  DeviceId;          ///< Device ID to match the PCI device
+  #    UINT32  ClockRate;         ///< UART clock rate.  Set to 0 for default clock rate of 1843200 Hz
+  #    UINT64  Offset;            ///< The byte offset into to the BAR
+  #    UINT8   BarIndex;          ///< Which BAR to get the UART base address
+  #    UINT8   RegisterStride;    ///< UART register stride in bytes.  Set to 0 for default register stride of 1 byte.
+  #    UINT16  ReceiveFifoDepth;  ///< UART receive FIFO depth in bytes. Set to 0 for a default FIFO depth of 16 bytes.
+  #    UINT16  TransmitFifoDepth; ///< UART transmit FIFO depth in bytes. Set to 0 for a default FIFO depth of 16 bytes.
+  #    UINT8   Reserved[2];
+  #  } PCI_SERIAL_PARAMETER;
+  #
+  # Vendor 8086 Device 0936 Prog Interface 2, BAR #0, Offset 0, Stride = 4, Clock 44236800 (0x2a300000)
+  # Vendor 8086 Device 0936 Prog Interface 2, BAR #0, Offset 0, Stride = 4, Clock 44236800 (0x2a300000)
+  #
+  #                                                       [Vendor]   [Device]  [---ClockRate---]  [------------Offset-----------] [Bar] [Stride] [RxFifo] [TxFifo]   [Rsvd]   [Vendor]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPciSerialParameters|{0x86,0x80, 0x36,0x09, 0x0,0x0,0xA3,0x02, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x00,    0x04, 0x0,0x0, 0x0,0x0, 0x0,0x0, 0xff,0xff}
+
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBusNumber           |0
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciDeviceNumber        |31
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciFunctionNumber      |0
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciEnableRegisterOffset|0x4b
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoBarEnableMask          |0x80
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBarRegisterOffset   |0x48
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddress        |0x1000
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiPm1TmrOffset             |0x0008
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand|FALSE
+
+  #
+  # Quark does not support LFENCE.  Use CPUID as speculation barrier
+  #
+  gEfiMdePkgTokenSpaceGuid.PcdSpeculationBarrierType|0x02
+
+[PcdsPatchableInModule]
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x803000C7
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
+
+[PcdsDynamicExHii.common.DEFAULT]
+!if $(PERFORMANCE_ENABLE)
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|0
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|5
+!endif
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBootState|L"BootState"|gQuarkPlatformTokenSpaceGuid|0x0|TRUE
+
+[PcdsDynamicExDefault.common.DEFAULT]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr|0x0
+  gQuarkPlatformTokenSpaceGuid.PcdEnableFastBoot|TRUE
+  gQuarkPlatformTokenSpaceGuid.PcdUserIsPhysicallyPresent|FALSE
+  gQuarkPlatformTokenSpaceGuid.PcdSpiFlashDeviceSize|0
+
+[PcdsDynamicExVpd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVendor|*|32|L"EDK II"
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareRevision|*|0x01000400
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|*|64|L"Galileo 1.0.4"
+
+#
+# ClantonPeakSVP
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformType|*|0x0002
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformTypeName|*|64|L"ClantonPeakSVP"
+# gEfiQuarkNcSocIdTokenSpaceGuid.PcdMrcParameters|*|40|{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x03, 0x7c, 0x92, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x40, 0x9c, 0x00, 0x00, 0x06}
+#
+# KipsBay
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformType|*|0x0003
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformTypeName|*|64|L"KipsBay"
+# gEfiQuarkNcSocIdTokenSpaceGuid.PcdMrcParameters|*|40|{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x7c, 0x92, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x40, 0x9c, 0x00, 0x00, 0x06}
+#
+# CrossHill
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformType|*|0x0004
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformTypeName|*|64|L"CrossHill"
+# gEfiQuarkNcSocIdTokenSpaceGuid.PcdMrcParameters|*|40|{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x03, 0x7c, 0x92, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x40, 0x9c, 0x00, 0x00, 0x06}
+#
+# ClantonHill
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformType|*|0x0005
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformTypeName|*|64|L"ClantonHill"
+# gEfiQuarkNcSocIdTokenSpaceGuid.PcdMrcParameters|*|40|{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x7c, 0x92, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x40, 0x9c, 0x00, 0x00, 0x06}
+#
+# Galileo
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformType|*|0x0006
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformTypeName|*|64|L"Galileo"
+# gEfiQuarkNcSocIdTokenSpaceGuid.PcdMrcParameters|*|40|{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x7c, 0x92, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x40, 0x9c, 0x00, 0x00, 0x06}
+#
+# GalileoGen2
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformType|*|0x0008
+# gQuarkPlatformTokenSpaceGuid.PcdPlatformTypeName|*|64|L"GalileoGen2"
+# gEfiQuarkNcSocIdTokenSpaceGuid.PcdMrcParameters|*|40|{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x7c, 0x92, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x40, 0x9c, 0x00, 0x00, 0x06}
+#
+!if $(GALILEO) == GEN1
+  gQuarkPlatformTokenSpaceGuid.PcdPlatformType|*|0x0006
+  gQuarkPlatformTokenSpaceGuid.PcdPlatformTypeName|*|64|L"Galileo"
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdMrcParameters|*|40|{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x7c, 0x92, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x40, 0x9c, 0x00, 0x00, 0x06}
+!endif
+!if $(GALILEO) == GEN2
+  gQuarkPlatformTokenSpaceGuid.PcdPlatformType|*|0x0008
+  gQuarkPlatformTokenSpaceGuid.PcdPlatformTypeName|*|64|L"GalileoGen2"
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdMrcParameters|*|40|{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x7c, 0x92, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x40, 0x9c, 0x00, 0x00, 0x06}
+!endif
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohEthernetMac0|*|8|{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
+  gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohEthernetMac1|*|8|{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
+
+###################################################################################################
+#
+# Components Section - list of the modules and components that will be processed by compilation
+#                      tools and the EDK II tools to generate PE32/PE32+/Coff image files.
+#
+# Note: The EDK II DSC file is not used to specify how compiled binary images get placed
+#       into firmware volume images. This section is just a list of modules to compile from
+#       source into UEFI-compliant binaries.
+#       It is the FDF file that contains information on combining binary files into firmware
+#       volume images, whose concept is beyond UEFI and is described in PI specification.
+#       Binary modules do not need to be listed in this section, as they should be
+#       specified in the FDF file. For example: Shell binary, FAT binary (Fat.efi),
+#       Logo (Logo.bmp), and etc.
+#       There may also be modules listed in this section that are not required in the FDF file,
+#       When a module listed here is excluded from FDF file, then UEFI-compliant binary will be
+#       generated for it, but the binary will not be put into any firmware volume.
+#
+###################################################################################################
+
+[Components.IA32]
+  #
+  # SEC Core
+  #
+  UefiCpuPkg/SecCore/SecCore.inf {
+    !if $(SOURCE_DEBUG_ENABLE)
+      <LibraryClasses>
+        PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+        DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
+        ResetSystemLib|QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/ResetSystemLib.inf
+    !endif
+  }
+
+  #
+  # PEI Core
+  #
+  MdeModulePkg/Core/Pei/PeiMain.inf
+
+  #
+  # PEIM
+  #
+  MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+  MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
+  MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+  MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2Pei.inf
+
+  QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInitPei.inf
+  QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.inf
+  QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.inf
+
+  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+
+[Components.IA32]
+  #
+  # DXE Core
+  #
+  MdeModulePkg/Core/Dxe/DxeMain.inf
+
+!if $(SOURCE_DEBUG_ENABLE)
+  SourceLevelDebugPkg/DebugAgentDxe/DebugAgentDxe.inf {
+    <LibraryClasses>
+      DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+      ResetSystemLib|QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/ResetSystemLib.inf
+  }
+!endif
+
+
+  QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.inf
+
+  #
+  # Components that produce the architectural protocols
+  #
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+  UefiCpuPkg/CpuDxe/CpuDxe.inf
+  MdeModulePkg/Universal/Metronome/Metronome.inf
+  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
+
+  #
+  # Following are the DXE drivers (alphabetical order)
+  #
+  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+
+  QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.inf
+  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
+
+  #
+  # Platform
+  #
+  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf {
+    <LibraryClasses>
+      PlatformBootManagerLib|QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+  }
+
+  QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInitDxe.inf
+  PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf
+  QuarkPlatformPkg/Platform/Dxe/Setup/DxePlatform.inf
+  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+
+  #
+  # PCI
+  #
+  QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.inf
+  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+  QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohInitDxe.inf
+  MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf
+
+  #
+  # Console
+  #
+  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf {
+    <LibraryClasses>
+      CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+  }
+  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+
+  #
+  # File System Modules
+  #
+  MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf
+
+  #
+  # Performance Application
+  #
+!if $(PERFORMANCE_ENABLE)
+  ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf {
+    <PcdsFixedAtBuild>
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+  }
+!endif
+
+  ShellPkg/Application/Shell/Shell.inf {
+    <LibraryClasses>
+      ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
+      HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+      PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+      BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+      gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
+  }
diff --git a/Platform/Intel/QuarkPlatformPkg/QuarkMin.fdf b/Platform/Intel/QuarkPlatformPkg/QuarkMin.fdf
new file mode 100644
index 0000000000..bdd5af8fb8
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/QuarkMin.fdf
@@ -0,0 +1,608 @@
+## @file
+# FDF file of Clanton Peak CRB platform with 32-bit DXE
+#
+# This package provides QuarkNcSocId platform specific modules.
+# Copyright (c) 2013 - 2019 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+#                  Address 0x100000000 (4 GB reset address)
+#                                 Base                               Size
+#                                      +---------------------------+
+#                           FLASH_BASE | FD.Quark:                 | 0x800000 (8 MB)
+#                           0xFF800000 | BaseAddress               |
+#                                      +---------------------------+
+#
+# Flash offsets are 0 based, but are relative to FD.Quark BaseAddress, e.g. Payload Base is at 0x400000, Flash Base is at 0xFF800000 for 8 MB SPI part.
+# 0xFF800000 + 0x400000 = 0xFFC00000.
+#
+#                          Address 0x0 (0xFF800000 for 8 MB SPI part)
+#                                      +---------------------------+
+#                FLASH_FV_PAYLOAD_BASE | Payload Image             | FLASH_FV_PAYLOAD_SIZE
+#                           0x00400000 |                           | 0x00100000
+#                                      +---------------------------+
+#                   FLASH_FV_MAIN_BASE | FvMain Image (Compressed) | FLASH_FV_MAIN_SIZE
+#                           0x00500000 |                           | 0x001E0000
+#                                      +---------------------------+
+#                      NVRAM_AREA_BASE | NVRAM Area=               | NVRAM_AREA_SIZE
+#                           0x006E0000 | Variable + FTW Working +  |
+#                                      | FTW Spare                 |
+#                                      +---+-------------------+---+
+#                 NVRAM_AREA_VARIABLE_BASE |                   | NVRAM_AREA_VARIABLE_SIZE
+#                                          |                   |
+#                                          +-------------------+
+#                         FTW_WORKING_BASE |                   | FTW_WORKING_SIZE
+#                                          |                   |
+#                                          +-------------------+
+#                           FTW_SPARE_BASE |                   | FTW_SPARE_SIZE
+#                                          |                   |
+#                                      +---+-------------------+---+
+#                      RMU_BINARY_BASE | RMU Binary                | RMU_BINARY_SIZE
+#                           0x00700000 |                           | 0x00008000
+#                                      +---------------------------+
+#                   PLATFORM_DATA_BASE | PlatformData Binary       | PLATFORM_DATA_SIZE
+#                           0x00710000 |                           | 0x00001000
+#                                      +---------------------------+
+#                FVRECOVERY_IMAGE_BASE | FVRECOVERY Image          | FVRECOVERY_IMAGE_SIZE
+#                             0x720000 |                           | 0x000E0000
+#                                      +---------------------------+
+
+  #
+  # Define value used to compute FLASH regions below reset vector location just below 4GB
+  #
+  DEFINE RESET_ADDRESS                           = 0x100000000       # 4 GB
+
+  #
+  # Set size of FLASH to 8MB
+  #
+  DEFINE FLASH_SIZE                              = 0x800000
+  DEFINE FLASH_BASE                              = $(RESET_ADDRESS) - $(FLASH_SIZE)                                                      # The base address of the Flash Device
+
+  #
+  # Set FLASH block size to 4KB
+  #
+  DEFINE FLASH_BLOCKSIZE                         = 0x1000            # 4 KB
+
+  #
+  # Misc settings
+  #
+  DEFINE FLASH_BLOCKSIZE_DATA                    = 0x00, 0x10, 0x00, 0x00                                                                # equivalent for DATA blocks
+
+  #
+  # Start PAYLOAD at 4MB into 8MB FLASH
+  #
+  DEFINE FLASH_FV_PAYLOAD_BASE                   = 0x00400000
+  DEFINE FLASH_FV_PAYLOAD_SIZE                   = 0x00100000
+
+  #
+  # Put FVMAIN between PAYLOAD and RMU Binary
+  #
+  DEFINE FLASH_FV_MAIN_BASE                      = 0x00500000
+  DEFINE FLASH_FV_MAIN_SIZE                      = 0x001E0000
+
+  #
+  # Place NV Storage just above Platform Data Base
+  #
+  DEFINE NVRAM_AREA_VARIABLE_BASE                = 0x006E0000
+  DEFINE NVRAM_AREA_SIZE                         = 0x00020000
+
+  DEFINE NVRAM_AREA_VARIABLE_SIZE                = 0x0000E000
+  DEFINE FTW_WORKING_BASE                        = $(NVRAM_AREA_VARIABLE_BASE) + $(NVRAM_AREA_VARIABLE_SIZE)
+  DEFINE FTW_WORKING_SIZE                        = 0x00002000
+  DEFINE FTW_SPARE_BASE                          = $(FTW_WORKING_BASE) + $(FTW_WORKING_SIZE)
+  DEFINE FTW_SPARE_SIZE                          = $(NVRAM_AREA_SIZE) - $(NVRAM_AREA_VARIABLE_SIZE) - $(FTW_WORKING_SIZE)
+
+  #
+  # RMU Binary must be at fixed address 1MB below 4GB (0xFFF00000)
+  #
+  DEFINE RMU_BINARY_BASE                         = 0x00700000  # HW fixed address
+  DEFINE RMU_BINARY_SIZE                         = 0x00008000  # HW fixed address, so fixed size
+
+  #
+  # Platform Data Base must be 64KB above RMU
+  #
+  DEFINE VPD_BASE                                = 0x00708000
+  DEFINE VPD_SIZE                                = 0x00001000
+
+  #
+  # Place FV Recovery above NV Storage
+  #
+  DEFINE FVRECOVERY_IMAGE_SIZE                   = 0x000F0000
+  DEFINE FVRECOVERY_IMAGE_BASE                   = $(FLASH_SIZE) - $(FVRECOVERY_IMAGE_SIZE)
+
+################################################################################
+#
+# FD Section
+# The [FD] Section is made up of the definition statements and a
+# description of what goes into  the Flash Device Image.  Each FD section
+# defines one flash "device" image.  A flash device image may be one of
+# the following: Removable media bootable image (like a boot floppy
+# image,) an Option ROM image (that would be "flashed" into an add-in
+# card,) a System "Flash"  image (that would be burned into a system's
+# flash) or an Update ("Capsule") image that will be used to update and
+# existing system flash.
+#
+################################################################################
+[FD.Quark]
+BaseAddress   = 0xFF800000                   #The base address of the Flash Device; set to same value as FLASH_BASE.
+Size          = 0x800000                     #The size in bytes of the Flash Device; set to same value as FLASH_SIZE.
+ErasePolarity = 1
+BlockSize     = $(FLASH_BLOCKSIZE)
+NumBlocks     = 0x800                        #The number of blocks for the Flash Device.
+
+SET gQuarkPlatformTokenSpaceGuid.PcdFlashAreaBaseAddress = $(FLASH_BASE)
+SET gQuarkPlatformTokenSpaceGuid.PcdFlashAreaSize        = $(FLASH_SIZE)
+
+################################################################################
+#
+# Following are lists of FD Region layout which correspond to the locations of different
+# images within the flash device.
+#
+# Regions must be defined in ascending order and may not overlap.
+#
+# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
+# the pipe "|" character, followed by the size of the region, also in hex with the leading
+# "0x" characters. Like:
+# Offset|Size
+# PcdOffsetCName|PcdSizeCName
+# RegionType <FV, DATA, or FILE>
+#
+################################################################################
+
+########################################################
+# Quark Payload Image
+########################################################
+$(FLASH_FV_PAYLOAD_BASE)|$(FLASH_FV_PAYLOAD_SIZE)
+gQuarkPlatformTokenSpaceGuid.PcdFlashFvPayloadBase|gQuarkPlatformTokenSpaceGuid.PcdFlashFvPayloadSize
+FV = PAYLOAD
+
+########################################################
+# Quark FVMAIN Image (Compressed)
+########################################################
+$(FLASH_FV_MAIN_BASE)|$(FLASH_FV_MAIN_SIZE)
+gQuarkPlatformTokenSpaceGuid.PcdFlashFvMainBase|gQuarkPlatformTokenSpaceGuid.PcdFlashFvMainSize
+FV = FVMAIN_COMPACT
+
+#############################################################################
+# Quark NVRAM Area
+# Quark NVRAM Area contains: Variable + FTW Working + FTW Spare
+#############################################################################
+$(NVRAM_AREA_VARIABLE_BASE)|$(NVRAM_AREA_VARIABLE_SIZE)
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+#NV_VARIABLE_STORE
+DATA = {
+  ## This is the EFI_FIRMWARE_VOLUME_HEADER
+  # ZeroVector []
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  # FileSystemGuid: gEfiSystemNvDataFvGuid         =
+  #  { 0xFFF12B8D, 0x7696, 0x4C8B, { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }}
+  0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
+  0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
+  # FvLength: 0x20000
+  0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+  #Signature "_FVH"       #Attributes
+  0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,
+  #HeaderLength #CheckSum #ExtHeaderOffset #Reserved #Revision
+  0x48, 0x00, 0x19, 0xF9, 0x00, 0x00, 0x00, 0x02,
+  #Blockmap[0]: 32 Blocks * 0x1000 Bytes / Block
+  0x20, 0x00, 0x00, 0x00, $(FLASH_BLOCKSIZE_DATA),
+  #Blockmap[1]: End
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  ## This is the VARIABLE_STORE_HEADER
+  !if $(SECURE_BOOT_ENABLE)
+    # Signature: gEfiAuthenticatedVariableGuid = { 0xaaf32c78, 0x947b, 0x439a, { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 } }
+    0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,
+    0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,
+  !else
+    #  Signature: gEfiVariableGuid = { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }}
+    0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41,
+    0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d,
+  !endif
+  #Size: 0x0E000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x0DFB8
+  # This can speed up the Variable Dispatch a bit.
+  0xB8, 0xDF, 0x00, 0x00,
+  #FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
+  0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+$(FTW_WORKING_BASE)|$(FTW_WORKING_SIZE)
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+#NV_FTW_WORKING
+DATA = {
+  # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid         =
+  #  { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95 }}
+  0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49,
+  0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95,
+  # Crc:UINT32            #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
+  0xE2, 0x33, 0xF2, 0x03, 0xFE, 0xFF, 0xFF, 0xFF,
+  # WriteQueueSize: UINT64 #Size: 0x2000 - 0x20 (FTW_WORKING_HEADER) = 0x1FE0
+  0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+$(FTW_SPARE_BASE)|$(FTW_SPARE_SIZE)
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+#NV_FTW_SPARE
+
+#########################################################
+# Quark Remote Management Unit Binary
+#########################################################
+$(RMU_BINARY_BASE)|$(RMU_BINARY_SIZE)
+INF  QuarkSocBinPkg/QuarkNorthCluster/Binary/QuarkMicrocode/QuarkMicrocode.inf
+
+#########################################################
+# PlatformData Binary, default for standalone is none built-in so user selects.
+#########################################################
+$(VPD_BASE)|$(VPD_SIZE)
+gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress
+FILE = $(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/FV/8C3D856A-9BE6-468E-850A-24F7A8D38E08.bin
+
+#######################
+# Quark FVRECOVERY Image
+#######################
+$(FVRECOVERY_IMAGE_BASE)|$(FVRECOVERY_IMAGE_SIZE)
+gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoveryBase|gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoverySize
+FV = FVRECOVERY
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file.  This section also defines order the components and modules are positioned
+# within the image.  The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+[FV.FVRECOVERY]
+BlockSize          = $(FLASH_BLOCKSIZE)
+FvAlignment        = 16         #FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 18D6D9F4-2EEF-4913-AEE6-BE61C6DA6CC8
+
+################################################################################
+#
+# The INF statements point to EDK component and EDK II module INF files, which will be placed into this FV image.
+# Parsing tools will scan the INF file to determine the type of component or module.
+# The component or module type is used to reference the standard rules
+# defined elsewhere in the FDF file.
+#
+# The format for INF statements is:
+# INF $(PathAndInfFileName)
+#
+################################################################################
+
+##
+#  PEI Apriori file example, more PEIM module added later.
+##
+APRIORI PEI {
+  INF  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+  # PlatformConfigPei should be immediately after Pcd driver.
+  INF  QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.inf
+  INF  MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2Pei.inf
+}
+
+##
+#  SEC Phase modules
+##
+INF  UefiCpuPkg/SecCore/SecCore.inf
+
+INF  MdeModulePkg/Core/Pei/PeiMain.inf
+
+##
+#  PEI Phase RAW Data files.
+##
+FILE FREEFORM = PCD(gEfiQuarkNcSocIdTokenSpaceGuid.PcdQuarkMicrocodeFile) {
+  SECTION RAW = QuarkSocBinPkg/QuarkNorthCluster/Binary/QuarkMicrocode/RMU.bin
+}
+
+INF  RuleOverride = NORELOC  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+INF  QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.inf
+INF  RuleOverride = NORELOC  MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
+INF  RuleOverride = NORELOC  MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+INF  RuleOverride = NORELOC  QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInitPei.inf
+INF  QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.inf
+INF  MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2Pei.inf
+INF  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file.  This section also defines order the components and modules are positioned
+# within the image.  The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+[FV.FVMAIN]
+BlockSize          = $(FLASH_BLOCKSIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 30D9ED01-38D2-418a-90D5-C561750BF80F
+
+##
+#  DXE Phase modules
+##
+INF  MdeModulePkg/Core/Dxe/DxeMain.inf
+INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+
+!if $(SOURCE_DEBUG_ENABLE)
+  INF  SourceLevelDebugPkg/DebugAgentDxe/DebugAgentDxe.inf
+!endif
+
+#
+# Early SoC / Platform modules
+#
+INF  QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.inf
+
+##
+#  EDK Core modules
+##
+INF  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
+
+INF  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+INF  UefiCpuPkg/CpuDxe/CpuDxe.inf
+INF  MdeModulePkg/Universal/Metronome/Metronome.inf
+INF  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+INF  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+INF  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+INF  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+INF  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+INF  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+INF  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
+INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+INF  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+
+#
+# Platform
+#
+INF  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+#INF  MdeModulePkg/Application/UiApp/UiApp.inf
+
+INF  QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.inf
+INF  QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInitDxe.inf
+INF  PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf
+INF  QuarkPlatformPkg/Platform/Dxe/Setup/DxePlatform.inf
+
+#
+# PCI
+#
+INF  QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.inf
+INF  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+INF  QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohInitDxe.inf
+!if $(SOURCE_DEBUG_ENABLE)
+!else
+INF  MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf
+!endif
+
+#
+# Console
+#
+INF  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+INF  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+INF  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+
+INF  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+INF  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+INF  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+INF  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+
+#
+# File System Modules
+#
+INF  MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf
+
+#
+# Performance Application
+#
+!if $(PERFORMANCE_ENABLE)
+INF  ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf
+!endif
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file.  This section also defines order the components and modules are positioned
+# within the image.  The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+[FV.FVMAIN_COMPACT]
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+  SECTION GUIDED A31280AD-481E-41B6-95E8-127F4C984779 {    # TIANO COMPRESS GUID
+    SECTION FV_IMAGE = FVMAIN
+  }
+}
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file.  This section also defines order the components and modules are positioned
+# within the image.  The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+[FV.PAYLOAD]
+BlockSize          = $(FLASH_BLOCKSIZE)
+FvAlignment        = 16         #FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+#
+# Shell and Applications
+#
+INF  ShellPkg/Application/Shell/Shell.inf
+
+################################################################################
+#
+# Rules are use with the [FV] section's module INF type to define
+# how an FFS file is created for a given INF file. The following Rule are the default
+# rules for the different module type. User can add the customized rules to define the
+# content of the FFS file.
+#
+################################################################################
+[Rule.Common.SEC]
+  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+    TE  TE    Align = 8       $(INF_OUTPUT)/$(MODULE_NAME).efi
+    RAW BIN   Align = 16      |.com
+  }
+
+[Rule.Common.PEI_CORE]
+  FILE PEI_CORE = $(NAMED_GUID)            {
+    TE       TE               $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.PEIM.NORELOC]
+  FILE PEIM = $(NAMED_GUID) RELOCS_STRIPPED  {
+     PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+     TE        TE                        $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI        STRING="$(MODULE_NAME)" Optional
+     VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.PEIM]
+  FILE PEIM = $(NAMED_GUID)               {
+     PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+     TE        TE                        $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI        STRING="$(MODULE_NAME)" Optional
+     VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_CORE]
+  FILE DXE_CORE = $(NAMED_GUID) {
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_RUNTIME_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_SMM_DRIVER]
+  FILE SMM = $(NAMED_GUID) {
+    SMM_DEPEX SMM_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.SMM_CORE]
+  FILE SMM_CORE = $(NAMED_GUID) {
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION]
+  FILE APPLICATION = $(NAMED_GUID) {
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION.UI]
+  FILE APPLICATION = $(NAMED_GUID) {
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="Enter Setup"
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.USER_DEFINED.ACPITABLE]
+  FILE FREEFORM = $(NAMED_GUID) {
+    RAW ACPI               |.acpi
+    RAW ASL                |.aml
+  }
diff --git a/Platform/Intel/QuarkPlatformPkg/QuarkPlatformPkg.dec b/Platform/Intel/QuarkPlatformPkg/QuarkPlatformPkg.dec
new file mode 100644
index 0000000000..57bd393bb0
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/QuarkPlatformPkg.dec
@@ -0,0 +1,933 @@
+## @file
+# Package for support of Clanton Peak CRB platform
+#
+# This package provides QuarkNcSocId platform specific modules.
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+
+[Defines]
+  DEC_SPECIFICATION              = 0x00010005
+  PACKAGE_NAME                   = QuarkPlatformPkg
+  PACKAGE_GUID                   = 46C1F476-A85E-49a8-B258-DD4396B87FEF
+  PACKAGE_VERSION                = 0.1
+
+
+################################################################################
+#
+# Include Section - list of Include Paths that are provided by this package.
+#                   Comments are used for Keywords and Module Types.
+#
+# Supported Module Types:
+#  SEC PEIM DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER
+#
+################################################################################
+[Includes]
+  Include
+
+################################################################################
+#
+# Library Class Header section - list of Library Class header files that are
+#                                provided by this package.
+#
+################################################################################
+[LibraryClasses]
+
+################################################################################
+#
+# Global Guid Definition section - list of Global Guid C Name Data Structures
+#                                  that are provided by this package.
+#
+################################################################################
+[Guids]
+  gQuarkPlatformTokenSpaceGuid      = { 0x199c1ef0, 0x6400, 0x41c5, { 0xb0, 0xa4, 0xff, 0xbf, 0x21, 0x9d, 0xcb, 0xae }}
+  gEfiMemoryConfigDataGuid       = { 0x80dbd530, 0xb74c, 0x4f11, { 0x8c, 0x03, 0x41, 0x86, 0x65, 0x53, 0x28, 0x31 }}
+  gPowerManagementAcpiTableStorageGuid = { 0xc0cc43bd, 0xc920, 0x4064, { 0x93, 0x5b, 0x93, 0xb4, 0x47, 0x37, 0x94, 0x70 }}
+  gPeiCapsuleOnFatFloppyDiskGuid = {0x2e3d2e75, 0x9b2e, 0x412d, {0xb4, 0xb1, 0x70, 0x41, 0x6b, 0x87, 0x0, 0xff }}
+  gPeiCapsuleOnFatIdeDiskGuid = {0xb38573b6, 0x6200, 0x4ac5, {0xb5, 0x1d, 0x82, 0xe6, 0x59, 0x38, 0xd7, 0x83 }}
+  gPeiCapsuleOnFatUsbDiskGuid = {0x0ffbce19, 0x324c, 0x4690, {0xa0, 0x09, 0x98, 0xc6, 0xae, 0x2e, 0xb1, 0x86 }}
+  gPeiCapsuleOnDataCDGuid = {0x5cac0099, 0x0dc9, 0x48e5, {0x80, 0x68, 0xbb, 0x95, 0xf5, 0x40, 0x0a, 0x9f }}
+  gEfiQuarkCapsuleGuid = { 0xd400d1e4, 0xa314, 0x442b, { 0x89, 0xed, 0xa9, 0x2e, 0x4c, 0x81, 0x97, 0xcb } }
+  gQuarkVariableLockGuid      = { 0xeef749c2, 0xc047, 0x4d6e, { 0xb1, 0xbc, 0xd3, 0x6e, 0xb3, 0xa5, 0x55, 0x9c }}
+
+################################################################################
+#
+# Global Protocols Definition section - list of Global Protocols C Name Data
+#                                  Structures that are provided by this package.
+#
+################################################################################
+[Protocols]
+  gEfiGlobalNvsAreaProtocolGuid  = { 0x074E1E48, 0x8132, 0x47A1, { 0x8C, 0x2C, 0x3F, 0x14, 0xAD, 0x9A, 0x66, 0xDC }}
+  gEfiSmmSpiReadyProtocolGuid    = { 0x7a5dbc75, 0x5b2b, 0x4e67, { 0xbd, 0xe1, 0xd4, 0x8e, 0xee, 0x76, 0x15, 0x62 }}
+  gEfiIioUdsProtocolGuid        = { 0xa7ced760, 0xc71c, 0x4e1a, { 0xac, 0xb1, 0x89, 0x60, 0x4d, 0x52, 0x16, 0xcb }}
+
+################################################################################
+#
+# PCD Declarations section - list of all PCDs Declared by this Package
+#                            Only this package should be providing the
+#                            declaration, other packages should not.
+#
+################################################################################
+
+[PcdsFeatureFlag]
+  gQuarkPlatformTokenSpaceGuid.WaitIfResetDueToError|FALSE|BOOLEAN|0x2000000F
+
+[PcdsFixedAtBuild]
+  gQuarkPlatformTokenSpaceGuid.PcdFlashAreaBaseAddress|0xFF800000|UINT32|0x20000001
+  gQuarkPlatformTokenSpaceGuid.PcdFlashAreaSize|0x800000|UINT32|0x20000002
+  gQuarkPlatformTokenSpaceGuid.PcdFlashNvStorageBase|0xFFF30000|UINT32|0x20000003
+  gQuarkPlatformTokenSpaceGuid.PcdFlashNvStorageSize|0x00020000|UINT32|0x20000004
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecovery2Base|0xFFEF0400|UINT32|0x2000001C
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecovery2Size|0x00007000|UINT32|0x2000001D
+  gQuarkPlatformTokenSpaceGuid.PcdFlashQNCMicrocodeSize|0x00004000|UINT32|0x2000000C
+  gQuarkPlatformTokenSpaceGuid.PcdPlatformDataBaseAddress|0xFFF10000|UINT32|0x2000001E
+  gQuarkPlatformTokenSpaceGuid.PcdPlatformDataMaxLen|0x20000|UINT32|0x2000001F
+  gQuarkPlatformTokenSpaceGuid.PcdHpetEnable|TRUE|BOOLEAN|0x20000018
+
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvDefaultPayloadBase|0xFFC00400|UINT32|0x20000020
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvDefaultPayloadSize|0x000F0000|UINT32|0x20000021
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvDefaultMainBase|0xFFD00400|UINT32|0x20000022
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvDefaultMainSize|0x000D0000|UINT32|0x20000023
+
+  gQuarkPlatformTokenSpaceGuid.PcdMemorySize|0x80000000|UINT32|0x20000032
+  # ECC scrub interval in miliseconds 1..255 (0 works as feature disable)
+  gQuarkPlatformTokenSpaceGuid.PcdEccScrubInterval|0x00|UINT8|0x20000037
+  # Number of 32B blocks read for ECC scrub 2..16
+  gQuarkPlatformTokenSpaceGuid.PcdEccScrubBlkSize|0x02|UINT8|0x20000038
+  gQuarkPlatformTokenSpaceGuid.PcdFlashNvMfh|0xFFF08000|UINT32|0x20000039
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvFixedStage1AreaBase|0xFFF90000|UINT32|0x2000003A
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvFixedStage1AreaSize|0x00040000|UINT32|0x2000003B
+  gQuarkPlatformTokenSpaceGuid.PcdEsramStage1Base|0x80000000|UINT32|0x2000003C
+
+  # Legacy Bridge protected BIOS range register configs, if == 0 then do nothing since register default.
+  gQuarkPlatformTokenSpaceGuid.PcdLegacyProtectedBIOSRange0Pei|0x00000000|UINT32|0x2000003D
+  gQuarkPlatformTokenSpaceGuid.PcdLegacyProtectedBIOSRange1Pei|0x00000000|UINT32|0x2000003E
+  gQuarkPlatformTokenSpaceGuid.PcdLegacyProtectedBIOSRange2Pei|0x00000000|UINT32|0x2000004F
+
+  # ACPI Power management settings.
+
+  # Power Management flags.
+  # PpmFlags[5] = PPM_C2      = C2 Capable, Enabled.
+  gQuarkPlatformTokenSpaceGuid.PcdPpmFlags|0x00000020|UINT32|0xA00000CF
+
+  # Madt Table Initialize settings.
+  # Defines a flag to Enable/Disable interrupt override setting table0,
+  # and the source Irq, Polarity, Triger Mode and global Irq of interrupt override setting table0
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable0Enable|0x01|UINT8|0xA0000100
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable0SourceIrq|0x00|UINT8|0xA0000101
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable0Polarity|0x00|UINT8|0xA0000102
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable0TrigerMode|0x00|UINT8|0xA0000103
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable0GlobalIrq|0x02|UINT32|0xA0000104
+
+  # Madt Table Initialize settings.
+  # Defines a flag to Enable/Disable interrupt override setting table1,
+  # and the source Irq, Polarity, Triger Mode and global Irq of interrupt override setting table1
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable1Enable|0x01|UINT8|0xA0000105
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable1SourceIrq|0x09|UINT8|0xA0000106
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable1Polarity|0x01|UINT8|0xA0000107
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable1TrigerMode|0x03|UINT8|0xA0000108
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable1GlobalIrq|0x09|UINT32|0xA0000109
+
+  # Madt Table Initialize settings.
+  # Defines a flag to Enable/Disable interrupt override setting table2,
+  # and the source Irq, Polarity, Triger Mode and global Irq of interrupt override setting table2
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable2Enable|0x0|UINT8|0xA000010F
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable2SourceIrq|0x0|UINT8|0xA0000110
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable2Polarity|0x0|UINT8|0xA0000111
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable2TrigerMode|0x0|UINT8|0xA0000112
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable2GlobalIrq|0x0|UINT32|0xA0000113
+
+  # Madt Table Initialize settings.
+  # Defines a flag to Enable/Disable interrupt override setting table3,
+  # and the source Irq, Polarity, Triger Mode and global Irq of interrupt override setting table3
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable3Enable|0x0|UINT8|0xA0000114
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable3SourceIrq|0x0|UINT8|0xA0000115
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable3Polarity|0x0|UINT8|0xA0000116
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable3TrigerMode|0x0|UINT8|0xA0000117
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable3GlobalIrq|0x0|UINT32|0xA0000118
+
+  # Madt Table Initialize settings.
+  # Defines a flag to Enable/Disable interrupt override setting table4,
+  # and the source Irq, Polarity, Triger Mode and global Irq of interrupt override setting table4
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable4Enable|0x0|UINT8|0xA0000119
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable4SourceIrq|0x0|UINT8|0xA000011A
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable4Polarity|0x0|UINT8|0xA0000120
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable4TrigerMode|0x0|UINT8|0xA0000121
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable4GlobalIrq|0x0|UINT32|0xA0000122
+
+  # Madt Table Initialize settings.
+  # Defines a flag to Enable/Disable interrupt override setting table5,
+  # and the source Irq, Polarity, Triger Mode and global Irq of interrupt override setting table5
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable5Enable|0x0|UINT8|0xA0000123
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable5SourceIrq|0x0|UINT8|0xA0000124
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable5Polarity|0x0|UINT8|0xA0000125
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable5TrigerMode|0x0|UINT8|0xA0000126
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable5GlobalIrq|0x0|UINT32|0xA0000127
+
+  # Madt Table Initialize settings.
+  # Defines a flag to Enable/Disable interrupt override setting table6,
+  # and the source Irq, Polarity, Triger Mode and global Irq of interrupt override setting table6
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable6Enable|0x0|UINT8|0xA0000128
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable6SourceIrq|0x0|UINT8|0xA0000129
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable6Polarity|0x0|UINT8|0xA000012A
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable6TrigerMode|0x0|UINT8|0xA000012B
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable6GlobalIrq|0x0|UINT32|0xA000012C
+
+  # Madt Table Initialize settings.
+  # Defines a flag to Enable/Disable interrupt override setting table7,
+  # and the source Irq, Polarity, Triger Mode and global Irq of interrupt override setting table7
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable7Enable|0x0|UINT8|0xA000012D
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable7SourceIrq|0x0|UINT8|0xA000012E
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable7Polarity|0x0|UINT8|0xA000012F
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable7TrigerMode|0x0|UINT8|0xA0000130
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable7GlobalIrq|0x0|UINT32|0xA0000131
+
+  # Madt Table Initialize settings.
+  # Defines a flag to Enable/Disable interrupt override setting table8,
+  # and the source Irq, Polarity, Triger Mode and global Irq of interrupt override setting table8
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable8Enable|0x0|UINT8|0xA0000132
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable8SourceIrq|0x0|UINT8|0xA0000133
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable8Polarity|0x0|UINT8|0xA0000134
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable8TrigerMode|0x0|UINT8|0xA0000135
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable8GlobalIrq|0x0|UINT32|0xA0000136
+
+  # Madt Table Initialize settings.
+  # Defines a flag to Enable/Disable interrupt override setting table9,
+  # and the source Irq, Polarity, Triger Mode and global Irq of interrupt override setting table9
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable9Enable|0x0|UINT8|0xA0000137
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable9SourceIrq|0x0|UINT8|0xA0000138
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable9Polarity|0x0|UINT8|0xA0000139
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable9TrigerMode|0x0|UINT8|0xA000013A
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable9GlobalIrq|0x0|UINT32|0xA000013B
+
+  # Madt Table Initialize settings.
+  # Defines a flag to Enable/Disable interrupt override setting table10,
+  # and the source Irq, Polarity, Triger Mode and global Irq of interrupt override setting table10
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable10Enable|0x0|UINT8|0xA000013C
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable10SourceIrq|0x0|UINT8|0xA000013D
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable10Polarity|0x0|UINT8|0xA000013E
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable10TrigerMode|0x0|UINT8|0xA000013F
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable10GlobalIrq|0x0|UINT32|0xA0000140
+
+  # Madt Table Initialize settings.
+  # Defines a flag to Enable/Disable interrupt override setting table11,
+  # and the source Irq, Polarity, Triger Mode and global Irq of interrupt override setting table11
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable11Enable|0x0|UINT8|0xA0000141
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable11SourceIrq|0x0|UINT8|0xA0000142
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable11Polarity|0x0|UINT8|0xA0000143
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable11TrigerMode|0x0|UINT8|0xA0000144
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable11GlobalIrq|0x0|UINT32|0xA0000145
+
+  # Madt Table Initialize settings.
+  # Defines a flag to Enable/Disable interrupt override setting table12,
+  # and the source Irq, Polarity, Triger Mode and global Irq of interrupt override setting table12
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable12Enable|0x0|UINT8|0xA0000146
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable12SourceIrq|0x0|UINT8|0xA0000147
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable12Polarity|0x0|UINT8|0xA0000148
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable12TrigerMode|0x0|UINT8|0xA0000149
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable12GlobalIrq|0x0|UINT32|0xA000014A
+
+  # Madt Table Initialize settings.
+  # Defines a flag to Enable/Disable interrupt override setting table13,
+  # and the source Irq, Polarity, Triger Mode and global Irq of interrupt override setting table13
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable13Enable|0x0|UINT8|0xA000014B
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable13SourceIrq|0x0|UINT8|0xA000014C
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable13Polarity|0x0|UINT8|0xA000014D
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable13TrigerMode|0x0|UINT8|0xA000014E
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable13GlobalIrq|0x0|UINT32|0xA000014F
+
+  # Madt Table Initialize settings.
+  # Defines a flag to Enable/Disable interrupt override setting table14,
+  # and the source Irq, Polarity, Triger Mode and global Irq of interrupt override setting table14
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable14Enable|0x0|UINT8|0xA0000150
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable14SourceIrq|0x0|UINT8|0xA0000151
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable14Polarity|0x0|UINT8|0xA0000152
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable14TrigerMode|0x0|UINT8|0xA0000153
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable14GlobalIrq|0x0|UINT32|0xA0000154
+
+  # Madt Table Initialize settings.
+  # Defines a flag to Enable/Disable interrupt override setting table15,
+  # and the source Irq, Polarity, Triger Mode and global Irq of interrupt override setting table15
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable15Enable|0x0|UINT8|0xA0000155
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable15SourceIrq|0x0|UINT8|0xA0000156
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable15Polarity|0x0|UINT8|0xA0000157
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable15TrigerMode|0x0|UINT8|0xA0000158
+  gQuarkPlatformTokenSpaceGuid.PcdInterruptOverrideSettingTable15GlobalIrq|0x0|UINT32|0xA0000159
+
+  # Madt Table Initialize settings.
+  # Defines a bunch of Pcds for IO APIC setting:
+  # IoApicAddress, GlobalInterruptBase, IoApicId, NmiEnable, NmiSource, Polarity and TrigerMode
+  gQuarkPlatformTokenSpaceGuid.PcdIoApicSettingIoApicAddress|0xFEC00000|UINT32|0xA0000170
+  gQuarkPlatformTokenSpaceGuid.PcdIoApicSettingGlobalInterruptBase|0x0|UINT32|0xA0000171
+  gQuarkPlatformTokenSpaceGuid.PcdIoApicSettingIoApicId|0x01|UINT8|0xA0000172
+  gQuarkPlatformTokenSpaceGuid.PcdIoApicSettingNmiEnable|0x0|UINT8|0xA0000173
+  gQuarkPlatformTokenSpaceGuid.PcdIoApicSettingNmiSource|0x0|UINT8|0xA0000174
+  gQuarkPlatformTokenSpaceGuid.PcdIoApicSettingPolarity|0x0|UINT8|0xA0000175
+  gQuarkPlatformTokenSpaceGuid.PcdIoApicSettingTrigerMode|0x0|UINT8|0xA0000176
+
+  # Madt Table Initialize settings.
+  # Defines a bunch of Pcds for Local APIC setting:
+  # NmiEnabelApicIdMask, AddressOverrideEnable, Polarity, TrigerMode, LocalApicLint, LocalApicAddress and LocalApicAddressOverride
+  gQuarkPlatformTokenSpaceGuid.PcdLocalApicSettingNmiEnabelApicIdMask|0x03|UINT8|0xA0000177
+  gQuarkPlatformTokenSpaceGuid.PcdLocalApicSettingAddressOverrideEnable|0x00|UINT8|0xA0000178
+  gQuarkPlatformTokenSpaceGuid.PcdLocalApicSettingPolarity|0x01|UINT8|0xA0000179
+  gQuarkPlatformTokenSpaceGuid.PcdLocalApicSettingTrigerMode|0x01|UINT8|0xA000017A
+  gQuarkPlatformTokenSpaceGuid.PcdLocalApicSettingLocalApicLint|0x01|UINT8|0xA000017B
+  gQuarkPlatformTokenSpaceGuid.PcdLocalApicAddressOverride|0x00|UINT64|0xA000017C
+
+  # PCDs for auto provisioning of UEFI SecureBoot.
+  gQuarkPlatformTokenSpaceGuid.PcdPkX509File |{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }|VOID*|0xA0000180
+  gQuarkPlatformTokenSpaceGuid.PcdKekX509File |{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }|VOID*|0xA0000181
+  gQuarkPlatformTokenSpaceGuid.PcdKekRsa2048File |{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }|VOID*|0xA0000182
+  gQuarkPlatformTokenSpaceGuid.PcdDbX509File |{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }|VOID*|0xA0000183
+  gQuarkPlatformTokenSpaceGuid.PcdDbxX509File |{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }|VOID*|0xA0000184
+
+[PcdsFixedAtBuild, PcdsPatchableInModule]
+  ## This PCD points to the file name GUID of the BootManagerMenuApp
+  #  Platform can customize the PCD to point to different application for Boot Manager Menu
+  gQuarkPlatformTokenSpaceGuid.PcdBootManagerMenuFile|{ 0xdc, 0x5b, 0xc2, 0xee, 0xf2, 0x67, 0x95, 0x4d, 0xb1, 0xd5, 0xf8, 0x1b, 0x20, 0x39, 0xd1, 0x1d }|VOID*|0x00000003
+
+  #BIOS Information (Type 0), please refer spec SMBIOS 2.4, section 3.3.1 ,for following SMBIOS relates comments.
+
+  # String number of the BIOS Vendors Name
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBiosVendor|"Intel Corp."|VOID*|0xA0000033
+  # String number of the BIOS Release Data
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBiosReleaseDate|"01/01/2014"|VOID*|0xA0000035
+  # Segment location of BIOS starting address.
+  # Note: The size of the runtime BIOS image can be computed by subtracting the Starting Address Segment from 10000h and multiplying the result by 16.
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBiosStartAddress|0xE000|UINT16|0xA0000036
+  #Defines which functions the BIOS supports. PCI, PCMCIA, Flash, etc. See 3.3.1.1.
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBiosChar|0x03037C099880|UINT64|0xA0000037
+  #Defines which functions the BIOS supports. etc.See 3.3.1.2.1.
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBiosCharEx1|0x03|UINT8|0xA0000038
+  #Defines which functions the BIOS supports. etc.See 3.3.1.2.2.
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBiosCharEx2|0x03|UINT8|0xA0000039
+
+  # System Information (Type 1), Section 3.3.2
+  # System Manufacturer String
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemManufacturer|"Intel Corp."|VOID*|0xA000003A
+  # System Product String
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemProductName|"QUARK"|VOID*|0xA000003B
+  # System Version
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemVersion|"1.0"|VOID*|0xA000003C
+  # System SerialNumber String
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSerialNumber|"Unknown"|VOID*|0xA000003D
+  # System UUID
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemUuid|{0x23, 0xef, 0xff, 0x13,0x54, 0x86, 0xda, 0x46, 0xa4, 0x7, 0x39, 0xc9, 0x12, 0x2, 0xd3, 0x56}|VOID*|0xA000003E
+  # Manufacturer String
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSKUNumber|"System SKUNumber"|VOID*|0xA000003F
+  # System Family String
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemFamily|"X1000"|VOID*|0xA0000040
+
+  # Base Board (or Module) Information (Type 2), Section 3.3.3
+  # Board Manufacturer String
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBoardManufacturer|"Intel Corp."|VOID*|0xA0000041
+  # Board Product Name| String
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBoardProductName|"QUARK"|VOID*|0xA0000042
+  # Board Version String
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBoardVersion|"FAB-D"|VOID*|0xA0000043
+  # Board Serial Number
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBoardSerialNumber|"3"|VOID*|0xA0000044
+  # System Enclosure or Chassis(Type 3) Section 3.3.4
+  # Chassis Manufacturer String
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisManufacturer|"Chassis Manufacturer"|VOID*|0xA0000045
+  # ChassisVersion
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisVersion|"Chassis Version"|VOID*|0xA0000046
+  # Chassis SerialNumber String
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisSerialNumber|"Chassis Serial Number"|VOID*|0xA0000047
+  # Chassis Asset Tag
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisAssetTag|"Chassis Asset Tag"|VOID*|0xA0000051
+  # Chassis Type
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisType|0x00000003|UINT8|0xA0000048
+  # Identifies the state of the enclosure when it was last booted. See 3.3.4.2 for definitions.
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisBootupState|0x03|UINT8|0xA0000049
+  # Identifies the state of the enclosures power supply (or supplies) when last booted. See 3.3.4.2 for definitions.
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisPowerSupplyState|0x03|UINT8|0xA000004A
+  # Identifies the enclosures physical security status when last booted. See 3.3.4.3 for definitions.
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisSecurityState|0x01|UINT8|0xA000004B
+  # Contains OEM- or BIOS vendor-specific information.
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisOemDefined|0x0|UINT32|0xA000004C
+  # The height of the enclosure, in 'U's. A U is a standard unit of measure for the height of a rack or rack-mountable component
+  # and is equal to 1.75 inches or 4.445 cm. A value of 00h indicates that the enclosure height is unspecified.
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisHeight|0x0|UINT8|0xA000004D
+  # Identifies the number of power cords associated with the enclosure or chassis. A value of 00h indicates that the number is unspecified.
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisNumberPowerCords|0x0|UINT8|0xA000004E
+  # Identifies the number of Contained Element records that follow, in the range 0 to 255.
+  # Each Contained Element group comprises m bytes, as specified by the Contained Element Record Length field that follows.
+  # If no Contained Elements are included, this field is set to 0.
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisElementCount|0x0|UINT8|0xA000004F
+  # Identifies the byte length of each Contained Element record that follow, in the range 0 to 255.
+  # If no Contained Elements are included, this field is set to 0. For v2.3.2 and later of this specification,
+  # this field is set to at least 03h when Contained Elements are specified.
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisElementRecordLength|0x0|UINT8|0xA0000050
+
+  # Defines the number of connectors existent on the board
+  # The valid range is between 0 and 16
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSConnectorNumber|16|UINT8|0xA0000060
+
+  # Defines the designator of port1 internal connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort1InternalConnectorDesignator|"X14 "|VOID*|0xA0000061
+  # Defines the designator of port1 external connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort1ExternalConnectorDesignator|"Keyboard"|VOID*|0xA0000062
+  # Defines the type of port1 internal connector
+  # The valid range is between 0 to 0xFF, and 0 here means EfiPortConnectorTypeNone
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort1InternalConnectorType|0x0F|UINT8|0xA0000063
+  # Defines the type of port1 external connector
+  # The valid range is between 0 to 0xFF, and 0x0F here means EfiPortConnectorTypePS2
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort1ExternalConnectorType|0x0F|UINT8|0xA0000064
+  # Defines the type of port1
+  # The valid range is between 0 to 0xFF, and 0x0D here means EfiPortTypeKeyboard
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort1Type|0x0D|UINT8|0xA0000065
+
+  # Defines the designator of port2 internal connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort2InternalConnectorDesignator|"X15 "|VOID*|0xA0000066
+  # Defines the designator of port2 external connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort2ExternalConnectorDesignator|"Mouse"|VOID*|0xA0000067
+  # Defines the type of port2 internal connector
+  # The valid range is between 0 to 0xFF, and 0 here means EfiPortConnectorTypeNone
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort2InternalConnectorType|0x0F|UINT8|0xA0000068
+  # Defines the type of port2 external connector
+  # The valid range is between 0 to 0xFF, and 0x0F here means EfiPortConnectorTypePS2
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort2ExternalConnectorType|0x0F|UINT8|0xA0000069
+  # Defines the type of port2
+  # The valid range is between 0 to 0xFF, and 0x0E here means EfiPortTypeMouse
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort2Type|0x0E|UINT8|0xA000006A
+
+  # Defines the designator of port3 internal connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort3InternalConnectorDesignator|"X16 "|VOID*|0xA000006B
+  # Defines the designator of port3 external connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort3ExternalConnectorDesignator|"COM 1"|VOID*|0xA000006C
+  # Defines the type of port3 internal connector
+  # The valid range is between 0 to 0xFF, and 0xFF here means EfiPortConnectorTypeOther
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort3InternalConnectorType|0xFF|UINT8|0xA000006D
+  # Defines the type of port3 external connector
+  # The valid range is between 0 to 0xFF, and 0 here means EfiPortConnectorTypeNone
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort3ExternalConnectorType|0x0|UINT8|0xA000006E
+  # Defines the type of port3
+  # The valid range is between 0 to 0xFF, and 0x09 here means EfiPortTypeSerial16550ACompatible
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort3Type|0x09|UINT8|0xA000006F
+
+  # Defines the designator of port4 internal connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort4InternalConnectorDesignator|"X17 "|VOID*|0xA0000070
+  # Defines the designator of port4 external connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort4ExternalConnectorDesignator|"COM 2"|VOID*|0xA0000071
+  # Defines the type of port4 internal connector
+  # The valid range is between 0 to 0xFF, and 0xFF here means EfiPortConnectorTypeOther
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort4InternalConnectorType|0xFF|UINT8|0xA0000072
+  # Defines the type of port4 external connector
+  # The valid range is between 0 to 0xFF, and 0 here means EfiPortConnectorTypeNone
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort4ExternalConnectorType|0x0|UINT8|0xA0000073
+  # Defines the type of port4
+  # The valid range is between 0 to 0xFF, and 0x09 here means EfiPortTypeSerial16550ACompatible
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort4Type|0x09|UINT8|0xA0000074
+
+  # Defines the designator of port5 internal connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort5InternalConnectorDesignator|"X18 "|VOID*|0xA0000075
+  # Defines the designator of port5 external connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort5ExternalConnectorDesignator|"COM 3"|VOID*|0xA0000076
+  # Defines the type of port5 internal connector
+  # The valid range is between 0 to 0xFF, and 0xFF here means EfiPortConnectorTypeOther
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort5InternalConnectorType|0xFF|UINT8|0xA0000077
+  # Defines the type of port5 external connector
+  # The valid range is between 0 to 0xFF, and 0 here means EfiPortConnectorTypeNone
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort5ExternalConnectorType|0x0|UINT8|0xA0000078
+  # Defines the type of port5
+  # The valid range is between 0 to 0xFF, and 0x09 here means EfiPortTypeSerial16550ACompatible
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort5Type|0x09|UINT8|0xA0000079
+
+  # Defines the designator of port6 internal connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort6InternalConnectorDesignator|"X19 "|VOID*|0xA000007A
+  # Defines the designator of port6 external connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort6ExternalConnectorDesignator|"COM 4"|VOID*|0xA000007B
+  # Defines the type of port6 internal connector
+  # The valid range is between 0 to 0xFF, and 0xFF here means EfiPortConnectorTypeOther
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort6InternalConnectorType|0xFF|UINT8|0xA000007C
+  # Defines the type of port6 external connector
+  # The valid range is between 0 to 0xFF, and 0 here means EfiPortConnectorTypeNone
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort6ExternalConnectorType|0x0|UINT8|0xA000007D
+  # Defines the type of port6
+  # The valid range is between 0 to 0xFF, and 0x09 here means EfiPortTypeSerial16550ACompatible
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort6Type|0x09|UINT8|0xA000007E
+
+  # Defines the designator of port7 internal connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort7InternalConnectorDesignator|"J4A2"|VOID*|0xA000007F
+  # Defines the designator of port7 external connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort7ExternalConnectorDesignator|"LPT 1"|VOID*|0xA0000080
+  # Defines the type of port7 internal connector
+  # The valid range is between 0 to 0xFF, and 0 here means EfiPortConnectorTypeNone
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort7InternalConnectorType|0x0|UINT8|0xA0000081
+  # Defines the type of port7 external connector
+  # The valid range is between 0 to 0xFF, and 0x12 here means EfiPortConnectorTypeDB25Male
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort7ExternalConnectorType|0x04|UINT8|0xA0000082
+  # Defines the type of port7
+  # The valid range is between 0 to 0xFF, and 0x10 here means EfiPortTypeEcpEpp
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort7Type|0x05|UINT8|0xA0000083
+
+  # Defines the designator of port8 internal connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort8InternalConnectorDesignator|"X20 "|VOID*|0xA0000084
+  # Defines the designator of port8 external connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort8ExternalConnectorDesignator|"USB1"|VOID*|0xA0000085
+  # Defines the type of port8 internal connector
+  # The valid range is between 0 to 0xFF, and 0 here means EfiPortConnectorTypeNone
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort8InternalConnectorType|0x0|UINT8|0xA0000086
+  # Defines the type of port8 external connector
+  # The valid range is between 0 to 0xFF, and 0x12 here means EfiPortConnectorTypeUsb
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort8ExternalConnectorType|0x12|UINT8|0xA0000087
+  # Defines the type of port8
+  # The valid range is between 0 to 0xFF, and 0x10 here means EfiPortTypeUsb
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort8Type|0x10|UINT8|0xA0000088
+
+  # Defines the designator of port9 internal connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort9InternalConnectorDesignator|"X21 "|VOID*|0xA0000089
+  # Defines the designator of port9 external connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort9ExternalConnectorDesignator|"USB2"|VOID*|0xA000008A
+  # Defines the type of port9 internal connector
+  # The valid range is between 0 to 0xFF, and 0 here means EfiPortConnectorTypeNone
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort9InternalConnectorType|0x0|UINT8|0xA000008B
+  # Defines the type of port9 external connector
+  # The valid range is between 0 to 0xFF, and 0x12 here means EfiPortConnectorTypeUsb
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort9ExternalConnectorType|0x12|UINT8|0xA000008C
+  # Defines the type of port9
+  # The valid range is between 0 to 0xFF, and 0x10 here means EfiPortTypeUsb
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort9Type|0x10|UINT8|0xA000008D
+
+  # Defines the designator of port10 internal connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort10InternalConnectorDesignator|"X22 "|VOID*|0xA000008E
+  # Defines the designator of port10 external connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort10ExternalConnectorDesignator|"USB3"|VOID*|0xA000008F
+  # Defines the type of port10 internal connector
+  # The valid range is between 0 to 0xFF, and 0 here means EfiPortConnectorTypeNone
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort10InternalConnectorType|0x0|UINT8|0xA0000090
+  # Defines the type of port10 external connector
+  # The valid range is between 0 to 0xFF, and 0x12 here means EfiPortConnectorTypeUsb
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort10ExternalConnectorType|0x12|UINT8|0xA0000091
+  # Defines the type of port10
+  # The valid range is between 0 to 0xFF, and 0x10 here means EfiPortTypeUsb
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort10Type|0x10|UINT8|0xA0000092
+
+  # Defines the designator of port11 internal connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort11InternalConnectorDesignator|"X23 "|VOID*|0xA0000093
+  # Defines the designator of port11 external connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort11ExternalConnectorDesignator|"USB4"|VOID*|0xA0000094
+  # Defines the type of port11 internal connector
+  # The valid range is between 0 to 0xFF, and 0 here means EfiPortConnectorTypeNone
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort11InternalConnectorType|0x0|UINT8|0xA0000095
+  # Defines the type of port11 external connector
+  # The valid range is between 0 to 0xFF, and 0x12 here means EfiPortConnectorTypeUsb
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort11ExternalConnectorType|0x12|UINT8|0xA0000096
+  # Defines the type of port11
+  # The valid range is between 0 to 0xFF, and 0x10 here means EfiPortTypeUsb
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort11Type|0x10|UINT8|0xA0000097
+
+  # Defines the designator of port12 internal connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort12InternalConnectorDesignator|"X28 "|VOID*|0xA0000098
+  # Defines the designator of port12 external connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort12ExternalConnectorDesignator|"RJ-45 Type"|VOID*|0xA0000099
+  # Defines the type of port12 internal connector
+  # The valid range is between 0 to 0xFF, and 0 here means EfiPortConnectorTypeNone
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort12InternalConnectorType|0x0|UINT8|0xA000009A
+  # Defines the type of port12 external connector
+  # The valid range is between 0 to 0xFF, and 0x0B here means EfiPortConnectorTypeRJ45
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort12ExternalConnectorType|0x0B|UINT8|0xA000009B
+  # Defines the type of port12
+  # The valid range is between 0 to 0xFF, and 0x1F here means EfiPortTypeNetworkPort
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort12Type|0x1F|UINT8|0xA000009C
+
+  # Defines the designator of port13 internal connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort13InternalConnectorDesignator|"J1G1"|VOID*|0xA000009D
+  # Defines the designator of port13 external connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort13ExternalConnectorDesignator|"Floppy"|VOID*|0xA000009E
+  # Defines the type of port13 internal connector
+  # The valid range is between 0 to 0xFF, and 0x16 here means EfiPortConnectorTypeOnboardFloppy
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort13InternalConnectorType|0x17|UINT8|0xA000009F
+  # Defines the type of port13 external connector
+  # The valid range is between 0 to 0xFF, and 0 here means EfiPortConnectorTypeNone
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort13ExternalConnectorType|0x0|UINT8|0xA00000A0
+  # Defines the type of port13
+  # The valid range is between 0 to 0xFF, and 0xFF here means EfiPortTypeOther
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort13Type|0xFF|UINT8|0xA00000A1
+
+  # Defines the designator of port14 internal connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort14InternalConnectorDesignator|"J2H2"|VOID*|0xA00000A2
+  # Defines the designator of port14 external connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort14ExternalConnectorDesignator|"IDE"|VOID*|0xA00000A3
+  # Defines the type of port14 internal connector
+  # The valid range is between 0 to 0xFF, and 0x16 here means EfiPortConnectorTypeOnboardIde
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort14InternalConnectorType|0x16|UINT8|0xA00000A4
+  # Defines the type of port14 external connector
+  # The valid range is between 0 to 0xFF, and 0 here means EfiPortConnectorTypeNone
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort14ExternalConnectorType|0x0|UINT8|0xA00000A5
+  # Defines the type of port14
+  # The valid range is between 0 to 0xFF, and 0xFF here means EfiPortTypeOther
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort14Type|0xFF|UINT8|0xA00000A6
+
+  # Defines the designator of port15 internal connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort15InternalConnectorDesignator|"X29 "|VOID*|0xA00000A7
+  # Defines the designator of port15 external connector
+
+  # Defines the type of port15 internal connector
+  # The valid range is between 0 to 0xFF, and 0x16 here means EfiPortConnectorTypeOnboardIde
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort15InternalConnectorType|0x16|UINT8|0xA00000A9
+  # Defines the type of port15 external connector
+  # The valid range is between 0 to 0xFF, and 0 here means EfiPortConnectorTypeNone
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort15ExternalConnectorType|0x0|UINT8|0xA00000AA
+  # Defines the type of port15
+  # The valid range is between 0 to 0xFF, and 0xFF here means EfiPortTypeOther
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort15Type|0xFF|UINT8|0xA00000AB
+
+  # Defines the designator of port16 internal connector
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort16InternalConnectorDesignator|"X30 "|VOID*|0xA00000AC
+  # Defines the designator of port16 external connector
+
+  # Defines the type of port16 internal connector
+  # The valid range is between 0 to 0xFF, and 0x16 here means EfiPortConnectorTypeOnboardIde
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort16InternalConnectorType|0x16|UINT8|0xA00000AE
+  # Defines the type of port16 external connector
+  # The valid range is between 0 to 0xFF, and 0 here means EfiPortConnectorTypeNone
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort16ExternalConnectorType|0x0|UINT8|0xA00000AF
+  # Defines the type of port16
+  # The valid range is between 0 to 0xFF, and 0xFF here means EfiPortTypeOther
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort16Type|0xFF|UINT8|0xA00000B0
+
+  # Defines the number of the slots existent on board
+  # The valid range is between 0 and 14
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlotNumber|5|UINT8|0xA000023F
+  # Defines the designation of system slot1
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot1Designation|"PCI SLOT1"|VOID*|0xA0000240
+  # Defines the type of system slot1
+  # The valid range is between 0x01 to 0xA5, and 0x06 here means EfiSlotTypePci
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot1Type|0x6|UINT8|0xA0000241
+  # Defines the data bus width of system slot1
+  # The valid range is between 0x01 to 0x07, and 0x05 here means EfiSlotDataBusWidth32Bit
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot1DataBusWidth|0x5|UINT8|0xA0000242
+  # Defines the usage of system slot1
+  # The valid range is between 0x01 to 0x04, and 0x03 here means EfiSlotUsageAvailable
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot1Usage|0x3|UINT8|0xA0000243
+  # Defines the length of system slot1
+  # The valid range is between 0x01 to 0x04, and 0x04 here means EfiSlotLengthLong
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot1Length|0x4|UINT8|0xA0000244
+  # Defines the ID of system slot1, a number of UINT16
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot1Id|0x01|UINT16|0xA0000245
+  # Defines the characteristics of system slot1 , a bit mask of EFI_MISC_SLOT_CHARACTERISTICS
+  # typedef struct {
+  #   UINT32  CharacteristicsUnknown  :1;
+  #   UINT32  Provides50Volts         :1;
+  #   UINT32  Provides33Volts         :1;
+  #   UINT32  SharedSlot              :1;
+  #   UINT32  PcCard16Supported       :1;
+  #   UINT32  CardBusSupported        :1;
+  #   UINT32  ZoomVideoSupported      :1;
+  #   UINT32  ModemRingResumeSupported:1;
+  #   UINT32  PmeSignalSupported      :1;
+  #   UINT32  HotPlugDevicesSupported :1;
+  #   UINT32  SmbusSignalSupported    :1;
+  #   UINT32  Reserved                :21;
+  # } EFI_MISC_SLOT_CHARACTERISTICS;
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot1Characteristics|0x504|UINT32|0xA0000246
+
+  # Defines the designation of system slot2
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot2Designation|"PCI-Express 1"|VOID*|0xA0000247
+
+  # Defines the type of system slot2
+  # The valid range is between 0x01 to 0xA5, and 0x06 here means EfiSlotTypePci
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot2Type|0xA5|UINT8|0xA0000248
+  # Defines the data bus width of system slot2
+  # The valid range is between 0x01 to 0x07, and 0x05 here means EfiSlotDataBusWidth32Bit
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot2DataBusWidth|0x5|UINT8|0xA0000249
+  # Defines the usage of system slot2
+  # The valid range is between 0x01 to 0x04, and 0x03 here means EfiSlotUsageAvailable
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot2Usage|0x3|UINT8|0xA000024A
+  # Defines the length of system slot2
+  # The valid range is between 0x01 to 0x04, and 0x04 here means EfiSlotLengthLong
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot2Length|0x4|UINT8|0xA000024B
+  # Defines the ID of system slot2, a number of UINT16
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot2Id|0x02|UINT16|0xA000024C
+  # Defines the characteristics of system slot2 , a bit mask of EFI_MISC_SLOT_CHARACTERISTICS
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot2Characteristics|0x504|UINT32|0xA000024D
+
+  # Defines the designation of system slot3
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot3Designation|"PCI-Express 2"|VOID*|0xA000024E
+  # Defines the type of system slot3
+  # The valid range is between 0x01 to 0xA5, and 0x06 here means EfiSlotTypePci
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot3Type|0xA5|UINT8|0xA000024F
+  # Defines the data bus width of system slot3
+  # The valid range is between 0x01 to 0x07, and 0x05 here means EfiSlotDataBusWidth32Bit
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot3DataBusWidth|0x5|UINT8|0xA0000250
+  # Defines the usage of system slot3
+  # The valid range is between 0x01 to 0x04, and 0x03 here means EfiSlotUsageAvailable
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot3Usage|0x3|UINT8|0xA0000251
+  # Defines the length of system slot3
+  # The valid range is between 0x01 to 0x04, and 0x04 here means EfiSlotLengthLong
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot3Length|0x4|UINT8|0xA0000252
+  # Defines the ID of system slot3, a number of UINT16
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot3Id|0x03|UINT16|0xA0000253
+  # Defines the characteristics of system slot3 , a bit mask of EFI_MISC_SLOT_CHARACTERISTICS
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot3Characteristics|0x504|UINT32|0xA000254
+
+  # Defines the designation of system slot4
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot4Designation|"PCI-Express 3"|VOID*|0xA0000255
+  # Defines the type of system slot4
+  # The valid range is between 0x01 to 0xA5, and 0xA5 here means EfiSlotTypePciExpress
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot4Type|0xA5|UINT8|0xA0000256
+  # Defines the data bus width of system slot4
+  # The valid range is between 0x01 to 0x07, and 0x05 here means EfiSlotDataBusWidth32Bit
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot4DataBusWidth|0x5|UINT8|0xA0000257
+  # Defines the usage of system slot4
+  # The valid range is between 0x01 to 0x04, and 0x03 here means EfiSlotUsageAvailable
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot4Usage|0x3|UINT8|0xA0000258
+  # Defines the length of system slot4
+  # The valid range is between 0x01 to 0x04, and 0x04 here means EfiSlotLengthLong
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot4Length|0x4|UINT8|0xA0000259
+  # Defines the ID of system slot4, a number of UINT16
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot4Id|0x04|UINT16|0xA0000260
+  # Defines the characteristics of system slot4 , a bit mask of EFI_MISC_SLOT_CHARACTERISTICS
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot4Characteristics|0x504|UINT32|0xA0000261
+
+  # Defines the designation of system slot5
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot5Designation|"Mini PCI-E"|VOID*|0xA0000262
+  # Defines the type of system slot5
+  # The valid range is between 0x01 to 0xA5, and 0xA5 here means EfiSlotTypePciExpress
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot5Type|0xA5|UINT8|0xA0000263
+  # Defines the data bus width of system slot5
+  # The valid range is between 0x01 to 0x07, and 0x05 here means EfiSlotDataBusWidth32Bit
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot5DataBusWidth|0x5|UINT8|0xA0000264
+  # Defines the usage of system slot5
+  # The valid range is between 0x01 to 0x04, and 0x03 here means EfiSlotUsageAvailable
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot5Usage|0x3|UINT8|0xA0000265
+  # Defines the length of system slot5
+  # The valid range is between 0x01 to 0x04, and 0x04 here means EfiSlotLengthLong
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot5Length|0x4|UINT8|0xA0000266
+  # Defines the ID of system slot5, a number of UINT16
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot5Id|0x05|UINT16|0xA0000267
+  # Defines the characteristics of system slot5 , a bit mask of EFI_MISC_SLOT_CHARACTERISTICS
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot5Characteristics|0x504|UINT32|0xA0000268
+
+  # Defines the designation of system slot6
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot6Designation|"NONE"|VOID*|0xA0000269
+  # Defines the type of system slot6
+  # The valid range is between 0x01 to 0xA5, and 0x02 here means EfiSlotTypeUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot6Type|0x2|UINT8|0xA000026A
+  # Defines the data bus width of system slot6
+  # The valid range is between 0x01 to 0x07, and 0x02 here means EfiSlotDataBusWidthUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot6DataBusWidth|0x2|UINT8|0xA000026B
+  # Defines the usage of system slot6
+  # The valid range is between 0x01 to 0x04, and 0x02 here means EfiSlotUsageUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot6Usage|0x2|UINT8|0xA000026C
+  # Defines the length of system slot6
+  # The valid range is between 0x01 to 0x04, and 0x02 here means EfiSlotLengthUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot6Length|0x2|UINT8|0xA000026D
+  # Defines the ID of system slot6, a number of UINT16
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot6Id|0x0|UINT16|0xA000026E
+  # Defines the characteristics of system slot6 , a bit mask of EFI_MISC_SLOT_CHARACTERISTICS
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot6Characteristics|0x0|UINT32|0xA000026F
+
+  # Defines the designation of system slot7
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot7Designation|"NONE"|VOID*|0xA0000270
+  # Defines the type of system slot7
+  # The valid range is between 0x01 to 0xA5, and 0x02 here means EfiSlotTypeUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot7Type|0x2|UINT8|0xA0000271
+  # Defines the data bus width of system slot7
+  # The valid range is between 0x01 to 0x07, and 0x02 here means EfiSlotDataBusWidthUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot7DataBusWidth|0x2|UINT8|0xA0000272
+  # Defines the usage of system slot7
+  # The valid range is between 0x01 to 0x04, and 0x02 here means EfiSlotUsageUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot7Usage|0x2|UINT8|0xA0000273
+  # Defines the length of system slot7
+  # The valid range is between 0x01 to 0x04, and 0x02 here means EfiSlotLengthUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot7Length|0x2|UINT8|0xA0000274
+  # Defines the ID of system slot7, a number of UINT16
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot7Id|0x0|UINT16|0xA0000275
+  # Defines the characteristics of system slot7 , a bit mask of EFI_MISC_SLOT_CHARACTERISTICS
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot7Characteristics|0x0|UINT32|0xA0000276
+
+  # Defines the designation of system slot8
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot8Designation|"NONE"|VOID*|0xA0000277
+  # Defines the type of system slot8
+  # The valid range is between 0x01 to 0xA5, and 0x02 here means EfiSlotTypeUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot8Type|0x2|UINT8|0xA0000278
+  # Defines the data bus width of system slot8
+  # The valid range is between 0x01 to 0x07, and 0x02 here means EfiSlotDataBusWidthUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot8DataBusWidth|0x2|UINT8|0xA0000279
+  # Defines the usage of system slot8
+  # The valid range is between 0x01 to 0x04, and 0x02 here means EfiSlotUsageUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot8Usage|0x2|UINT8|0xA000027A
+  # Defines the length of system slot8
+  # The valid range is between 0x01 to 0x04, and 0x02 here means EfiSlotLengthUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot8Length|0x2|UINT8|0xA000027B
+  # Defines the ID of system slot8, a number of UINT16
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot8Id|0x0|UINT16|0xA000027C
+  # Defines the characteristics of system slot8 , a bit mask of EFI_MISC_SLOT_CHARACTERISTICS
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot8Characteristics|0x0|UINT32|0xA000027D
+
+  # Defines the designation of system slot9
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot9Designation|"NONE"|VOID*|0xA000027E
+  # Defines the type of system slot9
+  # The valid range is between 0x01 to 0xA5, and 0x02 here means EfiSlotTypeUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot9Type|0x2|UINT8|0xA000027F
+  # Defines the data bus width of system slot9
+  # The valid range is between 0x01 to 0x07, and 0x02 here means EfiSlotDataBusWidthUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot9DataBusWidth|0x2|UINT8|0xA0000280
+  # Defines the usage of system slot9
+  # The valid range is between 0x01 to 0x04, and 0x02 here means EfiSlotUsageUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot9Usage|0x2|UINT8|0xA0000281
+  # Defines the length of system slot9
+  # The valid range is between 0x01 to 0x04, and 0x02 here means EfiSlotLengthUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot9Length|0x2|UINT8|0xA0000282
+  # Defines the ID of system slot9, a number of UINT16
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot9Id|0x0|UINT16|0xA0000283
+  # Defines the characteristics of system slot9 , a bit mask of EFI_MISC_SLOT_CHARACTERISTICS
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot9Characteristics|0x0|UINT32|0xA0000284
+
+  # Defines the designation of system slot10
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot10Designation|"None"|VOID*|0xA0000285
+  # Defines the type of system slot10
+  # The valid range is between 0x01 to 0xA5, and 0x02 here means EfiSlotTypeUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot10Type|0x2|UINT8|0xA0000286
+  # Defines the data bus width of system slot10
+  # The valid range is between 0x01 to 0x07, and 0x02 here means EfiSlotDataBusWidthUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot10DataBusWidth|0x2|UINT8|0xA0000287
+  # Defines the usage of system slot10
+  # The valid range is between 0x01 to 0x04, and 0x02 here means EfiSlotUsageUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot10Usage|0x2|UINT8|0xA0000288
+  # Defines the length of system slot10
+  # The valid range is between 0x01 to 0x04, and 0x02 here means EfiSlotLengthUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot10Length|0x2|UINT8|0xA0000289
+  # Defines the ID of system slot10, a number of UINT16
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot10Id|0x0|UINT16|0xA000028A
+  # Defines the characteristics of system slot10 , a bit mask of EFI_MISC_SLOT_CHARACTERISTICS
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot10Characteristics|0x0|UINT32|0xA000028B
+
+  # Defines the designation of system slot11
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot11Designation|"None"|VOID*|0xA000028C
+  # Defines the type of system slot11
+  # The valid range is between 0x01 to 0xA5, and 0x02 here means EfiSlotTypeUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot11Type|0x2|UINT8|0xA000028D
+  # Defines the data bus width of system slot11
+  # The valid range is between 0x01 to 0x07, and 0x02 here means EfiSlotDataBusWidthUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot11DataBusWidth|0x2|UINT8|0xA000028E
+  # Defines the usage of system slot11
+  # The valid range is between 0x01 to 0x04, and 0x02 here means EfiSlotUsageUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot11Usage|0x2|UINT8|0xA000028F
+  # Defines the length of system slot11
+  # The valid range is between 0x01 to 0x04, and 0x02 here means EfiSlotLengthUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot11Length|0x2|UINT8|0xA0000290
+  # Defines the ID of system slot11, a number of UINT16
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot11Id|0x0|UINT16|0xA00000EE
+  # Defines the characteristics of system slot11 , a bit mask of EFI_MISC_SLOT_CHARACTERISTICS
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot11Characteristics|0x0|UINT32|0xA0000291
+
+  # Defines the designation of system slot12
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot12Designation|"None"|VOID*|0xA0000292
+  # Defines the type of system slot12
+  # The valid range is between 0x01 to 0xA5, and 0x02 here means EfiSlotTypeUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot12Type|0x2|UINT8|0xA0000293
+  # Defines the data bus width of system slot12
+  # The valid range is between 0x01 to 0x07, and 0x02 here means EfiSlotDataBusWidthUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot12DataBusWidth|0x2|UINT8|0xA0000294
+  # Defines the usage of system slot12
+  # The valid range is between 0x01 to 0x04, and 0x02 here means EfiSlotUsageUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot12Usage|0x2|UINT8|0xA0000295
+  # Defines the length of system slot12
+  # The valid range is between 0x01 to 0x04, and 0x02 here means EfiSlotLengthUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot12Length|0x2|UINT8|0xA0000296
+  # Defines the ID of system slot12, a number of UINT16
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot12Id|0x0|UINT16|0xA0000297
+  # Defines the characteristics of system slot12 , a bit mask of EFI_MISC_SLOT_CHARACTERISTICS
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot12Characteristics|0x0|UINT32|0xA0000298
+
+  # Defines the designation of system slot13
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot13Designation|"None"|VOID*|0xA0000299
+  # Defines the type of system slot13
+  # The valid range is between 0x01 to 0xA5, and 0x02 here means EfiSlotTypeUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot13Type|0x2|UINT8|0xA000029A
+  # Defines the data bus width of system slot13
+  # The valid range is between 0x01 to 0x07, and 0x02 here means EfiSlotDataBusWidthUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot13DataBusWidth|0x2|UINT8|0xA000029B
+  # Defines the usage of system slot13
+  # The valid range is between 0x01 to 0x04, and 0x02 here means EfiSlotUsageUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot13Usage|0x2|UINT8|0xA000029C
+  # Defines the length of system slot13
+  # The valid range is between 0x01 to 0x04, and 0x02 here means EfiSlotLengthUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot13Length|0x2|UINT8|0xA000029D
+  # Defines the ID of system slot13, a number of UINT16
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot13Id|0x0|UINT16|0xA000029E
+  # Defines the characteristics of system slot13 , a bit mask of EFI_MISC_SLOT_CHARACTERISTICS
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot13Characteristics|0x0|UINT32|0xA000029F
+
+  # Defines the designation of system slot14
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot14Designation|"None"|VOID*|0xA00002A0
+  # Defines the type of system slot14
+  # The valid range is between 0x01 to 0xA5, and 0x02 here means EfiSlotTypeUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot14Type|0x2|UINT8|0xA00002A1
+  # Defines the data bus width of system slot14
+  # The valid range is between 0x01 to 0x07, and 0x02 here means EfiSlotDataBusWidthUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot14DataBusWidth|0x2|UINT8|0xA00002A2
+  # Defines the usage of system slot14
+  # The valid range is between 0x01 to 0x04, and 0x02 here means EfiSlotUsageUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot14Usage|0x2|UINT8|0xA00002A3
+  # Defines the length of system slot14
+  # The valid range is between 0x01 to 0x04, and 0x02 here means EfiSlotLengthUnknown
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot14Length|0x2|UINT8|0xA00002A4
+  # Defines the ID of system slot14, a number of UINT16
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot14Id|0x0|UINT16|0xA00002A5
+  # Defines the characteristics of system slot14 , a bit mask of EFI_MISC_SLOT_CHARACTERISTICS
+  gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot14Characteristics|0x0|UINT32|0xA00002A6
+
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvPayloadBase|0xFFC00400|UINT32|0xA00002A7
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvPayloadSize|0x000F0000|UINT32|0xA00002A8
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvMainBase|0xFFD00400|UINT32|0xA00002A9
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvMainSize|0x000D0000|UINT32|0xA00002AA
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoveryBase|0xFFEC0400|UINT32|0xA00002AB
+  gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoverySize|0x0003F000|UINT32|0xA00002AC
+
+[PcdsDynamic, PcdsDynamicEx]
+  ## Provides the ability to enable the Fast Boot feature of the BIOS.  This
+  #  enables the system to boot faster but may only enumerate the hardware
+  #  that is required to boot the system.<BR>
+  #
+  # @Prompt Fast Boot Support
+  #
+  gQuarkPlatformTokenSpaceGuid.PcdEnableFastBoot|FALSE|BOOLEAN|0xB000004
+
+  ## Determines if the user is physically present.  This information is collected and shared
+  #  with all other modules using a dynamic PCD.<BR>
+  #
+  # @Prompt The User is Physically Present
+  #
+  gQuarkPlatformTokenSpaceGuid.PcdUserIsPhysicallyPresent|FALSE|BOOLEAN|0xB000006
+
+  ## The Quark SOC X1000 Based Platform Type.<BR>
+  #   0x0000 - Unknown<BR>
+  #   0x0001 - Quark Emulation<BR>
+  #   0x0002 - ClantonPeak SVP<BR>
+  #   0x0003 - KipsBay<BR>
+  #   0x0004 - CrossHill<BR>
+  #   0x0005 - ClantonHill<BR>
+  #   0x0006 - Galileo Gen 1<BR>
+  #   0x0007 - Reserved<BR>
+  #   0x0008 - Galileo Gen 2<BR>
+  #
+  # @Prompt The Quark SOC X1000 Based Platform Type
+  #
+  gQuarkPlatformTokenSpaceGuid.PcdPlatformType|0x0008|UINT16|0xB000007
+
+  ## The Quark SOC X1000 Based Platform Type Name.<BR>
+  #
+  # @Prompt The Quark SOC X1000 Based Platform Type Name
+  #
+  gQuarkPlatformTokenSpaceGuid.PcdPlatformTypeName|L"GalileoGen2"|VOID*|0xB000008
+
+  ## The size, in bytes, of the SPI FLASH part attached to Quark SOC X1000
+  #
+  # @Prompt The SPI FALSH Part Size
+  #
+  gQuarkPlatformTokenSpaceGuid.PcdSpiFlashDeviceSize|0|UINT32|0xB000009
diff --git a/Platform/Intel/QuarkPlatformPkg/Readme.md b/Platform/Intel/QuarkPlatformPkg/Readme.md
new file mode 100644
index 0000000000..126de6937b
--- /dev/null
+++ b/Platform/Intel/QuarkPlatformPkg/Readme.md
@@ -0,0 +1,685 @@
+# **EDK II firmware for Intel(R) Quark SoC X1000 based platforms**
+
+## **Features**
+* UEFI firmware image with ability to enable/disable major features such as
+    - Logging
+    - Source level debug using [Intel(R) UEFI Development Kit Debugger Tool](
+      https://firmware.intel.com/develop/intel-uefi-tools-and-utilities/intel-uefi-development-kit-debugger-tool)
+    - Boot Performance Measurements
+    - UEFI Secure Boot with Physical Presence
+    - TCG Measured Boot using TPM 1.2 hardware devices on I2C bus
+* Minimal firmware image for initial power-on and debug
+* UEFI Shell built into FLASH image
+* UEFI Linux operating system boot support from Micro SD FLASH
+* Hardware Support
+    -  [Intel(R) Quark SoC X1000 CPU](
+       http://www.intel.com/content/www/us/en/embedded/products/quark/quark-x1000-datasheet.html)
+    -  [Intel(R) Galileo Development Board](
+       http://www.intel.com/content/www/us/en/embedded/products/galileo/galileo-g1-datasheet.html)
+    -  [Intel(R) Galileo Gen 2 Development Board](
+       http://www.intel.com/content/www/us/en/embedded/products/galileo/galileo-overview.html)
+    -  HPET Timer
+    -  Real Time Clock
+* Major I/O Subsystems
+    - PCI including support for Mini PCI Express Cards
+    - USB using EHCI and OHCI host controllers
+    - Micro SD FLASH with FAT file system support
+    - Serial UART up to 921600 baud for console, logging, and debug
+* ACPI Tables with ACPI S3 sleep state support
+* SMBIOS Tables
+
+## **Windows Build Instructions**
+
+### Pre-requisites
+
+* GIT client: Available from https://git-scm.com/downloads
+* Microsoft Visual Studio.
+  - Visual Studio 2015 recommended and is used in the examples below.
+* Microsoft Windows Driver Development Kit 3790.1830
+  - http://download.microsoft.com/download/9/0/f/90f019ac-8243-48d3-91cf-81fc4093ecfd/1830_usa_ddk.iso
+  - Mount ISO image
+  - Right click on ```x86\kitsetup.exe``` & choose **Run as administrator**
+  - Install to C:\WINDDK\3790.1830
+  - Uncheck all Component Groups
+  - Expand Build Environment Component
+  - Check Windows Driver Development Kit 16-bit Additional Build Tools
+  - Install
+* ASL compiler: Available from http://www.acpica.org
+  - Install into ```C:\ASL``` to match default tools_def.txt configuration.
+* Python 2.7: Available from http://www.python.org
+
+Create a new directory for an EDK II WORKSPACE.
+
+The code block below shows the GIT clone operations required to pull the EDK II
+source tree and the edk2-non-osi repository that provides a binary file for the
+Quark Remote Management Unit (RMU).
+
+Next it sets environment variables that must be set before running
+```edksetup.bat```. Since content is being pulled from multiple repositories,
+the EDK II [Multiple Workspace](
+https://github.com/tianocore/tianocore.github.io/wiki/Multiple_Workspace)
+feature is used.
+
+Next, the EDK II BaseTools required to build firmware images are built.
+
+Next, the ```edksetup.bat``` file is run to complete the initialization of an
+EDK II build environment.  Two example build commands are shown.  The first one
+in ```QuarkPlatformPlg/Quark.dsc``` builds a full UEFI firmware image that is
+able to boot the built-in UEFI Shell and Linux from a micro SD FLASH card.  The
+second one in ```QuarkPlatformPkg/QuarkMin.dsc``` builds a minimal firmware
+image that is useful for initial power-on and debug of new features.
+
+```cmd
+git clone https://github.com/tianocore/edk2.git
+git clone https://github.com/tianocore/edk2-non-osi.git
+
+set PYTHON_HOME=c:\Python27
+set WORKSPACE=%CD%
+set PACKAGES_PATH=%WORKSPACE%\edk2;%WORKSPACE%\edk2-non-osi\Silicon\Intel
+set EDK_TOOLS_PATH=%WORKSPACE%\edk2\BaseTools
+cd %WORKSPACE%\edk2
+
+BaseTools\toolsetup.bat Rebuild
+
+edksetup.bat Rebuild
+
+build -a IA32 -t VS2015x86 -p QuarkPlatformPkg/Quark.dsc
+build -a IA32 -t VS2015x86 -p QuarkPlatformPkg/QuarkMin.dsc
+```
+
+## **Linux Build Instructions**
+
+### Pre-requisites
+
+* GIT client
+* GCC 4.9 compiler
+* ASL compiler: Available from http://www.acpica.org.
+* Python 2.7
+
+Create a new directory for an EDK II WORKSPACE.
+
+The code block below shows the GIT clone operations required to pull the EDK II
+source tree and the edk2-non-osi repository that provides a binary file for the
+Quark Remote Management Unit (RMU).
+
+Next it sets environment variables that must be set before running
+```edksetup.bat```. Since content is being pulled from multiple repositories,
+the EDK II [Multiple Workspace](
+https://github.com/tianocore/tianocore.github.io/wiki/Multiple_Workspace)
+feature is used.
+
+Next, the EDK II BaseTools required to build firmware images are built.
+
+Next, the ```edksetup.sh``` file is run to complete the initialization of an
+EDK II build environment.  Two example build commands are shown.  The first one
+in ```QuarkPlatformPlg/Quark.dsc``` builds a full UEFI firmware image that is
+able to boot the built-in UEFI Shell and Linux from a micro SD FLASH card.  The
+second one in ```QuarkPlatformPkg/QuarkMin.dsc``` builds a minimal firmware
+image that is useful for initial power-on and debug of new features.
+
+```sh
+git clone https://github.com/tianocore/edk2.git
+git clone https://github.com/tianocore/edk2-non-osi.git
+
+export WORKSPACE=$PWD
+export PACKAGES_PATH=$WORKSPACE/edk2:$WORKSPACE/edk2-non-osi/Silicon/Intel
+export EDK_TOOLS_PATH=$WORKSPACE/edk2/BaseTools
+cd $WORKSPACE/edk2
+
+make -C BaseTools
+
+. edksetup.sh BaseTools
+
+build -a IA32 -t GCC49 -p QuarkPlatformPkg/Quark.dsc
+build -a IA32 -t GCC49 -p QuarkPlatformPkg/QuarkMin.dsc
+```
+
+## **Build Features**
+
+The table below contains a summary of the build flags to enable or disable
+features on the build command line using ```-D``` flags.
+
+| **Define Name**            | **Default Value** | **Supported Values** |
+| -------------------------- | ----------------- | -------------------- |
+| ```GALILEO```              |              GEN2 | GEN1, GEN2           |
+| ```LOGGING```              |              TRUE | TRUE, FALSE          |
+| ```SOURCE_DEBUG_ENABLE```  |             FALSE | TRUE, FALSE          |
+| ```PERFORMANCE_ENABLE```   |             FALSE | TRUE, FALSE          |
+| ```SECURE_BOOT_ENABLE```   |             FALSE | TRUE, FALSE          |
+| ```MEASURED_BOOT_ENABLE``` |             FALSE | TRUE, FALSE          |
+| ```TPM_12_HARDWARE```      |              NONE | NONE, LPC, ATMEL_I2C, INFINEON_I2C |
+| ```CAPSULE_ENABLE```       |             FALSE | TRUE, FALSE          |
+| ```RECOVERY_ENABLE```      |             FALSE | TRUE, FALSE          |
+
+* ```GALILEO``` - Used to specify the type of Intel(R) Galileo board type.  The
+  default is ```GEN2``` for the [Intel(R) Galileo Gen 2 Development Board](
+  http://www.intel.com/content/www/us/en/embedded/products/galileo/galileo-overview.html).
+  The other supported value is ```GEN1``` for the [Intel(R) Galileo Development Board](
+  http://www.intel.com/content/www/us/en/embedded/products/galileo/galileo-g1-datasheet.html).
+  Add ```-D GALILEO=GEN1``` to the build command for [Intel(R) Galileo Development Board](
+  http://www.intel.com/content/www/us/en/embedded/products/galileo/galileo-g1-datasheet.html).
+
+* ```LOGGING``` - Used to enable/disable logging messages from DEBUG() macros to
+  a serial UART.  The default is TRUE for enabled when the BUILDTARGET is DEBUG
+  (```-b DEBUG```).  The default is FALSE for disabled when the BUILDTARGET is
+  not DEBUG (e.g. ```-b RELEASE```).  Add ```-D LOGGING``` to the build command
+  to force logging enabled.  Add ```-D LOGGING=FALSE``` to force logging
+  disabled.
+
+* ```SOURCE_DEBUG_ENABLE``` - Used to enable/disable source level debug using the
+  [Intel(R) UEFI Development Kit Debugger Tool](
+  https://firmware.intel.com/develop/intel-uefi-tools-and-utilities/intel-uefi-development-kit-debugger-tool).
+  The default is FALSE for disabled.  Add ```-D SOURCE_DEBUG_ENABLE``` to the
+  build command line to enable source level debug.
+
+* ```PERFORMANCE_ENABLE``` - Used to enable/disable boot performance measurement.
+  The default is FALSE for disabled.  Add ```-D PERFORMANCE_ENABLE``` to the
+  build command line to enable boot performance measurement.  When this feature
+  is enabled, both ```LOGGING``` and ```SOURCE_DEBUG_ENABLE``` are automatically
+  disabled so there is not boot time overhead from the serial UART for logging
+  messages or the debug agent.
+
+* ```SECURE_BOOT_ENABLE``` - Used to enable/disable UEFI Secure Boot features.
+  The default is FALSE for disabled.  Add ```-D SECURE_BOOT_ENABLE``` to the
+  build command line to enable UEFI Secure Boot features.
+
+* ```MEASURED_BOOT_ENABLE``` - Used to enable/disable measurement of firmware
+  code and data into a TPM 1.2 hardware device.  The default is FALSE for
+  disabled.  Add ```-D MEASURED_BOOT_ENABLE``` to the build command line to
+  enable UEFI Secure Boot features.
+
+* ```TPM_12_HARDWARE``` - Used to specify the type of TPM 1.2 hardware device
+  that is connected to the Galileo board.  This define is valid if the measure
+  boot feature is enabled using ```-D MEASURED_BOOT_ENABLE```.  The default is
+  NONE for no TPM 1.2 hardware device connected.  Add ```-D TPM_12_HARDWARE=LPC```
+  for a TPM hardware device attached to an LPC bus (not supported on on Intel(R)
+  Quark SoC X1000).  Add ```-D TPM_12_HARDWARE=ATMEL_I2C``` for an
+  [Atmel AT97SC3204T](http://www.atmel.com/devices/AT97SC3204T.aspx) or
+  [Atmel AT97SC3205T](http://www.atmel.com/images/atmel-8883s-tpm-at97sc3205t-datasheet-summary.pdf)
+  attached to the I2C bus of the Galileo Arduino header.  Add
+  ```-D TPM_12_HARDWARE=INFINION_I2C``` for an [Infineon SLB9645](
+  http://www.infineon.com/dgdl/Infineon-TPM+SLB+9645-DS-v01_00-EN.pdf?fileId=5546d4625185e0e201518b83d0c63d7c)
+  attached to the I2C bus of the Galileo Arduino header.  The ATMEL_I2C setting
+  has been tested with the [CryptoShield](https://www.sparkfun.com/products/13183)
+  available from [SparkFun](https://www.sparkfun.com/).
+
+* ```CAPSULE_ENABLE``` - Used to enable/disable capsule update features.
+  The default is FALSE for disabled.  Add ```-D CAPSULE_ENABLE``` to the
+  build command line to enable capsule update features.
+  The build process generate capsule update image - QUARKFIRMWAREUPDATECAPSULEFMPPKCS7.Cap.
+  The user need copy QUARKFIRMWAREUPDATECAPSULEFMPPKCS7.Cap and CapsuleApp.efi
+  to a storage media attached to the Quark Board.
+  Then the user can boot to shell and run ```CapsuleApp QUARKFIRMWAREUPDATECAPSULEFMPPKCS7.Cap```.
+  In next reboot, the system firmware is updated.
+
+* ```RECOVERY_ENABLE``` - Used to enable/disable recovery features.
+  The default is FALSE for disabled.  Add ```-D RECOVERY_ENABLE``` to the
+  build command line to enable recovery features.
+  The build process generates the recovery capsule image - QUARKREC.Cap.
+  Then the user need copy QUARKREC.Cap to a USB KEY, plug the USB KEY to the Quark Board.
+  In next boot, if a user runs ForceRecovery.efi in shell, or if a user presses the RESET button during power on, warm reset or REBOOT,
+  or if the FvMain is corrupted in flash, the system will boot into recovery mode.
+
+### **Example Build Commands**
+
+Default build with logging enabled:
+
+```build -a IA32 -t VS2015x86 -p QuarkPlatformPkg/Quark.dsc```
+
+Release build with logging disabled:
+
+```build -a IA32 -t VS2015x86 -p QuarkPlatformPkg/Quark.dsc -b RELEASE```
+
+Enable source level debugging:
+
+```build -a IA32 -t VS2015x86 -p QuarkPlatformPkg/Quark.dsc -D SOURCE_DEBUG_ENABLE```
+
+Enable boot performance metrics:
+
+```build -a IA32 -t VS2015x86 -p QuarkPlatformPkg/Quark.dsc -D PERFORMANCE_ENABLE```
+
+Enable UEFI Secure Boot features:
+
+```build -a IA32 -t VS2015x86 -p QuarkPlatformPkg/Quark.dsc -D UEFI_SECURE_BOOT```
+
+Enable UEFI Secure Boot and Measured Boot using Atmel I2C TPM hardware device:
+
+```build -a IA32 -t VS2015x86 -p QuarkPlatformPkg/Quark.dsc -D UEFI_SECURE_BOOT -D MEASURED_BOOT_ENABLE -D TPM_12_HARDWARE=ATMEL_I2C```
+
+## **FLASH Update using DediProg SF100**
+
+Once the sources have been downloaded, an EDK II build environment established,
+and an EDK II firmware image has been built, the EDK II firmware image needs to
+installed into the FLASH device on the target Galileo development board.  One
+way to do this is with the [Dediprog SF100 IC Programmer](
+http://www.dediprog.com/pd/spi-flash-solution/SF100).
+
+* Install the DediProg SF100 software.
+
+* Connect the DediProg SF100 to the Galileo development board.
+
+    ![](https://github.com/tianocore/tianocore.github.io/wiki/Projects/QuarkPlatformPkg/Images/Dediprog.jpg)
+
+* Make sure ```dpcmd.exe``` is in ```PATH```
+
+  ```PATH=%PATH%;"c:\Program Files (x86)\DediProg\SF100"```
+
+* **NOTE**: It is recommended that the FLASH image that was shipped with the
+  Galileo development board be read and saved before updating FLASH image.  The
+  command shown below read the FLASH image and saves it to the file
+  called ```GalileoOriginalFirmware.bin```.
+
+  ```dpcmd.exe -r GalileoOriginalFirmware.bin```
+
+* Update FLASH image using either the DediProg SF100 GUI or ```dpcmd.exe```.
+  - Example update of Galileo firmware image when BUILDTARGET is DEBUG (default)
+
+    ```dpcmd.exe -u%WORKSPACE%\Build\Quark\DEBUG_VS2015x86\FV\QUARK.fd ```
+
+  - Example update of Galileo firmware image when BUILDTARGET is RELEASE
+    (```-b RELEASE```)
+
+    ```dpcmd.exe -u%WORKSPACE%\Build\Quark\RELEASE_VS2015x86\FV\QUARK.fd ```
+
+## **Setting up a Serial Console and Booting to UEFI Shell**
+
+After the FLASH is updated on Galileo, a serial cable is connected between the
+host system and the Galileo target.  A serial terminal emulator (such as
+[Tera Term](https://en.osdn.jp/projects/ttssh2/releases/)) can be used to see
+the logging messages from DEBUG() macros and the serial console for the UEFI
+Boot Manager, UEFI Shell, and operating system.
+
+The default serial communication parameters for the Intel(R) Galileo Gen 2
+Development Board is 921600,n,8,1 with no hardware flow control.
+
+![](https://github.com/tianocore/tianocore.github.io/wiki/Projects/QuarkPlatformPkg/Images/TeraTermSerialParameters.png)
+
+The default serial communication parameters for the Intel(R) Galileo Development
+Board is 461800,n,8,1 with no hardware flow control.
+
+The following changes to the [Tera Term](https://en.osdn.jp/projects/ttssh2/releases/)
+configuration files are recommended for UEFI serial console compatibility.
+Some of the later use cases involve using the TCPIP mode, so some of these
+recommendation apply to the TCPIP use cases.
+
+* TERATERM.INI - Set terminal size to 80 x 25 and terminal settings to UTF8.
+
+![](https://github.com/tianocore/tianocore.github.io/wiki/Projects/QuarkPlatformPkg/Images/TeraTermTerminal.png)
+
+* TERATERM.INI - Set font type to Terminal to support box drawing glyphs.
+
+![](https://github.com/tianocore/tianocore.github.io/wiki/Projects/QuarkPlatformPkg/Images/TeraTermFont.png)
+
+* TERATERM.INI - Disable line mode to make TCPIP mode work like COM port mode.
+
+```ini
+; Line at a time mode
+EnableLineMode=off
+```
+
+* KEYBOARD.CNF - Disable VT function keys for F5..F10
+
+```ini
+[VT function keys]
+;F6 key
+;F6=64
+;F7 key
+;F7=65
+;F8 key
+;F8=66
+;F9 key
+;F9=67
+;F10 key
+;F10=68
+```
+
+* KEYBOARD.CNF - Disable X function keys for F1..F4
+
+```ini
+[X function keys]
+; F1 key
+XF1=off
+; F2 key
+;XF2=60
+XF2=off
+; F3 key
+;XF3=61
+XF3=off
+; F4 key
+;XF4=62
+XF4=off
+; F5 key
+;XF5=63
+```
+
+* KEYBOARD.CNF - Add UEFI serial console sequences for F1..F10
+
+```ini
+[User keys]
+User1=59,0,$1B[M
+User2=60,0,$1B[N
+User3=61,0,$1B[O
+User4=62,0,$1B[P
+User5=63,0,$1B[Q
+User6=64,0,$1B[R
+User7=65,0,$1B[S
+User8=66,0,$1B[T
+User9=67,0,$1B[U
+User10=68,0,$1B[V
+```
+
+Connect power adapter to Galileo development board, and the logging messages
+should be seen, followed by 5 second countdown, followed by an automatic boot to
+the built-in UEFI Shell.
+
+![](https://github.com/tianocore/tianocore.github.io/wiki/Projects/QuarkPlatformPkg/Images/UefiShell.png)
+
+## **Source Level Debug Using Intel(R) UEFI Development Kit Debugger Tool**
+
+### Pre-requisites
+
+* Intel(R) UEFI Development Kit Debugger Tool User Manual for Ver 1.5 or higher:
+  Available from https://firmware.intel.com/develop/intel-uefi-tools-and-utilities/intel-uefi-development-kit-debugger-tool
+* Intel(R) UEFI Development Kit Debugger Tool Ver 1.5 or higher: Available from
+  https://firmware.intel.com/develop/intel-uefi-tools-and-utilities/intel-uefi-development-kit-debugger-tool
+* [Tera Term](https://en.osdn.jp/projects/ttssh2/releases/) or other serial
+  terminal emulator with TCPIP support
+
+Follow instructions in Intel(R) UEFI Development Kit Debugger Tool User manual
+to setup host system.
+
+Build a firmware image with SOURCE_DEBUG_ENABLE enabled
+(```-D SOURCE_DEBUG_ENABLE```).  This will select the appropriate libraries,
+debug agent, and PCDs for Galileo.  Galileo does not support a USB 2.0 debug
+port, so only the UART based communications library is used.
+
+Use Dediprog SF100 to update the Galileo development board FLASH image.
+
+Update the ```[Debug Port]``` section of the SoftDebugger.ini file with the host
+side UART configuration settings.  The following example uses COM5, which must
+be updated with the COM port the Galileo target is attached.  The following
+example also shows a baud rate of 921600 which is correct for a Galileo Gen 2.
+If a Galileo Gen 1 is being used, set the baud rate to 460800.  By default, the
+Galileo console is redirected to TCPIP port 20715.
+
+```ini
+[Debug Port]
+Channel = Serial
+Port = COM5
+FlowControl = 0
+BaudRate = 921600
+Server =
+```
+
+Connect power adapter to Galileo development board and run a command script with
+the contents below to start a Tera Term session on TCPIP port 20715 and start
+the Intel(R) UEFI Development Kit Debugger Tool using UART connection between
+the host and target and WinDbg.  The REBOOT button on the Galileo development
+board may need to be pressed for the debugger to perform the initial connect.
+
+```cmd
+start "Console" /B "c:\Program Files (x86)\teraterm\ttermpro.exe" localhost:20715 /nossh
+start "Debugger" /B "C:\Program Files (x86)\Intel\Intel(R) UEFI Development Kit Debugger Tool\eXdi.exe" /LaunchWinDbg
+```
+
+The figure below should be seen when a connection is made.  The SoftDebugger
+Debug Console window shows the status of the connection between the host and the
+target.  The Tera Term window shows the console output from the SEC phase until
+the debug agent is initialized.  The WinDbg window shows that the debugger is
+connected and the WinDbg application can be used for run control, breakpoint
+management, and viewing call stacks, local variables,  global variables, etc.
+
+![](https://github.com/tianocore/tianocore.github.io/wiki/Projects/QuarkPlatformPkg/Images/UdkDebugger.png)
+
+## **Debug Using Intel(R) System Debugger using OpenOCD**
+
+Setup hardware and software components following the instructions in the article at:
+https://software.intel.com/en-us/articles/using-intel-system-debugger-with-openocd
+
+Connect power adapter to Galileo development board.
+
+The following batch file starts Tera Term serial console on COM5 at 921600 baud,
+starts OpenOCD using a Flyswatter2, and starts Intel(R) System Studio Debugger.
+Select the **Connect** button to complete the host to target connection.
+
+```cmd
+set OPENOCD="C:\Program Files (x86)\IntelSWTools\system_studio_for_windows_2016.0.023\debugger\openocd"
+start "Console" /B "c:\Program Files (x86)\teraterm\ttermpro.exe" /C=5 /BAUD=921600
+start "OpenOcd" /B %OPENOCD%\bin\openocd.exe -f ..\scripts\interface\ftdi\flyswatter2.cfg -f ..\scripts\board\quark_x10xx_board.cfg
+call "C:\Program Files (x86)\IntelSWTools\System Debugger 2016\system_debugger\start_xdb_gdb_remote.bat"
+```
+
+When **Reset Target** is selected, the Galileo development board does not always
+halt at the first instruction at the reset vector.  If debug is required from
+the first instruction of the reset vector, then update the file
+```UefiCpuPkg/SecCore/Ia32/ResetVector.asm``` and change the two NOP
+instructions at the label ```ResetHandler:``` to ```JMP $```.  This puts the CPU
+into a wait loop until the debugger is connected and the debugger is used to set
+instruction pointer to the next instruction.
+
+```
+;
+; For IA32, the reset vector must be at 0xFFFFFFF0, i.e., 4G-16 byte
+; Execution starts here upon power-on/platform-reset.
+;
+ResetHandler:
+;    nop
+;    nop
+    jmp $
+ApStartup:
+    ;
+    ; Jmp Rel16 instruction
+    ; Use machine code directly in case of the assembler optimization
+    ; SEC entry point relative address will be fixed up by some build tool.
+    ;
+    ; Typically, SEC entry point is the function _ModuleEntryPoint() defined in
+    ; SecEntry.asm
+    ;
+    DB      0e9h
+    DW      -3
+```
+
+## **Install, Configure, and Boot Linux**
+
+* Download SD Card Linux Image: Available at
+  http://www.intel.com/content/www/us/en/support/boards-and-kits/intel-galileo-boards/000005614.html
+* Extract the SD Card Linux Image to a FAT formatted Micro SD FLASH device
+* Install Micro SD FLASH device into Galileo development board
+
+Connect power adapter to Galileo development board and boot to the UEFI Shell.
+
+From the UEFI Shell execute the following commands to copy the GRUB EFI boot
+loader to ```\efi\boot\bootia32.efi```.  This allows the UEFI Boot Manager, on
+all future boots, to auto detect that the Micro SD FLASH device is bootable.
+
+```
+Shell> connect -r
+Shell> map -r
+Shell> fs0:
+FS0:> mkdir efi
+FS0:> mkdir efi\boot
+FS0:> cp grub.efi efi\boot\bootia32.efi
+```
+
+The GRUB boot loader is set to a UART baud rate of 115200.  A couple changes are
+required to change the baud rate to 460800 for Galileo Gen 1 or 921600 for
+Galileo Gen 2.  From the UEFI Shell, execute the following commands to make a
+backup copy and edit the GRUB configuration file.
+
+```
+FS0:> cp boot\grub\grub.conf boot\grub\grub.conf.org
+FS0:> edit boot\grub\grub.conf
+```
+
+* Delete the lines associated with the boot option with the following title.
+
+```
+title Clanton SVP kernel-SPI initrd-SPI IMR-On IO-APIC/HPET NoEMU
+```
+
+* Replace the two instances of 115200 in the following line to 460800 for
+  Galileo Gen 1 or 921600 for Galileo Gen 2.
+
+```
+kernel /bzImage root=/dev/ram0 console=ttyS1,115200n8 earlycon=uart8250,mmio32,$EARLY_CON_ADDR_REPLACE,115200n8 reboot=efi,warm apic=debug rw LABEL=boot debugshell=5 rootimage=image-full-galileo-clanton.ext3
+```
+* Press F3 to save the file
+* Run the ```exit``` command to exit from the UEFI Shell and return to the
+  UEFI Boot Manager
+* Select **Boot Manager**
+* Select **UEFI Misc Device** for the Micro SD FLASH device.
+* GRUB should run and Linux should boot with serial log messages.
+* When the serial log messages stop, change the Tera Term baud rate to 115200
+* Login as ```root```.   No password is required.
+* Use ```vi``` to edit ```/etc/inittab```
+* Change the baud rate of ttyS1 from 115200 to 460800 for Galileo Gen 1 or
+  921600 for Galileo Gen 2.  The line that need to be updated is shown below
+
+```
+S:2345:respawn:/sbin/getty 115200 ttyS1
+```
+
+* Save the updated ```/etc/inittab```
+* Run ```reboot -f``` to shutdown Linux and reboot the platform.
+* Set the Tera Term baud rate back to 460800 for Galileo Gen 1 or 921600 for
+  Galileo Gen 2.
+
+After these changes both the EDK II firmware and the Linux operating system use
+the same baud rate.
+
+### **Testing ACPI S3 Sleep**
+
+The ACPI S3 Sleep and Resume feature can be tested on a Galileo development
+board using the Real Time Clock (RTC) for a wake event.  The shell script shown
+below arms the RTC wake alarm 10 seconds in the future and puts the system to
+sleep.  A shorter time in seconds can be passed in as the first argument to the
+script, but do not use times shorter than 2 or 3 seconds.
+
+**NOTE**: The stmmac module is unloaded because the module is not compatible
+with S3 resume.
+
+```sh
+#
+# Unload NIC driver that causes S3 to fail
+#
+rmmod stmmac
+
+#
+# Disable RTC wake alarm
+#
+echo 0 > /sys/class/rtc/rtc0/wakealarm
+
+#
+# Compute wake time that is $1 seconds in the future
+#
+let WakeTime=`date '+%s'`
+echo $WakeTime
+if ["$1" = ""]; then
+  let WakeTime=$WakeTime+10
+else
+  let WakeTime=$WakeTime+$1
+fi
+echo $WakeTime
+
+#
+# Enable RTC wake alarm $1 seconds in the future
+#
+echo $WakeTime > /sys/class/rtc/rtc0/wakealarm
+
+#
+# Put systems into ACPI S3 sleep state
+#
+echo mem > /sys/power/state
+```
+
+## **UEFI Secure Boot Feature and Physical Presence**
+
+Build a firmware image with SECURE_BOOT_ENABLE enabled
+(```-D SECURE_BOOT_ENABLE```). This builds in support for UEFI authenticated
+variables, UEFI image verification, and UEFI Secure Boot configuration screens
+in the Device Manager. In order to change the UEFI Secure Boot configuration,
+the user must assert physical presence.  The Galileo development board only has
+two push buttons (REBOOT and RESET).  The REBOOT button unconditionally reboots
+the platform. The RESET button asserts the reset signal on the Arduino header
+and is also connected to a GPIO pin, so the state of the RESET button can be
+read.  The user asserts physical presence by holding the RESET button while the
+Galileo development board boots, or by holding the RESET button while selecting
+the **Secure Boot Configuration** option in the Device Manager.
+
+Use Dediprog SF100 to update the Galileo development board FLASH image.
+
+Connect power adapter to Galileo development board and boot to the UEFI Boot
+Manager by pressing F2 or running the ```exit``` command from the UEFI Shell.
+Select **Device Manager** and then**Secure Boot Configuration**.  Change
+**Customize Secure Boot** to **Customized** and then select **Custom Secure Boot
+Options**.  If **Custom Secure Boot Options** can not be selected, then physical
+presence was not asserted using one of two methods listed above.  Assert
+physical presence and try again.
+
+The **Custom Secure Boot Options** screen allows the Galileo development board
+to be enrolled into UEFI Secure Boot.  See [How to Sign UEFI Drivers & Application V1.31](
+http://sourceforge.net/projects/edk2/files/General%20Documentation/SigningUefiImages%20-v1dot31.pdf/download)
+in the [SecurityPkg Wiki](https://github.com/tianocore/tianocore.github.io/wiki/SecurityPkg)
+for details on how to complete the UEFI Secure Boot enrollment.
+
+## **Enable Measured Boot Feature using Atmel I2C TPM on CryptoShield**
+
+Build a firmware image with MEASURED_BOOT_ENABLE enabled
+(```-D MEASURED_BOOT_ENABLE```) and TPM_12_HARDWARE set to ATMEL_I2C
+(```-D TMP_12_HARDWARE=ATMEL_I2C```). This builds in the TCG PEIM and DXE
+modules and uses the library for the Atmel I2C TPM hardware device.
+
+Use Dediprog SF100 to update the Galileo development board FLASH image.
+
+Attach the CryptoShield to the Arduino header of the Galileo development board
+as shown below.
+
+![](https://github.com/tianocore/tianocore.github.io/wiki/Projects/QuarkPlatformPkg/Images/GalileoCryptoShield.jpg)
+
+Connect power adapter to Galileo development board and boot to the UEFI Shell.
+In the boot logging messages, messages similar to the following should be seen
+as the Atmel I2C TPM hardware device is detected and used to measure the
+contents of firmware volumes and firmware tables.
+
+```
+Loading PEIM at 0x0000FC75188 EntryPoint=0x0000FC75260 TrEEConfigPei.efi
+PROGRESS CODE: V03020002 I0
+TrEEConfiguration.TpmDevice from Setup: 1
+DetectTpmDevice:
+TpmDevice final: 1
+TpmDevice PCD: 8B01E5B6-4F19-46E8-AB93-1C53671B90CC
+. . .
+Loading PEIM at 0x0000FC70190 EntryPoint=0x0000FC70260 TcgPei.efi
+PROGRESS CODE: V03020002 I0
+Install PPI: E9DB0D58-D48D-47F6-9C6E-6F40E86C7B41
+Install PPI: A030D115-54DD-447B-9064-F206883D7CCC
+PROGRESS CODE: V03020003 I0
+The FV which is measured by TcgPei starts at: 0xFFF10000
+The FV which is measured by TcgPei has the size: 0xF0000
+The FV which is measured by TcgPei starts at: 0xFFD00000
+The FV which is measured by TcgPei has the size: 0x1E0000
+. . .
+Loading driver at 0x0000F620000 EntryPoint=0x0000F620260 TcgDxe.efi
+. . .
+TPM TcgDxe Measure Data when ReadyToBoot
+```
+See the [SecurityPkg Wiki](https://github.com/tianocore/tianocore.github.io/wiki/SecurityPkg)
+for additional details on EDK II TPM support
+
+## **Measuring Boot Performance**
+
+Build a firmware image with PERFORMANCE_ENABLE enabled
+(```-D PERFORMANCE_ENABLE```). This builds in the UEFI Shell and the DP.EFI
+(Dump Performance) into a firmware volume and also includes a simple file system
+driver for firmware volumes so the DP.EFI command can be run out of the FLASH.
+
+Use Dediprog SF100 to update the Galileo development board FLASH image.
+
+Connect power adapter to Galileo development board and let it boot to the UEFI
+Shell.  Then use the REBOOT button or the ```reset``` UEFI Shell command to
+reboot the Galileo development board.  The first boot after a FLASH update does
+extra work that is only performed one time.  In order to get correct performance
+measurements, use the 2nd or later boots.  After the 2nd boot, run the
+```dp -s``` command.  The output should look similar to the figure below.
+
+![](https://github.com/tianocore/tianocore.github.io/wiki/Projects/QuarkPlatformPkg/Images/DpCommand.png)
-- 
2.21.0.windows.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [edk2-platforms: Patch 5/8] Platform/Vlv2DeviceRefCodePkg: Import Vlv2DeviceRefCodePkg from edk2
  2019-05-10  3:34 [edk2-platforms: Patch 0/8] Add packages from edk2 Michael D Kinney
                   ` (3 preceding siblings ...)
  2019-05-10  3:34 ` [edk2-platforms: Patch 4/8] Platform/QuarkPlatformPkg: Import QuarkPlatformPkg " Michael D Kinney
@ 2019-05-10  3:34 ` Michael D Kinney
  2019-05-13  2:52   ` Sun, Zailiang
  2019-05-10  3:34 ` [edk2-platforms: Patch 6/8] Platform/Vlv2TbltDevicePkg: Import Vlv2TbltDevicePkg " Michael D Kinney
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 23+ messages in thread
From: Michael D Kinney @ 2019-05-10  3:34 UTC (permalink / raw)
  To: devel; +Cc: Zailiang Sun, Yi Qian, Michael Kubacki, Leif Lindholm,
	Ard Biesheuvel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 864434 bytes --]

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

Import Vlv2DeviceRefCodePkg 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>
---
 .../AcpiTablesPCAT/98_LINK.ASL                |  617 +++++++++
 .../AcpiTablesPCAT/AcpiTablePlatform.h        |   70 +
 .../AcpiTablesPCAT/AcpiTables.inf             |   40 +
 .../AcpiTablesPCAT/CPU.asl                    |   49 +
 .../AcpiTablesPCAT/DSDT.ASL                   |   75 +
 .../AcpiTablesPCAT/Facp/Facp.aslc             |  188 +++
 .../AcpiTablesPCAT/Facs/Facs.aslc             |   84 ++
 .../AcpiTablesPCAT/GloblNvs.asl               |  348 +++++
 .../AcpiTablesPCAT/Gpe.asl                    |   99 ++
 .../AcpiTablesPCAT/HOST_BUS.ASL               |  347 +++++
 .../AcpiTablesPCAT/Hpet/Hpet.aslc             |   63 +
 .../AcpiTablesPCAT/INTELGFX.ASL               |  879 ++++++++++++
 .../AcpiTablesPCAT/INTELISPDev2.ASL           |   71 +
 .../AcpiTablesPCAT/IgdOGBDA.ASL               |  155 +++
 .../AcpiTablesPCAT/IgdOMOBF.ASL               |  485 +++++++
 .../AcpiTablesPCAT/IgdOSBCB.ASL               |  274 ++++
 .../AcpiTablesPCAT/IgdOpRn.ASL                |  299 ++++
 .../AcpiTablesPCAT/IoTVirtualDevice.asl       |  171 +++
 .../AcpiTablesPCAT/LPC_DEV.ASL                |  151 +++
 .../AcpiTablesPCAT/LpcB.asl                   |   59 +
 .../AcpiTablesPCAT/Lpit/Lpit.aslc             |  223 +++
 .../AcpiTablesPCAT/Madt/Madt.h                |  189 +++
 .../AcpiTablesPCAT/Madt/Madt30.aslc           |  178 +++
 .../AcpiTablesPCAT/Mcfg/Mcfg.aslc             |   86 ++
 .../AcpiTablesPCAT/PCI_DRC.ASL                |   90 ++
 .../AcpiTablesPCAT/Pch.asl                    |  686 ++++++++++
 .../AcpiTablesPCAT/PchAudio.asl               |   36 +
 .../AcpiTablesPCAT/PchEhci.asl                |  269 ++++
 .../AcpiTablesPCAT/PchLpss.asl                | 1093 +++++++++++++++
 .../AcpiTablesPCAT/PchPcie.asl                |   50 +
 .../AcpiTablesPCAT/PchScc.asl                 |  610 +++++++++
 .../AcpiTablesPCAT/PchSmb.asl                 |  833 ++++++++++++
 .../AcpiTablesPCAT/PchXhci.asl                |  379 ++++++
 .../AcpiTablesPCAT/PciTree.asl                |  377 ++++++
 .../AcpiTablesPCAT/Platform.asl               |  703 ++++++++++
 .../AcpiTablesPCAT/RTD3.asl                   |  197 +++
 .../AcpiTablesPCAT/RhProxy.asl                |  160 +++
 .../AcpiTablesPCAT/THERMAL.ASL                |  137 ++
 .../AcpiTablesPCAT/UsbSbd.asl                 |   93 ++
 .../AcpiTablesPCAT/Video.asl                  |   34 +
 .../AcpiTablesPCAT/Vlv.asl                    |   39 +
 .../AcpiTablesPCAT/Wsmt/Wsmt.aslc             |   54 +
 .../AcpiTablesPCAT/token.asl                  |   39 +
 .../Guid/Vlv2DeviceRefCodePkgTokenSpace.h     |   24 +
 .../Include/Ppi/PttPassThruPpi.h              |   92 ++
 .../Include/Ppi/fTPMPolicy.h                  |   26 +
 .../Include/Protocol/PttPassThru.h            |   91 ++
 .../Guid/PowerManagementAcpiTableStorage.h    |   27 +
 .../CPU/Include/Ppi/VlvPolicy.h               |  104 ++
 .../CPU/Include/Protocol/PpmPlatformPolicy.h  |  132 ++
 .../ValleyView2Soc/CPU/Include/Types.h        |   55 +
 .../AcpiTables/PowerManagementAcpiTables.inf  |   39 +
 .../PowerManagement/AcpiTables/Ssdt/ApCst.asl |  110 ++
 .../PowerManagement/AcpiTables/Ssdt/ApIst.asl |  166 +++
 .../PowerManagement/AcpiTables/Ssdt/ApTst.asl |  262 ++++
 .../AcpiTables/Ssdt/Cpu0Cst.asl               |  274 ++++
 .../AcpiTables/Ssdt/Cpu0Ist.asl               |  260 ++++
 .../AcpiTables/Ssdt/Cpu0Tst.asl               |  235 ++++
 .../PowerManagement/AcpiTables/Ssdt/CpuPm.asl |  793 +++++++++++
 .../Include/PlatformBaseAddresses.h           |   92 ++
 .../NorthCluster/Include/Ppi/Capsule.h        |   60 +
 .../Include/Ppi/PlatformMemoryRange.h         |  144 ++
 .../Include/Ppi/PlatformMemorySize.h          |   46 +
 .../NorthCluster/Include/Ppi/SmmAccess.h      |  165 +++
 .../NorthCluster/Include/Ppi/VlvMmioPolicy.h  |   39 +
 .../NorthCluster/Include/Ppi/VlvPeiInit.h     |   35 +
 .../NorthCluster/Include/Ppi/VlvPolicy.h      |  106 ++
 .../Include/Protocol/IgdOpRegion.h            |  213 +++
 .../NorthCluster/Include/Protocol/MemInfo.h   |   83 ++
 .../Include/Protocol/PlatformGopPolicy.h      |   67 +
 .../Include/Protocol/VlvPlatformPolicy.h      |  105 ++
 .../NorthCluster/Include/Valleyview.h         |   55 +
 .../NorthCluster/Include/VlvAccess.h          |  254 ++++
 .../Include/VlvCommonDefinitions.h            |  252 ++++
 .../SouthCluster/Include/Guid/PchInitVar.h    |   48 +
 .../Include/Guid/SataControllerGuid.h         |   34 +
 .../SouthCluster/Include/Guid/SmbusArpMap.h   |   30 +
 .../SouthCluster/Include/Guid/Vlv2Variable.h  |   28 +
 .../Include/IndustryStandard/CeAta.h          |  126 ++
 .../Include/IndustryStandard/Mmc.h            |  349 +++++
 .../Include/IndustryStandard/SdCard.h         |  157 +++
 .../SouthCluster/Include/Library/I2CLib.h     |  169 +++
 .../Include/Library/PchPlatformLib.h          |  115 ++
 .../SouthCluster/Include/PchAccess.h          |  471 +++++++
 .../Include/PchCommonDefinitions.h            |  210 +++
 .../SouthCluster/Include/PchRegs.h            |  205 +++
 .../SouthCluster/Include/PchRegs/PchRegsHda.h |   50 +
 .../Include/PchRegs/PchRegsLpss.h             |  486 +++++++
 .../Include/PchRegs/PchRegsPcie.h             |   83 ++
 .../SouthCluster/Include/PchRegs/PchRegsPcu.h | 1201 +++++++++++++++++
 .../Include/PchRegs/PchRegsRcrb.h             |   48 +
 .../Include/PchRegs/PchRegsSata.h             |  245 ++++
 .../SouthCluster/Include/PchRegs/PchRegsScc.h |   53 +
 .../Include/PchRegs/PchRegsSmbus.h            |  149 ++
 .../SouthCluster/Include/PchRegs/PchRegsSpi.h |  119 ++
 .../SouthCluster/Include/PchRegs/PchRegsUsb.h |   92 ++
 .../SouthCluster/Include/Ppi/PchInit.h        |   75 +
 .../SouthCluster/Include/Ppi/PchPeiInit.h     |   34 +
 .../Include/Ppi/PchPlatformPolicy.h           |  161 +++
 .../SouthCluster/Include/Ppi/PchUsbPolicy.h   |   69 +
 .../SouthCluster/Include/Ppi/PeiBlockIo.h     |  230 ++++
 .../SouthCluster/Include/Ppi/Sdhc.h           |  359 +++++
 .../SouthCluster/Include/Ppi/SmbusPolicy.h    |   40 +
 .../SouthCluster/Include/Ppi/Spi.h            |   42 +
 .../Include/Protocol/ActiveBios.h             |  123 ++
 .../Include/Protocol/ActiveBiosProtocol.h     |  125 ++
 .../Protocol/DxePchPolicyUpdateProtocol.h     |   51 +
 .../Include/Protocol/EmmcCardInfoProtocol.h   |   42 +
 .../SouthCluster/Include/Protocol/Gpio.h      |  161 +++
 .../Include/Protocol/HwWatchdogTimer.h        |  294 ++++
 .../SouthCluster/Include/Protocol/I2cBus.h    |  164 +++
 .../Include/Protocol/PchExtendedReset.h       |   84 ++
 .../SouthCluster/Include/Protocol/PchInfo.h   |   60 +
 .../Include/Protocol/PchPlatformPolicy.h      |  550 ++++++++
 .../SouthCluster/Include/Protocol/PchReset.h  |  114 ++
 .../Include/Protocol/PchS3Support.h           |  132 ++
 .../SouthCluster/Include/Protocol/SdHostIo.h  |  409 ++++++
 .../Include/Protocol/SmbiosSlotPopulation.h   |   47 +
 .../Include/Protocol/SmmIchnDispatchEx.h      |  159 +++
 .../SouthCluster/Include/Protocol/SmmSmbus.h  |   39 +
 .../SouthCluster/Include/Protocol/Spi.h       |  260 ++++
 .../SouthCluster/Include/Protocol/TcoReset.h  |   88 ++
 .../SouthCluster/Include/Rsci.h               |   28 +
 .../SouthCluster/Include/TianoApi.h           |   61 +
 .../Vlv2DeviceRefCodePkg.dec                  |  231 ++++
 125 files changed, 24185 insertions(+)
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/98_LINK.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTablePlatform.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTables.inf
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/CPU.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/DSDT.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facp/Facp.aslc
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facs/Facs.aslc
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/GloblNvs.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Gpe.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/HOST_BUS.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Hpet/Hpet.aslc
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELGFX.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELISPDev2.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOGBDA.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOMOBF.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOSBCB.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOpRn.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IoTVirtualDevice.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LPC_DEV.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LpcB.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Lpit/Lpit.aslc
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt30.aslc
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Mcfg/Mcfg.aslc
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PCI_DRC.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Pch.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchAudio.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchEhci.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchLpss.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchPcie.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchScc.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchSmb.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchXhci.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PciTree.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Platform.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RTD3.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RhProxy.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/THERMAL.ASL
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/UsbSbd.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Video.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Vlv.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Wsmt/Wsmt.aslc
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/token.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Guid/Vlv2DeviceRefCodePkgTokenSpace.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/PttPassThruPpi.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/fTPMPolicy.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Protocol/PttPassThru.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Guid/PowerManagementAcpiTableStorage.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Ppi/VlvPolicy.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Protocol/PpmPlatformPolicy.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Types.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/PowerManagementAcpiTables.inf
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/ApCst.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/ApIst.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/ApTst.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/Cpu0Cst.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/Cpu0Ist.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/Cpu0Tst.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/CpuPm.asl
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/PlatformBaseAddresses.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/Capsule.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/PlatformMemoryRange.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/PlatformMemorySize.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/SmmAccess.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/VlvMmioPolicy.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/VlvPeiInit.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/VlvPolicy.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Protocol/IgdOpRegion.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Protocol/MemInfo.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Protocol/PlatformGopPolicy.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Protocol/VlvPlatformPolicy.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Valleyview.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/VlvAccess.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/VlvCommonDefinitions.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Guid/PchInitVar.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Guid/SataControllerGuid.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Guid/SmbusArpMap.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Guid/Vlv2Variable.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/IndustryStandard/CeAta.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/IndustryStandard/Mmc.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/IndustryStandard/SdCard.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Library/I2CLib.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Library/PchPlatformLib.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchAccess.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchCommonDefinitions.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsHda.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsLpss.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsPcie.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsPcu.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsRcrb.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsSata.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsScc.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsSmbus.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsSpi.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsUsb.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PchInit.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PchPeiInit.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PchPlatformPolicy.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PchUsbPolicy.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PeiBlockIo.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/Sdhc.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/SmbusPolicy.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/Spi.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/ActiveBios.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/ActiveBiosProtocol.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/DxePchPolicyUpdateProtocol.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/EmmcCardInfoProtocol.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/Gpio.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/HwWatchdogTimer.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/I2cBus.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchExtendedReset.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchInfo.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchPlatformPolicy.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchReset.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchS3Support.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/SdHostIo.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/SmbiosSlotPopulation.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/SmmIchnDispatchEx.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/SmmSmbus.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/Spi.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/TcoReset.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Rsci.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/TianoApi.h
 create mode 100644 Silicon/Intel/Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec

diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/98_LINK.ASL b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/98_LINK.ASL
new file mode 100644
index 0000000000..50ebaffc34
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/98_LINK.ASL
@@ -0,0 +1,617 @@
+/**************************************************************************;
+;*                                                                        *;
+;*                                                                        *;
+;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
+;*    Family of Customer Reference Boards.                                *;
+;*                                                                        *;
+;*                                                                        *;
+;*    Copyright (c)  2012  - 2014, Intel Corporation. All rights reserved   *;
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;*                                                                        *;
+;*                                                                        *;
+;**************************************************************************/
+
+
+
+// Use this information when determining the Possible IRQs that can be
+// used in a given system.
+//
+// The following IRQs are always in use by legacy devices:
+//              0  = System Timer
+//              2  = 8259 PIC
+//              8  = RTC
+//              9  = SCI Interrupt (It may be used, we choose not to)
+//              13 = Co-processor Error
+//
+// The following may be in use by legacy devices:
+//              1  = If using PS/2 Keyboard
+//              3  = If COMx Port Enabled and IRQ = 3
+//              4  = If COMx Port Enabled and IRQ = 4
+//              5  = If LPT Port Enabled and IRQ = 5
+//              6  = If FDC Enabled
+//              7  = If LPT Port Enabled and IRQ = 7
+//              12 = If using PS/2 Mouse
+//              14 = Primary IDE (If populated and in Compatibility Mode)
+//              15 = Secondary IDE (If populated and in Compatibility Mode)
+//
+// The following will never be in use by legacy devices:
+//              10 = Assign to PARC, PCRC, PERC, PGRC
+//              11 = Assign to PBRC, PDRC, PFRC, PHRC
+
+Device(LNKA)                            // PARC Routing Resource
+{
+  Name(_HID,EISAID("PNP0C0F"))    // PCI Interrupt Link Device
+
+  Name(_UID,1)                    // Unique to other Link Devices
+
+  // Disable the PCI IRQ.
+
+  Method(_DIS,0,Serialized)
+  {
+    Or(PARC,0x80,PARC)
+  }
+
+  // Possible IRQ Resource Setting.
+
+  Method (_PRS, 0, Serialized)
+  {
+    return (PRSA)
+  }
+
+  // Current IRQ Resource Setting.
+
+  Method(_CRS,0,Serialized)
+  {
+    Name(RTLA,ResourceTemplate()
+    {
+      IRQ(Level,ActiveLow,Shared) {}
+    })
+
+    // Point to specific byte.
+
+    CreateWordField(RTLA,1,IRQ0)
+
+    // Zero out IRQ mask bits 0-15
+
+    Store(Zero,IRQ0)
+
+    ShiftLeft(1,And(PARC,0x0F),IRQ0)
+
+    Return(RTLA)
+  }
+
+  // Set IRQ Resource Setting.
+
+  Method(_SRS,1,Serialized)
+  {
+    // Point to the specific byte passed in
+
+    CreateWordField(Arg0,1,IRQ0)
+
+    // Determine the IRQ bit to set and store it
+
+    FindSetRightBit(IRQ0,Local0)
+    Decrement(Local0)
+    Store(Local0,PARC)
+  }
+
+  // PCI IRQ Status.
+
+  Method(_STA,0,Serialized)
+  {
+    If(And(PARC,0x80))
+    {
+      Return(0x0009)
+    }
+    Else
+    {
+      Return(0x000B)
+    }
+  }
+}
+
+Device(LNKB)                            // PBRC Routing Resource
+{
+  Name(_HID,EISAID("PNP0C0F"))
+
+  Name(_UID,2)
+
+  // Disable the PCI IRQ.
+
+  Method(_DIS,0,Serialized)
+  {
+    Or(PBRC,0x80,PBRC)
+  }
+
+  // Possible IRQ Resource Setting.
+
+  Method (_PRS, 0, Serialized)
+  {
+    return (PRSB)
+  }
+
+  // Current IRQ Resource Setting.
+
+  Method(_CRS,0,Serialized)
+  {
+    Name(RTLB,ResourceTemplate()
+    {
+      IRQ(Level,ActiveLow,Shared) {}
+    })
+
+    // Point to specific byte.
+
+    CreateWordField(RTLB,1,IRQ0)
+
+    // Zero out IRQ mask bits 0-15
+
+    Store(Zero,IRQ0)
+
+    ShiftLeft(1,And(PBRC,0x0F),IRQ0)
+
+    Return(RTLB)
+  }
+
+  // Set IRQ Resource Setting.
+
+  Method(_SRS,1,Serialized)
+  {
+    // Point to the specific byte passed in.
+
+    CreateWordField(Arg0,1,IRQ0)
+
+    // Determine the IRQ bit to set and store it,
+
+    FindSetRightBit(IRQ0,Local0)
+    Decrement(Local0)
+    Store(Local0,PBRC)
+  }
+
+  // PCI IRQ Status.
+
+  Method(_STA,0,Serialized)
+  {
+    If(And(PBRC,0x80))
+    {
+      Return(0x0009)
+    }
+    Else
+    {
+      Return(0x000B)
+    }
+  }
+}
+
+Device(LNKC)                            // PCRC Routing Resource
+{
+  Name(_HID,EISAID("PNP0C0F"))
+
+  Name(_UID,3)
+
+  // Disable the PCI IRQ.
+
+  Method(_DIS,0,Serialized)
+  {
+    Or(PCRC,0x80,PCRC)
+  }
+
+  // Possible IRQ Resource Setting.
+
+  Method (_PRS, 0, Serialized)
+  {
+    return (PRSC)
+  }
+
+  // Current IRQ Resource Setting.
+
+  Method(_CRS,0,Serialized)
+  {
+    Name(RTLC,ResourceTemplate()
+    {
+      IRQ(Level,ActiveLow,Shared) {}
+    })
+
+    // Point to specific byte.
+
+    CreateWordField(RTLC,1,IRQ0)
+
+    // Zero out IRQ mask bits 0-15
+
+    Store(Zero,IRQ0)
+
+    ShiftLeft(1,And(PCRC,0x0F),IRQ0)
+
+    Return(RTLC)
+  }
+
+  // Set IRQ Resource Setting.
+
+  Method(_SRS,1,Serialized)
+  {
+    // Point to the specific byte passed in.
+
+    CreateWordField(Arg0,1,IRQ0)
+
+    // Determine the IRQ bit to set and store it,
+
+    FindSetRightBit(IRQ0,Local0)
+    Decrement(Local0)
+    Store(Local0,PCRC)
+  }
+
+  // PCI IRQ Status.
+
+  Method(_STA,0,Serialized)
+  {
+    If(And(PCRC,0x80))
+    {
+      Return(0x0009)
+    }
+    Else
+    {
+      Return(0x000B)
+    }
+  }
+}
+
+Device(LNKD)                            // PDRC Routing Resource
+{
+  Name(_HID,EISAID("PNP0C0F"))
+
+  Name(_UID,4)
+
+  // Disable the PCI IRQ.
+
+  Method(_DIS,0,Serialized)
+  {
+    Or(PDRC,0x80,PDRC)
+  }
+
+  // Possible IRQ Resource Setting.
+
+  Method (_PRS, 0, Serialized)
+  {
+    return (PRSD)
+  }
+
+  // Current IRQ Resource Setting.
+
+  Method(_CRS,0,Serialized)
+  {
+    Name(RTLD,ResourceTemplate()
+    {
+      IRQ(Level,ActiveLow,Shared) {}
+    })
+
+    // Point to specific byte.
+
+    CreateWordField(RTLD,1,IRQ0)
+
+    // Zero out IRQ mask bits 0-15
+
+    Store(Zero,IRQ0)
+
+    ShiftLeft(1,And(PDRC,0x0F),IRQ0)
+
+    Return(RTLD)
+  }
+
+  // Set IRQ Resource Setting.
+
+  Method(_SRS,1,Serialized)
+  {
+    // Point to the specific byte passed in.
+
+    CreateWordField(Arg0,1,IRQ0)
+
+    // Determine the IRQ bit to set and store it,
+
+    FindSetRightBit(IRQ0,Local0)
+    Decrement(Local0)
+    Store(Local0,PDRC)
+  }
+
+  // PCI IRQ Status.
+
+  Method(_STA,0,Serialized)
+  {
+    If(And(PDRC,0x80))
+    {
+      Return(0x0009)
+    }
+    Else
+    {
+      Return(0x000B)
+    }
+  }
+}
+
+Device(LNKE)                            // PERC Routing Resource
+{
+  Name(_HID,EISAID("PNP0C0F"))
+
+  Name(_UID,5)
+
+  // Disable the PCI IRQ.
+
+  Method(_DIS,0,Serialized)
+  {
+    Or(PERC,0x80,PERC)
+  }
+
+  // Possible IRQ Resource Setting.
+
+  Method (_PRS, 0, Serialized)
+  {
+    return (PRSE)
+  }
+
+  // Current IRQ Resource Setting.
+
+  Method(_CRS,0,Serialized)
+  {
+    Name(RTLE,ResourceTemplate()
+    {
+      IRQ(Level,ActiveLow,Shared) {}
+    })
+
+    // Point to specific byte.
+
+    CreateWordField(RTLE,1,IRQ0)
+
+    // Zero out IRQ mask bits 0-15
+
+    Store(Zero,IRQ0)
+
+    ShiftLeft(1,And(PERC,0x0F),IRQ0)
+
+    Return(RTLE)
+  }
+
+  // Set IRQ Resource Setting.
+
+  Method(_SRS,1,Serialized)
+  {
+    // Point to the specific byte passed in
+
+    CreateWordField(Arg0,1,IRQ0)
+
+    // Determine the IRQ bit to set and store it
+
+    FindSetRightBit(IRQ0,Local0)
+    Decrement(Local0)
+    Store(Local0,PERC)
+  }
+
+  // PCI IRQ Status.
+
+  Method(_STA,0,Serialized)
+  {
+    If(And(PERC,0x80))
+    {
+      Return(0x0009)
+    }
+    Else
+    {
+      Return(0x000B)
+    }
+  }
+}
+
+Device(LNKF)                            // PFRC Routing Resource
+{
+  Name(_HID,EISAID("PNP0C0F"))
+
+  Name(_UID,6)
+
+  // Disable the PCI IRQ.
+
+  Method(_DIS,0,Serialized)
+  {
+    Or(PFRC,0x80,PFRC)
+  }
+
+  // Possible IRQ Resource Setting.
+
+  Method (_PRS, 0, Serialized)
+  {
+    return (PRSF)
+  }
+
+  // Current IRQ Resource Setting.
+
+  Method(_CRS,0,Serialized)
+  {
+    Name(RTLF,ResourceTemplate()
+    {
+      IRQ(Level,ActiveLow,Shared) {}
+    })
+
+    // Point to specific byte.
+
+    CreateWordField(RTLF,1,IRQ0)
+
+    // Zero out IRQ mask bits 0-15
+
+    Store(Zero,IRQ0)
+
+    ShiftLeft(1,And(PFRC,0x0F),IRQ0)
+
+    Return(RTLF)
+  }
+
+  // Set IRQ Resource Setting.
+
+  Method(_SRS,1,Serialized)
+  {
+    // Point to the specific byte passed in.
+
+    CreateWordField(Arg0,1,IRQ0)
+
+    // Determine the IRQ bit to set and store it,
+
+    FindSetRightBit(IRQ0,Local0)
+    Decrement(Local0)
+    Store(Local0,PFRC)
+  }
+
+  // PCI IRQ Status.
+
+  Method(_STA,0,Serialized)
+  {
+    If(And(PFRC,0x80))
+    {
+      Return(0x0009)
+    }
+    Else
+    {
+      Return(0x000B)
+    }
+  }
+}
+
+Device(LNKG)                            // PGRC Routing Resource
+{
+  Name(_HID,EISAID("PNP0C0F"))
+
+  Name(_UID,7)
+
+  // Disable the PCI IRQ.
+
+  Method(_DIS,0,Serialized)
+  {
+    Or(PGRC,0x80,PGRC)
+  }
+
+  // Possible IRQ Resource Setting.
+
+  Method (_PRS, 0, Serialized)
+  {
+    return (PRSG)
+  }
+
+  // Current IRQ Resource Setting.
+
+  Method(_CRS,0,Serialized)
+  {
+    Name(RTLG,ResourceTemplate()
+    {
+      IRQ(Level,ActiveLow,Shared) {}
+    })
+
+    // Point to specific byte.
+
+    CreateWordField(RTLG,1,IRQ0)
+
+    // Zero out IRQ mask bits 0-15
+
+    Store(Zero,IRQ0)
+
+    ShiftLeft(1,And(PGRC,0x0F),IRQ0)
+
+    Return(RTLG)
+  }
+
+  // Set IRQ Resource Setting.
+
+  Method(_SRS,1,Serialized)
+  {
+    // Point to the specific byte passed in.
+
+    CreateWordField(Arg0,1,IRQ0)
+
+    // Determine the IRQ bit to set and store it,
+
+    FindSetRightBit(IRQ0,Local0)
+    Decrement(Local0)
+    Store(Local0,PGRC)
+  }
+
+  // PCI IRQ Status.
+
+  Method(_STA,0,Serialized)
+  {
+    If(And(PGRC,0x80))
+    {
+      Return(0x0009)
+    }
+    Else
+    {
+      Return(0x000B)
+    }
+  }
+}
+
+Device(LNKH)                            // PHRC Routing Resource
+{
+  Name(_HID,EISAID("PNP0C0F"))
+
+  Name(_UID,8)
+
+  // Disable the PCI IRQ.
+
+  Method(_DIS,0,Serialized)
+  {
+    Or(PHRC,0x80,PHRC)
+  }
+
+  // Possible IRQ Resource Setting.
+
+  Method (_PRS, 0, Serialized)
+  {
+    return (PRSH)
+  }
+
+  // Current IRQ Resource Setting.
+
+  Method(_CRS,0,Serialized)
+  {
+    Name(RTLH,ResourceTemplate()
+    {
+      IRQ(Level,ActiveLow,Shared) {}
+    })
+
+    // Point to specific byte.
+
+    CreateWordField(RTLH,1,IRQ0)
+
+    // Zero out IRQ mask bits 0-15
+
+    Store(Zero,IRQ0)
+
+    ShiftLeft(1,And(PHRC,0x0F),IRQ0)
+
+    Return(RTLH)
+  }
+
+  // Set IRQ Resource Setting.
+
+  Method(_SRS,1,Serialized)
+  {
+    // Point to the specific byte passed in.
+
+    CreateWordField(Arg0,1,IRQ0)
+
+    // Determine the IRQ bit to set and store it,
+
+    FindSetRightBit(IRQ0,Local0)
+    Decrement(Local0)
+    Store(Local0,PHRC)
+  }
+
+  // PCI IRQ Status.
+
+  Method(_STA,0,Serialized)
+  {
+    If(And(PHRC,0x80))
+    {
+      Return(0x0009)
+    }
+    Else
+    {
+      Return(0x000B)
+    }
+  }
+}
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTablePlatform.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTablePlatform.h
new file mode 100644
index 0000000000..b3a7cba106
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTablePlatform.h
@@ -0,0 +1,70 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  AcpiTablePlatform.h
+
+
+Abstract: File contains platform specific ACPI defines for use in ACPI tables
+
+
+--*/
+#ifndef _Platform_h_INCLUDED_
+#define _Platform_h_INCLUDED_
+
+#ifdef ECP_FLAG
+#include "EdkIIGlueDxe.h"
+#endif
+#include <IndustryStandard/Acpi.h>
+//
+// ACPI table information used to initialize tables.
+//
+#define EFI_ACPI_OEM_ID           'O','E','M','I','D',' '   // OEMID 6 bytes long
+#define EFI_ACPI_OEM_TABLE_ID     SIGNATURE_64('O','E','M','T','A','B','L','E') // OEM table id 8 bytes long
+#define EFI_ACPI_OEM_REVISION     0x00000005
+#define EFI_ACPI_CREATOR_ID       SIGNATURE_32('C','R','E','A')
+#define EFI_ACPI_CREATOR_REVISION 0x0100000D
+#define INT_MODEL       0x01
+#define PM_PROFILE      EFI_ACPI_4_0_PM_PROFILE_MOBILE
+#define SCI_INT_VECTOR  0x0009
+#define SMI_CMD_IO_PORT 0x000000B2
+#define ACPI_ENABLE     0x0A0
+#define ACPI_DISABLE    0x0A1
+#define S4BIOS_REQ      0x00
+#define PSTATE_CNT      0x00
+#define PM1a_EVT_BLK    0x00000400
+#define PM1b_EVT_BLK    0x00000000
+#define PM1a_CNT_BLK    0x00000404
+#define PM1b_CNT_BLK    0x00000000
+#define PM2_CNT_BLK     0x00000450
+#define PM_TMR_BLK      0x00000408
+#define GPE0_BLK        0x00000420
+#define GPE1_BLK        0x00000000
+#define PM1_EVT_LEN     0x04
+#define PM1_CNT_LEN     0x02
+#define PM2_CNT_LEN     0x01
+#define PM_TM_LEN       0x04
+#define GPE0_BLK_LEN    0x10
+#define GPE1_BLK_LEN    0x00
+#define GPE1_BASE       0x00
+#define CST_CNT         0x00
+#define P_LVL2_LAT      0x0064
+#define P_LVL3_LAT      0x01F4
+#define FLUSH_SIZE      0x0400
+#define FLUSH_STRIDE    0x0010
+#define DUTY_OFFSET     0x01
+#define DUTY_WIDTH      0x03
+#define DAY_ALRM        0x0D
+#define MON_ALRM        0x00
+#define CENTURY         0x32
+#define FLAG            ( EFI_ACPI_4_0_WBINVD | EFI_ACPI_4_0_SLP_BUTTON | EFI_ACPI_4_0_RESET_REG_SUP | EFI_ACPI_4_0_RTC_S4)
+#define IAPC_BOOT_ARCH  ( EFI_ACPI_4_0_VGA_NOT_PRESENT | EFI_ACPI_4_0_8042 | EFI_ACPI_4_0_LEGACY_DEVICES)
+#define RESERVED        0x00
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTables.inf b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTables.inf
new file mode 100644
index 0000000000..170598df7f
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTables.inf
@@ -0,0 +1,40 @@
+## @file
+# Component description file for PlatformAcpiTable module.
+#
+# Build acpi table data required by system boot.
+#  All .asi files tagged with "ToolCode="DUMMY"" in following file list are device description and are included
+#  by top level ASL file which will be dealed with by asl.exe application.
+#
+# Copyright (c)  1999  - 2016, Intel Corporation. All rights reserved
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#
+##
+
+[defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = AcpiTables
+  FILE_GUID                      = 7E374E25-8E01-4FEE-87F2-390C23C606CD
+  MODULE_TYPE                    = USER_DEFINED
+  VERSION_STRING                 = 1.0
+  EDK_RELEASE_VERSION            = 0x00020000
+  EFI_SPECIFICATION_VERSION      = 0x00020000
+
+[sources.common]
+  DSDT.ASL
+  RhProxy.asl
+  Facs/Facs.aslc
+  Facp/Facp.aslc
+  Madt/Madt30.aslc
+  Mcfg/Mcfg.aslc
+  Hpet/Hpet.aslc
+  Lpit/Lpit.aslc
+  Wsmt/Wsmt.aslc
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/CPU.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/CPU.asl
new file mode 100644
index 0000000000..8449ed0d55
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/CPU.asl
@@ -0,0 +1,49 @@
+/**************************************************************************;
+;*                                                                        *;
+;*                                                                        *;
+;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
+;*    Family of Customer Reference Boards.                                *;
+;*                                                                        *;
+;*                                                                        *;
+;*    Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved   *;
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;*                                                                        *;
+;*                                                                        *;
+;**************************************************************************/
+
+
+
+// NOTE:  The _PDC Implementation is out of the scope of this
+// reference code.  Please see the latest Hyper-Threading Technology
+// Reference Code for complete implementation details.
+
+Scope(\_PR)
+{
+  Processor(CPU0,         // Unique name for Processor 0.
+            1,                        // Unique ID for Processor 0.
+            0x00,                 // CPU0 ACPI P_BLK address = ACPIBASE + 10h.
+            0)                        // CPU0  P_BLK length = 6 bytes.
+  {}
+
+  Processor(CPU1,         // Unique name for Processor 1.
+            2,                        // Unique ID for Processor 1.
+            0x00,
+            0)                    // CPU1 P_BLK length = 6 bytes.
+  {}
+
+  Processor(CPU2,         // Unique name for Processor 2.
+            3,                        // Unique ID for Processor 2.
+            0x00,
+            0)                    // CPU2 P_BLK length = 6 bytes.
+  {}
+
+  Processor(CPU3,         // Unique name for Processor 3.
+            4,                        // Unique ID for Processor 3.
+            0x00,
+            0)                    // CPU3 P_BLK length = 6 bytes.
+  {}
+}     // End _PR
+
+
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/DSDT.ASL b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/DSDT.ASL
new file mode 100644
index 0000000000..cbf0d302b1
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/DSDT.ASL
@@ -0,0 +1,75 @@
+/**************************************************************************;
+;*                                                                        *;
+;*                                                                        *;
+;*    Intel Corporation - ACPI Reference Code for the Sandy Bridge        *;
+;*    Family of Customer Reference Boards.                                *;
+;*                                                                        *;
+;*                                                                        *;
+;*    Copyright (c) 2012  - 2015, Intel Corporation. All rights reserved    *;
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;*                                                                        *;
+;*                                                                        *;
+;**************************************************************************/
+
+DefinitionBlock (
+  "DSDT.aml",
+  "DSDT",
+  0x02,  // DSDT revision.
+  "OEMID", // OEM ID (6 byte string)
+  "VLV-SOC", // OEM table ID  (8 byte string)
+  0x0 // OEM version of DSDT table (4 byte Integer)
+)
+
+// BEGIN OF ASL SCOPE
+{
+  External(MDBG, MethodObj)
+
+  Method(ADBG, 1, Serialized)
+  {
+
+    If(CondRefOf(MDBG))   //check if SSDT is loaded
+    {
+      Return(MDBG(Arg0))
+    }
+
+    Return(0)
+  }
+
+
+// Miscellaneous services enabled in Project
+  include ("token.asl")
+  include ("GloblNvs.asl")
+  include ("PciTree.asl")
+  include ("Pch.asl")
+  include ("Vlv.asl")
+  include ("CPU.asl")
+  include ("Platform.asl")
+  include ("THERMAL.ASL")
+  include ("PCI_DRC.ASL")
+  include ("Video.asl")
+  include ("Gpe.asl")
+  //include ("IoTVirtualDevice.asl")
+
+  // Sleep states supported by Chipset/Board.
+  // SSx - BIOS setup controlled enabled _Sx Sleep state status
+  // Values to be written to SLP_TYPE register are provided by SBACPI.SDL (South Bridge ACPI ModulePart)
+
+  Name(\_S0, Package(4) {0x0,0x0,0,0}) // mandatory System state
+  Name(\_S1, Package(4) {0x1,0x0,0,0})
+  Name(\_S3, Package(4) {0x5,0x0,0,0})
+  Name(\_S4, Package(4) {0x6,0x0,0,0})
+  Name(\_S5, Package(4) {0x7,0x0,0,0}) // mandatory System state
+
+  Method(PTS, 1)          // METHOD CALLED FROM _PTS PRIOR TO ENTER ANY SLEEP STATE
+  {
+    If(Arg0)            // entering any sleep state
+    {
+    }
+  }
+  Method(WAK, 1)          // METHOD CALLED FROM _WAK RIGHT AFTER WAKE UP
+  {
+  }
+
+}// End of ASL File
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facp/Facp.aslc b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facp/Facp.aslc
new file mode 100644
index 0000000000..df47144623
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facp/Facp.aslc
@@ -0,0 +1,188 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  Facp.c
+
+
+Abstract: The fixed ACPI description Table (FADT) Structure
+
+
+--*/
+#ifdef ECP_FLAG
+#include "EDKIIGlueDxe.h"
+#else
+#include <PiDxe.h>
+#endif
+#include <IndustryStandard/Acpi50.h>
+#include "AcpiTablePlatform.h"
+
+EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE FACP = {
+  {
+    EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
+    sizeof (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE),
+    EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION,
+    0,                                                                                    // to make sum of entire table == 0
+    EFI_ACPI_OEM_ID,         // OEMID is a 6 bytes long field
+    EFI_ACPI_OEM_TABLE_ID,      // OEM table identification(8 bytes long)
+    EFI_ACPI_OEM_REVISION,      // OEM revision number
+    EFI_ACPI_CREATOR_ID,        // ASL compiler vendor ID
+    EFI_ACPI_CREATOR_REVISION   // ASL compiler revision number
+  },
+  0,                                                                                    // Physical addesss of FACS
+  0,                                                                                    // Physical address of DSDT
+  INT_MODEL,                                                                                    // System Interrupt Model (ignored in 2k and later, must be 0 for 98)
+  PM_PROFILE,                                                                                   // Preferred PM Profile
+  SCI_INT_VECTOR,                                                                       // System vector of SCI interrupt
+  SMI_CMD_IO_PORT,                                                                      // Port address of SMI command port
+  ACPI_ENABLE,                                                                          // value to write to port smi_cmd to enable ACPI
+  ACPI_DISABLE,                                                                         // value to write to port smi_cmd to disable ACPI
+  S4BIOS_REQ,                                                                           // Value to write to SMI CMD port to enter the S4BIOS state
+  PSTATE_CNT,       // PState control
+  PM1a_EVT_BLK,                                                                         // Port address of Power Mgt 1a Event Reg Blk
+  PM1b_EVT_BLK,                                                                         // Port address of Power Mgt 1b Event Reg Blk
+  PM1a_CNT_BLK,                                                                         // Port address of Power Mgt 1a Ctrl Reg Blk
+  PM1b_CNT_BLK,                                                                         // Port address of Power Mgt 1b Ctrl Reg Blk
+  PM2_CNT_BLK,                                                                          // Port address of Power Mgt 2  Ctrl Reg Blk
+  PM_TMR_BLK,                                                                           // Port address of Power Mgt Timer Ctrl Reg Blk
+  GPE0_BLK,                                                                             // Port addr of General Purpose Event 0 Reg Blk
+  GPE1_BLK,                                                                             // Port addr of General Purpose Event 1 Reg Blk
+  PM1_EVT_LEN,                                                                          // Byte Length of ports at pm1X_evt_blk
+  PM1_CNT_LEN,                                                                          // Byte Length of ports at pm1X_cnt_blk
+  PM2_CNT_LEN,                                                                          // Byte Length of ports at pm2_cnt_blk
+  PM_TM_LEN,                                                                            // Byte Length of ports at pm_tm_blk
+  GPE0_BLK_LEN,                                                                         // Byte Length of ports at gpe0_blk
+  GPE1_BLK_LEN,                                                                         // Byte Length of ports at gpe1_blk
+  GPE1_BASE,                                                                            // offset in gpe model where gpe1 events start
+  CST_CNT,          // _CST support
+  P_LVL2_LAT,                                                                           // worst case HW latency to enter/exit C2 state
+  P_LVL3_LAT,                                                                           // worst case HW latency to enter/exit C3 state
+  FLUSH_SIZE,                                                                           // Size of area read to flush caches
+  FLUSH_STRIDE,                                                                         // Stride used in flushing caches
+  DUTY_OFFSET,                                                                          // bit location of duty cycle field in p_cnt reg
+  DUTY_WIDTH,                                                                           // bit width of duty cycle field in p_cnt reg
+  DAY_ALRM,                                                                             // index to day-of-month alarm in RTC CMOS RAM
+  MON_ALRM,                                                                             // index to month-of-year alarm in RTC CMOS RAM
+  CENTURY,                                                                              // index to century in RTC CMOS RAM
+  IAPC_BOOT_ARCH,                                                                       // IA-PCI Boot Architecture Flag
+  RESERVED,                                                                             // reserved
+  FLAG,
+  {
+    EFI_ACPI_5_0_SYSTEM_IO,
+    8,
+    0,
+    0,
+    0xCF9
+  },
+  0x0E,             // Hardware reset value
+  0, 0, 0,          // Reserved
+  0,                // XFirmwareCtrl
+  0,                // XDsdt
+  //
+  // X_PM1a Event Register Block
+  //
+  EFI_ACPI_5_0_SYSTEM_IO,
+  0x20,
+  0x00,
+  EFI_ACPI_3_0_DWORD,
+  PM1a_EVT_BLK,
+
+  //
+  // X_PM1b Event Register Block
+  //
+  EFI_ACPI_5_0_SYSTEM_IO,
+  0x00,
+  0x00,
+  EFI_ACPI_RESERVED_BYTE,
+  PM1b_EVT_BLK,
+
+  //
+  // X_PM1a Control Register Block
+  //
+  EFI_ACPI_5_0_SYSTEM_IO,
+  0x10,
+  0x00,
+  EFI_ACPI_3_0_WORD,
+  PM1a_CNT_BLK,
+
+  //
+  // X_PM1b Control Register Block
+  //
+  EFI_ACPI_5_0_SYSTEM_IO,
+  0x00,
+  0x00,
+  EFI_ACPI_RESERVED_BYTE,
+  PM1b_CNT_BLK,
+
+  //
+  // X_PM2 Control Register Block
+  //
+  EFI_ACPI_5_0_SYSTEM_IO,
+  0x08,
+  0x00,
+  EFI_ACPI_3_0_BYTE,
+  PM2_CNT_BLK,
+
+  //
+  // X_PM Timer Control Register Block
+  //
+  EFI_ACPI_5_0_SYSTEM_IO,
+  0x20,
+  0x00,
+  EFI_ACPI_3_0_DWORD,
+  PM_TMR_BLK,
+
+  //
+  // X_General Purpose Event 0 Register Block
+  //
+  EFI_ACPI_5_0_SYSTEM_IO,
+  0x80,
+  0x00,
+  EFI_ACPI_RESERVED_BYTE,
+  GPE0_BLK,
+
+  //
+  // X_General Purpose Event 1 Register Block
+  //
+  EFI_ACPI_5_0_SYSTEM_IO,
+  0x00,
+  0x00,
+  EFI_ACPI_RESERVED_BYTE,
+  GPE1_BLK,
+
+  //
+  // Sleep Control Register Block
+  //
+  EFI_ACPI_5_0_SYSTEM_IO,
+  0x08,
+  0x00,
+  EFI_ACPI_RESERVED_BYTE,
+  0,
+
+  //
+  // Sleep Status Register Block
+  //
+  EFI_ACPI_5_0_SYSTEM_IO,
+  0x08,
+  0x00,
+  EFI_ACPI_RESERVED_BYTE,
+  0,
+};
+
+VOID*
+ReferenceAcpiTable (
+  VOID
+  )
+{
+  //
+  // Reference the table being generated to prevent the optimizer from
+  // removing the data structure from the executable
+  //
+  return (VOID*)&FACP;
+}
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facs/Facs.aslc b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facs/Facs.aslc
new file mode 100644
index 0000000000..e216f61299
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facs/Facs.aslc
@@ -0,0 +1,84 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  Ea815acpiFACS.c
+
+
+Abstract:
+
+  This file contains the FACS structure definition.
+
+--*/
+
+//
+// Statements that include other files
+//
+#ifdef ECP_FLAG
+#include "EDKIIGlueDxe.h"
+#else
+#include <PiDxe.h>
+#endif
+#include <IndustryStandard/Acpi50.h>
+#include "AcpiTablePlatform.h"
+
+EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE FACS = {
+  EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE,
+  sizeof (EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE),
+
+  //
+  // Hardware Signature will be updated at runtime
+  //
+  0x00000000,                  //HardwareSignature
+  0x00000000,                  //FirmwareWakingVector
+  0x00000000,                  //GlobalLock
+  0x00000000,                  //Flags
+  0x0000000000000000,          //XFirmwareWakingVector
+  EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION,
+  EFI_ACPI_RESERVED_BYTE,      //Reserved0[3]
+  EFI_ACPI_RESERVED_BYTE,
+  EFI_ACPI_RESERVED_BYTE,
+  0x00000000,                  //OspmFlags
+  EFI_ACPI_RESERVED_BYTE,      //Reserved1[24]
+  EFI_ACPI_RESERVED_BYTE,
+  EFI_ACPI_RESERVED_BYTE,
+  EFI_ACPI_RESERVED_BYTE,
+  EFI_ACPI_RESERVED_BYTE,
+  EFI_ACPI_RESERVED_BYTE,
+  EFI_ACPI_RESERVED_BYTE,
+  EFI_ACPI_RESERVED_BYTE,
+  EFI_ACPI_RESERVED_BYTE,
+  EFI_ACPI_RESERVED_BYTE,
+  EFI_ACPI_RESERVED_BYTE,
+  EFI_ACPI_RESERVED_BYTE,
+  EFI_ACPI_RESERVED_BYTE,
+  EFI_ACPI_RESERVED_BYTE,
+  EFI_ACPI_RESERVED_BYTE,
+  EFI_ACPI_RESERVED_BYTE,
+  EFI_ACPI_RESERVED_BYTE,
+  EFI_ACPI_RESERVED_BYTE,
+  EFI_ACPI_RESERVED_BYTE,
+  EFI_ACPI_RESERVED_BYTE,
+  EFI_ACPI_RESERVED_BYTE,
+  EFI_ACPI_RESERVED_BYTE,
+  EFI_ACPI_RESERVED_BYTE,
+  EFI_ACPI_RESERVED_BYTE
+};
+
+VOID*
+ReferenceAcpiTable (
+  VOID
+  )
+{
+  //
+  // Reference the table being generated to prevent the optimizer from
+  // removing the data structure from the executable
+  //
+  return (VOID*)&FACS;
+}
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/GloblNvs.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/GloblNvs.asl
new file mode 100644
index 0000000000..513fa95e46
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/GloblNvs.asl
@@ -0,0 +1,348 @@
+/**************************************************************************;
+;*                                                                        *;
+;*                                                                        *;
+;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
+;*    Family of Customer Reference Boards.                                *;
+;*                                                                        *;
+;*                                                                        *;
+;*    Copyright (c)  1999  - 2016, Intel Corporation. All rights reserved   *;
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;*                                                                        *;
+;*                                                                        *;
+;**************************************************************************/
+
+
+
+// Define a Global region of ACPI NVS Region that may be used for any
+// type of implementation.  The starting offset and size will be fixed
+// up by the System BIOS during POST.  Note that the Size must be a word
+// in size to be fixed up correctly.
+
+OperationRegion(GNVS,SystemMemory,0xFFFF0000,0xAA55)
+Field(GNVS,AnyAcc,Lock,Preserve)
+{
+  Offset(0),       // Miscellaneous Dynamic Registers:
+  OSYS,   16,      //   (00) Operating System
+      ,   8,       //   (02)
+      ,   8,       //   (03)
+      ,   8,       //   (04)
+      ,   8,       //   (05)
+      ,   8,       //   (06)
+      ,   8,       //   (07)
+      ,   8,       //   (08)
+      ,   8,       //   (09)
+      ,   8,       //   (10)
+  P80D,   32,      //   (11) Port 80 Debug Port Value
+  LIDS,   8,       //   (15) Lid State (Lid Open = 1)
+      ,   8,       //   (16)
+      ,   8,       //   (17)
+  Offset(18),      // Thermal Policy Registers:
+      ,   8,       //   (18)
+      ,   8,       //   (19)
+  ACTT,   8,       //   (20) Active Trip Point
+  PSVT,   8,       //   (21) Passive Trip Point
+  TC1V,   8,       //   (22) Passive Trip Point TC1 Value
+  TC2V,   8,       //   (23) Passive Trip Point TC2 Value
+  TSPV,   8,       //   (24) Passive Trip Point TSP Value
+  CRTT,   8,       //   (25) Critical Trip Point
+  DTSE,   8,       //   (26) Digital Thermal Sensor Enable
+  DTS1,   8,       //   (27) Digital Thermal Sensor 1 Reading
+  DTS2,   8,       //   (28) Digital Thermal Sensor 2 Reading
+  DTSF,   8,       //   (29) DTS SMI Function Call
+  Offset(30),      // Battery Support Registers:
+      ,   8,       //   (30)
+      ,   8,       //   (31)
+      ,   8,       //   (32)
+      ,   8,       //   (33)
+      ,   8,       //   (34)
+      ,   8,       //   (35)
+      ,   8,       //   (36)
+  Offset(40),      // CPU Identification Registers:
+  APIC,   8,       //   (40) APIC Enabled by SBIOS (APIC Enabled = 1)
+  MPEN,   8,       //   (41) Number of Logical Processors if MP Enabled != 0
+      ,   8,       //   (42)
+      ,   8,       //   (43)
+      ,   8,       //   (44)
+      ,   32,      //   (45)
+  Offset(50),      // SIO CMOS Configuration Registers:
+      ,   8,       //   (50)
+      ,   8,       //   (51)
+      ,   8,       //   (52)
+      ,   8,       //   (53)
+      ,   8,       //   (54)
+      ,   8,       //   (55)
+      ,   8,       //   (56)
+      ,   8,       //   (57)
+      ,   8,       //   (58)
+  Offset(60),      // Internal Graphics Registers:
+      ,   8,       //   (60)
+      ,   8,       //   (61)
+  CADL,   8,       //   (62) Current Attached Device List
+      ,   8,       //   (63)
+  CSTE,   16,      //   (64) Current Display State
+  NSTE,   16,      //   (66) Next Display State
+      ,   16,      //   (68)
+  NDID,   8,       //   (70) Number of Valid Device IDs
+  DID1,   32,      //   (71) Device ID 1
+  DID2,   32,      //   (75) Device ID 2
+  DID3,   32,      //   (79) Device ID 3
+  DID4,   32,      //   (83) Device ID 4
+  DID5,   32,      //   (87) Device ID 5
+      ,   32,      //   (91)
+      ,   8,       //   (95) Fifth byte of AKSV (mannufacturing mode)
+  Offset(103),     // Backlight Control Registers:
+      ,   8,       //   (103)
+  BRTL,   8,       //   (104) Brightness Level Percentage
+  Offset(105),     // Ambiant Light Sensor Registers:
+      ,   8,       //   (105)
+      ,   8,       //   (106)
+  LLOW,   8,       //   (107) LUX Low Value
+      ,   8,       //   (108)
+  Offset(110),     // EMA Registers:
+      ,   8,       //   (110)
+      ,   16,      //   (111)
+      ,   16,      //   (113)
+  Offset(116),     // MEF Registers:
+      ,   8,       //   (116) MEF Enable
+  Offset(117),     // PCIe Dock:
+      ,   8,       //   (117)
+  Offset(120),     // TPM Registers:
+      ,   8,       //   (120)
+      ,   8,       //   (121)
+      ,   8,       //   (122)
+      ,   8,       //   (123)
+      ,   32,      //   (124)
+      ,   8,       //   (125)
+      ,   8,       //   (129)
+  Offset(130),     //
+      ,   56,      //   (130)
+      ,   56,      //   (137)
+      ,   8,       //   (144)
+      ,   56,      //   (145)
+  Offset(170),     // IGD OpRegion/Software SCI base address
+  ASLB,   32,      //   (170) IGD OpRegion base address
+  Offset(174),     // IGD OpRegion/Software SCI shared data
+  IBTT,   8,       //   (174) IGD Boot Display Device
+  IPAT,   8,       //   (175) IGD Panel Type CMOs option
+  ITVF,   8,       //   (176) IGD TV Format CMOS option
+  ITVM,   8,       //   (177) IGD TV Minor Format CMOS option
+  IPSC,   8,       //   (178) IGD Panel Scaling
+  IBLC,   8,       //   (179) IGD BLC Configuration
+  IBIA,   8,       //   (180) IGD BIA Configuration
+  ISSC,   8,       //   (181) IGD SSC Configuration
+  I409,   8,       //   (182) IGD 0409 Modified Settings Flag
+  I509,   8,       //   (183) IGD 0509 Modified Settings Flag
+  I609,   8,       //   (184) IGD 0609 Modified Settings Flag
+  I709,   8,       //   (185) IGD 0709 Modified Settings Flag
+  IDMM,   8,       //   (186) IGD DVMT Mode
+  IDMS,   8,       //   (187) IGD DVMT Memory Size
+  IF1E,   8,       //   (188) IGD Function 1 Enable
+  HVCO,   8,       //   (189) HPLL VCO
+  NXD1,   32,      //   (190) Next state DID1 for _DGS
+  NXD2,   32,      //   (194) Next state DID2 for _DGS
+  NXD3,   32,      //   (198) Next state DID3 for _DGS
+  NXD4,   32,      //   (202) Next state DID4 for _DGS
+  NXD5,   32,      //   (206) Next state DID5 for _DGS
+  NXD6,   32,      //   (210) Next state DID6 for _DGS
+  NXD7,   32,      //   (214) Next state DID7 for _DGS
+  NXD8,   32,      //   (218) Next state DID8 for _DGS
+  GSMI,   8,       //   (222) GMCH SMI/SCI mode (0=SCI)
+  PAVP,   8,       //   (223) IGD PAVP data
+  Offset(225),
+  OSCC,   8,       //   (225) PCIE OSC Control
+  NEXP,   8,       //   (226) Native PCIE Setup Value
+  Offset(235), // Global Variables
+  DSEN,   8,       //   (235) _DOS Display Support Flag.
+  ECON,   8,       //   (236) Embedded Controller Availability Flag.
+  GPIC,   8,       //   (237) Global IOAPIC/8259 Interrupt Mode Flag.
+  CTYP,   8,       //   (238) Global Cooling Type Flag.
+  L01C,   8,       //   (239) Global L01 Counter.
+  VFN0,   8,       //   (240) Virtual Fan0 Status.
+  VFN1,   8,       //   (241) Virtual Fan1 Status.
+  Offset(256),
+  NVGA,   32,  //   (256) NVIG opregion address
+  NVHA,   32,  //   (260) NVHM opregion address
+  AMDA,   32,  //   (264) AMDA opregion address
+  DID6,   32,  //   (268) Device ID 6
+  DID7,   32,  //   (272) Device ID 7
+  DID8,   32,  //   (276) Device ID 8
+  Offset(332),
+  USEL,   8,    // (332) UART Selection
+  PU1E,   8,    // (333) PCU UART 1 Enabled
+  PU2E,   8,    // (334) PCU UART 2 Enabled
+
+  LPE0, 32,     // (335) LPE Bar0
+  LPE1, 32,     // (339) LPE Bar1
+  LPE2, 32,     // (343) LPE Bar2
+
+  Offset(347),
+      ,   8,    // (347)
+      ,   8,    // (348)
+  PFLV,   8,    // (349) Platform Flavor
+
+  Offset(351),
+  ICNF,   8,   //   (351) ISCT / AOAC Configuration
+  XHCI,   8,   //   (352) xHCI controller mode
+  PMEN,   8,   //   (353) PMIC enable/disable
+
+  LPEE,   8,   //   (354) LPE enable/disable
+  ISPA,   32,  //   (355) ISP Base Addr
+  ISPD,   8,    //  (359) ISP Device Selection 0: Disabled; 1: PCI Device 2; 2: PCI Device 3
+
+  offset(360),  // ((4+8+6)*4+2)*4=296
+  //
+  // Lpss controllers
+  //
+  PCIB,     32,
+  PCIT,     32,
+  D10A,     32,  //DMA1
+  D10L,     32,
+  D11A,     32,
+  D11L,     32,
+  P10A,     32,  //  PWM1
+  P10L,     32,
+  P11A,     32,
+  P11L,     32,
+  P20A,     32,  //  PWM2
+  P20L,     32,
+  P21A,     32,
+  P21L,     32,
+  U10A,     32,  // UART1
+  U10L,     32,
+  U11A,     32,
+  U11L,     32,
+  U20A,     32,  // UART2
+  U20L,     32,
+  U21A,     32,
+  U21L,     32,
+  SP0A,     32,  // SPI
+  SP0L,     32,
+  SP1A,     32,
+  SP1L,     32,
+
+  D20A,     32,  //DMA2
+  D20L,     32,
+  D21A,     32,
+  D21L,     32,
+  I10A,     32,  //  I2C1
+  I10L,     32,
+  I11A,     32,
+  I11L,     32,
+  I20A,     32,  //  I2C2
+  I20L,     32,
+  I21A,     32,
+  I21L,     32,
+  I30A,     32,  //  I2C3
+  I30L,     32,
+  I31A,     32,
+  I31L,     32,
+  I40A,     32,  //  I2C4
+  I40L,     32,
+  I41A,     32,
+  I41L,     32,
+  I50A,     32,  //  I2C5
+  I50L,     32,
+  I51A,     32,
+  I51L,     32,
+  I60A,     32,  //  I2C6
+  I60L,     32,
+  I61A,     32,
+  I61L,     32,
+  I70A,     32,  //  I2C7
+  I70L,     32,
+  I71A,     32,
+  I71L,     32,
+  //
+  // Scc controllers
+  //
+  eM0A,     32,  //  EMMC
+  eM0L,     32,
+  eM1A,     32,
+  eM1L,     32,
+  SI0A,     32,  //  SDIO
+  SI0L,     32,
+  SI1A,     32,
+  SI1L,     32,
+  SD0A,     32,  //  SDCard
+  SD0L,     32,
+  SD1A,     32,
+  SD1L,     32,
+  MH0A,     32,  //
+  MH0L,     32,
+  MH1A,     32,
+  MH1L,     32,
+
+  offset(656),
+  SDRM,     8,
+  offset(657),
+  HLPS,     8,   //(657) Hide Devices
+  offset(658),
+  OSEL,     8,      //(658) OS Seletion - Windows/Android
+
+  offset(659),  // VLV1 DPTF
+  SDP1,     8,      //(659) An enumerated value corresponding to SKU
+  DPTE,     8,      //(660) DPTF Enable
+  THM0,     8,      //(661) System Thermal 0
+  THM1,     8,      //(662) System Thermal 1
+  THM2,     8,      //(663) System Thermal 2
+  THM3,     8,      //(664) System Thermal 3
+  THM4,     8,      //(665) System Thermal 3
+  CHGR,     8,      //(666) DPTF Changer Device
+  DDSP,     8,      //(667) DPTF Display Device
+  DSOC,     8,      //(668) DPTF SoC device
+  DPSR,     8,      //(669) DPTF Processor device
+  DPCT,     32,     //(670) DPTF Processor participant critical temperature
+  DPPT,     32,     //(674) DPTF Processor participant passive temperature
+  DGC0,     32,     //(678) DPTF Generic sensor0 participant critical temperature
+  DGP0,     32,     //(682) DPTF Generic sensor0 participant passive temperature
+  DGC1,     32,     //(686) DPTF Generic sensor1 participant critical temperature
+  DGP1,     32,     //(690) DPTF Generic sensor1 participant passive temperature
+  DGC2,     32,     //(694) DPTF Generic sensor2 participant critical temperature
+  DGP2,     32,     //(698) DPTF Generic sensor2 participant passive temperature
+  DGC3,     32,     //(702) DPTF Generic sensor3 participant critical temperature
+  DGP3,     32,     //(706) DPTF Generic sensor3 participant passive temperature
+  DGC4,     32,     //(710)DPTF Generic sensor3 participant critical temperature
+  DGP4,     32,     //(714)DPTF Generic sensor3 participant passive temperature
+  DLPM,     8,      //(718) DPTF Current low power mode setting
+  DSC0,     32,     //(719) DPTF Critical threshold0 for SCU
+  DSC1,     32,     //(723) DPTF Critical threshold1 for SCU
+  DSC2,     32,     //(727) DPTF Critical threshold2 for SCU
+  DSC3,     32,     //(731) DPTF Critical threshold3 for SCU
+  DSC4,     32,     //(735) DPTF Critical threshold3 for SCU
+  DDBG,     8,      //(739) DPTF Super Debug option. 0 - Disabled, 1 - Enabled
+  LPOE,     32,     //(740) DPTF LPO Enable
+  LPPS,     32,     //(744) P-State start index
+  LPST,     32,     //(748) Step size
+  LPPC,     32,     //(752) Power control setting
+  LPPF,     32,     //(756) Performance control setting
+  DPME,     8,      //(760) DPTF DPPM enable/disable
+  BCSL,     8,      //(761) Battery charging solution 0-CLV 1-ULPMC
+  NFCS,     8,      //(762) NFCx Select 1: NFC1    2:NFC2
+  PCIM,     8,      //(763) EMMC device 0-ACPI mode, 1-PCI mode
+  TPMA,     32,     //(764)
+  TPML,     32,     //(768)
+  ITSA,      8,     //(772) I2C Touch Screen Address
+  S0IX,     8,      //(773) S0ix status
+  SDMD,     8,      //(774) SDIO Mode
+  EMVR,     8,      //(775) eMMC controller version
+  BMBD,     32,     //(776) BM Bound
+  FSAS,     8,      //(780) FSA Status
+  BDID,     8,      //(781) Board ID
+  FBID,     8,      //(782) FAB ID
+  OTGM,     8,      //(783) OTG mode
+  STEP,     8,      //(784) Stepping ID
+  WITT,     8,      //(785) Enable Test Device connected to I2C for WHCK test.
+  SOCS,     8,      //(786) provide the SoC stepping infomation
+  AMTE,     8,      //(787) Ambient Trip point change
+  UTS,      8,      //(788) Enable Test Device connected to URT for WHCK test.
+  SCPE,     8,      //(789) Allow higher performance on AC/USB - Enable/Disable
+  Offset(792),
+  EDPV,     8,      //(792) Check for eDP display device
+  DIDX,     32,     //(793) Device ID for eDP device
+  IOT,      8,      //(794) MinnowBoard Max JP1 is configured for MSFT IOT project.
+  BATT,     8,      //(795) The Flag of RTC Battery Prensent.
+  LPAD,     8,      //(796)
+}
+
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Gpe.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Gpe.asl
new file mode 100644
index 0000000000..c3c9cb6315
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Gpe.asl
@@ -0,0 +1,99 @@
+/**************************************************************************;
+;*                                                                        *;
+;*                                                                        *;
+;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
+;*    Family of Customer Reference Boards.                                *;
+;*                                                                        *;
+;*                                                                        *;
+;*    Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved    *;
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;*                                                                        *;
+;*                                                                        *;
+;**************************************************************************/
+
+
+// General Purpose Events.  This Scope handles the Run-time and
+// Wake-time SCIs.  The specific method called will be determined by
+// the _Lxx value, where xx equals the bit location in the General
+// Purpose Event register(s).
+
+Scope(\_GPE)
+{
+  //
+  // Software GPE caused the event.
+  //
+  Method(_L02)
+  {
+    // Clear GPE status bit.
+    Store(0,GPEC)
+    //
+    // Handle DTS Thermal Events.
+    //
+    External(DTSE, IntObj)
+    If(CondRefOf(DTSE))
+    {
+      If(LGreaterEqual(DTSE, 0x01))
+      {
+        Notify(\_TZ.TZ01,0x80)
+      }
+    }
+  }
+
+  //
+  // PUNIT SCI event.
+  //
+  Method(_L04)
+  {
+    // Clear the PUNIT Status Bit.
+    Store(1, PSCI)
+  }
+
+
+  //
+  // IGD OpRegion SCI event (see IGD OpRegion/Software SCI BIOS SPEC).
+  //
+  Method(_L05)
+  {
+    If(LAnd(\_SB.PCI0.GFX0.GSSE, LNot(GSMI)))   // Graphics software SCI event?
+    {
+      \_SB.PCI0.GFX0.GSCI()     // Handle the SWSCI
+    }
+  }
+
+  //
+  // This PME event (PCH's GPE #13) is received when any PCH internal device with PCI Power Management capabilities
+  // on bus 0 asserts the equivalent of the PME# signal.
+  //
+  Method(_L0D, 0)
+  {
+    If(LAnd(\_SB.PCI0.EHC1.PMEE, \_SB.PCI0.EHC1.PMES))
+    {
+      If(LNotEqual(OSEL, 1))
+      {
+        Store(1, \_SB.PCI0.EHC1.PMES) //Clear PME status
+        Store(0, \_SB.PCI0.EHC1.PMEE) //Disable PME
+      }
+      Notify(\_SB.PCI0.EHC1, 0x02)
+    }
+    If(LAnd(\_SB.PCI0.XHC1.PMEE, \_SB.PCI0.XHC1.PMES))
+    {
+      If(LNotEqual(OSEL, 1))
+      {
+        Store(1, \_SB.PCI0.XHC1.PMES) //Clear PME status
+        Store(0, \_SB.PCI0.XHC1.PMEE) //Disable PME
+      }
+      Notify(\_SB.PCI0.XHC1, 0x02)
+    }
+    If(LAnd(\_SB.PCI0.HDEF.PMEE, \_SB.PCI0.HDEF.PMES))
+    {
+      If(LNotEqual(OSEL, 1))
+      {
+        Store(1, \_SB.PCI0.HDEF.PMES) //Clear PME status
+        Store(0, \_SB.PCI0.HDEF.PMEE) //Disable PME
+      }
+      Notify(\_SB.PCI0.HDEF, 0x02)
+    }
+  }
+}
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/HOST_BUS.ASL b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/HOST_BUS.ASL
new file mode 100644
index 0000000000..6b0c2a349f
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/HOST_BUS.ASL
@@ -0,0 +1,347 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  HOST_BUS.ASL
+
+Abstract:
+
+  Baytrail PCI configuration space definition.
+
+---*/
+Device(VLVC)
+{
+  Name(_ADR, 0x00000000)           // Device 0, Function 0
+
+  // Define various MCH Controller PCI Configuration Space
+  // registers which will be used to dynamically produce all
+  // resources in the Host Bus _CRS.
+  OperationRegion(HBUS, PCI_Config, 0x00, 0xFF)
+  Field(HBUS, DWordAcc, NoLock, Preserve)
+  {
+    Offset(0xD0),
+    SMCR,   32,             // VLV Message Control Register (0xD0)
+    Offset(0xD4),
+    SMDR,   32,             // VLV Message Data Register (0xD4)
+    Offset(0xD8),
+    MCRX,   32,             // VLV Message Control Register Extension (0xD8)
+  }
+
+  // Define a method to read a 32-bit register on the VLV Message bus.
+  //  Arg0 = Port
+  //  Arg1 = Register
+  //
+  //  Returns 32-bit register value
+
+  Method(RMBR, 2, Serialized)
+  {
+
+    // Initiate regsiter read message on VLV Message Bus MCR
+
+    Or(ShiftLeft(Arg0, 16), ShiftLeft(Arg1, 8), Local0)
+    Or(0x100000F0, Local0, SMCR)
+
+    // Read register value from Message Data Register
+
+    Return(SMDR)
+  }
+
+
+  // Define a method to write a 32-bit register on the VLV Message bus MDR.
+  //  Arg0 = Port
+  //  Arg1 = Register
+  //  Arg2 = 32-bit value
+
+  Method(WMBR, 3, Serialized)
+  {
+
+    // Write register value to Message Data Register
+
+    Store(Arg2, SMDR)
+
+    // Initiate register write message on VLV Message Bus
+
+    Or(ShiftLeft(Arg0, 16), ShiftLeft(Arg1, 8), Local0)
+    Or(0x110000F0, Local0, SMCR)
+  }
+}
+
+//
+// BUS, I/O, and MMIO resources
+//
+Method(_CRS,0,Serialized)
+{
+  //Update ISP0 reserved memory
+  CreateDwordField(RES0, ^ISP0._MIN,ISMN)
+  CreateDwordField(RES0, ^ISP0._MAX,ISMX)
+  CreateDwordField(RES0, ^ISP0._LEN,ISLN)
+  If (LEqual(ISPD,1))
+  {
+    Store (ISPA, ISMN)
+    Add (ISMN, ISLN, ISMX)
+    Subtract(ISMX, 1, ISMX)
+  } Else
+  {
+    Store (0, ISMN)
+    Store (0, ISMX)
+    Store (0, ISLN)
+  }
+
+  //PCI MMIO SPACE
+  CreateDwordField(RES0, ^PM01._MIN,M1MN)
+  CreateDwordField(RES0, ^PM01._MAX,M1MX)
+  CreateDwordField(RES0, ^PM01._LEN,M1LN)
+
+  //Get dBMBOUND Base
+  And(BMBD, 0xFF000000, M1MN)
+
+  //Get ECBASE
+  Store(PCIT, M1MX)
+  Add(Subtract(M1MX, M1MN), 1, M1LN)
+  Subtract(M1MX, 1, M1MX)
+
+  // Create pointers to Gfx Stolen Memory Sizing values.
+  CreateDwordField(RES0, ^STOM._MIN,GSMN)
+  CreateDwordField(RES0, ^STOM._MAX,GSMX)
+  CreateDwordField(RES0, ^STOM._LEN,GSLN)
+
+  If (LNotEqual (\_SB.PCI0.GFX0.GSTM, 0xFFFFFFFF))
+  {
+    Store(0x00, GSMN) //Read the Stolen memory base from B0:D2:F0:R5C
+  } else
+  {
+    Store(\_SB.PCI0.GFX0.GSTM, GSMN) //Read the Stolen memory base from B0:D2:F0:R5C
+  }
+  If (LNotEqual (\_SB.PCI0.GFX0.GUMA, 0xFFFFFFFF))
+  {
+    Store(0x00, GSLN) //Read the Stolen memory base from B0:D2:F0:R5C
+  } else
+  {
+    ShiftLeft(\_SB.PCI0.GFX0.GUMA, 25, GSLN) //Read Stolen memory base form B0:D2:F0:R50
+  }
+  Add(GSMN, GSLN, GSMX) //Store the Stolen Memory Size
+  Subtract(GSMX, 1, GSMX)
+
+  Return(RES0)
+}
+
+Name( RES0,ResourceTemplate()
+{
+  WORDBusNumber (          // Bus number resource (0); the bridge produces bus numbers for its subsequent buses
+    ResourceProducer,      // bit 0 of general flags is 1
+    MinFixed,              // Range is fixed
+    MaxFixed,              // Range is fixed
+    PosDecode,             // PosDecode
+    0x0000,                // Granularity
+    0x0000,                // Min
+    0x00FF,                // Max
+    0x0000,                // Translation
+    0x0100                 // Range Length = Max-Min+1
+  )
+
+  IO (Decode16, 0x70, 0x77, 0x01, 0x08)         //Consumed resource (0xCF8-0xCFF)
+  IO (Decode16, 0xCF8, 0xCF8, 0x01, 0x08)       //Consumed resource (0xCF8-0xCFF)
+
+  WORDIO (                 // Consumed-and-produced resource (all I/O below CF8)
+    ResourceProducer,      // bit 0 of general flags is 0
+    MinFixed,              // Range is fixed
+    MaxFixed,              // Range is fixed
+    PosDecode,
+    EntireRange,
+    0x0000,                // Granularity
+    0x0000,                // Min
+    0x006F,                // Max
+    0x0000,                // Translation
+    0x0070                 // Range Length
+  )
+
+  WORDIO (                 // Consumed-and-produced resource
+    ResourceProducer,      // bit 0 of general flags is 0
+    MinFixed,              // Range is fixed
+    MaxFixed,              // Range is fixed
+    PosDecode,
+    EntireRange,
+    0x0000,                // Granularity
+    0x0078,                // Min
+    0x0CF7,                // Max
+    0x0000,                // Translation
+    0x0C80                 // Range Length
+  )
+
+  WORDIO (                 // Consumed-and-produced resource (all I/O above CFF)
+    ResourceProducer,      // bit 0 of general flags is 0
+    MinFixed,              // Range is fixed
+    MaxFixed,              // Range is fixed
+    PosDecode,
+    EntireRange,
+    0x0000,                // Granularity
+    0x0D00,                // Min
+    0xFFFF,                // Max
+    0x0000,                // Translation
+    0xF300                 // Range Length
+  )
+
+  DWORDMEMORY (            // Descriptor for legacy VGA video RAM
+    ResourceProducer,      // bit 0 of general flags is 0
+    PosDecode,
+    MinFixed,              // Range is fixed
+    MaxFixed,              // Range is fixed
+    Cacheable,
+    ReadWrite,
+    0x00000000,            // Granularity
+    0x000A0000,            // Min
+    0x000BFFFF,            // Max
+    0x00000000,            // Translation
+    0x00020000             // Range Length
+  )
+
+  DWORDMEMORY (            // Descriptor for legacy OptionRom
+    ResourceProducer,      // bit 0 of general flags is 0
+    PosDecode,
+    MinFixed,              // Range is fixed
+    MaxFixed,              // Range is fixed
+    Cacheable,
+    ReadWrite,
+    0x00000000,            // Granularity
+    0x000C0000,            // Min
+    0x000DFFFF,            // Max
+    0x00000000,            // Translation
+    0x00020000             // Range Length
+  )
+
+  DWORDMEMORY (            // Descriptor for BIOS Area
+    ResourceProducer,      // bit 0 of general flags is 0
+    PosDecode,
+    MinFixed,              // Range is fixed
+    MaxFixed,              // Range is fixed
+    Cacheable,
+    ReadWrite,
+    0x00000000,            // Granularity
+    0x000E0000,            // Min
+    0x000FFFFF,            // Max
+    0x00000000,            // Translation
+    0x00020000             // Range Length
+  )
+
+  DWORDMEMORY (            // Descriptor for ISP0 reserved Mem
+    ResourceProducer,      // bit 0 of general flags is 0
+    PosDecode,
+    MinFixed,              // Range is fixed
+    MaxFixed,              // Range is fixed
+    Cacheable,
+    ReadWrite,
+    0x00000000,            // Granularity
+    0x7A000000,            // Min
+    0x7A3FFFFF,            // Max
+    0x00000000,            // Translation
+    0x00400000             // Range Length
+    ,,,
+    ISP0
+  )
+
+  DWORDMEMORY (            // Descriptor for VGA Stolen Mem
+    ResourceProducer,      // bit 0 of general flags is 0
+    PosDecode,
+    MinFixed,              // Range is fixed
+    MaxFixed,              // Range is fixed
+    Cacheable,
+    ReadWrite,
+    0x00000000,            // Granularity
+    0x7C000000,            // Min
+    0x7FFFFFFF,            // Max
+    0x00000000,            // Translation
+    0x04000000             // Range Length
+    ,,,
+    STOM
+  )
+
+  DWORDMEMORY (            // Descriptor for PCI MMIO
+    ResourceProducer,      // bit 0 of general flags is 0
+    PosDecode,
+    MinFixed,              // Range is fixed
+    MaxFixed,              // Range is fixed
+    Cacheable,
+    ReadWrite,
+    0x00000000,            // Granularity
+    0x80000000,            // Min
+    0xDFFFFFFF,            // Max
+    0x00000000,            // Translation
+    0x60000000             // Range Length
+    ,,,
+    PM01
+  )
+})
+
+//Name(GUID,UUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))
+Name(GUID,Buffer()
+{
+  0x5b, 0x4d, 0xdb, 0x33,
+  0xf7, 0x1f,
+  0x1c, 0x40,
+  0x96, 0x57,
+  0x74, 0x41, 0xc0, 0x3d, 0xd7, 0x66
+})
+
+
+Name(SUPP,0)    // PCI _OSC Support Field value
+Name(CTRL,0)    // PCI _OSC Control Field value
+
+Method(_OSC,4,Serialized)
+{
+  // Check for proper UUID
+  // Save the capabilities buffer
+  Store(Arg3,Local0)
+
+  // Create DWord-adressable fields from the Capabilties Buffer
+  CreateDWordField(Local0,0,CDW1)
+  CreateDWordField(Local0,4,CDW2)
+  CreateDWordField(Local0,8,CDW3)
+
+  // Check for proper UUID
+  If(LAnd(LEqual(Arg0,GUID),NEXP))
+  {
+    // Save Capabilities DWord2 & 3
+    Store(CDW2,SUPP)
+    Store(CDW3,CTRL)
+
+    If(Not(And(CDW1,1)))    // Query flag clear?
+    {
+      // Disable GPEs for features granted native control.
+      If(And(CTRL,0x02))
+      {
+        NHPG()
+      }
+      If(And(CTRL,0x04))      // PME control granted?
+      {
+        NPME()
+      }
+    }
+
+    If(LNotEqual(Arg1,One))
+    {
+      // Unknown revision
+      Or(CDW1,0x08,CDW1)
+    }
+
+    If(LNotEqual(CDW3,CTRL))
+    {
+      // Capabilities bits were masked
+      Or(CDW1,0x10,CDW1)
+    }
+    // Update DWORD3 in the buffer
+	And(CTRL,0xfe,CTRL)                
+    Store(CTRL,CDW3)
+    Store(CTRL,OSCC)
+    Return(Local0)
+  } Else
+  {
+    Or(CDW1,4,CDW1)         // Unrecognized UUID
+    Return(Local0)
+  }
+}       // End _OSC
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Hpet/Hpet.aslc b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Hpet/Hpet.aslc
new file mode 100644
index 0000000000..ecbe51e6b0
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Hpet/Hpet.aslc
@@ -0,0 +1,63 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  Hpet.c
+
+Abstract:
+
+  This file contains a structure definition for the ACPI HPET Table.
+--*/
+
+//
+// Statements that include other files
+//
+#ifdef ECP_FLAG
+#include <Tiano.h>
+#endif
+#include <Hpet.h>
+#include "AcpiTablePlatform.h"
+
+// Hpet Table
+EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER HPET = {
+  {
+    EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE,
+    sizeof (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER),
+    EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_REVISION,
+    0,                          // to make sum of entire table == 0
+    EFI_ACPI_OEM_ID,            // OEMID is a 6 bytes long field
+    EFI_ACPI_OEM_TABLE_ID,      // OEM table identification(8 bytes long)
+    EFI_ACPI_OEM_REVISION,      // OEM revision
+    EFI_ACPI_CREATOR_ID,        // ASL compiler vendor ID
+    EFI_ACPI_CREATOR_REVISION   // ASL compiler revision number
+  },
+  0x0,                          // EventTimerBlockId
+  {
+    0x00,                     // Address_Space_ID = System Memory
+    0x40,                     // Register_Bit_Width = 32 bits, mentioned about write failures when in 64bit in SCU HAS
+    0x00,                     // Register_Bit_offset
+    0x00,                     // Dword access
+    HPET_BASE_ADDRESS,        // Base addresse of HPET
+  },
+  0x0,                          // Only HPET's _UID in Namespace
+  MAIN_COUNTER_MIN_PERIODIC_CLOCK_TICKS,
+  0x0
+};
+
+VOID*
+ReferenceAcpiTable (
+  VOID
+  )
+{
+  //
+  // Reference the table being generated to prevent the optimizer from
+  // removing the data structure from the executable
+  //
+  return (VOID*)&HPET;
+}
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELGFX.ASL b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELGFX.ASL
new file mode 100644
index 0000000000..a2ba398568
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELGFX.ASL
@@ -0,0 +1,879 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  INTELGFX.ASL
+
+Abstract:
+
+  IGD OpRegion/Software ACPI Reference Code for the Baytrail Family.
+
+--*/
+
+// Enable/Disable Output Switching.  In WIN2K/WINXP, _DOS = 0 will
+// get called during initialization to prepare for an ACPI Display
+// Switch Event.  During an ACPI Display Switch, the OS will call
+// _DOS = 2 immediately after a Notify=0x80 to temporarily disable
+// all Display Switching.  After ACPI Display Switching is complete,
+// the OS will call _DOS = 0 to re-enable ACPI Display Switching.
+
+Method(_DOS,1)
+{
+  // Store Display Switching and LCD brightness BIOS control bit
+  Store(And(Arg0,7),DSEN)
+}
+
+// Enumerate the Display Environment.  This method will return
+// valid addresses for all display device encoders present in the
+// system.  The Miniport Driver will reject the addresses for every
+// encoder that does not have an attached display device.  After
+// enumeration is complete, the OS will call the _DGS methods
+// during a display switch only for the addresses accepted by the
+// Miniport Driver.  For hot-insertion and removal of display
+// devices, a re-enumeration notification will be required so the
+// address of the newly present display device will be accepted by
+// the Miniport Driver.
+
+Method(_DOD, 0, Serialized)
+{
+  Store(0, NDID)
+  If(LNotEqual(DIDL, Zero))
+  {
+    Store(SDDL(DIDL),DID1)
+  }
+  If(LNotEqual(DDL2, Zero))
+  {
+    Store(SDDL(DDL2),DID2)
+  }
+  If(LNotEqual(DDL3, Zero))
+  {
+    Store(SDDL(DDL3),DID3)
+  }
+  If(LNotEqual(DDL4, Zero))
+  {
+    Store(SDDL(DDL4),DID4)
+  }
+  If(LNotEqual(DDL5, Zero))
+  {
+    Store(SDDL(DDL5),DID5)
+  }
+
+  // TODO - This level of flexibility is not needed for a true
+  //      OEM design.  Simply determine the greatest number of
+  //      encoders the platform will suppport then remove all
+  //      return packages beyond that value.  Note that for
+  //      current silicon, the maximum number of encoders
+  //      possible is 5.
+
+  If(LEqual(NDID,1))
+  {
+    If (LNOTEqual (ISPD, 0))
+    {
+      Name(TMP0,Package() {0xFFFFFFFF,0xFFFFFFFF})
+      Store(Or(0x10000,DID1),Index(TMP0,0))
+      //Add ISP device to GFX0
+      Store(0x00020F38, Index(TMP0,1))
+      Return(TMP0)
+    } Else
+    {
+      Name(TMP1,Package() {0xFFFFFFFF})
+      Store(Or(0x10000,DID1),Index(TMP1,0))
+      Return(TMP1)
+    }
+  }
+
+  If(LEqual(NDID,2))
+  {
+    If (LNOTEqual (ISPD, 0))
+    {
+      Name(TMP2,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+      Store(Or(0x10000,DID1),Index(TMP2,0))
+      Store(Or(0x10000,DID2),Index(TMP2,1))
+      //Add ISP device to GFX0
+      Store(0x00020F38, Index(TMP2,2))
+      Return(TMP2)
+    } Else
+    {
+      Name(TMP3,Package() {0xFFFFFFFF, 0xFFFFFFFF})
+      Store(Or(0x10000,DID1),Index(TMP3,0))
+      Store(Or(0x10000,DID2),Index(TMP3,1))
+      Return(TMP3)
+    }
+  }
+
+  If(LEqual(NDID,3))
+  {
+    If (LNOTEqual (ISPD, 0))
+    {
+      Name(TMP4,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,0xFFFFFFFF})
+      Store(Or(0x10000,DID1),Index(TMP4,0))
+      Store(Or(0x10000,DID2),Index(TMP4,1))
+      Store(Or(0x10000,DID3),Index(TMP4,2))
+      //Add ISP device to GFX0
+      Store(0x00020F38, Index(TMP4,3))
+      Return(TMP4)
+    } Else
+    {
+      Name(TMP5,Package() {0xFFFFFFFF, 0xFFFFFFFF,0xFFFFFFFF})
+      Store(Or(0x10000,DID1),Index(TMP5,0))
+      Store(Or(0x10000,DID2),Index(TMP5,1))
+      Store(Or(0x10000,DID3),Index(TMP5,2))
+      Return(TMP5)
+    }
+  }
+
+  If(LEqual(NDID,4))
+  {
+    If (LNOTEqual (ISPD, 0))
+    {
+      Name(TMP6,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+      Store(Or(0x10000,DID1),Index(TMP6,0))
+      Store(Or(0x10000,DID2),Index(TMP6,1))
+      Store(Or(0x10000,DID3),Index(TMP6,2))
+      Store(Or(0x10000,DID4),Index(TMP6,3))
+      //Add ISP device to GFX0
+      Store(0x00020F38, Index(TMP6,4))
+      Return(TMP6)
+    } Else
+    {
+      Name(TMP7,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+      Store(Or(0x10000,DID1),Index(TMP7,0))
+      Store(Or(0x10000,DID2),Index(TMP7,1))
+      Store(Or(0x10000,DID3),Index(TMP7,2))
+      Store(Or(0x10000,DID4),Index(TMP7,3))
+      Return(TMP7)
+    }
+  }
+
+  If(LGreater(NDID,4))
+  {
+    If (LNOTEqual (ISPD, 0))
+    {
+      Name(TMP8,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+      Store(Or(0x10000,DID1),Index(TMP8,0))
+      Store(Or(0x10000,DID2),Index(TMP8,1))
+      Store(Or(0x10000,DID3),Index(TMP8,2))
+      Store(Or(0x10000,DID4),Index(TMP8,3))
+      Store(Or(0x10000,DID5),Index(TMP8,4))
+      //Add ISP device to GFX0
+      Store(0x00020F38, Index(TMP8,5))
+      Return(TMP8)
+    } Else
+    {
+      Name(TMP9,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+      Store(Or(0x10000,DID1),Index(TMP9,0))
+      Store(Or(0x10000,DID2),Index(TMP9,1))
+      Store(Or(0x10000,DID3),Index(TMP9,2))
+      Store(Or(0x10000,DID4),Index(TMP9,3))
+      Store(Or(0x10000,DID5),Index(TMP9,4))
+      Return(TMP9)
+    }
+  }
+
+  // If nothing else, return Unknown LFP.
+  // (Prevents compiler warning.)
+
+  //Add ISP device to GFX0
+  If (LNOTEqual (ISPD, 0))
+  {
+    Return(Package() {0x00000400, 0x00020F38})
+  } Else
+  {
+    Return(Package() {0x00000400})
+  }
+}
+
+Device(DD01)
+{
+
+  // Return Unique ID.
+
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID1),0x400))
+    {
+      Store(0x1, EDPV)
+      Store(DID1, DIDX)
+      Return(1)
+    }
+    If(LEqual(DID1,0))
+    {
+      Return(1)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID1))
+    }
+  }
+
+  // Return the Current Status.
+
+  Method(_DCS,0)
+  {
+    Return(CDDS(DID1))
+  }
+
+  // Query Graphics State (active or inactive).
+
+  Method(_DGS,0)
+  {
+    Return(NDDS(DID1))
+  }
+
+  // Device Set State.
+
+  // _DSS Table:
+  //
+  //      BIT31   BIT30   Execution
+  //      0       0       Don't implement.
+  //      0       1       Cache change.  Nothing to Implement.
+  //      1       0       Don't Implement.
+  //      1       1       Display Switch Complete.  Implement.
+
+  Method(_DSS,1)
+  {
+    If(LEqual(And(Arg0,0xC0000000),0xC0000000))
+    {
+
+      // State change was performed by the
+      // Video Drivers.  Simply update the
+      // New State.
+
+      Store(NSTE,CSTE)
+    }
+  }
+}
+
+Device(DD02)
+{
+
+  // Return Unique ID.
+
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID2),0x400))
+    {
+      Store(0x2, EDPV)
+      Store(DID2, DIDX)
+      Return(2)
+    }
+    If(LEqual(DID2,0))
+    {
+      Return(2)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID2))
+    }
+  }
+
+  // Return the Current Status.
+
+  Method(_DCS,0)
+  {
+    Return(CDDS(DID2))
+  }
+
+  // Query Graphics State (active or inactive).
+
+  Method(_DGS,0)
+  {
+    // Return the Next State.
+    Return(NDDS(DID2))
+  }
+
+  // Device Set State. (See table above.)
+
+  Method(_DSS,1)
+  {
+    If(LEqual(And(Arg0,0xC0000000),0xC0000000))
+    {
+
+      // State change was performed by the
+      // Video Drivers.  Simply update the
+      // New State.
+
+      Store(NSTE,CSTE)
+    }
+  }
+}
+
+Device(DD03)
+{
+
+  // Return Unique ID.
+
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID3),0x400))
+    {
+      Store(0x3, EDPV)
+      Store(DID3, DIDX)
+      Return(3)
+    }
+    If(LEqual(DID3,0))
+    {
+      Return(3)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID3))
+    }
+  }
+
+  // Return the Current Status.
+
+  Method(_DCS,0)
+  {
+    If(LEqual(DID3,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DID3))
+    }
+  }
+
+  // Query Graphics State (active or inactive).
+
+  Method(_DGS,0)
+  {
+    Return(NDDS(DID3))
+  }
+
+  // Device Set State. (See table above.)
+
+  Method(_DSS,1)
+  {
+    If(LEqual(And(Arg0,0xC0000000),0xC0000000))
+    {
+      // State change was performed by the
+      // Video Drivers.  Simply update the
+      // New State.
+
+      Store(NSTE,CSTE)
+    }
+  }
+}
+
+Device(DD04)
+{
+
+  // Return Unique ID.
+
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID4),0x400))
+    {
+      Store(0x4, EDPV)
+      Store(DID4, DIDX)
+      Return(4)
+    }
+    If(LEqual(DID4,0))
+    {
+      Return(4)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID4))
+    }
+  }
+
+  // Return the Current Status.
+
+  Method(_DCS,0)
+  {
+    If(LEqual(DID4,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DID4))
+    }
+  }
+
+  // Query Graphics State (active or inactive).
+
+  Method(_DGS,0)
+  {
+    Return(NDDS(DID4))
+  }
+
+  // Device Set State. (See table above.)
+
+  Method(_DSS,1)
+  {
+    If(LEqual(And(Arg0,0xC0000000),0xC0000000))
+    {
+
+      // State change was performed by the
+      // Video Drivers.  Simply update the
+      // New State.
+
+      Store(NSTE,CSTE)
+    }
+  }
+}
+
+
+Device(DD05)
+{
+
+  // Return Unique ID.
+
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID5),0x400))
+    {
+      Store(0x5, EDPV)
+      Store(DID5, DIDX)
+      Return(5)
+    }
+    If(LEqual(DID5,0))
+    {
+      Return(5)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID5))
+    }
+  }
+
+  // Return the Current Status.
+
+  Method(_DCS,0)
+  {
+    If(LEqual(DID5,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DID5))
+    }
+  }
+
+  // Query Graphics State (active or inactive).
+
+  Method(_DGS,0)
+  {
+    Return(NDDS(DID5))
+  }
+
+  // Device Set State. (See table above.)
+
+  Method(_DSS,1)
+  {
+    If(LEqual(And(Arg0,0xC0000000),0xC0000000))
+    {
+      // State change was performed by the
+      // Video Drivers.  Simply update the
+      // New State.
+
+      Store(NSTE,CSTE)
+    }
+  }
+}
+
+
+Device(DD06)
+{
+
+  // Return Unique ID.
+
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID6),0x400))
+    {
+      Store(0x6, EDPV)
+      Store(DID6, DIDX)
+      Return(6)
+    }
+    If(LEqual(DID6,0))
+    {
+      Return(6)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID6))
+    }
+  }
+
+  // Return the Current Status.
+
+  Method(_DCS,0)
+  {
+    If(LEqual(DID6,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DID6))
+    }
+  }
+
+  // Query Graphics State (active or inactive).
+
+  Method(_DGS,0)
+  {
+    Return(NDDS(DID6))
+  }
+
+  // Device Set State. (See table above.)
+
+  Method(_DSS,1)
+  {
+    If(LEqual(And(Arg0,0xC0000000),0xC0000000))
+    {
+      // State change was performed by the
+      // Video Drivers.  Simply update the
+      // New State.
+
+      Store(NSTE,CSTE)
+    }
+  }
+}
+
+
+Device(DD07)
+{
+
+  // Return Unique ID.
+
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID7),0x400))
+    {
+      Store(0x7, EDPV)
+      Store(DID7, DIDX)
+      Return(7)
+    }
+    If(LEqual(DID7,0))
+    {
+      Return(7)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID7))
+    }
+  }
+
+  // Return the Current Status.
+
+  Method(_DCS,0)
+  {
+    If(LEqual(DID7,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DID7))
+    }
+  }
+
+  // Query Graphics State (active or inactive).
+
+  Method(_DGS,0)
+  {
+    Return(NDDS(DID7))
+  }
+
+  // Device Set State. (See table above.)
+
+  Method(_DSS,1)
+  {
+    If(LEqual(And(Arg0,0xC0000000),0xC0000000))
+    {
+      // State change was performed by the
+      // Video Drivers.  Simply update the
+      // New State.
+
+      Store(NSTE,CSTE)
+    }
+  }
+}
+
+
+Device(DD08)
+{
+
+  // Return Unique ID.
+
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID8),0x400))
+    {
+      Store(0x8, EDPV)
+      Store(DID8, DIDX)
+      Return(8)
+    }
+    If(LEqual(DID8,0))
+    {
+      Return(8)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID8))
+    }
+  }
+
+  // Return the Current Status.
+
+  Method(_DCS,0)
+  {
+    If(LEqual(DID8,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DID8))
+    }
+  }
+
+  // Query Graphics State (active or inactive).
+
+  Method(_DGS,0)
+  {
+    Return(NDDS(DID8))
+  }
+
+  // Device Set State. (See table above.)
+
+  Method(_DSS,1)
+  {
+    If(LEqual(And(Arg0,0xC0000000),0xC0000000))
+    {
+      // State change was performed by the
+      // Video Drivers.  Simply update the
+      // New State.
+
+      Store(NSTE,CSTE)
+    }
+  }
+}
+
+//device for eDP
+Device(DD1F)
+{
+  // Return Unique ID.
+
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(EDPV, 0x0))
+    {
+      Return(0x1F)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DIDX))
+    }
+  }
+
+  // Return the Current Status.
+
+  Method(_DCS,0)
+  {
+    If(LEqual(EDPV, 0x0))
+    {
+      Return(0x00)
+    }
+    Else
+    {
+      Return(CDDS(DIDX))
+    }
+  }
+
+  // Query Graphics State (active or inactive).
+
+  Method(_DGS,0)
+  {
+    Return(NDDS(DIDX))
+  }
+
+  // Device Set State. (See table above.)
+
+  Method(_DSS,1)
+  {
+    If(LEqual(And(Arg0,0xC0000000),0xC0000000))
+    {
+      // State change was performed by the
+      // Video Drivers.  Simply update the
+      // New State.
+      Store(NSTE,CSTE)
+    }
+  }
+  // Query List of Brightness Control Levels Supported.
+
+  Method(_BCL,0)
+  {
+    // List of supported brightness levels in the following sequence.
+
+    // Level when machine has full power.
+    // Level when machine is on batteries.
+    // Other supported levels.
+    Return(Package() {80, 50, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100})
+  }
+
+  // Set the Brightness Level.
+
+  Method (_BCM,1)
+  {
+    // Set the requested level if it is between 0 and 100%.
+
+    If(LAnd(LGreaterEqual(Arg0,0),LLessEqual(Arg0,100)))
+    {
+      \_SB.PCI0.GFX0.AINT(1, Arg0)
+      Store(Arg0,BRTL)  // Store Brightness Level.
+    }
+  }
+
+  // Brightness Query Current level.
+
+  Method (_BQC,0)
+  {
+    Return(BRTL)
+  }
+}
+
+Method(SDDL,1)
+{
+  Increment(NDID)
+  Store(And(Arg0,0xF0F),Local0)
+  Or(0x80000000,Local0, Local1)
+  If(LEqual(DIDL,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DDL2,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DDL3,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DDL4,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DDL5,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DDL6,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DDL7,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DDL8,Local0))
+  {
+    Return(Local1)
+  }
+  Return(0)
+}
+
+Method(CDDS,1)
+{
+  Store(And(Arg0,0xF0F),Local0)
+
+  If(LEqual(0, Local0))
+  {
+    Return(0x1D)
+  }
+  If(LEqual(CADL, Local0))
+  {
+    Return(0x1F)
+  }
+  If(LEqual(CAL2, Local0))
+  {
+    Return(0x1F)
+  }
+  If(LEqual(CAL3, Local0))
+  {
+    Return(0x1F)
+  }
+  If(LEqual(CAL4, Local0))
+  {
+    Return(0x1F)
+  }
+  If(LEqual(CAL5, Local0))
+  {
+    Return(0x1F)
+  }
+  If(LEqual(CAL6, Local0))
+  {
+    Return(0x1F)
+  }
+  If(LEqual(CAL7, Local0))
+  {
+    Return(0x1F)
+  }
+  If(LEqual(CAL8, Local0))
+  {
+    Return(0x1F)
+  }
+  Return(0x1D)
+}
+
+Method(NDDS,1)
+{
+  Store(And(Arg0,0xF0F),Local0)
+
+  If(LEqual(0, Local0))
+  {
+    Return(0)
+  }
+  If(LEqual(NADL, Local0))
+  {
+    Return(1)
+  }
+  If(LEqual(NDL2, Local0))
+  {
+    Return(1)
+  }
+  If(LEqual(NDL3, Local0))
+  {
+    Return(1)
+  }
+  If(LEqual(NDL4, Local0))
+  {
+    Return(1)
+  }
+  If(LEqual(NDL5, Local0))
+  {
+    Return(1)
+  }
+  If(LEqual(NDL6, Local0))
+  {
+    Return(1)
+  }
+  If(LEqual(NDL7, Local0))
+  {
+    Return(1)
+  }
+  If(LEqual(NDL8, Local0))
+  {
+    Return(1)
+  }
+  Return(0)
+}
+
+//
+// Include IGD OpRegion/Software SCI interrupt handler which is use by
+// the graphics drivers to request data from system BIOS.
+//
+include("IgdOpRn.ASL")
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELISPDev2.ASL b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELISPDev2.ASL
new file mode 100644
index 0000000000..97548a41f9
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELISPDev2.ASL
@@ -0,0 +1,71 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  INTELISPDev2.ASL
+
+Abstract:
+
+  ISP Exist as B0D2F0 Software ACPI Reference Code for the Baytrail Family.
+
+--*/
+////Device ISP0
+Device(ISP0)
+{
+  Name(_ADR, 0x0F38)
+  //Name (_HID, "80860F38")
+  //Name (_CID, "80860F38")
+  Name(_DDN, "VLV2 ISP - 80860F38")
+  Name(_UID, 0x01)
+
+  Method (_STA, 0, NotSerialized)
+  {
+    If(LEqual(ISPD,1))   //Dev2 need report ISP0 as GFX0 child
+    {
+      Return (0xF)
+    }
+    Else
+    {
+      Return (0x0)
+    }
+  }
+  Name(SBUF,ResourceTemplate ()
+  {
+    Memory32Fixed (ReadWrite, 0x00000000, 0x00400000, ISP0)
+  })
+  Method(_CRS, 0x0, NotSerialized)
+  {
+    Return (SBUF)
+  }
+  Method (_SRS, 0x1, NotSerialized)
+  {
+  }
+  Method (_DIS, 0x0, NotSerialized)
+  {
+  }
+  Method(_DSM, 0x4, NotSerialized)
+  {
+    If (LEqual (Arg0, 0x01))
+    {
+      ///Switch ISP to D3H
+      Return (0x01)
+    }
+    Elseif (LEqual (Arg0, 0x02))
+    {
+      //Switch ISP to D0
+      Return (0x02)
+    }
+    Else
+    {
+      //Do nothing
+      Return (0x0F)
+    }
+  }
+} ///End ISP0
+
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOGBDA.ASL b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOGBDA.ASL
new file mode 100644
index 0000000000..4482db6906
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOGBDA.ASL
@@ -0,0 +1,155 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  IgdOGBDA.ASL
+
+Abstract:
+
+  IGD OpRegion/Software SCI Reference Code for the Baytrail Family.
+  This file contains Get BIOS Data Area funciton support for
+  the Integrated Graphics Device (IGD) OpRegion/Software SCI mechanism.
+
+--*/
+
+
+Method (GBDA, 0, Serialized)
+{
+
+  // Supported calls: Sub-function 0
+
+  If (LEqual(GESF, 0))
+  {
+    //<TODO> Update implementation specific supported calls.  Reference
+    // code is set to Intel's validated implementation.
+
+    Store(0x0000279, PARM)
+
+    Store(Zero, GESF)               // Clear the exit parameter
+    Return(SUCC)                    // Success
+  }
+
+  // Requested callbacks: Sub-function 1
+
+  If (LEqual(GESF, 1))
+  {
+
+    //<TODO> Update implementation specific system BIOS requested call
+    // back functions.  Call back functions are where the driver calls the
+    // system BIOS at function indicated event.
+
+    Store(0x00000240, PARM)
+
+    Store(Zero, GESF)               // Clear the exit parameter
+    Return(SUCC)                    // Success
+  }
+
+  // Get Boot display Preferences: Sub-function 4
+
+  If (LEqual(GESF, 4))
+  {
+
+    //<TODO> Update the implementation specific Get Boot Display
+    // Preferences function.
+
+    And(PARM, 0xEFFF0000, PARM)     // PARM[30:16] = Boot device ports
+    And(PARM, ShiftLeft(DeRefOf(Index(DBTB, IBTT)), 16), PARM)
+    Or(IBTT, PARM, PARM)            // PARM[7:0] = Boot device type
+
+    Store(Zero, GESF)               // Clear the exit parameter
+    Return(SUCC)                    // Success
+  }
+
+  // Panel details: Sub-function 5
+
+  If (LEqual(GESF, 5))
+  {
+
+    //<TODO> Update the implementation specific Get Panel Details
+    // function.
+
+    Store(IPSC, PARM)               // Report the scaling setting
+    Or(PARM, ShiftLeft(IPAT, 8), PARM)
+    Add(PARM, 0x100, PARM)          // Adjust panel type, 0 = VBT default
+    Or(PARM, ShiftLeft(LIDS, 16), PARM) // Report the lid state
+    Add(PARM, 0x10000, PARM)        // Adjust the lid state, 0 = Unknown
+    Or(PARM, ShiftLeft(IBLC, 18), PARM) // Report the BLC setting
+    Or(PARM, ShiftLeft(IBIA, 20), PARM) // Report the BIA setting
+    Store(Zero, GESF)
+    Return(SUCC)
+  }
+
+  // TV-standard/Video-connector: Sub-function 6
+
+  If (LEqual(GESF, 6))
+  {
+
+    //<TODO> Update the implementation specific Get
+    // TV-standard/Video-connectorPanel function.
+
+    Store(ITVF, PARM)
+    Or(PARM, ShiftLeft(ITVM, 4), PARM)
+    Store(Zero, GESF)
+    Return(SUCC)
+  }
+
+  // Internal graphics: Sub-function 7
+
+  If (LEqual(GESF, 7))
+  {
+    Store(GIVD, PARM)               // PARM[0]      - VGA mode(1=VGA)
+    Xor(PARM, 1, PARM)              // Invert the VGA mode polarity
+    Or(PARM, ShiftLeft(GMFN, 1), PARM) // PARM[1]   - # IGD PCI functions-1
+    // PARM[3:2]    - Reserved
+    // PARM[4]      - IGD D3 support(0=cold)
+    // PARM[10:5]   - Reserved
+    Or(PARM, ShiftLeft(3, 11), PARM) // PARM[12:11] - DVMT mode(11b = 5.0)
+
+    //
+    // Report DVMT 5.0 Total Graphics memory size.
+    //
+    Or(PARM, ShiftLeft(IDMS, 17), PARM)   // Bits 20:17 are for Gfx total memory size
+
+    // If the "Set Internal Graphics" call is supported, the modified
+    // settings flag must be programmed per the specification.  This means
+    // that the flag must be set to indicate that system BIOS requests
+    // these settings.  Once "Set Internal Graphics" is called, the
+    //  modified settings flag must be cleared on all subsequent calls to
+    // this function.
+
+    // Report the graphics frequency based on DISPLAY_CLOCK_FREQUENCY_ENCODING [MMADR+0x20C8]
+
+    Or(ShiftLeft(Derefof(Index(CDCT, \_SB.PCI0.GFX0.MCHK.DCFE)), 21),PARM, PARM)
+
+    Store(1, GESF)                  // Set the modified settings flag
+    Return(SUCC)
+  }
+
+  // Spread spectrum clocks: Sub-function 10
+
+  If (LEqual(GESF, 10))
+  {
+
+    Store(0, PARM)                  // Assume SSC is disabled
+
+    If(ISSC)
+    {
+      Or(PARM, 3, PARM)       // If SSC enabled, return SSC1+Enabled
+    }
+
+    Store(0, GESF)                  // Set the modified settings flag
+    Return(SUCC)                    // Success
+  }
+
+
+  // A call to a reserved "Get BIOS data" function was received.
+
+  Store(Zero, GESF)                     // Clear the exit parameter
+  Return(CRIT)                          // Reserved, "Critical failure"
+}
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOMOBF.ASL b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOMOBF.ASL
new file mode 100644
index 0000000000..917e3268d7
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOMOBF.ASL
@@ -0,0 +1,485 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  IgdOMOBF.ASL
+
+Abstract:
+
+  IGD OpRegion/Software SCI Reference Code for the Baytrail Family.
+  This file contains ASL code with the purpose of handling events
+  i.e. hotkeys and other system interrupts.
+
+--*/
+
+
+// Notes:
+// 1. The following routines are to be called from the appropriate event
+//    handlers.
+// 2. This code cannot comprehend the exact implementation in the OEM's BIOS.
+//    Therefore, an OEM must call these methods from the existing event
+//    handler infrastructure.  Details on when/why to call each method is
+//    included in the method header under the "usage" section.
+
+
+/************************************************************************;
+;* ACPI Notification Methods
+;************************************************************************/
+
+
+/************************************************************************;
+;*
+;* Name:        PDRD
+;*
+;* Description: Check if the graphics driver is ready to process
+;*              notifications and video extensions.
+;*
+;* Usage:       This method is to be called prior to performing any
+;*              notifications or handling video extensions.
+;*              Ex: If (PDRD()) {Return (FAIL)}
+;*
+;* Input:       None
+;*
+;* Output:      None
+;*
+;* References:  DRDY (Driver ready status), ASLP (Driver recommended
+;*              sleep timeout value).
+;*
+;************************************************************************/
+
+Method(PDRD)
+{
+  If(LNot(DRDY))
+  {
+
+    // Sleep for ASLP milliseconds if the driver is not ready.
+
+    Sleep(ASLP)
+  }
+
+  // If DRDY is clear, the driver is not ready.  If the return value is
+  // !=0, do not perform any notifications or video extension handling.
+
+  Return(LNot(DRDY))
+}
+
+
+/************************************************************************;
+;*
+;* Name:        PSTS
+;*
+;* Description: Check if the graphics driver has completed the previous
+;*              "notify" command.
+;*
+;* Usage:       This method is called before every "notify" command.  A
+;*              "notify" should only be set if the driver has completed the
+;*              previous command.  Else, ignore the event and exit the parent
+;*              method.
+;*              Ex: If (PSTS()) {Return (FAIL)}
+;*
+;* Input:       None
+;*
+;* Output:      None
+;*
+;* References:  CSTS (Notification status), ASLP (Driver recommended sleep
+;*              timeout value).
+;*
+;************************************************************************/
+
+Method(PSTS)
+{
+  If(LGreater(CSTS, 2))
+  {
+    // Sleep for ASLP milliseconds if the status is not "success,
+    // failure, or pending"
+    //
+    Sleep(ASLP)
+  }
+
+  Return(LEqual(CSTS, 3))         // Return True if still Dispatched
+}
+
+
+/************************************************************************;
+;*
+;* Name:        GNOT
+;*
+;* Description: Call the appropriate methods to query the graphics driver
+;*              status.  If all methods return success, do a notification of
+;*              the graphics device.
+;*
+;* Usage:       This method is to be called when a graphics device
+;*              notification is required (display switch hotkey, etc).
+;*
+;* Input:       Arg0 = Current event type:
+;*                      1 = display switch
+;*                      2 = lid
+;*                      3 = dock
+;*              Arg1 = Notification type:
+;*                      0 = Re-enumeration
+;*                      0x80 = Display switch
+;*
+;* Output:      Returns 0 = success, 1 = failure
+;*
+;* References:  PDRD and PSTS methods.  OSYS (OS version)
+;*
+;************************************************************************/
+
+Method(GNOT, 2)
+{
+  // Check for 1. Driver loaded, 2. Driver ready.
+  // If any of these cases is not met, skip this event and return failure.
+  //
+  If(PDRD())
+  {
+    Return(0x1)             // Return failure if driver not loaded.
+  }
+
+  Store(Arg0, CEVT)               // Set up the current event value
+  Store(3, CSTS)                  // CSTS=BIOS dispatched an event
+
+  If(LAnd(LEqual(CHPD, 0), LEqual(Arg1, 0)))      // Do not re-enum if driver supports hotplug
+  {
+    If(LOr(LGreater(OSYS, 2000), LLess(OSYS, 2006)))
+    {
+      //
+      // WINXP requires that the entire PCI Bridge be re-enumerated.
+      //
+      Notify(\_SB.PCI0, Arg1)
+    }
+    Else
+    {
+      //
+      // Re-enumerate the Graphics Device for non-XP operating systems.
+      //
+      Notify(\_SB.PCI0.GFX0, Arg1)
+    }
+  }
+
+  Notify(\_SB.PCI0.GFX0,0x80)
+
+
+  Return(0x0)                     // Return success
+}
+
+
+/************************************************************************;
+;*
+;* Name:        GHDS
+;*
+;* Description: Handle a hotkey display switching event (performs a
+;*              Notify(GFX0, 0).
+;*
+;* Usage:       This method must be called when a hotkey event occurs and the
+;*              purpose of that hotkey is to do a display switch.
+;*
+;* Input:       Arg0 = Toggle table number.
+;*
+;* Output:      Returns 0 = success, 1 = failure.
+;*              CEVT and TIDX are indirect outputs.
+;*
+;* References:  TIDX, GNOT
+;*
+;************************************************************************/
+
+Method(GHDS, 1)
+{
+  Store(Arg0, TIDX)               // Store the table number
+
+  // Call GNOT for CEVT = 1 = hotkey, notify value = 0
+
+  Return(GNOT(1, 0))              // Return stats from GNOT
+}
+
+
+/************************************************************************;
+;*
+;* Name:        GLID
+;*
+;* Description: Handle a lid event (performs the Notify(GFX0, 0), but not the
+;*              lid notify).
+;*
+;* Usage:       This method must be called when a lid event occurs.  A
+;*              Notify(LID0, 0x80) must follow the call to this method.
+;*
+;* Input:       Arg0 = Lid state:
+;*                      0 = All closed
+;*                      1 = internal LFP lid open
+;*                      2 = external lid open
+;*                      3 = both external and internal open
+;*
+;* Output:      Returns 0=success, 1=failure.
+;*              CLID and CEVT are indirect outputs.
+;*
+;* References:  CLID, GNOT
+;*
+;************************************************************************/
+
+Method(GLID, 1)
+{
+  Store(Arg0, CLID)               // Store the current lid state
+
+  // Call GNOT for CEVT=2=Lid, notify value = 0
+
+  Return(GNOT(2, 0))              // Return stats from GNOT
+}
+
+
+/************************************************************************;
+;*
+;* Name:        GDCK
+;*
+;* Description: Handle a docking event by updating the current docking status
+;*              and doing a notification.
+;*
+;* Usage:       This method must be called when a docking event occurs.
+;*
+;* Input:       Arg0 = Docking state:
+;*                      0 = Undocked
+;*                      1 = Docked
+;*
+;* Output:      Returns 0=success, 1=failure.
+;*              CDCK and CEVT are indirect outputs.
+;*
+;* References:  CDCK, GNOT
+;*
+;************************************************************************/
+
+Method(GDCK, 1)
+{
+  Store(Arg0, CDCK)               // Store the current dock state
+
+  // Call GNOT for CEVT=4=Dock, notify value = 0
+
+  Return(GNOT(4, 0))              // Return stats from GNOT
+}
+
+
+/************************************************************************;
+;* ASLE Interrupt Methods
+;************************************************************************/
+
+
+/************************************************************************;
+;*
+;* Name:        PARD
+;*
+;* Description: Check if the driver is ready to handle ASLE interrupts
+;*              generate by the system BIOS.
+;*
+;* Usage:       This method must be called before generating each ASLE
+;*              interrupt.
+;*
+;* Input:       None
+;*
+;* Output:      Returns 0 = success, 1 = failure.
+;*
+;* References:  ARDY (Driver readiness), ASLP (Driver recommended sleep
+;*              timeout value)
+;*
+;************************************************************************/
+
+Method(PARD)
+{
+  If(LNot(ARDY))
+  {
+
+    // Sleep for ASLP milliseconds if the driver is not ready.
+
+    Sleep(ASLP)
+  }
+
+  // If ARDY is clear, the driver is not ready.  If the return value is
+  // !=0, do not generate the ASLE interrupt.
+
+  Return(LNot(ARDY))
+}
+
+
+/************************************************************************;
+;*
+;* Name:        AINT
+;*
+;* Description: Call the appropriate methods to generate an ASLE interrupt.
+;*              This process includes ensuring the graphics driver is ready
+;*              to process the interrupt, ensuring the driver supports the
+;*              interrupt of interest, and passing information about the event
+;*              to the graphics driver.
+;*
+;* Usage:       This method must called to generate an ASLE interrupt.
+;*
+;* Input:       Arg0 = ASLE command function code:
+;*                      0 = Set ALS illuminance
+;*                      1 = Set backlight brightness
+;*                      2 = Do Panel Fitting
+;*              Arg1 = If Arg0 = 0, current ALS reading:
+;*                      0 = Reading below sensor range
+;*                      1-0xFFFE = Current sensor reading
+;*                      0xFFFF = Reading above sensor range
+;*              Arg1 = If Arg0 = 1, requested backlight percentage
+;*
+;* Output:      Returns 0 = success, 1 = failure
+;*
+;* References:  PARD method.
+;*
+;************************************************************************/
+
+Method(AINT, 2)
+{
+
+  // Return failure if the requested feature is not supported by the
+  // driver.
+
+  If(LNot(And(TCHE, ShiftLeft(1, Arg0))))
+  {
+    Return(0x1)
+  }
+
+  // Return failure if the driver is not ready to handle an ASLE
+  // interrupt.
+
+  If(PARD())
+  {
+    Return(0x1)
+  }
+
+  // Evaluate the first argument (Panel fitting, backlight brightness, or ALS).
+
+  If(LEqual(Arg0, 2))             // Arg0 = 2, so request a panel fitting mode change.
+  {
+    If(CPFM)                                        // If current mode field is non-zero use it.
+    {
+      And(CPFM, 0x0F, Local0)                 // Create variables without reserved
+      And(EPFM, 0x0F, Local1)                 // or valid bits.
+
+      If(LEqual(Local0, 1))                   // If current mode is centered,
+      {
+        If(And(Local1, 6))              // and if stretched is enabled,
+        {
+          Store(6, PFIT)          // request stretched.
+        }
+        Else                            // Otherwise,
+        {
+          If(And(Local1, 8))      // if aspect ratio is enabled,
+          {
+            Store(8, PFIT)  // request aspect ratio.
+          }
+          Else                    // Only centered mode is enabled
+          {
+            Store(1, PFIT)  // so request centered. (No change.)
+          }
+        }
+      }
+      If(LEqual(Local0, 6))                   // If current mode is stretched,
+      {
+        If(And(Local1, 8))              // and if aspect ratio is enabled,
+        {
+          Store(8, PFIT)          // request aspect ratio.
+        }
+        Else                            // Otherwise,
+        {
+          If(And(Local1, 1))      // if centered is enabled,
+          {
+            Store(1, PFIT)  // request centered.
+          }
+          Else                    // Only stretched mode is enabled
+          {
+            Store(6, PFIT)  // so request stretched. (No change.)
+          }
+        }
+      }
+      If(LEqual(Local0, 8))                   // If current mode is aspect ratio,
+      {
+        If(And(Local1, 1))              // and if centered is enabled,
+        {
+          Store(1, PFIT)          // request centered.
+        }
+        Else                            // Otherwise,
+        {
+          If(And(Local1, 6))      // if stretched is enabled,
+          {
+            Store(6, PFIT)  // request stretched.
+          }
+          Else                    // Only aspect ratio mode is enabled
+          {
+            Store(8, PFIT)  // so request aspect ratio. (No change.)
+          }
+        }
+      }
+    }
+
+    // The following code for panel fitting (within the Else condition) is retained for backward compatiblity.
+
+    Else                            // If CFPM field is zero use PFIT and toggle the
+    {
+      Xor(PFIT,7,PFIT)        // mode setting between stretched and centered only.
+    }
+
+    Or(PFIT,0x80000000,PFIT)        // Set the valid bit for all cases.
+
+    Store(4, ASLC)                  // Store "Panel fitting event" to ASLC[31:1]
+  }
+  Else
+  {
+    If(LEqual(Arg0, 1))             // Arg0=1, so set the backlight brightness.
+    {
+      Store(Divide(Multiply(Arg1, 255), 100), BCLP) // Convert from percent to 0-255.
+
+      Or(BCLP, 0x80000000, BCLP)      // Set the valid bit.
+
+      Store(2, ASLC)                  // Store "Backlight control event" to ASLC[31:1]
+    }
+    Else
+    {
+      If(LEqual(Arg0, 0))             // Arg0=0, so set the ALS illuminace
+      {
+        Store(Arg1, ALSI)
+
+        Store(1, ASLC)          // Store "ALS event" to ASLC[31:1]
+      }
+      Else
+      {
+        Return(0x1) // Unsupported function
+      }
+    }
+  }
+
+  Store(0x01, ASLE)               // Generate ASLE interrupt
+  Return(0x0)                     // Return success
+}
+
+
+/************************************************************************;
+;*
+;* Name:        SCIP
+;*
+;* Description: Checks the presence of the OpRegion and SCI
+;*
+;* Usage:       This method is called before other OpRegion methods. The
+;*              former "GSMI True/False is not always valid.  This method
+;*              checks if the OpRegion Version is non-zero and if non-zero,
+;*              (present and readable) then checks the GSMI flag.
+;*
+;* Input:       None
+;*
+;* Output:      Boolean True = SCI present.
+;*
+;* References:  None
+;*
+;************************************************************************/
+
+Method(SCIP)
+{
+  If(LNotEqual(OVER,0))           // If OpRegion Version not 0.
+  {
+    Return(LNot(GSMI))      // Return True if SCI.
+  }
+
+  Return(0)                       // Else Return False.
+}
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOSBCB.ASL b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOSBCB.ASL
new file mode 100644
index 0000000000..9e0482efb9
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOSBCB.ASL
@@ -0,0 +1,274 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  IgdOSBCB.ASL
+
+Abstract:
+
+  IGD OpRegion/Software SCI Reference Code for the Baytrail Family.
+  This file contains the system BIOS call back functionality for the
+  OpRegion/Software SCI mechanism.
+
+--*/
+
+
+Method (SBCB, 0, Serialized)
+{
+
+  // Supported Callbacks: Sub-function 0
+
+  If (LEqual(GESF, 0x0))
+  {
+
+    //<TODO> An OEM may support the driver->SBIOS status callbacks, but
+    // the supported callbacks value must be modified.  The code that is
+    // executed upon reception of the callbacks must be also be updated
+    // to perform the desired functionality.
+
+    Store(0x00000000, PARM)         // No callbacks supported
+
+    If(LEqual(PFLV,FMBL))
+    {
+      Store(0x000F87FD, PARM)         // Mobile
+    }
+    If(LEqual(PFLV,FDTP))
+    {
+      Store(0x000F87BD, PARM)         // Desktop
+    }
+
+    Store(Zero, GESF)               // Clear the exit parameter
+    Return(SUCC)                    // "Success"
+  }
+
+  // BIOS POST Completion: Sub-function 1
+
+  If (LEqual(GESF, 1))
+  {
+    Store(Zero, GESF)               // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)                    // Not supported, but no failure
+  }
+
+  // Pre-Hires Set Mode: Sub-function 3
+
+  If (LEqual(GESF, 3))
+  {
+    Store(Zero, GESF)               // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)                    // Not supported, but no failure
+  }
+
+  // Post-Hires Set Mode: Sub-function 4
+
+  If (LEqual(GESF, 4))
+  {
+    Store(Zero, GESF)               // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)                    // Not supported, but no failure
+  }
+
+  // Display Switch: Sub-function 5
+
+  If (LEqual(GESF, 5))
+  {
+    Store(Zero, GESF)               // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)                    // Not supported, but no failure
+  }
+
+  // Set TV format: Sub-function 6
+
+  If (LEqual(GESF, 6))
+  {
+
+    //<TODO> If implemented, the input values must be saved into
+    // non-volatile storage for parsing during the next boot.  The
+    // following Sample code is Intel validated implementation.
+
+    Store(And(PARM, 0x0F), ITVF)
+    Store(ShiftRight(And(PARM, 0xF0), 4), ITVM)
+    Store(Zero, GESF)               // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)
+  }
+
+  // Adapter Power State: Sub-function 7
+
+  If (LEqual(GESF, 7))
+  {
+
+    // Upon notification from driver that the Adapter Power State = D0,
+    // check if previous lid event failed.  If it did, retry the lid
+    // event here.
+    If(LEqual(PARM, 0))
+    {
+      Store(CLID, Local0)
+      If(And(0x80000000,Local0))
+      {
+        And(CLID, 0x0000000F, CLID)
+        GLID(CLID)
+      }
+    }
+    Store(Zero, GESF)               // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)                    // Not supported, but no failure
+  }
+
+  // Display Power State: Sub-function 8
+
+  If (LEqual(GESF, 8))
+  {
+    Store(Zero, GESF)               // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)                    // Not supported, but no failure
+  }
+
+  // Set Boot Display: Sub-function 9
+
+  If (LEqual(GESF, 9))
+  {
+
+    //<TODO> An OEM may elect to implement this method.  In that case,
+    // the input values must be saved into non-volatile storage for
+    // parsing during the next boot.  The following Sample code is Intel
+    // validated implementation.
+
+    And(PARM, 0xFF, IBTT)           // Save the boot display to NVS
+    Store(Zero, GESF)               // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)                    // Reserved, "Critical failure"
+  }
+
+  // Set Panel Details: Sub-function 10 (0Ah)
+
+  If (LEqual(GESF, 10))
+  {
+
+    //<TODO> An OEM may elect to implement this method.  In that case,
+    // the input values must be saved into non-volatile storage for
+    // parsing during the next boot.  The following Sample code is Intel
+    // validated implementation.
+
+    // Set the panel-related NVRAM variables based the input from the driver.
+
+    And(PARM, 0xFF, IPSC)
+
+    // Change panel type if a change is requested by the driver (Change if
+    // panel type input is non-zero).  Zero=No change requested.
+
+    If(And(ShiftRight(PARM, 8), 0xFF))
+    {
+      And(ShiftRight(PARM, 8), 0xFF, IPAT)
+      Decrement(IPAT)         // 0 = no change, so fit to CMOS map
+    }
+    And(ShiftRight(PARM, 18), 0x3, IBLC)
+    And(ShiftRight(PARM, 20), 0x7, IBIA)
+    Store(Zero, GESF)               // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)                    // Success
+  }
+
+  // Set Internal Graphics: Sub-function 11 (0Bh)
+
+  If (LEqual(GESF, 11))
+  {
+
+    //<TODO> An OEM may elect to implement this method.  In that case,
+    // the input values must be saved into non-volatile storage for
+    // parsing during the next boot.  The following Sample code is Intel
+    // validated implementation.
+
+    And(ShiftRight(PARM, 1), 1, IF1E) // Program the function 1 option
+
+    // Fixed memory/DVMT memory
+
+    And(ShiftRight(PARM, 17), 0xF, IDMS) // Program DVMT/fixed memory size
+
+    Store(Zero, GESF)               // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)                    // Success
+  }
+
+  // Post-Hires to DOS FS: Sub-function 16 (10h)
+
+  If (LEqual(GESF, 16))
+  {
+    Store(Zero, GESF)               // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)                    // Not supported, but no failure
+  }
+
+  // APM Complete:  Sub-function 17 (11h)
+
+  If (LEqual(GESF, 17))
+  {
+
+    Store(ShiftLeft(LIDS, 8), PARM) // Report the lid state
+    Add(PARM, 0x100, PARM)          // Adjust the lid state, 0 = Unknown
+
+    Store(Zero, GESF)               // Clear the exit parameter
+    Return(SUCC)                    // Not supported, but no failure
+  }
+
+  // Set Spread Spectrum Clocks: Sub-function 18 (12h)
+
+  If (LEqual(GESF, 18))
+  {
+
+    //<TODO> An OEM may elect to implement this method.  In that case,
+    // the input values must be saved into non-volatile storage for
+    // parsing during the next boot.  The following Sample code is Intel
+    // validated implementation.
+
+    If(And(PARM, 1))
+    {
+      If(LEqual(ShiftRight(PARM, 1), 1))
+      {
+        Store(1, ISSC)  // Enable HW SSC, only for clock 1
+      }
+      Else
+      {
+        Store(Zero, GESF)
+        Return(CRIT)    // Failure, as the SSC clock must be 1
+      }
+    }
+    Else
+    {
+      Store(0, ISSC)          // Disable SSC
+    }
+    Store(Zero, GESF)               // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)                    // Success
+  }
+
+  // Post VBE/PM Callback: Sub-function 19 (13h)
+
+  If (LEqual(GESF, 19))
+  {
+    Store(Zero, GESF)               // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)                    // Not supported, but no failure
+  }
+
+  // Set PAVP Data: Sub-function 20 (14h)
+
+  If (LEqual(GESF, 20))
+  {
+    And(PARM, 0xF, PAVP)    // Store PAVP info
+    Store(Zero, GESF)               // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)                    // Success
+  }
+
+  // A call to a reserved "System BIOS callbacks" function was received
+
+  Store(Zero, GESF)                     // Clear the exit parameter
+  Return(SUCC)                          // Reserved, "Critical failure"
+}
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOpRn.ASL b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOpRn.ASL
new file mode 100644
index 0000000000..8575fbfe6c
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOpRn.ASL
@@ -0,0 +1,299 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  IgdOpRn.ASL
+
+Abstract:
+
+  IGD OpRegion/Software SCI Reference Code for the Baytrail Family.
+  This file contains the interrupt handler code for the Integrated
+  Graphics Device (IGD) OpRegion/Software SCI mechanism.
+
+--*/
+
+
+//NOTES:
+//
+// (1)  The code contained in this file inherits the scope in which it
+//      was included.  So BIOS developers must be sure to include this
+//      file in the scope associated with the graphics device
+//      (ex. \_SB.PCI0.GFX0).
+// (2)  Create a _L06 method under the GPE scope to handle the event
+//      generated by the graphics driver.  The _L06 method must call
+//      the GSCI method in this file.
+// (3)  The MCHP operation region assumes that _ADR and _BBN names
+//      corresponding to bus 0, device0, function 0 have been declared
+//      under the PCI0 scope.
+// (4)  Before the first execution of the GSCI method, the base address
+//      of the GMCH SCI OpRegion must be programmed where the driver can
+//      access it. A 32bit scratch register at 0xFC in the IGD PCI
+//      configuration space (B0/D2/F0/R0FCh) is used for this purpose.
+
+//  Define an OperationRegion to cover the GMCH PCI configuration space as
+//  described in the IGD OpRegion specificiation.
+
+//  Define an OperationRegion to cover the IGD PCI configuration space as
+//  described in the IGD OpRegion specificiation.
+
+OperationRegion(IGDP, PCI_Config,0x00,0x100)
+Field(IGDP, AnyAcc, NoLock, Preserve)
+{
+  Offset(0x10),  // GTTMMADR
+  MADR,   32,
+  Offset(0x50),  // GMCH Graphics Control Register
+  ,   1,
+  GIVD,   1,     // IGD VGA disable bit
+  ,   1,
+  GUMA,   5,     // Stolen memory size
+  ,   8,
+  Offset(0x54),
+  ,   4,
+  GMFN,   1,     // Gfx function 1 enable
+  ,   27,
+  Offset(0x5C),  // Stolen Memory Base Address
+  GSTM,   32,
+  Offset(0xE0),  // Reg 0xE8, SWSCI control register
+  GSSE,   1,     // Graphics SCI event (1=event pending)
+  GSSB,   14,    // Graphics SCI scratchpad bits
+  GSES,   1,     // Graphics event select (1=SCI)
+  Offset(0xE4),
+  ASLE,   8,     // Reg 0xE4, ASLE interrupt register
+  ,   24,    // Only use first byte of ASLE reg
+  Offset(0xFC),
+  ASLS,   32,    // Reg 0xFC, Address of the IGD OpRegion
+}
+
+Method (MCHK, 0, Serialized)
+{
+
+  If (LNotEqual (MADR, 0xFFFFFFFF))
+  {
+    OperationRegion(IGMM,SystemMemory,MADR,0x3000)
+    Field(IGMM,AnyAcc, NoLock, Preserve)
+    {
+      Offset(0X20C8),
+      ,    4,
+      DCFE,    4,                     // DISPLAY_CLOCK_FREQUENCY_ENCODING
+    }
+  }
+}
+
+
+//  Define an OperationRegion to cover the IGD OpRegion layout.
+
+OperationRegion(IGDM, SystemMemory, ASLB, 0x2000)
+Field(IGDM, AnyAcc, NoLock, Preserve)
+{
+
+  // OpRegion Header
+
+  SIGN,   128,                    // Signature-"IntelGraphicsMem"
+  SIZE,   32,                     // OpRegion Size
+  OVER,   32,                     // OpRegion Version
+  SVER,   256,                    // System BIOS Version
+  VVER,   128,                    // VBIOS Version
+  GVER,   128,                    // Driver version
+  MBOX,   32,                     // Mailboxes supported
+  DMOD,   32,                     // Driver Model
+  PCON,   32,                     // 96, Platform Configuration
+
+  // OpRegion Mailbox 1 (Public ACPI Methods)
+  // Note: Mailbox 1 is normally reserved for desktop platforms.
+
+  Offset(0x100),
+  DRDY,   32,                     // Driver readiness (ACPI notification)
+  CSTS,   32,                     // Notification status
+  CEVT,   32,                     // Current event
+  Offset(0x120),
+  DIDL,   32,                     // Supported display device ID list
+  DDL2,   32,                     // Allows for 8 devices
+  DDL3,   32,
+  DDL4,   32,
+  DDL5,   32,
+  DDL6,   32,
+  DDL7,   32,
+  DDL8,   32,
+  CPDL,   32,                     // Currently present display list
+  CPL2,   32,                     // Allows for 8 devices
+  CPL3,   32,
+  CPL4,   32,
+  CPL5,   32,
+  CPL6,   32,
+  CPL7,   32,
+  CPL8,   32,
+  CAD1,   32,                     // Currently active display list
+  CAL2,   32,                     // Allows for 8 devices
+  CAL3,   32,
+  CAL4,   32,
+  CAL5,   32,
+  CAL6,   32,
+  CAL7,   32,
+  CAL8,   32,
+  NADL,   32,                     // Next active display list
+  NDL2,   32,                     // Allows for 8 devices
+  NDL3,   32,
+  NDL4,   32,
+  NDL5,   32,
+  NDL6,   32,
+  NDL7,   32,
+  NDL8,   32,
+  ASLP,   32,                     // ASL sleep timeout
+  TIDX,   32,                     // Toggle table index
+  CHPD,   32,                     // Current hot plug enable indicator
+  CLID,   32,                     // Current lid state indicator
+  CDCK,   32,                     // Current docking state indicator
+  SXSW,   32,                     // Display switch notify on resume
+  EVTS,   32,                     // Events supported by ASL (diag only)
+  CNOT,   32,                     // Current OS notifications (diag only)
+  NRDY,   32,
+
+  // OpRegion Mailbox 2 (Software SCI Interface)
+
+  Offset(0x200),                  // SCIC
+  SCIE,   1,                      // SCI entry bit (1=call unserviced)
+  GEFC,   4,                      // Entry function code
+  GXFC,   3,                      // Exit result
+  GESF,   8,                      // Entry/exit sub-function/parameter
+  ,   16,                     // SCIC[31:16] reserved
+  Offset(0x204),                  // PARM
+  PARM,   32,                     // PARM register (extra parameters)
+  DSLP,   32,                     // Driver sleep time out
+
+  // OpRegion Mailbox 3 (BIOS to Driver Notification)
+  // Note: Mailbox 3 is normally reserved for desktop platforms.
+
+  Offset(0x300),
+  ARDY,   32,                     // Driver readiness (power conservation)
+  ASLC,   32,                     // ASLE interrupt command/status
+  TCHE,   32,                     // Technology enabled indicator
+  ALSI,   32,                     // Current ALS illuminance reading
+  BCLP,   32,                     // Backlight brightness
+  PFIT,   32,                     // Panel fitting state or request
+  CBLV,   32,                     // Current brightness level
+  BCLM,   320,                    // Backlight brightness level duty cycle mapping table
+  CPFM,   32,                     // Current panel fitting mode
+  EPFM,   32,                     // Enabled panel fitting modes
+  PLUT,   592,                    // Optional. 74-byte Panel LUT Table
+  PFMB,   32,                     // Optional. PWM Frequency and Minimum Brightness
+  CCDV,   32,                     // Optional. Gamma, Brightness, Contrast values.
+  PCFT,   32,                     // Optional. Power Conservation Features
+
+  Offset(0x3B6),
+  STAT,   32,                     // Status register
+
+  // OpRegion Mailbox 4 (VBT)
+
+  Offset(0x400),
+  GVD1,   0xC000,                 // 6K bytes maximum VBT image
+
+  // OpRegion Mailbox 5 (BIOS to Driver Notification Extension)
+
+  Offset(0x1C00),
+  PHED,   32,                     // Panel Header
+  BDDC,   2048,                   // Panel EDID (Max 256 bytes)
+
+}
+
+
+
+// Convert boot display type into a port mask.
+
+Name (DBTB, Package()
+{
+  0x0000,                         // Automatic
+  0x0007,                         // Port-0 : Integrated CRT
+  0x0038,                         // Port-1 : DVO-A, or Integrated LVDS
+  0x01C0,                         // Port-2 : SDVO-B, or SDVO-B/C
+  0x0E00,                         // Port-3 : SDVO-C
+  0x003F,                         // [CRT + DVO-A / Integrated LVDS]
+  0x01C7,                         // [CRT + SDVO-B] or [CRT + SDVO-B/C]
+  0x0E07,                         // [CRT + SDVO-C]
+  0x01F8,                         // [DVO-A / Integrated LVDS + SDVO-B]
+  0x0E38,                         // [DVO-A / Integrated LVDS + SDVO-C]
+  0x0FC0,                         // [SDVO-B + SDVO-C]
+  0x0000,                         // Reserved
+  0x0000,                         // Reserved
+  0x0000,                         // Reserved
+  0x0000,                         // Reserved
+  0x0000,                         // Reserved
+  0x7000,                         // Port-4: Integrated TV
+  0x7007,                         // [Integrated TV + CRT]
+  0x7038,                         // [Integrated TV + LVDS]
+  0x71C0,                         // [Integrated TV + DVOB]
+  0x7E00                          // [Integrated TV + DVOC]
+})
+
+// Core display clock value table.
+
+Name (CDCT, Package()
+{
+  Package() {160},
+  Package() {200},
+  Package() {267},
+  Package() {320},
+  Package() {356},
+  Package() {400},
+})
+
+// Defined exit result values:
+
+Name (SUCC, 1)                          // Exit result: Success
+Name (NVLD, 2)                          // Exit result: Invalid parameter
+Name (CRIT, 4)                          // Exit result: Critical failure
+Name (NCRT, 6)                          // Exit result: Non-critical failure
+
+
+/************************************************************************;
+;*
+;* Name: GSCI
+;*
+;* Description: Handles an SCI generated by the graphics driver.  The
+;*              PARM and SCIC input fields are parsed to determine the
+;*              functionality requested by the driver.  GBDA or SBCB
+;*              is called based on the input data in SCIC.
+;*
+;* Usage:       The method must be called in response to a GPE 06 event
+;*              which will be generated by the graphics driver.
+;*              Ex: Method(\_GPE._L06) {Return(\_SB.PCI0.GFX0.GSCI())}
+;*
+;* Input:       PARM and SCIC are indirect inputs
+;*
+;* Output:      PARM and SIC are indirect outputs
+;*
+;* References:  GBDA (Get BIOS Data method), SBCB (System BIOS Callback
+;*              method)
+;*
+;************************************************************************/
+
+Method (GSCI, 0, Serialized)
+{
+  Include("IgdOGBDA.ASL") // "Get BIOS Data" Functions
+  Include("IgdOSBCB.ASL") // "System BIOS CallBacks"
+
+  If (LEqual(GEFC, 4))
+  {
+    Store(GBDA(), GXFC)     // Process Get BIOS Data functions
+  }
+
+  If (LEqual(GEFC, 6))
+  {
+    Store(SBCB(), GXFC)     // Process BIOS Callback functions
+  }
+
+  Store(0, GEFC)                  // Wipe out the entry function code
+  Store(1, SCIS)                  // Clear the GUNIT SCI status bit in PCH ACPI I/O space.
+  Store(0, GSSE)                  // Clear the SCI generation bit in PCI space.
+  Store(0, SCIE)                  // Clr SCI serviced bit to signal completion
+
+  Return(Zero)
+}
+
+// Include MOBLFEAT.ASL for mobile systems only.  Remove for desktop.
+Include("IgdOMOBF.ASL")     // IGD SCI mobile features
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IoTVirtualDevice.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IoTVirtualDevice.asl
new file mode 100644
index 0000000000..320b36ffb2
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IoTVirtualDevice.asl
@@ -0,0 +1,171 @@
+/** @file
+Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+Device(IOTD) { 
+  Name(_HID, "MSFT8000")
+  Name(_CID, "MSFT8000")
+  
+  Name(_CRS, ResourceTemplate() {  
+    // Index 0 
+    SPISerialBus(            // Pin 5, 7, 9 , 11 of JP1 for SIO_SPI
+      1,                     // Device selection
+      PolarityLow,           // Device selection polarity
+      FourWireMode,          // wiremode
+      8,                     // databit len
+      ControllerInitiated,   // slave mode
+      8000000,               // Connection speed
+      ClockPolarityLow,      // Clock polarity
+      ClockPhaseSecond,      // clock phase
+      "\\_SB.SPI1",          // ResourceSource: SPI bus controller name
+      0,                     // ResourceSourceIndex
+      ResourceConsumer,      // Resource usage
+      JSPI,                  // DescriptorName: creates name for offset of resource descriptor
+      )                      // Vendor Data  
+    
+    // Index 1     
+    I2CSerialBus(            // Pin 13, 15 of JP1, for SIO_I2C5 (signal)
+      0x00,                  // SlaveAddress: bus address (TBD)
+      ,                      // SlaveMode: default to ControllerInitiated
+      400000,                // ConnectionSpeed: in Hz
+      ,                      // Addressing Mode: default to 7 bit
+      "\\_SB.I2C6",          // ResourceSource: I2C bus controller name (For MinnowBoard Max, hardware I2C5(0-based) is reported as ACPI I2C6(1-based))
+      ,
+      ,
+      JI2C,                  // Descriptor Name: creates name for offset of resource descriptor
+      )                      // VendorData
+    
+    // Index 2
+    UARTSerialBus(           // Pin 17, 19 of JP1, for SIO_UART2
+      115200,                // InitialBaudRate: in bits ber second
+      ,                      // BitsPerByte: default to 8 bits
+      ,                      // StopBits: Defaults to one bit
+      0xfc,                  // LinesInUse: 8 1-bit flags to declare line enabled
+      ,                      // IsBigEndian: default to LittleEndian
+      ,                      // Parity: Defaults to no parity
+      ,                      // FlowControl: Defaults to no flow control
+      32,                    // ReceiveBufferSize
+      32,                    // TransmitBufferSize
+      "\\_SB.URT2",          // ResourceSource: UART bus controller name
+      ,
+      ,
+      UAR2,                  // DescriptorName: creates name for offset of resource descriptor
+      )                      
+    
+    // Index 3
+    GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO2",) {0}  // Pin 21 of JP1 (GPIO_S5[00])
+    // Index 4
+    GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO2",) {0} 
+    
+    // Index 5
+    GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO2",) {1}  // Pin 23 of JP1 (GPIO_S5[01])
+    // Index 6
+    GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO2",) {1}
+    
+    // Index 7
+    GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO2",) {2}  // Pin 25 of JP1 (GPIO_S5[02])
+    // Index 8
+    GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO2",) {2} 
+    
+    // Index 9
+    UARTSerialBus(           // Pin 6, 8, 10, 12 of JP1, for SIO_UART1
+      115200,                // InitialBaudRate: in bits ber second
+      ,                      // BitsPerByte: default to 8 bits
+      ,                      // StopBits: Defaults to one bit
+      0xfc,                  // LinesInUse: 8 1-bit flags to declare line enabled
+      ,                      // IsBigEndian: default to LittleEndian
+      ,                      // Parity: Defaults to no parity
+      FlowControlHardware,   // FlowControl: Defaults to no flow control
+      32,                    // ReceiveBufferSize
+      32,                    // TransmitBufferSize
+      "\\_SB.URT1",          // ResourceSource: UART bus controller name
+      ,
+      ,
+      UAR1,              // DescriptorName: creates name for offset of resource descriptor
+      )  
+    
+    // Index 10
+    GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {62}  // Pin 14 of JP1 (GPIO_SC[62])
+    // Index 11
+    GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",) {62} 
+    
+    // Index 12
+    GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {63}  // Pin 16 of JP1 (GPIO_SC[63])
+    // Index 13
+    GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",) {63} 
+    
+    // Index 14
+    GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {65}  // Pin 18 of JP1 (GPIO_SC[65])
+    // Index 15
+    GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",) {65} 
+    
+    // Index 16
+    GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {64}  // Pin 20 of JP1 (GPIO_SC[64])
+    // Index 17
+    GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",) {64} 
+    
+    // Index 18
+    GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {94}  // Pin 22 of JP1 (GPIO_SC[94])
+    // Index 19
+    GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",) {94} 
+    
+    // Index 20
+    GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {95}  // Pin 24 of JP1 (GPIO_SC[95])
+    // Index 21
+    GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",) {95} 
+    
+    // Index 22
+    GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {54}  // Pin 26 of JP1 (GPIO_SC[54])
+    // Index 23
+    GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",) {54}
+  })
+
+  Name(_DSD, Package() {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package(1) {	  // Just one Property for IOT (at this time) 
+      Package(2) {	//The “symbolic-identifiers” property
+        "symbolic-identifiers", 
+        Package() {	//Contains all the <resource index, symbolic-identifier> pairs       
+          0, "SPI0",	  
+          1, "I2C5",		
+          2, "UART2",
+          3, 21,       // Pin 21 of JP1 (GPIO_S5[00])
+          4, 21,       // Pin 21 for separate resource. 
+          5, 23,       // Pin 23 of JP1 (GPIO_S5[01])
+          6, 23,
+          7, 25,       // Pin 25 of JP1 (GPIO_S5[02])
+          8, 25,
+          9, "UART1",
+          10, 14,      // Pin 14 of JP1 (GPIO_SC[62])
+          11, 14,
+          12, 16,      // Pin 16 of JP1 (GPIO_SC[63])
+          13, 16,
+          14, 18,      // Pin 18 of JP1 (GPIO_SC[65])
+          15, 18,
+          16, 20,      // Pin 20 of JP1 (GPIO_SC[64])
+          17, 20,
+          18, 22,      // Pin 22 of JP1 (GPIO_SC[94])
+          19, 22,
+          20, 24,      // Pin 24 of JP1 (GPIO_SC[95])
+          21, 24,
+          22, 26,      // Pin 26 of JP1 (GPIO_SC[54])
+          23, 26
+        }
+      } 
+    }
+  })
+  
+  Method(_STA,0,Serialized) {
+    
+    //
+    // Only report IoT virtual device when all pins' configuration follows MSFT's datasheet.
+    //
+    If (LEqual(IOT, 1)) {
+      Return (0xF)
+    }
+    
+    Return (0x0)
+  }
+}
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LPC_DEV.ASL b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LPC_DEV.ASL
new file mode 100644
index 0000000000..7367f4c77c
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LPC_DEV.ASL
@@ -0,0 +1,151 @@
+/**************************************************************************;
+;*                                                                        *;
+;*                                                                        *;
+;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
+;*    Family of Customer Reference Boards.                                *;
+;*                                                                        *;
+;*                                                                        *;
+;*    Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved    *;
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;*                                                                        *;
+;*                                                                        *;
+;**************************************************************************/
+
+Device(FWHD) // Firmware Hub Device
+{
+  Name(_HID,EISAID("INT0800"))
+
+  Name(_CRS,ResourceTemplate()
+  {
+    Memory32Fixed(ReadOnly,0xFF000000,0x1000000)
+  })
+}
+
+Device(IPIC) // 8259 PIC
+{
+  Name(_HID,EISAID("PNP0000"))
+
+  Name(_CRS,ResourceTemplate()
+  {
+    IO(Decode16,0x20,0x20,0x01,0x02)
+    IO(Decode16,0x24,0x24,0x01,0x02)
+    IO(Decode16,0x28,0x28,0x01,0x02)
+    IO(Decode16,0x2C,0x2C,0x01,0x02)
+    IO(Decode16,0x30,0x30,0x01,0x02)
+    IO(Decode16,0x34,0x34,0x01,0x02)
+    IO(Decode16,0x38,0x38,0x01,0x02)
+    IO(Decode16,0x3C,0x3C,0x01,0x02)
+    IO(Decode16,0xA0,0xA0,0x01,0x02)
+    IO(Decode16,0xA4,0xA4,0x01,0x02)
+    IO(Decode16,0xA8,0xA8,0x01,0x02)
+    IO(Decode16,0xAC,0xAC,0x01,0x02)
+    IO(Decode16,0xB0,0xB0,0x01,0x02)
+    IO(Decode16,0xB4,0xB4,0x01,0x02)
+    IO(Decode16,0xB8,0xB8,0x01,0x02)
+    IO(Decode16,0xBC,0xBC,0x01,0x02)
+    IO(Decode16,0x4D0,0x4D0,0x01,0x02)
+    IRQNoFlags() {2}
+  })
+}
+
+Device(LDRC) // LPC Device Resource Consumption
+{
+  Name(_HID,EISAID("PNP0C02"))
+
+  Name(_UID,2)
+
+  Name(_CRS,ResourceTemplate()
+  {
+    IO(Decode16,0x4E,0x4E,0x1,0x02)         // LPC Slot Access.
+    IO(Decode16,0x61,0x61,0x1,0x1)          // NMI Status.
+    IO(Decode16,0x63,0x63,0x1,0x1)          // Processor I/F.
+    IO(Decode16,0x65,0x65,0x1,0x1)          // Processor I/F.
+    IO(Decode16,0x67,0x67,0x1,0x1)          // Processor I/F.
+    IO(Decode16,0x70,0x70,0x1,0x1)          // NMI Enable.
+    IO(Decode16,0x80,0x80,0x1,0x10)         // Postcode.
+    IO(Decode16,0x92,0x92,0x1,0x1)          // Processor I/F.
+    IO(Decode16,0xB2,0xB2,0x01,0x02)        // Software SMI.
+    IO(Decode16,0x680,0x680,0x1,0x20)       // 32 Byte I/O.
+    IO(Decode16,0x400,0x400,0x1,0x80)       // ACPI Base.
+    IO(Decode16,0x500,0x500,0x1,0xFF)       // GPIO Base.
+  })
+}
+
+Device(TIMR) // 8254 Timer
+{
+  Name(_HID,EISAID("PNP0100"))
+
+  Name(_CRS,ResourceTemplate()
+  {
+    IO(Decode16,0x40,0x40,0x01,0x04)
+    IO(Decode16,0x50,0x50,0x10,0x04)
+    IRQNoFlags() {0}
+  })
+}
+
+Device(IUR3) // Internal UART
+{
+  Name(_HID, EISAID("PNP0501"))
+
+  Name(_UID,1)
+
+  // Status Method for internal UART
+
+  Method(_STA,0,Serialized)
+  {
+    // Only report resources to the OS if internal UART is
+    // not set to Disabled in BIOS Setup.
+
+    If(LEqual(USEL,0))
+    {
+      If(LEqual(PU1E,1))
+      {
+        Store(1,UI3E) // Enable IRQ3 for UART
+        Store(1,UI4E) // Enable IRQ4 for UART
+        Store(1,C1EN) // Enable UART
+        Return(0x000F)
+      }
+    }
+
+    Return(0x0000)
+  }
+
+  // Disable Method for internal UART
+
+  Method(_DIS,0,Serialized)
+  {
+    Store(0,UI3E)
+    Store(0,UI4E)
+    Store(0,C1EN)
+  }
+
+  // Current Resource Setting Method for internal UART
+
+  Method(_CRS,0,Serialized)
+  {
+    // Create the Buffer that stores the Resources to
+    // be returned.
+
+    Name(BUF0,ResourceTemplate()
+    {
+      IO(Decode16,0x03F8,0x03F8,0x01,0x08)
+      IRQNoFlags() {3}
+    })
+
+    Name(BUF1,ResourceTemplate()
+    {
+      IO(Decode16,0x03F8,0x03F8,0x01,0x08)
+      IRQNoFlags() {4}
+    })
+
+    If (LLessEqual(SRID, 0x04))
+    {
+      Return(BUF0)
+    } Else
+    {
+      Return(BUF1)
+    }
+  }
+}
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LpcB.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LpcB.asl
new file mode 100644
index 0000000000..157c149d0a
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LpcB.asl
@@ -0,0 +1,59 @@
+/**************************************************************************;
+;*                                                                        *;
+;*                                                                        *;
+;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
+;*    Family of Customer Reference Boards.                                *;
+;*                                                                        *;
+;*                                                                        *;
+;*    Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved    *;
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;*                                                                        *;
+;*                                                                        *;
+;**************************************************************************/
+
+
+// LPC Bridge - Device 31, Function 0
+// Define the needed LPC registers used by ASL.
+
+scope(\_SB)
+{
+  OperationRegion(ILBR, SystemMemory, \IBAS, 0x8C)
+  Field(ILBR, AnyAcc, NoLock, Preserve)
+  {
+    Offset(0x08), // 0x08
+    PARC,   8,
+    PBRC,   8,
+    PCRC,   8,
+    PDRC,   8,
+    PERC,   8,
+    PFRC,   8,
+    PGRC,   8,
+    PHRC,   8,
+    Offset(0x88), // 0x88
+    ,       3,
+    UI3E,   1,
+    UI4E,   1
+  }
+
+  Include ("98_LINK.ASL")
+}
+
+OperationRegion(LPC0, PCI_Config, 0x00, 0xC0)
+Field(LPC0, AnyAcc, NoLock, Preserve)
+{
+  Offset(0x08), // 0x08
+  SRID,   8,  // Revision ID
+  Offset(0x080), // 0x80
+  C1EN,   1, // COM1 Enable
+  ,      31
+}
+
+
+Include ("LPC_DEV.ASL")
+
+
+
+
+
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Lpit/Lpit.aslc b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Lpit/Lpit.aslc
new file mode 100644
index 0000000000..9847ec3a12
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Lpit/Lpit.aslc
@@ -0,0 +1,223 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+--*/
+
+//
+// Include files
+//
+
+#include <PiDxe.h>
+#include <IndustryStandard/Acpi50.h>
+
+
+
+//
+// LPIT Definitions
+//
+
+#define EFI_ACPI_LOW_POWER_IDLE_TABLE_REVISION 0x1
+
+//
+// Ensure proper structure formats
+//
+#pragma pack(1)
+
+typedef union _EFI_ACPI_LPI_STATE_FLAGS {
+  struct {
+    UINT32 Disabled           :1;
+    UINT32 CounterUnavailable :1;
+    UINT32 Reserved           :30;
+  };
+  UINT32 AsUlong;
+} EFI_ACPI_LPI_STATE_FLAGS, *PEFI_ACPI_LPI_STATE_FLAGS;
+
+// Only Mwait LPI here:
+
+typedef struct _EFI_ACPI_MWAIT_LPI_STATE_DESCRIPTOR {
+  UINT32 Type;        // offset: 0
+  UINT32 Length;      // offset: 4
+  UINT16 UniqueId;    // offset: 8
+  UINT8 Reserved[2];  // offset: 9
+  EFI_ACPI_LPI_STATE_FLAGS Flags; // offset: 12
+  EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE EntryTrigger; // offset: 16
+  UINT32 Residency;   // offset: 28
+  UINT32 Latency;     // offset: 32
+  EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE ResidencyCounter; // offset: 36
+  UINT64 ResidencyCounterFrequency; //offset: 48
+} EFI_ACPI_MWAIT_LPI_STATE_DESCRIPTOR;
+
+
+//
+// Defines for LPIT table, some are VLV specific
+//
+
+
+// signature "LPIT"
+#define EFI_ACPI_LOW_POWER_IDLE_TABLE_SIGNATURE  0x5449504c
+
+#define EFI_ACPI_OEM_LPIT_REVISION                      0x00000000
+
+#define EFI_ACPI_LOW_POWER_IDLE_MWAIT_TYPE    0x0
+#define EFI_ACPI_LOW_POWER_IDLE_DEFAULT_FLAG  0x0
+#define EFI_ACPI_LOW_POWER_IDLE_RES_FREQ_8K   0x8000    // 32768
+
+//
+// LPI state count (4 on VLV: S0ir, S0i1, S0i2, S0i3)
+//
+
+#define EFI_ACPI_VLV_LPI_STATE_COUNT          0x4
+
+//
+// LPI TRIGGER (HW C7 on VLV),
+// TOFIX!!!
+//
+#define EFI_ACPI_VLV_LPI_TRIGGER {0x7F,0x1,0x2,0x0,0x64}
+
+//
+// LPI residency counter (MMIO)
+//
+#define  EFI_ACPI_VLV_LPI_RES_COUNTER0   {0x0,32,0x0,0x03,0xFED03080}
+#define  EFI_ACPI_VLV_LPI_RES_COUNTER1   {0x0,32,0x0,0x03,0xFED03084}
+#define  EFI_ACPI_VLV_LPI_RES_COUNTER2   {0x0,32,0x0,0x03,0xFED03088}
+#define  EFI_ACPI_VLV_LPI_RES_COUNTER3   {0x0,32,0x0,0x03,0xFED0308C}
+
+//
+// LPI break-even residency in us - all match S0i3 residency
+// Residency estimate: Latency x 3
+//
+#define  EFI_ACPI_VLV_LPI_MIN_RES0   15000
+#define  EFI_ACPI_VLV_LPI_MIN_RES1   15000
+#define  EFI_ACPI_VLV_LPI_MIN_RES2   15000
+#define  EFI_ACPI_VLV_LPI_MIN_RES3   15000
+
+//
+// LPI latency in us - all match S0i3 latency
+//
+#define  EFI_ACPI_VLV_LPI_LATENCY0   5000
+#define  EFI_ACPI_VLV_LPI_LATENCY1   5000
+#define  EFI_ACPI_VLV_LPI_LATENCY2   5000
+#define  EFI_ACPI_VLV_LPI_LATENCY3   5000
+
+
+//
+// LPI ID
+//
+#define  EFI_ACPI_VLV_LPI_UNIQUE_ID0   0
+#define  EFI_ACPI_VLV_LPI_UNIQUE_ID1   1
+#define  EFI_ACPI_VLV_LPI_UNIQUE_ID2   2
+#define  EFI_ACPI_VLV_LPI_UNIQUE_ID3   3
+
+//
+//  LPI ACPI table header
+//
+
+
+typedef struct _EFI_ACPI_LOW_POWER_IDLE_TABLE {
+  EFI_ACPI_DESCRIPTION_HEADER             Header;
+  EFI_ACPI_MWAIT_LPI_STATE_DESCRIPTOR     LpiStates[EFI_ACPI_VLV_LPI_STATE_COUNT];
+} EFI_ACPI_LOW_POWER_IDLE_TABLE;
+
+#pragma pack()
+
+EFI_ACPI_LOW_POWER_IDLE_TABLE Lpit = {
+
+  //
+  // Header
+  //
+
+
+  EFI_ACPI_LOW_POWER_IDLE_TABLE_SIGNATURE,
+  sizeof (EFI_ACPI_LOW_POWER_IDLE_TABLE),
+  EFI_ACPI_LOW_POWER_IDLE_TABLE_REVISION ,
+
+  //
+  // Checksum will be updated at runtime
+  //
+  0x00,
+
+  //
+  // It is expected that these values will be updated at runtime
+  //
+  ' ', ' ', ' ', ' ', ' ', ' ',
+
+  0,
+  EFI_ACPI_OEM_LPIT_REVISION,
+  0,
+  0,
+
+
+
+  //
+  // Descriptor
+  //
+  {
+    {
+      EFI_ACPI_LOW_POWER_IDLE_MWAIT_TYPE,
+      sizeof(EFI_ACPI_MWAIT_LPI_STATE_DESCRIPTOR),
+      EFI_ACPI_VLV_LPI_UNIQUE_ID0,
+      {0,0},
+      {EFI_ACPI_LOW_POWER_IDLE_DEFAULT_FLAG},   // Flags
+      EFI_ACPI_VLV_LPI_TRIGGER,  //EntryTrigger
+      EFI_ACPI_VLV_LPI_MIN_RES0, //Residency
+      EFI_ACPI_VLV_LPI_LATENCY0, //Latency
+      EFI_ACPI_VLV_LPI_RES_COUNTER0, //ResidencyCounter
+      EFI_ACPI_LOW_POWER_IDLE_RES_FREQ_8K //Residency counter frequency
+    },
+    {
+      EFI_ACPI_LOW_POWER_IDLE_MWAIT_TYPE,
+      sizeof(EFI_ACPI_MWAIT_LPI_STATE_DESCRIPTOR),
+      EFI_ACPI_VLV_LPI_UNIQUE_ID1,
+      {0,0},
+      {EFI_ACPI_LOW_POWER_IDLE_DEFAULT_FLAG},   // Flags
+      EFI_ACPI_VLV_LPI_TRIGGER,  //EntryTrigger
+      EFI_ACPI_VLV_LPI_MIN_RES1, //Residency
+      EFI_ACPI_VLV_LPI_LATENCY1, //Latency
+      EFI_ACPI_VLV_LPI_RES_COUNTER1, //ResidencyCounter
+      EFI_ACPI_LOW_POWER_IDLE_RES_FREQ_8K //Residency counter frequency
+    },
+    {
+      EFI_ACPI_LOW_POWER_IDLE_MWAIT_TYPE,
+      sizeof(EFI_ACPI_MWAIT_LPI_STATE_DESCRIPTOR),
+      EFI_ACPI_VLV_LPI_UNIQUE_ID2,
+      {0,0},
+      {EFI_ACPI_LOW_POWER_IDLE_DEFAULT_FLAG},   // Flags
+      EFI_ACPI_VLV_LPI_TRIGGER,  //EntryTrigger
+      EFI_ACPI_VLV_LPI_MIN_RES2, //Residency
+      EFI_ACPI_VLV_LPI_LATENCY2, //Latency
+      EFI_ACPI_VLV_LPI_RES_COUNTER2, //ResidencyCounter
+      EFI_ACPI_LOW_POWER_IDLE_RES_FREQ_8K //Residency counter frequency
+    },
+    {
+      EFI_ACPI_LOW_POWER_IDLE_MWAIT_TYPE,
+      sizeof(EFI_ACPI_MWAIT_LPI_STATE_DESCRIPTOR),
+      EFI_ACPI_VLV_LPI_UNIQUE_ID3,
+      {0,0},
+      {EFI_ACPI_LOW_POWER_IDLE_DEFAULT_FLAG},   // Flags
+      EFI_ACPI_VLV_LPI_TRIGGER,  //EntryTrigger
+      EFI_ACPI_VLV_LPI_MIN_RES3, //Residency
+      EFI_ACPI_VLV_LPI_LATENCY3, //Latency
+      EFI_ACPI_VLV_LPI_RES_COUNTER3, //ResidencyCounter
+      EFI_ACPI_LOW_POWER_IDLE_RES_FREQ_8K //Residency counter frequency
+    }
+  }
+
+};
+
+
+VOID*
+ReferenceAcpiTable (
+  VOID
+  )
+{
+  //
+  // Reference the table being generated to prevent the optimizer from
+  // removing the data structure from the executable
+  //
+  return (VOID*)&Lpit;
+}
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt.h
new file mode 100644
index 0000000000..72eb44e900
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt.h
@@ -0,0 +1,189 @@
+/*++
+
+Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+Module Name:
+
+  Madt.h
+
+Abstract:
+
+  This file describes the contents of the ACPI Multiple APIC Description
+  Table (MADT).  Some additional ACPI values are defined in Acpi1_0.h and
+  Acpi2_0.h.
+  To make changes to the MADT, it is necessary to update the count for the
+  APIC structure being updated, and to modify table found in Madt.c.
+
+--*/
+
+#ifndef _MADT_H
+#define _MADT_H
+
+//
+// Statements that include other files
+//
+#include "AcpiTablePlatform.h"
+#include <IndustryStandard/Acpi10.h>
+#include <IndustryStandard/Acpi20.h>
+#include <IndustryStandard/Acpi30.h>
+#include "Platform.h"
+
+//
+// MADT Definitions
+//
+#define EFI_ACPI_OEM_MADT_REVISION                      0x00000000
+//
+// Multiple APIC Flags are defined in AcpiX.0.h
+//
+#define EFI_ACPI_1_0_MULTIPLE_APIC_FLAGS  (EFI_ACPI_1_0_PCAT_COMPAT)
+#define EFI_ACPI_2_0_MULTIPLE_APIC_FLAGS  (EFI_ACPI_2_0_PCAT_COMPAT)
+#define EFI_ACPI_3_0_MULTIPLE_APIC_FLAGS  (EFI_ACPI_3_0_PCAT_COMPAT)
+#define EFI_ACPI_4_0_MULTIPLE_APIC_FLAGS  (EFI_ACPI_4_0_PCAT_COMPAT)
+
+//
+// Define the number of each table type.
+// This is where the table layout is modified.
+//
+#define EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT             MAX_CPU_NUM
+#define EFI_ACPI_LOCAL_APIC_NMI_COUNT                   MAX_CPU_NUM
+#define EFI_ACPI_IO_APIC_COUNT                          1
+#define EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT        2
+#define EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT    0
+#define EFI_ACPI_LOCAL_APIC_ADDRESS_OVERRIDE_COUNT      0
+#define EFI_ACPI_IO_SAPIC_COUNT                         0
+#define EFI_ACPI_PROCESSOR_LOCAL_SAPIC_COUNT            0
+#define EFI_ACPI_PLATFORM_INTERRUPT_SOURCES_COUNT       0
+
+//
+// MADT structure
+//
+//
+// Ensure proper structure formats
+//
+#pragma pack(1)
+//
+// ACPI 1.0 Table structure
+//
+typedef struct {
+  EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER   Header;
+
+#if EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT > 0
+  EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC_STRUCTURE           LocalApic[EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT];
+#endif
+
+#if EFI_ACPI_IO_APIC_COUNT > 0
+  EFI_ACPI_1_0_IO_APIC_STRUCTURE                        IoApic[EFI_ACPI_IO_APIC_COUNT];
+#endif
+
+#if EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT > 0
+  EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE      Iso[EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT];
+#endif
+
+#if EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT > 0
+  EFI_ACPI_1_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE  NmiSource[EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT];
+#endif
+
+#if EFI_ACPI_LOCAL_APIC_NMI_COUNT > 0
+  EFI_ACPI_1_0_LOCAL_APIC_NMI_STRUCTURE                 LocalApicNmi[EFI_ACPI_LOCAL_APIC_NMI_COUNT];
+#endif
+
+#if EFI_ACPI_LOCAL_APIC_ADDRESS_OVERRIDE_COUNT > 0
+  EFI_ACPI_1_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE    LocalApicOverride[EFI_ACPI_LOCAL_APIC_ADDRESS_OVERRIDE_COUNT];
+#endif
+
+} EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE;
+
+//
+// ACPI 2.0 Table structure
+//
+typedef struct {
+  EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER   Header;
+
+#if EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT > 0
+  EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE           LocalApic[EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT];
+#endif
+
+#if EFI_ACPI_IO_APIC_COUNT > 0
+  EFI_ACPI_2_0_IO_APIC_STRUCTURE                        IoApic[EFI_ACPI_IO_APIC_COUNT];
+#endif
+
+#if EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT > 0
+  EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE      Iso[EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT];
+#endif
+
+#if EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT > 0
+  EFI_ACPI_2_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE  NmiSource[EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT];
+#endif
+
+#if EFI_ACPI_LOCAL_APIC_NMI_COUNT > 0
+  EFI_ACPI_2_0_LOCAL_APIC_NMI_STRUCTURE                 LocalApicNmi[EFI_ACPI_LOCAL_APIC_NMI_COUNT];
+#endif
+
+#if EFI_ACPI_LOCAL_APIC_ADDRESS_OVERRIDE_COUNT > 0
+  EFI_ACPI_2_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE    LocalApicOverride[EFI_ACPI_LOCAL_APIC_ADDRESS_OVERRIDE_COUNT];
+#endif
+
+#if EFI_ACPI_IO_SAPIC_COUNT > 0
+  EFI_ACPI_2_0_IO_SAPIC_STRUCTURE                       IoSapic[EFI_ACPI_IO_SAPIC_COUNT];
+#endif
+
+#if EFI_ACPI_PROCESSOR_LOCAL_SAPIC_COUNT > 0
+  EFI_ACPI_2_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE          LocalSapic[EFI_ACPI_PROCESSOR_LOCAL_SAPIC_COUNT];
+#endif
+
+#if EFI_ACPI_PLATFORM_INTERRUPT_SOURCES_COUNT > 0
+  EFI_ACPI_2_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE     PlatformInterruptSources[EFI_ACPI_PLATFORM_INTERRUPT_SOURCES_COUNT];
+#endif
+
+} EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE;
+
+//
+// ACPI 3.0 Table structure
+//
+typedef struct {
+  EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER   Header;
+
+#if EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT > 0           // Type 0x00
+  EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_STRUCTURE           LocalApic[EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT];
+#endif
+
+#if EFI_ACPI_IO_APIC_COUNT > 0                        // Type 0x01
+  EFI_ACPI_3_0_IO_APIC_STRUCTURE                        IoApic[EFI_ACPI_IO_APIC_COUNT];
+#endif
+
+#if EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT > 0      // Type 0x02
+  EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE      Iso[EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT];
+#endif
+
+#if EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT > 0  // Type 0x03
+  EFI_ACPI_3_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE  NmiSource[EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT];
+#endif
+
+#if EFI_ACPI_LOCAL_APIC_NMI_COUNT > 0                 // Type 0x04
+  EFI_ACPI_3_0_LOCAL_APIC_NMI_STRUCTURE                 LocalApicNmi[EFI_ACPI_LOCAL_APIC_NMI_COUNT];
+#endif
+
+#if EFI_ACPI_LOCAL_APIC_ADDRESS_OVERRIDE_COUNT > 0    // Type 0x05
+  EFI_ACPI_3_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE    LocalApicOverride[EFI_ACPI_LOCAL_APIC_ADDRESS_OVERRIDE_COUNT];
+#endif
+
+#if EFI_ACPI_IO_SAPIC_COUNT > 0                       // Type 0x06
+  EFI_ACPI_3_0_IO_SAPIC_STRUCTURE                       IoSapic[EFI_ACPI_IO_SAPIC_COUNT];
+#endif
+
+#if EFI_ACPI_PROCESSOR_LOCAL_SAPIC_COUNT > 0          // Type 0x07 : This table changes in madt 2.0
+  EFI_ACPI_3_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE          LocalSapic[EFI_ACPI_PROCESSOR_LOCAL_SAPIC_COUNT];
+#endif
+
+#if EFI_ACPI_PLATFORM_INTERRUPT_SOURCES_COUNT > 0     // Type 0x08
+  EFI_ACPI_3_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE     PlatformInterruptSources[EFI_ACPI_PLATFORM_INTERRUPT_SOURCES_COUNT];
+#endif
+
+} EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE;
+
+#pragma pack()
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt30.aslc b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt30.aslc
new file mode 100644
index 0000000000..926b32f512
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt30.aslc
@@ -0,0 +1,178 @@
+/*++
+
+  Copyright (c) 2004  - 2015, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  Madt3.0.c
+
+Abstract:
+
+  This file contains a structure definition for the ACPI 2.0 Multiple APIC
+  Description Table (MADT).  Any changes to the MADT table require updating the
+  respective structure count in Madt.h and then adding the structure to the
+  MADT defined in this file.  The table layout is defined in Madt.h and the
+  table contents are defined in Acpi3_0.h and Madt.h.
+
+--*/
+
+//
+// Statements that include other files
+//
+#include "Madt.h"
+#include <IndustryStandard/Acpi50.h>
+
+//
+// Multiple APIC Description Table
+//
+EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE  Madt = {
+  EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, // **Signatures are the same 1.0-3.0 because it says "APIC".
+  sizeof (EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE),  // **Length
+  EFI_ACPI_5_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,
+  //
+  // EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,  // **Table Revision must be 2.0 for ACPI 3.0
+  // Checksum will be updated at runtime
+  //
+  0x00, // **Check sum
+  //
+  // It is expected that these values will be programmed at runtime
+  //
+  ' ',                        // OEMID
+  ' ',                        // Creative way to
+  ' ',                        // make six bytes
+  ' ',                        // of space in
+  ' ',                        // a table for
+  ' ',                        // **OEMID
+  0,                          // **OEM Table ID
+  EFI_ACPI_OEM_MADT_REVISION, // **OEM Revision
+  0,                          // **Creator ID
+  0,                          // **Creator Revision
+  //
+  // MADT specific fields
+  //
+  LOCAL_APIC_ADDRESS,               // **Local APIC Address
+  EFI_ACPI_4_0_MULTIPLE_APIC_FLAGS, // **Flags
+  //
+  // Processor Local APIC Structure
+  // Correct processor order, Primary threads first then Hyper threads
+  // And correct APIC-ids
+  // This text below is included as a reference until Thurley is 100%:
+  // According to EDS the Local APIC ID is determined based of a bit structure
+  // Bit 24: Core ID Bit 25: Core Pair ID Bit 26-27: Reserved Bit 28-30: Socket ID Bit 31: Reserved
+  // 4 Sockets and 4 Cores per Socket.
+  // So possible LAPIC IDs 00, 01, 02, 03, 10, 11, 12, 13, 20, 21, 22, 23, 30, 31, 32, 33
+  // Static Entries 00, 10, 20, 30, 01, 11, 21, 31, 02, 12, 22, 32, 03, 13, 23, 33
+  // BSP needs to be first entry in table. Check before boot. If BSP non zero need to rotate the entries.
+  // Suppore BSP is LAPIC ID xy. Rotate the table by using formula [x + (y * 4)]
+  // So if BSP LAPIC ID is 21 then table rotated 6 times.
+  // End of Reference Text.
+  // Thurley is supposed to be 2 sockets, 4 cores, and hyperthreading available per each core.
+  // 2 (sockets) x 4 (cores) = 8 (processors non-HT), 8 (processors non-HT) x 2 (HT/proc) = 16 (HT procs)
+  // Rhyme & reason of the ordering below.  This is a best guess ordering for now,
+  // Thurley EPS may give better info on LAPIC numbers.
+  // Ordering was established to help dissipate heat across two sockets evenly.
+  // Since logical processor number only has to be unique, I followed
+  // a similar approach to high end servers and have the first digit of the LAPIC
+  // id the socket number.
+  //
+  EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC,                    // Type 0x00
+  sizeof (EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_STRUCTURE), // Length
+  0x01,                                                 // Processor ID
+  0x00,                                                 // Local APIC ID
+  0x00000001,                                           // Flags - Disabled (until initialized by platform driver)
+  EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC,                    // Type
+  sizeof (EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_STRUCTURE), // Length
+  0x02,                                                 // Processor ID
+  0x04,                                                 // Local APIC ID 
+  0x00000001,                                           // Flags - Disabled (until initialized by platform driver)
+  EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC,                    // Type
+  sizeof (EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_STRUCTURE), // Length
+  0x03,                                                 // Processor ID
+  0x02,                                                 // Local APIC ID
+  0x00000001,                                           // Flags - Disabled (until initialized by platform driver)
+  EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC,                    // Type
+  sizeof (EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_STRUCTURE), // Length
+  0x04,                                                 // Processor ID
+  0x06,                                                 // Local APIC ID
+  0x00000001,                                           // Flags - Disabled (until initialized by platform driver)
+  //
+  // ***************   IO APIC Structure ******************
+  //
+  //
+  //
+  // **************************  I/O APIC  **************
+  //
+  EFI_ACPI_3_0_IO_APIC,                     // Type 0x01
+  sizeof (EFI_ACPI_3_0_IO_APIC_STRUCTURE),  // Length
+  ICH_IOAPIC_ID,                            // IO APIC ID
+  EFI_ACPI_RESERVED_BYTE,                   // Reserved    EFI_ACPI_RESERVED_BYTE
+  IO_APIC_ADDRESS,                          // IO APIC Address (physical)   0xFEC00000
+  0x18 * 0,                                 // Global System Interrupt Base
+
+  //
+  // Interrupt Source Override Structure: Sample
+  //
+  // EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE,                   // Type  0x02
+  // sizeof (EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE),// Length
+  // 0x00,                                                     // Bus
+  // 0x00,                                                     // Source
+  // 0x00000000,                                               // Global System Interrupt
+  // 0x0000,                                                   // Flags
+  //
+  // IRQ0=>IRQ2 Interrupt Source Override Structure
+  //
+  EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE, // Type  0x02
+  sizeof (EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE),  // Length
+  0x00,       // Bus - ISA
+  0x00,       // Source - IRQ0
+  0x00000002, // Global System Interrupt - IRQ2
+  0x0000,     // Flags - Conforms to specifications of the bus
+  //
+  // ISO (SCI Active High) Interrupt Source Override Structure
+  //
+  EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE, // Type  0x02
+  sizeof (EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE),  // Length
+  0x00,       // Bus - ISA
+  0x09,       // Source - IRQ0
+  0x00000009, // Global System Interrupt - IRQ2
+  0x000D,     // Flags - Level-tiggered, Active High
+
+
+
+  EFI_ACPI_3_0_LOCAL_APIC_NMI,                    // Type
+  sizeof (EFI_ACPI_3_0_LOCAL_APIC_NMI_STRUCTURE), // Length
+  0x01,                                           // ACPI Processor ID
+  0x000D,                                         // Flags - Level-tiggered, Active High
+  0x01,                                           // Local APIC LINT#
+  EFI_ACPI_3_0_LOCAL_APIC_NMI,                    // Type
+  sizeof (EFI_ACPI_3_0_LOCAL_APIC_NMI_STRUCTURE), // Length
+  0x02,                                           // ACPI Processor ID
+  0x000D,                                         // Flags - Level-tiggered, Active High
+  0x01,                                           // Local APIC LINT#
+  EFI_ACPI_3_0_LOCAL_APIC_NMI,                    // Type
+  sizeof (EFI_ACPI_3_0_LOCAL_APIC_NMI_STRUCTURE), // Length
+  0x03,                                           // ACPI Processor ID
+  0x000D,                                         // Flags - Level-tiggered, Active High
+  0x01,                                           // Local APIC LINT#
+  EFI_ACPI_3_0_LOCAL_APIC_NMI,                    // Type
+  sizeof (EFI_ACPI_3_0_LOCAL_APIC_NMI_STRUCTURE), // Length
+  0x04,                                           // ACPI Processor ID
+  0x000D,                                         // Flags - Level-tiggered, Active High
+  0x01,                                           // Local APIC LINT#
+};
+
+VOID*
+ReferenceAcpiTable (
+  VOID
+  )
+{
+  //
+  // Reference the table being generated to prevent the optimizer from
+  // removing the data structure from the executable
+  //
+  return (VOID*)&Madt;
+}
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Mcfg/Mcfg.aslc b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Mcfg/Mcfg.aslc
new file mode 100644
index 0000000000..9373c542f6
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Mcfg/Mcfg.aslc
@@ -0,0 +1,86 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  Mcfg.c
+
+Abstract:
+
+  This file contains a structure definition for the ACPI Memory mapped
+  configuration space base address Description Table (MCFG).  Any changes
+  to the MCFG table require updating the respective structure count in
+  Mcfg.h and then adding the structure to the MCFG defined in this file.
+  The table layout is defined in Mcfg.h and the table contents are defined
+  in McfgTable.h and Mcfg.h.
+
+--*/
+
+//
+// Statements that include other files
+//
+#include <Mcfg.h>
+
+//
+// MCFG Table definition
+//
+EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE MCFG = {
+  EFI_ACPI_3_0_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_SIGNATURE,
+  sizeof (EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE),
+  EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_REVISION,
+  //
+  // Checksum will be updated at runtime
+  //
+  0x00,
+  //
+  // It is expected that these values will be programmed at runtime
+  //
+  ' ',
+  ' ',
+  ' ',
+  ' ',
+  ' ',
+  ' ',
+
+  0,
+  EFI_ACPI_OEM_MCFG_REVISION,
+  0,
+  0,
+  //
+  // Beginning of MCFG specific fields
+  //
+  EFI_ACPI_RESERVED_QWORD,
+  //
+  // Sample Memory Mapped Configuration Space Base Address Structure
+  //
+  // 0x0,                                                              // Base Address
+  // 0x0,                                                              // PCI Segment Group Number
+  // 0x0,                                                              // Start Bus Number
+  // 0x0,                                                              // End Bus Number
+  // EFI_ACPI_RESERVED_DWORD,                                          // Reserved
+  //
+  // Memory Mapped Configuration Space Base Address Structure
+  //
+  0x0,                      // Base Address, will be updated by AcpiPlatform
+  0x0,                      // PCI Segment Group Number
+  0x0,                      // Start Bus Number
+  PLATFORM_MAX_BUS_NUM,     // End Bus Number
+  EFI_ACPI_RESERVED_DWORD,  // Reserved
+};
+
+VOID*
+ReferenceAcpiTable (
+  VOID
+  )
+{
+  //
+  // Reference the table being generated to prevent the optimizer from
+  // removing the data structure from the executable
+  //
+  return (VOID*)&MCFG;
+}
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PCI_DRC.ASL b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PCI_DRC.ASL
new file mode 100644
index 0000000000..a475040898
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PCI_DRC.ASL
@@ -0,0 +1,90 @@
+/**************************************************************************;
+;*                                                                        *;
+;*                                                                        *;
+;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
+;*    Family of Customer Reference Boards.                                *;
+;*                                                                        *;
+;*                                                                        *;
+;*    Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved    *;
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;*                                                                        *;
+;*                                                                        *;
+;**************************************************************************/
+
+
+
+Scope (\_SB.PCI0)
+{
+
+  Device(PDRC)   // PCI Device Resource Consumption
+  {
+    Name(_HID,EISAID("PNP0C02"))
+
+    Name(_UID,1)
+
+    Name(BUF0,ResourceTemplate()
+    {
+      //
+      // PCI Express BAR _BAS and _LEN will be updated in _CRS below according to B0:D0:F0:Reg.60h
+      // Forced hard code at the moment.
+      //
+      //Memory32Fixed(ReadWrite,0,0,PCIX)       // PCIEX BAR
+      Memory32Fixed(ReadWrite,0x0E0000000,0x010000000,PCIX)
+
+      //
+      // SPI BAR. Check if the hard code meets the real configuration.
+      // If not, dynamically update it like the _CRS method below.
+      //
+      Memory32Fixed(ReadWrite,0x0FED01000,0x01000,SPIB) // SPI BAR
+
+      //
+      // PMC BAR. Check if the hard code meets the real configuration.
+      // If not, dynamically update it like the _CRS method below.
+      //
+      Memory32Fixed(ReadWrite,0x0FED03000,0x01000,PMCB) // PMC BAR
+
+      //
+      // SMB BAR. Check if the hard code meets the real configuration.
+      // If not, dynamically update it like the _CRS method below.
+      //
+      Memory32Fixed(ReadWrite,0x0FED04000,0x01000,SMBB) // SMB BAR
+
+      //
+      // IO BAR. Check if the hard code meets the real configuration.
+      // If not, dynamically update it like the _CRS method below.
+      //
+      Memory32Fixed(ReadWrite,0x0FED0C000,0x04000,IOBR) // IO BAR
+
+      //
+      // ILB BAR. Check if the hard code meets the real configuration.
+      // If not, dynamically update it like the _CRS method below.
+      //
+      Memory32Fixed(ReadWrite,0x0FED08000,0x01000,ILBB) // ILB BAR
+
+      //
+      // RCRB BAR _BAS will be updated in _CRS below according to B0:D31:F0:Reg.F0h
+      //
+      Memory32Fixed(ReadWrite,0x0FED1C000,0x01000,RCRB) // RCRB BAR
+
+      //
+      // Local APIC range(0xFEE0_0000 to 0xFEEF_FFFF)
+      //
+      Memory32Fixed (ReadOnly, 0x0FEE00000, 0x0100000, LIOH)
+
+      //
+      // MPHY BAR. Check if the hard code meets the real configuration.
+      // If not, dynamically update it like the _CRS method below.
+      //
+      Memory32Fixed(ReadWrite,0x0FEF00000,0x0100000,MPHB)       // MPHY BAR
+    })
+
+    Method(_CRS,0,Serialized)
+    {
+
+      Return(BUF0)
+    }
+
+  }
+}
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Pch.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Pch.asl
new file mode 100644
index 0000000000..af8aceb515
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Pch.asl
@@ -0,0 +1,686 @@
+/**************************************************************************;
+;*                                                                        *;
+;*                                                                        *;
+;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
+;*    Family of Customer Reference Boards.                                *;
+;*                                                                        *;
+;*                                                                        *;
+;*    Copyright (c) 2012  - 2016, Intel Corporation. All rights reserved    *;
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;*                                                                        *;
+;*                                                                        *;
+;**************************************************************************/
+
+
+Scope(\)
+{
+  //
+  // Define VLV ABASE I/O as an ACPI operating region. The base address
+  // can be found in Device 31, Registers 40-43h.
+  //
+  OperationRegion(PMIO, SystemIo, \PMBS, 0x46)
+  Field(PMIO, ByteAcc, NoLock, Preserve)
+  {
+    ,      8,
+    PWBS,  1,       // Power Button Status
+    Offset(0x20),
+    ,      13,
+    PMEB,  1,     // PME_B0_STS
+    Offset(0x42),     // General Purpose Control
+    ,      1,
+    GPEC,  1
+  }
+  Field(PMIO, ByteAcc, NoLock, WriteAsZeros)
+  {
+    Offset(0x20),     // GPE0 Status
+    ,      4,
+    PSCI,  1,       // PUNIT SCI Status
+    SCIS,  1        // GUNIT SCI Status
+  }
+
+
+
+  //
+  // Define a Memory Region that will allow access to the PMC
+  // Register Block.  Note that in the Intel Reference Solution, the PMC
+  // will get fixed up dynamically during POST.
+  //
+  OperationRegion(PMCR, SystemMemory, \PFDR, 0x04)// PMC Function Disable Register
+  Field(PMCR,DWordAcc,Lock,Preserve)
+  {
+    Offset(0x00),   //  Function Disable Register
+    L10D,  1,         //  (0) LPIO1 DMA Disable
+    L11D,  1,         //  (1) LPIO1 PWM #1 Disable
+    L12D,  1,         //  (2) LPIO1 PWM #2 Disable
+    L13D,  1,         //  (3) LPIO1 HS-UART #1 Disable
+    L14D,  1,         //  (4) LPIO1 HS-UART #2 Disable
+    L15D,  1,         //  (5) LPIO1 SPI Disable
+    ,          2,     //  (6:7) Reserved
+    SD1D,  1,         //  (8) SCC SDIO #1 Disable
+    SD2D,  1,         //  (9) SCC SDIO #2 Disable
+    SD3D,  1,         //  (10) SCC SDIO #3 Disable
+    HSID,  1,         //  (11)
+    HDAD,  1,         //  (12) Azalia Disable
+    LPED,  1,         //  (13) LPE Disable
+    OTGD,  1,         //  (14) USB OTG Disable
+    ,          1,     //  (15) USH Disable
+    ,          1,     //  (16)
+    ,          1,     //  (17)
+    ,          1,     //  (18) USB Disable
+    ,          1,     //  (19) SEC Disable
+    RP1D,  1,         //  (20) Root Port 0 Disable
+    RP2D,  1,         //  (21) Root Port 1 Disable
+    RP3D,  1,         //  (22) Root Port 2 Disable
+    RP4D,  1,         //  (23) Root Port 3 Disable
+    L20D,  1,         //  (24) LPIO2 DMA Disable
+    L21D,  1,         //  (25) LPIO2 I2C #1 Disable
+    L22D,  1,         //  (26) LPIO2 I2C #2 Disable
+    L23D,  1,         //  (27) LPIO2 I2C #3 Disable
+    L24D,  1,         //  (28) LPIO2 I2C #4 Disable
+    L25D,  1,         //  (29) LPIO2 I2C #5 Disable
+    L26D,  1,         //  (30) LPIO2 I2C #6 Disable
+    L27D,  1          //  (31) LPIO2 I2C #7 Disable
+  }
+
+
+  OperationRegion(CLKC, SystemMemory, \PCLK, 0x18)// PMC CLK CTL Registers
+  Field(CLKC,DWordAcc,Lock,Preserve)
+  {
+    Offset(0x00),   //  PLT_CLK_CTL_0
+    CKC0, 2,
+    CKF0, 1,
+    ,     29,
+    Offset(0x04),   //  PLT_CLK_CTL_1
+    CKC1, 2,
+    CKF1, 1,
+    ,     29,
+    Offset(0x08),   //  PLT_CLK_CTL_2
+    CKC2,  2,
+    CKF2, 1,
+    ,     29,
+    Offset(0x0C),   //  PLT_CLK_CTL_3
+    CKC3,  2,
+    CKF3, 1,
+    ,     29,
+    Offset(0x10),   //  PLT_CLK_CTL_4
+    CKC4,  2,
+    CKF4, 1,
+    ,     29,
+    Offset(0x14),   //  PLT_CLK_CTL_5
+    CKC5,  2,
+    CKF5, 1,
+    ,     29,
+  }
+} //end Scope(\)
+
+scope (\_SB)
+{
+  Device(LPEA)
+  {
+    Name (_ADR, 0)
+    Name (_HID, "80860F28")
+    Name (_CID, "80860F28")
+    //Name (_CLS, Package (3) {0x04, 0x01, 0x00})
+    Name (_DDN, "Intel(R) Low Power Audio Controller - 80860F28")
+    Name (_SUB, "80867270")
+    Name (_UID, 1)
+    Name (_DEP, Package() {\_SB.I2C2.RTEK})
+    Name(_PR0,Package() {PLPE})
+
+    Method (_STA, 0x0, NotSerialized)
+    {
+      If (LAnd(LAnd(LEqual(LPEE, 2), LEqual(LPED, 0)), LEqual(OSEL, 0)))
+      {
+        If(LEqual(LPAD, 1))
+        {
+          Return (0xF)
+        }
+      }
+      Return (0x0)
+    }
+
+    Method (_DIS, 0x0, NotSerialized)
+    {
+      //Add a dummy disable function
+    }
+
+    Name (RBUF, ResourceTemplate ()
+      {
+        Memory32Fixed (ReadWrite, 0xFE400000, 0x00200000, BAR0)  // MMIO 1 - LPE MMIO
+        Memory32Fixed (ReadWrite, 0xFE830000, 0x00001000, BAR1)  // MMIO 2 - Shadowed PCI Config Space
+        Memory32Fixed (ReadWrite, 0x55AA55AA, 0x00100000, BAR2)  // LPE Memory Bar Allocate during post
+        Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {24}
+        Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {25}
+        Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {26}
+        Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {27}
+        Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {28}
+        Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {29}
+        GpioInt(Edge, ActiveBoth, ExclusiveAndWake, PullNone, 0,"\\_SB.GPO2") {28} //  Audio jack interrupt
+      }
+    )
+
+    Method (_CRS, 0x0, NotSerialized)
+    {
+      CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
+      Store(LPE0, B0BA)
+      CreateDwordField(^RBUF, ^BAR1._BAS, B1BA)
+      Store(LPE1, B1BA)
+      CreateDwordField(^RBUF, ^BAR2._BAS, B2BA)
+      Store(LPE2, B2BA)
+      Return (RBUF)
+    }
+
+    OperationRegion (KEYS, SystemMemory, LPE1, 0x100)
+    Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+    {
+      Offset (0x84),
+      PSAT,   32
+    }
+
+    PowerResource(PLPE, 0, 0)   // Power Resource for LPEA
+    {
+      Method (_STA)
+      {
+        Return (1)      // Power Resource is always available.
+      }
+
+      Method (_ON)
+      {
+        And(PSAT, 0xfffffffC, PSAT)
+        OR(PSAT, 0X00000000, PSAT)
+      }
+
+      Method (_OFF)
+      {
+        OR(PSAT, 0x00000003, PSAT)
+        OR(PSAT, 0X00000000, PSAT)
+      }
+    } // End PLPE
+  } // End "Low Power Engine Audio"
+
+  Device(LPA2)
+  {
+    Name (_ADR, 0)
+    Name (_HID, "LPE0F28")  // _HID: Hardware ID
+    Name (_CID, "LPE0F28")  // _CID: Compatible ID
+    Name (_DDN, "Intel(R) SST Audio - LPE0F28")  // _DDN: DOS Device Name
+    Name (_SUB, "80867270")
+    Name (_UID, 1)
+    Name (_DEP, Package() {\_SB.I2C2.RTEK})
+    Name(_PR0,Package() {PLPE})
+
+    Method (_STA, 0x0, NotSerialized)
+    {
+      If (LAnd(LAnd(LEqual(LPEE, 2), LEqual(LPED, 0)), LEqual(OSEL, 1)))
+      {
+        If(LEqual(LPAD, 1))
+        {
+          Return (0xF)
+        }
+      }
+      Return (0x0)
+    }
+
+    Method (_DIS, 0x0, NotSerialized)
+    {
+      //Add a dummy disable function
+    }
+
+    Name (RBUF, ResourceTemplate ()
+      {
+        Memory32Fixed (ReadWrite, 0x55AA55AA, 0x00100000, BAR2)  // LPE Memory Bar Allocate during post
+        Memory32Fixed (ReadWrite, 0x55AA55AA, 0x00000100, SHIM)
+        Memory32Fixed (ReadWrite, 0x55AA55AA, 0x00001000, MBOX)
+        Memory32Fixed (ReadWrite, 0x55AA55AA, 0x00014000, IRAM)
+        Memory32Fixed (ReadWrite, 0x55AA55AA, 0x00028000, DRAM)
+        Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {29}
+        Memory32Fixed (ReadWrite, 0xFE830000, 0x00001000, BAR1)  // MMIO 2 - Shadowed PCI Config Space
+      }
+    )
+
+    Method (_CRS, 0x0, NotSerialized)
+    {
+      CreateDwordField(^RBUF, ^SHIM._BAS, SHBA)
+      Add(LPE0, 0x140000, SHBA)
+      CreateDwordField(^RBUF, ^MBOX._BAS, MBBA)
+      Add(LPE0, 0x144000, MBBA)
+      CreateDwordField(^RBUF, ^IRAM._BAS, IRBA)
+      Add(LPE0, 0xC0000, IRBA)
+      CreateDwordField(^RBUF, ^DRAM._BAS, DRBA)
+      Add(LPE0, 0x100000, DRBA)
+      CreateDwordField(^RBUF, ^BAR1._BAS, B1BA)
+      Store(LPE1, B1BA)
+      CreateDwordField(^RBUF, ^BAR2._BAS, B2BA)
+      Store(LPE2, B2BA)
+      Return (RBUF)
+    }
+
+    OperationRegion (KEYS, SystemMemory, LPE1, 0x100)
+    Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+    {
+      Offset (0x84),
+      PSAT,   32
+    }
+
+    PowerResource(PLPE, 0, 0)   // Power Resource for LPEA
+    {
+      Method (_STA)
+      {
+        Return (1)      // Power Resource is always available.
+      }
+
+      Method (_ON)
+      {
+        And(PSAT, 0xfffffffC, PSAT)
+        OR(PSAT, 0X00000000, PSAT)
+      }
+
+      Method (_OFF)
+      {
+        OR(PSAT, 0x00000003, PSAT)
+        OR(PSAT, 0X00000000, PSAT)
+      }
+    } // End PLPE
+
+    Device (ADMA)
+    {
+      Name (_ADR, Zero)  // _ADR: Address
+      Name (_HID, "DMA0F28")  // _HID: Hardware ID
+      Name (_CID, "DMA0F28")  // _CID: Compatible ID
+      Name (_DDN, "Intel(R) Audio  DMA0 - DMA0F28")  // _DDN: DOS Device Name
+      Name (_UID, One)  // _UID: Unique ID
+      Name (RBUF, ResourceTemplate ()
+      {
+        Memory32Fixed (ReadWrite, 0x55AA55AA, 0x00001000, DMA0)  // LPE BASE + LPE DMA0 offset
+        Memory32Fixed (ReadWrite, 0x55AA55AA, 0x00001000, SHIM)  // LPE BASE + LPE SHIM offset
+        Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {24}
+      })
+
+      Method (_CRS, 0, NotSerialized)   // _CRS: Current Resource Settings
+      {
+        CreateDwordField(^RBUF, ^DMA0._BAS, D0BA)
+        Add(LPE0, 0x98000, D0BA)
+        CreateDwordField(^RBUF, ^SHIM._BAS, SHBA)
+        Add(LPE0, 0x140000, SHBA)
+        Return (RBUF)
+      }
+    }
+  } // End "Low Power Engine Audio" for Android
+}
+
+scope (\_SB.PCI0)
+{
+
+  //
+  // Serial ATA Host Controller - Device 19, Function 0
+  //
+
+  Device(SATA)
+  {
+    Name(_ADR,0x00130000)
+    //
+    // SATA Methods pulled in via SSDT.
+    //
+
+    OperationRegion(SATR, PCI_Config, 0x74,0x4)
+    Field(SATR,WordAcc,NoLock,Preserve)
+    {
+      Offset(0x00), // 0x74, PMCR
+      ,   8,
+      PMEE,   1,    //PME_EN
+      ,   6,
+      PMES,   1     //PME_STS
+    }
+
+    Method (_STA, 0x0, NotSerialized)
+    {
+      Return(0xf)
+    }
+
+    Method(_DSW, 3)
+    {
+    } // End _DSW
+  }
+
+  //
+  // For eMMC 4.41 PCI mode in order to present non-removable device under Windows environment
+  //
+  Device(EM41)
+  {
+    Name(_ADR,0x00100000)
+    OperationRegion(SDIO, PCI_Config, 0x84,0x4)
+    Field(SDIO,WordAcc,NoLock,Preserve)
+    {
+      Offset(0x00), // 0x84, PMCR
+      ,   8,
+      PMEE,   1,    //PME_EN
+      ,   6,
+      PMES,   1     //PME_STS
+    }
+
+    Method (_STA, 0x0, NotSerialized)
+    {
+      If (LAnd(LEqual(PCIM, 1), LEqual(SD1D, 0)))
+      {
+        Return(0xF)
+      }
+      Else
+      {
+        Return(0x0)
+      }
+    }
+
+    Method(_DSW, 3)
+    {
+    } // End _DSW
+
+    Device (CARD)
+    {
+      Name (_ADR, 0x00000008)
+      Method(_RMV, 0x0, NotSerialized)
+      {
+        Return (0)
+      } // End _DSW
+    }
+  }
+
+  //
+  // For eMMC 4.5 PCI mode in order to present non-removable device under Windows environment
+  //
+  Device(EM45)
+  {
+    Name(_ADR,0x00170000)
+    OperationRegion(SDIO, PCI_Config, 0x84,0x4)
+    Field(SDIO,WordAcc,NoLock,Preserve)
+    {
+      Offset(0x00), // 0x84, PMCR
+      ,   8,
+      PMEE,   1,    //PME_EN
+      ,   6,
+      PMES,   1     //PME_STS
+    }
+
+    Method (_STA, 0x0, NotSerialized)
+    {
+      If (LAnd(LEqual(PCIM, 1), LEqual(HSID, 0)))
+      {
+        Return(0xF)
+      }
+      Else
+      {
+        Return(0x0)
+      }
+    }
+
+    Method(_DSW, 3)
+    {
+    } // End _DSW
+
+    Device (CARD)
+    {
+      Name (_ADR, 0x00000008)
+      Method(_RMV, 0x0, NotSerialized)
+      {
+        Return (0)
+      } // End _DSW
+    }
+  }
+  //
+  // For SD Host Controller (Bus 0x00 : Dev 0x12 : Func 0x00) PCI mode in order to present non-removable device under Windows environment
+  //
+  Device(SD12)
+  {
+    Name(_ADR,0x00120000)
+
+    Method (_STA, 0x0, NotSerialized)
+    {
+      //
+      // PCIM>> 0:ACPI mode           1:PCI mode
+      //
+      If (LEqual(PCIM, 0)) {
+        Return (0x0)
+      }
+
+      //
+      // If device is disabled.
+      //
+      If (LEqual(SD3D, 1))
+      {
+        Return (0x0)
+      }
+
+      Return (0xF)
+    }
+
+    Device (CARD)
+    {
+      Name (_ADR, 0x00000008)
+      Method(_RMV, 0x0, NotSerialized)
+      {
+        // SDRM = 0 non-removable;
+        If (LEqual(SDRM, 0))
+        {
+          Return (0)
+        }
+
+        Return (1)
+      }
+    }
+  }
+
+  // xHCI Controller - Device 20, Function 0
+  include("PchXhci.asl")
+
+  //
+  // High Definition Audio Controller - Device 27, Function 0
+  //
+  Device(HDEF)
+  {
+    Name(_ADR, 0x001B0000)
+    include("PchAudio.asl")
+
+    Method (_STA, 0x0, NotSerialized)
+    {
+      If (LEqual(HDAD, 0))
+      {
+        Return(0xf)
+      }
+      Return(0x0)
+    }
+
+    Method(_DSW, 3)
+    {
+    } // End _DSW
+  } // end "High Definition Audio Controller"
+
+
+
+  //
+  // PCIE Root Port #1
+  //
+  Device(RP01)
+  {
+    Name(_ADR, 0x001C0000)
+    include("PchPcie.asl")
+    Name(_PRW, Package() {9, 4})
+
+    Method(_PRT,0)
+    {
+      If(PICM) { Return(AR04) }// APIC mode
+      Return (PR04) // PIC Mode
+    } // end _PRT
+  } // end "PCIE Root Port #1"
+
+  //
+  // PCIE Root Port #2
+  //
+  Device(RP02)
+  {
+    Name(_ADR, 0x001C0001)
+    include("PchPcie.asl")
+    Name(_PRW, Package() {9, 4})
+
+    Method(_PRT,0)
+    {
+      If(PICM) { Return(AR05) }// APIC mode
+      Return (PR05) // PIC Mode
+    } // end _PRT
+
+  } // end "PCIE Root Port #2"
+
+  //
+  // PCIE Root Port #3
+  //
+  Device(RP03)
+  {
+    Name(_ADR, 0x001C0002)
+    include("PchPcie.asl")
+    Name(_PRW, Package() {9, 4})
+    Method(_PRT,0)
+    {
+      If(PICM) { Return(AR06) }// APIC mode
+      Return (PR06) // PIC Mode
+    } // end _PRT
+
+  } // end "PCIE Root Port #3"
+
+  //
+  // PCIE Root Port #4
+  //
+  Device(RP04)
+  {
+    Name(_ADR, 0x001C0003)
+    include("PchPcie.asl")
+    Name(_PRW, Package() {9, 4})
+    Method(_PRT,0)
+    {
+      If(PICM) { Return(AR07) }// APIC mode
+      Return (PR07) // PIC Mode
+    } // end _PRT
+
+  } // end "PCIE Root Port #4"
+
+
+  Scope(\_SB)
+  {
+    //
+    // Dummy power resource for USB D3 cold support
+    //
+    PowerResource(USBC, 0, 0)
+    {
+      Method(_STA) { Return (0xF) }
+      Method(_ON) {}
+      Method(_OFF) {}
+    }
+  }
+  //
+  // EHCI Controller - Device 29, Function 0
+  //
+  Device(EHC1)
+  {
+    Name(_ADR, 0x001D0000)
+    Name(_DEP, Package(0x1)
+    {
+      PEPD
+    })
+    include("PchEhci.asl")
+    Name(_PRW, Package() {0x0D, 4})
+
+    OperationRegion(USBR, PCI_Config, 0x54,0x4)
+    Field(USBR,WordAcc,NoLock,Preserve)
+    {
+      Offset(0x00), // 0x54, PMCR
+      ,   8,
+      PMEE,   1,    //PME_EN
+      ,   6,
+      PMES,   1     //PME_STS
+    }
+
+    Method (_STA, 0x0, NotSerialized)
+    {
+      If(LEqual(XHCI, 0))      //XHCI is not present. It means EHCI is there
+      {
+        Return (0xF)
+      } Else
+      {
+        Return (0x0)
+      }
+    }
+
+    Method (_RMV, 0, NotSerialized)
+    {
+      Return (0x0)
+    }
+    //
+    // Create a dummy PR3 method to indicate to the PCI driver
+    // that the device is capable of D3 cold
+    //
+    Method(_PR3, 0x0, NotSerialized)
+    {
+      return (Package() {\_SB.USBC})
+    }
+
+  } // end "EHCI Controller"
+
+  //
+  // SMBus Controller - Device 31, Function 3
+  //
+  Device(SBUS)
+  {
+    Name(_ADR,0x001F0003)
+    Include("PchSmb.asl")
+  }
+
+  Device(SEC0)
+  {
+    Name (_ADR, 0x001a0000)                     // Device 0x1a, Function 0
+    Name(_DEP, Package(0x1)
+    {
+      PEPD
+    })
+
+
+    OperationRegion (PMEB, PCI_Config, 0x84, 0x04)  //PMECTRLSTATUS
+    Field (PMEB, WordAcc, NoLock, Preserve)
+    {
+      ,   8,
+      PMEE,   1,    //bit8 PMEENABLE
+      ,   6,
+      PMES,   1     //bit15 PMESTATUS
+    }
+
+    // Arg0 -- integer that contains the device wake capability control (0-disable 1- enable)
+    // Arg1 -- integer that contains target system state (0-4)
+    // Arg2 -- integer that contains the target device state
+    Method (_DSW, 3, NotSerialized)   // _DSW: Device Sleep Wake
+    {
+    }
+
+    Method (_CRS, 0, NotSerialized)
+    {
+      Name (RBUF, ResourceTemplate ()
+      {
+        Memory32Fixed (ReadWrite, 0x1e000000, 0x2000000)
+      })
+
+      If (LEqual(PAVP, 2))
+      {
+        Return (RBUF)
+      }
+      Return (ResourceTemplate() {})
+    }
+
+    Method (_STA)
+    {
+      If (LNotEqual(PAVP, 0))
+      {
+        Return (0xF)
+      }
+      Return (0x0)
+    }
+  }   // Device(SEC0)
+
+} // End scope (\_SB.PCI0)
+
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchAudio.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchAudio.asl
new file mode 100644
index 0000000000..4dd5e6f756
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchAudio.asl
@@ -0,0 +1,36 @@
+/**************************************************************************;
+;*                                                                        *;
+;*                                                                        *;
+;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
+;*    Family of Customer Reference Boards.                                *;
+;*                                                                        *;
+;*                                                                        *;
+;*    Copyright (c)  2011  - 2014, Intel Corporation. All rights reserved   *;
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;*                                                                        *;
+;*                                                                        *;
+;**************************************************************************/
+//
+// High Definition Audio - Device 27, Function 0
+//
+OperationRegion(HDAR, PCI_Config, 0x4C,0x10)
+Field(HDAR,WordAcc,NoLock,Preserve)
+{
+  Offset(0x00), // 0x4C, Dock Control Register
+  DCKA,    1,   // Dock Attach
+  ,    7,
+  Offset(0x01), // 04Dh, Dock Status Register
+  DCKM,    1,   // Dock Mated
+  ,    6,
+  DCKS,    1,   // Docking Supported
+  Offset(0x08), // 0x54, Power Management Control and Status Register
+  ,    8,
+  PMEE,    1,   // PME_EN
+  ,    6,
+  PMES,    1    // PME Status
+}
+
+
+
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchEhci.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchEhci.asl
new file mode 100644
index 0000000000..c058cd0c3e
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchEhci.asl
@@ -0,0 +1,269 @@
+/***************************************************************************************;
+;*                                                                                     *;
+;*                                                                                     *;
+;*    Intel Corporation - ACPI Reference Code for the Baytrail                         *;
+;*    Family of Customer Reference Boards.                                             *;
+;*                                                                                     *;
+;*                                                                                     *;
+;*    Copyright (c)  2011  - 2014, Intel Corporation. All rights reserved              *;
+;*                                                                                     *;
+;*   ThSPDX-License-Identifier: BSD-2-Clause-Patent
+;*                                                                                     *;
+;*                                                                                     *;
+;*                                                                                     *;
+;***************************************************************************************/
+
+OperationRegion(PWKE,PCI_Config,0x62,0x04)
+
+Field(PWKE,DWordAcc,NoLock,Preserve)
+{
+  , 1,
+  PWUC, 8 // Port Wake Up Capability Mask
+}
+
+Method(_PSW,1)
+{
+  If(Arg0)
+  {
+    Store(Ones,PWUC)
+  }
+  Else
+  {
+    Store(0,PWUC)
+  }
+}
+
+// Leaves the USB ports on in S3/S4 to allow
+// the ability to Wake from USB.  Therefore, define
+// the below control methods to state D2 entry during
+// the given S-State.
+
+Method(_S3D,0)
+{
+  Return(2)
+}
+
+Method(_S4D,0)
+{
+  Return(2)
+}
+
+Device(HUBN)
+{
+  Name(_ADR, Zero)
+  Device(PR01)
+  {
+    Name(_ADR, One)
+
+    //
+    // There will have "Generic USB Hub" existed at Port 1 of each EHCI controller
+    // in Windows "Device Manager" while RMH is enabled, so need to add _UPC
+    // and _PLD to report OS that it's not user visible to pass WHQL: Single Computer
+    // Display Object test in Win7
+    //
+    Name(_UPC, Package()
+    {
+      0xFF,                       // Port is connectable
+      0x00,                       // Connector type - Type "A"
+      0x00000000,                 // Reserved 0 - must be zero
+      0x00000000
+    })                // Reserved 1 - must be zero
+
+    Name(_PLD, Package()
+    {
+      Buffer (0x10)
+      {
+        0x81, 0x00, 0x00, 0x00,     // Revision 1, Ignore color
+        0x00, 0x00, 0x00, 0x00,
+        0x30, 0x1C, 0x00, 0x00,     // Panel Unknown, Shape Unknown
+        0x00, 0x00, 0x00, 0x00
+      }
+    })
+
+    Device(PR11)
+    {
+      Name(_ADR, One)
+      Name(_UPC, Package()
+      {
+        0xFF,                       // Port is connectable
+        0xFF,                       // Proprietary connector
+        0x00000000,                 // Reserved 0 - must be zero
+        0x00000000
+      })                // Reserved 1 - must be zero
+      Name(_PLD, Package()
+      {
+        Buffer (0x10)
+        {
+          0x81, 0x00, 0x00, 0x00,     // Revision 1, Ignore color
+          0x00, 0x00, 0x00, 0x00,
+          0xE1, 0x1C, 0x00, 0x00,     // Front Panel, Vertical Upper, Horz. Left, Shape Unknown
+          0x00, 0x00, 0x00, 0x00
+        }
+      })
+    }
+
+    Device(PR12)
+    {
+      Name(_ADR, 0x02)
+      Name(_UPC, Package()
+      {
+        0xFF,                       // Port is connectable
+        0xFF,                       // Proprietary connector
+        0x00000000,                 // Reserved 0 - must be zero
+        0x00000000
+      })                // Reserved 1 - must be zero
+      Name(_PLD, Package()
+      {
+        Buffer (0x10)
+        {
+          0x81, 0x00, 0x00, 0x00,     // Revision 1, Ignore color
+          0x00, 0x00, 0x00, 0x00,
+          0xE1, 0x1D, 0x00, 0x00,     // Front Panel, Vertical Center, Horz. Left, Shape Unknown
+          0x00, 0x00, 0x00, 0x00
+        }
+      })
+    }
+
+    Device(PR13)
+    {
+      Name(_ADR, 0x03)
+      Name(_UPC, Package()
+      {
+        0xFF,                       // Port is connectable
+        0xFF,                       // Proprietary connector
+        0x00000000,                 // Reserved 0 - must be zero
+        0x00000000
+      })                // Reserved 1 - must be zero
+      Name(_PLD, Package()
+      {
+        Buffer (0x10)
+        {
+          0x81, 0x00, 0x00, 0x00,     // Revision 1, Ignore color
+          0x00, 0x00, 0x00, 0x00,
+          0xE1, 0x1D, 0x00, 0x00,     // Front Panel, Vertical Center, Horz. Left, Shape Unknown
+          0x00, 0x00, 0x00, 0x00
+        }
+      })
+    }
+
+    Device(PR14)
+    {
+      Name(_ADR, 0x04)
+      Name(_UPC, Package()
+      {
+        0xFF,                       // Port is connectable
+        0xFF,                       // Proprietary connector
+        0x00000000,                 // Reserved 0 - must be zero
+        0x00000000
+      })                // Reserved 1 - must be zero
+
+      Name(_PLD, Package()
+      {
+        Buffer (0x10)
+        {
+          0x81, 0x00, 0x00, 0x00,     // Revision 1, Ignore color
+          0x00, 0x00, 0x00, 0x00,
+          0xE1, 0x1E, 0x00, 0x00,     // Front Panel, Vertical Lower, Horz. Left, Shape Unknown
+          0x00, 0x00, 0x00, 0x00
+        }
+      })
+
+      // copy USB Sideband Deferring GPE Vector (HOST_ALERT#1) to DSM method
+      Include("UsbSbd.asl")
+    }
+
+    Device(PR15)
+    {
+      Name(_ADR, 0x05)
+      Name(_UPC, Package()
+      {
+        0xFF,                       // Port is connectable
+        0xFF,                       // Proprietary connector
+        0x00000000,                 // Reserved 0 - must be zero
+        0x00000000
+      })                // Reserved 1 - must be zero
+      Name(_PLD, Package()
+      {
+        Buffer (0x10)
+        {
+          0x81, 0x00, 0x00, 0x00,     // Revision 1, Ignore color
+          0x00, 0x00, 0x00, 0x00,
+          0xB1, 0x1E, 0x00, 0x00,     // Panel Unknown, Shape Unknown
+          0x00, 0x00, 0x00, 0x00
+        }
+      })
+      // copy USB Sideband Deferring GPE Vector (HOST_ALERT#2) to DSM method
+      Include("UsbSbd.asl")
+    }
+
+    Device(PR16)
+    {
+      Name(_ADR, 0x06)
+      Name(_UPC, Package()
+      {
+        0xFF,                       // Port is connectable
+        0xFF,                       // Proprietary connector
+        0x00000000,                 // Reserved 0 - must be zero
+        0x00000000
+      })                // Reserved 1 - must be zero
+      Name(_PLD, Package()
+      {
+        Buffer (0x10)
+        {
+          0x81, 0x00, 0x00, 0x00,     // Revision 1, Ignore color
+          0x00, 0x00, 0x00, 0x00,
+          0xB1, 0x1E, 0x00, 0x00,     // Panel Unknown, Shape Unknown
+          0x00, 0x00, 0x00, 0x00
+        }
+      })
+      // copy USB Sideband Deferring GPE Vector (HOST_ALERT#1) to DSM method
+      Include("UsbSbd.asl")
+    }
+
+    Device(PR17)
+    {
+      Name(_ADR, 0x07)
+      Name(_UPC, Package()
+      {
+        0xFF,                       // Port is connectable
+        0xFF,                       // Proprietary connector
+        0x00000000,                 // Reserved 0 - must be zero
+        0x00000000
+      })                // Reserved 1 - must be zero
+      Name(_PLD, Package()
+      {
+        Buffer (0x10)
+        {
+          0x81, 0x00, 0x00, 0x00,     // Revision 1, Ignore color
+          0x00, 0x00, 0x00, 0x00,
+          0xB1, 0x1E, 0x00, 0x00,     // Panel Unknown, Shape Unknown
+          0x00, 0x00, 0x00, 0x00
+        }
+      })
+      // copy USB Sideband Deferring GPE Vector (HOST_ALERT#2) to DSM method
+      Include("UsbSbd.asl")
+    }
+
+    Device(PR18)
+    {
+      Name(_ADR, 0x08)
+      Name(_UPC, Package()
+      {
+        0xFF,                       // Port is connectable
+        0xFF,                       // Proprietary connector
+        0x00000000,                 // Reserved 0 - must be zero
+        0x00000000
+      })                // Reserved 1 - must be zero
+      Name(_PLD, Package()
+      {
+        Buffer (0x10)
+        {
+          0x81, 0x00, 0x00, 0x00,     // Revision 1, Ignore color
+          0x00, 0x00, 0x00, 0x00,
+          0xB1, 0x1E, 0x00, 0x00,     // Panel Unknown, Shape Unknown
+          0x00, 0x00, 0x00, 0x00
+        }
+      })
+    }
+  } // End of PR01
+} // End of HUBN
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchLpss.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchLpss.asl
new file mode 100644
index 0000000000..9510efd698
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchLpss.asl
@@ -0,0 +1,1093 @@
+/**************************************************************************;
+;*                                                                        *;
+;*                                                                        *;
+;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
+;*    Family of Customer Reference Boards.                                *;
+;*                                                                        *;
+;*                                                                        *;
+;*    Copyright (c) 2012  - 2016, Intel Corporation. All rights reserved    *;
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;*                                                                        *;
+;*                                                                        *;
+;**************************************************************************/
+//
+// LPIO1 DMA#1 (Synopsis GP DMA)
+//
+Device (GDM1)
+{
+  Name (_HID, "INTL9C60")
+  Name (_DDN, "Intel(R) DMA Controller #1 - INTL9C60")
+  Name (_UID, 1)
+
+  Name (RBUF, ResourceTemplate ()
+  {
+    Memory32Fixed (ReadWrite, 0x00000000, 0x00004000, BAR0)
+    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {42}  // DMA #1 IRQ
+  })
+  Method (_CRS, 0x0, NotSerialized)
+  {
+    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
+    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
+    Store(D10A, B0BA)
+    Store(D10L, B0LN)
+    Return (RBUF)
+  }
+  Method (_STA, 0x0, NotSerialized)
+  {
+    //
+    // PCIM>> 0:ACPI mode           1:PCI mode
+    //
+    If (LEqual(PCIM, 1)) {
+      Return (0x0)
+    }
+
+    If (LOr(LEqual(D10A, 0), LEqual(L10D, 1)))
+    {
+      Return (0x0)
+    }
+    Return (0xF)
+  }
+}
+
+//
+// LPIO1 DMA#2 (Synopsis GP DMA)
+//
+Device (GDM2)
+{
+  Name (_HID, "INTL9C60")
+  Name (_DDN, "Intel(R) DMA Controller #2 - INTL9C60")
+  Name (_UID, 2)
+
+  Name (RBUF, ResourceTemplate ()
+  {
+    Memory32Fixed (ReadWrite, 0x00000000, 0x00004000, BAR0)
+    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {43}  // DMA #2 IRQ
+  })
+  Method (_CRS, 0x0, NotSerialized)
+  {
+    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
+    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
+    Store(D20A, B0BA)
+    Store(D20L, B0LN)
+    Return (RBUF)
+  }
+  Method (_STA, 0x0, NotSerialized)
+  {
+    //
+    // PCIM>> 0:ACPI mode           1:PCI mode
+    //
+    If (LEqual(PCIM, 1)) {
+      Return (0x0)
+    }
+
+    If (LOr(LEqual(D20A, 0), LEqual(L20D, 1)))
+    {
+      Return (0x0)
+    }
+    Return (0xF)
+  }
+}
+
+//
+// LPIO1 PWM #1
+//
+Device(PWM1)
+{
+  Name (_ADR, 0)
+  Name (_HID, "80860F09")
+  Name (_CID, "80860F09")
+  Name (_DDN, "Intel(R) PWM Controller #1 - 80860F08")
+  Name (_UID, 1)
+
+  Name (RBUF, ResourceTemplate ()
+  {
+    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
+  })
+  Method (_CRS, 0x0, NotSerialized)
+  {
+    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
+    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
+    Store(P10A, B0BA)
+    Store(P10L, B0LN)
+    Return (RBUF)
+  }
+  Method (_STA, 0x0, NotSerialized)
+  {
+    //
+    // PCIM>> 0:ACPI mode           1:PCI mode
+    //
+    If (LEqual(PCIM, 1)) {
+      Return (0x0)
+    }
+
+    If (LOr(LEqual(P10A, 0), LEqual(L11D, 1)))
+    {
+      Return (0x0)
+    }
+    Return (0xF)
+  }
+}
+
+//
+// LPIO1 PWM #2
+//
+Device(PWM2)
+{
+  Name (_ADR, 0)
+  Name (_HID, "80860F09")
+  Name (_CID, "80860F09")
+  Name (_DDN, "Intel(R) PWM Controller #2 - 80860F09")
+  Name (_UID, 2)
+
+  Name (RBUF, ResourceTemplate ()
+  {
+    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
+  })
+  Method (_CRS, 0x0, NotSerialized)
+  {
+    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
+    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
+    Store(P20A, B0BA)
+    Store(P20L, B0LN)
+    Return (RBUF)
+  }
+  Method (_STA, 0x0, NotSerialized)
+  {
+    //
+    // PCIM>> 0:ACPI mode           1:PCI mode
+    //
+    If (LEqual(PCIM, 1)) {
+      Return (0x0)
+    }
+
+    If (LOr(LEqual(P20A, 0), LEqual(L12D, 1)))
+    {
+      Return (0x0)
+    }
+    Return (0xF)
+  }
+}
+
+//
+// LPIO1 HS-UART #1
+//
+Device(URT1)
+{
+  Name (_ADR, 0)
+  Name (_HID, "80860F0A")
+  Name (_CID, "80860F0A")
+  Name (_DDN, "Intel(R) HS-UART Controller #1 - 80860F0A")
+  Name (_UID, 1)
+  Name(_DEP, Package(0x1)
+  {
+    PEPD
+  })
+  Name (RBUF, ResourceTemplate ()
+  {
+    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
+    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {39}  // HS-UART #1 IRQ
+
+    FixedDMA(0x2, 0x2, Width32Bit, )
+    FixedDMA(0x3, 0x3, Width32Bit, )
+  })
+  Method (_HRV, 0x0, NotSerialized)
+  {
+    Return (SOCS)
+  }
+  Method (_CRS, 0x0, NotSerialized)
+  {
+    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
+    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
+    Store(U10A, B0BA)
+    Store(U10L, B0LN)
+    Return (RBUF)
+  }
+
+  Method (_STA, 0x0, NotSerialized)
+  {
+    //
+    // PCIM>> 0:ACPI mode           1:PCI mode
+    //
+    If (LEqual(PCIM, 1)) {
+      Return (0x0)
+    }
+
+    If (LOr(LEqual(U10A, 0), LEqual(L13D, 1)))
+    {
+      Return (0x0)
+    }
+    Return (0xF)
+  }
+
+  Method (_PS3, 0, NotSerialized)
+  {
+    OR(PSAT, 0x00000003, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+  }
+
+  Method (_PS0, 0, NotSerialized)
+  {
+    And(PSAT, 0xfffffffC, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+  }
+
+  OperationRegion (KEYS, SystemMemory, U11A, 0x100)
+  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+  {
+    Offset (0x84),
+    PSAT,   32
+  }
+}//  Device (URT1)
+
+//
+// LPIO1 HS-UART #2
+//
+Device(URT2)
+{
+  Name (_ADR, 0)
+  Name (_HID, "80860F0A")
+  Name (_CID, "80860F0A")
+  Name (_DDN, "Intel(R) HS-UART Controller #2 - 80860F0C")
+  Name (_UID, 2)
+
+  Name(_DEP, Package(0x1)
+  {
+    PEPD
+  })
+
+  Name (RBUF, ResourceTemplate ()
+  {
+    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
+    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {40}  // HS-UART #2 IRQ
+
+    FixedDMA(0x4, 0x4, Width32Bit, )
+    FixedDMA(0x5, 0x5, Width32Bit, )
+  })
+
+  Method (_HRV, 0x0, NotSerialized)
+  {
+    Return (SOCS)
+  }
+
+  Method (_CRS, 0x0, NotSerialized)
+  {
+    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
+    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
+    Store(U20A, B0BA)
+    Store(U20L, B0LN)
+    Return (RBUF)
+  }
+
+  Method (_STA, 0x0, NotSerialized)
+  {
+    //
+    // PCIM>> 0:ACPI mode           1:PCI mode
+    //
+    If (LEqual(PCIM, 1)) {
+      Return (0x0)
+    }
+
+    If (LOr(LEqual(U20A, 0), LEqual(L14D, 1)))
+    {
+      Return (0x0)
+    }
+    Return (0xF)
+  }
+
+  Method (_PS3, 0, NotSerialized)
+  {
+    OR(PSAT, 0x00000003, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+  }
+
+  Method (_PS0, 0, NotSerialized)
+  {
+    And(PSAT, 0xfffffffC, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+  }
+
+  OperationRegion (KEYS, SystemMemory, U21A, 0x100)
+  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+  {
+    Offset (0x84),
+    PSAT,   32
+  }
+}//  Device (URT2)
+
+//
+// LPIO1 SPI
+//
+Device(SPI1)
+{
+  Name (_ADR, 0)
+  Name (_HID, "80860F0E")
+  Name (_CID, "80860F0E")
+  Name (_UID, "0")  // Static bus number assignment
+  Name(_DEP, Package(0x1)
+  {
+    PEPD
+  })
+  Name (_DDN, "Intel(R) SPI Controller - 80860F0E")
+
+  Name (RBUF, ResourceTemplate ()
+  {
+    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
+    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {41}  // SPI IRQ
+
+    FixedDMA(0x0, 0x0, Width32Bit, )
+    FixedDMA(0x1, 0x1, Width32Bit, )
+  })
+
+  Method (_HRV, 0x0, NotSerialized)
+  {
+    Return (SOCS)
+  }
+
+  Method (_CRS, 0x0, NotSerialized)
+  {
+    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
+    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
+    Store(SP0A, B0BA)
+    Store(SP0L, B0LN)
+    Return (RBUF)
+  }
+
+  Method (_STA, 0x0, NotSerialized)
+  {
+    //
+    // PCIM>> 0:ACPI mode           1:PCI mode
+    //
+    If (LEqual(PCIM, 1)) {
+      Return (0x0)
+    }
+
+    If (LOr(LEqual(SP0A, 0), LEqual(L15D, 1)))
+    {
+      Return (0x0)
+    }
+    Return (0xF)
+  }
+
+  Method (_PS3, 0, NotSerialized)
+  {
+    OR(PSAT, 0x00000003, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+  }
+
+  Method (_PS0, 0, NotSerialized)
+  {
+    And(PSAT, 0xfffffffC, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+  }
+
+  OperationRegion (KEYS, SystemMemory, SP1A, 0x100)
+  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+  {
+    Offset (0x84),
+           PSAT,   32
+  }
+}//  Device (SPI1)
+
+//
+// LPIO2 I2C #1
+//
+Device(I2C1)
+{
+  Name (_ADR, 0)
+  Name (_HID, "80860F41")
+  Name (_CID, "80860F41")
+  Name(_DEP, Package(0x1)
+  {
+    PEPD
+  })
+  Name (_DDN, "Intel(R) I2C Controller #1 - 80860F41")
+  Name (_UID, 1)
+
+  Name (RBUF, ResourceTemplate ()
+  {
+    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
+    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {32}  // I2C #1 IRQ
+
+    FixedDMA(0x10, 0x0, Width32Bit, )
+    FixedDMA(0x11, 0x1, Width32Bit, )
+  })
+
+  Method (SSCN, 0x0, NotSerialized)
+  {
+    Name (PKG, Package(3) { 0x200, 0x200, 0x06 })
+    Return (PKG)
+  }
+  Method (FMCN, 0x0, NotSerialized)
+  {
+    Name (PKG, Package(3) { 0x55, 0x99, 0x06 })
+    Return (PKG)
+  }
+  Method (FPCN, 0x0, NotSerialized)
+  {
+    Name (PKG, Package(3) { 0x1b, 0x3a, 0x06 })
+    Return (PKG)
+  }
+
+  Method (_HRV, 0x0, NotSerialized)
+  {
+    Return (SOCS)
+  }
+  Method (_CRS, 0x0, NotSerialized)
+  {
+    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
+    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
+    Store(I10A, B0BA)
+    Store(I10L, B0LN)
+    Return (RBUF)
+  }
+  Method (_STA, 0x0, NotSerialized)
+  {
+    //
+    // PCIM>> 0:ACPI mode           1:PCI mode
+    //
+    If (LEqual(PCIM, 1)) {
+      Return (0x0)
+    }
+
+    If (LOr(LEqual(I10A, 0), LEqual(L21D, 1)))
+    {
+      Return (0x0)
+    }
+    Return (0xF)
+
+  }
+
+  Method (_PS3, 0, NotSerialized)
+  {
+    OR(PSAT, 0x00000003, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+  }
+  Method (_PS0, 0, NotSerialized)
+  {
+    And(PSAT, 0xfffffffC, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+  }
+  OperationRegion (KEYS, SystemMemory, I11A, 0x100)
+  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+  {
+    Offset (0x84),
+           PSAT,   32
+  }
+
+}
+
+//
+// LPIO2 I2C #2
+//
+Device(I2C2)
+{
+  Name (_ADR, 0)
+  Name (_HID, "80860F41")
+  Name (_CID, "80860F41")
+  Name(_DEP, Package(0x1)
+  {
+    PEPD
+  })
+  Name (_DDN, "Intel(R) I2C Controller #2 - 80860F42")
+  Name (_UID, 2)
+
+  Name (RBUF, ResourceTemplate ()
+  {
+    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
+    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {33}  // I2C #2 IRQ
+
+    FixedDMA(0x12, 0x2, Width32Bit, )
+    FixedDMA(0x13, 0x3, Width32Bit, )
+  })
+
+  Method (SSCN, 0x0, NotSerialized)
+  {
+    Name (PKG, Package(3) { 0x200, 0x200, 0x06 })
+    Return (PKG)
+  }
+  Method (FMCN, 0x0, NotSerialized)
+  {
+    Name (PKG, Package(3) { 0x55, 0x99, 0x06 })
+    Return (PKG)
+  }
+  Method (FPCN, 0x0, NotSerialized)
+  {
+    Name (PKG, Package(3) { 0x1b, 0x3a, 0x06 })
+    Return (PKG)
+  }
+
+  Method (_HRV, 0x0, NotSerialized)
+  {
+    Return (SOCS)
+  }
+  Method (_CRS, 0x0, NotSerialized)
+  {
+    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
+    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
+    Store(I20A, B0BA)
+    Store(I20L, B0LN)
+    Return (RBUF)
+  }
+  Method (_STA, 0x0, NotSerialized)
+  {
+    //
+    // PCIM>> 0:ACPI mode           1:PCI mode
+    //
+    If (LEqual(PCIM, 1)) {
+      Return (0x0)
+    }
+
+    If (LOr(LEqual(I20A, 0), LEqual(L22D, 1)))
+    {
+      Return (0x0)
+    }
+    Return (0xF)
+  }
+
+  Method (_PS3, 0, NotSerialized)
+  {
+    OR(PSAT, 0x00000003, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+
+  }
+  Method (_PS0, 0, NotSerialized)
+  {
+    And(PSAT, 0xfffffffC, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+  }
+  OperationRegion (KEYS, SystemMemory, I21A, 0x100)
+  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+  {
+    Offset (0x84),
+           PSAT,   32
+  }
+
+
+  //
+  // Realtek Audio Codec
+  //
+  Device (RTEK)   //Audio Codec driver I2C
+  {
+    Name (_ADR, 0)
+    Name (_HID, "10EC5640")
+    Name (_CID, "10EC5640")
+    Name (_DDN, "RTEK Codec Controller " )
+    Name (_UID, 1)
+
+
+    Method(_CRS, 0x0, Serialized)
+    {
+      Name(SBUF,ResourceTemplate ()
+      {
+        I2CSerialBus(0x1C,          //SlaveAddress: bus address
+                     ,                         //SlaveMode: default to ControllerInitiated
+                     400000,                   //ConnectionSpeed: in Hz
+                     ,                         //Addressing Mode: default to 7 bit
+                     "\\_SB.I2C2",             //ResourceSource: I2C bus controller name
+                     ,                         //ResourceSourceIndex: defaults to 0
+                     ,                         //ResourceUsage: Defaults to ResourceConsumer
+                     ,                         //Descriptor Name: creates name for offset of resource descriptor
+                    )  //VendorData
+        GpioInt(Edge, ActiveHigh, ExclusiveAndWake, PullNone, 0,"\\_SB.GPO2") {4} //  AUD_INT
+      })
+      Return (SBUF)
+    }
+
+    Method (_STA, 0x0, NotSerialized)
+    {
+
+      If (LEqual(LPEE, 2)) { // LPE enable/disable
+        If (LEqual(LPAD, 1))
+        {
+          Return(0xF)
+        }
+      }
+      Return(0)
+    }
+
+    Method (_DIS, 0x0, NotSerialized)
+    {
+
+    }
+  } // Device (RTEK)
+} //  Device (I2C2)
+
+//
+// LPIO2 I2C #3
+//
+Device(I2C3)
+{
+  Name (_ADR, 0)
+  Name (_HID, "80860F41")
+  Name (_CID, "80860F41")
+  Name (_DDN, "Intel(R) I2C Controller #3 - 80860F43")
+  Name (_UID, 3)
+  Name(_DEP, Package(0x1)
+  {
+    PEPD
+  })
+  Name (RBUF, ResourceTemplate ()
+  {
+    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
+    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {34}  // I2C #3 IRQ
+
+    FixedDMA(0x14, 0x4, Width32Bit, )
+    FixedDMA(0x15, 0x5, Width32Bit, )
+  })
+
+  Method (SSCN, 0x0, NotSerialized)
+  {
+    Name (PKG, Package(3) { 0x200, 0x200, 0x06 })
+    Return (PKG)
+  }
+  Method (FMCN, 0x0, NotSerialized)
+  {
+    Name (PKG, Package(3) { 0x55, 0x99, 0x06 })
+    Return (PKG)
+  }
+  Method (FPCN, 0x0, NotSerialized)
+  {
+    Name (PKG, Package(3) { 0x1b, 0x3a, 0x06 })
+    Return (PKG)
+  }
+
+  Method (_HRV, 0x0, NotSerialized)
+  {
+    Return (SOCS)
+  }
+  Method (_CRS, 0x0, NotSerialized)
+  {
+    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
+    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
+    Store(I30A, B0BA)
+    Store(I30L, B0LN)
+    Return (RBUF)
+  }
+
+  Method (_STA, 0x0, NotSerialized)
+  {
+    //
+    // PCIM>> 0:ACPI mode           1:PCI mode
+    //
+    If (LEqual(PCIM, 1)) {
+      Return (0x0)
+    }
+
+    If (LOr(LEqual(I30A, 0), LEqual(L23D, 1)))
+    {
+      Return (0x0)
+    }
+    Return (0xF)
+  }
+
+  Method (_PS3, 0, NotSerialized)
+  {
+    OR(PSAT, 0x00000003, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+
+  }
+  Method (_PS0, 0, NotSerialized)
+  {
+    And(PSAT, 0xfffffffC, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+  }
+  OperationRegion (KEYS, SystemMemory, I31A, 0x100)
+  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+  {
+    Offset (0x84),
+    PSAT,   32
+  }
+
+
+}
+
+//
+// LPIO2 I2C #4
+//
+Device(I2C4)
+{
+  Name (_ADR, 0)
+  Name (_HID, "80860F41")
+  Name (_CID, "80860F41")
+  Name (_DDN, "Intel(R) I2C Controller #4 - 80860F44")
+  Name (_UID, 4)
+  Name(_DEP, Package(0x1)
+  {
+    PEPD
+  })
+  Name (RBUF, ResourceTemplate ()
+  {
+    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
+    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {35}  // I2C #4 IRQ
+
+    FixedDMA(0x16, 0x6, Width32Bit, )
+    FixedDMA(0x17, 0x7, Width32Bit, )
+  })
+
+  Method (SSCN, 0x0, NotSerialized)
+  {
+    Name (PKG, Package(3) { 0x200, 0x200, 0x06 })
+    Return (PKG)
+  }
+  Method (FMCN, 0x0, NotSerialized)
+  {
+    Name (PKG, Package(3) { 0x55, 0x99, 0x06 })
+    Return (PKG)
+  }
+  Method (FPCN, 0x0, NotSerialized)
+  {
+    Name (PKG, Package(3) { 0x1b, 0x3a, 0x06 })
+    Return (PKG)
+  }
+
+
+  Method (_HRV, 0x0, NotSerialized)
+  {
+    Return (SOCS)
+  }
+  Method (_CRS, 0x0, NotSerialized)
+  {
+    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
+    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
+    Store(I40A, B0BA)
+    Store(I40L, B0LN)
+    Return (RBUF)
+  }
+
+  Method (_STA, 0x0, NotSerialized)
+  {
+    //
+    // PCIM>> 0:ACPI mode           1:PCI mode
+    //
+    If (LEqual(PCIM, 1)) {
+      Return (0x0)
+    }
+
+    If (LOr(LEqual(I40A, 0), LEqual(L24D, 1)))
+    {
+      Return (0x0)
+    }
+    Return (0xF)
+  }
+
+  Method (_PS3, 0, NotSerialized)
+  {
+    OR(PSAT, 0x00000003, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+
+  }
+  Method (_PS0, 0, NotSerialized)
+  {
+    And(PSAT, 0xfffffffC, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+  }
+  OperationRegion (KEYS, SystemMemory, I41A, 0x100)
+  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+  {
+    Offset (0x84),
+    PSAT,   32
+  }
+
+  PowerResource (CLK0, 0x00, 0x0000)
+  {
+    Method (_STA, 0, NotSerialized)   // _STA: Status
+    {
+      Return (CKC0)
+    }
+
+    Method (_ON, 0, NotSerialized)   // _ON_: Power On
+    {
+      Store (One, CKC0)
+      Store (One, CKF0)
+      Sleep (0x20)
+    }
+
+    Method (_OFF, 0, NotSerialized)   // _OFF: Power Off
+    {
+      Store (0x02, CKC0)
+    }
+  }
+  PowerResource (CLK1, 0x00, 0x0000)
+  {
+    Method (_STA, 0, NotSerialized)   // _STA: Status
+    {
+      Return (CKC1)
+    }
+
+    Method (_ON, 0, NotSerialized)   // _ON_: Power On
+    {
+      Store (One, CKC1)
+      Store (One, CKF1)
+      Sleep (0x20)
+    }
+
+    Method (_OFF, 0, NotSerialized)   // _OFF: Power Off
+    {
+      Store (0x02, CKC1)
+    }
+  }
+}
+
+//
+// LPIO2 I2C #5
+//
+Device(I2C5)
+{
+  Name (_ADR, 0)
+  Name (_HID, "80860F41")
+  Name (_CID, "80860F41")
+  Name (_DDN, "Intel(R) I2C Controller #5 - 80860F45")
+  Name (_UID, 5)
+  Name(_DEP, Package(0x1)
+  {
+    PEPD
+  })
+  Name (RBUF, ResourceTemplate ()
+  {
+    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
+    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {36}  // I2C #5 IRQ
+
+    FixedDMA(0x18, 0x0, Width32Bit, )
+    FixedDMA(0x19, 0x1, Width32Bit, )
+  })
+
+  Method (SSCN, 0x0, NotSerialized)
+  {
+    Name (PKG, Package(3) { 0x200, 0x200, 0x06 })
+    Return (PKG)
+  }
+  Method (FMCN, 0x0, NotSerialized)
+  {
+    Name (PKG, Package(3) { 0x55, 0x99, 0x06 })
+    Return (PKG)
+  }
+  Method (FPCN, 0x0, NotSerialized)
+  {
+    Name (PKG, Package(3) { 0x1b, 0x3a, 0x06 })
+    Return (PKG)
+  }
+
+  Method (_HRV, 0x0, NotSerialized)
+  {
+    Return (SOCS)
+  }
+  Method (_CRS, 0x0, NotSerialized)
+  {
+    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
+    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
+    Store(I50A, B0BA)
+    Store(I50L, B0LN)
+    Return (RBUF)
+  }
+  Method (_STA, 0x0, NotSerialized)
+  {
+    //
+    // PCIM>> 0:ACPI mode           1:PCI mode
+    //
+    If (LEqual(PCIM, 1)) {
+      Return (0x0)
+    }
+
+    If (LOr(LEqual(I50A, 0), LEqual(L25D, 1)))
+    {
+      Return (0x0)
+    }
+    Return (0xF)
+  }
+
+  Method (_PS3, 0, NotSerialized)
+  {
+    OR(PSAT, 0x00000003, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+  }
+  Method (_PS0, 0, NotSerialized)
+  {
+    And(PSAT, 0xfffffffC, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+  }
+  OperationRegion (KEYS, SystemMemory, I51A, 0x100)
+  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+  {
+    Offset (0x84),
+    PSAT,   32
+  }
+}
+
+//
+// LPIO2 I2C #6
+//
+Device(I2C6)
+{
+  Name (_ADR, 0)
+  Name (_HID, "80860F41")
+  Name (_CID, "80860F41")
+  Name (_DDN, "Intel(R) I2C Controller #6 - 80860F46")
+  Name (_UID, 6)
+  Name(_DEP, Package(0x1)
+  {
+    PEPD
+  })
+  Name (RBUF, ResourceTemplate ()
+  {
+    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
+    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {37}  // I2C #6 IRQ
+
+    FixedDMA(0x1A, 0x02, Width32Bit, )
+    FixedDMA(0x1B, 0x03, Width32Bit, )
+  })
+
+  Method (SSCN, 0x0, NotSerialized)
+  {
+    Name (PKG, Package(3) { 0x200, 0x200, 0x06 })
+    Return (PKG)
+  }
+  Method (FMCN, 0x0, NotSerialized)
+  {
+    Name (PKG, Package(3) { 0x55, 0x99, 0x06 })
+    Return (PKG)
+  }
+  Method (FPCN, 0x0, NotSerialized)
+  {
+    Name (PKG, Package(3) { 0x1b, 0x3a, 0x06 })
+    Return (PKG)
+  }
+
+  Method (_HRV, 0x0, NotSerialized)
+  {
+    Return (SOCS)
+  }
+  Method (_CRS, 0x0, NotSerialized)
+  {
+    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
+    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
+    Store(I60A, B0BA)
+    Store(I60L, B0LN)
+    Return (RBUF)
+  }
+  Method (_STA, 0x0, NotSerialized)
+  {
+    //
+    // PCIM>> 0:ACPI mode           1:PCI mode
+    //
+    If (LEqual(PCIM, 1)) {
+      Return (0x0)
+    }
+
+    If (LOr(LEqual(I60A, 0), LEqual(L26D, 1)))
+    {
+      Return (0x0)
+    }
+    Return (0xF)
+  }
+
+  Method (_PS3, 0, NotSerialized)
+  {
+    OR(PSAT, 0x00000003, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+  }
+  Method (_PS0, 0, NotSerialized)
+  {
+    And(PSAT, 0xfffffffC, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+  }
+  OperationRegion (KEYS, SystemMemory, I61A, 0x100)
+  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+  {
+    Offset (0x84),
+           PSAT,   32
+  }
+}
+
+//
+// LPIO2 I2C #7
+//
+Device(I2C7)
+{
+  Name (_ADR, 0)
+  Name (_HID, "80860F41")
+  Name (_CID, "80860F41")
+  //Name (_CLS, Package (3) {0x0C, 0x80, 0x00})
+  Name (_DDN, "Intel(R) I2C Controller #7 - 80860F47")
+  Name (_UID, 7)
+  Name(_DEP, Package(0x1)
+  {
+    PEPD
+  })
+  Name (RBUF, ResourceTemplate ()
+  {
+    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
+    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {38}  // I2C #7 IRQ
+
+    FixedDMA(0x1C, 0x4, Width32Bit, )
+    FixedDMA(0x1D, 0x5, Width32Bit, )
+  })
+
+  Method (SSCN, 0x0, NotSerialized)
+  {
+    Name (PKG, Package(3) { 0x200, 0x200, 0x06 })
+    Return (PKG)
+  }
+  Method (FMCN, 0x0, NotSerialized)
+  {
+    Name (PKG, Package(3) { 0x55, 0x99, 0x06 })
+    Return (PKG)
+  }
+  Method (FPCN, 0x0, NotSerialized)
+  {
+    Name (PKG, Package(3) { 0x1b, 0x3a, 0x06 })
+    Return (PKG)
+  }
+
+  Method (_HRV, 0x0, NotSerialized)
+  {
+    Return (SOCS)
+  }
+
+  Method (_CRS, 0x0, NotSerialized)
+  {
+    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
+    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
+    Store(I70A, B0BA)
+    Store(I70L, B0LN)
+    Return (RBUF)
+  }
+
+  Method (_STA, 0x0, NotSerialized)
+  {
+    //
+    // PCIM>> 0:ACPI mode           1:PCI mode
+    //
+    If (LEqual(PCIM, 1)) {
+      Return (0x0)
+    }
+
+    If (LOr(LEqual(I70A, 0), LEqual(L27D, 1)))
+    {
+      Return (0x0)
+    }
+    Return (0xF)
+  }
+
+  Method (_PS3, 0, NotSerialized)
+  {
+    OR(PSAT, 0x00000003, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+  }
+
+  Method (_PS0, 0, NotSerialized)
+  {
+    And(PSAT, 0xfffffffC, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+  }
+
+  OperationRegion (KEYS, SystemMemory, I71A, 0x100)
+  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+  {
+    Offset (0x84),
+    PSAT,   32
+  }
+
+}
+
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchPcie.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchPcie.asl
new file mode 100644
index 0000000000..7b32ea2dae
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchPcie.asl
@@ -0,0 +1,50 @@
+/**************************************************************************;
+;*                                                                        *;
+;*                                                                        *;
+;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
+;*    Family of Customer Reference Boards.                                *;
+;*                                                                        *;
+;*                                                                        *;
+;*    Copyright (c)  2011  - 2014, Intel Corporation. All rights reserved   *;
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;*                                                                        *;
+;*                                                                        *;
+;**************************************************************************/
+
+
+OperationRegion(PXCS,PCI_Config,0x40,0xC0)
+Field(PXCS,AnyAcc, NoLock, Preserve)
+{
+  Offset(0x10), // LCTL - Link Control Register
+  L0SE, 1,      // 0, L0s Entry Enabled
+  , 7,
+  Offset(0x12), // LSTS - Link Status Register
+  , 13,
+  LASX, 1,      // 0, Link Active Status
+  Offset(0x1A), // SLSTS[7:0] - Slot Status Register
+  ABPX, 1,      // 0, Attention Button Pressed
+  , 2,
+  PDCX, 1,      // 3, Presence Detect Changed
+  , 2,
+  PDSX, 1,      // 6, Presence Detect State
+  , 1,
+  Offset(0x20), // RSTS - Root Status Register
+  , 16,
+  PSPX, 1,      // 16,        PME Status
+}
+
+
+Device(PXSX)
+{
+  Name(_ADR, 0x00000000)
+
+  // NOTE:  Any PCIE Hot-Plug dependency for this port is
+  // specific to the CRB.  Please modify the code based on
+  // your platform requirements.
+
+  Name(_PRW, Package() {9,4})
+}
+
+
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchScc.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchScc.asl
new file mode 100644
index 0000000000..78a928a5da
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchScc.asl
@@ -0,0 +1,610 @@
+/**************************************************************************;
+;*                                                                        *;
+;*                                                                        *;
+;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
+;*    Family of Customer Reference Boards.                                *;
+;*                                                                        *;
+;*                                                                        *;
+;*    Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved    *;
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;*                                                                        *;
+;*                                                                        *;
+;**************************************************************************/
+Device (PEPD)
+{
+  Name (_HID, "INT3396")
+  Name(_CID, 0x800dd041)
+  Name (_UID, 0x1)
+
+  // Indicates if the platform PEP has loaded
+  Name(PEPP, Zero)
+
+  // Devices score-boarded by the PEP, Rev0 format
+  Name (DEVS, Package() {0})
+
+  // Devices score-boarded by the PEP, Rev1 format
+  Name(DEVX, Package()
+  {
+    Package () {"\\_SB.PCI0.XHC1", 0x1},
+    Package () {"\\_SB.PCI0.EHC1", 0x1},
+    Package () {"\\_SB.PCI0.GFX0", 0x1},
+    Package () {"\\_SB.PCI0.GFX0.ISP0", 0x1},
+    Package () {"\\_SB.PCI0.SEC0", 0x1},
+    Package () {"\\_SB.I2C1", 0x1},
+    Package () {"\\_SB.I2C2", 0x1},
+    Package () {"\\_SB.I2C3", 0x1},
+    Package () {"\\_SB.I2C4", 0x1},
+    Package () {"\\_SB.I2C5", 0x1},
+    Package () {"\\_SB.I2C6", 0x1},
+    Package () {"\\_SB.I2C7", 0x1},
+    Package () {"\\_SB.SDHA", 0x1},
+    Package () {"\\_SB.SDHB", 0x1},
+    Package () {"\\_SB.SDHC", 0x1},
+    Package () {"\\_SB.SPI1", 0x1},
+    Package () {"\\_SB.URT1", 0x1},
+    Package () {"\\_SB.URT2", 0x1},
+  })
+  // Crashdump device package
+  Name(CDMP, Package(2) {})
+  // Device dependency for uPEP
+  Name(DEVY, Package()
+  {
+    Package() {"\\_PR.CPU0", 0x1, Package() {Package() {0xFF, 0}}},
+    Package() {"\\_PR.CPU1", 0x1, Package() {Package() {0xFF, 0}}},
+    Package() {"\\_PR.CPU2", 0x1, Package() {Package() {0xFF, 0}}},
+    Package() {"\\_PR.CPU3", 0x1, Package() {Package() {0xFF, 0}}},
+    Package() {"\\_SB.I2C1", 0x1, Package() {Package() {0xFF,3}}},
+    Package() {"\\_SB.I2C2", 0x1, Package() {Package() {0xFF,3}}},
+    Package() {"\\_SB.I2C3", 0x1, Package() {Package() {0xFF,3}}},
+    Package() {"\\_SB.I2C4", 0x1, Package() {Package() {0xFF,3}}},
+    Package() {"\\_SB.I2C5", 0x1, Package() {Package() {0xFF,3}}},
+    Package() {"\\_SB.I2C6", 0x1, Package() {Package() {0xFF,3}}},
+    Package() {"\\_SB.I2C7", 0x1, Package() {Package() {0xFF,3}}},
+    Package() {"\\_SB.PCI0.GFX0", 0x1, Package() {Package() {0xFF,3}}},
+    Package() {"\\_SB.PCI0.SEC0", 0x1, Package() {Package() {0xFF,3}}},
+    Package() {"\\_SB.PCI0.XHC1", 0x1, Package() {Package() {0xFF,3}}},
+    Package() {"\\_SB.PCI0.GFX0.ISP0", 0x1, Package() {Package() {0xFF,3}}},
+    Package() {"\\_SB.LPEA", 0x1, Package() {Package() {0x0,3}, Package() {0x1,0}, Package() {0x2,3}, Package() {0x3,3}}},
+    Package() {"\\_SB.SDHA", 0x1, Package() {Package() {0xFF,3}}},
+    Package() {"\\_SB.SDHB", 0x1, Package() {Package() {0xFF,3}}},
+    Package() {"\\_SB.SDHC", 0x1, Package() {Package() {0xFF,3}}},
+    Package() {"\\_SB.SPI1", 0x1, Package() {Package() {0xFF,3}}},
+    Package() {"\\_SB.URT1", 0x1, Package() {Package() {0xFF,3}}},
+    Package() {"\\_SB.URT2", 0x1, Package() {Package() {0xFF,3}}}
+  })
+  // BCCD crashdump information
+  Name(BCCD, Package()
+  {
+    Package()
+    {
+      "\\_SB.SDHA",
+      Package()
+      {
+        Package() { Package() {0, 32, 0,  3, 0xFFFFFFFFFFFFFFFF}, Package() {0xFFFFFFFC, 0x0, 0x4}, 0}
+      }
+    }
+  })
+
+  Method(_STA, 0x0, NotSerialized)
+  {
+    Return(0xf)
+  }
+
+  Method(_DSM, 0x4, Serialized)
+  {
+    If(LEqual(Arg0,ToUUID("B8FEBFE0-BAF8-454b-AECD-49FB91137B21")))
+    {
+
+      // Number of fn IDs supported
+      If(LEqual(Arg2, Zero))
+      {
+        Return(Buffer(One)
+        {
+          0xf
+        })
+      }
+
+      // Pep presence
+      If(LEqual(Arg2, One))
+      {
+        Store(0x1, PEPP)
+        Return(0xf)
+      }
+
+      // Mitigation devices
+      If(LEqual(Arg2, 0x2))
+      {
+        If(LEqual(Arg1, 0x0))
+        {
+          // Rev0
+          Return(DEVS)
+        }
+        If(LEqual(Arg1, 0x1))
+        {
+          // Rev1
+          Return(DEVX)
+        }
+      }
+
+      // Crashdump device data
+      If(LEqual(Arg2, 0x3))
+      {
+        Store("\\_SB.SDHA", Index(CDMP,0))
+        Store(EM1A, Index(CDMP,1))
+        Return(CDMP)
+      }
+    }
+    // New UUID for built-in uPEP
+    If(LEqual(Arg0,ToUUID("C4EB40A0-6CD2-11E2-BCFD-0800200C9A66")))
+    {
+
+      // Number of fn IDs supported
+      If(LEqual(Arg2, Zero))
+      {
+        Return(Buffer(One)
+        {
+          0x7
+        })
+      }
+      // LPI device dependencies
+      If(LEqual(Arg2, 0x1))
+      {
+        Return(DEVY)
+      }
+      // Crashdump device data
+      If(LEqual(Arg2, 0x2))
+      {
+        Store(EM1A, Local0)
+        Add(Local0, 0x84, Local0)
+        Store(Local0, Index(DerefOf(Index(DerefOf(Index(DerefOf(Index(DerefOf(Index(BCCD, Zero, )), One, )), Zero, )), Zero, )), 0x4, ))
+        Return(BCCD)
+      }
+    }
+
+    Return(One)
+  }
+}
+
+//
+// eMMC 4.41
+//
+Device(SDHA)
+{
+  Name (_ADR, 0)
+  Name (_HID, "80860F14")
+  Name (_CID, "PNP0D40")
+  Name (_DDN, "Intel(R) eMMC Controller - 80860F14")
+  Name (_UID, 1)
+  Name(_DEP, Package(0x1)
+  {
+    PEPD
+  })
+
+  Name (RBF1, ResourceTemplate ()
+  {
+    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
+    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {45}  // eMMC 4.41 IRQ
+  })
+
+  Method (_CRS, 0x0, NotSerialized)
+  {
+    // Update the Base address for BAR0 of eMMC 4.41
+    CreateDwordField(^RBF1, ^BAR0._BAS, B0B1)
+    CreateDwordField(^RBF1, ^BAR0._LEN, B0L1)
+    Store(eM0A, B0B1)
+    Store(eM0L, B0L1)
+    Return (RBF1)
+  }
+  Method (_STA, 0x0, NotSerialized)
+  {
+    //
+    // PCIM>> 0:ACPI mode            1:PCI mode
+    // SD1D>> 0:eMMC 4.41 enable     1:eMMC 4.41 disable
+    //
+    If (LAnd(LEqual(PCIM, 0), LEqual(SD1D, 0)))
+    {
+      Return (0xF)
+    }
+    Else
+    {
+      Return (0x0)
+    }
+  }
+
+
+  Method (_PS3, 0, NotSerialized)
+  {
+    OR(PSAT, 0x00000003, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+    //
+    // If not B1, still keep 2 ms w/a
+    //
+    If(LLess(SOCS, 0x03))
+    {
+      Sleep(2)
+    }
+  }
+  Method (_PS0, 0, NotSerialized)
+  {
+    And(PSAT, 0xfffffffC, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+    //
+    // If not B1, still keep 2 ms w/a
+    //
+    If(LLess(SOCS, 0x03))
+    {
+      Sleep(2)
+    }
+  }
+
+  OperationRegion (KEYS, SystemMemory, eM1A, 0x100)
+  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+  {
+    Offset (0x84),
+           PSAT,  32
+  }
+
+         Method (_DIS, 0x0, NotSerialized)
+  {
+    //Adding dummy disable methods for device EMM0
+  }
+
+  Device (EMMD)
+  {
+    Name (_ADR, 0x00000008) // Slot 0, Function 8
+    Method (_RMV, 0, NotSerialized)
+    {
+      Return (0x0)
+    }
+  }
+}
+
+
+//
+// eMMC 4.5
+//
+Device(SDHD)
+{
+  Name (_ADR, 0)
+  Name (_HID, "80860F14")
+  Name (_CID, "PNP0D40")
+  Name (_DDN, "Intel(R) eMMC Controller - 80860F14")
+  Name (_UID, 1)
+  Name(_DEP, Package(0x1)
+  {
+    PEPD
+  })
+
+  Name (RBF1, ResourceTemplate ()
+  {
+    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
+    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {44}  // eMMC 4.5 IRQ
+  })
+  Method (_CRS, 0x0, NotSerialized)
+  {
+    CreateDwordField(^RBF1, ^BAR0._BAS, B0B1)
+    CreateDwordField(^RBF1, ^BAR0._LEN, B0L1)
+    Store(eM0A, B0B1)
+    Store(eM0L, B0L1)
+    Return (RBF1)
+  }
+  Method (_STA, 0x0, NotSerialized)
+  {
+    //
+    // PCIM>> 0:ACPI mode           1:PCI mode
+    // HSID>> 0:eMMC 4.5 enable     1:eMMC 4.5 disable
+    //
+    If (LAnd(LEqual(PCIM, 0), LEqual(HSID, 0)))
+    {
+      Return (0xF)
+    }
+    Else
+    {
+      Return (0x0)
+    }
+  }
+
+
+  Method (_PS3, 0, NotSerialized)
+  {
+    OR(PSAT, 0x00000003, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+    //
+    // If not B1, still keep 2 ms w/a
+    //
+    If(LLess(SOCS, 0x03))
+    {
+      Sleep(2)
+    }
+  }
+  Method (_PS0, 0, NotSerialized)
+  {
+    And(PSAT, 0xfffffffC, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+    //
+    // If not B1, still keep 2 ms w/a
+    //
+    If(LLess(SOCS, 0x03))
+    {
+      Sleep(2)
+    }
+  }
+
+  OperationRegion (KEYS, SystemMemory, eM1A, 0x100)
+  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+  {
+    Offset (0x84),
+           PSAT,  32
+  }
+
+         Method (_DIS, 0x0, NotSerialized)
+  {
+    //Adding dummy disable methods for device EMM0
+  }
+
+  Device (EM45)
+  {
+    Name (_ADR, 0x00000008) // Slot 0, Function 8
+    Method (_RMV, 0, NotSerialized)
+    {
+      Return (0x0)
+    }
+  }
+}
+
+
+//
+// SDIO
+//
+Device(SDHB)
+{
+  Name (_ADR, 0)
+  Name (_HID, "INT33BB")
+  Name (_CID, "PNP0D40")
+  Name (_DDN, "Intel(R) SDIO Controller - 80860F15")
+  Name (_UID, 2)
+  Name (_HRV, 2)
+  Name(_DEP, Package(0x01)
+  {
+    PEPD
+  })
+  Name (PSTS, 0x0)
+
+  Name (RBUF, ResourceTemplate ()
+  {
+    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
+    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {46}  // SDIO IRQ
+  })
+
+  Method (_CRS, 0x0, NotSerialized)
+  {
+
+    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
+    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
+    Store(SI0A, B0BA)
+    Store(SI0L, B0LN)
+    Return (RBUF)
+  }
+  Method (_STA, 0x0, NotSerialized)
+  {
+    If (LLessEqual(STEP, 0x04))
+    {
+      //A stepping
+      Store(SDMD, _HRV)
+    }
+
+    //
+    // PCIM>> 0:ACPI mode           1:PCI mode
+    //
+    If (LEqual(PCIM, 1)) {
+      Return (0x0)
+    }
+
+    If (LOr(LEqual(SI0A, 0), LEqual(SD2D, 1)))
+    {
+      Return (0x0)
+    }
+    Return (0xF)
+  }
+  Method (_DIS, 0x0, NotSerialized)
+  {
+    //Adding dummy disable methods for device EMM0
+  }
+
+  Method (_PS3, 0, NotSerialized)
+  {
+    OR(PSAT, 0x00000003, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+  }
+  Method (_PS0, 0, NotSerialized)
+  {
+    And(PSAT, 0xfffffffC, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+
+    if(LEqual(\_SB.SDHB.PSTS,0x0))
+    {
+      if(LEqual (\_SB.GPO2.AVBL, 1))
+      {
+        Store( 0x01, \_SB.GPO2.WFD3 ) // WL_WIFI_REQ_ON = 1 put the device to normal state
+        Store( 0x01, \_SB.SDHB.PSTS)  // indicates that the device powered ON
+      }
+    }
+
+
+  }
+  OperationRegion (KEYS, SystemMemory, SI1A, 0x100)
+  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+  {
+    Offset (0x84),
+           PSAT,   32
+  }
+
+
+         Device (BRCM)
+  {
+    Name (_ADR, 0x01)                 //SlotNumber + Function
+    Name (_DEP, Package() {\_SB.GPO2})
+
+    Method (_RMV, 0, NotSerialized)
+    {
+      Return (0x0)
+    }
+    Name (_PRW, Package() {0, 0})
+    Name (_S4W, 2)
+
+    Method (_CRS, 0, Serialized)
+    {
+      Name (RBUF, ResourceTemplate ()
+      {
+        Interrupt (ResourceConsumer, Edge, ActiveHigh, ExclusiveAndWake, , , ) {73}
+      })
+      Return (RBUF)
+    }
+
+    Method (_PS3, 0, NotSerialized)
+    {
+      if(LEqual (\_SB.GPO2.AVBL, 1))
+      {
+        Store( 0x00, \_SB.GPO2.WFD3 ) // WL_WIFI_REQ_ON = 0 puts the device in reset state
+        Store( 0x00, \_SB.SDHB.PSTS) //Indicates that the device is powered off
+      }
+
+    }
+    Method (_PS0, 0, NotSerialized)
+    {
+      if(LEqual(\_SB.SDHB.PSTS,0x0))
+      {
+        if(LEqual (\_SB.GPO2.AVBL, 1))
+        {
+          Store( 0x01, \_SB.GPO2.WFD3 ) // WL_WIFI_REQ_ON = 1 put the device to normal state
+          Store( 0x01, \_SB.SDHB.PSTS)     // indicates that the device powered ON
+        }
+      }
+    }
+  } // Device (BRCM)
+  //
+  // Secondary Broadcom WIFI function
+  //
+  Device(BRC2)
+  {
+    Name(_ADR, 0x2) // function 2
+    Name(_STA, 0xf)
+    //
+    // The device is not removable. This must be a method.
+    //
+    Method(_RMV, 0x0, NotSerialized)
+    {
+      Return(0x0)
+    }
+
+    //
+    // Describe a vendor-defined connection between this device and the
+    // primary wifi device
+    //
+
+    Method(_CRS)
+    {
+      Name(NAM, Buffer() {"\\_SB.SDHB.BRCM"})
+      Name(SPB, Buffer()
+      {
+        0x8E,       // SPB Descriptor
+        0x18, 0x00, // Length including NAM above
+        0x01,       // +0x00 SPB Descriptor Revision
+        0x00,       // +0x01 Resource Source Index
+        0xc0,       // +0x02 Bus type - vendor defined
+        0x02,       // +0x03 Consumer + controller initiated
+        0x00, 0x00, // +0x04 Type specific flags
+        0x01,       // +0x06 Type specific revision
+        0x00, 0x00  // +0x07 type specific data length
+        // +0x09 - 0xf bytes for NULL-terminated NAM
+        // Length = 0x18
+      })
+
+      Name(END, Buffer() {0x79, 0x00})
+      Concatenate(SPB, NAM, Local0)
+      Concatenate(Local0, END, Local1)
+      Return(Local1)
+    }
+  }
+
+}
+
+//
+// SD Card
+//
+Device(SDHC)
+{
+  Name (_ADR, 0)
+  Name (_HID, "80860F16")
+  Name (_CID, "PNP0D40")
+  Name (_DDN, "Intel(R) SD Card Controller - 80860F16")
+  Name (_UID, 3)
+  Name(_DEP, Package(0x01)
+  {
+    PEPD
+  })
+  Name (RBUF, ResourceTemplate ()
+  {
+    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
+    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {47}  // SD Card IRQ
+  })
+  Method (_CRS, 0x0, NotSerialized)
+  {
+    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
+    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
+    Store(SD0A, B0BA)
+    Store(SD0L, B0LN)
+    Return (RBUF)
+  }
+  Method (_STA, 0x0, NotSerialized)
+  {
+    //
+    // PCIM>> 0:ACPI mode           1:PCI mode
+    //
+    If (LEqual(PCIM, 1)) {
+      Return (0x0)
+    }
+
+    If (LOr(LEqual(SD0A, 0), LEqual(SD3D, 1)))
+    {
+      Return (0x0)
+    }
+    Return (0xF)
+  }
+
+  Method (_PS3, 0, NotSerialized)
+  {
+    OR(PSAT, 0x00000003, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+  }
+  Method (_PS0, 0, NotSerialized)
+  {
+    And(PSAT, 0xfffffffC, PSAT)
+    OR(PSAT, 0X00000000, PSAT)
+  }
+  OperationRegion (KEYS, SystemMemory, SD1A, 0x100)
+  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
+  {
+    Offset (0x84),
+           PSAT,   32
+  }
+
+  Device (CARD)
+  {
+    Name (_ADR, 0x00000008)
+    Method(_RMV, 0x0, NotSerialized)
+    {
+      // SDRM = 0 non-removable;
+      If (LEqual(SDRM, 0))
+      {
+        Return (0)
+      }
+
+      Return (1)
+    }
+  }
+
+}
+
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchSmb.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchSmb.asl
new file mode 100644
index 0000000000..4de0c32927
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchSmb.asl
@@ -0,0 +1,833 @@
+/**************************************************************************;
+;*                                                                        *;
+;*                                                                        *;
+;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
+;*    Family of Customer Reference Boards.                                *;
+;*                                                                        *;
+;*                                                                        *;
+;*    Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved   *;
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;*                                                                        *;
+;*                                                                        *;
+;**************************************************************************/
+
+
+// Define various SMBus PCI Configuration Space Registers.
+
+OperationRegion(SMBP,PCI_Config,0x40,0xC0)
+Field(SMBP,DWordAcc,NoLock,Preserve)
+{
+  ,     2,
+  I2CE, 1
+}
+
+// SMBus Send Byte - This function will write a single byte of
+// data to a specific Slave Device per SMBus Send Byte Protocol.
+//      Arg0 = Address
+//      Arg1 = Data
+//      Return: Success = 1
+//              Failure = 0
+
+      Method(SSXB,2,Serialized)
+{
+  OperationRegion(SMPB,PCI_Config,0x20,4)
+  Field(SMPB,DWordAcc,NoLock,Preserve)
+  {
+    ,     5,
+    SBAR, 11
+  }
+
+  // Define various SMBus IO Mapped Registers.
+
+  OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10)
+  Field(SMBI,ByteAcc,NoLock,Preserve)
+  {
+    HSTS, 8,        // 0 - Host Status Register
+    Offset(0x02),
+    HCON, 8,        // 2 - Host Control
+    HCOM, 8,        // 3 - Host Command
+    TXSA, 8,        // 4 - Transmit Slave Address
+    DAT0, 8,        // 5 - Host Data 0
+    DAT1, 8,        // 6 - Host Data 1
+    HBDR, 8,        // 7 - Host Block Data
+    PECR, 8,        // 8 - Packer Error Check
+    RXSA, 8,        // 9 - Receive Slave Address
+    SDAT, 16,       // A - Slave Data
+  }
+
+  // Step 1:  Confirm the ICHx SMBus is ready to perform
+  // communication.
+
+  If(STRT())
+  {
+    Return(0)
+  }
+
+  // Step 2:  Initiate a Send Byte.
+
+  Store(0,I2CE)                           // Ensure SMbus Mode.
+  Store(0xBF,HSTS)                        // Clear all but INUSE_STS.
+  Store(Arg0,TXSA)                        // Write Address in TXSA.
+  Store(Arg1,HCOM)                        // Data in HCOM.
+
+  // Set the SMBus Host control register to 0x48.
+  //   Bit 7:    =  0  = reserved
+  //   Bit 6:    =  1  = start
+  //   Bit 5:    =  0  = disregard, I2C related bit
+  //   Bits 4:2: = 001 = Byte Protocol
+  //   Bit 1:    =  0  = Normal Function
+  //   Bit 0:    =  0  = Disable interrupt generation
+
+  Store(0x48,HCON)
+
+  // Step 3:  Exit the Method correctly.
+
+  If(COMP)
+  {
+    Or(HSTS,0xFF,HSTS)              // Clear INUSE_STS and others..
+    Return(1)                       // Return Success.
+  }
+
+  Return(0)
+}
+
+// SMBus Receive Byte - This function will write a single byte
+// of data to a specific Slave Device per SMBus Receive Byte
+// Protocol.
+//      Arg0 = Address
+//      Return: Success = Byte-Size Value
+//              Failure = Word-Size Value = FFFFh.
+
+Method(SRXB,1,Serialized)
+{
+  OperationRegion(SMPB,PCI_Config,0x20,4)
+  Field(SMPB,DWordAcc,NoLock,Preserve)
+  {
+    ,     5,
+    SBAR, 11
+  }
+
+  // Define various SMBus IO Mapped Registers.
+
+  OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10)
+  Field(SMBI,ByteAcc,NoLock,Preserve)
+  {
+    HSTS, 8,        // 0 - Host Status Register
+    Offset(0x02),
+    HCON, 8,        // 2 - Host Control
+    HCOM, 8,        // 3 - Host Command
+    TXSA, 8,        // 4 - Transmit Slave Address
+    DAT0, 8,        // 5 - Host Data 0
+    DAT1, 8,        // 6 - Host Data 1
+    HBDR, 8,        // 7 - Host Block Data
+    PECR, 8,        // 8 - Packer Error Check
+    RXSA, 8,        // 9 - Receive Slave Address
+    SDAT, 16,       // A - Slave Data
+  }
+  // Step 1:  Confirm the ICHx SMBus is ready to perform
+  // communication.
+
+  If(STRT())
+  {
+    Return(0xFFFF)
+  }
+
+  // Step 2:  Initiate a Receive Byte.
+
+  Store(0,I2CE)                           // Ensure SMbus Mode.
+  Store(0xBF,HSTS)                        // Clear all but INUSE_STS.
+  Store(Or(Arg0,1),TXSA)                  // Read Address in TXSA.
+
+  // Set the SMBus Host control register to 0x48.
+  //   Bit 7:    =  0  = reserved
+  //   Bit 6:    =  1  = start
+  //   Bit 5:    =  0  = disregard, I2C related bit
+  //   Bits 4:2: = 001 = Byte Protocol
+  //   Bit 1:    =  0  = Normal Function
+  //   Bit 0:    =  0  = Disable interrupt generation
+
+  Store(0x44,HCON)
+
+  // Step 3:  Exit the Method correctly.
+
+  If(COMP)
+  {
+    Or(HSTS,0xFF,HSTS)              // Clear INUSE_STS and others..
+    Return(DAT0)                    // Return Success.
+  }
+
+  Return(0xFFFF)                          // Return Failure.
+}
+
+// SMBus Write Byte - This function will write a single byte
+// of data to a specific Slave Device per SMBus Write Byte
+// Protocol.
+//      Arg0 = Address
+//      Arg1 = Command
+//      Arg2 = Data
+//      Return: Success = 1
+//              Failure = 0
+
+Method(SWRB,3,Serialized)
+{
+  OperationRegion(SMPB,PCI_Config,0x20,4)
+  Field(SMPB,DWordAcc,NoLock,Preserve)
+  {
+    ,     5,
+    SBAR, 11
+  }
+
+  // Define various SMBus IO Mapped Registers.
+
+  OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10)
+  Field(SMBI,ByteAcc,NoLock,Preserve)
+  {
+    HSTS, 8,        // 0 - Host Status Register
+    Offset(0x02),
+    HCON, 8,        // 2 - Host Control
+    HCOM, 8,        // 3 - Host Command
+    TXSA, 8,        // 4 - Transmit Slave Address
+    DAT0, 8,        // 5 - Host Data 0
+    DAT1, 8,        // 6 - Host Data 1
+    HBDR, 8,        // 7 - Host Block Data
+    PECR, 8,        // 8 - Packer Error Check
+    RXSA, 8,        // 9 - Receive Slave Address
+    SDAT, 16,       // A - Slave Data
+  }
+  // Step 1:  Confirm the ICHx SMBus is ready to perform communication.
+
+  If(STRT())
+  {
+    Return(0)
+  }
+
+  // Step 2:  Initiate a Write Byte.
+
+  Store(0,I2CE)                           // Ensure SMbus Mode.
+  Store(0xBF,HSTS)                        // Clear all but INUSE_STS.
+  Store(Arg0,TXSA)                        // Write Address in TXSA.
+  Store(Arg1,HCOM)                        // Command in HCOM.
+  Store(Arg2,DAT0)                        // Data in DAT0.
+
+  // Set the SMBus Host control register to 0x48.
+  //   Bit 7:    =  0  = reserved
+  //   Bit 6:    =  1  = start
+  //   Bit 5:    =  0  = disregard, I2C related bit
+  //   Bits 4:2: = 010 = Byte Data Protocol
+  //   Bit 1:    =  0  = Normal Function
+  //   Bit 0:    =  0  = Disable interrupt generation
+
+  Store(0x48,HCON)
+
+  // Step 3:  Exit the Method correctly.
+
+  If(COMP)
+  {
+    Or(HSTS,0xFF,HSTS)              // Clear INUSE_STS and others..
+    Return(1)                       // Return Success.
+  }
+
+  Return(0)                               // Return Failure.
+}
+
+// SMBus Read Byte - This function will read a single byte of data
+// from a specific slave device per SMBus Read Byte Protocol.
+//      Arg0 = Address
+//      Arg1 = Command
+//      Return: Success = Byte-Size Value
+//              Failure = Word-Size Value
+
+Method(SRDB,2,Serialized)
+{
+  OperationRegion(SMPB,PCI_Config,0x20,4)
+  Field(SMPB,DWordAcc,NoLock,Preserve)
+  {
+    ,     5,
+    SBAR, 11
+  }
+
+  // Define various SMBus IO Mapped Registers.
+
+  OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10)
+  Field(SMBI,ByteAcc,NoLock,Preserve)
+  {
+    HSTS, 8,        // 0 - Host Status Register
+    Offset(0x02),
+    HCON, 8,        // 2 - Host Control
+    HCOM, 8,        // 3 - Host Command
+    TXSA, 8,        // 4 - Transmit Slave Address
+    DAT0, 8,        // 5 - Host Data 0
+    DAT1, 8,        // 6 - Host Data 1
+    HBDR, 8,        // 7 - Host Block Data
+    PECR, 8,        // 8 - Packer Error Check
+    RXSA, 8,        // 9 - Receive Slave Address
+    SDAT, 16,       // A - Slave Data
+  }
+  // Step 1:  Confirm the ICHx SMBus is ready to perform communication.
+
+  If(STRT())
+  {
+    Return(0xFFFF)
+  }
+
+  // Step 2:  Initiate a Read Byte.
+
+  Store(0,I2CE)                           // Ensure SMbus Mode.
+  Store(0xBF,HSTS)                        // Clear all but INUSE_STS.
+  Store(Or(Arg0,1),TXSA)                  // Read Address in TXSA.
+  Store(Arg1,HCOM)                        // Command in HCOM.
+
+  // Set the SMBus Host control register to 0x48.
+  //   Bit 7:    =  0  = reserved
+  //   Bit 6:    =  1  = start
+  //   Bit 5:    =  0  = disregard, I2C related bit
+  //   Bits 4:2: = 010 = Byte Data Protocol
+  //   Bit 1:    =  0  = Normal Function
+  //   Bit 0:    =  0  = Disable interrupt generation
+
+  Store(0x48,HCON)
+
+  // Step 3:  Exit the Method correctly.
+
+  If(COMP)
+  {
+    Or(HSTS,0xFF,HSTS)              // Clear INUSE_STS and others..
+    Return(DAT0)                    // Return Success.
+  }
+
+  Return(0xFFFF)                          // Return Failure.
+}
+
+// SMBus Write Word - This function will write a single word
+// of data to a specific Slave Device per SMBus Write Word
+// Protocol.
+//      Arg0 = Address
+//      Arg1 = Command
+//      Arg2 = Data (16 bits in size)
+//      Return: Success = 1
+//              Failure = 0
+
+Method(SWRW,3,Serialized)
+{
+  OperationRegion(SMPB,PCI_Config,0x20,4)
+  Field(SMPB,DWordAcc,NoLock,Preserve)
+  {
+    ,     5,
+    SBAR, 11
+  }
+
+  // Define various SMBus IO Mapped Registers.
+
+  OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10)
+  Field(SMBI,ByteAcc,NoLock,Preserve)
+  {
+    HSTS, 8,        // 0 - Host Status Register
+    Offset(0x02),
+	HCON, 8,        // 2 - Host Control
+	HCOM, 8,        // 3 - Host Command
+	TXSA, 8,        // 4 - Transmit Slave Address
+	DAT0, 8,        // 5 - Host Data 0
+	DAT1, 8,        // 6 - Host Data 1
+	HBDR, 8,        // 7 - Host Block Data
+	PECR, 8,        // 8 - Packer Error Check
+	RXSA, 8,        // 9 - Receive Slave Address
+	SDAT, 16,       // A - Slave Data
+  }
+  // Step 1:  Confirm the ICHx SMBus is ready to perform communication.
+
+  If(STRT())
+  {
+    Return(0)
+  }
+
+  // Step 2:  Initiate a Write Word.
+
+  Store(0,I2CE)                           // Ensure SMbus Mode.
+  Store(0xBF,HSTS)                        // Clear all but INUSE_STS.
+  Store(Arg0,TXSA)                        // Write Address in TXSA.
+  Store(Arg1,HCOM)                        // Command in HCOM.
+  And(Arg2,0xFF,DAT1)                     // Low byte Data in DAT1.
+  And(ShiftRight(Arg2,8),0xFF,DAT0)       // High byte Data in DAT0.
+
+  // Set the SMBus Host control register to 0x4C.
+  //   Bit 7:    =  0  = reserved
+  //   Bit 6:    =  1  = start
+  //   Bit 5:    =  0  = disregard, I2C related bit
+  //   Bits 4:2: = 011 = Word Data Protocol
+  //   Bit 1:    =  0  = Normal Function
+  //   Bit 0:    =  0  = Disable interrupt generation
+
+  Store(0x4C,HCON)
+
+  // Step 3:  Exit the Method correctly.
+
+  If(COMP())
+  {
+    Or(HSTS,0xFF,HSTS)              // Clear INUSE_STS and others.
+    Return(1)                       // Return Success.
+  }
+
+  Return(0)                               // Return Failure.
+}
+
+// SMBus Read Word - This function will read a single byte of data
+// from a specific slave device per SMBus Read Word Protocol.
+//      Arg0 = Address
+//      Arg1 = Command
+//      Return: Success = Word-Size Value
+//              Failure = Dword-Size Value
+
+Method(SRDW,2,Serialized)
+{
+  OperationRegion(SMPB,PCI_Config,0x20,4)
+  Field(SMPB,DWordAcc,NoLock,Preserve)
+  {
+    ,     5,
+    SBAR, 11
+  }
+
+  // Define various SMBus IO Mapped Registers.
+
+  OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10)
+  Field(SMBI,ByteAcc,NoLock,Preserve)
+  {
+    HSTS, 8,        // 0 - Host Status Register
+	Offset(0x02),
+	HCON, 8,        // 2 - Host Control
+	HCOM, 8,        // 3 - Host Command
+	TXSA, 8,        // 4 - Transmit Slave Address
+	DAT0, 8,        // 5 - Host Data 0
+	DAT1, 8,        // 6 - Host Data 1
+	HBDR, 8,        // 7 - Host Block Data
+	PECR, 8,        // 8 - Packer Error Check
+	RXSA, 8,        // 9 - Receive Slave Address
+	SDAT, 16,       // A - Slave Data
+  }
+  // Step 1:  Confirm the ICHx SMBus is ready to perform communication.
+
+  If(STRT())
+  {
+    Return(0xFFFF)
+  }
+
+  // Step 2:  Initiate a Read Word.
+
+  Store(0,I2CE)                           // Ensure SMbus Mode.
+  Store(0xBF,HSTS)                        // Clear all but INUSE_STS.
+  Store(Or(Arg0,1),TXSA)                  // Read Address in TXSA.
+  Store(Arg1,HCOM)                        // Command in HCOM.
+
+  // Set the SMBus Host control register to 0x4C.
+  //   Bit 7:    =  0  = reserved
+  //   Bit 6:    =  1  = start
+  //   Bit 5:    =  0  = disregard, I2C related bit
+  //   Bits 4:2: = 011 = Word Data Protocol
+  //   Bit 1:    =  0  = Normal Function
+  //   Bit 0:    =  0  = Disable interrupt generation
+
+  Store(0x4C,HCON)
+
+  // Step 3:  Exit the Method correctly.
+
+  If(COMP())
+  {
+    Or(HSTS,0xFF,HSTS)                      // Clear INUSE_STS and others.
+    Return(Or(ShiftLeft(DAT0,8),DAT1))      // Return Success.
+  }
+
+  Return(0xFFFFFFFF)                      // Return Failure.
+}
+
+// SMBus Block Write - This function will write an entire block of data
+// to a specific slave device per SMBus Block Write Protocol.
+//      Arg0 = Address
+//      Arg1 = Command
+//      Arg2 = Buffer of Data to Write
+//      Arg3 = 1 = I2C Block Write, 0 = SMBus Block Write
+//      Return: Success = 1
+//              Failure = 0
+
+Method(SBLW,4,Serialized)
+{
+  OperationRegion(SMPB,PCI_Config,0x20,4)
+  Field(SMPB,DWordAcc,NoLock,Preserve)
+  {
+    ,     5,
+    SBAR, 11
+  }
+
+  // Define various SMBus IO Mapped Registers.
+
+  OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10)
+  Field(SMBI,ByteAcc,NoLock,Preserve)
+  {
+    HSTS, 8,        // 0 - Host Status Register
+	Offset(0x02),
+	HCON, 8,        // 2 - Host Control
+	HCOM, 8,        // 3 - Host Command
+	TXSA, 8,        // 4 - Transmit Slave Address
+	DAT0, 8,        // 5 - Host Data 0
+	DAT1, 8,        // 6 - Host Data 1
+	HBDR, 8,        // 7 - Host Block Data
+	PECR, 8,        // 8 - Packer Error Check
+	RXSA, 8,        // 9 - Receive Slave Address
+	SDAT, 16,       // A - Slave Data
+  }
+  // Step 1:  Confirm the ICHx SMBus is ready to perform communication.
+
+  If(STRT())
+  {
+    Return(0)
+  }
+
+  // Step 2:  Initiate a Block Write.
+
+  Store(Arg3,I2CE)                        // Select the proper protocol.
+  Store(0xBF,HSTS)                        // Clear all but INUSE_STS.
+  Store(Arg0,TXSA)                        // Write Address in TXSA.
+  Store(Arg1,HCOM)                        // Command in HCOM.
+  Store(Sizeof(Arg2),DAT0)                // Count in DAT0.
+  Store(0,Local1)                         // Init Pointer to Buffer.
+  Store(DerefOf(Index(Arg2,0)),HBDR)      // First Byte in HBD Register.
+
+  // Set the SMBus Host control register to 0x48.
+  //   Bit 7:    =  0  = reserved
+  //   Bit 6:    =  1  = start
+  //   Bit 5:    =  0  = disregard, I2C related bit
+  //   Bits 4:2: = 101 = Block Protocol
+  //   Bit 1:    =  0  = Normal Function
+  //   Bit 0:    =  0  = Disable interrupt generation
+
+  Store(0x54,HCON)
+
+  // Step 3:  Send the entire Block of Data.
+
+  While(LGreater(Sizeof(Arg2),Local1))
+  {
+    // Wait up to 200ms for Host Status to get set.
+
+    Store(4000,Local0)              // 4000 * 50us = 200ms.
+
+    While(LAnd(LNot(And(HSTS,0x80)),Local0))
+    {
+      Decrement(Local0)       // Decrement Count.
+      Stall(50)               // Delay = 50us.
+    }
+
+    If(LNot(Local0))                // Timeout?
+    {
+      KILL()                  // Yes.  Kill Communication.
+      Return(0)               // Return failure.
+    }
+
+    Store(0x80,HSTS)                // Clear Host Status.
+    Increment(Local1)               // Point to Next Byte.
+
+    // Place next byte in HBDR if last byte has not been sent.
+
+    If(LGreater(Sizeof(Arg2),Local1))
+    {
+      Store(DerefOf(Index(Arg2,Local1)),HBDR)
+    }
+  }
+
+  // Step 4:  Exit the Method correctly.
+
+  If(COMP())
+  {
+    Or(HSTS,0xFF,HSTS)              // Clear all status bits.
+    Return(1)                       // Return Success.
+  }
+
+  Return(0)                               // Return Failure.
+}
+
+// SMBus Block Read - This function will read a block of data from
+// a specific slave device per SMBus Block Read Protocol.
+//      Arg0 = Address
+//      Arg1 = Command
+//      Arg2 = 1 = I2C Block Write, 0 = SMBus Block Write
+//      Return: Success = Data Buffer (First Byte = length)
+//              Failure = 0
+
+Method(SBLR,3,Serialized)
+{
+  OperationRegion(SMPB,PCI_Config,0x20,4)
+  Field(SMPB,DWordAcc,NoLock,Preserve)
+  {
+    ,     5,
+    SBAR, 11
+  }
+
+  // Define various SMBus IO Mapped Registers.
+
+  OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10)
+  Field(SMBI,ByteAcc,NoLock,Preserve)
+  {
+    HSTS, 8,        // 0 - Host Status Register
+	Offset(0x02),
+	HCON, 8,        // 2 - Host Control
+	HCOM, 8,        // 3 - Host Command
+	TXSA, 8,        // 4 - Transmit Slave Address
+	DAT0, 8,        // 5 - Host Data 0
+	DAT1, 8,        // 6 - Host Data 1
+	HBDR, 8,        // 7 - Host Block Data
+	PECR, 8,        // 8 - Packer Error Check
+	RXSA, 8,        // 9 - Receive Slave Address
+	SDAT, 16,       // A - Slave Data
+  }
+  Name(TBUF, Buffer(256) {})
+
+  // Step 1:  Confirm the ICHx SMBus is ready to perform communication.
+
+  If(STRT())
+  {
+    Return(0)
+  }
+
+  // Step 2:  Initiate a Block Read.
+
+  Store(Arg2,I2CE)                        // Select the proper protocol.
+  Store(0xBF,HSTS)                        // Clear all but INUSE_STS.
+  Store(Or(Arg0,1),TXSA)                  // Read Address in TXSA.
+  Store(Arg1,HCOM)                        // Command in HCOM.
+
+  // Set the SMBus Host control register to 0x48.
+  //   Bit 7:    =  0  = reserved
+  //   Bit 6:    =  1  = start
+  //   Bit 5:    =  0  = disregard, I2C related bit
+  //   Bits 4:2: = 101 = Block Protocol
+  //   Bit 1:    =  0  = Normal Function
+  //   Bit 0:    =  0  = Disable interrupt generation
+
+  Store(0x54,HCON)
+
+  // Step 3:  Wait up to 200ms to get the Data Count.
+
+  Store(4000,Local0)                      // 4000 * 50us = 200ms.
+
+  While(LAnd(LNot(And(HSTS,0x80)),Local0))
+  {
+    Decrement(Local0)               // Decrement Count.
+    Stall(50)                       // Delay = 50us.
+  }
+
+  If(LNot(Local0))                        // Timeout?
+  {
+    KILL()                          // Yes.  Kill Communication.
+    Return(0)                       // Return failure.
+  }
+
+  Store(DAT0,Index(TBUF,0))               // Get the Data Count.
+  Store(0x80,HSTS)                        // Clear Host Status.
+  Store(1,Local1)                         // Local1 = Buffer Pointer.
+
+  // Step 4:  Get the Block Data and store it.
+
+  While(LLess(Local1,DerefOf(Index(TBUF,0))))
+  {
+    // Wait up to 200ms for Host Status to get set.
+
+    Store(4000,Local0)              // 4000 * 50us = 200ms.
+
+    While(LAnd(LNot(And(HSTS,0x80)),Local0))
+    {
+      Decrement(Local0)       // Decrement Count.
+      Stall(50)               // Delay = 50us.
+    }
+
+    If(LNot(Local0))                // Timeout?
+    {
+      KILL()                  // Yes.  Kill Communication.
+      Return(0)               // Return failure.
+    }
+
+    Store(HBDR,Index(TBUF,Local1))  // Place into Buffer.
+    Store(0x80,HSTS)                // Clear Host Status.
+    Increment(Local1)
+  }
+
+  // Step 5:  Exit the Method correctly.
+
+  If(COMP())
+  {
+    Or(HSTS,0xFF,HSTS)              // Clear INUSE_STS and others.
+    Return(TBUF)                    // Return Success.
+  }
+
+  Return(0)                               // Return Failure.
+}
+
+
+// SMBus Start Check
+//      Return: Success = 0
+//              Failure = 1
+
+Method(STRT,0,Serialized)
+{
+  OperationRegion(SMPB,PCI_Config,0x20,4)
+  Field(SMPB,DWordAcc,NoLock,Preserve)
+  {
+    ,     5,
+    SBAR, 11
+  }
+
+  // Define various SMBus IO Mapped Registers.
+
+  OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10)
+  Field(SMBI,ByteAcc,NoLock,Preserve)
+  {
+    HSTS, 8,        // 0 - Host Status Register
+	Offset(0x02),
+	HCON, 8,        // 2 - Host Control
+	HCOM, 8,        // 3 - Host Command
+	TXSA, 8,        // 4 - Transmit Slave Address
+	DAT0, 8,        // 5 - Host Data 0
+	DAT1, 8,        // 6 - Host Data 1
+	HBDR, 8,        // 7 - Host Block Data
+	PECR, 8,        // 8 - Packer Error Check
+	RXSA, 8,        // 9 - Receive Slave Address
+	SDAT, 16,       // A - Slave Data
+  }
+  // Wait up to 200ms to confirm the SMBus Semaphore has been
+  // released (In Use Status = 0).  Note that the Sleep time may take
+  // longer as the This function will yield the Processor such that it
+  // may perform different tasks during the delay.
+
+  Store(200,Local0)                       // 200 * 1ms = 200ms.
+
+  While(Local0)
+  {
+    If(And(HSTS,0x40))              // In Use Set?
+    {
+      Decrement(Local0)       // Yes.  Decrement Count.
+      Sleep(1)                // Delay = 1ms.
+      If(LEqual(Local0,0))    // Count = 0?
+      {
+        Return(1)       // Return failure.
+      }
+    }
+    Else
+    {
+      Store(0,Local0)         // In Use Clear.  Continue.
+    }
+  }
+
+  // In Use Status = 0 during last read, which will make subsequent
+  // reads return In Use Status = 1 until software clears it.  All
+  // software using ICHx SMBus should check this bit before initiating
+  // any SMBus communication.
+
+  // Wait up to 200ms to confirm the Host Interface is
+  // not processing a command.
+
+  Store(4000,Local0)                      // 4000 * 50us = 200ms.
+
+  While(Local0)
+  {
+    If(And(HSTS,0x01))              // Host Busy Set?
+    {
+      Decrement(Local0)       // Decrement Count.
+      Stall(50)               // Delay = 50us.
+      If(LEqual(Local0,0))    // Count = 0?
+      {
+        KILL()          // Yes.  Kill Communication.
+      }
+    }
+    Else
+    {
+      Return(0)
+    }
+  }
+
+  Return(1)                               // Timeout.  Return failure.
+}
+
+// SMBus Completion Check
+//      Return: Success = 1
+//              Failure = 0
+
+Method(COMP,0,Serialized)
+{
+  OperationRegion(SMPB,PCI_Config,0x20,4)
+  Field(SMPB,DWordAcc,NoLock,Preserve)
+  {
+    ,     5,
+    SBAR, 11
+  }
+
+  // Define various SMBus IO Mapped Registers.
+
+  OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10)
+  Field(SMBI,ByteAcc,NoLock,Preserve)
+  {
+    HSTS, 8,        // 0 - Host Status Register
+	Offset(0x02),
+	HCON, 8,        // 2 - Host Control
+	HCOM, 8,        // 3 - Host Command
+	TXSA, 8,        // 4 - Transmit Slave Address
+	DAT0, 8,        // 5 - Host Data 0
+	DAT1, 8,        // 6 - Host Data 1
+	HBDR, 8,        // 7 - Host Block Data
+	PECR, 8,        // 8 - Packer Error Check
+	RXSA, 8,        // 9 - Receive Slave Address
+	SDAT, 16,       // A - Slave Data
+  }
+  // Wait for up to 200ms for the Completion Command
+  // Status to get set.
+
+  Store(4000,Local0)                      // 4000 * 50us = 200ms.
+
+  While(Local0)
+  {
+    If(And(HSTS,0x02))              // Completion Status Set?
+    {
+      Return(1)               // Yes.  We are done.
+    }
+    Else
+    {
+      Decrement(Local0)       // Decrement Count.
+      Stall(50)               // Delay 50us.
+      If(LEqual(Local0,0))    // Count = 0?
+      {
+        KILL()          // Yes.  Kill Communication.
+      }
+    }
+  }
+
+  Return(0)                               // Timeout.  Return Failure.
+}
+
+// SMBus Kill Command
+
+Method(KILL,0,Serialized)
+{
+  OperationRegion(SMPB,PCI_Config,0x20,4)
+  Field(SMPB,DWordAcc,NoLock,Preserve)
+  {
+    ,     5,
+    SBAR, 11
+  }
+
+  // Define various SMBus IO Mapped Registers.
+
+  OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10)
+  Field(SMBI,ByteAcc,NoLock,Preserve)
+  {
+    HSTS, 8,        // 0 - Host Status Register
+	Offset(0x02),
+	HCON, 8,        // 2 - Host Control
+	HCOM, 8,        // 3 - Host Command
+	TXSA, 8,        // 4 - Transmit Slave Address
+	DAT0, 8,        // 5 - Host Data 0
+	DAT1, 8,        // 6 - Host Data 1
+	HBDR, 8,        // 7 - Host Block Data
+	PECR, 8,        // 8 - Packer Error Check
+	RXSA, 8,        // 9 - Receive Slave Address
+	SDAT, 16,       // A - Slave Data
+  }
+  Or(HCON,0x02,HCON)                      // Yes.  Send Kill command.
+  Or(HSTS,0xFF,HSTS)                      // Clear all status.
+}
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchXhci.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchXhci.asl
new file mode 100644
index 0000000000..914209f668
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchXhci.asl
@@ -0,0 +1,379 @@
+/**************************************************************************;
+;*                                                                        *;
+;*                                                                        *;
+;*    Intel Corporation - ACPI Reference Code for the Haswell             *;
+;*    Family of Customer Reference Boards.                                *;
+;*                                                                        *;
+;*                                                                        *;
+;*    Copyright (c)  2010  - 2015, Intel Corporation. All rights reserved   *;
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;*                                                                        *;
+;*                                                                        *;
+;**************************************************************************/
+
+//scope is \_SB.PCI0.XHC
+Device(XHC1)
+{
+  Name(_ADR, 0x00140000)                     //Device 20, Function 0
+
+  //When it is in Host mode, USH core is connected to USB3 microAB(USB3 P1 and USB2 P0)
+  Name (_DDN, "Baytrail XHCI controller (CCG core/Host only)" )
+
+  Method(XDEP, 0)
+  {
+    If(LEqual(OSYS,2013))
+    {
+      Name(_DEP, Package(0x1)
+      {
+        PEPD
+      })
+    }
+  }
+
+  Name (_STR, Unicode ("Baytrail XHCI controller (CCG core/Host only)"))
+  Name(_PRW, Package() {0xD,4})
+
+  Method(_PSW,1)
+  {
+    If (LAnd (PMES, PMEE)) {
+       Store (0, PMEE)
+       Store (1, PMES)
+    }
+  }
+
+  OperationRegion (PMEB, PCI_Config, 0x74, 0x04)  // Power Management Control/Status
+  Field (PMEB, WordAcc, NoLock, Preserve)
+  {
+    ,   8,
+    PMEE,   1,   //bit8 PME_En
+    ,   6,
+    PMES,   1    //bit15 PME_Status
+  }
+
+  Method(_STA, 0)
+  {
+    If(LNotEqual(XHCI, 0))      //NVS variable controls present of XHCI controller
+    {
+      Return (0xF)
+    } Else
+    {
+      Return (0x0)
+    }
+  }
+
+  OperationRegion(XPRT,PCI_Config,0xD0,0x10)
+  Field(XPRT,DWordAcc,NoLock,Preserve)       //usbx_top.doc.xml
+  {
+    PR2,  32,                              //bit[8:0] USB2HCSEL
+    PR2M, 32,                              //bit[8:0] USB2HCSELM
+    PR3,  32,                              //bit[3:0] USB3SSEN
+    PR3M, 32                               //bit[3:0] USB3SSENM
+  }
+
+  Device(RHUB)
+  {
+    Name(_ADR, Zero)         //address 0 is reserved for root hub
+
+    //
+    // Super Speed Ports - must match _UPC declarations of the coresponding Full Speed Ports.
+    //   Paired with Port 1
+    Device(SSP1)
+    {
+      Name(_ADR, 0x07)
+
+      Method(_UPC,0,Serialized)
+      {
+        Name(UPCP, Package()
+        {
+          0xFF,                                      // Port is connectable if non-zero
+          0x06,                                      // USB3 uAB connector
+          0x00,
+          0x00
+        })
+        Return(UPCP)
+      }
+
+      Method(_PLD,0,Serialized)
+      {
+        Name(PLDP, Package()       //pls check ACPI 5.0 section 6.1.8
+        {
+          Buffer(0x14)
+          {
+            //31:0   - Bit[6:0]=2 revision is 0x2, Bit[7]=1 Ignore Color Bit[31:8]=0 RGB color is ignored
+            0x82, 0x00, 0x00, 0x00,
+            //63:32 - Bit[47:32]=0 width: 0x0000  Bit[63:48]=0 Height:0x0000
+            0x00, 0x00, 0x00, 0x00,
+            //95:64 - bit[66:64]=b'011 visiable/docking/no lid bit[69:67]=b'001 bottom panel bit[71:70]=b'01 Center  bit[73:72]=b'01 Center
+            //           bit[77:74]=6 Horizontal Trapezoid bit[78]=0 bit[86:79]=0 bit[94:87]='0 no group info' bit[95]=0 not a bay
+            0x4B, 0x19, 0x00, 0x00,
+            //127:96 -bit[96]=1 Ejectable bit[97]=1 OSPM Ejection required Bit[105:98]=0 no Cabinet Number
+            //            bit[113:106]=0 no Card cage Number bit[114]=0 no reference shape Bit[118:115]=0 no rotation Bit[123:119]=0 no order
+            0x03, 0x00, 0x00, 0x00,
+            //159:128  Vert. and Horiz. Offsets not supplied
+            0xFF, 0xFF, 0xFF, 0xFF
+          }
+        })
+        Return (PLDP)
+      }
+    }
+    //
+    // High Speed Ports
+    // pair port with port 7 (SS)
+    //    The UPC declarations for LS/FS/HS and SS ports that are paired to form a USB3.0 compatible connector.
+    //    A "pair" is defined by two ports that declare _PLDs with identical Panel, Vertical Position, Horizontal Postion, Shape, Group Orientation
+    //    and Group Token
+    Device(HS01)
+    {
+      Name(_ADR, 0x01)
+
+      Method(_UPC,0,Serialized)
+      {
+        Name(UPCP, Package() { 0xFF,0x06,0x00,0x00 })
+        Return(UPCP)
+      }
+
+      Method(_PLD,0,Serialized)
+      {
+        Name(PLDP, Package()       //pls check ACPI 5.0 section 6.1.8
+        {
+          Buffer(0x14)
+          {
+            //31:0   - Bit[6:0]=2 revision is 0x2, Bit[7]=1 Ignore Color Bit[31:8]=0 RGB color is ignored
+            0x82, 0x00, 0x00, 0x00,
+            //63:32 - Bit[47:32]=0 width: 0x0000  Bit[63:48]=0 Height:0x0000
+            0x00, 0x00, 0x00, 0x00,
+            //95:64 - bit[66:64]=b'011 visiable/docking/no lid bit[69:67]=b'001 bottom panel bit[71:70]=b'01 Center  bit[73:72]=b'01 Center
+            //           bit[77:74]=6 Horizontal Trapezoid bit[78]=0 bit[86:79]=0 bit[94:87]='0 no group info' bit[95]=0 not a bay
+            0x4B, 0x19, 0x00, 0x00,
+            //127:96 -bit[96]=1 Ejectable bit[97]=1 OSPM Ejection required Bit[105:98]=0 no Cabinet Number
+            //            bit[113:106]=0 no Card cage Number bit[114]=0 no reference shape Bit[118:115]=0 no rotation Bit[123:119]=0 no order
+            0x03, 0x00, 0x00, 0x00,
+            //159:128  Vert. and Horiz. Offsets not supplied
+            0xFF, 0xFF, 0xFF, 0xFF
+          }
+        })
+        Return (PLDP)
+      }
+    }//end of HS01
+
+    // USB2 Type-A/USB2 only
+    // EHCI debug capable
+    Device(HS02)
+    {
+      Name(_ADR, 0x02)                                   // 0 is for root hub so physical port index starts from 1 (it is port1 in schematic)
+
+      Method(_UPC,0,Serialized)
+      {
+        Name(UPCP, Package()
+        {
+          0xFF,                     // connectable
+          0xFF,                     //
+          0x00,
+          0x00
+        })
+
+        Return(UPCP)
+      }
+
+      Method(_PLD,0,Serialized)
+      {
+        Name(PLDP, Package()
+        {
+          Buffer(0x14)
+          {
+            //31:0   - Bit[6:0]=2 revision is 0x2, Bit[7]=1 Ignore Color Bit[31:8]=0 RGB color is ignored
+            0x82, 0x00, 0x00, 0x00,
+            //63:32 - Bit[47:32]=0 width: 0x0000  Bit[63:48]=0 Height:0x0000
+            0x00, 0x00, 0x00, 0x00,
+            //95:64 - bit[66:64]=b'011 visiable/docking/no lid bit[69:67]=b'001 bottom panel bit[71:70]=b'01 Center  bit[73:72]=b'00 Left
+            //           bit[77:74]=2 Square bit[78]=0 bit[86:79]=0 bit[94:87]='0 no group info' bit[95]=0 not a bay
+            0x4B, 0x08, 0x00, 0x00,
+            //127:96 -bit[96]=1 Ejectable bit[97]=1 OSPM Ejection required Bit[105:98]=0 no Cabinet Number
+            //            bit[113:106]=0 no Card cage Number bit[114]=0 no reference shape Bit[118:115]=0 no rotation Bit[123:119]=0 no order
+            0x03, 0x00, 0x00, 0x00,
+            //159:128  Vert. and Horiz. Offsets not supplied
+            0xFF, 0xFF, 0xFF, 0xFF
+          }
+        })
+
+        Return (PLDP)
+      }
+    }//end of HS02
+    // high speed port 3
+    Device(HS03)
+    {
+      Name(_ADR, 0x03)
+
+      Method(_UPC,0,Serialized)
+      {
+        Name(UPCP, Package()
+        {
+          0xFF,                     //  connectable
+          0xFF,
+          0x00,
+          0x00
+        })
+
+        Return(UPCP)
+      }
+
+      Method(_RMV, 0)                                    // for XHCICV debug purpose
+      {
+        Return(0x0)
+      }
+
+      Method(_PLD,0,Serialized)
+      {
+        Name(PLDP, Package()
+        {
+          Buffer(0x14)
+          {
+            //31:0   - Bit[6:0]=2 revision is 0x2, Bit[7]=1 Ignore Color Bit[31:8]=0 RGB color is ignored
+            0x82, 0x00, 0x00, 0x00,
+            //63:32 - Bit[47:32]=0 width: 0x0000  Bit[63:48]=0 Height:0x0000
+            0x00, 0x00, 0x00, 0x00,
+            //95:64 - bit[66:64]=b'000 not Visible/no docking/no lid bit[69:67]=6 (b'110) unknown(Vertical Position and  Horizontal Position will be ignored)
+            //           bit[71:70]=b'00 Vertical Position ignore bit[73:72]=b'00 Horizontal Position ignore
+            //           bit[77:74]=2 Square bit[78]=0 bit[86:79]=0 bit[94:87]='0 no group info' bit[95]=0 not a bay
+            0x30, 0x08, 0x00, 0x00,
+            //127:96 -bit[96]=0 not Ejectable bit[97]=0 OSPM Ejection not required Bit[105:98]=0 no Cabinet Number
+            //            bit[113:106]=0 no Card cage Number bit[114]=0 no reference shape Bit[118:115]=0 no rotation Bit[123:119]=0 no order
+            0x00, 0x00, 0x00, 0x00,
+            //159:128  Vert. and Horiz. Offsets not supplied
+            0xFF, 0xFF, 0xFF, 0xFF
+          }
+        })
+        Return (PLDP)
+      }
+    }
+
+    Device(HS04)
+    {
+      Name(_ADR, 0x04)
+
+      Method(_UPC,0,Serialized)
+      {
+        Name(UPCP, Package()
+        {
+          0xFF,                     //connectable
+          0xFF,                     //Proprietary connector (FPC connector)
+          0x00,
+          0x00
+        })
+
+        Return(UPCP)
+      }
+      Method(_PLD,0,Serialized)
+      {
+        Name(PLDP, Package()
+        {
+          Buffer(0x14)
+          {
+            //31:0   - Bit[6:0]=2 revision is 0x2, Bit[7]=1 Ignore Color Bit[31:8]=0 RGB color is ignored
+            0x82, 0x00, 0x00, 0x00,
+            //63:32 - Bit[47:32]=0 width: 0x0000  Bit[63:48]=0 Height:0x0000
+            0x00, 0x00, 0x00, 0x00,
+            //95:64 - bit[66:64]=b'000 not Visible/no docking/no lid bit[69:67]=6 (b'110) unknown(Vertical Position and  Horizontal Position will be ignored)
+            //           bit[71:70]=b'00 Vertical Position ignore bit[73:72]=b'00 Horizontal Position ignore
+            //           bit[77:74]=2 Square bit[78]=0 bit[86:79]=0 bit[94:87]='0 no group info' bit[95]=0 not a bay
+            0x30, 0x08, 0x00, 0x00,
+            //127:96 -bit[96]=0 not Ejectable bit[97]=0 OSPM Ejection not required Bit[105:98]=0 no Cabinet Number
+            //            bit[113:106]=0 no Card cage Number bit[114]=0 no reference shape Bit[118:115]=0 no rotation Bit[123:119]=0 no order
+            0x00, 0x00, 0x00, 0x00,
+            //159:128  Vert. and Horiz. Offsets not supplied
+            0xFF, 0xFF, 0xFF, 0xFF
+          }
+        })
+
+        Return (PLDP)
+      }
+    }
+
+
+    Device(HSC1)                                           // USB2 HSIC 01
+    {
+      Name(_ADR, 0x05)
+
+      Method(_UPC,0,Serialized)
+      {
+        Name(UPCP, Package()
+        {
+          0xFF,                     //connectable
+          0xFF,                     //Proprietary connector (FPC connector)
+          0x00,
+          0x00
+        })
+
+        Return(UPCP)
+      }
+      Method(_PLD,0,Serialized)
+      {
+        Name(PLDP, Package()
+        {
+          Buffer(0x14)
+          {
+            //31:0   - Bit[6:0]=2 revision is 0x2, Bit[7]=1 Ignore Color Bit[31:8]=0 RGB color is ignored
+            0x82, 0x00, 0x00, 0x00,
+            //63:32 - Bit[47:32]=0 width: 0x0000  Bit[63:48]=0 Height:0x0000
+            0x00, 0x00, 0x00, 0x00,
+            //95:64 - bit[66:64]=b'000 not Visible/no docking/no lid bit[69:67]=6 (b'110) unknown(Vertical Position and  Horizontal Position will be ignored)
+            //           bit[71:70]=b'00 Vertical Position ignore bit[73:72]=b'00 Horizontal Position ignore
+            //           bit[77:74]=2 Square bit[78]=0 bit[86:79]=0 bit[94:87]='0 no group info' bit[95]=0 not a bay
+            0x30, 0x08, 0x00, 0x00,
+            //127:96 -bit[96]=0 not Ejectable bit[97]=0 OSPM Ejection not required Bit[105:98]=0 no Cabinet Number
+            //            bit[113:106]=0 no Card cage Number bit[114]=0 no reference shape Bit[118:115]=0 no rotation Bit[123:119]=0 no order
+            0x00, 0x00, 0x00, 0x00,
+            //159:128  Vert. and Horiz. Offsets not supplied
+            0xFF, 0xFF, 0xFF, 0xFF
+          }
+        })
+        Return (PLDP)
+      }
+    }
+
+    Device(HSC2)                                           // USB2 HSIC 02
+    {
+      Name(_ADR, 0x06)
+
+      Method(_UPC,0,Serialized)
+      {
+        Name(UPCP, Package()
+        {
+          0xFF,                     //connectable
+          0xFF,                     //Proprietary connector (FPC connector)
+          0x00,
+          0x00
+        })
+
+        Return(UPCP)
+      }
+      Method(_PLD,0,Serialized)
+      {
+        Name(PLDP, Package()
+        {
+          Buffer(0x14)
+          {
+            //31:0   - Bit[6:0]=2 revision is 0x2, Bit[7]=1 Ignore Color Bit[31:8]=0 RGB color is ignored
+            0x82, 0x00, 0x00, 0x00,
+            //63:32 - Bit[47:32]=0 width: 0x0000  Bit[63:48]=0 Height:0x0000
+            0x00, 0x00, 0x00, 0x00,
+            //95:64 - bit[66:64]=b'000 not Visible/no docking/no lid bit[69:67]=6 (b'110) unknown(Vertical Position and  Horizontal Position will be ignored)
+            //           bit[71:70]=b'00 Vertical Position ignore bit[73:72]=b'00 Horizontal Position ignore
+            //           bit[77:74]=2 Square bit[78]=0 bit[86:79]=0 bit[94:87]='0 no group info' bit[95]=0 not a bay
+            0x30, 0x08, 0x00, 0x00,
+            //127:96 -bit[96]=0 not Ejectable bit[97]=0 OSPM Ejection not required Bit[105:98]=0 no Cabinet Number
+            //            bit[113:106]=0 no Card cage Number bit[114]=0 no reference shape Bit[118:115]=0 no rotation Bit[123:119]=0 no order
+            0x00, 0x00, 0x00, 0x00,
+            //159:128  Vert. and Horiz. Offsets not supplied
+            0xFF, 0xFF, 0xFF, 0xFF
+          }
+        })
+        Return (PLDP)
+      }
+    }
+  }  //end of root hub
+
+} // end of XHC1
+
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PciTree.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PciTree.asl
new file mode 100644
index 0000000000..a64dbafc86
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PciTree.asl
@@ -0,0 +1,377 @@
+/**************************************************************************;
+;*                                                                        *;
+;*                                                                        *;
+;*    Intel Corporation - ACPI Reference Code for the Sandy Bridge        *;
+;*    Family of Customer Reference Boards.                                *;
+;*                                                                        *;
+;*                                                                        *;
+;*    Copyright (c) 2012  - 2015, Intel Corporation. All rights reserved    *;
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;*                                                                        *;
+;*                                                                        *;
+;**************************************************************************/
+
+Scope(\_SB)
+{
+//RTC
+  Device(RTC)    // RTC
+  {
+    Name(_HID,EISAID("PNP0B00"))
+
+    Name(_CRS,ResourceTemplate()
+    {
+      IO(Decode16,0x70,0x70,0x01,0x08)
+    })
+
+    Method(_STA,0,Serialized) {
+
+      //
+      // Report RTC Battery is Prensent or Not Present.
+      //
+      If (LEqual(BATT, 1)) {
+        Return (0xF)
+      }
+      Return (0x0)
+    }
+  }
+//RTC
+
+  Device(HPET)   // High Performance Event Timer
+  {
+    Name (_HID, EisaId ("PNP0103"))
+    Name (_UID, 0x00)
+    Method (_STA, 0, NotSerialized)
+    {
+      Return (0x0F)
+    }
+
+    Method (_CRS, 0, Serialized)
+    {
+      Name (RBUF, ResourceTemplate ()
+      {
+        Memory32Fixed (ReadWrite,
+                       0xFED00000,         // Address Base
+                       0x00000400,         // Address Length
+                      )
+        Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, )
+        {
+          0x00000008,   //0xB HPET-2
+        }
+      })
+      Return (RBUF)
+    }
+  }
+//HPET
+
+  Name(PR00, Package()
+  {
+// SD Host #0 - eMMC
+    Package() {0x0010FFFF, 0, LNKA, 0 },
+// SD Host #1 - SDIO
+    Package() {0x0011FFFF, 0, LNKB, 0 },
+// SD Host #2 - SD Card
+    Package() {0x0012FFFF, 0, LNKC, 0 },
+// SATA Controller
+    Package() {0x0013FFFF, 0, LNKD, 0 },
+// xHCI Host
+    Package() {0x0014FFFF, 0, LNKE, 0 },
+// Low Power Audio Engine
+    Package() {0x0015FFFF, 0, LNKF, 0 },
+// USB OTG
+    Package() {0x0016FFFF, 0, LNKG, 0 },
+// MIPI-HSI/eMMC4.5
+    Package() {0x0017FFFF, 0, LNKH, 0 },
+// LPSS2 DMA
+// LPSS2 I2C #4
+    Package() {0x0018FFFF, 0, LNKB, 0 },
+// LPSS2 I2C #1
+// LPSS2 I2C #5
+    Package() {0x0018FFFF, 2, LNKD, 0 },
+// LPSS2 I2C #2
+// LPSS2 I2C #6
+    Package() {0x0018FFFF, 3, LNKC, 0 },
+// LPSS2 I2C #3
+// LPSS2 I2C #7
+    Package() {0x0018FFFF, 1, LNKA, 0 },
+// SeC
+    Package() {0x001AFFFF, 0, LNKF, 0 },
+//
+// High Definition Audio Controller
+    Package() {0x001BFFFF, 0, LNKG, 0 },
+//
+// EHCI Controller
+    Package() {0x001DFFFF, 0, LNKH, 0 },
+// LPSS DMA
+    Package() {0x001EFFFF, 0, LNKD, 0 },
+// LPSS I2C #0
+    Package() {0x001EFFFF, 3, LNKA, 0 },
+// LPSS I2C #1
+    Package() {0x001EFFFF, 1, LNKB, 0 },
+// LPSS PCM
+    Package() {0x001EFFFF, 2, LNKC, 0 },
+// LPSS I2S
+// LPSS HS-UART #0
+// LPSS HS-UART #1
+// LPSS SPI
+// LPC Bridge
+//
+// SMBus Controller
+    Package() {0x001FFFFF, 1, LNKC, 0 },
+//
+// PCIE Root Port #1
+    Package() {0x001CFFFF, 0, LNKA, 0 },
+// PCIE Root Port #2
+    Package() {0x001CFFFF, 1, LNKB, 0 },
+// PCIE Root Port #3
+    Package() {0x001CFFFF, 2, LNKC, 0 },
+// PCIE Root Port #4
+    Package() {0x001CFFFF, 3, LNKD, 0 },
+
+// Host Bridge
+// Mobile IGFX
+    Package() {0x0002FFFF, 0, LNKA, 0 },
+  })
+
+  Name(AR00, Package()
+  {
+// SD Host #0 - eMMC
+    Package() {0x0010FFFF, 0, 0, 16 },
+// SD Host #1 - SDIO
+    Package() {0x0011FFFF, 0, 0, 17 },
+// SD Host #2 - SD Card
+    Package() {0x0012FFFF, 0, 0, 18 },
+// SATA Controller
+    Package() {0x0013FFFF, 0, 0, 19 },
+// xHCI Host
+    Package() {0x0014FFFF, 0, 0, 20 },
+// Low Power Audio Engine
+    Package() {0x0015FFFF, 0, 0, 21 },
+// USB OTG
+    Package() {0x0016FFFF, 0, 0, 22 },
+//
+// MIPI-HSI
+    Package() {0x0017FFFF, 0, 0, 23 },
+//
+// LPSS2 DMA
+// LPSS2 I2C #4
+    Package() {0x0018FFFF, 0, 0, 17 },
+// LPSS2 I2C #1
+// LPSS2 I2C #5
+    Package() {0x0018FFFF, 2, 0, 19 },
+// LPSS2 I2C #2
+// LPSS2 I2C #6
+    Package() {0x0018FFFF, 3, 0, 18 },
+// LPSS2 I2C #3
+// LPSS2 I2C #7
+    Package() {0x0018FFFF, 1, 0, 16 },
+
+// SeC
+    Package() {0x001AFFFF, 0, 0, 21 },
+//
+// High Definition Audio Controller
+    Package() {0x001BFFFF, 0, 0, 22 },
+//
+// EHCI Controller
+    Package() {0x001DFFFF, 0, 0, 23 },
+// LPSS DMA
+    Package() {0x001EFFFF, 0, 0, 19 },
+// LPSS I2C #0
+    Package() {0x001EFFFF, 3, 0, 16 },
+// LPSS I2C #1
+    Package() {0x001EFFFF, 1, 0, 17 },
+// LPSS PCM
+    Package() {0x001EFFFF, 2, 0, 18 },
+// LPSS I2S
+// LPSS HS-UART #0
+// LPSS HS-UART #1
+// LPSS SPI
+// LPC Bridge
+//
+// SMBus Controller
+    Package() {0x001FFFFF, 1, 0, 18 },
+//
+// PCIE Root Port #1
+    Package() {0x001CFFFF, 0, 0, 16 },
+// PCIE Root Port #2
+    Package() {0x001CFFFF, 1, 0, 17 },
+// PCIE Root Port #3
+    Package() {0x001CFFFF, 2, 0, 18 },
+// PCIE Root Port #4
+    Package() {0x001CFFFF, 3, 0, 19 },
+// Host Bridge
+// Mobile IGFX
+    Package() {0x0002FFFF, 0, 0, 16 },
+  })
+
+  Name(PR04, Package()
+  {
+// PCIE Port #1 Slot
+    Package() {0x0000FFFF, 0, LNKA, 0 },
+    Package() {0x0000FFFF, 1, LNKB, 0 },
+    Package() {0x0000FFFF, 2, LNKC, 0 },
+    Package() {0x0000FFFF, 3, LNKD, 0 },
+  })
+
+  Name(AR04, Package()
+  {
+// PCIE Port #1 Slot
+    Package() {0x0000FFFF, 0, 0, 16 },
+    Package() {0x0000FFFF, 1, 0, 17 },
+    Package() {0x0000FFFF, 2, 0, 18 },
+    Package() {0x0000FFFF, 3, 0, 19 },
+  })
+
+  Name(PR05, Package()
+  {
+// PCIE Port #2 Slot
+    Package() {0x0000FFFF, 0, LNKB, 0 },
+    Package() {0x0000FFFF, 1, LNKC, 0 },
+    Package() {0x0000FFFF, 2, LNKD, 0 },
+    Package() {0x0000FFFF, 3, LNKA, 0 },
+  })
+
+  Name(AR05, Package()
+  {
+// PCIE Port #2 Slot
+    Package() {0x0000FFFF, 0, 0, 17 },
+    Package() {0x0000FFFF, 1, 0, 18 },
+    Package() {0x0000FFFF, 2, 0, 19 },
+    Package() {0x0000FFFF, 3, 0, 16 },
+  })
+
+  Name(PR06, Package()
+  {
+// PCIE Port #3 Slot
+    Package() {0x0000FFFF, 0, LNKC, 0 },
+    Package() {0x0000FFFF, 1, LNKD, 0 },
+    Package() {0x0000FFFF, 2, LNKA, 0 },
+    Package() {0x0000FFFF, 3, LNKB, 0 },
+  })
+
+  Name(AR06, Package()
+  {
+// PCIE Port #3 Slot
+    Package() {0x0000FFFF, 0, 0, 18 },
+    Package() {0x0000FFFF, 1, 0, 19 },
+    Package() {0x0000FFFF, 2, 0, 16 },
+    Package() {0x0000FFFF, 3, 0, 17 },
+  })
+
+  Name(PR07, Package()
+  {
+// PCIE Port #4 Slot
+    Package() {0x0000FFFF, 0, LNKD, 0 },
+    Package() {0x0000FFFF, 1, LNKA, 0 },
+    Package() {0x0000FFFF, 2, LNKB, 0 },
+    Package() {0x0000FFFF, 3, LNKC, 0 },
+  })
+
+  Name(AR07, Package()
+  {
+// PCIE Port #4 Slot
+    Package() {0x0000FFFF, 0, 0, 19 },
+    Package() {0x0000FFFF, 1, 0, 16 },
+    Package() {0x0000FFFF, 2, 0, 17 },
+    Package() {0x0000FFFF, 3, 0, 18 },
+  })
+
+  Name(PR01, Package()
+  {
+// PCI slot 1
+    Package() {0x0000FFFF, 0, LNKF, 0 },
+    Package() {0x0000FFFF, 1, LNKG, 0 },
+    Package() {0x0000FFFF, 2, LNKH, 0 },
+    Package() {0x0000FFFF, 3, LNKE, 0 },
+// PCI slot 2
+    Package() {0x0001FFFF, 0, LNKG, 0 },
+    Package() {0x0001FFFF, 1, LNKF, 0 },
+    Package() {0x0001FFFF, 2, LNKE, 0 },
+    Package() {0x0001FFFF, 3, LNKH, 0 },
+// PCI slot 3
+    Package() {0x0002FFFF, 0, LNKC, 0 },
+    Package() {0x0002FFFF, 1, LNKD, 0 },
+    Package() {0x0002FFFF, 2, LNKB, 0 },
+    Package() {0x0002FFFF, 3, LNKA, 0 },
+// PCI slot 4
+    Package() {0x0003FFFF, 0, LNKD, 0 },
+    Package() {0x0003FFFF, 1, LNKC, 0 },
+    Package() {0x0003FFFF, 2, LNKF, 0 },
+    Package() {0x0003FFFF, 3, LNKG, 0 },
+  })
+
+  Name(AR01, Package()
+  {
+// PCI slot 1
+    Package() {0x0000FFFF, 0, 0, 21 },
+    Package() {0x0000FFFF, 1, 0, 22 },
+    Package() {0x0000FFFF, 2, 0, 23 },
+    Package() {0x0000FFFF, 3, 0, 20 },
+// PCI slot 2
+    Package() {0x0001FFFF, 0, 0, 22 },
+    Package() {0x0001FFFF, 1, 0, 21 },
+    Package() {0x0001FFFF, 2, 0, 20 },
+    Package() {0x0001FFFF, 3, 0, 23 },
+// PCI slot 3
+    Package() {0x0002FFFF, 0, 0, 18 },
+    Package() {0x0002FFFF, 1, 0, 19 },
+    Package() {0x0002FFFF, 2, 0, 17 },
+    Package() {0x0002FFFF, 3, 0, 16 },
+// PCI slot 4
+    Package() {0x0003FFFF, 0, 0, 19 },
+    Package() {0x0003FFFF, 1, 0, 18 },
+    Package() {0x0003FFFF, 2, 0, 21 },
+    Package() {0x0003FFFF, 3, 0, 22 },
+  })
+//---------------------------------------------------------------------------
+// List of IRQ resource buffers compatible with _PRS return format.
+//---------------------------------------------------------------------------
+// Naming legend:
+// RSxy, PRSy - name of the IRQ resource buffer to be returned by _PRS, "xy" - last two characters of IRQ Link name.
+// Note. PRSy name is generated if IRQ Link name starts from "LNK".
+// HLxy , LLxy - reference names, can be used to access bit mask of available IRQs. HL and LL stand for active High(Low) Level triggered Irq model.
+//---------------------------------------------------------------------------
+  Name(PRSA, ResourceTemplate()         // Link name: LNKA
+  {
+    IRQ(Level, ActiveLow, Shared, LLKA) {3,4,5,6,10,11,12,14,15}
+  })
+  Alias(PRSA,PRSB)      // Link name: LNKB
+  Alias(PRSA,PRSC)      // Link name: LNKC
+  Alias(PRSA,PRSD)      // Link name: LNKD
+  Alias(PRSA,PRSE)      // Link name: LNKE
+  Alias(PRSA,PRSF)      // Link name: LNKF
+  Alias(PRSA,PRSG)      // Link name: LNKG
+  Alias(PRSA,PRSH)      // Link name: LNKH
+//---------------------------------------------------------------------------
+// Begin PCI tree object scope
+//---------------------------------------------------------------------------
+
+  Device(PCI0)   // PCI Bridge "Host Bridge"
+  {
+    Name(_HID, EISAID("PNP0A08"))       // Indicates PCI Express/PCI-X Mode2 host hierarchy
+    Name(_CID, EISAID("PNP0A03"))       // To support legacy OS that doesn't understand the new HID
+    Name(_ADR, 0x00000000)
+    Method(^BN00, 0) { return(0x0000) } // Returns default Bus number for Peer PCI busses. Name can be overriden with control method placed directly under Device scope
+    Method(_BBN, 0) { return(BN00()) }  // Bus number, optional for the Root PCI Bus
+    Name(_UID, 0x0000)  // Unique Bus ID, optional
+    Name(_DEP, Package(0x1)
+    {
+      PEPD
+    })
+
+                            Method(_PRT,0)
+    {
+      If(PICM) {Return(AR00)} // APIC mode
+      Return (PR00) // PIC Mode
+    } // end _PRT
+
+    include("HOST_BUS.ASL")
+    Device(LPCB)   // LPC Bridge
+    {
+      Name(_ADR, 0x001F0000)
+      include("LpcB.asl")
+    } // end "LPC Bridge"
+
+  } // end PCI0 Bridge "Host Bridge"
+} // end _SB scope
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Platform.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Platform.asl
new file mode 100644
index 0000000000..784eb09f90
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Platform.asl
@@ -0,0 +1,703 @@
+/**************************************************************************;
+;*                                                                        *;
+;*                                                                        *;
+;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
+;*    Family of Customer Reference Boards.                                *;
+;*                                                                        *;
+;*                                                                        *;
+;*    Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved    *;
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;*                                                                        *;
+;*                                                                        *;
+;**************************************************************************/
+
+
+// Define the following External variables to prevent a WARNING when
+// using ASL.EXE and an ERROR when using IASL.EXE.
+
+External(PDC0)
+External(PDC1)
+External(PDC2)
+External(PDC3)
+External(CFGD)
+External(\_PR.CPU0._PPC, IntObj)
+External(\_SB.PCI0.LPCB.TPM.PTS, MethodObj)
+External(\_SB.STR3, DeviceObj)
+External(\_SB.I2C1.BATC, DeviceObj)
+External(\_SB.DPTF, DeviceObj)
+External(\_SB.TCHG, DeviceObj)
+External(\_SB.IAOE.PTSL)
+External(\_SB.IAOE.WKRS)
+
+//
+// Create a Global MUTEX.
+//
+Mutex(MUTX,0)
+
+
+
+// Port 80h Update:
+//              Update 8 bits of the 32-bit Port 80h.
+//
+//      Arguments:
+//              Arg0:   0 = Write Port 80h, Bits 7:0 Only.
+//                      1 = Write Port 80h, Bits 15:8 Only.
+//                      2 = Write Port 80h, Bits 23:16 Only.
+//                      3 = Write Port 80h, Bits 31:24 Only.
+//              Arg1:   8-bit Value to write
+//
+//      Return Value:
+//              None
+
+Method(P8XH,2,Serialized)
+{
+  If(LEqual(Arg0,0))            // Write Port 80h, Bits 7:0.
+  {
+    Store(Or(And(P80D,0xFFFFFF00),Arg1),P80D)
+  }
+
+  If(LEqual(Arg0,1))            // Write Port 80h, Bits 15:8.
+  {
+    Store(Or(And(P80D,0xFFFF00FF),ShiftLeft(Arg1,8)),P80D)
+  }
+
+  If(LEqual(Arg0,2))            // Write Port 80h, Bits 23:16.
+  {
+    Store(Or(And(P80D,0xFF00FFFF),ShiftLeft(Arg1,16)),P80D)
+  }
+
+  If(LEqual(Arg0,3))            // Write Port 80h, Bits 31:24.
+  {
+    Store(Or(And(P80D,0x00FFFFFF),ShiftLeft(Arg1,24)),P80D)
+  }
+
+}
+
+//
+// Define SW SMI port as an ACPI Operating Region to use for generate SW SMI.
+//
+OperationRegion (SPRT, SystemIO, 0xB2, 2)
+Field (SPRT, ByteAcc, Lock, Preserve)
+{
+  SSMP, 8
+}
+
+// The _PIC Control Method is optional for ACPI design.  It allows the
+// OS to inform the ASL code which interrupt controller is being used,
+// the 8259 or APIC.  The reference code in this document will address
+// PCI IRQ Routing and resource allocation for both cases.
+//
+// The values passed into _PIC are:
+//       0 = 8259
+//       1 = IOAPIC
+
+Method(\_PIC,1)
+{
+  Store(Arg0,GPIC)
+  Store(Arg0,PICM)
+}
+
+OperationRegion(SWC0, SystemIO, 0x610, 0x0F)
+Field(SWC0, ByteAcc, NoLock, Preserve)
+{
+  G1S, 8,      //SWC GPE1_STS
+  Offset(0x4),
+  G1E, 8,
+  Offset(0xA),
+  G1S2, 8,     //SWC GPE1_STS_2
+  G1S3, 8      //SWC GPE1_STS_3
+}
+
+OperationRegion (SWC1, SystemIO, \PMBS, 0x2C)
+Field(SWC1, DWordAcc, NoLock, Preserve)
+{
+  Offset(0x20),
+  G0S, 32,      //GPE0_STS
+  Offset(0x28),
+  G0EN, 32      //GPE0_EN
+}
+
+// Prepare to Sleep.  The hook is called when the OS is about to
+// enter a sleep state.  The argument passed is the numeric value of
+// the Sx state.
+
+Method(_PTS,1)
+{
+  Store(0,P80D)         // Zero out the entire Port 80h DWord.
+  P8XH(0,Arg0)          // Output Sleep State to Port 80h, Byte 0.
+
+  //clear the 3 SWC status bits
+  Store(Ones, G1S3)
+  Store(Ones, G1S2)
+  Store(1, G1S)
+
+  //set SWC GPE1_EN
+  Store(1,G1E)
+
+  //clear GPE0_STS
+  Store(Ones, G0S)
+
+
+  If(LEqual(Arg0,3))   // If S3 Suspend
+  {
+    //
+    // Disable Digital Thermal Sensor function when doing S3 suspend
+    //
+    If(CondRefOf(DTSE))
+    {
+      If(LGreaterEqual(DTSE, 0x01))
+      {
+        Store(30, DTSF) // DISABLE_UPDATE_DTS_EVERY_SMI
+        Store(0xD0, SSMP) // DTS SW SMI
+      }
+    }
+  }
+}
+
+// Wake.  This hook is called when the OS is about to wake from a
+// sleep state.  The argument passed is the numeric value of the
+// sleep state the system is waking from.
+Method(_WAK,1,Serialized)
+{
+  P8XH(1,0xAB) // Beginning of _WAK.
+
+  Notify(\_SB.PWRB,0x02)
+
+  If(NEXP)
+  {
+    // Reinitialize the Native PCI Express after resume
+    If(And(OSCC,0x02))
+    {
+      \_SB.PCI0.NHPG()
+    }
+
+    If(And(OSCC,0x04))   // PME control granted?
+    {
+      \_SB.PCI0.NPME()
+    }
+  }
+
+  If(LOr(LEqual(Arg0,3), LEqual(Arg0,4)))   // If S3 or S4 Resume
+  {
+
+
+    // If CMP is enabled, we may need to restore the C-State and/or
+    // P-State configuration, as it may have been saved before the
+    // configuration was finalized based on OS/driver support.
+    //
+    //   CFGD[24]  = Two or more cores enabled
+    //
+    If(And(CFGD,0x01000000))
+    {
+      //
+      // If CMP and the OSYS is WinXP SP1, we will enable C1-SMI if
+      // C-States are enabled.
+      //
+      //   CFGD[7:4] = C4, C3, C2, C1 Capable/Enabled
+      //
+      //
+    }
+
+    // Windows XP SP2 does not properly restore the P-State
+    // upon resume from S4 or S3 with degrade modes enabled.
+    // Use the existing _PPC methods to cycle the available
+    // P-States such that the processor ends up running at
+    // the proper P-State.
+    //
+    // Note:  For S4, another possible W/A is to always boot
+    // the system in LFM.
+    //
+    If(LEqual(OSYS,2002))
+    {
+      If(And(CFGD,0x01))
+      {
+        If(LGreater(\_PR.CPU0._PPC,0))
+        {
+          Subtract(\_PR.CPU0._PPC,1,\_PR.CPU0._PPC)
+          PNOT()
+          Add(\_PR.CPU0._PPC,1,\_PR.CPU0._PPC)
+          PNOT()
+        }
+        Else
+        {
+          Add(\_PR.CPU0._PPC,1,\_PR.CPU0._PPC)
+          PNOT()
+          Subtract(\_PR.CPU0._PPC,1,\_PR.CPU0._PPC)
+          PNOT()
+        }
+      }
+    }
+  }
+  Return(Package() {0,0})
+}
+
+// Power Notification:
+//              Perform all needed OS notifications during a
+//              Power Switch.
+//
+//      Arguments:
+//              None
+//
+//      Return Value:
+//              None
+
+Method(PNOT,0,Serialized)
+{
+  // If MP enabled and driver support is present, notify all
+  // processors.
+
+  If(MPEN)
+  {
+    If(And(PDC0,0x0008))
+    {
+      Notify(\_PR.CPU0,0x80)    // Eval CPU0 _PPC.
+
+      If(And(PDC0,0x0010))
+      {
+        Sleep(100)
+        Notify(\_PR.CPU0,0x81)  // Eval _CST.
+      }
+    }
+
+    If(And(PDC1,0x0008))
+    {
+      Notify(\_PR.CPU1,0x80)    // Eval CPU1 _PPC.
+
+      If(And(PDC1,0x0010))
+      {
+        Sleep(100)
+        Notify(\_PR.CPU1,0x81)  // Eval _CST.
+      }
+    }
+
+    If(And(PDC2,0x0008))
+    {
+      Notify(\_PR.CPU2,0x80)    // Eval CPU2 _PPC.
+
+      If(And(PDC2,0x0010))
+      {
+        Sleep(100)
+        Notify(\_PR.CPU2,0x81)  // Eval _CST.
+      }
+    }
+
+    If(And(PDC3,0x0008))
+    {
+      Notify(\_PR.CPU3,0x80)    // Eval CPU3 _PPC.
+
+      If(And(PDC3,0x0010))
+      {
+        Sleep(100)
+        Notify(\_PR.CPU3,0x81)  // Eval _CST.
+      }
+    }
+  }
+  Else
+  {
+    Notify(\_PR.CPU0,0x80)      // Eval _PPC.
+    Sleep(100)
+    Notify(\_PR.CPU0,0x81)      // Eval _CST
+  }
+}
+
+//
+// System Bus
+//
+Scope(\_SB)
+{
+  Name(CRTT, 110) // Processor critical temperature
+  Name(ACTT, 77)  // Active temperature limit for processor participant
+  Name(GCR0, 70)  // Critical temperature for Generic participant 0 in degree celsius
+  Name(GCR1, 70)  // Critical temperature for Generic participant 1 in degree celsius
+  Name(GCR2, 70)  // Critical temperature for Generic participant 2 in degree celsius
+  Name(GCR3, 70)  // Critical temperature for Generic participant 3 in degree celsius
+  Name(GCR4, 70)  // Critical temperature for Generic participant 4 in degree celsius
+  Name(GCR5, 70)  // Critical temperature for Generic participant 5 in degree celsius
+  Name(GCR6, 70)  // Critical temperature for Generic participant 6 in degree celsius
+  Name(PST0, 60)  // Passive temperature limit for Generic Participant 0 in degree celsius
+  Name(PST1, 60)  // Passive temperature limit for Generic Participant 1 in degree celsius
+  Name(PST2, 60)  // Passive temperature limit for Generic Participant 2 in degree celsius
+  Name(PST3, 60)  // Passive temperature limit for Generic Participant 3 in degree celsius
+  Name(PST4, 60)  // Passive temperature limit for Generic Participant 4 in degree celsius
+  Name(PST5, 60)  // Passive temperature limit for Generic Participant 5 in degree celsius
+  Name(PST6, 60)  // Passive temperature limit for Generic Participant 6 in degree celsius
+  Name(LPMV, 3)
+  Name(PDBG, 0)   // DPTF Super debug option
+  Name(PDPM, 1)   // DPTF DPPM enable
+  Name(PDBP, 1)   // DPTF DBPT enable (dynamic battery protection technology)
+  Name(DLPO, Package()
+  {
+    0x1, // Revision
+    0x1, // LPO Enable
+    0x1, // LPO StartPState
+    25,  // LPO StepSize
+    0x1, //
+    0x1, //
+  })
+  Name(BRQD, 0x00) // This is used to determine if DPTF display participant requested Brightness level change
+  // or it is from Graphics driver. Value of 1 is for DPTF else it is 0
+
+  Method(_INI,0)
+  {
+    // NVS has stale DTS data.  Get and update the values
+    // with current temperatures.   Note that this will also
+    // re-arm any AP Thermal Interrupts.
+    // Read temperature settings from global NVS
+    Store(DPCT, CRTT)
+    Store(Subtract(DPPT, 8), ACTT)                      // Active Trip point = Passive trip point - 8
+    Store(DGC0, GCR0)
+    Store(DGC0, GCR1)
+    Store(DGC1, GCR2)
+    Store(DGC1, GCR3)
+    Store(DGC1, GCR4)
+    Store(DGC2, GCR5)
+    Store(DGC2, GCR6)
+    Store(DGP0, PST0)
+    Store(DGP0, PST1)
+    Store(DGP1, PST2)
+    Store(DGP1, PST3)
+    Store(DGP1, PST4)
+    Store(DGP2, PST5)
+    Store(DGP2, PST6)
+    // Read Current low power mode setting from global NVS
+    Store(DLPM, LPMV)
+
+
+    // Update DPTF Super Debug option
+    Store(DDBG, PDBG)
+
+
+    // Update DPTF LPO Options
+    Store(LPOE, Index(DLPO,1))
+    Store(LPPS, Index(DLPO,2))
+    Store(LPST, Index(DLPO,3))
+    Store(LPPC, Index(DLPO,4))
+    Store(LPPF, Index(DLPO,5))
+    Store(DPME, PDPM)
+  }
+
+  // Define a (Control Method) Power Button.
+  Device(PWRB)
+  {
+    Name(_HID,EISAID("PNP0C0C"))
+
+    // GPI_SUS0 = GPE16 = Waketime SCI.  The PRW isn't working when
+    // placed in any of the logical locations ( PS2K, PS2M),
+    // so a Power Button Device was created specifically
+    // for the WAKETIME_SCI PRW.
+
+    Name(_PRW, Package() {16,4})
+  }
+
+  Device(SLPB)
+  {
+    Name(_HID, EISAID("PNP0C0E"))
+  } // END SLPB
+
+  Scope(PCI0)
+  {
+    Method(_INI,0)
+    {
+      // Determine the OS and store the value, where:
+      //
+      //   OSYS = 2009 = Windows 7 and Windows Server 2008 R2.
+      //   OSYS = 2012 = Windows 8 and Windows Server 2012.
+      //
+      // Assume Windows 7 at a minimum.
+
+      Store(2009,OSYS)
+
+      // Check for a specific OS which supports _OSI.
+
+      If(CondRefOf(\_OSI,Local0))
+      {
+        // Linux returns _OSI = TRUE for numerous Windows
+        // strings so that it is fully compatible with
+        // BIOSes available in the market today.  There are
+        // currently 2 known exceptions to this model:
+        //      1) Video Repost - Linux supports S3 without
+        //              requireing a Driver, meaning a Video
+        //              Repost will be required.
+        //      2) On-Screen Branding - a full CMT Logo
+        //              is limited to the WIN2K and WINXP
+        //              Operating Systems only.
+
+        // Use OSYS for Windows Compatibility.
+        If(\_OSI("Windows 2009"))   // Windows 7 or Windows Server 2008 R2
+        {
+          Store(2009,OSYS)
+        }
+        If(\_OSI("Windows 2012"))   // Windows 8 or Windows Server 2012
+        {
+          Store(2012,OSYS)
+        }
+        If(\_OSI("Windows 2013"))   //Windows Blue
+        {
+          Store(2013,OSYS)
+        }
+
+        //
+        // If CMP is enabled, enable SMM C-State
+        // coordination.  SMM C-State coordination
+        // will be disabled in _PDC if driver support
+        // for independent C-States deeper than C1
+        // is indicated.
+      }
+    }
+
+    Method(NHPG,0,Serialized)
+    {
+
+    }
+
+    Method(NPME,0,Serialized)
+    {
+
+    }
+  } // end Scope(PCI0)
+
+  Device (GPED)   //virtual GPIO device for ASL based AC/Battery/Expection notification
+  {
+    Name (_ADR, 0)
+    Name (_HID, "INT0002")
+    Name (_CID, "INT0002")
+    Name (_DDN, "Virtual GPIO controller" )
+    Name (_UID, 1)
+
+    Method (_CRS, 0x0, Serialized)
+    {
+      Name (RBUF, ResourceTemplate ()
+      {
+        Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, ) {0x9} // Was 9
+      })
+      Return (RBUF)
+    }
+
+    Method (_STA, 0x0, NotSerialized)
+    {
+      Return(0x0)
+    }
+
+    Method (_AEI, 0x0, Serialized)
+    {
+      Name(RBUF, ResourceTemplate()
+      {
+        GpioInt(Edge, ActiveHigh, ExclusiveAndWake, PullDown,,"\\_SB.GPED",) {2} //pin 2
+      })
+      Return(RBUF)
+    }
+
+    Method(_E02)   // _Exx method will be called when interrupt is raised
+    {
+      If (LEqual (PWBS, 1))
+      {
+        Store (1, PWBS)      //Clear PowerButton Status
+      }
+      If (LEqual (PMEB, 1))
+      {
+        Store (1, PMEB)      //Clear PME_B0_STS
+      }
+      If (LEqual (\_SB.PCI0.SATA.PMES, 1))
+      {
+        Store (1, \_SB.PCI0.SATA.PMES)
+        Notify (\_SB.PCI0.SATA, 0x02)
+      }
+      //
+      // eMMC 4.41
+      //
+      If (LAnd(LEqual (\_SB.PCI0.EM41.PMES, 1), LEqual(PCIM, 1)))
+      {
+        Store (1, \_SB.PCI0.EM41.PMES)
+        Notify (\_SB.PCI0.EM41, 0x02)
+      }
+
+      //
+      // eMMC 4.5
+      //
+      If (LAnd(LEqual (\_SB.PCI0.EM45.PMES, 1), LEqual(PCIM, 1)))
+      {
+        Store (1, \_SB.PCI0.EM45.PMES)
+        Notify (\_SB.PCI0.EM45, 0x02)
+      }
+
+      If (LEqual(HDAD, 0))
+      {
+        If (LEqual (\_SB.PCI0.HDEF.PMES, 1))
+        {
+          Store (1, \_SB.PCI0.HDEF.PMES)
+          Notify (\_SB.PCI0.HDEF, 0x02)
+        }
+      }
+
+      If (LEqual (\_SB.PCI0.EHC1.PMES, 1))
+      {
+        Store (1, \_SB.PCI0.EHC1.PMES)
+        Notify (\_SB.PCI0.EHC1, 0x02)
+      }
+      If (LEqual (\_SB.PCI0.XHC1.PMES, 1))
+      {
+        Store (1, \_SB.PCI0.XHC1.PMES)
+        Notify (\_SB.PCI0.XHC1, 0x02)
+      }
+      If (LEqual (\_SB.PCI0.SEC0.PMES, 1))
+      {
+        Or (\_SB.PCI0.SEC0.PMES, Zero, \_SB.PCI0.SEC0.PMES)
+        Notify (\_SB.PCI0.SEC0, 0x02)
+      }
+    }
+  } //  Device (GPED)
+
+  //--------------------
+  //  GPIO
+  //--------------------
+  Device (GPO0)
+  {
+    Name (_ADR, 0)
+    Name (_HID, "INT33FC")
+    Name (_CID, "INT33B2")
+    Name (_DDN, "ValleyView2 General Purpose Input/Output (GPIO) controller" )
+    Name (_UID, 1)
+    Method (_CRS, 0x0, Serialized)
+    {
+      Name (RBUF, ResourceTemplate ()
+      {
+        Memory32Fixed (ReadWrite, 0x0FED0C000, 0x00001000)
+        Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , , ) {49}
+
+      })
+      Return (RBUF)
+    }
+
+    Method (_STA, 0x0, NotSerialized)
+    {
+      //
+      // GPO driver will report present if any of below New IO bus exist
+      //
+      If (LOr(LEqual(L11D, 0), LEqual(L12D, 0))) // LPIO1 PWM #1 or #2 exist
+      { Return(0xF) }
+      If (LOr(LEqual(L13D, 0), LEqual(L14D, 0))) // LPIO1 HS-UART #1 or #2 exist
+      { Return(0xF) }
+      If (LOr(LEqual(L15D, 0), LEqual(SD1D, 0))) // LPIO1 SPI or SCC SDIO #1 exist
+      { Return(0xF) }
+      If (LOr(LEqual(SD2D, 0), LEqual(SD3D, 0))) // SCC SDIO #2 or #3 exist
+      { Return(0xF) }
+      If (LOr(LEqual(L21D, 0), LEqual(L22D, 0))) // LPIO2 I2C #1 or #2 exist
+      { Return(0xF) }
+      If (LOr(LEqual(L23D, 0), LEqual(L24D, 0))) // LPIO2 I2C #3 or #4 exist
+      { Return(0xF) }
+      If (LOr(LEqual(L25D, 0), LEqual(L26D, 0))) // LPIO2 I2C #5 or #6 exist
+      { Return(0xF) }
+      If (LEqual(L27D, 0))                       // LPIO2 I2C #7 exist
+      { Return(0xF) }
+
+      Return(0x0)
+    }
+
+    // Track status of GPIO OpRegion availability for this controller
+    Name(AVBL, 0)
+    Method(_REG,2)
+    {
+      If (Lequal(Arg0, 8))
+      {
+        Store(Arg1, ^AVBL)
+      }
+    }
+
+    OperationRegion(GPOP, SystemIo, \GPBS, 0x50)
+      Field(GPOP, ByteAcc, NoLock, Preserve) {
+      Offset(0x28), // cfio_ioreg_SC_GP_LVL_63_32_ - [GPIO_BASE_ADDRESS] + 28h
+          ,  21,
+      BTD3,  1,     //This field is not used. Pin not defined in schematics. Closest is GPIO_S5_35 - COMBO_BT_WAKEUP
+      Offset(0x48), // cfio_ioreg_SC_GP_LVL_95_64_ - [GPIO_BASE_ADDRESS] + 48h
+          ,  30,
+      SHD3,  1      //GPIO_S0_SC_95 - SENS_HUB_RST_N
+    }
+
+
+
+  }   //  Device (GPO0)
+
+  Device (GPO1)
+  {
+    Name (_ADR, 0)
+    Name (_HID, "INT33FC")
+    Name (_CID, "INT33B2")
+    Name (_DDN, "ValleyView2 GPNCORE controller" )
+    Name (_UID, 2)
+    Method (_CRS, 0x0, Serialized)
+    {
+      Name (RBUF, ResourceTemplate ()
+      {
+        Memory32Fixed (ReadWrite, 0x0FED0D000, 0x00001000)
+        Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , , ) {48}
+      })
+      Return (RBUF)
+    }
+
+    Method (_STA, 0x0, NotSerialized)
+    {
+      Return(\_SB.GPO0._STA)
+    }
+  }   //  Device (GPO1)
+
+  Device (GPO2)
+  {
+    Name (_ADR, 0)
+    Name (_HID, "INT33FC")
+    Name (_CID, "INT33B2")
+    Name (_DDN, "ValleyView2 GPSUS controller" )
+    Name (_UID, 3)
+    Method (_CRS, 0x0, Serialized)
+    {
+      Name (RBUF, ResourceTemplate ()
+      {
+        Memory32Fixed (ReadWrite, 0x0FED0E000, 0x00001000)
+        Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , , ) {50}
+      })
+      Return (RBUF)
+    }
+
+    Method (_STA, 0x0, NotSerialized)
+    {
+      Return(^^GPO0._STA)
+    }
+
+    // Track status of GPIO OpRegion availability for this controller
+    Name(AVBL, 0)
+    Method(_REG,2)
+    {
+      If (Lequal(Arg0, 8))
+      {
+        Store(Arg1, ^AVBL)
+      }
+    }
+    //Manipulate GPIO line using GPIO operation regions.
+    Name (GMOD, ResourceTemplate ()     //One method of creating a Connection for OpRegion accesses in Field definitions
+    {
+      //is creating a named object that refers to the connection attributes
+      GpioIo (Exclusive, PullDefault, 0, 0, IoRestrictionOutputOnly, "\\_SB.GPO2") {21}  //sus 21+128 BT+WLAN_ENABLE
+    })
+
+  OperationRegion(GPOP, SystemIo, \GPBS, 0x100)
+  Field(GPOP, ByteAcc, NoLock, Preserve) {
+      Offset(0x88),  // cfio_ioreg_SUS_GP_LVL_31_0_ - [GPIO_BASE_ADDRESS] + 88h
+          ,  20,
+      WFD3,  1
+    }
+
+
+  }   //  Device (GPO2)
+  include ("PchScc.asl")
+  include ("PchLpss.asl")
+
+         Scope(I2C7)
+  {
+
+  } //End Scope(I2C7)
+
+} // end Scope(\_SB)
+
+Name(PICM, 0)   // Global Name, returns current Interrupt controller mode; updated from _PIC control method
+
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RTD3.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RTD3.asl
new file mode 100644
index 0000000000..2bf62e92a1
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RTD3.asl
@@ -0,0 +1,197 @@
+/**************************************************************************;
+;*                                                                        *;
+;*                                                                        *;
+;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
+;*    Family of Customer Reference Boards.                                *;
+;*                                                                        *;
+;*                                                                        *;
+;*    Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved    *;
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;*                                                                        *;
+;*                                                                        *;
+;**************************************************************************/
+DefinitionBlock (
+  "Rtd3.aml",
+  "SSDT",
+  1,
+  "AcpiRef",
+  "Msg_Rtd3",
+  0x1000
+)
+{
+  External(RTD3)             //flag if RTD3 is enabled
+
+  If(LEqual(RTD3,1))
+  {
+    Scope (\_SB)
+    {
+      Name(OSCI, 0)  // \_SB._OSC DWORD2 input
+      Name(OSCO, 0)  // \_SB._OSC DWORD2 output
+
+      //Arg0 -- A buffer containing UUID
+      //Arg1 -- An Interger containing a Revision ID of the buffer format
+      //Arg2 -- An interger containing a count of entries in Arg3
+      //Arg3 -- A buffer containing a list of DWORD capacities
+      Method(_OSC, 4, NotSerialized)
+      {
+        // Check for proper UUID
+        If(LEqual(Arg0, ToUUID("0811B06E-4A27-44F9-8D60-3CBBC22E7B48")))
+        {
+          CreateDWordField(Arg3,0,CDW1)     //bit1,2 is always clear
+          CreateDWordField(Arg3,4,CDW2)     //Table 6-147 from ACPI spec
+
+          Store(CDW2, OSCI)                 // Save DWord2
+          Or(OSCI, 0x4, OSCO)               // Only allow _PR3 support
+
+          If(LNotEqual(Arg1,One))
+          {
+            Or(CDW1,0x08,CDW1)            // Unknown revision
+          }
+
+          If(LNotEqual(OSCI, OSCO))
+          {
+            Or(CDW1,0x10,CDW1)            // Capabilities bits were masked
+          }
+
+          Store(OSCO, CDW2)                 // Replace DWord2
+          Return(Arg3)
+        } Else
+        {
+          Or(CDW1,4,CDW1)                   // Unrecognized UUID
+          Return(Arg3)
+        }
+      }// End _OSC
+    }
+  }//end of RTD3 condition
+
+
+  //USB RTD3 code
+  If(LEqual(RTD3,1))
+  {
+    Scope(\_SB.PCI0.EHC1.HUBN.PR01.PR13)
+    {
+      Name(_PR0, Package() {\PR34})
+      Name(_PR3, Package() {\PR34})
+
+      Method(_S0W, 0)
+      {
+        If(And(\_SB.OSCO, 0x04))              // PMEs can be genrated from D3cold
+        {
+          Return(4)                         // OS comprehends D3cold, as described via \_SB._OSC
+        } Else
+        {
+          Return(3)
+        }
+      } // End _S0W
+    }
+
+    Scope(\_SB.PCI0.EHC1.HUBN.PR01.PR14)
+    {
+      Name(_PR0, Package() {\PR34})
+      Name(_PR3, Package() {\PR34})
+
+      Method(_S0W, 0)
+      {
+        If(And(\_SB.OSCO, 0x04))
+        {
+          Return(4)
+        } Else
+        {
+          Return(3)
+        }
+      } // End _S0W
+    }
+
+
+    Scope(\_SB.PCI0.EHC1.HUBN.PR01.PR15)
+    {
+      Name(_PR0, Package() {\PR56})
+      Name(_PR3, Package() {\PR56})
+
+      Method(_S0W, 0)
+      {
+        If(And(\_SB.OSCO, 0x04))
+        {
+          Return(4)
+        } Else
+        {
+          Return(3)
+        }
+      } // End _S0W
+    }
+
+    Scope(\_SB.PCI0.EHC1.HUBN.PR01.PR16)
+    {
+      Name(_PR0, Package() {\PR56})
+      Name(_PR3, Package() {\PR56})
+
+      Method(_S0W, 0)
+      {
+        If(And(\_SB.OSCO, 0x04))
+        {
+          Return(4)
+        } Else
+        {
+          Return(3)
+        }
+      } // End _S0W
+    }
+
+    Scope(\_SB.PCI0.XHC1)                              // XHCI host only controller
+    {
+
+      Method(_PS0,0,Serialized)                      // set device into D0 state
+      {
+      }
+
+      Method(_PS3,0,Serialized)                      // place device into D3H state
+      {
+        //write to PMCSR
+      }
+
+      Method(_DSW, 3,Serialized)                     // enable or disable the device’s ability to wake a sleeping system.
+      {
+      }
+    }
+
+    Scope(\_SB.PCI0.XHC1.RHUB.HS01)
+    {
+
+    }
+
+    Scope(\_SB.PCI0.XHC1.RHUB.SSP1)
+    {
+
+    }
+
+    Scope(\_SB.PCI0.XHC2)                              // OTG
+    {
+
+      Method(_PS0,0,Serialized)                      // set device into D0 state
+      {
+      }
+
+      Method(_PS3,0,Serialized)                      // place device into D3H state
+      {
+        //write to PMCSR
+      }
+
+      Method(_DSW, 3,Serialized)                      // enable or disable the device’s ability to wake a sleeping system.
+      {
+      }
+    }
+
+    Scope(\_SB.PCI0.XHC2.RHUB.HS01)
+    {
+
+    }
+
+    Scope(\_SB.PCI0.XHC2.RHUB.SSP1)
+    {
+
+    }
+  } //If(LEqual(RTD3,1)) USB
+
+}//end of SSDT
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RhProxy.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RhProxy.asl
new file mode 100644
index 0000000000..d7e785f532
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RhProxy.asl
@@ -0,0 +1,160 @@
+/** @file
+  SSDT for RhProxy Driver.
+
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+DefinitionBlock ("RHPX.aml", "SSDT", 1, "MSFT", "RHPROXY", 1)
+{
+    Scope (\_SB)
+    {
+        //
+        // Test peripheral device node for MinnowBoardMax
+        //
+        Device(RHPX)
+        {
+            Name(_HID, "MSFT8000")
+            Name(_CID, "MSFT8000")
+            Name(_UID, 1)
+
+            Name(_CRS, ResourceTemplate() 
+            {  
+                // Index 0 
+                SPISerialBus(            // Pin 5, 7, 9 , 11 of JP1 for SIO_SPI
+                    1,                     // Device selection
+                    PolarityLow,           // Device selection polarity
+                    FourWireMode,          // wiremode
+                    8,                     // databit len
+                    ControllerInitiated,   // slave mode
+                    8000000,               // Connection speed
+                    ClockPolarityLow,      // Clock polarity
+                    ClockPhaseSecond,      // clock phase
+                    "\\_SB.SPI1",          // ResourceSource: SPI bus controller name
+                    0,                     // ResourceSourceIndex
+                    ResourceConsumer,      // Resource usage
+                    JSPI,                  // DescriptorName: creates name for offset of resource descriptor
+                    )                      // Vendor Data  
+    
+                // Index 1     
+                I2CSerialBus(            // Pin 13, 15 of JP1, for SIO_I2C5 (signal)
+                    0xFF,                  // SlaveAddress: bus address (TBD)
+                    ,                      // SlaveMode: default to ControllerInitiated
+                    400000,                // ConnectionSpeed: in Hz
+                    ,                      // Addressing Mode: default to 7 bit
+                    "\\_SB.I2C6",          // ResourceSource: I2C bus controller name (For MinnowBoard Max, hardware I2C5(0-based) is reported as ACPI I2C6(1-based))
+                    ,
+                    ,
+                    JI2C,                  // Descriptor Name: creates name for offset of resource descriptor
+                    )                      // VendorData
+    
+                // Index 2
+                UARTSerialBus(           // Pin 17, 19 of JP1, for SIO_UART2
+                    115200,                // InitialBaudRate: in bits ber second
+                    ,                      // BitsPerByte: default to 8 bits
+                    ,                      // StopBits: Defaults to one bit
+                    0xfc,                  // LinesInUse: 8 1-bit flags to declare line enabled
+                    ,                      // IsBigEndian: default to LittleEndian
+                    ,                      // Parity: Defaults to no parity
+                    ,                      // FlowControl: Defaults to no flow control
+                    32,                    // ReceiveBufferSize
+                    32,                    // TransmitBufferSize
+                    "\\_SB.URT2",          // ResourceSource: UART bus controller name
+                    ,
+                    ,
+                    UAR2,                  // DescriptorName: creates name for offset of resource descriptor
+                    )                      
+    
+                // Index 3
+                GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO2",) {0}  // Pin 21 of JP1 (GPIO_S5[00])
+                // Index 4
+                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO2",) {0} 
+    
+                // Index 5
+                GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO2",) {1}  // Pin 23 of JP1 (GPIO_S5[01])
+                // Index 6
+                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO2",) {1}
+    
+                // Index 7
+                GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO2",) {2}  // Pin 25 of JP1 (GPIO_S5[02])
+                // Index 8
+                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO2",) {2} 
+    
+                // Index 9
+                UARTSerialBus(           // Pin 6, 8, 10, 12 of JP1, for SIO_UART1
+                    115200,                // InitialBaudRate: in bits ber second
+                    ,                      // BitsPerByte: default to 8 bits
+                    ,                      // StopBits: Defaults to one bit
+                    0xfc,                  // LinesInUse: 8 1-bit flags to declare line enabled
+                    ,                      // IsBigEndian: default to LittleEndian
+                    ,                      // Parity: Defaults to no parity
+                    FlowControlHardware,   // FlowControl: Defaults to no flow control
+                    32,                    // ReceiveBufferSize
+                    32,                    // TransmitBufferSize
+                    "\\_SB.URT1",          // ResourceSource: UART bus controller name
+                    ,
+                    ,
+                    UAR1,              // DescriptorName: creates name for offset of resource descriptor
+                    )  
+    
+                // Index 10
+                GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {62}  // Pin 14 of JP1 (GPIO_SC[62])
+                // Index 11
+                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",) {62} 
+
+                // Index 12
+                GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {63}  // Pin 16 of JP1 (GPIO_SC[63])
+                // Index 13
+                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",) {63} 
+    
+                // Index 14
+                GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {65}  // Pin 18 of JP1 (GPIO_SC[65])
+                // Index 15
+                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",) {65} 
+    
+                // Index 16
+                GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {64}  // Pin 20 of JP1 (GPIO_SC[64])
+                // Index 17
+                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",) {64} 
+    
+                // Index 18
+                GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {94}  // Pin 22 of JP1 (GPIO_SC[94])
+                // Index 19
+                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",) {94} 
+    
+                // Index 20
+                GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {95}  // Pin 24 of JP1 (GPIO_SC[95])
+                // Index 21
+                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",) {95} 
+    
+                // Index 22
+                GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {54}  // Pin 26 of JP1 (GPIO_SC[54])
+                // Index 23
+                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",) {54}
+            })
+    
+            Name(_DSD, Package() 
+            {
+                ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+                Package() 
+                {
+                    // SPI Mapping
+                    Package(2) { "bus-SPI-SPI0", Package() { 0 }},
+
+                    // TODO: Intel will need to provide the right value for SPI0 properties
+                    Package(2) { "SPI0-MinClockInHz", 100000 },
+                    Package(2) { "SPI0-MaxClockInHz", 15000000 },
+                    // SupportedDataBitLengths takes a list of support data bit length
+                    // Example : Package(2) { "SPI0-SupportedDataBitLengths", Package() { 8, 7, 16 }},
+                    Package(2) { "SPI0-SupportedDataBitLengths", Package() { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 }},
+                    // I2C Mapping
+                    Package(2) { "bus-I2C-I2C5", Package() { 1 }},
+                    // UART Mapping
+                    Package(2) { "bus-UART-UART2", Package() { 2 }},
+                    Package(2) { "bus-UART-UART1", Package() { 9 }},
+                }
+            })
+        }
+    }
+}
\ No newline at end of file
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/THERMAL.ASL b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/THERMAL.ASL
new file mode 100644
index 0000000000..6d9e9f3d69
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/THERMAL.ASL
@@ -0,0 +1,137 @@
+/**************************************************************************;
+;*                                                                        *;
+;*                                                                        *;
+;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
+;*    Family of Customer Reference Boards.                                *;
+;*                                                                        *;
+;*                                                                        *;
+;*    Copyright (c)  1999  - 2017, Intel Corporation. All rights reserved   *;
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;*                                                                        *;
+;*                                                                        *;
+;**************************************************************************/
+
+
+// THERMAL.ASL represents a Thermal Zone to be used for testing on the
+// Customer Reference Boards.
+
+External(\_SB.DPTF.CTOK, MethodObj)
+
+Scope(\_TZ)
+{
+
+  // Thermal Zone 1 = DTS Thermal Zone.
+
+  ThermalZone(TZ01)
+  {
+    // Return the temperature at which the OS must perform a Critcal
+    // Shutdown.
+
+    Method(_CRT,0,Serialized)
+    {
+      Return(Add(2732,Multiply(CRTT,10)))
+    }
+
+    // Notifies ASL Code the current cooling mode.
+    //      0 - Active cooling
+    //      1 - Passive cooling
+
+    Method(_SCP,1,Serialized)
+    {
+      Store(Arg0,CTYP)
+    }
+
+    // _TMP (Temperature)
+    //
+    // Return the highest of the CPU temperatures to the OS.
+    //
+    // Arguments: (0)
+    //   None
+    // Return Value:
+    //   An Integer containing the current temperature of the thermal zone (in tenths of degrees Kelvin)
+    //
+    Method(_TMP,0,Serialized)
+    {
+      If(DTSE)
+      {
+        If(LGreater(DTS2, DTS1))
+        {
+          Store(DTS2,Local0)
+        } else
+        {
+          Store(DTS1,Local0)
+        }
+        If (LEqual(And(Local0, 0x80), 0)) {
+          Return(Add(2732,Multiply(Local0,10)))
+        } else {
+          Add(Subtract(255, Local0), 1, Local0)
+          Return(Subtract(2732,Multiply(Local0,10)))
+        }
+        //
+        // Else return a static value if both EC and DTS are unavailable.
+        //
+      } Else
+      {
+        Return(3000) // (3000-2732)/10 = 26.8 degree C
+      }
+    }
+
+    // Return the Processor(s) used for Passive Cooling.
+
+    Method(_PSL,0,Serialized)
+    {
+      If(LEqual(MPEN, 4))
+      {
+        //  CMP - Throttling controls all four logical CPUs.
+        Return(Package() {\_PR.CPU0,\_PR.CPU1,\_PR.CPU2,\_PR.CPU3})
+      }
+
+      If(MPEN)
+      {
+        //  CMP - Throttling controls both CPUs.
+
+        Return(Package() {\_PR.CPU0,\_PR.CPU1})
+      }
+
+      Return(Package() {\_PR.CPU0})
+    }
+
+    // Returns the temperature at which the OS initiates CPU throttling.
+
+    Method(_PSV,0,Serialized)
+    {
+      Return(Add(2732,Multiply(PSVT,10)))
+    }
+
+    // Returns TC1 value used in the passive cooling formula.
+
+    Method(_TC1,0,Serialized)
+    {
+      Return(TC1V)
+    }
+
+    // Returns TC2 value used in the passive cooling formula.
+
+    Method(_TC2,0,Serialized)
+    {
+      Return(TC2V)
+    }
+
+    // Returns the sampling period used in the passive cooling formula.
+
+    Method(_TSP,0,Serialized)
+    {
+      Return(TSPV)
+    }
+
+    // Returns Hot Temperature
+
+    Method(_HOT,0,Serialized)
+    {
+      Subtract(CRTT, 5, Local0)
+      Return(Add(2732,Multiply(Local0,10)))
+    }
+  }
+}
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/UsbSbd.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/UsbSbd.asl
new file mode 100644
index 0000000000..a4fb173862
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/UsbSbd.asl
@@ -0,0 +1,93 @@
+/************************************************************************************;
+;*                                                                                  *;
+;*                                                                                  *;
+;*    Intel Corporation - ACPI Reference Code for the Baytrail                      *;
+;*    Family of Customer Reference Boards.                                          *;
+;*                                                                                  *;
+;*    MPG-MSAE                                                                      *;
+;*                                                                                  *;
+;*    Copyright (c) 1999 - 2014, Intel Corporation.                                 *;
+;*                                                                                  *;
+;* ThSPDX-License-Identifier: BSD-2-Clause-Patent
+;*                                                                                  *;
+;*                                                                                  *;
+;*    This program has been developed by Intel Corporation.                         *;
+;*    Licensee has Intel's permission to incorporate this source code               *;
+;*    into their product, royalty free.  This source code may NOT be                *;
+;*    redistributed to anyone without Intel's written permission.                   *;
+;*                                                                                  *;
+;*    Intel specifically disclaims all warranties, express or                       *;
+;*    implied, and all liability, including consequential and other                 *;
+;*    indirect damages, for the use of this code, including liability               *;
+;*    for infringement of any proprietary rights, and including the                 *;
+;*    warranties of merchantability and fitness for a particular                    *;
+;*    purpose.  Intel does not assume any responsibility for any                    *;
+;*    errors which may appear in this code nor any responsibility to                *;
+;*    update it.                                                                    *;
+;*                                                                                  *;
+;*    Version:  See README.TXT                                                      *;
+;*                                                                                  *;
+;************************************************************************************/
+
+//
+// _DSM : Device Specific Method supporting USB Sideband Deferring function
+//
+// Arg0: UUID Unique function identifier
+// Arg1: Integer Revision Level
+// Arg2: Integer Function Index
+// Arg3: Package Parameters
+//
+Method (_DSM, 4, Serialized, 0, UnknownObj, {BuffObj, IntObj, IntObj, PkgObj})
+{
+
+  If (LEqual(Arg0, ToUUID ("A5FC708F-8775-4BA6-BD0C-BA90A1EC72F8")))
+  {
+    //
+    // Switch by function index
+    //
+    Switch (ToInteger(Arg2))
+    {
+      //
+      // Standard query - A bitmask of functions supported
+      // Supports function 0-2
+      //
+      Case (0)
+      {
+        if (LEqual(Arg1, 1))   // test Arg1 for the revision
+        {
+          Return (Buffer () {0x07})
+        }
+        else
+        {
+          Return (Buffer () {0})
+        }
+      }
+      //
+      // USB Sideband Deferring Support
+      //   0: USB Sideband Deferring not supported on this device
+      //   1: USB Sideband Deferring supported
+      //
+      Case (1)
+      {
+        if (LEqual(SDGV,0xFF))   // check for valid GPE vector
+        {
+          Return (0)
+        }
+        else
+        {
+          Return (1)
+        }
+      }
+      //
+      // GPE Vector
+      //  Return the bit offset within the GPE block of the GPIO (HOST_ALERT) driven by this device
+      //
+      Case (2)
+      {
+        Return (SDGV)
+      }
+    }
+  }
+
+  Return (0)
+}
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Video.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Video.asl
new file mode 100644
index 0000000000..768b912aae
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Video.asl
@@ -0,0 +1,34 @@
+/**************************************************************************;
+;*                                                                        *;
+;*                                                                        *;
+;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
+;*    Family of Customer Reference Boards.                                *;
+;*                                                                        *;
+;*                                                                        *;
+;*    Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved   *;
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;*                                                                        *;
+;*                                                                        *;
+;**************************************************************************/
+
+
+
+
+// Brightness Notification:
+//              Generate a brightness related notification
+//      to the LFP if its populated.
+//
+//      Arguments:
+//              Arg0:   Notification value.
+//
+//      Return Value:
+//              None
+Method(BRTN,1,Serialized)
+{
+  If(LEqual(And(DIDX,0x0F00),0x400))
+  {
+    Notify(\_SB.PCI0.GFX0.DD1F,Arg0)
+  }
+}
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Vlv.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Vlv.asl
new file mode 100644
index 0000000000..32e1851303
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Vlv.asl
@@ -0,0 +1,39 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  VLV.ASL
+
+Abstract:
+
+  Baytrail PCI configuration space definition.
+
+--*/
+Scope (\_SB.PCI0)
+{
+
+  Device(GFX0)   // Mobile I.G.D
+  {
+    Name(_ADR, 0x00020000)
+
+    Method(GDEP, 0)
+    {
+      If(LEqual(OSYS,2013))
+      {
+        Name(_DEP, Package(0x1)
+        {
+          PEPD
+        })
+      }
+    }
+
+    include("INTELGFX.ASL")
+    include("INTELISPDev2.ASL")
+  } // end "Mobile I.G.D"
+}//end scope
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Wsmt/Wsmt.aslc b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Wsmt/Wsmt.aslc
new file mode 100644
index 0000000000..35fa799123
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Wsmt/Wsmt.aslc
@@ -0,0 +1,54 @@
+/*++
+  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  Wsmt.c
+
+Abstract:
+
+  This file contains a structure definition for the Windows SMM Security
+  Mitigations Table (WSMT).
+
+++*/
+
+//
+// Statements that include other files
+//
+#include "AcpiTablePlatform.h"
+#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
+
+//
+// WSMT Table definition
+//
+EFI_ACPI_WSMT_TABLE WSMT = {
+  EFI_ACPI_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE,
+  sizeof (EFI_ACPI_WSMT_TABLE),
+  EFI_WSMT_TABLE_REVISION,
+  //
+  // Checksum will be updated at runtime
+  //
+  0,
+  EFI_ACPI_OEM_ID,            // OEMID is a 6 bytes long field
+  EFI_ACPI_OEM_TABLE_ID,      // OEM table identification(8 bytes long)
+  EFI_ACPI_OEM_REVISION,      // OEM revision
+  EFI_ACPI_CREATOR_ID,        // ASL compiler vendor ID
+  EFI_ACPI_CREATOR_REVISION,  // ASL compiler revision number
+  0x00000000,                 // Protection flag
+};
+
+VOID*
+ReferenceAcpiTable (
+  VOID
+  )
+{
+  //
+  // Reference the table being generated to prevent the optimizer from
+  // removing the data structure from the executable
+  //
+  return (VOID*)&WSMT;
+}
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/token.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/token.asl
new file mode 100644
index 0000000000..f976cb84d3
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/token.asl
@@ -0,0 +1,39 @@
+/**************************************************************************;
+;*                                                                        *;
+;*                                                                        *;
+;*    Intel Corporation - ACPI Reference Code for the Sandy Bridge        *;
+;*    Family of Customer Reference Boards.                                *;
+;*                                                                        *;
+;*                                                                        *;
+;*    Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved    *;
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;*                                                                        *;
+;*                                                                        *;
+;**************************************************************************/
+
+Name(PMBS, 0x400)       // ASL alias for ACPI I/O base address.
+Name(SMIP, 0xb2)        // I/O port to trigger SMI
+Name(GPBS, 0x500)       // GPIO Register Block address
+Name(APCB, 0xfec00000)  // Default I/O APIC(s) memory start address, 0x0FEC00000 - default, 0 - I/O APIC's disabled
+Name(APCL, 0x1000)      // I/O APIC(s) memory decoded range, 0x1000 - default, 0 - I/O APIC's not decoded
+Name(PFDR, 0xfed03034)  // PMC Function Disable Register
+Name(PMCB, 0xfed03000)  // PMC Base Address
+Name(PCLK, 0xfed03060)  // PMC Clock Control Register
+Name(PUNB, 0xfed05000)  // PUNIT Base Address
+Name(IBAS, 0xfed08000)  // ILB Base Address
+Name(SRCB, 0xfed1c000)  // RCBA (Root Complex Base Address)
+Name(SRCL, 0x1000)      // RCBA length
+Name(HPTB, 0xfed00000)  // Same as HPET_BASE_ADDRESS for ASL use
+Name(PEBS, 0xe0000000)  // PCIe Base
+Name(PELN, 0x10000000)  //
+Name(FMBL, 0x1) // Platform Flavor - Mobile flavor for ASL code.
+Name(FDTP, 0x2) // Platform Flavor - Desktop flavor for ASL code.
+Name(SDGV, 0x1c)        // UHCI Controller HOST_ALERT's bit offset within the GPE block. GPIO[0:15] corresponding to GPE[16:31]
+Name(PEHP, 0x1) // _OSC: Pci Express Native Hot Plug Control
+Name(SHPC, 0x0) // _OSC: Standard Hot Plug Controller (SHPC) Native Hot Plug control
+Name(PEPM, 0x1) // _OSC: Pci Express Native Power Management Events control
+Name(PEER, 0x1) // _OSC: Pci Express Advanced Error Reporting control
+Name(PECS, 0x1) // _OSC: Pci Express Capability Structure control
+
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Guid/Vlv2DeviceRefCodePkgTokenSpace.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Guid/Vlv2DeviceRefCodePkgTokenSpace.h
new file mode 100644
index 0000000000..c7408b9308
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Guid/Vlv2DeviceRefCodePkgTokenSpace.h
@@ -0,0 +1,24 @@
+/*++
+
+Copyright (c)  2010  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+Module Name:
+
+  Vlv2DeviceRefCodeTokenSpace.h
+
+Abstract:
+
+  Interface definition details for GUID.
+
+--*/
+#ifndef __VLV2_REF_CODE__PKG_TOKEN_SPACE_GUID_H__
+#define __VLV2_REF_CODE__PKG_TOKEN_SPACE_GUID_H__
+
+#define EFI_VLV_TOKEN_SPACE_GUID \
+  { 0xca452c68, 0xdf0c, 0x45c9, {0x82, 0xfb, 0xea, 0xe4, 0x2b, 0x31, 0x29, 0x46}}
+extern EFI_GUID gEfiVLVTokenSpaceGuid;
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/PttPassThruPpi.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/PttPassThruPpi.h
new file mode 100644
index 0000000000..55646f4f3e
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/PttPassThruPpi.h
@@ -0,0 +1,92 @@
+/*++
+
+  Copyright (c) 2004  - 2015, Intel Corporation. All rights reserved.<BR>
+                                                                                   
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+                                                                                   
+--*/
+
+#ifndef _EFI_PTT_PASS_THRU_PPI_H
+#define _EFI_PTT_PASS_THRU_PPI_H
+
+#define PTT_PASS_THRU_PPI_GUID \
+  { \
+    0xc5068bac, 0xa7dc, 0x42f1, 0xae, 0x80, 0xca, 0xa2, 0x4b, 0xb4, 0x90, 0x4b   \
+  }
+// {C5068BAC-A7DC-42f1-AE80-CAA24BB4904B}
+//static const GUID <<name>> = 
+//{ 0xc5068bac, 0xa7dc, 0x42f1, { 0xae, 0x80, 0xca, 0xa2, 0x4b, 0xb4, 0x90, 0x4b } };
+
+
+
+//#define EFI_PTT_PROTOCOL_GUID  HECI_PROTOCOL_GUID
+
+typedef struct _PTT_PASS_THRU_PPI PTT_PASS_THRU_PPI;
+
+/**
+  This service enables the sending of commands to the TPM2.
+
+  @param[in]      InputParameterBlockSize  Size of the TPM2 input parameter block.
+  @param[in]      InputParameterBlock      Pointer to the TPM2 input parameter block.
+  @param[in,out]  OutputParameterBlockSize Size of the TPM2 output parameter block.
+  @param[in]      OutputParameterBlock     Pointer to the TPM2 output parameter block.
+
+  @retval EFI_SUCCESS            The command byte stream was successfully sent to the device and a response was successfully received.
+  @retval EFI_DEVICE_ERROR       The command was not successfully sent to the device or a response was not successfully received from the device.
+  @retval EFI_BUFFER_TOO_SMALL   The output parameter block is too small. 
+**/
+typedef
+EFI_STATUS
+(EFIAPI *TPM2_SUBMIT_COMMAND) (
+  IN PTT_PASS_THRU_PPI *This,
+  IN UINT32                  InputParameterBlockSize,
+  IN UINT8                   *InputParameterBlock,
+  IN OUT UINT32              *OutputParameterBlockSize,
+  IN UINT8                   *OutputParameterBlock
+  );
+
+/**
+  This service requests use TPM2.
+
+  @retval EFI_SUCCESS      Get the control of TPM2 chip.
+  @retval EFI_NOT_FOUND    TPM2 not found.
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *TPM2_REQUEST_USE_TPM) (
+  IN PTT_PASS_THRU_PPI *This
+  );
+
+typedef struct {
+  EFI_GUID                           ProviderGuid;
+  TPM2_SUBMIT_COMMAND                Tpm2SubmitCommand;
+  TPM2_REQUEST_USE_TPM               Tpm2RequestUseTpm;
+} PTT_TPM2_DEVICE_INTERFACE;
+
+
+/**
+  This service register TPM2 device.
+
+  @param Tpm2Device  TPM2 device
+
+  @retval EFI_SUCCESS          This TPM2 device is registered successfully.
+  @retval EFI_UNSUPPORTED      System does not support register this TPM2 device.
+  @retval EFI_ALREADY_STARTED  System already register this TPM2 device.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *TPM2_REGISTER_TPM2_DEVICE_LIB) (
+  IN PTT_PASS_THRU_PPI  *This,
+  IN PTT_TPM2_DEVICE_INTERFACE   *Tpm2Device
+  );
+  
+typedef struct _PTT_PASS_THRU_PPI {
+  TPM2_SUBMIT_COMMAND             Tpm2SubmitCommand;
+  TPM2_REQUEST_USE_TPM            Tpm2RequestUseTpm;
+  TPM2_REGISTER_TPM2_DEVICE_LIB   Tpm2RegisterTpm2DeviceLib;
+} PTT_PASS_THRU_PPI;
+
+extern EFI_GUID gPttPassThruPpiGuid;
+
+#endif // _EFI_HECI_H
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/fTPMPolicy.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/fTPMPolicy.h
new file mode 100644
index 0000000000..8f3acfd005
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/fTPMPolicy.h
@@ -0,0 +1,26 @@
+/*++
+
+  Copyright (c) 2004  - 2015, Intel Corporation. All rights reserved.<BR>
+                                                                                   
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+                                                                                   
+--*/
+
+#ifndef _SEC_FTPM_POLICY_PPI_H_
+#define _SEC_FTPM_POLICY_PPI_H_
+
+#define SEC_FTPM_POLICY_PPI_GUID \
+  { \
+    0x4fd1ba49, 0x8f90, 0x471a, 0xa2, 0xc9, 0x17, 0x3c, 0x7a, 0x73, 0x2f, 0xd0 \
+  }
+
+extern EFI_GUID  gSeCfTPMPolicyPpiGuid;
+
+//
+// PPI definition
+//
+typedef struct SEC_FTPM_POLICY_PPI {
+  BOOLEAN                 fTPMEnable;
+} SEC_FTPM_POLICY_PPI;
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Protocol/PttPassThru.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Protocol/PttPassThru.h
new file mode 100644
index 0000000000..2009a46816
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Protocol/PttPassThru.h
@@ -0,0 +1,91 @@
+/*++
+
+  Copyright (c) 2004  - 2015, Intel Corporation. All rights reserved.<BR>
+                                                                                   
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+                                                                                   
+--*/
+
+#ifndef _EFI_PTT_PASS_THRU_H
+#define _EFI_PTT_PASS_THRU_H
+
+#define PTT_PASS_THRU_PROTOCOL_GUID \
+  { \
+    0x73e2576, 0xf6c1, 0x4b91, 0x92, 0xa9, 0xd4, 0x67, 0x5d, 0xda, 0x34, 0xb1  \
+  }
+// {073E2576-F6C1-4b91-92A9-D4675DDA34B1}
+//static const GUID <<name>> = 
+//{ 0x73e2576, 0xf6c1, 0x4b91, { 0x92, 0xa9, 0xd4, 0x67, 0x5d, 0xda, 0x34, 0xb1 } };
+
+
+//#define EFI_PTT_PROTOCOL_GUID  HECI_PROTOCOL_GUID
+
+typedef struct _PTT_PASS_THRU_PROTOCOL PTT_PASS_THRU_PROTOCOL;
+
+/**
+  This service enables the sending of commands to the TPM2.
+
+  @param[in]      InputParameterBlockSize  Size of the TPM2 input parameter block.
+  @param[in]      InputParameterBlock      Pointer to the TPM2 input parameter block.
+  @param[in,out]  OutputParameterBlockSize Size of the TPM2 output parameter block.
+  @param[in]      OutputParameterBlock     Pointer to the TPM2 output parameter block.
+
+  @retval EFI_SUCCESS            The command byte stream was successfully sent to the device and a response was successfully received.
+  @retval EFI_DEVICE_ERROR       The command was not successfully sent to the device or a response was not successfully received from the device.
+  @retval EFI_BUFFER_TOO_SMALL   The output parameter block is too small. 
+**/
+typedef
+EFI_STATUS
+(EFIAPI *TPM2_SUBMIT_COMMAND) (
+  IN PTT_PASS_THRU_PROTOCOL *This,
+  IN UINT32                  InputParameterBlockSize,
+  IN UINT8                   *InputParameterBlock,
+  IN OUT UINT32              *OutputParameterBlockSize,
+  IN UINT8                   *OutputParameterBlock
+  );
+
+/**
+  This service requests use TPM2.
+
+  @retval EFI_SUCCESS      Get the control of TPM2 chip.
+  @retval EFI_NOT_FOUND    TPM2 not found.
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *TPM2_REQUEST_USE_TPM) (
+  IN PTT_PASS_THRU_PROTOCOL *This
+  );
+
+typedef struct {
+  EFI_GUID                           ProviderGuid;
+  TPM2_SUBMIT_COMMAND                Tpm2SubmitCommand;
+  TPM2_REQUEST_USE_TPM               Tpm2RequestUseTpm;
+} PTT_TPM2_DEVICE_INTERFACE;
+
+
+/**
+  This service register TPM2 device.
+
+  @param Tpm2Device  TPM2 device
+
+  @retval EFI_SUCCESS          This TPM2 device is registered successfully.
+  @retval EFI_UNSUPPORTED      System does not support register this TPM2 device.
+  @retval EFI_ALREADY_STARTED  System already register this TPM2 device.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *TPM2_REGISTER_TPM2_DEVICE_LIB) (
+  IN PTT_PASS_THRU_PROTOCOL  *This,
+  IN PTT_TPM2_DEVICE_INTERFACE   *Tpm2Device
+  );
+  
+typedef struct _PTT_PASS_THRU_PROTOCOL {
+  TPM2_SUBMIT_COMMAND             Tpm2SubmitCommand;
+  TPM2_REQUEST_USE_TPM            Tpm2RequestUseTpm;
+  TPM2_REGISTER_TPM2_DEVICE_LIB   Tpm2RegisterTpm2DeviceLib;
+} PTT_PASS_THRU_PROTOCOL;
+
+extern EFI_GUID gPttPassThruProtocolGuid;
+
+#endif // _EFI_HECI_H
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Guid/PowerManagementAcpiTableStorage.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Guid/PowerManagementAcpiTableStorage.h
new file mode 100644
index 0000000000..eab1db0897
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Guid/PowerManagementAcpiTableStorage.h
@@ -0,0 +1,27 @@
+
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+Module Name:
+
+  PowerManagementAcpiTableStorage.h
+
+Abstract:
+
+  GUID definition for the Power Management ACPI table storage file name
+
+--*/
+
+#ifndef _POWER_MANAGEMENT_ACPI_TABLE_STORAGE_H_
+#define _POWER_MANAGEMENT_ACPI_TABLE_STORAGE_H_
+
+#define POWER_MANAGEMENT_ACPI_TABLE_STORAGE_GUID \
+  { 0x161be597, 0xe9c5, 0x49db, 0xae, 0x50, 0xc4, 0x62, 0xab, 0x54, 0xee, 0xda }
+
+extern EFI_GUID gPowerManagementAcpiTableStorageGuid;
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Ppi/VlvPolicy.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Ppi/VlvPolicy.h
new file mode 100644
index 0000000000..0a8b267db1
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Ppi/VlvPolicy.h
@@ -0,0 +1,104 @@
+
+/*++
+
+Copyright (c)  2010  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+Module Name:
+
+  VlvPolicy.h
+
+Abstract:
+
+  Interface definition details between ValleyView MRC and platform drivers during PEI phase.
+
+--*/
+
+#ifndef _VLV_POLICY_PPI_H_
+#define _VLV_POLICY_PPI_H_
+
+//
+// MRC Policy provided by platform for PEI phase {7D84B2C2-22A1-4372-B12C-EBB232D3A6A3}
+//
+#define VLV_POLICY_PPI_GUID \
+  { \
+    0x7D84B2C2, 0x22A1, 0x4372, 0xB1, 0x2C, 0xEB, 0xB2, 0x32, 0xD3, 0xA6, 0xA3 \
+  }
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gVlvPolicyPpiGuid;
+
+//
+// PPI revision number
+// Any backwards compatible changes to this PPI will result in an update in the revision number
+// Major changes will require publication of a new PPI
+//
+#define MRC_PLATFORM_POLICY_PPI_REVISION  1
+
+#ifndef MAX_SOCKETS
+#define MAX_SOCKETS 4
+#endif
+
+#define S3_TIMING_DATA_LEN          9
+#define S3_READ_TRAINING_DATA_LEN   16
+#define S3_WRITE_TRAINING_DATA_LEN  12
+
+#ifndef S3_RESTORE_DATA_LEN
+#define S3_RESTORE_DATA_LEN (S3_TIMING_DATA_LEN + S3_READ_TRAINING_DATA_LEN + S3_WRITE_TRAINING_DATA_LEN)
+#endif // S3_RESTORE_DATA_LEN
+#pragma pack(1)
+//
+// MRC Platform Data Structure
+//
+typedef struct {
+  UINT8   SpdAddressTable[MAX_SOCKETS];
+  UINT8   TSonDimmSmbusAddress[MAX_SOCKETS];
+
+  UINT16  SmbusBar;
+  UINT32  IchRcba;
+  UINT32  WdbBaseAddress; // Write Data Buffer area (WC caching mode)
+  UINT32  WdbRegionSize;
+  UINT32  SmBusAddress;
+  UINT8   UserBd;
+  UINT8   PlatformType;
+  UINT8   FastBoot;
+  UINT8   DynSR;
+} VLV_PLATFORM_DATA;
+
+
+typedef struct {
+  UINT16  MmioSize;
+  UINT16  GttSize;
+  UINT8   IgdDvmt50PreAlloc;
+  UINT8   PrimaryDisplay;
+  UINT8   PAVPMode;
+  UINT8   ApertureSize;
+} GT_CONFIGURATION;
+
+typedef struct {
+  UINT8   EccSupport;
+  UINT16  DdrFreqLimit;
+  UINT8   MaxTolud;
+} MEMORY_CONFIGURATION;
+
+
+//
+// MRC Platform Policiy PPI
+//
+typedef struct _VLV_POLICY_PPI {
+  UINT8                 Revision;
+  VLV_PLATFORM_DATA     PlatformData;
+  GT_CONFIGURATION      GtConfig;
+  MEMORY_CONFIGURATION  MemConfig;
+  VOID                  *S3DataPtr; // was called MRC_PARAMS_SAVE_RESTORE
+  UINT8                 ISPEn;            //ISP (IUNIT) Device Enabled
+  UINT8                 ISPPciDevConfig;  //ISP (IUNIT) Device Config: 0->B0/D2/F0 for Window OS, 1->B0D3/F0 for Linux OS
+} VLV_POLICY_PPI;
+
+#pragma pack()
+
+#endif // _VLV_POLICY_PPI_H_
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Protocol/PpmPlatformPolicy.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Protocol/PpmPlatformPolicy.h
new file mode 100644
index 0000000000..ab6b9e80d3
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Protocol/PpmPlatformPolicy.h
@@ -0,0 +1,132 @@
+/** 
+  Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+/*++
+
+Module Name:
+
+  PpmPlatformPolicy.h
+
+Abstract:
+
+  Interface definition details between PPM and platform drivers during DXE phase.
+
+--*/
+#ifndef _PPM_PLATFORM_POLICY_H_
+#define _PPM_PLATFORM_POLICY_H_
+
+//
+//  PPM policy provided by platform for DXE phase {DDABFEAC-EF63-452c-8F39-ED7FAED8265E}
+//
+#define PPM_PLATFORM_POLICY_PROTOCOL_GUID \
+  {0xddabfeac, 0xef63, 0x452c, 0x8f, 0x39, 0xed, 0x7f, 0xae, 0xd8, 0x26, 0x5e}
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gPpmPlatformPolicyProtocolGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _PPM_PLATFORM_POLICY_PROTOCOL PPM_PLATFORM_POLICY_PROTOCOL;
+
+//
+// Protocol revision number
+// Any backwards compatible changes to this protocol will result in an update in the revision number
+// Major changes will require publication of a new protocol
+//
+// Revision 1: Original version
+// Revision 2: Added T-states field to the PPM_FUNCTION_ENABLES structure, Renamed unused fields - CxPopUpEnable, CxPopDownEnable, FastC4ExitEnable
+// Revision 3: Extended VidCpuid to 32 bits for extended CPUID support (Penryn)
+// Revision 4: Added support for extended C6 residency enabling
+//
+#define PPM_PLATFORM_POLICY_PROTOCOL_REVISION     1
+#define PPM_PLATFORM_POLICY_PROTOCOL_REVISION_2   2
+#define PPM_PLATFORM_POLICY_PROTOCOL_REVISION_3   3
+#define PPM_PLATFORM_POLICY_PROTOCOL_REVISION_4   4
+
+//
+// Define maximum number of custom VID states supported
+//
+#ifndef MAX_CUSTOM_VID_TABLE_STATES
+#define MAX_CUSTOM_VID_TABLE_STATES               6
+#endif
+//
+// Custom VID table
+//
+typedef struct {
+  UINT8   VidNumber;
+  UINT32  VidCpuid;
+  UINT16  VidMaxRatio;
+  UINT16  VidMaxVid;
+  UINT16  StateRatio[MAX_CUSTOM_VID_TABLE_STATES];
+  UINT16  StateVid[MAX_CUSTOM_VID_TABLE_STATES];
+} PPM_CUSTOM_VID_TABLE;
+
+//
+// PPM functional enables
+//
+typedef struct {
+  UINT8   EnableGv                   :1; // 0: Disabled; 1: Enabled
+  UINT8   EnableCx                   :1;
+  UINT8   EnableCxe                  :1;
+  UINT8   EnableC4                   :1;
+  UINT8   EnableC6                   :1;
+  UINT8   EnableC7                   :1;
+  UINT8   EnableTm                   :1;
+  UINT8   Reserve00                  :1;
+  UINT8   Reserve01                  :1;
+  UINT8   EnableTurboMode            :1;
+  UINT8   PowerLimit2                :1;
+  UINT8   EnableProcHot              :1;
+  UINT8   Reserve02                  :1;
+  UINT8   EnableCMP                  :1;
+  UINT8   TStatesEnable              :1;
+  UINT8   Reserve03                  :1;
+  UINT8   Reserve04                  ;
+
+} PPM_FUNCTION_ENABLES;
+
+
+//
+// PPM Turbo settings
+//
+typedef struct _PPM_TURBO_SETTINGS {
+  UINT16  PowerLimit1;
+  UINT32  PowerLimit1Time;
+  UINT16  PowerLimit2;
+  UINT8   TurboPowerLimitLock;
+} PPM_TURBO_SETTINGS;
+
+//
+// Platform Policy
+//
+struct _PPM_PLATFORM_POLICY_PROTOCOL {
+  UINT8                                 Revision;
+  PPM_FUNCTION_ENABLES                  FunctionEnables;
+  PPM_CUSTOM_VID_TABLE                  CustomVidTable;
+  PPM_TURBO_SETTINGS                    TurboSettings;
+
+  UINT8                                 Reserve00;
+  UINT8                                 Reserve01;
+  UINT8                                 Reserve02;
+  UINT8                                 Reserve03;
+  UINT8                                 Reserve04;
+  UINT8                                 Reserve05;
+  UINT8                                 Reserve06;
+
+  UINT8                                 S3RestoreMsrSwSmiNumber;
+  UINT8                                 Reserve07;
+  UINT32                                Reserve08;
+  UINT8                                 Reserve09;
+  //
+  // Primary and Secondary Plane Current Limits
+  //
+  UINT16                                Reserve10;
+  UINT8                                 Reserve11;
+};
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Types.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Types.h
new file mode 100644
index 0000000000..0df6a6d193
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Types.h
@@ -0,0 +1,55 @@
+/*++
+
+Copyright (c) 1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+    Types.h
+
+Abstract:
+
+    This file include all the external data types.
+
+--*/
+
+#ifndef _TYPES_H_
+#define _TYPES_H_
+
+
+
+//
+// Modifiers to abstract standard types to aid in debug of problems
+//
+#define CONST     const
+#define STATIC    static
+#define VOID      void
+#define VOLATILE  volatile
+
+//
+// Constants. They may exist in other build structures, so #ifndef them.
+//
+#ifndef TRUE
+#define TRUE  ((BOOLEAN) 1 == 1)
+#endif
+
+#ifndef FALSE
+#define FALSE ((BOOLEAN) 0 == 1)
+#endif
+
+#ifndef NULL
+#define NULL  ((VOID *) 0)
+#endif
+
+typedef UINT32 STATUS;
+#define SUCCESS 0
+#define FAILURE 0xFFFFFFFF
+
+#ifndef MRC_DEADLOOP
+#define MRC_DEADLOOP()    while (TRUE)
+#endif
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/PowerManagementAcpiTables.inf b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/PowerManagementAcpiTables.inf
new file mode 100644
index 0000000000..021b95fa61
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/PowerManagementAcpiTables.inf
@@ -0,0 +1,39 @@
+#
+#/*++
+#
+#Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#Module Name:
+#
+#  PowerManagementAcpiTables.inf
+#
+#Abstract:
+#
+#  Component description file for the ACPI tables
+#
+#--*/
+
+[defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PowerManagementAcpiTables2
+  FILE_GUID                      = 161BE597-E9C5-49DB-AE50-C462AB54EEDA
+  MODULE_TYPE                    = USER_DEFINED
+  VERSION_STRING                 = 1.0
+  EDK_RELEASE_VERSION            = 0x00020000
+  EFI_SPECIFICATION_VERSION      = 0x00020000
+
+
+[sources.common]
+  Ssdt/Cpu0Cst.asl
+  Ssdt/Cpu0Ist.asl
+  Ssdt/Cpu0Tst.asl
+  Ssdt/ApCst.asl
+  Ssdt/ApIst.asl
+  Ssdt/ApTst.asl
+  Ssdt/CpuPm.asl
+
+[Packages]
+  MdePkg/MdePkg.dec
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/ApCst.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/ApCst.asl
new file mode 100644
index 0000000000..6aa130b115
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/ApCst.asl
@@ -0,0 +1,110 @@
+/*-----------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+
+
+ Intel Silvermont Processor Power Management BIOS Reference Code
+
+ Copyright (c) 2006 - 2014, Intel Corporation
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+ Filename:      CPU1CST.ASL
+
+ Revision:      Refer to Readme
+
+ Date:          Refer to Readme
+
+--------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+
+ This Processor Power Management BIOS Source Code is furnished under license
+ and may only be used or copied in accordance with the terms of the license.
+ The information in this document is furnished for informational use only, is
+ subject to change without notice, and should not be construed as a commitment
+ by Intel Corporation. Intel Corporation assumes no responsibility or liability
+ for any errors or inaccuracies that may appear in this document or any
+ software that may be provided in association with this document.
+
+ Except as permitted by such license, no part of this document may be
+ reproduced, stored in a retrieval system, or transmitted in any form or by
+ any means without the express written consent of Intel Corporation.
+
+ WARNING: You are authorized and licensed to install and use this BIOS code
+ ONLY on an IST PC. This utility may damage any system that does not
+ meet these requirements.
+
+        An IST PC is a computer which
+        (1) Is capable of seamlessly and automatically transitioning among
+        multiple performance states (potentially operating at different
+        efficiency ratings) based upon power source changes, END user
+        preference, processor performance demand, and thermal conditions; and
+        (2) Includes an Intel Pentium II processors, Intel Pentium III
+        processor, Mobile Intel Pentium III Processor-M, Mobile Intel Pentium 4
+        Processor-M, Intel Pentium M Processor, or any other future Intel
+        processors that incorporates the capability to transition between
+        different performance states by altering some, or any combination of,
+        the following processor attributes: core voltage, core frequency, bus
+        frequency, number of processor cores available, or any other attribute
+        that changes the efficiency (instructions/unit time-power) at which the
+        processor operates.
+
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+
+NOTES:
+        (1) <TODO> - IF the trap range and port definitions do not match those
+        specified by this reference code, this file must be modified IAW the
+        individual implmentation.
+
+--------------------------------------------------------------------------------
+------------------------------------------------------------------------------*/
+
+
+DefinitionBlock (
+        "APCST.aml",
+        "SSDT",
+        1,
+        "PmRef",
+        "ApCst",
+        0x3000
+        )
+{
+External(\_PR.CPU1, DeviceObj)
+External(\_PR.CPU2, DeviceObj)
+External(\_PR.CPU3, DeviceObj)
+External(\_PR.CPU0._CST)
+
+        Scope(\_PR.CPU1)
+        {
+                Method(_CST,0)
+                {
+                        //
+                        // Return P0's _CST object.
+                        //
+                        Return(\_PR.CPU0._CST)
+                }
+        }
+
+        Scope(\_PR.CPU2)
+        {
+                Method(_CST,0)
+                {
+                        //
+                        // Return P0's _CST object.
+                        //
+                        Return(\_PR.CPU0._CST)
+                }
+        }
+
+        Scope(\_PR.CPU3)
+        {
+                Method(_CST,0)
+                {
+                        //
+                        // Return P0's _CST object.
+                        //
+                        Return(\_PR.CPU0._CST)
+                }
+        }
+}  // End of Definition Block
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/ApIst.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/ApIst.asl
new file mode 100644
index 0000000000..ffffe9a8fc
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/ApIst.asl
@@ -0,0 +1,166 @@
+/*-----------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+
+
+ Intel Silvermont Processor Power Management BIOS Reference Code
+
+ Copyright (c) 2006 - 2014, Intel Corporation
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+ Filename:      APIST.ASL
+
+ Revision:      Refer to Readme
+
+ Date:          Refer to Readme
+
+--------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+
+ This Processor Power Management BIOS Source Code is furnished under license
+ and may only be used or copied in accordance with the terms of the license.
+ The information in this document is furnished for informational use only, is
+ subject to change without notice, and should not be construed as a commitment
+ by Intel Corporation. Intel Corporation assumes no responsibility or liability
+ for any errors or inaccuracies that may appear in this document or any
+ software that may be provided in association with this document.
+
+ Except as permitted by such license, no part of this document may be
+ reproduced, stored in a retrieval system, or transmitted in any form or by
+ any means without the express written consent of Intel Corporation.
+
+ WARNING: You are authorized and licensed to install and use this BIOS code
+ ONLY on an IST PC. This utility may damage any system that does not
+ meet these requirements.
+
+        An IST PC is a computer which
+        (1) Is capable of seamlessly and automatically transitioning among
+        multiple performance states (potentially operating at different
+        efficiency ratings) based upon power source changes, END user
+        preference, processor performance demand, and thermal conditions; and
+        (2) Includes an Intel Pentium II processors, Intel Pentium III
+        processor, Mobile Intel Pentium III Processor-M, Mobile Intel Pentium 4
+        Processor-M, Intel Pentium M Processor, or any other future Intel
+        processors that incorporates the capability to transition between
+        different performance states by altering some, or any combination of,
+        the following processor attributes: core voltage, core frequency, bus
+        frequency, number of processor cores available, or any other attribute
+        that changes the efficiency (instructions/unit time-power) at which the
+        processor operates.
+
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+
+NOTES:
+        (1) <TODO> - IF the trap range and port definitions do not match those
+        specified by this reference code, this file must be modified IAW the
+        individual implmentation.
+
+--------------------------------------------------------------------------------
+------------------------------------------------------------------------------*/
+
+
+DefinitionBlock (
+        "APIST.aml",
+        "SSDT",
+        1,
+        "PmRef",
+        "ApIst",
+        0x3000
+        )
+{
+        External(\_PR.CPU0._PSS, MethodObj)
+        External(\_PR.CPU0._PCT, MethodObj)
+        External(\_PR.CPU0._PPC, IntObj)
+        External(\_PR.CPU0._PSD, MethodObj)
+        External(\_PR.CPU1, DeviceObj)
+        External(\_PR.CPU2, DeviceObj)
+        External(\_PR.CPU3, DeviceObj)
+        External (CFGD)
+        External (PDC0)
+
+        Scope(\_PR.CPU1)
+        {
+                Method(_PPC,0)
+                {
+                        Return(\_PR.CPU0._PPC)  // Return P0 _PPC value.
+                }
+
+                Method(_PCT,0)
+                {
+                        Return(\_PR.CPU0._PCT)  // Return P0 _PCT.
+                }
+
+                Method(_PSS,0)
+                {
+                        //Return the same table as CPU0 for CMP cases.
+                        Return(\_PR.CPU0._PSS)
+                }
+
+                // The _PSD object provides information to the OSPM related
+                // to P-State coordination between processors in a multi-processor
+                // configurations.
+                //
+                Method(_PSD,0)
+                {
+                        Return(\_PR.CPU0._PSD)  // Return P0 _PSD.
+                }
+        }
+
+        Scope(\_PR.CPU2)
+        {
+                Method(_PPC,0)
+                {
+                        Return(\_PR.CPU0._PPC)  // Return P0 _PPC value.
+                }
+
+                Method(_PCT,0)
+                {
+                        Return(\_PR.CPU0._PCT)  // Return P0 _PCT.
+                }
+
+                Method(_PSS,0)
+                {
+                        //Return the same table as CPU0 for CMP cases.
+                        Return(\_PR.CPU0._PSS)
+                }
+
+                // The _PSD object provides information to the OSPM related
+                // to P-State coordination between processors in a multi-processor
+                // configurations.
+                //
+                Method(_PSD,0)
+                {
+                        Return(\_PR.CPU0._PSD)  // Return P0 _PSD.
+                }
+        }
+
+        Scope(\_PR.CPU3)
+        {
+                Method(_PPC,0)
+                {
+                        Return(\_PR.CPU0._PPC)  // Return P0 _PPC value.
+                }
+
+                Method(_PCT,0)
+                {
+                        Return(\_PR.CPU0._PCT)  // Return P0 _PCT.
+                }
+
+                Method(_PSS,0)
+                {
+                        //Return the same table as CPU0 for CMP cases.
+                        Return(\_PR.CPU0._PSS)
+                }
+
+                // The _PSD object provides information to the OSPM related
+                // to P-State coordination between processors in a multi-processor
+                // configurations.
+                //
+                Method(_PSD,0)
+                {
+                        Return(\_PR.CPU0._PSD)  // Return P0 _PSD.
+                }
+        }
+} // End of Definition Block
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/ApTst.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/ApTst.asl
new file mode 100644
index 0000000000..760eb3c108
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/ApTst.asl
@@ -0,0 +1,262 @@
+/*-----------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+
+
+ Intel Platform Processor Power Management BIOS Reference Code
+
+ Copyright (c) 2007  - 2014, Intel Corporation
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+ Filename:      APTST.ASL
+
+ Revision:      Refer to Readme
+
+ Date:          Refer to Readme
+
+--------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+
+ This Processor Power Management BIOS Source Code is furnished under license
+ and may only be used or copied in accordance with the terms of the license.
+ The information in this document is furnished for informational use only, is
+ subject to change without notice, and should not be construed as a commitment
+ by Intel Corporation. Intel Corporation assumes no responsibility or liability
+ for any errors or inaccuracies that may appear in this document or any
+ software that may be provided in association with this document.
+
+ Except as permitted by such license, no part of this document may be
+ reproduced, stored in a retrieval system, or transmitted in any form or by
+ any means without the express written consent of Intel Corporation.
+
+ WARNING: You are authorized and licensed to install and use this BIOS code
+ ONLY on an IST PC. This utility may damage any system that does not
+ meet these requirements.
+
+        An IST PC is a computer which
+        (1) Is capable of seamlessly and automatically transitioning among
+        multiple performance states (potentially operating at different
+        efficiency ratings) based upon power source changes, END user
+        preference, processor performance demand, and thermal conditions; and
+        (2) Includes an Intel Pentium II processors, Intel Pentium III
+        processor, Mobile Intel Pentium III Processor-M, Mobile Intel Pentium 4
+        Processor-M, Intel Pentium M Processor, or any other future Intel
+        processors that incorporates the capability to transition between
+        different performance states by altering some, or any combination of,
+        the following processor attributes: core voltage, core frequency, bus
+        frequency, number of processor cores available, or any other attribute
+        that changes the efficiency (instructions/unit time-power) at which the
+        processor operates.
+
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+
+NOTES:
+        (1) <TODO> - IF the trap range and port definitions do not match those
+        specified by this reference code, this file must be modified IAW the
+        individual implmentation.
+
+--------------------------------------------------------------------------------
+------------------------------------------------------------------------------*/
+
+
+DefinitionBlock(
+        "APTST.aml",
+        "SSDT",
+        0x01,
+        "PmRef",
+        "ApTst",
+        0x3000
+        )
+{
+        External(\_PR.CPU1, DeviceObj)
+        External(\_PR.CPU2, DeviceObj)
+        External(\_PR.CPU3, DeviceObj)
+        External(\_PR.CPU0._PTC)
+        External(\_PR.CPU0._TSS)
+        External(PDC0)
+        External(CFGD)
+        External(MPEN)
+
+        Scope(\_PR.CPU1)
+        {
+                Name(_TPC, 0)   // All T-States are available
+
+                //
+                // T-State Control/Status interface
+                //
+                Method(_PTC, 0)
+                {
+                        Return(\_PR.CPU0._PTC)
+                }
+
+                Method(_TSS, 0)
+                {
+                        Return(\_PR.CPU0._TSS)
+                }
+
+                //
+                // T-State Dependency
+                //
+                Method(_TSD, 0)
+                {
+                        //
+                        // IF four cores are supported/enabled && !(direct access to MSR)
+                        //    Report 4 processors and SW_ANY as the coordination
+                        // IF two cores are supported/enabled && !(direct access to MSR)
+                        //    Report 2 processors and SW_ANY as the coordination type
+                        //  ELSE
+                        //    Report 1 processor and SW_ALL as the coordination type (domain 1)
+                        //
+                        //  CFGD[23] = Four cores enabled
+                        //  CFGD[24] = Two or more cores enabled
+                        //  PDCx[2] = OSPM is capable of direct access to On
+                        //              Demand throttling MSR
+                        //
+
+                If(LNot(And(PDC0,4)))
+                {
+                                Return(Package(){       // SW_ANY
+                                        Package(){
+                                                5,                // # entries.
+                                                0,                // Revision.
+                                                0,                // Domain #.
+                                                0xFD,           // Coord Type- SW_ANY
+                                                MPEN          // # processors.
+                                        }
+                                })
+                }
+                Return(Package(){               // SW_ALL
+                        Package(){
+                                5,                        // # entries.
+                                0,                        // Revision.
+                                1,                        // Domain #.
+                                0xFC,                   // Coord Type- SW_ALL
+                                1               // # processors.
+                        }
+                })
+                }
+        }  // End of CPU1
+
+        Scope(\_PR.CPU2)
+        {
+                Name(_TPC, 0)   // All T-States are available
+
+                //
+                // T-State Control/Status interface
+                //
+                Method(_PTC, 0)
+                {
+                        Return(\_PR.CPU0._PTC)
+                }
+
+                Method(_TSS, 0)
+                {
+                        Return(\_PR.CPU0._TSS)
+                }
+
+                //
+                // T-State Dependency
+                //
+                Method(_TSD, 0)
+                {
+                        //
+                        // IF four cores are supported/enabled && !(direct access to MSR)
+                        //    Report 4 processors and SW_ANY as the coordination
+                        // IF two cores are supported/enabled && !(direct access to MSR)
+                        //    Report 2 processors and SW_ANY as the coordination type
+                        //  ELSE
+                        //    Report 1 processor and SW_ALL as the coordination type (domain 1)
+                        //
+                        //  CFGD[23] = Four cores enabled
+                        //  CFGD[24] = Two or more cores enabled
+                        //  PDCx[2] = OSPM is capable of direct access to On
+                        //              Demand throttling MSR
+                        //
+
+                If(LNot(And(PDC0,4)))
+                {
+                                Return(Package(){       // SW_ANY
+                                        Package(){
+                                                5,                // # entries.
+                                                0,                // Revision.
+                                                0,                // Domain #.
+                                                0xFD,           // Coord Type- SW_ANY
+                                                MPEN          // # processors.
+                                        }
+                                })
+                }
+                Return(Package(){               // SW_ALL
+                        Package(){
+                                5,                        // # entries.
+                                0,                        // Revision.
+                                1,                        // Domain #.
+                                0xFC,                   // Coord Type- SW_ALL
+                                1                // # processors.
+                        }
+                })
+                }
+        }  // End of CPU2
+
+        Scope(\_PR.CPU3)
+        {
+                Name(_TPC, 0)   // All T-States are available
+
+                //
+                // T-State Control/Status interface
+                //
+                Method(_PTC, 0)
+                {
+                        Return(\_PR.CPU0._PTC)
+                }
+
+                Method(_TSS, 0)
+                {
+                        Return(\_PR.CPU0._TSS)
+                }
+
+                //
+                // T-State Dependency
+                //
+                Method(_TSD, 0)
+                {
+                        //
+                        // IF four cores are supported/enabled && !(direct access to MSR)
+                        //    Report 4 processors and SW_ANY as the coordination
+                        // IF two cores are supported/enabled && !(direct access to MSR)
+                        //    Report 2 processors and SW_ANY as the coordination type
+                        //  ELSE
+                        //    Report 1 processor and SW_ALL as the coordination type (domain 1)
+                        //
+                        //  CFGD[23] = Four cores enabled
+                        //  CFGD[24] = Two or more cores enabled
+                        //  PDCx[2] = OSPM is capable of direct access to On
+                        //              Demand throttling MSR
+                        //
+
+                If(LNot(And(PDC0,4)))
+                {
+                                Return(Package(){       // SW_ANY
+                                        Package(){
+                                                5,                // # entries.
+                                                0,                // Revision.
+                                                0,                // Domain #.
+                                                0xFD,           // Coord Type- SW_ANY
+                                                MPEN          // # processors.
+                                        }
+                                })
+                }
+                Return(Package(){               // SW_ALL
+                        Package(){
+                                5,                        // # entries.
+                                0,                        // Revision.
+                                1,                        // Domain #.
+                                0xFC,                   // Coord Type- SW_ALL
+                                1                // # processors.
+                        }
+                })
+                }
+        }  // End of CPU3
+} // End of Definition Block
+
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/Cpu0Cst.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/Cpu0Cst.asl
new file mode 100644
index 0000000000..76c774a44d
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/Cpu0Cst.asl
@@ -0,0 +1,274 @@
+
+/*-----------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+
+
+ Intel Silvermont Processor Power Management BIOS Reference Code
+
+ Copyright (c) 2006 - 2014, Intel Corporation
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+ Filename:    CPU0CST.ASL
+
+ Revision:    Refer to Readme
+
+ Date:        Refer to Readme
+
+--------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+
+ This Processor Power Management BIOS Source Code is furnished under license
+ and may only be used or copied in accordance with the terms of the license.
+ The information in this document is furnished for informational use only, is
+ subject to change without notice, and should not be construed as a commitment
+ by Intel Corporation. Intel Corporation assumes no responsibility or liability
+ for any errors or inaccuracies that may appear in this document or any
+ software that may be provided in association with this document.
+
+ Except as permitted by such license, no part of this document may be
+ reproduced, stored in a retrieval system, or transmitted in any form or by
+ any means without the express written consent of Intel Corporation.
+
+ WARNING: You are authorized and licensed to install and use this BIOS code
+ ONLY on an IST PC. This utility may damage any system that does not
+ meet these requirements.
+
+    An IST PC is a computer which
+    (1) Is capable of seamlessly and automatically transitioning among
+    multiple performance states (potentially operating at different
+    efficiency ratings) based upon power source changes, END user
+    preference, processor performance demand, and thermal conditions; and
+    (2) Includes an Intel Pentium II processors, Intel Pentium III
+    processor, Mobile Intel Pentium III Processor-M, Mobile Intel Pentium 4
+    Processor-M, Intel Pentium M Processor, or any other future Intel
+    processors that incorporates the capability to transition between
+    different performance states by altering some, or any combination of,
+    the following processor attributes: core voltage, core frequency, bus
+    frequency, number of processor cores available, or any other attribute
+    that changes the efficiency (instructions/unit time-power) at which the
+    processor operates.
+
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+
+NOTES:
+    (1) <TODO> - IF the trap range and port definitions do not match those
+    specified by this reference code, this file must be modified IAW the
+    individual implmentation.
+
+--------------------------------------------------------------------------------
+------------------------------------------------------------------------------*/
+
+
+DefinitionBlock (
+    "CPU0CST.aml",
+    "SSDT",
+    1,
+    "PmRef",
+    "Cpu0Cst",
+    0x3001
+    )
+{
+    External(\_PR.CPU0, DeviceObj)
+    External(PWRS)
+    External(CFGD)
+    External(PDC0)
+
+    Scope(\_PR.CPU0)
+    {
+        OperationRegion (DEB0, SystemIO, 0x80, 1)    //DBG
+        Field (DEB0, ByteAcc,NoLock,Preserve)        //DBG
+        { DBG8, 8,}                    //DBG
+
+        Method (_CST, 0)
+        {
+            Store(0x60,DBG8) //DBG
+
+            // IF CMP is supported, but independent C-States beyond C1 are
+            // not supported; return C1 Halt and rely on BIOS based software
+            // coordination
+            //
+            //   CFGD[24] = CMP support
+            //   PDCx[4]  = 0 - OS does not support ind. C2/C3 in MP systems
+            //
+            // Note:  SMI will be generated when both processor enter the
+            // Halt state.
+            //
+            If(LAnd(And(CFGD,0x01000000), LNot(And(PDC0,0x10))))
+            {
+                Store(0x61,DBG8) //DBG
+                Return(Package() {
+                    1,
+                    Package()
+                    {   // C1 halt, but with BIOS coordination
+                        ResourceTemplate(){Register(FFixedHW, 0, 0, 0)},
+                        1,
+                        157,
+                        1000
+                    }
+                })
+            }
+
+            // IF MWAIT extensions are supported, use them.
+            //
+            //  IF C6 capable/enabled AND Battery
+            //        Report MWAIT C1, C2, C6 w/ BM_STS avoidance
+            //  ELSE IF C4 capable/enabled AND Battery
+            //        Report MWAIT C1, C2, C4 w/ BM_STS avoidance
+            //  ELSE IF C3 capable/enabled
+            //      Report MWAIT C1, C2, C3 w/ BM_STS avoidance
+            //  ELSE IF C2 capable/enabled
+            //        Report MWAIT C1, C2
+            //  ELSE
+            //        Report MWAIT C1
+            //
+            //   CFGD[21] = 1 - MWAIT extensions supported
+            //   CFGD[13] = 1 - C7  Capable/Enabled
+            //   CFGD[12] = 1 - C6S Capable/Enabled
+            //   CFGD[11] = 1 - C6  Capable/Enabled
+            //   CFGD[7]  = 1 - C4  Capable/Enabled
+            //   CFGD[5]  = 1 - C3  Capable/Enabled
+            //   PDCx[9]  = 1 - OS  supports MWAIT extensions
+            //   PDCx[8]  = 1 - OS  supports MWAIT for C1
+            //            (Inferred from PDCx[9] = 1.)
+            //   PDCx[4]  = 1 - OS supports independent C2/C3 in MP systems
+            //    or
+            //   NOT CMP  (Inferred from previous check.)
+            //
+            If(LAnd(And(CFGD, 0x200000), And(PDC0,0x200)))
+            {
+                //
+                // <TODO> The implementor may wish to only report C1-C2
+                // when on AC power.  In this case, the IF clause below can
+                // be modified to something like:
+                //
+                // "If(LAnd(And(CFGD,0x200), LNot(PWRS)))"
+                //
+                // Which uses the power state of the system (PWRS) to
+                // determine whether to allow deepers states.
+                //
+                //   IF C7 supported AND on battery
+                //    report MWAIT C1, C6, C7
+                //
+                //   CFGD[13] = C7  Capable/Enabled
+                //   CFGD[11] = C6  Capable/Enabled
+                //
+              If(LAnd(And(CFGD,0x2000),And(CFGD,0x40000000)))
+                {
+                    Store(0x77,DBG8) //DBG
+                    Return( Package()
+                    {
+                        3,
+                        Package()
+                        {   // C1, MWAIT
+                            ResourceTemplate(){Register(FFixedHW, 1, 2, 0x00, 1)},
+                            1,
+                            1,
+                            1000
+                        },
+                        Package()
+                        {
+                            // C6, MWAIT Extension with Incremental L2 Shrink
+                            // ResourceTemplate(){Register(FFixedHW, 1, 2, 0x50, 1)},
+                            // C6, MWAIT Extension with No L2 Shrink
+                            ResourceTemplate(){Register(FFixedHW, 1, 2, 0x51, 1)},
+                            2,
+                            500,
+                            10
+                        },
+                        Package()
+                        {
+                            // C7, MWAIT Extension with Full L2 Shrink
+                            ResourceTemplate(){Register(FFixedHW, 1, 2, 0x64, 1)},
+                            3,
+                            1500,   //PnP setting, 1.5 ms for worst-case exit latency
+                            10
+                        }
+                    })
+                }
+
+
+             If(LAnd(And(CFGD,0x2000),LNot(And(CFGD,0x40000000))))
+                {
+                    Store(0x67,DBG8) //DBG
+                    Return( Package()
+                    {
+                        3,
+                        Package()
+                        {   // C1, MWAIT
+                            ResourceTemplate(){Register(FFixedHW, 1, 2, 0x00, 1)},
+                            1,
+                            1,
+                            1000
+                        },
+                        Package()
+                        {
+                            // C6, MWAIT Extension with Incremental L2 Shrink
+                            // ResourceTemplate(){Register(FFixedHW, 1, 2, 0x50, 1)},
+                            // C6 = C6NS, MWAIT Extension with No L2 Shrink
+                            ResourceTemplate(){Register(FFixedHW, 1, 2, 0x51, 1)},
+                            2,
+                            500,
+                            10
+                        },
+                        Package()
+                        {
+
+                            ResourceTemplate(){Register(FFixedHW, 1, 2, 0x52, 1)},
+                            3,
+                            1500,   //PnP setting, 1.5 ms for worst-case exit latency
+                            10
+                        }
+                    })
+                }
+
+                If(And(CFGD,0x800)) // Setup Max C-State = C6
+                {
+                    Store(0x76,DBG8) //DBG
+                    Return( Package()
+                    {
+                        2,
+                        Package()
+                        {   // C1, MWAIT
+                            ResourceTemplate(){Register(FFixedHW, 1, 2, 0x00, 1)},
+                            1,
+                            1,
+                            1000
+                        },
+                        Package()
+                        {
+                            // C6, MWAIT Extension with Incremental L2 Shrink
+                            // ResourceTemplate(){Register(FFixedHW, 1, 2, 0x50, 1)},
+                            // C6, MWAIT Extension with No L2 Shrink
+                            ResourceTemplate(){Register(FFixedHW, 1, 2, 0x51, 1)},
+                            2,
+                            500,
+                            10
+                        }
+                    })
+                }
+                //
+                // IF no deeper C-States are supported; report MWAIT C1.
+                //
+                Store(0x71,DBG8) //DBG
+                Return(Package()
+                {
+                    1,
+                    Package()
+                    {   // C1, MWAIT
+                        ResourceTemplate () {Register(FFixedHW, 1, 2, 0x00, 1)},
+                        1,
+                        1,
+                        1000
+                    }
+                })
+            }
+
+
+        }
+    }
+}
+
+
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/Cpu0Ist.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/Cpu0Ist.asl
new file mode 100644
index 0000000000..07bdb85602
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/Cpu0Ist.asl
@@ -0,0 +1,260 @@
+/*-----------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+
+
+ Intel Silvermont Processor Power Management BIOS Reference Code
+
+ Copyright (c) 2006 - 2014, Intel Corporation
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+ Filename:    CPU0IST.ASL
+
+ Revision:    Refer to Readme
+
+ Date:        Refer to Readme
+
+--------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+
+ This Processor Power Management BIOS Source Code is furnished under license
+ and may only be used or copied in accordance with the terms of the license.
+ The information in this document is furnished for informational use only, is
+ subject to change without notice, and should not be construed as a commitment
+ by Intel Corporation. Intel Corporation assumes no responsibility or liability
+ for any errors or inaccuracies that may appear in this document or any
+ software that may be provided in association with this document.
+
+ Except as permitted by such license, no part of this document may be
+ reproduced, stored in a retrieval system, or transmitted in any form or by
+ any means without the express written consent of Intel Corporation.
+
+ WARNING: You are authorized and licensed to install and use this BIOS code
+ ONLY on an IST PC. This utility may damage any system that does not
+ meet these requirements.
+
+    An IST PC is a computer which
+    (1) Is capable of seamlessly and automatically transitioning among
+    multiple performance states (potentially operating at different
+    efficiency ratings) based upon power source changes, END user
+    preference, processor performance demand, and thermal conditions; and
+    (2) Includes an Intel Pentium II processors, Intel Pentium III
+    processor, Mobile Intel Pentium III Processor-M, Mobile Intel Pentium 4
+    Processor-M, Intel Pentium M Processor, or any other future Intel
+    processors that incorporates the capability to transition between
+    different performance states by altering some, or any combination of,
+    the following processor attributes: core voltage, core frequency, bus
+    frequency, number of processor cores available, or any other attribute
+    that changes the efficiency (instructions/unit time-power) at which the
+    processor operates.
+
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+
+NOTES:
+    (1) <TODO> - IF the trap range and port definitions do not match those
+    specified by this reference code, this file must be modified IAW the
+    individual implmentation.
+
+--------------------------------------------------------------------------------
+------------------------------------------------------------------------------*/
+
+
+DefinitionBlock (
+    "CPU0IST.aml",
+    "SSDT",
+    0x01,
+    "PmRef",
+    "Cpu0Ist",
+    0x3000
+    )
+{
+    External (\_PR.CPU0, DeviceObj)
+    External (PDC0)
+    External (CFGD)
+
+    Scope(\_PR.CPU0)
+    {
+        //OperationRegion (DEB0, SystemIO, 0x80, 1)    //DBG
+        //Field (DEB0, ByteAcc,NoLock,Preserve)        //DBG
+        //{ DBG8, 8,}                                  //DBG
+
+        Name(_PPC, 0)        // Initialize as All States Available.
+
+        // NOTE:  For CMP systems; this table is not loaded unless
+        //      the required driver support is present.
+        //      So, we do not check for those cases here.
+        //
+        //   CFGD[0] = GV3 Capable/Enabled
+        //   PDCx[0]  = OS Capable of Hardware P-State control
+        //
+        Method(_PCT,0)
+        {
+            If(LAnd(And(CFGD,0x0001), And(PDC0,0x0001)))
+            {
+                //Store(0xA0,DBG8) //DBG
+                Return(Package()    // Native Mode
+                {
+                    ResourceTemplate(){Register(FfixedHW, 0, 0, 0)},
+                    ResourceTemplate(){Register(FfixedHW, 0, 0, 0)}
+                })
+            }
+            // @NOTE: IO Trap is not supported. Therefore should not expose any IO interface for _PCT
+            // For all other cases, report control through the
+            // SMI interface.  (The port used for SMM control is fixed up
+            // by the initialization code.)
+            //
+            Return(Package()        // SMM Mode
+            {
+               ResourceTemplate(){Register(FfixedHW, 0, 0, 0)},
+               ResourceTemplate(){Register(FfixedHW, 0, 0, 0)}
+            })
+        }
+
+
+        // NOTE:  For CMP systems; this table is not loaded if MP
+        //      driver support is not present or P-State are disabled.
+        //
+        Method(_PSS,0)
+        {
+            //
+            // Report NSPP if:
+            //   (1) GV3 capable (Not checked, see above.)
+            //   (2) Driver support direct hardware control
+            //   (3) MP driver support present (Not checked, see above.)
+            // else;
+            //   Report SPSS
+            //
+            //   PDCx[0]  = OS Capable of Hardware P-State control
+            //
+            If(And(PDC0,0x0001)){
+                //Store(0xB0,DBG8) //DBG
+                Return(NPSS)
+            }
+            //Store(0xBF,DBG8) //DBG
+            // Otherwise, report SMM mode
+            //
+            Return(SPSS)
+
+        }
+
+        Name(SPSS,Package()
+        {
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000}
+        })
+
+        Name(NPSS,Package()
+        {
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000}
+        })
+
+        // The _PSD object provides information to the OSPM related
+        // to P-State coordination between processors in a multi-processor
+        // configurations.
+        //
+        Method(_PSD,0)
+        {
+            //
+            // IF CMP is supported/enabled
+            //   IF quad core processor
+            //     IF PDC[11]
+            //         Report 4 processors and HW_ALL as the coordination type
+            //     ELSE
+            //         Report 4 processors and SW_ALL as the coordination type
+            //   ELSE
+            //     IF PDC[11]
+            //         Report 2 processors and HW_ALL as the coordination type
+            //     ELSE
+            //         Report 2 processors and SW_ALL as the coordination type
+            // ELSE
+            //    Report 1 processor and SW_ALL as the coordination type
+            //    (Domain 0)
+            //
+            //   CFGD[24] = Two or more cores enabled
+            //   CFGD[23] = Four cores enabled
+            //   PDCx[11] = Hardware coordination with hardware feedback
+            //
+
+            If(And(CFGD,0x1000000))    // CMP Enabled.
+            {
+              If(And(CFGD,0x800000))    // 2 or 4 process.
+                {
+                  If(And(PDC0,0x0800))
+                  {
+                      Return(Package(){    // HW_ALL
+                        Package(){
+                            5,              // # entries.
+                            0,              // Revision.
+                            0,              // Domain #.
+                            0xFE,           // Coord Type- HW_ALL.
+                            4               // # processors.
+                        }
+                      })
+                  } // If(And(PDC0,0x0800))
+                   Return(Package(){        // SW_ALL
+                     Package(){
+                        5,                  // # entries.
+                        0,                  // Revision.
+                        0,                  // Domain #.
+                        0xFC,               // Coord Type- SW_ALL.
+                        4                   // # processors.
+                     }
+                    })
+                } else {
+                  Return(Package(){        // HW_ALL
+                      Package(){
+                          5,                  // # entries.
+                          0,                  // Revision.
+                          0,                  // Domain #.
+                          0xFE,               // Coord Type- HW_ALL.
+                          2                   // # processors.
+                      }
+                  })
+                }
+            }    // If(And(CFGD,0x1000000))    // CMP Enabled.
+
+            Return(Package(){              // SW_ALL
+                Package(){
+                    5,                        // # entries.
+                    0,                        // Revision.
+                    0,                        // Domain #.
+                    0xFC,                     // Coord Type- SW_ALL.
+                    1                         // # processors.
+                }
+            })
+        } // Method(_PSD,0)
+    } // Scope(\_PR.CPU0)
+} // End of Definition Block
+
+
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/Cpu0Tst.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/Cpu0Tst.asl
new file mode 100644
index 0000000000..1d65b0dc0d
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/Cpu0Tst.asl
@@ -0,0 +1,235 @@
+/*-----------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+
+
+ Intel Silvermont Processor Power Management BIOS Reference Code
+
+ Copyright (c) 2006 - 2014, Intel Corporation
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+ Filename:      CPU0TST.ASL
+
+ Revision:      Refer to Readme
+
+ Date:          Refer to Readme
+
+--------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+
+ This Processor Power Management BIOS Source Code is furnished under license
+ and may only be used or copied in accordance with the terms of the license.
+ The information in this document is furnished for informational use only, is
+ subject to change without notice, and should not be construed as a commitment
+ by Intel Corporation. Intel Corporation assumes no responsibility or liability
+ for any errors or inaccuracies that may appear in this document or any
+ software that may be provided in association with this document.
+
+ Except as permitted by such license, no part of this document may be
+ reproduced, stored in a retrieval system, or transmitted in any form or by
+ any means without the express written consent of Intel Corporation.
+
+ WARNING: You are authorized and licensed to install and use this BIOS code
+ ONLY on an IST PC. This utility may damage any system that does not
+ meet these requirements.
+
+        An IST PC is a computer which
+        (1) Is capable of seamlessly and automatically transitioning among
+        multiple performance states (potentially operating at different
+        efficiency ratings) based upon power source changes, end user
+        preference, processor performance demand, and thermal conditions; and
+        (2) Includes an Intel Pentium II processors, Intel Pentium III
+        processor, Mobile Intel Pentium III Processor-M, Mobile Intel Pentium 4
+        Processor-M, Intel Pentium M Processor, or any other future Intel
+        processors that incorporates the capability to transition between
+        different performance states by altering some, or any combination of,
+        the following processor attributes: core voltage, core frequency, bus
+        frequency, number of processor cores available, or any other attribute
+        that changes the efficiency (instructions/unit time-power) at which the
+        processor operates.
+
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+
+NOTES:
+        (1) <TODO> - IF the trap range and port definitions do not match those
+        specified by this reference code, this file must be modified IAW the
+        individual implmentation.
+
+--------------------------------------------------------------------------------
+------------------------------------------------------------------------------*/
+
+DefinitionBlock(
+        "CPU0TST.aml",
+        "SSDT",
+        0x01,
+        "PmRef",
+        "Cpu0Tst",
+        0x3000
+        )
+{
+        External(\_PR.CPU0, DeviceObj)
+        External(PDC0)
+        External(CFGD)
+        External(_PSS)
+
+        Scope(\_PR.CPU0)
+        {
+                Name(_TPC, 0)   // All T-States are available
+
+                //
+                // T-State Control/Status interface
+                //
+                Method(_PTC, 0)
+                {
+                        //
+                        // IF OSPM is capable of direct access to MSR
+                        //    Report MSR interface
+                        // ELSE
+                        //    Report I/O interface
+                        //
+                        //  PDCx[2] = OSPM is capable of direct access to On
+                        //              Demand throttling MSR
+                        //
+                        If(And(PDC0, 0x0004)) {
+                                Return(Package() {
+                                        ResourceTemplate(){Register(FFixedHW, 0, 0, 0)},
+                                        ResourceTemplate(){Register(FFixedHW, 0, 0, 0)}
+                                })
+                        }
+
+                }
+
+                // _TSS package for I/O port based T-State control
+                // "Power" fields are replaced with real values by the first
+                // call of _TSS method.
+                //
+                Name(TSSI, Package() {
+                                Package(){100, 1000, 0, 0x00, 0},
+                                Package(){ 88,  875, 0, 0x0F, 0},
+                                Package(){ 75,  750, 0, 0x0E, 0},
+                                Package(){ 63,  625, 0, 0x0D, 0},
+                                Package(){ 50,  500, 0, 0x0C, 0},
+                                Package(){ 38,  375, 0, 0x0B, 0},
+                                Package(){ 25,  250, 0, 0x0A, 0},
+                                Package(){ 13,  125, 0, 0x09, 0}
+                })
+
+                // _TSS package for MSR based T-State control
+                // "Power" fields are replaced with real values by the first
+                // call of _TSS method.
+                //
+                Name(TSSM, Package() {
+                                Package(){100, 1000, 0, 0x00, 0},
+                                Package(){ 88,  875, 0, 0x1E, 0},
+                                Package(){ 75,  750, 0, 0x1C, 0},
+                                Package(){ 63,  625, 0, 0x1A, 0},
+                                Package(){ 50,  500, 0, 0x18, 0},
+                                Package(){ 38,  375, 0, 0x16, 0},
+                                Package(){ 25,  250, 0, 0x14, 0},
+                                Package(){ 13,  125, 0, 0x12, 0}
+                })
+
+                Name(TSSF, 0)   // Flag for TSSI/TSSM initialization
+
+                Method(_TSS, 0)
+                {
+                        // Update "Power" fields of TSSI/TSSM with the LFM
+                        // power data IF _PSS is available
+                        //
+                        IF (LAnd(LNot(TSSF),CondRefOf(_PSS)))
+                        {
+                                Store(_PSS, Local0)
+                                Store(SizeOf(Local0), Local1)   // _PSS size
+                                Decrement(Local1)               // Index of LFM
+                                Store(DerefOf(Index(DerefOf(Index(Local0,Local1)),1)), Local2)  // LFM Power
+
+                                Store(0, Local3)
+                                While(LLess(Local3, SizeOf(TSSI)))
+                                {
+                                        Store(Divide(Multiply(Local2, Subtract(8, Local3)), 8),
+                                              Local4)           // Power for this TSSI/TSSM entry
+                                        Store(Local4,Index(DerefOf(Index(TSSI,Local3)),1))
+                                        Store(Local4,Index(DerefOf(Index(TSSM,Local3)),1))
+                                        Increment(Local3)
+                                }
+                                Store(Ones, TSSF)               // TSSI/TSSM are updated
+                        }
+                        //
+                        // IF OSPM is capable of direct access to MSR
+                        //    Report TSSM
+                        // ELSE
+                        //    Report TSSI
+                        //
+                        If(And(PDC0, 0x0004))
+                        {
+                                Return(TSSM)
+                        }
+                        Return(TSSI)
+                }
+
+              Method(_TDL, 0)
+              {
+                Store ("Cpu0: _TDL Called", Debug)
+                Name ( LFMI, 0)
+                Store (SizeOf(TSSM), LFMI)
+                Decrement(LFMI)    // Index of LFM entry in TSSM
+                Return(LFMI)
+              }
+
+                //
+                // T-State Dependency
+                //
+                Method(_TSD, 0)
+                {
+                        //
+      // IF four cores are supported/enabled && !(direct access to MSR)
+                        //    Report 4 processors and SW_ANY as the coordination type
+      // ELSE IF two cores are supported/enabled && !(direct access to MSR)
+                        //    Report 2 processors and SW_ANY as the coordination type
+                        // ELSE
+                        //   Report 1 processor and SW_ALL as the coordination type
+                        //
+                        //  CFGD[23] = Four cores enabled
+                        //  CFGD[24] = Two or more cores enabled
+                        //  PDCx[2] = OSPM is capable of direct access to On
+                        //              Demand throttling MSR
+                        //
+                        If(LAnd(And(CFGD,0x0800000),LNot(And(PDC0,4))))
+                        {
+                                Return(Package(){       // SW_ANY
+                                        Package(){
+                                                5,                // # entries.
+                                                0,                // Revision.
+                                                0,                // Domain #.
+                                                0xFD,           // Coord Type- SW_ANY
+                                                4                   // # processors.
+                                        }
+                                })
+                        }
+                        If(LAnd(And(CFGD,0x1000000),LNot(And(PDC0,4))))
+                        {
+                                Return(Package(){       // SW_ANY
+                                        Package(){
+                                                5,                // # entries.
+                                                0,                // Revision.
+                                                0,                // Domain #.
+                                                0xFD,           // Coord Type- SW_ANY
+                                                2                   // # processors.
+                                        }
+                                })
+                        }
+                        Return(Package(){               // SW_ALL
+                                Package(){
+                                        5,                        // # entries.
+                                        0,                        // Revision.
+                                        0,                        // Domain #.
+                                        0xFC,                   // Coord Type- SW_ALL
+                                        1                           // # processors.
+                                }
+                        })
+                }
+        }
+} // End of Definition Block
+
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/CpuPm.asl b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/CpuPm.asl
new file mode 100644
index 0000000000..3d30965c9f
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/Ssdt/CpuPm.asl
@@ -0,0 +1,793 @@
+/*-----------------------------------------------------------------------------
+
+
+ Intel Silvermont Processor Power Management BIOS Reference Code
+
+ Copyright (c) 2006 - 2014, Intel Corporation
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+ Filename:    CPUPM.ASL
+
+ Revision:    Refer to Readme
+
+ Date:        Refer to Readme
+-------------------------------------------------------------------------------
+
+ This Processor Power Management BIOS Source Code is furnished under license
+ and may only be used or copied in accordance with the terms of the license.
+ The information in this document is furnished for informational use only, is
+ subject to change without notice, and should not be construed as a commitment
+ by Intel Corporation. Intel Corporation assumes no responsibility or liability
+ for any errors or inaccuracies that may appear in this document or any
+ software that may be provided in association with this document.
+
+ Except as permitted by such license, no part of this document may be
+ reproduced, stored in a retrieval system, or transmitted in any form or by
+ any means without the express written consent of Intel Corporation.
+
+ WARNING: You are authorized and licensed to install and use this BIOS code
+ ONLY on an IST PC. This utility may damage any system that does not
+ meet these requirements.
+
+    An IST PC is a computer which
+    (1) Is capable of seamlessly and automatically transitioning among
+    multiple performance states (potentially operating at different
+    efficiency ratings) based upon power source changes, END user
+    preference, processor performance demand, and thermal conditions; and
+    (2) Includes an Intel Pentium II processors, Intel Pentium III
+    processor, Mobile Intel Pentium III Processor-M, Mobile Intel Pentium 4
+    Processor-M, Intel Pentium M Processor, or any other future Intel
+    processors that incorporates the capability to transition between
+    different performance states by altering some, or any combination of,
+    the following processor attributes: core voltage, core frequency, bus
+    frequency, number of processor cores available, or any other attribute
+    that changes the efficiency (instructions/unit time-power) at which the
+    processor operates.
+-------------------------------------------------------------------------------
+
+NOTES:
+    (1) <TODO> - Except for the SSDT package, the objects in this ASL code
+    may be moved to the DSDT. It is kept separate in this reference package
+    for ease of distribution only.
+------------------------------------------------------------------------------*/
+
+DefinitionBlock (
+    "CPUPM.aml",
+    "SSDT",
+    0x01,
+    "PmRef",
+    "CpuPm",
+    0x3000
+    )
+{
+    External(\_PR.CPU0, DeviceObj)
+    External(\_PR.CPU1, DeviceObj)
+    External(\_PR.CPU2, DeviceObj)
+    External(\_PR.CPU3, DeviceObj)
+    External(SMIF)
+
+  Scope(\)
+  {
+
+      // Package of pointers to SSDT's
+      //
+      // First column is SSDT name, used for debug only.
+      // (First column must be EXACTLY eight characters.)
+      // Second column is physical address.
+      // Third column is table length.
+      //
+      // IF modifying this file, see warnings listed in ppminit.asm.
+      //
+      Name(SSDT,Package()
+      {
+          "CPU0IST ", 0x80000000, 0x80000000,
+          "APIST   ", 0x80000000, 0x80000000,
+          "CPU0CST ", 0x80000000, 0x80000000,
+          "APCST   ", 0x80000000, 0x80000000
+      })
+
+      //
+      // Note:  See PpmBiosInit in PPMINIT.ASM for a definition of
+      // the PpmFlags mirrored in CFGD.
+      //
+      Name(CFGD, 0x80000000)
+
+      Name(\PDC0,0x80000000)    // CPU0 _PDC Flags.
+      Name(\PDC1,0x80000000)    // CPU1 _PDC Flags.
+      Name(\PDC2,0x80000000)    // CPU2 _PDC Flags.
+      Name(\PDC3,0x80000000)    // CPU3 _PDC Flags.
+      Name(\SDTL,0x00)          // Loaded SSDT Flags.
+  }
+
+  Scope(\_PR.CPU0)
+  {
+      //
+      // Define handles for opregions (used by load.)
+      //
+      Name(HI0,0)        // Handle to CPU0IST
+      Name(HC0,0)        // Handle to CPU0CST
+
+      Method(_PDC,1)
+      {
+          //
+          // Check and extract the _PDC information.
+          //
+          Store(CPDC(Arg0), Local0)
+          //
+          // Save the capability information and load tables as needed.
+          //
+          GCAP(Local0)
+          //
+          // Return status.
+          //
+          //Return (Local0)
+      }
+
+      Method(_OSC, 4)
+      {
+          //
+          // Check and extract the _OSC information.
+          //
+          Store(COSC(Arg0, Arg1, Arg2, Arg3), Local0)
+          //
+          // Save the capability information and load tables as needed.
+          //
+          GCAP(Local0)
+          //
+          // Return status.
+          //
+          Return (Local0)
+      }
+
+      //
+      // Implement a generic Method to check _PDC information which may be called
+      // by any of the processor scopes.  (The use of _PDC is deprecated in ACPI 3.
+      // in favor of _OSC. However, for backwards compatibility, _PDC may be
+      // implemented using _OSC as follows:)
+      //
+      Method(CPDC,1)
+      {
+          CreateDwordField (Arg0, 0, REVS)
+          CreateDwordField (Arg0, 4, SIZE)
+
+          //
+          // Local0 = Number of bytes for Arg0
+          //
+          Store (SizeOf (Arg0), Local0)
+
+          //
+          // Local1 = Number of Capabilities bytes in Arg0
+          //
+          Store (Subtract (Local0, 8), Local1)
+
+          //
+          // TEMP = Temporary field holding Capability DWORDs
+          //
+          CreateField (Arg0, 64, Multiply (Local1, 8), TEMP)
+
+          //
+          // Create the Status (STAT) buffer with the first DWORD = 0
+          // This is required as per ACPI 3.0 Spec which says the
+          // first DWORD is used to return errors defined by _OSC.
+          //
+          Name (STS0, Buffer () {0x00, 0x00, 0x00, 0x00})
+
+          //
+          // Concatenate the _PDC capabilities bytes to the STS0 Buffer
+          // and store them in a local variable for calling OSC
+          //
+          Concatenate (STS0, TEMP, Local2)
+
+          Return(COSC (ToUUID("4077A616-290C-47BE-9EBD-D87058713953"), REVS, SIZE, Local2))
+      }
+
+      //
+      // Implement a generic Method to check _OSC information which may be called
+      // by any of the processor scopes.
+      //
+      Method(COSC, 4)
+      {
+          //
+          // Point to Status DWORD in the Arg3 buffer (STATUS)
+          //
+          CreateDWordField(Arg3, 0, STS0)
+          //
+          // Point to Caps DWORDs of the Arg3 buffer (CAPABILITIES)
+          //
+          CreateDwordField(Arg3, 4, CAP0)
+
+          //
+          // _OSC needs to validate the UUID and Revision.
+          //
+          // IF Unrecognized UUID
+          //    Return Unrecognized UUID _OSC Failure
+          // IF Unsupported Revision
+          //    Return Unsupported Revision _OSC Failure
+          //
+          //    STS0[0] = Reserved
+          //    STS0[1] = _OSC Failure
+          //    STS0[2] = Unrecognized UUID
+          //    STS0[3] = Unsupported Revision
+          //    STS0[4] = Capabilities masked
+          //
+          // Note:  The comparison method used is necessary due to
+          // limitations of certain OSes which cannot perform direct
+          // buffer comparisons.
+          //
+          // Create a set of "Input" UUID fields.
+          //
+          CreateDwordField(Arg0, 0x0, IID0)
+          CreateDwordField(Arg0, 0x4, IID1)
+          CreateDwordField(Arg0, 0x8, IID2)
+          CreateDwordField(Arg0, 0xC, IID3)
+          //
+          // Create a set of "Expected" UUID fields.
+          //
+          Name(UID0, ToUUID("4077A616-290C-47BE-9EBD-D87058713953"))
+          CreateDwordField(UID0, 0x0, EID0)
+          CreateDwordField(UID0, 0x4, EID1)
+          CreateDwordField(UID0, 0x8, EID2)
+          CreateDwordField(UID0, 0xC, EID3)
+          //
+          // Verify the input UUID matches the expected UUID.
+          //
+          If(LNot(LAnd(LAnd(LEqual(IID0, EID0),LEqual(IID1, EID1)),LAnd(LEqual(IID2, EID2),LEqual(IID3, EID3)))))
+          {
+              //
+              // Return Unrecognized UUID _OSC Failure
+              //
+              Store (0x6, STS0)
+              Return (Arg3)
+          }
+
+          If(LNot(LEqual(Arg1,1)))
+          {
+              //
+              // Return Unsupported Revision _OSC Failure
+              //
+              Store (0xA, STS0)
+              Return (Arg3)
+          }
+
+          Return (Arg3)
+      }
+
+      //
+      // Get the capability information and load appropriate tables as needed.
+      //
+      Method(GCAP, 1)
+      {
+
+          // Point to Status DWORD in the Arg0 buffer (STATUS)
+          CreateDWordField(Arg0, 0, STS0)
+
+          // Point to Caps DWORDs of the Arg0 buffer (CAPABILITIES)
+          CreateDwordField(Arg0, 4, CAP0)
+
+          //
+          // If the UUID was unrecognized or the _OSC revision was unsupported,
+          // return without updating capabilities.
+          //
+          If(LOr(LEqual(STS0,0x6),LEqual(STS0,0xA)))
+          {
+              Return()
+          }
+
+          //
+          // Check if this is a query (BIT0 of Status = 1).
+          // If so, mask off the bits we support and return.
+          //
+          if (And(STS0, 1))
+          {
+              And(CAP0, 0xBFF, CAP0)
+              Return()
+          }
+
+          //
+          // Store result of PDC. (We clear out the MSB, which was just
+          // used as a placeholder for the compiler; and then "OR" the
+          // value in case we get multiple calls, each of which only
+          // reports partial support.)
+          //
+          Or(And(PDC0, 0x7FFFFFFF), CAP0, PDC0)
+
+          //
+          // Check IF the IST SSDTs should be loaded.
+          //
+          //   CFGD[0] = GV3 Capable/Enabled
+          //
+          If(And(CFGD,0x01))
+          {
+              //
+              // Load the IST SSDTs if:
+              //   (1) CMP capable and enabled.
+              //   (2) Driver supports P-States in MP configurations
+              //   (3) Driver supports direct HW P-State control
+              //   (4) SSDT is not already loaded
+              //
+              //   CFGD[24] = Two or more cores enabled
+              //   PDCx[3]  = OS supports C1 and P-states in MP systems
+              //   PDCx[0]  = OS supports direct access of the perf MSR
+              //   SDTL[0]  = CPU0 IST SSDT Loaded
+              //
+              If(LAnd(LAnd(And(CFGD,0x01000000),LEqual(And(PDC0, 0x0009), 0x0009)),LNot(And(SDTL,0x01))))
+              {
+                  //
+                  // Flag the IST SSDT as loaded for CPU0
+                  //
+                  Or(SDTL, 0x01, SDTL)
+
+                  OperationRegion(IST0,SystemMemory,DeRefOf(Index(SSDT,1)),DeRefOf(Index(SSDT,2)))
+                  Load(IST0, HI0)    // Dynamically load the CPU0IST SSDT
+              }
+          }
+
+          //
+          // Check IF the CST SSDTs should be loaded.
+          //
+          //   CFGD[11,7,2,1] = C6, C4, C1E, C1 Capable/Enabled
+          //
+          If(And(CFGD,0x82))
+          {
+              //
+              // Load the CST SSDTs if:
+              //   (1) CMP capable/enabled
+              //   (2) Driver supports multi-processor configurations
+              //   (3) CPU0 CST ISDT is not already loaded
+              //
+              //   CFGD[24] = Two or more cores enabled
+              //   PDCx[3]  = OS supports C1 and P-states in MP systems
+              //   PDCx[4]  = OS supports ind. C2/C3 in MP systems
+              //   SDTL[1]  = CPU0 CST SSDT Loaded
+              //
+              If(LAnd(LAnd(And(CFGD,0x01000000),And(PDC0,0x0018)),LNot(And(SDTL,0x02))))
+              {
+                  //
+                  // Flag the CST SSDT as loaded for CPU0
+                  //
+                  Or(SDTL, 0x02, SDTL)
+
+                  OperationRegion(CST0,SystemMemory,DeRefOf(Index(SSDT,7)),DeRefOf(Index(SSDT,8)))
+                  Load(CST0, HC0)    // Dynamically load the CPU0CST SSDT
+              }
+          }
+
+          Return ()
+      }
+  }
+
+
+  Scope(\_PR.CPU1)
+  {
+      //
+      // Define handles for opregions (used by load.)
+      //
+      Name(HI1,0)        // Handle to APIST
+      Name(HC1,0)        // Handle to APCST
+
+      Method(_PDC,1)
+      {
+          //
+          // Refer to \_PR.CPU0._PDC for description.
+          //
+          Store(\_PR.CPU0.CPDC(Arg0), Local0)
+          GCAP(Local0)
+          //Return (Local0)
+      }
+
+      Method(_OSC, 4)
+      {
+          //
+          // Refer to \_PR.CPU0._OSC for description.
+          //
+          Store(\_PR.CPU0.COSC(Arg0, Arg1, Arg2, Arg3), Local0)
+          GCAP(Local0)
+          Return (Local0)
+      }
+
+      //
+      // Get the capability information and load appropriate tables as needed.
+      //
+      Method(GCAP, 1)
+      {
+          //
+          // Point to Status DWORD in the Arg0 buffer (STATUS)
+          //
+          CreateDWordField(Arg0, 0, STS1)
+          //
+          // Point to Caps DWORDs of the Arg0 buffer (CAPABILITIES)
+          //
+          CreateDwordField(Arg0, 4, CAP1)
+          //
+          // If the UUID was unrecognized or the _OSC revision was unsupported,
+          // return without updating capabilities.
+          //
+          If(LOr(LEqual(STS1,0x6),LEqual(STS1,0xA)))
+          {
+              Return()
+          }
+
+          //
+          // Check if this is a query (BIT0 of Status = 1).
+          // If so, mask off the bits we support and return.
+          //
+          if (And(STS1, 1))
+          {
+              And(CAP1, 0xBFF, CAP1)
+              Return()
+          }
+
+          //
+          // Store result of PDC. (We clear out the MSB, which was just
+          // used as a placeholder for the compiler; and then "OR" the
+          // value in case we get multiple calls, each of which only
+          // reports partial support.)
+          //
+          Or(And(PDC1, 0x7FFFFFFF), CAP1, PDC1)
+
+          //
+          // Attempt to dynamically load the IST SSDTs if:
+          //   (1) Driver supports P-States in MP configurations
+          //   (2) Driver supports direct HW P-State control
+          //
+          //   PDCx[3]  = OS supports C1 and P-states in MP systems
+          //   PDCx[0]  = OS supports direct access of the perf MSR
+          //
+          If(LEqual(And(PDC0, 0x0009), 0x0009))
+          {
+              APPT()
+          }
+
+          //
+          // Load the CST SSDTs if:
+          //   (1) Driver supports multi-processor configurations
+          //
+          //   PDCx[3]  = OS supports C1 and P-states in MP systems
+          //   PDCx[4]  = OS supports ind. C2/C3 in MP systems
+          //
+          If(And(PDC0,0x0018))
+          {
+              APCT()
+          }
+
+          Return()
+      }
+
+      //
+      // Dynamically load the CST SSDTs if:
+      //   (1) C-States are enabled
+      //   (2) SSDT is not already loaded
+      //
+      //   CFGD[11,7,2,1] = C6, C4, C1E, C1 Capable/Enabled
+      //   SDTL[5]   = AP CST SSDT Loaded
+      //
+      Method(APCT,0)
+      {
+          If(LAnd(And(CFGD,0x82),LNot(And(SDTL,0x20))))
+          {
+              //
+              // Flag the CST SSDT as loaded for the AP's
+              //
+              Or(SDTL, 0x20, SDTL)
+              //
+              // Dynamically load the APCST SSDT
+              //
+              OperationRegion(CST1,SystemMemory,DeRefOf(Index(SSDT,10)),DeRefOf(Index(SSDT,11)))
+              Load(CST1, HC1)
+          }
+      }
+
+      //
+      // Dynamically load the IST SSDTs if:
+      //   (1) If GV3 capable and enabled
+      //   (2) SSDT is not already loaded
+      //
+      //   CFGD[0] = GV3 Capable/Enabled
+      //   SDTL[4] = AP IST SSDT Loaded
+      //
+      Method(APPT,0)
+      {
+          If(LAnd(And(CFGD,0x01),LNot(And(SDTL,0x10))))
+          {
+              //
+              // Flag the IST SSDT as loaded for CPU0
+              //
+              Or(SDTL, 0x10, SDTL)
+
+              OperationRegion(IST1,SystemMemory,DeRefOf(Index(SSDT,4)),DeRefOf(Index(SSDT,5)))
+              Load(IST1, HI1)    // Dynamically load the CPU1IST SSDT
+          }
+      }
+  }    // End CPU1
+
+  Scope(\_PR.CPU2)
+  {
+      //
+      // Define handles for opregions (used by load.)
+      //
+      Name(HI1,0)        // Handle to APIST
+      Name(HC1,0)        // Handle to APCST
+
+      Method(_PDC,1)
+      {
+          //
+          // Refer to \_PR.CPU0._PDC for description.
+          //
+          Store(\_PR.CPU0.CPDC(Arg0), Local0)
+          GCAP(Local0)
+          //Return (Local0)
+      }
+
+      Method(_OSC, 4)
+      {
+          //
+          // Refer to \_PR.CPU0._OSC for description.
+          //
+          Store(\_PR.CPU0.COSC(Arg0, Arg1, Arg2, Arg3), Local0)
+          GCAP(Local0)
+          Return (Local0)
+      }
+
+      //
+      // Get the capability information and load appropriate tables as needed.
+      //
+      Method(GCAP, 1)
+      {
+          //
+          // Point to Status DWORD in the Arg0 buffer (STATUS)
+          //
+          CreateDWordField(Arg0, 0, STS1)
+          //
+          // Point to Caps DWORDs of the Arg0 buffer (CAPABILITIES)
+          //
+          CreateDwordField(Arg0, 4, CAP1)
+          //
+          // If the UUID was unrecognized or the _OSC revision was unsupported,
+          // return without updating capabilities.
+          //
+          If(LOr(LEqual(STS1,0x6),LEqual(STS1,0xA)))
+          {
+              Return()
+          }
+
+          //
+          // Check if this is a query (BIT0 of Status = 1).
+          // If so, mask off the bits we support and return.
+          //
+          if (And(STS1, 1))
+          {
+              And(CAP1, 0xBFF, CAP1)
+              Return()
+          }
+
+          //
+          // Store result of PDC. (We clear out the MSB, which was just
+          // used as a placeholder for the compiler; and then "OR" the
+          // value in case we get multiple calls, each of which only
+          // reports partial support.)
+          //
+          Or(And(PDC1, 0x7FFFFFFF), CAP1, PDC1)
+
+          //
+          // Attempt to dynamically load the IST SSDTs if:
+          //   (1) Driver supports P-States in MP configurations
+          //   (2) Driver supports direct HW P-State control
+          //
+          //   PDCx[3]  = OS supports C1 and P-states in MP systems
+          //   PDCx[0]  = OS supports direct access of the perf MSR
+          //
+          If(LEqual(And(PDC0, 0x0009), 0x0009))
+          {
+              APPT()
+          }
+
+          //
+          // Load the CST SSDTs if:
+          //   (1) Driver supports multi-processor configurations
+          //
+          //   PDCx[3]  = OS supports C1 and P-states in MP systems
+          //   PDCx[4]  = OS supports ind. C2/C3 in MP systems
+          //
+          If(And(PDC0,0x0018))
+          {
+              APCT()
+          }
+
+          Return()
+      }
+
+      //
+      // Dynamically load the CST SSDTs if:
+      //   (1) C-States are enabled
+      //   (2) SSDT is not already loaded
+      //
+      //   CFGD[11,7,2,1] = C6, C4, C1E, C1 Capable/Enabled
+      //   SDTL[5]   = AP CST SSDT Loaded
+      //
+      Method(APCT,0)
+      {
+          If(LAnd(And(CFGD,0x82),LNot(And(SDTL,0x20))))
+          {
+              //
+              // Flag the CST SSDT as loaded for the AP's
+              //
+              Or(SDTL, 0x20, SDTL)
+              //
+              // Dynamically load the APCST SSDT
+              //
+              OperationRegion(CST1,SystemMemory,DeRefOf(Index(SSDT,10)),DeRefOf(Index(SSDT,11)))
+              Load(CST1, HC1)
+          }
+      }
+
+      //
+      // Dynamically load the IST SSDTs if:
+      //   (1) If GV3 capable and enabled
+      //   (2) SSDT is not already loaded
+      //
+      //   CFGD[0] = GV3 Capable/Enabled
+      //   SDTL[4] = AP IST SSDT Loaded
+      //
+      Method(APPT,0)
+      {
+          If(LAnd(And(CFGD,0x01),LNot(And(SDTL,0x10))))
+          {
+              //
+              // Flag the IST SSDT as loaded for CPU0
+              //
+              Or(SDTL, 0x10, SDTL)
+
+              OperationRegion(IST1,SystemMemory,DeRefOf(Index(SSDT,4)),DeRefOf(Index(SSDT,5)))
+              Load(IST1, HI1)    // Dynamically load the CPU1IST SSDT
+          }
+      }
+  }    // End CPU1
+
+  Scope(\_PR.CPU3)
+  {
+      //
+      // Define handles for opregions (used by load.)
+      //
+      Name(HI1,0)        // Handle to APIST
+      Name(HC1,0)        // Handle to APCST
+
+      Method(_PDC,1)
+      {
+          //
+          // Refer to \_PR.CPU0._PDC for description.
+          //
+          Store(\_PR.CPU0.CPDC(Arg0), Local0)
+          GCAP(Local0)
+          //Return (Local0)
+      }
+
+      Method(_OSC, 4)
+      {
+          //
+          // Refer to \_PR.CPU0._OSC for description.
+          //
+          Store(\_PR.CPU0.COSC(Arg0, Arg1, Arg2, Arg3), Local0)
+          GCAP(Local0)
+          Return (Local0)
+      }
+
+      //
+      // Get the capability information and load appropriate tables as needed.
+      //
+      Method(GCAP, 1)
+      {
+          //
+          // Point to Status DWORD in the Arg0 buffer (STATUS)
+          //
+          CreateDWordField(Arg0, 0, STS1)
+          //
+          // Point to Caps DWORDs of the Arg0 buffer (CAPABILITIES)
+          //
+          CreateDwordField(Arg0, 4, CAP1)
+          //
+          // If the UUID was unrecognized or the _OSC revision was unsupported,
+          // return without updating capabilities.
+          //
+          If(LOr(LEqual(STS1,0x6),LEqual(STS1,0xA)))
+          {
+              Return()
+          }
+
+          //
+          // Check if this is a query (BIT0 of Status = 1).
+          // If so, mask off the bits we support and return.
+          //
+          if (And(STS1, 1))
+          {
+              And(CAP1, 0xBFF, CAP1)
+              Return()
+          }
+
+          //
+          // Store result of PDC. (We clear out the MSB, which was just
+          // used as a placeholder for the compiler; and then "OR" the
+          // value in case we get multiple calls, each of which only
+          // reports partial support.)
+          //
+          Or(And(PDC1, 0x7FFFFFFF), CAP1, PDC1)
+
+          //
+          // Attempt to dynamically load the IST SSDTs if:
+          //   (1) Driver supports P-States in MP configurations
+          //   (2) Driver supports direct HW P-State control
+          //
+          //   PDCx[3]  = OS supports C1 and P-states in MP systems
+          //   PDCx[0]  = OS supports direct access of the perf MSR
+          //
+          If(LEqual(And(PDC0, 0x0009), 0x0009))
+          {
+              APPT()
+          }
+
+          //
+          // Load the CST SSDTs if:
+          //   (1) Driver supports multi-processor configurations
+          //
+          //   PDCx[3]  = OS supports C1 and P-states in MP systems
+          //   PDCx[4]  = OS supports ind. C2/C3 in MP systems
+          //
+          If(And(PDC0,0x0018))
+          {
+              APCT()
+          }
+
+          Return()
+      }
+
+      //
+      // Dynamically load the CST SSDTs if:
+      //   (1) C-States are enabled
+      //   (2) SSDT is not already loaded
+      //
+      //   CFGD[11,7,2,1] = C6, C4, C1E, C1 Capable/Enabled
+      //   SDTL[5]   = AP CST SSDT Loaded
+      //
+      Method(APCT,0)
+      {
+          If(LAnd(And(CFGD,0x82),LNot(And(SDTL,0x20))))
+          {
+              //
+              // Flag the CST SSDT as loaded for the AP's
+              //
+              Or(SDTL, 0x20, SDTL)
+              //
+              // Dynamically load the APCST SSDT
+              //
+              OperationRegion(CST1,SystemMemory,DeRefOf(Index(SSDT,10)),DeRefOf(Index(SSDT,11)))
+              Load(CST1, HC1)
+          }
+      }
+
+      //
+      // Dynamically load the IST SSDTs if:
+      //   (1) If GV3 capable and enabled
+      //   (2) SSDT is not already loaded
+      //
+      //   CFGD[0] = GV3 Capable/Enabled
+      //   SDTL[4] = AP IST SSDT Loaded
+      //
+      Method(APPT,0)
+      {
+          If(LAnd(And(CFGD,0x01),LNot(And(SDTL,0x10))))
+          {
+              //
+              // Flag the IST SSDT as loaded for CPU0
+              //
+              Or(SDTL, 0x10, SDTL)
+
+              OperationRegion(IST1,SystemMemory,DeRefOf(Index(SSDT,4)),DeRefOf(Index(SSDT,5)))
+              Load(IST1, HI1)    // Dynamically load the CPU1IST SSDT
+          }
+      }
+  }    // End CPU3
+} // End of Definition Block
+
+
+
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/PlatformBaseAddresses.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/PlatformBaseAddresses.h
new file mode 100644
index 0000000000..1d230fdecd
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/PlatformBaseAddresses.h
@@ -0,0 +1,92 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+
+
+Module Name:
+
+  PlatformBaseAddresses.h
+
+Abstract:
+
+
+
+Revision History
+
+++*/
+
+
+#ifndef _PLATFORM_BASE_ADDRESSES_H
+#define _PLATFORM_BASE_ADDRESSES_H
+
+//
+// Define some fixed platform device location information
+//
+
+//
+// Define platform base
+//
+
+//
+// SIO
+//
+#define SIO_BASE_ADDRESS                  0x0680
+#define SIO_MONITORING_BASE_ADDRESS       0x0290
+#define SIO_BASE_MASK                     0xFFF0
+#define WINDBOND_ECIR_BASE_ADDRESS        0x0810
+#define SIO_MAILBOX_BASE_ADDRESS          0x0360    // Used by EC controller
+#define SIO_EC_CHANNEL2                   0x62      // Used by EC controller for offset 0x62 and 0x66
+
+
+//
+// South Cluster
+//
+#define ACPI_BASE_ADDRESS                 0x0400
+#define GPIO_BASE_ADDRESS                 0x0500
+#define SMBUS_BUS_DEV_FUNC                0x1F0300
+#define SMBUS_BASE_ADDRESS                0xEFA0     // SMBus IO Base Address
+#define SPI_BASE_ADDRESS                  0xFED01000 // SPI Memory Base Address
+#define PMC_BASE_ADDRESS                  0xFED03000 // PMC Memory Base Address
+#define SMBM_BASE_ADDRESS                 0xFED04000 // SMBus Memory Base Address
+#define IO_BASE_ADDRESS                   0xFED0C000 // IO Memory Base Address
+#define ILB_BASE_ADDRESS                  0xFED08000 // ILB Memory Base Address
+#define HPET_BASE_ADDRESS                 0xFED00000 // HPET Base Address
+#define RCBA_BASE_ADDRESS                 0xFED1C000 // Root Complex Base Address
+#define MPHY_BASE_ADDRESS                 0xFEF00000 // MPHY Memory Base Address
+#define PUNIT_BASE_ADDRESS                0xFED05000 // PUnit Memory Base Address
+
+//
+// GPIO GROUP OFFSET
+//
+#define GPIO_SCORE_OFFSET                 0x0000
+#define GPIO_NCORE_OFFSET                 0x1000
+#define GPIO_SSUS_OFFSET                  0x2000
+
+//
+// MCH/CPU
+//
+#define DMI_BASE_ADDRESS                  0xFED18000 // 4K, similar to IIO_RCBA // modify from bearlake -- cchew10
+#define EP_BASE_ADDRESS                   0xFED19000
+#define MC_MMIO_BASE                      0xFED14000 // Base Address for MMIO registers
+
+//
+// TPM
+//
+#define TPM_BASE_ADDRESS                  0xFED40000  // Base address for TPM
+
+//
+// Local and I/O APIC addresses.
+//
+#define IO_APIC_ADDRESS                   0xFEC00000
+#define IIO_IOAPIC_ADDRESS                0xFEC90000
+#define LOCAL_APIC_ADDRESS                0xFEE00000
+
+
+#endif
+
+
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/Capsule.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/Capsule.h
new file mode 100644
index 0000000000..98485701af
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/Capsule.h
@@ -0,0 +1,60 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  Capsule.h
+
+Abstract:
+
+  Capsule PPI definitions.
+
+--*/
+//
+//
+#ifndef _PEI_CAPSULE_PPI_H_
+#define _PEI_CAPSULE_PPI_H_
+
+#define PEI_CAPSULE_PPI_GUID \
+  { \
+    0x3acf33ee, 0xd892, 0x40f4, 0xa2, 0xfc, 0x38, 0x54, 0xd2, 0xe1, 0x32, 0x3d \
+  }
+
+EFI_FORWARD_DECLARATION (PEI_CAPSULE_PPI);
+
+typedef
+EFI_STATUS
+(EFIAPI *PEI_CAPSULE_COALESCE) (
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN OUT VOID                        **MemoryBase,
+  IN OUT UINTN                       *MemSize
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *PEI_CAPSULE_CREATE_STATE) (
+  IN EFI_PEI_SERVICES                                   **PeiServices,
+  IN VOID                                               *CapsuleBase, // returned from coalesce
+  IN UINTN                              CapsuleSize                   // returned from coalesce
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *PEI_CAPSULE_CHECK_CAPSULE_UPDATE) (
+  IN EFI_PEI_SERVICES           **PeiServices
+  );
+
+typedef struct _PEI_CAPSULE_PPI {
+  PEI_CAPSULE_COALESCE              Coalesce;
+  PEI_CAPSULE_CHECK_CAPSULE_UPDATE  CheckCapsuleUpdate;
+  PEI_CAPSULE_CREATE_STATE          CreateState;
+} PEI_CAPSULE_PPI;
+
+extern EFI_GUID gPeiCapsulePpiGuid;
+
+#endif // #ifndef _PEI_CAPSULE_PPI_H_
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/PlatformMemoryRange.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/PlatformMemoryRange.h
new file mode 100644
index 0000000000..7378e2c9ca
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/PlatformMemoryRange.h
@@ -0,0 +1,144 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  PlatformMemoryRange.h
+
+Abstract:
+
+  Platform Memory Range PPI as defined in EFI 2.0
+
+  PPI for reserving special purpose memory ranges.
+
+--*/
+//
+//
+#ifndef _PEI_PLATFORM_MEMORY_RANGE_H_
+#define _PEI_PLATFORM_MEMORY_RANGE_H_
+
+#define PEI_PLATFORM_MEMORY_RANGE_PPI_GUID \
+  { \
+    0x30eb2979, 0xb0f7, 0x4d60, 0xb2, 0xdc, 0x1a, 0x2c, 0x96, 0xce, 0xb1, 0xf4 \
+  }
+
+typedef struct _PEI_PLATFORM_MEMORY_RANGE_PPI  PEI_PLATFORM_MEMORY_RANGE_PPI ;
+
+#define PEI_MEMORY_RANGE_OPTION_ROM UINT32
+
+#define PEI_MR_OPTION_ROM_ALL       0xFFFFFFFF
+#define PEI_MR_OPTION_ROM_NONE      0x00000000
+#define PEI_MR_OPTION_ROM_C0000_16K 0x00000001
+#define PEI_MR_OPTION_ROM_C4000_16K 0x00000002
+#define PEI_MR_OPTION_ROM_C8000_16K 0x00000004
+#define PEI_MR_OPTION_ROM_CC000_16K 0x00000008
+#define PEI_MR_OPTION_ROM_D0000_16K 0x00000010
+#define PEI_MR_OPTION_ROM_D4000_16K 0x00000020
+#define PEI_MR_OPTION_ROM_D8000_16K 0x00000040
+#define PEI_MR_OPTION_ROM_DC000_16K 0x00000080
+#define PEI_MR_OPTION_ROM_E0000_16K 0x00000100
+#define PEI_MR_OPTION_ROM_E4000_16K 0x00000200
+#define PEI_MR_OPTION_ROM_E8000_16K 0x00000400
+#define PEI_MR_OPTION_ROM_EC000_16K 0x00000800
+#define PEI_MR_OPTION_ROM_F0000_16K 0x00001000
+#define PEI_MR_OPTION_ROM_F4000_16K 0x00002000
+#define PEI_MR_OPTION_ROM_F8000_16K 0x00004000
+#define PEI_MR_OPTION_ROM_FC000_16K 0x00008000
+
+//
+// SMRAM Memory Range
+//
+#define PEI_MEMORY_RANGE_SMRAM      UINT32
+#define PEI_MR_SMRAM_ALL            0xFFFFFFFF
+#define PEI_MR_SMRAM_NONE           0x00000000
+#define PEI_MR_SMRAM_CACHEABLE_MASK 0x80000000
+#define PEI_MR_SMRAM_SEGTYPE_MASK   0x00FF0000
+#define PEI_MR_SMRAM_ABSEG_MASK     0x00010000
+#define PEI_MR_SMRAM_HSEG_MASK      0x00020000
+#define PEI_MR_SMRAM_TSEG_MASK      0x00040000
+//
+// If adding additional entries, SMRAM Size
+// is a multiple of 128KB.
+//
+#define PEI_MR_SMRAM_SIZE_MASK          0x0000FFFF
+#define PEI_MR_SMRAM_SIZE_128K_MASK     0x00000001
+#define PEI_MR_SMRAM_SIZE_256K_MASK     0x00000002
+#define PEI_MR_SMRAM_SIZE_512K_MASK     0x00000004
+#define PEI_MR_SMRAM_SIZE_1024K_MASK    0x00000008
+#define PEI_MR_SMRAM_SIZE_2048K_MASK    0x00000010
+#define PEI_MR_SMRAM_SIZE_4096K_MASK    0x00000020
+#define PEI_MR_SMRAM_SIZE_8192K_MASK    0x00000040
+
+#define PEI_MR_SMRAM_ABSEG_128K_NOCACHE 0x00010001
+#define PEI_MR_SMRAM_HSEG_128K_CACHE    0x80020001
+#define PEI_MR_SMRAM_HSEG_128K_NOCACHE  0x00020001
+#define PEI_MR_SMRAM_TSEG_128K_CACHE    0x80040001
+#define PEI_MR_SMRAM_TSEG_128K_NOCACHE  0x00040001
+#define PEI_MR_SMRAM_TSEG_256K_CACHE    0x80040002
+#define PEI_MR_SMRAM_TSEG_256K_NOCACHE  0x00040002
+#define PEI_MR_SMRAM_TSEG_512K_CACHE    0x80040004
+#define PEI_MR_SMRAM_TSEG_512K_NOCACHE  0x00040004
+#define PEI_MR_SMRAM_TSEG_1024K_CACHE   0x80040008
+#define PEI_MR_SMRAM_TSEG_1024K_NOCACHE 0x00040008
+
+//
+// Graphics Memory Range
+//
+#define PEI_MEMORY_RANGE_GRAPHICS_MEMORY  UINT32
+#define PEI_MR_GRAPHICS_MEMORY_ALL        0xFFFFFFFF
+#define PEI_MR_GRAPHICS_MEMORY_NONE       0x00000000
+#define PEI_MR_GRAPHICS_MEMORY_CACHEABLE  0x80000000
+//
+// If adding additional entries, Graphics Memory Size
+// is a multiple of 512KB.
+//
+#define PEI_MR_GRAPHICS_MEMORY_SIZE_MASK    0x0000FFFF
+#define PEI_MR_GRAPHICS_MEMORY_512K_NOCACHE 0x00000001
+#define PEI_MR_GRAPHICS_MEMORY_512K_CACHE   0x80000001
+#define PEI_MR_GRAPHICS_MEMORY_1M_NOCACHE   0x00000002
+#define PEI_MR_GRAPHICS_MEMORY_1M_CACHE     0x80000002
+#define PEI_MR_GRAPHICS_MEMORY_4M_NOCACHE   0x00000008
+#define PEI_MR_GRAPHICS_MEMORY_4M_CACHE     0x80000008
+#define PEI_MR_GRAPHICS_MEMORY_8M_NOCACHE   0x00000010
+#define PEI_MR_GRAPHICS_MEMORY_8M_CACHE     0x80000010
+#define PEI_MR_GRAPHICS_MEMORY_16M_NOCACHE  0x00000020
+#define PEI_MR_GRAPHICS_MEMORY_16M_CACHE    0x80000020
+#define PEI_MR_GRAPHICS_MEMORY_32M_NOCACHE  0x00000040
+#define PEI_MR_GRAPHICS_MEMORY_32M_CACHE    0x80000040
+#define PEI_MR_GRAPHICS_MEMORY_48M_NOCACHE  0x00000060
+#define PEI_MR_GRAPHICS_MEMORY_48M_CACHE    0x80000060
+#define PEI_MR_GRAPHICS_MEMORY_64M_NOCACHE  0x00000080
+#define PEI_MR_GRAPHICS_MEMORY_64M_CACHE    0x80000080
+#define PEI_MR_GRAPHICS_MEMORY_128M_NOCACHE 0x00000100
+#define PEI_MR_GRAPHICS_MEMORY_128M_CACHE   0x80000100
+#define PEI_MR_GRAPHICS_MEMORY_256M_NOCACHE 0x00000200
+#define PEI_MR_GRAPHICS_MEMORY_256M_CACHE   0x80000200
+//
+// Pci Memory Hole
+//
+#define PEI_MEMORY_RANGE_PCI_MEMORY       UINT32
+#define PEI_MR_PCI_MEMORY_SIZE_512M_MASK  0x00000001
+
+typedef
+EFI_STATUS
+(EFIAPI *PEI_CHOOSE_RANGES) (
+  IN      EFI_PEI_SERVICES                      **PeiServices,
+  IN PEI_PLATFORM_MEMORY_RANGE_PPI              * This,
+  IN OUT  PEI_MEMORY_RANGE_OPTION_ROM           * OptionRomMask,
+  IN OUT  PEI_MEMORY_RANGE_SMRAM                * SmramMask,
+  IN OUT  PEI_MEMORY_RANGE_GRAPHICS_MEMORY      * GraphicsMemoryMask,
+  IN OUT  PEI_MEMORY_RANGE_PCI_MEMORY           * PciMemoryMask
+  );
+
+struct _PEI_PLATFORM_MEMORY_RANGE_PPI {
+  PEI_CHOOSE_RANGES ChooseRanges;
+};
+
+extern EFI_GUID gPeiPlatformMemoryRangePpiGuid;
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/PlatformMemorySize.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/PlatformMemorySize.h
new file mode 100644
index 0000000000..b19a178732
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/PlatformMemorySize.h
@@ -0,0 +1,46 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+Module Name:
+
+  PlatformMemorySize.h
+
+Abstract:
+
+  Platform Memory Size PPI as defined in Tiano
+
+  PPI for describing the minimum platform memory size in order to successfully
+  pass control into DXE
+
+--*/
+//
+//
+#ifndef _PEI_PLATFORM_MEMORY_SIZE_H_
+#define _PEI_PLATFORM_MEMORY_SIZE_H_
+
+#define PEI_PLATFORM_MEMORY_SIZE_PPI_GUID \
+  { \
+    0x9a7ef41e, 0xc140, 0x4bd1, 0xb8, 0x84, 0x1e, 0x11, 0x24, 0xb, 0x4c, 0xe6 \
+  }
+
+EFI_FORWARD_DECLARATION (PEI_PLATFORM_MEMORY_SIZE_PPI);
+
+typedef
+EFI_STATUS
+(EFIAPI *PEI_GET_MINIMUM_PLATFORM_MEMORY_SIZE) (
+  IN      EFI_PEI_SERVICES                       **PeiServices,
+  IN PEI_PLATFORM_MEMORY_SIZE_PPI                * This,
+  IN OUT  UINT64                                 *MemorySize
+  );
+
+typedef struct _PEI_PLATFORM_MEMORY_SIZE_PPI {
+  PEI_GET_MINIMUM_PLATFORM_MEMORY_SIZE  GetPlatformMemorySize;
+} PEI_PLATFORM_MEMORY_SIZE_PPI;
+
+extern EFI_GUID gPeiPlatformMemorySizePpiGuid;
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/SmmAccess.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/SmmAccess.h
new file mode 100644
index 0000000000..dda3f8cabe
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/SmmAccess.h
@@ -0,0 +1,165 @@
+//
+//
+/*++
+
+Copyright (c)  2009  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  SmmAccess.h
+
+Abstract:
+
+  SmmAccess PPI
+
+  This code abstracts the PEI core to provide SmmAccess services.
+
+--*/
+
+#ifndef _PEI_SMM_ACCESS_PPI_H_
+#define _PEI_SMM_ACCESS_PPI_H_
+
+#ifdef ECP_FLAG
+#include "Guid/SmramMemoryReserve/SmramMemoryReserve.h"
+#else
+#include "Guid/SmramMemoryReserve.h"
+#endif
+
+#define PEI_SMM_ACCESS_PPI_GUID \
+  { \
+    0x268f33a9, 0xcccd, 0x48be, 0x88, 0x17, 0x86, 0x5, 0x3a, 0xc3, 0x2e, 0xd6 \
+  }
+
+typedef struct _PEI_SMM_ACCESS_PPI PEI_SMM_ACCESS_PPI;
+
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SMM_OPEN) (
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN PEI_SMM_ACCESS_PPI              *This,
+  IN UINTN                           DescriptorIndex
+  )
+/*++
+
+  Routine Description:
+    This routine accepts a request to "open" a region of SMRAM.  The
+    region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
+    The use of "open" means that the memory is visible from all PEIM
+    and SMM agents.
+
+  Arguments:
+    PeiServices           - General purpose services available to every PEIM.
+    This                  - Pointer to the SMM Access Interface.
+    DescriptorIndex       - Region of SMRAM to Open.
+
+  Returns:
+    EFI_SUCCESS           - The region was successfully opened.
+    EFI_DEVICE_ERROR      - The region could not be opened because locked by
+                            chipset.
+    EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+--*/
+;
+
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SMM_CLOSE) (
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN PEI_SMM_ACCESS_PPI              *This,
+  IN UINTN                           DescriptorIndex
+  )
+/*++
+
+  Routine Description:
+    This routine accepts a request to "close" a region of SMRAM.  The
+    region could be legacy AB or TSEG near top of physical memory.
+    The use of "close" means that the memory is only visible from SMM agents,
+    not from PEIM.
+
+  Arguments:
+    PeiServices           - General purpose services available to every PEIM.
+    This                  - Pointer to the SMM Access Interface.
+    DescriptorIndex       - Region of SMRAM to Close.
+
+  Returns:
+    EFI_SUCCESS           - The region was successfully closed.
+    EFI_DEVICE_ERROR      - The region could not be closed because locked by
+                              chipset.
+    EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+
+--*/
+;
+
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SMM_LOCK) (
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN PEI_SMM_ACCESS_PPI              *This,
+  IN UINTN                           DescriptorIndex
+  )
+/*++
+
+  Routine Description:
+    This routine accepts a request to "lock" SMRAM.  The
+    region could be legacy AB or TSEG near top of physical memory.
+    The use of "lock" means that the memory can no longer be opened
+    to PEIM.
+
+  Arguments:
+    PeiServices           - General purpose services available to every PEIM.
+    This                  - Pointer to the SMM Access Interface.
+    DescriptorIndex       - Region of SMRAM to Lock.
+
+  Returns:
+    EFI_SUCCESS           - The region was successfully locked.
+    EFI_DEVICE_ERROR      - The region could not be locked because at least
+                            one range is still open.
+    EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+
+--*/
+;
+
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SMM_CAPABILITIES) (
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN PEI_SMM_ACCESS_PPI              *This,
+  IN OUT UINTN                       *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
+  )
+/*++
+
+  Routine Description:
+    This routine services a user request to discover the SMRAM
+    capabilities of this platform.  This will report the possible
+    ranges that are possible for SMRAM access, based upon the
+    memory controller capabilities.
+
+  Arguments:
+    PeiServices           - General purpose services available to every PEIM.
+    This                  - Pointer to the SMRAM Access Interface.
+    SmramMapSize          - Pointer to the variable containing size of the
+                              buffer to contain the description information.
+    SmramMap              - Buffer containing the data describing the Smram
+                              region descriptors.
+  Returns:
+    EFI_BUFFER_TOO_SMALL  - The user did not provide a sufficient buffer.
+    EFI_SUCCESS           - The user provided a sufficiently-sized buffer.
+--*/
+;
+
+struct _PEI_SMM_ACCESS_PPI {
+  PEI_SMM_OPEN          Open;
+  PEI_SMM_CLOSE         Close;
+  PEI_SMM_LOCK          Lock;
+  PEI_SMM_CAPABILITIES  GetCapabilities;
+  BOOLEAN               LockState;
+  BOOLEAN               OpenState;
+};
+
+extern EFI_GUID gPeiSmmAccessPpiGuid;
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/VlvMmioPolicy.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/VlvMmioPolicy.h
new file mode 100644
index 0000000000..0d359e6062
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/VlvMmioPolicy.h
@@ -0,0 +1,39 @@
+
+/*++
+
+Copyright (c)  2010  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+Module Name:
+
+  VlvMmioPolicy.h
+
+Abstract:
+
+  Interface definition details between ValleyView platform drivers during PEI phase.
+
+--*/
+
+#ifndef _VLV_MMIO_POLICY_PPI_H_
+#define _VLV_MMIO_POLICY_PPI_H_
+
+#define VLV_MMIO_POLICY_PPI_GUID \
+  { \
+    0xE767BF7F, 0x4DB6, 0x5B34, 0x10, 0x11, 0x4F, 0xBE, 0x4C, 0xA7, 0xAF, 0xD2 \
+  }
+
+extern EFI_GUID gVlvMmioPolicyPpiGuid;
+
+
+//
+// MRC Platform Policiy PPI
+//
+typedef struct _VLV_MMIO_POLICY_PPI {
+  UINT16                 MmioSize;
+} VLV_MMIO_POLICY_PPI;
+
+#pragma pack()
+
+#endif // _VLV_MMIO_POLICY_PPI_H_
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/VlvPeiInit.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/VlvPeiInit.h
new file mode 100644
index 0000000000..f9f8e816f5
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/VlvPeiInit.h
@@ -0,0 +1,35 @@
+
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+Module Name:
+
+  VlvPeiInit.h
+
+Abstract:
+
+  Interface definition between ValleyView MRC and VlvInitPeim driver..
+
+--*/
+
+#ifndef _VLV_PEI_INIT_H_
+#define _VLV_PEI_INIT_H_
+
+//
+// Define the VLV PEI Init PPI GUID
+//
+#define VLV_PEI_INIT_PPI_GUID \
+  { \
+    0x9ea8911, 0xbe0d, 0x4230, 0xa0, 0x3, 0xed, 0xc6, 0x93, 0xb4, 0x8e, 0x11 \
+  }
+
+//
+// Extern the GUID for PPI users.
+//
+extern EFI_GUID     gVlvPeiInitPpiGuid;
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/VlvPolicy.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/VlvPolicy.h
new file mode 100644
index 0000000000..07ebfe3fb1
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Ppi/VlvPolicy.h
@@ -0,0 +1,106 @@
+
+/*++
+
+Copyright (c)  2010  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+Module Name:
+
+  VlvPolicy.h
+
+Abstract:
+
+  Interface definition details between ValleyView MRC and platform drivers during PEI phase.
+
+--*/
+
+#ifndef _VLV_POLICY_PPI_H_
+#define _VLV_POLICY_PPI_H_
+
+//
+// MRC Policy provided by platform for PEI phase {7D84B2C2-22A1-4372-B12C-EBB232D3A6A3}
+//
+#define VLV_POLICY_PPI_GUID \
+  { \
+    0x7D84B2C2, 0x22A1, 0x4372, 0xB1, 0x2C, 0xEB, 0xB2, 0x32, 0xD3, 0xA6, 0xA3 \
+  }
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gVlvPolicyPpiGuid;
+
+//
+// PPI revision number
+// Any backwards compatible changes to this PPI will result in an update in the revision number
+// Major changes will require publication of a new PPI
+//
+#define MRC_PLATFORM_POLICY_PPI_REVISION  1
+
+#ifndef MAX_SOCKETS
+#define MAX_SOCKETS 4
+#endif
+
+#define S3_TIMING_DATA_LEN          9
+#define S3_READ_TRAINING_DATA_LEN   16
+#define S3_WRITE_TRAINING_DATA_LEN  12
+
+#ifndef S3_RESTORE_DATA_LEN
+#define S3_RESTORE_DATA_LEN (S3_TIMING_DATA_LEN + S3_READ_TRAINING_DATA_LEN + S3_WRITE_TRAINING_DATA_LEN)
+#endif // S3_RESTORE_DATA_LEN
+#pragma pack(1)
+//
+// MRC Platform Data Structure
+//
+typedef struct {
+  UINT8   SpdAddressTable[MAX_SOCKETS];
+  UINT8   TSonDimmSmbusAddress[MAX_SOCKETS];
+
+  UINT16  SmbusBar;
+  UINT32  IchRcba;
+  UINT32  WdbBaseAddress; // Write Data Buffer area (WC caching mode)
+  UINT32  WdbRegionSize;
+  UINT32  SmBusAddress;
+  UINT8   UserBd;
+  UINT8   PlatformType;
+  UINT8   FastBoot;
+  UINT8   DynSR;
+} VLV_PLATFORM_DATA;
+
+
+typedef struct {
+  UINT16  MmioSize;
+  UINT16  GttSize;
+  UINT8   IgdDvmt50PreAlloc;
+  UINT8   PrimaryDisplay;
+  UINT8   PAVPMode;
+  UINT8   ApertureSize;
+  UINT8   InternalGraphics;
+  UINT8   IgdTurboEn;
+} GT_CONFIGURATION;
+
+typedef struct {
+  UINT8   EccSupport;
+  UINT16  DdrFreqLimit;
+  UINT8   MaxTolud;
+} MEMORY_CONFIGURATION;
+
+
+//
+// MRC Platform Policiy PPI
+//
+typedef struct _VLV_POLICY_PPI {
+  UINT8                 Revision;
+  VLV_PLATFORM_DATA      PlatformData;
+  GT_CONFIGURATION      GtConfig;
+  MEMORY_CONFIGURATION  MemConfig;
+  VOID                  *S3DataPtr; // was called MRC_PARAMS_SAVE_RESTORE
+  UINT8                 ISPEn;            //ISP (IUNIT) Device Enabled
+  UINT8                 ISPPciDevConfig;  //ISP (IUNIT) Device Config: 0->B0/D2/F0 for Window OS, 1->B0D3/F0 for Linux OS
+} VLV_POLICY_PPI;
+
+#pragma pack()
+
+#endif // _VLV_POLICY_PPI_H_
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Protocol/IgdOpRegion.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Protocol/IgdOpRegion.h
new file mode 100644
index 0000000000..5cf15be3c7
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Protocol/IgdOpRegion.h
@@ -0,0 +1,213 @@
+
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+Module Name:
+
+  IgdOpRegion.h
+
+Abstract:
+
+  This file is part of the IGD OpRegion Implementation.  The IGD OpRegion is
+  an interface between system BIOS, ASL code, and Graphics drivers.
+
+  Supporting Specifiction: IGD OpRegion/Software SCI SPEC
+
+  Note:  Data structures defined in this protocol are packed not naturally
+    aligned.
+
+  GUID forms:
+    {CDC5DDDF-E79D-41ec-A9B0-6565490DB9D3}
+    (0xcdc5dddf, 0xe79d, 0x41ec, 0xa9, 0xb0, 0x65, 0x65, 0x49, 0xd, 0xb9, 0xd3);
+
+  Acronyms:
+    NVS:        ACPI Non Volatile Storage
+    OpRegion:   ACPI Operational Region
+    VBT:        Video BIOS Table (OEM customizable data)
+
+--*/
+
+#ifndef _IGD_OPREGION_PROTOCOL_H_
+#define _IGD_OPREGION_PROTOCOL_H_
+
+//
+// OpRegion / Software SCI protocol GUID
+//
+#define IGD_OPREGION_PROTOCOL_GUID \
+  { \
+    0xcdc5dddf, 0xe79d, 0x41ec, 0xa9, 0xb0, 0x65, 0x65, 0x49, 0xd, 0xb9, 0xd3 \
+  }
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gIgdOpRegionProtocolGuid;
+
+//
+// Forward reference for pure ANSI compatability
+//
+typedef struct _IGD_OPREGION_PROTOCOL IGD_OPREGION_PROTOCOL;
+
+//
+// Protocol data definitions
+//
+
+//
+// OpRegion structures:
+// Sub-structures define the different parts of the OpRegion followed by the
+// main structure representing the entire OpRegion.
+//
+// Note: These structures are packed to 1 byte offsets because the exact
+// data location is requred by the supporting design specification due to
+// the fact that the data is used by ASL and Graphics driver code compiled
+// separatly.
+//
+
+//
+// OpRegion header (mailbox 0) structure and #defines.
+//
+#pragma pack (1)
+typedef struct {
+  CHAR8   SIGN[0x10]; // 0      OpRegion signature
+  UINT32  SIZE;       // 0x10   OpRegion size
+  UINT32  OVER;       // 0x14   OpRegion structure version
+  UINT8   SVER[0x20]; // 0x18   System BIOS build version
+  UINT8   VVER[0x10]; // 0x38   Video BIOS build version
+  UINT8   GVER[0x10]; // 0x48   Graphic driver build version
+  UINT32  MBOX;       // 0x58   Mailboxes supported
+  UINT32  DMOD;       // 0x5C   Driver Model
+  UINT32  PCON;       // 0x60   Platform Configuration Info
+  CHAR8   GOPV[0x20]; // 0X64   GOP build version
+  UINT8   RSV[0x7C];  //        Reserved
+} OPREGION_HEADER;
+#pragma pack ()
+
+//
+// OpRegion mailbox 1 (public ACPI Methods).
+//
+#pragma pack (1)
+typedef struct {
+  UINT32  DRDY;     // 0    Driver readiness
+  UINT32  CSTS;     // 4    Status
+  UINT32  CEVT;     // 8    Current event
+  UINT8   RM11[0x14]; // 12   Reserved
+  UINT32  DIDL;       // 32   Supported display devices list
+  UINT32  DDL2;       //  8 Devices.
+  UINT32  DDL3;
+  UINT32  DDL4;
+  UINT32  DDL5;
+  UINT32  DDL6;
+  UINT32  DDL7;
+  UINT32  DDL8;
+  UINT32  CPDL;       // 64   Currently present display devices list
+  UINT32  CPL2;       //  8 Devices.
+  UINT32  CPL3;
+  UINT32  CPL4;
+  UINT32  CPL5;
+  UINT32  CPL6;
+  UINT32  CPL7;
+  UINT32  CPL8;
+  UINT32  CADL;       // 96   Currently active display devices list
+  UINT32  CAL2;       //  8 Devices.
+  UINT32  CAL3;
+  UINT32  CAL4;
+  UINT32  CAL5;
+  UINT32  CAL6;
+  UINT32  CAL7;
+  UINT32  CAL8;
+  UINT32  NADL;       // 128  Next active device list
+  UINT32  NDL2;       //   8 Devices.
+  UINT32  NDL3;
+  UINT32  NDL4;
+  UINT32  NDL5;
+  UINT32  NDL6;
+  UINT32  NDL7;
+  UINT32  NDL8;
+  UINT32  ASLP;     // 160  ASL sleep timeout
+  UINT32  TIDX;     // 164  Toggle table index
+  UINT32  CHPD;     // 168  Current hot plug enable indicator
+  UINT32  CLID;     // 172  Current lid state indicator
+  UINT32  CDCK;     // 176  Current docking state indicator
+  UINT32  SXSW;     // 180  Display Switch notification on Sx State resume
+  UINT32  EVTS;     // 184  Events supported by ASL
+  UINT32  CNOT;     // 188  Current OS Notification
+  UINT32  NRDY;     // 192  Reasons for DRDY = 0
+  UINT8   RM12[0x3C]; // 196  Reserved
+} OPREGION_MBOX1;
+#pragma pack ()
+
+//
+// OpRegion mailbox 2 (Software SCI Interface).
+//
+#pragma pack (1)
+typedef struct {
+  UINT32  SCIC;       // 0    Software SCI function number parameters
+  UINT32  PARM;       // 4    Software SCI additional parameters
+  UINT32  DSLP;       // 8    Driver sleep timeout
+  UINT8   RM21[0xF4]; // 12   Reserved
+} OPREGION_MBOX2;
+#pragma pack ()
+
+//
+// OpRegion mailbox 3 (Power Conservation).
+//
+#pragma pack (1)
+typedef struct {
+  UINT32  ARDY;       // 0    Driver readiness
+  UINT32  ASLC;       // 4    ASLE interrupt command / status
+  UINT32  TCHE;       // 8    Technology enabled indicator
+  UINT32  ALSI;       // 12   Current ALS illuminance reading
+  UINT32  BCLP;       // 16   Backlight britness to set
+  UINT32  PFIT;       // 20   Panel fitting Current State or Request
+  UINT32  CBLV;       // 24   Brightness Current State
+  UINT16  BCLM[0x14]; // 28   Backlight Brightness Level Duty Cycle Mapping Table
+  UINT32  CPFM;       // 68   Panel Fitting Current Mode
+  UINT32  EPFM;       // 72   Enabled Panel Fitting Mode
+  UINT8   PLUT[0x4A]; // 76   Panel Look Up Table
+  UINT32  PFMB;       // 150  PWM Frequency and Minimum Brightness
+  UINT32  CCDV;       // 154  Color Correction Default Values
+  UINT32  PCFT;       // 158  Power Conservation Features
+  UINT8   RM31[0x5E]; // 162  Reserved
+} OPREGION_MBOX3;
+#pragma pack ()
+
+//
+// OpRegion mailbox 4 (VBT).
+//
+#pragma pack (1)
+typedef struct {
+  UINT8 GVD1[0x1800]; // 6K Reserved
+} OPREGION_VBT;
+#pragma pack ()
+
+#pragma pack (1)
+typedef struct {
+  UINT8 EDIDOVRD[0x400]; // 6K Edid overriding data
+} OPREGION_MBOX5;
+#pragma pack ()
+//
+// Entire OpRegion
+//
+#pragma pack (1)
+typedef struct {
+  OPREGION_HEADER  Header; // OpRegion header
+  OPREGION_MBOX1   MBox1;  // Mailbox 1: Public ACPI Methods
+  OPREGION_MBOX2   MBox2;  // Mailbox 2: Software SCI Inteface
+  OPREGION_MBOX3   MBox3;  // Mailbox 3: Power Conservation
+  OPREGION_VBT        VBT;    // VBT: Video BIOS Table (OEM customizable data)
+  OPREGION_MBOX5   MBox5;
+} IGD_OPREGION_STRUC;
+#pragma pack ()
+
+//
+// Protocol data structure definition
+//
+struct _IGD_OPREGION_PROTOCOL {
+  IGD_OPREGION_STRUC    *OpRegion;
+};
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Protocol/MemInfo.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Protocol/MemInfo.h
new file mode 100644
index 0000000000..f5a51e03b0
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Protocol/MemInfo.h
@@ -0,0 +1,83 @@
+
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+Module Name:
+
+  MemInfo.h
+
+Abstract:
+
+  This protocol provides the memory information data, such as
+  total physical memory size, memory frequency, memory size
+  of each dimm and rank.
+
+  This protocol is EFI compatible.
+
+--*/
+
+#ifndef _MEM_INFO_PROTOCOL_H_
+#define _MEM_INFO_PROTOCOL_H_
+
+//
+// Define the  protocol GUID
+//
+#define MEM_INFO_PROTOCOL_GUID \
+  { \
+    0x6f20f7c8, 0xe5ef, 0x4f21, 0x8d, 0x19, 0xed, 0xc5, 0xf0, 0xc4, 0x96, 0xae \
+  }
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID                   gMemInfoProtocolGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _MEM_INFO_PROTOCOL MEM_INFO_PROTOCOL;
+
+//
+// Protocol definitions
+//
+
+#define CH_NUM    2
+#define DIMM_NUM  1
+#define RANK_NUM  2
+
+#pragma pack(1)
+typedef struct {
+  UINT32  memSize;
+  UINT8   ddrFreq;
+  UINT8   ddrType;
+  BOOLEAN EccSupport;
+  UINT16  dimmSize[CH_NUM * DIMM_NUM];
+  UINT8   reserved;
+  UINT16   reserved2;
+} MEMORY_INFO_DATA;
+#pragma pack()
+
+/*++
+Data definition:
+
+  memSize         Total physical memory size
+  ddrFreq         DDR Frequency
+  EccSupport      ECC Support
+  dimmSize        Dimm Size
+  DimmExist       Dimm Present or not
+  RankInDimm      No. of ranks in a dimm
+
+--*/
+
+//
+// Protocol definition
+//
+struct _MEM_INFO_PROTOCOL {
+  MEMORY_INFO_DATA  MemInfoData;
+};
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Protocol/PlatformGopPolicy.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Protocol/PlatformGopPolicy.h
new file mode 100644
index 0000000000..a862e505bc
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Protocol/PlatformGopPolicy.h
@@ -0,0 +1,67 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+--*/
+
+/** @file
+**/
+
+#ifndef _PLATFORM_GOP_POLICY_PROTOCOL_H_
+#define _PLATFORM_GOP_POLICY_PROTOCOL_H_
+
+#define EFI_PLATFORM_GOP_POLICY_PROTOCOL_GUID \
+  { 0xec2e931b, 0x3281, 0x48a5, 0x81, 0x7, 0xdf, 0x8a, 0x8b, 0xed, 0x3c, 0x5d }
+
+#define EFI_BMP_IMAGE_GUID \
+  { 0x878AC2CC, 0x5343, 0x46F2, 0xB5, 0x63, 0x51, 0xF8, 0x9D, 0xAF, 0x56, 0xBA }
+
+#define PLATFORM_GOP_POLICY_PROTOCOL_REVISION_01 0x01
+#define PLATFORM_GOP_POLICY_PROTOCOL_REVISION_02 x0222
+
+#pragma pack(1)
+
+typedef enum {
+  LidClosed,
+  LidOpen,
+  LidStatusMax
+} LID_STATUS;
+
+typedef enum {
+  Docked,
+  UnDocked,
+  DockStatusMax
+} DOCK_STATUS;
+
+typedef
+EFI_STATUS
+(EFIAPI *GET_PLATFORM_LID_STATUS) (
+  OUT LID_STATUS *CurrentLidStatus
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *GET_VBT_DATA) (
+  OUT EFI_PHYSICAL_ADDRESS *VbtAddress,
+  OUT UINT32 *VbtSize
+  );
+
+#pragma pack()
+
+typedef struct _PLATFORM_GOP_POLICY_PROTOCOL {
+  UINT32                             Revision;
+  GET_PLATFORM_LID_STATUS            GetPlatformLidStatus;
+  GET_VBT_DATA                       GetVbtData;
+} PLATFORM_GOP_POLICY_PROTOCOL;
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID  gPlatformGOPPolicyGuid;
+
+extern EFI_GUID  gBmpImageGuid;
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Protocol/VlvPlatformPolicy.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Protocol/VlvPlatformPolicy.h
new file mode 100644
index 0000000000..93756c5dea
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Protocol/VlvPlatformPolicy.h
@@ -0,0 +1,105 @@
+
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+Module Name:
+
+  VlvPlatformPolicy.h
+
+Abstract:
+
+  Interface definition details between MCH and platform drivers during DXE phase.
+
+--*/
+
+#ifndef _VLV_PLATFORM_POLICY_H_
+#define _VLV_PLATFORM_POLICY_H_
+
+//
+// VLV Policy provided by platform for DXE phase {5BAB88BA-E0E2-4674-B6AD-B812F6881CD6}
+//
+#define DXE_VLV_PLATFORM_POLICY_GUID \
+  {0x5bab88ba, 0xe0e2, 0x4674, 0xb6, 0xad, 0xb8, 0x12, 0xf6, 0x88, 0x1c, 0xd6}
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gDxeVlvPlatformPolicyGuid;
+
+//
+// Protocol revision number
+// Any backwards compatible changes to this protocol will result in an update in the revision number
+// Major changes will require publication of a new protocol
+//
+#define DXE_VLV_PLATFORM_POLICY_PROTOCOL_REVISION 0
+
+
+typedef struct {
+  UINT8  PFITStatus;
+  UINT8  IgdTheramlSupport;
+  UINT8  ALSEnabled;
+  UINT8  LidStatus;
+} IGD_PANEL_FEATURES;
+
+typedef struct {
+  UINT8   Reserved00;                     
+  UINT8   Reserved01;                     
+  UINT16  Reserved02;  
+  UINT16  Reserved03; 
+  UINT16  Reserved04; 
+  UINT16  Reserved05;  
+  UINT16  Reserved06;  
+  UINT16  Reserved07; 
+  UINT16  Reserved08; 
+  UINT16  Reserved09;  
+  UINT16  Reserved0A; 
+  UINT16  Reserved0B;
+  UINT16  Reserved0C;
+  UINT16  Reserved0D;
+  UINT8   Reserved0E;
+  UINT8   Reserved0F;
+  UINT32  Reserved10;
+  UINT32  Reserved11;
+  UINT32  Reserved12;
+  UINT32  Reserved13;
+  UINT32  Reserved14;
+  UINT8   Reserved15;
+  UINT8   Reserved16;
+} DPTF_SETTINGS;
+
+//
+// MCH DXE Platform Policiy ==================================================
+//
+
+#define NO_AUDIO   0
+#define HD_AUDIO   1
+#define LPE_AUDIO  2
+
+typedef struct _DXE_VLV_PLATFORM_POLICY_PROTOCOL {
+  UINT8                   Revision;
+  IGD_PANEL_FEATURES      IgdPanelFeatures;
+  DPTF_SETTINGS           Reserved;
+  UINT8                   GraphicReserve00;
+  UINT8                   GraphicsPerfAnalyzers;
+  UINT8                   PwmReserved00;
+  UINT8                   PwmReserved01;  
+  UINT8                   PmSupport;
+  UINT8                   GraphicReserve01;
+  UINT8                   GfxPause;
+  UINT8                   GraphicsFreqReq;
+  UINT8                   GraphicReserve03;
+  UINT8                   GraphicReserve02;
+  UINT8                   GraphicReserve04;
+  UINT8                   PavpMode;
+  UINT8                   GraphicReserve05;
+  UINT8                   UlClockGating;
+  UINT8                   IdleReserve;
+  UINT8                   AudioTypeSupport;
+  UINT8                   GraphicReserve06;
+} DXE_VLV_PLATFORM_POLICY_PROTOCOL;
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Valleyview.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Valleyview.h
new file mode 100644
index 0000000000..589e30b1a8
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Valleyview.h
@@ -0,0 +1,55 @@
+
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  Valleyview.h
+
+Abstract:
+
+  This header file provides common definitions just for Valleyview-SOC using to avoid including extra module's file.
+--*/
+
+#ifndef _MC_H_INCLUDED_
+#define _MC_H_INCLUDED_
+/*
+< Extended Configuration Base Address.*/
+#define EC_BASE             0xE0000000
+
+//
+// DEVICE 0 (Memroy Controller Hub)
+//
+#define MC_BUS          0x00
+#define MC_DEV          0x00
+#define MC_DEV2         0x02
+#define MC_FUN          0x00
+// NC DEV 0 Vendor and Device IDs
+#define MC_VID          0x8086
+#define MC_DID_OFFSET   0x2         //Device Identification
+#define MC_GGC_OFFSET   0x50        //GMCH Graphics Control Register
+
+//
+// Device 2 Register Equates
+//
+#define IGD_BUS             0x00
+#define IGD_DEV             0x02
+#define IGD_FUN_0           0x00
+#define IGD_FUN_1           0x01
+#define IGD_DEV_FUN         (IGD_DEV << 3)
+#define IGD_BUS_DEV_FUN     (MC_BUS << 8) + IGD_DEV_FUN
+#define IGD_VID             0x8086
+#define IGD_DID             0xA001
+#define IGD_MGGC_OFFSET     0x0050      //GMCH Graphics Control Register 0x50
+#define IGD_BSM_OFFSET      0x005C      //Base of Stolen Memory
+#define IGD_SWSCI_OFFSET    0x00E0      //Software SCI 0xE0 2
+#define IGD_ASLE_OFFSET     0x00E4      //System Display Event Register 0xE4 4
+#define IGD_ASLS_OFFSET     0x00FC      // ASL Storage
+#define IGD_DID_QS          0x0BE2      //RCOverride -a: Fix the DID error
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/VlvAccess.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/VlvAccess.h
new file mode 100644
index 0000000000..d471921edc
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/VlvAccess.h
@@ -0,0 +1,254 @@
+
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  vlvAccess.h
+
+Abstract:
+
+  Macros to simplify and abstract the interface to PCI configuration.
+
+--*/
+
+#ifndef _VLVACCESS_H_INCLUDED_
+#define _VLVACCESS_H_INCLUDED_
+
+#include "Valleyview.h"
+#include "VlvCommonDefinitions.h"
+#include <Library/IoLib.h>
+
+//
+// Memory Mapped IO access macros used by MSG BUS LIBRARY
+//
+#define MmioAddress( BaseAddr, Register ) \
+  ( (UINTN)BaseAddr + \
+    (UINTN)(Register) \
+  )
+
+
+//
+// UINT32
+//
+
+#define Mmio32Ptr( BaseAddr, Register ) \
+  ( (volatile UINT32 *)MmioAddress( BaseAddr, Register ) )
+
+#define Mmio32( BaseAddr, Register ) \
+  *Mmio32Ptr( BaseAddr, Register )
+
+#define Mmio32Or( BaseAddr, Register, OrData ) \
+  Mmio32( BaseAddr, Register ) = \
+    (UINT32) ( \
+      Mmio32( BaseAddr, Register ) | \
+      (UINT32)(OrData) \
+    )
+
+#define Mmio32And( BaseAddr, Register, AndData ) \
+  Mmio32( BaseAddr, Register ) = \
+    (UINT32) ( \
+      Mmio32( BaseAddr, Register ) & \
+      (UINT32)(AndData) \
+    )
+
+#define Mmio32AndThenOr( BaseAddr, Register, AndData, OrData ) \
+  Mmio32( BaseAddr, Register ) = \
+    (UINT32) ( \
+      ( Mmio32( BaseAddr, Register ) & \
+          (UINT32)(AndData) \
+      ) | \
+      (UINT32)(OrData) \
+    )
+
+//
+// UINT16
+//
+
+#define Mmio16Ptr( BaseAddr, Register ) \
+  ( (volatile UINT16 *)MmioAddress( BaseAddr, Register ) )
+
+#define Mmio16( BaseAddr, Register ) \
+  *Mmio16Ptr( BaseAddr, Register )
+
+#define Mmio16Or( BaseAddr, Register, OrData ) \
+  Mmio16( BaseAddr, Register ) = \
+    (UINT16) ( \
+      Mmio16( BaseAddr, Register ) | \
+      (UINT16)(OrData) \
+    )
+
+#define Mmio16And( BaseAddr, Register, AndData ) \
+  Mmio16( BaseAddr, Register ) = \
+    (UINT16) ( \
+      Mmio16( BaseAddr, Register ) & \
+      (UINT16)(AndData) \
+    )
+
+#define Mmio16AndThenOr( BaseAddr, Register, AndData, OrData ) \
+  Mmio16( BaseAddr, Register ) = \
+    (UINT16) ( \
+      ( Mmio16( BaseAddr, Register ) & \
+          (UINT16)(AndData) \
+      ) | \
+      (UINT16)(OrData) \
+    )
+
+//
+// UINT8
+//
+
+#define Mmio8Ptr( BaseAddr, Register ) \
+  ( (volatile UINT8 *)MmioAddress( BaseAddr, Register ) )
+
+#define Mmio8( BaseAddr, Register ) \
+  *Mmio8Ptr( BaseAddr, Register )
+
+#define Mmio8Or( BaseAddr, Register, OrData ) \
+  Mmio8( BaseAddr, Register ) = \
+    (UINT8) ( \
+      Mmio8( BaseAddr, Register ) | \
+      (UINT8)(OrData) \
+    )
+
+#define Mmio8And( BaseAddr, Register, AndData ) \
+  Mmio8( BaseAddr, Register ) = \
+    (UINT8) ( \
+      Mmio8( BaseAddr, Register ) & \
+      (UINT8)(AndData) \
+    )
+
+#define Mmio8AndThenOr( BaseAddr, Register, AndData, OrData ) \
+  Mmio8( BaseAddr, Register ) = \
+    (UINT8) ( \
+      ( Mmio8( BaseAddr, Register ) & \
+          (UINT8)(AndData) \
+        ) | \
+      (UINT8)(OrData) \
+    )
+
+//
+// MSG BUS API
+//
+
+#define MSG_BUS_ENABLED     0x000000F0
+#define MSGBUS_MASKHI       0xFFFFFF00
+#define MSGBUS_MASKLO       0x000000FF
+
+#define MESSAGE_BYTE_EN          BIT4
+#define MESSAGE_WORD_EN          BIT4 | BIT5
+#define MESSAGE_DWORD_EN         BIT4 | BIT5 | BIT6 | BIT7
+
+#define SIDEBAND_OPCODE          0x78
+#define MEMREAD_OPCODE           0x00000000
+#define MEMWRITE_OPCODE          0x01000000
+
+
+
+/***************************/
+//
+// Memory mapped PCI IO
+//
+
+#define PciCfgPtr(Bus, Device, Function, Register )\
+    (UINTN)(Bus << 20) + \
+    (UINTN)(Device << 15) + \
+    (UINTN)(Function << 12) + \
+    (UINTN)(Register)
+
+#define PciCfg32Read_CF8CFC(B,D,F,R) \
+  (UINT32)(IoOut32(0xCF8,(0x80000000|(B<<16)|(D<<11)|(F<<8)|(R))),IoIn32(0xCFC))
+
+#define PciCfg32Write_CF8CFC(B,D,F,R,Data) \
+  (IoOut32(0xCF8,(0x80000000|(B<<16)|(D<<11)|(F<<8)|(R))),IoOut32(0xCFC,Data))
+
+#define PciCfg32Or_CF8CFC(B,D,F,R,O) \
+  PciCfg32Write_CF8CFC(B,D,F,R, \
+    (PciCfg32Read_CF8CFC(B,D,F,R) | (O)))
+
+#define PciCfg32And_CF8CFC(B,D,F,R,A) \
+  PciCfg32Write_CF8CFC(B,D,F,R, \
+    (PciCfg32Read_CF8CFC(B,D,F,R) & (A)))
+
+#define PciCfg32AndThenOr_CF8CFC(B,D,F,R,A,O) \
+  PciCfg32Write_CF8CFC(B,D,F,R, \
+    (PciCfg32Read_CF8CFC(B,D,F,R) & (A)) | (O))
+
+//
+// Device 0, Function 0
+//
+#define McD0PciCfg64(Register)                              MmPci64           (0, MC_BUS, 0, 0, Register)
+#define McD0PciCfg64Or(Register, OrData)                    MmPci64Or         (0, MC_BUS, 0, 0, Register, OrData)
+#define McD0PciCfg64And(Register, AndData)                  MmPci64And        (0, MC_BUS, 0, 0, Register, AndData)
+#define McD0PciCfg64AndThenOr(Register, AndData, OrData)    MmPci64AndThenOr  (0, MC_BUS, 0, 0, Register, AndData, OrData)
+
+#define McD0PciCfg32(Register)                              MmPci32           (0, MC_BUS, 0, 0, Register)
+#define McD0PciCfg32Or(Register, OrData)                    MmPci32Or         (0, MC_BUS, 0, 0, Register, OrData)
+#define McD0PciCfg32And(Register, AndData)                  MmPci32And        (0, MC_BUS, 0, 0, Register, AndData)
+#define McD0PciCfg32AndThenOr(Register, AndData, OrData)    MmPci32AndThenOr  (0, MC_BUS, 0, 0, Register, AndData, OrData)
+
+#define McD0PciCfg16(Register)                              MmPci16           (0, MC_BUS, 0, 0, Register)
+#define McD0PciCfg16Or(Register, OrData)                    MmPci16Or         (0, MC_BUS, 0, 0, Register, OrData)
+#define McD0PciCfg16And(Register, AndData)                  MmPci16And        (0, MC_BUS, 0, 0, Register, AndData)
+#define McD0PciCfg16AndThenOr(Register, AndData, OrData)    MmPci16AndThenOr  (0, MC_BUS, 0, 0, Register, AndData, OrData)
+
+#define McD0PciCfg8(Register)                               MmPci8            (0, MC_BUS, 0, 0, Register)
+#define McD0PciCfg8Or(Register, OrData)                     MmPci8Or          (0, MC_BUS, 0, 0, Register, OrData)
+#define McD0PciCfg8And(Register, AndData)                   MmPci8And         (0, MC_BUS, 0, 0, Register, AndData)
+#define McD0PciCfg8AndThenOr( Register, AndData, OrData )   MmPci8AndThenOr   (0, MC_BUS, 0, 0, Register, AndData, OrData)
+
+
+//
+// Device 2, Function 0
+//
+#define McD2PciCfg64(Register)                              MmPci64           (0, MC_BUS, 2, 0, Register)
+#define McD2PciCfg64Or(Register, OrData)                    MmPci64Or         (0, MC_BUS, 2, 0, Register, OrData)
+#define McD2PciCfg64And(Register, AndData)                  MmPci64And        (0, MC_BUS, 2, 0, Register, AndData)
+#define McD2PciCfg64AndThenOr(Register, AndData, OrData)    MmPci64AndThenOr  (0, MC_BUS, 2, 0, Register, AndData, OrData)
+
+#define McD2PciCfg32(Register)                              MmPci32           (0, MC_BUS, 2, 0, Register)
+#define McD2PciCfg32Or(Register, OrData)                    MmPci32Or         (0, MC_BUS, 2, 0, Register, OrData)
+#define McD2PciCfg32And(Register, AndData)                  MmPci32And        (0, MC_BUS, 2, 0, Register, AndData)
+#define McD2PciCfg32AndThenOr(Register, AndData, OrData)    MmPci32AndThenOr  (0, MC_BUS, 2, 0, Register, AndData, OrData)
+
+#define McD2PciCfg16(Register)                              MmPci16           (0, MC_BUS, 2, 0, Register)
+#define McD2PciCfg16Or(Register, OrData)                    MmPci16Or         (0, MC_BUS, 2, 0, Register, OrData)
+#define McD2PciCfg16And(Register, AndData)                  MmPci16And        (0, MC_BUS, 2, 0, Register, AndData)
+#define McD2PciCfg16AndThenOr(Register, AndData, OrData)    MmPci16AndThenOr  (0, MC_BUS, 2, 0, Register, AndData, OrData)
+
+#define McD2PciCfg8(Register)                               MmPci8            (0, MC_BUS, 2, 0, Register)
+#define McD2PciCfg8Or(Register, OrData)                     MmPci8Or          (0, MC_BUS, 2, 0, Register, OrData)
+#define McD2PciCfg8And(Register, AndData)                   MmPci8And         (0, MC_BUS, 2, 0, Register, AndData)
+
+//
+// IO
+//
+
+#ifndef IoIn8
+
+#define IoIn8(Port) \
+  IoRead8(Port)
+
+#define IoIn16(Port) \
+  IoRead16(Port)
+
+#define IoIn32(Port) \
+  IoRead32(Port)
+
+#define IoOut8(Port, Data) \
+  IoWrite8(Port, Data)
+
+#define IoOut16(Port, Data) \
+  IoWrite16(Port, Data)
+
+#define IoOut32(Port, Data) \
+  IoWrite32(Port, Data)
+
+#endif
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/VlvCommonDefinitions.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/VlvCommonDefinitions.h
new file mode 100644
index 0000000000..4a521154d9
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/VlvCommonDefinitions.h
@@ -0,0 +1,252 @@
+
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  VlvCommonDefinitions.h
+
+Abstract:
+
+  Macros to simplify and abstract the interface to PCI configuration.
+
+--*/
+
+///
+/// PCI CONFIGURATION MAP REGISTER OFFSETS
+///
+#ifndef PCI_VID
+#define PCI_VID             0x0000  ///< Vendor ID Register
+#define PCI_DID             0x0002  ///< Device ID Register
+#define PCI_CMD             0x0004  ///< PCI Command Register
+#define PCI_STS             0x0006  ///< PCI Status Register
+#define PCI_RID             0x0008  ///< Revision ID Register
+#define PCI_IFT             0x0009  ///< Interface Type
+#define PCI_SCC             0x000A  ///< Sub Class Code Register
+#define PCI_BCC             0x000B  ///< Base Class Code Register
+#define PCI_CLS             0x000C  ///< Cache Line Size
+#define PCI_PMLT            0x000D  ///< Primary Master Latency Timer
+#define PCI_HDR             0x000E  ///< Header Type Register
+#define PCI_BIST            0x000F  ///< Built in Self Test Register
+#define PCI_BAR0            0x0010  ///< Base Address Register 0
+#define PCI_BAR1            0x0014  ///< Base Address Register 1
+#define PCI_BAR2            0x0018  ///< Base Address Register 2
+#define PCI_PBUS            0x0018  ///< Primary Bus Number Register
+#define PCI_SBUS            0x0019  ///< Secondary Bus Number Register
+#define PCI_SUBUS           0x001A  ///< Subordinate Bus Number Register
+#define PCI_SMLT            0x001B  ///< Secondary Master Latency Timer
+#define PCI_BAR3            0x001C  ///< Base Address Register 3
+#define PCI_IOBASE          0x001C  ///< I/O base Register
+#define PCI_IOLIMIT         0x001D  ///< I/O Limit Register
+#define PCI_SECSTATUS       0x001E  ///< Secondary Status Register
+#define PCI_BAR4            0x0020  ///< Base Address Register 4
+#define PCI_MEMBASE         0x0020  ///< Memory Base Register
+#define PCI_MEMLIMIT        0x0022  ///< Memory Limit Register
+#define PCI_BAR5            0x0024  ///< Base Address Register 5
+#define PCI_PRE_MEMBASE     0x0024  ///< Prefetchable memory Base register
+#define PCI_PRE_MEMLIMIT    0x0026  ///< Prefetchable memory Limit register
+#define PCI_PRE_MEMBASE_U   0x0028  ///< Prefetchable memory base upper 32 bits
+#define PCI_PRE_MEMLIMIT_U  0x002C  ///< Prefetchable memory limit upper 32 bits
+#define PCI_SVID            0x002C  ///< Subsystem Vendor ID
+#define PCI_SID             0x002E  ///< Subsystem ID
+#define PCI_IOBASE_U        0x0030  ///< I/O base Upper Register
+#define PCI_IOLIMIT_U       0x0032  ///< I/O Limit Upper Register
+#define PCI_CAPP            0x0034  ///< Capabilities Pointer
+#define PCI_EROM            0x0038  ///< Expansion ROM Base Address
+#define PCI_INTLINE         0x003C  ///< Interrupt Line Register
+#define PCI_INTPIN          0x003D  ///< Interrupt Pin Register
+#define PCI_MAXGNT          0x003E  ///< Max Grant Register
+#define PCI_BRIDGE_CNTL     0x003E  ///< Bridge Control Register
+#define PCI_MAXLAT          0x003F  ///< Max Latency Register
+#endif
+//
+// Bit Difinitions
+//
+#ifndef BIT0
+#define BIT0                     0x0001
+#define BIT1                     0x0002
+#define BIT2                     0x0004
+#define BIT3                     0x0008
+#define BIT4                     0x0010
+#define BIT5                     0x0020
+#define BIT6                     0x0040
+#define BIT7                     0x0080
+#define BIT8                     0x0100
+#define BIT9                     0x0200
+#define BIT10                    0x0400
+#define BIT11                    0x0800
+#define BIT12                    0x1000
+#define BIT13                    0x2000
+#define BIT14                    0x4000
+#define BIT15                    0x8000
+#define BIT16                    0x00010000
+#define BIT17                    0x00020000
+#define BIT18                    0x00040000
+#define BIT19                    0x00080000
+#define BIT20                    0x00100000
+#define BIT21                    0x00200000
+#define BIT22                    0x00400000
+#define BIT23                    0x00800000
+#define BIT24                    0x01000000
+#define BIT25                    0x02000000
+#define BIT26                    0x04000000
+#define BIT27                    0x08000000
+#define BIT28                    0x10000000
+#define BIT29                    0x20000000
+#define BIT30                    0x40000000
+#define BIT31                    0x80000000
+#endif
+
+#ifndef _PCIACCESS_H_INCLUDED_
+#define _PCIACCESS_H_INCLUDED_
+#ifndef PCI_EXPRESS_BASE_ADDRESS
+ #define PCI_EXPRESS_BASE_ADDRESS 0xE0000000
+#endif
+
+#ifndef MmPciAddress
+#define MmPciAddress( Segment, Bus, Device, Function, Register ) \
+  ( (UINTN)PCI_EXPRESS_BASE_ADDRESS + \
+    (UINTN)(Bus << 20) + \
+    (UINTN)(Device << 15) + \
+    (UINTN)(Function << 12) + \
+    (UINTN)(Register) \
+  )
+#endif
+
+//
+// UINT64
+//
+#define MmPci64Ptr( Segment, Bus, Device, Function, Register ) \
+  ( (volatile UINT64 *)MmPciAddress( Segment, Bus, Device, Function, Register ) )
+
+#define MmPci64( Segment, Bus, Device, Function, Register ) \
+  *MmPci64Ptr( Segment, Bus, Device, Function, Register )
+
+#define MmPci64Or( Segment, Bus, Device, Function, Register, OrData ) \
+  MmPci64( Segment, Bus, Device, Function, Register ) = \
+    (UINT64) ( \
+      MmPci64( Segment, Bus, Device, Function, Register ) | \
+      (UINT64)(OrData) \
+    )
+
+#define MmPci64And( Segment, Bus, Device, Function, Register, AndData ) \
+  MmPci64( Segment, Bus, Device, Function, Register ) = \
+    (UINT64) ( \
+      MmPci64( Segment, Bus, Device, Function, Register ) & \
+      (UINT64)(AndData) \
+    )
+
+#define MmPci64AndThenOr( Segment, Bus, Device, Function, Register, AndData, OrData ) \
+  MmPci64( Segment, Bus, Device, Function, Register ) = \
+    (UINT64) ( \
+      ( MmPci64( Segment, Bus, Device, Function, Register ) & \
+          (UINT64)(AndData) \
+      ) | \
+      (UINT64)(OrData) \
+    )
+
+//
+// UINT32
+//
+
+#define MmPci32Ptr( Segment, Bus, Device, Function, Register ) \
+  ( (volatile UINT32 *) MmPciAddress( Segment, Bus, Device, Function, Register ) )
+
+#define MmPci32( Segment, Bus, Device, Function, Register ) \
+  *MmPci32Ptr( Segment, Bus, Device, Function, Register )
+
+#define MmPci32Or( Segment, Bus, Device, Function, Register, OrData ) \
+  MmPci32( Segment, Bus, Device, Function, Register ) = \
+    (UINT32) ( \
+      MmPci32( Segment, Bus, Device, Function, Register ) | \
+      (UINT32)(OrData) \
+    )
+
+#define MmPci32And( Segment, Bus, Device, Function, Register, AndData ) \
+  MmPci32( Segment, Bus, Device, Function, Register ) = \
+    (UINT32) ( \
+      MmPci32( Segment, Bus, Device, Function, Register ) & \
+      (UINT32)(AndData) \
+    )
+
+#define MmPci32AndThenOr( Segment, Bus, Device, Function, Register, AndData, OrData ) \
+  MmPci32( Segment, Bus, Device, Function, Register ) = \
+    (UINT32) ( \
+      ( MmPci32( Segment, Bus, Device, Function, Register ) & \
+          (UINT32)(AndData) \
+      ) | \
+      (UINT32)(OrData) \
+    )
+
+//
+// UINT16
+//
+
+#define MmPci16Ptr( Segment, Bus, Device, Function, Register ) \
+  ( (volatile UINT16 *)MmPciAddress( Segment, Bus, Device, Function, Register ) )
+
+#define MmPci16( Segment, Bus, Device, Function, Register ) \
+  *MmPci16Ptr( Segment, Bus, Device, Function, Register )
+
+#define MmPci16Or( Segment, Bus, Device, Function, Register, OrData ) \
+  MmPci16( Segment, Bus, Device, Function, Register ) = \
+    (UINT16) ( \
+      MmPci16( Segment, Bus, Device, Function, Register ) | \
+      (UINT16)(OrData) \
+    )
+
+#define MmPci16And( Segment, Bus, Device, Function, Register, AndData ) \
+  MmPci16( Segment, Bus, Device, Function, Register ) = \
+    (UINT16) ( \
+      MmPci16( Segment, Bus, Device, Function, Register ) & \
+      (UINT16)(AndData) \
+    )
+
+#define MmPci16AndThenOr( Segment, Bus, Device, Function, Register, AndData, OrData ) \
+  MmPci16( Segment, Bus, Device, Function, Register ) = \
+    (UINT16) ( \
+      ( MmPci16( Segment, Bus, Device, Function, Register ) & \
+          (UINT16)(AndData) \
+      ) | \
+      (UINT16)(OrData) \
+    )
+
+//
+// UINT8
+//
+
+#define MmPci8Ptr( Segment, Bus, Device, Function, Register ) \
+  ( (volatile UINT8 *)MmPciAddress( Segment, Bus, Device, Function, Register ) )
+
+#define MmPci8( Segment, Bus, Device, Function, Register ) \
+  *MmPci8Ptr( Segment, Bus, Device, Function, Register )
+
+#define MmPci8Or( Segment, Bus, Device, Function, Register, OrData ) \
+  MmPci8( Segment, Bus, Device, Function, Register ) = \
+    (UINT8) ( \
+      MmPci8( Segment, Bus, Device, Function, Register ) | \
+      (UINT8)(OrData) \
+    )
+
+#define MmPci8And( Segment, Bus, Device, Function, Register, AndData ) \
+  MmPci8( Segment, Bus, Device, Function, Register ) = \
+    (UINT8) ( \
+      MmPci8( Segment, Bus, Device, Function, Register ) & \
+      (UINT8)(AndData) \
+    )
+
+#define MmPci8AndThenOr( Segment, Bus, Device, Function, Register, AndData, OrData ) \
+  MmPci8( Segment, Bus, Device, Function, Register ) = \
+    (UINT8) ( \
+      ( MmPci8( Segment, Bus, Device, Function, Register ) & \
+          (UINT8)(AndData) \
+        ) | \
+      (UINT8)(OrData) \
+    )
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Guid/PchInitVar.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Guid/PchInitVar.h
new file mode 100644
index 0000000000..aa5de5f4fd
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Guid/PchInitVar.h
@@ -0,0 +1,48 @@
+/*++
+
+Copyright (c) 2011  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  PchInitVar.h
+
+Abstract:
+
+  This file defines variable shared between PCH Init DXE driver and PCH
+  Init S3 Resume PEIM.
+
+--*/
+#ifndef _PCH_INIT_VAR_H_
+#define _PCH_INIT_VAR_H_
+
+#include <Protocol/PchPlatformPolicy.h>
+//
+// Define the PCH Init Var GUID
+//
+#define PCH_INIT_VARIABLE_GUID {0xe6c2f70a, 0xb604, 0x4877,{0x85, 0xba, 0xde, 0xec, 0x89, 0xe1, 0x17, 0xeb}}
+//
+// Extern the GUID for PPI users.
+//
+extern EFI_GUID gPchInitVariableGuid;
+
+#define PCH_INIT_VARIABLE_NAME  L"PchInit"
+
+//
+// Define the Pch Init Variable structure
+//
+typedef struct {
+  UINT32  StorePosition;
+  UINT32  ExecutePosition;
+} PCH_S3_PARAMETER_HEADER;
+
+#pragma pack(1)
+typedef struct _PCH_INIT_VARIABLE {
+  PCH_S3_PARAMETER_HEADER *PchS3Parameter;
+} PCH_INIT_VARIABLE;
+#pragma pack()
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Guid/SataControllerGuid.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Guid/SataControllerGuid.h
new file mode 100644
index 0000000000..42643ec770
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Guid/SataControllerGuid.h
@@ -0,0 +1,34 @@
+/*++
+
+Copyright (c)  2009  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  SataControllerGuid.h
+
+Abstract:
+
+  GUID for use in describing SataController
+
+--*/
+#ifndef _SERIAL_ATA_CONTROLLER_GUID_H_
+#define _SERIAL_ATA_CONTROLLER_GUID_H_
+
+#ifdef ECP_FLAG
+#define PCH_SATA_CONTROLLER_DRIVER_GUID \
+  { \
+    0xbb929da9, 0x68f7, 0x4035, 0xb2, 0x2c, 0xa3, 0xbb, 0x3f, 0x23, 0xda, 0x55 \
+  }
+#else
+#define PCH_SATA_CONTROLLER_DRIVER_GUID \
+  {\
+    0xbb929da9, 0x68f7, 0x4035, 0xb2, 0x2c, 0xa3, 0xbb, 0x3f, 0x23, 0xda, 0x55 \}
+
+#endif
+
+extern EFI_GUID gSataControllerDriverGuid;
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Guid/SmbusArpMap.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Guid/SmbusArpMap.h
new file mode 100644
index 0000000000..98c2f38443
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Guid/SmbusArpMap.h
@@ -0,0 +1,30 @@
+//
+//
+/*++
+
+Copyright (c)  2009  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  SmbusArpMap.h
+
+Abstract:
+
+  GUID for use in describing SMBus devices that were ARPed during PEI.
+
+--*/
+#ifndef _EFI_SMBUS_ARP_MAP_GUID_H_
+#define _EFI_SMBUS_ARP_MAP_GUID_H_
+
+#define EFI_SMBUS_ARP_MAP_GUID \
+  { \
+    0x707be83e, 0x0bf6, 0x40a5, 0xbe, 0x64, 0x34, 0xc0, 0x3a, 0xa0, 0xb8, 0xe2 \
+  }
+
+extern EFI_GUID gEfiSmbusArpMapGuid;
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Guid/Vlv2Variable.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Guid/Vlv2Variable.h
new file mode 100644
index 0000000000..c67ae129a1
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Guid/Vlv2Variable.h
@@ -0,0 +1,28 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  Vlv2Variable.h
+
+Abstract:
+
+  GUID used to define ValleyView2 variable.
+
+--*/
+
+#ifndef _VLV2_VARIABLE_GUID_H_
+#define _VLV2_VARIABLE_GUID_H_
+
+#define EFI_VLV2_VARIABLE \
+  { \
+    0x10ba6bbe, 0xa97e, 0x41c3, {0x9a, 0x07, 0x60, 0x7a, 0xd9, 0xbd, 0x60, 0xe5 } \
+  }
+extern EFI_GUID gEfiVlv2VariableGuid;
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/IndustryStandard/CeAta.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/IndustryStandard/CeAta.h
new file mode 100644
index 0000000000..8cfbd74f7b
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/IndustryStandard/CeAta.h
@@ -0,0 +1,126 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+--*/
+
+
+/*++
+
+Module Name:
+
+  CEATA.h
+
+Abstract:
+
+  Header file for chipset CE-AT spec.
+
+--*/
+
+#ifndef _CE_ATA_H
+#define _CE_ATA_H
+
+#pragma pack(1)
+
+
+#define  DATA_UNIT_SIZE       512
+
+
+#define  CMD60                60
+#define  CMD61                61
+
+
+#define RW_MULTIPLE_REGISTER  CMD60
+#define RW_MULTIPLE_BLOCK     CMD61
+
+
+#define CE_ATA_SIG_CE         0xCE
+#define CE_ATA_SIG_AA         0xAA
+
+
+#define Reg_Features_Exp      01
+#define Reg_SectorCount_Exp   02
+#define Reg_LBALow_Exp        03
+#define Reg_LBAMid_Exp        04
+#define Reg_LBAHigh_Exp       05
+#define Reg_Control           06
+#define Reg_Features_Error    09
+#define Reg_SectorCount       10
+#define Reg_LBALow            11
+#define Reg_LBAMid            12
+#define Reg_LBAHigh           13
+#define Reg_Device_Head       14
+#define Reg_Command_Status    15
+
+#define Reg_scrTempC          0x80
+#define Reg_scrTempMaxP       0x84
+#define Reg_scrTempMinP       0x88
+#define Reg_scrStatus         0x8C
+#define Reg_scrReallocsA      0x90
+#define Reg_scrERetractsA     0x94
+#define Reg_scrCapabilities   0x98
+#define Reg_scrControl        0xC0
+
+
+
+typedef struct {
+  UINT8  Reserved0;
+  UINT8  Features_Exp;
+  UINT8  SectorCount_Exp;
+  UINT8  LBALow_Exp;
+  UINT8  LBAMid_Exp;
+  UINT8  LBAHigh_Exp;
+  UINT8  Control;
+  UINT8  Reserved1[2];
+  UINT8  Features_Error;
+  UINT8  SectorCount;
+  UINT8  LBALow;
+  UINT8  LBAMid;
+  UINT8  LBAHigh;
+  UINT8  Device_Head;
+  UINT8  Command_Status;
+} TASK_FILE;
+
+
+//
+//Reduced ATA command set
+//
+#define IDENTIFY_DEVICE       0xEC
+#define READ_DMA_EXT          0x25
+#define WRITE_DMA_EXT         0x35
+#define STANDBY_IMMEDIATE     0xE0
+#define FLUSH_CACHE_EXT       0xEA
+
+
+
+typedef struct {
+  UINT16  Reserved0[10];
+  UINT16  SerialNumber[10];
+  UINT16  Reserved1[3];
+  UINT16  FirmwareRevision[4];
+  UINT16  ModelNumber[20];
+  UINT16  Reserved2[33];
+  UINT16  MajorVersion;
+  UINT16  Reserved3[19];
+  UINT16  MaximumLBA[4];
+  UINT16  Reserved4[2];
+  UINT16  Sectorsize;
+  UINT16  Reserved5;
+  UINT16  DeviceGUID[4];
+  UINT16  Reserved6[94];
+  UINT16  Features;
+  UINT16  MaxWritesPerAddress;
+  UINT16  Reserved7[47];
+  UINT16  IntegrityWord;
+} IDENTIFY_DEVICE_DATA;
+
+
+
+
+
+#pragma pack()
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/IndustryStandard/Mmc.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/IndustryStandard/Mmc.h
new file mode 100644
index 0000000000..fd2706eb89
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/IndustryStandard/Mmc.h
@@ -0,0 +1,349 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+--*/
+
+
+/*++
+
+Module Name:
+
+  MMC.h
+
+Abstract:
+
+  Header file for Industry MMC 4.2 spec.
+
+--*/
+
+#ifndef _MMC_H
+#define _MMC_H
+
+#pragma pack(1)
+//
+//Command definition
+//
+
+#define  CMD0              0
+#define  CMD1              1
+#define  CMD2              2
+#define  CMD3              3
+#define  CMD4              4
+#define  CMD6              6
+#define  CMD7              7
+#define  CMD8              8
+#define  CMD9              9
+#define  CMD10             10
+#define  CMD11             11
+#define  CMD12             12
+#define  CMD13             13
+#define  CMD14             14
+#define  CMD15             15
+#define  CMD16             16
+#define  CMD17             17
+#define  CMD18             18
+#define  CMD19             19
+#define  CMD20             20
+#define  CMD23             23
+#define  CMD24             24
+#define  CMD25             25
+#define  CMD26             26
+#define  CMD27             27
+#define  CMD28             28
+#define  CMD29             29
+#define  CMD30             30
+#define  CMD35             35
+#define  CMD36             36
+#define  CMD38             38
+#define  CMD39             39
+#define  CMD40             40
+#define  CMD42             42
+#define  CMD55             55
+#define  CMD56             56
+
+
+
+#define  GO_IDLE_STATE           CMD0
+#define  SEND_OP_COND            CMD1
+#define  ALL_SEND_CID            CMD2
+#define  SET_RELATIVE_ADDR       CMD3
+#define  SET_DSR                 CMD4
+#define  SWITCH                  CMD6
+#define  SELECT_DESELECT_CARD    CMD7
+#define  SEND_EXT_CSD            CMD8
+#define  SEND_CSD                CMD9
+#define  SEND_CID                CMD10
+#define  READ_DAT_UNTIL_STOP     CMD11
+#define  STOP_TRANSMISSION       CMD12
+#define  SEND_STATUS             CMD13
+#define  BUSTEST_R               CMD14
+#define  GO_INACTIVE_STATE       CMD15
+#define  SET_BLOCKLEN            CMD16
+#define  READ_SINGLE_BLOCK       CMD17
+#define  READ_MULTIPLE_BLOCK     CMD18
+#define  BUSTEST_W               CMD19
+#define  WRITE_DAT_UNTIL_STOP    CMD20
+#define  SET_BLOCK_COUNT         CMD23
+#define  WRITE_BLOCK             CMD24
+#define  WRITE_MULTIPLE_BLOCK    CMD25
+#define  PROGRAM_CID             CMD26
+#define  PROGRAM_CSD             CMD27
+#define  SET_WRITE_PROT          CMD28
+#define  CLR_WRITE_PROT          CMD29
+#define  SEND_WRITE_PROT         CMD30
+#define  ERASE_GROUP_START       CMD35
+#define  ERASE_GROUP_END         CMD36
+#define  ERASE                   CMD38
+#define  FAST_IO                 CMD39
+#define  GO_IRQ_STATE            CMD40
+#define  LOCK_UNLOCK             CMD42
+#define  APP_CMD                 CMD55
+#define  GEN_CMD                 CMD56
+
+#define B_PERM_WP_DIS            0x10
+#define B_PWR_WP_EN              0x01
+#define US_PERM_WP_DIS           0x10
+#define US_PWR_WP_EN             0x01
+
+#define FREQUENCY_OD            (400 * 1000)
+#define FREQUENCY_MMC_PP        (26 * 1000 * 1000)
+#define FREQUENCY_MMC_PP_HIGH   (52 * 1000 * 1000)
+
+#define DEFAULT_DSR_VALUE        0x404
+
+//
+//Registers definition
+//
+
+typedef struct {
+  UINT32  Reserved0:   7;  // 0
+  UINT32  V170_V195:   1;  // 1.70V - 1.95V
+  UINT32  V200_V260:   7;  // 2.00V - 2.60V
+  UINT32  V270_V360:   9;  // 2.70V - 3.60V
+  UINT32  Reserved1:   5;  // 0
+  UINT32  AccessMode:  2;  // 00b (byte mode), 10b (sector mode)
+  UINT32  Busy:        1;  // This bit is set to LOW if the card has not finished the power up routine
+} OCR;
+
+
+typedef struct {
+  UINT8   NotUsed:     1; //  1
+  UINT8   CRC:         7; //  CRC7 checksum
+  UINT8   MDT;            //  Manufacturing date
+  UINT32  PSN;            //  Product serial number
+  UINT8   PRV;            //  Product revision
+  UINT8   PNM[6];         //  Product name
+  UINT16  OID;            //  OEM/Application ID
+  UINT8   MID;            //  Manufacturer ID
+} CID;
+
+
+typedef struct {
+  UINT8   NotUsed:            1; //  1 [0:0]
+  UINT8   CRC:                7; //  CRC [7:1]
+  UINT8   ECC:                2; //  ECC code [9:8]
+  UINT8   FILE_FORMAT:        2; //  File format [11:10]
+  UINT8   TMP_WRITE_PROTECT:  1; //  Temporary write protection [12:12]
+  UINT8   PERM_WRITE_PROTECT: 1; //  Permanent write protection [13:13]
+  UINT8   COPY:               1; //  Copy flag (OTP) [14:14]
+  UINT8   FILE_FORMAT_GRP:    1; //  File format group [15:15]
+  UINT16  CONTENT_PROT_APP:   1; //  Content protection application [16:16]
+  UINT16  Reserved0:          4; //  0 [20:17]
+  UINT16  WRITE_BL_PARTIAL:   1; //  Partial blocks for write allowed [21:21]
+  UINT16  WRITE_BL_LEN:       4; //  Max. write data block length [25:22]
+  UINT16  R2W_FACTOR:         3; //  Write speed factor [28:26]
+  UINT16  DEFAULT_ECC:        2; //  Manufacturer default ECC [30:29]
+  UINT16  WP_GRP_ENABLE:      1; //  Write protect group enable [31:31]
+  UINT32  WP_GRP_SIZE:        5; //  Write protect group size [36:32]
+  UINT32  ERASE_GRP_MULT:     5; //  Erase group size multiplier [41:37]
+  UINT32  ERASE_GRP_SIZE:     5; //  Erase group size [46:42]
+  UINT32  C_SIZE_MULT:        3; //  Device size multiplier [49:47]
+  UINT32  VDD_W_CURR_MAX:     3; //  Max. write current @ VDD max [52:50]
+  UINT32  VDD_W_CURR_MIN:     3; //  Max. write current @ VDD min [55:53]
+  UINT32  VDD_R_CURR_MAX:     3; //  Max. read current @ VDD max [58:56]
+  UINT32  VDD_R_CURR_MIN:     3; //  Max. read current @ VDD min [61:59]
+  UINT32  C_SIZELow2:         2;//  Device size [73:62]
+  UINT32  C_SIZEHigh10:       10;//  Device size [73:62]
+  UINT32  Reserved1:          2; //  0 [75:74]
+  UINT32  DSR_IMP:            1; //  DSR implemented [76:76]
+  UINT32  READ_BLK_MISALIGN:  1; //  Read block misalignment [77:77]
+  UINT32  WRITE_BLK_MISALIGN: 1; //  Write block misalignment [78:78]
+  UINT32  READ_BL_PARTIAL:    1; //  Partial blocks for read allowed [79:79]
+  UINT32  READ_BL_LEN:        4; //  Max. read data block length [83:80]
+  UINT32  CCC:                12;//  Card command classes [95:84]
+  UINT8   TRAN_SPEED          ; //  Max. bus clock frequency [103:96]
+  UINT8   NSAC                ; //  Data read access-time 2 in CLK cycles (NSAC*100) [111:104]
+  UINT8   TAAC                ; //  Data read access-time 1 [119:112]
+  UINT8   Reserved2:          2; //  0 [121:120]
+  UINT8   SPEC_VERS:          4; //  System specification version [125:122]
+  UINT8   CSD_STRUCTURE:      2; //  CSD structure [127:126]
+} CSD;
+
+typedef struct {
+  UINT8  Reserved133_0[134];     // [133:0] 0
+  UINT8  SEC_BAD_BLOCK_MGMNT;    // [134] Bad Block Management mode
+  UINT8  Reserved135;            // [135] 0
+  UINT8  ENH_START_ADDR[4];      // [139:136] Enhanced User Data Start Address
+  UINT8  ENH_SIZE_MULT[3];       // [142:140] Enhanced User Data Start Size
+  UINT8  GP_SIZE_MULT_1[3];      // [145:143] GPP1 Size
+  UINT8  GP_SIZE_MULT_2[3];      // [148:146] GPP2 Size
+  UINT8  GP_SIZE_MULT_3[3];      // [151:149] GPP3 Size
+  UINT8  GP_SIZE_MULT_4[3];      // [154:152] GPP4 Size
+  UINT8  PARTITION_SETTING_COMPLETED; // [155] Partitioning Setting
+  UINT8  PARTITIONS_ATTRIBUTES;  // [156] Partitions attributes
+  UINT8  MAX_ENH_SIZE_MULT[3];   // [159:157] GPP4 Start Size
+  UINT8  PARTITIONING_SUPPORT;   // [160] Partitioning Support
+  UINT8  HPI_MGMT;               // [161] HPI management
+  UINT8  RST_n_FUNCTION;         // [162] H/W reset function
+  UINT8  BKOPS_EN;               // [163] Enable background operations handshake
+  UINT8  BKOPS_START;            // [164] Manually start background operations
+  UINT8  Reserved165;            // [165] 0
+  UINT8  WR_REL_PARAM;           // [166] Write reliability parameter register
+  UINT8  WR_REL_SET;             // [167] Write reliability setting register
+  UINT8  RPMB_SIZE_MULT;         // [168] RPMB Size
+  UINT8  FW_CONFIG;              // [169] FW configuration
+  UINT8  Reserved170;            // [170] 0
+  UINT8  USER_WP;                // [171] User area write protection
+  UINT8  Reserved172;            // [172] 0
+  UINT8  BOOT_WP;                // [173] Boot area write protection
+  UINT8  Reserved174;            // [174] 0
+  UINT8  ERASE_GROUP_DEF;        // [175] High density erase group definition
+  UINT8  Reserved176;            // [176] 0
+  UINT8  BOOT_BUS_WIDTH;         // [177] Boot bus width
+  UINT8  BOOT_CONFIG_PROT;       // [178] Boot config protection
+  UINT8  PARTITION_CONFIG;       // [179] Partition config
+  UINT8  Reserved180;            // [180] 0
+  UINT8  ERASED_MEM_CONT;        // [181] Erased Memory Content
+  UINT8  Reserved182;            // [182] 0
+  UINT8  BUS_WIDTH;              // [183] Bus Width Mode
+  UINT8  Reserved184;            // [184] 0
+  UINT8  HS_TIMING;              // [185] High Speed Interface Timing
+  UINT8  Reserved186;            // [186] 0
+  UINT8  POWER_CLASS;            // [187] Power Class
+  UINT8  Reserved188;            // [188] 0
+  UINT8  CMD_SET_REV;            // [189] Command Set Revision
+  UINT8  Reserved190;            // [190] 0
+  UINT8  CMD_SET;                // [191] Command Set
+  UINT8  EXT_CSD_REV;            // [192] Extended CSD Revision
+  UINT8  Reserved193;            // [193] 0
+  UINT8  CSD_STRUCTURE;          // [194] CSD Structure Version
+  UINT8  Reserved195;            // [195] 0
+  UINT8  CARD_TYPE;              // [196] Card Type
+  UINT8  Reserved197;            // [197] 0
+  UINT8  OUT_OF_INTERRUPT_TIME;  // [198] Out-of-interrupt busy timing
+  UINT8  PARTITION_SWITCH_TIME;  // [199] Partition switching timing
+  UINT8  PWR_CL_52_195;          // [200] Power Class for 52MHz @ 1.95V
+  UINT8  PWR_CL_26_195;          // [201] Power Class for 26MHz @ 1.95V
+  UINT8  PWR_CL_52_360;          // [202] Power Class for 52MHz @ 3.6V
+  UINT8  PWR_CL_26_360;          // [203] Power Class for 26MHz @ 3.6V
+  UINT8  Reserved204;            // [204] 0
+  UINT8  MIN_PERF_R_4_26;        // [205] Minimum Read Performance for 4bit @26MHz
+  UINT8  MIN_PERF_W_4_26;        // [206] Minimum Write Performance for 4bit @26MHz
+  UINT8  MIN_PERF_R_8_26_4_52;   // [207] Minimum Read Performance for 8bit @26MHz/4bit @52MHz
+  UINT8  MIN_PERF_W_8_26_4_52;   // [208] Minimum Write Performance for 8bit @26MHz/4bit @52MHz
+  UINT8  MIN_PERF_R_8_52;        // [209] Minimum Read Performance for 8bit @52MHz
+  UINT8  MIN_PERF_W_8_52;        // [210] Minimum Write Performance for 8bit @52MHz
+  UINT8  Reserved211;            // [211] 0
+  UINT8  SEC_COUNT[4];           // [215:212] Sector Count
+  UINT8  Reserved216;            // [216] 0
+  UINT8  S_A_TIMEOUT;            // [217] Sleep/awake timeout
+  UINT8  Reserved218;            // [218] 0
+  UINT8  S_C_VCCQ;               // [219] Sleep current (VCCQ)
+  UINT8  S_C_VCC;                // [220] Sleep current (VCC)
+  UINT8  HC_WP_GRP_SIZE;         // [221] High-capacity write protect group size
+  UINT8  REL_WR_SEC_C;           // [222] Reliable write sector count
+  UINT8  ERASE_TIMEOUT_MULT;     // [223] High-capacity erase timeout
+  UINT8  HC_ERASE_GRP_SIZE;      // [224] High-capacity erase unit size
+  UINT8  ACC_SIZE;               // [225] Access size
+  UINT8  BOOT_SIZE_MULTI;        // [226] Boot partition size
+  UINT8  Reserved227;            // [227] 0
+  UINT8  BOOT_INFO;              // [228] Boot information
+  UINT8  SEC_TRIM_MULT;          // [229] Secure TRIM Multiplier
+  UINT8  SEC_ERASE_MULT;         // [230] Secure Erase Multiplier
+  UINT8  SEC_FEATURE_SUPPORT;    // [231] Secure Feature support
+  UINT8  TRIM_MULT;              // [232] TRIM Multiplier
+  UINT8  Reserved233;            // [233] 0
+  UINT8  MIN_PERF_DDR_R_8_52;    // [234] Min Read Performance for 8-bit @ 52MHz
+  UINT8  MIN_PERF_DDR_W_8_52;    // [235] Min Write Performance for 8-bit @ 52MHz
+  UINT8  Reserved237_236[2];     // [237:236] 0
+  UINT8  PWR_CL_DDR_52_195;      // [238] Power class for 52MHz, DDR at 1.95V
+  UINT8  PWR_CL_DDR_52_360;      // [239] Power class for 52MHz, DDR at 3.6V
+  UINT8  Reserved240;            // [240] 0
+  UINT8  INI_TIMEOUT_AP;         // [241] 1st initialization time after partitioning
+  UINT8  CORRECTLY_PRG_SECTORS_NUM[4]; // [245:242] Number of correctly programmed sectors
+  UINT8  BKOPS_STATUS;           // [246] Background operations status
+  UINT8  Reserved501_247[255];   // [501:247] 0
+  UINT8  BKOPS_SUPPORT;          // [502] Background operations support
+  UINT8  HPI_FEATURES;           // [503] HPI features
+  UINT8  S_CMD_SET;              // [504] Sector Count
+  UINT8  Reserved511_505[7];     // [511:505] Sector Count
+} EXT_CSD;
+
+
+//
+//Card Status definition
+//
+typedef struct {
+  UINT32  Reserved0:           2; //Reserved for Manufacturer Test Mode
+  UINT32  Reserved1:           2; //Reserved for Application Specific commands
+  UINT32  Reserved2:           1; //
+  UINT32  SAPP_CMD:            1; //
+  UINT32  Reserved3:           1; //Reserved
+  UINT32  SWITCH_ERROR:        1; //
+  UINT32  READY_FOR_DATA:      1; //
+  UINT32  CURRENT_STATE:       4; //
+  UINT32  ERASE_RESET:         1; //
+  UINT32  Reserved4:           1; //Reserved
+  UINT32  WP_ERASE_SKIP:       1; //
+  UINT32  CID_CSD_OVERWRITE:   1; //
+  UINT32  OVERRUN:             1; //
+  UINT32  UNDERRUN:            1; //
+  UINT32  ERROR:               1; //
+  UINT32  CC_ERROR:            1; //
+  UINT32  CARD_ECC_FAILED:     1; //
+  UINT32  ILLEGAL_COMMAND:     1; //
+  UINT32  COM_CRC_ERROR:       1; //
+  UINT32  LOCK_UNLOCK_FAILED:  1; //
+  UINT32  CARD_IS_LOCKED:      1; //
+  UINT32  WP_VIOLATION:        1; //
+  UINT32  ERASE_PARAM:         1; //
+  UINT32  ERASE_SEQ_ERROR:     1; //
+  UINT32  BLOCK_LEN_ERROR:     1; //
+  UINT32  ADDRESS_MISALIGN:    1; //
+  UINT32  ADDRESS_OUT_OF_RANGE:1; //
+} CARD_STATUS;
+
+typedef struct {
+  UINT32  CmdSet:              3;
+  UINT32  Reserved0:           5;
+  UINT32  Value:               8;
+  UINT32  Index:               8;
+  UINT32  Access:              2;
+  UINT32  Reserved1:           6;
+} SWITCH_ARGUMENT;
+
+#define CommandSet_Mode          0
+#define SetBits_Mode             1
+#define ClearBits_Mode           2
+#define WriteByte_Mode           3
+
+
+#define  Idle_STATE              0
+#define  Ready_STATE             1
+#define  Ident_STATE             2
+#define  Stby_STATE              3
+#define  Tran_STATE              4
+#define  Data_STATE              5
+#define  Rcv_STATE               6
+#define  Prg_STATE               7
+#define  Dis_STATE               8
+#define  Btst_STATE              9
+
+
+
+#pragma pack()
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/IndustryStandard/SdCard.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/IndustryStandard/SdCard.h
new file mode 100644
index 0000000000..62bd6e0823
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/IndustryStandard/SdCard.h
@@ -0,0 +1,157 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+--*/
+
+
+/*++
+Module Name:
+
+  SDCard.h
+
+Abstract:
+
+  Header file for Industry SD Card 2.0 spec.
+
+--*/
+
+#ifndef _SD_CARD_H
+#define _SD_CARD_H
+
+#include "Mmc.h"
+
+#pragma pack(1)
+
+#define CHECK_PATTERN     0xAA
+
+#define ACMD6             6
+#define ACMD13            13
+#define ACMD23            23
+#define ACMD41            41
+#define ACMD42            42
+#define ACMD51            51
+
+
+#define SWITCH_FUNC              CMD6
+#define SEND_IF_COND             CMD8
+
+
+#define SET_BUS_WIDTH            ACMD6
+#define SD_STATUS                ACMD13
+#define SET_WR_BLK_ERASE_COUNT   ACMD23
+#define SD_SEND_OP_COND          ACMD41
+#define SET_CLR_CARD_DETECT      ACMD42
+#define SEND_SCR                 ACMD51
+
+
+
+#define SD_BUS_WIDTH_1              0
+#define SD_BUS_WIDTH_4              2
+
+
+
+#define FREQUENCY_SD_PP        (25 * 1000 * 1000)
+#define FREQUENCY_SD_PP_HIGH   (50 * 1000 * 1000)
+
+
+#define SD_SPEC_10                  0
+#define SD_SPEC_11                  1
+#define SD_SPEC_20                  2
+
+
+#define VOLTAGE_27_36               0x1
+
+typedef struct {
+  UINT8   NotUsed:            1; //  1 [0:0]
+  UINT8   CRC:                7; //  CRC [7:1]
+  UINT8   ECC:                2; //  ECC code [9:8]
+  UINT8   FILE_FORMAT:        2; //  File format [11:10]
+  UINT8   TMP_WRITE_PROTECT:  1; //  Temporary write protection [12:12]
+  UINT8   PERM_WRITE_PROTECT: 1; //  Permanent write protection [13:13]
+  UINT8   COPY:               1; //  Copy flag (OTP) [14:14]
+  UINT8   FILE_FORMAT_GRP:    1; //  File format group [15:15]
+  UINT16  Reserved0:          5; //  0 [20:16]
+  UINT16  WRITE_BL_PARTIAL:   1; //  Partial blocks for write allowed [21:21]
+  UINT16  WRITE_BL_LEN:       4; //  Max. write data block length [25:22]
+  UINT16  R2W_FACTOR:         3; //  Write speed factor [28:26]
+  UINT16  DEFAULT_ECC:        2; //  Manufacturer default ECC [30:29]
+  UINT16  WP_GRP_ENABLE:      1; //  Write protect group enable [31:31]
+  UINT16  WP_GRP_SIZE:        7; //  Write protect group size [38:32]
+  UINT16  SECTOR_SIZE:        7; //  Erase sector size [45:39]
+  UINT16  ERASE_BLK_EN:       1; //  Erase single block enable [46:46]
+  UINT16  Reserved1:          1; //  0 [47:47]
+
+  UINT32  C_SIZE:             22; //  Device size [69:48]
+  UINT32  Reserved2:          6;  //  0 [75:70]
+  UINT32  DSR_IMP:            1;  //  DSR implemented [76:76]
+  UINT32  READ_BLK_MISALIGN:  1;  //  Read block misalignment [77:77]
+  UINT32  WRITE_BLK_MISALIGN: 1;  //  Write block misalignment [78:78]
+  UINT32  READ_BL_PARTIAL:    1;  //  Partial blocks for read allowed [79:79]
+
+  UINT16  READ_BL_LEN:        4;  //  Max. read data block length [83:80]
+  UINT16  CCC:                12; //  Card command classes [95:84]
+  UINT8   TRAN_SPEED          ;   //  Max. bus clock frequency [103:96]
+  UINT8   NSAC                ;   //  Data read access-time 2 in CLK cycles (NSAC*100) [111:104]
+  UINT8   TAAC                ;   //  Data read access-time 1 [119:112]
+  UINT8   Reserved3:          6;  //  0 [125:120]
+  UINT8   CSD_STRUCTURE:      2;  //  CSD structure [127:126]
+} CSD_SDV2;
+
+typedef struct {
+  UINT32  Reserved0;
+  UINT32  Reserved1:               16;
+  UINT32  SD_BUS_WIDTH:            4;
+  UINT32  SD_SECURITY:             3;
+  UINT32  DATA_STAT_AFTER_ERASE:   1;
+  UINT32  SD_SPEC:                 4;
+  UINT32  SCR_STRUCT:              4;
+} SCR;
+
+
+typedef struct {
+  UINT8   Reserved0[50];
+  UINT8   ERASE_OFFSET:               2;
+  UINT8   ERASE_TIMEOUT:              6;
+  UINT16  ERASE_SIZE;
+  UINT8   Reserved1:                  4;
+  UINT8   AU_SIZE:                    4;
+  UINT8   PERFORMANCE_MOVE;
+  UINT8   SPEED_CLASS;
+  UINT32  SIZE_OF_PROTECTED_AREA;
+  UINT32  SD_CARD_TYPE:              16;
+  UINT32  Reserved2:                 13;
+  UINT32  SECURED_MODE:               1;
+  UINT32  DAT_BUS_WIDTH:              2;
+} SD_STATUS_REG;
+
+
+
+typedef struct {
+  UINT8   Reserved0[34];
+  UINT16  Group1BusyStatus;
+  UINT16  Group2BusyStatus;
+  UINT16  Group3BusyStatus;
+  UINT16  Group4BusyStatus;
+  UINT16  Group5BusyStatus;
+  UINT16  Group6BusyStatus;
+  UINT8   DataStructureVersion;
+  UINT8   Group21Status;
+  UINT8   Group43Status;
+  UINT8   Group65Status;
+  UINT16  Group1Function;
+  UINT16  Group2Function;
+  UINT16  Group3Function;
+  UINT16  Group4Function;
+  UINT16  Group5Function;
+  UINT16  Group6Function;
+  UINT16  MaxCurrent;
+} SWITCH_STATUS;
+
+
+#pragma pack()
+#endif
+
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Library/I2CLib.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Library/I2CLib.h
new file mode 100644
index 0000000000..7df5ff2fef
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Library/I2CLib.h
@@ -0,0 +1,169 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  I2CRegs.h
+
+Abstract:
+
+  Register Definitions for I2C Driver/PEIM.
+
+--*/
+#include <Uefi.h>
+#include <Library/IoLib.h>
+
+#ifndef I2C_REGS_A0_H
+#define I2C_REGS_A0_H
+
+//
+// FIFO write workaround value.
+//
+#define FIFO_WRITE_DELAY    2
+
+//
+// MMIO Register Definitions
+//
+#define    R_IC_CON                          ( 0x00) // I2C Control
+#define     B_IC_RESTART_EN                  BIT5
+#define     B_IC_SLAVE_DISABLE               BIT6
+#define     V_SPEED_STANDARD                 0x02
+#define     V_SPEED_FAST                     0x04
+#define     V_SPEED_HIGH                     0x06
+#define     B_MASTER_MODE                    BIT0
+
+#define    R_IC_TAR                          ( 0x04) // I2C Target Address
+#define     IC_TAR_10BITADDR_MASTER           BIT12
+
+#define    R_IC_SAR                          ( 0x08) // I2C Slave Address
+#define    R_IC_HS_MADDR                     ( 0x0C) // I2C HS MasterMode Code Address
+#define    R_IC_DATA_CMD                     ( 0x10) // I2C Rx/Tx Data Buffer and Command
+
+#define    B_READ_CMD                         BIT8    // 1 = read, 0 = write
+#define    B_CMD_STOP                         BIT9    // 1 = STOP
+#define    B_CMD_RESTART                      BIT10   // 1 = IC_RESTART_EN
+
+#define    V_WRITE_CMD_MASK                  ( 0xFF)
+
+#define    R_IC_SS_SCL_HCNT                  ( 0x14) // Standard Speed I2C Clock SCL High Count
+#define    R_IC_SS_SCL_LCNT                  ( 0x18) // Standard Speed I2C Clock SCL Low Count
+#define    R_IC_FS_SCL_HCNT                  ( 0x1C) // Full Speed I2C Clock SCL High Count
+#define    R_IC_FS_SCL_LCNT                  ( 0x20) // Full Speed I2C Clock SCL Low Count
+#define    R_IC_HS_SCL_HCNT                  ( 0x24) // High Speed I2C Clock SCL High Count
+#define    R_IC_HS_SCL_LCNT                  ( 0x28) // High Speed I2C Clock SCL Low Count
+#define    R_IC_INTR_STAT                    ( 0x2C) // I2C Inetrrupt Status
+#define    R_IC_INTR_MASK                    ( 0x30) // I2C Interrupt Mask
+#define     I2C_INTR_GEN_CALL                 BIT11  // General call received
+#define     I2C_INTR_START_DET                BIT10
+#define     I2C_INTR_STOP_DET                 BIT9
+#define     I2C_INTR_ACTIVITY                 BIT8
+#define     I2C_INTR_TX_ABRT                  BIT6   // Set on NACK
+#define     I2C_INTR_TX_EMPTY                 BIT4
+#define     I2C_INTR_TX_OVER                  BIT3
+#define     I2C_INTR_RX_FULL                  BIT2   // Data bytes in RX FIFO over threshold
+#define     I2C_INTR_RX_OVER                  BIT1
+#define     I2C_INTR_RX_UNDER                 BIT0
+#define    R_IC_RAW_INTR_STAT                ( 0x34) // I2C Raw Interrupt Status
+#define    R_IC_RX_TL                        ( 0x38) // I2C Receive FIFO Threshold
+#define    R_IC_TX_TL                        ( 0x3C) // I2C Transmit FIFO Threshold
+#define    R_IC_CLR_INTR                     ( 0x40) // Clear Combined and Individual Interrupts
+#define    R_IC_CLR_RX_UNDER                 ( 0x44) // Clear RX_UNDER Interrupt
+#define    R_IC_CLR_RX_OVER                  ( 0x48) // Clear RX_OVERinterrupt
+#define    R_IC_CLR_TX_OVER                  ( 0x4C) // Clear TX_OVER interrupt
+#define    R_IC_CLR_RD_REQ                   ( 0x50) // Clear RD_REQ interrupt
+#define    R_IC_CLR_TX_ABRT                  ( 0x54) // Clear TX_ABRT interrupt
+#define    R_IC_CLR_RX_DONE                  ( 0x58) // Clear RX_DONE interrupt
+#define    R_IC_CLR_ACTIVITY                 ( 0x5C) // Clear ACTIVITY interrupt
+#define    R_IC_CLR_STOP_DET                 ( 0x60) // Clear STOP_DET interrupt
+#define    R_IC_CLR_START_DET                ( 0x64) // Clear START_DET interrupt
+#define    R_IC_CLR_GEN_CALL                 ( 0x68) // Clear GEN_CALL interrupt
+#define    R_IC_ENABLE                       ( 0x6C) // I2C Enable
+#define    R_IC_STATUS                       ( 0x70) // I2C Status
+
+#define    R_IC_SDA_HOLD                     ( 0x7C) // I2C IC_DEFAULT_SDA_HOLD//16bits
+
+#define     STAT_MST_ACTIVITY                 BIT5   // Master FSM Activity Status.
+#define     STAT_RFF                          BIT4   // RX FIFO is completely full
+#define     STAT_RFNE                         BIT3   // RX FIFO is not empty
+#define     STAT_TFE                          BIT2   // TX FIFO is completely empty
+#define     STAT_TFNF                         BIT1   // TX FIFO is not full
+
+#define    R_IC_TXFLR                        ( 0x74) // Transmit FIFO Level Register
+#define    R_IC_RXFLR                        ( 0x78) // Receive FIFO Level Register
+#define    R_IC_TX_ABRT_SOURCE               ( 0x80) // I2C Transmit Abort Status Register
+#define    R_IC_SLV_DATA_NACK_ONLY           ( 0x84) // Generate SLV_DATA_NACK Register
+#define    R_IC_DMA_CR                       ( 0x88) // DMA Control Register
+#define    R_IC_DMA_TDLR                     ( 0x8C) // DMA Transmit Data Level
+#define    R_IC_DMA_RDLR                     ( 0x90) // DMA Receive Data Level
+#define    R_IC_SDA_SETUP                    ( 0x94) // I2C SDA Setup Register
+#define    R_IC_ACK_GENERAL_CALL             ( 0x98) // I2C ACK General Call Register
+#define    R_IC_ENABLE_STATUS                ( 0x9C) // I2C Enable Status Register
+#define    R_IC_COMP_PARAM                   ( 0xF4) // Component Parameter Register
+#define    R_IC_COMP_VERSION                 ( 0xF8) // Component Version ID
+#define    R_IC_COMP_TYPE                    ( 0xFC) // Component Type
+
+#define    R_IC_CLK_GATE                     ( 0xC0) // Clock Gate
+
+#define    I2C_SS_SCL_HCNT_VALUE_100M        0x1DD
+#define    I2C_SS_SCL_LCNT_VALUE_100M        0x1E4
+#define    I2C_FS_SCL_HCNT_VALUE_100M        0x54
+#define    I2C_FS_SCL_LCNT_VALUE_100M        0x9a
+#define    I2C_HS_SCL_HCNT_VALUE_100M        0x7
+#define    I2C_HS_SCL_LCNT_VALUE_100M        0xE
+
+#define     IC_TAR_10BITADDR_MASTER           BIT12
+#define     FIFO_SIZE                         32
+#define     R_IC_INTR_STAT                    ( 0x2C) // I2c Inetrrupt Status
+#define     R_IC_INTR_MASK                    ( 0x30) // I2c Interrupt Mask
+#define     I2C_INTR_GEN_CALL                 BIT11  // General call received
+#define     I2C_INTR_START_DET                BIT10
+#define     I2C_INTR_STOP_DET                 BIT9
+#define     I2C_INTR_ACTIVITY                 BIT8
+#define     I2C_INTR_TX_ABRT                  BIT6   // Set on NACK
+#define     I2C_INTR_TX_EMPTY                 BIT4
+#define     I2C_INTR_TX_OVER                  BIT3
+#define     I2C_INTR_RX_FULL                  BIT2   // Data bytes in RX FIFO over threshold
+#define     I2C_INTR_RX_OVER                  BIT1
+#define     I2C_INTR_RX_UNDER                 BIT0
+
+EFI_STATUS ProgramPciLpssI2C (
+  IN  UINT8 BusNo
+  );
+EFI_STATUS ByteReadI2C_Basic(
+  IN  UINT8 BusNo,
+  IN  UINT8 SlaveAddress,
+  IN  UINTN ReadBytes,
+  OUT UINT8 *ReadBuffer,
+  IN  UINT8 Start,
+  IN  UINT8 End
+  );
+EFI_STATUS ByteWriteI2C_Basic(
+  IN  UINT8 BusNo,
+  IN  UINT8 SlaveAddress,
+  IN  UINTN WriteBytes,
+  IN  UINT8 *WriteBuffer,
+  IN  UINT8 Start,
+  IN  UINT8 End
+  );
+
+EFI_STATUS ByteReadI2C(
+  IN  UINT8 BusNo,
+  IN  UINT8 SlaveAddress,
+  IN  UINT8 Offset,
+  IN  UINTN ReadBytes,
+  OUT UINT8 *ReadBuffer
+  );
+EFI_STATUS ByteWriteI2C(
+  IN  UINT8 BusNo,
+  IN  UINT8 SlaveAddress,
+  IN  UINT8 Offset,
+  IN  UINTN WriteBytes,
+  IN  UINT8 *WriteBuffer
+  );
+
+#endif  // I2C_REGS_A0_H
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Library/PchPlatformLib.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Library/PchPlatformLib.h
new file mode 100644
index 0000000000..f6593324a9
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Library/PchPlatformLib.h
@@ -0,0 +1,115 @@
+/**
+**/
+/**
+
+Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+  @file
+  PchPlatformLib.h
+
+  @brief
+  Header file for PchPlatform Lib.
+
+**/
+#ifndef _PCH_PLATFORM_LIB_H_
+#define _PCH_PLATFORM_LIB_H_
+
+///
+/// Timeout value used when Sending / Receiving messages.
+/// NOTE: this must cover the longest possible wait time
+/// between message being sent and response being available.
+/// e.g. Virtual function readiness might take some time.
+///
+VOID
+EFIAPI
+PchPmTimerStall (
+  IN  UINTN   Microseconds
+  )
+/**
+
+  @brief
+  Delay for at least the request number of microseconds.
+  This function would be called by runtime driver, please do not use any MMIO marco here.
+
+  @param[in] Microseconds         Number of microseconds to delay.
+
+  @retval NONE
+
+**/
+;
+
+BOOLEAN
+EFIAPI
+PchIsSpiDescriptorMode (
+  IN  UINTN   SpiBase
+  )
+/**
+
+  @brief
+  Check whether SPI is in descriptor mode
+
+  @param[in] SpiBase              The PCH Spi Base Address
+
+  @retval TRUE                    SPI is in descriptor mode
+  @retval FALSE                   SPI is not in descriptor mode
+
+**/
+;
+
+PCH_STEPPING
+EFIAPI
+PchStepping (
+  VOID
+  )
+/**
+
+  @brief
+  Return Pch stepping type
+
+  @param[in] None
+
+  @retval PCH_STEPPING            Pch stepping type
+
+**/
+;
+
+BOOLEAN
+IsPchSupported (
+  VOID
+  )
+/**
+
+  @brief
+  Determine if PCH is supported
+
+  @param[in] None
+
+  @retval TRUE                    PCH is supported
+  @retval FALSE                   PCH is not supported
+
+**/
+;
+
+VOID
+EFIAPI
+PchAlternateAccessMode (
+  IN  UINTN         IlbBase,
+  IN  BOOLEAN       AmeCtrl
+  )
+/**
+
+  This function can be called to enable/disable Alternate Access Mode
+
+  @param[in] IlbBase              The PCH ILB Base Address
+  @param[in] AmeCtrl              If TRUE, enable Alternate Access Mode.
+                                  If FALSE, disable Alternate Access Mode.
+
+  @retval NONE
+
+**/
+;
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchAccess.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchAccess.h
new file mode 100644
index 0000000000..d7988c55be
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchAccess.h
@@ -0,0 +1,471 @@
+/**
+
+Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+  @file
+  PchAccess.h
+
+  @brief
+  Macros that simplify accessing PCH devices's PCI registers.
+
+  ** NOTE ** these macros assume the PCH device is on BUS 0
+
+**/
+#ifndef _PCH_ACCESS_H_
+#define _PCH_ACCESS_H_
+
+#include "PchRegs.h"
+#include "PchCommonDefinitions.h"
+
+#ifndef STALL_ONE_MICRO_SECOND
+#define STALL_ONE_MICRO_SECOND 1
+#endif
+#ifndef STALL_ONE_SECOND
+#define STALL_ONE_SECOND 1000000
+#endif
+
+///
+/// Memory Mapped PCI Access macros
+///
+///
+/// PCI Device MM Base
+///
+#ifndef MmPciAddress
+#define MmPciAddress(Segment, Bus, Device, Function, Register) \
+  ((UINTN) PatchPcdGet64 (PcdPciExpressBaseAddress) + \
+   (UINTN) (Bus << 20) + \
+   (UINTN) (Device << 15) + \
+   (UINTN) (Function << 12) + \
+   (UINTN) (Register) \
+  )
+#endif
+///
+/// Pch Controller PCI access macros
+///
+#define PCH_RCRB_BASE ( \
+  MmioRead32 (MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_LPC, \
+  PCI_FUNCTION_NUMBER_PCH_LPC), \
+  R_PCH_LPC_RCBA)) & B_PCH_LPC_RCBA_BAR \
+  )
+
+///
+/// Device 0x1b, Function 0
+///
+#define PchAzaliaPciCfg32(Register) \
+  MmioRead32 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_AZALIA, \
+  0, \
+  Register) \
+  )
+
+#define PchAzaliaPciCfg32Or(Register, OrData) \
+  MmioOr32 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_AZALIA, \
+  0, \
+  Register), \
+  OrData \
+  )
+
+#define PchAzaliaPciCfg32And(Register, AndData) \
+  MmioAnd32 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_AZALIA, \
+  0, \
+  Register), \
+  AndData \
+  )
+
+#define PchAzaliaPciCfg32AndThenOr(Register, AndData, OrData) \
+  MmioAndThenOr32 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_AZALIA, \
+  0, \
+  Register), \
+  OrData \
+  )
+
+#define PchAzaliaPciCfg16(Register) \
+  MmioRead16 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_AZALIA, \
+  0, \
+  Register) \
+  )
+
+#define PchAzaliaPciCfg16Or(Register, OrData) \
+  MmioOr16 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_AZALIA, \
+  0, \
+  Register), \
+  OrData \
+  )
+
+#define PchAzaliaPciCfg16And(Register, AndData) \
+  MmioAnd16 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_AZALIA, \
+  0, \
+  Register), \
+  AndData \
+  )
+
+#define PchAzaliaPciCfg16AndThenOr(Register, AndData, OrData) \
+  MmioAndThenOr16 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_AZALIA, \
+  0, \
+  Register), \
+  AndData, \
+  OrData \
+  )
+
+#define PchAzaliaPciCfg8(Register)  MmioRead8 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_AZALIA, 0, Register))
+
+#define PchAzaliaPciCfg8Or(Register, OrData) \
+  MmioOr8 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_AZALIA, \
+  0, \
+  Register), \
+  OrData \
+  )
+
+#define PchAzaliaPciCfg8And(Register, AndData) \
+  MmioAnd8 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_AZALIA, \
+  0, \
+  Register), \
+  AndData \
+  )
+
+#define PchAzaliaPciCfg8AndThenOr(Register, AndData, OrData) \
+  MmioAndThenOr8 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_AZALIA, \
+  0, \
+  Register), \
+  AndData, \
+  OrData \
+  )
+
+///
+/// Device 0x1f, Function 0
+///
+#define PchLpcPciCfg32(Register)  MmioRead32 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, Register))
+
+#define PchLpcMmioOr32 (Register, OrData) \
+  MmioOr32 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_LPC, \
+  0, \
+  Register), \
+  OrData \
+  )
+
+#define PchLpcPciCfg32And(Register, AndData) \
+  MmioAnd32 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_LPC, \
+  0, \
+  Register), \
+  AndData \
+  )
+
+#define PchLpcPciCfg32AndThenOr(Register, AndData, OrData) \
+  MmioAndThenOr32 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_LPC, \
+  0, \
+  Register), \
+  AndData, \
+  OrData \
+  )
+
+#define PchLpcPciCfg16(Register)  MmioRead16 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, Register))
+
+#define PchLpcPciCfg16Or(Register, OrData) \
+  MmioOr16 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_LPC, \
+  0, \
+  Register), \
+  OrData \
+  )
+
+#define PchLpcPciCfg16And(Register, AndData) \
+  MmioAndThenOr16 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_LPC, \
+  0, \
+  Register), \
+  AndData \
+  )
+
+#define PchLpcPciCfg16AndThenOr(Register, AndData, OrData) \
+  MmioAndThenOr16 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_LPC, \
+  0, \
+  Register), \
+  AndData, \
+  OrData \
+  )
+
+#define PchLpcPciCfg8(Register) MmioRead8 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, Register))
+
+#define PchLpcPciCfg8Or(Register, OrData) \
+  MmioOr8 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_LPC, \
+  0, \
+  Register), \
+  OrData \
+  )
+
+#define PchLpcPciCfg8And(Register, AndData) \
+  MmioAnd8 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_LPC, \
+  0, \
+  Register), \
+  AndData \
+  )
+
+#define PchLpcPciCfg8AndThenOr(Register, AndData, OrData) \
+  MmioAndThenOr8 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_LPC, \
+  0, \
+  Register), \
+  AndData, \
+  OrData \
+  )
+
+
+///
+/// SATA device 0x13, Function 0
+///
+#define PchSataPciCfg32(Register) MmioRead32 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SATA, PCI_FUNCTION_NUMBER_PCH_SATA, Register))
+
+#define PchSataPciCfg32Or(Register, OrData) \
+  MmioOr32 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_SATA, \
+  PCI_FUNCTION_NUMBER_PCH_SATA, \
+  Register), \
+  OrData \
+  )
+
+#define PchSataPciCfg32And(Register, AndData) \
+  MmioAnd32 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_SATA, \
+  PCI_FUNCTION_NUMBER_PCH_SATA, \
+  Register), \
+  AndData \
+  )
+
+#define PchSataPciCfg32AndThenOr(Register, AndData, OrData) \
+  MmioAndThenOr32 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_SATA, \
+  PCI_FUNCTION_NUMBER_PCH_SATA, \
+  Register), \
+  AndData, \
+  OrData \
+  )
+
+#define PchSataPciCfg16(Register) MmioRead16 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SATA, PCI_FUNCTION_NUMBER_PCH_SATA, Register))
+
+#define PchSataPciCfg16Or(Register, OrData) \
+  MmioOr16 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_SATA, \
+  PCI_FUNCTION_NUMBER_PCH_SATA, \
+  Register), \
+  OrData \
+  )
+
+#define PchSataPciCfg16And(Register, AndData) \
+  MmioAndThenOr16 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_SATA, \
+  PCI_FUNCTION_NUMBER_PCH_SATA, \
+  Register), \
+  AndData \
+  )
+
+#define PchSataPciCfg16AndThenOr(Register, AndData, OrData) \
+  MmioAndThenOr16 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_SATA, \
+  PCI_FUNCTION_NUMBER_PCH_SATA, \
+  Register), \
+  AndData, \
+  OrData \
+  )
+
+#define PchSataPciCfg8(Register)  MmioRead8 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SATA, PCI_FUNCTION_NUMBER_PCH_SATA, Register))
+
+#define PchSataPciCfg8Or(Register, OrData) \
+  MmioOr8 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_SATA, \
+  PCI_FUNCTION_NUMBER_PCH_SATA, \
+  Register), \
+  OrData \
+  )
+
+#define PchSataPciCfg8And(Register, AndData) \
+  MmioAnd8 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_SATA, \
+  PCI_FUNCTION_NUMBER_PCH_SATA, \
+  Register), \
+  AndData \
+  )
+
+#define PchSataPciCfg8AndThenOr(Register, AndData, OrData) \
+  MmioAndThenOr8 ( \
+  MmPciAddress (0, \
+  DEFAULT_PCI_BUS_NUMBER_PCH, \
+  PCI_DEVICE_NUMBER_PCH_SATA, \
+  PCI_FUNCTION_NUMBER_PCH_SATA, \
+  Register), \
+  AndData, \
+  OrData \
+  )
+
+
+///
+/// Root Complex Register Block
+///
+#define PchMmRcrb32(Register)                           MmioRead32 (PCH_RCRB_BASE + Register)
+
+#define PchMmRcrb32Or(Register, OrData)                 MmioOr32 (PCH_RCRB_BASE + Register, OrData)
+
+#define PchMmRcrb32And(Register, AndData)               MmioAnd32 (PCH_RCRB_BASE + Register, AndData)
+
+#define PchMmRcrb32AndThenOr(Register, AndData, OrData) MmioAndThenOr32 (PCH_RCRB_BASE + Register, AndData, OrData)
+
+#define PchMmRcrb16(Register)                           MmioRead16 (PCH_RCRB_BASE + Register)
+
+#define PchMmRcrb16Or(Register, OrData)                 MmioOr16 (PCH_RCRB_BASE + Register, OrData)
+
+#define PchMmRcrb16And(Register, AndData)               MmioAnd16 (PCH_RCRB_BASE + Register, AndData)
+
+#define PchMmRcrb16AndThenOr(Register, AndData, OrData) MmioAndThenOr16 (PCH_RCRB_BASE + Register, AndData, OrData)
+
+#define PchMmRcrb8(Register)                            MmioRead8 (PCH_RCRB_BASE + Register)
+
+#define PchMmRcrb8Or(Register, OrData)                  MmioOr8 (PCH_RCRB_BASE + Register, OrData)
+
+#define PchMmRcrb8And(Register, AndData)                MmioAnd8 (PCH_RCRB_BASE + Register, AndData)
+
+#define PchMmRcrb8AndThenOr(Register, AndData, OrData)  MmioAndThenOr8 (PCH_RCRB_BASE + Register, AndData, OrData)
+
+
+///
+/// Message Bus
+///
+
+///
+/// Message Bus Registers
+///
+#define MC_MCR            0x000000D0 // Cunit Message Control Register
+#define MC_MDR            0x000000D4 // Cunit Message Data Register
+#define MC_MCRX           0x000000D8 // Cunit Message Control Register Extension
+
+///
+/// Message Bus API
+///
+#define MSG_BUS_ENABLED   0x000000F0
+#define MSGBUS_MASKHI     0xFFFFFF00
+#define MSGBUS_MASKLO     0x000000FF
+#define MESSAGE_DWORD_EN  BIT4 | BIT5 | BIT6 | BIT7
+
+#define PchMsgBusRead32(PortId, Register, Dbuff, ReadOpCode, WriteOpCode) \
+{ \
+  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCRX), (UINT32) (Register & MSGBUS_MASKHI)); \
+  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCR ), (UINT32) ((ReadOpCode << 24) | (PortId << 16) | ((Register & MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN)); \
+  (Dbuff) = MmioRead32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MDR)); \
+}
+
+#define PchMsgBusAnd32(PortId, Register, Dbuff, AndData, ReadOpCode, WriteOpCode) \
+{ \
+  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCRX), (UINT32) (Register & MSGBUS_MASKHI)); \
+  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCR ), (UINT32) ((ReadOpCode << 24) | (PortId << 16) | ((Register & MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN)); \
+  (Dbuff) = MmioRead32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MDR)); \
+  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCRX), (UINT32) (Register & MSGBUS_MASKHI)); \
+  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MDR ), (UINT32) (Dbuff & AndData)); \
+  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCR ), (UINT32) ((WriteOpCode << 24) | (PortId << 16) | ((Register & MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN)); \
+}
+
+#define PchMsgBusOr32(PortId, Register, Dbuff, OrData, ReadOpCode, WriteOpCode) \
+{ \
+  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCRX), (UINT32) (Register & MSGBUS_MASKHI)); \
+  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCR ), (UINT32) ((ReadOpCode << 24) | (PortId << 16) | ((Register & MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN)); \
+  (Dbuff) = MmioRead32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MDR)); \
+  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCRX), (UINT32) (Register & MSGBUS_MASKHI)); \
+  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MDR ), (UINT32) (Dbuff | OrData)); \
+  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCR ), (UINT32) ((WriteOpCode << 24) | (PortId << 16) | ((Register & MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN)); \
+}
+
+#define PchMsgBusAndThenOr32(PortId, Register, Dbuff, AndData, OrData, ReadOpCode, WriteOpCode) \
+{ \
+  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCRX), (UINT32) (Register & MSGBUS_MASKHI)); \
+  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCR ), (UINT32) ((ReadOpCode << 24) | (PortId << 16) | ((Register & MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN)); \
+  (Dbuff) = MmioRead32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MDR)); \
+  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCRX), (UINT32) (Register & MSGBUS_MASKHI)); \
+  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MDR ), (UINT32) ((Dbuff & AndData) | OrData)); \
+  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCR ), (UINT32) ((WriteOpCode << 24) | (PortId << 16) | ((Register & MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN)); \
+}
+
+typedef struct _PCH_MSG_BUS_TABLE_STRUCT {
+  UINT32      PortId;
+  UINT32      Address;
+  UINT32      AndMask;
+  UINT32      OrMask;
+  UINT32      ReadOpCode;
+  UINT32      WriteOpCode;
+} PCH_MSG_BUS_TABLE_STRUCT_TABLE_STRUCT;
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchCommonDefinitions.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchCommonDefinitions.h
new file mode 100644
index 0000000000..c12f0d2195
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchCommonDefinitions.h
@@ -0,0 +1,210 @@
+/*++
+
+Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  PchCommonDefinitions.h
+
+Abstract:
+
+  This header file provides common definitions for PCH
+
+--*/
+#ifndef _PCH_COMMON_DEFINITIONS_H_
+#define _PCH_COMMON_DEFINITIONS_H_
+
+//
+//  MMIO access macros
+//
+#define PchMmioAddress(BaseAddr, Register)  ((UINTN) BaseAddr + (UINTN) (Register))
+
+//
+// 32 bit MMIO access
+//
+#define PchMmio32Ptr(BaseAddr, Register)  ((volatile UINT32 *) PchMmioAddress (BaseAddr, Register))
+
+#define PchMmio32(BaseAddr, Register)     *PchMmio32Ptr (BaseAddr, Register)
+
+#define PchMmio32Or(BaseAddr, Register, OrData) \
+  PchMmio32 (BaseAddr, Register) = (UINT32) \
+    (PchMmio32 (BaseAddr, Register) | (UINT32) (OrData))
+
+#define PchMmio32And(BaseAddr, Register, AndData) \
+  PchMmio32 (BaseAddr, Register) = (UINT32) \
+    (PchMmio32 (BaseAddr, Register) & (UINT32) (AndData))
+
+#define PchMmio32AndThenOr(BaseAddr, Register, AndData, OrData) \
+  PchMmio32 (BaseAddr, Register) = (UINT32) \
+    ((PchMmio32 (BaseAddr, Register) & (UINT32) (AndData)) | (UINT32) (OrData))
+
+//
+// 16 bit MMIO access
+//
+#define PchMmio16Ptr(BaseAddr, Register)  ((volatile UINT16 *) PchMmioAddress (BaseAddr, Register))
+
+#define PchMmio16(BaseAddr, Register)     *PchMmio16Ptr (BaseAddr, Register)
+
+#define PchMmio16Or(BaseAddr, Register, OrData) \
+  PchMmio16 (BaseAddr, Register) = (UINT16) \
+    (PchMmio16 (BaseAddr, Register) | (UINT16) (OrData))
+
+#define PchMmio16And(BaseAddr, Register, AndData) \
+  PchMmio16 (BaseAddr, Register) = (UINT16) \
+    (PchMmio16 (BaseAddr, Register) & (UINT16) (AndData))
+
+#define PchMmio16AndThenOr(BaseAddr, Register, AndData, OrData) \
+  PchMmio16 (BaseAddr, Register) = (UINT16) \
+    ((PchMmio16 (BaseAddr, Register) & (UINT16) (AndData)) | (UINT16) (OrData))
+
+//
+// 8 bit MMIO access
+//
+#define PchMmio8Ptr(BaseAddr, Register) ((volatile UINT8 *) PchMmioAddress (BaseAddr, Register))
+
+#define PchMmio8(BaseAddr, Register)    *PchMmio8Ptr (BaseAddr, Register)
+
+#define PchMmio8Or(BaseAddr, Register, OrData) \
+  PchMmio8 (BaseAddr, Register) = (UINT8) \
+    (PchMmio8 (BaseAddr, Register) | (UINT8) (OrData))
+
+#define PchMmio8And(BaseAddr, Register, AndData) \
+  PchMmio8 (BaseAddr, Register) = (UINT8) \
+    (PchMmio8 (BaseAddr, Register) & (UINT8) (AndData))
+
+#define PchMmio8AndThenOr(BaseAddr, Register, AndData, OrData) \
+  PchMmio8 (BaseAddr, Register) = (UINT8) \
+    ((PchMmio8 (BaseAddr, Register) & (UINT8) (AndData)) | (UINT8) (OrData))
+
+//
+// Memory Mapped PCI Access macros
+//
+#define PCH_PCI_EXPRESS_BASE_ADDRESS  0xE0000000
+//
+// PCI Device MM Base
+//
+#define PchPciDeviceMmBase(Bus, Device, Function) \
+    ( \
+      (UINTN) PCH_PCI_EXPRESS_BASE_ADDRESS + (UINTN) (Bus << 20) + (UINTN) (Device << 15) + (UINTN) \
+        (Function << 12) \
+    )
+
+//
+// PCI Device MM Address
+//
+#define PchPciDeviceMmAddress(Segment, Bus, Device, Function, Register) \
+    ( \
+      (UINTN) PCH_PCI_EXPRESS_BASE_ADDRESS + (UINTN) (Bus << 20) + (UINTN) (Device << 15) + (UINTN) \
+        (Function << 12) + (UINTN) (Register) \
+    )
+
+//
+// 32 bit PCI access
+//
+#define PchMmPci32Ptr(Segment, Bus, Device, Function, Register) \
+    ((volatile UINT32 *) PchPciDeviceMmAddress (Segment, Bus, Device, Function, Register))
+
+#define PchMmPci32(Segment, Bus, Device, Function, Register)  *PchMmPci32Ptr (Segment, Bus, Device, Function, Register)
+
+#define PchMmPci32Or(Segment, Bus, Device, Function, Register, OrData) \
+  PchMmPci32 ( \
+  Segment, \
+  Bus, \
+  Device, \
+  Function, \
+  Register \
+  ) = (UINT32) (PchMmPci32 (Segment, Bus, Device, Function, Register) | (UINT32) (OrData))
+
+#define PchMmPci32And(Segment, Bus, Device, Function, Register, AndData) \
+  PchMmPci32 ( \
+  Segment, \
+  Bus, \
+  Device, \
+  Function, \
+  Register \
+  ) = (UINT32) (PchMmPci32 (Segment, Bus, Device, Function, Register) & (UINT32) (AndData))
+
+#define PchMmPci32AndThenOr(Segment, Bus, Device, Function, Register, AndData, OrData) \
+  PchMmPci32 ( \
+  Segment, \
+  Bus, \
+  Device, \
+  Function, \
+  Register \
+  ) = (UINT32) ((PchMmPci32 (Segment, Bus, Device, Function, Register) & (UINT32) (AndData)) | (UINT32) (OrData))
+
+//
+// 16 bit PCI access
+//
+#define PchMmPci16Ptr(Segment, Bus, Device, Function, Register) \
+    ((volatile UINT16 *) PchPciDeviceMmAddress (Segment, Bus, Device, Function, Register))
+
+#define PchMmPci16(Segment, Bus, Device, Function, Register)  *PchMmPci16Ptr (Segment, Bus, Device, Function, Register)
+
+#define PchMmPci16Or(Segment, Bus, Device, Function, Register, OrData) \
+  PchMmPci16 ( \
+  Segment, \
+  Bus, \
+  Device, \
+  Function, \
+  Register \
+  ) = (UINT16) (PchMmPci16 (Segment, Bus, Device, Function, Register) | (UINT16) (OrData))
+
+#define PchMmPci16And(Segment, Bus, Device, Function, Register, AndData) \
+  PchMmPci16 ( \
+  Segment, \
+  Bus, \
+  Device, \
+  Function, \
+  Register \
+  ) = (UINT16) (PchMmPci16 (Segment, Bus, Device, Function, Register) & (UINT16) (AndData))
+
+#define PchMmPci16AndThenOr(Segment, Bus, Device, Function, Register, AndData, OrData) \
+  PchMmPci16 ( \
+  Segment, \
+  Bus, \
+  Device, \
+  Function, \
+  Register \
+  ) = (UINT16) ((PchMmPci16 (Segment, Bus, Device, Function, Register) & (UINT16) (AndData)) | (UINT16) (OrData))
+
+//
+// 8 bit PCI access
+//
+#define PchMmPci8Ptr(Segment, Bus, Device, Function, Register) \
+    ((volatile UINT8 *) PchPciDeviceMmAddress (Segment, Bus, Device, Function, Register))
+
+#define PchMmPci8(Segment, Bus, Device, Function, Register) *PchMmPci8Ptr (Segment, Bus, Device, Function, Register)
+
+#define PchMmPci8Or(Segment, Bus, Device, Function, Register, OrData) \
+  PchMmPci8 ( \
+  Segment, \
+  Bus, \
+  Device, \
+  Function, \
+  Register \
+  ) = (UINT8) (PchMmPci8 (Segment, Bus, Device, Function, Register) | (UINT8) (OrData))
+
+#define PchMmPci8And(Segment, Bus, Device, Function, Register, AndData) \
+  PchMmPci8 ( \
+  Segment, \
+  Bus, \
+  Device, \
+  Function, \
+  Register \
+  ) = (UINT8) (PchMmPci8 (Segment, Bus, Device, Function, Register) & (UINT8) (AndData))
+
+#define PchMmPci8AndThenOr(Segment, Bus, Device, Function, Register, AndData, OrData) \
+  PchMmPci8 ( \
+  Segment, \
+  Bus, \
+  Device, \
+  Function, \
+  Register \
+  ) = (UINT8) ((PchMmPci8 (Segment, Bus, Device, Function, Register) & (UINT8) (AndData)) | (UINT8) (OrData))
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs.h
new file mode 100644
index 0000000000..3314b9dcf7
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs.h
@@ -0,0 +1,205 @@
+/**
+
+Copyright (c) 2011  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+  @file
+  PchRegs.h
+
+  @brief
+  Register names for VLV SC.
+
+  Conventions:
+
+  - Prefixes:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values of bits within the registers
+    Definitions beginning with "S_" are register sizes
+    Definitions beginning with "N_" are the bit position
+  - In general, PCH registers are denoted by "_PCH_" in register names
+  - Registers / bits that are different between PCH generations are denoted by
+    "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_VLV_"
+  - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+    at the end of the register/bit names
+  - Registers / bits of new devices introduced in a PCH generation will be just named
+    as "_PCH_" without <generation_name> inserted.
+
+**/
+#ifndef _PCH_REGS_H_
+#define _PCH_REGS_H_
+
+///
+/// Bit Definitions. BUGBUG: drive these definitions to code base. Should not need
+/// to be part of chipset modules
+///
+#ifndef BIT0
+#define BIT0  0x0001
+#define BIT1  0x0002
+#define BIT2  0x0004
+#define BIT3  0x0008
+#define BIT4  0x0010
+#define BIT5  0x0020
+#define BIT6  0x0040
+#define BIT7  0x0080
+#define BIT8  0x0100
+#define BIT9  0x0200
+#define BIT10 0x0400
+#define BIT11 0x0800
+#define BIT12 0x1000
+#define BIT13 0x2000
+#define BIT14 0x4000
+#define BIT15 0x8000
+#define BIT16 0x00010000
+#define BIT17 0x00020000
+#define BIT18 0x00040000
+#define BIT19 0x00080000
+#define BIT20 0x00100000
+#define BIT21 0x00200000
+#define BIT22 0x00400000
+#define BIT23 0x00800000
+#define BIT24 0x01000000
+#define BIT25 0x02000000
+#define BIT26 0x04000000
+#define BIT27 0x08000000
+#define BIT28 0x10000000
+#define BIT29 0x20000000
+#define BIT30 0x40000000
+#define BIT31 0x80000000
+#define BIT32 0x100000000
+#define BIT33 0x200000000
+#define BIT34 0x400000000
+#define BIT35 0x800000000
+#define BIT36 0x1000000000
+#define BIT37 0x2000000000
+#define BIT38 0x4000000000
+#define BIT39 0x8000000000
+#define BIT40 0x10000000000
+#define BIT41 0x20000000000
+#define BIT42 0x40000000000
+#define BIT43 0x80000000000
+#define BIT44 0x100000000000
+#define BIT45 0x200000000000
+#define BIT46 0x400000000000
+#define BIT47 0x800000000000
+#define BIT48 0x1000000000000
+#define BIT49 0x2000000000000
+#define BIT50 0x4000000000000
+#define BIT51 0x8000000000000
+#define BIT52 0x10000000000000
+#define BIT53 0x20000000000000
+#define BIT54 0x40000000000000
+#define BIT55 0x80000000000000
+#define BIT56 0x100000000000000
+#define BIT57 0x200000000000000
+#define BIT58 0x400000000000000
+#define BIT59 0x800000000000000
+#define BIT60 0x1000000000000000
+#define BIT61 0x2000000000000000
+#define BIT62 0x4000000000000000
+#define BIT63 0x8000000000000000
+#endif
+///
+/// The default PCH PCI bus number
+///
+#define DEFAULT_PCI_BUS_NUMBER_PCH  0
+
+///
+/// Default Vendor ID and Subsystem ID
+///
+#define V_PCH_INTEL_VENDOR_ID   0x8086
+#define V_PCH_DEFAULT_SID       0x7270
+#define V_PCH_DEFAULT_SVID_SID  (V_PCH_INTEL_VENDOR_ID + (V_PCH_DEFAULT_SID << 16))
+
+///
+/// Include device register definitions
+///
+#include "PchRegs/PchRegsHda.h"
+#include "PchRegs/PchRegsLpss.h"
+#include "PchRegs/PchRegsPcie.h"
+#include "PchRegs/PchRegsPcu.h"
+#include "PchRegs/PchRegsRcrb.h"
+#include "PchRegs/PchRegsSata.h"
+#include "PchRegs/PchRegsScc.h"
+#include "PchRegs/PchRegsSmbus.h"
+#include "PchRegs/PchRegsSpi.h"
+#include "PchRegs/PchRegsUsb.h"
+//#include "PchRegs/PchRegsLpe.h"
+
+///
+/// Device IDS that are PCH Server specific
+///
+#define IS_PCH_DEVICE_ID(DeviceId) \
+    ( \
+      (DeviceId == V_PCH_LPC_DEVICE_ID_0) || \
+      (DeviceId == V_PCH_LPC_DEVICE_ID_1) || \
+      (DeviceId == V_PCH_LPC_DEVICE_ID_2) || \
+      (DeviceId == V_PCH_LPC_DEVICE_ID_3) \
+    )
+
+#define IS_PCH_VLV_LPC_DEVICE_ID(DeviceId) \
+    ( \
+      IS_PCH_DEVICE_ID (DeviceId) \
+    )
+
+#define IS_PCH_VLV_SATA_DEVICE_ID(DeviceId) \
+    ( \
+      IS_PCH_VLV_SATA_AHCI_DEVICE_ID (DeviceId) || \
+      IS_PCH_VLV_SATA_MODE_DEVICE_ID (DeviceId) || \
+      IS_PCH_VLV_SATA_RAID_DEVICE_ID (DeviceId) \
+    )
+
+#define IS_PCH_VLV_SATA_AHCI_DEVICE_ID(DeviceId) \
+    ( \
+      (DeviceId == V_PCH_SATA_DEVICE_ID_D_AHCI) || \
+      (DeviceId == V_PCH_SATA_DEVICE_ID_M_AHCI) \
+    )
+
+#define IS_PCH_VLV_SATA_RAID_DEVICE_ID(DeviceId) \
+    ( \
+      (DeviceId == V_PCH_SATA_DEVICE_ID_D_RAID) || \
+      (DeviceId == V_PCH_SATA_DEVICE_ID_M_RAID) \
+    )
+
+#define IS_PCH_VLV_SATA_MODE_DEVICE_ID(DeviceId) \
+    ( \
+      (DeviceId == V_PCH_SATA_DEVICE_ID_D_IDE) || \
+      (DeviceId == V_PCH_SATA_DEVICE_ID_M_IDE) \
+    )
+#define IS_PCH_VLV_USB_DEVICE_ID(DeviceId) \
+    ( \
+      (DeviceId == V_PCH_USB_DEVICE_ID_0) || \
+      (DeviceId == V_PCH_USB_DEVICE_ID_1) \
+    )
+#define IS_PCH_VLV_PCIE_DEVICE_ID(DeviceId) \
+    ( \
+      (DeviceId == V_PCH_PCIE_DEVICE_ID_0) || \
+      (DeviceId == V_PCH_PCIE_DEVICE_ID_1) || \
+      (DeviceId == V_PCH_PCIE_DEVICE_ID_2) || \
+      (DeviceId == V_PCH_PCIE_DEVICE_ID_3) || \
+      (DeviceId == V_PCH_PCIE_DEVICE_ID_4) || \
+      (DeviceId == V_PCH_PCIE_DEVICE_ID_5) || \
+      (DeviceId == V_PCH_PCIE_DEVICE_ID_6) || \
+      (DeviceId == V_PCH_PCIE_DEVICE_ID_7) \
+    )
+
+///
+/// Any device ID that is Valleyview SC
+///
+#define IS_PCH_VLV_DEVICE_ID(DeviceId) \
+    ( \
+      IS_PCH_VLV_LPC_DEVICE_ID (DeviceId) || \
+      IS_PCH_VLV_SATA_DEVICE_ID (DeviceId) || \
+      IS_PCH_VLV_USB_DEVICE_ID (DeviceId) || \
+      IS_PCH_VLV_PCIE_DEVICE_ID (DeviceId) || \
+      (DeviceId) == V_PCH_SMBUS_DEVICE_ID || \
+      (DeviceId) == V_PCH_HDA_DEVICE_ID_0 || \
+      (DeviceId) == V_PCH_HDA_DEVICE_ID_1 \
+    )
+
+#define IS_SUPPORTED_DEVICE_ID(DeviceId)  IS_PCH_VLV_DEVICE_ID (DeviceId)
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsHda.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsHda.h
new file mode 100644
index 0000000000..b25a79a4d1
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsHda.h
@@ -0,0 +1,50 @@
+/**
+
+Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+  @file
+  PchRegsHda.h
+
+  @brief
+  Register names for PCH High Definition Audio device.
+
+  Conventions:
+
+  - Prefixes:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values of bits within the registers
+    Definitions beginning with "S_" are register sizes
+    Definitions beginning with "N_" are the bit position
+  - In general, PCH registers are denoted by "_PCH_" in register names
+  - Registers / bits that are different between PCH generations are denoted by
+    "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_VLV_"
+  - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+    at the end of the register/bit names
+  - Registers / bits of new devices introduced in a PCH generation will be just named
+    as "_PCH_" without <generation_name> inserted.
+
+**/
+#ifndef _PCH_REGS_HDA_H_
+#define _PCH_REGS_HDA_H_
+
+///
+/// Azalia Controller Registers (D27:F0)
+///
+#define PCI_DEVICE_NUMBER_PCH_AZALIA       27
+#define PCI_FUNCTION_NUMBER_PCH_AZALIA     0
+
+#define R_PCH_HDA_PCS                      0x54  // Power Management Control and Status
+#define B_PCH_HDA_PCS_DATA                 0xFF000000 // Data, does not apply
+#define B_PCH_HDA_PCS_CCE                  BIT23 // Bus Power Control Enable, does not apply
+#define B_PCH_HDA_PCS_PMES                 BIT15 // PME Status
+#define B_PCH_HDA_PCS_PMEE                 BIT8  // PME Enable
+#define B_PCH_HDA_PCS_PS                   (BIT1 | BIT0) // Power State - D0/D3 Hot
+#define V_PCH_HDA_PCS_PS0                  0x00
+#define V_PCH_HDA_PCS_PS3                  0x03
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsLpss.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsLpss.h
new file mode 100644
index 0000000000..a5d0d49cdb
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsLpss.h
@@ -0,0 +1,486 @@
+/*++
+
+Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  PchRegsLpss.h
+
+Abstract:
+
+  Register names for VLV Low Input Output (LPSS) module.
+
+  Conventions:
+
+  - Prefixes:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values of bits within the registers
+    Definitions beginning with "S_" are register sizes
+    Definitions beginning with "N_" are the bit position
+  - In general, PCH registers are denoted by "_PCH_" in register names
+  - Registers / bits that are different between PCH generations are denoted by
+    "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_VLV_"
+  - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+    at the end of the register/bit names
+  - Registers / bits of new devices introduced in a PCH generation will be just named
+    as "_PCH_" without <generation_name> inserted.
+
+--*/
+#ifndef _PCH_REGS_LPSS_H_
+#define _PCH_REGS_LPSS_H_
+
+
+//
+// Low Power Input Output (LPSS) Module Registers
+//
+
+//
+// LPSS DMAC Modules
+// PCI Config Space Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_LPSS_DMAC0          30
+#define PCI_DEVICE_NUMBER_PCH_LPSS_DMAC1          24
+#define PCI_FUNCTION_NUMBER_PCH_LPSS_DMAC         0
+
+#define R_PCH_LPSS_DMAC_DEVVENDID                 0x00  // Device ID & Vendor ID
+#define B_PCH_LPSS_DMAC_DEVVENDID_DID             0xFFFF0000 // Device ID
+#define B_PCH_LPSS_DMAC_DEVVENDID_VID             0x0000FFFF // Vendor ID
+
+#define R_PCH_LPSS_DMAC_STSCMD                    0x04  // Status & Command
+#define B_PCH_LPSS_DMAC_STSCMD_RMA                BIT29 // RMA
+#define B_PCH_LPSS_DMAC_STSCMD_RCA                BIT28 // RCA
+#define B_PCH_LPSS_DMAC_STSCMD_CAPLIST            BIT20 // Capability List
+#define B_PCH_LPSS_DMAC_STSCMD_INTRSTS            BIT19 // Interrupt Status
+#define B_PCH_LPSS_DMAC_STSCMD_INTRDIS            BIT10 // Interrupt Disable
+#define B_PCH_LPSS_DMAC_STSCMD_SERREN             BIT8  // SERR# Enable
+#define B_PCH_LPSS_DMAC_STSCMD_BME                BIT2  // Bus Master Enable
+#define B_PCH_LPSS_DMAC_STSCMD_MSE                BIT1  // Memory Space Enable
+
+#define R_PCH_LPSS_DMAC_REVCC                     0x08  // Revision ID & Class Code
+#define B_PCH_LPSS_DMAC_REVCC_CC                  0xFFFFFF00 // Class Code
+#define B_PCH_LPSS_DMAC_REVCC_RID                 0x000000FF // Revision ID
+
+#define R_PCH_LPSS_DMAC_CLHB                      0x0C
+#define B_PCH_LPSS_DMAC_CLHB_MULFNDEV             BIT23
+#define B_PCH_LPSS_DMAC_CLHB_HT                   0x007F0000 // Header Type
+#define B_PCH_LPSS_DMAC_CLHB_LT                   0x0000FF00 // Latency Timer
+#define B_PCH_LPSS_DMAC_CLHB_CLS                  0x000000FF // Cache Line Size
+
+#define R_PCH_LPSS_DMAC_BAR                       0x10  // BAR
+#define B_PCH_LPSS_DMAC_BAR_BA                    0xFFFFC000 // Base Address
+#define V_PCH_LPSS_DMAC_BAR_SIZE                  0x4000
+#define N_PCH_LPSS_DMAC_BAR_ALIGNMENT             14
+#define B_PCH_LPSS_DMAC_BAR_SI                    0x00000FF0 // Size Indicator
+#define B_PCH_LPSS_DMAC_BAR_PF                    BIT3  // Prefetchable
+#define B_PCH_LPSS_DMAC_BAR_TYPE                  (BIT2 | BIT1) // Type
+#define B_PCH_LPSS_DMAC_BAR_MS                    BIT0  // Message Space
+
+#define R_PCH_LPSS_DMAC_BAR1                      0x14  // BAR 1
+#define B_PCH_LPSS_DMAC_BAR1_BA                   0xFFFFF000 // Base Address
+#define B_PCH_LPSS_DMAC_BAR1_SI                   0x00000FF0 // Size Indicator
+#define B_PCH_LPSS_DMAC_BAR1_PF                   BIT3  // Prefetchable
+#define B_PCH_LPSS_DMAC_BAR1_TYPE                 (BIT2 | BIT1) // Type
+#define B_PCH_LPSS_DMAC_BAR1_MS                   BIT0  // Message Space
+
+#define R_PCH_LPSS_DMAC_SSID                      0x2C  // Sub System ID
+#define B_PCH_LPSS_DMAC_SSID_SID                  0xFFFF0000 // Sub System ID
+#define B_PCH_LPSS_DMAC_SSID_SVID                 0x0000FFFF // Sub System Vendor ID
+
+#define R_PCH_LPSS_DMAC_ERBAR                     0x30  // Expansion ROM BAR
+#define B_PCH_LPSS_DMAC_ERBAR_BA                  0xFFFFFFFF // Expansion ROM Base Address
+
+#define R_PCH_LPSS_DMAC_CAPPTR                    0x34  // Capability Pointer
+#define B_PCH_LPSS_DMAC_CAPPTR_CPPWR              0xFF  // Capability Pointer Power
+
+#define R_PCH_LPSS_DMAC_INTR                      0x3C  // Interrupt
+#define B_PCH_LPSS_DMAC_INTR_ML                   0xFF000000 // Max Latency
+#define B_PCH_LPSS_DMAC_INTR_MG                   0x00FF0000
+#define B_PCH_LPSS_DMAC_INTR_IP                   0x00000F00 // Interrupt Pin
+#define B_PCH_LPSS_DMAC_INTR_IL                   0x000000FF // Interrupt Line
+
+#define R_PCH_LPSS_DMAC_PCAPID                    0x80  // Power Capability ID
+#define B_PCH_LPSS_DMAC_PCAPID_PS                 0xF8000000 // PME Support
+#define B_PCH_LPSS_DMAC_PCAPID_VS                 0x00070000 // Version
+#define B_PCH_LPSS_DMAC_PCAPID_NC                 0x0000FF00 // Next Capability
+#define B_PCH_LPSS_DMAC_PCAPID_PC                 0x000000FF // Power Capability
+
+#define R_PCH_LPSS_DMAC_PCS                       0x84  // PME Control Status
+#define B_PCH_LPSS_DMAC_PCS_PMESTS                BIT15 // PME Status
+#define B_PCH_LPSS_DMAC_PCS_PMEEN                 BIT8  // PME Enable
+#define B_PCH_LPSS_DMAC_PCS_NSS                   BIT3  // No Soft Reset
+#define B_PCH_LPSS_DMAC_PCS_PS                    (BIT1 | BIT0) // Power State
+
+#define R_PCH_LPSS_DMAC_MANID                     0xF8  // Manufacturer ID
+#define B_PCH_LPSS_DMAC_MANID_MANID               0xFFFFFFFF // Manufacturer ID
+
+
+//
+// LPSS I2C Module
+// PCI Config Space Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_LPSS_I2C            24
+#define PCI_FUNCTION_NUMBER_PCH_LPSS_I2C0         1
+#define PCI_FUNCTION_NUMBER_PCH_LPSS_I2C1         2
+#define PCI_FUNCTION_NUMBER_PCH_LPSS_I2C2         3
+#define PCI_FUNCTION_NUMBER_PCH_LPSS_I2C3         4
+#define PCI_FUNCTION_NUMBER_PCH_LPSS_I2C4         5
+#define PCI_FUNCTION_NUMBER_PCH_LPSS_I2C5         6
+#define PCI_FUNCTION_NUMBER_PCH_LPSS_I2C6         7
+
+#define R_PCH_LPSS_I2C_DEVVENDID                  0x00  // Device ID & Vendor ID
+#define B_PCH_LPSS_I2C_DEVVENDID_DID              0xFFFF0000 // Device ID
+#define B_PCH_LPSS_I2C_DEVVENDID_VID              0x0000FFFF // Vendor ID
+
+#define R_PCH_LPSS_I2C_STSCMD                     0x04  // Status & Command
+#define B_PCH_LPSS_I2C_STSCMD_RMA                 BIT29 // RMA
+#define B_PCH_LPSS_I2C_STSCMD_RCA                 BIT28 // RCA
+#define B_PCH_LPSS_I2C_STSCMD_CAPLIST             BIT20 // Capability List
+#define B_PCH_LPSS_I2C_STSCMD_INTRSTS             BIT19 // Interrupt Status
+#define B_PCH_LPSS_I2C_STSCMD_INTRDIS             BIT10 // Interrupt Disable
+#define B_PCH_LPSS_I2C_STSCMD_SERREN              BIT8  // SERR# Enable
+#define B_PCH_LPSS_I2C_STSCMD_BME                 BIT2  // Bus Master Enable
+#define B_PCH_LPSS_I2C_STSCMD_MSE                 BIT1  // Memory Space Enable
+
+#define R_PCH_LPSS_I2C_REVCC                      0x08  // Revision ID & Class Code
+#define B_PCH_LPSS_I2C_REVCC_CC                   0xFFFFFF00 // Class Code
+#define B_PCH_LPSS_I2C_REVCC_RID                  0x000000FF // Revision ID
+
+#define R_PCH_LPSS_I2C_CLHB                       0x0C
+#define B_PCH_LPSS_I2C_CLHB_MULFNDEV              BIT23
+#define B_PCH_LPSS_I2C_CLHB_HT                    0x007F0000 // Header Type
+#define B_PCH_LPSS_I2C_CLHB_LT                    0x0000FF00 // Latency Timer
+#define B_PCH_LPSS_I2C_CLHB_CLS                   0x000000FF // Cache Line Size
+
+#define R_PCH_LPSS_I2C_BAR                        0x10  // BAR
+#define B_PCH_LPSS_I2C_BAR_BA                     0xFFFFF000 // Base Address
+#define V_PCH_LPSS_I2C_BAR_SIZE                   0x1000
+#define N_PCH_LPSS_I2C_BAR_ALIGNMENT              12
+#define B_PCH_LPSS_I2C_BAR_SI                     0x00000FF0 // Size Indicator
+#define B_PCH_LPSS_I2C_BAR_PF                     BIT3  // Prefetchable
+#define B_PCH_LPSS_I2C_BAR_TYPE                   (BIT2 | BIT1) // Type
+#define B_PCH_LPSS_I2C_BAR_MS                     BIT0  // Message Space
+
+#define R_PCH_LPSS_I2C_BAR1                       0x14  // BAR 1
+#define B_PCH_LPSS_I2C_BAR1_BA                    0xFFFFF000 // Base Address
+#define B_PCH_LPSS_I2C_BAR1_SI                    0x00000FF0 // Size Indicator
+#define B_PCH_LPSS_I2C_BAR1_PF                    BIT3  // Prefetchable
+#define B_PCH_LPSS_I2C_BAR1_TYPE                  (BIT2 | BIT1) // Type
+#define B_PCH_LPSS_I2C_BAR1_MS                    BIT0  // Message Space
+
+#define R_PCH_LPSS_I2C_SSID                       0x2C  // Sub System ID
+#define B_PCH_LPSS_I2C_SSID_SID                   0xFFFF0000 // Sub System ID
+#define B_PCH_LPSS_I2C_SSID_SVID                  0x0000FFFF // Sub System Vendor ID
+
+#define R_PCH_LPSS_I2C_ERBAR                      0x30  // Expansion ROM BAR
+#define B_PCH_LPSS_I2C_ERBAR_BA                   0xFFFFFFFF // Expansion ROM Base Address
+
+#define R_PCH_LPSS_I2C_CAPPTR                     0x34  // Capability Pointer
+#define B_PCH_LPSS_I2C_CAPPTR_CPPWR               0xFF  // Capability Pointer Power
+
+#define R_PCH_LPSS_I2C_INTR                       0x3C  // Interrupt
+#define B_PCH_LPSS_I2C_INTR_ML                    0xFF000000 // Max Latency
+#define B_PCH_LPSS_I2C_INTR_MG                    0x00FF0000
+#define B_PCH_LPSS_I2C_INTR_IP                    0x00000F00 // Interrupt Pin
+#define B_PCH_LPSS_I2C_INTR_IL                    0x000000FF // Interrupt Line
+
+#define R_PCH_LPSS_I2C_PCAPID                     0x80  // Power Capability ID
+#define B_PCH_LPSS_I2C_PCAPID_PS                  0xF8000000 // PME Support
+#define B_PCH_LPSS_I2C_PCAPID_VS                  0x00070000 // Version
+#define B_PCH_LPSS_I2C_PCAPID_NC                  0x0000FF00 // Next Capability
+#define B_PCH_LPSS_I2C_PCAPID_PC                  0x000000FF // Power Capability
+
+#define R_PCH_LPSS_I2C_PCS                        0x84  // PME Control Status
+#define B_PCH_LPSS_I2C_PCS_PMESTS                 BIT15 // PME Status
+#define B_PCH_LPSS_I2C_PCS_PMEEN                  BIT8  // PME Enable
+#define B_PCH_LPSS_I2C_PCS_NSS                    BIT3  // No Soft Reset
+#define B_PCH_LPSS_I2C_PCS_PS                     (BIT1 | BIT0) // Power State
+
+#define R_PCH_LPSS_I2C_MANID                      0xF8  // Manufacturer ID
+#define B_PCH_LPSS_I2C_MANID_MANID                0xFFFFFFFF // Manufacturer ID
+
+//
+// LPSS I2C Module
+// Memory Space Registers
+//
+#define R_PCH_LPSS_I2C_MEM_RESETS                 0x804 // Software Reset
+#define B_PCH_LPSS_I2C_MEM_RESETS_FUNC            BIT1  // Function Clock Domain Reset
+#define B_PCH_LPSS_I2C_MEM_RESETS_APB             BIT0  // APB Domain Reset
+
+//
+// LPSS PWM Modules
+// PCI Config Space Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_LPSS_PWM            30
+#define PCI_FUNCTION_NUMBER_PCH_LPSS_PWM0         1
+#define PCI_FUNCTION_NUMBER_PCH_LPSS_PWM1         2
+
+#define R_PCH_LPSS_PWM_DEVVENDID                  0x00  // Device ID & Vendor ID
+#define B_PCH_LPSS_PWM_DEVVENDID_DID              0xFFFF0000 // Device ID
+#define B_PCH_LPSS_PWM_DEVVENDID_VID              0x0000FFFF // Vendor ID
+
+#define R_PCH_LPSS_PWM_STSCMD                     0x04  // Status & Command
+#define B_PCH_LPSS_PWM_STSCMD_RMA                 BIT29 // RMA
+#define B_PCH_LPSS_PWM_STSCMD_RCA                 BIT28 // RCA
+#define B_PCH_LPSS_PWM_STSCMD_CAPLIST             BIT20 // Capability List
+#define B_PCH_LPSS_PWM_STSCMD_INTRSTS             BIT19 // Interrupt Status
+#define B_PCH_LPSS_PWM_STSCMD_INTRDIS             BIT10 // Interrupt Disable
+#define B_PCH_LPSS_PWM_STSCMD_SERREN              BIT8  // SERR# Enable
+#define B_PCH_LPSS_PWM_STSCMD_BME                 BIT2  // Bus Master Enable
+#define B_PCH_LPSS_PWM_STSCMD_MSE                 BIT1  // Memory Space Enable
+
+#define R_PCH_LPSS_PWM_REVCC                      0x08  // Revision ID & Class Code
+#define B_PCH_LPSS_PWM_REVCC_CC                   0xFFFFFF00 // Class Code
+#define B_PCH_LPSS_PWM_REVCC_RID                  0x000000FF // Revision ID
+
+#define R_PCH_LPSS_PWM_CLHB                       0x0C
+#define B_PCH_LPSS_PWM_CLHB_MULFNDEV              BIT23
+#define B_PCH_LPSS_PWM_CLHB_HT                    0x007F0000 // Header Type
+#define B_PCH_LPSS_PWM_CLHB_LT                    0x0000FF00 // Latency Timer
+#define B_PCH_LPSS_PWM_CLHB_CLS                   0x000000FF // Cache Line Size
+
+#define R_PCH_LPSS_PWM_BAR                        0x10  // BAR
+#define B_PCH_LPSS_PWM_BAR_BA                     0xFFFFF000 // Base Address
+#define V_PCH_LPSS_PWM_BAR_SIZE                   0x1000
+#define N_PCH_LPSS_PWM_BAR_ALIGNMENT              12
+#define B_PCH_LPSS_PWM_BAR_SI                     0x00000FF0 // Size Indicator
+#define B_PCH_LPSS_PWM_BAR_PF                     BIT3  // Prefetchable
+#define B_PCH_LPSS_PWM_BAR_TYPE                   (BIT2 | BIT1) // Type
+#define B_PCH_LPSS_PWM_BAR_MS                     BIT0  // Message Space
+
+#define R_PCH_LPSS_PWM_BAR1                       0x14  // BAR 1
+#define B_PCH_LPSS_PWM_BAR1_BA                    0xFFFFF000 // Base Address
+#define B_PCH_LPSS_PWM_BAR1_SI                    0x00000FF0 // Size Indicator
+#define B_PCH_LPSS_PWM_BAR1_PF                    BIT3  // Prefetchable
+#define B_PCH_LPSS_PWM_BAR1_TYPE                  (BIT2 | BIT1) // Type
+#define B_PCH_LPSS_PWM_BAR1_MS                    BIT0  // Message Space
+
+#define R_PCH_LPSS_PWM_SSID                       0x2C  // Sub System ID
+#define B_PCH_LPSS_PWM_SSID_SID                   0xFFFF0000 // Sub System ID
+#define B_PCH_LPSS_PWM_SSID_SVID                  0x0000FFFF // Sub System Vendor ID
+
+#define R_PCH_LPSS_PWM_ERBAR                      0x30  // Expansion ROM BAR
+#define B_PCH_LPSS_PWM_ERBAR_BA                   0xFFFFFFFF // Expansion ROM Base Address
+
+#define R_PCH_LPSS_PWM_CAPPTR                     0x34  // Capability Pointer
+#define B_PCH_LPSS_PWM_CAPPTR_CPPWR               0xFF  // Capability Pointer Power
+
+#define R_PCH_LPSS_PWM_INTR                       0x3C  // Interrupt
+#define B_PCH_LPSS_PWM_INTR_ML                    0xFF000000 // Max Latency
+#define B_PCH_LPSS_PWM_INTR_MG                    0x00FF0000
+#define B_PCH_LPSS_PWM_INTR_IP                    0x00000F00 // Interrupt Pin
+#define B_PCH_LPSS_PWM_INTR_IL                    0x000000FF // Interrupt Line
+
+#define R_PCH_LPSS_PWM_PCAPID                     0x80  // Power Capability ID
+#define B_PCH_LPSS_PWM_PCAPID_PS                  0xF8000000 // PME Support
+#define B_PCH_LPSS_PWM_PCAPID_VS                  0x00070000 // Version
+#define B_PCH_LPSS_PWM_PCAPID_NC                  0x0000FF00 // Next Capability
+#define B_PCH_LPSS_PWM_PCAPID_PC                  0x000000FF // Power Capability
+
+#define R_PCH_LPSS_PWM_PCS                        0x84  // PME Control Status
+#define B_PCH_LPSS_PWM_PCS_PMESTS                 BIT15 // PME Status
+#define B_PCH_LPSS_PWM_PCS_PMEEN                  BIT8  // PME Enable
+#define B_PCH_LPSS_PWM_PCS_NSS                    BIT3  // No Soft Reset
+#define B_PCH_LPSS_PWM_PCS_PS                     (BIT1 | BIT0) // Power State
+
+#define R_PCH_LPSS_PWM_MANID                      0xF8  // Manufacturer ID
+#define B_PCH_LPSS_PWM_MANID_MANID                0xFFFFFFFF // Manufacturer ID
+
+//
+// LPSS PWM Module
+// Memory Space Registers
+//
+#define R_PCH_LPSS_PWM_MEM_RESETS                 0x804 // Software Reset
+#define B_PCH_LPSS_PWM_MEM_RESETS_FUNC            BIT1  // Function Clock Domain Reset
+#define B_PCH_LPSS_PWM_MEM_RESETS_APB             BIT0  // APB Domain Reset
+
+//
+// LPSS HSUART Modules
+// PCI Config Space Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_LPSS_HSUART         30
+#define PCI_FUNCTION_NUMBER_PCH_LPSS_HSUART0      3
+#define PCI_FUNCTION_NUMBER_PCH_LPSS_HSUART1      4
+
+#define R_PCH_LPSS_HSUART_DEVVENDID               0x00  // Device ID & Vendor ID
+#define B_PCH_LPSS_HSUART_DEVVENDID_DID           0xFFFF0000 // Device ID
+#define B_PCH_LPSS_HSUART_DEVVENDID_VID           0x0000FFFF // Vendor ID
+
+#define R_PCH_LPSS_HSUART_STSCMD                  0x04  // Status & Command
+#define B_PCH_LPSS_HSUART_STSCMD_RMA              BIT29 // RMA
+#define B_PCH_LPSS_HSUART_STSCMD_RCA              BIT28 // RCA
+#define B_PCH_LPSS_HSUART_STSCMD_CAPLIST          BIT20 // Capability List
+#define B_PCH_LPSS_HSUART_STSCMD_INTRSTS          BIT19 // Interrupt Status
+#define B_PCH_LPSS_HSUART_STSCMD_INTRDIS          BIT10 // Interrupt Disable
+#define B_PCH_LPSS_HSUART_STSCMD_SERREN           BIT8  // SERR# Enable
+#define B_PCH_LPSS_HSUART_STSCMD_BME              BIT2  // Bus Master Enable
+#define B_PCH_LPSS_HSUART_STSCMD_MSE              BIT1  // Memory Space Enable
+
+#define R_PCH_LPSS_HSUART_REVCC                   0x08  // Revision ID & Class Code
+#define B_PCH_LPSS_HSUART_REVCC_CC                0xFFFFFF00 // Class Code
+#define B_PCH_LPSS_HSUART_REVCC_RID               0x000000FF // Revision ID
+
+#define R_PCH_LPSS_HSUART_CLHB                    0x0C
+#define B_PCH_LPSS_HSUART_CLHB_MULFNDEV           BIT23
+#define B_PCH_LPSS_HSUART_CLHB_HT                 0x007F0000 // Header Type
+#define B_PCH_LPSS_HSUART_CLHB_LT                 0x0000FF00 // Latency Timer
+#define B_PCH_LPSS_HSUART_CLHB_CLS                0x000000FF // Cache Line Size
+
+#define R_PCH_LPSS_HSUART_BAR                     0x10  // BAR
+#define B_PCH_LPSS_HSUART_BAR_BA                  0xFFFFF000 // Base Address
+#define V_PCH_LPSS_HSUART_BAR_SIZE                0x1000
+#define N_PCH_LPSS_HSUART_BAR_ALIGNMENT           12
+#define B_PCH_LPSS_HSUART_BAR_SI                  0x00000FF0 // Size Indicator
+#define B_PCH_LPSS_HSUART_BAR_PF                  BIT3  // Prefetchable
+#define B_PCH_LPSS_HSUART_BAR_TYPE                (BIT2 | BIT1) // Type
+#define B_PCH_LPSS_HSUART_BAR_MS                  BIT0  // Message Space
+
+#define R_PCH_LPSS_HSUART_BAR1                    0x14  // BAR 1
+#define B_PCH_LPSS_HSUART_BAR1_BA                 0xFFFFF000 // Base Address
+#define B_PCH_LPSS_HSUART_BAR1_SI                 0x00000FF0 // Size Indicator
+#define B_PCH_LPSS_HSUART_BAR1_PF                 BIT3  // Prefetchable
+#define B_PCH_LPSS_HSUART_BAR1_TYPE               (BIT2 | BIT1) // Type
+#define B_PCH_LPSS_HSUART_BAR1_MS                 BIT0  // Message Space
+
+#define R_PCH_LPSS_HSUART_SSID                    0x2C  // Sub System ID
+#define B_PCH_LPSS_HSUART_SSID_SID                0xFFFF0000 // Sub System ID
+#define B_PCH_LPSS_HSUART_SSID_SVID               0x0000FFFF // Sub System Vendor ID
+
+#define R_PCH_LPSS_HSUART_ERBAR                   0x30  // Expansion ROM BAR
+#define B_PCH_LPSS_HSUART_ERBAR_BA                0xFFFFFFFF // Expansion ROM Base Address
+
+#define R_PCH_LPSS_HSUART_CAPPTR                  0x34  // Capability Pointer
+#define B_PCH_LPSS_HSUART_CAPPTR_CPPWR            0xFF  // Capability Pointer Power
+
+#define R_PCH_LPSS_HSUART_INTR                    0x3C  // Interrupt
+#define B_PCH_LPSS_HSUART_INTR_ML                 0xFF000000 // Max Latency
+#define B_PCH_LPSS_HSUART_INTR_MG                 0x00FF0000
+#define B_PCH_LPSS_HSUART_INTR_IP                 0x00000F00 // Interrupt Pin
+#define B_PCH_LPSS_HSUART_INTR_IL                 0x000000FF // Interrupt Line
+
+#define R_PCH_LPSS_HSUART_PCAPID                  0x80  // Power Capability ID
+#define B_PCH_LPSS_HSUART_PCAPID_PS               0xF8000000 // PME Support
+#define B_PCH_LPSS_HSUART_PCAPID_VS               0x00070000 // Version
+#define B_PCH_LPSS_HSUART_PCAPID_NC               0x0000FF00 // Next Capability
+#define B_PCH_LPSS_HSUART_PCAPID_PC               0x000000FF // Power Capability
+
+#define R_PCH_LPSS_HSUART_PCS                     0x84  // PME Control Status
+#define B_PCH_LPSS_HSUART_PCS_PMESTS              BIT15 // PME Status
+#define B_PCH_LPSS_HSUART_PCS_PMEEN               BIT8  // PME Enable
+#define B_PCH_LPSS_HSUART_PCS_NSS                 BIT3  // No Soft Reset
+#define B_PCH_LPSS_HSUART_PCS_PS                  (BIT1 | BIT0) // Power State
+
+#define R_PCH_LPSS_HSUART_MANID                   0xF8  // Manufacturer ID
+#define B_PCH_LPSS_HSUART_MANID_MANID             0xFFFFFFFF // Manufacturer ID
+
+//
+// LPSS HSUART Module
+// Memory Space Registers
+//
+#define R_PCH_LPSS_HSUART_MEM_PCP                 0x800 // Private Clock Parameters
+#define B_PCH_LPSS_HSUART_MEM_PCP_CLKUPDATE       BIT31 // Clock Divider Update
+#define B_PCH_LPSS_HSUART_MEM_PCP_NVAL            0x7FFF0000 // N value for the M over N divider
+#define B_PCH_LPSS_HSUART_MEM_PCP_MVAL            0x0000FFFE // M value for the M over N divider
+#define B_PCH_LPSS_HSUART_MEM_PCP_CLKEN           BIT0  // Clock Enable
+
+#define R_PCH_LPSS_HSUART_MEM_RESETS              0x804 // Software Reset
+#define B_PCH_LPSS_HSUART_MEM_RESETS_FUNC         BIT1  // Function Clock Domain Reset
+#define B_PCH_LPSS_HSUART_MEM_RESETS_APB          BIT0  // APB Domain Reset
+
+//
+// LPSS SPI Module
+// PCI Config Space Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_LPSS_SPI            30
+#define PCI_FUNCTION_NUMBER_PCH_LPSS_SPI          5
+
+#define R_PCH_LPSS_SPI_DEVVENDID                  0x00  // Device ID & Vendor ID
+#define B_PCH_LPSS_SPI_DEVVENDID_DID              0xFFFF0000 // Device ID
+#define B_PCH_LPSS_SPI_DEVVENDID_VID              0x0000FFFF // Vendor ID
+
+#define R_PCH_LPSS_SPI_STSCMD                     0x04  // Status & Command
+#define B_PCH_LPSS_SPI_STSCMD_RMA                 BIT29 // RMA
+#define B_PCH_LPSS_SPI_STSCMD_RCA                 BIT28 // RCA
+#define B_PCH_LPSS_SPI_STSCMD_CAPLIST             BIT20 // Capability List
+#define B_PCH_LPSS_SPI_STSCMD_INTRSTS             BIT19 // Interrupt Status
+#define B_PCH_LPSS_SPI_STSCMD_INTRDIS             BIT10 // Interrupt Disable
+#define B_PCH_LPSS_SPI_STSCMD_SERREN              BIT8  // SERR# Enable
+#define B_PCH_LPSS_SPI_STSCMD_BME                 BIT2  // Bus Master Enable
+#define B_PCH_LPSS_SPI_STSCMD_MSE                 BIT1  // Memory Space Enable
+
+#define R_PCH_LPSS_SPI_REVCC                      0x08  // Revision ID & Class Code
+#define B_PCH_LPSS_SPI_REVCC_CC                   0xFFFFFF00 // Class Code
+#define B_PCH_LPSS_SPI_REVCC_RID                  0x000000FF // Revision ID
+
+#define R_PCH_LPSS_SPI_CLHB                       0x0C
+#define B_PCH_LPSS_SPI_CLHB_MULFNDEV              BIT23
+#define B_PCH_LPSS_SPI_CLHB_HT                    0x007F0000 // Header Type
+#define B_PCH_LPSS_SPI_CLHB_LT                    0x0000FF00 // Latency Timer
+#define B_PCH_LPSS_SPI_CLHB_CLS                   0x000000FF // Cache Line Size
+
+#define R_PCH_LPSS_SPI_BAR                        0x10  // BAR
+#define B_PCH_LPSS_SPI_BAR_BA                     0xFFFFF000 // Base Address
+#define V_PCH_LPSS_SPI_BAR_SIZE                   0x1000
+#define N_PCH_LPSS_SPI_BAR_ALIGNMENT              12
+#define B_PCH_LPSS_SPI_BAR_SI                     0x00000FF0 // Size Indicator
+#define B_PCH_LPSS_SPI_BAR_PF                     BIT3  // Prefetchable
+#define B_PCH_LPSS_SPI_BAR_TYPE                   (BIT2 | BIT1) // Type
+#define B_PCH_LPSS_SPI_BAR_MS                     BIT0  // Message Space
+
+#define R_PCH_LPSS_SPI_BAR1                       0x14  // BAR 1
+#define B_PCH_LPSS_SPI_BAR1_BA                    0xFFFFF000 // Base Address
+#define B_PCH_LPSS_SPI_BAR1_SI                    0x00000FF0 // Size Indicator
+#define B_PCH_LPSS_SPI_BAR1_PF                    BIT3  // Prefetchable
+#define B_PCH_LPSS_SPI_BAR1_TYPE                  (BIT2 | BIT1) // Type
+#define B_PCH_LPSS_SPI_BAR1_MS                    BIT0  // Message Space
+
+#define R_PCH_LPSS_SPI_SSID                       0x2C  // Sub System ID
+#define B_PCH_LPSS_SPI_SSID_SID                   0xFFFF0000 // Sub System ID
+#define B_PCH_LPSS_SPI_SSID_SVID                  0x0000FFFF // Sub System Vendor ID
+
+#define R_PCH_LPSS_SPI_ERBAR                      0x30  // Expansion ROM BAR
+#define B_PCH_LPSS_SPI_ERBAR_BA                   0xFFFFFFFF // Expansion ROM Base Address
+
+#define R_PCH_LPSS_SPI_CAPPTR                     0x34  // Capability Pointer
+#define B_PCH_LPSS_SPI_CAPPTR_CPPWR               0xFF  // Capability Pointer Power
+
+#define R_PCH_LPSS_SPI_INTR                       0x3C  // Interrupt
+#define B_PCH_LPSS_SPI_INTR_ML                    0xFF000000 // Max Latency
+#define B_PCH_LPSS_SPI_INTR_MG                    0x00FF0000
+#define B_PCH_LPSS_SPI_INTR_IP                    0x00000F00 // Interrupt Pin
+#define B_PCH_LPSS_SPI_INTR_IL                    0x000000FF // Interrupt Line
+
+#define R_PCH_LPSS_SPI_PCAPID                     0x80  // Power Capability ID
+#define B_PCH_LPSS_SPI_PCAPID_PS                  0xF8000000 // PME Support
+#define B_PCH_LPSS_SPI_PCAPID_VS                  0x00070000 // Version
+#define B_PCH_LPSS_SPI_PCAPID_NC                  0x0000FF00 // Next Capability
+#define B_PCH_LPSS_SPI_PCAPID_PC                  0x000000FF // Power Capability
+
+#define R_PCH_LPSS_SPI_PCS                        0x84  // PME Control Status
+#define B_PCH_LPSS_SPI_PCS_PMESTS                 BIT15 // PME Status
+#define B_PCH_LPSS_SPI_PCS_PMEEN                  BIT8  // PME Enable
+#define B_PCH_LPSS_SPI_PCS_NSS                    BIT3  // No Soft Reset
+#define B_PCH_LPSS_SPI_PCS_PS                     (BIT1 | BIT0) // Power State
+
+#define R_PCH_LPSS_SPI_MANID                      0xF8  // Manufacturer ID
+#define B_PCH_LPSS_SPI_MANID_MANID                0xFFFFFFFF // Manufacturer ID
+
+//
+// LPSS SPI Module
+// Memory Space Registers
+//
+#define R_PCH_LPSS_SPI_MEM_PCP                    0x400 // Private Clock Parameters
+#define B_PCH_LPSS_SPI_MEM_PCP_CLKUPDATE          BIT31 // Clock Divider Update
+#define B_PCH_LPSS_SPI_MEM_PCP_NVAL               0x7FFF0000 // N value for the M over N divider
+#define B_PCH_LPSS_SPI_MEM_PCP_MVAL               0x0000FFFE // M value for the M over N divider
+#define B_PCH_LPSS_SPI_MEM_PCP_CLKEN              BIT0  // Clock Enable
+
+#define R_PCH_LPSS_SPI_MEM_RESETS                 0x404 // Software Reset
+#define B_PCH_LPSS_SPI_MEM_RESETS_FUNC            BIT1  // Function Clock Domain Reset
+#define B_PCH_LPSS_SPI_MEM_RESETS_APB             BIT0  // APB Domain Reset
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsPcie.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsPcie.h
new file mode 100644
index 0000000000..8b1ae403c9
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsPcie.h
@@ -0,0 +1,83 @@
+/**
+
+Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+  @file
+  PchRegsPcie.h
+
+  @brief
+  Register names for VLV PCI-E root port devices
+
+  Conventions:
+
+  - Prefixes:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values of bits within the registers
+    Definitions beginning with "S_" are register sizes
+    Definitions beginning with "N_" are the bit position
+  - In general, PCH registers are denoted by "_PCH_" in register names
+  - Registers / bits that are different between PCH generations are denoted by
+    "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_VLV_"
+  - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+    at the end of the register/bit names
+  - Registers / bits of new devices introduced in a PCH generation will be just named
+    as "_PCH_" without <generation_name> inserted.
+
+--*/
+#ifndef _PCH_REGS_PCIE_H_
+#define _PCH_REGS_PCIE_H_
+
+#define PCH_PCIE_MAX_ROOT_PORTS                            4
+
+///
+/// VLV PCI Express Root Ports (D28:F0~F3)
+///
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS              28
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1           0
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2           1
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3           2
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4           3
+
+#define R_PCH_PCIE_ID                                      0x00  // Identifiers
+#define B_PCH_PCIE_ID_DID                                  0xFFFF0000 // Device ID
+#define V_PCH_PCIE_DEVICE_ID_0                             0x0F48  // PCIE Root Port #1
+#define V_PCH_PCIE_DEVICE_ID_1                             0x0F4A  // PCIE Root Port #2
+#define V_PCH_PCIE_DEVICE_ID_2                             0x0F4C  // PCIE Root Port #3
+#define V_PCH_PCIE_DEVICE_ID_3                             0x0F4E  // PCIE Root Port #4
+#define B_PCH_PCIE_ID_VID                                  0x0000FFFF // Vendor ID
+#define V_PCH_PCIE_VENDOR_ID                               V_PCH_INTEL_VENDOR_ID
+
+
+#define R_PCH_PCIE_BNUM_SLT                                0x18  // Bus Numbers; Secondary Latency Timer
+#define B_PCH_PCIE_BNUM_SLT_SLT                            0xFF000000 // Secondary Latency Timer
+#define B_PCH_PCIE_BNUM_SLT_SBBN                           0x00FF0000 // Subordinate Bus Number
+#define B_PCH_PCIE_BNUM_SLT_SCBN                           0x0000FF00 // Secondary Bus Number
+#define B_PCH_PCIE_BNUM_SLT_PBN                            0x000000FF // Primary Bus Number
+#define R_PCH_PCIE_CAPP                                    0x34  // Capabilities List Pointer
+#define B_PCH_PCIE_CAPP                                    0xFF  // Capabilities Pointer
+
+#define R_PCH_PCIE_SLCTL_SLSTS                             0x58  // Slot Control; Slot Status
+#define S_PCH_PCIE_SLCTL_SLSTS                             4
+#define B_PCH_PCIE_SLCTL_SLSTS_DLLSC                       BIT24 // Data Link Layer State Changed
+#define B_PCH_PCIE_SLCTL_SLSTS_PDS                         BIT22 // Presence Detect State
+#define B_PCH_PCIE_SLCTL_SLSTS_MS                          BIT21 // MRL Sensor State
+#define B_PCH_PCIE_SLCTL_SLSTS_PDC                         BIT19 // Presence Detect Changed
+#define B_PCH_PCIE_SLCTL_SLSTS_MSC                         BIT18 // MRL Sensor Changed
+#define B_PCH_PCIE_SLCTL_SLSTS_PFD                         BIT17 // Power Fault Detected
+#define B_PCH_PCIE_SLCTL_SLSTS_DLLSCE                      BIT12 // Data Link Layer State Changed Enable
+#define B_PCH_PCIE_SLCTL_SLSTS_PCC                         BIT10 // Power Controller Control
+#define B_PCH_PCIE_SLCTL_SLSTS_HPE                         BIT5  // Hot Plug Interrupt Enable
+#define B_PCH_PCIE_SLCTL_SLSTS_CCE                         BIT4  // Command Completed Interrupt Enable
+#define B_PCH_PCIE_SLCTL_SLSTS_PDE                         BIT3  // Presence Detect Changed Enable
+
+#define R_PCH_PCIE_SVID                                    0x94  // Subsystem Vendor IDs
+#define S_PCH_PCIE_SVID                                    4
+#define B_PCH_PCIE_SVID_SID                                0xFFFF0000 // Subsystem Identifier
+#define B_PCH_PCIE_SVID_SVID                               0x0000FFFF // Subsystem Vendor Identifier
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsPcu.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsPcu.h
new file mode 100644
index 0000000000..456c033bc6
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsPcu.h
@@ -0,0 +1,1201 @@
+/*++
+
+Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  PchRegsPcu.h
+
+Abstract:
+
+  Register names for VLV PCU device.
+
+  Conventions:
+
+  - Prefixes:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values of bits within the registers
+    Definitions beginning with "S_" are register sizes
+    Definitions beginning with "N_" are the bit position
+  - In general, PCH registers are denoted by "_PCH_" in register names
+  - Registers / bits that are different between PCH generations are denoted by
+    "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_VLV_"
+  - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+    at the end of the register/bit names
+  - Registers / bits of new devices introduced in a PCH generation will be just named
+    as "_PCH_" without <generation_name> inserted.
+
+--*/
+#ifndef _PCH_REGS_LPC_H_
+#define _PCH_REGS_LPC_H_
+
+//
+// VLV PCU Registers (D31:F0)
+//
+#define PCI_DEVICE_NUMBER_PCH_LPC                 31
+#define PCI_FUNCTION_NUMBER_PCH_LPC               0
+
+// Silicon Steppings
+typedef enum {
+  PchA0         = 0,
+  PchA1         = 1,
+  PchB0         = 2,
+  PchB1         = 3,
+  PchB2         = 4,
+  PchB3         = 5,
+  PchC0         = 6,
+  PchD0         = 7,
+  PchSteppingMax
+} PCH_STEPPING;
+
+#define R_PCH_LPC_REG_ID                          0x00  // Identifiers Register
+#define B_PCH_LPC_DEVICE_ID                       0xFFFF0000 // Device Identification
+#define B_PCH_LPC_VENDOR_ID                       0x0000FFFF // Vendor Identification
+#define V_PCH_LPC_VENDOR_ID                       V_PCH_INTEL_VENDOR_ID // Vendor ID for Intel
+//
+// General VLV PCU Device ID
+//
+#define V_PCH_LPC_DEVICE_ID_0                     0x0F1C
+#define V_PCH_LPC_DEVICE_ID_1                     0x0F1D
+#define V_PCH_LPC_DEVICE_ID_2                     0x0F1E
+#define V_PCH_LPC_DEVICE_ID_3                     0x0F1F
+
+#define R_PCH_LPC_COMMAND                         0x04  // Command
+#define B_PCH_LPC_COMMAND_ID                      BIT10 // Interrupt Disable
+#define B_PCH_LPC_COMMAND_FBE                     BIT9  // Fast Back to Back Enable
+#define B_PCH_LPC_COMMAND_SERR_EN                 BIT8  // SERR# Enable
+#define B_PCH_LPC_COMMAND_WCC                     BIT7  // Wait Cycle Control
+#define B_PCH_LPC_COMMAND_PER                     BIT6  // Parity Error Response Enable
+#define B_PCH_LPC_COMMAND_VPS                     BIT5  // VGA Palette Snoop
+#define B_PCH_LPC_COMMAND_MWIE                    BIT4  // Memory Write and Invalidate Enable
+#define B_PCH_LPC_COMMAND_SCE                     BIT3  // Special Cycle Enable
+#define B_PCH_LPC_COMMAND_BME                     BIT2  // Bus Master Enable
+#define B_PCH_LPC_COMMAND_MSE                     BIT1  // Memory Space Enable
+#define B_PCH_LPC_COMMAND_IOSE                    BIT0  // I/O Space Enable
+
+#define R_PCH_LPC_DEV_STS                         0x06  // Status
+#define B_PCH_LPC_DEV_STS_DPE                     BIT15 // Detected Parity Error
+#define B_PCH_LPC_DEV_STS_SSE                     BIT14 // Signaled System Error
+#define B_PCH_LPC_DEV_STS_RMA                     BIT13 // Received Master Abort
+#define B_PCH_LPC_DEV_STS_RTA                     BIT12 // Received Target Abort
+#define B_PCH_LPC_DEV_STS_STA                     BIT11 // Signaled Target Abort
+#define B_PCH_LPC_DEV_STS_DEVT_STS                (BIT10 | BIT9) // DEVSEL# Timing Status
+#define B_PCH_LPC_DEV_STS_MDPED                   BIT8  // Data Parity Error
+#define B_PCH_LPC_DEV_STS_FB2B                    BIT7  // Fast Back to Back Capable
+#define B_PCH_LPC_DEV_STS_66MHZ_CAP               BIT5  // 66 MHz capable
+#define B_PCH_LPC_DEV_STS_CAP_LIST                BIT4  // Capabilities List
+#define B_PCH_LPC_DEV_STS_INT_STS                 BIT3  // Interrupt Status
+
+#define R_PCH_LPC_RID_CC                          0x08  // Revision ID & Class Code
+#define B_PCH_LPC_RID_CC_BCC                      0xFF000000 // Base Class Code
+#define B_PCH_LPC_RID_CC_SCC                      0x00FF0000 // Sub-Class Code
+#define B_PCH_LPC_RID_CC_PI                       0x0000FF00 // Programming Interface
+#define B_PCH_LPC_RID_CC_RID                      0x000000FF // Revision ID
+
+// Silicon Steppings
+
+#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)
+#define V_PCH_LPC_RID_E                           0x10  // D0 Stepping (17 x 17)
+#define V_PCH_LPC_RID_F                           0x11  // D0 Stepping (25 x 27)
+
+#define R_PCH_LPC_MLT                             0x0D  // Master Latency Timer
+#define B_PCH_LPC_MLT_MLC                         0xF8  // Master Latency Count
+
+#define R_PCH_LPC_HEADTYP                         0x0E  // Header Type
+#define B_PCH_LPC_HEADTYP_MFD                     BIT7  // Multi-function Device
+#define B_PCH_LPC_HEADTYP_HT                      0x7F  // Header Type
+
+#define R_PCH_LPC_SS                              0x2C  // Subsystem ID & Vendor ID
+#define B_PCH_LPC_SS_SSID                         0xFFFF0000 // Subsystem ID
+#define B_PCH_LPC_SS_SSVID                        0x0000FFFF // Subsystem Vendor ID
+
+#define R_PCH_LPC_CAP_LIST                        0x34  // Capability List
+#define B_PCH_LPC_CAP_LIST_CP                     0xFF  // Capability Pointer
+
+#define R_PCH_LPC_ACPI_BASE                       0x40 // ABASE, 16bit
+#define B_PCH_LPC_ACPI_BASE_BAR                   0x0000FF80 // Base Address, 128 Bytes
+#define B_PCH_LPC_ACPI_BASE_EN                    BIT1 // Enable Bit
+#define B_PCH_LPC_ACPI_BASE_MEMI                  BIT0 // Memory Space Indication
+
+#define R_PCH_LPC_PMC_BASE                        0x44  // PBASE, 32bit, 512 Bytes
+#define B_PCH_LPC_PMC_BASE_BAR                    0xFFFFFE00 // Base Address
+#define B_PCH_LPC_PMC_BASE_PREF                   BIT3  // Prefetchable
+#define B_PCH_LPC_PMC_BASE_ADDRNG                 BIT2  // Address Range
+#define B_PCH_LPC_PMC_BASE_EN                     BIT1  // Enable Bit
+#define B_PCH_LPC_PMC_BASE_MEMI                   BIT0  // Memory Space Indication
+
+#define R_PCH_LPC_GPIO_BASE                       0x48  // GBASE, 16bit
+#define B_PCH_LPC_GPIO_BASE_BAR                   0xFF00 // Base Address, 256 Bytes
+#define B_PCH_LPC_GPIO_BASE_EN                    BIT1  // Enable Bit
+#define B_PCH_LPC_GPIO_BASE_MEMI                  BIT0  // Memory Space Indication
+
+#define R_PCH_LPC_IO_BASE                         0x4C  // IOBASE, 32bit
+#define B_PCH_LPC_IO_BASE_BAR                     0xFFFFC000 // Base Address, 16 KiloBytes
+#define B_PCH_LPC_IO_BASE_PREF                    BIT3  // Prefetchable
+#define B_PCH_LPC_IO_BASE_ADDRNG                  BIT2  // Address Range
+#define B_PCH_LPC_IO_BASE_EN                      BIT1  // Enable Bit
+#define B_PCH_LPC_IO_BASE_MEMI                    BIT0  // Memory Space Indication
+
+#define R_PCH_LPC_ILB_BASE                        0x50  // IBASE, 32bit
+#define B_PCH_LPC_ILB_BASE_BAR                    0xFFFFFE00 // Base Address, 512 bytes
+#define B_PCH_LPC_ILB_BASE_PREF                   BIT3  // Prefetchable
+#define B_PCH_LPC_ILB_BASE_ADDRNG                 BIT2  // Address Range
+#define B_PCH_LPC_ILB_BASE_EN                     BIT1  // Enable Bit
+#define B_PCH_LPC_ILB_BASE_MEMI                   BIT0  // Memory Space Indication
+
+#define R_PCH_LPC_SPI_BASE                        0x54  // SBASE, 32bit
+#define B_PCH_LPC_SPI_BASE_BAR                    0xFFFFFE00 // Base Address, 512 bytes
+#define B_PCH_LPC_SPI_BASE_PREF                   BIT3  // Prefetchable
+#define B_PCH_LPC_SPI_BASE_ADDRNG                 BIT2  // Address Range
+#define B_PCH_LPC_SPI_BASE_EN                     BIT1  // Enable Bit
+#define B_PCH_LPC_SPI_BASE_MEMI                   BIT0  // Memory Space Indicator
+
+#define R_PCH_LPC_MPHY_BASE                       0x58 // MPBASE, 32bit
+#define B_PCH_LPC_MPHY_BASE_BAR                   0xFFF00000 // Base Address, 1 MegaByte
+#define B_PCH_LPC_MPHY_BASE_PREF                  BIT3  // Prefetchable
+#define B_PCH_LPC_MPHY_BASE_ADDRNG                BIT2  // Address Range
+#define B_PCH_LPC_MPHY_BASE_EN                    BIT1  // Enable Bit
+#define B_PCH_LPC_MPHY_BASE_MEMI                  BIT0  // Memory Space Indicator
+
+#define R_PCH_LPC_PUNIT_BASE                      0x5C  // PUBASE, 32bit
+#define B_PCH_LPC_PUNIT_BASE_BAR                  0xFFFFF800 // Base Address, 2K bytes
+#define B_PCH_LPC_PUNIT_BASE_PREF                 BIT3  // Prefetchable
+#define B_PCH_LPC_PUNIT_BASE_ADDRNG               BIT2  // Address Range
+#define B_PCH_LPC_PUNIT_BASE_EN                   BIT1  // Enable Bit
+#define B_PCH_LPC_PUNIT_BASE_MEMI                 BIT0  // Memory Space Indicator
+
+#define R_PCH_LPC_UART_CTRL                       0x80  // UART Control
+#define B_PCH_LPC_UART_CTRL_COM1_EN               BIT0  // COM1 Enable
+
+#define R_PCH_LPC_FWH_BIOS_DEC                    0xD8  // BIOS Decode Enable
+#define B_PCH_LPC_FWH_BIOS_DEC_EF8                BIT15 // F8-FF Enable
+#define B_PCH_LPC_FWH_BIOS_DEC_EF0                BIT14 // F0-F8 Enable
+#define B_PCH_LPC_FWH_BIOS_DEC_EE8                BIT13 // E8-EF Enable
+#define B_PCH_LPC_FWH_BIOS_DEC_EE0                BIT12 // E0-E8 Enable
+#define B_PCH_LPC_FWH_BIOS_DEC_ED8                BIT11 // D8-DF Enable
+#define B_PCH_LPC_FWH_BIOS_DEC_ED0                BIT10 // D0-D8 Enable
+#define B_PCH_LPC_FWH_BIOS_DEC_EC8                BIT9  // C8-CF Enable
+#define B_PCH_LPC_FWH_BIOS_DEC_EC0                BIT8  // C0-C8 Enable
+#define B_PCH_LPC_FWH_BIOS_DEC_LFE                BIT7  // Legacy F Segment Enable
+#define B_PCH_LPC_FWH_BIOS_DEC_LEE                BIT6  // Legacy E Segment Enable
+#define B_PCH_LPC_FWH_BIOS_DEC_E70                BIT3  // 70-7F Enable
+#define B_PCH_LPC_FWH_BIOS_DEC_E60                BIT2  // 60-6F Enable
+#define B_PCH_LPC_FWH_BIOS_DEC_E50                BIT1  // 50-5F Enable
+#define B_PCH_LPC_FWH_BIOS_DEC_E40                BIT0  // 40-4F Enable
+
+#define R_PCH_LPC_FDCAP                           0xE0  // Feature Detection Capability ID
+#define B_PCH_LPC_FDCAP_NEXT                      0xFF00 // Next Capability
+#define B_PCH_LPC_FDCAP_CAPID                     0x00FF // Capability ID
+
+#define R_PCH_LPC_FDLEN                           0xE2  // Feature Detection Capability Length
+#define B_PCH_LPC_FDLEN_CAPLEN                    0xFF  // Capability Length
+
+#define R_PCH_LPC_FDVER                           0xE3  // Feature Detection Capability Version
+#define B_PCH_LPC_FDVER_VSCID                     0xF0  // Vendor Specific Capability ID
+#define B_PCH_LPC_FDVER_CAPVER                    0x0F  // Capability Version
+
+#define R_PCH_LPC_FVECTIDX                        0xE4  // Feature Vector Index
+
+#define R_PCH_LPC_FVECTD                          0xE8  // Feature Vector Data
+
+#define R_PCH_LPC_RCBA                            0xF0  // RCBA, 32bit
+#define B_PCH_LPC_RCBA_BAR                        0xFFFFFC00 // Base Address, 1 KiloByte
+#define B_PCH_LPC_RCBA_EN                         BIT0  // Enable Bit
+
+#define R_PCH_LPC_ULT_OBS                         0xF4  // ULT Observability
+#define B_PCH_LPC_ULT_OBS_WNUM                    0x3FF000 // Reserved Wafer Number
+#define B_PCH_LPC_ULT_OBS_XLOC                    0xFC0 // Reserved X Loc
+#define B_PCH_LPC_ULT_OBS_YLOC                    0x3F  // Reserved Y Loc
+
+#define R_PCH_LPC_MAN_ID                          0xF8  // Manufacturer ID
+#define B_PCH_LPC_MAN_ID_DPID                     0xF000000 // Dot Portion of Process ID
+#define B_PCH_LPC_MAN_ID_MSID                     0xFF0000 // Manufacturing Stepping Identifier
+#define B_PCH_LPC_MAN_ID_MID                      0xFF00 // Manufacturing Identifier
+#define B_PCH_LPC_MAN_ID_PPID                     0xFF  // Process Portion of Process ID
+
+#define R_PCH_LPC_CGC                             0xFC  // Clock Gating Control
+#define B_PCH_LPC_CGC_SBLCG                       BIT9  // IOSF-SB Local Clock Gating Disable
+#define B_PCH_LPC_CGC_SBTCG                       BIT8  // IOSF-SB Trunk Clock Gating (Request) Disable
+#define B_PCH_LPC_CGC_PRILCG                      BIT1  // IOSF-PRI Local Clock Gating Disable
+#define B_PCH_LPC_CGC_PRITCG                      BIT0  // IOSF-PRI Trunk Clock Gating (Request) Disable
+
+//
+// iLB Memory Space Registers (IBASE)
+//
+#define R_PCH_ILB_ACPI_CNT                        0x00  // ACPI Control
+#define B_PCH_ILB_ACPI_CNT_SCI_IRQ_SEL            (BIT2 | BIT1 | BIT0) // SCI IRQ Select
+#define V_PCH_ILB_ACPI_CNT_SCI_IRQ_9              0     // IRQ9
+#define V_PCH_ILB_ACPI_CNT_SCI_IRQ_10             BIT0  // IRQ10
+#define V_PCH_ILB_ACPI_CNT_SCI_IRQ_11             BIT1  // IRQ11
+#define V_PCH_ILB_ACPI_CNT_SCI_IRQ_20             BIT2  // IRQ20 (Only if APIC enabled)
+#define V_PCH_ILB_ACPI_CNT_SCI_IRQ_21             (BIT2 | BIT0) // IRQ21 (Only if APIC enabled)
+#define V_PCH_ILB_ACPI_CNT_SCI_IRQ_22             (BIT2 | BIT1) // IRQ22 (Only if APIC enabled)
+#define V_PCH_ILB_ACPI_CNT_SCI_IRQ_23             (BIT2 | BIT1 | BIT0) // IRQ23 (Only if APIC enabled)
+
+#define R_PCH_ILB_MC                              0x04  // Miscellaneous Control
+#define B_PCH_ILB_MC_DRTC                         BIT3  // Disable RTC
+#define B_PCH_ILB_MC_D8259                        BIT2  // Disable 8259
+#define B_PCH_ILB_MC_D8254                        BIT1  // Disable 8254
+#define B_PCH_ILB_MC_AME                          BIT0  // Alternate Access Mode Enable
+
+#define R_PCH_ILB_PIRQA_ROUT                      0x08  // PIRQA Routing Control
+#define R_PCH_ILB_PIRQB_ROUT                      0x09  // PIRQB Routing Control
+#define R_PCH_ILB_PIRQC_ROUT                      0x0A  // PIRQC Routing Control
+#define R_PCH_ILB_PIRQD_ROUT                      0x0B  // PIRQD Routing Control
+#define R_PCH_ILB_PIRQE_ROUT                      0x0C  // PIRQE Routing Control
+#define R_PCH_ILB_PIRQF_ROUT                      0x0D  // PIRQF Routing Control
+#define R_PCH_ILB_PIRQG_ROUT                      0x0E  // PIRQG Routing Control
+#define R_PCH_ILB_PIRQH_ROUT                      0x0F  // PIRQH Routing Control
+//
+// Bit values are the same for R_PCH_ILB_PIRQA_ROUT to R_PCH_ILB_PIRQH_ROUT
+//
+#define B_PCH_ILB_PIRQX_ROUT_IRQEN                BIT7  // Interrupt Routing Enable
+#define B_PCH_ILB_PIRQX_ROUT                      0x0F  // IRQ Routing
+#define V_PCH_ILB_PIRQX_ROUT_IRQ_3                0x03  // Route to IRQ3
+#define V_PCH_ILB_PIRQX_ROUT_IRQ_4                0x04  // Route to IRQ4
+#define V_PCH_ILB_PIRQX_ROUT_IRQ_5                0x05  // Route to IRQ5
+#define V_PCH_ILB_PIRQX_ROUT_IRQ_6                0x06  // Route to IRQ6
+#define V_PCH_ILB_PIRQX_ROUT_IRQ_7                0x07  // Route to IRQ7
+#define V_PCH_ILB_PIRQX_ROUT_IRQ_9                0x09  // Route to IRQ9
+#define V_PCH_ILB_PIRQX_ROUT_IRQ_10               0x0A  // Route to IRQ10
+#define V_PCH_ILB_PIRQX_ROUT_IRQ_11               0x0B  // Route to IRQ11
+#define V_PCH_ILB_PIRQX_ROUT_IRQ_12               0x0C  // Route to IRQ12
+#define V_PCH_ILB_PIRQX_ROUT_IRQ_14               0x0E  // Route to IRQ14
+#define V_PCH_ILB_PIRQX_ROUT_IRQ_15               0x0F  // Route to IRQ15
+
+#define R_PCH_ILB_SERIRQ_CNT                      0x10  // Serial IRQ Control
+#define B_PCH_ILB_SERIRQ_CNT_SIRQMD               BIT7  // Mode
+
+#define R_PCH_ILB_ULKMC                           0x14  // USB Legacy Keyboard / Mouse Control
+#define B_PCH_ILB_ULKMC_TRAPBY64W                 BIT11 // SMI Caused by Port 64 Write
+#define B_PCH_ILB_ULKMC_TRAPBY64R                 BIT10 // SMI Caused by Port 64 Read
+#define B_PCH_ILB_ULKMC_TRAPBY60W                 BIT9  // SMI Caused by Port 60 Write
+#define B_PCH_ILB_ULKMC_TRAPBY60R                 BIT8  // SMI Caused by Port 60 Read
+#define B_PCH_ILB_ULKMC_64WEN                     BIT3  // SMI on Port 64 Writes Enable
+#define B_PCH_ILB_ULKMC_64REN                     BIT2  // SMI on Port 64 Reads Enable
+#define B_PCH_ILB_ULKMC_60WEN                     BIT1  // SMI on Port 60 Writes Enable
+#define B_PCH_ILB_ULKMC_60REN                     BIT0  // SMI on Port 60 Reads Enable
+
+#define R_PCH_ILB_FWH_BIOS_SEL                    0x18  // FWH ID Select
+#define B_PCH_ILB_FWH_BIOS_SEL_F8                 0xF0000000 // F8-FF ID Select
+#define B_PCH_ILB_FWH_BIOS_SEL_F0                 0x0F000000 // F0-F7 ID Select
+#define B_PCH_ILB_FWH_BIOS_SEL_E8                 0x00F00000 // E8-EF ID Select
+#define B_PCH_ILB_FWH_BIOS_SEL_E0                 0x000F0000 // E0-E7 ID Select
+#define B_PCH_ILB_FWH_BIOS_SEL_D8                 0x0000F000 // D8-DF ID Select
+#define B_PCH_ILB_FWH_BIOS_SEL_D0                 0x00000F00 // D0-D7 ID Select
+#define B_PCH_ILB_FWH_BIOS_SEL_C8                 0x000000F0 // C8-CF ID Select
+#define B_PCH_ILB_FWH_BIOS_SEL_C0                 0x0000000F // C0-C7 ID Select
+
+#define R_PCH_ILB_BIOS_CNTL                       0x1C  // BIOS Control
+#define S_PCH_ILB_BIOS_CNTL                       4
+#define B_PCH_ILB_BIOS_CNTL_PFE                   BIT8  // Prefetch Enable
+#define B_PCH_ILB_BIOS_CNTL_LE                    BIT1  // Lock Enable
+#define N_PCH_ILB_BIOS_CNTL_LE                    1
+#define B_PCH_ILB_BIOS_CNTL_WP                    BIT0  // Write Protect
+
+#define R_PCH_ILB_D0IR                            0x20  // Device 0 Interrupt Route
+#define R_PCH_ILB_D1IR                            0x22  // Device 1 Interrupt Route
+#define R_PCH_ILB_D2IR                            0x24  // Device 2 Interrupt Route
+#define R_PCH_ILB_D3IR                            0x26  // Device 3 Interrupt Route
+#define R_PCH_ILB_D4IR                            0x28  // Device 4 Interrupt Route
+#define R_PCH_ILB_D5IR                            0x2A  // Device 5 Interrupt Route
+#define R_PCH_ILB_D6IR                            0x2C  // Device 6 Interrupt Route
+#define R_PCH_ILB_D7IR                            0x2E  // Device 7 Interrupt Route
+#define R_PCH_ILB_D8IR                            0x30  // Device 8 Interrupt Route
+#define R_PCH_ILB_D9IR                            0x32  // Device 9 Interrupt Route
+#define R_PCH_ILB_D10IR                           0x34  // Device 10 Interrupt Route
+#define R_PCH_ILB_D11IR                           0x36  // Device 11 Interrupt Route
+#define R_PCH_ILB_D12IR                           0x38  // Device 12 Interrupt Route
+#define R_PCH_ILB_D13IR                           0x3A  // Device 13 Interrupt Route
+#define R_PCH_ILB_D14IR                           0x3C  // Device 14 Interrupt Route
+#define R_PCH_ILB_D15IR                           0x3E  // Device 15 Interrupt Route
+#define R_PCH_ILB_D16IR                           0x40  // Device 16 Interrupt Route
+#define R_PCH_ILB_D17IR                           0x42  // Device 17 Interrupt Route
+#define R_PCH_ILB_D18IR                           0x44  // Device 18 Interrupt Route
+#define R_PCH_ILB_D19IR                           0x46  // Device 19 Interrupt Route
+#define R_PCH_ILB_D20IR                           0x48  // Device 20 Interrupt Route
+#define R_PCH_ILB_D21IR                           0x4A  // Device 21 Interrupt Route
+#define R_PCH_ILB_D22IR                           0x4C  // Device 22 Interrupt Route
+#define R_PCH_ILB_D23IR                           0x4E  // Device 23 Interrupt Route
+#define R_PCH_ILB_D24IR                           0x50  // Device 24 Interrupt Route
+#define R_PCH_ILB_D25IR                           0x52  // Device 25 Interrupt Route
+#define R_PCH_ILB_D26IR                           0x54  // Device 26 Interrupt Route
+#define R_PCH_ILB_D27IR                           0x56  // Device 27 Interrupt Route
+#define R_PCH_ILB_D28IR                           0x58  // Device 28 Interrupt Route
+#define R_PCH_ILB_D29IR                           0x5A  // Device 29 Interrupt Route
+#define R_PCH_ILB_D30IR                           0x5C  // Device 30 Interrupt Route
+#define R_PCH_ILB_D31IR                           0x5E  // Device 31 Interrupt Route
+
+#define B_PCH_ILB_DXXIR_IDR_MASK                  (BIT14 | BIT13 | BIT12) // INTD Mask
+#define V_PCH_ILB_DXXIR_IDR_PIRQA                 0                       // INTD Mapping to IRQ A
+#define V_PCH_ILB_DXXIR_IDR_PIRQB                 BIT12                   // INTD Mapping to IRQ B
+#define V_PCH_ILB_DXXIR_IDR_PIRQC                 BIT13                   // INTD Mapping to IRQ C
+#define V_PCH_ILB_DXXIR_IDR_PIRQD                 (BIT13 | BIT12)         // INTD Mapping to IRQ D
+#define V_PCH_ILB_DXXIR_IDR_PIRQE                 BIT14                   // INTD Mapping to IRQ E
+#define V_PCH_ILB_DXXIR_IDR_PIRQF                 (BIT14 | BIT12)         // INTD Mapping to IRQ F
+#define V_PCH_ILB_DXXIR_IDR_PIRQG                 (BIT14 | BIT13)         // INTD Mapping to IRQ G
+#define V_PCH_ILB_DXXIR_IDR_PIRQH                 (BIT14 | BIT13 | BIT12) // INTD Mapping to IRQ H
+
+#define B_PCH_ILB_DXXIR_ICR_MASK                  (BIT10 | BIT9 | BIT8) // INTC Mask
+#define V_PCH_ILB_DXXIR_ICR_PIRQA                 0                     // INTC Mapping to IRQ A
+#define V_PCH_ILB_DXXIR_ICR_PIRQB                 BIT8                  // INTC Mapping to IRQ B
+#define V_PCH_ILB_DXXIR_ICR_PIRQC                 BIT9                  // INTC Mapping to IRQ C
+#define V_PCH_ILB_DXXIR_ICR_PIRQD                 (BIT9 | BIT8)         // INTC Mapping to IRQ D
+#define V_PCH_ILB_DXXIR_ICR_PIRQE                 BIT10                 // INTC Mapping to IRQ E
+#define V_PCH_ILB_DXXIR_ICR_PIRQF                 (BIT10 | BIT8)        // INTC Mapping to IRQ F
+#define V_PCH_ILB_DXXIR_ICR_PIRQG                 (BIT10 | BIT9)        // INTC Mapping to IRQ G
+#define V_PCH_ILB_DXXIR_ICR_PIRQH                 (BIT10 | BIT9 | BIT8) // INTC Mapping to IRQ H
+
+#define B_PCH_ILB_DXXIR_IBR_MASK                  (BIT6 | BIT5 | BIT4) // INTB Mask
+#define V_PCH_ILB_DXXIR_IBR_PIRQA                 0                    // INTB Mapping to IRQ A
+#define V_PCH_ILB_DXXIR_IBR_PIRQB                 BIT4                 // INTB Mapping to IRQ B
+#define V_PCH_ILB_DXXIR_IBR_PIRQC                 BIT5                 // INTB Mapping to IRQ C
+#define V_PCH_ILB_DXXIR_IBR_PIRQD                 (BIT5 | BIT4)        // INTB Mapping to IRQ D
+#define V_PCH_ILB_DXXIR_IBR_PIRQE                 BIT6                 // INTB Mapping to IRQ E
+#define V_PCH_ILB_DXXIR_IBR_PIRQF                 (BIT6 | BIT4)        // INTB Mapping to IRQ F
+#define V_PCH_ILB_DXXIR_IBR_PIRQG                 (BIT6 | BIT5)        // INTB Mapping to IRQ G
+#define V_PCH_ILB_DXXIR_IBR_PIRQH                 (BIT6 | BIT5 | BIT4) // INTB Mapping to IRQ H
+
+#define B_PCH_ILB_DXXIR_IAR_MASK                  (BIT2 | BIT1 | BIT0) // INTA Mask
+#define V_PCH_ILB_DXXIR_IAR_PIRQA                 0                    // INTA Mapping to IRQ A
+#define V_PCH_ILB_DXXIR_IAR_PIRQB                 BIT0                 // INTA Mapping to IRQ B
+#define V_PCH_ILB_DXXIR_IAR_PIRQC                 BIT1                 // INTA Mapping to IRQ C
+#define V_PCH_ILB_DXXIR_IAR_PIRQD                 (BIT1 | BIT0)        // INTA Mapping to IRQ D
+#define V_PCH_ILB_DXXIR_IAR_PIRQE                 BIT2                 // INTA Mapping to IRQ E
+#define V_PCH_ILB_DXXIR_IAR_PIRQF                 (BIT2 | BIT0)        // INTA Mapping to IRQ F
+#define V_PCH_ILB_DXXIR_IAR_PIRQG                 (BIT2 | BIT1)        // INTA Mapping to IRQ G
+#define V_PCH_ILB_DXXIR_IAR_PIRQH                 (BIT2 | BIT1 | BIT0) // INTA Mapping to IRQ H
+
+#define R_PCH_ILB_OIC                             0x60  // Other Interrupt Controller
+#define B_PCH_ILB_OIC_SIRQEN                      BIT12 // Serial IRQ Enable
+#define B_PCH_ILB_OIC_AEN                         BIT8  // APIC Enable
+
+#define R_PCH_ILB_RTC_CONF                        0x64  // RTC Control
+#define B_PCH_ILB_RTC_CONF_UCMOS_LOCK             BIT1  // Upper 128 Byte Lock
+#define B_PCH_ILB_RTC_CONF_LCMOS_LOCK             BIT0  // Lower 128 Byte Lock
+
+#define R_PCH_ILB_RTM                             0x68  // RTC Test Mode
+#define B_PCH_ILB_RTM_RTM1                        (BIT2 | BIT1 | BIT0)
+
+#define R_PCH_ILB_BCS                             0x6C  // BIOS Control Status
+#define B_PCH_ILB_BCS_SMIWPEN                     BIT1  // SMI WPD Enable
+#define B_PCH_ILB_BCS_SMIWPST                     BIT0  // SMI WPD Status
+
+#define R_PCH_ILB_LE                              0x70  // LE
+#define B_PCH_ILB_LE_IRQ12C                       BIT1  // IRQ12 Cause
+#define B_PCH_ILB_LE_IRQ1C                        BIT0  // IRQ1 Cause
+
+#define R_PCH_ILB_RTCC                            0x74  // RTC HIP Configuration
+#define B_PCH_ILB_RTCC_RTCB4                      BIT6  // RTC Bias Resistor 4, Adds 480 Kohm
+#define B_PCH_ILB_RTCC_RTCB3                      BIT5  // RTC Bias Resistor 3, Adds 240 Kohm
+#define B_PCH_ILB_RTCC_RTCB2                      BIT4  // RTC Bias Resistor 2, Adds 120 Kohm
+#define B_PCH_ILB_RTCC_RTCB1                      BIT3  // RTC Bias Resistor 1, Adds 60 Kohm
+#define B_PCH_ILB_RTCC_RTCB0                      BIT2  // RTC Bias Resistor 0, Adds 30 Kohm
+#define B_PCH_ILB_RTCC_DSWEN                      BIT1  // Deep Sleep Well Enable
+#define B_PCH_ILB_RTCC_FEN                        BIT0  // Enable the Fast Oscillator Bypass Mode
+
+#define R_PCH_ILB_DEF0                            0x78  // Defeature Register 0
+#define B_PCH_ILB_DEF0_SHRTSYNC                   BIT22 // Short Sync Abort Defeature
+#define B_PCH_ILB_DEF0_SDD                        BIT21 // Sub Decode Disable
+
+#define R_PCH_ILB_DEF1                            0x7C  // Defeature Register 1
+#define B_PCH_ILB_DEF1_TPMPF                      BIT10 // usb2leg_chknbit_TPM_PF
+#define B_PCH_ILB_DEF1_HPETDEF                    BIT8  // usb2leg_chknbit_hpet
+#define B_PCH_ILB_DEF1_ECWS                       BIT6  // 8254 Early CW Select
+#define B_PCH_ILB_DEF1_FOF                        BIT5  // 8254 Freeze on first on 1st rd wr11
+#define B_PCH_ILB_DEF1_FOAR                       BIT4  // 8254 Freeze_On_AnyRead
+#define B_PCH_ILB_DEF1_LMOO                       BIT3  // 8259 L2L0_Match_On_OCW2
+#define B_PCH_ILB_DEF1_DFP                        BIT2  // 8259 Disable_Freeze_Priority
+#define B_PCH_ILB_DEF1_EETI                       BIT1  // 8259 Extend_EdgeTrig_IRQ
+#define B_PCH_ILB_DEF1_DSAEOI                     BIT0  // 8259 Disable_Slave_AEOI
+
+#define R_PCH_ILB_GNMI                            0x80  // NMI Register
+#define S_PCH_ILB_GNMI                            4
+#define B_PCH_ILB_GNMI_NMI2SMIEN                  BIT6  // NMI to SMI Enable
+#define N_PCH_ILB_GNMI_NMI2SMIEN                  6
+#define B_PCH_ILB_GNMI_NMI2SMIST                  BIT5  // NMI to SMI Status
+#define N_PCH_ILB_GNMI_NMI2SMIST                  5
+#define B_PCH_ILB_GNMI_NMIN                       BIT4  // NMI NOW
+#define B_PCH_ILB_GNMI_NMINS                      BIT3  // NMI NOW Status
+#define B_PCH_ILB_GNMI_GNMIED                     BIT2  // GPIO NMI Edge Detection
+#define B_PCH_ILB_GNMI_GNMIE                      BIT1  // GPIO NMI Enable
+#define B_PCH_ILB_GNMI_GNMIS                      BIT0  // GPIO NMI Status
+
+#define R_PCH_ILB_LPCC                            0x84  // LPC Control
+#define B_PCH_ILB_LPCC_LPCCLK_SLC                 BIT8  // iLPCCLK Mux Select
+#define B_PCH_ILB_LPCC_LPCCLK_FORCE_OFF           BIT3
+#define B_PCH_ILB_LPCC_CLKRUN_EN                  BIT2  // LPC CLKRUN Protocol Enable
+#define B_PCH_ILB_LPCC_LPCCLK1EN                  BIT1  // Clock 1 Enable
+#define B_PCH_ILB_LPCC_LPCCLK0EN                  BIT0  // Clock 0 Enable
+
+#define R_PCH_ILB_IRQE                            0x88  // IRQ Enable Control
+#define B_PCH_ILB_IRQE_IRQ4TO7EN                  (BIT7 | BIT6 | BIT5 | BIT4) // IRQ4 - IRQ7 Enable
+#define B_PCH_ILB_IRQE_UARTIRQEN_IRQ3             BIT3  // UART IRQ3 Enable
+
+//
+// ACPI and Legacy I/O Registers (ABASE)
+//
+#define R_PCH_ACPI_PM1_STS                        0x00  // Power Management 1 Status
+#define S_PCH_ACPI_PM1_STS                        2
+#define B_PCH_ACPI_PM1_STS_WAK                    BIT15 // Wake Status
+#define B_PCH_ACPI_PM1_STS_WAK_PCIE0              BIT14 // PCI Express 0 Wake Status
+#define B_PCH_ACPI_PM1_STS_USB_CLKLESS            BIT13 // USB Clockless Status
+#define B_PCH_ACPI_PM1_STS_PRBTNOR                BIT11 // Power Button Override Status
+#define B_PCH_ACPI_PM1_STS_RTC                    BIT10 // RTC Status
+#define B_PCH_ACPI_PM1_STS_PWRBTN                 BIT8  // Power Button Status
+#define B_PCH_ACPI_PM1_STS_GBL                    BIT5  // Global Status
+#define B_PCH_ACPI_PM1_STS_WAK_PCIE3              BIT4  // PCI Express 3 Wake Status
+#define B_PCH_ACPI_PM1_STS_WAK_PCIE2              BIT3  // PCI Express 2 Wake Status
+#define B_PCH_ACPI_PM1_STS_WAK_PCIE1              BIT2  // PCI Express 1 Wake Status
+#define B_PCH_ACPI_PM1_STS_TMROF                  BIT0  // Timer Overflow Status
+#define N_PCH_ACPI_PM1_STS_WAK                    15
+#define N_PCH_ACPI_PM1_STS_PRBTNOR                11
+#define N_PCH_ACPI_PM1_STS_RTC                    10
+#define N_PCH_ACPI_PM1_STS_PWRBTN                 8
+#define N_PCH_ACPI_PM1_STS_GBL                    5
+#define N_PCH_ACPI_PM1_STS_TMROF                  0
+
+#define R_PCH_ACPI_PM1_EN                         0x02  // Power Management 1 Enables
+#define S_PCH_ACPI_PM1_EN                         2
+#define B_PCH_ACPI_PM1_WAK_DIS_PCIE0              BIT14 // PCI Express 0 Disable
+#define B_PCH_ACPI_PM1_EN_USB_CLKLESS             BIT13 // USB Clockless Enable Bit
+#define B_PCH_ACPI_PM1_EN_RTC                     BIT10 // RTC Alarm Enable Bit
+#define B_PCH_ACPI_PM1_EN_PWRBTN                  BIT8  // Power Button Enable Bit
+#define B_PCH_ACPI_PM1_EN_GBL                     BIT5  // Global Enable Bit
+#define B_PCH_ACPI_PM1_WAK_DIS_PCIE3              BIT4  // PCI Express 3 Disable
+#define B_PCH_ACPI_PM1_WAK_DIS_PCIE2              BIT3  // PCI Express 2 Disable
+#define B_PCH_ACPI_PM1_WAK_DIS_PCIE1              BIT2  // PCI Express 1 Disable
+#define B_PCH_ACPI_PM1_EN_TMROF                   BIT0  // Timer Overflow Interrupt Enable Bit
+#define N_PCH_ACPI_PM1_EN_RTC                     10
+#define N_PCH_ACPI_PM1_EN_PWRBTN                  8
+#define N_PCH_ACPI_PM1_EN_GBL                     5
+#define N_PCH_ACPI_PM1_EN_TMROF                   0
+
+#define R_PCH_ACPI_PM1_CNT                        0x04  // Power Management 1 Control
+#define S_PCH_ACPI_PM1_CNT                        4
+#define B_PCH_ACPI_PM1_CNT_SLP_EN                 BIT13 // Sleep enable
+#define B_PCH_ACPI_PM1_CNT_SLP_TYP                (BIT12 | BIT11 | BIT10) // Sleep Type
+#define V_PCH_ACPI_PM1_CNT_S0                     0x00000000 // ON (S0)
+#define V_PCH_ACPI_PM1_CNT_S1                     0x00000400 // Puts CPU in S1 state (S1)
+#define V_PCH_ACPI_PM1_CNT_S3                     0x00001400 // Suspend-to-RAM (S3)
+#define V_PCH_ACPI_PM1_CNT_S4                     0x00001800 // Suspend-to-Disk (S4)
+#define V_PCH_ACPI_PM1_CNT_S5                     0x00001C00 // Soft Off (S5)
+#define B_PCH_ACPI_PM1_CNT_GBL_RLS                BIT2
+#define B_PCH_ACPI_PM1_CNT_BM_RLD                 BIT1  // Treated as Scratchpad Bit
+#define B_PCH_ACPI_PM1_CNT_SCI_EN                 BIT0  // SCI Enable
+
+#define R_PCH_ACPI_PM1_TMR                        0x08  // Power Management 1 Timer
+#define B_PCH_ACPI_PM1_TMR_VAL                    0xFFFFFF // The timer value mask
+#define V_PCH_ACPI_PM1_TMR_MAX_VAL                0x1000000 // The timer is 24 bit overflow
+#define V_PCH_ACPI_PM1_TMR_FREQUENCY              3579545 // Timer Frequency
+#define V_PCH_ACPI_PM1_TMR_NUM_BITS               24    // Programmed to 24 not 32
+#define V_PCH_ACPI_PM1_TMR_MAX_BITS               32
+
+#define R_PCH_ACPI_GPE0a_STS                      0x20  // General Purpose Event 0a Status
+#define S_PCH_ACPI_GPE0a_STS                      4
+#define B_PCH_ACPI_GPE0a_STS_CORE_GPIO            0xFF000000 // CORE GPIO Status
+#define B_PCH_ACPI_GPE0a_STS_SUS_GPIO             0x00FF0000 // SUS GPIO Status
+#define B_PCH_ACPI_GPE0a_STS_PME_B0               BIT13 // Power Management Event Bus 0 Status
+#define B_PCH_ACPI_GPE0a_STS_BATLOW               BIT10 // Battery Low Status
+#define B_PCH_ACPI_GPE0a_STS_PCI_EXP              BIT9  // PCI Express Status
+#define B_PCH_ACPI_GPE0a_STS_GUNIT_SCI            BIT5  // GUNIT SCI Status
+#define B_PCH_ACPI_GPE0a_STS_PUNIT_SCI            BIT4  // PUNIT SCI Status
+#define B_PCH_ACPI_GPE0a_STS_SWGPE                BIT2  // Software GPE Status
+#define B_PCH_ACPI_GPE0a_STS_HOT_PLUG             BIT1  // Hot Plug Status
+#define N_PCH_ACPI_GPE0a_STS_PME_B0               13
+#define N_PCH_ACPI_GPE0a_STS_BATLOW               10
+#define N_PCH_ACPI_GPE0a_STS_PCI_EXP              9
+#define N_PCH_ACPI_GPE0a_STS_GUNIT_SCI            5
+#define N_PCH_ACPI_GPE0a_STS_PUNIT_SCI            4
+#define N_PCH_ACPI_GPE0a_STS_SWGPE                2
+#define N_PCH_ACPI_GPE0a_STS_HOT_PLUG             1
+
+#define R_PCH_ACPI_GPE0a_EN                       0x28  // General Purpose Event 0a Enables
+#define S_PCH_ACPI_GPE0a_EN                       4
+#define B_PCH_ACPI_GPE0a_EN_CORE_GPIO             0xFF000000 // CORE GPIO Enable
+#define B_PCH_ACPI_GPE0a_EN_SUS_GPIO              0x00FF0000 // SUS GPIO Enable
+#define B_PCH_ACPI_GPE0a_EN_PME_B0                BIT13 // Power Management Event Bus 0 Enable
+#define B_PCH_ACPI_GPE0a_EN_BATLOW                BIT10 // Battery Low Enable
+#define B_PCH_ACPI_GPE0a_EN_PCI_EXP               BIT9  // PCI Express Enable
+#define B_PCH_ACPI_GPE0a_EN_SWGPE                 BIT2  // Software GPE Enable
+#define B_PCH_ACPI_GPE0a_EN_HOT_PLUG              BIT1  // Hot Plug Enable
+#define N_PCH_ACPI_GPE0a_EN_PME_B0                13
+#define N_PCH_ACPI_GPE0a_EN_BATLOW                10
+#define N_PCH_ACPI_GPE0a_EN_PCI_EXP               9
+#define N_PCH_ACPI_GPE0a_EN_SWGPE                 2
+#define N_PCH_ACPI_GPE0a_EN_HOT_PLUG              1
+
+#define R_PCH_SMI_EN                              0x30  // SMI Control and Enable
+#define S_PCH_SMI_EN                              4
+#define B_PCH_SMI_EN_LEGACY_USB3                  BIT31 // Legacy USB 3 Enable
+#define B_PCH_SMI_EN_INTEL_USB2                   BIT18 // Intel USB 2 Enable
+#define B_PCH_SMI_EN_LEGACY_USB2                  BIT17 // Legacy USB 2 Enable
+#define B_PCH_SMI_EN_PERIODIC                     BIT14 // Periodic Enable
+#define B_PCH_SMI_EN_TCO                          BIT13 // TCO Enable
+#define B_PCH_SMI_EN_BIOS_RLS                     BIT7  // BIOS RLS
+#define B_PCH_SMI_EN_SWSMI_TMR                    BIT6  // Software SMI Timer Enable
+#define B_PCH_SMI_EN_APMC                         BIT5  // APMC Enable
+#define B_PCH_SMI_EN_ON_SLP_EN                    BIT4  // SMI On Sleep Enable
+#define B_PCH_SMI_EN_BIOS                         BIT2  // BIOS Enable
+#define B_PCH_SMI_EN_EOS                          BIT1  // End of SMI
+#define B_PCH_SMI_EN_GBL_SMI                      BIT0  // Global SMI Enable
+#define N_PCH_SMI_EN_LEGACY_USB3                  31
+#define N_PCH_SMI_EN_GPIO_UNLOCK                  27
+#define N_PCH_SMI_EN_INTEL_USB2                   18
+#define N_PCH_SMI_EN_LEGACY_USB2                  17
+#define N_PCH_SMI_EN_PERIODIC                     14
+#define N_PCH_SMI_EN_TCO                          13
+#define N_PCH_SMI_EN_BIOS_RLS                     7
+#define N_PCH_SMI_EN_SWSMI_TMR                    6
+#define N_PCH_SMI_EN_APMC                         5
+#define N_PCH_SMI_EN_ON_SLP_EN                    4
+#define N_PCH_SMI_EN_BIOS                         2
+#define N_PCH_SMI_EN_EOS                          1
+#define N_PCH_SMI_EN_GBL_SMI                      0
+
+#define R_PCH_SMI_STS                             0x34  // SMI Status Register
+#define S_PCH_SMI_STS                             4
+#define B_PCH_SMI_STS_LEGACY_USB3                 BIT31 // Legacy USB 3 Status
+#define B_PCH_SMI_STS_GUNIT_SMI                   BIT29 // GUNIT SMI Status
+#define B_PCH_SMI_STS_PUNIT_SMI                   BIT28 // PUNIT SMI Status
+#define B_PCH_SMI_STS_SPI                         BIT26 // SPI SMI Status
+#define B_PCH_SMI_STS_PCI_EXP                     BIT20 // PCI Express SMI Status
+#define B_PCH_SMI_STS_INTEL_USB2                  BIT18 // Intel USB 2 Status
+#define B_PCH_SMI_STS_LEGACY_USB2                 BIT17 // Legacy USB 2 Status
+#define N_PCH_SMI_STS_TCO                         13
+#define B_PCH_SMI_STS_SMBUS                       BIT16 // SMBUS SMI Status
+#define B_PCH_SMI_STS_ILB                         BIT15 // ILB SMI Status
+#define B_PCH_SMI_STS_PERIODIC                    BIT14 // Periodic Status
+#define B_PCH_SMI_STS_TCO                         BIT13 // TCO Status
+#define B_PCH_SMI_STS_GPE0                        BIT9  // GPE0 Status
+#define B_PCH_SMI_STS_PM1_STS_REG                 BIT8  // PM1 Status Register
+#define B_PCH_SMI_STS_SWSMI_TMR                   BIT6  // Software SMI Timer Status
+#define B_PCH_SMI_STS_APM                         BIT5  // APM Status
+#define B_PCH_SMI_STS_ON_SLP_EN                   BIT4  // SMI On Sleep Enable Status
+#define B_PCH_SMI_STS_BIOS                        BIT2  // BIOS Status
+#define N_PCH_SMI_STS_LEGACY_USB3                 31
+#define N_PCH_SMI_STS_SPI                         26
+#define N_PCH_SMI_STS_PCI_EXP                     20
+#define N_PCH_SMI_STS_INTEL_USB2                  18
+#define N_PCH_SMI_STS_LEGACY_USB2                 17
+#define N_PCH_SMI_STS_SMBUS                       16
+#define N_PCH_SMI_STS_ILB                         15
+#define N_PCH_SMI_STS_PERIODIC                    14
+#define N_PCH_SMI_STS_TCO                         13
+#define N_PCH_SMI_STS_GPE0                        9
+#define N_PCH_SMI_STS_PM1_STS_REG                 8
+#define N_PCH_SMI_STS_SWSMI_TMR                   6
+#define N_PCH_SMI_STS_APM                         5
+#define N_PCH_SMI_STS_ON_SLP_EN                   4
+#define N_PCH_SMI_STS_BIOS                        2
+
+#define R_PCH_ALT_GP_SMI_EN                       0x38  // Alternate GPI SMI Enable
+#define S_PCH_ALT_GP_SMI_EN                       2
+#define B_PCH_ALT_GP_SMI_EN_CORE_GPIO             0xFF00 // SUS GPIO SMI Enable
+#define B_PCH_ALT_GP_SMI_EN_SUS_GPIO              0x00FF // CORE GPIO SMI Enable
+
+#define R_PCH_ALT_GP_SMI_STS                      0x3A  // Alternate GPI SMI Status
+#define S_PCH_ALT_GP_SMI_STS                      2
+#define B_PCH_ALT_GP_SMI_STS_CORE_GPIO            0xFF00 // SUS GPIO SMI Status
+#define B_PCH_ALT_GP_SMI_STS_SUS_GPIO             0x00FF // CORE GPIO SMI Status
+
+#define R_PCH_UPRWC                               0x3C  // USB Per-Port Registers Write Control
+#define S_PCH_UPRWC                               2
+#define B_PCH_UPRWC_WR_EN_SMI_STS                 BIT8 // Write Enable Status
+#define B_PCH_UPRWC_WR_EN                         BIT1 // USB Per-Port Registers Write Enable
+#define B_PCH_UPRWC_WR_EN_SMI_EN                  BIT0 // Write Enable SMI Enable
+
+#define R_PCH_ACPI_GPE_CNTL                       0x40  // General Purpose Event Control
+#define B_PCH_ACPI_GPE_CNTL_SWGPE_CTRL            BIT17 // Software GPE Control
+#define B_PCH_ACPI_GPE_CNTL_PCIE3_SCI_EN          BIT3
+#define B_PCH_ACPI_GPE_CNTL_PCIE2_SCI_EN          BIT2
+#define B_PCH_ACPI_GPE_CNTL_PCIE1_SCI_EN          BIT1
+#define B_PCH_ACPI_GPE_CNTL_PCIE0_SCI_EN          BIT0
+
+#define R_PCH_ACPI_PM2_CNT                        0x50  // PM2a Control Block
+#define B_PCH_ACPI_PM2_CNT_ARB_DIS                BIT0  // Scratchpad Bit
+
+#define R_PCH_TCO_RLD                             0x60  // TCO Reload
+#define B_PCH_TCO_RLD_VAL                         0x3FF // TCO Timer Count Value
+
+#define R_PCH_TCO_STS                             0x64  // TCO Timer Status
+#define S_PCH_TCO_STS                             4
+#define B_PCH_TCO_STS_SECOND_TO                   BIT17 // Second Timeout Status
+#define B_PCH_TCO_STS_TIMEOUT                     BIT3  // Timeout
+#define N_PCH_TCO_STS_TIMEOUT                     3
+
+#define R_PCH_TCO_CNT                             0x68  // TCO Control
+#define S_PCH_TCO_CNT                             2
+#define B_PCH_TCO_CNT_OS_POLICY                   (BIT21 | BIT20) // OS Policy
+#define B_PCH_TCO_CNT_LOCK                        BIT12 // TCO Enable Lock
+#define B_PCH_TCO_CNT_TMR_HLT                     BIT11 // TCO Timer Halt
+
+#define R_PCH_TCO_TMR                             0x70  // TCO Timer
+#define B_PCH_TCO_TMR_TCO_TRLD                    0x3FF0000
+
+//
+// PMC Memory Space Registers (PBASE)
+//
+#define R_PCH_PMC_PRSTS                           0x00  // Power and Reset Status
+#define B_PCH_PMC_PRSTS_PRODID                    0xFF000000 // Power Management Controller Product ID
+#define B_PCH_PMC_PRSTS_REVID                     0x00FF0000 // Power Management Controller Revision ID
+#define B_PCH_PMC_PRSTS_PM_WD_TMR                 BIT15 // PMC Watchdog Timer Status
+#define B_PCH_PMC_PRSTS_CODE_COPIED_STS           BIT11 // Patch Copied Over Status
+#define B_PCH_PMC_PRSTS_CODE_LOAD_TO              BIT9  // Patch Load Timeout Status
+#define B_PCH_PMC_PRSTS_OP_STS                    BIT8  // PMC Operational Status
+#define B_PCH_PMC_PRSTS_SEC_GBLRST_STS            BIT7  // SEC Global Reset Status
+#define B_PCH_PMC_PRSTS_SEC_WD_TMR_STS            BIT6  // SEC Watchdog Timer Status
+#define B_PCH_PMC_PRSTS_WOL_OVR_WK_STS            BIT5  // Wake On LAN Override Wake Status
+#define B_PCH_PMC_PRSTS_HOST_WAKE_STS             BIT4  // PMC Host Wake Status
+
+#define R_PCH_PMC_PM_CFG                          0x08  // Power Management Configuration
+#define B_PCH_PMC_PM_CFG_SPS                      BIT5  // Shutdown Policy Select
+#define B_PCH_PMC_PM_CFG_NO_REBOOT                BIT4  // No Reboot Strap
+#define B_PCH_PMC_PM_CFG_SX_ENT_TO_EN             BIT3  // S1 / 3 / 4 / 5 Entry Timeout Enable
+#define B_PCH_PMC_PM_CFG_TIMING_T581              (BIT1 | BIT0) // Timing t581
+
+#define R_PCH_PMC_PM_STS                          0x0C  // Power Management Status
+#define B_PCH_PMC_PM_STS_PMC_MSG_FULL             BIT24 // PMC Message Full Status
+#define B_PCH_PMC_PM_STS_PMC_MSG_4_FULL           BIT23 // PMC 4 Message Full Status
+#define B_PCH_PMC_PM_STS_PMC_MSG_3_FULL           BIT22 // PMC 3 Message Full Status
+#define B_PCH_PMC_PM_STS_PMC_MSG_2_FULL           BIT21 // PMC 2 Message Full Status
+#define B_PCH_PMC_PM_STS_PMC_MSG_1_FULL           BIT20 // PMC 1 Message Full Status
+#define B_PCH_PMC_PM_STS_CODE_REQ                 BIT8  // Patch Request Status
+#define B_PCH_PMC_PM_STS_HPR_ENT_TO               BIT2  // Host partition Reset Entry Timeout Status
+#define B_PCH_PMC_PM_STS_SX_ENT_TO                BIT1  // S3 / 4 / 5 Entry Timeout Status
+
+#define R_PCH_PMC_MTPMC                           0x10  // Message to PMC
+
+#define R_PCH_PMC_GEN_PMCON_1                     0x20  // General PM Configuration 1
+#define B_PCH_PMC_GEN_PMCON_UART_EN               BIT24 // UART Debug Port Enable
+#define B_PCH_PMC_GEN_PMCON_DRAM_INIT             BIT23 // DRAM Initialization Scratchpad Bit
+#define B_PCH_PMC_GEN_PMCON_MEM_SR                BIT21 // Memory Placed in Self-Refresh
+#define B_PCH_PMC_GEN_PMCON_SRS                   BIT20 // System Reset Status
+#define B_PCH_PMC_GEN_PMCON_CTS                   BIT19 // CPU Thermal Trip Status
+#define B_PCH_PMC_GEN_PMCON_MIN_SLP_S4            BIT18 // Minimum SLP_S4# Assertion Width Violation Status
+#define B_PCH_PMC_GEN_PMCON_PWROK_FLR             BIT16 // PWROK Failure
+#define B_PCH_PMC_GEN_PMCON_PME_B0_S5_DIS         BIT15 // PME B0 S5 Disable
+#define B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR           BIT14 // SUS Well Power Failure
+#define B_PCH_PMC_GEN_PMCON_WOL_ENABLE_OVERRIDE   BIT13 // WOL Enable Override
+#define B_PCH_PMC_GEN_PMCON_DISABLE_SX_STRETCH    BIT12 // Disable SLP_X Scretching After SUS Well Power Up
+#define B_PCH_PMC_GEN_PMCON_SLP_S3_MAW            (BIT11 | BIT10) // SLP_S3# Minimum Assertion Width
+#define V_PCH_PMC_GEN_PMCON_SLP_S3_MAW_60US       0x000 // 60 micro seconds
+#define V_PCH_PMC_GEN_PMCON_SLP_S3_MAW_1MS        0x400 // 1 milli second
+#define V_PCH_PMC_GEN_PMCON_SLP_S3_MAW_50MS       0x800 // 50 milli seconds
+#define V_PCH_PMC_GEN_PMCON_SLP_S3_MAW_2S         0xC00 // 2 seconds
+#define B_PCH_PMC_GEN_PMCON_GEN_RST_STS           BIT9  // General Reset Status
+#define B_PCH_PMC_GEN_PMCON_RTC_RESERVED          BIT8  // RTC Reserved
+#define B_PCH_PMC_GEN_PMCON_SWSMI_RTSL            (BIT7 | BIT6)  // SWSMI Rate Select
+#define V_PCH_PMC_GEN_PMCON_SWSMI_RTSL_64MS       0xC0  // 64ms +/- 4ms
+#define V_PCH_PMC_GEN_PMCON_SWSMI_RTSL_32MS       0x80  // 32ms +/- 4ms
+#define V_PCH_PMC_GEN_PMCON_SWSMI_RTSL_16MS       0x40  // 16ms +/- 4ms
+#define V_PCH_PMC_GEN_PMCON_SWSMI_RTSL_1_5MS      0x00  // 1.5ms +/- 0.6ms
+#define B_PCH_PMC_GEN_PMCON_SLP_S4_MAW            (BIT5 | BIT4) // SLP_S4# Minimum Assertion Width
+#define V_PCH_PMC_GEN_PMCON_SLP_S4_MAW_1S         0x30  // 1 second
+#define V_PCH_PMC_GEN_PMCON_SLP_S4_MAW_2S         0x20  // 2 seconds
+#define V_PCH_PMC_GEN_PMCON_SLP_S4_MAW_3S         0x10  // 3 seconds
+#define V_PCH_PMC_GEN_PMCON_SLP_S4_MAW_4S         0x00  // 4 seconds
+#define B_PCH_PMC_GEN_PMCON_SLP_S4_ASE            BIT3  // SLP_S4# Assertion Scretch Enable
+#define B_PCH_PMC_GEN_PMCON_RTC_PWR_STS           BIT2  // RTC Power Status
+#define B_PCH_PMC_GEN_PMCON_AFTERG3_EN            BIT0  // After G3 State Enable
+
+#define R_PCH_PMC_GEN_PMCON_2                     0x24  // General PM Configuration 2
+#define B_PCH_PMC_GEN_PMCON_LOCK_S4_STRET_LD      BIT18 // SLP_S3 / SLP_S4 Stretching Policy Lock-Down
+#define B_PCH_PMC_GEN_PMCON_BIOS_PCI_EXP_EN       BIT10 // BIOS PCI Express Enable
+#define B_PCH_PMC_GEN_PMCON_PWRBTN_LVL            BIT9  // Power Button Level
+#define B_PCH_PMC_GEN_PMCON_SMI_LOCK              BIT4  // SMI Lock
+#define B_PCH_PMC_GEN_PMCON_PER_SMI_SEL           (BIT1 | BIT0) // Period SMI Select
+#define V_PCH_PMC_GEN_PMCON_PER_SMI_64S           0x0000 // 64 seconds
+#define V_PCH_PMC_GEN_PMCON_PER_SMI_32S           0x0001 // 32 seconds
+#define V_PCH_PMC_GEN_PMCON_PER_SMI_16S           0x0002 // 16 seconds
+#define V_PCH_PMC_GEN_PMCON_PER_SMI_8S            0x0003 //  8 seconds
+
+#define R_PCH_PMC_MFPMC                           0x28  // Message from PMC
+
+#define R_PCH_PMC_SEC_STS                         0x2C  // SEC Status
+#define B_PCH_PMC_SEC_STS_SEC                     (BIT3 | BIT2 | BIT1 | BIT0) // SEC Exclusion Cause
+
+#define R_PCH_PMC_CRID                            0x30  // Configured Revision ID
+#define B_PCH_PMC_CRID_RID_SEL                    (BIT1 | BIT0) // Revision ID Select
+
+#define R_PCH_PMC_FUNC_DIS                        0x34  // Function Disable Register
+#define B_PCH_PMC_FUNC_DIS_LPSS2_FUNC7            BIT31 // LPSS2 I2C #7
+#define B_PCH_PMC_FUNC_DIS_LPSS2_FUNC6            BIT30 // LPSS2 I2C #6
+#define B_PCH_PMC_FUNC_DIS_LPSS2_FUNC5            BIT29 // LPSS2 I2C #5
+#define B_PCH_PMC_FUNC_DIS_LPSS2_FUNC4            BIT28 // LPSS2 I2C #4
+#define B_PCH_PMC_FUNC_DIS_LPSS2_FUNC3            BIT27 // LPSS2 I2C #3
+#define B_PCH_PMC_FUNC_DIS_LPSS2_FUNC2            BIT26 // LPSS2 I2C #2
+#define B_PCH_PMC_FUNC_DIS_LPSS2_FUNC1            BIT25 // LPSS2 I2C #1
+#define B_PCH_PMC_FUNC_DIS_LPSS2_FUNC0            BIT24 // LPSS2 DMA Disable
+#define B_PCH_PMC_FUNC_DIS_PCI_EX_FUNC3           BIT23 // PCI Express Function 3 Disable
+#define B_PCH_PMC_FUNC_DIS_PCI_EX_FUNC2           BIT22 // PCI Express Function 2 Disable
+#define B_PCH_PMC_FUNC_DIS_PCI_EX_FUNC1           BIT21 // PCI Express Function 1 Disable
+#define B_PCH_PMC_FUNC_DIS_PCI_EX_FUNC0           BIT20 // PCI Express Function 0 Disable
+#define N_PCH_PMC_FUNC_DIS_PCI_EX_FUNC0           20
+#define B_PCH_PMC_FUNC_DIS_SEC                    BIT19 // SEC Disable
+#define B_PCH_PMC_FUNC_DIS_USB                    BIT18 // USB Disable
+#define B_PCH_PMC_FUNC_DIS_SATA                   BIT17 // SATA Disable
+#define B_PCH_PMC_FUNC_DIS_USH                    BIT15 // USH (USB3) Disable
+#define B_PCH_PMC_FUNC_DIS_OTG                    BIT14 // USB OTG Disable
+#define B_PCH_PMC_FUNC_DIS_LPE                    BIT13 // LPE Disable
+#define B_PCH_PMC_FUNC_DIS_AZALIA                 BIT12 // Azalia Disable
+#define B_PCH_PMC_FUNC_DIS_MIPI                   BIT11 // MIPI-HSI Disable
+#define B_PCH_PMC_FUNC_DIS_SDIO4                  BIT11 // SCC SDIO #4 (Device 23, eMMC4.5) Disable
+#define B_PCH_PMC_FUNC_DIS_SDIO3                  BIT10 // SCC SDIO #3 (Device 18, SD Card) Disable
+#define B_PCH_PMC_FUNC_DIS_SDIO2                  BIT9  // SCC SDIO #2 (Device 17, SDIO) Disable
+#define B_PCH_PMC_FUNC_DIS_SDIO1                  BIT8  // SCC SDIO #1 (Device 16, eMMC) Disable
+#define B_PCH_PMC_FUNC_DIS_LPSS1_FUNC7            BIT7  // LPSS1 Spare #2 Disable
+#define B_PCH_PMC_FUNC_DIS_LPSS1_FUNC6            BIT6  // LPSS1 Spare #1 Disable
+#define B_PCH_PMC_FUNC_DIS_LPSS1_FUNC5            BIT5  // LPSS1 SPI Disable
+#define B_PCH_PMC_FUNC_DIS_LPSS1_FUNC4            BIT4  // LPSS1 HS-UART #2 Disable
+#define B_PCH_PMC_FUNC_DIS_LPSS1_FUNC3            BIT3  // LPSS1 HS-UART #1 Disable
+#define B_PCH_PMC_FUNC_DIS_LPSS1_FUNC2            BIT2  // LPSS1 PWM #2 Disable
+#define B_PCH_PMC_FUNC_DIS_LPSS1_FUNC1            BIT1  // LPSS1 PWM #1 Disable
+#define B_PCH_PMC_FUNC_DIS_LPSS1_FUNC0            BIT0  // LPSS1 DMA Disable
+
+#define R_PCH_PMC_FUNC_DIS2                       0x38  // Function Disable 2 Register
+#define B_PCH_PMC_FUNC_DIS2_USH_SS_PHY            BIT2  // USH Super Speed PHY Disable
+#define B_PCH_PMC_FUNC_DIS2_OTG_SS_PHY            BIT1  // OTG Super Speed PHY Disable
+#define B_PCH_PMC_FUNC_DIS2_SMBUS                 BIT0  // SMBus Disable
+
+#define R_PCH_PMC_PMIR                            0x48  // Extended Test Mode Register (ETR)
+#define B_PCH_PMC_PMIR_CF9LOCK                    BIT31 // CF9h Lockdown
+#define B_PCH_PMC_PMIR_LTR_DEF                    BIT22 // LTR Default
+#define B_PCH_PMC_PMIR_IGNORE_HPET                BIT21 // Ignore HPET Disable Check Before Going to S0i2
+#define B_PCH_PMC_PMIR_CF9GR                      BIT20 // CF9h Global Reset
+
+#define R_PCH_PMC_VLT                             0x50  // Voltage Detect Register
+#define B_PCH_PMC_VLT_FUSES                       0xFF  // Voltage Detect Fuses
+
+#define R_PCH_PMC_GPI_ROUT                        0x58  // GPI Rout
+#define B_PCH_PMC_GPI_ROUT_0                      (BIT1 | BIT0)
+#define B_PCH_PMC_GPI_ROUT_1                      (BIT3 | BIT2)
+#define B_PCH_PMC_GPI_ROUT_2                      (BIT5 | BIT4)
+#define B_PCH_PMC_GPI_ROUT_3                      (BIT7 | BIT6)
+#define B_PCH_PMC_GPI_ROUT_4                      (BIT9 | BIT8)
+#define B_PCH_PMC_GPI_ROUT_5                      (BIT11 | BIT10)
+#define B_PCH_PMC_GPI_ROUT_6                      (BIT13 | BIT12)
+#define B_PCH_PMC_GPI_ROUT_7                      (BIT15 | BIT14)
+#define B_PCH_PMC_GPI_ROUT_8                      (BIT17 | BIT16)
+#define B_PCH_PMC_GPI_ROUT_9                      (BIT19 | BIT18)
+#define B_PCH_PMC_GPI_ROUT_10                     (BIT21 | BIT20)
+#define B_PCH_PMC_GPI_ROUT_11                     (BIT23 | BIT22)
+#define B_PCH_PMC_GPI_ROUT_12                     (BIT25 | BIT24)
+#define B_PCH_PMC_GPI_ROUT_13                     (BIT27 | BIT26)
+#define B_PCH_PMC_GPI_ROUT_14                     (BIT29 | BIT28)
+#define B_PCH_PMC_GPI_ROUT_15                     (BIT31 | BIT30)
+
+#define R_PCH_PMC_PCC0                            0x60  // Platform Clock Control 0
+#define B_PCH_PMC_PCC0_CLK_FREQ                   BIT2  // Clock Frequency
+#define B_PCH_PMC_PCC0_CLK_CTL                    (BIT1 | BIT0) // Clock Gating
+
+#define R_PCH_PMC_PCC1                            0x64  // Platform Clock Control 1
+#define B_PCH_PMC_PCC1_CLK_FREQ                   BIT2  // Clock Frequency
+#define B_PCH_PMC_PCC1_CLK_CTL                    (BIT1 | BIT0) // Clock Gating
+
+#define R_PCH_PMC_PCC2                            0x68  // Platform Clock Control 2
+#define B_PCH_PMC_PCC2_CLK_FREQ                   BIT2  // Clock Frequency
+#define B_PCH_PMC_PCC2_CLK_CTL                    (BIT1 | BIT0) // Clock Gating
+
+#define R_PCH_PMC_PCC3                            0x6C  // Platform Clock Control 3
+#define B_PCH_PMC_PCC3_CLK_FREQ                   BIT2  // Clock Frequency
+#define B_PCH_PMC_PCC3_CLK_CTL                    (BIT1 | BIT0) // Clock Gating
+
+#define R_PCH_PMC_PCC4                            0x70  // Platform Clock Control 4
+#define B_PCH_PMC_PCC4_CLK_FREQ                   BIT2  // Clock Frequency
+#define B_PCH_PMC_PCC4_CLK_CTL                    (BIT1 | BIT0) // Clock Gating
+
+#define R_PCH_PMC_PCC5                            0x74  // Platform Clock Control 5
+#define B_PCH_PMC_PCC5_CLK_FREQ                   BIT2  // Clock Frequency
+#define B_PCH_PMC_PCC5_CLK_CTL                    (BIT1 | BIT0) // Clock Gating
+
+#define R_PCH_PMC_S0IR_TMR                        0x80  // S0I Ready Residency Timer
+#define B_PCH_PMC_S0IR_TMR_RTIME                  0xFFFFFFFF // Time Spent in S0I Ready State
+
+#define R_PCH_PMC_S0I1_TMR                        0x84  // S0I1 Ready Residency Timer
+#define B_PCH_PMC_S0I1_TMR_RTIME                  0xFFFFFFFF // Time Spent in S0I1 Ready State
+
+#define R_PCH_PMC_S0I2_TMR                        0x88  // S0I2 Ready Residency Timer
+#define B_PCH_PMC_S0I2_TMR_RTIME                  0xFFFFFFFF // Time Spent in S0I2 Ready State
+
+#define R_PCH_PMC_S0I3_TMR                        0x8C  // S0I3 Ready Residency Timer
+#define B_PCH_PMC_S0I3_TMR_RTIME                  0xFFFFFFFF // Time Spent in S0I3 Ready State
+
+#define R_PCH_PMC_S0_TMR                          0x90  // S0 Residency Timer
+#define B_PCH_PMC_S0_TMR_RTIME                    0xFFFFFFFF // Time Spent in S0 State
+
+#define R_PCH_PMC_PSS                             0x98  // Power Island Power Status
+#define B_PCH_PMC_PSS_PG_STS                      0x3FFFF // Power Gate Status of All Power Islands
+#define B_PCH_PMC_PSS_PG_STS_USB_SUS              BIT17 // USB SUS
+#define B_PCH_PMC_PSS_PG_STS_USB                  BIT16 // USB
+#define B_PCH_PMC_PSS_PG_STS_OTG_VCCACLK          BIT15 // OTG VCCACLK
+#define B_PCH_PMC_PSS_PG_STS_OTG VCCA             BIT14 // OTG VCCA
+#define B_PCH_PMC_PSS_PG_STS_OTG_VCCS             BIT13 // OTG VCCS
+#define B_PCH_PMC_PSS_PG_STS_OTG_CTL              BIT12 // OTG Control
+#define B_PCH_PMC_PSS_PG_STS_USH_VCCA             BIT11 // USH VCCA
+#define B_PCH_PMC_PSS_PG_STS_USH_VCCS             BIT10 // USH VCCS
+#define B_PCH_PMC_PSS_PG_STS_USH_SUS              BIT9  // USH SUS
+#define B_PCH_PMC_PSS_PG_STS_USH_CTL              BIT8  // USH Control
+#define B_PCH_PMC_PSS_PG_STS_DFX                  BIT7  // DFX
+#define B_PCH_PMC_PSS_PG_STS_LPE                  BIT6  // LPE Audio
+#define B_PCH_PMC_PSS_PG_STS_LPSS                 BIT5  // LPSS
+#define B_PCH_PMC_PSS_PG_STS_PCIE                 BIT4  // PCIe
+#define B_PCH_PMC_PSS_PG_STS_HDA                  BIT2  // HDA
+#define B_PCH_PMC_PSS_PG_STS_SATA                 BIT1  // SATA
+
+#define R_PCH_PMC_D3_STS_0                        0xA0  // D3 Status 0
+#define B_PCH_PMC_D3_STS_0_LPSS1F7                BIT31 // LPSS 1 Function 7
+#define B_PCH_PMC_D3_STS_0_LPSS1F6                BIT30 // LPSS 1 Function 6
+#define B_PCH_PMC_D3_STS_0_LPSS1F5                BIT29 // LPSS 1 Function 5
+#define B_PCH_PMC_D3_STS_0_LPSS1F4                BIT28 // LPSS 1 Function 4
+#define B_PCH_PMC_D3_STS_0_LPSS1F3                BIT27 // LPSS 1 Function 3
+#define B_PCH_PMC_D3_STS_0_LPSS1F2                BIT26 // LPSS 1 Function 2
+#define B_PCH_PMC_D3_STS_0_LPSS1F1                BIT25 // LPSS 1 Function 1
+#define B_PCH_PMC_D3_STS_0_LPSS1F0                BIT24 // LPSS 1 Function 0
+#define B_PCH_PMC_D3_STS_0_PCIEF3                 BIT23 // PCIe Function 3
+#define B_PCH_PMC_D3_STS_0_PCIEF2                 BIT22 // PCIe Function 2
+#define B_PCH_PMC_D3_STS_0_PCIEF1                 BIT21 // PCIe Function 1
+#define B_PCH_PMC_D3_STS_0_PCIEF0                 BIT20 // PCIe Function 0
+#define B_PCH_PMC_D3_STS_0_USB                    BIT18 // USB
+#define B_PCH_PMC_D3_STS_0_SATA                   BIT17 // SATA
+#define B_PCH_PMC_D3_STS_0_USH                    BIT15 // USH
+#define B_PCH_PMC_D3_STS_0_OTG                    BIT14 // OTG
+#define B_PCH_PMC_D3_STS_0_LPE                    BIT13 // LPE
+#define B_PCH_PMC_D3_STS_0_HDA                    BIT12 // HDA
+#define B_PCH_PMC_D3_STS_0_MIPI                   BIT11 // MIPI-HSI
+#define B_PCH_PMC_D3_STS_0_SCCF2                  BIT10 // SCC Function 2
+#define B_PCH_PMC_D3_STS_0_SCCF1                  BIT9  // SCC Function 1
+#define B_PCH_PMC_D3_STS_0_SCCF0                  BIT8  // SCC Function 0
+#define B_PCH_PMC_D3_STS_0_LPSS0F7                BIT7  // LPSS 0 Function 7
+#define B_PCH_PMC_D3_STS_0_LPSS0F6                BIT6  // LPSS 0 Function 6
+#define B_PCH_PMC_D3_STS_0_LPSS0F5                BIT5  // LPSS 0 Function 5
+#define B_PCH_PMC_D3_STS_0_LPSS0F4                BIT4  // LPSS 0 Function 4
+#define B_PCH_PMC_D3_STS_0_LPSS0F3                BIT3  // LPSS 0 Function 3
+#define B_PCH_PMC_D3_STS_0_LPSS0F2                BIT2  // LPSS 0 Function 2
+#define B_PCH_PMC_D3_STS_0_LPSS0F1                BIT1  // LPSS 0 Function 1
+#define B_PCH_PMC_D3_STS_0_LPSS0F0                BIT0  // LPSS 0 Function 0
+
+#define R_PCH_PMC_D3_STS_1                        0xA4  // D3 Status 1
+#define B_PCH_PMC_D3_STS_1_DFX                    BIT3  // DFX
+#define B_PCH_PMC_D3_STS_1_OTG_SS                 BIT2  // OTG SS
+#define B_PCH_PMC_D3_STS_1_USH_SS                 BIT1  // USH SS
+#define B_PCH_PMC_D3_STS_1_SMB                    BIT0  // SMBus
+#define R_PCH_PMC_D3_STDBY_STS_0                  0xA8  // D3 Standby Status 0
+#define B_PCH_PMC_D3_STDBY_STS_0_LPSS1F7          BIT31 // LPSS 1 Function 7
+#define B_PCH_PMC_D3_STDBY_STS_0_LPSS1F6          BIT30 // LPSS 1 Function 6
+#define B_PCH_PMC_D3_STDBY_STS_0_LPSS1F5          BIT29 // LPSS 1 Function 5
+#define B_PCH_PMC_D3_STDBY_STS_0_LPSS1F4          BIT28 // LPSS 1 Function 4
+#define B_PCH_PMC_D3_STDBY_STS_0_LPSS1F3          BIT27 // LPSS 1 Function 3
+#define B_PCH_PMC_D3_STDBY_STS_0_LPSS1F2          BIT26 // LPSS 1 Function 2
+#define B_PCH_PMC_D3_STDBY_STS_0_LPSS1F1          BIT25 // LPSS 1 Function 1
+#define B_PCH_PMC_D3_STDBY_STS_0_LPSS1F0          BIT24 // LPSS 1 Function 0
+#define B_PCH_PMC_D3_STDBY_STS_0_PCIEF3           BIT23 // PCIe Function 3
+#define B_PCH_PMC_D3_STDBY_STS_0_PCIEF2           BIT22 // PCIe Function 2
+#define B_PCH_PMC_D3_STDBY_STS_0_PCIEF1           BIT21 // PCIe Function 1
+#define B_PCH_PMC_D3_STDBY_STS_0_PCIEF0           BIT20 // PCIe Function 0
+#define B_PCH_PMC_D3_STDBY_STS_0_USB              BIT18 // USB
+#define B_PCH_PMC_D3_STDBY_STS_0_SATA             BIT17 // SATA
+#define B_PCH_PMC_D3_STDBY_STS_0_USH              BIT15 // USH
+#define B_PCH_PMC_D3_STDBY_STS_0_OTG              BIT14 // OTG
+#define B_PCH_PMC_D3_STDBY_STS_0_LPE              BIT13 // LPE
+#define B_PCH_PMC_D3_STDBY_STS_0_HDA              BIT12 // HDA
+#define B_PCH_PMC_D3_STDBY_STS_0_MIPI             BIT11 // MIPI-HSI
+#define B_PCH_PMC_D3_STDBY_STS_0_SCCF2            BIT10 // SCC Function 2
+#define B_PCH_PMC_D3_STDBY_STS_0_SCCF1            BIT9  // SCC Function 1
+#define B_PCH_PMC_D3_STDBY_STS_0_SCCF0            BIT8  // SCC Function 0
+#define B_PCH_PMC_D3_STDBY_STS_0_LPSS0F7          BIT7  // LPSS 0 Function 7
+#define B_PCH_PMC_D3_STDBY_STS_0_LPSS0F6          BIT6  // LPSS 0 Function 6
+#define B_PCH_PMC_D3_STDBY_STS_0_LPSS0F5          BIT5  // LPSS 0 Function 5
+#define B_PCH_PMC_D3_STDBY_STS_0_LPSS0F4          BIT4  // LPSS 0 Function 4
+#define B_PCH_PMC_D3_STDBY_STS_0_LPSS0F3          BIT3  // LPSS 0 Function 3
+#define B_PCH_PMC_D3_STDBY_STS_0_LPSS0F2          BIT2  // LPSS 0 Function 2
+#define B_PCH_PMC_D3_STDBY_STS_0_LPSS0F1          BIT1  // LPSS 0 Function 1
+#define B_PCH_PMC_D3_STDBY_STS_0_LPSS0F0          BIT0  // LPSS 0 Function 0
+
+#define R_PCH_PMC_D3_STDBY_STS_1                  0xAC  // D3 Standby Status 1
+#define B_PCH_PMC_D3_STDBY_STS_1_DFX              BIT3  // DFX
+#define B_PCH_PMC_D3_STDBY_STS_1_OTG_SS           BIT2  // OTG SS
+#define B_PCH_PMC_D3_STDBY_STS_1_USH_SS           BIT1  // USH SS
+#define B_PCH_PMC_D3_STDBY_STS_1_SMB              BIT0  // SMBus
+
+#define R_PCH_PMC_MTPMC1                          0xB0  // Message to PMC 1
+
+#define R_PCH_PMC_MTPMC2                          0xB4  // Message to PMC 2
+
+#define R_PCH_PMC_MTPMC3                          0xB8  // Message to PMC 3
+
+#define R_PCH_PMC_MTPMC4                          0xBC  // Message to PMC 4
+
+//
+// IO Memory Space Registers (IOBASE)
+//
+#define R_PCH_CFIO_PAD_CONF0                      0x00  // CFIO PAD_CONF0
+#define R_PCH_CFIO_PAD_CONF1                      0x04  // CFIO PAD_CONF1
+#define R_PCH_CFIO_PAD_VAL                        0x08  // CFIO PAD_VAL
+#define R_PCH_CFIO_PAD_DFT                        0x0C  // CFIO PAD_CFT
+
+//
+// GPIO Register Offsets from GBASE
+//
+#define R_PCH_GPIO_SC_USE_SEL                     0x00  // GPIO South Usage Select [31:0]
+#define R_PCH_GPIO_SC_IO_SEL                      0x04  // GPIO South Input / Output Select [31:0]
+#define R_PCH_GPIO_SC_LVL                         0x08  // GPIO South Level for Input or Output [31:0]
+
+#define R_PCH_GPIO_SC_TPE                         0x0C  // GPIO South Trigger Positive Edge Enable [31:0]
+#define R_PCH_GPIO_SC_TNE                         0x10  // GPIO South Trigger Negative Edge Enable [31:0]
+#define R_PCH_GPIO_SC_TS                          0x14  // GPIO South Trigger Status [31:0]
+
+#define R_PCH_GPIO_SC_USE_SEL2                    0x20  // GPIO South Usage Select 2 [63:32]
+#define R_PCH_GPIO_SC_IO_SEL2                     0x24  // GPIO South Input / Output Select 2 [63:32]
+#define R_PCH_GPIO_SC_LVL2                        0x28  // GPIO South Level for Input or Output 2 [63:32]
+
+#define R_PCH_GPIO_SC_TPE2                        0x2C  // GPIO South Trigger Positive Edge Enable 2 [63:32]
+#define R_PCH_GPIO_SC_TNE2                        0x30  // GPIO South Trigger Negative Edge Enable 2 [63:32]
+#define R_PCH_GPIO_SC_TS2                         0x34  // GPIO South Trigger Status 2 [63:32]
+
+#define R_PCH_GPIO_SC_USE_SEL3                    0x40  // GPIO South Usage Select 3 [95:64]
+#define R_PCH_GPIO_SC_IO_SEL3                     0x44  // GPIO South Input / Output Select 3 [95:64]
+#define R_PCH_GPIO_SC_LVL3                        0x48  // GPIO South Level for Input or Output 3 [95:64]
+
+#define R_PCH_GPIO_SC_TPE3                        0x4C  // GPIO South Trigger Positive Edge Enable 3 [95:64]
+#define R_PCH_GPIO_SC_TNE3                        0x50  // GPIO South Trigger Negative Edge Enable 3 [95:64]
+#define R_PCH_GPIO_SC_TS3                         0x54  // GPIO South Trigger Status 3 [95:64]
+
+#define R_PCH_GPIO_SC_USE_SEL4                    0x60  // GPIO South Usage Select 4 [127:96]
+#define R_PCH_GPIO_SC_IO_SEL4                     0x64  // GPIO South Input / Output Select 4 [127:96]
+#define R_PCH_GPIO_SC_LVL4                        0x68  // GPIO South Level for Input or Output 4 [127:96]
+
+#define R_PCH_GPIO_SC_TPE4                        0x6C  // GPIO South Trigger Positive Edge Enable 4 [127:96]
+#define R_PCH_GPIO_SC_TNE4                        0x70  // GPIO South Trigger Negative Edge Enable 4 [127:96]
+#define R_PCH_GPIO_SC_TS4                         0x74  // GPIO South Trigger Status 4 [127:96]
+
+#define R_PCH_GPIO_SUS_USE_SEL                    0x80  // GPIO Suspend Use Select [31:0]
+#define R_PCH_GPIO_SUS_IO_SEL                     0x84  // GPIO Suspend Input / Output Select [31:0]
+#define R_PCH_GPIO_SUS_LVL                        0x88  // GPIO Suspend Level for Input or Output [31:0]
+
+#define R_PCH_GPIO_SUS_TPE                        0x8C  // GPIO Suspend Trigger Positive Edge Enable [31:0]
+#define R_PCH_GPIO_SUS_TNE                        0x90  // GPIO Suspend Trigger Negative Edge Enable [31:0]
+#define R_PCH_GPIO_SUS_TS                         0x94  // GPIO Suspend Trigger Status [31:0]
+
+#define R_PCH_GPIO_SUS_WAKE_EN                    0x98  // GPIO Suspend Wake Enable [31:0]
+
+#define R_PCH_GPIO_SUS_USE_SEL2                   0x100 // GPIO Suspend Use Select 2 [42:32]
+#define R_PCH_GPIO_SUS_IO_SEL2                    0x104 // GPIO Suspend Input / Output Select 2 [42:32]
+#define R_PCH_GPIO_SUS_LVL2                       0x108 // GPIO Suspend Level for Input or Output 2 [42:32]
+
+#define R_PCH_GPIO_SUS_TPE2                       0x10C // GPIO Suspend Trigger Positive Edge Enable [42:32]
+#define R_PCH_GPIO_SUS_TNE2                       0x110 // GPIO Suspend Trigger Negative Edge Enable [42:32]
+#define R_PCH_GPIO_SUS_TS2                        0x114 // GPIO Suspend Trigger Status [42:32]
+
+#define R_PCH_GPIO_SUS_WAKE_EN2                   0x118 // GPIO Suspend Wake Enable 2 [42:32]
+
+//
+// Fixed IO Space
+//
+
+//
+// Processor Interface Registers
+//
+#define R_PCH_NMI_SC                              0x61  // NMI Status and Control
+#define B_PCH_NMI_SC_SERR_NMI_STS                 BIT7  // SERR# NMI Status
+#define B_PCH_NMI_SC_IOCHK_NMI_STS                BIT6  // IOCHK NMI Status
+#define B_PCH_NMI_SC_TMR2_OUT_STS                 BIT5  // Timer Counter 2 Status
+#define B_PCH_NMI_SC_REF_TOGGLE                   BIT4  // Refresh Cycle toggle Status
+#define B_PCH_NMI_SC_IOCHK_NMI_EN                 BIT3  // IOCHK NMI Enable
+#define B_PCH_NMI_SC_PCI_SERR_EN                  BIT2  // SERR# NMI Enable
+#define B_PCH_NMI_SC_SPKR_DAT_EN                  BIT1  // Speaker Data Enable
+#define B_PCH_NMI_SC_TIM_CNT2_EN                  BIT0  // Timer Counter 2 Enable
+
+#define R_PCH_NMI_EN                              0x70  // NMI Enable and Real Time Clock Index, Co-function with R_PCH_RTC_INDEX
+#define B_PCH_NMI_EN_NMI_EN                       BIT7  // NMI Enable, must preserve this bit first before writing to IO port 0x70
+
+//
+// RTC Registers
+//
+#define R_PCH_RTC_INDEX                           0x70  // NMI Enable and Real Time Clock Index, Co-function with R_PCH_NMI_EN
+#define R_PCH_RTC_TARGET                          0x71  // Real-Time Clock Target Register
+#define R_PCH_RTC_EXT_INDEX                       0x72  // Extended RAM Index Register
+#define R_PCH_RTC_EXT_TARGET                      0x73  // Extended RAM Target Register
+#define R_PCH_RTC_INDEX2                          0x74  // Real-Time Clock Index Register
+#define R_PCH_RTC_TARGET2                         0x75  // Real-Time Clock Target Register
+#define R_PCH_RTC_EXT_INDEX2                      0x76  // Extended RAM Index Register
+#define R_PCH_RTC_EXT_TARGET2                     0x77  // Extended RAM Target Register
+
+#define R_PCH_RTC_SECONDS                         0x00  // Seconds, Range 0..59
+#define R_PCH_RTC_SECONDSALARM                    0x01  // Seconds Alarm, Range 0..59
+#define R_PCH_RTC_MINUTES                         0x02  // Minutes, Range 0..59
+#define R_PCH_RTC_MINUTESALARM                    0x03  // Minutes Alarm, Range 0..59
+#define R_PCH_RTC_HOURS                           0x04  // Hours, Range 1..12 or 0..23 Bit 7 is AM/PM
+#define R_PCH_RTC_HOURSALARM                      0x05  // Hours Alarm, Range 1..12 or 0..23 Bit 7 is AM/PM
+#define R_PCH_RTC_DAYOFWEEK                       0x06  // Day of Week, Range 1..7
+#define R_PCH_RTC_DAYOFMONTH                      0x07  // Day of Month, Range 1..31
+#define R_PCH_RTC_MONTH                           0x08  // Month, Range 1..12
+#define R_PCH_RTC_YEAR                            0x09  // Year, Range 0..99
+
+#define R_PCH_RTC_REGISTERA                       0x0A  // RTC Register A
+#define B_PCH_RTC_REGISTERA_UIP                   BIT7  // Update In Progress
+#define B_PCH_RTC_REGISTERA_DV                    (BIT6 | BIT5 | BIT4) // Division Chain Select
+#define V_PCH_RTC_REGISTERA_DV_NORM_OP            0x20  // Normal Operation
+#define V_PCH_RTC_REGISTERA_DV_BYP_5              0x30  // Bypass 5 Stages (Test mode only)
+#define V_PCH_RTC_REGISTERA_DV_BYP_10             0x40  // Bypass 10 Stages (Test mode only)
+#define V_PCH_RTC_REGISTERA_DV_BYP_15             0x50  // Bypass 15 Stages (Test mode only)
+#define V_PCH_RTC_REGISTERA_DV_DIV_RST1           0x60  // Divider Reset
+#define V_PCH_RTC_REGISTERA_DV_DIV_RST2           0x70  // Divider Reset
+#define B_PCH_RTC_REGISTERA_RS                    (BIT3 | BIT2 | BIT1 | BIT0) // Rate Select
+#define V_PCH_RTC_REGISTERA_RS_INT_NV_TGL         0x00  // Interrupt Never Toggles
+#define V_PCH_RTC_REGISTERA_RS_3P906MS1           0x01  // 3.90625 ms
+#define V_PCH_RTC_REGISTERA_RS_7P812MS1           0x02  // 7.8125 ms
+#define V_PCH_RTC_REGISTERA_RS_122P0US            0x03  // 122.070 us
+#define V_PCH_RTC_REGISTERA_RS_244P1US            0x04  // 244.141 us
+#define V_PCH_RTC_REGISTERA_RS_488P2US            0x05  // 488.281 us
+#define V_PCH_RTC_REGISTERA_RS_976P5US            0x06  // 976.5625 us
+#define V_PCH_RTC_REGISTERA_RS_1P953MS            0x07  // 1.953125 ms
+#define V_PCH_RTC_REGISTERA_RS_3P906MS            0x08  // 3.90625 ms
+#define V_PCH_RTC_REGISTERA_RS_7P812MS            0x09  // 7.8125 ms
+#define V_PCH_RTC_REGISTERA_RS_15P62MS            0x0A  // 15.625 ms
+#define V_PCH_RTC_REGISTERA_RS_31P25MS            0x0B  // 31.25 ms
+#define V_PCH_RTC_REGISTERA_RS_62P5MS             0x0C  // 62.5 ms
+#define V_PCH_RTC_REGISTERA_RS_125MS              0x0D  // 125 ms
+#define V_PCH_RTC_REGISTERA_RS_250MS              0x0E  // 250 ms
+#define V_PCH_RTC_REGISTERA_RS_500MS              0x0F  // 500 ms
+
+#define R_PCH_RTC_REGISTERB                       0x0B  // RTC Register B
+#define B_PCH_RTC_REGISTERB_SET                   BIT7  // Update Cycle Inhibit 1: Stop auto update, begin set value; 0: Update cycle occurs
+#define B_PCH_RTC_REGISTERB_PIE                   BIT6  // Periodic Interrupt Enable
+#define B_PCH_RTC_REGISTERB_AIE                   BIT5  // Alarm Interrupt Enable
+#define B_PCH_RTC_REGISTERB_UIE                   BIT4  // Update-ended Interrupt Enable
+#define B_PCH_RTC_REGISTERB_SQWE                  BIT3  // Square Wave Enable (Not implemented)
+#define B_PCH_RTC_REGISTERB_DM                    BIT2  // Data Mode 1: Binary; 0:BCD
+#define B_PCH_RTC_REGISTERB_HF                    BIT1  // Hour Format 1: 24 mode; 0: 12 mode.
+#define B_PCH_RTC_REGISTERB_DSE                   BIT0  // Daylight Savings Enable (Not Implemented)
+
+#define R_PCH_RTC_REGISTERC                       0x0C  // RTC Register C
+#define B_PCH_RTC_REGISTERC_IRQF                  BIT7  // Interrupt Request Flag
+#define B_PCH_RTC_REGISTERC_PF                    BIT6  // Periodic Interrupt Flag
+#define B_PCH_RTC_REGISTERC_AF                    BIT5  // Alarm Flag
+#define B_PCH_RTC_REGISTERC_UF                    BIT4  // Update-ended Flag
+#define B_PCH_RTC_REGISTERC_RESERVED              (BIT3 | BIT2 | BIT1 | BIT0)
+
+#define R_PCH_RTC_REGISTERD                       0x0D  // RTC Register D
+#define B_PCH_RTC_REGISTERD_VRT                   BIT7  // Valid RAM and Time Bit
+#define B_PCH_RTC_REGISTERD_RESERVED              BIT6
+#define B_PCH_RTC_REGISTERD_DA                    0x3F  // Date Alarm
+
+#define B_PCH_RTC_CENTURY                         0x32  // Century Data
+
+//
+// APM Registers
+//
+#define R_PCH_APM_CNT                             0xB2  // Advanced Power Management Control Port
+#define R_PCH_APM_STS                             0xB3  // Advanced Power Management Status Port
+
+//
+// INIT Register
+//
+#define R_PCH_PORT92                              0x92
+#define B_PCH_PORT92_ALT_A20_GATE                 BIT1  // Alternate A20 Gate
+#define B_PCH_PORT92_INIT_NOW                     BIT0  // Init Now
+
+//
+// PCU UART
+//
+#define R_PCH_COM1_BASE                           0x3F8 // COM1 IO BASE
+
+//
+// Reset Control Register
+//
+#define R_PCH_RST_CNT                             0xCF9 // Reset Control
+#define B_PCH_RST_CNT_FULL_RST                    BIT3
+#define B_PCH_RST_CNT_RST_CPU                     BIT2
+#define B_PCH_RST_CNT_SYS_RST                     BIT1
+#define V_PCH_RST_CNT_FULLRESET                   0x0E
+#define V_PCH_RST_CNT_HARDRESET                   0x06
+#define V_PCH_RST_CNT_SOFTRESET                   0x04  // Not supported by VLV
+#define V_PCH_RST_CNT_HARDSTARTSTATE              0x02
+#define V_PCH_RST_CNT_SOFTSTARTSTATE              0x00
+
+//
+// Fixed Memory Region
+//
+
+//
+// IO APIC Registers
+//
+#define R_PCH_IO_APIC_INDEX                       0xFEC00000 // IOAPIC Index Register, 8bit
+#define R_PCH_IO_APIC_WINDOW                      0xFEC00010 // IOAPIC Window Register, 32bit
+#define R_PCH_IO_APIC_EOI                         0xFEC00040 // IOAPIC EOI Register, 8bit
+
+#define R_PCH_IO_APIC_ID                          0x00  // Identification
+#define B_PCH_IO_APIC_ID_AID                      (BIT27 | BIT26 | BIT25 | BIT24) // APIC Identification
+
+#define R_PCH_IO_APIC_VS                          0x01  // Version
+#define B_PCH_IO_APIC_VS_MRE                      0xFF0000 // Maximum Redirection Entries
+#define B_PCH_IO_APIC_VS_PRQ                      BIT15 // Pin Assertion Register Supported
+#define B_PCH_IO_APIC_VS_VS                       0xFF  // Version
+
+//
+// HPET Registers
+//
+#define R_PCH_PCH_HPET                            0xFED00000 // HPET Base Address
+
+#define R_PCH_PCH_HPET_GCID                       0x00  // HPET General Capabilities and ID, 64bit
+#define B_PCH_PCH_HPET_GCID_CTP                   0xFFFFFFFF00000000 // Counter Tick Period
+#define B_PCH_PCH_HPET_GCID_VID                   0xFFFF0000 // Vendor ID
+#define B_PCH_PCH_HPET_GCID_LRC                   BIT15 // Legacy Rout Capable
+#define B_PCH_PCH_HPET_GCID_CS                    BIT13 // Counter Size
+#define B_PCH_PCH_HPET_GCID_NT                    0x1F00 // Number of Timers
+#define B_PCH_PCH_HPET_GCID_RID                   0xFF  // Revision ID
+#define N_PCH_HPET_ADDR_ASEL                      12
+
+#define R_PCH_PCH_HPET_GCFG                       0x10  // HPET General Configuration
+#define B_PCH_PCH_HPET_GCFG_LRE                   BIT1  // Legacy Rout Enable
+#define B_PCH_PCH_HPET_GCFG_EN                    BIT0  // Overall Enable
+
+#define R_PCH_PCH_HPET_GIS                        0x20  // HPET General Interrupt Status
+#define B_PCH_PCH_HPET_GIS_T2                     BIT2  // Timer 2 Status
+#define B_PCH_PCH_HPET_GIS_T1                     BIT1  // Timer 1 Status
+#define B_PCH_PCH_HPET_GIS_T0                     BIT0  // Timer 0 Status
+
+#define R_PCH_PCH_HPET_MCV                        0xF0  // HPET Main Counter Value, 64bit
+
+#define R_PCH_PCH_HPET_T0C                        0x100 // HPET Timer 0 Config and Capabilities
+#define R_PCH_PCH_HPET_T0CV_L                     0x108 // HPET Timer 0 Lower Comparator Value
+#define R_PCH_PCH_HPET_T0CV_H                     0x10C // HPET Timer 0 Upper Comparator Value
+
+#define R_PCH_PCH_HPET_T1C                        0x120 // HPET Timer 1 Config and Capabilities
+#define R_PCH_PCH_HPET_T1CV                       0x128 // HPET Timer 1 Comparator Value
+
+#define R_PCH_PCH_HPET_T2C                        0x140 // HPET Timer 2 Config and Capabilities
+#define R_PCH_PCH_HPET_T2CV                       0x148 // HPET Timer 2 Comparator Value
+
+#define B_PCH_PCH_HPET_TXC_IRC                    0xFFFFFFFF00000000 // Interrupt Rout Capability
+#define B_PCH_PCH_HPET_TXC_FID                    BIT15 // FSB Interrupt Delivery
+#define B_PCH_PCH_HPET_TXC_FE                     BIT14 // FSB Enable
+#define B_PCH_PCH_HPET_TXC_IR                     0x3E00 // Interrupt Rout
+#define B_PCH_PCH_HPET_TXC_T32M                   BIT8  // Timer 32-bit Mode
+#define B_PCH_PCH_HPET_TXC_TVS                    BIT6  // Timer Value Set
+#define B_PCH_PCH_HPET_TXC_TS                     BIT5  // Timer Size
+#define B_PCH_PCH_HPET_TXC_PIC                    BIT4  // Periodic Interrupt Capable
+#define B_PCH_PCH_HPET_TXC_TYP                    BIT3  // Timer Type
+#define B_PCH_PCH_HPET_TXC_IE                     BIT2  // Interrupt Enable
+#define B_PCH_PCH_HPET_TXC_IT                     BIT1  // Timer Interrupt Type
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsRcrb.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsRcrb.h
new file mode 100644
index 0000000000..7cc599cd6a
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsRcrb.h
@@ -0,0 +1,48 @@
+/**
+
+Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+  @file
+  PchRegsRcrb.h
+
+  @brief
+  Register names for VLV Chipset Configuration Registers
+
+  Conventions:
+
+  - Prefixes:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values of bits within the registers
+    Definitions beginning with "S_" are register sizes
+    Definitions beginning with "N_" are the bit position
+  - In general, PCH registers are denoted by "_PCH_" in register names
+  - Registers / bits that are different between PCH generations are denoted by
+    "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_VLV_"
+  - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+    at the end of the register/bit names
+  - Registers / bits of new devices introduced in a PCH generation will be just named
+    as "_PCH_" without <generation_name> inserted.
+
+**/
+#ifndef _PCH_REGS_RCRB_H_
+#define _PCH_REGS_RCRB_H_
+
+///
+/// Chipset Configuration Registers (Memory space)
+/// RCBA
+///
+#define R_PCH_RCRB_GCS                    0x00  // General Control and Status
+#define B_PCH_RCRB_GCS_BBSIZE             (BIT30 | BIT29) // Boot Block Size
+#define B_PCH_RCRB_GCS_BBS                (BIT11 | BIT10) // Boot BIOS Straps
+#define V_PCH_RCRB_GCS_BBS_SPI            (3 << 10) // Boot BIOS strapped to SPI
+#define V_PCH_RCRB_GCS_BBS_LPC            (0 << 10) // Boot BIOS strapped to LPC
+#define B_PCH_RCRB_GCS_TS                 BIT1 // Top Swap
+#define B_PCH_RCRB_GCS_BILD               BIT0 // BIOS Interface Lock-Down
+
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsSata.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsSata.h
new file mode 100644
index 0000000000..a326e178fe
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsSata.h
@@ -0,0 +1,245 @@
+/**
+
+Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+  @file
+  PchRegsSata.h
+
+  @brief
+  Register names for VLV SATA controllers
+
+  Conventions:
+
+  - Prefixes:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values of bits within the registers
+    Definitions beginning with "S_" are register sizes
+    Definitions beginning with "N_" are the bit position
+  - In general, PCH registers are denoted by "_PCH_" in register names
+  - Registers / bits that are different between PCH generations are denoted by
+    "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_VLV_"
+  - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+    at the end of the register/bit names
+  - Registers / bits of new devices introduced in a PCH generation will be just named
+    as "_PCH_" without <generation_name> inserted.
+
+**/
+#ifndef _PCH_REGS_SATA_H_
+#define _PCH_REGS_SATA_H_
+
+///
+/// VLV SATA Message Bus
+///
+#define PCH_SATA_PHY_PORT_ID                0xA3  // SATA PHY Port ID
+#define PCH_SATA_PHY_MMIO_READ_OPCODE       0x00  // CUnit to SATA PHY MMIO Read Opcode
+#define PCH_SATA_PHY_MMIO_WRITE_OPCODE      0x01  // CUnit to SATA PHY MMIO Write Opcode
+
+///
+///  SATA Controller Registers (D19:F0)
+///
+#define PCI_DEVICE_NUMBER_PCH_SATA          19
+#define PCI_FUNCTION_NUMBER_PCH_SATA        0
+
+#define R_PCH_SATA_ID                       0x00  // Identifiers
+#define B_PCH_SATA_ID_DID                   0xFFFF0000 // Device ID
+#define B_PCH_SATA_ID_VID                   0x0000FFFF // Vendor ID
+#define V_PCH_SATA_VENDOR_ID                V_PCH_INTEL_VENDOR_ID
+#define V_PCH_SATA_DEVICE_ID_D_IDE          0x0F20  // Desktop IDE Mode (Ports 0 and 1)
+#define V_PCH_SATA_DEVICE_ID_D_AHCI         0x0F22  // Desktop AHCI Mode (Ports 0 and 1)
+#define V_PCH_SATA_DEVICE_ID_D_RAID         0x2822  // Desktop RAID 0/1/5/10 Mode, based on D19:F0:9Ch[7]
+
+#define V_PCH_SATA_DEVICE_ID_M_IDE          0x0F21  // Mobile IDE Mode (Ports 0 and 1)
+#define V_PCH_SATA_DEVICE_ID_M_AHCI         0x0F23  // Mobile AHCI Mode (Ports 0 and 1)
+#define V_PCH_SATA_DEVICE_ID_M_RAID         0x282A  // Mobile RAID 0/1/5/10 Mode, based on D19:F0:9Ch[7]
+
+#define R_PCH_SATA_COMMAND                  0x04  // Command
+#define B_PCH_SATA_COMMAND_INT_DIS          BIT10 // Interrupt Disable
+#define B_PCH_SATA_COMMAND_FBE              BIT9  // Fast Back-to-back Enable
+#define B_PCH_SATA_COMMAND_SERR_EN          BIT8  // SERR# Enable
+#define B_PCH_SATA_COMMAND_WCC              BIT7  // Wait Cycle Enable
+#define B_PCH_SATA_COMMAND_PER              BIT6  // Parity Error Response Enable
+#define B_PCH_SATA_COMMAND_VPS              BIT5  // VGA Palette Snooping Enable
+#define B_PCH_SATA_COMMAND_PMWE             BIT4  // Memory Write and Invalidate Enable
+#define B_PCH_SATA_COMMAND_SCE              BIT3  // Special Cycle Enable
+#define B_PCH_SATA_COMMAND_BME              BIT2  // Bus Master Enable
+#define B_PCH_SATA_COMMAND_MSE              BIT1  // Memory Space Enable
+#define B_PCH_SATA_COMMAND_IOSE             BIT0  // I/O Space Enable
+
+#define R_PCH_SATA_PCISTS                   0x06  // Device Status
+#define B_PCH_SATA_PCISTS_DPE               BIT15 // Detected Parity Error
+#define B_PCH_SATA_PCISTS_SSE               BIT14 // Signaled System Error
+#define B_PCH_SATA_PCISTS_RMA               BIT13 // Received Master-Abort Status
+#define B_PCH_SATA_PCISTS_RTA               BIT12 // Received Target-Abort Status
+#define B_PCH_SATA_PCISTS_STA               BIT11 // Signaled Target-Abort Status
+#define B_PCH_SATA_PCISTS_DEV_STS_MASK      (BIT10 | BIT9) // DEVSEL# Timing Status
+#define B_PCH_SATA_PCISTS_DPED              BIT8  // Master Data Parity Error Detected
+#define B_PCH_SATA_PCISTS_CAP_LIST          BIT4  // Capabilities List
+#define B_PCH_SATA_PCISTS_ITNS              BIT3  // Interrupt Status
+
+#define R_PCH_SATA_RID                      0x08  // Revision ID (8 bits)
+
+#define R_PCH_SATA_PI_REGISTER              0x09  // Programming Interface (8 bits)
+#define B_PCH_SATA_PI_REGISTER_SNC          BIT3  // Secondary Mode Native Capable
+#define B_PCH_SATA_PI_REGISTER_SNE          BIT2  // Secondary Mode Native Enable
+#define B_PCH_SATA_PI_REGISTER_PNC          BIT1  // Primary Mode Native Capable
+#define B_PCH_SATA_PI_REGISTER_PNE          BIT0  // Primary Mode Native Enable
+
+#define R_PCH_SATA_CC                       0x0A  // Class Code
+#define B_PCH_SATA_CC_BCC                   0xFF00 // Base Class Code
+#define B_PCH_SATA_CC_SCC                   0x00FF // Sub Class Code
+#define V_PCH_SATA_CC_SCC_IDE               0x01
+#define V_PCH_SATA_CC_SCC_AHCI              0x06
+#define V_PCH_SATA_CC_SCC_RAID              0x04
+
+#define R_PCH_SATA_CLS                      0x0C  // Cache Line Size (8 bits)
+#define B_PCH_SATA_CLS                      0xFF
+
+#define R_PCH_SATA_MLT                      0x0D  // Master Latency Timer (8 bits)
+#define B_PCH_SATA_MLT                      0xFF
+
+#define R_PCH_SATA_HTYPE                    0x0E  // Header Type
+#define B_PCH_SATA_HTYPE_MFD                BIT7  // Multi-function Device
+#define B_PCH_SATA_HTYPE_HL                 0x7F  // Header Layout
+
+#define R_PCH_SATA_PCMD_BAR                 0x10  // Primary Command Block Base Address
+#define B_PCH_SATA_PCMD_BAR_BA              0x0000FFF8 // Base Address
+#define B_PCH_SATA_PCMD_BAR_RTE             BIT0  // Resource Type Indicator
+
+#define R_PCH_SATA_PCTL_BAR                 0x14  // Primary Control Block Base Address
+#define B_PCH_SATA_PCTL_BAR_BA              0x0000FFFC // Base Address
+#define B_PCH_SATA_PCTL_BAR_RTE             BIT0  // Resource Type Indicator
+
+#define R_PCH_SATA_SCMD_BAR                 0x18  // Secondary Command Block Base Address
+#define B_PCH_SATA_SCMD_BAR_BA              0x0000FFF8 // Base Address
+#define B_PCH_SATA_SCMD_BAR_RTE             BIT0  // Resource Type Indicator
+
+#define R_PCH_SATA_SCTL_BAR                 0x1C  // Secondary Control Block Base Address
+#define B_PCH_SATA_SCTL_BAR_BA              0x0000FFFC // Base Address
+#define B_PCH_SATA_SCTL_BAR_RTE             BIT0  // Resource Type Indicator
+
+#define R_PCH_SATA_LBAR                     0x20  // Legacy IDE Base Address / AHCI Index Data Pair Base Address
+#define B_PCH_SATA_LBAR_BA                  0x0000FFE0 // Base Address
+#define B_PCH_SATA_LBAR_BA4                 BIT4  // Base Address 4
+#define B_PCH_SATA_LBAR_RTE                 BIT0  // Resource Type Indicator
+
+#define R_PCH_SATA_SIDPBA                   0x24  // Serial ATA Index Data Pair Base Address
+#define R_PCH_SATA_ABAR                     0x24  // AHCI Base Address
+#define B_PCH_SATA_ABAR_BA                  0xFFFFF800 // AHCI Memory Base Address (When CC.SCC not equal 0x01)
+#define V_PCH_SATA_ABAR_LENGTH              0x800 // AHCI Memory Length (When CC.SCC not equal 0x01)
+#define N_PCH_SATA_ABAR_ALIGNMENT           11    // AHCI Base Address Alignment (When CC.SCC not equal 0x01)
+#define B_PCH_SATA_SIDPBA_BA                0x0000FFF0 // Serial ATA Index Data Pair IO Base Address (When CC.SCC equal 0x01)
+#define V_PCH_SATA_SIDPBA_LENGTH            0x10  // Serial ATA Index Data Pair IO Length (When CC.SCC equal 0x01)
+#define N_PCH_SATA_SIDPBA_ALIGNMENT         4     // Serial ATA Index Data Pair Base Address Alignment (When CC.SCC not equal 0x01)
+#define B_PCH_SATA_ABAR_PF                  BIT3  // Prefetchable
+#define B_PCH_SATA_ABAR_TP                  (BIT2 | BIT1) // Type
+#define B_PCH_SATA_ABAR_RTE                 BIT0  // Resource Type Indicator
+
+#define R_PCH_SATA_SS                       0x2C  // Sub System Identifiers
+#define B_PCH_SATA_SS_SSID                  0xFFFF0000 // Subsystem ID
+#define B_PCH_SATA_SS_SSVID                 0x0000FFFF // Subsystem Vendor ID
+
+#define R_PCH_SATA_AHCI_CAP_PTR             0x34  // Capabilities Pointer (8 bits)
+#define B_PCH_SATA_AHCI_CAP_PTR             0xFF
+
+#define R_PCH_SATA_INTR                     0x3C  // Interrupt Information
+#define B_PCH_SATA_INTR_IPIN                0xFFFF0000 // Interrupt Pin
+#define B_PCH_SATA_INTR_ILINE               0x0000FFFF // Interrupt Line
+
+#define R_PCH_SATA_PMCS                     0x74  // PCI Power Management Control and Status
+#define B_PCH_SATA_PMCS_PMES                BIT15 // PME Status
+#define B_PCH_SATA_PMCS_PMEE                BIT8  // PME Enable
+#define B_PCH_SATA_PMCS_NSFRST              BIT3  // No Soft Reset
+#define V_PCH_SATA_PMCS_NSFRST_1            0x01
+#define V_PCH_SATA_PMCS_NSFRST_0            0x00
+#define B_PCH_SATA_PMCS_PS                  (BIT1 | BIT0) // Power State
+#define V_PCH_SATA_PMCS_PS_3                0x03
+#define V_PCH_SATA_PMCS_PS_0                0x00
+
+#define R_PCH_SATA_MAP                      0x90  // Port Mapping Register
+#define B_PCH_SATA_MAP_SPD                  (BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8) // SATA Port Disable
+#define B_PCH_SATA_PORT6_DISABLED           BIT14
+#define B_PCH_SATA_PORT5_DISABLED           BIT13
+#define B_PCH_SATA_PORT4_DISABLED           BIT12
+#define B_PCH_SATA_PORT3_DISABLED           BIT11
+#define B_PCH_SATA_PORT2_DISABLED           BIT10
+#define B_PCH_SATA_PORT1_DISABLED           BIT9
+#define B_PCH_SATA_PORT0_DISABLED           BIT8
+#define B_PCH_SATA_MAP_SMS_MASK             (BIT7 | BIT6) // SATA Mode Select
+#define V_PCH_SATA_MAP_SMS_IDE              0x00
+#define V_PCH_SATA_MAP_SMS_AHCI             0x40
+#define V_PCH_SATA_MAP_SMS_RAID             0x80
+#define B_PCH_SATA_PORT_TO_CONTROLLER_CFG   BIT5  // SATA Port-to-Controller Configuration
+
+#define R_PCH_SATA_PCS                      0x92  // Port Control and Status
+#define S_PCH_SATA_PCS                      0x2
+#define B_PCH_SATA_PCS_OOB_RETRY            BIT15 // OOB Retry Mode
+#define B_PCH_SATA_PCS_PORT6_DET            BIT14 // Port 6 Present
+#define B_PCH_SATA_PCS_PORT5_DET            BIT13 // Port 5 Present
+#define B_PCH_SATA_PCS_PORT4_DET            BIT12 // Port 4 Present
+#define B_PCH_SATA_PCS_PORT3_DET            BIT11 // Port 3 Present
+#define B_PCH_SATA_PCS_PORT2_DET            BIT10 // Port 2 Present
+#define B_PCH_SATA_PCS_PORT1_DET            BIT9  // Port 1 Present
+#define B_PCH_SATA_PCS_PORT0_DET            BIT8  // Port 0 Present
+#define B_PCH_SATA_PCS_PORT5_EN             BIT5  // Port 5 Enabled
+#define B_PCH_SATA_PCS_PORT4_EN             BIT4  // Port 4 Enabled
+#define B_PCH_SATA_PCS_PORT3_EN             BIT3  // Port 3 Enabled
+#define B_PCH_SATA_PCS_PORT2_EN             BIT2  // Port 2 Enabled
+#define B_PCH_SATA_PCS_PORT1_EN             BIT1  // Port 1 Enabled
+#define B_PCH_SATA_PCS_PORT0_EN             BIT0  // Port 0 Enabled
+
+#define R_PCH_SATA_AHCI_PI                  0x0C  // Ports Implemented
+#define B_PCH_SATA_PORT_MASK                0x3F
+#define B_PCH_SATA_PORT5_IMPLEMENTED        BIT5  // Port 5 Implemented
+#define B_PCH_SATA_PORT4_IMPLEMENTED        BIT4  // Port 4 Implemented
+#define B_PCH_SATA_PORT3_IMPLEMENTED        BIT3  // Port 3 Implemented
+#define B_PCH_SATA_PORT2_IMPLEMENTED        BIT2  // Port 2 Implemented
+#define B_PCH_SATA_PORT1_IMPLEMENTED        BIT1  // Port 1 Implemented
+#define B_PCH_SATA_PORT0_IMPLEMENTED        BIT0  // Port 0 Implemented
+
+#define R_PCH_SATA_AHCI_P0SSTS              0x128 // Port 0 Serial ATA Status
+#define R_PCH_SATA_AHCI_P1SSTS              0x1A8 // Port 1 Serial ATA Status
+#define B_PCH_SATA_AHCI_PXSSTS_IPM          0x00000F00 // Interface Power Management
+#define B_PCH_SATA_AHCI_PXSSTS_IPM_0        0x00000000
+#define B_PCH_SATA_AHCI_PXSSTS_IPM_1        0x00000100
+#define B_PCH_SATA_AHCI_PXSSTS_IPM_2        0x00000200
+#define B_PCH_SATA_AHCI_PXSSTS_IPM_6        0x00000600
+#define B_PCH_SATA_AHCI_PXSSTS_SPD          0x000000F0 // Current Interface Speed
+#define B_PCH_SATA_AHCI_PXSSTS_SPD_0        0x00000000
+#define B_PCH_SATA_AHCI_PXSSTS_SPD_1        0x00000010
+#define B_PCH_SATA_AHCI_PXSSTS_SPD_2        0x00000020
+#define B_PCH_SATA_AHCI_PXSSTS_SPD_3        0x00000030
+#define B_PCH_SATA_AHCI_PXSSTS_DET          0x0000000F // Device Detection
+#define B_PCH_SATA_AHCI_PXSSTS_DET_0        0x00000000
+#define B_PCH_SATA_AHCI_PXSSTS_DET_1        0x00000001
+#define B_PCH_SATA_AHCI_PXSSTS_DET_3        0x00000003
+#define B_PCH_SATA_AHCI_PXSSTS_DET_4        0x00000004
+
+//
+// Macros of VLV capabilities for SATA controller which are used by SATA controller driver
+//
+//
+//
+// Define the individual capabilities of each SATA controller
+//
+#define PCH_SATA_MAX_CONTROLLERS            1     // Max SATA controllers number supported
+#define PCH_SATA_MAX_DEVICES                2     // Max SATA devices number of single SATA channel
+#define PCH_IDE_MAX_CHANNELS                2     // Max IDE channels number of single SATA controller
+#define PCH_IDE_MAX_DEVICES                 2     // Max IDE devices number of single SATA channel
+#define PCH_AHCI_MAX_PORTS                  2     // Max number of SATA ports in VLV
+#define PCH_IDE_MAX_PORTS                   2     // Max number of IDE ports in VLV
+
+//
+// GPIOS_14 SATA0GP is the SATA port 0 reset pin.
+//
+#define PCH_GPIO_SATA_PORT0_RESET           14
+//
+// GPIOS_15 SATA1GP is the SATA port 1 reset pin.
+//
+#define PCH_GPIO_SATA_PORT1_RESET           15
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsScc.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsScc.h
new file mode 100644
index 0000000000..a45c2358f6
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsScc.h
@@ -0,0 +1,53 @@
+/*++
+
+Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  PchRegsScc.h
+
+Abstract:
+
+  Register names for VLV SCC module.
+
+  Conventions:
+
+  - Prefixes:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values of bits within the registers
+    Definitions beginning with "S_" are register sizes
+    Definitions beginning with "N_" are the bit position
+  - In general, PCH registers are denoted by "_PCH_" in register names
+  - Registers / bits that are different between PCH generations are denoted by
+    "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_VLV_"
+  - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+    at the end of the register/bit names
+  - Registers / bits of new devices introduced in a PCH generation will be just named
+    as "_PCH_" without <generation_name> inserted.
+
+--*/
+#ifndef _PCH_REGS_SCC_H_
+#define _PCH_REGS_SCC_H_
+
+
+//
+// SCC Modules Registers
+//
+
+//
+// SCC SDIO Modules
+// PCI Config Space Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SCC_SDIO_0         16
+#define PCI_DEVICE_NUMBER_PCH_SCC_SDIO_1         17
+#define PCI_DEVICE_NUMBER_PCH_SCC_SDIO_2         18
+#define PCI_DEVICE_NUMBER_PCH_SCC_SDIO_3         23
+
+#define PCI_FUNCTION_NUMBER_PCH_SCC_SDIO         0
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsSmbus.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsSmbus.h
new file mode 100644
index 0000000000..dc858c244c
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsSmbus.h
@@ -0,0 +1,149 @@
+/**
+
+Copyright (c) 2011  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+  @file
+  PchRegsSmbus.h
+
+  @brief
+  Register names for VLV Smbus Device.
+
+  Conventions:
+
+  - Prefixes:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values of bits within the registers
+    Definitions beginning with "S_" are register sizes
+    Definitions beginning with "N_" are the bit position
+  - In general, PCH registers are denoted by "_PCH_" in register names
+  - Registers / bits that are different between PCH generations are denoted by
+    "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_VLV_"
+  - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+    at the end of the register/bit names
+  - Registers / bits of new devices introduced in a PCH generation will be just named
+    as "_PCH_" without <generation_name> inserted.
+
+**/
+#ifndef _PCH_REGS_SMBUS_H_
+#define _PCH_REGS_SMBUS_H_
+
+///
+/// SMBus Controller Registers (D31:F3)
+///
+#define PCI_DEVICE_NUMBER_PCH_SMBUS        31
+#define PCI_FUNCTION_NUMBER_PCH_SMBUS      3
+
+#define R_PCH_SMBUS_VENDOR_ID              0x00  // Vendor ID
+#define V_PCH_SMBUS_VENDOR_ID              V_PCH_INTEL_VENDOR_ID // Intel Vendor ID
+
+#define R_PCH_SMBUS_DEVICE_ID              0x02  // Device ID
+#define V_PCH_SMBUS_DEVICE_ID              0x0F12
+
+#define R_PCH_SMBUS_PCICMD                 0x04  // CMD register enables/disables, Memory/IO space access and interrupt
+#define B_PCH_SMBUS_PCICMD_INTR_DIS        BIT10 // Interrupt Disable
+#define B_PCH_SMBUS_PCICMD_FBE             BIT9  // FBE - reserved as '0'
+#define B_PCH_SMBUS_PCICMD_SERR_EN         BIT8  // SERR Enable - reserved as '0'
+#define B_PCH_SMBUS_PCICMD_WCC             BIT7  // Wait Cycle Control - reserved as '0'
+#define B_PCH_SMBUS_PCICMD_PER             BIT6  // Parity Error - reserved as '0'
+#define B_PCH_SMBUS_PCICMD_VPS             BIT5  // VGA Palette Snoop - reserved as '0'
+#define B_PCH_SMBUS_PCICMD_PMWE            BIT4  // Postable Memory Write Enable - reserved as '0'
+#define B_PCH_SMBUS_PCICMD_SCE             BIT3  // Special Cycle Enable - reserved as '0'
+#define B_PCH_SMBUS_PCICMD_BME             BIT2  // Bus Master Enable - reserved as '0'
+#define B_PCH_SMBUS_PCICMD_MSE             BIT1  // Memory Space Enable
+#define B_PCH_SMBUS_PCICMD_IOSE            BIT0  // I/O Space Enable
+
+#define R_PCH_SMBUS_BASE                   0x20  // The I/O memory bar
+#define B_PCH_SMBUS_BASE_BAR               0x0000FFE0 // Base Address
+#define B_PCH_SMBUS_BASE_IOSI              BIT0  // IO Space Indicator
+
+#define R_PCH_SMBUS_SVID                   0x2C  // Subsystem Vendor ID
+#define B_PCH_SMBUS_SVID                   0xFFFF // Subsystem Vendor ID
+
+//
+// SMBus I/O Registers
+//
+#define R_PCH_SMBUS_HSTS                   0x00  // Host Status Register R/W
+#define B_PCH_SMBUS_HSTS_ALL               0xFF
+#define B_PCH_SMBUS_BYTE_DONE_STS          BIT7  // Byte Done Status
+#define B_PCH_SMBUS_IUS                    BIT6  // In Use Status
+#define B_PCH_SMBUS_SMBALERT_STS           BIT5  // SMBUS Alert
+#define B_PCH_SMBUS_FAIL                   BIT4  // Failed
+#define B_PCH_SMBUS_BERR                   BIT3  // Bus Error
+#define B_PCH_SMBUS_DERR                   BIT2  // Device Error
+#define B_PCH_SMBUS_ERRORS                 (B_PCH_SMBUS_FAIL | B_PCH_SMBUS_BERR | B_PCH_SMBUS_DERR)
+#define B_PCH_SMBUS_INTR                   BIT1  // Interrupt
+#define B_PCH_SMBUS_HBSY                   BIT0  // Host Busy
+
+#define R_PCH_SMBUS_HCTL                   0x02  // Host Control Register R/W
+#define B_PCH_SMBUS_PEC_EN                 BIT7  // Packet Error Checking Enable
+#define B_PCH_SMBUS_START                  BIT6  // Start
+#define B_PCH_SMBUS_LAST_BYTE              BIT5  // Last Byte
+#define B_PCH_SMBUS_SMB_CMD                0x1C  // SMB Command
+#define V_PCH_SMBUS_SMB_CMD_BLOCK_PROCESS  0x1C  // Block Process
+#define V_PCH_SMBUS_SMB_CMD_IIC_READ       0x18  // I2C Read
+#define V_PCH_SMBUS_SMB_CMD_BLOCK          0x14  // Block
+#define V_PCH_SMBUS_SMB_CMD_PROCESS_CALL   0x10  // Process Call
+#define V_PCH_SMBUS_SMB_CMD_WORD_DATA      0x0C  // Word Data
+#define V_PCH_SMBUS_SMB_CMD_BYTE_DATA      0x08  // Byte Data
+#define V_PCH_SMBUS_SMB_CMD_BYTE           0x04  // Byte
+#define V_PCH_SMBUS_SMB_CMD_QUICK          0x00  // Quick
+#define B_PCH_SMBUS_KILL                   BIT1  // Kill
+#define B_PCH_SMBUS_INTREN                 BIT0  // Interrupt Enable
+
+#define R_PCH_SMBUS_HCMD                   0x03  // Host Command Register R/W
+#define B_PCH_SMBUS_HCMD                   0xFF  // Command to be transmitted
+
+#define R_PCH_SMBUS_TSA                    0x04  // Transmit Slave Address Register R/W
+#define B_PCH_SMBUS_ADDRESS                0xFE  // 7-bit address of the targeted slave
+#define B_PCH_SMBUS_RW_SEL                 BIT0  // Direction of the host transfer, 1 = read, 0 = write
+#define B_PCH_SMBUS_RW_SEL_READ            0x01  // Read
+#define B_PCH_SMBUS_RW_SEL_WRITE           0x00  // Write
+//
+#define R_PCH_SMBUS_HD0                    0x05  // Data 0 Register R/W
+#define R_PCH_SMBUS_HD1                    0x06  // Data 1 Register R/W
+#define R_PCH_SMBUS_HBD                    0x07  // Host Block Data Register R/W
+#define R_PCH_SMBUS_PEC                    0x08  // Packet Error Check Data Register R/W
+
+#define R_PCH_SMBUS_RSA                    0x09  // Receive Slave Address Register R/W
+#define B_PCH_SMBUS_SLAVE_ADDR             0x7F  // TCO slave address (Not used, reserved)
+
+#define R_PCH_SMBUS_SD                     0x0A  // Receive Slave Data Register R/W
+
+#define R_PCH_SMBUS_AUXS                   0x0C  // Auxiliary Status Register R/WC
+#define B_PCH_SMBUS_CRCE                   BIT0  // CRC Error
+//
+#define R_PCH_SMBUS_AUXC                   0x0D  // Auxiliary Control Register R/W
+#define B_PCH_SMBUS_E32B                   BIT1  // Enable 32-byte Buffer
+#define B_PCH_SMBUS_AAC                    BIT0  // Automatically Append CRC
+
+#define R_PCH_SMBUS_SMLC                   0x0E  // SMLINK Pin Control Register R/W
+#define B_PCH_SMBUS_SMLINK_CLK_CTL         BIT2  // Not supported
+#define B_PCH_SMBUS_SMLINK1_CUR_STS        BIT1  // Not supported
+#define B_PCH_SMBUS_SMLINK0_CUR_STS        BIT0  // Not supported
+
+
+#define R_PCH_SMBUS_SMBC                   0x0F  // SMBus Pin Control Register R/W
+#define B_PCH_SMBUS_SMBCLK_CTL             BIT2  // SMBCLK Control
+#define B_PCH_SMBUS_SMBDATA_CUR_STS        BIT1  // SMBDATA Current Status
+#define B_PCH_SMBUS_SMBCLK_CUR_STS         BIT0  // SMBCLK Current Status
+
+#define R_PCH_SMBUS_SSTS                   0x10  // Slave Status Register R/WC
+#define B_PCH_SMBUS_HOST_NOTIFY_STS        BIT0  // Host Notify Status
+
+#define R_PCH_SMBUS_SCMD                   0x11  // Slave Command Register R/W
+#define B_PCH_SMBUS_SMBALERT_DIS           BIT2  // Not supported
+#define B_PCH_SMBUS_HOST_NOTIFY_WKEN       BIT1  // Host Notify Wake Enable
+#define B_PCH_SMBUS_HOST_NOTIFY_INTREN     BIT0  // Host Notify Interrupt Enable
+
+#define R_PCH_SMBUS_NDA                    0x14  // Notify Device Address Register RO
+#define B_PCH_SMBUS_DEVICE_ADDRESS         0xFE  // Device Address
+
+#define R_PCH_SMBUS_NDLB                   0x16  // Notify Data Low Byte Register RO
+#define R_PCH_SMBUS_NDHB                   0x17  // Notify Data High Byte Register RO
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsSpi.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsSpi.h
new file mode 100644
index 0000000000..bca7e4567e
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsSpi.h
@@ -0,0 +1,119 @@
+/**
+
+Copyright (c) 2011  - 2015, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+  @file
+  PchRegsSpi.h
+
+  @brief
+  Register names for PCH SPI device.
+
+  Conventions:
+
+  - Prefixes:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values of bits within the registers
+    Definitions beginning with "S_" are register sizes
+    Definitions beginning with "N_" are the bit position
+  - In general, PCH registers are denoted by "_PCH_" in register names
+  - Registers / bits that are different between PCH generations are denoted by
+    "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_VLV_"
+  - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+    at the end of the register/bit names
+  - Registers / bits of new devices introduced in a PCH generation will be just named
+    as "_PCH_" without <generation_name> inserted.
+
+**/
+#ifndef _PCH_REGS_SPI_H_
+#define _PCH_REGS_SPI_H_
+
+///
+/// SPI Host Interface Registers
+///
+
+#define R_PCH_SPI_HSFS                       0x04  // Hardware Sequencing Flash Status Register (16bits)
+#define B_PCH_SPI_HSFS_FLOCKDN               BIT15 // Flash Configuration Lock-Down
+#define B_PCH_SPI_HSFS_FDV                   BIT14 // Flash Descriptor Valid
+#define B_PCH_SPI_HSFS_FDOPSS                BIT13 // Flash Descriptor Override Pin-Strap Status
+#define B_PCH_SPI_HSFS_SCIP                  BIT5  // SPI Cycle in Progress
+#define B_PCH_SPI_HSFS_BERASE_MASK           (BIT4 | BIT3) // Block / Sector Erase Size
+#define V_PCH_SPI_HSFS_BERASE_256B           0x00  // Block/Sector = 256 Bytes
+#define V_PCH_SPI_HSFS_BERASE_4K             0x01  // Block/Sector = 4K Bytes
+#define V_PCH_SPI_HSFS_BERASE_8K             0x10  // Block/Sector = 8K Bytes
+#define V_PCH_SPI_HSFS_BERASE_64K            0x11  // Block/Sector = 64K Bytes
+#define B_PCH_SPI_HSFS_AEL                   BIT2  // Access Error Log
+#define B_PCH_SPI_HSFS_FCERR                 BIT1  // Flash Cycle Error
+#define B_PCH_SPI_HSFS_FDONE                 BIT0  // Flash Cycle Done
+
+#define R_PCH_SPI_PR0                        0x74  // Protected Region 0 Register
+#define B_PCH_SPI_PR0_WPE                    BIT31 // Write Protection Enable
+#define B_PCH_SPI_PR0_PRL_MASK               0x1FFF0000 // Protected Range Limit Mask, [28:16] here represents upper limit of address [24:12]
+#define B_PCH_SPI_PR0_RPE                    BIT15 // Read Protection Enable
+#define B_PCH_SPI_PR0_PRB_MASK               0x00001FFF // Protected Range Base Mask, [12:0] here represents base limit of address [24:12]
+
+#define R_PCH_SPI_PR1                        0x78  // Protected Region 1 Register
+#define B_PCH_SPI_PR1_WPE                    BIT31 // Write Protection Enable
+#define B_PCH_SPI_PR1_PRL_MASK               0x1FFF0000 // Protected Range Limit Mask, [28:16] here represents upper limit of address [24:12]
+#define B_PCH_SPI_PR1_RPE                    BIT15 // Read Protection Enable
+#define B_PCH_SPI_PR1_PRB_MASK               0x00001FFF // Protected Range Base Mask, [12:0] here represents base limit of address [24:12]
+
+#define R_PCH_SPI_PREOP                      0x94  // Prefix Opcode Configuration Register (16 bits)
+#define B_PCH_SPI_PREOP1_MASK                0xFF00 // Prefix Opcode 1 Mask
+#define B_PCH_SPI_PREOP0_MASK                0x00FF // Prefix Opcode 0 Mask
+
+#define R_PCH_SPI_OPTYPE                     0x96  // Opcode Type Configuration
+#define B_PCH_SPI_OPTYPE7_MASK               (BIT15 | BIT14) // Opcode Type 7 Mask
+#define B_PCH_SPI_OPTYPE6_MASK               (BIT13 | BIT12) // Opcode Type 6 Mask
+#define B_PCH_SPI_OPTYPE5_MASK               (BIT11 | BIT10) // Opcode Type 5 Mask
+#define B_PCH_SPI_OPTYPE4_MASK               (BIT9 | BIT8) // Opcode Type 4 Mask
+#define B_PCH_SPI_OPTYPE3_MASK               (BIT7 | BIT6) // Opcode Type 3 Mask
+#define B_PCH_SPI_OPTYPE2_MASK               (BIT5 | BIT4) // Opcode Type 2 Mask
+#define B_PCH_SPI_OPTYPE1_MASK               (BIT3 | BIT2) // Opcode Type 1 Mask
+#define B_PCH_SPI_OPTYPE0_MASK               (BIT1 | BIT0) // Opcode Type 0 Mask
+#define V_PCH_SPI_OPTYPE_RDNOADDR            0x00  // Read cycle type without address
+#define V_PCH_SPI_OPTYPE_WRNOADDR            0x01  // Write cycle type without address
+#define V_PCH_SPI_OPTYPE_RDADDR              0x02  // Address required; Read cycle type
+#define V_PCH_SPI_OPTYPE_WRADDR              0x03  // Address required; Write cycle type
+
+#define R_PCH_SPI_OPMENU0                    0x98  // Opcode Menu Configuration 0 (32bits)
+#define R_PCH_SPI_OPMENU1                    0x9C  // Opcode Menu Configuration 1 (32bits)
+
+#define R_PCH_SPI_IND_LOCK                   0xA4  // Indvidual Lock
+#define B_PCH_SPI_IND_LOCK_PR0               BIT2  // PR0 LockDown
+
+
+#define R_PCH_SPI_FDOC                       0xB0  // Flash Descriptor Observability Control Register (32 bits)
+#define B_PCH_SPI_FDOC_FDSS_MASK             (BIT14 | BIT13 | BIT12) // Flash Descriptor Section Select
+#define V_PCH_SPI_FDOC_FDSS_FSDM             0x0000 // Flash Signature and Descriptor Map
+#define V_PCH_SPI_FDOC_FDSS_COMP             0x1000 // Component
+#define V_PCH_SPI_FDOC_FDSS_REGN             0x2000 // Region
+#define V_PCH_SPI_FDOC_FDSS_MSTR             0x3000 // Master
+#define V_PCH_SPI_FDOC_FDSS_VLVS             0x4000 // Soft Straps
+#define B_PCH_SPI_FDOC_FDSI_MASK             0x0FFC // Flash Descriptor Section Index
+
+#define R_PCH_SPI_FDOD                       0xB4  // Flash Descriptor Observability Data Register (32 bits)
+
+#define R_PCH_SPI_BCR                        0xFC  // BIOS Control Register
+#define S_PCH_SPI_BCR                        1
+#define B_PCH_SPI_BCR_SMM_BWP                BIT5  // SMM BIOS Write Protect Disable
+#define B_PCH_SPI_BCR_SRC                    (BIT3 | BIT2) // SPI Read Configuration (SRC)
+#define V_PCH_SPI_BCR_SRC_PREF_EN_CACHE_EN   0x08  // Prefetch Enable, Cache Enable
+#define V_PCH_SPI_BCR_SRC_PREF_DIS_CACHE_DIS 0x04  // Prefetch Disable, Cache Disable
+#define V_PCH_SPI_BCR_SRC_PREF_DIS_CACHE_EN  0x00  // Prefetch Disable, Cache Enable
+#define B_PCH_SPI_BCR_BLE                    BIT1  // Lock Enable (LE)
+#define B_PCH_SPI_BCR_BIOSWE                 BIT0  // Write Protect Disable (WPD)
+#define N_PCH_SPI_BCR_BLE                    1
+#define N_PCH_SPI_BCR_BIOSWE                 0
+
+//
+// Flash Descriptor Base Address Region (FDBAR) from Flash Region 0
+//
+#define R_PCH_SPI_FDBAR_FLVALSIG             0x00  // Flash Valid Signature
+#define V_PCH_SPI_FDBAR_FLVALSIG             0x0FF0A55A
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsUsb.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsUsb.h
new file mode 100644
index 0000000000..93b6419eb7
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/PchRegs/PchRegsUsb.h
@@ -0,0 +1,92 @@
+/**
+
+Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+  @file
+  PchRegsUsb.h
+
+  @brief
+  Register names for PCH USB devices.
+
+  Conventions:
+
+  - Prefixes:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values of bits within the registers
+    Definitions beginning with "S_" are register sizes
+    Definitions beginning with "N_" are the bit position
+  - In general, PCH registers are denoted by "_PCH_" in register names
+  - Registers / bits that are different between PCH generations are denoted by
+    "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_VLV_"
+  - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+    at the end of the register/bit names
+  - Registers / bits of new devices introduced in a PCH generation will be just named
+    as "_PCH_" without <generation_name> inserted.
+
+**/
+#ifndef _PCH_REGS_USB_H_
+#define _PCH_REGS_USB_H_
+
+///
+/// USB Definitions
+///
+
+typedef enum {
+  PchEhci1 = 0,
+  PchEhciControllerMax
+} PCH_USB20_CONTROLLER_TYPE;
+
+#define PCH_USB_MAX_PHYSICAL_PORTS          4      /// Max Physical Connector EHCI + XHCI, not counting virtual ports like USB-R.
+#define PCH_EHCI_MAX_PORTS                  4      /// Counting ports behind RMHs 8 from EHCI-1 and 6 from EHCI-2, not counting EHCI USB-R virtual ports.
+#define PCH_HSIC_MAX_PORTS                  2
+#define PCH_XHCI_MAX_USB3_PORTS             1
+
+#define PCI_DEVICE_NUMBER_PCH_USB           29
+#define PCI_FUNCTION_NUMBER_PCH_EHCI        0
+
+#define R_PCH_USB_VENDOR_ID                 0x00  // Vendor ID
+#define V_PCH_USB_VENDOR_ID                 V_PCH_INTEL_VENDOR_ID
+
+#define R_PCH_USB_DEVICE_ID                 0x02  // Device ID
+#define V_PCH_USB_DEVICE_ID_0               0x0F34  // EHCI#1
+
+#define R_PCH_EHCI_SVID                     0x2C  // USB2 Subsystem Vendor ID
+#define B_PCH_EHCI_SVID                     0xFFFF // USB2 Subsystem Vendor ID Mask
+
+#define R_PCH_EHCI_PWR_CNTL_STS             0x54  // Power Management Control / Status
+#define B_PCH_EHCI_PWR_CNTL_STS_PME_STS     BIT15 // PME Status
+#define B_PCH_EHCI_PWR_CNTL_STS_DATASCL     (BIT14 | BIT13) // Data Scale
+#define B_PCH_EHCI_PWR_CNTL_STS_DATASEL     (BIT12 | BIT11 | BIT10 | BIT9) // Data Select
+#define B_PCH_EHCI_PWR_CNTL_STS_PME_EN      BIT8  // Power Enable
+#define B_PCH_EHCI_PWR_CNTL_STS_PWR_STS     (BIT1 | BIT0) // Power State
+#define V_PCH_EHCI_PWR_CNTL_STS_PWR_STS_D0  0     // D0 State
+#define V_PCH_EHCI_PWR_CNTL_STS_PWR_STS_D3  (BIT1 | BIT0) // D3 Hot State
+
+///
+/// USB3 (XHCI) related definitions
+///
+#define PCI_DEVICE_NUMBER_PCH_XHCI          20
+#define PCI_FUNCTION_NUMBER_PCH_XHCI        0
+//
+/////
+///// XHCI PCI Config Space registers
+/////
+
+#define R_PCH_XHCI_SVID                     0x2C
+#define B_PCH_XHCI_SVID                     0xFFFF
+
+
+#define R_PCH_XHCI_PWR_CNTL_STS             0x74
+#define B_PCH_XHCI_PWR_CNTL_STS_PME_STS     BIT15
+#define B_PCH_XHCI_PWR_CNTL_STS_DATASCL     (BIT14 | BIT13)
+#define B_PCH_XHCI_PWR_CNTL_STS_DATASEL     (BIT12 | BIT11 | BIT10 | BIT9)
+#define B_PCH_XHCI_PWR_CNTL_STS_PME_EN      BIT8
+#define B_PCH_XHCI_PWR_CNTL_STS_PWR_STS     (BIT1 | BIT0)
+#define V_PCH_XHCI_PWR_CNTL_STS_PWR_STS_D3  (BIT1 | BIT0)
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PchInit.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PchInit.h
new file mode 100644
index 0000000000..c8aba9c5e6
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PchInit.h
@@ -0,0 +1,75 @@
+/**
+**/
+/**
+
+Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+  @file
+  PchInit.h
+
+  @brief
+  This file defines the PCH Init PPI
+
+**/
+#ifndef _PCH_INIT_H_
+#define _PCH_INIT_H_
+
+//
+// Define the PCH Init PPI GUID
+//
+
+
+#include <Protocol/PchPlatformPolicy.h>
+#define PCH_INIT_PPI_GUID \
+  { \
+    0x9ea894a, 0xbe0d, 0x4230, 0xa0, 0x3, 0xed, 0xc6, 0x93, 0xb4, 0x8e, 0x95 \
+  }
+extern EFI_GUID               gPchInitPpiGuid;
+
+///
+/// Forward reference for ANSI C compatibility
+///
+typedef struct _PCH_INIT_PPI  PCH_INIT_PPI;
+
+///
+/// Data structure definitions
+///
+typedef enum _CPU_STRAP_OPERATION {
+  GetCpuStrapSetData,
+  SetCpuStrapSetData,
+  LockCpuStrapSetData
+} CPU_STRAP_OPERATION;
+
+typedef
+EFI_STATUS
+(EFIAPI *PCH_USB_INIT) (
+  IN  EFI_PEI_SERVICES            **PeiServices
+  )
+/**
+
+  @brief
+  The function performing USB init in PEI phase. This could be used by USB recovery
+  or debug features that need USB initialization during PEI phase.
+  Note: Before executing this function, please be sure that PCH_INIT_PPI.Initialize
+  has been done and PchUsbPolicyPpi has been installed.
+
+  @param[in] PeiServices    General purpose services available to every PEIM
+
+  @retval EFI_SUCCESS       The function completed successfully
+  @retval Others            All other error conditions encountered result in an ASSERT.
+
+**/
+;
+
+///
+/// PCH_INIT_PPI Structure Definition
+///
+struct _PCH_INIT_PPI {
+  PCH_USB_INIT          UsbInit;
+};
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PchPeiInit.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PchPeiInit.h
new file mode 100644
index 0000000000..a9bbb3766c
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PchPeiInit.h
@@ -0,0 +1,34 @@
+
+/*++
+
+Copyright (c)  2013  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+Module Name:
+
+  PchPeiInit.h
+
+Abstract:
+
+
+--*/
+
+#ifndef _PCH_PEI_INIT_H_
+#define _PCH_PEI_INIT_H_
+
+//
+// Define the PCH PEI Init PPI GUID
+//
+#define PCH_PEI_INIT_PPI_GUID \
+  { \
+    0xACB93B08, 0x5CDC, 0x4A8F, 0x93, 0xD4, 0x6, 0xE3, 0x42, 0xDF, 0x18, 0x2E \
+  }
+
+//
+// Extern the GUID for PPI users.
+//
+extern EFI_GUID     gPchPeiInitPpiGuid;
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PchPlatformPolicy.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PchPlatformPolicy.h
new file mode 100644
index 0000000000..b3b2f549cd
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PchPlatformPolicy.h
@@ -0,0 +1,161 @@
+/**
+**/
+/**
+
+Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+  @file
+  PchPlatformPolicy.h
+
+  @brief
+  PCH policy PPI produced by a platform driver specifying various
+  expected PCH settings. This PPI is consumed by the PCH PEI modules.
+
+**/
+#ifndef PCH_PLATFORM_POLICY_H_
+#define PCH_PLATFORM_POLICY_H_
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+
+
+#include "PchRegs.h"
+
+//
+#define PCH_PLATFORM_POLICY_PPI_GUID \
+  { \
+    0x15344673, 0xd365, 0x4be2, 0x85, 0x13, 0x14, 0x97, 0xcc, 0x7, 0x61, 0x1d \
+  }
+
+extern EFI_GUID                         gPchPlatformPolicyPpiGuid;
+
+///
+/// Forward reference for ANSI C compatibility
+///
+typedef struct _PCH_PLATFORM_POLICY_PPI PCH_PLATFORM_POLICY_PPI;
+
+///
+/// PPI revision number
+/// Any backwards compatible changes to this PPI will result in an update in the revision number
+/// Major changes will require publication of a new PPI
+///
+/// Revision 1:    Original version
+///
+#define PCH_PLATFORM_POLICY_PPI_REVISION_1  1
+#define PCH_PLATFORM_POLICY_PPI_REVISION_2  2
+#define PCH_PLATFORM_POLICY_PPI_REVISION_3  3
+#define PCH_PLATFORM_POLICY_PPI_REVISION_4  4
+#define PCH_PLATFORM_POLICY_PPI_REVISION_5  5
+//
+// Generic definitions for device enabling/disabling used by PCH code.
+//
+#define PCH_DEVICE_ENABLE   1
+#define PCH_DEVICE_DISABLE  0
+
+typedef struct {
+  UINT8  ThermalDataReportEnable  : 1;   // OBSOLETE from Revision 5 !!! DO NOT USE !!!
+  UINT8  MchTempReadEnable        : 1;
+  UINT8  PchTempReadEnable        : 1;
+  UINT8  CpuEnergyReadEnable      : 1;
+  UINT8  CpuTempReadEnable        : 1;
+  UINT8  Cpu2TempReadEnable       : 1;
+  UINT8  TsOnDimmEnable           : 1;
+  UINT8  Dimm1TempReadEnable      : 1;
+
+  UINT8  Dimm2TempReadEnable      : 1;
+  UINT8  Dimm3TempReadEnable      : 1;
+  UINT8  Dimm4TempReadEnable      : 1;
+  UINT8  Rsvdbits                 : 5;
+} PCH_THERMAL_REPORT_CONTROL;
+//
+// ---------------------------- HPET Config -----------------------------
+//
+typedef struct {
+  BOOLEAN Enable; /// Determines if enable HPET function
+  UINT32  Base;   /// The HPET base address
+} PCH_HPET_CONFIG;
+
+
+///
+/// ---------------------------- SATA Config -----------------------------
+///
+typedef enum {
+  PchSataModeIde,
+  PchSataModeAhci,
+  PchSataModeRaid,
+  PchSataModeMax
+} PCH_SATA_MODE;
+
+///
+/// ---------------------------- PCI Express Config -----------------------------
+///
+typedef enum {
+  PchPcieAuto,
+  PchPcieGen1,
+  PchPcieGen2
+} PCH_PCIE_SPEED;
+
+typedef struct {
+  PCH_PCIE_SPEED  PcieSpeed[PCH_PCIE_MAX_ROOT_PORTS];
+} PCH_PCIE_CONFIG;
+
+///
+/// ---------------------------- IO APIC Config -----------------------------
+///
+typedef struct {
+  UINT8 IoApicId;
+} PCH_IOAPIC_CONFIG;
+
+///
+/// --------------------- Low Power Input Output Config ------------------------
+///
+typedef struct {
+  UINT8                   LpssPciModeEnabled    : 1;    /// Determines if LPSS PCI Mode enabled
+  UINT8                   Dma0Enabled           : 1;     /// Determines if LPSS DMA1 enabled
+  UINT8                   Dma1Enabled           : 1;     /// Determines if LPSS DMA2 enabled
+  UINT8                   I2C0Enabled           : 1;     /// Determines if LPSS I2C #1 enabled
+  UINT8                   I2C1Enabled           : 1;     /// Determines if LPSS I2C #2 enabled
+  UINT8                   I2C2Enabled           : 1;     /// Determines if LPSS I2C #3 enabled
+  UINT8                   I2C3Enabled           : 1;     /// Determines if LPSS I2C #4 enabled
+  UINT8                   I2C4Enabled           : 1;     /// Determines if LPSS I2C #5 enabled
+  UINT8                   I2C5Enabled           : 1;     /// Determines if LPSS I2C #6 enabled
+  UINT8                   I2C6Enabled           : 1;     /// Determines if LPSS I2C #7 enabled
+  UINT8                   Pwm0Enabled           : 1;     /// Determines if LPSS PWM #1 enabled
+  UINT8                   Pwm1Enabled           : 1;     /// Determines if LPSS PWM #2 enabled
+  UINT8                   Hsuart0Enabled        : 1;     /// Determines if LPSS HSUART #1 enabled
+  UINT8                   Hsuart1Enabled        : 1;     /// Determines if LPSS HSUART #2 enabled
+  UINT8                   SpiEnabled            : 1;     /// Determines if LPSS SPI enabled
+  UINT8                   Rsvdbits              : 2;
+} PEI_PCH_LPSS_CONFIG;
+
+///
+/// ------------ General PCH Platform Policy PPI definition ------------
+///
+struct _PCH_PLATFORM_POLICY_PPI {
+  UINT8                         Revision;
+  UINT8                         BusNumber;  // Bus Number of the PCH device
+  UINT32                        SpiBase;    // SPI Base Address.
+  UINT32                        PmcBase;    // PMC Base Address.
+  UINT32                        SmbmBase;   // SMB Memory Base Address.
+  UINT32                        IoBase;     // IO Base Address.
+  UINT32                        IlbBase;    // Intel Legacy Block Base Address.
+  UINT32                        PUnitBase;  // PUnit Base Address.
+  UINT32                        Rcba;       // Root Complex Base Address.
+  UINT32                        MphyBase;   // MPHY Base Address.
+  UINT16                        AcpiBase;   // ACPI I/O Base address.
+  UINT16                        GpioBase;   // GPIO Base address
+  PCH_HPET_CONFIG               *HpetConfig;
+  PCH_SATA_MODE                 SataMode;
+  PCH_PCIE_CONFIG               *PcieConfig;
+  PCH_IOAPIC_CONFIG             *IoApicConfig;
+  PEI_PCH_LPSS_CONFIG           *LpssConfig;
+  BOOLEAN                       EnableRmh;      // Determines if enable USB RMH function
+  BOOLEAN                       EhciPllCfgEnable;
+};
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PchUsbPolicy.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PchUsbPolicy.h
new file mode 100644
index 0000000000..d03aa4a8b4
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PchUsbPolicy.h
@@ -0,0 +1,69 @@
+/**
+**/
+/**
+
+Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+  @file
+  PchUsbPolicy.h
+
+  @brief
+  PCH Usb policy PPI produced by a platform driver specifying
+  various expected PCH Usb settings. This PPI is consumed by the
+  PCH PEI drivers.
+
+**/
+#ifndef _PCH_USB_POLICY_H_
+#define _PCH_USB_POLICY_H_
+
+//
+// PCH Usb policy provided by platform for PEI phase
+//
+
+#ifndef ECP_FLAG
+#include <PiPei.h>
+#endif
+
+#include "PchRegs.h"
+#include <Protocol/PchPlatformPolicy.h>
+
+#define PCH_USB_POLICY_PPI_GUID \
+  { \
+    0xc02b0573, 0x2b4e, 0x4a31, 0xa3, 0x1a, 0x94, 0x56, 0x7b, 0x50, 0x44, 0x2c \
+  }
+
+extern EFI_GUID                     gPchUsbPolicyPpiGuid;
+
+typedef struct _PCH_USB_POLICY_PPI  PCH_USB_POLICY_PPI;
+
+///
+/// PPI revision number
+/// Any backwards compatible changes to this PPI will result in an update in the revision number
+/// Major changes will require publication of a new PPI
+///
+/// Revision 1: Original version
+///
+#define PCH_USB_POLICY_PPI_REVISION_1 1
+
+///
+/// Generic definitions for device enabling/disabling used by PCH code.
+///
+#define PCH_DEVICE_ENABLE   1
+#define PCH_DEVICE_DISABLE  0
+
+#define EHCI_MODE           1
+
+struct _PCH_USB_POLICY_PPI {
+  UINT8           Revision;
+  PCH_USB_CONFIG  *UsbConfig;
+  UINT8           Mode;
+  UINTN           EhciMemBaseAddr;
+  UINT32          EhciMemLength;
+  UINTN           XhciMemBaseAddr;
+};
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PeiBlockIo.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PeiBlockIo.h
new file mode 100644
index 0000000000..d6c8366e26
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/PeiBlockIo.h
@@ -0,0 +1,230 @@
+/** @file
+  Block IO protocol as defined in the UEFI 2.0 specification.
+
+  The Block IO protocol is used to abstract block devices like hard drives,
+  DVD-ROMs and floppy drives.
+
+  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __PEI_BLOCK_IO_H__
+#define __PEI_BLOCK_IO_H__
+// {BC5FA650-EDBB-4d0d-B3A3-D98907F847DF}
+#ifndef ECP_FLAG
+#define PEI_BLOCK_IO_PPI_GUID \
+  {  \
+    0xbc5fa650, 0xedbb, 0x4d0d, { 0xb3, 0xa3, 0xd9, 0x89, 0x7, 0xf8, 0x47, 0xdf }  \
+  }
+#endif
+typedef struct _PEI_BLOCK_IO_PPI  PEI_BLOCK_IO_PPI;
+
+
+/**
+  Reset the Block Device.
+
+  @param  This                 Indicates a pointer to the calling context.
+  @param  ExtendedVerification Driver may perform diagnostics on reset.
+
+  @retval EFI_SUCCESS          The device was reset.
+  @retval EFI_DEVICE_ERROR     The device is not functioning properly and could
+                               not be reset.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PEI_BLOCK_RESET)(
+  IN PEI_BLOCK_IO_PPI               *This,
+  IN BOOLEAN                        ExtendedVerification
+  );
+
+/**
+  Read BufferSize bytes from Lba into Buffer.
+
+  @param  This       Indicates a pointer to the calling context.
+  @param  MediaId    Id of the media, changes every time the media is replaced.
+  @param  Lba        The starting Logical Block Address to read from
+  @param  BufferSize Size of Buffer, must be a multiple of device block size.
+  @param  Buffer     A pointer to the destination buffer for the data. The caller is
+                     responsible for either having implicit or explicit ownership of the buffer.
+
+  @retval EFI_SUCCESS           The data was read correctly from the device.
+  @retval EFI_DEVICE_ERROR      The device reported an error while performing the read.
+  @retval EFI_NO_MEDIA          There is no media in the device.
+  @retval EFI_MEDIA_CHANGED     The MediaId does not matched the current device.
+  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
+  @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
+                                or the buffer is not on proper alignment.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PEI_BLOCK_READ)(
+  IN  EFI_PEI_SERVICES              **PeiServices,
+  IN PEI_BLOCK_IO_PPI               *This,
+  IN UINT32                         MediaId,
+  IN EFI_LBA                        Lba,
+  IN UINTN                          BufferSize,
+  OUT VOID                          *Buffer
+  );
+
+/**
+  Write BufferSize bytes from Lba into Buffer.
+
+  @param  This       Indicates a pointer to the calling context.
+  @param  MediaId    The media ID that the write request is for.
+  @param  Lba        The starting logical block address to be written. The caller is
+                     responsible for writing to only legitimate locations.
+  @param  BufferSize Size of Buffer, must be a multiple of device block size.
+  @param  Buffer     A pointer to the source buffer for the data.
+
+  @retval EFI_SUCCESS           The data was written correctly to the device.
+  @retval EFI_WRITE_PROTECTED   The device can not be written to.
+  @retval EFI_DEVICE_ERROR      The device reported an error while performing the write.
+  @retval EFI_NO_MEDIA          There is no media in the device.
+  @retval EFI_MEDIA_CHNAGED     The MediaId does not matched the current device.
+  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
+  @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
+                                or the buffer is not on proper alignment.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PEI_BLOCK_WRITE)(
+  IN  EFI_PEI_SERVICES              **PeiServices,
+  IN PEI_BLOCK_IO_PPI               *This,
+  IN UINT32                         MediaId,
+  IN EFI_LBA                        Lba,
+  IN UINTN                          BufferSize,
+  IN VOID                           *Buffer
+  );
+
+/**
+  Flush the Block Device.
+
+  @param  This              Indicates a pointer to the calling context.
+
+  @retval EFI_SUCCESS       All outstanding data was written to the device
+  @retval EFI_DEVICE_ERROR  The device reported an error while writting back the data
+  @retval EFI_NO_MEDIA      There is no media in the device.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PEI_BLOCK_FLUSH)(
+  IN  PEI_BLOCK_IO_PPI           *This
+  );
+
+/**
+  Block IO read only mode data and updated only via members of BlockIO
+**/
+typedef struct {
+  ///
+  /// The curent media Id. If the media changes, this value is changed.
+  ///
+  UINT32  MediaId;
+
+  ///
+  /// TRUE if the media is removable; otherwise, FALSE.
+  ///
+  BOOLEAN RemovableMedia;
+
+  ///
+  /// TRUE if there is a media currently present in the device;
+  /// othersise, FALSE. THis field shows the media present status
+  /// as of the most recent ReadBlocks() or WriteBlocks() call.
+  ///
+  BOOLEAN MediaPresent;
+
+  ///
+  /// TRUE if LBA 0 is the first block of a partition; otherwise
+  /// FALSE. For media with only one partition this would be TRUE.
+  ///
+  BOOLEAN LogicalPartition;
+
+  ///
+  /// TRUE if the media is marked read-only otherwise, FALSE.
+  /// This field shows the read-only status as of the most recent WriteBlocks () call.
+  ///
+  BOOLEAN ReadOnly;
+
+  ///
+  /// TRUE if the WriteBlock () function caches write data.
+  ///
+  BOOLEAN WriteCaching;
+
+  ///
+  /// The intrinsic block size of the device. If the media changes, then
+  /// this field is updated.
+  ///
+  UINT32  BlockSize;
+
+  ///
+  /// Supplies the alignment requirement for any buffer to read or write block(s).
+  ///
+  UINT32  IoAlign;
+
+  ///
+  /// The last logical block address on the device.
+  /// If the media changes, then this field is updated.
+  ///
+  EFI_LBA LastBlock;
+
+  ///
+  /// Only present if EFI_BLOCK_IO_PROTOCOL.Revision is greater than or equal to
+  /// EFI_BLOCK_IO_PROTOCOL_REVISION2. Returns the first LBA is aligned to
+  /// a physical block boundary.
+  ///
+  EFI_LBA LowestAlignedLba;
+
+  ///
+  /// Only present if EFI_BLOCK_IO_PROTOCOL.Revision is greater than or equal to
+  /// EFI_BLOCK_IO_PROTOCOL_REVISION2. Returns the number of logical blocks
+  /// per physical block.
+  ///
+  UINT32 LogicalBlocksPerPhysicalBlock;
+
+  ///
+  /// Only present if EFI_BLOCK_IO_PROTOCOL.Revision is greater than or equal to
+  /// EFI_BLOCK_IO_PROTOCOL_REVISION3. Returns the optimal transfer length
+  /// granularity as a number of logical blocks.
+  ///
+  UINT32 OptimalTransferLengthGranularity;
+#ifdef ECP_FLAG
+} PEI_BLOCK_IO_MEDIA2;
+#else
+} PEI_BLOCK_IO_MEDIA;
+#endif
+#define EFI_BLOCK_IO_PROTOCOL_REVISION  0x00010000
+#define EFI_BLOCK_IO_PROTOCOL_REVISION2 0x00020001
+#define EFI_BLOCK_IO_PROTOCOL_REVISION3 0x00020031
+
+///
+/// Revision defined in EFI1.1.
+///
+#define EFI_BLOCK_IO_INTERFACE_REVISION   EFI_BLOCK_IO_PROTOCOL_REVISION
+
+///
+///  This protocol provides control over block devices.
+///
+struct _PEI_BLOCK_IO_PPI {
+  ///
+  /// The revision to which the block IO interface adheres. All future
+  /// revisions must be backwards compatible. If a future version is not
+  /// back wards compatible, it is not the same GUID.
+  ///
+  UINT64              Revision;
+  ///
+  /// Pointer to the EFI_BLOCK_IO_MEDIA data for this device.
+  ///
+  PEI_BLOCK_IO_MEDIA  *Media;
+  PEI_BLOCK_RESET     Reset;
+  PEI_BLOCK_READ      ReadBlocks;
+  PEI_BLOCK_WRITE     WriteBlocks;
+  PEI_BLOCK_FLUSH     FlushBlocks;
+};
+
+//extern EFI_GUID gEfiBlockIoProtocolGuid;
+extern EFI_GUID gPeiBlockIoPpiGuid;
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/Sdhc.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/Sdhc.h
new file mode 100644
index 0000000000..4909d81573
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/Sdhc.h
@@ -0,0 +1,359 @@
+/**
+**/
+/**
+
+Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+  @file
+  Spi.h
+
+  @brief
+  This file defines the EFI SPI PPI which implements the
+  Intel(R) PCH SPI Host Controller Compatibility Interface.
+
+**/
+#ifndef _PEI_SDHC_H_
+#define _PEI_SDHC_H_
+
+
+
+//
+#define PEI_SDHC_PPI_GUID \
+  {  \
+    0xf4ef9d7a, 0x98c5, 0x4c1a, 0xb4, 0xd9, 0xd8, 0xd8, 0x72, 0x65, 0xbe, 0xc \
+  }
+typedef struct _PEI_SD_CONTROLLER_PPI PEI_SD_CONTROLLER_PPI;
+
+#define EFI_SD_HOST_IO_PROTOCOL_REVISION_01          0x01
+
+typedef enum {
+  ResponseNo = 0,
+  ResponseR1,
+  ResponseR1b,
+  ResponseR2,
+  ResponseR3,
+  ResponseR4,
+  ResponseR5,
+  ResponseR5b,
+  ResponseR6,
+  ResponseR7
+} RESPONSE_TYPE;
+
+typedef enum {
+  NoData = 0,
+  InData,
+  OutData
+} TRANSFER_TYPE;
+
+typedef enum {
+  Reset_Auto = 0,
+  Reset_DAT,
+  Reset_CMD,
+  Reset_DAT_CMD,
+  Reset_All
+} RESET_TYPE;
+
+
+
+typedef enum {
+  SDMA = 0,
+  ADMA2,
+  PIO
+} DMA_MOD;
+
+typedef struct {
+  UINT32  HighSpeedSupport:    1;  //High speed supported
+  UINT32  V18Support:          1;  //1.8V supported
+  UINT32  V30Support:          1;  //3.0V supported
+  UINT32  V33Support:          1;  //3.3V supported
+  UINT32  Reserved0:           4;
+  UINT32  BusWidth4:           1;  // 4 bit width
+  UINT32  BusWidth8:           1;  // 8 bit width
+  UINT32  Reserved1:           6;
+  UINT32  SDMASupport:         1;
+  UINT32  ADMA2Support:        1;
+  UINT32  DmaMode:             2;
+  UINT32  Reserved2:           12;
+  UINT32  BoundarySize;
+}HOST_CAPABILITY;
+
+
+#define PCI_SUBCLASS_SD_HOST_CONTROLLER   0x05
+#define PCI_IF_STANDARD_HOST_NO_DMA       0x00
+#define PCI_IF_STANDARD_HOST_SUPPORT_DMA  0x01
+
+//
+//MMIO Registers definition for MMC/SDIO controller
+//
+#define  MMIO_DMAADR                     0x00
+#define  MMIO_BLKSZ                      0x04
+#define  MMIO_BLKCNT                     0x06
+#define  MMIO_CMDARG                     0x08
+#define  MMIO_XFRMODE                    0x0C
+#define  MMIO_SDCMD                      0x0E
+#define  MMIO_RESP                       0x10
+#define  MMIO_BUFDATA                    0x20
+#define  MMIO_PSTATE                     0x24
+#define  MMIO_HOSTCTL                    0x28
+#define  MMIO_PWRCTL                     0x29
+#define  MMIO_BLKGAPCTL                  0x2A
+#define  MMIO_WAKECTL                    0x2B
+#define  MMIO_CLKCTL                     0x2C
+#define  MMIO_TOCTL                      0x2E
+#define  MMIO_SWRST                      0x2F
+#define  MMIO_NINTSTS                    0x30
+#define  MMIO_ERINTSTS                   0x32
+#define  MMIO_NINTEN                     0x34
+#define  MMIO_ERINTEN                    0x36
+#define  MMIO_NINTSIGEN                  0x38
+#define  MMIO_ERINTSIGEN                 0x3A
+#define  MMIO_AC12ERRSTS                 0x3C
+#define  MMIO_HOST_CTL2                  0x3E //hphang <- New in VLV2
+#define  MMIO_CAP                        0x40
+#define  MMIO_CAP2                       0x44 //hphang <- New in VLV2
+#define  MMIO_MCCAP                      0x48
+#define  MMIO_FORCEEVENTCMD12ERRSTAT     0x50 //hphang <- New in VLV2
+#define  MMIO_FORCEEVENTERRINTSTAT       0x52 //hphang <- New in VLV2
+#define  MMIO_ADMAERRSTAT                0x54 //hphang <- New in VLV2
+#define  MMIO_ADMASYSADDR                0x58 //hphang <- New in VLV2
+#define  MMIO_PRESETVALUE0               0x60 //hphang <- New in VLV2
+#define  MMIO_PRESETVALUE1               0x64 //hphang <- New in VLV2
+#define  MMIO_PRESETVALUE2               0x68 //hphang <- New in VLV2
+#define  MMIO_PRESETVALUE3               0x6C //hphang <- New in VLV2
+#define  MMIO_BOOTTIMEOUTCTRL            0x70 //hphang <- New in VLV2
+#define  MMIO_DEBUGSEL                   0x74 //hphang <- New in VLV2
+#define  MMIO_SHAREDBUS                  0xE0 //hphang <- New in VLV2
+#define  MMIO_SPIINTSUP                  0xF0 //hphang <- New in VLV2
+#define  MMIO_SLTINTSTS                  0xFC
+#define  MMIO_CTRLRVER                   0xFE
+#define  MMIO_SRST                       0x1FC
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_CONTROLLER_PPI_SEND_COMMAND) (
+  IN  PEI_SD_CONTROLLER_PPI       *This,
+  IN   UINT16                     CommandIndex,
+  IN   UINT32                     Argument,
+  IN   TRANSFER_TYPE              DataType,
+  IN   UINT8                      *Buffer, OPTIONAL
+  IN   UINT32                     BufferSize,
+  IN   RESPONSE_TYPE              ResponseType,
+  IN   UINT32                     TimeOut,
+  OUT  UINT32                     *ResponseData OPTIONAL
+  );
+
+/*++
+
+  Routine Description:
+    Set max clock frequency of the host, the actual frequency
+    may not be the same as MaxFrequency. It depends on
+    the max frequency the host can support, divider, and host
+    speed mode.
+
+  Arguments:
+    This           - Pointer to EFI_SD_HOST_IO_PROTOCOL
+    MaxFrequency   - Max frequency in HZ
+
+  Returns:
+    EFI_SUCCESS
+    EFI_TIMEOUT
+--*/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_CONTROLLER_PPI_SET_CLOCK_FREQUENCY) (
+  IN  PEI_SD_CONTROLLER_PPI      *This,
+  IN  UINT32                     MaxFrequency
+  );
+
+/*++
+
+  Routine Description:
+    Set bus width of the host
+
+  Arguments:
+    This       - Pointer to EFI_SD_HOST_IO_PROTOCOL
+    BusWidth   - Bus width in 1, 4, 8 bits
+
+  Returns:
+    EFI_SUCCESS
+    EFI_INVALID_PARAMETER
+
+--*/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_CONTROLLER_PPI_SET_BUS_WIDTH) (
+  IN  PEI_SD_CONTROLLER_PPI      *This,
+  IN  UINT32                     BusWidth
+  );
+
+/*++
+
+  Routine Description:
+    Set Host mode in DDR
+  Arguments:
+    This      - Pointer to EFI_SD_HOST_IO_PROTOCOL
+    SetHostDdrMode   - True for DDR Mode set, false for normal mode
+
+  Returns:
+    EFI_SUCCESS
+    EFI_INVALID_PARAMETER
+
+--*/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SET_HOST_DDR_MODE) (
+  IN  PEI_SD_CONTROLLER_PPI    *This,
+  IN  UINT32                     DdrMode
+  );
+
+/*++
+
+  Routine Description:
+    Set voltage which could supported by the host.
+    Support 0(Power off the host), 1.8V, 3.0V, 3.3V
+  Arguments:
+    This      - Pointer to EFI_SD_HOST_IO_PROTOCOL
+    Voltage   - Units in 0.1 V
+
+  Returns:
+    EFI_SUCCESS
+    EFI_INVALID_PARAMETER
+
+--*/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_CONTROLLER_PPI_SET_HOST_VOLTAGE) (
+  IN  PEI_SD_CONTROLLER_PPI      *This,
+  IN  UINT32                     Voltage
+  );
+
+/*++
+
+  Routine Description:
+   Reset the host
+
+  Arguments:
+    This      - Pointer to EFI_SD_HOST_IO_PROTOCOL
+    ResetAll  - TRUE to reset all
+
+  Returns:
+    EFI_SUCCESS
+    EFI_TIMEOUT
+
+--*/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_CONTROLLER_PPI_RESET_SD_HOST) (
+  IN  PEI_SD_CONTROLLER_PPI      *This,
+  IN  RESET_TYPE                 ResetType
+  );
+
+/*++
+
+  Routine Description:
+   Reset the host
+
+  Arguments:
+    This    - Pointer to EFI_SD_HOST_IO_PROTOCOL
+    Enable  - TRUE to enable, FALSE to disable
+
+  Returns:
+    EFI_SUCCESS
+    EFI_TIMEOUT
+
+--*/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_CONTROLLER_PPI_ENABLE_AUTO_STOP_CMD) (
+  IN  PEI_SD_CONTROLLER_PPI      *This,
+  IN  BOOLEAN                    Enable
+  );
+
+/*++
+
+  Routine Description:
+    Find whether these is a card inserted into the slot. If so
+    init the host. If not, return EFI_NOT_FOUND.
+
+  Arguments:
+    This      - Pointer to EFI_SD_HOST_IO_PROTOCOL
+
+  Returns:
+    EFI_SUCCESS
+    EFI_NOT_FOUND
+
+--*/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_CONTROLLER_PPI_DETECT_CARD_AND_INIT_HOST) (
+  IN  PEI_SD_CONTROLLER_PPI      *This
+  );
+
+/*++
+
+  Routine Description:
+   Set the Block length
+
+  Arguments:
+    This        - Pointer to EFI_SD_HOST_IO_PROTOCOL
+    BlockLength - card supportes block length
+
+  Returns:
+    EFI_SUCCESS
+    EFI_TIMEOUT
+
+--*/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_CONTROLLER_PPI_SET_BLOCK_LENGTH) (
+  IN  PEI_SD_CONTROLLER_PPI      *This,
+  IN  UINT32                     BlockLength
+  );
+
+/*++
+
+  Routine Description:
+   Set the Block length
+
+  Arguments:
+    This        - Pointer to EFI_SD_HOST_IO_PROTOCOL
+    BlockLength - card supportes block length
+
+  Returns:
+    EFI_SUCCESS
+    EFI_TIMEOUT
+
+--*/
+
+typedef EFI_STATUS
+(EFIAPI *EFI_SD_CONTROLLER_PPI_SETUP_DEVICE)(
+  IN  PEI_SD_CONTROLLER_PPI    *This
+  );
+
+//
+// Interface structure for the EFI SD Host I/O Protocol
+//
+struct _PEI_SD_CONTROLLER_PPI {
+  UINT32                                           Revision;
+  HOST_CAPABILITY                                  HostCapability;
+  EFI_SD_CONTROLLER_PPI_SEND_COMMAND               SendCommand;
+  EFI_SD_CONTROLLER_PPI_SET_CLOCK_FREQUENCY        SetClockFrequency;
+  EFI_SD_CONTROLLER_PPI_SET_BUS_WIDTH              SetBusWidth;
+  EFI_SD_CONTROLLER_PPI_SET_HOST_VOLTAGE           SetHostVoltage;
+  EFI_SD_HOST_IO_PROTOCOL_SET_HOST_DDR_MODE        SetHostDdrMode;
+  EFI_SD_CONTROLLER_PPI_RESET_SD_HOST              ResetSdHost;
+  EFI_SD_CONTROLLER_PPI_ENABLE_AUTO_STOP_CMD       EnableAutoStopCmd;
+  EFI_SD_CONTROLLER_PPI_DETECT_CARD_AND_INIT_HOST  DetectCardAndInitHost;
+  EFI_SD_CONTROLLER_PPI_SET_BLOCK_LENGTH           SetBlockLength;
+  EFI_SD_CONTROLLER_PPI_SETUP_DEVICE               SetupDevice;
+};
+// Extern the GUID for PPI users.
+//
+extern EFI_GUID           gPeiSdhcPpiGuid;
+
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/SmbusPolicy.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/SmbusPolicy.h
new file mode 100644
index 0000000000..3f48142138
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/SmbusPolicy.h
@@ -0,0 +1,40 @@
+//
+//
+
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  SmbusPolicy.h
+
+Abstract:
+
+  Smbus Policy PPI as defined in EFI 2.0
+
+--*/
+#ifndef _PEI_SMBUS_POLICY_PPI_H
+#define _PEI_SMBUS_POLICY_PPI_H
+
+#define PEI_SMBUS_POLICY_PPI_GUID \
+  { \
+    0x63b6e435, 0x32bc, 0x49c6, 0x81, 0xbd, 0xb7, 0xa1, 0xa0, 0xfe, 0x1a, 0x6c \
+  }
+
+typedef struct _PEI_SMBUS_POLICY_PPI PEI_SMBUS_POLICY_PPI;
+
+struct _PEI_SMBUS_POLICY_PPI {
+  UINTN   BaseAddress;
+  UINT32  PciAddress;
+  UINT8   NumRsvdAddress;
+  UINT8   *RsvdAddress;
+};
+
+extern EFI_GUID gPeiSmbusPolicyPpiGuid;
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/Spi.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/Spi.h
new file mode 100644
index 0000000000..3496f59d1d
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ppi/Spi.h
@@ -0,0 +1,42 @@
+/**
+**/
+/**
+
+Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+  @file
+  Spi.h
+
+  @brief
+  This file defines the EFI SPI PPI which implements the
+  Intel(R) PCH SPI Host Controller Compatibility Interface.
+
+**/
+#ifndef _PEI_SPI_H_
+#define _PEI_SPI_H_
+
+
+#include <Protocol/Spi.h>
+
+
+//
+#define PEI_SPI_PPI_GUID \
+  { \
+    0xa38c6898, 0x2b5c, 0x4ff6, 0x93, 0x26, 0x2e, 0x63, 0x21, 0x2e, 0x56, 0xc2 \
+  }
+// Extern the GUID for PPI users.
+//
+extern EFI_GUID           gPeiSpiPpiGuid;
+
+///
+/// Reuse the EFI_SPI_PROTOCOL definitions
+/// This is possible becaues the PPI implementation does not rely on a PeiService pointer,
+/// as it uses EDKII Glue Lib to do IO accesses
+///
+typedef EFI_SPI_PROTOCOL  PEI_SPI_PPI;
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/ActiveBios.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/ActiveBios.h
new file mode 100644
index 0000000000..4bd0523445
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/ActiveBios.h
@@ -0,0 +1,123 @@
+/**
+**/
+/**
+
+Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+  @file
+  ActiveBios.h
+
+  @brief
+  This protocol is used to report and control what BIOS is mapped to the
+  BIOS address space anchored at 4GB boundary.
+
+  This protocol is EFI compatible.
+
+  E.G. For current generation ICH, the 4GB-16MB to 4GB range can be mapped
+  to PCI, SPI, or FWH.
+
+**/
+#ifndef _EFI_ACTIVE_BIOS_PROTOCOL_H_
+#define _EFI_ACTIVE_BIOS_PROTOCOL_H_
+
+
+
+
+//
+#define EFI_ACTIVE_BIOS_PROTOCOL_GUID \
+  { \
+    0xebbe2d1b, 0x1647, 0x4bda, 0xab, 0x9a, 0x78, 0x63, 0xe3, 0x96, 0xd4, 0x1a \
+  }
+extern EFI_GUID                           gEfiActiveBiosProtocolGuid;
+
+///
+/// Forward reference for ANSI C compatibility
+///
+typedef struct _EFI_ACTIVE_BIOS_PROTOCOL  EFI_ACTIVE_BIOS_PROTOCOL;
+
+///
+/// Protocol definitions
+///
+typedef enum {
+  ActiveBiosStateSpi,
+  ActiveBiosStatePci,   /// Obsolete since VLV
+  ActiveBiosStateLpc,
+  ActiveBiosStateMax
+} EFI_ACTIVE_BIOS_STATE;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ACTIVE_BIOS_SET_ACTIVE_BIOS_STATE) (
+  IN EFI_ACTIVE_BIOS_PROTOCOL     * This,
+  IN EFI_ACTIVE_BIOS_STATE        DesiredState,
+  IN UINTN                        Key
+  )
+/**
+
+  @brief
+  Change the current active BIOS settings to the requested state.
+  The caller is responsible for requesting a supported state from
+  the EFI_ACTIVE_BIOS_STATE selections.
+  This will fail if someone has locked the interface and the correct key is
+  not provided.
+
+  @param[in] This                 Pointer to the EFI_ACTIVE_BIOS_PROTOCOL instance.
+  @param[in] DesiredState         The requested state to configure the system for.
+  @param[in] Key                  If the interface is locked, Key must be the Key
+                                  returned from the LockState function call.
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_ACCESS_DENIED       The interface is currently locked.
+
+**/
+;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ACTIVE_BIOS_LOCK_ACTIVE_BIOS_STATE) (
+  IN     EFI_ACTIVE_BIOS_PROTOCOL   * This,
+  IN     BOOLEAN                    Lock,
+  IN OUT UINTN                      *Key
+  );
+
+/**
+
+  @brief
+  Lock the current active BIOS state from further changes.  This allows a
+  caller to implement a critical section.  This is optionally supported
+  functionality.  Size conscious implementations may choose to require
+  callers cooperate without support from this protocol.
+
+  @param[in] This                 Pointer to the EFI_ACTIVE_BIOS_PROTOCOL instance.
+  @param[in] Lock                 TRUE to lock the current state, FALSE to unlock.
+  @param[in] Key                  If Lock is TRUE, then a key will be returned.  If
+                                  Lock is FALSE, the key returned from the prior call
+                                  to lock the protocol must be provided to unlock the
+                                  protocol.  The value of Key is undefined except that
+                                  it cannot be 0.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @exception EFI_UNSUPPORTED      The function is not supported.
+  @retval EFI_ACCESS_DENIED       The interface is currently locked.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+
+**/
+
+///
+/// Protocol definition
+///
+/// Note that some functions are optional.  This means that they may be NULL.
+/// Caller is required to verify that an optional function is defined by checking
+/// that the value is not NULL.
+///
+struct _EFI_ACTIVE_BIOS_PROTOCOL {
+  EFI_ACTIVE_BIOS_STATE                   State;
+  EFI_ACTIVE_BIOS_SET_ACTIVE_BIOS_STATE   SetState;
+  EFI_ACTIVE_BIOS_LOCK_ACTIVE_BIOS_STATE  LockState;
+};
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/ActiveBiosProtocol.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/ActiveBiosProtocol.h
new file mode 100644
index 0000000000..a41e5831f1
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/ActiveBiosProtocol.h
@@ -0,0 +1,125 @@
+/**
+  This protocol is used to report and control what BIOS is mapped to the
+  BIOS address space anchored at 4GB boundary.
+
+  This protocol is EFI compatible.
+
+  E.G. For current generation ICH, the 4GB-16MB to 4GB range can be mapped
+  to PCI, SPI, or FWH.
+
+Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+
+#ifndef _EFI_ACTIVE_BIOS_PROTOCOL_H_
+#define _EFI_ACTIVE_BIOS_PROTOCOL_H_
+
+//
+// Define the  protocol GUID
+//
+#define EFI_ACTIVE_BIOS_PROTOCOL_GUID  \
+  { 0xebbe2d1b, 0x1647, 0x4bda, {0xab, 0x9a, 0x78, 0x63, 0xe3, 0x96, 0xd4, 0x1a} }
+
+typedef struct _EFI_ACTIVE_BIOS_PROTOCOL EFI_ACTIVE_BIOS_PROTOCOL;
+
+//
+// Protocol definitions
+//
+typedef enum {
+  ActiveBiosStateSpi,
+  ActiveBiosStatePci,
+  ActiveBiosStateLpc,
+  ActiveBiosStateMax
+} EFI_ACTIVE_BIOS_STATE;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ACTIVE_BIOS_SET_ACTIVE_BIOS_STATE) (
+  IN EFI_ACTIVE_BIOS_PROTOCOL     *This,
+  IN EFI_ACTIVE_BIOS_STATE        DesiredState,
+  IN UINTN                        Key
+  );
+/*++
+
+Routine Description:
+
+  Change the current active BIOS settings to the requested state.
+  The caller is responsible for requesting a supported state from
+  the EFI_ACTIVE_BIOS_STATE selections.
+
+  This will fail if someone has locked the interface and the correct key is
+  not provided.
+
+Arguments:
+
+  This                    Pointer to the EFI_ACTIVE_BIOS_PROTOCOL instance.
+  DesiredState            The requested state to configure the system for.
+  Key                     If the interface is locked, Key must be the Key
+                          returned from the LockState function call.
+
+Returns:
+
+  EFI_SUCCESS             Command succeed.
+  EFI_ACCESS_DENIED       The interface is currently locked.
+  EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+
+--*/
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ACTIVE_BIOS_LOCK_ACTIVE_BIOS_STATE) (
+  IN     EFI_ACTIVE_BIOS_PROTOCOL   *This,
+  IN     BOOLEAN                    Lock,
+  IN OUT UINTN                      *Key
+  );
+/*++
+
+Routine Description:
+
+  Lock the current active BIOS state from further changes.  This allows a
+  caller to implement a critical section.  This is optionally supported
+  functionality.  Size conscious implementations may choose to require
+  callers cooperate without support from this protocol.
+
+Arguments:
+
+  This                    Pointer to the EFI_ACTIVE_BIOS_PROTOCOL instance.
+  Lock                    TRUE to lock the current state, FALSE to unlock.
+  Key                     If Lock is TRUE, then a key will be returned.  If
+                          Lock is FALSE, the key returned from the prior call
+                          to lock the protocol must be provided to unlock the
+                          protocol.  The value of Key is undefined except that it
+                          will never be 0.
+
+Returns:
+
+  EFI_SUCCESS             Command succeed.
+  EFI_UNSUPPORTED         The function is not supported.
+  EFI_ACCESS_DENIED       The interface is currently locked.
+  EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+
+--*/
+
+//
+// Protocol definition
+//
+// Note that some functions are optional.  This means that they may be NULL.
+// Caller is required to verify that an optional function is defined by checking
+// that the value is not NULL.
+//
+struct _EFI_ACTIVE_BIOS_PROTOCOL {
+  EFI_ACTIVE_BIOS_STATE                       State;
+  EFI_ACTIVE_BIOS_SET_ACTIVE_BIOS_STATE       SetState;
+  EFI_ACTIVE_BIOS_LOCK_ACTIVE_BIOS_STATE      LockState;
+};
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gEfiActiveBiosProtocolGuid;
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/DxePchPolicyUpdateProtocol.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/DxePchPolicyUpdateProtocol.h
new file mode 100644
index 0000000000..4e7140e868
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/DxePchPolicyUpdateProtocol.h
@@ -0,0 +1,51 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  DxePchPolicyUpdateProtocol.h
+
+Abstract:
+
+  PCH policy update protocol. This protocol is consumed by the PchDxePolicyInit driver
+
+--*/
+#ifndef _DXE_PCH_POLICY_UPDATE_PROTOCOL_H_
+#define _DXE_PCH_POLICY_UPDATE_PROTOCOL_H_
+
+#include "PchRegs.h"
+
+
+#ifdef ECP_FLAG
+#define DXE_PCH_POLICY_UPDATE_PROTOCOL_GUID \
+  { \
+    0x1a819e49, 0xd8ee, 0x48cb, 0x9a, 0x9c, 0xa, 0xa0, 0xd2, 0x81, 0xa, 0x38 \
+  }
+#else
+#define DXE_PCH_POLICY_UPDATE_PROTOCOL_GUID \
+  { \
+    0x1a819e49, 0xd8ee, 0x48cb, \
+    { \
+        0x9a, 0x9c, 0xa, 0xa0, 0xd2, 0x81, 0xa, 0x38 \
+    } \
+  }
+#endif
+
+extern EFI_GUID                                   gDxePchPolicyUpdateProtocolGuid;
+#define DXE_PCH_POLICY_UPDATE_PROTOCOL_REVISION_1 1
+
+//
+// ------------ General PCH policy Update protocol definition ------------
+//
+struct _DXE_PCH_POLICY_UPDATE_PROTOCOL {
+  UINT8                   Revision;
+};
+
+typedef struct _DXE_PCH_POLICY_UPDATE_PROTOCOL  DXE_PCH_POLICY_UPDATE_PROTOCOL;
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/EmmcCardInfoProtocol.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/EmmcCardInfoProtocol.h
new file mode 100644
index 0000000000..d92f227d5b
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/EmmcCardInfoProtocol.h
@@ -0,0 +1,42 @@
+/*++
+
+Copyright (c)  2013  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+--*/
+
+
+/*++
+Module Name:
+
+  EmmcCardInfoProtocol.h
+
+Abstract:
+
+  Interface definition for EFI_EMMC_CARD_INFO_PROTOCOL
+
+--*/
+
+
+#ifndef _EMMC_CARD_INFO_H_
+#define _EMMC_CARD_INFO_H_
+
+#define EFI_EMMC_CARD_INFO_PROTOCOL_GUID \
+  { \
+    0x1ebe5ab9, 0x2129, 0x49e7, {0x84, 0xd7, 0xee, 0xb9, 0xfc, 0xe5, 0xde, 0xdd } \
+  }
+
+typedef struct _EFI_EMMC_CARD_INFO_PROTOCOL  EFI_EMMC_CARD_INFO_PROTOCOL;
+
+
+//
+// EMMC Card info Structures
+//
+struct _EFI_EMMC_CARD_INFO_PROTOCOL {
+  CARD_DATA *CardData;
+};
+
+extern EFI_GUID gEfiEmmcCardInfoProtocolGuid;
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/Gpio.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/Gpio.h
new file mode 100644
index 0000000000..3f7260e0bf
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/Gpio.h
@@ -0,0 +1,161 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  Gpio.h
+
+Abstract:
+
+EFI 2.0 PEIM to provide platform specific information to other
+modules and to do some platform specific initialization.
+
+--*/
+
+#ifndef _PEI_GPIO_H
+#define _PEI_GPIO_H
+
+//#include "Efi.h"
+//#include "EfiCommonLib.h"
+//#include "Pei.h"
+//#include "Numbers.h"
+
+////
+//// GPIO Register Settings for BeaverBridge (FFVS) (Cedarview/Tigerpoint)
+////
+//// Field Descriptions:
+////    USE: Defines the pin's usage model:  GPIO (G) or Native (N) mode.
+////    I/O: Defines whether GPIOs are inputs (I) or outputs (O).
+////         (Note:  Only meaningful for pins used as GPIOs.)
+////    LVL: This field gives you the initial value for "output" GPIO's.
+////         (Note: The output level is dependent upon whether the pin is inverted.)
+////    INV: Defines whether Input GPIOs activation level is inverted.
+////         (Note:  Only affects the level sent to the GPE logic and does not
+////         affect the level read through the GPIO registers.)
+////
+//// Notes:
+////    1. BoardID is GPIO [8:38:34]
+////
+////Signal         UsedAs               USE     I/O      LVL     INV
+////--------------------------------------------------------------------------
+////GPIO0           Nonfunction       G     O            H       -
+////GPIO1           SMC_RUNTIME_SCI#    G        I           -       I
+////PIRQE#/GPIO2    Nonfunction G   O   H   -
+////PIRQF#/GPIO3    Nonfunction G   O   H   -
+////PIRQG#/GPIO4    Nonfunction G   O   H   -
+////PIRQH#/GPIO5    Nonfunction G   O   H   -
+////GPIO6   unused  G   O   L   -
+////GPIO7   unused  G   O   L   -
+////GPIO8          BOARD ID2    G   I   -   -
+////GPIO9   unused  G   O   L   -
+////GPIO10  SMC_EXTSMI# G   I   -   I
+////GPIO11  Nonfunction G   O   H   -
+////GPIO12  unused  G   O   L   -
+////GPIO13  SMC_WAKE_SCI#   G   I   -   I
+////GPIO14  unused  G   O   L   -
+////GPIO15  unused  G   O   L   -
+////GPIO16  PM_DPRSLPVR N   -   -   -
+////GNT5#/GPIO17    GNT5#   N   -   -   -
+////STPPCI#/GPIO18  PM_STPPCI#  N   -   -   -
+////STPCPU#/GPIO20  PM_STPCPU#  N   -   -   -
+////GPIO22  CRT_RefClk  G   I   -   -
+////GPIO23  unused  G   O   L   -
+////GPIO24  unused  G   O   L   -
+////GPIO25  DMI strap   G   O   L   -
+////GPIO26  unused  G   O   L   -
+////GPIO27  unused  G   O   L   -
+////GPIO28  RF_KILL#    G   O   H   -
+////OC5#/GPIO29 OC  N   -   -   -
+////OC6#/GPIO30 OC  N   -   -   -
+////OC7#/GPIO31 OC  N   -   -   -
+////CLKRUN#/GPIO32  PM_CLKRUN#  N   -   -   -
+////GPIO33  NC  G   O   L   -
+////GPIO34  BOARD ID0   G   I   -   -
+////GPIO36  unused  G   O   L   -
+////GPIO38  BOARD ID1   G   I   -   -
+////GPIO39  unused  G   O   L   -
+////GPIO48  unused  G   O   L   -
+////CPUPWRGD/GPIO49 H_PWRGD N   -   -   -
+//
+//#define   GPIO_USE_SEL_VAL              0x1FC0FFFF       //GPIO1, 10, 13 is EC signal
+//#define   GPIO_USE_SEL2_VAL             0x000100D6
+//#define   GPIO_IO_SEL_VAL               0x00402502
+//#define   GPIO_IO_SEL2_VAL              0x00000044
+//#define   GPIO_LVL_VAL                  0x1800083D
+//#define   GPIO_LVL2_VAL                 0x00000000
+//#define   GPIO_INV_VAL                  0x00002402
+//#define   GPIO_BLNK_VAL                 0x00000000
+//#define   ICH_GPI_ROUTE (ICH_GPI_ROUTE_SCI(13) | ICH_GPI_ROUTE_SCI(1))
+
+//
+// GPIO Register Settings for CedarRock and CedarFalls platforms
+//
+//      GPIO Register Settings for NB10_CRB
+//---------------------------------------------------------------------------------
+//Signal        Used As         USE         I/O     LVL
+//---------------------------------------------------------------------------------
+//
+// GPIO0    FP_AUDIO_DETECT     G       I
+// GPIO1    SMC_RUNTIME_SCI#    G       I
+// GPIO2        INT_PIRQE_N     N       I
+// GPIO3    INT_PIRQF_N     N       I
+// GPIO4        INT_PIRQG_N     N       I
+// GPIO5        INT_PIRQH_N     N       I
+// GPIO6
+// GPIO7
+// GPIO8
+// GPIO9    LPC_SIO_PME     G       I
+// GPIO10   SMC_EXTSMI_N        G       I
+// GPIO11   SMBALERT- pullup    N
+// GPIO12   ICH_GP12        G       I
+// GPIO13   SMC_WAKE_SCI_N      G       I
+// GPIO14   LCD_PID0        G       O       H
+// GPIO15   CONFIG_MODE_N       G       I
+// GPIO16       PM_DPRSLPVR     N
+// GPIO17   SPI_SELECT_STRAP1
+//          /L_BKLTSEL0_N   G       I
+// GPIO18   PM_STPPCI_N     N
+// GPIO19
+// GPIO20   PM_STPCPU_N     N
+// GPIO21
+// GPIO22   REQ4B           G       I
+// GPIO23   L_DRQ1_N        N
+// GPIO24   CRB_SV_DET_N        G       O       H
+// GPIO25   DMI strap
+//          / L_BKLTSEL1_N  G       O       H
+// GPIO26   LCD_PID1        G       O       H
+// GPIO27   TPEV_DDR3L_DETECT   G       O       H
+// GPIO28   RF_KILL         G       O       H:enable
+// GPIO29   OC          N
+// GPIO30   OC          N
+// GPIO31   OC          N
+// GPIO32   PM_CLKRUN_N     Native
+// GPIO33   MFG_MODE_N      G       I
+// GPIO34   BOARD ID0       G       I
+// GPIO35
+// GPIO36   SV_SET_UP       G       O       H
+// GPIO37
+// GPIO38   BOARD ID1       G       I
+// GPIO39   BOARD ID2       G       I
+// GPIO48   FLASH_SEL0      N
+// GPIO49   H_PWRGD         N
+
+#define ICH_GPI_ROUTE_SMI(Gpio)          ((( 0 << ((Gpio * 2) + 1)) | (1 << (Gpio * 2))))
+#define ICH_GPI_ROUTE_SCI(Gpio)          ((( 1 << ((Gpio * 2) + 1)) | (0 << (Gpio * 2))))
+
+#define   GPIO_USE_SEL_VAL              0X1F42F7C3
+#define   GPIO_USE_SEL2_VAL             0X000000D6
+#define   GPIO_IO_SEL_VAL               0X1042B73F
+#define   GPIO_IO_SEL2_VAL              0X000100C6
+#define   GPIO_LVL_VAL                  0X1F15F601
+#define   GPIO_LVL2_VAL                 0X000200D7
+#define   GPIO_INV_VAL                  0x00002602
+#define   GPIO_BLNK_VAL                 0x00040000
+#define   ICH_GPI_ROUTE (ICH_GPI_ROUTE_SCI(13) | ICH_GPI_ROUTE_SCI(1))
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/HwWatchdogTimer.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/HwWatchdogTimer.h
new file mode 100644
index 0000000000..592ac285ea
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/HwWatchdogTimer.h
@@ -0,0 +1,294 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  HwWatchdogTimer.h
+
+Abstract:
+
+
+--*/
+
+#ifndef __EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL_H__
+#define __EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL_H__
+
+#define EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL_GUID \
+  { 0xd5b06d16, 0x2ea1, 0x4def, 0x98, 0xd0, 0xa0, 0x5d, 0x40, 0x72, 0x84, 0x17 }
+
+#define EFI_WATCHDOG_TIMER_NOT_SUPPORTED_PROTOCOL_GUID \
+  { 0xe9e156ac, 0x3203, 0x4572, 0xac, 0xdf, 0x84, 0x4f, 0xdc, 0xdb, 0x6, 0xbf }
+
+
+#include <Guid/HwWatchdogTimerHob.h>
+
+//
+// General Purpose Constants
+//
+#define ICH_INSTAFLUSH_GPIO      BIT16 // BIT 16 in GPIO Level 2 is GPIO 48.
+#define B_INSTAFLUSH             BIT4
+//
+// Other Watchdog timer values
+//
+#define WDT_COUNTDOWN_VALUE                 0x14
+#define BDS_WDT_COUNTDOWN_VALUE             0x35
+
+
+//
+// Prototypes for the Watchdog Timer Driver Protocol
+//
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_WATCHDOG_START_TIMER) (
+  VOID
+  );
+/*++
+
+  Routine Description:
+    This service begins the Watchdog Timer countdown.  If the countdown completes prior to
+    Stop Timer or Restart Timer the system will reset.
+
+  Arguments:
+    None
+
+  Returns:
+    EFI_SUCCESS       - Operation completed successfully
+    EFI_DEVICE_ERROR  - The command was unsuccessful
+
+--*/
+
+
+
+typedef
+EFI_STATUS
+(EFIAPI *PEI_WATCHDOG_RESET_TIMER) (
+  VOID
+  );
+/*++
+
+  Routine Description:
+    This service resets the Watchdog Timer countdown and should only be called after the
+    Start Timer function.
+
+  Arguments:
+    None
+
+  Returns:
+    EFI_SUCCESS       - Operation completed successfully
+    EFI_DEVICE_ERROR  - The command was unsuccessful
+
+--*/
+
+
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_WATCHDOG_RESTART_TIMER) (
+  VOID
+  );
+/*++
+
+  Routine Description:
+    This service restarts the Watchdog Timer countdown and should only be called after the
+    Start Timer function.
+
+  Arguments:
+    None
+
+  Returns:
+    EFI_SUCCESS       - Operation completed successfully
+    EFI_DEVICE_ERROR  - The command was unsuccessful
+
+--*/
+
+
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_WATCHDOG_STOP_TIMER) (
+  VOID
+  );
+/*++
+
+  Routine Description:
+    This service disables the Watchdog Timer countdown.
+
+  Arguments:
+    None
+
+  Returns:
+    EFI_SUCCESS       - Operation completed successfully
+    EFI_DEVICE_ERROR  - The command was unsuccessful
+
+--*/
+
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_WATCHDOG_CHECK_TIMEOUT) (
+  OUT HW_WATCHDOG_TIMEOUT       *WatchdogTimeout
+  );
+/*++
+
+  Routine Description:
+    This service disables the Watchdog Timer countdown.
+
+  Arguments:
+    None
+
+  Returns:
+    EFI_SUCCESS       - Operation completed successfully
+    EFI_DEVICE_ERROR  - The command was unsuccessful
+
+--*/
+
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_WATCHDOG_FORCE_REBOOT) (
+  IN BOOLEAN                    ForceTimeout,
+  IN UINT8                      ResetType
+  );
+/*++
+
+  Routine Description:
+    This service forces a reboot of the system due to a reset of the POWERGOOD_PS,
+    POWERGOOD_CLK, and the BSEL Override
+
+  Arguments:
+    None
+
+  Returns:
+    This function should not return!
+
+    EFI_DEVICE_ERROR  - The command was unsuccessful and a reboot did not occur
+
+--*/
+
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_WATCHDOG_KNOWN_RESET) (
+  IN BOOLEAN                    AllowReset
+  );
+/*++
+
+  Routine Description:
+    This service notifies the Watchdog Timer of the fact that a known reset is occuring.
+
+  Arguments:
+    AllowReset -  TRUE if a Reset is currently expected
+                  FALSE if a Reset is not currently expected
+
+  Returns:
+    This function should not return!
+
+    EFI_DEVICE_ERROR  - The command was unsuccessful and a reboot did not occur
+
+--*/
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_TIMER_COUNT_DOWN_PERIOD)(
+  OUT UINT32      *CountdownValue
+  );
+/*++
+
+  Routine Description:
+    This service reads the current Watchdog Timer countdown reload value.
+
+  Arguments:
+    CountdownValue - pointer to UINT32 to return the value of the reload register.
+
+  Returns:
+    EFI_SUCCESS       - Operation completed successfully
+    EFI_DEVICE_ERROR  - The command was unsuccessful
+
+--*/
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_TIMER_COUNT_DOWN_PERIOD)(
+  OUT UINT32      CountdownValue
+  );
+/*++
+
+  Routine Description:
+    This service reads the current Watchdog Timer countdown reload value.
+
+  Arguments:
+    CountdownValue - Value to set the reload register.
+
+  Returns:
+    EFI_SUCCESS       - Operation completed successfully
+    EFI_DEVICE_ERROR  - The command was unsuccessful
+
+--*/
+
+typedef
+EFI_STATUS
+(EFIAPI *PEI_WATCHDOG_CLEAR_TIMER_STATE) (
+  );
+/*++
+
+  Routine Description:
+    This service clears the state that indicates the Watchdog Timer fired.
+
+  Arguments:
+
+  Returns:
+    EFI_SUCCESS       - Operation completed successfully
+    EFI_DEVICE_ERROR  - The command was unsuccessful
+
+--*/
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_STALL_WATCHDOG_COUNTDOWN) (
+  IN BOOLEAN Stall
+  );
+/*++
+
+  Routine Description:
+    This service disables the Watchdog Timer countdown.  It also closes the recurring restart event
+    if the event exists.
+
+  Arguments:
+    Stall - TRUE = Stop the timer countdown
+            FALSE = Start the timer countdown
+
+  Returns:
+    EFI_SUCCESS       - Operation completed successfully
+    EFI_DEVICE_ERROR  - The command was unsuccessful
+
+--*/
+
+typedef struct _EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL {
+  EFI_WATCHDOG_START_TIMER                      StartWatchdogTimer;
+  PEI_WATCHDOG_RESET_TIMER                      ResetWatchdogTimeout;
+  EFI_WATCHDOG_RESTART_TIMER                    RestartWatchdogTimer;
+  EFI_WATCHDOG_STOP_TIMER                       StopWatchdogTimer;
+  EFI_WATCHDOG_CHECK_TIMEOUT                    CheckWatchdogTimeout;
+  EFI_WATCHDOG_FORCE_REBOOT                     ForceReboot;
+  EFI_WATCHDOG_KNOWN_RESET                      AllowKnownReset;
+  EFI_GET_TIMER_COUNT_DOWN_PERIOD               GetCountdownPeriod;
+  EFI_SET_TIMER_COUNT_DOWN_PERIOD               SetCountdownPeriod;
+  PEI_WATCHDOG_CLEAR_TIMER_STATE                ClearTimerState;
+  EFI_STALL_WATCHDOG_COUNTDOWN                  StallWatchdogCountdown;
+} EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL;
+
+extern EFI_GUID gEfiWatchdogTimerDriverProtocolGuid;
+extern EFI_GUID gEfiWatchdogTimerNotSupportedProtocolGuid;
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/I2cBus.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/I2cBus.h
new file mode 100644
index 0000000000..0fccaa0786
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/I2cBus.h
@@ -0,0 +1,164 @@
+/** @file
+  I2C bus interface
+
+  This layer provides I/O access to an I2C device.
+
+  Copyright (c) 2012, Intel Corporation. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __I2C_BUS_H__
+#define __I2C_BUS_H__
+
+#include <Protocol/I2cHostMcg.h>
+
+///
+/// I2C bus protocol
+///
+typedef struct _EFI_I2C_BUS_PROTOCOL  EFI_I2C_BUS_PROTOCOL;
+
+
+/**
+  Perform an I2C operation on the device
+
+  This routine must be called at or below TPL_NOTIFY.  For synchronous
+  requests this routine must be called at or below TPL_CALLBACK.
+
+  N.B. The typical consumers of this API are the third party I2C
+  drivers.  Extreme care must be taken by other consumers of this
+  API to prevent confusing the third party I2C drivers due to a
+  state change at the I2C device which the third party I2C drivers
+  did not initiate.  I2C platform drivers may use this API within
+  these guidelines.
+
+  This routine queues an operation to the I2C controller for execution
+  on the I2C bus.
+
+  As an upper layer driver writer, the following need to be provided
+  to the platform vendor:
+
+  1.  ACPI CID value or string - this is used to connect the upper layer
+      driver to the device.
+  2.  Slave address array guidance when the I2C device uses more than one
+      slave address.  This is used to access the blocks of hardware within
+      the I2C device.
+
+  @param[in] This               Address of an EFI_I2C_BUS_PROTOCOL
+                                structure
+  @param[in] SlaveAddressIndex  Index into an array of slave addresses for
+                                the I2C device.  The values in the array are
+                                specified by the board designer, with the
+                                I2C device driver writer providing the slave
+                                address order.
+
+                                For devices that have a single slave address,
+                                this value must be zero.  If the I2C device
+                                uses more than one slave address then the third
+                                party (upper level) I2C driver writer needs to
+                                specify the order of entries in the slave address
+                                array.
+
+                                \ref ThirdPartyI2cDrivers "Third Party I2C Drivers"
+                                section in I2cMaster.h.
+  @param[in] Event              Event to set for asynchronous operations,
+                                NULL for synchronous operations
+  @param[in] RequestPacket      Address of an EFI_I2C_REQUEST_PACKET
+                                structure describing the I2C operation
+  @param[out] I2cStatus         Optional buffer to receive the I2C operation
+                                completion status
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_ABORTED           The request did not complete because the driver
+                                was shutdown.
+  @retval EFI_ACCESS_DENIED     Invalid SlaveAddressIndex value
+  @retval EFI_BAD_BUFFER_SIZE   The WriteBytes or ReadBytes buffer size is too large.
+  @retval EFI_DEVICE_ERROR      There was an I2C error (NACK) during the operation.
+                                This could indicate the slave device is not present.
+  @retval EFI_INVALID_PARAMETER RequestPacket is NULL
+  @retval EFI_INVALID_PARAMETER TPL is too high
+  @retval EFI_NO_RESPONSE       The I2C device is not responding to the
+                                slave address.  EFI_DEVICE_ERROR may also be
+                                returned if the controller can not distinguish
+                                when the NACK occurred.
+  @retval EFI_NOT_FOUND         I2C slave address exceeds maximum address
+  @retval EFI_NOT_READY         I2C bus is busy or operation pending, wait for
+                                the event and then read status pointed to by
+                                the request packet.
+  @retval EFI_OUT_OF_RESOURCES  Insufficient memory for I2C operation
+  @retval EFI_TIMEOUT           The transaction did not complete within an internally
+                                specified timeout period.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_I2C_BUS_START_REQUEST) (
+  IN CONST EFI_I2C_BUS_PROTOCOL *This,
+  IN UINTN SlaveAddressIndex,
+  IN EFI_EVENT Event OPTIONAL,
+  IN CONST EFI_I2C_REQUEST_PACKET *RequestPacket,
+  OUT EFI_STATUS *I2cStatus OPTIONAL
+  );
+
+///
+/// The I2C bus protocol enables access to a specific device on the I2C bus.
+///
+/// Each I2C device is described as an ACPI node (HID, UID and CID) within the
+/// platform layer.  The I2C bus protocol enumerates the I2C devices in the
+/// platform and creates a unique handle and device path for each I2C device.
+///
+/// I2C slave addressing is abstracted to validate addresses and limit operation
+/// to the specified I2C device.  The third party providing the I2C device support
+/// provides an ordered list of slave addresses for the I2C device to the team
+/// building the platform layer.  The platform team must preserve the order of the
+/// supplied list.  SlaveAddressCount is the number of entries in this list or
+/// array within the platform layer.  The third party device support references
+/// a slave address using an index into the list or array in the range of zero
+/// to SlaveAddressCount - 1.
+///
+struct _EFI_I2C_BUS_PROTOCOL {
+  ///
+  /// Start an I2C operation on the bus
+  ///
+  EFI_I2C_BUS_START_REQUEST StartRequest;
+
+  ///
+  /// The maximum number of slave addresses for the I2C device.  The caller may
+  /// validate this value as a check on the platform layer's configuration.  Slave
+  /// address selection uses an index value in the range of zero to SlaveAddressCount - 1.
+  ///
+  UINTN SlaveAddressCount;
+
+  ///
+  /// Hardware revision - Matches the ACPI _HRV value
+  ///
+  /// The HardwareRevision value allows a single driver to support multiple hardware
+  /// revisions and implement the necessary workarounds for limitations within the
+  /// hardware.
+  ///
+  UINT32 HardwareRevision;
+
+  ///
+  /// The maximum number of bytes the I2C host controller
+  /// is able to receive from the I2C bus.
+  ///
+  UINT32 MaximumReceiveBytes;
+
+  ///
+  /// The maximum number of bytes the I2C host controller
+  /// is able to send on the I2C bus.
+  ///
+  UINT32 MaximumTransmitBytes;
+
+  ///
+  /// The maximum number of bytes in the I2C bus transaction.
+  ///
+  UINT32 MaximumTotalBytes;
+};
+
+///
+/// GUID for the I2C bus protocol
+///
+extern EFI_GUID gEfiI2cBusProtocolGuid;
+
+#endif  //  __I2C_BUS_H__
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchExtendedReset.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchExtendedReset.h
new file mode 100644
index 0000000000..ef7975b033
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchExtendedReset.h
@@ -0,0 +1,84 @@
+/*++
+
+Copyright (c) 2008  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  PchExtendedReset.h
+
+Abstract:
+
+  PCH Extended Reset Protocol
+
+--*/
+#ifndef _EFI_PCH_EXTENDED_RESET_H_
+#define _EFI_PCH_EXTENDED_RESET_H_
+
+
+
+//
+#define EFI_PCH_EXTENDED_RESET_PROTOCOL_GUID \
+  { \
+    0xf0bbfca0, 0x684e, 0x48b3, 0xba, 0xe2, 0x6c, 0x84, 0xb8, 0x9e, 0x53, 0x39 \
+  }
+extern EFI_GUID                                 gEfiPchExtendedResetProtocolGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _EFI_PCH_EXTENDED_RESET_PROTOCOL EFI_PCH_EXTENDED_RESET_PROTOCOL;
+
+//
+// Related Definitions
+//
+//
+// PCH Extended Reset Types
+//
+typedef struct {
+  UINT8 PowerCycle  : 1;  // 0: Disabled*; 1: Enabled
+  UINT8 GlobalReset : 1;  // 0: Disabled*; 1: Enabled
+  UINT8 SusPwrDnAck : 1;  // 0: Do Nothing;
+  // 1: GPIO[30](SUS_PWR_DN_ACK) level is set low prior to Global Reset(for systems with an embedded controller)
+  UINT8 RsvdBits : 5;     // Reserved fields for future expansion w/o protocol change
+} PCH_EXTENDED_RESET_TYPES;
+
+//
+// Member functions
+//
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PCH_EXTENDED_RESET) (
+  IN     EFI_PCH_EXTENDED_RESET_PROTOCOL   * This,
+  IN     PCH_EXTENDED_RESET_TYPES          PchExtendedResetTypes
+  );
+
+/*++
+
+Routine Description:
+
+  Execute Pch Extended Reset from the host controller.
+
+Arguments:
+
+  This                    - Pointer to the EFI_PCH_EXTENDED_RESET_PROTOCOL instance.
+  PchExtendedResetTypes   - Pch Extended Reset Types which includes PowerCycle, Globalreset.
+
+Returns:
+
+  Does not return if the reset takes place.
+  EFI_INVALID_PARAMETER   - If ResetType is invalid.
+
+--*/
+
+//
+// Interface structure for the Pch Extended Reset Protocol
+//
+struct _EFI_PCH_EXTENDED_RESET_PROTOCOL {
+  EFI_PCH_EXTENDED_RESET  Reset;
+};
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchInfo.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchInfo.h
new file mode 100644
index 0000000000..22e25c27fa
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchInfo.h
@@ -0,0 +1,60 @@
+/**
+**/
+/**
+
+Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+  @file
+  PchInfo.h
+
+  @brief
+  This file defines the PCH Info Protocol.
+
+**/
+#ifndef _PCH_INFO_H_
+#define _PCH_INFO_H_
+
+
+#define EFI_PCH_INFO_PROTOCOL_GUID \
+  { \
+    0xd31f0400, 0x7d16, 0x4316, 0xbf, 0x88, 0x60, 0x65, 0x88, 0x3b, 0x40, 0x2b \
+  }
+extern EFI_GUID                       gEfiPchInfoProtocolGuid;
+
+///
+/// Forward reference for ANSI C compatibility
+///
+typedef struct _EFI_PCH_INFO_PROTOCOL EFI_PCH_INFO_PROTOCOL;
+
+///
+/// Protocol revision number
+/// Any backwards compatible changes to this protocol will result in an update in the revision number
+/// Major changes will require publication of a new protocol
+///
+/// Revision 1:  Original version
+///
+#define PCH_INFO_PROTOCOL_REVISION_1  1
+#define PCH_INFO_PROTOCOL_REVISION_2  2
+
+///
+/// RCVersion[7:0] is the release number.
+/// For example:
+/// VlvFramework 0.6.0-01 should be 00 06 00 01 (0x00060001)
+/// VlvFramework 0.6.2    should be 00 06 02 00 (0x00060200)
+///
+#define PCH_RC_VERSION                0x01000000
+
+///
+/// Protocol definition
+///
+struct _EFI_PCH_INFO_PROTOCOL {
+  UINT8   Revision;
+  UINT8   BusNumber;
+  UINT32  RCVersion;
+};
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchPlatformPolicy.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchPlatformPolicy.h
new file mode 100644
index 0000000000..79845d646d
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchPlatformPolicy.h
@@ -0,0 +1,550 @@
+/**
+**/
+/**
+
+Copyright (c) 2013  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+  @file
+  PchPlatformPolicy.h
+
+  @brief
+  PCH policy protocol produced by a platform driver specifying various
+  expected PCH settings. This protocol is consumed by the PCH drivers.
+
+**/
+#ifndef _PCH_PLATFORM_POLICY_H_
+#define _PCH_PLATFORM_POLICY_H_
+
+
+//
+#include "PchRegs.h"
+#ifndef ECP_FLAG
+#include "Uefi.h"
+#endif
+
+#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_GUID \
+  { \
+    0x4b0165a9, 0x61d6, 0x4e23, 0xa0, 0xb5, 0x3e, 0xc7, 0x9c, 0x2e, 0x30, 0xd5 \
+  }
+extern EFI_GUID                                   gDxePchPlatformPolicyProtocolGuid;
+
+///
+/// Forward reference for ANSI C compatibility
+///
+typedef struct _DXE_PCH_PLATFORM_POLICY_PROTOCOL  DXE_PCH_PLATFORM_POLICY_PROTOCOL;
+
+///
+/// Protocol revision number
+/// Any backwards compatible changes to this protocol will result in an update in the revision number
+/// Major changes will require publication of a new protocol
+///
+/// Revision 1: Original version
+///
+#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_1 1
+#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_2 2
+#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_3 3
+#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_4 4
+#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_5 5
+#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_6 6
+#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_7 7
+#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_8 8
+#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_9 9
+#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_10 10
+#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_11 11
+#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_12 12
+
+///
+/// Generic definitions for device enabling/disabling used by PCH code.
+///
+#define PCH_DEVICE_ENABLE   1
+#define PCH_DEVICE_DISABLE  0
+
+///
+/// ---------------------------- Device Enabling ------------------------------
+///
+/// PCH Device enablings
+///
+typedef struct {
+  UINT8 Lan               : 1;    /// 0: Disable; 1: Enable
+  UINT8 Azalia            : 2;    /// 0: Disable; 1: Enable; 2: Auto
+  UINT8 Sata              : 1;    /// 0: Disable; 1: Enable
+  UINT8 Smbus             : 1;    /// 0: Disable; 1: Enable
+  UINT8 LpeEnabled        : 2;    /// 0: Disabled; 1: PCI Mode 2: ACPI Mode
+  UINT8 Reserved[1];              /// Reserved fields for future expansion w/o protocol change
+} PCH_DEVICE_ENABLING;
+
+///
+/// ---------------------------- USB Config -----------------------------
+///
+///
+/// Overcurrent pins
+///
+typedef enum {
+  PchUsbOverCurrentPin0 = 0,
+  PchUsbOverCurrentPin1,
+  PchUsbOverCurrentPin2,
+  PchUsbOverCurrentPin3,
+  PchUsbOverCurrentPin4,
+  PchUsbOverCurrentPin5,
+  PchUsbOverCurrentPin6,
+  PchUsbOverCurrentPin7,
+  PchUsbOverCurrentPinSkip,
+  PchUsbOverCurrentPinMax
+} PCH_USB_OVERCURRENT_PIN;
+
+typedef struct {
+  UINT8   Enable            : 1;    /// 0: Disable; 1: Enable. This would take effect while UsbPerPortCtl is enabled
+  UINT8   Panel             : 1;    /// 0: Back Panel Port; 1: Front Panel Port.
+  UINT8   Dock              : 1;    /// 0: Not docking port; 1: Docking Port.
+  UINT8   Rsvdbits          : 5;
+} PCH_USB_PORT_SETTINGS;
+
+typedef struct {
+  UINT8 Enable              : 1;    /// 0: Disable; 1: Enable
+  UINT8 Rsvdbits            : 7;
+} PCH_USB20_CONTROLLER_SETTINGS;
+
+typedef struct {
+  UINT8 Enable              : 2;    /// 0: 0: Disabled; 1: PCI Mode 2: ACPI Mode
+  UINT8 Rsvdbits            : 6;
+} PCH_USBOTG_CONTROLLER_SETTINGS;
+
+#define PCH_XHCI_MODE_OFF         0
+#define PCH_XHCI_MODE_ON          1
+#define PCH_XHCI_MODE_AUTO        2
+#define PCH_XHCI_MODE_SMARTAUTO   3
+
+#define PCH_EHCI_DEBUG_OFF        0
+#define PCH_EHCI_DEBUG_ON         1
+
+#define PCH_USB_FRONT_PANEL       1
+#define PCH_USB_BACK_PANEL        0
+
+typedef struct {
+  UINT8 Mode               : 2;    /// 0: Disable; 1: Enable, 2: Auto, 3: Smart Auto
+  UINT8 PreBootSupport     : 1;    /// 0: No xHCI driver available; 1: xHCI driver available
+  UINT8 XhciStreams        : 1;    /// 0: Disable; 1: Enable
+  UINT8 Rsvdbits           : 4;
+} PCH_USB30_CONTROLLER_SETTINGS;
+
+typedef struct {
+  UINT8 UsbPerPortCtl       : 1;    /// 0: Disable; 1: Enable Per-port enable control
+  UINT8 Ehci1Usbr           : 1;    /// 0: Disable; 1: Enable EHCI 1 USBR
+  UINT8 RsvdBits            : 6;
+  PCH_USB_PORT_SETTINGS          PortSettings[PCH_USB_MAX_PHYSICAL_PORTS];
+  PCH_USB20_CONTROLLER_SETTINGS  Usb20Settings[PchEhciControllerMax];
+  PCH_USB30_CONTROLLER_SETTINGS  Usb30Settings;
+  PCH_USBOTG_CONTROLLER_SETTINGS UsbOtgSettings;
+  PCH_USB_OVERCURRENT_PIN        Usb20OverCurrentPins[PCH_USB_MAX_PHYSICAL_PORTS];
+  PCH_USB_OVERCURRENT_PIN        Usb30OverCurrentPins[PCH_XHCI_MAX_USB3_PORTS];
+  ///
+  /// The length of Usb Port to configure the USB transmitter,
+  /// Bits [16:4] represents length of Usb Port in inches using octal format and [3:0] is for the decimal Point.
+  ///
+  UINT16                        Usb20PortLength[PCH_EHCI_MAX_PORTS];
+  UINT16                        EhciDebug;
+  UINT16                        UsbXhciLpmSupport;
+
+} PCH_USB_CONFIG;
+
+///
+/// ---------------------------- PCI Express Config ----------------------
+///
+/// The values before AutoConfig match the setting of PCI Express Base Specification 1.1, please be careful for adding new feature
+///
+typedef enum {
+  PchPcieAspmDisabled,
+  PchPcieAspmL0s,
+  PchPcieAspmL1,
+  PchPcieAspmL0sL1,
+  PchPcieAspmAutoConfig,
+  PchPcieAspmMax
+} PCH_PCI_EXPRESS_ASPM_CONTROL;
+
+///
+/// Refer to PCH EDS for the PCH implementation values corresponding
+/// to below PCI-E spec defined ranges
+///
+typedef enum {
+  PchPciECompletionTO_Default,
+  PchPciECompletionTO_50_100us,
+  PchPciECompletionTO_1_10ms,
+  PchPciECompletionTO_16_55ms,
+  PchPciECompletionTO_65_210ms,
+  PchPciECompletionTO_260_900ms,
+  PchPciECompletionTO_1_3P5s,
+  PchPciECompletionTO_4_13s,
+  PchPciECompletionTO_17_64s,
+  PchPciECompletionTO_Disabled
+} PCH_PCIE_COMPLETION_TIMEOUT;
+
+typedef struct {
+  UINT8 Enable                          : 1;    /// Root Port enabling, 0: Disable; 1: Enable.
+  UINT8 Hide                            : 1;    /// Whether or not to hide the configuration space of this port
+  UINT8 SlotImplemented                 : 1;
+  UINT8 HotPlug                         : 1;
+  UINT8 PmSci                           : 1;
+  UINT8 ExtSync                         : 1;    /// Extended Synch
+  UINT8 Rsvdbits                        : 2;
+  ///
+  /// Error handlings
+  ///
+  UINT8 UnsupportedRequestReport        : 1;
+  UINT8 FatalErrorReport                : 1;
+  UINT8 NoFatalErrorReport              : 1;
+  UINT8 CorrectableErrorReport          : 1;
+  UINT8 PmeInterrupt                    : 1;
+  UINT8 SystemErrorOnFatalError         : 1;
+  UINT8 SystemErrorOnNonFatalError      : 1;
+  UINT8 SystemErrorOnCorrectableError   : 1;
+
+  UINT8 AdvancedErrorReporting          : 1;
+  UINT8 TransmitterHalfSwing            : 1;
+  UINT8 Reserved                        : 6;    /// Reserved fields for future expansion w/o protocol change
+
+  UINT8 FunctionNumber;                         /// The function number this root port is mapped to.
+  UINT8 PhysicalSlotNumber;
+  PCH_PCIE_COMPLETION_TIMEOUT   CompletionTimeout;
+  PCH_PCI_EXPRESS_ASPM_CONTROL  Aspm;
+} PCH_PCI_EXPRESS_ROOT_PORT_CONFIG;
+
+typedef struct {
+  /**
+    VendorId
+
+      The vendor Id of Pci Express card ASPM setting override, 0xFFFF means any Vendor ID
+
+    DeviceId
+
+      The Device Id of Pci Express card ASPM setting override, 0xFFFF means any Device ID
+
+    RevId
+
+      The Rev Id of Pci Express card ASPM setting override, 0xFF means all steppings
+
+    BaseClassCode
+
+      The Base Class Code of Pci Express card ASPM setting override, 0xFF means all base class
+
+    SubClassCode
+
+      The Sub Class Code of Pci Express card ASPM setting override, 0xFF means all sub class
+
+
+    EndPointAspm
+
+      The override ASPM setting from End point
+  **/
+  UINT16                        VendorId;
+  UINT16                        DeviceId;
+  UINT8                         RevId;
+  UINT8                         BaseClassCode;
+  UINT8                         SubClassCode;
+  PCH_PCI_EXPRESS_ASPM_CONTROL  EndPointAspm;
+} PCH_PCIE_DEVICE_ASPM_OVERRIDE;
+
+typedef struct {
+  UINT16  VendorId; ///< PCI configuration space offset 0
+  UINT16  DeviceId; ///< PCI configuration space offset 2
+  UINT8   RevId;    ///< PCI configuration space offset 8; 0xFF means all steppings
+  /**
+    SnoopLatency bit definition
+    Note: All Reserved bits must be set to 0
+
+    BIT[15]     - When set to 1b, indicates that the values in bits 9:0 are valid
+                  When clear values in bits 9:0 will be ignored
+    BITS[14:13] - Reserved
+    BITS[12:10] - Value in bits 9:0 will be multiplied with the scale in these bits
+                  000b - 1 ns
+                  001b - 32 ns
+                  010b - 1024 ns
+                  011b - 32,768 ns
+                  100b - 1,048,576 ns
+                  101b - 33,554,432 ns
+                  110b - Reserved
+                  111b - Reserved
+    BITS[9:0]   - Snoop Latency Value. The value in these bits will be multiplied with
+                  the scale in bits 12:10
+  **/
+  UINT16  SnoopLatency;
+  /**
+    NonSnoopLatency bit definition
+    Note: All Reserved bits must be set to 0
+
+    BIT[15]     - When set to 1b, indicates that the values in bits 9:0 are valid
+                  When clear values in bits 9:0 will be ignored
+    BITS[14:13] - Reserved
+    BITS[12:10] - Value in bits 9:0 will be multiplied with the scale in these bits
+                  000b - 1 ns
+                  001b - 32 ns
+                  010b - 1024 ns
+                  011b - 32,768 ns
+                  100b - 1,048,576 ns
+                  101b - 33,554,432 ns
+                  110b - Reserved
+                  111b - Reserved
+    BITS[9:0]   - Non Snoop Latency Value. The value in these bits will be multiplied with
+                  the scale in bits 12:10
+  **/
+  UINT16  NonSnoopLatency;
+} PCH_PCIE_DEVICE_LTR_OVERRIDE;
+
+typedef struct {
+  ///
+  /// Temp Bus Number range available to be assigned to
+  /// each root port and its downstream devices for initialization
+  /// of these devices before PCI Bus enumeration
+  ///
+  UINT8                             TempRootPortBusNumMin;
+  UINT8                             TempRootPortBusNumMax;
+  PCH_PCI_EXPRESS_ROOT_PORT_CONFIG  RootPort[PCH_PCIE_MAX_ROOT_PORTS];
+  BOOLEAN                           RootPortClockGating;
+  UINT8                             NumOfDevAspmOverride;     /// Number of PCI Express card Aspm setting override
+  PCH_PCIE_DEVICE_ASPM_OVERRIDE     *DevAspmOverride;         /// The Pointer which is point to Pci Express card Aspm setting override
+  UINT8                             PcieDynamicGating;        /// Need PMC enable it first from PMC 0x3_12 MCU 318.
+} PCH_PCI_EXPRESS_CONFIG;
+
+
+///
+/// ---------------------------- SATA Config -----------------------------
+///
+typedef enum {
+  PchSataSpeedSupportGen1 = 1,
+  PchSataSpeedSupportGen2
+} PCH_SATA_SPEED_SUPPORT;
+
+typedef struct {
+  UINT8 Enable          : 1;    /// 0: Disable; 1: Enable
+  UINT8 HotPlug         : 1;    /// 0: Disable; 1: Enable
+  UINT8 MechSw          : 1;    /// 0: Disable; 1: Enable
+  UINT8 External        : 1;    /// 0: Disable; 1: Enable
+  UINT8 SpinUp          : 1;    /// 0: Disable; 1: Enable the COMRESET initialization Sequence to the device
+  UINT8 Rsvdbits        : 3;    /// Reserved fields for future expansion w/o protocol change
+} PCH_SATA_PORT_SETTINGS;
+
+typedef struct {
+  PCH_SATA_PORT_SETTINGS  PortSettings[PCH_AHCI_MAX_PORTS];
+  UINT8 RaidAlternateId : 1;    /// 0: Disable; 1: Enable
+  UINT8 Raid0           : 1;    /// 0: Disable; 1: Enable RAID0
+  UINT8 Raid1           : 1;    /// 0: Disable; 1: Enable RAID1
+  UINT8 Raid10          : 1;    /// 0: Disable; 1: Enable RAID10
+  UINT8 Raid5           : 1;    /// 0: Disable; 1: Enable RAID5
+  UINT8 Irrt            : 1;    /// 0: Disable; 1: Enable Intel Rapid Recovery Technology
+  UINT8 OromUiBanner    : 1;    /// 0: Disable; 1: Enable OROM UI and BANNER
+  UINT8 HddUnlock       : 1;    /// 0: Disable; 1: Indicates that the HDD password unlock in the OS is enabled
+
+  UINT8 LedLocate       : 1;    /// 0: Disable; 1: Indicates that the LED/SGPIO hardware is attached and ping to locate feature is enabled on the OS
+  UINT8 IrrtOnly        : 1;    /// 0: Disable; 1: Allow only IRRT drives to span internal and external ports
+  UINT8 TestMode        : 1;    /// 0: Disable; 1: Allow entrance to the PCH SATA test modes
+  UINT8 SalpSupport     : 1;    /// 0: Disable; 1: Enable Aggressive Link Power Management
+  UINT8 LegacyMode      : 1;    /// 0: Native PCI mode; 1: Legacy mode, when SATA controller is operating in IDE mode
+  UINT8 SpeedSupport    : 4;    /// Indicates the maximum speed the SATA controller can support
+  /// 1h: 1.5 Gb/s (Gen 1); 2h: 3 Gb/s(Gen 2)
+
+  UINT8 Rsvdbits        : 7;    // Reserved fields for future expansion w/o protocol change
+} PCH_SATA_CONFIG;
+///
+/// --------------------------- AZALIA Config ------------------------------
+///
+typedef struct {
+  UINT32  VendorDeviceId;
+  UINT16  SubSystemId;
+  UINT8   RevisionId;                       /// 0xFF applies to all steppings
+  UINT8   FrontPanelSupport;
+  UINT16  NumberOfRearJacks;
+  UINT16  NumberOfFrontJacks;
+} PCH_AZALIA_VERB_TABLE_HEADER;
+
+typedef struct {
+  PCH_AZALIA_VERB_TABLE_HEADER  VerbTableHeader;
+  UINT32                        *VerbTableData;
+} PCH_AZALIA_VERB_TABLE;
+
+typedef struct {
+  UINT8                 Pme       : 1;      /// 0: Disable; 1: Enable
+  UINT8                 DS        : 1;      /// 0: Docking is not supported; 1:Docking is supported
+  UINT8                 DA        : 1;      /// 0: Docking is not attached; 1:Docking is attached
+  UINT8                 HdmiCodec : 1;      /// 0: Disable; 1: Enable
+  UINT8                 AzaliaVCi : 1;      /// 0: Disable; 1: Enable
+  UINT8                 Rsvdbits  : 3;
+  UINT8                 AzaliaVerbTableNum; /// Number of verb tables provided by platform
+  PCH_AZALIA_VERB_TABLE *AzaliaVerbTable;   /// Pointer to the actual verb table(s)
+  UINT16                ResetWaitTimer;     /// The delay timer after Azalia reset, the value is number of microseconds
+} PCH_AZALIA_CONFIG;
+
+///
+/// --------------------------- Smbus Config ------------------------------
+///
+typedef struct {
+  UINT8 NumRsvdSmbusAddresses;
+  UINT8 *RsvdSmbusAddressTable;
+} PCH_SMBUS_CONFIG;
+
+///
+/// --------------------------- Miscellaneous PM Config ------------------------------
+///
+typedef struct {
+  UINT8 MeWakeSts           : 1;
+  UINT8 MeHrstColdSts       : 1;
+  UINT8 MeHrstWarmSts       : 1;
+  UINT8 MeHostPowerDn       : 1;
+  UINT8 WolOvrWkSts         : 1;
+  UINT8 Rsvdbits            : 3;
+} PCH_POWER_RESET_STATUS;
+
+typedef struct {
+  UINT8  PmeB0S5Dis         : 1;
+  UINT8  WolEnableOverride  : 1;
+  UINT8  Rsvdbits           : 6;
+} PCH_WAKE_CONFIG;
+
+typedef enum {
+  PchSlpS360us,
+  PchSlpS31ms,
+  PchSlpS350ms,
+  PchSlpS32s
+} PCH_SLP_S3_MIN_ASSERT;
+
+typedef enum {
+  PchSlpS4PchTime,   /// The time defined in EDS Power Sequencing and Reset Signal Timings table
+  PchSlpS41s,
+  PchSlpS42s,
+  PchSlpS43s,
+  PchSlpS44s
+} PCH_SLP_S4_MIN_ASSERT;
+
+typedef struct {
+  ///
+  /// Specify which Power/Reset bits need to be cleared by
+  /// the PCH Init Driver.
+  /// Usually platform drivers take care of these bits, but if
+  /// not, let PCH Init driver clear the bits.
+  ///
+  PCH_POWER_RESET_STATUS  PowerResetStatusClear;
+  ///
+  /// Specify Wake Policy
+  ///
+  PCH_WAKE_CONFIG         WakeConfig;
+  ///
+  /// SLP_XX Minimum Assertion Width Policy
+  ///
+  PCH_SLP_S3_MIN_ASSERT   PchSlpS3MinAssert;
+  PCH_SLP_S4_MIN_ASSERT   PchSlpS4MinAssert;
+  UINT8                   SlpStrchSusUp : 1;  /// Enable/Disable SLP_X Stretching After SUS Well Power Up
+  UINT8                   SlpLanLowDc   : 1;
+  UINT8                   Rsvdbits      : 6;
+} PCH_MISC_PM_CONFIG;
+
+///
+/// --------------------------- Subsystem Vendor ID / Subsystem ID Config -----
+///
+typedef struct {
+  UINT16  SubSystemVendorId;
+  UINT16  SubSystemId;
+} PCH_DEFAULT_SVID_SID;
+
+///
+/// --------------------------- Lock Down Config ------------------------------
+///
+typedef struct {
+  UINT8  GlobalSmi      : 1;
+  UINT8  BiosInterface  : 1;
+  UINT8  RtcLock        : 1;
+  UINT8  BiosLock       : 1;
+  UINT8  Rsvdbits       : 4;
+  UINT8  PchBiosLockSwSmiNumber;
+} PCH_LOCK_DOWN_CONFIG;
+//
+// --------------------------- Serial IRQ Config ------------------------------
+//
+typedef enum {
+  PchQuietMode,
+  PchContinuousMode
+} PCH_SIRQ_MODE;
+///
+/// Refer to SoC EDS for the details of Start Frame Pulse Width in Continuous and Quiet mode
+///
+
+typedef struct {
+  BOOLEAN                 SirqEnable;       /// Determines if enable Serial IRQ
+  PCH_SIRQ_MODE           SirqMode;         /// Serial IRQ Mode Select
+} PCH_LPC_SIRQ_CONFIG;
+
+///
+/// --------------------------- Power Optimizer Config ------------------------------
+///
+typedef struct {
+  UINT8  NumOfDevLtrOverride;                            /// Number of Pci Express card listed in LTR override table
+  PCH_PCIE_DEVICE_LTR_OVERRIDE *DevLtrOverride;          /// Pointer to Pci Express devices LTR override table
+} PCH_PWR_OPT_CONFIG;
+
+///
+/// --------------------- Low Power Input Output Config ------------------------
+///
+typedef struct {
+  UINT8                   LpssPciModeEnabled    : 1;    /// Determines if LPSS PCI Mode enabled
+  UINT8                   Dma0Enabled           : 1;     /// Determines if LPSS DMA1 enabled
+  UINT8                   Dma1Enabled           : 1;     /// Determines if LPSS DMA2 enabled
+  UINT8                   I2C0Enabled           : 1;     /// Determines if LPSS I2C #1 enabled
+  UINT8                   I2C1Enabled           : 1;     /// Determines if LPSS I2C #2 enabled
+  UINT8                   I2C2Enabled           : 1;     /// Determines if LPSS I2C #3 enabled
+  UINT8                   I2C3Enabled           : 1;     /// Determines if LPSS I2C #4 enabled
+  UINT8                   I2C4Enabled           : 1;     /// Determines if LPSS I2C #5 enabled
+  UINT8                   I2C5Enabled           : 1;     /// Determines if LPSS I2C #6 enabled
+  UINT8                   I2C6Enabled           : 1;     /// Determines if LPSS I2C #7 enabled
+  UINT8                   Pwm0Enabled           : 1;     /// Determines if LPSS PWM #1 enabled
+  UINT8                   Pwm1Enabled           : 1;     /// Determines if LPSS PWM #2 enabled
+  UINT8                   Hsuart0Enabled        : 1;     /// Determines if LPSS HSUART #1 enabled
+  UINT8                   Hsuart1Enabled        : 1;     /// Determines if LPSS HSUART #2 enabled
+  UINT8                   SpiEnabled            : 1;     /// Determines if LPSS SPI enabled
+  UINT8                   Rsvdbits              : 2;
+} PCH_LPSS_CONFIG;
+
+///
+/// ----------------------------- SCC Config --------------------------------
+///
+typedef struct {
+  UINT8                   eMMCEnabled           : 1;      /// Determines if SCC eMMC enabled
+  UINT8                   SdioEnabled           : 1;      /// Determines if SCC SDIO enabled
+  UINT8                   SdcardEnabled         : 1;      /// Determines if SCC SD Card enabled
+  UINT8                   HsiEnabled            : 1;      /// Determines if SCC HSI enabled
+  UINT8                   eMMC45Enabled         : 1;      /// Determines if SCC eMMC 4.5 enabled
+  UINT8                   eMMC45DDR50Enabled    : 1;  /// Determines if DDR50 enabled for eMMC 4.5
+  UINT8                   eMMC45HS200Enabled    : 1;  /// Determines if HS200nabled for eMMC 4.5
+  UINT8                   Rsvdbits              : 1;
+  UINT8                   SdCardSDR25Enabled    : 1;    /// Determines if SDR25 for SD Card
+  UINT8                   SdCardDDR50Enabled    : 1;    /// Determines if DDR50 for SD Card
+  UINT8                   Rsvdbits1             : 6;
+  UINT8                   eMMC45RetuneTimerValue;  /// Determines retune timer value.
+} PCH_SCC_CONFIG;
+
+///
+/// ------------ General PCH Platform Policy protocol definition ------------
+///
+struct _DXE_PCH_PLATFORM_POLICY_PROTOCOL {
+  UINT8                   Revision;
+  UINT8                   BusNumber;  /// PCI Bus Number of the PCH device
+  PCH_DEVICE_ENABLING     *DeviceEnabling;
+  PCH_USB_CONFIG          *UsbConfig;
+  PCH_PCI_EXPRESS_CONFIG  *PciExpressConfig;
+
+  PCH_SATA_CONFIG         *SataConfig;
+  PCH_AZALIA_CONFIG       *AzaliaConfig;
+  PCH_SMBUS_CONFIG        *SmbusConfig;
+  PCH_MISC_PM_CONFIG      *MiscPmConfig;
+  PCH_DEFAULT_SVID_SID    *DefaultSvidSid;
+  PCH_LOCK_DOWN_CONFIG    *LockDownConfig;
+  PCH_LPC_SIRQ_CONFIG     *SerialIrqConfig;
+  PCH_PWR_OPT_CONFIG      *PwrOptConfig;
+  PCH_LPSS_CONFIG         *LpssConfig;
+  PCH_SCC_CONFIG          *SccConfig;
+  UINT8                   IdleReserve;
+  UINT8                   EhciPllCfgEnable;
+  UINT8                   AcpiHWRed; //Hardware Reduced Mode
+};
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchReset.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchReset.h
new file mode 100644
index 0000000000..7e63f58346
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchReset.h
@@ -0,0 +1,114 @@
+/**
+**/
+/**
+
+Copyright (c) 2011  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+  @file
+  PchReset.h
+
+  @brief
+  PCH Reset Protocol
+
+**/
+#ifndef _PCH_RESET_H_
+#define _PCH_RESET_H_
+
+
+//
+#define PCH_RESET_PROTOCOL_GUID \
+  { \
+    0xdb63592c, 0xb8cc, 0x44c8, 0x91, 0x8c, 0x51, 0xf5, 0x34, 0x59, 0x8a, 0x5a \
+  }
+#define PCH_RESET_CALLBACK_PROTOCOL_GUID \
+  { \
+    0x3a3300ab, 0xc929, 0x487d, 0xab, 0x34, 0x15, 0x9b, 0xc1, 0x35, 0x62, 0xc0 \
+  }
+extern EFI_GUID                             gPchResetProtocolGuid;
+extern EFI_GUID                             gPchResetCallbackProtocolGuid;
+
+///
+/// Forward reference for ANSI C compatibility
+///
+typedef struct _PCH_RESET_PROTOCOL          PCH_RESET_PROTOCOL;
+
+typedef struct _PCH_RESET_CALLBACK_PROTOCOL PCH_RESET_CALLBACK_PROTOCOL;
+
+///
+/// Related Definitions
+///
+///
+/// PCH Reset Types
+///
+typedef enum {
+  ColdReset,
+  WarmReset,
+  ShutdownReset,
+  PowerCycleReset,
+  GlobalReset,
+  GlobalResetWithEc
+} PCH_RESET_TYPE;
+
+///
+/// Member functions
+///
+typedef
+EFI_STATUS
+(EFIAPI *PCH_RESET) (
+  IN     PCH_RESET_PROTOCOL       * This,
+  IN     PCH_RESET_TYPE           PchResetType
+  )
+/**
+
+  @brief
+  Execute Pch Reset from the host controller.
+
+  @param[in] This                 Pointer to the PCH_RESET_PROTOCOL instance.
+  @param[in] PchResetType         Pch Reset Types which includes ColdReset, WarmReset, ShutdownReset,
+                                  PowerCycleReset, GlobalReset, GlobalResetWithEc
+
+  @retval EFI_SUCCESS             Successfully completed.
+  @retval EFI_INVALID_PARAMETER   If ResetType is invalid.
+
+**/
+;
+
+typedef
+EFI_STATUS
+(EFIAPI *PCH_RESET_CALLBACK) (
+  IN     PCH_RESET_TYPE           PchResetType
+  )
+/**
+
+  @brief
+  Execute call back function for Pch Reset.
+
+  @param[in] PchResetType         Pch Reset Types which includes PowerCycle, Globalreset.
+
+  @retval EFI_SUCCESS             The callback function has been done successfully
+  @retval EFI_NOT_FOUND           Failed to find Pch Reset Callback protocol. Or, none of
+                                  callback protocol is installed.
+  @retval Others                  Do not do any reset from PCH
+
+**/
+;
+
+///
+/// Interface structure for the Pch Reset Protocol
+///
+struct _PCH_RESET_PROTOCOL {
+  PCH_RESET Reset;
+};
+
+///
+/// PCH_RESET_CALLBACK_PROTOCOL Structure Definition
+///
+struct _PCH_RESET_CALLBACK_PROTOCOL {
+  PCH_RESET_CALLBACK  ResetCallback;
+};
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchS3Support.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchS3Support.h
new file mode 100644
index 0000000000..ae1543c9ea
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/PchS3Support.h
@@ -0,0 +1,132 @@
+/**
+**/
+/**
+
+Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+  @file
+  PchS3Support.h
+
+  @brief
+  This file defines the PCH S3 support Protocol.
+
+**/
+#ifndef _PCH_S3_SUPPORT_PROTOCOL_H_
+#define _PCH_S3_SUPPORT_PROTOCOL_H_
+
+#ifndef ECP_FLAG
+#include <Pi/PiS3BootScript.h>
+#endif
+
+#define EFI_PCH_S3_SUPPORT_PROTOCOL_GUID \
+  { \
+    0xe287d20b, 0xd897, 0x4e1e, 0xa5, 0xd9, 0x97, 0x77, 0x63, 0x93, 0x6a, 0x4 \
+  }
+
+#include <Protocol/PchPlatformPolicy.h>
+
+///
+/// Extern the GUID for protocol users.
+///
+extern EFI_GUID                             gEfiPchS3SupportProtocolGuid;
+
+///
+/// Forward reference for ANSI C compatibility
+///
+typedef struct _EFI_PCH_S3_SUPPORT_PROTOCOL EFI_PCH_S3_SUPPORT_PROTOCOL;
+
+typedef enum {
+  PchS3ItemTypeSendCodecCommand,
+  PchS3ItemTypePollStatus,
+  PchS3ItemTypeInitPcieRootPortDownstream,
+  PchS3ItemTypePcieSetPm,
+  PchS3ItemTypePmTimerStall,
+  PchS3ItemTypeMax
+} EFI_PCH_S3_DISPATCH_ITEM_TYPE;
+
+///
+/// It's better not to use pointer here because the size of pointer in DXE is 8, but it's 4 in PEI
+/// plug 4 to ParameterSize in PEIM if you really need it
+///
+typedef struct {
+  UINT32                        HdaBar;
+  UINT32                        CodecCmdData;
+} EFI_PCH_S3_PARAMETER_SEND_CODEC_COMMAND;
+
+typedef struct {
+  UINT64                        MmioAddress;
+  EFI_BOOT_SCRIPT_WIDTH         Width;
+  UINT64                        Mask;
+  UINT64                        Value;
+  UINT32                        Timeout;  // us
+} EFI_PCH_S3_PARAMETER_POLL_STATUS;
+
+typedef struct {
+  UINT8                         RootPortBus;
+  UINT8                         RootPortDevice;
+  UINT8                         RootPortFunc;
+  UINT8                         TempBusNumberMin;
+  UINT8                         TempBusNumberMax;
+} EFI_PCH_S3_PARAMETER_INIT_PCIE_ROOT_PORT_DOWNSTREAM;
+
+typedef struct {
+  UINT8                         RootPortBus;
+  UINT8                         RootPortDevice;
+  UINT8                         RootPortFunc;
+  PCH_PCI_EXPRESS_ASPM_CONTROL  RootPortAspm;
+  UINT8                         NumOfDevAspmOverride;
+  UINT32                        DevAspmOverrideAddr;
+  UINT8                         TempBusNumberMin;
+  UINT8                         TempBusNumberMax;
+  UINT8                         NumOfDevLtrOverride;
+  UINT32                        DevLtrOverrideAddr;
+} EFI_PCH_S3_PARAMETER_PCIE_SET_PM;
+
+typedef struct {
+  UINT32                        DelayTime;  // us
+} EFI_PCH_S3_PARAMETER_PM_TIMER_STALL;
+
+typedef struct {
+  EFI_PCH_S3_DISPATCH_ITEM_TYPE Type;
+  VOID                          *Parameter;
+} EFI_PCH_S3_DISPATCH_ITEM;
+
+///
+/// Member functions
+///
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PCH_S3_SUPPORT_SET_S3_DISPATCH_ITEM) (
+  IN     EFI_PCH_S3_SUPPORT_PROTOCOL   * This,
+  IN     EFI_PCH_S3_DISPATCH_ITEM      * DispatchItem,
+  OUT    EFI_PHYSICAL_ADDRESS          * S3DispatchEntryPoint
+  );
+
+/**
+
+  @brief
+  Set an item to be dispatched at S3 resume time. At the same time, the entry point
+  of the PCH S3 support image is returned to be used in subsequent boot script save
+  call
+
+  @param[in] This                 Pointer to the protocol instance.
+  @param[in] DispatchItem         The item to be dispatched.
+  @param[in] S3DispatchEntryPoint The entry point of the PCH S3 support image.
+
+  @retval EFI_STATUS              Successfully completed.
+  @retval EFI_OUT_OF_RESOURCES    Out of resources.
+
+**/
+
+///
+/// Protocol definition
+///
+struct _EFI_PCH_S3_SUPPORT_PROTOCOL {
+  EFI_PCH_S3_SUPPORT_SET_S3_DISPATCH_ITEM SetDispatchItem;
+};
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/SdHostIo.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/SdHostIo.h
new file mode 100644
index 0000000000..c0c94b9384
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/SdHostIo.h
@@ -0,0 +1,409 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+--*/
+
+
+/*++
+Module Name:
+
+  SdHostIo.h
+
+Abstract:
+
+  Interface definition for EFI_SD_HOST_IO_PROTOCOL
+
+--*/
+
+#ifndef _SD_HOST_IO_H
+#define _SD_HOST_IO_H
+
+
+// Global ID for the EFI_SD_HOST_IO_PROTOCOL
+// {B63F8EC7-A9C9-4472-A4C0-4D8BF365CC51}
+//
+#define EFI_SD_HOST_IO_PROTOCOL_GUID \
+  { 0xb63f8ec7, 0xa9c9, 0x4472, { 0xa4, 0xc0, 0x4d, 0x8b, 0xf3, 0x65, 0xcc, 0x51 } }
+
+typedef struct _EFI_SD_HOST_IO_PROTOCOL EFI_SD_HOST_IO_PROTOCOL;
+
+//
+// TODO: Move to Pci22.h
+//
+#define PCI_SUBCLASS_SD_HOST_CONTROLLER   0x05
+#define PCI_IF_STANDARD_HOST_NO_DMA       0x00
+#define PCI_IF_STANDARD_HOST_SUPPORT_DMA  0x01
+
+//
+// TODO: Retire
+//
+#define EFI_SD_HOST_IO_PROTOCOL_REVISION_01          0x01
+
+//
+// TODO: Do these belong in an Industry Standard include file?
+//
+// MMIO Registers definition for MMC/SDIO controller
+//
+#define  MMIO_DMAADR                     0x00
+#define  MMIO_BLKSZ                      0x04
+#define  MMIO_BLKCNT                     0x06
+#define  MMIO_CMDARG                     0x08
+#define  MMIO_XFRMODE                    0x0C
+#define  MMIO_SDCMD                      0x0E
+#define  MMIO_RESP                       0x10
+#define  MMIO_BUFDATA                    0x20
+#define  MMIO_PSTATE                     0x24
+#define  MMIO_HOSTCTL                    0x28
+#define  MMIO_PWRCTL                     0x29
+#define  MMIO_BLKGAPCTL                  0x2A
+#define  MMIO_WAKECTL                    0x2B
+#define  MMIO_CLKCTL                     0x2C
+#define  MMIO_TOCTL                      0x2E
+#define  MMIO_SWRST                      0x2F
+#define  MMIO_NINTSTS                    0x30
+#define  MMIO_ERINTSTS                   0x32
+#define  MMIO_NINTEN                     0x34
+#define  MMIO_ERINTEN                    0x36
+#define  MMIO_NINTSIGEN                  0x38
+#define  MMIO_ERINTSIGEN                 0x3A
+#define  MMIO_AC12ERRSTS                 0x3C
+#define  MMIO_HOST_CTL2                  0x3E //hphang <- New in VLV2
+#define  MMIO_CAP                        0x40
+#define  MMIO_CAP2                       0x44 //hphang <- New in VLV2
+#define  MMIO_MCCAP                      0x48
+#define  MMIO_FORCEEVENTCMD12ERRSTAT     0x50 //hphang <- New in VLV2
+#define  MMIO_FORCEEVENTERRINTSTAT       0x52 //hphang <- New in VLV2
+#define  MMIO_ADMAERRSTAT                0x54 //hphang <- New in VLV2
+#define  MMIO_ADMASYSADDR                0x58 //hphang <- New in VLV2
+#define  MMIO_PRESETVALUE0               0x60 //hphang <- New in VLV2
+#define  MMIO_PRESETVALUE1               0x64 //hphang <- New in VLV2
+#define  MMIO_PRESETVALUE2               0x68 //hphang <- New in VLV2
+#define  MMIO_PRESETVALUE3               0x6C //hphang <- New in VLV2
+#define  MMIO_BOOTTIMEOUTCTRL            0x70 //hphang <- New in VLV2
+#define  MMIO_DEBUGSEL                   0x74 //hphang <- New in VLV2
+#define  MMIO_SHAREDBUS                  0xE0 //hphang <- New in VLV2
+#define  MMIO_SPIINTSUP                  0xF0 //hphang <- New in VLV2
+#define  MMIO_SLTINTSTS                  0xFC
+#define  MMIO_CTRLRVER                   0xFE
+
+typedef enum {
+  ResponseNo = 0,
+  ResponseR1,
+  ResponseR1b,
+  ResponseR2,
+  ResponseR3,
+  ResponseR4,
+  ResponseR5,
+  ResponseR5b,
+  ResponseR6,
+  ResponseR7
+} RESPONSE_TYPE;
+
+typedef enum {
+  NoData = 0,
+  InData,
+  OutData
+} TRANSFER_TYPE;
+
+typedef enum {
+  Reset_Auto = 0,
+  Reset_DAT,
+  Reset_CMD,
+  Reset_DAT_CMD,
+  Reset_All,
+  Reset_HW
+} RESET_TYPE;
+
+
+typedef enum {
+  SDMA = 0,
+  ADMA2,
+  PIO
+} DMA_MOD;
+
+typedef struct {
+  UINT32  HighSpeedSupport:    1;  //High speed supported
+  UINT32  V18Support:          1;  //1.8V supported
+  UINT32  V30Support:          1;  //3.0V supported
+  UINT32  V33Support:          1;  //3.3V supported
+  UINT32  SDR50Support:        1;
+  UINT32  SDR104Support:       1;
+  UINT32  DDR50Support:        1;
+  UINT32  Reserved0:           1;
+  UINT32  BusWidth4:           1;  // 4 bit width
+  UINT32  BusWidth8:           1;  // 8 bit width
+  UINT32  Reserved1:           6;
+  UINT32  SDMASupport:         1;
+  UINT32  ADMA2Support:        1;
+  UINT32  DmaMode:             2;
+  UINT32  ReTuneTimer:         4;
+  UINT32  ReTuneMode:          2;
+  UINT32  Reserved2:           6;
+  UINT32  BoundarySize;
+} HOST_CAPABILITY;
+
+/*++
+
+  Routine Description:
+    The main function used to send the command to the card inserted into the SD host
+    slot.
+    It will assemble the arguments to set the command register and wait for the command
+    and transfer completed until timeout. Then it will read the response register to fill
+    the ResponseData
+
+  Arguments:
+    This           - Pointer to EFI_SD_HOST_IO_PROTOCOL
+    CommandIndex   - The command index to set the command index field of command register
+    Argument       - Command argument to set the argument field of command register
+    DataType       - TRANSFER_TYPE, indicates no data, data in or data out
+    Buffer         - Contains the data read from / write to the device
+    BufferSize     - The size of the buffer
+    ResponseType   - RESPONSE_TYPE
+    TimeOut        - Time out value in 1 ms unit
+    ResponseData   - Depending on the ResponseType, such as CSD or card status
+
+  Returns:
+    EFI_SUCCESS
+    EFI_INVALID_PARAMETER
+    EFI_OUT_OF_RESOURCES
+    EFI_TIMEOUT
+    EFI_DEVICE_ERROR
+
+--*/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SEND_COMMAND) (
+  IN   EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN   UINT16                     CommandIndex,
+  IN   UINT32                     Argument,
+  IN   TRANSFER_TYPE              DataType,
+  IN   UINT8                      *Buffer, OPTIONAL
+  IN   UINT32                     BufferSize,
+  IN   RESPONSE_TYPE              ResponseType,
+  IN   UINT32                     TimeOut,
+  OUT  UINT32                     *ResponseData OPTIONAL
+  );
+
+/*++
+
+  Routine Description:
+    Set max clock frequency of the host, the actual frequency
+    may not be the same as MaxFrequency. It depends on
+    the max frequency the host can support, divider, and host
+    speed mode.
+
+  Arguments:
+    This           - Pointer to EFI_SD_HOST_IO_PROTOCOL
+    MaxFrequency   - Max frequency in HZ
+
+  Returns:
+    EFI_SUCCESS
+    EFI_TIMEOUT
+--*/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SET_CLOCK_FREQUENCY) (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  UINT32                     MaxFrequency
+  );
+
+/*++
+
+  Routine Description:
+    Set bus width of the host
+
+  Arguments:
+    This       - Pointer to EFI_SD_HOST_IO_PROTOCOL
+    BusWidth   - Bus width in 1, 4, 8 bits
+
+  Returns:
+    EFI_SUCCESS
+    EFI_INVALID_PARAMETER
+
+--*/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SET_BUS_WIDTH) (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  UINT32                     BusWidth
+  );
+
+/*++
+
+  Routine Description:
+    Set voltage which could supported by the host.
+    Support 0(Power off the host), 1.8V, 3.0V, 3.3V
+  Arguments:
+    This      - Pointer to EFI_SD_HOST_IO_PROTOCOL
+    Voltage   - Units in 0.1 V
+
+  Returns:
+    EFI_SUCCESS
+    EFI_INVALID_PARAMETER
+
+--*/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SET_HOST_VOLTAGE) (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  UINT32                     Voltage
+  );
+
+/*++
+
+  Routine Description:
+    Set Host High Speed
+  Arguments:
+    This      - Pointer to EFI_SD_HOST_IO_PROTOCOL
+    HighSpeed   - True for High Speed Mode set, false for normal mode
+
+  Returns:
+    EFI_SUCCESS
+    EFI_INVALID_PARAMETER
+
+--*/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SET_HOST_SPEED_MODE) (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  UINT32                     HighSpeed
+  );
+
+/*++
+
+  Routine Description:
+    Set High Speed Mode
+  Arguments:
+    This      - Pointer to EFI_SD_HOST_IO_PROTOCOL
+    SetHostDdrMode   - True for DDR Mode set, false for normal mode
+
+  Returns:
+    EFI_SUCCESS
+    EFI_INVALID_PARAMETER
+
+--*/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SET_HOST_DDR_MODE) (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  UINT32                     DdrMode
+  );
+
+
+/*++
+
+  Routine Description:
+   Reset the host
+
+  Arguments:
+    This      - Pointer to EFI_SD_HOST_IO_PROTOCOL
+    ResetAll  - TRUE to reset all
+
+  Returns:
+    EFI_SUCCESS
+    EFI_TIMEOUT
+
+--*/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_RESET_SD_HOST) (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  RESET_TYPE                 ResetType
+  );
+
+/*++
+
+  Routine Description:
+   Reset the host
+
+  Arguments:
+    This    - Pointer to EFI_SD_HOST_IO_PROTOCOL
+    Enable  - TRUE to enable, FALSE to disable
+
+  Returns:
+    EFI_SUCCESS
+    EFI_TIMEOUT
+
+--*/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_ENABLE_AUTO_STOP_CMD) (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  BOOLEAN                    Enable
+  );
+
+/*++
+
+  Routine Description:
+    Find whether these is a card inserted into the slot. If so
+    init the host. If not, return EFI_NOT_FOUND.
+
+  Arguments:
+    This      - Pointer to EFI_SD_HOST_IO_PROTOCOL
+
+  Returns:
+    EFI_SUCCESS
+    EFI_NOT_FOUND
+
+--*/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_DETECT_CARD_AND_INIT_HOST) (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This
+  );
+
+/*++
+
+  Routine Description:
+   Set the Block length
+
+  Arguments:
+    This        - Pointer to EFI_SD_HOST_IO_PROTOCOL
+    BlockLength - card supportes block length
+
+  Returns:
+    EFI_SUCCESS
+    EFI_TIMEOUT
+
+--*/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SET_BLOCK_LENGTH) (
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
+  IN  UINT32                     BlockLength
+  );
+
+typedef EFI_STATUS
+(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SETUP_DEVICE)(
+  IN  EFI_SD_HOST_IO_PROTOCOL    *This
+  );
+
+
+
+//
+// Interface structure for the EFI SD Host I/O Protocol
+//
+struct _EFI_SD_HOST_IO_PROTOCOL {
+  UINT32                                             Revision;
+  HOST_CAPABILITY                                    HostCapability;
+  EFI_SD_HOST_IO_PROTOCOL_SEND_COMMAND               SendCommand;
+  EFI_SD_HOST_IO_PROTOCOL_SET_CLOCK_FREQUENCY        SetClockFrequency;
+  EFI_SD_HOST_IO_PROTOCOL_SET_BUS_WIDTH              SetBusWidth;
+  EFI_SD_HOST_IO_PROTOCOL_SET_HOST_VOLTAGE           SetHostVoltage;
+  EFI_SD_HOST_IO_PROTOCOL_SET_HOST_DDR_MODE          SetHostDdrMode;
+  EFI_SD_HOST_IO_PROTOCOL_RESET_SD_HOST              ResetSdHost;
+  EFI_SD_HOST_IO_PROTOCOL_ENABLE_AUTO_STOP_CMD       EnableAutoStopCmd;
+  EFI_SD_HOST_IO_PROTOCOL_DETECT_CARD_AND_INIT_HOST  DetectCardAndInitHost;
+  EFI_SD_HOST_IO_PROTOCOL_SET_BLOCK_LENGTH           SetBlockLength;
+  EFI_SD_HOST_IO_PROTOCOL_SETUP_DEVICE               SetupDevice;
+  EFI_SD_HOST_IO_PROTOCOL_SET_HOST_SPEED_MODE        SetHostSpeedMode;
+};
+
+extern EFI_GUID gEfiSdHostIoProtocolGuid;
+
+#endif
+
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/SmbiosSlotPopulation.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/SmbiosSlotPopulation.h
new file mode 100644
index 0000000000..8b7c42805f
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/SmbiosSlotPopulation.h
@@ -0,0 +1,47 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+    SmbiosSlotPopulation.h
+
+Abstract:
+
+    EFI SMBIOS slot structure control code.
+
+GUID:
+    {EF7BF7D6-F8FF-4a76-8247-C0D0D1CC49C0}
+    0xef7bf7d6, 0xf8ff, 0x4a76, 0x82, 0x47, 0xc0, 0xd0, 0xd1, 0xcc, 0x49, 0xc0
+
+Revision History
+
+--*/
+
+#ifndef _EFI_SMBIOS_SLOT_POPULATION_H_
+#define _EFI_SMBIOS_SLOT_POPULATION_H_
+
+//
+// Slot Population Protocol GUID
+//
+#define EFI_SMBIOS_SLOT_POPULATION_GUID \
+  { 0xef7bf7d6, 0xf8ff, 0x4a76, 0x82, 0x47, 0xc0, 0xd0, 0xd1, 0xcc, 0x49, 0xc0 }
+
+typedef struct {
+  UINT16      SmbiosSlotId;   // SMBIOS Slot ID
+  BOOLEAN     InUse;          // Does the slot have a card in it
+  BOOLEAN     Disabled;       // Should the slot information be in SMBIOS
+} EFI_SMBIOS_SLOT_ENTRY;
+
+typedef struct {
+  UINT32                NumberOfEntries;
+  EFI_SMBIOS_SLOT_ENTRY *SlotEntries;
+} EFI_SMBIOS_SLOT_POPULATION_INFO;
+
+extern EFI_GUID gEfiSmbiosSlotPopulationGuid;
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/SmmIchnDispatchEx.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/SmmIchnDispatchEx.h
new file mode 100644
index 0000000000..73e12c5d6a
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/SmmIchnDispatchEx.h
@@ -0,0 +1,159 @@
+/**
+**/
+/**
+
+Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+  @file
+  SmmIchnDispatchEx.h
+
+  @brief
+  SmmIchnDispatch Extended Protocol
+
+**/
+#ifndef _EFI_SMM_ICHN_DISPATCH_EX_H_
+#define _EFI_SMM_ICHN_DISPATCH_EX_H_
+
+#ifdef ECP_FLAG
+#include <Protocol/SmmIchnDispatch/SmmIchnDispatch.h>
+#else
+#include <Protocol/SmmIchnDispatch.h>
+#endif
+
+#define EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL_GUID \
+  { \
+    0x3920405b, 0xc897, 0x44da, 0x88, 0xf3, 0x4c, 0x49, 0x8a, 0x6f, 0xf7, 0x36 \
+  }
+extern EFI_GUID                                   gEfiSmmIchnDispatchExProtocolGuid;
+
+///
+/// Forward reference for ANSI C compatibility
+///
+typedef struct _EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL;
+
+///
+/// Related Definitions
+///
+///
+/// Ichn Dispatch Extended Types
+///
+typedef enum {
+  IchnExPciExpress = NUM_ICHN_TYPES + 1,
+  IchnExMonitor,
+  IchnExSpi,
+  IchnExQRT,
+  IchnExGpioUnlock,
+  IchnExTmrOverflow,
+  IchnExPcie0Hotplug,
+  IchnExPcie1Hotplug,
+  IchnExPcie2Hotplug,
+  IchnExPcie3Hotplug,
+  IchnExPcie0LinkActive,
+  IchnExPcie1LinkActive,
+  IchnExPcie2LinkActive,
+  IchnExPcie3LinkActive,
+  ///
+  /// INSERT NEW ITEMS JUST BEFORE THIS LINE
+  ///
+  IchnExTypeMAX /// the maximum number of items in this enumeration
+} EFI_SMM_ICHN_EX_SMI_TYPE;
+
+typedef struct {
+  EFI_SMM_ICHN_EX_SMI_TYPE  Type;
+} EFI_SMM_ICHN_DISPATCH_EX_CONTEXT;
+
+///
+/// Member functions
+///
+typedef
+VOID
+(EFIAPI *EFI_SMM_ICHN_DISPATCH_EX) (
+  IN  EFI_HANDLE                                DispatchHandle,
+  IN  EFI_SMM_ICHN_DISPATCH_EX_CONTEXT          * DispatchContext
+  );
+
+/**
+
+  @brief
+  Dispatch function for a ICH n Extended specific SMI handler.
+
+  @param[in] DispatchHandle       Handle of this dispatch function.
+  @param[in] DispatchContext      Pointer to the dispatch function's context.
+                                  The DispatchContext fields are filled in
+                                  by the dispatching driver prior to
+                                  invoking this dispatch function.
+
+    @retval None
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SMM_ICHN_EX_REGISTER) (
+  IN  EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL   * This,
+  IN  EFI_SMM_ICHN_DISPATCH_EX            DispatchFunction,
+  IN  EFI_SMM_ICHN_DISPATCH_EX_CONTEXT    * DispatchContext,
+  OUT EFI_HANDLE                          * DispatchHandle
+  );
+
+/**
+
+  @brief
+  Register a child SMI source dispatch function with a parent SMM driver
+
+  @param[in] This                 Protocol instance pointer.
+  @param[in] DispatchFunction     Pointer to dispatch function to be invoked for
+                                  this SMI source
+  @param[in] DispatchContext      Pointer to the dispatch function's context.
+                                  The caller fills this context in before calling
+                                  the register function to indicate to the register
+                                  function the ICHN SMI source for which the dispatch
+                                  function should be invoked.
+  @param[in] DispatchHandle       Handle of dispatch function, for when interfacing
+                                  with the parent SMM driver.
+
+  @retval EFI_SUCCESS             The dispatch function has been successfully
+                                  registered and the SMI source has been enabled.
+  @retval EFI_DEVICE_ERROR        The driver was unable to enable the SMI source.
+  @retval EFI_OUT_OF_RESOURCES    Not enough memory (system or SMM) to manage this
+                                  child.
+  @retval EFI_INVALID_PARAMETER   DispatchContext is invalid. The ICHN input value
+                                  is not within valid range.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SMM_ICHN_EX_UNREGISTER) (
+  IN  EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL         * This,
+  IN  EFI_HANDLE                                DispatchHandle
+  );
+
+/**
+
+  @brief
+  Unregister a child SMI source dispatch function with a parent SMM driver
+
+  @param[in] This                 Protocol instance pointer.
+  @param[in] DispatchHandle       Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS             The dispatch function has been successfully
+                                  unregistered and the SMI source has been disabled
+                                  if there are no other registered child dispatch
+                                  functions for this SMI source.
+  @retval EFI_INVALID_PARAMETER   Handle is invalid.
+  @retval Others                  TBD
+
+**/
+
+///
+/// Interface structure for the SMM Ich n specific SMI Dispatch Protocol
+///
+typedef struct _EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL {
+  EFI_SMM_ICHN_EX_REGISTER    Register;
+  EFI_SMM_ICHN_EX_UNREGISTER  UnRegister;
+};
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/SmmSmbus.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/SmmSmbus.h
new file mode 100644
index 0000000000..bb2b4d7c13
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/SmmSmbus.h
@@ -0,0 +1,39 @@
+/*++
+
+Copyright (c)  2009  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  SmmSmbus.h
+
+Abstract:
+
+  SmmSmbus Protocol
+
+--*/
+#ifndef __EFI_SMM_SMBUS_PROTOCOL_H__
+#define __EFI_SMM_SMBUS_PROTOCOL_H__
+
+//
+// GUID for the SmmSmbus Protocol
+//
+// EDK and EDKII have different GUID formats
+//
+
+#define EFI_SMM_SMBUS_PROTOCOL_GUID  \
+  { \
+    0x72e40094, 0x2ee1, 0x497a, 0x8f, 0x33, 0x4c, 0x93, 0x4a, 0x9e, 0x9c, 0xc \
+  }
+
+//
+// Resuse the DXE definition, and use another GUID.
+//
+typedef EFI_SMBUS_HC_PROTOCOL  SMM_SMBUS_HC_PROTOCOL;
+
+extern EFI_GUID  gEfiSmmSmbusProtocolGuid;
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/Spi.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/Spi.h
new file mode 100644
index 0000000000..a8d50cbbf2
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/Spi.h
@@ -0,0 +1,260 @@
+/**
+**/
+/**
+
+Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+  @file
+  Spi.h
+
+  @brief
+  This file defines the EFI SPI Protocol which implements the
+  Intel(R) ICH SPI Host Controller Compatibility Interface.
+
+**/
+#ifndef _EFI_SPI_H_
+#define _EFI_SPI_H_
+
+
+//
+#define EFI_SPI_PROTOCOL_GUID \
+  { \
+    0x1156efc6, 0xea32, 0x4396, 0xb5, 0xd5, 0x26, 0x93, 0x2e, 0x83, 0xc3, 0x13 \
+  }
+#define EFI_SMM_SPI_PROTOCOL_GUID \
+  { \
+    0xD9072C35, 0xEB8F, 0x43ad, 0xA2, 0x20, 0x34, 0xD4, 0x0E, 0x2A, 0x82, 0x85 \
+  }
+extern EFI_GUID                   gEfiSpiProtocolGuid;
+extern EFI_GUID                   gEfiSmmSpiProtocolGuid;
+
+///
+/// Forward reference for ANSI C compatibility
+///
+typedef struct _EFI_SPI_PROTOCOL  EFI_SPI_PROTOCOL;
+
+///
+/// SPI protocol data structures and definitions
+///
+///
+/// Number of Prefix Opcodes allowed on the SPI interface
+///
+#define SPI_NUM_PREFIX_OPCODE 2
+
+///
+/// Number of Opcodes in the Opcode Menu
+///
+#define SPI_NUM_OPCODE  8
+
+///
+/// Opcode Type
+///    EnumSpiOpcodeCommand: Command without address
+///    EnumSpiOpcodeRead: Read with address
+///    EnumSpiOpcodeWrite: Write with address
+///
+typedef enum {
+  EnumSpiOpcodeReadNoAddr,
+  EnumSpiOpcodeWriteNoAddr,
+  EnumSpiOpcodeRead,
+  EnumSpiOpcodeWrite,
+  EnumSpiOpcodeMax
+} SPI_OPCODE_TYPE;
+
+typedef enum {
+  EnumSpiCycle20MHz,
+  EnumSpiCycle33MHz,
+  EnumSpiCycle66MHz,  /// Not supported by VLV
+  EnumSpiCycle50MHz,
+  EnumSpiCycleMax
+} SPI_CYCLE_FREQUENCY;
+
+typedef enum {
+  EnumSpiRegionAll,
+  EnumSpiRegionBios,
+  EnumSpiRegionSeC,
+  EnumSpiRegionDescriptor,
+  EnumSpiRegionPlatformData,
+  EnumSpiRegionMax
+} SPI_REGION_TYPE;
+
+///
+/// Hardware Sequencing required operations (as listed in Valleyview EDS "Hardware
+/// Sequencing Commands and Opcode Requirements"
+///
+typedef enum {
+  EnumSpiOperationWriteStatus,
+  EnumSpiOperationProgramData_1_Byte,
+  EnumSpiOperationProgramData_64_Byte,
+  EnumSpiOperationReadData,
+  EnumSpiOperationWriteDisable,
+  EnumSpiOperationReadStatus,
+  EnumSpiOperationWriteEnable,
+  EnumSpiOperationFastRead,
+  EnumSpiOperationEnableWriteStatus,
+  EnumSpiOperationErase_256_Byte,
+  EnumSpiOperationErase_4K_Byte,
+  EnumSpiOperationErase_8K_Byte,
+  EnumSpiOperationErase_64K_Byte,
+  EnumSpiOperationFullChipErase,
+  EnumSpiOperationJedecId,
+  EnumSpiOperationDualOutputFastRead,
+  EnumSpiOperationDiscoveryParameters,
+  EnumSpiOperationOther,
+  EnumSpiOperationMax
+} SPI_OPERATION;
+
+///
+/// SPI Command Configuration
+///   Frequency       The expected frequency to be used (value to be programmed to the SSFC
+///                   Register)
+///   Operation       Which Hardware Sequencing required operation this opcode respoinds to.
+///                   The required operations are listed in EDS Table 5-55: "Hardware
+///                   Sequencing Commands and Opcode Requirements"
+///                   If the opcode does not corresponds to any operation listed, use
+///                   EnumSpiOperationOther, and provides TYPE and Code for it in
+///                   SpecialOpcodeEntry.
+///
+typedef struct _SPI_OPCODE_MENU_ENTRY {
+  SPI_OPCODE_TYPE     Type;
+  UINT8               Code;
+  SPI_CYCLE_FREQUENCY Frequency;
+  SPI_OPERATION       Operation;
+} SPI_OPCODE_MENU_ENTRY;
+
+//
+// Initialization data table loaded to the SPI host controller
+//    VendorId        Vendor ID of the SPI device
+//    DeviceId0       Device ID0 of the SPI device
+//    DeviceId1       Device ID1 of the SPI device
+//    PrefixOpcode    Prefix opcodes which are loaded into the SPI host controller
+//    OpcodeMenu      Opcodes which are loaded into the SPI host controller Opcode Menu
+//    BiosStartOffset The offset of the start of the BIOS image relative to the flash device.
+//                    Please note this is a Flash Linear Address, NOT a memory space address.
+//                    This value is platform specific and depends on the system flash map.
+//                    This value is only used on non Descriptor mode.
+//    BiosSize        The the BIOS Image size in flash. This value is platform specific
+//                    and depends on the system flash map. Please note BIOS Image size may
+//                    be smaller than BIOS Region size (in Descriptor Mode) or the flash size
+//                    (in Non Descriptor Mode), and in this case, BIOS Image is supposed to be
+//                    placed at the top end of the BIOS Region (in Descriptor Mode) or the flash
+//                    (in Non Descriptor Mode)
+//
+typedef struct _SPI_INIT_TABLE {
+  UINT8                 VendorId;
+  UINT8                 DeviceId0;
+  UINT8                 DeviceId1;
+  UINT8                 PrefixOpcode[SPI_NUM_PREFIX_OPCODE];
+  SPI_OPCODE_MENU_ENTRY OpcodeMenu[SPI_NUM_OPCODE];
+  UINTN                 BiosStartOffset;
+  UINTN                 BiosSize;
+} SPI_INIT_TABLE;
+
+//
+// Protocol member functions
+//
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SPI_INIT) (
+  IN EFI_SPI_PROTOCOL     * This,
+  IN SPI_INIT_TABLE       * InitTable
+  );
+
+/**
+
+  @brief
+  Initializes the host controller to execute SPI commands.
+
+  @param[in] This                 Pointer to the EFI_SPI_PROTOCOL instance.
+  @param[in] InitData             Pointer to caller-allocated buffer containing the SPI
+                                  interface initialization table.
+
+  @retval EFI_SUCCESS             Opcode initialization on the SPI host controller completed.
+  @retval EFI_ACCESS_DENIED       The SPI configuration interface is locked.
+  @retval EFI_OUT_OF_RESOURCES    Not enough resource available to initialize the device.
+  @retval EFI_DEVICE_ERROR        Device error, operation failed.
+
+**/
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SPI_LOCK) (
+  IN EFI_SPI_PROTOCOL     * This
+  );
+/**
+
+  @brief
+  Initializes the host controller to execute SPI commands.
+
+  @param[in] This                 Pointer to the EFI_SPI_PROTOCOL instance.
+  @param[in] InitData             Pointer to caller-allocated buffer containing the SPI
+                                  interface initialization table.
+
+  @retval EFI_SUCCESS             Opcode initialization on the SPI host controller completed.
+  @retval EFI_ACCESS_DENIED       The SPI configuration interface is locked.
+  @retval EFI_OUT_OF_RESOURCES    Not enough resource available to initialize the device.
+  @retval EFI_DEVICE_ERROR        Device error, operation failed.
+
+**/
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SPI_EXECUTE) (
+  IN     EFI_SPI_PROTOCOL   * This,
+  IN     UINT8              OpcodeIndex,
+  IN     UINT8              PrefixOpcodeIndex,
+  IN     BOOLEAN            DataCycle,
+  IN     BOOLEAN            Atomic,
+  IN     BOOLEAN            ShiftOut,
+  IN     UINTN              Address,
+  IN     UINT32             DataByteCount,
+  IN OUT UINT8              *Buffer,
+  IN     SPI_REGION_TYPE    SpiRegionType
+  );
+/**
+
+  @brief
+  Execute SPI commands from the host controller.
+
+  @param[in] This                 Pointer to the EFI_SPI_PROTOCOL instance.
+  @param[in] OpcodeIndex          Index of the command in the OpCode Menu.
+  @param[in] PrefixOpcodeIndex    Index of the first command to run when in an atomic cycle sequence.
+  @param[in] DataCycle            TRUE if the SPI cycle contains data
+  @param[in] Atomic               TRUE if the SPI cycle is atomic and interleave cycles are not allowed.
+  @param[in] ShiftOut             If DataByteCount is not zero, TRUE to shift data out and FALSE to shift data in.
+  @param[in] Address              In Descriptor Mode, for Descriptor Region, GbE Region, ME Region and Platform
+                                  Region, this value specifies the offset from the Region Base; for BIOS Region,
+                                  this value specifies the offset from the start of the BIOS Image. In Non
+                                  Descriptor Mode, this value specifies the offset from the start of the BIOS Image.
+                                  Please note BIOS Image size may be smaller than BIOS Region size (in Descriptor
+                                  Mode) or the flash size (in Non Descriptor Mode), and in this case, BIOS Image is
+                                  supposed to be placed at the top end of the BIOS Region (in Descriptor Mode) or
+                                  the flash (in Non Descriptor Mode)
+  @param[in] DataByteCount        Number of bytes in the data portion of the SPI cycle.
+  @param[in] Buffer               Pointer to caller-allocated buffer containing the dada received or sent during the SPI cycle.
+  @param[in] SpiRegionType        SPI Region type. Values EnumSpiRegionBios, EnumSpiRegionGbE, EnumSpiRegionMe,
+                                  EnumSpiRegionDescriptor, and EnumSpiRegionPlatformData are only applicable in
+                                  Descriptor mode. Value EnumSpiRegionAll is applicable to both Descriptor Mode
+                                  and Non Descriptor Mode, which indicates "SpiRegionOffset" is actually relative
+                                  to base of the 1st flash device (i.e., it is a Flash Linear Address).
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @exception EFI_UNSUPPORTED      Command not supported.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+
+**/
+
+///
+/// Protocol definition
+///
+struct _EFI_SPI_PROTOCOL {
+  EFI_SPI_INIT    Init;
+  EFI_SPI_LOCK    Lock;
+  EFI_SPI_EXECUTE Execute;
+};
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/TcoReset.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/TcoReset.h
new file mode 100644
index 0000000000..09be81ecbe
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Protocol/TcoReset.h
@@ -0,0 +1,88 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  TcoReset.h
+
+Abstract:
+
+  Protocol to communicate with ICH TCO.
+
+GUID Info:
+ {A6A79162-E325-4c30-BCC3-59373064EFB3}
+ 0xa6a79162, 0xe325, 0x4c30, 0xbc, 0xc3, 0x59, 0x37, 0x30, 0x64, 0xef, 0xb3);
+
+
+--*/
+
+#ifndef _TCO_RESET_H_
+#define _TCO_RESET_H_
+
+
+#define EFI_TCO_RESET_PROTOCOL_GUID  \
+  {0xa6a79162, 0xe325, 0x4c30, 0xbc, 0xc3, 0x59, 0x37, 0x30, 0x64, 0xef, 0xb3}
+
+typedef struct _EFI_TCO_RESET_PROTOCOL EFI_TCO_RESET_PROTOCOL;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCO_RESET_PROTOCOL_ENABLE_TCO_RESET) (
+  IN      UINT32            *RcrbGcsSaveValue
+  )
+/*++
+
+Routine Description:
+
+  Enables the TCO timer to reset the system in case of a system hang.  This is
+  used when writing the clock registers.
+
+Arguments:
+
+  RcrbGcsSaveValue  - This is the value of the RCRB GCS register before it is
+                      changed by this procedure.  This will be used to restore
+                      the settings of this register in PpiDisableTcoReset.
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCO_RESET_PROTOCOL_DISABLE_TCO_RESET) (
+  OUT     UINT32    RcrbGcsRestoreValue
+  )
+/*++
+
+Routine Description:
+
+  Disables the TCO timer.  This is used after writing the clock registers.
+
+Arguments:
+
+  RcrbGcsRestoreValue - Value saved in PpiEnableTcoReset so that it can
+                        restored.
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+;
+
+typedef struct _EFI_TCO_RESET_PROTOCOL {
+  EFI_TCO_RESET_PROTOCOL_ENABLE_TCO_RESET       EnableTcoReset;
+  EFI_TCO_RESET_PROTOCOL_DISABLE_TCO_RESET      DisableTcoReset;
+} EFI_TCO_RESET_PROTOCOL;
+
+extern EFI_GUID gEfiTcoResetProtocolGuid;
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Rsci.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Rsci.h
new file mode 100644
index 0000000000..f5aa2eaf86
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Rsci.h
@@ -0,0 +1,28 @@
+/*++
+Copyright (c) 1996  - 2014, Intel Corporation.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+
+
+Abstract:
+
+
+
+--*/
+
+#ifndef _RSCI_H
+#define _RSCI_H
+
+typedef enum {
+  NOT_APPLICABLE_RESET = 0,
+  WARM_RESET = 1,
+  COLD_RESET = 2,
+  GLOBAL_RESET = 7,
+}ANDROID_RESET_TYPE;
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/TianoApi.h b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/TianoApi.h
new file mode 100644
index 0000000000..784ea187c6
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/TianoApi.h
@@ -0,0 +1,61 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  TianoApi.h
+
+Abstract:
+
+  Tiano intrinsic definitions.
+
+
+--*/
+
+#ifndef _TIANO_API_H_
+#define _TIANO_API_H_
+
+//
+// Pointer to internal runtime function
+//
+#define EFI_INTERNAL_FUNCTION 0x00000002
+
+//
+// Pointer to internal runtime pointer
+//
+#define EFI_INTERNAL_POINTER  0x00000004
+
+//
+// Pointer to internal runtime pointer
+//
+#define EFI_IPF_GP_POINTER  0x00000008
+
+#define EFI_TPL_DRIVER      6
+
+//
+// EFI Event Types
+//
+#define EFI_EVENT_TIMER                         0x80000000
+#define EFI_EVENT_RUNTIME                       0x40000000
+#define EFI_EVENT_RUNTIME_CONTEXT               0x20000000
+
+#define EFI_EVENT_NOTIFY_WAIT                   0x00000100
+#define EFI_EVENT_NOTIFY_SIGNAL                 0x00000200
+
+#define EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES     0x00000201
+#define EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202
+
+#define EFI_EVENT_EFI_SIGNAL_MASK               0x000000FF
+#define EFI_EVENT_EFI_SIGNAL_MAX                4
+
+//
+// Task priority level
+//
+#define EFI_TPL_APPLICATION 4
+#define EFI_TPL_CALLBACK    8
+#define EFI_TPL_NOTIFY      16
+#define EFI_TPL_HIGH_LEVEL  31
+
+#endif
diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec b/Silicon/Intel/Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
new file mode 100644
index 0000000000..6117f179ba
--- /dev/null
+++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
@@ -0,0 +1,231 @@
+##  @file  Vlv2DeviceRefCodePkg.dec
+#
+# Copyright (c) 2012  - 2015, Intel Corporation. All rights reserved
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  DEC_SPECIFICATION              = 0x00010005
+  PACKAGE_NAME                   = Vlv2DeviceRefCodePkg
+  PACKAGE_GUID                   = E4FA0DCA-91A3-4957-9344-C10BAA0BFE5F
+  PACKAGE_VERSION                = 0.1
+
+[Ppis]
+  gVlvPolicyPpiGuid                                           = { 0x7D84B2C2, 0x22A1, 0x4372, {0xB1, 0x2C, 0xEB, 0xB2, 0x32, 0xD3, 0xA6, 0xA3}}
+  gVlvMmioPolicyPpiGuid                                       = { 0xE767BF7F, 0x4DB6, 0x5B34, {0x10, 0x11, 0x4F, 0xBE, 0x4C, 0xA7, 0xAF, 0xD2}}
+  gPeiSmbusPolicyPpiGuid                            = { 0x63b6e435, 0x32bc, 0x49c6, {0x81, 0xbd, 0xb7, 0xa1, 0xa0, 0xfe, 0x1a, 0x6c}}
+  gSeCfTPMPpiGuid                       = { 0x10e26df1, 0x8775, 0x4ee1, {0xb5, 0x0a, 0x3a, 0xe8, 0x28, 0x93, 0x70, 0x3a}}
+  gPchUsbPolicyPpiGuid                  = { 0xc02b0573, 0x2b4e, 0x4a31, {0xa3, 0x1a, 0x94, 0x56, 0x7b, 0x50, 0x44, 0x2c}}
+  gPchInitPpiGuid                       = { 0x09ea894a, 0xbe0d, 0x4230, {0xa0, 0x03, 0xed, 0xc6, 0x93, 0xb4, 0x8e, 0x95}}
+  gPchPlatformPolicyPpiGuid             = { 0x15344673, 0xD365, 0x4BE2, {0x85, 0x13, 0x14, 0x97, 0xCC, 0x07, 0x61, 0x1D}}
+  gPeiSpiPpiGuid                        = { 0xA38C6898, 0x2B5C, 0x4FF6, {0x93, 0x26, 0x2E, 0x63, 0x21, 0x2E, 0x56, 0xC2}}
+  gVlvPeiInitPpiGuid                    = { 0x09ea8911, 0xbe0d, 0x4230, {0xa0, 0x03, 0xed, 0xc6, 0x93, 0xb4, 0x8e, 0x11}}
+  gSeCUmaPpiGuid                        = { 0xcbd86677, 0x362f, 0x4c04, {0x94, 0x59, 0xa7, 0x41, 0x32, 0x6e, 0x05, 0xcf}}
+  gPeiSeCPlatformPolicyPpiGuid          = { 0x7ae3ceb7, 0x2ee2, 0x48fa, {0xaa, 0x49, 0x35, 0x10, 0xbc, 0x83, 0xca, 0xbf}}
+  gPeiHeciPpiGuid                       = { 0xEE0EA811, 0xFBD9, 0x4777, {0xB9, 0x5A, 0xBA, 0x4F, 0x71, 0x10, 0x1F, 0x74}}
+  gPeiSdhcPpiGuid                       = { 0xf4ef9d7a, 0x98c5, 0x4c1a, {0xb4, 0xd9, 0xd8, 0xd8, 0x72, 0x65, 0xbe, 0x0c}}
+  gPeiBlockIoPpiGuid                    = { 0xbc5fa650, 0xedbb, 0x4d0d, {0xb3, 0xa3, 0xd9, 0x89, 0x07, 0xf8, 0x47, 0xdf}}
+  gSeCfTPMPolicyPpiGuid                 = { 0x4fd1ba49, 0x8f90, 0x471a, {0xa2, 0xc9, 0x17, 0x3c, 0x7a, 0x73, 0x2f, 0xd0}}
+  gEfiPeiReadOnlyVariable2PpiGuid       = { 0x2ab86ef5, 0xecb5, 0x4134, {0xb5, 0x56, 0x38, 0x54, 0xca, 0x1f, 0xe1, 0xb4}}
+  gPchPeiInitPpiGuid                    = { 0xACB93B08, 0x5CDC, 0x4A8F, {0x93, 0xD4, 0x6, 0xE3, 0x42, 0xDF, 0x18, 0x2E}}
+  gPttPassThruPpiGuid                   = { 0xc5068bac, 0xa7dc, 0x42f1, {0xae, 0x80, 0xca, 0xa2, 0x4b, 0xb4, 0x90, 0x4b}}
+  
+[Protocols]
+  gEfiGlobalNvsAreaProtocolGuid         = { 0x074e1e48, 0x8132, 0x47a1, {0x8c, 0x2c, 0x3f, 0x14, 0xad, 0x9a, 0x66, 0xdc}}
+  gPpmPlatformPolicyProtocolGuid        = { 0xddabfeac, 0xef63, 0x452c, {0x8f, 0x39, 0xed, 0x7f, 0xae, 0xd8, 0x26, 0x5e}}
+  gEfiSpiProtocolGuid                   = { 0x1156efc6, 0xea32, 0x4396, {0xb5, 0xd5, 0x26, 0x93, 0x2e, 0x83, 0xc3, 0x13}}
+  gMemInfoProtocolGuid                  = { 0x6f20f7c8, 0xe5ef, 0x4f21, {0x8d, 0x19, 0xed, 0xc5, 0xf0, 0xc4, 0x96, 0xae}}
+  gEfiSdHostIoProtocolGuid              = { 0xb63f8ec7, 0xa9c9, 0x4472, {0xa4, 0xc0, 0x4d, 0x8b, 0xf3, 0x65, 0xcc, 0x51}}
+  gEfiSpiProtocolGuid                   = { 0x1156efc6, 0xea32, 0x4396, {0xb5, 0xd5, 0x26, 0x93, 0x2e, 0x83, 0xc3, 0x13}}
+  gEfiSmmSpiProtocolGuid                = { 0xD9072C35, 0xEB8F, 0x43AD, {0xA2, 0x20, 0x34, 0xD4, 0x0E, 0x2A, 0x82, 0x85}}
+  gEfiSmmIchnDispatchExProtocolGuid     = { 0x3920405B, 0xC897, 0x44DA, {0x88, 0xF3, 0x4C, 0x49, 0x8A, 0x6F, 0xF7, 0x36}}
+  gEfiPchS3SupportProtocolGuid          = { 0xE287D20B, 0xD897, 0x4E1E, {0xA5, 0xD9, 0x97, 0x77, 0x63, 0x93, 0x6A, 0x04}}
+  gPchResetProtocolGuid                 = { 0xDB63592C, 0xB8CC, 0x44C8, {0x91, 0x8C, 0x51, 0xF5, 0x34, 0x59, 0x8A, 0x5A}}
+  gPchResetCallbackProtocolGuid         = { 0x3A3300AB, 0xC929, 0x487D, {0xAB, 0x34, 0x15, 0x9B, 0xC1, 0x35, 0x62, 0xC0}}
+  gDxePchPlatformPolicyProtocolGuid     = { 0x4b0165a9, 0x61d6, 0x4e23, {0xa0, 0xb5, 0x3e, 0xc7, 0x9c, 0x2e, 0x30, 0xd5}}
+  gEfiPchInfoProtocolGuid               = { 0xD31F0400, 0x7D16, 0x4316, {0xBF, 0x88, 0x60, 0x65, 0x88, 0x3B, 0x40, 0x2B}}
+  gEfiPchExtendedResetProtocolGuid      = { 0xF0BBFCA0, 0x684E, 0x48B3, {0xBA, 0xE2, 0x6C, 0x84, 0xB8, 0x9E, 0x53, 0x39}}
+  gEfiActiveBiosProtocolGuid            = { 0xEBBE2D1B, 0x1647, 0x4BDA, {0xAB, 0x9A, 0x78, 0x63, 0xE3, 0x96, 0xD4, 0x1A}}
+  gDxeIchPlatformPolicyProtocolGuid     = { 0xf617b358, 0x12cf, 0x414a, {0xa0, 0x69, 0x60, 0x67, 0x7b, 0xda, 0x13, 0xb3}}
+  gEfiIchInfoProtocolGuid               = { 0xd31f0400, 0x7d16, 0x4316, {0xbf, 0x88, 0x60, 0x65, 0x88, 0x3b, 0x40, 0x2b}}
+  gEfiSmmIoTrapDispatchProtocolGuid     = { 0x58dc368d, 0x7bfa, 0x4e77, {0xab, 0xbc, 0x0e, 0x29, 0x41, 0x8d, 0xf9, 0x30}}
+  gEfiSmmSmbusProtocolGuid              = { 0x72e40094, 0x2ee1, 0x497a, {0x8f, 0x33, 0x4c, 0x93, 0x4a, 0x9e, 0x9c, 0x0c}}
+  gDxeVlvPlatformPolicyGuid             = { 0x5bab88ba, 0xe0e2, 0x4674, {0xb6, 0xad, 0xb8, 0x12, 0xf6, 0x88, 0x1c, 0xd6}}
+  gIgdOpRegionProtocolGuid              = { 0xcdc5dddf, 0xe79d, 0x41ec, {0xa9, 0xb0, 0x65, 0x65, 0x49, 0x0d, 0xb9, 0xd3}}
+  gEfiHeciProtocolGuid                  = { 0xcfb33810, 0x6e87, 0x4284, {0xb2, 0x03, 0xa6, 0x6a, 0xbe, 0x07, 0xf6, 0xe8}}
+  gPlatformSeCHookProtocolGuid          = { 0xbc52476e, 0xf67e, 0x4301, {0xb2, 0x62, 0x36, 0x9c, 0x48, 0x78, 0xaa, 0xc2}}
+  gEfiSeCRcInfoProtocolGuid             = { 0x11fbfdfb, 0x10d2, 0x43e6, {0xb5, 0xb1, 0xb4, 0x38, 0x6e, 0xdc, 0xcb, 0x9a}}
+  gEfiTdtProtocolGuid                   = { 0x0bf70067, 0xd53b, 0x42df, {0xb7, 0x70, 0xe9, 0x2c, 0x91, 0xc6, 0x14, 0x11}}
+  gDxePlatformSeCPolicyGuid             = { 0xf8bff014, 0x18fb, 0x4ef9, {0xb1, 0x0c, 0xae, 0x22, 0x73, 0x8d, 0xbe, 0xed}}
+  gLpssDummyProtocolGuid                = { 0xaf4cc162, 0xd41c, 0x455a, {0xab, 0x45, 0x6d, 0xbc, 0xc1, 0xcd, 0x32, 0xf3}}
+  gEfiEmmcCardInfoProtocolGuid          = { 0x1ebe5ab9, 0x2129, 0x49e7, {0x84, 0xd7, 0xee, 0xb9, 0xfc, 0xe5, 0xde, 0xdd}}
+  gEfiTdtOperationProtocolGuid          = {0xfd301ba4, 0x5e62, 0x4679,{ 0xa0, 0x6f, 0xe0, 0x9a, 0xab, 0xdd, 0x2a, 0x91}}
+  gEfiConfigFileNameGuid            = { 0x98B8D59B, 0xE8BA, 0x48EE, { 0x98, 0xDD, 0xC2, 0x95, 0x39, 0x2F, 0x1E, 0xDB }}
+  gEfiDFUResultGuid                 = { 0x14a7c46f, 0xbc02, 0x4047, { 0x9f, 0x18, 0xa5, 0xd7, 0x25, 0xd8, 0xbd, 0x19 }}
+  gPttPassThruProtocolGuid          = { 0x73e2576, 0xf6c1, 0x4b91, { 0x92, 0xa9, 0xd4, 0x67, 0x5d, 0xda, 0x34, 0xb1 } }
+  
+[Guids]
+  gEfiCPTokenSpaceGuid                  = { 0x918211ce, 0xa1d2, 0x43a0, {0xa0, 0x4e, 0x75, 0xb5, 0xbf, 0x44, 0x50, 0x0E}}
+  gEfiSmbusArpMapGuid                   = { 0x707BE83E, 0x0BF6, 0x40A5, {0xBE, 0x64, 0x34, 0xC0, 0x3A, 0xA0, 0xB8, 0xE2}}
+  gEfiMemoryConfigDataGuid              = { 0x80dbd530, 0xb74c, 0x4f11, {0x8c, 0x03, 0x41, 0x86, 0x65, 0x53, 0x28, 0x31}}
+  gEfiVLVTokenSpaceGuid                 = { 0xca452c68, 0xdf0c, 0x45c9, {0x82, 0xfb, 0xea, 0xe4, 0x2b, 0x31, 0x29, 0x46}}
+  gSataControllerDriverGuid             = { 0xbb929da9, 0x68f7, 0x4035, {0xb2, 0x2c, 0xa3, 0xbb, 0x3f, 0x23, 0xda, 0x55}}
+  gDxePchPolicyUpdateProtocolGuid       = { 0x1a819e49, 0xd8ee, 0x48cb, {0x9a, 0x9c, 0x0a, 0xa0, 0xd2, 0x81, 0x0a, 0x38}}
+  gPowerManagementAcpiTableStorageGuid  = { 0x161be597, 0xe9c5, 0x49db, {0xae, 0x50, 0xc4, 0x62, 0xab, 0x54, 0xee, 0xda}}
+  gEfiSetupVariableGuid                 = { 0xec87d643, 0xeba4, 0x4bb5, {0xa1, 0xe5, 0x3f, 0x3e, 0x36, 0xb2, 0x0d, 0xa9}}
+  gBmpImageGuid                         = { 0x878AC2CC, 0x5343, 0x46F2, {0xB5, 0x63, 0x51, 0xF8, 0x9D, 0xAF, 0x56, 0xBA}}
+  gPchInitVariableGuid                  = { 0xe6c2f70a, 0xb604, 0x4877, {0x85, 0xba, 0xde, 0xec, 0x89, 0xe1, 0x17, 0xeb}}
+  gEfiMemoryConfigDataGuid              = { 0x80dbd530, 0xb74c, 0x4f11, {0x8c, 0x03, 0x41, 0x86, 0x65, 0x53, 0x28, 0x31}}
+  gVlvRefCodePkgTokenSpaceGuid          = { 0x85768E4A, 0x6CDC, 0x444E, {0x93, 0xDF, 0x93, 0x66, 0x85, 0xB5, 0xDF, 0xCC}}
+  gSeCPlatformReadyToBootGuid           = { 0x03fdf171, 0x1d67, 0x4ace, {0xa9, 0x04, 0x3e, 0x36, 0xd3, 0x38, 0xfa, 0x74}}
+  gAmtReadyToBootGuid                   = { 0x40b09b5a, 0xf0ef, 0x4627, {0x93, 0xd5, 0x27, 0xf0, 0x4b, 0x75, 0x4d, 0x05}}
+  #
+  # According to UEFI 2.3.1 Errata C, 3.2 Globally Defined Variables.
+  # To prevent name collisions with possible future globally defined variables,
+  # other internal firmware data variables that are not defined in Table.10 must be saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE.
+  #
+  gEfiVlv2VariableGuid                  = { 0x10ba6bbe, 0xa97e, 0x41c3, {0x9a, 0x07, 0x60, 0x7a, 0xd9, 0xbd, 0x60, 0xe5}}
+
+[Includes.common]
+  .
+  ValleyView2Soc/NorthCluster/Include
+  ValleyView2Soc/SouthCluster/Include
+  ValleyView2Soc/CPU/Include
+  Include
+
+[PcdsFixedAtBuild]
+  gEfiVLVTokenSpaceGuid.PcdTCSmbaIoBaseAddress|0x1040|UINT16|0x10000207
+
+[PcdsDynamic, PcdsDynamicEx]
+  gEfiVLVTokenSpaceGuid.PcdTCSmbaIoBaseAddress|0x1040|UINT16|0x10000207
+  gEfiVLVTokenSpaceGuid.PcdEmmcManufacturerId|0|UINT8|0x10000208
+  gEfiVLVTokenSpaceGuid.PcdProductSerialNumber|0|UINT32|0x10000209
+  gEfiVLVTokenSpaceGuid.PcdMeasuredBootEnable|TRUE|BOOLEAN|0x1000020A
+  gEfiVLVTokenSpaceGuid.PcdFTPMErrorOccur|FALSE|BOOLEAN|0x1000020B
+  gEfiVLVTokenSpaceGuid.PcdFTPMErrorSkip|FALSE|BOOLEAN|0x1000020C
+  gEfiVLVTokenSpaceGuid.PcdFTPMCommand|0|UINT32|0x1000020D
+  gEfiVLVTokenSpaceGuid.PcdFTPMResponse|0|UINT32|0x1000020E
+  gEfiVLVTokenSpaceGuid.PcdFTPMNotRespond|FALSE|BOOLEAN|0x1000020F
+  gEfiVLVTokenSpaceGuid.PcdFTPMStatus|0|UINT32|0x10000210
+  gEfiVLVTokenSpaceGuid.PcdCpuLockBoxDataAddress|0x0|UINT64|0x10000211
+  gEfiVLVTokenSpaceGuid.PcdCpuSmramCpuDataAddress|0x0|UINT64|0x10000212
+  gEfiVLVTokenSpaceGuid.PcdCpuLockBoxSize|0x0|UINT64|0x10000213
+
+[PcdsFeatureFlag]
+  gVlvRefCodePkgTokenSpaceGuid.PcdCeAtaSupport|FALSE|BOOLEAN|0x12
+  gVlvRefCodePkgTokenSpaceGuid.PcdMmcSdMultiBlockSupport|TRUE|BOOLEAN|0x13
+
+[PcdsPatchableInModule]
+
+  ## Memory Down or DIMM slot.<BR><BR>
+  #  0 - DIMM<BR>
+  #  1 - Memory Down<BR>
+  # @Prompt Enable Memory Down
+  # @ValidList 0x80000001 | 0, 1
+  gVlvRefCodePkgTokenSpaceGuid.PcdEnableMemoryDown|1|UINT8|0x20000000
+  
+  ## Memory Parameter Patchable.<BR><BR>
+  #  0 - Fixed Parameter for MinnowBoard Max<BR>
+  #  1 - Patchable Parameter for Customization<BR>
+  # @Prompt Memory Parameter Patchable.
+  # @ValidList 0x80000001 | 0, 1  
+  gVlvRefCodePkgTokenSpaceGuid.PcdMemoryParameterPatchable|FALSE|BOOLEAN|0x20000010
+    
+  ## The speed of DRAM.<BR><BR>
+  #  0 - 800 MHz<BR>
+  #  1 - 1066 MHz<BR>
+  #  2 - 1333 MHz<BR>
+  #  3 - 1600 MHz<BR>
+  # @Prompt DRAM Speed
+  # @ValidList 0x80000001 | 0, 1, 2, 3
+  gVlvRefCodePkgTokenSpaceGuid.PcdDramSpeed|1|UINT8|0x20000001
+
+  ## DRAM Type.<BR><BR>
+  #  0 - DDR3<BR>
+  #  1 - DDR3L<BR>
+  #  2 - DDR3U<BR>
+  #  3 - DDR3All<BR>
+  #  4 - LPDDR2<BR>
+  #  5 - LPDDR3<BR>
+  #  6 - DDR4<BR>
+  # @Prompt DRAM Type
+  # @ValidList 0x80000001 | 0, 1, 2, 3, 4, 5, 6
+  gVlvRefCodePkgTokenSpaceGuid.PcdDramType|1|UINT8|0x20000002
+    
+  ## Please populate DIMM slot 0 if only one DIMM is supported.<BR><BR>
+  #  0 - Disable<BR>
+  #  1 - Enable<BR>
+  # @Prompt DIMM 0 Enable 
+  # @ValidList 0x80000001 | 0, 1
+  gVlvRefCodePkgTokenSpaceGuid.PcdEnableDimm0|1|UINT8|0x20000003
+
+  ## DIMM 1 has to be identical to DIMM 0.<BR><BR>
+  #  0 - Disable<BR>
+  #  1 - Enable<BR>
+  # @Prompt DIMM 1 Enable Type
+  # @ValidList 0x80000001 | 0, 1
+  gVlvRefCodePkgTokenSpaceGuid.PcdEnableDimm1|0|UINT8|0x20000004
+  
+  ## DRAM device data width.<BR><BR>
+  #  0 - x8<BR>
+  #  1 - x16<BR>
+  #  2 - x32<BR>
+  # @Prompt DIMM_DWIDTH
+  # @ValidList 0x80000001 | 0, 1, 2
+  gVlvRefCodePkgTokenSpaceGuid.PcdDimmDataWidth|1|UINT8|0x20000005
+
+  ## DRAM device data density.<BR><BR>
+  #  0 - 1 Gbit<BR>
+  #  1 - 2 Gbit<BR>
+  #  2 - 4 Gbit<BR>
+  #  3 - 8 Gbit<BR>
+  # @Prompt DIMM_Density
+  # @ValidList 0x80000001 | 0, 1, 2, 3
+  gVlvRefCodePkgTokenSpaceGuid.PcdDimmDensity|2|UINT8|0x20000006
+  
+  ## DRAM device data bus width.<BR><BR>
+  #  0 - 8 bits<BR>
+  #  1 - 16 bits<BR>
+  #  2 - 32 bits<BR>
+  #  3 - 64 bits<BR>
+  # @Prompt DIMM_BusWidth
+  # @ValidList 0x80000001 | 0, 1, 2, 3
+  gVlvRefCodePkgTokenSpaceGuid.PcdDimmBusWidth|3|UINT8|0x20000007
+
+  ## Ranks Per DIMM or Sides Per DIMM.<BR><BR>
+  #  0 - 1 Rank<BR>
+  #  1 - 2 Ranks<BR>
+  # @Prompt DIMM_Sides
+  # @ValidList 0x80000001 | 0, 1
+  gVlvRefCodePkgTokenSpaceGuid.PcdRankPerDimm|0|UINT8|0x20000008
+
+  ## tCL.<BR><BR>
+  # @Prompt tCL
+  gVlvRefCodePkgTokenSpaceGuid.PcdTcl|11|UINT8|0x20000009
+
+  ## tRP and tRCD in DRAM clk - 5:12.5ns, 6:15ns, etc.<BR><BR>   
+  # @Prompt tRP_tRCD 
+  gVlvRefCodePkgTokenSpaceGuid.PcdTrpTrcd|11|UINT8|0x2000000A
+
+  ## tWR in DRAM clk.<BR><BR>   
+  # @Prompt tWR 
+  gVlvRefCodePkgTokenSpaceGuid.PcdTwr|12|UINT8|0x2000000B
+  
+  ## tWTR in DRAM clk.<BR><BR>   
+  # @Prompt tWTR 
+  gVlvRefCodePkgTokenSpaceGuid.PcdTwtr|6|UINT8|0x2000000C
+  
+  ## tRRD in DRAM clk.<BR><BR>   
+  # @Prompt tRRD 
+  gVlvRefCodePkgTokenSpaceGuid.PcdTrrd|6|UINT8|0x2000000D
+   
+  ## tRTP in DRAM clk.<BR><BR>   
+  # @Prompt tRTP 
+  gVlvRefCodePkgTokenSpaceGuid.PcdTrtp|6|UINT8|0x2000000E
+
+  ## tFAW in DRAM clk.<BR><BR>   
+  # @Prompt tFAW 
+  gVlvRefCodePkgTokenSpaceGuid.PcdTfaw|32|UINT8|0x2000000F
-- 
2.21.0.windows.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [edk2-platforms: Patch 6/8] Platform/Vlv2TbltDevicePkg: Import Vlv2TbltDevicePkg from edk2
  2019-05-10  3:34 [edk2-platforms: Patch 0/8] Add packages from edk2 Michael D Kinney
                   ` (4 preceding siblings ...)
  2019-05-10  3:34 ` [edk2-platforms: Patch 5/8] Platform/Vlv2DeviceRefCodePkg: Import Vlv2DeviceRefCodePkg " Michael D Kinney
@ 2019-05-10  3:34 ` Michael D Kinney
  2019-05-13  2:52   ` Sun, Zailiang
  2019-05-10  3:34 ` [edk2-platforms: Patch 7/8] Drivers/OptionRomPkg: Import OptionRomPkg " Michael D Kinney
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 23+ messages in thread
From: Michael D Kinney @ 2019-05-10  3:34 UTC (permalink / raw)
  To: devel; +Cc: Zailiang Sun, Yi Qian, Michael Kubacki, Leif Lindholm,
	Ard Biesheuvel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 4285292 bytes --]

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>
---
 Platform/Intel/Vlv2TbltDevicePkg/.gitignore   |    5 +
 .../AcpiPlatform/AcpiPlatform.c               | 1338 +++++
 .../AcpiPlatform/AcpiPlatform.h               |  219 +
 .../AcpiPlatform/AcpiPlatform.inf             |   89 +
 .../AcpiPlatform/AcpiPlatformHooks.c          |  493 ++
 .../AcpiPlatform/AcpiPlatformHooks.h          |  127 +
 .../AcpiPlatform/AcpiPlatformHooksLib.h       |   91 +
 .../Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h     |   56 +
 .../FirmwareUpdate/FirmwareUpdate.c           |  922 ++++
 .../FirmwareUpdate/FirmwareUpdate.h           |  185 +
 .../FirmwareUpdate/FirmwareUpdate.inf         |   83 +
 .../FirmwareUpdate/FirmwareUpdateStrings.uni  |   45 +
 Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe   |  Bin 0 -> 499712 bytes
 Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env  |   25 +
 Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env  |   25 +
 .../Intel/Vlv2TbltDevicePkg/BiosIdx64D.env    |   25 +
 .../Intel/Vlv2TbltDevicePkg/BiosIdx64R.env    |   25 +
 .../BootScriptSaveDxe/BootScriptSaveDxe.inf   |   60 +
 .../InternalBootScriptSave.h                  |  102 +
 .../BootScriptSaveDxe/ScriptSave.c            |  626 +++
 .../Intel/Vlv2TbltDevicePkg/Build_IFWI.bat    |  200 +
 .../Intel/Vlv2TbltDevicePkg/Build_IFWI.sh     |  104 +
 Platform/Intel/Vlv2TbltDevicePkg/FCE.exe      |  Bin 0 -> 632832 bytes
 .../Capsule/GenerateCapsule/GenCapsuleAll.bat |   35 +
 .../Capsule/GenerateCapsule/GenCapsuleAll.sh  |   28 +
 .../GenerateCapsule/GenCapsuleMinnowMax.bat   |  131 +
 .../GenerateCapsule/GenCapsuleMinnowMax.sh    |   65 +
 .../GenCapsuleMinnowMaxRelease.bat            |  131 +
 .../GenCapsuleMinnowMaxRelease.sh             |   65 +
 .../GenerateCapsule/GenCapsuleSampleColor.bat |  137 +
 .../GenerateCapsule/GenCapsuleSampleColor.sh  |   70 +
 .../Feature/Capsule/GenerateCapsule/Lvfs.ddf  |   14 +
 .../LvfsGenCapsuleMinnowMax.bat               |  139 +
 .../LvfsGenCapsuleMinnowMaxRelease.bat        |  139 +
 .../LvfsGenCapsuleSampleColor.bat             |  145 +
 ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
 ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
 ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
 .../GenerateCapsule/template.metainfo.xml     |   27 +
 .../Library/FmpDeviceLib/FmpDeviceLib.c       |  589 +++
 .../Library/FmpDeviceLib/FmpDeviceLib.inf     |   46 +
 .../Library/FmpDeviceLibSample/FmpDeviceLib.c |  412 ++
 .../FmpDeviceLibSample/FmpDeviceLib.inf       |   34 +
 .../PlatformFlashAccessLib.c                  |  685 +++
 .../PlatformFlashAccessLib.inf                |   54 +
 .../SystemFirmwareDescriptor.aslc             |   83 +
 .../SystemFirmwareDescriptor.inf              |   40 +
 .../SystemFirmwareDescriptorPei.c             |   60 +
 .../SystemFirmwareUpdateConfig.ini            |   66 +
 .../SystemFirmwareUpdateConfigGcc.ini         |   66 +
 .../Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc |   55 +
 .../Vlv2TbltDevicePkg/FmpCertificate.dsc      |   22 +
 .../FmpGreenSampleDevice.dsc                  |   55 +
 .../Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc  |   59 +
 .../Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc  |   55 +
 .../FspAzaliaConfigData/AzaliaConfig.bin      |  Bin 0 -> 3708 bytes
 .../FspSupport/BootModePei/BootModePei.c      |   42 +
 .../FspSupport/BootModePei/BootModePei.inf    |   40 +
 .../FspHobProcessLibVlv2.c                    |  421 ++
 .../FspHobProcessLibVlv2.inf                  |   74 +
 .../FspPlatformSecLibVlv2.c                   |  144 +
 .../FspPlatformSecLibVlv2.inf                 |   82 +
 .../Ia32/AsmSaveSecContext.asm                |   45 +
 .../SecFspPlatformSecLibVlv2/Ia32/Fsp.inc     |   45 +
 .../Ia32/PeiCoreEntry.asm                     |  135 +
 .../Ia32/SecEntry.asm                         |  338 ++
 .../SecFspPlatformSecLibVlv2/Ia32/Stack.S     |   71 +
 .../SecFspPlatformSecLibVlv2/Ia32/Stack.asm   |   76 +
 .../SecFspPlatformSecLibVlv2/PlatformInit.c   |   36 +
 .../SecFspPlatformSecLibVlv2/SaveSecContext.c |  108 +
 .../SecGetPerformance.c                       |   83 +
 .../SecPlatformInformation.c                  |   77 +
 .../SecFspPlatformSecLibVlv2/SecRamInitData.c |   16 +
 .../SecTempRamSupport.c                       |  149 +
 .../SecFspPlatformSecLibVlv2/UartInit.c       |  192 +
 .../Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c   |   68 +
 .../Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf |   49 +
 .../Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c |  170 +
 .../FvbRuntimeDxe/FvbRuntimeDxe.inf           |   80 +
 .../FvbRuntimeDxe/FvbService.c                | 1098 ++++
 .../FvbRuntimeDxe/FvbService.h                |  182 +
 .../FvbRuntimeDxe/FvbServiceDxe.c             |  199 +
 .../FvbRuntimeDxe/FvbServiceSmm.c             |  127 +
 .../FvbRuntimeDxe/FvbSmm.inf                  |   82 +
 .../FvbRuntimeDxe/FvbSmmCommon.h              |   73 +
 .../FvbRuntimeDxe/FvbSmmDxe.c                 |  944 ++++
 .../FvbRuntimeDxe/FvbSmmDxe.h                 |  232 +
 .../FvbRuntimeDxe/FvbSmmDxe.inf               |   50 +
 Platform/Intel/Vlv2TbltDevicePkg/GenBiosId    |  Bin 0 -> 12236 bytes
 .../Intel/Vlv2TbltDevicePkg/GenBiosId.exe     |  Bin 0 -> 384000 bytes
 .../Include/AlertStandardFormatTable.h        |  122 +
 .../Vlv2TbltDevicePkg/Include/ChipsetAccess.h |   28 +
 .../Include/CommonIncludes.h                  |  115 +
 .../Intel/Vlv2TbltDevicePkg/Include/CpuType.h |   59 +
 .../Vlv2TbltDevicePkg/Include/FileHandleLib.h |  499 ++
 .../Include/Guid/AcpiTableStorage.h           |   30 +
 .../Include/Guid/AlertStandardFormat.h        |   86 +
 .../Vlv2TbltDevicePkg/Include/Guid/BiosId.h   |   30 +
 .../Include/Guid/BoardFeatures.h              |  214 +
 .../Include/Guid/EfiVpdData.h                 |  156 +
 .../Include/Guid/FirmwareId.h                 |   61 +
 .../Include/Guid/HwWatchdogTimerHob.h         |  134 +
 .../Vlv2TbltDevicePkg/Include/Guid/IdccData.h |  104 +
 .../Vlv2TbltDevicePkg/Include/Guid/ItkData.h  |   70 +
 .../Include/Guid/MemoryConfigData.h           |   32 +
 .../Include/Guid/OsSelection.h                |   85 +
 .../Include/Guid/PciLanInfo.h                 |   39 +
 .../Include/Guid/PlatformCpuInfo.h            |  180 +
 .../Include/Guid/PlatformInfo.h               |  433 ++
 .../Include/Guid/SensorInfoVariable.h         |  279 +
 .../Include/Guid/SetupVariable.h              | 1344 +++++
 .../Intel/Vlv2TbltDevicePkg/Include/Hpet.h    |   40 +
 .../Include/Library/BiosIdLib.h               |  104 +
 .../Include/Library/CpuIA32.h                 |  345 ++
 .../Include/Library/EfiRegTableLib.h          |  196 +
 .../Vlv2TbltDevicePkg/Include/Library/Esrt.h  |   74 +
 .../Vlv2TbltDevicePkg/Include/Library/Fd.h    |  264 +
 .../Include/Library/FlashDeviceLib.h          |  122 +
 .../Include/Library/I2CLib.h                  |   58 +
 .../Include/Library/I2cMmioConfigLib.h        |   23 +
 .../Include/Library/I2cPort_platform.h        |   26 +
 .../Include/Library/PlatformFsaLib.h          |   50 +
 .../Include/Library/PlatformFspLib.h          |   23 +
 .../Include/Library/SpiFlash.H                |  239 +
 .../Include/Library/StallSmmLib.h             |   40 +
 .../Include/Library/UsbDeviceModeLib.h        |  181 +
 .../Intel/Vlv2TbltDevicePkg/Include/Mcfg.h    |   69 +
 .../Vlv2TbltDevicePkg/Include/McfgTable.h     |   65 +
 .../Vlv2TbltDevicePkg/Include/Platform.h      |  133 +
 .../Include/PlatformBootMode.h                |   35 +
 .../Include/PlatformDefinitions.h             |   43 +
 .../Include/Ppi/MfgMemoryTest.h               |   42 +
 .../Include/Ppi/Sha256Hash.h                  |  131 +
 .../Vlv2TbltDevicePkg/Include/Ppi/Speaker.h   |   65 +
 .../Include/Ppi/UsbController.h               |   85 +
 .../Include/Protocol/CK505ClockPlatformInfo.h |  126 +
 .../Include/Protocol/EnhancedSpeedstep.h      |   76 +
 .../Include/Protocol/GlobalNvsArea.h          |  475 ++
 .../Include/Protocol/HwWatchdogTimer.h        |  235 +
 .../Include/Protocol/I2cAcpi.h                |  107 +
 .../Include/Protocol/I2cBus.h                 |  164 +
 .../Include/Protocol/I2cBusMcg.h              |  163 +
 .../Include/Protocol/I2cHostMcg.h             |  138 +
 .../Include/Protocol/I2cMasterMcg.h           |  519 ++
 .../Include/Protocol/I2cSlave.h               |  194 +
 .../Include/Protocol/LpcWpc83627Policy.h      |   92 +
 .../Include/Protocol/LpcWpce791Policy.h       |   55 +
 .../Include/Protocol/MmioDevice.h             |   84 +
 .../Include/Protocol/Observable.h             |  186 +
 .../Include/Protocol/PlatformGopPolicy.h      |   68 +
 .../Include/Protocol/PlatformIdeInit.h        |   43 +
 .../Include/Protocol/SetupMode.h              |   79 +
 .../Include/Protocol/SmbiosSlotPopulation.h   |   47 +
 .../Include/Protocol/Speaker.h                |   65 +
 .../Include/Protocol/TcoReset.h               |   67 +
 .../Include/Protocol/TpmMp.h                  |  136 +
 .../Include/Protocol/UsbPolicy.h              |  126 +
 .../Include/Protocol/VlvPlatformPolicy.h      |  102 +
 .../Vlv2TbltDevicePkg/Include/SetupMode.h     |   85 +
 .../IntelGopDepex/IntelGopDriver.depex        |    1 +
 .../Library/BiosIdLib/BiosIdLib.c             |  337 ++
 .../Library/BiosIdLib/BiosIdLib.inf           |   50 +
 .../Library/CpuIA32Lib/CpuIA32Lib.inf         |   41 +
 .../Library/CpuIA32Lib/EfiCpuVersion.c        |   70 +
 .../Library/CpuIA32Lib/IA32/CpuIA32.S         |  223 +
 .../Library/CpuIA32Lib/IA32/CpuIA32.asm       |  206 +
 .../Library/CpuIA32Lib/IA32/CpuIA32.c         |  177 +
 .../Library/CpuIA32Lib/X64/Cpu.S              |  207 +
 .../Library/CpuIA32Lib/X64/Cpu.asm            |  222 +
 .../Library/EfiRegTableLib/EfiRegTableLib.c   |  282 ++
 .../Library/EfiRegTableLib/EfiRegTableLib.inf |   47 +
 .../Library/FlashDeviceLib/FlashDeviceLib.c   |  461 ++
 .../Library/FlashDeviceLib/FlashDeviceLib.inf |   44 +
 .../FlashDeviceLib/FlashDeviceLibDxe.c        |   56 +
 .../FlashDeviceLib/FlashDeviceLibDxe.inf      |   43 +
 .../FlashDeviceLibDxeRuntimeSmm.c             |  173 +
 .../FlashDeviceLib/SpiChipDefinitions.h       |  835 +++
 .../Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c |   46 +
 .../Library/I2CLib/I2CLibNull.inf             |   39 +
 .../Library/I2CLibDxe/I2CLib.c                |  735 +++
 .../Library/I2CLibDxe/I2CLibDxe.inf           |   39 +
 .../Library/I2CLibDxe/I2CRegs.h               |  126 +
 .../Library/I2CLibPei/I2CAccess.h             |   44 +
 .../Library/I2CLibPei/I2CDelayPei.c           |   46 +
 .../Library/I2CLibPei/I2CDelayPei.h           |   30 +
 .../Library/I2CLibPei/I2CIoLibPei.c           |  178 +
 .../Library/I2CLibPei/I2CIoLibPei.h           |  153 +
 .../Library/I2CLibPei/I2CLibPei.c             |  638 +++
 .../Library/I2CLibPei/I2CLibPei.h             |  280 +
 .../Library/I2CLibPei/I2CLibPei.inf           |   40 +
 .../IntelPchAcpiTimerLib/CommonHeader.h       |   27 +
 .../IntelPchAcpiTimerLib.c                    |  255 +
 .../IntelPchAcpiTimerLib.inf                  |   51 +
 .../BoardClkGens/BoardClkGens.c               |  430 ++
 .../BoardClkGens/BoardClkGens.h               |  255 +
 .../MultiPlatformLib/BoardGpios/BoardGpios.c  |  531 ++
 .../MultiPlatformLib/BoardGpios/BoardGpios.h  |  324 ++
 .../BoardJumpers/BoardJumpers.c               |   30 +
 .../BoardJumpers/BoardJumpers.h               |   30 +
 .../BoardOemIds/BoardOemIds.c                 |   43 +
 .../BoardOemIds/BoardOemIds.h                 |   29 +
 .../BoardSsidSvid/BoardSsidSvid.c             |   38 +
 .../BoardSsidSvid/BoardSsidSvid.h             |   35 +
 .../MultiPlatformLib/MultiPlatformLib.c       |  120 +
 .../MultiPlatformLib/MultiPlatformLib.h       |   89 +
 .../MultiPlatformLib/MultiPlatformLib.inf     |   77 +
 .../MultiPlatformLib/PlatformInfoHob.c        |   54 +
 .../Library/PchPlatformLib/PchPlatformLib.inf |   50 +
 .../PchPlatformLib/PchPlatformLibrary.c       |  131 +
 .../PchPlatformLib/PchPlatformLibrary.h       |   35 +
 .../Library/PchSmmLib/CommonHeader.h          |   32 +
 .../Library/PchSmmLib/PchSmmLib.c             |  157 +
 .../Library/PchSmmLib/PchSmmLib.inf           |   46 +
 .../Library/PlatformBdsLib/BdsPlatform.c      | 3098 ++++++++++++
 .../Library/PlatformBdsLib/BdsPlatform.h      |  516 ++
 .../Library/PlatformBdsLib/PlatformBdsLib.inf |  127 +
 .../PlatformBdsLib/PlatformBdsStrings.uni     |   30 +
 .../Library/PlatformBdsLib/PlatformData.c     |  306 ++
 .../Library/PlatformCmosLib/PlatformCmosLib.c |  106 +
 .../PlatformCmosLib/PlatformCmosLib.inf       |   30 +
 .../Library/PlatformFspLib/PlatformFspLib.c   |   44 +
 .../Library/PlatformFspLib/PlatformFspLib.inf |   49 +
 .../Library/ResetSystemLib/ResetSystemLib.c   |  235 +
 .../Library/ResetSystemLib/ResetSystemLib.inf |   47 +
 .../SerialPortLib/PlatformSerialPortLib.h     |   53 +
 .../Library/SerialPortLib/SerialPortLib.c     |  246 +
 .../Library/SerialPortLib/SerialPortLib.inf   |   52 +
 .../Library/SerialPortLib/SioInit.c           |  127 +
 .../Library/SerialPortLib/SioInit.h           |   62 +
 .../Library/SmbusLib/CommonHeader.h           |   26 +
 .../Library/SmbusLib/SmbusLib.c               |  873 ++++
 .../Library/SmbusLib/SmbusLib.inf             |   46 +
 .../Library/StallSmmLib/StallSmm.c            |   89 +
 .../Library/StallSmmLib/StallSmmLib.inf       |   51 +
 .../Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.c    |  117 +
 .../Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.inf  |   61 +
 .../Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.c    |  145 +
 .../Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.inf  |   60 +
 .../Intel/Vlv2TbltDevicePkg/Logo/Logo.bmp     |  Bin 0 -> 94434 bytes
 .../Metronome/LegacyMetronome.c               |  185 +
 .../Metronome/LegacyMetronome.h               |   64 +
 .../Vlv2TbltDevicePkg/Metronome/Metronome.inf |   49 +
 .../MonoStatusCode/EfiStatusCode.h            |  178 +
 .../MonoStatusCode/MonoStatusCode.c           |  132 +
 .../MonoStatusCode/MonoStatusCode.h           |  128 +
 .../MonoStatusCode/MonoStatusCode.inf         |   72 +
 .../MonoStatusCode/PeiPostCode.c              |  121 +
 .../MonoStatusCode/PlatformStatusCode.c       |  381 ++
 .../MonoStatusCode/PlatformStatusCode.h       |  138 +
 .../Library/GenericBdsLib/BdsBoot.c           | 4490 +++++++++++++++++
 .../Library/GenericBdsLib/BdsConnect.c        |  429 ++
 .../Library/GenericBdsLib/BdsConsole.c        | 1061 ++++
 .../Library/GenericBdsLib/BdsMisc.c           | 1575 ++++++
 .../Library/GenericBdsLib/DevicePath.c        |   27 +
 .../Library/GenericBdsLib/GenericBdsLib.inf   |  142 +
 .../Library/GenericBdsLib/GenericBdsLib.uni   |   19 +
 .../GenericBdsLib/GenericBdsStrings.uni       |   30 +
 .../Library/GenericBdsLib/InternalBdsLib.h    |  173 +
 .../Library/GenericBdsLib/String.c            |   26 +
 .../Library/GenericBdsLib/String.h            |   42 +
 .../PciPlatform/BoardPciPlatform.c            |   55 +
 .../PciPlatform/PciPlatform.c                 |  367 ++
 .../PciPlatform/PciPlatform.h                 |   83 +
 .../PciPlatform/PciPlatform.inf               |   65 +
 .../Vlv2TbltDevicePkg/PlatformCapsule.dsc     |   39 +
 .../Vlv2TbltDevicePkg/PlatformCapsule.fdf     |   52 +
 .../Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc  |   38 +
 .../Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf  |   52 +
 .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.c   |   60 +
 .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.h   |   29 +
 .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf |   55 +
 .../PlatformDxe/AzaliaVerbTable.h             |  247 +
 .../Vlv2TbltDevicePkg/PlatformDxe/BoardId.c   |  223 +
 .../PlatformDxe/BoardIdDecode.c               |  129 +
 .../PlatformDxe/BoardIdDecode.h               |   61 +
 .../PlatformDxe/ClockControl.c                |  202 +
 .../PlatformDxe/Configuration.h               |  692 +++
 .../Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c |   89 +
 .../PlatformDxe/IchPlatformPolicy.c           |  484 ++
 .../PlatformDxe/IchRegTable.c                 |  134 +
 .../PlatformDxe/IchTcoReset.c                 |  211 +
 .../Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c  |   72 +
 .../PlatformDxe/LegacySpeaker.c               |  161 +
 .../PlatformDxe/LegacySpeaker.h               |   69 +
 .../PlatformDxe/Observable/Observable.c       |  582 +++
 .../PlatformDxe/Observable/Observable.h       |  137 +
 .../Vlv2TbltDevicePkg/PlatformDxe/PciBus.h    |  379 ++
 .../Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c |  506 ++
 .../Vlv2TbltDevicePkg/PlatformDxe/Platform.c  | 1820 +++++++
 .../PlatformDxe/PlatformDxe.h                 |  722 +++
 .../PlatformDxe/PlatformDxe.inf               |  149 +
 .../Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c |  154 +
 .../Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c |  112 +
 .../PlatformDxe/SioPlatformPolicy.c           |   82 +
 .../PlatformDxe/SlotConfig.c                  |  148 +
 .../PlatformDxe/SlotConfig.h                  |   80 +
 .../PlatformGopPolicy/PlatformGopPolicy.c     |  201 +
 .../PlatformGopPolicy/PlatformGopPolicy.inf   |   51 +
 .../PlatformInfoDxe/PlatformInfoDxe.c         |  169 +
 .../PlatformInfoDxe/PlatformInfoDxe.h         |   30 +
 .../PlatformInfoDxe/PlatformInfoDxe.inf       |   52 +
 .../PlatformInitPei/BootMode.c                |  434 ++
 .../PlatformInitPei/CpuInitPeim.c             |   44 +
 .../Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c  |  319 ++
 .../PlatformInitPei/FlashMap.c                |  143 +
 .../PlatformInitPei/LegacySpeaker.c           |  168 +
 .../PlatformInitPei/LegacySpeaker.h           |   71 +
 .../PlatformInitPei/MchInit.c                 |   72 +
 .../PlatformInitPei/MemoryCallback.c          |  338 ++
 .../PlatformInitPei/MemoryPeim.c              |  408 ++
 .../PlatformInitPei/PchInitPeim.c             |  808 +++
 .../PlatformInitPei/PlatformEarlyInit.c       | 1195 +++++
 .../PlatformInitPei/PlatformEarlyInit.h       | 1499 ++++++
 .../PlatformInitPei/PlatformInfoInit.c        |  181 +
 .../PlatformInitPei/PlatformInitPei.inf       |  117 +
 .../PlatformInitPei/PlatformSsaInitPeim.c     |   58 +
 .../PlatformInitPei/Recovery.c                |  361 ++
 .../Vlv2TbltDevicePkg/PlatformInitPei/Stall.c |   91 +
 .../Vlv2TbltDevicePkg/PlatformPei/BootMode.c  |  346 ++
 .../PlatformPei/CommonHeader.h                |   60 +
 .../PlatformPei/MemoryCallback.c              |  154 +
 .../Vlv2TbltDevicePkg/PlatformPei/Platform.c  | 1198 +++++
 .../Vlv2TbltDevicePkg/PlatformPei/Platform.h  |  213 +
 .../PlatformPei/PlatformPei.inf               |  129 +
 .../Vlv2TbltDevicePkg/PlatformPei/Stall.c     |   90 +
 .../Intel/Vlv2TbltDevicePkg/PlatformPkg.dec   |  211 +
 .../Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf   | 1073 ++++
 .../Vlv2TbltDevicePkg/PlatformPkgConfig.dsc   |  107 +
 .../Vlv2TbltDevicePkg/PlatformPkgGcc.fdf      | 1033 ++++
 .../Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc   | 1711 +++++++
 .../Vlv2TbltDevicePkg/PlatformPkgIA32.dsc     | 1699 +++++++
 .../Vlv2TbltDevicePkg/PlatformPkgX64.dsc      | 1714 +++++++
 .../PlatformSetupDxe/Boot.vfi                 |   72 +
 .../PlatformSetupDxe/Configuration.h          |   56 +
 .../PlatformSetupDxe/DebugConfig.vfi          |  118 +
 .../PlatformSetupDxe/FwVersionStrings.uni     |   40 +
 .../PlatformSetupDxe/Main.vfi                 |  331 ++
 .../PlatformSetupDxe/PlatformSetupDxe.c       |  929 ++++
 .../PlatformSetupDxe/PlatformSetupDxe.h       |   97 +
 .../PlatformSetupDxe/PlatformSetupDxe.inf     |  141 +
 .../PlatformSetupDxe/Security.vfi             |  104 +
 .../PlatformSetupDxe/SetupFunctions.c         |   85 +
 .../PlatformSetupDxe/SetupInfoRecords.c       | 1855 +++++++
 .../PlatformSetupDxe/SouthClusterConfig.vfi   |  933 ++++
 .../PlatformSetupDxe/SystemComponent.vfi      |   81 +
 .../PlatformSetupDxe/Thermal.vfi              |  106 +
 .../PlatformSetupDxe/UnCore.vfi               |  235 +
 .../PlatformSetupDxe/UqiList.uni              |  452 ++
 .../PlatformSetupDxe/Vfr.vfr                  |  123 +
 .../PlatformSetupDxe/VfrStrings.uni           | 1417 ++++++
 .../Vlv2TbltDevicePkg/PlatformSmm/Platform.c  |  997 ++++
 .../PlatformSmm/PlatformSmm.inf               |   93 +
 .../Vlv2TbltDevicePkg/PlatformSmm/S3Save.c    |  377 ++
 .../PlatformSmm/SmmPlatform.h                 |  240 +
 .../PlatformSmm/SmmScriptSave.c               |  252 +
 .../PlatformSmm/SmmScriptSave.h               |   50 +
 .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c   |  148 +
 .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h   |   36 +
 .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf |   49 +
 Platform/Intel/Vlv2TbltDevicePkg/Readme.md    |  233 +
 .../SaveMemoryConfig/SaveMemoryConfig.c       |  181 +
 .../SaveMemoryConfig/SaveMemoryConfig.h       |   66 +
 .../SaveMemoryConfig/SaveMemoryConfig.inf     |   60 +
 .../SmBiosMiscDxe/CommonHeader.h              |   39 +
 .../MiscBaseBoardManufacturer.uni             |   33 +
 .../MiscBaseBoardManufacturerData.c           |   58 +
 .../MiscBaseBoardManufacturerFunction.c       |  238 +
 .../SmBiosMiscDxe/MiscBiosVendor.uni          |   26 +
 .../SmBiosMiscDxe/MiscBiosVendorData.c        |  101 +
 .../SmBiosMiscDxe/MiscBiosVendorFunction.c    |  336 ++
 .../SmBiosMiscDxe/MiscBootInformationData.c   |   34 +
 .../MiscBootInformationFunction.c             |   82 +
 .../SmBiosMiscDxe/MiscChassisManufacturer.uni |   28 +
 .../MiscChassisManufacturerData.c             |   57 +
 .../MiscChassisManufacturerFunction.c         |  158 +
 .../SmBiosMiscDxe/MiscMemoryDevice.uni        |   35 +
 .../SmBiosMiscDxe/MiscMemoryDeviceData.c      |   45 +
 .../SmBiosMiscDxe/MiscMemoryDeviceFunction.c  |  319 ++
 .../MiscNumberOfInstallableLanguagesData.c    |   38 +
 ...MiscNumberOfInstallableLanguagesFunction.c |  251 +
 .../SmBiosMiscDxe/MiscOemString.uni           |   25 +
 .../SmBiosMiscDxe/MiscOemStringData.c         |   34 +
 .../SmBiosMiscDxe/MiscOemStringFunction.c     |   89 +
 .../SmBiosMiscDxe/MiscOemType0x90.uni         |   31 +
 .../SmBiosMiscDxe/MiscOemType0x90Data.c       |   36 +
 .../SmBiosMiscDxe/MiscOemType0x90Function.c   |  442 ++
 .../SmBiosMiscDxe/MiscOemType0x94.uni         |   42 +
 .../SmBiosMiscDxe/MiscOemType0x94Data.c       |   54 +
 .../SmBiosMiscDxe/MiscOemType0x94Function.c   | 1218 +++++
 .../SmBiosMiscDxe/MiscOnboardDevice.uni       |   26 +
 .../SmBiosMiscDxe/MiscOnboardDeviceData.c     |   48 +
 .../SmBiosMiscDxe/MiscOnboardDeviceFunction.c |  135 +
 .../SmBiosMiscDxe/MiscPhysicalArray.uni       |   25 +
 .../SmBiosMiscDxe/MiscPhysicalArrayData.c     |   38 +
 .../SmBiosMiscDxe/MiscPhysicalArrayFunction.c |  101 +
 .../MiscPortInternalConnectorDesignator.uni   |   31 +
 .../MiscPortInternalConnectorDesignatorData.c |   56 +
 ...cPortInternalConnectorDesignatorFunction.c |  152 +
 .../SmBiosMiscDxe/MiscProcessorCache.uni      |   22 +
 .../SmBiosMiscDxe/MiscProcessorCacheData.c    |   33 +
 .../MiscProcessorCacheFunction.c              |  189 +
 .../MiscProcessorInformation.uni              |   27 +
 .../MiscProcessorInformationData.c            |   71 +
 .../MiscProcessorInformationFunction.c        |  448 ++
 .../SmBiosMiscDxe/MiscResetCapabilitiesData.c |   43 +
 .../MiscResetCapabilitiesFunction.c           |   85 +
 .../SmBiosMiscDxe/MiscSubclassDriver.h        |  188 +
 .../SmBiosMiscDxe/MiscSubclassDriver.uni      |   35 +
 .../MiscSubclassDriverDataTable.c             |   98 +
 .../MiscSubclassDriverEntryPoint.c            |  182 +
 .../MiscSystemLanguageString.uni              |   24 +
 .../MiscSystemLanguageStringData.c            |   34 +
 .../MiscSystemLanguageStringFunction.c        |   93 +
 .../SmBiosMiscDxe/MiscSystemManufacturer.uni  |   30 +
 .../MiscSystemManufacturerData.c              |   48 +
 .../MiscSystemManufacturerFunction.c          |  364 ++
 .../SmBiosMiscDxe/MiscSystemOptionString.uni  |   24 +
 .../MiscSystemOptionStringData.c              |   31 +
 .../MiscSystemOptionStringFunction.c          |   93 +
 .../MiscSystemSlotDesignation.uni             |   34 +
 .../MiscSystemSlotDesignationData.c           |  246 +
 .../MiscSystemSlotDesignationFunction.c       |  127 +
 .../SmBiosMiscDxe/SmBiosMiscDxe.inf           |  139 +
 .../SmmSwDispatch2OnSmmSwDispatchThunk.c      |  459 ++
 .../SmmSwDispatch2OnSmmSwDispatchThunk.inf    |   54 +
 .../SmramSaveInfoHandlerSmm.c                 |  164 +
 .../SmramSaveInfoHandlerSmm.inf               |   60 +
 .../Stitch/Gcc/NvStorageFtwSpare.bin          |  Bin 0 -> 262144 bytes
 .../Stitch/Gcc/NvStorageFtwWorking.bin        |  Bin 0 -> 8192 bytes
 .../Stitch/Gcc/NvStorageVariable.bin          |  Bin 0 -> 253952 bytes
 .../Stitch/IFWIHeader/IFWI_HEADER.bin         |  Bin 0 -> 4096 bytes
 .../Stitch/IFWIHeader/IFWI_HEADER_SPILOCK.bin |  Bin 0 -> 4096 bytes
 .../Stitch/IFWIHeader/Vacant.bin              |  Bin 0 -> 3928064 bytes
 .../Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat   |  270 +
 .../Stitch/MNW2_Stitch_Config.txt             |   10 +
 .../Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c |   33 +
 .../Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf   |   32 +
 .../VlvPlatformInitDxe/IgdOpRegion.c          |  929 ++++
 .../VlvPlatformInitDxe/IgdOpRegion.h          |  235 +
 .../VlvPlatformInitDxe/VlvPlatformInit.c      |  287 ++
 .../VlvPlatformInitDxe/VlvPlatformInit.h      |   65 +
 .../VlvPlatformInitDxe/VlvPlatformInitDxe.inf |   74 +
 .../Vlv2TbltDevicePkg/Wpce791/LpcDriver.c     |  340 ++
 .../Vlv2TbltDevicePkg/Wpce791/LpcDriver.h     |  112 +
 .../Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c    |  366 ++
 .../Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h    |  103 +
 .../Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c  |  126 +
 .../Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h  |  101 +
 .../Vlv2TbltDevicePkg/Wpce791/Wpce791.inf     |   63 +
 Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat  |  332 ++
 Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh   |  256 +
 Platform/Intel/Vlv2TbltDevicePkg/cln.sh       |   62 +
 452 files changed, 95411 insertions(+)
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/.gitignore
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooksLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdate.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdate.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdate.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdateStrings.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64D.env
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64R.env
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/BootScriptSaveDxe.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/InternalBootScriptSave.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/ScriptSave.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.bat
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.sh
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FCE.exe
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleAll.bat
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleAll.sh
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMax.bat
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMax.sh
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMaxRelease.bat
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMaxRelease.sh
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleSampleColor.bat
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleSampleColor.sh
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Lvfs.ddf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGenCapsuleMinnowMax.bat
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGenCapsuleMinnowMaxRelease.bat
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGenCapsuleSampleColor.bat
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/NewRoot.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMPLE_DEVELOPMENT.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMPLE_DEVELOPMENT_SAMPLE_PRODUCTION.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/template.metainfo.xml
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptor.aslc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptor.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptorPei.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdateConfig/SystemFirmwareUpdateConfig.ini
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdateConfig/SystemFirmwareUpdateConfigGcc.ini
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FmpCertificate.dsc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FmpGreenSampleDevice.dsc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspAzaliaConfigData/AzaliaConfig.bin
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLibVlv2/FspHobProcessLibVlv2.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLibVlv2/FspHobProcessLibVlv2.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/FspPlatformSecLibVlv2.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/FspPlatformSecLibVlv2.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/AsmSaveSecContext.asm
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Fsp.inc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/PeiCoreEntry.asm
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/SecEntry.asm
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Stack.S
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Stack.asm
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/PlatformInit.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SaveSecContext.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecGetPerformance.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecPlatformInformation.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecRamInitData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecTempRamSupport.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/UartInit.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbRuntimeDxe.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceDxe.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceSmm.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmm.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmCommon.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.inf
 create mode 100755 Platform/Intel/Vlv2TbltDevicePkg/GenBiosId
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/GenBiosId.exe
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/AlertStandardFormatTable.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/ChipsetAccess.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/CommonIncludes.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/CpuType.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/FileHandleLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AcpiTableStorage.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AlertStandardFormat.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BiosId.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BoardFeatures.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/EfiVpdData.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/FirmwareId.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/HwWatchdogTimerHob.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/IdccData.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/ItkData.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/MemoryConfigData.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/OsSelection.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PciLanInfo.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformCpuInfo.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformInfo.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SensorInfoVariable.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SetupVariable.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Hpet.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/BiosIdLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/CpuIA32.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/EfiRegTableLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Esrt.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Fd.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/FlashDeviceLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2CLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cMmioConfigLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cPort_platform.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFsaLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFspLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/SpiFlash.H
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/StallSmmLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/UsbDeviceModeLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Mcfg.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/McfgTable.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Platform.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformBootMode.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformDefinitions.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/MfgMemoryTest.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Sha256Hash.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Speaker.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/UsbController.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/CK505ClockPlatformInfo.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/EnhancedSpeedstep.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/GlobalNvsArea.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/HwWatchdogTimer.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cAcpi.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBus.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBusMcg.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cHostMcg.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cMasterMcg.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cSlave.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpc83627Policy.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpce791Policy.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/MmioDevice.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Observable.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformGopPolicy.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformIdeInit.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SetupMode.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SmbiosSlotPopulation.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Speaker.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TcoReset.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TpmMp.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/UsbPolicy.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/VlvPlatformPolicy.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/SetupMode.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/IntelGopDepex/IntelGopDriver.depex
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/CpuIA32Lib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/EfiCpuVersion.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.S
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.asm
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.S
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.asm
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxe.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxe.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxeRuntimeSmm.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/SpiChipDefinitions.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLibNull.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLibDxe.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CRegs.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CAccess.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/CommonHeader.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens/BoardClkGens.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens/BoardClkGens.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/BoardGpios.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/BoardGpios.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers/BoardJumpers.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers/BoardJumpers.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/BoardOemIds.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/BoardOemIds.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid/BoardSsidSvid.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid/BoardSsidSvid.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/PlatformInfoHob.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibrary.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibrary.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/CommonHeader.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsStrings.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmosLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmosLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/PlatformSerialPortLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/CommonHeader.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmm.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmmLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Logo/Logo.bmp
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Metronome/Metronome.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/EfiStatusCode.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PeiPostCode.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConnect.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/DevicePath.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsStrings.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/InternalBdsLib.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/BoardPciPlatform.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.dsc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.fdf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/AzaliaVerbTable.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardId.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ClockControl.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Configuration.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchPlatformPolicy.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchRegTable.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchTcoReset.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciBus.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Platform.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SioPlatformPolicy.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/BootMode.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/CpuInitPeim.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/FlashMap.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MchInit.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryCallback.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryPeim.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PchInitPeim.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInfoInit.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInitPei.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformSsaInitPeim.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Recovery.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Stall.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/BootMode.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/CommonHeader.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/MemoryCallback.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/PlatformPei.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Stall.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.dec
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgConfig.dsc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGcc.fdf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgIA32.dsc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgX64.dsc
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Boot.vfi
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Configuration.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/DebugConfig.vfi
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/FwVersionStrings.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Main.vfi
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Security.vfi
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupFunctions.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupInfoRecords.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SouthClusterConfig.vfi
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SystemComponent.vfi
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Thermal.vfi
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UnCore.vfi
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UqiList.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Vfr.vfr
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/VfrStrings.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/Platform.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/PlatformSmm.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/S3Save.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmPlatform.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Readme.md
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/CommonHeader.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufacturer.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufacturerData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufacturerFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendor.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturer.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturerData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturerFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDevice.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstallableLanguagesData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstallableLanguagesFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemString.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Data.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Function.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Data.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Function.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDevice.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArray.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnectorDesignator.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnectorDesignatorData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnectorDesignatorFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCache.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformation.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformationData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformationFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverDataTable.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverEntryPoint.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageString.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageStringData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageStringFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacturer.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacturerData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacturerFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionString.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStringData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStringFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignation.uni
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignationData.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignationFunction.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/SmBiosMiscDxe.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchThunk/SmmSwDispatch2OnSmmSwDispatchThunk.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchThunk/SmmSwDispatch2OnSmmSwDispatchThunk.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwSpare.bin
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwWorking.bin
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageVariable.bin
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_HEADER.bin
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_HEADER_SPILOCK.bin
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/Vacant.bin
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Stitch/MNW2_Stitch_Config.txt
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInitDxe.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/Wpce791.inf
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh
 create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/cln.sh

diff --git a/Platform/Intel/Vlv2TbltDevicePkg/.gitignore b/Platform/Intel/Vlv2TbltDevicePkg/.gitignore
new file mode 100644
index 0000000000..c7698262ad
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/.gitignore
@@ -0,0 +1,5 @@
+AutoPlatformCFG.txt
+Stitch/Stitching.log
+Stitch/MNW*.bin
+Stitch/MNW*.rom
+Stitch/MNW*.rom.orig
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.c b/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.c
new file mode 100644
index 0000000000..5c03f66edb
--- /dev/null
+++ b/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));
+}
+
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.h b/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.h
new file mode 100644
index 0000000000..598756846a
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.inf b/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.inf
new file mode 100644
index 0000000000..c59920db03
--- /dev/null
+++ b/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
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.c b/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.c
new file mode 100644
index 0000000000..ebe783e29e
--- /dev/null
+++ b/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;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.h b/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.h
new file mode 100644
index 0000000000..4718949610
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooksLib.h b/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooksLib.h
new file mode 100644
index 0000000000..a253d64ec0
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h b/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h
new file mode 100644
index 0000000000..4d98db7592
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdate.c b/Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdate.c
new file mode 100644
index 0000000000..a2fc54e20e
--- /dev/null
+++ b/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;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdate.h b/Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdate.h
new file mode 100644
index 0000000000..745fb3aca4
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdate.inf b/Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdate.inf
new file mode 100644
index 0000000000..25104a86ed
--- /dev/null
+++ b/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 
\ No newline at end of file
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdateStrings.uni b/Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdateStrings.uni
new file mode 100644
index 0000000000..9418edfbf9
--- /dev/null
+++ b/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"
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe b/Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe
new file mode 100644
index 0000000000000000000000000000000000000000..4402a78456ae1018915ac4a1fce5d5d5de656652
GIT binary patch
literal 499712
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
K9QaSjfqw%w5I}YS

literal 0
HcmV?d00001

diff --git a/Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env b/Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env
new file mode 100644
index 0000000000..85313dfbd7
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env b/Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env
new file mode 100644
index 0000000000..4af249dc19
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64D.env b/Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64D.env
new file mode 100644
index 0000000000..a2173b7e44
--- /dev/null
+++ b/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 
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64R.env b/Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64R.env
new file mode 100644
index 0000000000..c235177e1b
--- /dev/null
+++ b/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 
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/BootScriptSaveDxe.inf b/Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/BootScriptSaveDxe.inf
new file mode 100644
index 0000000000..d2fa621096
--- /dev/null
+++ b/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
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/InternalBootScriptSave.h b/Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/InternalBootScriptSave.h
new file mode 100644
index 0000000000..f232281e2b
--- /dev/null
+++ b/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_
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/ScriptSave.c b/Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/ScriptSave.c
new file mode 100644
index 0000000000..837a8c95cd
--- /dev/null
+++ b/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
+                  );
+
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.bat b/Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.bat
new file mode 100644
index 0000000000..887206703a
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.sh b/Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.sh
new file mode 100644
index 0000000000..4a11a1cba9
--- /dev/null
+++ b/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 ======================================================================
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FCE.exe b/Platform/Intel/Vlv2TbltDevicePkg/FCE.exe
new file mode 100644
index 0000000000000000000000000000000000000000..18300115d08320c40843a8c6ff69e37db83d6a5e
GIT binary patch
literal 632832
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%0DuSkC*9Ekqq@Yo|u
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
S@?P5ULO$Ea$Ja;8f&T|O4^B`3

literal 0
HcmV?d00001

diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleAll.bat b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleAll.bat
new file mode 100644
index 0000000000..8f589565fa
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleAll.sh b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleAll.sh
new file mode 100644
index 0000000000..040024553a
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMax.bat b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMax.bat
new file mode 100644
index 0000000000..6e4afd201e
--- /dev/null
+++ b/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%
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMax.sh b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMax.sh
new file mode 100644
index 0000000000..4fb963c93c
--- /dev/null
+++ b/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
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMaxRelease.bat b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMaxRelease.bat
new file mode 100644
index 0000000000..43c609e4b2
--- /dev/null
+++ b/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%
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMaxRelease.sh b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMaxRelease.sh
new file mode 100644
index 0000000000..29d46dad1e
--- /dev/null
+++ b/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
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleSampleColor.bat b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleSampleColor.bat
new file mode 100644
index 0000000000..3e9f94c530
--- /dev/null
+++ b/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%
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleSampleColor.sh b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleSampleColor.sh
new file mode 100644
index 0000000000..a1c6f28cde
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Lvfs.ddf b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Lvfs.ddf
new file mode 100644
index 0000000000..f2c925a6dd
--- /dev/null
+++ b/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
+;***
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGenCapsuleMinnowMax.bat b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGenCapsuleMinnowMax.bat
new file mode 100644
index 0000000000..dd8274a1cc
--- /dev/null
+++ b/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%
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGenCapsuleMinnowMaxRelease.bat b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGenCapsuleMinnowMaxRelease.bat
new file mode 100644
index 0000000000..2b68a98f98
--- /dev/null
+++ b/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%
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGenCapsuleSampleColor.bat b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGenCapsuleSampleColor.bat
new file mode 100644
index 0000000000..1dbbe7341d
--- /dev/null
+++ b/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%
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/NewRoot.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/NewRoot.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
new file mode 100644
index 0000000000..d3f5a12faa
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/NewRoot.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
@@ -0,0 +1 @@
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMPLE_DEVELOPMENT.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMPLE_DEVELOPMENT.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
new file mode 100644
index 0000000000..d3f5a12faa
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMPLE_DEVELOPMENT.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
@@ -0,0 +1 @@
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMPLE_DEVELOPMENT_SAMPLE_PRODUCTION.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMPLE_DEVELOPMENT_SAMPLE_PRODUCTION.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
new file mode 100644
index 0000000000..d3f5a12faa
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMPLE_DEVELOPMENT_SAMPLE_PRODUCTION.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
@@ -0,0 +1 @@
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/template.metainfo.xml b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/template.metainfo.xml
new file mode 100644
index 0000000000..5d550c1f48
--- /dev/null
+++ b/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>
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.c b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.c
new file mode 100644
index 0000000000..a863d69381
--- /dev/null
+++ b/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;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.inf b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.inf
new file mode 100644
index 0000000000..6fd618974f
--- /dev/null
+++ b/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
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.c b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.c
new file mode 100644
index 0000000000..80ce83a14b
--- /dev/null
+++ b/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;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.inf b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.inf
new file mode 100644
index 0000000000..af31fbcffb
--- /dev/null
+++ b/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
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.c b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.c
new file mode 100644
index 0000000000..079c3ef2d6
--- /dev/null
+++ b/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;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.inf b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.inf
new file mode 100644
index 0000000000..9b29b05bac
--- /dev/null
+++ b/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
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptor.aslc b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptor.aslc
new file mode 100644
index 0000000000..884da36b97
--- /dev/null
+++ b/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;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptor.inf b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptor.inf
new file mode 100644
index 0000000000..dd85c86d95
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptorPei.c b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptorPei.c
new file mode 100644
index 0000000000..d21ee52184
--- /dev/null
+++ b/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;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdateConfig/SystemFirmwareUpdateConfig.ini b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdateConfig/SystemFirmwareUpdateConfig.ini
new file mode 100644
index 0000000000..126cd123b1
--- /dev/null
+++ b/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
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdateConfig/SystemFirmwareUpdateConfigGcc.ini b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdateConfig/SystemFirmwareUpdateConfigGcc.ini
new file mode 100644
index 0000000000..e22f136f8e
--- /dev/null
+++ b/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
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc b/Platform/Intel/Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc
new file mode 100644
index 0000000000..3bd9f150b3
--- /dev/null
+++ b/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
+  }
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FmpCertificate.dsc b/Platform/Intel/Vlv2TbltDevicePkg/FmpCertificate.dsc
new file mode 100644
index 0000000000..237ec87ac8
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FmpGreenSampleDevice.dsc b/Platform/Intel/Vlv2TbltDevicePkg/FmpGreenSampleDevice.dsc
new file mode 100644
index 0000000000..61bdd36a96
--- /dev/null
+++ b/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
+  }
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc b/Platform/Intel/Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc
new file mode 100644
index 0000000000..304519b294
--- /dev/null
+++ b/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
+  }
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc b/Platform/Intel/Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc
new file mode 100644
index 0000000000..59851f2b41
--- /dev/null
+++ b/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
+  }
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FspAzaliaConfigData/AzaliaConfig.bin b/Platform/Intel/Vlv2TbltDevicePkg/FspAzaliaConfigData/AzaliaConfig.bin
new file mode 100644
index 0000000000000000000000000000000000000000..da24c02b5d25ce888c630c664095902b4bb035e7
GIT binary patch
literal 3708
zcmd^>Pl#JZ9LMK3`)XRdt$F?9>(+TQNqa~UwYzRL6+{xdH3}71P@h!~iwKK?QYsja
zyX|(<qQVxzbj5>fq4Da)Ts;(X@!&zpF$WI;5lLww$LD8u(;7lcLET;q4D-G_leaV9
z`ONQ|ZR6t$o%9hYzfnH1u=S6uQmNdpwECI9F1+yKF{PAjL*H2Jq)QXOgh~bLdf(Yj
zx{Q{={HK>X>1pl1uVg3l=gxJ~cL&<PZ)v%co*%q_JNnyNCp|Z$e>&eufBh)t{i$qa
zymz6Ko;kF<fYxKYbk8T9^zHTcrQ*MT^i#$MdK~@MXPtDW{K}NLuFTl3<m0X=(-m=j
zxoZ39zGO`wT@kSrDa94Z8J=B&PSA<u4bN^KJufTqyc{q*yDGXWlW|oJ8lGK47HtDf
zGYxc2)@+UWHJLIsS#>R$wk^39x8#&*q1$rZw$W`_Fm2JUDS6xE|21XSG|_dwU+4RE
znKN}^tDE}4qiNQxW^7I6<C;>Yro`3NRa-~bRo2weO(nLeSfk1ro?RE+MR!%+@QkN|
zrz?1RVBOP<7MszNaYi3BJiC@!v@JCm(@cx`ZMA0GY9(%~l4+||7vWKaClMY+c+gjQ
z+voj#HEa4xy9}OWcz*^@GMnznsNr~Yq{O;PtS`?xHS5iqf=FDD$QES96{Kg1=%Vbl
zMS0m3VWGl$E3CW1e9u<Gcp?p(Fh7yUJWDV&4O^=))-zRfRj$~oyy~jx8oGwAp=;=d
zgfMm;)-J+a4^~2$ISxBz80x{6z}V-ob`s`B_psR-kDkb~#xiTnvqsGtCt0KC8g{rB
zP3}XBd%`+dBTUHSrj18!G|jbT+HgnXu7tKL6RwMAeYprzYp?|qQi3JV)FNz&%jj7X
zX^A6!(MI~Di}ai+pbL7+7W9NGXwC#()Zf`6<3)4@UD4NUh4BhH(b+iB$8Ey<5`7Om
zdQz(``s;53YS<Qi?D>E-M4TfHuF7zggR5<Dbs4T!2V8}46~a{+uCj2&9^kCPc!hIM
z_&yD;%5c?#s}Qb2xGE303gIe*t1?_onwngSH)>SiJXdw*(`=pbI(mb%kTWcEhBrA2
zIYZCcqnz27oLR(~l{m8=XBH05tjw7?&V+lSxhFc{O#D8_N*nw2{oOo<qvGU<2cvs-
z?0LODv*+M8doKOUJ#Jx-XV~NJ!5(viJsyY4fIW_$SqhgaTq?L!aQOgxCKq*<{&yGX
zkp9CRfsW}z{=PoG_IH0bPe#Y_=;&{`NR8(s_2z*{We?Ke!e^Mkh0nBIcm&&M8Xkpk
zF$Whu%LFd=n5yL9Lf}H+A~)n2c_4@3;w!jVgA4M2EaX1N8(HTwj~tK_ag)35GwbjA
z<7<!4yD>cc9uFV911CMxhZ~yh!&U!3uUB~VR348M9xdb1!oZ`MA&-1bp24F$9_ib7
z<ZJTq-I*QoNaN8iJj&vc3_L2~(UBpKUc#eGc(jH`zW(_d9mX{LDbsp*BzSZdk50Na
zcXQ(|dCtUn&NkhnXLF`O4mZf-207bMj(qny&$*(TN|D!!-0qRzC2~AVUbAKu`urxx
z`Ax-mm+>y+Jd@Xo-0u1OCdZW_uj7pLY=(Nlvx(3VIzscz9+{7(zIzV1OU&2I*UZ;H
zWLQt8t)~8r)UF%R=vCNs4M)egTR9b1a<AD+Zl9~<;0B$b6LgZBH1p_r^nC7h$MgT}
zgGV!?HL*tx4`Z4waK8)dxiws$?v`7l^(fC>yTo1d^~nE5K0H#7;CB7D2Hf7NN4M@8
zHA%Q@KgMm@!(F>wZry{scKj6e==4xMQYkzSwVSzj1<zInp82egsOc-z^wE0cJ=zy<
zWce8N=$~Zy5}xe6gC{=Avx6)jBg^0SxppDYAJgysBGC8IOFqyO^vV7}@Au<me3Aa)
og+TA{`cR;E`u>AJKSaMh8|ZiFi`_ua(_elr(C^Vdb2!j{0U29Y3;+NC

literal 0
HcmV?d00001

diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.c b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.c
new file mode 100644
index 0000000000..bf6c7efba5
--- /dev/null
+++ b/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;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.inf b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.inf
new file mode 100644
index 0000000000..27200bca15
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLibVlv2/FspHobProcessLibVlv2.c b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLibVlv2/FspHobProcessLibVlv2.c
new file mode 100644
index 0000000000..8a97e25bd4
--- /dev/null
+++ b/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;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLibVlv2/FspHobProcessLibVlv2.inf b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLibVlv2/FspHobProcessLibVlv2.inf
new file mode 100644
index 0000000000..b789b27f4c
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/FspPlatformSecLibVlv2.c b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/FspPlatformSecLibVlv2.c
new file mode 100644
index 0000000000..2b03cfaec9
--- /dev/null
+++ b/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;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/FspPlatformSecLibVlv2.inf b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/FspPlatformSecLibVlv2.inf
new file mode 100644
index 0000000000..578066d98f
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/AsmSaveSecContext.asm b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/AsmSaveSecContext.asm
new file mode 100644
index 0000000000..2546a09a1a
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Fsp.inc b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Fsp.inc
new file mode 100644
index 0000000000..23295587b4
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/PeiCoreEntry.asm b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/PeiCoreEntry.asm
new file mode 100644
index 0000000000..3d34c62ea4
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/SecEntry.asm b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/SecEntry.asm
new file mode 100644
index 0000000000..b7026c433f
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Stack.S b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Stack.S
new file mode 100644
index 0000000000..9bd29ce0f4
--- /dev/null
+++ b/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
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Stack.asm b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Stack.asm
new file mode 100644
index 0000000000..95e56cec9b
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/PlatformInit.c b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/PlatformInit.c
new file mode 100644
index 0000000000..d4e1c2a425
--- /dev/null
+++ b/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));
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SaveSecContext.c b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SaveSecContext.c
new file mode 100644
index 0000000000..382e617b27
--- /dev/null
+++ b/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);
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecGetPerformance.c b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecGetPerformance.c
new file mode 100644
index 0000000000..c5c22a29c2
--- /dev/null
+++ b/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;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecPlatformInformation.c b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecPlatformInformation.c
new file mode 100644
index 0000000000..a1ba35d47d
--- /dev/null
+++ b/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;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecRamInitData.c b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecRamInitData.c
new file mode 100644
index 0000000000..33734e3111
--- /dev/null
+++ b/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)
+};
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecTempRamSupport.c b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecTempRamSupport.c
new file mode 100644
index 0000000000..8dd1367980
--- /dev/null
+++ b/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;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/UartInit.c b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/UartInit.c
new file mode 100644
index 0000000000..2a9ab17120
--- /dev/null
+++ b/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  ;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c b/Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c
new file mode 100644
index 0000000000..11832bd295
--- /dev/null
+++ b/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;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf b/Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf
new file mode 100644
index 0000000000..397c2ce2a9
--- /dev/null
+++ b/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
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c b/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c
new file mode 100644
index 0000000000..d3b9145db0
--- /dev/null
+++ b/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;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbRuntimeDxe.inf b/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbRuntimeDxe.inf
new file mode 100644
index 0000000000..670db13465
--- /dev/null
+++ b/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
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.c b/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.c
new file mode 100644
index 0000000000..aa4fab013d
--- /dev/null
+++ b/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;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.h b/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.h
new file mode 100644
index 0000000000..89e0212f98
--- /dev/null
+++ b/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
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceDxe.c b/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceDxe.c
new file mode 100644
index 0000000000..32aa216728
--- /dev/null
+++ b/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;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceSmm.c b/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceSmm.c
new file mode 100644
index 0000000000..d1360bb90d
--- /dev/null
+++ b/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;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmm.inf b/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmm.inf
new file mode 100644
index 0000000000..4e33c3b9fb
--- /dev/null
+++ b/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
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmCommon.h b/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmCommon.h
new file mode 100644
index 0000000000..236e487111
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.c b/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.c
new file mode 100644
index 0000000000..e46c65c3fc
--- /dev/null
+++ b/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;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.h b/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.h
new file mode 100644
index 0000000000..9edb1bcaf0
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.inf b/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.inf
new file mode 100644
index 0000000000..aa2b63fe13
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/GenBiosId b/Platform/Intel/Vlv2TbltDevicePkg/GenBiosId
new file mode 100755
index 0000000000000000000000000000000000000000..ef1578f2bcb8922905e0693035245c4329809aa7
GIT binary patch
literal 12236
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
Oj(!g3>{OC7S^N)t{R~b3

literal 0
HcmV?d00001

diff --git a/Platform/Intel/Vlv2TbltDevicePkg/GenBiosId.exe b/Platform/Intel/Vlv2TbltDevicePkg/GenBiosId.exe
new file mode 100644
index 0000000000000000000000000000000000000000..323b87c444915b173b7f32d5481c67e4471b047b
GIT binary patch
literal 384000
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%0D_cl4iKT8j
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
ZjZG+N4<D9DmnW{lYNQ{GdHj36{y$a{V$uKr

literal 0
HcmV?d00001

diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/AlertStandardFormatTable.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/AlertStandardFormatTable.h
new file mode 100644
index 0000000000..3b0f00198b
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/ChipsetAccess.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/ChipsetAccess.h
new file mode 100644
index 0000000000..31ccfe6d5f
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/CommonIncludes.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/CommonIncludes.h
new file mode 100644
index 0000000000..eab47b28d9
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/CpuType.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/CpuType.h
new file mode 100644
index 0000000000..c195dee773
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/FileHandleLib.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/FileHandleLib.h
new file mode 100644
index 0000000000..5d733a0240
--- /dev/null
+++ b/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_
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AcpiTableStorage.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AcpiTableStorage.h
new file mode 100644
index 0000000000..7320bf6cfe
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AlertStandardFormat.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AlertStandardFormat.h
new file mode 100644
index 0000000000..f0459545e4
--- /dev/null
+++ b/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
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BiosId.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BiosId.h
new file mode 100644
index 0000000000..e86fc852fc
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BoardFeatures.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BoardFeatures.h
new file mode 100644
index 0000000000..ae3c2d9aea
--- /dev/null
+++ b/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
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/EfiVpdData.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/EfiVpdData.h
new file mode 100644
index 0000000000..e00e582ce1
--- /dev/null
+++ b/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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/FirmwareId.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/FirmwareId.h
new file mode 100644
index 0000000000..fd524b8ce5
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/FirmwareId.h
@@ -0,0 +1,61 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  FirmwareId.h
+
+--*/
+
+#ifndef _FirmwareId_h_GUID_included
+#define _FirmwareId_h_GUID_included
+
+
+#pragma pack(1)
+
+//
+// Firmware ID
+//
+
+#define FIRMWARE_ID_MAX_LENGTH      35
+
+typedef struct {
+  CHAR8    BiosId[8];
+  CHAR8    Separator1;
+  CHAR8    OemId[3];
+  CHAR8    Separator2;
+  CHAR8    BuildId[4];
+  CHAR8    Separator3;
+  CHAR8    Century[2];
+  CHAR8    Year[2];
+  CHAR8    Separator4;
+  CHAR8    Month[2];
+  CHAR8    Date[2];
+  CHAR8    Separator5;
+  CHAR8    Hour[2];
+  CHAR8    Minute[2];
+  CHAR8    Dummy[3];
+} FIRMWARE_ID_DATA;
+
+#define  OLD_FIRMWARE_ID_GUID \
+  {0xefc071ae, 0x41b8, 0x4018, 0xaf, 0xa7, 0x31, 0x4b, 0x18, 0x5e, 0x57, 0x8b}
+
+#define  FIRMWARE_ID_GUID \
+  {0x5e559c23, 0x1faa, 0x4ae1, 0x8d, 0x4a, 0xc6, 0xcf, 0x02, 0x6c, 0x76, 0x6f}
+
+#define FIRMWARE_ID_NAME L"FirmwareId"
+#define FIRMWARE_ID_NAME_WITH_PASSWORD FIRMWARE_ID_NAME L"H#8,^-!t"
+
+extern EFI_GUID gFirmwareIdGuid;
+extern CHAR16   gFirmwareIdName[];
+
+#pragma pack()
+
+#endif
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/HwWatchdogTimerHob.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/HwWatchdogTimerHob.h
new file mode 100644
index 0000000000..3cd6c843b1
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/HwWatchdogTimerHob.h
@@ -0,0 +1,134 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  HwWatchdogTimerHob.h
+
+Abstract:
+
+  GUID used for Watchdog Timer status in the HOB list.
+
+--*/
+
+#ifndef _EFI_WATCHDOG_TIMER_HOB_GUID_H_
+#define _EFI_WATCHDOG_TIMER_HOB_GUID_H_
+
+#define EFI_WATCHDOG_TIMER_HOB_GUID \
+  { 0x226cd3f, 0x69b5, 0x4150, 0xac, 0xbe, 0xbf, 0xbf, 0x18, 0xe3, 0x3, 0xd5 }
+
+#define EFI_WATCHDOG_TIMER_DEFINITION_HOB_GUID \
+  { 0xd29302b0, 0x11ba, 0x4073, 0xa2, 0x27, 0x53, 0x8d, 0x25, 0x42, 0x70, 0x9f }
+
+typedef enum {
+  HWWD_NONE,
+  HWWD_TIMER_EXPIRED,
+  HWWD_SPONTANEOUS_REBOOT,
+  HWWD_FORCED_TIMEOUT
+} HW_WATCHDOG_TIMEOUT;
+
+typedef struct {
+  HW_WATCHDOG_TIMEOUT         TimeoutStatus;
+} HW_WATCHDOG_INFO;
+
+//
+// Watchdog timer action values.
+//
+#define WDT_ACTION_RESET                    0x01    // reload/reset timer
+#define WDT_ACTION_QUERY_CURRENT_VALUE      0x04    // get current value                     // DON'T NEED FOR OVERCLOCK UTILITY
+#define WDT_ACTION_QUERY_COUNTDOWN_PERIOD   0x05    // get countdown period
+#define WDT_ACTION_SET_COUNTDOWN_PERIOD     0x06    // set countdown period
+#define WDT_ACTION_QUERY_RUNNING_STATE      0x08    // query if running
+#define WDT_ACTION_SET_RUNNING_STATE        0x09    // start timer
+#define WDT_ACTION_QUERY_STOPPED_STATE      0x0A    // query if stopped
+#define WDT_ACTION_SET_STOPPED_STATE        0x0B    // stop timer
+#define WDT_ACTION_QUERY_STATUS             0x20    // is current boot cause by wdt timeout?
+#define WDT_ACTION_SET_STATUS               0x21    // resets wdt status bit
+
+//
+// Watchdog timer instruction values.
+//
+#define WDT_INSTR_VALUE_MASK                0x03    // Mask for just the value
+#define WDT_INSTR_READ_CMP_VALUE            0x00    // Read / compare value
+#define WDT_INSTR_READ_COUNTDOWN            0x01    // read countdown value
+#define WDT_INSTR_WRITE_VALUE               0x02    // Write value
+#define WDT_INSTR_WRITE_COUNTDOWN           0x03    // write countdown value
+#define WDT_INSTR_PRESERVE_REG              0x80    // preserve reg; used in Write Value / Write Countdown
+#define WDT_INSTR_WRITE_VALUE_PRES         (0x02 | WDT_INSTR_PRESERVE_REG)   // Write value with preserve
+#define WDT_INSTR_WRITE_COUNTDOWN_PRES     (0x03 | WDT_INSTR_PRESERVE_REG)   // write countdown value with preserve
+
+//
+// The Generic Address Structure is defined in the ACPI Specification and should only be
+// changed to match updated revisions of that specification.  The GAS_ADDRESS_SPACE and
+// GAS_ACCESS_SIZE enumerations are also defined by the ACPI Specification.
+//
+typedef enum {
+  GAS_SYSTEM_MEMORY,
+  GAS_SYSTEM_IO,
+  GAS_PCI_CONFIG_SPACE,
+  GAS_EMBEDDED_CONTROLLER,
+  GAS_SMBUS
+} GAS_ADDRESS_SPACE;
+
+typedef enum {
+  GAS_UNDEFINED,
+  GAS_BYTE_ACCESS,
+  GAS_WORD_ACCESS,
+  GAS_DWORD_ACCESS,
+  GAS_QWORD_ACCESS
+} GAS_ACCESS_SIZE;
+
+#pragma pack(1)
+
+typedef struct {
+  UINT8                       AddressSpaceId;
+  UINT8                       RegisterBitWidth;
+  UINT8                       RegisterBitOffset;
+  UINT8                       AccessSize;
+  UINT64                      Address;
+} GENERIC_ADDRESS_STRUCTURE;
+
+//
+// GAS_SYSTEM_MEMORY -    When used as the AddressSpaceId, the 64-bit physical memory address
+//                        of the register.  32-bit platforms must have the high DWORD set to 0.
+// GAS_SYSTEM_IO -        The 64-bit I/O address of the register.  32-bit platforms must have
+//                        the high DWORD set to 0.
+// GAS_PCI_CONFIG_SPACE - PCI Configuration space addresses must be confined to devices on PCI
+//                        Sepment Group 0, Bus 0.  This restriction exists to accommodate access
+//                        to fixed hardware prior to PCI bus enumeration.  The format of addresses
+//                        are defined as follows:
+//                            Highest WORD: Reserved and must be -0-
+//                            ...           PCI Device number on bus 0
+//                            ...           PCI Function number
+//                            Lowest WORD:  Offset in the configuration space header.
+//
+
+typedef struct {
+  UINT8                       WdAction;
+  UINT8                       Flag;
+  UINT16                      Res;
+  GENERIC_ADDRESS_STRUCTURE   GenericAddressStructures;
+  UINT32                      Value;
+  UINT32                      Mask;
+} WD_INSTRUCTION;
+
+typedef struct {
+  UINT32                      TimerPeriod;
+  UINT32                      MaxTimerCount;
+  UINT32                      MinTimerCount;
+  UINT16                      InstructionCount;
+  WD_INSTRUCTION              ActionDefinitions[1];
+} WD_HOB_DEFINITION;
+
+#pragma pack()
+
+extern EFI_GUID gWatchdogTimerHobGuid;
+extern EFI_GUID gWatchdogTimerDefinitionHobGuid;
+
+#endif // _EFI_WATCHDOG_TIMER_HOB_GUID_H_
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/IdccData.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/IdccData.h
new file mode 100644
index 0000000000..7e3b965666
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/IdccData.h
@@ -0,0 +1,104 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  IdccData.h
+
+Abstract:
+
+--*/
+
+#ifndef _IDCCDATAHUB_GUID_H_
+#define _IDCCDATAHUB_GUID_H_
+
+//
+// This GUID is for the IDCC related data found in the Data Hub.
+//
+#define IDCC_DATA_HUB_GUID \
+  { 0x788e1d9f, 0x1eab, 0x47d2, 0xa2, 0xf3, 0x78, 0xca, 0xe8, 0x7d, 0x60, 0x12 }
+
+extern EFI_GUID gIdccDataHubGuid;
+
+#pragma pack(1)
+
+typedef struct {
+  UINT32    Type;
+  UINT32    RecordLength;
+} EFI_IDCC_DATA_HEADER;
+
+typedef struct {
+  EFI_IDCC_DATA_HEADER  IdccHeader;
+  UINT32                Tcontrol;
+} EFI_IDCC_TCONTROL;
+
+typedef struct {
+  UINT32    EntryCount;
+} EFI_IDCC_CLOCK_COMMON;
+
+typedef struct {
+  UINT8     Polarity;
+  UINT8     Percent;
+  UINT32    FpValue;
+} EFI_IDCC_TYPE_2_DATA;
+
+typedef struct {
+  UINT8     SetupVal;
+  UINT32    FpValue;
+} EFI_IDCC_TYPE_3_4_DATA;
+
+typedef struct {
+  EFI_IDCC_DATA_HEADER  IdccHeader;
+  UINT32                ProcessorRatio;
+} EFI_IDCC_PROCESSOR_RATIO;
+
+typedef struct {
+  EFI_IDCC_DATA_HEADER  IdccHeader;
+  UINT32                BoardFormFactor;
+} EFI_IDCC_BOARD_FORM_FACTOR;
+
+typedef struct {
+  EFI_IDCC_DATA_HEADER  IdccHeader;
+  UINT32                ProcessorInfo;
+} EFI_IDCC_PROCESSOR_INFO;
+
+#define EFI_IDCC_PROCESSOR_UNCON    (1 << 0)  // Bit 0: UnCon CPU
+#define EFI_IDCC_PROCESSOR_UNLOCK   (1 << 1)  // Bit 1: UnLock CPU
+#define EFI_IDCC_PROCESSOR_CNR      (1 << 2)  // Bit 2: CNR CPU
+#define EFI_IDCC_PROCESSOR_KNF      (1 << 3)  // Bit 3: KNF CPU
+
+typedef struct {
+  EFI_IDCC_DATA_HEADER  IdccHeader;
+  UINT32    MinFSB;
+  UINT32    MaxFSB;
+  UINT8     StepFSB;
+} EFI_IDCC_FSB_DATA;
+
+#pragma pack()
+
+#define EFI_IDCC_POSITIVE   0
+#define EFI_IDCC_NEGATIVE   1
+
+//
+// Board Form Factor equates.
+//
+#define ATX_FORM_FACTOR		0x00
+#define BTX_FORM_FACTOR		0x01
+
+
+#define EFI_IDCC_TCONTROL_TYPE          1
+#define EFI_IDCC_FSB_TYPE               2
+#define EFI_IDCC_PCI_TYPE               3
+#define EFI_IDCC_PCIE_TYPE              4
+#define EFI_IDCC_PROC_RATIO_TYPE        5
+#define EFI_IDCC_BOARD_FORM_FACTOR_TYPE 6
+#define EFI_IDCC_PROC_INFO_TYPE         7
+#define EFI_IDCC_FSB_DATA_TYPE          8
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/ItkData.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/ItkData.h
new file mode 100644
index 0000000000..e7bd29e6e4
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/ItkData.h
@@ -0,0 +1,70 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  ItkData.h
+
+Abstract:
+
+--*/
+
+#ifndef _ITKDATAHUB_GUID_H_
+#define _ITKDATAHUB_GUID_H_
+
+//
+// This GUID is for the ITK related data found in the Data Hub {E7060843-A336-4d5b-9598-13402F5D7375}
+//
+#define ITK_DATA_HUB_GUID \
+  { 0xe7060843, 0xa336, 0x4d5b, 0x95, 0x98, 0x13, 0x40, 0x2f, 0x5d, 0x73, 0x75 }
+
+extern EFI_GUID gItkDataHubGuid;
+
+//
+// This GUID is for the ITK related data found in a Variable  {3812723D-7E48-4e29-BC27-F5A39AC94EF1}
+//
+#define ITK_DATA_VAR_GUID \
+  { 0x3812723d, 0x7e48, 0x4e29, 0xbc, 0x27, 0xf5, 0xa3, 0x9a, 0xc9, 0x4e, 0xf1 }
+
+extern EFI_GUID gItkDataVarGuid;
+
+#define ITK_DATA_VAR_NAME L"ItkDataVar"
+
+extern CHAR16 gItkDataVarName[];
+
+#define ITK_BIOS_MOD_VAR_NAME L"ItkBiosModVar"
+
+extern CHAR16 gItkBiosModVarName[];
+
+#pragma pack(1)
+typedef struct {
+  UINT32    Type;
+  UINT32    RecordLength;
+} EFI_ITK_DATA_HEADER;
+
+typedef struct {
+  EFI_ITK_DATA_HEADER   ItkHeader;
+  UINT32                HecetaAddress;
+} EFI_ITK_HECETA_ADDRESS;
+
+typedef struct {
+  UINT16    VarEqName;
+  UINT16    VarEqValue;
+} EFI_ITK_VAR_EQ_RECORD;
+
+typedef struct {
+  EFI_ITK_DATA_HEADER   ItkHeader;
+  EFI_ITK_VAR_EQ_RECORD VarEqRecord[0x10000];
+} EFI_ITK_VAR_EQ;
+#pragma pack()
+
+#define EFI_ITK_HECETA_ADDRESS_TYPE    1
+#define EFI_ITK_MOBILE_BIOS_TYPE       2
+#define EFI_ITK_VAR_EQ_TYPE            3
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/MemoryConfigData.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/MemoryConfigData.h
new file mode 100644
index 0000000000..0fe759a16e
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/MemoryConfigData.h
@@ -0,0 +1,32 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+
+Module Name:
+
+  MemoryConfigData.h
+
+Abstract:
+
+  GUID used for Memory Configuration Data entries in the HOB list.
+
+--*/
+
+#ifndef _MEMORY_CONFIG_DATA_GUID_H_
+#define _MEMORY_CONFIG_DATA_GUID_H_
+
+#define EFI_MEMORY_CONFIG_DATA_GUID \
+  { \
+    0x80dbd530, 0xb74c, 0x4f11, 0x8c, 0x03, 0x41, 0x86, 0x65, 0x53, 0x28, 0x31 \
+  }
+
+extern EFI_GUID gEfiMemoryConfigDataGuid;
+extern CHAR16   EfiMemoryConfigVariable[];
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/OsSelection.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/OsSelection.h
new file mode 100644
index 0000000000..e7bbcf67c9
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/OsSelection.h
@@ -0,0 +1,85 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  OsSelection.h
+
+Abstract:
+
+  GUID used for LPSS, SCC and LPE configuration data entries in the HOB list.
+
+--*/
+
+#ifndef _OS_SELECTION_GUID_H_
+#define _OS_SELECTION_GUID_H_
+
+#ifndef ECP_FLAG
+#include <PiPei.h>
+
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#endif
+
+#define ANDROID 1
+
+#define EFI_OS_SELECTION_VARIABLE_GUID \
+  { \
+    0x86843f56, 0x675d, 0x40a5, 0x95, 0x30, 0xbc, 0x85, 0x83, 0x72, 0xf1, 0x03 \
+  }
+
+extern EFI_GUID gOsSelectionVariableGuid;
+
+#pragma pack(1)
+
+typedef struct {
+  UINT8           LpssPciModeEnabled;
+  //SCC
+  UINT8           LpsseMMCEnabled;
+  UINT8           LpssSdioEnabled;
+  UINT8           LpssSdcardEnabled;
+  UINT8           LpssSdCardSDR25Enabled;
+  UINT8           LpssSdCardDDR50Enabled;
+  UINT8           LpssMipiHsi;
+  UINT8           LpsseMMC45Enabled;
+  UINT8           LpsseMMC45DDR50Enabled;
+  UINT8           LpsseMMC45HS200Enabled;
+  UINT8           LpsseMMC45RetuneTimerValue;
+  UINT8           eMMCBootMode;
+  //LPSS2
+  UINT8           LpssDma1Enabled;
+  UINT8           LpssI2C0Enabled;
+  UINT8           LpssI2C1Enabled;
+  UINT8           LpssI2C2Enabled;
+  UINT8           LpssI2C3Enabled;
+  UINT8           LpssI2C4Enabled;
+  UINT8           LpssI2C5Enabled;
+  UINT8           LpssI2C6Enabled;
+  //LPSS1
+  UINT8           LpssDma0Enabled;
+  UINT8           LpssPwm0Enabled;
+  UINT8           LpssPwm1Enabled;
+  UINT8           LpssHsuart0Enabled;
+  UINT8           LpssHsuart1Enabled;
+  UINT8           LpssSpiEnabled;
+  UINT8           I2CTouchAd;
+} EFI_PLATFORM_LPSS_DATA;
+
+typedef struct _EFI_OS_SELECTION_HOB {
+  UINT8                       OsSelection;
+  UINT8                       OsSelectionChanged;
+  UINT8                       Lpe;
+  UINT8                       PchAzalia;
+  EFI_PLATFORM_LPSS_DATA      LpssData;
+} EFI_OS_SELECTION_HOB;
+
+#pragma pack()
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PciLanInfo.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PciLanInfo.h
new file mode 100644
index 0000000000..46c45b0303
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PciLanInfo.h
@@ -0,0 +1,39 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  PciLanInfo.h
+
+Abstract:
+
+--*/
+
+#ifndef _PCI_LAN_INFO_GUID_H_
+#define _PCI_LAN_INFO_GUID_H_
+
+#pragma pack(1)
+
+//
+// structure used for Pci Lan variable
+//
+typedef struct {
+  UINT8         PciBus;
+  UINT8         PciDevice;
+  UINT8         PciFunction;
+} PCI_LAN_INFO;
+
+#pragma pack()
+
+#define EFI_PCI_LAN_INFO_GUID \
+  {0xd9a1427, 0xe02a, 0x437d, 0x92, 0x6b, 0xaa, 0x52, 0x1f, 0xd7, 0x22, 0xba};
+
+extern EFI_GUID gEfiPciLanInfoGuid;
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformCpuInfo.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformCpuInfo.h
new file mode 100644
index 0000000000..f1756662bd
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformCpuInfo.h
@@ -0,0 +1,180 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  PlatformCpuInfo.h
+
+Abstract:
+
+  GUID used for Platform CPU Info Data entries in the HOB list.
+
+--*/
+
+#ifndef _PLATFORM_CPU_INFO_GUID_H_
+#define _PLATFORM_CPU_INFO_GUID_H_
+
+#include "CpuType.h"
+#include <Library/CpuIA32.h>
+
+#define EFI_PLATFORM_CPU_INFO_GUID \
+  {\
+    0xbb9c7ab7, 0xb8d9, 0x4bf3, 0x9c, 0x29, 0x9b, 0xf3, 0x41, 0xe2, 0x17, 0xbc \
+  }
+
+extern EFI_GUID gEfiPlatformCpuInfoGuid;
+extern CHAR16   EfiPlatformCpuInfoVariable[];
+
+//
+// Tri-state for feature capabilities and enable/disable.
+// [0] clear=feature isn't capable
+// [0] set  =feature is capable
+// [1] clear=feature is disabled
+// [1] set  =feature is enabled
+//
+#define CPU_FEATURES_CAPABLE      BIT0
+#define CPU_FEATURES_ENABLE       BIT1
+
+#define MAX_CACHE_DESCRIPTORS     64
+#define MAXIMUM_CPU_BRAND_STRING_LENGTH 48
+
+#pragma pack(1)
+
+typedef struct {
+  UINT32              FullCpuId;                // [31:0] & 0x0FFF0FFF
+  UINT32              FullFamilyModelId;        // [31:0] & 0x0FFF0FF0
+  UINT8               ExtendedFamilyId;         // [27:20]
+  UINT8               ExtendedModelId;          // [19:16]
+  UINT8               ProcessorType;            // [13:11]
+  UINT8               FamilyId;                 // [11:8]
+  UINT8               Model;                    // [7:4]
+  UINT8               SteppingId;               // [3:0]
+} EFI_CPU_VERSION_INFO; // CPUID.1.EAX
+
+typedef struct {
+  UINT32              L1InstructionCacheSize;
+  UINT32              L1DataCacheSize;
+  UINT32              L2CacheSize;
+  UINT32              L3CacheSize;
+  UINT32              TraceCacheSize;
+  UINT8               CacheDescriptor[MAX_CACHE_DESCRIPTORS];
+} EFI_CPU_CACHE_INFO; // CPUID.2.EAX
+
+typedef struct {
+  UINT8               PhysicalPackages;
+  UINT8               LogicalProcessorsPerPhysicalPackage;
+  UINT8               CoresPerPhysicalPackage;
+  UINT8               ThreadsPerCore;
+} EFI_CPU_PACKAGE_INFO; // CPUID.4.EAX
+
+typedef struct {
+  UINT32              RegEdx;                   // CPUID.5.EAX
+  UINT8               MaxCState;
+  UINT8               C0SubCStatesMwait;        // EDX [3:0]
+  UINT8               C1SubCStatesMwait;        // EDX [7:4]
+  UINT8               C2SubCStatesMwait;        // EDX [11:8]
+  UINT8               C3SubCStatesMwait;        // EDX [15:12]
+  UINT8               C4SubCStatesMwait;        // EDX [19:16]
+  UINT8               C5SubCStatesMwait;        // EDX [23:20]
+  UINT8               C6SubCStatesMwait;        // EDX [27:24]
+  UINT8               C7SubCStatesMwait;        // EDX [31:28]
+  UINT8               MonitorMwaitSupport;      // ECX [0]
+  UINT8               InterruptsBreakMwait;     // ECX [1]
+} EFI_CPU_CSTATE_INFO; // CPUID.5.EAX
+
+typedef struct {
+  UINT8               Turbo;                    // EAX [1]
+  UINT8               PECI;                     // EAX [0]
+  UINT8               NumIntThresholds;         // EBX [3:0]
+  UINT8               HwCoordinationFeedback;   // ECX [0]
+} EFI_CPU_POWER_MANAGEMENT; // CPUID.6.EAX
+
+//
+// IMPORTANT: Each CPU feature enabling entry is assumed a tri-state variable.
+//   - Keep the respective feature entry variable as default value (0x00)
+//     if the CPU is not capable for the feature.
+//   - Use the specially defined programming convention to update the variable
+//     to indicate capable, enable or disable.
+//     ie. F_CAPABLE for feature available
+//         F_ENABLE for feature enable
+//         F_DISABLE for feature disable
+//
+typedef struct {
+  EFI_CPUID_REGISTER  Regs;                     // CPUID.1.EAX
+  UINT8               Xapic;                    // ECX [21]
+  UINT8               SSE4_2;                   // ECX [20]
+  UINT8               SSE4_1;                   // ECX [19]
+  UINT8               Dca;                      // ECX [18]
+  UINT8               SupSSE3;                  // ECX [9]
+  UINT8               Tm2;                      // ECX [8]
+  UINT8               Eist;                     // ECX [7]
+  UINT8               Lt;                       // ECX [6]
+  UINT8               Vt;                       // ECX [5]
+  UINT8               Mwait;                    // ECX [3]
+  UINT8               SSE3;                     // ECX [0]
+  UINT8               Tcc;                      // EDX [29]
+  UINT8               Mt;                       // EDX [28]
+  UINT8               SSE2;                     // EDX [26]
+  UINT8               SSE;                      // EDX [25]
+  UINT8               MMX;                      // EDX [23]
+  EFI_CPUID_REGISTER  ExtRegs;                  // CPUID.80000001.EAX
+  UINT8               ExtLahfSahf64;            // ECX [0]
+  UINT8               ExtIntel64;               // EDX [29]
+  UINT8               ExtXd;                    // EDX [20]
+  UINT8               ExtSysCallRet64;          // EDX [11]
+  UINT16              Ht;                       // CPUID.0B.EAX EBX [15:0]
+} EFI_CPU_FEATURES; // CPUID.1.EAX, CPUID.0B.EAX, CPUID.80000001.EAX
+
+typedef struct {
+  UINT8               PhysicalBits;
+  UINT8               VirtualBits;
+} EFI_CPU_ADDRESS_BITS; // CPUID.80000008.EAX
+
+typedef struct {
+  UINT8               PlatformID;               // MSR 0x17 [52:50]
+  UINT32              MicrocodeRevision;        // MSR 0x8B [63:32]
+  UINT8               MaxEfficiencyRatio;       // MSR 0xCE [47:40]
+  UINT8               DdrRatioUnlockCap;        // MSR 0xCE [30]
+  UINT8               TdcTdpLimitsTurbo;        // MSR 0xCE [29]
+  UINT8               RatioLimitsTurbo;         // MSR 0xCE [28]
+  UINT8               PreProduction;            // MSR 0xCE [27]
+  UINT8               DcuModeSelect;            // MSR 0xCE [26]
+  UINT8               MaxNonTurboRatio;         // MSR 0xCE [15:8]
+  UINT8               Emrr;                     // MSR 0xFE [12]
+  UINT8               Smrr;                     // MSR 0xFE [11]
+  UINT8               VariableMtrrCount;        // MSR 0xFE [7:0]
+  UINT16              PState;                   // MSR 0x198 [15:0]
+  UINT8               TccActivationTemperature; // MSR 0x1A2 [23:16]
+  UINT8               TemperatureControlOffset; // MSR 0x1A2 [15:8]
+  UINT32              PCIeBar;                  // MSR 0x300 [39:20]
+  UINT8               PCIeBarSizeMB;            // MSR 0x300 [3:1]
+} EFI_MSR_FEATURES;
+
+typedef struct {
+  BOOLEAN                            IsIntelProcessor;
+  UINT8                              BrandString[MAXIMUM_CPU_BRAND_STRING_LENGTH + 1];
+  UINT32                             CpuidMaxInputValue;
+  UINT32                             CpuidMaxExtInputValue;
+  EFI_CPU_UARCH                      CpuUarch;
+  EFI_CPU_FAMILY                     CpuFamily;
+  EFI_CPU_PLATFORM                   CpuPlatform;
+  EFI_CPU_TYPE                       CpuType;
+  EFI_CPU_VERSION_INFO               CpuVersion;
+  EFI_CPU_CACHE_INFO                 CpuCache;
+  EFI_CPU_FEATURES                   CpuFeatures;
+  EFI_CPU_CSTATE_INFO                CpuCState;
+  EFI_CPU_PACKAGE_INFO               CpuPackage;
+  EFI_CPU_POWER_MANAGEMENT           CpuPowerManagement;
+  EFI_CPU_ADDRESS_BITS               CpuAddress;
+  EFI_MSR_FEATURES                   Msr;
+} EFI_PLATFORM_CPU_INFO;
+
+#pragma pack()
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformInfo.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformInfo.h
new file mode 100644
index 0000000000..cac31e2a40
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformInfo.h
@@ -0,0 +1,433 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+
+Module Name:
+
+  PlatformInfo.h
+
+Abstract:
+
+  GUID used for Platform Info Data entries in the HOB list.
+
+--*/
+
+#ifndef _PLATFORM_INFO_GUID_H_
+#define _PLATFORM_INFO_GUID_H_
+
+#ifndef ECP_FLAG
+#include <PiPei.h>
+
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/SmbusLib.h>
+#include <IndustryStandard/SmBus.h>
+#endif
+
+#define PLATFORM_INFO_REVISION = 1      // Revision id for current platform information struct.
+
+//
+// Start::BayLake Board Defines
+//
+#define BOARD_REVISION_DEFAULT = 0xff
+#define UNKNOWN_FABID		0x0F
+#define FAB_ID_MASK			0x0F
+#define BOARD_ID_2   0x01
+#define BOARD_ID_1   0x40
+#define BOARD_ID_0   0x04
+
+#define BOARD_ID_DT_CRB     0x0
+#define BOARD_ID_DT_VLVR    0x1
+#define BOARD_ID_SVP_VLV    0xC
+#define BOARD_ID_SVP_EV_VLV 0xD
+//
+// End::BayLake Board Defines
+//
+
+//
+// Start::Alpine Valley Board Defines
+//
+#define DC_ID_DDR3L      0x00
+#define DC_ID_DDR3       0x04
+#define DC_ID_LPDDR3     0x02
+#define DC_ID_LPDDR2     0x06
+#define DC_ID_DDR4       0x01
+#define DC_ID_DDR3L_ECC  0x05
+#define DC_ID_NO_MEM     0x07
+//
+// End::Alpine Valley Board Defines
+//
+
+#define MAX_FAB_ID_RETRY_COUNT  100
+#define MAX_FAB_ID_CHECK_COUNT  3
+
+#define PLATFORM_INFO_HOB_REVISION	0x1
+
+#define EFI_PLATFORM_INFO_GUID \
+  { \
+    0x1e2acc41, 0xe26a, 0x483d, 0xaf, 0xc7, 0xa0, 0x56, 0xc3, 0x4e, 0x8, 0x7b \
+  }
+
+extern EFI_GUID gEfiPlatformInfoGuid;
+
+typedef enum {
+  FlavorUnknown = 0,
+
+  //
+  // Mobile
+  //
+  FlavorMobile = 1,
+
+  //
+  // Desktop
+  //
+  FlavorDesktop = 2,
+
+  //
+  // Tablet
+  //
+  FlavorTablet = 3
+} PLATFORM_FLAVOR;
+
+#pragma pack(1)
+
+typedef struct {
+  UINT16  PciResourceIoBase;
+  UINT16  PciResourceIoLimit;
+  UINT32  PciResourceMem32Base;
+  UINT32  PciResourceMem32Limit;
+  UINT64  PciResourceMem64Base;
+  UINT64  PciResourceMem64Limit;
+  UINT64  PciExpressBase;
+  UINT32  PciExpressSize;
+  UINT8   PciHostAddressWidth;
+  UINT8   PciResourceMinSecBus;
+} EFI_PLATFORM_PCI_DATA;
+
+typedef struct {
+  UINT8 CpuAddressWidth;
+  UINT32 CpuFamilyStepping;
+} EFI_PLATFORM_CPU_DATA;
+
+typedef struct {
+  UINT8 SysIoApicEnable;
+  UINT8 SysSioExist;
+} EFI_PLATFORM_SYS_DATA;
+
+typedef struct {
+  UINT32  MemTolm;
+  UINT32  MemMaxTolm;
+  UINT32  MemTsegSize;
+  UINT32  MemTsegBase;
+  UINT32  MemIedSize;
+  UINT32  MemIgdSize;
+  UINT32  MemIgdBase;
+  UINT32  MemIgdGttSize;
+  UINT32  MemIgdGttBase;
+  UINT64  MemMir0;
+  UINT64  MemMir1;
+  UINT32  MemConfigSize;
+  UINT16  MmioSize;
+  UINT8   DdrFreq;
+  UINT8   DdrType; 
+  UINT32  MemSize;
+  BOOLEAN EccSupport;
+  UINT8   Reserved[3];
+  UINT16  DimmSize[2];
+} EFI_PLATFORM_MEM_DATA;
+
+
+typedef struct {
+  UINT32 IgdOpRegionAddress;    // IGD OpRegion Starting Address
+  UINT8  IgdBootType;           // IGD Boot Display Device
+  UINT8  IgdPanelType;          // IGD Panel Type CMOs option
+  UINT8  IgdTvFormat;           // IGD TV Format CMOS option
+  UINT8  IgdTvMinor;            // IGD TV Minor Format CMOS option
+  UINT8  IgdPanelScaling;       // IGD Panel Scaling
+  UINT8  IgdBlcConfig;          // IGD BLC Configuration
+  UINT8  IgdBiaConfig;          // IGD BIA Configuration
+  UINT8  IgdSscConfig;          // IGD SSC Configuration
+  UINT8  IgdDvmtMemSize;        // IGD DVMT Memory Size
+  UINT8  IgdFunc1Enable;        // IGD Function 1 Enable
+  UINT8  IgdHpllVco;            // HPLL VCO
+  UINT8  IgdSciSmiMode;         // GMCH SMI/SCI mode (0=SCI)
+  UINT8  IgdPAVP;               // IGD PAVP data
+} EFI_PLATFORM_IGD_DATA;
+
+typedef enum {
+  BOARD_ID_AV_SVP   = 0x0,    // Alpine Valley Board
+  BOARD_ID_BL_RVP   = 0x2,    // BayLake Board (RVP)
+  BOARD_ID_BL_FFRD8 = 0x3,    // FFRD8 b'0011
+  BOARD_ID_BL_FFRD  = 0x4,    // BayLake Board (FFRD)
+  BOARD_ID_BL_RVP_DDR3L  = 0x5,    // BayLake Board (RVP DDR3L)
+  BOARD_ID_BL_STHI  = 0x7,    // PPV- STHI Board
+  BOARD_ID_BB_RVP   = 0x20,   // Bayley Bay Board
+  BOARD_ID_BS_RVP   = 0x30,   // Bakersport Board
+  BOARD_ID_CVH      = 0x90,   // Crestview Hills
+  BOARD_ID_MINNOW2  = 0xA0,    // MinnowBorad Max
+  BOARD_ID_MINNOW2_TURBOT  = 0xB0    // MinnowBoard Turbot
+
+} BOARD_ID_LIST;
+
+typedef enum {
+  FAB1 = 0,
+  FAB2 = 1,
+  FAB3 = 2
+} FAB_ID_LIST;
+
+typedef enum {
+    PR0  = 0,   // FFRD PR0
+    PR05 = 1,   // FFRD PR0.3 and PR 0.5
+    PR1  = 2,   // FFRD PR1
+    PR11 = 3    // FFRD PR1.1
+} FFRD_ID_LIST;
+
+
+//
+// VLV2 GPIO GROUP OFFSET
+//
+#define GPIO_SCORE_OFFSET	0x0000
+#define GPIO_NCORE_OFFSET	0x1000
+#define GPIO_SSUS_OFFSET	0x2000
+
+//
+// GPIO Initialization Data Structure for BayLake.
+// SC = SCORE, SS= SSUS
+// Note: NC doesn't support GPIO functionality in IO access mode, only support in MMIO access mode.
+//
+
+//
+// IO space
+//
+typedef struct{
+  UINT32  Use_Sel_SC0;
+  UINT32  Use_Sel_SC1;
+  UINT32  Use_Sel_SC2;
+  UINT32  Use_Sel_SS;
+
+  UINT32  Io_Sel_SC0;
+  UINT32  Io_Sel_SC1;
+  UINT32  Io_Sel_SC2;
+  UINT32  Io_Sel_SS;
+
+  UINT32  GP_Lvl_SC0;
+  UINT32  GP_Lvl_SC1;
+  UINT32  GP_Lvl_SC2;
+  UINT32  GP_Lvl_SS;
+
+  UINT32  TPE_SC0;
+  UINT32  TPE_SS;
+
+  UINT32  TNE_SC0;
+  UINT32  TNE_SS;
+
+  UINT32  TS_SC0;
+  UINT32  TS_SS;
+
+  UINT32  WE_SS;
+} CFIO_INIT_STRUCT;
+
+
+
+//
+// CFIO PAD configuration Registers
+//
+//
+// Memory space
+//
+typedef union {
+  UINT32 dw;
+  struct {
+    UINT32 Func_Pin_Mux:3;  // 0:2 Function of CFIO selection
+    UINT32 ipslew:2; // 3:4 Pad (P) Slew Rate Controls PAD slew rate check Width
+    UINT32 inslew:2; // 5:6 Pad (N) Slew Rate Controls PAD slew rate
+    UINT32 Pull_assign:2; // 7:8 Pull assignment
+    UINT32 Pull_strength:2; // 9:10 Pull strength
+    UINT32 Bypass_flop:1; // 11 Bypass flop
+    UINT32 Filter_en:1; // 12 Filter Enable
+    UINT32 Hist_ctrl:2; // 13:14 hysteresis control
+    UINT32 Hist_enb:1; // 15 Hysteresis enable, active low
+    UINT32 Delay_line:6; // 16:21 Delay line values - Delay values for input or output
+    UINT32 Reserved:3; // 22:24 Reserved
+    UINT32 TPE:1; // 25 Trigger Positive Edge Enable
+    UINT32 TNE:1; // 26 Trigger Negative Edge Enable
+    UINT32 Reserved2:3; // 27:29 Reserved
+    UINT32 i1p5sel:1; // 30
+    UINT32 IODEN:1; // 31 : Open Drain enable. Active high
+	} r;
+} PAD_CONF0;
+
+typedef union{
+  UINT32 dw;
+  struct {
+    UINT32 instr:16; // 0:15 Pad (N) strength.
+    UINT32 ipstr:16; // 16:31 Pad (P) strength.
+  }r;
+} PAD_CONF1;
+
+typedef union{
+  UINT32 dw;
+  struct {
+    UINT32 pad_val:1; // 0 These registers are implemented as dual read/write with dedicated storage each.
+    UINT32 ioutenb:1; // 1 output enable
+    UINT32 iinenb:1; // 2 input enable
+    UINT32 Reserved:29; // 3:31 Reserved
+  }r;
+} PAD_VAL;
+
+typedef union{
+  UINT32 GPI;
+  struct {
+    UINT32 ihbpen:1; // 0 Pad high by pass enable
+    UINT32 ihbpinen:1; // 1 Pad high by pass input
+    UINT32 instaticen:1; // 2 TBD
+    UINT32 ipstaticen:1; // 3 TBD
+    UINT32 Overide_strap_pin :1; // 4 DFX indicates if it wants to override the strap pin value on this pad, if exists.
+    UINT32 Overide_strap_pin_val:1; // 5 In case DFX need to override strap pin value and it exist for the specific pad, this value will be used.
+    UINT32 TestMode_Pin_Mux:3; // 6:9 DFX Pin Muxing
+  }r;
+} PAD_DFT;
+
+//
+// GPIO_USAGE value need to matche the PAD_VAL input/output enable bits.
+//
+typedef enum {
+  Native = 0xFF,  // Native, no need to set PAD_VALUE
+  GPI = 2,    // GPI, input only in PAD_VALUE
+  GPO = 4,    // GPO, output only in PAD_VALUE
+  GPIO = 0,      // GPIO, input & output
+  TRISTS = 6,      // Tri-State
+  GPIO_NONE
+} GPIO_USAGE;
+
+typedef enum {
+  LO = 0,
+  HI = 1,
+  NA = 0xFF
+} GPO_D4;
+
+typedef enum {
+  F0 = 0,
+  F1 = 1,
+  F2 = 2,
+  F3 = 3,
+  F4 = 4,
+  F5 = 5,
+  F6 = 6,
+  F7 = 7
+} GPIO_FUNC_NUM;
+
+//
+// Mapping to CONF0 bit 27:24
+// Note: Assume "Direct Irq En" is not set, unless specially notified.
+//
+typedef enum {
+  TRIG_ = 0,
+  TRIG_Edge_High = /*BIT3 |*/ BIT1,	// Positive Edge (Rasing)
+  TRIG_Edge_Low  = /*BIT3 |*/ BIT2,	// Negative Edge (Falling)
+  TRIG_Edge_Both = /*BIT3 |*/ BIT2 | BIT1,	// Both Edge
+  TRIG_Level_High= /*BIT3 |*/ BIT1 | BIT0,	// Level High
+  TRIG_Level_Low = /*BIT3 |*/ BIT2 | BIT0,	// Level Low
+} INT_TYPE;
+
+typedef enum {
+  P_20K_H,	// Pull Up 20K
+  P_20K_L,	// Pull Down 20K
+  P_10K_H,	// Pull Up 10K
+  P_10K_L,	// Pull Down 10K
+  P_2K_H,	// Pull Up 2K
+  P_2K_L,	// Pull Down 2K
+  P_NONE      // Pull None
+} PULL_TYPE;
+
+#ifdef EFI_DEBUG
+  #define GPIO_INIT_ITEM(pad_name, usage, gpod4, func, int_cap, int_type, pull, offset) {pad_name, usage, gpod4, func, /*int_cap,*/ TRIG_##int_type, P_##pull, offset}
+#else
+  #define GPIO_INIT_ITEM(pad_name, usage, gpod4, func, int_cap, int_type, pull, offset) {          usage, gpod4, func, /*int_cap,*/ TRIG_##int_type, P_##pull, offset}
+#endif
+
+//
+// GPIO CONF & PAD Initialization Data Structure for BayLake GPIOs bits.
+// NC = NCORE, SC = SCORE, SS= SSUS
+//
+typedef struct {
+
+#ifdef EFI_DEBUG
+  char         pad_name[32];// GPIO Pin Name for debug purpose
+#endif
+
+  GPIO_USAGE     usage;     // GPIO pin used as Native mode or GPI/GPO/GPIO mode
+  GPO_D4         gpod4;     // GPO default value
+  GPIO_FUNC_NUM  func;      // Function Number (F0~F7)
+  INT_TYPE       int_type;  // Edge or Level trigger, low or high active
+  PULL_TYPE      pull;      // Pull Up or Down
+  UINT8          offset;    // Equal with (PCONF0 register offset >> 4 bits)
+} GPIO_CONF_PAD_INIT;
+
+//
+//typedef UINT64 BOARD_FEATURES
+//
+typedef struct _EFI_PLATFORM_INFO_HOB {
+  UINT16                      PlatformType; // Platform Type
+  UINT8                       BoardId;             // Board ID
+  UINT8                       BoardRev;            // Board Revision
+  PLATFORM_FLAVOR             PlatformFlavor;      // Platform Flavor
+  UINT8                       DDRDaughterCardCh0Id;// DDR daughter card channel 0 id
+  UINT8                       DDRDaughterCardCh1Id;// DDR daughter card channel 1 id
+  UINT8                       ECOId;               // ECO applied on platform
+  UINT16                      IohSku;
+  UINT8                       IohRevision;
+  UINT16                      IchSku;
+  UINT8                       IchRevision;
+  EFI_PLATFORM_PCI_DATA       PciData;
+  EFI_PLATFORM_CPU_DATA       CpuData;
+  EFI_PLATFORM_MEM_DATA       MemData;
+  EFI_PLATFORM_SYS_DATA       SysData;
+  EFI_PLATFORM_IGD_DATA       IgdData;
+  UINT8                       RevisonId;           // Structure Revision ID
+  EFI_PHYSICAL_ADDRESS        PlatformCfioData;
+  EFI_PHYSICAL_ADDRESS        PlatformGpioData_NC;
+  EFI_PHYSICAL_ADDRESS        PlatformGpioData_SC;
+  EFI_PHYSICAL_ADDRESS        PlatformGpioData_SUS;
+  EFI_PHYSICAL_ADDRESS        PlatformGpioData_NC_TRI;
+  EFI_PHYSICAL_ADDRESS        PlatformGpioData_SC_TRI;
+  EFI_PHYSICAL_ADDRESS        PlatformGpioData_SUS_TRI;
+  EFI_PHYSICAL_ADDRESS        PlatformGpioData_SUS_PR1;
+  EFI_PHYSICAL_ADDRESS        PlatformGpioData_SC_PR1_1;
+  EFI_PHYSICAL_ADDRESS        PlatformGpioData_SUS_PR1_1;
+
+  UINT8                       CfioEnabled;
+  UINT32                      SsidSvid;
+  UINT16                      AudioSubsystemDeviceId;
+  UINT64                      AcpiOemId;
+  UINT64                      AcpiOemTableId;
+  UINT16                      MemCfgID;
+} EFI_PLATFORM_INFO_HOB;
+
+#pragma pack()
+
+EFI_STATUS
+GetPlatformInfoHob (
+  IN CONST EFI_PEI_SERVICES           **PeiServices,
+  OUT EFI_PLATFORM_INFO_HOB           **PlatformInfoHob
+  );
+
+
+EFI_STATUS
+InstallPlatformClocksNotify (
+  IN CONST EFI_PEI_SERVICES           **PeiServices
+  );
+
+EFI_STATUS
+InstallPlatformSysCtrlGPIONotify (
+  IN CONST EFI_PEI_SERVICES           **PeiServices
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SensorInfoVariable.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SensorInfoVariable.h
new file mode 100644
index 0000000000..19eee2b729
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SensorInfoVariable.h
@@ -0,0 +1,279 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+
+Module Name:
+
+  SensorInfoVariable.h
+
+Abstract:
+
+  GUID used for Sensor Info variable.
+
+--*/
+
+
+//
+//  Module:         SensorInfoVariable.h
+//
+//  Description:    Provides  structure  and  literal  definitions for the
+//                  Sensor Information Variable.  The  BIOS  will  provide
+//                  this  variable  to  runtime  applications  via the EFI
+//                  GetVariable function.
+//
+//  Notes:      1.  When defining and initializing the variable within the
+//                  BIOS, the module will define the structure  using  the
+//                  typedef  macros  in  a block. For an ATX board using a
+//                  single Heceta 6P, which has 4 temperature  sensors,  6
+//                  voltage  sensors,  4 fan speed sensors and 3 fan speed
+//                  controllers, this block would be declared as follows:
+//
+//                      TYPEDEF_TEMP_SENSOR_SECTION(4);
+//                      TYPEDEF_VOLT_SENSOR_SECTION(6);
+//                      TYPEDEF_FAN_SENSOR_SECTION(4);
+//                      TYPEDEF_FAN_CONTROLLER_SENSOR(3);
+//                      TYPEDEF_SENSOR_INFO_VAR;
+//
+//              2.  When crafting code to access the variable, the  module
+//                  will  also  need  to  invoke  the  typedef macros in a
+//                  block but, since it cannot declare a structure for the
+//                overall variable (because array lengths will vary), it
+//                cannot  use  TYPEDEF_SENSOR_INFO_VAR.  The  block will
+//                typically be used as follows:
+//
+//                      TYPEDEF_TEMP_SENSOR_SECTION(1);
+//                     TYPEDEF_VOLT_SENSOR_SECTION(1);
+//                     TYPEDEF_FAN_SENSOR_SECTION(1);
+//                     TYPEDEF_FAN_CONTROLLER_SENSOR(1);
+//
+//                 The structure buffer should instead be declared  as  a
+//                 BYTE  array. Pointers to the various sections can then
+//                  be built using the XXXX_SECTION_LEN macros...
+//
+
+
+#ifndef _SENSOR_INFO_VAR_GUID_H_
+#define _SENSOR_INFO_VAR_GUID_H_
+
+#define SENSOR_INFO_VAR_GUID \
+  { \
+    0xE59E7B4D, 0x06DC, 0x44AB, 0xB3, 0x6D, 0x5E, 0xD7, 0x78, 0x9C, 0x53, 0x0A \
+  }
+
+extern EFI_GUID gEfiSensorInfoVarGuid;
+extern CHAR16   gEfiSensorInfoVarName[];
+extern CHAR16   gEfiSensorInfoVarNameWithPassword[];
+
+#define SENSOR_INFO_VAR_NAME L"SensorInfoVar"
+#define SENSOR_INFO_VAR_NAME_WITH_PASSWORD SENSOR_INFO_VAR_NAME L"S4k?A^7!"
+
+//
+// Sensor/Controller usage definitions
+//
+
+#define UNKNOWN_OTHER                   0
+
+//
+// Temperature Sensors
+//
+#define CPU_CORE_TEMPERATURE            1
+#define CPU_DIE_TEMPERATURE             2
+#define ICH_TEMPERATURE                 3
+#define MCH_TEMPERATURE                 4
+#define VR_TEMPERATURE                  5
+#define MEMORY_TEMPERATURE              6
+#define MOTHERBOARD_AMBIENT_TEMPERATURE 7
+#define SYSTEM_AMBIENT_AIR_TEMPERATURE  8
+#define CPU_INLET_AIR_TEMPERATURE       9
+#define SYSTEM_INLET_AIR_TEMPERATURE    10
+#define SYSTEM_OUTLET_AIR_TEMPERATURE   11
+#define PSU_HOTSPOT_TEMPERATURE         12
+#define PSU_INLET_AIR_TEMPERATURE       13
+#define PSU_OUTLET_AIR_TEMPERATURE      14
+#define DRIVE_TEMPERATURE               15
+#define GPU_TEMPERATURE                 16
+#define IOH_TEMPERATURE                 17
+
+#define LAST_TEMPERATURE                17
+
+//
+// Voltage Sensors
+//
+#define PLUS_12_VOLTS                   1
+#define NEG_12_VOLTS                    2
+#define PLUS_5_VOLTS                    3
+#define PLUS_5_VOLT_BACKUP              4
+#define NEG_5_VOLTS                     5
+#define PLUS_3P3_VOLTS                  6
+#define PLUS_2P5_VOLTS                  7
+#define PLUS_1P5_VOLTS                  8
+#define CPU_1_VCCP_VOLTAGE              9
+#define CPU_2_VCCP_VOLTAGE              10
+#define CPU_3_VCCP_VOLTAGE              11
+#define CPU_4_VCCP_VOLTAGE              12
+#define PSU_INPUT_VOLTAGE               13
+#define MCH_VCC_VOLTAGE                 14
+#define PLUS_3P3_VOLT_STANDBY           15
+#define CPU_VTT_VOLTAGE                 16
+#define PLUS_1P8_VOLTS                  17
+
+#define LAST_VOLTAGE                    17
+
+//
+// Fan Speed Sensors and Controllers.
+//
+#define CPU_COOLING_FAN                 1
+#define SYSTEM_COOLING_FAN              2
+#define MCH_COOLING_FAN                 3
+#define VR_COOLING_FAN                  4
+#define CHASSIS_COOLING_FAN             5
+#define CHASSIS_INLET_FAN               6
+#define CHASSIS_OUTLET_FAN              7
+#define PSU_COOLING_FAN                 8
+#define PSU_INLET_FAN                   9
+#define PSU_OUTLET_FAN                  10
+#define DRIVE_COOLING_FAN               11
+#define GPU_COOLING_FAN                 12
+#define AUX_COOLING_FAN                 13
+#define IOH_COOLING_FAN                 14
+
+#define LAST_FAN                        14
+
+//
+// Fan Type Definitions
+//
+#define FAN_TYPE_UNKNOWN                0
+#define FAN_3WIRE_PULSE                 1
+#define FAN_3WIRE_VOLTAGE               2
+#define FAN_4WIRE                       3
+
+#pragma pack(1)
+
+//
+// TEMP_SENSOR_INFO - Structure providing info for a temperature sensor.
+//
+typedef struct _TEMP_SENSOR_INFO
+{
+    UINT8                               byDevice;       // Device index
+    UINT8                               byIndex;        // Physical sensor index
+    UINT8                               byUsage;        // Usage indicator
+    UINT8                               bRelative;      // Relative vs. Absolute readings
+
+} TEMP_SENSOR_INFO, *P_TEMP_SENSOR_INFO;
+
+//
+// TYPEDEF_TEMP_SENSOR_SECTION - Macro that can be used to typedef the
+// TEMP_SENSOR_SECTION structure, which provides information about all
+// temperature sensors.
+//
+#define TYPEDEF_TEMP_SENSOR_SECTION(count)                              \
+typedef struct _TEMP_SENSOR_SECTION                                     \
+{                                                                       \
+    UINT8                               byCount;                        \
+    TEMP_SENSOR_INFO                    stSensor[count];                \
+                                                                        \
+} TEMP_SENSOR_SECTION, *P_TEMP_SENSOR_SECTION
+
+//
+// VOLT_SENSOR_INFO - Structure providing info for a voltage sensor.
+//
+typedef struct _VOLT_SENSOR_INFO
+{
+    UINT8                               byDevice;       // Device index
+    UINT8                               byIndex;        // Physical sensor index
+    UINT8                               byUsage;        // Usage indicator
+
+} VOLT_SENSOR_INFO, *P_VOLT_SENSOR_INFO;
+
+//
+// TYPEDEF_VOLT_SENSOR_SECTION - Macro that can be used to typedef the
+// VOLT_SENSOR_SECTION structure, which provides information about all
+// voltage sensors.
+//
+#define TYPEDEF_VOLT_SENSOR_SECTION(count)                              \
+typedef struct _VOLT_SENSOR_SECTION                                     \
+{                                                                       \
+    UINT8                               byCount;                        \
+    VOLT_SENSOR_INFO                    stSensor[count];                \
+                                                                        \
+} VOLT_SENSOR_SECTION, *P_VOLT_SENSOR_SECTION
+
+//
+// FAN_SENSOR_INFO - Structure providing info for a fan speed sensor.
+//
+typedef struct _FAN_SENSOR_INFO
+{
+    UINT8                               byDevice;       // Device index
+    UINT8                               byIndex;        // Physical sensor index
+    UINT8                               byUsage;        // Usage indicator
+    UINT8                               byType;         // Fan type
+    UINT8                               byController;   // Associated Fan Controller
+
+} FAN_SENSOR_INFO, *P_FAN_SENSOR_INFO;
+
+//
+// TYPEDEF_FAN_SENSOR_SECTION - Macro that can be used to typedef the
+// FAN_SENSOR_SECTION structure, which provides information about all fan
+// speed sensors.
+//
+#define TYPEDEF_FAN_SENSOR_SECTION(count)                               \
+typedef struct _FAN_SENSOR_SECTION                                      \
+{                                                                       \
+    UINT8                               byCount;                        \
+    FAN_SENSOR_INFO                     stSensor[count];                \
+                                                                        \
+} FAN_SENSOR_SECTION, *P_FAN_SENSOR_SECTION
+
+//
+// FAN_CONTROLLER_INFO - Structure providing info for a fan speed controller.
+//
+#define MAX_ASSOC_FANS                  4
+#define ASSOC_UNUSED                    0xFF
+
+typedef struct _FAN_CONTROLLER_INFO
+{
+    UINT8                               byDevice;       // Device index
+    UINT8                               byIndex;        // Physical Controller Index
+    UINT8                               byUsage;        // Usage Indicator
+    UINT8                               byFan[MAX_ASSOC_FANS]; // Associated Fan Sensors
+
+} FAN_CONTROLLER_INFO, *P_FAN_CONTROLLER_INFO;
+
+//
+// TYPEDEF_FAN_CONTROLLER_SECTION - Macro that can be used to typedef the
+// FAN_CONTROLLER_SECTION structure, which provides information about all
+// fan speed controllers.
+//
+#define TYPEDEF_FAN_CONTROLLER_SECTION(count)                           \
+typedef struct _FAN_CONTROLLER_SECTION                                  \
+{                                                                       \
+    UINT8                               byCount;                        \
+    FAN_CONTROLLER_INFO                 stController[count];            \
+                                                                        \
+} FAN_CONTROLLER_SECTION, *P_FAN_CONTROLLER_SECTION
+
+//
+// TYPEDEF_SENSOR_INFO_VAR - Macro that can be used to typedef the
+// SENSOR_INFO_VAR structure, which provides information about all sensors
+// and fan speed controllers. The other TYPEDEF macros must be invoked
+// before using this one...
+//
+#define TYPEDEF_SENSOR_INFO_VAR                                         \
+typedef struct _SENSOR_INFO_VAR                                         \
+{                                                                       \
+    TEMP_SENSOR_SECTION                 stTemps;                        \
+    VOLT_SENSOR_SECTION                 stVolts;                        \
+    FAN_SENSOR_SECTION                  stFans;                         \
+    FAN_CONTROLLER_SECTION              stCtrls;                        \
+                                                                        \
+} SENSOR_INFO_VAR, *P_SENSOR_INFO_VAR
+
+#pragma pack()
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SetupVariable.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SetupVariable.h
new file mode 100644
index 0000000000..32f121892b
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SetupVariable.h
@@ -0,0 +1,1344 @@
+/** @file
+
+  Copyright (c) 2004  - 2018, Intel Corporation. All rights reserved.<BR>
+
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+
+Module Name:
+
+    SetupVariable.h
+
+Abstract:
+
+    Driver configuration include file
+
+
+**/
+
+#ifndef _SETUP_VARIABLE_H
+#define _SETUP_VARIABLE_H
+
+//
+// ---------------------------------------------------------------------------
+//
+// Driver Configuration
+//
+// ---------------------------------------------------------------------------
+//
+
+//
+// {EC87D643-EBA4-4bb5-A1E5-3F3E36B20DA9}
+//
+#define SYSTEM_CONFIGURATION_GUID\
+  { \
+    0xec87d643, 0xeba4, 0x4bb5, 0xa1, 0xe5, 0x3f, 0x3e, 0x36, 0xb2, 0xd, 0xa9 \
+  }
+
+#define ROOT_SECURITY_GUID\
+  { \
+    0xd387d688, 0xeba4, 0x45b5, 0xa1, 0xe5, 0x3f, 0x3e, 0x36, 0xb2, 0xd, 0x37 \
+  }
+
+//
+// {6936B3BD-4350-46d9-8940-1FA20961AEB1}
+//
+#define SYSTEM_ROOT_MAIN_GUID\
+  { \
+     0x6936b3bd, 0x4350, 0x46d9, 0x89, 0x40, 0x1f, 0xa2, 0x9, 0x61, 0xae, 0xb1 \
+  }
+
+//
+// {21FEE8DB-0D29-477e-B5A9-96EB343BA99C}
+//
+#define ADDITIONAL_SYSTEM_INFO_GUID\
+  { \
+     0x21fee8db, 0xd29, 0x477e, 0xb5, 0xa9, 0x96, 0xeb, 0x34, 0x3b, 0xa9, 0x9c \
+  }
+
+#define SETUP_GUID { 0xEC87D643, 0xEBA4, 0x4BB5, 0xA1, 0xE5, 0x3F, 0x3E, 0x36, 0xB2, 0x0D, 0xA9 }
+
+// {1B838190-4625-4ead-ABC9-CD5E6AF18FE0}
+#define EFI_HII_EXPORT_DATABASE_GUID { 0x1b838190, 0x4625, 0x4ead, 0xab, 0xc9, 0xcd, 0x5e, 0x6a, 0xf1, 0x8f, 0xe0 }
+
+#define PASSWORD_MAX_SIZE               20
+
+#define MAX_CUSTOM_VID_TABLE_STATES 6
+//
+// Overclocking Source Defines
+//
+#define OVERCLOCK_SOURCE_BIOS       0
+#define OVERCLOCK_SOURCE_OS         1
+
+#define PCH_PCIE_MAX_ROOT_PORTS     4
+
+#pragma pack(1)
+
+// NOTE: When you add anything to this structure,
+//   you MUST add it to the very bottom!!!!
+//   You must make sure the structure size is able to divide by 32!
+typedef struct {
+
+  //
+  // Floppy
+  //
+  UINT8         Floppy;
+  UINT8         FloppyLockHide;
+
+  UINT8         FloppyWriteProtect;
+  UINT8         FloppyWriteProtectLockHide;
+
+  //
+  // System ports
+  //
+  UINT8         Serial;
+  UINT8         SerialLockHide;
+
+  UINT8         Serial2;
+  UINT8         Serial2LockHide;
+
+  UINT8         Parallel;
+  UINT8         ParallelLockHide;
+
+  UINT8         ParallelMode;
+  UINT8         ParallelModeLockHide;
+
+  UINT8         AllUsb;
+  UINT8         UsbPortsLockHide;
+
+  UINT8         Usb2;
+  UINT8         Usb2LockHide;
+
+  UINT8         UsbLegacy;
+  UINT8         UsbLegacyLockHide;
+
+  UINT8         Audio;
+  UINT8         AudioLockHide;
+
+  UINT8         Lan;
+  UINT8         LanLockHide;
+
+  //
+  // Keyboard
+  //
+  UINT8         Numlock;
+  UINT8         NumlockLockHide;
+
+  //
+  // ECIR
+  //
+  UINT8         ECIR;
+  UINT8         ECIRLockHide;
+
+  //
+  // Power State
+  //
+  UINT8         PowerState;
+  UINT8         PowerStateLockHide;
+
+  //
+  // Wake on RTC variables
+  //
+  UINT8         WakeOnRtcS5;
+  UINT8         WakeOnRtcS5LockHide;
+  UINT8         RTCWakeupDate;
+  UINT8         RTCWakeupDateLockHide;
+  UINT8         RTCWakeupTimeHour;
+  UINT8         RTCWakeupHourLockHide;
+  UINT8         RTCWakeupTimeMinute;
+  UINT8         RTCWakeupMinuteLockHide;
+  UINT8         RTCWakeupTimeSecond;
+  UINT8         RTCWakeupSecondLockHide;
+
+  //
+  // Wake On Lan
+  //
+  UINT8         WakeOnLanS5;
+  UINT8         WakeOnLanS5LockHide;
+
+  //Spread spectrum
+  UINT8         SpreadSpectrum;
+
+  //
+  // Boot Order
+  //
+  UINT8         BootOrder[8];
+  UINT8         BootOrderLockHide;
+
+  //
+  // Hard Drive Boot Order
+  //
+  UINT8         HardDriveBootOrder[8];
+  UINT8         HardDriveBootOrderLockHide;
+
+  //
+  // CD Drive Boot Order
+  //
+  UINT8         CdDriveBootOrder[4];
+  UINT8         CdDriveBootOrderLockHide;
+
+  //
+  // FDD Drive Boot Order
+  //
+  UINT8         FddDriveBootOrder[4];
+  UINT8         FddDriveBootOrderLockHide;
+
+  //
+  // Drive Boot Order
+  //
+  UINT8         DriveBootOrder[16];
+  UINT8         DriveBootOrderLockHide;
+
+  //
+  // Boot Menu Type
+  //
+  UINT8         BootMenuType;
+  UINT8         BootMenuTypeLockHide;
+
+  //
+  // Boot from Removable Devices
+  //
+  UINT8         BootFloppy;
+  UINT8         BootFloppyLockHide;
+
+  //
+  // Boot from Optical Devices
+  //
+  UINT8         BootCd;
+  UINT8         BootCdLockHide;
+
+  //
+  // Boot from Network
+  //
+  UINT8         BootNetwork;
+  UINT8         BootNetworkLockHide;
+
+  //
+  // Boot USB
+  //
+  UINT8         BootUsb;
+  UINT8         BootUsbLockHide;
+
+  //
+  // USB Zip Emulation Type
+  //
+  UINT8         UsbZipEmulation;
+  UINT8         UsbZipEmulationLockHide;
+
+  //
+  // USB Devices Boot First in Boot Order
+  //
+  UINT8         UsbDevicesBootFirst;
+  UINT8         UsbDevicesBootFirstLockHide;
+
+  //
+  // USB Boot Device SETUP Emulation
+  //
+  UINT8         UsbSetupDeviceEmulation;
+  UINT8         UsbSetupDeviceEmulationLockHide;
+
+  //
+  // BIOS INT13 Emulation for USB Mass Devices
+  //
+  UINT8         UsbBIOSINT13DeviceEmulation;
+  UINT8         UsbBIOSINT13DeviceEmulationLockHide;
+
+  //
+  // BIOS INT13 Emulation Size for USB Mass Devices
+  //
+  UINT16        UsbBIOSINT13DeviceEmulationSize;
+  UINT8         UsbBIOSINT13DeviceEmulationSizeLockHide;
+
+  //
+  // Dummy place holder to prevent VFR compiler problem.
+  //
+  UINT16        DummyDataForVfrBug;  // Don't change or use.
+
+  //
+  // Language Select
+  //
+  UINT8         LanguageSelect;
+
+  //
+  // SATA Type (Ide, Ahci, Raid)
+  //
+  UINT8         SataType;
+  UINT8         SataTypeLockHide;
+  UINT8         SataTestMode;
+
+  //
+  // Fixed Disk Boot Sector (Fdbs)
+  //
+  UINT8         Fdbs;
+  UINT8         FdbsLockHide;
+
+  //
+  // DisplaySetupPrompt
+  //
+  UINT8         DisplaySetupPrompt;
+  UINT8         DisplaySetupPromptLockHide;
+
+  //
+  // ASF
+  //
+  UINT8         Asf;
+  UINT8         AsfLockHide;
+
+  //
+  // Event Logging
+  //
+  UINT8         EventLogging;
+  UINT8         EventLoggingLockHide;
+
+  //
+  // Clear Event Log
+  //
+  UINT8         ClearEvents;
+  UINT8         ClearEventsLockHide;
+
+  //
+  // Expansion Card Text
+  //
+  UINT8         ExpansionCardText;
+  UINT8         ExpansionCardTextLockHide;
+
+  //
+  // Video Adaptor
+  //
+  UINT8         PrimaryVideoAdaptor;
+  UINT8         PrimaryVideoAdaptorLockHide;
+
+  //
+  // Chassis intrusion
+  //
+  UINT8         IntruderDetection;
+  UINT8         IntruderDetectionLockHide;
+
+  //
+  // User Access Level
+  //
+  UINT8         UserPasswordLevel;
+  UINT8         UserPasswordLevelLockHide;
+
+  //
+  // Maximum FSB Automatic/Disable
+  //
+  UINT8         MaxFsb;
+  UINT8         MaxFsbLockHide;
+
+  //
+  // Hard Disk Pre-delay
+  //
+  UINT8         HddPredelay;
+  UINT8         HddPredelayLockHide;
+
+  //
+  // S.M.A.R.T. Mode
+  //
+  UINT8         SmartMode;
+  UINT8         SmartModeLockHide;
+
+  //
+  // ACPI Suspend State
+  //
+  UINT8         AcpiSuspendState;
+  UINT8         AcpiSuspendStateLockHide;
+
+  //
+  // PCI Latency Timer
+  //
+  UINT8         PciLatency;
+  UINT8         PciLatencyLockHide;
+
+  //
+  // Fan Control
+  //
+  UINT8         FanControl;
+  UINT8         FanControlLockHide;
+
+  //
+  // CPU Fan Control
+  //
+  UINT8         CpuFanControl;
+  UINT8         CpuFanControlLockHide;
+
+  //
+  // Lowest Fan Speed
+  //
+  UINT8         LowestFanSpeed;
+  UINT8         LowestFanSpeedLockHide;
+
+  //
+  // Processor (CPU)
+  //
+  UINT8         CpuFlavor;
+
+  UINT8         CpuidMaxValue;
+  UINT8         CpuidMaxValueLockHide;
+
+  UINT8         ExecuteDisableBit;
+  UINT8         ExecuteDisableBitLockHide;
+
+  //
+  // EIST or GV3 setup option
+  //
+  UINT8         ProcessorEistEnable;
+  UINT8         ProcessorEistEnableLockHide;
+
+  //
+  // C1E Enable
+  //
+  UINT8         ProcessorC1eEnable;
+  UINT8         ProcessorC1eEnableLockHide;
+
+  //
+  // Enabling CPU C-States of processor
+  //
+  UINT8         ProcessorCcxEnable;
+  UINT8         ProcessorCcxEnableLockHide;
+
+  //
+  // Package C-State Limit
+  //
+  UINT8         PackageCState;
+  UINT8         PackageCStateLockHide;
+
+  //
+  // Enable/Disable NHM C3(ACPI C2) report to OS
+  //
+  UINT8         OSC2Report;
+  UINT8         OSC2ReportLockHide;
+
+  //
+  // Enable/Disable NHM C6(ACPI C3) report to OS
+  //
+  UINT8         C6Enable;
+  UINT8         C6EnableLockHide;
+
+  //
+  // Enable/Disable NHM C7(ACPI C3) report to OS
+  //
+  UINT8         C7Enable;
+  UINT8         C7EnableLockHide;
+
+  //
+  // EIST/PSD Function select option
+  //
+  UINT8         ProcessorEistPsdFunc;
+  UINT8         ProcessorEistPsdFuncLockHide;
+
+  //
+  //
+  //
+  UINT8         CPU00;
+  UINT8         CPU01;
+
+  //
+  //
+  //
+  UINT8         CPU02;
+  UINT8         CPU03;
+
+  //
+  //
+  //
+  UINT8         CPU04;
+  UINT8         CPU05;
+
+  //
+  //
+  //
+  UINT8         CPU06;
+  UINT8         CPU07;
+
+  //
+  //
+  //
+  UINT8         CPU08;
+  UINT8         CPU09;
+
+  //
+  //
+  //
+  UINT8         CPU10;
+  UINT8         CPU11;
+
+  //
+  //
+  //
+  UINT8         CPU12;
+  UINT8         CPU13;
+
+  //
+  //
+  //
+  UINT8         CPU14;
+  UINT8         CPU15;
+
+  //
+  //
+  //
+  UINT8         CPU16;
+  UINT8         CPU17;
+
+  //
+  //
+  //
+  UINT8         CPU18;
+  UINT8         CPU19;
+
+  //
+  //
+  //
+  UINT8         CPU20;
+  UINT8         CPU21;
+
+  //
+  //
+  //
+  UINT8         CPU22;
+  UINT8         CPU23;
+
+  //
+  //
+  //
+  UINT8         CPU24;
+  UINT8         CPU25;
+
+  //
+  //
+  //
+  UINT8         CPU26;
+  UINT8         CPU27;
+
+  //
+  //
+  //
+  UINT8         CPU28;
+  UINT8         CPU29;
+
+  //
+  //
+  //
+  UINT8         CPU30;
+  UINT8         CPU31;
+
+  //
+  //
+  //
+  UINT8         CPU32;
+  UINT8         CPU33;
+
+  //
+  //
+  //
+  UINT8         CPU34;
+  UINT8         CPU35;
+
+  //
+  //
+  //
+  UINT8         CPU36;
+  UINT8         CPU37;
+
+  //
+  //
+  //
+  UINT8         CPU38;
+  UINT8         CPU39;
+
+  //
+  //
+  //
+  UINT16        CPU40;
+  UINT8         CPU41;
+
+  //
+  //
+  //
+  UINT8         CPU42;
+  UINT8         CPU43;
+
+  //
+  //
+  //
+  UINT16        CPU44;
+  UINT8         CPU45;
+
+  //
+  //
+  //
+  UINT8         CPU46;
+  UINT8         CPU47;
+
+  //
+  //
+  //
+  UINT8         CPU48;
+  UINT8         CPU49;
+
+  //
+  //
+  //
+  UINT8         CPU50;
+  UINT8         CPU51;
+
+  //
+  //
+  //
+  UINT8         CPU52;
+  UINT8         CPU53;
+
+  //
+  //
+  //
+  UINT8         CPU54;
+  UINT8         CPU55;
+
+  //
+  //
+  //
+  UINT8         CPU56;
+  UINT8         CPU57;
+
+  //
+  //
+  //
+  UINT8         CPU58;
+  UINT8         CPU59;
+
+  //
+  //
+  //
+  UINT8         CPU60;
+  UINT8         CPU61;
+
+  //
+  //
+  //
+  UINT8         CPU62;
+  UINT8         CPU63;
+
+  //
+  //
+  //
+  UINT8         CPU64;
+  UINT8         CPU65;
+
+  //
+  //
+  //
+  UINT8         CPU66;
+  UINT8         CPU67;
+
+  //
+  //
+  //
+  UINT16        CPU68;
+  UINT8         CPU69;
+
+  //
+  //
+  //
+  UINT16        CPU70;
+
+  //
+  //
+  //
+  UINT8         CPU71;
+
+  //
+  //
+  //
+  UINT8         MEM00;
+  UINT8         MEM01;
+
+  //
+  //
+  //
+  UINT8         MEM02;
+  UINT8         MEM03;
+
+  UINT16        MEM04;
+  UINT8         MEM05;
+
+  UINT8         MEM06;
+  UINT8         MEM07;
+
+  UINT8         MEM08;
+  UINT8         MEM09;
+
+  UINT8         MEM10;
+  UINT8         MEM11;
+
+  UINT8         MEM12;
+  UINT8         MEM13;
+
+  UINT8         MEM14;
+  UINT8         MEM15;
+
+  UINT8         MEM16;
+  UINT8         MEM17;
+
+  UINT16        MEM18;
+  UINT8         MEM19;
+
+  UINT8         MEM20;
+  UINT8         MEM21;
+
+  UINT8         MEM22;
+  UINT8         MEM23;
+
+  UINT8         MEM24;
+  UINT8         MEM25;
+
+  UINT8         MEM26;
+  UINT8         MEM27;
+
+  UINT8         MEM28;
+  UINT8         MEM29;
+
+  UINT8         MEM30;
+  UINT8         MEM31;
+
+  UINT8         MEM32;
+  UINT8         MEM33;
+
+  UINT8         MEM34;
+  UINT8         MEM35;
+
+  //
+  //
+  //
+  UINT8         MEM36;
+  UINT8         MEM37;
+  UINT8         MEM38;
+  UINT8         MEM39;
+
+  //
+  //
+  //
+  UINT8         MEM40;
+  UINT8         MEM41;
+  UINT8         MEM42;
+  UINT8         MEM43;
+  UINT8         MEM44;
+  UINT8         MEM45;
+  UINT8         MEM46;
+  UINT8         MEM47;
+
+
+  //
+  // Port 80 decode 0/1 - PCI/LPC
+  UINT8         Port80Route;
+  UINT8         Port80RouteLockHide;
+
+  //
+  // ECC Event Logging
+  //
+  UINT8         EccEventLogging;
+  UINT8         EccEventLoggingLockHide;
+
+  //
+  // TPM Enable/Disable
+  //
+  UINT8         ETpm;
+
+  //
+  // TPM question  0 = Disabled, 1 = Enabled
+  //
+  UINT8         ETpmClear;
+
+  //
+  // Secondary SATA Controller question  0 = Disabled, 1 = Enabled
+  //
+  UINT8         ExtSata;
+  UINT8         ExtSataLockHide;
+
+  //
+  // Mode selection for Secondary SATA Controller (0=IDE, 1=RAID)
+  //
+  UINT8         ExtSataMode;
+  UINT8         ExtSataModeLockHide;
+
+  //
+  // LT Technology 0/1 -> Disable/Enable
+  //
+  UINT8         LtTechnology;
+  UINT8         LtTechnologyLockHide;
+
+  //
+  // HPET Support 0/1 -> Disable/Enable
+  //
+  UINT8         Hpet;
+  UINT8         HpetLockHide;
+
+  //
+  // ICH Function Level Reset enable/disable
+  //
+  UINT8         FlrCapability;
+  UINT8         FlrCapabilityLockHide;
+
+  // VT-d Option
+  UINT8         VTdSupport;
+  UINT8         VTdSupportLockHide;
+
+  UINT8         InterruptRemap;
+  UINT8         InterruptRemapLockHide;
+
+  UINT8         Isoc;
+  UINT8         IsocLockHide;
+
+  UINT8         CoherencySupport;
+  UINT8         CoherencySupportLockHide;
+
+  UINT8         ATS;
+  UINT8         ATSLockHide;
+
+  UINT8         PassThroughDma;
+  UINT8         PassThroughDmaLockHide;
+
+  //
+  // IGD option
+  //
+  UINT8         GraphicsDriverMemorySize;
+  UINT8         GraphicsDriverMemorySizeLockHide;
+
+
+  //
+  // Discrete SATA Type (Ide, Raid, Ahci)
+  //
+  UINT8         ExtSataMode2;
+  UINT8         ExtSataMode2LockHide;
+
+  UINT8         ProcessorReserve00;
+  UINT8         ProcessorReserve01;
+
+  //
+  // IGD Aperture Size question
+  //
+  UINT8         IgdApertureSize;
+  UINT8         IgdApertureSizeLockHide;
+
+  //
+  // Boot Display Device
+  //
+  UINT8         BootDisplayDevice;
+  UINT8         BootDisplayDeviceLockHide;
+
+
+  //
+  // System fan speed duty cycle
+  //
+  UINT8         SystemFanDuty;
+  UINT8         SystemFanDutyLockHide;
+
+
+  //
+  // S3 state LED indicator
+  //
+  UINT8         S3StateIndicator;
+  UINT8         S3StateIndicatorLockHide;
+
+  //
+  // S1 state LED indicator
+  //
+  UINT8         S1StateIndicator;
+  UINT8         S1StateIndicatorLockHide;
+
+  //
+  // PS/2 Wake from S5
+  //
+  UINT8         WakeOnS5Keyboard;
+  UINT8         WakeOnS5KeyboardLockHide;
+
+
+  //
+  // SATA Controller question  0 = Disabled, 1 = Enabled
+  //
+  UINT8         Sata;
+  UINT8         SataLockHide;
+
+  //
+  // PS2 port
+  //
+  UINT8         PS2;
+
+  //
+  // No VideoBeep
+  //
+  UINT8         NoVideoBeepEnable;
+
+  //
+  // Integrated Graphics Device
+  //
+  UINT8         Igd;
+
+  //
+  // Video Device select order
+  //
+  UINT8         VideoSelectOrder[8];
+
+  // Flash update sleep delay
+  UINT8         FlashSleepDelay;
+  UINT8         FlashSleepDelayLockHide;
+
+  //
+  // Boot Display Device2
+  //
+  UINT8         BootDisplayDevice2;
+  UINT8         BootDisplayDevice2LockHide;
+
+  //
+  // Flat Panel
+  //
+  UINT8         EdpInterfaceType;
+  UINT8         EdpInterfaceTypeLockHide;
+
+  UINT8         LvdsInterfaceType;
+  UINT8         LvdsInterfaceTypeLockHide;
+
+  UINT8         ColorDepth;
+  UINT8         ColorDepthLockHide;
+
+  UINT8         EdidConfiguration;
+  UINT8         EdidConfigurationLockHide;
+
+  UINT8         PwmReserved;
+  UINT8         MaxInverterPWMLockHide;
+
+  UINT8         PreDefinedEdidConfiguration;
+  UINT8         PreDefinedEdidConfigurationLockHide;
+
+  UINT16        ScreenBrightnessResponseTime;
+  UINT8         ScreenBrightnessResponseTimeLockHide;
+
+  UINT8         Serial3;
+  UINT8         Serial3LockHide;
+
+  UINT8         Serial4;
+  UINT8         Serial4LockHide;
+
+  UINT8         CurrentSetupProfile;
+  UINT8         CurrentSetupProfileLockHide;
+
+  //
+  // FSC system Variable
+  //
+  UINT8         CPUFanUsage;
+  UINT8         CPUFanUsageLockHide;
+  UINT16        CPUUnderSpeedthreshold;
+  UINT8         CPUUnderSpeedthresholdLockHide;
+  UINT8         CPUFanControlMode;
+  UINT8         CPUFanControlModeLockHide;
+  UINT16        Voltage12UnderVolts;
+  UINT8         Voltage12UnderVoltsLockHide;
+  UINT16        Voltage12OverVolts;
+  UINT8         Voltage12OverVoltsLockHide;
+  UINT16        Voltage5UnderVolts;
+  UINT8         Voltage5UnderVoltsLockHide;
+  UINT16        Voltage5OverVolts;
+  UINT8         Voltage5OverVoltsLockHide;
+  UINT16        Voltage3p3UnderVolts;
+  UINT8         Voltage3p3UnderVoltsLockHide;
+  UINT16        Voltage3p3OverVolts;
+  UINT8         Voltage3p3OverVoltsLockHide;
+  UINT16        Voltage2p5UnderVolts;
+  UINT8         Voltage2p5UnderVoltsLockHide;
+  UINT16        Voltage2p5OverVolts;
+  UINT8         Voltage2p5OverVoltsLockHide;
+  UINT16        VoltageVccpUnderVolts;
+  UINT8         VoltageVccpUnderVoltsLockHide;
+  UINT16        VoltageVccpOverVolts;
+  UINT8         VoltageVccpOverVoltsLockHide;
+  UINT16        Voltage5BackupUnderVolts;
+  UINT8         Voltage5BackupUnderVoltsLockHide;
+  UINT16        Voltage5BackupOverVolts;
+  UINT8         Voltage5BackupOverVoltsLockHide;
+  UINT16        VS3p3StbyUnderVolt;
+  UINT8         VS3p3StbyUnderVoltLockHide;
+  UINT16        VS3p3StbyOverVolt;
+  UINT8         VS3p3StbyOverVoltLockHide;
+  UINT8         CPUFanMinDutyCycle;
+  UINT8         CPUFanMinDutyCycleLockHide;
+  UINT8         CPUFanMaxDutyCycle;
+  UINT8         CPUFanMaxDutyCycleLockHide;
+  UINT8         CPUFanOnDutyCycle;
+  UINT8         CPUFanOnDutyCycleLockHide;
+  UINT16        CpuOverTemp;
+  UINT8         CpuOverTempLockHide;
+  UINT16        CpuControlTemp;
+  UINT8         CpuControlTempLockHide;
+  UINT16        CpuAllOnTemp;
+  UINT8         CpuAllOnTempLockHide;
+  UINT8         CpuResponsiveness;
+  UINT8         CpuResponsivenessLockHide;
+  UINT8         CpuDamping;
+  UINT8         CpuDampingLockHide;
+  UINT16        PchOverTemp;
+  UINT8         PchOverTempLockHide;
+  UINT16        PchControlTemp;
+  UINT8         PchControlTempLockHide;
+  UINT16        PchAllOnTemp;
+  UINT8         PchAllOnTempLockHide;
+  UINT8         PchResponsiveness;
+  UINT8         PchResponsivenessLockHide;
+  UINT8         PchDamping;
+  UINT8         PchDampingLockHide;
+  UINT16        MemoryOverTemp;
+  UINT8         MemoryOverTempLockHide;
+  UINT16        MemoryControlTemp;
+  UINT8         MemoryControlTempLockHide;
+  UINT16        MemoryAllOnTemp;
+  UINT8         MemoryAllOnTempLockHide;
+  UINT8         MemoryResponsiveness;
+  UINT8         MemoryResponsivenessLockHide;
+  UINT8         MemoryDamping;
+  UINT8         MemoryDampingLockHide;
+  UINT16        VROverTemp;
+  UINT8         VROverTempLockHide;
+  UINT16        VRControlTemp;
+  UINT8         VRControlTempLockHide;
+  UINT16        VRAllOnTemp;
+  UINT8         VRAllOnTempLockHide;
+  UINT8         VRResponsiveness;
+  UINT8         VRResponsivenessLockHide;
+  UINT8         VRDamping;
+  UINT8         VRDampingLockHide;
+
+  UINT8         LvdsBrightnessSteps;
+  UINT8         LvdsBrightnessStepsLockHide;
+  UINT8         EdpDataRate;
+  UINT8         EdpDataRateLockHide;
+  UINT16        LvdsPowerOnToBacklightEnableDelayTime;
+  UINT8         LvdsPowerOnToBacklightEnableDelayTimeLockHide;
+  UINT16        LvdsPowerOnDelayTime;
+  UINT8         LvdsPowerOnDelayTimeLockHide;
+  UINT16        LvdsBacklightOffToPowerDownDelayTime;
+  UINT8         LvdsBacklightOffToPowerDownDelayTimeLockHide;
+  UINT16        LvdsPowerDownDelayTime;
+  UINT8         LvdsPowerDownDelayTimeLockHide;
+  UINT16        LvdsPowerCycleDelayTime;
+  UINT8         LvdsPowerCycleDelayTimeLockHide;
+
+  UINT8         IgdFlatPanel;
+  UINT8         IgdFlatPanelLockHide;
+  UINT8         Lan2;
+  UINT8         Lan2LockHide;
+
+  UINT8         SwapMode;
+  UINT8         SwapModeLockHide;
+
+  UINT8         Sata0HotPlugCap;
+  UINT8         Sata0HotPlugCapLockHide;
+  UINT8         Sata1HotPlugCap;
+  UINT8         Sata1HotPlugCapLockHide;
+
+  UINT8         UsbCharging;
+  UINT8         UsbChargingLockHide;
+
+  UINT8         Cstates;
+  UINT8         EnableC4;
+  UINT8         EnableC6;
+
+  UINT8          FastBoot;
+  UINT8          EfiNetworkSupport;
+  UINT8          PxeRom;
+
+  //Add for PpmPlatformPlicy
+  UINT8          PPM00;
+  UINT8          PPM01;
+  UINT8          PPM02;
+  UINT8          PPM03;
+  UINT8          PPM04;
+  UINT8          PPM05;
+  UINT8          PPM06;
+  UINT8          PPM07;
+  UINT8          PPM08;
+  UINT8          PPM09;
+  UINT8          PPM10;
+  UINT8          QuietBoot;
+  UINT8          LegacyUSBBooting;
+
+  UINT8          PwmReserved02;
+  //
+  // Thermal Policy Values
+  //
+  UINT8           EnableDigitalThermalSensor;
+  UINT8           PassiveThermalTripPoint;
+  UINT8           PassiveTc1Value;
+  UINT8           PassiveTc2Value;
+  UINT8           PassiveTspValue;
+  UINT8           DisableActiveTripPoints;
+  UINT8           CriticalThermalTripPoint;
+  UINT8           IchPciExp[4];
+  UINT8           DeepStandby;
+  UINT8           AlsEnable;
+  UINT8           IgdLcdIBia;
+  UINT8           LogBootTime;
+
+
+  UINT8           PcieRootPortIOApic[4];
+  UINT8           IffsEnable;
+  UINT8           IffsOnS3RtcWake;
+  UINT8           IffsS3WakeTimerMin;
+  UINT8           IffsOnS3CritBattWake;
+  UINT8           IffsCritBattWakeThreshold;
+  UINT8           ScramblerSupport;
+  UINT8           SecureBoot;
+  UINT8           SecureBootCustomMode;
+  UINT8           SecureBootUserPhysicalPresent;
+  UINT8           CoreFreMultipSelect;
+  UINT8           MaxCState;
+  UINT8           PanelScaling;
+  UINT8           IgdLcdIGmchBlc;
+  UINT8           GfxBoost;
+  UINT8           IgdThermal;
+  UINT8           SEC00;
+  UINT8           fTPM;
+  UINT8           SEC02;
+  UINT8           SEC03;
+  UINT8           MeasuredBootEnable;
+  UINT8           UseProductKey;
+  //Image Signal Processor PCI Device Configuration
+  //
+  UINT8         ISPDevSel;
+  UINT8         ISPEn;
+  // Passwords
+  UINT16          UserPassword[PASSWORD_MAX_SIZE];
+  UINT16          AdminPassword[PASSWORD_MAX_SIZE];
+  UINT8           Tdt;
+  UINT8           Recovery;
+  UINT8           Suspend;
+  UINT8           TdtState;
+  UINT8           TdtEnrolled;
+  UINT8           PBAEnable;
+
+  UINT8           HpetBootTime;
+  UINT8           UsbDebug;
+  UINT8           Lpe;
+  //
+  // LPSS Configuration
+  //
+  UINT8           LpssPciModeEnabled;
+  //Scc
+  UINT8           LpsseMMCEnabled;
+  UINT8           LpssSdioEnabled;
+  UINT8           LpssSdcardEnabled;
+  UINT8           LpssSdCardSDR25Enabled;
+  UINT8           LpssSdCardDDR50Enabled;
+  UINT8           LpssMipiHsi;
+  UINT8           LpsseMMC45Enabled;
+  UINT8           LpsseMMC45DDR50Enabled;
+  UINT8           LpsseMMC45HS200Enabled;
+  UINT8           LpsseMMC45RetuneTimerValue;
+  UINT8           eMMCBootMode;
+
+  //LPSS2
+  UINT8           LpssDma1Enabled;
+  UINT8           LpssI2C0Enabled;
+  UINT8           LpssI2C1Enabled;
+  UINT8           LpssI2C2Enabled;
+  UINT8           LpssI2C3Enabled;
+  UINT8           LpssI2C4Enabled;
+  UINT8           LpssI2C5Enabled;
+  UINT8           LpssI2C6Enabled;
+  //LPSS1
+  UINT8           LpssDma0Enabled;
+  UINT8           LpssPwm0Enabled;
+  UINT8           LpssPwm1Enabled;
+  UINT8           LpssHsuart0Enabled;
+  UINT8           LpssHsuart1Enabled;
+  UINT8           LpssSpiEnabled;
+  UINT8           I2CTouchAd;
+
+  UINT8   GTTSize;
+  //
+  // DVMT5.0 Graphic memory setting
+  //
+  UINT8   IgdDvmt50PreAlloc;
+  UINT8   IgdDvmt50TotalAlloc;
+  UINT8   IgdTurboEnabled;
+
+  //
+  // Usb Config
+  //
+  UINT8   UsbAutoMode;       // PCH controller Auto mode
+  UINT8   UsbXhciSupport;
+  UINT8   Hsic0;
+  UINT8   PchUsb30Mode;
+  UINT8   PchUsb30Streams;
+  UINT8   PchUsb20;
+  UINT8   PchUsbPerPortCtl;
+  UINT8   PchUsbPort[8];
+  UINT8   PchUsbRmh;
+  UINT8   PchUsbOtg;
+  UINT8   PchUsbVbusOn;       //OTG VBUS control
+  UINT8   PchFSAOn;       //FSA control
+  UINT8   EhciPllCfgEnable;
+
+
+  //Gbe
+  UINT8         PcieRootPortSpeed[PCH_PCIE_MAX_ROOT_PORTS];
+  UINT8   SlpLanLowDc;
+
+  UINT8   ISCT00;
+  UINT8   ISCT01;
+  UINT8   ISCT02;
+  UINT8   ISCT03;
+  UINT8    ISCT04;
+  UINT8    ISCT05;
+  UINT8    ISCT06;
+  UINT8    ISCT07;
+  //
+  // Azalia Configuration
+  //
+  UINT8   PchAzalia;
+  UINT8   AzaliaVCiEnable;
+  UINT8   AzaliaDs;
+  UINT8   AzaliaPme;
+  UINT8   HdmiCodec;
+
+  UINT8   UartInterface;
+  UINT8   PcuUart1;
+  //UINT8   PcuUart2;//for A0
+  UINT8   StateAfterG3;
+  UINT8   EnableClockSpreadSpec;
+  UINT8   GraphicReserve00;
+  UINT8   GOPEnable;
+  UINT8   GOPBrightnessLevel;                     //Gop Brightness level
+  UINT8   PavpMode;
+  UINT8   SEC04;
+  UINT8   SEC05;
+  UINT8   SEC06;
+  UINT8   SEC07;
+
+  UINT8   HdmiCodecPortB;
+  UINT8   HdmiCodecPortC;
+  UINT8   HdmiCodecPortD;
+  UINT8   LidStatus;
+  UINT8   Reserved00;
+  UINT8   Reserved01;
+  UINT16  Reserved02;
+  UINT16  Reserved03;
+  UINT16  Reserved04;
+  UINT16  Reserved05;
+  UINT16  Reserved06;
+  UINT16  Reserved07;
+  UINT16  Reserved08;
+  UINT16  Reserved09;
+  UINT16  Reserved0A;
+  UINT16  Reserved0B;
+  UINT16  Reserved0C;
+  UINT16  Reserved0D;
+  UINT8   Reserved0E;
+  UINT8   Reserved0F;
+  UINT32  Reserved10;
+  UINT32  Reserved11;
+  UINT32  Reserved12;
+  UINT32  Reserved13;
+  UINT32  Reserved14;
+  UINT8   Reserved15;
+  UINT8   Reserved16;
+  UINT8   Reserved17;
+  UINT8   Reserved18;
+  UINT8   Reserved19;
+  UINT8   Reserved1A;
+  UINT8   Reserved1B;
+  UINT8   Reserved1C;
+  UINT8   Reserved1D;
+  UINT8   Reserved1E;
+  UINT8   Reserved1F;
+  UINT8   Reserved20;
+  UINT8   PmicEnable;
+  UINT8   IdleReserve;
+  UINT8   TSEGSizeSel;
+  UINT8   ACPIMemDbg;
+  UINT8    ExISupport;
+  UINT8   BatteryChargingSolution;                 //0-non ULPMC 1-ULPMC
+  UINT8   PnpSettings;
+  UINT8   CfioPnpSettings;
+  UINT8   PchEhciDebug;
+  UINT8   CRIDSettings;
+  UINT8   ULPMCFWLock;
+  UINT8   SpiRwProtect;
+  UINT8   GraphicReserve02;
+  UINT8   PDMConfig;
+  UINT16  LmMemSize;
+  UINT8   PunitBIOSConfig;
+  UINT8   LpssSdioMode;
+  UINT8   ENDBG2;
+  UINT8   WittEnable;
+  UINT8   UtsEnable;
+  UINT8   TristateLpc;
+  UINT8   GraphicReserve05;
+  UINT8   UsbXhciLpmSupport;
+  UINT8   EnableAESNI;
+  UINT8   SecureErase;
+
+  UINT8   MmioSize;
+
+
+  UINT8   SAR1;
+
+  UINT8   DisableCodec262;
+  UINT8   ReservedO;
+  UINT8   PcieDynamicGating;        // Need PMC enable it first from PMC 0x3_12 MCU 318.
+
+  UINT8   MipiDsi;
+
+  //Added flow control item for UART1 and UART2
+  UINT8  LpssHsuart0FlowControlEnabled;
+  UINT8  LpssHsuart1FlowControlEnabled;
+
+  UINT8   SdCardRemovable; // ACPI reporting MMC/SD media as: removable/non-removable
+  UINT8   GpioWakeCapability;
+  UINT8   RtcBattery;
+  UINT8   LpeAudioReportedByDSDT;
+  
+  UINT8   Uart1Int3511Com; // Report UART1 as COM with _HID INT3511
+  CHAR16  SystemUuid[37];
+
+} SYSTEM_CONFIGURATION;
+#pragma pack()
+
+#ifndef PLATFORM_SETUP_VARIABLE_NAME
+#define PLATFORM_SETUP_VARIABLE_NAME             L"Setup"
+#endif
+
+#pragma pack(1)
+typedef struct{
+  // Passwords
+  UINT16        UserPassword[PASSWORD_MAX_SIZE];
+  UINT16        AdminPassword[PASSWORD_MAX_SIZE];
+  UINT16        DummyDataForVfrBug;  // Don't change or use
+
+} SYSTEM_PASSWORDS;
+#pragma pack()
+
+//
+// #defines for Drive Presence
+//
+#define EFI_HDD_PRESENT       0x01
+#define EFI_HDD_NOT_PRESENT   0x00
+#define EFI_CD_PRESENT        0x02
+#define EFI_CD_NOT_PRESENT    0x00
+
+#define EFI_HDD_WARNING_ON    0x01
+#define EFI_CD_WARNING_ON     0x02
+#define EFI_SMART_WARNING_ON  0x04
+#define EFI_HDD_WARNING_OFF   0x00
+#define EFI_CD_WARNING_OFF    0x00
+#define EFI_SMART_WARNING_OFF 0x00
+
+#ifndef VFRCOMPILE
+extern EFI_GUID gEfiSetupVariableGuid;
+#endif
+
+#define SETUP_DATA SYSTEM_CONFIGURATION
+
+#endif // #ifndef _SETUP_VARIABLE
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Hpet.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Hpet.h
new file mode 100644
index 0000000000..e448ee9796
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Hpet.h
@@ -0,0 +1,40 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  Mseg.h
+
+Abstract:
+
+  This file describes the contents of the ACPI HEPT Table.
+
+--*/
+
+#ifndef _HPET_H
+#define _HPET_H
+
+//
+// Statements that include other files
+//
+#include <IndustryStandard/Acpi10.h>
+#include <IndustryStandard/Acpi20.h>
+#include <IndustryStandard/Acpi30.h>
+#include <IndustryStandard/HighPrecisionEventTimerTable.h>
+
+//
+// HPET Definitions
+//
+#define EFI_ACPI_HPET_TABLE_REVISION            0x1
+#define MAIN_COUNTER_MIN_PERIODIC_CLOCK_TICKS	0x80        //approx 1ms
+
+#define HPET_BASE_ADDRESS                       0xFED00000
+#define EFI_ACPI_EVENT_TIMER_BLOCK_ID           0x8086A001
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/BiosIdLib.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/BiosIdLib.h
new file mode 100644
index 0000000000..484b358264
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/BiosIdLib.h
@@ -0,0 +1,104 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  BiosIdLib.h
+
+Abstract:
+
+  BIOS ID library definitions.
+
+  This library provides functions to get BIOS ID, VERSION, DATE and TIME
+
+--*/
+
+#ifndef _BIOS_ID_LIB_H_
+#define _BIOS_ID_LIB_H_
+
+//
+// BIOS ID string format:
+//
+// $(BOARD_ID)$(BOARD_REV).$(OEM_ID).$(VERSION_MAJOR).$(BUILD_TYPE)$(VERSION_MINOR).YYMMDDHHMM
+//
+// Example: "TRFTCRB1.86C.0008.D03.0506081529"
+//
+#pragma pack(1)
+
+typedef struct {
+  CHAR16  BoardId[7];               // "TRFTCRB"
+  CHAR16  BoardRev;                 // "1"
+  CHAR16  Dot1;                     // "."
+  CHAR16  OemId[3];                 // "86C"
+  CHAR16  Dot2;                     // "."
+  CHAR16  VersionMajor[4];          // "0008"
+  CHAR16  Dot3;                     // "."
+  CHAR16  BuildType;                // "D"
+  CHAR16  VersionMinor[2];          // "03"
+  CHAR16  Dot4;                     // "."
+  CHAR16  TimeStamp[10];            // "YYMMDDHHMM"
+  CHAR16  NullTerminator;           // 0x0000
+} BIOS_ID_STRING;
+
+#define MEM_IFWIVER_START           0x7E0000
+#define MEM_IFWIVER_LENGTH          0x1000
+
+typedef struct _MANIFEST_OEM_DATA{
+  UINT32         Signature;
+  unsigned char  FillNull[0x39];
+  UINT32         IFWIVersionLen;
+  unsigned char  IFWIVersion[32];
+}MANIFEST_OEM_DATA;
+
+//
+// A signature precedes the BIOS ID string in the FV to enable search by external tools.
+//
+typedef struct {
+  UINT8           Signature[8];     // "$IBIOSI$"
+  BIOS_ID_STRING  BiosIdString;     // "TRFTCRB1.86C.0008.D03.0506081529"
+} BIOS_ID_IMAGE;
+
+#pragma pack()
+
+/**
+  This function returns BIOS ID by searching HOB or FV.
+
+  @param[in]  BiosIdImage         The BIOS ID got from HOB or FV
+
+  @retval  EFI_SUCCESS            All parameters were valid and BIOS ID has been got.
+  @retval  EFI_NOT_FOUND          BiosId image is not found, and no parameter will be modified.
+  @retval  EFI_INVALID_PARAMETER  The parameter is NULL.
+
+**/
+EFI_STATUS
+GetBiosId (
+  OUT BIOS_ID_IMAGE     *BiosIdImage
+  );
+
+/**
+  This function returns the Version & Release Date and Time by getting and converting
+  BIOS ID.
+
+  @param[in] BiosVersion         The Bios Version out of the conversion.
+  @param[in] BiosReleaseDate     The Bios Release Date out of the conversion.
+  @param[in] BiosReleaseTime     The Bios Release Time out of the conversion.
+
+  @retval EFI_SUCCESS            BIOS Version & Release Date and Time have been got successfully.
+  @retval EFI_NOT_FOUND          BiosId image is not found, and no parameter will be modified.
+  @retval EFI_INVALID_PARAMETER  All the parameters are NULL.
+
+**/
+EFI_STATUS
+GetBiosVersionDateTime (
+  OUT CHAR16    *BiosVersion, OPTIONAL
+  OUT CHAR16    *BiosReleaseDate, OPTIONAL
+  OUT CHAR16    *BiosReleaseTime OPTIONAL
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/CpuIA32.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/CpuIA32.h
new file mode 100644
index 0000000000..78c78319ce
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/CpuIA32.h
@@ -0,0 +1,345 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  CpuIA32.h
+
+Abstract:
+
+--*/
+
+#ifndef _CPU_IA32_H
+#define _CPU_IA32_H
+
+typedef struct {
+  UINT32  RegEax;
+  UINT32  RegEbx;
+  UINT32  RegEcx;
+  UINT32  RegEdx;
+} EFI_CPUID_REGISTER;
+
+typedef struct {
+  UINT32  HeaderVersion;
+  UINT32  UpdateRevision;
+  UINT32  Date;
+  UINT32  ProcessorId;
+  UINT32  Checksum;
+  UINT32  LoaderRevision;
+  UINT32  ProcessorFlags;
+  UINT32  DataSize;
+  UINT32  TotalSize;
+  UINT8   Reserved[12];
+} EFI_CPU_MICROCODE_HEADER;
+
+typedef struct {
+  UINT32  ExtendedSignatureCount;
+  UINT32  ExtendedTableChecksum;
+  UINT8   Reserved[12];
+} EFI_CPU_MICROCODE_EXTENDED_TABLE_HEADER;
+
+typedef struct {
+  UINT32  ProcessorSignature;
+  UINT32  ProcessorFlag;
+  UINT32  ProcessorChecksum;
+} EFI_CPU_MICROCODE_EXTENDED_TABLE;
+
+typedef struct {
+  UINT32  Stepping       : 4;
+  UINT32  Model          : 4;
+  UINT32  Family         : 4;
+  UINT32  Type           : 2;
+  UINT32  Reserved1      : 2;
+  UINT32  ExtendedModel  : 4;
+  UINT32  ExtendedFamily : 8;
+  UINT32  Reserved2      : 4;
+} EFI_CPU_VERSION;
+
+#define EFI_CPUID_SIGNATURE                   0x0
+#define EFI_CPUID_VERSION_INFO                0x1
+#define EFI_CPUID_CACHE_INFO                  0x2
+#define EFI_CPUID_SERIAL_NUMBER               0x3
+#define EFI_CPUID_EXTENDED_FUNCTION           0x80000000
+#define EFI_CPUID_EXTENDED_CPU_SIG            0x80000001
+#define EFI_CPUID_BRAND_STRING1               0x80000002
+#define EFI_CPUID_BRAND_STRING2               0x80000003
+#define EFI_CPUID_BRAND_STRING3               0x80000004
+
+#define EFI_MSR_IA32_PLATFORM_ID              0x17
+#define EFI_MSR_IA32_APIC_BASE                0x1B
+#define EFI_MSR_EBC_HARD_POWERON              0x2A
+#define EFI_MSR_EBC_SOFT_POWERON              0x2B
+#define BINIT_DRIVER_DISABLE                  0x40
+#define INTERNAL_MCERR_DISABLE                0x20
+#define INITIATOR_MCERR_DISABLE               0x10
+#define EFI_MSR_EBC_FREQUENCY_ID              0x2C
+#define EFI_MSR_IA32_BIOS_UPDT_TRIG           0x79
+#define EFI_MSR_IA32_BIOS_SIGN_ID             0x8B
+#define EFI_MSR_PSB_CLOCK_STATUS              0xCD
+#define EFI_APIC_GLOBAL_ENABLE                0x800
+#define EFI_MSR_IA32_MISC_ENABLE              0x1A0
+#define LIMIT_CPUID_MAXVAL_ENABLE_BIT         0x00400000
+#define AUTOMATIC_THERMAL_CONTROL_ENABLE_BIT  0x00000008
+#define COMPATIBLE_FPU_OPCODE_ENABLE_BIT      0x00000004
+#define LOGICAL_PROCESSOR_PRIORITY_ENABLE_BIT 0x00000002
+#define FAST_STRING_ENABLE_BIT                0x00000001
+
+#define EFI_CACHE_VARIABLE_MTRR_BASE          0x200
+#define EFI_CACHE_VARIABLE_MTRR_END           0x20F
+#define EFI_CACHE_IA32_MTRR_DEF_TYPE          0x2FF
+#define EFI_CACHE_MTRR_VALID                  0x800
+#define EFI_CACHE_FIXED_MTRR_VALID            0x400
+#define EFI_CACHE_VALID_ADDRESS               0xFFFFFF000
+#define EFI_MSR_VALID_MASK                    0xFFFFFFFFF
+#define EFI_CACHE_VALID_EXTENDED_ADDRESS      0xFFFFFFFFFF000
+#define EFI_MSR_VALID_EXTENDED_MASK           0xFFFFFFFFFFFFF
+
+#define EFI_IA32_MTRR_FIX64K_00000            0x250
+#define EFI_IA32_MTRR_FIX16K_80000            0x258
+#define EFI_IA32_MTRR_FIX16K_A0000            0x259
+#define EFI_IA32_MTRR_FIX4K_C0000             0x268
+#define EFI_IA32_MTRR_FIX4K_C8000             0x269
+#define EFI_IA32_MTRR_FIX4K_D0000             0x26A
+#define EFI_IA32_MTRR_FIX4K_D8000             0x26B
+#define EFI_IA32_MTRR_FIX4K_E0000             0x26C
+#define EFI_IA32_MTRR_FIX4K_E8000             0x26D
+#define EFI_IA32_MTRR_FIX4K_F0000             0x26E
+#define EFI_IA32_MTRR_FIX4K_F8000             0x26F
+
+#define EFI_IA32_MCG_CAP                      0x179
+#define EFI_IA32_MCG_CTL                      0x17B
+#define EFI_IA32_MC0_CTL                      0x400
+#define EFI_IA32_MC0_STATUS                   0x401
+
+#define EFI_IA32_PERF_STATUS                  0x198
+#define EFI_IA32_PERF_CTL                     0x199
+
+#define EFI_CACHE_UNCACHEABLE                 0
+#define EFI_CACHE_WRITECOMBINING              1
+#define EFI_CACHE_WRITETHROUGH                4
+#define EFI_CACHE_WRITEPROTECTED              5
+#define EFI_CACHE_WRITEBACK                   6
+
+//
+// Combine f(FamilyId), m(Model), s(SteppingId) to a single 32 bit number
+//
+#define EfiMakeCpuVersion(f, m, s)         \
+  (((UINT32) (f) << 16) | ((UINT32) (m) << 8) | ((UINT32) (s)))
+
+/**
+  Halt the Cpu
+
+  @param[in] None
+
+  @retval None
+
+**/
+VOID
+EFIAPI
+EfiHalt (
+  VOID
+  );
+
+/**
+  Write back and invalidate the Cpu cache
+
+  @param[in] None
+
+  @retval None
+
+**/
+VOID
+EFIAPI
+EfiWbinvd (
+  VOID
+  );
+
+/**
+  Invalidate the Cpu cache
+
+   @param[in] None
+
+   @retval None
+
+**/
+VOID
+EFIAPI
+EfiInvd (
+  VOID
+  );
+
+/**
+  Get the Cpu info by execute the CPUID instruction
+
+  @param[in] RegisterInEax The input value to put into register EAX
+  @param[in] Regs          The Output value
+
+  @retval None
+
+**/
+VOID
+EFIAPI
+EfiCpuid (
+  IN  UINT32                 RegisterInEax,
+  OUT EFI_CPUID_REGISTER     *Regs
+  );
+
+/**
+  When RegisterInEax != 4, the functionality is the same as EfiCpuid.
+  When RegisterInEax == 4, the function return the deterministic cache
+  parameters by excuting the CPUID instruction.
+
+  @param[in]  RegisterInEax  The input value to put into register EAX.
+  @param[in]  CacheLevel     The deterministic cache level.
+  @param[in]  Regs           The Output value.
+
+  @retval None
+
+**/
+VOID
+EFIAPI
+EfiCpuidExt (
+  IN  UINT32                 RegisterInEax,
+  IN  UINT32                 CacheLevel,
+  OUT EFI_CPUID_REGISTER     *Regs
+  );
+
+/**
+  Read Cpu MSR
+
+  @param[in] Index  The index value to select the register
+
+  @retval           Return the read data
+
+**/
+UINT64
+EFIAPI
+EfiReadMsr (
+  IN UINT32     Index
+  );
+
+/**
+  Write Cpu MSR
+
+  @param[in] Index  The index value to select the register
+  @param[in] Value  The value to write to the selected register
+
+  @retval None
+
+**/
+VOID
+EFIAPI
+EfiWriteMsr (
+  IN UINT32     Index,
+  IN UINT64     Value
+  );
+
+/**
+  Read Time stamp
+
+  @param[in] None
+
+  @retval Return the read data
+
+**/
+UINT64
+EFIAPI
+EfiReadTsc (
+  VOID
+  );
+
+/**
+  Writing back and invalidate the cache,then diable it
+
+  @param[in] None
+
+  @retval None
+
+**/
+VOID
+EFIAPI
+EfiDisableCache (
+  VOID
+  );
+
+/**
+  Invalidate the cache,then Enable it
+
+  @param[in] None
+
+  @retval None
+
+**/
+VOID
+EFIAPI
+EfiEnableCache (
+  VOID
+  );
+
+/**
+  Get Eflags
+
+  @param[in] None
+
+  @retval Return the Eflags value
+
+**/
+UINT32
+EFIAPI
+EfiGetEflags (
+  VOID
+  );
+
+/**
+  Disable Interrupts
+
+  @param[in] None
+
+  @retval None
+
+**/
+VOID
+EFIAPI
+EfiDisableInterrupts (
+  VOID
+  );
+
+/**
+  Enable Interrupts
+
+  @param[in] None
+
+  @retval None
+
+**/
+VOID
+EFIAPI
+EfiEnableInterrupts (
+  VOID
+  );
+
+/**
+  Extract CPU detail version infomation
+
+  @param[in] FamilyId    FamilyId, including ExtendedFamilyId
+  @param[in] Model       Model, including ExtendedModel
+  @param[in] SteppingId  SteppingId
+  @param[in] Processor   Processor
+
+**/
+VOID
+EFIAPI
+EfiCpuVersion (
+  IN   UINT16  *FamilyId,    OPTIONAL
+  IN   UINT8   *Model,       OPTIONAL
+  IN   UINT8   *SteppingId,  OPTIONAL
+  IN   UINT8   *Processor    OPTIONAL
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/EfiRegTableLib.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/EfiRegTableLib.h
new file mode 100644
index 0000000000..915f8b39d9
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/EfiRegTableLib.h
@@ -0,0 +1,196 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  EfiRegTableLib.h
+
+Abstract:
+
+  Definitions and macros for building register tables for chipset
+  initialization..
+
+  Components linking this lib must include CpuIo, PciRootBridgeIo, and
+  BootScriptSave protocols in their DPX.
+
+
+
+--*/
+
+#ifndef EFI_REG_TABLE_H
+#define EFI_REG_TABLE_H
+
+
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Protocol/CpuIo.h>
+#include <Protocol/BootScriptSave.h>
+#include <Framework/BootScript.h>
+#include <Protocol/PciRootBridgeIo.h>
+
+
+#define OPCODE_BASE(OpCode)       ((UINT8)((OpCode) & 0xFF))
+#define OPCODE_FLAGS(OpCode)      ((UINT8)(((OpCode) >> 8) & 0xFF))
+#define OPCODE_EXTRA_DATA(OpCode) ((UINT16)((OpCode) >> 16))
+
+//
+// RegTable Base OpCodes
+//
+#define OP_TERMINATE_TABLE                0
+#define OP_MEM_WRITE                      1
+#define OP_MEM_READ_MODIFY_WRITE          2
+#define OP_IO_WRITE                       3
+#define OP_IO_READ_MODIFY_WRITE           4
+#define OP_PCI_WRITE                      5
+#define OP_PCI_READ_MODIFY_WRITE          6
+#define OP_STALL                          7
+
+//
+// RegTable OpCode Flags
+//
+#define OPCODE_FLAG_S3SAVE                1
+
+
+#define TERMINATE_TABLE { (UINT32) OP_TERMINATE_TABLE, (UINT32) 0, (UINT32) 0 }
+
+
+//
+// REG_TABLE_ENTRY_PCI_WRITE encodes the width in the upper bits of the OpCode
+// as one of the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH values
+//
+typedef struct {
+  UINT32                                OpCode;
+  UINT32                                PciAddress;
+  UINT32                                Data;
+} EFI_REG_TABLE_PCI_WRITE;
+
+#define PCI_WRITE(Bus, Dev, Fnc, Reg, Width, Data, S3Flag)                    \
+  {                                                                           \
+    (UINT32) (OP_PCI_WRITE | ((S3Flag) << 8) | ((Width) << 16)),              \
+    (UINT32) (EFI_PCI_ADDRESS ((Bus), (Dev), (Fnc), (Reg))),                  \
+    (UINT32) (Data),                                                          \
+    (UINT32) (0)                                                              \
+  }
+
+typedef struct {
+  UINT32                                OpCode;
+  UINT32                                MemAddress;
+  UINT32                                Data;
+} EFI_REG_TABLE_MEM_WRITE;
+
+typedef struct {
+  UINT32                                OpCode;
+  UINT32                                PciAddress;
+  UINT32                                OrMask;
+  UINT32                                AndMask;
+} EFI_REG_TABLE_PCI_READ_MODIFY_WRITE;
+
+#define PCI_READ_MODIFY_WRITE(Bus, Dev, Fnc, Reg, Width, OrMask, AndMask, S3Flag)  \
+  {                                                                           \
+    (UINT32) (OP_PCI_READ_MODIFY_WRITE | ((S3Flag) << 8) | ((Width) << 16)),  \
+    (UINT32) (EFI_PCI_ADDRESS ((Bus), (Dev), (Fnc), (Reg))),                  \
+    (UINT32) (OrMask),                                                        \
+    (UINT32) (AndMask)                                                        \
+  }
+
+typedef struct {
+  UINT32                                OpCode;
+  UINT32                                MemAddress;
+  UINT32                                OrMask;
+  UINT32                                AndMask;
+} EFI_REG_TABLE_MEM_READ_MODIFY_WRITE;
+
+#define MEM_READ_MODIFY_WRITE(Address, Width, OrMask, AndMask, S3Flag)  \
+  {                                                                           \
+    (UINT32) (OP_MEM_READ_MODIFY_WRITE | ((S3Flag) << 8) | ((Width) << 16)),  \
+    (UINT32) (Address),                  \
+    (UINT32) (OrMask),                                                        \
+    (UINT32) (AndMask)                                                        \
+  }
+
+typedef struct {
+  UINT32                                OpCode;
+  UINT32                                Field2;
+  UINT32                                Field3;
+  UINT32                                Field4;
+} EFI_REG_TABLE_GENERIC;
+
+typedef union {
+  EFI_REG_TABLE_GENERIC                 Generic;
+  EFI_REG_TABLE_PCI_WRITE               PciWrite;
+  EFI_REG_TABLE_PCI_READ_MODIFY_WRITE   PciReadModifyWrite;
+  EFI_REG_TABLE_MEM_READ_MODIFY_WRITE   MemReadModifyWrite;
+} EFI_REG_TABLE;
+
+/**
+  Processes register table assuming which may contain PCI, IO, MEM, and STALL
+  entries.
+
+  No parameter checking is done so the caller must be careful about omitting
+  values for PciRootBridgeIo or CpuIo parameters.  If the regtable does
+  not contain any PCI accesses, it is safe to omit the PciRootBridgeIo (supply
+  NULL).  If the regtable does not contain any IO or Mem entries, it is safe to
+  omit the CpuIo (supply NULL).
+
+  The RegTableEntry parameter is not checked, but is required.
+
+  gBS is assumed to have been defined and is used when processing stalls.
+
+  The function processes each entry sequentially until an OP_TERMINATE_TABLE
+  entry is encountered.
+
+  @param[in] RegTableEntry    A pointer to the register table to process
+
+  @param[in] PciRootBridgeIo  A pointer to the instance of PciRootBridgeIo that is used
+                              when processing PCI table entries
+
+  @param[in] CpuIo            A pointer to the instance of CpuIo that is used when processing IO and
+                              MEM table entries
+
+  @retval Nothing.
+
+**/
+VOID
+ProcessRegTablePci (
+  EFI_REG_TABLE                   * RegTableEntry,
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * PciRootBridgeIo,
+  EFI_CPU_IO_PROTOCOL             * CpuIo
+  );
+
+/**
+  Processes register table assuming which may contain IO, MEM, and STALL
+  entries, but must NOT contain any PCI entries.  Any PCI entries cause an
+  ASSERT in a DEBUG build and are skipped in a free build.
+
+  No parameter checking is done.  Both RegTableEntry and CpuIo parameters are
+  required.
+
+  gBS is assumed to have been defined and is used when processing stalls.
+
+  The function processes each entry sequentially until an OP_TERMINATE_TABLE
+  entry is encountered.
+
+  @param[in] RegTableEntry - A pointer to the register table to process
+
+  @param[in] CpuIo - A pointer to the instance of CpuIo that is used when processing IO and
+                  MEM table entries
+
+  @retval Nothing.
+
+**/
+VOID
+ProcessRegTableCpu (
+  EFI_REG_TABLE                   * RegTableEntry,
+  EFI_CPU_IO_PROTOCOL             * CpuIo
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Esrt.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Esrt.h
new file mode 100644
index 0000000000..a92a27cade
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Esrt.h
@@ -0,0 +1,74 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+ Esrt.h
+
+Abstract:
+
+--*/
+
+#ifndef _DFU_ESRT_H_
+#define _DFU_ESRT_H_
+
+typedef struct {
+  EFI_GUID         FwClass;
+  UINT32           FwType;
+  UINT32           FwVersion;
+  UINT32           FwLstCompatVersion;
+  UINT32           CapsuleFlags;
+  UINT32           LastAttemptVersion;
+  UINT32           LastAttemptStatus;
+} FW_RES_ENTRY;
+
+typedef struct {
+  UINT32           NumEntries;
+  FW_RES_ENTRY     FwEntries[256];
+} FW_RES_ENTRY_LIST;
+
+
+typedef struct {
+  UINT32          FwResourceCount;
+  UINT32          FwResourceMax;
+  UINT64          FwResourceVersion;
+} EFI_SYSTEM_RESOURCE_TABLE;
+
+
+typedef
+EFI_STATUS
+(EFIAPI *ESRT_POPULATE_TABLE) (
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *ESRT_UPDATE_TABLE_ENTRY_BY_GUID) (
+	IN EFI_GUID FwEntryGuid,
+	IN FW_RES_ENTRY *FwEntry
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *ESRT_GET_FW_ENTRY_BY_GUID) (
+    IN EFI_GUID FwEntryGuid,
+	OUT FW_RES_ENTRY *FwEntry
+);
+
+
+#pragma pack()
+
+typedef struct _ESRT_OPERATION_PROTOCOL {
+   ESRT_POPULATE_TABLE					EsrtPopulateTable;
+   ESRT_UPDATE_TABLE_ENTRY_BY_GUID		EsrtUpdateTableEntryByGuid;
+   ESRT_GET_FW_ENTRY_BY_GUID			EsrtGetFwEntryByGuid;
+} ESRT_OPERATION_PROTOCOL;
+
+extern EFI_GUID gEfiEsrtOperationProtocolGuid;
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Fd.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Fd.h
new file mode 100644
index 0000000000..a54ac11162
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Fd.h
@@ -0,0 +1,264 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+
+Module Name:
+
+  Fd.h
+
+Abstract:
+
+  EFI Intel82802AB/82802AC Firmware Hub.
+
+
+--*/
+
+
+//
+// Supported SPI devices
+//
+
+//
+// MFG and Device code
+//
+#define SST_25LF040A        0x0044BF
+#define SST_25LF040         0x0040BF
+#define SST_25LF080A        0x0080BF
+#define SST_25VF080B        0x008EBF
+#define SST_25VF016B        0x0041BF
+#define SST_25VF032B        0x004ABF
+
+#define PMC_25LV040         0x007E9D
+
+#define ATMEL_26DF041       0x00441F
+#define Atmel_AT26F004      0x00041F
+#define Atmel_AT26DF081A    0x01451F
+#define Atmel_AT25DF161     0x02461F
+#define Atmel_AT26DF161     0x00461F
+#define Atmel_AT25DF641     0x00481F
+#define Atmel_AT26DF321     0x00471F
+
+#define Macronix_MX25L8005  0x1420C2
+#define Macronix_MX25L1605A 0x1520C2
+#define Macronix_MX25L3205D 0x1620C2
+
+#define STMicro_M25PE80     0x148020
+
+#define Winbond_W25X40      0x1330EF
+#define Winbond_W25X80      0x1430EF
+#define Winbond_W25Q80      0x1440EF
+
+#define Winbond_W25X16      0x1540EF    // W25Q16
+#define Winbond_W25X32      0x1630EF
+
+//
+//  NOTE: Assuming that 8Mbit flash will only contain a 4Mbit binary.
+//  Treating 4Mbit and 8Mbit devices the same.
+//
+
+//
+// BIOS Base Address
+//
+#define BIOS_BASE_ADDRESS_4M  0xFFF80000
+#define BIOS_BASE_ADDRESS_8M  0xFFF00000
+#define BIOS_BASE_ADDRESS_16M 0xFFE00000
+
+//
+// block and sector sizes
+//
+#define SECTOR_SIZE_256BYTE 0x100       // 256byte page size
+#define SECTOR_SIZE_4KB     0x1000      // 4kBytes sector size
+#define BLOCK_SIZE_32KB     0x00008000  // 32Kbytes block size
+#define MAX_FLASH_SIZE      0x00400000  // 32Mbit (Note that this can also be used for the 4Mbit & 8Mbit)
+
+//
+// Flash commands
+//
+#define SPI_SST25LF_COMMAND_WRITE         0x02
+#define SPI_SST25LF_COMMAND_READ          0x03
+#define SPI_SST25LF_COMMAND_ERASE         0x20
+#define SPI_SST25LF_COMMAND_WRITE_DISABLE 0x04
+#define SPI_SST25LF_COMMAND_READ_STATUS   0x05
+#define SPI_SST25LF_COMMAND_WRITE_ENABLE  0x06
+#define SPI_SST25LF_COMMAND_READ_ID       0xAB
+#define SPI_SST25LF_COMMAND_WRITE_S_EN    0x50
+#define SPI_SST25LF_COMMAND_WRITE_S       0x01
+
+#define SPI_PMC25LV_COMMAND_WRITE         0x02
+#define SPI_PMC25LV_COMMAND_READ          0x03
+#define SPI_PMC25LV_COMMAND_ERASE         0xD7
+#define SPI_PMC25LV_COMMAND_WRITE_DISABLE 0x04
+#define SPI_PMC25LV_COMMAND_READ_STATUS   0x05
+#define SPI_PMC25LV_COMMAND_WRITE_ENABLE  0x06
+#define SPI_PMC25LV_COMMAND_READ_ID       0xAB
+#define SPI_PMC25LV_COMMAND_WRITE_S_EN    0x06
+#define SPI_PMC25LV_COMMAND_WRITE_S       0x01
+
+#define SPI_AT26DF_COMMAND_WRITE         0x02
+#define SPI_AT26DF_COMMAND_READ          0x03
+#define SPI_AT26DF_COMMAND_ERASE         0x20
+#define SPI_AT26DF_COMMAND_WRITE_DISABLE 0x00
+#define SPI_AT26DF_COMMAND_READ_STATUS   0x05
+#define SPI_AT26DF_COMMAND_WRITE_ENABLE  0x00
+#define SPI_AT26DF_COMMAND_READ_ID       0x9F
+#define SPI_AT26DF_COMMAND_WRITE_S_EN    0x00
+#define SPI_AT26DF_COMMAND_WRITE_S       0x00
+
+#define SPI_AT26F_COMMAND_WRITE          0x02
+#define SPI_AT26F_COMMAND_READ           0x03
+#define SPI_AT26F_COMMAND_ERASE          0x20
+#define SPI_AT26F_COMMAND_WRITE_DISABLE  0x04
+#define SPI_AT26F_COMMAND_READ_STATUS    0x05
+#define SPI_AT26F_COMMAND_WRITE_ENABLE   0x06
+#define SPI_AT26F_COMMAND_JEDEC_ID       0x9F
+#define SPI_AT26F_COMMAND_WRITE_S_EN     0x00
+#define SPI_AT26F_COMMAND_WRITE_S        0x01
+#define SPI_AT26F_COMMAND_WRITE_UNPROTECT 0x39
+
+#define SPI_SST25VF_COMMAND_WRITE         0x02
+#define SPI_SST25VF_COMMAND_READ          0x03
+#define SPI_SST25VF_COMMAND_ERASE         0x20
+#define SPI_SST25VF_COMMAND_WRITE_DISABLE 0x04
+#define SPI_SST25VF_COMMAND_READ_STATUS   0x05
+#define SPI_SST25VF_COMMAND_WRITE_ENABLE  0x06
+#define SPI_SST25VF_COMMAND_READ_ID       0xAB
+#define SPI_SST25VF_COMMAND_JEDEC_ID      0x9F
+#define SPI_SST25VF_COMMAND_WRITE_S_EN    0x50
+#define SPI_SST25VF_COMMAND_WRITE_S       0x01
+
+#define SPI_STM25PE_COMMAND_WRITE         0x02
+#define SPI_STM25PE_COMMAND_READ          0x03
+#define SPI_STM25PE_COMMAND_ERASE         0xDB
+#define SPI_STM25PE_COMMAND_WRITE_DISABLE 0x04
+#define SPI_STM25PE_COMMAND_READ_STATUS   0x05
+#define SPI_STM25PE_COMMAND_WRITE_ENABLE  0x06
+#define SPI_STM25PE_COMMAND_JEDEC_ID      0x9F
+
+#define SPI_WinbondW25X_COMMAND_WRITE_S      0x01
+#define SPI_WinbondW25X_COMMAND_WRITE        0x02
+#define SPI_WinbondW25X_COMMAND_READ         0x03
+#define SPI_WinbondW25X_COMMAND_READ_STATUS  0x05
+#define SPI_WinbondW25X_COMMAND_ERASE_S      0x20
+#define SPI_WinbondW25X_COMMAND_WRITE_ENABLE 0x06
+#define SPI_WinbondW25X_COMMAND_JEDEC_ID     0x9F
+
+//
+// SPI default opcode slots
+//
+#define SPI_OPCODE_WRITE_INDEX           0
+#define SPI_OPCODE_READ_INDEX            1
+#define SPI_OPCODE_ERASE_INDEX           2
+#define SPI_OPCODE_READ_S_INDEX          3
+#define SPI_OPCODE_READ_ID_INDEX         4
+#define SPI_OPCODE_WRITE_S_INDEX         6
+#define SPI_OPCODE_WRITE_UNPROTECT_INDEX 7
+
+#define SPI_PREFIX_WRITE_S_EN 1
+#define SPI_PREFIX_WRITE_EN   0
+
+//
+// Atmel AT26F00x
+//
+#define B_AT26F_STS_REG_SPRL  0x80
+#define B_AT26F_STS_REG_SWP   0x0C
+
+//
+// Block lock bit definitions:
+//
+#define READ_LOCK   0x04
+#define LOCK_DOWN   0x02
+#define WRITE_LOCK  0x01
+#define FULL_ACCESS 0x00
+
+//
+// Function Prototypes
+//
+EFI_STATUS
+FlashGetNextBlock (
+  IN UINTN*                               Key,
+  OUT EFI_PHYSICAL_ADDRESS*               BlockAddress,
+  OUT UINTN*                              BlockSize
+  );
+
+EFI_STATUS
+FlashGetSize (
+  OUT UINTN* Size
+  );
+
+EFI_STATUS
+FlashGetUniformBlockSize (
+  OUT UINTN* Size
+  );
+
+EFI_STATUS
+FlashEraseWithNoTopSwapping (
+  IN  UINT8 *BaseAddress,
+  IN  UINTN NumBytes
+  );
+
+EFI_STATUS
+FlashErase (
+  IN  UINT8                 *BaseAddress,
+  IN  UINTN                 NumBytes
+  );
+
+EFI_STATUS
+FlashWriteWithNoTopSwapping (
+  IN UINT8*                 DstBufferPtr,
+  IN UINT8*                 SrcBufferPtr,
+  IN UINTN                  NumBytes
+  );
+
+EFI_STATUS
+FlashWrite (
+  IN  UINT8                 *DstBufferPtr,
+  IN  UINT8                 *SrcBufferPtr,
+  IN  UINTN                 NumBytes
+  );
+
+EFI_STATUS
+FlashReadWithNoTopSwapping (
+  IN  UINT8                 *BaseAddress,
+  IN  UINT8                 *DstBufferPtr,
+  IN  UINTN                 NumBytes
+  );
+
+EFI_STATUS
+FlashRead (
+  IN  UINT8                 *BaseAddress,
+  IN  UINT8                 *DstBufferPtr,
+  IN  UINTN                 NumBytes
+  );
+
+EFI_STATUS
+FlashLockWithNoTopSwapping (
+  IN UINT8*                BaseAddress,
+  IN UINTN                 NumBytes,
+  IN UINT8                 LockState
+  );
+
+EFI_STATUS
+FlashLock(
+  IN  UINT8                 *BaseAddress,
+  IN  UINTN                 NumBytes,
+  IN  UINT8                 LockState
+  );
+
+EFI_STATUS
+CheckIfErased(
+  IN  UINT8       *DstBufferPtr,
+  IN  UINTN       NumBytes
+  );
+
+EFI_STATUS
+CheckIfFlashIsReadyForWrite (
+  IN  UINT8       *DstBufferPtr,
+  IN  UINT8       *SrcBufferPtr,
+  IN  UINTN       NumBytes
+  );
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/FlashDeviceLib.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/FlashDeviceLib.h
new file mode 100644
index 0000000000..43c5e88586
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/FlashDeviceLib.h
@@ -0,0 +1,122 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+  Flash device library class header file.
+
+  Flash Device Library common type, MACRO and API definition. The basic idea for
+  this library is to provide API to abstract the different between flash
+  technology (SPI, FWH etc..), flash controller (SPI host controller on
+  ICH, MMIO type access for FWH), flash chip (programming command, method
+  of status checking). This library class can be consumed by drivers or applications
+  such as Firmware Volume Block driver, Flash Update application. These driver
+  can be written in a generic manner so that they are more easy to be
+  ported to other platforms.
+
+  This library can be build on a set of APIs which can touch flash controller, flash
+  chip directly for a platform with simple flash device configuration.
+
+  For a platform with complex flash device configuration, this library can be built
+  on the Flash Device Operate Library. Please see the header file for that library
+  class for detailed usage.
+
+**/
+
+#ifndef __FLASHDEVICE_LIB_H__
+#define __FLASHDEVICE_LIB_H__
+
+/**
+  Read NumBytes bytes of data from the address specified by
+  PAddress into Buffer.
+
+  @param[in]      PAddress    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
+LibFvbFlashDeviceRead (
+  IN      UINTN                           PAddress,
+  IN  OUT UINTN                           *NumBytes,
+      OUT UINT8                           *Buffer
+  );
+
+/**
+  Write NumBytes bytes of data from Buffer to the address specified by
+  PAddresss.
+
+  @param[in]      PAddress 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
+LibFvbFlashDeviceWrite (
+  IN        UINTN                           PAddress,
+  IN OUT    UINTN                           *NumBytes,
+  IN        UINT8                           *Buffer
+  );
+
+/**
+  Erase the block staring at PAddress.
+
+  @param[in]  PAddress The starting physical address of the region to be erased.
+  @param[in]  LbaLength   The length of the region to be erased. This parameter is necessary
+                       as the physical block size on a flash device could be different than
+                       the logical block size of Firmware Volume Block protocol. Erase on
+                       flash chip is always performed block by block. Therefore, the ERASE
+                       operation to a logical block is converted a number of ERASE operation
+                       (or a partial erase) on the hardware.
+
+  @retval EFI_SUCCESS.            Opertion is successful.
+  @retval EFI_DEVICE_ERROR        If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+LibFvbFlashDeviceBlockErase (
+  IN    UINTN                      PAddress,
+  IN    UINTN                      LbaLength
+);
+
+/**
+  Lock or unlock the block staring at PAddress.
+
+  @param[in]  PAddress The starting physical address of region to be (un)locked.
+  @param[in]  LbaLength   The length of the region to be (un)locked. This parameter is necessary
+                       as the physical block size on a flash device could be different than
+                       the logical block size of Firmware Volume Block protocol. (Un)Lock on
+                       flash chip is always performed block by block. Therefore, the (Un)Lock
+                       operation to a logical block is converted a number of (Un)Lock operation
+                       (or a partial erase) on the hardware.
+  @param[in]  Lock     TRUE to lock. FALSE to unlock.
+
+  @retval EFI_SUCCESS. Opertion is successful.
+
+**/
+EFI_STATUS
+EFIAPI
+LibFvbFlashDeviceBlockLock (
+  IN    UINTN                          PAddress,
+  IN    UINTN                          LbaLength,
+  IN    BOOLEAN                        Lock
+);
+
+#endif
+
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2CLib.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2CLib.h
new file mode 100644
index 0000000000..672c2b45f9
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2CLib.h
@@ -0,0 +1,58 @@
+/** @file
+  Interface Definitions for I2C Lib.
+  
+  Copyright (c) 2004  - 2015, Intel Corporation. All rights reserved.<BR>
+                                                                                   
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+                                                                               
+--*/
+
+#include <Uefi.h>
+#include <Library/IoLib.h>
+
+#ifndef I2C_LIB_HEADER_H
+#define I2C_LIB_HEADER_H
+
+
+/**
+  Reads a Byte from I2C Device.
+ 
+  @param  I2cControllerIndex   I2C Bus no to which the I2C device has been connected
+  @param  SlaveAddress         Device Address from which the byte value has to be read
+  @param  Offset               Offset from which the data has to be read
+  @param  ReadBytes            Number of bytes to be read
+  @param  *ReadBuffer          Address to which the value read has to be stored
+                                
+  @return  EFI_SUCCESS       If the byte value has been successfully read
+  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
+**/
+EFI_STATUS 
+ByteReadI2C(
+  IN  UINT8 BusNo, 
+  IN  UINT8 SlaveAddress, 
+  IN  UINT8 Offset,  
+  IN  UINTN ReadBytes,
+  OUT UINT8 *ReadBuffer
+  );
+
+/**
+  Writes a Byte to I2C Device.
+ 
+  @param  I2cControllerIndex  I2C Bus no to which the I2C device has been connected
+  @param  SlaveAddress        Device Address from which the byte value has to be written
+  @param  Offset              Offset from which the data has to be written
+  @param  WriteBytes          Number of bytes to be written
+  @param  *Byte               Address to which the value written is stored
+                                
+  @return  EFI_SUCCESS       If the byte value has been successfully read
+  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
+**/  
+EFI_STATUS ByteWriteI2C(
+  IN  UINT8 BusNo, 
+  IN  UINT8 SlaveAddress,
+  IN  UINT8 Offset,
+  IN  UINTN WriteBytes,
+  IN  UINT8 *WriteBuffer
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cMmioConfigLib.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cMmioConfigLib.h
new file mode 100644
index 0000000000..7eea7e1d29
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cMmioConfigLib.h
@@ -0,0 +1,23 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+**/
+
+#ifndef __MMIO_CONFIG_LIB_H__
+#define __MMIO_CONFIG_LIB_H__
+
+#include <Protocol/MmioDevice.h>
+
+///
+/// Declare the memory mapped I/O devices assocaited with the
+/// board.
+///
+extern CONST EFI_MMIO_DEVICE_PROTOCOL gMmioDeviceList [ ];
+extern CONST UINTN gMmioDeviceCount;
+
+#endif  //  __MMIO_CONFIG_LIB_H__
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cPort_platform.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cPort_platform.h
new file mode 100644
index 0000000000..9975faeac8
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cPort_platform.h
@@ -0,0 +1,26 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+**/
+
+#ifndef _I2C_PORT_H
+#define _I2C_PORT_H
+
+//
+//  Types
+//
+
+//
+// Context passed from platform (board) layer to the I2C port driver.
+//
+typedef struct {
+  EFI_PHYSICAL_ADDRESS BaseAddress;
+  UINT32 InputFrequencyHertz;
+} I2C_PIO_PLATFORM_CONTEXT;
+
+#endif  //  _I2C_PORT_A0_H
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFsaLib.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFsaLib.h
new file mode 100644
index 0000000000..06dab3016b
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFsaLib.h
@@ -0,0 +1,50 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+--*/
+
+#ifndef _FSA_LIB_H
+#define _FSA_LIB_H
+#include <Uefi.h>
+#include <Uefi/UefiSpec.h>
+
+#define FSA_REG_DEVID           0x1
+#define FSA_REG_CTRL            0x2
+#define FSA_REG_INTR            0x3
+#define FSA_REG_INTR_MSK        0x5
+#define FSA_REG_RESISTOR_CODE   0x7
+#define FSA_REG_TIMING_SET      0x8
+#define FSA_REG_STATUS          0x9
+#define FSA_REG_DEV_TYPE        0xA
+#define FSA_REG_DAC_SAR         0xB
+#define FSA_REG_MANUAL_SW       0x13
+#define FSA_REG_MANUAL_CHG_CTRL 0x14
+
+extern
+EFI_STATUS
+EFIAPI
+FsaUsbDeviceMode (
+  VOID
+);
+
+
+extern
+EFI_STATUS
+EFIAPI
+DisableFsaTimerHandler (
+  VOID
+);
+
+extern
+EFI_STATUS
+EFIAPI
+FSAInit (
+ IN UINT32 FFRDVer
+);
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFspLib.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFspLib.h
new file mode 100644
index 0000000000..c3235afa90
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFspLib.h
@@ -0,0 +1,23 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+--*/
+
+#ifndef _PLATFORM_FSP_LIB_H
+#define _PLATFORM_FSP_LIB_H
+#include <Base.h>
+#include <Uefi.h>
+
+extern
+EFI_STATUS
+PlatformHobCreateFromFsp (
+  IN CONST EFI_PEI_SERVICES     **PeiServices,
+  VOID                          *HobList
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/SpiFlash.H b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/SpiFlash.H
new file mode 100644
index 0000000000..335660cd4c
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/SpiFlash.H
@@ -0,0 +1,239 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+**/
+
+#ifndef _SPIFlash_H_
+#define _SPIFlash_H_
+
+#include <Protocol/Spi.h>
+
+//EFI_STATUS SpiFlashLock(BOOLEAN Lock);
+//EFI_STATUS SpiFlashInit(void);
+
+typedef enum {
+  EnumSpiFlashW25Q64,
+  EnumSpiFlashAT25DF321A,
+  EnumSpiFlashAT26DF321,
+  EnumSpiFlashAT25DF641,
+  EnumSpiFlashW25Q16,
+  EnumSpiFlashW25Q32,
+  EnumSpiFlashW25X32,
+  EnumSpiFlashW25X64,
+  EnumSpiFlashW25Q128,
+  EnumSpiFlashMX25L16,
+  EnumSpiFlashMX25L32,
+  EnumSpiFlashMX25L64,
+  EnumSpiFlashMX25L128,
+  EnumSpiFlashMX25U6435F,
+  EnumSpiFlashSST25VF016B,
+  EnumSpiFlashSST25VF064C,
+  EnumSpiFlashN25Q064,
+  EnumSpiFlashM25PX16,
+  EnumSpiFlashN25Q032,
+  EnumSpiFlashM25PX32,
+  EnumSpiFlashM25PX64,
+  EnumSpiFlashN25Q128,
+  EnumSpiFlashEN25Q16,
+  EnumSpiFlashEN25Q32,
+  EnumSpiFlashEN25Q64,
+  EnumSpiFlashEN25Q128,
+  EnumSpiFlashA25L016,
+  EnumSpiFlashMax
+} SPI_FLASH_TYPES_SUPPORTED;
+
+//
+// Serial Flash VendorId and DeviceId
+//
+#define SF_VENDOR_ID_ATMEL          0x1F
+#define SF_DEVICE_ID0_AT26DF321     0x47
+#define SF_DEVICE_ID1_AT26DF321     0x00
+#define SF_DEVICE_ID0_AT25DF321A    0x47
+#define SF_DEVICE_ID1_AT25DF321A    0x01
+#define SF_DEVICE_ID0_AT25DF641     0x48
+#define SF_DEVICE_ID1_AT25DF641     0x00
+
+#define SF_VENDOR_ID_WINBOND        0xEF
+#define SF_DEVICE_ID0_W25XXX        0x30
+#define SF_DEVICE_ID1_W25X32        0x16
+#define SF_DEVICE_ID1_W25X64        0x17
+#define SF_DEVICE_ID0_W25QXX        0x40
+#define SF_DEVICE_ID1_W25Q16        0x15
+#define SF_DEVICE_ID1_W25Q32        0x16
+#define SF_DEVICE_ID1_W25Q64        0x17
+#define SF_DEVICE_ID1_W25Q128       0x18
+
+#define	SF_VENDOR_ID_MACRONIX       0xC2
+#define	SF_DEVICE_ID0_MX25LXX       0x20
+#define	SF_DEVICE_ID1_MX25L16       0x15
+#define	SF_DEVICE_ID1_MX25L32       0x16
+#define	SF_DEVICE_ID1_MX25L64       0x17
+#define	SF_DEVICE_ID1_MX25L128      0x18
+#define SF_DEVICE_ID0_MX25UXX       0x25
+#define SF_DEVICE_ID1_MX25U6435F    0x37
+
+#define	SF_VENDOR_ID_NUMONYX        0x20
+#define SF_DEVICE_ID0_N25Q064       0xBB
+#define SF_DEVICE_ID1_N25Q064       0x17
+#define	SF_DEVICE_ID0_M25PXXX       0x71
+#define	SF_DEVICE_ID0_N25QXXX       0xBA
+#define	SF_DEVICE_ID1_M25PX16       0x15
+#define	SF_DEVICE_ID1_N25Q032       0x16
+#define	SF_DEVICE_ID1_M25PX32       0x16
+#define	SF_DEVICE_ID1_M25PX64       0x17
+#define	SF_DEVICE_ID1_N25Q128       0x18
+
+#define SF_VENDOR_ID_SST            0xBF
+#define SF_DEVICE_ID0_SST25VF0XXX   0x25
+#define SF_DEVICE_ID1_SST25VF016B   0x41
+#define SF_DEVICE_ID1_SST25VF064C   0x4B
+
+#define SF_VENDOR_ID_EON            0x1C
+#define SF_DEVICE_ID0_EN25QXX       0x30
+#define SF_DEVICE_ID1_EN25Q16       0x15
+#define SF_DEVICE_ID1_EN25Q32       0x16
+#define SF_DEVICE_ID1_EN25Q64       0x17
+#define SF_DEVICE_ID1_EN25Q128      0x18
+
+#define SF_VENDOR_ID_AMIC           0x37
+#define SF_DEVICE_ID0_A25L016       0x30
+#define SF_DEVICE_ID1_A25L016       0x15
+
+#define ATMEL_AT26DF321_SIZE        0x00400000
+#define ATMEL_AT25DF321A_SIZE       0x00400000
+#define ATMEL_AT25DF641_SIZE        0x00800000
+#define WINBOND_W25X32_SIZE         0x00400000
+#define WINBOND_W25X64_SIZE         0x00800000
+#define WINBOND_W25Q16_SIZE         0x00200000
+#define WINBOND_W25Q32_SIZE         0x00400000
+#define WINBOND_W25Q64_SIZE         0x00800000
+#define WINBOND_W25Q128_SIZE        0x01000000
+#define SST_SST25VF016B_SIZE        0x00200000
+#define SST_SST25VF064C_SIZE        0x00800000
+#define MACRONIX_MX25L16_SIZE       0x00200000
+#define MACRONIX_MX25L32_SIZE       0x00400000
+#define MACRONIX_MX25L64_SIZE       0x00800000
+#define MACRONIX_MX25U64_SIZE       0x00800000
+#define MACRONIX_MX25L128_SIZE      0x01000000
+#define NUMONYX_M25PX16_SIZE        0x00400000
+#define NUMONYX_N25Q032_SIZE        0x00400000
+#define NUMONYX_M25PX32_SIZE        0x00400000
+#define NUMONYX_M25PX64_SIZE        0x00800000
+#define NUMONYX_N25Q064_SIZE        0x00800000
+#define NUMONYX_N25Q128_SIZE        0x01000000
+#define EON_EN25Q16_SIZE            0x00200000
+#define EON_EN25Q32_SIZE            0x00400000
+#define EON_EN25Q64_SIZE            0x00800000
+#define EON_EN25Q128_SIZE           0x01000000
+#define AMIC_A25L16_SIZE            0x00200000
+
+#define SF_VENDOR_ID_SST           0xBF
+#define SF_DEVICE_ID0_25LF080A     0x25
+#define SF_DEVICE_ID1_25LF080A     0x8E
+#define SF_DEVICE_ID0_25VF016B     0x25
+#define SF_DEVICE_ID1_25VF016B     0x41
+
+#define SF_VENDOR_ID_ATMEL         0x1F
+#define SF_DEVICE_ID0_AT26DF321    0x47
+#define SF_DEVICE_ID1_AT26DF321    0x00
+
+#define SF_VENDOR_ID_STM           0x20
+#define SF_DEVICE_ID0_M25P32       0x20
+#define SF_DEVICE_ID1_M25P32       0x16
+
+#define SF_VENDOR_ID_WINBOND       0xEF
+#define SF_DEVICE_ID0_W25XXX       0x30
+
+#define SF_DEVICE_ID1_W25X80       0x14
+#define SF_DEVICE_ID1_W25X16       0x15
+#define SF_DEVICE_ID1_W25X32       0x16
+#define SF_DEVICE_ID1_W25X64       0x17
+
+#define	SF_VENDOR_ID_MX				0xC2
+#define	SF_DEVICE_ID0_25L1605A		0x20
+#define	SF_DEVICE_ID1_25L1605A		0x15
+
+#define SF_VENDOR_ID_NUMONYX        0x20
+#define SF_DEVICE_ID0_M25PX16       0x71
+#define SF_DEVICE_ID1_M25PX16       0x15
+
+#define SST_25LF080A_SIZE          0x00100000
+#define SST_25LF016B_SIZE          0x00200000
+#define ATMEL_AT26DF321_SIZE       0x00400000
+#define STM_M25P32_SIZE            0x00400000
+#define WINBOND_W25X80_SIZE        0x00100000
+#define WINBOND_W25X16_SIZE        0x00200000
+#define WINBOND_W25X32_SIZE        0x00400000
+#define WINBOND_W25X64_SIZE        0x00800000
+#define MX_25L1605A_SIZE           0x00200000
+
+//
+// Physical Sector Size on the Serial Flash device
+//
+#define SF_SECTOR_SIZE    0x1000
+#define SF_BLOCK_SIZE     0x8000
+
+//
+// Serial Flash Status Register definitions
+//
+#define SF_SR_BUSY        0x01      // Indicates if internal write operation is in progress
+#define SF_SR_WEL         0x02      // Indicates if device is memory write enabled
+#define SF_SR_BP0         0x04      // Block protection bit 0
+#define SF_SR_BP1         0x08      // Block protection bit 1
+#define SF_SR_BP2         0x10      // Block protection bit 2
+#define SF_SR_BP3         0x20      // Block protection bit 3
+#define SF_SR_WPE         0x3C      // Enable write protection on all blocks
+#define SF_SR_AAI         0x40      // Auto Address Increment Programming status
+#define SF_SR_BPL         0x80      // Block protection lock-down
+
+//
+// Operation Instruction definitions for  the Serial Flash Device
+//
+#define SF_INST_WRSR            0x01     // Write Status Register
+#define SF_INST_PROG            0x02     // Byte Program
+#define SF_INST_READ            0x03     // Read
+#define SF_INST_WRDI            0x04     // Write Disable
+#define SF_INST_RDSR            0x05     // Read Status Register
+#define SF_INST_WREN            0x06     // Write Enable
+#define SF_INST_HS_READ         0x0B     // High-speed Read
+#define SF_INST_SERASE          0x20     // Sector Erase (4KB)
+#define SF_INST_BERASE          0x52     // Block Erase (32KB)
+#define SF_INST_64KB_ERASE      0xD8     // Block Erase (64KB)
+#define SF_INST_EWSR            0x50     // Enable Write Status Register
+#define SF_INST_READ_ID         0xAB     // Read ID
+#define SF_INST_JEDEC_READ_ID   0x9F     // JEDEC Read ID
+#define SF_INST_DOFR            0x3B     // Dual Output Fast Read
+#define SF_INST_SFDP            0x5A     // Serial Flash Discovery Parameters
+
+#define SECTOR_SIZE_4KB 	0x1000       // Common 4kBytes sector size
+#define SECTOR_SIZE_64KB	0x10000      // Common 64kBytes sector size
+#define BLOCK_SIZE_64KB 	0x00010000   // Common 64kBytes block size
+#define MAX_FWH_SIZE    	0x00100000   // 8Mbit (Note that this can also be used for the 4Mbit )
+
+//
+// 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
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/StallSmmLib.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/StallSmmLib.h
new file mode 100644
index 0000000000..49baffdcc5
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/StallSmmLib.h
@@ -0,0 +1,40 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+                                                                                   

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

+
+Module Name:
+
+  SmmStallLib.h
+
+Abstract:
+
+  This library provides SMM functions for Stall.
+  These can be used to save size and simplify code.
+  All contents must be runtime and SMM safe.
+
+--*/
+
+#ifndef _SMM_STALL_LIB_H_
+#define _SMM_STALL_LIB_H_
+#include "PiDxe.h"
+#include "Pi/PiSmmCis.h"
+extern EFI_SMM_SYSTEM_TABLE2  *mSmst;
+
+/**
+  Delay for at least the request number of microseconds
+
+  @param[in] Microseconds  Number of microseconds to delay.
+
+  @retval None
+
+**/
+VOID
+SmmStall (
+  IN  UINTN   Microseconds
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/UsbDeviceModeLib.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/UsbDeviceModeLib.h
new file mode 100644
index 0000000000..c52417f00f
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/UsbDeviceModeLib.h
@@ -0,0 +1,181 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+**/
+
+#ifndef __BASE_USBDEVICEMODE_LIB_H__
+#define __BASE_USBDEVICEMODE_LIB_H__
+
+#pragma pack(1)
+typedef struct {
+    UINT8  bLength;
+    UINT8  bDescriptorType;
+    UINT8  bMaxBurst;
+    UINT8  bmAttributes;
+    UINT16 wBytesPerInterval;
+} endpointCompanionDescriptor;
+#pragma pack()
+
+#pragma pack(1)
+typedef struct {
+    UINT8  bLength;
+    UINT8  bDescriptorType;
+    UINT8  bEndpointAddress;
+    UINT8  bmAttributes;
+    UINT16 wMaxPacketSize;
+    UINT8  bInterval;
+} endpointDescriptor;
+#pragma pack()
+
+typedef struct {
+    endpointDescriptor          *pEpDesc;
+    endpointCompanionDescriptor *pEpCompDesc;
+} USB_DEV_EP_INFO;    //usbdEpInfo;
+
+typedef struct {
+    VOID        *pBuf;
+    UINT32    dataLen;
+} USBD_IO_INFO;
+
+typedef struct {
+    USBD_IO_INFO     ioInfo;
+    USB_DEV_EP_INFO  epInfo;
+} USBD_IO_REQ;
+
+UINTN
+EFIAPI
+usbdInitDCI (
+  VOID
+  );
+
+BOOLEAN
+EFIAPI
+fbInit (
+  OUT  VOID  *pParams
+  );
+
+BOOLEAN
+EFIAPI
+fbDeinit (
+  VOID
+  );
+
+BOOLEAN
+EFIAPI
+fbStart (
+  VOID
+  );
+
+BOOLEAN
+EFIAPI
+fbStop (
+  VOID
+  );
+
+BOOLEAN
+EFIAPI
+usbdSetMmioBar (
+  UINT32 mmioBar
+  );
+
+BOOLEAN
+EFIAPI
+udciDeinit (
+  VOID    *pUdciHndl,
+  UINT32  flags
+  );
+
+BOOLEAN
+EFIAPI
+udciIsr (
+  VOID    *pUdciHndl
+  );
+
+BOOLEAN
+EFIAPI
+udciConnect (
+  VOID    *pUdciHndl
+  );
+
+BOOLEAN
+EFIAPI
+udciDisconnect (
+  VOID    *pUdciHndl
+  );
+
+BOOLEAN
+EFIAPI
+udciSetAddress (
+  VOID    *pUdciHndl,
+  UINT8   address
+  );
+
+BOOLEAN
+EFIAPI
+udciInitEp (
+  VOID            *pUdciHndl,
+  USB_DEV_EP_INFO *pEpInfo
+  );
+
+BOOLEAN
+EFIAPI
+udciEnableEp (
+  VOID            *pUdciHndl,
+  USB_DEV_EP_INFO *pEpInfo
+  );
+
+BOOLEAN
+EFIAPI
+udciDisableEp (
+  VOID            *pUdciHndl,
+  USB_DEV_EP_INFO *pEpInfo
+  );
+
+BOOLEAN
+EFIAPI
+udciStallEp (
+  VOID            *pUdciHndl,
+  USB_DEV_EP_INFO *pEpInfo
+  );
+
+BOOLEAN
+EFIAPI
+udciClearStallEp (
+  VOID            *pUdciHndl,
+  USB_DEV_EP_INFO *pEpInfo
+  );
+
+
+BOOLEAN
+EFIAPI
+udciEp0TxStatus (
+  VOID            *pUdciHndl
+  );
+
+
+BOOLEAN
+EFIAPI
+udciEpTxData (
+  VOID        *pUdciHndl,
+  USBD_IO_REQ *pIoReq
+  );
+
+BOOLEAN
+EFIAPI
+udciEpRxData (
+  VOID        *pUdciHndl,
+  USBD_IO_REQ *pIoReq
+  );
+
+BOOLEAN
+EFIAPI
+udciRegisterCallbacks (
+  VOID            *pUdciHndl
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Mcfg.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Mcfg.h
new file mode 100644
index 0000000000..2751a27d2d
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Mcfg.h
@@ -0,0 +1,69 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  Mcfg.h
+
+Abstract:
+
+  ACPI Memory mapped configuration space base address Description Table
+  implementation, based on PCI Firmware Specification Revision 3.0 final draft,
+  downloadable at http://www.pcisig.com/home
+
+**/
+
+#ifndef _MCFG_H_
+#define _MCFG_H_
+
+//
+// Statements that include other files
+//
+#include <IndustryStandard/Acpi20.h>
+#include "McfgTable.h"
+#include "Platform.h"
+
+//
+// "MCFG" Static Resource Affinity Table
+//
+#define EFI_ACPI_3_0_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_SIGNATURE 0x4746434D
+
+//
+// MCFG Definitions, see specification for details.
+//
+#define EFI_ACPI_OEM_MCFG_REVISION  0x00000001
+
+//
+// Define the number of each table type.
+// This is where the table layout is modified.
+//
+#define EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_BASE_ADDRESS_STRUCTURE_COUNT  1
+
+//
+// MCFG Table definition.  The table must be defined in a platform
+// specific manner.
+//
+//
+// Ensure proper structure formats
+//
+#pragma pack(1)
+
+typedef struct {
+  EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER        Header;
+
+#if EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_BASE_ADDRESS_STRUCTURE_COUNT > 0
+  EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_BASE_ADDRESS_STRUCTURE  Segment[
+    EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_BASE_ADDRESS_STRUCTURE_COUNT];
+#endif
+
+} EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE;
+
+#pragma pack()
+
+#endif // _MCFG_H_
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/McfgTable.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/McfgTable.h
new file mode 100644
index 0000000000..dc9dc49e74
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/McfgTable.h
@@ -0,0 +1,65 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  McfgTable.h
+
+Abstract:
+
+  ACPI Memory mapped configuration space base address Description Table
+  definition, based on PCI Firmware Specification Revision 3.0 final draft,
+  downloadable at http://www.pcisig.com/home
+
+**/
+
+#ifndef _MCFG_TABLE_H_
+#define _MCFG_TABLE_H_
+
+//
+// Include files
+//
+#include <PiDxe.h>
+
+//
+// Ensure proper structure formats
+//
+#pragma pack(1)
+
+//
+// MCFG Revision (defined in spec)
+//
+#define EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_REVISION  0x01
+
+//
+// MCFG Structure Definitions
+//
+//
+// Memory Mapped Enhanced Configuration Base Address Allocation
+// Structure Definition
+//
+typedef struct {
+  UINT64  BaseAddress;
+  UINT16  PciSegmentGroupNumber;
+  UINT8   StartBusNumber;
+  UINT8   EndBusNumber;
+  UINT32  Reserved;
+} EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_BASE_ADDRESS_STRUCTURE;
+
+//
+// MCFG Table header definition.  The rest of the table
+// must be defined in a platform specific manner.
+//
+typedef struct {
+  EFI_ACPI_DESCRIPTION_HEADER Header;
+  UINT64                      Reserved;
+} EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER;
+
+#pragma pack()
+
+#endif // _MCFG_TABLE_H
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Platform.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Platform.h
new file mode 100644
index 0000000000..4d1932febd
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Platform.h
@@ -0,0 +1,133 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  Platform.h
+
+Abstract:
+
+  Pinetrail platform specific information.
+
+**/
+
+#ifndef _PLATFORM_H
+#define _PLATFORM_H
+
+#include "ChipsetAccess.h"
+#include "PlatformBaseAddresses.h"
+
+
+//
+// Number of P & T states supported.
+//
+#define NPTM_P_STATES_SUPPORTED         16
+#define NPTM_T_STATES_SUPPORTED         8
+
+//
+// I/O APIC IDs, the code uses math to generate the numbers
+// instead of using these defines.
+//
+#define ICH_IOAPIC                     (1 << 0)
+#define ICH_IOAPIC_ID                   0x08
+
+//
+// Possible SMBus addresses that will be present.
+//
+#define SMBUS_ADDR_CH_A_1     0xA0
+#define SMBUS_ADDR_CH_A_2     0xA2
+#define SMBUS_ADDR_CH_B_1     0xA4
+#define SMBUS_ADDR_CH_B_2     0xA6
+#define SMBUS_ADDR_CH_C_1     0xA8
+#define SMBUS_ADDR_CH_C_2     0xAA
+#define SMBUS_ADDR_CH_D_1     0xAC
+#define SMBUS_ADDR_CH_D_2     0xAE
+#define SMBUS_ADDR_HOST_CLK_BUFFER  0xDC
+#define SMBUS_ADDR_ICH_SLAVE        0x44
+#define SMBUS_ADDR_HECETA     0x5C
+#define SMBUS_ADDR_SMBARP     0xC2
+#define SMBUS_ADDR_82573E     0xC6
+#define SMBUS_ADDR_CLKCHIP    0xD2
+#define SMBUS_ADDR_BRD_REV          0x4E
+#define SMBUS_ADDR_DB803            0x82
+
+//
+// SMBus addresses that used on this platform.
+//
+#define PLATFORM_SMBUS_RSVD_ADDRESSES { \
+  SMBUS_ADDR_CH_A_1, \
+  SMBUS_ADDR_CH_A_2, \
+  SMBUS_ADDR_HOST_CLK_BUFFER, \
+  SMBUS_ADDR_ICH_SLAVE, \
+  SMBUS_ADDR_SMBARP, \
+  SMBUS_ADDR_CLKCHIP, \
+  SMBUS_ADDR_BRD_REV, \
+  SMBUS_ADDR_DB803 \
+  }
+
+//
+// Count of addresses present in PLATFORM_SMBUS_RSVD_ADDRESSES.
+//
+#define PLATFORM_NUM_SMBUS_RSVD_ADDRESSES 8
+
+//
+// CMOS usage
+//
+#define CMOS_CPU_BSP_SELECT         0x10
+#define CMOS_CPU_UP_MODE            0x11
+#define CMOS_CPU_RATIO_OFFSET       0x12
+#define CMOS_CPU_CORE_HT_OFFSET     0x13
+#define CMOS_EFI_DEBUG              0x14
+#define CMOS_CPU_BIST_OFFSET        0x15
+#define CMOS_CPU_VMX_OFFSET         0x16
+#define CMOS_ICH_PORT80_OFFSET      0x17
+#define CMOS_PLATFORM_DESIGNATOR    0x18      // Second bank CMOS location of Platform ID.
+#define CMOS_VALIDATION_TEST_BYTE   0x19      // BIT0 - Validation mailbox for UPonDP.
+#define CMOS_SERIAL_BAUD_RATE       0x1A      // 0=115200; 1=57600; 2=38400; 3=19200; 4=9600
+#define CMOS_DCU_MODE_OFFSET        0x1B
+#define CMOS_VR11_SET_OFFSET        0x1C
+#define CMOS_SBSP_TO_AP_COMM        0x20      // SEC code use ONLY!!!
+#define CMOS_RESET_TYPE_BY_OS       0x52
+#define TCG_CMOS_MOR_AREA_OFFSET    0x65      // Also Change in Universal\Security\Tpm\PhysicalPresence\Dxe\PhysicalPresence.c &
+#define CMOS_S4_WAKEUP_FLAG_ADDRESS 0x6E
+#define ACPI_TPM_REQUEST            0x75
+#define ACPI_TPM_LAST_REQUEST       0x76
+#define CMOS_BOOT_FLAG_ADDRESS      0x7E
+
+//
+// GPIO Index Data Structure.
+//
+typedef struct {
+  UINT8   Register;
+  UINT32  Value;
+} ICH_GPIO_DEV;
+
+//
+// CPU Equates
+//
+#define MAX_THREAD                      2
+#define MAX_CORE                        1
+#define MAX_DIE                         2
+#define MAX_CPU_SOCKET                  1
+#define MAX_CPU_NUM                     (MAX_THREAD * MAX_CORE * MAX_DIE * MAX_CPU_SOCKET)
+
+#define MEM64_LEN                       0x00100000000
+#define RES_MEM64_36_BASE               0x01000000000 - MEM64_LEN   // 2^36
+#define RES_MEM64_36_LIMIT              0x01000000000 - 1           // 2^36
+#define RES_MEM64_39_BASE               0x08000000000 - MEM64_LEN   // 2^39
+#define RES_MEM64_39_LIMIT              0x08000000000 - 1           // 2^39
+#define RES_MEM64_40_BASE               0x10000000000 - MEM64_LEN   // 2^40
+#define RES_MEM64_40_LIMIT              0x10000000000 - 1           // 2^40
+
+#define PLATFORM_MAX_BUS_NUM             0x3f
+#define V_DEFAULT_SUBSYSTEM_DEVICE_ID    0x574d
+#define V_DEFAULT_SUBSYSTEM_DEVICE_ID_KT 0x544b
+#define V_DEFAULT_SUBSYSTEM_VENDOR_ID    0x8086
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformBootMode.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformBootMode.h
new file mode 100644
index 0000000000..812077ce14
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformBootMode.h
@@ -0,0 +1,35 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+    PlatformBootMode.h
+
+Abstract:
+
+    EFI Platform Boot Mode
+
+Revision History
+
+--*/
+
+#ifndef _EFI_PLATFORM_BOOT_MODE_H_
+#define _EFI_PLATFORM_BOOT_MODE_H_
+
+//
+// Global ID for the Platform Boot Mode Protocol.
+//
+#define   MANUFACTURE_SETUP_NAME             L"MfgDefault"
+#define   SAFE_SETUP_NAME                    L"SetupDefault"
+#define   OEM_DEFAULTS_SETUP_NAME            L"OemDefault"
+#define   CUSTOM_DEFAULTS_SETUP_NAME         L"CustomDefault"
+
+#endif
+
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformDefinitions.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformDefinitions.h
new file mode 100644
index 0000000000..a64cda0799
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformDefinitions.h
@@ -0,0 +1,43 @@
+/*++
+
+Copyright (c) 1999  - 2014, Intel Corporation. All rights reserved
+                                                                                   

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

+
+
+Module Name:
+
+  PlatformDefinitions.h
+
+Abstract:
+
+  This header file provides platform specific definitions used by other modules
+  for platform specific initialization.
+
+  THIS FILE SHOULD ONLY CONTAIN #defines BECAUSE IT IS CONSUMED BY NON-C MODULES
+  (ASL and VFR)
+
+  This file should not contain addition or other operations that an ASL compiler or
+  VFR compiler does not understand.
+
+--*/
+
+#ifndef _PLATFORM_DEFINITIONS_H_
+#define _PLATFORM_DEFINITIONS_H_
+
+
+//
+// Platform Base Address definitions
+//
+#define PCIEX_BASE_ADDRESS          EDKII_GLUE_PciExpressBaseAddress // Pci Express Configuration Space Base Address
+
+#define PCIEX_LENGTH                PLATFORM_PCIEXPRESS_LENGTH
+
+#define THERMAL_BASE_ADDRESS        0xFED08000
+
+#ifndef MCH_BASE_ADDRESS
+#define MCH_BASE_ADDRESS            0xFED10000  // MCH  Register Base Address
+#endif
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/MfgMemoryTest.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/MfgMemoryTest.h
new file mode 100644
index 0000000000..353c80b629
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/MfgMemoryTest.h
@@ -0,0 +1,42 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  BaseMemoryTest.h
+
+Abstract:
+
+  Pei memory test PPI as defined in Tiano
+
+  Used to Pei memory test in PEI
+
+--*/
+
+#ifndef _BASE_MEMORY_TEST_H_
+#define _BASE_MEMORY_TEST_H_
+
+typedef struct _PEI_MFG_MEMORY_TEST_PPI PEI_MFG_MEMORY_TEST_PPI;
+
+typedef
+EFI_STATUS
+(EFIAPI *PEI_MFG_MEMORY_TEST) (
+  IN  CONST EFI_PEI_SERVICES                   **PeiServices,
+  IN  PEI_MFG_MEMORY_TEST_PPI            * This,
+  IN  UINT32                             BeginAddress,
+  IN  UINT32                             MemoryLength
+  );
+
+typedef struct _PEI_MFG_MEMORY_TEST_PPI {
+  PEI_MFG_MEMORY_TEST  MfgMemoryTest;
+}PEI_MFG_MEMORY_TEST_PPI;
+
+
+extern EFI_GUID gPeiMfgMemoryTestPpiGuid;
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Sha256Hash.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Sha256Hash.h
new file mode 100644
index 0000000000..1c9b2b9ea1
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Sha256Hash.h
@@ -0,0 +1,131 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  Speaker.h
+
+Abstract:
+
+  EFI Speaker Interface Protocol
+
+
+
+--*/
+
+#ifndef _PEI_SHA256_HASH_H
+#define _PEI_SHA256_HASH_H
+
+//
+// Global ID Speaker Interface
+//
+#define PEI_SHA256_HASH_PPI_GUID \
+  { \
+    0x950e191b, 0x8524, 0x4f51,  0x80, 0xa1, 0x5c, 0x4f, 0x1b, 0x3, 0xf3, 0x5c  \
+  }
+
+typedef struct _PEI_SHA256_HASH_PPI PEI_SHA256_HASH_PPI;
+
+/**
+  @return  The size, in bytes, of the context buffer required for hash operations.
+
+**/
+typedef
+UINTN
+(EFIAPI *HASH_GET_CONTEXT_SIZE)(
+  VOID
+  );
+
+/**
+  Initializes user-supplied memory pointed by HashContext as hash context for
+  subsequent use.
+
+  If HashContext is NULL, then ASSERT().
+
+  @param[in, out]  HashContext  Pointer to  Context being initialized.
+
+  @retval TRUE   HASH context initialization succeeded.
+  @retval FALSE  HASH context initialization failed.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI *HASH_INIT)(
+  IN OUT  VOID  *HashContext
+  );
+
+/**
+  Performs digest on a data buffer of the specified length. This function can
+  be called multiple times to compute the digest of long or discontinuous data streams.
+
+  If HashContext is NULL, then ASSERT().
+
+  @param[in, out]  HashContext  Pointer to the MD5 context.
+  @param[in]       Data         Pointer to the buffer containing the data to be hashed.
+  @param[in]       DataLength   Length of Data buffer in bytes.
+
+  @retval TRUE     HASH data digest succeeded.
+  @retval FALSE    Invalid HASH context. After HashFinal function has been called, the
+                   HASH context cannot be reused.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI *HASH_UPDATE)(
+  IN OUT  VOID        *HashContext,
+  IN      CONST VOID  *Data,
+  IN      UINTN       DataLength
+  );
+
+/**
+  Completes hash computation and retrieves the digest value into the specified
+  memory. After this function has been called, the context cannot be used again.
+
+  If HashContext is NULL, then ASSERT().
+  If HashValue is NULL, then ASSERT().
+
+  @param[in, out]  HashContext  Pointer to the MD5 context
+  @param[out]      HashValue    Pointer to a buffer that receives the HASH digest
+                                value.
+
+  @retval TRUE   HASH digest computation succeeded.
+  @retval FALSE  HASH digest computation failed.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI *HASH_FINAL)(
+  IN OUT  VOID   *HashContext,
+  OUT     UINT8  *HashValue
+  );
+
+//
+// Ppi definition
+//
+typedef struct _PEI_SHA256_HASH_PPI {
+  //
+  // Pointer to Hash GetContentSize function
+  //
+  HASH_GET_CONTEXT_SIZE    GetContextSize;
+  //
+  // Pointer to Hash Init function
+  //
+  HASH_INIT                HashInit;
+  //
+  // Pointer to Hash Update function
+  //
+  HASH_UPDATE              HashUpdate;
+  //
+  // Pointer to Hash Final function
+  //
+  HASH_FINAL               HashFinal;
+
+} PEI_SHA256_HASH_PPI;
+
+extern EFI_GUID gPeiSha256HashPpiGuid;
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Speaker.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Speaker.h
new file mode 100644
index 0000000000..b8c817e4ca
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Speaker.h
@@ -0,0 +1,65 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  Speaker.h
+
+Abstract:
+
+  EFI Speaker Interface Protocol
+
+
+
+--*/
+
+#ifndef _PEI_SPEAKER_IF_H
+#define _PEI_SPEAKER_IF_H
+
+//
+// Global ID Speaker Interface
+//
+#define PEI_SPEAKER_INTERFACE_PPI_GUID \
+  { \
+    0x30ac275e, 0xbb30, 0x4b84, 0xa1, 0xcd, 0x0a, 0xf1, 0x32, 0x2c, 0x89, 0xc0 \
+  }
+
+typedef struct _PEI_SPEAKER_IF_PPI PEI_SPEAKER_IF_PPI;
+
+//
+// Beep Code
+//
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SPEAKER_GENERATE_BEEP) (
+  IN CONST EFI_PEI_SERVICES           **PeiServices,
+  IN UINTN                            NumberOfBeep,
+  IN UINTN                            BeepDuration,
+  IN UINTN                            TimeInterval
+  );
+
+//
+// Set Frequency
+//
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SPEAKER_SET_FREQUENCY) (
+  IN CONST EFI_PEI_SERVICES           **PeiServices,
+  IN UINT16                           Frequency
+  );
+
+//
+// Protocol definition
+//
+typedef struct _PEI_SPEAKER_IF_PPI {
+  EFI_SPEAKER_SET_FREQUENCY SetSpeakerToneFrequency;
+  EFI_SPEAKER_GENERATE_BEEP GenerateBeep;
+} PEI_SPEAKER_IF_PPI;
+
+extern EFI_GUID gPeiSpeakerInterfacePpiGuid;
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/UsbController.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/UsbController.h
new file mode 100644
index 0000000000..5448566116
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/UsbController.h
@@ -0,0 +1,85 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+  Define APIs to retrieve USB Host Controller Info such as controller type and
+  I/O Port Base Address.
+
+
+**/
+
+#ifndef _PEI_USB_CONTROLLER_PPI_H_
+#define _PEI_USB_CONTROLLER_PPI_H_
+
+//
+// Global ID for the PEI_USB_CONTROLLER_PPI.
+//
+#define PEI_USB_CONTROLLER_PPI_GUID \
+  { \
+    0x3bc1f6de, 0x693e, 0x4547,{ 0xa3, 0x0, 0x21, 0x82, 0x3c, 0xa4, 0x20, 0xb2} \
+  }
+
+//
+// Forward declaration for the PEI_USB_CONTROLLER_PPI.
+//
+typedef struct _PEI_USB_CONTROLLER_PPI PEI_USB_CONTROLLER_PPI;
+
+//
+// This bit is used in the ControllerType return parameter of GetUsbController()
+// to identify the USB Host Controller type as UHCI
+//
+#define PEI_UHCI_CONTROLLER 0x01
+
+//
+// This bit is used in the ControllerType return parameter of GetUsbController()
+// to identify the USB Host Controller type as OHCI
+//
+#define PEI_OHCI_CONTROLLER 0x02
+
+//
+// This bit is used in the ControllerType return parameter of GetUsbController()
+// to identify the USB Host Controller type as EHCI
+//
+#define PEI_EHCI_CONTROLLER 0x03
+
+/**
+  Retrieve USB Host Controller Info such as controller type and I/O Base Address.
+
+  @param[in]  PeiServices      The pointer to the PEI Services Table.
+  @param[in]  This             The pointer to this instance of the PEI_USB_CONTROLLER_PPI.
+  @param[in]  ControllerId     The ID of the USB controller.
+  @param[out] ControllerType   On output, returns the type of the USB controller.
+  @param[out] BaseAddress      On output, returns the base address of UHCI's I/O ports
+                               if UHCI is enabled or the base address of EHCI's MMIO
+                               if EHCI is enabled.
+
+  @retval EFI_SUCCESS             USB controller attributes were returned successfully.
+  @retval EFI_INVALID_PARAMETER   ControllerId is greater than the maximum number
+                                  of USB controller supported by this platform.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PEI_GET_USB_CONTROLLER)(
+  IN  EFI_PEI_SERVICES        **PeiServices,
+  IN  PEI_USB_CONTROLLER_PPI  *This,
+  IN  UINT8                   UsbControllerId,
+  OUT UINTN                   *ControllerType,
+  OUT UINTN                   *BaseAddress
+  );
+
+//
+// This PPI contains a single service to retrieve the USB Host Controller type
+// and the base address of the I/O ports used to access the USB Host Controller.
+//
+struct _PEI_USB_CONTROLLER_PPI {
+  PEI_GET_USB_CONTROLLER  GetUsbController;
+};
+
+extern EFI_GUID gPeiUsbControllerPpiGuid;
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/CK505ClockPlatformInfo.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/CK505ClockPlatformInfo.h
new file mode 100644
index 0000000000..daf5d22d71
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/CK505ClockPlatformInfo.h
@@ -0,0 +1,126 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  CK505ClockPlatformInfo.h
+
+Abstract:
+
+  Protocol to communicate product clock routing information.
+
+GUID Info:
+ {3C485EA4-449A-46ce-BB08-2A336EA96B4E}
+ 0x3c485ea4, 0x449a, 0x46ce, 0xbb, 0x8, 0x2a, 0x33, 0x6e, 0xa9, 0x6b, 0x4e);
+
+**/
+
+#ifndef _CLOCK_PLATFORM_INFO_H_
+#define _CLOCK_PLATFORM_INFO_H_
+
+
+#define EFI_CK505_CLOCK_PLATFORM_INFO_GUID  \
+  {0x3c485ea4, 0x449a, 0x46ce, 0xbb, 0x8, 0x2a, 0x33, 0x6e, 0xa9, 0x6b, 0x4e}
+
+//
+// Structure to hold register modifications
+//
+typedef enum {
+  None           = 0x00000000,
+  nICS9LP505_1   = 0x00000001,
+  nICS9LP505_2   = 0x00000002,
+  nIDTCV163      = 0x00000004,
+  nIDTCV174      = 0x00000008,
+  nSLG505YC56    = 0x00000010,
+  nSLG505YC64    = 0x00000020,
+  nCY28505       = 0x00000040,
+  nCY28505_2     = 0x00000080,
+  nCY28505LF     = 0x00000100,
+  nPI6C505_OLD   = 0x00000200,
+  nPI6C505_RevD  = 0x00000400,
+  nGENERIC_505   = 0x00000800,
+  nSLG505YC264   = 0x00001000,
+  nIDTCV183      = 0x00002000,
+  nSLG505YC256   = 0x00004000,
+  nIDTCV184      = 0x00008000,
+  nIDTCV190      = 0x00010000,
+  All            = 0xFFFFFFFF
+} EFI_CLOCKS_SUPPORTED;
+
+typedef enum {
+  Disabled,
+  Enabled,
+  EnabledWithoutSwitch,
+  EnabledWithSwitch
+} EFI_SIGNAL_STATE;
+
+typedef enum {
+  SrcClk11,
+  SrcClk10,
+  SrcClk9,
+  SrcClk8,
+  SrcClk7,
+  SrcClk6,
+  SrcClk5,
+  SrcClk4,
+  SrcClk3,
+  SrcClk2,
+  SrcClk1,
+  SrcClk0,
+  CpuClk1,
+  CpuClk0,
+  Ref0,
+  Dot96,
+  Usb48,
+  PciClkF5,
+  PciClk4,
+  PciClk3,
+  PciClk2,
+  PciClk1,
+  PciClk0,
+  SaveClockConfiguration,
+  MePresent,
+  Cr_A,
+  Cr_B,
+  Cr_C,
+  Cr_D,
+  Cr_E,
+  Cr_F,
+  Cr_G,
+  Cr_H,
+  Clk_None // Dummy entry for dynamic detection
+} EFI_CLOCK_SIGNAL_NAME;
+
+typedef struct {
+  EFI_CLOCK_SIGNAL_NAME     Signal;
+  EFI_SIGNAL_STATE          State;
+  EFI_CLOCKS_SUPPORTED      Supported;
+} EFI_STATIC_SIGNALS;
+
+typedef struct {
+  BOOLEAN               BehindBridge;
+  UINT16                BridgeBus;
+  UINT16                BridgeDev;
+  UINT16                BridgeFunction;
+  UINT16                TargetDevice;
+  EFI_CLOCK_SIGNAL_NAME Signal;
+} EFI_DYNAMIC_SIGNALS;
+
+
+typedef struct {
+  EFI_STATIC_SIGNALS      *StaticClockTable;
+  UINTN                   StaticClockTableCount;
+  EFI_STATIC_SIGNALS      *SxClockTable;
+  UINTN                   SxClockTableCount;
+  EFI_STATIC_SIGNALS	  *DynamicDisabledClocksTable;
+  UINTN			  DynamicDisabledClocksTableCount;
+} EFI_CLOCK_PLATFORM_INFO;
+
+extern EFI_GUID gEfiCk505ClockPlatformInfoGuid;
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/EnhancedSpeedstep.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/EnhancedSpeedstep.h
new file mode 100644
index 0000000000..9b74180845
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/EnhancedSpeedstep.h
@@ -0,0 +1,76 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+
+Module Name:
+
+  EnhancedSpeedstep.h
+
+Abstract:
+
+  Enhanced Speedstep protocol
+
+  The Enhanced Speedstep Protocol support.
+
+**/
+
+#ifndef _ENHANCED_SPEEDSTEP_H_
+#define _ENHANCED_SPEEDSTEP_H_
+
+#define ENHANCED_SPEEDSTEP_PROTOCOL_GUID \
+  { \
+    0x91a1ddcf, 0x5374, 0x4939, 0x89, 0x51, 0xd7, 0x29, 0x3f, 0x1a, 0x78, 0x6f \
+  }
+
+typedef struct _ENHANCED_SPEEDSTEP_PROTOCOL ENHANCED_SPEEDSTEP_PROTOCOL;
+
+typedef struct {
+  UINT8   Version;      // EIST State format
+  UINT8   Size;         // Size of element
+  UINT32  RatioStep;    // Step
+  UINT32  MinRatio;     // Calculated min ratio
+  UINT32  MaxRatio;     // Calculated max ratio
+  UINT32  MinCoreFreq;  // Calculated min freq
+  UINT32  MaxCoreFreq;  // Calculated max freq
+  UINT32  MinPower;     // Calculated min power
+  UINT32  MaxPower;     // Calculated max power
+  UINT32  NumStates;    // Number of states
+} EIST_INFORMATION;
+
+typedef struct {
+  UINT32  CoreFrequency;
+  UINT32  Power;
+  UINT32  TransitionLatency;
+  UINT32  BusMasterLatency;
+  UINT32  Control;
+  UINT32  Status;
+} EFI_ACPI_CPU_PSS_STATE;
+
+typedef
+EFI_STATUS
+(EFIAPI *GET_EIST_TABLE) (
+  IN    ENHANCED_SPEEDSTEP_PROTOCOL    *This,
+  OUT   EIST_INFORMATION               **EistInformation,
+  OUT   VOID                           **PssStates
+  );
+
+struct _ENHANCED_SPEEDSTEP_PROTOCOL {
+  UINT32              ProcApicId;
+  GET_EIST_TABLE      GetEistTable;
+};
+
+//
+// There will be an instance of this protocol for every processor
+// in the system.  ProcNumber is used to manage all the different
+// processors in the system and passed into the MP protocol
+// to run code streams on application processors
+//
+extern EFI_GUID gEnhancedSpeedstepProtocolGuid;
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/GlobalNvsArea.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/GlobalNvsArea.h
new file mode 100644
index 0000000000..e2683b2e5b
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/GlobalNvsArea.h
@@ -0,0 +1,475 @@
+/** @file
+
+  Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
+
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+
+
+Module Name:
+
+  GlobalNvsArea.h
+
+Abstract:
+
+  Definition of the global NVS area protocol.  This protocol
+  publishes the address and format of a global ACPI NVS buffer used as a communications
+  buffer between SMM code and ASL code.
+  The format is derived from the ACPI reference code, version 0.95.
+
+  Note:  Data structures defined in this protocol are not naturally aligned.
+
+**/
+
+
+#ifndef _GLOBAL_NVS_AREA_H_
+#define _GLOBAL_NVS_AREA_H_
+
+//
+// Includes
+//
+#define GLOBAL_NVS_DEVICE_ENABLE 1
+#define GLOBAL_NVS_DEVICE_DISABLE 0
+
+//
+// Forward reference for pure ANSI compatibility
+//
+
+//EFI_FORWARD_DECLARATION (EFI_GLOBAL_NVS_AREA_PROTOCOL);
+
+//
+// Global NVS Area Protocol GUID
+//
+#define EFI_GLOBAL_NVS_AREA_PROTOCOL_GUID \
+{ 0x74e1e48, 0x8132, 0x47a1, 0x8c, 0x2c, 0x3f, 0x14, 0xad, 0x9a, 0x66, 0xdc }
+
+//
+// Revision id - Added TPM related fields
+//
+#define GLOBAL_NVS_AREA_RIVISION_1       1
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gEfiGlobalNvsAreaProtocolGuid;
+
+//
+// Global NVS Area definition
+//
+#pragma pack (1)
+typedef struct {
+  //
+  // Miscellaneous Dynamic Values, the definitions below need to be matched
+  // GNVS definitions in Platform.ASL
+  //
+  UINT16      OperatingSystem;    // 00
+  UINT8       SmiFunction;        // 02   SMI function call via IO Trap
+  UINT8       SmiParameter0;      // 03
+  UINT8       SmiParameter1;      // 04
+  UINT8       SciFunction;        // 05   SCI function call via _L00
+  UINT8       SciParameter0;      // 06
+  UINT8       SciParameter1;      // 07
+  UINT8       GlobalLock;         // 08   Global lock function call
+  UINT8       LockParameter0;     // 09
+  UINT8       LockParameter1;     // 10
+  UINT32      Port80DebugValue;   // 11
+  UINT8       LidState;           // 15   Open = 1
+  UINT8       PowerState;         // 16   AC = 1
+  UINT8       DebugState;         // 17
+
+
+  //
+  // Thermal Policy Values
+  //
+  UINT8       EnableThermalOffset;                        // 18 ThermalOffset for KSC
+  UINT8       Reserved1;                           // 19
+  UINT8       Reserved2;                           // 20
+  UINT8       PassiveThermalTripPoint;                    // 21
+  UINT8       PassiveTc1Value;                            // 22
+  UINT8       PassiveTc2Value;                            // 23
+  UINT8       PassiveTspValue;                            // 24
+  UINT8       CriticalThermalTripPoint;                   // 25
+  UINT8       EnableDigitalThermalSensor;                 // 26
+  UINT8       BspDigitalThermalSensorTemperature;         // 27   Temperature of BSP
+  UINT8       ApDigitalThermalSensorTemperature;          // 28   Temperature of AP
+  UINT8       DigitalThermalSensorSmiFunction;            // 29   SMI function call via DTS IO Trap
+
+  //
+  // Battery Support Values
+  //
+  UINT8       NumberOfBatteries;      // 30
+  UINT8       BatteryCapacity0;       // 31   Battery 0 Stored Capacity
+  UINT8       BatteryCapacity1;       // 32   Battery 1 Stored Capacity
+  UINT8       BatteryCapacity2;       // 33   Battery 2 Stored Capacity
+  UINT8       BatteryStatus0;         // 34   Battery 0 Stored Status
+  UINT8       BatteryStatus1;         // 35   Battery 1 Stored Status
+  UINT8       BatteryStatus2;         // 36   Battery 2 Stored Status
+
+  // NOTE: Do NOT Change the Offset of Revision Field
+  UINT8       Revision;               // 37   Revision of the structure EFI_GLOBAL_NVS_AREA
+  UINT8       Reserved3[2];           // 38:39
+
+  //
+  // Processor Configuration Values
+  //
+  UINT8       ApicEnable;             // 40   APIC Enabled by SBIOS (APIC Enabled = 1)
+  UINT8       LogicalProcessorCount;  // 41   Processor Count Enabled (MP Enabled != 0)
+  UINT8       CurentPdcState0;        // 42   PDC settings, Processor 0
+  UINT8       CurentPdcState1;        // 43   PDC settings, Processor 1
+  UINT8       MaximumPpcState;        // 44   Maximum PPC state
+  UINT32      PpmFlags;               // 45:48 PPM configuration flags, same as CFGD
+  UINT8       Reserved4[1];           // 49
+
+  //
+  // SIO Configuration Values
+  //
+  UINT8       DockedSioPresent;       // 50   Dock SIO Present
+  UINT8       DockComA;               // 51     COM A Port
+  UINT8       DockComB;               // 52     COM B Port
+  UINT8       LptP;                   // 53     LPT Port
+  UINT8       DockFdc;                // 54     FDC Port
+  UINT8       OnboardCom;             // 55   Onboard COM Port
+  UINT8       OnboardComCir;          // 56   Onboard COM CIR Port
+
+  UINT8       WPCN381U;               // 57
+  UINT8       NPCE791x;               // 58
+  UINT8       Reserved5[1];           // 59
+
+  //
+  // Internal Graphics Device Values
+  //
+  UINT8       IgdState;               // 60   IGD State (Primary Display = 1)
+  UINT8       DisplayToggleList;      // 61   Display Toggle List Selection
+  UINT8       CurrentDeviceList;      // 62   Current Attached Device List
+  UINT8       PreviousDeviceList;     // 63   Previous Attached Device List
+  UINT16      CurrentDisplayState;    // 64   Current Display State
+  UINT16      NextDisplayState;       // 66   Next Display State
+  UINT16      SetDisplayState;        // 68   Set Display State
+  UINT8       NumberOfValidDeviceId;  // 70   Number of Valid Device IDs
+  UINT32      DeviceId1;              // 71   Device ID 1
+  UINT32      DeviceId2;              // 75   Device ID 2
+  UINT32      DeviceId3;              // 79   Device ID 3
+  UINT32      DeviceId4;              // 83   Device ID 4
+  UINT32      DeviceId5;              // 87   Device ID 5
+
+  UINT32      AKsv0;                  // 91:94 First four bytes of AKSV (manufacturing mode)
+  UINT8       AKsv1;                  // 95    Fifth byte of AKSV (manufacturing mode
+
+  UINT8       Reserved6[7];           // 96:102
+
+  //
+  // Backlight Control Values
+  //
+  UINT8       BacklightControlSupport;  // 103  Backlight Control Support
+  UINT8       BrightnessPercentage;     // 104  Brightness Level Percentage
+
+  //
+  // Ambient Light Sensor Values
+  //
+  UINT8       AlsEnable;              // 105  Ambient Light Sensor Enable
+  UINT8       AlsAdjustmentFactor;    // 106  Ambient Light Adjusment Factor
+  UINT8       LuxLowValue;            // 107  LUX Low Value
+  UINT8       LuxHighValue;           // 108  LUX High Value
+
+  UINT8       Reserved7[1];           // 109
+
+  //
+  // Extended Mobile Access Values
+  //
+  UINT8       EmaEnable;              // 110  EMA Enable
+  UINT16      EmaPointer;             // 111  EMA Pointer
+  UINT16      EmaLength;              // 113  EMA Length
+
+  UINT8       Reserved8[1];           // 115
+
+  //
+  // Mobile East Fork Values
+  //
+  UINT8       MefEnable;              // 116 Mobile East Fork Enable
+
+  //
+  // PCIe Dock Status
+  //
+  UINT8       PcieDockStatus;         // 117 PCIe Dock Status
+
+  UINT8       Reserved9[2];           // 118:119
+
+  //
+  // TPM Registers
+  //
+  UINT8       TpmPresent;             // 120 TPM Present
+  UINT8       TpmEnable;              // 121 TPM Enable
+
+  UINT8       MorData;                // 122 Memory Overwrite Request Data
+  UINT8       TcgParamter;            // 123 Used for save the Mor and/or physical presence parameter
+  UINT32      PPResponse;             // 124 Physical Presence request operation response
+  UINT8       PPRequest;              // 128 Physical Presence request operation
+  UINT8       LastPPRequest;          // 129 Last Physical Presence request operation
+
+  //
+  // SATA Values
+  //
+  UINT8       GtfTaskFileBufferPort0[7];    // 130  GTF Task File Buffer for Port 0
+  UINT8       GtfTaskFileBufferPort2[7];    // 137  GTF Task File Buffer for Port 2
+  UINT8       IdeMode;                      // 144  IDE Mode (Compatible\Enhanced)
+  UINT8       GtfTaskFileBufferPort1[7];    // 145:151 GTF Task File Buffer for Port 1
+
+  UINT8       Reserved111[10];                // 152:161
+  UINT64      BootTimeLogAddress;           // 162:169 Boot Time Log Table Address
+
+  UINT32      IgdOpRegionAddress;           // 170  IGD OpRegion Starting Address
+  UINT8       IgdBootType;                  // 174  IGD Boot Type CMOS option
+  UINT8       IgdPanelType;                 // 175  IGD Panel Type CMOs option
+  UINT8       IgdTvFormat;                  // 176  IGD TV Format CMOS option
+  UINT8       IgdTvMinor;                   // 177  IGD TV Minor Format CMOS option
+  UINT8       IgdPanelScaling;              // 178  IGD Panel Scaling
+  UINT8       IgdBlcConfig;                 // 179  IGD BLC Configuration
+  UINT8       IgdBiaConfig;                 // 180  IGD BIA Configuration
+  UINT8       IgdSscConfig;                 // 181  IGD SSC Configuration
+  UINT8       Igd409;                       // 182  IGD 0409 Modified Settings Flag
+  UINT8       Igd509;                       // 183  IGD 0509 Modified Settings Flag
+  UINT8       Igd609;                       // 184  IGD 0609 Modified Settings Flag
+  UINT8       Igd709;                       // 185  IGD 0709 Modified Settings Flag
+  UINT8       IgdPowerConservation;         // 186  IGD Power Conservation Feature Flag
+  UINT8       IgdDvmtMemSize;               // 187  IGD DVMT Memory Size
+  UINT8       IgdFunc1Enable;               // 188  IGD Function 1 Enable
+  UINT8       IgdHpllVco;                   // 189  HPLL VCO
+  UINT32      NextStateDid1;                // 190  Next state DID1 for _DGS
+  UINT32      NextStateDid2;                // 194  Next state DID2 for _DGS
+  UINT32      NextStateDid3;                // 198  Next state DID3 for _DGS
+  UINT32      NextStateDid4;                // 202  Next state DID4 for _DGS
+  UINT32      NextStateDid5;                // 206  Next state DID5 for _DGS
+  UINT32      NextStateDid6;                // 210  Next state DID6 for _DGS
+  UINT32      NextStateDid7;                // 214  Next state DID7 for _DGS
+  UINT32      NextStateDid8;                // 218  Next state DID8 for _DGS
+  UINT8       IgdSciSmiMode;                // 222  GMCH SMI/SCI mode (0=SCI)
+  UINT8       IgdPAVP;                      // 223  IGD PAVP data
+  UINT8       IgdSelfRefresh;               // 224  IGD Self Refresh
+  UINT8       PcieOSCControl;               // 225  PCIE OSC Control
+  UINT8       NativePCIESupport;            // 226  Native PCI Express Support
+
+  //
+  // USB Sideband Deferring Support
+  //
+  UINT8       HostAlertVector;              // 227  GPE vector used for HOST_ALERT
+  UINT8       HostAlertPio;                 // 228  PIO of USB device used for HOST_ALERT
+
+  UINT8       Reserved112[27];               // 229
+  UINT32      NvIgOpRegionAddress;          // 256 NVIG support
+  UINT32      NvHmOpRegionAddress;          // 260 NVHM support
+  UINT32      ApXmOpRegionAddress;          // 264 AMDA support
+  UINT32      DeviceId6;                    // 268   Device ID 6
+  UINT32      DeviceId7;                    // 272   Device ID 7
+  UINT32      DeviceId8;                    // 276   Device ID 8
+  UINT32      EndpointBaseAddress;          // 280 PEG Endpoint PCIe Base Address
+  UINT32      CapStrPresence;               // 284 PEG Endpoint Capability Structure Presence
+  UINT32      EndpointPcieCapBaseAddress;   // 288 PEG Endpoint PCIe Capability Structure Base Address
+  UINT32      EndpointVcCapBaseAddress;     // 292 PEG Endpoint Virtual Channel Capability Structure Base Address
+  UINT32      XPcieCfgBaseAddress;          // 296 Any Device's PCIe Config Space Base Address
+  UINT32      OccupiedBuses1;               // 300 Occupied Buses from 0 to 31
+  UINT32      OccupiedBuses2;               // 304 Occupied Buses from 32 to 63
+  UINT32      OccupiedBuses3;               // 308 Occupied Buses from 64 to 95
+  UINT32      OccupiedBuses4;               // 312 Occupied Buses from 96 to 127
+  UINT32      OccupiedBuses5;               // 316 Occupied Buses from 128 to 159
+  UINT32      OccupiedBuses6;               // 320 Occupied Buses from 160 to 191
+  UINT32      OccupiedBuses7;               // 324 Occupied Buses from 192 to 223
+  UINT32      OccupiedBuses8;               // 328 Occupied Buses from 224 to 255
+  UINT8       UartSelection;                // 332 UART Interface Selection 0: Internal; 1: SIO
+  UINT8       PcuUart1Enable;               // 333 PCU UART 1 Enabled
+  UINT8       PcuUart2Enable;               // 334 PCU UART 2 Enabled
+
+  UINT32      LPEBar0;                      // 335~338  LPE Bar0
+  UINT32      LPEBar1;                      // 339~342  LPE Bar1
+
+  UINT32      LPEBar2;                      // 343~346  LPE Bar2
+  UINT8        AcSetup;                      // 347 For Ac Powered Config option - IST applet
+  UINT8       BatterySetup;                 // 348 For Battery Powered Config option - IST applet
+  UINT8       PlatformFlavor;               // 349 0:unknown 1: Mobile; 2: desktop
+  UINT8       Reserved113[1];                // 350
+
+  UINT8       IsctReserve;                      // 351 ISCT / AOAC Configuration
+  UINT8       XhciMode;                     // 352 xHCI mode
+  UINT8       PmicEnable;                   // 353 PMIC enable
+
+  UINT8       LpeEnable;                    // 354 LPE enable
+  UINT32      ISPAddr;                      // 355 ISP Base address
+  UINT8       ISPDevSel;                    // 359 ISP device enabled selection 0: Disabled; 1: PCI Device 2; 2: PCI Device 3
+
+  //
+  // Lpss controllers
+  //
+  UINT32      PCIBottomAddress;            //360  ((4+8+6)*4+2)*4=296
+  UINT32      PCITopAddress;               //364
+
+  UINT32      LDMA1Addr;                   // 368
+  UINT32      LDMA1Len;                    // 372
+  UINT32      LDMA11Addr;                  // 376
+  UINT32      LDMA11Len;                   // 380
+  UINT32      PWM1Addr;                    // 384 PWM1
+  UINT32      PWM1Len;                     // 388
+  UINT32      PWM11Addr;                   // 392
+  UINT32      PWM11Len;                    // 396
+  UINT32      PWM2Addr;                    // 400 PWM2
+  UINT32      PWM2Len;                     // 404
+  UINT32      PWM21Addr;                   // 408
+  UINT32      PWM21Len;                    // 412
+  UINT32      UART1Addr;                   // 416 UART1
+  UINT32      UART1Len;                    // 420
+  UINT32      UART11Addr;                  // 424 UART1
+  UINT32      UART11Len;                   // 428
+  UINT32      UART2Addr;                   // 432 UART2
+  UINT32      UART2Len;                    // 436
+  UINT32      UART21Addr;                  // 440 UART2
+  UINT32      UART21Len;                   // 444
+  UINT32      SPIAddr;                     // 448 SPI
+  UINT32      SPILen;                      // 452
+  UINT32      SPI1Addr;                    // 456
+  UINT32      SPI1Len;                     // 460
+
+  UINT32      LDMA2Addr;                   // 464
+  UINT32      LDMA2Len;                    // 468
+  UINT32      LDMA21Addr;                  // 472
+  UINT32      LDMA21Len;                   // 476
+  UINT32      I2C1Addr;                    // 480 I2C1
+  UINT32      I2C1Len;                     // 484
+  UINT32      I2C11Addr;                   // 488 I2C1
+  UINT32      I2C11Len;                    // 492
+  UINT32      I2C2Addr;                    // 496 I2C2
+  UINT32      I2C2Len;                     // 500
+  UINT32      I2C21Addr;                   // 504 I2C2
+  UINT32      I2C21Len;                    // 508
+  UINT32      I2C3Addr;                    // 512 I2C3
+  UINT32      I2C3Len;                     // 516
+  UINT32      I2C31Addr;                   // 520 I2C3
+  UINT32      I2C31Len;                    // 524
+  UINT32      I2C4Addr;                    // 528 I2C4
+  UINT32      I2C4Len;                     // 532
+  UINT32      I2C41Addr;                   // 536 I2C4
+  UINT32      I2C41Len;                    // 540
+  UINT32      I2C5Addr;                    // 544 I2C5
+  UINT32      I2C5Len;                     // 548
+  UINT32      I2C51Addr;                   // 552 I2C5
+  UINT32      I2C51Len;                    // 556
+  UINT32      I2C6Addr;                    // 560 I2C6
+  UINT32      I2C6Len;                     // 564
+  UINT32      I2C61Addr;                   // 566 I2C6
+  UINT32      I2C61Len;                    // 570
+  UINT32      I2C7Addr;                    // 574 I2C7
+  UINT32      I2C7Len;                     // 578
+  UINT32      I2C71Addr;                   // 582 I2C7
+  UINT32      I2C71Len;                    // 586
+
+  //
+  // Scc controllers
+  //
+  UINT32      eMMCAddr;                    // 590 EMMC
+  UINT32      eMMCLen;                     // 594
+  UINT32      eMMC1Addr;                   // 598
+  UINT32      eMMC1Len;                    // 602
+  UINT32      SDIOAddr;                    // 606 SDIO
+  UINT32      SDIOLen;                     // 610
+  UINT32      SDIO1Addr;                   // 614
+  UINT32      SDIO1Len;                    // 618
+  UINT32      SDCardAddr;                  // 622 SDCard
+  UINT32      SDCardLen;                   // 626
+  UINT32      SDCard1Addr;                 // 630
+  UINT32      SDCard1Len;                  // 636
+  UINT32      MipiHsiAddr;                 // 640 MIPI-HSI
+  UINT32      MipiHsiLen;                  // 644
+  UINT32      MipiHsi1Addr;                // 648
+  UINT32      MipiHsi1Len;                 // 652
+
+  UINT8       SdCardRemovable;                   // 656 reserve offset upto 658
+  UINT8       HideLPSSDevices;                   // 657 Hide unsupported LPSS devices when in ACPI mode
+  UINT8       ReservedO;                         // 658 OS Selection
+  UINT8       Reserved00;                        // 659
+  UINT8       Reserved01;                        // 660
+  UINT8       Reserved02;                   // 661
+  UINT8       Reserved03;                   // 662
+  UINT8       Reserved04;                   // 663
+  UINT8       Reserved05;                   // 664
+  UINT8       Reserved06;                   // 665
+  UINT8       Reserved07;                       // 666
+  UINT8       Reserved08;                 // 667
+  UINT8       Reserved09;                     // 668
+  UINT8       Reserved0A;                     // 669
+  UINT32      Reserved0B;       // 670
+  UINT32      Reserved0C;        // 674
+  UINT32      Reserved0D;   // 678
+  UINT32      Reserved0E;    // 682
+  UINT32      Reserved0F;   // 686
+  UINT32      Reserved10;    // 690
+  UINT32      Reserved11;   // 694
+  UINT32      Reserved12;    // 698
+  UINT32      Reserved13;   // 702
+  UINT32      Reserved14;    // 706
+  UINT32      Reserved15;   // 710
+  UINT32      Reserved16;    // 714
+  UINT8       Reserved17;
+  UINT32      Reserved18;
+  UINT32      Reserved19;
+  UINT32      Reserved1A;
+  UINT32      Reserved1B;
+  UINT32      Reserved1C;
+  UINT8       Reserved1D;
+  UINT32      Reserved1E;
+  UINT32      Reserved1F;
+  UINT32      Reserved20;
+  UINT32      Reserved21;
+  UINT32      Reserved22;
+  UINT8       Reserved23;
+  UINT8       BatteryChargingSolution;           // 761 0-non ULPMC 1-ULPMC
+
+  //
+  //101 bytes
+  //
+  UINT8       NFCnSelect;                        // 762 NFCx Select 1: NFC1    2:NFC2
+  UINT8       LpssSccMode;                       // 763 EMMC device 0-ACPI mode, 1-PCI mode
+
+  UINT32      TPMAddress;                        // 764
+  UINT32      TPMLength;                         // 768
+
+  UINT8       I2CTouchAddress;                   // 772 I2C touch address, 0x4B:RVP   0x4A:FFRD
+  UINT8       IdleReserve;                       // 773  0 - disabled 1 - enabled
+  UINT8       SDIOMode;                          // 774  3 - Default  2 - DDR50
+  UINT8       emmcVersion;                       // 775  0 - 4.41 1 - 4.5
+  UINT32      BmBound;                           // 776 BM Bound
+  UINT8       FsaStatus;                         // 780 0 - Fsa is off, 1- Fsa is on
+
+  //
+  // Board Id
+  // This field is for the ASL code to know whether this board is Baylake or Bayley Bay etc
+  //
+  UINT8       BoardID;                           //  781
+  UINT8       FabID;                             // 782
+  UINT8       OtgMode;                           // 783 0- OTG disable 1- OTG PCI mode
+  UINT8       Stepping;                          //  784 Stepping
+  UINT8       WittEnable;                        // 785 WITT eanble 0 - disable 1 - enable
+
+  UINT8       SocStepping;                       // 786 Soc Stepping infomation
+  UINT8       AmbientTripPointChange;            // 787 DPTF: Controls whether _ATI changes other participant's trip point(enabled/disabled)
+  UINT8       UtsEnable;                         // 788 Uart Test eanble 0 - disable 1 - enable
+  UINT8     DptfReserve;       // 789
+
+  UINT8       SarEnable;                          // 790
+  UINT8       PssDeveice;                        // 791 PSS Deveice: 0 - None, 1 - Monzax 2K, 2 - Monzax 8K
+  UINT8       EDPV;                              // 792 Check for eDP display device
+  UINT32      DIDX;                              // 793 Device ID for eDP device
+  UINT8       MicrosoftIoT;                      // (794)JP1 pins are for Microsoft IoT project.
+  UINT8       RtcBattery;                        // (795) The Flag of RTC Battery Present.
+  UINT8       LpeAudioReportedByDSDT;            // (796)
+} EFI_GLOBAL_NVS_AREA;
+#pragma pack ()
+
+//
+// Global NVS Area Protocol
+//
+typedef struct _EFI_GLOBAL_NVS_AREA_PROTOCOL {
+  EFI_GLOBAL_NVS_AREA     *Area;
+} EFI_GLOBAL_NVS_AREA_PROTOCOL;
+
+#endif
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/HwWatchdogTimer.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/HwWatchdogTimer.h
new file mode 100644
index 0000000000..71fe6275ee
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/HwWatchdogTimer.h
@@ -0,0 +1,235 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  HwWatchdogTimer.h
+
+Abstract:
+
+
+--*/
+
+#ifndef __EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL_H__
+#define __EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL_H__
+
+#define EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL_GUID \
+  { 0xd5b06d16, 0x2ea1, 0x4def, 0x98, 0xd0, 0xa0, 0x5d, 0x40, 0x72, 0x84, 0x17 }
+
+#define EFI_WATCHDOG_TIMER_NOT_SUPPORTED_PROTOCOL_GUID \
+  { 0xe9e156ac, 0x3203, 0x4572, 0xac, 0xdf, 0x84, 0x4f, 0xdc, 0xdb, 0x6, 0xbf }
+
+
+#include <Guid/HwWatchdogTimerHob.h>
+
+//
+// General Purpose Constants
+//
+#define ICH_INSTAFLUSH_GPIO      BIT16 // BIT 16 in GPIO Level 2 is GPIO 48.
+#define B_INSTAFLUSH             BIT4
+
+//
+// Other Watchdog timer values
+//
+#define WDT_COUNTDOWN_VALUE                 0x14
+#define BDS_WDT_COUNTDOWN_VALUE             0x35
+
+//
+// Prototypes for the Watchdog Timer Driver Protocol
+//
+
+/**
+  This service begins the Watchdog Timer countdown.  If the countdown completes prior to
+  Stop Timer or Restart Timer the system will reset.
+
+  @param[in] None
+
+  @retval EFI_SUCCESS        Operation completed successfully
+  @retval EFI_DEVICE_ERROR   The command was unsuccessful
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_WATCHDOG_START_TIMER) (
+  VOID
+  );
+
+/**
+  This service resets the Watchdog Timer countdown and should only be called after the
+  Start Timer function.
+
+  @param[in] None
+
+  @retval EFI_SUCCESS        Operation completed successfully
+  @retval EFI_DEVICE_ERROR   The command was unsuccessful
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PEI_WATCHDOG_RESET_TIMER) (
+  VOID
+  );
+
+/**
+  This service restarts the Watchdog Timer countdown and should only be called after the
+  Start Timer function.
+
+  @param[in] None
+
+  @retval EFI_SUCCESS        Operation completed successfully
+  @retval EFI_DEVICE_ERROR   The command was unsuccessful
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_WATCHDOG_RESTART_TIMER) (
+  VOID
+  );
+
+/**
+  This service disables the Watchdog Timer countdown.
+
+  @param[in] None
+
+  @retval EFI_SUCCESS        Operation completed successfully
+  @retval EFI_DEVICE_ERROR   The command was unsuccessful
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_WATCHDOG_STOP_TIMER) (
+  VOID
+  );
+
+/**
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_WATCHDOG_CHECK_TIMEOUT) (
+  OUT HW_WATCHDOG_TIMEOUT       *WatchdogTimeout
+  );
+
+
+
+/**
+  This service forces a reboot of the system due to a reset of the POWERGOOD_PS,
+  POWERGOOD_CLK, and the BSEL Override
+
+  Arguments:
+    None
+
+  Returns:
+    This function should not return!
+
+    EFI_DEVICE_ERROR  - The command was unsuccessful and a reboot did not occur
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_WATCHDOG_FORCE_REBOOT) (
+  IN BOOLEAN                    ForceTimeout,
+  IN UINT8                      ResetType
+  );
+
+/**
+  This service notifies the Watchdog Timer of the fact that a known reset is occuring.
+
+  @param[in] AllowReset  TRUE if a Reset is currently expected
+                         FALSE if a Reset is not currently expected
+
+    This function should not return!
+
+    EFI_DEVICE_ERROR  - The command was unsuccessful and a reboot did not occur
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_WATCHDOG_KNOWN_RESET) (
+  IN BOOLEAN                    AllowReset
+  );
+
+/**
+  This service reads the current Watchdog Timer countdown reload value.
+
+  @param[in] CountdownValue      pointer to UINT32 to return the value of the reload register.
+
+  @retval    EFI_SUCCESS         Operation completed successfully
+  @retval    EFI_DEVICE_ERROR    The command was unsuccessful
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_TIMER_COUNT_DOWN_PERIOD)(
+  OUT UINT32      *CountdownValue
+  );
+
+/**
+  This service reads the current Watchdog Timer countdown reload value.
+
+  @param[in] CountdownValue  Value to set the reload register.
+
+  @retval EFI_SUCCESS        Operation completed successfully
+  @retval EFI_DEVICE_ERROR   The command was unsuccessful
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_TIMER_COUNT_DOWN_PERIOD)(
+  OUT UINT32      CountdownValue
+  );
+
+/**
+  This service clears the state that indicates the Watchdog Timer fired.
+
+  @retval EFI_SUCCESS       - Operation completed successfully
+  @retval EFI_DEVICE_ERROR  - The command was unsuccessful
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PEI_WATCHDOG_CLEAR_TIMER_STATE) (
+  );
+
+/**
+  This service disables the Watchdog Timer countdown.  It also closes the recurring restart event
+  if the event exists.
+
+  @param[in] Stall  TRUE = Stop the timer countdown
+                    FALSE = Start the timer countdown
+
+  @retval  EFI_SUCCESS        Operation completed successfully
+  @retval  EFI_DEVICE_ERROR   The command was unsuccessful
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_STALL_WATCHDOG_COUNTDOWN) (
+  IN BOOLEAN Stall
+  );
+
+
+typedef struct _EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL {
+  EFI_WATCHDOG_START_TIMER                      StartWatchdogTimer;
+  PEI_WATCHDOG_RESET_TIMER                      ResetWatchdogTimeout;
+  EFI_WATCHDOG_RESTART_TIMER                    RestartWatchdogTimer;
+  EFI_WATCHDOG_STOP_TIMER                       StopWatchdogTimer;
+  EFI_WATCHDOG_CHECK_TIMEOUT                    CheckWatchdogTimeout;
+  EFI_WATCHDOG_FORCE_REBOOT                     ForceReboot;
+  EFI_WATCHDOG_KNOWN_RESET                      AllowKnownReset;
+  EFI_GET_TIMER_COUNT_DOWN_PERIOD               GetCountdownPeriod;
+  EFI_SET_TIMER_COUNT_DOWN_PERIOD               SetCountdownPeriod;
+  PEI_WATCHDOG_CLEAR_TIMER_STATE                ClearTimerState;
+  EFI_STALL_WATCHDOG_COUNTDOWN                  StallWatchdogCountdown;
+} EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL;
+
+extern EFI_GUID gEfiWatchdogTimerDriverProtocolGuid;
+extern EFI_GUID gEfiWatchdogTimerNotSupportedProtocolGuid;
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cAcpi.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cAcpi.h
new file mode 100644
index 0000000000..9ec5e1473b
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cAcpi.h
@@ -0,0 +1,107 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+**/
+
+#ifndef __I2C_ACPI_H__
+#define __I2C_ACPI_H__
+
+#include <Protocol/DevicePath.h>
+
+//
+// I2C ACPI protocol
+//
+typedef struct _EFI_I2C_ACPI_PROTOCOL   EFI_I2C_ACPI_PROTOCOL;
+
+//
+// I2C device description
+//
+// This structure provides the platform specific information which
+// describes an I2C device.
+//
+typedef struct {
+  //
+  // Hardware revision - ACPI _HRV value
+  //
+  UINT32 HardwareRevision;
+
+  //
+  // Device path node for the I2C device.
+  //
+  CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+  //
+  // I2C bus configuration for the I2C device.
+  //
+  UINT32 I2cBusConfiguration;
+
+  //
+  // Number of slave addresses for the I2C device.
+  //
+  UINT32 SlaveAddressCount;
+
+  //
+  // Address of the array of slave addresses for the I2C device.
+  //
+  CONST UINT32 *SlaveAddressArray;
+}EFI_I2C_DEVICE;
+
+
+/**
+  Enumerate the I2C devices
+
+  This routine must be called at or below TPL_NOTIFY.
+
+  This function walks the platform specific data to enumerates the
+  I2C devices on an I2C bus.
+
+  @param[in]  This              Address of an EFI_I2C_ENUM_PROTOCOL
+                                structure.
+  @param[in, out] Device        Buffer containing the address of an
+                                EFI_I2C_DEVICE structure.  Enumeration
+                                is started by setting the initial
+                                EFI_I2C_DEVICE structure address to NULL.
+                                The buffer receives an EFI_I2C_DEVICE
+                                structure address for the next I2C device.
+
+  @retval EFI_SUCCESS           The platform data for the next device
+                                on the I2C bus was returned successfully.
+  @retval EFI_INVALID_PARAMETER NextDevice was NULL
+  @retval EFI_NO_MAPPING        PreviousDevice does not point to a valid
+                                EFI_I2C_DEVICE structure.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_I2C_ACPI_ENUMERATE) (
+  IN CONST EFI_I2C_ACPI_PROTOCOL *This,
+  IN OUT CONST EFI_I2C_DEVICE **Device
+  );
+
+//
+// I2C device description
+//
+// This structure provides the platform specific information which
+// describes an I2C device.
+//
+struct _EFI_I2C_ACPI_PROTOCOL {
+  //
+  // Walk the platform's list of I2C devices on the bus.  This
+  // routine returns the next I2C device in the platform's list
+  // for this I2C bus.
+  //
+  EFI_I2C_ACPI_ENUMERATE Enumerate;
+};
+
+//
+// Variable containing the GUID for the I2C device enumeration protocol
+//
+extern EFI_GUID gEfiI2cAcpiProtocolGuid;
+
+#endif  //  __I2C_ACPI_H__
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBus.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBus.h
new file mode 100644
index 0000000000..b321a026b2
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBus.h
@@ -0,0 +1,164 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+**/
+
+#ifndef __I2C_BUS_H__
+#define __I2C_BUS_H__
+
+#include <Protocol/I2cHostMcg.h>
+
+//
+// I2C bus protocol
+//
+typedef struct _EFI_I2C_BUS_PROTOCOL  EFI_I2C_BUS_PROTOCOL;
+
+
+/**
+  Perform an I2C operation on the device
+
+  This routine must be called at or below TPL_NOTIFY.  For synchronous
+  requests this routine must be called at or below TPL_CALLBACK.
+
+  N.B. The typical consumers of this API are the third party I2C
+  drivers.  Extreme care must be taken by other consumers of this
+  API to prevent confusing the third party I2C drivers due to a
+  state change at the I2C device which the third party I2C drivers
+  did not initiate.  I2C platform drivers may use this API within
+  these guidelines.
+
+  This routine queues an operation to the I2C controller for execution
+  on the I2C bus.
+
+  As an upper layer driver writer, the following need to be provided
+  to the platform vendor:
+
+  1.  ACPI CID value or string - this is used to connect the upper layer
+      driver to the device.
+  2.  Slave address array guidance when the I2C device uses more than one
+      slave address.  This is used to access the blocks of hardware within
+      the I2C device.
+
+  @param[in] This               Address of an EFI_I2C_BUS_PROTOCOL
+                                structure
+  @param[in] SlaveAddressIndex  Index into an array of slave addresses for
+                                the I2C device.  The values in the array are
+                                specified by the board designer, with the
+                                I2C device driver writer providing the slave
+                                address order.
+
+                                For devices that have a single slave address,
+                                this value must be zero.  If the I2C device
+                                uses more than one slave address then the third
+                                party (upper level) I2C driver writer needs to
+                                specify the order of entries in the slave address
+                                array.
+
+                                \ref ThirdPartyI2cDrivers "Third Party I2C Drivers"
+                                section in I2cMaster.h.
+  @param[in] Event              Event to set for asynchronous operations,
+                                NULL for synchronous operations
+  @param[in] RequestPacket      Address of an EFI_I2C_REQUEST_PACKET
+                                structure describing the I2C operation
+  @param[out] I2cStatus         Optional buffer to receive the I2C operation
+                                completion status
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_ABORTED           The request did not complete because the driver
+                                was shutdown.
+  @retval EFI_ACCESS_DENIED     Invalid SlaveAddressIndex value
+  @retval EFI_BAD_BUFFER_SIZE   The WriteBytes or ReadBytes buffer size is too large.
+  @retval EFI_DEVICE_ERROR      There was an I2C error (NACK) during the operation.
+                                This could indicate the slave device is not present.
+  @retval EFI_INVALID_PARAMETER RequestPacket is NULL
+  @retval EFI_INVALID_PARAMETER TPL is too high
+  @retval EFI_NO_RESPONSE       The I2C device is not responding to the
+                                slave address.  EFI_DEVICE_ERROR may also be
+                                returned if the controller can not distinguish
+                                when the NACK occurred.
+  @retval EFI_NOT_FOUND         I2C slave address exceeds maximum address
+  @retval EFI_NOT_READY         I2C bus is busy or operation pending, wait for
+                                the event and then read status pointed to by
+                                the request packet.
+  @retval EFI_OUT_OF_RESOURCES  Insufficient memory for I2C operation
+  @retval EFI_TIMEOUT           The transaction did not complete within an internally
+                                specified timeout period.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_I2C_BUS_START_REQUEST) (
+  IN CONST EFI_I2C_BUS_PROTOCOL *This,
+  IN UINTN SlaveAddressIndex,
+  IN EFI_EVENT Event OPTIONAL,
+  IN CONST EFI_I2C_REQUEST_PACKET *RequestPacket,
+  OUT EFI_STATUS *I2cStatus OPTIONAL
+  );
+
+//
+// The I2C bus protocol enables access to a specific device on the I2C bus.
+//
+// Each I2C device is described as an ACPI node (HID, UID and CID) within the
+// platform layer.  The I2C bus protocol enumerates the I2C devices in the
+// platform and creates a unique handle and device path for each I2C device.
+//
+// I2C slave addressing is abstracted to validate addresses and limit operation
+// to the specified I2C device.  The third party providing the I2C device support
+// provides an ordered list of slave addresses for the I2C device to the team
+// building the platform layer.  The platform team must preserve the order of the
+// supplied list.  SlaveAddressCount is the number of entries in this list or
+// array within the platform layer.  The third party device support references
+// a slave address using an index into the list or array in the range of zero
+// to SlaveAddressCount - 1.
+//
+struct _EFI_I2C_BUS_PROTOCOL {
+  //
+  // Start an I2C operation on the bus
+  //
+  EFI_I2C_BUS_START_REQUEST StartRequest;
+
+  //
+  // The maximum number of slave addresses for the I2C device.  The caller may
+  // validate this value as a check on the platform layer's configuration.  Slave
+  // address selection uses an index value in the range of zero to SlaveAddressCount - 1.
+  //
+  UINTN SlaveAddressCount;
+
+  //
+  // Hardware revision - Matches the ACPI _HRV value
+  //
+  // The HardwareRevision value allows a single driver to support multiple hardware
+  // revisions and implement the necessary workarounds for limitations within the
+  // hardware.
+  //
+  UINT32 HardwareRevision;
+
+  //
+  // The maximum number of bytes the I2C host controller
+  // is able to receive from the I2C bus.
+  //
+  UINT32 MaximumReceiveBytes;
+
+  //
+  // The maximum number of bytes the I2C host controller
+  // is able to send on the I2C bus.
+  //
+  UINT32 MaximumTransmitBytes;
+
+  //
+  // The maximum number of bytes in the I2C bus transaction.
+  //
+  UINT32 MaximumTotalBytes;
+};
+
+//
+// GUID for the I2C bus protocol
+//
+extern EFI_GUID gEfiI2cBusProtocolGuid;
+
+#endif  //  __I2C_BUS_H__
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBusMcg.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBusMcg.h
new file mode 100644
index 0000000000..1cfca218bd
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBusMcg.h
@@ -0,0 +1,163 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+**/
+
+#ifndef __I2C_BUS_H__
+#define __I2C_BUS_H__
+
+#include <Protocol/I2cHostMcg.h>
+
+//
+// I2C bus protocol
+//
+typedef struct _EFI_I2C_BUS_PROTOCOL  EFI_I2C_BUS_PROTOCOL;
+
+/**
+  Perform an I2C operation on the device
+
+  This routine must be called at or below TPL_NOTIFY.  For synchronous
+  requests this routine must be called at or below TPL_CALLBACK.
+
+  N.B. The typical consumers of this API are the third party I2C
+  drivers.  Extreme care must be taken by other consumers of this
+  API to prevent confusing the third party I2C drivers due to a
+  state change at the I2C device which the third party I2C drivers
+  did not initiate.  I2C platform drivers may use this API within
+  these guidelines.
+
+  This routine queues an operation to the I2C controller for execution
+  on the I2C bus.
+
+  As an upper layer driver writer, the following need to be provided
+  to the platform vendor:
+
+  1.  ACPI CID value or string - this is used to connect the upper layer
+      driver to the device.
+  2.  Slave address array guidance when the I2C device uses more than one
+      slave address.  This is used to access the blocks of hardware within
+      the I2C device.
+
+  @param[in] This               Address of an EFI_I2C_BUS_PROTOCOL
+                                structure
+  @param[in] SlaveAddressIndex  Index into an array of slave addresses for
+                                the I2C device.  The values in the array are
+                                specified by the board designer, with the
+                                I2C device driver writer providing the slave
+                                address order.
+
+                                For devices that have a single slave address,
+                                this value must be zero.  If the I2C device
+                                uses more than one slave address then the third
+                                party (upper level) I2C driver writer needs to
+                                specify the order of entries in the slave address
+                                array.
+
+                                \ref ThirdPartyI2cDrivers "Third Party I2C Drivers"
+                                section in I2cMaster.h.
+  @param[in] Event              Event to set for asynchronous operations,
+                                NULL for synchronous operations
+  @param[in] RequestPacket      Address of an EFI_I2C_REQUEST_PACKET
+                                structure describing the I2C operation
+  @param[out] I2cStatus         Optional buffer to receive the I2C operation
+                                completion status
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_ABORTED           The request did not complete because the driver
+                                was shutdown.
+  @retval EFI_ACCESS_DENIED     Invalid SlaveAddressIndex value
+  @retval EFI_BAD_BUFFER_SIZE   The WriteBytes or ReadBytes buffer size is too large.
+  @retval EFI_DEVICE_ERROR      There was an I2C error (NACK) during the operation.
+                                This could indicate the slave device is not present.
+  @retval EFI_INVALID_PARAMETER RequestPacket is NULL
+  @retval EFI_INVALID_PARAMETER TPL is too high
+  @retval EFI_NO_RESPONSE       The I2C device is not responding to the
+                                slave address.  EFI_DEVICE_ERROR may also be
+                                returned if the controller can not distinguish
+                                when the NACK occurred.
+  @retval EFI_NOT_FOUND         I2C slave address exceeds maximum address
+  @retval EFI_NOT_READY         I2C bus is busy or operation pending, wait for
+                                the event and then read status pointed to by
+                                the request packet.
+  @retval EFI_OUT_OF_RESOURCES  Insufficient memory for I2C operation
+  @retval EFI_TIMEOUT           The transaction did not complete within an internally
+                                specified timeout period.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_I2C_BUS_START_REQUEST) (
+  IN CONST EFI_I2C_BUS_PROTOCOL *This,
+  IN UINTN SlaveAddressIndex,
+  IN EFI_EVENT Event OPTIONAL,
+  IN CONST EFI_I2C_REQUEST_PACKET *RequestPacket,
+  OUT EFI_STATUS *I2cStatus OPTIONAL
+  );
+
+//
+// The I2C bus protocol enables access to a specific device on the I2C bus.
+//
+// Each I2C device is described as an ACPI node (HID, UID and CID) within the
+// platform layer.  The I2C bus protocol enumerates the I2C devices in the
+// platform and creates a unique handle and device path for each I2C device.
+//
+// I2C slave addressing is abstracted to validate addresses and limit operation
+// to the specified I2C device.  The third party providing the I2C device support
+// provides an ordered list of slave addresses for the I2C device to the team
+// building the platform layer.  The platform team must preserve the order of the
+// supplied list.  SlaveAddressCount is the number of entries in this list or
+// array within the platform layer.  The third party device support references
+// a slave address using an index into the list or array in the range of zero
+// to SlaveAddressCount - 1.
+//
+struct _EFI_I2C_BUS_PROTOCOL {
+  //
+  // Start an I2C operation on the bus
+  //
+  EFI_I2C_BUS_START_REQUEST StartRequest;
+
+  //
+  // The maximum number of slave addresses for the I2C device.  The caller may
+  // validate this value as a check on the platform layer's configuration.  Slave
+  // address selection uses an index value in the range of zero to SlaveAddressCount - 1.
+  //
+  UINTN SlaveAddressCount;
+
+  //
+  // Hardware revision - Matches the ACPI _HRV value
+  //
+  // The HardwareRevision value allows a single driver to support multiple hardware
+  // revisions and implement the necessary workarounds for limitations within the
+  // hardware.
+  //
+  UINT32 HardwareRevision;
+
+  //
+  // The maximum number of bytes the I2C host controller
+  // is able to receive from the I2C bus.
+  ///
+  UINT32 MaximumReceiveBytes;
+
+  //
+  // The maximum number of bytes the I2C host controller
+  // is able to send on the I2C bus.
+  //
+  UINT32 MaximumTransmitBytes;
+
+  //
+  // The maximum number of bytes in the I2C bus transaction.
+  //
+  UINT32 MaximumTotalBytes;
+};
+
+//
+// GUID for the I2C bus protocol
+//
+extern EFI_GUID gEfiI2cBusProtocolGuid;
+
+#endif  //  __I2C_BUS_H__
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cHostMcg.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cHostMcg.h
new file mode 100644
index 0000000000..1d94ee4106
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cHostMcg.h
@@ -0,0 +1,138 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+**/
+
+#ifndef __I2C_HOST_H__
+#define __I2C_HOST_H__
+
+#include <Protocol/I2cMasterMcg.h>
+
+/**
+  Declare the forward references
+
+**/
+typedef struct _EFI_I2C_HOST_PROTOCOL EFI_I2C_HOST_PROTOCOL;
+typedef struct _EFI_I2C_HOST_CALLBACKS EFI_I2C_HOST_CALLBACKS;
+
+
+/**
+  Queue an I2C operation for execution on the I2C controller.
+
+  This routine must be called at or below TPL_NOTIFY.  For synchronous
+  requests this routine must be called at or below TPL_CALLBACK.
+
+  N.B. The typical consumers of this API are the I2C bus driver and
+  on rare occasions the I2C test application.  Extreme care must be
+  taken by other consumers of this API to prevent confusing the
+  third party I2C drivers due to a state change at the I2C device
+  which the third party I2C drivers did not initiate.  I2C platform
+  drivers may use this API within these guidelines.
+
+  This layer uses the concept of I2C bus configurations to describe
+  the I2C bus.  An I2C bus configuration is defined as a unique
+  setting of the multiplexers and switches in the I2C bus which
+  enable access to one or more I2C devices.  When using a switch
+  to divide a bus, due to speed differences, the I2C platform layer
+  would define an I2C bus configuration for the I2C devices on each
+  side of the switch.  When using a multiplexer, the I2C platform
+  layer defines an I2C bus configuration for each of the selector
+  values required to control the multiplexer.  See Figure 1 in the
+  <a href="http://www.nxp.com/documents/user_manual/UM10204.pdf">I<sup>2</sup>C
+  Specification</a> for a complex I2C bus configuration.
+
+  The I2C host driver processes all operations in FIFO order.  Prior to
+  performing the operation, the I2C host driver calls the I2C platform
+  driver to reconfigure the switches and multiplexers in the I2C bus
+  enabling access to the specified I2C device.  The I2C platform driver
+  also selects the maximum bus speed for the device.  After the I2C bus
+  is configured, the I2C host driver calls the I2C port driver to
+  initialize the I2C controller and start the I2C operation.
+
+  @param[in] This             Address of an EFI_I2C_HOST_PROTOCOL instance.
+  @param[in] I2cBusConfiguration  I2C bus configuration to access the I2C
+                                  device.
+  @param[in] SlaveAddress     Address of the device on the I2C bus.
+  @param[in] Event            Event to set for asynchronous operations,
+                              NULL for synchronous operations
+  @param[in] RequestPacket    Address of an EFI_I2C_REQUEST_PACKET
+                              structure describing the I2C operation
+  @param[out] I2cStatus       Optional buffer to receive the I2C operation
+                              completion status
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_ABORTED           The request did not complete because the driver
+                                was shutdown.
+  @retval EFI_BAD_BUFFER_SIZE   The WriteBytes or ReadBytes buffer size is too large.
+  @retval EFI_DEVICE_ERROR      There was an I2C error (NACK) during the operation.
+                                This could indicate the slave device is not present.
+  @retval EFI_INVALID_PARAMETER RequestPacket is NULL
+  @retval EFI_INVALID_PARAMETER TPL is too high
+  @retval EFI_NO_MAPPING        Invalid I2cBusConfiguration value
+  @retval EFI_NO_RESPONSE       The I2C device is not responding to the
+                                slave address.  EFI_DEVICE_ERROR may also be
+                                returned if the controller cannot distinguish
+                                when the NACK occurred.
+  @retval EFI_NOT_FOUND         I2C slave address exceeds maximum address
+  @retval EFI_NOT_READY         I2C bus is busy or operation pending, wait for
+                                the event and then read status pointed to by
+                                the request packet.
+  @retval EFI_OUT_OF_RESOURCES  Insufficient memory for I2C operation
+  @retval EFI_TIMEOUT           The transaction did not complete within an internally
+                                specified timeout period.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_I2C_HOST_QUEUE_REQUEST) (
+  IN CONST EFI_I2C_HOST_PROTOCOL *This,
+  IN UINTN I2cBusConfiguration,
+  IN UINTN SlaveAddress,
+  IN EFI_EVENT Event OPTIONAL,
+  IN CONST EFI_I2C_REQUEST_PACKET *RequestPacket,
+  OUT EFI_STATUS *I2cStatus OPTIONAL
+  );
+
+///
+/// Host access to the I2C bus.
+///
+struct _EFI_I2C_HOST_PROTOCOL {
+  ///
+  /// Queue an operation for execution on the I2C bus
+  ///
+  EFI_I2C_HOST_QUEUE_REQUEST QueueRequest;
+
+  ///
+  /// The maximum number of I2C bus configurations
+  ///
+  UINTN I2cBusConfigurationCount;
+
+  ///
+  /// The maximum number of bytes the I2C host controller
+  /// is able to receive from the I2C bus.
+  ///
+  UINT32 MaximumReceiveBytes;
+
+  ///
+  /// The maximum number of bytes the I2C host controller
+  /// is able to send on the I2C bus.
+  ///
+  UINT32 MaximumTransmitBytes;
+
+  ///
+  /// The maximum number of bytes in the I2C bus transaction.
+  ///
+  UINT32 MaximumTotalBytes;
+};
+
+///
+/// GUID for the EFI_I2C_HOST_PROTOCOL
+///
+extern EFI_GUID gEfiI2cHostProtocolGuid;
+
+#endif  //  __I2C_HOST_H__
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cMasterMcg.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cMasterMcg.h
new file mode 100644
index 0000000000..5ca47b2c7f
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cMasterMcg.h
@@ -0,0 +1,519 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+  \section I2cDriverStack       I2C Driver Stack
+
+  The following is a representation of the I<sup>2</sup>C (I2C)
+  driver stack and an I2C bus layout.
+
+  <code><pre>
+              +-----------------+
+              |   Application   |
+              +-----------------+
+                       |
+                       | Third Party or UEFI
+                       |
+                       V
+ +--------+   +-----------------+
+ | Slave  |   |   Third Party   |
+ | Driver |   |   I2C Device    |
+ |        |   |     Driver      |
+ +--------+   +-----------------+
+      |                |
+      |          BUS   |
+      |                |
+      |                V
+      |       +-----------------+
+      |       | I2C Bus Driver  |------------------.
+      |       +-----------------+                  |
+      |                |                           |
+      |         HOST   |          BUS              |
+      |                |          CONFIGURATION    |
+SLAVE |                V          MANAGEMENT       | ACPI
+      |       +-----------------+                  |
+      |       | I2C Host Driver |----------.       |
+      |       +-----------------+          |       |
+      |                |                   |       |
+      |        MASTER  |                   V       V
+      |                |               +-------=-------------+
+      |                V               | I2C Platform Driver |
+      |       +-----------------+      +---------------------+
+      `------>| I2C Port Driver |               |      |
+              +-----------------+               |      |
+                       |                        |      |
+            Software   |                        |      |
+            --------------------------------------------------
+            Hardware   |                        |      |
+                       |                        |      |
+                       V                        |      |
+              +-----------------+               |      |
+              | I2C Controller  |               |      |
+              +-----------------+               |      |
+                       |                        |      |
+            -----------------------             |      |
+            I2C Bus    |                        |      |
+                       |    +------------+      |      |
+                       +----| High speed |      |      |
+                       |    | I2C device |      |      |
+                       |    |    0x01    |      |      |
+                       |    +------------+      |      |
+                       |                        |      |
+                  +---------+  0                |      |
+                  | Switch  |<------------------`      |
+                  +---------+  1                       |
+                       |                               |
+                       |    +------------+             |
+                       +----| Fast speed |             |
+                       |    | I2C device |             |
+                       |    |    0x02    |             |
+                       |    +------------+             |
+                       |                               |
+                +-------------+                        |
+                | Multiplexer |<-----------------------`
+                +-------------+
+                 0 |       | 1
+                   |       |
+                   |       |
+                   |       |    +-------------+
+                   |       +----| Third Party |
+                   |       |    | I2C Device  |
+                   |       |    |  0x03, 0x04 |
+                   |       |    +-------------+
+                   |       |
+                   |
+                   |            +-------------+
+                   +------------| Third Party |
+                   |            | I2C Device  |
+                   |            |  0x03, 0x04 |
+                   |            +-------------+
+                   |
+  </pre></code>
+
+  The platform hardware designer chooses the bus layout based upon
+  the platform, I2C chip and software requirements.  The design uses
+  switches to truncate the bus to enable higher speed operation for a
+  subset of devices which are placed closer to the controller.  When the
+  switch is on, the extended bus must operate at a lower speed.  The
+  design uses multiplexer to create separate address spaces enabling
+  the use of multiple devices which would otherwise have conflicting
+  addresses. See the
+  <a href="http://www.nxp.com/documents/user_manual/UM10204.pdf">I<sup>2</sup>C
+  Specification</a> for more details.
+
+  N.B. Some operating systems may prohibit the changing of switches
+  and multiplexers in the I2C bus.  In this case the platform hardware
+  and software designers must select a single I2C bus configuration
+  consisting of constant input values for the switches and multiplexers.
+  The platform software designer must then ensure that this I2C bus
+  configuration is enabled prior to passing control to the operating
+  system.
+
+  The platform hardware designer needs to provide the platform software
+  designer the following data for each I2C bus:
+
+  1.  Which controller controls this bus
+
+  2.  A list of logic blocks contained in one or more I2C devices:
+
+      a.  I2C device which contains this logic block
+
+      b.  Logic block slave address
+
+      c.  Logic block name
+
+  3.  For each configuration of the switches and multiplexer
+
+      a.  What is the maximum speed of operation
+
+      b.  What devices are accessible
+
+  4.  The settings for the switches and multiplexers when control is
+      given to the operating system.
+
+  \section ThirdPartyI2cDrivers   Third Party I2C Drivers
+
+  This layer is I2C chip specific but platform and host controller
+  independent.
+
+  Third party I2C driver writers, typically silicon vendors, need
+  to provide:
+
+  1.  The device path node data that is used to select their
+      driver.
+
+  2.  The order for the blocks of logic that get referenced
+      by the entries in the slave address array.
+
+  3.  The hardware version of the I2C device, this value is passed
+      to the third party I2C driver to enable it to perform work
+      arounds for the specific hardware version.  This value should
+      match the value in the ACPI _HRV tag.
+
+  The third party I2C driver uses relative addressing to abstract
+  the platform specific details of the I2C device.  Using an
+  example I2C device containing an accelerometer and a magnetometer
+  which consumes two slave addresses, one for each logic block.  The
+  third party I2C driver writer may choose to write two drivers, one
+  for each block of logic, in which case each driver refers to the
+  single I2C slave address using the relative value of zero (0).
+  However if the third party I2C driver writer chooses to write a
+  single driver which consumes multiple slave addresses then the
+  third party I2C driver writer needs to convey the order of the
+  I2C slave address entries in the slave address array to the
+  platform software designer.  For the example:
+
+      0: Accelerometer
+
+      1: Magnetometer
+
+  The platform hardware designer picks the actual slave addresses
+  from the I2C device's data sheet and provides this information
+  to the platform software designer.  The platform software designer
+  then places the slave addresses into the slave address array in the
+  order specified by the third party I2C driver writer.  The third
+  party driver I2C writer then indirectly references this array by
+  specifying the index value as the relative slave address.  The
+  relative value always starts at zero (0) and its maximum value is
+  the number of entries in slave address array minus one.
+
+  The slave address is specified as a 32-bit integer to allow room
+  for future slave address expansion.  Only the port driver knows
+  the maximum slave address value.  All other drivers and
+  applications must look for the EFI_NOT_FOUND status for the
+  indication that the maximum slave address was exceeded.
+
+  \section I2cBusDriver         I2C Bus Driver
+
+  This layer is platform, host controller, and I2C chip independent.
+
+  The I2C bus driver creates a handle for each of the I2C devices
+  described within the platform driver.  The I2C controller's device
+  path is extended with the device path node provided by the platform
+  driver and attached to the handle.  The third party I2C device driver
+  uses the device path to determine if it may connect.  For ACPI nodes,
+  the third party I2C driver should use the CID or CidString value.
+
+  The I2C bus driver validates the relative address for the I2C device
+  and then converts the relative value to an actual I2C slave address.
+  The request is then passed to the I2C host driver.
+
+  \section I2cHostDriver        I2C Host Driver
+
+  This layer is platform, host controller, and I2C chip independent.
+
+  N.B. For proper operation of the I2C bus, only the I2C bus driver
+  and the I2C test application should connect to the I2C host driver
+  via the EFI_I2C_HOST_DRIVER_PROTOCOL.
+
+  The I2C host driver may access any device on the I2C bus.  The I2C
+  host driver has the following responsibilities:
+
+  1.  Limits the number of requests to the I2C port driver to one.
+      The I2C host driver holds on to additional requests until the
+      I2C port driver is available to process the request.  The I2C
+      requests are issued in FIFO order to the I2C port driver.
+
+  2.  Enable the proper I2C bus configuration before starting the
+      I2C request on the I2C port driver
+
+  I2C devices are addressed as the tuple: BusConfiguration:SlaveAddress.
+  I2C bus configuration zero (0) is the portion of the I2C bus that
+  connects to the host controller.  The bus configuration specifies
+  the control values for the switches and multiplexers in the I2C bus.
+  After the switches and multiplexers are properly configured, the I2C
+  controller uses the slave address to access the requested I2C device.
+
+  Since the I2C driver stack supports asynchronous operations this
+  layer maintains a queue of I2C requests until the I2C controller
+  is available them.  When a request reaches the head of the queue
+  the necessary bus configuration is enabled and then the request
+  is sent to the I2C port driver.
+
+  \section I2cPortDriver        I2C Port Driver
+
+  This layer is I2C controller specific but platform independent.
+
+  This layer manipulates the I2C controller to perform an operation
+  on the I2C bus.  This layer does not configure the I2C bus so it
+  is up to the caller to ensure that the I2C bus is in the proper
+  configuration before issuing the I2C request.
+
+  This layer typically needs the following information:
+
+  1.  Host controller address
+  2.  Controller's input clock frequency
+
+  Depending upon the I2C controller, more data may be necessary.
+  This layer may use any method to get these values: hard coded
+  values, PCD values, or may choose to communicate with the platform
+  layer using an undefined mechanism to get these values.
+
+  If the I2C port driver requires data from the platform driver then
+  the I2C port driver writer needs to provide the platform interface
+  details to the platform software designer.
+
+  \section I2cPlatformDriver    I2C Platform Driver
+
+  When enabling access to I2C devices within UEFI, this driver
+  installs the EFI_I2C_ACPI_PROTOCOL to provide the I2C device
+  descriptions to the I2C bus driver using the EFI_I2C_DEVICE
+  structure.  These descriptions include the bus configuration
+  number required for the I2C device, the slave address array
+  and the device path.
+
+  The EFI_I2C_BUS_CONFIGURATION_MANAGEMENT protocol is optional.
+  This protocol needs to be specified under the following conditions:
+
+  1.  The I2C bus must operate at a frequency greater than 100 KHz
+  2.  The I2C bus contains switches or multiplexers.
+
+  The EFI_I2C_BUS_CONFIGURATION_MANAGEMENT protocol enables the
+  I2C host driver to call into the I2C platform driver to enable
+  a specific I2C bus configuration and set its maximum clock speed.
+
+  The platform software designer collects the data requirements
+  from third party I2C driver writers, the I2C controller
+  driver writer, the EFI_I2C_ACPI_PROTOCOL and
+  EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL.  The platform
+  software designer gets the necessary data from the platform
+  hardware designer.  The platform software designer then builds
+  the data structures and implements the necessary routines to
+  construct the I2C platform driver.
+
+  \section I2cSwitches          Switches and Multiplexers
+
+  There are some I2C switches and I2C multiplexers where the control
+  is done via I2C commands.  When the control inputs come via the
+  same I2C bus that is being configured then the platform driver must
+  use the EFI_I2C_MASTER_PROTOCOL that is passed to the platform
+  driver.  While the I2C host driver makes the call to the I2C
+  platform driver to configure the bus, the host driver keeps the
+  I2C port driver idle, to allow the I2C platform driver preform
+  the necessary configuration operations.
+
+  If however the configuration control is done via and I2C device
+  connected to a different I2C bus (host controller), then it is
+  possible for the platform software designer may choose between
+  the following:
+
+  1.  Call into a third party I2C driver to manipulate the I2C
+      bus control device.
+  2.  Call into the EFI_I2C_BUS_PROTOCOL if no third party I2C
+      driver exists for the I2C bus control device
+  3.  Call into the EFI_I2C_HOST_PROTOCOL if the platform does
+      not expose the I2C bus control device.
+
+**/
+
+#ifndef __I2C_MASTER_H__
+#define __I2C_MASTER_H__
+
+/**
+  Declare the forward references
+
+**/
+typedef struct _EFI_I2C_MASTER_PROTOCOL   EFI_I2C_MASTER_PROTOCOL;  ///<  I2C master protocol
+
+///
+/// I2C device operation
+///
+/// This structure provides the information necessary for an operation
+/// on an I2C device
+///
+typedef struct {
+  ///
+  /// Number of bytes to send to the I2C device
+  ///
+  UINT32 WriteBytes;
+
+  ///
+  /// Number of bytes to read, set to zero for write only operations
+  ///
+  UINT32 ReadBytes;
+
+  ///
+  /// Address of the buffer containing the data to send to the I2C device.
+  /// The WriteBuffer must be at least WriteBytes in length.
+  ///
+  UINT8 *WriteBuffer;
+
+  ///
+  /// Address of the buffer to receive data from the I2C device. Use NULL
+  /// for write only operations.  The ReadBuffer must be at least ReadBytes
+  /// in length.
+  ///
+  UINT8 *ReadBuffer;
+
+  ///
+  /// Timeout for the I2C operation in 100 ns units
+  ///
+  UINT32 Timeout;
+} EFI_I2C_REQUEST_PACKET;
+
+
+/**
+  Set the I2C controller bus clock frequency.
+
+  This routine must be called at or below TPL_NOTIFY.
+
+  The software and controller do a best case effort of using the specified
+  frequency for the I2C bus.  If the frequency does not match exactly then
+  the controller will use a slightly lower frequency to avoid
+  exceeding the operating conditions for any of the I2C devices on the bus.
+  For example if 400 KHz was specified and the controller's divide network
+  only supports 402 KHz or 398 KHz then the controller would be set to 398
+  KHz.  However if the desired frequency is 400 KHz and the controller only
+  supports 1 MHz and 100 KHz then this routine would return EFI_UNSUPPORTED.
+
+  @param[in] This           Address of an EFI_I2C_MASTER_PROTOCOL
+                            structure
+  @param[in] BusClockHertz  New I2C bus clock frequency in Hertz
+
+  @retval EFI_SUCCESS       The bus frequency was set successfully.
+  @retval EFI_UNSUPPORTED   The controller does not support this frequency.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_I2C_MASTER_BUS_FREQUENCY_SET) (
+  IN CONST EFI_I2C_MASTER_PROTOCOL *This,
+  IN UINTN BusClockHertz
+  );
+
+/**
+  Reset the I2C controller and configure it for use
+
+  This routine must be called at or below TPL_NOTIFY.
+
+  The I2C controller is reset and the I2C bus frequency is set to 100 KHz.
+
+  @param[in]     This       Address of an EFI_I2C_MASTER_PROTOCOL
+                            structure
+
+**/
+typedef
+VOID
+(EFIAPI *EFI_I2C_MASTER_RESET) (
+  IN CONST EFI_I2C_MASTER_PROTOCOL *This
+  );
+
+/**
+  Start an I2C operation on the host controller
+
+  This routine must be called at or below TPL_NOTIFY.  For synchronous
+  requests this routine must be called at or below TPL_CALLBACK.
+
+  This function initiates an I2C operation on the controller.
+
+  The operation is performed by selecting the I2C device with its slave
+  address and then sending all write data to the I2C device.  If read data
+  is requested, a restart is sent followed by the slave address and then
+  the read data is clocked into the I2C controller and placed in the read
+  buffer.  When the operation completes, the status value is returned and
+  then the event is set.
+
+  N.B. The typical consumer of this API is the I2C host driver.
+  Extreme care must be taken by other consumers of this API to
+  prevent confusing the third party I2C drivers due to a state
+  change at the I2C device which the third party I2C drivers did
+  not initiate.  I2C platform drivers may use this API within
+  these guidelines.
+
+  N.B. This API supports only one operation, no queuing support
+  exists at this layer.  This API assumes that the I2C bus is in
+  the correct configuration for the I2C request.
+
+  @param[in] This           Address of an EFI_I2C_MASTER_PROTOCOL
+                            structure
+  @param[in] SlaveAddress   Address of the device on the I2C bus.
+  @param[in] Event          Event to set for asynchronous operations,
+                            NULL for synchronous operations
+  @param[in] RequestPacket  Address of an EFI_I2C_REQUEST_PACKET
+                            structure describing the I2C operation
+  @param[out] I2cStatus     Optional buffer to receive the I2C operation
+                            completion status
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_ABORTED           The request did not complete because the driver
+                                was shutdown.
+  @retval EFI_BAD_BUFFER_SIZE   The WriteBytes or ReadBytes buffer size is too large.
+  @retval EFI_DEVICE_ERROR      There was an I2C error (NACK) during the operation.
+                                This could indicate the slave device is not present.
+  @retval EFI_INVALID_PARAMETER RequestPacket is NULL
+  @retval EFI_INVALID_PARAMETER TPL is too high
+  @retval EFI_NOT_FOUND         SlaveAddress exceeds maximum address
+  @retval EFI_NOT_READY         I2C bus is busy or operation pending, wait for
+                                the event and then read status pointed to by
+                                the request packet.
+  @retval EFI_NO_RESPONSE       The I2C device is not responding to the
+                                slave address.  EFI_DEVICE_ERROR may also be
+                                returned if the controller cannot distinguish
+                                when the NACK occurred.
+  @retval EFI_OUT_OF_RESOURCES  Insufficient memory for I2C operation
+  @retval EFI_TIMEOUT           The transaction did not complete within an internally
+                                specified timeout period.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_I2C_MASTER_START_REQUEST) (
+  IN CONST EFI_I2C_MASTER_PROTOCOL *This,
+  IN UINTN SlaveAddress,
+  IN EFI_EVENT Event OPTIONAL,
+  IN CONST EFI_I2C_REQUEST_PACKET *RequestPacket,
+  OUT EFI_STATUS *I2cStatus OPTIONAL
+  );
+
+///
+/// I2C master mode protocol
+///
+/// This protocol manipulates the I2C host controller to perform transactions as a
+/// master on the I2C bus using the current state of any switches or multiplexers
+/// in the I2C bus.
+///
+struct _EFI_I2C_MASTER_PROTOCOL {
+  ///
+  /// Set the clock frequency for the I2C bus
+  ///
+  EFI_I2C_MASTER_BUS_FREQUENCY_SET BusFrequencySet;
+
+  ///
+  /// Reset the I2C host controller
+  ///
+  EFI_I2C_MASTER_RESET Reset;
+
+  ///
+  /// Start an I2C transaction in master mode on the host controller
+  ///
+  EFI_I2C_MASTER_START_REQUEST StartRequest;
+
+  ///
+  /// The maximum number of bytes the I2C host controller
+  /// is able to receive from the I2C bus.
+  ///
+  UINT32 MaximumReceiveBytes;
+
+  ///
+  /// The maximum number of bytes the I2C host controller
+  /// is able to send on the I2C bus.
+  ///
+  UINT32 MaximumTransmitBytes;
+
+  ///
+  /// The maximum number of bytes in the I2C bus transaction.
+  ///
+  UINT32 MaximumTotalBytes;
+};
+
+///
+/// GUID for the EFI_I2C_MASTER_PROTOCOL
+///
+extern EFI_GUID gEfiI2cMasterProtocolGuid;
+
+#endif  //  __I2C_MASTER_H__
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cSlave.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cSlave.h
new file mode 100644
index 0000000000..64cb2b7398
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cSlave.h
@@ -0,0 +1,194 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+**/
+
+#ifndef __I2C_SLAVE_H__
+#define __I2C_SLAVE_H__
+
+#include <Protocol/I2cHostMcg.h>
+
+/**
+  Declare the forward references
+
+**/
+typedef struct _EFI_I2C_SLAVE_PROTOCOL    EFI_I2C_SLAVE_PROTOCOL;   ///<  I2C slave protocol
+
+/**
+  The I2C controller received a data byte from the
+  I2C msster.
+
+  @param[in] Context        The value passed to the slave enable routine.
+  @param[in] NumberOfBytes  Number of data bytes received
+  @param[in] Data           Buffer containing the received data bytes
+
+  @retval EFI_SUCCESS       ACK the data byte
+  @retval EFI_UNSUPPORTED   NACK the data byte
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_I2C_SLAVE_RECEIVE_DATA) (
+  IN VOID *Context,
+  IN UINTN NumberOfBytes,
+  IN CONST UINT8 *Data
+  );
+
+/**
+  The I2C controller received the start bit from the
+  I2C master.
+
+  @param[in] Context        The value passed to the slave enable routine.
+
+**/
+typedef
+VOID
+(EFIAPI *EFI_I2C_SLAVE_RECEIVE_START) (
+  IN VOID *Context,
+  IN UINTN BytesSent,
+  IN EFI_STATUS Status
+  );
+
+/**
+  The I2C controller received the stop bit from the
+  I2C master.
+
+  @param[in] Context        The value passed to the slave enable routine.
+  @param[in] BytesSent      Number of bytes successfully ACKed by the
+                            I2C master.  This is a hint, not all I2C
+                            controllers support the ability to return
+                            the number of bytes sent.  When it is not
+                            possible, the port driver returns zero.
+  @param[in] Status         <ul>
+                              <li>EFI_SUCCESS - All of the data was successfully sent</li>
+                              <li>EFI_ABORTED - The controller was reset</li>
+                              <li>EFI_DEVICE_ERROR - A NACK was received when sending the data.</li>
+                              <li>EFI_END_OF_FILE - The stop bit was received before all of
+                                the data was sent.</li>
+                            </ul>
+
+**/
+typedef
+VOID
+(EFIAPI *EFI_I2C_SLAVE_RECEIVE_STOP) (
+  IN VOID *Context,
+  IN UINTN BytesSent,
+  IN EFI_STATUS Status
+  );
+
+/**
+  Enable or disable I2C slave operation.
+
+  The ReceiveData callback allows the port driver to return data
+  to the driver or application handling slave mode operations.  This
+  is data that a remote master has sent to the local I2C controller.
+  The data may be returned one byte at a time if the controller supports
+  the ability to ACK/NACK on each receive byte.  If not, a block of
+  data may be returned by the I2C port driver and the ACK/NACK status
+  is used only as a hint for the port driver.
+
+  The slave mode driver or application should buffer the data until
+  either ReceiveStart or ReceiveStop is called.  At that time all of
+  the data is received and the command may be processed.
+
+  ReceiveStart is called when the I2C master is expecting a response.
+  After processing the command, but before sending the response the
+  slave driver or application should mark the command as processed to
+  avoid processing it a second time when ReceiveStop is called.  The
+  slave driver or application then calls SendData to send to queue the
+  response data for transmission.  The data must remain valid in the
+  WriteBuffer until ReceiveStop is called.
+
+  ReceiveStop is called when the stop bit is received on the I2C bus.
+  The slave driver or application starts processing the command if an
+  command data is pending in the slave driver's or application's buffer.
+  The BytesSent value is a hint to the slave driver or application as
+  to how much data was returned to the I2C master.  If the controller
+  does not provide this level of support then this value is set to zero.
+
+  @param[in] This           Address of an EFI_I2C_SLAVE_PROTOCOL
+                            structure
+  @param[in] SlaveAddress   Slave address for the I2C controller
+  @param[in] Context        Address of a context structure for use when
+                            calling ReceiveData or ReceiveStop
+  @param[in] ReceiveData    Called by the I2C port driver as data bytes
+                            are received from the master.  Response status
+                            indicates if the byte is ACKed or NACKed. When
+                            data is passed back a byte at a time, the port
+                            driver must hold the clock until this callback
+                            returns.
+  @param[in] ReceiveStart   Called when the I2C controller receives a start bit.
+  @param[in] ReceiveStop    Called after all of the data bytes are
+                            received.
+
+  @retval EFI_SUCCESS       Slave operation is enabled on the controller.
+  @retval EFI_UNSUPPORTED   The controller does not support this frequency.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_I2C_SLAVE_ENABLE) (
+  IN CONST EFI_I2C_SLAVE_PROTOCOL *This,
+  IN UINT32 SlaveAddress,
+  IN VOID *Context,
+  IN EFI_I2C_SLAVE_RECEIVE_DATA ReceiveData,
+  IN EFI_I2C_SLAVE_RECEIVE_START ReceiveStart,
+  IN EFI_I2C_SLAVE_RECEIVE_STOP ReceiveStop
+  );
+
+/**
+  Send data to the I2C master.
+
+  Port drivers may implement this as a blocking or non-blocking call.
+  The data in the write buffer must remain valid until ReceiveStop or
+  ReceiveStart is called indicating that the I2C master has terminated
+  the transfer.
+
+  @param[in] This         Address of an EFI_I2C_SLAVE_PROTOCOL
+                          structure
+  @param[in] WriteBytes   Number of bytes to write
+  @param[in] WriteBuffer  Buffer containing the data to send
+
+  @retval EFI_SUCCESS           Data waiting for master access.
+  @retval EFI_INVALID_PARAMETER WriteBuffer is NULL or WriteBytes
+                                is zero.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_I2C_SLAVE_SEND) (
+  IN CONST EFI_I2C_SLAVE_PROTOCOL *This,
+  IN UINTN WriteBytes,
+  IN CONST UINT8 *WriteBuffer
+  );
+
+///
+/// I2C slave protocol
+///
+/// The port driver publishes this protocol when slave mode is
+/// supported by the controller.
+///
+struct _EFI_I2C_SLAVE_PROTOCOL {
+  ///
+  /// Enable or disable I2C slave operation
+  ///
+  EFI_I2C_SLAVE_ENABLE SlaveEnable;
+
+  ///
+  /// Send data to the I2C master
+  ///
+  EFI_I2C_SLAVE_SEND SendData;
+};
+
+///
+/// GUID for the EFI_I2C_SLAVE_PROTOCOL
+///
+extern EFI_GUID gEfiI2cSlaveProtocolGuid;
+
+#endif  //  __I2C_SLAVE_H__
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpc83627Policy.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpc83627Policy.h
new file mode 100644
index 0000000000..62d026f133
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpc83627Policy.h
@@ -0,0 +1,92 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  LpcWpc83667Policy.h
+
+Abstract:
+
+  Protocol used for WPC83627 Policy definition.
+-------------------------------------------------------------------------------
+   Rev   Date<MM/DD/YYYY>    Name    Description
+  -------------------------------------------------------------------------------
+  R01   < 4/22/2011>         LB     Update driver for Sio83627UGH support.
+  -------------------------------------------------------------------------------
+**/
+
+#ifndef _WPC83627_POLICY_PROTOCOL_H_
+#define _WPC83627_POLICY_PROTOCOL_H_
+
+EFI_FORWARD_DECLARATION (EFI_WPC83627_POLICY_PROTOCOL);
+
+#define EFI_WPC83627_POLICY_PROTOCOL_GUID \
+  { \
+    0xd3ecc567, 0x9fd5, 0x44c1, 0x86, 0xcf, 0x5d, 0xa7, 0xa2, 0x4f, 0x4b, 0x5d \
+  }
+
+#define EFI_WPC83627_COM1_ENABLE          0x01
+#define EFI_WPC83627_COM2_ENABLE          0x01
+
+#define EFI_WPC83627_COM3_ENABLE          0x01
+#define EFI_WPC83627_COM4_ENABLE          0x01
+
+#define EFI_WPC83627_LPT1_ENABLE          0x01
+#define EFI_WPC83627_LPT1_ENABLE          0x01
+#define EFI_WPC83627_FDD_ENABLE           0x01
+#define EFI_WPC83627_FDD_WRITE_ENABLE     0x01
+#define EFI_WPC83627_PS2_KBC_ENABLE       0x01
+#define EFI_WPC83627_ECIR_ENABLE	  0x01
+
+#define EFI_WPC83627_COM1_DISABLE         0x00
+#define EFI_WPC83627_COM2_DISABLE         0x00
+
+#define EFI_WPC83627_COM3_DISABLE         0x00
+#define EFI_WPC83627_COM4_DISABLE         0x00
+
+#define EFI_WPC83627_LPT1_DISABLE         0x00
+#define EFI_WPC83627_FDD_DISABLE          0x00
+#define EFI_WPC83627_FDD_WRITE_PROTECT    0x00
+#define EFI_WPC83627_PS2_KBC_DISABLE      0x00
+#define EFI_WPC83627_ECIR_DISABLE         0x00
+#define EFI_WPC83627_RESERVED_DEFAULT     0x00
+
+typedef struct {
+  UINT16  Com1               :1;             // 0 = Disable, 1 = Enable
+  UINT16  Lpt1               :1;             // 0 = Disable, 1 = Enable
+  UINT16  Floppy             :1;             // 0 = Disable, 1 = Enable
+  UINT16  FloppyWriteProtect :1;             // 0 = Write Protect, 1 = Write Enable
+  UINT16  Port80             :1;             // 0 = Disable, 1 = Enable
+  UINT16  CIR                :1;             // CIR enable or disable
+  UINT16  Ps2Keyboard        :1;             // 0 = Disable, 1 = Enable
+  UINT16  Ps2Mouse           :1;             // 0 = Disable, 1 = Enable
+  UINT16  Com2               :1;             // 0 = Disable, 1 = Enable
+
+  UINT16  Com3               :1;             // 0 = Disable, 1 = Enable
+  UINT16  Com4               :1;             // 0 = Disable, 1 = Enable
+
+  UINT16  Dac                :1;             // 0 = Disable, 1 = Enable
+  UINT16  Rsvd               :6;
+} EFI_WPC83627_DEVICE_ENABLES;
+
+typedef enum {
+  LptModeOutput,
+  LptModeBiDirectional,
+  LptModeEpp,
+  LptModeEcp
+} EFI_LPT_MODE;
+
+typedef struct _EFI_WPC83627_POLICY_PROTOCOL {
+  EFI_WPC83627_DEVICE_ENABLES DeviceEnables;
+  EFI_LPT_MODE              LptMode;
+} EFI_WPC83627_POLICY_PROTOCOL;
+
+extern EFI_GUID gEfiLpcWpc83627PolicyProtocolGuid;
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpce791Policy.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpce791Policy.h
new file mode 100644
index 0000000000..1b2459e54a
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpce791Policy.h
@@ -0,0 +1,55 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  LpcWpce791Policy.h
+
+Abstract:
+
+  Protocol used for WPCE791 Policy definition.
+
+**/
+
+#ifndef _WPCE791_POLICY_PROTOCOL_H_
+#define _WPCE791_POLICY_PROTOCOL_H_
+
+
+#define EFI_WPCE791_POLICY_PROTOCOL_GUID \
+  { \
+    0xab2bee2f, 0xc1a6, 0x4399, 0x85, 0x3d, 0xc0, 0x7c, 0x77, 0x4f, 0xfd, 0xd \
+  }
+
+#define EFI_WPCE791_PS2_KEYBOARD_ENABLE       0x01
+#define EFI_WPCE791_PS2_KEYBOARD_DISABLE      0x00
+
+#define EFI_WPCE791_PS2_MOUSE_ENABLE       0x01
+#define EFI_WPCE791_PS2_MOUSE_DISABLE      0x00
+
+typedef struct {
+  UINT16  Com1               :1;             // 0 = Disable, 1 = Enable
+  UINT16  Lpt1               :1;             // 0 = Disable, 1 = Enable
+  UINT16  Floppy             :1;             // 0 = Disable, 1 = Enable
+  UINT16  FloppyWriteProtect :1;             // 0 = Write Protect, 1 = Write Enable
+  UINT16  Port80             :1;             // 0 = Disable, 1 = Enable
+  UINT16  CIR                :1;             // CIR enable or disable
+  UINT16  Ps2Keyboard        :1;             // 0 = Disable, 1 = Enable
+  UINT16  Ps2Mouse           :1;             // 0 = Disable, 1 = Enable
+  UINT16  Com2               :1;             // 0 = Disable, 1 = Enable
+  UINT16  Dac                :1;             // 0 = Disable, 1 = Enable
+  UINT16  Rsvd               :6;
+} EFI_WPCE791_DEVICE_ENABLES;
+
+typedef struct _EFI_WPCE791_POLICY_PROTOCOL {
+  EFI_WPCE791_DEVICE_ENABLES DeviceEnables;
+} EFI_WPCE791_POLICY_PROTOCOL;
+
+extern EFI_GUID gEfiLpcWpce791PolicyProtocolGuid;
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/MmioDevice.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/MmioDevice.h
new file mode 100644
index 0000000000..3c0eb5201a
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/MmioDevice.h
@@ -0,0 +1,84 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+**/
+
+#ifndef __MMIO_DEVICE_H__
+#define __MMIO_DEVICE_H__
+
+//
+// Protocol to define for the MMIO device
+//
+typedef struct {
+  //
+  // Address of a GUID
+  //
+  EFI_GUID *Guid;
+
+  //
+  // Context for the protocol
+  //
+  VOID *Context;
+} EFI_MMIO_DEVICE_PROTOCOL_ITEM;
+
+
+typedef struct _EFI_MMIO_DEVICE_PROTOCOL  EFI_MMIO_DEVICE_PROTOCOL;
+
+//
+//  The MMIO device protocol defines a memory mapped I/O device
+//  for use by the system.
+//
+struct _EFI_MMIO_DEVICE_PROTOCOL {
+  //
+  // Pointer to an ACPI_EXTENDED_HID_DEVICE_PATH structure
+  // containing HID/HidStr and CID/CidStr values.
+  //
+  // See the note below associated with the UnitIdentification
+  // field.
+  //
+  CONST ACPI_EXTENDED_HID_DEVICE_PATH *AcpiPath;
+
+  //
+  // Allow the use of a shared template for the AcpiPath.
+  //
+  // If this value is non-zero UID value then the AcpiPath must
+  // be a template which contains only the HID/HidStr and CID/CidStr
+  // values.  The UID/UidStr values in the AcpiPath must be zero!
+  //
+  // If this value is zero then the AcpiPath is not shared and
+  // must contain either a non-zero UID value or a UidStr value.
+  //
+  UINT32 UnitIdentification;
+
+  //
+  // Hardware revision - ACPI _HRV value
+  //
+  UINT32 HardwareRevision;
+
+  //
+  // Pointer to a data structure containing the controller
+  // resources and configuration.  At a minimum this points
+  // to an EFI_PHYSICAL_ADDRESS for the base address of the
+  // MMIO device.
+  //
+  CONST VOID *DriverResources;
+
+  //
+  // Number of protocols in the array
+  //
+  UINTN ProtocolCount;
+
+  //
+  // List of protocols to define
+  //
+  CONST EFI_MMIO_DEVICE_PROTOCOL_ITEM *ProtocolArray;
+};
+
+extern EFI_GUID gEfiMmioDeviceProtocolGuid;
+
+#endif  //  __MMIO_DEVICE_H__
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Observable.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Observable.h
new file mode 100644
index 0000000000..bc5571e6d5
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Observable.h
@@ -0,0 +1,186 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  Observable.h
+
+Abstract:
+
+  Interface and GUID definitions for Observable protocol.
+
+**/
+
+#ifndef _OBSERVABLE_PROTOCOL_H_
+#define _OBSERVABLE_PROTOCOL_H_
+
+//
+// GUID Definitions
+//
+#define OBSERVABLE_PROTOCOL_GUID \
+  { \
+    0xe227c522, 0xd5fe, 0x4a53, 0x87, 0xb1, 0x0f, 0xbe, 0x57, 0x0f, 0x98, 0xe9 \
+  }
+
+extern EFI_GUID gObservableProtocolGuid;
+
+typedef struct _OBS_OBSERVABLE_PROTOCOL OBS_OBSERVABLE_PROTOCOL;
+
+//
+// Interface Definitions
+//
+
+/**
+  Remove all observables.
+
+  Remove all observable guids and all interfaces subscribed to them.
+
+  @param   VOID          No Parameters.
+
+  @return  EFI_SUCCESS   Successfully removed all observables and subscribed interfaces.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *OBS_REMOVE_ALL_OBSERVABLES) (
+  VOID
+  );
+
+/**
+  Interface for notification functions.
+
+  Functions that are to be used as callbacks must inherit this interface in order to be used properly.
+
+  @param   VOID*   Data  Parameter context to be passed to the notification function.
+
+  @return  EFI_STATUS    Varies depending on implementation.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *OBS_CALLBACK) (
+  IN  OUT VOID*   Data
+  );
+
+/**
+  Subscribe an interface with an observable guid.
+
+  Use this to register a callback function with a guid. The function provided by CallbackInterface will be executed
+  whenever the appropriate observable instance specified by ReferenceGuid calls Publish.
+
+  @param   EFI_GUID                ReferenceGuid       The observable guid that the callback interface will subscribe to.
+           OBS_NOTIFY_INTERFACE    CallbackInterface   A pointer to the function that is subscribing to the observable.
+
+  @return  EFI_SUCCESS           Successfully subscribed the interface to the observable guid.
+           EFI_NOT_FOUND         No match could be found between the provided guid and existing observables.
+           EFI_OUT_OF_RESOURCES  Could not subscribe to this observer due to resource limitations.
+           EFI_INVALID_PARAMETER Interface is already subscribed to this observer.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *OBS_SUBSCRIBE) (
+  IN      EFI_GUID        ReferenceGuid,
+  IN      OBS_CALLBACK    CallbackInterface
+  );
+
+/**
+  Unsubscribe an interface with an observable guid.
+
+  Use this to remove an interface from the callback list associated with an observable guid.
+
+  @param   EFI_GUID                ReferenceGuid   The observable guid to unsubscribe the interface from.
+           OBS_NOTIFY_INTERFACE    NotifyCallback  A pointer to the interface that is being unsubscribed.
+
+  @return  EFI_SUCCESS           Successfully unsubscribed the interface from the observable guid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *OBS_UNSUBSCRIBE) (
+  IN      EFI_GUID        ReferenceGuid,
+  IN      OBS_CALLBACK    CallbackInterface
+  );
+
+/**
+  Notify observing functions.
+
+  Use this to notify all functions who are subscribed to the guid specified by ReferenceGuid.
+
+  @param   EFI_GUID          ReferenceGuid   The observable guid that contains the the list of interfaces to be notified.
+           VOID*             Data            Parameter context to be passed to the notification function.
+
+  @return  EFI_SUCCESS       Successfully notified all observers listening to this guid.
+           EFI_NOT_FOUND     No match could be found between the provided guid and existing observables.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *OBS_PUBLISH) (
+  IN      EFI_GUID        ReferenceGuid,
+  IN  OUT VOID*           Data
+  );
+
+/**
+  Creates a new observable.
+
+  Create a new observable that can be observed with the use of Subscribe function.
+
+  @param   EFI_GUID              ReferenceGuid   The observable guid to add.
+
+  @return  EFI_SUCCESS           Successfully added observable.
+           EFI_INVALID_PARAMETER Observable already exists.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *OBS_ADD_OBSERVABLE) (
+  IN      EFI_GUID        ReferenceGuid
+  );
+
+/**
+  Remove an observable.
+
+  Remove an observable so that it can no longer be subscribed to. In addition, unsubscribe any functions
+  that are subscribed to this guid.
+
+  @param   EFI_GUID              ReferenceGuid   The observable guid to remove.
+
+  @return  EFI_SUCCESS           Successfully removed observable.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *OBS_REMOVE_OBSERVABLE) (
+  IN      EFI_GUID        ReferenceGuid
+  );
+
+//
+// Protocol Definitions
+//
+typedef struct _OBS_LEAF {
+  OBS_CALLBACK      Observer;
+  struct _OBS_LEAF* Next;
+} OBS_LEAF;
+
+typedef struct _OBS_TREE {
+  EFI_GUID              ObservableGuid;
+  OBS_LEAF*             Leaf;
+  struct _OBS_TREE*     Next;
+} OBS_TREE;
+
+struct _OBS_OBSERVABLE_PROTOCOL {
+  OBS_ADD_OBSERVABLE          AddObservable;
+  OBS_REMOVE_OBSERVABLE       RemoveObservable;
+  OBS_SUBSCRIBE               Subscribe;
+  OBS_UNSUBSCRIBE             Unsubscribe;
+  OBS_PUBLISH                 Publish;
+  OBS_REMOVE_ALL_OBSERVABLES  RemoveAllObservables;
+} ;
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformGopPolicy.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformGopPolicy.h
new file mode 100644
index 0000000000..ef2ad3d558
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformGopPolicy.h
@@ -0,0 +1,68 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+                                                                                   

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

+
+--*/
+
+/** @file
+**/
+
+#ifndef _PLATFORM_GOP_POLICY_PROTOCOL_H_
+#define _PLATFORM_GOP_POLICY_PROTOCOL_H_
+
+#define EFI_PLATFORM_GOP_POLICY_PROTOCOL_GUID \
+  { 0xec2e931b, 0x3281, 0x48a5, 0x81, 0x7, 0xdf, 0x8a, 0x8b, 0xed, 0x3c, 0x5d }
+
+#define EFI_BMP_IMAGE_GUID \
+  { 0x878AC2CC, 0x5343, 0x46F2, 0xB5, 0x63, 0x51, 0xF8, 0x9D, 0xAF, 0x56, 0xBA }
+
+#define PLATFORM_GOP_POLICY_PROTOCOL_REVISION_01 0x01
+#define PLATFORM_GOP_POLICY_PROTOCOL_REVISION_02 x0222
+
+#pragma pack(1)
+
+typedef enum {
+  LidClosed,
+  LidOpen,
+  LidStatusMax
+} LID_STATUS;
+
+typedef enum {
+  Docked,
+  UnDocked,
+  DockStatusMax
+} DOCK_STATUS;
+
+typedef
+EFI_STATUS
+(EFIAPI *GET_PLATFORM_LID_STATUS) (
+   OUT LID_STATUS *CurrentLidStatus
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *GET_VBT_DATA) (
+   OUT EFI_PHYSICAL_ADDRESS *VbtAddress,
+   OUT UINT32 *VbtSize
+);
+
+#pragma pack()
+
+typedef struct _PLATFORM_GOP_POLICY_PROTOCOL {
+  UINT32                             Revision;
+  GET_PLATFORM_LID_STATUS            GetPlatformLidStatus;
+  GET_VBT_DATA                       GetVbtData;
+} PLATFORM_GOP_POLICY_PROTOCOL;
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID  gPlatformGOPPolicyGuid;
+
+extern EFI_GUID  gBmpImageGuid;
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformIdeInit.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformIdeInit.h
new file mode 100644
index 0000000000..a8b6900d16
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformIdeInit.h
@@ -0,0 +1,43 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+    PlatformIdeInit.h
+
+Abstract:
+
+    EFI Platform Ide Init Protocol
+
+Revision History
+
+**/
+
+#ifndef _EFI_PLATFORM_IDE_INIT_H_
+#define _EFI_PLATFORM_IDE_INIT_H_
+
+//
+// Global ID for the IDE Platform Protocol
+//
+#define EFI_PLATFORM_IDE_INIT_PROTOCOL_GUID \
+  { 0x377c66a3, 0x8fe7, 0x4ee8, 0x85, 0xb8, 0xf1, 0xa2, 0x82, 0x56, 0x9e, 0x3b };
+
+EFI_FORWARD_DECLARATION (EFI_PLATFORM_IDE_INIT_PROTOCOL);
+
+
+//
+// Interface structure for the Platform IDE Init Protocol
+//
+typedef struct _EFI_PLATFORM_IDE_INIT_PROTOCOL {
+  BOOLEAN                               SmartMode;
+} EFI_PLATFORM_IDE_INIT_PROTOCOL;
+
+extern EFI_GUID gEfiPlatformIdeInitProtocolGuid;
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SetupMode.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SetupMode.h
new file mode 100644
index 0000000000..6892106a36
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SetupMode.h
@@ -0,0 +1,79 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+    SetupMode.h
+
+Abstract:
+
+    EFI Setup Mode
+
+Revision History
+
+**/
+
+#ifndef _EFI_SETUP_MODE_H_
+#define _EFI_SETUP_MODE_H_
+
+//
+// Global ID for the Setup Mode
+//
+#define EFI_PLATFORM_BOOT_MODE_GUID \
+  { 0xce845704, 0x1683, 0x4d38, 0xa4, 0xf9, 0x7d, 0xb, 0x50, 0x77, 0x57, 0x93 }
+
+#define EFI_NORMAL_SETUP_GUID \
+  { 0xec87d643, 0xeba4, 0x4bb5, 0xa1, 0xe5, 0x3f, 0x3e, 0x36, 0xb2, 0xd, 0xa9 }
+
+#define EFI_NORMAL_SETUP_RESET_NAME L"Reset"
+
+enum {
+  //
+  // This means: "whatever reset defaults in setup does"
+  //
+  SetupDataResetNormal        = 0,
+
+  //
+  // This means: "the defaults built into the BIOS"
+  //
+  SetupDataResetStandard      = 1,
+
+  //
+  // This means: "the manufacturing mode defaults"
+  //
+  SetupDataResetManufacturing = 2,
+
+  //
+  // This means: "the oem defaults"
+  //
+  SetupDataResetOem           = 3,
+};
+
+//
+// PlatformBootMode types
+//
+#define PLATFORM_NORMAL_MODE          0x01
+#define PLATFORM_SAFE_MODE            0x02
+#define PLATFORM_RECOVERY_MODE        0x04
+#define PLATFORM_MANUFACTURING_MODE   0x08
+#define PLATFORM_BACK_TO_BIOS_MODE    0x10
+
+extern EFI_GUID gEfiPlatformBootModeGuid;
+extern EFI_GUID gEfiNormalSetupGuid;
+extern CHAR16   gEfiNormalSetupName[];
+extern CHAR16   gEfiInSetupName[];
+extern CHAR16   gEfiSystemPasswordName[];
+
+typedef struct {
+  EFI_GUID    SetupGuid;
+  CHAR16      SetupName[0x20];          // Maximum "Setup" Name
+  UINT32      PlatformBootMode;
+} EFI_PLATFORM_SETUP_ID;
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SmbiosSlotPopulation.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SmbiosSlotPopulation.h
new file mode 100644
index 0000000000..ac051d1759
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SmbiosSlotPopulation.h
@@ -0,0 +1,47 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+    SmbiosSlotPopulation.h
+
+Abstract:
+
+    EFI SMBIOS slot structure control code.
+
+GUID:
+    {EF7BF7D6-F8FF-4a76-8247-C0D0D1CC49C0}
+    0xef7bf7d6, 0xf8ff, 0x4a76, 0x82, 0x47, 0xc0, 0xd0, 0xd1, 0xcc, 0x49, 0xc0
+
+Revision History
+
+**/
+
+#ifndef _EFI_SMBIOS_SLOT_POPULATION_H_
+#define _EFI_SMBIOS_SLOT_POPULATION_H_
+
+//
+// Slot Population Protocol GUID
+//
+#define EFI_SMBIOS_SLOT_POPULATION_GUID \
+  { 0xef7bf7d6, 0xf8ff, 0x4a76, 0x82, 0x47, 0xc0, 0xd0, 0xd1, 0xcc, 0x49, 0xc0 }
+
+typedef struct {
+  UINT16      SmbiosSlotId;   // SMBIOS Slot ID
+  BOOLEAN     InUse;          // Does the slot have a card in it
+  BOOLEAN     Disabled;       // Should the slot information be in SMBIOS
+} EFI_SMBIOS_SLOT_ENTRY;
+
+typedef struct {
+  UINT32                NumberOfEntries;
+  EFI_SMBIOS_SLOT_ENTRY *SlotEntries;
+} EFI_SMBIOS_SLOT_POPULATION_INFO;
+
+extern EFI_GUID gEfiSmbiosSlotPopulationGuid;
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Speaker.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Speaker.h
new file mode 100644
index 0000000000..9bffcad24e
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Speaker.h
@@ -0,0 +1,65 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  Speaker.h
+
+Abstract:
+
+  EFI Speaker Interface Protocol
+
+Revision History
+
+**/
+
+#ifndef _EFI_SPEAKER_H
+#define _EFI_SPEAKER_H
+
+//
+// Global Id for Speaker Interface
+//
+#define EFI_SPEAKER_INTERFACE_PROTOCOL_GUID \
+  { \
+    0x400b4476, 0x3081, 0x11d6, 0x87, 0xed, 0x00, 0x06, 0x29, 0x45, 0xc3, 0xb9 \
+  }
+
+typedef struct _EFI_SPEAKER_IF_PROTOCOL  EFI_SPEAKER_IF_PROTOCOL;
+
+//
+// Beep Code
+//
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GENERATE_BEEP) (
+  IN EFI_SPEAKER_IF_PROTOCOL                * This,
+  IN     UINTN                              NumberOfBeep,
+  IN     UINTN                              BeepDuration,
+  IN     UINTN                              TimeInterval
+  );
+
+//
+// Set Frequency
+//
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SPEAKER_SET_FREQUENCY) (
+  IN EFI_SPEAKER_IF_PROTOCOL               * This,
+  IN     UINT16                            Frequency
+  );
+
+//
+// Protocol definition
+//
+struct _EFI_SPEAKER_IF_PROTOCOL {
+  EFI_SPEAKER_SET_FREQUENCY SetSpeakerToneFrequency;
+  EFI_GENERATE_BEEP         GenerateBeep;
+} ;
+
+extern EFI_GUID gEfiSpeakerInterfaceProtocolGuid;
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TcoReset.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TcoReset.h
new file mode 100644
index 0000000000..bda47c359d
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TcoReset.h
@@ -0,0 +1,67 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  TcoReset.h
+
+Abstract:
+
+  Protocol to communicate with ICH TCO.
+
+GUID Info:
+ {A6A79162-E325-4c30-BCC3-59373064EFB3}
+ 0xa6a79162, 0xe325, 0x4c30, 0xbc, 0xc3, 0x59, 0x37, 0x30, 0x64, 0xef, 0xb3);
+
+
+--*/
+
+#ifndef _TCO_RESET_H_
+#define _TCO_RESET_H_
+
+
+#define EFI_TCO_RESET_PROTOCOL_GUID  \
+  {0xa6a79162, 0xe325, 0x4c30, 0xbc, 0xc3, 0x59, 0x37, 0x30, 0x64, 0xef, 0xb3}
+
+typedef struct _EFI_TCO_RESET_PROTOCOL EFI_TCO_RESET_PROTOCOL;
+
+/**
+  Enables the TCO timer to reset the system in case of a system hang.  This is
+  used when writing the clock registers.
+
+  @param[in] RcrbGcsSaveValue  This is the value of the RCRB GCS register before it is
+                               changed by this procedure.  This will be used to restore
+                               the settings of this register in PpiDisableTcoReset.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCO_RESET_PROTOCOL_ENABLE_TCO_RESET) (
+  IN      UINT32            *RcrbGcsSaveValue
+  );
+
+/**
+  Disables the TCO timer.  This is used after writing the clock registers.
+
+  @param[in] RcrbGcsRestoreValue  Value saved in PpiEnableTcoReset so that it can
+                                  restored.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCO_RESET_PROTOCOL_DISABLE_TCO_RESET) (
+  OUT     UINT32    RcrbGcsRestoreValue
+  );
+
+typedef struct _EFI_TCO_RESET_PROTOCOL {
+  EFI_TCO_RESET_PROTOCOL_ENABLE_TCO_RESET       EnableTcoReset;
+  EFI_TCO_RESET_PROTOCOL_DISABLE_TCO_RESET    	DisableTcoReset;
+} EFI_TCO_RESET_PROTOCOL;
+
+extern EFI_GUID gEfiTcoResetProtocolGuid;
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TpmMp.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TpmMp.h
new file mode 100644
index 0000000000..415e53daf2
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TpmMp.h
@@ -0,0 +1,136 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  Tpm.h
+
+Abstract:
+
+
+--*/
+
+#ifndef __EFI_TPM_MP_DRIVER_PROTOCOL_H__
+#define __EFI_TPM_MP_DRIVER_PROTOCOL_H__
+
+
+#define EFI_TPM_MP_DRIVER_PROTOCOL_GUID \
+  { 0xde161cfe, 0x1e60, 0x42a1, 0x8c, 0xc3, 0xee, 0x7e, 0xf0, 0x73, 0x52, 0x12 }
+
+
+EFI_FORWARD_DECLARATION (EFI_TPM_MP_DRIVER_PROTOCOL);
+
+#define TPM_DRIVER_STATUS         0
+#define TPM_DEVICE_STATUS         1
+
+#define TPM_DRIVER_OK             0
+#define TPM_DRIVER_FAILED         1
+#define TPM_DRIVER_NOT_OPENED     2
+#define TPM_DEVICE_OK             0
+#define TPM_DEVICE_UNRECOVERABLE  1
+#define TPM_DEVICE_RECOVERABLE    2
+#define TPM_DEVICE_NOT_FOUND      3
+
+//
+// Prototypes for the TPM MP Driver Protocol
+//
+
+/**
+  This service Open the TPM interface
+
+  @param[in] This             A pointer to the EFI_TPM_MP_DRIVER_PROTOCOL.
+
+  @retval  EFI_SUCCESS        Operation completed successfully
+  @retval  EFI_DEVICE_ERROR   The command was unsuccessful
+  @retval  EFI_NOT_FOUND      The component was not running
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TPM_MP_INIT) (
+  IN EFI_TPM_MP_DRIVER_PROTOCOL   *This
+  );
+
+/**
+  This service close the TPM interface and deactivate TPM
+
+  @param[in] This            A pointer to the EFI_TPM_MP_DRIVER_PROTOCOL.
+
+  @retval EFI_SUCCESS        Operation completed successfully
+  @retval EFI_DEVICE_ERROR   The command was unsuccessful
+  @retval EFI_NOT_FOUND      The component was not running
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TPM_MP_CLOSE) (
+  IN EFI_TPM_MP_DRIVER_PROTOCOL   *This
+  );
+
+/**
+  This service get the current status infomation of TPM
+
+  @param[in]  This                  A pointer to the EFI_TPM_MP_DRIVER_PROTOCOL.
+  @param[in]  ReqStatusType	        Requested type of status information, driver or device.
+  @param[in]  Status	              Pointer to the returned status.
+
+  @retval  EFI_SUCCESS              Operation completed successfully
+  @retval  EFI_DEVICE_ERROR         The command was unsuccessful
+  @retval  EFI_INVALID_PARAMETER    One or more of the parameters are incorrect
+  @retval  EFI_BUFFER_TOO_SMALL     The receive buffer is too small
+  @retval  EFI_NOT_FOUND            The component was not running
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TPM_MP_GET_STATUS_INFO) (
+  IN EFI_TPM_MP_DRIVER_PROTOCOL   *This,
+  IN UINT32				                ReqStatusType,
+  OUT UINT32				              *Status
+  );
+
+/**
+  This service transmit data to the TPM and get response from TPM
+
+  @param[in] This                  A pointer to the EFI_TPM_MP_DRIVER_PROTOCOL.
+  @param[in] TransmitBuf	         Pointer to a buffer containing TPM transmit data.
+  @param[in] TransmitBufLen	       Sizeof TPM input buffer in bytes.
+  @param[in] ReceiveBuf	           Pointer to a buffer containing TPM receive data.
+  @param[in]  ReceiveBufLen	       On input, size of TPM receive buffer in bytes.
+                                   On output, number of bytes written.
+
+  @retval  EFI_SUCCESS             Operation completed successfully
+  @retval  EFI_DEVICE_ERROR        The command was unsuccessful
+  @retval  EFI_INVALID_PARAMETER   One or more of the parameters are incorrect
+  @retval  EFI_BUFFER_TOO_SMALL    The receive buffer is too small
+  @retval  EFI_NOT_FOUND           The component was not running
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TPM_MP_TRANSMIT) (
+  IN EFI_TPM_MP_DRIVER_PROTOCOL   *This,
+  IN UINT8				  	            *TransmitBuffer,
+  IN UINT32			  	              TransmitBufferLen,
+  OUT UINT8				  	            *ReceiveBuf,
+  IN OUT UINT32			  	          *ReceiveBufLen
+  );
+
+
+
+typedef struct _EFI_TPM_MP_DRIVER_PROTOCOL {
+  EFI_TPM_MP_INIT			              Init;
+  EFI_TPM_MP_CLOSE			            Close;
+  EFI_TPM_MP_GET_STATUS_INFO 		    GetStatusInfo;
+  EFI_TPM_MP_TRANSMIT		            Transmit;
+} EFI_TPM_MP_DRIVER_PROTOCOL;
+
+extern EFI_GUID gEfiTpmMpDriverProtocolGuid;
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/UsbPolicy.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/UsbPolicy.h
new file mode 100644
index 0000000000..16e9f9c6bc
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/UsbPolicy.h
@@ -0,0 +1,126 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+  UsbPolicy.h
+
+Abstract:
+
+--*/
+
+#ifndef _USB_POLICY_H_
+#define _USB_POLICY_H_
+
+EFI_FORWARD_DECLARATION (EFI_USB_POLICY_PROTOCOL);
+
+#define USB_POLICY_GUID \
+  {\
+    0xf617b358, 0x12cf, 0x414a, 0xa0, 0x69, 0x60, 0x67, 0x7b, 0xda, 0x13, 0xb4\
+  }
+
+#define TIANO_CODE_BASE           0x00
+#define ICBD_CODE_BASE            0x01
+
+#define ATUO_TYPE                 0x00
+#define USB_FDD_TYPE              0x01
+#define HDD_TYPE                  0x02
+#define ZIP_TYPE                  0x03
+#define CDROM_TYPE                0x04
+#define SIZE_TYPE                 0x05
+
+#define ZIP_FDD                 0x80
+
+#define FDD_EMULATION             0x00
+#define HDD_EMULATION             0x01
+
+#define HIGH_SPEED                0x00
+#define FULL_SPEED                0x01
+#define SUPER_SPEED               0x02
+
+#define LEGACY_KB_EN              0x01
+#define LEGACY_KB_DIS             0x00
+#define LEGACY_MS_EN              0x01
+#define LEGACY_MS_DIS             0x00
+#define LEGACY_USB_EN             0x00
+#define LEGACY_USB_DIS            0x01
+#define LEGACY_FREE_SUPP          0x01
+#define LEGACY_FREE_UN_SUPP       0x00
+#define LEGACY_PERIOD_SUPP        0x01
+#define LEGACY_PERIOD_UN_SUPP     0x00
+
+#define LEGACY_USB_TIME_TUE_ENABLE       0x01
+#define LEGACY_USB_TIME_TUE_DISABLE      0x00
+#define USB_HAVE_HUB_INTERNEL            0x01
+#define USB_NOT_HAVE_HUB_INTERNEL        0x00
+
+#define USB_POLICY_PROTOCOL_REVISION_1 1
+#define USB_POLICY_PROTOCOL_REVISION_2 2
+
+#ifndef __GNUC__
+#pragma warning ( disable : 4306 )
+#pragma warning ( disable : 4054 )
+#endif
+
+#define GET_USB_CFG (UsbCfg);\
+ do{\
+  UINT16                *pSegOfEbda;\
+  UINT32                mToEbda;\
+  pSegOfEbda = (UINT16 *)(UINTN)0x40E;\
+  mToEbda    = (UINT32)(((UINTN)(*pSegOfEbda) << 4) + 0x80);\
+  UsbCfg     = (USB_CFG *)(UINTN)mToEbda;\
+ }while(0);
+
+#pragma    pack(1)
+typedef struct {
+    UINT8   HasUSBKeyboard:1;
+    UINT8   HasUSBMouse:1;
+    UINT8   LegacyFreeSupport:1;
+    UINT8   UsbOperationMode:1;
+    UINT8   LegacyKBEnable:1;
+    UINT8   LegacyMSEnable:1;
+    UINT8   USBPeriodSupport:1;
+    UINT8   Reserved:1;
+} USB_DEVICE_INFOR;
+
+typedef struct {
+    UINT8               Codebase;
+    UINT8               USBHDDForceType;
+    UINT8               Configurated;
+    UINT8               LpcAcpiBase;
+    UINT8               AcpiTimerReg;
+    UINT8               Reserved1[0x01];
+    UINT8               LegacyUsbEnable;
+    USB_DEVICE_INFOR    UsbDeviceInfor;
+    UINT16              UsbEmulationSize;
+    UINT8               Reserved2[0x06];
+} USB_CFG;
+#pragma pack()
+
+typedef struct _EFI_USB_POLICY_PROTOCOL{
+  UINT8   Version;
+  UINT8   UsbMassStorageEmulationType;  // 1: FDD_Type; 2: HDD_Type; other:Auto_Type*
+  UINT8   UsbOperationMode;             // 0: High_Speed; 1: Full_Speed;
+  UINT8   LegacyKBEnable;               // 0: Disabled;   1: Enabled*
+  UINT8   LegacyMSEnable;               // 0: Disabled;   1: Enabled*
+  UINT8   USBPeriodSupport;             // 0; Unsupport;  1: Support
+  UINT8   LegacyUsbEnable;              // 1: Disabled;   0: Enabled*
+  UINT8   LegacyFreeSupport;            // 0: Unsupport;  1: Support
+  UINT8   CodeBase;
+  UINT8   LpcAcpiBase;                  // 40h(default)
+  UINT8   AcpiTimerReg;
+  UINT8   UsbTimeTue;
+  UINT8   InternelHubExist;             // 1: Host have internel hub on board; 0: No internel hub on board
+  UINT8   EnumWaitPortStableStall;      // Value for wait port stable when enum a new dev.
+  UINT16  UsbEmulationSize;             // Mbytes.
+  UINT8   UsbZipEmulationType;
+  UINT8   Reserved[3];                  // Reserved fields for future expansion w/o protocol change
+} EFI_USB_POLICY_PROTOCOL;
+
+extern EFI_GUID gUsbPolicyGuid;
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/VlvPlatformPolicy.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/VlvPlatformPolicy.h
new file mode 100644
index 0000000000..5c0ffa3027
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/VlvPlatformPolicy.h
@@ -0,0 +1,102 @@
+/** 
+  Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+Module Name:
+
+  VlvPlatformPolicy.h
+
+Abstract:
+
+  Interface definition details between MCH and platform drivers during DXE phase.
+
+--*/
+
+#ifndef _VLV_PLATFORM_POLICY_H_
+#define _VLV_PLATFORM_POLICY_H_
+
+//
+// VLV Policy provided by platform for DXE phase {5BAB88BA-E0E2-4674-B6AD-B812F6881CD6}
+//
+#define DXE_VLV_PLATFORM_POLICY_GUID \
+  {0x5bab88ba, 0xe0e2, 0x4674, 0xb6, 0xad, 0xb8, 0x12, 0xf6, 0x88, 0x1c, 0xd6}
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gDxeVlvPlatformPolicyGuid;
+
+//
+// Protocol revision number
+// Any backwards compatible changes to this protocol will result in an update in the revision number
+// Major changes will require publication of a new protocol
+//
+#define DXE_VLV_PLATFORM_POLICY_PROTOCOL_REVISION 0
+
+
+typedef struct {
+  UINT8  PFITStatus;
+  UINT8  IgdTheramlSupport;
+  UINT8  ALSEnabled;
+  UINT8  LidStatus;
+} IGD_PANEL_FEATURES;
+
+typedef struct {
+  UINT8   Reserved00;                     
+  UINT8   Reserved01;                     
+  UINT16  Reserved02;  
+  UINT16  Reserved03; 
+  UINT16  Reserved04; 
+  UINT16  Reserved05;  
+  UINT16  Reserved06;  
+  UINT16  Reserved07; 
+  UINT16  Reserved08; 
+  UINT16  Reserved09;  
+  UINT16  Reserved0A; 
+  UINT16  Reserved0B;
+  UINT16  Reserved0C;
+  UINT16  Reserved0D;
+  UINT8   Reserved0E;
+  UINT8   Reserved0F;
+  UINT32  Reserved10;
+  UINT32  Reserved11;
+  UINT32  Reserved12;
+  UINT32  Reserved13;
+  UINT32  Reserved14;
+  UINT8   Reserved15;
+  UINT8   Reserved16;
+} DPTF_SETTINGS;
+
+//
+// MCH DXE Platform Policiy ==================================================
+//
+
+#define NO_AUDIO   0
+#define HD_AUDIO   1
+#define LPE_AUDIO  2
+
+typedef struct _DXE_VLV_PLATFORM_POLICY_PROTOCOL {
+  UINT8                   Revision;
+  IGD_PANEL_FEATURES      IgdPanelFeatures;
+  DPTF_SETTINGS           Reserved;
+  UINT8                   GraphicReserve00;
+  UINT8                   GraphicsPerfAnalyzers;
+  UINT8                   PwmReserved00;
+  UINT8                   PwmReserved01;  
+  UINT8                   PmSupport;
+  UINT8                   GraphicReserve01;
+  UINT8                   GfxPause;
+  UINT8                   GraphicsFreqReq;
+  UINT8                   GraphicReserve03;
+  UINT8                   GraphicReserve02;
+  UINT8                   GraphicReserve04;
+  UINT8                   PavpMode;
+  UINT8                   GraphicReserve05;
+  UINT8                   UlClockGating;
+  UINT8                   IdleReserve;
+  UINT8                   AudioTypeSupport;
+  UINT8                   GraphicReserve06;
+} DXE_VLV_PLATFORM_POLICY_PROTOCOL;
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/SetupMode.h b/Platform/Intel/Vlv2TbltDevicePkg/Include/SetupMode.h
new file mode 100644
index 0000000000..53abd1d3a6
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/SetupMode.h
@@ -0,0 +1,85 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+    SetupMode.h
+
+Abstract:
+
+    EFI Setup Mode
+
+
+
+--*/
+
+#ifndef _EFI_SETUP_MODE_H_
+#define _EFI_SETUP_MODE_H_
+
+//
+// Global ID for the Setup Mode
+//
+#define EFI_PLATFORM_BOOT_MODE_GUID \
+  { 0xce845704, 0x1683, 0x4d38, 0xa4, 0xf9, 0x7d, 0xb, 0x50, 0x77, 0x57, 0x93 }
+
+#define EFI_NORMAL_SETUP_GUID \
+  { 0xec87d643, 0xeba4, 0x4bb5, 0xa1, 0xe5, 0x3f, 0x3e, 0x36, 0xb2, 0xd, 0xa9 }
+
+#define EFI_NORMAL_SETUP_RESET_NAME L"Reset"
+
+enum {
+  //
+  // This means: "whatever reset defaults in setup does"
+  //
+  SetupDataResetNormal        = 0,
+
+  //
+  // This means: "the defaults built into the BIOS"
+  //
+  SetupDataResetStandard      = 1,
+
+  //
+  // This means: "the manufacturing mode defaults"
+  //
+  SetupDataResetManufacturing = 2,
+
+  //
+  // This means: "the oem defaults"
+  //
+  SetupDataResetOem           = 3,
+};
+
+//
+// PlatformBootMode types
+//
+#define PLATFORM_NORMAL_MODE          0x01
+#define PLATFORM_SAFE_MODE            0x02
+#define PLATFORM_RECOVERY_MODE        0x04
+#define PLATFORM_MANUFACTURING_MODE   0x08
+#define PLATFORM_BACK_TO_BIOS_MODE    0x10
+
+extern EFI_GUID gEfiPlatformBootModeGuid;
+
+#define   NORMAL_SETUP_NAME                L"Setup"
+#define   IN_SETUP_NAME                    L"InSetup"
+#define   SYSTEM_PASSWORD_NAME             L"SystemPassword"
+#define   BOOT_TIME_NAME                   L"BootTime"
+
+extern EFI_GUID gEfiNormalSetupGuid;
+extern CHAR16   gEfiNormalSetupName[];
+extern CHAR16   gEfiInSetupName[];
+extern CHAR16   gEfiSystemPasswordName[];
+
+typedef struct {
+  EFI_GUID    SetupGuid;
+  CHAR16      SetupName[0x20];          // Maximum "Setup" Name
+  UINT32      PlatformBootMode;
+} EFI_PLATFORM_SETUP_ID;
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/IntelGopDepex/IntelGopDriver.depex b/Platform/Intel/Vlv2TbltDevicePkg/IntelGopDepex/IntelGopDriver.depex
new file mode 100644
index 0000000000..011f929f0a
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/IntelGopDepex/IntelGopDriver.depex
@@ -0,0 +1 @@
+\x02^[“.ì2¥H\aߊ‹í<]\b
\ No newline at end of file
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.c
new file mode 100644
index 0000000000..3f0e20c7a8
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.c
@@ -0,0 +1,337 @@
+/*++
+
+Copyright (c) 2011  - 2014, Intel Corporation. All rights reserved
+                                                                                   

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

+
+Module Name:
+
+  BiosIdLib.c
+
+Abstract:
+
+  Boot service DXE BIOS ID library implementation.
+
+  These functions in this file can be called during DXE and cannot be called during runtime
+  or in SMM which should use a RT or SMM library.
+
+--*/
+
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+
+#include <Library/BiosIdLib.h>
+#include <Guid/BiosId.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/LoadedImage.h>
+
+
+EFI_STATUS
+GetImageFromFv (
+  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,
+  IN  EFI_GUID           *NameGuid,
+  IN  EFI_SECTION_TYPE   SectionType,
+  OUT VOID               **Buffer,
+  OUT UINTN              *Size
+  )
+{
+  EFI_STATUS                Status;
+  EFI_FV_FILETYPE           FileType;
+  EFI_FV_FILE_ATTRIBUTES    Attributes;
+  UINT32                    AuthenticationStatus;
+
+  //
+  // Read desired section content in NameGuid file
+  //
+  *Buffer     = NULL;
+  *Size       = 0;
+  Status      = Fv->ReadSection (
+                      Fv,
+                      NameGuid,
+                      SectionType,
+                      0,
+                      Buffer,
+                      Size,
+                      &AuthenticationStatus
+                      );
+
+  if (EFI_ERROR (Status) && (SectionType == EFI_SECTION_TE)) {
+    //
+    // Try reading PE32 section, since the TE section does not exist
+    //
+    *Buffer = NULL;
+    *Size   = 0;
+    Status  = Fv->ReadSection (
+                    Fv,
+                    NameGuid,
+                    EFI_SECTION_PE32,
+                    0,
+                    Buffer,
+                    Size,
+                    &AuthenticationStatus
+                    );
+  }
+
+  if (EFI_ERROR (Status) &&
+      ((SectionType == EFI_SECTION_TE) || (SectionType == EFI_SECTION_PE32))) {
+    //
+    // Try reading raw file, since the desired section does not exist
+    //
+    *Buffer = NULL;
+    *Size   = 0;
+    Status  = Fv->ReadFile (
+                    Fv,
+                    NameGuid,
+                    Buffer,
+                    Size,
+                    &FileType,
+                    &Attributes,
+                    &AuthenticationStatus
+                    );
+  }
+
+  return Status;
+}
+
+
+EFI_STATUS
+GetImageEx (
+  IN  EFI_HANDLE         ImageHandle,
+  IN  EFI_GUID           *NameGuid,
+  IN  EFI_SECTION_TYPE   SectionType,
+  OUT VOID               **Buffer,
+  OUT UINTN              *Size,
+  BOOLEAN                WithinImageFv
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_HANDLE                    *HandleBuffer;
+  UINTN                         HandleCount;
+  UINTN                         Index;
+  EFI_LOADED_IMAGE_PROTOCOL     *LoadedImage;
+
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *ImageFv;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+
+
+  if (ImageHandle == NULL && WithinImageFv) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status  = EFI_NOT_FOUND;
+  ImageFv = NULL;
+  if (ImageHandle != NULL) {
+    Status = gBS->HandleProtocol (
+                    ImageHandle,
+                    &gEfiLoadedImageProtocolGuid,
+                    (VOID **) &LoadedImage
+                    );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    Status = gBS->HandleProtocol (
+                    LoadedImage->DeviceHandle,
+                    &gEfiFirmwareVolume2ProtocolGuid,
+                    (VOID **) &ImageFv
+                    );
+    if (!EFI_ERROR (Status)) {
+      Status = GetImageFromFv (ImageFv, NameGuid, SectionType, Buffer, Size);
+    }
+  }
+
+  if (Status == EFI_SUCCESS || WithinImageFv) {
+    return Status;
+  }
+
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiFirmwareVolume2ProtocolGuid,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Find desired image in all Fvs
+  //
+  for (Index = 0; Index < HandleCount; ++Index) {
+    Status = gBS->HandleProtocol (
+                    HandleBuffer[Index],
+                    &gEfiFirmwareVolume2ProtocolGuid,
+                    (VOID**)&Fv
+                    );
+
+    if (EFI_ERROR (Status)) {
+      gBS->FreePool(HandleBuffer);
+      return Status;
+    }
+
+    if (ImageFv != NULL && Fv == ImageFv) {
+      continue;
+    }
+
+    Status = GetImageFromFv (Fv, NameGuid, SectionType, Buffer, Size);
+
+    if (!EFI_ERROR (Status)) {
+      break;
+    }
+  }
+  gBS->FreePool(HandleBuffer);
+
+  //
+  // Not found image
+  //
+  if (Index == HandleCount) {
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function returns BIOS ID by searching HOB or FV.
+
+  @param BiosIdImage             The BIOS ID got from HOB or FV.
+
+  @retval EFI_SUCCESS            All parameters were valid and BIOS ID has been got.
+  @retval EFI_NOT_FOUND          BiosId image is not found, and no parameter will be modified.
+  @retval EFI_INVALID_PARAMETER  The parameter is NULL.
+
+**/
+EFI_STATUS
+GetBiosId (
+  OUT BIOS_ID_IMAGE     *BiosIdImage
+  )
+
+{
+  EFI_STATUS    Status;
+  VOID          *Address = NULL;
+  UINTN         Size = 0;
+
+    DEBUG ((EFI_D_INFO, "Get BIOS ID from FV\n"));
+
+    Status = GetImageEx (
+               NULL,
+               &gEfiBiosIdGuid,
+               EFI_SECTION_RAW,
+               &Address,
+               &Size,
+               FALSE
+               );
+
+    if (Status == EFI_SUCCESS) {
+      //
+      // BiosId image is present in FV
+      //
+      if (Address != NULL) {
+        Size = sizeof (BIOS_ID_IMAGE);
+        gBS->CopyMem (
+              (void *) BiosIdImage,
+              Address,
+              Size
+              );
+        //
+        // GetImage () allocated buffer for Address, now clear it.
+        //
+        gBS->FreePool (Address);
+
+        DEBUG ((EFI_D_INFO, "Get BIOS ID from FV successfully\n"));
+        DEBUG ((EFI_D_INFO, "BIOS ID: %s\n", (CHAR16 *) (&(BiosIdImage->BiosIdString))));
+
+        return EFI_SUCCESS;
+      }
+    }
+  return EFI_NOT_FOUND;
+}
+
+/**
+  This function returns the Version & Release Date and Time by getting and converting
+  BIOS ID.
+
+  @param BiosVersion  The Bios Version out of the conversion.
+  @param BiosReleaseDate  The Bios Release Date out of the conversion.
+  @param BiosReleaseTime - The Bios Release Time out of the conversion.
+
+  @retval EFI_SUCCESS - BIOS Version & Release Date and Time have been got successfully.
+  @retval EFI_NOT_FOUND - BiosId image is not found, and no parameter will be modified.
+  @retval EFI_INVALID_PARAMETER - All the parameters are NULL.
+
+**/
+EFI_STATUS
+GetBiosVersionDateTime (
+  OUT CHAR16    *BiosVersion, OPTIONAL
+  OUT CHAR16    *BiosReleaseDate, OPTIONAL
+  OUT CHAR16    *BiosReleaseTime OPTIONAL
+  )
+{
+  EFI_STATUS        Status;
+  BIOS_ID_IMAGE     BiosIdImage;
+
+  if ((BiosVersion == NULL) && (BiosReleaseDate == NULL) && (BiosReleaseTime == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = GetBiosId (&BiosIdImage);
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  if (BiosVersion != NULL) {
+    //
+    // Fill the BiosVersion data from the BIOS ID.
+    //
+    StrCpy (BiosVersion, (CHAR16 *) (&(BiosIdImage.BiosIdString)));
+  }
+
+  if (BiosReleaseDate != NULL) {
+    //
+    // Fill the build timestamp date from the BIOS ID in the "MM/DD/YY" format.
+    //
+    BiosReleaseDate[0] = BiosIdImage.BiosIdString.TimeStamp[2];
+    BiosReleaseDate[1] = BiosIdImage.BiosIdString.TimeStamp[3];
+    BiosReleaseDate[2] = (CHAR16) ((UINT8) ('/'));
+
+    BiosReleaseDate[3] = BiosIdImage.BiosIdString.TimeStamp[4];
+    BiosReleaseDate[4] = BiosIdImage.BiosIdString.TimeStamp[5];
+    BiosReleaseDate[5] = (CHAR16) ((UINT8) ('/'));
+
+    //
+    // Add 20 for SMBIOS table
+    // Current Linux kernel will misjudge 09 as year 0, so using 2009 for SMBIOS table
+    //
+    BiosReleaseDate[6] = '2';
+    BiosReleaseDate[7] = '0';
+    BiosReleaseDate[8] = BiosIdImage.BiosIdString.TimeStamp[0];
+    BiosReleaseDate[9] = BiosIdImage.BiosIdString.TimeStamp[1];
+
+    BiosReleaseDate[10] = (CHAR16) ((UINT8) ('\0'));
+  }
+
+  if (BiosReleaseTime != NULL) {
+
+    //
+    // Fill the build timestamp time from the BIOS ID in the "HH:MM" format.
+    //
+
+    BiosReleaseTime[0] = BiosIdImage.BiosIdString.TimeStamp[6];
+    BiosReleaseTime[1] = BiosIdImage.BiosIdString.TimeStamp[7];
+    BiosReleaseTime[2] = (CHAR16) ((UINT8) (':'));
+
+    BiosReleaseTime[3] = BiosIdImage.BiosIdString.TimeStamp[8];
+    BiosReleaseTime[4] = BiosIdImage.BiosIdString.TimeStamp[9];
+
+    BiosReleaseTime[5] = (CHAR16) ((UINT8) ('\0'));
+  }
+
+  return  EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.inf b/Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.inf
new file mode 100644
index 0000000000..3e53680d08
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.inf
@@ -0,0 +1,50 @@
+#/*++
+#
+# Copyright (c)  2010  - 2014, Intel Corporation. All rights reserved
+#                                                                                  

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

+
+#
+#  Module Name:
+#
+#   BiosIdLib.inf
+#
+#  Abstract:
+#
+#    Component description file for BIOS ID library
+#
+#--*/
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BiosIdLib
+  FILE_GUID                      = 98546145-64F1-4d2e-814F-6BF963DB7930
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = BiosIdLib
+  PI_SPECIFICATION_VERSION       = 0x0001000A
+
+[Sources]
+  BiosIdLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+
+[LibraryClasses]
+  HobLib
+
+[Guids]
+  gEfiBiosIdGuid
+
+[Protocols]
+  gEfiLoadedImageProtocolGuid
+  gEfiFirmwareVolume2ProtocolGuid
+
+[Depex]
+  gEfiLoadedImageProtocolGuid AND
+  gEfiFirmwareVolume2ProtocolGuid
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/CpuIA32Lib.inf b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/CpuIA32Lib.inf
new file mode 100644
index 0000000000..c9f0a434ac
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/CpuIA32Lib.inf
@@ -0,0 +1,41 @@
+#
+#
+# Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+#                                                                                  

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

+#
+#
+#   Module Name:
+#
+#     CpuIA32Lib.inf
+#
+#   Abstract:
+#
+#     Component description file for the Cpu IA32 library.
+#
+#--*/
+
+[defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = CpuIA32Lib
+  FILE_GUID                      = 98546178-64F1-4d2e-814F-6BF963DB7930
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = CpuIA32Lib
+  PI_SPECIFICATION_VERSION       = 0x0001000A
+
+[Sources]
+  EfiCpuVersion.c
+
+[Sources.IA32]
+  IA32/CpuIA32.c
+
+[Sources.X64]
+  X64/Cpu.asm
+  X64/Cpu.S
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/EfiCpuVersion.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/EfiCpuVersion.c
new file mode 100644
index 0000000000..935f11e871
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/EfiCpuVersion.c
@@ -0,0 +1,70 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+  EfiCpuVersion.c
+
+Abstract:
+
+  Provide cpu version extract considering extended family & model ID.
+--*/
+
+#include <Library/CpuIA32.h>
+
+/**
+  Extract CPU detail version infomation
+
+  @param  FamilyId    FamilyId, including ExtendedFamilyId
+  @param  Model       Model, including ExtendedModel
+  @param  SteppingId  SteppingId
+  @param  Processor   Processor
+
+**/
+VOID
+EFIAPI
+EfiCpuVersion (
+  IN  OUT UINT16  *FamilyId,    OPTIONAL
+  IN  OUT UINT8   *Model,       OPTIONAL
+  IN  OUT UINT8   *SteppingId,  OPTIONAL
+  IN  OUT UINT8   *Processor    OPTIONAL
+  )
+
+{
+  EFI_CPUID_REGISTER Register;
+  UINT8              TempFamilyId;
+
+  EfiCpuid (EFI_CPUID_VERSION_INFO, &Register);
+
+  if (SteppingId != NULL) {
+    *SteppingId = (UINT8) (Register.RegEax & 0xF);
+  }
+
+  if (Processor != NULL) {
+    *Processor = (UINT8) ((Register.RegEax >> 12) & 0x3);
+  }
+
+  if (Model != NULL || FamilyId != NULL) {
+    TempFamilyId = (UINT8) ((Register.RegEax >> 8) & 0xF);
+
+    if (Model != NULL) {
+      *Model = (UINT8) ((Register.RegEax >> 4) & 0xF);
+      if (TempFamilyId == 0x6 || TempFamilyId == 0xF) {
+        *Model = (UINT8) (*Model  | ((Register.RegEax >> 12) & 0xF0));
+      }
+    }
+
+    if (FamilyId != NULL) {
+      *FamilyId = TempFamilyId;
+      if (TempFamilyId == 0xF) {
+        *FamilyId = (UINT8 ) (*FamilyId + (UINT16) ((Register.RegEax >> 20) & 0xFF));
+      }
+    }
+  }
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.S b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.S
new file mode 100644
index 0000000000..ba1bd448c0
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.S
@@ -0,0 +1,223 @@
+#
+#
+# Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+#                                                                                  

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

+#
+#
+#Module Name:
+#
+#  CpuIA32.c
+#
+#Abstract:
+#
+#--*/
+
+##include "CpuIA32.h"
+#include "EfiBind.h"
+
+#---------------------------------------------------------------------------
+    .586p:
+    #.MODEL flat,C
+    .code:
+
+#---------------------------------------------------------------------------
+
+.globl ASM_PFX(EfiHalt)
+.globl ASM_PFX(EfiWbinvd)
+.globl ASM_PFX(EfiInvd)
+.globl ASM_PFX(EfiCpuid)
+.globl ASM_PFX(EfiReadMsr)
+.globl ASM_PFX(EfiWriteMsr)
+.globl ASM_PFX(EfiReadTsc)
+.globl ASM_PFX(EfiDisableCache)
+.globl ASM_PFX(EfiEnableCache)
+.globl ASM_PFX(EfiGetEflags)
+.globl ASM_PFX(EfiDisableInterrupts)
+.globl ASM_PFX(EfiEnableInterrupts)
+.globl ASM_PFX(EfiCpuidExt)
+
+
+#VOID
+#EfiHalt (
+#  VOID
+#)
+ASM_PFX(EfiHalt):
+    hlt
+    ret
+#EfiHalt ENDP
+
+#VOID
+#EfiWbinvd (
+#  VOID
+#)
+ASM_PFX(EfiWbinvd):
+    wbinvd
+    ret
+#EfiWbinvd ENDP
+
+#VOID
+#EfiInvd (
+# VOID
+#)
+ASM_PFX(EfiInvd):
+    invd
+    ret
+#EfiInvd ENDP
+
+#VOID
+#EfiCpuid (IN UINT32 RegisterInEax,
+#          OUT EFI_CPUID_REGISTER *Reg OPTIONAL)
+ASM_PFX(EfiCpuid):
+    pushl %ebp
+    movl %esp, %ebp
+    pushl %ebx
+    pushl %esi
+    pushl %edi
+    pushal
+
+    movl   8(%ebp), %eax           #RegisterInEax
+    cpuid
+    cmpl   $0, 0xC(%ebp)           # Reg
+    je     L1
+    movl        0xC(%ebp), %edi         # Reg
+
+    movl        %eax, (%edi)        # Reg->RegEax
+    movl        %ebx, 4(%edi)         # Reg->RegEbx
+    movl        %ecx, 8(%edi)         # Reg->RegEcx
+    movl        %edx, 0xC(%edi)         # Reg->RegEdx
+
+L1:
+    popal
+    popl        %edi
+    popl        %esi
+    popl        %ebx
+    popl        %ebp
+
+    ret
+#EfiCpuid ENDP
+
+
+#UINT64
+#EfiReadMsr (
+#  IN UINT32 Index
+#  );
+ASM_PFX(EfiReadMsr):
+    movl   4(%esp), %ecx           # Index
+    rdmsr
+    ret
+#EfiReadMsr ENDP
+
+#VOID
+#EfiWriteMsr (
+#  IN   UINT32  Index,
+#  IN   UINT64  Value
+#  );
+ASM_PFX(EfiWriteMsr):
+    movl   4(%esp), %ecx         # Index
+    movl   8(%esp), %eax         # DWORD PTR Value[0]
+    movl   0xC(%esp), %edx         # DWORD PTR Value[4]
+    wrmsr
+    ret
+#EfiWriteMsr ENDP
+
+#UINT64
+#EfiReadTsc (
+#  VOID
+#  )
+ASM_PFX(EfiReadTsc):
+    rdtsc
+    ret
+#EfiReadTsc ENDP
+
+#VOID
+#EfiDisableCache (
+#  VOID
+#)
+ASM_PFX(EfiDisableCache):
+    movl  %cr0, %eax
+    bswapl %eax
+    andb  $0x60, %al
+    cmpb  $0x60, %al
+    je    L2
+    movl  %cr0, %eax
+    orl   $0x60000000, %eax
+    movl  %eax, %cr0
+    wbinvd
+L2:
+    ret
+#EfiDisableCache ENDP
+
+#VOID
+#EfiEnableCache (
+#  VOID
+#  )
+ASM_PFX(EfiEnableCache):
+    wbinvd
+    movl  %cr0, %eax
+    andl  $0x9fffffff, %eax
+    movl  %eax, %cr0
+    ret
+#EfiEnableCache ENDP
+
+#UINT32
+#EfiGetEflags (
+#  VOID
+#  )
+ASM_PFX(EfiGetEflags):
+    pushfl
+    popl %eax
+    ret
+#EfiGetEflags ENDP
+
+#VOID
+#EfiDisableInterrupts (
+#  VOID
+#  )
+ASM_PFX(EfiDisableInterrupts):
+    cli
+    ret
+#EfiDisableInterrupts ENDP
+
+#VOID
+#EfiEnableInterrupts (
+#  VOID
+#  )
+ASM_PFX(EfiEnableInterrupts):
+    sti
+    ret
+#EfiEnableInterrupts ENDP
+
+#VOID
+#EfiCpuidExt (
+#  IN   UINT32              RegisterInEax,
+#  IN   UINT32              CacheLevel,
+#  OUT  EFI_CPUID_REGISTER  *Regs
+#  )
+ASM_PFX(EfiCpuidExt):
+    push   %ebx
+    push   %edi
+    push   %esi
+    pushal
+
+    movl   0x30(%esp), %eax           # RegisterInEax
+    movl   0x34(%esp), %ecx           # CacheLevel
+    cpuid
+    movl   0x38(%esp), %edi           # DWORD PTR Regs
+
+    movl   %eax, (%edi)                 # Reg->RegEax
+    movl   %ebx, 4(%edi)                # Reg->RegEbx
+    movl   %ecx, 8(%edi)                # Reg->RegEcx
+    movl   %edx, 0xC(%edi)              # Reg->RegEdx
+
+    popal
+    pop    %esi
+    pop    %edi
+    pop    %ebx
+    ret
+#EfiCpuidExt ENDP
+
+
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.asm b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.asm
new file mode 100644
index 0000000000..3fdf16f8ee
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.asm
@@ -0,0 +1,206 @@
+;
+; This file contains an 'Intel Sample Driver' and is
+; licensed for Intel CPUs and chipsets under the terms of your
+; license agreement with Intel or your vendor.  This file may
+; be modified by the user, subject to additional terms of the
+; license agreement
+;
+;
+; Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+;                                                                                  

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

+;
+
+;Module Name:
+;
+;  CpuIA32.c
+;
+;Abstract:
+;
+;--*/
+
+;#include "CpuIA32.h"
+
+;---------------------------------------------------------------------------
+    .586p
+    .model  flat,C
+    .code
+
+;---------------------------------------------------------------------------
+;VOID
+;EfiHalt (
+;  VOID
+;)
+EfiHalt PROC C PUBLIC
+    hlt
+    ret
+EfiHalt ENDP
+
+;VOID
+;EfiWbinvd (
+;  VOID
+;)
+EfiWbinvd PROC C PUBLIC
+    wbinvd
+    ret
+EfiWbinvd ENDP
+
+;VOID
+;EfiInvd (
+; VOID
+;)
+EfiInvd PROC C PUBLIC
+    invd
+    ret
+EfiInvd ENDP
+
+;VOID
+;EfiCpuid (IN UINT32 RegisterInEax,
+;          OUT EFI_CPUID_REGISTER *Reg OPTIONAL)
+EfiCpuid PROC C PUBLIC
+    push ebp
+    mov  ebp, esp
+    push ebx
+    push esi
+    push edi
+    pushad
+
+    mov    eax, dword ptr[ebp + 8] ;egisterInEax
+    cpuid
+    cmp    dword ptr[ebp + 0Ch], 0 ; Reg
+    je     @F
+    mov         edi,dword ptr [ebp+0Ch] ; Reg
+
+    mov         dword ptr [edi],eax ; Reg->RegEax
+    mov         dword ptr [edi+4],ebx ; Reg->RegEbx
+    mov         dword ptr [edi+8],ecx ; Reg->RegEcx
+    mov         dword ptr [edi+0Ch],edx ; Reg->RegEdx
+
+@@:
+    popad
+    pop         edi
+    pop         esi
+    pop         ebx
+    pop         ebp
+
+    ret
+EfiCpuid ENDP
+
+
+;UINT64
+;EfiReadMsr (
+;  IN UINT32 Index
+;  );
+EfiReadMsr PROC C PUBLIC
+    mov    ecx, dword ptr [esp + 4]; Index
+    rdmsr
+    ret
+EfiReadMsr ENDP
+
+;VOID
+;EfiWriteMsr (
+;  IN   UINT32  Index,
+;  IN   UINT64  Value
+;  );
+EfiWriteMsr PROC C PUBLIC
+    mov    ecx, dword ptr [esp+4]; Index
+    mov    eax, dword ptr [esp+8]; DWORD PTR Value[0]
+    mov    edx, dword ptr [esp+0Ch]; DWORD PTR Value[4]
+    wrmsr
+    ret
+EfiWriteMsr  ENDP
+
+;UINT64
+;EfiReadTsc (
+;  VOID
+;  )
+EfiReadTsc PROC C PUBLIC
+    rdtsc
+    ret
+EfiReadTsc  ENDP
+
+;VOID
+;EfiDisableCache (
+;  VOID
+;)
+EfiDisableCache PROC C PUBLIC
+    mov   eax, cr0
+    bswap eax
+    and   al, 60h
+    cmp   al, 60h
+    je    @F
+    mov   eax, cr0
+    or    eax, 060000000h
+    mov   cr0, eax
+    wbinvd
+@@:
+    ret
+EfiDisableCache  ENDP
+
+;VOID
+;EfiEnableCache (
+;  VOID
+;  )
+EfiEnableCache PROC C PUBLIC
+    wbinvd
+    mov   eax, cr0
+    and   eax, 09fffffffh
+    mov   cr0, eax
+    ret
+EfiEnableCache  ENDP
+
+;UINT32
+;EfiGetEflags (
+;  VOID
+;  )
+EfiGetEflags PROC C PUBLIC
+    pushfd
+    pop  eax
+    ret
+EfiGetEflags  ENDP
+
+;VOID
+;EfiDisableInterrupts (
+;  VOID
+;  )
+EfiDisableInterrupts PROC C PUBLIC
+    cli
+    ret
+EfiDisableInterrupts  ENDP
+
+;VOID
+;EfiEnableInterrupts (
+;  VOID
+;  )
+EfiEnableInterrupts  PROC C PUBLIC
+    sti
+    ret
+EfiEnableInterrupts   ENDP
+
+;VOID
+;EfiCpuidExt (
+;  IN   UINT32              RegisterInEax,
+;  IN   UINT32              CacheLevel,
+;  OUT  EFI_CPUID_REGISTER  *Regs
+;  )
+EfiCpuidExt PROC C PUBLIC USES ebx edi esi
+    pushad
+
+    mov    eax, dword ptr [esp + 30h] ; RegisterInEax
+    mov    ecx, dword ptr [esp + 34h] ; CacheLevel
+    cpuid
+    mov    edi, dword ptr [esp + 38h] ; DWORD PTR Regs
+
+    mov    dword ptr [edi], eax   	; Reg->RegEax
+    mov    dword ptr [edi + 4], ebx   	; Reg->RegEbx
+    mov    dword ptr [edi + 8], ecx   	; Reg->RegEcx
+    mov    dword ptr [edi + 0Ch], edx   ; Reg->RegEdx
+
+    popad
+    ret
+EfiCpuidExt  ENDP
+
+	END
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.c
new file mode 100644
index 0000000000..cb8de2f9c7
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.c
@@ -0,0 +1,177 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+  CpuIA32.c
+
+Abstract:
+
+--*/
+
+#include <Library/CpuIA32.h>
+
+VOID
+EfiHalt (VOID)
+{
+  __asm {
+    hlt
+  }
+}
+
+VOID
+EfiWbinvd (VOID)
+{
+  __asm {
+    wbinvd
+  }
+}
+
+VOID
+EfiInvd (VOID)
+{
+  __asm {
+    invd
+  }
+}
+
+VOID
+EfiCpuid (IN UINT32 RegisterInEax,
+          OUT EFI_CPUID_REGISTER *Reg OPTIONAL)
+{
+  __asm {
+    pushad
+
+    mov    eax, RegisterInEax
+    cpuid
+    cmp    Reg, 0
+    je     _Exit
+    mov    edi, DWORD PTR Reg
+
+    mov    DWORD PTR [edi].RegEax, eax   ; Reg->RegEax
+    mov    DWORD PTR [edi].RegEbx, ebx   ; Reg->RegEbx
+    mov    DWORD PTR [edi].RegEcx, ecx   ; Reg->RegEcx
+    mov    DWORD PTR [edi].RegEdx, edx   ; Reg->RegEdx
+
+_Exit:
+     popad
+  }
+}
+
+UINT64
+EfiReadMsr (IN UINT32 Index)
+{
+  __asm {
+    mov    ecx, Index
+    rdmsr
+  }
+}
+
+VOID
+EfiWriteMsr (
+  IN   UINT32  Index,
+  IN   UINT64  Value
+  )
+{
+  __asm {
+    mov    ecx, Index
+    mov    eax, DWORD PTR Value[0]
+    mov    edx, DWORD PTR Value[4]
+    wrmsr
+  }
+}
+
+UINT64
+EfiReadTsc (VOID)
+{
+  __asm {
+    rdtsc
+  }
+}
+
+VOID
+EfiDisableCache (VOID)
+{
+  __asm {
+    mov   eax, cr0
+    bswap eax
+    and   al, 60h
+    cmp   al, 60h
+    je    Exit
+    mov   eax, cr0
+    or    eax, 060000000h
+    mov   cr0, eax
+    wbinvd
+Exit:
+  }
+}
+
+VOID
+EfiEnableCache (VOID)
+{
+  __asm {
+    wbinvd
+    mov   eax, cr0
+    and   eax, 09fffffffh
+    mov   cr0, eax
+  }
+}
+
+UINT32
+EfiGetEflags (
+  VOID
+  )
+{
+  __asm {
+    pushfd
+    pop  eax
+  }
+}
+
+VOID
+EfiDisableInterrupts (VOID)
+{
+  __asm {
+    cli
+  }
+}
+
+VOID
+EfiEnableInterrupts (
+  VOID
+  )
+{
+  __asm {
+    sti
+  }
+}
+
+VOID
+EfiCpuidExt (
+  IN   UINT32              RegisterInEax,
+  IN   UINT32              CacheLevel,
+  OUT  EFI_CPUID_REGISTER  *Regs
+  )
+{
+  __asm {
+    pushad
+
+    mov    eax, RegisterInEax
+    mov    ecx, CacheLevel
+    cpuid
+    mov    edi, DWORD PTR Regs
+
+    mov    DWORD PTR [edi].RegEax, eax   ; Reg->RegEax
+    mov    DWORD PTR [edi].RegEbx, ebx   ; Reg->RegEbx
+    mov    DWORD PTR [edi].RegEcx, ecx   ; Reg->RegEcx
+    mov    DWORD PTR [edi].RegEdx, edx   ; Reg->RegEdx
+
+    popad
+  }
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.S b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.S
new file mode 100644
index 0000000000..3a8d6e6bc5
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.S
@@ -0,0 +1,207 @@
+#
+#
+# Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+#                                                                                  

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

+#
+#
+#*   Module Name:
+#*
+#*    Cpu.asm
+#*
+#*   Abstract:
+#*
+#------------------------------------------------------------------------------
+##include <EfiBind.h>
+
+.globl ASM_PFX(EfiHalt)
+.globl ASM_PFX(EfiWbinvd)
+.globl ASM_PFX(EfiInvd)
+.globl ASM_PFX(EfiCpuid)
+.globl ASM_PFX(EfiReadTsc)
+.globl ASM_PFX(EfiDisableCache)
+.globl ASM_PFX(EfiEnableCache)
+.globl ASM_PFX(EfiReadMsr)
+.globl ASM_PFX(EfiWriteMsr)
+.globl ASM_PFX(EfiGetEflags)
+.globl ASM_PFX(EfiDisableInterrupts)
+.globl ASM_PFX(EfiEnableInterrupts)
+.globl ASM_PFX(EfiCpuidExt)
+
+.text
+
+
+#------------------------------------------------------------------------------
+#  VOID
+#  EfiHalt (
+#    VOID
+#    )
+#------------------------------------------------------------------------------
+ASM_PFX(EfiHalt):
+    hlt
+    retq
+
+
+#------------------------------------------------------------------------------
+#  VOID
+#  EfiWbinvd (
+#    VOID
+#    )
+#------------------------------------------------------------------------------
+ASM_PFX(EfiWbinvd):
+    wbinvd
+    retq
+
+
+#------------------------------------------------------------------------------
+#  VOID
+#  EfiInvd (
+#    VOID
+#    )
+#------------------------------------------------------------------------------
+ASM_PFX(EfiInvd):
+    invd
+    retq
+
+#------------------------------------------------------------------------------
+#  VOID
+#  EfiCpuid (
+#    IN   UINT32              RegisterInEax,          // rcx
+#    OUT  EFI_CPUID_REGISTER  *Reg           OPTIONAL // rdx
+#    )
+#------------------------------------------------------------------------------
+ASM_PFX(EfiCpuid):
+      push   %rbx
+      mov    %rdx,%r8
+      mov    %rcx,%rax
+      cpuid
+      cmp    $0x0,%r8
+      je     _Exit
+      mov    %eax,(%r8)
+      mov    %ebx,0x4(%r8)
+      mov    %ecx,0x8(%r8)
+      mov    %edx,0xc(%r8)
+_Exit:
+      pop    %rbx
+      retq
+
+#------------------------------------------------------------------------------
+#  UINT64
+#  EfiReadMsr (
+#    IN   UINT32  Index,  // rcx
+#    )
+#------------------------------------------------------------------------------
+ASM_PFX(EfiReadMsr):
+      rdmsr
+      shl    $0x20,%rdx
+      or     %rdx,%rax
+      retq
+
+#------------------------------------------------------------------------------
+#  VOID
+#  EfiWriteMsr (
+#    IN   UINT32  Index,  // rcx
+#    IN   UINT64  Value   // rdx
+#    )
+#------------------------------------------------------------------------------
+ASM_PFX(EfiWriteMsr):
+      mov    %rdx,%rax
+      sar    $0x20,%rdx
+      wrmsr
+      retq
+
+#------------------------------------------------------------------------------
+# UINT64
+# EfiReadTsc (
+#   VOID
+#   );
+#------------------------------------------------------------------------------
+ASM_PFX(EfiReadTsc):
+      rdtsc
+      shl    $0x20,%rax
+      shrd   $0x20,%rdx,%rax
+      retq
+
+#------------------------------------------------------------------------------
+# VOID
+# EfiDisableCache (
+#   VOID
+#   );
+#------------------------------------------------------------------------------
+ASM_PFX(EfiDisableCache):
+# added a check to see if cache is already disabled. If it is, then skip.
+      mov    %cr0,%rax
+      and    $0x60000000,%rax
+      cmp    $0x0,%rax
+      jne    1f
+      mov    %cr0,%rax
+      or     $0x60000000,%rax
+      mov    %rax,%cr0
+      wbinvd
+1:
+      retq
+
+#------------------------------------------------------------------------------
+# VOID
+# EfiEnableCache (
+#   VOID
+#   );
+#------------------------------------------------------------------------------
+ASM_PFX(EfiEnableCache):
+      wbinvd
+      mov    %cr0,%rax
+      and    $0xffffffff9fffffff,%rax
+      mov    %rax,%cr0
+      retq
+
+#------------------------------------------------------------------------------
+# UINTN
+# EfiGetEflags (
+#   VOID
+#   );
+#------------------------------------------------------------------------------
+ASM_PFX(EfiGetEflags):
+      pushfq
+      pop    %rax
+      retq
+
+#------------------------------------------------------------------------------
+# VOID
+# EfiDisableInterrupts (
+#   VOID
+#   );
+#------------------------------------------------------------------------------
+ASM_PFX(EfiDisableInterrupts):
+    cli
+    ret
+
+#------------------------------------------------------------------------------
+# VOID
+# EfiEnableInterrupts (
+#   VOID
+#   );
+#------------------------------------------------------------------------------
+ASM_PFX(EfiEnableInterrupts):
+    sti
+    ret
+#------------------------------------------------------------------------------
+#  VOID
+#  EfiCpuidExt (
+#    IN   UINT32              RegisterInEax,
+#    IN   UINT32              CacheLevel,
+#    OUT  EFI_CPUID_REGISTER  *Regs
+#    )
+#------------------------------------------------------------------------------
+ASM_PFX(EfiCpuidExt):
+      push   %rbx
+      mov    %rcx,%rax
+      mov    %rdx,%rcx
+      cpuid
+      mov    %eax,(%r8)
+      mov    %ebx,0x4(%r8)
+      mov    %ecx,0x8(%r8)
+      mov    %edx,0xc(%r8)
+      pop    %rbx
+      retq
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.asm b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.asm
new file mode 100644
index 0000000000..44aae7de64
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.asm
@@ -0,0 +1,222 @@
+
+TITLE   Cpu.asm: Assembly code for the x64 resources
+
+;
+; This file contains an 'Intel Sample Driver' and is
+; licensed for Intel CPUs and chipsets under the terms of your
+; license agreement with Intel or your vendor.  This file may
+; be modified by the user, subject to additional terms of the
+; license agreement
+;
+;
+; Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+;                                                                                  

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

+;
+;
+;
+;
+;*   Module Name:
+;*
+;*    Cpu.asm
+;*
+;*   Abstract:
+;*
+;------------------------------------------------------------------------------
+
+text    SEGMENT
+
+
+;------------------------------------------------------------------------------
+;  VOID
+;  EfiHalt (
+;    VOID
+;    )
+;------------------------------------------------------------------------------
+EfiHalt PROC    PUBLIC
+    hlt
+    ret
+EfiHalt ENDP
+
+
+;------------------------------------------------------------------------------
+;  VOID
+;  EfiWbinvd (
+;    VOID
+;    )
+;------------------------------------------------------------------------------
+EfiWbinvd PROC    PUBLIC
+    wbinvd
+    ret
+EfiWbinvd ENDP
+
+
+;------------------------------------------------------------------------------
+;  VOID
+;  EfiInvd (
+;    VOID
+;    )
+;------------------------------------------------------------------------------
+EfiInvd PROC    PUBLIC
+    invd
+    ret
+EfiInvd ENDP
+
+;------------------------------------------------------------------------------
+;  VOID
+;  EfiCpuid (
+;    IN   UINT32              RegisterInEax,          // rcx
+;    OUT  EFI_CPUID_REGISTER  *Reg           OPTIONAL // rdx
+;    )
+;------------------------------------------------------------------------------
+EfiCpuid PROC   PUBLIC
+    push  rbx
+
+    mov   r8,   rdx         ; r8 = *Reg
+    mov   rax,  rcx         ; RegisterInEax
+    cpuid
+    cmp   r8,   0
+    je    _Exit
+    mov   [r8 +  0], eax    ; Reg->RegEax
+    mov   [r8 +  4], ebx    ; Reg->RegEbx
+    mov   [r8 +  8], ecx    ; Reg->RegEcx
+    mov   [r8 + 12], edx    ; Reg->RegEdx
+
+_Exit:
+    pop   rbx
+    ret
+EfiCpuid  ENDP
+
+;------------------------------------------------------------------------------
+;  UINT64
+;  EfiReadMsr (
+;    IN   UINT32  Index,  // rcx
+;    )
+;------------------------------------------------------------------------------
+EfiReadMsr PROC  PUBLIC
+    rdmsr
+    sal     rdx, 32   ; edx:eax -> rax
+    or      rax, rdx  ; rax = edx:eax
+    ret
+EfiReadMsr  ENDP
+
+;------------------------------------------------------------------------------
+;  VOID
+;  EfiWriteMsr (
+;    IN   UINT32  Index,  // rcx
+;    IN   UINT64  Value   // rdx
+;    )
+;------------------------------------------------------------------------------
+EfiWriteMsr PROC   PUBLIC
+    mov     rax,  rdx   ; rdx = Value
+    sar     rdx,  32    ; convert rdx to edx upper 32-bits
+    wrmsr               ; wrmsr[ecx] result = edx:eax
+    ret
+EfiWriteMsr  ENDP
+
+
+;------------------------------------------------------------------------------
+; UINT64
+; EfiReadTsc (
+;   VOID
+;   );
+;------------------------------------------------------------------------------
+EfiReadTsc PROC    PUBLIC
+    rdtsc
+    shl     rax, 32
+    shrd    rax, rdx, 32
+    ret
+EfiReadTsc  ENDP
+
+;------------------------------------------------------------------------------
+; VOID
+; EfiDisableCache (
+;   VOID
+;   );
+;------------------------------------------------------------------------------
+EfiDisableCache PROC    PUBLIC
+; added a check to see if cache is already disabled. If it is, then skip.
+    mov   rax, cr0
+    and   rax, 060000000h
+    cmp   rax, 0
+    jne   @f
+    mov   rax, cr0
+    or    rax, 060000000h
+    mov   cr0, rax
+    wbinvd
+@@:
+    ret
+EfiDisableCache ENDP
+
+;------------------------------------------------------------------------------
+; VOID
+; EfiEnableCache (
+;   VOID
+;   );
+;------------------------------------------------------------------------------
+EfiEnableCache PROC    PUBLIC
+    wbinvd
+    mov   rax, cr0
+    and   rax, 09fffffffh
+    mov   cr0, rax
+    ret
+EfiEnableCache ENDP
+
+;------------------------------------------------------------------------------
+; UINTN
+; EfiGetEflags (
+;   VOID
+;   );
+;------------------------------------------------------------------------------
+EfiGetEflags PROC    PUBLIC
+    pushfq
+    pop   rax
+    ret
+EfiGetEflags  ENDP
+
+;------------------------------------------------------------------------------
+; VOID
+; EfiDisableInterrupts (
+;   VOID
+;   );
+;------------------------------------------------------------------------------
+EfiDisableInterrupts PROC    PUBLIC
+    cli
+    ret
+EfiDisableInterrupts  ENDP
+
+;------------------------------------------------------------------------------
+; VOID
+; EfiEnableInterrupts (
+;   VOID
+;   );
+;------------------------------------------------------------------------------
+EfiEnableInterrupts PROC    PUBLIC
+    sti
+    ret
+EfiEnableInterrupts  ENDP
+;------------------------------------------------------------------------------
+;  VOID
+;  EfiCpuidExt (
+;    IN   UINT32              RegisterInEax,
+;    IN   UINT32              CacheLevel,
+;    OUT  EFI_CPUID_REGISTER  *Regs
+;    )
+;------------------------------------------------------------------------------
+EfiCpuidExt PROC    PUBLIC
+     push   rbx
+     mov    rax, rcx          ; rax = RegisterInEax
+     mov    rcx, rdx          ; rcx = CacheLevel
+
+     cpuid
+     mov    [r8 + 0 ],  eax   ; Reg->RegEax
+     mov    [r8 + 4 ],  ebx   ; Reg->RegEbx
+     mov    [r8 + 8 ],  ecx   ; Reg->RegEcx
+     mov    [r8 + 12],  edx   ; Reg->RegEdx
+
+     pop rbx
+     ret
+EfiCpuidExt  ENDP
+END
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.c
new file mode 100644
index 0000000000..b7d896d9fd
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.c
@@ -0,0 +1,282 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+                                                                                   

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

+
+
+Module Name:
+
+  EfiRegTableLib.c
+
+Abstract:
+
+  Lib function for table driven register initialization.
+
+Revision History
+
+--*/
+
+#include <Library/EfiRegTableLib.h>
+#include <Library/S3BootScriptLib.h>
+
+//
+// Local Functions
+//
+
+/**
+  Local worker function to process PCI_WRITE table entries.  Performs write and
+  may also call BootScriptSave protocol if indicated in the Entry flags
+
+  @param Entry            A pointer to the PCI_WRITE entry to process
+
+  @param PciRootBridgeIo  A pointer to the instance of PciRootBridgeIo that is used
+                          when processing the entry.
+
+  @retval Nothing.
+
+**/
+STATIC
+VOID
+PciWrite (
+  EFI_REG_TABLE_PCI_WRITE             *Entry,
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL     *PciRootBridgeIo
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = PciRootBridgeIo->Pci.Write (
+                                  PciRootBridgeIo,
+                                  (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+                                  (UINT64) Entry->PciAddress,
+                                  1,
+                                  &Entry->Data
+                                  );
+  ASSERT_EFI_ERROR (Status);
+
+  if (OPCODE_FLAGS (Entry->OpCode) & OPCODE_FLAG_S3SAVE) {
+    Status = S3BootScriptSavePciCfgWrite (
+              (EFI_BOOT_SCRIPT_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+              (UINT64) Entry->PciAddress,
+              1,
+              &Entry->Data
+              );
+    ASSERT_EFI_ERROR (Status);
+  }
+}
+
+/**
+  Local worker function to process PCI_READ_MODIFY_WRITE table entries.
+  Performs RMW write and may also call BootScriptSave protocol if indicated in
+  the Entry flags.
+
+  @param Entry            A pointer to the PCI_READ_MODIFY_WRITE entry to process.
+
+  @param PciRootBridgeIo  A pointer to the instance of PciRootBridgeIo that is used
+                          when processing the entry.
+
+  @retval Nothing.
+
+**/
+STATIC
+VOID
+PciReadModifyWrite (
+  EFI_REG_TABLE_PCI_READ_MODIFY_WRITE *Entry,
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL     *PciRootBridgeIo
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      TempData;
+
+  Status = PciRootBridgeIo->Pci.Read (
+                                  PciRootBridgeIo,
+                                  (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+                                  (UINT64) Entry->PciAddress,
+                                  1,
+                                  &TempData
+                                  );
+  ASSERT_EFI_ERROR (Status);
+
+  Entry->OrMask &= Entry->AndMask;
+  TempData &= ~Entry->AndMask;
+  TempData |= Entry->OrMask;
+
+  Status = PciRootBridgeIo->Pci.Write (
+                                  PciRootBridgeIo,
+                                  (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+                                  (UINT64) Entry->PciAddress,
+                                  1,
+                                  &TempData
+                                  );
+  ASSERT_EFI_ERROR (Status);
+
+  if (OPCODE_FLAGS (Entry->OpCode) & OPCODE_FLAG_S3SAVE) {
+    Status = S3BootScriptSavePciCfgReadWrite (
+              (EFI_BOOT_SCRIPT_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+              (UINT64) Entry->PciAddress,
+              &Entry->OrMask,
+              &Entry->AndMask
+              );
+    ASSERT_EFI_ERROR (Status);
+  }
+}
+
+/**
+  Local worker function to process MEM_READ_MODIFY_WRITE table entries.
+  Performs RMW write and may also call BootScriptSave protocol if indicated in
+  the Entry flags.
+
+  @param Entry            A pointer to the MEM_READ_MODIFY_WRITE entry to process.
+
+  @param PciRootBridgeIo  A pointer to the instance of PciRootBridgeIo that is used
+                          when processing the entry.
+
+  @retval Nothing.
+
+**/
+STATIC
+VOID
+MemReadModifyWrite (
+  EFI_REG_TABLE_MEM_READ_MODIFY_WRITE *Entry,
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL     *PciRootBridgeIo
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      TempData;
+
+  Status = PciRootBridgeIo->Mem.Read (
+                                  PciRootBridgeIo,
+                                  (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+                                  (UINT64) Entry->MemAddress,
+                                  1,
+                                  &TempData
+                                  );
+  ASSERT_EFI_ERROR (Status);
+
+  Entry->OrMask &= Entry->AndMask;
+  TempData &= ~Entry->AndMask;
+  TempData |= Entry->OrMask;
+
+  Status = PciRootBridgeIo->Mem.Write (
+                                  PciRootBridgeIo,
+                                  (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+                                  (UINT64) Entry->MemAddress,
+                                  1,
+                                  &TempData
+                                  );
+  ASSERT_EFI_ERROR (Status);
+
+  if (OPCODE_FLAGS (Entry->OpCode) & OPCODE_FLAG_S3SAVE) {
+    Status = S3BootScriptSaveMemReadWrite (
+              (EFI_BOOT_SCRIPT_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+              Entry->MemAddress,
+              &Entry->OrMask,
+              &Entry->AndMask
+              );
+    ASSERT_EFI_ERROR (Status);
+  }
+}
+
+//
+// Exported functions
+//
+
+/**
+  Processes register table assuming which may contain PCI, IO, MEM, and STALL
+  entries.
+
+  No parameter checking is done so the caller must be careful about omitting
+  values for PciRootBridgeIo or CpuIo parameters.  If the regtable does
+  not contain any PCI accesses, it is safe to omit the PciRootBridgeIo (supply
+  NULL).  If the regtable does not contain any IO or Mem entries, it is safe to
+  omit the CpuIo (supply NULL).
+
+  The RegTableEntry parameter is not checked, but is required.
+
+  gBS is assumed to have been defined and is used when processing stalls.
+
+  The function processes each entry sequentially until an OP_TERMINATE_TABLE
+  entry is encountered.
+
+  @param RegTableEntry    A pointer to the register table to process
+
+  @param PciRootBridgeIo  A pointer to the instance of PciRootBridgeIo that is used
+                          when processing PCI table entries
+
+  @param CpuIo            A pointer to the instance of CpuIo that is used when processing IO and
+                          MEM table entries
+
+  @retval Nothing.
+
+**/
+VOID
+ProcessRegTablePci (
+  EFI_REG_TABLE                       *RegTableEntry,
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL     *PciRootBridgeIo,
+  EFI_CPU_IO_PROTOCOL                 *CpuIo
+  )
+{
+  while (OPCODE_BASE (RegTableEntry->Generic.OpCode) != OP_TERMINATE_TABLE) {
+    switch (OPCODE_BASE (RegTableEntry->Generic.OpCode)) {
+    case OP_PCI_WRITE:
+      PciWrite ((EFI_REG_TABLE_PCI_WRITE *) RegTableEntry, PciRootBridgeIo);
+      break;
+
+    case OP_PCI_READ_MODIFY_WRITE:
+      PciReadModifyWrite ((EFI_REG_TABLE_PCI_READ_MODIFY_WRITE *) RegTableEntry, PciRootBridgeIo);
+      break;
+
+    case OP_MEM_READ_MODIFY_WRITE:
+      MemReadModifyWrite ((EFI_REG_TABLE_MEM_READ_MODIFY_WRITE *) RegTableEntry, PciRootBridgeIo);
+      break;
+
+    default:
+      DEBUG ((EFI_D_ERROR, "RegTable ERROR: Unknown RegTable OpCode (%x)\n", OPCODE_BASE (RegTableEntry->Generic.OpCode)));
+      ASSERT (0);
+      break;
+    }
+
+    RegTableEntry++;
+  }
+}
+
+/**
+  Processes register table assuming which may contain IO, MEM, and STALL
+  entries, but must NOT contain any PCI entries.  Any PCI entries cause an
+  ASSERT in a DEBUG build and are skipped in a free build.
+
+  No parameter checking is done.  Both RegTableEntry and CpuIo parameters are
+  required.
+
+  gBS is assumed to have been defined and is used when processing stalls.
+
+  The function processes each entry sequentially until an OP_TERMINATE_TABLE
+  entry is encountered.
+
+  @param  RegTableEntry   A pointer to the register table to process
+
+  @param  CpuIo           A pointer to the instance of CpuIo that is used when processing IO and
+                          MEM table entries
+
+  @retval Nothing.
+
+**/
+VOID
+ProcessRegTableCpu (
+  EFI_REG_TABLE                       *RegTableEntry,
+  EFI_CPU_IO_PROTOCOL                 *CpuIo
+  )
+{
+  while (OPCODE_BASE (RegTableEntry->Generic.OpCode) != OP_TERMINATE_TABLE) {
+    switch (OPCODE_BASE (RegTableEntry->Generic.OpCode)) {
+    default:
+      DEBUG ((EFI_D_ERROR, "RegTable ERROR: Unknown RegTable OpCode (%x)\n", OPCODE_BASE (RegTableEntry->Generic.OpCode)));
+      ASSERT (0);
+      break;
+    }
+
+    RegTableEntry++;
+  }
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.inf b/Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.inf
new file mode 100644
index 0000000000..9cb8841d65
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.inf
@@ -0,0 +1,47 @@
+#
+#
+#/*++
+#
+# Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
+#                                                                                  

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

+
+#
+#  Module Name:
+#
+#    EfiRegTableLib.inf
+#
+#  Abstract:
+#
+#    Component description file.
+#
+#--*/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = EfiRegTableLib
+  FILE_GUID                      = 98546145-64F1-4d2e-814F-6BF963DB7930
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = EfiRegTableLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  EfiRegTableLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+
+
+[LibraryClasses]
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.c
new file mode 100644
index 0000000000..558763fa98
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.c
@@ -0,0 +1,461 @@
+/** @file
+
+  Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+**/
+
+#include <PiDxe.h>
+
+#include <Library/FlashDeviceLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Protocol/SmmBase2.h>
+#include <Guid/EventGroup.h>
+#include "SpiChipDefinitions.h"
+
+UINTN FlashDeviceBase = FLASH_DEVICE_BASE_ADDRESS;
+
+EFI_SPI_PROTOCOL *mSpiProtocol = NULL;
+
+EFI_STATUS
+SpiFlashErase (
+  UINT8 *BaseAddress,
+  UINTN NumBytes
+  )
+{
+  EFI_STATUS          Status = EFI_SUCCESS;
+  UINT32              SectorSize;
+  UINT32              SpiAddress;
+
+  SpiAddress = (UINT32)(UINTN)(BaseAddress) - (UINT32)FlashDeviceBase;
+  SectorSize = SECTOR_SIZE_4KB;
+  while ( (NumBytes > 0) && (NumBytes <= MAX_FWH_SIZE) ) {
+    Status = mSpiProtocol->Execute (
+                             mSpiProtocol,
+                             SPI_SERASE,
+                             SPI_WREN,
+                             FALSE,
+                             TRUE,
+                             FALSE,
+                             (UINT32) SpiAddress,
+                             0,
+                             NULL,
+                             EnumSpiRegionBios
+                             );
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+    SpiAddress += SectorSize;
+    NumBytes   -= SectorSize;
+  }
+
+  return Status;
+}
+
+
+EFI_STATUS
+SpiFlashBlockErase (
+  UINT8 *BaseAddress,
+  UINTN NumBytes
+  )
+{
+  EFI_STATUS          Status = EFI_SUCCESS;
+  UINT32              SectorSize;
+  UINT32              SpiAddress;
+
+  SpiAddress = (UINT32)(UINTN)(BaseAddress) - (UINT32)FlashDeviceBase;
+  SectorSize = SECTOR_SIZE_4KB;
+  while ( (NumBytes > 0) && (NumBytes <= MAX_FWH_SIZE) ) {
+    Status = mSpiProtocol->Execute (
+                             mSpiProtocol,
+                             SPI_SERASE,
+                             SPI_WREN,
+                             FALSE,
+                             TRUE,
+                             FALSE,
+                             (UINT32) SpiAddress,
+                             0,
+                             NULL,
+                             EnumSpiRegionBios
+                             );
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+    SpiAddress += SectorSize;
+    NumBytes   -= SectorSize;
+  }
+
+  return Status;
+}
+
+
+static
+EFI_STATUS
+SpiFlashWrite (
+  UINT8 *DstBufferPtr,
+  UINT8 *Byte,
+  IN  UINTN Length
+  )
+{
+  EFI_STATUS                Status;
+  UINT32                    NumBytes = (UINT32)Length;
+  UINT8*                    pBuf8 = Byte;
+  UINT32                    SpiAddress;
+
+  SpiAddress = (UINT32)(UINTN)(DstBufferPtr) - (UINT32)FlashDeviceBase;
+  Status = mSpiProtocol->Execute (
+                           mSpiProtocol,
+                           SPI_PROG,
+                           SPI_WREN,
+                           TRUE,
+                           TRUE,
+                           TRUE,
+                           (UINT32)SpiAddress,
+                           NumBytes,
+                           pBuf8,
+                           EnumSpiRegionBios
+                           );
+  return Status;
+}
+
+/**
+  Read the Serial Flash Status Registers.
+
+  @param  SpiStatus         Pointer to a caller-allocated UINT8. On successful return, it contains the
+                            status data read from the Serial Flash Status Register.
+
+
+  @retval EFI_SUCCESS       Operation success, status is returned in SpiStatus.
+  @retval EFI_DEVICE_ERROR  The block device is not functioning correctly and the operation failed.
+
+**/
+EFI_STATUS
+ReadStatusRegister (
+  UINT8   *SpiStatus
+  )
+{
+  EFI_STATUS          Status;
+
+  Status = mSpiProtocol->Execute (
+             mSpiProtocol,
+             SPI_RDSR,
+             SPI_WREN,
+             TRUE,
+             FALSE,
+             FALSE,
+             0,
+             1,
+             SpiStatus,
+             EnumSpiRegionBios
+             );
+  return Status;
+}
+
+EFI_STATUS
+SpiFlashLock (
+    IN  UINT8  *BaseAddress,
+    IN  UINTN  NumBytes,
+    IN  BOOLEAN  Lock
+  )
+{
+  EFI_STATUS          Status;
+  UINT8               SpiData;
+  UINT8               SpiStatus;
+
+  if (Lock) {
+    SpiData = SF_SR_WPE;
+  } else {
+    SpiData = 0;
+  }
+
+  //
+  // Always disable block protection to workaround tool issue.
+  // Feature may be re-enabled in a future bios.
+  //
+  SpiData = 0;
+  Status = mSpiProtocol->Execute (
+                           mSpiProtocol,
+                           SPI_WRSR,
+                           SPI_EWSR,
+                           TRUE,
+                           TRUE,
+                           TRUE,
+                           0,
+                           1,
+                           &SpiData,
+                           EnumSpiRegionBios
+                           );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = ReadStatusRegister (&SpiStatus);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if ((SpiStatus & SpiData) != SpiData) {
+    Status = EFI_DEVICE_ERROR;
+  }
+
+  return Status;
+}
+
+
+/**
+  Read NumBytes bytes of data from the address specified by
+  PAddress into Buffer.
+
+  @param[in]      PAddress          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
+LibFvbFlashDeviceRead (
+  IN      UINTN                           PAddress,
+  IN  OUT UINTN                           *NumBytes,
+      OUT UINT8                           *Buffer
+  )
+{
+  CopyMem(Buffer, (VOID*)PAddress, *NumBytes);
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Write NumBytes bytes of data from Buffer to the address specified by
+  PAddresss.
+
+  @param[in]      PAddress          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
+LibFvbFlashDeviceWrite (
+  IN        UINTN                           PAddress,
+  IN OUT    UINTN                           *NumBytes,
+  IN        UINT8                           *Buffer
+  )
+{
+EFI_STATUS Status;
+  Status =  SpiFlashWrite((UINT8 *)PAddress, Buffer, *NumBytes);
+ return Status;
+}
+
+
+/**
+  Erase the block staring at PAddress.
+
+  @param[in]  PAddress          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]  LbaLength         The length of the logical block to be erased.
+
+  @retval     EFI_SUCCESS.      Opertion is successful.
+  @retval     EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+LibFvbFlashDeviceBlockErase (
+  IN    UINTN                     PAddress,
+  IN    UINTN                     LbaLength
+  )
+{
+  EFI_STATUS Status;
+  Status = SpiFlashBlockErase((UINT8 *)PAddress, LbaLength);
+
+  return Status;
+}
+
+
+/**
+  Lock or unlock the block staring at PAddress.
+
+  @param[in]  PAddress        The starting physical address of region to be (un)locked.
+  @param[in]  LbaLength       The length of the logical block to be erased.
+  @param[in]  Lock            TRUE to lock. FALSE to unlock.
+
+  @retval     EFI_SUCCESS.      Opertion is successful.
+  @retval     EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+LibFvbFlashDeviceBlockLock (
+  IN    UINTN                          PAddress,
+  IN    UINTN                          LbaLength,
+  IN    BOOLEAN                        Lock
+  )
+{
+  EFI_STATUS Status;
+
+    Status = SpiFlashLock((UINT8*)PAddress, LbaLength, Lock);
+  return Status;
+}
+
+VOID
+EFIAPI
+LibFvbFlashDeviceVirtualAddressChangeNotifyEvent (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  )
+{
+  gRT->ConvertPointer (0, (VOID **) &mSpiProtocol);
+  gRT->ConvertPointer (0, (VOID **) &FlashDeviceBase);
+}
+
+
+/**
+  The library constructuor.
+
+  The function does the necessary initialization work for this library
+  instance. Please put all initialization works in it.
+
+  @param[in]  ImageHandle       The firmware allocated handle for the UEFI image.
+  @param[in]  SystemTable       A pointer to the EFI system table.
+
+  @retval     EFI_SUCCESS       The function always return EFI_SUCCESS for now.
+                                It will ASSERT on error for debug version.
+  @retval     EFI_ERROR         Please reference LocateProtocol for error code details.
+
+**/
+EFI_STATUS
+EFIAPI
+LibFvbFlashDeviceSupportInit (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS Status;
+  EFI_EVENT  Event;
+  UINT8                         SfId[3];
+  UINT8                         FlashIndex;
+  UINT8                         SpiReadError;
+  UINT8                         SpiNotMatchError;
+  EFI_SMM_BASE2_PROTOCOL       *SmmBase;
+  BOOLEAN                       InSmm;
+
+  SpiReadError     = 0x00;
+  SpiNotMatchError = 0x00;
+
+  InSmm = FALSE;
+  Status = gBS->LocateProtocol (
+                  &gEfiSmmBase2ProtocolGuid,
+                  NULL,
+                  (void **)&SmmBase
+                  );
+  if (!EFI_ERROR(Status)) {
+    Status = SmmBase->InSmm(SmmBase, &InSmm);
+    if (EFI_ERROR(Status)) {
+      InSmm = FALSE;
+    }
+  }
+
+  if (!InSmm) {
+    Status = gBS->LocateProtocol (
+                  &gEfiSpiProtocolGuid,
+                  NULL,
+                  (VOID **)&mSpiProtocol
+                  );
+    ASSERT_EFI_ERROR (Status);
+
+    Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  LibFvbFlashDeviceVirtualAddressChangeNotifyEvent,
+                  NULL,
+                  &gEfiEventVirtualAddressChangeGuid,
+                  &Event
+                  );
+    ASSERT_EFI_ERROR (Status);
+  } else {
+    Status = gBS->LocateProtocol (
+                    &gEfiSmmSpiProtocolGuid,
+                    NULL,
+                    (VOID **)&mSpiProtocol
+                    );
+    ASSERT_EFI_ERROR (Status);
+  }
+
+
+  for (FlashIndex = EnumSpiFlashW25Q64; FlashIndex < EnumSpiFlashMax; FlashIndex++) {
+    Status = mSpiProtocol->Init (mSpiProtocol, &(mInitTable[FlashIndex]));
+    if (!EFI_ERROR (Status)) {
+      //
+      // Read Vendor/Device IDs to check if the driver supports the Serial Flash device.
+      //
+      Status = mSpiProtocol->Execute (
+                               mSpiProtocol,
+                               SPI_READ_ID,
+                               SPI_WREN,
+                               TRUE,
+                               FALSE,
+                               FALSE,
+                               0,
+                               3,
+                               SfId,
+                               EnumSpiRegionAll
+                               );
+      if (!EFI_ERROR (Status)) {
+        if ((SfId[0] == mInitTable[FlashIndex].VendorId)  &&
+            (SfId[1] == mInitTable[FlashIndex].DeviceId0) &&
+            (SfId[2] == mInitTable[FlashIndex].DeviceId1)) {
+            //
+            // Found a matching SPI device, FlashIndex now contains flash device.
+            //
+            DEBUG ((DEBUG_ERROR, "OK - Found SPI Flash Type in SPI Flash Driver, Device Type ID 0 = 0x%02x!\n", mInitTable[FlashIndex].DeviceId0));
+            DEBUG ((DEBUG_ERROR, "Device Type ID 1 = 0x%02x!\n", mInitTable[FlashIndex].DeviceId1));
+
+            if (mInitTable[FlashIndex].BiosStartOffset == (UINTN) (-1)) {
+              DEBUG ((DEBUG_ERROR, "ERROR - The size of BIOS image is bigger than SPI Flash device!\n"));
+              CpuDeadLoop ();
+            }
+            break;
+        } else {
+          SpiNotMatchError++;
+        }
+      } else {
+        SpiReadError++;
+      }
+    }
+  }
+
+  DEBUG ((DEBUG_ERROR, "SPI flash chip VID = 0x%X, DID0 = 0x%X, DID1 = 0x%X\n", SfId[0], SfId[1], SfId[2]));
+
+  if (FlashIndex < EnumSpiFlashMax)  {
+    return EFI_SUCCESS;
+  } else {
+  if (SpiReadError != 0) {
+      DEBUG ((DEBUG_ERROR, "ERROR - SPI Read ID execution failed! Error Count = %d\n", SpiReadError));
+   }
+    else {
+      if (SpiNotMatchError != 0) {
+        DEBUG ((DEBUG_ERROR, "ERROR - No supported SPI flash chip found! Error Count = %d\n", SpiNotMatchError));
+        DEBUG ((DEBUG_ERROR, "SPI flash chip VID = 0x%X, DID0 = 0x%X, DID1 = 0x%X\n", SfId[0], SfId[1], SfId[2]));
+      }
+    }
+    return EFI_UNSUPPORTED;
+  }
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.inf b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.inf
new file mode 100644
index 0000000000..4ef48cc12b
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.inf
@@ -0,0 +1,44 @@
+#
+#
+# Copyright (c)  1999  - 2016, Intel Corporation. All rights reserved
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#
+
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = FlashDeviceLib
+  FILE_GUID                      = E38A1C3C-928C-4bf7-B6C1-7F0EF163FAA5
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = FlashDeviceLib | DXE_SMM_DRIVER DXE_RUNTIME_DRIVER
+  CONSTRUCTOR                    = LibFvbFlashDeviceSupportInit
+
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  FlashDeviceLib.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+
+[LibraryClasses]
+  DebugLib
+
+[Protocols]
+  gEfiSpiProtocolGuid
+  gEfiSmmSpiProtocolGuid
+  gEfiSmmBase2ProtocolGuid
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxe.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxe.c
new file mode 100644
index 0000000000..cf4677ed88
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxe.c
@@ -0,0 +1,56 @@
+/** @file
+
+  Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+**/
+
+#include <PiDxe.h>
+
+#include <Library/FlashDeviceLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include "SpiChipDefinitions.h"
+
+extern UINTN FlashDeviceBase;
+
+extern EFI_SPI_PROTOCOL *mSpiProtocol;
+
+/**
+  The library constructuor.
+
+  The function does the necessary initialization work for this library
+  instance. Please put all initialization works in it.
+
+  @param[in]  ImageHandle       The firmware allocated handle for the UEFI image.
+  @param[in]  SystemTable       A pointer to the EFI system table.
+
+  @retval     EFI_SUCCESS       The function always return EFI_SUCCESS for now.
+                                It will ASSERT on error for debug version.
+  @retval     EFI_ERROR         Please reference LocateProtocol for error code details.
+
+**/
+EFI_STATUS
+EFIAPI
+LibFvbFlashDeviceSupportInit (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS Status;
+  Status = gBS->LocateProtocol (
+                  &gEfiSpiProtocolGuid,
+                  NULL,
+                  (VOID **)&mSpiProtocol
+                  );
+  ASSERT_EFI_ERROR (Status);
+  // There is no need to call Init, because Runtime or SMM FVB already does that.
+  DEBUG((EFI_D_ERROR, "LibFvbFlashDeviceSupportInit - no init\n"));
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxe.inf b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxe.inf
new file mode 100644
index 0000000000..2237e95781
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxe.inf
@@ -0,0 +1,43 @@
+#
+#
+# Copyright (c)  1999  - 2016, Intel Corporation. All rights reserved
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#
+
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = FlashDeviceLibDxe
+  FILE_GUID                      = F0D7222F-FD43-4A5D-B8BF-A259C87AE3B2
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = FlashDeviceLib | DXE_DRIVER
+  CONSTRUCTOR                    = LibFvbFlashDeviceSupportInit
+
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  FlashDeviceLib.c
+  FlashDeviceLibDxe.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+
+[LibraryClasses]
+  DebugLib
+
+[Protocols]
+  gEfiSpiProtocolGuid
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxeRuntimeSmm.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxeRuntimeSmm.c
new file mode 100644
index 0000000000..df395fbc03
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxeRuntimeSmm.c
@@ -0,0 +1,173 @@
+/** @file
+
+  Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+**/
+
+#include <PiDxe.h>
+
+#include <Library/FlashDeviceLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Protocol/SmmBase2.h>
+#include <Guid/EventGroup.h>
+#include "SpiChipDefinitions.h"
+
+extern UINTN FlashDeviceBase;
+
+extern EFI_SPI_PROTOCOL *mSpiProtocol;
+
+VOID
+EFIAPI
+LibFvbFlashDeviceVirtualAddressChangeNotifyEvent (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  )
+{
+  gRT->ConvertPointer (0, (VOID **) &mSpiProtocol);
+  gRT->ConvertPointer (0, (VOID **) &FlashDeviceBase);
+}
+
+
+/**
+  The library constructuor.
+
+  The function does the necessary initialization work for this library
+  instance. Please put all initialization works in it.
+
+  @param[in]  ImageHandle       The firmware allocated handle for the UEFI image.
+  @param[in]  SystemTable       A pointer to the EFI system table.
+
+  @retval     EFI_SUCCESS       The function always return EFI_SUCCESS for now.
+                                It will ASSERT on error for debug version.
+  @retval     EFI_ERROR         Please reference LocateProtocol for error code details.
+
+**/
+EFI_STATUS
+EFIAPI
+LibFvbFlashDeviceSupportInit (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS Status;
+  EFI_EVENT  Event;
+  UINT8                         SfId[3];
+  UINT8                         FlashIndex;
+  UINT8                         SpiReadError;
+  UINT8                         SpiNotMatchError;
+  EFI_SMM_BASE2_PROTOCOL       *SmmBase;
+  BOOLEAN                       InSmm;
+
+  SpiReadError     = 0x00;
+  SpiNotMatchError = 0x00;
+
+  InSmm = FALSE;
+  Status = gBS->LocateProtocol (
+                  &gEfiSmmBase2ProtocolGuid,
+                  NULL,
+                  (void **)&SmmBase
+                  );
+  if (!EFI_ERROR(Status)) {
+    Status = SmmBase->InSmm(SmmBase, &InSmm);
+    if (EFI_ERROR(Status)) {
+      InSmm = FALSE;
+    }
+  }
+
+  if (!InSmm) {
+    Status = gBS->LocateProtocol (
+                  &gEfiSpiProtocolGuid,
+                  NULL,
+                  (VOID **)&mSpiProtocol
+                  );
+    ASSERT_EFI_ERROR (Status);
+
+    Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  LibFvbFlashDeviceVirtualAddressChangeNotifyEvent,
+                  NULL,
+                  &gEfiEventVirtualAddressChangeGuid,
+                  &Event
+                  );
+    ASSERT_EFI_ERROR (Status);
+
+  } else {
+    Status = gBS->LocateProtocol (
+                    &gEfiSmmSpiProtocolGuid,
+                    NULL,
+                    (VOID **)&mSpiProtocol
+                    );
+    ASSERT_EFI_ERROR (Status);
+  }
+
+
+  for (FlashIndex = EnumSpiFlashW25Q64; FlashIndex < EnumSpiFlashMax; FlashIndex++) {
+    Status = mSpiProtocol->Init (mSpiProtocol, &(mInitTable[FlashIndex]));
+    if (!EFI_ERROR (Status)) {
+      //
+      // Read Vendor/Device IDs to check if the driver supports the Serial Flash device.
+      //
+      Status = mSpiProtocol->Execute (
+                               mSpiProtocol,
+                               SPI_READ_ID,
+                               SPI_WREN,
+                               TRUE,
+                               FALSE,
+                               FALSE,
+                               0,
+                               3,
+                               SfId,
+                               EnumSpiRegionAll
+                               );
+      if (!EFI_ERROR (Status)) {
+        if ((SfId[0] == mInitTable[FlashIndex].VendorId)  &&
+            (SfId[1] == mInitTable[FlashIndex].DeviceId0) &&
+            (SfId[2] == mInitTable[FlashIndex].DeviceId1)) {
+            //
+            // Found a matching SPI device, FlashIndex now contains flash device.
+            //
+            DEBUG ((EFI_D_ERROR, "OK - Found SPI Flash Type in SPI Flash Driver, Device Type ID 0 = 0x%02x!\n", mInitTable[FlashIndex].DeviceId0));
+            DEBUG ((EFI_D_ERROR, "Device Type ID 1 = 0x%02x!\n", mInitTable[FlashIndex].DeviceId1));
+
+            if (mInitTable[FlashIndex].BiosStartOffset == (UINTN) (-1)) {
+              DEBUG ((EFI_D_ERROR, "ERROR - The size of BIOS image is bigger than SPI Flash device!\n"));
+              CpuDeadLoop ();
+            }
+            break;
+        } else {
+          SpiNotMatchError++;
+        }
+      } else {
+        SpiReadError++;
+      }
+    }
+  }
+
+  DEBUG ((EFI_D_ERROR, "SPI flash chip VID = 0x%X, DID0 = 0x%X, DID1 = 0x%X\n", SfId[0], SfId[1], SfId[2]));
+
+  if (FlashIndex < EnumSpiFlashMax)  {
+    return EFI_SUCCESS;
+  } else {
+  if (SpiReadError != 0) {
+      DEBUG ((EFI_D_ERROR, "ERROR - SPI Read ID execution failed! Error Count = %d\n", SpiReadError));
+   }
+    else {
+      if (SpiNotMatchError != 0) {
+        DEBUG ((EFI_D_ERROR, "ERROR - No supported SPI flash chip found! Error Count = %d\n", SpiNotMatchError));
+        DEBUG ((EFI_D_ERROR, "SPI flash chip VID = 0x%X, DID0 = 0x%X, DID1 = 0x%X\n", SfId[0], SfId[1], SfId[2]));
+      }
+    }
+    return EFI_UNSUPPORTED;
+  }
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/SpiChipDefinitions.h b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/SpiChipDefinitions.h
new file mode 100644
index 0000000000..c20ee6e372
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/SpiChipDefinitions.h
@@ -0,0 +1,835 @@
+/** @file
+
+  Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+**/
+
+#include <Library/SpiFlash.H>
+
+#define FLASH_SIZE  0x400000
+#define FLASH_DEVICE_BASE_ADDRESS (0xFFFFFFFF-FLASH_SIZE+1)
+
+//
+// Serial Flash device initialization data table provided to the
+// Intel(R) SPI Host Controller Compatibility Interface.
+//
+SPI_INIT_TABLE  mInitTable[] = {
+  {
+  SF_VENDOR_ID_WINBOND,     // VendorId
+  SF_DEVICE_ID0_W25QXX,     // DeviceId 0
+  SF_DEVICE_ID1_W25Q64,     // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_EWSR            // Prefix Opcode 1: Enable Write Status Register
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId           },     // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz, EnumSpiOperationReadData          },     // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus        },     // Opcode 2: Read Status Register
+    {EnumSpiOpcodeRead,           SF_INST_SFDP,           EnumSpiCycle50MHz, EnumSpiOperationDiscoveryParameters},    // Opcode 3: Serial Flash Discovery Parameters
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte     },     // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte    },     // Opcode 5: Block Erase (64KB
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus       },     // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((WINBOND_W25Q64_SIZE >= FLASH_SIZE) ? WINBOND_W25Q64_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_ATMEL,       // VendorId
+  SF_DEVICE_ID0_AT25DF321A,  // DeviceId 0
+  SF_DEVICE_ID1_AT25DF321A, // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't support EWSR).
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId           },     // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz, EnumSpiOperationReadData          },     // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus        },     // Opcode 2: Read Status Register
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,           EnumSpiCycle50MHz, EnumSpiOperationWriteDisable      },     // Opcode 3: Write Disable
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte     },     // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte    },     // Opcode 5: Block Erase (32KB)
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus       },     // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((ATMEL_AT25DF321A_SIZE >= FLASH_SIZE) ? ATMEL_AT25DF321A_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_ATMEL,       // VendorId
+  SF_DEVICE_ID0_AT26DF321,  // DeviceId 0
+  SF_DEVICE_ID1_AT26DF321,  // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't support EWSR).
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId           },     // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz, EnumSpiOperationReadData          },     // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus        },     // Opcode 2: Read Status Register
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,           EnumSpiCycle50MHz, EnumSpiOperationWriteDisable      },     // Opcode 3: Write Disable
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte     },     // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte    },     // Opcode 5: Block Erase (32KB)
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus       },     // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((ATMEL_AT26DF321_SIZE >= FLASH_SIZE) ? ATMEL_AT26DF321_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_ATMEL,       // VendorId
+  SF_DEVICE_ID0_AT25DF641,  // DeviceId 0
+  SF_DEVICE_ID1_AT25DF641,  // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't support EWSR).
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId           },     // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz, EnumSpiOperationReadData          },     // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus        },     // Opcode 2: Read Status Register
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,           EnumSpiCycle50MHz, EnumSpiOperationWriteDisable      },     // Opcode 3: Write Disable
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte     },     // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte    },     // Opcode 5: Block Erase (32KB)
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus       },     // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((ATMEL_AT25DF641_SIZE >= FLASH_SIZE) ? ATMEL_AT25DF641_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_WINBOND,     // VendorId
+  SF_DEVICE_ID0_W25QXX,     // DeviceId 0
+  SF_DEVICE_ID1_W25Q16,     // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_EWSR            // Prefix Opcode 1: Enable Write Status Register
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId           },     // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz, EnumSpiOperationReadData          },     // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus        },     // Opcode 2: Read Status Register
+    {EnumSpiOpcodeRead,           SF_INST_SFDP,           EnumSpiCycle50MHz, EnumSpiOperationDiscoveryParameters},    // Opcode 3: Serial Flash Discovery Parameters
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte     },     // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte    },     // Opcode 5: Block Erase (64KB
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus       },     // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((WINBOND_W25Q16_SIZE >= FLASH_SIZE) ? WINBOND_W25Q16_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_WINBOND,     // VendorId
+  SF_DEVICE_ID0_W25QXX,     // DeviceId 0
+  SF_DEVICE_ID1_W25Q32,     // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_EWSR            // Prefix Opcode 1: Enable Write Status Register.
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId           },     // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz, EnumSpiOperationReadData          },     // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus        },     // Opcode 2: Read Status Register
+    {EnumSpiOpcodeRead,           SF_INST_SFDP,           EnumSpiCycle50MHz, EnumSpiOperationDiscoveryParameters},    // Opcode 3: Serial Flash Discovery Parameters
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte     },     // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte    },     // Opcode 5: Block Erase (64KB
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus       },     // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((WINBOND_W25Q32_SIZE >= FLASH_SIZE) ? WINBOND_W25Q32_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_WINBOND,     // VendorId
+  SF_DEVICE_ID0_W25XXX,     // DeviceId 0
+  SF_DEVICE_ID1_W25X32,     // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_EWSR            // Prefix Opcode 1: Enable Write Status Register
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId           },     // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz, EnumSpiOperationReadData          },     // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus        },     // Opcode 2: Read Status Register
+    {EnumSpiOpcodeRead,           SF_INST_SFDP,           EnumSpiCycle50MHz, EnumSpiOperationDiscoveryParameters},    // Opcode 3: Serial Flash Discovery Parameters
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte     },     // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte    },     // Opcode 5: Block Erase (64KB
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus       },     // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((WINBOND_W25X32_SIZE >= FLASH_SIZE) ? WINBOND_W25X32_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_WINBOND,     // VendorId
+  SF_DEVICE_ID0_W25XXX,     // DeviceId 0
+  SF_DEVICE_ID1_W25X64,     // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_EWSR            // Prefix Opcode 1: Enable Write Status Register
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId      },     // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz, EnumSpiOperationReadData      },     // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },     // Opcode 2: Read Status Register
+    {EnumSpiOpcodeRead,           SF_INST_SFDP,           EnumSpiCycle50MHz, EnumSpiOperationDiscoveryParameters},    // Opcode 3: Serial Flash Discovery Parameters
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte  },     // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },     // Opcode 5: Block Erase (64KB
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},    // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },     // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((WINBOND_W25X64_SIZE >= FLASH_SIZE) ? WINBOND_W25X64_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_WINBOND,     // VendorId
+  SF_DEVICE_ID0_W25QXX,     // DeviceId 0
+  SF_DEVICE_ID1_W25Q128,    // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_EWSR            // Prefix Opcode 1: Enable Write Status Register
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId           },     // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz, EnumSpiOperationReadData          },     // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus        },     // Opcode 2: Read Status Register
+    {EnumSpiOpcodeRead,           SF_INST_SFDP,           EnumSpiCycle50MHz, EnumSpiOperationDiscoveryParameters},    // Opcode 3: Serial Flash Discovery Parameters
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte     },     // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte    },     // Opcode 5: Block Erase (64KB
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus       },     // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((WINBOND_W25Q128_SIZE >= FLASH_SIZE) ? WINBOND_W25Q128_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_MACRONIX,    // VendorId
+  SF_DEVICE_ID0_MX25LXX,    // DeviceId 0
+  SF_DEVICE_ID1_MX25L16,    // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_EWSR            // Prefix Opcode 1:  Write Enable (this part doesn't support EWSR).
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle33MHz, EnumSpiOperationReadData      },      // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read Status Register
+    {EnumSpiOpcodeRead,           SF_INST_SFDP,           EnumSpiCycle50MHz, EnumSpiOperationDiscoveryParameters},    // Opcode 3: Serial Flash Discovery Parameters
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5: Block Erase (64KB
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((MACRONIX_MX25L16_SIZE >= FLASH_SIZE) ? MACRONIX_MX25L16_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_MACRONIX,    // VendorId
+  SF_DEVICE_ID0_MX25LXX,    // DeviceId 0
+  SF_DEVICE_ID1_MX25L32,    // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_EWSR            // Prefix Opcode 1:  Write Enable (this part doesn't support EWSR).
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle33MHz, EnumSpiOperationReadData      },      // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read Status Register
+    {EnumSpiOpcodeRead,           SF_INST_SFDP,           EnumSpiCycle50MHz, EnumSpiOperationDiscoveryParameters},    // Opcode 3: Serial Flash Discovery Parameters
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5: Block Erase (64KB
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((MACRONIX_MX25L32_SIZE >= FLASH_SIZE) ? MACRONIX_MX25L32_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_MACRONIX,    // VendorId
+  SF_DEVICE_ID0_MX25LXX,    // DeviceId 0
+  SF_DEVICE_ID1_MX25L64,    // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_EWSR            // Prefix Opcode 1:  Write Enable (this part doesn't support EWSR)
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle33MHz, EnumSpiOperationReadData      },      // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read Status Register
+    {EnumSpiOpcodeRead,           SF_INST_SFDP,           EnumSpiCycle50MHz, EnumSpiOperationDiscoveryParameters},    // Opcode 3: Serial Flash Discovery Parameters
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5: Block Erase (64KB
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((MACRONIX_MX25L64_SIZE >= FLASH_SIZE) ? MACRONIX_MX25L64_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_MACRONIX,    // VendorId
+  SF_DEVICE_ID0_MX25LXX,    // DeviceId 0
+  SF_DEVICE_ID1_MX25L128,   // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_EWSR            // Prefix Opcode 1:  Write Enable (this part doesn't support EWSR)
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle33MHz, EnumSpiOperationReadData      },      // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read Status Register
+    {EnumSpiOpcodeRead,           SF_INST_SFDP,           EnumSpiCycle50MHz, EnumSpiOperationDiscoveryParameters},    // Opcode 3: Serial Flash Discovery Parameters
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5: Block Erase (64KB
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((MACRONIX_MX25L128_SIZE >= FLASH_SIZE) ? MACRONIX_MX25L128_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_MACRONIX,	  // VendorId
+  SF_DEVICE_ID0_MX25UXX,	  // DeviceId 0
+  SF_DEVICE_ID1_MX25U6435F,   // DeviceId 1
+  {
+    SF_INST_WREN, 		      // Prefix Opcode 0: Write Enable
+    SF_INST_EWSR			  // Prefix Opcode 1:  Write Enable (this part doesn't support EWSR)
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr, 	SF_INST_JEDEC_READ_ID,	EnumSpiCycle50MHz, EnumSpiOperationJedecId		},		// Opcode 0: Read ID
+    {EnumSpiOpcodeRead,			SF_INST_READ,			EnumSpiCycle33MHz, EnumSpiOperationReadData 	 }, 	 // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr, 	SF_INST_RDSR,			EnumSpiCycle50MHz, EnumSpiOperationReadStatus	 }, 	 // Opcode 2: Read Status Register
+    {EnumSpiOpcodeRead,			SF_INST_SFDP,			EnumSpiCycle50MHz, EnumSpiOperationDiscoveryParameters},	// Opcode 3: Serial Flash Discovery Parameters
+    {EnumSpiOpcodeWrite,		SF_INST_SERASE, 		EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte  },	  // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,		SF_INST_64KB_ERASE, 	EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },	   // Opcode 5: Block Erase (64KB
+    {EnumSpiOpcodeWrite,		SF_INST_PROG,			EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte}, 	// Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,	SF_INST_WRSR,			EnumSpiCycle50MHz, EnumSpiOperationWriteStatus	  },	  // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((MACRONIX_MX25U64_SIZE >= FLASH_SIZE) ? MACRONIX_MX25U64_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_SST,         // VendorId
+  SF_DEVICE_ID0_SST25VF0XXX,// DeviceId 0
+  SF_DEVICE_ID1_SST25VF016B,// DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_EWSR            // Prefix Opcode 1: Enable Write Status Register
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId           },     // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle20MHz, EnumSpiOperationReadData          },     // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus        },     // Opcode 2: Read Status Register
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,           EnumSpiCycle50MHz, EnumSpiOperationWriteDisable      },     // Opcode 3: Write Disable
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte     },     // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte    },     // Opcode 5: Block Erase (32KB)
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus       },     // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((SST_SST25VF016B_SIZE >= FLASH_SIZE) ? SST_SST25VF016B_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_SST,         // VendorId
+  SF_DEVICE_ID0_SST25VF0XXX,// DeviceId 0
+  SF_DEVICE_ID1_SST25VF064C,// DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_EWSR            // Prefix Opcode 1: Enable Write Status Register
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId           },     // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle20MHz, EnumSpiOperationReadData          },     // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus        },     // Opcode 2: Read Status Register
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,           EnumSpiCycle50MHz, EnumSpiOperationWriteDisable      },     // Opcode 3: Write Disable
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte     },     // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte    },     // Opcode 5: Block Erase (32KB)
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus       },     // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((SST_SST25VF064C_SIZE >= FLASH_SIZE) ? SST_SST25VF064C_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  	//
+  	// Minnow2 SPI type
+  	//
+  SF_VENDOR_ID_NUMONYX,     // VendorId
+  SF_DEVICE_ID0_N25Q064,    // DeviceId 0
+  SF_DEVICE_ID1_N25Q064,    // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't support EWSR)
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle20MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle20MHz, EnumSpiOperationReadData      },      // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle20MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read Status Register
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,           EnumSpiCycle20MHz, EnumSpiOperationWriteDisable    },      // Opcode 3: Write Disable
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle20MHz, EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle20MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5: Block Erase (64KB
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle20MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle20MHz, EnumSpiOperationWriteStatus    },      // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((NUMONYX_N25Q064_SIZE >= FLASH_SIZE) ? NUMONYX_N25Q064_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_NUMONYX,     // VendorId
+  SF_DEVICE_ID0_M25PXXX,    // DeviceId 0
+  SF_DEVICE_ID1_M25PX16,    // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't support EWSR).
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle33MHz, EnumSpiOperationReadData      },      // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read Status Register
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,           EnumSpiCycle50MHz, EnumSpiOperationWriteDisable    },      // Opcode 3: Write Disable
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5: Block Erase (64KB
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((NUMONYX_M25PX16_SIZE >= FLASH_SIZE) ? NUMONYX_M25PX16_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_NUMONYX,     // VendorId
+  SF_DEVICE_ID0_N25QXXX,    // DeviceId 0
+  SF_DEVICE_ID1_N25Q032,    // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't support EWSR).
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId      },        // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle33MHz, EnumSpiOperationReadData      },        // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },        // Opcode 2: Read Status Register
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,           EnumSpiCycle50MHz, EnumSpiOperationWriteDisable    },      // Opcode 3: Write Disable
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5: Block Erase (64KB
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},   // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((NUMONYX_N25Q032_SIZE >= FLASH_SIZE) ? NUMONYX_N25Q032_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_NUMONYX,     // VendorId
+  SF_DEVICE_ID0_M25PXXX,    // DeviceId 0
+  SF_DEVICE_ID1_M25PX32,    // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't support EWSR).
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle33MHz, EnumSpiOperationReadData      },      // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read Status Register
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,           EnumSpiCycle50MHz, EnumSpiOperationWriteDisable    },      // Opcode 3: Write Disable
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5: Block Erase (64KB
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((NUMONYX_M25PX32_SIZE >= FLASH_SIZE) ? NUMONYX_M25PX32_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_NUMONYX,     // VendorId
+  SF_DEVICE_ID0_M25PXXX,    // DeviceId 0
+  SF_DEVICE_ID1_M25PX64,    // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't support EWSR)
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle33MHz, EnumSpiOperationReadData      },      // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read Status Register
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,           EnumSpiCycle50MHz, EnumSpiOperationWriteDisable    },      // Opcode 3: Write Disable
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5: Block Erase (64KB
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((NUMONYX_M25PX64_SIZE >= FLASH_SIZE) ? NUMONYX_M25PX64_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_NUMONYX,     // VendorId
+  SF_DEVICE_ID0_N25QXXX,    // DeviceId 0
+  SF_DEVICE_ID1_N25Q128,    // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't support EWSR)
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle33MHz, EnumSpiOperationReadData      },      // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read Status Register
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,           EnumSpiCycle50MHz, EnumSpiOperationWriteDisable    },      // Opcode 3: Write Disable
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5: Block Erase (64KB
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((NUMONYX_N25Q128_SIZE >= FLASH_SIZE) ? NUMONYX_N25Q128_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_EON,         // VendorId
+  SF_DEVICE_ID0_EN25QXX,    // DeviceId 0
+  SF_DEVICE_ID1_EN25Q16,    // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't support EWSR)
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz, EnumSpiOperationReadData      },      // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read Status Register
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,           EnumSpiCycle50MHz, EnumSpiOperationWriteDisable    },      // Opcode 3: Write Disable
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5: Block Erase (64KB
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((EON_EN25Q16_SIZE >= FLASH_SIZE) ? EON_EN25Q16_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_EON,         // VendorId
+  SF_DEVICE_ID0_EN25QXX,    // DeviceId 0
+  SF_DEVICE_ID1_EN25Q32,    // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't support EWSR)
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle33MHz, EnumSpiOperationReadData      },      // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read Status Register
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,           EnumSpiCycle50MHz, EnumSpiOperationWriteDisable    },      // Opcode 3: Write Disable
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5: Block Erase (64KB
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((EON_EN25Q32_SIZE >= FLASH_SIZE) ? EON_EN25Q32_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_EON,         // VendorId
+  SF_DEVICE_ID0_EN25QXX,    // DeviceId 0
+  SF_DEVICE_ID1_EN25Q64,    // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't support EWSR).
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz, EnumSpiOperationReadData      },      // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read Status Register
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,           EnumSpiCycle50MHz, EnumSpiOperationWriteDisable    },      // Opcode 3: Write Disable
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5: Block Erase (64KB
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((EON_EN25Q64_SIZE >= FLASH_SIZE) ? EON_EN25Q64_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_EON,         // VendorId
+  SF_DEVICE_ID0_EN25QXX,    // DeviceId 0
+  SF_DEVICE_ID1_EN25Q128,   // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't support EWSR)
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz, EnumSpiOperationReadData      },      // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read Status Register
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,           EnumSpiCycle50MHz, EnumSpiOperationWriteDisable    },      // Opcode 3: Write Disable
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5: Block Erase (64KB
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((EON_EN25Q128_SIZE >= FLASH_SIZE) ? EON_EN25Q128_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  },
+  {
+  SF_VENDOR_ID_AMIC,        // VendorId
+  SF_DEVICE_ID0_A25L016,    // DeviceId 0
+  SF_DEVICE_ID1_A25L016,    // DeviceId 1
+  {
+    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
+    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't support EWSR)
+  },
+  {
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,  EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
+    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz, EnumSpiOperationReadData      },      // Opcode 1: Read
+    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,           EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read Status Register
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,           EnumSpiCycle50MHz, EnumSpiOperationWriteDisable    },      // Opcode 3: Write Disable
+    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
+    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,     EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5: Block Erase (64KB
+    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
+    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,           EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7: Write Status Register
+  },
+
+  //
+  // The offset of the start of the BIOS image in flash. This value is platform specific
+  // and depends on the system flash map. If BIOS size is bigger than flash return -1.
+  //
+  ((AMIC_A25L16_SIZE >= FLASH_SIZE) ? AMIC_A25L16_SIZE - FLASH_SIZE : (UINTN) (-1)),
+
+  //
+  // The size of the BIOS image in flash. This value is platform specific and depends on the system flash map.
+  //
+  FLASH_SIZE
+  }
+};
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c
new file mode 100644
index 0000000000..85f066a9e3
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c
@@ -0,0 +1,46 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+                                                                                   

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

+
+
+Module Name:
+
+  I2CLib.c
+
+
+
+--*/
+#ifdef ECP_FLAG
+#include "EdkIIGlueDxe.h"
+#else
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+#endif
+#include <PchRegs/PchRegsPcu.h>
+#include <PchRegs.h>
+#include <PlatformBaseAddresses.h>
+#include <PchRegs/PchRegsLpss.h>
+#ifdef ECP_FLAG
+#include "I2CLib.h"
+#else
+#include <Library/I2CLib.h>
+#endif
+#include <Protocol/GlobalNvsArea.h>
+#ifndef ECP_FLAG
+#include <Library/UefiBootServicesTableLib.h>
+#endif
+
+EFI_STATUS ByteReadI2C(
+  IN  UINT8 BusNo,
+  IN  UINT8 SlaveAddress,
+  IN  UINT8 Offset,
+  IN  UINTN ReadBytes,
+  OUT UINT8 *ReadBuffer
+  )
+{
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLibNull.inf b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLibNull.inf
new file mode 100644
index 0000000000..d669a4eaf8
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLibNull.inf
@@ -0,0 +1,39 @@
+## @file
+# Null instance of Debug Agent Library with empty functions.
+#
+#  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = I2CLib
+  FILE_GUID                      = 7f62bf44-2ba7-4c2d-9d4a-91c8906ff053
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = I2CLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources.common]
+  I2CLib.c
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  TimerLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+
+[Protocols]
+  gEfiGlobalNvsAreaProtocolGuid
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLib.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLib.c
new file mode 100644
index 0000000000..104c2ded43
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLib.c
@@ -0,0 +1,735 @@
+/** @file
+  Functions for accessing I2C registers.
+  
+  Copyright (c) 2004  - 2015, Intel Corporation. All rights reserved.<BR>
+                                                                                   
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+                                                                               
+--*/
+
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+#include <PchRegs/PchRegsPcu.h> 
+#include <PchRegs.h>
+#include <PlatformBaseAddresses.h>
+#include <PchRegs/PchRegsLpss.h> 
+#include <Library/I2CLib.h>
+#include <Protocol/GlobalNvsArea.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <I2CRegs.h>
+
+#define GLOBAL_NVS_OFFSET(Field)    (UINTN)((CHAR8*)&((EFI_GLOBAL_NVS_AREA*)0)->Field - (CHAR8*)0)
+
+#define PCIEX_BASE_ADDRESS  0xE0000000
+#define PCI_EXPRESS_BASE_ADDRESS ((VOID *) (UINTN) PCIEX_BASE_ADDRESS)
+#define MmPciAddress( Segment, Bus, Device, Function, Register ) \
+         ((UINTN)PCI_EXPRESS_BASE_ADDRESS + \
+         (UINTN)(Bus << 20) + \
+         (UINTN)(Device << 15) + \
+         (UINTN)(Function << 12) + \
+         (UINTN)(Register) \
+        )
+#define PCI_D31F0_REG_BASE             PCIEX_BASE_ADDRESS + (UINT32) (31 << 15)
+
+typedef struct _LPSS_PCI_DEVICE_INFO {
+  UINTN        Segment;
+  UINTN        BusNum;
+  UINTN        DeviceNum;
+  UINTN        FunctionNum;
+  UINTN        Bar0;
+  UINTN        Bar1;
+} LPSS_PCI_DEVICE_INFO;
+
+LPSS_PCI_DEVICE_INFO  mLpssPciDeviceList[] = {
+  {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_DMAC1, PCI_FUNCTION_NUMBER_PCH_LPSS_DMAC, 0xFE900000, 0xFE908000},
+  {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C,   PCI_FUNCTION_NUMBER_PCH_LPSS_I2C0, 0xFE910000, 0xFE918000},
+  {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C,   PCI_FUNCTION_NUMBER_PCH_LPSS_I2C1, 0xFE920000, 0xFE928000},
+  {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C,   PCI_FUNCTION_NUMBER_PCH_LPSS_I2C2, 0xFE930000, 0xFE938000},
+  {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C,   PCI_FUNCTION_NUMBER_PCH_LPSS_I2C3, 0xFE940000, 0xFE948000},
+  {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C,   PCI_FUNCTION_NUMBER_PCH_LPSS_I2C4, 0xFE950000, 0xFE958000},
+  {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C,   PCI_FUNCTION_NUMBER_PCH_LPSS_I2C5, 0xFE960000, 0xFE968000},
+  {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C,   PCI_FUNCTION_NUMBER_PCH_LPSS_I2C6, 0xFE970000, 0xFE978000}
+};
+
+#define LPSS_PCI_DEVICE_NUMBER  sizeof(mLpssPciDeviceList)/sizeof(LPSS_PCI_DEVICE_INFO)
+
+STATIC UINTN mI2CBaseAddress = 0;
+STATIC UINT16 mI2CSlaveAddress = 0;
+
+UINT16 mI2cMode=B_IC_RESTART_EN | B_IC_SLAVE_DISABLE | B_MASTER_MODE ;
+
+UINTN mI2cNvsBaseAddress[] = {
+        GLOBAL_NVS_OFFSET(LDMA2Addr),
+        GLOBAL_NVS_OFFSET(I2C1Addr),
+        GLOBAL_NVS_OFFSET(I2C2Addr),
+        GLOBAL_NVS_OFFSET(I2C3Addr),
+        GLOBAL_NVS_OFFSET(I2C4Addr),
+        GLOBAL_NVS_OFFSET(I2C5Addr),
+        GLOBAL_NVS_OFFSET(I2C6Addr),
+        GLOBAL_NVS_OFFSET(I2C7Addr)
+      };
+
+/**
+  This function get I2Cx controller base address (BAR0).
+
+  @param I2cControllerIndex  Bus Number of I2C controller.
+
+  @return I2C BAR. 
+**/
+UINTN
+GetI2cBarAddr(
+  IN    UINT8 I2cControllerIndex
+  )
+{
+  EFI_STATUS           Status;
+  EFI_GLOBAL_NVS_AREA_PROTOCOL  *GlobalNvsArea;
+  UINTN  AcpiBaseAddr;
+  UINTN  PciMmBase=0;
+
+  ASSERT(gBS!=NULL);
+
+  Status = gBS->LocateProtocol (
+                  &gEfiGlobalNvsAreaProtocolGuid,
+                  NULL,
+                  &GlobalNvsArea
+                  );
+                  
+  //
+  // PCI mode from PEI ( Global NVS is not ready).
+  //
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_INFO, "GetI2cBarAddr() gEfiGlobalNvsAreaProtocolGuid:%r\n", Status));
+    //
+    // Global NVS is not ready.
+    //
+    return 0;
+  }
+
+  AcpiBaseAddr =  *(UINTN*)((CHAR8*)GlobalNvsArea->Area + mI2cNvsBaseAddress[I2cControllerIndex + 1]);
+  
+  //
+  //PCI mode from DXE (global NVS protocal) to LPSS OnReadytoBoot(swith to ACPI).
+  //
+  if(AcpiBaseAddr==0) {
+    PciMmBase = MmPciAddress (
+                  mLpssPciDeviceList[I2cControllerIndex + 1].Segment,
+                  mLpssPciDeviceList[I2cControllerIndex + 1].BusNum,
+                  mLpssPciDeviceList[I2cControllerIndex + 1].DeviceNum,
+                  mLpssPciDeviceList[I2cControllerIndex + 1].FunctionNum,
+                  0
+                  );
+    DEBUG((EFI_D_ERROR, "\nGetI2cBarAddr() I2C Device %x %x %x PciMmBase:%x\n", \
+           mLpssPciDeviceList[I2cControllerIndex + 1].BusNum, \
+           mLpssPciDeviceList[I2cControllerIndex + 1].DeviceNum, \
+           mLpssPciDeviceList[I2cControllerIndex + 1].FunctionNum, PciMmBase));
+
+    if (MmioRead32 (PciMmBase) != 0xFFFFFFFF)    {
+      if((MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_STSCMD)& B_PCH_LPSS_I2C_STSCMD_MSE)) {
+        //
+        // Get the address allocted.
+        //
+        mLpssPciDeviceList[I2cControllerIndex + 1].Bar0=MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR);     
+        mLpssPciDeviceList[I2cControllerIndex + 1].Bar1=MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR1);
+      }
+    }
+    AcpiBaseAddr =mLpssPciDeviceList[I2cControllerIndex+1].Bar0;
+  }
+  
+  //
+  // ACPI mode from BDS: LPSS OnReadytoBoot
+  //
+  else {
+    DEBUG ((EFI_D_INFO, "GetI2cBarAddr() NVS Varialable is updated by this LIB or LPSS  \n"));
+  }
+  
+  DEBUG ((EFI_D_INFO, "GetI2cBarAddr() I2cControllerIndex+1 0x%x AcpiBaseAddr:0x%x \n", (I2cControllerIndex + 1), AcpiBaseAddr));
+  return AcpiBaseAddr;
+}
+
+
+/**
+  This function enables I2C controllers.
+
+  @param I2cControllerIndex  Bus Number of I2C controllers.
+
+  @return Result of the I2C initialization.
+**/
+EFI_STATUS
+ProgramPciLpssI2C (
+  IN  UINT8 I2cControllerIndex
+  )
+{
+  UINT32                        PmcBase;
+  UINTN                         PciMmBase=0;
+  EFI_STATUS                    Status;
+  EFI_GLOBAL_NVS_AREA_PROTOCOL  *GlobalNvsArea;
+
+  UINT32 PmcFunctionDsiable[]= {
+    B_PCH_PMC_FUNC_DIS_LPSS2_FUNC1,
+    B_PCH_PMC_FUNC_DIS_LPSS2_FUNC2,
+    B_PCH_PMC_FUNC_DIS_LPSS2_FUNC3,
+    B_PCH_PMC_FUNC_DIS_LPSS2_FUNC4,
+    B_PCH_PMC_FUNC_DIS_LPSS2_FUNC5,
+    B_PCH_PMC_FUNC_DIS_LPSS2_FUNC6,
+    B_PCH_PMC_FUNC_DIS_LPSS2_FUNC7
+  };
+
+  DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() Start\n"));
+
+  //
+  // Set the VLV Function Disable Register to ZERO
+  //
+  PmcBase = MmioRead32 (PCI_D31F0_REG_BASE + R_PCH_LPC_PMC_BASE) & B_PCH_LPC_PMC_BASE_BAR;
+  if(MmioRead32(PmcBase+R_PCH_PMC_FUNC_DIS)&PmcFunctionDsiable[I2cControllerIndex]) {
+    DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() End:I2C[%x] is disabled\n",I2cControllerIndex));
+    return EFI_NOT_READY;
+  }
+  
+  DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C()------------I2cControllerIndex=%x,PMC=%x\n",I2cControllerIndex,MmioRead32(PmcBase+R_PCH_PMC_FUNC_DIS)));
+
+  {
+    PciMmBase = MmPciAddress (
+                  mLpssPciDeviceList[I2cControllerIndex+1].Segment,
+                  mLpssPciDeviceList[I2cControllerIndex+1].BusNum,
+                  mLpssPciDeviceList[I2cControllerIndex+1].DeviceNum,
+                  mLpssPciDeviceList[I2cControllerIndex+1].FunctionNum,
+                  0
+                  );
+                  
+    DEBUG((EFI_D_ERROR, "Program Pci Lpss I2C Device  %x %x %x PciMmBase:%x\n", \
+           mLpssPciDeviceList[I2cControllerIndex+1].BusNum, \
+           mLpssPciDeviceList[I2cControllerIndex+1].DeviceNum, \
+           mLpssPciDeviceList[I2cControllerIndex+1].FunctionNum, PciMmBase));
+
+    if (MmioRead32 (PciMmBase) != 0xFFFFFFFF)     {
+      if((MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_STSCMD)& B_PCH_LPSS_I2C_STSCMD_MSE)) {
+        //
+        // Get the address allocted.
+        //
+        mLpssPciDeviceList[I2cControllerIndex+1].Bar0=MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR);     
+        mLpssPciDeviceList[I2cControllerIndex+1].Bar1=MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR1);
+        DEBUG((EFI_D_ERROR, "ProgramPciLpssI2C() bar0:0x%x bar1:0x%x\n",mLpssPciDeviceList[I2cControllerIndex+1].Bar0, mLpssPciDeviceList[I2cControllerIndex+1].Bar1));
+      } else {
+        
+        //
+        // Program BAR 0
+        //
+        ASSERT (((mLpssPciDeviceList[I2cControllerIndex+1].Bar0 & B_PCH_LPSS_I2C_BAR_BA) == mLpssPciDeviceList[I2cControllerIndex+1].Bar0) && (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 != 0));
+        MmioWrite32 ((UINTN) (PciMmBase + R_PCH_LPSS_I2C_BAR), (UINT32) (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 & B_PCH_LPSS_I2C_BAR_BA));
+       
+        //
+        // Program BAR 1
+        //
+        ASSERT (((mLpssPciDeviceList[I2cControllerIndex+1].Bar1 & B_PCH_LPSS_I2C_BAR1_BA) == mLpssPciDeviceList[I2cControllerIndex+1].Bar1) && (mLpssPciDeviceList[I2cControllerIndex+1].Bar1 != 0));
+        MmioWrite32 ((UINTN) (PciMmBase + R_PCH_LPSS_I2C_BAR1), (UINT32) (mLpssPciDeviceList[I2cControllerIndex+1].Bar1 & B_PCH_LPSS_I2C_BAR1_BA));
+        
+        //
+        // Bus Master Enable & Memory Space Enable
+        //
+        MmioOr32 ((UINTN) (PciMmBase + R_PCH_LPSS_I2C_STSCMD), (UINT32) (B_PCH_LPSS_I2C_STSCMD_BME | B_PCH_LPSS_I2C_STSCMD_MSE));
+        ASSERT (MmioRead32 (mLpssPciDeviceList[I2cControllerIndex+1].Bar0) != 0xFFFFFFFF);
+      }
+      
+      //
+      // Release Resets
+      //
+      MmioWrite32 (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 + R_PCH_LPIO_I2C_MEM_RESETS,(B_PCH_LPIO_I2C_MEM_RESETS_FUNC | B_PCH_LPIO_I2C_MEM_RESETS_APB));
+      
+      //
+      // Activate Clocks
+      //
+      MmioWrite32 (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 + R_PCH_LPSS_I2C_MEM_PCP,0x80020003);//No use for A0
+
+      DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() Programmed()\n"));
+    }
+    
+    //
+    // BDS: already switched to ACPI mode
+    //
+    else {
+      ASSERT(gBS!=NULL);
+      Status = gBS->LocateProtocol (
+                      &gEfiGlobalNvsAreaProtocolGuid,
+                      NULL,
+                      &GlobalNvsArea
+                      );
+      if (EFI_ERROR(Status)) {
+        DEBUG ((EFI_D_INFO, "GetI2cBarAddr() gEfiGlobalNvsAreaProtocolGuid:%r\n", Status));
+        //
+        // gEfiGlobalNvsAreaProtocolGuid is not ready.
+        //
+        return 0;
+      }
+      mLpssPciDeviceList[I2cControllerIndex + 1].Bar0 = *(UINTN*)((CHAR8*)GlobalNvsArea->Area + mI2cNvsBaseAddress[I2cControllerIndex + 1]);
+      DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C(): is switched to ACPI 0x:%x \n",mLpssPciDeviceList[I2cControllerIndex + 1].Bar0));
+    }
+  }
+  
+  DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() End\n"));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Disable I2C Bus.
+
+  @param VOID.
+
+  @return Result of the I2C disabling.
+**/
+RETURN_STATUS
+I2cDisable (
+  VOID
+  )
+{ 
+  //
+  // 0.1 seconds
+  //
+  UINT32 NumTries = 10000;
+  
+  MmioWrite32 ( mI2CBaseAddress + R_IC_ENABLE, 0 );
+  while ( 0 != ( MmioRead32 ( mI2CBaseAddress + R_IC_ENABLE_STATUS) & 1)) {
+    MicroSecondDelay (10);
+    NumTries --;
+    if(0 == NumTries) {
+      return RETURN_NOT_READY;
+    }
+  }
+  
+  return RETURN_SUCCESS;
+}
+
+/**
+  Enable I2C Bus.
+
+  @param VOID.
+
+  @return Result of the I2C disabling.
+**/
+RETURN_STATUS
+I2cEnable (
+  VOID
+  )
+{
+  //
+  // 0.1 seconds
+  //
+  UINT32 NumTries = 10000;
+  
+  MmioWrite32 (mI2CBaseAddress + R_IC_ENABLE, 1);
+  
+  while (0 == (MmioRead32 (mI2CBaseAddress + R_IC_ENABLE_STATUS) & 1)) {
+    MicroSecondDelay (10);
+    NumTries --;
+    if(0 == NumTries){
+       return RETURN_NOT_READY;
+    }
+  }
+  
+  return RETURN_SUCCESS;
+}
+
+/**
+  Enable I2C Bus.
+
+  @param VOID.
+
+  @return Result of the I2C enabling.
+**/
+RETURN_STATUS
+I2cBusFrequencySet (
+  IN UINTN BusClockHertz
+  )
+{
+  DEBUG((EFI_D_INFO,"InputFreq BusClockHertz: %d\r\n",BusClockHertz));
+  
+  //
+  //  Set the 100 KHz clock divider according to SV result and I2C spec
+  //
+  MmioWrite32 ( mI2CBaseAddress + R_IC_SS_SCL_HCNT, (UINT16)0x214 );
+  MmioWrite32 ( mI2CBaseAddress + R_IC_SS_SCL_LCNT, (UINT16)0x272 );
+  
+  //
+  //  Set the 400 KHz clock divider according to SV result and I2C spec
+  //
+  MmioWrite32 ( mI2CBaseAddress + R_IC_FS_SCL_HCNT, (UINT16)0x50 );
+  MmioWrite32 ( mI2CBaseAddress + R_IC_FS_SCL_LCNT, (UINT16)0xAD );
+
+  switch ( BusClockHertz ) {
+    case 100 * 1000:
+      MmioWrite32 ( mI2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x40);//100K
+      mI2cMode = V_SPEED_STANDARD;
+      break;
+    case 400 * 1000:
+      MmioWrite32 ( mI2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x32);//400K
+      mI2cMode = V_SPEED_FAST;
+      break;
+    default:
+      MmioWrite32 ( mI2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x09);//3.4M
+      mI2cMode = V_SPEED_HIGH;
+  }
+
+  //
+  //  Select the frequency counter,
+  //  Enable restart condition,
+  //  Enable master FSM, disable slave FSM.
+  //
+  mI2cMode |= B_IC_RESTART_EN | B_IC_SLAVE_DISABLE | B_MASTER_MODE;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Initializes the host controller to execute I2C commands.
+
+  @param I2cControllerIndex Index of I2C controller in LPSS device. 0 represents I2C0, which is PCI function 1 of LPSS device.   
+                                
+  @return EFI_SUCCESS       Opcode initialization on the I2C host controller completed.
+  @return EFI_DEVICE_ERROR  Device error, operation failed.
+**/
+EFI_STATUS
+I2CInit (
+  IN  UINT8  I2cControllerIndex,
+  IN  UINT16 SlaveAddress
+  )
+{
+  EFI_STATUS Status=RETURN_SUCCESS;
+  UINT32    NumTries = 0;
+  UINTN    GnvsI2cBarAddr=0;
+  
+  //
+  // Verify the parameters
+  //
+  if ((1023 < SlaveAddress) || (6 < I2cControllerIndex)) {
+    Status =  RETURN_INVALID_PARAMETER;
+    DEBUG((EFI_D_INFO,"I2CInit Exit with RETURN_INVALID_PARAMETER\r\n"));
+    return Status;
+  }
+  MmioWrite32 ( mI2CBaseAddress + R_IC_TAR, (UINT16)SlaveAddress );
+  mI2CSlaveAddress = SlaveAddress;
+
+  //
+  // 1.PEI: program and init ( before pci enumeration).
+  // 2.DXE:update address and re-init ( after pci enumeration).
+  // 3.BDS:update ACPI address and re-init ( after acpi mode is enabled).
+  //
+  if(mI2CBaseAddress == mLpssPciDeviceList[I2cControllerIndex + 1].Bar0) {
+    
+    //
+    // I2CInit is already  called.
+    //
+    GnvsI2cBarAddr=GetI2cBarAddr(I2cControllerIndex);
+    
+    if((GnvsI2cBarAddr == 0)||(GnvsI2cBarAddr == mI2CBaseAddress)) {
+      DEBUG((EFI_D_INFO,"I2CInit Exit with mI2CBaseAddress:%x == [%x].Bar0\r\n",mI2CBaseAddress,I2cControllerIndex+1));
+      return RETURN_SUCCESS;
+    }
+  }
+  
+  Status=ProgramPciLpssI2C(I2cControllerIndex);
+  if(Status!=EFI_SUCCESS) {
+    return Status;
+  }
+
+
+  mI2CBaseAddress = (UINT32) mLpssPciDeviceList[I2cControllerIndex + 1].Bar0;
+  DEBUG ((EFI_D_ERROR, "mI2CBaseAddress = 0x%x \n",mI2CBaseAddress));
+  
+  //
+  // 1 seconds.
+  //
+  NumTries = 10000; 
+  while ((1 == ( MmioRead32 ( mI2CBaseAddress + R_IC_STATUS) & STAT_MST_ACTIVITY ))) {
+    MicroSecondDelay(10);
+    NumTries --;
+    if(0 == NumTries) {
+      DEBUG((EFI_D_INFO, "Try timeout\r\n"));
+      return RETURN_DEVICE_ERROR;
+    }
+  }
+  
+  Status = I2cDisable();
+  DEBUG((EFI_D_INFO, "I2cDisable Status = %r\r\n", Status));
+  I2cBusFrequencySet(400 * 1000);
+
+  MmioWrite32(mI2CBaseAddress + R_IC_INTR_MASK, 0x0);
+  if (0x7f < SlaveAddress )
+    SlaveAddress = ( SlaveAddress & 0x3ff ) | IC_TAR_10BITADDR_MASTER;
+  MmioWrite32 ( mI2CBaseAddress + R_IC_TAR, (UINT16)SlaveAddress );
+  MmioWrite32 ( mI2CBaseAddress + R_IC_RX_TL, 0);
+  MmioWrite32 ( mI2CBaseAddress + R_IC_TX_TL, 0 );
+  MmioWrite32 ( mI2CBaseAddress + R_IC_CON, mI2cMode);
+  Status = I2cEnable();
+
+  DEBUG((EFI_D_INFO, "I2cEnable Status = %r\r\n", Status));
+  MmioRead32 ( mI2CBaseAddress + R_IC_CLR_TX_ABRT );
+  
+  return EFI_SUCCESS;
+}
+
+/**
+  Reads a Byte from I2C Device.
+ 
+  @param  I2cControllerIndex             I2C Bus no to which the I2C device has been connected
+  @param  SlaveAddress      Device Address from which the byte value has to be read
+  @param  Offset            Offset from which the data has to be read
+  @param  *Byte             Address to which the value read has to be stored
+  @param  Start               Whether a RESTART is issued before the byte is sent or received
+  @param  End                 Whether STOP is generated after a data byte is sent or received  
+                                  
+  @return  EFI_SUCCESS       IF the byte value has been successfully read
+  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
+**/
+EFI_STATUS 
+ByteReadI2CBasic(
+  IN  UINT8 I2cControllerIndex,
+  IN  UINT8 SlaveAddress,
+  IN  UINTN ReadBytes,
+  OUT UINT8 *ReadBuffer,
+  IN  UINT8 Start,
+  IN  UINT8 End
+  )
+{
+
+  EFI_STATUS Status;
+  UINT32 I2cStatus;
+  UINT16 ReceiveData;
+  UINT8 *ReceiveDataEnd;
+  UINT8 *ReceiveRequest;
+  UINT16 RawIntrStat;
+  UINT32 Count=0;
+
+  Status = EFI_SUCCESS;
+
+  ReceiveDataEnd = &ReadBuffer [ReadBytes];
+  if( ReadBytes ) {
+
+    ReceiveRequest = ReadBuffer;
+    DEBUG((EFI_D_INFO,"Read: ---------------%d bytes to RX\r\n",ReceiveDataEnd - ReceiveRequest));
+
+    while ((ReceiveDataEnd > ReceiveRequest) || (ReceiveDataEnd > ReadBuffer)) {
+      
+      //
+      //  Check for NACK
+      //
+      RawIntrStat = (UINT16)MmioRead32 (mI2CBaseAddress + R_IC_RawIntrStat);
+      if ( 0 != ( RawIntrStat & I2C_INTR_TX_ABRT )) {
+        MmioRead32 ( mI2CBaseAddress + R_IC_CLR_TX_ABRT );
+        Status = RETURN_DEVICE_ERROR;
+        DEBUG((EFI_D_INFO,"TX ABRT ,%d bytes hasn't been transferred\r\n",ReceiveDataEnd - ReceiveRequest));
+        break;
+      }
+      
+      //
+      // Determine if another byte was received
+      //
+      I2cStatus = (UINT16)MmioRead32 (mI2CBaseAddress + R_IC_STATUS);
+      if (0 != ( I2cStatus & STAT_RFNE )) {
+        ReceiveData = (UINT16)MmioRead32 ( mI2CBaseAddress + R_IC_DATA_CMD );
+        *ReadBuffer++ = (UINT8)ReceiveData;
+        DEBUG((EFI_D_INFO,"MmioRead32 ,1 byte 0x:%x is received\r\n",ReceiveData));
+      }
+
+      if(ReceiveDataEnd == ReceiveRequest) {
+        MicroSecondDelay ( FIFO_WRITE_DELAY );
+        DEBUG((EFI_D_INFO,"ReceiveDataEnd==ReceiveRequest------------%x\r\n",I2cStatus & STAT_RFNE));
+        Count++;
+        if(Count<1024) {
+          //
+          // To avoid sys hung  without ul-pmc device  on RVP,
+          // waiting the last request to get data and make (ReceiveDataEnd > ReadBuffer) =TRUE.
+          //
+          continue;
+        } else {
+          break;
+        }
+      }
+      
+      //
+      //  Wait until a read request will fit.
+      //
+      if (0 == (I2cStatus & STAT_TFNF)) {
+        DEBUG((EFI_D_INFO,"Wait until a read request will fit\r\n"));
+        MicroSecondDelay (10);
+        continue;
+      }
+      
+      //
+      //  Issue the next read request.
+      //
+      if(End && Start) {
+        MmioWrite32 ( mI2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD|B_CMD_RESTART|B_CMD_STOP);
+      } else if (!End && Start) {
+        MmioWrite32 ( mI2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD|B_CMD_RESTART);
+      } else if (End && !Start) {
+        MmioWrite32 ( mI2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD|B_CMD_STOP);
+      } else if (!End && !Start) {
+        MmioWrite32 ( mI2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD);
+      }
+      MicroSecondDelay (FIFO_WRITE_DELAY);
+
+      ReceiveRequest += 1;
+    }
+  }
+  
+  return Status;
+}
+
+/**
+  Writes a Byte to I2C Device.
+ 
+  @param  I2cControllerIndex   I2C Bus no to which the I2C device has been connected
+  @param  SlaveAddress         Device Address from which the byte value has to be written
+  @param  Offset               Offset from which the data has to be read
+  @param  *Byte                Address to which the value written is stored
+  @param  Start               Whether a RESTART is issued before the byte is sent or received
+  @param  End                 Whether STOP is generated after a data byte is sent or received  
+                                    
+  @return  EFI_SUCCESS         IF the byte value has been successfully written
+  @return  EFI_DEVICE_ERROR    Operation Failed, Device Error
+**/
+EFI_STATUS ByteWriteI2CBasic(
+  IN  UINT8 I2cControllerIndex,
+  IN  UINT8 SlaveAddress,
+  IN  UINTN WriteBytes,
+  IN  UINT8 *WriteBuffer,
+  IN  UINT8 Start,
+  IN  UINT8 End
+  )
+{
+
+  EFI_STATUS Status;
+  UINT32 I2cStatus;
+  UINT8 *TransmitEnd;
+  UINT16 RawIntrStat;
+  UINT32 Count=0;
+
+  Status = EFI_SUCCESS;
+
+  Status=I2CInit(I2cControllerIndex, SlaveAddress);
+  if(Status!=EFI_SUCCESS)
+    return Status;
+
+  TransmitEnd = &WriteBuffer[WriteBytes];
+  if( WriteBytes ) {
+    DEBUG((EFI_D_INFO,"Write: --------------%d bytes to TX\r\n",TransmitEnd - WriteBuffer));
+    while (TransmitEnd > WriteBuffer) {
+      I2cStatus = MmioRead32 (mI2CBaseAddress + R_IC_STATUS);
+      RawIntrStat = (UINT16)MmioRead32 (mI2CBaseAddress + R_IC_RawIntrStat);
+      if (0 != ( RawIntrStat & I2C_INTR_TX_ABRT)) {
+        MmioRead32 ( mI2CBaseAddress + R_IC_CLR_TX_ABRT);
+        Status = RETURN_DEVICE_ERROR;
+        DEBUG((EFI_D_ERROR,"TX ABRT TransmitEnd:0x%x WriteBuffer:0x%x\r\n", TransmitEnd, WriteBuffer));
+        break;
+      }
+      if (0 == (I2cStatus & STAT_TFNF)) {
+        //
+        // If TX not full , will  send cmd  or continue to wait
+        //
+        MicroSecondDelay (FIFO_WRITE_DELAY);
+        continue;
+      }
+
+      if(End && Start) {
+        MmioWrite32 (mI2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++)|B_CMD_RESTART|B_CMD_STOP);
+      } else if (!End && Start) {
+        MmioWrite32 (mI2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++)|B_CMD_RESTART);
+      } else if (End && !Start) {
+        MmioWrite32 (mI2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++)|B_CMD_STOP);
+      } else if (!End && !Start ) {
+        MmioWrite32 (mI2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++));
+      }
+      
+      //
+      // Add a small delay to work around some odd behavior being seen.  Without this delay bytes get dropped.
+      //
+      MicroSecondDelay ( FIFO_WRITE_DELAY );//wait after send cmd
+      
+      //
+      // Time out
+      //
+      while(1) {
+        RawIntrStat = MmioRead16 ( mI2CBaseAddress + R_IC_RawIntrStat );
+        if (0 != ( RawIntrStat & I2C_INTR_TX_ABRT)) {
+          MmioRead16 (mI2CBaseAddress + R_IC_CLR_TX_ABRT);
+          Status = RETURN_DEVICE_ERROR;
+          DEBUG((EFI_D_ERROR,"TX ABRT TransmitEnd:0x%x WriteBuffer:0x%x\r\n", TransmitEnd, WriteBuffer));
+        }
+        if(0 == MmioRead16(mI2CBaseAddress + R_IC_TXFLR)) break;
+
+        MicroSecondDelay (FIFO_WRITE_DELAY);
+        Count++;
+        if(Count<1024) {
+          //
+          // to avoid sys hung without ul-pmc device on RVP.
+          // Waiting the last request to get data and make (ReceiveDataEnd > ReadBuffer) =TRUE.
+          //
+          continue;
+        } else {
+          break;
+        }
+      }//while( 1 )
+    }
+
+  }
+
+  return Status;
+}
+
+/**
+  Reads a Byte from I2C Device.
+ 
+  @param  I2cControllerIndex   I2C Bus no to which the I2C device has been connected
+  @param  SlaveAddress         Device Address from which the byte value has to be read
+  @param  Offset               Offset from which the data has to be read
+  @param  ReadBytes            Number of bytes to be read
+  @param  *ReadBuffer          Address to which the value read has to be stored
+                                
+  @return  EFI_SUCCESS       IF the byte value has been successfully read
+  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
+**/
+EFI_STATUS ByteReadI2C(
+  IN  UINT8 I2cControllerIndex,
+  IN  UINT8 SlaveAddress,
+  IN  UINT8 Offset,
+  IN  UINTN ReadBytes,
+  OUT UINT8 *ReadBuffer
+  )
+{
+  EFI_STATUS          Status;
+
+  DEBUG ((EFI_D_INFO, "ByteReadI2C:---offset:0x%x\n",Offset));
+  Status = ByteWriteI2CBasic(I2cControllerIndex, SlaveAddress,1,&Offset,TRUE,FALSE);
+  Status = ByteReadI2CBasic(I2cControllerIndex, SlaveAddress,ReadBytes,ReadBuffer,TRUE,TRUE);
+
+  return Status;
+}
+
+/**
+  Writes a Byte to I2C Device.
+ 
+  @param  I2cControllerIndex  I2C Bus no to which the I2C device has been connected
+  @param  SlaveAddress        Device Address from which the byte value has to be written
+  @param  Offset              Offset from which the data has to be written
+  @param  WriteBytes          Number of bytes to be written
+  @param  *Byte               Address to which the value written is stored
+                                
+  @return  EFI_SUCCESS       IF the byte value has been successfully read
+  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
+**/
+EFI_STATUS ByteWriteI2C(
+  IN  UINT8 I2cControllerIndex,
+  IN  UINT8 SlaveAddress,
+  IN  UINT8 Offset,
+  IN  UINTN WriteBytes,
+  IN  UINT8 *WriteBuffer
+  )
+{
+  EFI_STATUS          Status;
+
+  DEBUG ((EFI_D_INFO, "ByteWriteI2C:---offset/bytes/buf:0x%x,0x%x,0x%x,0x%x\n",Offset,WriteBytes,WriteBuffer,*WriteBuffer));
+  Status = ByteWriteI2CBasic(I2cControllerIndex, SlaveAddress,1,&Offset,TRUE,FALSE);
+  Status = ByteWriteI2CBasic(I2cControllerIndex, SlaveAddress,WriteBytes,WriteBuffer,FALSE,TRUE);
+
+  return Status;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLibDxe.inf b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLibDxe.inf
new file mode 100644
index 0000000000..cd10f1de93
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLibDxe.inf
@@ -0,0 +1,39 @@
+## @file
+#  Instance of I2C Library.
+#
+#  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = I2CLib
+  FILE_GUID                      = 7f62bf44-2ba7-4c2d-9d4a-91c8906ff053
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = I2CLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION
+  
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources.common]
+  I2CLib.c
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  TimerLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+
+[Protocols]
+  gEfiGlobalNvsAreaProtocolGuid
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CRegs.h b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CRegs.h
new file mode 100644
index 0000000000..57455162f6
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CRegs.h
@@ -0,0 +1,126 @@
+/** @file
+  Register Definitions for I2C Driver/PEIM.
+  
+  Copyright (c) 2004  - 2015, Intel Corporation. All rights reserved.<BR>
+                                                                                   
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+                                                                               
+--*/
+
+#ifndef I2C_REGS_H
+#define I2C_REGS_H
+
+//
+// FIFO write delay value.
+//
+#define FIFO_WRITE_DELAY    2
+
+//
+// MMIO Register Definitions.
+//
+#define    R_IC_CON                          ( 0x00) // I2C Control  
+#define     B_IC_RESTART_EN                  BIT5
+#define     B_IC_SLAVE_DISABLE               BIT6
+#define     V_SPEED_STANDARD                 0x02
+#define     V_SPEED_FAST                     0x04
+#define     V_SPEED_HIGH                     0x06
+#define     B_MASTER_MODE                    BIT0
+
+#define    R_IC_TAR                          ( 0x04) // I2C Target Address
+#define     IC_TAR_10BITADDR_MASTER           BIT12
+
+#define    R_IC_SAR                          ( 0x08) // I2C Slave Address
+#define    R_IC_HS_MADDR                     ( 0x0C) // I2C HS MasterMode Code Address
+#define    R_IC_DATA_CMD                     ( 0x10) // I2C Rx/Tx Data Buffer and Command
+
+#define    B_READ_CMD                         BIT8    // 1 = read, 0 = write
+#define    B_CMD_STOP                         BIT9    // 1 = STOP
+#define    B_CMD_RESTART                      BIT10   // 1 = IC_RESTART_EN
+
+#define    V_WRITE_CMD_MASK                  ( 0xFF)
+
+#define    R_IC_SS_SCL_HCNT                  ( 0x14) // Standard Speed I2C Clock SCL High Count
+#define    R_IC_SS_SCL_LCNT                  ( 0x18) // Standard Speed I2C Clock SCL Low Count
+#define    R_IC_FS_SCL_HCNT                  ( 0x1C) // Full Speed I2C Clock SCL High Count
+#define    R_IC_FS_SCL_LCNT                  ( 0x20) // Full Speed I2C Clock SCL Low Count
+#define    R_IC_HS_SCL_HCNT                  ( 0x24) // High Speed I2C Clock SCL High Count
+#define    R_IC_HS_SCL_LCNT                  ( 0x28) // High Speed I2C Clock SCL Low Count
+#define    R_IC_INTR_STAT                    ( 0x2C) // I2C Inetrrupt Status
+#define    R_IC_INTR_MASK                    ( 0x30) // I2C Interrupt Mask
+#define     I2C_INTR_GEN_CALL                 BIT11  // General call received
+#define     I2C_INTR_START_DET                BIT10
+#define     I2C_INTR_STOP_DET                 BIT9
+#define     I2C_INTR_ACTIVITY                 BIT8
+#define     I2C_INTR_TX_ABRT                  BIT6   // Set on NACK
+#define     I2C_INTR_TX_EMPTY                 BIT4
+#define     I2C_INTR_TX_OVER                  BIT3
+#define     I2C_INTR_RX_FULL                  BIT2   // Data bytes in RX FIFO over threshold
+#define     I2C_INTR_RX_OVER                  BIT1
+#define     I2C_INTR_RX_UNDER                 BIT0
+#define    R_IC_RawIntrStat                ( 0x34) // I2C Raw Interrupt Status
+#define    R_IC_RX_TL                        ( 0x38) // I2C Receive FIFO Threshold
+#define    R_IC_TX_TL                        ( 0x3C) // I2C Transmit FIFO Threshold
+#define    R_IC_CLR_INTR                     ( 0x40) // Clear Combined and Individual Interrupts
+#define    R_IC_CLR_RX_UNDER                 ( 0x44) // Clear RX_UNDER Interrupt
+#define    R_IC_CLR_RX_OVER                  ( 0x48) // Clear RX_OVERinterrupt
+#define    R_IC_CLR_TX_OVER                  ( 0x4C) // Clear TX_OVER interrupt
+#define    R_IC_CLR_RD_REQ                   ( 0x50) // Clear RD_REQ interrupt
+#define    R_IC_CLR_TX_ABRT                  ( 0x54) // Clear TX_ABRT interrupt
+#define    R_IC_CLR_RX_DONE                  ( 0x58) // Clear RX_DONE interrupt
+#define    R_IC_CLR_ACTIVITY                 ( 0x5C) // Clear ACTIVITY interrupt
+#define    R_IC_CLR_STOP_DET                 ( 0x60) // Clear STOP_DET interrupt
+#define    R_IC_CLR_START_DET                ( 0x64) // Clear START_DET interrupt
+#define    R_IC_CLR_GEN_CALL                 ( 0x68) // Clear GEN_CALL interrupt
+#define    R_IC_ENABLE                       ( 0x6C) // I2C Enable
+#define    R_IC_STATUS                       ( 0x70) // I2C Status
+
+#define    R_IC_SDA_HOLD                     ( 0x7C) // I2C IC_DEFAULT_SDA_HOLD//16bits
+
+#define     STAT_MST_ACTIVITY                 BIT5   // Master FSM Activity Status.
+#define     STAT_RFF                          BIT4   // RX FIFO is completely full
+#define     STAT_RFNE                         BIT3   // RX FIFO is not empty
+#define     STAT_TFE                          BIT2   // TX FIFO is completely empty
+#define     STAT_TFNF                         BIT1   // TX FIFO is not full
+
+#define    R_IC_TXFLR                        ( 0x74) // Transmit FIFO Level Register
+#define    R_IC_RXFLR                        ( 0x78) // Receive FIFO Level Register
+#define    R_IC_TX_ABRT_SOURCE               ( 0x80) // I2C Transmit Abort Status Register
+#define    R_IC_SLV_DATA_NACK_ONLY           ( 0x84) // Generate SLV_DATA_NACK Register
+#define    R_IC_DMA_CR                       ( 0x88) // DMA Control Register
+#define    R_IC_DMA_TDLR                     ( 0x8C) // DMA Transmit Data Level
+#define    R_IC_DMA_RDLR                     ( 0x90) // DMA Receive Data Level
+#define    R_IC_SDA_SETUP                    ( 0x94) // I2C SDA Setup Register
+#define    R_IC_ACK_GENERAL_CALL             ( 0x98) // I2C ACK General Call Register
+#define    R_IC_ENABLE_STATUS                ( 0x9C) // I2C Enable Status Register
+#define    R_IC_COMP_PARAM                   ( 0xF4) // Component Parameter Register
+#define    R_IC_COMP_VERSION                 ( 0xF8) // Component Version ID
+#define    R_IC_COMP_TYPE                    ( 0xFC) // Component Type
+
+#define    I2C_SS_SCL_HCNT_VALUE_100M        0x1DD
+#define    I2C_SS_SCL_LCNT_VALUE_100M        0x1E4
+#define    I2C_FS_SCL_HCNT_VALUE_100M        0x54
+#define    I2C_FS_SCL_LCNT_VALUE_100M        0x9a
+#define    I2C_HS_SCL_HCNT_VALUE_100M        0x7
+#define    I2C_HS_SCL_LCNT_VALUE_100M        0xE
+
+#define     IC_TAR_10BITADDR_MASTER           BIT12
+#define     FIFO_SIZE                         32
+#define     R_IC_INTR_STAT                    ( 0x2C) // I2c Inetrrupt Status
+#define     R_IC_INTR_MASK                    ( 0x30) // I2c Interrupt Mask
+#define     I2C_INTR_GEN_CALL                 BIT11  // General call received
+#define     I2C_INTR_START_DET                BIT10
+#define     I2C_INTR_STOP_DET                 BIT9
+#define     I2C_INTR_ACTIVITY                 BIT8
+#define     I2C_INTR_TX_ABRT                  BIT6   // Set on NACK
+#define     I2C_INTR_TX_EMPTY                 BIT4
+#define     I2C_INTR_TX_OVER                  BIT3
+#define     I2C_INTR_RX_FULL                  BIT2   // Data bytes in RX FIFO over threshold
+#define     I2C_INTR_RX_OVER                  BIT1
+#define     I2C_INTR_RX_UNDER                 BIT0
+
+#define R_PCH_LPIO_I2C_MEM_RESETS                 0x804 // Software Reset
+#define B_PCH_LPIO_I2C_MEM_RESETS_FUNC            BIT1  // Function Clock Domain Reset
+#define B_PCH_LPIO_I2C_MEM_RESETS_APB             BIT0  // APB Domain Reset
+#define R_PCH_LPSS_I2C_MEM_PCP                    0x800 // Private Clock Parameters
+
+#endif
\ No newline at end of file
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CAccess.h b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CAccess.h
new file mode 100644
index 0000000000..bf6ef4c747
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CAccess.h
@@ -0,0 +1,44 @@
+/** @file
+  Misc Registers Definition.
+  
+  Copyright (c) 2011  - 2015, Intel Corporation. All rights reserved.<BR>
+                                                                                   
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+                                                                               
+--*/
+
+#ifndef _I2C_ACCESS_H_
+#define _I2C_ACCESS_H_
+
+#include "I2CIoLibPei.h"
+
+#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_ACPI_BASE                    0x40            // ABASE, 16bit
+#define R_PCH_LPC_ACPI_BASEADR                 0x400           // ABASE, 16bit
+#define B_PCH_LPC_ACPI_BASE_EN                 BIT1            // Enable Bit
+#define B_PCH_LPC_ACPI_BASE_BAR                0x0000FF80      // Base Address, 128 Bytes
+#define V_PCH_ACPI_PM1_TMR_MAX_VAL             0x1000000       // The timer is 24 bit overflow
+#define B_PCH_ACPI_PM1_TMR_VAL                 0xFFFFFF        // The timer value mask
+
+#define R_PCH_ACPI_PM1_TMR                     0x08            // Power Management 1 Timer
+#define V_PCH_ACPI_PM1_TMR_FREQUENCY           3579545         // Timer Frequency
+
+
+#define PchLpcPciCfg8(Register) I2CLibPeiMmioRead8 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, Register))
+
+#define PCIEX_BASE_ADDRESS                     0xE0000000
+#define PCI_EXPRESS_BASE_ADDRESS               ((VOID *) (UINTN) PCIEX_BASE_ADDRESS)
+
+#define MmPciAddress( Segment, Bus, Device, Function, Register ) \
+  ( (UINTN)PCI_EXPRESS_BASE_ADDRESS + \
+    (UINTN)(Bus << 20) + \
+    (UINTN)(Device << 15) + \
+    (UINTN)(Function << 12) + \
+    (UINTN)(Register) \
+  )
+#endif
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.c
new file mode 100644
index 0000000000..d5f8dfd012
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.c
@@ -0,0 +1,46 @@
+/** @file
+  MicroSecondDelay implementation of ACPI Timer.
+  
+  Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
+                                                                                   
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+                                                                               
+--*/
+
+#include "PiPei.h"
+#include "I2CAccess.h"
+#include "I2CDelayPei.h"
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Ppi/Stall.h>
+
+/**
+  Stalls the CPU for at least the given number of microseconds.
+  Stalls the CPU for the number of microseconds specified by MicroSeconds.
+
+  @param  MicroSeconds  The minimum number of microseconds to delay.
+
+  @return EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+MicroSecondDelay (
+  IN      UINTN                     MicroSeconds
+  )
+{
+
+  EFI_PEI_STALL_PPI              *StallPpi;
+  EFI_STATUS                     Status;
+  CONST EFI_PEI_SERVICES         **PeiServices;
+  
+  PeiServices = GetPeiServicesTablePointer();
+
+
+  Status = (**PeiServices).LocatePpi (PeiServices, &gEfiPeiStallPpiGuid, 0, NULL, &StallPpi);
+  ASSERT(!EFI_ERROR(Status));
+
+  StallPpi->Stall (PeiServices, StallPpi, MicroSeconds);
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.h b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.h
new file mode 100644
index 0000000000..604f1f67c5
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.h
@@ -0,0 +1,30 @@
+/** @file
+  MicroSecondDelay implementation of ACPI Timer.
+
+  Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __I2C_DELAY_PEI__
+
+#define __I2C_DELAY_PEI__
+#include "PiPei.h"
+
+/**
+  Stalls the CPU for at least the given number of microseconds.
+
+  Stalls the CPU for the number of microseconds specified by MicroSeconds.
+
+  @param  MicroSeconds  The minimum number of microseconds to delay.
+
+  @return MicroSeconds
+
+**/
+EFI_STATUS
+EFIAPI
+MicroSecondDelay (
+  IN      UINTN                     MicroSeconds
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.c
new file mode 100644
index 0000000000..6a37dbec1d
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.c
@@ -0,0 +1,178 @@
+/** @file
+  Functions for access I2C MMIO register.
+
+  Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+
+/**
+  Reads an 8-bit MMIO register.
+
+  Reads the 8-bit MMIO register specified by Address. The 8-bit read value is
+  returned. This function must guarantee that all MMIO read and write
+  operations are serialized.
+
+  If 8-bit MMIO register operations are not supported, then ASSERT().
+
+  @param  Address The MMIO register to read.
+
+  @return The value read.
+
+**/
+UINT8
+EFIAPI
+I2CLibPeiMmioRead8 (
+  IN UINTN Address
+  )
+{
+  UINT8 Value;
+
+  Value = *(volatile UINT8*)Address;
+  return Value;
+}
+
+/**
+  Reads a 16-bit MMIO register.
+
+  Reads the 16-bit MMIO register specified by Address. The 16-bit read value is
+  returned. This function must guarantee that all MMIO read and write
+  operations are serialized.
+
+  If 16-bit MMIO register operations are not supported, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param  Address The MMIO register to read.
+
+  @return The value read.
+
+**/
+UINT16
+EFIAPI
+I2CLibPeiMmioRead16 (
+  IN UINTN  Address
+  )
+{
+  UINT16 Value;
+
+  ASSERT ((Address & 1) == 0);
+  Value = *(volatile UINT16*)Address;
+  return Value;
+}
+
+/**
+  Writes a 16-bit MMIO register.
+
+  Writes the 16-bit MMIO register specified by Address with the value specified
+  by Value and returns Value. This function must guarantee that all MMIO read
+  and write operations are serialized.
+
+  If 16-bit MMIO register operations are not supported, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param  Address The MMIO register to write.
+  @param  Value   The value to write to the MMIO register.
+
+  @return Value.
+
+**/
+UINT16
+EFIAPI
+I2CLibPeiMmioWrite16 (
+  IN  UINTN   Address,
+  IN  UINT16  Value
+  )
+{
+  ASSERT ((Address & 1) == 0);
+  *(volatile UINT16*)Address = Value;
+  return Value;
+}
+
+/**
+  Reads a 32-bit MMIO register.
+
+  Reads the 32-bit MMIO register specified by Address. The 32-bit read value is
+  returned. This function must guarantee that all MMIO read and write
+  operations are serialized.
+
+  If 32-bit MMIO register operations are not supported, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param  Address The MMIO register to read.
+
+  @return The value read.
+
+**/
+UINT32
+EFIAPI
+I2CLibPeiMmioRead32 (
+  IN UINTN Address
+  )
+{
+  UINT32  Value;
+
+  ASSERT ((Address & 3) == 0);
+  Value = *(volatile UINT32*)Address;
+
+  return Value;
+}
+
+/**
+  Writes a 32-bit MMIO register.
+
+  Writes the 32-bit MMIO register specified by Address with the value specified
+  by Value and returns Value. This function must guarantee that all MMIO read
+  and write operations are serialized.
+
+  If 32-bit MMIO register operations are not supported, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param  Address The MMIO register to write.
+  @param  Value   The value to write to the MMIO register.
+
+  @return Value.
+
+**/
+UINT32
+EFIAPI
+I2CLibPeiMmioWrite32 (
+  IN      UINTN                     Address,
+  IN      UINT32                    Value
+  )
+{
+  ASSERT ((Address & 3) == 0);
+  *(volatile UINT32*)Address = Value;
+  return Value;
+}
+
+/**
+  OR a 32-bit MMIO register.
+
+  OR the 32-bit MMIO register specified by Address with the value specified
+  by Value and returns Value. This function must guarantee that all MMIO read
+  and write operations are serialized.
+
+  If 32-bit MMIO register operations are not supported, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param  Address The MMIO register to write OR.
+  @param  Value   The value to OR to the MMIO register.
+
+  @return Value.
+
+**/
+UINT32
+EFIAPI
+I2CLibPeiMmioOr32 (
+  IN      UINTN                     Address,
+  IN      UINT32                    OrData
+  )
+{
+  return I2CLibPeiMmioWrite32 (Address, I2CLibPeiMmioRead32(Address) | OrData);
+}
+
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.h b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.h
new file mode 100644
index 0000000000..b68bc1ed09
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.h
@@ -0,0 +1,153 @@
+/** @file
+  Functions for access I2C MMIO register.
+
+  Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __I2C_IOLIB_PEI__
+
+#define __I2C_IOLIB_PEI__
+#include <PiPei.h>
+
+
+/**
+  Reads an 8-bit MMIO register.
+
+  Reads the 8-bit MMIO register specified by Address. The 8-bit read value is
+  returned. This function must guarantee that all MMIO read and write
+  operations are serialized.
+
+  If 8-bit MMIO register operations are not supported, then ASSERT().
+
+  @param  Address The MMIO register to read.
+
+  @return The value read.
+
+**/
+
+UINT8
+EFIAPI
+I2CLibPeiMmioRead8 (
+  IN      UINTN                     Address
+  );
+
+
+/**
+  Reads a 16-bit MMIO register.
+
+  Reads the 16-bit MMIO register specified by Address. The 16-bit read value is
+  returned. This function must guarantee that all MMIO read and write
+  operations are serialized.
+
+  If 16-bit MMIO register operations are not supported, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param  Address The MMIO register to read.
+
+  @return The value read.
+
+**/
+UINT16
+EFIAPI
+I2CLibPeiMmioRead16 (
+  IN      UINTN                     Address
+  );
+
+
+/**
+  Writes a 16-bit MMIO register.
+
+  Writes the 16-bit MMIO register specified by Address with the value specified
+  by Value and returns Value. This function must guarantee that all MMIO read
+  and write operations are serialized.
+
+  If 16-bit MMIO register operations are not supported, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param  Address The MMIO register to write.
+  @param  Value   The value to write to the MMIO register.
+
+  @return Value.
+
+**/
+UINT16
+EFIAPI
+I2CLibPeiMmioWrite16 (
+  IN      UINTN                     Address,
+  IN      UINT16                    Value
+  );
+
+
+/**
+  Reads a 32-bit MMIO register.
+
+  Reads the 32-bit MMIO register specified by Address. The 32-bit read value is
+  returned. This function must guarantee that all MMIO read and write
+  operations are serialized.
+
+  If 32-bit MMIO register operations are not supported, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param  Address The MMIO register to read.
+
+  @return The value read.
+
+**/
+UINT32
+EFIAPI
+I2CLibPeiMmioRead32 (
+  IN      UINTN                     Address
+  );
+
+
+/**
+  Writes a 32-bit MMIO register.
+
+  Writes the 32-bit MMIO register specified by Address with the value specified
+  by Value and returns Value. This function must guarantee that all MMIO read
+  and write operations are serialized.
+
+  If 32-bit MMIO register operations are not supported, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param  Address The MMIO register to write.
+  @param  Value   The value to write to the MMIO register.
+
+  @return Value.
+
+**/
+UINT32
+EFIAPI
+I2CLibPeiMmioWrite32 (
+  IN      UINTN                     Address,
+  IN      UINT32                    Value
+  );
+
+
+/**
+  OR a 32-bit MMIO register.
+
+  OR the 32-bit MMIO register specified by Address with the value specified
+  by Value and returns Value. This function must guarantee that all MMIO read
+  and write operations are serialized.
+
+  If 32-bit MMIO register operations are not supported, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param  Address The MMIO register to write OR.
+  @param  Value   The value to OR to the MMIO register.
+
+  @return Value.
+
+**/
+UINT32
+EFIAPI
+I2CLibPeiMmioOr32 (
+  IN      UINTN                     Address,
+  IN      UINT32                    OrData
+  );
+
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.c
new file mode 100644
index 0000000000..dd5cceb70d
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.c
@@ -0,0 +1,638 @@
+/** @file
+  I2C PEI Lib Instance.
+
+  Copyright (c) 1999- 2015, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "I2CDelayPei.h"
+#include "I2CIoLibPei.h"
+#include "I2CAccess.h"
+#include "I2CLibPei.h"
+#include <PlatformBaseAddresses.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/HobLib.h>
+#include <PchRegs/PchRegsPcu.h> 
+#include <PchRegs/PchRegsLpss.h> 
+
+#define LPSS_PCI_DEVICE_NUMBER  8
+
+#define R_PCH_LPIO_I2C_MEM_RESETS                 0x804 // Software Reset
+#define B_PCH_LPIO_I2C_MEM_RESETS_FUNC            BIT1  // Function Clock Domain Reset
+#define B_PCH_LPIO_I2C_MEM_RESETS_APB             BIT0  // APB Domain Reset
+#define R_PCH_LPSS_I2C_MEM_PCP                    0x800 // Private Clock Parameters
+
+#define PEI_TEPM_LPSS_DMA_BAR                     0xFE900000
+#define PEI_TEPM_LPSS_I2C0_BAR                    0xFE910000
+#define PCI_CONFIG_SPACE_SIZE                     0x10000
+
+EFI_GUID  mI2CPeiInitGuid = {
+  0x96DED71A, 0xB9E7, 0x4EAD, 0x96, 0x2C, 0x01, 0x69, 0x3C, 0xED, 0x2A, 0x64
+};
+
+
+UINT16 I2CGPIO[]= {
+  //
+  // 19.1.6  I2C0
+  // I2C0_SDA-OD-O -    write 0x2003CC81 to IOBASE + 0x0210
+  // I2C0_SCL-OD-O -    write 0x2003CC81 to IOBASE + 0x0200
+  //
+  0x0210,
+  0x0200,
+
+  //
+  // 19.1.7  I2C1
+  // I2C1_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x01F0
+  // I2C1_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x01E0
+  //
+  0x01F0,
+  0x01E0,
+
+  //
+  // 19.1.8  I2C2
+  // I2C2_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x01D0
+  // I2C2_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x01B0
+  //
+  0x01D0,
+  0x01B0,
+
+  //
+  // 19.1.9  I2C3
+  // I2C3_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x0190
+  // I2C3_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x01C0
+  // 
+  0x0190,
+  0x01C0,
+
+  //
+  // 19.1.10 I2C4
+  // I2C4_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x01A0
+  // I2C4_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x0170
+  //
+  0x01A0,
+  0x0170,
+
+  // 
+  // 19.1.11 I2C5
+  // I2C5_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x0150
+  // I2C5_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x0140
+  // 
+  0x0150,
+  0x0140,
+
+  //
+  // 19.1.12 I2C6
+  // I2C6_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x0180
+  // I2C6_SCL-OD-O/I -  write 0x2003CC81 to IOBASE + 0x0160
+  // 
+  0x0180,
+  0x0160
+};
+
+/**
+  Constructor of this library.
+
+  @param   VOID
+
+  @return  EFI_SUCCESS
+**/
+EFI_STATUS
+EFIAPI
+IntelI2CPeiLibConstructor (
+  IN EFI_PEI_FILE_HANDLE     FileHandle,
+  IN CONST EFI_PEI_SERVICES  **PeiServices
+  )
+{
+  UINTN Index;
+  
+  for (Index = 0; Index < sizeof(I2CGPIO)/sizeof(UINT16); Index ++) {
+    I2CLibPeiMmioWrite32(IO_BASE_ADDRESS+I2CGPIO[Index], 0x2003CC81);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Programe all I2C controllers on LPSS. 
+  
+  I2C0 is function 1 of LPSS. I2C1 is function 2 of LPSS, etc..
+
+  @param   VOID
+
+  @return  EFI_SUCCESS
+**/
+EFI_STATUS
+ProgramPciLpssI2C (
+  VOID
+  )
+{
+  UINT32       PmcBase;
+  UINT32       DevID;
+  UINTN        PciMmBase=0;
+  UINTN        Index;
+  UINTN        Bar0;
+  UINTN        Bar1;
+  DEBUG ((EFI_D_INFO, "Pei ProgramPciLpssI2C() Start\n"));
+  
+  //
+  // Set the VLV Function Disable Register to ZERO
+  //
+  PmcBase         = I2CLibPeiMmioRead32(PciD31F0RegBase + R_PCH_LPC_PMC_BASE) & B_PCH_LPC_PMC_BASE_BAR;
+  
+  if(I2CLibPeiMmioRead32(PmcBase + R_PCH_PMC_FUNC_DIS)&
+      (B_PCH_PMC_FUNC_DIS_LPSS2_FUNC1 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC2
+       | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC3 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC4 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC5
+       | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC6 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC7)) {
+    I2CLibPeiMmioWrite32(
+      PmcBase+R_PCH_PMC_FUNC_DIS,
+      I2CLibPeiMmioRead32(PmcBase + R_PCH_PMC_FUNC_DIS)& \
+      ~(B_PCH_PMC_FUNC_DIS_LPSS2_FUNC1 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC2 \
+        | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC3 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC4 \
+        | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC5 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC6|B_PCH_PMC_FUNC_DIS_LPSS2_FUNC7)
+      );
+    DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() enable all I2C controllers\n"));
+  }
+
+  for(Index = 0; Index < LPSS_PCI_DEVICE_NUMBER; Index ++) {
+
+    PciMmBase = MmPciAddress (
+                  0,
+                  DEFAULT_PCI_BUS_NUMBER_PCH,
+                  PCI_DEVICE_NUMBER_PCH_LPSS_I2C,
+                  Index,
+                  0
+                  );
+    DevID =  I2CLibPeiMmioRead32(PciMmBase);
+
+    Bar0 = PEI_TEPM_LPSS_DMA_BAR + (Index * PCI_CONFIG_SPACE_SIZE);
+    Bar1 = Bar0 + 0x8000;
+
+    DEBUG((EFI_D_ERROR, "Program Pci Lpss I2C Device  Function=%x DevID=%08x\n", Index, DevID));
+    
+    //
+    // Check if device present
+    //
+    if (DevID  != 0xFFFFFFFF)  {
+      if(!(I2CLibPeiMmioRead32 (PciMmBase + R_PCH_LPSS_I2C_STSCMD) & B_PCH_LPSS_I2C_STSCMD_MSE)) {
+        //
+        // Program BAR 0
+        //
+        I2CLibPeiMmioWrite32((UINTN) (PciMmBase + R_PCH_LPSS_I2C_BAR), (UINT32)(Bar0 & B_PCH_LPSS_I2C_BAR_BA));
+        
+        DEBUG ((EFI_D_ERROR, "I2CBaseAddress1 = 0x%x \n",I2CLibPeiMmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR)));
+        
+        //
+        // Program BAR 1
+        //
+        I2CLibPeiMmioWrite32 ((UINTN)(PciMmBase + R_PCH_LPSS_I2C_BAR1), (UINT32)(Bar1 & B_PCH_LPSS_I2C_BAR1_BA));
+        DEBUG ((EFI_D_ERROR, "I2CBaseAddress1 = 0x%x \n",I2CLibPeiMmioRead32(PciMmBase+R_PCH_LPSS_I2C_BAR1)));
+        
+        //
+        // Bus Master Enable & Memory Space Enable
+        //
+        I2CLibPeiMmioWrite32((UINTN) (PciMmBase + R_PCH_LPSS_I2C_STSCMD), (UINT32)(B_PCH_LPSS_I2C_STSCMD_BME | B_PCH_LPSS_I2C_STSCMD_MSE));
+      }
+      
+      //
+      // Release Resets
+      //
+      I2CLibPeiMmioWrite32 (Bar0 + R_PCH_LPIO_I2C_MEM_RESETS, (B_PCH_LPIO_I2C_MEM_RESETS_FUNC | B_PCH_LPIO_I2C_MEM_RESETS_APB));
+      
+      //
+      // Activate Clocks
+      //
+      I2CLibPeiMmioWrite32 (Bar0 + R_PCH_LPSS_I2C_MEM_PCP, 0x80020003);//No use for A0
+
+      DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() Programmed()\n"));
+    }
+
+  }
+  
+  DEBUG ((EFI_D_INFO, "Pei ProgramPciLpssI2C() End\n"));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Disable I2C Bus.
+
+  @param I2cControllerIndex   Index of I2C controller.
+
+  @return EFI_SUCCESS
+**/
+EFI_STATUS
+I2cDisable (
+  IN UINT8 I2cControllerIndex
+  )
+{
+  UINTN  I2CBaseAddress;
+  UINT32 NumTries = 10000;  // 0.1 seconds
+  
+  I2CBaseAddress = (UINT32) PEI_TEPM_LPSS_I2C0_BAR + I2cControllerIndex * PCI_CONFIG_SPACE_SIZE;
+  
+  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_ENABLE, 0);
+  while (0 != ( I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_ENABLE_STATUS ) & 1)) {
+    MicroSecondDelay (10);
+    NumTries --;
+    if(0 == NumTries) return EFI_NOT_READY;
+  }
+  
+  return EFI_SUCCESS;
+}
+
+/**
+  Enable I2C Bus.
+
+  @param I2cControllerIndex   Index of I2C controller.
+
+  @return EFI_SUCCESS
+**/
+EFI_STATUS
+I2cEnable (
+  IN UINT8 I2cControllerIndex
+  )
+{
+  UINTN   I2CBaseAddress;
+  UINT32 NumTries = 10000;  // 0.1 seconds
+  
+  I2CBaseAddress = (UINT32) PEI_TEPM_LPSS_I2C0_BAR+ I2cControllerIndex * PCI_CONFIG_SPACE_SIZE;
+  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_ENABLE, 1);
+  while (0 == ( I2CLibPeiMmioRead16 ( I2CBaseAddress + R_IC_ENABLE_STATUS ) & 1)) {
+    MicroSecondDelay (10);
+    NumTries --;
+    if(0 == NumTries) return EFI_NOT_READY;
+  }
+  
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Set the I2C controller bus clock frequency.
+
+  @param[in] This           Address of the library's I2C context structure
+  @param[in] PlatformData   Address of the platform configuration data
+  @param[in] BusClockHertz  New I2C bus clock frequency in Hertz
+
+  @retval RETURN_SUCCESS      The bus frequency was set successfully.
+  @retval RETURN_UNSUPPORTED  The controller does not support this frequency.
+
+**/
+EFI_STATUS
+I2cBusFrequencySet (
+  IN UINTN   I2CBaseAddress,
+  IN UINTN   BusClockHertz,
+  IN UINT16  *I2cMode
+  )
+{
+  DEBUG((EFI_D_INFO,"InputFreq BusClockHertz: %d\r\n",BusClockHertz));
+
+  *I2cMode = B_IC_RESTART_EN | B_IC_SLAVE_DISABLE | B_MASTER_MODE;
+
+  //
+  //  Set the 100 KHz clock divider
+  //
+  //  From Table 10 of the I2C specification
+  //
+  //    High: 4.00 uS
+  //    Low:  4.70 uS
+  //
+  I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_SS_SCL_HCNT, (UINT16)0x214 );
+  I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_SS_SCL_LCNT, (UINT16)0x272 );
+  
+  //
+  //    Set the 400 KHz clock divider
+  //
+  //    From Table 10 of the I2C specification
+  //
+  //      High: 0.60 uS
+  //      Low:  1.30 uS
+  //
+  I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_FS_SCL_HCNT, (UINT16)0x50 );
+  I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_FS_SCL_LCNT, (UINT16)0xAD );
+
+  switch ( BusClockHertz ) {
+    case 100 * 1000:
+      I2CLibPeiMmioWrite32 ( I2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x40);//100K
+      *I2cMode |= V_SPEED_STANDARD;
+      break;
+    case 400 * 1000:
+      I2CLibPeiMmioWrite32 ( I2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x32);//400K
+      *I2cMode |= V_SPEED_FAST;
+      break;
+    default:
+      I2CLibPeiMmioWrite32 ( I2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x09);//3.4M
+      *I2cMode |= V_SPEED_HIGH;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Initializes the host controller to execute I2C commands.
+
+  @param I2cControllerIndex Index of I2C controller in LPSS device. 0 represents I2C0, which is PCI function 1 of LPSS device.   
+                                
+  @return EFI_SUCCESS       Opcode initialization on the I2C host controller completed.
+  @return EFI_DEVICE_ERROR  Device error, operation failed.
+**/
+EFI_STATUS
+I2CInit (
+  UINT8 I2cControllerIndex, 
+  UINT16 SlaveAddress
+  )
+{
+  EFI_STATUS   Status;
+  UINT32       NumTries = 0;
+  UINTN        I2CBaseAddress;
+  UINT16       I2cMode;
+  UINTN        PciMmBase=0;
+
+
+  PciMmBase = MmPciAddress (
+                0,
+                DEFAULT_PCI_BUS_NUMBER_PCH,
+                PCI_DEVICE_NUMBER_PCH_LPSS_I2C,
+                (I2cControllerIndex + 1),
+                0
+                );
+
+  I2CBaseAddress = I2CLibPeiMmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR);
+
+  //
+  //  Verify the parameters
+  //
+  if (1023 < SlaveAddress ) {
+    Status =  EFI_INVALID_PARAMETER;
+    DEBUG((EFI_D_INFO,"I2cStartRequest Exit with Status %r\r\n", Status));
+    return Status;
+  }
+
+  if(I2CBaseAddress ==  (PEI_TEPM_LPSS_I2C0_BAR + I2cControllerIndex * PCI_CONFIG_SPACE_SIZE)) {
+    return EFI_SUCCESS;
+  }
+  ProgramPciLpssI2C();
+
+  I2CBaseAddress = (UINT32) (PEI_TEPM_LPSS_I2C0_BAR + I2cControllerIndex * PCI_CONFIG_SPACE_SIZE);
+  DEBUG ((EFI_D_ERROR, "I2CBaseAddress = 0x%x \n",I2CBaseAddress));
+  NumTries = 10000; // 1 seconds
+  while ((1 == ( I2CLibPeiMmioRead32 ( I2CBaseAddress + R_IC_STATUS) & STAT_MST_ACTIVITY ))) {
+    MicroSecondDelay(10);
+    NumTries --;
+    if(0 == NumTries)
+      return EFI_DEVICE_ERROR;
+  }
+
+  Status = I2cDisable (I2cControllerIndex);
+  DEBUG((EFI_D_INFO, "I2cDisable Status = %r\r\n", Status));
+
+  I2cBusFrequencySet(I2CBaseAddress, 400 * 1000, &I2cMode);//Set I2cMode
+
+  I2CLibPeiMmioWrite16(I2CBaseAddress + R_IC_INTR_MASK, 0x0);
+  if (0x7F < SlaveAddress) {
+    SlaveAddress = (SlaveAddress & 0x3ff ) | IC_TAR_10BITADDR_MASTER;
+  }
+  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_TAR, (UINT16) SlaveAddress );
+  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_RX_TL, 0);
+  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_TX_TL, 0 );
+  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_CON, I2cMode);
+
+  Status = I2cEnable(I2cControllerIndex);
+  DEBUG((EFI_D_INFO, "I2cEnable Status = %r\r\n", Status));
+  I2CLibPeiMmioRead16 ( I2CBaseAddress + R_IC_CLR_TX_ABRT );
+  
+  return EFI_SUCCESS;
+}
+
+/**
+  Reads a Byte from I2C Device.
+ 
+  @param  I2cControllerIndex  I2C Bus no to which the I2C device has been connected
+  @param  SlaveAddress        Device Address from which the byte value has to be read
+  @param  Offset              Offset from which the data has to be read
+  @param  *Byte               Address to which the value read has to be stored
+                                
+  @return  EFI_SUCCESS        If the byte value has been successfully read
+  @return  EFI_DEVICE_ERROR   Operation Failed, Device Error
+**/
+EFI_STATUS ByteReadI2CBasic(
+  IN  UINT8 I2cControllerIndex,
+  IN  UINT8 SlaveAddress,
+  IN  UINTN ReadBytes,
+  OUT UINT8 *ReadBuffer,
+  IN  UINT8 Start,
+  IN  UINT8 End
+  )
+{
+
+  EFI_STATUS Status;
+  UINT32 I2cStatus;
+  UINT16 ReceiveData;
+  UINT8 *ReceiveDataEnd;
+  UINT8 *ReceiveRequest;
+  UINT16 RawIntrStat;
+  UINTN   I2CBaseAddress;
+
+  I2CBaseAddress = (UINT32)(PEI_TEPM_LPSS_I2C0_BAR + I2cControllerIndex * PCI_CONFIG_SPACE_SIZE);
+
+  Status = EFI_SUCCESS;
+
+  I2CInit(I2cControllerIndex, SlaveAddress);
+
+  ReceiveDataEnd = &ReadBuffer [ReadBytes];
+  if(ReadBytes) {
+    ReceiveRequest = ReadBuffer;
+    DEBUG((EFI_D_INFO,"Read: ---------------%d bytes to RX\r\n",ReceiveDataEnd - ReceiveRequest));
+
+    while ((ReceiveDataEnd > ReceiveRequest) || (ReceiveDataEnd > ReadBuffer)) {
+      //
+      // Check for NACK
+      //
+      RawIntrStat = I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_RawIntrStat );
+      if ( 0 != (RawIntrStat & I2C_INTR_TX_ABRT )) {
+        I2CLibPeiMmioRead16 ( I2CBaseAddress + R_IC_CLR_TX_ABRT );
+        Status = RETURN_DEVICE_ERROR;
+        DEBUG((EFI_D_INFO,"TX ABRT ,%d bytes hasn't been transferred\r\n",ReceiveDataEnd - ReceiveRequest));
+        break;
+      }
+      
+      //
+      // Determine if another byte was received
+      //
+      I2cStatus = I2CLibPeiMmioRead16 ( I2CBaseAddress + R_IC_STATUS );
+      if ( 0 != ( I2cStatus & STAT_RFNE )) {
+        ReceiveData = I2CLibPeiMmioRead16 ( I2CBaseAddress + R_IC_DATA_CMD );
+        *ReadBuffer++ = (UINT8)ReceiveData;
+        DEBUG((EFI_D_INFO,"MmioRead32 ,1 byte 0x:%x is received\r\n",ReceiveData));
+      }
+
+      if(ReceiveDataEnd==ReceiveRequest) {
+        //
+        // Waiting the last request to get data and make (ReceiveDataEnd > ReadBuffer) =TRUE.
+        //
+        continue;
+      }
+      
+      //
+      // Wait until a read request will fit
+      //
+      if ( 0 == ( I2cStatus & STAT_TFNF )) {
+        MicroSecondDelay ( 10 );
+        continue;
+      }
+      
+      //
+      // Issue the next read request
+      //
+      if(End && Start ) {
+        I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD|B_CMD_RESTART|B_CMD_STOP);
+      } else if (!End && Start ) {
+        I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD|B_CMD_RESTART);
+      } else if (End && !Start ) {
+        I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD|B_CMD_STOP);
+      } else if (!End && !Start ) {
+        I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD);
+      }
+      ReceiveRequest += 1;
+    }
+
+  }
+  return Status;
+
+}
+
+/**
+  Writes a Byte to I2C Device.
+ 
+  @param  I2cControllerIndex   I2C Bus no to which the I2C device has been connected
+  @param  SlaveAddress         Device Address from which the byte value has to be written
+  @param  Offset               Offset from which the data has to be read
+  @param  *Byte                Address to which the value written is stored
+                                
+  @return  EFI_SUCCESS         IF the byte value has been successfully written
+  @return  EFI_DEVICE_ERROR    Operation Failed, Device Error
+**/
+EFI_STATUS 
+ByteWriteI2CBasic(
+  IN  UINT8 I2cControllerIndex,
+  IN  UINT8 SlaveAddress,
+  IN  UINTN WriteBytes,
+  IN  UINT8 *WriteBuffer,
+  IN  UINT8 Start,
+  IN  UINT8 End
+  )
+{
+
+  EFI_STATUS Status;
+  UINT32 I2cStatus;
+  UINT8 *TransmitEnd;
+  UINT16 RawIntrStat;
+  UINTN   I2CBaseAddress;
+
+  I2CBaseAddress = (UINT32)PEI_TEPM_LPSS_I2C0_BAR+ I2cControllerIndex * PCI_CONFIG_SPACE_SIZE;
+
+  Status = EFI_SUCCESS;
+
+  I2CInit(I2cControllerIndex, SlaveAddress);
+
+  TransmitEnd = &WriteBuffer [WriteBytes];
+  if( WriteBytes ) {
+
+    DEBUG((EFI_D_INFO,"Write: --------------%d bytes to TX\r\n", TransmitEnd - WriteBuffer));
+
+    while ( TransmitEnd > WriteBuffer) {
+      I2cStatus = I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_STATUS);
+      RawIntrStat = I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_RawIntrStat);
+      if ( 0 != (RawIntrStat & I2C_INTR_TX_ABRT)) {
+        I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_CLR_TX_ABRT);
+        Status = RETURN_DEVICE_ERROR;
+        DEBUG((EFI_D_ERROR,"TX ABRT TransmitEnd:0x%x WriteBuffer:0x%x\r\n", TransmitEnd, WriteBuffer));
+        break;
+      }
+      if (0 == ( I2cStatus & STAT_TFNF)) {
+        continue;
+      }
+      if(End && Start) {
+        I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++) | B_CMD_RESTART | B_CMD_STOP);
+      } else if (!End && Start ) {
+        I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++) | B_CMD_RESTART);
+      } else if (End && !Start ) {
+        I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++) | B_CMD_STOP);
+      } else if (!End && !Start ) {
+        I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++));
+      }
+      
+      // Add a small delay to work around some odd behavior being seen.  Without this delay bytes get dropped.
+      MicroSecondDelay ( FIFO_WRITE_DELAY );
+    }
+
+  }
+  
+  if(EFI_ERROR(Status)) {
+    DEBUG((EFI_D_INFO,"I2cStartRequest Exit with Status %r\r\n",Status));
+  }
+    
+  return Status;
+}
+
+/**
+  Reads a Byte from I2C Device.
+ 
+  @param  I2cControllerIndex   I2C Bus no to which the I2C device has been connected
+  @param  SlaveAddress         Device Address from which the byte value has to be read
+  @param  Offset               Offset from which the data has to be read
+  @param  ReadBytes            Number of bytes to be read
+  @param  *ReadBuffer          Address to which the value read has to be stored
+                                
+  @return  EFI_SUCCESS       IF the byte value has been successfully read
+  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
+**/
+EFI_STATUS 
+ByteReadI2C(
+  IN  UINT8 I2cControllerIndex,
+  IN  UINT8 SlaveAddress,
+  IN  UINT8 Offset,
+  IN  UINTN ReadBytes,
+  OUT UINT8 *ReadBuffer
+  )
+{
+  EFI_STATUS        Status;
+
+  DEBUG ((EFI_D_ERROR, "ByteReadI2C:---offset:0x%x\n",Offset));
+  Status = ByteWriteI2CBasic(I2cControllerIndex, SlaveAddress, 1, &Offset,TRUE,FALSE);
+  Status = ByteReadI2CBasic(I2cControllerIndex, SlaveAddress, ReadBytes, ReadBuffer, TRUE, TRUE);
+
+  return Status;
+}
+
+/**
+  Writes a Byte to I2C Device.
+ 
+  @param  I2cControllerIndex  I2C Bus no to which the I2C device has been connected
+  @param  SlaveAddress        Device Address from which the byte value has to be written
+  @param  Offset              Offset from which the data has to be written
+  @param  WriteBytes          Number of bytes to be written
+  @param  *Byte               Address to which the value written is stored
+                                
+  @return  EFI_SUCCESS       IF the byte value has been successfully read
+  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
+**/
+EFI_STATUS ByteWriteI2C(
+  IN  UINT8 I2cControllerIndex,
+  IN  UINT8 SlaveAddress,
+  IN  UINT8 Offset,
+  IN  UINTN WriteBytes,
+  IN  UINT8 *WriteBuffer
+  )
+{
+  EFI_STATUS        Status;
+
+  DEBUG ((EFI_D_ERROR, "ByteWriteI2C:---offset/bytes/buf:0x%x,0x%x,0x%x,0x%x\n",Offset,WriteBytes,WriteBuffer,*WriteBuffer));
+  Status = ByteWriteI2CBasic(I2cControllerIndex, SlaveAddress, 1, &Offset, TRUE, FALSE);
+  Status = ByteWriteI2CBasic(I2cControllerIndex, SlaveAddress, WriteBytes, WriteBuffer, FALSE, TRUE);
+
+  return Status;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.h b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.h
new file mode 100644
index 0000000000..47536aebf7
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.h
@@ -0,0 +1,280 @@
+/** @file
+  I2C PEI Lib Instance.
+
+  Copyright (c) 1999- 2015, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef I2C_PEI_REGS_H
+#define I2C_PEI_REGS_H
+
+#include "PiPei.h"
+
+#define R_PCH_LPC_PMC_BASE                        0x44
+#define B_PCH_LPC_PMC_BASE_BAR                    0xFFFFFE00
+#define R_PCH_PMC_FUNC_DIS                        0x34  // Function Disable Register
+#define PCIEX_BASE_ADDRESS                        0xE0000000
+#define PciD31F0RegBase                           PCIEX_BASE_ADDRESS + (UINT32) (31 << 15)
+#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC7             BIT7  // LPSS SPI Disable
+#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC6             BIT6  // LPSS HSUART #2 Disable
+#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC5             BIT5  // LPSS HSUART #1 Disable
+#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC4             BIT4  // LPSS I2S Disable
+#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC3             BIT3  // LPSS PCM Disable
+#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC2             BIT2  // LPSS I2C #2 Disable
+#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC1             BIT1  // LPSS I2C #1 Disable
+#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC0             BIT0  // LPSS DMA Disable
+
+
+#define DEFAULT_PCI_BUS_NUMBER_PCH       0
+
+#define R_PCH_LPSS_I2C_STSCMD                     0x04  // Status & Command
+#define B_PCH_LPSS_I2C_STSCMD_RMA                 BIT29 // RMA
+#define B_PCH_LPSS_I2C_STSCMD_RCA                 BIT28 // RCA
+#define B_PCH_LPSS_I2C_STSCMD_CAPLIST             BIT20 // Capability List
+#define B_PCH_LPSS_I2C_STSCMD_INTRSTS             BIT19 // Interrupt Status
+#define B_PCH_LPSS_I2C_STSCMD_INTRDIS             BIT10 // Interrupt Disable
+#define B_PCH_LPSS_I2C_STSCMD_SERREN              BIT8  // SERR# Enable
+#define B_PCH_LPSS_I2C_STSCMD_BME                 BIT2  // Bus Master Enable
+#define B_PCH_LPSS_I2C_STSCMD_MSE                 BIT1  // Memory Space Enable
+
+#define R_PCH_LPSS_I2C_BAR                        0x10  // BAR
+#define B_PCH_LPSS_I2C_BAR_BA                     0xFFFFF000 // Base Address
+#define B_PCH_LPSS_I2C_BAR_SI                     0x00000FF0 // Size Indicator
+#define B_PCH_LPSS_I2C_BAR_PF                     BIT3  // Prefetchable
+#define B_PCH_LPSS_I2C_BAR_TYPE                   (BIT2 | BIT1) // Type
+#define B_PCH_LPSS_I2C_BAR_MS                     BIT0  // Message Space
+
+#define R_PCH_LPSS_I2C_BAR1                       0x14  // BAR 1
+#define B_PCH_LPSS_I2C_BAR1_BA                    0xFFFFF000 // Base Address
+#define B_PCH_LPSS_I2C_BAR1_SI                    0x00000FF0 // Size Indicator
+#define B_PCH_LPSS_I2C_BAR1_PF                    BIT3  // Prefetchable
+#define B_PCH_LPSS_I2C_BAR1_TYPE                  (BIT2 | BIT1) // Type
+#define B_PCH_LPSS_I2C_BAR1_MS                    BIT0  // Message Space
+
+#define NUM_RETRIES         0xFFFF
+
+//
+// LPIO I2C Module Memory Space Registers
+//
+#define R_PCH_LPIO_I2C_MEM_RESETS                 0x804 // Software Reset
+#define B_PCH_LPIO_I2C_MEM_RESETS_FUNC            BIT1  // Function Clock Domain Reset
+#define B_PCH_LPIO_I2C_MEM_RESETS_APB             BIT0  // APB Domain Reset
+
+#define R_PCH_LPSS_I2C_MEM_PCP                    0x800 // Private Clock Parameters
+
+#define  bit(a)                   1 << (a)
+
+//
+// MMIO Register Definitions
+//
+
+#define  I2C0_REG_SPACE_ADDR_BASE            0xFF138000  //01K
+
+#define    R_IC_CON                          ( 0x00) // I2C Control
+#define     B_IC_RESTART_EN                  BIT5
+#define     B_IC_SLAVE_DISABLE               BIT6
+#define     V_SPEED_STANDARD                 0x02
+#define     V_SPEED_FAST                     0x04
+#define     V_SPEED_HIGH                     0x06
+#define     B_MASTER_MODE                    BIT0
+
+#define    R_IC_TAR                          ( 0x04) // I2C Target Address
+#define     IC_TAR_10BITADDR_MASTER           BIT12
+
+#define    R_IC_SAR                          ( 0x08) // I2C Slave Address
+#define    R_IC_HS_MADDR                     ( 0x0C) // I2C HS MasterMode Code Address
+#define    R_IC_DATA_CMD                     ( 0x10) // I2C Rx/Tx Data Buffer and Command
+
+#define    B_READ_CMD                         BIT8    // 1 = read, 0 = write
+#define    B_CMD_STOP                         BIT9    // 1 = STOP
+#define    B_CMD_RESTART                      BIT10   // 1 = IC_RESTART_EN
+
+#define    V_WRITE_CMD_MASK                  ( 0xFF)
+
+#define    R_IC_SS_SCL_HCNT                  ( 0x14) // Standard Speed I2C Clock SCL High Count
+#define    R_IC_SS_SCL_LCNT                  ( 0x18) // Standard Speed I2C Clock SCL Low Count
+#define    R_IC_FS_SCL_HCNT                  ( 0x1C) // Full Speed I2C Clock SCL High Count
+#define    R_IC_FS_SCL_LCNT                  ( 0x20) // Full Speed I2C Clock SCL Low Count
+#define    R_IC_HS_SCL_HCNT                  ( 0x24) // High Speed I2C Clock SCL High Count
+#define    R_IC_HS_SCL_LCNT                  ( 0x28) // High Speed I2C Clock SCL Low Count
+#define    R_IC_INTR_STAT                    ( 0x2C) // I2C Inetrrupt Status
+#define    R_IC_INTR_MASK                    ( 0x30) // I2C Interrupt Mask
+#define     I2C_INTR_GEN_CALL                 BIT11  // General call received
+#define     I2C_INTR_START_DET                BIT10
+#define     I2C_INTR_STOP_DET                 BIT9
+#define     I2C_INTR_ACTIVITY                 BIT8
+#define     I2C_INTR_TX_ABRT                  BIT6   // Set on NACK
+#define     I2C_INTR_TX_EMPTY                 BIT4
+#define     I2C_INTR_TX_OVER                  BIT3
+#define     I2C_INTR_RX_FULL                  BIT2   // Data bytes in RX FIFO over threshold
+#define     I2C_INTR_RX_OVER                  BIT1
+#define     I2C_INTR_RX_UNDER                 BIT0
+#define    R_IC_RawIntrStat                ( 0x34) // I2C Raw Interrupt Status
+#define    R_IC_RX_TL                        ( 0x38) // I2C Receive FIFO Threshold
+#define    R_IC_TX_TL                        ( 0x3C) // I2C Transmit FIFO Threshold
+#define    R_IC_CLR_INTR                     ( 0x40) // Clear Combined and Individual Interrupts
+#define    R_IC_CLR_RX_UNDER                 ( 0x44) // Clear RX_UNDER Interrupt
+#define    R_IC_CLR_RX_OVER                  ( 0x48) // Clear RX_OVERinterrupt
+#define    R_IC_CLR_TX_OVER                  ( 0x4C) // Clear TX_OVER interrupt
+#define    R_IC_CLR_RD_REQ                   ( 0x50) // Clear RD_REQ interrupt
+#define    R_IC_CLR_TX_ABRT                  ( 0x54) // Clear TX_ABRT interrupt
+#define    R_IC_CLR_RX_DONE                  ( 0x58) // Clear RX_DONE interrupt
+#define    R_IC_CLR_ACTIVITY                 ( 0x5C) // Clear ACTIVITY interrupt
+#define    R_IC_CLR_STOP_DET                 ( 0x60) // Clear STOP_DET interrupt
+#define    R_IC_CLR_START_DET                ( 0x64) // Clear START_DET interrupt
+#define    R_IC_CLR_GEN_CALL                 ( 0x68) // Clear GEN_CALL interrupt
+#define    R_IC_ENABLE                       ( 0x6C) // I2C Enable
+#define    R_IC_STATUS                       ( 0x70) // I2C Status
+
+#define    R_IC_SDA_HOLD                     ( 0x7C) // I2C IC_DEFAULT_SDA_HOLD//16bits
+
+#define     STAT_MST_ACTIVITY                 BIT5   // Master FSM Activity Status.
+#define     STAT_RFF                          BIT4   // RX FIFO is completely full
+#define     STAT_RFNE                         BIT3   // RX FIFO is not empty
+#define     STAT_TFE                          BIT2   // TX FIFO is completely empty
+#define     STAT_TFNF                         BIT1   // TX FIFO is not full
+
+#define    R_IC_TXFLR                        ( 0x74) // Transmit FIFO Level Register
+#define    R_IC_RXFLR                        ( 0x78) // Receive FIFO Level Register
+#define    R_IC_TX_ABRT_SOURCE               ( 0x80) // I2C Transmit Abort Status Register
+#define    R_IC_SLV_DATA_NACK_ONLY           ( 0x84) // Generate SLV_DATA_NACK Register
+#define    R_IC_DMA_CR                       ( 0x88) // DMA Control Register
+#define    R_IC_DMA_TDLR                     ( 0x8C) // DMA Transmit Data Level
+#define    R_IC_DMA_RDLR                     ( 0x90) // DMA Receive Data Level
+#define    R_IC_SDA_SETUP                    ( 0x94) // I2C SDA Setup Register
+#define    R_IC_ACK_GENERAL_CALL             ( 0x98) // I2C ACK General Call Register
+#define    R_IC_ENABLE_STATUS                ( 0x9C) // I2C Enable Status Register
+#define    R_IC_COMP_PARAM                   ( 0xF4) // Component Parameter Register
+#define    R_IC_COMP_VERSION                 ( 0xF8) // Component Version ID
+#define    R_IC_COMP_TYPE                    ( 0xFC) // Component Type
+
+#define I2C_SS_SCL_HCNT_VALUE_100M           0x1DD
+#define I2C_SS_SCL_LCNT_VALUE_100M           0x1E4
+#define I2C_FS_SCL_HCNT_VALUE_100M           0x54
+#define I2C_FS_SCL_LCNT_VALUE_100M           0x9a
+#define I2C_HS_SCL_HCNT_VALUE_100M           0x7
+#define I2C_HS_SCL_LCNT_VALUE_100M           0xE
+
+//
+// FIFO write workaround value.
+//
+#define     FIFO_WRITE_DELAY    2
+#define     IC_TAR_10BITADDR_MASTER           BIT12
+#define     FIFO_SIZE                         32
+#define     R_IC_INTR_STAT                    ( 0x2C) // I2c Inetrrupt Status
+#define     R_IC_INTR_MASK                    ( 0x30) // I2c Interrupt Mask
+#define     I2C_INTR_GEN_CALL                 BIT11  // General call received
+#define     I2C_INTR_START_DET                BIT10
+#define     I2C_INTR_STOP_DET                 BIT9
+#define     I2C_INTR_ACTIVITY                 BIT8
+#define     I2C_INTR_TX_ABRT                  BIT6   // Set on NACK
+#define     I2C_INTR_TX_EMPTY                 BIT4
+#define     I2C_INTR_TX_OVER                  BIT3
+#define     I2C_INTR_RX_FULL                  BIT2   // Data bytes in RX FIFO over threshold
+#define     I2C_INTR_RX_OVER                  BIT1
+#define     I2C_INTR_RX_UNDER                 BIT0
+
+/**
+  Programe all I2C controllers on LPSS. 
+  
+  I2C0 is function 1 of LPSS. I2C1 is function 2 of LPSS, etc..
+
+  @param   VOID
+
+  @return  EFI_SUCCESS
+**/
+EFI_STATUS
+ProgramPciLpssI2C (
+  VOID
+  );
+
+/**
+  Reads a Byte from I2C Device.
+ 
+  @param  I2cControllerIndex  I2C Bus no to which the I2C device has been connected
+  @param  SlaveAddress        Device Address from which the byte value has to be read
+  @param  Offset              Offset from which the data has to be read
+  @param  *Byte               Address to which the value read has to be stored
+  @param  Start               Whether a RESTART is issued before the byte is sent or received
+  @param  End                 Whether STOP is generated after a data byte is sent or received  
+                                  
+  @return  EFI_SUCCESS        If the byte value has been successfully read
+  @return  EFI_DEVICE_ERROR   Operation Failed, Device Error
+**/
+EFI_STATUS
+ByteReadI2CBasic(
+  IN  UINT8 I2cControllerIndex,
+  IN  UINT8 SlaveAddress,
+  IN  UINTN ReadBytes,
+  OUT UINT8 *ReadBuffer,
+  IN  UINT8 Start,
+  IN  UINT8 End
+  );
+
+/**
+  Writes a Byte to I2C Device.
+ 
+  @param  I2cControllerIndex   I2C Bus no to which the I2C device has been connected
+  @param  SlaveAddress         Device Address from which the byte value has to be written
+  @param  Offset               Offset from which the data has to be read
+  @param  *Byte                Address to which the value written is stored
+  @param  Start               Whether a RESTART is issued before the byte is sent or received
+  @param  End                 Whether STOP is generated after a data byte is sent or received  
+                                  
+  @return  EFI_SUCCESS         IF the byte value has been successfully written
+  @return  EFI_DEVICE_ERROR    Operation Failed, Device Error
+**/
+EFI_STATUS
+ByteWriteI2CBasic(
+  IN  UINT8 I2cControllerIndex,
+  IN  UINT8 SlaveAddress,
+  IN  UINTN WriteBytes,
+  IN  UINT8 *WriteBuffer,
+  IN  UINT8 Start,
+  IN  UINT8 End
+  );
+
+/**
+  Reads a Byte from I2C Device.
+ 
+  @param  I2cControllerIndex   I2C Bus no to which the I2C device has been connected
+  @param  SlaveAddress         Device Address from which the byte value has to be read
+  @param  Offset               Offset from which the data has to be read
+  @param  ReadBytes            Number of bytes to be read
+  @param  *ReadBuffer          Address to which the value read has to be stored
+                                
+  @return  EFI_SUCCESS       IF the byte value has been successfully read
+  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
+**/
+EFI_STATUS
+ByteReadI2C(
+  IN  UINT8 I2cControllerIndex,
+  IN  UINT8 SlaveAddress,
+  IN  UINT8 Offset,
+  IN  UINTN ReadBytes,
+  OUT UINT8 *ReadBuffer
+  );
+
+/**
+  Writes a Byte to I2C Device.
+ 
+  @param  I2cControllerIndex  I2C Bus no to which the I2C device has been connected
+  @param  SlaveAddress        Device Address from which the byte value has to be written
+  @param  Offset              Offset from which the data has to be written
+  @param  WriteBytes          Number of bytes to be written
+  @param  *Byte               Address to which the value written is stored
+                                
+  @return  EFI_SUCCESS       IF the byte value has been successfully read
+  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
+**/
+EFI_STATUS
+ByteWriteI2C(
+  IN  UINT8 I2cControllerIndex,
+  IN  UINT8 SlaveAddress,
+  IN  UINT8 Offset,
+  IN  UINTN WriteBytes,
+  IN  UINT8 *WriteBuffer
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.inf b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.inf
new file mode 100644
index 0000000000..a78212a0e7
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.inf
@@ -0,0 +1,40 @@
+## @file
+#  Instance of I2C Library.
+#
+#  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = I2CLibPei
+  FILE_GUID                      = 8EF61509-890B-4FF2-B352-1C0E9CDDEC8B
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = LockBoxLib|PEIM
+  CONSTRUCTOR                    = IntelI2CPeiLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources.common]
+  I2CLibPei.c
+  I2CIoLibPei.c
+
+[LibraryClasses]
+  TimerLib
+
+[PPIs]
+  gEfiPeiStallPpiGuid
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/CommonHeader.h b/Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/CommonHeader.h
new file mode 100644
index 0000000000..794c9178f1
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/CommonHeader.h
@@ -0,0 +1,27 @@
+/**@file
+  Common header file shared by all source files.
+
+  This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+**/
+
+#ifndef __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+
+#include <Base.h>
+#include <PchAccess.h>
+
+#include <Library/TimerLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/PcdLib.h>
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.c
new file mode 100644
index 0000000000..af44c6bd27
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.c
@@ -0,0 +1,255 @@
+/** @file
+  ICH9 ACPI Timer implements one instance of Timer Library.
+
+Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+**/
+
+#include "CommonHeader.h"
+
+/**
+  The constructor function enables ACPI IO space.
+
+  If ACPI I/O space not enabled, this function will enable it.
+  It will always return RETURN_SUCCESS.
+
+  @retval EFI_SUCCESS   The constructor always returns RETURN_SUCCESS.
+
+**/
+RETURN_STATUS
+EFIAPI
+IntelPchAcpiTimerLibConstructor (
+  VOID
+  )
+{
+  if ((PchLpcPciCfg8(R_PCH_LPC_ACPI_BASE) & B_PCH_LPC_ACPI_BASE_EN) == 0) {
+  //
+  // If ACPI I/O space is not enabled, program ACPI I/O base address and enable it.
+  //
+    MmioWrite16 (
+      MmPciAddress (
+        0,
+        DEFAULT_PCI_BUS_NUMBER_PCH,
+        PCI_DEVICE_NUMBER_PCH_LPC,
+        PCI_FUNCTION_NUMBER_PCH_LPC,
+        R_PCH_LPC_ACPI_BASE
+        ),
+      ((PcdGet16 (PcdPchAcpiIoPortBaseAddress) & B_PCH_LPC_ACPI_BASE_BAR) | B_PCH_LPC_ACPI_BASE_EN)
+    );
+  }
+  return RETURN_SUCCESS;
+}
+
+/**
+  Internal function to read the current tick counter of ACPI.
+
+  Internal function to read the current tick counter of ACPI.
+
+  @return The tick counter read.
+
+**/
+STATIC
+UINT32
+InternalAcpiGetTimerTick (
+  VOID
+  )
+{
+  return IoRead32 (PcdGet16 (PcdPchAcpiIoPortBaseAddress) + R_PCH_ACPI_PM1_TMR);
+}
+
+/**
+  Stalls the CPU for at least the given number of ticks.
+
+  Stalls the CPU for at least the given number of ticks. It's invoked by
+  MicroSecondDelay() and NanoSecondDelay().
+
+  @param  Delay     A period of time to delay in ticks.
+
+**/
+STATIC
+VOID
+InternalAcpiDelay (
+  IN      UINT32                    Delay
+  )
+{
+  UINT32                            Ticks;
+  UINT32                            Times;
+
+  Times    = Delay >> 22;
+  Delay   &= BIT22 - 1;
+  do {
+    //
+    // The target timer count is calculated here
+    //
+    Ticks    = InternalAcpiGetTimerTick () + Delay;
+    Delay    = BIT22;
+    //
+    // Wait until time out
+    // Delay >= 2^23 could not be handled by this function
+    // Timer wrap-arounds are handled correctly by this function
+    //
+    while (((Ticks - InternalAcpiGetTimerTick ()) & BIT23) == 0) {
+      CpuPause ();
+    }
+  } while (Times-- > 0);
+}
+
+/**
+  Stalls the CPU for at least the given number of microseconds.
+
+  Stalls the CPU for the number of microseconds specified by MicroSeconds.
+
+  @param  MicroSeconds  The minimum number of microseconds to delay.
+
+  @return MicroSeconds
+
+**/
+UINTN
+EFIAPI
+MicroSecondDelay (
+  IN      UINTN                     MicroSeconds
+  )
+{
+  InternalAcpiDelay (
+    (UINT32)DivU64x32 (
+              MultU64x32 (
+                MicroSeconds,
+                V_PCH_ACPI_PM1_TMR_FREQUENCY
+                ),
+              1000000u
+              )
+    );
+  return MicroSeconds;
+}
+
+/**
+  Stalls the CPU for at least the given number of nanoseconds.
+
+  Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
+
+  @param  NanoSeconds The minimum number of nanoseconds to delay.
+
+  @return NanoSeconds
+
+**/
+UINTN
+EFIAPI
+NanoSecondDelay (
+  IN      UINTN                     NanoSeconds
+  )
+{
+  InternalAcpiDelay (
+    (UINT32)DivU64x32 (
+              MultU64x32 (
+                NanoSeconds,
+                V_PCH_ACPI_PM1_TMR_FREQUENCY
+                ),
+              1000000000u
+              )
+    );
+  return NanoSeconds;
+}
+
+/**
+  Retrieves the current value of a 64-bit free running performance counter.
+
+  Retrieves the current value of a 64-bit free running performance counter. The
+  counter can either count up by 1 or count down by 1. If the physical
+  performance counter counts by a larger increment, then the counter values
+  must be translated. The properties of the counter can be retrieved from
+  GetPerformanceCounterProperties().
+
+  @return The current value of the free running performance counter.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounter (
+  VOID
+  )
+{
+  return (UINT64)InternalAcpiGetTimerTick ();
+}
+
+/**
+  Retrieves the 64-bit frequency in Hz and the range of performance counter
+  values.
+
+  If StartValue is not NULL, then the value that the performance counter starts
+  with immediately after is it rolls over is returned in StartValue. If
+  EndValue is not NULL, then the value that the performance counter end with
+  immediately before it rolls over is returned in EndValue. The 64-bit
+  frequency of the performance counter in Hz is always returned. If StartValue
+  is less than EndValue, then the performance counter counts up. If StartValue
+  is greater than EndValue, then the performance counter counts down. For
+  example, a 64-bit free running counter that counts up would have a StartValue
+  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter
+  that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.
+
+  @param  StartValue  The value the performance counter starts with when it
+                      rolls over.
+  @param  EndValue    The value that the performance counter ends with before
+                      it rolls over.
+
+  @return             The frequency in Hz.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounterProperties (
+  OUT      UINT64                    *StartValue,  OPTIONAL
+  OUT      UINT64                    *EndValue     OPTIONAL
+  )
+{
+  if (StartValue != NULL) {
+    *StartValue = 0;
+  }
+
+  if (EndValue != NULL) {
+    *EndValue = V_PCH_ACPI_PM1_TMR_MAX_VAL - 1;
+  }
+
+  return V_PCH_ACPI_PM1_TMR_FREQUENCY;
+}
+
+/**
+  Converts elapsed ticks of performance counter to time in nanoseconds.
+
+  This function converts the elapsed ticks of running performance counter to
+  time value in unit of nanoseconds.
+
+  @param  Ticks     The number of elapsed ticks of running performance counter.
+
+  @return           The elapsed time in nanoseconds.
+
+**/
+UINT64
+EFIAPI
+GetTimeInNanoSecond (
+  IN      UINT64                     Ticks
+  )
+{
+  UINT64  NanoSeconds;
+  UINT32  Remainder;
+
+  //
+  //          Ticks
+  // Time = --------- x 1,000,000,000
+  //        Frequency
+  //
+  NanoSeconds = MultU64x32 (DivU64x32Remainder (Ticks, V_PCH_ACPI_PM1_TMR_FREQUENCY, &Remainder), 1000000000u);
+
+  //
+  // Frequency < 0x100000000, so Remainder < 0x100000000, then (Remainder * 1,000,000,000)
+  // will not overflow 64-bit.
+  //
+  NanoSeconds += DivU64x32 (MultU64x32 ((UINT64) Remainder, 1000000000u), V_PCH_ACPI_PM1_TMR_FREQUENCY);
+
+  return NanoSeconds;
+}
+
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf b/Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
new file mode 100644
index 0000000000..f30d70e01f
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
@@ -0,0 +1,51 @@
+#/** @file
+# Intel ICH9 Acpi Timer Instance
+#
+# ICH9 Acpi timer implements one instance of Timer Library. Acpi timer cannot be programmed,
+#  so it could be used by any types of drivers, including SMM drivers and Runtime drivers.
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+#                                                                                  

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

+#
+#
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = IntelPchAcpiTimerLib
+  FILE_GUID                      = 0C0AC8C1-E368-4d20-85FE-23EFB3DB094E
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = TimerLib
+  EDK_RELEASE_VERSION            = 0x00020000
+  EFI_SPECIFICATION_VERSION      = 0x00020000
+
+  CONSTRUCTOR                    = IntelPchAcpiTimerLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources.common]
+  IntelPchAcpiTimerLib.c
+  CommonHeader.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  PciLib
+  IoLib
+  BaseLib
+
+[Pcd.common]
+  gEfiPchTokenSpaceGuid.PcdPchAcpiIoPortBaseAddress
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens/BoardClkGens.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens/BoardClkGens.c
new file mode 100644
index 0000000000..919032c2df
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens/BoardClkGens.c
@@ -0,0 +1,430 @@
+/** @file
+  Clock generator setting for multiplatform.
+
+  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+**/
+
+#include <BoardClkGens.h>
+#include <Guid/SetupVariable.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Library/BaseMemoryLib.h>
+
+#ifndef __GNUC__
+#pragma optimize( "", off )
+#endif
+
+#define CLKGEN_EN 1
+#define EFI_DEBUG 1
+
+CLOCK_GENERATOR_DETAILS   mSupportedClockGeneratorTable[] =
+{
+  { ClockGeneratorCk410, CK410_GENERATOR_ID , CK410_GENERATOR_SPREAD_SPECTRUM_BYTE, CK410_GENERATOR_SPREAD_SPECTRUM_BIT },
+  { ClockGeneratorCk505, CK505_GENERATOR_ID , CK505_GENERATOR_SPREAD_SPECTRUM_BYTE, CK505_GENERATOR_SPREAD_SPECTRUM_BIT }
+};
+
+/**
+  Configure the clock generator using the SMBUS PPI services.
+
+  This function performs a block write, and dumps debug information.
+
+  @param  PeiServices                General purpose services available to every PEIM.
+  @param  ClockType                  Clock generator's model name.
+  @param  ClockAddress               SMBUS address of clock generator.
+  @param  ConfigurationTableLength   Length of configuration table.
+  @param  ConfigurationTable         Pointer of configuration table.
+
+  @retval EFI_SUCCESS - Operation success.
+
+**/
+EFI_STATUS
+ConfigureClockGenerator (
+  IN     EFI_PEI_SERVICES              **PeiServices,
+  IN     EFI_PEI_SMBUS_PPI                 *SmbusPpi,
+  IN     CLOCK_GENERATOR_TYPE          ClockType,
+  IN     UINT8                         ClockAddress,
+  IN     UINTN                         ConfigurationTableLength,
+  IN OUT UINT8                         *ConfigurationTable
+  )
+{
+
+  EFI_STATUS                    Status;
+  EFI_SMBUS_DEVICE_ADDRESS      SlaveAddress;
+  UINT8                         Buffer[MAX_CLOCK_GENERATOR_BUFFER_LENGTH];
+  UINTN                         Length;
+  EFI_SMBUS_DEVICE_COMMAND      Command;
+#if CLKGEN_CONFIG_EXTRA
+  UINT8                         j;
+#endif
+
+  //
+  // Verify input arguments
+  //
+  ASSERT (ConfigurationTableLength >= 6);
+  ASSERT (ConfigurationTableLength <= MAX_CLOCK_GENERATOR_BUFFER_LENGTH);
+  ASSERT (ClockType < ClockGeneratorMax);
+  ASSERT (ConfigurationTable != NULL);
+
+  //
+  // Read the clock generator
+  //
+  SlaveAddress.SmbusDeviceAddress = ClockAddress >> 1;
+  Length = sizeof (Buffer);
+  Command = 0;
+  Status = SmbusPpi->Execute (
+    PeiServices,
+    SmbusPpi,
+    SlaveAddress,
+    Command,
+    EfiSmbusReadBlock,
+    FALSE,
+    &Length,
+    Buffer
+    );
+  ASSERT_EFI_ERROR (Status);
+
+#ifdef EFI_DEBUG
+  {
+    UINT8 i;
+    for (i = 0; i < sizeof (Buffer); i++) {
+      DEBUG((EFI_D_ERROR, "CK505 default Clock Generator Byte %d: %x\n", i, Buffer[i]));
+    }
+#if CLKGEN_EN
+    for (i = 0; i < ConfigurationTableLength; i++) {
+      DEBUG((EFI_D_ERROR, "BIOS structure Clock Generator Byte %d: %x\n", i, ConfigurationTable[i]));
+    }
+#endif
+  }
+#endif
+
+  DEBUG((EFI_D_ERROR, "Expected Clock Generator ID is %x, expecting %x\n", mSupportedClockGeneratorTable[ClockType].ClockId,(Buffer[7]&0xF)));
+
+  //
+  // Program clock generator
+  //
+  Command = 0;
+#if CLKGEN_EN
+#if CLKGEN_CONFIG_EXTRA
+  for (j = 0; j < ConfigurationTableLength; j++) {
+    Buffer[j] = ConfigurationTable[j];
+  }
+
+  Buffer[30] = 0x00;
+
+  Status = SmbusPpi->Execute (
+    PeiServices,
+    SmbusPpi,
+    SlaveAddress,
+    Command,
+    EfiSmbusWriteBlock,
+    FALSE,
+    &Length,
+    Buffer
+    );
+#else
+  Status = SmbusPpi->Execute (
+    PeiServices,
+    SmbusPpi,
+    SlaveAddress,
+    Command,
+    EfiSmbusWriteBlock,
+    FALSE,
+    &ConfigurationTableLength,
+    ConfigurationTable
+    );
+#endif // CLKGEN_CONFIG_EXTRA
+#else
+    ConfigurationTable[4] = (ConfigurationTable[4] & 0x3) | (Buffer[4] & 0xFC);
+    Command = 4;
+    Length = 1;
+  Status = SmbusPpi->Execute (
+    PeiServices,
+    SmbusPpi,
+    SlaveAddress,
+    Command,
+    EfiSmbusWriteBlock,
+    FALSE,
+    &Length,
+    &ConfigurationTable[4]
+    );
+#endif //CLKGEN_EN
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Dump contents after write
+  //
+  #ifdef EFI_DEBUG
+    {
+      UINT8   i;
+    SlaveAddress.SmbusDeviceAddress = ClockAddress >> 1;
+    Length = sizeof (Buffer);
+      Command = 0;
+      Status =  SmbusPpi->Execute (
+        PeiServices,
+        SmbusPpi,
+        SlaveAddress,
+        Command,
+        EfiSmbusReadBlock,
+        FALSE,
+        &Length,
+        Buffer
+        );
+
+      for (i = 0; i < ConfigurationTableLength; i++) {
+        DEBUG((EFI_D_ERROR, "Clock Generator Byte %d: %x\n", i, Buffer[i]));
+      }
+    }
+    #endif
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Configure the clock generator using the SMBUS PPI services.
+
+  This function performs a block write, and dumps debug information.
+
+  @param  PeiServices                General purpose services available to every PEIM.
+  @param  ClockType                  Clock generator's model name.
+  @param  ClockAddress               SMBUS address of clock generator.
+  @param  ConfigurationTableLength   Length of configuration table.
+  @param  ConfigurationTable         Pointer of configuration table.
+
+
+  @retval  EFI_SUCCESS  Operation success.
+
+**/
+UINT8
+ReadClockGeneratorID (
+  IN     EFI_PEI_SERVICES              **PeiServices,
+  IN     EFI_PEI_SMBUS_PPI                 *SmbusPpi,
+  IN     UINT8                         ClockAddress
+  )
+{
+  EFI_SMBUS_DEVICE_ADDRESS      SlaveAddress;
+  UINT8                         Buffer[MAX_CLOCK_GENERATOR_BUFFER_LENGTH];
+  UINTN                         Length;
+  EFI_SMBUS_DEVICE_COMMAND      Command;
+
+  //
+  // Read the clock generator
+  //
+  SlaveAddress.SmbusDeviceAddress = ClockAddress >> 1;
+  Length = sizeof (Buffer);
+  Command = 0;
+  SmbusPpi->Execute (
+    PeiServices,
+    SmbusPpi,
+    SlaveAddress,
+    Command,
+    EfiSmbusReadBlock,
+    FALSE,
+    &Length,
+    Buffer
+    );
+
+  //
+  // Sanity check that the requested clock type is present in our supported clocks table
+  //
+  DEBUG((EFI_D_ERROR, "Expected Clock Generator ID is 0x%x\n", Buffer[7]));
+
+  return (Buffer[7]);
+}
+
+/**
+  Configure the clock generator to enable free-running operation.  This keeps
+  the clocks from being stopped when the system enters C3 or C4.
+
+  @param None
+
+  @retval EFI_SUCCESS    The function completed successfully.
+
+**/
+EFI_STATUS
+ConfigurePlatformClocks (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *SmbusPpi
+  )
+{
+  //
+  // Comment it out for now
+  // Not supported by Hybrid model.
+  //
+  EFI_STATUS                    Status;
+  UINT8                         *ConfigurationTable;
+
+  CLOCK_GENERATOR_TYPE          ClockType = ClockGeneratorCk505;
+  UINT8                         ConfigurationTable_Desktop[] = CLOCK_GENERATOR_SETTINGS_DESKTOP;
+  UINT8                         ConfigurationTable_Mobile[] = CLOCK_GENERATOR_SETTINGS_MOBILE;
+  UINT8                         ConfigurationTable_Tablet[] = CLOCK_GENERATOR_SEETINGS_TABLET;
+
+  EFI_PLATFORM_INFO_HOB         *PlatformInfoHob;
+  BOOLEAN                       EnableSpreadSpectrum;
+  SYSTEM_CONFIGURATION          SystemConfiguration;
+
+  UINTN                         Length;
+  EFI_SMBUS_DEVICE_COMMAND      Command;
+  EFI_SMBUS_DEVICE_ADDRESS      SlaveAddress;
+  UINT8                         Data;
+
+  UINT8                         ClockAddress = CLOCK_GENERATOR_ADDRESS;
+  UINTN                         VariableSize;
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI   *Variable;
+
+  //
+  // Obtain Platform Info from HOB.
+  //
+  Status = GetPlatformInfoHob ((CONST EFI_PEI_SERVICES **) PeiServices, &PlatformInfoHob);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG((EFI_D_ERROR, "PlatformInfo protocol is working in ConfigurePlatformClocks()...%x\n",PlatformInfoHob->PlatformFlavor));
+
+  //
+  // Locate SMBUS PPI
+  //
+  Status = (**PeiServices).LocatePpi (
+                             (CONST EFI_PEI_SERVICES **) PeiServices,
+                             &gEfiPeiSmbusPpiGuid,
+                             0,
+                             NULL,
+                             &SmbusPpi
+                             );
+  ASSERT_EFI_ERROR (Status);
+
+  Data  = 0;
+  SlaveAddress.SmbusDeviceAddress = ClockAddress >> 1;
+  Length = 1;
+  Command = 0x87;   //Control Register 7 Vendor ID Check
+  Status = ((EFI_PEI_SMBUS_PPI *) SmbusPpi)->Execute (
+                                               PeiServices,
+                                               SmbusPpi,
+                                               SlaveAddress,
+                                               Command,
+                                               EfiSmbusReadByte,
+                                               FALSE,
+                                               &Length,
+                                               &Data
+                                               );
+
+  if (EFI_ERROR (Status) || ((Data & 0x0F) != CK505_GENERATOR_ID)) {
+      DEBUG((EFI_D_ERROR, "Clock Generator CK505 Not Present, vendor ID on board is %x\n",(Data & 0x0F)));
+      return EFI_SUCCESS;
+}
+
+  EnableSpreadSpectrum = FALSE;
+  VariableSize = sizeof (SYSTEM_CONFIGURATION);
+  ZeroMem (&SystemConfiguration, sizeof (SYSTEM_CONFIGURATION));
+
+  Status = (*PeiServices)->LocatePpi (
+                             (CONST EFI_PEI_SERVICES **) PeiServices,
+                             &gEfiPeiReadOnlyVariable2PpiGuid,
+                             0,
+                             NULL,
+                             (VOID **) &Variable
+                             );
+  //
+  // Use normal setup default from NVRAM variable,
+  // the Platform Mode (manufacturing/safe/normal) is handle in PeiGetVariable.
+  //
+  VariableSize = sizeof(SYSTEM_CONFIGURATION);
+  Status = Variable->GetVariable (Variable,
+                                   L"Setup",
+                                   &gEfiSetupVariableGuid,
+                                   NULL,
+                                   &VariableSize,
+                                   &SystemConfiguration);
+  if (EFI_ERROR (Status) || VariableSize != sizeof(SYSTEM_CONFIGURATION)) {
+    //The setup variable is corrupted
+    VariableSize = sizeof(SYSTEM_CONFIGURATION);
+    Status = Variable->GetVariable(Variable,
+              L"SetupRecovery",
+              &gEfiSetupVariableGuid,
+              NULL,
+              &VariableSize,
+              &SystemConfiguration
+              );
+    ASSERT_EFI_ERROR (Status);
+  }  
+  if(!EFI_ERROR (Status)){
+    EnableSpreadSpectrum = SystemConfiguration.EnableClockSpreadSpec;
+  }
+
+  //
+  // Perform platform-specific intialization dependent upon Board ID:
+  //
+  DEBUG((EFI_D_ERROR, "board id is %x, platform id is %x\n",PlatformInfoHob->BoardId,PlatformInfoHob->PlatformFlavor));
+
+
+  switch (PlatformInfoHob->BoardId) {
+    case BOARD_ID_MINNOW2:
+    case BOARD_ID_MINNOW2_TURBOT:
+    default:
+      switch(PlatformInfoHob->PlatformFlavor) {
+      case FlavorTablet:
+        ConfigurationTable = ConfigurationTable_Tablet;
+        Length = sizeof (ConfigurationTable_Tablet);
+        break;
+      case FlavorMobile:
+        ConfigurationTable = ConfigurationTable_Mobile;
+        Length = sizeof (ConfigurationTable_Mobile);
+        break;
+      case FlavorDesktop:
+      default:
+        ConfigurationTable = ConfigurationTable_Desktop;
+        Length = sizeof (ConfigurationTable_Desktop);
+        break;
+      }
+    break;
+    }
+
+  //
+  // Perform common clock initialization:
+  //
+  // Program Spread Spectrum function.
+  //
+  if (EnableSpreadSpectrum)
+  {
+    ConfigurationTable[mSupportedClockGeneratorTable[ClockType].SpreadSpectrumByteOffset] |= mSupportedClockGeneratorTable[ClockType].SpreadSpectrumBitOffset;
+  } else {
+    ConfigurationTable[mSupportedClockGeneratorTable[ClockType].SpreadSpectrumByteOffset] &= ~(mSupportedClockGeneratorTable[ClockType].SpreadSpectrumBitOffset);
+  }
+
+
+#if CLKGEN_EN
+  Status = ConfigureClockGenerator (PeiServices, SmbusPpi, ClockType, ClockAddress, Length, ConfigurationTable);
+  ASSERT_EFI_ERROR (Status);
+#endif // CLKGEN_EN
+  return EFI_SUCCESS;
+}
+
+static EFI_PEI_NOTIFY_DESCRIPTOR    mNotifyList[] = {
+  {
+    EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+    &gEfiPeiSmbusPpiGuid,
+    ConfigurePlatformClocks
+  }
+};
+
+EFI_STATUS
+InstallPlatformClocksNotify (
+  IN CONST EFI_PEI_SERVICES           **PeiServices
+  )
+{
+  EFI_STATUS                    Status;
+
+  DEBUG ((EFI_D_INFO, "InstallPlatformClocksNotify()...\n"));
+
+  Status = (*PeiServices)->NotifyPpi(PeiServices, &mNotifyList[0]);
+  ASSERT_EFI_ERROR (Status);
+  return EFI_SUCCESS;
+
+}
+
+#ifndef __GNUC__
+#pragma optimize( "", on )
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens/BoardClkGens.h b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens/BoardClkGens.h
new file mode 100644
index 0000000000..e153933d72
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens/BoardClkGens.h
@@ -0,0 +1,255 @@
+/**@file
+  Clock generator setting for multiplatform.
+
+  This file includes package header files, library classes.
+
+  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+**/
+
+#ifndef _BOARD_CLK_GEN_H_
+#define _BOARD_CLK_GEN_H_
+
+#include <PiPei.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/SmbusLib.h>
+#include <Ppi/Smbus.h>
+#include <IndustryStandard/SmBus.h>
+#include <Guid/PlatformInfo.h>
+
+
+#define CLOCK_GENERATOR_ADDRESS  0xd2
+
+#define CLOCK_GENERATOR_SEETINGS_TABLET {0xB1, 0x82, 0xFF, 0xBF, 0xFF, 0x80}
+#define CLOCK_GENERATOR_SETTINGS_MOBILE {0xB1, 0x82, 0xFF, 0xBF, 0xFF, 0x80}
+#define CLOCK_GENERATOR_SETTINGS_DESKTOP {0xB1, 0x82, 0xFF, 0xBF, 0xFF, 0x80}
+
+typedef enum {
+  ClockGeneratorCk410,
+  ClockGeneratorCk505,
+  ClockGeneratorMax
+} CLOCK_GENERATOR_TYPE;
+
+typedef struct {
+  CLOCK_GENERATOR_TYPE      ClockType;
+  UINT8                     ClockId;
+  UINT8                     SpreadSpectrumByteOffset;
+  UINT8                     SpreadSpectrumBitOffset;
+} CLOCK_GENERATOR_DETAILS;
+
+#define MAX_CLOCK_GENERATOR_BUFFER_LENGTH           0x20
+
+//
+// CK410 Definitions
+//
+#define CK410_GENERATOR_ID                          0x65
+#define CK410_GENERATOR_SPREAD_SPECTRUM_BYTE        1
+#define CK410_GENERATOR_SPREAD_SPECTRUM_BIT         BIT0
+#define CK410_GENERATOR_CLOCK_FREERUN_BYTE          4
+#define CK410_GENERATOR_CLOCK_FREERUN_BIT           (BIT0 | BIT1 | BIT2)
+
+//
+// CK505 Definitions
+//
+#define VF_CK505_GENERATOR_ID                       0x5
+#define CK505_GENERATOR_ID                          0x5  // Confirmed readout is 5
+#define CK505_GENERATOR_SPREAD_SPECTRUM_BYTE        4
+#define CK505_GENERATOR_SPREAD_SPECTRUM_BIT         (BIT0 | BIT1)
+#define CK505_GENERATOR_PERCENT_SPREAD_BYTE      1
+#define CK505_GENERATOR_PERCENT_MASK        ~(0xE)
+#define CK505_GENERATOR_PERCENT_250_VALUE      0xC
+#define CK505_GENERATOR_PERCENT_050_VALUE      0x4
+#define CK505_GENERATOR_PERCENT_000_VALUE      0x2
+
+//
+// IDT Definitions
+//
+#define IDT_GENERATOR_ID_REVA                       0x1    //IDT Rev A
+#define IDTRevA_GENERATOR_SPREAD_SPECTRUM_BYTE        0
+#define IDTRevA_GENERATOR_SPREAD_SPECTRUM_BIT       BIT0
+#define IDTRevA_GENERATOR_PERCENT_SPREAD_BYTE      5
+#define IDTRevA_GENERATOR_PERCENT_250_VALUE      0xF
+#define IDTRevA_GENERATOR_PERCENT_050_VALUE      0x3
+#define IDTRevA_GENERATOR_PERCENT_000_VALUE      0xE
+#define IDTRevA_GENERATOR_PERCENT_MASK        ~(0xF)
+
+#define IDT_GENERATOR_ID_REVB                       0x11  //IDT RevB
+#define IDT_GENERATOR_ID_REVD                       0x21  //IDT RevD
+
+//
+// CLOCK CONTROLLER
+// SmBus address to read DIMM SPD
+//
+#define SMBUS_BASE_ADDRESS                  0xEFA0
+#define SMBUS_BUS_DEV_FUNC                  0x1F0300
+#define PLATFORM_NUM_SMBUS_RSVD_ADDRESSES   4
+#define SMBUS_ADDR_CH_A_1                   0xA0
+#define SMBUS_ADDR_CH_A_2                   0xA2
+#define SMBUS_ADDR_CH_B_1                   0xA4
+#define SMBUS_ADDR_CH_B_2                   0xA6
+
+//
+// Bits for FWH_DEC_EN1—Firmware Hub Decode Enable Register (LPC I/F—D31:F0)
+//
+#define   B_ICH_LPC_FWH_BIOS_DEC_F0             0x4000
+#define   B_ICH_LPC_FWH_BIOS_DEC_E0             0x1000
+#define   B_ICH_LPC_FWH_BIOS_DEC_E8             0x2000
+#define   B_ICH_LPC_FWH_BIOS_LEG_F              0x0080
+#define   B_ICH_LPC_FWH_BIOS_LEG_E              0x0040
+
+
+//
+// An arbitrary maximum length for clock generator buffers
+//
+#define MAX_CLOCK_GENERATOR_BUFFER_LENGTH           0x20
+
+//
+// SmBus Bus Device Function and Register Definitions
+//
+#define SMBUS_BUS_NUM          0
+#define SMBUS_DEV_NUM          31
+#define SMBUS_FUNC_NUM          3
+#define SMBUS_BUS_DEV_FUNC_NUM    \
+      SB_PCI_CFG_ADDRESS(SMBUS_BUS_NUM, SMBUS_DEV_NUM, SMBUS_FUNC_NUM, 0)
+
+//
+//ICH7: SMBus I/O Space Equates;
+//
+#define  BIT_SLAVE_ADDR    BIT00
+#define  BIT_COMMAND      BIT01
+#define  BIT_DATA      BIT02
+#define  BIT_COUNT      BIT03
+#define  BIT_WORD      BIT04
+#define  BIT_CONTROL      BIT05
+#define  BIT_PEC        BIT06
+#define  BIT_READ      BIT07
+#define  SMBUS_IO_READ_BIT  BIT00
+
+
+#define  SMB_CMD_QUICK      0x00
+#define  SMB_CMD_BYTE      0x04
+#define  SMB_CMD_BYTE_DATA    0x08
+#define  SMB_CMD_WORD_DATA    0x0C
+#define  SMB_CMD_PROCESS_CALL  0x10
+#define  SMB_CMD_BLOCK      0x14
+#define  SMB_CMD_I2C_READ    0x18
+#define  SMB_CMD_RESERVED    0x1c
+
+#define  HST_STS_BYTE_DONE 0x80
+#define SMB_HST_STS    0x000
+#define SMB_HST_CNT    0x002
+#define SMB_HST_CMD    0x003
+#define SMB_HST_ADD    0x004
+#define SMB_HST_DAT_0    0x005
+#define SMB_HST_DAT_1    0x006
+#define SMB_HST_BLK_DAT   0x007
+#define SMB_PEC     0x008
+#define SMB_RCV_SLVA    0x009
+#define SMB_SLV_DAT    0x00A
+#define SMB_AUX_STS    0x00C
+#define SMB_AUX_CTL    0x00D
+#define SMB_SMLINK_PIN_CTL  0x00E
+#define SMB_SMBUS_PIN_CTL  0x00F
+#define SMB_SLV_STS    0x010
+#define SMB_SLV_CMD    0x011
+#define SMB_NTFY_DADDR    0x014
+#define SMB_NTFY_DLOW    0x016
+#define SMB_NTFY_DHIGH    0x017
+
+//
+// PCI Register Definitions - use SmbusPolicyPpi->PciAddress + offset listed below
+//
+#define R_COMMAND                     0x04      // PCI Command Register, 16bit
+#define   B_IOSE                        0x01    // RW
+#define R_BASE_ADDRESS                0x20      // PCI BAR for SMBus I/O
+#define   B_BASE_ADDRESS                0xFFE0  // RW
+#define R_HOST_CONFIGURATION          0x40      // SMBus Host Configuration Register
+#define   B_HST_EN                      0x01    // RW
+#define   B_SMB_SMI_EN                  0x02    // RW
+#define   B_I2C_EN                      0x04    // RW
+//
+// I/O Register Definitions - use SmbusPolicyPpi->BaseAddress + offset listed below
+//
+#define HOST_STATUS_REGISTER      0x00  // Host Status Register R/W
+#define    HST_STS_HOST_BUSY                  0x01  // RO
+#define   HST_STS_INTR                  0x02  // R/WC
+#define   HST_STS_DEV_ERR                  0x04  // R/WC
+#define   HST_STS_BUS_ERR                  0x08  // R/WC
+#define   HST_STS_FAILED                  0x10  // R/WC
+#define   SMBUS_B_SMBALERT_STS          0x20  // R/WC
+#define   HST_STS_INUSE                   0x40  // R/WC
+#define   SMBUS_B_BYTE_DONE_STS         0x80  // R/WC
+#define   SMBUS_B_HSTS_ALL              0xFF  // R/WC
+#define  HOST_CONTROL_REGISTER                  0x02  // Host Control Register R/W
+#define    HST_CNT_INTREN                0x01  // RW
+#define   HST_CNT_KILL                  0x02  // RW
+#define   SMBUS_B_SMB_CMD               0x1C  // RW
+#define     SMBUS_V_SMB_CMD_QUICK         0x00
+#define     SMBUS_V_SMB_CMD_BYTE          0x04
+#define     SMBUS_V_SMB_CMD_BYTE_DATA     0x08
+#define     SMBUS_V_SMB_CMD_WORD_DATA     0x0C
+#define     SMBUS_V_SMB_CMD_PROCESS_CALL  0x10
+#define     SMBUS_V_SMB_CMD_BLOCK         0x14
+#define     SMBUS_V_SMB_CMD_IIC_READ      0x18
+#define   SMBUS_B_LAST_BYTE             0x20  // WO
+#define   HST_CNT_START                 0x40  // WO
+#define   HST_CNT_PEC_EN                0x80  // RW
+#define  HOST_COMMAND_REGISTER                  0x03  // Host Command Register R/W
+#define  XMIT_SLAVE_ADDRESS_REGISTER                   0x04  // Transmit Slave Address Register R/W
+#define   SMBUS_B_RW_SEL                0x01  // RW
+#define   SMBUS_B_ADDRESS               0xFE  // RW
+#define  HOST_DATA_0_REGISTER                   0x05  // Data 0 Register R/W
+#define  HOST_DATA_1_REGISTER                   0x06  // Data 1 Register R/W
+#define  HOST_BLOCK_DATA_BYTE_REGISTER          0x07  // Host Block Data Register R/W
+#define SMBUS_R_PEC                   0x08  // Packet Error Check Data Register R/W
+#define SMBUS_R_RSA                   0x09  // Receive Slave Address Register R/W
+#define   SMBUS_B_SLAVE_ADDR            0x7F  // RW
+#define SMBUS_R_SD                    0x0A  // Receive Slave Data Register R/W
+#define SMBUS_R_AUXS                  0x0C  // Auxiliary Status Register R/WC
+#define   SMBUS_B_CRCE                  0x01  //R/WC
+#define AUXILIARY_CONTROL_REGISTER                  0x0D  // Auxiliary Control Register R/W
+#define   SMBUS_B_AAC                  0x01  //R/W
+#define   SMBUS_B_E32B                 0x02  //R/W
+#define  SMBUS_R_SMLC                  0x0E  // SMLINK Pin Control Register R/W
+#define   SMBUS_B_SMLINK0_CUR_STS       0x01  // RO
+#define   SMBUS_B_SMLINK1_CUR_STS       0x02  // RO
+#define   SMBUS_B_SMLINK_CLK_CTL        0x04  // RW
+#define SMBUS_R_SMBC                  0x0F  // SMBus Pin Control Register R/W
+#define   SMBUS_B_SMBCLK_CUR_STS        0x01  // RO
+#define   SMBUS_B_SMBDATA_CUR_STS       0x02  // RO
+#define   SMBUS_B_SMBCLK_CTL            0x04  // RW
+#define SMBUS_R_SSTS                  0x10  // Slave Status Register R/WC
+#define   SMBUS_B_HOST_NOTIFY_STS       0x01  // R/WC
+#define SMBUS_R_SCMD                  0x11  // Slave Command Register R/W
+#define   SMBUS_B_HOST_NOTIFY_INTREN    0x01  // R/W
+#define   SMBUS_B_HOST_NOTIFY_WKEN      0x02  // R/W
+#define   SMBUS_B_SMBALERT_DIS          0x04  // R/W
+#define SMBUS_R_NDA                   0x14  // Notify Device Address Register RO
+#define   SMBUS_B_DEVICE_ADDRESS        0xFE  // RO
+#define SMBUS_R_NDLB                  0x16  // Notify Data Low Byte Register RO
+#define SMBUS_R_NDHB                  0x17  // Notify Data High Byte Register RO
+#define BUS_TRIES           3       // How many times to retry on Bus Errors
+#define SMBUS_NUM_RESERVED  21      // Number of device addresses that are
+                                    //   reserved by the SMBus spec.
+#define SMBUS_ADDRESS_ARP   0xC2 >> 1
+#define   SMBUS_DATA_PREPARE_TO_ARP   0x01
+#define   SMBUS_DATA_RESET_DEVICE     0x02
+#define   SMBUS_DATA_GET_UDID_GENERAL 0x03
+#define   SMBUS_DATA_ASSIGN_ADDRESS   0x04
+#define SMBUS_GET_UDID_LENGTH 17    // 16 byte UDID + 1 byte address
+
+
+EFI_STATUS
+ConfigurePlatformClocks (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *SmbusPpi
+  );
+
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/BoardGpios.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/BoardGpios.c
new file mode 100644
index 0000000000..5790d045fc
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/BoardGpios.c
@@ -0,0 +1,531 @@
+/** @file
+  Gpio setting for multiplatform..
+
+  Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+**/
+
+#include <BoardGpios.h>
+#include <Guid/SetupVariable.h>
+
+//
+//AlpineValley platform ocde begin
+//
+#define AV_SC_REG_GPIOS_MUXES_SEL0 0x48
+#define AV_SC_REG_GPIOS_MUXES_SEL1 0x4C
+#define AV_SC_REG_GPIOS_MUXES_SEL2 0x50
+#define AV_SC_REG_GPIOS_MUXES_EN0  0x54
+#define AV_SC_REG_GPIOS_MUXES_EN1  0x58
+#define AV_SC_REG_GPIOS_MUXES_EN2  0x5C
+//
+//AlpineValley platform code end
+//
+
+EFI_GUID  gPeiSmbusPpiGuid               = EFI_PEI_SMBUS_PPI_GUID;
+
+/**
+  @param None
+
+  @retval EFI_SUCCESS    The function completed successfully.
+
+**/
+EFI_STATUS
+ConfigurePlatformSysCtrlGpio (
+  IN EFI_PEI_SERVICES                   **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR          *NotifyDescriptor,
+  IN VOID                               *SmbusPpi
+  )
+{
+  //
+  //AlpineValley platform code begin
+  //
+  // Initialize GPIO Settings:
+  //
+  UINT32        Status;
+  EFI_PLATFORM_INFO_HOB               *PlatformInfoHob;
+
+   DEBUG ((EFI_D_INFO, "ConfigurePlatformSysCtrlGpio()...\n"));
+
+  //
+  // Obtain Platform Info from HOB.
+  //
+  Status = GetPlatformInfoHob ((const EFI_PEI_SERVICES **)PeiServices, &PlatformInfoHob);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // The GPIO settings are dependent upon the platform.  Obtain the Board ID through
+  // the EC to determine the current platform.
+  //
+   DEBUG ((EFI_D_INFO, "Platform Flavor | Board ID = 0x%X | 0x%X\n", PlatformInfoHob->PlatformFlavor, PlatformInfoHob->BoardId));
+
+
+
+  Status = (**PeiServices).LocatePpi (
+                            (const EFI_PEI_SERVICES **)PeiServices,
+                            &gPeiSmbusPpiGuid,
+                            0,
+                            NULL,
+                            (void **)&SmbusPpi
+                            );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Select/modify the GPIO initialization data based on the Board ID.
+  //
+  switch (PlatformInfoHob->BoardId)
+  {
+    default:
+      Status = EFI_SUCCESS;
+
+      //
+      // Do nothing for other RVP boards.
+      //
+      break;
+  }
+  return Status;
+}
+
+static EFI_PEI_NOTIFY_DESCRIPTOR    mNotifyList[] = {
+  {
+    EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+    &gEfiPeiSmbusPpiGuid,
+    ConfigurePlatformSysCtrlGpio
+  }
+};
+
+EFI_STATUS
+InstallPlatformSysCtrlGPIONotify (
+  IN CONST EFI_PEI_SERVICES           **PeiServices
+  )
+{
+  EFI_STATUS                    Status;
+
+  DEBUG ((EFI_D_INFO, "InstallPlatformSysCtrlGPIONotify()...\n"));
+
+  Status = (*PeiServices)->NotifyPpi(PeiServices, &mNotifyList[0]);
+  ASSERT_EFI_ERROR (Status);
+  return EFI_SUCCESS;
+
+}
+
+#define V_PCH_ILB_IRQE_UARTIRQEN_IRQ3             BIT3 // UART IRQ3 Enable
+
+/**
+  Returns the Correct GPIO table for Mobile/Desktop respectively.
+  Before call it, make sure PlatformInfoHob->BoardId&PlatformFlavor is get correctly.
+
+  @param PeiServices             General purpose services available to every PEIM.
+  @param PlatformInfoHob         PlatformInfoHob pointer with PlatformFlavor specified.
+  @param BoardId                 BoardId ID as determined through the EC.
+
+  @retval EFI_SUCCESS            The function completed successfully.
+  @retval EFI_DEVICE_ERROR       KSC fails to respond.
+
+**/
+EFI_STATUS
+MultiPlatformGpioTableInit (
+  IN CONST EFI_PEI_SERVICES     **PeiServices,
+  IN EFI_PLATFORM_INFO_HOB      *PlatformInfoHob
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI *PeiReadOnlyVarPpi;
+  UINTN                           VarSize;
+  SYSTEM_CONFIGURATION            SystemConfiguration;
+
+  DEBUG ((EFI_D_INFO, "MultiPlatformGpioTableInit()...\n"));
+
+  //
+  // Select/modify the GPIO initialization data based on the Board ID.
+  //
+  switch (PlatformInfoHob->BoardId) {
+
+  case BOARD_ID_MINNOW2: // Minnow2
+  case BOARD_ID_MINNOW2_TURBOT: 
+   Status = (**PeiServices).LocatePpi (
+                             PeiServices,
+                             &gEfiPeiReadOnlyVariable2PpiGuid,
+                             0,
+                             NULL,
+                             (void **)&PeiReadOnlyVarPpi
+                             );
+    ASSERT_EFI_ERROR (Status);
+   
+    VarSize = sizeof (SYSTEM_CONFIGURATION);
+    Status = PeiReadOnlyVarPpi->GetVariable ( 
+                                  PeiReadOnlyVarPpi, 
+                                  PLATFORM_SETUP_VARIABLE_NAME, 
+                                  &gEfiSetupVariableGuid,
+                                  NULL,
+                                  &VarSize,
+                                  &SystemConfiguration
+                                  );
+                                                                       
+     if (SystemConfiguration.GpioWakeCapability == 1) {
+      PlatformInfoHob->PlatformCfioData     = (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2CfioInitData2;
+     }
+     else {
+      PlatformInfoHob->PlatformCfioData     = (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2CfioInitData;
+     }	
+	 
+     PlatformInfoHob->PlatformGpioData_NC  = (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2_GpioInitData_NC[0];
+     PlatformInfoHob->PlatformGpioData_SC  = (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2_GpioInitData_SC[0];
+     PlatformInfoHob->PlatformGpioData_SUS = (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2_GpioInitData_SUS[0];
+     break;
+
+  }
+
+  return EFI_SUCCESS;
+}
+
+UINT32
+GPIORead32 (
+  IN  UINT32 mmio_conf
+  )
+{
+  UINT32 conf_val;
+  UINT32 i;
+  conf_val = MmioRead32(mmio_conf);
+  for(i=0;i<5;i++){
+    if(conf_val == 0xffffffff)
+      conf_val = MmioRead32(mmio_conf);
+      else
+        break;
+  }
+
+  return conf_val;
+}
+
+/**
+
+  Set GPIO CONF0 and PAD_VAL registers for NC/SC/SUS GPIO clusters
+
+  @param Gpio_Mmio_Offset          GPIO_SCORE_OFFSET or GPIO_NCORE_OFFSET or GPIO_SSUS_OFFSET.
+  @param Gpio_Pin_Num              Pin numbers to config for each GPIO clusters.
+  @param Gpio_Conf_Data            GPIO_CONF_PAD_INIT data array for each GPIO clusters.
+
+**/
+VOID
+InternalGpioConfig (
+  IN UINT32             Gpio_Mmio_Offset,
+  IN UINT32             Gpio_Pin_Num,
+  GPIO_CONF_PAD_INIT*   Gpio_Conf_Data
+  )
+{
+  UINT32    index;
+  UINT32    mmio_conf0;
+  UINT32    mmio_padval;
+  PAD_CONF0 conf0_val;
+  PAD_VAL   pad_val;
+
+  //
+  // GPIO WELL -- Memory base registers
+  //
+
+  // A0 BIOS Spec doesn't mention it although X0 does. comment out now.
+  // GPIO write 0x01001002 to IOBASE + Gpio_Mmio_Offset + 0x0900
+  //
+  for(index=0; index < Gpio_Pin_Num; index++)
+  {
+  	//
+    // Calculate the MMIO Address for specific GPIO pin CONF0 register pointed by index.
+    //
+    mmio_conf0 = IO_BASE_ADDRESS + Gpio_Mmio_Offset + R_PCH_CFIO_PAD_CONF0 + Gpio_Conf_Data[index].offset * 16;
+    mmio_padval= IO_BASE_ADDRESS + Gpio_Mmio_Offset + R_PCH_CFIO_PAD_VAL   + Gpio_Conf_Data[index].offset * 16;
+
+#ifdef EFI_DEBUG
+    DEBUG ((EFI_D_INFO, "%s, ", Gpio_Conf_Data[index].pad_name));
+
+#endif
+    DEBUG ((EFI_D_INFO, "Usage = %d, Func# = %d, IntType = %d, Pull Up/Down = %d, MMIO Base = 0x%08x, ",
+      Gpio_Conf_Data[index].usage,
+      Gpio_Conf_Data[index].func,
+      Gpio_Conf_Data[index].int_type,
+      Gpio_Conf_Data[index].pull,
+      mmio_conf0));
+
+    //
+    // Step 1: PadVal Programming.
+    //
+    pad_val.dw = GPIORead32(mmio_padval);
+
+    //
+    // Config PAD_VAL only for GPIO (Non-Native) Pin
+    //
+    if(Native != Gpio_Conf_Data[index].usage)
+    {
+      pad_val.dw &= ~0x6; // Clear bits 1:2
+      pad_val.dw |= (Gpio_Conf_Data[index].usage & 0x6);  // Set bits 1:2 according to PadVal
+
+        //
+        // set GPO default value
+        //
+        if(Gpio_Conf_Data[index].usage == GPO && Gpio_Conf_Data[index].gpod4 != NA)
+        {
+        pad_val.r.pad_val = Gpio_Conf_Data[index].gpod4;
+        }
+    }
+
+
+    DEBUG ((EFI_D_INFO, "Set PAD_VAL = 0x%08x, ", pad_val.dw));
+
+    MmioWrite32(mmio_padval, pad_val.dw);
+
+    //
+    // Step 2: CONF0 Programming
+    // Read GPIO default CONF0 value, which is assumed to be default value after reset.
+    //
+    conf0_val.dw = GPIORead32(mmio_conf0);
+
+    //
+    // Set Function #
+    //
+    conf0_val.r.Func_Pin_Mux = Gpio_Conf_Data[index].func;
+
+    if(GPO == Gpio_Conf_Data[index].usage)
+    {
+      //
+      // If used as GPO, then internal pull need to be disabled.
+      //
+      conf0_val.r.Pull_assign = 0;  // Non-pull
+    }
+    else
+    {
+      //
+      // Set PullUp / PullDown
+      //
+      if(P_20K_H == Gpio_Conf_Data[index].pull)
+      {
+        conf0_val.r.Pull_assign = 0x1;  // PullUp
+        conf0_val.r.Pull_strength = 0x2;// 20K
+      }
+      else if(P_20K_L == Gpio_Conf_Data[index].pull)
+      {
+        conf0_val.r.Pull_assign = 0x2;  // PullDown
+        conf0_val.r.Pull_strength = 0x2;// 20K
+      }
+      else if(P_10K_H == Gpio_Conf_Data[index].pull)
+      {
+        conf0_val.r.Pull_assign = 0x1; 	// PullUp
+        conf0_val.r.Pull_strength = 0x1;// 10K
+      }
+      else if(P_10K_L == Gpio_Conf_Data[index].pull)
+      {
+        conf0_val.r.Pull_assign = 0x2; 	// PullDown
+        conf0_val.r.Pull_strength = 0x1;// 10K
+      }
+      else if(P_2K_H == Gpio_Conf_Data[index].pull)
+      {
+        conf0_val.r.Pull_assign = 0x1;  // PullUp
+        conf0_val.r.Pull_strength = 0x0;// 2K
+      }
+      else if(P_2K_L == Gpio_Conf_Data[index].pull)
+      {
+        conf0_val.r.Pull_assign = 0x2;  // PullDown
+        conf0_val.r.Pull_strength = 0x0;// 2K
+      }
+      else if(P_NONE == Gpio_Conf_Data[index].pull)
+      {
+        conf0_val.r.Pull_assign = 0;	// Non-pull
+      }
+      else
+      {
+        ASSERT(FALSE);  // Invalid value
+      }
+    }
+
+
+    //
+    // Set INT Trigger Type
+    //
+    conf0_val.dw &= ~0x0f000000;  // Clear bits 27:24
+
+    //
+    // Set INT Trigger Type
+    //
+    if(TRIG_ == Gpio_Conf_Data[index].int_type)
+    {
+      //
+      // Interrupt not capable, clear bits 27:24
+      //
+    }
+    else
+    {
+      conf0_val.dw |= (Gpio_Conf_Data[index].int_type & 0x0f)<<24;
+    }
+
+    DEBUG ((EFI_D_INFO, "Set CONF0 = 0x%08x\n", conf0_val.dw));
+
+    //
+    // Write back the targeted GPIO config value according to platform (board) GPIO setting.
+    //
+    MmioWrite32 (mmio_conf0, conf0_val.dw);
+  }
+
+  //
+  // A0 BIOS Spec doesn't mention it although X0 does. comment out now.
+  // GPIO SCORE write 0x01001002 to IOBASE + 0x0900
+  //
+}
+
+/**
+  Returns the Correct GPIO table for Mobile/Desktop respectively.
+  Before call it, make sure PlatformInfoHob->BoardId&PlatformFlavor is get correctly.
+
+  @param PeiServices               General purpose services available to every PEIM.
+  @param PlatformInfoHob           PlatformInfoHob pointer with PlatformFlavor specified.
+  @param BoardId                   BoardId ID as determined through the EC.
+
+  @retval EFI_SUCCESS              The function completed successfully.
+  @retval EFI_DEVICE_ERROR         KSC fails to respond.
+
+**/
+EFI_STATUS
+MultiPlatformGpioProgram (
+  IN CONST EFI_PEI_SERVICES     **PeiServices,
+  IN EFI_PLATFORM_INFO_HOB      *PlatformInfoHob
+  )
+{
+#if !_SIMIC_
+  CFIO_INIT_STRUCT*           PlatformCfioDataPtr;
+
+  PlatformCfioDataPtr = (CFIO_INIT_STRUCT *) (UINTN) PlatformInfoHob->PlatformCfioData;
+  DEBUG ((EFI_D_INFO, "MultiPlatformGpioProgram()...\n"));
+
+  //
+  //  SCORE GPIO WELL -- IO base registers
+  //
+
+  //
+  // GPIO_USE_SEL Register -> 1 = GPIO 0 = Native
+  //
+  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_USE_SEL, PlatformCfioDataPtr->Use_Sel_SC0);
+
+  //
+  // Set GP_LVL Register
+  //
+  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL , PlatformCfioDataPtr->GP_Lvl_SC0);
+
+  //
+  // GP_IO_SEL Register -> 1 = Input 0 = Output.  If Native Mode don't care
+  //
+  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_IO_SEL, PlatformCfioDataPtr->Io_Sel_SC0);
+
+  //
+  // GPIO Triger Positive Edge Enable Register
+  //
+  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_TPE, PlatformCfioDataPtr->TPE_SC0);
+
+  //
+  //  GPIO Trigger Negative Edge Enable Register
+  //
+  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_TNE, PlatformCfioDataPtr->TNE_SC0);
+
+  //
+  //  GPIO Trigger Status
+  //
+  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_TS, PlatformCfioDataPtr->TS_SC0);
+
+  //
+  // GPIO_USE_SEL2 Register -> 1 = GPIO 0 = Native
+  //
+  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_USE_SEL2, PlatformCfioDataPtr->Use_Sel_SC1);
+
+  //
+  // Set GP_LVL2 Register
+  //
+  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL2, PlatformCfioDataPtr->GP_Lvl_SC1);
+
+  //
+  // GP_IO_SEL2 Register -> 1 = Input 0 = Output.  If Native Mode don't care
+  //
+  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_IO_SEL2, PlatformCfioDataPtr->Io_Sel_SC1);
+
+  //
+  // GPIO_USE_SEL3 Register -> 1 = GPIO 0 = Native
+  //
+  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_USE_SEL3, PlatformCfioDataPtr->Use_Sel_SC2);
+
+  //
+  // Set GP_LVL3 Register
+  //
+  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL3, PlatformCfioDataPtr->GP_Lvl_SC2);
+
+  //
+  // GP_IO_SEL3 Register -> 1 = Input 0 = Output if Native Mode don't care
+  //
+  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_IO_SEL3, PlatformCfioDataPtr->Io_Sel_SC2);
+
+  //
+  //  SUS GPIO WELL -- IO base registers
+  //
+
+  //
+  // GPIO_USE_SEL Register -> 1 = GPIO 0 = Native
+  //
+  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_USE_SEL, PlatformCfioDataPtr->Use_Sel_SS);
+
+  //
+  // Set GP_LVL Register
+  //
+  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_LVL , PlatformCfioDataPtr->GP_Lvl_SS);
+
+  //
+  // GP_IO_SEL Register -> 1 = Input 0 = Output.  If Native Mode don't care.
+  //
+  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_IO_SEL, PlatformCfioDataPtr->Io_Sel_SS);
+
+  //
+  // GPIO Triger Positive Edge Enable Register.
+  //
+  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_TPE, PlatformCfioDataPtr->TPE_SS);
+
+  //
+  //  GPIO Trigger Negative Edge Enable Register.
+  //
+  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_TNE, PlatformCfioDataPtr->TNE_SS);
+
+  //
+  //  GPIO Trigger Status.
+  //
+  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_TS, PlatformCfioDataPtr->TS_SS);
+
+  //
+  //  GPIO Wake Enable.
+  //
+  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_WAKE_EN, PlatformCfioDataPtr->WE_SS);
+
+  //
+  // Config SC/NC/SUS GPIO Pins
+  //
+  switch (PlatformInfoHob->BoardId) {
+    case BOARD_ID_MINNOW2:
+    case BOARD_ID_MINNOW2_TURBOT:
+      DEBUG ((EFI_D_INFO, "Start to config Minnow2 GPIO pins\n"));
+      InternalGpioConfig(GPIO_SCORE_OFFSET, sizeof(mMinnow2_GpioInitData_SC)/sizeof(mMinnow2_GpioInitData_SC[0]),   (GPIO_CONF_PAD_INIT *) (UINTN) PlatformInfoHob->PlatformGpioData_SC);
+      InternalGpioConfig(GPIO_NCORE_OFFSET, sizeof(mMinnow2_GpioInitData_NC)/sizeof(mMinnow2_GpioInitData_NC[0]),   (GPIO_CONF_PAD_INIT *) (UINTN) PlatformInfoHob->PlatformGpioData_NC);
+      InternalGpioConfig(GPIO_SSUS_OFFSET,  sizeof(mMinnow2_GpioInitData_SUS)/sizeof(mMinnow2_GpioInitData_SUS[0]), (GPIO_CONF_PAD_INIT *) (UINTN) PlatformInfoHob->PlatformGpioData_SUS);
+      break;
+    default:
+
+      break;
+  }
+
+   //
+   // configure the CFIO Pnp settings
+   //
+   if (PlatformInfoHob->CfioEnabled) {
+     if (PlatformInfoHob->BoardId == BOARD_ID_MINNOW2 || PlatformInfoHob->BoardId == BOARD_ID_MINNOW2_TURBOT){
+       InternalGpioConfig(GPIO_SCORE_OFFSET, sizeof(mNB_BB_FAB3_GpioInitData_SC_TRI)/sizeof(mNB_BB_FAB3_GpioInitData_SC_TRI[0]), (GPIO_CONF_PAD_INIT *) (UINTN)PlatformInfoHob->PlatformGpioData_SC_TRI);
+     }
+   }
+#else
+   DEBUG ((EFI_D_INFO, "Skip MultiPlatformGpioProgram()...for SIMICS or HYB model\n"));
+#endif
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/BoardGpios.h b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/BoardGpios.h
new file mode 100644
index 0000000000..0e19819b22
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/BoardGpios.h
@@ -0,0 +1,324 @@
+/**@file
+  Gpio setting for multiplatform.
+
+  This file includes package header files, library classes.
+
+  Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+**/
+
+#ifndef _BOARDGPIOS_H_
+#define _BOARDGPIOS_H_
+
+#include <PiPei.h>
+#include "PchAccess.h"
+#include "PlatformBaseAddresses.h"
+#include <../MultiPlatformLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Guid/PlatformInfo.h>
+#include <Ppi/Smbus.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Guid/SetupVariable.h>
+
+
+GPIO_CONF_PAD_INIT mNB_BB_FAB3_GpioInitData_SC_TRI[] =
+{
+//              Pad Name          GPIO Number     Used As   GPO Default  Function#     INT Capable   Interrupt Type   PULL H/L    MMIO Offset
+GPIO_INIT_ITEM("LPC_CLKOUT1       GPIOC_48 "     ,TRISTS   ,NA           ,F0           ,             ,                ,NONE       ,0x41),
+GPIO_INIT_ITEM("PLT_CLK0          GPIOC_96 "     ,TRISTS   ,NA           ,F0           ,             ,                ,NONE       ,0x6a),
+GPIO_INIT_ITEM("PLT_CLK3          GPIOC_99 "     ,TRISTS   ,NA           ,F0           ,             ,                ,NONE       ,0x68),
+};
+
+//
+// Minnow2
+//
+#define MINNOW2_GPIO_USE_SEL_VAL_0_31        0x00000000
+#define MINNOW2_GPIO_USE_SEL_VAL_32_63       0x00000000
+#define MINNOW2_GPIO_USE_SEL_VAL_64_70       0x00000000
+#define MINNOW2_GPIO_USE_SEL_VAL_64_70       0x00000000
+#define MINNOW2_GPIO_USE_SEL_VAL_SUS         0x00000000
+#define MINNOW2_GPIO_USE_SEL_VAL_SUS2        0x00000001
+  
+
+#define MINNOW2_GPIO_IO_SEL_VAL_0_31         0x00000000
+#define MINNOW2_GPIO_IO_SEL_VAL_32_63        0x00000000
+#define MINNOW2_GPIO_IO_SEL_VAL_64_70        0x00000000
+#define MINNOW2_GPIO_IO_SEL_VAL_SUS          0x00000000
+#define MINNOW2_GPIO_IO_SEL_VAL_SUS2         0x00000001   
+
+
+#define MINNOW2_GPIO_LVL_VAL_0_31            0x00000000
+#define MINNOW2_GPIO_LVL_VAL_32_63           0x00000000
+#define MINNOW2_GPIO_LVL_VAL_64_70           0x00000000
+#define MINNOW2_GPIO_LVL_VAL_SUS             0x00000000
+#define MINNOW2_GPIO_LVL_VAL_SUS2            0x00000001   
+
+#define MINNOW2_GPIO_TPE_VAL_0_31            0x00000000
+#define MINNOW2_GPIO_TPE_VAL_SUS             0x00000000
+#define MINNOW2_GPIO_TPE_VAL_SUS2            0x00000001   
+
+#define MINNOW2_GPIO_TNE_VAL_0_31            0x00000000
+#define MINNOW2_GPIO_TNE_VAL_SUS             0x00000000
+#define MINNOW2_GPIO_TNE_VAL_SUS2            0x00000001  
+
+#define MINNOW2_GPIO_TS_VAL_0_31             0x00000000
+#define MINNOW2_GPIO_TS_VAL_SUS              0x00000000
+#define MINNOW2_GPIO_TS_VAL_SUS2             0x00000001   
+
+static CFIO_INIT_STRUCT mMinnow2CfioInitData =
+{
+        MINNOW2_GPIO_USE_SEL_VAL_0_31,
+        MINNOW2_GPIO_USE_SEL_VAL_32_63,
+        MINNOW2_GPIO_USE_SEL_VAL_64_70,
+        MINNOW2_GPIO_USE_SEL_VAL_SUS,
+
+        MINNOW2_GPIO_IO_SEL_VAL_0_31,
+        MINNOW2_GPIO_IO_SEL_VAL_32_63,
+        MINNOW2_GPIO_IO_SEL_VAL_64_70,
+        MINNOW2_GPIO_IO_SEL_VAL_SUS,
+
+        MINNOW2_GPIO_LVL_VAL_0_31,
+        MINNOW2_GPIO_LVL_VAL_32_63,
+        MINNOW2_GPIO_LVL_VAL_64_70,
+        MINNOW2_GPIO_LVL_VAL_SUS,
+
+        MINNOW2_GPIO_TPE_VAL_0_31,
+        MINNOW2_GPIO_TPE_VAL_SUS,
+        MINNOW2_GPIO_TNE_VAL_0_31,
+        MINNOW2_GPIO_TNE_VAL_SUS,
+
+        MINNOW2_GPIO_TS_VAL_0_31,
+        MINNOW2_GPIO_TS_VAL_SUS
+};
+
+static CFIO_INIT_STRUCT mMinnow2CfioInitData2 =
+{
+        MINNOW2_GPIO_USE_SEL_VAL_0_31,
+        MINNOW2_GPIO_USE_SEL_VAL_32_63,
+        MINNOW2_GPIO_USE_SEL_VAL_64_70,
+        MINNOW2_GPIO_USE_SEL_VAL_SUS2,
+
+        MINNOW2_GPIO_IO_SEL_VAL_0_31,
+        MINNOW2_GPIO_IO_SEL_VAL_32_63,
+        MINNOW2_GPIO_IO_SEL_VAL_64_70,
+        MINNOW2_GPIO_IO_SEL_VAL_SUS2,
+
+        MINNOW2_GPIO_LVL_VAL_0_31,
+        MINNOW2_GPIO_LVL_VAL_32_63,
+        MINNOW2_GPIO_LVL_VAL_64_70,
+        MINNOW2_GPIO_LVL_VAL_SUS2,
+
+        MINNOW2_GPIO_TPE_VAL_0_31,
+        MINNOW2_GPIO_TPE_VAL_SUS2,		
+        MINNOW2_GPIO_TNE_VAL_0_31,
+        MINNOW2_GPIO_TNE_VAL_SUS2,
+
+        MINNOW2_GPIO_TS_VAL_0_31,
+        MINNOW2_GPIO_TS_VAL_SUS2
+};
+
+static GPIO_CONF_PAD_INIT mMinnow2_GpioInitData_NC[] =
+{
+//              Pad Name          GPIO Number     Used As   GPO Default   Function#     INT Capable   Interrupt Type   PULL H/L    MMIO Offset
+GPIO_INIT_ITEM("HV_DDI0_HPD       GPIONC_0 "     ,Native   ,NA           ,F2           ,             ,                ,NONE       ,0x13),
+GPIO_INIT_ITEM("HV_DDI0_DDC_SDA   GPIONC_1 "     ,Native   ,NA           ,F2           ,             ,                ,NONE       ,0x12),
+GPIO_INIT_ITEM("HV_DDI0_DDC_SCL   GPIONC_2 "     ,Native   ,NA           ,F2           ,             ,                ,NONE       ,0x11),
+GPIO_INIT_ITEM("PANEL0_VDDEN      GPIONC_3 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x14),
+GPIO_INIT_ITEM("PANEL0_BKLTEN     GPIONC_4 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x15),
+GPIO_INIT_ITEM("PANEL0_BKLTCTL    GPIONC_5 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x16),
+GPIO_INIT_ITEM("HV_DDI1_HPD       GPIONC_6 "     ,Native   ,NA           ,F2           ,             ,                ,NONE       ,0x18),
+GPIO_INIT_ITEM("HV_DDI1_DDC_SDA   GPIONC_7 "     ,Native   ,NA           ,F2           ,             ,                ,NONE       ,0x19),
+GPIO_INIT_ITEM("HV_DDI1_DDC_SCL   GPIONC_8 "     ,Native   ,NA           ,F2           ,             ,                ,NONE       ,0x17),
+GPIO_INIT_ITEM("PANEL1_VDDEN      GPIONC_9 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x10),
+GPIO_INIT_ITEM("PANEL1_BKLTEN     GPIONC_10"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x0e),
+GPIO_INIT_ITEM("PANEL1_BKLTCTL    GPIONC_11"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x0f),
+GPIO_INIT_ITEM("GP_INTD_DSI_TE1   GPIONC_12"     ,GPO      ,NA           ,F0           ,             ,                ,NONE       ,0x0c),
+GPIO_INIT_ITEM("HV_DDI2_DDC_SDA   GPIONC_13"     ,GPI      ,NA           ,F0           ,             ,                ,10K_L      ,0x1a),
+GPIO_INIT_ITEM("HV_DDI2_DDC_SCL   GPIONC_14"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x1b),
+GPIO_INIT_ITEM("GP_CAMERASB00     GPIONC_15"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x01),
+GPIO_INIT_ITEM("GP_CAMERASB01     GPIONC_16"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x04),
+GPIO_INIT_ITEM("GP_CAMERASB02     GPIONC_17"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x08),
+GPIO_INIT_ITEM("GP_CAMERASB03     GPIONC_18"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x0b),
+GPIO_INIT_ITEM("GP_CAMERASB04     GPIONC_19"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x00),
+GPIO_INIT_ITEM("GP_CAMERASB05     GPIONC_20"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x03),
+GPIO_INIT_ITEM("GP_CAMERASB06     GPIONC_21"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x06),
+GPIO_INIT_ITEM("GP_CAMERASB07     GPIONC_22"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x0a),
+GPIO_INIT_ITEM("GP_CAMERASB08     GPIONC_23"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x0d),
+GPIO_INIT_ITEM("GP_CAMERASB09     GPIONC_24"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x02),
+GPIO_INIT_ITEM("GP_CAMERASB10     GPIONC_25"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x05),
+GPIO_INIT_ITEM("GP_CAMERASB11     GPIONC_26"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x09),
+};
+
+
+static GPIO_CONF_PAD_INIT mMinnow2_GpioInitData_SC[] = {
+//              Pad Name          GPIO Number     Used As   GPO Default   Function#     INT Capable   Interrupt Type   PULL H/L    MMIO Offset
+GPIO_INIT_ITEM("SATA_GP0          GPIOC_0  "     ,Native   ,NA           ,F1           ,             ,                ,NONE       ,0x55),
+GPIO_INIT_ITEM("SATA_GP1          GPIOC_1  "     ,Native   ,NA           ,F1           ,             ,                ,NONE       ,0x59),
+GPIO_INIT_ITEM("SATA_LEDN         GPIOC_2  "     ,Native   ,NA           ,F1           ,             ,                ,NONE       ,0x5d),
+GPIO_INIT_ITEM("PCIE_CLKREQ0B     GPIOC_3  "     ,Native   ,NA           ,F1           ,             ,                ,10K_H      ,0x60),
+GPIO_INIT_ITEM("PCIE_CLKREQ1B     GPIOC_4  "     ,Native   ,NA           ,F1           ,             ,                ,10K_H      ,0x63),
+GPIO_INIT_ITEM("PCIE_CLKREQ2B     GPIOC_5  "     ,Native   ,NA           ,F1           ,             ,                ,10K_H      ,0x66),
+GPIO_INIT_ITEM("PCIE_CLKREQ3B     GPIOC_6  "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x62),
+GPIO_INIT_ITEM("SDMMC3_WP         GPIOC_7  "     ,Native   ,NA           ,F2           ,             ,                ,NONE       ,0x65),
+GPIO_INIT_ITEM("HDA_RSTB          GPIOC_8  "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x22),
+GPIO_INIT_ITEM("HDA_SYNC          GPIOC_9  "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x25),
+GPIO_INIT_ITEM("HDA_CLK           GPIOC_10 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x24),
+GPIO_INIT_ITEM("HDA_SDO           GPIOC_11 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x26),
+GPIO_INIT_ITEM("HDA_SDI0          GPIOC_12 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x27),
+GPIO_INIT_ITEM("HDA_SDI1          GPIOC_13 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x23),
+GPIO_INIT_ITEM("HDA_DOCKRSTB      GPIOC_14 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x28),
+GPIO_INIT_ITEM("HDA_DOCKENB       GPIOC_15 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x54),
+GPIO_INIT_ITEM("SDMMC1_CLK        GPIOC_16 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x3e),
+GPIO_INIT_ITEM("SDMMC1_D0         GPIOC_17 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x3d),
+GPIO_INIT_ITEM("SDMMC1_D1         GPIOC_18 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x40),
+GPIO_INIT_ITEM("SDMMC1_D2         GPIOC_19 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x3b),
+GPIO_INIT_ITEM("SDMMC1_D3_CD_B    GPIOC_20 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x36),
+GPIO_INIT_ITEM("MMC1_D4_SD_WE     GPIOC_21 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x38),
+GPIO_INIT_ITEM("MMC1_D5           GPIOC_22 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x3c),
+GPIO_INIT_ITEM("MMC1_D6           GPIOC_23 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x37),
+GPIO_INIT_ITEM("MMC1_D7           GPIOC_24 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x3f),
+GPIO_INIT_ITEM("SDMMC1_CMD        GPIOC_25 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x39),
+GPIO_INIT_ITEM("MMC1_RESET_B      GPIOC_26 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x33),
+GPIO_INIT_ITEM("SDMMC2_CLK        GPIOC_27 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x32),
+GPIO_INIT_ITEM("SDMMC2_D0         GPIOC_28 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x35),
+GPIO_INIT_ITEM("SDMMC2_D1         GPIOC_29 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x2f),
+GPIO_INIT_ITEM("SDMMC2_D2         GPIOC_30 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x34),
+GPIO_INIT_ITEM("SDMMC2_D3_CD_B    GPIOC_31 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x31),
+GPIO_INIT_ITEM("SDMMC2_CMD        GPIOC_32 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x30),
+//
+//Just for test, We make the setting that all is same with Bayleybay.
+//
+GPIO_INIT_ITEM("SDMMC3_CLK        GPIOC_33 "     ,Native   ,NA           ,F1           ,             ,                ,NONE      ,0x2b),
+GPIO_INIT_ITEM("SDMMC3_D0         GPIOC_34 "     ,Native   ,NA           ,F1           ,             ,                ,NONE      ,0x2e),
+GPIO_INIT_ITEM("SDMMC3_D1         GPIOC_35 "     ,Native   ,NA           ,F1           ,YES          ,                ,NONE      ,0x29),
+GPIO_INIT_ITEM("SDMMC3_D2         GPIOC_36 "     ,Native   ,NA           ,F1           ,             ,                ,NONE      ,0x2d),
+GPIO_INIT_ITEM("SDMMC3_D3         GPIOC_37 "     ,Native   ,NA           ,F1           ,             ,                ,NONE      ,0x2a),
+GPIO_INIT_ITEM("SDMMC3_CD_B       GPIOC_38 "     ,Native   ,NA           ,F1           ,YES          ,Edge_Both       ,NONE      ,0x3a),
+GPIO_INIT_ITEM("SDMMC3_CMD        GPIOC_39 "     ,Native   ,NA           ,F1           ,             ,                ,NONE      ,0x2c),
+GPIO_INIT_ITEM("SDMMC3_1P8_EN     GPIOC_40 "     ,Native   ,NA           ,F1           ,             ,                ,NONE      ,0x5f),
+GPIO_INIT_ITEM("SDMMC3_PWR_EN_B   GPIOC_41 "     ,Native   ,NA           ,F1           ,             ,                ,NONE      ,0x69),
+GPIO_INIT_ITEM("LPC_AD0           GPIOC_42 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x46),
+GPIO_INIT_ITEM("LPC_AD1           GPIOC_43 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x44),
+GPIO_INIT_ITEM("LPC_AD2           GPIOC_44 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x43),
+GPIO_INIT_ITEM("LPC_AD3           GPIOC_45 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x42),
+GPIO_INIT_ITEM("LPC_FRAMEB        GPIOC_46 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x45),
+GPIO_INIT_ITEM("LPC_CLKOUT0       GPIOC_47 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x47),
+GPIO_INIT_ITEM("LPC_CLKOUT1       GPIOC_48 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x41),
+GPIO_INIT_ITEM("LPC_CLKRUNB       GPIOC_49 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x48),
+GPIO_INIT_ITEM("ILB_SERIRQ        GPIOC_50 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x56),
+GPIO_INIT_ITEM("SMB_DATA          GPIOC_51 "     ,Native   ,NA           ,F1           ,             ,                ,NONE       ,0x5a),
+GPIO_INIT_ITEM("SMB_CLK           GPIOC_52 "     ,Native   ,NA           ,F1           ,             ,                ,NONE       ,0x58),
+GPIO_INIT_ITEM("SMB_ALERTB        GPIOC_53 "     ,Native   ,NA           ,F1           ,             ,                ,10K_H      ,0x5c),
+GPIO_INIT_ITEM("SPKR              GPIOC_54 "     ,GPI     ,NA           ,F0           ,             ,                ,20K_H      ,0x67),
+GPIO_INIT_ITEM("MHSI_ACDATA       GPIOC_55 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x4d),
+GPIO_INIT_ITEM("MHSI_ACFLAG       GPIOC_56 "     ,GPI      ,NA           ,F0           ,             ,                ,20K_H      ,0x4f),
+GPIO_INIT_ITEM("MHSI_ACWAKE       GPIOC_58 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x4e),
+GPIO_INIT_ITEM("MHSI_CADATA       GPIOC_59 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x51),
+GPIO_INIT_ITEM("MHSI_CAFLAG       GPIOC_60 "     ,GPO      ,HI           ,F0           ,             ,                ,20K_H      ,0x50),
+GPIO_INIT_ITEM("GP_SSP_2_CLK      GPIOC_62 "     ,GPI     ,NA           ,F0           ,             ,                ,20K_H      ,0x0d),
+GPIO_INIT_ITEM("GP_SSP_2_FS       GPIOC_63 "     ,GPI     ,NA           ,F0           ,             ,                ,20K_H      ,0x0c),
+GPIO_INIT_ITEM("GP_SSP_2_RXD      GPIOC_64 "     ,GPI       ,NA           ,F0           ,             ,              ,20K_H      ,0x0f),
+GPIO_INIT_ITEM("GP_SSP_2_TXD      GPIOC_65 "     ,GPI     ,NA           ,F0           ,             ,                ,20K_H      ,0x0e),
+GPIO_INIT_ITEM("SPI1_CS0_B        GPIOC_66 "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x11),
+GPIO_INIT_ITEM("SPI1_MISO         GPIOC_67 "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x12),
+GPIO_INIT_ITEM("SPI1_MOSI         GPIOC_68 "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x13),
+GPIO_INIT_ITEM("SPI1_CLK          GPIOC_69 "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x10),
+GPIO_INIT_ITEM("UART1_RXD         GPIOC_70 "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x02),
+GPIO_INIT_ITEM("UART1_TXD         GPIOC_71 "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x01),
+GPIO_INIT_ITEM("UART1_RTS_B       GPIOC_72 "     ,GPI     ,NA           ,F0           ,             ,                ,20K_H      ,0x00),
+GPIO_INIT_ITEM("UART1_CTS_B       GPIOC_73 "     ,GPI     ,NA           ,F0           ,             ,                ,20K_H      ,0x04),
+GPIO_INIT_ITEM("UART2_RXD         GPIOC_74 "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x06),
+GPIO_INIT_ITEM("UART2_TXD         GPIOC_75 "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x07),
+GPIO_INIT_ITEM("UART2_RTS_B       GPIOC_76 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x09),
+GPIO_INIT_ITEM("UART2_CTS_B       GPIOC_77 "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x08),
+GPIO_INIT_ITEM("I2C0_SDA          GPIOC_78 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x21),
+GPIO_INIT_ITEM("I2C0_SCL          GPIOC_79 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x20),
+GPIO_INIT_ITEM("I2C1_SDA          GPIOC_80 "     ,Native   ,NA           ,F1           ,             ,                ,NONE       ,0x1f),
+GPIO_INIT_ITEM("I2C1_SCL          GPIOC_81 "     ,Native   ,NA           ,F1           ,             ,                ,NONE       ,0x1e),
+GPIO_INIT_ITEM("I2C2_SDA          GPIOC_82 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x1d),
+GPIO_INIT_ITEM("I2C2_SCL          GPIOC_83 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x1b),
+GPIO_INIT_ITEM("I2C3_SDA          GPIOC_84 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x19),
+GPIO_INIT_ITEM("I2C3_SCL          GPIOC_85 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x1c),
+GPIO_INIT_ITEM("I2C4_SDA          GPIOC_86 "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x1a),
+GPIO_INIT_ITEM("I2C4_SCL          GPIOC_87 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x17),
+GPIO_INIT_ITEM("I2C5_SDA          GPIOC_88 "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x15),
+GPIO_INIT_ITEM("I2C5_SCL          GPIOC_89 "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x14),
+GPIO_INIT_ITEM("I2C6_SDA          GPIOC_90 "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x18),
+GPIO_INIT_ITEM("I2C6_SCL          GPIOC_91 "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x16),
+GPIO_INIT_ITEM("I2C_NFC_SDA       GPIOC_92 "     ,GPIO     ,NA           ,F1           ,             ,                ,NONE       ,0x05),
+GPIO_INIT_ITEM("I2C_NFC_SCL       GPIOC_93 "     ,GPO      ,LO           ,F1           ,             ,                ,NONE       ,0x03),
+GPIO_INIT_ITEM("PWM0              GPIOC_94 "     ,Native   ,NA           ,F1           ,             ,                ,20K_L      ,0x0a),
+GPIO_INIT_ITEM("PWM1              GPIOC_95 "     ,Native   ,NA           ,F1           ,             ,                ,20K_L      ,0x0b),
+GPIO_INIT_ITEM("PLT_CLK0          GPIOC_96 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x6a),
+GPIO_INIT_ITEM("PLT_CLK1          GPIOC_97 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x57),
+GPIO_INIT_ITEM("PLT_CLK2          GPIOC_98 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x5b),
+GPIO_INIT_ITEM("PLT_CLK3          GPIOC_99 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x68),
+GPIO_INIT_ITEM("PLT_CLK4          GPIOC_100"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x61),
+GPIO_INIT_ITEM("PLT_CLK5          GPIOC_101"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x64),
+};
+
+static GPIO_CONF_PAD_INIT mMinnow2_GpioInitData_SUS[] = {
+//              Pad Name          GPIO Number     Used As   GPIO Default  Function#     INT Capable   Interrupt Type   PULL H/L    MMIO Offset
+GPIO_INIT_ITEM("GPIO_SUS0         GPIO_SUS0"     ,GPI      ,NA           ,F0           ,             ,                ,20K_H      ,0x1d),
+GPIO_INIT_ITEM("GPIO_SUS1         GPIO_SUS1"     ,GPI      ,NA           ,F0           ,             ,                ,20K_H      ,0x21),
+GPIO_INIT_ITEM("GPIO_SUS2         GPIO_SUS2"     ,GPI      ,NA           ,F0           ,             ,                ,20K_H      ,0x1e),
+GPIO_INIT_ITEM("GPIO_SUS3         GPIO_SUS3"     ,Native   ,NA           ,F6           ,YES          ,Level_Low       ,2K_H       ,0x1f),
+GPIO_INIT_ITEM("GPIO_SUS4         GPIO_SUS4"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x20),
+GPIO_INIT_ITEM("GPIO_SUS5         GPIO_SUS5"     ,GPI      ,NA           ,F0           ,             ,                ,NONE       ,0x22),
+GPIO_INIT_ITEM("GPIO_SUS6         GPIO_SUS6"     ,GPI      ,NA           ,F0           ,             ,                ,NONE       ,0x24),
+GPIO_INIT_ITEM("GPIO_SUS7         GPIO_SUS7"     ,GPI      ,NA           ,F0           ,             ,                ,NONE       ,0x23),
+GPIO_INIT_ITEM("SEC_GPIO_SUS8     GPIO_SUS8"     ,GPO      ,HI           ,F0           ,             ,                ,20K_H      ,0x26),
+GPIO_INIT_ITEM("SEC_GPIO_SUS9     GPIO_SUS9"     ,GPO      ,HI           ,F0           ,             ,                ,20K_H      ,0x25),
+GPIO_INIT_ITEM("SEC_GPIO_SUS10    GPIO_SUS10"    ,GPO      ,HI           ,F0           ,             ,                ,NONE       ,0x12),
+GPIO_INIT_ITEM("SUSPWRDNACK       GPIOS_11 "     ,Native   ,NA           ,F0           ,             ,                ,10K_H      ,0x07),
+GPIO_INIT_ITEM("PMU_SUSCLK        GPIOS_12 "     ,Native   ,NA           ,F0           ,             ,                ,NONE       ,0x0b),
+GPIO_INIT_ITEM("PMU_SLP_S0IX_B    GPIOS_13 "     ,Native   ,NA           ,F0           ,             ,                ,NONE       ,0x14),
+GPIO_INIT_ITEM("PMU_SLP_LAN_B     GPIOS_14 "     ,GPO      ,LO           ,F1           ,             ,                ,10K_H      ,0x11),
+GPIO_INIT_ITEM("PMU_WAKE_B        GPIOS_15 "     ,Native   ,NA           ,F0           ,             ,                ,20K_H      ,0x01),
+GPIO_INIT_ITEM("PMU_PWRBTN_B      GPIOS_16 "     ,Native   ,NA           ,F0           ,             ,                ,20K_H      ,0x08),
+GPIO_INIT_ITEM("PMU_WAKE_LAN_B    GPIOS_17 "     ,GPIO     ,NA           ,F1           ,             ,                ,NONE       ,0x0a),
+GPIO_INIT_ITEM("SUS_STAT_B        GPIOS_18 "     ,GPO      ,NA           ,F1           ,             ,                ,NONE       ,0x13),
+GPIO_INIT_ITEM("USB_OC0_B         GPIOS_19 "     ,Native   ,NA           ,F0           ,             ,                ,10K_H      ,0x0c),
+GPIO_INIT_ITEM("USB_OC1_B         GPIOS_20 "     ,Native   ,NA           ,F0           ,             ,                ,10K_H      ,0x00),
+GPIO_INIT_ITEM("SPI_CS1_B         GPIOS_21 "     ,Native   ,NA           ,F0           ,             ,                ,NONE       ,0x02),
+GPIO_INIT_ITEM("GPIO_DFX0         GPIOS_22 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x17),
+GPIO_INIT_ITEM("GPIO_DFX1         GPIOS_23 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x27),
+GPIO_INIT_ITEM("GPIO_DFX2         GPIOS_24 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x1c),
+GPIO_INIT_ITEM("GPIO_DFX3         GPIOS_25 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x1b),
+GPIO_INIT_ITEM("GPIO_DFX4         GPIOS_26 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x16),
+GPIO_INIT_ITEM("GPIO_DFX5         GPIOS_27 "     ,GPI      ,NA           ,F0           ,             ,                ,20K_H      ,0x15),
+GPIO_INIT_ITEM("GPIO_DFX6         GPIOS_28 "     ,GPI      ,NA           ,F0           ,             ,                ,20K_H      ,0x18),
+GPIO_INIT_ITEM("GPIO_DFX7         GPIOS_29 "     ,GPI      ,NA           ,F0           ,             ,                ,20K_H      ,0x19),
+GPIO_INIT_ITEM("GPIO_DFX8         GPIOS_30 "     ,GPI      ,NA           ,F0           ,             ,                ,20K_H      ,0x1a),
+GPIO_INIT_ITEM("USB_ULPI_0_CLK    GPIOS_31 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x33),
+GPIO_INIT_ITEM("USB_ULPI_0_DATA0  GPIOS_32 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x38),
+GPIO_INIT_ITEM("USB_ULPI_0_DATA1  GPIOS_33 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x36),
+GPIO_INIT_ITEM("USB_ULPI_0_DATA2  GPIOS_34 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x31),
+GPIO_INIT_ITEM("USB_ULPI_0_DATA3  GPIOS_35 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x37),
+GPIO_INIT_ITEM("USB_ULPI_0_DATA4  GPIOS_36 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x30),
+GPIO_INIT_ITEM("USB_ULPI_0_DATA5  GPIOS_37 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x39),
+GPIO_INIT_ITEM("USB_ULPI_0_DATA6  GPIOS_38 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x32),
+GPIO_INIT_ITEM("USB_ULPI_0_DATA7  GPIOS_39 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x3a),
+GPIO_INIT_ITEM("USB_ULPI_0_DIR    GPIOS_40 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x34),
+GPIO_INIT_ITEM("USB_ULPI_0_NXT    GPIOS_41 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x35),
+GPIO_INIT_ITEM("USB_ULPI_0_STP    GPIOS_42 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x3b),
+GPIO_INIT_ITEM("USB_ULPI_0_REFCLK GPIOS_43 "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x28),
+};
+
+EFI_STATUS
+MultiPlatformGpioTableInit (
+  IN CONST EFI_PEI_SERVICES     **PeiServices,
+  IN EFI_PLATFORM_INFO_HOB      *PlatformInfoHob
+  );
+
+EFI_STATUS
+MultiPlatformGpioProgram (
+  IN CONST EFI_PEI_SERVICES     **PeiServices,
+  IN EFI_PLATFORM_INFO_HOB      *PlatformInfoHob
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers/BoardJumpers.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers/BoardJumpers.c
new file mode 100644
index 0000000000..67f5e24ede
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers/BoardJumpers.c
@@ -0,0 +1,30 @@
+/** @file
+  Jumper setting for multiplatform.
+
+  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+**/
+
+#include <BoardJumpers.h>
+
+BOOLEAN
+IsRecoveryJumper (
+  IN CONST EFI_PEI_SERVICES    **PeiServices,
+  IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
+)
+{
+  return FALSE;
+}
+
+BOOLEAN
+IsManufacturingMode(
+  IN CONST EFI_PEI_SERVICES    **PeiServices,
+  IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
+)
+{
+  return FALSE;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers/BoardJumpers.h b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers/BoardJumpers.h
new file mode 100644
index 0000000000..7c1fc88909
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers/BoardJumpers.h
@@ -0,0 +1,30 @@
+/**@file
+  Jumper setting for multiplatform.
+
+  This file includes package header files, library classes.
+
+  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+**/
+
+#ifndef _BOARDJUMPERS_H_
+#define _BOARDJUMPERS_H_
+
+#include <PiPei.h>
+#include "PchAccess.h"
+#include "PlatformBaseAddresses.h"
+
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Guid/PlatformInfo.h>
+
+BOOLEAN
+IsRecoveryJumper (
+  IN CONST EFI_PEI_SERVICES    **PeiServices,
+  IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
+);
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/BoardOemIds.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/BoardOemIds.c
new file mode 100644
index 0000000000..bb3f4c0a33
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/BoardOemIds.c
@@ -0,0 +1,43 @@
+/** @file
+  ACPI oem ids setting for multiplatform.
+
+  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+**/
+
+#include <BoardOemIds.h>
+
+//
+// Global module data
+//
+EFI_STATUS
+InitializeBoardOemId (
+  IN CONST EFI_PEI_SERVICES       **PeiServices,
+  IN EFI_PLATFORM_INFO_HOB        *PlatformInfoHob
+  )
+{
+    UINT64  OemId;
+    UINT64  OemTableId;
+
+    //
+    // Set OEM ID according to Board ID.
+    //
+    switch (PlatformInfoHob->BoardId) {
+
+      case BOARD_ID_MINNOW2:
+      case BOARD_ID_MINNOW2_TURBOT:
+      default:
+        OemId = EFI_ACPI_OEM_ID_DEFAULT;
+        OemTableId = EFI_ACPI_OEM_TABLE_ID_DEFAULT;
+        break;
+    }
+
+    PlatformInfoHob->AcpiOemId = OemId;
+    PlatformInfoHob->AcpiOemTableId = OemTableId;
+    return  EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/BoardOemIds.h b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/BoardOemIds.h
new file mode 100644
index 0000000000..3598a21a61
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/BoardOemIds.h
@@ -0,0 +1,29 @@
+/**@file
+  ACPI oem ids setting for multiplatform.
+
+  This file includes package header files, library classes.
+
+  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+**/
+
+#include <Guid/PlatformInfo.h>
+#include <Library/BaseMemoryLib.h>
+
+#define EFI_ACPI_OEM_ID_DEFAULT    SIGNATURE_64('I', 'N', 'T', 'E', 'L', ' ', ' ', ' ')     // max 6 chars
+#define EFI_ACPI_OEM_ID1           SIGNATURE_64('I', 'N', 'T', 'E', 'L', '1', ' ', ' ')     // max 6 chars
+#define EFI_ACPI_OEM_ID2           SIGNATURE_64('I', 'N', 'T', 'E', 'L', '2', ' ', ' ')     // max 6 chars
+
+#define EFI_ACPI_OEM_TABLE_ID_DEFAULT   SIGNATURE_64('E', 'D', 'K', '2', ' ', ' ', ' ', ' ')
+#define EFI_ACPI_OEM_TABLE_ID1          SIGNATURE_64('E', 'D', 'K', '2', '_', '1', ' ', ' ')
+#define EFI_ACPI_OEM_TABLE_ID2          SIGNATURE_64('E', 'D', 'K', '2', '_', '2', ' ', ' ')
+
+
+EFI_STATUS
+InitializeBoardOemId (
+  IN CONST EFI_PEI_SERVICES      **PeiServices,
+  IN EFI_PLATFORM_INFO_HOB        *PlatformInfoHob
+  );
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid/BoardSsidSvid.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid/BoardSsidSvid.c
new file mode 100644
index 0000000000..77764945c3
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid/BoardSsidSvid.c
@@ -0,0 +1,38 @@
+/** @file
+  Subsystem IDs setting for multiplatform.
+
+  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+**/
+
+#include <BoardSsidSvid.h>
+
+//
+// Global module data
+//
+EFI_STATUS
+InitializeBoardSsidSvid (
+    IN CONST EFI_PEI_SERVICES       **PeiServices,
+    IN EFI_PLATFORM_INFO_HOB        *PlatformInfoHob
+  )
+{
+    UINT32  SsidSvidValue = 0;
+
+    //
+    // Set OEM ID according to Board ID.
+    //
+    switch (PlatformInfoHob->BoardId) {
+      case BOARD_ID_MINNOW2:
+      case BOARD_ID_MINNOW2_TURBOT:
+      default:
+        SsidSvidValue = SUBSYSTEM_SVID_SSID;//SUBSYSTEM_SVID_SSID_DEFAULT;
+        break;
+      }
+    PlatformInfoHob->SsidSvid = SsidSvidValue;
+    return  EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid/BoardSsidSvid.h b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid/BoardSsidSvid.h
new file mode 100644
index 0000000000..6a9995c34c
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid/BoardSsidSvid.h
@@ -0,0 +1,35 @@
+/**@file
+  Subsystem IDs setting for multiplatform.
+
+  This file includes package header files, library classes.
+
+  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+**/
+
+#include <Guid/PlatformInfo.h>
+#include <Library/BaseMemoryLib.h>
+
+//
+// Default Vendor ID and Subsystem ID
+//
+#define SUBSYSTEM_VENDOR_ID1   0x8086
+#define SUBSYSTEM_DEVICE_ID1   0x1999
+#define SUBSYSTEM_SVID_SSID1   (SUBSYSTEM_VENDOR_ID1 + (SUBSYSTEM_DEVICE_ID1 << 16))
+
+#define SUBSYSTEM_VENDOR_ID2   0x8086
+#define SUBSYSTEM_DEVICE_ID2   0x1888
+#define SUBSYSTEM_SVID_SSID2   (SUBSYSTEM_VENDOR_ID2 + (SUBSYSTEM_DEVICE_ID2 << 16))
+
+#define SUBSYSTEM_VENDOR_ID   0x8086
+#define SUBSYSTEM_DEVICE_ID   0x1234
+#define SUBSYSTEM_SVID_SSID   (SUBSYSTEM_VENDOR_ID + (SUBSYSTEM_DEVICE_ID << 16))
+
+EFI_STATUS
+InitializeBoardSsidSvid (
+    IN CONST EFI_PEI_SERVICES       **PeiServices,
+    IN EFI_PLATFORM_INFO_HOB        *PlatformInfoHob
+  );
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib.c
new file mode 100644
index 0000000000..d24e90c7f4
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib.c
@@ -0,0 +1,120 @@
+/** @file
+  Multiplatform initialization.
+
+  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+**/
+
+#include <MultiPlatformLib.h>
+
+/**
+  Platform Type detection. Because the PEI globle variable
+  is in the flash, it could not change directly.So use
+  2 PPIs to distinguish the platform type.
+
+  @param FfsHeader       Pointer to Firmware File System file header.
+  @param PeiServices     General purpose services available to every PEIM.
+
+  @retval EFI_SUCCESS    Memory initialization completed successfully.
+  @retval Others         All other error conditions encountered result in an ASSERT.
+
+**/
+EFI_STATUS
+MultiPlatformInfoInit (
+  IN CONST EFI_PEI_SERVICES             **PeiServices,
+  IN OUT EFI_PLATFORM_INFO_HOB          *PlatformInfoHob
+  )
+{
+  UINT32 PcieLength;
+
+
+  PlatformInfoHob->IohSku = MmPci16(0, MC_BUS, MC_DEV, MC_FUN, PCI_DEVICE_ID_OFFSET);
+
+  PlatformInfoHob->IohRevision = MmPci8(0, MC_BUS, MC_DEV, MC_FUN, PCI_REVISION_ID_OFFSET);
+
+  //
+  // Update ICH Type
+  //
+  //
+  // Device ID
+  //
+  PlatformInfoHob->IchSku = PchLpcPciCfg16(PCI_DEVICE_ID_OFFSET);
+
+  PlatformInfoHob->IchRevision = PchLpcPciCfg8(PCI_REVISION_ID_OFFSET);
+
+  //
+  //64MB
+  //
+  PcieLength = 0x04000000;
+
+  //
+  // Don't support BASE above 4GB currently.
+  //
+  PlatformInfoHob->PciData.PciExpressSize     = PcieLength;
+  PlatformInfoHob->PciData.PciExpressBase     = PcdGet64 (PcdPciExpressBaseAddress);
+
+  PlatformInfoHob->PciData.PciResourceMem32Base  = (UINT32) (PlatformInfoHob->PciData.PciExpressBase - RES_MEM32_MIN_LEN);
+  PlatformInfoHob->PciData.PciResourceMem32Limit = (UINT32) (PlatformInfoHob->PciData.PciExpressBase -1);
+
+  PlatformInfoHob->PciData.PciResourceMem64Base   = RES_MEM64_36_BASE;
+  PlatformInfoHob->PciData.PciResourceMem64Limit  = RES_MEM64_36_LIMIT;
+  PlatformInfoHob->CpuData.CpuAddressWidth        = 36;
+
+  PlatformInfoHob->MemData.MemMir0 = PlatformInfoHob->PciData.PciResourceMem64Base;
+  PlatformInfoHob->MemData.MemMir1 = PlatformInfoHob->PciData.PciResourceMem64Limit + 1;
+
+  PlatformInfoHob->PciData.PciResourceMinSecBus  = 1;  //can be changed by SystemConfiguration->PciMinSecondaryBus;
+
+  //
+  // Set MemMaxTolm to the lowest address between PCIe Base and PCI32 Base.
+  //
+  if (PlatformInfoHob->PciData.PciExpressBase > PlatformInfoHob->PciData.PciResourceMem32Base ) {
+    PlatformInfoHob->MemData.MemMaxTolm = (UINT32) PlatformInfoHob->PciData.PciResourceMem32Base;
+  } else {
+    PlatformInfoHob->MemData.MemMaxTolm = (UINT32) PlatformInfoHob->PciData.PciExpressBase;
+  }
+  PlatformInfoHob->MemData.MemTolm = PlatformInfoHob->MemData.MemMaxTolm;
+
+  //
+  // Platform PCI MMIO Size in unit of 1MB.
+  //
+  PlatformInfoHob->MemData.MmioSize = 0x1000 - (UINT16)(PlatformInfoHob->MemData.MemMaxTolm >> 20);
+
+  //
+  // Enable ICH IOAPIC
+  //
+  PlatformInfoHob->SysData.SysIoApicEnable  = ICH_IOAPIC;
+
+  DEBUG ((EFI_D_ERROR, "PlatformFlavor is %x (%x=tablet,%x=mobile,%x=desktop)\n",
+    PlatformInfoHob->PlatformFlavor,
+    FlavorTablet,
+    FlavorMobile,
+    FlavorDesktop));
+
+  //
+  // Get Platform Info and fill the Hob.
+  //
+  PlatformInfoHob->RevisonId = PLATFORM_INFO_HOB_REVISION;
+
+  //
+  // Get GPIO table
+  //
+  MultiPlatformGpioTableInit (PeiServices, PlatformInfoHob);
+
+  //
+  // Program GPIO
+  //
+  MultiPlatformGpioProgram (PeiServices, PlatformInfoHob);
+
+  //
+  // Update OemId
+  //
+  InitializeBoardOemId (PeiServices, PlatformInfoHob);
+  InitializeBoardSsidSvid (PeiServices, PlatformInfoHob);
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib.h b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib.h
new file mode 100644
index 0000000000..807ca20acb
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib.h
@@ -0,0 +1,89 @@
+/**@file
+  Multiplatform initialization header file.
+
+  This file includes package header files, library classes.
+
+  Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+**/
+
+#ifndef _MULTIPLATFORM_LIB_H_
+#define _MULTIPLATFORM_LIB_H_
+
+
+#define LEN_64M       0x4000000
+
+//
+// Default PCI32 resource size
+//
+#define RES_MEM32_MIN_LEN   0x38000000
+
+#define RES_IO_BASE   0x0D00
+#define RES_IO_LIMIT  0xFFFF
+
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <FrameworkPei.h>
+
+#include "PlatformBaseAddresses.h"
+#include "PchAccess.h"
+#include "SetupMode.h"
+#include "PlatformBootMode.h"
+#include "Platform.h"
+
+#include <Ppi/Stall.h>
+#include <Guid/SetupVariable.h>
+#include <Ppi/AtaController.h>
+#include <Ppi/FindFv.h>
+#include <Ppi/BootInRecoveryMode.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Ppi/Capsule.h>
+#include <Guid/EfiVpdData.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseLib.h>
+#include <IndustryStandard/Pci22.h>
+#include <Ppi/Speaker.h>
+#include <Guid/FirmwareFileSystem.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Ppi/Cache.h>
+#include <Ppi/Reset.h>
+#include <Ppi/EndOfPeiPhase.h>
+#include <Ppi/MemoryDiscovered.h>
+#include <Guid/GlobalVariable.h>
+#include <Ppi/RecoveryModule.h>
+#include <Ppi/DeviceRecoveryModule.h>
+#include <Guid/Capsule.h>
+#include <Guid/RecoveryDevice.h>
+#include <Ppi/MasterBootMode.h>
+#include <Guid/PlatformInfo.h>
+
+#include <BoardOemIds/BoardOemIds.h>
+#include <BoardSsidSvid/BoardSsidSvid.h>
+
+
+EFI_STATUS
+GetPlatformInfoHob (
+  IN CONST EFI_PEI_SERVICES           **PeiServices,
+  OUT EFI_PLATFORM_INFO_HOB     **PlatformInfoHob
+  );
+
+EFI_STATUS
+MultiPlatformGpioTableInit (
+  IN CONST EFI_PEI_SERVICES     **PeiServices,
+  IN EFI_PLATFORM_INFO_HOB      *PlatformInfoHob
+  );
+
+EFI_STATUS
+MultiPlatformGpioProgram (
+  IN CONST EFI_PEI_SERVICES     **PeiServices,
+  IN EFI_PLATFORM_INFO_HOB      *PlatformInfoHob
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib.inf b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib.inf
new file mode 100644
index 0000000000..758e47ca70
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib.inf
@@ -0,0 +1,77 @@
+#
+#
+# Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+#                                                                                  
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#                                                                                  
+#
+#
+#
+#  Module Name:
+#
+#   MultiPlatform.inf
+#
+#  Abstract:
+#
+#
+--*/
+
+
+[defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = MultiPlatformLib
+  FILE_GUID                      = AB83A52B-B44A-462c-B099-444CC0ED274D
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = MultiPlatformLib
+  PI_SPECIFICATION_VERSION       = 0x0001000A
+
+[sources]
+  MultiPlatformLib.c
+  MultiPlatformLib.h
+  PlatformInfoHob.c
+#GPIO
+  BoardGpios/BoardGpios.c
+  BoardGpios/BoardGpios.h
+
+#ClkGen
+  BoardClkGens/BoardClkGens.c
+  BoardClkGens/BoardClkGens.h
+
+#Jumper
+  BoardJumpers/BoardJumpers.c
+  BoardJumpers/BoardJumpers.h
+
+#OemId
+  BoardOemIds/BoardOemIds.c
+  BoardOemIds/BoardOemIds.h
+
+#SSIDSVID
+  BoardSsidSvid/BoardSsidSvid.c
+  BoardSsidSvid/BoardSsidSvid.h
+[Guids]
+
+  gEfiPlatformInfoGuid                     # ALWAYS_CONSUMED
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+  Vlv2SocBinPkg/Vlv2SocBinPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  HobLib
+  IoLib
+#  PeiKscLib
+
+[Ppis]
+  gEfiPeiReadOnlyVariable2PpiGuid
+
+[Pcd.common]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+[Guids]
+  gEfiSetupVariableGuid
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/PlatformInfoHob.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/PlatformInfoHob.c
new file mode 100644
index 0000000000..efa3619a76
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/PlatformInfoHob.c
@@ -0,0 +1,54 @@
+/** @file
+  Platform Hob access interface for multiplatform.
+
+  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+**/
+
+#include <MultiPlatformLib.h>
+
+/**
+  Returns the Platform Info of the platform from the HOB.
+
+  @param PeiServices         General purpose services available to every PEIM.
+  @param PlatformInfoHob     Pointer to the PLATFORM_INFO_HOB Pointer
+
+  @retval EFI_SUCCESS        The function completed successfully.
+  @retval EFI_NOT_FOUND      PlatformInfoHob data doesn't exist, use default instead.
+
+**/
+EFI_STATUS
+GetPlatformInfoHob (
+  IN CONST EFI_PEI_SERVICES           **PeiServices,
+  OUT EFI_PLATFORM_INFO_HOB     **PlatformInfoHob
+  )
+{
+  EFI_PEI_HOB_POINTERS        GuidHob;
+
+  //
+  // Find the PlatformInfo HOB
+  //
+  GuidHob.Raw = GetHobList ();
+  if (GuidHob.Raw == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformInfoGuid, GuidHob.Raw)) != NULL) {
+    *PlatformInfoHob = GET_GUID_HOB_DATA (GuidHob.Guid);
+  }
+
+  //
+  // PlatformInfo PEIM should provide this HOB data, if not ASSERT and return error.
+  //
+  ASSERT (*PlatformInfoHob != NULL);
+  if (!(*PlatformInfoHob)) {
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLib.inf b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLib.inf
new file mode 100644
index 0000000000..6b5cc2861c
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLib.inf
@@ -0,0 +1,50 @@
+#
+#
+#/*++
+#
+#  Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
+#                                                                                  

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

+#
+#  Module Name:
+#
+#    PeiDxePchPlatformLib.inf
+#
+#  Abstract:
+#
+#    Component description file for PEI/DXE PCH Platform Lib
+#
+#--*/
+
+[defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PchPlatformLib
+  FILE_GUID                      = 32F89CBC-305D-4bdd-8B2C-9C65592E66AC
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PchPlatformLib
+
+[sources.common]
+  PchPlatformLibrary.h
+  PchPlatformLibrary.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+
+[LibraryClasses]
+  BaseLib
+  PciLib
+  IoLib
+  DebugLib
+
+
+[Pcd.common]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+
+[Protocols]
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibrary.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibrary.c
new file mode 100644
index 0000000000..c31fd754cb
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibrary.c
@@ -0,0 +1,131 @@
+/**
+
+Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
+                                                                                   

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

+
+  @file
+  PchPlatformLib.c
+
+  @brief
+  PCH Platform Lib implementation.
+
+**/
+
+#include "PchPlatformLibrary.h"
+
+//
+// Silicon Steppings
+//
+/**
+  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;
+    
+    case V_PCH_LPC_RID_E:
+    case V_PCH_LPC_RID_F:
+      return PchD0;
+      break;
+        
+    default:
+      return PchSteppingMax;
+      break;
+
+  }
+}
+
+/**
+  Determine if PCH is supported
+
+  @param[in] None
+
+  @retval TRUE                    PCH is supported
+  @retval FALSE                   PCH is not supported
+
+**/
+BOOLEAN
+IsPchSupported (
+  VOID
+  )
+{
+  UINT32  Identifiers;
+  UINT16  PcuVendorId;
+  UINT16  PcuDeviceId;
+
+  Identifiers = MmioRead32 (
+                  MmPciAddress (0,
+                  DEFAULT_PCI_BUS_NUMBER_PCH,
+                  PCI_DEVICE_NUMBER_PCH_LPC,
+                  PCI_FUNCTION_NUMBER_PCH_LPC,
+                  R_PCH_LPC_REG_ID)
+                );
+
+  PcuDeviceId = (UINT16) ((Identifiers & B_PCH_LPC_DEVICE_ID) >> 16);
+  PcuVendorId = (UINT16) (Identifiers & B_PCH_LPC_VENDOR_ID);
+
+  //
+  // Verify that this is a supported chipset
+  //
+  if (PcuVendorId != (UINT16) V_PCH_LPC_VENDOR_ID || !IS_PCH_VLV_LPC_DEVICE_ID (PcuDeviceId)) {
+    DEBUG ((EFI_D_ERROR, "VLV SC code doesn't support the PcuDeviceId: 0x%04x!\n", PcuDeviceId));
+    return FALSE;
+  }
+  return TRUE;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibrary.h b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibrary.h
new file mode 100644
index 0000000000..da1f77f680
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibrary.h
@@ -0,0 +1,35 @@
+/**
+**/
+/**
+
+Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
+                                                                                   

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

+
+  @file
+  PchPlatformLibrary.h
+
+  @brief
+  Header file for PCH Platform Lib implementation.
+
+**/
+
+#ifndef _PCH_PLATFORM_LIBRARY_IMPLEMENTATION_H_
+#define _PCH_PLATFORM_LIBRARY_IMPLEMENTATION_H_
+
+#include "PchAccess.h"
+#ifdef ECP_FLAG
+#include "EdkIIGlueBase.h"
+#include "Library/EdkIIGlueMemoryAllocationLib.h"
+#else
+#include "Library/PciLib.h"
+#include "Library/IoLib.h"
+#include "Library/DebugLib.h"
+#include "Library/PcdLib.h"
+
+#include "PchCommonDefinitions.h"
+#endif
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/CommonHeader.h b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/CommonHeader.h
new file mode 100644
index 0000000000..e0a1f3a0f7
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/CommonHeader.h
@@ -0,0 +1,32 @@
+/**@file
+  Common header file shared by all source files.
+
+  This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+**/
+
+#ifndef __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+
+#include <Base.h>
+
+#include <Library/TimerLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+#define R_PCH_ACPI_SMI_EN       0x30
+#define B_PCH_ACPI_APMC_EN      0x00000020
+#define B_PCH_ACPI_EOS          0x00000002
+#define B_PCH_ACPI_GBL_SMI_EN   0x00000001
+#define R_PCH_ACPI_SMI_STS      0x34
+#define B_PCH_ACPI_APM_STS      0x00000020
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.c
new file mode 100644
index 0000000000..2b0aacaccf
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.c
@@ -0,0 +1,157 @@
+/** @file
+  PCH Smm Library Services that implements both S/W SMI generation and detection.
+
+  Copyright (c) 2007  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+**/
+
+
+#include "CommonHeader.h"
+
+
+/**
+  Triggers a run time or boot time SMI.
+
+  This function triggers a software SMM interrupt and set the APMC status with an 8-bit Data.
+
+  @param  Data                 The value to set the APMC status.
+
+**/
+VOID
+InternalTriggerSmi (
+  IN UINT8                     Data
+  )
+{
+  ASSERT(FALSE);
+}
+
+
+/**
+  Triggers an SMI at boot time.
+
+  This function triggers a software SMM interrupt at boot time.
+
+**/
+VOID
+EFIAPI
+TriggerBootServiceSoftwareSmi (
+  VOID
+  )
+{
+  ASSERT(FALSE);
+}
+
+
+/**
+  Triggers an SMI at run time.
+
+  This function triggers a software SMM interrupt at run time.
+
+**/
+VOID
+EFIAPI
+TriggerRuntimeSoftwareSmi (
+  VOID
+  )
+{
+  ASSERT(FALSE);
+}
+
+
+/**
+  Gets the software SMI data.
+
+  This function tests if a software SMM interrupt happens. If a software SMI happens,
+  it retrieves the SMM data and returns it as a non-negative value; otherwise a negative
+  value is returned.
+
+  @return Data                 The data retrieved from SMM data port in case of a software SMI;
+                               otherwise a negative value.
+
+**/
+INTN
+InternalGetSwSmiData (
+  VOID
+  )
+{
+  ASSERT(FALSE);
+  return -1;
+}
+
+
+/**
+  Test if a boot time software SMI happened.
+
+  This function tests if a software SMM interrupt happened. If a software SMM interrupt happened and
+  it was triggered at boot time, it returns TRUE. Otherwise, it returns FALSE.
+
+  @retval TRUE   A software SMI triggered at boot time happened.
+  @retval FLASE  No software SMI happened or the software SMI was triggered at run time.
+
+**/
+BOOLEAN
+EFIAPI
+IsBootServiceSoftwareSmi (
+  VOID
+  )
+{
+  ASSERT(FALSE);
+  return FALSE;
+}
+
+
+/**
+  Test if a run time software SMI happened.
+
+  This function tests if a software SMM interrupt happened. If a software SMM interrupt happened and
+  it was triggered at run time, it returns TRUE. Otherwise, it returns FALSE.
+
+  @retval TRUE   A software SMI triggered at run time happened.
+  @retval FLASE  No software SMI happened or the software SMI was triggered at boot time.
+
+**/
+BOOLEAN
+EFIAPI
+IsRuntimeSoftwareSmi (
+  VOID
+  )
+{
+  ASSERT(FALSE);
+  return FALSE;
+}
+
+
+/**
+
+  Clear APM SMI Status Bit; Set the EOS bit.
+
+**/
+VOID
+EFIAPI
+ClearSmi (
+  VOID
+  )
+{
+
+  UINT16                       PmBase;
+
+  //
+  // Get PMBase
+  //
+  PmBase = PcdGet16 (PcdPchAcpiIoPortBaseAddress);
+
+  //
+  // Clear the APM SMI Status Bit
+  //
+  IoWrite16 (PmBase + R_PCH_ACPI_SMI_STS, B_PCH_ACPI_APM_STS);
+
+  //
+  // Set the EOS Bit
+  //
+  IoOr32 (PmBase + R_PCH_ACPI_SMI_EN, B_PCH_ACPI_EOS);
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.inf b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.inf
new file mode 100644
index 0000000000..9d4823d488
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.inf
@@ -0,0 +1,46 @@
+## @file
+# Component description file for Intel Ich7 SMM Library.
+#
+# ICH SMM Library that layers on top of the I/O Library to directly
+#  access SMM power management registers.
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+#                                                                                  

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

+#
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PchSmmLib
+  FILE_GUID                      = A6A16CCB-91B0-42f4-B4F3-D17D7A5662E6
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SmmLib
+
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  PchSmmLib.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  IoLib
+
+[Pcd]
+  gEfiPchTokenSpaceGuid.PcdPchAcpiIoPortBaseAddress
+
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.c
new file mode 100644
index 0000000000..4d5997d6e9
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.c
@@ -0,0 +1,3098 @@
+/** @file
+
+  Copyright (c) 2004  - 2019, Intel Corporation. All rights reserved.<BR>
+                                                                                   
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+                                                                                   
+
+
+Module Name:
+
+  BdsPlatform.c
+
+Abstract:
+
+  This file include all platform action which can be customized
+  by IBV/OEM.
+
+--*/
+
+#include "BdsPlatform.h"
+#include "SetupMode.h"
+#include <Guid/SetupVariable.h>
+#include <Library/TcgPhysicalPresenceLib.h>
+#include <Library/Tcg2PhysicalPresenceLib.h>
+#include <Protocol/I2cMasterMcg.h>
+#include <TianoApi.h>
+#include <PlatformBaseAddresses.h>
+#include <Protocol/GlobalNvsArea.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Protocol/BlockIo.h>
+#include <PchRegs/PchRegsPcu.h>
+#include <Library/S3BootScriptLib.h>
+#include "PchAccess.h"
+#include "PchRegs/PchRegsSata.h"
+#include <Library/SerialPortLib.h>
+#include <Library/DebugLib.h>
+
+#include <Library/GenericBdsLib/InternalBdsLib.h>
+#include <Library/GenericBdsLib/String.h>
+#include <Library/NetLib.h>
+
+#include <Library/CapsuleLib.h>
+#include <Protocol/EsrtManagement.h>
+
+EFI_GUID *ConnectDriverTable[] = {
+  &gEfiMmioDeviceProtocolGuid,
+  &gEfiI2cMasterProtocolGuid,
+  &gEfiI2cHostProtocolGuid
+};
+
+#define SHELL_ENVIRONMENT_INTERFACE_PROTOCOL \
+  { \
+    0x47c7b221, 0xc42a, 0x11d2, 0x8e, 0x57, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b \
+  }
+VOID               *mShellImageCallbackReg = NULL;
+
+
+
+EFI_USER_PROFILE_HANDLE                           mCurrentUser = NULL;
+EFI_EVENT                                         mHotKeyTimerEvent = NULL;
+EFI_EVENT                                         mHitHotkeyEvent = NULL;
+EFI_EVENT                                         mUsbKeyboardConnectEvent = NULL;
+BOOLEAN                                           mHotKeyPressed = FALSE;
+VOID                                              *mHitHotkeyRegistration;
+#define KEYBOARD_TIMER_INTERVAL                   20000 // 0.02s
+
+VOID
+ConnectUSBController (
+  VOID
+  );
+
+EFI_STATUS
+PlatformBdsConnectSimpleConsole (
+  IN BDS_CONSOLE_CONNECT_ENTRY   *PlatformConsole
+);
+
+VOID 
+BootIntoFirmwareInterface(
+  VOID
+  );
+  
+VOID
+EFIAPI
+PlatformBdsInitHotKeyEvent (
+  VOID
+  );
+
+VOID
+EFIAPI
+DisableAhciCtlr (
+  IN EFI_EVENT                          Event,
+  IN VOID                               *Context
+  )
+{
+  UINT32                    PmcDisableAddress;
+  UINT8                     SataStorageAmount;
+  UINT32                    SataBase;
+  UINT16                    SataPortStatus;
+
+
+  DEBUG ((EFI_D_INFO, "Disable AHCI event is signalled\n"));
+  SataStorageAmount = 0;
+  SataBase = *(UINT32*) Context;
+
+  //
+  // BayTrail-M EDS chapter 16 ---- PCI IO Register Offset 92 (SATA Port Control and Status)
+  //
+  SataPortStatus = MmioRead16 (SataBase + R_PCH_SATA_PCS);
+
+  //
+  // Bit 8 EN: Port 0 Present
+  //
+  if ((SataPortStatus & 0x100) == 0x100) {
+    SataStorageAmount++;
+  }
+
+  //
+  // Bit 9 EN: Port 1 Present
+  //
+  if ((SataPortStatus & 0x200) == 0x200) {
+    SataStorageAmount++;
+  }
+
+  //
+  // Disable SATA controller when it sets to AHCI mode without carrying any devices
+  // in order to prevent AHCI yellow bang under Win device manager.
+  //
+  if (SataStorageAmount == 0) {
+    PmcDisableAddress = (MmioRead32 ((PCH_PCI_EXPRESS_BASE_ADDRESS + (UINT32) (31 << 15)) + R_PCH_LPC_PMC_BASE) & B_PCH_LPC_PMC_BASE_BAR) + R_PCH_PMC_FUNC_DIS;
+    MmioOr32 (PmcDisableAddress, B_PCH_PMC_FUNC_DIS_SATA);
+    S3BootScriptSaveMemWrite (
+      EfiBootScriptWidthUint32,
+      (UINTN) PmcDisableAddress,
+      1,
+      (VOID *) (UINTN) PmcDisableAddress
+      );
+  }
+}
+
+VOID
+InstallReadyToLock (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  EFI_HANDLE                Handle;
+  EFI_SMM_ACCESS2_PROTOCOL  *SmmAccess;
+  EFI_ACPI_S3_SAVE_PROTOCOL *AcpiS3Save;
+
+  //
+  // Install DxeSmmReadyToLock protocol prior to the processing of boot options
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiSmmAccess2ProtocolGuid,
+                  NULL,
+                  (VOID **) &SmmAccess
+                  );
+  if (!EFI_ERROR (Status)) {
+
+    //
+    // Prepare S3 information, this MUST be done before DxeSmmReadyToLock
+    //
+    Status = gBS->LocateProtocol (
+                    &gEfiAcpiS3SaveProtocolGuid,
+                    NULL,
+                    (VOID **)&AcpiS3Save
+                    );
+    if (!EFI_ERROR (Status)) {
+      AcpiS3Save->S3Save (AcpiS3Save, NULL);
+    }
+
+    Handle = NULL;
+    Status = gBS->InstallProtocolInterface (
+                    &Handle,
+                    &gExitPmAuthProtocolGuid,
+                    EFI_NATIVE_INTERFACE,
+                    NULL
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    //
+    // Signal EndOfDxe PI Event
+    //
+    EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);
+
+    Handle = NULL;
+    Status = gBS->InstallProtocolInterface (
+                    &Handle,
+                    &gEfiDxeSmmReadyToLockProtocolGuid,
+                    EFI_NATIVE_INTERFACE,
+                    NULL
+                    );
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  return ;
+}
+
+VOID
+EFIAPI
+ShellImageCallback (
+  IN EFI_EVENT                          Event,
+  IN VOID                               *Context
+  )
+{
+ BdsSetConsoleMode (TRUE);
+ DEBUG ((EFI_D_INFO, "BdsEntry ShellImageCallback \n"));
+}
+
+//
+// BDS Platform Functions
+//
+/**
+  Platform Bds init. Include the platform firmware vendor, revision
+  and so crc check.
+
+  @param VOID
+
+  @retval  None.
+
+**/
+VOID
+EFIAPI
+PlatformBdsInit (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+  EFI_EVENT   ShellImageEvent;
+  EFI_GUID    ShellEnvProtocol = SHELL_ENVIRONMENT_INTERFACE_PROTOCOL;
+
+  #ifdef __GNUC__
+  SerialPortWrite((UINT8 *)">>>>BdsEntry[GCC]\r\n", 19);
+  #else
+  SerialPortWrite((UINT8 *)">>>>BdsEntry\r\n", 14);
+  #endif
+  BdsLibSaveMemoryTypeInformation ();
+
+  //
+  // Before user authentication, the user identification devices need be connected
+  // from the platform customized device paths
+  //
+  PlatformBdsConnectAuthDevice ();
+
+  //
+  // As console is not ready, the auto logon user will be identified.
+  //
+  BdsLibUserIdentify (&mCurrentUser);
+
+  //
+  // Change Gop mode when boot into Shell
+  //
+  if (mShellImageCallbackReg == NULL) {
+    Status = gBS->CreateEvent (
+                    EFI_EVENT_NOTIFY_SIGNAL,
+                    EFI_TPL_CALLBACK,
+                    ShellImageCallback,
+                    NULL,
+                    &ShellImageEvent
+                    );
+    if (!EFI_ERROR (Status)) {
+      Status = gBS->RegisterProtocolNotify (
+                      &ShellEnvProtocol,
+                      ShellImageEvent,
+                      &mShellImageCallbackReg
+                      );
+
+      DEBUG ((EFI_D_INFO, "BdsEntry ShellImageCallback \n"));
+    }
+  }
+}
+
+EFI_STATUS
+GetGopDevicePath (
+   IN  EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,
+   OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath
+   )
+{
+  UINTN                           Index;
+  EFI_STATUS                      Status;
+  EFI_HANDLE                      PciDeviceHandle;
+  EFI_DEVICE_PATH_PROTOCOL        *TempDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL        *TempPciDevicePath;
+  UINTN                           GopHandleCount;
+  EFI_HANDLE                      *GopHandleBuffer;
+
+  UINTN                                 VarSize;
+  SYSTEM_CONFIGURATION  mSystemConfiguration;
+
+  if (PciDevicePath == NULL || GopDevicePath == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Initialize the GopDevicePath to be PciDevicePath
+  //
+  *GopDevicePath    = PciDevicePath;
+  TempPciDevicePath = PciDevicePath;
+
+  Status = gBS->LocateDevicePath (
+                  &gEfiDevicePathProtocolGuid,
+                  &TempPciDevicePath,
+                  &PciDeviceHandle
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Try to connect this handle, so that GOP driver could start on this
+  // device and create child handles with GraphicsOutput Protocol installed
+  // on them, then we get device paths of these child handles and select
+  // them as possible console device.
+  //
+
+  //
+  // Select display devices
+  //
+  VarSize = sizeof(SYSTEM_CONFIGURATION);
+  Status = gRT->GetVariable(
+                  L"Setup",
+                  &gEfiNormalSetupGuid,
+                  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",
+              &gEfiNormalSetupGuid,
+              NULL,
+              &VarSize,
+              &mSystemConfiguration
+              );
+    ASSERT_EFI_ERROR (Status);
+  }    
+
+  if(mSystemConfiguration.BootDisplayDevice != 0x0)
+  {
+    ACPI_ADR_DEVICE_PATH         AcpiAdr;
+    EFI_DEVICE_PATH_PROTOCOL  *MyDevicePath = NULL;
+
+    AcpiAdr.Header.Type     = ACPI_DEVICE_PATH;
+    AcpiAdr.Header.SubType  = ACPI_ADR_DP;
+
+    switch (mSystemConfiguration.BootDisplayDevice) {
+    case 1:
+      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, PORT_CRT, 0);    //CRT Device
+      break;
+    case 2:
+      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_B_HDMI, 0);  //HDMI Device Port B
+      break;
+    case 3:
+      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_B_DP, 0);    //DP PortB
+      break;
+    case 4:
+      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_C_DP, 0);    //DP PortC
+      break;
+    case 5:
+      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_C_DP, 0);    //eDP Port C
+      break;
+    case 6:
+      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_MIPI_A, 0);  //DSI Port A
+      break;
+    case 7:
+      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_MIPI_C, 0);  //DSI Port C
+      break;
+    default:
+      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, PORT_CRT, 0);
+      break;
+    }
+
+    SetDevicePathNodeLength (&AcpiAdr.Header, sizeof (ACPI_ADR_DEVICE_PATH));
+
+    MyDevicePath = AppendDevicePathNode(MyDevicePath, (EFI_DEVICE_PATH_PROTOCOL*)&AcpiAdr);
+
+    gBS->ConnectController (
+           PciDeviceHandle,
+           NULL,
+           MyDevicePath,
+           FALSE
+           );
+
+    FreePool(MyDevicePath);
+  }
+  else
+  {
+    gBS->ConnectController (
+           PciDeviceHandle,
+           NULL,
+           NULL,
+           FALSE
+           );
+  }
+
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiGraphicsOutputProtocolGuid,
+                  NULL,
+                  &GopHandleCount,
+                  &GopHandleBuffer
+                  );
+  if (!EFI_ERROR (Status)) {
+    //
+    // Add all the child handles as possible Console Device
+    //
+    for (Index = 0; Index < GopHandleCount; Index++) {
+      Status = gBS->HandleProtocol (
+                      GopHandleBuffer[Index],
+                      &gEfiDevicePathProtocolGuid,
+                      (VOID**)&TempDevicePath
+                      );
+      if (EFI_ERROR (Status)) {
+        continue;
+      }
+      if (CompareMem (
+            PciDevicePath,
+            TempDevicePath,
+            GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH
+            ) == 0) {
+        //
+        // In current implementation, we only enable one of the child handles
+        // as console device, i.e. sotre one of the child handle's device
+        // path to variable "ConOut"
+        // In future, we could select all child handles to be console device
+        //
+        *GopDevicePath = TempDevicePath;
+      }
+    }
+    gBS->FreePool (GopHandleBuffer);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Search out all the platform pci or agp video device. The function may will
+  find multiple video device, and return all enabled device path.
+
+  @param PlugInPciVgaDevicePath    Return the platform plug in pci video device
+                                   path if the system have plug in pci video device.
+  @param OnboardPciVgaDevicePath   Return the platform active agp video device path
+                                   if the system have plug in agp video device or on
+                                   chip agp device.
+
+  @retval EFI_SUCCSS               Get all platform active video device path.
+  @retval EFI_STATUS               Return the status of gBS->LocateDevicePath (),
+                                   gBS->ConnectController (),
+                                   and gBS->LocateHandleBuffer ().
+
+**/
+EFI_STATUS
+GetPlugInPciVgaDevicePath (
+  IN OUT EFI_DEVICE_PATH_PROTOCOL     **PlugInPciVgaDevicePath,
+  IN OUT EFI_DEVICE_PATH_PROTOCOL     **OnboardPciVgaDevicePath
+  )
+{
+  EFI_STATUS                Status;
+  EFI_HANDLE                RootHandle;
+  UINTN                     HandleCount;
+  EFI_HANDLE                *HandleBuffer;
+  UINTN                     Index;
+  UINTN                     Index1;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  BOOLEAN                   PlugInPciVga;
+  EFI_PCI_IO_PROTOCOL       *PciIo;
+  PCI_TYPE00                Pci;
+
+  DevicePath = NULL;
+  PlugInPciVga = TRUE;
+  HandleCount = 0;
+  HandleBuffer = NULL;
+
+  //
+  // Make all the PCI_IO protocols on PCI Seg 0 show up
+  //
+  BdsLibConnectDevicePath (gPlatformRootBridges[0]);
+
+  Status = gBS->LocateDevicePath (
+                  &gEfiDevicePathProtocolGuid,
+                  &gPlatformRootBridges[0],
+                  &RootHandle
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = gBS->ConnectController (
+                  RootHandle,
+                  NULL,
+                  NULL,
+                  FALSE
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Start to check all the pci io to find all possible VGA device
+  //
+  HandleCount = 0;
+  HandleBuffer = NULL;
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiPciIoProtocolGuid,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  for (Index = 0; Index < HandleCount; Index++) {
+    Status = gBS->HandleProtocol (
+                    HandleBuffer[Index],
+                    &gEfiPciIoProtocolGuid,
+                    (VOID**)&PciIo
+                    );
+    if (!EFI_ERROR (Status)) {
+
+      //
+      // Check for all VGA device
+      //
+      Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint32,
+                        0,
+                        sizeof (Pci) / sizeof (UINT32),
+                        &Pci
+                        );
+      if (EFI_ERROR (Status)) {
+        continue;
+      }
+
+      //
+      // Here we decide which VGA device to enable in PCI bus
+      //
+      // The first plugin PCI VGA card device will be present as PCI VGA
+      // The onchip AGP or AGP card will be present as AGP VGA
+      //
+      if (!IS_PCI_VGA (&Pci)) {
+        continue;
+      }
+
+      //
+      // Set the device as the possible console out device,
+      //
+      // Below code will make every VGA device to be one
+      // of the possibe console out device
+      //
+      PlugInPciVga = TRUE;
+      gBS->HandleProtocol (
+             HandleBuffer[Index],
+             &gEfiDevicePathProtocolGuid,
+             (VOID**)&DevicePath
+             );
+
+      Index1 = 0;
+
+      while (gPlatformAllPossiblePciVgaConsole[Index1] != NULL) {
+        if (CompareMem (
+              DevicePath,
+              gPlatformAllPossiblePciVgaConsole[Index1],
+              GetDevicePathSize (gPlatformAllPossiblePciVgaConsole[Index1])
+              ) == 0) {
+
+          //
+          // This device is an AGP device
+          //
+          *OnboardPciVgaDevicePath = DevicePath;
+          PlugInPciVga = FALSE;
+          break;
+        }
+
+        Index1 ++;
+      }
+
+      if (PlugInPciVga) {
+        *PlugInPciVgaDevicePath = DevicePath;
+      }
+    }
+  }
+
+  FreePool (HandleBuffer);
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Find the platform  active vga, and base on the policy to enable the vga as
+  the console out device. The policy is driven by one setup variable "VBIOS".
+
+  None.
+
+  @param EFI_UNSUPPORTED         There is no active vga device
+
+  @retval EFI_STATUS             Return the status of BdsLibGetVariableAndSize ()
+
+**/
+EFI_STATUS
+PlatformBdsForceActiveVga (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  EFI_DEVICE_PATH_PROTOCOL  *PlugInPciVgaDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *OnboardPciVgaDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePathFirst;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePathSecond;
+  EFI_DEVICE_PATH_PROTOCOL  *GopDevicePath;
+  UINTN                VarSize;
+  SYSTEM_CONFIGURATION  mSystemConfiguration;
+
+  Status = EFI_SUCCESS;
+  PlugInPciVgaDevicePath = NULL;
+  OnboardPciVgaDevicePath = NULL;
+
+  //
+  // Check the policy which is the first enabled VGA
+  //
+  GetPlugInPciVgaDevicePath (&PlugInPciVgaDevicePath, &OnboardPciVgaDevicePath);
+
+  if (PlugInPciVgaDevicePath == NULL && OnboardPciVgaDevicePath == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  VarSize = sizeof(SYSTEM_CONFIGURATION);
+  Status = gRT->GetVariable(
+                  L"Setup",
+                  &gEfiNormalSetupGuid,
+                  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",
+              &gEfiNormalSetupGuid,
+              NULL,
+              &VarSize,
+              &mSystemConfiguration
+              );
+    ASSERT_EFI_ERROR (Status);
+  }    
+
+
+  if ((PlugInPciVgaDevicePath == NULL && OnboardPciVgaDevicePath != NULL) ) {
+    DEBUG ((EFI_D_ERROR,"Update onboard PCI VGA ...\n"));
+    DevicePathFirst  = OnboardPciVgaDevicePath;
+    DevicePathSecond = PlugInPciVgaDevicePath;
+    goto UpdateConOut;
+  }
+  if(OnboardPciVgaDevicePath != NULL && mSystemConfiguration.PrimaryVideoAdaptor == 0) {
+    DEBUG ((EFI_D_ERROR,"Update onboard PCI VGA When set primary!!!...\n"));
+    DevicePathFirst  = OnboardPciVgaDevicePath;
+    DevicePathSecond = PlugInPciVgaDevicePath;
+    goto UpdateConOut;
+  }
+
+  DEBUG ((EFI_D_ERROR,"Update plug in PCI VGA ...\n"));
+  DevicePathFirst  = PlugInPciVgaDevicePath;
+  DevicePathSecond = OnboardPciVgaDevicePath;
+
+UpdateConOut:
+  GetGopDevicePath (DevicePathFirst, &GopDevicePath);
+  DevicePathFirst = GopDevicePath;
+
+  Status = BdsLibUpdateConsoleVariable (
+             L"ConOut",
+             DevicePathFirst,
+             DevicePathSecond
+             );
+
+  return Status;
+}
+
+VOID
+UpdateConsoleResolution(
+  VOID
+  )
+{
+  UINT32                 HorizontalResolution;
+  UINT32                 VerticalResolution;
+  SYSTEM_CONFIGURATION   SystemConfiguration;
+  UINTN                  VarSize;
+  EFI_STATUS             Status;
+
+
+  HorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
+  VerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);
+
+  VarSize = sizeof(SYSTEM_CONFIGURATION);
+  Status = gRT->GetVariable(
+                  L"Setup",
+                  &gEfiNormalSetupGuid,
+                  NULL,
+                  &VarSize,
+                  &SystemConfiguration
+                  );
+  if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
+    //The setup variable is corrupted
+    VarSize = sizeof(SYSTEM_CONFIGURATION);
+    Status = gRT->GetVariable(
+              L"SetupRecovery",
+              &gEfiNormalSetupGuid,
+              NULL,
+              &VarSize,
+              &SystemConfiguration
+              );
+    ASSERT_EFI_ERROR (Status);
+  }  
+
+  switch (SystemConfiguration.IgdFlatPanel) {
+
+  case 0:
+    //
+    // Use the detault PCD values.
+    //
+    break;
+
+  case 1:
+    HorizontalResolution = 640;
+    VerticalResolution = 480;
+    break;
+
+  case 2:
+    HorizontalResolution = 800;
+    VerticalResolution = 600;
+    break;
+
+  case 3:
+    HorizontalResolution = 1024;
+    VerticalResolution = 768;
+    break;
+
+  case 4:
+  HorizontalResolution = 1280;
+  VerticalResolution = 1024;
+  break;
+
+  case 5:
+  HorizontalResolution = 1366;
+  VerticalResolution = 768;
+  break;
+
+  case 6:
+  HorizontalResolution = 1680;
+  VerticalResolution = 1050;
+  break;
+
+  case 7:
+  HorizontalResolution = 1920;
+  VerticalResolution = 1200;
+  break;
+
+  case 8:
+  HorizontalResolution = 1280;
+  VerticalResolution = 800;
+  break;
+  }
+
+  PcdSet32 (PcdSetupVideoHorizontalResolution, HorizontalResolution);
+  PcdSet32 (PcdSetupVideoVerticalResolution, VerticalResolution);
+  DEBUG ((EFI_D_ERROR, "HorizontalResolution = %x; VerticalResolution = %x", HorizontalResolution, VerticalResolution));
+
+  return;
+}
+
+/**
+  Connect the predefined platform default console device. Always try to find
+  and enable the vga device if have.
+
+  @param PlatformConsole    Predefined platform default console device array.
+
+  @retval EFI_SUCCESS       Success connect at least one ConIn and ConOut
+                            device, there must have one ConOut device is
+                            active vga device.
+
+  @retval EFI_STATUS        Return the status of
+                            BdsLibConnectAllDefaultConsoles ()
+
+**/
+EFI_STATUS
+PlatformBdsConnectConsole (
+  IN BDS_CONSOLE_CONNECT_ENTRY   *PlatformConsole
+)
+{
+  EFI_STATUS                         Status;
+  UINTN                              Index;
+  EFI_DEVICE_PATH_PROTOCOL           *VarConout;
+  EFI_DEVICE_PATH_PROTOCOL           *VarConin;
+  UINTN                              DevicePathSize;
+
+  UpdateConsoleResolution();
+
+  Index = 0;
+  Status = EFI_SUCCESS;
+  DevicePathSize = 0;
+  VarConout = BdsLibGetVariableAndSize (
+                L"ConOut",
+                &gEfiGlobalVariableGuid,
+                &DevicePathSize
+                );
+  VarConin = BdsLibGetVariableAndSize (
+               L"ConIn",
+               &gEfiGlobalVariableGuid,
+               &DevicePathSize
+               );
+  if (VarConout == NULL || VarConin == NULL) {
+    //
+    // Have chance to connect the platform default console,
+    // the platform default console is the minimum device group
+    // the platform should support
+    //
+    while (PlatformConsole[Index].DevicePath != NULL) {
+
+      //
+      // Update the console variable with the connect type
+      //
+      if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
+        BdsLibUpdateConsoleVariable (L"ConIn", PlatformConsole[Index].DevicePath, NULL);
+      }
+
+      if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
+        BdsLibUpdateConsoleVariable (L"ConOut", PlatformConsole[Index].DevicePath, NULL);
+      }
+
+      if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
+        BdsLibUpdateConsoleVariable (L"ErrOut", PlatformConsole[Index].DevicePath, NULL);
+      }
+
+      Index ++;
+    }
+  }
+
+  //
+  // Make sure we have at least one active VGA, and have the right
+  // active VGA in console variable
+  //
+  Status = PlatformBdsForceActiveVga ();
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  DEBUG ((EFI_D_INFO, "DISPLAY INIT DONE\n"));
+
+  //
+  // Connect the all the default console with current console variable
+  //
+  Status = BdsLibConnectAllDefaultConsoles ();
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Connect with predefined platform connect sequence,
+  the OEM/IBV can customize with their own connect sequence.
+
+  @param None.
+
+  @retval None.
+
+**/
+VOID
+PlatformBdsConnectSequence (
+  VOID
+  )
+{
+  UINTN                     Index;
+
+  Index = 0;
+
+  //
+  // Here we can get the customized platform connect sequence
+  // Notes: we can connect with new variable which record the
+  // last time boots connect device path sequence
+  //
+  while (gPlatformConnectSequence[Index] != NULL) {
+
+    //
+    // Build the platform boot option
+    //
+    BdsLibConnectDevicePath (gPlatformConnectSequence[Index]);
+    Index ++;
+  }
+
+  //
+  // Just use the simple policy to connect all devices
+  // There should be no difference between debug tip and release tip, or it will be extremely hard to debug.
+  //
+  // There is case that IdeController driver will write boot script in driver model Start() function. It will be rejected by boot script save.
+  // It is only found when DEBUG disabled, because we are using BdsLibConnectAll() when DEBUG enabled.
+  //
+  // So we use BdsLibConnectAll() here to make sure IdeController.Start() is invoked before InstallReadyToLock().
+  // We may also consider to connect SataController only later if needed.
+  //
+  BdsLibConnectAll ();
+}
+
+/**
+
+  Load the predefined driver option, OEM/IBV can customize this
+  to load their own drivers
+
+  @param BdsDriverLists  The header of the driver option link list.
+
+  @retval None.
+
+**/
+VOID
+PlatformBdsGetDriverOption (
+  IN OUT LIST_ENTRY                  *BdsDriverLists
+  )
+{
+  UINTN                              Index;
+
+  Index = 0;
+
+  //
+  // Here we can get the customized platform driver option
+  //
+  while (gPlatformDriverOption[Index] != NULL) {
+
+    //
+    // Build the platform boot option
+    //
+    BdsLibRegisterNewOption (BdsDriverLists, gPlatformDriverOption[Index], NULL, L"DriverOrder");
+    Index ++;
+  }
+
+}
+
+/**
+  This function is used for some critical time if the the system
+  have no any boot option, and there is no time out for user to add
+  the new boot option. This can also treat as the platform default
+  boot option.
+
+  @param BdsBootOptionList   The header of the boot option link list.
+
+  @retval None.
+
+**/
+VOID
+PlatformBdsPredictBootOption (
+  IN OUT LIST_ENTRY                  *BdsBootOptionList
+  )
+{
+  UINTN                              Index;
+
+  Index = 0;
+
+  //
+  // Here give chance to get platform boot option data
+  //
+  while (gPlatformBootOption[Index] != NULL) {
+
+    //
+    // Build the platform boot option
+    //
+    BdsLibRegisterNewOption (BdsBootOptionList, gPlatformBootOption[Index], NULL, L"BootOrder");
+    Index ++;
+  }
+}
+
+/**
+  Perform the platform diagnostic, such like test memory. OEM/IBV also
+  can customize this fuction to support specific platform diagnostic.
+
+  @param MemoryTestLevel   The memory test intensive level
+  @param QuietBoot         Indicate if need to enable the quiet boot
+  @param BaseMemoryTest    A pointer to BdsMemoryTest()
+
+  @retval  None.
+
+**/
+VOID
+PlatformBdsDiagnostics (
+  IN EXTENDMEM_COVERAGE_LEVEL    MemoryTestLevel,
+  IN BOOLEAN                     QuietBoot,
+  IN BASEM_MEMORY_TEST           BaseMemoryTest
+  )
+{
+  EFI_STATUS                     Status;
+
+  //
+  // Here we can decide if we need to show
+  // the diagnostics screen
+  // Notes: this quiet boot code should be remove
+  // from the graphic lib
+  //
+  if (QuietBoot) {
+    EnableQuietBoot (PcdGetPtr(PcdLogoFile));
+
+    //
+    // Perform system diagnostic
+    //
+    Status = BaseMemoryTest (MemoryTestLevel);
+    if (EFI_ERROR (Status)) {
+      DisableQuietBoot ();
+    }
+
+    return;
+  }
+
+  //
+  // Perform system diagnostic
+  //
+  Status = BaseMemoryTest (MemoryTestLevel);
+}
+
+
+/**
+  For EFI boot option, BDS separate them as six types:
+  1. Network - The boot option points to the SimpleNetworkProtocol device.
+               Bds will try to automatically create this type boot option when enumerate.
+  2. Shell   - The boot option points to internal flash shell.
+               Bds will try to automatically create this type boot option when enumerate.
+  3. Removable BlockIo      - The boot option only points to the removable media
+                              device, like USB flash disk, DVD, Floppy etc.
+                              These device should contain a *removable* blockIo
+                              protocol in their device handle.
+                              Bds will try to automatically create this type boot option
+                              when enumerate.
+  4. Fixed BlockIo          - The boot option only points to a Fixed blockIo device,
+                              like HardDisk.
+                              These device should contain a *fixed* blockIo
+                              protocol in their device handle.
+                              BDS will skip fixed blockIo devices, and NOT
+                              automatically create boot option for them. But BDS
+                              will help to delete those fixed blockIo boot option,
+                              whose description rule conflict with other auto-created
+                              boot options.
+  5. Non-BlockIo Simplefile - The boot option points to a device whose handle
+                              has SimpleFileSystem Protocol, but has no blockio
+                              protocol. These devices do not offer blockIo
+                              protocol, but BDS still can get the
+                              \EFI\BOOT\boot{machinename}.EFI by SimpleFileSystem
+                              Protocol.
+  6. File    - The boot option points to a file. These boot options are usually
+               created by user manually or OS loader. BDS will not delete or modify
+               these boot options.
+
+  This function will enumerate all possible boot device in the system, and
+  automatically create boot options for Network, Shell, Removable BlockIo,
+  and Non-BlockIo Simplefile devices.
+  It will only execute once of every boot.
+
+  @param  BdsBootOptionList      The header of the link list which indexed all
+                                 current boot options
+
+  @retval EFI_SUCCESS            Finished all the boot device enumerate and create
+                                 the boot option base on that boot device
+
+  @retval EFI_OUT_OF_RESOURCES   Failed to enumerate the boot device and create the boot option list
+**/
+EFI_STATUS
+EFIAPI
+PlatformBdsLibEnumerateAllBootOption (
+  IN OUT LIST_ENTRY          *BdsBootOptionList
+  )
+{
+  EFI_STATUS                    Status;
+  UINT16                        FloppyNumber;
+  UINT16                        HarddriveNumber;
+  UINT16                        CdromNumber;
+  UINT16                        UsbNumber;
+  UINT16                        MiscNumber;
+  UINT16                        ScsiNumber;
+  UINT16                        NonBlockNumber;
+  UINTN                         NumberBlockIoHandles;
+  EFI_HANDLE                    *BlockIoHandles;
+  EFI_BLOCK_IO_PROTOCOL         *BlkIo;
+  BOOLEAN                       Removable[2];
+  UINTN                         RemovableIndex;
+  UINTN                         Index;
+  UINTN                         NumOfLoadFileHandles;
+  EFI_HANDLE                    *LoadFileHandles;
+  UINTN                         FvHandleCount;
+  EFI_HANDLE                    *FvHandleBuffer;
+  EFI_FV_FILETYPE               Type;
+  UINTN                         Size;
+  EFI_FV_FILE_ATTRIBUTES        Attributes;
+  UINT32                        AuthenticationStatus;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+  EFI_DEVICE_PATH_PROTOCOL      *DevicePath;
+  UINTN                         DevicePathType;
+  CHAR16                        Buffer[40];
+  EFI_HANDLE                    *FileSystemHandles;
+  UINTN                         NumberFileSystemHandles;
+  BOOLEAN                       NeedDelete;
+  EFI_IMAGE_DOS_HEADER          DosHeader;
+  CHAR8                         *PlatLang;
+  CHAR8                         *LastLang;
+  EFI_IMAGE_OPTIONAL_HEADER_UNION       HdrData;
+  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;
+  CHAR16                        *MacStr;
+  CHAR16                        *IPverStr;
+  EFI_HANDLE                    *NetworkHandles;
+  UINTN                         BufferSize;
+
+  FloppyNumber    = 0;
+  HarddriveNumber = 0;
+  CdromNumber     = 0;
+  UsbNumber       = 0;
+  MiscNumber      = 0;
+  ScsiNumber      = 0;
+  PlatLang        = NULL;
+  LastLang        = NULL;
+  ZeroMem (Buffer, sizeof (Buffer));
+
+  //
+  // If the boot device enumerate happened, just get the boot
+  // device from the boot order variable
+  //
+  if (mEnumBootDevice) {
+    GetVariable2 (LAST_ENUM_LANGUAGE_VARIABLE_NAME, &gLastEnumLangGuid, (VOID**)&LastLang, NULL);
+    GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&PlatLang, NULL);
+    ASSERT (PlatLang != NULL);
+    if ((LastLang != NULL) && (AsciiStrCmp (LastLang, PlatLang) == 0)) {
+      Status = BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");
+      FreePool (LastLang);
+      FreePool (PlatLang);
+      return Status;
+    } else {
+      Status = gRT->SetVariable (
+        LAST_ENUM_LANGUAGE_VARIABLE_NAME,
+        &gLastEnumLangGuid,
+        EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+        AsciiStrSize (PlatLang),
+        PlatLang
+        );
+      //
+      // Failure to set the variable only impacts the performance next time enumerating the boot options.
+      //
+
+      if (LastLang != NULL) {
+        FreePool (LastLang);
+      }
+      FreePool (PlatLang);
+    }
+  }
+
+  //
+  // Notes: this dirty code is to get the legacy boot option from the
+  // BBS table and create to variable as the EFI boot option, it should
+  // be removed after the CSM can provide legacy boot option directly
+  //
+  REFRESH_LEGACY_BOOT_OPTIONS;
+
+  //
+  // Delete invalid boot option
+  //
+  BdsDeleteAllInvalidEfiBootOption ();
+
+  //
+  // Parse removable media followed by fixed media.
+  // The Removable[] array is used by the for-loop below to create removable media boot options 
+  // at first, and then to create fixed media boot options.
+  //
+  Removable[0]  = FALSE;
+  Removable[1]  = TRUE;
+
+  gBS->LocateHandleBuffer (
+        ByProtocol,
+        &gEfiBlockIoProtocolGuid,
+        NULL,
+        &NumberBlockIoHandles,
+        &BlockIoHandles
+        );
+
+  for (RemovableIndex = 0; RemovableIndex < 2; RemovableIndex++) {
+    for (Index = 0; Index < NumberBlockIoHandles; Index++) {
+      Status = gBS->HandleProtocol (
+                      BlockIoHandles[Index],
+                      &gEfiBlockIoProtocolGuid,
+                      (VOID **) &BlkIo
+                      );
+      //
+      // skip the logical partition
+      //
+      if (EFI_ERROR (Status) || BlkIo->Media->LogicalPartition) {
+        continue;
+      }
+
+      //
+      // firstly fixed block io then the removable block io
+      //
+      if (BlkIo->Media->RemovableMedia == Removable[RemovableIndex]) {
+        continue;
+      }
+      DevicePath  = DevicePathFromHandle (BlockIoHandles[Index]);
+      DevicePathType = BdsGetBootTypeFromDevicePath (DevicePath);
+
+      switch (DevicePathType) {
+      case BDS_EFI_ACPI_FLOPPY_BOOT:
+        if (FloppyNumber != 0) {
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY)), FloppyNumber);
+        } else {
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY)));
+        }
+        BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
+        FloppyNumber++;
+        break;
+
+      //
+      // Assume a removable SATA device should be the DVD/CD device, a fixed SATA device should be the Hard Drive device.
+      //
+      case BDS_EFI_MESSAGE_ATAPI_BOOT:
+      case BDS_EFI_MESSAGE_SATA_BOOT:
+        if (BlkIo->Media->RemovableMedia) {
+          if (CdromNumber != 0) {
+            UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_CD_DVD)), CdromNumber);
+          } else {
+            UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_CD_DVD)));
+          }
+          CdromNumber++;
+        } else {
+          if (HarddriveNumber != 0) {
+            UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_HARDDRIVE)), HarddriveNumber);
+          } else {
+            UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_HARDDRIVE)));
+          }
+          HarddriveNumber++;
+        }
+        DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Buffer: %S\n", Buffer));
+        BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
+        break;
+
+      case BDS_EFI_MESSAGE_USB_DEVICE_BOOT:
+        if (UsbNumber != 0) {
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_USB)), UsbNumber);
+        } else {
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_USB)));
+        }
+        BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
+        UsbNumber++;
+        break;
+
+      case BDS_EFI_MESSAGE_SCSI_BOOT:
+        if (ScsiNumber != 0) {
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI)), ScsiNumber);
+        } else {
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI)));
+        }
+        BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
+        ScsiNumber++;
+        break;
+
+      case BDS_EFI_MESSAGE_MISC_BOOT:
+      default:
+        if (MiscNumber != 0) {
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC)), MiscNumber);
+        } else {
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC)));
+        }
+        BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
+        MiscNumber++;
+        break;
+      }
+    }
+  }
+
+  if (NumberBlockIoHandles != 0) {
+    FreePool (BlockIoHandles);
+  }
+
+  //
+  // If there is simple file protocol which does not consume block Io protocol, create a boot option for it here.
+  //
+  NonBlockNumber = 0;
+  gBS->LocateHandleBuffer (
+        ByProtocol,
+        &gEfiSimpleFileSystemProtocolGuid,
+        NULL,
+        &NumberFileSystemHandles,
+        &FileSystemHandles
+        );
+  for (Index = 0; Index < NumberFileSystemHandles; Index++) {
+    Status = gBS->HandleProtocol (
+                    FileSystemHandles[Index],
+                    &gEfiBlockIoProtocolGuid,
+                    (VOID **) &BlkIo
+                    );
+     if (!EFI_ERROR (Status)) {
+      //
+      //  Skip if the file system handle supports a BlkIo protocol,
+      //
+      continue;
+    }
+
+    //
+    // Do the removable Media thing. \EFI\BOOT\boot{machinename}.EFI
+    //  machinename is ia32, ia64, x64, ...
+    //
+    Hdr.Union  = &HdrData;
+    NeedDelete = TRUE;
+    Status     = BdsLibGetImageHeader (
+                   FileSystemHandles[Index],
+                   EFI_REMOVABLE_MEDIA_FILE_NAME,
+                   &DosHeader,
+                   Hdr
+                   );
+    if (!EFI_ERROR (Status) &&
+        EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr.Pe32->FileHeader.Machine) &&
+        Hdr.Pe32->OptionalHeader.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {
+      NeedDelete = FALSE;
+    }
+
+    if (NeedDelete) {
+      //
+      // No such file or the file is not a EFI application, delete this boot option
+      //
+      BdsLibDeleteOptionFromHandle (FileSystemHandles[Index]);
+    } else {
+      if (NonBlockNumber != 0) {
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NON_BLOCK)), NonBlockNumber);
+      } else {
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NON_BLOCK)));
+      }
+      BdsLibBuildOptionFromHandle (FileSystemHandles[Index], BdsBootOptionList, Buffer);
+      NonBlockNumber++;
+    }
+  }
+
+  if (NumberFileSystemHandles != 0) {
+    FreePool (FileSystemHandles);
+  }
+
+  //
+  // Check if we have on flash shell
+  //
+  gBS->LocateHandleBuffer (
+        ByProtocol,
+        &gEfiFirmwareVolume2ProtocolGuid,
+        NULL,
+        &FvHandleCount,
+        &FvHandleBuffer
+        );
+  for (Index = 0; Index < FvHandleCount; Index++) {
+    gBS->HandleProtocol (
+          FvHandleBuffer[Index],
+          &gEfiFirmwareVolume2ProtocolGuid,
+          (VOID **) &Fv
+          );
+
+    Status = Fv->ReadFile (
+                  Fv,
+                  &gUefiShellFileGuid,
+                  NULL,
+                  &Size,
+                  &Type,
+                  &Attributes,
+                  &AuthenticationStatus
+                  );
+    if (EFI_ERROR (Status)) {
+      //
+      // Skip if no shell file in the FV
+      //
+      continue;
+    }
+    //
+    // Build the shell boot option
+    //
+    BdsLibBuildOptionFromShell (FvHandleBuffer[Index], BdsBootOptionList);
+  }
+
+  if (FvHandleCount != 0) {
+    FreePool (FvHandleBuffer);
+  }
+
+  //
+  // Parse Network Boot Device
+  //
+  NumOfLoadFileHandles = 0;
+  //
+  // Search Load File protocol for PXE boot option.
+  //
+  gBS->LocateHandleBuffer (
+        ByProtocol,
+        &gEfiLoadFileProtocolGuid,
+        NULL,
+        &NumOfLoadFileHandles,
+        &LoadFileHandles
+        );
+
+  for (Index = 0; Index < NumOfLoadFileHandles; Index++) {
+
+//
+//Locate EFI_DEVICE_PATH_PROTOCOL to dynamically get IPv4/IPv6 protocol information.
+//
+
+ Status = gBS->HandleProtocol (
+                  LoadFileHandles[Index],
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID **) &DevicePath
+                  );
+  
+ ASSERT_EFI_ERROR (Status);
+
+  while (!IsDevicePathEnd (DevicePath)) {
+    if ((DevicePath->Type == MESSAGING_DEVICE_PATH) &&
+        (DevicePath->SubType == MSG_IPv4_DP)) {
+
+  //
+  //Get handle infomation
+  //
+  BufferSize = 0;
+  NetworkHandles = NULL;
+  Status = gBS->LocateHandle (
+                  ByProtocol, 
+                  &gEfiSimpleNetworkProtocolGuid,
+                  NULL,
+                  &BufferSize,
+                  NetworkHandles
+                  );
+
+  if (Status == EFI_BUFFER_TOO_SMALL) {
+    NetworkHandles = AllocateZeroPool(BufferSize);
+    if (NetworkHandles == NULL) {
+      return (EFI_OUT_OF_RESOURCES);
+    }
+    Status = gBS->LocateHandle(
+                    ByProtocol,
+                    &gEfiSimpleNetworkProtocolGuid,
+                    NULL,
+                    &BufferSize,
+                    NetworkHandles
+                    );
+ }
+               
+  //
+  //Get the MAC string
+  //
+  Status = NetLibGetMacString (
+             *NetworkHandles,
+             NULL,
+             &MacStr
+             );
+  if (EFI_ERROR (Status)) {	
+    return Status;
+  }
+  IPverStr = L" IPv4";
+  UnicodeSPrint (Buffer, sizeof (Buffer), L"%s%s%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NETWORK)),MacStr,IPverStr);
+  break;
+  }
+    if((DevicePath->Type == MESSAGING_DEVICE_PATH) &&
+        (DevicePath->SubType == MSG_IPv6_DP)) {
+
+  //
+  //Get handle infomation
+  //
+  BufferSize = 0;
+  NetworkHandles = NULL;
+  Status = gBS->LocateHandle (
+                  ByProtocol, 
+                  &gEfiSimpleNetworkProtocolGuid,
+                  NULL,
+                  &BufferSize,
+                  NetworkHandles
+                  );
+
+  if (Status == EFI_BUFFER_TOO_SMALL) {
+    NetworkHandles = AllocateZeroPool(BufferSize);
+    if (NetworkHandles == NULL) {
+       return (EFI_OUT_OF_RESOURCES);
+    }
+    Status = gBS->LocateHandle(
+                    ByProtocol,
+                    &gEfiSimpleNetworkProtocolGuid,
+                    NULL,
+                    &BufferSize,
+                    NetworkHandles
+                    );
+ }
+                    
+  //
+  //Get the MAC string
+  //
+  Status = NetLibGetMacString (
+             *NetworkHandles,
+             NULL,
+             &MacStr
+             );
+  if (EFI_ERROR (Status)) {	
+    return Status;
+  }
+      IPverStr = L" IPv6";
+      UnicodeSPrint (Buffer, sizeof (Buffer), L"%s%s%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NETWORK)),MacStr,IPverStr);
+      break;
+    }
+    DevicePath = NextDevicePathNode (DevicePath);
+  }
+  
+    BdsLibBuildOptionFromHandle (LoadFileHandles[Index], BdsBootOptionList, Buffer);
+  }
+
+  if (NumOfLoadFileHandles != 0) {
+    FreePool (LoadFileHandles);
+  }
+
+  //
+  // Check if we have on flash shell
+  //
+ /* gBS->LocateHandleBuffer (
+        ByProtocol,
+        &gEfiFirmwareVolume2ProtocolGuid,
+        NULL,
+        &FvHandleCount,
+        &FvHandleBuffer
+        );
+  for (Index = 0; Index < FvHandleCount; Index++) {
+    gBS->HandleProtocol (
+          FvHandleBuffer[Index],
+          &gEfiFirmwareVolume2ProtocolGuid,
+          (VOID **) &Fv
+          );
+
+    Status = Fv->ReadFile (
+                  Fv,
+                  &gUefiShellFileGuid,
+                  NULL,
+                  &Size,
+                  &Type,
+                  &Attributes,
+                  &AuthenticationStatus
+                  );
+    if (EFI_ERROR (Status)) {
+      //
+      // Skip if no shell file in the FV
+      //
+      continue;
+    }
+    //
+    // Build the shell boot option
+    //
+    BdsLibBuildOptionFromShell (FvHandleBuffer[Index], BdsBootOptionList);
+  }
+
+  if (FvHandleCount != 0) {
+    FreePool (FvHandleBuffer);
+  } */
+  
+  //
+  // Make sure every boot only have one time
+  // boot device enumerate
+  //
+  Status = BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");
+  mEnumBootDevice = TRUE;
+
+  return Status;
+} 
+
+
+
+/**
+
+  The function will execute with as the platform policy, current policy
+  is driven by boot mode. IBV/OEM can customize this code for their specific
+  policy action.
+
+  @param DriverOptionList - The header of the driver option link list
+  @param  BootOptionList   - The header of the boot option link list
+  @param ProcessCapsules  - A pointer to ProcessCapsules()
+  @param BaseMemoryTest   - A pointer to BaseMemoryTest()
+
+  @retval None.
+
+**/
+VOID
+EFIAPI
+PlatformBdsPolicyBehavior (
+  IN OUT LIST_ENTRY                  *DriverOptionList,
+  IN OUT LIST_ENTRY                  *BootOptionList,
+  IN PROCESS_CAPSULES                BdsProcessCapsules,
+  IN BASEM_MEMORY_TEST               BaseMemoryTest
+  )
+{
+  EFI_STATUS                         Status;
+  UINT16                             Timeout;
+  EFI_BOOT_MODE                      BootMode;
+  BOOLEAN                            DeferredImageExist;
+  UINTN                              Index;
+  SYSTEM_CONFIGURATION               SystemConfiguration;
+  UINTN                              VarSize;
+  PLATFORM_PCI_DEVICE_PATH           *EmmcBootDevPath;
+  EFI_GLOBAL_NVS_AREA_PROTOCOL       *GlobalNvsArea;
+  EFI_HANDLE                         FvProtocolHandle;
+  UINTN                              HandleCount;
+  EFI_HANDLE                         *HandleBuffer;
+  UINTN                              Index1;
+  UINTN                              SataPciRegBase = 0;
+  UINT16                             SataModeSelect = 0;
+  VOID                               *RegistrationExitPmAuth = NULL;
+  EFI_EVENT                          Event;
+  BOOLEAN                            IsFirstBoot;
+  UINT16                             *BootOrder;
+  UINTN                              BootOrderSize;
+  ESRT_MANAGEMENT_PROTOCOL           *EsrtManagement;
+
+  Timeout = PcdGet16 (PcdPlatformBootTimeOut);
+  if (Timeout > 10 ) {
+    //we think the Timeout variable is corrupted
+    Timeout = 10;
+  }
+
+  VarSize = sizeof(SYSTEM_CONFIGURATION);
+  Status = gRT->GetVariable(
+                  NORMAL_SETUP_NAME,
+                  &gEfiNormalSetupGuid,
+                  NULL,
+                  &VarSize,
+                  &SystemConfiguration
+                  );
+
+  if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
+    //The setup variable is corrupted
+    VarSize = sizeof(SYSTEM_CONFIGURATION);
+    Status = gRT->GetVariable(
+              L"SetupRecovery",
+              &gEfiNormalSetupGuid,
+              NULL,
+              &VarSize,
+              &SystemConfiguration
+              );
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  //
+  // Load the driver option as the driver option list
+  //
+  PlatformBdsGetDriverOption (DriverOptionList);
+
+  //
+  // Get current Boot Mode
+  //
+  BootMode = GetBootModeHob();
+
+  //
+  // No deferred images exist by default
+  //
+  DeferredImageExist = FALSE;
+  if ((BootMode != BOOT_WITH_MINIMAL_CONFIGURATION) && (PcdGet32(PcdFlashFvShellSize) > 0)){
+    gDS->ProcessFirmwareVolume (
+           (VOID *)(UINTN)PcdGet32(PcdFlashFvShellBase),
+           PcdGet32(PcdFlashFvShellSize),
+           &FvProtocolHandle
+           );
+  }
+
+  if (SystemConfiguration.FastBoot == 1) {
+    BootOrder = BdsLibGetVariableAndSize (
+                  L"BootOrder",
+                  &gEfiGlobalVariableGuid,
+                  &BootOrderSize
+                  );
+    if ((BootOrder != NULL) && (BootMode != BOOT_ON_FLASH_UPDATE)) {
+      //
+      // BootOrder exist, it means system has boot before. We can do fast boot.
+      //
+      BootMode = BOOT_WITH_MINIMAL_CONFIGURATION;
+    }
+  }
+
+
+  //
+  // Use eMMC to boot OS and turn on AHCI, when SATA HDD is diconnected,
+  // SATA AHCI CTLR device will show yellow bang, implement this solution to solve it.
+  //
+  SataPciRegBase  = MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_SATA, 0, 0);
+  SataModeSelect  = MmioRead16 (SataPciRegBase + R_PCH_SATA_MAP) & B_PCH_SATA_MAP_SMS_MASK;
+  Status          = EFI_SUCCESS;
+  if (SataModeSelect != V_PCH_SATA_MAP_SMS_IDE) {
+    Status = gBS->CreateEvent (
+                    EVT_NOTIFY_SIGNAL,
+                    TPL_CALLBACK,
+                    DisableAhciCtlr,
+                    &SataPciRegBase,
+                    &Event
+                     );
+    if (!EFI_ERROR (Status)) {
+      Status = gBS->RegisterProtocolNotify (
+                      &gExitPmAuthProtocolGuid,
+                      Event,
+                      &RegistrationExitPmAuth
+                      );
+    }
+  }
+
+  Status = gBS->LocateProtocol(&gEsrtManagementProtocolGuid, NULL, (VOID **)&EsrtManagement);
+  if (EFI_ERROR(Status)) {
+    EsrtManagement = NULL;
+  }
+
+  DEBUG ((DEBUG_INFO, "BDS: BootMode=%02x\n", BootMode));
+
+  switch (BootMode) {
+
+  case BOOT_WITH_MINIMAL_CONFIGURATION:
+    PlatformBdsInitHotKeyEvent ();
+    PlatformBdsConnectSimpleConsole (gPlatformSimpleConsole);
+
+
+    //
+    // Check to see if it's needed to dispatch more DXE drivers.
+    //
+    for (Index = 0; Index < sizeof(ConnectDriverTable)/sizeof(EFI_GUID *); Index++) {
+      Status = gBS->LocateHandleBuffer (
+                      ByProtocol,
+                      ConnectDriverTable[Index],
+                      NULL,
+                      &HandleCount,
+                      &HandleBuffer
+                      );
+      if (!EFI_ERROR (Status)) {
+        for (Index1 = 0; Index1 < HandleCount; Index1++) {
+          gBS->ConnectController (
+                 HandleBuffer[Index1],
+                 NULL,
+                 NULL,
+                 TRUE
+                 );
+        }
+      }
+
+      if (HandleBuffer != NULL) {
+        FreePool (HandleBuffer);
+      }
+
+      gDS->Dispatch ();
+    }
+
+    //
+    //  Locate the Global NVS Protocol.
+    //
+    Status = gBS->LocateProtocol (
+                    &gEfiGlobalNvsAreaProtocolGuid,
+                    NULL,
+                    (void **)&GlobalNvsArea
+                    );
+    if (GlobalNvsArea->Area->emmcVersion == 0){
+      EmmcBootDevPath = (PLATFORM_PCI_DEVICE_PATH *)gPlatformSimpleBootOption[0];
+      EmmcBootDevPath->PciDevice.Device = 0x10;
+    }
+
+    //
+    // Connect boot device here to give time to read keyboard.
+    //
+    BdsLibConnectDevicePath (gPlatformSimpleBootOption[0]);
+
+    //
+    // This is a workround for dectecting hotkey from USB keyboard.
+    //
+    gBS->Stall(KEYBOARD_TIMER_INTERVAL);
+
+    if (mHotKeyTimerEvent != NULL) {
+      gBS->SetTimer (
+             mHotKeyTimerEvent,
+             TimerCancel,
+             0
+             );
+      gBS->CloseEvent (mHotKeyTimerEvent);
+      mHotKeyTimerEvent = NULL;
+    }
+    if (mHotKeyPressed) {
+      //
+      // Skip show progress count down
+      //
+      Timeout = 0xFFFF;
+      goto FULL_CONFIGURATION;
+    }
+
+    EnableQuietBoot (PcdGetPtr(PcdLogoFile));
+    if (!SystemConfiguration.QuietBoot) {
+      PlatformBdsDiagnostics (IGNORE, FALSE, BaseMemoryTest);
+    }
+
+
+    #ifdef TPM_ENABLED
+    TcgPhysicalPresenceLibProcessRequest();
+    #endif
+    #ifdef FTPM_ENABLE
+    Tcg2PhysicalPresenceLibProcessRequest(NULL);
+    #endif
+
+    if (EsrtManagement != NULL) {
+      EsrtManagement->LockEsrtRepository();
+    }
+
+    //
+    // Close boot script and install ready to lock
+    //
+    InstallReadyToLock ();
+
+    //
+    // Give one chance to enter the setup if we
+    // select Gummiboot "Reboot Into Firmware Interface" and Fast Boot is enabled.
+    //
+    BootIntoFirmwareInterface();
+    break;
+
+  case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
+
+    //
+    // In no-configuration boot mode, we can connect the
+    // console directly.
+    //
+    BdsLibConnectAllDefaultConsoles ();
+    PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest);
+
+    //
+    // Perform some platform specific connect sequence
+    //
+    PlatformBdsConnectSequence ();
+
+    //
+    // As console is ready, perform user identification again.
+    //
+    if (mCurrentUser == NULL) {
+      PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
+      if (DeferredImageExist) {
+        //
+        // After user authentication, the deferred drivers was loaded again.
+        // Here, need to ensure the deferred images are connected.
+        //
+        BdsLibConnectAllDefaultConsoles ();
+        PlatformBdsConnectSequence ();
+      }
+    }
+
+    if (EsrtManagement != NULL) {
+      EsrtManagement->LockEsrtRepository();
+    }
+
+    //
+    // Close boot script and install ready to lock
+    //
+    InstallReadyToLock ();
+
+    //
+    // Notes: current time out = 0 can not enter the
+    // front page
+    //
+    PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);
+
+    //
+    // Check the boot option with the boot option list
+    //
+    BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");
+    break;
+
+  case BOOT_ON_FLASH_UPDATE:
+
+    //
+    // Boot with the specific configuration
+    //
+    PlatformBdsConnectConsole (gPlatformConsole);
+    PlatformBdsDiagnostics (EXTENSIVE, TRUE, BaseMemoryTest);
+
+    DEBUG((DEBUG_INFO, "ProcessCapsules Before EndOfDxe......\n"));
+    ProcessCapsules ();
+    DEBUG((DEBUG_INFO, "ProcessCapsules Done\n"));
+
+    //
+    // Close boot script and install ready to lock
+    //
+    InstallReadyToLock ();
+
+    BdsLibConnectAll ();
+
+    //
+    // Perform user identification
+    //
+    if (mCurrentUser == NULL) {
+      PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
+      if (DeferredImageExist) {
+        //
+        // After user authentication, the deferred drivers was loaded again.
+        // Here, need to ensure the deferred images are connected.
+        //
+        BdsLibConnectAll ();
+      }
+    }
+
+    if (EsrtManagement != NULL) {
+      EsrtManagement->SyncEsrtFmp();
+    }
+
+    DEBUG((DEBUG_INFO, "ProcessCapsules After ConnectAll......\n"));
+    ProcessCapsules();
+    DEBUG((DEBUG_INFO, "ProcessCapsules Done\n"));
+    break;
+
+  case BOOT_IN_RECOVERY_MODE:
+
+    //
+    // In recovery mode, just connect platform console
+    // and show up the front page
+    //
+    PlatformBdsConnectConsole (gPlatformConsole);
+    PlatformBdsDiagnostics (EXTENSIVE, FALSE, BaseMemoryTest);
+    BdsLibConnectAll ();
+
+    //
+    // Perform user identification
+    //
+    if (mCurrentUser == NULL) {
+      PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
+      if (DeferredImageExist) {
+        //
+        // After user authentication, the deferred drivers was loaded again.
+        // Here, need to ensure the deferred drivers are connected.
+        //
+        BdsLibConnectAll ();
+      }
+    }
+
+    //
+    // Close boot script and install ready to lock
+    //
+    InstallReadyToLock ();
+
+    //
+    // In recovery boot mode, we still enter to the
+    // frong page now
+    //
+    PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);
+    break;
+
+FULL_CONFIGURATION:
+  case BOOT_WITH_FULL_CONFIGURATION:
+  case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:
+  case BOOT_WITH_DEFAULT_SETTINGS:
+  default:
+
+    //
+    // Connect platform console
+    //
+    Status = PlatformBdsConnectConsole (gPlatformConsole);
+    if (EFI_ERROR (Status)) {
+
+      //
+      // Here OEM/IBV can customize with defined action
+      //
+      PlatformBdsNoConsoleAction ();
+    }
+
+    //
+    // Chenyunh[TODO]: This is Workgroud to show the fs for uSDcard,
+    // Need to root cause this issue.
+    //
+    DEBUG ((DEBUG_ERROR, "Start to reconnect all driver.\n"));
+    BdsLibDisconnectAllEfi();
+    BdsLibConnectAll ();
+    DEBUG ((DEBUG_ERROR, "End to reconnect all driver.\n"));
+
+    //
+    // Perform some platform specific connect sequence
+    //
+    PlatformBdsConnectSequence ();
+    EnableQuietBoot (PcdGetPtr(PcdLogoFile));
+    if (!SystemConfiguration.QuietBoot) {
+      PlatformBdsDiagnostics (IGNORE, FALSE, BaseMemoryTest);
+    }
+
+    //
+    // Do a pre-delay so Hard Disk can spin up and see more logo.
+    //
+    gBS->Stall(SystemConfiguration.HddPredelay * 1000000);
+
+    //
+    // Perform user identification
+    //
+    if (mCurrentUser == NULL) {
+      PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
+      if (DeferredImageExist) {
+        //
+        // After user authentication, the deferred drivers was loaded again.
+        // Here, need to ensure the deferred drivers are connected.
+        //
+        Status = PlatformBdsConnectConsole (gPlatformConsole);
+        if (EFI_ERROR (Status)) {
+          PlatformBdsNoConsoleAction ();
+        }
+        PlatformBdsConnectSequence ();
+      }
+    }
+   #ifdef TPM_ENABLED
+   TcgPhysicalPresenceLibProcessRequest();
+   #endif
+   #ifdef FTPM_ENABLE
+   Tcg2PhysicalPresenceLibProcessRequest(NULL);
+   #endif
+
+    if (EsrtManagement != NULL) {
+      EsrtManagement->SyncEsrtFmp();
+    }
+    //
+    // Close boot script and install ready to lock
+    //
+    InstallReadyToLock ();
+
+    //
+    // Here we have enough time to do the enumeration of boot device
+    //
+    PlatformBdsLibEnumerateAllBootOption (BootOptionList);
+
+    //
+    // Give one chance to enter the setup if we
+    // have the time out
+    //
+    PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);
+
+	//
+	// Give one chance to enter the setup if we
+	// select Gummiboot "Reboot Into Firmware Interface"
+	//
+	BootIntoFirmwareInterface();
+
+    //
+    // In default boot mode, always find all boot
+    // option and do enumerate all the default boot option
+    //
+    if (Timeout == 0) {
+      BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");
+      if (IsListEmpty(BootOptionList)) {
+        PlatformBdsPredictBootOption (BootOptionList);
+      }
+
+      return;
+    }
+
+
+    break;
+  }
+
+
+  IsFirstBoot = PcdGetBool(PcdBootState);
+  if (IsFirstBoot) {
+    PcdSetBool(PcdBootState, FALSE);
+  }
+  return;
+
+}
+
+/**
+  Hook point after a boot attempt succeeds. We don't expect a boot option to
+  return, so the UEFI 2.0 specification defines that you will default to an
+  interactive mode and stop processing the BootOrder list in this case. This
+  is alos a platform implementation and can be customized by IBV/OEM.
+
+  @param Option  Pointer to Boot Option that succeeded to boot.
+
+  @retval None.
+
+**/
+VOID
+EFIAPI
+PlatformBdsBootSuccess (
+  IN  BDS_COMMON_OPTION *Option
+  )
+{
+  CHAR16  *TmpStr;
+
+  //
+  // If Boot returned with EFI_SUCCESS and there is not in the boot device
+  // select loop then we need to pop up a UI and wait for user input.
+  //
+  TmpStr =  Option->StatusString;
+  if (TmpStr != NULL) {
+    BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);
+    FreePool(TmpStr);
+  }
+}
+
+/**
+  Hook point after a boot attempt fails.
+
+  @param Option - Pointer to Boot Option that failed to boot.
+  @param Status - Status returned from failed boot.
+  @param ExitData - Exit data returned from failed boot.
+  @param ExitDataSize - Exit data size returned from failed boot.
+
+  @retval None.
+
+**/
+VOID
+EFIAPI
+PlatformBdsBootFail (
+  IN  BDS_COMMON_OPTION  *Option,
+  IN  EFI_STATUS         Status,
+  IN  CHAR16             *ExitData,
+  IN  UINTN              ExitDataSize
+  )
+{
+  CHAR16          *TmpStr;
+  EFI_HANDLE      FvProtocolHandle;
+
+  //
+  // If Boot returned with failed status then we need to pop up a UI and wait
+  // for user input.
+  //
+  TmpStr = Option->StatusString;
+  if (TmpStr != NULL) {
+    BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);
+    FreePool(TmpStr);
+  }
+  if (PcdGet32(PcdFlashFvShellSize) > 0){
+    gDS->ProcessFirmwareVolume (
+           (VOID *)(UINTN)PcdGet32(PcdFlashFvShellBase),
+           PcdGet32(PcdFlashFvShellSize),
+           &FvProtocolHandle
+           );
+  }
+  PlatformBdsConnectSequence ();
+}
+
+/**
+  This function is remained for IBV/OEM to do some platform action,
+  if there no console device can be connected.
+
+  @param  None.
+
+  @retval EFI_SUCCESS       Direct return success now.
+
+**/
+EFI_STATUS
+PlatformBdsNoConsoleAction (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  This function locks the block
+
+  @param Base            The base address flash region to be locked.
+
+**/
+VOID
+BdsLockFv (
+  IN EFI_PHYSICAL_ADDRESS  Base
+  )
+{
+  EFI_FV_BLOCK_MAP_ENTRY      *BlockMap;
+  EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;
+  EFI_PHYSICAL_ADDRESS        BaseAddress;
+  UINT32                      BlockLength;
+  UINTN                       Index;
+
+  BaseAddress = Base - 0x400000 + 2;
+  FvHeader    = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) (Base));
+  BlockMap    = &(FvHeader->BlockMap[0]);
+
+  while ((BlockMap->NumBlocks != 0) && (BlockMap->Length != 0)) {
+    BlockLength = BlockMap->Length;
+    for (Index = 0; Index < BlockMap->NumBlocks; Index++) {
+      MmioOr8 ((UINTN) BaseAddress, 0x03);
+      BaseAddress += BlockLength;
+    }
+    BlockMap++;
+  }
+}
+
+VOID
+EFIAPI
+PlatformBdsLockNonUpdatableFlash (
+  VOID
+  )
+{
+  EFI_PHYSICAL_ADDRESS  Base;
+
+  Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvMainBase);
+  if (Base > 0) {
+    BdsLockFv (Base);
+  }
+
+  Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvRecoveryBase);
+  if (Base > 0) {
+    BdsLockFv (Base);
+  }
+}
+
+/**
+  Lock the ConsoleIn device in system table. All key
+  presses will be ignored until the Password is typed in. The only way to
+  disable the password is to type it in to a ConIn device.
+
+  @param  Password        Password used to lock ConIn device.
+
+  @retval EFI_SUCCESS     lock the Console In Spliter virtual handle successfully.
+  @retval EFI_UNSUPPORTED Password not found
+
+**/
+EFI_STATUS
+EFIAPI
+LockKeyboards (
+  IN  CHAR16    *Password
+  )
+{
+    return EFI_UNSUPPORTED;
+}
+
+/**
+  Connect the predefined platform default authentication devices.
+
+  This function connects the predefined device path for authentication device,
+  and if the predefined device path has child device path, the child handle will
+  be connected too. But the child handle of the child will not be connected.
+
+**/
+VOID
+EFIAPI
+PlatformBdsConnectAuthDevice (
+  VOID
+  )
+{
+  EFI_STATUS                   Status;
+  UINTN                        Index;
+  UINTN                        HandleIndex;
+  UINTN                        HandleCount;
+  EFI_HANDLE                   *HandleBuffer;
+  EFI_DEVICE_PATH_PROTOCOL     *ChildDevicePath;
+  EFI_USER_MANAGER_PROTOCOL    *Manager;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiUserManagerProtocolGuid,
+                  NULL,
+                  (VOID **) &Manager
+                  );
+  if (EFI_ERROR (Status)) {
+    //
+    // As user manager protocol is not installed, the authentication devices
+    // should not be connected.
+    //
+    return ;
+  }
+
+  Index = 0;
+  while (gUserAuthenticationDevice[Index] != NULL) {
+    //
+    // Connect the platform customized device paths
+    //
+    BdsLibConnectDevicePath (gUserAuthenticationDevice[Index]);
+    Index++;
+  }
+
+  //
+  // Find and connect the child device paths of the platform customized device paths
+  //
+  HandleBuffer = NULL;
+  for (Index = 0; gUserAuthenticationDevice[Index] != NULL; Index++) {
+    HandleCount = 0;
+    Status = gBS->LocateHandleBuffer (
+                    AllHandles,
+                    NULL,
+                    NULL,
+                    &HandleCount,
+                    &HandleBuffer
+                    );
+    ASSERT (!EFI_ERROR (Status));
+
+    //
+    // Find and connect the child device paths of gUserIdentificationDevice[Index]
+    //
+    for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+      ChildDevicePath = NULL;
+      Status = gBS->HandleProtocol (
+                      HandleBuffer[HandleIndex],
+                      &gEfiDevicePathProtocolGuid,
+                      (VOID **) &ChildDevicePath
+                      );
+      if (EFI_ERROR (Status) || ChildDevicePath == NULL) {
+        continue;
+      }
+
+      if (CompareMem (
+            ChildDevicePath,
+            gUserAuthenticationDevice[Index],
+            (GetDevicePathSize (gUserAuthenticationDevice[Index]) - sizeof (EFI_DEVICE_PATH_PROTOCOL))
+            ) != 0) {
+        continue;
+      }
+      gBS->ConnectController (
+             HandleBuffer[HandleIndex],
+             NULL,
+             NULL,
+             TRUE
+             );
+    }
+  }
+
+  if (HandleBuffer != NULL) {
+    FreePool (HandleBuffer);
+  }
+}
+
+/**
+  This function is to identify a user, and return whether deferred images exist.
+
+  @param[out]  User               Point to user profile handle.
+  @param[out]  DeferredImageExist On return, points to TRUE if the deferred image
+                                  exist or FALSE if it did not exist.
+
+**/
+VOID
+EFIAPI
+PlatformBdsUserIdentify (
+  OUT EFI_USER_PROFILE_HANDLE        *User,
+  OUT BOOLEAN                        *DeferredImageExist
+  )
+{
+  EFI_STATUS                         Status;
+  EFI_DEFERRED_IMAGE_LOAD_PROTOCOL   *DeferredImage;
+  UINTN                              HandleCount;
+  EFI_HANDLE                         *HandleBuf;
+  UINTN                              Index;
+  UINTN                              DriverIndex;
+  EFI_DEVICE_PATH_PROTOCOL           *ImageDevicePath;
+  VOID                               *DriverImage;
+  UINTN                              ImageSize;
+  BOOLEAN                            BootOption;
+
+  //
+  // Perform user identification
+  //
+  do {
+    Status = BdsLibUserIdentify (User);
+  } while (EFI_ERROR (Status));
+
+  //
+  // After user authentication now, try to find whether deferred image exists
+  //
+  HandleCount = 0;
+  HandleBuf   = NULL;
+  *DeferredImageExist = FALSE;
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiDeferredImageLoadProtocolGuid,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuf
+                  );
+  if (EFI_ERROR (Status)) {
+    return ;
+  }
+
+  for (Index = 0; Index < HandleCount; Index++) {
+    Status = gBS->HandleProtocol (
+                    HandleBuf[Index],
+                    &gEfiDeferredImageLoadProtocolGuid,
+                    (VOID **) &DeferredImage
+                    );
+    if (!EFI_ERROR (Status)) {
+      //
+      // Find whether deferred image exists in this instance.
+      //
+      DriverIndex = 0;
+      Status = DeferredImage->GetImageInfo(
+                                DeferredImage,
+                                DriverIndex,
+                                &ImageDevicePath,
+                                (VOID **) &DriverImage,
+                                &ImageSize,
+                                &BootOption
+                                );
+      if (!EFI_ERROR (Status)) {
+        //
+        // The deferred image is found.
+        //
+        FreePool (HandleBuf);
+        *DeferredImageExist = TRUE;
+        return ;
+      }
+    }
+  }
+
+  FreePool (HandleBuf);
+}
+
+UINTN gHotKey = 0;
+
+
+EFI_STATUS
+ShowProgressHotKey (
+  IN UINT16                       TimeoutDefault
+  )
+{
+  CHAR16                        *TmpStr;
+  UINT16                        TimeoutRemain;
+  EFI_STATUS                    Status;
+  EFI_INPUT_KEY                 Key;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;
+  UINT32                        GpioValue;
+  CHAR16                        *TmpStr1;
+  CHAR16                        *TmpStr2;
+  CHAR16                        *TmpStr3;
+  UINTN                         TmpStrSize;
+  VOID                          *Buffer;
+  UINTN                         Size;
+
+  if (TimeoutDefault == 0) {
+    return EFI_TIMEOUT;
+  }
+
+  gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
+    
+  if (DebugAssertEnabled())
+  {
+    DEBUG ((EFI_D_INFO, "\n\nStart showing progress bar... Press any key to stop it, or press <F2> or <DEL> to enter setup page! ...Zzz....\n"));
+  }
+  else
+  {  
+    #ifdef __GNUC__
+    SerialPortWrite((UINT8 *)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)[GCC]", 76);
+    #else
+    SerialPortWrite((UINT8 *)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)", 71);
+    #endif
+  } 
+  SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
+  SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
+  SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
+
+  TmpStr2 = NULL;
+  TmpStr3 = NULL;
+
+  //
+  // Check if the platform is using test key.
+  //
+  Status = GetSectionFromAnyFv(
+             PcdGetPtr(PcdEdkiiRsa2048Sha256TestPublicKeyFileGuid),
+             EFI_SECTION_RAW,
+             0,
+             &Buffer,
+             &Size
+             );
+  if (!EFI_ERROR(Status)) {
+    if ((Size == PcdGetSize(PcdRsa2048Sha256PublicKeyBuffer)) &&
+        (CompareMem(Buffer, PcdGetPtr(PcdRsa2048Sha256PublicKeyBuffer), Size) == 0)) {
+      TmpStr2 = L"WARNING: Recovery Test Key is used.\r\n";
+      if (DebugAssertEnabled()) {
+        DEBUG ((DEBUG_INFO, "\n\nWARNING: Recovery Test Key is used.\n"));
+      } else {
+        SerialPortWrite((UINT8 *)"\n\nWARNING: Recovery Test Key is used.", sizeof("\n\nWARNING: Recovery Test Key is used."));
+      }
+      PcdSetBoolS(PcdTestKeyUsed, TRUE);
+    }
+    FreePool(Buffer);
+  }
+  Status = GetSectionFromAnyFv(
+             PcdGetPtr(PcdEdkiiPkcs7TestPublicKeyFileGuid),
+             EFI_SECTION_RAW,
+             0,
+             &Buffer,
+             &Size
+             );
+  if (!EFI_ERROR(Status)) {
+    if ((Size == PcdGetSize(PcdPkcs7CertBuffer)) &&
+        (CompareMem(Buffer, PcdGetPtr(PcdPkcs7CertBuffer), Size) == 0)) {
+      TmpStr3 = L"WARNING: Capsule Test Key is used.\r\n";
+      if (DebugAssertEnabled()) {
+        DEBUG ((DEBUG_INFO, "\n\nWARNING: Capsule Test Key is used.\r\n"));
+      } else {
+        SerialPortWrite((UINT8 *)"\n\nWARNING: Capsule Test Key is used.", sizeof("\n\nWARNING: Capsule Test Key is used."));
+      }
+      PcdSetBoolS(PcdTestKeyUsed, TRUE);
+    }
+    FreePool(Buffer);
+  }
+
+  //
+  // Clear the progress status bar first
+  //
+  TmpStr1 = L"Start boot option, Press <F2> or <DEL> to enter setup page.\r\n";
+  TmpStrSize = StrSize(TmpStr1);
+  if (TmpStr2 != NULL) {
+    TmpStrSize += StrSize(TmpStr2);
+  }
+  if (TmpStr3 != NULL) {
+    TmpStrSize += StrSize(TmpStr3);
+  }
+  TmpStr = AllocatePool (TmpStrSize);
+  if (TmpStr == NULL) {
+    TmpStr = TmpStr1;
+  } else {
+    StrCpyS(TmpStr, TmpStrSize/sizeof(CHAR16), TmpStr1);
+    if (TmpStr2 != NULL) {
+      StrCatS(TmpStr, TmpStrSize/sizeof(CHAR16), TmpStr2);
+    }
+    if (TmpStr3 != NULL) {
+      StrCatS(TmpStr, TmpStrSize/sizeof(CHAR16), TmpStr3);
+    }
+  }
+  PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);
+
+  TimeoutRemain = TimeoutDefault;
+  while (TimeoutRemain != 0) {
+    if (DebugAssertEnabled())
+    {
+    DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain));
+    }
+    else
+    {	
+    SerialPortWrite ((UINT8 *)".", 1);
+    }
+    Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);
+    if (Status != EFI_TIMEOUT) {
+      break;
+    }
+    TimeoutRemain--;
+
+    //
+    // Show progress
+    //
+    if (TmpStr != NULL) {
+      PlatformBdsShowProgress (
+        Foreground,
+        Background,
+        TmpStr,
+        Color,
+        ((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault),
+        0
+        );
+    }
+  }
+
+  //
+  // Timeout expired
+  //
+  if (TimeoutRemain == 0) {
+    if (DebugAssertEnabled())
+	{
+	}
+    else
+    {	
+    SerialPortWrite ((UINT8 *)"\r\n", 2);
+    }
+    return EFI_TIMEOUT;
+  }
+
+  //
+  // User pressed some key
+  //
+  Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Check Volume Up Key to enter Setup
+  //
+  GpioValue = MmioRead32 (IO_BASE_ADDRESS + 0x0668);  // The value of GPIOC_5
+  if (((GpioValue & BIT0) == 0) && (Key.ScanCode == SCAN_UP)) {
+    gHotKey = 0;
+    return EFI_SUCCESS;
+  }
+
+  if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
+    //
+    // User pressed enter, equivalent to select "continue"
+    //
+    return EFI_TIMEOUT;
+  }
+
+  //
+  //F2 --  Front Page
+  //F5 --  Device Manager
+  //F7 --  Boot Manager
+  // do not use F8. generally people assume it is windows safe mode key.
+  //F9 --  Boot order
+  //
+  DEBUG ((EFI_D_INFO, "[Key Pressed]: ScanCode 0x%x\n", Key.ScanCode));
+  switch(Key.ScanCode) {
+      case SCAN_F2:
+          gHotKey = 0;
+          break;
+
+      case SCAN_DELETE:
+          gHotKey = 0;
+          break;
+
+      case SCAN_F5:
+          gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
+          break;
+
+      case SCAN_F7:
+          gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER;
+          break;
+
+      case SCAN_F9:
+          gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN;
+          break;
+
+      default:
+          //set gHotKey to continue so that flow will not go into CallFrontPage
+          gHotKey = FRONT_PAGE_KEY_CONTINUE;
+          return EFI_TIMEOUT;
+          break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+
+/**
+  This function is the main entry of the platform setup entry.
+  The function will present the main menu of the system setup,
+  this is the platform reference part and can be customize.
+
+
+  @param TimeoutDefault     The fault time out value before the system
+                            continue to boot.
+  @param ConnectAllHappened The indicater to check if the connect all have
+                            already happened.
+
+**/
+VOID
+PlatformBdsEnterFrontPageWithHotKey (
+  IN UINT16                       TimeoutDefault,
+  IN BOOLEAN                      ConnectAllHappened
+  )
+{
+  EFI_STATUS                    Status;
+
+  EFI_STATUS                         LogoStatus;
+  EFI_BOOT_LOGO_PROTOCOL             *BootLogo;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL       *GraphicsOutput;
+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL    *SimpleTextOut;
+  UINTN                              BootTextColumn;
+  UINTN                              BootTextRow;
+
+  GraphicsOutput = NULL;
+  SimpleTextOut = NULL;
+
+  PERF_START (NULL, "BdsTimeOut", "BDS", 0);
+
+  //
+  // Indicate if we need connect all in the platform setup
+  //
+  if (ConnectAllHappened) {
+    gConnectAllHappened = TRUE;
+  }
+
+  if (!mModeInitialized) {
+    //
+    // After the console is ready, get current video resolution
+    // and text mode before launching setup at first time.
+    //
+    Status = gBS->HandleProtocol (
+                    gST->ConsoleOutHandle,
+                    &gEfiGraphicsOutputProtocolGuid,
+                    (VOID**)&GraphicsOutput
+                    );
+    if (EFI_ERROR (Status)) {
+      GraphicsOutput = NULL;
+    }
+
+    Status = gBS->HandleProtocol (
+                    gST->ConsoleOutHandle,
+                    &gEfiSimpleTextOutProtocolGuid,
+                    (VOID**)&SimpleTextOut
+                    );
+    if (EFI_ERROR (Status)) {
+      SimpleTextOut = NULL;
+    }
+
+    if (GraphicsOutput != NULL) {
+      //
+      // Get current video resolution and text mode.
+      //
+      mBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;
+      mBootVerticalResolution   = GraphicsOutput->Mode->Info->VerticalResolution;
+    }
+
+    if (SimpleTextOut != NULL) {
+      Status = SimpleTextOut->QueryMode (
+                                SimpleTextOut,
+                                SimpleTextOut->Mode->Mode,
+                                &BootTextColumn,
+                                &BootTextRow
+                                );
+      mBootTextModeColumn = (UINT32)BootTextColumn;
+      mBootTextModeRow    = (UINT32)BootTextRow;
+    }
+
+    //
+    // Get user defined text mode for setup.
+    //
+    mSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
+    mSetupVerticalResolution   = PcdGet32 (PcdSetupVideoVerticalResolution);
+    mSetupTextModeColumn       = PcdGet32 (PcdSetupConOutColumn);
+    mSetupTextModeRow          = PcdGet32 (PcdSetupConOutRow);
+
+    mModeInitialized           = TRUE;
+  }
+
+  if (TimeoutDefault != 0xffff) {
+    Status = ShowProgressHotKey (TimeoutDefault);
+
+    //
+    // Ensure screen is clear when switch Console from Graphics mode to Text mode
+    //
+    gST->ConOut->EnableCursor (gST->ConOut, TRUE);
+    gST->ConOut->ClearScreen (gST->ConOut);
+
+    //
+    // Boot Logo is corrupted, report it using Boot Logo protocol.
+    //
+    LogoStatus = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo);
+    if (!EFI_ERROR (LogoStatus) && (BootLogo != NULL)) {
+      BootLogo->SetBootLogo (BootLogo, NULL, 0, 0, 0, 0);
+    }
+
+    if (EFI_ERROR (Status)) {
+      //
+      // Timeout or user press enter to continue
+      //
+      goto Exit;
+    }
+  }
+
+  //
+  // Install BM HiiPackages. 
+  // Keep BootMaint HiiPackage, so that it can be covered by global setting. 
+  //
+	InitBMPackage ();
+  do {
+
+    BdsSetConsoleMode (TRUE);
+
+    InitializeFrontPage (FALSE);
+
+    //
+    // Update Front Page strings
+    //
+    UpdateFrontPageStrings ();
+
+    Status = EFI_SUCCESS;
+    gCallbackKey = 0;
+    if (gHotKey == 0) {
+      Status = CallFrontPage ();
+    } else {
+      gCallbackKey = gHotKey;
+      gHotKey = 0;
+    }
+
+    //
+    // If gCallbackKey is greater than 1 and less or equal to 5,
+    // it will launch configuration utilities.
+    // 2 = set language
+    // 3 = boot manager
+    // 4 = device manager
+    // 5 = boot maintenance manager
+    //
+    if (gCallbackKey != 0) {
+      REPORT_STATUS_CODE (
+        EFI_PROGRESS_CODE,
+        (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)
+        );
+    }
+
+    //
+    // Based on the key that was set, we can determine what to do
+    //
+    switch (gCallbackKey) {
+    //
+    // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
+    // describe to their customers in documentation how to find their setup information (namely
+    // under the device manager and specific buckets)
+    //
+    // These entries consist of the Continue, Select language, Boot Manager, and Device Manager
+    //
+    case FRONT_PAGE_KEY_CONTINUE:
+
+      //
+      // User hit continue
+      //
+      break;
+
+    case FRONT_PAGE_KEY_LANGUAGE:
+
+      //
+      // User made a language setting change - display front page again
+      //
+      break;
+
+    case FRONT_PAGE_KEY_BOOT_MANAGER:
+      //
+	  // Remove the installed BootMaint HiiPackages when exit.
+      //
+      FreeBMPackage ();
+
+      //
+      // User chose to run the Boot Manager
+      //
+      CallBootManager ();
+	  
+	  //
+      // Reinstall BootMaint HiiPackages after exiting from Boot Manager.
+      //
+      InitBMPackage ();
+      break;
+
+    case FRONT_PAGE_KEY_DEVICE_MANAGER:
+
+      //
+      // Display the Device Manager
+      //
+      do {
+        CallDeviceManager ();
+      } while (gCallbackKey == FRONT_PAGE_KEY_DEVICE_MANAGER);
+      break;
+
+    case FRONT_PAGE_KEY_BOOT_MAINTAIN:
+
+      //
+      // Display the Boot Maintenance Manager
+      //
+      BdsStartBootMaint ();
+      break;
+    }
+
+  } while (((UINTN)gCallbackKey) != FRONT_PAGE_KEY_CONTINUE);
+
+  //
+  //Will leave browser, check any reset required change is applied? if yes, reset system
+  //
+  SetupResetReminder ();
+  //
+  // Remove the installed BootMaint HiiPackages when exit.
+  //
+  FreeBMPackage ();
+
+Exit:
+  //
+  // Automatically load current entry
+  // Note: The following lines of code only execute when Auto boot
+  // takes affect
+  //
+  PERF_END (NULL, "BdsTimeOut", "BDS", 0);
+}
+
+
+VOID 
+BootIntoFirmwareInterface(
+VOID
+)
+{
+  EFI_STATUS        Status;
+  UINTN             DataSize;
+  UINT16            Timeout;    
+  UINT64            OsIndication;
+
+  
+  OsIndication = 0;
+  DataSize = sizeof(UINT64);
+  Status = gRT->GetVariable (
+                  L"OsIndications",
+                  &gEfiGlobalVariableGuid,
+                  NULL,
+                  &DataSize,
+                  &OsIndication
+                  );
+				  
+  DEBUG ((EFI_D_INFO, "OSIndication Variable Value %d\n", OsIndication));
+  //
+  //Goto FrontPage directly when bit EFI_OS_INDICATIONS_BOOT_TO_FW_UI in OSIndication Variable is setted.
+  //  
+  if (!EFI_ERROR(Status) && (OsIndication != 0)) {				  
+   Timeout = 0xffff;
+   PlatformBdsEnterFrontPage (Timeout, FALSE);
+   }
+}
+
+
+EFI_STATUS
+PlatformBdsConnectSimpleConsole (
+  IN BDS_CONSOLE_CONNECT_ENTRY   *PlatformConsole
+)
+{
+  EFI_STATUS                         Status;
+  UINTN                              Index;
+  EFI_DEVICE_PATH_PROTOCOL           *VarConout;
+  EFI_DEVICE_PATH_PROTOCOL           *VarConin;
+  UINTN                              DevicePathSize;
+
+
+  Index = 0;
+  Status = EFI_SUCCESS;
+  DevicePathSize = 0;
+  VarConout = BdsLibGetVariableAndSize (
+                L"ConOut",
+                &gEfiGlobalVariableGuid,
+                &DevicePathSize
+                );
+  VarConin = BdsLibGetVariableAndSize (
+               L"ConIn",
+               &gEfiGlobalVariableGuid,
+               &DevicePathSize
+               );
+  if (VarConout == NULL || VarConin == NULL) {
+    //
+    // Have chance to connect the platform default console,
+    // the platform default console is the minimum device group
+    // the platform should support
+    //
+    while (PlatformConsole[Index].DevicePath != NULL) {
+
+      //
+      // Update the console variable with the connect type
+      //
+      if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
+        BdsLibUpdateConsoleVariable (L"ConIn", PlatformConsole[Index].DevicePath, NULL);
+      }
+
+      if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
+        BdsLibUpdateConsoleVariable (L"ConOut", PlatformConsole[Index].DevicePath, NULL);
+      }
+
+      if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
+        BdsLibUpdateConsoleVariable (L"ErrOut", PlatformConsole[Index].DevicePath, NULL);
+      }
+
+      Index ++;
+    }
+  }
+
+  //
+  // Connect ConIn first to give keyboard time to parse hot key event.
+  //
+  Status = BdsLibConnectConsoleVariable (L"ConIn");
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Make sure we have at least one active VGA, and have the right
+  // active VGA in console variable
+  //
+  Status = PlatformBdsForceActiveVga ();
+
+  //
+  // It seems impossible not to have any ConOut device on platform,
+  // so we check the status here.
+  //
+  Status = BdsLibConnectConsoleVariable (L"ConOut");
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Timer handler to convert the key from USB.
+
+  @param  Event                    Indicates the event that invoke this function.
+  @param  Context                  Indicates the calling context.
+**/
+VOID
+EFIAPI
+HotKeyTimerHandler (
+  IN  EFI_EVENT                 Event,
+  IN  VOID                      *Context
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_INPUT_KEY                 Key;
+
+  Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  switch(Key.ScanCode) {
+  case SCAN_F2:
+    gHotKey = 0;
+    mHotKeyPressed = TRUE;
+    break;
+
+  case SCAN_F5:
+    gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
+    mHotKeyPressed = TRUE;
+    break;
+
+  case SCAN_F7:
+    gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER;
+    mHotKeyPressed = TRUE;
+    break;
+
+  case SCAN_F9:
+    gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN;
+    mHotKeyPressed = TRUE;
+    break;
+  }
+
+  if (mHotKeyPressed) {
+    gBS->SetTimer (
+           mHotKeyTimerEvent,
+           TimerCancel,
+           0
+           );
+    gBS->CloseEvent (mHotKeyTimerEvent);
+    mHotKeyTimerEvent = NULL;
+  }
+
+  return;
+}
+
+
+/**
+  Callback function for SimpleTextInEx protocol install events
+
+  @param Event           the event that is signaled.
+  @param Context         not used here.
+
+**/
+VOID
+EFIAPI
+HitHotkeyEvent (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  )
+{
+  EFI_STATUS                         Status;
+
+  Status = gBS->CloseEvent(mHitHotkeyEvent);
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+  Status = gBS->CreateEvent (
+                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  HotKeyTimerHandler,
+                  NULL,
+                  &mHotKeyTimerEvent
+                  );
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+  Status = gBS->SetTimer (
+                  mHotKeyTimerEvent,
+                  TimerPeriodic,
+                  KEYBOARD_TIMER_INTERVAL
+                  );
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  return;
+}
+
+
+VOID
+EFIAPI
+PlatformBdsInitHotKeyEvent (
+  VOID
+  )
+{
+  EFI_STATUS      Status;
+
+  //
+  // Register Protocol notify for Hotkey service
+  //
+  Status = gBS->CreateEvent (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  HitHotkeyEvent,
+                  NULL,
+                  &mHitHotkeyEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Register for protocol notifications on this event
+  //
+  Status = gBS->RegisterProtocolNotify (
+                  &gEfiSimpleTextInputExProtocolGuid,
+                  mHitHotkeyEvent,
+                  &mHitHotkeyRegistration
+                  );
+  ASSERT_EFI_ERROR (Status);
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.h b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.h
new file mode 100644
index 0000000000..b5bb519747
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.h
@@ -0,0 +1,516 @@
+/*++
+
+  Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  BdsPlatform.h
+
+Abstract:
+
+  Head file for BDS Platform specific code
+
+--*/
+
+#ifndef _BDS_PLATFORM_H
+#define _BDS_PLATFORM_H
+
+#include <FrameworkDxe.h>
+
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/SimpleNetwork.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/LoadFile.h>
+#include <Protocol/LegacyBios.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/SmmAccess2.h>
+#include <Protocol/DxeSmmReadyToLock.h>
+#include <Protocol/UserManager.h>
+#include <Protocol/DeferredImageLoad.h>
+#include <Protocol/AcpiS3Save.h>
+#include <Protocol/ExitPmAuth.h>
+#include <Protocol/MmioDevice.h>
+#include <Protocol/I2cBusMcg.h>
+#include <Protocol/I2cHostMcg.h>
+#include <Guid/CapsuleVendor.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/GlobalVariable.h>
+#include <Guid/DebugAgentGuid.h>
+
+
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/GenericBdsLib.h>
+#include <Library/PlatformBdsLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiLib.h>
+#include <Library/HobLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/ReportStatusCodeLib.h>
+
+#include <IndustryStandard/Pci.h>
+
+extern EFI_DEVICE_PATH_PROTOCOL  *gPlatformRootBridges [];
+extern BDS_CONSOLE_CONNECT_ENTRY gPlatformConsole [];
+extern EFI_DEVICE_PATH_PROTOCOL  *gPlatformAllPossiblePciVgaConsole [];
+extern EFI_DEVICE_PATH_PROTOCOL  *gPlatformConnectSequence [];
+extern EFI_DEVICE_PATH_PROTOCOL  *gPlatformDriverOption [];
+extern EFI_DEVICE_PATH_PROTOCOL  *gPlatformBootOption [];
+extern EFI_DEVICE_PATH_PROTOCOL  *gUserAuthenticationDevice[];
+extern BDS_CONSOLE_CONNECT_ENTRY gPlatformSimpleConsole [];
+extern EFI_DEVICE_PATH_PROTOCOL  *gPlatformSimpleBootOption [];
+
+extern BOOLEAN mEnumBootDevice;
+
+
+//
+// the short form device path for Usb keyboard
+//
+#define CLASS_HID           3
+#define SUBCLASS_BOOT       1
+#define PROTOCOL_KEYBOARD   1
+
+#define PCI_DEVICE_PATH_NODE(Func, Dev) \
+  { \
+    HARDWARE_DEVICE_PATH, \
+    HW_PCI_DP, \
+    { \
+      (UINT8) (sizeof (PCI_DEVICE_PATH)), \
+      (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) \
+    }, \
+    (Func), \
+    (Dev) \
+  }
+
+#define PNPID_DEVICE_PATH_NODE(PnpId) \
+  { \
+    { \
+      ACPI_DEVICE_PATH, \
+      ACPI_DP, \
+      { \
+        (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \
+        (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \
+      } \
+    }, \
+    EISA_PNP_ID((PnpId)), \
+    0 \
+  }
+
+#define gUart(BaudRate, DataBits, Parity, StopBits) \
+  { \
+    { \
+      MESSAGING_DEVICE_PATH, \
+      MSG_UART_DP, \
+      { \
+        (UINT8) (sizeof (UART_DEVICE_PATH)), \
+        (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8) \
+      } \
+    }, \
+    0, \
+    (BaudRate), \
+    (DataBits), \
+    (Parity), \
+    (StopBits) \
+  }
+
+#define gPcAnsiTerminal \
+  { \
+    { \
+      MESSAGING_DEVICE_PATH, \
+      MSG_VENDOR_DP, \
+      { \
+        (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \
+        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \
+      } \
+    }, \
+    DEVICE_PATH_MESSAGING_PC_ANSI \
+  }
+
+#define gUsbKeyboardMouse \
+  { \
+    { \
+      MESSAGING_DEVICE_PATH, \
+      MSG_USB_CLASS_DP, \
+      (UINT8) (sizeof (USB_CLASS_DEVICE_PATH)), \
+      (UINT8) ((sizeof (USB_CLASS_DEVICE_PATH)) >> 8) \
+    }, \
+    0xffff, \
+    0xffff, \
+    CLASS_HID, \
+    SUBCLASS_BOOT, \
+    PROTOCOL_KEYBOARD \
+  }
+
+#define gEndEntire \
+  { \
+    END_DEVICE_PATH_TYPE, \
+    END_ENTIRE_DEVICE_PATH_SUBTYPE, \
+    { \
+      END_DEVICE_PATH_LENGTH, \
+      0 \
+    } \
+  }
+
+#define gPciRootBridge \
+  PNPID_DEVICE_PATH_NODE(0x0A03)
+
+#define gPnpPs2Keyboard \
+  PNPID_DEVICE_PATH_NODE(0x0303)
+
+#define gPnp16550ComPort \
+  PNPID_DEVICE_PATH_NODE(0x0501)
+
+#define gPciePort0Bridge \
+  PCI_DEVICE_PATH_NODE(0, 0x1C)
+
+#define gPciePort1Bridge \
+  PCI_DEVICE_PATH_NODE(1, 0x1C)
+
+#define gPciePort2Bridge \
+  PCI_DEVICE_PATH_NODE(2, 0x1C)
+
+#define gPciePort3Bridge \
+  PCI_DEVICE_PATH_NODE(3, 0x1C)
+
+#define gPciIsaBridge \
+  PCI_DEVICE_PATH_NODE(0, 0x1f)
+
+//
+// Platform Root Bridge
+//
+typedef struct {
+  ACPI_HID_DEVICE_PATH      PciRootBridge;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} PLATFORM_ROOT_BRIDGE_DEVICE_PATH;
+
+//
+// Below is the platform console device path
+//
+typedef struct {
+  ACPI_HID_DEVICE_PATH      PciRootBridge;
+  PCI_DEVICE_PATH           IsaBridge;
+  ACPI_HID_DEVICE_PATH      Keyboard;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} PLATFORM_ISA_KEYBOARD_DEVICE_PATH;
+
+typedef struct {
+  VENDOR_DEVICE_PATH             VendorDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL       End;
+} HII_VENDOR_DEVICE_PATH;
+
+typedef struct {
+  USB_CLASS_DEVICE_PATH           UsbClass;
+  EFI_DEVICE_PATH_PROTOCOL        End;
+} USB_CLASS_FORMAT_DEVICE_PATH;
+
+typedef struct {
+  ACPI_HID_DEVICE_PATH      PciRootBridge;
+  PCI_DEVICE_PATH           OnboardVga;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} PLATFORM_ONBOARD_VGA_DEVICE_PATH;
+
+typedef struct {
+  ACPI_HID_DEVICE_PATH      PciRootBridge;
+  PCI_DEVICE_PATH           AgpBridge;
+  PCI_DEVICE_PATH           AgpDevice;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} PLATFORM_OFFBOARD_VGA_DEVICE_PATH;
+
+typedef struct {
+  ACPI_HID_DEVICE_PATH      PciRootBridge;
+  PCI_DEVICE_PATH           IsaBridge;
+  ACPI_HID_DEVICE_PATH      IsaSerial;
+  UART_DEVICE_PATH          Uart;
+  VENDOR_DEVICE_PATH        TerminalType;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} PLATFORM_ISA_SERIAL_DEVICE_PATH;
+
+//
+// Below is the boot option device path
+//
+typedef struct {
+  BBS_BBS_DEVICE_PATH             LegacyHD;
+  EFI_DEVICE_PATH_PROTOCOL        End;
+} LEGACY_HD_DEVICE_PATH;
+
+//
+// Below is the platform IDE device path
+//
+typedef struct {
+  ACPI_HID_DEVICE_PATH      PciRootBridge;
+  PCI_DEVICE_PATH           IsaBridge;
+  ATAPI_DEVICE_PATH         Ide;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} PLATFORM_IDE_DEVICE_PATH;
+
+//
+// Floppy device path definition
+//
+typedef struct {
+  ACPI_HID_DEVICE_PATH      PciRootBridge;
+  PCI_DEVICE_PATH           IsaBridge;
+  ACPI_HID_DEVICE_PATH      Floppy;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} PLATFORM_FLOPPY_DEVICE_PATH;
+
+//
+// Below is the platform USB controller device path for
+// USB disk as user authentication device.
+//
+typedef struct {
+  ACPI_HID_DEVICE_PATH      PciRootBridge;
+  PCI_DEVICE_PATH           PciDevice;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} PLATFORM_USB_DEVICE_PATH;
+
+//
+// Debug Agent UART Console device path definition
+//
+typedef struct {
+  VENDOR_DEVICE_PATH        VendorHardware;
+  UART_DEVICE_PATH          Uart;
+  VENDOR_DEVICE_PATH        TerminalType;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} VENDOR_UART_DEVICE_PATH;
+
+//
+// Below is the platform PCI device path
+//
+typedef struct {
+  ACPI_HID_DEVICE_PATH      PciRootBridge;
+  PCI_DEVICE_PATH           PciDevice;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} PLATFORM_PCI_DEVICE_PATH;
+
+typedef enum {
+  PMIC_Equal         = 0, // =		0
+  PMIC_Greater_Than,	  // >		1
+  PMIC_Smaller_Than,	  // <		2
+  PMIC_Greater_Equal,	  // >=		3
+  PMIC_Smaller_Equal,	  // <=		4
+  PMIC_Any				  // don't care 5
+} PMIC_Condition_list;
+
+typedef enum {
+  PMIC_White_List	= 0,  //White list
+  PMIC_Black_List	= 1   //Black list
+} PMIC_Compliance_mode;
+
+typedef struct {
+  UINT8		Cond_Choice;	// PMIC_Condition_list
+  UINT8		Cond_Number;		// the number
+}PMIC_Condition_Item;
+
+typedef struct {
+  PMIC_Condition_Item   					PMIC_BoardID;
+  PMIC_Condition_Item   					PMIC_FabID;
+  PMIC_Condition_Item   					Soc_Stepping;//define PMIC type, 1:Dialog , 2:Rohm
+  PMIC_Condition_Item   					PMIC_VendID;
+  PMIC_Condition_Item   					PMIC_RevID;
+  PMIC_Compliance_mode 				        mode;        //if 1, blacklist; if 0, white list.
+} PMIC_Compliance_Item;
+
+//
+// Platform BDS Functions
+//
+VOID
+PlatformBdsGetDriverOption (
+  IN LIST_ENTRY                   *BdsDriverLists
+  );
+
+VOID
+PlatformBdsPredictBootOption (
+  IN  LIST_ENTRY                     *BdsBootOptionList
+  );
+
+EFI_STATUS
+PlatformBdsShowProgress (
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground,
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground,
+  CHAR16                        *Title,
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor,
+  UINTN                         Progress,
+  UINTN                         PreviousValue
+  );
+
+VOID
+PlatformBdsConnectSequence (
+  VOID
+  );
+
+EFI_STATUS
+PlatformBdsConnectConsole (
+  IN BDS_CONSOLE_CONNECT_ENTRY   *PlatformConsole
+  );
+
+EFI_STATUS
+PlatformBdsNoConsoleAction (
+  VOID
+  );
+
+VOID
+PlatformBdsEnterFrontPage (
+  IN UINT16                 TimeoutDefault,
+  IN BOOLEAN                ConnectAllHappened
+  );
+
+VOID
+EFIAPI
+PlatformBdsUserIdentify (
+  OUT EFI_USER_PROFILE_HANDLE        *User,
+  OUT BOOLEAN                        *DeferredImage
+  );
+
+VOID
+EFIAPI
+PlatformBdsConnectAuthDevice (
+  VOID
+  );
+
+VOID
+PlatformBdsEnterFrontPageWithHotKey (
+  IN UINT16                       TimeoutDefault,
+  IN BOOLEAN                      ConnectAllHappened
+  );
+
+ EFI_STATUS
+ ShowProgress (
+   IN UINT16					   TimeoutDefault
+   );
+
+ EFI_STATUS
+ InitializeFrontPage (
+   IN BOOLEAN						  InitializeHiiData
+   );
+
+ VOID
+ UpdateFrontPageStrings (
+   VOID
+   );
+   
+   
+ EFI_STATUS
+ InitBMPackage  (
+   VOID
+   );
+   
+      
+ VOID
+ FreeBMPackage  (
+   VOID
+   );
+   
+   
+ EFI_STATUS
+ CallFrontPage (
+   VOID
+   );
+
+
+ VOID
+ CallBootManager (
+   VOID
+   );
+
+VOID
+CallDeviceManager (
+  VOID
+  );
+
+VOID
+BdsStartBootMaint (
+  VOID
+  );
+
+CHAR16 *
+GetStringById (
+  IN  EFI_STRING_ID   Id
+  );
+
+EFI_STATUS
+WaitForSingleEvent (
+  IN EFI_EVENT                  Event,
+  IN UINT64                     Timeout OPTIONAL
+  );
+
+EFI_STATUS
+BdsLibDeleteOptionFromHandle (
+  IN  EFI_HANDLE                 Handle
+  );
+
+EFI_STATUS
+BdsDeleteAllInvalidEfiBootOption (
+  VOID
+  );
+
+
+#define ONE_SECOND  10000000
+#define FRONT_PAGE_KEY_CONTINUE        0x1000
+#define FRONT_PAGE_KEY_LANGUAGE        0x1234
+#define FRONT_PAGE_KEY_BOOT_MANAGER    0x1064
+#define FRONT_PAGE_KEY_DEVICE_MANAGER  0x8567
+#define FRONT_PAGE_KEY_BOOT_MAINTAIN   0x9876
+
+#define PORT_A_DVO                     0           // ; DVO A
+#define PORT_B_DVO                     1           // ; DVO B
+#define PORT_C_DVO                     2           // ; DVO C
+#define PORT_D_DVO                     3           // ; DVO D
+#define PORT_LVDS                      4           // ; Integrated LVDS port
+#define PORT_ANALOG_TV                 5           // ; Integrated TV port
+#define PORT_CRT                       6           // ; integrated Analog port
+#define PORT_B_DP                      7           // ; DisplayPort B
+#define PORT_C_DP                      8           // ; DisplayPort C
+#define PORT_D_DP                      9           // ; DisplayPort D
+#define PORT_A_DP                      10          // ; DisplayPort A (for eDP on ILK)
+#define PORT_B_HDMI                    11          // ; HDMI B
+#define PORT_C_HDMI                    12          // ; HDMI C
+#define PORT_D_HDMI                    13          // ; HDMI D
+#define PORT_B_DVI                     14          // ; DVI B
+#define PORT_C_DVI                     15          // ; DVI C
+#define PORT_D_DVI                     16          // ; DVI D
+#define PORT_MIPI_A                    21          // ; MIPI
+#define PORT_MIPI_B                    22
+#define PORT_MIPI_C                    23
+
+
+extern BOOLEAN gConnectAllHappened;
+extern UINTN gCallbackKey;
+
+VOID
+BdsBootDeviceSelect (
+  VOID
+);
+VOID FastBoot(VOID);
+
+extern BOOLEAN    mModeInitialized;
+
+//
+// Boot video resolution and text mode.
+//
+extern UINT32     mBootHorizontalResolution    ;
+extern UINT32     mBootVerticalResolution      ;
+extern UINT32     mBootTextModeColumn          ;
+extern UINT32     mBootTextModeRow             ;
+
+//
+// BIOS setup video resolution and text mode.
+//
+extern UINT32     mSetupTextModeColumn         ;
+extern UINT32     mSetupTextModeRow            ;
+extern UINT32     mSetupHorizontalResolution   ;
+extern UINT32     mSetupVerticalResolution     ;
+extern EFI_STATUS BdsSetConsoleMode (BOOLEAN);
+#endif // _BDS_PLATFORM_H
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsLib.inf b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsLib.inf
new file mode 100644
index 0000000000..d3bef0fa39
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsLib.inf
@@ -0,0 +1,127 @@
+#/** @file
+# Component name for module PlatformBootManagerLib
+#
+# Copyright (c) 2008  - 2019, Intel Corporation. All rights reserved.<BR>
+#
+
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+#
+
+#
+#
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformBdsLib
+  FILE_GUID                      = A6BC385D-59E5-4b77-87D7-200ABAA83C15
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformBootManagerLib|DXE_DRIVER
+  EDK_RELEASE_VERSION            = 0x00020000
+  EFI_SPECIFICATION_VERSION      = 0x0002000A
+
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  BdsPlatform.c
+  BdsPlatform.h
+  PlatformData.c
+  PlatformBdsStrings.uni
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+  ShellPkg/ShellPkg.dec
+  CryptoPkg/CryptoPkg.dec
+  SecurityPkg/SecurityPkg.dec
+  SignedCapsulePkg/SignedCapsulePkg.dec
+  SourceLevelDebugPkg/SourceLevelDebugPkg.dec
+
+[LibraryClasses]
+  DxeServicesTableLib
+  BaseLib
+  MemoryAllocationLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  BaseMemoryLib
+  DebugLib
+  PcdLib
+  GenericBdsLib
+  DevicePathLib
+  NetLib
+  UefiLib
+  HobLib
+  PciLib
+  PrintLib
+  BaseCryptLib
+#  TcgPhysicalPresenceLib
+  Tcg2PhysicalPresenceLib  
+  FileHandleLib
+  S3BootScriptLib
+  SerialPortLib
+  CapsuleLib
+
+[Protocols]
+  gEfiFirmwareVolume2ProtocolGuid
+  gEfiSimpleNetworkProtocolGuid
+  gEfiLoadFileProtocolGuid
+  gEfiPciIoProtocolGuid
+  gEfiSmmAccess2ProtocolGuid
+  gEfiDxeSmmReadyToLockProtocolGuid
+  gEfiUserManagerProtocolGuid
+  gEfiDeferredImageLoadProtocolGuid
+  gEfiAcpiS3SaveProtocolGuid
+  gEfiSpiProtocolGuid                           ## PROTOCOL CONSUMES
+  gExitPmAuthProtocolGuid
+  gEfiTdtOperationProtocolGuid
+  gEfiGlobalNvsAreaProtocolGuid
+  gEfiMmioDeviceProtocolGuid
+  gEfiI2cMasterProtocolGuid
+  gEfiI2cHostProtocolGuid
+  gEsrtManagementProtocolGuid
+
+[Guids]
+  gEfiMemoryTypeInformationGuid
+  gEfiCapsuleVendorGuid
+  gEfiGlobalVariableGuid
+  gEfiNormalSetupGuid
+  gEfiPartTypeSystemPartGuid
+  gEfiEndOfDxeEventGroupGuid
+  gUefiShellFileGuid
+
+[Pcd]
+  gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiRsa2048Sha256TestPublicKeyFileGuid
+  gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiPkcs7TestPublicKeyFileGuid
+  gEfiSecurityPkgTokenSpaceGuid.PcdRsa2048Sha256PublicKeyBuffer
+  gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer
+  gEfiMdeModulePkgTokenSpaceGuid.PcdTestKeyUsed
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Base
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvMainBase
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoveryBase
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvShellBase
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvShellSize
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile
+  gPlatformModuleTokenSpaceGuid.PcdIFWISigBaseAddress
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutColumn
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutRow
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBootState
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsStrings.uni b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsStrings.uni
new file mode 100644
index 0000000000..101106f9f4
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsStrings.uni
@@ -0,0 +1,30 @@
+///** @file
+//  
+//  String definitions for Boot Option description.
+//  
+//  Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
+//  SPDX-License-Identifier: BSD-2-Clause-Patent
+//  
+//**/
+
+/=#
+
+#langdef   en-US "English"
+#langdef   fr-FR "Français"
+
+#string STR_DESCRIPTION_FLOPPY         #language en-US  "EFI Floppy"
+                                       #language fr-FR  "fr-FR: EFI Floppy"
+#string STR_DESCRIPTION_CD_DVD         #language en-US  "EFI DVD/CDROM"
+                                       #language fr-FR  "fr-FR: EFI DVD/CDROM"
+#string STR_DESCRIPTION_HARDDRIVE      #language en-US  "EFI Hard Drive"
+                                       #language fr-FR  "fr-FR: EFI Hard Drive"
+#string STR_DESCRIPTION_USB            #language en-US  "EFI USB Device"
+                                       #language fr-FR  "fr-FR: EFI USB Device"
+#string STR_DESCRIPTION_SCSI           #language en-US  "EFI SCSI Device"
+                                       #language fr-FR  "fr-FR: EFI SCSI Device"
+#string STR_DESCRIPTION_MISC           #language en-US  "EFI Misc Device"
+                                       #language fr-FR  "fr-FR: EFI Misc Device"
+#string STR_DESCRIPTION_NETWORK        #language en-US  "EFI Network"
+                                       #language fr-FR  "fr-FR: EFI Network"
+#string STR_DESCRIPTION_NON_BLOCK      #language en-US  "EFI Non-Block Boot Device"
+                                       #language fr-FR  "fr-FR: EFI Non-Block Boot Device"
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformData.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformData.c
new file mode 100644
index 0000000000..9dff93f52b
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformData.c
@@ -0,0 +1,306 @@
+/** @file
+
+  Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  PlatformData.c
+
+Abstract:
+
+  Defined the platform specific device path which will be used by
+  platform Bbd to perform the platform policy connect.
+
+--*/
+
+#include "BdsPlatform.h"
+
+//
+// Predefined platform default time out value
+//
+UINT16  gPlatformBootTimeOutDefault = 10;
+
+//
+// Predefined platform root bridge
+//
+PLATFORM_ROOT_BRIDGE_DEVICE_PATH gPlatformRootBridge0 = {
+  gPciRootBridge,
+  gEndEntire
+};
+
+EFI_DEVICE_PATH_PROTOCOL* gPlatformRootBridges [] = {
+  (EFI_DEVICE_PATH_PROTOCOL*)&gPlatformRootBridge0,
+  NULL
+};
+
+//
+// Platform specific ISA keyboard device path
+//
+PLATFORM_ISA_KEYBOARD_DEVICE_PATH gIsaKeyboardDevicePath = {
+  gPciRootBridge,
+  gPciIsaBridge,
+  gPnpPs2Keyboard,
+  gEndEntire
+};
+
+//
+// Platform specific on chip PCI VGA device path
+//
+PLATFORM_ONBOARD_VGA_DEVICE_PATH gOnChipPciVgaDevicePath = {
+  gPciRootBridge,
+  PCI_DEVICE_PATH_NODE(0, 0x2),
+  gEndEntire
+};
+
+//
+// Platform specific plug in PCI VGA device path
+//
+PLATFORM_OFFBOARD_VGA_DEVICE_PATH gPlugInPciVgaDevicePath = {
+  gPciRootBridge,
+  PCI_DEVICE_PATH_NODE(0, 0x1),
+  PCI_DEVICE_PATH_NODE(0, 0x0),
+  gEndEntire
+};
+
+//
+// Platform specific ISA serial device path
+//
+PLATFORM_ISA_SERIAL_DEVICE_PATH gIsaSerialDevicePath = {
+  gPciRootBridge,
+  gPciIsaBridge,
+  gPnp16550ComPort,
+  gUart(115200, 8, 1, 1),
+  gPcAnsiTerminal,
+  gEndEntire
+};
+
+
+//
+// Platform specific Button Array device path
+//
+HII_VENDOR_DEVICE_PATH  gHiiVendorDevicePath0 = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      {
+        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+      }
+    },
+
+    //
+    // {C8752FDE-B5C8-4528-897D-6920FE771E38}
+    //
+    { 0xC8752FDE, 0xB5C8, 0x4528, { 0x89, 0x7D, 0x69, 0x20, 0xFE, 0x77, 0x1E, 0x38 } }
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      (UINT8) (END_DEVICE_PATH_LENGTH),
+      (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
+    }
+  }
+};
+
+USB_CLASS_FORMAT_DEVICE_PATH gUsbClassKeyboardDevicePath = {
+  gUsbKeyboardMouse,
+  gEndEntire
+};
+
+//
+// Debug Agent UART Console device path 
+//
+VENDOR_UART_DEVICE_PATH gDebugAgentUartDevicePath = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      {
+        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+      }
+    },
+    EFI_DEBUG_AGENT_GUID,
+  },
+  {
+    {
+      MESSAGING_DEVICE_PATH,
+      MSG_UART_DP,
+      {
+        (UINT8) (sizeof (UART_DEVICE_PATH)),
+        (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8)
+      }
+    },
+    0,  // Reserved
+    0,  // BaudRate - Default
+    0,  // DataBits - Default
+    0,  // Parity   - Default
+    0,  // StopBits - Default
+  },
+  {
+    {
+      MESSAGING_DEVICE_PATH,
+      MSG_VENDOR_DP,
+      {
+        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
+        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+      }
+    },
+    DEVICE_PATH_MESSAGING_PC_ANSI
+  },
+  gEndEntire
+};
+
+//
+// Predefined platform default console device path
+//
+BDS_CONSOLE_CONNECT_ENTRY gPlatformConsole [] = {
+  {(EFI_DEVICE_PATH_PROTOCOL*)&gIsaSerialDevicePath, CONSOLE_ALL},
+  {(EFI_DEVICE_PATH_PROTOCOL*)&gHiiVendorDevicePath0, CONSOLE_IN},
+  {(EFI_DEVICE_PATH_PROTOCOL*)&gIsaKeyboardDevicePath, CONSOLE_IN},
+  {(EFI_DEVICE_PATH_PROTOCOL*)&gDebugAgentUartDevicePath, CONSOLE_ALL},
+  {(EFI_DEVICE_PATH_PROTOCOL*)&gUsbClassKeyboardDevicePath, CONSOLE_IN},
+  {NULL, 0}
+};
+
+//
+// All the possible platform PCI VGA device path
+//
+EFI_DEVICE_PATH_PROTOCOL* gPlatformAllPossiblePciVgaConsole [] = {
+  (EFI_DEVICE_PATH_PROTOCOL*)&gOnChipPciVgaDevicePath,
+  (EFI_DEVICE_PATH_PROTOCOL*)&gPlugInPciVgaDevicePath,
+  NULL
+};
+
+//
+// Legacy hard disk boot option
+//
+LEGACY_HD_DEVICE_PATH gLegacyHd = {
+  {
+    BBS_DEVICE_PATH,
+    BBS_BBS_DP,
+    (UINT8)(sizeof(BBS_BBS_DEVICE_PATH)),
+    (UINT8)((sizeof(BBS_BBS_DEVICE_PATH)) >> 8),
+    BBS_TYPE_HARDDRIVE,
+    0,
+    0
+  },
+  gEndEntire
+};
+
+//
+// Legacy cdrom boot option
+//
+LEGACY_HD_DEVICE_PATH gLegacyCdrom = {
+  {
+    BBS_DEVICE_PATH,
+    BBS_BBS_DP,
+    (UINT8)(sizeof(BBS_BBS_DEVICE_PATH)),
+    (UINT8)((sizeof(BBS_BBS_DEVICE_PATH)) >> 8),
+    BBS_TYPE_CDROM,
+    0,
+    0
+  },
+  gEndEntire
+};
+
+//
+// Predefined platform specific perdict boot option
+//
+EFI_DEVICE_PATH_PROTOCOL* gPlatformBootOption [] = {
+  (EFI_DEVICE_PATH_PROTOCOL*)&gLegacyHd,
+  (EFI_DEVICE_PATH_PROTOCOL*)&gLegacyCdrom,
+  NULL
+};
+
+//
+// Predefined platform specific driver option
+//
+EFI_DEVICE_PATH_PROTOCOL* gPlatformDriverOption [] = {
+  NULL
+};
+
+//
+// Predefined platform connect sequence
+//
+EFI_DEVICE_PATH_PROTOCOL* gPlatformConnectSequence [] = {
+  (EFI_DEVICE_PATH_PROTOCOL *)&gPlatformRootBridge0,  // Force PCI enumer before Legacy OpROM shadow
+  NULL
+};
+
+//
+// Platform specific USB controller device path
+//
+PLATFORM_USB_DEVICE_PATH gUsbDevicePath0 = {
+  gPciRootBridge,
+  PCI_DEVICE_PATH_NODE(0, 0x1D),
+  gEndEntire
+};
+
+PLATFORM_USB_DEVICE_PATH gUsbDevicePath1 = {
+  gPciRootBridge,
+  PCI_DEVICE_PATH_NODE(1, 0x1D),
+  gEndEntire
+};
+
+PLATFORM_USB_DEVICE_PATH gUsbDevicePath2 = {
+  gPciRootBridge,
+  PCI_DEVICE_PATH_NODE(2, 0x1D),
+  gEndEntire
+};
+
+PLATFORM_USB_DEVICE_PATH gUsbDevicePath3 = {
+  gPciRootBridge,
+  PCI_DEVICE_PATH_NODE(3, 0x1D),
+  gEndEntire
+};
+
+//
+// Predefined platform device path for user authtication
+//
+EFI_DEVICE_PATH_PROTOCOL* gUserAuthenticationDevice[] = {
+  //
+  // Predefined device path for secure card (USB disk).
+  //
+  (EFI_DEVICE_PATH_PROTOCOL*)&gUsbDevicePath0,
+  (EFI_DEVICE_PATH_PROTOCOL*)&gUsbDevicePath1,
+  (EFI_DEVICE_PATH_PROTOCOL*)&gUsbDevicePath2,
+  (EFI_DEVICE_PATH_PROTOCOL*)&gUsbDevicePath3,
+  NULL
+};
+
+//
+// Predefined platform console device path
+//
+BDS_CONSOLE_CONNECT_ENTRY gPlatformSimpleConsole [] = {
+  {(EFI_DEVICE_PATH_PROTOCOL*)&gOnChipPciVgaDevicePath, CONSOLE_OUT},
+  {(EFI_DEVICE_PATH_PROTOCOL*)&gIsaSerialDevicePath, CONSOLE_ALL},
+  {(EFI_DEVICE_PATH_PROTOCOL*)&gHiiVendorDevicePath0, CONSOLE_IN},
+  {(EFI_DEVICE_PATH_PROTOCOL*)&gDebugAgentUartDevicePath, CONSOLE_ALL},
+  {(EFI_DEVICE_PATH_PROTOCOL*)&gUsbClassKeyboardDevicePath, CONSOLE_IN},
+  {NULL, 0}
+};
+
+//
+// eMMC device at BDF(0x0, 0x17, 0x0)
+//
+PLATFORM_PCI_DEVICE_PATH gEmmcBootDevPath0 = {
+  gPciRootBridge,
+  PCI_DEVICE_PATH_NODE (0x00, 0x10),
+  gEndEntire
+};
+
+//
+// Predefined platform specific perdict boot option
+//
+EFI_DEVICE_PATH_PROTOCOL* gPlatformSimpleBootOption [] = {
+  (EFI_DEVICE_PATH_PROTOCOL*)&gEmmcBootDevPath0,
+  NULL
+};
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmosLib.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmosLib.c
new file mode 100644
index 0000000000..2a02cabcaf
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmosLib.c
@@ -0,0 +1,106 @@
+/*++
+
+Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  CmosTable.h
+
+Abstract:
+
+--*/
+
+#include <Base.h>
+#include <Library/IoLib.h>
+#include <Library/PlatformCmosLib.h>
+#include "CmosMap.h"
+#include <PchAccess.h>
+#include "PlatformBaseAddresses.h"
+
+#define DEFAULT_VALUE          0
+#define  DEFAULT_ATTRIBUTES     0
+#define  EXCLUDE_FROM_CHECKSUM   CMOS_ATTRIBUTE_EXCLUDE_FROM_CHECKSUM
+
+#define CMOS_DEBUG_PRINT_LEVEL_DEFAULT_VALUE      0x46   // EFI_D_WARN|EFI_D_INFO|EFI_D_LOAD
+#define CMOS_DEBUG_PRINT_LEVEL_3_DEFAULT_VALUE    0x80   // EFI_D_ERROR
+
+//
+// Add the CMOS entry below
+//
+CMOS_ENTRY mCmosTable[] = {
+{ CPU_HT_POLICY, CPU_HT_POLICY_ENABLED, EXCLUDE_FROM_CHECKSUM },
+{ TPM_POLICY, TPM_POLICY_ENABLED, DEFAULT_ATTRIBUTES },
+{ CMOS_LCDPANELTYPE_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_LCDPANELSCALING_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_IGDBOOTTYPE_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_BACKLIGHT_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_LFP_PANEL_COLOR_DEPTH_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_EDP_ACTIVE_LFP_CONFIG_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_PRIMARY_DISPLAY_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_IGD_DISPLAY_PIPE_B_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_SDVOPANELTYPE_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_PLATFORM_RESET_OS, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_CPU_BSP_SELECT, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_CPU_RATIO_OFFSET, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_ICH_PORT80_OFFSET, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ CMOS_MAXRATIO_CONFIG_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
+{ RTC_ADDRESS_CENTURY, RTC_ADDRESS_CENTURY_DEFAULT, CMOS_ATTRIBUTE_EXCLUDE_FROM_CHECKSUM },
+{ CMOS_POST_CODE_BREAK_REG, DEFAULT_VALUE, EXCLUDE_FROM_CHECKSUM },
+{ CMOS_POST_CODE_BREAK_1_REG, DEFAULT_VALUE, EXCLUDE_FROM_CHECKSUM },
+{ CMOS_POST_CODE_BREAK_2_REG, DEFAULT_VALUE, EXCLUDE_FROM_CHECKSUM },
+{ CMOS_POST_CODE_BREAK_3_REG, DEFAULT_VALUE, EXCLUDE_FROM_CHECKSUM },
+{ CMOS_DEBUG_PRINT_LEVEL_REG, CMOS_DEBUG_PRINT_LEVEL_DEFAULT_VALUE, EXCLUDE_FROM_CHECKSUM },
+{ CMOS_DEBUG_PRINT_LEVEL_1_REG, DEFAULT_VALUE, EXCLUDE_FROM_CHECKSUM },
+{ CMOS_DEBUG_PRINT_LEVEL_2_REG, DEFAULT_VALUE, EXCLUDE_FROM_CHECKSUM },
+{ CMOS_DEBUG_PRINT_LEVEL_3_REG, CMOS_DEBUG_PRINT_LEVEL_3_DEFAULT_VALUE, EXCLUDE_FROM_CHECKSUM },
+};
+
+/**
+  Funtion to return platform CMOS entry.
+
+  @param [out]  CmosEntry  Platform CMOS entry.
+
+  @param [out]  CmosEntryCount Number of platform CMOS entry.
+
+  @return Status.
+**/
+RETURN_STATUS
+EFIAPI
+GetPlatformCmosEntry (
+  OUT CMOS_ENTRY  **CmosEntry,
+  OUT UINTN       *CmosEntryCount
+  )
+{
+  *CmosEntry = mCmosTable;
+  *CmosEntryCount = sizeof(mCmosTable)/sizeof(mCmosTable[0]);
+  return RETURN_SUCCESS;
+}
+
+/**
+  Function to check if Battery lost or CMOS cleared.
+
+  @reval TRUE  Battery is always present.
+  @reval FALSE CMOS is cleared.
+**/
+BOOLEAN
+EFIAPI
+CheckCmosBatteryStatus (
+  VOID
+  )
+{
+  //
+  // Check if the CMOS battery is present
+  // Checks RTC_PWR_STS bit in the GEN_PMCON_1 register
+  //
+
+  if ((MmioRead8 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1) & B_PCH_PMC_GEN_PMCON_RTC_PWR_STS) == 0) {
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmosLib.inf b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmosLib.inf
new file mode 100644
index 0000000000..c5d8b66591
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmosLib.inf
@@ -0,0 +1,30 @@
+#/** @file
+#
+# Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+#                                                                                  

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

+#
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformCmosLib
+  FILE_GUID                      = ECA883EF-0CBE-40b6-84BC-FA4A709782F7
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformCmosLib
+
+[Sources]
+  PlatformCmosLib.c
+
+[LibraryClasses]
+  IoLib
+
+[Packages]
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.c
new file mode 100644
index 0000000000..b99c3b0122
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.c
@@ -0,0 +1,44 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+**/
+#include "PiPei.h"
+#include <Library/HobLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Guid/MemoryConfigData.h>
+#include <PlatformFspLib.h>
+
+EFI_STATUS
+PlatformHobCreateFromFsp (
+  IN CONST EFI_PEI_SERVICES     **PeiServices,
+  VOID                          *HobList
+  )
+{
+  VOID       *HobData;
+  VOID       *NewHobData;
+  UINTN      DataSize;
+
+  //
+  // Other hob, todo: put this into FspWrapPlatformLib
+  //
+  if ((HobList = GetNextGuidHob (&gEfiMemoryConfigDataGuid, HobList)) != NULL) {
+    HobData = GET_GUID_HOB_DATA (HobList);
+    DataSize = GET_GUID_HOB_DATA_SIZE(HobList);
+    DEBUG((EFI_D_ERROR, "gEfiMemoryConfigDataGuid Hob found: 0x%x.\n", DataSize));
+
+    NewHobData = BuildGuidHob (&gEfiMemoryConfigDataGuid, DataSize);
+    (*PeiServices)->CopyMem (
+                      NewHobData,
+                      HobData,
+                      DataSize
+                      );
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.inf b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.inf
new file mode 100644
index 0000000000..ddd97c5ad9
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.inf
@@ -0,0 +1,49 @@
+#
+#
+# Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
+#                                                                                  

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

+#
+#
+#
+#    FSP Platform HOB Library
+#
+#
+#
+##
+
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformFspLib
+  FILE_GUID                      = 1305A712-33A6-4fa7-BA59-AEAC3362931A
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformFspLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  PlatformFspLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+  IntelFspWrapperPkg/IntelFspWrapperPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  HobLib
+
+[Guids]
+  gEfiMemoryConfigDataGuid
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLib.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLib.c
new file mode 100644
index 0000000000..fac998fefa
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLib.c
@@ -0,0 +1,235 @@
+/** @file
+
+  Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+
+Module Name:
+
+  IdeBus.h
+
+Abstract:
+
+  System reset Library Services.  This library class provides a set of
+  methods to reset whole system with manipulate ICH.
+
+**/
+
+
+#include <Base.h>
+
+
+#include <Library/ResetSystemLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PciLib.h>
+
+#include "PchRegs.h"
+#include "Rsci.h"
+#include "Platform.h"
+
+#define RESET_GENERATOR_PORT R_PCH_RST_CNT
+
+VOID
+EFIAPI
+PlatformResetHook (
+  UINT8 ResetType
+  )
+{
+  //
+  // Platform need to save OS reset request/types for next Android boot
+  //
+  IoWrite8 (0x72, CMOS_RESET_TYPE_BY_OS);
+  IoWrite8 (0x73, ResetType);
+}
+
+/**
+  Calling this function causes a system-wide reset. This sets
+  all circuitry within the system to its initial state. This type of reset
+  is asynchronous to system operation and operates without regard to
+  cycle boundaries.
+
+  System reset should not return, if it returns, it means the system does
+  not support cold reset.
+**/
+VOID
+EFIAPI
+ResetCold (
+  VOID
+  )
+{
+  PlatformResetHook(COLD_RESET);
+  IoWrite8 (RESET_GENERATOR_PORT, 0x2);
+  IoWrite8 (RESET_GENERATOR_PORT, 0x6);
+}
+
+/**
+  Calling this function causes a system-wide initialization. The processors
+  are set to their initial state, and pending cycles are not corrupted.
+
+  System reset should not return, if it returns, it means the system does
+  not support warm reset.
+**/
+VOID
+EFIAPI
+ResetWarm (
+  VOID
+  )
+{
+  PlatformResetHook(WARM_RESET);
+  IoWrite8 (RESET_GENERATOR_PORT, 0x0);
+  IoWrite8 (RESET_GENERATOR_PORT, 0x4);
+}
+
+/**
+  Calling this function causes the system to enter a power state equivalent
+  to the ACPI G2/S5 or G3 states.
+
+  System shutdown should not return, if it returns, it means the system does
+  not support shut down reset.
+**/
+VOID
+EFIAPI
+ResetShutdown (
+  VOID
+  )
+{
+  UINT16  PchPmioBase;
+  UINT16  Data16;
+  UINT32  Data32;
+
+  PchPmioBase = (UINT16) (PciRead16 (PCI_LIB_ADDRESS(0, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_ACPI_BASE)) & ~BIT0);
+
+  //
+  // Then, GPE0_EN should be disabled to avoid any GPI waking up the system from S5
+  //
+  Data16 = 0;
+  IoWrite16 (
+    (UINTN)(PchPmioBase + R_PCH_ACPI_GPE0a_EN),
+    (UINT16)Data16
+    );
+
+  //
+  // Clear Sleep SMI Status
+  //
+  IoWrite16 (PchPmioBase + R_PCH_SMI_STS,
+             (UINT16)(IoRead16 (PchPmioBase + R_PCH_SMI_STS) | B_PCH_SMI_STS_ON_SLP_EN));
+  //
+  // Clear Sleep Type Enable
+  //
+  IoWrite16 (PchPmioBase + R_PCH_SMI_EN,
+             (UINT16)(IoRead16 (PchPmioBase + R_PCH_SMI_EN) & (~B_PCH_SMI_EN_ON_SLP_EN)));
+  //
+  // Clear Power Button Status
+  //
+  IoWrite16(PchPmioBase + R_PCH_ACPI_PM1_STS, B_PCH_ACPI_PM1_STS_PWRBTN);
+
+  //
+  // Secondly, Power Button Status bit must be cleared
+  //
+  // Write a "1" to bit[8] of power button status register at
+  // (ABASE + PM1_STS) to clear this bit
+  // Clear it through SMI Status register
+  //
+  Data16 = B_PCH_SMI_STS_PM1_STS_REG;
+  IoWrite16 ((UINTN) (PchPmioBase + R_PCH_SMI_STS), Data16);
+
+  //
+  // Finally, transform system into S5 sleep state
+  //
+  Data32  = IoRead32 ((UINTN) (PchPmioBase + R_PCH_ACPI_PM1_CNT));
+
+  Data32  = (UINT32) ((Data32 &~(B_PCH_ACPI_PM1_CNT_SLP_TYP + B_PCH_ACPI_PM1_CNT_SLP_EN)) | V_PCH_ACPI_PM1_CNT_S5);
+
+  IoWrite32 ((UINTN) (PchPmioBase + R_PCH_ACPI_PM1_CNT), Data32);
+
+  Data32 = Data32 | B_PCH_ACPI_PM1_CNT_SLP_EN;
+
+  IoWrite32 ((UINTN) (PchPmioBase + R_PCH_ACPI_PM1_CNT), Data32);
+
+  return;
+}
+
+/**
+  Calling this function causes the system to enter a power state for capsule
+  update.
+
+  Reset update should not return, if it returns, it means the system does
+  not support capsule update.
+
+**/
+VOID
+EFIAPI
+EnterS3WithImmediateWake (
+  VOID
+  )
+{
+  ASSERT (FALSE);
+}
+
+/**
+  This function causes a systemwide reset. The exact type of the reset is
+  defined by the EFI_GUID that follows the Null-terminated Unicode string passed
+  into ResetData. If the platform does not recognize the EFI_GUID in ResetData
+  the platform must pick a supported reset type to perform.The platform may
+  optionally log the parameters from any non-normal reset that occurs.
+
+  @param[in]  DataSize   The size, in bytes, of ResetData.
+  @param[in]  ResetData  The data buffer starts with a Null-terminated string,
+                         followed by the EFI_GUID.
+**/
+VOID
+EFIAPI
+ResetPlatformSpecific (
+  IN UINTN   DataSize,
+  IN VOID    *ResetData
+  )
+{
+  ResetCold ();
+}
+
+/**
+  The ResetSystem function resets the entire platform.
+
+  @param[in] ResetType      The type of reset to perform.
+  @param[in] ResetStatus    The status code for the reset.
+  @param[in] DataSize       The size, in bytes, of ResetData.
+  @param[in] ResetData      For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown
+                            the data buffer starts with a Null-terminated string, optionally
+                            followed by additional binary data. The string is a description
+                            that the caller may use to further indicate the reason for the
+                            system reset.
+**/
+VOID
+EFIAPI
+ResetSystem (
+  IN EFI_RESET_TYPE               ResetType,
+  IN EFI_STATUS                   ResetStatus,
+  IN UINTN                        DataSize,
+  IN VOID                         *ResetData OPTIONAL
+  )
+{
+  switch (ResetType) {
+  case EfiResetWarm:
+    ResetWarm ();
+    break;
+
+  case EfiResetCold:
+    ResetCold ();
+    break;
+
+  case EfiResetShutdown:
+    ResetShutdown ();
+    return;
+
+  case EfiResetPlatformSpecific:
+    ResetPlatformSpecific (DataSize, ResetData);
+    return;
+
+  default:
+    return;
+  }
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLib.inf b/Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLib.inf
new file mode 100644
index 0000000000..db1a92b34e
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLib.inf
@@ -0,0 +1,47 @@
+#/** @file
+# Component description file for Intel Ich7 Reset System Library.
+#
+# Reset System Library that layers on top of the I/O Library to directly
+#  access a standard SMBUS host controller.
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+#                                                                                  

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

+#
+#
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = ResetSystemLib
+  FILE_GUID                      = D4FF05AA-3C7D-4b8a-A1EE-AA5EFA0B1732
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ResetSystemLib
+  EDK_RELEASE_VERSION            = 0x00020000
+  EFI_SPECIFICATION_VERSION      = 0x00020000
+
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources.common]
+  ResetSystemLib.c
+
+
+[Packages]
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+
+[LibraryClasses]
+  IoLib
+  BaseLib
+  DebugLib
+  PciLib
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/PlatformSerialPortLib.h b/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/PlatformSerialPortLib.h
new file mode 100644
index 0000000000..fe47e8f68d
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/PlatformSerialPortLib.h
@@ -0,0 +1,53 @@
+/** @file
+  Header file of Serial port hardware definition.
+
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+                                                                                   
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __PLATFORM_SERIAL_PORT_LIB_H_
+#define __PLATFORM_SERIAL_PORT_LIB_H_
+
+#include <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/SerialPortLib.h>
+
+//
+// UART Register Offsets
+//
+#define BAUD_LOW_OFFSET   0x00
+#define BAUD_HIGH_OFFSET  0x01
+#define IER_OFFSET        0x01
+#define LCR_SHADOW_OFFSET 0x01
+#define FCR_SHADOW_OFFSET 0x02
+#define IR_CONTROL_OFFSET 0x02
+#define FCR_OFFSET        0x02
+#define EIR_OFFSET        0x02
+#define BSR_OFFSET        0x03
+#define LCR_OFFSET        0x03
+#define MCR_OFFSET        0x04
+#define LSR_OFFSET        0x05
+#define MSR_OFFSET        0x06
+
+//
+// UART Register Bit Defines
+//
+#define LSR_TXRDY 0x20
+#define LSR_RXDA  0x01
+#define DLAB      0x01
+
+#define UART_DATA    8
+#define UART_STOP    1
+#define UART_PARITY  0
+#define UART_BREAK_SET  0
+
+VOID
+InitializeSio (
+  VOID
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.c
new file mode 100644
index 0000000000..f6012593d0
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.c
@@ -0,0 +1,246 @@
+/** @file
+  Serial I/O Port library functions with no library constructor/destructor
+
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+                                                                                   
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PlatformSerialPortLib.h"
+
+UINT16 gComBase  = 0x3f8;
+UINTN  gBps      = 115200;
+UINT8  gData     = 8;
+UINT8  gStop     = 1;
+UINT8  gParity   = 0;
+UINT8  gBreakSet = 0;
+
+/**
+  Initialize Serial Port
+
+  The Baud Rate Divisor registers are programmed and the LCR
+  is used to configure the communications format. Hard coded
+  UART config comes from globals in DebugSerialPlatform lib.
+
+  @param None
+
+  @retval None
+
+**/
+RETURN_STATUS
+EFIAPI
+UARTInitialize (
+  VOID
+  )
+{
+  UINTN Divisor;
+  UINT8 OutputData;
+  UINT8 Data;
+
+  //
+  // Map 5..8 to 0..3
+  //
+  Data = (UINT8) (gData - (UINT8) 5);
+
+  //
+  // Calculate divisor for baud generator
+  //
+  Divisor = 115200 / gBps;
+
+  //
+  // Set communications format
+  //
+  OutputData = (UINT8) ((DLAB << 7) | ((gBreakSet << 6) | ((gParity << 3) | ((gStop << 2) | Data))));
+  IoWrite8 (gComBase + LCR_OFFSET, OutputData);
+
+  //
+  // Configure baud rate
+  //
+  IoWrite8 (gComBase + BAUD_HIGH_OFFSET, (UINT8) (Divisor >> 8));
+  IoWrite8 (gComBase + BAUD_LOW_OFFSET, (UINT8) (Divisor & 0xff));
+
+  //
+  // Switch back to bank 0
+  //
+  OutputData = (UINT8) ((~DLAB << 7) | ((gBreakSet << 6) | ((gParity << 3) | ((gStop << 2) | Data))));
+  IoWrite8 (gComBase + LCR_OFFSET, OutputData);
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Common function to initialize UART Serial device and USB Serial device.
+
+  @param None
+
+  @retval None
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortInitialize (
+  VOID
+  )
+{
+
+  UARTInitialize ();
+
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Write data to serial device.
+
+  If the buffer is NULL, then return 0;
+  if NumberOfBytes is zero, then return 0.
+
+  @param  Buffer           Point of data buffer which need to be writed.
+  @param  NumberOfBytes    Number of output bytes which are cached in Buffer.
+
+  @retval 0                Write data failed.
+  @retval !0               Actual number of bytes writed to serial device.
+
+**/
+UINTN
+EFIAPI
+UARTDbgOut (
+  IN UINT8     *Buffer,
+  IN UINTN     NumberOfBytes
+)
+{
+  UINTN Result;
+  UINT8 Data;
+
+  if (NULL == Buffer) {
+    return 0;
+  }
+
+  Result = NumberOfBytes;
+
+  while (NumberOfBytes--) {
+    //
+    // Wait for the serial port to be ready.
+    //
+    do {
+      Data = IoRead8 ((UINT16) PcdGet64 (PcdSerialRegisterBase) + LSR_OFFSET);
+    } while ((Data & LSR_TXRDY) == 0);
+    IoWrite8 ((UINT16) PcdGet64 (PcdSerialRegisterBase), *Buffer++);
+  }
+
+  return Result;
+}
+
+/**
+  Common function to write data to UART Serial device and USB Serial device.
+
+  @param  Buffer           Point of data buffer which need to be writed.
+  @param  NumberOfBytes    Number of output bytes which are cached in Buffer.
+
+**/
+UINTN
+EFIAPI
+SerialPortWrite (
+  IN UINT8     *Buffer,
+  IN UINTN     NumberOfBytes
+)
+{
+  if (FeaturePcdGet (PcdStatusCodeUseIsaSerial)) {
+    UARTDbgOut (Buffer, NumberOfBytes);
+  }
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Read data from serial device and save the datas in buffer.
+
+  If the buffer is NULL, then return 0;
+  if NumberOfBytes is zero, then return 0.
+
+  @param  Buffer           Point of data buffer which need to be writed.
+  @param  NumberOfBytes    Number of output bytes which are cached in Buffer.
+
+  @retval 0                Read data failed.
+  @retval !0               Actual number of bytes raed to serial device.
+
+**/
+UINTN
+EFIAPI
+UARTDbgIn (
+  OUT UINT8     *Buffer,
+  IN  UINTN     NumberOfBytes
+)
+{
+  UINTN Result;
+  UINT8 Data;
+
+  if (NULL == Buffer) {
+    return 0;
+  }
+
+  Result = NumberOfBytes;
+
+  while (NumberOfBytes--) {
+    //
+    // Wait for the serial port to be ready.
+    //
+    do {
+      Data = IoRead8 ((UINT16) PcdGet64 (PcdSerialRegisterBase) + LSR_OFFSET);
+    } while ((Data & LSR_RXDA) == 0);
+
+    *Buffer++ = IoRead8 ((UINT16) PcdGet64 (PcdSerialRegisterBase));
+  }
+
+  return Result;
+}
+
+/**
+  Common function to Read data from UART serial device, USB serial device and save the datas in buffer.
+
+  @param  Buffer           Point of data buffer which need to be writed.
+  @param  NumberOfBytes    Number of output bytes which are cached in Buffer.
+
+**/
+UINTN
+EFIAPI
+SerialPortRead (
+  OUT UINT8     *Buffer,
+  IN  UINTN     NumberOfBytes
+)
+{
+  if (FeaturePcdGet (PcdStatusCodeUseIsaSerial)) {
+    UARTDbgIn (Buffer, NumberOfBytes);
+  }
+
+  return RETURN_SUCCESS;
+}
+
+
+/**
+  Polls a serial device to see if there is any data waiting to be read.
+
+  Polls aserial device to see if there is any data waiting to be read.
+  If there is data waiting to be read from the serial device, then TRUE is returned.
+  If there is no data waiting to be read from the serial device, then FALSE is returned.
+
+  @retval TRUE             Data is waiting to be read from the serial device.
+  @retval FALSE            There is no data waiting to be read from the serial device.
+
+**/
+BOOLEAN
+EFIAPI
+SerialPortPoll (
+  VOID
+  )
+{
+  UINT8  Data;
+
+  //
+  // Read the serial port status.
+  //
+  Data = IoRead8 ((UINT16) PcdGet64 (PcdSerialRegisterBase) + LSR_OFFSET);
+
+  return (BOOLEAN) ((Data & LSR_RXDA) != 0);
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.inf b/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.inf
new file mode 100644
index 0000000000..0e7a6d3cfc
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.inf
@@ -0,0 +1,52 @@
+#/** @file
+#
+# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
+#                                                                                  

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

+#
+#
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SerialPortLib
+  FILE_GUID                      = 15B26F43-A389-4bae-BDE3-4BB0719B7D4F
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SerialPortLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  SerialPortLib.c
+  SioInit.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+
+[LibraryClasses]
+  BaseLib
+  PcdLib
+  IoLib
+  PciLib
+  TimerLib
+
+[FixedPcd.common]
+  gEfiSerialPortTokenSpaceGuid.PcdSerialBoudRate
+  gEfiSerialPortTokenSpaceGuid.PcdSerialRegisterBase
+
+[FeaturePcd]
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseIsaSerial
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseUsbSerial
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseRam
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.c
new file mode 100644
index 0000000000..d9d48539dc
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.c
@@ -0,0 +1,127 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+    SioInit.c
+
+Abstract:
+
+    Functions for LpcSio initialization
+
+--*/
+
+#include "PlatformSerialPortLib.h"
+#include "SioInit.h"
+
+typedef struct {
+  UINT8 Register;
+  UINT8 Value;
+} EFI_SIO_TABLE;
+
+EFI_SIO_TABLE mSioTableWpcn381u[] = {
+    {0x29, 0x0A0},
+    {WPCN381U_LD_SEL_REGISTER, WPCN381U_LDN_UART0},                                       // Select UART0 device
+    {WPCN381U_BASE1_HI_REGISTER, (UINT8)(WPCN381U_SERIAL_PORT0_BASE_ADDRESS >> 8)},       // Set Base Address MSB
+    {WPCN381U_BASE1_LO_REGISTER, (UINT8)(WPCN381U_SERIAL_PORT0_BASE_ADDRESS & 0x00FF)},   // Set Base Address LSB
+    {WPCN381U_IRQ1_REGISTER, 0x014},                                                      // Set to IRQ4
+    {WPCN381U_ACTIVATE_REGISTER, WPCN381U_ACTIVATE_VALUE},                                // Enable it with Activation bit
+    {WPCN381U_LD_SEL_REGISTER, WPCN381U_LDN_UART1},                                       // Select UART1 device
+    {WPCN381U_BASE1_HI_REGISTER, (UINT8)(WPCN381U_SERIAL_PORT1_BASE_ADDRESS >> 8)},       // Set Base Address MSB
+    {WPCN381U_BASE1_LO_REGISTER, (UINT8)(WPCN381U_SERIAL_PORT1_BASE_ADDRESS & 0x00FF)},   // Set Base Address LSB
+    {WPCN381U_IRQ1_REGISTER, 0x013},                                                      // Set to IRQ3
+    {WPCN381U_ACTIVATE_REGISTER, WPCN381U_ACTIVATE_VALUE},                                // Enable it with Activation bit
+    {WPCN381U_LD_SEL_REGISTER, WPCN381U_LDN_GPIO},                                        // Select GPIO device
+    {WPCN381U_BASE1_HI_REGISTER, (UINT8)(WPCN381U_GPIO_BASE_ADDRESS >> 8)},               // Set Base Address MSB
+    {WPCN381U_BASE1_LO_REGISTER, (UINT8)(WPCN381U_GPIO_BASE_ADDRESS & 0x00FF)},           // Set Base Address LSB
+    {WPCN381U_ACTIVATE_REGISTER, WPCN381U_ACTIVATE_VALUE},                                // Enable it with Activation bit
+    {0x21, 0x001},                                                                        // Global Device Enable
+    {0x26, 0x000}
+};
+
+EFI_SIO_TABLE mSioTableWdcp376[] = {
+    {0x29, 0x0A0},
+    {WPCN381U_LD_SEL_REGISTER, WPCN381U_LDN_UART0},                                       // Select UART0 device
+    {WPCN381U_BASE1_HI_REGISTER, (UINT8)(WPCN381U_SERIAL_PORT0_BASE_ADDRESS >> 8)},       // Set Base Address MSB
+    {WPCN381U_BASE1_LO_REGISTER, (UINT8)(WPCN381U_SERIAL_PORT0_BASE_ADDRESS & 0x00FF)},   // Set Base Address LSB
+    {WPCN381U_IRQ1_REGISTER, 0x014},                                                      // Set to IRQ4
+    {WPCN381U_ACTIVATE_REGISTER, WPCN381U_ACTIVATE_VALUE},                                // Enable it with Activation bit
+    {WPCN381U_LD_SEL_REGISTER, WPCN381U_LDN_UART1},                                       // Select UART1 device
+    {WPCN381U_BASE1_HI_REGISTER, (UINT8)(WPCN381U_SERIAL_PORT1_BASE_ADDRESS >> 8)},       // Set Base Address MSB
+    {WPCN381U_BASE1_LO_REGISTER, (UINT8)(WPCN381U_SERIAL_PORT1_BASE_ADDRESS & 0x00FF)},   // Set Base Address LSB
+    {WPCN381U_IRQ1_REGISTER, 0x013},                                                      // Set to IRQ3
+    {WPCN381U_ACTIVATE_REGISTER, WPCN381U_ACTIVATE_VALUE},                                // Enable it with Activation bit
+    {WPCN381U_LD_SEL_REGISTER, WPCN381U_LDN_GPIO},                                        // Select GPIO device
+    {WPCN381U_BASE1_HI_REGISTER, (UINT8)(WPCN381U_GPIO_BASE_ADDRESS >> 8)},               // Set Base Address MSB
+    {WPCN381U_BASE1_LO_REGISTER, (UINT8)(WPCN381U_GPIO_BASE_ADDRESS & 0x00FF)},           // Set Base Address LSB
+    {WPCN381U_ACTIVATE_REGISTER, WPCN381U_ACTIVATE_VALUE},                                // Enable it with Activation bit
+    {0x21, 0x001},                                                                        // Global Device Enable
+    {0x26, 0x000},
+    {WPCN381U_LD_SEL_REGISTER, WPCN381U_LDN_PS2K},                                        // Select PS2 Keyboard
+    {WPCN381U_BASE1_HI_REGISTER, (UINT8)(WPCN381U_KB_BASE1_ADDRESS >> 8)},                // Set Base Address MSB
+    {WPCN381U_BASE1_LO_REGISTER, (UINT8)(WPCN381U_KB_BASE1_ADDRESS & 0x00FF)},            // Set Base Address LSB
+    {WPCN381U_BASE2_HI_REGISTER, (UINT8)(WPCN381U_KB_BASE2_ADDRESS >> 8)},                // Set Base Address MSB
+    {WPCN381U_BASE2_LO_REGISTER, (UINT8)(WPCN381U_KB_BASE2_ADDRESS & 0x00FF)},            // Set Base Address LSB
+    {WPCN381U_IRQ1_REGISTER, 0x011},                                                      // Set to IRQ1
+    {0xF0, (SIO_KBC_CLOCK << 6)},                                                         // Select KBC Clock Source
+    {WPCN381U_ACTIVATE_REGISTER, WPCN381U_ACTIVATE_VALUE},                                // Enable it with Activation bit
+    {WPCN381U_LD_SEL_REGISTER, WPCN381U_LDN_PS2M},                                        // Select PS2 Mouse
+    {WPCN381U_IRQ1_REGISTER, 0x01c},                                                      // Set to IRQ12
+    {WPCN381U_ACTIVATE_REGISTER, WPCN381U_ACTIVATE_VALUE}                                 // Enable it with Activation bit
+};
+
+/**
+  Initialization for SIO.
+
+  @param FfsHeader     FV this PEIM was loaded from.
+  @param PeiServices   General purpose services available to every PEIM.
+
+  None
+
+**/
+VOID
+InitializeSio (
+  VOID
+  )
+{
+  UINT16          Index;
+  UINT16          IndexPort;
+  UINT16          DataPort;
+
+  //
+  // Super I/O initialization for Winbond WPCN381U
+  //
+  IndexPort  = WPCN381U_CONFIG_INDEX;
+  DataPort   = WPCN381U_CONFIG_DATA;
+
+  //
+  // Check for Winbond WPCN381U
+  //
+  IoWrite8 (IndexPort, WPCN381U_DEV_ID_REGISTER);   // Winbond WPCN381U Device ID register is 0x20
+
+  if (IoRead8 (DataPort) == WPCN381U_CHIP_ID) {   // Winbond WPCN381U Device ID is 0xF4
+    //
+    // Configure WPCN381U SIO
+    //
+    for (Index = 0; Index < sizeof (mSioTableWpcn381u) / sizeof (EFI_SIO_TABLE); Index++) {
+      IoWrite8 (IndexPort, mSioTableWpcn381u[Index].Register);
+      IoWrite8 (DataPort, mSioTableWpcn381u[Index].Value);
+    }
+  }
+
+  if (IoRead8 (DataPort) == WDCP376_CHIP_ID) {   // Winbond WDCP376 Device ID is 0xF1
+    //
+    // Configure WDCP376 SIO
+    //
+    for (Index = 0; Index < sizeof (mSioTableWdcp376) / sizeof (EFI_SIO_TABLE); Index++) {
+      IoWrite8 (IndexPort, mSioTableWdcp376[Index].Register);
+      IoWrite8 (DataPort, mSioTableWdcp376[Index].Value);
+    }
+  }
+  return;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.h b/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.h
new file mode 100644
index 0000000000..06fa19b93d
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.h
@@ -0,0 +1,62 @@
+/** @file
+  Header file of Serial port hardware definition.
+
+  Copyright (c) 2012  - 2017, Intel Corporation. All rights reserved.<BR>
+                                                                                   
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _SIO_INIT_H_
+#define _SIO_INIT_H_
+
+#define WPCN381U_CONFIG_INDEX               0x2E
+#define WPCN381U_CONFIG_DATA                0x2F
+#define WPCN381U_CONFIG_INDEX1              0x164E
+#define WPCN381U_CONFIG_DATA1               0x164F
+#define WPCN381U_CHIP_ID                    0xF4
+#define WDCP376_CHIP_ID                     0xF1
+
+//
+// SIO Logical Devices Numbers
+//
+#define WPCN381U_LDN_UART0                  0x03   // LDN for Serial Port Controller
+#define WPCN381U_LDN_UART1                  0x02   // LDN for Parallel Port Controller
+#define WPCN381U_LDN_PS2K                   0x06   // LDN for PS2 Keyboard Controller
+#define WPCN381U_LDN_PS2M                   0x05   // LDN for PS2 Mouse Controller
+#define WPCN381U_KB_BASE1_ADDRESS           0x60   // Base Address of KB controller
+#define WPCN381U_KB_BASE2_ADDRESS           0x64   // Base Address of KB controller
+#define SIO_KBC_CLOCK                       0x01   // 0/1/2 - 8/12/16 MHz KBC Clock Source
+#define WPCN381U_LDN_GPIO                   0x07   // LDN for GPIO
+
+//
+// SIO Registers Layout
+//
+#define WPCN381U_LD_SEL_REGISTER            0x07   // Logical Device Select Register Address
+#define WPCN381U_DEV_ID_REGISTER            0x20   // Device Identification Register Address
+#define WPCN381U_ACTIVATE_REGISTER          0x30   // Device Identification Register Address
+#define WPCN381U_BASE1_HI_REGISTER          0x60   // Device BaseAddres Register #1 MSB Address
+#define WPCN381U_BASE1_LO_REGISTER          0x61   // Device BaseAddres Register #1 LSB Address
+#define WPCN381U_BASE2_HI_REGISTER          0x62   // Device BaseAddres Register #1 MSB Address
+#define WPCN381U_BASE2_LO_REGISTER          0x63   // Device Ba1eAddres Register #1 LSB Address
+#define WPCN381U_IRQ1_REGISTER              0x70   // Device IRQ Register #1 Address
+#define WPCN381U_IRQ2_REGISTER              0x71   // Device IRQ Register #2 Address
+
+//
+// SIO Activation Values
+//
+#define WPCN381U_ACTIVATE_VALUE             0x01   // Value to activate Device
+#define WPCN381U_DEACTIVATE_VALUE           0x00   // Value to deactivate Device
+
+//
+// SIO GPIO
+//
+#define WPCN381U_GPIO_BASE_ADDRESS          0x0A20 // SIO GPIO Base Address
+
+//
+// SIO Serial Port Settings
+//
+#define WPCN381U_SERIAL_PORT0_BASE_ADDRESS  0x03F8 // Base Address of Serial Port 0 (COMA / UART0)
+#define WPCN381U_SERIAL_PORT1_BASE_ADDRESS  0x02F8 // Base Address of Serial Port 1 (COMB / UART1)
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/CommonHeader.h b/Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/CommonHeader.h
new file mode 100644
index 0000000000..d34dd942d3
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/CommonHeader.h
@@ -0,0 +1,26 @@
+/**@file
+  Common header file shared by all source files.
+
+  This file includes package header files, library classes.
+
+  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+**/
+
+#ifndef __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+
+#include <Base.h>
+#include <PchAccess.h>
+
+#include <Library/SmbusLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.c
new file mode 100644
index 0000000000..4052724812
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.c
@@ -0,0 +1,873 @@
+/** @file
+  Intel ICH9 SMBUS library implementation built upon I/O library.
+
+  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+**/
+
+#include "CommonHeader.h"
+
+/**
+  Gets Io port base address of Smbus Host Controller.
+
+  This internal function depends on a feature flag named PcdIchSmbusFixedIoPortBaseAddress
+  to retrieve Smbus Io port base. If that feature flag is true, it will get Smbus Io port base
+  address from a preset Pcd entry named PcdIchSmbusIoPortBaseAddress; otherwise, it will always
+  read Pci configuration space to get that value in each Smbus bus transaction.
+
+  @return The Io port base address of Smbus host controller.
+
+**/
+UINTN
+InternalGetSmbusIoPortBaseAddress (
+  VOID
+  )
+{
+  UINTN     IoPortBaseAddress;
+
+  IoPortBaseAddress = (UINTN) MmioRead32 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SMBUS, PCI_FUNCTION_NUMBER_PCH_SMBUS, R_PCH_SMBUS_BASE)) & B_PCH_SMBUS_BASE_BAR;
+
+  //
+  // Make sure that the IO port base address has been properly set.
+  //
+  ASSERT (IoPortBaseAddress != 0);
+
+  return IoPortBaseAddress;
+}
+
+/**
+  Acquires the ownership of SMBUS.
+
+  This internal function reads the host state register.
+  If the SMBUS is not available, RETURN_TIMEOUT is returned;
+  Otherwise, it performs some basic initializations and returns
+  RETURN_SUCCESS.
+
+  @param  IoPortBaseAddress The Io port base address of Smbus Host controller.
+
+  @retval RETURN_SUCCESS    The SMBUS command was executed successfully.
+  @retval RETURN_TIMEOUT    A timeout occurred while executing the SMBUS command.
+
+**/
+RETURN_STATUS
+InternalSmBusAcquire (
+  UINTN                     IoPortBaseAddress
+  )
+{
+  UINT8   HostStatus;
+
+  HostStatus = IoRead8 (IoPortBaseAddress + R_PCH_SMBUS_HSTS);
+  if ((HostStatus & B_PCH_SMBUS_IUS) != 0) {
+    return RETURN_TIMEOUT;
+  } else if ((HostStatus & B_PCH_SMBUS_HBSY) != 0) {
+    //
+    // Clear host status register and exit.
+    //
+    IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
+    return RETURN_TIMEOUT;
+  }
+  //
+  // Clear out any odd status information (Will Not Clear In Use).
+  //
+  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HSTS, HostStatus);
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Starts the SMBUS transaction and waits until the end.
+
+  This internal function start the SMBUS transaction and waits until the transaction
+  of SMBUS is over by polling the INTR bit of Host status register.
+  If the SMBUS is not available, RETURN_TIMEOUT is returned;
+  Otherwise, it performs some basic initializations and returns
+  RETURN_SUCCESS.
+
+  @param  IoPortBaseAddress   The Io port base address of Smbus Host controller.
+  @param  HostControl         The Host control command to start SMBUS transaction.
+
+  @retval RETURN_SUCCESS      The SMBUS command was executed successfully.
+  @retval RETURN_CRC_ERROR    The checksum is not correct (PEC is incorrect).
+  @retval RETURN_DEVICE_ERROR The request was not completed because a failure reflected
+                              in the Host Status Register bit.  Device errors are
+                              a result of a transaction collision, illegal command field,
+                              unclaimed cycle (host initiated), or bus errors (collisions).
+
+**/
+RETURN_STATUS
+InternalSmBusStart (
+  IN  UINTN                   IoPortBaseAddress,
+  IN  UINT8                   HostControl
+  )
+{
+  UINT8   HostStatus;
+  UINT8   AuxiliaryStatus;
+
+  //
+  // Set Host Control Register (Initiate Operation, Interrupt disabled).
+  //
+  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HCTL, (UINT8)(HostControl + B_PCH_SMBUS_START));
+
+  do {
+    //
+    // Poll INTR bit of Host Status Register.
+    //
+    HostStatus = IoRead8 (IoPortBaseAddress + R_PCH_SMBUS_HSTS);
+  } while ((HostStatus & (B_PCH_SMBUS_INTR | B_PCH_SMBUS_ERRORS | B_PCH_SMBUS_BYTE_DONE_STS)) == 0);
+
+  if ((HostStatus & B_PCH_SMBUS_ERRORS) == 0) {
+    return RETURN_SUCCESS;
+  }
+
+  //
+  // Clear error bits of Host Status Register.
+  //
+  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HSTS, B_PCH_SMBUS_ERRORS);
+
+  //
+  // Read Auxiliary Status Register to judge CRC error.
+  //
+  AuxiliaryStatus = IoRead8 (IoPortBaseAddress + R_PCH_SMBUS_AUXS);
+  if ((AuxiliaryStatus & B_PCH_SMBUS_CRCE) != 0) {
+    return RETURN_CRC_ERROR;
+  }
+
+  return RETURN_DEVICE_ERROR;
+}
+
+/**
+  Executes an SMBUS quick, byte or word command.
+
+  This internal function executes an SMBUS quick, byte or word commond.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+
+  @param  HostControl     The value of Host Control Register to set.
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Value           The byte/word write to the SMBUS.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+  @return The byte/word read from the SMBUS.
+
+**/
+UINT16
+InternalSmBusNonBlock (
+  IN  UINT8                     HostControl,
+  IN  UINTN                     SmBusAddress,
+  IN  UINT16                    Value,
+  OUT RETURN_STATUS             *Status
+  )
+{
+  RETURN_STATUS                 ReturnStatus;
+  UINTN                         IoPortBaseAddress;
+  UINT8                         AuxiliaryControl;
+
+  IoPortBaseAddress = InternalGetSmbusIoPortBaseAddress ();
+
+  //
+  // Try to acquire the ownership of ICH SMBUS.
+  //
+  ReturnStatus = InternalSmBusAcquire (IoPortBaseAddress);
+  if (RETURN_ERROR (ReturnStatus)) {
+    goto Done;
+  }
+
+  //
+  // Set the appropriate Host Control Register and auxiliary Control Register.
+  //
+  AuxiliaryControl = 0;
+  if (SMBUS_LIB_PEC (SmBusAddress)) {
+    AuxiliaryControl |= B_PCH_SMBUS_AAC;
+    HostControl      |= B_PCH_SMBUS_PEC_EN;
+  }
+
+  //
+  // Set Host Command Register.
+  //
+  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HCMD, (UINT8) SMBUS_LIB_COMMAND (SmBusAddress));
+
+  //
+  // Write value to Host Data 0 and Host Data 1 Registers.
+  //
+  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HD0, (UINT8) Value);
+  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HD1, (UINT8) (Value >> 8));
+
+  //
+  // Set Auxiliary Control Register.
+  //
+  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_AUXC, AuxiliaryControl);
+
+  //
+  // Set SMBUS slave address for the device to send/receive from.
+  //
+  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_TSA, (UINT8) SmBusAddress);
+
+  //
+  // Start the SMBUS transaction and wait for the end.
+  //
+  ReturnStatus = InternalSmBusStart (IoPortBaseAddress, HostControl);
+
+  //
+  // Read value from Host Data 0 and Host Data 1 Registers.
+  //
+  Value = (UINT16)(IoRead8 (IoPortBaseAddress + R_PCH_SMBUS_HD1) << 8);
+  Value = (UINT16)(Value | IoRead8 (IoPortBaseAddress + R_PCH_SMBUS_HD0));
+
+  //
+  // Clear Host Status Register and Auxiliary Status Register.
+  //
+  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
+  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_AUXS, B_PCH_SMBUS_CRCE);
+
+Done:
+  if (Status != NULL) {
+    *Status = ReturnStatus;
+  }
+
+  return Value;
+}
+
+/**
+  Executes an SMBUS quick read command.
+
+  Executes an SMBUS quick read command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address field of SmBusAddress is required.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If PEC is set in SmBusAddress, then ASSERT().
+  If Command in SmBusAddress is not zero, then ASSERT().
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+**/
+VOID
+EFIAPI
+SmBusQuickRead (
+  IN  UINTN                     SmBusAddress,
+  OUT RETURN_STATUS             *Status       OPTIONAL
+  )
+{
+  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));
+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress)  == 0);
+
+  InternalSmBusNonBlock (
+    V_PCH_SMBUS_SMB_CMD_QUICK,
+    SmBusAddress | B_PCH_SMBUS_RW_SEL_READ,
+    0,
+    Status
+    );
+}
+
+/**
+  Executes an SMBUS quick write command.
+
+  Executes an SMBUS quick write command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address field of SmBusAddress is required.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If PEC is set in SmBusAddress, then ASSERT().
+  If Command in SmBusAddress is not zero, then ASSERT().
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+**/
+VOID
+EFIAPI
+SmBusQuickWrite (
+  IN  UINTN                     SmBusAddress,
+  OUT RETURN_STATUS             *Status       OPTIONAL
+  )
+{
+  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));
+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  InternalSmBusNonBlock (
+    V_PCH_SMBUS_SMB_CMD_QUICK,
+    SmBusAddress | B_PCH_SMBUS_RW_SEL_WRITE,
+    0,
+    Status
+    );
+}
+
+/**
+  Executes an SMBUS receive byte command.
+
+  Executes an SMBUS receive byte command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address field of SmBusAddress is required.
+  The byte received from the SMBUS is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Command in SmBusAddress is not zero, then ASSERT().
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+  @return The byte received from the SMBUS.
+
+**/
+UINT8
+EFIAPI
+SmBusReceiveByte (
+  IN  UINTN          SmBusAddress,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  UINT8 ValueReturn = 0;
+
+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  ValueReturn = (UINT8) InternalSmBusNonBlock (
+                   V_PCH_SMBUS_SMB_CMD_BYTE,
+                   SmBusAddress | B_PCH_SMBUS_RW_SEL_READ,
+                   0,
+                   Status
+                   );
+  return ValueReturn;
+
+  }
+
+/**
+  Executes an SMBUS send byte command.
+
+  Executes an SMBUS send byte command on the SMBUS device specified by SmBusAddress.
+  The byte specified by Value is sent.
+  Only the SMBUS slave address field of SmBusAddress is required.  Value is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Command in SmBusAddress is not zero, then ASSERT().
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Value           The 8-bit value to send.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+  @return The parameter of Value.
+
+**/
+UINT8
+EFIAPI
+SmBusSendByte (
+  IN  UINTN          SmBusAddress,
+  IN  UINT8          Value,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  UINT8 ValueReturn = 0;
+
+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  ValueReturn = (UINT8) InternalSmBusNonBlock (
+                          V_PCH_SMBUS_SMB_CMD_BYTE,
+                          SmBusAddress | B_PCH_SMBUS_RW_SEL_WRITE,
+                          Value,
+                          Status
+                          );
+  return ValueReturn;
+
+  }
+
+/**
+  Executes an SMBUS read data byte command.
+
+  Executes an SMBUS read data byte command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  The 8-bit value read from the SMBUS is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+  @return The byte read from the SMBUS.
+
+**/
+UINT8
+EFIAPI
+SmBusReadDataByte (
+  IN  UINTN          SmBusAddress,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  UINT8 ValueReturn = 0;
+
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+   ValueReturn = (UINT8) InternalSmBusNonBlock (
+                           V_PCH_SMBUS_SMB_CMD_BYTE_DATA,
+                           SmBusAddress | B_PCH_SMBUS_RW_SEL_READ,
+                           0,
+                           Status
+                           );
+  return ValueReturn;
+}
+
+/**
+  Executes an SMBUS write data byte command.
+
+  Executes an SMBUS write data byte command on the SMBUS device specified by SmBusAddress.
+  The 8-bit value specified by Value is written.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  Value is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Value           The 8-bit value to write.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+  @return The parameter of Value.
+
+**/
+UINT8
+EFIAPI
+SmBusWriteDataByte (
+  IN  UINTN          SmBusAddress,
+  IN  UINT8          Value,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  UINT8 ValueReturn = 0;
+
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  ValueReturn = (UINT8) InternalSmBusNonBlock (
+                          V_PCH_SMBUS_SMB_CMD_BYTE_DATA,
+                          SmBusAddress | B_PCH_SMBUS_RW_SEL_WRITE,
+                          Value,
+                          Status
+                          );
+  return ValueReturn;
+
+}
+
+/**
+  Executes an SMBUS read data word command.
+
+  Executes an SMBUS read data word command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  The 16-bit value read from the SMBUS is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+  @return The byte read from the SMBUS.
+
+**/
+UINT16
+EFIAPI
+SmBusReadDataWord (
+  IN  UINTN          SmBusAddress,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  UINT16 ValueReturn = 0;
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  ValueReturn = InternalSmBusNonBlock (
+                  V_PCH_SMBUS_SMB_CMD_WORD_DATA,
+                  SmBusAddress | B_PCH_SMBUS_RW_SEL_READ,
+                  0,
+                  Status
+                  );
+  return ValueReturn;
+
+}
+
+/**
+  Executes an SMBUS write data word command.
+
+  Executes an SMBUS write data word command on the SMBUS device specified by SmBusAddress.
+  The 16-bit value specified by Value is written.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  Value is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Value           The 16-bit value to write.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+  @return The parameter of Value.
+
+**/
+UINT16
+EFIAPI
+SmBusWriteDataWord (
+  IN  UINTN          SmBusAddress,
+  IN  UINT16         Value,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  UINT16 ValueReturn = 0;
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  ValueReturn = InternalSmBusNonBlock (
+                  V_PCH_SMBUS_SMB_CMD_WORD_DATA,
+                  SmBusAddress | B_PCH_SMBUS_RW_SEL_WRITE,
+                  Value,
+                  Status
+                  );
+  return ValueReturn;
+}
+
+/**
+  Executes an SMBUS process call command.
+
+  Executes an SMBUS process call command on the SMBUS device specified by SmBusAddress.
+  The 16-bit value specified by Value is written.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  The 16-bit value returned by the process call command is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Value           The 16-bit value to write.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+  @return The 16-bit value returned by the process call command.
+
+**/
+UINT16
+EFIAPI
+SmBusProcessCall (
+  IN  UINTN          SmBusAddress,
+  IN  UINT16         Value,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  UINT16 ValueReturn = 0;
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  ValueReturn = InternalSmBusNonBlock (
+                  V_PCH_SMBUS_SMB_CMD_PROCESS_CALL,
+                  SmBusAddress | B_PCH_SMBUS_RW_SEL_WRITE,
+                  Value,
+                  Status
+                  );
+  return ValueReturn;
+}
+
+/**
+  Executes an SMBUS block command.
+
+  Executes an SMBUS block read, block write and block write-block read command
+  on the SMBUS device specified by SmBusAddress.
+  Bytes are read from the SMBUS and stored in Buffer.
+  The number of bytes read is returned, and will never return a value larger than 32-bytes.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.
+
+  @param  HostControl     The value of Host Control Register to set.
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  WriteBuffer     Pointer to the buffer of bytes to write to the SMBUS.
+  @param  ReadBuffer      Pointer to the buffer of bytes to read from the SMBUS.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+  @return The number of bytes read from the SMBUS.
+
+**/
+UINTN
+InternalSmBusBlock (
+  IN  UINT8                     HostControl,
+  IN  UINTN                     SmBusAddress,
+  IN  UINT8                     *WriteBuffer,
+  OUT UINT8                     *ReadBuffer,
+  OUT RETURN_STATUS             *Status
+  )
+{
+  RETURN_STATUS                 ReturnStatus;
+  UINTN                         Index;
+  UINTN                         BytesCount;
+  UINTN                         IoPortBaseAddress;
+  UINT8                         AuxiliaryControl;
+
+  IoPortBaseAddress = InternalGetSmbusIoPortBaseAddress ();
+
+  BytesCount = SMBUS_LIB_LENGTH (SmBusAddress);
+
+  //
+  // Try to acquire the ownership of ICH SMBUS.
+  //
+  ReturnStatus = InternalSmBusAcquire (IoPortBaseAddress);
+  if (RETURN_ERROR (ReturnStatus)) {
+    goto Done;
+  }
+
+  //
+  // Set the appropriate Host Control Register and auxiliary Control Register.
+  //
+  AuxiliaryControl = B_PCH_SMBUS_E32B;
+  if (SMBUS_LIB_PEC (SmBusAddress)) {
+    AuxiliaryControl |= B_PCH_SMBUS_AAC;
+    HostControl      |= B_PCH_SMBUS_PEC_EN;
+  }
+
+  //
+  // Set Host Command Register.
+  //
+  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HCMD, (UINT8) SMBUS_LIB_COMMAND (SmBusAddress));
+
+  //
+  // Set Auxiliary Control Regiester.
+  //
+  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_AUXC, AuxiliaryControl);
+
+  //
+  // Clear byte pointer of 32-byte buffer.
+  //
+  IoRead8 (IoPortBaseAddress + R_PCH_SMBUS_HCTL);
+
+  if (WriteBuffer != NULL) {
+    //
+    // Write the number of block to Host Block Data Byte Register.
+    //
+    IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HD0, (UINT8) BytesCount);
+
+    //
+    // Write data block to Host Block Data Register.
+    //
+    for (Index = 0; Index < BytesCount; Index++) {
+      IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HBD, WriteBuffer[Index]);
+    }
+  }
+
+  //
+  // Set SMBUS slave address for the device to send/receive from.
+  //
+  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_TSA, (UINT8) SmBusAddress);
+
+  //
+  // Start the SMBUS transaction and wait for the end.
+  //
+  ReturnStatus = InternalSmBusStart (IoPortBaseAddress, HostControl);
+  if (RETURN_ERROR (ReturnStatus)) {
+    goto Done;
+  }
+
+  if (ReadBuffer != NULL) {
+    //
+    // Read the number of block from host block data byte register.
+    //
+    BytesCount = IoRead8 (IoPortBaseAddress + R_PCH_SMBUS_HD0);
+
+    //
+    // Write data block from Host Block Data Register.
+    //
+    for (Index = 0; Index < BytesCount; Index++) {
+      ReadBuffer[Index] = IoRead8 (IoPortBaseAddress + R_PCH_SMBUS_HBD);
+    }
+  }
+
+Done:
+  //
+  // Clear Host Status Register and Auxiliary Status Register.
+  //
+  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
+  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_AUXS, B_PCH_SMBUS_CRCE);
+
+  if (Status != NULL) {
+    *Status = ReturnStatus;
+  }
+
+  return BytesCount;
+}
+
+/**
+  Executes an SMBUS read block command.
+
+  Executes an SMBUS read block command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  Bytes are read from the SMBUS and stored in Buffer.
+  The number of bytes read is returned, and will never return a value larger than 32-bytes.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If Buffer is NULL, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Buffer          Pointer to the buffer to store the bytes read from the SMBUS.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+  @return The number of bytes read.
+
+**/
+UINTN
+EFIAPI
+SmBusReadBlock (
+  IN  UINTN          SmBusAddress,
+  OUT VOID           *Buffer,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  UINTN BytesCount = 0;
+
+  ASSERT (Buffer != NULL);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+
+  BytesCount = InternalSmBusBlock (
+                 V_PCH_SMBUS_SMB_CMD_BLOCK,
+                 SmBusAddress | B_PCH_SMBUS_RW_SEL_READ,
+                 NULL,
+                 Buffer,
+                 Status
+                 );
+  return BytesCount;
+
+}
+
+/**
+  Executes an SMBUS write block command.
+
+  Executes an SMBUS write block command on the SMBUS device specified by SmBusAddress.
+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.
+  Bytes are written to the SMBUS from Buffer.
+  The number of bytes written is returned, and will never return a value larger than 32-bytes.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is zero or greater than 32, then ASSERT().
+  If Buffer is NULL, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  Buffer          Pointer to the buffer to store the bytes read from the SMBUS.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+  @return The number of bytes written.
+
+**/
+UINTN
+EFIAPI
+SmBusWriteBlock (
+  IN  UINTN          SmBusAddress,
+  OUT VOID           *Buffer,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  UINTN	BytesCount = 0;
+
+  ASSERT (Buffer != NULL);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+
+ BytesCount = InternalSmBusBlock (
+
+                V_PCH_SMBUS_SMB_CMD_BLOCK,
+                SmBusAddress | B_PCH_SMBUS_RW_SEL_WRITE,
+                Buffer,
+                NULL,
+                Status
+                );
+
+  return BytesCount;
+}
+
+/**
+  Executes an SMBUS block process call command.
+
+  Executes an SMBUS block process call command on the SMBUS device specified by SmBusAddress.
+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.
+  Bytes are written to the SMBUS from WriteBuffer.  Bytes are then read from the SMBUS into ReadBuffer.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  It is the caller's responsibility to make sure ReadBuffer is large enough for the total number of bytes read.
+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.
+  If Length in SmBusAddress is zero or greater than 32, then ASSERT().
+  If WriteBuffer is NULL, then ASSERT().
+  If ReadBuffer is NULL, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                          SMBUS Command, SMBUS Data Length, and PEC.
+  @param  WriteBuffer     Pointer to the buffer of bytes to write to the SMBUS.
+  @param  ReadBuffer      Pointer to the buffer of bytes to read from the SMBUS.
+  @param  Status          Return status for the executed command.
+                          This is an optional parameter and may be NULL.
+
+  @return The number of bytes written.
+
+**/
+UINTN
+EFIAPI
+SmBusBlockProcessCall (
+  IN  UINTN          SmBusAddress,
+  IN  VOID           *WriteBuffer,
+  OUT VOID           *ReadBuffer,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  UINTN BytesCount = 0;
+
+  ASSERT (WriteBuffer != NULL);
+  ASSERT (ReadBuffer  != NULL);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  BytesCount = InternalSmBusBlock (
+                 V_PCH_SMBUS_SMB_CMD_BLOCK_PROCESS,
+                 SmBusAddress | B_PCH_SMBUS_RW_SEL_WRITE,
+                 WriteBuffer,
+                 ReadBuffer,
+                 Status
+                 );
+  return BytesCount;
+
+  }
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.inf b/Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.inf
new file mode 100644
index 0000000000..b13e3de0cc
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.inf
@@ -0,0 +1,46 @@
+## @file
+# Component description file for Intel Ich9 Smbus Library.
+#
+# SMBUS Library that layers on top of the I/O Library to directly
+#  access a standard SMBUS host controller.
+# Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+#                                                                                  

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

+#
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SmbusLib
+  FILE_GUID                      = 0558CAEA-FEF3-4b6d-915E-8742EFE6DEE1
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SmbusLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  SmbusLib.c
+
+[Packages]
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+  MdePkg/MdePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  DebugLib
+  PciLib
+  IoLib
+
+[Pcd.common]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmm.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmm.c
new file mode 100644
index 0000000000..062994f088
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmm.c
@@ -0,0 +1,89 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+                                                                                   

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

+
+
+Module Name:
+
+  SmmIo.c
+
+Abstract:
+
+  SMM I/O access utility implementation file, for Ia32
+
+--*/
+
+//
+// Include files
+//
+#include "Library/StallSmmLib.h"
+#include "Pi/PiSmmCis.h"
+#include "PiDxe.h"
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include "PchAccess.h"
+
+/**
+  Delay for at least the request number of microseconds.
+  Timer used is ACPI time counter, which has 1us granularity.
+
+  @param Microseconds  Number of microseconds to delay.
+
+  @retval None
+
+**/
+VOID
+SmmStall (
+  IN  UINTN   Microseconds
+  )
+{
+  UINTN   Ticks;
+  UINTN   Counts;
+  UINTN   CurrentTick;
+  UINTN   OriginalTick;
+  UINTN   RemainingTick;
+  UINT16  AcpiBaseAddr;
+
+  if (Microseconds == 0) {
+    return;
+  }
+
+  AcpiBaseAddr = PchLpcPciCfg16 (R_PCH_LPC_ACPI_BASE) & B_PCH_LPC_ACPI_BASE_BAR;
+
+  OriginalTick = IoRead32 (AcpiBaseAddr + R_PCH_ACPI_PM1_TMR);
+  CurrentTick = OriginalTick;
+
+  //
+  // The timer frequency is 3.579545 MHz, so 1 ms corresponds 3.58 clocks
+  //
+  Ticks = Microseconds * 358 / 100 + OriginalTick + 1;
+
+  //
+  // The loops needed by timer overflow
+  //
+  Counts = Ticks / V_PCH_ACPI_PM1_TMR_MAX_VAL;
+
+  //
+  // Remaining clocks within one loop
+  //
+  RemainingTick = Ticks % V_PCH_ACPI_PM1_TMR_MAX_VAL;
+
+  //
+  // not intend to use TMROF_STS bit of register PM1_STS, because this adds extra
+  // one I/O operation, and maybe generate SMI
+  //
+  while ((Counts != 0) || (RemainingTick > CurrentTick)) {
+    CurrentTick = IoRead32 (AcpiBaseAddr + R_PCH_ACPI_PM1_TMR);
+    //
+    // Check if timer overflow
+    //
+    if (CurrentTick < OriginalTick) {
+      Counts--;
+    }
+    OriginalTick = CurrentTick;
+  }
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmmLib.inf b/Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmmLib.inf
new file mode 100644
index 0000000000..703ea3238c
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmmLib.inf
@@ -0,0 +1,51 @@
+#/*++
+#
+# Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
+#                                                                                  

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

+
+#
+#  Module Name:
+#
+#   SmmStallLib.inf
+#
+#  Abstract:
+#
+#    Component description file for SmmStall library
+#
+#--*/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = StallSmmLib
+  FILE_GUID                      = A6A16CCB-91B0-42f4-B4F3-D16D7A8662E6
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = StallSmmLib
+
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+ StallSmm.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+
+[LibraryClasses]
+  PcdLib
+  PciLib
+  IoLib
+  BaseLib
+
+[Pcd.common]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.c
new file mode 100644
index 0000000000..ad3d201e07
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.c
@@ -0,0 +1,117 @@
+/*++
+
+Copyright (c)  1999  - 2015, Intel Corporation. All rights reserved
+                                                                                   
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+                                                                                   
+--*/
+
+#include <Uefi.h>
+#include <Protocol/PttPassThru.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+//#include <Library/Tpm2DeviceLib.h>
+
+
+PTT_PASS_THRU_PROTOCOL *mPttPassThruProtocol;
+
+
+/**
+  The constructor function caches the pointer to PEI services.
+
+  The constructor function caches the pointer to PEI services.
+  It will always return EFI_SUCCESS.
+
+  @param  FfsHeader   Pointer to FFS header the loaded driver.
+  @param  PeiServices Pointer to the PEI services.
+
+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
+
+**/
+
+EFI_STATUS
+EFIAPI
+Tpm2DeviceLibConstructor (
+  VOID
+  )
+{
+  EFI_STATUS Status = EFI_SUCCESS;
+  
+  Status = gBS->LocateProtocol (&gPttPassThruProtocolGuid, NULL, (VOID **) &mPttPassThruProtocol);
+  
+  return Status;
+}
+
+/**
+  This service enables the sending of commands to the TPM2.
+
+  @param[in]  InputParameterBlockSize  Size of the TPM2 input parameter block.
+  @param[in]  InputParameterBlock      Pointer to the TPM2 input parameter block.
+  @param[in]  OutputParameterBlockSize Size of the TPM2 output parameter block.
+  @param[in]  OutputParameterBlock     Pointer to the TPM2 output parameter block.
+
+  @retval EFI_SUCCESS            The command byte stream was successfully sent to the device and a response was successfully received.
+  @retval EFI_DEVICE_ERROR       The command was not successfully sent to the device or a response was not successfully received from the device.
+  @retval EFI_BUFFER_TOO_SMALL   The output parameter block is too small.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2SubmitCommand (
+  IN UINT32            InputParameterBlockSize,
+  IN UINT8             *InputParameterBlock,
+  IN OUT UINT32        *OutputParameterBlockSize,
+  IN UINT8             *OutputParameterBlock
+  )
+{
+  EFI_STATUS Status;
+  
+  Status = mPttPassThruProtocol->Tpm2SubmitCommand (
+             mPttPassThruProtocol,
+             InputParameterBlockSize,
+             InputParameterBlock,
+             OutputParameterBlockSize,
+             OutputParameterBlock
+           );
+
+  return Status;
+}
+
+/**
+  This service requests use TPM2.
+
+  @retval EFI_SUCCESS      Get the control of TPM2 chip.
+  @retval EFI_NOT_FOUND    TPM2 not found.
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2RequestUseTpm (
+  VOID
+  )
+{
+  EFI_STATUS Status;
+  
+  Status = mPttPassThruProtocol->Tpm2RequestUseTpm (mPttPassThruProtocol);
+           
+  return Status;
+}
+
+/**
+  This service register TPM2 device.
+
+  @Param Tpm2Device  TPM2 device
+
+  @retval EFI_SUCCESS          This TPM2 device is registered successfully.
+  @retval EFI_UNSUPPORTED      System does not support register this TPM2 device.
+  @retval EFI_ALREADY_STARTED  System already register this TPM2 device.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2RegisterTpm2DeviceLib (
+  IN PTT_TPM2_DEVICE_INTERFACE   *Tpm2Device
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.inf b/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.inf
new file mode 100644
index 0000000000..9ee91527c1
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.inf
@@ -0,0 +1,61 @@
+#/** @file
+# 
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+#                                                                                  
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#                                                                                 
+#
+#
+#
+#**/
+
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = Tpm2DeviceLibSeC
+  FILE_GUID                      = 294B196A-A3CC-4a43-857F-EEC26147857B
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = Tpm2DeviceLib | DXE_DRIVER DXE_SMM_DRIVER
+  CONSTRUCTOR                    = Tpm2DeviceLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources.common]
+  Tpm2DeviceLibSeC.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  PcdLib
+  UefiBootServicesTableLib
+
+  
+[Guids]
+  gEfiVLVTokenSpaceGuid
+  
+[Pcd]
+  gEfiVLVTokenSpaceGuid.PcdMeasuredBootEnable
+  gEfiVLVTokenSpaceGuid.PcdFTPMErrorOccur
+  gEfiVLVTokenSpaceGuid.PcdFTPMCommand
+  gEfiVLVTokenSpaceGuid.PcdFTPMResponse
+  gEfiVLVTokenSpaceGuid.PcdFTPMNotRespond
+  gEfiVLVTokenSpaceGuid.PcdFTPMStatus
+  
+[Protocols]
+  gPttPassThruProtocolGuid
+    
+[Depex]
+  gPttPassThruProtocolGuid
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.c b/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.c
new file mode 100644
index 0000000000..12717a5f69
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.c
@@ -0,0 +1,145 @@
+/*++
+
+Copyright (c)  1999  - 2015, Intel Corporation. All rights reserved
+                                                                                   
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+                                                                                   
+
+--*/
+
+#include <Uefi.h>
+#include <PiPei.h>
+#include <Ppi/PttPassThruPpi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+
+
+
+
+
+
+PTT_PASS_THRU_PPI  *SecPttPassThruPpi = NULL;
+
+/**
+  The constructor function caches the pointer to PEI services.
+
+  The constructor function caches the pointer to PEI services.
+  It will always return EFI_SUCCESS.
+
+  @param  FfsHeader   Pointer to FFS header the loaded driver.
+  @param  PeiServices Pointer to the PEI services.
+
+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+Tpm2DeviceLibConstructor (
+  VOID
+  )
+{
+  EFI_STATUS  Status = EFI_SUCCESS;
+  
+  Status = PeiServicesLocatePpi (&gPttPassThruPpiGuid, 0, NULL, (VOID **) &SecPttPassThruPpi);
+  if (EFI_ERROR (Status)) {
+     // Locate the PPI failed
+     SecPttPassThruPpi = NULL;
+  }
+  return Status;
+}
+
+/**
+  This service enables the sending of commands to the TPM2.
+
+  @param[in]  InputParameterBlockSize  Size of the TPM2 input parameter block.
+  @param[in]  InputParameterBlock      Pointer to the TPM2 input parameter block.
+  @param[in]  OutputParameterBlockSize Size of the TPM2 output parameter block.
+  @param[in]  OutputParameterBlock     Pointer to the TPM2 output parameter block.
+
+  @retval EFI_SUCCESS            The command byte stream was successfully sent to the device and a response was successfully received.
+  @retval EFI_DEVICE_ERROR       The command was not successfully sent to the device or a response was not successfully received from the device.
+  @retval EFI_BUFFER_TOO_SMALL   The output parameter block is too small.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2SubmitCommand (
+  IN UINT32            InputParameterBlockSize,
+  IN UINT8             *InputParameterBlock,
+  IN OUT UINT32        *OutputParameterBlockSize,
+  IN UINT8             *OutputParameterBlock
+  )
+{
+  EFI_STATUS  Status = EFI_SUCCESS;
+
+  if(NULL == InputParameterBlock || NULL == OutputParameterBlock || 0 == InputParameterBlockSize) {
+    DEBUG ((EFI_D_ERROR, "Buffer == NULL or InputParameterBlockSize == 0\n"));
+    Status = EFI_INVALID_PARAMETER;
+    return Status;
+  }
+
+  if (NULL == SecPttPassThruPpi) {
+    // Don't locate PPI by calling Tpm2DeviceLibConstructor() function??
+    Status = EFI_DEVICE_ERROR;
+    return Status;
+  }
+
+  Status = SecPttPassThruPpi->Tpm2SubmitCommand (
+             SecPttPassThruPpi, 
+             InputParameterBlockSize, 
+             InputParameterBlock, 
+             OutputParameterBlockSize, 
+             OutputParameterBlock
+           );
+  
+  return Status;
+}
+
+/**
+  This service requests use TPM2.
+
+  @retval EFI_SUCCESS      Get the control of TPM2 chip.
+  @retval EFI_NOT_FOUND    TPM2 not found.
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2RequestUseTpm (
+  VOID
+  )
+{
+  EFI_STATUS  Status = EFI_SUCCESS;
+
+  if (NULL == SecPttPassThruPpi) {
+    // Don't locate PPI by calling Tpm2DeviceLibConstructor() function??
+    Status = EFI_DEVICE_ERROR;
+    return Status;
+  }
+
+  Status = SecPttPassThruPpi->Tpm2RequestUseTpm (SecPttPassThruPpi);
+  
+  return Status;
+}
+
+/**
+  This service register TPM2 device.
+
+  @Param Tpm2Device  TPM2 device
+
+  @retval EFI_SUCCESS          This TPM2 device is registered successfully.
+  @retval EFI_UNSUPPORTED      System does not support register this TPM2 device.
+  @retval EFI_ALREADY_STARTED  System already register this TPM2 device.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2RegisterTpm2DeviceLib (
+  IN PTT_TPM2_DEVICE_INTERFACE   *Tpm2Device
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.inf b/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.inf
new file mode 100644
index 0000000000..a9b2948597
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.inf
@@ -0,0 +1,60 @@
+#/** @file
+# 
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+#                                                                                  
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#                                                                                 
+#
+#
+#
+#**/
+
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = Tpm2DeviceLibSeC
+  FILE_GUID                      = 1EEA2BFE-01CB-40cc-A34E-CB224C800AA2
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = Tpm2DeviceLib | PEI_DRIVER PEIM
+  CONSTRUCTOR                    = Tpm2DeviceLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources.common]
+  Tpm2DeviceLibSeC.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  DebugLib
+  IoLib
+  PciLib
+  TimerLib
+  PcdLib
+  PeiServicesLib
+  PeimEntryPoint
+
+  
+[Guids]
+
+[Ppis]
+  gPttPassThruPpiGuid
+  
+[Depex]
+  gPttPassThruPpiGuid
+  
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Logo/Logo.bmp b/Platform/Intel/Vlv2TbltDevicePkg/Logo/Logo.bmp
new file mode 100644
index 0000000000000000000000000000000000000000..26ac1a81dad1de6c6f94c27b91d448300a339059
GIT binary patch
literal 94434
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

literal 0
HcmV?d00001

diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.c b/Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.c
new file mode 100644
index 0000000000..b1fb4adb34
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.c
@@ -0,0 +1,185 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+  LegacyMetronome.c
+
+Abstract:
+
+  This contains the installation function for the driver.
+
+--*/
+
+#include "LegacyMetronome.h"
+
+//
+// Handle for the Metronome Architectural Protocol instance produced by this driver
+//
+EFI_HANDLE                  mMetronomeHandle = NULL;
+
+//
+// The Metronome Architectural Protocol instance produced by this driver
+//
+EFI_METRONOME_ARCH_PROTOCOL mMetronome = {
+  WaitForTick,
+  TICK_PERIOD
+};
+
+//
+// The CPU I/O Protocol used to access system hardware
+//
+EFI_CPU_IO_PROTOCOL         *mCpuIo = NULL;
+
+//
+// Worker Functions
+//
+
+/**
+  Write an 8 bit value to an I/O port and save it to the S3 script
+
+  @param Port  IO Port
+  @param Data  Data in IO Port
+
+  @retval None.
+
+**/
+VOID
+ScriptWriteIo8 (
+  UINT16  Port,
+  UINT8   Data
+  )
+{
+  mCpuIo->Io.Write (
+               mCpuIo,
+               EfiCpuIoWidthUint8,
+               Port,
+               1,
+               &Data
+               );
+
+}
+
+/**
+
+  Read the refresh bit from the REFRESH_PORT
+
+  @param None.
+
+  @retval Refresh bit.
+
+**/
+UINT8
+ReadRefresh (
+  VOID
+  )
+{
+  UINT8 Data;
+
+  mCpuIo->Io.Read (
+               mCpuIo,
+               EfiCpuIoWidthUint8,
+               REFRESH_PORT,
+               1,
+               &Data
+               );
+  return (UINT8) (Data & REFRESH_ON);
+}
+
+/**
+
+  Waits for the TickNumber of ticks from a known platform time source.
+
+  @param This                Pointer to the protocol instance.
+  @param TickNumber          Tick Number to be waited
+
+
+  @retval EFI_SUCCESS         If number of ticks occurred.
+  @retval EFI_NOT_FOUND       Could not locate CPU IO protocol
+
+**/
+EFI_STATUS
+EFIAPI
+WaitForTick (
+  IN EFI_METRONOME_ARCH_PROTOCOL  *This,
+  IN UINT32                       TickNumber
+  )
+{
+  //
+  // Wait for TickNumber toggles of the Refresh bit
+  //
+  for (; TickNumber != 0x00; TickNumber--) {
+    while (ReadRefresh () == REFRESH_ON)
+      ;
+    while (ReadRefresh () == REFRESH_OFF)
+      ;
+  }
+
+  return EFI_SUCCESS;
+}
+
+//
+// Driver Entry Point
+//
+/**
+  Install the LegacyMetronome driver.  Loads a Metronome Arch Protocol based
+  on the Port 61 timer.
+
+  @param ImageHandle      Handle for the image of this driver
+  @param SystemTable      Pointer to the EFI System Table
+
+  @retval EFI_SUCCESS     Metronome Architectural Protocol Installed
+
+**/
+EFI_STATUS
+EFIAPI
+InstallLegacyMetronome (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // Make sure the Metronome Architectural Protocol is not already installed in the system
+  //
+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiMetronomeArchProtocolGuid);
+
+  //
+  // Get the CPU I/O Protocol that this driver requires
+  // If the CPU I/O Protocol is not found, then ASSERT because the dependency expression
+  // should guarantee that it is present in the handle database.
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiCpuIoProtocolGuid,
+                  NULL,
+                  (void **)&mCpuIo
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Program port 61 timer 1 as refresh timer. We could use ACPI timer in the
+  // future.
+  //
+  ScriptWriteIo8 (TIMER1_CONTROL_PORT, LOAD_COUNTER1_LSB);
+  ScriptWriteIo8 (TIMER1_COUNT_PORT, COUNTER1_COUNT);
+
+  //
+  // Install on a new handle
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mMetronomeHandle,
+                  &gEfiMetronomeArchProtocolGuid,
+                  &mMetronome,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.h b/Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.h
new file mode 100644
index 0000000000..9599eca702
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.h
@@ -0,0 +1,64 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  LegacyMetronome.h
+
+Abstract:
+
+  Driver implementing the EFI 2.0 metronome protocol using the legacy PORT 61
+  timer.
+
+--*/
+
+#ifndef _LEGACY_METRONOME_H
+#define _LEGACY_METRONOME_H
+
+//
+// Statements that include other files
+//
+#include "Protocol/Metronome.h"
+#include "Protocol/CpuIo.h"
+#include "Library/DebugLib.h"
+#include "Library/UefiBootServicesTableLib.h"
+
+
+//
+// Private definitions
+//
+#define TICK_PERIOD         300
+#define REFRESH_PORT        0x61
+#define REFRESH_ON          0x10
+#define REFRESH_OFF         0x00
+#define TIMER1_CONTROL_PORT 0x43
+#define TIMER1_COUNT_PORT   0x41
+#define LOAD_COUNTER1_LSB   0x54
+#define COUNTER1_COUNT      0x12
+
+//
+// Function Prototypes
+//
+/**
+  Waits for the TickNumber of ticks from a known platform time source.
+
+  @param This                 Pointer to the protocol instance.
+  @param TickNumber           Tick Number to be waited
+
+  @retval EFI_SUCCESS         If number of ticks occurred.
+  @retval EFI_NOT_FOUND       Could not locate CPU IO protocol
+
+**/
+EFI_STATUS
+EFIAPI
+WaitForTick (
+  IN EFI_METRONOME_ARCH_PROTOCOL  *This,
+  IN UINT32                       TickNumber
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Metronome/Metronome.inf b/Platform/Intel/Vlv2TbltDevicePkg/Metronome/Metronome.inf
new file mode 100644
index 0000000000..173370d652
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Metronome/Metronome.inf
@@ -0,0 +1,49 @@
+#
+#
+# Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+#                                                                                  

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

+#
+
+#  Module Name:
+#
+#    LegacyMetronome.inf
+#
+#  Abstract:
+#
+#    Component description file for LegacyMetronome module
+#
+#--*/
+[defines]
+  INF_VERSION	       = 0x00010005
+  BASE_NAME            = LegacyMetronome
+  FILE_GUID            = 07A9330A-F347-11d4-9A49-0090273FC14D
+  MODULE_TYPE          = DXE_DRIVER
+  VERSION_STRING       = 1.0
+  ENTRY_POINT	       = InstallLegacyMetronome
+
+[sources.common]
+  LegacyMetronome.c
+  LegacyMetronome.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  DevicePathLib
+  UefiLib
+
+[Protocols]
+
+gEfiMetronomeArchProtocolGuid
+gEfiCpuIoProtocolGuid
+
+[Depex]
+gEfiCpuIoProtocolGuid  AND  gEfiBootScriptSaveProtocolGuid
+
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/EfiStatusCode.h b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/EfiStatusCode.h
new file mode 100644
index 0000000000..1d396ffde2
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/EfiStatusCode.h
@@ -0,0 +1,178 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  EfiStatusCode.h
+
+Abstract:
+
+  Status Code Definitions, according to Intel Platform Innovation Framework
+  for EFI Status Codes Specification
+  Revision 0.92
+
+  The file is divided into sections for ease of use.
+
+  Section:    Contents:
+    1           General Status Code Definitions
+    2           Class definitions
+    3           Computing Unit Subclasses, Progress and Error Codes
+    4           Peripheral Subclasses, Progress and Error Codes.
+    5           IO Bus Subclasses, Progress and Error Codes.
+    6           Software Subclasses, Progress and Error Codes.
+    7           Debug Codes
+
+--*/
+
+#ifndef _EFI_STATUS_CODE_H_
+#define _EFI_STATUS_CODE_H_
+
+
+
+#define EFI_SW_PEIM_EC_NO_RECOVERY_CAPSULE        (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_SW_PEIM_EC_INVALID_CAPSULE_DESCRIPTOR (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+
+
+
+#define EFI_SW_PEIM_PC_RECOVERY_BEGIN (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_SW_PEIM_PC_CAPSULE_LOAD   (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_SW_PEIM_PC_CAPSULE_START  (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+#define EFI_SW_PEIM_PC_RECOVERY_USER  (EFI_SUBCLASS_SPECIFIC | 0x00000003)
+#define EFI_SW_PEIM_PC_RECOVERY_AUTO  (EFI_SUBCLASS_SPECIFIC | 0x00000004)
+
+
+
+#define EFI_CU_MEMORY_PC_SPD_READ         (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_CU_MEMORY_PC_PRESENCE_DETECT  (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_CU_MEMORY_PC_TIMING           (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+#define EFI_CU_MEMORY_PC_CONFIGURING      (EFI_SUBCLASS_SPECIFIC | 0x00000003)
+#define EFI_CU_MEMORY_PC_OPTIMIZING       (EFI_SUBCLASS_SPECIFIC | 0x00000004)
+#define EFI_CU_MEMORY_PC_INIT             (EFI_SUBCLASS_SPECIFIC | 0x00000005)
+#define EFI_CU_MEMORY_PC_TEST             (EFI_SUBCLASS_SPECIFIC | 0x00000006)
+#define EFI_CU_MEMORY_PC_COMPLETE         (EFI_SUBCLASS_SPECIFIC | 0x00000007)
+#define EFI_CU_MEMORY_PC_INIT_BEGIN       (EFI_SUBCLASS_SPECIFIC | 0x00000008)
+
+
+#define EFI_DC_UNSPECIFIED  0x0
+
+//
+// CPU PEI
+//
+#define EFI_CU_HP_PC_PEI_INIT                     (EFI_SUBCLASS_SPECIFIC | 0x00000010)
+#define EFI_CU_HP_PC_PEI_STEP1                    (EFI_SUBCLASS_SPECIFIC | 0x00000011)
+#define EFI_CU_HP_PC_PEI_STEP2                    (EFI_SUBCLASS_SPECIFIC | 0x00000012)
+#define EFI_CU_HP_PC_PEI_STEP3                    (EFI_SUBCLASS_SPECIFIC | 0x00000013)
+#define EFI_CU_HP_PC_PEI_STEP4                    (EFI_SUBCLASS_SPECIFIC | 0x00000014)
+#define EFI_CU_HP_PC_PEI_STEP5                    (EFI_SUBCLASS_SPECIFIC | 0x00000015)
+#define EFI_CU_HP_PC_PEI_STEP6                    (EFI_SUBCLASS_SPECIFIC | 0x00000016)
+#define EFI_CU_HP_PC_PEI_STEP7                    (EFI_SUBCLASS_SPECIFIC | 0x00000017)
+#define EFI_CU_HP_PC_PEI_STEP8                    (EFI_SUBCLASS_SPECIFIC | 0x00000018)
+#define EFI_CU_HP_PC_PEI_STEP9                    (EFI_SUBCLASS_SPECIFIC | 0x00000019)
+#define EFI_CU_HP_PC_PEI_STEP10                   (EFI_SUBCLASS_SPECIFIC | 0x0000001A)
+#define EFI_CU_HP_PC_PEI_STEP11                   (EFI_SUBCLASS_SPECIFIC | 0x0000001B)
+#define EFI_CU_HP_PC_PEI_STEP12                   (EFI_SUBCLASS_SPECIFIC | 0x0000001C)
+#define EFI_CU_HP_PC_PEI_STEP13                   (EFI_SUBCLASS_SPECIFIC | 0x0000001D)
+#define EFI_CU_HP_PC_PEI_STEP14                   (EFI_SUBCLASS_SPECIFIC | 0x0000001E)
+#define EFI_CU_HP_PC_PEI_END                      (EFI_SUBCLASS_SPECIFIC | 0x0000001F)
+
+//
+// CPU DXE
+//
+#define EFI_CU_HP_PC_DXE_INIT                     (EFI_SUBCLASS_SPECIFIC | 0x00000020)
+#define EFI_CU_HP_PC_DXE_STEP1                    (EFI_SUBCLASS_SPECIFIC | 0x00000021)
+#define EFI_CU_HP_PC_DXE_STEP2                    (EFI_SUBCLASS_SPECIFIC | 0x00000022)
+#define EFI_CU_HP_PC_DXE_STEP3                    (EFI_SUBCLASS_SPECIFIC | 0x00000023)
+#define EFI_CU_HP_PC_DXE_STEP4                    (EFI_SUBCLASS_SPECIFIC | 0x00000024)
+#define EFI_CU_HP_PC_DXE_STEP5                    (EFI_SUBCLASS_SPECIFIC | 0x00000025)
+#define EFI_CU_HP_PC_DXE_STEP6                    (EFI_SUBCLASS_SPECIFIC | 0x00000026)
+#define EFI_CU_HP_PC_DXE_STEP7                    (EFI_SUBCLASS_SPECIFIC | 0x00000027)
+#define EFI_CU_HP_PC_DXE_STEP8                    (EFI_SUBCLASS_SPECIFIC | 0x00000028)
+#define EFI_CU_HP_PC_DXE_STEP9                    (EFI_SUBCLASS_SPECIFIC | 0x00000029)
+#define EFI_CU_HP_PC_DXE_STEP10                   (EFI_SUBCLASS_SPECIFIC | 0x0000002A)
+#define EFI_CU_HP_PC_DXE_STEP11                   (EFI_SUBCLASS_SPECIFIC | 0x0000002B)
+#define EFI_CU_HP_PC_DXE_STEP12                   (EFI_SUBCLASS_SPECIFIC | 0x0000002C)
+#define EFI_CU_HP_PC_DXE_STEP13                   (EFI_SUBCLASS_SPECIFIC | 0x0000002D)
+#define EFI_CU_HP_PC_DXE_STEP14                   (EFI_SUBCLASS_SPECIFIC | 0x0000002E)
+#define EFI_CU_HP_PC_DXE_END                      (EFI_SUBCLASS_SPECIFIC | 0x0000002F)
+
+//
+// CPU SMM PEI
+//
+#define EFI_CU_HP_PC_SMM_PEI_INIT                 (EFI_SUBCLASS_SPECIFIC | 0x00000030)
+#define EFI_CU_HP_PC_SMM_PEI_STEP1                (EFI_SUBCLASS_SPECIFIC | 0x00000031)
+#define EFI_CU_HP_PC_SMM_PEI_STEP2                (EFI_SUBCLASS_SPECIFIC | 0x00000032)
+#define EFI_CU_HP_PC_SMM_PEI_STEP3                (EFI_SUBCLASS_SPECIFIC | 0x00000033)
+#define EFI_CU_HP_PC_SMM_PEI_STEP4                (EFI_SUBCLASS_SPECIFIC | 0x00000034)
+#define EFI_CU_HP_PC_SMM_PEI_STEP5                (EFI_SUBCLASS_SPECIFIC | 0x00000035)
+#define EFI_CU_HP_PC_SMM_PEI_STEP6                (EFI_SUBCLASS_SPECIFIC | 0x00000036)
+#define EFI_CU_HP_PC_SMM_PEI_END                  (EFI_SUBCLASS_SPECIFIC | 0x0000003F)
+
+//
+// CPU SMM DXE
+//
+#define EFI_CU_HP_PC_SMM_DXE_INIT                 (EFI_SUBCLASS_SPECIFIC | 0x00000040)
+#define EFI_CU_HP_PC_SMM_DXE_STEP1                (EFI_SUBCLASS_SPECIFIC | 0x00000041)
+#define EFI_CU_HP_PC_SMM_DXE_STEP2                (EFI_SUBCLASS_SPECIFIC | 0x00000042)
+#define EFI_CU_HP_PC_SMM_DXE_STEP3                (EFI_SUBCLASS_SPECIFIC | 0x00000043)
+#define EFI_CU_HP_PC_SMM_DXE_STEP4                (EFI_SUBCLASS_SPECIFIC | 0x00000044)
+#define EFI_CU_HP_PC_SMM_DXE_STEP5                (EFI_SUBCLASS_SPECIFIC | 0x00000045)
+#define EFI_CU_HP_PC_SMM_DXE_STEP6                (EFI_SUBCLASS_SPECIFIC | 0x00000046)
+#define EFI_CU_HP_PC_SMM_DXE_END                  (EFI_SUBCLASS_SPECIFIC | 0x0000004F)
+
+//
+// PEI before memory initialization
+//
+#define EFI_CU_PLATFORM_PEI_INIT                     (EFI_OEM_SPECIFIC | 0x00000001)
+#define EFI_CU_PLATFORM_PEI_STEP1                    (EFI_OEM_SPECIFIC | 0x00000002)
+#define EFI_CU_PLATFORM_PEI_STEP2                    (EFI_OEM_SPECIFIC | 0x00000003)
+#define EFI_CU_PLATFORM_PEI_STEP3                    (EFI_OEM_SPECIFIC | 0x00000004)
+#define EFI_CU_PLATFORM_PEI_STEP4                    (EFI_OEM_SPECIFIC | 0x00000005)
+#define EFI_CU_SMBUS_PEI_INIT                        (EFI_OEM_SPECIFIC | 0x00000006)
+#define EFI_CU_SMBUS_PEI_EXEC_ENTRY                  (EFI_OEM_SPECIFIC | 0x00000007)
+#define EFI_CU_SMBUS_PEI_EXEC_EXIT                   (EFI_OEM_SPECIFIC | 0x00000008)
+#define EFI_CU_CLOCK_PEI_INIT_ENTRY                  (EFI_OEM_SPECIFIC | 0x00000009)
+#define EFI_CU_CLOCK_PEI_INIT_EXIT                   (EFI_OEM_SPECIFIC | 0x0000000A)
+#define EFI_CU_MEMORY_PC_PROG_MTRR                   (EFI_OEM_SPECIFIC | 0x0000000B)
+#define EFI_CU_MEMORY_PC_PROG_MTRR_END               (EFI_OEM_SPECIFIC | 0x0000000C)
+#define EFI_CU_PLATFORM_PEI_STEP12                   (EFI_OEM_SPECIFIC | 0x0000000D)
+#define EFI_CU_PLATFORM_PEI_STEP13                   (EFI_OEM_SPECIFIC | 0x0000000E)
+#define EFI_CU_PLATFORM_PEI_END                      (EFI_OEM_SPECIFIC | 0x0000000F)
+
+#define EFI_CU_PLATFORM_DXE_INIT                     (EFI_OEM_SPECIFIC | 0x00000011)
+#define EFI_CU_PLATFORM_DXE_STEP1                    (EFI_OEM_SPECIFIC | 0x00000012)
+#define EFI_CU_PLATFORM_DXE_STEP2                    (EFI_OEM_SPECIFIC | 0x00000013)
+#define EFI_CU_PLATFORM_DXE_STEP3                    (EFI_OEM_SPECIFIC | 0x00000014)
+#define EFI_CU_PLATFORM_DXE_STEP4                    (EFI_OEM_SPECIFIC | 0x00000015)
+#define EFI_CU_PLATFORM_DXE_INIT_DONE                (EFI_OEM_SPECIFIC | 0x00000016)
+
+#define EFI_CU_OVERCLOCK_PEI_INIT_ENTRY              (EFI_OEM_SPECIFIC | 0x00000017)
+#define EFI_CU_OVERCLOCK_PEI_INIT_EXIT               (EFI_OEM_SPECIFIC | 0x00000018)
+
+//
+// BDS
+//
+#define EFI_CU_BDS_INIT                              (EFI_OEM_SPECIFIC | 0x00000060)
+#define EFI_CU_BDS_STEP1                             (EFI_OEM_SPECIFIC | 0x00000061)
+#define EFI_CU_BDS_STEP2                             (EFI_OEM_SPECIFIC | 0x00000062)
+#define EFI_CU_BDS_STEP3                             (EFI_OEM_SPECIFIC | 0x00000063)
+#define EFI_CU_BDS_STEP4                             (EFI_OEM_SPECIFIC | 0x00000064)
+#define EFI_CU_BDS_STEP5                             (EFI_OEM_SPECIFIC | 0x00000065)
+#define EFI_CU_BDS_STEP6                             (EFI_OEM_SPECIFIC | 0x00000066)
+#define EFI_CU_BDS_STEP7                             (EFI_OEM_SPECIFIC | 0x00000067)
+#define EFI_CU_BDS_STEP8                             (EFI_OEM_SPECIFIC | 0x00000068)
+#define EFI_CU_BDS_STEP9                             (EFI_OEM_SPECIFIC | 0x00000069)
+#define EFI_CU_BDS_STEP10                            (EFI_OEM_SPECIFIC | 0x0000006A)
+#define EFI_CU_BDS_STEP11                            (EFI_OEM_SPECIFIC | 0x0000006B)
+#define EFI_CU_BDS_STEP12                            (EFI_OEM_SPECIFIC | 0x0000006C)
+#define EFI_CU_BDS_STEP13                            (EFI_OEM_SPECIFIC | 0x0000006D)
+#define EFI_CU_BDS_STEP14                            (EFI_OEM_SPECIFIC | 0x0000006E)
+#define EFI_CU_BDS_END                               (EFI_OEM_SPECIFIC | 0x0000006F)
+
+
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.c b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.c
new file mode 100644
index 0000000000..8283483ff8
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.c
@@ -0,0 +1,132 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+  MonoStatusCode.c
+
+Abstract:
+
+  PEIM to provide the status code functionality, to aid in system debug.
+  It includes output to 0x80 port and/or to serial port.
+  This PEIM is monolithic. Different platform should provide different library.
+
+--*/
+
+#include "MonoStatusCode.h"
+#include "PlatformStatusCode.h"
+#define CMOS_EFI_DEBUG              0x14
+
+//
+// Module globals
+//
+EFI_PEI_PROGRESS_CODE_PPI     mStatusCodePpi = { PlatformReportStatusCode };
+
+EFI_PEI_PPI_DESCRIPTOR  mPpiListStatusCode = {
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEfiPeiStatusCodePpiGuid,
+  &mStatusCodePpi
+};
+
+//
+// Function implemenations
+//
+
+/**
+  Translate from a DXE status code interface into a PEI-callable
+  interface, making the PEI the least common denominator..
+
+  Same as DXE ReportStatusCode RT service
+
+
+**/
+EFI_STATUS
+EFIAPI
+TranslateDxeStatusCodeToPeiStatusCode (
+  IN EFI_STATUS_CODE_TYPE     CodeType,
+  IN EFI_STATUS_CODE_VALUE    Value,
+  IN UINT32                   Instance,
+  IN EFI_GUID                 * CallerId,
+  IN EFI_STATUS_CODE_DATA     * Data OPTIONAL
+  )
+{
+  return PlatformReportStatusCode (NULL, CodeType, Value, Instance, CallerId, Data);
+}
+
+/**
+  Build a hob describing the status code listener that has been installed.
+  This will be used by DXE code until a runtime status code listener is
+  installed.
+
+  @param PeiServices      General purpose services available to every PEIM.
+
+  @retval Status          EFI_SUCCESS if the interface could be successfully
+                          installed
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeDxeReportStatusCode (
+  IN const EFI_PEI_SERVICES       **PeiServices
+  )
+{
+  EFI_STATUS  Status = EFI_UNSUPPORTED;
+
+  VOID        *Instance;
+
+  VOID        *Result;
+
+  Instance = (VOID *) (UINTN) TranslateDxeStatusCodeToPeiStatusCode;
+
+  Result = BuildGuidDataHob (
+             &gEfiStatusCodeRuntimeProtocolGuid,
+             &Instance,
+             sizeof (VOID *)
+             );
+  if (Result != NULL) {
+    Status = EFI_SUCCESS;
+  }
+  return Status;
+}
+
+/**
+  Initialize the platform status codes and publish the platform status code
+  PPI.
+
+  @param  FfsHeader      FV this PEIM was loaded from.
+  @param  PeiServices    General purpose services available to every PEIM.
+
+  @retval Status         EFI_SUCCESS
+
+**/
+VOID
+EFIAPI
+InitializeMonoStatusCode (
+  IN EFI_FFS_FILE_HEADER       *FfsHeader,
+  IN CONST EFI_PEI_SERVICES          **PeiServices
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // Initialize status code listeners.
+  //
+  PlatformInitializeStatusCode (FfsHeader, PeiServices);
+
+  //
+  // Publish the status code capability to other modules
+  //
+  Status = (*PeiServices)->InstallPpi (PeiServices, &mPpiListStatusCode);
+
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_ERROR, "\nMono Status Code PEIM Loaded\n"));
+
+  return ;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.h b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.h
new file mode 100644
index 0000000000..0b256093a6
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.h
@@ -0,0 +1,128 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  MonoStatusCode.h
+
+Abstract:
+
+  Monolithic single PEIM to provide the status code functionality.
+  The PEIM is a blend of libraries that correspond to the different status code
+  listeners that a platform installs.
+
+--*/
+
+#ifndef _MONO_STATUS_CODE_H_
+#define _MONO_STATUS_CODE_H_
+
+//
+// Statements that include other files.
+//
+#include "PiPei.h"
+
+#include "Pi/PiBootMode.h"
+
+#include "Ppi/StatusCode.h"
+#include "Ppi/MemoryDiscovered.h"
+#include "Ppi/FvLoadFile.h"
+
+#include "Library/HobLib.h"
+#include "Library/DebugLib.h"
+#include "Library/IoLib.h"
+#include "Library/SerialPortLib.h"
+#include "Protocol/StatusCode.h"
+
+
+#ifndef _STATUS_CODE_ENABLER_H_
+#define _STATUS_CODE_ENABLER_H_
+
+#ifdef EFI_DEBUG
+
+#define EFI_STATUS_CODE_ENABLER_HOB_GUID \
+  { \
+    0x5ffc6cf3, 0x71ad, 0x46f5, 0xbd, 0x8b, 0x7e, 0x8f, 0xfe, 0x19, 0x7, 0xd7 \
+  }
+
+extern EFI_GUID gEfiSerialStatusCodeEnablerHobGuid;
+
+typedef struct _EFI_STATUS_CODE_INFO {
+  BOOLEAN    StatusCodeDisable;
+} EFI_STATUS_CODE_INFO;
+
+#endif
+#endif
+
+
+
+//
+// Platform specific function Declarations.  These must be implemented in a
+// subdirectory named PlatformName in a file named PlatformStatusCode.c.
+//
+
+//
+// This is the platform function to initialize the listeners desired by the
+// platform.
+//
+VOID
+PlatformInitializeStatusCode (
+  IN EFI_FFS_FILE_HEADER       *FfsHeader,
+  IN CONST EFI_PEI_SERVICES          **PeiServices
+  );
+
+//
+// This is the platform function that calls all of the listeners desired by the
+// platform.
+//
+EFI_STATUS
+EFIAPI
+PlatformReportStatusCode (
+  IN CONST EFI_PEI_SERVICES       **PeiServices,
+  IN EFI_STATUS_CODE_TYPE         CodeType,
+  IN EFI_STATUS_CODE_VALUE        Value,
+  IN UINT32                       Instance,
+  IN CONST EFI_GUID               * CallerId,
+  IN CONST EFI_STATUS_CODE_DATA   * Data OPTIONAL
+  );
+
+//
+// Platform independent function Declarations
+//
+//
+// Initialize the status code listeners and publish the status code PPI.
+//
+VOID
+EFIAPI
+InitializeMonoStatusCode (
+  IN EFI_FFS_FILE_HEADER       *FfsHeader,
+  IN const EFI_PEI_SERVICES    **PeiServices
+  );
+
+//
+// Convert a DXE status code call into a PEI status code call.
+//
+EFI_STATUS
+EFIAPI
+TranslateDxeStatusCodeToPeiStatusCode (
+  IN EFI_STATUS_CODE_TYPE     CodeType,
+  IN EFI_STATUS_CODE_VALUE    Value,
+  IN UINT32                   Instance,
+  IN EFI_GUID                 * CallerId,
+  IN EFI_STATUS_CODE_DATA     * Data OPTIONAL
+  );
+
+//
+// Publish a HOB that contains the listener to be used by DXE.
+//
+EFI_STATUS
+EFIAPI
+InitializeDxeReportStatusCode (
+  IN const EFI_PEI_SERVICES       **PeiServices
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.inf b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.inf
new file mode 100644
index 0000000000..f1be5b8d6c
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.inf
@@ -0,0 +1,72 @@
+#
+#
+# Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+#                                                                                  
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#                                                                                  
+#
+#  Module Name:
+#
+#    MonoStatusCode.inf
+#
+#  Abstract:
+#
+#    Component description file for Status Code PEI module
+#
+#--*/
+
+[defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = MonoStatusCode
+  FILE_GUID                      = 4BB346D2-8076-4671-8BC9-7B95CBB9A6DF
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+#  ENTRY_POINT                    = InstallMonoStatusCode
+  LIBRARY_CLASS                  = MonoStatusCodeLib
+
+[sources.common]
+  MonoStatusCode.c
+  MonoStatusCode.h
+  PlatformStatusCode.c
+  PlatformStatusCode.h
+  PeiPostCode.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Vlv2SocBinPkg/Vlv2SocBinPkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+
+[LibraryClasses]
+  PeimEntryPoint
+  HobLib
+  DebugLib
+  SerialPortLib
+  ReportStatusCodeLib
+  PrintLib
+  BaseMemoryLib
+  PchPlatformLib
+
+[Ppis]
+  gEfiPeiMemoryDiscoveredPpiGuid
+  gEfiPeiStatusCodePpiGuid
+  gEfiPeiFvFileLoaderPpiGuid
+
+[Protocols]
+  gEfiStatusCodeRuntimeProtocolGuid
+
+[Pcd]
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseRam
+
+[Guids]
+  gEfiPlatformCpuInfoGuid
+  gEfiHtBistHobGuid
+  gEfiStatusCodeDataTypeStringGuid              ## CONSUMES
+
+[Depex]
+  TRUE
+
+
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PeiPostCode.c b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PeiPostCode.c
new file mode 100644
index 0000000000..92dbef551e
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PeiPostCode.c
@@ -0,0 +1,121 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+  PeiPostCode.c
+
+Abstract:
+
+  Worker functions for PostCode
+
+--*/
+
+#include "EfiStatusCode.h"
+
+#pragma pack(1)
+typedef struct {
+  EFI_STATUS_CODE_VALUE   StatusValue;
+  UINT8                   Port80Value;
+} EFI_STATUS_CODE_TO_PORT_80;
+#pragma pack()
+
+//
+// see Edk\Foundation\Library\EfiCommonLib\PostCode.c for DXE/BDS POST codes.
+//
+EFI_STATUS_CODE_TO_PORT_80  mPeiPort80Table[] = {
+  //
+  // Platform init
+  //
+  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_PLATFORM_PEI_INIT,          0x11},
+  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_PLATFORM_PEI_STEP1,         0x12},
+  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_PLATFORM_PEI_STEP2,         0x13},
+  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_PLATFORM_PEI_STEP3,         0x14},
+  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_PLATFORM_PEI_STEP4,         0x15},
+
+  //
+  // SMBUS
+  //
+  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_SMBUS_PEI_INIT,             0x16},
+  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_SMBUS_PEI_EXEC_ENTRY,       0x17},
+  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_SMBUS_PEI_EXEC_EXIT,        0x18},
+
+  //
+  // Clock
+  //
+  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_CLOCK_PEI_INIT_ENTRY,       0x19},
+  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_CLOCK_PEI_INIT_EXIT,        0x1A},
+
+  //
+  // Over clocking support
+  //
+  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_OVERCLOCK_PEI_INIT_ENTRY,   0x1B},
+  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_OVERCLOCK_PEI_INIT_EXIT,    0x1C},
+
+  //
+  // MRC
+  //
+  {EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_INIT_BEGIN,        0x21},
+  {EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_SPD_READ,          0x23},
+  {EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_PRESENCE_DETECT,   0x24},
+  {EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_TIMING,            0x25},
+  {EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_OPTIMIZING,        0x26},
+  {EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_CONFIGURING,       0x27},
+  {EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_TEST,              0x28},
+  {EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_COMPLETE,          0x29},
+
+  //
+  // Platform Init after MRC
+  //
+  {EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_PROG_MTRR,         0x2A},
+  {EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_PROG_MTRR_END,     0x2B},
+
+  {EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEIM_PC_RECOVERY_BEGIN,        0x31},
+  {EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEIM_PC_RECOVERY_AUTO,         0x32},
+  {EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEIM_PC_CAPSULE_LOAD,          0x33},
+  {EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEIM_PC_CAPSULE_START,         0x34},
+  {EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEIM_EC_NO_RECOVERY_CAPSULE,   0x35},
+
+  {EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_PEI_INIT,      0x41},
+  {EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_PEI_STEP1,     0x42},
+  {EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_PEI_END,       0x43},
+  {EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_SMM_PEI_INIT,  0x44},
+  {EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_SMM_PEI_STEP1, 0x45},
+  {EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_SMM_PEI_END,   0x46}
+};
+
+BOOLEAN
+PeiCodeTypeToPostCode (
+  IN  EFI_STATUS_CODE_TYPE    CodeType,
+  IN  EFI_STATUS_CODE_VALUE   Value,
+  OUT UINT8                   *PostCode
+  )
+{
+  UINTN             Index;
+
+  if (CodeType == EFI_PROGRESS_CODE) {
+    if ((Value == (EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_BEGIN)) ||
+        (Value == (EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_END)) ||
+        (Value == (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_BEGIN)) ||
+        (Value == (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_END))) {
+      return FALSE;
+    }
+  } else {
+    return FALSE;
+  }
+
+  for (Index = 0; Index < sizeof(mPeiPort80Table)/sizeof(EFI_STATUS_CODE_TO_PORT_80); Index++) {
+    if (mPeiPort80Table[Index].StatusValue == Value) {
+      *PostCode = mPeiPort80Table[Index].Port80Value;
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.c b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.c
new file mode 100644
index 0000000000..a1abddc512
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.c
@@ -0,0 +1,381 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+  PlatformStatusCode.c
+
+Abstract:
+
+  Contains Platform specific implementations required to use status codes.
+
+--*/
+
+#include "PlatformStatusCode.h"
+#include <PchRegs.h>
+#include <PlatformBaseAddresses.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+
+typedef struct {
+  EFI_STATUS_CODE_DATA  DataHeader;
+  EFI_HANDLE            Handle;
+} PEIM_FILE_HANDLE_EXTENDED_DATA;
+
+#define CONFIG_PORT0    0x4E
+#define PCI_IDX         0xCF8
+#define PCI_DAT         0xCFC
+
+#define PCI_LPC_BASE    (0x8000F800)
+#define PCI_LPC_REG(x)  (PCI_LPC_BASE + (x))
+
+//
+// Function implementations
+//
+BOOLEAN
+PeiCodeTypeToPostCode (
+  IN  EFI_STATUS_CODE_TYPE    CodeType,
+  IN  EFI_STATUS_CODE_VALUE   Value,
+  OUT UINT8                   *PostCode
+  );
+
+/**
+  Provide a port 80 status code
+
+  @param Same as ReportStatusCode PPI
+
+  @retval EFI_SUCCESS   Always returns success.
+
+**/
+EFI_STATUS
+EFIAPI
+Port80ReportStatusCode (
+  IN CONST EFI_PEI_SERVICES         **PeiServices,
+  IN EFI_STATUS_CODE_TYPE           CodeType,
+  IN EFI_STATUS_CODE_VALUE          Value,
+  IN UINT32                         Instance,
+  IN CONST EFI_GUID                 *CallerId,
+  IN CONST EFI_STATUS_CODE_DATA     *Data OPTIONAL
+  )
+
+{
+  EFI_STATUS               Status;
+  EFI_FV_FILE_INFO         FvFileInfo;
+  UINT16                   Port80Code = 0;
+
+  //
+  // Progress or error code, Output Port 80h card.
+  //
+  if (!PeiCodeTypeToPostCode (CodeType, Value, (UINT8 *)&Port80Code)) {
+    if ((Data != NULL) && (Value ==(EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_BEGIN))){
+      Status = PeiServicesFfsGetFileInfo (
+                 ((PEIM_FILE_HANDLE_EXTENDED_DATA *) (Data + 1))->Handle,
+                 &FvFileInfo
+                 );
+      if (!EFI_ERROR (Status)) {
+        Port80Code = (FvFileInfo.FileName.Data4[6]<<8) + (FvFileInfo.FileName.Data4[7]);
+      }
+    }
+  }
+  if (Port80Code != 0){
+    IoWrite16 (0x80, (UINT16) Port80Code);
+    DEBUG ((EFI_D_ERROR, "POSTCODE=<%04x>\n", Port80Code));
+  }
+  return  EFI_SUCCESS;
+}
+
+/**
+  Provide a serial status code
+
+  @param Same as ReportStatusCode PPI
+
+  @retval EFI_SUCCESS   Always returns success.
+
+**/
+EFI_STATUS
+EFIAPI
+SerialReportStatusCode (
+  IN CONST EFI_PEI_SERVICES         **PeiServices,
+  IN EFI_STATUS_CODE_TYPE           CodeType,
+  IN EFI_STATUS_CODE_VALUE          Value,
+  IN UINT32                         Instance,
+  IN CONST EFI_GUID                 * CallerId,
+  IN CONST EFI_STATUS_CODE_DATA     * Data OPTIONAL
+  )
+{
+  CHAR8           *Filename;
+  CHAR8           *Description;
+  CHAR8           *Format;
+  CHAR8           Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];
+  UINT32          ErrorLevel;
+  UINT32          LineNumber;
+  UINTN           CharCount;
+  BASE_LIST       Marker;
+
+  Buffer[0] = '\0';
+
+  if (Data != NULL &&
+      ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {
+    //
+    // Print ASSERT() information into output buffer.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "\n\rPEI_ASSERT!: %a (%d): %a\n\r",
+                  Filename,
+                  LineNumber,
+                  Description
+                  );
+  } else if (Data != NULL &&
+             ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {
+    //
+    // Print DEBUG() information into output buffer.
+    //
+    CharCount = AsciiBSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  Format,
+                  Marker
+                  );
+  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
+    //
+    // Print ERROR information into output buffer.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "ERROR: C%x:V%x I%x",
+                  CodeType,
+                  Value,
+                  Instance
+                  );
+
+    ASSERT(CharCount > 0);
+
+    if (CallerId != NULL) {
+      CharCount += AsciiSPrint (
+                     &Buffer[CharCount],
+                     (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
+                     " %g",
+                     CallerId
+                     );
+    }
+
+    if (Data != NULL) {
+      CharCount += AsciiSPrint (
+                     &Buffer[CharCount],
+                     (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
+                     " %x",
+                     Data
+                     );
+    }
+
+    CharCount += AsciiSPrint (
+                   &Buffer[CharCount],
+                   (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
+                   "\n\r"
+                   );
+  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
+    //
+    // Print PROGRESS information into output buffer.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "PROGRESS CODE: V%x I%x\n\r",
+                  Value,
+                  Instance
+                  );
+  } else if (Data != NULL &&
+             CompareGuid (&Data->Type, &gEfiStatusCodeDataTypeStringGuid) &&
+             ((EFI_STATUS_CODE_STRING_DATA *) Data)->StringType == EfiStringAscii) {
+    //
+    // EFI_STATUS_CODE_STRING_DATA
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "%a\n\r",
+                  ((EFI_STATUS_CODE_STRING_DATA *) Data)->String.Ascii
+                  );
+  } else {
+    //
+    // Code type is not defined.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "Undefined: C%x:V%x I%x\n\r",
+                  CodeType,
+                  Value,
+                  Instance
+                  );
+  }
+
+  //
+  // Call SerialPort Lib function to do print.
+  //
+  SerialPortWrite ((UINT8 *) Buffer, CharCount);
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Call all status code listeners in the MonoStatusCode.
+
+  @param PeiServices    The PEI core services table.
+  @param CodeType       Type of Status Code.
+  @param Value          Value to output for Status Code.
+  @param Instance       Instance Number of this status code.
+  @param CallerId       ID of the caller of this status code.
+  @param Data           Optional data associated with this status code.
+
+  @retval EFI_SUCCESS              If status code is successfully reported.
+  @retval EFI_NOT_AVAILABLE_YET    If StatusCodePpi has not been installed.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformReportStatusCode (
+  IN  CONST EFI_PEI_SERVICES        **PeiServices,
+  IN EFI_STATUS_CODE_TYPE           CodeType,
+  IN EFI_STATUS_CODE_VALUE          Value,
+  IN UINT32                         Instance,
+  IN CONST EFI_GUID                 * CallerId,
+  IN CONST EFI_STATUS_CODE_DATA     * Data OPTIONAL
+  )
+{
+  //
+  // If we are in debug mode, we will allow serial status codes
+  //
+  SerialReportStatusCode (PeiServices, CodeType, Value, Instance, CallerId, Data);
+
+  Port80ReportStatusCode (PeiServices, CodeType, Value, Instance, CallerId, Data);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Install the PEIM.  Initialize listeners, publish the PPI and HOB for PEI and
+  DXE use respectively.
+
+  @param FfsHeader      FV this PEIM was loaded from.
+  @param PeiServices    General purpose services available to every PEIM.
+
+  @retval EFI_SUCCESS   The function always returns success.
+
+**/
+EFI_STATUS
+EFIAPI
+InstallMonoStatusCode (
+  IN EFI_FFS_FILE_HEADER       *FfsHeader,
+  IN CONST EFI_PEI_SERVICES    **PeiServices
+  )
+{
+
+  //
+  // Initialize all listeners
+  //
+  InitializeMonoStatusCode (FfsHeader, PeiServices);
+
+  //
+  // Publish the listener in a HOB for DXE use.
+  //
+  InitializeDxeReportStatusCode (PeiServices);
+
+  return EFI_SUCCESS;
+}
+
+#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 PciD31F0RegBase                           PCIEX_BASE_ADDRESS + (UINT32) (31 << 15)
+#define SB_RCBA                                   0xfed1c000
+
+extern PCH_STEPPING EFIAPI PchStepping (VOID);
+
+VOID
+RamDebugInit (
+  VOID
+  );
+
+/**
+  Enable legacy decoding on ICH6
+
+  @param none
+
+  @retval EFI_SUCCESS     Always returns success.
+
+**/
+EFI_STATUS
+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);
+
+  return  EFI_SUCCESS;
+}
+
+/**
+  INIT the SIO. Ported this code and I don't undertand the comments either.
+
+  @param FfsHeader    FV this PEIM was loaded from.
+  @param PeiServices  General purpose services available to every PEIM.
+
+  None
+
+**/
+VOID
+EFIAPI
+PlatformInitializeStatusCode (
+  IN EFI_FFS_FILE_HEADER       *FfsHeader,
+  IN CONST EFI_PEI_SERVICES    **PeiServices
+  )
+{
+
+  //
+  // Enable internal COM1 on South Cluster.
+  //
+	EnableInternalUart();
+
+
+  //
+  // Initialize additional debug status code listeners.
+  //
+   SerialPortInitialize();
+
+}
+//#endif //EFI_DEBUG
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.h b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.h
new file mode 100644
index 0000000000..42b7c9a2c8
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.h
@@ -0,0 +1,138 @@
+/*++
+
+  Copyright (c) 2004  - 2017, Intel Corporation. All rights reserved.<BR>
+                                                                                   
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+                                                                                   
+
+Module Name:
+
+  PlatformStatusCode.h
+
+Abstract:
+
+  Contains Platform specific implementations required to use status codes.
+
+--*/
+
+#ifndef _PLATFORM_STATUS_CODE_H_
+#define _PLATFORM_STATUS_CODE_H_
+
+
+#define CONFIG_PORT0    0x4E
+#define INDEX_PORT0     0x4E
+#define DATA_PORT0      0x4F
+#define PCI_IDX        0xCF8
+#define PCI_DAT        0xCFC
+
+#include "MonoStatusCode.h"
+#ifndef _PEI_PORT_80_STATUS_CODE_H_
+#define _PEI_PORT_80_STATUS_CODE_H_
+
+
+
+//
+// Status code reporting function
+//
+EFI_STATUS
+Port80ReportStatusCode (
+  IN CONST EFI_PEI_SERVICES         **PeiServices,
+  IN EFI_STATUS_CODE_TYPE           CodeType,
+  IN EFI_STATUS_CODE_VALUE          Value,
+  IN UINT32                         Instance,
+  IN CONST EFI_GUID                 * CallerId,
+  IN CONST EFI_STATUS_CODE_DATA     * Data OPTIONAL
+  );
+
+#endif
+
+#ifndef _PEI_SERIAL_STATUS_CODE_LIB_H_
+#define _PEI_SERIAL_STATUS_CODE_LIB_H_
+
+
+#include <Guid/StatusCodeDataTypeId.h>
+#include <Guid/StatusCodeDataTypeDebug.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/PrintLib.h>
+#include <Library/BaseMemoryLib.h>
+
+//
+// Initialization function
+//
+VOID
+SerialInitializeStatusCode (
+  VOID
+  );
+
+//
+// Status code reporting function
+//
+EFI_STATUS
+SerialReportStatusCode (
+  IN CONST EFI_PEI_SERVICES         **PeiServices,
+  IN EFI_STATUS_CODE_TYPE     CodeType,
+  IN EFI_STATUS_CODE_VALUE    Value,
+  IN UINT32                   Instance,
+  IN CONST EFI_GUID                 * CallerId,
+  IN CONST EFI_STATUS_CODE_DATA     * Data OPTIONAL
+  );
+
+#endif
+
+extern EFI_PEI_PROGRESS_CODE_PPI    mStatusCodePpi;
+extern EFI_PEI_PPI_DESCRIPTOR mPpiListStatusCode;
+#define EFI_SIGNATURE_16(A, B)        ((A) | (B << 8))
+#define EFI_SIGNATURE_32(A, B, C, D)  (EFI_SIGNATURE_16 (A, B) | (EFI_SIGNATURE_16 (C, D) << 16))
+#define STATUSCODE_PEIM_SIGNATURE EFI_SIGNATURE_32 ('p', 's', 't', 'c')
+
+typedef struct {
+  UINT32                    Signature;
+  EFI_FFS_FILE_HEADER       *FfsHeader;
+  EFI_PEI_NOTIFY_DESCRIPTOR StatusCodeNotify;
+} STATUSCODE_CALLBACK_STATE_INFORMATION;
+
+#pragma pack(1)
+typedef struct {
+  UINT16  Limit;
+  UINT32  Base;
+} GDT_DSCRIPTOR;
+#pragma pack()
+
+#define STATUSCODE_PEIM_FROM_THIS(a) \
+  BASE_CR ( \
+  a, \
+  STATUSCODE_CALLBACK_STATE_INFORMATION, \
+  StatusCodeNotify \
+  )
+
+VOID
+EFIAPI
+PlatformInitializeStatusCode (
+  IN EFI_FFS_FILE_HEADER       *FfsHeader,
+  IN CONST EFI_PEI_SERVICES    **PeiServices
+  );
+
+
+//
+// Function declarations
+//
+/**
+  Install Firmware Volume Hob's once there is main memory
+
+  @param PeiServices        General purpose services available to every PEIM.
+  @param NotifyDescriptor   Not Used
+  @param Ppi                Not Used
+
+  @retval Status            EFI_SUCCESS if the interface could be successfully
+                            installed
+
+**/
+EFI_STATUS
+EFIAPI
+MemoryDiscoveredPpiNotifyCallback (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c
new file mode 100644
index 0000000000..3034853695
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c
@@ -0,0 +1,4490 @@
+/** @file
+  BDS Lib functions which relate with create or process the boot option.
+
+Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalBdsLib.h"
+#include "String.h"
+#include <Library/NetLib.h>
+#include "Library/DebugLib.h"
+
+BOOLEAN mEnumBootDevice = FALSE;
+EFI_HII_HANDLE gBdsLibStringPackHandle = NULL;
+
+/**
+
+  End Perf entry of BDS
+
+  @param  Event                 The triggered event.
+  @param  Context               Context for this event.
+
+**/
+VOID
+EFIAPI
+BmEndOfBdsPerfCode (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  //
+  // Record the performance data for End of BDS
+  //
+  PERF_END(NULL, "BDS", NULL, 0);
+
+  return ;
+}
+
+/**
+  The constructor function register UNI strings into imageHandle.
+  
+  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. 
+
+  @param  ImageHandle   The firmware allocated handle for the EFI image.
+  @param  SystemTable   A pointer to the EFI System Table.
+  
+  @retval EFI_SUCCESS   The constructor successfully added string package.
+  @retval Other value   The constructor can't add string package.
+
+**/
+EFI_STATUS
+EFIAPI
+GenericBdsLibConstructor (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+
+  gBdsLibStringPackHandle = HiiAddPackages (
+                              &gBdsLibStringPackageGuid,
+                              ImageHandle,
+                              GenericBdsLibStrings,
+                              NULL
+                              );
+
+  ASSERT (gBdsLibStringPackHandle != NULL);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Deletete the Boot Option from EFI Variable. The Boot Order Arrray
+  is also updated.
+
+  @param OptionNumber    The number of Boot option want to be deleted.
+  @param BootOrder       The Boot Order array.
+  @param BootOrderSize   The size of the Boot Order Array.
+
+  @retval  EFI_SUCCESS           The Boot Option Variable was found and removed
+  @retval  EFI_UNSUPPORTED       The Boot Option Variable store was inaccessible
+  @retval  EFI_NOT_FOUND         The Boot Option Variable was not found
+**/
+EFI_STATUS
+EFIAPI
+BdsDeleteBootOption (
+  IN UINTN                       OptionNumber,
+  IN OUT UINT16                  *BootOrder,
+  IN OUT UINTN                   *BootOrderSize
+  )
+{
+  CHAR16      BootOption[9];
+  UINTN       Index;
+  EFI_STATUS  Status;
+
+  UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", OptionNumber);
+  Status = gRT->SetVariable (
+                  BootOption,
+                  &gEfiGlobalVariableGuid,
+                  0,
+                  0,
+                  NULL
+                  );
+  //
+  // Deleting variable with existing variable implementation shouldn't fail.
+  //
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // adjust boot order array
+  //
+  for (Index = 0; Index < *BootOrderSize / sizeof (UINT16); Index++) {
+    if (BootOrder[Index] == OptionNumber) {
+      CopyMem (&BootOrder[Index], &BootOrder[Index+1], *BootOrderSize - (Index+1) * sizeof (UINT16));
+      *BootOrderSize -= sizeof (UINT16);
+      break;
+    }
+  }
+
+  return Status;
+}
+/**
+
+  Translate the first n characters of an Ascii string to
+  Unicode characters. The count n is indicated by parameter
+  Size. If Size is greater than the length of string, then
+  the entire string is translated.
+
+
+  @param AStr               Pointer to input Ascii string.
+  @param Size               The number of characters to translate.
+  @param UStr               Pointer to output Unicode string buffer.
+
+**/
+VOID
+AsciiToUnicodeSize (
+  IN UINT8              *AStr,
+  IN UINTN              Size,
+  OUT UINT16            *UStr
+  )
+{
+  UINTN Idx;
+
+  Idx = 0;
+  while (AStr[Idx] != 0) {
+    UStr[Idx] = (CHAR16) AStr[Idx];
+    if (Idx == Size) {
+      break;
+    }
+
+    Idx++;
+  }
+  UStr[Idx] = 0;
+}
+
+/**
+  Build Legacy Device Name String according.
+
+  @param CurBBSEntry     BBS Table.
+  @param Index           Index.
+  @param BufSize         The buffer size.
+  @param BootString      The output string.
+
+**/
+VOID
+BdsBuildLegacyDevNameString (
+  IN  BBS_TABLE                 *CurBBSEntry,
+  IN  UINTN                     Index,
+  IN  UINTN                     BufSize,
+  OUT CHAR16                    *BootString
+  )
+{
+  CHAR16  *Fmt;
+  CHAR16  *Type;
+  UINT8   *StringDesc;
+  CHAR16  Temp[80];
+
+  switch (Index) {
+  //
+  // Primary Master
+  //
+  case 1:
+    Fmt = L"Primary Master %s";
+    break;
+
+ //
+ // Primary Slave
+ //
+  case 2:
+    Fmt = L"Primary Slave %s";
+    break;
+
+  //
+  // Secondary Master
+  //
+  case 3:
+    Fmt = L"Secondary Master %s";
+    break;
+
+  //
+  // Secondary Slave
+  //
+  case 4:
+    Fmt = L"Secondary Slave %s";
+    break;
+
+  default:
+    Fmt = L"%s";
+    break;
+  }
+
+  switch (CurBBSEntry->DeviceType) {
+  case BBS_FLOPPY:
+    Type = L"Floppy";
+    break;
+
+  case BBS_HARDDISK:
+    Type = L"Harddisk";
+    break;
+
+  case BBS_CDROM:
+    Type = L"CDROM";
+    break;
+
+  case BBS_PCMCIA:
+    Type = L"PCMCIAe";
+    break;
+
+  case BBS_USB:
+    Type = L"USB";
+    break;
+
+  case BBS_EMBED_NETWORK:
+    Type = L"Network";
+    break;
+
+  case BBS_BEV_DEVICE:
+    Type = L"BEVe";
+    break;
+
+  case BBS_UNKNOWN:
+  default:
+    Type = L"Unknown";
+    break;
+  }
+  //
+  // If current BBS entry has its description then use it.
+  //
+  StringDesc = (UINT8 *) (UINTN) ((CurBBSEntry->DescStringSegment << 4) + CurBBSEntry->DescStringOffset);
+  if (NULL != StringDesc) {
+    //
+    // Only get fisrt 32 characters, this is suggested by BBS spec
+    //
+    AsciiToUnicodeSize (StringDesc, 32, Temp);
+    Fmt   = L"%s";
+    Type  = Temp;
+  }
+
+  //
+  // BbsTable 16 entries are for onboard IDE.
+  // Set description string for SATA harddisks, Harddisk 0 ~ Harddisk 11
+  //
+  if (Index >= 5 && Index <= 16 && (CurBBSEntry->DeviceType == BBS_HARDDISK || CurBBSEntry->DeviceType == BBS_CDROM)) {
+    Fmt = L"%s %d";
+    UnicodeSPrint (BootString, BufSize, Fmt, Type, Index - 5);
+  } else {
+    UnicodeSPrint (BootString, BufSize, Fmt, Type);
+  }
+}
+
+/**
+
+  Create a legacy boot option for the specified entry of
+  BBS table, save it as variable, and append it to the boot
+  order list.
+
+
+  @param CurrentBbsEntry    Pointer to current BBS table.
+  @param CurrentBbsDevPath  Pointer to the Device Path Protocol instance of BBS
+  @param Index              Index of the specified entry in BBS table.
+  @param BootOrderList      On input, the original boot order list.
+                            On output, the new boot order list attached with the
+                            created node.
+  @param BootOrderListSize  On input, the original size of boot order list.
+                            On output, the size of new boot order list.
+
+  @retval  EFI_SUCCESS             Boot Option successfully created.
+  @retval  EFI_OUT_OF_RESOURCES    Fail to allocate necessary memory.
+  @retval  Other                   Error occurs while setting variable.
+
+**/
+EFI_STATUS
+BdsCreateLegacyBootOption (
+  IN BBS_TABLE                        *CurrentBbsEntry,
+  IN EFI_DEVICE_PATH_PROTOCOL         *CurrentBbsDevPath,
+  IN UINTN                            Index,
+  IN OUT UINT16                       **BootOrderList,
+  IN OUT UINTN                        *BootOrderListSize
+  )
+{
+  EFI_STATUS           Status;
+  UINT16               CurrentBootOptionNo;
+  UINT16               BootString[10];
+  CHAR16               BootDesc[100];
+  CHAR8                HelpString[100];
+  UINT16               *NewBootOrderList;
+  UINTN                BufferSize;
+  UINTN                StringLen;
+  VOID                 *Buffer;
+  UINT8                *Ptr;
+  UINT16               CurrentBbsDevPathSize;
+  UINTN                BootOrderIndex;
+  UINTN                BootOrderLastIndex;
+  UINTN                ArrayIndex;
+  BOOLEAN              IndexNotFound;
+  BBS_BBS_DEVICE_PATH  *NewBbsDevPathNode;
+
+  if ((*BootOrderList) == NULL) {
+    CurrentBootOptionNo = 0;
+  } else {
+    for (ArrayIndex = 0; ArrayIndex < (UINTN) (*BootOrderListSize / sizeof (UINT16)); ArrayIndex++) {
+      IndexNotFound = TRUE;
+      for (BootOrderIndex = 0; BootOrderIndex < (UINTN) (*BootOrderListSize / sizeof (UINT16)); BootOrderIndex++) {
+        if ((*BootOrderList)[BootOrderIndex] == ArrayIndex) {
+          IndexNotFound = FALSE;
+          break;
+        }
+      }
+
+      if (!IndexNotFound) {
+        continue;
+      } else {
+        break;
+      }
+    }
+
+    CurrentBootOptionNo = (UINT16) ArrayIndex;
+  }
+
+  UnicodeSPrint (
+    BootString,
+    sizeof (BootString),
+    L"Boot%04x",
+    CurrentBootOptionNo
+    );
+
+  BdsBuildLegacyDevNameString (CurrentBbsEntry, Index, sizeof (BootDesc), BootDesc);
+
+  //
+  // Create new BBS device path node with description string
+  //
+  UnicodeStrToAsciiStr (BootDesc, HelpString);
+
+  StringLen = AsciiStrLen (HelpString);
+  NewBbsDevPathNode = AllocateZeroPool (sizeof (BBS_BBS_DEVICE_PATH) + StringLen);
+  if (NewBbsDevPathNode == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  CopyMem (NewBbsDevPathNode, CurrentBbsDevPath, sizeof (BBS_BBS_DEVICE_PATH));
+  CopyMem (NewBbsDevPathNode->String, HelpString, StringLen + 1);
+  SetDevicePathNodeLength (&(NewBbsDevPathNode->Header), sizeof (BBS_BBS_DEVICE_PATH) + StringLen);
+
+  //
+  // Create entire new CurrentBbsDevPath with end node
+  //
+  CurrentBbsDevPath = AppendDevicePathNode (
+                        NULL,
+                        (EFI_DEVICE_PATH_PROTOCOL *) NewBbsDevPathNode
+                        );
+   if (CurrentBbsDevPath == NULL) {
+    FreePool (NewBbsDevPathNode);
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  CurrentBbsDevPathSize = (UINT16) (GetDevicePathSize (CurrentBbsDevPath));
+
+  BufferSize = sizeof (UINT32) +
+    sizeof (UINT16) +
+    StrSize (BootDesc) +
+    CurrentBbsDevPathSize +
+    sizeof (BBS_TABLE) +
+    sizeof (UINT16);
+
+  Buffer = AllocateZeroPool (BufferSize);
+  if (Buffer == NULL) {
+    FreePool (NewBbsDevPathNode);
+    FreePool (CurrentBbsDevPath);
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Ptr               = (UINT8 *) Buffer;
+
+  *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE;
+  Ptr += sizeof (UINT32);
+
+  *((UINT16 *) Ptr) = CurrentBbsDevPathSize;
+  Ptr += sizeof (UINT16);
+
+  CopyMem (
+    Ptr,
+    BootDesc,
+    StrSize (BootDesc)
+    );
+  Ptr += StrSize (BootDesc);
+
+  CopyMem (
+    Ptr,
+    CurrentBbsDevPath,
+    CurrentBbsDevPathSize
+    );
+  Ptr += CurrentBbsDevPathSize;
+
+  CopyMem (
+    Ptr,
+    CurrentBbsEntry,
+    sizeof (BBS_TABLE)
+    );
+
+  Ptr += sizeof (BBS_TABLE);
+  *((UINT16 *) Ptr) = (UINT16) Index;
+
+  Status = gRT->SetVariable (
+                  BootString,
+                  &gEfiGlobalVariableGuid,
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                  BufferSize,
+                  Buffer
+                  );
+
+  FreePool (Buffer);
+  
+  Buffer = NULL;
+
+  NewBootOrderList = AllocateZeroPool (*BootOrderListSize + sizeof (UINT16));
+  if (NULL == NewBootOrderList) {
+    FreePool (NewBbsDevPathNode);
+    FreePool (CurrentBbsDevPath);
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  if (*BootOrderList != NULL) {
+    CopyMem (NewBootOrderList, *BootOrderList, *BootOrderListSize);
+    FreePool (*BootOrderList);
+  }
+
+  BootOrderLastIndex                    = (UINTN) (*BootOrderListSize / sizeof (UINT16));
+  NewBootOrderList[BootOrderLastIndex]  = CurrentBootOptionNo;
+  *BootOrderListSize += sizeof (UINT16);
+  *BootOrderList = NewBootOrderList;
+
+  FreePool (NewBbsDevPathNode);
+  FreePool (CurrentBbsDevPath);
+  return Status;
+}
+
+/**
+  Check if the boot option is a legacy one.
+
+  @param BootOptionVar   The boot option data payload.
+  @param BbsEntry        The BBS Table.
+  @param BbsIndex        The table index.
+
+  @retval TRUE           It is a legacy boot option.
+  @retval FALSE          It is not a legacy boot option.
+
+**/
+BOOLEAN
+BdsIsLegacyBootOption (
+  IN UINT8                 *BootOptionVar,
+  OUT BBS_TABLE            **BbsEntry,
+  OUT UINT16               *BbsIndex
+  )
+{
+  UINT8                     *Ptr;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  BOOLEAN                   Ret;
+  UINT16                    DevPathLen;
+
+  Ptr = BootOptionVar;
+  Ptr += sizeof (UINT32);
+  DevPathLen = *(UINT16 *) Ptr;
+  Ptr += sizeof (UINT16);
+  Ptr += StrSize ((UINT16 *) Ptr);
+  DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
+  if ((BBS_DEVICE_PATH == DevicePath->Type) && (BBS_BBS_DP == DevicePath->SubType)) {
+    Ptr += DevPathLen;
+    *BbsEntry = (BBS_TABLE *) Ptr;
+    Ptr += sizeof (BBS_TABLE);
+    *BbsIndex = *(UINT16 *) Ptr;
+    Ret       = TRUE;
+  } else {
+    *BbsEntry = NULL;
+    Ret       = FALSE;
+  }
+
+  return Ret;
+}
+
+/**
+  Delete all the invalid legacy boot options.
+
+  @retval EFI_SUCCESS             All invalide legacy boot options are deleted.
+  @retval EFI_OUT_OF_RESOURCES    Fail to allocate necessary memory.
+  @retval EFI_NOT_FOUND           Fail to retrive variable of boot order.
+**/
+EFI_STATUS
+EFIAPI
+BdsDeleteAllInvalidLegacyBootOptions (
+  VOID
+  )
+{
+  UINT16                    *BootOrder;
+  UINT8                     *BootOptionVar;
+  UINTN                     BootOrderSize;
+  UINTN                     BootOptionSize;
+  EFI_STATUS                Status;
+  UINT16                    HddCount;
+  UINT16                    BbsCount;
+  HDD_INFO                  *LocalHddInfo;
+  BBS_TABLE                 *LocalBbsTable;
+  BBS_TABLE                 *BbsEntry;
+  UINT16                    BbsIndex;
+  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;
+  UINTN                     Index;
+  UINT16                    BootOption[10];
+  UINT16                    BootDesc[100];
+  BOOLEAN                   DescStringMatch;
+
+  Status        = EFI_SUCCESS;
+  BootOrder     = NULL;
+  BootOrderSize = 0;
+  HddCount      = 0;
+  BbsCount      = 0;
+  LocalHddInfo  = NULL;
+  LocalBbsTable = NULL;
+  BbsEntry      = NULL;
+
+  Status        = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  BootOrder = BdsLibGetVariableAndSize (
+                L"BootOrder",
+                &gEfiGlobalVariableGuid,
+                &BootOrderSize
+                );
+  if (BootOrder == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  LegacyBios->GetBbsInfo (
+                LegacyBios,
+                &HddCount,
+                &LocalHddInfo,
+                &BbsCount,
+                &LocalBbsTable
+                );
+
+  Index = 0;
+  while (Index < BootOrderSize / sizeof (UINT16)) {
+    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);
+    BootOptionVar = BdsLibGetVariableAndSize (
+                      BootOption,
+                      &gEfiGlobalVariableGuid,
+                      &BootOptionSize
+                      );
+    if (NULL == BootOptionVar) {
+      BootOptionSize = 0;
+      Status = gRT->GetVariable (
+                      BootOption,
+                      &gEfiGlobalVariableGuid,
+                      NULL,
+                      &BootOptionSize,
+                      BootOptionVar
+                      );
+      if (Status == EFI_NOT_FOUND) {
+        //
+        // Update BootOrder
+        //
+        BdsDeleteBootOption (
+          BootOrder[Index],
+          BootOrder,
+          &BootOrderSize
+          );
+        continue;
+      } else {
+        FreePool (BootOrder);
+        return EFI_OUT_OF_RESOURCES;
+      }
+    }
+  
+    //
+    // Skip Non-Legacy boot option
+    // 
+    if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, &BbsIndex)) {
+      if (BootOptionVar!= NULL) {
+        FreePool (BootOptionVar);
+      }
+      Index++;
+      continue;
+    }
+
+    if (BbsIndex < BbsCount) {
+      //
+      // Check if BBS Description String is changed
+      //
+      DescStringMatch = FALSE;
+      BdsBuildLegacyDevNameString (
+        &LocalBbsTable[BbsIndex],
+        BbsIndex,
+        sizeof (BootDesc),
+        BootDesc
+        );
+
+      if (StrCmp (BootDesc, (UINT16*)(BootOptionVar + sizeof (UINT32) + sizeof (UINT16))) == 0) {
+        DescStringMatch = TRUE;
+      }
+
+      if (!((LocalBbsTable[BbsIndex].BootPriority == BBS_IGNORE_ENTRY) ||
+            (LocalBbsTable[BbsIndex].BootPriority == BBS_DO_NOT_BOOT_FROM)) &&
+          (LocalBbsTable[BbsIndex].DeviceType == BbsEntry->DeviceType) &&
+          DescStringMatch) {
+        Index++;
+        continue;
+      }
+    }
+
+    if (BootOptionVar != NULL) {
+      FreePool (BootOptionVar);
+    }
+    //
+    // should delete
+    //
+    BdsDeleteBootOption (
+      BootOrder[Index],
+      BootOrder,
+      &BootOrderSize
+      );
+  }
+
+  //
+  // Adjust the number of boot options.
+  //
+  Status = gRT->SetVariable (
+                  L"BootOrder",
+                  &gEfiGlobalVariableGuid,
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                  BootOrderSize,
+                  BootOrder
+                  );
+  //
+  // Shrinking variable with existing variable implementation shouldn't fail.
+  //
+  ASSERT_EFI_ERROR (Status);
+  FreePool (BootOrder);
+
+  return Status;
+}
+
+/**
+  Find all legacy boot option by device type.
+
+  @param BootOrder       The boot order array.
+  @param BootOptionNum   The number of boot option.
+  @param DevType         Device type.
+  @param DevName         Device name.
+  @param Attribute       The boot option attribute.
+  @param BbsIndex        The BBS table index.
+  @param OptionNumber    The boot option index.
+
+  @retval TRUE           The Legacy boot option is found.
+  @retval FALSE          The legacy boot option is not found.
+
+**/
+BOOLEAN
+BdsFindLegacyBootOptionByDevTypeAndName (
+  IN UINT16                 *BootOrder,
+  IN UINTN                  BootOptionNum,
+  IN UINT16                 DevType,
+  IN CHAR16                 *DevName,
+  OUT UINT32                *Attribute,
+  OUT UINT16                *BbsIndex,
+  OUT UINT16                *OptionNumber
+  )
+{
+  UINTN     Index;
+  CHAR16    BootOption[9];
+  UINTN     BootOptionSize;
+  UINT8     *BootOptionVar;
+  BBS_TABLE *BbsEntry;
+  BOOLEAN   Found;
+
+  BbsEntry  = NULL;
+  Found     = FALSE;
+
+  if (NULL == BootOrder) {
+    return Found;
+  }
+
+  //
+  // Loop all boot option from variable
+  //
+  for (Index = 0; Index < BootOptionNum; Index++) {
+    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", (UINTN) BootOrder[Index]);
+    BootOptionVar = BdsLibGetVariableAndSize (
+                      BootOption,
+                      &gEfiGlobalVariableGuid,
+                      &BootOptionSize
+                      );
+    if (NULL == BootOptionVar) {
+      continue;
+    }
+
+    //
+    // Skip Non-legacy boot option
+    //
+    if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, BbsIndex)) {
+      FreePool (BootOptionVar);
+      continue;
+    }
+
+    if (
+        (BbsEntry->DeviceType != DevType) ||
+        (StrCmp (DevName, (CHAR16*)(BootOptionVar + sizeof (UINT32) + sizeof (UINT16))) != 0)
+       ) {
+      FreePool (BootOptionVar);
+      continue;
+    }
+
+    *Attribute    = *(UINT32 *) BootOptionVar;
+    *OptionNumber = BootOrder[Index];
+    Found         = TRUE;
+    FreePool (BootOptionVar);
+    break;
+  }
+
+  return Found;
+}
+
+/**
+  Create a legacy boot option.
+
+  @param BbsItem         The BBS Table entry.
+  @param Index           Index of the specified entry in BBS table.
+  @param BootOrderList   The boot order list.
+  @param BootOrderListSize The size of boot order list.
+
+  @retval EFI_OUT_OF_RESOURCE  No enough memory.
+  @retval EFI_SUCCESS          The function complete successfully.
+  @return Other value if the legacy boot option is not created.
+
+**/
+EFI_STATUS
+BdsCreateOneLegacyBootOption (
+  IN BBS_TABLE              *BbsItem,
+  IN UINTN                  Index,
+  IN OUT UINT16             **BootOrderList,
+  IN OUT UINTN              *BootOrderListSize
+  )
+{
+  BBS_BBS_DEVICE_PATH       BbsDevPathNode;
+  EFI_STATUS                Status;
+  EFI_DEVICE_PATH_PROTOCOL  *DevPath;
+
+  DevPath                       = NULL;
+
+  //
+  // Create device path node.
+  //
+  BbsDevPathNode.Header.Type    = BBS_DEVICE_PATH;
+  BbsDevPathNode.Header.SubType = BBS_BBS_DP;
+  SetDevicePathNodeLength (&BbsDevPathNode.Header, sizeof (BBS_BBS_DEVICE_PATH));
+  BbsDevPathNode.DeviceType = BbsItem->DeviceType;
+  CopyMem (&BbsDevPathNode.StatusFlag, &BbsItem->StatusFlags, sizeof (UINT16));
+
+  DevPath = AppendDevicePathNode (
+              NULL,
+              (EFI_DEVICE_PATH_PROTOCOL *) &BbsDevPathNode
+              );
+  if (NULL == DevPath) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Status = BdsCreateLegacyBootOption (
+            BbsItem,
+            DevPath,
+            Index,
+            BootOrderList,
+            BootOrderListSize
+            );
+  BbsItem->BootPriority = 0x00;
+
+  FreePool (DevPath);
+
+  return Status;
+}
+
+/**
+  Add the legacy boot options from BBS table if they do not exist.
+
+  @retval EFI_SUCCESS          The boot options are added successfully 
+                               or they are already in boot options.
+  @retval EFI_NOT_FOUND        No legacy boot options is found.
+  @retval EFI_OUT_OF_RESOURCE  No enough memory.
+  @return Other value          LegacyBoot options are not added.
+**/
+EFI_STATUS
+EFIAPI
+BdsAddNonExistingLegacyBootOptions (
+  VOID
+  )
+{
+  UINT16                    *BootOrder;
+  UINTN                     BootOrderSize;
+  EFI_STATUS                Status;
+  CHAR16                    Desc[100];
+  UINT16                    HddCount;
+  UINT16                    BbsCount;
+  HDD_INFO                  *LocalHddInfo;
+  BBS_TABLE                 *LocalBbsTable;
+  UINT16                    BbsIndex;
+  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;
+  UINT16                    Index;
+  UINT32                    Attribute;
+  UINT16                    OptionNumber;
+  BOOLEAN                   Exist;
+
+  HddCount      = 0;
+  BbsCount      = 0;
+  LocalHddInfo  = NULL;
+  LocalBbsTable = NULL;
+
+  Status        = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  LegacyBios->GetBbsInfo (
+                LegacyBios,
+                &HddCount,
+                &LocalHddInfo,
+                &BbsCount,
+                &LocalBbsTable
+                );
+
+  BootOrder = BdsLibGetVariableAndSize (
+                L"BootOrder",
+                &gEfiGlobalVariableGuid,
+                &BootOrderSize
+                );
+  if (BootOrder == NULL) {
+    BootOrderSize = 0;
+  }
+
+  for (Index = 0; Index < BbsCount; Index++) {
+    if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||
+        (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)
+        ) {
+      continue;
+    }
+
+    BdsBuildLegacyDevNameString (&LocalBbsTable[Index], Index, sizeof (Desc), Desc);
+
+    Exist = BdsFindLegacyBootOptionByDevTypeAndName (
+              BootOrder,
+              BootOrderSize / sizeof (UINT16),
+              LocalBbsTable[Index].DeviceType,
+              Desc,
+              &Attribute,
+              &BbsIndex,
+              &OptionNumber
+              );
+    if (!Exist) {
+      //
+      // Not found such type of legacy device in boot options or we found but it's disabled
+      // so we have to create one and put it to the tail of boot order list
+      //
+      Status = BdsCreateOneLegacyBootOption (
+                &LocalBbsTable[Index],
+                Index,
+                &BootOrder,
+                &BootOrderSize
+                );
+      if (!EFI_ERROR (Status)) {
+        ASSERT (BootOrder != NULL);
+        BbsIndex     = Index;
+        OptionNumber = BootOrder[BootOrderSize / sizeof (UINT16) - 1];
+      }
+    }
+
+    ASSERT (BbsIndex == Index);
+  }
+
+  Status = gRT->SetVariable (
+                  L"BootOrder",
+                  &gEfiGlobalVariableGuid,
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                  BootOrderSize,
+                  BootOrder
+                  );
+  if (BootOrder != NULL) {
+    FreePool (BootOrder);
+  }
+
+  return Status;
+}
+
+/**
+  Fill the device order buffer.
+
+  @param BbsTable        The BBS table.
+  @param BbsType         The BBS Type.
+  @param BbsCount        The BBS Count.
+  @param Buf             device order buffer.
+
+  @return The device order buffer.
+
+**/
+UINT16 *
+BdsFillDevOrderBuf (
+  IN BBS_TABLE                    *BbsTable,
+  IN BBS_TYPE                     BbsType,
+  IN UINTN                        BbsCount,
+  OUT UINT16                      *Buf
+  )
+{
+  UINTN Index;
+
+  for (Index = 0; Index < BbsCount; Index++) {
+    if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) {
+      continue;
+    }
+
+    if (BbsTable[Index].DeviceType != BbsType) {
+      continue;
+    }
+
+    *Buf = (UINT16) (Index & 0xFF);
+    Buf++;
+  }
+
+  return Buf;
+}
+
+/**
+  Create the device order buffer.
+
+  @param BbsTable        The BBS table.
+  @param BbsCount        The BBS Count.
+
+  @retval EFI_SUCCES             The buffer is created and the EFI variable named 
+                                 VAR_LEGACY_DEV_ORDER and gEfiLegacyDevOrderVariableGuid is
+                                 set correctly.
+  @retval EFI_OUT_OF_RESOURCES   Memmory or storage is not enough.
+  @retval EFI_DEVICE_ERROR       Fail to add the device order into EFI variable fail
+                                 because of hardware error.
+**/
+EFI_STATUS
+BdsCreateDevOrder (
+  IN BBS_TABLE                  *BbsTable,
+  IN UINT16                     BbsCount
+  )
+{
+  UINTN                       Index;
+  UINTN                       FDCount;
+  UINTN                       HDCount;
+  UINTN                       CDCount;
+  UINTN                       NETCount;
+  UINTN                       BEVCount;
+  UINTN                       TotalSize;
+  UINTN                       HeaderSize;
+  LEGACY_DEV_ORDER_ENTRY      *DevOrder;
+  LEGACY_DEV_ORDER_ENTRY      *DevOrderPtr;
+  EFI_STATUS                  Status;
+
+  FDCount     = 0;
+  HDCount     = 0;
+  CDCount     = 0;
+  NETCount    = 0;
+  BEVCount    = 0;
+  TotalSize   = 0;
+  HeaderSize  = sizeof (BBS_TYPE) + sizeof (UINT16);
+  DevOrder    = NULL;
+  Status      = EFI_SUCCESS;
+
+  //
+  // Count all boot devices
+  //
+  for (Index = 0; Index < BbsCount; Index++) {
+    if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) {
+      continue;
+    }
+
+    switch (BbsTable[Index].DeviceType) {
+    case BBS_FLOPPY:
+      FDCount++;
+      break;
+
+    case BBS_HARDDISK:
+      HDCount++;
+      break;
+
+    case BBS_CDROM:
+      CDCount++;
+      break;
+
+    case BBS_EMBED_NETWORK:
+      NETCount++;
+      break;
+
+    case BBS_BEV_DEVICE:
+      BEVCount++;
+      break;
+
+    default:
+      break;
+    }
+  }
+
+  TotalSize += (HeaderSize + sizeof (UINT16) * FDCount);
+  TotalSize += (HeaderSize + sizeof (UINT16) * HDCount);
+  TotalSize += (HeaderSize + sizeof (UINT16) * CDCount);
+  TotalSize += (HeaderSize + sizeof (UINT16) * NETCount);
+  TotalSize += (HeaderSize + sizeof (UINT16) * BEVCount);
+
+  //
+  // Create buffer to hold all boot device order
+  //
+  DevOrder = AllocateZeroPool (TotalSize);
+  if (NULL == DevOrder) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  DevOrderPtr          = DevOrder;
+
+  DevOrderPtr->BbsType = BBS_FLOPPY;
+  DevOrderPtr->Length  = (UINT16) (sizeof (DevOrderPtr->Length) + FDCount * sizeof (UINT16));
+  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_FLOPPY, BbsCount, DevOrderPtr->Data);
+
+  DevOrderPtr->BbsType = BBS_HARDDISK;
+  DevOrderPtr->Length  = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));
+  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_HARDDISK, BbsCount, DevOrderPtr->Data);
+  
+  DevOrderPtr->BbsType = BBS_CDROM;
+  DevOrderPtr->Length  = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));
+  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_CDROM, BbsCount, DevOrderPtr->Data);
+  
+  DevOrderPtr->BbsType = BBS_EMBED_NETWORK;
+  DevOrderPtr->Length  = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));
+  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_EMBED_NETWORK, BbsCount, DevOrderPtr->Data);
+
+  DevOrderPtr->BbsType = BBS_BEV_DEVICE;
+  DevOrderPtr->Length  = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));
+  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_BEV_DEVICE, BbsCount, DevOrderPtr->Data);
+
+  ASSERT (TotalSize == (UINTN) ((UINT8 *) DevOrderPtr - (UINT8 *) DevOrder));
+
+  //
+  // Save device order for legacy boot device to variable.
+  //
+  Status = gRT->SetVariable (
+                  VAR_LEGACY_DEV_ORDER,
+                  &gEfiLegacyDevOrderVariableGuid,
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                  TotalSize,
+                  DevOrder
+                  );
+  FreePool (DevOrder);
+
+  return Status;
+}
+
+/**
+  Add the legacy boot devices from BBS table into 
+  the legacy device boot order.
+
+  @retval EFI_SUCCESS           The boot devices are added successfully.
+  @retval EFI_NOT_FOUND         The legacy boot devices are not found.
+  @retval EFI_OUT_OF_RESOURCES  Memmory or storage is not enough.
+  @retval EFI_DEVICE_ERROR      Fail to add the legacy device boot order into EFI variable
+                                because of hardware error.
+**/
+EFI_STATUS
+EFIAPI
+BdsUpdateLegacyDevOrder (
+  VOID
+  )
+{
+  LEGACY_DEV_ORDER_ENTRY      *DevOrder;
+  LEGACY_DEV_ORDER_ENTRY      *NewDevOrder;
+  LEGACY_DEV_ORDER_ENTRY      *Ptr;
+  LEGACY_DEV_ORDER_ENTRY      *NewPtr;
+  UINTN                       DevOrderSize;
+  EFI_LEGACY_BIOS_PROTOCOL    *LegacyBios;
+  EFI_STATUS                  Status;
+  UINT16                      HddCount;
+  UINT16                      BbsCount;
+  HDD_INFO                    *LocalHddInfo;
+  BBS_TABLE                   *LocalBbsTable;
+  UINTN                       Index;
+  UINTN                       Index2;
+  UINTN                       *Idx;
+  UINTN                       FDCount;
+  UINTN                       HDCount;
+  UINTN                       CDCount;
+  UINTN                       NETCount;
+  UINTN                       BEVCount;
+  UINTN                       TotalSize;
+  UINTN                       HeaderSize;
+  UINT16                      *NewFDPtr;
+  UINT16                      *NewHDPtr;
+  UINT16                      *NewCDPtr;
+  UINT16                      *NewNETPtr;
+  UINT16                      *NewBEVPtr;
+  UINT16                      *NewDevPtr;
+  UINTN                       FDIndex;
+  UINTN                       HDIndex;
+  UINTN                       CDIndex;
+  UINTN                       NETIndex;
+  UINTN                       BEVIndex;
+
+  Idx           = NULL;
+  FDCount       = 0;
+  HDCount       = 0;
+  CDCount       = 0;
+  NETCount      = 0;
+  BEVCount      = 0;
+  TotalSize     = 0;
+  HeaderSize    = sizeof (BBS_TYPE) + sizeof (UINT16);
+  FDIndex       = 0;
+  HDIndex       = 0;
+  CDIndex       = 0;
+  NETIndex      = 0;
+  BEVIndex      = 0;
+  NewDevPtr     = NULL;
+
+  Status        = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = LegacyBios->GetBbsInfo (
+                         LegacyBios,
+                         &HddCount,
+                         &LocalHddInfo,
+                         &BbsCount,
+                         &LocalBbsTable
+                         );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  DevOrder = BdsLibGetVariableAndSize (
+               VAR_LEGACY_DEV_ORDER,
+               &gEfiLegacyDevOrderVariableGuid,
+               &DevOrderSize
+               );
+  if (NULL == DevOrder) {
+    return BdsCreateDevOrder (LocalBbsTable, BbsCount);
+  }
+  //
+  // First we figure out how many boot devices with same device type respectively
+  //
+  for (Index = 0; Index < BbsCount; Index++) {
+    if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||
+        (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)
+        ) {
+      continue;
+    }
+
+    switch (LocalBbsTable[Index].DeviceType) {
+    case BBS_FLOPPY:
+      FDCount++;
+      break;
+
+    case BBS_HARDDISK:
+      HDCount++;
+      break;
+
+    case BBS_CDROM:
+      CDCount++;
+      break;
+
+    case BBS_EMBED_NETWORK:
+      NETCount++;
+      break;
+
+    case BBS_BEV_DEVICE:
+      BEVCount++;
+      break;
+
+    default:
+      break;
+    }
+  }
+
+  TotalSize += (HeaderSize + FDCount * sizeof (UINT16));
+  TotalSize += (HeaderSize + HDCount * sizeof (UINT16));
+  TotalSize += (HeaderSize + CDCount * sizeof (UINT16));
+  TotalSize += (HeaderSize + NETCount * sizeof (UINT16));
+  TotalSize += (HeaderSize + BEVCount * sizeof (UINT16));
+
+  NewDevOrder = AllocateZeroPool (TotalSize);
+  if (NULL == NewDevOrder) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+
+
+  //
+  // copy FD
+  //
+  Ptr             = DevOrder;
+  NewPtr          = NewDevOrder;
+  NewPtr->BbsType = Ptr->BbsType;
+  NewPtr->Length  = (UINT16) (sizeof (UINT16) + FDCount * sizeof (UINT16));
+  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
+    if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_FLOPPY
+        ) {
+      continue;
+    }
+
+    NewPtr->Data[FDIndex] = Ptr->Data[Index];
+    FDIndex++;
+  }
+  NewFDPtr = NewPtr->Data;
+
+  //
+  // copy HD
+  //
+  Ptr             = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);
+  NewPtr          = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);
+  NewPtr->BbsType = Ptr->BbsType;
+  NewPtr->Length  = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));
+  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
+    if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_HARDDISK
+        ) {
+      continue;
+    }
+
+    NewPtr->Data[HDIndex] = Ptr->Data[Index];
+    HDIndex++;
+  }
+  NewHDPtr = NewPtr->Data;
+
+  //
+  // copy CD
+  //
+  Ptr    = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);
+  NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);
+  NewPtr->BbsType = Ptr->BbsType;
+  NewPtr->Length  = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));
+  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
+    if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_CDROM
+        ) {
+      continue;
+    }
+
+    NewPtr->Data[CDIndex] = Ptr->Data[Index];
+    CDIndex++;
+  }
+  NewCDPtr = NewPtr->Data;
+
+  //
+  // copy NET
+  //
+  Ptr    = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);
+  NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);
+  NewPtr->BbsType = Ptr->BbsType;
+  NewPtr->Length  = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));
+  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
+    if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_EMBED_NETWORK
+        ) {
+      continue;
+    }
+
+    NewPtr->Data[NETIndex] = Ptr->Data[Index];
+    NETIndex++;
+  }
+  NewNETPtr = NewPtr->Data;
+  
+  //
+  // copy BEV
+  //
+  Ptr    = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);
+  NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);
+  NewPtr->BbsType = Ptr->BbsType;
+  NewPtr->Length  = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));
+  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
+    if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||
+        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_BEV_DEVICE
+        ) {
+      continue;
+    }
+
+    NewPtr->Data[BEVIndex] = Ptr->Data[Index];
+    BEVIndex++;
+  }
+  NewBEVPtr = NewPtr->Data;
+
+  for (Index = 0; Index < BbsCount; Index++) {
+    if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||
+        (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)
+        ) {
+      continue;
+    }
+
+    switch (LocalBbsTable[Index].DeviceType) {
+    case BBS_FLOPPY:
+      Idx       = &FDIndex;
+      NewDevPtr = NewFDPtr;
+      break;
+
+    case BBS_HARDDISK:
+      Idx       = &HDIndex;
+      NewDevPtr = NewHDPtr;
+      break;
+
+    case BBS_CDROM:
+      Idx       = &CDIndex;
+      NewDevPtr = NewCDPtr;
+      break;
+
+    case BBS_EMBED_NETWORK:
+      Idx       = &NETIndex;
+      NewDevPtr = NewNETPtr;
+      break;
+
+    case BBS_BEV_DEVICE:
+      Idx       = &BEVIndex;
+      NewDevPtr = NewBEVPtr;
+      break;
+
+    default:
+      Idx = NULL;
+      break;
+    }
+    //
+    // at this point we have copied those valid indexes to new buffer
+    // and we should check if there is any new appeared boot device
+    //
+    if (Idx != NULL) {
+      for (Index2 = 0; Index2 < *Idx; Index2++) {
+        if ((NewDevPtr[Index2] & 0xFF) == (UINT16) Index) {
+          break;
+        }
+      }
+
+      if (Index2 == *Idx) {
+        //
+        // Index2 == *Idx means we didn't find Index
+        // so Index is a new appeared device's index in BBS table
+        // insert it before disabled indexes.
+        //
+        for (Index2 = 0; Index2 < *Idx; Index2++) {
+          if ((NewDevPtr[Index2] & 0xFF00) == 0xFF00) {
+            break;
+          }
+        }
+        CopyMem (&NewDevPtr[Index2 + 1], &NewDevPtr[Index2], (*Idx - Index2) * sizeof (UINT16));
+        NewDevPtr[Index2] = (UINT16) (Index & 0xFF);
+        (*Idx)++;
+      }
+    }
+  }
+
+  FreePool (DevOrder);
+
+  Status = gRT->SetVariable (
+                  VAR_LEGACY_DEV_ORDER,
+                  &gEfiLegacyDevOrderVariableGuid,
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                  TotalSize,
+                  NewDevOrder
+                  );
+  FreePool (NewDevOrder);
+
+  return Status;
+}
+
+/**
+  Set Boot Priority for specified device type.
+
+  @param DeviceType      The device type.
+  @param BbsIndex        The BBS index to set the highest priority. Ignore when -1.
+  @param LocalBbsTable   The BBS table.
+  @param Priority        The prority table.
+
+  @retval EFI_SUCCESS           The function completes successfully.
+  @retval EFI_NOT_FOUND         Failed to find device.
+  @retval EFI_OUT_OF_RESOURCES  Failed to get the efi variable of device order.
+
+**/
+EFI_STATUS
+BdsSetBootPriority4SameTypeDev (
+  IN UINT16                                              DeviceType,
+  IN UINTN                                               BbsIndex,
+  IN OUT BBS_TABLE                                       *LocalBbsTable,
+  IN OUT UINT16                                          *Priority
+  )
+{
+  LEGACY_DEV_ORDER_ENTRY      *DevOrder;
+  LEGACY_DEV_ORDER_ENTRY      *DevOrderPtr;
+  UINTN                       DevOrderSize;
+  UINTN                       Index;
+
+  DevOrder = BdsLibGetVariableAndSize (
+               VAR_LEGACY_DEV_ORDER,
+               &gEfiLegacyDevOrderVariableGuid,
+               &DevOrderSize
+               );
+  if (NULL == DevOrder) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  DevOrderPtr = DevOrder;
+  while ((UINT8 *) DevOrderPtr < (UINT8 *) DevOrder + DevOrderSize) {
+    if (DevOrderPtr->BbsType == DeviceType) {
+      break;
+    }
+
+    DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) ((UINTN) DevOrderPtr + sizeof (BBS_TYPE) + DevOrderPtr->Length);
+  }
+
+  if ((UINT8 *) DevOrderPtr >= (UINT8 *) DevOrder + DevOrderSize) {
+    FreePool (DevOrder);
+    return EFI_NOT_FOUND;
+  }
+
+  if (BbsIndex != (UINTN) -1) {
+    LocalBbsTable[BbsIndex].BootPriority = *Priority;
+    (*Priority)++;
+  }
+  //
+  // If the high byte of the DevIndex is 0xFF, it indicates that this device has been disabled.
+  //
+  for (Index = 0; Index < DevOrderPtr->Length / sizeof (UINT16) - 1; Index++) {
+    if ((DevOrderPtr->Data[Index] & 0xFF00) == 0xFF00) {
+      //
+      // LocalBbsTable[DevIndex[Index] & 0xFF].BootPriority = BBS_DISABLED_ENTRY;
+      //
+    } else if (DevOrderPtr->Data[Index] != BbsIndex) {
+      LocalBbsTable[DevOrderPtr->Data[Index]].BootPriority = *Priority;
+      (*Priority)++;
+    }
+  }
+
+  FreePool (DevOrder);
+  return EFI_SUCCESS;
+}
+
+/**
+  Print the BBS Table.
+
+  @param LocalBbsTable   The BBS table.
+  @param BbsCount        The count of entry in BBS table.
+**/
+VOID
+PrintBbsTable (
+  IN BBS_TABLE  *LocalBbsTable,
+  IN UINT16     BbsCount
+  )
+{
+  UINT16  Idx;
+
+  DEBUG ((DEBUG_ERROR, "\n"));
+  DEBUG ((DEBUG_ERROR, " NO  Prio bb/dd/ff cl/sc Type Stat segm:offs\n"));
+  DEBUG ((DEBUG_ERROR, "=============================================\n"));
+  for (Idx = 0; Idx < BbsCount; Idx++) {
+    if ((LocalBbsTable[Idx].BootPriority == BBS_IGNORE_ENTRY) ||
+        (LocalBbsTable[Idx].BootPriority == BBS_DO_NOT_BOOT_FROM) ||
+        (LocalBbsTable[Idx].BootPriority == BBS_LOWEST_PRIORITY)
+        ) {
+      continue;
+    }
+
+    DEBUG (
+      (DEBUG_ERROR,
+      " %02x: %04x %02x/%02x/%02x %02x/%02x %04x %04x %04x:%04x\n",
+      (UINTN) Idx,
+      (UINTN) LocalBbsTable[Idx].BootPriority,
+      (UINTN) LocalBbsTable[Idx].Bus,
+      (UINTN) LocalBbsTable[Idx].Device,
+      (UINTN) LocalBbsTable[Idx].Function,
+      (UINTN) LocalBbsTable[Idx].Class,
+      (UINTN) LocalBbsTable[Idx].SubClass,
+      (UINTN) LocalBbsTable[Idx].DeviceType,
+      (UINTN) * (UINT16 *) &LocalBbsTable[Idx].StatusFlags,
+      (UINTN) LocalBbsTable[Idx].BootHandlerSegment,
+      (UINTN) LocalBbsTable[Idx].BootHandlerOffset,
+      (UINTN) ((LocalBbsTable[Idx].MfgStringSegment << 4) + LocalBbsTable[Idx].MfgStringOffset),
+      (UINTN) ((LocalBbsTable[Idx].DescStringSegment << 4) + LocalBbsTable[Idx].DescStringOffset))
+      );
+  }
+
+  DEBUG ((DEBUG_ERROR, "\n"));
+}
+
+/**
+  Set the boot priority for BBS entries based on boot option entry and boot order.
+
+  @param  Entry             The boot option is to be checked for refresh BBS table.
+  
+  @retval EFI_SUCCESS           The boot priority for BBS entries is refreshed successfully.
+  @retval EFI_NOT_FOUND         BBS entries can't be found.
+  @retval EFI_OUT_OF_RESOURCES  Failed to get the legacy device boot order.
+**/
+EFI_STATUS
+EFIAPI
+BdsRefreshBbsTableForBoot (
+  IN BDS_COMMON_OPTION        *Entry
+  )
+{
+  EFI_STATUS                Status;
+  UINT16                    BbsIndex;
+  UINT16                    HddCount;
+  UINT16                    BbsCount;
+  HDD_INFO                  *LocalHddInfo;
+  BBS_TABLE                 *LocalBbsTable;
+  UINT16                    DevType;
+  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;
+  UINTN                     Index;
+  UINT16                    Priority;
+  UINT16                    *BootOrder;
+  UINTN                     BootOrderSize;
+  UINT8                     *BootOptionVar;
+  UINTN                     BootOptionSize;
+  CHAR16                    BootOption[9];
+  UINT8                     *Ptr;
+  UINT16                    DevPathLen;
+  EFI_DEVICE_PATH_PROTOCOL  *DevPath;
+  UINT16                    *DeviceType;
+  UINTN                     DeviceTypeCount;
+  UINTN                     DeviceTypeIndex;
+
+  HddCount      = 0;
+  BbsCount      = 0;
+  LocalHddInfo  = NULL;
+  LocalBbsTable = NULL;
+  DevType       = BBS_UNKNOWN;
+
+  Status        = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  LegacyBios->GetBbsInfo (
+                LegacyBios,
+                &HddCount,
+                &LocalHddInfo,
+                &BbsCount,
+                &LocalBbsTable
+                );
+  //
+  // First, set all the present devices' boot priority to BBS_UNPRIORITIZED_ENTRY
+  // We will set them according to the settings setup by user
+  //
+  for (Index = 0; Index < BbsCount; Index++) {
+    if (!((BBS_IGNORE_ENTRY == LocalBbsTable[Index].BootPriority) ||
+        (BBS_DO_NOT_BOOT_FROM == LocalBbsTable[Index].BootPriority) ||
+         (BBS_LOWEST_PRIORITY == LocalBbsTable[Index].BootPriority))) {
+      LocalBbsTable[Index].BootPriority = BBS_UNPRIORITIZED_ENTRY;
+    }
+  }
+  //
+  // boot priority always starts at 0
+  //
+  Priority = 0;
+  if (Entry->LoadOptionsSize == sizeof (BBS_TABLE) + sizeof (UINT16)) {
+    //
+    // If Entry stands for a legacy boot option, we prioritize the devices with the same type first.
+    //
+    DevType  = ((BBS_TABLE *) Entry->LoadOptions)->DeviceType;
+    BbsIndex = *(UINT16 *) ((BBS_TABLE *) Entry->LoadOptions + 1);
+    Status = BdsSetBootPriority4SameTypeDev (
+              DevType,
+              BbsIndex,
+              LocalBbsTable,
+              &Priority
+              );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+  //
+  // we have to set the boot priority for other BBS entries with different device types
+  //
+  BootOrder = BdsLibGetVariableAndSize (
+                L"BootOrder",
+                &gEfiGlobalVariableGuid,
+                &BootOrderSize
+                );
+  DeviceType = AllocatePool (BootOrderSize + sizeof (UINT16));
+  ASSERT (DeviceType != NULL);
+
+  DeviceType[0]   = DevType;
+  DeviceTypeCount = 1;
+  for (Index = 0; ((BootOrder != NULL) && (Index < BootOrderSize / sizeof (UINT16))); Index++) {
+    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);
+    BootOptionVar = BdsLibGetVariableAndSize (
+                      BootOption,
+                      &gEfiGlobalVariableGuid,
+                      &BootOptionSize
+                      );
+    if (NULL == BootOptionVar) {
+      continue;
+    }
+
+    Ptr = BootOptionVar;
+
+    Ptr += sizeof (UINT32);
+    DevPathLen = *(UINT16 *) Ptr;
+    Ptr += sizeof (UINT16);
+    Ptr += StrSize ((UINT16 *) Ptr);
+    DevPath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
+    if (BBS_DEVICE_PATH != DevPath->Type || BBS_BBS_DP != DevPath->SubType) {
+      FreePool (BootOptionVar);
+      continue;
+    }
+
+    Ptr += DevPathLen;
+    DevType = ((BBS_TABLE *) Ptr)->DeviceType;
+    for (DeviceTypeIndex = 0; DeviceTypeIndex < DeviceTypeCount; DeviceTypeIndex++) {
+      if (DeviceType[DeviceTypeIndex] == DevType) {
+        break;
+      }
+    }
+    if (DeviceTypeIndex < DeviceTypeCount) {
+      //
+      // We don't want to process twice for a device type
+      //
+      FreePool (BootOptionVar);
+      continue;
+    }
+
+    DeviceType[DeviceTypeCount] = DevType;
+    DeviceTypeCount++;
+
+    Status = BdsSetBootPriority4SameTypeDev (
+              DevType,
+              (UINTN) -1,
+              LocalBbsTable,
+              &Priority
+              );
+    FreePool (BootOptionVar);
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+  }
+
+  FreePool (DeviceType);
+
+  if (BootOrder != NULL) {
+    FreePool (BootOrder);
+  }
+
+  DEBUG_CODE_BEGIN();
+    PrintBbsTable (LocalBbsTable, BbsCount);
+  DEBUG_CODE_END();
+
+  return Status;
+}
+
+/**
+  Boot the legacy system with the boot option
+
+  @param  Option                 The legacy boot option which have BBS device path
+
+  @retval EFI_UNSUPPORTED        There is no legacybios protocol, do not support
+                                 legacy boot.
+  @retval EFI_STATUS             Return the status of LegacyBios->LegacyBoot ().
+
+**/
+EFI_STATUS
+BdsLibDoLegacyBoot (
+  IN  BDS_COMMON_OPTION           *Option
+  )
+{
+  EFI_STATUS                Status;
+  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;
+  EFI_EVENT                 LegacyBootEvent;
+
+  Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);
+  if (EFI_ERROR (Status)) {
+    //
+    // If no LegacyBios protocol we do not support legacy boot
+    //
+    return EFI_UNSUPPORTED;
+  }
+  //
+  // Notes: if we separate the int 19, then we don't need to refresh BBS
+  //
+  BdsRefreshBbsTableForBoot (Option);
+
+  //
+  // Write boot to OS performance data for legacy boot.
+  //
+  PERF_CODE (
+    //
+    // Create an event to be signalled when Legacy Boot occurs to write performance data.
+    //
+    Status = EfiCreateEventLegacyBootEx(
+               TPL_NOTIFY,
+               BmEndOfBdsPerfCode,
+               NULL, 
+               &LegacyBootEvent
+               );
+    ASSERT_EFI_ERROR (Status);
+  );
+
+  DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Legacy Boot: %S\n", Option->Description));
+  return LegacyBios->LegacyBoot (
+                      LegacyBios,
+                      (BBS_BBS_DEVICE_PATH *) Option->DevicePath,
+                      Option->LoadOptionsSize,
+                      Option->LoadOptions
+                      );
+}
+
+/**
+  Internal function to check if the input boot option is a valid EFI NV Boot####.
+
+  @param OptionToCheck  Boot option to be checked.
+
+  @retval TRUE      This boot option matches a valid EFI NV Boot####.
+  @retval FALSE     If not.
+
+**/
+BOOLEAN
+IsBootOptionValidNVVarialbe (
+  IN  BDS_COMMON_OPTION             *OptionToCheck
+  )
+{
+  LIST_ENTRY        TempList;
+  BDS_COMMON_OPTION *BootOption;
+  BOOLEAN           Valid;
+  CHAR16            OptionName[20];
+
+  Valid = FALSE;
+
+  InitializeListHead (&TempList);
+  UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", OptionToCheck->BootCurrent);
+
+  BootOption = BdsLibVariableToOption (&TempList, OptionName);
+  if (BootOption == NULL) {
+    return FALSE;
+  }
+
+  //
+  // If the Boot Option Number and Device Path matches, OptionToCheck matches a
+  // valid EFI NV Boot####.
+  //
+  if ((OptionToCheck->BootCurrent == BootOption->BootCurrent) &&
+      (CompareMem (OptionToCheck->DevicePath, BootOption->DevicePath, GetDevicePathSize (OptionToCheck->DevicePath)) == 0))
+      {
+    Valid = TRUE;
+  }
+
+  FreePool (BootOption);
+
+  return Valid;
+}
+
+/**
+  Check whether a USB device match the specified USB Class device path. This
+  function follows "Load Option Processing" behavior in UEFI specification.
+
+  @param UsbIo       USB I/O protocol associated with the USB device.
+  @param UsbClass    The USB Class device path to match.
+
+  @retval TRUE       The USB device match the USB Class device path.
+  @retval FALSE      The USB device does not match the USB Class device path.
+
+**/
+BOOLEAN
+BdsMatchUsbClass (
+  IN EFI_USB_IO_PROTOCOL        *UsbIo,
+  IN USB_CLASS_DEVICE_PATH      *UsbClass
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_USB_DEVICE_DESCRIPTOR     DevDesc;
+  EFI_USB_INTERFACE_DESCRIPTOR  IfDesc;
+  UINT8                         DeviceClass;
+  UINT8                         DeviceSubClass;
+  UINT8                         DeviceProtocol;
+
+  if ((DevicePathType (UsbClass) != MESSAGING_DEVICE_PATH) ||
+      (DevicePathSubType (UsbClass) != MSG_USB_CLASS_DP)){
+    return FALSE;
+  }
+
+  //
+  // Check Vendor Id and Product Id.
+  //
+  Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &DevDesc);
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+
+  if ((UsbClass->VendorId != 0xffff) &&
+      (UsbClass->VendorId != DevDesc.IdVendor)) {
+    return FALSE;
+  }
+
+  if ((UsbClass->ProductId != 0xffff) &&
+      (UsbClass->ProductId != DevDesc.IdProduct)) {
+    return FALSE;
+  }
+
+  DeviceClass    = DevDesc.DeviceClass;
+  DeviceSubClass = DevDesc.DeviceSubClass;
+  DeviceProtocol = DevDesc.DeviceProtocol;
+  if (DeviceClass == 0) {
+    //
+    // If Class in Device Descriptor is set to 0, use the Class, SubClass and
+    // Protocol in Interface Descriptor instead.
+    //
+    Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &IfDesc);
+    if (EFI_ERROR (Status)) {
+      return FALSE;
+    }
+
+    DeviceClass    = IfDesc.InterfaceClass;
+    DeviceSubClass = IfDesc.InterfaceSubClass;
+    DeviceProtocol = IfDesc.InterfaceProtocol;
+  }
+
+  //
+  // Check Class, SubClass and Protocol.
+  //
+  if ((UsbClass->DeviceClass != 0xff) &&
+      (UsbClass->DeviceClass != DeviceClass)) {
+    return FALSE;
+  }
+
+  if ((UsbClass->DeviceSubClass != 0xff) &&
+      (UsbClass->DeviceSubClass != DeviceSubClass)) {
+    return FALSE;
+  }
+
+  if ((UsbClass->DeviceProtocol != 0xff) &&
+      (UsbClass->DeviceProtocol != DeviceProtocol)) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+/**
+  Check whether a USB device match the specified USB WWID device path. This
+  function follows "Load Option Processing" behavior in UEFI specification.
+
+  @param UsbIo       USB I/O protocol associated with the USB device.
+  @param UsbWwid     The USB WWID device path to match.
+
+  @retval TRUE       The USB device match the USB WWID device path.
+  @retval FALSE      The USB device does not match the USB WWID device path.
+
+**/
+BOOLEAN
+BdsMatchUsbWwid (
+  IN EFI_USB_IO_PROTOCOL        *UsbIo,
+  IN USB_WWID_DEVICE_PATH       *UsbWwid
+  )
+{
+  EFI_STATUS                   Status;
+  EFI_USB_DEVICE_DESCRIPTOR    DevDesc;
+  EFI_USB_INTERFACE_DESCRIPTOR IfDesc;
+  UINT16                       *LangIdTable;
+  UINT16                       TableSize;
+  UINT16                       Index;
+  CHAR16                       *CompareStr;
+  UINTN                        CompareLen;
+  CHAR16                       *SerialNumberStr;
+  UINTN                        Length;
+
+  if ((DevicePathType (UsbWwid) != MESSAGING_DEVICE_PATH) ||
+      (DevicePathSubType (UsbWwid) != MSG_USB_WWID_DP )){
+    return FALSE;
+  }
+
+  //
+  // Check Vendor Id and Product Id.
+  //
+  Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &DevDesc);
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+  if ((DevDesc.IdVendor != UsbWwid->VendorId) ||
+      (DevDesc.IdProduct != UsbWwid->ProductId)) {
+    return FALSE;
+  }
+
+  //
+  // Check Interface Number.
+  //
+  Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &IfDesc);
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+  if (IfDesc.InterfaceNumber != UsbWwid->InterfaceNumber) {
+    return FALSE;
+  }
+
+  //
+  // Check Serial Number.
+  //
+  if (DevDesc.StrSerialNumber == 0) {
+    return FALSE;
+  }
+
+  //
+  // Get all supported languages.
+  //
+  TableSize = 0;
+  LangIdTable = NULL;
+  Status = UsbIo->UsbGetSupportedLanguages (UsbIo, &LangIdTable, &TableSize);
+  if (EFI_ERROR (Status) || (TableSize == 0) || (LangIdTable == NULL)) {
+    return FALSE;
+  }
+
+  //
+  // Serial number in USB WWID device path is the last 64-or-less UTF-16 characters.
+  //
+  CompareStr = (CHAR16 *) (UINTN) (UsbWwid + 1);
+  CompareLen = (DevicePathNodeLength (UsbWwid) - sizeof (USB_WWID_DEVICE_PATH)) / sizeof (CHAR16);
+  if (CompareStr[CompareLen - 1] == L'\0') {
+    CompareLen--;
+  }
+
+  //
+  // Compare serial number in each supported language.
+  //
+  for (Index = 0; Index < TableSize / sizeof (UINT16); Index++) {
+    SerialNumberStr = NULL;
+    Status = UsbIo->UsbGetStringDescriptor (
+                      UsbIo,
+                      LangIdTable[Index],
+                      DevDesc.StrSerialNumber,
+                      &SerialNumberStr
+                      );
+    if (EFI_ERROR (Status) || (SerialNumberStr == NULL)) {
+      continue;
+    }
+
+    Length = StrLen (SerialNumberStr);
+    if ((Length >= CompareLen) &&
+        (CompareMem (SerialNumberStr + Length - CompareLen, CompareStr, CompareLen * sizeof (CHAR16)) == 0)) {
+      FreePool (SerialNumberStr);
+      return TRUE;
+    }
+
+    FreePool (SerialNumberStr);
+  }
+
+  return FALSE;
+}
+
+/**
+  Find a USB device path which match the specified short-form device path start
+  with USB Class or USB WWID device path and load the boot file then return the 
+  image handle. If ParentDevicePath is NULL, this function will search in all USB
+  devices of the platform. If ParentDevicePath is not NULL,this function will only
+  search in its child devices.
+
+  @param ParentDevicePath      The device path of the parent.
+  @param ShortFormDevicePath   The USB Class or USB WWID device path to match.
+
+  @return  The image Handle if find load file from specified short-form device path
+           or NULL if not found.
+
+**/
+EFI_HANDLE *
+BdsFindUsbDevice (
+  IN EFI_DEVICE_PATH_PROTOCOL   *ParentDevicePath,
+  IN EFI_DEVICE_PATH_PROTOCOL   *ShortFormDevicePath
+  )
+{
+  EFI_STATUS                Status;
+  UINTN                     UsbIoHandleCount;
+  EFI_HANDLE                *UsbIoHandleBuffer;
+  EFI_DEVICE_PATH_PROTOCOL  *UsbIoDevicePath;
+  EFI_USB_IO_PROTOCOL       *UsbIo;
+  UINTN                     Index;
+  UINTN                     ParentSize;
+  UINTN                     Size;
+  EFI_HANDLE                ImageHandle;
+  EFI_HANDLE                Handle;
+  EFI_DEVICE_PATH_PROTOCOL  *FullDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *NextDevicePath;
+
+  FullDevicePath = NULL;
+  ImageHandle    = NULL;
+
+  //
+  // Get all UsbIo Handles.
+  //
+  UsbIoHandleCount = 0;
+  UsbIoHandleBuffer = NULL;
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiUsbIoProtocolGuid,
+                  NULL,
+                  &UsbIoHandleCount,
+                  &UsbIoHandleBuffer
+                  );
+  if (EFI_ERROR (Status) || (UsbIoHandleCount == 0) || (UsbIoHandleBuffer == NULL)) {
+    return NULL;
+  }
+
+  ParentSize = (ParentDevicePath == NULL) ? 0 : GetDevicePathSize (ParentDevicePath);
+  for (Index = 0; Index < UsbIoHandleCount; Index++) {
+    //
+    // Get the Usb IO interface.
+    //
+    Status = gBS->HandleProtocol(
+                    UsbIoHandleBuffer[Index],
+                    &gEfiUsbIoProtocolGuid,
+                    (VOID **) &UsbIo
+                    );
+    if (EFI_ERROR (Status)) {
+      continue;
+    }
+
+    UsbIoDevicePath = DevicePathFromHandle (UsbIoHandleBuffer[Index]);
+    if (UsbIoDevicePath == NULL) {
+      continue;
+    }
+
+    if (ParentDevicePath != NULL) {
+      //
+      // Compare starting part of UsbIoHandle's device path with ParentDevicePath.
+      //
+      Size = GetDevicePathSize (UsbIoDevicePath);
+      if ((Size < ParentSize) ||
+          (CompareMem (UsbIoDevicePath, ParentDevicePath, ParentSize - END_DEVICE_PATH_LENGTH) != 0)) {
+        continue;
+      }
+    }
+
+    if (BdsMatchUsbClass (UsbIo, (USB_CLASS_DEVICE_PATH *) ShortFormDevicePath) ||
+        BdsMatchUsbWwid (UsbIo, (USB_WWID_DEVICE_PATH *) ShortFormDevicePath)) {
+      //
+      // Try to find if there is the boot file in this DevicePath
+      //
+      NextDevicePath = NextDevicePathNode (ShortFormDevicePath);
+      if (!IsDevicePathEnd (NextDevicePath)) {
+        FullDevicePath = AppendDevicePath (UsbIoDevicePath, NextDevicePath);
+        //
+        // Connect the full device path, so that Simple File System protocol
+        // could be installed for this USB device.
+        //
+        BdsLibConnectDevicePath (FullDevicePath);
+        REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderLoad));
+        Status = gBS->LoadImage (
+                       TRUE,
+                       gImageHandle,
+                       FullDevicePath,
+                       NULL,
+                       0,
+                       &ImageHandle
+                       );
+        FreePool (FullDevicePath);
+      } else {
+        FullDevicePath = UsbIoDevicePath;
+        Status = EFI_NOT_FOUND;
+      }
+
+      //
+      // If we didn't find an image directly, we need to try as if it is a removable device boot option
+      // and load the image according to the default boot behavior for removable device.
+      //
+      if (EFI_ERROR (Status)) {
+        //
+        // check if there is a bootable removable media could be found in this device path ,
+        // and get the bootable media handle
+        //
+        Handle = BdsLibGetBootableHandle(UsbIoDevicePath);
+        if (Handle == NULL) {
+          continue;
+        }
+        //
+        // Load the default boot file \EFI\BOOT\boot{machinename}.EFI from removable Media
+        //  machinename is ia32, ia64, x64, ...
+        //
+        FullDevicePath = FileDevicePath (Handle, EFI_REMOVABLE_MEDIA_FILE_NAME);
+        if (FullDevicePath != NULL) {
+          REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderLoad));
+          Status = gBS->LoadImage (
+                          TRUE,
+                          gImageHandle,
+                          FullDevicePath,
+                          NULL,
+                          0,
+                          &ImageHandle
+                          );
+          if (EFI_ERROR (Status)) {
+            //
+            // The DevicePath failed, and it's not a valid
+            // removable media device.
+            //
+            continue;
+          }
+        } else {
+          continue;
+        }
+      }
+      break;
+    }
+  }
+
+  FreePool (UsbIoHandleBuffer);
+  return ImageHandle;
+}
+
+/**
+  Expand USB Class or USB WWID device path node to be full device path of a USB
+  device in platform then load the boot file on this full device path and return the 
+  image handle.
+
+  This function support following 4 cases:
+  1) Boot Option device path starts with a USB Class or USB WWID device path,
+     and there is no Media FilePath device path in the end.
+     In this case, it will follow Removable Media Boot Behavior.
+  2) Boot Option device path starts with a USB Class or USB WWID device path,
+     and ended with Media FilePath device path.
+  3) Boot Option device path starts with a full device path to a USB Host Controller,
+     contains a USB Class or USB WWID device path node, while not ended with Media
+     FilePath device path. In this case, it will follow Removable Media Boot Behavior.
+  4) Boot Option device path starts with a full device path to a USB Host Controller,
+     contains a USB Class or USB WWID device path node, and ended with Media
+     FilePath device path.
+
+  @param  DevicePath    The Boot Option device path.
+
+  @return  The image handle of boot file, or NULL if there is no boot file found in
+           the specified USB Class or USB WWID device path.
+
+**/
+EFI_HANDLE *
+BdsExpandUsbShortFormDevicePath (
+  IN EFI_DEVICE_PATH_PROTOCOL       *DevicePath
+  )
+{
+  EFI_HANDLE                *ImageHandle;
+  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *ShortFormDevicePath;
+
+  //
+  // Search for USB Class or USB WWID device path node.
+  //
+  ShortFormDevicePath = NULL;
+  ImageHandle         = NULL;
+  TempDevicePath      = DevicePath;
+  while (!IsDevicePathEnd (TempDevicePath)) {
+    if ((DevicePathType (TempDevicePath) == MESSAGING_DEVICE_PATH) &&
+        ((DevicePathSubType (TempDevicePath) == MSG_USB_CLASS_DP) ||
+         (DevicePathSubType (TempDevicePath) == MSG_USB_WWID_DP))) {
+      ShortFormDevicePath = TempDevicePath;
+      break;
+    }
+    TempDevicePath = NextDevicePathNode (TempDevicePath);
+  }
+
+  if (ShortFormDevicePath == NULL) {
+    //
+    // No USB Class or USB WWID device path node found, do nothing.
+    //
+    return NULL;
+  }
+
+  if (ShortFormDevicePath == DevicePath) {
+    //
+    // Boot Option device path starts with USB Class or USB WWID device path.
+    //
+    ImageHandle = BdsFindUsbDevice (NULL, ShortFormDevicePath);
+    if (ImageHandle == NULL) {
+      //
+      // Failed to find a match in existing devices, connect the short form USB
+      // device path and try again.
+      //
+      BdsLibConnectUsbDevByShortFormDP (0xff, ShortFormDevicePath);
+      ImageHandle = BdsFindUsbDevice (NULL, ShortFormDevicePath);
+    }
+  } else {
+    //
+    // Boot Option device path contains USB Class or USB WWID device path node.
+    //
+
+    //
+    // Prepare the parent device path for search.
+    //
+    TempDevicePath = DuplicateDevicePath (DevicePath);
+    ASSERT (TempDevicePath != NULL);
+    SetDevicePathEndNode (((UINT8 *) TempDevicePath) + ((UINTN) ShortFormDevicePath - (UINTN) DevicePath));
+
+    //
+    // The USB Host Controller device path is already in Boot Option device path
+    // and USB Bus driver already support RemainingDevicePath starts with USB
+    // Class or USB WWID device path, so just search in existing USB devices and
+    // doesn't perform ConnectController here.
+    //
+    ImageHandle = BdsFindUsbDevice (TempDevicePath, ShortFormDevicePath);
+    FreePool (TempDevicePath);
+  }
+
+  return ImageHandle;
+}
+
+/**
+  Process the boot option follow the UEFI specification and
+  special treat the legacy boot option with BBS_DEVICE_PATH.
+
+  @param  Option                 The boot option need to be processed
+  @param  DevicePath             The device path which describe where to load the
+                                 boot image or the legacy BBS device path to boot
+                                 the legacy OS
+  @param  ExitDataSize           The size of exit data.
+  @param  ExitData               Data returned when Boot image failed.
+
+  @retval EFI_SUCCESS            Boot from the input boot option successfully.
+  @retval EFI_NOT_FOUND          If the Device Path is not found in the system
+
+**/
+EFI_STATUS
+EFIAPI
+BdsLibBootViaBootOption (
+  IN  BDS_COMMON_OPTION             *Option,
+  IN  EFI_DEVICE_PATH_PROTOCOL      *DevicePath,
+  OUT UINTN                         *ExitDataSize,
+  OUT CHAR16                        **ExitData OPTIONAL
+  )
+{
+  EFI_STATUS                Status;
+  EFI_STATUS                StatusLogo;
+  EFI_HANDLE                Handle;
+  EFI_HANDLE                ImageHandle;
+  EFI_DEVICE_PATH_PROTOCOL  *FilePath;
+  EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;
+  EFI_DEVICE_PATH_PROTOCOL  *WorkingDevicePath;
+  EFI_ACPI_S3_SAVE_PROTOCOL *AcpiS3Save;
+  LIST_ENTRY                TempBootLists;
+  EFI_BOOT_LOGO_PROTOCOL    *BootLogo;
+
+  *ExitDataSize = 0;
+  *ExitData     = NULL;
+
+  //
+  // Notes: this code can be remove after the s3 script table
+  // hook on the event EVT_SIGNAL_READY_TO_BOOT or
+  // EVT_SIGNAL_LEGACY_BOOT
+  //
+  Status = gBS->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid, NULL, (VOID **) &AcpiS3Save);
+  if (!EFI_ERROR (Status)) {
+    AcpiS3Save->S3Save (AcpiS3Save, NULL);
+  }
+  //
+  // If it's Device Path that starts with a hard drive path, append it with the front part to compose a
+  // full device path
+  //
+  WorkingDevicePath = NULL;
+  if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) &&
+      (DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP)) {
+    WorkingDevicePath = BdsExpandPartitionPartialDevicePathToFull (
+                          (HARDDRIVE_DEVICE_PATH *)DevicePath
+                          );
+    if (WorkingDevicePath != NULL) {
+      DevicePath = WorkingDevicePath;
+    }
+  }
+
+  //
+  // Set Boot Current
+  //
+  if (IsBootOptionValidNVVarialbe (Option)) {
+    //
+    // For a temporary boot (i.e. a boot by selected a EFI Shell using "Boot From File"), Boot Current is actually not valid.
+    // In this case, "BootCurrent" is not created.
+    // Only create the BootCurrent variable when it points to a valid Boot#### variable.
+    //
+    SetVariableAndReportStatusCodeOnError (
+          L"BootCurrent",
+          &gEfiGlobalVariableGuid,
+          EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+          sizeof (UINT16),
+          &Option->BootCurrent
+          );
+  }
+
+  //
+  // Report Status Code to indicate ReadyToBoot event will be signalled
+  //
+  REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT));
+
+  //
+  // Signal the EVT_SIGNAL_READY_TO_BOOT event
+  //
+  EfiSignalEventReadyToBoot();
+
+  //
+  // Expand USB Class or USB WWID device path node to be full device path of a USB
+  // device in platform then load the boot file on this full device path and get the
+  // image handle.
+  //
+  ImageHandle = BdsExpandUsbShortFormDevicePath (DevicePath);
+
+  //
+  // Adjust the different type memory page number just before booting
+  // and save the updated info into the variable for next boot to use
+  //
+  BdsSetMemoryTypeInformationVariable ();
+
+  //
+  // By expanding the USB Class or WWID device path, the ImageHandle has returnned.
+  // Here get the ImageHandle for the non USB class or WWID device path.
+  //
+  if (ImageHandle == NULL) {
+    ASSERT (Option->DevicePath != NULL);
+    if ((DevicePathType (Option->DevicePath) == BBS_DEVICE_PATH) &&
+        (DevicePathSubType (Option->DevicePath) == BBS_BBS_DP)
+       ) {
+      //
+      // Check to see if we should legacy BOOT. If yes then do the legacy boot
+      //
+      return BdsLibDoLegacyBoot (Option);
+    }
+
+    //
+    // If the boot option point to Internal FV shell, make sure it is valid
+    //
+    Status = BdsLibUpdateFvFileDevicePath (&DevicePath, &gUefiShellFileGuid);
+    if (!EFI_ERROR(Status)) {
+      if (Option->DevicePath != NULL) {
+        FreePool(Option->DevicePath);
+      }
+      Option->DevicePath  = AllocateZeroPool (GetDevicePathSize (DevicePath));
+      ASSERT(Option->DevicePath != NULL);
+      CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize (DevicePath));
+      //
+      // Update the shell boot option
+      //
+      InitializeListHead (&TempBootLists);
+      BdsLibRegisterNewOption (&TempBootLists, DevicePath, L"EFI Internal Shell", L"BootOrder");
+
+      //
+      // free the temporary device path created by BdsLibUpdateFvFileDevicePath()
+      //
+      FreePool (DevicePath);
+      DevicePath = Option->DevicePath;
+    }
+
+    DEBUG_CODE_BEGIN();
+
+    if (Option->Description == NULL) {
+      DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Booting from unknown device path\n"));
+    } else {
+      DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Booting %S\n", Option->Description));
+    }
+        
+    DEBUG_CODE_END();
+  
+    //
+    // Report status code for OS Loader LoadImage.
+    //
+    REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderLoad));
+    Status = gBS->LoadImage (
+                    TRUE,
+                    gImageHandle,
+                    DevicePath,
+                    NULL,
+                    0,
+                    &ImageHandle
+                    );
+
+    //
+    // If we didn't find an image directly, we need to try as if it is a removable device boot option
+    // and load the image according to the default boot behavior for removable device.
+    //
+    if (EFI_ERROR (Status)) {
+      //
+      // check if there is a bootable removable media could be found in this device path ,
+      // and get the bootable media handle
+      //
+      Handle = BdsLibGetBootableHandle(DevicePath);
+      if (Handle != NULL) {
+        //
+        // Load the default boot file \EFI\BOOT\boot{machinename}.EFI from removable Media
+        //  machinename is ia32, ia64, x64, ...
+        //
+        FilePath = FileDevicePath (Handle, EFI_REMOVABLE_MEDIA_FILE_NAME);
+        if (FilePath != NULL) {
+          REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderLoad));
+          Status = gBS->LoadImage (
+                          TRUE,
+                          gImageHandle,
+                          FilePath,
+                          NULL,
+                          0,
+                          &ImageHandle
+                          );
+        }
+      }
+    }
+  }
+  //
+  // Provide the image with it's load options
+  //
+  if ((ImageHandle == NULL) || (EFI_ERROR(Status))) {
+    //
+    // Report Status Code to indicate that the failure to load boot option
+    //
+    REPORT_STATUS_CODE (
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,
+      (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR)
+      );    
+    goto Done;
+  }
+
+  Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &ImageInfo);
+  ASSERT_EFI_ERROR (Status);
+
+  if (Option->LoadOptionsSize != 0) {
+    ImageInfo->LoadOptionsSize  = Option->LoadOptionsSize;
+    ImageInfo->LoadOptions      = Option->LoadOptions;
+  }
+
+  //
+  // Clean to NULL because the image is loaded directly from the firmwares boot manager.
+  //
+  ImageInfo->ParentHandle = NULL;
+
+  //
+  // Before calling the image, enable the Watchdog Timer for
+  // the 5 Minute period
+  //
+  gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);
+
+  //
+  // Write boot to OS performance data for UEFI boot
+  //
+  PERF_CODE (
+    BmEndOfBdsPerfCode (NULL, NULL);
+  );
+
+  //
+  // Report status code for OS Loader StartImage.
+  //
+  REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderStart));
+
+  Status = gBS->StartImage (ImageHandle, ExitDataSize, ExitData);
+  DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Image Return Status = %r\n", Status));
+  if (EFI_ERROR (Status)) {
+    //
+    // Report Status Code to indicate that boot failure
+    //
+    REPORT_STATUS_CODE (
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,
+      (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED)
+      );
+  }
+
+  //
+  // Clear the Watchdog Timer after the image returns
+  //
+  gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
+
+Done:
+  //
+  // Set Logo status invalid after trying one boot option
+  //
+  BootLogo = NULL;
+  StatusLogo = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo);
+  if (!EFI_ERROR (StatusLogo) && (BootLogo != NULL)) {
+    BootLogo->SetBootLogo (BootLogo, NULL, 0, 0, 0, 0);
+  }
+
+  //
+  // Clear Boot Current
+  // Deleting variable with current implementation shouldn't fail.
+  //
+  gRT->SetVariable (
+        L"BootCurrent",
+        &gEfiGlobalVariableGuid,
+        EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+        0,
+        NULL
+        );
+
+  return Status;
+}
+
+
+/**
+  Expand a device path that starts with a hard drive media device path node to be a
+  full device path that includes the full hardware path to the device. We need
+  to do this so it can be booted. As an optimization the front match (the part point
+  to the partition node. E.g. ACPI() /PCI()/ATA()/Partition() ) is saved in a variable
+  so a connect all is not required on every boot. All successful history device path
+  which point to partition node (the front part) will be saved.
+
+  @param  HardDriveDevicePath    EFI Device Path to boot, if it starts with a hard
+                                 drive media device path.
+  @return A Pointer to the full device path or NULL if a valid Hard Drive devic path
+          cannot be found.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+BdsExpandPartitionPartialDevicePathToFull (
+  IN  HARDDRIVE_DEVICE_PATH      *HardDriveDevicePath
+  )
+{
+  EFI_STATUS                Status;
+  UINTN                     BlockIoHandleCount;
+  EFI_HANDLE                *BlockIoBuffer;
+  EFI_DEVICE_PATH_PROTOCOL  *FullDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *BlockIoDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  UINTN                     Index;
+  UINTN                     InstanceNum;
+  EFI_DEVICE_PATH_PROTOCOL  *CachedDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *TempNewDevicePath;
+  UINTN                     CachedDevicePathSize;
+  BOOLEAN                   DeviceExist;
+  BOOLEAN                   NeedAdjust;
+  EFI_DEVICE_PATH_PROTOCOL  *Instance;
+  UINTN                     Size;
+
+  FullDevicePath = NULL;
+  //
+  // Check if there is prestore HD_BOOT_DEVICE_PATH_VARIABLE_NAME variable.
+  // If exist, search the front path which point to partition node in the variable instants.
+  // If fail to find or HD_BOOT_DEVICE_PATH_VARIABLE_NAME not exist, reconnect all and search in all system
+  //
+  GetVariable2 (
+    HD_BOOT_DEVICE_PATH_VARIABLE_NAME,
+    &gHdBootDevicePathVariablGuid,
+    (VOID **) &CachedDevicePath,
+    &CachedDevicePathSize
+    );
+
+  //
+  // Delete the invalid HD_BOOT_DEVICE_PATH_VARIABLE_NAME variable.
+  //
+  if ((CachedDevicePath != NULL) && !IsDevicePathValid (CachedDevicePath, CachedDevicePathSize)) {
+    FreePool (CachedDevicePath);
+    CachedDevicePath = NULL;
+    Status = gRT->SetVariable (
+                    HD_BOOT_DEVICE_PATH_VARIABLE_NAME,
+                    &gHdBootDevicePathVariablGuid,
+                    0,
+                    0,
+                    NULL
+                    );
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  if (CachedDevicePath != NULL) {
+    TempNewDevicePath = CachedDevicePath;
+    DeviceExist = FALSE;
+    NeedAdjust = FALSE;
+    do {
+      //
+      // Check every instance of the variable
+      // First, check whether the instance contain the partition node, which is needed for distinguishing  multi
+      // partial partition boot option. Second, check whether the instance could be connected.
+      //
+      Instance  = GetNextDevicePathInstance (&TempNewDevicePath, &Size);
+      if (MatchPartitionDevicePathNode (Instance, HardDriveDevicePath)) {
+        //
+        // Connect the device path instance, the device path point to hard drive media device path node
+        // e.g. ACPI() /PCI()/ATA()/Partition()
+        //
+        Status = BdsLibConnectDevicePath (Instance);
+        if (!EFI_ERROR (Status)) {
+          DeviceExist = TRUE;
+          break;
+        }
+      }
+      //
+      // Come here means the first instance is not matched
+      //
+      NeedAdjust = TRUE;
+      FreePool(Instance);
+    } while (TempNewDevicePath != NULL);
+
+    if (DeviceExist) {
+      //
+      // Find the matched device path.
+      // Append the file path information from the boot option and return the fully expanded device path.
+      //
+      DevicePath     = NextDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL *) HardDriveDevicePath);
+      FullDevicePath = AppendDevicePath (Instance, DevicePath);
+
+      //
+      // Adjust the HD_BOOT_DEVICE_PATH_VARIABLE_NAME instances sequence if the matched one is not first one.
+      //
+      if (NeedAdjust) {
+        //
+        // First delete the matched instance.
+        //
+        TempNewDevicePath = CachedDevicePath;
+        CachedDevicePath  = BdsLibDelPartMatchInstance (CachedDevicePath, Instance );
+        FreePool (TempNewDevicePath);
+
+        //
+        // Second, append the remaining path after the matched instance
+        //
+        TempNewDevicePath = CachedDevicePath;
+        CachedDevicePath = AppendDevicePathInstance (Instance, CachedDevicePath );
+        FreePool (TempNewDevicePath);
+        //
+        // Save the matching Device Path so we don't need to do a connect all next time
+        // Failure to set the variable only impacts the performance when next time expanding the short-form device path.
+        //
+        Status = gRT->SetVariable (
+                        HD_BOOT_DEVICE_PATH_VARIABLE_NAME,
+                        &gHdBootDevicePathVariablGuid,
+                        EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                        GetDevicePathSize (CachedDevicePath),
+                        CachedDevicePath
+                        );
+      }
+
+      FreePool (Instance);
+      FreePool (CachedDevicePath);
+      return FullDevicePath;
+    }
+  }
+
+  //
+  // If we get here we fail to find or HD_BOOT_DEVICE_PATH_VARIABLE_NAME not exist, and now we need
+  // to search all devices in the system for a matched partition
+  //
+  BdsLibConnectAllDriversToAllControllers ();
+  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &BlockIoHandleCount, &BlockIoBuffer);
+  if (EFI_ERROR (Status) || BlockIoHandleCount == 0 || BlockIoBuffer == NULL) {
+    //
+    // If there was an error or there are no device handles that support
+    // the BLOCK_IO Protocol, then return.
+    //
+    return NULL;
+  }
+  //
+  // Loop through all the device handles that support the BLOCK_IO Protocol
+  //
+  for (Index = 0; Index < BlockIoHandleCount; Index++) {
+
+    Status = gBS->HandleProtocol (BlockIoBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID *) &BlockIoDevicePath);
+    if (EFI_ERROR (Status) || BlockIoDevicePath == NULL) {
+      continue;
+    }
+
+    if (MatchPartitionDevicePathNode (BlockIoDevicePath, HardDriveDevicePath)) {
+      //
+      // Find the matched partition device path
+      //
+      DevicePath    = NextDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL *) HardDriveDevicePath);
+      FullDevicePath = AppendDevicePath (BlockIoDevicePath, DevicePath);
+
+      //
+      // Save the matched partition device path in HD_BOOT_DEVICE_PATH_VARIABLE_NAME variable
+      //
+      if (CachedDevicePath != NULL) {
+        //
+        // Save the matched partition device path as first instance of HD_BOOT_DEVICE_PATH_VARIABLE_NAME variable
+        //
+        if (BdsLibMatchDevicePaths (CachedDevicePath, BlockIoDevicePath)) {
+          TempNewDevicePath = CachedDevicePath;
+          CachedDevicePath = BdsLibDelPartMatchInstance (CachedDevicePath, BlockIoDevicePath);
+          FreePool(TempNewDevicePath);
+        }
+
+        if (CachedDevicePath != NULL) {
+          TempNewDevicePath = CachedDevicePath;
+          CachedDevicePath = AppendDevicePathInstance (BlockIoDevicePath, CachedDevicePath);
+          FreePool(TempNewDevicePath);
+        } else {
+          CachedDevicePath = DuplicateDevicePath (BlockIoDevicePath);
+        }
+
+        //
+        // Here limit the device path instance number to 12, which is max number for a system support 3 IDE controller
+        // If the user try to boot many OS in different HDs or partitions, in theory, 
+        // the HD_BOOT_DEVICE_PATH_VARIABLE_NAME variable maybe become larger and larger.
+        //
+        InstanceNum = 0;
+        ASSERT (CachedDevicePath != NULL);
+        TempNewDevicePath = CachedDevicePath;
+        while (!IsDevicePathEnd (TempNewDevicePath)) {
+          TempNewDevicePath = NextDevicePathNode (TempNewDevicePath);
+          //
+          // Parse one instance
+          //
+          while (!IsDevicePathEndType (TempNewDevicePath)) {
+            TempNewDevicePath = NextDevicePathNode (TempNewDevicePath);
+          }
+          InstanceNum++;
+          //
+          // If the CachedDevicePath variable contain too much instance, only remain 12 instances.
+          //
+          if (InstanceNum >= 12) {
+            SetDevicePathEndNode (TempNewDevicePath);
+            break;
+          }
+        }
+      } else {
+        CachedDevicePath = DuplicateDevicePath (BlockIoDevicePath);
+      }
+
+      //
+      // Save the matching Device Path so we don't need to do a connect all next time
+      // Failure to set the variable only impacts the performance when next time expanding the short-form device path.
+      //
+      Status = gRT->SetVariable (
+                      HD_BOOT_DEVICE_PATH_VARIABLE_NAME,
+                      &gHdBootDevicePathVariablGuid,
+                      EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                      GetDevicePathSize (CachedDevicePath),
+                      CachedDevicePath
+                      );
+
+      break;
+    }
+  }
+
+  if (CachedDevicePath != NULL) {
+    FreePool (CachedDevicePath);
+  }
+  if (BlockIoBuffer != NULL) {
+    FreePool (BlockIoBuffer);
+  }
+  return FullDevicePath;
+}
+
+/**
+  Check whether there is a instance in BlockIoDevicePath, which contain multi device path
+  instances, has the same partition node with HardDriveDevicePath device path
+
+  @param  BlockIoDevicePath      Multi device path instances which need to check
+  @param  HardDriveDevicePath    A device path which starts with a hard drive media
+                                 device path.
+
+  @retval TRUE                   There is a matched device path instance.
+  @retval FALSE                  There is no matched device path instance.
+
+**/
+BOOLEAN
+EFIAPI
+MatchPartitionDevicePathNode (
+  IN  EFI_DEVICE_PATH_PROTOCOL   *BlockIoDevicePath,
+  IN  HARDDRIVE_DEVICE_PATH      *HardDriveDevicePath
+  )
+{
+  HARDDRIVE_DEVICE_PATH     *TmpHdPath;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  BOOLEAN                   Match;
+  EFI_DEVICE_PATH_PROTOCOL  *BlockIoHdDevicePathNode;
+
+  if ((BlockIoDevicePath == NULL) || (HardDriveDevicePath == NULL)) {
+    return FALSE;
+  }
+
+  //
+  // Make PreviousDevicePath == the device path node before the end node
+  //
+  DevicePath              = BlockIoDevicePath;
+  BlockIoHdDevicePathNode = NULL;
+
+  //
+  // find the partition device path node
+  //
+  while (!IsDevicePathEnd (DevicePath)) {
+    if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) &&
+        (DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP)
+        ) {
+      BlockIoHdDevicePathNode = DevicePath;
+      break;
+    }
+
+    DevicePath = NextDevicePathNode (DevicePath);
+  }
+
+  if (BlockIoHdDevicePathNode == NULL) {
+    return FALSE;
+  }
+  //
+  // See if the harddrive device path in blockio matches the orig Hard Drive Node
+  //
+  TmpHdPath = (HARDDRIVE_DEVICE_PATH *) BlockIoHdDevicePathNode;
+  Match = FALSE;
+
+  //
+  // Check for the match
+  //
+  if ((TmpHdPath->MBRType == HardDriveDevicePath->MBRType) &&
+      (TmpHdPath->SignatureType == HardDriveDevicePath->SignatureType)) {
+    switch (TmpHdPath->SignatureType) {
+    case SIGNATURE_TYPE_GUID:
+      Match = CompareGuid ((EFI_GUID *)TmpHdPath->Signature, (EFI_GUID *)HardDriveDevicePath->Signature);
+      break;
+    case SIGNATURE_TYPE_MBR:
+      Match = (BOOLEAN)(*((UINT32 *)(&(TmpHdPath->Signature[0]))) == ReadUnaligned32((UINT32 *)(&(HardDriveDevicePath->Signature[0]))));
+      break;
+    default:
+      Match = FALSE;
+      break;
+    }
+  }
+
+  return Match;
+}
+
+/**
+  Delete the boot option associated with the handle passed in.
+
+  @param  Handle                 The handle which present the device path to create
+                                 boot option
+
+  @retval EFI_SUCCESS            Delete the boot option success
+  @retval EFI_NOT_FOUND          If the Device Path is not found in the system
+  @retval EFI_OUT_OF_RESOURCES   Lack of memory resource
+  @retval Other                  Error return value from SetVariable()
+
+**/
+EFI_STATUS
+BdsLibDeleteOptionFromHandle (
+  IN  EFI_HANDLE                 Handle
+  )
+{
+  UINT16                    *BootOrder;
+  UINT8                     *BootOptionVar;
+  UINTN                     BootOrderSize;
+  UINTN                     BootOptionSize;
+  EFI_STATUS                Status;
+  UINTN                     Index;
+  UINT16                    BootOption[BOOT_OPTION_MAX_CHAR];
+  UINTN                     DevicePathSize;
+  UINTN                     OptionDevicePathSize;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *OptionDevicePath;
+  UINT8                     *TempPtr;
+
+  Status        = EFI_SUCCESS;
+  BootOrder     = NULL;
+  BootOrderSize = 0;
+
+  //
+  // Check "BootOrder" variable, if no, means there is no any boot order.
+  //
+  BootOrder = BdsLibGetVariableAndSize (
+                L"BootOrder",
+                &gEfiGlobalVariableGuid,
+                &BootOrderSize
+                );
+  if (BootOrder == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Convert device handle to device path protocol instance
+  //
+  DevicePath = DevicePathFromHandle (Handle);
+  if (DevicePath == NULL) {
+    return EFI_NOT_FOUND;
+  }
+  DevicePathSize = GetDevicePathSize (DevicePath);
+
+  //
+  // Loop all boot order variable and find the matching device path
+  //
+  Index = 0;
+  while (Index < BootOrderSize / sizeof (UINT16)) {
+    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);
+    BootOptionVar = BdsLibGetVariableAndSize (
+                      BootOption,
+                      &gEfiGlobalVariableGuid,
+                      &BootOptionSize
+                      );
+
+    if (BootOptionVar == NULL) {
+      FreePool (BootOrder);
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    if (!ValidateOption(BootOptionVar, BootOptionSize)) {
+      BdsDeleteBootOption (BootOrder[Index], BootOrder, &BootOrderSize);
+      FreePool (BootOptionVar);
+      Index++;
+      continue;
+    }
+
+    TempPtr = BootOptionVar;
+    TempPtr += sizeof (UINT32) + sizeof (UINT16);
+    TempPtr += StrSize ((CHAR16 *) TempPtr);
+    OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
+    OptionDevicePathSize = GetDevicePathSize (OptionDevicePath);
+
+    //
+    // Check whether the device path match
+    //
+    if ((OptionDevicePathSize == DevicePathSize) &&
+        (CompareMem (DevicePath, OptionDevicePath, DevicePathSize) == 0)) {
+      BdsDeleteBootOption (BootOrder[Index], BootOrder, &BootOrderSize);
+      FreePool (BootOptionVar);
+      break;
+    }
+
+    FreePool (BootOptionVar);
+    Index++;
+  }
+
+  //
+  // Adjust number of boot option for "BootOrder" variable.
+  //
+  Status = gRT->SetVariable (
+                  L"BootOrder",
+                  &gEfiGlobalVariableGuid,
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                  BootOrderSize,
+                  BootOrder
+                  );
+  //
+  // Shrinking variable with existing variable implementation shouldn't fail.
+  //
+  ASSERT_EFI_ERROR (Status);
+
+  FreePool (BootOrder);
+
+  return Status;
+}
+
+
+/**
+  Delete all invalid EFI boot options.
+
+  @retval EFI_SUCCESS            Delete all invalid boot option success
+  @retval EFI_NOT_FOUND          Variable "BootOrder" is not found
+  @retval EFI_OUT_OF_RESOURCES   Lack of memory resource
+  @retval Other                  Error return value from SetVariable()
+
+**/
+EFI_STATUS
+BdsDeleteAllInvalidEfiBootOption (
+  VOID
+  )
+{
+  UINT16                    *BootOrder;
+  UINT8                     *BootOptionVar;
+  UINTN                     BootOrderSize;
+  UINTN                     BootOptionSize;
+  EFI_STATUS                Status;
+  UINTN                     Index;
+  UINTN                     Index2;
+  UINT16                    BootOption[BOOT_OPTION_MAX_CHAR];
+  EFI_DEVICE_PATH_PROTOCOL  *OptionDevicePath;
+  UINT8                     *TempPtr;
+  CHAR16                    *Description;
+  BOOLEAN                   Corrupted;
+
+  Status           = EFI_SUCCESS;
+  BootOrder        = NULL;
+  Description      = NULL;
+  OptionDevicePath = NULL;
+  BootOrderSize    = 0;
+  Corrupted        = FALSE;
+
+  //
+  // Check "BootOrder" variable firstly, this variable hold the number of boot options
+  //
+  BootOrder = BdsLibGetVariableAndSize (
+                L"BootOrder",
+                &gEfiGlobalVariableGuid,
+                &BootOrderSize
+                );
+  if (NULL == BootOrder) {
+    return EFI_NOT_FOUND;
+  }
+
+  Index = 0;
+  while (Index < BootOrderSize / sizeof (UINT16)) {
+    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);
+    BootOptionVar = BdsLibGetVariableAndSize (
+                      BootOption,
+                      &gEfiGlobalVariableGuid,
+                      &BootOptionSize
+                      );
+    if (NULL == BootOptionVar) {
+      FreePool (BootOrder);
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    if (!ValidateOption(BootOptionVar, BootOptionSize)) {
+      Corrupted = TRUE;
+    } else {
+      TempPtr = BootOptionVar;
+      TempPtr += sizeof (UINT32) + sizeof (UINT16);
+      Description = (CHAR16 *) TempPtr;
+      TempPtr += StrSize ((CHAR16 *) TempPtr);
+      OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
+
+      //
+      // Skip legacy boot option (BBS boot device)
+      //
+      if ((DevicePathType (OptionDevicePath) == BBS_DEVICE_PATH) &&
+          (DevicePathSubType (OptionDevicePath) == BBS_BBS_DP)) {
+        FreePool (BootOptionVar);
+        Index++;
+        continue;
+      }
+    }
+
+    if (Corrupted || !BdsLibIsValidEFIBootOptDevicePathExt (OptionDevicePath, FALSE, Description)) {
+      //
+      // Delete this invalid boot option "Boot####"
+      //
+      Status = gRT->SetVariable (
+                      BootOption,
+                      &gEfiGlobalVariableGuid,
+                      EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                      0,
+                      NULL
+                      );
+      //
+      // Deleting variable with current variable implementation shouldn't fail.
+      //
+      ASSERT_EFI_ERROR (Status);
+      //
+      // Mark this boot option in boot order as deleted
+      //
+      BootOrder[Index] = 0xffff;
+      Corrupted        = FALSE;
+    }
+
+    FreePool (BootOptionVar);
+    Index++;
+  }
+
+  //
+  // Adjust boot order array
+  //
+  Index2 = 0;
+  for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {
+    if (BootOrder[Index] != 0xffff) {
+      BootOrder[Index2] = BootOrder[Index];
+      Index2 ++;
+    }
+  }
+  Status = gRT->SetVariable (
+                  L"BootOrder",
+                  &gEfiGlobalVariableGuid,
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                  Index2 * sizeof (UINT16),
+                  BootOrder
+                  );
+  //
+  // Shrinking variable with current variable implementation shouldn't fail.
+  //
+  ASSERT_EFI_ERROR (Status);
+
+  FreePool (BootOrder);
+
+  return Status;
+}
+
+
+/**
+  For EFI boot option, BDS separate them as six types:
+  1. Network - The boot option points to the SimpleNetworkProtocol device.
+               Bds will try to automatically create this type boot option when enumerate.
+  2. Shell   - The boot option points to internal flash shell.
+               Bds will try to automatically create this type boot option when enumerate.
+  3. Removable BlockIo      - The boot option only points to the removable media
+                              device, like USB flash disk, DVD, Floppy etc.
+                              These device should contain a *removable* blockIo
+                              protocol in their device handle.
+                              Bds will try to automatically create this type boot option
+                              when enumerate.
+  4. Fixed BlockIo          - The boot option only points to a Fixed blockIo device,
+                              like HardDisk.
+                              These device should contain a *fixed* blockIo
+                              protocol in their device handle.
+                              BDS will skip fixed blockIo devices, and NOT
+                              automatically create boot option for them. But BDS
+                              will help to delete those fixed blockIo boot option,
+                              whose description rule conflict with other auto-created
+                              boot options.
+  5. Non-BlockIo Simplefile - The boot option points to a device whose handle
+                              has SimpleFileSystem Protocol, but has no blockio
+                              protocol. These devices do not offer blockIo
+                              protocol, but BDS still can get the
+                              \EFI\BOOT\boot{machinename}.EFI by SimpleFileSystem
+                              Protocol.
+  6. File    - The boot option points to a file. These boot options are usually
+               created by user manually or OS loader. BDS will not delete or modify
+               these boot options.
+
+  This function will enumerate all possible boot device in the system, and
+  automatically create boot options for Network, Shell, Removable BlockIo,
+  and Non-BlockIo Simplefile devices.
+  It will only execute once of every boot.
+
+  @param  BdsBootOptionList      The header of the link list which indexed all
+                                 current boot options
+
+  @retval EFI_SUCCESS            Finished all the boot device enumerate and create
+                                 the boot option base on that boot device
+
+  @retval EFI_OUT_OF_RESOURCES   Failed to enumerate the boot device and create the boot option list
+**/
+EFI_STATUS
+EFIAPI
+BdsLibEnumerateAllBootOption (
+  IN OUT LIST_ENTRY          *BdsBootOptionList
+  )
+{
+  EFI_STATUS                    Status;
+  UINT16                        FloppyNumber;
+  UINT16                        HarddriveNumber;
+  UINT16                        CdromNumber;
+  UINT16                        UsbNumber;
+  UINT16                        MiscNumber;
+  UINT16                        ScsiNumber;
+  UINT16                        NonBlockNumber;
+  UINTN                         NumberBlockIoHandles;
+  EFI_HANDLE                    *BlockIoHandles;
+  EFI_BLOCK_IO_PROTOCOL         *BlkIo;
+  BOOLEAN                       Removable[2];
+  UINTN                         RemovableIndex;
+  UINTN                         Index;
+  UINTN                         NumOfLoadFileHandles;
+  EFI_HANDLE                    *LoadFileHandles;
+  UINTN                         FvHandleCount;
+  EFI_HANDLE                    *FvHandleBuffer;
+  EFI_FV_FILETYPE               Type;
+  UINTN                         Size;
+  EFI_FV_FILE_ATTRIBUTES        Attributes;
+  UINT32                        AuthenticationStatus;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+  EFI_DEVICE_PATH_PROTOCOL      *DevicePath;
+  UINTN                         DevicePathType;
+  CHAR16                        Buffer[40];
+  EFI_HANDLE                    *FileSystemHandles;
+  UINTN                         NumberFileSystemHandles;
+  BOOLEAN                       NeedDelete;
+  EFI_IMAGE_DOS_HEADER          DosHeader;
+  CHAR8                         *PlatLang;
+  CHAR8                         *LastLang;
+  EFI_IMAGE_OPTIONAL_HEADER_UNION       HdrData;
+  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;
+  CHAR16                        *MacStr;
+  CHAR16                        *IPverStr;
+  EFI_HANDLE                    *NetworkHandles;
+  UINTN                         BufferSize;
+
+  FloppyNumber    = 0;
+  HarddriveNumber = 0;
+  CdromNumber     = 0;
+  UsbNumber       = 0;
+  MiscNumber      = 0;
+  ScsiNumber      = 0;
+  PlatLang        = NULL;
+  LastLang        = NULL;
+  ZeroMem (Buffer, sizeof (Buffer));
+
+  //
+  // If the boot device enumerate happened, just get the boot
+  // device from the boot order variable
+  //
+  if (mEnumBootDevice) {
+    GetVariable2 (LAST_ENUM_LANGUAGE_VARIABLE_NAME, &gLastEnumLangGuid, (VOID**)&LastLang, NULL);
+    GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&PlatLang, NULL);
+    ASSERT (PlatLang != NULL);
+    if ((LastLang != NULL) && (AsciiStrCmp (LastLang, PlatLang) == 0)) {
+      Status = BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");
+      FreePool (LastLang);
+      FreePool (PlatLang);
+      return Status;
+    } else {
+      Status = gRT->SetVariable (
+        LAST_ENUM_LANGUAGE_VARIABLE_NAME,
+        &gLastEnumLangGuid,
+        EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+        AsciiStrSize (PlatLang),
+        PlatLang
+        );
+      //
+      // Failure to set the variable only impacts the performance next time enumerating the boot options.
+      //
+
+      if (LastLang != NULL) {
+        FreePool (LastLang);
+      }
+      FreePool (PlatLang);
+    }
+  }
+
+  //
+  // Notes: this dirty code is to get the legacy boot option from the
+  // BBS table and create to variable as the EFI boot option, it should
+  // be removed after the CSM can provide legacy boot option directly
+  //
+  REFRESH_LEGACY_BOOT_OPTIONS;
+
+  //
+  // Delete invalid boot option
+  //
+  BdsDeleteAllInvalidEfiBootOption ();
+
+  //
+  // Parse removable media followed by fixed media.
+  // The Removable[] array is used by the for-loop below to create removable media boot options 
+  // at first, and then to create fixed media boot options.
+  //
+  Removable[0]  = FALSE;
+  Removable[1]  = TRUE;
+
+  gBS->LocateHandleBuffer (
+        ByProtocol,
+        &gEfiBlockIoProtocolGuid,
+        NULL,
+        &NumberBlockIoHandles,
+        &BlockIoHandles
+        );
+
+  for (RemovableIndex = 0; RemovableIndex < 2; RemovableIndex++) {
+    for (Index = 0; Index < NumberBlockIoHandles; Index++) {
+      Status = gBS->HandleProtocol (
+                      BlockIoHandles[Index],
+                      &gEfiBlockIoProtocolGuid,
+                      (VOID **) &BlkIo
+                      );
+      //
+      // skip the logical partition
+      //
+      if (EFI_ERROR (Status) || BlkIo->Media->LogicalPartition) {
+        continue;
+      }
+
+      //
+      // firstly fixed block io then the removable block io
+      //
+      if (BlkIo->Media->RemovableMedia == Removable[RemovableIndex]) {
+        continue;
+      }
+      DevicePath  = DevicePathFromHandle (BlockIoHandles[Index]);
+      DevicePathType = BdsGetBootTypeFromDevicePath (DevicePath);
+
+      switch (DevicePathType) {
+      case BDS_EFI_ACPI_FLOPPY_BOOT:
+        if (FloppyNumber != 0) {
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY)), FloppyNumber);
+        } else {
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY)));
+        }
+        BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
+        FloppyNumber++;
+        break;
+
+      //
+      // Assume a removable SATA device should be the DVD/CD device, a fixed SATA device should be the Hard Drive device.
+      //
+      case BDS_EFI_MESSAGE_ATAPI_BOOT:
+      case BDS_EFI_MESSAGE_SATA_BOOT:
+        if (BlkIo->Media->RemovableMedia) {
+          if (CdromNumber != 0) {
+            UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_CD_DVD)), CdromNumber);
+          } else {
+            UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_CD_DVD)));
+          }
+          CdromNumber++;
+        } else {
+          if (HarddriveNumber != 0) {
+            UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_HARDDRIVE)), HarddriveNumber);
+          } else {
+            UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_HARDDRIVE)));
+          }
+          HarddriveNumber++;
+        }
+        DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Buffer: %S\n", Buffer));
+        BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
+        break;
+
+      case BDS_EFI_MESSAGE_USB_DEVICE_BOOT:
+        if (UsbNumber != 0) {
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_USB)), UsbNumber);
+        } else {
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_USB)));
+        }
+        BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
+        UsbNumber++;
+        break;
+
+      case BDS_EFI_MESSAGE_SCSI_BOOT:
+        if (ScsiNumber != 0) {
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI)), ScsiNumber);
+        } else {
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI)));
+        }
+        BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
+        ScsiNumber++;
+        break;
+
+      case BDS_EFI_MESSAGE_MISC_BOOT:
+      default:
+        if (MiscNumber != 0) {
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC)), MiscNumber);
+        } else {
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC)));
+        }
+        BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
+        MiscNumber++;
+        break;
+      }
+    }
+  }
+
+  if (NumberBlockIoHandles != 0) {
+    FreePool (BlockIoHandles);
+  }
+
+  //
+  // If there is simple file protocol which does not consume block Io protocol, create a boot option for it here.
+  //
+  NonBlockNumber = 0;
+  gBS->LocateHandleBuffer (
+        ByProtocol,
+        &gEfiSimpleFileSystemProtocolGuid,
+        NULL,
+        &NumberFileSystemHandles,
+        &FileSystemHandles
+        );
+  for (Index = 0; Index < NumberFileSystemHandles; Index++) {
+    Status = gBS->HandleProtocol (
+                    FileSystemHandles[Index],
+                    &gEfiBlockIoProtocolGuid,
+                    (VOID **) &BlkIo
+                    );
+     if (!EFI_ERROR (Status)) {
+      //
+      //  Skip if the file system handle supports a BlkIo protocol,
+      //
+      continue;
+    }
+
+    //
+    // Do the removable Media thing. \EFI\BOOT\boot{machinename}.EFI
+    //  machinename is ia32, ia64, x64, ...
+    //
+    Hdr.Union  = &HdrData;
+    NeedDelete = TRUE;
+    Status     = BdsLibGetImageHeader (
+                   FileSystemHandles[Index],
+                   EFI_REMOVABLE_MEDIA_FILE_NAME,
+                   &DosHeader,
+                   Hdr
+                   );
+    if (!EFI_ERROR (Status) &&
+        EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr.Pe32->FileHeader.Machine) &&
+        Hdr.Pe32->OptionalHeader.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {
+      NeedDelete = FALSE;
+    }
+
+    if (NeedDelete) {
+      //
+      // No such file or the file is not a EFI application, delete this boot option
+      //
+      BdsLibDeleteOptionFromHandle (FileSystemHandles[Index]);
+    } else {
+      if (NonBlockNumber != 0) {
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NON_BLOCK)), NonBlockNumber);
+      } else {
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NON_BLOCK)));
+      }
+      BdsLibBuildOptionFromHandle (FileSystemHandles[Index], BdsBootOptionList, Buffer);
+      NonBlockNumber++;
+    }
+  }
+
+  if (NumberFileSystemHandles != 0) {
+    FreePool (FileSystemHandles);
+  }
+
+  //
+  // Parse Network Boot Device
+  //
+  NumOfLoadFileHandles = 0;
+  //
+  // Search Load File protocol for PXE boot option.
+  //
+  gBS->LocateHandleBuffer (
+        ByProtocol,
+        &gEfiLoadFileProtocolGuid,
+        NULL,
+        &NumOfLoadFileHandles,
+        &LoadFileHandles
+        );
+
+  for (Index = 0; Index < NumOfLoadFileHandles; Index++) {
+
+//
+//Locate EFI_DEVICE_PATH_PROTOCOL to dynamically get IPv4/IPv6 protocol information.
+//
+
+ Status = gBS->HandleProtocol (
+                  LoadFileHandles[Index],
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID **) &DevicePath
+                  );
+  
+ ASSERT_EFI_ERROR (Status);
+
+  while (!IsDevicePathEnd (DevicePath)) {
+    if ((DevicePath->Type == MESSAGING_DEVICE_PATH) &&
+        (DevicePath->SubType == MSG_IPv4_DP)) {
+
+  //
+  //Get handle infomation
+  //
+  BufferSize = 0;
+  NetworkHandles = NULL;
+  Status = gBS->LocateHandle (
+                  ByProtocol, 
+                  &gEfiSimpleNetworkProtocolGuid,
+                  NULL,
+                  &BufferSize,
+                  NetworkHandles
+                  );
+
+  if (Status == EFI_BUFFER_TOO_SMALL) {
+    NetworkHandles = AllocateZeroPool(BufferSize);
+    if (NetworkHandles == NULL) {
+      return (EFI_OUT_OF_RESOURCES);
+    }
+    Status = gBS->LocateHandle(
+                    ByProtocol,
+                    &gEfiSimpleNetworkProtocolGuid,
+                    NULL,
+                    &BufferSize,
+                    NetworkHandles
+                    );
+ }
+               
+  //
+  //Get the MAC string
+  //
+  Status = NetLibGetMacString (
+             *NetworkHandles,
+             NULL,
+             &MacStr
+             );
+  if (EFI_ERROR (Status)) {	
+    return Status;
+  }
+  IPverStr = L" IPv4";
+  UnicodeSPrint (Buffer, sizeof (Buffer), L"%s%s%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NETWORK)),MacStr,IPverStr);
+  break;
+  }
+    if((DevicePath->Type == MESSAGING_DEVICE_PATH) &&
+        (DevicePath->SubType == MSG_IPv6_DP)) {
+
+  //
+  //Get handle infomation
+  //
+  BufferSize = 0;
+  NetworkHandles = NULL;
+  Status = gBS->LocateHandle (
+                  ByProtocol, 
+                  &gEfiSimpleNetworkProtocolGuid,
+                  NULL,
+                  &BufferSize,
+                  NetworkHandles
+                  );
+
+  if (Status == EFI_BUFFER_TOO_SMALL) {
+    NetworkHandles = AllocateZeroPool(BufferSize);
+    if (NetworkHandles == NULL) {
+       return (EFI_OUT_OF_RESOURCES);
+    }
+    Status = gBS->LocateHandle(
+                    ByProtocol,
+                    &gEfiSimpleNetworkProtocolGuid,
+                    NULL,
+                    &BufferSize,
+                    NetworkHandles
+                    );
+ }
+                    
+  //
+  //Get the MAC string
+  //
+  Status = NetLibGetMacString (
+             *NetworkHandles,
+             NULL,
+             &MacStr
+             );
+  if (EFI_ERROR (Status)) {	
+    return Status;
+  }
+      IPverStr = L" IPv6";
+      UnicodeSPrint (Buffer, sizeof (Buffer), L"%s%s%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NETWORK)),MacStr,IPverStr);
+      break;
+    }
+    DevicePath = NextDevicePathNode (DevicePath);
+  }
+  
+    BdsLibBuildOptionFromHandle (LoadFileHandles[Index], BdsBootOptionList, Buffer);
+  }
+
+  if (NumOfLoadFileHandles != 0) {
+    FreePool (LoadFileHandles);
+  }
+
+  //
+  // Check if we have on flash shell
+  //
+  gBS->LocateHandleBuffer (
+        ByProtocol,
+        &gEfiFirmwareVolume2ProtocolGuid,
+        NULL,
+        &FvHandleCount,
+        &FvHandleBuffer
+        );
+  for (Index = 0; Index < FvHandleCount; Index++) {
+    gBS->HandleProtocol (
+          FvHandleBuffer[Index],
+          &gEfiFirmwareVolume2ProtocolGuid,
+          (VOID **) &Fv
+          );
+
+    Status = Fv->ReadFile (
+                  Fv,
+                  &gUefiShellFileGuid,
+                  NULL,
+                  &Size,
+                  &Type,
+                  &Attributes,
+                  &AuthenticationStatus
+                  );
+    if (EFI_ERROR (Status)) {
+      //
+      // Skip if no shell file in the FV
+      //
+      continue;
+    }
+    //
+    // Build the shell boot option
+    //
+    BdsLibBuildOptionFromShell (FvHandleBuffer[Index], BdsBootOptionList);
+  }
+
+  if (FvHandleCount != 0) {
+    FreePool (FvHandleBuffer);
+  }
+  //
+  // Make sure every boot only have one time
+  // boot device enumerate
+  //
+  Status = BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");
+  mEnumBootDevice = TRUE;
+
+  return Status;
+}
+
+/**
+  Build the boot option with the handle parsed in
+
+  @param  Handle                 The handle which present the device path to create
+                                 boot option
+  @param  BdsBootOptionList      The header of the link list which indexed all
+                                 current boot options
+  @param  String                 The description of the boot option.
+
+**/
+VOID
+EFIAPI
+BdsLibBuildOptionFromHandle (
+  IN  EFI_HANDLE                 Handle,
+  IN  LIST_ENTRY                 *BdsBootOptionList,
+  IN  CHAR16                     *String
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+
+  DevicePath = DevicePathFromHandle (Handle);
+
+  //
+  // Create and register new boot option
+  //
+  BdsLibRegisterNewOption (BdsBootOptionList, DevicePath, String, L"BootOrder");
+}
+
+
+/**
+  Build the on flash shell boot option with the handle parsed in.
+
+  @param  Handle                 The handle which present the device path to create
+                                 on flash shell boot option
+  @param  BdsBootOptionList      The header of the link list which indexed all
+                                 current boot options
+
+**/
+VOID
+EFIAPI
+BdsLibBuildOptionFromShell (
+  IN EFI_HANDLE                  Handle,
+  IN OUT LIST_ENTRY              *BdsBootOptionList
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH ShellNode;
+
+  DevicePath = DevicePathFromHandle (Handle);
+
+  //
+  // Build the shell device path
+  //
+  EfiInitializeFwVolDevicepathNode (&ShellNode, &gUefiShellFileGuid);
+
+  DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &ShellNode);
+
+  //
+  // Create and register the shell boot option
+  //
+  BdsLibRegisterNewOption (BdsBootOptionList, DevicePath, L"EFI Internal Shell", L"BootOrder");
+
+}
+
+/**
+  Boot from the UEFI spec defined "BootNext" variable.
+
+**/
+VOID
+EFIAPI
+BdsLibBootNext (
+  VOID
+  )
+{
+  EFI_STATUS        Status;
+  UINT16            *BootNext;
+  UINTN             BootNextSize;
+  CHAR16            Buffer[20];
+  BDS_COMMON_OPTION *BootOption;
+  LIST_ENTRY        TempList;
+  UINTN             ExitDataSize;
+  CHAR16            *ExitData;
+
+  //
+  // Init the boot option name buffer and temp link list
+  //
+  InitializeListHead (&TempList);
+  ZeroMem (Buffer, sizeof (Buffer));
+
+  BootNext = BdsLibGetVariableAndSize (
+              L"BootNext",
+              &gEfiGlobalVariableGuid,
+              &BootNextSize
+              );
+
+  //
+  // Clear the boot next variable first
+  //
+  if (BootNext != NULL) {
+    Status = gRT->SetVariable (
+                    L"BootNext",
+                    &gEfiGlobalVariableGuid,
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                    0,
+                    NULL
+                    );
+    //
+    // Deleting variable with current variable implementation shouldn't fail.
+    //
+    ASSERT_EFI_ERROR (Status);
+
+    //
+    // Start to build the boot option and try to boot
+    //
+    UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", *BootNext);
+    BootOption = BdsLibVariableToOption (&TempList, Buffer);
+    ASSERT (BootOption != NULL);
+    BdsLibConnectDevicePath (BootOption->DevicePath);
+    BdsLibBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData);
+    FreePool(BootOption);
+    FreePool(BootNext);
+  }
+
+}
+
+/**
+  Return the bootable media handle.
+  First, check the device is connected
+  Second, check whether the device path point to a device which support SimpleFileSystemProtocol,
+  Third, detect the the default boot file in the Media, and return the removable Media handle.
+
+  @param  DevicePath  Device Path to a  bootable device
+
+  @return  The bootable media handle. If the media on the DevicePath is not bootable, NULL will return.
+
+**/
+EFI_HANDLE
+EFIAPI
+BdsLibGetBootableHandle (
+  IN  EFI_DEVICE_PATH_PROTOCOL      *DevicePath
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_TPL                         OldTpl;
+  EFI_DEVICE_PATH_PROTOCOL        *UpdatedDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL        *DupDevicePath;
+  EFI_HANDLE                      Handle;
+  EFI_BLOCK_IO_PROTOCOL           *BlockIo;
+  VOID                            *Buffer;
+  EFI_DEVICE_PATH_PROTOCOL        *TempDevicePath;
+  UINTN                           Size;
+  UINTN                           TempSize;
+  EFI_HANDLE                      ReturnHandle;
+  EFI_HANDLE                      *SimpleFileSystemHandles;
+
+  UINTN                           NumberSimpleFileSystemHandles;
+  UINTN                           Index;
+  EFI_IMAGE_DOS_HEADER            DosHeader;
+  EFI_IMAGE_OPTIONAL_HEADER_UNION       HdrData;
+  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;
+
+  UpdatedDevicePath = DevicePath;
+
+  //
+  // Enter to critical section to protect the acquired BlockIo instance 
+  // from getting released due to the USB mass storage hotplug event
+  //
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+  //
+  // Check whether the device is connected
+  //
+  Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &UpdatedDevicePath, &Handle);
+  if (EFI_ERROR (Status)) {
+    //
+    // Skip the case that the boot option point to a simple file protocol which does not consume block Io protocol,
+    //
+    Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &UpdatedDevicePath, &Handle);
+    if (EFI_ERROR (Status)) {
+      //
+      // Fail to find the proper BlockIo and simple file protocol, maybe because device not present,  we need to connect it firstly
+      //
+      UpdatedDevicePath = DevicePath;
+      Status            = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &UpdatedDevicePath, &Handle);
+      gBS->ConnectController (Handle, NULL, NULL, TRUE);
+    }
+  } else {
+    //
+    // For removable device boot option, its contained device path only point to the removable device handle, 
+    // should make sure all its children handles (its child partion or media handles) are created and connected. 
+    //
+    gBS->ConnectController (Handle, NULL, NULL, TRUE); 
+    //
+    // Get BlockIo protocol and check removable attribute
+    //
+    Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
+    ASSERT_EFI_ERROR (Status);
+
+    //
+    // Issue a dummy read to the device to check for media change.
+    // When the removable media is changed, any Block IO read/write will
+    // cause the BlockIo protocol be reinstalled and EFI_MEDIA_CHANGED is
+    // returned. After the Block IO protocol is reinstalled, subsequent
+    // Block IO read/write will success.
+    //
+    Buffer = AllocatePool (BlockIo->Media->BlockSize);
+    if (Buffer != NULL) {
+      BlockIo->ReadBlocks (
+               BlockIo,
+               BlockIo->Media->MediaId,
+               0,
+               BlockIo->Media->BlockSize,
+               Buffer
+               );
+      FreePool(Buffer);
+    }
+  }
+
+  //
+  // Detect the the default boot file from removable Media
+  //
+
+  //
+  // If fail to get bootable handle specified by a USB boot option, the BDS should try to find other bootable device in the same USB bus
+  // Try to locate the USB node device path first, if fail then use its previous PCI node to search
+  //
+  DupDevicePath = DuplicateDevicePath (DevicePath);
+  ASSERT (DupDevicePath != NULL);
+
+  UpdatedDevicePath = DupDevicePath;
+  Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &UpdatedDevicePath, &Handle);
+  //
+  // if the resulting device path point to a usb node, and the usb node is a dummy node, should only let device path only point to the previous Pci node
+  // Acpi()/Pci()/Usb() --> Acpi()/Pci()
+  //
+  if ((DevicePathType (UpdatedDevicePath) == MESSAGING_DEVICE_PATH) &&
+      (DevicePathSubType (UpdatedDevicePath) == MSG_USB_DP)) {
+    //
+    // Remove the usb node, let the device path only point to PCI node
+    //
+    SetDevicePathEndNode (UpdatedDevicePath);
+    UpdatedDevicePath = DupDevicePath;
+  } else {
+    UpdatedDevicePath = DevicePath;
+  }
+
+  //
+  // Get the device path size of boot option
+  //
+  Size = GetDevicePathSize(UpdatedDevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL); // minus the end node
+  ReturnHandle = NULL;
+  gBS->LocateHandleBuffer (
+      ByProtocol,
+      &gEfiSimpleFileSystemProtocolGuid,
+      NULL,
+      &NumberSimpleFileSystemHandles,
+      &SimpleFileSystemHandles
+      );
+  for (Index = 0; Index < NumberSimpleFileSystemHandles; Index++) {
+    //
+    // Get the device path size of SimpleFileSystem handle
+    //
+    TempDevicePath = DevicePathFromHandle (SimpleFileSystemHandles[Index]);
+    TempSize = GetDevicePathSize (TempDevicePath)- sizeof (EFI_DEVICE_PATH_PROTOCOL); // minus the end node
+    //
+    // Check whether the device path of boot option is part of the  SimpleFileSystem handle's device path
+    //
+    if (Size <= TempSize && CompareMem (TempDevicePath, UpdatedDevicePath, Size)==0) {
+      //
+      // Load the default boot file \EFI\BOOT\boot{machinename}.EFI from removable Media
+      //  machinename is ia32, ia64, x64, ...
+      //
+      Hdr.Union = &HdrData;
+      Status = BdsLibGetImageHeader (
+                 SimpleFileSystemHandles[Index],
+                 EFI_REMOVABLE_MEDIA_FILE_NAME,
+                 &DosHeader,
+                 Hdr
+                 );
+      if (!EFI_ERROR (Status) &&
+        EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr.Pe32->FileHeader.Machine) &&
+        Hdr.Pe32->OptionalHeader.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {
+        ReturnHandle = SimpleFileSystemHandles[Index];
+        break;
+      }
+    }
+  }
+
+  FreePool(DupDevicePath);
+
+  if (SimpleFileSystemHandles != NULL) {
+    FreePool(SimpleFileSystemHandles);
+  }
+
+  gBS->RestoreTPL (OldTpl);
+
+  return ReturnHandle;
+}
+
+/**
+  Check to see if the network cable is plugged in. If the DevicePath is not
+  connected it will be connected.
+
+  @param  DevicePath             Device Path to check
+
+  @retval TRUE                   DevicePath points to an Network that is connected
+  @retval FALSE                  DevicePath does not point to a bootable network
+
+**/
+BOOLEAN
+BdsLibNetworkBootWithMediaPresent (
+  IN  EFI_DEVICE_PATH_PROTOCOL      *DevicePath
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_DEVICE_PATH_PROTOCOL        *UpdatedDevicePath;
+  EFI_HANDLE                      Handle;
+  EFI_SIMPLE_NETWORK_PROTOCOL     *Snp;
+  BOOLEAN                         MediaPresent;
+  UINT32                          InterruptStatus;
+
+  MediaPresent = FALSE;
+
+  UpdatedDevicePath = DevicePath;
+  //
+  // Locate Load File Protocol for PXE boot option first
+  //
+  Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &UpdatedDevicePath, &Handle);
+  if (EFI_ERROR (Status)) {
+    //
+    // Device not present so see if we need to connect it
+    //
+    Status = BdsLibConnectDevicePath (DevicePath);
+    if (!EFI_ERROR (Status)) {
+      //
+      // This one should work after we did the connect
+      //
+      Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &UpdatedDevicePath, &Handle);
+    }
+  }
+
+  if (!EFI_ERROR (Status)) {
+    Status = gBS->HandleProtocol (Handle, &gEfiSimpleNetworkProtocolGuid, (VOID **)&Snp);
+    if (EFI_ERROR (Status)) {
+      //
+      // Failed to open SNP from this handle, try to get SNP from parent handle
+      //
+      UpdatedDevicePath = DevicePathFromHandle (Handle);
+      if (UpdatedDevicePath != NULL) {
+        Status = gBS->LocateDevicePath (&gEfiSimpleNetworkProtocolGuid, &UpdatedDevicePath, &Handle);
+        if (!EFI_ERROR (Status)) {
+          //
+          // SNP handle found, get SNP from it
+          //
+          Status = gBS->HandleProtocol (Handle, &gEfiSimpleNetworkProtocolGuid, (VOID **) &Snp);
+        }
+      }
+    }
+
+    if (!EFI_ERROR (Status)) {
+      if (Snp->Mode->MediaPresentSupported) {
+        if (Snp->Mode->State == EfiSimpleNetworkInitialized) {
+          //
+          // Invoke Snp->GetStatus() to refresh the media status
+          //
+          Snp->GetStatus (Snp, &InterruptStatus, NULL);
+
+          //
+          // In case some one else is using the SNP check to see if it's connected
+          //
+          MediaPresent = Snp->Mode->MediaPresent;
+        } else {
+          //
+          // No one is using SNP so we need to Start and Initialize so
+          // MediaPresent will be valid.
+          //
+          Status = Snp->Start (Snp);
+          if (!EFI_ERROR (Status)) {
+            Status = Snp->Initialize (Snp, 0, 0);
+            if (!EFI_ERROR (Status)) {
+              MediaPresent = Snp->Mode->MediaPresent;
+              Snp->Shutdown (Snp);
+            }
+            Snp->Stop (Snp);
+          }
+        }
+      } else {
+        MediaPresent = TRUE;
+      }
+    }
+  }
+
+  return MediaPresent;
+}
+
+/**
+  For a bootable Device path, return its boot type.
+
+  @param  DevicePath                      The bootable device Path to check
+
+  @retval BDS_EFI_MEDIA_HD_BOOT           If given device path contains MEDIA_DEVICE_PATH type device path node
+                                          which subtype is MEDIA_HARDDRIVE_DP
+  @retval BDS_EFI_MEDIA_CDROM_BOOT        If given device path contains MEDIA_DEVICE_PATH type device path node
+                                          which subtype is MEDIA_CDROM_DP
+  @retval BDS_EFI_ACPI_FLOPPY_BOOT        If given device path contains ACPI_DEVICE_PATH type device path node
+                                          which HID is floppy device.
+  @retval BDS_EFI_MESSAGE_ATAPI_BOOT      If given device path contains MESSAGING_DEVICE_PATH type device path node
+                                          and its last device path node's subtype is MSG_ATAPI_DP.
+  @retval BDS_EFI_MESSAGE_SCSI_BOOT       If given device path contains MESSAGING_DEVICE_PATH type device path node
+                                          and its last device path node's subtype is MSG_SCSI_DP.
+  @retval BDS_EFI_MESSAGE_USB_DEVICE_BOOT If given device path contains MESSAGING_DEVICE_PATH type device path node
+                                          and its last device path node's subtype is MSG_USB_DP.
+  @retval BDS_EFI_MESSAGE_MISC_BOOT       If the device path not contains any media device path node,  and
+                                          its last device path node point to a message device path node.
+  @retval BDS_LEGACY_BBS_BOOT             If given device path contains BBS_DEVICE_PATH type device path node.
+  @retval BDS_EFI_UNSUPPORT               An EFI Removable BlockIO device path not point to a media and message device,
+
+**/
+UINT32
+EFIAPI
+BdsGetBootTypeFromDevicePath (
+  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath
+  )
+{
+  ACPI_HID_DEVICE_PATH          *Acpi;
+  EFI_DEVICE_PATH_PROTOCOL      *TempDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL      *LastDeviceNode;
+  UINT32                        BootType;
+
+  if (NULL == DevicePath) {
+    return BDS_EFI_UNSUPPORT;
+  }
+
+  TempDevicePath = DevicePath;
+
+  while (!IsDevicePathEndType (TempDevicePath)) {
+    switch (DevicePathType (TempDevicePath)) {
+      case BBS_DEVICE_PATH:
+         return BDS_LEGACY_BBS_BOOT;
+      case MEDIA_DEVICE_PATH:
+        if (DevicePathSubType (TempDevicePath) == MEDIA_HARDDRIVE_DP) {
+          return BDS_EFI_MEDIA_HD_BOOT;
+        } else if (DevicePathSubType (TempDevicePath) == MEDIA_CDROM_DP) {
+          return BDS_EFI_MEDIA_CDROM_BOOT;
+        }
+        break;
+      case ACPI_DEVICE_PATH:
+        Acpi = (ACPI_HID_DEVICE_PATH *) TempDevicePath;
+        if (EISA_ID_TO_NUM (Acpi->HID) == 0x0604) {
+          return BDS_EFI_ACPI_FLOPPY_BOOT;
+        }
+        break;
+      case MESSAGING_DEVICE_PATH:
+        //
+        // Get the last device path node
+        //
+        LastDeviceNode = NextDevicePathNode (TempDevicePath);
+        if (DevicePathSubType(LastDeviceNode) == MSG_DEVICE_LOGICAL_UNIT_DP) {
+          //
+          // if the next node type is Device Logical Unit, which specify the Logical Unit Number (LUN),
+          // skip it
+          //
+          LastDeviceNode = NextDevicePathNode (LastDeviceNode);
+        }
+        //
+        // if the device path not only point to driver device, it is not a messaging device path,
+        //
+        if (!IsDevicePathEndType (LastDeviceNode)) {
+          break;
+        }
+
+        switch (DevicePathSubType (TempDevicePath)) {
+        case MSG_ATAPI_DP:
+          BootType = BDS_EFI_MESSAGE_ATAPI_BOOT;
+          break;
+
+        case MSG_USB_DP:
+          BootType = BDS_EFI_MESSAGE_USB_DEVICE_BOOT;
+          break;
+
+        case MSG_SCSI_DP:
+          BootType = BDS_EFI_MESSAGE_SCSI_BOOT;
+          break;
+
+        case MSG_SATA_DP:
+          BootType = BDS_EFI_MESSAGE_SATA_BOOT;
+          break;
+
+        case MSG_MAC_ADDR_DP:
+        case MSG_VLAN_DP:
+        case MSG_IPv4_DP:
+        case MSG_IPv6_DP:
+          BootType = BDS_EFI_MESSAGE_MAC_BOOT;
+          break;
+
+        default:
+          BootType = BDS_EFI_MESSAGE_MISC_BOOT;
+          break;
+        }
+        return BootType;
+
+      default:
+        break;
+    }
+    TempDevicePath = NextDevicePathNode (TempDevicePath);
+  }
+
+  return BDS_EFI_UNSUPPORT;
+}
+
+/**
+  Check whether the Device path in a boot option point to a valid bootable device,
+  And if CheckMedia is true, check the device is ready to boot now.
+
+  @param  DevPath     the Device path in a boot option
+  @param  CheckMedia  if true, check the device is ready to boot now.
+
+  @retval TRUE        the Device path  is valid
+  @retval FALSE       the Device path  is invalid .
+
+**/
+BOOLEAN
+EFIAPI
+BdsLibIsValidEFIBootOptDevicePath (
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevPath,
+  IN BOOLEAN                      CheckMedia
+  )
+{
+  return BdsLibIsValidEFIBootOptDevicePathExt (DevPath, CheckMedia, NULL);
+}
+
+/**
+  Check whether the Device path in a boot option point to a valid bootable device,
+  And if CheckMedia is true, check the device is ready to boot now.
+  If Description is not NULL and the device path point to a fixed BlockIo
+  device, check the description whether conflict with other auto-created
+  boot options.
+
+  @param  DevPath     the Device path in a boot option
+  @param  CheckMedia  if true, check the device is ready to boot now.
+  @param  Description the description in a boot option
+
+  @retval TRUE        the Device path  is valid
+  @retval FALSE       the Device path  is invalid .
+
+**/
+BOOLEAN
+EFIAPI
+BdsLibIsValidEFIBootOptDevicePathExt (
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevPath,
+  IN BOOLEAN                      CheckMedia,
+  IN CHAR16                       *Description
+  )
+{
+  EFI_STATUS                Status;
+  EFI_HANDLE                Handle;
+  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *LastDeviceNode;
+  EFI_BLOCK_IO_PROTOCOL     *BlockIo;
+
+  TempDevicePath = DevPath;
+  LastDeviceNode = DevPath;
+
+  //
+  // Check if it's a valid boot option for network boot device.
+  // Check if there is EfiLoadFileProtocol installed. 
+  // If yes, that means there is a boot option for network.
+  //
+  Status = gBS->LocateDevicePath (
+                  &gEfiLoadFileProtocolGuid,
+                  &TempDevicePath,
+                  &Handle
+                  );
+  if (EFI_ERROR (Status)) {
+    //
+    // Device not present so see if we need to connect it
+    //
+    TempDevicePath = DevPath;
+    BdsLibConnectDevicePath (TempDevicePath);
+    Status = gBS->LocateDevicePath (
+                    &gEfiLoadFileProtocolGuid,
+                    &TempDevicePath,
+                    &Handle
+                    );
+  }
+
+  if (!EFI_ERROR (Status)) {
+    if (!IsDevicePathEnd (TempDevicePath)) {
+      //
+      // LoadFile protocol is not installed on handle with exactly the same DevPath
+      //
+      return FALSE;
+    }
+
+    if (CheckMedia) {
+      //
+      // Test if it is ready to boot now
+      //
+      if (BdsLibNetworkBootWithMediaPresent(DevPath)) {
+        return TRUE;
+      }
+    } else {
+      return TRUE;
+    }    
+  }
+
+  //
+  // If the boot option point to a file, it is a valid EFI boot option,
+  // and assume it is ready to boot now
+  //
+  while (!IsDevicePathEnd (TempDevicePath)) {
+    //
+    // If there is USB Class or USB WWID device path node, treat it as valid EFI
+    // Boot Option. BdsExpandUsbShortFormDevicePath () will be used to expand it
+    // to full device path.
+    //
+    if ((DevicePathType (TempDevicePath) == MESSAGING_DEVICE_PATH) &&
+        ((DevicePathSubType (TempDevicePath) == MSG_USB_CLASS_DP) ||
+         (DevicePathSubType (TempDevicePath) == MSG_USB_WWID_DP))) {
+      return TRUE;
+    }
+
+    LastDeviceNode = TempDevicePath;
+    TempDevicePath = NextDevicePathNode (TempDevicePath);
+  }
+  if ((DevicePathType (LastDeviceNode) == MEDIA_DEVICE_PATH) &&
+    (DevicePathSubType (LastDeviceNode) == MEDIA_FILEPATH_DP)) {
+    return TRUE;
+  }
+
+  //
+  // Check if it's a valid boot option for internal FV application
+  //
+  if (EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode) != NULL) {
+    //
+    // If the boot option point to internal FV application, make sure it is valid
+    //
+    TempDevicePath = DevPath;
+    Status = BdsLibUpdateFvFileDevicePath (
+               &TempDevicePath,
+               EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode)
+               );
+    if (Status == EFI_ALREADY_STARTED) {
+      return TRUE;
+    } else {
+      if (Status == EFI_SUCCESS) {
+        FreePool (TempDevicePath);
+      }
+      return FALSE;
+    }
+  }
+
+  //
+  // If the boot option point to a blockIO device:
+  //    if it is a removable blockIo device, it is valid.
+  //    if it is a fixed blockIo device, check its description confliction.
+  //
+  TempDevicePath = DevPath;
+  Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &TempDevicePath, &Handle);
+  if (EFI_ERROR (Status)) {
+    //
+    // Device not present so see if we need to connect it
+    //
+    Status = BdsLibConnectDevicePath (DevPath);
+    if (!EFI_ERROR (Status)) {
+      //
+      // Try again to get the Block Io protocol after we did the connect
+      //
+      TempDevicePath = DevPath;
+      Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &TempDevicePath, &Handle);
+    }
+  }
+
+  if (!EFI_ERROR (Status)) {
+    Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
+    if (!EFI_ERROR (Status)) {
+      if (CheckMedia) {
+        //
+        // Test if it is ready to boot now
+        //
+        if (BdsLibGetBootableHandle (DevPath) != NULL) {
+          return TRUE;
+        }
+      } else {
+        return TRUE;
+      }
+    }
+  } else {
+    //
+    // if the boot option point to a simple file protocol which does not consume block Io protocol, it is also a valid EFI boot option,
+    //
+    Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &TempDevicePath, &Handle);
+    if (!EFI_ERROR (Status)) {
+      if (CheckMedia) {
+        //
+        // Test if it is ready to boot now
+        //
+        if (BdsLibGetBootableHandle (DevPath) != NULL) {
+          return TRUE;
+        }
+      } else {
+        return TRUE;
+      }
+    }
+  }
+
+  return FALSE;
+}
+
+
+/**
+  According to a file guild, check a Fv file device path is valid. If it is invalid,
+  try to return the valid device path.
+  FV address maybe changes for memory layout adjust from time to time, use this function
+  could promise the Fv file device path is right.
+
+  @param  DevicePath             on input, the Fv file device path need to check on
+                                 output, the updated valid Fv file device path
+  @param  FileGuid               the Fv file guild
+
+  @retval EFI_INVALID_PARAMETER  the input DevicePath or FileGuid is invalid
+                                 parameter
+  @retval EFI_UNSUPPORTED        the input DevicePath does not contain Fv file
+                                 guild at all
+  @retval EFI_ALREADY_STARTED    the input DevicePath has pointed to Fv file, it is
+                                 valid
+  @retval EFI_SUCCESS            has successfully updated the invalid DevicePath,
+                                 and return the updated device path in DevicePath
+
+**/
+EFI_STATUS
+EFIAPI
+BdsLibUpdateFvFileDevicePath (
+  IN  OUT EFI_DEVICE_PATH_PROTOCOL      ** DevicePath,
+  IN  EFI_GUID                          *FileGuid
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL      *TempDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL      *LastDeviceNode;
+  EFI_STATUS                    Status;
+  EFI_GUID                      *GuidPoint;
+  UINTN                         Index;
+  UINTN                         FvHandleCount;
+  EFI_HANDLE                    *FvHandleBuffer;
+  EFI_FV_FILETYPE               Type;
+  UINTN                         Size;
+  EFI_FV_FILE_ATTRIBUTES        Attributes;
+  UINT32                        AuthenticationStatus;
+  BOOLEAN                       FindFvFile;
+  EFI_LOADED_IMAGE_PROTOCOL     *LoadedImage;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FvFileNode;
+  EFI_HANDLE                    FoundFvHandle;
+  EFI_DEVICE_PATH_PROTOCOL      *NewDevicePath;
+
+  if ((DevicePath == NULL) || (*DevicePath == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+  if (FileGuid == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check whether the device path point to the default the input Fv file
+  //
+  TempDevicePath = *DevicePath;
+  LastDeviceNode = TempDevicePath;
+  while (!IsDevicePathEnd (TempDevicePath)) {
+     LastDeviceNode = TempDevicePath;
+     TempDevicePath = NextDevicePathNode (TempDevicePath);
+  }
+  GuidPoint = EfiGetNameGuidFromFwVolDevicePathNode (
+                (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode
+                );
+  if (GuidPoint == NULL) {
+    //
+    // if this option does not points to a Fv file, just return EFI_UNSUPPORTED
+    //
+    return EFI_UNSUPPORTED;
+  }
+  if (!CompareGuid (GuidPoint, FileGuid)) {
+    //
+    // If the Fv file is not the input file guid, just return EFI_UNSUPPORTED
+    //
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Check whether the input Fv file device path is valid
+  //
+  TempDevicePath = *DevicePath;
+  FoundFvHandle = NULL;
+  Status = gBS->LocateDevicePath (
+                  &gEfiFirmwareVolume2ProtocolGuid,
+                  &TempDevicePath,
+                  &FoundFvHandle
+                  );
+  if (!EFI_ERROR (Status)) {
+    Status = gBS->HandleProtocol (
+                    FoundFvHandle,
+                    &gEfiFirmwareVolume2ProtocolGuid,
+                    (VOID **) &Fv
+                    );
+    if (!EFI_ERROR (Status)) {
+      //
+      // Set FV ReadFile Buffer as NULL, only need to check whether input Fv file exist there
+      //
+      Status = Fv->ReadFile (
+                    Fv,
+                    FileGuid,
+                    NULL,
+                    &Size,
+                    &Type,
+                    &Attributes,
+                    &AuthenticationStatus
+                    );
+      if (!EFI_ERROR (Status)) {
+        return EFI_ALREADY_STARTED;
+      }
+    }
+  }
+
+  //
+  // Look for the input wanted FV file in current FV
+  // First, try to look for in Bds own FV. Bds and input wanted FV file usually are in the same FV
+  //
+  FindFvFile = FALSE;
+  FoundFvHandle = NULL;
+  Status = gBS->HandleProtocol (
+             gImageHandle,
+             &gEfiLoadedImageProtocolGuid,
+             (VOID **) &LoadedImage
+             );
+  if (!EFI_ERROR (Status)) {
+    Status = gBS->HandleProtocol (
+                    LoadedImage->DeviceHandle,
+                    &gEfiFirmwareVolume2ProtocolGuid,
+                    (VOID **) &Fv
+                    );
+    if (!EFI_ERROR (Status)) {
+      Status = Fv->ReadFile (
+                    Fv,
+                    FileGuid,
+                    NULL,
+                    &Size,
+                    &Type,
+                    &Attributes,
+                    &AuthenticationStatus
+                    );
+      if (!EFI_ERROR (Status)) {
+        FindFvFile = TRUE;
+        FoundFvHandle = LoadedImage->DeviceHandle;
+      }
+    }
+  }
+  //
+  // Second, if fail to find, try to enumerate all FV
+  //
+  if (!FindFvFile) {
+    FvHandleBuffer = NULL;
+    gBS->LocateHandleBuffer (
+          ByProtocol,
+          &gEfiFirmwareVolume2ProtocolGuid,
+          NULL,
+          &FvHandleCount,
+          &FvHandleBuffer
+          );
+    for (Index = 0; Index < FvHandleCount; Index++) {
+      gBS->HandleProtocol (
+            FvHandleBuffer[Index],
+            &gEfiFirmwareVolume2ProtocolGuid,
+            (VOID **) &Fv
+            );
+
+      Status = Fv->ReadFile (
+                    Fv,
+                    FileGuid,
+                    NULL,
+                    &Size,
+                    &Type,
+                    &Attributes,
+                    &AuthenticationStatus
+                    );
+      if (EFI_ERROR (Status)) {
+        //
+        // Skip if input Fv file not in the FV
+        //
+        continue;
+      }
+      FindFvFile = TRUE;
+      FoundFvHandle = FvHandleBuffer[Index];
+      break;
+    }
+
+    if (FvHandleBuffer != NULL) {
+      FreePool (FvHandleBuffer);
+    }
+  }
+
+  if (FindFvFile) {
+    //
+    // Build the shell device path
+    //
+    NewDevicePath = DevicePathFromHandle (FoundFvHandle);
+    EfiInitializeFwVolDevicepathNode (&FvFileNode, FileGuid);
+    NewDevicePath = AppendDevicePathNode (NewDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &FvFileNode);
+    ASSERT (NewDevicePath != NULL);
+    *DevicePath = NewDevicePath;
+    return EFI_SUCCESS;
+  }
+  return EFI_NOT_FOUND;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConnect.c b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConnect.c
new file mode 100644
index 0000000000..dfeefc01b8
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConnect.c
@@ -0,0 +1,429 @@
+/** @file
+  BDS Lib functions which relate with connect the device
+
+Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalBdsLib.h"
+
+
+/**
+  This function will connect all the system driver to controller
+  first, and then special connect the default console, this make
+  sure all the system controller available and the platform default
+  console connected.
+
+**/
+VOID
+EFIAPI
+BdsLibConnectAll (
+  VOID
+  )
+{
+  //
+  // Connect the platform console first
+  //
+  BdsLibConnectAllDefaultConsoles ();
+
+  //
+  // Generic way to connect all the drivers
+  //
+  BdsLibConnectAllDriversToAllControllers ();
+
+  //
+  // Here we have the assumption that we have already had
+  // platform default console
+  //
+  BdsLibConnectAllDefaultConsoles ();
+}
+
+
+/**
+  This function will connect all the system drivers to all controllers
+  first, and then connect all the console devices the system current
+  have. After this we should get all the device work and console available
+  if the system have console device.
+
+**/
+VOID
+BdsLibGenericConnectAll (
+  VOID
+  )
+{
+  //
+  // Most generic way to connect all the drivers
+  //
+  BdsLibConnectAllDriversToAllControllers ();
+  BdsLibConnectAllConsoles ();
+}
+
+/**
+  This function will create all handles associate with every device
+  path node. If the handle associate with one device path node can not
+  be created successfully, then still give chance to do the dispatch,
+  which load the missing drivers if possible.
+
+  @param  DevicePathToConnect   The device path which will be connected, it can be
+                                a multi-instance device path
+
+  @retval EFI_SUCCESS           All handles associate with every device path  node
+                                have been created
+  @retval EFI_OUT_OF_RESOURCES  There is no resource to create new handles
+  @retval EFI_NOT_FOUND         Create the handle associate with one device  path
+                                node failed
+
+**/
+EFI_STATUS
+EFIAPI
+BdsLibConnectDevicePath (
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePathToConnect
+  )
+{
+  EFI_STATUS                Status;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *CopyOfDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *Instance;
+  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *Next;
+  EFI_HANDLE                Handle;
+  EFI_HANDLE                PreviousHandle;
+  UINTN                     Size;
+  EFI_TPL                   CurrentTpl;
+
+  if (DevicePathToConnect == NULL) {
+    return EFI_SUCCESS;
+  }
+
+  CurrentTpl  = EfiGetCurrentTpl ();
+
+  DevicePath        = DuplicateDevicePath (DevicePathToConnect);
+  if (DevicePath == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  CopyOfDevicePath  = DevicePath;
+  
+  do {
+    //
+    // The outer loop handles multi instance device paths.
+    // Only console variables contain multiple instance device paths.
+    //
+    // After this call DevicePath points to the next Instance
+    //
+    Instance  = GetNextDevicePathInstance (&DevicePath, &Size);
+    if (Instance == NULL) {
+      FreePool (CopyOfDevicePath);
+      return EFI_OUT_OF_RESOURCES;
+    }
+    
+    Next      = Instance;
+    while (!IsDevicePathEndType (Next)) {
+      Next = NextDevicePathNode (Next);
+    }
+
+    SetDevicePathEndNode (Next);
+
+    //
+    // Start the real work of connect with RemainingDevicePath
+    //
+    PreviousHandle = NULL;
+    do {
+      //
+      // Find the handle that best matches the Device Path. If it is only a
+      // partial match the remaining part of the device path is returned in
+      // RemainingDevicePath.
+      //
+      RemainingDevicePath = Instance;
+      Status              = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &Handle);
+
+      if (!EFI_ERROR (Status)) {
+        if (Handle == PreviousHandle) {
+          //
+          // If no forward progress is made try invoking the Dispatcher.
+          // A new FV may have been added to the system an new drivers
+          // may now be found.
+          // Status == EFI_SUCCESS means a driver was dispatched
+          // Status == EFI_NOT_FOUND means no new drivers were dispatched
+          //
+          if (CurrentTpl == TPL_APPLICATION) {
+            //
+            // Dispatch calls LoadImage/StartImage which cannot run at TPL > TPL_APPLICATION
+            //
+            Status = gDS->Dispatch ();
+          } else {
+            //
+            // Always return EFI_NOT_FOUND here
+            // to prevent dead loop when control handle is found but connection failded case
+            //
+            Status = EFI_NOT_FOUND;
+          }
+        }
+
+        if (!EFI_ERROR (Status)) {
+          PreviousHandle = Handle;
+          //
+          // Connect all drivers that apply to Handle and RemainingDevicePath,
+          // the Recursive flag is FALSE so only one level will be expanded.
+          //
+          // Do not check the connect status here, if the connect controller fail,
+          // then still give the chance to do dispatch, because partial
+          // RemainingDevicepath may be in the new FV
+          //
+          // 1. If the connect fail, RemainingDevicepath and handle will not
+          //    change, so next time will do the dispatch, then dispatch's status
+          //    will take effect
+          // 2. If the connect success, the RemainingDevicepath and handle will
+          //    change, then avoid the dispatch, we have chance to continue the
+          //    next connection
+          //
+          gBS->ConnectController (Handle, NULL, RemainingDevicePath, FALSE);
+        }
+      }
+      //
+      // Loop until RemainingDevicePath is an empty device path
+      //
+    } while (!EFI_ERROR (Status) && !IsDevicePathEnd (RemainingDevicePath));
+
+  } while (DevicePath != NULL);
+
+  if (CopyOfDevicePath != NULL) {
+    FreePool (CopyOfDevicePath);
+  }
+  //
+  // All handle with DevicePath exists in the handle database
+  //
+  return Status;
+}
+
+/**
+  This function will connect all current system handles recursively. 
+  
+  gBS->ConnectController() service is invoked for each handle exist in system handler buffer.
+  If the handle is bus type handler, all childrens also will be connected recursively
+  by gBS->ConnectController().
+
+  @retval EFI_SUCCESS           All handles and it's child handle have been connected
+  @retval EFI_STATUS            Error status returned by of gBS->LocateHandleBuffer().
+
+**/
+EFI_STATUS
+EFIAPI
+BdsLibConnectAllEfi (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+  UINTN       HandleCount;
+  EFI_HANDLE  *HandleBuffer;
+  UINTN       Index;
+
+  Status = gBS->LocateHandleBuffer (
+                  AllHandles,
+                  NULL,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  for (Index = 0; Index < HandleCount; Index++) {
+    Status = gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
+  }
+
+  if (HandleBuffer != NULL) {
+    FreePool (HandleBuffer);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function will disconnect all current system handles. 
+  
+  gBS->DisconnectController() is invoked for each handle exists in system handle buffer.
+  If handle is a bus type handle, all childrens also are disconnected recursively by
+  gBS->DisconnectController().
+
+  @retval EFI_SUCCESS           All handles have been disconnected
+  @retval EFI_STATUS            Error status returned by of gBS->LocateHandleBuffer().
+
+**/
+EFI_STATUS
+EFIAPI
+BdsLibDisconnectAllEfi (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+  UINTN       HandleCount;
+  EFI_HANDLE  *HandleBuffer;
+  UINTN       Index;
+
+  //
+  // Disconnect all
+  //
+  Status = gBS->LocateHandleBuffer (
+                  AllHandles,
+                  NULL,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  for (Index = 0; Index < HandleCount; Index++) {
+    Status = gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
+  }
+
+  if (HandleBuffer != NULL) {
+    FreePool (HandleBuffer);
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Connects all drivers to all controllers.
+  This function make sure all the current system driver will manage
+  the correspoinding controllers if have. And at the same time, make
+  sure all the system controllers have driver to manage it if have.
+
+**/
+VOID
+EFIAPI
+BdsLibConnectAllDriversToAllControllers (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  do {
+    //
+    // Connect All EFI 1.10 drivers following EFI 1.10 algorithm
+    //
+    BdsLibConnectAllEfi ();
+
+    //
+    // Check to see if it's possible to dispatch an more DXE drivers.
+    // The BdsLibConnectAllEfi () may have made new DXE drivers show up.
+    // If anything is Dispatched Status == EFI_SUCCESS and we will try
+    // the connect again.
+    //
+    Status = gDS->Dispatch ();
+
+  } while (!EFI_ERROR (Status));
+
+}
+
+
+/**
+  Connect the specific Usb device which match the short form device path,
+  and whose bus is determined by Host Controller (Uhci or Ehci).
+
+  @param  HostControllerPI      Uhci (0x00) or Ehci (0x20) or Both uhci and ehci
+                                (0xFF)
+  @param  RemainingDevicePath   a short-form device path that starts with the first
+                                element  being a USB WWID or a USB Class device
+                                path
+
+  @return EFI_INVALID_PARAMETER  RemainingDevicePath is NULL pointer.
+                                 RemainingDevicePath is not a USB device path.
+                                 Invalid HostControllerPI type.
+  @return EFI_SUCCESS            Success to connect USB device
+  @return EFI_NOT_FOUND          Fail to find handle for USB controller to connect.
+
+**/
+EFI_STATUS
+EFIAPI
+BdsLibConnectUsbDevByShortFormDP(
+  IN UINT8                      HostControllerPI,
+  IN EFI_DEVICE_PATH_PROTOCOL   *RemainingDevicePath
+  )
+{
+  EFI_STATUS                            Status;
+  EFI_HANDLE                            *HandleArray;
+  UINTN                                 HandleArrayCount;
+  UINTN                                 Index;
+  EFI_PCI_IO_PROTOCOL                   *PciIo;
+  UINT8                                 Class[3];
+  BOOLEAN                               AtLeastOneConnected;
+
+  //
+  // Check the passed in parameters
+  //
+  if (RemainingDevicePath == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((DevicePathType (RemainingDevicePath) != MESSAGING_DEVICE_PATH) ||
+      ((DevicePathSubType (RemainingDevicePath) != MSG_USB_CLASS_DP)
+      && (DevicePathSubType (RemainingDevicePath) != MSG_USB_WWID_DP)
+      )) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (HostControllerPI != 0xFF &&
+      HostControllerPI != 0x00 &&
+      HostControllerPI != 0x20) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Find the usb host controller firstly, then connect with the remaining device path
+  //
+  AtLeastOneConnected = FALSE;
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiPciIoProtocolGuid,
+                  NULL,
+                  &HandleArrayCount,
+                  &HandleArray
+                  );
+  if (!EFI_ERROR (Status)) {
+    for (Index = 0; Index < HandleArrayCount; Index++) {
+      Status = gBS->HandleProtocol (
+                      HandleArray[Index],
+                      &gEfiPciIoProtocolGuid,
+                      (VOID **)&PciIo
+                      );
+      if (!EFI_ERROR (Status)) {
+        //
+        // Check whether the Pci device is the wanted usb host controller
+        //
+        Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x09, 3, &Class);
+        if (!EFI_ERROR (Status)) {
+          if ((PCI_CLASS_SERIAL == Class[2]) &&
+              (PCI_CLASS_SERIAL_USB == Class[1])) {
+            if (HostControllerPI == Class[0] || HostControllerPI == 0xFF) {
+              Status = gBS->ConnectController (
+                              HandleArray[Index],
+                              NULL,
+                              RemainingDevicePath,
+                              FALSE
+                              );
+              if (!EFI_ERROR(Status)) {
+                AtLeastOneConnected = TRUE;
+              }
+            }
+          }
+        }
+      }
+    }
+
+    if (HandleArray != NULL) {
+      FreePool (HandleArray);
+    }
+
+    if (AtLeastOneConnected) {
+      return EFI_SUCCESS;
+    }
+  }
+
+  return EFI_NOT_FOUND;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c
new file mode 100644
index 0000000000..2fffd9e4bc
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c
@@ -0,0 +1,1061 @@
+/** @file
+  BDS Lib functions which contain all the code to connect console device
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalBdsLib.h"
+
+
+/**
+  Check if we need to save the EFI variable with "ConVarName" as name
+  as NV type
+  If ConVarName is NULL, then ASSERT().
+  
+  @param ConVarName The name of the EFI variable.
+
+  @retval TRUE    Set the EFI variable as NV type.
+  @retval FALSE   EFI variable as NV type can be set NonNV.
+**/
+BOOLEAN
+IsNvNeed (
+  IN CHAR16 *ConVarName
+  )
+{
+  CHAR16 *Ptr;
+
+  ASSERT (ConVarName != NULL);
+  
+  Ptr = ConVarName;
+
+  //
+  // If the variable includes "Dev" at last, we consider
+  // it does not support NV attribute.
+  //
+  while (*Ptr != L'\0') {
+    Ptr++;
+  }
+
+  if (((INTN)((UINTN)Ptr - (UINTN)ConVarName) / sizeof (CHAR16)) <= 3) {
+    return TRUE;
+  }
+  
+  if ((*(Ptr - 3) == 'D') && (*(Ptr - 2) == 'e') && (*(Ptr - 1) == 'v')) {
+    return FALSE;
+  } else {
+    return TRUE;
+  }
+}
+
+/**
+  Fill console handle in System Table if there are no valid console handle in.
+
+  Firstly, check the validation of console handle in System Table. If it is invalid,
+  update it by the first console device handle from EFI console variable. 
+
+  @param  VarName            The name of the EFI console variable.
+  @param  ConsoleGuid        Specified Console protocol GUID.
+  @param  ConsoleHandle      On IN,  console handle in System Table to be checked. 
+                             On OUT, new console handle in system table.
+  @param  ProtocolInterface  On IN,  console protocol on console handle in System Table to be checked. 
+                             On OUT, new console protocol on new console handle in system table.
+
+  @retval TRUE               System Table has been updated.
+  @retval FALSE              System Table hasn't been updated.
+
+**/
+BOOLEAN 
+UpdateSystemTableConsole (
+  IN     CHAR16                          *VarName,
+  IN     EFI_GUID                        *ConsoleGuid,
+  IN OUT EFI_HANDLE                      *ConsoleHandle,
+  IN OUT VOID                            **ProtocolInterface
+  )
+{
+  EFI_STATUS                Status;
+  UINTN                     DevicePathSize;
+  EFI_DEVICE_PATH_PROTOCOL  *FullDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *VarConsole;
+  EFI_DEVICE_PATH_PROTOCOL  *Instance;
+  VOID                      *Interface;
+  EFI_HANDLE                NewHandle;
+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut;
+
+  ASSERT (VarName != NULL);
+  ASSERT (ConsoleHandle != NULL);
+  ASSERT (ConsoleGuid != NULL);
+  ASSERT (ProtocolInterface != NULL);
+
+  if (*ConsoleHandle != NULL) {
+    Status = gBS->HandleProtocol (
+                   *ConsoleHandle,
+                   ConsoleGuid,
+                   &Interface
+                   );
+    if (Status == EFI_SUCCESS && Interface == *ProtocolInterface) {
+      //
+      // If ConsoleHandle is valid and console protocol on this handle also
+      // also matched, just return.
+      //
+      return FALSE;
+    }
+  }
+  
+  //
+  // Get all possible consoles device path from EFI variable
+  //
+  VarConsole = BdsLibGetVariableAndSize (
+                VarName,
+                &gEfiGlobalVariableGuid,
+                &DevicePathSize
+                );
+  if (VarConsole == NULL) {
+    //
+    // If there is no any console device, just return.
+    //
+    return FALSE;
+  }
+
+  FullDevicePath = VarConsole;
+
+  do {
+    //
+    // Check every instance of the console variable
+    //
+    Instance  = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);
+    if (Instance == NULL) {
+      FreePool (FullDevicePath);
+      ASSERT (FALSE);
+    }
+    
+    //
+    // Find console device handle by device path instance
+    //
+    Status = gBS->LocateDevicePath (
+                   ConsoleGuid,
+                   &Instance,
+                   &NewHandle
+                   );
+    if (!EFI_ERROR (Status)) {
+      //
+      // Get the console protocol on this console device handle
+      //
+      Status = gBS->HandleProtocol (
+                     NewHandle,
+                     ConsoleGuid,
+                     &Interface
+                     );
+      if (!EFI_ERROR (Status)) {
+        //
+        // Update new console handle in System Table.
+        //
+        *ConsoleHandle     = NewHandle;
+        *ProtocolInterface = Interface;
+        if (CompareGuid (ConsoleGuid, &gEfiSimpleTextOutProtocolGuid)) {
+          //
+          // If it is console out device, set console mode 80x25 if current mode is invalid.
+          //
+          TextOut = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *) Interface;
+          if (TextOut->Mode->Mode == -1) {
+            TextOut->SetMode (TextOut, 0);
+          }
+        }
+        return TRUE;
+      }
+    }
+
+  } while (Instance != NULL);
+
+  //
+  // No any available console devcie found.
+  //
+  return FALSE;
+}
+
+/**
+  This function update console variable based on ConVarName, it can
+  add or remove one specific console device path from the variable
+
+  @param  ConVarName               Console related variable name, ConIn, ConOut,
+                                   ErrOut.
+  @param  CustomizedConDevicePath  The console device path which will be added to
+                                   the console variable ConVarName, this parameter
+                                   can not be multi-instance.
+  @param  ExclusiveDevicePath      The console device path which will be removed
+                                   from the console variable ConVarName, this
+                                   parameter can not be multi-instance.
+
+  @retval EFI_UNSUPPORTED          The added device path is same to the removed one.
+  @retval EFI_SUCCESS              Success add or remove the device path from  the
+                                   console variable.
+
+**/
+EFI_STATUS
+EFIAPI
+BdsLibUpdateConsoleVariable (
+  IN  CHAR16                    *ConVarName,
+  IN  EFI_DEVICE_PATH_PROTOCOL  *CustomizedConDevicePath,
+  IN  EFI_DEVICE_PATH_PROTOCOL  *ExclusiveDevicePath
+  )
+{
+  EFI_STATUS                Status;
+  EFI_DEVICE_PATH_PROTOCOL  *VarConsole;
+  UINTN                     DevicePathSize;
+  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *TempNewDevicePath;
+  UINT32                    Attributes;
+
+  VarConsole      = NULL;
+  DevicePathSize  = 0;
+
+  //
+  // Notes: check the device path point, here should check
+  // with compare memory
+  //
+  if (CustomizedConDevicePath == ExclusiveDevicePath) {
+    return EFI_UNSUPPORTED;
+  }
+  //
+  // Delete the ExclusiveDevicePath from current default console
+  //
+  VarConsole = BdsLibGetVariableAndSize (
+                ConVarName,
+                &gEfiGlobalVariableGuid,
+                &DevicePathSize
+                );
+
+  //
+  // Initialize NewDevicePath
+  //
+  NewDevicePath  = VarConsole;
+
+  //
+  // If ExclusiveDevicePath is even the part of the instance in VarConsole, delete it.
+  // In the end, NewDevicePath is the final device path.
+  //
+  if (ExclusiveDevicePath != NULL && VarConsole != NULL) {
+      NewDevicePath = BdsLibDelPartMatchInstance (VarConsole, ExclusiveDevicePath);
+  }
+  //
+  // Try to append customized device path to NewDevicePath.
+  //
+  if (CustomizedConDevicePath != NULL) {
+    if (!BdsLibMatchDevicePaths (NewDevicePath, CustomizedConDevicePath)) {
+      //
+      // Check if there is part of CustomizedConDevicePath in NewDevicePath, delete it.
+      //
+      NewDevicePath = BdsLibDelPartMatchInstance (NewDevicePath, CustomizedConDevicePath);
+      //
+      // In the first check, the default console variable will be _ModuleEntryPoint,
+      // just append current customized device path
+      //
+      TempNewDevicePath = NewDevicePath;
+      NewDevicePath = AppendDevicePathInstance (NewDevicePath, CustomizedConDevicePath);
+      if (TempNewDevicePath != NULL) {
+        FreePool(TempNewDevicePath);
+      }
+    }
+  }
+
+  //
+  // The attribute for ConInDev, ConOutDev and ErrOutDev does not include NV.
+  //
+  if (IsNvNeed(ConVarName)) {
+    //
+    // ConVarName has NV attribute.
+    //
+    Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;
+  } else {
+    //
+    // ConVarName does not have NV attribute.
+    //
+    Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
+  }
+
+  //
+  // Finally, Update the variable of the default console by NewDevicePath
+  //
+  DevicePathSize = GetDevicePathSize (NewDevicePath);
+  Status = SetVariableAndReportStatusCodeOnError (
+             ConVarName,
+             &gEfiGlobalVariableGuid,
+             Attributes,
+             DevicePathSize,
+             NewDevicePath
+             );
+  if ((DevicePathSize == 0) && (Status == EFI_NOT_FOUND)) {
+    Status = EFI_SUCCESS;
+  }
+
+  if (VarConsole == NewDevicePath) {
+    if (VarConsole != NULL) {
+      FreePool(VarConsole);
+    }
+  } else {
+    if (VarConsole != NULL) {
+      FreePool(VarConsole);
+    }
+    if (NewDevicePath != NULL) {
+      FreePool(NewDevicePath);
+    }
+  }
+
+  return Status;
+
+}
+
+
+/**
+  Connect the console device base on the variable ConVarName, if
+  device path of the ConVarName is multi-instance device path and
+  anyone of the instances is connected success, then this function
+  will return success.
+  If the handle associate with one device path node can not
+  be created successfully, then still give chance to do the dispatch,
+  which load the missing drivers if possible..
+
+  @param  ConVarName               Console related variable name, ConIn, ConOut,
+                                   ErrOut.
+
+  @retval EFI_NOT_FOUND            There is not any console devices connected
+                                   success
+  @retval EFI_SUCCESS              Success connect any one instance of the console
+                                   device path base on the variable ConVarName.
+
+**/
+EFI_STATUS
+EFIAPI
+BdsLibConnectConsoleVariable (
+  IN  CHAR16                 *ConVarName
+  )
+{
+  EFI_STATUS                Status;
+  EFI_DEVICE_PATH_PROTOCOL  *StartDevicePath;
+  UINTN                     VariableSize;
+  EFI_DEVICE_PATH_PROTOCOL  *Instance;
+  EFI_DEVICE_PATH_PROTOCOL  *Next;
+  EFI_DEVICE_PATH_PROTOCOL  *CopyOfDevicePath;
+  UINTN                     Size;
+  BOOLEAN                   DeviceExist;
+
+  Status      = EFI_SUCCESS;
+  DeviceExist = FALSE;
+
+  //
+  // Check if the console variable exist
+  //
+  StartDevicePath = BdsLibGetVariableAndSize (
+                      ConVarName,
+                      &gEfiGlobalVariableGuid,
+                      &VariableSize
+                      );
+  if (StartDevicePath == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  CopyOfDevicePath = StartDevicePath;
+  do {
+    //
+    // Check every instance of the console variable
+    //
+    Instance  = GetNextDevicePathInstance (&CopyOfDevicePath, &Size);
+    if (Instance == NULL) {
+      FreePool (StartDevicePath);
+      return EFI_UNSUPPORTED;
+    }
+    
+    Next      = Instance;
+    while (!IsDevicePathEndType (Next)) {
+      Next = NextDevicePathNode (Next);
+    }
+
+    SetDevicePathEndNode (Next);
+    //
+    // Connect the USB console
+    // USB console device path is a short-form device path that 
+    //  starts with the first element being a USB WWID
+    //  or a USB Class device path
+    //
+    if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) &&
+       ((DevicePathSubType (Instance) == MSG_USB_CLASS_DP)
+       || (DevicePathSubType (Instance) == MSG_USB_WWID_DP)
+       )) {
+      Status = BdsLibConnectUsbDevByShortFormDP (0xFF, Instance);
+      if (!EFI_ERROR (Status)) {
+        DeviceExist = TRUE;
+      }
+    } else {
+      //
+      // Connect the instance device path
+      //
+      Status = BdsLibConnectDevicePath (Instance);
+
+      if (EFI_ERROR (Status)) {
+        //
+        // Delete the instance from the console varialbe
+        //
+        BdsLibUpdateConsoleVariable (ConVarName, NULL, Instance);
+      } else {
+        DeviceExist = TRUE;
+      }
+    }
+    FreePool(Instance);
+  } while (CopyOfDevicePath != NULL);
+
+  FreePool (StartDevicePath);
+
+  if (!DeviceExist) {
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function will search every simpletext device in current system,
+  and make every simpletext device as pertantial console device.
+
+**/
+VOID
+EFIAPI
+BdsLibConnectAllConsoles (
+  VOID
+  )
+{
+  UINTN                     Index;
+  EFI_DEVICE_PATH_PROTOCOL  *ConDevicePath;
+  UINTN                     HandleCount;
+  EFI_HANDLE                *HandleBuffer;
+
+  Index         = 0;
+  HandleCount   = 0;
+  HandleBuffer  = NULL;
+  ConDevicePath = NULL;
+
+  //
+  // Update all the console variables
+  //
+  gBS->LocateHandleBuffer (
+          ByProtocol,
+          &gEfiSimpleTextInProtocolGuid,
+          NULL,
+          &HandleCount,
+          &HandleBuffer
+          );
+
+  for (Index = 0; Index < HandleCount; Index++) {
+    gBS->HandleProtocol (
+            HandleBuffer[Index],
+            &gEfiDevicePathProtocolGuid,
+            (VOID **) &ConDevicePath
+            );
+    BdsLibUpdateConsoleVariable (L"ConIn", ConDevicePath, NULL);
+  }
+
+  if (HandleBuffer != NULL) {
+    FreePool(HandleBuffer);
+    HandleBuffer = NULL;
+  }
+
+  gBS->LocateHandleBuffer (
+          ByProtocol,
+          &gEfiSimpleTextOutProtocolGuid,
+          NULL,
+          &HandleCount,
+          &HandleBuffer
+          );
+  for (Index = 0; Index < HandleCount; Index++) {
+    gBS->HandleProtocol (
+            HandleBuffer[Index],
+            &gEfiDevicePathProtocolGuid,
+            (VOID **) &ConDevicePath
+            );
+    BdsLibUpdateConsoleVariable (L"ConOut", ConDevicePath, NULL);
+    BdsLibUpdateConsoleVariable (L"ErrOut", ConDevicePath, NULL);
+  }
+
+  if (HandleBuffer != NULL) {
+    FreePool(HandleBuffer);
+  }
+
+  //
+  // Connect all console variables
+  //
+  BdsLibConnectAllDefaultConsoles ();
+
+}
+
+/**
+  This function will connect console device base on the console
+  device variable ConIn, ConOut and ErrOut.
+
+  @retval EFI_SUCCESS              At least one of the ConIn and ConOut device have
+                                   been connected success.
+  @retval EFI_STATUS               Return the status of BdsLibConnectConsoleVariable ().
+
+**/
+EFI_STATUS
+EFIAPI
+BdsLibConnectAllDefaultConsoles (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  BOOLEAN                   SystemTableUpdated;
+
+  //
+  // Connect all default console variables
+  //
+
+  //
+  // It seems impossible not to have any ConOut device on platform,
+  // so we check the status here.
+  //
+  Status = BdsLibConnectConsoleVariable (L"ConOut");
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Insert the performance probe for Console Out
+  //
+  PERF_START (NULL, "ConOut", "BDS", 1);
+  PERF_END (NULL, "ConOut", "BDS", 0);
+
+  //
+  // Because possibly the platform is legacy free, in such case,
+  // ConIn devices (Serial Port and PS2 Keyboard ) does not exist,
+  // so we need not check the status.
+  //
+  BdsLibConnectConsoleVariable (L"ConIn");
+
+  //
+  // The _ModuleEntryPoint err out var is legal.
+  //
+  BdsLibConnectConsoleVariable (L"ErrOut");
+
+  SystemTableUpdated = FALSE;
+  //
+  // Fill console handles in System Table if no console device assignd.
+  //
+  if (UpdateSystemTableConsole (L"ConIn", &gEfiSimpleTextInProtocolGuid, &gST->ConsoleInHandle, (VOID **) &gST->ConIn)) {
+    SystemTableUpdated = TRUE;
+  }
+  if (UpdateSystemTableConsole (L"ConOut", &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **) &gST->ConOut)) {
+    SystemTableUpdated = TRUE;
+  }
+  if (UpdateSystemTableConsole (L"ErrOut", &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **) &gST->StdErr)) {
+    SystemTableUpdated = TRUE;
+  }
+
+  if (SystemTableUpdated) {
+    //
+    // Update the CRC32 in the EFI System Table header
+    //
+    gST->Hdr.CRC32 = 0;
+    gBS->CalculateCrc32 (
+          (UINT8 *) &gST->Hdr,
+          gST->Hdr.HeaderSize,
+          &gST->Hdr.CRC32
+          );
+  }
+
+  //
+  // If any component set PcdTestKeyUsed to TRUE because use of a test key
+  // was detected, then display a warning message on the debug log and the console
+  //
+  if (PcdGetBool (PcdTestKeyUsed) == TRUE) {
+    DEBUG ((DEBUG_ERROR, "**********************************\n"));
+    DEBUG ((DEBUG_ERROR, "**  WARNING: Test Key is used.  **\n"));
+    DEBUG ((DEBUG_ERROR, "**********************************\n"));
+    Print (L"**  WARNING: Test Key is used.  **\n");
+  }
+
+  return EFI_SUCCESS;
+
+}
+
+/**
+  This function will connect console device except ConIn base on the console
+  device variable  ConOut and ErrOut.
+
+  @retval EFI_SUCCESS              At least one of the ConOut device have
+                                   been connected success.
+  @retval EFI_STATUS               Return the status of BdsLibConnectConsoleVariable ().
+
+**/
+EFI_STATUS
+EFIAPI
+BdsLibConnectAllDefaultConsolesWithOutConIn (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  BOOLEAN                   SystemTableUpdated;
+
+  //
+  // Connect all default console variables except ConIn
+  //
+
+  //
+  // It seems impossible not to have any ConOut device on platform,
+  // so we check the status here.
+  //
+  Status = BdsLibConnectConsoleVariable (L"ConOut");
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Insert the performance probe for Console Out
+  //
+  PERF_START (NULL, "ConOut", "BDS", 1);
+  PERF_END (NULL, "ConOut", "BDS", 0);
+
+  //
+  // The _ModuleEntryPoint err out var is legal.
+  //
+  BdsLibConnectConsoleVariable (L"ErrOut");
+
+  SystemTableUpdated = FALSE;
+  //
+  // Fill console handles in System Table if no console device assignd.
+  //
+  if (UpdateSystemTableConsole (L"ConOut", &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **) &gST->ConOut)) {
+    SystemTableUpdated = TRUE;
+  }
+  if (UpdateSystemTableConsole (L"ErrOut", &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **) &gST->StdErr)) {
+    SystemTableUpdated = TRUE;
+  }
+
+  if (SystemTableUpdated) {
+    //
+    // Update the CRC32 in the EFI System Table header
+    //
+    gST->Hdr.CRC32 = 0;
+    gBS->CalculateCrc32 (
+          (UINT8 *) &gST->Hdr,
+          gST->Hdr.HeaderSize,
+          &gST->Hdr.CRC32
+          );
+  }
+
+  return EFI_SUCCESS;
+
+}
+
+/**
+  Use SystemTable Conout to stop video based Simple Text Out consoles from going
+  to the video device. Put up LogoFile on every video device that is a console.
+
+  @param[in]  LogoFile   File name of logo to display on the center of the screen.
+
+  @retval EFI_SUCCESS     ConsoleControl has been flipped to graphics and logo displayed.
+  @retval EFI_UNSUPPORTED Logo not found
+
+**/
+EFI_STATUS
+EFIAPI
+EnableQuietBoot (
+  IN  EFI_GUID  *LogoFile
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_OEM_BADGING_PROTOCOL      *Badging;
+  UINT32                        SizeOfX;
+  UINT32                        SizeOfY;
+  INTN                          DestX;
+  INTN                          DestY;
+  UINT8                         *ImageData;
+  UINTN                         ImageSize;
+  UINTN                         BltSize;
+  UINT32                        Instance;
+  EFI_BADGING_FORMAT            Format;
+  EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;
+  UINTN                         CoordinateX;
+  UINTN                         CoordinateY;
+  UINTN                         Height;
+  UINTN                         Width;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
+  EFI_UGA_DRAW_PROTOCOL         *UgaDraw;
+  UINT32                        ColorDepth;
+  UINT32                        RefreshRate;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL  *GraphicsOutput;
+  EFI_BOOT_LOGO_PROTOCOL        *BootLogo;
+  UINTN                         NumberOfLogos;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LogoBlt;
+  UINTN                         LogoDestX;
+  UINTN                         LogoDestY;
+  UINTN                         LogoHeight;
+  UINTN                         LogoWidth;
+  UINTN                         NewDestX;
+  UINTN                         NewDestY;
+  UINTN                         NewHeight;
+  UINTN                         NewWidth;
+  UINT64                        BufferSize;
+
+  UgaDraw = NULL;
+  //
+  // Try to open GOP first
+  //
+  Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);
+  if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
+    GraphicsOutput = NULL;
+    //
+    // Open GOP failed, try to open UGA
+    //
+    Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);
+  }
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Try to open Boot Logo Protocol.
+  //
+  BootLogo = NULL;
+  gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo);
+
+  //
+  // Erase Cursor from screen
+  //
+  gST->ConOut->EnableCursor (gST->ConOut, FALSE);
+
+  Badging = NULL;
+  Status  = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);
+
+  if (GraphicsOutput != NULL) {
+    SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;
+    SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;
+
+  } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
+    Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  } else {
+    return EFI_UNSUPPORTED;
+  }
+
+  Blt = NULL;
+  NumberOfLogos = 0;
+  LogoDestX = 0;
+  LogoDestY = 0;
+  LogoHeight = 0;
+  LogoWidth = 0;
+  NewDestX = 0;
+  NewDestY = 0;
+  NewHeight = 0;
+  NewWidth = 0;
+  Instance = 0;
+  while (1) {
+    ImageData = NULL;
+    ImageSize = 0;
+
+    if (Badging != NULL) {
+      //
+      // Get image from OEMBadging protocol.
+      //
+      Status = Badging->GetImage (
+                          Badging,
+                          &Instance,
+                          &Format,
+                          &ImageData,
+                          &ImageSize,
+                          &Attribute,
+                          &CoordinateX,
+                          &CoordinateY
+                          );
+      if (EFI_ERROR (Status)) {
+        goto Done;
+      }
+
+      //
+      // Currently only support BMP format.
+      //
+      if (Format != EfiBadgingFormatBMP) {
+        if (ImageData != NULL) {
+          FreePool (ImageData);
+        }
+        continue;
+      }
+    } else {
+      //
+      // Get the specified image from FV.
+      //
+      Status = GetSectionFromAnyFv (LogoFile, EFI_SECTION_RAW, 0, (VOID **) &ImageData, &ImageSize);
+      if (EFI_ERROR (Status)) {
+        return EFI_UNSUPPORTED;
+      }
+
+      CoordinateX = 0;
+      CoordinateY = 0;
+      if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
+        Attribute   = EfiBadgingDisplayAttributeCenter;
+      } else {
+        Attribute   = EfiBadgingDisplayAttributeCustomized;
+      } 
+    }
+
+    if (Blt != NULL) {
+      FreePool (Blt);
+    }
+    Blt = NULL;
+    Status = TranslateBmpToGopBlt (
+              ImageData,
+              ImageSize,
+              &Blt,
+              &BltSize,
+              &Height,
+              &Width
+              );
+    if (EFI_ERROR (Status)) {
+      FreePool (ImageData);
+
+      if (Badging == NULL) {
+        return Status;
+      } else {
+        continue;
+      }
+    }
+
+    //
+    // Calculate the display position according to Attribute.
+    //
+    switch (Attribute) {
+    case EfiBadgingDisplayAttributeLeftTop:
+      DestX = CoordinateX;
+      DestY = CoordinateY;
+      break;
+
+    case EfiBadgingDisplayAttributeCenterTop:
+      DestX = (SizeOfX - Width) / 2;
+      DestY = CoordinateY;
+      break;
+
+    case EfiBadgingDisplayAttributeRightTop:
+      DestX = (SizeOfX - Width - CoordinateX);
+      DestY = CoordinateY;;
+      break;
+
+    case EfiBadgingDisplayAttributeCenterRight:
+      DestX = (SizeOfX - Width - CoordinateX);
+      DestY = (SizeOfY - Height) / 2;
+      break;
+
+    case EfiBadgingDisplayAttributeRightBottom:
+      DestX = (SizeOfX - Width - CoordinateX);
+      DestY = (SizeOfY - Height - CoordinateY);
+      break;
+
+    case EfiBadgingDisplayAttributeCenterBottom:
+      DestX = (SizeOfX - Width) / 2;
+      DestY = (SizeOfY - Height - CoordinateY);
+      break;
+
+    case EfiBadgingDisplayAttributeLeftBottom:
+      DestX = CoordinateX;
+      DestY = (SizeOfY - Height - CoordinateY);
+      break;
+
+    case EfiBadgingDisplayAttributeCenterLeft:
+      DestX = CoordinateX;
+      DestY = (SizeOfY - Height) / 2;
+      break;
+
+    case EfiBadgingDisplayAttributeCenter:
+      DestX = (SizeOfX - Width) / 2;
+      DestY = (SizeOfY - Height) / 2;
+      break;
+
+    case EfiBadgingDisplayAttributeCustomized:
+      DestX = (SizeOfX - Width) / 2;
+      DestY = ((SizeOfY * 382) / 1000) - Height / 2;
+      break;
+
+    default:
+      DestX = CoordinateX;
+      DestY = CoordinateY;
+      break;
+    }
+
+    if ((DestX >= 0) && (DestY >= 0)) {
+      if (GraphicsOutput != NULL) {
+        Status = GraphicsOutput->Blt (
+                            GraphicsOutput,
+                            Blt,
+                            EfiBltBufferToVideo,
+                            0,
+                            0,
+                            (UINTN) DestX,
+                            (UINTN) DestY,
+                            Width,
+                            Height,
+                            Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+                            );
+      } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
+        Status = UgaDraw->Blt (
+                            UgaDraw,
+                            (EFI_UGA_PIXEL *) Blt,
+                            EfiUgaBltBufferToVideo,
+                            0,
+                            0,
+                            (UINTN) DestX,
+                            (UINTN) DestY,
+                            Width,
+                            Height,
+                            Width * sizeof (EFI_UGA_PIXEL)
+                            );
+      } else {
+        Status = EFI_UNSUPPORTED;
+      }
+
+      //
+      // Report displayed Logo information.
+      //
+      if (!EFI_ERROR (Status)) {
+        NumberOfLogos++;
+
+        if (LogoWidth == 0) {
+          //
+          // The first Logo.
+          //
+          LogoDestX = (UINTN) DestX;
+          LogoDestY = (UINTN) DestY;
+          LogoWidth = Width;
+          LogoHeight = Height;
+        } else {
+          //
+          // Merge new logo with old one.
+          //
+          NewDestX = MIN ((UINTN) DestX, LogoDestX);
+          NewDestY = MIN ((UINTN) DestY, LogoDestY);
+          NewWidth = MAX ((UINTN) DestX + Width, LogoDestX + LogoWidth) - NewDestX;
+          NewHeight = MAX ((UINTN) DestY + Height, LogoDestY + LogoHeight) - NewDestY;
+
+          LogoDestX = NewDestX;
+          LogoDestY = NewDestY;
+          LogoWidth = NewWidth;
+          LogoHeight = NewHeight;
+        }
+      }
+    }
+
+    FreePool (ImageData);
+
+    if (Badging == NULL) {
+      break;
+    }
+  }
+
+Done:
+  if (BootLogo == NULL || NumberOfLogos == 0) {
+    //
+    // No logo displayed.
+    //
+    if (Blt != NULL) {
+      FreePool (Blt);
+    }
+
+    return Status;
+  }
+
+  //
+  // Advertise displayed Logo information.
+  //
+  if (NumberOfLogos == 1) {
+    //
+    // Only one logo displayed, use its Blt buffer directly for BootLogo protocol.
+    //
+    LogoBlt = Blt;
+    Status = EFI_SUCCESS;
+  } else {
+    //
+    // More than one Logo displayed, get merged BltBuffer using VideoToBuffer operation. 
+    //
+    if (Blt != NULL) {
+      FreePool (Blt);
+    }
+
+    //
+    // Ensure the LogoHeight * LogoWidth doesn't overflow
+    //
+    if (LogoHeight > DivU64x64Remainder ((UINTN) ~0, LogoWidth, NULL)) {
+      return EFI_UNSUPPORTED;
+    }
+    BufferSize = MultU64x64 (LogoWidth, LogoHeight);
+
+    //
+    // Ensure the BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
+    //
+    if (BufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
+      return EFI_UNSUPPORTED;
+    }
+
+    LogoBlt = AllocateZeroPool ((UINTN)BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+    if (LogoBlt == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    if (GraphicsOutput != NULL) {
+      Status = GraphicsOutput->Blt (
+                          GraphicsOutput,
+                          LogoBlt,
+                          EfiBltVideoToBltBuffer,
+                          LogoDestX,
+                          LogoDestY,
+                          0,
+                          0,
+                          LogoWidth,
+                          LogoHeight,
+                          LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+                          );
+    } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
+      Status = UgaDraw->Blt (
+                          UgaDraw,
+                          (EFI_UGA_PIXEL *) LogoBlt,
+                          EfiUgaVideoToBltBuffer,
+                          LogoDestX,
+                          LogoDestY,
+                          0,
+                          0,
+                          LogoWidth,
+                          LogoHeight,
+                          LogoWidth * sizeof (EFI_UGA_PIXEL)
+                          );
+    } else {
+      Status = EFI_UNSUPPORTED;
+    }
+  }
+
+  if (!EFI_ERROR (Status)) {
+    BootLogo->SetBootLogo (BootLogo, LogoBlt, LogoDestX, LogoDestY, LogoWidth, LogoHeight);
+  }
+  FreePool (LogoBlt);
+
+  return Status;
+}
+
+/**
+  Use SystemTable Conout to turn on video based Simple Text Out consoles. The 
+  Simple Text Out screens will now be synced up with all non video output devices
+
+  @retval EFI_SUCCESS     UGA devices are back in text mode and synced up.
+
+**/
+EFI_STATUS
+EFIAPI
+DisableQuietBoot (
+  VOID
+  )
+{
+
+  //
+  // Enable Cursor on Screen
+  //
+  gST->ConOut->EnableCursor (gST->ConOut, TRUE);
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c
new file mode 100644
index 0000000000..313a1ea9f6
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c
@@ -0,0 +1,1575 @@
+/** @file
+  Misc BDS library function
+
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalBdsLib.h"
+
+
+#define MAX_STRING_LEN        200
+
+BOOLEAN   mFeaturerSwitch = TRUE;
+BOOLEAN   mResetRequired  = FALSE;
+
+extern UINT16 gPlatformBootTimeOutDefault;
+
+/**
+  The function will go through the driver option link list, load and start
+  every driver the driver option device path point to.
+
+  @param  BdsDriverLists        The header of the current driver option link list
+
+**/
+VOID
+EFIAPI
+BdsLibLoadDrivers (
+  IN LIST_ENTRY                   *BdsDriverLists
+  )
+{
+  EFI_STATUS                Status;
+  LIST_ENTRY                *Link;
+  BDS_COMMON_OPTION         *Option;
+  EFI_HANDLE                ImageHandle;
+  EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;
+  UINTN                     ExitDataSize;
+  CHAR16                    *ExitData;
+  BOOLEAN                   ReconnectAll;
+
+  ReconnectAll = FALSE;
+
+  //
+  // Process the driver option
+  //
+  for (Link = BdsDriverLists->ForwardLink; Link != BdsDriverLists; Link = Link->ForwardLink) {
+    Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
+    
+    //
+    // If a load option is not marked as LOAD_OPTION_ACTIVE,
+    // the boot manager will not automatically load the option.
+    //
+    if (!IS_LOAD_OPTION_TYPE (Option->Attribute, LOAD_OPTION_ACTIVE)) {
+      continue;
+    }
+    
+    //
+    // If a driver load option is marked as LOAD_OPTION_FORCE_RECONNECT,
+    // then all of the EFI drivers in the system will be disconnected and
+    // reconnected after the last driver load option is processed.
+    //
+    if (IS_LOAD_OPTION_TYPE (Option->Attribute, LOAD_OPTION_FORCE_RECONNECT)) {
+      ReconnectAll = TRUE;
+    }
+    
+    //
+    // Make sure the driver path is connected.
+    //
+    BdsLibConnectDevicePath (Option->DevicePath);
+
+    //
+    // Load and start the image that Driver#### describes
+    //
+    Status = gBS->LoadImage (
+                    FALSE,
+                    gImageHandle,
+                    Option->DevicePath,
+                    NULL,
+                    0,
+                    &ImageHandle
+                    );
+
+    if (!EFI_ERROR (Status)) {
+      gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &ImageInfo);
+
+      //
+      // Verify whether this image is a driver, if not,
+      // exit it and continue to parse next load option
+      //
+      if (ImageInfo->ImageCodeType != EfiBootServicesCode && ImageInfo->ImageCodeType != EfiRuntimeServicesCode) {
+        gBS->Exit (ImageHandle, EFI_INVALID_PARAMETER, 0, NULL);
+        continue;
+      }
+
+      if (Option->LoadOptionsSize != 0) {
+        ImageInfo->LoadOptionsSize  = Option->LoadOptionsSize;
+        ImageInfo->LoadOptions      = Option->LoadOptions;
+      }
+      //
+      // Before calling the image, enable the Watchdog Timer for
+      // the 5 Minute period
+      //
+      gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);
+
+      Status = gBS->StartImage (ImageHandle, &ExitDataSize, &ExitData);
+      DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Driver Return Status = %r\n", Status));
+
+      //
+      // Clear the Watchdog Timer after the image returns
+      //
+      gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
+    }
+  }
+  
+  //
+  // Process the LOAD_OPTION_FORCE_RECONNECT driver option
+  //
+  if (ReconnectAll) {
+    BdsLibDisconnectAllEfi ();
+    BdsLibConnectAll ();
+  }
+
+}
+
+/**
+  Get the Option Number that does not used.
+  Try to locate the specific option variable one by one utile find a free number.
+
+  @param  VariableName          Indicate if the boot#### or driver#### option
+
+  @return The Minimal Free Option Number
+
+**/
+UINT16
+BdsLibGetFreeOptionNumber (
+  IN  CHAR16    *VariableName
+  )
+{
+  UINTN         Index;
+  CHAR16        StrTemp[10];
+  UINT16        *OptionBuffer;
+  UINTN         OptionSize;
+
+  //
+  // Try to find the minimum free number from 0, 1, 2, 3....
+  //
+  Index = 0;
+  do {
+    if (*VariableName == 'B') {
+      UnicodeSPrint (StrTemp, sizeof (StrTemp), L"Boot%04x", Index);
+    } else {
+      UnicodeSPrint (StrTemp, sizeof (StrTemp), L"Driver%04x", Index);
+    }
+    //
+    // try if the option number is used
+    //
+    OptionBuffer = BdsLibGetVariableAndSize (
+                     StrTemp,
+                     &gEfiGlobalVariableGuid,
+                     &OptionSize
+                     );
+    if (OptionBuffer == NULL) {
+      break;
+    }
+    FreePool(OptionBuffer);
+    Index++;
+  } while (TRUE);
+
+  return ((UINT16) Index);
+}
+
+
+/**
+  This function will register the new boot#### or driver#### option base on
+  the VariableName. The new registered boot#### or driver#### will be linked
+  to BdsOptionList and also update to the VariableName. After the boot#### or
+  driver#### updated, the BootOrder or DriverOrder will also be updated.
+
+  @param  BdsOptionList         The header of the boot#### or driver#### link list
+  @param  DevicePath            The device path which the boot#### or driver####
+                                option present
+  @param  String                The description of the boot#### or driver####
+  @param  VariableName          Indicate if the boot#### or driver#### option
+
+  @retval EFI_SUCCESS           The boot#### or driver#### have been success
+                                registered
+  @retval EFI_STATUS            Return the status of gRT->SetVariable ().
+
+**/
+EFI_STATUS
+EFIAPI
+BdsLibRegisterNewOption (
+  IN  LIST_ENTRY                     *BdsOptionList,
+  IN  EFI_DEVICE_PATH_PROTOCOL       *DevicePath,
+  IN  CHAR16                         *String,
+  IN  CHAR16                         *VariableName
+  )
+{
+  EFI_STATUS                Status;
+  UINTN                     Index;
+  UINT16                    RegisterOptionNumber;
+  UINT16                    *TempOptionPtr;
+  UINTN                     TempOptionSize;
+  UINT16                    *OptionOrderPtr;
+  VOID                      *OptionPtr;
+  UINTN                     OptionSize;
+  UINT8                     *TempPtr;
+  EFI_DEVICE_PATH_PROTOCOL  *OptionDevicePath;
+  CHAR16                    *Description;
+  CHAR16                    OptionName[10];
+  BOOLEAN                   UpdateDescription;
+  UINT16                    BootOrderEntry;
+  UINTN                     OrderItemNum;
+
+  if (DevicePath == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  OptionPtr             = NULL;
+  OptionSize            = 0;
+  TempPtr               = NULL;
+  OptionDevicePath      = NULL;
+  Description           = NULL;
+  OptionOrderPtr        = NULL;
+  UpdateDescription     = FALSE;
+  Status                = EFI_SUCCESS;
+  ZeroMem (OptionName, sizeof (OptionName));
+
+  TempOptionSize = 0;
+  TempOptionPtr = BdsLibGetVariableAndSize (
+                    VariableName,
+                    &gEfiGlobalVariableGuid,
+                    &TempOptionSize
+                    );
+  //
+  // Compare with current option variable if the previous option is set in global variable.
+  //
+  for (Index = 0; Index < TempOptionSize / sizeof (UINT16); Index++) {
+    //
+    // TempOptionPtr must not be NULL if we have non-zero TempOptionSize.
+    //
+    ASSERT (TempOptionPtr != NULL);
+
+    if (*VariableName == 'B') {
+      UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", TempOptionPtr[Index]);
+    } else {
+      UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", TempOptionPtr[Index]);
+    }
+
+    OptionPtr = BdsLibGetVariableAndSize (
+                  OptionName,
+                  &gEfiGlobalVariableGuid,
+                  &OptionSize
+                  );
+    if (OptionPtr == NULL) {
+      continue;
+    }
+
+    //
+    // Validate the variable.
+    //
+    if (!ValidateOption(OptionPtr, OptionSize)) {
+      FreePool(OptionPtr);
+      continue;
+    }
+
+    TempPtr         =   OptionPtr;
+    TempPtr         +=  sizeof (UINT32) + sizeof (UINT16);
+    Description     =   (CHAR16 *) TempPtr;
+    TempPtr         +=  StrSize ((CHAR16 *) TempPtr);
+    OptionDevicePath =  (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
+
+    //
+    // Notes: the description may will change base on the GetStringToken
+    //
+    if (CompareMem (OptionDevicePath, DevicePath, GetDevicePathSize (OptionDevicePath)) == 0) {
+      if (CompareMem (Description, String, StrSize (Description)) == 0) { 
+        //
+        // Got the option, so just return
+        //
+        FreePool (OptionPtr);
+        FreePool (TempOptionPtr);
+        return EFI_SUCCESS;
+      } else {
+        //
+        // Option description changed, need update.
+        //
+        UpdateDescription = TRUE;
+        FreePool (OptionPtr);
+        break;
+      }
+    }
+
+    FreePool (OptionPtr);
+  }
+
+  OptionSize          = sizeof (UINT32) + sizeof (UINT16) + StrSize (String);
+  OptionSize          += GetDevicePathSize (DevicePath);
+  OptionPtr           = AllocateZeroPool (OptionSize);
+  ASSERT (OptionPtr != NULL);
+  
+  TempPtr             = OptionPtr;
+  *(UINT32 *) TempPtr = LOAD_OPTION_ACTIVE;
+  TempPtr             += sizeof (UINT32);
+  *(UINT16 *) TempPtr = (UINT16) GetDevicePathSize (DevicePath);
+  TempPtr             += sizeof (UINT16);
+  CopyMem (TempPtr, String, StrSize (String));
+  TempPtr             += StrSize (String);
+  CopyMem (TempPtr, DevicePath, GetDevicePathSize (DevicePath));
+
+  if (UpdateDescription) {
+    //
+    // The number in option#### to be updated. 
+    // In this case, we must have non-NULL TempOptionPtr.
+    //
+    ASSERT (TempOptionPtr != NULL);
+    RegisterOptionNumber = TempOptionPtr[Index];
+  } else {
+    //
+    // The new option#### number
+    //
+    RegisterOptionNumber = BdsLibGetFreeOptionNumber(VariableName);
+  }
+
+  if (*VariableName == 'B') {
+    UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", RegisterOptionNumber);
+  } else {
+    UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", RegisterOptionNumber);
+  }
+
+  Status = gRT->SetVariable (
+                  OptionName,
+                  &gEfiGlobalVariableGuid,
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                  OptionSize,
+                  OptionPtr
+                  );
+  //
+  // Return if only need to update a changed description or fail to set option.
+  //
+  if (EFI_ERROR (Status) || UpdateDescription) {
+    FreePool (OptionPtr);
+    if (TempOptionPtr != NULL) {
+      FreePool (TempOptionPtr);
+    }
+    return Status;
+  }
+
+  FreePool (OptionPtr);
+
+  //
+  // Update the option order variable
+  //
+
+  //
+  // If no option order
+  //
+  if (TempOptionSize == 0) {
+    BootOrderEntry = 0;
+    Status = gRT->SetVariable (
+                    VariableName,
+                    &gEfiGlobalVariableGuid,
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                    sizeof (UINT16),
+                    &BootOrderEntry
+                    );
+    if (TempOptionPtr != NULL) {
+      FreePool (TempOptionPtr);
+    }
+    return Status;
+  }
+  
+  //
+  // TempOptionPtr must not be NULL if TempOptionSize is not zero.
+  //
+  ASSERT (TempOptionPtr != NULL);
+  //
+  // Append the new option number to the original option order
+  //
+  OrderItemNum = (TempOptionSize / sizeof (UINT16)) + 1 ;
+  OptionOrderPtr = AllocateZeroPool ( OrderItemNum * sizeof (UINT16));
+  ASSERT (OptionOrderPtr!= NULL);
+  CopyMem (OptionOrderPtr, TempOptionPtr, (OrderItemNum - 1) * sizeof (UINT16));
+
+  OptionOrderPtr[Index] = RegisterOptionNumber;
+
+  Status = gRT->SetVariable (
+                  VariableName,
+                  &gEfiGlobalVariableGuid,
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                  OrderItemNum * sizeof (UINT16),
+                  OptionOrderPtr
+                  );
+  FreePool (TempOptionPtr);
+  FreePool (OptionOrderPtr);
+
+  return Status;
+}
+
+/**
+  Returns the size of a device path in bytes.
+
+  This function returns the size, in bytes, of the device path data structure 
+  specified by DevicePath including the end of device path node. If DevicePath 
+  is NULL, then 0 is returned. If the length of the device path is bigger than
+  MaxSize, also return 0 to indicate this is an invalidate device path.
+
+  @param  DevicePath         A pointer to a device path data structure.
+  @param  MaxSize            Max valid device path size. If big than this size, 
+                             return error.
+  
+  @retval 0                  An invalid device path.
+  @retval Others             The size of a device path in bytes.
+
+**/
+UINTN
+GetDevicePathSizeEx (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
+  IN UINTN                           MaxSize
+  )
+{
+  UINTN  Size;
+  UINTN  NodeSize;
+
+  if (DevicePath == NULL) {
+    return 0;
+  }
+
+  //
+  // Search for the end of the device path structure
+  //
+  Size = 0;
+  while (!IsDevicePathEnd (DevicePath)) {
+    NodeSize = DevicePathNodeLength (DevicePath);
+    if (NodeSize < END_DEVICE_PATH_LENGTH) {
+      return 0;
+    }
+    Size += NodeSize;
+    if (Size > MaxSize) {
+      return 0;
+    }
+    DevicePath = NextDevicePathNode (DevicePath);
+  }
+  Size += DevicePathNodeLength (DevicePath);
+  if (Size > MaxSize) {
+    return 0;
+  }
+
+  return Size;
+}
+
+/**
+  Returns the length of a Null-terminated Unicode string. If the length is 
+  bigger than MaxStringLen, return length 0 to indicate that this is an 
+  invalidate string.
+
+  This function returns the byte length of Unicode characters in the Null-terminated
+  Unicode string specified by String. 
+
+  If String is NULL, then ASSERT().
+  If String is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param  String           A pointer to a Null-terminated Unicode string.
+  @param  MaxStringLen     Max string len in this string.
+
+  @retval 0                An invalid string.
+  @retval Others           The length of String.
+
+**/
+UINTN
+StrSizeEx (
+  IN      CONST CHAR16              *String,
+  IN      UINTN                     MaxStringLen
+  )
+{
+  UINTN                             Length;
+
+  ASSERT (String != NULL && MaxStringLen != 0);
+  ASSERT (((UINTN) String & BIT0) == 0);
+
+  for (Length = 0; *String != L'\0' && MaxStringLen != Length; String++, Length+=2);
+
+  if (*String != L'\0' && MaxStringLen == Length) {
+    return 0;
+  }
+
+  return Length + 2;
+}
+
+/**
+  Validate the EFI Boot#### variable (VendorGuid/Name)
+
+  @param  Variable              Boot#### variable data.
+  @param  VariableSize          Returns the size of the EFI variable that was read
+
+  @retval TRUE                  The variable data is correct.
+  @retval FALSE                 The variable data is corrupted.
+
+**/
+BOOLEAN 
+ValidateOption (
+  UINT8                     *Variable,
+  UINTN                     VariableSize
+  )
+{
+  UINT16                    FilePathSize;
+  UINT8                     *TempPtr;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  UINTN                     TempSize;
+
+  if (VariableSize <= sizeof (UINT16) + sizeof (UINT32)) {
+    return FALSE;
+  }
+
+  //
+  // Skip the option attribute
+  //
+  TempPtr    = Variable;
+  TempPtr   += sizeof (UINT32);
+
+  //
+  // Get the option's device path size
+  //
+  FilePathSize  = *(UINT16 *) TempPtr;
+  TempPtr      += sizeof (UINT16);
+
+  //
+  // Get the option's description string size
+  //
+  TempSize = StrSizeEx ((CHAR16 *) TempPtr, VariableSize - sizeof (UINT16) - sizeof (UINT32));
+  TempPtr += TempSize;
+
+  //
+  // Get the option's device path
+  //
+  DevicePath =  (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
+  TempPtr   += FilePathSize;
+
+  //
+  // Validation boot option variable.
+  //
+  if ((FilePathSize == 0) || (TempSize == 0)) {
+    return FALSE;
+  }
+
+  if (TempSize + FilePathSize + sizeof (UINT16) + sizeof (UINT32) > VariableSize) {
+    return FALSE;
+  }
+
+  return (BOOLEAN) (GetDevicePathSizeEx (DevicePath, FilePathSize) != 0);
+}
+
+/**
+  Convert a single character to number.
+  It assumes the input Char is in the scope of L'0' ~ L'9' and L'A' ~ L'F'
+  
+  @param Char    The input char which need to change to a hex number.
+  
+**/
+UINTN
+CharToUint (
+  IN CHAR16                           Char
+  )
+{
+  if ((Char >= L'0') && (Char <= L'9')) {
+    return (UINTN) (Char - L'0');
+  }
+
+  if ((Char >= L'A') && (Char <= L'F')) {
+    return (UINTN) (Char - L'A' + 0xA);
+  }
+
+  ASSERT (FALSE);
+  return 0;
+}
+
+/**
+  Build the boot#### or driver#### option from the VariableName, the
+  build boot#### or driver#### will also be linked to BdsCommonOptionList.
+
+  @param  BdsCommonOptionList   The header of the boot#### or driver#### option
+                                link list
+  @param  VariableName          EFI Variable name indicate if it is boot#### or
+                                driver####
+
+  @retval BDS_COMMON_OPTION     Get the option just been created
+  @retval NULL                  Failed to get the new option
+
+**/
+BDS_COMMON_OPTION *
+EFIAPI
+BdsLibVariableToOption (
+  IN OUT LIST_ENTRY                   *BdsCommonOptionList,
+  IN  CHAR16                          *VariableName
+  )
+{
+  UINT32                    Attribute;
+  UINT16                    FilePathSize;
+  UINT8                     *Variable;
+  UINT8                     *TempPtr;
+  UINTN                     VariableSize;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  BDS_COMMON_OPTION         *Option;
+  VOID                      *LoadOptions;
+  UINT32                    LoadOptionsSize;
+  CHAR16                    *Description;
+  UINT8                     NumOff;
+
+  //
+  // Read the variable. We will never free this data.
+  //
+  Variable = BdsLibGetVariableAndSize (
+              VariableName,
+              &gEfiGlobalVariableGuid,
+              &VariableSize
+              );
+  if (Variable == NULL) {
+    return NULL;
+  }
+
+  //
+  // Validate Boot#### variable data.
+  //
+  if (!ValidateOption(Variable, VariableSize)) {
+    FreePool (Variable);
+    return NULL;
+  }
+
+  //
+  // Notes: careful defined the variable of Boot#### or
+  // Driver####, consider use some macro to abstract the code
+  //
+  //
+  // Get the option attribute
+  //
+  TempPtr   =  Variable;
+  Attribute =  *(UINT32 *) Variable;
+  TempPtr   += sizeof (UINT32);
+
+  //
+  // Get the option's device path size
+  //
+  FilePathSize =  *(UINT16 *) TempPtr;
+  TempPtr      += sizeof (UINT16);
+
+  //
+  // Get the option's description string
+  //
+  Description = (CHAR16 *) TempPtr;
+
+  //
+  // Get the option's description string size
+  //
+  TempPtr += StrSize((CHAR16 *) TempPtr);
+
+  //
+  // Get the option's device path
+  //
+  DevicePath =  (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
+  TempPtr    += FilePathSize;
+
+  //
+  // Get load opion data.
+  //
+  LoadOptions     = TempPtr;
+  LoadOptionsSize = (UINT32) (VariableSize - (UINTN) (TempPtr - Variable));
+
+  //
+  // The Console variables may have multiple device paths, so make
+  // an Entry for each one.
+  //
+  Option = AllocateZeroPool (sizeof (BDS_COMMON_OPTION));
+  if (Option == NULL) {
+    FreePool (Variable);
+    return NULL;
+  }
+
+  Option->Signature   = BDS_LOAD_OPTION_SIGNATURE;
+  Option->DevicePath  = AllocateZeroPool (GetDevicePathSize (DevicePath));
+  ASSERT(Option->DevicePath != NULL);
+  CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize (DevicePath));
+
+  Option->Attribute   = Attribute;
+  Option->Description = AllocateZeroPool (StrSize (Description));
+  ASSERT(Option->Description != NULL);
+  CopyMem (Option->Description, Description, StrSize (Description));
+
+  Option->LoadOptions = AllocateZeroPool (LoadOptionsSize);
+  ASSERT(Option->LoadOptions != NULL);
+  CopyMem (Option->LoadOptions, LoadOptions, LoadOptionsSize);
+  Option->LoadOptionsSize = LoadOptionsSize;
+
+  //
+  // Get the value from VariableName Unicode string
+  // since the ISO standard assumes ASCII equivalent abbreviations, we can be safe in converting this
+  // Unicode stream to ASCII without any loss in meaning.
+  //
+  if (*VariableName == 'B') {
+    NumOff = (UINT8) (sizeof (L"Boot") / sizeof (CHAR16) - 1);
+    Option->BootCurrent = (UINT16) (CharToUint (VariableName[NumOff+0]) * 0x1000) 
+               + (UINT16) (CharToUint (VariableName[NumOff+1]) * 0x100)
+               + (UINT16) (CharToUint (VariableName[NumOff+2]) * 0x10)
+               + (UINT16) (CharToUint (VariableName[NumOff+3]) * 0x1);
+  }
+  InsertTailList (BdsCommonOptionList, &Option->Link);
+  FreePool (Variable);
+  return Option;
+}
+
+/**
+  Process BootOrder, or DriverOrder variables, by calling
+  BdsLibVariableToOption () for each UINT16 in the variables.
+
+  @param  BdsCommonOptionList   The header of the option list base on variable
+                                VariableName
+  @param  VariableName          EFI Variable name indicate the BootOrder or
+                                DriverOrder
+
+  @retval EFI_SUCCESS           Success create the boot option or driver option
+                                list
+  @retval EFI_OUT_OF_RESOURCES  Failed to get the boot option or driver option list
+
+**/
+EFI_STATUS
+EFIAPI
+BdsLibBuildOptionFromVar (
+  IN  LIST_ENTRY                      *BdsCommonOptionList,
+  IN  CHAR16                          *VariableName
+  )
+{
+  UINT16            *OptionOrder;
+  UINTN             OptionOrderSize;
+  UINTN             Index;
+  BDS_COMMON_OPTION *Option;
+  CHAR16            OptionName[20];
+
+  //
+  // Zero Buffer in order to get all BOOT#### variables
+  //
+  ZeroMem (OptionName, sizeof (OptionName));
+
+  //
+  // Read the BootOrder, or DriverOrder variable.
+  //
+  OptionOrder = BdsLibGetVariableAndSize (
+                  VariableName,
+                  &gEfiGlobalVariableGuid,
+                  &OptionOrderSize
+                  );
+  if (OptionOrder == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  for (Index = 0; Index < OptionOrderSize / sizeof (UINT16); Index++) {
+    if (*VariableName == 'B') {
+      UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", OptionOrder[Index]);
+    } else {
+      UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", OptionOrder[Index]);
+    }
+
+    Option              = BdsLibVariableToOption (BdsCommonOptionList, OptionName);
+    if (Option != NULL) {
+      Option->BootCurrent = OptionOrder[Index];
+    }
+  }
+
+  FreePool (OptionOrder);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Get boot mode by looking up configuration table and parsing HOB list
+
+  @param  BootMode              Boot mode from PEI handoff HOB.
+
+  @retval EFI_SUCCESS           Successfully get boot mode
+
+**/
+EFI_STATUS
+EFIAPI
+BdsLibGetBootMode (
+  OUT EFI_BOOT_MODE       *BootMode
+  )
+{
+  *BootMode = GetBootModeHob ();
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
+  buffer, and the size of the buffer. If failure return NULL.
+
+  @param  Name                  String part of EFI variable name
+  @param  VendorGuid            GUID part of EFI variable name
+  @param  VariableSize          Returns the size of the EFI variable that was read
+
+  @return                       Dynamically allocated memory that contains a copy of the EFI variable
+                                Caller is responsible freeing the buffer.
+  @retval NULL                  Variable was not read
+
+**/
+VOID *
+EFIAPI
+BdsLibGetVariableAndSize (
+  IN  CHAR16              *Name,
+  IN  EFI_GUID            *VendorGuid,
+  OUT UINTN               *VariableSize
+  )
+{
+  EFI_STATUS  Status;
+  UINTN       BufferSize;
+  VOID        *Buffer;
+
+  Buffer = NULL;
+
+  //
+  // Pass in a zero size buffer to find the required buffer size.
+  //
+  BufferSize  = 0;
+  Status      = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
+  if (Status == EFI_BUFFER_TOO_SMALL) {
+    //
+    // Allocate the buffer to return
+    //
+    Buffer = AllocateZeroPool (BufferSize);
+    if (Buffer == NULL) {
+      *VariableSize = 0;
+      return NULL;
+    }
+    //
+    // Read variable into the allocated buffer.
+    //
+    Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
+    if (EFI_ERROR (Status)) {
+      FreePool (Buffer);
+      BufferSize = 0;
+      Buffer     = NULL;
+    }
+  }
+
+  ASSERT (((Buffer == NULL) && (BufferSize == 0)) ||
+          ((Buffer != NULL) && (BufferSize != 0))
+          );
+  *VariableSize = BufferSize;
+  return Buffer;
+}
+
+/**
+  Delete the instance in Multi which matches partly with Single instance
+
+  @param  Multi                 A pointer to a multi-instance device path data
+                                structure.
+  @param  Single                A pointer to a single-instance device path data
+                                structure.
+
+  @return This function will remove the device path instances in Multi which partly
+          match with the Single, and return the result device path. If there is no
+          remaining device path as a result, this function will return NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+BdsLibDelPartMatchInstance (
+  IN     EFI_DEVICE_PATH_PROTOCOL  *Multi,
+  IN     EFI_DEVICE_PATH_PROTOCOL  *Single
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  *Instance;
+  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *TempNewDevicePath;
+  UINTN                     InstanceSize;
+  UINTN                     SingleDpSize;
+  UINTN                     Size;
+
+  NewDevicePath     = NULL;
+  TempNewDevicePath = NULL;
+
+  if (Multi == NULL || Single == NULL) {
+    return Multi;
+  }
+
+  Instance        =  GetNextDevicePathInstance (&Multi, &InstanceSize);
+  SingleDpSize    =  GetDevicePathSize (Single) - END_DEVICE_PATH_LENGTH;
+  InstanceSize    -= END_DEVICE_PATH_LENGTH;
+
+  while (Instance != NULL) {
+
+    Size = (SingleDpSize < InstanceSize) ? SingleDpSize : InstanceSize;
+
+    if ((CompareMem (Instance, Single, Size) != 0)) {
+      //
+      // Append the device path instance which does not match with Single
+      //
+      TempNewDevicePath = NewDevicePath;
+      NewDevicePath = AppendDevicePathInstance (NewDevicePath, Instance);
+      if (TempNewDevicePath != NULL) {
+        FreePool(TempNewDevicePath);
+      }
+    }
+    FreePool(Instance);
+    Instance = GetNextDevicePathInstance (&Multi, &InstanceSize);
+    InstanceSize  -= END_DEVICE_PATH_LENGTH;
+  }
+
+  return NewDevicePath;
+}
+
+/**
+  Function compares a device path data structure to that of all the nodes of a
+  second device path instance.
+
+  @param  Multi                 A pointer to a multi-instance device path data
+                                structure.
+  @param  Single                A pointer to a single-instance device path data
+                                structure.
+
+  @retval TRUE                  If the Single device path is contained within Multi device path.
+  @retval FALSE                 The Single device path is not match within Multi device path.
+
+**/
+BOOLEAN
+EFIAPI
+BdsLibMatchDevicePaths (
+  IN  EFI_DEVICE_PATH_PROTOCOL  *Multi,
+  IN  EFI_DEVICE_PATH_PROTOCOL  *Single
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInst;
+  UINTN                     Size;
+
+  if (Multi == NULL || Single  == NULL) {
+    return FALSE;
+  }
+
+  DevicePath      = Multi;
+  DevicePathInst  = GetNextDevicePathInstance (&DevicePath, &Size);
+
+  //
+  // Search for the match of 'Single' in 'Multi'
+  //
+  while (DevicePathInst != NULL) {
+    //
+    // If the single device path is found in multiple device paths,
+    // return success
+    //
+    if (CompareMem (Single, DevicePathInst, Size) == 0) {
+      FreePool (DevicePathInst);
+      return TRUE;
+    }
+
+    FreePool (DevicePathInst);
+    DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);
+  }
+
+  return FALSE;
+}
+
+/**
+  This function prints a series of strings.
+
+  @param  ConOut                Pointer to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
+  @param  ...                   A variable argument list containing series of
+                                strings, the last string must be NULL.
+
+  @retval EFI_SUCCESS           Success print out the string using ConOut.
+  @retval EFI_STATUS            Return the status of the ConOut->OutputString ().
+
+**/
+EFI_STATUS
+EFIAPI
+BdsLibOutputStrings (
+  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL   *ConOut,
+  ...
+  )
+{
+  VA_LIST     Args;
+  EFI_STATUS  Status;
+  CHAR16      *String;
+
+  Status = EFI_SUCCESS;
+  VA_START (Args, ConOut);
+
+  while (!EFI_ERROR (Status)) {
+    //
+    // If String is NULL, then it's the end of the list
+    //
+    String = VA_ARG (Args, CHAR16 *);
+    if (String == NULL) {
+      break;
+    }
+
+    Status = ConOut->OutputString (ConOut, String);
+
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+  }
+  
+  VA_END(Args);
+  return Status;
+}
+
+//
+//  Following are BDS Lib functions which contain all the code about setup browser reset reminder feature.
+//  Setup Browser reset reminder feature is that an reset reminder will be given before user leaves the setup browser  if
+//  user change any option setting which needs a reset to be effective, and  the reset will be applied according to  the user selection.
+//
+
+
+/**
+  Enable the setup browser reset reminder feature.
+  This routine is used in platform tip. If the platform policy need the feature, use the routine to enable it.
+
+**/
+VOID
+EFIAPI
+EnableResetReminderFeature (
+  VOID
+  )
+{
+  mFeaturerSwitch = TRUE;
+}
+
+
+/**
+  Disable the setup browser reset reminder feature.
+  This routine is used in platform tip. If the platform policy do not want the feature, use the routine to disable it.
+
+**/
+VOID
+EFIAPI
+DisableResetReminderFeature (
+  VOID
+  )
+{
+  mFeaturerSwitch = FALSE;
+}
+
+
+/**
+  Record the info that  a reset is required.
+  A  module boolean variable is used to record whether a reset is required.
+
+**/
+VOID
+EFIAPI
+EnableResetRequired (
+  VOID
+  )
+{
+  mResetRequired = TRUE;
+}
+
+
+/**
+  Record the info that  no reset is required.
+  A  module boolean variable is used to record whether a reset is required.
+
+**/
+VOID
+EFIAPI
+DisableResetRequired (
+  VOID
+  )
+{
+  mResetRequired = FALSE;
+}
+
+
+/**
+  Check whether platform policy enable the reset reminder feature. The default is enabled.
+
+**/
+BOOLEAN
+EFIAPI
+IsResetReminderFeatureEnable (
+  VOID
+  )
+{
+  return mFeaturerSwitch;
+}
+
+
+/**
+  Check if  user changed any option setting which needs a system reset to be effective.
+
+**/
+BOOLEAN
+EFIAPI
+IsResetRequired (
+  VOID
+  )
+{
+  return mResetRequired;
+}
+
+
+/**
+  Check whether a reset is needed, and finish the reset reminder feature.
+  If a reset is needed, Popup a menu to notice user, and finish the feature
+  according to the user selection.
+
+**/
+VOID
+EFIAPI
+SetupResetReminder (
+  VOID
+  )
+{
+  EFI_INPUT_KEY                 Key;
+  CHAR16                        *StringBuffer1;
+  CHAR16                        *StringBuffer2;
+
+
+  //
+  //check any reset required change is applied? if yes, reset system
+  //
+  if (IsResetReminderFeatureEnable ()) {
+    if (IsResetRequired ()) {
+
+      StringBuffer1 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));
+      ASSERT (StringBuffer1 != NULL);
+      StringBuffer2 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));
+      ASSERT (StringBuffer2 != NULL);
+      StrCpy (StringBuffer1, L"Configuration changed. Reset to apply it Now.");
+      StrCpy (StringBuffer2, L"Press ENTER to reset");
+      //
+      // Popup a menu to notice user
+      //
+      do {
+        CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL);
+      } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
+
+      FreePool (StringBuffer1);
+      FreePool (StringBuffer2);
+
+      gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
+    }
+  }
+}
+
+/**
+  Get the headers (dos, image, optional header) from an image
+
+  @param  Device                SimpleFileSystem device handle
+  @param  FileName              File name for the image
+  @param  DosHeader             Pointer to dos header
+  @param  Hdr                   The buffer in which to return the PE32, PE32+, or TE header.
+
+  @retval EFI_SUCCESS           Successfully get the machine type.
+  @retval EFI_NOT_FOUND         The file is not found.
+  @retval EFI_LOAD_ERROR        File is not a valid image file.
+
+**/
+EFI_STATUS
+EFIAPI
+BdsLibGetImageHeader (
+  IN  EFI_HANDLE                  Device,
+  IN  CHAR16                      *FileName,
+  OUT EFI_IMAGE_DOS_HEADER        *DosHeader,
+  OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr
+  )
+{
+  EFI_STATUS                       Status;
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *Volume;
+  EFI_FILE_HANDLE                  Root;
+  EFI_FILE_HANDLE                  ThisFile;
+  UINTN                            BufferSize;
+  UINT64                           FileSize;
+  EFI_FILE_INFO                    *Info;
+
+  Root     = NULL;
+  ThisFile = NULL;
+  //
+  // Handle the file system interface to the device
+  //
+  Status = gBS->HandleProtocol (
+                  Device,
+                  &gEfiSimpleFileSystemProtocolGuid,
+                  (VOID *) &Volume
+                  );
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  Status = Volume->OpenVolume (
+                     Volume,
+                     &Root
+                     );
+  if (EFI_ERROR (Status)) {
+    Root = NULL;
+    goto Done;
+  }
+  ASSERT (Root != NULL);
+  Status = Root->Open (Root, &ThisFile, FileName, EFI_FILE_MODE_READ, 0);
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+  ASSERT (ThisFile != NULL);
+
+  //
+  // Get file size
+  //
+  BufferSize  = SIZE_OF_EFI_FILE_INFO + 200;
+  do {
+    Info   = NULL;
+    Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, (VOID **) &Info);
+    if (EFI_ERROR (Status)) {
+      goto Done;
+    }
+    Status = ThisFile->GetInfo (
+                         ThisFile,
+                         &gEfiFileInfoGuid,
+                         &BufferSize,
+                         Info
+                         );
+    if (!EFI_ERROR (Status)) {
+      break;
+    }
+    if (Status != EFI_BUFFER_TOO_SMALL) {
+      FreePool (Info);
+      goto Done;
+    }
+    FreePool (Info);
+  } while (TRUE);
+
+  FileSize = Info->FileSize;
+  FreePool (Info);
+
+  //
+  // Read dos header
+  //
+  BufferSize = sizeof (EFI_IMAGE_DOS_HEADER);
+  Status = ThisFile->Read (ThisFile, &BufferSize, DosHeader);
+  if (EFI_ERROR (Status) ||
+      BufferSize < sizeof (EFI_IMAGE_DOS_HEADER) ||
+      FileSize <= DosHeader->e_lfanew ||
+      DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) {
+    Status = EFI_LOAD_ERROR;
+    goto Done;
+  }
+
+  //
+  // Move to PE signature
+  //
+  Status = ThisFile->SetPosition (ThisFile, DosHeader->e_lfanew);
+  if (EFI_ERROR (Status)) {
+    Status = EFI_LOAD_ERROR;
+    goto Done;
+  }
+
+  //
+  // Read and check PE signature
+  //
+  BufferSize = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION);
+  Status = ThisFile->Read (ThisFile, &BufferSize, Hdr.Pe32);
+  if (EFI_ERROR (Status) ||
+      BufferSize < sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION) ||
+      Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
+    Status = EFI_LOAD_ERROR;
+    goto Done;
+  }
+
+  //
+  // Check PE32 or PE32+ magic
+  //
+  if (Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC &&
+      Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+    Status = EFI_LOAD_ERROR;
+    goto Done;
+  }
+
+ Done:
+  if (ThisFile != NULL) {
+    ThisFile->Close (ThisFile);
+  }
+  if (Root != NULL) {
+    Root->Close (Root);
+  }
+  return Status;
+}
+
+/**
+  This routine adjust the memory information for different memory type and 
+  save them into the variables for next boot.
+**/
+VOID
+BdsSetMemoryTypeInformationVariable (
+  VOID
+  )
+{
+  EFI_STATUS                   Status;
+  EFI_MEMORY_TYPE_INFORMATION  *PreviousMemoryTypeInformation;
+  EFI_MEMORY_TYPE_INFORMATION  *CurrentMemoryTypeInformation;
+  UINTN                        VariableSize;
+  UINTN                        Index;
+  UINTN                        Index1;
+  UINT32                       Previous;
+  UINT32                       Current;
+  UINT32                       Next;
+  EFI_HOB_GUID_TYPE            *GuidHob;
+  BOOLEAN                      MemoryTypeInformationModified;
+  BOOLEAN                      MemoryTypeInformationVariableExists;
+  EFI_BOOT_MODE                BootMode;
+
+  MemoryTypeInformationModified       = FALSE;
+  MemoryTypeInformationVariableExists = FALSE;
+
+
+  BootMode = GetBootModeHob ();
+  //
+  // In BOOT_IN_RECOVERY_MODE, Variable region is not reliable.
+  //
+  if (BootMode == BOOT_IN_RECOVERY_MODE) {
+    return;
+  }
+
+  //
+  // Only check the the Memory Type Information variable in the boot mode 
+  // other than BOOT_WITH_DEFAULT_SETTINGS because the Memory Type
+  // Information is not valid in this boot mode.
+  //
+  if (BootMode != BOOT_WITH_DEFAULT_SETTINGS) {
+    VariableSize = 0;
+    Status = gRT->GetVariable (
+                    EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
+                    &gEfiMemoryTypeInformationGuid,
+                    NULL, 
+                    &VariableSize, 
+                    NULL
+                    );
+    if (Status == EFI_BUFFER_TOO_SMALL) {
+      MemoryTypeInformationVariableExists = TRUE;
+    }
+  }
+
+  //
+  // Retrieve the current memory usage statistics.  If they are not found, then
+  // no adjustments can be made to the Memory Type Information variable.
+  //
+  Status = EfiGetSystemConfigurationTable (
+             &gEfiMemoryTypeInformationGuid,
+             (VOID **) &CurrentMemoryTypeInformation
+             );
+  if (EFI_ERROR (Status) || CurrentMemoryTypeInformation == NULL) {
+    return;
+  }
+
+  //
+  // Get the Memory Type Information settings from Hob if they exist,
+  // PEI is responsible for getting them from variable and build a Hob to save them.
+  // If the previous Memory Type Information is not available, then set defaults
+  //
+  GuidHob = GetFirstGuidHob (&gEfiMemoryTypeInformationGuid);
+  if (GuidHob == NULL) {
+    //
+    // If Platform has not built Memory Type Info into the Hob, just return.
+    //
+    return;
+  }
+  PreviousMemoryTypeInformation = GET_GUID_HOB_DATA (GuidHob);
+  VariableSize = GET_GUID_HOB_DATA_SIZE (GuidHob);
+
+  //
+  // Use a heuristic to adjust the Memory Type Information for the next boot
+  //
+  DEBUG ((EFI_D_INFO, "Memory  Previous  Current    Next   \n"));
+  DEBUG ((EFI_D_INFO, " Type    Pages     Pages     Pages  \n"));
+  DEBUG ((EFI_D_INFO, "======  ========  ========  ========\n"));
+
+  for (Index = 0; PreviousMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) {
+
+    for (Index1 = 0; CurrentMemoryTypeInformation[Index1].Type != EfiMaxMemoryType; Index1++) {
+      if (PreviousMemoryTypeInformation[Index].Type == CurrentMemoryTypeInformation[Index1].Type) {
+        break;
+      }
+    }
+    if (CurrentMemoryTypeInformation[Index1].Type == EfiMaxMemoryType) {
+      continue;
+    }
+
+    //
+    // Previous is the number of pages pre-allocated
+    // Current is the number of pages actually needed
+    //
+    Previous = PreviousMemoryTypeInformation[Index].NumberOfPages;
+    Current  = CurrentMemoryTypeInformation[Index1].NumberOfPages;
+    Next     = Previous;
+
+    //
+    // Inconsistent Memory Reserved across bootings may lead to S4 fail
+    // Write next varible to 125% * current when the pre-allocated memory is:
+    //  1. More than 150% of needed memory and boot mode is BOOT_WITH_DEFAULT_SETTING
+    //  2. Less than the needed memory
+    //
+    if ((Current + (Current >> 1)) < Previous) {
+      if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) {
+        Next = Current + (Current >> 2);
+      }
+    } else if (Current > Previous) {
+      Next = Current + (Current >> 2);
+    }
+    if (Next > 0 && Next < 4) {
+      Next = 4;
+    }
+
+    if (Next != Previous) {
+      PreviousMemoryTypeInformation[Index].NumberOfPages = Next;
+      MemoryTypeInformationModified = TRUE;
+    }
+
+    DEBUG ((EFI_D_INFO, "  %02x    %08x  %08x  %08x\n", PreviousMemoryTypeInformation[Index].Type, Previous, Current, Next));
+  }
+
+  //
+  // If any changes were made to the Memory Type Information settings, then set the new variable value;
+  // Or create the variable in first boot.
+  //
+  if (MemoryTypeInformationModified || !MemoryTypeInformationVariableExists) {
+    Status = SetVariableAndReportStatusCodeOnError (
+               EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
+               &gEfiMemoryTypeInformationGuid,
+               EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+               VariableSize,
+               PreviousMemoryTypeInformation
+               );
+
+    if (!EFI_ERROR (Status)) {
+      //
+      // If the Memory Type Information settings have been modified, then reset the platform
+      // so the new Memory Type Information setting will be used to guarantee that an S4
+      // entry/resume cycle will not fail.
+      //
+      if (MemoryTypeInformationModified && PcdGetBool (PcdResetOnMemoryTypeInformationChange)) {
+        DEBUG ((EFI_D_INFO, "Memory Type Information settings change. Warm Reset!!!\n"));
+        gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
+      }
+    } else {
+      DEBUG ((EFI_D_ERROR, "Memory Type Information settings cannot be saved. OS S4 may fail!\n"));
+    }
+  }
+}
+
+/**
+  This routine is kept for backward compatibility.
+**/
+VOID
+EFIAPI
+BdsLibSaveMemoryTypeInformation (
+  VOID
+  )
+{
+}
+
+
+/**
+  Identify a user and, if authenticated, returns the current user profile handle.
+
+  @param[out]  User           Point to user profile handle.
+  
+  @retval EFI_SUCCESS         User is successfully identified, or user identification
+                              is not supported.
+  @retval EFI_ACCESS_DENIED   User is not successfully identified
+
+**/
+EFI_STATUS
+EFIAPI
+BdsLibUserIdentify (
+  OUT EFI_USER_PROFILE_HANDLE         *User
+  )
+{
+  EFI_STATUS                          Status;
+  EFI_USER_MANAGER_PROTOCOL           *Manager;
+  
+  Status = gBS->LocateProtocol (
+                  &gEfiUserManagerProtocolGuid,
+                  NULL,
+                  (VOID **) &Manager
+                  );
+  if (EFI_ERROR (Status)) {
+    return EFI_SUCCESS;
+  }
+
+  return Manager->Identify (Manager, User);
+}
+
+/**
+  Set the variable and report the error through status code upon failure.
+
+  @param  VariableName           A Null-terminated string that is the name of the vendor's variable.
+                                 Each VariableName is unique for each VendorGuid. VariableName must
+                                 contain 1 or more characters. If VariableName is an empty string,
+                                 then EFI_INVALID_PARAMETER is returned.
+  @param  VendorGuid             A unique identifier for the vendor.
+  @param  Attributes             Attributes bitmask to set for the variable.
+  @param  DataSize               The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE, 
+                                 EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, or 
+                                 EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero 
+                                 causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is 
+                                 set, then a SetVariable() call with a DataSize of zero will not cause any change to 
+                                 the variable value (the timestamp associated with the variable may be updated however 
+                                 even if no new data value is provided,see the description of the 
+                                 EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not 
+                                 be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated). 
+  @param  Data                   The contents for the variable.
+
+  @retval EFI_SUCCESS            The firmware has successfully stored the variable and its data as
+                                 defined by the Attributes.
+  @retval EFI_INVALID_PARAMETER  An invalid combination of attribute bits, name, and GUID was supplied, or the
+                                 DataSize exceeds the maximum allowed.
+  @retval EFI_INVALID_PARAMETER  VariableName is an empty string.
+  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the variable and its data.
+  @retval EFI_DEVICE_ERROR       The variable could not be retrieved due to a hardware error.
+  @retval EFI_WRITE_PROTECTED    The variable in question is read-only.
+  @retval EFI_WRITE_PROTECTED    The variable in question cannot be deleted.
+  @retval EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 
+                                 or EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, but the AuthInfo 
+                                 does NOT pass the validation check carried out by the firmware.
+
+  @retval EFI_NOT_FOUND          The variable trying to be updated or deleted was not found.
+**/
+EFI_STATUS
+SetVariableAndReportStatusCodeOnError (
+  IN CHAR16     *VariableName,
+  IN EFI_GUID   *VendorGuid,
+  IN UINT32     Attributes,
+  IN UINTN      DataSize,
+  IN VOID       *Data
+  )
+{
+  EFI_STATUS                 Status;
+  EDKII_SET_VARIABLE_STATUS  *SetVariableStatus;
+  UINTN                      NameSize;
+
+  Status = gRT->SetVariable (
+                  VariableName,
+                  VendorGuid,
+                  Attributes,
+                  DataSize,
+                  Data
+                  );
+  if (EFI_ERROR (Status)) {
+    NameSize = StrSize (VariableName);
+    SetVariableStatus = AllocatePool (sizeof (EDKII_SET_VARIABLE_STATUS) + NameSize + DataSize);
+    if (SetVariableStatus != NULL) {
+      CopyGuid (&SetVariableStatus->Guid, VendorGuid);
+      SetVariableStatus->NameSize   = NameSize;
+      SetVariableStatus->DataSize   = DataSize;
+      SetVariableStatus->SetStatus  = Status;
+      SetVariableStatus->Attributes = Attributes;
+      CopyMem (SetVariableStatus + 1,                          VariableName, NameSize);
+      if ((Data != NULL) && (DataSize != 0)) {
+        CopyMem (((UINT8 *) (SetVariableStatus + 1)) + NameSize, Data,         DataSize);
+      }
+
+      REPORT_STATUS_CODE_EX (
+        EFI_ERROR_CODE,
+        PcdGet32 (PcdErrorCodeSetVariable),
+        0,
+        NULL,
+        &gEdkiiStatusCodeDataTypeVariableGuid,
+        SetVariableStatus,
+        sizeof (EDKII_SET_VARIABLE_STATUS) + NameSize + DataSize
+        );
+
+      FreePool (SetVariableStatus);
+    }
+  }
+
+  return Status;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/DevicePath.c b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/DevicePath.c
new file mode 100644
index 0000000000..a0b9da880d
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/DevicePath.c
@@ -0,0 +1,27 @@
+/** @file
+  BDS internal function define the default device path string, it can be
+  replaced by platform device path.
+
+Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalBdsLib.h"
+
+/**
+  This function converts an input device structure to a Unicode string.
+
+  @param DevPath                  A pointer to the device path structure.
+
+  @return A new allocated Unicode string that represents the device path.
+
+**/
+CHAR16 *
+EFIAPI
+DevicePathToStr (
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevPath
+  )
+{
+  return ConvertDevicePathToText (DevPath, TRUE, TRUE);
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
new file mode 100644
index 0000000000..e3c8a6fa27
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
@@ -0,0 +1,142 @@
+## @file
+#  General BDS library.
+#  
+#  General BDS defines and produce general interfaces for platform BDS driver including:
+#  1) BDS boot policy interface;
+#  2) BDS boot device connect interface;
+#  3) BDS Misc interfaces for mainting boot variable, ouput string, etc.
+#  
+#  Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#  
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = GenericBdsLib
+  MODULE_UNI_FILE                = GenericBdsLib.uni
+  FILE_GUID                      = e405ec31-ccaa-4dd4-83e8-0aec01703f7e
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = GenericBdsLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION 
+  CONSTRUCTOR                    = GenericBdsLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  DevicePath.c
+  BdsConnect.c
+  BdsMisc.c
+  BdsConsole.c
+  BdsBoot.c
+  InternalBdsLib.h
+  String.h
+  String.c
+  GenericBdsStrings.uni
+  
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+  ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+  DevicePathLib
+  PeCoffGetEntryPointLib
+  BaseLib
+  HobLib
+  UefiRuntimeServicesTableLib
+  DxeServicesTableLib
+  MemoryAllocationLib
+  UefiLib
+  UefiBootServicesTableLib
+  BaseMemoryLib
+  DebugLib
+  PrintLib
+  PcdLib
+  PerformanceLib
+  TimerLib
+  DxeServicesLib
+  HiiLib
+  ReportStatusCodeLib
+  NetLib
+  BmpSupportLib
+
+[Guids]
+  ## SOMETIMES_CONSUMES ## HOB         # The hob holding memory type information
+  ## SOMETIMES_CONSUMES ## SystemTable # The identifier of memory type information type in system table
+  ## SOMETIMES_CONSUMES ## Variable:L"MemoryTypeInformation"
+  ## SOMETIMES_PRODUCES ## Variable:L"MemoryTypeInformation"
+  gEfiMemoryTypeInformationGuid                 
+  ## SOMETIMES_CONSUMES ## Variable:L"BootXXXX"    # Boot option variable
+  ## SOMETIMES_PRODUCES ## Variable:L"BootXXXX"    # Boot option variable
+  ## SOMETIMES_CONSUMES ## Variable:L"DriverXXXX"  # Driver load option.
+  ## SOMETIMES_PRODUCES ## Variable:L"DriverXXXX"  # Driver load option.
+  ## SOMETIMES_CONSUMES ## Variable:L"BootNext"    # Next Boot Option
+  ## SOMETIMES_PRODUCES ## Variable:L"BootNext"    # Next Boot Option
+  ## SOMETIMES_CONSUMES ## Variable:L"BootOrder"   # The boot option array
+  ## SOMETIMES_PRODUCES ## Variable:L"BootOrder"   # The boot option array
+  ## SOMETIMES_CONSUMES ## Variable:L"DriverOrder" # The driver order list
+  ## SOMETIMES_CONSUMES ## Variable:L"ConIn"       # The device path of console in device
+  ## SOMETIMES_PRODUCES ## Variable:L"ConIn"       # The device path of console in device
+  ## SOMETIMES_CONSUMES ## Variable:L"ConOut"      # The device path of console out device
+  ## SOMETIMES_PRODUCES ## Variable:L"ConOut"      # The device path of console out device
+  ## SOMETIMES_CONSUMES ## Variable:L"ErrOut"      # The device path of error out device
+  ## SOMETIMES_PRODUCES ## Variable:L"ErrOut"      # The device path of error out device
+  ## SOMETIMES_PRODUCES ## Variable:L"BootCurrent" # The boot option of current boot
+  ## SOMETIMES_PRODUCES ## Variable:L"BootNext"    # The number of next boot option
+  gEfiGlobalVariableGuid
+  gEfiFileInfoGuid                              ## SOMETIMES_CONSUMES ## GUID
+  gLastEnumLangGuid                             ## SOMETIMES_PRODUCES ## Variable:L"LastEnumLang" # Platform language at last time enumeration.
+  gHdBootDevicePathVariablGuid                  ## SOMETIMES_PRODUCES ## Variable:L"HDDP" # The device path of Boot file on Hard device.
+  gBdsLibStringPackageGuid                      ## CONSUMES ## HII # HII String PackageList Guid
+  ## SOMETIMES_PRODUCES ## Variable:L"LegacyDevOrder"
+  ## SOMETIMES_CONSUMES ## Variable:L"LegacyDevOrder"
+  gEfiLegacyDevOrderVariableGuid
+  gEdkiiStatusCodeDataTypeVariableGuid          ## SOMETIMES_CONSUMES ## GUID
+  gUefiShellFileGuid
+
+[Protocols]
+  gEfiSimpleFileSystemProtocolGuid              ## SOMETIMES_CONSUMES
+  gEfiLoadFileProtocolGuid                      ## SOMETIMES_CONSUMES
+  gEfiSimpleTextOutProtocolGuid                 ## CONSUMES
+  gEfiPciIoProtocolGuid                         ## SOMETIMES_CONSUMES
+  gEfiLoadedImageProtocolGuid                   ## SOMETIMES_CONSUMES
+  gEfiSimpleNetworkProtocolGuid                 ## SOMETIMES_CONSUMES
+  gEfiDebugPortProtocolGuid                     ## SOMETIMES_CONSUMES
+  gEfiSimpleTextInProtocolGuid                  ## CONSUMES
+  gEfiBlockIoProtocolGuid                       ## SOMETIMES_CONSUMES
+  gEfiFirmwareVolume2ProtocolGuid               ## SOMETIMES_CONSUMES
+  gEfiLegacyBiosProtocolGuid                    ## SOMETIMES_CONSUMES
+  gEfiCpuArchProtocolGuid                       ## CONSUMES
+  gEfiDevicePathProtocolGuid                    ## CONSUMES
+  gEfiAcpiS3SaveProtocolGuid                    ## SOMETIMES_CONSUMES
+  gEfiGraphicsOutputProtocolGuid                ## SOMETIMES_CONSUMES
+  gEfiUgaDrawProtocolGuid |gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport ## SOMETIMES_CONSUMES
+  gEfiOEMBadgingProtocolGuid                    ## SOMETIMES_CONSUMES
+  gEfiHiiFontProtocolGuid                       ## CONSUMES
+  gEfiUserManagerProtocolGuid                   ## SOMETIMES_CONSUMES
+  gEfiUsbIoProtocolGuid                         ## SOMETIMES_CONSUMES
+  gEfiBootLogoProtocolGuid                      ## SOMETIMES_CONSUMES
+
+[FeaturePcd]
+  gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport                   ## CONSUMES
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBootlogoOnlyEnable ## CONSUMES
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange ## SOMETIMES_CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeOsLoaderLoad  ## SOMETIMES_CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeOsLoaderStart ## SOMETIMES_CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdErrorCodeSetVariable      ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdTestKeyUsed                       ## CONSUMES
+
+#
+# [BootMode] 
+#   RECOVERY_FULL    ## SOMETIMES_CONSUMES # Memory Type Information variable
+#
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.uni b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.uni
new file mode 100644
index 0000000000..c853d3409e
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.uni
@@ -0,0 +1,19 @@
+// /** @file
+// General BDS library.
+//
+// General BDS defines and produce general interfaces for platform BDS driver including:
+// 1) BDS boot policy interface;
+// 2) BDS boot device connect interface;
+// 3) BDS Misc interfaces for mainting boot variable, ouput string, etc.
+//
+// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT             #language en-US "General BDS library"
+
+#string STR_MODULE_DESCRIPTION          #language en-US "General BDS defines and produces general interfaces for a platform BDS driver including: 1) BDS boot policy interface; 2) BDS boot device connect interface; 3) BDS Misc interfaces for maintaining boot variable, output string, etc."
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsStrings.uni b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsStrings.uni
new file mode 100644
index 0000000000..59a75e548b
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsStrings.uni
@@ -0,0 +1,30 @@
+///** @file
+//  
+//  String definitions for Boot Option description.
+//  
+//  Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
+//  SPDX-License-Identifier: BSD-2-Clause-Patent
+//  
+//**/
+
+/=#
+
+#langdef   en-US "English"
+#langdef   fr-FR "Français"
+
+#string STR_DESCRIPTION_FLOPPY         #language en-US  "EFI Floppy"
+                                       #language fr-FR  "fr-FR: EFI Floppy"
+#string STR_DESCRIPTION_CD_DVD         #language en-US  "EFI DVD/CDROM"
+                                       #language fr-FR  "fr-FR: EFI DVD/CDROM"
+#string STR_DESCRIPTION_HARDDRIVE      #language en-US  "EFI Hard Drive"
+                                       #language fr-FR  "fr-FR: EFI Hard Drive"
+#string STR_DESCRIPTION_USB            #language en-US  "EFI USB Device"
+                                       #language fr-FR  "fr-FR: EFI USB Device"
+#string STR_DESCRIPTION_SCSI           #language en-US  "EFI SCSI Device"
+                                       #language fr-FR  "fr-FR: EFI SCSI Device"
+#string STR_DESCRIPTION_MISC           #language en-US  "EFI Misc Device"
+                                       #language fr-FR  "fr-FR: EFI Misc Device"
+#string STR_DESCRIPTION_NETWORK        #language en-US  "EFI Network "
+                                       #language fr-FR  "fr-FR: EFI Network "
+#string STR_DESCRIPTION_NON_BLOCK      #language en-US  "EFI Non-Block Boot Device"
+                                       #language fr-FR  "fr-FR: EFI Non-Block Boot Device"
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/InternalBdsLib.h b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/InternalBdsLib.h
new file mode 100644
index 0000000000..025f06572b
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/InternalBdsLib.h
@@ -0,0 +1,173 @@
+/** @file
+  BDS library definition, include the file and data structure
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _INTERNAL_BDS_LIB_H_
+#define _INTERNAL_BDS_LIB_H_
+
+#include <FrameworkDxe.h>
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/PeImage.h>
+
+#include <Protocol/BlockIo.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/Cpu.h>
+#include <Protocol/SimpleFileSystem.h>
+#include <Protocol/LoadFile.h>
+#include <Protocol/DebugPort.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/SimpleTextIn.h>
+#include <Protocol/LegacyBios.h>
+#include <Protocol/SimpleTextOut.h>
+#include <Protocol/SimpleNetwork.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/AcpiS3Save.h>
+#include <Protocol/OEMBadging.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/UgaDraw.h>
+#include <Protocol/HiiFont.h>
+#include <Protocol/HiiImage.h>
+#include <Protocol/UsbIo.h>
+#include <Protocol/BootLogo.h>
+
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/FileInfo.h>
+#include <Guid/GlobalVariable.h>
+#include <Guid/PcAnsi.h>
+#include <Guid/BdsLibHii.h>
+#include <Guid/HdBootVariable.h>
+#include <Guid/LastEnumLang.h>
+#include <Guid/LegacyDevOrder.h>
+#include <Guid/StatusCodeDataTypeVariable.h>
+
+#include <Library/PrintLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+#include <Library/GenericBdsLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DxeServicesLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/BmpSupportLib.h>
+
+#if !defined (EFI_REMOVABLE_MEDIA_FILE_NAME)
+    #if defined (MDE_CPU_EBC)
+        //
+        // Uefi specification only defines the default boot file name for IA32, X64
+        // and IPF processor, so need define boot file name for EBC architecture here.
+        //
+        #define EFI_REMOVABLE_MEDIA_FILE_NAME L"\\EFI\\BOOT\\BOOTEBC.EFI"
+    #else
+        #error "Can not determine the default boot file name for unknown processor type!"
+    #endif
+#endif
+
+/**
+  Get the headers (dos, image, optional header) from an image
+
+  @param  Device                SimpleFileSystem device handle
+  @param  FileName              File name for the image
+  @param  DosHeader             Pointer to dos header
+  @param  Hdr                   The buffer in which to return the PE32, PE32+, or TE header.
+
+  @retval EFI_SUCCESS           Successfully get the machine type.
+  @retval EFI_NOT_FOUND         The file is not found.
+  @retval EFI_LOAD_ERROR        File is not a valid image file.
+
+**/
+EFI_STATUS
+EFIAPI
+BdsLibGetImageHeader (
+  IN  EFI_HANDLE                  Device,
+  IN  CHAR16                      *FileName,
+  OUT EFI_IMAGE_DOS_HEADER        *DosHeader,
+  OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr
+  );
+
+/**
+  This routine adjust the memory information for different memory type and 
+  save them into the variables for next boot.
+**/
+VOID
+BdsSetMemoryTypeInformationVariable (
+  VOID
+  );
+
+/**
+  Validate the EFI Boot#### or Driver#### variable (VendorGuid/Name)
+
+  @param  Variable              Boot#### variable data.
+  @param  VariableSize          Returns the size of the EFI variable that was read
+
+  @retval TRUE                  The variable data is correct.
+  @retval FALSE                 The variable data is corrupted.
+
+**/
+BOOLEAN 
+ValidateOption (
+  UINT8                     *Variable,
+  UINTN                     VariableSize
+  );
+
+/**
+  Set the variable and report the error through status code upon failure.
+
+  @param  VariableName           A Null-terminated string that is the name of the vendor's variable.
+                                 Each VariableName is unique for each VendorGuid. VariableName must
+                                 contain 1 or more characters. If VariableName is an empty string,
+                                 then EFI_INVALID_PARAMETER is returned.
+  @param  VendorGuid             A unique identifier for the vendor.
+  @param  Attributes             Attributes bitmask to set for the variable.
+  @param  DataSize               The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE, 
+                                 EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, or 
+                                 EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero 
+                                 causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is 
+                                 set, then a SetVariable() call with a DataSize of zero will not cause any change to 
+                                 the variable value (the timestamp associated with the variable may be updated however 
+                                 even if no new data value is provided,see the description of the 
+                                 EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not 
+                                 be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated). 
+  @param  Data                   The contents for the variable.
+
+  @retval EFI_SUCCESS            The firmware has successfully stored the variable and its data as
+                                 defined by the Attributes.
+  @retval EFI_INVALID_PARAMETER  An invalid combination of attribute bits, name, and GUID was supplied, or the
+                                 DataSize exceeds the maximum allowed.
+  @retval EFI_INVALID_PARAMETER  VariableName is an empty string.
+  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the variable and its data.
+  @retval EFI_DEVICE_ERROR       The variable could not be retrieved due to a hardware error.
+  @retval EFI_WRITE_PROTECTED    The variable in question is read-only.
+  @retval EFI_WRITE_PROTECTED    The variable in question cannot be deleted.
+  @retval EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 
+                                 or EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, but the AuthInfo 
+                                 does NOT pass the validation check carried out by the firmware.
+
+  @retval EFI_NOT_FOUND          The variable trying to be updated or deleted was not found.
+**/
+EFI_STATUS
+SetVariableAndReportStatusCodeOnError (
+  IN CHAR16     *VariableName,
+  IN EFI_GUID   *VendorGuid,
+  IN UINT32     Attributes,
+  IN UINTN      DataSize,
+  IN VOID       *Data
+  );
+
+#endif // _BDS_LIB_H_
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.c b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.c
new file mode 100644
index 0000000000..f36860d5a1
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.c
@@ -0,0 +1,26 @@
+/** @file
+  String support
+
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "String.h"
+
+/**
+  Get string by string id from HII Interface
+
+
+  @param Id              String ID.
+
+  @retval  CHAR16 *  String from ID.
+  @retval  NULL      If error occurs.
+
+**/
+CHAR16 *
+BdsLibGetStringById (
+  IN  EFI_STRING_ID   Id
+  )
+{
+  return HiiGetString (gBdsLibStringPackHandle, Id, NULL);
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.h b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.h
new file mode 100644
index 0000000000..53cabe64a9
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.h
@@ -0,0 +1,42 @@
+/** @file
+  String support
+
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _STRING_H_
+#define _STRING_H_
+
+#include <Library/HiiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+extern EFI_HII_HANDLE gBdsLibStringPackHandle;
+
+//
+// This is the VFR compiler generated header file which defines the
+// string identifiers.
+//
+
+extern UINT8  GenericBdsLibStrings[];
+
+/**
+  Get string by string id from HII Interface
+
+
+  @param Id              String ID.
+
+  @retval  CHAR16 *  String from ID.
+  @retval  NULL      If error occurs.
+
+**/
+CHAR16 *
+BdsLibGetStringById (
+  IN  EFI_STRING_ID   Id
+  );
+
+#endif // _STRING_H_
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/BoardPciPlatform.c b/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/BoardPciPlatform.c
new file mode 100644
index 0000000000..0372c175a6
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/BoardPciPlatform.c
@@ -0,0 +1,55 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+    BoardPciPlatform.c
+
+Abstract:
+
+Revision History:
+--*/
+
+
+#include "PciPlatform.h"
+#include "PchRegs.h"
+#include "VlvAccess.h"
+
+#define R_INTEL_LAN_VENDOR_ID           0x00
+#define   V_INTEL_LAN_VENDOR_ID         0x8086     // INTEL 82574 Gbe Controller Vendor ID
+#define R_INTEL_LAN_DEVICE_ID           0x02
+#define   V_INTEL_LAN_DEVICE_ID         0x153E     // INTEL 82574 Gbe Controller Device ID
+
+//
+// Global variables for Option ROMs
+//
+
+#define ONBOARD_VIDEO_OPTION_ROM_FILE_GUID \
+{ 0xF2FE1FAA, 0xF04A, 0x4ba1, 0xAE, 0x73, 0xD1, 0x84, 0x6A, 0x6C, 0xD6, 0xD8 }
+
+#define PXE_UNDI_OPTION_ROM_INTELPXE_GUID \
+{0x49F2C48B, 0x4D8E, 0x4238, 0x8D, 0x82, 0x9B, 0x27, 0xF4, 0x38, 0x44, 0xB0}
+
+#define SATA_AHCI_ROM_GUID \
+  {0x592bfc62, 0xd817, 0x4d1a, 0x86, 0xf8, 0x33, 0x33, 0x4c, 0x9e, 0x90, 0xd8}
+
+#define NULL_ROM_FILE_GUID \
+{ 0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+
+PCI_OPTION_ROM_TABLE mPciOptionRomTable[] = {
+  { ONBOARD_VIDEO_OPTION_ROM_FILE_GUID,     0, 0, 0x02, 0, IGD_VID, IGD_DID_VLV_A0, 0},
+  { ONBOARD_VIDEO_OPTION_ROM_FILE_GUID,     0, 0, 0x02, 0, IGD_VID, IGD_DID, 0},  // Desktop/Mobile IGD
+  { ONBOARD_VIDEO_OPTION_ROM_FILE_GUID,     0, 0, 0x02, 0, IGD_VID, IGD_DID_II, 0},  // Desktop/Mobile IGD
+  { ONBOARD_VIDEO_OPTION_ROM_FILE_GUID,     0, 0, 0x02, 0, IGD_VID, IGD_DID_QS, 0},
+  { NULL_ROM_FILE_GUID,                     0, 0, 0, 0, 0xffff, 0xffff, 0}
+};
+
+UINTN mSizeOptionRomTable =  sizeof(mPciOptionRomTable)/sizeof(PCI_OPTION_ROM_TABLE);
+
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.c b/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.c
new file mode 100644
index 0000000000..b135e2646c
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.c
@@ -0,0 +1,367 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+    PciPlatform.c
+
+Abstract:
+--*/
+
+
+#include "PciPlatform.h"
+#include "PchRegs.h"
+#include "PchAccess.h"
+#include "VlvCommonDefinitions.h"
+#include "PlatformBootMode.h"
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Protocol/CpuIo.h>
+#include <Protocol/PciIo.h>
+#include <Guid/SetupVariable.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include "SetupMode.h"
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Library/HobLib.h>
+#include <IndustryStandard/Pci22.h>
+
+extern  PCI_OPTION_ROM_TABLE  mPciOptionRomTable[];
+extern  UINTN                 mSizeOptionRomTable;
+
+EFI_PCI_PLATFORM_PROTOCOL mPciPlatform = {
+  PhaseNotify,
+  PlatformPrepController,
+  GetPlatformPolicy,
+  GetPciRom
+};
+
+EFI_HANDLE mPciPlatformHandle = NULL;
+
+
+SYSTEM_CONFIGURATION          mSystemConfiguration;
+
+EFI_STATUS
+GetRawImage (
+  IN EFI_GUID   *NameGuid,
+  IN OUT VOID   **Buffer,
+  IN OUT UINTN  *Size
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_HANDLE                    *HandleBuffer;
+  UINTN                         HandleCount;
+  UINTN                         Index;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL  *Fv;
+  UINT32                        AuthenticationStatus;
+
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiFirmwareVolume2ProtocolGuid,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer
+                  );
+  if (EFI_ERROR (Status) || HandleCount == 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Find desired image in all Fvs
+  //
+  for (Index = 0; Index < HandleCount; Index++) {
+    Status = gBS->HandleProtocol(
+                    HandleBuffer[Index],
+                    &gEfiFirmwareVolume2ProtocolGuid,
+                    (VOID **) &Fv
+                    );
+
+    if ( EFI_ERROR ( Status ) ) {
+      return EFI_LOAD_ERROR;
+    }
+
+    //
+    // Try a raw file
+    //
+    *Buffer = NULL;
+    *Size = 0;
+    Status = Fv->ReadSection (
+                   Fv,
+                   NameGuid,
+                   EFI_SECTION_RAW,
+                   0,
+                   Buffer,
+                   Size,
+                   &AuthenticationStatus
+                   );
+
+    if ( !EFI_ERROR ( Status )) {
+        break;
+    }
+  }
+
+  if ( Index >= HandleCount ) {
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI    
+PhaseNotify (
+  IN EFI_PCI_PLATFORM_PROTOCOL              *This,
+  IN  EFI_HANDLE                                     HostBridge,
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE  Phase,
+  IN  EFI_PCI_CHIPSET_EXECUTION_PHASE                ChipsetPhase
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+
+EFI_STATUS
+EFIAPI
+PlatformPrepController (
+  IN EFI_PCI_PLATFORM_PROTOCOL                      *This,
+  IN  EFI_HANDLE                                     HostBridge,
+  IN  EFI_HANDLE                                     RootBridge,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS    PciAddress,
+  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE   Phase,
+  IN  EFI_PCI_CHIPSET_EXECUTION_PHASE                ChipsetPhase
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+GetPlatformPolicy (
+  IN CONST EFI_PCI_PLATFORM_PROTOCOL        *This,
+  OUT EFI_PCI_PLATFORM_POLICY               *PciPolicy
+  )
+{
+  *PciPolicy = EFI_RESERVE_VGA_IO_ALIAS;
+  return EFI_SUCCESS;
+}
+
+/**
+  GetPciRom from platform specific location for specific PCI device
+
+  @param This        Protocol instance
+  @param PciHandle   Identify the specific PCI devic
+  @param RomImage    Returns the ROM Image memory location
+  @param RomSize     Returns Rom Image size
+
+  @retval EFI_SUCCESS
+  @retval EFI_NOT_FOUND
+  @retval  EFI_OUT_OF_RESOURCES
+
+**/
+EFI_STATUS
+EFIAPI    
+GetPciRom (
+  IN CONST EFI_PCI_PLATFORM_PROTOCOL     *This,
+  IN EFI_HANDLE                           PciHandle,
+  OUT  VOID                               **RomImage,
+  OUT  UINTN                              *RomSize
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_PCI_IO_PROTOCOL           *PciIo;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+  UINTN                         Segment;
+  UINTN                         Bus;
+  UINTN                         Device;
+  UINTN                         Function;
+  UINT16                        VendorId;
+  UINT16                        DeviceId;
+  UINT16                        DeviceClass;
+  UINTN                         TableIndex;
+  UINT8                         Data8;
+  BOOLEAN                       MfgMode;
+  EFI_PLATFORM_SETUP_ID         *BootModeBuffer;
+
+  EFI_PEI_HOB_POINTERS        GuidHob;
+
+  MfgMode = FALSE;
+
+//
+// Check if system is in manufacturing mode.
+//
+  GuidHob.Raw = GetHobList ();
+  if (GuidHob.Raw == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformBootModeGuid, GuidHob.Raw)) != NULL) {
+    BootModeBuffer = GET_GUID_HOB_DATA (GuidHob.Guid);
+    if (!CompareMem (&BootModeBuffer->SetupName, MANUFACTURE_SETUP_NAME,
+        StrSize (MANUFACTURE_SETUP_NAME)))
+      {
+      	//
+        // System is in manufacturing mode.
+        //
+        MfgMode = TRUE;
+      }
+   }
+
+  Status = gBS->HandleProtocol (
+                  PciHandle,
+                  &gEfiPciIoProtocolGuid,
+                  (void **)&PciIo
+                  );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  Status = gBS->LocateProtocol (
+                  &gEfiPciRootBridgeIoProtocolGuid,
+                  NULL,
+                  (void **)&PciRootBridgeIo
+                  );
+
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, 0x0A, 1, &DeviceClass);
+
+  PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);
+
+  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, 0, 1, &VendorId);
+
+  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, 2, 1, &DeviceId);
+
+  //
+  // WA for PCIe SATA card (SYBA SY-PEX400-40)
+  //
+  if ((VendorId == 0x1B21) && (DeviceId == 0x0612)) {
+    Data8 = 0x07;
+    PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 4, 1, &Data8);
+  }
+
+    //
+    // Do not run RAID or AHCI Option ROM if IDE
+    //
+    if ( (DeviceClass == ((PCI_CLASS_MASS_STORAGE << 8 ) | PCI_CLASS_MASS_STORAGE_IDE)) ) {
+      return EFI_NOT_FOUND;
+    }
+
+    //
+    // Run PXE ROM only if Boot network is enabled and not in MFG mode
+    //
+    if (DeviceClass == ((PCI_CLASS_NETWORK << 8 ) | PCI_CLASS_NETWORK_ETHERNET)) {
+      if (((mSystemConfiguration.BootNetwork == 0) && (MfgMode == FALSE )) || (mSystemConfiguration.FastBoot == 1)) {
+      return EFI_NOT_FOUND;
+      }
+    }
+
+    //
+    // Loop through table of Onboard option rom descriptions
+    //
+    for (TableIndex = 0; mPciOptionRomTable[TableIndex].VendorId != 0xffff; TableIndex++) {
+
+      //
+      // See if the PCI device specified by PciHandle matches at device in mPciOptionRomTable
+      //
+      if (VendorId != mPciOptionRomTable[TableIndex].VendorId ||
+          DeviceId != mPciOptionRomTable[TableIndex].DeviceId ||
+          ((DeviceClass == ((PCI_CLASS_NETWORK << 8 ) | PCI_CLASS_NETWORK_ETHERNET)) &&
+           (mPciOptionRomTable[TableIndex].Flag != mSystemConfiguration.BootNetwork))  ) {
+        continue;
+      }
+
+      Status = GetRawImage(
+                 &mPciOptionRomTable[TableIndex].FileName,
+                 RomImage,
+                 RomSize
+                 );
+
+      if ((VendorId == IGD_VID) && (DeviceId == IGD_DID_VLV_A0)) {
+        *(UINT16 *)(((UINTN) *RomImage) + OPROM_DID_OFFSET) = IGD_DID_VLV_A0;
+      }
+
+      if ((VendorId == IGD_VID) && (DeviceId == IGD_DID_II)) {
+        *(UINT16 *)(((UINTN) *RomImage) + OPROM_DID_OFFSET) = IGD_DID_II;
+      }
+
+      if ((VendorId == IGD_VID) && (DeviceId == IGD_DID_0BE4)) {
+        *(UINT16 *)(((UINTN) *RomImage) + OPROM_DID_OFFSET) = IGD_DID_0BE4;
+      }
+
+      if ((VendorId == IGD_VID) && (DeviceId == IGD_DID_QS)) {
+        *(UINT16 *)(((UINTN) *RomImage) + OPROM_DID_OFFSET) = IGD_DID_QS;
+      }
+
+
+        if (EFI_ERROR (Status)) {
+          continue;
+        }
+        return EFI_SUCCESS;
+      }
+
+  return EFI_NOT_FOUND;
+}
+
+/**
+
+  @param  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
+
+  @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+PciPlatformDriverEntry (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+  UINTN       VarSize;
+
+  VarSize = sizeof(SYSTEM_CONFIGURATION);
+  Status = gRT->GetVariable(
+                  L"Setup",
+                  &gEfiNormalSetupGuid,
+                  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",
+              &gEfiNormalSetupGuid,
+              NULL,
+              &VarSize,
+              &mSystemConfiguration
+              );
+    ASSERT_EFI_ERROR (Status);
+  }  
+
+  //
+  // Install on a new handle
+  //
+  Status = gBS->InstallProtocolInterface (
+                  &mPciPlatformHandle,
+                  &gEfiPciPlatformProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &mPciPlatform
+                  );
+
+  return Status;
+}
+
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.h b/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.h
new file mode 100644
index 0000000000..cd846eae75
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.h
@@ -0,0 +1,83 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+    PciPlatform.h
+
+Abstract:
+
+--*/
+#ifndef PCI_PLATFORM_H_
+#define PCI_PLATFORM_H_
+
+
+#include <PiDxe.h>
+#include "Platform.h"
+
+//
+// Produced Protocols
+//
+#include <Protocol/PciPlatform.h>
+
+#define IGD_DID_II                     0x0BE1
+#define IGD_DID_0BE4                   0x0BE4
+#define IGD_DID_VLV_A0                 0x0F31
+#define OPROM_DID_OFFSET               0x46
+
+typedef struct {
+  EFI_GUID  FileName;
+  UINTN     Segment;
+  UINTN     Bus;
+  UINTN     Device;
+  UINTN     Function;
+  UINT16    VendorId;
+  UINT16    DeviceId;
+  UINT8     Flag;
+} PCI_OPTION_ROM_TABLE;
+
+EFI_STATUS
+EFIAPI
+PhaseNotify (
+  IN  EFI_PCI_PLATFORM_PROTOCOL                     *This,
+  IN  EFI_HANDLE                                    HostBridge,
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase,
+  IN  EFI_PCI_CHIPSET_EXECUTION_PHASE               ChipsetPhase
+  );
+
+
+EFI_STATUS
+EFIAPI
+PlatformPrepController (
+  IN EFI_PCI_PLATFORM_PROTOCOL                      *This,
+  IN   EFI_HANDLE                                   HostBridge,
+  IN  EFI_HANDLE                                    RootBridge,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS   PciAddress,
+  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE  Phase,
+  IN  EFI_PCI_CHIPSET_EXECUTION_PHASE               ChipsetPhase
+  );
+
+EFI_STATUS
+EFIAPI    
+GetPlatformPolicy (
+  IN CONST EFI_PCI_PLATFORM_PROTOCOL                      *This,
+  OUT EFI_PCI_PLATFORM_POLICY                       *PciPolicy
+  );
+
+EFI_STATUS
+EFIAPI
+GetPciRom (
+  IN CONST EFI_PCI_PLATFORM_PROTOCOL                      *This,
+  IN EFI_HANDLE                                     PciHandle,
+  OUT  VOID                                         **RomImage,
+  OUT  UINTN                                        *RomSize
+  );
+
+#endif
+
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.inf b/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.inf
new file mode 100644
index 0000000000..a0837917d8
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.inf
@@ -0,0 +1,65 @@
+#/*++
+#
+# Copyright (c)  2003  - 2018, Intel Corporation. All rights reserved
+#                                                                                  

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

+
+#
+#  Module Name:
+#
+#    PciPlatform.inf
+#
+#  Abstract:
+#
+#    Component description file for PciPlatform module.
+#
+--*/
+
+[defines]
+  INF_VERSION          = 0x00010005
+  BASE_NAME            = PciPlatform
+  FILE_GUID            = E2441B64-7EF4-41fe-B3A3-8CAA7F8D3017
+  MODULE_TYPE          = DXE_DRIVER
+  VERSION_STRING       = 1.0
+  ENTRY_POINT          = PciPlatformDriverEntry
+
+[sources.common]
+  BoardPciPlatform.c
+  PciPlatform.c
+  PciPlatform.h
+
+[Guids]
+  gEfiNormalSetupGuid
+  gEfiPlatformBootModeGuid
+
+[Protocols]
+  gEfiPciPlatformProtocolGuid
+  gEfiCpuIoProtocolGuid
+  gEfiFirmwareVolume2ProtocolGuid
+  gEfiPciRootBridgeIoProtocolGuid
+  gEfiPciIoProtocolGuid
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+
+[LibraryClasses]
+  HobLib
+  UefiDriverEntryPoint
+  BaseLib
+  BaseMemoryLib
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  DxeServicesTableLib
+
+[BuildOptions]
+
+[Depex]
+  gEfiVariableArchProtocolGuid AND
+  gEfiVariableWriteArchProtocolGuid
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.dsc b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.dsc
new file mode 100644
index 0000000000..524bb74e2a
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.dsc
@@ -0,0 +1,39 @@
+#/** @file
+# Platform capsule description.
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#**/
+
+[Defines]
+  PLATFORM_NAME                  = Vlv2TbltDevicePkg
+  PLATFORM_GUID                  = EE87F258-6ECC-4415-B1D8-23771BEE26E7
+  PLATFORM_VERSION               = 0.1
+  FLASH_DEFINITION               = Vlv2TbltDevicePkg/PlatformCapsule.fdf
+  OUTPUT_DIRECTORY               = Build/Vlv2TbltDevicePkg
+  SUPPORTED_ARCHITECTURES        = IA32|X64
+  BUILD_TARGETS                  = DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+  POSTBUILD                      = Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleAll.bat
+
+###################################################################################################
+#
+# Components Section - list of the modules and components that will be processed by compilation
+#                      tools and the EDK II tools to generate PE32/PE32+/Coff image files.
+#
+# Note: The EDK II DSC file is not used to specify how compiled binary images get placed
+#       into firmware volume images. This section is just a list of modules to compile from
+#       source into UEFI-compliant binaries.
+#       It is the FDF file that contains information on combining binary files into firmware
+#       volume images, whose concept is beyond UEFI and is described in PI specification.
+#       Binary modules do not need to be listed in this section, as they should be
+#       specified in the FDF file. For example: Shell binary, FAT binary (Fat.efi),
+#       Logo (Logo.bmp), and etc.
+#       There may also be modules listed in this section that are not required in the FDF file,
+#       When a module listed here is excluded from FDF file, then UEFI-compliant binary will be
+#       generated for it, but the binary will not be put into any firmware volume.
+#
+###################################################################################################
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.fdf b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.fdf
new file mode 100644
index 0000000000..43dd987eaf
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.fdf
@@ -0,0 +1,52 @@
+## @file
+# FDF file of Platform capsule.
+#
+# Copyright (c) 2016 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[FV.SystemFirmwareUpdateCargo]
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+FILE RAW = AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215 { # PcdEdkiiSystemFirmwareFileGuid
+    $(WORKSPACE)/$(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/FV/Vlv.ROM
+  }
+
+FILE RAW = 812136D3-4D3A-433A-9418-29BB9BF78F6E { # gEdkiiSystemFmpCapsuleConfigFileGuid
+    Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdateConfig/SystemFirmwareUpdateConfig.ini
+  }
+
+[FmpPayload.FmpPayloadSystemFirmwareRsa2048]
+IMAGE_HEADER_INIT_VERSION = 0x02
+IMAGE_TYPE_ID             = 4096267b-da0a-42eb-b5eb-fef31d207cb4 # PcdSystemFmpCapsuleImageTypeIdGuid
+IMAGE_INDEX               = 0x1
+HARDWARE_INSTANCE         = 0x0
+MONOTONIC_COUNT           = 0x2
+CERTIFICATE_GUID          = A7717414-C616-4977-9420-844712A735BF # RSA2048SHA256
+
+FILE DATA = $(WORKSPACE)/$(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/FV/SYSTEMFIRMWAREUPDATECARGO.Fv
+
+[Capsule.Vlv2Rec]
+CAPSULE_GUID                = 6dcbd5ed-e82d-4c44-bda1-7194199ad92a # gEfiFmpCapsuleGuid
+CAPSULE_FLAGS               = PersistAcrossReset,InitiateReset
+CAPSULE_HEADER_SIZE         = 0x20
+CAPSULE_HEADER_INIT_VERSION = 0x1
+
+FMP_PAYLOAD = FmpPayloadSystemFirmwareRsa2048
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc
new file mode 100644
index 0000000000..1856ac349b
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc
@@ -0,0 +1,38 @@
+#/** @file
+# Platform capsule description.
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  PLATFORM_NAME                  = Vlv2TbltDevicePkg
+  PLATFORM_GUID                  = EE87F258-6ECC-4415-B1D8-23771BEE26E7
+  PLATFORM_VERSION               = 0.1
+  FLASH_DEFINITION               = Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf
+  OUTPUT_DIRECTORY               = Build/Vlv2TbltDevicePkg
+  SUPPORTED_ARCHITECTURES        = IA32|X64
+  BUILD_TARGETS                  = DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+  POSTBUILD                      = Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleAll.sh
+
+###################################################################################################
+#
+# Components Section - list of the modules and components that will be processed by compilation
+#                      tools and the EDK II tools to generate PE32/PE32+/Coff image files.
+#
+# Note: The EDK II DSC file is not used to specify how compiled binary images get placed
+#       into firmware volume images. This section is just a list of modules to compile from
+#       source into UEFI-compliant binaries.
+#       It is the FDF file that contains information on combining binary files into firmware
+#       volume images, whose concept is beyond UEFI and is described in PI specification.
+#       Binary modules do not need to be listed in this section, as they should be
+#       specified in the FDF file. For example: Shell binary, FAT binary (Fat.efi),
+#       Logo (Logo.bmp), and etc.
+#       There may also be modules listed in this section that are not required in the FDF file,
+#       When a module listed here is excluded from FDF file, then UEFI-compliant binary will be
+#       generated for it, but the binary will not be put into any firmware volume.
+#
+###################################################################################################
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf
new file mode 100644
index 0000000000..7917be3d68
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf
@@ -0,0 +1,52 @@
+## @file
+# FDF file of Platform capsule.
+#
+# Copyright (c) 2016 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[FV.SystemFirmwareUpdateCargo]
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+FILE RAW = AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215 { # PcdEdkiiSystemFirmwareFileGuid
+    $(WORKSPACE)/$(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/FV/Vlv.ROM
+  }
+
+FILE RAW = 812136D3-4D3A-433A-9418-29BB9BF78F6E { # gEdkiiSystemFmpCapsuleConfigFileGuid
+    Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdateConfig/SystemFirmwareUpdateConfigGcc.ini
+  }
+
+[FmpPayload.FmpPayloadSystemFirmwareRsa2048]
+IMAGE_HEADER_INIT_VERSION = 0x02
+IMAGE_TYPE_ID             = 4096267b-da0a-42eb-b5eb-fef31d207cb4 # PcdSystemFmpCapsuleImageTypeIdGuid
+IMAGE_INDEX               = 0x1
+HARDWARE_INSTANCE         = 0x0
+MONOTONIC_COUNT           = 0x2
+CERTIFICATE_GUID          = A7717414-C616-4977-9420-844712A735BF # RSA2048SHA256
+
+FILE DATA = $(WORKSPACE)/$(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/FV/SYSTEMFIRMWAREUPDATECARGO.Fv
+
+[Capsule.Vlv2Rec]
+CAPSULE_GUID                = 6dcbd5ed-e82d-4c44-bda1-7194199ad92a # gEfiFmpCapsuleGuid
+CAPSULE_FLAGS               = PersistAcrossReset,InitiateReset
+CAPSULE_HEADER_SIZE         = 0x20
+CAPSULE_HEADER_INIT_VERSION = 0x1
+
+FMP_PAYLOAD = FmpPayloadSystemFirmwareRsa2048
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe.c
new file mode 100644
index 0000000000..d35a158181
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe.c
@@ -0,0 +1,60 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  PlatformCpuInfoDxe.c
+
+Abstract:
+  Platform Cpu Info driver to public platform related HOB data
+
+--*/
+
+#include "PlatformCpuInfoDxe.h"
+
+CHAR16    EfiPlatformCpuInfoVariable[] = L"PlatformCpuInfo";
+
+EFI_STATUS
+EFIAPI
+PlatformCpuInfoInit (
+  IN EFI_HANDLE                         ImageHandle,
+  IN EFI_SYSTEM_TABLE                   *SystemTable
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_PLATFORM_CPU_INFO       *PlatformCpuInfoPtr;
+  EFI_PEI_HOB_POINTERS        GuidHob;
+
+  //
+  // Get Platform Cpu Info HOB
+  //
+  GuidHob.Raw = GetHobList ();
+  while ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformCpuInfoGuid, GuidHob.Raw)) != NULL) {
+    PlatformCpuInfoPtr = GET_GUID_HOB_DATA (GuidHob.Guid);
+    GuidHob.Raw = GET_NEXT_HOB (GuidHob);
+
+      //
+      // Write the Platform CPU Info to volatile memory for runtime purposes.
+      // This must be done in its own driver because SetVariable protocol is dependent on chipset,
+      // which is dependent on CpuIo, PlatformInfo, and Metronome.
+      //
+      Status = gRT->SetVariable(
+                      EfiPlatformCpuInfoVariable,
+                      &gEfiVlv2VariableGuid,
+                      EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+                      sizeof(EFI_PLATFORM_CPU_INFO),
+                      PlatformCpuInfoPtr
+                      );
+      if (EFI_ERROR(Status)) {
+        return Status;
+      }
+  }
+
+   return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe.h b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe.h
new file mode 100644
index 0000000000..b13611f4f8
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe.h
@@ -0,0 +1,29 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+  PlatformCpuInfoDxe.h
+
+Abstract:
+  Platform Cpu Info Driver.
+
+--*/
+
+#ifndef _PLATFORM_CPU_INFO_DRIVER_H_
+#define _PLATFORM_CPU_INFO_DRIVER_H_
+
+#include "PiDxe.h"
+#include "Library/HobLib.h"
+#include "Guid/GlobalVariable.h"
+#include "Guid/AcpiVariableCompatibility.h"
+#include "Guid/PlatformCpuInfo.h"
+#include "Library/UefiRuntimeServicesTableLib.h"
+#include <Guid/Vlv2Variable.h>
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf
new file mode 100644
index 0000000000..f2ade1b105
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf
@@ -0,0 +1,55 @@
+#/*++
+#
+# Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+#                                                                                  
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#                                                                                  
+
+#
+#  Module Name:
+#
+#   PlatformCpuInfoDxe.inf
+#
+#  Abstract:
+#
+#
+--*/
+
+
+[Defines]
+  INF_VERSION          = 0x00010005
+  BASE_NAME            = PlatformCpuInfoDxe
+  FILE_GUID            = 025F738B-4EBD-4d55-B728-5F421B601F20
+  MODULE_TYPE          = DXE_DRIVER
+  VERSION_STRING       = 1.0
+  ENTRY_POINT          = PlatformCpuInfoInit
+
+[Sources]
+  PlatformCpuInfoDxe.c
+  PlatformCpuInfoDxe.h
+
+[Guids]
+  gEfiPlatformCpuInfoGuid
+  gEfiVlv2VariableGuid
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  Vlv2SocBinPkg/Vlv2SocBinPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+
+[LibraryClasses]
+  HobLib
+  UefiRuntimeServicesTableLib
+  UefiDriverEntryPoint
+
+[BuildOptions]
+  MSFT:*_*_*_CC_FLAGS = /Od /GL-
+  INTEL:*_*_*_CC_FLAGS = /Od /GL-
+
+[Depex]
+  gEfiVariableArchProtocolGuid AND
+  gEfiVariableWriteArchProtocolGuid
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/AzaliaVerbTable.h b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/AzaliaVerbTable.h
new file mode 100644
index 0000000000..331d0cbede
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/AzaliaVerbTable.h
@@ -0,0 +1,247 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+--*/
+
+UINT32 mAzaliaVerbTableData12[] = {
+  //
+  // Audio Verb Table - 0x80862805
+  //
+  // Pin Widget 5 - PORT B
+  0x20471C10,
+  0x20471D00,
+  0x20471E56,
+  0x20471F18,
+
+  // Pin Widget 6 - PORT C
+  0x20571C20,
+  0x20571D00,
+  0x20571E56,
+  0x20571F18,
+
+  // Pin Widget 7 - PORT D
+  0x20671C30,
+  0x20671D00,
+  0x20671E56,
+  0x20671F58
+};
+
+
+PCH_AZALIA_VERB_TABLE mAzaliaVerbTable[] = {
+  {
+    //
+    // VerbTable:
+    //  Revision ID = 0xFF, support all steps
+    //  Codec Verb Table For AZALIA
+    //  Codec Address: CAd value (0/1/2)
+    //  Codec Vendor:  0x10EC0880
+    //
+    {
+      0x10EC0880,     // Vendor ID/Device ID
+      0x0000,         // SubSystem ID
+      0xFF,           // Revision ID
+      0x01,           // Front panel support (1=yes, 2=no)
+      0x000A,         // Number of Rear Jacks = 10
+      0x0002          // Number of Front Jacks = 2
+    },
+    0                 // Pointer to verb table data, need to be inited in the code.
+  },
+  {
+    //
+    // Revision ID >= 0x03
+    // Codec Verb Table For AZALIA
+    // Codec Address: CAd value (0/1/2)
+    // Codec Vendor: 0x434D4980
+    //
+    {
+      0x434D4980,     // Vendor ID/Device ID
+      0x0000,         // SubSystem ID
+      0x00,           // Revision ID
+      0x01,           // Front panel support (1=yes, 2=no)
+      0x0009,         // Number of Rear Jacks = 9
+      0x0002          // Number of Front Jacks = 2
+    },
+    0                 // Pointer to verb table data, need to be inited in the code.
+  },
+  {
+    //
+    // Lawndale Azalia Audio Codec Verb Table
+    // Revision ID = 0x00
+    // Codec Address: CAd value (0/1/2)
+    // Codec Vendor: 0x11D41984
+    //
+    {
+      0x11D41984,     // Vendor ID/Device ID
+      0x0000,         // SubSystem ID
+      0x04,           // Revision ID
+      0x01,           // Front panel support (1=yes, 2=no)
+      0x0009,         // Number of Rear Jacks = 9
+      0x0002          // Number of Front Jacks = 2
+    },
+    0                 // Pointer to verb table data, need to be inited in the code.
+  },
+  {
+    //
+    // VerbTable:
+    //  Revision ID = 0xFF, support all steps
+    //  Codec Verb Table For AZALIA
+    //  Codec Address: CAd value (0/1/2)
+    //  Codec Vendor: 0x11D41986
+    //
+    {
+      0x11D41986,     // Vendor ID/Device ID
+      0x0001,         // SubSystem ID
+      0xFF,           // Revision ID
+      0x01,           // Front panel support (1=yes, 2=no)
+      0x000A,         // Number of Rear Jacks = 8
+      0x0002          // Number of Front Jacks = 2
+    },
+    0                 // Pointer to verb table data, need to be inited in the code.
+  },
+  {
+    //
+    // VerbTable: (for Slim River, FFDS3)
+    //  Revision ID = 0x00
+    //  Codec Verb Table For AZALIA
+    //  Codec Address: CAd value (0/1/2)
+    //  Codec Vendor: 0x10EC0272
+    //
+    {
+      0x10EC0272,     // Vendor ID/Device ID
+      0x0000,         // SubSystem ID
+      0x00,           // Revision ID
+      0x01,           // Front panel support (1=yes, 2=no)
+      0x000E,         // Number of Rear Jacks
+      0x0002          // Number of Front Jacks
+    },
+    0                 // Pointer to verb table data, need to be inited in the code.
+  },
+  {
+    //
+    //  VerbTable: (for Buffalo Trail)
+    //  Revision ID = 0x00
+    //  Codec Verb Table For AZALIA
+    //  Codec Address: CAd value (0/1/2)
+    //  Codec Vendor: 0x10EC0269
+    //
+    {
+      0x10EC0269,     // Vendor ID/Device ID
+      0x0000,         // SubSystem ID
+      0x00,           // Revision ID
+      0x01,           // Front panel support (1=yes, 2=no)
+      0x000A,         // Number of Rear Jacks
+      0x0002          // Number of Front Jacks
+    },
+    0                 // Pointer to verb table data, need to be inited in the code.
+  },
+  {
+    //
+    //  VerbTable: (RealTek ALC888)
+    //  Revision ID = 0xFF
+    //  Codec Verb Table For Redfort
+    //  Codec Address: CAd value (0/1/2)
+    //  Codec Vendor: 0x10EC0888
+    //
+    {
+      0x10EC0888,     // Vendor ID/Device ID
+      0x0000,         // SubSystem ID
+      0xFF,           // Revision ID
+      0x01,           // Front panel support (1=yes, 2=no)
+      0x000B,         // Number of Rear Jacks
+      0x0002          // Number of Front Jacks
+    },
+    0                 // Pointer to verb table data, need to be inited in the code.
+  },
+  {
+    //
+    //  VerbTable: (RealTek ALC885)
+    //  Revision ID = 0xFF
+    //  Codec Verb Table For Redfort
+    //  Codec Address: CAd value (0/1/2)
+    //  Codec Vendor: 0x10EC0885
+    //
+    {
+      0x10EC0885,     // Vendor ID/Device ID
+      0x0000,         // SubSystem ID
+      0xFF,           // Revision ID
+      0x01,           // Front panel support (1=yes, 2=no)
+      0x000B,         // Number of Rear Jacks
+      0x0002          // Number of Front Jacks
+    },
+    0                 // Pointer to verb table data, need to be inited in the code.
+  },
+  {
+    //
+    //  VerbTable: (IDT 92HD81)
+    //  Revision ID = 0xFF
+    //  Codec Vendor: 0x111D7605
+    //
+    {
+      0x111D76d5,     // Vendor ID/Device ID
+      0x0000,         // SubSystem ID
+      0xFF,           // Revision ID
+      0x01,           // Front panel support (1=yes, 2=no)
+      0x0008,         // Number of Rear Jacks
+      0x0002          // Number of Front Jacks
+    },
+    0                 // Pointer to verb table data, need to be inited in the code.
+  },
+  {
+    //
+    //  VerbTable: (Intel VLV HDMI)
+    //  Revision ID = 0xFF
+    //  Codec Verb Table For EmeraldLake/LosLunas
+    //  Codec Vendor: 0x80862804
+    //
+    {
+      0x80862882,     // Vendor ID/Device ID
+      0x0000,         // SubSystem ID
+      0xFF,           // Revision ID
+      0x02,           // Front panel support (1=yes, 2=no)
+      0x0003,         // Number of Rear Jacks
+      0x0000          // Number of Front Jacks
+    },
+    0                 // Pointer to verb table data, need to be inited in the code.
+  },
+  {
+    //
+    // VerbTable: (RealTek ALC262)
+    //  Revision ID = 0xFF, support all steps
+    //  Codec Verb Table For AZALIA
+    //  Codec Address: CAd value (0/1/2)
+    //  Codec Vendor:  0x10EC0262
+    //
+    {
+      0x10EC0262,     // Vendor ID/Device ID
+      0x0000,         // SubSystem ID
+      0xFF,           // Revision ID
+      0x01,           // Front panel support (1=yes, 2=no)
+      0x000B,         // Number of Rear Jacks = 11
+      0x0002          // Number of Front Jacks = 2
+    },
+    0                 // Pointer to verb table data, need to be inited in the code.
+  },
+  {
+    //
+    //  VerbTable: (RealTek ALC282)
+    //  Revision ID = 0xff
+    //  Codec Verb Table For Azalia on SharkBay-WhiteBluff refresh and Haswell ULT FFRD Harris Beach, WTM1, WTM2iCRB
+    //  Codec Address: CAd value (0/1/2)
+    //  Codec Vendor: 0x10EC0282
+    //
+    {
+      0x10EC0282, // Vendor ID/Device ID
+      0x0000,     // SubSystem ID
+      0xff,       // Revision ID
+      0x01,       // Front panel support (1=yes, 2=no)
+      0x000C,     // Number of Rear Jacks, 0x0010 for Harris Beach, 0x000B for WTM1 & WTM2iCRB
+      0x0002      // Number of Front Jacks
+    },
+    0             // Pointer to verb table data, need to be inited in the code.
+  }
+};
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardId.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardId.c
new file mode 100644
index 0000000000..7d774568e3
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardId.c
@@ -0,0 +1,223 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+  BoardId.c
+
+Abstract:
+
+  Initialization for the board ID.
+
+  This code should be common across a chipset family of products.
+
+
+
+--*/
+
+#include "PchRegs.h"
+#include "PlatformDxe.h"
+#include <Guid/IdccData.h>
+#include <Guid/EfiVpdData.h>
+#include <Protocol/DataHub.h>
+
+
+extern EFI_GUID mPlatformDriverGuid;
+
+//
+// Global module data
+//
+UINT32 mBoardId;
+UINT8  mBoardIdIndex;
+EFI_BOARD_FEATURES mBoardFeatures;
+UINT16 mSubsystemDeviceId;
+UINT16 mSubsystemAudioDeviceId;
+CHAR8  BoardAaNumber[7];
+BOOLEAN mFoundAANum;
+
+/**
+
+  Write the boardid variable if it does not already exist.
+
+**/
+VOID
+InitializeBoardId (
+  )
+{
+
+  UINT32                        BoardIdBufferSize;
+  EFI_IDCC_BOARD_FORM_FACTOR    IdccBoardFormFactor;
+  EFI_DATA_HUB_PROTOCOL         *DataHub;
+  EFI_STATUS                    Status;
+  DMI_DATA                      DmiDataVariable;
+  UINTN                         Size;
+#if defined(DUPLICATE_AA_NO_BASE_ADDR)
+  CHAR8                         DuplicateAaNoAscii[sizeof(DmiDataVariable.BaseBoardVersion)];
+  UINTN                         iter;
+#endif
+#if defined(GPIO_BOARD_ID_SUPPORT) && GPIO_BOARD_ID_SUPPORT != 0
+  UINT8                         Data8;
+#endif
+
+  //
+  // Update data from the updatable DMI data area
+  //
+  Size = sizeof (DMI_DATA);
+  SetMem(&DmiDataVariable, Size, 0xFF);
+  Status = gRT->GetVariable (
+                  DMI_DATA_NAME,
+                  &gDmiDataGuid,
+                  NULL,
+                  &Size,
+                  &DmiDataVariable
+                  );
+
+#if defined(DUPLICATE_AA_NO_BASE_ADDR)
+  //
+  // Get AA# from flash descriptor region
+  //
+  EfiSetMem(DuplicateAaNoAscii, sizeof(DuplicateAaNoAscii), 0xFF);
+  FlashRead((UINT8 *)(UINTN)DUPLICATE_AA_NO_BASE_ADDR,
+            (UINT8 *)DuplicateAaNoAscii,
+            sizeof(DuplicateAaNoAscii));
+
+  //
+  // Validate AA# read from VPD
+  //
+  for (iter = 0; iter < sizeof(DuplicateAaNoAscii); iter++) {
+     if ((DuplicateAaNoAscii[iter] != 0xFF) &&
+         (DuplicateAaNoAscii[iter] != DmiDataVariable.BaseBoardVersion[iter])) {
+       DmiDataVariable.BaseBoardVersion[iter] = DuplicateAaNoAscii[iter];
+     }
+  }
+
+  Status = EFI_SUCCESS;
+#endif
+
+  mFoundAANum = FALSE;
+
+  //
+  // No variable...no copy
+  //
+  if (EFI_ERROR (Status)) {
+    mBoardIdIndex = 0; // If we can't find the BoardId in the table, use the first entry
+  } else {
+  	//
+    // This is the correct method of checking for AA#.
+    //
+    CopyMem(&BoardAaNumber, ((((UINT8*)&DmiDataVariable.BaseBoardVersion)+2)), 6);
+    BoardAaNumber[6] = 0;
+    for (mBoardIdIndex = 0; mBoardIdIndex < mBoardIdDecodeTableSize; mBoardIdIndex++) {
+      if (AsciiStrnCmp(mBoardIdDecodeTable[mBoardIdIndex].AaNumber, BoardAaNumber, 6) == 0) {
+        mFoundAANum = TRUE;
+        break;
+      }
+    }
+
+    if(!mFoundAANum) {
+    	//
+      // Add check for AA#'s that is programmed without the AA as leading chars.
+      //
+      CopyMem(&BoardAaNumber, (((UINT8*)&DmiDataVariable.BaseBoardVersion)), 6);
+      BoardAaNumber[6] = 0;
+      for (mBoardIdIndex = 0; mBoardIdIndex < mBoardIdDecodeTableSize; mBoardIdIndex++) {
+        if (AsciiStrnCmp(mBoardIdDecodeTable[mBoardIdIndex].AaNumber, BoardAaNumber, 6) == 0) {
+          mFoundAANum = TRUE;
+          break;
+        }
+      }
+    }
+  }
+
+#if defined(GPIO_BOARD_ID_SUPPORT) && GPIO_BOARD_ID_SUPPORT != 0
+  //
+  // If we can't find the BoardAA# in the table, find BoardId
+  //
+  if (mFoundAANum != TRUE) {
+    //
+    // BoardID BIT    Location
+    //  0             GPIO33  (ICH)
+    //  1             GPIO34  (ICH)
+    //
+    Data8 = IoRead8(GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL2);
+
+    //
+    // BoardId[0]
+    //
+    mBoardId = (UINT32)((Data8 >> 1) & BIT0);
+    //
+    // BoardId[1]
+    //
+    mBoardId |= (UINT32)((Data8 >> 1) & BIT1);
+
+    for (mBoardIdIndex = 0; mBoardIdIndex < mBoardIdDecodeTableSize; mBoardIdIndex++) {
+      if (mBoardIdDecodeTable[mBoardIdIndex].BoardId == mBoardId) {
+        break;
+      }
+    }
+#endif
+    if (mBoardIdIndex == mBoardIdDecodeTableSize) {
+      mBoardIdIndex = 0; // If we can't find the BoardId in the table, use the first entry
+    }
+#if defined(GPIO_BOARD_ID_SUPPORT) && GPIO_BOARD_ID_SUPPORT != 0
+  }
+#endif
+
+  mBoardFeatures = mBoardIdDecodeTable[mBoardIdIndex].Features;
+  mSubsystemDeviceId = mBoardIdDecodeTable[mBoardIdIndex].SubsystemDeviceId;
+  mSubsystemAudioDeviceId = mBoardIdDecodeTable[mBoardIdIndex].AudioSubsystemDeviceId;
+
+  //
+  // Set the BoardFeatures variable
+  //
+  BoardIdBufferSize = sizeof (mBoardFeatures);
+  gRT->SetVariable (
+         BOARD_FEATURES_NAME,
+         &gEfiBoardFeaturesGuid,
+         EFI_VARIABLE_NON_VOLATILE |
+         EFI_VARIABLE_BOOTSERVICE_ACCESS |
+         EFI_VARIABLE_RUNTIME_ACCESS,
+         BoardIdBufferSize,
+         &mBoardFeatures
+         );
+
+  //
+  // Get the Data Hub protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiDataHubProtocolGuid,
+                  NULL,
+                  (VOID **) &DataHub
+                  );
+  if (!(EFI_ERROR(Status))) {
+    //
+    // Fill out data
+    //
+    IdccBoardFormFactor.IdccHeader.Type = EFI_IDCC_BOARD_FORM_FACTOR_TYPE;
+    IdccBoardFormFactor.IdccHeader.RecordLength = sizeof(EFI_IDCC_BOARD_FORM_FACTOR);
+    if ((mBoardFeatures & B_BOARD_FEATURES_FORM_FACTOR_ATX) || (mBoardFeatures & B_BOARD_FEATURES_FORM_FACTOR_MICRO_ATX)) {
+        IdccBoardFormFactor.BoardFormFactor = ATX_FORM_FACTOR; // ATX
+    } else {
+        IdccBoardFormFactor.BoardFormFactor = BTX_FORM_FACTOR; // BTX
+    }
+
+    //
+    // Publish the Board Form Factor value for IDCC
+    //
+    Status = DataHub->LogData (
+                        DataHub,
+                        &gIdccDataHubGuid,
+                        &mPlatformDriverGuid,
+                        EFI_DATA_RECORD_CLASS_DATA,
+                        &IdccBoardFormFactor,
+                        sizeof(EFI_IDCC_BOARD_FORM_FACTOR)
+                        );
+  }
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.c
new file mode 100644
index 0000000000..d4bf5df690
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.c
@@ -0,0 +1,129 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+  BoardIdDecode.c
+
+Abstract:
+
+--*/
+
+#include "PchRegs.h"
+#include "PlatformDxe.h"
+#include "Platform.h"
+
+
+//
+// Define macros to build data structure signatures from characters.
+//
+#define EFI_SIGNATURE_16(A, B)        ((A) | (B << 8))
+#define EFI_SIGNATURE_32(A, B, C, D)  (EFI_SIGNATURE_16 (A, B) | (EFI_SIGNATURE_16 (C, D) << 16))
+#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))
+
+BOARD_ID_DECODE mBoardIdDecodeTable[] = {
+  //
+  // Board ID, Board Features bitmap, Subsystem Device ID
+  // This is a dummy entry that has to exist. Do not delete, just make a generic entry that fit for product.
+  //
+  {
+  	MW_ITX_MPCIE_LVDS_LOEM_AA,
+    MW_ITX_MPCIE_LVDS_LOEM_ID,
+    B_BOARD_FEATURES_FORM_FACTOR_ATX |
+    B_BOARD_FEATURES_SIO_COM2 |
+    B_BOARD_FEATURES_2_C0_MEMORY_SLOT |
+    V_BOARD_FEATURES_SLEEP_S3 |
+    B_BOARD_FEATURES_PS2WAKEFROMS5 |
+    B_BOARD_FEATURES_LVDS |
+    B_BOARD_FEATURES_VERB_TABLE1,
+    V_DEFAULT_SUBSYSTEM_DEVICE_ID,
+    0xD625,
+    EFI_SIGNATURE_64('M','W','P','N','T','1','0','N')
+  },
+
+  {
+  	 MW_ITX_MPCIE_LVDS_CHANNEL_AA,
+    MW_ITX_MPCIE_LVDS_CHANNEL_ID,
+    B_BOARD_FEATURES_FORM_FACTOR_ATX |
+    B_BOARD_FEATURES_SIO_COM2 |
+    B_BOARD_FEATURES_2_C0_MEMORY_SLOT |
+    V_BOARD_FEATURES_SLEEP_S3 |
+    B_BOARD_FEATURES_PS2WAKEFROMS5 |
+    B_BOARD_FEATURES_LVDS |
+    B_BOARD_FEATURES_VERB_TABLE1,
+    V_DEFAULT_SUBSYSTEM_DEVICE_ID,
+    0xD625,
+    EFI_SIGNATURE_64('M','W','P','N','T','1','0','N')
+  },
+
+  {
+  	MW_ITX_MPCIE_CHANNEL_AA,
+    MW_ITX_MPCIE_CHANNEL_ID,
+    B_BOARD_FEATURES_FORM_FACTOR_ATX |
+    B_BOARD_FEATURES_SIO_COM2 |
+    B_BOARD_FEATURES_2_C0_MEMORY_SLOT |
+    V_BOARD_FEATURES_SLEEP_S3 |
+    B_BOARD_FEATURES_PS2WAKEFROMS5 |
+    B_BOARD_FEATURES_VERB_TABLE1,
+    V_DEFAULT_SUBSYSTEM_DEVICE_ID,
+    0xD625,
+    EFI_SIGNATURE_64('M','W','P','N','T','1','0','N')
+  },
+
+  {
+  	KT_ITX_MPCIE_LVDS_LOEM_AA,
+    KT_ITX_MPCIE_LVDS_LOEM_ID,
+    B_BOARD_FEATURES_FORM_FACTOR_ATX |
+    B_BOARD_FEATURES_SIO_COM2 |
+    B_BOARD_FEATURES_2_C0_MEMORY_SLOT |
+    V_BOARD_FEATURES_SLEEP_S3 |
+    B_BOARD_FEATURES_PS2WAKEFROMS5 |
+    B_BOARD_FEATURES_LVDS |
+    B_BOARD_FEATURES_VERB_TABLE2,
+    V_DEFAULT_SUBSYSTEM_DEVICE_ID_KT,
+    0xD626,
+    EFI_SIGNATURE_64('K','T','P','N','T','1','0','N')
+  },
+
+  {
+  	KT_ITX_CHANNEL_AA,
+    KT_ITX_CHANNEL_ID,
+    B_BOARD_FEATURES_FORM_FACTOR_ATX |
+    B_BOARD_FEATURES_SIO_COM2 |
+    B_BOARD_FEATURES_2_C0_MEMORY_SLOT |
+    V_BOARD_FEATURES_SLEEP_S3 |
+    B_BOARD_FEATURES_PS2WAKEFROMS5 |
+    B_BOARD_FEATURES_NO_MINIPCIE |
+    B_BOARD_FEATURES_VERB_TABLE2,
+    V_DEFAULT_SUBSYSTEM_DEVICE_ID_KT,
+    0xD626,
+    EFI_SIGNATURE_64('K','T','P','N','T','1','0','N')
+  },
+
+  {
+  	KT_ITX_LOEM_AA,
+    KT_ITX_LOEM_ID,
+    B_BOARD_FEATURES_FORM_FACTOR_ATX |
+    B_BOARD_FEATURES_SIO_COM2 |
+    B_BOARD_FEATURES_2_C0_MEMORY_SLOT |
+    V_BOARD_FEATURES_SLEEP_S3 |
+    B_BOARD_FEATURES_PS2WAKEFROMS5 |
+    B_BOARD_FEATURES_NO_MINIPCIE |
+    B_BOARD_FEATURES_VERB_TABLE2,
+    V_DEFAULT_SUBSYSTEM_DEVICE_ID_KT,
+    0xD626,
+    EFI_SIGNATURE_64('K','T','P','N','T','1','0','N')
+  }
+};
+
+UINTN mBoardIdDecodeTableSize = sizeof (mBoardIdDecodeTable) /
+                                sizeof (mBoardIdDecodeTable[0]);
+
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.h b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.h
new file mode 100644
index 0000000000..8068768a3a
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.h
@@ -0,0 +1,61 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  BoardIdDecode.h
+
+Abstract:
+
+  Header file for Platform Initialization Driver.
+
+Revision History
+
+++*/
+
+//
+// Board AA# and Board ID
+//
+#define DEFAULT_BOARD_AA                  "FFFFFF"
+
+//
+// Mount Washington (LVDS) LOEM
+//
+#define MW_ITX_MPCIE_LVDS_LOEM_AA         "E93081"
+#define MW_ITX_MPCIE_LVDS_LOEM_ID         3
+
+//
+// Mount Washington (LVDS) Channel
+//
+#define MW_ITX_MPCIE_LVDS_CHANNEL_AA      "E93080"
+#define MW_ITX_MPCIE_LVDS_CHANNEL_ID      3
+
+//
+// Mount Washington Channel
+//
+#define MW_ITX_MPCIE_CHANNEL_AA           "E93082"
+#define MW_ITX_MPCIE_CHANNEL_ID           1
+
+//
+// Kinston (mPCIe + LVDS) LOEM
+//
+#define KT_ITX_MPCIE_LVDS_LOEM_AA         "E93085"
+#define KT_ITX_MPCIE_LVDS_LOEM_ID         2
+
+//
+// Kinston (LVDS) Channel
+//
+#define KT_ITX_CHANNEL_AA                 "E93083"
+#define KT_ITX_CHANNEL_ID                 0
+
+//
+// Kinston LOEM
+//
+#define KT_ITX_LOEM_AA                    "E93084"
+#define KT_ITX_LOEM_ID                    0
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ClockControl.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ClockControl.c
new file mode 100644
index 0000000000..1669f0357f
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ClockControl.c
@@ -0,0 +1,202 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+  ClockControl.c
+
+Abstract:
+
+  Sets platform/SKU specific clock routing information.
+
+
+
+--*/
+
+#include "PlatformDxe.h"
+#include <Protocol/CK505ClockPlatformInfo.h>
+
+//
+// Default clock routing informtion (All On)
+//
+EFI_CLOCK_PLATFORM_INFO mDefClockPolicy = {NULL, 0, NULL, 0, NULL, 0};
+
+//
+// Clock Settings
+//
+// Static clock table.
+//  This should be used to define any clock settings that are static
+//  (Always On or Always Off).  Dynamic clocks should be set to enabled
+//  in this table.
+//
+EFI_STATIC_SIGNALS mAtxStaticClocks[] = {
+  {SrcClk8,   Enabled,  All},
+  {SrcClk7,   Enabled,  All},
+  {SrcClk6,   Enabled,  All},
+  {SrcClk5,   Enabled,  All},
+  {SrcClk4,   Enabled,  All},
+  {SrcClk3,   Enabled,  All},
+  {SrcClk2,   Enabled,  All},
+  {SrcClk1,   Enabled,  All},
+  {SrcClk0,   Enabled,  All},
+  {Ref0,      Enabled,  All},
+  {Dot96,     Enabled,  All},
+  {Usb48,     Enabled,  All},
+  {PciClkF5,  Enabled,  All},
+  {PciClk0,   Enabled,  All},
+  {PciClk2,   Enabled,  All},
+  {PciClk3,   Enabled,  All},
+  {PciClk4,   Disabled,  All},
+  {Cr_B,   EnabledWithSwitch,  All},
+};
+
+//
+// ClockSxInfo Table
+//  This is a list of clocks that need to be set to a known state when the
+//  system enters S4 or S5.
+//
+EFI_STATIC_SIGNALS mAtxSxClocks[] = {
+  {SaveClockConfiguration, Disabled, All}
+};
+
+//
+// ATX settings structure
+//
+EFI_CLOCK_PLATFORM_INFO mAtxClockSettings = {
+  mAtxStaticClocks,
+  sizeof(mAtxStaticClocks) / sizeof(mAtxStaticClocks[0]),
+  mAtxSxClocks,
+  sizeof(mAtxSxClocks) / sizeof(mAtxSxClocks[0])
+};
+
+#if defined( RVP_SUPPORT ) && RVP_SUPPORT
+//
+// RVP Clock Settings
+//
+// Static clock table.
+//  This should be used to define any clock settings that are static
+//  (Always On or Always Off).  Dynamic clocks should be set to enabled
+//  in this table.
+//
+//UPSD_TBD Check with Jan if any porting required.
+//
+EFI_STATIC_SIGNALS mRvpStaticClocks[] = {
+  {SrcClk11,  Enabled,  All},     // Not used/not present but leave coding enabled
+  {SrcClk10,  Enabled,  All},     // Not used/not present but leave coding enabled
+  {SrcClk9,   Enabled,  All},     // Not used/not present but leave coding enabled
+  {SrcClk8,   Enabled,  All},     // ICHSATAII
+  {SrcClk7,   Enabled,  All},     // DPL_REFSSCLKIN
+  {SrcClk6,   Enabled,  All},     // 100M_MCH
+  {SrcClk5,   Enabled,  All},     // Mini-PCIe  //TODO PNV: Need to check ICH GPIO38:
+                                                // 0: turn on; 1: turn off
+  {SrcClk4,   Enabled,  All},     // ICHSATA
+  {SrcClk3,   Enabled,  All},     // 100M_ICH
+  {SrcClk2,   Enabled,  All},     // 100M_LAN
+  {SrcClk1,   Enabled,  All},     // 25M_LAN
+  {SrcClk0,   Enabled,  All},     // 96M_DREF
+  {Ref0,      Enabled,  All},
+  {Dot96,     Enabled,  All},
+  {Usb48,     Enabled,  All},
+  {PciClkF5,  Enabled,  All},     // 33M_ICH
+  {PciClk0,   Enabled,  All},     // 33M_RISER
+  {PciClk1,   Enabled,  All},     // 33M_RISER
+  {PciClk2,   Enabled,  All},     // VDD_Clock
+  {PciClk3,   Enabled,  All},     // 33M_S1
+  {PciClk4,   Enabled,  All},     // 33M_PA
+};
+
+//
+// Dynamic clock table
+// This is used to determine if a clock should be left on or turned off based
+// on the presence of a device.  The bridge information is used so the bus
+// number for the device to be detected can be found.
+//
+
+//
+// ClockSxInfo Table
+// This is a list of clocks that need to be set to a known state when the
+// system enters S4 or S5.
+//
+EFI_STATIC_SIGNALS mRvpSxClocks[] = {
+  {SaveClockConfiguration, Disabled, All}
+};
+
+//
+// RVP settings structure
+//
+EFI_CLOCK_PLATFORM_INFO mRvpClockSettings = {
+  mRvpStaticClocks,
+  sizeof(mRvpStaticClocks) / sizeof(mRvpStaticClocks[0]),
+  0,  // No clocks will be turned off mRvpDynamicClocks,
+  0, // No clocks will be turned off sizeof(mRvpDynamicClocks) / sizeof(mRvpDynamicClocks[0]),
+  mRvpSxClocks,
+  sizeof(mRvpSxClocks) / sizeof(mRvpSxClocks[0])
+};
+#endif
+
+VOID
+InitializeClockRouting(
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           BoardIdVarSize;
+  EFI_BOARD_FEATURES              BoardIdVar;
+  EFI_CLOCK_PLATFORM_INFO         *ClockPolicy;
+  EFI_HANDLE                      Handle;
+
+  ClockPolicy = &mDefClockPolicy;
+
+  //
+  // Do modifications based on board type
+  //
+  BoardIdVarSize = sizeof (EFI_BOARD_FEATURES);
+  Status = gRT->GetVariable (
+                  BOARD_FEATURES_NAME,
+                  &gEfiBoardFeaturesGuid,
+                  NULL,
+                  &BoardIdVarSize,
+                  &BoardIdVar
+                  );
+  if (!EFI_ERROR (Status)) {
+
+#if defined( RVP_SUPPORT ) && RVP_SUPPORT
+    if (BoardIdVar & B_BOARD_FEATURES_RVP) {
+      ClockPolicy = &mRvpClockSettings;
+    }
+#else
+
+    //
+    // Isolate board type information
+    //
+    BoardIdVar = BoardIdVar & (B_BOARD_FEATURES_FORM_FACTOR_ATX |
+                               B_BOARD_FEATURES_FORM_FACTOR_BTX |
+                               B_BOARD_FEATURES_FORM_FACTOR_MICRO_ATX |
+                               B_BOARD_FEATURES_FORM_FACTOR_MICRO_BTX);
+
+    if (BoardIdVar == B_BOARD_FEATURES_FORM_FACTOR_ATX ||
+        BoardIdVar == B_BOARD_FEATURES_FORM_FACTOR_MICRO_ATX) {
+      ClockPolicy = &mAtxClockSettings;
+    }
+
+#endif
+
+  }
+
+  Handle = NULL;
+  Status = gBS->InstallProtocolInterface (
+                  &Handle,
+                  &gEfiCk505ClockPlatformInfoGuid,
+                  EFI_NATIVE_INTERFACE,
+                  ClockPolicy
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+}
+
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Configuration.h b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Configuration.h
new file mode 100644
index 0000000000..23e03111c9
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Configuration.h
@@ -0,0 +1,692 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+    Configuration.h
+
+Abstract:
+
+    Driver configuration include file
+
+
+--*/
+
+#ifndef _CONFIGURATION_H
+#define _CONFIGURATION_H
+
+#define EFI_NON_DEVICE_CLASS               0x00
+#define EFI_DISK_DEVICE_CLASS              0x01
+#define EFI_VIDEO_DEVICE_CLASS             0x02
+#define EFI_NETWORK_DEVICE_CLASS           0x04
+#define EFI_INPUT_DEVICE_CLASS             0x08
+#define EFI_ON_BOARD_DEVICE_CLASS          0x10
+#define EFI_OTHER_DEVICE_CLASS             0x20
+
+//
+// Processor labels
+//
+#define PROCESSOR_HT_MODE           0x0100
+#define PROCESSOR_FSB_MULTIPLIER    0x0101
+#define PROCESSOR_MULTIPLIER_OVERRIDE_CONTROL  0x0211
+
+//
+// Memory labels
+//
+#define MEMORY_SLOT1_SPEED          0x0200
+#define MEMORY_SLOT2_SPEED          0x0201
+#define MEMORY_SLOT3_SPEED          0x0202
+#define MEMORY_SLOT4_SPEED          0x0203
+#define END_MEMORY_SLOT_SPEED       0x020F
+#define PERFORMANCE_MEMORY_PROFILE_CONTROL  0x0210
+#define UCLK_RATIO_CONTROL          0x0212
+
+//
+// Language label
+//
+#define FRONT_PAGE_ITEM_LANGUAGE    0x300
+
+//
+// Boot Labels
+//
+#define BOOT_DEVICE_PRIORITY_BEGIN  0x0400
+#define BOOT_DEVICE_PRIORITY_END    0x0401
+#define BOOT_OPTICAL_DEVICE_BEGIN   0x0410
+#define BOOT_OPTICAL_DEVICE_END     0x0411
+#define BOOT_REMOVABLE_DEVICE_BEGIN 0x0420
+#define BOOT_REMOVABLE_DEVICE_END   0x0421
+#define BOOT_PXE_DEVICE_BEGIN       0x0430
+#define BOOT_PXE_DEVICE_END         0x0431
+#define BOOT_MENU_TYPE_BEGIN        0x0440
+#define BOOT_MENU_TYPE_END          0x0441
+#define BOOT_USB_DEVICE_BEGIN       0x0450
+#define BOOT_USB_DEVICE_END         0x0451
+#define BOOT_USB_FIRST_BEGIN        0x0460
+#define BOOT_USB_FIRST_END          0x0461
+#define BOOT_UEFI_BEGIN             0x0470
+#define BOOT_UEFI_END               0x0471
+#define BOOT_USB_UNAVAILABLE_BEGIN  0x0480
+#define BOOT_USB_UNAVAILABLE_END    0x0481
+#define BOOT_CD_UNAVAILABLE_BEGIN   0x0490
+#define BOOT_CD_UNAVAILABLE_END     0x0491
+#define BOOT_FDD_UNAVAILABLE_BEGIN  0x04A0
+#define BOOT_FDD_UNAVAILABLE_END    0x04A1
+#define BOOT_DEVICE_PRIORITY_DEFAULT_BEGIN  0x04B0
+#define BOOT_DEVICE_PRIORITY_DEFAULT_END    0x04B1
+#define BOOT_USB_OPT_LABEL_BEGIN    0x04C0
+#define BOOT_USB_OPT_LABEL_END      0x04C1
+
+#define VAR_EQ_ADMIN_NAME               0x0041  // A
+#define VAR_EQ_ADMIN_DECIMAL_NAME       L"65"
+#define VAR_EQ_VIEW_ONLY_NAME           0x0042  // B
+#define VAR_EQ_VIEW_ONLY_DECIMAL_NAME   L"66"
+#define VAR_EQ_CONFIG_MODE_NAME         0x0043  // C
+#define VAR_EQ_CONFIG_MODE_DECIMAL_NAME L"67"
+#define VAR_EQ_CPU_EE_NAME              0x0045  // E
+#define VAR_EQ_CPU_EE_DECIMAL_NAME  L"69"
+#define VAR_EQ_FLOPPY_MODE_NAME         0x0046  // F
+#define VAR_EQ_FLOPPY_MODE_DECIMAL_NAME L"70"
+#define VAR_EQ_HT_MODE_NAME             0x0048  // H
+#define VAR_EQ_HT_MODE_DECIMAL_NAME     L"72"
+#define VAR_EQ_AHCI_MODE_NAME           0x0049  // I
+#define VAR_EQ_AHCI_MODE_DECIMAL_NAME   L"73"
+#define VAR_EQ_CPU_LOCK_NAME            0x004C  // L
+#define VAR_EQ_CPU_LOCK_DECIMAL_NAME    L"76"
+#define VAR_EQ_NX_MODE_NAME             0x004E  // N
+#define VAR_EQ_NX_MODE_DECIMAL_NAME     L"78"
+#define VAR_EQ_RAID_MODE_NAME           0x0052  // R
+#define VAR_EQ_RAID_MODE_DECIMAL_NAME   L"82"
+#define VAR_EQ_1394_MODE_NAME           0x0054  // T
+#define VAR_EQ_1394_MODE_DECIMAL_NAME   L"84"
+#define VAR_EQ_USER_NAME                0x0055  // U
+#define VAR_EQ_USER_DECIMAL_NAME        L"85"
+#define VAR_EQ_VIDEO_MODE_NAME          0x0056  // V
+#define VAR_EQ_VIDEO_MODE_DECIMAL_NAME  L"86"
+#define VAR_EQ_LEGACY_FP_AUDIO_NAME     0x0057  // W
+#define VAR_EQ_LEGACY_FP_AUDIO_DECIMAL_NAME L"87"
+#define VAR_EQ_EM64T_CAPABLE_NAME       0x0058  // X
+#define VAR_EQ_EM64T_CAPABLE_DECIMAL_NAME L"88"
+#define VAR_EQ_BOARD_FORMFACTOR_NAME    0x0059  // Y
+#define VAR_EQ_BOARD_FORMFACTOR_DECIMAL_NAME L"89"
+#define VAR_EQ_UNCON_CPU_NAME           0x005B  // ??
+#define VAR_EQ_UNCON_CPU_DECIMAL_NAME   L"91"
+#define VAR_EQ_VAR_HIDE_NAME            0x005C  // ??
+#define VAR_EQ_VAR_HIDE_DECIMAL_NAME    L"92"
+#define VAR_EQ_ENERGY_LAKE_NAME         0x005D  // ??
+#define VAR_EQ_ENERGY_LAKE_DECIMAL_NAME L"93"
+#define VAR_EQ_TPM_MODE_NAME            0x005E  // ^
+#define VAR_EQ_TPM_MODE_DECIMAL_NAME    L"94"
+#define VAR_EQ_DISCRETE_SATA_NAME       0x005F  // ??
+#define VAR_EQ_DISCRETE_SATA_DECIMAL_NAME L"95"
+#define VAR_EQ_ROEM_SKU_NAME            0x0060  // ??
+#define VAR_EQ_ROEM_SKU_DECIMAL_NAME    L"96"
+#define VAR_EQ_AMTSOL_MODE_NAME         0x0061  // ??
+#define VAR_EQ_AMTSOL_MODE_DECIMAL_NAME L"97"
+#define VAR_EQ_NO_PEG_MODE_NAME         0x0062  // ??
+#define VAR_EQ_NO_PEG_MODE_DECIMAL_NAME L"98"
+#define VAR_EQ_SINGLE_PROCESSOR_MODE_NAME 0x0063  // ??
+#define VAR_EQ_SINGLE_PROCESSOR_MODE_DECIMAL_NAME L"99"
+#define VAR_EQ_FLOPPY_HIDE_NAME         0x0064  // ??
+#define VAR_EQ_FLOPPY_HIDE_DECIMAL_NAME L"100"
+#define VAR_EQ_SERIAL_HIDE_NAME         0x0065  // ??
+#define VAR_EQ_SERIAL_HIDE_DECIMAL_NAME L"101"
+#define VAR_EQ_GV3_CAPABLE_NAME         0x0066 // f
+#define VAR_EQ_GV3_CAPABLE_DECIMAL_NAME L"102"
+#define VAR_EQ_2_MEMORY_NAME            0x0067 // ??
+#define VAR_EQ_2_MEMORY_DECIMAL_NAME    L"103"
+#define VAR_EQ_2_SATA_NAME              0x0068 // ??
+#define VAR_EQ_2_SATA_DECIMAL_NAME      L"104"
+#define VAR_EQ_NEC_SKU_NAME            0x0069  // ??
+#define VAR_EQ_NEC_SKU_DECIMAL_NAME    L"105"
+#define VAR_EQ_AMT_MODE_NAME            0x006A  // ??
+#define VAR_EQ_AMT_MODE_DECIMAL_NAME    L"106"
+#define VAR_EQ_LCLX_SKU_NAME            0x006B  // ??
+#define VAR_EQ_LCLX_SKU_DECIMAL_NAME    L"107"
+#define VAR_EQ_VT_NAME                  0x006C
+#define VAR_EQ_VT_DECIMAL_NAME          L"108"
+#define VAR_EQ_LT_NAME                  0x006D
+#define VAR_EQ_LT_DECIMAL_NAME          L"109"
+#define VAR_EQ_ITK_BIOS_MOD_NAME         0x006E  // ??
+#define VAR_EQ_ITK_BIOS_MOD_DECIMAL_NAME L"110"
+#define VAR_EQ_HPET_NAME                0x006F
+#define VAR_EQ_HPET_DECIMAL_NAME        L"111"
+#define VAR_EQ_ADMIN_INSTALLED_NAME          0x0070  // ??
+#define VAR_EQ_ADMIN_INSTALLED_DECIMAL_NAME  L"112"
+#define VAR_EQ_USER_INSTALLED_NAME          0x0071  // ??
+#define VAR_EQ_USER_INSTALLED_DECIMAL_NAME  L"113"
+#define VAR_EQ_CPU_CMP_NAME             0x0072
+#define VAR_EQ_CPU_CMP_DECIMAL_NAME     L"114"
+#define VAR_EQ_LAN_MAC_ADDR_NAME          0x0073  // ??
+#define VAR_EQ_LAN_MAC_ADDR_DECIMAL_NAME  L"115"
+#define VAR_EQ_PARALLEL_HIDE_NAME         0x0074  // ??
+#define VAR_EQ_PARALLEL_HIDE_DECIMAL_NAME L"116"
+#define VAR_EQ_AFSC_SETUP_NAME          0x0075
+#define VAR_EQ_AFSC_SETUP_DECIMAL_NAME  L"117"
+#define VAR_EQ_MINICARD_MODE_NAME       0x0076  //
+#define VAR_EQ_MINICARD_MODE_DECIMAL_NAME   L"118"
+#define VAR_EQ_VIDEO_IGD_NAME          0x0077  //
+#define VAR_EQ_VIDEO_IGD_DECIMAL_NAME  L"119"
+#define VAR_EQ_ALWAYS_ENABLE_LAN_NAME            0x0078  //
+#define VAR_EQ_ALWAYS_ENABLE_LAN_DECIMAL_NAME    L"120"
+#define VAR_EQ_LEGACY_FREE_NAME          0x0079  //
+#define VAR_EQ_LEGACY_FREE_DECIMAL_NAME   L"121"
+#define VAR_EQ_CLEAR_CHASSIS_INSTRUSION_STATUS_NAME           0x007A
+#define VAR_EQ_CLEAR_CHASSIS_INSTRUSION_STATUS_DECIMAL_NAME  L"122"
+#define VAR_EQ_CPU_FSB_NAME            0x007B  //
+#define VAR_EQ_CPU_FSB_DECIMAL_NAME    L"123"
+#define VAR_EQ_SATA0_DEVICE_NAME            0x007C  //
+#define VAR_EQ_SATA0_DVICE_DECIMAL_NAME    L"124"
+#define VAR_EQ_SATA1_DEVICE_NAME            0x007D  //
+#define VAR_EQ_SATA1_DVICE_DECIMAL_NAME    L"125"
+#define VAR_EQ_SATA2_DEVICE_NAME            0x007E  //
+#define VAR_EQ_SATA2_DVICE_DECIMAL_NAME    L"126"
+#define VAR_EQ_SATA3_DEVICE_NAME            0x007F  //
+#define VAR_EQ_SATA3_DVICE_DECIMAL_NAME    L"127"
+#define VAR_EQ_SATA4_DEVICE_NAME            0x0080  //
+#define VAR_EQ_SATA4_DVICE_DECIMAL_NAME    L"128"
+#define VAR_EQ_SATA5_DEVICE_NAME            0x0081  //
+#define VAR_EQ_SATA5_DVICE_DECIMAL_NAME    L"129"
+#define VAR_EQ_TPM_STATUS_NAME              0x0082      // To indicate if TPM is enabled
+#define VAR_EQ_TPM_STATUS_DECIMAL_NAME     L"130"
+#define VAR_EQ_HECETA6E_PECI_CPU_NAME   0x0083
+#define VAR_EQ_HECETA6E_PECI_CPU_DECIMAL_NAME L"131"
+#define VAR_EQ_USB_2_NAME                   0x0084  //
+#define VAR_EQ_USB_2_DECIMAL_NAME          L"132"
+#define VAR_EQ_RVP_NAME                   0x0085  //
+#define VAR_EQ_RVP_DECIMAL_NAME          L"133"
+#define VAR_EQ_ECIR_NAME                    0x0086
+#define VAR_EQ_ECIR_DECIMAL_NAME           L"134"
+#define VAR_EQ_WAKONS5KB_NAME               0x0087
+#define VAR_EQ_WAKONS5KB_DECIMAL_NAME      L"135"
+#define VAR_EQ_HDAUDIOLINKBP_NAME           0x0088
+#define VAR_EQ_HDAUDIOLINKBP_DECIMAL_NAME  L"136"
+#define VAR_EQ_FINGERPRINT_NAME             0x0089
+#define VAR_EQ_FINGERPRINT_DECIMAL_NAME    L"137"
+#define VAR_EQ_BLUETOOTH_NAME               0x008A
+#define VAR_EQ_BLUETOOTH_DECIMAL_NAME      L"138"
+#define VAR_EQ_WLAN_NAME                    0x008B
+#define VAR_EQ_WLAN_DECIMAL_NAME           L"139"
+#define VAR_EQ_1_PATA_NAME                  0x008C
+#define VAR_EQ_1_PATA_DECIMAL_NAME         L"140"
+#define VAR_EQ_ACTIVE_PROCESSOR_CORE_NAME          0x008D
+#define VAR_EQ_ACTIVE_PROCESSOR_CORE_DECIMAL_NAME  L"141"
+#define VAR_EQ_TURBO_MODE_CAP_NAME          0x008E
+#define VAR_EQ_TURBO_MODE_CAP_DECIMAL_NAME  L"142"
+#define VAR_EQ_XE_MODE_CAP_NAME             0x008F
+#define VAR_EQ_XE_MODE_CAP_DECIMAL_NAME     L"143"
+#define VAR_EQ_NPI_QPI_VOLTAGE_NAME         0x0090
+#define VAR_EQ_NPI_QPI_VOLTAGE_DECIMAL_NAME L"144"
+#define VAR_EQ_PRE_PROD_NON_XE_NAME         0x0091
+#define VAR_EQ_PRE_PROD_NON_XE_DECIMAL_NAME L"145"
+#define VAR_EQ_2_C0_MEMORY_NAME            0x0092 // ??
+#define VAR_EQ_2_C0_MEMORY_DECIMAL_NAME    L"146"
+#define VAR_EQ_LVDS_NAME                    0x0093
+#define VAR_EQ_LVDS_DECIMAL_NAME            L"147"
+#define VAR_EQ_USB_OPTION_SHOW_NAME                    0x0094
+#define VAR_EQ_USB_OPTION_SHOW_DECIMAL_NAME            L"148"
+#define VAR_EQ_HDD_MASTER_INSTALLED_NAME      0x0095
+#define VAR_EQ_HDD_MASTER_INSTALLED_DECIMAL_NAME      L"149"
+#define VAR_EQ_HDD_USER_INSTALLED_NAME        0x0096
+#define VAR_EQ_HDD_USER_INSTALLED_DECIMAL_NAME       L"150"
+#define VAR_EQ_PS2_HIDE_NAME         0x0097  // ??
+#define VAR_EQ_PS2_HIDE_DECIMAL_NAME L"151"
+#define VAR_EQ_VIDEO_SLOT_NAME       0x0098
+#define VAR_EQ_VIDEO_SLOT_DECIMAL_NAME       L"152"
+#define VAR_EQ_HDMI_SLOT_NAME       0x0099
+#define VAR_EQ_HDMI_SLOT_DECIMAL_NAME       L"153"
+#define VAR_EQ_SERIAL2_HIDE_NAME         0x009a
+#define VAR_EQ_SERIAL2_HIDE_DECIMAL_NAME L"154"
+
+
+#define VAR_EQ_LVDS_WARNING_HIDE_NAME    0x009e
+#define VAR_EQ_LVDS_WARNING_HIDE_DECIMAL_NAME L"158"
+
+
+#define VAR_EQ_MSATA_HIDE_NAME    0x009f
+#define VAR_EQ_MSATA_HIDE_DECIMAL_NAME L"159"
+
+
+#define VAR_EQ_PCI_SLOT1_NAME    0x00a0
+#define VAR_EQ_PCI_SLOT1_DECIMAL_NAME L"160"
+#define VAR_EQ_PCI_SLOT2_NAME    0x00a1
+#define VAR_EQ_PCI_SLOT2_DECIMAL_NAME L"161"
+
+//
+// Generic Form Ids
+//
+#define ROOT_FORM_ID                    1
+
+//
+// Advance Page. Do not have to be sequential but have to be unique
+//
+#define CONFIGURATION_ROOT_FORM_ID          2
+#define BOOT_CONFIGURATION_ID               3
+#define ONBOARDDEVICE_CONFIGURATION_ID      4
+#define DRIVE_CONFIGURATION_ID              5
+#define FLOPPY_CONFIGURATION_ID             6
+#define EVENT_LOG_CONFIGURATION_ID          7
+#define VIDEO_CONFIGURATION_ID              8
+#define USB_CONFIGURATION_ID                9
+#define HARDWARE_MONITOR_CONFIGURATION_ID   10
+#define VIEW_EVENT_LOG_CONFIGURATION_ID     11
+#define MEMORY_OVERRIDE_ID                  12
+#define CHIPSET_CONFIGURATION_ID            13
+#define BURN_IN_MODE_ID                     14
+#define PCI_EXPRESS_ID                      15
+#define MANAGEMENT_CONFIGURATION_ID         16
+#define CPU_CONFIGURATION_ID                17
+#define PCI_CONFIGURATION_ID                18
+#define SECURITY_CONFIGURATION_ID           19
+#define ZIP_CONFIGURATION_ID                20
+#define AFSC_FAN_CONTROL_ID                 21
+#define VFR_FORMID_CSI                      22
+#define VFR_FORMID_MEMORY                   23
+#define VFR_FORMID_IOH                      24
+#define VFR_FORMID_CPU_CSI                  25
+#define VFR_FORMID_IOH_CONFIG               26
+#define VFR_FORMID_VTD                      27
+#define VFR_FORMID_PCIE_P0                  28
+#define VFR_FORMID_PCIE_P1                  29
+#define VFR_FORMID_PCIE_P2                  30
+#define VFR_FORMID_PCIE_P3                  31
+#define VFR_FORMID_PCIE_P4                  32
+#define VFR_FORMID_PCIE_P5                  33
+#define VFR_FORMID_PCIE_P6                  34
+#define VFR_FORMID_PCIE_P7                  35
+#define VFR_FORMID_PCIE_P8                  36
+#define VFR_FORMID_PCIE_P9                  37
+#define VFR_FORMID_PCIE_P10                 38
+#define VFR_FID_SKT0                        39
+#define VFR_FID_IOH0                        40
+#define VFR_FID_IOH_DEV_HIDE                41
+#define PROCESSOR_OVERRIDES_FORM_ID         42
+#define BUS_OVERRIDES_FORM_ID               43
+#define REF_OVERRIDES_FORM_ID               44
+#define MEMORY_INFORMATION_ID               45
+#define LVDS_WARNING_ID                     46
+#define LVDS_CONFIGURATION_ID               47
+#define PCI_SLOT_CONFIGURATION_ID           48
+#define HECETA_CONFIGURATION_ID             49
+#define LVDS_EXPERT_CONFIGURATION_ID        50
+#define PCI_SLOT_7_ID                       51
+#define PCI_SLOT_6_ID                       52
+#define PCI_SLOT_5_ID                       53
+#define PCI_SLOT_4_ID                       54
+#define PCI_SLOT_3_ID                       55
+#define PCI_SLOT_2_ID                       56
+#define PCI_SLOT_1_ID                       57
+#define BOOT_DISPLAY_ID                     58
+#define CPU_PWR_CONFIGURATION_ID            59
+
+#define FSC_CONFIGURATION_ID                60
+#define FSC_CPU_TEMPERATURE_FORM_ID         61
+#define FSC_VTT_VOLTAGE_FORM_ID             62
+#define FSC_FEATURES_CONTROL_ID             63
+#define FSC_FAN_CONFIGURATION_ID            64
+#define FSC_PROCESSOR_FAN_CONFIGURATION_ID  65
+#define FSC_FRONT_FAN_CONFIGURATION_ID      66
+#define FSC_REAR_FAN_CONFIGURATION_ID       67
+#define FSC_AUX_FAN_CONFIGURATION_ID        68
+#define FSC_12_VOLTAGE_FORM_ID              69
+#define FSC_5_VOLTAGE_FORM_ID               70
+#define FSC_3P3_VOLTAGE_FORM_ID             71
+#define FSC_2P5_VOLTAGE_FORM_ID             72
+#define FSC_VCC_VOLTAGE_FORM_ID             73
+#define FSC_PCH_TEMPERATURE_FORM_ID         74
+#define FSC_MEM_TEMPERATURE_FORM_ID         75
+#define FSC_VR_TEMPERATURE_FORM_ID          76
+#define FSC_3P3STANDBY_VOLTAGE_FORM_ID      77
+#define FSC_5BACKUP_VOLTAGE_FORM_ID         78
+#define ROOT_MAIN_FORM_ID                   79
+#define ROOT_BOOT_FORM_ID                   80
+#define ROOT_MAINTENANCE_ID                 81
+#define ROOT_POWER_FORM_ID                  82
+#define ROOT_SECURITY_FORM_ID               83
+#define ROOT_PERFORMANCE_FORM_ID            84
+#define ROOT_SYSTEM_SETUP_FORM_ID           85
+
+#define ADDITIONAL_SYSTEM_INFO_FORM_ID      86
+
+#define THERMAL_CONFIG_FORM_ID              87
+
+#define PCI_SLOT_CONFIG_LABEL_ID_1            0x300A
+#define PCI_SLOT_CONFIG_LABEL_ID_2            0x300B
+#define PCI_SLOT_CONFIG_LABEL_ID_3            0x300C
+#define PCI_SLOT_CONFIG_LABEL_ID_4            0x300D
+#define PCI_SLOT_CONFIG_LABEL_ID_5            0x300E
+#define PCI_SLOT_CONFIG_LABEL_ID_6            0x300F
+#define PCI_SLOT_CONFIG_LABEL_ID_7            0x3010
+#define PCI_SLOT_CONFIG_LABEL_ID_8            0x3011
+
+//
+// Advance Hardware Monitor Callback Keys. Do not have to be sequential but have to be unique
+//
+#define CONFIGURATION_HARDWARE_CALLBACK_KEY            0x2000
+#define ADVANCE_VIDEO_CALLBACK_KEY                     0x2001
+#define CONFIGURATION_FSC_CALLBACK_KEY                 0x2002
+#define CONFIGURATION_RESTORE_FAN_CONTROL_CALLBACK_KEY 0x2003
+#define CONFIGURATION_LVDS_CALLBACK_KEY                0x2004
+#define CONFIGURATION_PREDEFINED_EDID_CALLBACK_KEY     0x2005
+#define ADVANCE_LVDS_CALLBACK_KEY           0x2010
+
+//
+// Main Callback Keys. Do not have to be sequential but have to be unique
+//
+#define MAIN_LANGUAGE_CALLBACK_KEY          0x3000
+
+//
+// Power Hardware Monitor Callback Keys. Do not have to be sequential but have to be unique
+//
+#define POWER_HARDWARE_CALLBACK_KEY         0x4000
+
+//
+// Performance Callback Keys. Do not have to be sequential but have to be unique
+//
+#define PROCESSOR_OVERRIDES_CALLBACK_KEY 0x5000
+#define PERFORMANCE_CALLBACK_KEY         0x5001
+#define BUS_OVERRIDES_CALLBACK_KEY       0x5002
+#define MEMORY_CFG_CALLBACK_KEY          0x5003
+#define PERFORMANCE_STATUS_CALLBACK_KEY  0x5004
+#define MEMORY_RATIO_CALLBACK_KEY        0x5005
+#define MEMORY_MODE_CALLBACK_KEY         0x5006
+
+//
+// Security Callback Keys. Do not have to be sequential but have to be unique
+//
+#define SECURITY_SUPERVISOR_CALLBACK_KEY    0x1000
+#define SECURITY_USER_CALLBACK_KEY          0x1001
+#define SECURITY_CLEAR_ALL_CALLBACK_KEY     0x1002
+#define SECURITY_CLEAR_USER_CALLBACK_KEY    0x1004
+#define SECURITY_RESET_AMT_CALLBACK_KEY     0x1008
+#define SECURITY_CHANGE_VT_CALLBACK_KEY     0x1010
+#define SECURITY_MASTER_HDD_CALLBACK_KEY    0x1020
+#define SECURITY_USER_HDD_CALLBACK_KEY      0x1040
+
+//
+// Boot Callback Keys. Do not have to be sequential but have to be unique
+//
+#define BOOT_HYPERBOOT_CALLBACK_KEY                 0x6003
+#define BOOT_HYPERBOOT_CALLBACK_KEY_DISABLE         0x6004
+#define BOOT_HYPERBOOT_CALLBACK_KEY_USB             0x6005
+#define BOOT_HYPERBOOT_CALLBACK_KEY_DISABLE_USB_OPT 0x6006
+
+//
+// IDCC/Setup FSB Frequency Override Range
+//
+#define EFI_IDCC_FSB_MIN   133
+#define EFI_IDCC_FSB_MAX   240
+#define EFI_IDCC_FSB_STEP  1
+
+//
+// Reference voltage
+//
+#define EFI_REF_DAC_MIN     0
+#define EFI_REF_DAC_MAX     255
+#define EFI_GTLREF_DEF      170
+#define EFI_DDRREF_DEF      128
+#define EFI_DIMMREF_DEF     128
+
+//
+// Setup FSB Frequency Override Range
+//
+#define EFI_FSB_MIN       133
+#define EFI_FSB_MAX       240
+#define EFI_FSB_STEP      1
+#define EFI_FSB_AUTOMATIC 0
+#define EFI_FSB_MANUAL    1
+#define FSB_FREQ_ENTRY_COUNT ((EFI_FSB_MAX - EFI_FSB_MIN)/EFI_FSB_STEP) + 1
+#define FSB_FREQ_ENTRY_TYPE  UINT16_TYPE
+
+//
+// Setup processor multiplier range
+//
+#define EFI_PROC_MULT_MIN   5
+#define EFI_PROC_MULT_MAX   40
+#define EFI_PROC_MULT_STEP  1
+#define EFI_PROC_AUTOMATIC  0
+#define EFI_PROC_MANUAL     1
+#define PROC_MULT_ENTRY_COUNT ((EFI_PROC_MULT_MAX - EFI_PROC_MULT_MIN)/EFI_PROC_MULT_STEP) + 1
+#define PROC_MULT_ENTRY_TYPE  UINT8_TYPE
+
+//
+// PCI Express Definitions
+//
+#define EFI_PCIE_FREQ_DEF       0x0
+
+#define PCIE_FREQ_ENTRY_TYPE  UINT8_TYPE
+#define PCIE_FREQ_ENTRY_7       0x7
+#define PCIE_FREQ_ENTRY_6       0x6
+#define PCIE_FREQ_ENTRY_5       0x5
+#define PCIE_FREQ_ENTRY_4       0x4
+#define PCIE_FREQ_ENTRY_3       0x3
+#define PCIE_FREQ_ENTRY_2       0x2
+#define PCIE_FREQ_ENTRY_1       0x1
+#define PCIE_FREQ_ENTRY_0       0x0
+
+#define PCIE_FREQ_TRANSLATION_TABLE_ENTRIES 8
+#define PCIE_FREQ_TRANSLATION_TABLE     { PCIE_FREQ_ENTRY_0, \
+                                          PCIE_FREQ_ENTRY_1, \
+                                          PCIE_FREQ_ENTRY_2, \
+                                          PCIE_FREQ_ENTRY_3, \
+                                          PCIE_FREQ_ENTRY_4, \
+                                          PCIE_FREQ_ENTRY_5, \
+                                          PCIE_FREQ_ENTRY_6, \
+                                          PCIE_FREQ_ENTRY_7 }
+
+
+#define PCIE_FREQ_PRECISION     2
+#define PCIE_FREQ_VALUE_7       10924
+#define PCIE_FREQ_VALUE_6       10792
+#define PCIE_FREQ_VALUE_5       10660
+#define PCIE_FREQ_VALUE_4       10528
+#define PCIE_FREQ_VALUE_3       10396
+#define PCIE_FREQ_VALUE_2       10264
+#define PCIE_FREQ_VALUE_1       10132
+#define PCIE_FREQ_VALUE_0       10000
+
+#define PCIE_FREQ_VALUES      { PCIE_FREQ_VALUE_0, \
+                                PCIE_FREQ_VALUE_1, \
+                                PCIE_FREQ_VALUE_2, \
+                                PCIE_FREQ_VALUE_3, \
+                                PCIE_FREQ_VALUE_4, \
+                                PCIE_FREQ_VALUE_5, \
+                                PCIE_FREQ_VALUE_6, \
+                                PCIE_FREQ_VALUE_7 }
+
+//
+// Memory Frequency Definitions
+//
+#define MEMORY_REF_FREQ_ENTRY_DEF     0x08
+
+#define MEMORY_REF_FREQ_ENTRY_TYPE    UINT8_TYPE
+#define MEMORY_REF_FREQ_ENTRY_3       0x04
+#define MEMORY_REF_FREQ_ENTRY_2       0x00
+#define MEMORY_REF_FREQ_ENTRY_1       0x02
+#define MEMORY_REF_FREQ_ENTRY_0       0x01
+
+#define MEMORY_REF_FREQ_TRANSLATION_TABLE_ENTRIES 4
+#define MEMORY_REF_FREQ_TRANSLATION_TABLE     { MEMORY_REF_FREQ_ENTRY_0, \
+                                                MEMORY_REF_FREQ_ENTRY_1, \
+                                                MEMORY_REF_FREQ_ENTRY_2, \
+                                                MEMORY_REF_FREQ_ENTRY_3 }
+
+#define MEMORY_REF_FREQ_PRECISION     0
+#define MEMORY_REF_FREQ_VALUE_3       333
+#define MEMORY_REF_FREQ_VALUE_2       267
+#define MEMORY_REF_FREQ_VALUE_1       200
+#define MEMORY_REF_FREQ_VALUE_0       133
+
+#define MEMORY_REF_FREQ_VALUES      { MEMORY_REF_FREQ_VALUE_0, \
+                                      MEMORY_REF_FREQ_VALUE_1, \
+                                      MEMORY_REF_FREQ_VALUE_2, \
+                                      MEMORY_REF_FREQ_VALUE_3 }
+
+
+//
+// Memory Reference Frequency Definitions
+//
+
+#define MEMORY_FREQ_ENTRY_TYPE    UINT8_TYPE
+#define MEMORY_FREQ_ENTRY_3       0x4
+#define MEMORY_FREQ_ENTRY_2       0x3
+#define MEMORY_FREQ_ENTRY_1       0x2
+#define MEMORY_FREQ_ENTRY_0       0x1
+
+#define MEMORY_FREQ_TRANSLATION_TABLE_ENTRIES 4
+#define MEMORY_FREQ_TRANSLATION_TABLE     { MEMORY_FREQ_ENTRY_0, \
+                                            MEMORY_FREQ_ENTRY_1, \
+                                            MEMORY_FREQ_ENTRY_2, \
+                                            MEMORY_FREQ_ENTRY_3 }
+
+
+#define MEMORY_FREQ_MULT_PRECISION             2
+#define MEMORY_FREQ_MULT_333MHZ_VALUE_3        240
+#define MEMORY_FREQ_MULT_333MHZ_VALUE_2        200
+#define MEMORY_FREQ_MULT_333MHZ_VALUE_1        160
+#define MEMORY_FREQ_MULT_333MHZ_VALUE_0        120
+
+#define MEMORY_FREQ_MULT_266MHZ_VALUE_3        300
+#define MEMORY_FREQ_MULT_266MHZ_VALUE_2        250
+#define MEMORY_FREQ_MULT_266MHZ_VALUE_1        200
+#define MEMORY_FREQ_MULT_266MHZ_VALUE_0        150
+
+#define MEMORY_FREQ_MULT_200MHZ_VALUE_3        400
+#define MEMORY_FREQ_MULT_200MHZ_VALUE_2        333
+#define MEMORY_FREQ_MULT_200MHZ_VALUE_1        267
+#define MEMORY_FREQ_MULT_200MHZ_VALUE_0        200
+
+#define MEMORY_FREQ_MULT_133MHZ_VALUE_3        600
+#define MEMORY_FREQ_MULT_133MHZ_VALUE_2        500
+#define MEMORY_FREQ_MULT_133MHZ_VALUE_1        400
+#define MEMORY_FREQ_MULT_133MHZ_VALUE_0        300
+
+#define MEMORY_FREQ_MULT_333MHZ_VALUES      { MEMORY_FREQ_MULT_333MHZ_VALUE_0, \
+                                              MEMORY_FREQ_MULT_333MHZ_VALUE_1, \
+                                              MEMORY_FREQ_MULT_333MHZ_VALUE_2, \
+                                              MEMORY_FREQ_MULT_333MHZ_VALUE_3 }
+
+#define MEMORY_FREQ_MULT_266MHZ_VALUES      { MEMORY_FREQ_MULT_266MHZ_VALUE_0, \
+                                              MEMORY_FREQ_MULT_266MHZ_VALUE_1, \
+                                              MEMORY_FREQ_MULT_266MHZ_VALUE_2, \
+                                              MEMORY_FREQ_MULT_266MHZ_VALUE_3 }
+
+#define MEMORY_FREQ_MULT_200MHZ_VALUES      { MEMORY_FREQ_MULT_200MHZ_VALUE_0, \
+                                              MEMORY_FREQ_MULT_200MHZ_VALUE_1, \
+                                              MEMORY_FREQ_MULT_200MHZ_VALUE_2, \
+                                              MEMORY_FREQ_MULT_200MHZ_VALUE_3 }
+
+#define MEMORY_FREQ_MULT_133MHZ_VALUES      { MEMORY_FREQ_MULT_133MHZ_VALUE_0, \
+                                              MEMORY_FREQ_MULT_133MHZ_VALUE_1, \
+                                              MEMORY_FREQ_MULT_133MHZ_VALUE_2, \
+                                              MEMORY_FREQ_MULT_133MHZ_VALUE_3 }
+
+//
+// CAS Memory Timing Definitions
+//
+
+#define MEMORY_TCL_ENTRY_TYPE    UINT8_TYPE
+#define MEMORY_TCL_ENTRY_3       0x2
+#define MEMORY_TCL_ENTRY_2       0x1
+#define MEMORY_TCL_ENTRY_1       0x0
+#define MEMORY_TCL_ENTRY_0       0x3
+
+#define MEMORY_TCL_TRANSLATION_TABLE_ENTRIES 4
+#define MEMORY_TCL_TRANSLATION_TABLE     { MEMORY_TCL_ENTRY_0, \
+                                           MEMORY_TCL_ENTRY_1, \
+                                           MEMORY_TCL_ENTRY_2, \
+                                           MEMORY_TCL_ENTRY_3 }
+
+
+#define MEMORY_TCL_PRECISION     0
+#define MEMORY_TCL_VALUE_3       3
+#define MEMORY_TCL_VALUE_2       4
+#define MEMORY_TCL_VALUE_1       5
+#define MEMORY_TCL_VALUE_0       6
+
+#define MEMORY_TCL_VALUES      { MEMORY_TCL_VALUE_0, \
+                                 MEMORY_TCL_VALUE_1, \
+                                 MEMORY_TCL_VALUE_2, \
+                                 MEMORY_TCL_VALUE_3 }
+
+
+//
+// TRCD Memory Timing Definitions
+//
+
+#define MEMORY_TRCD_ENTRY_TYPE    UINT8_TYPE
+#define MEMORY_TRCD_ENTRY_3       0x0
+#define MEMORY_TRCD_ENTRY_2       0x1
+#define MEMORY_TRCD_ENTRY_1       0x2
+#define MEMORY_TRCD_ENTRY_0       0x3
+
+#define MEMORY_TRCD_TRANSLATION_TABLE_ENTRIES 4
+#define MEMORY_TRCD_TRANSLATION_TABLE     { MEMORY_TRCD_ENTRY_0, \
+                                            MEMORY_TRCD_ENTRY_1, \
+                                            MEMORY_TRCD_ENTRY_2, \
+                                            MEMORY_TRCD_ENTRY_3 }
+
+
+#define MEMORY_TRCD_PRECISION     0
+#define MEMORY_TRCD_VALUE_3       2
+#define MEMORY_TRCD_VALUE_2       3
+#define MEMORY_TRCD_VALUE_1       4
+#define MEMORY_TRCD_VALUE_0       5
+
+#define MEMORY_TRCD_VALUES      { MEMORY_TRCD_VALUE_0, \
+                                  MEMORY_TRCD_VALUE_1, \
+                                  MEMORY_TRCD_VALUE_2, \
+                                  MEMORY_TRCD_VALUE_3 }
+
+
+//
+// TRP Memory Timing Definitions
+//
+
+#define MEMORY_TRP_ENTRY_TYPE    UINT8_TYPE
+#define MEMORY_TRP_ENTRY_3       0x0
+#define MEMORY_TRP_ENTRY_2       0x1
+#define MEMORY_TRP_ENTRY_1       0x2
+#define MEMORY_TRP_ENTRY_0       0x3
+
+#define MEMORY_TRP_TRANSLATION_TABLE_ENTRIES 4
+#define MEMORY_TRP_TRANSLATION_TABLE     { MEMORY_TRP_ENTRY_0, \
+                                           MEMORY_TRP_ENTRY_1, \
+                                           MEMORY_TRP_ENTRY_2, \
+                                           MEMORY_TRP_ENTRY_3 }
+
+
+#define MEMORY_TRP_PRECISION     0
+#define MEMORY_TRP_VALUE_3       2
+#define MEMORY_TRP_VALUE_2       3
+#define MEMORY_TRP_VALUE_1       4
+#define MEMORY_TRP_VALUE_0       5
+
+#define MEMORY_TRP_VALUES      { MEMORY_TRP_VALUE_0, \
+                                 MEMORY_TRP_VALUE_1, \
+                                 MEMORY_TRP_VALUE_2, \
+                                 MEMORY_TRP_VALUE_3 }
+
+
+//
+// TRAS Memory Timing Definitions
+//
+#define MEMORY_TRAS_MIN     4
+#define MEMORY_TRAS_MAX     18
+#define MEMORY_TRAS_STEP    1
+#define MEMORY_TRAS_DEFAULT 13
+#define MEMORY_TRAS_COUNT ((MEMORY_TRAS_MAX - MEMORY_TRAS_MIN)/MEMORY_TRAS_STEP) + 1
+#define MEMORY_TRAS_TYPE  UINT8_TYPE
+
+//
+// Uncore Multiplier Definitions
+//
+#define UCLK_RATIO_MIN     12
+#define UCLK_RATIO_MAX     30
+#define UCLK_RATIO_DEFAULT 20
+
+#endif // #ifndef _CONFIGURATION_H
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c
new file mode 100644
index 0000000000..ad667b0bd8
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c
@@ -0,0 +1,89 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+  ExI.c
+
+Abstract:
+
+  ExI configuration based on setup option
+
+
+--*/
+
+
+#include "PlatformDxe.h"
+
+#define PchLpcPciCfg32(Register)  MmioRead32 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, Register))
+
+//
+// Procedure: GetPmcBase
+//
+// Description: This function read content of B:D:F 0:31:0, offset 44h (for
+// PmcBase)
+//
+// Input: None
+//
+// Output:  32 bit PmcBase
+//
+UINT32
+GetPmcBase (
+  VOID
+  )
+{
+  return (PchLpcPciCfg32 (R_PCH_LPC_PMC_BASE) & B_PCH_LPC_PMC_BASE_BAR);
+}
+
+/**
+  Configure ExI.
+
+  @param ImageHandle    Pointer to the loaded image protocol for this driver
+  @param SystemTable    Pointer to the EFI System Table
+
+  @retval EFI_SUCCESS   The driver initializes correctly.
+**/
+VOID
+InitExI (
+  )
+{
+  EFI_STATUS                  Status;
+
+  SYSTEM_CONFIGURATION          SystemConfiguration;
+  UINTN       VarSize;
+
+  VarSize = sizeof(SYSTEM_CONFIGURATION);
+
+  Status = gRT->GetVariable(
+                  L"Setup",
+                  &gEfiNormalSetupGuid,
+                  NULL,
+                  &VarSize,
+                  &SystemConfiguration
+                  );
+
+  if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
+    //The setup variable is corrupted
+    VarSize = sizeof(SYSTEM_CONFIGURATION);
+    Status = gRT->GetVariable(
+              L"SetupRecovery",
+              &gEfiNormalSetupGuid,
+              NULL,
+              &VarSize,
+              &SystemConfiguration
+              );
+    ASSERT_EFI_ERROR (Status);
+  }  
+
+  if (SystemConfiguration.ExISupport == 1) {
+	  MmioOr32 ((UINTN) (GetPmcBase() + R_PCH_PMC_MTPMC1), (UINT32) BIT0+BIT1+BIT2);
+  } else if (SystemConfiguration.ExISupport == 0) {
+    MmioAnd32 ((UINTN) (GetPmcBase() + R_PCH_PMC_MTPMC1), ~((UINT32) BIT0+BIT1+BIT2)); //clear bit 0,1,2
+  }
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchPlatformPolicy.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchPlatformPolicy.c
new file mode 100644
index 0000000000..fc19635f99
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchPlatformPolicy.c
@@ -0,0 +1,484 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   
+
+
+Module Name:
+
+
+  PchPlatformPolicy.c
+
+Abstract:
+
+
+--*/
+
+#include "PlatformDxe.h"
+#include <Protocol/PchPlatformPolicy.h>
+#include <Protocol/VlvPlatformPolicy.h>
+#include <Library/PchPlatformLib.h>
+
+#include "AzaliaVerbTable.h"
+#include "Protocol/GlobalNvsArea.h"
+#include "Protocol/DxePchPolicyUpdateProtocol.h"
+
+#define MOBILE_PLATFORM 1
+#define DESKTOP_PLATFORM 2
+
+EFI_GUID                        gDxePchPolicyUpdateProtocolGuid = DXE_PCH_POLICY_UPDATE_PROTOCOL_GUID;
+DXE_PCH_POLICY_UPDATE_PROTOCOL  mDxePchPolicyUpdate = { 0 };
+
+/**
+
+  Updates the feature policies according to the setup variable.
+
+  @retval VOID
+
+**/
+VOID
+InitPchPlatformPolicy (
+  IN EFI_PLATFORM_INFO_HOB      *PlatformInfo
+  )
+{
+  DXE_PCH_PLATFORM_POLICY_PROTOCOL *DxePlatformPchPolicy;
+  EFI_STATUS                       Status;
+  EFI_GLOBAL_NVS_AREA_PROTOCOL     *GlobalNvsArea;
+  UINT8                            PortIndex;
+  EFI_HANDLE                       Handle;
+  PCH_STEPPING                     SocStepping = PchA0;
+  BOOLEAN                          ModifyVariable;
+
+  ModifyVariable = FALSE;
+  DEBUG ((EFI_D_INFO, "InitPchPlatformPolicy() - Start\n"));
+
+  Status  = gBS->LocateProtocol (&gDxePchPlatformPolicyProtocolGuid, NULL, (VOID **) &DxePlatformPchPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  //  Locate the Global NVS Protocol.
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiGlobalNvsAreaProtocolGuid,
+                  NULL,
+                  (VOID **) &GlobalNvsArea
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Update system information
+  //
+  DxePlatformPchPolicy->Revision  = DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_12;
+
+  //
+  // General initialization
+  //
+  DxePlatformPchPolicy->BusNumber = 0;
+
+  //
+  // VLV BIOS Spec Section 3.6 Flash Security Recommendation,
+  // Intel strongly recommends that BIOS sets the BIOS Interface Lock Down bit. Enabling this bit
+  // will mitigate malicious software attempts to replace the system BIOS option ROM with its own code.
+  // We always enable this as a platform policy.
+  //
+  DxePlatformPchPolicy->LockDownConfig->BiosInterface = PCH_DEVICE_ENABLE;
+  DxePlatformPchPolicy->LockDownConfig->BiosLock = mSystemConfiguration.SpiRwProtect;
+
+  //
+  // DeviceEnables
+  //
+  DxePlatformPchPolicy->DeviceEnabling->Lan = mSystemConfiguration.Lan;
+  DxePlatformPchPolicy->DeviceEnabling->Azalia        = mSystemConfiguration.PchAzalia;
+  DxePlatformPchPolicy->DeviceEnabling->Sata          = mSystemConfiguration.Sata;
+  DxePlatformPchPolicy->DeviceEnabling->Smbus         = PCH_DEVICE_ENABLE;
+  DxePlatformPchPolicy->DeviceEnabling->LpeEnabled    = mSystemConfiguration.Lpe;
+
+  DxePlatformPchPolicy->UsbConfig->Ehci1Usbr          = PCH_DEVICE_DISABLE;
+
+  DxePlatformPchPolicy->UsbConfig->UsbXhciLpmSupport =mSystemConfiguration.UsbXhciLpmSupport;
+
+  //
+  // Disable FFRD PR0 USB port2 for power saving since PR0 uses non-POR WWAN (but enable on PR0.3/PR0.5/PR1)
+  //
+  if ((PlatformInfo->BoardId == BOARD_ID_BL_FFRD) && (PlatformInfo->BoardRev == PR0))
+    if (mSystemConfiguration.PchUsbPort[2] !=0) {
+      mSystemConfiguration.PchUsbPort[2]=0;
+      ModifyVariable = TRUE;
+    }
+
+
+  if (ModifyVariable) {
+    Status = gRT->SetVariable (
+                    NORMAL_SETUP_NAME,
+                    &gEfiNormalSetupGuid,
+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                    sizeof(SYSTEM_CONFIGURATION),
+                    &mSystemConfiguration
+                    );
+  }
+
+  SocStepping = PchStepping();
+  if (mSystemConfiguration.UsbAutoMode == 1) {   // auto mode is enabled
+    if (PchA0 == SocStepping) {
+    	//
+      //  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", SocStepping));
+    } 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", SocStepping));
+    }
+    //
+    //overwrite the setting
+    //
+    Status = gRT->SetVariable(
+                    NORMAL_SETUP_NAME,
+                    &gEfiNormalSetupGuid,
+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                    sizeof(SYSTEM_CONFIGURATION),
+                    &mSystemConfiguration
+                    );
+  }
+
+  //
+  // USB Device 29 configuration
+  //
+  DxePlatformPchPolicy->UsbConfig->Usb20Settings[0].Enable = mSystemConfiguration.PchUsb20;
+  DxePlatformPchPolicy->UsbConfig->UsbPerPortCtl           = mSystemConfiguration.PchUsbPerPortCtl;
+  if (mSystemConfiguration.PchUsbPerPortCtl != PCH_DEVICE_DISABLE) {
+    for (PortIndex = 0; PortIndex < PCH_USB_MAX_PHYSICAL_PORTS; PortIndex++) {
+      DxePlatformPchPolicy->UsbConfig->PortSettings[PortIndex].Enable = mSystemConfiguration.PchUsbPort[PortIndex];
+    }
+  }
+
+  DxePlatformPchPolicy->UsbConfig->EhciDebug               = mSystemConfiguration.PchEhciDebug;
+
+  //
+  // xHCI (USB 3.0) related settings from setup variable
+  //
+  DxePlatformPchPolicy->UsbConfig->Usb30Settings.XhciStreams    = mSystemConfiguration.PchUsb30Streams;
+
+  DxePlatformPchPolicy->UsbConfig->Usb30Settings.Mode           = mSystemConfiguration.PchUsb30Mode;
+
+  //
+  // Remove XHCI Pre-Boot Driver setup option selection from end-user view and automate loading of USB 3.0 BIOS driver based on XhciMode selection
+  //
+  switch (mSystemConfiguration.PchUsb30Mode) {
+    case 0: // Disabled
+      DxePlatformPchPolicy->UsbConfig->Usb30Settings.PreBootSupport = 0;
+      break;
+    case 1: // Enabled
+      DxePlatformPchPolicy->UsbConfig->Usb30Settings.PreBootSupport = 1;
+      break;
+    case 2: // Auto
+      DxePlatformPchPolicy->UsbConfig->Usb30Settings.PreBootSupport = 0;
+      break;
+    case 3: // Smart Auto
+      DxePlatformPchPolicy->UsbConfig->Usb30Settings.PreBootSupport = 1;
+      break;
+    default:
+      DxePlatformPchPolicy->UsbConfig->Usb30Settings.PreBootSupport = mSystemConfiguration.UsbXhciSupport;
+      break;
+  }
+
+
+
+  DxePlatformPchPolicy->UsbConfig->UsbOtgSettings.Enable  = mSystemConfiguration.PchUsbOtg;
+
+  DxePlatformPchPolicy->UsbConfig->PortSettings[0].Dock   = PCH_DEVICE_DISABLE;
+  DxePlatformPchPolicy->UsbConfig->PortSettings[1].Dock   = PCH_DEVICE_DISABLE;
+  DxePlatformPchPolicy->UsbConfig->PortSettings[2].Dock   = PCH_DEVICE_DISABLE;
+  DxePlatformPchPolicy->UsbConfig->PortSettings[3].Dock   = PCH_DEVICE_DISABLE;
+
+  DxePlatformPchPolicy->UsbConfig->PortSettings[0].Panel  = PCH_USB_FRONT_PANEL;
+  DxePlatformPchPolicy->UsbConfig->PortSettings[1].Panel  = PCH_USB_FRONT_PANEL;
+  DxePlatformPchPolicy->UsbConfig->PortSettings[2].Panel  = PCH_USB_BACK_PANEL;
+  DxePlatformPchPolicy->UsbConfig->PortSettings[3].Panel  = PCH_USB_BACK_PANEL;
+
+  //
+  //
+  // Enable USB Topology control and program the topology setting for every USB port
+  // See Platform Design Guide for description of topologies
+  //
+  //
+  // Port 0: ~5.3", Port 1: ~4.9", Port 2: ~4.7", Port 3: ~8.0"
+  //
+  DxePlatformPchPolicy->UsbConfig->Usb20PortLength[0]  = 0x53;
+  DxePlatformPchPolicy->UsbConfig->Usb20PortLength[1]  = 0x49;
+  DxePlatformPchPolicy->UsbConfig->Usb20PortLength[2]  = 0x47;
+  DxePlatformPchPolicy->UsbConfig->Usb20PortLength[3]  = 0x80;
+
+  DxePlatformPchPolicy->UsbConfig->Usb20OverCurrentPins[0]  = PchUsbOverCurrentPin0;
+  DxePlatformPchPolicy->UsbConfig->Usb20OverCurrentPins[1]  = PchUsbOverCurrentPin0;
+  DxePlatformPchPolicy->UsbConfig->Usb20OverCurrentPins[2]  = PchUsbOverCurrentPin1;
+  DxePlatformPchPolicy->UsbConfig->Usb20OverCurrentPins[3]  = PchUsbOverCurrentPin1;
+
+  DxePlatformPchPolicy->UsbConfig->Usb30OverCurrentPins[0]  = PchUsbOverCurrentPinSkip;//PchUsbOverCurrentPin0;
+
+  DxePlatformPchPolicy->EhciPllCfgEnable = mSystemConfiguration.EhciPllCfgEnable;
+  DEBUG ((EFI_D_INFO, "InitPchPlatformPolicy() DxePlatformPchPolicy->EhciPllCfgEnable = 0x%x \n",DxePlatformPchPolicy->EhciPllCfgEnable));
+    DxePlatformPchPolicy->PciExpressConfig->PcieDynamicGating                                 = mSystemConfiguration.PcieDynamicGating;
+  for (PortIndex = 0; PortIndex < PCH_PCIE_MAX_ROOT_PORTS; PortIndex++) {
+    DxePlatformPchPolicy->PciExpressConfig->RootPort[PortIndex].Enable                        = mSystemConfiguration.IchPciExp[PortIndex];
+    DxePlatformPchPolicy->PciExpressConfig->RootPort[PortIndex].SlotImplemented               = PCH_DEVICE_ENABLE;
+    DxePlatformPchPolicy->PciExpressConfig->RootPort[PortIndex].FunctionNumber                = PortIndex;
+    DxePlatformPchPolicy->PciExpressConfig->RootPort[PortIndex].PhysicalSlotNumber            = PortIndex;
+    DxePlatformPchPolicy->PciExpressConfig->RootPort[PortIndex].Aspm                          = 4;
+    DxePlatformPchPolicy->PciExpressConfig->RootPort[PortIndex].PmSci                         = PCH_DEVICE_DISABLE;
+    DxePlatformPchPolicy->PciExpressConfig->RootPort[PortIndex].ExtSync                       = PCH_DEVICE_DISABLE;
+    DxePlatformPchPolicy->PciExpressConfig->RootPort[PortIndex].HotPlug                       = PCH_DEVICE_DISABLE;
+    DxePlatformPchPolicy->PciExpressConfig->RootPort[PortIndex].AdvancedErrorReporting        = PCH_DEVICE_DISABLE;
+    DxePlatformPchPolicy->PciExpressConfig->RootPort[PortIndex].UnsupportedRequestReport      = PCH_DEVICE_DISABLE;
+    DxePlatformPchPolicy->PciExpressConfig->RootPort[PortIndex].FatalErrorReport              = PCH_DEVICE_DISABLE;
+    DxePlatformPchPolicy->PciExpressConfig->RootPort[PortIndex].NoFatalErrorReport            = PCH_DEVICE_DISABLE;
+    DxePlatformPchPolicy->PciExpressConfig->RootPort[PortIndex].CorrectableErrorReport        = PCH_DEVICE_DISABLE;
+    DxePlatformPchPolicy->PciExpressConfig->RootPort[PortIndex].PmeInterrupt                  = 0;
+    DxePlatformPchPolicy->PciExpressConfig->RootPort[PortIndex].SystemErrorOnFatalError       = PCH_DEVICE_DISABLE;
+    DxePlatformPchPolicy->PciExpressConfig->RootPort[PortIndex].SystemErrorOnNonFatalError    = PCH_DEVICE_DISABLE;
+    DxePlatformPchPolicy->PciExpressConfig->RootPort[PortIndex].SystemErrorOnCorrectableError = PCH_DEVICE_DISABLE;
+    DxePlatformPchPolicy->PciExpressConfig->RootPort[PortIndex].CompletionTimeout             = PchPciECompletionTO_Default;
+  }
+
+  //
+  // SATA configuration
+  //
+  for (PortIndex = 0; PortIndex < PCH_AHCI_MAX_PORTS; PortIndex++) {
+    if (mSystemConfiguration.SataType == 0) {
+      DxePlatformPchPolicy->SataConfig->PortSettings[PortIndex].Enable   = PCH_DEVICE_ENABLE;
+      DxePlatformPchPolicy->SataConfig->LegacyMode                       = PCH_DEVICE_ENABLE;
+    } else {
+      DxePlatformPchPolicy->SataConfig->PortSettings[PortIndex].Enable   = PCH_DEVICE_ENABLE;
+      DxePlatformPchPolicy->SataConfig->LegacyMode                       = PCH_DEVICE_DISABLE;
+    }
+    if(mSystemConfiguration.Sata == 1){
+      DxePlatformPchPolicy->SataConfig->PortSettings[PortIndex].Enable   = PCH_DEVICE_ENABLE;
+    } else {
+      DxePlatformPchPolicy->SataConfig->PortSettings[PortIndex].Enable   = PCH_DEVICE_DISABLE;
+    }
+    if(0 == PortIndex){
+      DxePlatformPchPolicy->SataConfig->PortSettings[PortIndex].HotPlug    = PCH_DEVICE_DISABLE;
+    } else if(1 == PortIndex){
+      DxePlatformPchPolicy->SataConfig->PortSettings[PortIndex].HotPlug    = PCH_DEVICE_DISABLE;
+    }
+
+    DxePlatformPchPolicy->SataConfig->PortSettings[PortIndex].SpinUp     = PCH_DEVICE_DISABLE;
+    DxePlatformPchPolicy->SataConfig->PortSettings[PortIndex].MechSw     = PCH_DEVICE_DISABLE;
+  }
+  DxePlatformPchPolicy->SataConfig->RaidAlternateId                 = PCH_DEVICE_DISABLE;
+  DxePlatformPchPolicy->SataConfig->Raid0                           = PCH_DEVICE_ENABLE;
+  DxePlatformPchPolicy->SataConfig->Raid1                           = PCH_DEVICE_ENABLE;
+  DxePlatformPchPolicy->SataConfig->Raid10                          = PCH_DEVICE_ENABLE;
+  DxePlatformPchPolicy->SataConfig->Raid5                           = PCH_DEVICE_ENABLE;
+  DxePlatformPchPolicy->SataConfig->Irrt                            = PCH_DEVICE_ENABLE;
+  DxePlatformPchPolicy->SataConfig->OromUiBanner                    = PCH_DEVICE_ENABLE;
+  DxePlatformPchPolicy->SataConfig->HddUnlock                       = PCH_DEVICE_ENABLE;
+  DxePlatformPchPolicy->SataConfig->LedLocate                       = PCH_DEVICE_ENABLE;
+  DxePlatformPchPolicy->SataConfig->IrrtOnly                        = PCH_DEVICE_ENABLE;
+  DxePlatformPchPolicy->SataConfig->SalpSupport                     = PCH_DEVICE_ENABLE;
+  DxePlatformPchPolicy->SataConfig->TestMode                        = mSystemConfiguration.SataTestMode;
+
+  //
+  // AzaliaConfig
+  //
+  DxePlatformPchPolicy->AzaliaConfig->Pme       = mSystemConfiguration.AzaliaPme;
+  DxePlatformPchPolicy->AzaliaConfig->HdmiCodec = mSystemConfiguration.HdmiCodec;
+  DxePlatformPchPolicy->AzaliaConfig->DS        = mSystemConfiguration.AzaliaDs;
+  DxePlatformPchPolicy->AzaliaConfig->AzaliaVCi = mSystemConfiguration.AzaliaVCiEnable;
+
+  //
+  // Set LPSS configuration according to setup value.
+  //
+  DxePlatformPchPolicy->LpssConfig->LpssPciModeEnabled   = mSystemConfiguration.LpssPciModeEnabled;
+
+  DxePlatformPchPolicy->LpssConfig->Dma1Enabled    = mSystemConfiguration.LpssDma1Enabled;
+  DxePlatformPchPolicy->LpssConfig->I2C0Enabled    = mSystemConfiguration.LpssI2C0Enabled;
+  DxePlatformPchPolicy->LpssConfig->I2C1Enabled    = mSystemConfiguration.LpssI2C1Enabled;
+  DxePlatformPchPolicy->LpssConfig->I2C2Enabled    = mSystemConfiguration.LpssI2C2Enabled;
+  DxePlatformPchPolicy->LpssConfig->I2C3Enabled    = mSystemConfiguration.LpssI2C3Enabled;
+  DxePlatformPchPolicy->LpssConfig->I2C4Enabled    = mSystemConfiguration.LpssI2C4Enabled;
+  DxePlatformPchPolicy->LpssConfig->I2C5Enabled    = mSystemConfiguration.LpssI2C5Enabled;
+  DxePlatformPchPolicy->LpssConfig->I2C6Enabled    = mSystemConfiguration.LpssI2C6Enabled;
+
+  DxePlatformPchPolicy->LpssConfig->Dma0Enabled    = mSystemConfiguration.LpssDma0Enabled;;
+  DxePlatformPchPolicy->LpssConfig->Pwm0Enabled    = mSystemConfiguration.LpssPwm0Enabled;
+  DxePlatformPchPolicy->LpssConfig->Pwm1Enabled    = mSystemConfiguration.LpssPwm1Enabled;
+  DxePlatformPchPolicy->LpssConfig->Hsuart0Enabled = mSystemConfiguration.LpssHsuart0Enabled;
+  DxePlatformPchPolicy->LpssConfig->Hsuart1Enabled = mSystemConfiguration.LpssHsuart1Enabled;
+  DxePlatformPchPolicy->LpssConfig->SpiEnabled     = mSystemConfiguration.LpssSpiEnabled;
+
+  //
+  // Set SCC configuration according to setup value.
+  //
+  DxePlatformPchPolicy->SccConfig->SdioEnabled   = mSystemConfiguration.LpssSdioEnabled;
+  DxePlatformPchPolicy->SccConfig->SdcardEnabled = TRUE;
+  DxePlatformPchPolicy->SccConfig->SdCardSDR25Enabled = mSystemConfiguration.LpssSdCardSDR25Enabled;
+  DxePlatformPchPolicy->SccConfig->SdCardDDR50Enabled = mSystemConfiguration.LpssSdCardDDR50Enabled;
+  DxePlatformPchPolicy->SccConfig->HsiEnabled    = mSystemConfiguration.LpssMipiHsi;
+
+  if (mSystemConfiguration.eMMCBootMode== 1) {// Auto detection mode
+  //
+  // Silicon Stepping
+  //
+  switch (PchStepping()) {
+    case PchA0: // A0 and A1
+    case PchA1:
+      DEBUG ((EFI_D_ERROR, "Auto Detect: SOC A0/A1: SCC eMMC 4.41 Configuration\n"));
+      DxePlatformPchPolicy->SccConfig->eMMCEnabled            = 1;
+      DxePlatformPchPolicy->SccConfig->eMMC45Enabled          = 0;
+      DxePlatformPchPolicy->SccConfig->eMMC45DDR50Enabled     = 0;
+      DxePlatformPchPolicy->SccConfig->eMMC45HS200Enabled     = 0;
+      DxePlatformPchPolicy->SccConfig->eMMC45RetuneTimerValue = 0;
+      break;
+    case PchB0: // B0 and later
+    default:
+      DEBUG ((EFI_D_ERROR, "Auto Detect: SOC B0 and later: SCC eMMC 4.5 Configuration\n"));
+      DxePlatformPchPolicy->SccConfig->eMMCEnabled            = 0;
+      DxePlatformPchPolicy->SccConfig->eMMC45Enabled          = mSystemConfiguration.LpsseMMC45Enabled;
+      DxePlatformPchPolicy->SccConfig->eMMC45DDR50Enabled     = mSystemConfiguration.LpsseMMC45DDR50Enabled;
+      DxePlatformPchPolicy->SccConfig->eMMC45HS200Enabled     = mSystemConfiguration.LpsseMMC45HS200Enabled;
+      DxePlatformPchPolicy->SccConfig->eMMC45RetuneTimerValue = mSystemConfiguration.LpsseMMC45RetuneTimerValue;
+      break;
+  }
+ } else if (mSystemConfiguration.eMMCBootMode == 2) { // eMMC 4.41
+    DEBUG ((EFI_D_ERROR, "Force to SCC eMMC 4.41 Configuration\n"));
+    DxePlatformPchPolicy->SccConfig->eMMCEnabled            = 1;
+    DxePlatformPchPolicy->SccConfig->eMMC45Enabled          = 0;
+    DxePlatformPchPolicy->SccConfig->eMMC45DDR50Enabled     = 0;
+    DxePlatformPchPolicy->SccConfig->eMMC45HS200Enabled     = 0;
+    DxePlatformPchPolicy->SccConfig->eMMC45RetuneTimerValue = 0;
+
+ } else if (mSystemConfiguration.eMMCBootMode == 3) { // eMMC 4.5
+      DEBUG ((EFI_D_ERROR, "Force to eMMC 4.5 Configuration\n"));
+      DxePlatformPchPolicy->SccConfig->eMMCEnabled            = 0;
+      DxePlatformPchPolicy->SccConfig->eMMC45Enabled          = mSystemConfiguration.LpsseMMC45Enabled;
+      DxePlatformPchPolicy->SccConfig->eMMC45DDR50Enabled     = mSystemConfiguration.LpsseMMC45DDR50Enabled;
+      DxePlatformPchPolicy->SccConfig->eMMC45HS200Enabled     = mSystemConfiguration.LpsseMMC45HS200Enabled;
+      DxePlatformPchPolicy->SccConfig->eMMC45RetuneTimerValue = mSystemConfiguration.LpsseMMC45RetuneTimerValue;
+
+ } else { // Disable eMMC controllers
+      DEBUG ((EFI_D_ERROR, "Disable eMMC controllers\n"));
+      DxePlatformPchPolicy->SccConfig->eMMCEnabled            = 0;
+      DxePlatformPchPolicy->SccConfig->eMMC45Enabled          = 0;
+      DxePlatformPchPolicy->SccConfig->eMMC45DDR50Enabled     = 0;
+      DxePlatformPchPolicy->SccConfig->eMMC45HS200Enabled     = 0;
+      DxePlatformPchPolicy->SccConfig->eMMC45RetuneTimerValue = 0;
+ }
+
+  //
+  // Reserved SMBus Address
+  //
+  DxePlatformPchPolicy->SmbusConfig->NumRsvdSmbusAddresses  = 4;
+  DxePlatformPchPolicy->SmbusConfig->RsvdSmbusAddressTable  = mSmbusRsvdAddresses;
+
+  //
+  // MiscPm Configuration
+  //
+  DxePlatformPchPolicy->MiscPmConfig->WakeConfig.WolEnableOverride        = mSystemConfiguration.WakeOnLanS5;
+  DxePlatformPchPolicy->MiscPmConfig->SlpLanLowDc                         = mSystemConfiguration.SlpLanLowDc;
+  DxePlatformPchPolicy->MiscPmConfig->PowerResetStatusClear.MeWakeSts     = PCH_DEVICE_ENABLE;
+  DxePlatformPchPolicy->MiscPmConfig->PowerResetStatusClear.MeHrstColdSts = PCH_DEVICE_ENABLE;
+  DxePlatformPchPolicy->MiscPmConfig->PowerResetStatusClear.MeHrstWarmSts = PCH_DEVICE_ENABLE;
+
+  //
+  // Enable / disable serial IRQ according to setup value.
+  //
+  DxePlatformPchPolicy->SerialIrqConfig->SirqEnable = PCH_DEVICE_ENABLE;
+
+  //
+  // Set Serial IRQ Mode Select according to setup value.
+  //
+  DxePlatformPchPolicy->SerialIrqConfig->SirqMode = PchQuietMode;
+
+  //
+  // Program the default Sub System Vendor Device Id
+  //
+  DxePlatformPchPolicy->DefaultSvidSid->SubSystemVendorId = V_PCH_INTEL_VENDOR_ID;
+  DxePlatformPchPolicy->DefaultSvidSid->SubSystemId       = V_PCH_DEFAULT_SID;
+
+  mAzaliaVerbTable[9].VerbTableData = mAzaliaVerbTableData12;
+
+  DxePlatformPchPolicy->AzaliaConfig->AzaliaVerbTableNum  = sizeof (mAzaliaVerbTable) / sizeof (PCH_AZALIA_VERB_TABLE);
+  DxePlatformPchPolicy->AzaliaConfig->AzaliaVerbTable     = mAzaliaVerbTable;
+  DxePlatformPchPolicy->AzaliaConfig->ResetWaitTimer      = 300;
+
+  DxePlatformPchPolicy->IdleReserve = mSystemConfiguration.IdleReserve;
+  DxePlatformPchPolicy->AcpiHWRed = PCH_DEVICE_DISABLE;
+
+  //
+  // Install DxePchPolicyUpdateProtocol
+  //
+  Handle                        = NULL;
+
+  mDxePchPolicyUpdate.Revision  = DXE_PCH_POLICY_UPDATE_PROTOCOL_REVISION_1;
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Handle,
+                  &gDxePchPolicyUpdateProtocolGuid,
+                  &mDxePchPolicyUpdate,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((EFI_D_INFO, "InitPchPlatformPolicy() - End\n"));
+}
+
+
+DXE_VLV_PLATFORM_POLICY_PROTOCOL mDxePlatformVlvPolicy;
+
+VOID
+InitVlvPlatformPolicy (
+  )
+{
+  DXE_VLV_PLATFORM_POLICY_PROTOCOL *DxePlatformVlvPolicy;
+  EFI_STATUS                      Status;
+  EFI_HANDLE                      Handle;
+
+  ZeroMem (&mDxePlatformVlvPolicy, sizeof(DXE_VLV_PLATFORM_POLICY_PROTOCOL));
+
+  DxePlatformVlvPolicy = &mDxePlatformVlvPolicy;
+
+
+  DxePlatformVlvPolicy->GraphicReserve00 = mSystemConfiguration.GraphicReserve00;
+  DxePlatformVlvPolicy->PavpMode = mSystemConfiguration.PavpMode;
+  DxePlatformVlvPolicy->GraphicReserve01 = 1;
+  DxePlatformVlvPolicy->GraphicReserve02 = mSystemConfiguration.GraphicReserve02;
+  DxePlatformVlvPolicy->GraphicReserve03 = 1;
+  DxePlatformVlvPolicy->GraphicReserve04 = 0;
+  DxePlatformVlvPolicy->GraphicReserve05 = mSystemConfiguration.GraphicReserve05;
+  DxePlatformVlvPolicy->IgdPanelFeatures.PFITStatus = mSystemConfiguration.PanelScaling;
+  
+  DxePlatformVlvPolicy->IgdPanelFeatures.LidStatus = 1;
+  DxePlatformVlvPolicy->IdleReserve = mSystemConfiguration.IdleReserve;
+
+  DxePlatformVlvPolicy->GraphicReserve06 = 1;
+
+  if ( (mSystemConfiguration.Lpe == 1) || mSystemConfiguration.Lpe == 2) {
+    DxePlatformVlvPolicy ->AudioTypeSupport = LPE_AUDIO ;
+  } else if ( mSystemConfiguration.PchAzalia == 1 ) {
+    DxePlatformVlvPolicy ->AudioTypeSupport = HD_AUDIO;
+  } else {
+    DxePlatformVlvPolicy ->AudioTypeSupport = NO_AUDIO;
+  }
+
+  Handle = NULL;
+  Status = gBS->InstallProtocolInterface (
+                  &Handle,
+                  &gDxeVlvPlatformPolicyGuid,
+                  EFI_NATIVE_INTERFACE,
+                  DxePlatformVlvPolicy
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchRegTable.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchRegTable.c
new file mode 100644
index 0000000000..cac61bffd0
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchRegTable.c
@@ -0,0 +1,134 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+  IchRegTable.c
+
+Abstract:
+
+  Register initialization table for Ich.
+
+
+
+--*/
+
+#include <Library/EfiRegTableLib.h>
+#include "PlatformDxe.h"
+extern EFI_PLATFORM_INFO_HOB      mPlatformInfo;
+
+#define R_EFI_PCI_SVID 0x2C
+
+EFI_REG_TABLE mSubsystemIdRegs [] = {
+
+  //
+  // Program SVID and SID for PCI devices.
+  // Combine two 16 bit PCI_WRITE into one 32 bit PCI_WRITE in order to boost performance
+  //
+  PCI_WRITE (
+      MC_BUS, MC_DEV, MC_FUN, R_EFI_PCI_SVID, EfiPciWidthUint32,
+      V_PCH_DEFAULT_SVID_SID, OPCODE_FLAG_S3SAVE
+    ),
+
+  PCI_WRITE (
+      IGD_BUS, IGD_DEV, IGD_FUN_0, R_EFI_PCI_SVID, EfiPciWidthUint32,
+      V_PCH_DEFAULT_SVID_SID, OPCODE_FLAG_S3SAVE
+    ),
+
+  PCI_WRITE(
+      DEFAULT_PCI_BUS_NUMBER_PCH, 0, 0, R_EFI_PCI_SVID, EfiPciWidthUint32,
+      V_PCH_DEFAULT_SVID_SID, OPCODE_FLAG_S3SAVE
+    ),
+  PCI_WRITE (
+      DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC, R_PCH_LPC_SS, EfiPciWidthUint32,
+      V_PCH_DEFAULT_SVID_SID, OPCODE_FLAG_S3SAVE
+    ),
+  PCI_WRITE (
+      DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SATA, PCI_FUNCTION_NUMBER_PCH_SATA, R_PCH_SATA_SS, EfiPciWidthUint32,
+      V_PCH_DEFAULT_SVID_SID, OPCODE_FLAG_S3SAVE
+    ),
+  PCI_WRITE (
+      DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SMBUS, PCI_FUNCTION_NUMBER_PCH_SMBUS, R_PCH_SMBUS_SVID, EfiPciWidthUint32,
+      V_PCH_DEFAULT_SVID_SID, OPCODE_FLAG_S3SAVE
+    ),
+  PCI_WRITE (
+      DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_USB, PCI_FUNCTION_NUMBER_PCH_EHCI, R_PCH_EHCI_SVID, EfiPciWidthUint32,
+      V_PCH_DEFAULT_SVID_SID, OPCODE_FLAG_S3SAVE
+    ),
+  PCI_WRITE (
+      DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1, R_PCH_PCIE_SVID, EfiPciWidthUint32,
+      V_PCH_DEFAULT_SVID_SID, OPCODE_FLAG_S3SAVE
+    ),
+  PCI_WRITE (
+      DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2, R_PCH_PCIE_SVID, EfiPciWidthUint32,
+      V_PCH_DEFAULT_SVID_SID, OPCODE_FLAG_S3SAVE
+    ),
+  PCI_WRITE (
+      DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3, R_PCH_PCIE_SVID, EfiPciWidthUint32,
+      V_PCH_DEFAULT_SVID_SID, OPCODE_FLAG_S3SAVE
+    ),
+  PCI_WRITE (
+      DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4, R_PCH_PCIE_SVID, EfiPciWidthUint32,
+      V_PCH_DEFAULT_SVID_SID, OPCODE_FLAG_S3SAVE
+    ),
+  TERMINATE_TABLE
+};
+
+/**
+  Updates the mSubsystemIdRegs table, and processes it.  This should program
+  the Subsystem Vendor and Device IDs.
+
+  @retval Returns  VOID
+
+**/
+VOID
+InitializeSubsystemIds (
+  )
+{
+
+  EFI_REG_TABLE *RegTablePtr;
+  UINT32 SubsystemVidDid;
+
+  SubsystemVidDid = mPlatformInfo.SsidSvid;
+
+  RegTablePtr = mSubsystemIdRegs;
+
+  //
+  // While we are not at the end of the table
+  //
+  while (RegTablePtr->Generic.OpCode != OP_TERMINATE_TABLE) {
+  	//
+    // If the data to write is the original SSID
+    //
+    if (RegTablePtr->PciWrite.Data ==
+          ((V_PCH_DEFAULT_SID << 16) |
+           V_PCH_INTEL_VENDOR_ID)
+       ) {
+
+    	//
+      // Then overwrite it to use the alternate SSID
+      //
+      RegTablePtr->PciWrite.Data = SubsystemVidDid;
+    }
+
+    //
+    // Go to next table entry
+    //
+    RegTablePtr++;
+    }
+
+  RegTablePtr = mSubsystemIdRegs;
+
+
+  //
+  // Program the SSVID/SSDID
+  //
+  ProcessRegTablePci (mSubsystemIdRegs, mPciRootBridgeIo, NULL);
+
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchTcoReset.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchTcoReset.c
new file mode 100644
index 0000000000..5b7822deda
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchTcoReset.c
@@ -0,0 +1,211 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+  IchTcoReset.c
+
+Abstract:
+  Implements the programming of events in TCO Reset
+
+
+--*/
+
+#include "PlatformDxe.h"
+#include <Protocol/TcoReset.h>
+#include <Protocol/HwWatchdogTimer.h>
+
+
+EFI_STATUS
+EFIAPI
+EnableTcoReset (
+  IN      UINT32            *RcrbGcsSaveValue
+  );
+  
+EFI_STATUS
+EFIAPI
+DisableTcoReset (
+  OUT     UINT32    RcrbGcsRestoreValue
+  );
+
+EFI_TCO_RESET_PROTOCOL  mTcoResetProtocol = {
+  EnableTcoReset,
+  DisableTcoReset
+};
+
+/**
+
+  Enables the TCO timer to reset the system in case of a system hang.  This is
+  used when writing the clock registers.
+
+  @param RcrbGcsSaveValue   This is the value of the RCRB GCS register before it is
+                            changed by this procedure.  This will be used to restore
+                            the settings of this register in PpiDisableTcoReset.
+
+  @retval  EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+EnableTcoReset (
+  IN      UINT32            *RcrbGcsSaveValue
+  )
+{
+  UINT16          TmpWord;
+  UINT16          AcpiBase;
+  EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL  *WatchdogTimerProtocol;
+  EFI_STATUS          Status;
+  UINTN           PbtnDisableInterval = 4;  //Default value
+
+  //
+  // Get Watchdog Timer protocol.
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiWatchdogTimerDriverProtocolGuid,
+                  NULL,
+                  (VOID **)&WatchdogTimerProtocol
+                  );
+
+  //
+  // If the protocol is present, shut off the Timer as we enter BDS
+  //
+  if (!EFI_ERROR(Status)) {
+    WatchdogTimerProtocol->RestartWatchdogTimer();
+    WatchdogTimerProtocol->AllowKnownReset(TRUE);
+  }
+
+  if (*RcrbGcsSaveValue == 0) {
+    PbtnDisableInterval = PcdGet32(PcdPBTNDisableInterval);
+  } else {
+    PbtnDisableInterval = *RcrbGcsSaveValue * 10 / 6;
+  }
+
+  //
+  // Read ACPI Base Address
+  //
+  AcpiBase = PchLpcPciCfg16(R_PCH_LPC_ACPI_BASE) & B_PCH_LPC_ACPI_BASE_BAR;
+
+  //
+  // Stop TCO if not already stopped
+  //
+  TmpWord = IoRead16(AcpiBase + R_PCH_TCO_CNT);
+  TmpWord |= B_PCH_TCO_CNT_TMR_HLT;
+  IoWrite16(AcpiBase + R_PCH_TCO_CNT, TmpWord);
+
+  //
+  // Clear second TCO status
+  //
+  IoWrite32(AcpiBase + R_PCH_TCO_STS, B_PCH_TCO_STS_SECOND_TO);
+
+  //
+  // Enable reboot on TCO timeout
+  //
+  *RcrbGcsSaveValue = MmioRead32 (PMC_BASE_ADDRESS + R_PCH_PMC_PM_CFG);
+  MmioAnd8 (PMC_BASE_ADDRESS + R_PCH_PMC_PM_CFG, (UINT8) ~B_PCH_PMC_PM_CFG_NO_REBOOT);
+
+  //
+  // Set TCO reload value (interval *.6s)
+  //
+  IoWrite32(AcpiBase + R_PCH_TCO_TMR, (UINT32)(PbtnDisableInterval<<16));
+
+  //
+  // Force TCO to load new value
+  //
+  IoWrite8(AcpiBase + R_PCH_TCO_RLD, 4);
+
+  //
+  // Clear second TCO status
+  //
+  IoWrite32(AcpiBase + R_PCH_TCO_STS, B_PCH_TCO_STS_SECOND_TO);
+
+  //
+  // Start TCO timer running
+  //
+  TmpWord = IoRead16(AcpiBase + R_PCH_TCO_CNT);
+  TmpWord &= ~(B_PCH_TCO_CNT_TMR_HLT);
+  IoWrite16(AcpiBase + R_PCH_TCO_CNT, TmpWord);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Disables the TCO timer.  This is used after writing the clock registers.
+
+  @param RcrbGcsRestoreValue   Value saved in PpiEnableTcoReset so that it can
+                               restored.
+
+  @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+DisableTcoReset (
+  OUT     UINT32    RcrbGcsRestoreValue
+  )
+{
+  UINT16          TmpWord;
+  UINT16          AcpiBase;
+  EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL  *WatchdogTimerProtocol;
+  EFI_STATUS          Status;
+
+  //
+  // Read ACPI Base Address
+  //
+  AcpiBase = PchLpcPciCfg16(R_PCH_LPC_ACPI_BASE) & B_PCH_LPC_ACPI_BASE_BAR;
+
+  //
+  // Stop the TCO timer
+  //
+  TmpWord = IoRead16(AcpiBase + R_PCH_TCO_CNT);
+  TmpWord |= B_PCH_TCO_CNT_TMR_HLT;
+  IoWrite16(AcpiBase + R_PCH_TCO_CNT, TmpWord);
+
+  //
+  // Get Watchdog Timer protocol.
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiWatchdogTimerDriverProtocolGuid,
+                  NULL,
+                  (VOID **)&WatchdogTimerProtocol
+                  );
+
+  //
+  // If the protocol is present, shut off the Timer as we enter BDS
+  //
+  if (!EFI_ERROR(Status)) {
+    WatchdogTimerProtocol->AllowKnownReset(FALSE);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Updates the feature policies according to the setup variable.
+
+  @retval Returns   VOID
+
+**/
+VOID
+InitTcoReset (
+  )
+{
+  EFI_HANDLE                        Handle;
+  EFI_STATUS                        Status;
+
+  Handle = NULL;
+  Status = gBS->InstallProtocolInterface (
+                  &Handle,
+                  &gEfiTcoResetProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &mTcoResetProtocol
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c
new file mode 100644
index 0000000000..3b3e4b4c82
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c
@@ -0,0 +1,72 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+  IdccInfo.c
+
+Abstract:
+
+  Platform information used by IDCC.
+
+Revision History
+
+--*/
+
+#include "PlatformDxe.h"
+
+#include <Guid/IdccData.h>
+
+extern EFI_GUID mPlatformDriverGuid;
+
+
+EFI_STATUS
+WriteIdccInfo (
+  )
+{
+  EFI_STATUS                Status;
+  EFI_DATA_HUB_PROTOCOL     *DataHub;
+  UINT8                     Ratio;
+  EFI_IDCC_PROCESSOR_RATIO  ProcRatio;
+
+  //
+  // Locate the data hub protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiDataHubProtocolGuid,
+                  NULL,
+                  (VOID **) &DataHub
+                  );
+
+  //
+  // Find processor actual ratio
+  //
+  Ratio = 15; //Temporary - some dummy value.
+
+  //
+  // Fill in IDCC Type 5 structure
+  //
+  ProcRatio.IdccHeader.Type = EFI_IDCC_PROC_RATIO_TYPE;
+  ProcRatio.IdccHeader.RecordLength = sizeof(EFI_IDCC_PROCESSOR_RATIO);
+  ProcRatio.ProcessorRatio = Ratio;
+
+  //
+  // Write data to the data hub
+  //
+  Status = DataHub->LogData (
+                      DataHub,
+                      &gIdccDataHubGuid,
+                      &mPlatformDriverGuid,
+                      EFI_DATA_RECORD_CLASS_DATA,
+                      &ProcRatio,
+                      sizeof(EFI_IDCC_PROCESSOR_RATIO)
+                      );
+
+  return Status;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.c
new file mode 100644
index 0000000000..09e7fe3113
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.c
@@ -0,0 +1,161 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+ LegacySpeaker.c
+
+Abstract:
+
+  This file implements DXE for Legacy Speaker.
+
+--*/
+
+#include "LegacySpeaker.h"
+
+/**
+
+  This function will enable the speaker to generate beep
+
+  @retval EFI_STATUS
+
+**/
+EFI_STATUS
+TurnOnSpeaker (
+  )
+{
+  UINT8                   Data;
+  Data = IoRead8 (EFI_SPEAKER_CONTROL_PORT);
+  Data |= 0x03;
+  IoWrite8(EFI_SPEAKER_CONTROL_PORT, Data);
+  return EFI_SUCCESS;
+}
+
+/**
+
+  This function will stop beep from speaker.
+
+  @retval Status
+
+**/
+EFI_STATUS
+TurnOffSpeaker (
+  )
+{
+  UINT8                   Data;
+
+  Data = IoRead8 (EFI_SPEAKER_CONTROL_PORT);
+  Data &= 0xFC;
+  IoWrite8(EFI_SPEAKER_CONTROL_PORT, Data);
+  return EFI_SUCCESS;
+}
+
+/**
+  Generate beep sound based upon number of beeps and duration of the beep
+
+  @param NumberOfBeeps     Number of beeps which user want to produce
+  @param BeepDuration      Duration for speaker gate need to be enabled
+  @param TimeInterval      Interval between each beep
+
+  @retval      Does not return if the reset takes place.
+               EFI_INVALID_PARAMETER   If ResetType is invalid.
+
+**/
+EFI_STATUS
+OutputBeep (
+  IN     UINTN                              NumberOfBeep,
+  IN     UINTN                              BeepDuration,
+  IN     UINTN                              TimeInterval
+  )
+{
+  UINTN           Num;
+
+  for (Num=0; Num < NumberOfBeep; Num++) {
+    TurnOnSpeaker ();
+    //
+    // wait some time,at least 120us
+    //
+    gBS->Stall (BeepDuration);
+    TurnOffSpeaker();
+    gBS->Stall (TimeInterval);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function will program the speaker tone frequency. The value should be with 64k
+  boundary since it takes only 16 bit value which gets programmed in two step IO opearattion
+
+  @param  Frequency     A value which should be 16 bit only.
+
+  @retval EFI_SUCESS
+
+**/
+EFI_STATUS
+EFIAPI    
+ProgramToneFrequency (
+  IN EFI_SPEAKER_IF_PROTOCOL            * This,
+  IN  UINT16                            Frequency
+  )
+{
+  UINT8                   Data;
+
+  Data = 0xB6;
+  IoWrite8(EFI_TIMER_CONTROL_PORT, Data);
+
+  Data = (UINT8)(Frequency & 0x00FF);
+  IoWrite8(EFI_TIMER_2_PORT, Data);
+  Data = (UINT8)((Frequency & 0xFF00) >> 8);
+  IoWrite8(EFI_TIMER_2_PORT, Data);
+  return EFI_SUCCESS;
+}
+
+/**
+  This function will generate the beep for specified duration.
+
+  @param NumberOfBeeps     Number of beeps which user want to produce
+  @param BeepDuration      Duration for speaker gate need to be enabled
+  @param TimeInterval      Interval between each beep
+
+  @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+GenerateBeepTone (
+  IN EFI_SPEAKER_IF_PROTOCOL            * This,
+  IN  UINTN                             NumberOfBeeps,
+  IN  UINTN                             BeepDuration,
+  IN  UINTN                             TimeInterval
+  )
+{
+
+  if ((NumberOfBeeps == 1) && (BeepDuration == 0) && (TimeInterval == 0)) {
+    TurnOnSpeaker ();
+    return EFI_SUCCESS;
+  }
+
+  if ((NumberOfBeeps == 0) && (BeepDuration == 0) && (TimeInterval == 0)) {
+    TurnOffSpeaker ();
+    return EFI_SUCCESS;
+  }
+
+  if (BeepDuration == 0) {
+    BeepDuration = EFI_DEFAULT_SHORT_BEEP_DURATION;
+  }
+
+  if (TimeInterval == 0) {
+    TimeInterval = EFI_DEFAULT_BEEP_TIME_INTERVAL;
+  }
+
+  OutputBeep (NumberOfBeeps, BeepDuration, TimeInterval);
+  return EFI_SUCCESS;
+
+
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.h b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.h
new file mode 100644
index 0000000000..0ab39b78fa
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.h
@@ -0,0 +1,69 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+ LegacySpeaker.h
+
+Abstract:
+
+  Speaker enabling related data
+
+--*/
+
+#ifndef _DXE_LEGACY_SPEAKER_H
+#define _DXE_LEGACY_SPEAKER_H
+
+#include "PlatformDxe.h"
+
+//
+// Speaker Related Port Information
+//
+#define EFI_TIMER_COUNTER_PORT            0x40
+#define EFI_TIMER_CONTROL_PORT            0x43
+#define EFI_TIMER_2_PORT                  0x42
+#define EFI_SPEAKER_CONTROL_PORT          0x61
+
+#define EFI_SPEAKER_OFF_MASK              0xFC
+
+#define EFI_DEFAULT_BEEP_FREQUENCY        0x500
+
+//
+// Default Intervals/Beep Duration
+//
+#define EFI_DEFAULT_LONG_BEEP_DURATION    0x70000
+#define EFI_DEFAULT_SHORT_BEEP_DURATION   0x50000
+#define EFI_DEFAULT_BEEP_TIME_INTERVAL    0x20000
+
+
+EFI_STATUS
+EFIAPI
+ProgramToneFrequency (
+  IN  EFI_SPEAKER_IF_PROTOCOL           * This,
+  IN  UINT16                            Frequency
+  );
+
+
+EFI_STATUS
+EFIAPI
+GenerateBeepTone (
+  IN  EFI_SPEAKER_IF_PROTOCOL           * This,
+  IN  UINTN                             NumberOfBeeps,
+  IN  UINTN                             BeepDuration,
+  IN  UINTN                             TimeInterval
+  );
+
+EFI_STATUS
+TurnOnSpeaker (
+  );
+
+EFI_STATUS
+TurnOffSpeaker (
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.c
new file mode 100644
index 0000000000..af466ce96d
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.c
@@ -0,0 +1,582 @@
+/*++
+  This file contains 'Framework Code' and is licensed as such
+  under the terms of your license agreement with Intel or your
+  vendor.  This file may not be modified, except as allowed by
+  additional terms of your license agreement.
+--*/
+/*++
+
+Copyright (c)  2010  - 2014, Intel Corporation. All rights reserved
+                                                                                   

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

+
+
+Module Name:
+
+  Observable.c
+
+Abstract:
+
+  The following contains all of the implementation for the Observable protocol. The
+  protocol uses the observer design pattern to provide a way to publish events and
+  to subscribe to those events so that a callback will be performed at the time of
+  the event. The observables and subscribers are maintained by the static tree,
+  mObservableDb. The difference between this protocol and the existing event protocol
+  that exists within the EFI framework is that this protocol allows for parameters
+  to be passed to the subscribed callbacks that can contain up to date context.
+
+--*/
+
+#include "Observable.h"
+
+static OBS_TREE*                mObservableDb = NULL;
+static EFI_HANDLE               mObservableHandle = NULL;
+static OBS_OBSERVABLE_PROTOCOL  mObservable = {
+  AddObservable,
+  RemoveObservable,
+  Subscribe,
+  Unsubscribe,
+  Publish,
+  RemoveAllObservables
+};
+
+/** Install observable protocol.
+ *
+ * Install interface and initialize the observable protocol.
+ *
+ * @param   VOID          No parameters.
+ *
+ * @return  EFI_SUCCESS   Successfully installed and initialized the protocol.
+ **/
+EFI_STATUS
+InitializeObservableProtocol(
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // Install protocol.
+  //
+  Status = gBS->InstallProtocolInterface (
+                  &mObservableHandle,
+                  &gObservableProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &mObservable
+                  );
+
+  return Status;
+}
+
+/** Deletes a subscriber
+ *
+ * This function removes the subscriber pointed to by Head.
+ *
+ * @param   OBS_TREE*     Head    Points to the current subscriber.
+ *
+ * @return  OBS_TREE*     Returns the tree after successfully removing the subscriber.
+ **/
+OBS_LEAF*
+DeleteSubscriber(
+  OBS_LEAF* Head
+  )
+{
+  OBS_LEAF* Temp;
+
+  if (Head) {
+    Temp = Head;
+    Head = Head->Next;
+    gBS->FreePool(Temp);
+  }
+
+  return Head;
+}
+
+/** Finds and deletes all subscribers
+ *
+ * This function iterates recursively through the existing subscribers and delets them all.
+ *
+ * @param   OBS_TREE*     Head    Points to the current subscriber.
+ *
+ * @return  OBS_TREE*     Returns the tree after successfully removing the subscribers.
+ **/
+OBS_LEAF*
+DeleteAllSubscribers(
+  OBS_LEAF* Head
+  )
+{
+  if (Head) {
+    if (Head->Next) {
+      //
+      // We aren't at the end of the list yet.
+      //
+      Head->Next = DeleteAllSubscribers(Head->Next);
+    }
+
+    //
+    // At the end, so delete the subscriber.
+    //
+    Head = DeleteSubscriber(Head);
+  }
+
+  return Head;
+}
+
+/** Deletes an observable
+ *
+ * This function removes the observable pointed to by Head.
+ *
+ * @param   OBS_TREE*     Head    Points to the current observable.
+ *
+ * @return  OBS_TREE*     Returns the tree after successfully removing the observable.
+ **/
+OBS_TREE*
+DeleteObservable(
+  OBS_TREE* Head
+  )
+{
+  OBS_TREE* Temp;
+
+  if (Head) {
+    Temp = Head;
+    Head = Head->Next;
+    gBS->FreePool(Temp);
+  }
+
+  return Head;
+}
+
+/** Finds and deletes all observables
+ *
+ * This function iterates recursively through the existing observables database and, starting with
+ * the last most observable, deletes all of its subscribers, then deletes the observable itself.
+ *
+ * @param   OBS_TREE*     Head    Points to the current observable.
+ *
+ * @return  OBS_TREE*     Returns the tree after successfully removing the observables.
+ **/
+OBS_TREE*
+DeleteAllObservables(
+  OBS_TREE* Head
+  )
+{
+  if (Head) {
+    if (Head->Next) {
+      //
+      // We aren't at the end of the list yet.
+      //
+      Head->Next = DeleteAllObservables(Head->Next);
+    }
+
+    //
+    // This is the end of the list of observables.
+    //
+    Head->Leaf = DeleteAllSubscribers(Head->Leaf);
+
+    //
+    // Subscribers are deleted, so now delete the observable.
+    //
+    Head = DeleteObservable(Head);
+  }
+
+  return Head;
+}
+
+/** Finds and deletes observable
+ *
+ * This function iterates recursively through the existing observable database in order to find the one
+ * specified by ReferenceGuid so that it can be deleted. If the requested observable is found, before it
+ * is deleted, all of the subscribers that are listening to this observable are deleted.
+ *
+ * @param   OBS_TREE*     Head              Points to the current observable.
+ *          EFI_GUID      ReferenceGuid     Corresponds to the observable that we're looking for.
+ *
+ * @return  OBS_TREE*     Returns the tree after successfully removing (or not finding) the observable.
+ **/
+OBS_TREE*
+FindAndDeleteObservable(
+  OBS_TREE* Head,
+  EFI_GUID  ReferenceGuid
+  )
+{
+  if (Head) {
+    if (CompareMem(&(Head->ObservableGuid), &ReferenceGuid, sizeof(ReferenceGuid)) == 0) {
+      //
+      // We found the observable. Delete all of it's subscribers, first.
+      //
+      Head->Leaf = DeleteAllSubscribers(Head->Leaf);
+      //
+      // Now we can safely remove the observable.
+      //
+      Head = DeleteObservable(Head);
+    } else {
+      //
+      // Not found. Keep searching.
+      //
+      Head->Next = FindAndDeleteObservable(Head->Next, ReferenceGuid);
+    }
+  }
+
+  return Head;
+}
+
+/** Finds and deletes subscriber
+ *
+ * This function iterates recursively through the existing subscribers that are listening to the
+ * observable that was found when this function was called.
+ *
+ * @param   OBS_TREE*     Head              Points to the current subscriber.
+ *          OBS_CALLBACK  CallbackInterface This is the subscriber that is requested be removed.
+ *
+ * @return  OBS_TREE*     Returns the tree after successfully removing (or not finding) the subscriber.
+ **/
+OBS_LEAF*
+_FindAndDeleteSubscriber(
+  OBS_LEAF*     Head,
+  OBS_CALLBACK  CallbackInterface
+  )
+{
+  if (Head) {
+    if (Head->Observer == CallbackInterface) {
+      //
+      // Found it. Now let's delete it.
+      //
+      Head = DeleteSubscriber(Head);
+    } else {
+      //
+      // Not found. Keep searching.
+      //
+      Head->Next = _FindAndDeleteSubscriber(Head->Next, CallbackInterface);
+    }
+  }
+
+  return Head;
+}
+
+/** Finds and deletes subscriber
+ *
+ * This function iterates recursively through the existing observables database until it either finds
+ * a matching guid or reaches the end of the list. After finding a match, it calls a helper function,
+ * _FindAndDeleteSubscriber. At this point, all responsibility for finding and deleting the subscriber
+ * lies on the helper function.
+ *
+ * @param   OBS_TREE*     Head              Points to the current observable.
+ *          EFI_GUID      ReferenceGuid     Corresponds to the observable that we're looking for.
+ *          OBS_CALLBACK  CallbackInterface This is the subscriber that is requested be removed.
+ *
+ * @return  OBS_TREE*     Returns the tree after successfully removing (or not finding) the subscriber.
+ **/
+OBS_TREE*
+FindAndDeleteSubscriber(
+  IN  OUT OBS_TREE*     Head,
+  IN      EFI_GUID      ReferenceGuid,
+  IN      OBS_CALLBACK  CallbackInterface
+  )
+{
+  if (Head) {
+    if (CompareMem(&(Head->ObservableGuid), &ReferenceGuid, sizeof(ReferenceGuid)) == 0) {
+      //
+      // We found the observer that matches ReferenceGuid. Find and delete the subscriber that is
+      // listening to it.
+      //
+      Head->Leaf = _FindAndDeleteSubscriber(Head->Leaf, CallbackInterface);
+    } else {
+      //
+      // Not found. Keep searching.
+      //
+      Head->Next = FindAndDeleteSubscriber(Head->Next, ReferenceGuid, CallbackInterface);
+    }
+  }
+
+  return Head;
+}
+
+/** Remove all observables.
+ *
+ * Remove all observable guids and all interfaces subscribed to them.
+ *
+ * @param   VOID          No parameters.
+ *
+ * @return  EFI_SUCCESS   Successfully removed all observables and subscribed interfaces.
+ **/
+EFI_STATUS
+EFIAPI
+RemoveAllObservables(
+  VOID
+  )
+{
+  mObservableDb = DeleteAllObservables(mObservableDb);
+
+  return EFI_SUCCESS;
+}
+
+/** Subscribe an interface with an observable guid.
+ *
+ * Use this to register a callback function with a guid. The function provided by CallbackInterface will be executed
+ * whenever the appropriate observable instance specified by ReferenceGuid calls Publish.
+ *
+ * @param   EFI_GUID              ReferenceGuid       The observable guid that the callback interface will subscribe to.
+ *          OBS_CASLLBACK         CallbackInterface   A pointer to the function that is subscribing to the observable.
+ *
+ * @return  EFI_SUCCESS           Successfully subscribed the interface to the observable guid.
+ *          EFI_NOT_FOUND         No match could be found between the provided guid and existing observables.
+ *          EFI_OUT_OF_RESOURCES  Could not subscribe to this observer due to resource limitations.
+ *          EFI_INVALID_PARAMETER Interface is already subscribed to this observer.
+ **/
+EFI_STATUS
+EFIAPI
+Subscribe (
+  IN      EFI_GUID        ReferenceGuid,
+  IN      OBS_CALLBACK    CallbackInterface
+  )
+{
+  EFI_STATUS  Status    = EFI_SUCCESS;
+  OBS_TREE*   TempTree  = NULL;
+  OBS_LEAF*   Last      = NULL;
+  OBS_LEAF*   TempLeaf  = NULL;
+  OBS_LEAF*   NewLeaf   = NULL;
+  BOOLEAN     Found     = FALSE;
+
+  if (mObservableDb != NULL) {
+    //
+    // Find the observable guid that we're looking for.
+    //
+    for (TempTree = mObservableDb; TempTree != NULL; TempTree = TempTree->Next) {
+      if (CompareMem(&(TempTree->ObservableGuid), &ReferenceGuid, sizeof(ReferenceGuid)) == 0) {
+        Found = TRUE;
+        break;
+      }
+    }
+    if (Found) {
+      //
+      // Prepare to add a new leaf.
+      //
+      NewLeaf = AllocateZeroPool(sizeof(OBS_LEAF));
+      if (!NewLeaf) {
+        Status = EFI_OUT_OF_RESOURCES;
+      } else {
+        NewLeaf->Next = NULL;
+        NewLeaf->Observer = CallbackInterface;
+        //
+        // Go to the end of the list of observers.
+        //
+        if (TempTree->Leaf != NULL) {
+          //
+          // First check to see if this is a duplicate observer.
+          //
+          Found = FALSE;
+          TempLeaf = TempTree->Leaf;
+          do {
+            Last = TempLeaf;
+            if (TempLeaf->Observer == CallbackInterface) {
+              //
+              // It is, so let's abort this process.
+              //
+              Found = TRUE;
+              break;
+            }
+            TempLeaf = TempLeaf->Next;
+          } while (TempLeaf != NULL);
+          TempLeaf = Last;
+
+          //
+          // Check for duplicates.
+          //
+          if (Found) {
+            gBS->FreePool(NewLeaf);
+            Status = EFI_INVALID_PARAMETER;
+          } else {
+            //
+            // At this point, TempLeaf->Next will be the end of the list.
+            //
+            TempLeaf->Next = NewLeaf;
+          }
+        } else {
+          //
+          // There are no observers listening to this guid. Start a new list.
+          //
+          TempTree->Leaf = NewLeaf;
+        }
+      }
+    } else {
+      Status = EFI_NOT_FOUND;
+    }
+  } else {
+    Status = EFI_NOT_FOUND;
+  }
+
+  return Status;
+}
+
+/** Unsubscribe an interface with an observable guid.
+ *
+ * Use this to remove an interface from the callback list associated with an observable guid.
+ *
+ * @param   EFI_GUID                ReferenceGuid   The observable guid to unsubscribe the interface from.
+ *          OBS_NOTIFY_INTERFACE    NotifyCallback  A pointer to the interface that is being unsubscribed.
+ *
+ * @return  EFI_SUCCESS           Successfully unsubscribed the interface from the observable guid.
+ **/
+EFI_STATUS
+EFIAPI
+Unsubscribe (
+  IN      EFI_GUID        ReferenceGuid,
+  IN      OBS_CALLBACK    CallbackInterface
+  )
+{
+  mObservableDb = FindAndDeleteSubscriber(mObservableDb, ReferenceGuid, CallbackInterface);
+
+  return EFI_SUCCESS;
+}
+
+/** Notify observing functions.
+ *
+ * Use this to notify all functions who are subscribed to the guid specified by ReferenceGuid.
+ *
+ * @param   EFI_GUID          ReferenceGuid   The observable guid that contains the the list of interfaces to be notified.
+ *          VOID*             Data            Parameter context to be passed to the notification function.
+ *
+ * @return  EFI_SUCCESS       Successfully notified all observers listening to this guid.
+ *          EFI_NOT_FOUND     No match could be found between the provided guid and existing observables.
+ **/
+EFI_STATUS
+EFIAPI
+Publish (
+  IN      EFI_GUID                  ReferenceGuid,
+  IN  OUT VOID*                     Data
+  )
+{
+  EFI_STATUS  Status    = EFI_SUCCESS;
+  OBS_TREE*   TempTree  = NULL;
+  OBS_LEAF*   TempLeaf  = NULL;
+  BOOLEAN     Found     = FALSE;
+
+  if (mObservableDb != NULL) {
+    //
+    // Find the observable guid that we're looking for.
+    //
+    for (TempTree = mObservableDb; TempTree != NULL; TempTree = TempTree->Next) {
+      if (CompareMem(&(TempTree->ObservableGuid), &ReferenceGuid, sizeof(ReferenceGuid)) == 0) {
+        Found = TRUE;
+        break;
+      }
+    }
+    if (Found) {
+      //
+      // Notify every listener by performing each provided callback.
+      //
+      for (TempLeaf = TempTree->Leaf; TempLeaf != NULL; TempLeaf = TempLeaf->Next) {
+        if (TempLeaf->Observer != NULL) {
+          //
+          // Execute the callback.
+          //
+          TempLeaf->Observer(Data);
+        }
+      }
+    } else {
+      Status = EFI_NOT_FOUND;
+    }
+  } else {
+    Status = EFI_NOT_FOUND;
+  }
+
+  return Status;
+}
+
+/** Creates a new observable.
+ *
+ * Create a new observable that can be observed with the use of Subscribe function.
+ *
+ * @param   EFI_GUID              ReferenceGuid   The observable guid to add.
+ *
+ * @return  EFI_SUCCESS           Successfully added observable.
+ *          EFI_INVALID_PARAMETER Observable already exists.
+ **/
+EFI_STATUS
+EFIAPI
+AddObservable (
+  IN      EFI_GUID                  ReferenceGuid
+  )
+{
+  EFI_STATUS  Status    = EFI_SUCCESS;
+  OBS_TREE*   TempTree  = NULL;
+  OBS_TREE*   Last      = NULL;
+  OBS_TREE*   NewTree   = NULL;
+  BOOLEAN     Found     = FALSE;
+
+  if (mObservableDb != NULL) {
+    if (mObservableDb->Next != NULL) {
+      //
+      // Iterate to the end of the observable list while checking to see if we aren't creating a duplicate.
+      //
+      TempTree = mObservableDb->Next;
+      do {
+        Last = TempTree;
+        if (CompareMem(&(TempTree->ObservableGuid), &ReferenceGuid, sizeof(ReferenceGuid)) == 0) {
+          Found = TRUE;
+          break;
+        }
+        TempTree = TempTree->Next;
+      } while (TempTree != NULL);
+      TempTree = Last;
+    } else {
+      TempTree = mObservableDb;
+    }
+    if (Found) {
+      //
+      // Duplicate, so reject the parameter.
+      //
+      Status = EFI_INVALID_PARAMETER;
+    } else {
+      //
+      // TempTree->Next is our target. Prepare to add a new tree link.
+      //
+      NewTree = AllocateZeroPool(sizeof(OBS_TREE));
+      if (NewTree) {
+        NewTree->Next = NULL;
+        NewTree->Leaf = NULL;
+        CopyMem(&(NewTree->ObservableGuid), &ReferenceGuid, sizeof(ReferenceGuid));
+        TempTree->Next = NewTree;
+      } else {
+        Status = EFI_OUT_OF_RESOURCES;
+      }
+    }
+  } else {
+    //
+    // mObservableDb has not been created yet. Let's do that.
+    //
+    NewTree = AllocateZeroPool(sizeof(OBS_TREE));
+    if (NewTree) {
+      NewTree->Next = NULL;
+      NewTree->Leaf = NULL;
+      CopyMem(&(NewTree->ObservableGuid), &ReferenceGuid, sizeof(ReferenceGuid));
+      mObservableDb = NewTree;
+    } else {
+      Status = EFI_OUT_OF_RESOURCES;
+    }
+  }
+
+  return Status;
+}
+
+/** Remove an observable.
+ *
+ * Remove an observable so that it can no longer be subscribed to. In addition, unsubscribe any functions
+ * that are subscribed to this guid.
+ *
+ * @param   EFI_GUID              ReferenceGuid   The observable guid to remove.
+ *
+ * @return  EFI_SUCCESS           Successfully removed observable.
+ **/
+EFI_STATUS
+EFIAPI
+RemoveObservable (
+  IN      EFI_GUID        ReferenceGuid
+  )
+{
+  mObservableDb = FindAndDeleteObservable(mObservableDb, ReferenceGuid);
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.h b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.h
new file mode 100644
index 0000000000..f46efe0f1b
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.h
@@ -0,0 +1,137 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  Observable.h
+
+Abstract:
+
+  Prototypes for Observable protocol implementation
+--*/
+
+#ifndef _OBSERVABLE_H_
+#define _OBSERVABLE_H_
+#include "PlatformDxe.h"
+#include "Protocol/Observable.h"
+
+//
+// Prototypes
+//
+
+/** Install observable protocol.
+ *
+ * Install interface and initialize the observable protocol.
+ *
+ * @param   VOID          No parameters.
+ *
+ * @return  EFI_SUCCESS   Successfully installed and initialized the protocol.
+ **/
+EFI_STATUS
+InitializeObservableProtocol(
+  VOID
+  );
+
+/** Remove all observables.
+ *
+ * Remove all observable guids and all interfaces subscribed to them.
+ *
+ * @param   VOID          No parameters.
+ *
+ * @return  EFI_SUCCESS   Successfully removed all observables and subscribed interfaces.
+ **/
+EFI_STATUS
+EFIAPI
+RemoveAllObservables(
+  VOID
+  );
+
+/** Subscribe an interface with an observable guid.
+ *
+ * Use this to register a callback function with a guid. The function provided by CallbackInterface will be executed
+ * whenever the appropriate observable instance specified by ReferenceGuid calls Publish.
+ *
+ * @param   EFI_GUID              ReferenceGuid       The observable guid that the callback interface will subscribe to.
+ *          OBS_CALLBACK          CallbackInterface   A pointer to the function that is subscribing to the observable.
+ *
+ * @return  EFI_SUCCESS           Successfully subscribed the interface to the observable guid.
+ *          EFI_NOT_FOUND         No match could be found between the provided guid and existing observables.
+ *          EFI_OUT_OF_RESOURCES  Could not subscribe to this observer due to resource limitations.
+ *          EFI_INVALID_PARAMETER Interface is already subscribed to this observer.
+ **/
+EFI_STATUS
+EFIAPI
+Subscribe (
+  IN      EFI_GUID        ReferenceGuid,
+  IN      OBS_CALLBACK    CallbackInterface
+  );
+
+/** Unsubscribe an interface with an observable guid.
+ *
+ * Use this to remove an interface from the callback list associated with an observable guid.
+ *
+ * @param   EFI_GUID              ReferenceGuid      The observable guid to unsubscribe the interface from.
+ *          OBS_CALLBACK          CallbackInterface  A pointer to the interface that is being unsubscribed.
+ *
+ * @return  EFI_SUCCESS           Successfully unsubscribed the interface from the observable guid.
+ **/
+EFI_STATUS
+EFIAPI
+Unsubscribe (
+  IN      EFI_GUID            ReferenceGuid,
+  IN      OBS_CALLBACK    CallbackInterface
+  );
+
+/** Notify observing functions.
+ *
+ * Use this to notify all functions who are subscribed to the guid specified by ReferenceGuid.
+ *
+ * @param   EFI_GUID          ReferenceGuid   The observable guid that contains the list of interfaces to be notified.
+ *          VOID*             Data            Parameter context to be passed to the subscribed function.
+ *
+ * @return  EFI_SUCCESS       Successfully notified all observers listening to this guid.
+ *          EFI_NOT_FOUND     No match could be found between the provided guid and existing observables.
+ **/
+EFI_STATUS
+EFIAPI
+Publish (
+  IN      EFI_GUID        ReferenceGuid,
+  IN  OUT VOID*           Data
+  );
+
+/** Creates a new observable.
+ *
+ * Create a new observable that can be observed with the use of Subscribe function.
+ *
+ * @param   EFI_GUID              ReferenceGuid   The observable guid to add.
+ *
+ * @return  EFI_SUCCESS           Successfully added observable.
+ *          EFI_INVALID_PARAMETER Observable already exists.
+ **/
+EFI_STATUS
+EFIAPI
+AddObservable (
+  IN      EFI_GUID        ReferenceGuid
+  );
+
+/** Remove an observable.
+ *
+ * Remove an observable so that it can no longer be subscribed to. In addition, unsubscribe any functions
+ * that are subscribed to this guid.
+ *
+ * @param   EFI_GUID              ReferenceGuid   The observable guid to remove.
+ *
+ * @return  EFI_SUCCESS           Successfully removed observable.
+ **/
+EFI_STATUS
+EFIAPI
+RemoveObservable (
+  IN      EFI_GUID        ReferenceGuid
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciBus.h b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciBus.h
new file mode 100644
index 0000000000..40c0d99392
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciBus.h
@@ -0,0 +1,379 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+**/
+
+
+#ifndef _EFI_PCI_BUS_H_
+#define _EFI_PCI_BUS_H_
+
+#include <PiDxe.h>
+
+#include <Protocol/LoadedImage.h>
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/LoadFile2.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/PciHotPlugRequest.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/PciPlatform.h>
+#include <Protocol/PciHotPlugInit.h>
+#include <Protocol/Decompress.h>
+#include <Protocol/BusSpecificDriverOverride.h>
+#include <Protocol/IncompatiblePciDeviceSupport.h>
+#include <Protocol/PciOverride.h>
+#include <Protocol/PciEnumerationComplete.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeCoffLib.h>
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/PeImage.h>
+#include <IndustryStandard/Acpi.h>
+
+typedef struct _PCI_IO_DEVICE              PCI_IO_DEVICE;
+typedef struct _PCI_BAR                    PCI_BAR;
+
+#define EFI_PCI_RID(Bus, Device, Function)  (((UINT32)Bus << 8) + ((UINT32)Device << 3) + (UINT32)Function)
+#define EFI_PCI_BUS_OF_RID(RID)             ((UINT32)RID >> 8)
+
+#define     EFI_PCI_IOV_POLICY_ARI           0x0001
+#define     EFI_PCI_IOV_POLICY_SRIOV         0x0002
+#define     EFI_PCI_IOV_POLICY_MRIOV         0x0004
+
+typedef enum {
+  PciBarTypeUnknown = 0,
+  PciBarTypeIo16,
+  PciBarTypeIo32,
+  PciBarTypeMem32,
+  PciBarTypePMem32,
+  PciBarTypeMem64,
+  PciBarTypePMem64,
+  PciBarTypeIo,
+  PciBarTypeMem,
+  PciBarTypeMaxType
+} PCI_BAR_TYPE;
+
+
+#define VGABASE1  0x3B0
+#define VGALIMIT1 0x3BB
+
+#define VGABASE2  0x3C0
+#define VGALIMIT2 0x3DF
+
+#define ISABASE   0x100
+#define ISALIMIT  0x3FF
+
+//
+// PCI BAR parameters
+//
+struct _PCI_BAR {
+  UINT64        BaseAddress;
+  UINT64        Length;
+  UINT64        Alignment;
+  PCI_BAR_TYPE  BarType;
+  BOOLEAN       Prefetchable;
+  UINT8         MemType;
+  UINT16        Offset;
+};
+
+//
+// defined in PCI Card Specification, 8.0
+//
+#define PCI_CARD_MEMORY_BASE_0                0x1C
+#define PCI_CARD_MEMORY_LIMIT_0               0x20
+#define PCI_CARD_MEMORY_BASE_1                0x24
+#define PCI_CARD_MEMORY_LIMIT_1               0x28
+#define PCI_CARD_IO_BASE_0_LOWER              0x2C
+#define PCI_CARD_IO_BASE_0_UPPER              0x2E
+#define PCI_CARD_IO_LIMIT_0_LOWER             0x30
+#define PCI_CARD_IO_LIMIT_0_UPPER             0x32
+#define PCI_CARD_IO_BASE_1_LOWER              0x34
+#define PCI_CARD_IO_BASE_1_UPPER              0x36
+#define PCI_CARD_IO_LIMIT_1_LOWER             0x38
+#define PCI_CARD_IO_LIMIT_1_UPPER             0x3A
+#define PCI_CARD_BRIDGE_CONTROL               0x3E
+
+#define PCI_CARD_PREFETCHABLE_MEMORY_0_ENABLE BIT8
+#define PCI_CARD_PREFETCHABLE_MEMORY_1_ENABLE BIT9
+
+#define PPB_BAR_0                             0
+#define PPB_BAR_1                             1
+#define PPB_IO_RANGE                          2
+#define PPB_MEM32_RANGE                       3
+#define PPB_PMEM32_RANGE                      4
+#define PPB_PMEM64_RANGE                      5
+#define PPB_MEM64_RANGE                       0xFF
+
+#define P2C_BAR_0                             0
+#define P2C_MEM_1                             1
+#define P2C_MEM_2                             2
+#define P2C_IO_1                              3
+#define P2C_IO_2                              4
+
+#define EFI_BRIDGE_IO32_DECODE_SUPPORTED      0x0001
+#define EFI_BRIDGE_PMEM32_DECODE_SUPPORTED    0x0002
+#define EFI_BRIDGE_PMEM64_DECODE_SUPPORTED    0x0004
+#define EFI_BRIDGE_IO16_DECODE_SUPPORTED      0x0008
+#define EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED 0x0010
+#define EFI_BRIDGE_MEM64_DECODE_SUPPORTED     0x0020
+#define EFI_BRIDGE_MEM32_DECODE_SUPPORTED     0x0040
+
+#define PCI_MAX_HOST_BRIDGE_NUM               0x0010
+
+//
+// Define option for attribute
+//
+#define EFI_SET_SUPPORTS    0
+#define EFI_SET_ATTRIBUTES  1
+
+#define PCI_IO_DEVICE_SIGNATURE               SIGNATURE_32 ('p', 'c', 'i', 'o')
+
+struct _PCI_IO_DEVICE {
+  UINT32                                    Signature;
+  EFI_HANDLE                                Handle;
+  EFI_PCI_IO_PROTOCOL                       PciIo;
+  LIST_ENTRY                                Link;
+
+  EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL PciDriverOverride;
+  EFI_DEVICE_PATH_PROTOCOL                  *DevicePath;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *PciRootBridgeIo;
+  EFI_LOAD_FILE2_PROTOCOL                   LoadFile2;
+
+  //
+  // PCI configuration space header type
+  //
+  PCI_TYPE00                                Pci;
+
+  //
+  // Bus number, Device number, Function number
+  //
+  UINT8                                     BusNumber;
+  UINT8                                     DeviceNumber;
+  UINT8                                     FunctionNumber;
+
+  //
+  // BAR for this PCI Device
+  //
+  PCI_BAR                                   PciBar[PCI_MAX_BAR];
+
+  //
+  // The bridge device this pci device is subject to
+  //
+  PCI_IO_DEVICE                             *Parent;
+
+  //
+  // A linked list for children Pci Device if it is bridge device
+  //
+  LIST_ENTRY                                ChildList;
+
+  //
+  // TRUE if the PCI bus driver creates the handle for this PCI device
+  //
+  BOOLEAN                                   Registered;
+
+  //
+  // TRUE if the PCI bus driver successfully allocates the resource required by
+  // this PCI device
+  //
+  BOOLEAN                                   Allocated;
+
+  //
+  // The attribute this PCI device currently set
+  //
+  UINT64                                    Attributes;
+
+  //
+  // The attributes this PCI device actually supports
+  //
+  UINT64                                    Supports;
+
+  //
+  // The resource decode the bridge supports
+  //
+  UINT32                                    Decodes;
+
+  //
+  // TRUE if the ROM image is from the PCI Option ROM BAR
+  //
+  BOOLEAN                                   EmbeddedRom;
+
+  //
+  // The OptionRom Size
+  //
+  UINT64                                    RomSize;
+
+  //
+  // The OptionRom Size
+  //
+  UINT64                                    RomBase;
+
+  //
+  // TRUE if all OpROM (in device or in platform specific position) have been processed
+  //
+  BOOLEAN                                   AllOpRomProcessed;
+
+  //
+  // TRUE if there is any EFI driver in the OptionRom
+  //
+  BOOLEAN                                   BusOverride;
+
+  //
+  // A list tracking reserved resource on a bridge device
+  //
+  LIST_ENTRY                                ReservedResourceList;
+
+  //
+  // A list tracking image handle of platform specific overriding driver
+  //
+  LIST_ENTRY                                OptionRomDriverList;
+
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR         *ResourcePaddingDescriptors;
+  EFI_HPC_PADDING_ATTRIBUTES                PaddingAttributes;
+
+  BOOLEAN                                   IsPciExp;
+
+  //
+  // For SR-IOV
+  //
+  UINT8                                     PciExpressCapabilityOffset;
+  UINT32                                    AriCapabilityOffset;
+  UINT32                                    SrIovCapabilityOffset;
+  UINT32                                    MrIovCapabilityOffset;
+  PCI_BAR                                   VfPciBar[PCI_MAX_BAR];
+  UINT32                                    SystemPageSize;
+  UINT16                                    InitialVFs;
+  UINT16                                    ReservedBusNum;
+
+  //
+  // Per PCI to PCI Bridge spec, I/O window is 4K aligned,
+  // but some chipsets support non-standard I/O window alignments less than 4K.
+  // This field is used to support this case.
+  //
+  UINT16                                    BridgeIoAlignment;
+};
+
+#define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \
+  CR (a, PCI_IO_DEVICE, PciIo, PCI_IO_DEVICE_SIGNATURE)
+
+#define PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS(a) \
+  CR (a, PCI_IO_DEVICE, PciDriverOverride, PCI_IO_DEVICE_SIGNATURE)
+
+#define PCI_IO_DEVICE_FROM_LINK(a) \
+  CR (a, PCI_IO_DEVICE, Link, PCI_IO_DEVICE_SIGNATURE)
+
+#define PCI_IO_DEVICE_FROM_LOAD_FILE2_THIS(a) \
+  CR (a, PCI_IO_DEVICE, LoadFile2, PCI_IO_DEVICE_SIGNATURE)
+
+
+
+//
+// Global Variables
+//
+extern EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL *gEfiIncompatiblePciDeviceSupport;
+extern EFI_DRIVER_BINDING_PROTOCOL                  gPciBusDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL                  gPciBusComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL                 gPciBusComponentName2;
+extern BOOLEAN                                      gFullEnumeration;
+extern UINTN                                        gPciHostBridgeNumber;
+extern EFI_HANDLE                                   gPciHostBrigeHandles[PCI_MAX_HOST_BRIDGE_NUM];
+extern UINT64                                       gAllOne;
+extern UINT64                                       gAllZero;
+extern EFI_PCI_PLATFORM_PROTOCOL                    *gPciPlatformProtocol;
+extern EFI_PCI_OVERRIDE_PROTOCOL                    *gPciOverrideProtocol;
+extern BOOLEAN                                      mReserveIsaAliases;
+extern BOOLEAN                                      mReserveVgaAliases;
+
+/**
+  Macro that checks whether device is a GFX device.
+
+  @param  _p      Specified device.
+
+  @retval TRUE    Device is a GFX device.
+  @retval FALSE   Device is not a GFX device.
+
+**/
+#define IS_PCI_GFX(_p)     IS_CLASS2 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_OTHER)
+
+/**
+  Test to see if this driver supports ControllerHandle. Any ControllerHandle
+  than contains a gEfiPciRootBridgeIoProtocolGuid protocol can be supported.
+
+  @param  This                Protocol instance pointer.
+  @param  Controller          Handle of device to test.
+  @param  RemainingDevicePath Optional parameter use to pick a specific child
+                              device to start.
+
+  @retval EFI_SUCCESS         This driver supports this device.
+  @retval EFI_ALREADY_STARTED This driver is already running on this device.
+  @retval other               This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+PciBusDriverBindingSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  );
+
+/**
+  Start this driver on ControllerHandle and enumerate Pci bus and start
+  all device under PCI bus.
+
+  @param  This                 Protocol instance pointer.
+  @param  Controller           Handle of device to bind driver to.
+  @param  RemainingDevicePath  Optional parameter use to pick a specific child
+                               device to start.
+
+  @retval EFI_SUCCESS          This driver is added to ControllerHandle.
+  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle.
+  @retval other                This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+PciBusDriverBindingStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  );
+
+/**
+  Stop this driver on ControllerHandle. Support stopping any child handles
+  created by this driver.
+
+  @param  This              Protocol instance pointer.
+  @param  Controller        Handle of device to stop driver on.
+  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
+                            children is zero stop the entire bus driver.
+  @param  ChildHandleBuffer List of Child Handles to Stop.
+
+  @retval EFI_SUCCESS       This driver is removed ControllerHandle.
+  @retval other             This driver was not removed from this device.
+
+**/
+EFI_STATUS
+EFIAPI
+PciBusDriverBindingStop (
+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
+  IN  EFI_HANDLE                    Controller,
+  IN  UINTN                         NumberOfChildren,
+  IN  EFI_HANDLE                    *ChildHandleBuffer
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c
new file mode 100644
index 0000000000..582d8627cd
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c
@@ -0,0 +1,506 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+  PciDevice.c
+
+Abstract:
+
+  Platform Initialization Driver.
+
+Revision History
+
+--*/
+
+#include "PlatformDxe.h"
+#include "Library/DxeServicesTableLib.h"
+#include "PciBus.h"
+#include "Guid/PciLanInfo.h"
+
+extern  VOID    *mPciLanInfo;
+extern  UINTN   mPciLanCount;
+
+extern  EFI_HANDLE  mImageHandle;
+extern  SYSTEM_CONFIGURATION    mSystemConfiguration;
+
+
+VOID       *mPciRegistration;
+#define NCR_VENDOR_ID  0x1000
+#define ATI_VENDOR_ID  0x1002
+#define INTEL_VENDOR_ID 0x8086
+#define ATI_RV423_ID   0x5548
+#define ATI_RV423_ID2  0x5d57
+#define ATI_RV380_ID   0x3e50
+#define ATI_RV370_ID   0x5b60
+#define SI_VENDOR_ID   0x1095
+#define SI_SISATA_ID   0x3114
+#define SI_SIRAID_PCIUNL 0x40
+#define INTEL_82573E_IDER 0x108D
+
+typedef struct {
+  UINT8               ClassCode;
+  UINT8               SubClassCode;
+  UINT16              VendorId;
+  UINT16              DeviceId;
+} BAD_DEVICE_TABLE;
+
+BAD_DEVICE_TABLE BadDeviceTable[] = {
+                    {(UINT8)PCI_CLASS_MASS_STORAGE,(UINT8)PCI_CLASS_MASS_STORAGE_SCSI,(UINT16)NCR_VENDOR_ID, (UINT16)0xffff}, // Any NCR cards
+                    {(UINT8)PCI_CLASS_MASS_STORAGE,(UINT8)PCI_CLASS_MASS_STORAGE_IDE,(UINT16)INTEL_VENDOR_ID, (UINT16)INTEL_82573E_IDER},  // Intel i82573E Tekoa GBit Lan IDE-R
+                    {(UINT8)0xff,(UINT8)0xff,(UINT16)0xffff,(UINT16)0xffff}
+                  };
+
+EFI_STATUS
+PciBusDriverHook (
+  )
+{
+  EFI_STATUS                Status;
+  EFI_EVENT                 FilterEvent;
+
+  //
+  // Register for callback to PCI I/O protocol
+  //
+  Status = gBS->CreateEvent (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  PciBusEvent,
+                  NULL,
+                  &FilterEvent
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  // Register for protocol notifications on this event
+  //
+  Status = gBS->RegisterProtocolNotify (
+                  &gEfiPciIoProtocolGuid,
+                  FilterEvent,
+                  &mPciRegistration
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return  EFI_SUCCESS;
+}
+
+VOID
+InitBadBars(
+  IN    EFI_PCI_IO_PROTOCOL           *PciIo,
+  IN    UINT16                        VendorId,
+  IN    UINT16                        DeviceId
+  )
+{
+
+  UINT64                              BaseAddress = 0;
+  UINT64                              TempBaseAddress = 0;
+  UINT8                               RevId = 0;
+  UINT32                              Bar;
+  UINT64                              IoSize;
+  UINT64                              MemSize;
+  UINTN                               MemSizeBits;
+
+  switch ( VendorId) {
+    case ATI_VENDOR_ID:
+      //
+      //  ATI fix-ups. At this time all ATI cards in BadDeviceTable
+      //  have same problem in that OPROM BAR needs to be increased.
+      //
+      Bar = 0x30 ;
+      //
+      // Get original BAR address
+      //
+      PciIo->Pci.Read (
+                   PciIo,
+                   EfiPciIoWidthUint32,
+                   Bar,
+                   1,
+                       (VOID *) &BaseAddress
+                   );
+      //
+      // Find BAR size
+      //
+      TempBaseAddress = 0xffffffff;
+      PciIo->Pci.Write (
+                   PciIo,
+                   EfiPciIoWidthUint32,
+                   Bar,
+                   1,
+                        (VOID *) &TempBaseAddress
+                   );
+      PciIo->Pci.Read (
+                   PciIo,
+                   EfiPciIoWidthUint32,
+                   Bar,
+                   1,
+                       (VOID *) &TempBaseAddress
+                   );
+      TempBaseAddress &= 0xfffffffe;
+      MemSize = 1;
+      while ((TempBaseAddress & 0x01) == 0) {
+        TempBaseAddress = TempBaseAddress >> 1;
+        MemSize = MemSize << 1;
+      }
+
+      //
+      // Free up allocated memory memory and re-allocate with increased size.
+      //
+      gDS->FreeMemorySpace (
+             BaseAddress,
+             MemSize
+             );
+      //
+      // Force new alignment
+      //
+      MemSize = 0x8000000;
+      MemSizeBits = 28;
+
+      gDS->AllocateMemorySpace (
+             EfiGcdAllocateAnySearchBottomUp,
+             EfiGcdMemoryTypeMemoryMappedIo,
+             MemSizeBits,           // Alignment
+             MemSize,
+             &BaseAddress,
+             mImageHandle,
+             NULL
+             );
+      PciIo->Pci.Write (
+                   PciIo,
+                   EfiPciIoWidthUint32,
+                   Bar,
+                   1,
+                        (VOID *) &BaseAddress
+                   );
+
+      break;
+    case    NCR_VENDOR_ID:
+#define MIN_NCR_IO_SIZE  0x800
+#define NCR_GRAN  11  // 2**11 = 0x800
+  //
+  // NCR SCSI cards like 8250S lie about IO needed. Assign as least 0x80.
+  //
+  for (Bar = 0x10; Bar < 0x28; Bar+= 4) {
+
+    PciIo->Pci.Read (
+                 PciIo,
+                 EfiPciIoWidthUint32,
+                 Bar,
+                 1,
+                     (VOID *) &BaseAddress
+                 );
+    if (BaseAddress && 0x01) {
+      TempBaseAddress = 0xffffffff;
+      PciIo->Pci.Write (
+                   PciIo,
+                   EfiPciIoWidthUint32,
+                   Bar,
+                   1,
+                        (VOID *) &TempBaseAddress
+                   );
+      TempBaseAddress &= 0xfffffffc;
+      IoSize = 1;
+      while ((TempBaseAddress & 0x01) == 0) {
+        TempBaseAddress = TempBaseAddress >> 1;
+        IoSize = IoSize << 1;
+      }
+      if (IoSize < MIN_NCR_IO_SIZE) {
+        gDS->FreeIoSpace (
+               BaseAddress,
+               IoSize
+               );
+
+        gDS->AllocateIoSpace (
+               EfiGcdAllocateAnySearchTopDown,
+               EfiGcdIoTypeIo,
+               NCR_GRAN,           // Alignment
+               MIN_NCR_IO_SIZE,
+               &BaseAddress,
+               mImageHandle,
+               NULL
+               );
+        TempBaseAddress = BaseAddress + 1;
+        PciIo->Pci.Write (
+                     PciIo,
+                     EfiPciIoWidthUint32,
+                     Bar,
+                     1,
+                          (VOID *) &TempBaseAddress
+                     );
+      }
+    }
+  }
+
+      break;
+
+    case INTEL_VENDOR_ID:
+      if (DeviceId == INTEL_82573E_IDER) {
+        //
+        //  Tekoa i82573E IDE-R fix-ups. At this time A2 step and earlier parts do not
+        //  support any BARs except BAR0. Other BARS will actualy map to BAR0 so disable
+        //  them all for Control Blocks and Bus mastering ops as well as Secondary IDE
+        //  Controller.
+        //  All Tekoa A2 or earlier step chips for now.
+        //
+        PciIo->Pci.Read (
+                     PciIo,
+                     EfiPciIoWidthUint8,
+                     PCI_REVISION_ID_OFFSET,
+                     1,
+                     &RevId
+                     );
+        if (RevId <= 0x02) {
+          for (Bar = 0x14; Bar < 0x24; Bar+= 4) {
+            //
+            // Maybe want to clean this up a bit later but for now just clear out the secondary
+            // Bars don't worry aboyut freeing up thge allocs.
+            //
+            TempBaseAddress = 0x0;
+            PciIo->Pci.Write (
+                         PciIo,
+                         EfiPciIoWidthUint32,
+                         Bar,
+                         1,
+                              (VOID *) &TempBaseAddress
+                         );
+          } // end for
+        }
+        else
+        {
+        	//
+          //Tekoa A3 or above:
+          //Clear bus master base address (PCI register 0x20)
+          //since Tekoa does not fully support IDE Bus Mastering
+          //
+          TempBaseAddress = 0x0;
+          PciIo->Pci.Write (
+                       PciIo,
+                       EfiPciIoWidthUint32,
+                       0x20,
+                       1,
+                            (VOID *) &TempBaseAddress
+                       );
+        }
+      }
+      break;
+
+    default:
+      break;
+  }
+  return;
+}
+
+VOID
+ProgramPciLatency(
+  IN    EFI_PCI_IO_PROTOCOL           *PciIo
+  )
+{
+  //
+  // Program Master Latency Timer
+  //
+  if (mSystemConfiguration.PciLatency != 0) {
+     PciIo->Pci.Write (
+                  PciIo,
+                  EfiPciIoWidthUint8,
+                  PCI_LATENCY_TIMER_OFFSET,
+                  1,
+                  &mSystemConfiguration.PciLatency
+                  );
+  }
+  return;
+}
+
+/**
+During S5 shutdown, we need to program PME in all LAN devices.
+Here we identify LAN devices and save their bus/dev/func.
+
+**/
+VOID
+SavePciLanAddress(
+  IN EFI_PCI_IO_PROTOCOL    *PciIo
+  )
+{
+  EFI_STATUS        Status;
+  UINTN             PciSegment,
+                    PciBus,
+                    PciDevice,
+                    PciFunction;
+  VOID              *NewBuffer;
+  PCI_LAN_INFO      *x;
+
+  Status = PciIo->GetLocation (
+                    PciIo,
+                    &PciSegment,
+                    &PciBus,
+                    &PciDevice,
+                    &PciFunction
+                    );
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  mPciLanCount ++;
+  Status = gBS->AllocatePool (
+                  EfiBootServicesData,
+                  mPciLanCount * sizeof(PCI_LAN_INFO),
+                  &NewBuffer
+                  );
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  if (mPciLanCount > 1) {
+    //
+    // copy old data into new, larger buffer
+    //
+    gBS->CopyMem (
+           NewBuffer,
+           mPciLanInfo,
+           (mPciLanCount - 1) * sizeof(PCI_LAN_INFO)
+           );
+
+    //
+    // free the old memory buffer
+    //
+    gBS->FreePool (mPciLanInfo);
+
+  }
+
+  //
+  // init the new entry
+  //
+  x = (PCI_LAN_INFO *)NewBuffer + (mPciLanCount - 1);
+  x->PciBus = (UINT8)PciBus;
+  x->PciDevice = (UINT8)PciDevice;
+  x->PciFunction = (UINT8)PciFunction;
+
+  mPciLanInfo = NewBuffer;
+
+  return;
+}
+
+/**
+  @param  Event          the event that is signaled.
+  @param Context        not used here.
+
+
+**/
+VOID
+EFIAPI
+PciBusEvent (
+  IN EFI_EVENT    Event,
+  IN VOID*        Context
+  )
+{
+
+  EFI_STATUS                    Status;
+  UINTN                         BufferSize;
+  EFI_HANDLE                    Handle;
+  EFI_PCI_IO_PROTOCOL           *PciIo;
+  PCI_IO_DEVICE                 *PciIoDevice;
+  UINT64                        Supports;
+  UINTN                         Index;
+  UINT8                         mCacheLineSize = 0x10;
+
+  while (TRUE) {
+    BufferSize = sizeof (EFI_HANDLE);
+    Status = gBS->LocateHandle (
+                    ByRegisterNotify,
+                    NULL,
+                    mPciRegistration,
+                    &BufferSize,
+                    &Handle
+                    );
+    if (EFI_ERROR (Status)) {
+      //
+      // If no more notification events exist
+      //
+      return;
+    }
+
+    Status = gBS->HandleProtocol (
+                    Handle,
+                    &gEfiPciIoProtocolGuid,
+                    (void **)&PciIo
+                    );
+
+    PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);
+
+    //
+    // Enable I/O for bridge so port 0x80 codes will come out
+    //
+    if (PciIoDevice->Pci.Hdr.VendorId == V_PCH_INTEL_VENDOR_ID)
+    {
+      Status = PciIo->Attributes(
+                        PciIo,
+                        EfiPciIoAttributeOperationSupported,
+                        0,
+                        &Supports
+                        );
+      Supports &= EFI_PCI_DEVICE_ENABLE;
+      Status = PciIo->Attributes (
+                        PciIo,
+                        EfiPciIoAttributeOperationEnable,
+                        Supports,
+                        NULL
+                        );
+      break;
+    }
+
+    //
+    // Program PCI Latency Timer
+    //
+    ProgramPciLatency(PciIo);
+
+    //
+    // Program Cache Line Size to 64 bytes (0x10 DWORDs)
+    //
+    Status = PciIo->Pci.Write (
+                          PciIo,
+                          EfiPciIoWidthUint8,
+                          PCI_CACHELINE_SIZE_OFFSET,
+                          1,
+                          &mCacheLineSize
+                          );
+
+    //
+    // If PCI LAN device, save bus/dev/func info
+    // so we can program PME during S5 shutdown
+    //
+    if (PciIoDevice->Pci.Hdr.ClassCode[2] == PCI_CLASS_NETWORK) {
+      SavePciLanAddress(PciIo);
+      break;
+    }
+
+    //
+    // Workaround for cards with bad BARs
+    //
+    Index = 0;
+    while (BadDeviceTable[Index].ClassCode != 0xff) {
+      if (BadDeviceTable[Index].DeviceId == 0xffff) {
+        if ((PciIoDevice->Pci.Hdr.ClassCode[2] == BadDeviceTable[Index].ClassCode) &&
+            (PciIoDevice->Pci.Hdr.ClassCode[1] == BadDeviceTable[Index].SubClassCode) &&
+            (PciIoDevice->Pci.Hdr.VendorId == BadDeviceTable[Index].VendorId)) {
+          InitBadBars(PciIo,BadDeviceTable[Index].VendorId,BadDeviceTable[Index].DeviceId);
+        }
+      } else {
+        if ((PciIoDevice->Pci.Hdr.ClassCode[2] == BadDeviceTable[Index].ClassCode) &&
+            (PciIoDevice->Pci.Hdr.ClassCode[1] == BadDeviceTable[Index].SubClassCode) &&
+            (PciIoDevice->Pci.Hdr.VendorId == BadDeviceTable[Index].VendorId) &&
+            (PciIoDevice->Pci.Hdr.DeviceId == BadDeviceTable[Index].DeviceId)) {
+
+          InitBadBars(PciIo,BadDeviceTable[Index].VendorId,BadDeviceTable[Index].DeviceId);
+        }
+      }
+      ++Index;
+    }
+      break;
+    }
+
+  return;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Platform.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Platform.c
new file mode 100644
index 0000000000..2a4a0b92e1
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Platform.c
@@ -0,0 +1,1820 @@
+/** @file
+
+  Copyright (c) 2004  - 2015, Intel Corporation. All rights reserved.<BR>
+                                                                                   
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   
+
+
+Module Name:
+
+
+  Platform.c
+
+Abstract:
+
+  Platform Initialization Driver.
+
+
+--*/
+
+#include "PlatformDxe.h"
+#include "Platform.h"
+#include "PchCommonDefinitions.h"
+#include <Protocol/UsbPolicy.h>
+#include <Protocol/PchPlatformPolicy.h>
+#include <Protocol/TpmMp.h>
+#include <Protocol/CpuIo2.h>
+#include <Library/S3BootScriptLib.h>
+#include <Guid/PciLanInfo.h>
+#include <Guid/ItkData.h>
+#include <Library/PciLib.h>
+#include <PlatformBootMode.h>
+#include <Guid/EventGroup.h>
+#include <Guid/Vlv2Variable.h>
+#include <Protocol/GlobalNvsArea.h>
+#include <Protocol/IgdOpRegion.h>
+#include <Library/PcdLib.h>
+#include <Protocol/VariableLock.h>
+
+
+//
+// VLV2 GPIO GROUP OFFSET
+//
+#define GPIO_SCORE_OFFSET	0x0000
+#define GPIO_NCORE_OFFSET	0x1000
+#define GPIO_SSUS_OFFSET	0x2000
+
+typedef struct {
+  UINT32 offset;
+  UINT32 val;
+} CFIO_PNP_INIT;
+
+GPIO_CONF_PAD_INIT mTB_BL_GpioInitData_SC_TRI_Exit_boot_Service[] =
+{
+//              Pad Name          GPIO Number     Used As   GPO Default  Function#     INT Capable   Interrupt Type   PULL H/L    MMIO Offset
+  GPIO_INIT_ITEM("LPC_CLKOUT0       GPIOC_47 "     ,TRISTS   ,NA           ,F0           ,             ,                ,NONE       ,0x47),
+  GPIO_INIT_ITEM("LPC_CLKOUT1       GPIOC_48 "     ,TRISTS   ,NA           ,F0           ,             ,                ,NONE       ,0x41),
+};
+
+
+EFI_GUID mSystemHiiExportDatabase = EFI_HII_EXPORT_DATABASE_GUID;
+EFI_GUID mPlatformDriverGuid = EFI_PLATFORM_DRIVER_GUID;
+SYSTEM_CONFIGURATION  mSystemConfiguration;
+SYSTEM_PASSWORDS      mSystemPassword;
+EFI_HANDLE            mImageHandle;
+BOOLEAN               mMfgMode = FALSE;
+VOID                  *mDxePlatformStringPack;
+UINT32                mPlatformBootMode = PLATFORM_NORMAL_MODE;
+extern CHAR16 gItkDataVarName[];
+
+
+EFI_PLATFORM_INFO_HOB      mPlatformInfo;
+EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *mPciRootBridgeIo;
+EFI_EVENT  mReadyToBootEvent;
+
+UINT8 mSmbusRsvdAddresses[] = PLATFORM_SMBUS_RSVD_ADDRESSES;
+UINT8 mNumberSmbusAddress = sizeof( mSmbusRsvdAddresses ) / sizeof( mSmbusRsvdAddresses[0] );
+UINT32 mSubsystemVidDid;
+UINT32 mSubsystemAudioVidDid;
+
+UINTN   mPciLanCount = 0;
+VOID    *mPciLanInfo = NULL;
+UINTN   SpiBase;
+
+static EFI_SPEAKER_IF_PROTOCOL mSpeakerInterface = {
+  ProgramToneFrequency,
+  GenerateBeepTone
+};
+
+EFI_USB_POLICY_PROTOCOL         mUsbPolicyData = {0};
+
+
+CFIO_PNP_INIT mTB_BL_GpioInitData_SC_TRI_S0ix_Exit_boot_Service[] =
+{
+  {0x410 ,0x20038e10},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_clkout1_pconf0
+  {0x470 ,0x20038e10},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_clkout0_pconf0
+  {0x560 ,0x20038e10},  //vlv.gpio.gpscore.cfio_regs_pad_ilb_serirq_pconf0
+  {0x450 ,0x20038e10},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_frameb_pconf0
+  {0x480 ,0x20038e10},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_clkrunb_pconf0
+  {0x420 ,0x20038e10},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_ad3_pconf0
+  {0x430 ,0x20038e10},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_ad2_pconf0
+  {0x440 ,0x20038e10},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_ad1_pconf0
+  {0x460 ,0x20038e10},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_ad0_pconf0
+  {0x418 ,0x00000006},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_clkout1_pad_val
+  {0x478 ,0x00000006},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_clkout0_pad_val
+  {0x568 ,0x00000006},  //vlv.gpio.gpscore.cfio_regs_pad_ilb_serirq_pad_val
+  {0x458 ,0x00000006},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_frameb_pad_val
+  {0x488 ,0x00000006},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_clkrunb_pad_val
+  {0x428 ,0x00000006},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_ad3_pad_val
+  {0x438 ,0x00000006},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_ad2_pad_val
+  {0x448 ,0x00000006},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_ad1_pad_val
+  {0x468 ,0x00000006},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_ad0_pad_val
+};
+
+VOID
+EfiOrMem (
+  IN VOID   *Destination,
+  IN VOID   *Source,
+  IN UINTN  Length
+  );
+
+#if defined(FIRMWARE_ID_BACKWARD_COMPATIBLE) && (FIRMWARE_ID_BACKWARD_COMPATIBLE != 0)
+STATIC
+VOID
+InitFirmwareId();
+#endif
+
+
+VOID
+InitializeClockRouting(
+  );
+
+VOID
+InitializeSlotInfo (
+  );
+
+#if defined(SENSOR_INFO_VAR_SUPPORT) && SENSOR_INFO_VAR_SUPPORT != 0
+VOID
+InitializeSensorInfoVariable (
+  );
+#endif
+
+VOID
+InitTcoReset (
+  );
+
+VOID
+InitExI ();
+
+VOID
+InitItk();
+
+VOID
+InitPlatformBootMode();
+
+VOID
+InitMfgAndConfigModeStateVar();
+
+VOID
+InitPchPlatformPolicy (
+  IN EFI_PLATFORM_INFO_HOB      *PlatformInfo
+  );
+
+VOID
+InitVlvPlatformPolicy (
+  );
+
+VOID
+InitSioPlatformPolicy(
+  );
+
+VOID
+PchInitBeforeBoot(
+  );
+
+VOID
+UpdateDVMTSetup(
+  );
+
+VOID
+InitPlatformUsbPolicy (
+  VOID
+  );
+
+VOID
+InitRC6Policy(
+  VOID
+  );
+
+
+EFI_STATUS
+EFIAPI
+SaveSetupRecoveryVar(
+  VOID
+  )
+{
+  EFI_STATUS                   Status = EFI_SUCCESS;
+  UINTN                        SizeOfNvStore = 0;
+  UINTN                        SizeOfSetupVar = 0;
+  SYSTEM_CONFIGURATION         *SetupData = NULL;
+  SYSTEM_CONFIGURATION         *RecoveryNvData = NULL;
+  EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock = NULL;
+
+
+  DEBUG ((EFI_D_INFO, "SaveSetupRecoveryVar() Entry \n"));
+  SizeOfNvStore = sizeof(SYSTEM_CONFIGURATION);
+  RecoveryNvData = AllocateZeroPool (sizeof(SYSTEM_CONFIGURATION));
+  if (NULL == RecoveryNvData) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Exit; 
+  }
+  
+  Status = gRT->GetVariable(
+                L"SetupRecovery",
+                &gEfiNormalSetupGuid,
+                NULL,
+                &SizeOfNvStore,
+                RecoveryNvData
+                );
+  
+  if (EFI_ERROR (Status)) {
+    // Don't find the "SetupRecovery" variable.
+    // have to copy "Setup" variable to "SetupRecovery" variable.
+    SetupData = AllocateZeroPool (sizeof(SYSTEM_CONFIGURATION));
+    if (NULL == SetupData) {
+      Status = EFI_OUT_OF_RESOURCES;
+      goto Exit;      
+    }
+    SizeOfSetupVar = sizeof(SYSTEM_CONFIGURATION);
+    Status = gRT->GetVariable(
+                    NORMAL_SETUP_NAME,
+                    &gEfiNormalSetupGuid,
+                    NULL,
+                    &SizeOfSetupVar,
+                    SetupData
+                    );
+    ASSERT_EFI_ERROR (Status);
+    
+    Status = gRT->SetVariable (
+                    L"SetupRecovery",
+                    &gEfiNormalSetupGuid,
+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                    sizeof(SYSTEM_CONFIGURATION),
+                    SetupData
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **) &VariableLock);
+      if (!EFI_ERROR (Status)) {
+        Status = VariableLock->RequestToLock (VariableLock, L"SetupRecovery", &gEfiNormalSetupGuid);
+        ASSERT_EFI_ERROR (Status);
+    }
+    
+  }
+
+Exit:
+  if (RecoveryNvData)
+    FreePool (RecoveryNvData);
+  if (SetupData)
+    FreePool (SetupData);
+  
+  return Status;
+    
+}
+
+
+VOID
+TristateLpcGpioConfig (
+  IN UINT32             Gpio_Mmio_Offset,
+  IN UINT32             Gpio_Pin_Num,
+  GPIO_CONF_PAD_INIT*   Gpio_Conf_Data
+  )
+
+{
+  UINT32    index;
+  UINT32    mmio_conf0;
+  UINT32    mmio_padval;
+  PAD_CONF0 conf0_val;
+  PAD_VAL   pad_val;
+
+  //
+  // GPIO WELL -- Memory base registers
+  //
+
+  //
+  // A0 BIOS Spec doesn't mention it although X0 does. comment out now.
+  // GPIO write 0x01001002 to IOBASE + Gpio_Mmio_Offset + 0x0900
+  //
+
+  for(index=0; index < Gpio_Pin_Num; index++)
+  {
+    //
+    // Calculate the MMIO Address for specific GPIO pin CONF0 register pointed by index.
+    //
+    mmio_conf0 = IO_BASE_ADDRESS + Gpio_Mmio_Offset + R_PCH_CFIO_PAD_CONF0 + Gpio_Conf_Data[index].offset * 16;
+    mmio_padval= IO_BASE_ADDRESS + Gpio_Mmio_Offset + R_PCH_CFIO_PAD_VAL   + Gpio_Conf_Data[index].offset * 16;
+
+#ifdef EFI_DEBUG
+    DEBUG ((EFI_D_INFO, "%s, ", Gpio_Conf_Data[index].pad_name));
+
+#endif
+    DEBUG ((EFI_D_INFO, "Usage = %d, Func# = %d, IntType = %d, Pull Up/Down = %d, MMIO Base = 0x%08x, ",
+      Gpio_Conf_Data[index].usage,
+      Gpio_Conf_Data[index].func,
+      Gpio_Conf_Data[index].int_type,
+      Gpio_Conf_Data[index].pull,
+      mmio_conf0));
+
+    //
+    // Step 1: PadVal Programming
+    //
+    pad_val.dw = MmioRead32(mmio_padval);
+
+    //
+    // Config PAD_VAL only for GPIO (Non-Native) Pin
+    //
+    if(Native != Gpio_Conf_Data[index].usage)
+    {
+      pad_val.dw &= ~0x6; // Clear bits 1:2
+      pad_val.dw |= (Gpio_Conf_Data[index].usage & 0x6);  // Set bits 1:2 according to PadVal
+
+        //
+        // set GPO default value
+        //
+        if(Gpio_Conf_Data[index].usage == GPO && Gpio_Conf_Data[index].gpod4 != NA)
+        {
+        pad_val.r.pad_val = Gpio_Conf_Data[index].gpod4;
+        }
+    }
+
+
+    DEBUG ((EFI_D_INFO, "Set PAD_VAL = 0x%08x, ", pad_val.dw));
+
+    MmioWrite32(mmio_padval, pad_val.dw);
+
+    //
+    // Step 2: CONF0 Programming
+    // Read GPIO default CONF0 value, which is assumed to be default value after reset.
+    //
+    conf0_val.dw = MmioRead32(mmio_conf0);
+
+    //
+    // Set Function #
+    //
+    conf0_val.r.Func_Pin_Mux = Gpio_Conf_Data[index].func;
+
+    if(GPO == Gpio_Conf_Data[index].usage)
+    {
+      //
+      // If used as GPO, then internal pull need to be disabled
+      //
+      conf0_val.r.Pull_assign = 0;  // Non-pull
+    }
+    else
+    {
+      //
+      // Set PullUp / PullDown
+      //
+      if(P_20K_H == Gpio_Conf_Data[index].pull)
+      {
+        conf0_val.r.Pull_assign = 0x1;  // PullUp
+        conf0_val.r.Pull_strength = 0x2;// 20K
+      }
+      else if(P_20K_L == Gpio_Conf_Data[index].pull)
+      {
+        conf0_val.r.Pull_assign = 0x2;  // PullDown
+        conf0_val.r.Pull_strength = 0x2;// 20K
+      }
+      else if(P_NONE == Gpio_Conf_Data[index].pull)
+      {
+        conf0_val.r.Pull_assign = 0;	// Non-pull
+      }
+      else
+      {
+        ASSERT(FALSE);  // Invalid value
+      }
+    }
+
+    //
+    // Set INT Trigger Type
+    //
+    conf0_val.dw &= ~0x0f000000;  // Clear bits 27:24
+
+    //
+    // Set INT Trigger Type
+    //
+    if(TRIG_ == Gpio_Conf_Data[index].int_type)
+    {
+      //
+      // Interrupt not capable, clear bits 27:24
+      //
+    }
+    else
+    {
+      conf0_val.dw |= (Gpio_Conf_Data[index].int_type & 0x0f)<<24;
+    }
+
+    DEBUG ((EFI_D_INFO, "Set CONF0 = 0x%08x\n", conf0_val.dw));
+
+    //
+    // Write back the targeted GPIO config value according to platform (board) GPIO setting
+    //
+    MmioWrite32 (mmio_conf0, conf0_val.dw);
+  }
+
+  // A0 BIOS Spec doesn't mention it although X0 does. comment out now.
+  // GPIO SCORE write 0x01001002 to IOBASE + 0x0900
+  //
+}
+
+VOID
+EFIAPI
+SpiBiosProtectionFunction(
+  EFI_EVENT Event,
+  VOID      *Context
+  )
+{
+
+  UINTN                             mPciD31F0RegBase;
+  UINTN                             BiosFlaLower0;
+  UINTN                             BiosFlaLimit0;
+  UINTN                             BiosFlaLower1;
+  UINTN                             BiosFlaLimit1;  
+  
+
+  BiosFlaLower0 = PcdGet32(PcdFlashMicroCodeAddress)-PcdGet32(PcdFlashAreaBaseAddress);
+  BiosFlaLimit0 = PcdGet32(PcdFlashMicroCodeSize)-1;  
+  #ifdef MINNOW2_FSP_BUILD
+  BiosFlaLower1 = PcdGet32(PcdFlashFvFspBase)-PcdGet32(PcdFlashAreaBaseAddress);
+  BiosFlaLimit1 = (PcdGet32(PcdFlashFvRecoveryBase)-PcdGet32(PcdFlashFvFspBase)+PcdGet32(PcdFlashFvRecoverySize))-1;
+  #else
+  BiosFlaLower1 = PcdGet32(PcdFlashFvMainBase)-PcdGet32(PcdFlashAreaBaseAddress);
+  BiosFlaLimit1 = (PcdGet32(PcdFlashFvRecoveryBase)-PcdGet32(PcdFlashFvMainBase)+PcdGet32(PcdFlashFvRecoverySize))-1;
+  #endif
+
+  
+  mPciD31F0RegBase = MmPciAddress (0,
+                         DEFAULT_PCI_BUS_NUMBER_PCH,
+                         PCI_DEVICE_NUMBER_PCH_LPC,
+                         PCI_FUNCTION_NUMBER_PCH_LPC,
+                         0
+                       );
+  SpiBase          = MmioRead32(mPciD31F0RegBase + R_PCH_LPC_SPI_BASE) & B_PCH_LPC_SPI_BASE_BAR;
+
+  //
+  //Set SMM_BWP, WPD and LE bit
+  //
+  MmioOr32 ((UINTN) (SpiBase + R_PCH_SPI_BCR), (UINT8) B_PCH_SPI_BCR_SMM_BWP);
+  MmioAnd32 ((UINTN) (SpiBase + R_PCH_SPI_BCR), (UINT8)(~B_PCH_SPI_BCR_BIOSWE));
+  MmioOr32 ((UINTN) (SpiBase + R_PCH_SPI_BCR), (UINT8) B_PCH_SPI_BCR_BLE);
+
+  //
+  //First check if FLOCKDN or PR0FLOCKDN is set. No action if either of them set already.
+  //
+  if( (MmioRead16(SpiBase + R_PCH_SPI_HSFS) & B_PCH_SPI_HSFS_FLOCKDN) != 0 ||
+      (MmioRead32(SpiBase + R_PCH_SPI_IND_LOCK)& B_PCH_SPI_IND_LOCK_PR0) != 0) {
+    //
+    //Already locked. we could take no action here
+    //
+    DEBUG((EFI_D_INFO, "PR0 already locked down. Stop configuring PR0.\n"));
+    return;
+  }
+
+  //
+  //Set PR0
+  //
+  MmioOr32((UINTN)(SpiBase + R_PCH_SPI_PR0),
+    B_PCH_SPI_PR0_RPE|B_PCH_SPI_PR0_WPE|\
+    (B_PCH_SPI_PR0_PRB_MASK&(BiosFlaLower0>>12))|(B_PCH_SPI_PR0_PRL_MASK&(BiosFlaLimit0>>12)<<16));
+
+  //
+  //Set PR1
+  //
+
+  MmioOr32((UINTN)(SpiBase + R_PCH_SPI_PR1),
+    B_PCH_SPI_PR1_RPE|B_PCH_SPI_PR1_WPE|\
+    (B_PCH_SPI_PR1_PRB_MASK&(BiosFlaLower1>>12))|(B_PCH_SPI_PR1_PRL_MASK&(BiosFlaLimit1>>12)<<16));
+
+  //
+  //Lock down PRx
+  //
+  MmioOr16 ((UINTN) (SpiBase + R_PCH_SPI_HSFS), (UINT16) (B_PCH_SPI_HSFS_FLOCKDN));
+
+  //
+  // Verify if it's really locked.
+  //
+  if ((MmioRead16 (SpiBase + R_PCH_SPI_HSFS) & B_PCH_SPI_HSFS_FLOCKDN) == 0) {
+    DEBUG((EFI_D_ERROR, "Failed to lock down PRx.\n"));
+  }
+  return;
+
+}
+
+VOID
+EFIAPI
+InitPciDevPME (
+  EFI_EVENT  Event,
+  VOID       *Context
+  )
+{
+  UINTN                  VarSize;
+
+  VarSize = sizeof(SYSTEM_CONFIGURATION);
+  gRT->GetVariable(
+         NORMAL_SETUP_NAME,
+         &gEfiNormalSetupGuid,
+         NULL,
+         &VarSize,
+         &mSystemConfiguration
+         );
+
+  //
+  //Program HDA PME_EN
+  //
+  PchAzaliaPciCfg32Or (R_PCH_HDA_PCS, B_PCH_HDA_PCS_PMEE);
+
+  //
+  //Program SATA PME_EN
+  //
+  PchSataPciCfg32Or (R_PCH_SATA_PMCS, B_PCH_SATA_PMCS_PMEE);
+
+  DEBUG ((EFI_D_INFO, "InitPciDevPME mSystemConfiguration.EhciPllCfgEnable = 0x%x \n",mSystemConfiguration.EhciPllCfgEnable));
+ if (mSystemConfiguration.EhciPllCfgEnable != 1) {
+  //
+  //Program EHCI PME_EN
+  //
+  PchMmPci32Or (
+    0,
+    0,
+    PCI_DEVICE_NUMBER_PCH_USB,
+    PCI_FUNCTION_NUMBER_PCH_EHCI,
+    R_PCH_EHCI_PWR_CNTL_STS,
+    B_PCH_EHCI_PWR_CNTL_STS_PME_EN
+    );
+ }
+   {
+     UINTN                 EhciPciMmBase;
+     UINT32                Buffer32 = 0;
+
+    EhciPciMmBase = MmPciAddress (0,
+                      0,
+                      PCI_DEVICE_NUMBER_PCH_USB,
+                      PCI_FUNCTION_NUMBER_PCH_EHCI,
+                      0
+                    );
+    DEBUG ((EFI_D_INFO, "ConfigureAdditionalPm() EhciPciMmBase = 0x%x \n",EhciPciMmBase));
+    Buffer32 = MmioRead32(EhciPciMmBase + R_PCH_EHCI_PWR_CNTL_STS);
+    DEBUG ((EFI_D_INFO, "ConfigureAdditionalPm() R_PCH_EHCI_PWR_CNTL_STS = 0x%x \n",Buffer32));
+  }
+}
+
+VOID
+EFIAPI
+InitThermalZone (
+  EFI_EVENT  Event,
+  VOID       *Context
+  )
+{
+  UINTN                  VarSize;
+  EFI_GLOBAL_NVS_AREA_PROTOCOL       *GlobalNvsArea;
+  VarSize = sizeof(SYSTEM_CONFIGURATION);
+  gRT->GetVariable(
+         NORMAL_SETUP_NAME,
+         &gEfiNormalSetupGuid,
+         NULL,
+         &VarSize,
+         &mSystemConfiguration
+         );
+  gBS->LocateProtocol (
+         &gEfiGlobalNvsAreaProtocolGuid,
+         NULL,
+         (void **)&GlobalNvsArea
+         );
+  GlobalNvsArea->Area->CriticalThermalTripPoint = mSystemConfiguration.CriticalThermalTripPoint;
+  GlobalNvsArea->Area->PassiveThermalTripPoint = mSystemConfiguration.PassiveThermalTripPoint;
+}
+#if defined SUPPORT_LVDS_DISPLAY && SUPPORT_LVDS_DISPLAY
+
+#endif
+
+
+EFI_STATUS
+EFIAPI
+TristateLpcGpioS0i3Config (
+  UINT32             Gpio_Mmio_Offset,
+  UINT32             Gpio_Pin_Num,
+  CFIO_PNP_INIT*   Gpio_Conf_Data
+  )
+{
+
+  UINT32	  index;
+  UINT32	  mmio_reg;
+  UINT32	  mmio_val;
+
+    DEBUG ((DEBUG_INFO, "TristateLpcGpioS0i3Config\n"));
+
+    for(index=0; index < Gpio_Pin_Num; index++)
+    {
+      mmio_reg = IO_BASE_ADDRESS + Gpio_Mmio_Offset + Gpio_Conf_Data[index].offset;
+
+      MmioWrite32(mmio_reg, Gpio_Conf_Data[index].val);
+      mmio_val = 0;
+      mmio_val = MmioRead32(mmio_reg);
+
+      DEBUG ((EFI_D_INFO, "Set MMIO=0x%08x  PAD_VAL = 0x%08x,\n", mmio_reg, mmio_val));
+    }
+
+     return EFI_SUCCESS;
+}
+
+
+EFI_BOOT_SCRIPT_SAVE_PROTOCOL *mBootScriptSave;
+
+/**
+  Event Notification during exit boot service to enabel ACPI mode
+
+   Disable SW SMI Timer, SMI from USB & Intel Specific USB 2
+
+   Clear all ACPI event status and disable all ACPI events
+   Disable PM sources except power button
+   Clear status bits
+
+   Guarantee day-of-month alarm is invalid (ACPI 5.0 Section 4.8.2.4 "Real Time Clock Alarm")
+
+   Update EC to disable SMI and enable SCI
+
+   Enable SCI
+
+   Enable PME_B0_EN in GPE0a_EN
+
+  @param Event  - EFI Event Handle
+  @param Context - Pointer to Notify Context
+
+  @retval  Nothing
+
+**/
+VOID
+EFIAPI
+EnableAcpiCallback (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  )
+{
+  UINT32  RegData32;
+  UINT16  Pm1Cnt;
+  UINT16  AcpiBase;
+  UINT32  Gpe0aEn;
+
+  AcpiBase = MmioRead16 (
+               PchPciDeviceMmBase (DEFAULT_PCI_BUS_NUMBER_PCH,
+               PCI_DEVICE_NUMBER_PCH_LPC,
+               PCI_FUNCTION_NUMBER_PCH_LPC) + R_PCH_LPC_ACPI_BASE
+               ) & B_PCH_LPC_ACPI_BASE_BAR;
+
+  DEBUG ((EFI_D_INFO, "EnableAcpiCallback: AcpiBase = %x\n", AcpiBase));
+
+  //
+  // Disable SW SMI Timer, SMI from USB & Intel Specific USB 2
+  //
+  RegData32 = IoRead32(AcpiBase + R_PCH_SMI_EN);
+  RegData32 &= ~(B_PCH_SMI_EN_SWSMI_TMR | B_PCH_SMI_EN_LEGACY_USB2 | B_PCH_SMI_EN_INTEL_USB2);
+  IoWrite32(AcpiBase + R_PCH_SMI_EN, RegData32);
+
+  RegData32 = IoRead32(AcpiBase + R_PCH_SMI_STS);
+  RegData32 |= B_PCH_SMI_STS_SWSMI_TMR;
+  IoWrite32(AcpiBase + R_PCH_SMI_STS, RegData32);
+
+  //
+  // Disable PM sources except power button
+  // power button is enabled only for PCAT. Disabled it on Tablet platform
+  //
+
+  IoWrite16(AcpiBase + R_PCH_ACPI_PM1_EN, B_PCH_ACPI_PM1_EN_PWRBTN);
+  IoWrite16(AcpiBase + R_PCH_ACPI_PM1_STS, 0xffff);
+
+  //
+  // Guarantee day-of-month alarm is invalid (ACPI 5.0 Section 4.8.2.4 "Real Time Clock Alarm")
+  // Clear Status D reg VM bit, Date of month Alarm to make Data in CMOS RAM is no longer Valid
+  //
+  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_D);
+  IoWrite8 (PCAT_RTC_DATA_REGISTER, 0x0);
+
+  RegData32 = IoRead32(AcpiBase + R_PCH_ALT_GP_SMI_EN);
+  RegData32 &= ~(BIT7);
+  IoWrite32((AcpiBase + R_PCH_ALT_GP_SMI_EN), RegData32);
+
+  //
+  // Enable SCI
+  //
+  Pm1Cnt = IoRead16(AcpiBase + R_PCH_ACPI_PM1_CNT);
+  Pm1Cnt |= B_PCH_ACPI_PM1_CNT_SCI_EN;
+  IoWrite16(AcpiBase + R_PCH_ACPI_PM1_CNT, Pm1Cnt);
+
+  IoWrite8(0x80, 0xA0);	//SW_SMI_ACPI_ENABLE
+
+  //
+  // Enable PME_B0_EN in GPE0a_EN
+  // Caution: Enable PME_B0_EN must be placed after enabling SCI.
+  // Otherwise, USB PME could not be handled as SMI event since no handler is there.
+  //
+  Gpe0aEn = IoRead32 (AcpiBase + R_PCH_ACPI_GPE0a_EN);
+  Gpe0aEn |= B_PCH_ACPI_GPE0a_EN_PME_B0;
+  IoWrite32(AcpiBase + R_PCH_ACPI_GPE0a_EN, Gpe0aEn);
+
+}
+
+/**
+
+  Routine Description:
+
+  This is the standard EFI driver point for the Driver. This
+  driver is responsible for setting up any platform specific policy or
+  initialization information.
+
+  @param ImageHandle    Handle for the image of this driver.
+  @param SystemTable    Pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS   Policy decisions set.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializePlatform (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS                          Status;
+  UINTN                               VarSize;
+  EFI_HANDLE                          Handle = NULL;
+  EFI_EVENT                           mEfiExitBootServicesEvent;
+  EFI_EVENT                           RtcEvent;
+  VOID                                *RtcCallbackReg = NULL;
+  
+  mImageHandle = ImageHandle;
+
+  Status = gBS->InstallProtocolInterface (
+                  &Handle,
+                  &gEfiSpeakerInterfaceProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &mSpeakerInterface
+                  );
+
+  Status = gBS->LocateProtocol (
+                  &gEfiPciRootBridgeIoProtocolGuid,
+                  NULL,
+                  (VOID **) &mPciRootBridgeIo
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  VarSize = sizeof(EFI_PLATFORM_INFO_HOB);
+  Status = gRT->GetVariable(
+                  L"PlatformInfo",
+                  &gEfiVlv2VariableGuid,
+                  NULL,
+                  &VarSize,
+                  &mPlatformInfo
+                  );
+
+  //
+  // Initialize Product Board ID variable
+  //
+  InitMfgAndConfigModeStateVar();
+  InitPlatformBootMode();
+
+  //
+  // Install Observable protocol
+  //
+  InitializeObservableProtocol();
+
+  Status = SaveSetupRecoveryVar();
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "InitializePlatform() Save SetupRecovery variable failed \n"));
+  }
+
+  VarSize = sizeof(SYSTEM_CONFIGURATION);
+  Status = gRT->GetVariable(
+                  NORMAL_SETUP_NAME,
+                  &gEfiNormalSetupGuid,
+                  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",
+              &gEfiNormalSetupGuid,
+              NULL,
+              &VarSize,
+              &mSystemConfiguration
+              );
+    ASSERT_EFI_ERROR (Status);
+    Status = gRT->SetVariable (
+                    NORMAL_SETUP_NAME,
+                    &gEfiNormalSetupGuid,
+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                    sizeof(SYSTEM_CONFIGURATION),
+                    &mSystemConfiguration
+                    );    
+  }
+    
+  Status = EfiCreateEventReadyToBootEx (
+             TPL_CALLBACK,
+             ReadyToBootFunction,
+             NULL,
+             &mReadyToBootEvent
+             );
+
+  //
+  // Create a ReadyToBoot Event to run the PME init process
+  //
+  Status = EfiCreateEventReadyToBootEx (
+             TPL_CALLBACK,
+             InitPciDevPME,
+             NULL,
+             &mReadyToBootEvent
+             );
+  //
+  // Create a ReadyToBoot Event to run enable PR0/PR1 and lock down,unlock variable region
+  //
+  if(mSystemConfiguration.SpiRwProtect==1) {
+    Status = EfiCreateEventReadyToBootEx (
+               TPL_CALLBACK,
+               SpiBiosProtectionFunction,
+               NULL,
+               &mReadyToBootEvent
+               );
+  }
+  //
+  // Create a ReadyToBoot Event to run the thermalzone init process
+  //
+  Status = EfiCreateEventReadyToBootEx (
+             TPL_CALLBACK,
+             InitThermalZone,
+             NULL,
+             &mReadyToBootEvent
+             );  
+ 
+  ReportStatusCodeEx (
+    EFI_PROGRESS_CODE,
+    EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_PLATFORM_DXE_STEP1,
+    0,
+    &gEfiCallerIdGuid,
+    NULL,
+    NULL,
+    0
+    );
+
+#if defined(SENSOR_INFO_VAR_SUPPORT) && SENSOR_INFO_VAR_SUPPORT != 0
+  //
+  // Initialize Sensor Info variable
+  //
+  InitializeSensorInfoVariable();
+#endif
+  InitPchPlatformPolicy(&mPlatformInfo);
+  InitVlvPlatformPolicy();
+
+  //
+  //  Add usb policy
+  //
+  InitPlatformUsbPolicy();
+  InitSioPlatformPolicy();
+  InitializeClockRouting();
+  InitializeSlotInfo();
+  InitTcoReset();
+
+  //
+  //Init ExI
+  //
+  InitExI();
+
+  ReportStatusCodeEx (
+    EFI_PROGRESS_CODE,
+    EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_PLATFORM_DXE_STEP2,
+    0,
+    &gEfiCallerIdGuid,
+    NULL,
+    NULL,
+    0
+    );
+
+  //
+  // Install PCI Bus Driver Hook
+  //
+  PciBusDriverHook();
+
+  InitItk();
+
+  ReportStatusCodeEx (
+    EFI_PROGRESS_CODE,
+    EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_PLATFORM_DXE_STEP3,
+    0,
+    &gEfiCallerIdGuid,
+    NULL,
+    NULL,
+    0
+    );
+
+
+  //
+  // Initialize Password States and Callbacks
+  //
+  PchInitBeforeBoot();
+
+#if defined SUPPORT_LVDS_DISPLAY && SUPPORT_LVDS_DISPLAY
+
+#endif
+
+#if defined(FIRMWARE_ID_BACKWARD_COMPATIBLE) && (FIRMWARE_ID_BACKWARD_COMPATIBLE != 0)
+  //
+  // Re-write Firmware ID if it is changed
+  //
+  InitFirmwareId();
+#endif
+
+  ReportStatusCodeEx (
+    EFI_PROGRESS_CODE,
+    EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_PLATFORM_DXE_STEP4,
+    0,
+    &gEfiCallerIdGuid,
+    NULL,
+    NULL,
+    0
+    );
+
+
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  EnableAcpiCallback,
+                  NULL,
+                  &gEfiEventExitBootServicesGuid,
+                  &mEfiExitBootServicesEvent
+                  );
+
+  //
+  // Adjust RTC deafult time to be BIOS-built time.
+  //
+  Status = gBS->CreateEvent (
+                    EVT_NOTIFY_SIGNAL,
+                    TPL_CALLBACK,
+                    AdjustDefaultRtcTimeCallback,
+                    NULL,
+                    &RtcEvent
+                    );
+  if (!EFI_ERROR (Status)) {
+      Status = gBS->RegisterProtocolNotify (
+                      &gExitPmAuthProtocolGuid,
+                      RtcEvent,
+                      &RtcCallbackReg
+                      );
+
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Source Or Destination with Length bytes.
+
+  @param[in] Destination   Target memory
+  @param[in] Source        Source memory
+  @param[in] Length        Number of bytes
+
+  @retval None
+
+**/
+VOID
+EfiOrMem (
+  IN VOID   *Destination,
+  IN VOID   *Source,
+  IN UINTN  Length
+  )
+{
+  CHAR8 *Destination8;
+  CHAR8 *Source8;
+
+  if (Source < Destination) {
+    Destination8  = (CHAR8 *) Destination + Length - 1;
+    Source8       = (CHAR8 *) Source + Length - 1;
+    while (Length--) {
+      *(Destination8--) |= *(Source8--);
+    }
+  } else {
+    Destination8  = (CHAR8 *) Destination;
+    Source8       = (CHAR8 *) Source;
+    while (Length--) {
+      *(Destination8++) |= *(Source8++);
+    }
+  }
+}
+
+VOID
+PchInitBeforeBoot()
+{
+  //
+  // Saved SPI Opcode menu to fix EFI variable unable to write after S3 resume.
+  //
+  S3BootScriptSaveMemWrite (
+                         EfiBootScriptWidthUint32,
+                         (UINTN)(SPI_BASE_ADDRESS + (R_PCH_SPI_OPMENU0)),
+                         1,
+                         (VOID *)(UINTN)(SPI_BASE_ADDRESS + (R_PCH_SPI_OPMENU0)));
+
+  S3BootScriptSaveMemWrite (
+                         EfiBootScriptWidthUint32,
+                         (UINTN)(SPI_BASE_ADDRESS + (R_PCH_SPI_OPMENU1)),
+                         1,
+                         (VOID *)(UINTN)(SPI_BASE_ADDRESS + (R_PCH_SPI_OPMENU1)));
+
+  S3BootScriptSaveMemWrite (
+                         EfiBootScriptWidthUint16,
+                         (UINTN)(SPI_BASE_ADDRESS + R_PCH_SPI_OPTYPE),
+                         1,
+                         (VOID *)(UINTN)(SPI_BASE_ADDRESS + R_PCH_SPI_OPTYPE));
+
+  S3BootScriptSaveMemWrite (
+                         EfiBootScriptWidthUint16,
+                         (UINTN)(SPI_BASE_ADDRESS + R_PCH_SPI_PREOP),
+                         1,
+                         (VOID *)(UINTN)(SPI_BASE_ADDRESS + R_PCH_SPI_PREOP));
+
+  //
+  // Saved MTPMC_1 for S3 resume.
+  //
+  S3BootScriptSaveMemWrite (
+                         EfiBootScriptWidthUint32,
+                         (UINTN)(PMC_BASE_ADDRESS + R_PCH_PMC_MTPMC1),
+                         1,
+                         (VOID *)(UINTN)(PMC_BASE_ADDRESS + R_PCH_PMC_MTPMC1));
+  return;
+}
+
+VOID
+EFIAPI
+ReadyToBootFunction (
+  EFI_EVENT  Event,
+  VOID       *Context
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_ISA_ACPI_PROTOCOL           *IsaAcpi;
+  EFI_ISA_ACPI_DEVICE_ID          IsaDevice;
+  UINTN                           Size;
+  UINT16                          State;
+  EFI_TPM_MP_DRIVER_PROTOCOL      *TpmMpDriver;
+  EFI_CPU_IO_PROTOCOL             *CpuIo;
+  UINT8                           Data;
+  UINT8                           ReceiveBuffer [64];
+  UINT32                          ReceiveBufferSize;
+
+  UINT8 TpmForceClearCommand [] =              {0x00, 0xC1,
+                                                0x00, 0x00, 0x00, 0x0A,
+                                                0x00, 0x00, 0x00, 0x5D};
+  UINT8 TpmPhysicalPresenceCommand [] =        {0x00, 0xC1,
+                                                0x00, 0x00, 0x00, 0x0C,
+                                                0x40, 0x00, 0x00, 0x0A,
+                                                0x00, 0x00};
+  UINT8 TpmPhysicalDisableCommand [] =         {0x00, 0xC1,
+                                                0x00, 0x00, 0x00, 0x0A,
+                                                0x00, 0x00, 0x00, 0x70};
+  UINT8 TpmPhysicalEnableCommand [] =          {0x00, 0xC1,
+                                                0x00, 0x00, 0x00, 0x0A,
+                                                0x00, 0x00, 0x00, 0x6F};
+  UINT8 TpmPhysicalSetDeactivatedCommand [] =  {0x00, 0xC1,
+                                                0x00, 0x00, 0x00, 0x0B,
+                                                0x00, 0x00, 0x00, 0x72,
+                                                0x00};
+  UINT8 TpmSetOwnerInstallCommand [] =         {0x00, 0xC1,
+                                                0x00, 0x00, 0x00, 0x0B,
+                                                0x00, 0x00, 0x00, 0x71,
+                                                0x00};
+
+  Size = sizeof(UINT16);
+  Status = gRT->GetVariable (
+                  VAR_EQ_FLOPPY_MODE_DECIMAL_NAME,
+                  &gEfiNormalSetupGuid,
+                  NULL,
+                  &Size,
+                  &State
+                  );
+
+  //
+  // Disable Floppy Controller if needed
+  //
+  Status = gBS->LocateProtocol (&gEfiIsaAcpiProtocolGuid, NULL, (VOID **) &IsaAcpi);
+  if (!EFI_ERROR(Status) && (State == 0x00)) {
+    IsaDevice.HID = EISA_PNP_ID(0x604);
+    IsaDevice.UID = 0;
+    Status = IsaAcpi->EnableDevice(IsaAcpi, &IsaDevice, FALSE);
+  }
+
+  //
+  // save LAN info to a variable
+  //
+  if (NULL != mPciLanInfo) {
+    gRT->SetVariable (
+           L"PciLanInfo",
+           &gEfiPciLanInfoGuid,
+           EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+           mPciLanCount * sizeof(PCI_LAN_INFO),
+           mPciLanInfo
+           );
+  }
+
+  if (NULL != mPciLanInfo) {
+    gBS->FreePool (mPciLanInfo);
+    mPciLanInfo = NULL;
+  }
+  
+
+  //
+  // Handle ACPI OS TPM requests here
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiCpuIoProtocolGuid,
+                  NULL,
+                  (VOID **)&CpuIo
+                  );
+  Status = gBS->LocateProtocol (
+                  &gEfiTpmMpDriverProtocolGuid,
+                  NULL,
+                  (VOID **)&TpmMpDriver
+                  );
+  if (!EFI_ERROR (Status))
+  {
+    Data = ReadCmosBank1Byte (CpuIo, ACPI_TPM_REQUEST);
+
+    //
+    // Clear pending ACPI TPM request indicator
+    //
+    WriteCmosBank1Byte (CpuIo, ACPI_TPM_REQUEST, 0x00);
+    if (Data != 0)
+    {
+      WriteCmosBank1Byte (CpuIo, ACPI_TPM_LAST_REQUEST, Data);
+
+      //
+      // Assert Physical Presence for these commands
+      //
+      TpmPhysicalPresenceCommand [11] = 0x20;
+      ReceiveBufferSize = sizeof(ReceiveBuffer);
+      Status = TpmMpDriver->Transmit (
+                              TpmMpDriver, TpmPhysicalPresenceCommand,
+                              sizeof (TpmPhysicalPresenceCommand),
+                              ReceiveBuffer, &ReceiveBufferSize
+                              );
+      //
+      // PF PhysicalPresence = TRUE
+      //
+      TpmPhysicalPresenceCommand [11] = 0x08;
+      ReceiveBufferSize = sizeof(ReceiveBuffer);
+      Status = TpmMpDriver->Transmit (
+                              TpmMpDriver, TpmPhysicalPresenceCommand,
+                              sizeof (TpmPhysicalPresenceCommand),
+                              ReceiveBuffer,
+                              &ReceiveBufferSize
+                              );
+      if (Data == 0x01)
+      {
+        //
+        // TPM_PhysicalEnable
+        //
+        ReceiveBufferSize = sizeof(ReceiveBuffer);
+        Status = TpmMpDriver->Transmit (
+                                TpmMpDriver, TpmPhysicalEnableCommand,
+                                sizeof (TpmPhysicalEnableCommand),
+                                ReceiveBuffer, &ReceiveBufferSize
+                                );
+      }
+      if (Data == 0x02)
+      {
+        //
+        // TPM_PhysicalDisable
+        //
+        ReceiveBufferSize = sizeof(ReceiveBuffer);
+        Status = TpmMpDriver->Transmit (
+                                TpmMpDriver, TpmPhysicalDisableCommand,
+                                sizeof (TpmPhysicalDisableCommand),
+                                ReceiveBuffer,
+                                &ReceiveBufferSize
+                                );
+      }
+      if (Data == 0x03)
+      {
+        //
+        // TPM_PhysicalSetDeactivated=FALSE
+        //
+        ReceiveBufferSize = sizeof(ReceiveBuffer);
+        TpmPhysicalSetDeactivatedCommand [10] = 0x00;
+        Status = TpmMpDriver->Transmit (
+                                TpmMpDriver,
+                                TpmPhysicalSetDeactivatedCommand,
+                                sizeof (TpmPhysicalSetDeactivatedCommand),
+                                ReceiveBuffer, &ReceiveBufferSize
+                                );
+        gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
+      }
+      if (Data == 0x04)
+      {
+        //
+        // TPM_PhysicalSetDeactivated=TRUE
+        //
+        ReceiveBufferSize = sizeof(ReceiveBuffer);
+        TpmPhysicalSetDeactivatedCommand [10] = 0x01;
+        Status = TpmMpDriver->Transmit (
+                                TpmMpDriver,
+                                TpmPhysicalSetDeactivatedCommand,
+                                sizeof (TpmPhysicalSetDeactivatedCommand),
+                                ReceiveBuffer,
+                                &ReceiveBufferSize
+                                );
+        gRT->ResetSystem (
+               EfiResetWarm,
+               EFI_SUCCESS,
+               0,
+               NULL
+               );
+      }
+      if (Data == 0x05)
+      {
+        //
+        // TPM_ForceClear
+        //
+        ReceiveBufferSize = sizeof(ReceiveBuffer);
+        Status = TpmMpDriver->Transmit (
+                                TpmMpDriver,
+                                TpmForceClearCommand,
+                                sizeof (TpmForceClearCommand),
+                                ReceiveBuffer,
+                                &ReceiveBufferSize
+                                );
+        gRT->ResetSystem (
+               EfiResetWarm,
+               EFI_SUCCESS,
+               0,
+               NULL
+               );
+      }
+      if (Data == 0x06)
+      {
+        //
+        // TPM_PhysicalEnable
+        //
+        ReceiveBufferSize = sizeof(ReceiveBuffer);
+        Status = TpmMpDriver->Transmit (
+                                TpmMpDriver,
+                                TpmPhysicalEnableCommand,
+                                sizeof (TpmPhysicalEnableCommand),
+                                ReceiveBuffer,
+                                &ReceiveBufferSize
+                                );
+        //
+        // TPM_PhysicalSetDeactivated=FALSE
+        //
+        ReceiveBufferSize = sizeof(ReceiveBuffer);
+        TpmPhysicalSetDeactivatedCommand [10] = 0x00;
+        Status = TpmMpDriver->Transmit (
+                                TpmMpDriver,
+                                TpmPhysicalSetDeactivatedCommand,
+                                sizeof (TpmPhysicalSetDeactivatedCommand),
+                                ReceiveBuffer,
+                                &ReceiveBufferSize
+                                );
+        gRT->ResetSystem (
+               EfiResetWarm,
+               EFI_SUCCESS,
+               0,
+               NULL
+               );
+      }
+      if (Data == 0x07)
+      {
+        //
+        // TPM_PhysicalSetDeactivated=TRUE
+        //
+        ReceiveBufferSize = sizeof(ReceiveBuffer);
+        TpmPhysicalSetDeactivatedCommand [10] = 0x01;
+        Status = TpmMpDriver->Transmit (
+                                TpmMpDriver,
+                                TpmPhysicalSetDeactivatedCommand,
+                                sizeof (TpmPhysicalSetDeactivatedCommand),
+                                ReceiveBuffer,
+                                &ReceiveBufferSize
+                                );
+        //
+        // TPM_PhysicalDisable
+        //
+        ReceiveBufferSize = sizeof(ReceiveBuffer);
+        Status = TpmMpDriver->Transmit (
+                                TpmMpDriver,
+                                TpmPhysicalDisableCommand,
+                                sizeof (TpmPhysicalDisableCommand),
+                                ReceiveBuffer,
+                                &ReceiveBufferSize
+                                );
+        gRT->ResetSystem (
+               EfiResetWarm,
+               EFI_SUCCESS,
+               0,
+               NULL
+               );
+      }
+      if (Data == 0x08)
+      {
+        //
+        // TPM_SetOwnerInstall=TRUE
+        //
+        ReceiveBufferSize = sizeof(ReceiveBuffer);
+        TpmSetOwnerInstallCommand [10] = 0x01;
+        Status = TpmMpDriver->Transmit (
+                                TpmMpDriver,
+                                TpmSetOwnerInstallCommand,
+                                sizeof (TpmSetOwnerInstallCommand),
+                                ReceiveBuffer,
+                                &ReceiveBufferSize
+                                );
+      }
+      if (Data == 0x09)
+      {
+        //
+        // TPM_SetOwnerInstall=FALSE
+        //
+        ReceiveBufferSize = sizeof(ReceiveBuffer);
+        TpmSetOwnerInstallCommand [10] = 0x00;
+        Status = TpmMpDriver->Transmit (
+                                TpmMpDriver,
+                                TpmSetOwnerInstallCommand,
+                                sizeof (TpmSetOwnerInstallCommand),
+                                ReceiveBuffer,
+                                &ReceiveBufferSize
+                                );
+      }
+      if (Data == 0x0A)
+      {
+        //
+        // TPM_PhysicalEnable
+        //
+        ReceiveBufferSize = sizeof(ReceiveBuffer);
+        Status = TpmMpDriver->Transmit (
+                                TpmMpDriver,
+                                TpmPhysicalEnableCommand,
+                                sizeof (TpmPhysicalEnableCommand),
+                                ReceiveBuffer,
+                                &ReceiveBufferSize
+                                );
+        //
+        // TPM_PhysicalSetDeactivated=FALSE
+        //
+        ReceiveBufferSize = sizeof(ReceiveBuffer);
+        TpmPhysicalSetDeactivatedCommand [10] = 0x00;
+        Status = TpmMpDriver->Transmit (
+                                TpmMpDriver,
+                                TpmPhysicalSetDeactivatedCommand,
+                                sizeof (TpmPhysicalSetDeactivatedCommand),
+                                ReceiveBuffer,
+                                &ReceiveBufferSize
+                                );
+        //
+        // Do TPM_SetOwnerInstall=TRUE on next reboot
+        //
+
+        WriteCmosBank1Byte (CpuIo, ACPI_TPM_REQUEST, 0xF0);
+
+        gRT->ResetSystem (
+               EfiResetWarm,
+               EFI_SUCCESS,
+               0,
+               NULL
+               );
+      }
+      if (Data == 0x0B)
+      {
+        //
+        // TPM_SetOwnerInstall=FALSE
+        //
+        ReceiveBufferSize = sizeof(ReceiveBuffer);
+        TpmSetOwnerInstallCommand [10] = 0x00;
+        Status = TpmMpDriver->Transmit (
+                                TpmMpDriver,
+                                TpmSetOwnerInstallCommand,
+                                sizeof (TpmSetOwnerInstallCommand),
+                                ReceiveBuffer,
+                                &ReceiveBufferSize
+                                );
+        //
+        // TPM_PhysicalSetDeactivated=TRUE
+        //
+        ReceiveBufferSize = sizeof(ReceiveBuffer);
+        TpmPhysicalSetDeactivatedCommand [10] = 0x01;
+        Status = TpmMpDriver->Transmit (
+                                TpmMpDriver,
+                                TpmPhysicalSetDeactivatedCommand,
+                                sizeof (TpmPhysicalSetDeactivatedCommand),
+                                ReceiveBuffer,
+                                &ReceiveBufferSize
+                                );
+        //
+        // TPM_PhysicalDisable
+        //
+        ReceiveBufferSize = sizeof(ReceiveBuffer);
+        Status = TpmMpDriver->Transmit (
+                                TpmMpDriver,
+                                TpmPhysicalDisableCommand,
+                                sizeof (TpmPhysicalDisableCommand),
+                                ReceiveBuffer,
+                                &ReceiveBufferSize
+                                );
+        gRT->ResetSystem (
+               EfiResetWarm,
+               EFI_SUCCESS,
+               0,
+               NULL
+               );
+      }
+      if (Data == 0x0E)
+      {
+        //
+        // TPM_ForceClear
+        //
+        ReceiveBufferSize = sizeof(ReceiveBuffer);
+        Status = TpmMpDriver->Transmit (
+                                TpmMpDriver,
+                                TpmForceClearCommand,
+                                sizeof (TpmForceClearCommand),
+                                ReceiveBuffer,
+                                &ReceiveBufferSize
+                                );
+        //
+        // TPM_PhysicalEnable
+        //
+        ReceiveBufferSize = sizeof(ReceiveBuffer);
+        Status = TpmMpDriver->Transmit (
+                                TpmMpDriver,
+                                TpmPhysicalEnableCommand,
+                                sizeof (TpmPhysicalEnableCommand),
+                                ReceiveBuffer,
+                                &ReceiveBufferSize
+                                );
+        //
+        // TPM_PhysicalSetDeactivated=FALSE
+        //
+        ReceiveBufferSize = sizeof(ReceiveBuffer);
+        TpmPhysicalSetDeactivatedCommand [10] = 0x00;
+        Status = TpmMpDriver->Transmit (
+                                TpmMpDriver,
+                                TpmPhysicalSetDeactivatedCommand,
+                                sizeof (TpmPhysicalSetDeactivatedCommand),
+                                ReceiveBuffer,
+                                &ReceiveBufferSize
+                                );
+        gRT->ResetSystem (
+               EfiResetWarm,
+               EFI_SUCCESS,
+               0,
+               NULL
+               );
+      }
+      if (Data == 0xF0)
+      {
+        //
+        // Second part of ACPI TPM request 0x0A: OEM custom TPM_SetOwnerInstall=TRUE
+        //
+        ReceiveBufferSize = sizeof(ReceiveBuffer);
+        TpmSetOwnerInstallCommand [10] = 0x01;
+        Status = TpmMpDriver->Transmit (
+                                TpmMpDriver,
+                                TpmSetOwnerInstallCommand,
+                                sizeof (TpmSetOwnerInstallCommand),
+                                ReceiveBuffer,
+                                &ReceiveBufferSize
+                                );
+        WriteCmosBank1Byte (CpuIo, ACPI_TPM_LAST_REQUEST, 0x0A);
+      }
+      //
+      // Deassert Physical Presence
+      //
+      TpmPhysicalPresenceCommand [11] = 0x10;
+      ReceiveBufferSize = sizeof(ReceiveBuffer);
+      Status = TpmMpDriver->Transmit (
+                              TpmMpDriver,
+                              TpmPhysicalPresenceCommand,
+                              sizeof (TpmPhysicalPresenceCommand),
+                              ReceiveBuffer,
+                              &ReceiveBufferSize
+                              );
+    }
+  }
+
+  return;
+}
+
+/**
+
+  Initializes manufacturing and config mode setting.
+
+**/
+VOID
+InitMfgAndConfigModeStateVar()
+{
+  EFI_PLATFORM_SETUP_ID           *BootModeBuffer;
+  VOID                            *HobList;
+
+
+  HobList = GetFirstGuidHob(&gEfiPlatformBootModeGuid);
+  if (HobList != NULL) {
+    BootModeBuffer = GET_GUID_HOB_DATA (HobList);
+
+      //
+      // Check if in Manufacturing mode
+      //
+      if ( !CompareMem (
+              &BootModeBuffer->SetupName,
+              MANUFACTURE_SETUP_NAME,
+              StrSize (MANUFACTURE_SETUP_NAME)
+              ) ) {
+        mMfgMode = TRUE;
+      }
+
+
+
+  }
+
+}
+
+/**
+
+  Initializes manufacturing and config mode setting.
+
+**/
+VOID
+InitPlatformBootMode()
+{
+  EFI_PLATFORM_SETUP_ID           *BootModeBuffer;
+  VOID                            *HobList;
+
+  HobList = GetFirstGuidHob(&gEfiPlatformBootModeGuid);
+  if (HobList != NULL) {
+    BootModeBuffer = GET_GUID_HOB_DATA (HobList);
+    mPlatformBootMode = BootModeBuffer->PlatformBootMode;
+  }
+}
+
+/**
+
+  Initializes ITK.
+
+**/
+VOID
+InitItk(
+  )
+{
+  EFI_STATUS                          Status;
+  UINT16                              ItkModBiosState;
+  UINT8                               Value;
+  UINTN                               DataSize;
+  UINT32                              Attributes;
+
+  //
+  // Setup local variable according to ITK variable
+  //
+  //
+  // Read ItkBiosModVar to determine if BIOS has been modified by ITK
+  // If ItkBiosModVar = 0 or if variable hasn't been initialized then BIOS has not been modified by ITK modified
+  // Set local variable VAR_EQ_ITK_BIOS_MOD_DECIMAL_NAME=0 if BIOS has not been modified by ITK
+  //
+  DataSize = sizeof (Value);
+  Status = gRT->GetVariable (
+                  ITK_BIOS_MOD_VAR_NAME,
+                  &gItkDataVarGuid,
+                  &Attributes,
+                  &DataSize,
+                  &Value
+                  );
+  if (Status == EFI_NOT_FOUND) {
+    //
+    // Variable not found, hasn't been initialized, intialize to 0
+    //
+    Value=0x00;
+  //
+  // Write variable to flash.
+  //
+  gRT->SetVariable (
+         ITK_BIOS_MOD_VAR_NAME,
+         &gItkDataVarGuid,
+         EFI_VARIABLE_RUNTIME_ACCESS |
+         EFI_VARIABLE_NON_VOLATILE |
+         EFI_VARIABLE_BOOTSERVICE_ACCESS,
+         sizeof (Value),
+         &Value
+         );
+
+}
+  if ( (!EFI_ERROR (Status)) || (Status == EFI_NOT_FOUND) ) {
+    if (Value == 0x00) {
+      ItkModBiosState = 0x00;
+    } else {
+      ItkModBiosState = 0x01;
+    }
+    gRT->SetVariable (
+           VAR_EQ_ITK_BIOS_MOD_DECIMAL_NAME,
+           &gEfiNormalSetupGuid,
+           EFI_VARIABLE_BOOTSERVICE_ACCESS,
+           2,
+           (void *)&ItkModBiosState
+           );
+  }
+}
+
+#if defined(FIRMWARE_ID_BACKWARD_COMPATIBLE) && (FIRMWARE_ID_BACKWARD_COMPATIBLE != 0)
+
+/**
+
+  Initializes the BIOS FIRMWARE ID from the FIRMWARE_ID build variable.
+
+**/
+STATIC
+VOID
+InitFirmwareId(
+  )
+{
+  EFI_STATUS   Status;
+  CHAR16       FirmwareIdNameWithPassword[] = FIRMWARE_ID_NAME_WITH_PASSWORD;
+
+  //
+  // First try writing the variable without a password in case we are
+  // upgrading from a BIOS without password protection on the FirmwareId
+  //
+  Status = gRT->SetVariable(
+                  (CHAR16 *)&gFirmwareIdName,
+                  &gFirmwareIdGuid,
+                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS |
+                  EFI_VARIABLE_RUNTIME_ACCESS,
+                  sizeof( FIRMWARE_ID ) - 1,
+                  FIRMWARE_ID
+                  );
+
+  if (Status == EFI_INVALID_PARAMETER) {
+
+    //
+    // Since setting the firmware id without the password failed,
+    // a password must be required.
+    //
+    Status = gRT->SetVariable(
+                    (CHAR16 *)&FirmwareIdNameWithPassword,
+                    &gFirmwareIdGuid,
+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS |
+                    EFI_VARIABLE_RUNTIME_ACCESS,
+                    sizeof( FIRMWARE_ID ) - 1,
+                    FIRMWARE_ID
+                    );
+  }
+}
+#endif
+
+VOID
+UpdateDVMTSetup(
+  )
+{
+    //
+  // Workaround to support IIA bug.
+  // IIA request to change option value to 4, 5 and 7 relatively
+  // instead of 1, 2, and 3 which follow Lakeport Specs.
+  // Check option value, temporary hardcode GraphicsDriverMemorySize
+  // Option value to fulfill IIA requirment. So that user no need to
+  // load default and update setupvariable after update BIOS.
+  //   Option value hardcoded as: 1 to 4, 2 to 5, 3 to 7.
+  // *This is for broadwater and above product only.
+  //
+
+  SYSTEM_CONFIGURATION        SystemConfiguration;
+  UINTN                       VarSize;
+  EFI_STATUS                  Status;
+
+  VarSize = sizeof(SYSTEM_CONFIGURATION);
+  Status = gRT->GetVariable(
+                  NORMAL_SETUP_NAME,
+                  &gEfiNormalSetupGuid,
+                  NULL,
+                  &VarSize,
+                  &SystemConfiguration
+                  );
+
+  if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
+    //The setup variable is corrupted
+    VarSize = sizeof(SYSTEM_CONFIGURATION);
+    Status = gRT->GetVariable(
+              L"SetupRecovery",
+              &gEfiNormalSetupGuid,
+              NULL,
+              &VarSize,
+              &SystemConfiguration
+              );
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  if((SystemConfiguration.GraphicsDriverMemorySize < 4) && !EFI_ERROR(Status) ) {
+    switch (SystemConfiguration.GraphicsDriverMemorySize){
+      case 1:
+        SystemConfiguration.GraphicsDriverMemorySize = 4;
+        break;
+      case 2:
+        SystemConfiguration.GraphicsDriverMemorySize = 5;
+        break;
+      case 3:
+        SystemConfiguration.GraphicsDriverMemorySize = 7;
+        break;
+      default:
+        break;
+     }
+
+    Status = gRT->SetVariable (
+                    NORMAL_SETUP_NAME,
+                    &gEfiNormalSetupGuid,
+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                    sizeof(SYSTEM_CONFIGURATION),
+                    &SystemConfiguration
+                    );
+  }
+}
+
+VOID
+InitPlatformUsbPolicy (
+  VOID
+  )
+
+{
+  EFI_HANDLE              Handle;
+  EFI_STATUS              Status;
+
+  Handle = NULL;
+
+  mUsbPolicyData.Version                       = (UINT8)USB_POLICY_PROTOCOL_REVISION_2;
+  mUsbPolicyData.UsbMassStorageEmulationType   = mSystemConfiguration.UsbBIOSINT13DeviceEmulation;
+  if(mUsbPolicyData.UsbMassStorageEmulationType == 3) {
+    mUsbPolicyData.UsbEmulationSize = mSystemConfiguration.UsbBIOSINT13DeviceEmulationSize;
+  } else {
+    mUsbPolicyData.UsbEmulationSize = 0;
+  }
+  mUsbPolicyData.UsbZipEmulationType         = mSystemConfiguration.UsbZipEmulation;
+  mUsbPolicyData.UsbOperationMode              = HIGH_SPEED;
+
+  //
+  //  Some chipset need Period smi, 0 = LEGACY_PERIOD_UN_SUPP
+  //
+  mUsbPolicyData.USBPeriodSupport      = LEGACY_PERIOD_UN_SUPP;
+
+  //
+  //  Some platform need legacyfree, 0 = LEGACY_FREE_UN_SUPP
+  //
+  mUsbPolicyData.LegacyFreeSupport    = LEGACY_FREE_UN_SUPP;
+
+  //
+  //  Set Code base , TIANO_CODE_BASE =0x01, ICBD =0x00
+  //
+  mUsbPolicyData.CodeBase    = (UINT8)ICBD_CODE_BASE;
+
+  //
+  //  Some chispet 's LpcAcpibase are diffrent,set by platform or chipset,
+  //  default is Ich  acpibase =0x040. acpitimerreg=0x08.
+  mUsbPolicyData.LpcAcpiBase     = 0x40;
+  mUsbPolicyData.AcpiTimerReg    = 0x08;
+
+  //
+  //  Set for reduce usb post time
+  //
+  mUsbPolicyData.UsbTimeTue           = 0x00;
+  mUsbPolicyData.InternelHubExist     = 0x00;  //TigerPoint doesn't have RMH
+  mUsbPolicyData.EnumWaitPortStableStall    = 100;
+
+
+  Status = gBS->InstallProtocolInterface (
+                  &Handle,
+                  &gUsbPolicyGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &mUsbPolicyData
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+}
+
+UINT8
+ReadCmosBank1Byte (
+  IN  EFI_CPU_IO_PROTOCOL             *CpuIo,
+  IN  UINT8                           Index
+  )
+{
+  UINT8                               Data;
+
+  CpuIo->Io.Write (CpuIo, EfiCpuIoWidthUint8, 0x72, 1, &Index);
+  CpuIo->Io.Read (CpuIo, EfiCpuIoWidthUint8, 0x73, 1, &Data);
+  return Data;
+}
+
+VOID
+WriteCmosBank1Byte (
+  IN  EFI_CPU_IO_PROTOCOL             *CpuIo,
+  IN  UINT8                           Index,
+  IN  UINT8                           Data
+  )
+{
+  CpuIo->Io.Write (
+              CpuIo,
+              EfiCpuIoWidthUint8,
+              0x72,
+              1,
+              &Index
+              );
+  CpuIo->Io.Write (
+              CpuIo,
+              EfiCpuIoWidthUint8,
+              0x73,
+              1,
+              &Data
+              );
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.h b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.h
new file mode 100644
index 0000000000..8f5df3257e
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.h
@@ -0,0 +1,722 @@
+/*++
+
+  Copyright (c) 2004  - 2015, Intel Corporation. All rights reserved.<BR>
+                                                                                   
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+                                                                                   
+
+
+Module Name:
+
+  PlatformDxe.h
+
+Abstract:
+
+  Header file for Platform Initialization Driver.
+
+
+
+++*/
+
+#ifndef _PLATFORM_DRIVER_H
+#define _PLATFORM_DRIVER_H
+
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/PcdLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/IoLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/HobLib.h>
+#include <Library/EfiRegTableLib.h>
+#include <Library/Tpm2CommandLib.h>
+#include <Library/Tpm2DeviceLib.h>
+#include <Library/BaseCryptLib.h>
+#include <Library/BiosIdLib.h>
+#include <Protocol/GlobalNvsArea.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/IsaAcpi.h>
+#include <Framework/FrameworkInternalFormRepresentation.h>
+#include <Protocol/FrameworkHii.h>
+#include <Protocol/FrameworkFormCallback.h>
+#include <Protocol/CpuIo.h>
+#include <Protocol/BootScriptSave.h>
+#include <Framework/BootScript.h>
+#include <Guid/GlobalVariable.h>
+#include <Guid/BoardFeatures.h>
+#include <Guid/DataHubRecords.h>
+#include <Protocol/DataHub.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/Speaker.h>
+#include <Protocol/ExitPmAuth.h>
+#include <IndustryStandard/Pci22.h>
+#include <Guid/SetupVariable.h>
+#include <Guid/PlatformInfo.h>
+#include "Configuration.h"
+#define _EFI_H_    //skip efi.h
+#include "PchAccess.h"
+#include "VlvAccess.h"
+#include "BoardIdDecode.h"
+#include "PlatformBaseAddresses.h"
+#include "SetupMode.h"
+#include "PlatformBootMode.h"
+#include "CpuType.h"
+
+#define PCAT_RTC_ADDRESS_REGISTER   0x74
+#define PCAT_RTC_DATA_REGISTER      0x75
+
+#define RTC_ADDRESS_SECOND_ALARM    0x01
+#define RTC_ADDRESS_MINUTE_ALARM    0x03
+#define RTC_ADDRESS_HOUR_ALARM      0x05
+
+#define RTC_ADDRESS_REGISTER_A      0x0A
+#define RTC_ADDRESS_REGISTER_B      0x0B
+#define RTC_ADDRESS_REGISTER_C      0x0C
+#define RTC_ADDRESS_REGISTER_D      0x0D
+
+#define B_RTC_ALARM_INT_ENABLE      0x20
+#define B_RTC_ALARM_INT_STATUS      0x20
+
+#define B_RTC_DATE_ALARM_MASK       0x3F
+
+//
+// Default CPU Alternate Duty Cycle (255=100%, 0=0%)
+//
+#define DEF_CPU_ALT_DUTY_CYCLE 0xFF
+
+#define MAX_ONBOARD_SATA_DEVICE 2
+
+#define DXE_DEVICE_ENABLED  1
+#define DXE_DEVICE_DISABLED 0
+
+#define AZALIA_MAX_LOOP_TIME  0x10000
+
+//
+// Platform driver GUID
+//
+#define EFI_PLATFORM_DRIVER_GUID \
+  { 0x056E7324, 0xA718, 0x465b, 0x9A, 0x84, 0x22, 0x8F, 0x06, 0x64, 0x2B, 0x4F }
+
+#define PASSWORD_MAX_SIZE               20
+#define PLATFORM_NORMAL_MODE          0x01
+#define PLATFORM_SAFE_MODE            0x02
+#define PLATFORM_RECOVERY_MODE        0x04
+#define PLATFORM_MANUFACTURING_MODE   0x08
+#define PLATFORM_BACK_TO_BIOS_MODE    0x10
+
+#define EFI_OEM_SPECIFIC      0x8000
+#define EFI_CU_PLATFORM_DXE_INIT                     (EFI_OEM_SPECIFIC | 0x00000011)
+#define EFI_CU_PLATFORM_DXE_STEP1                    (EFI_OEM_SPECIFIC | 0x00000012)
+#define EFI_CU_PLATFORM_DXE_STEP2                    (EFI_OEM_SPECIFIC | 0x00000013)
+#define EFI_CU_PLATFORM_DXE_STEP3                    (EFI_OEM_SPECIFIC | 0x00000014)
+#define EFI_CU_PLATFORM_DXE_STEP4                    (EFI_OEM_SPECIFIC | 0x00000015)
+#define EFI_CU_PLATFORM_DXE_INIT_DONE                (EFI_OEM_SPECIFIC | 0x00000016)
+
+
+#define EFI_SECTION_STRING                  0x1C
+#define EFI_FORWARD_DECLARATION(x) typedef struct _##x x
+#define PREFIX_BLANK                        0x04
+
+#pragma pack(1)
+
+typedef UINT64 EFI_BOARD_FEATURES;
+
+//
+//BUGBUG: should remove these EDK hii definition once Hii transtion is done
+//
+typedef UINT16  STRING_REF;
+typedef UINT16  EFI_FORM_LABEL;
+
+typedef enum {
+  EfiUserPassword,
+  EfiAdminPassword
+} EFI_PASSWORD_TYPE;
+
+typedef struct {
+  CHAR16            TempPassword[PASSWORD_MAX_SIZE];
+  CHAR16            EncodedPassword[PASSWORD_MAX_SIZE];
+  VOID              *PasswordLocation;
+  EFI_PASSWORD_TYPE PasswordType;
+} EFI_PASSWORD_DATA;
+
+typedef struct {
+  CHAR8 AaNumber[7];
+  UINT8 BoardId;
+  EFI_BOARD_FEATURES Features;
+  UINT16 SubsystemDeviceId;
+  UINT16 AudioSubsystemDeviceId;
+  UINT64 AcpiOemTableId;
+} BOARD_ID_DECODE;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FORM_ROUTINE) (
+  SYSTEM_CONFIGURATION *SetupBuffer
+  );
+
+typedef struct{
+  UINT16 DeviceNumber;
+  UINT16 FunctionNumber;
+}PCI_DEVICE_FUNC_INFO;
+
+typedef struct{
+  CHAR16 PortNumber[4];
+  STRING_REF SataDeviceInfoStringId;
+}SATA_DEVICE_STRING_INFO;
+
+typedef struct {
+  UINT16  Signature;
+  UINT8   Size;
+  UINT32  EntryPoint;
+  UINT8   Reserve[17];
+  UINT16  PciDataOff;
+  UINT16  ExpansionOff;
+} PNP_OPTION_ROM_HEADER;
+
+typedef struct {
+  UINT32  Signature;
+  UINT8   Revision;
+  UINT8   Length;
+  UINT16  NextHeader;
+  UINT8   Reserve;
+  UINT8   CheckSum;
+  UINT32  DeviceId;
+  UINT16  ManufactureStrOff;
+  UINT16  ProductStrOff;
+} PNP_EXPANSION_HEADER;
+
+typedef struct {
+  BOOLEAN                         Enable;
+  UINT8                           VerbTableNum;
+  UINT16                          CodecSSID;
+  EFI_PHYSICAL_ADDRESS            HDABar;
+  EFI_PHYSICAL_ADDRESS            UpperHDABar;
+  UINT8                           SDIPresent;
+  BOOLEAN                         Pme;
+  BOOLEAN                         LegacyFrontPanelAudio;
+  BOOLEAN                         HighDefinitionFrontPanelAudio;
+} EFI_AZALIA_S3;
+
+//
+//following structs are from R8. Remove them once R8->R9 transition is done
+//
+typedef struct {
+  CHAR16      *OptionString;  // Passed in string to generate a token for in a truly dynamic form creation
+  STRING_REF  StringToken;    // This is used when creating a single op-code without generating a StringToken (have one already)
+  UINT16      Value;
+  UINT8       Flags;
+  UINT16      Key;
+} IFR_OPTION;
+
+
+
+typedef struct {
+  UINT8   Number;
+  UINT32  HorizontalResolution;
+  UINT32  VerticalResolution;
+} PANEL_RESOLUTION;
+
+#pragma pack()
+
+//
+// Prototypes
+//
+EFI_STATUS
+EFIAPI
+EfiMain (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  );
+
+EFI_STATUS
+ProcessEventLog (
+  );
+
+EFI_STATUS
+FindDataRecords (
+  );
+
+EFI_STATUS
+ProcessPasswords(
+  );
+
+VOID
+MemorySetup(
+  );
+
+
+UINTN
+EfiValueToString (
+  IN  OUT CHAR16  *Buffer,
+  IN  INT64       Value,
+  IN  UINTN       Flags,
+  IN  UINTN       Width
+  );
+
+VOID
+EFIAPI
+ReadyToBootFunction (
+  EFI_EVENT  Event,
+  VOID       *Context
+  );
+
+VOID
+InstallHiiDataAndGetSettings(
+  IN EFI_HII_STRING_PACK            *StringPack,
+      //
+  ... // 0 or more of => IN EFI_HII_IFR_PACK *IfrPack,
+      // Terminate list with NULL
+      //
+  );
+
+EFI_STATUS
+ReadOrInitSetupVariable(
+  IN UINTN         RequiredVariableSize,
+  IN UINTN         RequiredPasswordSize,
+  IN VOID          *DefaultData,
+  IN VOID          *MfgDefaultData,
+  OUT VOID         *SetupVariableData,
+  OUT VOID         *SystemPassword
+  );
+
+VOID
+EfiLogicalOrMem(
+  IN VOID   *Destination,
+  IN VOID   *Source,
+  IN UINTN  Length
+  );
+
+EFI_STATUS
+GetStringFromToken (
+  IN      EFI_GUID                  *ProducerGuid,
+  IN      STRING_REF                Token,
+  OUT     CHAR16                    **String
+  );
+
+UINT32
+ConvertBase2ToRaw (
+  IN  EFI_EXP_BASE2_DATA             *Data);
+
+UINT32
+ConvertBase10ToRaw (
+  IN  EFI_EXP_BASE10_DATA             *Data);
+
+CHAR16 *
+GetStringById (
+  IN  STRING_REF   Id,
+  EFI_HII_HANDLE   StringPackHandle
+  );
+
+VOID
+EFIAPI
+SetupDataFilter (
+  IN EFI_EVENT    Event,
+  IN VOID*        Context
+  );
+
+VOID
+EFIAPI
+IdeDataFilter (
+  IN EFI_EVENT    Event,
+  IN VOID*        Context
+  );
+
+VOID
+EFIAPI
+UpdateAhciRaidDiskInfo (
+  IN EFI_EVENT    Event,
+  IN VOID*        Context
+  );
+
+VOID
+EFIAPI
+EventLogFilter (
+  IN EFI_EVENT    Event,
+  IN VOID*        Context
+  );
+
+VOID
+SwapEntries (
+  IN  CHAR8 *Data
+  );
+
+VOID
+AsciiToUnicode (
+  IN    CHAR8     *AsciiString,
+  IN    CHAR16    *UnicodeString
+  );
+
+UINT16
+ConfigModeStateGet();
+
+VOID
+SetSkus();
+
+VOID
+CPUSetupItems();
+
+EFI_STATUS
+SecurityDriverCallback (
+  IN EFI_FORM_CALLBACK_PROTOCOL       *This,
+  IN UINT16                           KeyValue,
+  IN EFI_IFR_DATA_ARRAY               *Data,
+  OUT EFI_HII_CALLBACK_PACKET         **Packet
+  );
+
+VOID
+SetPasswordState (
+  );
+
+VOID
+EncodePassword (
+  IN  CHAR16                      *Password
+  );
+
+VOID
+EFIAPI
+PciBusEvent (
+  IN EFI_EVENT    Event,
+  IN VOID*        Context
+  );
+VOID
+AsfInitialize(
+  );
+
+VOID
+InitializeAsf (
+  );
+
+UINT8
+ReadCmosBank1Byte (
+  IN  EFI_CPU_IO_PROTOCOL             *CpuIo,
+  IN  UINT8                           Index
+  );
+
+VOID
+WriteCmosBank1Byte (
+  IN  EFI_CPU_IO_PROTOCOL             *CpuIo,
+  IN  UINT8                           Index,
+  IN  UINT8                           Data
+  );
+
+VOID
+InitializeBoardId (
+  );
+
+EFI_STATUS
+InstallBootCallbackRoutine(
+  );
+
+EFI_STATUS
+InstallConfigurationCallbackRoutine(
+  );
+
+EFI_STATUS
+InstallPerformanceCallbackRoutine(
+  );
+
+EFI_STATUS
+InstallSecurityCallbackRoutine (
+  );
+
+EFI_STATUS
+InstallMainCallbackRoutine (
+  );
+
+EFI_STATUS
+MemoryConfigurationUpdate (
+  UINT16                *Key,
+  EFI_FORM_LABEL        *Label,
+  UINT16                *OpcodeCount,
+  UINT8                 **OpcodeData,
+  EFI_FORM_ROUTINE      *Routine
+  );
+
+EFI_STATUS
+MemoryConfigurationCallbackRoutine (
+  SYSTEM_CONFIGURATION  *SetupBuffer
+  );
+
+EFI_STATUS
+MemoryConfigurationCalculateSpeed(
+  SYSTEM_CONFIGURATION  *SetupBuffer
+  );
+
+VOID
+UpdateMemoryString(
+  IN  STRING_REF                  TokenToUpdate,
+  IN  CHAR16                      *NewString
+  );
+
+VOID
+InitFeaturePolicy (
+  IN EFI_PLATFORM_INFO_HOB      *PlatformInfo
+  );
+
+VOID
+InitializeSetupVarHide (
+  );
+
+VOID
+PreparePCIePCISlotInformation(
+  VOID
+  );
+
+
+EFI_STATUS
+BootConfigurationUpdate (
+  IN  OUT SYSTEM_CONFIGURATION  *SystemConfiguration
+  );
+
+EFI_STATUS
+InitializeBootConfiguration(
+  VOID
+  );
+
+UINT16
+GetStringSize(
+  IN      CHAR16 *ThisString
+  );
+
+UINT16
+GetDriveCount (
+  IN      STRING_REF *BootMap
+  );
+
+CHAR16 *
+GetBootString (
+  IN      STRING_REF    Id,
+      OUT UINTN        *Length
+  );
+
+EFI_STATUS
+BootCfgCreateTwoOptionOneOf(
+  IN      UINT16                QuestionId,
+  IN      EFI_FORM_LABEL        Label,
+  IN      STRING_REF            OptionPrompt,
+  IN      STRING_REF            OptionHelp,
+  IN      STRING_REF            OptionOneString,
+  IN      STRING_REF            OptionTwoString,
+  IN      UINT8                 OptionOneFlags,
+  IN      UINT8                 OptionTwoFlags,
+  IN      UINT16                KeyValueOne,
+  IN      UINT16                KeyValueTwo
+  );
+
+EFI_STATUS
+ReplaceOpcodeWithText(
+  IN      STRING_REF            OptionPrompt,
+  IN      STRING_REF            OptionHelp,
+  IN      STRING_REF            OptionOneString,
+  IN      EFI_FORM_LABEL        Label
+  );
+
+EFI_STATUS
+CreateDriveBootOrderOpcode(
+  IN      VOID                 *Data,
+  IN      STRING_REF           *BootMap,
+  IN      EFI_FORM_LABEL        Label,
+  IN      UINT16                QuestionId,
+  IN      STRING_REF            OptionOneString,
+  IN      STRING_REF            OptionTwoString
+  );
+
+VOID
+SetHyperBootCfgFlags(
+  IN  OUT SYSTEM_CONFIGURATION *SystemConfiguration
+  );
+
+VOID
+GetHyperBootCfgFlags(
+  IN  OUT SYSTEM_CONFIGURATION *SystemConfiguration
+  );
+
+VOID
+PrepareBootCfgForHyperBoot(
+  IN  OUT SYSTEM_CONFIGURATION *SystemConfiguration
+  );
+
+BOOLEAN
+BootCfgChanged(
+  IN      SYSTEM_CONFIGURATION *SystemConfiguration
+  );
+
+EFI_STATUS
+InsertOpcodeAtIndex(
+  IN      SYSTEM_CONFIGURATION *SystemConfiguration,
+  IN  OUT IFR_OPTION           *OptionList,
+  IN      IFR_OPTION            IfrOption,
+  IN      UINT16                OptionCount
+  );
+
+VOID
+ConfigureBootOrderStrings(
+  IN      SYSTEM_CONFIGURATION *SystemConfiguration
+  );
+
+VOID
+InitializeAllBootStrings(
+  VOID
+  );
+
+VOID
+SaveUsbCfgSettings(
+  IN  OUT SYSTEM_CONFIGURATION *SystemConfiguration
+  );
+
+VOID
+RestoreUsbCfgSettings(
+  IN  OUT SYSTEM_CONFIGURATION *SystemConfiguration
+  );
+
+EFI_STATUS
+UpdateBootDevicePriority(
+  IN  OUT SYSTEM_CONFIGURATION *SystemConfiguration
+  );
+
+EFI_STATUS
+DisableHyperBoot(
+  IN  OUT SYSTEM_CONFIGURATION *SystemConfiguration
+  );
+
+BOOLEAN
+CheckForUserPassword(
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+HyperBootPasswordCallback(
+  IN  OUT VOID*  Data
+  );
+
+EFI_STATUS
+EFIAPI
+HyperBootF9Callback (
+  IN VOID*  Data
+  );
+
+EFI_STATUS
+InstallHiiEvents(
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+ProgramToneFrequency (
+  IN  EFI_SPEAKER_IF_PROTOCOL           *This,
+  IN  UINT16                            Frequency
+  );
+
+EFI_STATUS
+EFIAPI
+GenerateBeepTone (
+  IN  EFI_SPEAKER_IF_PROTOCOL           *This,
+  IN  UINTN                             NumberOfBeeps,
+  IN  UINTN                             BeepDuration,
+  IN  UINTN                             TimeInterval
+  );
+
+EFI_STATUS
+InitializeObservableProtocol();
+
+EFI_STATUS
+PciBusDriverHook();
+
+VOID
+EFIAPI
+AdjustDefaultRtcTimeCallback (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  );
+
+typedef struct _GOP_DISPLAY_BRIGHTNESS_PROTOCOL GOP_DISPLAY_BRIGHTNESS_PROTOCOL;
+
+typedef
+EFI_STATUS
+(EFIAPI *GET_MAXIMUM_BRIGHTNESS_LEVEL) (
+  IN  GOP_DISPLAY_BRIGHTNESS_PROTOCOL *This,
+  OUT UINT32 *MaxBrightnessLevel
+  );
+
+
+typedef
+EFI_STATUS
+(EFIAPI *GET_CURRENT_BRIGHTNESS_LEVEL) (
+  IN  GOP_DISPLAY_BRIGHTNESS_PROTOCOL *This,
+  OUT UINT32 *MaxBrightnessLevel
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *SET_BRIGHTNESS_LEVEL) (
+  IN  GOP_DISPLAY_BRIGHTNESS_PROTOCOL *This,
+  IN  UINT32  BrightnessLevel
+  );
+
+struct _GOP_DISPLAY_BRIGHTNESS_PROTOCOL {
+  UINT32  Revision;
+  GET_MAXIMUM_BRIGHTNESS_LEVEL GetMaxBrightnessLevel;
+  GET_CURRENT_BRIGHTNESS_LEVEL GetCurrentBrightnessLevel;
+  SET_BRIGHTNESS_LEVEL SetBrightnessLevel;
+};
+
+//
+// Global externs
+//
+extern UINT8 MaintenanceBin[];
+extern UINT8 MainBin[];
+extern UINT8 ConfigurationBin[];
+extern UINT8 MemoryConfigurationBin[];
+extern UINT8 PerformanceBin[];
+extern UINT8 SecurityBin[];
+extern UINT8 BootBin[];
+extern UINT8 PowerBin[];
+extern UINT8 SystemSetupBin[];
+
+extern VOID                 *mDxePlatformStringPack;
+extern EFI_HII_PROTOCOL     *mHii;
+extern SYSTEM_CONFIGURATION mSystemConfiguration;
+extern FRAMEWORK_EFI_HII_HANDLE       mMaintenanceHiiHandle;
+extern FRAMEWORK_EFI_HII_HANDLE       mMainHiiHandle;
+extern FRAMEWORK_EFI_HII_HANDLE       mConfigurationHiiHandle;
+extern FRAMEWORK_EFI_HII_HANDLE       mPerformanceHiiHandle;
+extern FRAMEWORK_EFI_HII_HANDLE       mPowerHiiHandle;
+extern FRAMEWORK_EFI_HII_HANDLE       mBootHiiHandle;
+extern FRAMEWORK_EFI_HII_HANDLE       mSecurityHiiHandle;
+
+extern SYSTEM_PASSWORDS     mSystemPassword;
+extern EFI_PASSWORD_DATA    mAdminPassword;
+extern EFI_PASSWORD_DATA    mUserPassword;
+
+extern EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *mPciRootBridgeIo;
+
+//
+//extern EFI_REG_TABLE mSubsystemIdRegs[];
+//
+extern UINT32 mSubsystemVidDid;
+extern UINT32 mSubsystemAudioVidDid;
+
+extern UINT8 mBoardIdIndex;
+extern BOOLEAN mFoundAANum;
+extern EFI_BOARD_FEATURES mBoardFeatures;
+extern UINT16 mSubsystemDeviceId;
+extern UINT16 mSubsystemAudioDeviceId;
+extern BOARD_ID_DECODE mBoardIdDecodeTable[];
+extern UINTN mBoardIdDecodeTableSize;
+
+extern UINT8 mSmbusRsvdAddresses[];
+extern UINT8 mNumberSmbusAddress;
+extern BOOLEAN mMfgMode;
+extern UINT32 mPlatformBootMode;
+extern CHAR8 BoardAaNumber[];
+
+extern EFI_GUID gEfiGlobalNvsAreaProtocolGuid;
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.inf b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.inf
new file mode 100644
index 0000000000..4d1949d05d
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.inf
@@ -0,0 +1,149 @@
+## @file
+#
+#  Copyright (c)  1999  - 2016, Intel Corporation. All rights reserved
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#  Module Name:
+#
+#    PlatformBB.inf
+#
+#  Abstract:
+#
+#    Component description file for platform DXE driver
+#  ------------------------------------------------------------------------------
+#  Rev   Date<MM/DD/YYYY>    Name    Description
+#  ------------------------------------------------------------------------------
+#  R01     <04/22/2011>       LB     Update code for SIO83627UHG support.
+#  ------------------------------------------------------------------------------
+#
+##
+
+[defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformDxe
+  FILE_GUID                      = 056E7324-A718-465b-9A84-228F06642B4F
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  PI_SPECIFICATION_VERSION       = 0x0001000A
+  ENTRY_POINT                    = InitializePlatform
+
+[sources.common]
+  BoardId.c
+  BoardIdDecode.c
+  ClockControl.c
+  Platform.c
+  IchRegTable.c
+  IdccInfo.c
+  SioPlatformPolicy.c
+  IchPlatformPolicy.c
+  PciDevice.c
+  SlotConfig.c
+  IchTcoReset.c
+  SensorVar.c
+  LegacySpeaker.c
+  Observable/Observable.c
+  ExI.c
+  Rtc.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  CryptoPkg/CryptoPkg.dec
+  IntelFspWrapperPkg/IntelFspWrapperPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiRuntimeServicesTableLib
+  DxeServicesTableLib
+  PchPlatformLib
+
+  DebugLib
+  HiiLib
+  PrintLib
+  UefiLib
+  S3BootScriptLib
+  ReportStatusCodeLib
+  EfiRegTableLib
+  BiosIdLib
+  BaseCryptLib
+
+[Guids]
+  gEfiBiosIdGuid
+  gEfiPlatformBootModeGuid
+  gEfiBoardFeaturesGuid
+  gItkDataVarGuid
+  gDmiDataGuid
+  gIdccDataHubGuid
+  gEfiPciLanInfoGuid
+  gEfiNormalSetupGuid
+  gEfiGlobalVariableGuid
+  gEfiEventExitBootServicesGuid
+  gEfiVlv2VariableGuid
+  gEfiSecureBootEnableDisableGuid
+
+[Protocols]
+  gEfiPciRootBridgeIoProtocolGuid    # CONSUMES  ## GUID
+  gEfiVariableArchProtocolGuid
+  gEfiVariableWriteArchProtocolGuid
+  gEfiHiiConfigAccessProtocolGuid
+  gEfiBootScriptSaveProtocolGuid
+  gEfiCpuIoProtocolGuid
+  gEfiDevicePathProtocolGuid
+  gEfiDiskInfoProtocolGuid
+  gEfiPs2PolicyProtocolGuid
+  gEfiIsaAcpiProtocolGuid
+  gEfiDataHubProtocolGuid
+  gEfiPciIoProtocolGuid
+  gDxePchPlatformPolicyProtocolGuid
+  gEfiTpmMpDriverProtocolGuid
+  gEfiLpcWpce791PolicyProtocolGuid
+  gUsbPolicyGuid
+  gEfiSpeakerInterfaceProtocolGuid
+  gDxeVlvPlatformPolicyGuid
+  gEfiSmbiosSlotPopulationGuid
+  gObservableProtocolGuid
+  gEfiCk505ClockPlatformInfoGuid
+  gEfiLpcWpc83627PolicyProtocolGuid
+  gEfiTcoResetProtocolGuid
+  gEfiWatchdogTimerDriverProtocolGuid
+  gEfiPlatformIdeInitProtocolGuid
+  gEfiGlobalNvsAreaProtocolGuid
+  gEfiCpuIo2ProtocolGuid
+  gIgdOpRegionProtocolGuid
+  gExitPmAuthProtocolGuid
+  gEdkiiVariableLockProtocolGuid
+
+[Pcd.common]
+  gPlatformModuleTokenSpaceGuid.PcdPBTNDisableInterval
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+  gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress
+  gPlatformModuleTokenSpaceGuid.PcdFlashMicroCodeAddress
+  gPlatformModuleTokenSpaceGuid.PcdFlashMicroCodeSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFastPS2Detection
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvMainBase
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoveryBase
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoverySize
+  gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase
+
+
+[Depex]
+  gEfiPciRootBridgeIoProtocolGuid     AND
+  gEfiVariableArchProtocolGuid        AND
+  gEfiVariableWriteArchProtocolGuid   AND
+  gEfiBootScriptSaveProtocolGuid      AND
+  gEfiCpuIoProtocolGuid               AND
+  gDxePchPlatformPolicyProtocolGuid   AND
+  gEfiGlobalNvsAreaProtocolGuid
+
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c
new file mode 100644
index 0000000000..f7be592960
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c
@@ -0,0 +1,154 @@
+/** @file
+  Adjust Default System Time.
+  
+  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+                                                                                   
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+                                                                                   
+--*/
+
+#include <PlatformDxe.h>
+
+//
+// Date and time initial values.
+// They are used if the RTC values are invalid during driver initialization
+//
+#define RTC_INIT_SECOND 0
+#define RTC_INIT_MINUTE 0
+#define RTC_INIT_HOUR   0
+ 
+CHAR16  mBiosReleaseDate[20];    
+  
+/**
+  Convert a single character to number.
+  It assumes the input Char is in the scope of L'0' ~ L'9' and L'A' ~ L'F'
+  
+  @param Char    The input char which need to change to a hex number.
+  
+**/
+UINTN
+CharToUint (
+  IN CHAR16                           Char
+  )
+{
+  if ((Char >= L'0') && (Char <= L'9')) {
+    return (UINTN) (Char - L'0');
+  }
+
+  if ((Char >= L'A') && (Char <= L'F')) {
+    return (UINTN) (Char - L'A' + 0xA);
+  }
+
+  ASSERT (FALSE);
+  return 0;
+}
+
+/**
+  See if YEAR field of a variable of EFI_TIME type is correct.
+
+  @param   Time   The time to be checked.
+
+  @retval  EFI_INVALID_PARAMETER  Some fields of Time are not correct.
+  @retval  EFI_SUCCESS            Time is a valid EFI_TIME variable.
+
+**/
+EFI_STATUS
+CheckRtcTimeFields (
+  IN EFI_TIME *Time
+  )
+{
+  UINT16 YearBuilt;
+  
+  YearBuilt = (UINT16)(CharToUint(mBiosReleaseDate[8])*10 + CharToUint(mBiosReleaseDate[9]) + 2000);
+  
+  if ((Time->Year) < YearBuilt) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  ExitPmAuth Protocol notification event handler, which set initial system time to be
+  the time when BIOS was built.
+
+  @param[in] Event    Event whose notification function is being invoked.
+  @param[in] Context  Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+AdjustDefaultRtcTimeCallback (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  )
+{
+  EFI_STATUS      Status;
+  EFI_TIME        EfiTime;
+  CHAR16          BiosVersion[60];    
+  CHAR16          BiosReleaseTime[20];    
+  //
+  // Get BIOS built time from Bios-ID. 
+  //
+  
+  SetMem(BiosVersion, sizeof(BiosVersion), 0);
+  SetMem(mBiosReleaseDate, sizeof(mBiosReleaseDate), 0);
+  SetMem(BiosReleaseTime, sizeof(BiosReleaseTime), 0);
+    
+  Status = GetBiosVersionDateTime (BiosVersion, mBiosReleaseDate, BiosReleaseTime);
+  ASSERT_EFI_ERROR(Status);
+  if (EFI_ERROR (Status)) {
+    return; 
+  }
+  
+  //
+  // Get current RTC time.
+  // 
+  Status = gRT->GetTime (&EfiTime, NULL);
+ 
+  //
+  // Validate RTC time fields
+  //
+  Status = CheckRtcTimeFields (&EfiTime);
+  
+  if (EFI_ERROR (Status)) {
+    //
+    // Date such as Dec 28th of 2015
+    //
+    // Month
+    // BiosReleaseDate[0] = '1';
+    // BiosReleaseDate[1] = '2';
+    //
+    // Day
+    // BiosReleaseDate[3] = '2';
+    // BiosReleaseDate[4] = '8';
+    //  
+    //
+    // Year
+    //
+    // BiosReleaseDate[6] = '2';
+    // BiosReleaseDate[7] = '0';
+    // BiosReleaseDate[8] = '1'
+    // BiosReleaseDate[9] = '5';
+    
+    EfiTime.Second = RTC_INIT_SECOND;
+    EfiTime.Minute = RTC_INIT_MINUTE;
+    EfiTime.Hour   = RTC_INIT_HOUR;
+    EfiTime.Day    = (UINT8)(CharToUint(mBiosReleaseDate[3])*10 + CharToUint(mBiosReleaseDate[4]));
+    EfiTime.Month  = (UINT8)(CharToUint(mBiosReleaseDate[0])*10 + CharToUint(mBiosReleaseDate[1]));
+    EfiTime.Year   = (UINT16)(CharToUint(mBiosReleaseDate[8])*10 + CharToUint(mBiosReleaseDate[9]) + 2000);
+    EfiTime.Nanosecond  = 0;
+    EfiTime.TimeZone = EFI_UNSPECIFIED_TIMEZONE;
+    EfiTime.Daylight = 1; 
+
+    DEBUG ((EFI_D_INFO, "Day:%d Month:%d Year:%d \n", (UINT32)EfiTime.Day, (UINT32)EfiTime.Month, (UINT32)EfiTime.Year));
+
+    //
+    // Reset time value according to new RTC configuration
+    //
+    Status = gRT->SetTime (&EfiTime);
+    ASSERT_EFI_ERROR(Status);
+  }
+
+  return;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c
new file mode 100644
index 0000000000..5d13e99443
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c
@@ -0,0 +1,112 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+  SensorVar.c
+
+Abstract:
+
+  Initialization for the Sensor Info variable.
+
+Revision History
+
+--*/
+
+#include "PlatformDxe.h"
+#include "Guid/SensorInfoVariable.h"
+
+//
+// Sensor Information (board specific)
+//
+
+#define TEMPERATURE_SENSORS_COUNT       4
+#define VOLTAGE_SENSORS_COUNT           6
+#define FAN_SENSORS_COUNT               4
+#define FAN_CONTROLLERS_COUNT           3
+
+TYPEDEF_TEMP_SENSOR_SECTION(TEMPERATURE_SENSORS_COUNT);
+TYPEDEF_VOLT_SENSOR_SECTION(VOLTAGE_SENSORS_COUNT);
+TYPEDEF_FAN_SENSOR_SECTION(FAN_SENSORS_COUNT);
+TYPEDEF_FAN_CONTROLLER_SECTION(FAN_CONTROLLERS_COUNT);
+TYPEDEF_SENSOR_INFO_VAR;
+
+SENSOR_INFO_VAR               mSensorInfoData =
+{
+	  //
+    // Temperature Sensors
+    //
+    TEMPERATURE_SENSORS_COUNT,
+    {
+        { 0, 3, CPU_CORE_TEMPERATURE,            TRUE  },
+        { 0, 1, MOTHERBOARD_AMBIENT_TEMPERATURE, FALSE },
+        { 0, 2, VR_TEMPERATURE,                  FALSE },
+        { 0, 0, IOH_TEMPERATURE,                 FALSE }
+    },
+
+    //
+    // Voltage Sensors
+    //
+    VOLTAGE_SENSORS_COUNT,
+    {
+        { 0, 0, PLUS_12_VOLTS       },
+        { 0, 1, PLUS_5_VOLTS        },
+        { 0, 2, PLUS_3P3_VOLTS      },
+        { 0, 3, MCH_VCC_VOLTAGE     },
+        { 0, 4, CPU_1_VCCP_VOLTAGE  },
+        { 0, 5, CPU_VTT_VOLTAGE     }
+    },
+
+    //
+    // Fan Speed Sensors
+    //
+    FAN_SENSORS_COUNT,
+    {
+        { 0, 0, CPU_COOLING_FAN,    FAN_4WIRE,         0 },
+        { 0, 1, AUX_COOLING_FAN,    FAN_4WIRE,         1 },
+        { 0, 2, CHASSIS_INLET_FAN,  FAN_3WIRE_VOLTAGE, 1 },
+        { 0, 3, CHASSIS_OUTLET_FAN, FAN_3WIRE_VOLTAGE, 2 }
+    },
+
+    //
+    // Fan Speed Controllers
+    //
+    FAN_CONTROLLERS_COUNT,
+    {
+        { 0, 0, CPU_COOLING_FAN,     { 0, 0xff, 0xff, 0xff } },
+        { 0, 1, CHASSIS_COOLING_FAN, { 1,    2, 0xff, 0xff } },
+        { 0, 2, CHASSIS_COOLING_FAN, { 3, 0xff, 0xff, 0xff } }
+    }
+};
+
+/**
+
+  Write the Sensor Info variable if it does not already exist.
+
+**/
+VOID
+InitializeSensorInfoVariable (
+  )
+{
+  //
+  // Set the Sensor Info variable.  If it already exists and the data matches,
+  // the variable driver will simply return without writing; otherwise, the
+  // driver will write the variable.
+  //
+  gRT->SetVariable (
+         gEfiSensorInfoVarNameWithPassword,
+         &gEfiSensorInfoVarGuid,
+         EFI_VARIABLE_NON_VOLATILE |
+         EFI_VARIABLE_BOOTSERVICE_ACCESS |
+         EFI_VARIABLE_RUNTIME_ACCESS,
+         sizeof (SENSOR_INFO_VAR),
+         &mSensorInfoData
+         );
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SioPlatformPolicy.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SioPlatformPolicy.c
new file mode 100644
index 0000000000..32bee75f95
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SioPlatformPolicy.c
@@ -0,0 +1,82 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+  SioPlatformPolicy.c
+
+Abstract:
+
+  Sio Platform Policy Setting.
+
+
+--*/
+
+#include "PlatformDxe.h"
+#include <Protocol/LpcWpc83627Policy.h>
+
+
+EFI_WPC83627_POLICY_PROTOCOL  mSio83627PolicyData = {
+  { EFI_WPC83627_COM1_ENABLE,       // Com1
+    EFI_WPC83627_LPT1_ENABLE,       // Lpt1
+    EFI_WPC83627_FDD_DISABLE,       // Floppy
+    EFI_WPC83627_FDD_WRITE_ENABLE,  // FloppyWriteProtect
+    EFI_WPC83627_RESERVED_DEFAULT,  // Port80
+    EFI_WPC83627_ECIR_DISABLE,      // CIR
+    EFI_WPC83627_PS2_KBC_ENABLE,    // Ps2Keyboard
+    EFI_WPC83627_RESERVED_DEFAULT,  // Ps2Mouse
+    EFI_WPC83627_COM2_ENABLE,       // Com2
+    EFI_WPC83627_COM3_ENABLE,       // Com3
+    EFI_WPC83627_COM4_ENABLE,       // Com4
+    EFI_WPC83627_RESERVED_DEFAULT,  // Dac
+    0x00                            // Rsvd
+    },
+  LptModeEcp,                       // LptMode
+};
+
+/**
+
+  Publish the platform SIO policy setting.
+
+  @retval EFI_SUCCESS
+
+**/
+VOID
+InitSioPlatformPolicy(
+  )
+{
+
+  EFI_HANDLE              Handle;
+  EFI_STATUS              Status;
+
+  Handle = NULL;
+
+  if((mSystemConfiguration.Serial) || (mBoardFeatures & B_BOARD_FEATURES_SIO_NO_COM1)) {
+    mSio83627PolicyData.DeviceEnables.Com1 = EFI_WPC83627_COM1_DISABLE;
+  }
+
+  if((mSystemConfiguration.Serial2) || ((mBoardFeatures & B_BOARD_FEATURES_SIO_COM2)==0)) {
+    mSio83627PolicyData.DeviceEnables.Com2 = EFI_WPC83627_COM2_DISABLE;
+  }
+
+  mSio83627PolicyData.LptMode = mSystemConfiguration.ParallelMode;
+  if((!mSystemConfiguration.Parallel) || (mBoardFeatures & B_BOARD_FEATURES_SIO_NO_PARALLEL)) {
+    mSio83627PolicyData.DeviceEnables.Lpt1 = EFI_WPC83627_LPT1_DISABLE;
+  }
+
+  Status = gBS->InstallProtocolInterface (
+                  &Handle,
+                  &gEfiLpcWpc83627PolicyProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &mSio83627PolicyData
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.c
new file mode 100644
index 0000000000..f9b53ead95
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.c
@@ -0,0 +1,148 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  SlotConfig.c
+
+Abstract:
+
+  Sets platform/SKU specific expansion slot information.
+
+
+
+--*/
+#include "SlotConfig.h"
+
+//
+// Implementation
+//
+VOID
+InitializeSlotInfo (
+  )
+{
+  UINT16                              BusSaveState;
+  UINT16                              Vendor;
+  UINT8                               CurrentBus;
+  UINTN                               i;
+  UINTN                               j;
+  EFI_HANDLE                          Handle;
+  EFI_STATUS                          Status;
+  BOOLEAN                             RunNext;
+
+  //
+  // Loop through the slot table and see if any slots have cards in them
+  //
+  for (i = 0; i < mSlotBridgeTableSize; i++) {
+    //
+    // Initialize variable
+    //
+    RunNext = FALSE;
+
+    //
+    // Hide mini PCIe slots per SKU
+    //
+    for (j = 0; j < mSlotInformation.NumberOfEntries; j++) {
+      if (mSlotInformation.SlotEntries[j].SmbiosSlotId == mSlotBridgeTable[i].SmbiosSlotId) {
+        if ((mSlotInformation.SlotEntries[j].SmbiosSlotId == 0x02) &&
+            (mBoardFeatures & B_BOARD_FEATURES_NO_MINIPCIE)
+          ) {
+          mSlotInformation.SlotEntries[j].Disabled = TRUE;
+          RunNext = TRUE;
+        }
+        break;
+      }
+    }
+
+    if (RunNext) {
+      //
+      // Skip slot device detection since the slot is disabled.
+      //
+      continue;
+    }
+
+    //
+    // Check to see if the bridge has a bus number and assign one if not
+    //
+    BusSaveState = MmPci16 (
+      0,
+      mSlotBridgeTable[i].Bus,
+      mSlotBridgeTable[i].Dev,
+      mSlotBridgeTable[i].Function,
+      PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET
+                            );
+    if (BusSaveState == 0) {
+      //
+      // Assign temp bus number
+      //
+      MmPci16 (
+        0,
+        mSlotBridgeTable[i].Bus,
+        mSlotBridgeTable[i].Dev,
+        mSlotBridgeTable[i].Function,
+        PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET
+        ) = DEF_BUS_CONFIG;
+      CurrentBus = DEF_BUS;
+    } else if (BusSaveState == 0xFFFF) {
+      //
+      // Bridge is disabled so continue with next entry in the table
+      //
+      continue;
+    } else {
+      //
+      // Use existing bus number
+      //
+      CurrentBus = (UINT8) BusSaveState & 0xFF;
+    }
+
+    //
+    // Check to see if a device is behind the bridge
+    //
+    Vendor = MmPci16 (
+               0,
+               CurrentBus,
+               mSlotBridgeTable[i].TargetDevice,
+               0,
+               0
+               );
+    if (Vendor != 0xFFFF) {
+      //
+      // Device found so make sure the slot is marked that way
+      //
+      for (j = 0; j < mSlotInformation.NumberOfEntries; j++) {
+        if (mSlotInformation.SlotEntries[j].SmbiosSlotId == mSlotBridgeTable[i].SmbiosSlotId) {
+          mSlotInformation.SlotEntries[j].InUse = TRUE;
+          break;
+        }
+      }
+    }
+
+    //
+    // Restore previous bus information
+    //
+    if (BusSaveState == 0) {
+      MmPci16 (
+        0,
+        mSlotBridgeTable[i].Bus,
+        mSlotBridgeTable[i].Dev,
+        mSlotBridgeTable[i].Function,
+        PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET
+        ) = 0;
+    }
+  }
+
+  Handle = NULL;
+  Status = gBS->InstallProtocolInterface (
+                  &Handle,
+                  &gEfiSmbiosSlotPopulationGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &mSlotInformation
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.h b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.h
new file mode 100644
index 0000000000..738798261b
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.h
@@ -0,0 +1,80 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  SlotConfig.c
+
+Abstract:
+
+  Sets platform/SKU specific expansion slot information.
+
+
+
+
+--*/
+
+#include "PlatformDxe.h"
+#include <Protocol/SmbiosSlotPopulation.h>
+#include <IndustryStandard/Pci22.h>
+
+
+//
+// Default bus number for the bridge
+//
+#define DEF_BUS_CONFIG  0x0101
+#define DEF_BUS         0x01
+
+//
+// Data structures for slot information
+//
+typedef struct {
+  UINT16  SmbiosSlotId;
+  UINT8   Bus;
+  UINT8   Dev;
+  UINT8   Function;
+  UINT8   TargetDevice;
+} EFI_PCI_SLOT_BRIDGE_INFO;
+
+//
+// Product specific bridge to slot routing information
+//
+EFI_PCI_SLOT_BRIDGE_INFO mSlotBridgeTable[] = {
+  {
+    0x01,             //PCIe x1 ICH (Bridge B0:D28:F1)
+    DEFAULT_PCI_BUS_NUMBER_PCH,
+    PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2,
+    0
+  }
+};
+
+UINTN mSlotBridgeTableSize =
+  sizeof(mSlotBridgeTable) / sizeof(EFI_PCI_SLOT_BRIDGE_INFO);
+
+//
+// Slot entry table for IBX RVP
+//
+EFI_SMBIOS_SLOT_ENTRY mSlotEntries[] = {
+  {0x06, FALSE, TRUE},    // PCIe x16 Slot 1 (NOT USED)
+  {0x04, FALSE, TRUE},    // PCIe x16 Slot 2 (NOT USED)
+  {0x03, FALSE, TRUE},    // PCIe x4 Slot (NOT USED)
+  {0x02, FALSE, FALSE},   // Mini PCIe x1 Slot
+  {0x15, FALSE, TRUE},    // PCIe x1 Slot 2 (NOT USED)
+  {0x16, FALSE, TRUE},    // PCIe x1 Slot 3 (NOT USED)
+  {0x07, FALSE, FALSE},   // PCI Slot 1
+  {0x18, FALSE, TRUE},    // PCI Slot 2 (NOT USED)
+  {0x17, FALSE, TRUE},    // PCI Slot 3 (NOT USED)
+};
+
+EFI_SMBIOS_SLOT_POPULATION_INFO mSlotInformation = {
+  sizeof(mSlotEntries) / sizeof(EFI_SMBIOS_SLOT_ENTRY),
+  mSlotEntries
+};
+
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.c
new file mode 100644
index 0000000000..3900603d68
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.c
@@ -0,0 +1,201 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+                                                                                   

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

+
+--*/
+
+/** @file
+**/
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/PlatformGopPolicy.h>
+
+#include <Guid/SetupVariable.h>
+#include <SetupMode.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+PLATFORM_GOP_POLICY_PROTOCOL  mPlatformGOPPolicy;
+
+//
+// Function implementations
+//
+
+/**
+  The function will execute with as the platform policy, and gives
+  the Platform Lid Status. IBV/OEM can customize this code for their specific
+  policy action.
+
+  @param CurrentLidStatus  Gives the current LID Status
+
+  @retval EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+GetPlatformLidStatus (
+   OUT LID_STATUS *CurrentLidStatus
+)
+{
+  *CurrentLidStatus = LidOpen;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  The function will execute and gives the Video Bios Table Size and Address.
+
+  @param VbtAddress  Gives the Physical Address of Video BIOS Table
+
+  @param VbtSize     Gives the Size of Video BIOS Table
+
+  @retval EFI_STATUS.
+
+**/
+
+EFI_STATUS
+EFIAPI
+GetVbtData (
+   OUT EFI_PHYSICAL_ADDRESS *VbtAddress,
+   OUT UINT32 *VbtSize
+)
+{
+  EFI_STATUS                    Status;
+  UINTN                         FvProtocolCount;
+  EFI_HANDLE                    *FvHandles;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL  *Fv;
+  UINTN                         Index;
+  UINT32                        AuthenticationStatus;
+
+  UINT8                         *Buffer;
+  UINTN                         VbtBufferSize;
+
+  Buffer = 0;
+  FvHandles       = NULL;
+
+  if (VbtAddress == NULL || VbtSize == NULL){
+    return EFI_INVALID_PARAMETER;
+  }
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiFirmwareVolume2ProtocolGuid,
+                  NULL,
+                  &FvProtocolCount,
+                  &FvHandles
+                  );
+
+  if (!EFI_ERROR (Status)) {
+    for (Index = 0; Index < FvProtocolCount; Index++) {
+      Status = gBS->HandleProtocol (
+                      FvHandles[Index],
+                      &gEfiFirmwareVolume2ProtocolGuid,
+                      (VOID **) &Fv
+                      );
+      VbtBufferSize = 0;
+      Status = Fv->ReadSection (
+                     Fv,
+                     &gBmpImageGuid,
+                     EFI_SECTION_RAW,
+                     0,
+                    (void **)&Buffer,
+                     &VbtBufferSize,
+                     &AuthenticationStatus
+                     );
+
+      if (!EFI_ERROR (Status)) {
+        *VbtAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
+        *VbtSize = (UINT32)VbtBufferSize;
+        Status = EFI_SUCCESS;
+        break;
+      }
+    }
+  } else {
+    Status = EFI_NOT_FOUND;
+  }
+
+  if (FvHandles != NULL) {
+    gBS->FreePool (FvHandles);
+    FvHandles = NULL;
+  }
+
+  return Status;
+}
+
+/**
+  Entry point for the Platform GOP Policy Driver.
+
+  @param ImageHandle       Image handle of this driver.
+  @param SystemTable       Global system service table.
+
+  @retval EFI_SUCCESS           Initialization complete.
+  @retval EFI_OUT_OF_RESOURCES  Do not have enough resources to initialize the driver.
+
+**/
+
+EFI_STATUS
+EFIAPI
+PlatformGOPPolicyEntryPoint (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+
+{
+  EFI_STATUS  Status = EFI_SUCCESS;
+  SYSTEM_CONFIGURATION          SystemConfiguration;
+  UINTN       VarSize;
+
+
+  gBS = SystemTable->BootServices;
+
+  gBS->SetMem (
+         &mPlatformGOPPolicy,
+         sizeof (PLATFORM_GOP_POLICY_PROTOCOL),
+         0
+         );
+
+  mPlatformGOPPolicy.Revision                = PLATFORM_GOP_POLICY_PROTOCOL_REVISION_01;
+  mPlatformGOPPolicy.GetPlatformLidStatus    = GetPlatformLidStatus;
+  mPlatformGOPPolicy.GetVbtData              = GetVbtData;
+
+  //
+  // Install protocol to allow access to this Policy.
+  //
+  VarSize = sizeof(SYSTEM_CONFIGURATION);
+  Status = gRT->GetVariable(
+                  L"Setup",
+                  &gEfiNormalSetupGuid,
+                  NULL,
+                  &VarSize,
+                  &SystemConfiguration
+                  );
+  if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
+    //The setup variable is corrupted
+    VarSize = sizeof(SYSTEM_CONFIGURATION);
+    Status = gRT->GetVariable(
+              L"SetupRecovery",
+              &gEfiNormalSetupGuid,
+              NULL,
+              &VarSize,
+              &SystemConfiguration
+              );
+    ASSERT_EFI_ERROR (Status);
+  }
+  
+  if (SystemConfiguration.GOPEnable == 1)
+  {
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gPlatformGOPPolicyGuid,
+                  &mPlatformGOPPolicy,
+                  NULL
+                  );
+  }
+
+  return Status;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.inf b/Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.inf
new file mode 100644
index 0000000000..948793f719
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.inf
@@ -0,0 +1,51 @@
+#
+#
+# Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+#                                                                                  

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

+#
+#
+##
+
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformGOPPolicy
+  FILE_GUID                      = 9737D7CA-D869-45e5-A5EF-75D9438688DE
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = PlatformGOPPolicyEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32
+#
+
+[Sources.common]
+  PlatformGopPolicy.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  UefiDriverEntryPoint
+  UefiRuntimeServicesTableLib
+#  DxeKscLib
+
+[Guids]
+  gBmpImageGuid
+  gEfiNormalSetupGuid
+
+[Protocols]
+  gEfiCpuIoProtocolGuid
+  gEfiFirmwareVolume2ProtocolGuid
+  gPlatformGOPPolicyGuid
+
+[Depex]
+  gEfiCpuIoProtocolGuid AND gEfiVariableArchProtocolGuid
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.c
new file mode 100644
index 0000000000..fc784034cd
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.c
@@ -0,0 +1,169 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  PlatformInfoDxe.c
+
+Abstract:
+  Platform Info driver to public platform related HOB data
+
+--*/
+
+#include "PlatformInfoDxe.h"
+
+/**
+  Entry point for the driver.
+
+  This routine get the platform HOB data from PEI and publish
+  as Platform Info variable that can be accessed during boot service and
+  runtime.
+
+  @param ImageHandle    Image Handle.
+  @param SystemTable    EFI System Table.
+
+  @retval Status        Function execution status.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformInfoInit (
+  IN EFI_HANDLE                         ImageHandle,
+  IN EFI_SYSTEM_TABLE                   *SystemTable
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_PLATFORM_INFO_HOB       *PlatformInfoHobPtr;
+  EFI_PEI_HOB_POINTERS        GuidHob;
+  EFI_PLATFORM_INFO_HOB       TmpHob;
+  UINTN                       VarSize;
+  EFI_OS_SELECTION_HOB        *OsSlectionHobPtr;
+  UINT8                       Selection;
+  SYSTEM_CONFIGURATION        SystemConfiguration;
+  UINT8                       *LpssDataHobPtr;
+  UINT8                       *LpssDataVarPtr;
+  UINTN                       i;
+
+  VarSize = sizeof(SYSTEM_CONFIGURATION);
+  Status = gRT->GetVariable(
+                  NORMAL_SETUP_NAME,
+                  &gEfiNormalSetupGuid,
+                  NULL,
+                  &VarSize,
+                  &SystemConfiguration
+                  );
+  
+  if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
+    //The setup variable is corrupted
+    VarSize = sizeof(SYSTEM_CONFIGURATION);
+    Status = gRT->GetVariable(
+              L"SetupRecovery",
+              &gEfiNormalSetupGuid,
+              NULL,
+              &VarSize,
+              &SystemConfiguration
+              );
+    ASSERT_EFI_ERROR (Status);
+  }    
+
+  VarSize = sizeof(Selection);
+  Status = gRT->GetVariable(
+                  L"OsSelection",
+                  &gOsSelectionVariableGuid,
+                  NULL,
+                  &VarSize,
+                  &Selection
+                  );
+
+  if (EFI_ERROR(Status)) {
+    Selection = SystemConfiguration.ReservedO;
+    Status = gRT->SetVariable (
+                    L"OsSelection",
+                    &gOsSelectionVariableGuid,
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                    sizeof(Selection),
+                    &Selection
+                    );
+  }
+
+  GuidHob.Raw = GetHobList ();
+  if (GuidHob.Raw != NULL) {
+    if ((GuidHob.Raw = GetNextGuidHob (&gOsSelectionVariableGuid, GuidHob.Raw)) != NULL) {
+      OsSlectionHobPtr = GET_GUID_HOB_DATA (GuidHob.Guid);
+
+      if (OsSlectionHobPtr->OsSelectionChanged) {
+        SystemConfiguration.ReservedO = OsSlectionHobPtr->OsSelection;
+
+        //
+        // Load Audio default configuration
+        //
+        SystemConfiguration.Lpe         = OsSlectionHobPtr->Lpe;
+        SystemConfiguration.PchAzalia   = OsSlectionHobPtr->PchAzalia;
+
+        //
+        // Load LPSS and SCC default configurations
+        //
+        LpssDataHobPtr = &OsSlectionHobPtr->LpssData.LpssPciModeEnabled;
+        LpssDataVarPtr = &SystemConfiguration.LpssPciModeEnabled;
+        for (i = 0; i < sizeof(EFI_PLATFORM_LPSS_DATA); i++) {
+          *LpssDataVarPtr = *LpssDataHobPtr;
+          LpssDataVarPtr++;
+          LpssDataHobPtr++;
+        }
+
+        SystemConfiguration.GOPEnable = TRUE;
+
+        Status = gRT->SetVariable (
+                        NORMAL_SETUP_NAME,
+                        &gEfiNormalSetupGuid,
+                        EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                        sizeof(SYSTEM_CONFIGURATION),
+                        &SystemConfiguration
+                        );
+        ASSERT_EFI_ERROR (Status);
+      }
+    }
+  }
+
+  GuidHob.Raw = GetHobList ();
+  if (GuidHob.Raw == NULL) {
+  	return EFI_NOT_FOUND;
+  }
+
+  if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformInfoGuid, GuidHob.Raw)) != NULL) {
+    PlatformInfoHobPtr = GET_GUID_HOB_DATA (GuidHob.Guid);
+    VarSize = sizeof(EFI_PLATFORM_INFO_HOB);
+    Status = gRT->GetVariable(
+                    L"PlatformInfo",
+                    &gEfiVlv2VariableGuid,
+                    NULL,
+                    &VarSize,
+                    &TmpHob
+                    );
+
+    if (EFI_ERROR(Status) || CompareMem (&TmpHob, PlatformInfoHobPtr, VarSize)) {
+
+      //
+      // Write the Platform Info to volatile memory
+      //
+      Status = gRT->SetVariable(
+                      L"PlatformInfo",
+                      &gEfiVlv2VariableGuid,
+                      EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                      sizeof(EFI_PLATFORM_INFO_HOB),
+                      PlatformInfoHobPtr
+                      );
+      if (EFI_ERROR(Status)) {
+        return Status;
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.h b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.h
new file mode 100644
index 0000000000..615b32bb08
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.h
@@ -0,0 +1,30 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+  PlatformInfoDxe.h
+
+Abstract:
+  Platform Info Driver.
+
+--*/
+
+#ifndef _PLATFORM_INFO_DRIVER_H_
+#define _PLATFORM_INFO_DRIVER_H_
+
+#include <PiDxe.h>
+#include <Library/HobLib.h>
+#include <Guid/PlatformInfo.h>
+#include <Guid/GlobalVariable.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Guid/Vlv2Variable.h>
+#include <Library/BaseMemoryLib.h>
+#include <SetupMode.h>
+#include <Guid/OsSelection.h>
+#include <Guid/SetupVariable.h>
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.inf b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.inf
new file mode 100644
index 0000000000..ae3c2bf41b
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.inf
@@ -0,0 +1,52 @@
+#
+#
+# Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+#                                                                                  

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

+#
+#
+#  Module Name:
+#
+#   PlatformInfoDxe.inf
+#
+#  Abstract:
+#
+#
+--*/
+
+
+[defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformInfoDxe
+  FILE_GUID                      = 025F738B-4EBD-4d55-B728-5F421B601F1F
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = PlatformInfoInit
+
+[sources]
+  PlatformInfoDxe.c
+  PlatformInfoDxe.h
+
+[Guids]
+  gEfiAcpiVariableGuid                     # ALWAYS_CONSUMED
+  gEfiPlatformInfoGuid                     # ALWAYS_CONSUMED
+  gEfiVlv2VariableGuid
+  gEfiNormalSetupGuid
+  gOsSelectionVariableGuid
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+
+[LibraryClasses]
+  HobLib
+  UefiRuntimeServicesTableLib
+  UefiDriverEntryPoint
+  BaseMemoryLib
+
+[Depex]
+  gEfiVariableArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/BootMode.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/BootMode.c
new file mode 100644
index 0000000000..c906562c7e
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/BootMode.c
@@ -0,0 +1,434 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+  BootMode.c
+
+Abstract:
+
+  EFI PEIM to provide the platform support functionality on the Thurley.
+
+
+--*/
+
+#include "PlatformEarlyInit.h"
+
+
+#define NORMALMODE        0
+#define RECOVERYMODE      1
+#define SAFEMODE          2
+#define MANUFACTURINGMODE 3
+
+#define GPIO_SSUS_OFFSET    0x2000
+#define PMU_PWRBTN_B_OFFSET 0x88
+
+EFI_PEI_PPI_DESCRIPTOR  mPpiListRecoveryBootMode = {
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEfiPeiBootInRecoveryModePpiGuid,
+  NULL
+};
+
+/**
+  Return the setting of the Bios configuration jumper
+
+  @param  VOID
+
+  @retval RECOVERYMODE       jumper set to recovery mode
+  @retval SAFEMODE           jumper set to config mode
+  @retval NORMALMODE         jumper in normal mode
+
+**/
+UINTN
+GetConfigJumper(
+    IN CONST EFI_PEI_SERVICES           **PeiServices,
+    IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
+ )
+{
+  //
+  // Do the Forced recovery detection based on logic chart above
+  //
+  if (IsRecoveryJumper(PeiServices, PlatformInfoHob)) {
+    return RECOVERYMODE;
+  } else {
+    return NORMALMODE;
+  }
+}
+
+BOOLEAN
+CheckIfRecoveryMode(
+  IN CONST EFI_PEI_SERVICES           **PeiServices,
+  IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
+ )
+{
+  if (GetConfigJumper(PeiServices, PlatformInfoHob) == RECOVERYMODE) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
+BOOLEAN
+CheckIfSafeMode(
+  IN CONST EFI_PEI_SERVICES           **PeiServices,
+  IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
+ )
+{
+  if (GetConfigJumper(PeiServices, PlatformInfoHob) == SAFEMODE) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
+BOOLEAN
+CheckIfManufacturingMode (
+  IN CONST EFI_PEI_SERVICES  **PeiServices
+ )
+{
+  EFI_STATUS                  Status;
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI  *Variable;
+  UINT32                      Attributes;
+  UINTN                       DataSize;
+  CHAR16                      VarName[] = MFGMODE_VARIABLE_NAME;
+  UINT8                       MfgMode;
+
+  Status = (*PeiServices)->LocatePpi (
+                             PeiServices,
+                             &gEfiPeiReadOnlyVariable2PpiGuid,
+                             0,
+                             NULL,
+                             (void **)&Variable
+                             );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Check if SW MMJ mode
+  //
+  Attributes = (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS);
+  DataSize = sizeof (MFG_MODE_VAR);
+
+  Status = Variable->GetVariable (
+                       Variable,
+                       VarName,
+                       &gMfgModeVariableGuid,
+                       &Attributes,
+                       &DataSize,
+                       &MfgMode
+                       );
+  if (!(EFI_ERROR (Status))) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
+EFI_STATUS
+UpdateBootMode (
+  IN CONST EFI_PEI_SERVICES                       **PeiServices,
+  IN OUT EFI_PLATFORM_INFO_HOB                    *PlatformInfoHob
+  )
+{
+  EFI_STATUS                        Status;
+  EFI_BOOT_MODE                     BootMode;
+  UINT16                            SleepType;
+  CHAR16                            *strBootMode;
+  PEI_CAPSULE_PPI                   *Capsule;
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI   *Variable;
+  SYSTEM_CONFIGURATION              SystemConfiguration;
+  UINTN                             VarSize;
+  volatile UINT32                   GpioValue;
+  BOOLEAN                           IsFirstBoot;
+  UINT32                            Data32;
+
+  Status = (*PeiServices)->GetBootMode(
+                             PeiServices,
+                             &BootMode
+                             );
+  ASSERT_EFI_ERROR (Status);
+  if (BootMode  == BOOT_IN_RECOVERY_MODE){
+    return Status;
+  }
+  GetWakeupEventAndSaveToHob (PeiServices);
+
+  //
+  // Let's assume things are OK if not told otherwise
+  //
+  BootMode = BOOT_WITH_FULL_CONFIGURATION;
+
+  //
+  // When this boot is WDT reset, the system needs booting with CrashDump function eanbled.
+  //
+  Data32 = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_TCO_STS);
+
+  //
+  // Check Power Button, click the power button, the system will boot in fast boot mode,
+  // if it is pressed and hold for a second, it will boot in FullConfiguration/setup mode.
+  //
+  GpioValue = MmioRead32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + PMU_PWRBTN_B_OFFSET);    // The value of GPIOS_16 (PMU_PWRBTN_B)
+  if (((GpioValue & BIT0) != 0)&&((Data32 & B_PCH_TCO_STS_SECOND_TO) != B_PCH_TCO_STS_SECOND_TO)){
+    IsFirstBoot = PcdGetBool(PcdBootState);
+    if (!IsFirstBoot){
+      VarSize = sizeof (SYSTEM_CONFIGURATION);
+      ZeroMem (&SystemConfiguration, sizeof (SYSTEM_CONFIGURATION));
+
+      Status = (*PeiServices)->LocatePpi (
+                                 PeiServices,
+                                 &gEfiPeiReadOnlyVariable2PpiGuid,
+                                 0,
+                                 NULL,
+                                          (void **)&Variable
+                                 );
+      ASSERT_EFI_ERROR (Status);
+
+      //
+      // Use normal setup default from NVRAM variable,
+      // the Platform Mode (manufacturing/safe/normal) is handle in PeiGetVariable.
+      //
+      VarSize = sizeof(SYSTEM_CONFIGURATION);
+      Status = Variable->GetVariable (
+                           Variable,
+                           L"Setup",
+                           &gEfiSetupVariableGuid,
+                           NULL,
+                           &VarSize,
+                           &SystemConfiguration
+                           );
+      if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
+        //The setup variable is corrupted
+        VarSize = sizeof(SYSTEM_CONFIGURATION);
+        Status = Variable->GetVariable(
+                  Variable,
+                  L"SetupRecovery",
+                  &gEfiSetupVariableGuid,
+                  NULL,
+                  &VarSize,
+                  &SystemConfiguration
+                  );
+        ASSERT_EFI_ERROR (Status);
+      }      
+
+      if (SystemConfiguration.FastBoot == 1) {
+            BootMode = BOOT_WITH_MINIMAL_CONFIGURATION;
+      }
+    }
+  }
+
+  //
+  // Check if we need to boot in forced recovery mode
+  //
+  if (CheckIfRecoveryMode(PeiServices, PlatformInfoHob)) {
+    BootMode  = BOOT_IN_RECOVERY_MODE;
+  }
+
+  if (BootMode  == BOOT_IN_RECOVERY_MODE) {
+    Status = (*PeiServices)->InstallPpi (
+                               PeiServices,
+                               &mPpiListRecoveryBootMode
+                               );
+    ASSERT_EFI_ERROR (Status);
+  } else {
+    if (GetSleepTypeAfterWakeup (PeiServices, &SleepType)) {
+      switch (SleepType) {
+        case V_PCH_ACPI_PM1_CNT_S3:
+          BootMode = BOOT_ON_S3_RESUME;
+
+          //
+          // Determine if we're in capsule update mode
+          //
+          Status = (*PeiServices)->LocatePpi (
+                                     PeiServices,
+                                     &gPeiCapsulePpiGuid,
+                                     0,
+                                     NULL,
+                                     (void **)&Capsule
+                                     );
+
+          if (Status == EFI_SUCCESS) {
+            if (Capsule->CheckCapsuleUpdate ((EFI_PEI_SERVICES**)PeiServices) == EFI_SUCCESS) {
+              BootMode = BOOT_ON_FLASH_UPDATE;
+            }
+          }
+
+          break;
+
+        case V_PCH_ACPI_PM1_CNT_S4:
+          BootMode = BOOT_ON_S4_RESUME;
+          break;
+
+        case V_PCH_ACPI_PM1_CNT_S5:
+          BootMode = BOOT_ON_S5_RESUME;
+          break;
+      } // switch (SleepType)
+    }
+
+    //
+    // Check for Safe Mode
+    //
+  }
+
+  switch (BootMode) {
+    case BOOT_WITH_FULL_CONFIGURATION:
+      strBootMode = L"BOOT_WITH_FULL_CONFIGURATION";
+      break;
+    case BOOT_WITH_MINIMAL_CONFIGURATION:
+      strBootMode = L"BOOT_WITH_MINIMAL_CONFIGURATION";
+      break;
+    case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
+      strBootMode = L"BOOT_ASSUMING_NO_CONFIGURATION_CHANGES";
+      break;
+    case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:
+      strBootMode = L"BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS";
+      break;
+    case BOOT_WITH_DEFAULT_SETTINGS:
+      strBootMode = L"BOOT_WITH_DEFAULT_SETTINGS";
+      break;
+    case BOOT_ON_S4_RESUME:
+      strBootMode = L"BOOT_ON_S4_RESUME";
+      break;
+    case BOOT_ON_S5_RESUME:
+      strBootMode = L"BOOT_ON_S5_RESUME";
+      break;
+    case BOOT_ON_S2_RESUME:
+      strBootMode = L"BOOT_ON_S2_RESUME";
+      break;
+    case BOOT_ON_S3_RESUME:
+      strBootMode = L"BOOT_ON_S3_RESUME";
+      break;
+    case BOOT_ON_FLASH_UPDATE:
+      strBootMode = L"BOOT_ON_FLASH_UPDATE";
+      break;
+    case BOOT_IN_RECOVERY_MODE:
+      strBootMode = L"BOOT_IN_RECOVERY_MODE";
+      break;
+    default:
+      strBootMode = L"Unknown boot mode";
+  } // switch (BootMode)
+
+  DEBUG ((EFI_D_ERROR, "Setting BootMode to %s\n", strBootMode));
+  Status = (*PeiServices)->SetBootMode(
+                             PeiServices,
+                             BootMode
+                             );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+/**
+  Get sleep type after wakeup
+
+  @param PeiServices        Pointer to the PEI Service Table.
+  @param SleepType          Sleep type to be returned.
+
+  @retval TRUE              A wake event occured without power failure.
+  @retval FALSE             Power failure occured or not a wakeup.
+
+**/
+BOOLEAN
+GetSleepTypeAfterWakeup (
+  IN  CONST EFI_PEI_SERVICES          **PeiServices,
+  OUT UINT16                    *SleepType
+  )
+{
+  UINT16  Pm1Sts;
+  UINT16  Pm1Cnt;
+  UINT16  GenPmCon1;
+  GenPmCon1 = MmioRead16 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1);
+
+  //
+  // Read the ACPI registers
+  //
+  Pm1Sts  = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS);
+  Pm1Cnt  = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT);
+
+  if ((GenPmCon1 & (B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR | B_PCH_PMC_GEN_PMCON_GEN_RST_STS)) ||
+     (Pm1Sts & B_PCH_ACPI_PM1_STS_PRBTNOR)) {
+    //
+    // If power failure indicator, then don't attempt s3 resume.
+    // Clear PM1_CNT of S3 and set it to S5 as we just had a power failure, and memory has
+    // lost already.  This is to make sure no one will use PM1_CNT to check for S3 after
+    // power failure.
+    //
+    if ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S3) {
+      Pm1Cnt = ((Pm1Cnt & ~B_PCH_ACPI_PM1_CNT_SLP_TYP) | V_PCH_ACPI_PM1_CNT_S5);
+      IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT, Pm1Cnt);
+    }
+    //
+    // Clear Wake Status (WAK_STS)
+    //
+    IoWrite16 ((ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS), B_PCH_ACPI_PM1_STS_WAK);
+   }
+  //
+  // Get sleep type if a wake event occurred and there is no power failure
+  //
+  if ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S3) {
+    *SleepType = Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP;
+    return TRUE;
+  } else if ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S4){
+    *SleepType = Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+VOID
+SetPlatformBootMode (
+  IN CONST EFI_PEI_SERVICES             **PeiServices,
+  IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
+  )
+{
+  EFI_PLATFORM_SETUP_ID       PlatformSetupId;
+
+  ZeroMem(&PlatformSetupId, sizeof (EFI_PLATFORM_SETUP_ID));
+
+  CopyMem (&PlatformSetupId.SetupGuid,
+           &gEfiNormalSetupGuid,
+           sizeof (EFI_GUID));
+
+  if (CheckIfRecoveryMode(PeiServices, PlatformInfoHob)) {
+    //
+    // Recovery mode
+    //
+    CopyMem (&PlatformSetupId.SetupName,
+             &NORMAL_SETUP_NAME,
+             StrSize (NORMAL_SETUP_NAME));    
+    PlatformSetupId.PlatformBootMode = PLATFORM_RECOVERY_MODE;
+  } else if (CheckIfSafeMode(PeiServices, PlatformInfoHob)) {
+    //
+    // Safe mode also called config mode or maintenace mode.
+    //
+    CopyMem (&PlatformSetupId.SetupName,
+             &NORMAL_SETUP_NAME,
+             StrSize (NORMAL_SETUP_NAME));
+    PlatformSetupId.PlatformBootMode = PLATFORM_SAFE_MODE;
+
+  } else if(0) { // else if (CheckIfManufacturingMode(PeiServices)) {
+    //
+    // Manufacturing mode
+    //
+    CopyMem (&PlatformSetupId.SetupName,
+             MANUFACTURE_SETUP_NAME,
+             StrSize (MANUFACTURE_SETUP_NAME));
+    PlatformSetupId.PlatformBootMode = PLATFORM_MANUFACTURING_MODE;
+
+  } else {
+    //
+    // Default to normal mode.
+    //
+    CopyMem (&PlatformSetupId.SetupName,
+             &NORMAL_SETUP_NAME,
+             StrSize (NORMAL_SETUP_NAME));
+    PlatformSetupId.PlatformBootMode = PLATFORM_NORMAL_MODE;
+  }
+
+  BuildGuidDataHob (
+    &gEfiPlatformBootModeGuid,
+    &PlatformSetupId,
+    sizeof (EFI_PLATFORM_SETUP_ID)
+    );
+  return;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/CpuInitPeim.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/CpuInitPeim.c
new file mode 100644
index 0000000000..a3a3d5cbc9
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/CpuInitPeim.c
@@ -0,0 +1,44 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+    CpuInitPeim.c
+
+Abstract:
+
+    Functions for LpcSio initilization
+    It is needed for early onboard LAN controller disable/enable in platform setup.
+
+--*/
+
+#include "PlatformEarlyInit.h"
+
+
+EFI_STATUS
+PlatformCpuInit (
+  IN CONST EFI_PEI_SERVICES            **PeiServices,
+  IN SYSTEM_CONFIGURATION        *SystemConfiguration,
+  IN EFI_PLATFORM_CPU_INFO       *PlatformCpuInfo
+  )
+{
+  BOOLEAN                     ResetRequired;
+
+  //
+  // Variable initialization
+  //
+  ResetRequired = FALSE;
+
+
+  if (ResetRequired) {
+    CpuOnlyReset(PeiServices);
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c
new file mode 100644
index 0000000000..3fda6313d0
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c
@@ -0,0 +1,319 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+  Dimm.c
+
+Abstract:
+
+  PPI for reading SPD modules on DIMMs.
+
+--*/
+
+
+//
+// Header Files
+//
+#include "Platformearlyinit.h"
+
+#define DIMM_SOCKETS     4  // Total number of DIMM sockets allowed on
+                            //   the platform
+#define DIMM_SEGMENTS    1  // Total number of Segments Per DIMM.
+#define MEMORY_CHANNELS  2  // Total number of memory channels
+                            //   populated on the system board
+//
+// Prototypes
+//
+
+EFI_STATUS
+EFIAPI
+GetDimmState (
+  IN      EFI_PEI_SERVICES        **PeiServices,
+  IN      PEI_PLATFORM_DIMM_PPI   *This,
+  IN      UINT8                   Dimm,
+  OUT     PEI_PLATFORM_DIMM_STATE *State
+  );
+
+EFI_STATUS
+EFIAPI
+SetDimmState (
+  IN      EFI_PEI_SERVICES        **PeiServices,
+  IN      PEI_PLATFORM_DIMM_PPI   *This,
+  IN      UINT8                   Dimm,
+  IN      PEI_PLATFORM_DIMM_STATE *State
+  );
+
+EFI_STATUS
+EFIAPI
+ReadSpd (
+  IN      EFI_PEI_SERVICES      **PeiServices,
+  IN      PEI_PLATFORM_DIMM_PPI *This,
+  IN      UINT8                 Dimm,
+  IN      UINT8                 Offset,
+  IN      UINTN                 Count,
+  IN OUT  UINT8                 *Buffer
+  );
+
+static PEI_PLATFORM_DIMM_PPI mGchDimmPpi = {
+  DIMM_SOCKETS,
+  DIMM_SEGMENTS,
+  MEMORY_CHANNELS,
+  GetDimmState,
+  SetDimmState,
+  ReadSpd
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mPpiPlatformDimm = {
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gPeiPlatformDimmPpiGuid,
+  &mGchDimmPpi
+};
+
+
+//
+// Functions
+//
+
+/**
+  This function returns the current state of a single DIMM.  Present indicates
+  that the DIMM slot is physically populated.  Disabled indicates that the DIMM
+  should not be used.
+
+  @param PeiServices   PEI services table pointer
+  @param This          PPI pointer
+  @param Dimm          DIMM to read from
+  @param State         Pointer to a return buffer to be updated with the current state
+                       of the DIMM
+
+  @retval EFI_SUCCESS         The function completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+GetDimmState (
+  IN      EFI_PEI_SERVICES        **PeiServices,
+  IN      PEI_PLATFORM_DIMM_PPI   *This,
+  IN      UINT8                   Dimm,
+  OUT     PEI_PLATFORM_DIMM_STATE *State
+  )
+{
+  EFI_STATUS                    Status;
+  UINT8                         Buffer;
+
+  PEI_ASSERT (PeiServices, (Dimm < This->DimmSockets));
+
+  //
+  // A failure here does not necessarily mean that no DIMM is present.
+  // Read a single byte.  All we care about is the return status.
+  //
+  Status = ReadSpd (
+             PeiServices,
+             This,
+             Dimm,
+             0,
+             1,
+             &Buffer
+             );
+
+  if (EFI_ERROR (Status)) {
+    State->Present = 0;
+  } else {
+    State->Present = 1;
+  }
+
+  //
+  // BUGBUG: Update to check platform variable when it is available
+  //
+  State->Disabled = 0;
+  State->Reserved = 0;
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  This function updates the state of a single DIMM.
+
+  @param PeiServices          PEI services table pointer
+  @param This                 PPI pointer
+  @param Dimm                 DIMM to set state for
+  @param State                Pointer to the state information to set.
+
+  @retval EFI_SUCCESS         The function completed successfully.
+  @retval EFI_UNSUPPORTED     The function is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SetDimmState (
+  IN      EFI_PEI_SERVICES        **PeiServices,
+  IN      PEI_PLATFORM_DIMM_PPI   *This,
+  IN      UINT8                   Dimm,
+  IN      PEI_PLATFORM_DIMM_STATE *State
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  This function reads SPD information from a DIMM.
+
+  PeiServices   PEI services table pointer
+  This          PPI pointer
+  Dimm          DIMM to read from
+  Offset        Offset in DIMM
+  Count         Number of bytes
+  Buffer        Return buffer
+
+  @param EFI_SUCCESS              The function completed successfully.
+  @param EFI_DEVICE_ERROR         The DIMM being accessed reported a device error,
+                                  does not have an SPD module, or is not installed in
+                                  the system.
+  @retval EFI_TIMEOUT             Time out trying to read the SPD module.
+  @retval EFI_INVALID_PARAMETER   A parameter was outside the legal limits.
+
+**/
+EFI_STATUS
+EFIAPI
+ReadSpd (
+  IN      EFI_PEI_SERVICES      **PeiServices,
+  IN      PEI_PLATFORM_DIMM_PPI *This,
+  IN      UINT8                 Dimm,
+  IN      UINT8                 Offset,
+  IN      UINTN                 Count,
+  IN OUT  UINT8                 *Buffer
+  )
+{
+  EFI_STATUS                Status;
+  PEI_SMBUS_PPI             *Smbus;
+  UINTN                     Index;
+  UINTN                     Index1;
+  EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress;
+  EFI_SMBUS_DEVICE_COMMAND  Command;
+  UINTN                     Length;
+
+  Status = (**PeiServices).LocatePpi (
+                             PeiServices,
+                             &gPeiSmbusPpiGuid,   // GUID
+                             0,                   // INSTANCE
+                             NULL,                // EFI_PEI_PPI_DESCRIPTOR
+                             &Smbus               // PPI
+                             );
+  ASSERT_PEI_ERROR (PeiServices, Status);
+
+  switch (Dimm) {
+  case 0:
+    SlaveAddress.SmbusDeviceAddress = SMBUS_ADDR_CH_A_1 >> 1;
+    break;
+  case 1:
+    SlaveAddress.SmbusDeviceAddress = SMBUS_ADDR_CH_A_2 >> 1;
+    break;
+  case 2:
+    SlaveAddress.SmbusDeviceAddress = SMBUS_ADDR_CH_B_1 >> 1;
+    break;
+  case 3:
+    SlaveAddress.SmbusDeviceAddress = SMBUS_ADDR_CH_B_2 >> 1;
+    break;
+  default:
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Index = Count % 4;
+  if (Index != 0) {
+    //
+    // read the first serveral bytes to speed up following reading
+    //
+    for (Index1 = 0; Index1 < Index; Index1++) {
+      Length = 1;
+      Command = Offset + Index1;
+      Status = Smbus->Execute (
+                        PeiServices,
+                        Smbus,
+                        SlaveAddress,
+                        Command,
+                        EfiSmbusReadByte,
+                        FALSE,
+                        &Length,
+                        &Buffer[Index1]
+                        );
+      if (EFI_ERROR(Status)) {
+        return Status;
+      }
+    }
+  }
+
+  //
+  // Now collect all the remaining bytes on 4 bytes block
+  //
+  for (; Index < Count; Index += 2) {
+    Command = Index + Offset;
+    Length = 2;
+    Status = Smbus->Execute (
+                      PeiServices,
+                      Smbus,
+                      SlaveAddress,
+                      Command,
+                      EfiSmbusReadWord,
+                      FALSE,
+                      &Length,
+                      &Buffer[Index]
+                      );
+    if (EFI_ERROR(Status)) {
+      return Status;
+    }
+
+    Index += 2;
+    Command = Index + Offset;
+    Length = 2;
+    Status = Smbus->Execute (
+                      PeiServices,
+                      Smbus,
+                      SlaveAddress,
+                      Command,
+                      EfiSmbusReadWord,
+                      FALSE,
+                      &Length,
+                      &Buffer[Index]
+                      );
+    if (EFI_ERROR(Status)) {
+      return Status;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function initializes the PEIM.  It simply installs the DIMM PPI.
+
+  @param FfsHeader       Not used by this function
+  @param PeiServices     Pointer to PEI services table
+
+  @retval EFI_SUCCESS    The function completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+PeimInitializeDimm (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *SmbusPpi
+  )
+{
+  EFI_STATUS                    Status;
+
+  Status = (**PeiServices).InstallPpi (
+                             PeiServices,
+                             &mPpiPlatformDimm
+                             );
+  ASSERT_PEI_ERROR (PeiServices, Status);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/FlashMap.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/FlashMap.c
new file mode 100644
index 0000000000..f32eaac479
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/FlashMap.c
@@ -0,0 +1,143 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+
+Module Name:
+
+  FlashMap.c
+
+Abstract:
+
+  Build GUIDed HOBs for platform specific flash map.
+
+--*/
+
+#include "Efi.h"
+#include "Pei.h"
+#include "PeiLib.h"
+#include "PeiLib.h"
+#include "EfiFlashMap.h"
+#include EFI_PROTOCOL_CONSUMER (FirmwareVolumeBlock)
+#include EFI_GUID_DEFINITION (FlashMapHob)
+#include EFI_GUID_DEFINITION (SystemNvDataGuid)
+#include EFI_GUID_DEFINITION (FirmwareFileSystem)
+
+EFI_GUID                            mFvBlockGuid      = EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID;
+EFI_GUID                            mFfsGuid          = EFI_FIRMWARE_FILE_SYSTEM_GUID;
+EFI_GUID                            mSystemDataGuid   = EFI_SYSTEM_NV_DATA_HOB_GUID;
+
+static EFI_FLASH_AREA_DATA          mFlashAreaData[]  = {
+	//
+  // Variable area
+  //
+  { FixedPcdGet32 (PcdFlashNvStorageVariableBase),
+    FixedPcdGet32 (PcdFlashNvStorageVariableSize),
+    EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV,
+    EFI_FLASH_AREA_EFI_VARIABLES },
+
+  //
+  // Boot block 2nd part
+  //
+  { FixedPcdGet32 (PcdFlashFvRecovery2Base),
+    FixedPcdGet32 (PcdFlashFvRecovery2Size),
+    EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV,
+    EFI_FLASH_AREA_FTW_BACKUP },
+
+  //
+  // Recovery FV
+  //
+  { FixedPcdGet32 (PcdFlashFvRecoveryBase),
+    FixedPcdGet32 (PcdFlashFvRecoverySize),
+    EFI_FLASH_AREA_FV | EFI_FLASH_AREA_MEMMAPPED_FV,
+    EFI_FLASH_AREA_RECOVERY_BIOS },
+
+  //
+  // Main FV
+  //
+  { FixedPcdGet32 (PcdFlashFvMainBase),
+    FixedPcdGet32 (PcdFlashFvMainSize),
+    EFI_FLASH_AREA_FV | EFI_FLASH_AREA_MEMMAPPED_FV,
+    EFI_FLASH_AREA_MAIN_BIOS }
+
+};
+
+#define NUM_FLASH_AREA_DATA (ARRAY_SIZE (mFlashAreaData))
+
+/**
+  Build GUID HOBs for platform specific flash map.
+
+  @param FfsHeader     Pointer this FFS file header.
+  @param PeiServices   General purpose services available to every PEIM.
+
+  @retval EFI_SUCCESS   Guid HOBs for platform flash map is built.
+  @retval Otherwise     Failed to build the Guid HOB data.
+
+**/
+EFI_STATUS
+PeimInitializeFlashMap (
+  IN EFI_FFS_FILE_HEADER       *FfsHeader,
+  IN EFI_PEI_SERVICES          **PeiServices
+  )
+{
+  UINTN                         Index;
+  EFI_FLASH_AREA_HOB_DATA       FlashHobData;
+
+  //
+  // Build flash area entries as GUIDed HOBs.
+  //
+  for (Index = 0; Index < NUM_FLASH_AREA_DATA; Index++) {
+    ZeroMem(&FlashHobData, sizeof (EFI_FLASH_AREA_HOB_DATA));
+
+    FlashHobData.AreaType               = mFlashAreaData[Index].AreaType;
+    FlashHobData.NumberOfEntries        = 1;
+    FlashHobData.SubAreaData.Attributes = mFlashAreaData[Index].Attributes;
+    FlashHobData.SubAreaData.Base       = (EFI_PHYSICAL_ADDRESS) (UINTN) mFlashAreaData[Index].Base;
+    FlashHobData.SubAreaData.Length     = (EFI_PHYSICAL_ADDRESS) (UINTN) mFlashAreaData[Index].Length;
+
+    switch (FlashHobData.AreaType) {
+    case EFI_FLASH_AREA_RECOVERY_BIOS:
+    case EFI_FLASH_AREA_MAIN_BIOS:
+      CopyMem (
+        &FlashHobData.AreaTypeGuid,
+        &mFfsGuid,
+        sizeof (EFI_GUID)
+        );
+      CopyMem (
+        &FlashHobData.SubAreaData.FileSystem,
+        &mFvBlockGuid,
+        sizeof (EFI_GUID)
+        );
+      break;
+
+    case EFI_FLASH_AREA_GUID_DEFINED:
+      CopyMem (
+        &FlashHobData.AreaTypeGuid,
+        &mSystemDataGuid,
+        sizeof (EFI_GUID)
+        );
+      CopyMem (
+        &FlashHobData.SubAreaData.FileSystem,
+        &mFvBlockGuid,
+        sizeof (EFI_GUID)
+        );
+      break;
+
+    default:
+      break;
+    }
+
+    PeiBuildHobGuidData(PeiServices,
+                        &gEfiFlashMapHobGuid,
+                        &FlashHobData,
+                        sizeof (EFI_FLASH_AREA_HOB_DATA)
+                        );
+  }
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.c
new file mode 100644
index 0000000000..6711f54863
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.c
@@ -0,0 +1,168 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+ LegacySpeaker.c
+
+Abstract:
+
+  This file implements PEIM for Legacy Speaker. This file is valid for platforms both
+  on IA32 and Itanium Product Family
+
+--*/
+
+#include "PlatformEarlyInit.h"
+
+EFI_STATUS
+OutputBeep (
+  IN  CONST EFI_PEI_SERVICES  **PeiServices,
+  IN  UINTN             NumberOfBeep,
+  IN  UINTN             BeepDuration,
+  IN  UINTN             TimerInterval
+  );
+
+/**
+  This function will enable the speaker to generate beep
+
+  @param PeiServices     PeiServices to locate PPI
+
+  @retval EFI_STATUS
+
+**/
+EFI_STATUS
+TurnOnSpeaker (
+  IN  CONST EFI_PEI_SERVICES    **PeiServices
+  )
+{
+  UINT8                   Data;
+  Data = IoRead8 (EFI_SPEAKER_CONTROL_PORT);
+  Data |= 0x03;
+  IoWrite8(EFI_SPEAKER_CONTROL_PORT, Data);
+  return EFI_SUCCESS;
+}
+
+/**
+  This function will stop beep from speaker.
+
+  @param  PeiServices     PeiServices to locate PPI
+
+  @retval Status
+
+**/
+EFI_STATUS
+TurnOffSpeaker (
+  IN  CONST EFI_PEI_SERVICES    **PeiServices
+  )
+{
+  UINT8                   Data;
+
+  Data = IoRead8 (EFI_SPEAKER_CONTROL_PORT);
+  Data &= 0xFC;
+  IoWrite8(EFI_SPEAKER_CONTROL_PORT, Data);
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+OutputBeep (
+  IN  CONST EFI_PEI_SERVICES  **PeiServices,
+  IN  UINTN             NumberOfBeep,
+  IN  UINTN             BeepDuration,
+  IN  UINTN             TimeInterval
+  )
+{
+  UINTN           Num;
+  EFI_PEI_STALL_PPI*  StallPpi;
+
+  (**PeiServices).LocatePpi (PeiServices, &gEfiPeiStallPpiGuid, 0, NULL, (void **)&StallPpi);
+
+  for (Num=0; Num < NumberOfBeep; Num++) {
+    TurnOnSpeaker (PeiServices);
+    StallPpi->Stall(PeiServices, StallPpi, BeepDuration);
+    TurnOffSpeaker(PeiServices);
+    StallPpi->Stall(PeiServices, StallPpi, TimeInterval);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function will program the speaker tone frequency. The value should be with 64k
+  boundary since it takes only 16 bit value which gets programmed in two step IO opearattion
+
+  Frequency     - A value which should be 16 bit only.
+
+  EFI_SUCESS
+
+**/
+EFI_STATUS
+EFIAPI
+ProgramToneFrequency (
+  IN  CONST EFI_PEI_SERVICES                  **PeiServices,
+  IN  UINT16                            Frequency
+  )
+{
+  UINT8                   Data;
+
+  Data = 0xB6;
+  IoWrite8(EFI_TIMER_CONTROL_PORT, Data);
+
+  Data = (UINT8)(Frequency & 0x00FF);
+  IoWrite8(EFI_TIMER_2_PORT, Data);
+  Data = (UINT8)((Frequency & 0xFF00) >> 8);
+  IoWrite8(EFI_TIMER_2_PORT, Data);
+  return EFI_SUCCESS;
+}
+
+/**
+  This function will generate the beep for specified duration.
+
+  @param  PeiServices       PeiServices to locate various PPIs
+  @param  NumberOfBeeps     Number of beeps which user want to produce
+  @param  BeepDuration      Duration for speaker gate need to be enabled
+  @param  TimeInterval      Interval between each beep
+
+  @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+GenerateBeepTone (
+  IN  CONST EFI_PEI_SERVICES                  **PeiServices,
+  IN  UINTN                             NumberOfBeeps,
+  IN  UINTN                             BeepDuration,
+  IN  UINTN                             TimeInterval
+  )
+{
+
+  if ((NumberOfBeeps == 1) && (BeepDuration == 0) && (TimeInterval == 0)) {
+    TurnOnSpeaker (PeiServices);
+    return EFI_SUCCESS;
+  }
+
+  if ((NumberOfBeeps == 0) && (BeepDuration == 0) && (TimeInterval == 0)) {
+    TurnOffSpeaker (PeiServices);
+    return EFI_SUCCESS;
+  }
+
+  if (BeepDuration == 0) {
+    BeepDuration = EFI_DEFAULT_SHORT_BEEP_DURATION;
+  }
+
+  if (TimeInterval == 0) {
+    TimeInterval = EFI_DEFAULT_BEEP_TIME_INTERVAL;
+  }
+
+  OutputBeep (PeiServices, NumberOfBeeps, BeepDuration, TimeInterval);
+  return EFI_SUCCESS;
+
+
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.h b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.h
new file mode 100644
index 0000000000..dee022bf9b
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.h
@@ -0,0 +1,71 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+ LegacySpeaker.h
+
+Abstract:
+
+  Speaker enabling related data
+
+--*/
+
+#ifndef _PEI_LEGACY_SPEAKER_H
+#define _PEI_LEGACY_SPEAKER_H
+
+
+//
+// Speaker Related Port Information
+//
+#define EFI_TIMER_COUNTER_PORT            0x40
+#define EFI_TIMER_CONTROL_PORT            0x43
+#define EFI_TIMER_2_PORT                  0x42
+#define EFI_SPEAKER_CONTROL_PORT          0x61
+
+#define EFI_SPEAKER_OFF_MASK              0xFC
+
+#define EFI_DEFAULT_BEEP_FREQUENCY        0x500
+
+//
+// Default Intervals/Beep Duration
+//
+#define EFI_DEFAULT_LONG_BEEP_DURATION    0x70000
+#define EFI_DEFAULT_SHORT_BEEP_DURATION   0x50000
+#define EFI_DEFAULT_BEEP_TIME_INTERVAL    0x20000
+
+
+EFI_STATUS
+EFIAPI
+ProgramToneFrequency (
+  IN  CONST EFI_PEI_SERVICES  **PeiServices,
+  IN  UINT16 Frequency
+  );
+
+
+EFI_STATUS
+EFIAPI
+GenerateBeepTone (
+  IN  CONST EFI_PEI_SERVICES                  **PeiServices,
+  IN  UINTN                             NumberOfBeeps,
+  IN  UINTN                             BeepDuration,
+  IN  UINTN                             TimeInterval
+  );
+
+EFI_STATUS
+TurnOnSpeaker (
+  IN  CONST EFI_PEI_SERVICES  **PeiServices
+  );
+
+EFI_STATUS
+TurnOffSpeaker (
+  IN  CONST EFI_PEI_SERVICES  **PeiServices
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MchInit.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MchInit.c
new file mode 100644
index 0000000000..7d1a20c104
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MchInit.c
@@ -0,0 +1,72 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+    MchInit.c
+
+Abstract:
+
+
+--*/
+
+
+#include "PlatformEarlyInit.h"
+
+#define PSE_PAGE_SIZE 0x400000   // 4MB
+
+extern  BOOLEAN ImageInMemory;
+
+
+VOID
+EfiCommonLibEnablePsePaging (
+  IN UINT32   PDBR
+  );
+
+VOID
+EfiCommonLibDisablePsePaging (
+  );
+
+/**
+
+  Initialize the MCH Thermal Sensor
+
+**/
+VOID
+InitMchThermalSensor()
+{
+}
+
+/**
+
+  Programs and enables the CRID for MCH and ICH
+
+**/
+VOID
+ProgramMchCRID(
+  IN CONST EFI_PEI_SERVICES            **PeiServices
+  )
+{
+}
+
+/**
+
+  Initialize the GPIO IO selection, GPIO USE selection, and GPIO signal inversion registers
+
+**/
+VOID
+MchInit (
+  IN CONST EFI_PEI_SERVICES          **PeiServices
+  )
+{
+
+  return;
+}
+
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryCallback.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryCallback.c
new file mode 100644
index 0000000000..070848ed1e
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryCallback.c
@@ -0,0 +1,338 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  MemoryCallback.c
+
+Abstract:
+
+  EFI 2.0 PEIM to provide the platform support functionality on the Bridgeport.
+
+--*/
+
+#include "PlatformEarlyInit.h"
+
+
+VOID
+UpdateDefaultSetupValue (
+  IN  EFI_PLATFORM_INFO_HOB       *PlatformInfo
+  )
+{
+return;
+}
+
+/**
+  PEI termination callback.
+
+  @param PeiServices         General purpose services available to every PEIM.
+  @param NotifyDescriptor    Not uesed.
+  @param Ppi                 Not uesed.
+
+  @retval EFI_SUCCESS        If the interface could be successfully
+                             installed.
+
+**/
+EFI_STATUS
+EFIAPI    
+EndOfPeiPpiNotifyCallback (
+  IN CONST EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+  )
+{
+  EFI_STATUS                  Status;
+  UINT64                      LowUncableBase;
+  EFI_PLATFORM_INFO_HOB       *PlatformInfo;
+  UINT32                      HecBaseHigh;
+  EFI_BOOT_MODE               BootMode;
+  EFI_PEI_HOB_POINTERS        Hob;
+
+  Status = (*PeiServices)->GetBootMode(
+                             PeiServices,
+                             &BootMode
+                             );
+
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Set the some PCI and chipset range as UC
+  // And align to 1M at leaset
+  //
+  Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid);
+  ASSERT (Hob.Raw != NULL);
+  PlatformInfo = GET_GUID_HOB_DATA(Hob.Raw);
+
+  UpdateDefaultSetupValue (PlatformInfo);
+
+  DEBUG ((EFI_D_ERROR, "Memory TOLM: %X\n", PlatformInfo->MemData.MemTolm));
+  DEBUG ((EFI_D_ERROR, "PCIE OSBASE: %lX\n", PlatformInfo->PciData.PciExpressBase));
+  DEBUG (
+    (EFI_D_ERROR,
+    "PCIE   BASE: %lX     Size : %X\n",
+    PlatformInfo->PciData.PciExpressBase,
+    PlatformInfo->PciData.PciExpressSize)
+    );
+  DEBUG (
+    (EFI_D_ERROR,
+    "PCI32  BASE: %X     Limit: %X\n",
+    PlatformInfo->PciData.PciResourceMem32Base,
+    PlatformInfo->PciData.PciResourceMem32Limit)
+    );
+  DEBUG (
+    (EFI_D_ERROR,
+    "PCI64  BASE: %lX     Limit: %lX\n",
+    PlatformInfo->PciData.PciResourceMem64Base,
+    PlatformInfo->PciData.PciResourceMem64Limit)
+    );
+  DEBUG ((EFI_D_ERROR, "UC    START: %lX     End  : %lX\n", PlatformInfo->MemData.MemMir0, PlatformInfo->MemData.MemMir1));
+
+  LowUncableBase = PlatformInfo->MemData.MemMaxTolm;
+  LowUncableBase &= (0x0FFF00000);
+
+  if (BootMode != BOOT_ON_S3_RESUME) {
+    //
+    // In BIOS, HECBASE will be always below 4GB
+    //
+    HecBaseHigh = (UINT32) RShiftU64 (PlatformInfo->PciData.PciExpressBase, 28);
+    ASSERT (HecBaseHigh < 16);
+  }
+
+  return Status;
+}
+
+/**
+  Install Firmware Volume Hob's once there is main memory
+
+  @param PeiServices       General purpose services available to every PEIM.
+  @param NotifyDescriptor  Notify that this module published.
+  @param Ppi               PPI that was installed.
+
+  @retval EFI_SUCCESS     The function completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+MemoryDiscoveredPpiNotifyCallback (
+  IN CONST EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_BOOT_MODE               BootMode;
+  EFI_CPUID_REGISTER          FeatureInfo;
+  UINT8                       CpuAddressWidth;
+  UINT16                      Pm1Cnt;
+  EFI_PEI_HOB_POINTERS        Hob;
+  EFI_PLATFORM_INFO_HOB       *PlatformInfo;
+  UINT32                      RootComplexBar;
+  UINT32                      PmcBase;
+  UINT32                      IoBase;
+  UINT32                      IlbBase;
+  UINT32                      SpiBase;
+  UINT32                      MphyBase;
+
+  //
+  // Get Platform Info HOB
+  //
+  Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid);
+  ASSERT (Hob.Raw != NULL);
+  PlatformInfo = GET_GUID_HOB_DATA(Hob.Raw);
+
+  Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode);
+
+  //
+  // Check if user wants to turn off in PEI phase
+  //
+  if ((BootMode != BOOT_ON_S3_RESUME) && (BootMode != BOOT_ON_FLASH_UPDATE)) {
+    CheckPowerOffNow();
+  } else {
+    Pm1Cnt  = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT);
+    Pm1Cnt &= ~B_PCH_ACPI_PM1_CNT_SLP_TYP;
+    IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT, Pm1Cnt);
+  }
+
+  #ifndef MINNOW2_FSP_BUILD
+  //
+  // Set PEI cache mode here
+  //
+  SetPeiCacheMode (PeiServices);
+  #endif
+
+  //
+  //  Pulish memory tyoe info
+  //
+  PublishMemoryTypeInfo ();
+
+  //
+  // Work done if on a S3 resume
+  //
+  if (BootMode == BOOT_ON_S3_RESUME) {
+    //
+    //Program the side band packet register to send a sideband message to Punit
+    //To indicate that DRAM has been initialized and PUNIT FW base address in memory.
+    //
+    return EFI_SUCCESS;
+  }
+
+  RootComplexBar = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_RCBA ) & B_PCH_LPC_RCBA_BAR;
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_MEMORY_MAPPED_IO,
+    (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+    RootComplexBar,
+    0x1000
+    );
+  DEBUG ((EFI_D_INFO, "RootComplexBar     : 0x%x\n", RootComplexBar));
+
+  PmcBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_PMC_BASE ) & B_PCH_LPC_PMC_BASE_BAR;
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_MEMORY_MAPPED_IO,
+    (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+    PmcBase,
+    0x1000
+    );
+  DEBUG ((EFI_D_INFO, "PmcBase            : 0x%x\n", PmcBase));
+
+  IoBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_IO_BASE ) & B_PCH_LPC_IO_BASE_BAR;
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_MEMORY_MAPPED_IO,
+    (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+    IoBase,
+    0x4000
+    );
+  DEBUG ((EFI_D_INFO, "IoBase             : 0x%x\n", IoBase));
+
+  IlbBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_ILB_BASE ) & B_PCH_LPC_ILB_BASE_BAR;
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_MEMORY_MAPPED_IO,
+    (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+    IlbBase,
+    0x1000
+    );
+  DEBUG ((EFI_D_INFO, "IlbBase            : 0x%x\n", IlbBase));
+
+  SpiBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_SPI_BASE ) & B_PCH_LPC_SPI_BASE_BAR;
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_MEMORY_MAPPED_IO,
+    (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+    SpiBase,
+    0x1000
+    );
+  DEBUG ((EFI_D_INFO, "SpiBase            : 0x%x\n", SpiBase));
+
+  MphyBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_MPHY_BASE ) & B_PCH_LPC_MPHY_BASE_BAR;
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_MEMORY_MAPPED_IO,
+    (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+    MphyBase,
+    0x100000
+    );
+  DEBUG ((EFI_D_INFO, "MphyBase           : 0x%x\n", MphyBase));
+
+  //
+  // Local APIC
+  //
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_MEMORY_MAPPED_IO,
+    (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+    LOCAL_APIC_ADDRESS,
+    0x1000
+  );
+  DEBUG ((EFI_D_INFO, "LOCAL_APIC_ADDRESS : 0x%x\n", LOCAL_APIC_ADDRESS));
+
+  //
+  // IO APIC
+  //
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_MEMORY_MAPPED_IO,
+    (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+    IO_APIC_ADDRESS,
+    0x1000
+  );
+  DEBUG ((EFI_D_INFO, "IO_APIC_ADDRESS    : 0x%x\n", IO_APIC_ADDRESS));
+
+  //
+  // Adding the PCIE Express area to the E820 memory table as type 2 memory.
+  //
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_MEMORY_MAPPED_IO,
+    (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+    PlatformInfo->PciData.PciExpressBase,
+    PlatformInfo->PciData.PciExpressSize
+    );
+  DEBUG ((EFI_D_INFO, "PciExpressBase     : 0x%x\n", PlatformInfo->PciData.PciExpressBase));
+
+  //
+  // Adding the Flashpart to the E820 memory table as type 2 memory.
+  //
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_FIRMWARE_DEVICE,
+    (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+    FixedPcdGet32 (PcdFlashAreaBaseAddress),
+    FixedPcdGet32 (PcdFlashAreaSize)
+    );
+  DEBUG ((EFI_D_INFO, "FLASH_BASE_ADDRESS : 0x%x\n", FixedPcdGet32 (PcdFlashAreaBaseAddress)));
+
+  //
+  // Create a CPU hand-off information
+  //
+  CpuAddressWidth = 32;
+  AsmCpuid (EFI_CPUID_EXTENDED_FUNCTION, &FeatureInfo.RegEax, &FeatureInfo.RegEbx, &FeatureInfo.RegEcx, &FeatureInfo.RegEdx);
+  if (FeatureInfo.RegEax >= EFI_CPUID_VIRT_PHYS_ADDRESS_SIZE) {
+    AsmCpuid (EFI_CPUID_VIRT_PHYS_ADDRESS_SIZE, &FeatureInfo.RegEax, &FeatureInfo.RegEbx, &FeatureInfo.RegEcx, &FeatureInfo.RegEdx);
+    CpuAddressWidth = (UINT8) (FeatureInfo.RegEax & 0xFF);
+  }
+
+  BuildCpuHob(CpuAddressWidth, 16);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+
+}
+
+
+EFI_STATUS
+ValidateFvHeader (
+  IN EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader
+  )
+{
+  UINT16  *Ptr;
+  UINT16  HeaderLength;
+  UINT16  Checksum;
+
+  //
+  // Verify the header revision, header signature, length
+  // Length of FvBlock cannot be 2**64-1
+  // HeaderLength cannot be an odd number
+  //
+  if ((FwVolHeader->Revision != EFI_FVH_REVISION) ||
+      (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||
+      (FwVolHeader->FvLength == ((UINT64) -1)) ||
+      ((FwVolHeader->HeaderLength & 0x01) != 0)
+      ) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Verify the header checksum
+  //
+  HeaderLength  = (UINT16) (FwVolHeader->HeaderLength / 2);
+  Ptr           = (UINT16 *) FwVolHeader;
+  Checksum      = 0;
+  while (HeaderLength > 0) {
+    Checksum = *Ptr++;
+    HeaderLength--;
+  }
+
+  if (Checksum != 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryPeim.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryPeim.c
new file mode 100644
index 0000000000..e6189b7713
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryPeim.c
@@ -0,0 +1,408 @@
+/** @file
+
+  Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+  MemoryPeim.c
+
+Abstract:
+
+  Tiano PEIM to provide the platform support functionality.
+  This file implements the Platform Memory Range PPI
+
+--*/
+
+#include "PlatformEarlyInit.h"
+
+//
+// Need min. of 48MB PEI phase
+//
+#define  PEI_MIN_MEMORY_SIZE               (6 * 0x800000)
+#define  PEI_RECOVERY_MIN_MEMORY_SIZE      (6 * 0x800000)
+
+//
+// This is the memory needed for PEI to start up DXE.
+//
+// Over-estimating this size will lead to higher fragmentation
+// of main memory.  Under-estimation of this will cause catastrophic
+// failure of PEI to load DXE.  Generally, the failure may only be
+// realized during capsule updates.
+//
+#define PRERESERVED_PEI_MEMORY ( \
+  EFI_SIZE_TO_PAGES (3 * 0x800000)   /* PEI Core memory based stack          */ \
+  )
+
+EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
+  { EfiACPIReclaimMemory,       0x40  },    // 0x40 pages = 256k for ASL
+  { EfiACPIMemoryNVS,           0x100 },    // 0x100 pages = 1 MB for S3, SMM, HII, etc
+  { EfiReservedMemoryType,      0x600 },    // 48k for BIOS Reserved
+  { EfiMemoryMappedIO,          0     },
+  { EfiMemoryMappedIOPortSpace, 0     },
+  { EfiPalCode,                 0     },
+  { EfiRuntimeServicesCode,     0x200 },
+  { EfiRuntimeServicesData,     0x100 },
+  { EfiLoaderCode,              0x100 },
+  { EfiLoaderData,              0x100 },
+  { EfiBootServicesCode,        0x800 },
+  { EfiBootServicesData,        0x2500},
+  { EfiConventionalMemory,      0     },
+  { EfiUnusableMemory,          0     },
+  { EfiMaxMemoryType,           0     }
+};
+
+STATIC
+EFI_STATUS
+GetMemorySize (
+  IN  CONST EFI_PEI_SERVICES    **PeiServices,
+  OUT UINT64              *LowMemoryLength,
+  OUT UINT64              *HighMemoryLength
+  );
+
+
+/**
+  Initializes the valid address mask for MTRRs.
+
+  This function initializes the valid bits mask and valid address mask for MTRRs.
+
+**/
+UINT64
+InitializeAddressMtrrMask (
+  VOID
+  )
+{
+  UINT32                    RegEax;
+  UINT8                     PhysicalAddressBits; 
+  UINT64                    ValidMtrrBitsMask;
+
+  AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+
+  if (RegEax >= 0x80000008) {
+    AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
+
+    PhysicalAddressBits = (UINT8) RegEax;
+  } else {
+    PhysicalAddressBits = 36;
+  }
+
+  ValidMtrrBitsMask    = LShiftU64 (1, PhysicalAddressBits) - 1;
+  return (ValidMtrrBitsMask & 0xfffffffffffff000ULL);
+}
+
+EFI_STATUS
+EFIAPI
+SetPeiCacheMode (
+  IN  CONST EFI_PEI_SERVICES    **PeiServices
+  )
+{
+  EFI_STATUS              Status;
+  PEI_CACHE_PPI           *CachePpi;
+
+  EFI_BOOT_MODE           BootMode;
+  UINT64                  MemoryLength;
+  UINT64                  MemOverflow;
+  UINT64                  MemoryLengthUc;
+  UINT64                  MaxMemoryLength;
+  UINT64                  LowMemoryLength;
+  UINT64                  HighMemoryLength;
+  UINT8                   Index;
+  MTRR_SETTINGS           MtrrSetting;
+  UINT64                  ValidMtrrAddressMask;
+
+  //
+  // Load Cache PPI
+  //
+  Status = (**PeiServices).LocatePpi (
+             PeiServices,
+             &gPeiCachePpiGuid,    // GUID
+             0,                    // Instance
+             NULL,                 // EFI_PEI_PPI_DESCRIPTOR
+             (void **)&CachePpi             // PPI
+             );
+  if (!EFI_ERROR(Status)) {
+    //
+    // Clear the CAR Settings (Default Cache Type => UC)
+    //
+    DEBUG ((EFI_D_INFO, "Reset cache attribute and disable CAR. \n"));
+    CachePpi->ResetCache(
+                (EFI_PEI_SERVICES**)PeiServices,
+                CachePpi
+                );
+ }
+
+
+  //
+  // Variable initialization
+  //
+  LowMemoryLength = 0;
+  HighMemoryLength = 0;
+  MemoryLengthUc = 0;
+
+  Status = (*PeiServices)->GetBootMode (
+                             PeiServices,
+                             &BootMode
+                             );
+
+  ValidMtrrAddressMask = InitializeAddressMtrrMask ();
+
+  //
+  // Determine memory usage
+  //
+  GetMemorySize (
+    PeiServices,
+    &LowMemoryLength,
+    &HighMemoryLength
+    );
+
+  LowMemoryLength  = (EFI_PHYSICAL_ADDRESS)MmPci32( 0, 0, 2, 0, 0x70);
+  LowMemoryLength   &=  0xFFF00000ULL;
+
+  MaxMemoryLength = LowMemoryLength;
+
+  //
+  // Round up to nearest 256MB with high memory and 64MB w/o high memory
+  //
+  if (HighMemoryLength != 0 ) {
+    MemOverflow = (LowMemoryLength & 0x0fffffff);
+    if (MemOverflow != 0) {
+      MaxMemoryLength = LowMemoryLength + (0x10000000 - MemOverflow);
+    }
+  } else {
+    MemOverflow = (LowMemoryLength & 0x03ffffff);
+    if (MemOverflow != 0) {
+      MaxMemoryLength = LowMemoryLength + (0x4000000 - MemOverflow);
+    }
+  }
+
+  ZeroMem (&MtrrSetting, sizeof(MTRR_SETTINGS));
+  for (Index = 0; Index < 2; Index++) {
+    MtrrSetting.Fixed.Mtrr[Index]=0x0606060606060606;
+   }
+  for (Index = 2; Index < 11; Index++) {
+    MtrrSetting.Fixed.Mtrr[Index]=0x0505050505050505;
+   }
+
+  //
+  // Cache the flash area to improve the boot performance in PEI phase
+  //
+  Index = 0;
+  ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[0].Base)->Uint64 = FixedPcdGet32 (PcdFlashAreaBaseAddress);
+  ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[0].Base)->Bits.Type = CacheWriteProtected;
+  ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[0].Mask)->Uint64 = (~((UINT64)(FixedPcdGet32 (PcdFlashAreaSize) - 1))) & ValidMtrrAddressMask;
+  ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[0].Mask)->Bits.V = 1;
+
+  Index ++;
+
+  MemOverflow =0;
+  while (MaxMemoryLength > MemOverflow){
+    MemoryLength = MaxMemoryLength - MemOverflow;
+    MemoryLength = GetPowerOfTwo64 (MemoryLength);
+
+    ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Base)->Uint64 = MemOverflow & ValidMtrrAddressMask;
+    ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Base)->Bits.Type = CacheWriteBack;
+    ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Mask)->Uint64 = (~(MemoryLength - 1)) & ValidMtrrAddressMask;
+    ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Mask)->Bits.V = 1;
+
+    MemOverflow += MemoryLength;
+    Index++;
+  }
+
+  MemoryLength = LowMemoryLength;
+
+  while (MaxMemoryLength != MemoryLength) {
+    MemoryLengthUc = GetPowerOfTwo64 (MaxMemoryLength - MemoryLength);
+
+    ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Base)->Uint64 = (MaxMemoryLength - MemoryLengthUc) & ValidMtrrAddressMask;
+    ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Base)->Bits.Type = CacheUncacheable;
+    ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Mask)->Uint64 = (~(MemoryLengthUc   - 1)) & ValidMtrrAddressMask;
+    ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Mask)->Bits.V = 1;
+
+    MaxMemoryLength -= MemoryLengthUc;
+    Index++;
+  }
+
+  MemOverflow =0x100000000;
+  while (HighMemoryLength > 0) {
+
+    MemoryLength = HighMemoryLength;
+    MemoryLength = GetPowerOfTwo64 (MemoryLength);
+    if (MemoryLength > MemOverflow){
+      MemoryLength = MemOverflow;
+    }
+
+    ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Base)->Uint64 = MemOverflow & ValidMtrrAddressMask;
+    ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Base)->Bits.Type = CacheWriteBack;
+    ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Mask)->Uint64 = (~(MemoryLength - 1)) & ValidMtrrAddressMask;
+    ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Mask)->Bits.V = 1;
+
+    MemOverflow += MemoryLength;
+    HighMemoryLength -= MemoryLength;
+    Index++;
+  }
+
+
+  for (Index = 0; Index < MTRR_NUMBER_OF_VARIABLE_MTRR; Index++) {
+    if (MtrrSetting.Variables.Mtrr[Index].Base == 0){
+      break;
+    }
+    DEBUG ((EFI_D_INFO, "Base=%lx, Mask=%lx\n",MtrrSetting.Variables.Mtrr[Index].Base ,MtrrSetting.Variables.Mtrr[Index].Mask));
+  }
+
+  //
+  // set FE/E bits for IA32_MTRR_DEF_TYPE
+  //
+  MtrrSetting.MtrrDefType |=  3 <<10;
+
+  MtrrSetAllMtrrs(&MtrrSetting);
+  //
+  // Dump MTRR Setting
+  //
+  MtrrDebugPrintAllMtrrs ();
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+SetDxeCacheMode (
+  IN  CONST EFI_PEI_SERVICES    **PeiServices
+  )
+{
+  //
+  // This is not needed for now.
+  //
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetMemorySize (
+  IN  CONST EFI_PEI_SERVICES    **PeiServices,
+  OUT UINT64              *LowMemoryLength,
+  OUT UINT64              *HighMemoryLength
+  )
+{
+  EFI_STATUS              Status;
+  EFI_PEI_HOB_POINTERS    Hob;
+
+  *HighMemoryLength = 0;
+  *LowMemoryLength = 0x100000;
+
+  //
+  // Get the HOB list for processing
+  //
+  Status = (*PeiServices)->GetHobList (PeiServices, (void **)&Hob.Raw);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  //
+  // Collect memory ranges
+  //
+  while (!END_OF_HOB_LIST (Hob)) {
+    if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+      if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
+        //
+        // Need memory above 1MB to be collected here
+        //
+        if (Hob.ResourceDescriptor->PhysicalStart >= 0x100000 &&
+            Hob.ResourceDescriptor->PhysicalStart < (EFI_PHYSICAL_ADDRESS) 0x100000000) {
+          *LowMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);
+        } else if (Hob.ResourceDescriptor->PhysicalStart >= (EFI_PHYSICAL_ADDRESS) 0x100000000) {
+          *HighMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);
+        }
+      }
+    }
+    Hob.Raw = GET_NEXT_HOB (Hob);
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Publish Memory Type Information.
+
+  @param  NULL
+
+  @retval EFI_SUCCESS    Success.
+  @retval Others         Errors have occurred.
+**/
+
+EFI_STATUS
+EFIAPI
+PublishMemoryTypeInfo (
+  void
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;
+  UINTN                           DataSize;
+  EFI_MEMORY_TYPE_INFORMATION     MemoryData[EfiMaxMemoryType + 1];
+
+  Status = PeiServicesLocatePpi (
+             &gEfiPeiReadOnlyVariable2PpiGuid,
+             0,
+             NULL,
+            (void **)&Variable
+             );
+  if (EFI_ERROR(Status)) {
+    DEBUG((EFI_D_ERROR, "WARNING: Locating Pei variable failed 0x%x \n", Status));
+    DEBUG((EFI_D_ERROR, "Build Hob from default\n"));
+    //
+    // Build the default GUID'd HOB for DXE
+    //
+    BuildGuidDataHob (
+      &gEfiMemoryTypeInformationGuid,
+      mDefaultMemoryTypeInformation,
+      sizeof (mDefaultMemoryTypeInformation)
+      );
+
+    return Status;
+  }
+
+
+  DataSize = sizeof (MemoryData);
+
+  //
+  // This variable is saved in BDS stage. Now read it back
+  //
+  Status = Variable->GetVariable (
+                       Variable,
+                       EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
+                       &gEfiMemoryTypeInformationGuid,
+                       NULL,
+                       &DataSize,
+                       &MemoryData
+                       );
+  if (EFI_ERROR (Status)) {
+  	//
+    //build default
+    //
+    DEBUG((EFI_D_ERROR, "Build Hob from default\n"));
+    BuildGuidDataHob (
+      &gEfiMemoryTypeInformationGuid,
+      mDefaultMemoryTypeInformation,
+      sizeof (mDefaultMemoryTypeInformation)
+      );
+
+  } else {
+  	//
+    // Build the GUID'd HOB for DXE from variable
+    //
+    DEBUG((EFI_D_ERROR, "Build Hob from variable \n"));
+    BuildGuidDataHob (
+      &gEfiMemoryTypeInformationGuid,
+      MemoryData,
+      DataSize
+      );
+  }
+
+  return Status;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PchInitPeim.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PchInitPeim.c
new file mode 100644
index 0000000000..38b17156f4
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PchInitPeim.c
@@ -0,0 +1,808 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  PchInitPeim.c
+
+Abstract:
+
+  Do Early PCH platform initialization.
+
+
+--*/
+
+#include "PlatformEarlyInit.h"
+#include "Ppi/PchPlatformPolicy.h"
+#include "PchRegs.h"
+#include <Ppi/PchUsbPolicy.h>
+#include "Ppi/PchInit.h"
+#include <Library/PcdLib.h>
+
+EFI_GUID  gPchPlatformPolicyPpiGuid = PCH_PLATFORM_POLICY_PPI_GUID;
+
+#define MC_PMSTS_OFFSET                 0xC
+
+#define DEFAULT_BUS_INFO                0x2020
+
+
+#define PCI_LPC_BASE    (0x8000F800)
+#define PCI_LPC_REG(x)  (PCI_LPC_BASE + (x))
+#define PCIEX_BASE_ADDRESS                        0xE0000000
+#define PciD31F0RegBase                           PCIEX_BASE_ADDRESS + (UINT32) (31 << 15)
+
+VOID
+PchPolicySetupInit (
+  IN CONST EFI_PEI_SERVICES **PeiServices,
+  IN SYSTEM_CONFIGURATION   *SystemConfiguration
+  );
+
+VOID
+PchInitInterrupt (
+  IN SYSTEM_CONFIGURATION  *SystemConfiguration
+  );
+
+EFI_STATUS
+InstallPeiPchUsbPolicy (
+  IN CONST  EFI_PEI_SERVICES  **PeiServices
+  );
+
+#ifndef __GNUC__
+#pragma warning (push)
+#pragma warning (disable : 4245)
+#pragma warning (pop)
+#endif
+
+UINT8
+ReadCmosBank1Byte (
+  IN UINT8                      Address
+  )
+{
+  UINT8                           Data;
+
+  IoWrite8(R_PCH_RTC_EXT_INDEX, Address);
+  Data = IoRead8 (R_PCH_RTC_EXT_TARGET);
+  return Data;
+}
+
+VOID
+WriteCmosBank1Byte (
+  IN UINT8                     Address,
+  IN UINT8                     Data
+  )
+{
+  IoWrite8(R_PCH_RTC_EXT_INDEX, Address);
+  IoWrite8(R_PCH_RTC_EXT_TARGET, Data);
+}
+
+/**
+  Turn off system if needed.
+
+  @param PeiServices Pointer to PEI Services
+  @param CpuIo       Pointer to CPU I/O Protocol
+
+  @retval None.
+
+**/
+VOID
+CheckPowerOffNow (
+  VOID
+  )
+{
+  UINT16  Pm1Sts;
+
+  //
+  // Read and check the ACPI registers
+  //
+  Pm1Sts = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS);
+  if ((Pm1Sts & B_PCH_ACPI_PM1_STS_PWRBTN) == B_PCH_ACPI_PM1_STS_PWRBTN) {
+    IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS, B_PCH_ACPI_PM1_STS_PWRBTN);
+    IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT, V_PCH_ACPI_PM1_CNT_S5);
+    IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT, V_PCH_ACPI_PM1_CNT_S5 + B_PCH_ACPI_PM1_CNT_SLP_EN);
+
+    //
+    // Should not return
+    //
+    CpuDeadLoop();
+  }
+}
+
+VOID
+ClearPowerState (
+  IN SYSTEM_CONFIGURATION        *SystemConfiguration
+  )
+{
+  UINT8   Data8;
+  UINT16  Data16;
+  UINT32  Data32;
+
+  //
+  // Check for PowerState option for AC power loss and program the chipset
+  //
+
+  //
+  // Clear PWROK (Set to Clear)
+  //
+  MmioOr32 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1, B_PCH_PMC_GEN_PMCON_PWROK_FLR);
+
+  //
+  // Clear Power Failure Bit (Set to Clear)
+  //
+  // TODO: Check if it is OK to clear here
+  //
+
+  MmioOr32 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1, B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR);
+
+  //
+  // Clear the GPE and PM enable
+  //
+  IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_EN, (UINT16) 0x00);
+  IoWrite32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_GPE0a_EN, (UINT32) 0x00);
+
+  //
+  // Halt the TCO timer
+  //
+  Data16 = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_TCO_CNT);
+  Data16 |= B_PCH_TCO_CNT_TMR_HLT;
+  IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_TCO_CNT, Data16);
+
+  //
+  // if NMI_NOW_STS is set
+  // NMI NOW bit is "Write '1' to clear"
+  //
+  Data8 = MmioRead8(ILB_BASE_ADDRESS + R_PCH_ILB_GNMI);
+  if ((Data8 & B_PCH_ILB_GNMI_NMINS) == B_PCH_ILB_GNMI_NMINS) {
+    MmioOr8 (ILB_BASE_ADDRESS + R_PCH_ILB_GNMI, B_PCH_ILB_GNMI_NMIN);
+  }
+
+  //
+  // Before we clear the TO status bit here we need to save the results in a CMOS bit for later use.
+  //
+  Data32 = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_TCO_STS);
+  if ((Data32 & B_PCH_TCO_STS_SECOND_TO) == B_PCH_TCO_STS_SECOND_TO)
+  {
+#if (defined(HW_WATCHDOG_TIMER_SUPPORT) && (HW_WATCHDOG_TIMER_SUPPORT != 0))
+    WriteCmosBank1Byte (
+      EFI_CMOS_PERFORMANCE_FLAGS,
+      ReadCmosBank1Byte (EFI_CMOS_PERFORMANCE_FLAGS) | B_CMOS_TCO_WDT_RESET
+      );
+#endif
+  }
+}
+
+/*++
+
+  Clear any SMI status or wake status left over from boot.
+
+**/
+VOID
+ClearSmiAndWake (
+  VOID
+  )
+{
+  UINT16  Pm1Sts;
+  UINT32  Gpe0Sts;
+  UINT32  SmiSts;
+
+  //
+  // Read the ACPI registers
+  //
+  Pm1Sts  = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS);
+  Gpe0Sts = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_GPE0a_STS);
+  SmiSts  = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_SMI_STS);
+
+  //
+  // Register Wake up reason for S4.  This information is used to notify
+  // WinXp of wake up reason because S4 wake up path doesn't keep SCI.
+  // This is important for Viiv(Quick resume) platform.
+  //
+
+  //
+  // First Clear CMOS S4 Wake up flag.
+  //
+  WriteCmosBank1Byte(CMOS_S4_WAKEUP_FLAG_ADDRESS, 0);
+
+  //
+  // Check wake up reason and set CMOS accordingly.  Currently checks
+  // Power button, USB, PS/2.
+  // Note : PS/2 wake up is using GPI13 (IO_PME).  This must be changed depending
+  // on board design.
+  //
+  if ((Pm1Sts & B_PCH_ACPI_PM1_STS_PWRBTN) || (Gpe0Sts & (B_PCH_ACPI_GPE0a_STS_CORE_GPIO | B_PCH_ACPI_GPE0a_STS_SUS_GPIO))) {
+    WriteCmosBank1Byte(CMOS_S4_WAKEUP_FLAG_ADDRESS, 1);
+  }
+
+  //
+  // Clear any SMI or wake state from the boot
+  //
+  Pm1Sts = (B_PCH_ACPI_PM1_STS_PRBTNOR | B_PCH_ACPI_PM1_STS_PWRBTN);
+
+  Gpe0Sts |=
+    (
+      B_PCH_ACPI_GPE0a_STS_CORE_GPIO |
+      B_PCH_ACPI_GPE0a_STS_SUS_GPIO |
+      B_PCH_ACPI_GPE0a_STS_PME_B0 |
+      B_PCH_ACPI_GPE0a_STS_BATLOW |
+      B_PCH_ACPI_GPE0a_STS_PCI_EXP |
+      B_PCH_ACPI_GPE0a_STS_GUNIT_SCI |
+      B_PCH_ACPI_GPE0a_STS_PUNIT_SCI |
+      B_PCH_ACPI_GPE0a_STS_SWGPE |
+      B_PCH_ACPI_GPE0a_STS_HOT_PLUG
+    );
+
+  SmiSts |=
+    (
+      B_PCH_SMI_STS_SMBUS |
+      B_PCH_SMI_STS_PERIODIC |
+      B_PCH_SMI_STS_TCO |
+      B_PCH_SMI_STS_SWSMI_TMR |
+      B_PCH_SMI_STS_APM |
+      B_PCH_SMI_STS_ON_SLP_EN |
+      B_PCH_SMI_STS_BIOS
+    );
+
+  //
+  // Write them back
+  //
+  IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS, Pm1Sts);
+  IoWrite32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_GPE0a_STS, Gpe0Sts);
+  IoWrite32 (ACPI_BASE_ADDRESS + R_PCH_SMI_STS, SmiSts);
+}
+
+/**
+  Issue PCI-E Secondary Bus Reset
+
+  @param Bus  Bus number of the bridge
+  @param Dev  Devices number of the bridge
+  @param Fun  Function number of the bridge
+
+  @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+PcieSecondaryBusReset (
+  IN CONST EFI_PEI_SERVICES  **PeiServices,
+  IN UINT8             Bus,
+  IN UINT8             Dev,
+  IN UINT8             Fun
+  )
+{
+  EFI_PEI_STALL_PPI   *PeiStall;
+  EFI_STATUS          Status;
+
+  Status = (**PeiServices).LocatePpi (
+                             PeiServices,
+                             &gEfiPeiStallPpiGuid,
+                             0,
+                             NULL,
+                    (void **)&PeiStall
+                             );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Issue secondary bus reset
+  //
+  MmPci16Or(0, Bus, Dev, Fun, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_PCI_BRIDGE_CONTROL_RESET_SECONDARY_BUS);
+
+  //
+  // Wait 1ms
+  //
+  PeiStall->Stall (PeiServices, PeiStall, 1000);
+
+
+  //
+  // Clear the reset bit
+  // Note: The PCIe spec suggests 100ms delay between clearing this bit and accessing
+  // the device's config space. Since we will not access the config space until we enter DXE
+  // we don't put delay expressly here.
+  //
+  MmPci16And(0, Bus, Dev, Fun, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, ~(EFI_PCI_BRIDGE_CONTROL_RESET_SECONDARY_BUS));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Provide hard reset PPI service.
+  To generate full hard reset, write 0x0E to ICH RESET_GENERATOR_PORT (0xCF9).
+
+  @param PeiServices        General purpose services available to every PEIM.
+
+  @retval Not return        System reset occured.
+  @retval EFI_DEVICE_ERROR  Device error, could not reset the system.
+
+**/
+EFI_STATUS
+EFIAPI
+IchReset (
+  IN CONST EFI_PEI_SERVICES          **PeiServices
+  )
+{
+  IoWrite8 (
+    R_PCH_RST_CNT,
+    V_PCH_RST_CNT_HARDSTARTSTATE
+    );
+
+  IoWrite8 (
+    R_PCH_RST_CNT,
+    V_PCH_RST_CNT_HARDRESET
+    );
+
+  //
+  // System reset occured, should never reach at this line.
+  //
+  ASSERT_EFI_ERROR (EFI_DEVICE_ERROR);
+  CpuDeadLoop();
+
+  return EFI_DEVICE_ERROR;
+}
+
+VOID
+PchPlatformLpcInit (
+  IN  CONST EFI_PEI_SERVICES          **PeiServices,
+  IN SYSTEM_CONFIGURATION       *SystemConfiguration
+  )
+{
+  EFI_BOOT_MODE BootMode;
+  UINT8         Data8;
+  UINT16                Data16;
+
+  (*PeiServices)->GetBootMode(PeiServices, &BootMode);
+
+  if ((BootMode != BOOT_ON_S3_RESUME)) {
+
+    //
+    // Clear all pending SMI. On S3 clear power button enable so it wll not generate an SMI
+    //
+    ClearSmiAndWake ();
+  }
+
+  ClearPowerState (SystemConfiguration);
+
+  //
+  // Need to set and clear SET bit (RTC_REGB Bit 7) as requested by the ICH EDS
+  // early in POST after each power up directly after coin-cell battery insertion.
+  // This is to avoid the UIP bit (RTC_REGA Bit 7) from stuck at "1".
+  // The UIP bit status may be polled by software (i.e ME FW) during POST.
+  //
+  if (MmioRead8 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1) & B_PCH_PMC_GEN_PMCON_RTC_PWR_STS) {
+  	//
+    // Set and clear SET bit in RTC_REGB
+    //
+    IoWrite8(R_PCH_RTC_INDEX, R_PCH_RTC_REGISTERB);
+    Data8 = IoRead8(R_PCH_RTC_TARGET);
+    Data8 |= B_PCH_RTC_REGISTERB_SET;
+    IoWrite8(R_PCH_RTC_TARGET, Data8);
+
+    IoWrite8(R_PCH_RTC_INDEX, R_PCH_RTC_REGISTERB);
+    Data8 &= (~B_PCH_RTC_REGISTERB_SET);
+    IoWrite8(R_PCH_RTC_TARGET, Data8);
+
+    //
+    // Clear the UIP bit in RTC_REGA
+    //
+    IoWrite8(R_PCH_RTC_INDEX, R_PCH_RTC_REGISTERA);
+    IoWrite8(R_PCH_RTC_TARGET, 0x00);
+  }
+
+  //
+  // Disable SERR NMI and IOCHK# NMI in port 61
+  //
+  Data8 = IoRead8 (R_PCH_NMI_SC);
+  IoWrite8(R_PCH_NMI_SC, (UINT8) (Data8 | B_PCH_NMI_SC_PCI_SERR_EN | B_PCH_NMI_SC_IOCHK_NMI_EN));
+
+  //
+  // Enable Bus Master, I/O, Mem, and SERR on LPC bridge
+  //
+  Data16 = PchLpcPciCfg16 (R_PCH_LPC_COMMAND);
+  MmioWrite16 (
+    MmPciAddress (0,
+      DEFAULT_PCI_BUS_NUMBER_PCH,
+      PCI_DEVICE_NUMBER_PCH_LPC,
+      PCI_FUNCTION_NUMBER_PCH_LPC,
+      R_PCH_LPC_COMMAND
+    ),
+    (Data16 |
+     B_PCH_LPC_COMMAND_IOSE |
+     B_PCH_LPC_COMMAND_MSE |
+     B_PCH_LPC_COMMAND_BME |
+     B_PCH_LPC_COMMAND_SERR_EN)
+  );
+
+  //
+  // Set Stretch S4 to 1-2s per marketing request.
+  // Note: This register is powered by RTC well.
+  //
+  MmioAndThenOr8 (
+    PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1 ,
+    (UINT8) (~B_PCH_PMC_GEN_PMCON_SLP_S4_MAW),
+    (UINT8) (B_PCH_PMC_GEN_PMCON_SLP_S4_ASE | V_PCH_PMC_GEN_PMCON_SLP_S4_MAW_4S)
+    );
+
+}
+
+#define V_PCH_ILB_IRQE_UARTIRQEN_IRQ3             BIT3 // UART IRQ3 Enable
+
+VOID
+UARTInit (
+  IN SYSTEM_CONFIGURATION        *SystemConfiguration
+  )
+{
+  if (0) { // for fix cr4 issue
+    //
+    // Program and enable PMC Base.
+    //
+    IoWrite32 (0xCF8,  PCI_LPC_REG(R_PCH_LPC_PMC_BASE));
+    IoWrite32 (0xCFC,  (PMC_BASE_ADDRESS | B_PCH_LPC_PMC_BASE_EN));
+
+    if( (SystemConfiguration->PcuUart1 == 1) &&
+        (SystemConfiguration->LpssHsuart0Enabled == 0)){
+      //
+      // Enable COM1 for debug message output.
+      //
+      MmioOr32 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1, BIT24);
+
+      //
+      //Enable internal UART3 port(COM1)
+      //
+      MmioOr8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) V_PCH_ILB_IRQE_UARTIRQEN_IRQ3);
+      MmioOr32 (IO_BASE_ADDRESS + 0x0520, 0x01); // UART3_RXD-L
+      MmioOr32 (IO_BASE_ADDRESS + 0x0530, 0x01); // UART3_TXD-0
+      MmioOr8 (PciD31F0RegBase + R_PCH_LPC_UART_CTRL, (UINT8) B_PCH_LPC_UART_CTRL_COM1_EN);
+    } else {
+    	//
+      //Disable UART3(COM1)
+      //
+      MmioAnd8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) ~V_PCH_ILB_IRQE_UARTIRQEN_IRQ3);
+      MmioAnd32 (IO_BASE_ADDRESS + 0x0520, ~(UINT32)0x07);
+      MmioAnd32 (IO_BASE_ADDRESS + 0x0530, ~(UINT32)0x07);
+      MmioAnd8 (PciD31F0RegBase + R_PCH_LPC_UART_CTRL, (UINT8) ~B_PCH_LPC_UART_CTRL_COM1_EN);
+
+
+      if (SystemConfiguration->LpssHsuart0Enabled == 1){
+        //
+        //Valleyview BIOS Specification Vol2,17.2
+        //LPSS_UART1 ¨C set each pad PAD_CONF0.Func_Pin_Mux to function 1:
+        //
+        MmioAnd8 (IO_BASE_ADDRESS + 0x0090, (UINT8)~0x07);
+        MmioOr8 (IO_BASE_ADDRESS + 0x0090, 0x01);
+        MmioAnd8 (IO_BASE_ADDRESS + 0x00D0, (UINT8)~0x07);
+        MmioOr8 (IO_BASE_ADDRESS + 0x00D0, 0x01);
+
+      }
+    }
+
+
+    DEBUG ((EFI_D_ERROR, "EnableInternalUart\n"));
+  } else {
+  	//
+    // If SIO UART interface selected
+    //Disable internal UART port(COM1)
+    //
+    if (0) {; // For fix CR4 issue
+      MmioAnd8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) ~V_PCH_ILB_IRQE_UARTIRQEN_IRQ3);
+      MmioAnd8 (IO_BASE_ADDRESS + 0x0090, (UINT8)~0x07);
+      MmioAnd8 (IO_BASE_ADDRESS + 0x00D0, (UINT8)~0x07);
+      MmioAnd8 (PciD31F0RegBase + R_PCH_LPC_UART_CTRL, (UINT8) ~B_PCH_LPC_UART_CTRL_COM1_EN);
+
+    }
+  }
+}
+
+VOID
+IchRcrbInit (
+  IN CONST EFI_PEI_SERVICES            **PeiServices,
+  IN SYSTEM_CONFIGURATION        *SystemConfiguration
+  )
+{
+  EFI_BOOT_MODE                   BootMode;
+
+  (*PeiServices)->GetBootMode(PeiServices, &BootMode);
+
+  //
+  // If not recovery or flash update boot path. set the BIOS interface lock down bit.
+  // It locks the top swap bit and BIOS boot strap bits from being changed.
+  //
+  if ((BootMode != BOOT_IN_RECOVERY_MODE) && (BootMode != BOOT_ON_FLASH_UPDATE)) {
+    MmioOr8 (RCBA_BASE_ADDRESS + R_PCH_RCRB_GCS, B_PCH_RCRB_GCS_BILD);
+  }
+
+  //
+  // Disable the Watchdog timer expiration from causing a system reset
+  //
+  MmioOr8 (PMC_BASE_ADDRESS + R_PCH_PMC_PM_CFG, B_PCH_PMC_PM_CFG_NO_REBOOT);
+
+  //
+  // Initial RCBA according to the PeiRCBA table
+  //
+  if ((BootMode == BOOT_ON_S3_RESUME)) {
+    //
+    // We are resuming from S3
+    // Enable HPET if enabled in Setup
+    // ICH Config register Offset 0x3404 bit 7 (Enable) = 1,
+    // Bit 1:0 (Mem I/O address) = 0 (0xFED00000)
+    //
+    MmioOr8 (R_PCH_PCH_HPET + R_PCH_PCH_HPET_GCFG, B_PCH_PCH_HPET_GCFG_EN);
+
+  }
+
+}
+
+
+EFI_STATUS
+PlatformPchInit (
+  IN SYSTEM_CONFIGURATION        *SystemConfiguration,
+  IN CONST EFI_PEI_SERVICES      **PeiServices,
+  IN UINT16                      PlatformType
+  )
+{
+  EFI_STATUS     Status;
+  EFI_BOOT_MODE  BootMode;
+
+  Status = PeiServicesGetBootMode (&BootMode);
+  ASSERT_EFI_ERROR (Status);
+
+  IchRcrbInit (PeiServices, SystemConfiguration);
+
+  if (BootMode == BOOT_IN_RECOVERY_MODE) {
+    InstallPeiPchUsbPolicy(PeiServices);
+  }
+
+  //
+  // PCH Policy Initialization based on Setup variable.
+  //
+  PchPolicySetupInit (PeiServices, SystemConfiguration);
+
+  UARTInit(SystemConfiguration);
+
+  PchPlatformLpcInit (PeiServices, SystemConfiguration);
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Returns the state of A16 inversion
+
+  @retval TRUE    A16 is inverted
+  @retval FALSE   A16 is not inverted
+
+**/
+BOOLEAN
+IsA16Inverted (
+  )
+{
+  UINT8  Data;
+  Data = MmioRead8 (RCBA_BASE_ADDRESS + R_PCH_RCRB_GCS);
+  return (Data & B_PCH_RCRB_GCS_TS) ? TRUE : FALSE;
+}
+
+VOID
+PchPolicySetupInit (
+  IN CONST EFI_PEI_SERVICES **PeiServices,
+  IN SYSTEM_CONFIGURATION   *SystemConfiguration
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_PEI_PPI_DESCRIPTOR      *PchPlatformPolicyPpiDesc;
+  PCH_PLATFORM_POLICY_PPI     *PchPlatformPolicyPpi;
+  PCH_HPET_CONFIG             *HpetConfig;
+  PCH_PCIE_CONFIG             *PcieConfig;
+  UINT8                       Index;
+  PCH_IOAPIC_CONFIG           *IoApicConfig;
+  PCH_LPSS_CONFIG             *LpssConfig;
+  UINT32                      SpiHsfsReg;
+  UINT32                      SpiFdodReg;
+
+//
+// Disable codec ALC-262
+//
+  UINT32                      IoBase;
+
+  //
+  // Install Pch Platform Policy PPI. As we depend on Pch Init PPI so we are executed after
+  // PchInit PEIM. Thus we can insure PCH Initialization is performed when we install the Pch Platform Policy PPI,
+  // as PchInit PEIM registered a notification function on our policy PPI.
+  //
+  // --cr-- For better code structure / modularity, we should use a notification function on Pch Init PPI to perform
+  // actions that depend on PchInit PEIM's initialization.
+  //
+  //Todo: confirm if we need update to PCH_PLATFORM_POLICY_PPI_REVISION_5
+  //
+  DEBUG ((EFI_D_ERROR, "PchPolicySetupInit() - Start\n"));
+
+  Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (EFI_PEI_PPI_DESCRIPTOR), (void **)&PchPlatformPolicyPpiDesc);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_PLATFORM_POLICY_PPI), (void **)&PchPlatformPolicyPpi);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_HPET_CONFIG), (void **)&HpetConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_PCIE_CONFIG), (void **)&PcieConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_IOAPIC_CONFIG), (void **)&IoApicConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_LPSS_CONFIG), (void **)&LpssConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  PchPlatformPolicyPpi->Revision                = PCH_PLATFORM_POLICY_PPI_REVISION_1;
+  PchPlatformPolicyPpi->BusNumber               = DEFAULT_PCI_BUS_NUMBER_PCH;
+  PchPlatformPolicyPpi->SpiBase                 = SPI_BASE_ADDRESS;
+  PchPlatformPolicyPpi->PmcBase                 = PMC_BASE_ADDRESS;
+  PchPlatformPolicyPpi->IoBase                  = IO_BASE_ADDRESS;
+  PchPlatformPolicyPpi->IlbBase                 = ILB_BASE_ADDRESS;
+  PchPlatformPolicyPpi->PUnitBase               = PUNIT_BASE_ADDRESS;
+  PchPlatformPolicyPpi->MphyBase                = MPHY_BASE_ADDRESS;
+  PchPlatformPolicyPpi->Rcba                    = RCBA_BASE_ADDRESS;
+  PchPlatformPolicyPpi->AcpiBase                = ACPI_BASE_ADDRESS;
+  PchPlatformPolicyPpi->GpioBase                = GPIO_BASE_ADDRESS;
+  PchPlatformPolicyPpi->SataMode                = SystemConfiguration->SataType;
+  PchPlatformPolicyPpi->EnableRmh               = SystemConfiguration->PchUsbRmh;
+
+  PchPlatformPolicyPpi->EhciPllCfgEnable        = SystemConfiguration->EhciPllCfgEnable;
+
+
+  PchPlatformPolicyPpi->HpetConfig              = HpetConfig;
+  PchPlatformPolicyPpi->PcieConfig              = PcieConfig;
+  PchPlatformPolicyPpi->IoApicConfig            = IoApicConfig;
+
+  PchPlatformPolicyPpi->HpetConfig->Enable      = SystemConfiguration->Hpet;
+  PchPlatformPolicyPpi->HpetConfig->Base        = HPET_BASE_ADDRESS;
+  PchPlatformPolicyPpi->IoApicConfig->IoApicId  = 0x01;
+
+  //
+  // Set LPSS configuration according to setup value.
+  //
+  PchPlatformPolicyPpi->LpssConfig->LpssPciModeEnabled   = SystemConfiguration->LpssPciModeEnabled;
+
+  PchPlatformPolicyPpi->LpssConfig->Dma1Enabled    = SystemConfiguration->LpssDma1Enabled;
+  PchPlatformPolicyPpi->LpssConfig->I2C0Enabled    = SystemConfiguration->LpssI2C0Enabled;
+  PchPlatformPolicyPpi->LpssConfig->I2C1Enabled    = SystemConfiguration->LpssI2C1Enabled;
+  PchPlatformPolicyPpi->LpssConfig->I2C2Enabled    = SystemConfiguration->LpssI2C2Enabled;
+  PchPlatformPolicyPpi->LpssConfig->I2C3Enabled    = SystemConfiguration->LpssI2C3Enabled;
+  PchPlatformPolicyPpi->LpssConfig->I2C4Enabled    = SystemConfiguration->LpssI2C4Enabled;
+  PchPlatformPolicyPpi->LpssConfig->I2C5Enabled    = SystemConfiguration->LpssI2C5Enabled;
+  PchPlatformPolicyPpi->LpssConfig->I2C6Enabled    = SystemConfiguration->LpssI2C6Enabled;
+
+  PchPlatformPolicyPpi->LpssConfig->Dma0Enabled    = SystemConfiguration->LpssDma0Enabled;;
+  PchPlatformPolicyPpi->LpssConfig->Pwm0Enabled    = SystemConfiguration->LpssPwm0Enabled;
+  PchPlatformPolicyPpi->LpssConfig->Pwm1Enabled    = SystemConfiguration->LpssPwm1Enabled;
+  PchPlatformPolicyPpi->LpssConfig->Hsuart0Enabled = SystemConfiguration->LpssHsuart0Enabled;
+  PchPlatformPolicyPpi->LpssConfig->Hsuart1Enabled = SystemConfiguration->LpssHsuart1Enabled;
+  PchPlatformPolicyPpi->LpssConfig->SpiEnabled     = SystemConfiguration->LpssSpiEnabled;
+
+
+  for (Index = 0; Index < PCH_PCIE_MAX_ROOT_PORTS; Index++) {
+    PchPlatformPolicyPpi->PcieConfig->PcieSpeed[Index] = SystemConfiguration->PcieRootPortSpeed[Index];
+  }
+
+  SpiHsfsReg = MmioRead32 (SPI_BASE_ADDRESS + R_PCH_SPI_HSFS);
+  if ((SpiHsfsReg & B_PCH_SPI_HSFS_FDV) == B_PCH_SPI_HSFS_FDV) {
+    MmioWrite32 (SPI_BASE_ADDRESS + R_PCH_SPI_FDOC, V_PCH_SPI_FDOC_FDSS_FSDM);
+    SpiFdodReg = MmioRead32 (SPI_BASE_ADDRESS + R_PCH_SPI_FDOD);
+    if (SpiFdodReg == V_PCH_SPI_FDBAR_FLVALSIG) {
+    }
+  //
+  // Disable codec ALC-262
+  //
+  if (SystemConfiguration->DisableCodec262 == 1) {
+      IoBase = MmioRead32 (MmPciAddress (0,
+                        PchPlatformPolicyPpi->BusNumber,
+                        PCI_DEVICE_NUMBER_PCH_LPC,
+                        PCI_FUNCTION_NUMBER_PCH_LPC,
+                        0
+                      ) + R_PCH_LPC_IO_BASE) & B_PCH_LPC_IO_BASE_BAR;
+      MmioAnd32 ((UINTN) (IoBase + 0x270), (UINT32) (~0x07));
+  }
+  }
+
+  PchPlatformPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+  PchPlatformPolicyPpiDesc->Guid = &gPchPlatformPolicyPpiGuid;
+  PchPlatformPolicyPpiDesc->Ppi = PchPlatformPolicyPpi;
+
+  //
+  // Install PCH Platform Policy PPI
+  //
+  Status = (**PeiServices).InstallPpi (
+              PeiServices,
+              PchPlatformPolicyPpiDesc
+              );
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((EFI_D_ERROR, "PchPolicySetupInit() - End\n"));
+}
+
+EFI_STATUS
+InstallPeiPchUsbPolicy (
+  IN CONST  EFI_PEI_SERVICES  **PeiServices
+  )
+{
+  EFI_STATUS              Status = EFI_SUCCESS;
+
+  EFI_PEI_PPI_DESCRIPTOR  *PeiPchUsbPolicyPpiDesc;
+  PCH_USB_POLICY_PPI      *PeiPchUsbPolicyPpi;
+  PCH_USB_CONFIG          *UsbConfig;
+
+  DEBUG ((EFI_D_INFO, "InstallPeiPchUsbPolicy...\n"));
+
+  //
+  // Allocate descriptor and PPI structures.  Since these are dynamically updated
+  // we cannot do a global variable PPI.
+  //
+  Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (EFI_PEI_PPI_DESCRIPTOR), (void **)&PeiPchUsbPolicyPpiDesc);
+
+
+  Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_USB_POLICY_PPI), (void **)&PeiPchUsbPolicyPpi);
+
+
+
+  Status = (*PeiServices)->AllocatePool (PeiServices, sizeof (PCH_USB_CONFIG), (void **)&UsbConfig);
+
+
+  //
+  // Initiate PCH USB policy.
+  //
+  PeiPchUsbPolicyPpi->Revision = PCH_USB_POLICY_PPI_REVISION_1;
+  UsbConfig->Usb20Settings[0].Enable  = PCH_DEVICE_ENABLE;
+  UsbConfig->UsbPerPortCtl            = PCH_DEVICE_DISABLE;
+  UsbConfig->Ehci1Usbr                = PCH_DEVICE_DISABLE;
+
+  UsbConfig->Usb20OverCurrentPins[0] = PchUsbOverCurrentPin0;
+
+  UsbConfig->Usb20OverCurrentPins[1] = PchUsbOverCurrentPin0;
+
+  UsbConfig->Usb20OverCurrentPins[2] = PchUsbOverCurrentPin1;
+
+  UsbConfig->Usb20OverCurrentPins[3] = PchUsbOverCurrentPin1;
+
+
+  //
+  // Enable USB Topology control and program the topology setting for every USB port
+  // See Platform Design Guide for description of topologies
+  //
+    //
+    // Port 0: ~10.9", Port 1: ~10.1", Port 2: ~11.2", Port 3: ~11.5", Port 4: ~3.7", Port 5: ~2.7", Port 6: ~4.1"
+    // Port 7: ~4.5", Port 8: ~10.7", Port 9: ~10.5", Port 10: ~4.2", Port 11: ~4.3", Port 12: ~3.1", Port 13: ~2.9"
+    //
+
+    //
+    // Port 0: ~3.5", Port 1: ~4.1", Port 2: ~4.6", Port 3: ~4.6", Port 4: ~12.5", Port 5: ~12", Port 6: ~5.1"
+    // Port 7: ~5.1", Port 8: ~4.1", Port 9: ~4.1", Port 10: ~14.5", Port 11: ~12.8", Port 12: ~12.9", Port 13: ~14.6"
+    //
+  UsbConfig->Usb20PortLength[0]  = 0x53;
+  UsbConfig->Usb20PortLength[1]  = 0x49;
+  UsbConfig->Usb20PortLength[2]  = 0x47;
+  UsbConfig->Usb20PortLength[3]  = 0x80;
+
+  PeiPchUsbPolicyPpi->Mode = EHCI_MODE;
+
+  PeiPchUsbPolicyPpi->EhciMemBaseAddr = PcdGet32(PcdPeiIchEhciControllerMemoryBaseAddress);
+
+  PeiPchUsbPolicyPpi->EhciMemLength   = (UINT32) 0x400 * PchEhciControllerMax;
+
+  PeiPchUsbPolicyPpi->XhciMemBaseAddr = 0;
+
+  PeiPchUsbPolicyPpi->UsbConfig       = UsbConfig;
+
+  PeiPchUsbPolicyPpiDesc->Flags       = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+
+  PeiPchUsbPolicyPpiDesc->Guid        = &gPchUsbPolicyPpiGuid;
+
+  PeiPchUsbPolicyPpiDesc->Ppi         = PeiPchUsbPolicyPpi;
+
+  //
+  // Install PCH USB Policy PPI
+  //
+  Status = (**PeiServices).InstallPpi (PeiServices, PeiPchUsbPolicyPpiDesc);
+
+  return Status;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.c
new file mode 100644
index 0000000000..a359c95920
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.c
@@ -0,0 +1,1195 @@
+/** @file
+
+  Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  PlatformEarlyInit.c
+
+Abstract:
+
+  Do platform specific PEI stage initializations.
+
+--*/
+
+
+#include "PlatformEarlyInit.h"
+
+#ifdef __GNUC__
+#pragma GCC push_options
+#pragma GCC optimize ("O0")
+#else
+#pragma optimize ("", off)
+#endif
+
+
+
+static EFI_PEI_STALL_PPI  mStallPpi = {
+  PEI_STALL_RESOLUTION,
+  Stall
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mInstallStallPpi = {
+  EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+  &gEfiPeiStallPpiGuid,
+  &mStallPpi
+};
+
+//
+// The reserved SMBus addresses are defined in PlatformDxe.h file.
+//
+static UINT8 mSmbusRsvdAddresses[] = PLATFORM_SMBUS_RSVD_ADDRESSES;
+static PEI_SMBUS_POLICY_PPI         mSmbusPolicyPpi = {
+  SMBUS_BASE_ADDRESS,
+  SMBUS_BUS_DEV_FUNC,
+  PLATFORM_NUM_SMBUS_RSVD_ADDRESSES,
+  mSmbusRsvdAddresses
+};
+
+static EFI_PEI_PPI_DESCRIPTOR       mInstallSmbusPolicyPpi = {
+  EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+  &gPeiSmbusPolicyPpiGuid,
+  &mSmbusPolicyPpi
+};
+static PEI_SPEAKER_IF_PPI    mSpeakerInterfacePpi = {
+  ProgramToneFrequency,
+  GenerateBeepTone
+};
+
+static EFI_PEI_PPI_DESCRIPTOR       mInstallSpeakerInterfacePpi = {
+  EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+  &gPeiSpeakerInterfacePpiGuid,
+  &mSpeakerInterfacePpi
+};
+
+static EFI_PEI_RESET_PPI            mResetPpi = { IchReset };
+
+
+static EFI_PEI_FIND_FV_PPI mEfiFindFvPpi = {
+  (EFI_PEI_FIND_FV_FINDFV)FindFv
+};
+
+static EFI_PEI_PPI_DESCRIPTOR       mPpiList[] = {
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI,
+    &gEfiPeiMasterBootModePpiGuid,
+    NULL
+  },
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI,
+    &gEfiPeiResetPpiGuid,
+    &mResetPpi
+  },
+  {
+    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+    &gEfiFindFvPpiGuid,
+    &mEfiFindFvPpi
+  }
+};
+
+static EFI_PEI_NOTIFY_DESCRIPTOR    mNotifyList[] = {
+  {
+    EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
+    &gEfiEndOfPeiSignalPpiGuid,
+    (EFI_PEIM_NOTIFY_ENTRY_POINT)EndOfPeiPpiNotifyCallback
+  },
+  {
+    (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+    &gEfiPeiMemoryDiscoveredPpiGuid,
+    (EFI_PEIM_NOTIFY_ENTRY_POINT)MemoryDiscoveredPpiNotifyCallback
+  }
+
+};
+
+
+/**
+
+  Parse the status registers for figuring out the wake-up event and save it into
+  an GUID HOB which will be referenced later. However, modification is required
+  to meet the chipset register definition and the practical hardware design. Thus,
+  this is just an example.
+
+
+  @param PeiServices    pointer to the PEI Service Table
+  @param EFI_SUCCESS    Always return Success
+
+  @retval None
+
+
+**/
+EFI_STATUS
+EFIAPI
+GetWakeupEventAndSaveToHob (
+  IN CONST EFI_PEI_SERVICES   **PeiServices
+  )
+{
+  UINT16  Pm1Sts;
+  UINTN   Gpe0Sts;
+  UINTN   WakeEventData;
+
+  //
+  // Read the ACPI registers
+  //
+  Pm1Sts  = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS);
+  Gpe0Sts = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_GPE0a_STS);
+
+  //
+  // Figure out the wake-up event
+  //
+  if ((Pm1Sts & B_PCH_ACPI_PM1_STS_PWRBTN) != 0) {
+    WakeEventData = SMBIOS_WAKEUP_TYPE_POWER_SWITCH;
+  } else if (((Pm1Sts & B_PCH_ACPI_PM1_STS_WAK) != 0)) {
+    WakeEventData = SMBIOS_WAKEUP_TYPE_PCI_PME;
+  } else if (Gpe0Sts != 0) {
+    WakeEventData = SMBIOS_WAKEUP_TYPE_OTHERS;
+  } else {
+    WakeEventData = SMBIOS_WAKEUP_TYPE_UNKNOWN;
+  }
+
+  DEBUG ((EFI_D_ERROR, "ACPI Wake Status Register: %04x\n", Pm1Sts));
+  DEBUG ((EFI_D_ERROR, "ACPI Wake Event Data: %02x\n", WakeEventData));
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetSetupVariable (
+  IN CONST EFI_PEI_SERVICES                **PeiServices,
+  IN   SYSTEM_CONFIGURATION          *SystemConfiguration
+  )
+{
+  UINTN                        VariableSize;
+  EFI_STATUS                   Status;
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI   *Variable;
+
+  VariableSize = sizeof (SYSTEM_CONFIGURATION);
+  ZeroMem (SystemConfiguration, sizeof (SYSTEM_CONFIGURATION));
+
+  Status = (*PeiServices)->LocatePpi (
+                             PeiServices,
+                             &gEfiPeiReadOnlyVariable2PpiGuid,
+                             0,
+                             NULL,
+                                      (void **)&Variable
+                             );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Use normal setup default from NVRAM variable,
+  // the Platform Mode (manufacturing/safe/normal) is handle in PeiGetVariable.
+  //
+  VariableSize = sizeof(SYSTEM_CONFIGURATION);
+  Status = Variable->GetVariable (
+                       Variable,
+                       L"Setup",
+                       &gEfiSetupVariableGuid,
+                       NULL,
+                       &VariableSize,
+                       SystemConfiguration
+                       );
+  if (EFI_ERROR (Status) || VariableSize != sizeof(SYSTEM_CONFIGURATION)) {
+    //The setup variable is corrupted
+    VariableSize = sizeof(SYSTEM_CONFIGURATION);
+    Status = Variable->GetVariable(
+              Variable,
+              L"SetupRecovery",
+              &gEfiSetupVariableGuid,
+              NULL,
+              &VariableSize,
+              SystemConfiguration
+              );
+    ASSERT_EFI_ERROR (Status);
+  }  
+  return Status;
+}
+
+EFI_STATUS
+VlvPolicyInit (
+  IN CONST EFI_PEI_SERVICES             **PeiServices,
+  IN SYSTEM_CONFIGURATION         *SystemConfiguration
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_PEI_PPI_DESCRIPTOR          *mVlvPolicyPpiDesc;
+  VLV_POLICY_PPI                   *mVlvPolicyPpi;
+
+  Status = (*PeiServices)->AllocatePool(
+                             PeiServices,
+                             sizeof (EFI_PEI_PPI_DESCRIPTOR),
+                             (void **)&mVlvPolicyPpiDesc
+                             );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = (*PeiServices)->AllocatePool(
+                             PeiServices,
+                             sizeof (VLV_POLICY_PPI),
+                             (void **)&mVlvPolicyPpi
+                             );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Initialize PPI
+  //
+  (*PeiServices)->SetMem ((VOID *)mVlvPolicyPpi, sizeof (VLV_POLICY_PPI), 0);
+  mVlvPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+  mVlvPolicyPpiDesc->Guid = &gVlvPolicyPpiGuid;
+  mVlvPolicyPpiDesc->Ppi = mVlvPolicyPpi;
+  mVlvPolicyPpi->GtConfig.PrimaryDisplay = SystemConfiguration->PrimaryVideoAdaptor;
+  mVlvPolicyPpi->GtConfig.IgdDvmt50PreAlloc = SystemConfiguration->IgdDvmt50PreAlloc;
+  mVlvPolicyPpi->GtConfig.ApertureSize = SystemConfiguration->IgdApertureSize;
+  mVlvPolicyPpi->GtConfig.GttSize = SystemConfiguration->GTTSize;
+  if (SystemConfiguration->PrimaryVideoAdaptor != 2) {
+    mVlvPolicyPpi->GtConfig.InternalGraphics = SystemConfiguration->Igd;
+  } else {
+    mVlvPolicyPpi->GtConfig.InternalGraphics = 0;
+  }
+
+
+  mVlvPolicyPpi->GtConfig.IgdTurboEn = 1;
+
+
+  mVlvPolicyPpi->PlatformData.FastBoot = SystemConfiguration->FastBoot;
+  mVlvPolicyPpi->PlatformData.DynSR = 1;
+  DEBUG ((EFI_D_ERROR, "Setup Option ISPEn: 0x%x\n", SystemConfiguration->ISPEn));
+  mVlvPolicyPpi->ISPEn                      = SystemConfiguration->ISPEn;
+  DEBUG ((EFI_D_ERROR, "Setup Option ISPDevSel: 0x%x\n", SystemConfiguration->ISPDevSel));
+  mVlvPolicyPpi->ISPPciDevConfig            = SystemConfiguration->ISPDevSel;
+  if (SystemConfiguration->ISPEn == 0) {
+    mVlvPolicyPpi->ISPPciDevConfig          = 0;
+    DEBUG ((EFI_D_ERROR, "Update Setup Option ISPDevSel: 0x%x\n", mVlvPolicyPpi->ISPPciDevConfig));
+  }
+  Status = (*PeiServices)->InstallPpi(
+                             PeiServices,
+                             mVlvPolicyPpiDesc
+                             );
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+ConfigureSoCGpio (
+  IN SYSTEM_CONFIGURATION  *SystemConfiguration
+  )
+{
+
+    DEBUG ((EFI_D_ERROR, "ConfigureSoCGpio------------start\n"));
+    if (SystemConfiguration->eMMCBootMode== 1) {// Auto detection mode
+     DEBUG ((EFI_D_ERROR, "Auto detection mode------------start\n"));
+
+     //
+     //Silicon Steppings
+     //
+     switch (PchStepping()) {
+       case PchA0:  // SOC A0 and A1
+       case PchA1:
+         DEBUG ((EFI_D_ERROR, "SOC A0/A1: eMMC 4.41 GPIO Configuration\n"));
+         SystemConfiguration->LpsseMMCEnabled            = 1;
+         SystemConfiguration->LpsseMMC45Enabled          = 0;
+         break;
+       case PchB0:  // SOC B0 and later
+       default:
+         DEBUG ((EFI_D_ERROR, "SOC B0 and later: eMMC 4.5 GPIO Configuration\n"));
+         SystemConfiguration->LpsseMMCEnabled            = 0;
+         SystemConfiguration->LpsseMMC45Enabled          = 1;
+         break;
+     }
+    } else if (SystemConfiguration->eMMCBootMode == 2) { // eMMC 4.41
+        DEBUG ((EFI_D_ERROR, "Force to eMMC 4.41 GPIO Configuration\n"));
+        SystemConfiguration->LpsseMMCEnabled            = 1;
+        SystemConfiguration->LpsseMMC45Enabled          = 0;
+    } else if (SystemConfiguration->eMMCBootMode == 3) { // eMMC 4.5
+         DEBUG ((EFI_D_ERROR, "Force to eMMC 4.5 GPIO Configuration\n"));
+         SystemConfiguration->LpsseMMCEnabled            = 0;
+         SystemConfiguration->LpsseMMC45Enabled          = 1;
+
+    } else { // Disable eMMC controllers
+         DEBUG ((EFI_D_ERROR, "Disable eMMC GPIO controllers\n"));
+         SystemConfiguration->LpsseMMCEnabled            = 0;
+         SystemConfiguration->LpsseMMC45Enabled          = 0;
+    }
+
+  /*
+  20.1.1  EMMC
+  SDMMC1_CLK -         write 0x2003ED01 to IOBASE + 0x03E0
+  SDMMC1_CMD -        write 0x2003EC81 to IOBASE + 0x0390
+  SDMMC1_D0 -           write 0x2003EC81 to IOBASE + 0x03D0
+  SDMMC1_D1 -           write 0x2003EC81 to IOBASE + 0x0400
+  SDMMC1_D2 -           write 0x2003EC81 to IOBASE + 0x03B0
+  SDMMC1_D3_CD_B - write 0x2003EC81 to IOBASE + 0x0360
+  MMC1_D4_SD_WE -   write 0x2003EC81 to IOBASE + 0x0380
+  MMC1_D5 -                write 0x2003EC81 to IOBASE + 0x03C0
+  MMC1_D6 -                write 0x2003EC81 to IOBASE + 0x0370
+  MMC1_D7 -                write 0x2003EC81 to IOBASE + 0x03F0
+  MMC1_RESET_B -       write 0x2003ED01 to IOBASE + 0x0330
+  */
+  if (SystemConfiguration->LpsseMMCEnabled== 1) {
+    MmioWrite32 (IO_BASE_ADDRESS + 0x03E0, 0x2003ED01); //EMMC 4.41
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0390, 0x2003EC81);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x03D0, 0x2003EC81);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0400, 0x2003EC81);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x03B0, 0x2003EC81);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0360, 0x2003EC81);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0380, 0x2003EC81);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x03C0, 0x2003EC81);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0370, 0x2003EC81);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x03F0, 0x2003EC81);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0330, 0x2003ED01);
+  }
+
+  /*
+  eMMC 4.5 controller
+  SDMMC1_CLK -         write 0x2003ED03 to IOBASE + 0x03E0
+  SDMMC1_CMD -        write 0x2003EC83 to IOBASE + 0x0390
+  SDMMC1_D0 -           write 0x2003EC83 to IOBASE + 0x03D0
+  SDMMC1_D1 -           write 0x2003EC83 to IOBASE + 0x0400
+  SDMMC1_D2 -           write 0x2003EC83 to IOBASE + 0x03B0
+  SDMMC1_D3_CD_B -  write 0x2003EC83 to IOBASE + 0x0360
+  MMC1_D4_SD_WE -   write 0x2003EC83 to IOBASE + 0x0380
+  MMC1_D5 -                write 0x2003EC83 to IOBASE + 0x03C0
+  MMC1_D6 -                write 0x2003EC83 to IOBASE + 0x0370
+  MMC1_D7 -                write 0x2003EC83 to IOBASE + 0x03F0
+  MMC1_RESET_B -       write 0x2003ED03 to IOBASE + 0x0330
+  */
+  if (SystemConfiguration->LpsseMMC45Enabled== 1) {
+    MmioWrite32 (IO_BASE_ADDRESS + 0x03E0, 0x2003ED03); // EMMC 4.5
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0390, 0x2003EC83);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x03D0, 0x2003EC83);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0400, 0x2003EC83);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x03B0, 0x2003EC83);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0360, 0x2003EC83);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0380, 0x2003EC83);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x03C0, 0x2003EC83);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0370, 0x2003EC83);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x03F0, 0x2003EC83);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0330, 0x2003ED03);
+
+  }
+
+//
+// Change GPIOC_0 setting to allow MMIO access under Android.
+//
+  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_USE_SEL,
+           (IoRead32(GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_USE_SEL) & (UINT32)~BIT0));
+  DEBUG ((EFI_D_ERROR, "ConfigureSoCGpio------------end\n"));
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+MeasuredBootInit (
+  IN CONST EFI_PEI_SERVICES        **PeiServices,
+  IN SYSTEM_CONFIGURATION           *SystemConfiguration
+  )
+{
+  if (SystemConfiguration->MeasuredBootEnable) {
+    PcdSetBool (PcdMeasuredBootEnable, TRUE);
+  } else {
+    PcdSetBool (PcdMeasuredBootEnable, FALSE);
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+ConfigureLpssAndSccGpio (
+  IN SYSTEM_CONFIGURATION        *SystemConfiguration,
+  IN EFI_PLATFORM_INFO_HOB       *PlatformInfo
+  )
+{
+  /*One time configuration to each GPIO controller PSB_CONF register should be done before starting pad configuration:
+  GPIO SCORE -  write 0x01001002 to IOBASE + 0x0700
+  GPIO NCORE -  write 0x01001002 to IOBASE + 0x0F00
+  GPIO SSUS -    write 0x01001002 to IOBASE + 0x1700
+  */
+    DEBUG ((EFI_D_ERROR, "ConfigureLpssAndSccGpio------------start\n"));
+
+  /*
+  19.1.1  PWM0
+  PWM0 - write 0x2003CD01 to IOBASE + 0x00A0
+  19.1.2  PWM1
+  PWM0 - write 0x2003CD01 to IOBASE + 0x00B0
+  */
+  if (SystemConfiguration->LpssPwm0Enabled== 1) {
+    MmioWrite32 (IO_BASE_ADDRESS + 0x00A0, 0x2003CD01);
+  } else if (SystemConfiguration->LpssPwm0Enabled== 0) {
+    MmioWrite32 (IO_BASE_ADDRESS + 0x00A0, 0x2003CD00);
+  }
+
+  if (SystemConfiguration->LpssPwm1Enabled== 1) {
+    MmioWrite32 (IO_BASE_ADDRESS + 0x00B0, 0x2003CC01);
+  } else if (SystemConfiguration->LpssPwm1Enabled== 0) {
+    MmioWrite32 (IO_BASE_ADDRESS + 0x00B0, 0x2003CD00);
+  }
+
+  /*
+  19.1.3  UART1
+  UART1_RXD-L -     write 0x2003CC81 to IOBASE + 0x0020
+  UART1_TXD-0 -     write 0x2003CC81 to IOBASE + 0x0010
+  UART1_RTS_B-1 - write 0x2003CC81 to IOBASE + 0x0000
+  UART1_CTS_B-H - write 0x2003CC81 to IOBASE + 0x0040
+  */
+  if (SystemConfiguration->LpssHsuart0Enabled== 1) {
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0020, 0x2003CC81); // uart1
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0010, 0x2003CC81);
+  if (SystemConfiguration->LpssHsuart0FlowControlEnabled== 0) {
+    DEBUG ((EFI_D_ERROR, "LpssHsuart0FlowControlEnabled[0]\n"));
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0000, 0x2003CC80);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0040, 0x2003CC80);
+  } else {
+    DEBUG ((EFI_D_ERROR, "LpssHsuart0FlowControlEnabled[1]\n"));
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0000, 0x2003CC81);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0040, 0x2003CC01);//W/A HSD 4752617 0x2003CC81
+    }
+  } else if (SystemConfiguration->LpssHsuart0Enabled== 0) {
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0020, 0x2003CC80); // uart1
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0010, 0x2003CC80);
+  }
+
+
+  /*
+  19.1.4  UART2
+  UART2_RTS_B-1 -  write 0x2003CC81 to IOBASE + 0x0090
+  UART2_CTS_B-H - write 0x2003CC81 to IOBASE + 0x0080
+  UART2_RXD-H -    write 0x2003CC81 to IOBASE + 0x0060
+  UART2_TXD-0 -     write 0x2003CC81 to IOBASE + 0x0070
+  */
+  if (SystemConfiguration->LpssHsuart1Enabled== 1) {
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0060, 0x2003CC81);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0070, 0x2003CC81);
+
+  if (SystemConfiguration->LpssHsuart1FlowControlEnabled== 0) {
+    DEBUG ((EFI_D_ERROR, "LpssHsuart1FlowControlEnabled[0]\n"));
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0090, 0x2003CC80); // UART2_RTS_B
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0080, 0x2003CC80); // UART2_CTS_B
+  } else {
+    DEBUG ((EFI_D_ERROR, "LpssHsuart1FlowControlEnabled[1]\n"));
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0090, 0x2003CC81); // uart2
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0080, 0x2003CC01); //W/A HSD 4752617 0x2003CC81
+  }
+  } else if (SystemConfiguration->LpssHsuart1Enabled== 0) {
+  MmioWrite32 (IO_BASE_ADDRESS + 0x0060, 0x2003CC80);
+  MmioWrite32 (IO_BASE_ADDRESS + 0x0070, 0x2003CC80);
+  }
+
+  /*
+  19.1.5  SPI
+  SPI1_CS0_B - write 0x2003CC81 to IOBASE + 0x0110
+  SPI1_CLK -     write 0x2003CD01 to IOBASE + 0x0100
+  SPI1_MOSI -   write 0x2003CC81 to IOBASE + 0x0130
+  SPI1_MISO -   write 0x2003CC81 to IOBASE + 0x0120
+  */
+  if (SystemConfiguration->LpssSpiEnabled== 1) {
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0110, 0x2003CC81); // SPI
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0100, 0x2003CD01);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0130, 0x2003CC81);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0120, 0x2003CC81);
+  } else if (SystemConfiguration->LpssSpiEnabled== 0) {
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0110, 0x2003cc80);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0100, 0x2003cc80);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0130, 0x2003cc80);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0120, 0x2003cc80);
+  }
+
+  /*
+  19.1.6  I2C0
+  I2C0_SDA-OD-O -    write 0x2003CC81 to IOBASE + 0x0210
+  I2C0_SCL-OD-O -    write 0x2003CC81 to IOBASE + 0x0200
+  */
+  if (SystemConfiguration->LpssI2C0Enabled== 1) {
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0210, 0x2003C881);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0200, 0x2003C881);
+  }
+  /*
+  19.1.7  I2C1
+  I2C1_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x01F0
+  I2C1_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x01E0
+  */
+
+  if (SystemConfiguration->LpssI2C1Enabled== 1) {
+    MmioWrite32 (IO_BASE_ADDRESS + 0x01F0, 0x2003C881);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x01E0, 0x2003C881);
+  }
+  /*
+  19.1.8  I2C2
+  I2C2_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x01D0
+  I2C2_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x01B0
+  */
+  if (SystemConfiguration->LpssI2C2Enabled== 1) {
+    MmioWrite32 (IO_BASE_ADDRESS + 0x01D0, 0x2003C881);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x01B0, 0x2003C881);
+  }
+  /*
+  19.1.9  I2C3
+  I2C3_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x0190
+  I2C3_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x01C0
+  */
+  if (SystemConfiguration->LpssI2C3Enabled== 1) {
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0190, 0x2003C881);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x01C0, 0x2003C881);
+  }
+  /*
+  19.1.10 I2C4
+  I2C4_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x01A0
+  I2C4_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x0170
+  */
+  if (SystemConfiguration->LpssI2C4Enabled== 1) {
+    MmioWrite32 (IO_BASE_ADDRESS + 0x01A0, 0x2003C881);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0170, 0x2003C881);
+  }
+  /*
+  19.1.11 I2C5
+  I2C5_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x0150
+  I2C5_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x0140
+  */
+  //touch 1.7M support on i2c5(from 0) need 2k PULL-UP.
+  if (SystemConfiguration->LpssI2C5Enabled== 1) {
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0150, 0x2003C881);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0140, 0x2003C881);
+  } else if(SystemConfiguration->LpssI2C5Enabled== 0) {
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0150, 0x2003C880);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0140, 0x2003C880);
+  }
+  /*
+  19.1.12 I2C6
+  I2C6_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x0180
+  I2C6_SCL-OD-O/I -  write 0x2003CC81 to IOBASE + 0x0160
+  */
+  if (SystemConfiguration->LpssI2C6Enabled== 1) {
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0180, 0x2003C881);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0160, 0x2003C881);
+  } else if (SystemConfiguration->LpssI2C6Enabled== 0) {
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0180, 0x2003C880);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0160, 0x2003C880);
+  }
+
+
+  /*
+  20.1.2  SDIO
+  SDMMC2_CLK -  write 0x2003ED01 to IOBASE + 0x0320
+  SDMMC2_CMD - write 0x2003EC81 to IOBASE + 0x0300
+  SDMMC2_D0 -    write 0x2003EC81 to IOBASE + 0x0350
+  SDMMC2_D1 -    write 0x2003EC81 to IOBASE + 0x02F0
+  SDMMC2_D2 -    write 0x2003EC81 to IOBASE + 0x0340
+  SDMMC2_D3_CD_B - write 0x2003EC81 to IOBASE + 0x0310
+  */
+  if (SystemConfiguration->LpssSdioEnabled== 1) {
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0320, 0x2003ED01);//SDIO
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0300, 0x2003EC81);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0350, 0x2003EC81);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x02F0, 0x2003EC81);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0340, 0x2003EC81);
+    MmioWrite32 (IO_BASE_ADDRESS + 0x0310, 0x2003EC81);
+  }
+
+  /*
+  20.1.3  SD Card
+  SDMMC3_1P8_EN - write 0x2003CD01 to IOBASE + 0x03F0
+  SDMMC3_CD_B -    write 0x2003CC81 to IOBASE + 0x03A0
+  SDMMC3_CLK -       write 0x2003CD01 to IOBASE + 0x02B0
+  SDMMC3_CMD -      write 0x2003CC81 to IOBASE + 0x02C0
+  SDMMC3_D0 -         write 0x2003CC81 to IOBASE + 0x02E0
+  SDMMC3_D1 -         write 0x2003CC81 to IOBASE + 0x0290
+  SDMMC3_D2 -         write 0x2003CC81 to IOBASE + 0x02D0
+  SDMMC3_D3 -         write 0x2003CC81 to IOBASE + 0x02A0
+  SDMMC3_PWR_EN_B - write 0x2003CC81 to IOBASE + 0x0690
+  SDMMC3_WP -            write 0x2003CC82 to IOBASE + 0x0160
+  */
+  if (SystemConfiguration->LpssSdcardEnabled == 1) {
+    if (!((PlatformInfo->BoardId == BOARD_ID_BL_FFRD && PlatformInfo->BoardRev== PR11) && (SystemConfiguration->CfioPnpSettings == 1))) {
+      MmioWrite32 (IO_BASE_ADDRESS + 0x05F0, 0x2003CD01);//SDCARD
+      MmioWrite32 (IO_BASE_ADDRESS + 0x02B0, 0x2003CD01);
+      MmioWrite32 (IO_BASE_ADDRESS + 0x02C0, 0x2003CC81);
+      MmioWrite32 (IO_BASE_ADDRESS + 0x02E0, 0x2003CC81);
+      MmioWrite32 (IO_BASE_ADDRESS + 0x0290, 0x2003CC81);
+      MmioWrite32 (IO_BASE_ADDRESS + 0x02D0, 0x2003CC81);
+      MmioWrite32 (IO_BASE_ADDRESS + 0x02A0, 0x2003CC81);
+      MmioWrite32 (IO_BASE_ADDRESS + 0x0690, 0x2003CC81);
+      MmioWrite32 (IO_BASE_ADDRESS + 0x0650, 0x2003CC82); //GPIOC_7 set to WP Pin
+     }
+  }
+
+
+     DEBUG ((EFI_D_ERROR, "ConfigureLpssAndSccGpio------------end\n"));
+    return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ConfigureLpeGpio (
+  IN SYSTEM_CONFIGURATION  *SystemConfiguration
+  )
+{
+  DEBUG ((EFI_D_ERROR, "ConfigureLpeGpio------------start\n"));
+
+  if (SystemConfiguration->PchAzalia == 0) {
+    MmioAndThenOr32 (IO_BASE_ADDRESS + 0x220, (UINT32)~(0x7), (UINT32) (0x01));
+    MmioAndThenOr32 (IO_BASE_ADDRESS + 0x250, (UINT32)~(0x7), (UINT32) (0x01));
+    MmioAndThenOr32 (IO_BASE_ADDRESS + 0x240, (UINT32)~(0x7), (UINT32) (0x01));
+    MmioAndThenOr32 (IO_BASE_ADDRESS + 0x260, (UINT32)~(0x7), (UINT32) (0x01));
+    MmioAndThenOr32 (IO_BASE_ADDRESS + 0x270, (UINT32)~(0x7), (UINT32) (0x01));
+    MmioAndThenOr32 (IO_BASE_ADDRESS + 0x230, (UINT32)~(0x7), (UINT32) (0x01));
+    MmioAndThenOr32 (IO_BASE_ADDRESS + 0x280, (UINT32)~(0x7), (UINT32) (0x01));
+    MmioAndThenOr32 (IO_BASE_ADDRESS + 0x540, (UINT32)~(0x7), (UINT32) (0x01));
+  }
+
+  DEBUG ((EFI_D_ERROR, "ConfigureLpeGpio------------end\n"));
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ConfigureSciSmiGpioRout (
+  IN EFI_PLATFORM_INFO_HOB       *PlatformInfo)
+{
+	UINT32 	GPI_Routing;
+
+	GPI_Routing = MmioRead32 (PMC_BASE_ADDRESS + R_PCH_PMC_GPI_ROUT);
+
+	//
+	// For FAB3, Route GPIO_CORE 0 to cause Runtime SCI, GPIO_SUS 0 to cause Wake SCI and GPIO_SUS 7 to cause EXTSMI
+	//
+	if(PlatformInfo->BoardRev == 3) {
+	GPI_Routing = GPI_Routing & 0xfffc3ffc;
+	GPI_Routing = GPI_Routing | 0x00024002;
+	}
+
+	//
+	// For FAB2/1, Route GPIO_CORE 7 to cause Runtime SCI, GPIO_SUS 0 to cause Wake SCI and GPIO_SUS 7 to cause EXTSMI
+	//
+	else {
+	GPI_Routing = GPI_Routing & 0x3fff3ffc;
+	GPI_Routing = GPI_Routing | 0x80004002;
+	}
+	MmioWrite32((PMC_BASE_ADDRESS + R_PCH_PMC_GPI_ROUT), GPI_Routing);
+
+	return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ConfigureMipiCsi (
+  VOID)
+{
+	  //
+    //Configure the platform clock for MIPI-CSI usage
+    //PLT_CLK0
+    //
+    MmioAndThenOr32 (IO_BASE_ADDRESS + 0x6a0, (UINT32)~(0x7), (UINT32) (0x01));
+
+    //
+    //PLT_CLK1
+    //
+    MmioAndThenOr32 (IO_BASE_ADDRESS + 0x570, (UINT32)~(0x7), (UINT32) (0x01));
+
+    //
+    //PLT_CLK2
+    //
+    MmioAndThenOr32 (IO_BASE_ADDRESS + 0x5B0, (UINT32)~(0x7), (UINT32) (0x01));
+
+    return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ConfigureUSBULPI (
+  VOID)
+{
+	  //
+    //Configure USB ULPI
+    //USB_ULPI_0_CLK
+    //
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x338, (UINT32)~(0x7), (UINT32) (GPI));
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x330, (UINT32)~(0x187), (UINT32) (0x101));
+
+    //
+    //USB_ULPI_0_DATA0
+    //
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x388, (UINT32)~(0x7), (UINT32) (GPI));
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x380, (UINT32)~(0x187), (UINT32) (0x101));
+
+    //
+    //USB_ULPI_0_DATA1
+    //
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x368, (UINT32)~(0x7), (UINT32) (GPI));
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x360, (UINT32)~(0x187), (UINT32) (0x101));
+
+    //
+    //USB_ULPI_0_DATA2
+    //
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x318, (UINT32)~(0x7), (UINT32) (GPI));
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x310, (UINT32)~(0x187), (UINT32) (0x101));
+
+    //
+    //USB_ULPI_0_DATA3
+    //
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x378, (UINT32)~(0x7), (UINT32) (GPI));
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x370, (UINT32)~(0x187), (UINT32) (0x101));
+
+    //
+    //USB_ULPI_0_DATA4
+    //
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x308, (UINT32)~(0x7), (UINT32) (GPI));
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x300, (UINT32)~(0x187), (UINT32) (0x101));
+
+    //
+    //USB_ULPI_0_DATA5
+    //
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x398, (UINT32)~(0x7), (UINT32) (GPI));
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x390, (UINT32)~(0x187), (UINT32) (0x101));
+
+    //
+    //USB_ULPI_0_DATA6
+    //
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x328, (UINT32)~(0x7), (UINT32) (GPI));
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x320, (UINT32)~(0x187), (UINT32) (0x101));
+
+    //
+    //USB_ULPI_0_DATA7
+    //
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x3a8, (UINT32)~(0x7), (UINT32) (GPI));
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x3a0, (UINT32)~(0x187), (UINT32) (0x101));
+
+    //
+    //USB_ULPI_0_DIR
+    //
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x348, (UINT32)~(0x7), (UINT32) (GPI));
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x340, (UINT32)~(0x187), (UINT32) (0x81));
+
+    //
+    //USB_ULPI_0_NXT
+    //
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x358, (UINT32)~(0x7), (UINT32) (GPI));
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x350, (UINT32)~(0x187), (UINT32) (0x101));
+
+    //
+    //USB_ULPI_0_STP
+    //
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x3b8, (UINT32)~(0x7), (UINT32) (GPI));
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x3b0, (UINT32)~(0x187), (UINT32) (0x81));
+
+    //
+    //USB_ULPI_0_REFCLK
+    //
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x288, (UINT32)~(0x7), (UINT32) (GPI));
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x280, (UINT32)~(0x187), (UINT32) (0x101));
+
+    return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DisableRTD3 (
+  VOID)
+{
+	  //
+    //Disable RTD3
+    //
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x210, (UINT32)~(0x0f000007), (UINT32) (0x00));
+    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x1e0, (UINT32)~(0x0f000007), (UINT32) (0x00));
+
+    return EFI_SUCCESS;
+}
+
+/**
+  Platform specific initializations in stage1.
+
+  @param FfsHeader         Pointer to the PEIM FFS file header.
+  @param PeiServices       General purpose services available to every PEIM.
+
+  @retval EFI_SUCCESS       Operation completed successfully.
+  @retval Otherwise         Platform initialization failed.
+**/
+EFI_STATUS
+EFIAPI
+PlatformEarlyInitEntry (
+
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES    **PeiServices
+  )
+{
+  EFI_STATUS                  Status;
+  SYSTEM_CONFIGURATION        SystemConfiguration;
+  EFI_PLATFORM_INFO_HOB       *PlatformInfo;
+  EFI_PEI_HOB_POINTERS        Hob;
+  EFI_PLATFORM_CPU_INFO       PlatformCpuInfo;
+  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *DescriptorBlock;
+  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *NewDescriptorBlock;
+  UINTN                           Index;
+  UINTN                           MaxIndex;
+  UINT64                          Base;
+  UINT64                          Size;
+  UINT64                          NewSize;
+
+  //
+  // Make sure base and size of the SMRAM region is aligned
+  //
+  Hob.Raw = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid);
+  if (Hob.Raw != NULL) {
+    DescriptorBlock = GET_GUID_HOB_DATA (Hob.Raw);
+    DEBUG ((DEBUG_INFO, "SMM PEI SMRAM Memory Reserved HOB\n"));
+    for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
+      DEBUG((DEBUG_INFO, "  SMRAM Descriptor[%02x]: Start=%016lx  Size=%016lx  State=%02x\n",
+        Index,
+        DescriptorBlock->Descriptor[Index].PhysicalStart,
+        DescriptorBlock->Descriptor[Index].PhysicalSize,
+        DescriptorBlock->Descriptor[Index].RegionState
+        ));
+    }
+
+    //
+    // Find the largest usable range of SMRAM between 1MB and 4GB
+    //
+    for (Index = 0, MaxIndex = 0, Size = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
+      //
+      // Skip any SMRAM region that is already allocated, needs testing, or needs ECC initialization
+      //
+      if ((DescriptorBlock->Descriptor[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) {
+        continue;
+      }
+      //
+      // Skip any SMRAM region below 1MB
+      //
+      if (DescriptorBlock->Descriptor[Index].CpuStart < BASE_1MB) {
+        continue;
+      }
+      //
+      // Skip any SMRAM region that is above 4GB or crosses the 4GB boundary
+      //
+      if ((DescriptorBlock->Descriptor[Index].CpuStart + DescriptorBlock->Descriptor[Index].PhysicalSize) >= BASE_4GB) {
+        continue;
+      }
+      //
+      // Cache the largest SMRAM region index
+      //
+      if (DescriptorBlock->Descriptor[Index].PhysicalSize >= DescriptorBlock->Descriptor[MaxIndex].PhysicalSize) {
+        MaxIndex = Index;
+      }
+    }
+
+    //
+    // Find the extent of the contiguous SMRAM region that surrounds the largest usable SMRAM range
+    //
+    Base = DescriptorBlock->Descriptor[MaxIndex].CpuStart;
+    Size = DescriptorBlock->Descriptor[MaxIndex].PhysicalSize;
+    for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
+      if (DescriptorBlock->Descriptor[Index].CpuStart < Base &&
+          Base == (DescriptorBlock->Descriptor[Index].CpuStart + DescriptorBlock->Descriptor[Index].PhysicalSize)) {
+        Base  = DescriptorBlock->Descriptor[Index].CpuStart;
+        Size += DescriptorBlock->Descriptor[Index].PhysicalSize;
+      } else if ((Base + Size) == DescriptorBlock->Descriptor[Index].CpuStart) {
+        Size += DescriptorBlock->Descriptor[Index].PhysicalSize;
+      }
+    }
+
+    //
+    // Round SMRAM region up to nearest power of 2 that is at least 4KB
+    //
+    NewSize = MAX (LShiftU64 (1, HighBitSet64 (Size - 1) + 1), SIZE_4KB);
+    if ((Base & ~(NewSize - 1)) != Base) {
+      //
+      // SMRAM region Base Address has smaller alignment than SMRAM region Size
+      // This is not compatible with SMRR settings
+      //
+      DEBUG((DEBUG_ERROR, "ERROR: SMRAM Region Size has larger alignment than SMRAM Region Base\n"));
+      DEBUG((DEBUG_ERROR, "  SMRAM Region Base=%016lx  Size=%016lx\n", Base, NewSize));
+      ASSERT (FALSE);
+    } else if (Size != NewSize) {
+      //
+      // See if the size difference can be added to an adjacent descriptor that is already allocated
+      //
+      for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
+        if ((DescriptorBlock->Descriptor[Index].CpuStart + DescriptorBlock->Descriptor[Index].PhysicalSize) == (Base + Size)) {
+          if (((DescriptorBlock->Descriptor[Index].RegionState) & EFI_ALLOCATED) != 0) {
+            DescriptorBlock->Descriptor[Index].PhysicalSize += (NewSize - Size);
+            Size = NewSize;
+            break;
+          }
+        }
+      }
+
+      if (Size != NewSize) {
+        //
+        // Add an allocated descriptor to the SMM PEI SMRAM Memory Reserved HOB to accomodate the larger size.
+        //
+        Index = DescriptorBlock->NumberOfSmmReservedRegions;
+        NewDescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *)BuildGuidHob (
+          &gEfiSmmPeiSmramMemoryReserveGuid,
+          sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK) + ((Index + 1) * sizeof (EFI_SMRAM_DESCRIPTOR))
+          );
+        ASSERT (NewDescriptorBlock != NULL);
+
+        //
+        // Copy old EFI_SMRAM_HOB_DESCRIPTOR_BLOCK to new allocated region
+        //
+        CopyMem (
+          NewDescriptorBlock,
+          DescriptorBlock,
+          sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK) + (Index * sizeof (EFI_SMRAM_DESCRIPTOR))
+          );
+
+        //
+        // Make sure last descriptor in NewDescriptorBlock contains last descriptor from DescriptorBlock
+        //
+        CopyMem (
+          &NewDescriptorBlock->Descriptor[Index],
+          &NewDescriptorBlock->Descriptor[Index - 1],
+          sizeof (EFI_SMRAM_DESCRIPTOR)
+          );
+
+        //
+        // Fill next to last descriptor with an allocated descriptor that aligns the total size of SMRAM
+        //
+        NewDescriptorBlock->Descriptor[Index - 1].CpuStart      = Base + Size;
+        NewDescriptorBlock->Descriptor[Index - 1].PhysicalStart = Base + Size;
+        NewDescriptorBlock->Descriptor[Index - 1].PhysicalSize  = NewSize - Size;
+        NewDescriptorBlock->Descriptor[Index - 1].RegionState   = DescriptorBlock->Descriptor[MaxIndex].RegionState | EFI_ALLOCATED;
+        NewDescriptorBlock->NumberOfSmmReservedRegions++;
+
+        //
+        // Invalidate the original gEfiSmmPeiSmramMemoryReserveGuid HOB
+        //
+        ZeroMem (&Hob.Guid->Name, sizeof (&Hob.Guid->Name));
+      }
+
+      Hob.Raw = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid);
+      DescriptorBlock = GET_GUID_HOB_DATA (Hob.Raw);
+      DEBUG ((DEBUG_INFO, "SMM PEI SMRAM Memory Reserved HOB - Updated\n"));
+      for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
+        DEBUG((DEBUG_INFO, "  SMRAM Descriptor[%02x]: Start=%016lx  Size=%016lx  State=%02x\n",
+          Index,
+          DescriptorBlock->Descriptor[Index].PhysicalStart,
+          DescriptorBlock->Descriptor[Index].PhysicalSize,
+          DescriptorBlock->Descriptor[Index].RegionState
+          ));
+      }
+    }
+  }
+
+  //
+  // Initialize SmbusPolicy PPI
+  //
+  Status = (*PeiServices)->InstallPpi(PeiServices, &mInstallSmbusPolicyPpi);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Initialize Stall PPIs
+  //
+  Status = (*PeiServices)->InstallPpi (PeiServices, &mInstallStallPpi);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Initialize platform PPIs
+  //
+  Status = (*PeiServices)->InstallPpi (PeiServices, &mInstallSpeakerInterfacePpi);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Variable initialization
+  //
+  ZeroMem(&PlatformCpuInfo, sizeof(EFI_PLATFORM_CPU_INFO));
+
+  //
+  // Set the some PCI and chipset range as UC
+  // And align to 1M at leaset
+  //
+  Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid);
+  ASSERT (Hob.Raw != NULL);
+  PlatformInfo = GET_GUID_HOB_DATA(Hob.Raw);
+
+  //
+  // Initialize PlatformInfo HOB
+  //
+  MultiPlatformInfoInit(PeiServices, PlatformInfo);
+
+  //
+  // Do basic MCH init
+  //
+  MchInit (PeiServices);
+
+  //
+  // Set the new boot mode
+  //
+  Status = UpdateBootMode (PeiServices, PlatformInfo);
+  ASSERT_EFI_ERROR (Status);
+
+  SetPlatformBootMode (PeiServices, PlatformInfo);
+
+  //
+  // Get setup variable. This can only be done after BootMode is updated
+  //
+  GetSetupVariable (PeiServices, &SystemConfiguration);
+
+  CheckOsSelection(PeiServices, &SystemConfiguration);
+
+  //
+  // Update PlatformInfo HOB according to setup variable
+  //
+  PlatformInfoUpdate(PeiServices, PlatformInfo, &SystemConfiguration);
+
+  InitializePlatform (PeiServices, PlatformInfo, &SystemConfiguration);
+
+  //
+  // Initialize VlvPolicy PPI
+  //
+  Status = VlvPolicyInit (PeiServices, &SystemConfiguration);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Soc specific GPIO setting
+  //
+  ConfigureSoCGpio(&SystemConfiguration);
+
+  //
+  //  Baylake Board specific.
+  //
+  if (PlatformInfo->BoardId == BOARD_ID_BL_RVP  ||
+      PlatformInfo->BoardId == BOARD_ID_BL_FFRD ||
+	    PlatformInfo->BoardId == BOARD_ID_BL_FFRD8 ||
+      PlatformInfo->BoardId == BOARD_ID_BL_RVP_DDR3L ||
+      PlatformInfo->BoardId == BOARD_ID_BL_STHI ||
+      PlatformInfo->BoardId == BOARD_ID_BB_RVP ||
+      PlatformInfo->BoardId == BOARD_ID_BS_RVP ||
+      PlatformInfo->BoardId == BOARD_ID_MINNOW2 ||
+      PlatformInfo->BoardId == BOARD_ID_MINNOW2_TURBOT||
+      PlatformInfo->BoardId == BOARD_ID_CVH) {
+    ConfigureLpssAndSccGpio(&SystemConfiguration, PlatformInfo);
+
+  }
+
+
+  //
+  //  Configure LPE
+  //  Alpine Valley and Bayley Bay board specific
+  //
+  ConfigureLpeGpio(&SystemConfiguration);
+
+  //
+  //  Bayley Bay Board specific.
+  //
+  ConfigureSciSmiGpioRout(PlatformInfo);
+  if (SystemConfiguration.LpssI2C3Enabled == 1) {
+    ConfigureMipiCsi();
+  }
+
+
+  //
+  // Do basic CPU init
+  //
+  Status = PlatformCpuInit (PeiServices, &SystemConfiguration, &PlatformCpuInfo);
+
+  //
+  // Perform basic SSA related platform initialization
+  //
+  PlatformSsaInit (&SystemConfiguration,PeiServices);
+
+
+  //
+  // Do basic PCH init
+  //
+  Status = PlatformPchInit (&SystemConfiguration, PeiServices, PlatformInfo->PlatformType);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Initialize platform PPIs
+  //
+  Status = (*PeiServices)->InstallPpi (PeiServices, &mPpiList[0]);
+  ASSERT_EFI_ERROR (Status);
+
+  if (PlatformInfo->BoardId != BOARD_ID_CVH) {
+    InstallPlatformClocksNotify (PeiServices);
+    InstallPlatformSysCtrlGPIONotify(PeiServices);
+  }
+
+  //
+  // Initialize platform PPIs
+  //
+  Status = (*PeiServices)->NotifyPpi(PeiServices, &mNotifyList[0]);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Initialize Measured Boot
+  //
+  Status = MeasuredBootInit (PeiServices, &SystemConfiguration);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+/**
+
+  Return the mainblockcompact Fv.
+
+  @param FvNumber    Our enumeration of the firmware volumes we care about.
+
+  @param FvAddress  Base Address of the memory containing the firmware volume
+
+  @retval EFI_SUCCESS
+  @retval EFI_NOT_FOUND
+
+**/
+EFI_STATUS
+EFIAPI
+FindFv (
+  IN EFI_PEI_FIND_FV_PPI          *This,
+  IN CONST EFI_PEI_SERVICES             **PeiServices,
+  IN OUT UINT8                    *FvNumber,
+  OUT EFI_FIRMWARE_VOLUME_HEADER  **FVAddress
+  )
+{
+	//
+  // At present, we only have one Fv to search
+  //
+  if (*FvNumber == 0) {
+    *FvNumber = 1;
+    *FVAddress = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FixedPcdGet32 (PcdFlashFvMainBase);
+    return EFI_SUCCESS;
+  }
+  else if (*FvNumber == 1) {
+    *FvNumber = 2;
+    *FVAddress = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FixedPcdGet32 (PcdFlashFvRecovery2Base);
+    return EFI_SUCCESS;
+  }
+  else { // Not the one Fv we care about
+    return EFI_NOT_FOUND;
+  }
+}
+
+EFI_STATUS
+EFIAPI
+CpuOnlyReset (
+  IN CONST EFI_PEI_SERVICES   **PeiServices
+  )
+{
+//  MsgBus32Write(CDV_UNIT_PUNIT, PUNIT_CPU_RST, 0x01)
+#ifdef __GNUC__
+  __asm__
+  (
+   "xorl %ecx, %ecx\n"
+   "1:hlt; hlt; hlt\n"
+   "jmp 1b\n"
+  );
+#else
+  _asm {
+    xor   ecx, ecx
+  HltLoop:
+    hlt
+    hlt
+    hlt
+    loop  HltLoop
+  }
+#endif
+  //
+  // If we get here we need to mark it as a failure.
+  //
+  return EFI_UNSUPPORTED;
+}
+
+
+#ifdef __GNUC__
+#pragma GCC pop_options
+#else
+#pragma optimize ("", on)
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.h b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.h
new file mode 100644
index 0000000000..29749277d7
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.h
@@ -0,0 +1,1499 @@
+/*++
+
+  Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  PlatformEarlyInit.h
+
+Abstract:
+
+  Platform Early Stage header file
+
+
+
+--*/
+
+/*++
+ This file contains an 'Intel Peripheral Driver' and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor.  This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+--*/
+
+#ifndef _EFI_PLATFORM_EARLY_INIT_H_
+#define _EFI_PLATFORM_EARLY_INIT_H_
+
+#define EFI_FORWARD_DECLARATION(x) typedef struct _##x x
+#include <FrameworkPei.h>
+#include "PlatformBaseAddresses.h"
+#include "PchAccess.h"
+#include "VlvAccess.h"
+#include "SetupMode.h"
+#include "PlatformBootMode.h"
+#include "Platform.h"
+#include "LegacySpeaker.h"
+
+#include <Ppi/Stall.h>
+#include <Guid/PlatformInfo.h>
+#include <Guid/SetupVariable.h>
+#include <Ppi/AtaController.h>
+#include <Ppi/FindFv.h>
+#include <Ppi/BootInRecoveryMode.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Ppi/Capsule.h>
+#include <Guid/EfiVpdData.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MtrrLib.h>
+#include <Library/CpuIA32.h>
+
+#include <IndustryStandard/Pci22.h>
+#include <Ppi/Speaker.h>
+#include <Guid/FirmwareFileSystem.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Ppi/Cache.h>
+#include <Ppi/Smbus.h>
+#include <Library/PchPlatformLib.h>
+#include <Ppi/SmbusPolicy.h>
+#include <Ppi/Reset.h>
+#include <Ppi/EndOfPeiPhase.h>
+#include <Ppi/MemoryDiscovered.h>
+#include <Ppi/VlvPolicy.h>
+#include <Guid/GlobalVariable.h>
+#include <Ppi/RecoveryModule.h>
+#include <Ppi/DeviceRecoveryModule.h>
+#include <Guid/Capsule.h>
+#include <Guid/RecoveryDevice.h>
+#include <Ppi/MasterBootMode.h>
+#include <Guid/PlatformCpuInfo.h>
+#include <Guid/OsSelection.h>
+#include <Guid/SmramMemoryReserve.h>
+#include <Register/Msr.h>
+
+#define SMC_LAN_ON       0x46
+#define SMC_LAN_OFF    0x47
+#define SMC_DEEP_S3_STS    0xB2
+
+
+
+
+//
+// Wake Event Types
+//
+#define SMBIOS_WAKEUP_TYPE_RESERVED           0x00
+#define SMBIOS_WAKEUP_TYPE_OTHERS             0x01
+#define SMBIOS_WAKEUP_TYPE_UNKNOWN            0x02
+#define SMBIOS_WAKEUP_TYPE_APM_TIMER          0x03
+#define SMBIOS_WAKEUP_TYPE_MODEM_RING         0x04
+#define SMBIOS_WAKEUP_TYPE_LAN_REMOTE         0x05
+#define SMBIOS_WAKEUP_TYPE_POWER_SWITCH       0x06
+#define SMBIOS_WAKEUP_TYPE_PCI_PME            0x07
+#define SMBIOS_WAKEUP_TYPE_AC_POWER_RESTORED  0x08
+
+#define EFI_CPUID_VIRT_PHYS_ADDRESS_SIZE       0x80000008
+
+//
+// Defines for stall ppi
+//
+#define PEI_STALL_RESOLUTION  1
+
+//
+// Used in PEI memory test routines
+//
+#define MEMORY_TEST_COVER_SPAN  0x40000
+#define MEMORY_TEST_PATTERN     0x5A5A5A5A
+
+#define EFI_LOW_BEEP_FREQUENCY            0x31B
+#define EFI_HIGH_BEEP_FREQUENCY           0x254
+
+//
+// General Purpose Constants
+//
+#define ICH_ACPI_TIMER_MAX_VALUE  0x1000000 //The timer is 24 bit overflow
+
+
+
+//
+//
+//              GPIO Register Settings for ValleyFalls (Tablet)
+//
+//
+//                   IO Space configyuration registers
+// Field Descriptions:
+//    USE: Defines the pin's usage model:  GPIO (G) or Native (N) mode.
+//    I/O: Defines whether GPIOs are inputs (I) or outputs (O).
+//         (Note:  Only meaningful for pins used as GPIOs.)
+//    LVL: This field gives you the initial value for "output" GPIO's.
+//         (Note: The output level is dependent upon whether the pin is inverted.)
+//    TPE: Defines whether Trigger Positive Edge Enable.
+//    TNE: Defines whether Trigger Negative Edge Enable.
+//    WAKE_EN: only support in SUS community
+//         (Note:  Only affects the level sent to the GPE logic and does not
+//         affect the level read through the GPIO registers.)
+//
+//
+//                    Memory spcae configuration registers
+//
+// Field Descriptions:
+//   PAD releated:
+//    PAD_CONF0
+//      PAD_CONF1
+//      PAD_VAL
+//      PAD_DFT
+//
+// Notes:
+//    1. N = Native , G = GPIO , I = Input, O = Output, - = BOTH/NOT SURE
+//
+// Signal          UsedAs                       USE     I/O      LVL     TPE     TNE   PCONF0   PCONF1   PVAL  PDFT
+// -------------------------------------------------------------------------------------------------------------------------
+// GPIO0           UART1_RXD-L                   N       I        -       -       -     cd29h    -         -     -
+// GPIO1           UART1_TXD-0                   N       O        -       -       -     cd29h    -         -     -
+// *GPIO2           UART1_RTS_B-1                N       I        -       -       -     cca9h    -         -     -
+// *GPIO3           UART1_CTS_B-H                N       O        -       -       -     cca9h    -         -     -
+
+// GPIO4           I2C1_SDA-OD-O                 N       -        -       -       -     cca9h    -         -     -
+// GPIO5           I2C1_SCL-OD-O                 N       -        -       -       -     cca9h    -         -     -
+// GPIO6           I2S_SYSCLK-0                  N       O        -       -       -     8d51h    -         -     -
+// GPIO7           I2S_L_R-0 (SP)                N       O        -       -       -     8cd1h    -         -     -
+// GPIO8           I2S_DATA_OUT-0                N       O        -       -       -     8cd1h    -         -     -
+// GPIO9           I2S_SDATA_IN-L                N       I        -       -       -     8cd1h    -         -     -
+
+// GPIO10          PCM_CLK-0                     N       O        -       -       -     8d51h    -         -     -
+// GPIO11          PCM_FSYNC-0 (SP)              N       O        -       -       -     8cd1h    -         -     -
+// GPIO12          PCM_DATA_OUT-0 (SP)           N       O        -       -       -     8cd1h    -         -     -
+// GPIO13          PCM_DATA_IN-L                 N       I        -       -       -     8d51h    -         -     -
+
+// GPIO14          SATA_GP0                      N       -        -       -       -      -       -         -     -
+// GPIO15          I2C2_SDA-OD-O/I               N       -        -       -       -     ccaah    -         -     -
+
+// GPIO16          SATA_LEDN                     N       O        -       -       -      -       -         -     -
+// GPIO17          UART2_RTS_B-1                 N       I        -       -       -     cd2ah    -         -     -
+// GPIO18          UART2_CTS_B-H                 N       O        -       -       -     ccaah    -         -     -
+// GPIO19          UART2_RXD-H                   N       I        -       -       -     ccaah    -         -     -
+
+// GPIO20          I2C2_SCL-OD-O/I               N       -        -       -       -     ccaah    -         -     -
+// GPIO21          **PCIE_CLKREQ4B               N       -        -       -       -      -       -         -     -
+// GPIO22          UART2_TXD-0                   N       O        -       -       -     ccaah    -         -     -
+// GPIO23          FLEX_CLK_SE1                  N       -        -       -       -      -       -         -     -
+
+// GPIO24          SPI0_SCK-0                    N       O        -       -       -     8d02h    -         -     -
+// GPIO25          SPI0_CS-1                     N       O        -       -       -     8d02h    -         -     -
+// GPIO26          SPI0_MOSI-0                   N       O        -       -       -     8d02h    -         -     -
+// GPIO27          SPI0_MISO-L                   N       I        -       -       -     8d02h    -         -     -
+
+// GPIO28          UART3_RXD-L                   N       I        -       -       -      -       -         -     -
+// GPIO29          UART3_TXD-0                   N       O        -       -       -      -       -         -     -
+// GPIO30          UART4_RXD-L                   N       I        -       -       -      -       -         -     -
+// GPIO31          UART4_TXD-0                   N       O        -       -       -      -       -         -     -
+
+// GPIO32          SDMMC1_CLK                    N       -        -       -       -     208d51h   -         -     -
+// GPIO33          SDMMC1_D0                     N       -        -       -       -     8cd1h     -         -     -
+// GPIO34          SDMMC1_D1                     N       -        -       -       -     8cd1h     -         -     -
+// GPIO35          SDMMC1_D2                     N       -        -       -       -     8cd1h     -         -     -
+// GPIO36          SDMMC1_D3_CD_B                N       -        -       -       -     8cd1h     -         -     -
+// GPIO37          MMC1_D4_SD_WE                 N       -        -       -       -     8cd1h     -         -     -
+// GPIO38          MMC1_D5                       N       -        -       -       -     8cd1h     -         -     -
+// GPIO39          MMC1_D6                       N       -        -       -       -     8cd1h     -         -     -
+// GPIO40          MMC1_D7                       N       -        -       -       -     8cd1h     -         -     -
+// GPIO41          SDMMC1_CMD                    N       -        -       -       -     8cd1h     -         -     -
+// GPIO42          MMC1_RESET_B                  N       -        -       -       -     208d51h   -         -     -
+
+// GPIO43          SDMMC2_CLK                    N       -        -       -       -     208d51h   -         -     -
+// GPIO44          SDMMC2_D0                     N       -        -       -       -     8cd1h     -         -     -
+// GPIO45          SDMMC2_D1                     N       -        -       -       -     8cd1h     -         -     -
+// GPIO46          SDMMC2_D2                     N       -        -       -       -     8cd1h     -         -     -
+// GPIO47          SDMMC2_D3_CD_B                N       -        -       -       -     8cd1h     -         -     -
+// GPIO48          SDMMC2_CMD                    N       -        -       -       -     8cd1h     -         -     -
+
+// GPIO49          SDMMC3_CLK                    N       -        -       -       -     8d51h      -         -     -
+// GPIO50          SDMMC3_D0                     N       -        -       -       -     8cd1h      -         -     -
+// GPIO51          SDMMC3_D1                     N       -        -       -       -      8cd1h      -         -     -
+// GPIO52          SDMMC3_D2                     N       -        -       -       -      8cd1h      -         -     -
+// GPIO53          SDMMC3_D3                     N       -        -       -       -      8cd1h      -         -     -
+// GPIO54          SDMMC3_CD_B                   N       -        -       -       -      cca9h      -         -     -
+// GPIO55          SDMMC3_CMD                    N       -        -       -       -      8cd1h      -         -     -
+// GPIO56          SDMMC3_1P8_EN                 N       -        -       -       -      cd29h   -         -     -
+
+// GPIO57            LPC_AD0                     N       -        -       -       -      -       -         -     -
+// GPIO58            LPC_AD1                     N       -        -       -       -      -       -         -     -
+// GPIO59            LPC_AD2                     N       -        -       -       -      -       -         -     -
+// GPIO60            LPC_AD3                     N       -        -       -       -      -       -         -     -
+// GPIO61            LPC_FRAMEB                  N       O        -       -       -      -       -         -     -
+// GPIO62            LPC_CLKOUT0                 N       O        -       -       -      -       -         -     -
+// GPIO63            LPC_CLKOUT1                 N       O        -       -       -      -       -         -     -
+// GPIO64            LPC_CLKRUNB                 N       -        -       -       -      -       -         -     -
+
+// GPIO65            SMB_DATA                    N       -        -       -       -      -       -         -     -
+// GPIO66            SMB_CLK                     N       -        -       -       -      -       -         -     -
+// GPIO67            SMB_ALERTB                  N       -        -       -       -      -       -         -     -
+
+// GPIO68            ILB_SEIRQ                   N       -       -        -       -      -       -         -     -
+// GPIO69            SPKR                        N       O       -        -       -      -       -         -     -
+
+//SUS WELL
+
+//GPIO_SUS0             BT_WAKEUP_VLV               N       O       -        -       -    CCA8h       -         -     -
+//GPIO_SUS1             BT_CLOCK_REQ                N       O       -        -       -    CCA8h       -         -     -
+//GPIO_SUS2             WIFI_PWR_EN                 N       O       -        -       -    CCA8h       -         -     -
+//GPIO_SUS3             SD_CARD_PWR_EN              N       O       -        -       -    CD28h       -         -     -
+//GPIO_SUS4             GPIO_SUS4                   N       O       -        -       -    CD28h       -         -     -
+//GPIO_SUS5             GPIO_SUS5                   N       O       -        -       -    CD28h       -         -     -
+//GPIO_SUS6             SUSPWRDNACK                 N       O       -        -       -    8850h       -         -     -
+//GPIO_SUS7             PMU_SLP_DDRVTT_B            N       O       -        -       -    8850h       -         -     -
+//GPIO_SUS8             PMU_WAKE_B                  N       O       -        -       -    CCA8h       -         -     -
+//GPIO_SUS9             PMU_PWRBTN_B                N       O       -        -       -    CCA8h       -         -     -
+//GPIO_SUS10            PMU_WAKE_LAN_B              N       O       -        -       -    CCA8h       -         -     -
+//GPIO_SUS11            SUS_STAT_B                  N       O       -        -       -    C828h       -         -     -
+//GPIO_SUS12            GPIO_SUS12                  N       O       -        -       -    C828h      -         -     -
+//GPIO_SUS13            USB_OC0_B-20K,H             N       O       -        -       -    CCA8h       -         -     -
+//GPIO_SUS14            GPIO_SUS14                  N       O       -        -       -    CCA8h       -         -     -
+//GPIO_SUS15            SPI_CS1_B-20K,H             N       O       -        -       -    8C80h       -         -     -
+//GPIO_SUS16            PMU_SUSCLK                  N       O       -        -       -    C828h       -         -     -
+//
+
+
+#define VF_TAB_GPIO_USE_SEL_VAL_0_31        0x00000000
+#define VF_TAB_GPIO_USE_SEL_VAL_32_63       0x00000000
+#define VF_TAB_GPIO_USE_SEL_VAL_64_70       0x00000000
+#define VF_TAB_GPIO_USE_SEL_VAL_SUS         0x00000000
+
+//
+//1010 --00 0100 01-- 0101 --0- 0001 1010
+//
+#define VF_TAB_GPIO_IO_SEL_VAL_0_31         0x00000000 // BIT30 | BIT28 | BIT27 | BIT19 | BIT17 | BIT13 | BIT9 | BIT2 | BIT0
+#define VF_TAB_GPIO_IO_SEL_VAL_32_63        0x00000000
+#define VF_TAB_GPIO_IO_SEL_VAL_64_70        0x00000000
+#define VF_TAB_GPIO_IO_SEL_VAL_SUS          0x00000000
+
+
+#define VF_TAB_GPIO_LVL_VAL_0_31            0x00000000
+#define VF_TAB_GPIO_LVL_VAL_32_63           0x00000000
+#define VF_TAB_GPIO_LVL_VAL_64_70           0x00000000
+#define VF_TAB_GPIO_LVL_VAL_SUS             0x00000000
+
+#define VF_TAB_GPIO_TPE_VAL_0_31            0x00000000
+#define VF_TAB_GPIO_TPE_VAL_SUS             0x00000000
+
+#define VF_TAB_GPIO_TNE_VAL_0_31            0x00000000
+#define VF_TAB_GPIO_TNE_VAL_SUS             0x00000000
+
+#define VF_TAB_GPIO_TS_VAL_0_31             0x00000000
+#define VF_TAB_GPIO_TS_VAL_SUS              0x00000000
+
+
+//
+// Memory space registers
+//
+
+//
+// CONF0
+//
+#define  VF_TAB_PAD_CONF0_GPIO0  0xcd29
+#define  VF_TAB_PAD_CONF0_GPIO1  0xcd29
+#define  VF_TAB_PAD_CONF0_GPIO2  0xcca9
+#define  VF_TAB_PAD_CONF0_GPIO3  0xcca9
+#define  VF_TAB_PAD_CONF0_GPIO4  0xcca9
+#define  VF_TAB_PAD_CONF0_GPIO5  0xcca9
+#define  VF_TAB_PAD_CONF0_GPIO6  0x8d51
+#define  VF_TAB_PAD_CONF0_GPIO7  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO8  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO9  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO10  0x8d51
+#define  VF_TAB_PAD_CONF0_GPIO11  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO12  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO13  0x8d51
+#define  VF_TAB_PAD_CONF0_GPIO14  0xCCA8
+#define  VF_TAB_PAD_CONF0_GPIO15  0xccaa
+#define  VF_TAB_PAD_CONF0_GPIO16  0xC828
+#define  VF_TAB_PAD_CONF0_GPIO17  0xcd2a
+#define  VF_TAB_PAD_CONF0_GPIO18  0xccaa
+#define  VF_TAB_PAD_CONF0_GPIO19  0xccaa
+#define  VF_TAB_PAD_CONF0_GPIO20  0xccaa
+#define  VF_TAB_PAD_CONF0_GPIO21  0xCCA9
+#define  VF_TAB_PAD_CONF0_GPIO22  0xccaa
+#define  VF_TAB_PAD_CONF0_GPIO23  0xCD2A
+#define  VF_TAB_PAD_CONF0_GPIO24  0x8d02
+#define  VF_TAB_PAD_CONF0_GPIO25  0x8d02
+#define  VF_TAB_PAD_CONF0_GPIO26  0x8d02
+#define  VF_TAB_PAD_CONF0_GPIO27  0x8d02
+#define  VF_TAB_PAD_CONF0_GPIO28  0x8D02
+#define  VF_TAB_PAD_CONF0_GPIO29  0x8D02
+#define  VF_TAB_PAD_CONF0_GPIO30  0x8D00
+#define  VF_TAB_PAD_CONF0_GPIO31  0xCD2A
+#define  VF_TAB_PAD_CONF0_GPIO32  0x208d51
+#define  VF_TAB_PAD_CONF0_GPIO33  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO34  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO35  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO36  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO37  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO38  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO39  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO40  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO41  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO42  0x208d51
+#define  VF_TAB_PAD_CONF0_GPIO43  0x208d51
+#define  VF_TAB_PAD_CONF0_GPIO44  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO45  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO46  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO47  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO48  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO49  0x8d51
+#define  VF_TAB_PAD_CONF0_GPIO50  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO51  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO52  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO53  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO54  0xcca9
+#define  VF_TAB_PAD_CONF0_GPIO55  0x8cd1
+#define  VF_TAB_PAD_CONF0_GPIO56  0xcd29
+#define  VF_TAB_PAD_CONF0_GPIO57  0x8C80
+#define  VF_TAB_PAD_CONF0_GPIO58  0x8C80
+#define  VF_TAB_PAD_CONF0_GPIO59  0x8C80
+#define  VF_TAB_PAD_CONF0_GPIO60  0x8C80
+#define  VF_TAB_PAD_CONF0_GPIO61  0x8800
+#define  VF_TAB_PAD_CONF0_GPIO62  0x8D00
+#define  VF_TAB_PAD_CONF0_GPIO63  0x8800
+#define  VF_TAB_PAD_CONF0_GPIO64  0x8800
+#define  VF_TAB_PAD_CONF0_GPIO65  0xC828
+#define  VF_TAB_PAD_CONF0_GPIO66  0xC828
+#define  VF_TAB_PAD_CONF0_GPIO67  0xC828
+#define  VF_TAB_PAD_CONF0_GPIO68  0xCCA8
+#define  VF_TAB_PAD_CONF0_GPIO69  0xC828
+#define  VF_TAB_PAD_CONF0_GPIO70  0xCCA8
+
+
+
+//
+// PAD_CONF1
+//
+#define  VF_TAB_PAD_CONF1_GPIO0  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO1  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO2  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO3  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO4  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO5  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO6  0x1F000F
+#define  VF_TAB_PAD_CONF1_GPIO7  0x1F000F
+#define  VF_TAB_PAD_CONF1_GPIO8  0x1F000F
+#define  VF_TAB_PAD_CONF1_GPIO9  0x1F000F
+#define  VF_TAB_PAD_CONF1_GPIO10  0x1F000F
+#define  VF_TAB_PAD_CONF1_GPIO11  0x1F000F
+#define  VF_TAB_PAD_CONF1_GPIO12  0x1F000F
+#define  VF_TAB_PAD_CONF1_GPIO13  0x1F000F
+#define  VF_TAB_PAD_CONF1_GPIO14  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO15  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO16  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO17  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO18  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO19  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO20  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO21  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO22  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO23  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO24  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO25  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO26  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO27  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO28  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO29  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO30  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO31  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO32  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO33  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO34  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO35  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO36  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO37  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO38  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO39  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO40  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO41  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO42  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO43  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO44  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO45  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO46  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO47  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO48  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO49  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO50  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO51  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO52  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO53  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO54  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO55  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO56  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO57  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO58  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO59  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO60  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO61  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO62  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO63  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO64  0x00000
+#define  VF_TAB_PAD_CONF1_GPIO65  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO66  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO67  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO68  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO69  0x20002
+#define  VF_TAB_PAD_CONF1_GPIO70  0x20002
+
+
+//
+// PAD_VAL
+//
+#define  VF_TAB_PAD_VAL_GPIO0  0x2
+#define  VF_TAB_PAD_VAL_GPIO1  0x2
+#define  VF_TAB_PAD_VAL_GPIO2  0x2
+#define  VF_TAB_PAD_VAL_GPIO3  0x2
+#define  VF_TAB_PAD_VAL_GPIO4  0x2
+#define  VF_TAB_PAD_VAL_GPIO5  0x2
+#define  VF_TAB_PAD_VAL_GPIO6  0x2
+#define  VF_TAB_PAD_VAL_GPIO7  0x2
+#define  VF_TAB_PAD_VAL_GPIO8  0x2
+#define  VF_TAB_PAD_VAL_GPIO9  0x2
+#define  VF_TAB_PAD_VAL_GPIO10  0x2
+#define  VF_TAB_PAD_VAL_GPIO11  0x2
+#define  VF_TAB_PAD_VAL_GPIO12  0x2
+#define  VF_TAB_PAD_VAL_GPIO13  0x2
+#define  VF_TAB_PAD_VAL_GPIO14  0x2
+#define  VF_TAB_PAD_VAL_GPIO15  0x2
+#define  VF_TAB_PAD_VAL_GPIO16  0x4
+#define  VF_TAB_PAD_VAL_GPIO17  0x2
+#define  VF_TAB_PAD_VAL_GPIO18  0x2
+#define  VF_TAB_PAD_VAL_GPIO19  0x2
+#define  VF_TAB_PAD_VAL_GPIO20  0x2
+#define  VF_TAB_PAD_VAL_GPIO21  0x2
+#define  VF_TAB_PAD_VAL_GPIO22  0x2
+#define  VF_TAB_PAD_VAL_GPIO23  0x2
+#define  VF_TAB_PAD_VAL_GPIO24  0x2
+#define  VF_TAB_PAD_VAL_GPIO25  0x2
+#define  VF_TAB_PAD_VAL_GPIO26  0x2
+#define  VF_TAB_PAD_VAL_GPIO27  0x2
+#define  VF_TAB_PAD_VAL_GPIO28  0x2
+#define  VF_TAB_PAD_VAL_GPIO29  0x2
+#define  VF_TAB_PAD_VAL_GPIO30  0x2
+#define  VF_TAB_PAD_VAL_GPIO31  0x2
+#define  VF_TAB_PAD_VAL_GPIO32  0x2
+#define  VF_TAB_PAD_VAL_GPIO33  0x2
+#define  VF_TAB_PAD_VAL_GPIO34  0x2
+#define  VF_TAB_PAD_VAL_GPIO35  0x2
+#define  VF_TAB_PAD_VAL_GPIO36  0x2
+#define  VF_TAB_PAD_VAL_GPIO37  0x2
+#define  VF_TAB_PAD_VAL_GPIO38  0x2
+#define  VF_TAB_PAD_VAL_GPIO39  0x2
+#define  VF_TAB_PAD_VAL_GPIO40  0x2
+#define  VF_TAB_PAD_VAL_GPIO41  0x2
+#define  VF_TAB_PAD_VAL_GPIO42  0x2
+#define  VF_TAB_PAD_VAL_GPIO43  0x2
+#define  VF_TAB_PAD_VAL_GPIO44  0x2
+#define  VF_TAB_PAD_VAL_GPIO45  0x2
+#define  VF_TAB_PAD_VAL_GPIO46  0x2
+#define  VF_TAB_PAD_VAL_GPIO47  0x2
+#define  VF_TAB_PAD_VAL_GPIO48  0x2
+#define  VF_TAB_PAD_VAL_GPIO49  0x2
+#define  VF_TAB_PAD_VAL_GPIO50  0x2
+#define  VF_TAB_PAD_VAL_GPIO51  0x2
+#define  VF_TAB_PAD_VAL_GPIO52  0x2
+#define  VF_TAB_PAD_VAL_GPIO53  0x2
+#define  VF_TAB_PAD_VAL_GPIO54  0x2
+#define  VF_TAB_PAD_VAL_GPIO55  0x2
+#define  VF_TAB_PAD_VAL_GPIO56  0x2
+#define  VF_TAB_PAD_VAL_GPIO57  0x2
+#define  VF_TAB_PAD_VAL_GPIO58  0x2
+#define  VF_TAB_PAD_VAL_GPIO59  0x2
+#define  VF_TAB_PAD_VAL_GPIO60  0x2
+#define  VF_TAB_PAD_VAL_GPIO61  0x4
+#define  VF_TAB_PAD_VAL_GPIO62  0x2
+#define  VF_TAB_PAD_VAL_GPIO63  0x2
+#define  VF_TAB_PAD_VAL_GPIO64  0x2
+#define  VF_TAB_PAD_VAL_GPIO65  0x2
+#define  VF_TAB_PAD_VAL_GPIO66  0x2
+#define  VF_TAB_PAD_VAL_GPIO67  0x0
+#define  VF_TAB_PAD_VAL_GPIO68  0x2
+#define  VF_TAB_PAD_VAL_GPIO69  0x4
+#define  VF_TAB_PAD_VAL_GPIO70  0x2
+
+
+//
+// PAD_DFT
+//
+#define  VF_TAB_PAD_DFT_GPIO0  0xC
+#define  VF_TAB_PAD_DFT_GPIO1  0xC
+#define  VF_TAB_PAD_DFT_GPIO2  0xC
+#define  VF_TAB_PAD_DFT_GPIO3  0xC
+#define  VF_TAB_PAD_DFT_GPIO4  0xC
+#define  VF_TAB_PAD_DFT_GPIO5  0xC
+#define  VF_TAB_PAD_DFT_GPIO6  0xC
+#define  VF_TAB_PAD_DFT_GPIO7  0xC
+#define  VF_TAB_PAD_DFT_GPIO8  0xC
+#define  VF_TAB_PAD_DFT_GPIO9  0xC
+#define  VF_TAB_PAD_DFT_GPIO10  0xC
+#define  VF_TAB_PAD_DFT_GPIO11  0xC
+#define  VF_TAB_PAD_DFT_GPIO12  0xC
+#define  VF_TAB_PAD_DFT_GPIO13  0xC
+#define  VF_TAB_PAD_DFT_GPIO14  0xC
+#define  VF_TAB_PAD_DFT_GPIO15  0xC
+#define  VF_TAB_PAD_DFT_GPIO16  0xC
+#define  VF_TAB_PAD_DFT_GPIO17  0xC
+#define  VF_TAB_PAD_DFT_GPIO18  0xC
+#define  VF_TAB_PAD_DFT_GPIO19  0xC
+#define  VF_TAB_PAD_DFT_GPIO20  0xC
+#define  VF_TAB_PAD_DFT_GPIO21  0xC
+#define  VF_TAB_PAD_DFT_GPIO22  0xC
+#define  VF_TAB_PAD_DFT_GPIO23  0xC
+#define  VF_TAB_PAD_DFT_GPIO24  0xC
+#define  VF_TAB_PAD_DFT_GPIO25  0xC
+#define  VF_TAB_PAD_DFT_GPIO26  0xC
+#define  VF_TAB_PAD_DFT_GPIO27  0xC
+#define  VF_TAB_PAD_DFT_GPIO28  0xC
+#define  VF_TAB_PAD_DFT_GPIO29  0xC
+#define  VF_TAB_PAD_DFT_GPIO30  0xC
+#define  VF_TAB_PAD_DFT_GPIO31  0xC
+#define  VF_TAB_PAD_DFT_GPIO32  0xC
+#define  VF_TAB_PAD_DFT_GPIO33  0xC
+#define  VF_TAB_PAD_DFT_GPIO34  0xC
+#define  VF_TAB_PAD_DFT_GPIO35  0xC
+#define  VF_TAB_PAD_DFT_GPIO36  0xC
+#define  VF_TAB_PAD_DFT_GPIO37  0xC
+#define  VF_TAB_PAD_DFT_GPIO38  0xC
+#define  VF_TAB_PAD_DFT_GPIO39  0xC
+#define  VF_TAB_PAD_DFT_GPIO40  0xC
+#define  VF_TAB_PAD_DFT_GPIO41  0xC
+#define  VF_TAB_PAD_DFT_GPIO42  0xC
+#define  VF_TAB_PAD_DFT_GPIO43  0xC
+#define  VF_TAB_PAD_DFT_GPIO44  0xC
+#define  VF_TAB_PAD_DFT_GPIO45  0xC
+#define  VF_TAB_PAD_DFT_GPIO46  0xC
+#define  VF_TAB_PAD_DFT_GPIO47  0xC
+#define  VF_TAB_PAD_DFT_GPIO48  0xC
+#define  VF_TAB_PAD_DFT_GPIO49  0xC
+#define  VF_TAB_PAD_DFT_GPIO50  0xC
+#define  VF_TAB_PAD_DFT_GPIO51  0xC
+#define  VF_TAB_PAD_DFT_GPIO52  0xC
+#define  VF_TAB_PAD_DFT_GPIO53  0xC
+#define  VF_TAB_PAD_DFT_GPIO54  0xC
+#define  VF_TAB_PAD_DFT_GPIO55  0xC
+#define  VF_TAB_PAD_DFT_GPIO56  0xC
+#define  VF_TAB_PAD_DFT_GPIO57  0xC
+#define  VF_TAB_PAD_DFT_GPIO58  0xC
+#define  VF_TAB_PAD_DFT_GPIO59  0xC
+#define  VF_TAB_PAD_DFT_GPIO60  0xC
+#define  VF_TAB_PAD_DFT_GPIO61  0xC
+#define  VF_TAB_PAD_DFT_GPIO62  0xC
+#define  VF_TAB_PAD_DFT_GPIO63  0xC
+#define  VF_TAB_PAD_DFT_GPIO64  0xC
+#define  VF_TAB_PAD_DFT_GPIO65  0xC
+#define  VF_TAB_PAD_DFT_GPIO66  0xC
+#define  VF_TAB_PAD_DFT_GPIO67  0xC
+#define  VF_TAB_PAD_DFT_GPIO68  0xC
+#define  VF_TAB_PAD_DFT_GPIO69  0xC
+#define  VF_TAB_PAD_DFT_GPIO70  0xC
+
+
+//
+//SUS WELL
+//
+
+//
+// CONF0
+//
+#define  VF_TAB_PAD_CONF0_GPIO_SUS0  0xCCA8
+#define  VF_TAB_PAD_CONF0_GPIO_SUS1  0xCCA8
+#define  VF_TAB_PAD_CONF0_GPIO_SUS2  0xCCA8
+#define  VF_TAB_PAD_CONF0_GPIO_SUS3  0xCD28
+#define  VF_TAB_PAD_CONF0_GPIO_SUS4  0xCD28
+#define  VF_TAB_PAD_CONF0_GPIO_SUS5  0xCD28
+#define  VF_TAB_PAD_CONF0_GPIO_SUS6  0x8850
+#define  VF_TAB_PAD_CONF0_GPIO_SUS7  0x8850
+#define  VF_TAB_PAD_CONF0_GPIO_SUS8  0xCCA8
+#define  VF_TAB_PAD_CONF0_GPIO_SUS9  0xCCA8
+#define  VF_TAB_PAD_CONF0_GPIO_SUS10  0xCCA8
+#define  VF_TAB_PAD_CONF0_GPIO_SUS11  0xC828
+#define  VF_TAB_PAD_CONF0_GPIO_SUS12  0xC828
+#define  VF_TAB_PAD_CONF0_GPIO_SUS13  0xCCA8
+#define  VF_TAB_PAD_CONF0_GPIO_SUS14  0xCCA8
+#define  VF_TAB_PAD_CONF0_GPIO_SUS15  0x8C80
+#define  VF_TAB_PAD_CONF0_GPIO_SUS16  0xC828
+
+//
+// CONF1
+//
+#define  VF_TAB_PAD_CONF1_GPIO_SUS0  0
+#define  VF_TAB_PAD_CONF1_GPIO_SUS1  0
+#define  VF_TAB_PAD_CONF1_GPIO_SUS2  0
+#define  VF_TAB_PAD_CONF1_GPIO_SUS3  0
+#define  VF_TAB_PAD_CONF1_GPIO_SUS4  0
+#define  VF_TAB_PAD_CONF1_GPIO_SUS5  0
+#define  VF_TAB_PAD_CONF1_GPIO_SUS6  0
+#define  VF_TAB_PAD_CONF1_GPIO_SUS7  0
+#define  VF_TAB_PAD_CONF1_GPIO_SUS8  0
+#define  VF_TAB_PAD_CONF1_GPIO_SUS9  0
+#define  VF_TAB_PAD_CONF1_GPIO_SUS10  0
+#define  VF_TAB_PAD_CONF1_GPIO_SUS11  0
+#define  VF_TAB_PAD_CONF1_GPIO_SUS12  0
+#define  VF_TAB_PAD_CONF1_GPIO_SUS13  0
+#define  VF_TAB_PAD_CONF1_GPIO_SUS14  0
+#define  VF_TAB_PAD_CONF1_GPIO_SUS15  0
+#define  VF_TAB_PAD_CONF1_GPIO_SUS16  0
+
+//
+// PAD_VAL
+//
+#define  VF_TAB_PAD_VAL_GPIO_SUS0  0
+#define  VF_TAB_PAD_VAL_GPIO_SUS1  0
+#define  VF_TAB_PAD_VAL_GPIO_SUS2  0
+#define  VF_TAB_PAD_VAL_GPIO_SUS3  0
+#define  VF_TAB_PAD_VAL_GPIO_SUS4  0
+#define  VF_TAB_PAD_VAL_GPIO_SUS5  0
+#define  VF_TAB_PAD_VAL_GPIO_SUS6  0
+#define  VF_TAB_PAD_VAL_GPIO_SUS7  0
+#define  VF_TAB_PAD_VAL_GPIO_SUS8  0
+#define  VF_TAB_PAD_VAL_GPIO_SUS9  0
+#define  VF_TAB_PAD_VAL_GPIO_SUS10  0
+#define  VF_TAB_PAD_VAL_GPIO_SUS11  0
+#define  VF_TAB_PAD_VAL_GPIO_SUS12  0
+#define  VF_TAB_PAD_VAL_GPIO_SUS13  0
+#define  VF_TAB_PAD_VAL_GPIO_SUS14  0
+#define  VF_TAB_PAD_VAL_GPIO_SUS15  0
+#define  VF_TAB_PAD_VAL_GPIO_SUS16  0
+
+//
+// PAD_DFT
+//
+#define  VF_TAB_PAD_DFT_GPIO_SUS0  0
+#define  VF_TAB_PAD_DFT_GPIO_SUS1  0
+#define  VF_TAB_PAD_DFT_GPIO_SUS2  0
+#define  VF_TAB_PAD_DFT_GPIO_SUS3  0
+#define  VF_TAB_PAD_DFT_GPIO_SUS4  0
+#define  VF_TAB_PAD_DFT_GPIO_SUS5  0
+#define  VF_TAB_PAD_DFT_GPIO_SUS6  0
+#define  VF_TAB_PAD_DFT_GPIO_SUS7  0
+#define  VF_TAB_PAD_DFT_GPIO_SUS8  0
+#define  VF_TAB_PAD_DFT_GPIO_SUS9  0
+#define  VF_TAB_PAD_DFT_GPIO_SUS10  0
+#define  VF_TAB_PAD_DFT_GPIO_SUS11  0
+#define  VF_TAB_PAD_DFT_GPIO_SUS12  0
+#define  VF_TAB_PAD_DFT_GPIO_SUS13  0
+#define  VF_TAB_PAD_DFT_GPIO_SUS14  0
+#define  VF_TAB_PAD_DFT_GPIO_SUS15  0
+#define  VF_TAB_PAD_DFT_GPIO_SUS16  0
+
+
+//
+//
+//              GPIO Register Settings for ValleyFalls (Netbook)
+//
+//
+//                   IO Space configyuration registers
+// Field Descriptions:
+//    USE: Defines the pin's usage model:  GPIO (G) or Native (N) mode.
+//    I/O: Defines whether GPIOs are inputs (I) or outputs (O).
+//         (Note:  Only meaningful for pins used as GPIOs.)
+//    LVL: This field gives you the initial value for "output" GPIO's.
+//         (Note: The output level is dependent upon whether the pin is inverted.)
+//    TPE: Defines whether Trigger Positive Edge Enable.
+//    TNE: Defines whether Trigger Negative Edge Enable.
+//    WAKE_EN: only support in SUS community
+//         (Note:  Only affects the level sent to the GPE logic and does not
+//         affect the level read through the GPIO registers.)
+//
+//
+//                    Memory spcae configuration registers
+//
+// Field Descriptions:
+//   PAD releated:
+//    PAD_CONF0
+//      PAD_CONF1
+//      PAD_VAL
+//      PAD_DFT
+//
+// Notes:
+//    1. N = Native , G = GPIO , I = Input, O = Output, - = BOTH/NOT SURE
+//
+// Signal          UsedAs                       USE     I/O      LVL     TPE     TNE   PCONF0   PCONF1   PVAL  PDFT
+// -------------------------------------------------------------------------------------------------------------------------
+// GPIO0           UART1_RXD-L                   N       I        -       -       -     cd29h    -         -     -
+// GPIO1           UART1_TXD-0                   N       O        -       -       -     cd29h    -         -     -
+// *GPIO2           UART1_RTS_B-1                N       I        -       -       -     cca9h    -         -     -
+// *GPIO3           UART1_CTS_B-H                N       O        -       -       -     cca9h    -         -     -
+
+// GPIO4           NMI_B-H                       G       -        -       -       -     cca9h    -         -     -
+// GPIO5           GPIO_D5                       G       -        -       -       -     cca9h    -         -     -
+// GPIO6           GPIO_D6                       G       O        -       -       -     8d51h    -         -     -
+// GPIO7           GPIO_D7                       G       O        -       -       -     8cd1h    -         -     -
+// GPIO8           GPIO_D8                       G       O        -       -       -     8cd1h    -         -     -
+// GPIO9           GPIO_D9                       G       I        -       -       -     8cd1h    -         -     -
+
+// GPIO10          GPIO_D10                      G       O        -       -       -     8d51h    -         -     -
+// GPIO11          GPIO_D11                      G       O        -       -       -     8cd1h    -         -     -
+// GPIO12          GPIO_D12                      G       O        -       -       -     8cd1h    -         -     -
+// GPIO13          GPIO_D13                      G       I        -       -       -     8d51h    -         -     -
+
+// GPIO14          SATA_GP0                      N       -        -       -       -      -       -         -     -
+// GPIO15          SATA_GP1-L                    N       -        -       -       -     ccaah    -         -     -
+
+// GPIO16          SATA_LEDN-OD-O                N       O        -       -       -      -       -         -     -
+// GPIO17          PCIE_CLKREQ0B-20K,H           N       I        -       -       -     cd2ah    -         -     -
+// GPIO18          PCIE_CLKREQ1B-20K,H           N       O        -       -       -     ccaah    -         -     -
+// GPIO19          PCIE_CLKREQ2B-20K,H           N       I        -       -       -     ccaah    -         -     -
+// GPIO20          PCIE_CLKREQ3B-20K,H           N       -        -       -       -     ccaah    -         -     -
+// GPIO21          PCIE_CLKREQ4B-20K,H           N       -        -       -       -      -       -         -     -
+// GPIO22          FLEX_CLK_SE0-20K,L            N       O        -       -       -     ccaah    -         -     -
+// GPIO23          FLEX_CLK_SE1-20K,L            N       -        -       -       -      -       -         -     -
+
+// GPIO24          HDA_RSTB                      N       O        -       -       -     8d02h    -         -     -
+// GPIO25          HDA_SYNC                      N       O        -       -       -     8d02h    -         -     -
+// GPIO26          HDA_CLK                       N       O        -       -       -     8d02h    -         -     -
+// GPIO27          HDA_SDO                       N       I        -       -       -     8d02h    -         -     -
+// GPIO28          HDA_SDI0                      N       I        -       -       -      -       -         -     -
+// GPIO29          HDA_SDI1                      N       O        -       -       -      -       -         -     -
+// GPIO30          HDA_DOCKRSTB                  N       I        -       -       -      -       -         -     -
+// GPIO31          HDA_DOCKENB                   N       O        -       -       -      -       -         -     -
+
+// GPIO32          SDMMC1_CLK                    N       -        -       -       -     208d51h   -         -     -
+// GPIO33          SDMMC1_D0                     N       -        -       -       -     8cd1h     -         -     -
+// GPIO34          SDMMC1_D1                     N       -        -       -       -     8cd1h     -         -     -
+// GPIO35          SDMMC1_D2                     N       -        -       -       -     8cd1h     -         -     -
+// GPIO36          SDMMC1_D3_CD_B                N       -        -       -       -     8cd1h     -         -     -
+// GPIO37          MMC1_D4_SD_WE                 N       -        -       -       -     8cd1h     -         -     -
+// GPIO38          MMC1_D5                       N       -        -       -       -     8cd1h     -         -     -
+// GPIO39          MMC1_D6                       N       -        -       -       -     8cd1h     -         -     -
+// GPIO40          MMC1_D7                       N       -        -       -       -     8cd1h     -         -     -
+// GPIO41          SDMMC1_CMD                    N       -        -       -       -     8cd1h     -         -     -
+// GPIO42          MMC1_RESET_B                  N       -        -       -       -     208d51h   -         -     -
+
+// GPIO43          SDMMC2_CLK                    N       -        -       -       -     208d51h   -         -     -
+// GPIO44          SDMMC2_D0                     N       -        -       -       -     8cd1h     -         -     -
+// GPIO45          SDMMC2_D1                     N       -        -       -       -     8cd1h     -         -     -
+// GPIO46          SDMMC2_D2                     N       -        -       -       -     8cd1h     -         -     -
+// GPIO47          SDMMC2_D3_CD_B                N       -        -       -       -     8cd1h     -         -     -
+// GPIO48          SDMMC2_CMD                    N       -        -       -       -     8cd1h     -         -     -
+
+// GPIO49          SDMMC3_CLK                    N       -        -       -       -     8d51h      -         -     -
+// GPIO50          SDMMC3_D0                     N       -        -       -       -     8cd1h      -         -     -
+// GPIO51          SDMMC3_D1                     N       -        -       -       -      8cd1h      -         -     -
+// GPIO52          SDMMC3_D2                     N       -        -       -       -      8cd1h      -         -     -
+// GPIO53          SDMMC3_D3                     N       -        -       -       -      8cd1h      -         -     -
+// GPIO54          SDMMC3_CD_B                   N       -        -       -       -      cca9h      -         -     -
+// GPIO55          SDMMC3_CMD                    N       -        -       -       -      8cd1h      -         -     -
+// GPIO56          SDMMC3_1P8_EN                 N       -        -       -       -      cd29h   -         -     -
+
+// GPIO57          LPC_AD0                     N       -        -       -       -      -       -         -     -
+// GPIO58          LPC_AD1                     N       -        -       -       -      -       -         -     -
+// GPIO59          LPC_AD2                     N       -        -       -       -      -       -         -     -
+// GPIO60          LPC_AD3                     N       -        -       -       -      -       -         -     -
+// GPIO61          LPC_FRAMEB                  N       O        -       -       -      -       -         -     -
+// GPIO62          LPC_CLKOUT0                 N       O        -       -       -      -       -         -     -
+// GPIO63          LPC_CLKOUT1                 N       O        -       -       -      -       -         -     -
+// GPIO64          LPC_CLKRUNB                 N       -        -       -       -      -       -         -     -
+
+// GPIO65          SMB_DATA                    N       -        -       -       -      -       -         -     -
+// GPIO66          SMB_CLK                     N       -        -       -       -      -       -         -     -
+// GPIO67          SMB_ALERTB                  N       -        -       -       -      -       -         -     -
+
+// GPIO68          ILB_SEIRQ                   N       -       -        -       -      -       -         -     -
+// GPIO69          SPKR                        N       O       -        -       -      -       -         -     -
+
+//SUS WELL
+
+
+//GPIO_SUS0             GPIO_SUS0                   N       O       -        -       -     CCA8h       -         -     -
+//GPIO_SUS1             GPIO_SUS1                   N       O       -        -       -     CCA8h       -         -     -
+//GPIO_SUS2             GPIO_SUS2                   N       O       -        -       -     CCA8h       -         -     -
+//GPIO_SUS3             GPIO_SUS3                   N       O       -        -       -     CD28h       -         -     -
+//GPIO_SUS4             GPIO_SUS4                   N       O       -        -       -     CD28h       -         -     -
+//GPIO_SUS5             GPIO_SUS5                   N       O       -        -       -     CD28h       -         -     -
+//GPIO_SUS6             SUSPWRDNACK-0               N       O       -        -       -     8850h       -         -     -
+//GPIO_SUS7             PMU_SLP_DDRVTT_B-0          N       O       -        -       -     8850h       -         -     -
+//GPIO_SUS8             PMU_WAKE_B-20K,H            N       O       -        -       -     CCA8h       -         -     -
+//GPIO_SUS9             PMU_PWRBTN_B-20K,H          N       O       -        -       -     CCA8h       -         -     -
+//GPIO_SUS10            PMU_WAKE_LAN_B-20K,H        N       O       -        -       -     CCA8h       -         -     -
+//GPIO_SUS11            SUS_STAT_B-1                N       O       -        -       -     C828h       -         -     -
+//GPIO_SUS12            PMU_SUSCLK-0                N       O       -        -       -     C828h       -         -     -
+//GPIO_SUS13            USB_OC0_B-20K,H             N       O       -        -       -     CCA8h       -         -     -
+//GPIO_SUS14            USB_OC1_B-20K,H             N       O       -        -       -     CCA8h       -         -     -
+//GPIO_SUS15            SPI_CS1_B-20K,H             N       O       -        -       -     8C80h       -         -     -
+//GPIO_SUS16            SPI_CS1_B-20K,H             N       O       -        -       -     C828h       -         -     -
+//
+
+#define VF_NET_GPIO_USE_SEL_VAL_0_31        0x00000000
+#define VF_NET_GPIO_USE_SEL_VAL_32_63       0x00000000
+#define VF_NET_GPIO_USE_SEL_VAL_64_70       0x00000000
+#define VF_NET_GPIO_USE_SEL_VAL_SUS         0x00000000
+
+//
+//1010 --00 0100 01-- 0101 --0- 0001 1010
+//
+#define VF_NET_GPIO_IO_SEL_VAL_0_31         0x00000000 // BIT30 | BIT28 | BIT27 | BIT19 | BIT17 | BIT13 | BIT9 | BIT2 | BIT0
+#define VF_NET_GPIO_IO_SEL_VAL_32_63        0x00000000
+#define VF_NET_GPIO_IO_SEL_VAL_64_70        0x00000000
+#define VF_NET_GPIO_IO_SEL_VAL_SUS          0x00000000
+
+
+#define VF_NET_GPIO_LVL_VAL_0_31            0x00000000
+#define VF_NET_GPIO_LVL_VAL_32_63           0x00000000
+#define VF_NET_GPIO_LVL_VAL_64_70           0x00000000
+#define VF_NET_GPIO_LVL_VAL_SUS             0x00000000
+
+#define VF_NET_GPIO_TPE_VAL_0_31            0x00000000
+#define VF_NET_GPIO_TPE_VAL_SUS             0x00000000
+
+#define VF_NET_GPIO_TNE_VAL_0_31            0x00000000
+#define VF_NET_GPIO_TNE_VAL_SUS             0x00000000
+
+#define VF_NET_GPIO_TS_VAL_0_31             0x00000000
+#define VF_NET_GPIO_TS_VAL_SUS              0x00000000
+
+
+//
+// Memory space registers
+//
+
+
+//
+// CONF0
+//
+#define  VF_NET_PAD_CONF0_GPIO0  0xcd29
+#define  VF_NET_PAD_CONF0_GPIO1  0xcd29
+#define  VF_NET_PAD_CONF0_GPIO2  0xcca9
+#define  VF_NET_PAD_CONF0_GPIO3  0xcca9
+#define  VF_NET_PAD_CONF0_GPIO4  0xcca8
+#define  VF_NET_PAD_CONF0_GPIO5  0xcca8
+#define  VF_NET_PAD_CONF0_GPIO6  0x8d50
+#define  VF_NET_PAD_CONF0_GPIO7  0x8cd0
+#define  VF_NET_PAD_CONF0_GPIO8  0x8cd0
+#define  VF_NET_PAD_CONF0_GPIO9  0x8cd0
+#define  VF_NET_PAD_CONF0_GPIO10  0x8d50
+#define  VF_NET_PAD_CONF0_GPIO11  0x8cd0
+#define  VF_NET_PAD_CONF0_GPIO12  0x8cd0
+#define  VF_NET_PAD_CONF0_GPIO13  0x8d50
+#define  VF_NET_PAD_CONF0_GPIO14  0xCCA8
+#define  VF_NET_PAD_CONF0_GPIO15  0xccaa
+#define  VF_NET_PAD_CONF0_GPIO16  0xC828
+#define  VF_NET_PAD_CONF0_GPIO17  0xcd2a
+#define  VF_NET_PAD_CONF0_GPIO18  0xccaa
+#define  VF_NET_PAD_CONF0_GPIO19  0xccaa
+#define  VF_NET_PAD_CONF0_GPIO20  0xccaa
+#define  VF_NET_PAD_CONF0_GPIO21  0xCCA9
+#define  VF_NET_PAD_CONF0_GPIO22  0xccaa
+#define  VF_NET_PAD_CONF0_GPIO23  0xCD2A
+#define  VF_NET_PAD_CONF0_GPIO24  0x8d02
+#define  VF_NET_PAD_CONF0_GPIO25  0x8d02
+#define  VF_NET_PAD_CONF0_GPIO26  0x8d02
+#define  VF_NET_PAD_CONF0_GPIO27  0x8d02
+#define  VF_NET_PAD_CONF0_GPIO28  0x8D02
+#define  VF_NET_PAD_CONF0_GPIO29  0x8D02
+#define  VF_NET_PAD_CONF0_GPIO30  0x8D00
+#define  VF_NET_PAD_CONF0_GPIO31  0xCD2A
+#define  VF_NET_PAD_CONF0_GPIO32  0x208d51
+#define  VF_NET_PAD_CONF0_GPIO33  0x8cd1
+#define  VF_NET_PAD_CONF0_GPIO34  0x8cd1
+#define  VF_NET_PAD_CONF0_GPIO35  0x8cd1
+#define  VF_NET_PAD_CONF0_GPIO36  0x8cd1
+#define  VF_NET_PAD_CONF0_GPIO37  0x8cd1
+#define  VF_NET_PAD_CONF0_GPIO38  0x8cd1
+#define  VF_NET_PAD_CONF0_GPIO39  0x8cd1
+#define  VF_NET_PAD_CONF0_GPIO40  0x8cd1
+#define  VF_NET_PAD_CONF0_GPIO41  0x8cd1
+#define  VF_NET_PAD_CONF0_GPIO42  0x208d51
+#define  VF_NET_PAD_CONF0_GPIO43  0x208d51
+#define  VF_NET_PAD_CONF0_GPIO44  0x8cd1
+#define  VF_NET_PAD_CONF0_GPIO45  0x8cd1
+#define  VF_NET_PAD_CONF0_GPIO46  0x8cd1
+#define  VF_NET_PAD_CONF0_GPIO47  0x8cd1
+#define  VF_NET_PAD_CONF0_GPIO48  0x8cd1
+#define  VF_NET_PAD_CONF0_GPIO49  0x8d51
+#define  VF_NET_PAD_CONF0_GPIO50  0x8cd1
+#define  VF_NET_PAD_CONF0_GPIO51  0x8cd1
+#define  VF_NET_PAD_CONF0_GPIO52  0x8cd1
+#define  VF_NET_PAD_CONF0_GPIO53  0x8cd1
+#define  VF_NET_PAD_CONF0_GPIO54  0xcca9
+#define  VF_NET_PAD_CONF0_GPIO55  0x8cd1
+#define  VF_NET_PAD_CONF0_GPIO56  0xcd29
+#define  VF_NET_PAD_CONF0_GPIO57  0x8C80
+#define  VF_NET_PAD_CONF0_GPIO58  0x8C80
+#define  VF_NET_PAD_CONF0_GPIO59  0x8C80
+#define  VF_NET_PAD_CONF0_GPIO60  0x8C80
+#define  VF_NET_PAD_CONF0_GPIO61  0x8800
+#define  VF_NET_PAD_CONF0_GPIO62  0x8D00
+#define  VF_NET_PAD_CONF0_GPIO63  0x8800
+#define  VF_NET_PAD_CONF0_GPIO64  0x8800
+#define  VF_NET_PAD_CONF0_GPIO65  0xC828
+#define  VF_NET_PAD_CONF0_GPIO66  0xC828
+#define  VF_NET_PAD_CONF0_GPIO67  0xC828
+#define  VF_NET_PAD_CONF0_GPIO68  0xCCA8
+#define  VF_NET_PAD_CONF0_GPIO69  0xC828
+#define  VF_NET_PAD_CONF0_GPIO70  0xCCA8
+
+
+
+
+//
+// PAD_CONF1
+//
+#define  VF_NET_PAD_CONF1_GPIO0  0x20002
+#define  VF_NET_PAD_CONF1_GPIO1  0x20002
+#define  VF_NET_PAD_CONF1_GPIO2  0x20002
+#define  VF_NET_PAD_CONF1_GPIO3  0x20002
+#define  VF_NET_PAD_CONF1_GPIO4  0x20002
+#define  VF_NET_PAD_CONF1_GPIO5  0x20002
+#define  VF_NET_PAD_CONF1_GPIO6  0x1F000F
+#define  VF_NET_PAD_CONF1_GPIO7  0x1F000F
+#define  VF_NET_PAD_CONF1_GPIO8  0x1F000F
+#define  VF_NET_PAD_CONF1_GPIO9  0x1F000F
+#define  VF_NET_PAD_CONF1_GPIO10  0x1F000F
+#define  VF_NET_PAD_CONF1_GPIO11  0x1F000F
+#define  VF_NET_PAD_CONF1_GPIO12  0x1F000F
+#define  VF_NET_PAD_CONF1_GPIO13  0x1F000F
+#define  VF_NET_PAD_CONF1_GPIO14  0x20002
+#define  VF_NET_PAD_CONF1_GPIO15  0x20002
+#define  VF_NET_PAD_CONF1_GPIO16  0x20002
+#define  VF_NET_PAD_CONF1_GPIO17  0x20002
+#define  VF_NET_PAD_CONF1_GPIO18  0x20002
+#define  VF_NET_PAD_CONF1_GPIO19  0x20002
+#define  VF_NET_PAD_CONF1_GPIO20  0x20002
+#define  VF_NET_PAD_CONF1_GPIO21  0x20002
+#define  VF_NET_PAD_CONF1_GPIO22  0x20002
+#define  VF_NET_PAD_CONF1_GPIO23  0x20002
+#define  VF_NET_PAD_CONF1_GPIO24  0x00000
+#define  VF_NET_PAD_CONF1_GPIO25  0x00000
+#define  VF_NET_PAD_CONF1_GPIO26  0x00000
+#define  VF_NET_PAD_CONF1_GPIO27  0x00000
+#define  VF_NET_PAD_CONF1_GPIO28  0x00000
+#define  VF_NET_PAD_CONF1_GPIO29  0x00000
+#define  VF_NET_PAD_CONF1_GPIO30  0x00000
+#define  VF_NET_PAD_CONF1_GPIO31  0x20002
+#define  VF_NET_PAD_CONF1_GPIO32  0x00000
+#define  VF_NET_PAD_CONF1_GPIO33  0x00000
+#define  VF_NET_PAD_CONF1_GPIO34  0x00000
+#define  VF_NET_PAD_CONF1_GPIO35  0x00000
+#define  VF_NET_PAD_CONF1_GPIO36  0x00000
+#define  VF_NET_PAD_CONF1_GPIO37  0x00000
+#define  VF_NET_PAD_CONF1_GPIO38  0x00000
+#define  VF_NET_PAD_CONF1_GPIO39  0x00000
+#define  VF_NET_PAD_CONF1_GPIO40  0x00000
+#define  VF_NET_PAD_CONF1_GPIO41  0x00000
+#define  VF_NET_PAD_CONF1_GPIO42  0x00000
+#define  VF_NET_PAD_CONF1_GPIO43  0x00000
+#define  VF_NET_PAD_CONF1_GPIO44  0x00000
+#define  VF_NET_PAD_CONF1_GPIO45  0x00000
+#define  VF_NET_PAD_CONF1_GPIO46  0x00000
+#define  VF_NET_PAD_CONF1_GPIO47  0x00000
+#define  VF_NET_PAD_CONF1_GPIO48  0x00000
+#define  VF_NET_PAD_CONF1_GPIO49  0x00000
+#define  VF_NET_PAD_CONF1_GPIO50  0x00000
+#define  VF_NET_PAD_CONF1_GPIO51  0x00000
+#define  VF_NET_PAD_CONF1_GPIO52  0x00000
+#define  VF_NET_PAD_CONF1_GPIO53  0x00000
+#define  VF_NET_PAD_CONF1_GPIO54  0x20002
+#define  VF_NET_PAD_CONF1_GPIO55  0x00000
+#define  VF_NET_PAD_CONF1_GPIO56  0x20002
+#define  VF_NET_PAD_CONF1_GPIO57  0x00000
+#define  VF_NET_PAD_CONF1_GPIO58  0x00000
+#define  VF_NET_PAD_CONF1_GPIO59  0x00000
+#define  VF_NET_PAD_CONF1_GPIO60  0x00000
+#define  VF_NET_PAD_CONF1_GPIO61  0x00000
+#define  VF_NET_PAD_CONF1_GPIO62  0x00000
+#define  VF_NET_PAD_CONF1_GPIO63  0x00000
+#define  VF_NET_PAD_CONF1_GPIO64  0x00000
+#define  VF_NET_PAD_CONF1_GPIO65  0x20002
+#define  VF_NET_PAD_CONF1_GPIO66  0x20002
+#define  VF_NET_PAD_CONF1_GPIO67  0x20002
+#define  VF_NET_PAD_CONF1_GPIO68  0x20002
+#define  VF_NET_PAD_CONF1_GPIO69  0x20002
+#define  VF_NET_PAD_CONF1_GPIO70  0x20002
+
+
+
+//
+// PAD_VAL
+//
+#define  VF_NET_PAD_VAL_GPIO0  0x2
+#define  VF_NET_PAD_VAL_GPIO1  0x2
+#define  VF_NET_PAD_VAL_GPIO2  0x2
+#define  VF_NET_PAD_VAL_GPIO3  0x2
+#define  VF_NET_PAD_VAL_GPIO4  0x2
+#define  VF_NET_PAD_VAL_GPIO5  0x2
+#define  VF_NET_PAD_VAL_GPIO6  0x2
+#define  VF_NET_PAD_VAL_GPIO7  0x2
+#define  VF_NET_PAD_VAL_GPIO8  0x2
+#define  VF_NET_PAD_VAL_GPIO9  0x2
+#define  VF_NET_PAD_VAL_GPIO10  0x2
+#define  VF_NET_PAD_VAL_GPIO11  0x2
+#define  VF_NET_PAD_VAL_GPIO12  0x2
+#define  VF_NET_PAD_VAL_GPIO13  0x2
+#define  VF_NET_PAD_VAL_GPIO14  0x2
+#define  VF_NET_PAD_VAL_GPIO15  0x2
+#define  VF_NET_PAD_VAL_GPIO16  0x4
+#define  VF_NET_PAD_VAL_GPIO17  0x2
+#define  VF_NET_PAD_VAL_GPIO18  0x2
+#define  VF_NET_PAD_VAL_GPIO19  0x2
+#define  VF_NET_PAD_VAL_GPIO20  0x2
+#define  VF_NET_PAD_VAL_GPIO21  0x2
+#define  VF_NET_PAD_VAL_GPIO22  0x2
+#define  VF_NET_PAD_VAL_GPIO23  0x2
+#define  VF_NET_PAD_VAL_GPIO24  0x2
+#define  VF_NET_PAD_VAL_GPIO25  0x2
+#define  VF_NET_PAD_VAL_GPIO26  0x2
+#define  VF_NET_PAD_VAL_GPIO27  0x2
+#define  VF_NET_PAD_VAL_GPIO28  0x2
+#define  VF_NET_PAD_VAL_GPIO29  0x2
+#define  VF_NET_PAD_VAL_GPIO30  0x2
+#define  VF_NET_PAD_VAL_GPIO31  0x2
+#define  VF_NET_PAD_VAL_GPIO32  0x2
+#define  VF_NET_PAD_VAL_GPIO33  0x2
+#define  VF_NET_PAD_VAL_GPIO34  0x2
+#define  VF_NET_PAD_VAL_GPIO35  0x2
+#define  VF_NET_PAD_VAL_GPIO36  0x2
+#define  VF_NET_PAD_VAL_GPIO37  0x2
+#define  VF_NET_PAD_VAL_GPIO38  0x2
+#define  VF_NET_PAD_VAL_GPIO39  0x2
+#define  VF_NET_PAD_VAL_GPIO40  0x2
+#define  VF_NET_PAD_VAL_GPIO41  0x2
+#define  VF_NET_PAD_VAL_GPIO42  0x2
+#define  VF_NET_PAD_VAL_GPIO43  0x2
+#define  VF_NET_PAD_VAL_GPIO44  0x2
+#define  VF_NET_PAD_VAL_GPIO45  0x2
+#define  VF_NET_PAD_VAL_GPIO46  0x2
+#define  VF_NET_PAD_VAL_GPIO47  0x2
+#define  VF_NET_PAD_VAL_GPIO48  0x2
+#define  VF_NET_PAD_VAL_GPIO49  0x2
+#define  VF_NET_PAD_VAL_GPIO50  0x2
+#define  VF_NET_PAD_VAL_GPIO51  0x2
+#define  VF_NET_PAD_VAL_GPIO52  0x2
+#define  VF_NET_PAD_VAL_GPIO53  0x2
+#define  VF_NET_PAD_VAL_GPIO54  0x2
+#define  VF_NET_PAD_VAL_GPIO55  0x2
+#define  VF_NET_PAD_VAL_GPIO56  0x2
+#define  VF_NET_PAD_VAL_GPIO57  0x2
+#define  VF_NET_PAD_VAL_GPIO58  0x2
+#define  VF_NET_PAD_VAL_GPIO59  0x2
+#define  VF_NET_PAD_VAL_GPIO60  0x2
+#define  VF_NET_PAD_VAL_GPIO61  0x4
+#define  VF_NET_PAD_VAL_GPIO62  0x2
+#define  VF_NET_PAD_VAL_GPIO63  0x2
+#define  VF_NET_PAD_VAL_GPIO64  0x2
+#define  VF_NET_PAD_VAL_GPIO65  0x2
+#define  VF_NET_PAD_VAL_GPIO66  0x2
+#define  VF_NET_PAD_VAL_GPIO67  0x0
+#define  VF_NET_PAD_VAL_GPIO68  0x2
+#define  VF_NET_PAD_VAL_GPIO69  0x4
+#define  VF_NET_PAD_VAL_GPIO70  0x2
+
+
+//
+// PAD_DFT
+//
+#define  VF_NET_PAD_DFT_GPIO0  0xC
+#define  VF_NET_PAD_DFT_GPIO1  0xC
+#define  VF_NET_PAD_DFT_GPIO2  0xC
+#define  VF_NET_PAD_DFT_GPIO3  0xC
+#define  VF_NET_PAD_DFT_GPIO4  0xC
+#define  VF_NET_PAD_DFT_GPIO5  0xC
+#define  VF_NET_PAD_DFT_GPIO6  0xC
+#define  VF_NET_PAD_DFT_GPIO7  0xC
+#define  VF_NET_PAD_DFT_GPIO8  0xC
+#define  VF_NET_PAD_DFT_GPIO9  0xC
+#define  VF_NET_PAD_DFT_GPIO10  0xC
+#define  VF_NET_PAD_DFT_GPIO11  0xC
+#define  VF_NET_PAD_DFT_GPIO12  0xC
+#define  VF_NET_PAD_DFT_GPIO13  0xC
+#define  VF_NET_PAD_DFT_GPIO14  0xC
+#define  VF_NET_PAD_DFT_GPIO15  0xC
+#define  VF_NET_PAD_DFT_GPIO16  0xC
+#define  VF_NET_PAD_DFT_GPIO17  0xC
+#define  VF_NET_PAD_DFT_GPIO18  0xC
+#define  VF_NET_PAD_DFT_GPIO19  0xC
+#define  VF_NET_PAD_DFT_GPIO20  0xC
+#define  VF_NET_PAD_DFT_GPIO21  0xC
+#define  VF_NET_PAD_DFT_GPIO22  0xC
+#define  VF_NET_PAD_DFT_GPIO23  0xC
+#define  VF_NET_PAD_DFT_GPIO24  0xC
+#define  VF_NET_PAD_DFT_GPIO25  0xC
+#define  VF_NET_PAD_DFT_GPIO26  0xC
+#define  VF_NET_PAD_DFT_GPIO27  0xC
+#define  VF_NET_PAD_DFT_GPIO28  0xC
+#define  VF_NET_PAD_DFT_GPIO29  0xC
+#define  VF_NET_PAD_DFT_GPIO30  0xC
+#define  VF_NET_PAD_DFT_GPIO31  0xC
+#define  VF_NET_PAD_DFT_GPIO32  0xC
+#define  VF_NET_PAD_DFT_GPIO33  0xC
+#define  VF_NET_PAD_DFT_GPIO34  0xC
+#define  VF_NET_PAD_DFT_GPIO35  0xC
+#define  VF_NET_PAD_DFT_GPIO36  0xC
+#define  VF_NET_PAD_DFT_GPIO37  0xC
+#define  VF_NET_PAD_DFT_GPIO38  0xC
+#define  VF_NET_PAD_DFT_GPIO39  0xC
+#define  VF_NET_PAD_DFT_GPIO40  0xC
+#define  VF_NET_PAD_DFT_GPIO41  0xC
+#define  VF_NET_PAD_DFT_GPIO42  0xC
+#define  VF_NET_PAD_DFT_GPIO43  0xC
+#define  VF_NET_PAD_DFT_GPIO44  0xC
+#define  VF_NET_PAD_DFT_GPIO45  0xC
+#define  VF_NET_PAD_DFT_GPIO46  0xC
+#define  VF_NET_PAD_DFT_GPIO47  0xC
+#define  VF_NET_PAD_DFT_GPIO48  0xC
+#define  VF_NET_PAD_DFT_GPIO49  0xC
+#define  VF_NET_PAD_DFT_GPIO50  0xC
+#define  VF_NET_PAD_DFT_GPIO51  0xC
+#define  VF_NET_PAD_DFT_GPIO52  0xC
+#define  VF_NET_PAD_DFT_GPIO53  0xC
+#define  VF_NET_PAD_DFT_GPIO54  0xC
+#define  VF_NET_PAD_DFT_GPIO55  0xC
+#define  VF_NET_PAD_DFT_GPIO56  0xC
+#define  VF_NET_PAD_DFT_GPIO57  0xC
+#define  VF_NET_PAD_DFT_GPIO58  0xC
+#define  VF_NET_PAD_DFT_GPIO59  0xC
+#define  VF_NET_PAD_DFT_GPIO60  0xC
+#define  VF_NET_PAD_DFT_GPIO61  0xC
+#define  VF_NET_PAD_DFT_GPIO62  0xC
+#define  VF_NET_PAD_DFT_GPIO63  0xC
+#define  VF_NET_PAD_DFT_GPIO64  0xC
+#define  VF_NET_PAD_DFT_GPIO65  0xC
+#define  VF_NET_PAD_DFT_GPIO66  0xC
+#define  VF_NET_PAD_DFT_GPIO67  0xC
+#define  VF_NET_PAD_DFT_GPIO68  0xC
+#define  VF_NET_PAD_DFT_GPIO69  0xC
+#define  VF_NET_PAD_DFT_GPIO70  0xC
+
+//
+// PCONF0
+//
+#define  VF_NET_PAD_CONF0_GPIO_SUS0  0xCCA8
+#define  VF_NET_PAD_CONF0_GPIO_SUS1  0xCCA8
+#define  VF_NET_PAD_CONF0_GPIO_SUS2  0xCCA8
+#define  VF_NET_PAD_CONF0_GPIO_SUS3  0xCD28
+#define  VF_NET_PAD_CONF0_GPIO_SUS4  0xCD28
+#define  VF_NET_PAD_CONF0_GPIO_SUS5  0xCD28
+#define  VF_NET_PAD_CONF0_GPIO_SUS6  0x8850
+#define  VF_NET_PAD_CONF0_GPIO_SUS7  0x8850
+#define  VF_NET_PAD_CONF0_GPIO_SUS8  0xCCA8
+#define  VF_NET_PAD_CONF0_GPIO_SUS9  0xCCA8
+#define  VF_NET_PAD_CONF0_GPIO_SUS10  0xCCA8
+#define  VF_NET_PAD_CONF0_GPIO_SUS11  0xC828
+#define  VF_NET_PAD_CONF0_GPIO_SUS12  0xC828
+#define  VF_NET_PAD_CONF0_GPIO_SUS13  0xCCA8
+#define  VF_NET_PAD_CONF0_GPIO_SUS14  0xCCA8
+#define  VF_NET_PAD_CONF0_GPIO_SUS15  0x8C80
+#define  VF_NET_PAD_CONF0_GPIO_SUS16  0xC828
+
+//
+// PCONF1
+//
+#define  VF_NET_PAD_CONF1_GPIO_SUS0  0
+#define  VF_NET_PAD_CONF1_GPIO_SUS1  0
+#define  VF_NET_PAD_CONF1_GPIO_SUS2  0
+#define  VF_NET_PAD_CONF1_GPIO_SUS3  0
+#define  VF_NET_PAD_CONF1_GPIO_SUS4  0
+#define  VF_NET_PAD_CONF1_GPIO_SUS5  0
+#define  VF_NET_PAD_CONF1_GPIO_SUS6  0
+#define  VF_NET_PAD_CONF1_GPIO_SUS7  0
+#define  VF_NET_PAD_CONF1_GPIO_SUS8  0
+#define  VF_NET_PAD_CONF1_GPIO_SUS9  0
+#define  VF_NET_PAD_CONF1_GPIO_SUS10  0
+#define  VF_NET_PAD_CONF1_GPIO_SUS11  0
+#define  VF_NET_PAD_CONF1_GPIO_SUS12  0
+#define  VF_NET_PAD_CONF1_GPIO_SUS13  0
+#define  VF_NET_PAD_CONF1_GPIO_SUS14  0
+#define  VF_NET_PAD_CONF1_GPIO_SUS15  0
+#define  VF_NET_PAD_CONF1_GPIO_SUS16  0
+
+
+#define  VF_NET_PAD_VAL_GPIO_SUS0  0
+#define  VF_NET_PAD_VAL_GPIO_SUS1  0
+#define  VF_NET_PAD_VAL_GPIO_SUS2  0
+#define  VF_NET_PAD_VAL_GPIO_SUS3  0
+#define  VF_NET_PAD_VAL_GPIO_SUS4  0
+#define  VF_NET_PAD_VAL_GPIO_SUS5  0
+#define  VF_NET_PAD_VAL_GPIO_SUS6  0
+#define  VF_NET_PAD_VAL_GPIO_SUS7  0
+#define  VF_NET_PAD_VAL_GPIO_SUS8  0
+#define  VF_NET_PAD_VAL_GPIO_SUS9  0
+#define  VF_NET_PAD_VAL_GPIO_SUS10  0
+#define  VF_NET_PAD_VAL_GPIO_SUS11  0
+#define  VF_NET_PAD_VAL_GPIO_SUS12  0
+#define  VF_NET_PAD_VAL_GPIO_SUS13  0
+#define  VF_NET_PAD_VAL_GPIO_SUS14  0
+#define  VF_NET_PAD_VAL_GPIO_SUS15  0
+#define  VF_NET_PAD_VAL_GPIO_SUS16  0
+
+
+#define  VF_NET_PAD_DFT_GPIO_SUS0  0
+#define  VF_NET_PAD_DFT_GPIO_SUS1  0
+#define  VF_NET_PAD_DFT_GPIO_SUS2  0
+#define  VF_NET_PAD_DFT_GPIO_SUS3  0
+#define  VF_NET_PAD_DFT_GPIO_SUS4  0
+#define  VF_NET_PAD_DFT_GPIO_SUS5  0
+#define  VF_NET_PAD_DFT_GPIO_SUS6  0
+#define  VF_NET_PAD_DFT_GPIO_SUS7  0
+#define  VF_NET_PAD_DFT_GPIO_SUS8  0
+#define  VF_NET_PAD_DFT_GPIO_SUS9  0
+#define  VF_NET_PAD_DFT_GPIO_SUS10  0
+#define  VF_NET_PAD_DFT_GPIO_SUS11  0
+#define  VF_NET_PAD_DFT_GPIO_SUS12  0
+#define  VF_NET_PAD_DFT_GPIO_SUS13  0
+#define  VF_NET_PAD_DFT_GPIO_SUS14  0
+#define  VF_NET_PAD_DFT_GPIO_SUS15  0
+#define  VF_NET_PAD_DFT_GPIO_SUS16  0
+
+
+//
+// Function Prototypes
+//
+EFI_STATUS
+PlatformPchInit (
+  IN SYSTEM_CONFIGURATION        *SystemConfiguration,
+  IN CONST EFI_PEI_SERVICES      **PeiServices,
+  IN UINT16                      PlatformType
+  );
+
+EFI_STATUS
+PlatformCpuInit (
+  IN CONST EFI_PEI_SERVICES            **PeiServices,
+  IN SYSTEM_CONFIGURATION        *SystemConfiguration,
+  IN EFI_PLATFORM_CPU_INFO       *PlatformCpuInfo
+  );
+
+EFI_STATUS
+PeimInitializeFlashMap (
+  IN EFI_FFS_FILE_HEADER        *FfsHeader,
+  IN CONST EFI_PEI_SERVICES           **PeiServices
+  );
+
+EFI_STATUS
+PeimInstallFlashMapPpi (
+  IN EFI_FFS_FILE_HEADER        *FfsHeader,
+  IN CONST EFI_PEI_SERVICES           **PeiServices
+  );
+
+EFI_STATUS
+EFIAPI
+IchReset (
+  IN CONST EFI_PEI_SERVICES           **PeiServices
+  )
+;
+
+BOOLEAN
+GetSleepTypeAfterWakeup (
+  IN  CONST EFI_PEI_SERVICES          **PeiServices,
+  OUT UINT16                    *SleepType
+  );
+
+EFI_STATUS
+EFIAPI
+GetWakeupEventAndSaveToHob (
+  IN CONST EFI_PEI_SERVICES   **PeiServices
+  )
+;
+
+EFI_STATUS
+EFIAPI
+MemoryDiscoveredPpiNotifyCallback (
+  IN CONST EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+  )
+;
+
+EFI_STATUS
+EFIAPI
+PeiGetVariable (
+  IN CONST EFI_PEI_SERVICES             **PeiServices,
+  IN CHAR16                       *VariableName,
+  IN EFI_GUID                     * VendorGuid,
+  OUT UINT32                      *Attributes OPTIONAL,
+  IN OUT UINTN                    *DataSize,
+  OUT VOID                        *Data
+  )
+;
+
+EFI_STATUS
+EFIAPI
+PeiGetNextVariableName (
+  IN CONST EFI_PEI_SERVICES             **PeiServices,
+  IN OUT UINTN                    *VariableNameSize,
+  IN OUT CHAR16                   *VariableName,
+  IN OUT EFI_GUID                 *VendorGuid
+  )
+;
+
+EFI_STATUS
+UpdateBootMode (
+  IN CONST EFI_PEI_SERVICES                       **PeiServices,
+  IN OUT EFI_PLATFORM_INFO_HOB                    *PlatformInfoHob
+  );
+
+EFI_STATUS
+EFIAPI
+EndOfPeiPpiNotifyCallback (
+  IN CONST EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+  );
+
+EFI_STATUS
+EFIAPI
+PeimInitializeRecovery (
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+;
+
+VOID
+CheckPowerOffNow (
+  VOID
+  );
+
+VOID
+IchGpioInit (
+  IN UINT16                     PlatformType,
+  IN SYSTEM_CONFIGURATION       *SystemConfiguration
+  );
+
+EFI_STATUS
+PcieSecondaryBusReset (
+  IN CONST EFI_PEI_SERVICES  **PeiServices,
+  IN UINT8             Bus,
+  IN UINT8             Dev,
+  IN UINT8             Fun
+  );
+
+VOID
+SetPlatformBootMode (
+  IN CONST EFI_PEI_SERVICES             **PeiServices,
+  IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
+  );
+
+BOOLEAN
+CheckIfJumperSetForRecovery(
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI    
+FindFv (
+  IN EFI_PEI_FIND_FV_PPI              *This,
+  IN CONST EFI_PEI_SERVICES             **PeiServices,
+  IN OUT UINT8                    *FvNumber,
+  OUT EFI_FIRMWARE_VOLUME_HEADER  **FVAddress
+  );
+
+BOOLEAN
+IsA16Inverted (
+  );
+
+EFI_STATUS
+EFIAPI
+CpuOnlyReset (
+  IN CONST EFI_PEI_SERVICES   **PeiServices
+  );
+
+EFI_STATUS
+EFIAPI
+InitLan (
+  IN CONST EFI_PEI_SERVICES          **PeiServices,
+  IN SYSTEM_CONFIGURATION      *Buffer
+  );
+
+EFI_STATUS
+EFIAPI
+Stall (
+  IN CONST EFI_PEI_SERVICES     **PeiServices,
+  IN CONST EFI_PEI_STALL_PPI    *This,
+  IN UINTN                      Microseconds
+  );
+
+EFI_STATUS
+MultiPlatformInfoInit (
+  IN CONST EFI_PEI_SERVICES          **PeiServices,
+  IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
+  );
+
+BOOLEAN
+IsRecoveryJumper (
+  IN CONST EFI_PEI_SERVICES    **PeiServices,
+    IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
+);
+
+EFI_STATUS
+CheckOsSelection (
+  IN CONST EFI_PEI_SERVICES          **PeiServices,
+  IN SYSTEM_CONFIGURATION            *SystemConfiguration
+  );
+
+EFI_STATUS
+PlatformInfoUpdate (
+  IN CONST EFI_PEI_SERVICES          **PeiServices,
+  IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob,
+  IN SYSTEM_CONFIGURATION      *SystemConfiguration
+  );
+
+VOID
+PlatformSsaInit (
+IN SYSTEM_CONFIGURATION        *SystemConfiguration,
+IN CONST EFI_PEI_SERVICES      **PeiServices
+  );
+
+EFI_STATUS
+InitializePlatform (
+  IN CONST EFI_PEI_SERVICES             **PeiServices,
+  IN EFI_PLATFORM_INFO_HOB        *PlatformInfoHob,
+  IN SYSTEM_CONFIGURATION         *SystemConfiguration
+);
+
+VOID
+MchInit (
+IN CONST EFI_PEI_SERVICES                     **PeiServices
+  );
+
+
+EFI_STATUS
+EFIAPI
+SetPeiCacheMode (
+  IN  CONST EFI_PEI_SERVICES    **PeiServices
+  );
+
+EFI_STATUS
+EFIAPI
+SetDxeCacheMode (
+  IN  CONST EFI_PEI_SERVICES    **PeiServices
+  );
+
+EFI_STATUS
+GPIO_initialization (
+  IN EFI_PEI_SERVICES                   **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR          *NotifyDescriptor,
+  IN VOID                               *SmbusPpi
+  );
+
+
+BOOLEAN
+IsRtcUipAlwaysSet (
+  IN CONST EFI_PEI_SERVICES       **PeiServices
+  );
+
+
+
+EFI_STATUS
+InitPchUsb (
+  IN CONST EFI_PEI_SERVICES  **PeiServices
+  );
+
+EFI_STATUS
+EFIAPI
+PublishMemoryTypeInfo (
+  void
+  );
+
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInfoInit.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInfoInit.c
new file mode 100644
index 0000000000..c6948d99d5
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInfoInit.c
@@ -0,0 +1,181 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  PlatformInfoInit.c
+
+Abstract:
+  Platform Info Driver.
+
+--*/
+
+#include "PlatformEarlyInit.h"
+
+#define LEN_64M       0x4000000
+
+//
+// Default PCI32 resource size
+//
+#define RES_MEM32_MIN_LEN   0x38000000
+
+#define RES_IO_BASE   0x0D00
+#define RES_IO_LIMIT  0xFFFF
+
+#define MemoryCeilingVariable   L"MemCeil."
+
+EFI_STATUS
+CheckOsSelection (
+  IN CONST EFI_PEI_SERVICES          **PeiServices,
+  IN SYSTEM_CONFIGURATION            *SystemConfiguration
+  )
+{
+  EFI_STATUS                   Status;
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI   *Variable;
+  UINTN                        VariableSize;
+  EFI_OS_SELECTION_HOB         *OsSelectionHob;
+  UINT8                        OsSelection;
+  UINT8                        *LpssDataHobPtr;
+  UINT8                        *LpssDataVarPtr;
+  UINTN                        i;
+
+  Status = (*PeiServices)->LocatePpi (
+                             PeiServices,
+                             &gEfiPeiReadOnlyVariable2PpiGuid,
+                             0,
+                             NULL,
+                                      (void **)&Variable
+                             );
+  if (!EFI_ERROR(Status)) {
+    VariableSize = sizeof (OsSelection);
+    Status = Variable->GetVariable (
+                         Variable,
+                         L"OsSelection",
+                         &gOsSelectionVariableGuid,
+                         NULL,
+                         &VariableSize,
+                         &OsSelection
+                         );
+
+    if (!EFI_ERROR(Status) && (SystemConfiguration->ReservedO != OsSelection)) {
+      //
+      // Build HOB for OsSelection
+      //
+      OsSelectionHob = BuildGuidHob (&gOsSelectionVariableGuid, sizeof (EFI_OS_SELECTION_HOB));
+      ASSERT (OsSelectionHob != NULL);
+
+      OsSelectionHob->OsSelectionChanged = TRUE;
+      OsSelectionHob->OsSelection        = OsSelection;
+      SystemConfiguration->ReservedO   = OsSelectionHob->OsSelection;
+
+      //
+      // Load LPSS and SCC default configurations
+      //
+      OsSelectionHob->LpssData.LpsseMMCEnabled            = FALSE;
+      OsSelectionHob->LpssData.LpssSdioEnabled            = TRUE;
+      OsSelectionHob->LpssData.LpssSdcardEnabled          = TRUE;
+      OsSelectionHob->LpssData.LpssSdCardSDR25Enabled     = FALSE;
+      OsSelectionHob->LpssData.LpssSdCardDDR50Enabled     = TRUE;
+      OsSelectionHob->LpssData.LpssMipiHsi                = FALSE;
+      OsSelectionHob->LpssData.LpsseMMC45Enabled          = TRUE;
+      OsSelectionHob->LpssData.LpsseMMC45DDR50Enabled     = TRUE;
+      OsSelectionHob->LpssData.LpsseMMC45HS200Enabled     = FALSE;
+      OsSelectionHob->LpssData.LpsseMMC45RetuneTimerValue = 8;
+      OsSelectionHob->LpssData.eMMCBootMode               = 1;     // Auto Detect
+
+
+      SystemConfiguration->Lpe       = OsSelectionHob->Lpe;
+      SystemConfiguration->PchAzalia = SystemConfiguration->PchAzalia;
+      LpssDataHobPtr = &OsSelectionHob->LpssData.LpssPciModeEnabled;
+      LpssDataVarPtr = &SystemConfiguration->LpssPciModeEnabled;
+
+      for (i = 0; i < sizeof(EFI_PLATFORM_LPSS_DATA); i++) {
+        *LpssDataVarPtr = *LpssDataHobPtr;
+        LpssDataVarPtr++;
+        LpssDataHobPtr++;
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+PlatformInfoUpdate (
+  IN CONST EFI_PEI_SERVICES          **PeiServices,
+  IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob,
+  IN SYSTEM_CONFIGURATION      *SystemConfiguration
+  )
+{
+  EFI_STATUS                   Status;
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI   *Variable;
+  UINTN                        VariableSize;
+  UINT32                       MemoryCeiling;
+
+  //
+  // Checking PCI32 resource from previous boot to determine the memory ceiling
+  //
+  Status = (*PeiServices)->LocatePpi (
+                             PeiServices,
+                             &gEfiPeiReadOnlyVariable2PpiGuid,
+                             0,
+                             NULL,
+                                      (void **)&Variable
+                             );
+  if (!EFI_ERROR(Status)) {
+    //
+    // Get the memory ceiling
+    //
+    VariableSize = sizeof(MemoryCeiling);
+    Status = Variable->GetVariable (
+                         Variable,
+                         MemoryCeilingVariable,
+                         &gEfiGlobalVariableGuid,
+                         NULL,
+                         &VariableSize,
+                         &MemoryCeiling
+                         );
+    if(!EFI_ERROR(Status)) {
+      //
+      // Set the new PCI32 resource Base if the variable available
+      //
+      PlatformInfoHob->PciData.PciResourceMem32Base = MemoryCeiling;
+      PlatformInfoHob->MemData.MemMaxTolm = MemoryCeiling;
+      PlatformInfoHob->MemData.MemTolm = MemoryCeiling;
+
+      //
+      // Platform PCI MMIO Size in unit of 1MB
+      //
+      PlatformInfoHob->MemData.MmioSize = 0x1000 - (UINT16)(PlatformInfoHob->MemData.MemMaxTolm >> 20);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Initialize the platform related info hob according to the
+  pre-determine value or setup option
+
+  @retval EFI_SUCCESS    Memory initialization completed successfully.
+  @retval Others         All other error conditions encountered result in an ASSERT.
+**/
+EFI_STATUS
+InitializePlatform (
+  IN CONST EFI_PEI_SERVICES       **PeiServices,
+  IN EFI_PLATFORM_INFO_HOB        *PlatformInfoHob,
+  IN SYSTEM_CONFIGURATION         *SystemConfiguration
+)
+{
+//
+// -- cchew10 need to update here.
+//
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInitPei.inf b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInitPei.inf
new file mode 100644
index 0000000000..54277b1e8b
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInitPei.inf
@@ -0,0 +1,117 @@
+#
+#
+# Copyright (c)  1999  - 2016, Intel Corporation. All rights reserved
+#                                                                                  
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#                                                                                  
+#
+#
+#  Module Name:
+#
+#    PlatformEarlyInit.inf
+#
+#  Abstract:
+#
+#    Component description file for PlatformEarlyInit module
+#
+#--*/
+
+[defines]
+INF_VERSION 				   = 0x00010005
+BASE_NAME					   = PlatformEarlyInit
+FILE_GUID					   = 0A5EA2E1-BE0B-44a0-A775-F429C9A018A0
+MODULE_TYPE 				   = PEIM
+VERSION_STRING				   = 1.0
+PI_SPECIFICATION_VERSION	   = 0x0001000A
+ENTRY_POINT 				   = PlatformEarlyInitEntry
+
+[sources.common]
+  BootMode.c
+  CpuInitPeim.c
+  PchInitPeim.c
+  MchInit.c
+  MemoryCallback.c
+  MemoryPeim.c
+  PlatformEarlyInit.c
+  PlatformEarlyInit.h
+  PlatformInfoInit.c
+  LegacySpeaker.c
+  LegacySpeaker.h
+  Stall.c
+  PlatformSsaInitPeim.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+  Vlv2SocBinPkg/Vlv2SocBinPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+
+[LibraryClasses]
+  PeimEntryPoint
+  DebugLib
+  HobLib
+  IoLib
+#  PeiKscLib
+  MultiPlatformLib
+  PcdLib
+  PchPlatformLib
+  MtrrLib
+
+[Ppis]
+  gEfiPeiStallPpiGuid
+  gPeiSpeakerInterfacePpiGuid
+  gEfiPeiMemoryDiscoveredPpiGuid
+  gVlvPolicyPpiGuid
+  gEfiPeiReadOnlyVariable2PpiGuid
+  gEfiPeiResetPpiGuid
+  gEfiEndOfPeiSignalPpiGuid
+  gPeiSmbusPolicyPpiGuid
+  gEfiFindFvPpiGuid
+  gPeiCapsulePpiGuid
+  gEfiPeiBootInRecoveryModePpiGuid
+  gEfiPeiRecoveryModulePpiGuid
+  gEfiPeiDeviceRecoveryModulePpiGuid
+  gPeiCachePpiGuid
+  gEfiPeiMasterBootModePpiGuid
+  gEfiPeiSmbusPpiGuid
+  gPchInitPpiGuid
+  gPchUsbPolicyPpiGuid
+
+[Guids]
+  gEfiSetupVariableGuid
+  gEfiPlatformInfoGuid
+  gEfiPlatformBootModeGuid
+  gEfiPlatformCpuInfoGuid
+  gEfiGlobalVariableGuid
+  gRecoveryOnFatFloppyDiskGuid
+  gRecoveryOnFatUsbDiskGuid
+  gRecoveryOnFatIdeDiskGuid
+  gRecoveryOnDataCdGuid
+  gMfgModeVariableGuid
+  gEfiNormalSetupGuid
+  gEfiMemoryTypeInformationGuid
+  gOsSelectionVariableGuid
+  gEfiSmmPeiSmramMemoryReserveGuid
+
+[Pcd.common]
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvMainBase
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvMainSize
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+  gEfiIchTokenSpaceGuid.PcdPeiIchEhciControllerMemoryBaseAddress
+
+  gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress
+  gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Base
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Size
+
+[Pcd]
+  gEfiVLVTokenSpaceGuid.PcdMeasuredBootEnable
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBootState
+
+[Depex]
+  gEfiPeiReadOnlyVariable2PpiGuid  AND gPeiCachePpiGuid
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformSsaInitPeim.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformSsaInitPeim.c
new file mode 100644
index 0000000000..4ffa3a20a2
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformSsaInitPeim.c
@@ -0,0 +1,58 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+  PlatformSsaInitPeim.c
+
+Abstract:
+
+
+--*/
+
+#include "PlatformEarlyInit.h"
+
+/**
+  Perform SSA related platform initialization.
+
+**/
+VOID
+PlatformSsaInit (
+  IN SYSTEM_CONFIGURATION        *SystemConfiguration,
+  IN CONST EFI_PEI_SERVICES          **PeiServices
+  )
+{
+
+  DEBUG ((EFI_D_ERROR, "PlatformSsaInit() - Start\n"));
+  DEBUG ((EFI_D_ERROR, "PlatformSsaInit() - SystemConfiguration->ISPDevSel 0x%x\n",SystemConfiguration->ISPDevSel));
+  if(SystemConfiguration->ISPDevSel == 0x02)
+  {
+    //
+    // Device 3 Interrupt Route
+    //
+    MmioWrite16 (
+      (ILB_BASE_ADDRESS + R_PCH_ILB_D3IR),
+      V_PCH_ILB_DXXIR_IAR_PIRQH   // For IUNIT
+    );
+    MmioRead16(ILB_BASE_ADDRESS + R_PCH_ILB_D3IR); // Read Posted Writes Register
+    DEBUG ((EFI_D_ERROR, "PlatformSsaInit() - Device 3 Interrupt Route Done\n"));
+  }
+
+  //
+  // Device 2 Interrupt Route
+  //
+  MmioWrite16 (
+    (ILB_BASE_ADDRESS + R_PCH_ILB_D2IR),
+    V_PCH_ILB_DXXIR_IAR_PIRQA   // For IGD
+  );
+  MmioRead16(ILB_BASE_ADDRESS + R_PCH_ILB_D2IR); // Read Posted Writes Register
+  DEBUG ((EFI_D_ERROR, "PlatformSsaInit() - Device 2 Interrupt Route Done\n"));
+
+  return;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Recovery.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Recovery.c
new file mode 100644
index 0000000000..53cd2c6c0c
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Recovery.c
@@ -0,0 +1,361 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+  Recovery.c
+
+Abstract:
+
+  Tiano PEIM to provide the platform recovery functionality.
+
+--*/
+
+#include "PlatformEarlyInit.h"
+
+#define PEI_FVMAIN_COMPACT_GUID \
+  {0x4A538818, 0x5AE0, 0x4eb2, 0xB2, 0xEB, 0x48, 0x8b, 0x23, 0x65, 0x70, 0x22};
+
+EFI_GUID FvMainCompactFileGuid = PEI_FVMAIN_COMPACT_GUID;
+
+//
+// Required Service
+//
+EFI_STATUS
+EFIAPI
+PlatformRecoveryModule (
+  IN CONST EFI_PEI_SERVICES                       **PeiServices,
+  IN EFI_PEI_RECOVERY_MODULE_PPI          *This
+  );
+
+//
+// Module globals
+//
+
+typedef struct {
+  EFI_GUID  CapsuleGuid;
+  UINT32    HeaderSize;
+  UINT32    Flags;
+  UINT32    CapsuleImageSize;
+  UINT32    SequenceNumber;
+  EFI_GUID  InstanceId;
+  UINT32    OffsetToSplitInformation;
+  UINT32    OffsetToCapsuleBody;
+  UINT32    OffsetToOemDefinedHeader;
+  UINT32    OffsetToAuthorInformation;
+  UINT32    OffsetToRevisionInformation;
+  UINT32    OffsetToShortDescription;
+  UINT32    OffsetToLongDescription;
+  UINT32    OffsetToApplicableDevices;
+} OLD_EFI_CAPSULE_HEADER;
+
+
+static EFI_PEI_RECOVERY_MODULE_PPI mRecoveryPpi = {
+  PlatformRecoveryModule
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mRecoveryPpiList = {
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEfiPeiRecoveryModulePpiGuid,
+  &mRecoveryPpi
+};
+
+/**
+  Provide the functionality of the Recovery Module.
+
+  @param PeiServices  General purpose services available to every PEIM.
+
+  @retval Status      EFI_SUCCESS if the interface could be successfully
+                      installed
+
+**/
+EFI_STATUS
+EFIAPI
+PeimInitializeRecovery (
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = (*PeiServices)->InstallPpi (
+                             PeiServices,
+                             &mRecoveryPpiList
+                             );
+
+  return Status;
+}
+
+/**
+  Provide the functionality of the Ea Recovery Module.
+
+  @param PeiServices         General purpose services available to every PEIM.
+  @param This                Pointer to PEI_RECOVERY_MODULE_INTERFACE.
+
+  @retval EFI_SUCCESS        If the interface could be successfully
+                             installed.
+  @retval EFI_UNSUPPORTED    Not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformRecoveryModule (
+  IN CONST EFI_PEI_SERVICES               **PeiServices,
+  IN EFI_PEI_RECOVERY_MODULE_PPI          *This
+  )
+{
+  EFI_STATUS                            Status;
+  EFI_PEI_DEVICE_RECOVERY_MODULE_PPI    *DeviceRecoveryModule;
+  UINTN                                 NumberOfImageProviders;
+  BOOLEAN                               ProviderAvailable;
+  UINTN                                 NumberRecoveryCapsules;
+  UINTN                                 RecoveryCapsuleSize;
+  EFI_GUID                              DeviceId;
+  BOOLEAN                               ImageFound;
+  EFI_PHYSICAL_ADDRESS                  Address;
+  VOID                                  *Buffer;
+  OLD_EFI_CAPSULE_HEADER                *CapsuleHeader;
+  EFI_PEI_HOB_POINTERS                  Hob;
+  EFI_PEI_HOB_POINTERS                  HobOld;
+  EFI_HOB_CAPSULE_VOLUME                *CapsuleHob;
+  BOOLEAN                               HobUpdate;
+  EFI_FIRMWARE_VOLUME_HEADER            *FvHeader;
+  UINTN                                 Index;
+  BOOLEAN                                FoundFvMain;
+  BOOLEAN                                FoundCapsule;
+  static EFI_GUID mEfiCapsuleHeaderGuid = EFI_CAPSULE_GUID;
+  EFI_PEI_STALL_PPI                      *StallPpi;
+
+  (*PeiServices)->ReportStatusCode (
+                    PeiServices,
+                    EFI_PROGRESS_CODE,
+                    EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEIM_PC_RECOVERY_BEGIN,
+                    0,
+                    NULL,
+                    NULL
+                    );
+
+  Status = (**PeiServices).LocatePpi (
+              PeiServices,
+              &gEfiPeiStallPpiGuid,
+              0,
+              NULL,
+              &StallPpi
+              );
+  ASSERT_EFI_ERROR (Status);
+
+  StallPpi->Stall(
+              PeiServices,
+              StallPpi,
+              5000000
+              );
+
+
+  Index = 0;
+
+  Status                  = EFI_SUCCESS;
+  HobUpdate               = FALSE;
+
+  ProviderAvailable       = TRUE;
+  ImageFound              = FALSE;
+  NumberOfImageProviders  = 0;
+
+  DeviceRecoveryModule    = NULL;
+
+  FoundCapsule = FALSE;
+  FoundFvMain = FALSE;
+
+  DEBUG ((EFI_D_ERROR | EFI_D_LOAD, "Recovery Entry\n"));
+
+  //
+  // Search the platform for some recovery capsule if the DXE IPL
+  // discovered a recovery condition and has requested a load.
+  //
+  while (ProviderAvailable == TRUE) {
+
+    Status = (*PeiServices)->LocatePpi (
+                               PeiServices,
+                               &gEfiPeiDeviceRecoveryModulePpiGuid,
+                               Index,
+                               NULL,
+                               &DeviceRecoveryModule
+                               );
+
+    if (!EFI_ERROR (Status)) {
+      DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Device Recovery PPI located\n"));
+      NumberOfImageProviders++;
+
+      Status = DeviceRecoveryModule->GetNumberRecoveryCapsules (
+                                       (EFI_PEI_SERVICES**)PeiServices,
+                                       DeviceRecoveryModule,
+                                       &NumberRecoveryCapsules
+                                       );
+
+      DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Number Of Recovery Capsules: %d\n", NumberRecoveryCapsules));
+
+      if (NumberRecoveryCapsules == 0) {
+        Index++;
+      } else {
+        break;
+      }
+    } else {
+      ProviderAvailable = FALSE;
+    }
+  }
+
+  //
+  // If there is an image provider, get the capsule ID
+  //
+  if (ProviderAvailable) {
+    RecoveryCapsuleSize = 0;
+
+    Status = DeviceRecoveryModule->GetRecoveryCapsuleInfo (
+                                    (EFI_PEI_SERVICES**)PeiServices,
+                                    DeviceRecoveryModule,
+                                    0,
+                                    &RecoveryCapsuleSize,
+                                    &DeviceId
+                                    );
+
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Recovery Capsule Size: %d\n", RecoveryCapsuleSize));
+
+    //
+    // Only support the 2 capsule types known
+    // Future enhancement is to rank-order the selection
+    //
+    if ((!CompareGuid (&DeviceId, &gRecoveryOnFatIdeDiskGuid)) &&
+        (!CompareGuid (&DeviceId, &gRecoveryOnFatFloppyDiskGuid)) &&
+        (!CompareGuid (&DeviceId, &gRecoveryOnDataCdGuid)) &&
+       (!CompareGuid (&DeviceId, &gRecoveryOnFatUsbDiskGuid))
+        ) {
+      return EFI_UNSUPPORTED;
+    }
+
+    Buffer  = NULL;
+    Status = (*PeiServices)->AllocatePages (
+                               PeiServices,
+                               EfiBootServicesCode,
+                               (RecoveryCapsuleSize - 1) / 0x1000 + 1,
+                               &Address
+                               );
+
+    DEBUG ((EFI_D_INFO | EFI_D_LOAD, "AllocatePage Returns: %r\n", Status));
+
+    if (EFI_ERROR(Status)) {
+      return Status;
+    }
+
+    Buffer = (UINT8 *) (UINTN) Address;
+
+    (*PeiServices)->ReportStatusCode (
+                      PeiServices,
+                      EFI_PROGRESS_CODE,
+                      EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEIM_PC_CAPSULE_LOAD,
+                      0,
+                      NULL,
+                      NULL
+                      );
+
+    Status = DeviceRecoveryModule->LoadRecoveryCapsule (
+                                     (EFI_PEI_SERVICES**)PeiServices,
+                                     DeviceRecoveryModule,
+                                     0,
+                                     Buffer
+                                     );
+
+    DEBUG ((EFI_D_INFO | EFI_D_LOAD, "LoadRecoveryCapsule Returns: %r\n", Status));
+
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    //
+    // Update FV Hob if found
+    //
+    Status = (*PeiServices)->GetHobList (PeiServices, &Hob.Raw);
+    HobOld.Raw  = Hob.Raw;
+    while (!END_OF_HOB_LIST (Hob)) {
+      if (Hob.Header->HobType == EFI_HOB_TYPE_FV) {
+        DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Hob FV Length: %x\n", Hob.FirmwareVolume->Length));
+        //
+        // BUGBUG Why is it a FV hob if it is greater than 0x50000?
+        //
+        if (Hob.FirmwareVolume->Length > 0x50000) {
+          HobUpdate = TRUE;
+          //
+          // This looks like the Hob we are interested in
+          //
+          DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Hob Updated\n"));
+          Hob.FirmwareVolume->BaseAddress = (UINTN) Buffer;
+          Hob.FirmwareVolume->Length      = RecoveryCapsuleSize;
+        }
+      }
+      Hob.Raw = GET_NEXT_HOB (Hob);
+    }
+
+    FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)Buffer;
+    CapsuleHeader = (OLD_EFI_CAPSULE_HEADER *)Buffer;
+
+    //
+    // Check if top of file is a capsule
+    //
+    if (CompareGuid ((EFI_GUID *)CapsuleHeader, &mEfiCapsuleHeaderGuid)) {
+      FoundCapsule = TRUE;
+    } else if (FvHeader->Signature == EFI_FVH_SIGNATURE) {
+    	//
+      // Assume the Firmware volume is a "FVMAIN" image
+      //
+      FoundFvMain = TRUE;
+    }
+
+    if (FoundFvMain) {
+      //
+      // build FV Hob if it is not built before
+      //
+      if (!HobUpdate) {
+        DEBUG ((EFI_D_INFO | EFI_D_LOAD, "FV Hob is not found, Build FV Hob then..\n"));
+
+       BuildFvHob (
+         (UINTN)FvHeader,
+         FvHeader->FvLength
+          );
+      }
+    }
+
+    if (FoundCapsule) {
+      //
+      // Build capsule hob
+      //
+      Status = (*PeiServices)->CreateHob (
+                                 PeiServices,
+                                 EFI_HOB_TYPE_CV,
+                                 sizeof (EFI_HOB_CAPSULE_VOLUME),
+                                 &CapsuleHob
+                                 );
+      if (EFI_ERROR (Status)) {
+        return Status;
+      }
+      CapsuleHob->BaseAddress = (UINT64)((UINTN)CapsuleHeader + (UINTN)CapsuleHeader->OffsetToCapsuleBody);
+      CapsuleHob->Length = (UINT64)((UINTN)CapsuleHeader->CapsuleImageSize -(UINTN)CapsuleHeader->OffsetToCapsuleBody);
+      (*PeiServices)->ReportStatusCode (
+                        PeiServices,
+                        EFI_PROGRESS_CODE,
+                        EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEIM_PC_CAPSULE_START,
+                        0,
+                        NULL,
+                        NULL
+                        );
+    }
+  }
+  DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Recovery Module Returning: %r\n", Status));
+  return Status;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Stall.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Stall.c
new file mode 100644
index 0000000000..d9c24c0194
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Stall.c
@@ -0,0 +1,91 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+
+Module Name:
+
+  Stall.c
+
+Abstract:
+
+  Produce Stall Ppi.
+
+--*/
+
+
+#include "PlatformEarlyInit.h"
+
+
+/**
+
+  Waits for at least the given number of microseconds.
+
+  @param PeiServices     General purpose services available to every PEIM.
+  @param This            PPI instance structure.
+  @param Microseconds    Desired length of time to wait.
+
+  @retval EFI_SUCCESS    If the desired amount of time was passed.
+
+*/
+EFI_STATUS
+EFIAPI
+Stall (
+  IN CONST EFI_PEI_SERVICES   **PeiServices,
+  IN CONST EFI_PEI_STALL_PPI      *This,
+  IN UINTN              Microseconds
+  )
+{
+  UINTN   Ticks;
+  UINTN   Counts;
+  UINT32  CurrentTick;
+  UINT32  OriginalTick;
+  UINT32  RemainingTick;
+
+  if (Microseconds == 0) {
+    return EFI_SUCCESS;
+  }
+
+  OriginalTick = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_TMR);
+  OriginalTick &= (V_PCH_ACPI_PM1_TMR_MAX_VAL - 1);
+  CurrentTick = OriginalTick;
+
+  //
+  // The timer frequency is 3.579545MHz, so 1 ms corresponds to 3.58 clocks
+  //
+  Ticks = Microseconds * 358 / 100 + OriginalTick + 1;
+
+  //
+  // The loops needed for timer overflow
+  //
+  Counts = (UINTN)RShiftU64((UINT64)Ticks, 24);
+
+  //
+  // Remaining clocks within one loop
+  //
+  RemainingTick = Ticks & 0xFFFFFF;
+
+  //
+  // Do not intend to use TMROF_STS bit of register PM1_STS, because this add extra
+  // one I/O operation, and may generate SMI
+  //
+  while (Counts != 0) {
+    CurrentTick = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_TMR) & B_PCH_ACPI_PM1_TMR_VAL;
+    if (CurrentTick <= OriginalTick) {
+      Counts--;
+    }
+    OriginalTick = CurrentTick;
+  }
+
+  while ((RemainingTick > CurrentTick) && (OriginalTick <= CurrentTick)) {
+    OriginalTick  = CurrentTick;
+    CurrentTick   = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_TMR) & B_PCH_ACPI_PM1_TMR_VAL;
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/BootMode.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/BootMode.c
new file mode 100644
index 0000000000..9fdcb620a3
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/BootMode.c
@@ -0,0 +1,346 @@
+/** @file
+
+  Copyright (c) 2004  - 2018, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+
+  BootMode.c
+
+Abstract:
+
+  EFI PEIM to provide the platform support functionality on the Thurley.
+
+
+--*/
+#include "CommonHeader.h"
+#include "Platform.h"
+#include "PlatformBaseAddresses.h"
+#include "PchAccess.h"
+#include "PlatformBootMode.h"
+#include <Guid/SetupVariable.h>
+
+//
+// Priority of our boot modes, highest priority first
+//
+EFI_BOOT_MODE mBootModePriority[] = {
+  BOOT_IN_RECOVERY_MODE,
+  BOOT_WITH_DEFAULT_SETTINGS,
+  BOOT_ON_FLASH_UPDATE,
+  BOOT_ON_S2_RESUME,
+  BOOT_ON_S3_RESUME,
+  BOOT_ON_S4_RESUME,
+  BOOT_WITH_MINIMAL_CONFIGURATION,
+  BOOT_ASSUMING_NO_CONFIGURATION_CHANGES,
+  BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS,
+  BOOT_WITH_FULL_CONFIGURATION,
+  BOOT_ON_S5_RESUME
+};
+
+EFI_PEI_NOTIFY_DESCRIPTOR mCapsuleNotifyList[1] = {
+  {
+    (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+    &gPeiCapsulePpiGuid,
+    CapsulePpiNotifyCallback
+  }
+};
+
+BOOLEAN
+GetSleepTypeAfterWakeup (
+  IN  CONST EFI_PEI_SERVICES          **PeiServices,
+  OUT UINT16                    *SleepType
+  );
+
+EFI_STATUS
+EFIAPI
+CapsulePpiNotifyCallback (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+  )
+{
+  EFI_STATUS      Status;
+  EFI_BOOT_MODE   BootMode;
+  PEI_CAPSULE_PPI *Capsule;
+
+  Status = (*PeiServices)->GetBootMode((const EFI_PEI_SERVICES **)PeiServices, &BootMode);
+  ASSERT_EFI_ERROR (Status);
+
+  if (BootMode == BOOT_ON_S3_RESUME) {
+    //
+    // Determine if we're in capsule update mode
+    //
+    Status = (*PeiServices)->LocatePpi ((const EFI_PEI_SERVICES **)PeiServices,
+                                        &gPeiCapsulePpiGuid,
+                                        0,
+                                        NULL,
+                                        (VOID **)&Capsule
+                                        );
+
+    if (Status == EFI_SUCCESS) {
+      if (Capsule->CheckCapsuleUpdate ((EFI_PEI_SERVICES**)PeiServices) == EFI_SUCCESS) {
+        BootMode = BOOT_ON_FLASH_UPDATE;
+        Status = (*PeiServices)->SetBootMode((const EFI_PEI_SERVICES **)PeiServices, BootMode);
+        ASSERT_EFI_ERROR (Status);
+      }
+    }
+  }
+
+  return Status;
+}
+
+#ifdef NOCS_S3_SUPPORT
+EFI_STATUS
+UpdateBootMode (
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  EFI_STATUS      Status;
+  EFI_BOOT_MODE   BootMode;
+  UINT16          SleepType;
+  CHAR16          *strBootMode;
+
+  Status = (*PeiServices)->GetBootMode(PeiServices, &BootMode);
+  ASSERT_EFI_ERROR (Status);
+  if (BootMode  == BOOT_IN_RECOVERY_MODE){
+    return Status;
+  }
+
+  //
+  // Let's assume things are OK if not told otherwise
+  //
+  BootMode = BOOT_WITH_FULL_CONFIGURATION;
+
+  if (GetSleepTypeAfterWakeup (PeiServices, &SleepType)) {
+    switch (SleepType) {
+      case V_PCH_ACPI_PM1_CNT_S3:
+        BootMode = BOOT_ON_S3_RESUME;
+        Status = (*PeiServices)->NotifyPpi (PeiServices, &mCapsuleNotifyList[0]);
+        ASSERT_EFI_ERROR (Status);
+        break;
+
+      case V_PCH_ACPI_PM1_CNT_S4:
+        BootMode = BOOT_ON_S4_RESUME;
+        break;
+
+      case V_PCH_ACPI_PM1_CNT_S5:
+        BootMode = BOOT_ON_S5_RESUME;
+        break;
+    } // switch (SleepType)
+  }
+
+  if (IsFastBootEnabled (PeiServices)) {
+    DEBUG ((EFI_D_INFO, "Prioritizing Boot mode to BOOT_WITH_MINIMAL_CONFIGURATION\n"));
+    PrioritizeBootMode (&BootMode, BOOT_WITH_MINIMAL_CONFIGURATION);
+  }
+
+  switch (BootMode) {
+    case BOOT_WITH_FULL_CONFIGURATION:
+      strBootMode = L"BOOT_WITH_FULL_CONFIGURATION";
+      break;
+    case BOOT_WITH_MINIMAL_CONFIGURATION:
+      strBootMode = L"BOOT_WITH_MINIMAL_CONFIGURATION";
+      break;
+    case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
+      strBootMode = L"BOOT_ASSUMING_NO_CONFIGURATION_CHANGES";
+      break;
+    case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:
+      strBootMode = L"BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS";
+      break;
+    case BOOT_WITH_DEFAULT_SETTINGS:
+      strBootMode = L"BOOT_WITH_DEFAULT_SETTINGS";
+      break;
+    case BOOT_ON_S4_RESUME:
+      strBootMode = L"BOOT_ON_S4_RESUME";
+      break;
+    case BOOT_ON_S5_RESUME:
+      strBootMode = L"BOOT_ON_S5_RESUME";
+      break;
+    case BOOT_ON_S2_RESUME:
+      strBootMode = L"BOOT_ON_S2_RESUME";
+      break;
+    case BOOT_ON_S3_RESUME:
+      strBootMode = L"BOOT_ON_S3_RESUME";
+
+      break;
+    case BOOT_ON_FLASH_UPDATE:
+      strBootMode = L"BOOT_ON_FLASH_UPDATE";
+      break;
+    case BOOT_IN_RECOVERY_MODE:
+      strBootMode = L"BOOT_IN_RECOVERY_MODE";
+      break;
+    default:
+      strBootMode = L"Unknown boot mode";
+  } // switch (BootMode)
+
+  DEBUG ((EFI_D_ERROR, "Setting BootMode to %s\n", strBootMode));
+  Status = (*PeiServices)->SetBootMode(PeiServices, BootMode);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+#endif
+
+/**
+  Get sleep type after wakeup
+
+  @param PeiServices       Pointer to the PEI Service Table.
+  @param SleepType         Sleep type to be returned.
+
+  @retval TRUE              A wake event occured without power failure.
+  @retval FALSE             Power failure occured or not a wakeup.
+
+**/
+BOOLEAN
+GetSleepTypeAfterWakeup (
+  IN  CONST EFI_PEI_SERVICES          **PeiServices,
+  OUT UINT16                    *SleepType
+  )
+{
+  UINT16  Pm1Sts;
+  UINT16  Pm1Cnt;
+  UINT16  GenPmCon1;
+  //
+  // VLV BIOS Specification 0.6.2 - Section 18.4, "Power Failure Consideration"
+  //
+  // When the SUS_PWR_FLR bit is set, it indicates the SUS well power is lost.
+  // This bit is in the SUS Well and defaults to 1’b1 based on RSMRST# assertion (not cleared by any type of reset).
+  // System BIOS should follow cold boot path if SUS_PWR_FLR (PBASE + 0x20[14]),
+  // GEN_RST_STS (PBASE + 0x20[9]) or PWRBTNOR_STS (ABASE + 0x00[11]) is set to 1’b1
+  // regardless of the value in the SLP_TYP (ABASE + 0x04[12:10]) field.
+  //
+  GenPmCon1 = MmioRead16 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1);
+
+  //
+  // Read the ACPI registers
+  //
+  Pm1Sts  = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS);
+  Pm1Cnt  = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT);
+
+  if ((GenPmCon1 & (B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR | B_PCH_PMC_GEN_PMCON_GEN_RST_STS)) ||
+     (Pm1Sts & B_PCH_ACPI_PM1_STS_PRBTNOR)) {
+	  //
+    // If power failure indicator, then don't attempt s3 resume.
+    // Clear PM1_CNT of S3 and set it to S5 as we just had a power failure, and memory has
+    // lost already.  This is to make sure no one will use PM1_CNT to check for S3 after
+    // power failure.
+	  //
+    if ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S3) {
+      Pm1Cnt = ((Pm1Cnt & ~B_PCH_ACPI_PM1_CNT_SLP_TYP) | V_PCH_ACPI_PM1_CNT_S5);
+      IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT, Pm1Cnt);
+    }
+	  //
+    // Clear Wake Status (WAK_STS)
+    //
+  }
+  //
+  // Get sleep type if a wake event occurred and there is no power failure
+  //
+  if ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S3) {
+    *SleepType = Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP;
+    return TRUE;
+  } else if ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S4) {
+    *SleepType = Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+BOOLEAN
+EFIAPI
+IsFastBootEnabled (
+  IN CONST EFI_PEI_SERVICES           **PeiServices
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI *PeiReadOnlyVarPpi;
+  UINTN                           VarSize;
+  SYSTEM_CONFIGURATION            SystemConfiguration;
+  BOOLEAN                         FastBootEnabledStatus;
+
+  FastBootEnabledStatus = FALSE;
+  Status = (**PeiServices).LocatePpi (
+                             PeiServices,
+                             &gEfiPeiReadOnlyVariable2PpiGuid,
+                             0,
+                             NULL,
+                             (void **)&PeiReadOnlyVarPpi
+                             );
+  if (Status == EFI_SUCCESS) {
+    VarSize = sizeof (SYSTEM_CONFIGURATION);
+    Status = PeiReadOnlyVarPpi->GetVariable (
+                                  PeiReadOnlyVarPpi,
+                                  PLATFORM_SETUP_VARIABLE_NAME,
+                                  &gEfiSetupVariableGuid,
+                                  NULL,
+                                  &VarSize,
+                                  &SystemConfiguration
+                                  );
+    if (Status == EFI_SUCCESS) {
+      if (SystemConfiguration.FastBoot != 0) {
+        FastBootEnabledStatus = TRUE;
+      }
+    }
+  }
+
+  return FastBootEnabledStatus;
+}
+
+/**
+  Given the current boot mode, and a proposed new boot mode, determine
+  which has priority. If the new boot mode has higher priority, then
+  make it the current boot mode.
+
+  @param CurrentBootMode    pointer to current planned boot mode
+  @param NewBootMode        proposed boot mode
+
+  @retval EFI_NOT_FOUND      if either boot mode is not recognized
+  @retval EFI_SUCCESS        if both boot mode values were recognized and
+                             were processed.
+**/
+EFI_STATUS
+PrioritizeBootMode (
+  IN OUT EFI_BOOT_MODE    *CurrentBootMode,
+  IN EFI_BOOT_MODE        NewBootMode
+  )
+{
+  UINT32 CurrentIndex;
+  UINT32 NewIndex;
+
+  //
+  // Find the position of the current boot mode in our priority array
+  //
+  for ( CurrentIndex = 0;
+        CurrentIndex < ARRAY_SIZE (mBootModePriority);
+        CurrentIndex++) {
+    if (mBootModePriority[CurrentIndex] == *CurrentBootMode) {
+      break;
+    }
+  }
+  if (CurrentIndex >= ARRAY_SIZE (mBootModePriority)) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Find the position of the new boot mode in our priority array
+  //
+  for ( NewIndex = 0;
+        NewIndex < ARRAY_SIZE (mBootModePriority);
+        NewIndex++) {
+    if (mBootModePriority[NewIndex] == NewBootMode) {
+      //
+      // If this new boot mode occurs before the current boot mode in the
+      // priority array, then take it.
+      //
+      if (NewIndex < CurrentIndex) {
+        *CurrentBootMode = NewBootMode;
+      }
+      return EFI_SUCCESS;
+    }
+  }
+  return EFI_NOT_FOUND;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/CommonHeader.h b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/CommonHeader.h
new file mode 100644
index 0000000000..283993b44c
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/CommonHeader.h
@@ -0,0 +1,60 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+**/
+
+#ifndef __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+
+
+#include <FrameworkPei.h>
+
+#include <IndustryStandard/SmBus.h>
+#include <IndustryStandard/Pci22.h>
+#include <Ppi/AtaController.h>
+#include <Guid/Capsule.h>
+#include <Ppi/Cache.h>
+#include <Ppi/MasterBootMode.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/RecoveryDevice.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Ppi/FvLoadFile.h>
+#include <Ppi/DeviceRecoveryModule.h>
+#include <Ppi/Capsule.h>
+#include <Ppi/Reset.h>
+#include <Ppi/Stall.h>
+#include <Ppi/BootInRecoveryMode.h>
+#include <Guid/FirmwareFileSystem2.h>
+#include <Ppi/MemoryDiscovered.h>
+#include <Ppi/RecoveryModule.h>
+#include <Ppi/Smbus2.h>
+#include <Ppi/FirmwareVolumeInfo.h>
+#include <Ppi/EndOfPeiPhase.h>
+#include <Library/DebugLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/PcdLib.h>
+#include <Library/SmbusLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PrintLib.h>
+#include <Library/ResetSystemLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/MtrrLib.h>
+
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/MemoryCallback.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/MemoryCallback.c
new file mode 100644
index 0000000000..7dcc2c3ce9
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/MemoryCallback.c
@@ -0,0 +1,154 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+  This file includes a memory call back function notified when MRC is done,
+  following action is performed in this file,
+    1. ICH initialization after MRC.
+    2. SIO initialization.
+    3. Install ResetSystem and FinvFv PPI.
+    4. Set MTRR for PEI
+    5. Create FV HOB and Flash HOB
+
+
+**/
+
+
+#include "CommonHeader.h"
+#include "Platform.h"
+#include <Ppi/Cache.h>
+#include <Library/BaseCryptLib.h>
+#include <Library/PciLib.h>
+#include "VlvAccess.h"
+
+
+EFI_PEI_PPI_DESCRIPTOR  mPpiListRecoveryBootMode[] = {
+{ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEfiPeiBootInRecoveryModePpiGuid,
+  NULL
+}
+};
+
+#if 0
+STATIC
+EFI_STATUS
+GetMemorySize (
+  IN  CONST EFI_PEI_SERVICES    **PeiServices,
+  OUT UINT64              *LowMemoryLength,
+  OUT UINT64              *HighMemoryLength
+  )
+{
+  EFI_STATUS              Status;
+  EFI_PEI_HOB_POINTERS    Hob;
+
+  *HighMemoryLength = 0;
+  *LowMemoryLength = 0x100000;
+  //
+  // Get the HOB list for processing
+  //
+  Status = (*PeiServices)->GetHobList (PeiServices, (void **)&Hob.Raw);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  //
+  // Collect memory ranges
+  //
+  while (!END_OF_HOB_LIST (Hob)) {
+    if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+      if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
+        //
+        // Need memory above 1MB to be collected here
+        //
+        if (Hob.ResourceDescriptor->PhysicalStart >= 0x100000 &&
+            Hob.ResourceDescriptor->PhysicalStart < (EFI_PHYSICAL_ADDRESS) 0x100000000) {
+          *LowMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);
+        } else if (Hob.ResourceDescriptor->PhysicalStart >= (EFI_PHYSICAL_ADDRESS) 0x100000000) {
+          *HighMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);
+        }
+      }
+    }
+    Hob.Raw = GET_NEXT_HOB (Hob);
+  }
+
+  return EFI_SUCCESS;
+}
+
+#endif
+/**
+  This function will be called when MRC is done.
+
+  @param  PeiServices General purpose services available to every PEIM.
+  @param  NotifyDescriptor Information about the notify event..
+  @param  Ppi The notify context.
+
+  @retval EFI_SUCCESS If the function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+MemoryDiscoveredPpiNotifyCallback (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+  )
+{
+
+  EFI_BOOT_MODE    BootMode;
+  UINT32           Pages;
+  VOID*            Memory;
+  UINTN            Size;
+
+  //
+  // Allocate LM memory and configure PDM if enabled by user.
+  // ConfigureLM(PeiServices);
+  //
+  (*PeiServices)->GetBootMode (
+                    (const EFI_PEI_SERVICES **)PeiServices,
+                    &BootMode
+                    );
+
+  if (BootMode != BOOT_ON_S3_RESUME) {
+    Size = (PcdGet32 (PcdFlashFvRecovery2Base) - PcdGet32 (PcdFlashFvMainBase)) + FixedPcdGet32(PcdFlashFvRecovery2Size);
+    Pages=  Size/0x1000;
+
+    Memory = AllocatePages ( Pages );
+    CopyMem(Memory , (VOID *) FixedPcdGet32(PcdFlashFvMainBase) , Size);
+
+    //
+    // We don't verify just load
+    //
+    PeiServicesInstallFvInfoPpi (
+      NULL,
+      (VOID *) ((UINTN) Memory + (PcdGet32 (PcdFlashFvRecovery2Base) - PcdGet32 (PcdFlashFvMainBase))),
+      PcdGet32 (PcdFlashFvRecovery2Size),
+      NULL,
+      NULL
+      );
+
+    PeiServicesInstallFvInfoPpi (
+      NULL,
+      (VOID *)  Memory,
+      PcdGet32 (PcdFlashFvMainSize),
+      NULL,
+      NULL
+      );
+
+  }
+
+  if (BootMode == BOOT_ON_S3_RESUME) {
+    PeiServicesInstallFvInfoPpi (
+    NULL,
+    (VOID *) (UINTN) (PcdGet32 (PcdFlashFvRecovery2Base)),
+    PcdGet32 (PcdFlashFvRecovery2Size),
+    NULL,
+    NULL
+    );
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.c
new file mode 100644
index 0000000000..eba1dfff30
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.c
@@ -0,0 +1,1198 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+**/
+
+#include "CommonHeader.h"
+
+#include "Platform.h"
+#include <Library/PciCf8Lib.h>
+#include "PlatformBaseAddresses.h"
+#include "PchAccess.h"
+#include <Guid/PlatformInfo.h>
+#include "PchCommonDefinitions.h"
+#include <Ppi/MfgMemoryTest.h>
+#include <Guid/SetupVariable.h>
+#include <Guid/Vlv2Variable.h>
+#include <Ppi/fTPMPolicy.h>
+
+//
+// Start::Alpine Valley platform
+//
+enum {
+  SMBUS_READ_BYTE,
+  SMBUS_WRITE_BYTE,
+  SMBUS_READ_BLOCK,
+  SMBUS_WRITE_BLOCK
+};
+
+#define EC_BASE           0xE0000000
+
+//
+// DEVICE 0 (Memroy Controller Hub)
+//
+#define MC_BUS              0x00
+#define MC_DEV              0x00
+#define MC_FUN              0x00
+#define MC_DEV_FUN          (MC_DEV << 3)
+#define MC_BUS_DEV_FUN      ((MC_BUS << 8) + MC_DEV_FUN)
+
+//
+// SysCtl SMBus address and block size
+//
+#define AV_SC_SMBUS_ADDRESS        	0x60
+#define AV_SC_BYTE_LEN            	1
+#define AV_SC_BLOCK_LEN            	4
+#define AV_SC_SMBUS_WRCMD           1
+#define AV_SC_SMBUS_RDCMD           0
+
+//
+// SysCtl registers offset
+//
+#define AV_SC_REG_PLATFORM_ID               24  // 0x18
+#define AV_SC_REG_BOARD_ID                  28  // 0x1C
+#define AV_SC_REG_FAB_ID                    32  // 0x20
+#define AV_SC_REG_ECO_ID                    68  // 0x44
+#define AV_SC_REG_DDR_DAUGHTER_CARD_ID      144 // 0x90
+#define AV_SC_REG_SODIMM_CONFIG             36
+
+//
+// ID values
+//
+#define AV_SC_PLATFORM_ID_TABLET   0
+#define AV_SC_PLATFORM_ID_NETBOOK  2
+#define AV_SC_PLATFORM_ID_INTERPOSER 3 // Configuration TBD
+#define AV_SC_BOARD_ID_AV_SVP      1492
+
+#define BUS_TRIES                 3       // How many times to retry on Bus Errors
+
+#define GTT_SIZE_1MB        1
+#define GTT_SIZE_2MB        2
+
+#define PciCfg16Read( PciExpressBase, Bus, Device, Function, Register ) \
+  MmioRead16(PciExpressBase + \
+    (UINTN)(Bus << 20) + \
+    (UINTN)(Device << 15) + \
+    (UINTN)(Function << 12) + \
+    (UINTN)(Register))
+#define PciCfg16Write( PciExpressBase, Bus, Device, Function, Register, Data ) \
+    MmioWrite16(PciExpressBase + \
+      (UINTN)(Bus << 20) + \
+      (UINTN)(Device << 15) + \
+      (UINTN)(Function << 12) + \
+      (UINTN)(Register), \
+      (UINT16)Data)
+
+
+//
+//Memory Test Manufacturing mode
+//
+UINT32 DataPatternForMemoryTest[] = {
+    0x55555555, 0xAAAAAAAA, 0x55555510, 0x555555EF, 0x55555510, 0x555555EF, 0x55555510, 0x555555EF,
+    0x55555555, 0xAAAAAAAA, 0x55551055, 0x5555EF55, 0x55551055, 0x5555EF55, 0x55551055, 0x5555EF55,
+    0x55555555, 0xAAAAAAAA, 0x55105555, 0x55EF5555, 0x55105555, 0x55EF5555, 0x55105555, 0x55EF5555,
+    0x55555555, 0xAAAAAAAA, 0x10555555, 0xEF555555, 0x10555555, 0xEF555555, 0x10555555, 0xEF555555
+};
+#define DATA_PATTERN_ARRAY_SIZE (sizeof(DataPatternForMemoryTest) / sizeof(UINT32))
+
+//
+//Memory Test Manufacturing mode
+//
+//
+// The global indicator, the FvFileLoader callback will modify it to TRUE after loading PEIM into memory
+//
+BOOLEAN ImageInMemory = FALSE;
+
+EFI_STATUS
+EFIAPI
+Stall (
+  IN CONST EFI_PEI_SERVICES   **PeiServices,
+  IN CONST EFI_PEI_STALL_PPI      *This,
+  IN UINTN              Microseconds
+  );
+
+EFI_STATUS
+EFIAPI
+MfgMemoryTest (
+  IN  CONST EFI_PEI_SERVICES                   **PeiServices,
+  IN  PEI_MFG_MEMORY_TEST_PPI           *This,
+  IN  UINT32                             BeginAddress,
+  IN  UINT32                             MemoryLength
+  );
+
+static EFI_PEI_STALL_PPI  mStallPpi = {
+  PEI_STALL_RESOLUTION,
+  Stall
+};
+
+static PEI_MFG_MEMORY_TEST_PPI mPeiMfgMemoryTestPpi = {
+  MfgMemoryTest
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mInstallStallPpi[] = {
+  {
+  EFI_PEI_PPI_DESCRIPTOR_PPI,
+  &gEfiPeiStallPpiGuid,
+  &mStallPpi
+  },
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+    &gPeiMfgMemoryTestPpiGuid,
+    &mPeiMfgMemoryTestPpi
+  }
+ };
+
+EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList[1] = {
+  {
+    (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+    &gEfiPeiMemoryDiscoveredPpiGuid,
+    MemoryDiscoveredPpiNotifyCallback
+  }
+};
+
+EFI_STATUS
+EFIAPI
+InstallMonoStatusCode (
+  IN EFI_FFS_FILE_HEADER       *FfsHeader,
+  IN CONST EFI_PEI_SERVICES          **PeiServices
+  );
+
+
+EFI_STATUS
+ReadPlatformIds (
+  IN CONST EFI_PEI_SERVICES             **PeiServices,
+  IN OUT EFI_PLATFORM_INFO_HOB          *PlatformInfoHob
+  );
+
+//
+// Start::Alpine Valley platform
+//
+EFI_STATUS
+PeiSmbusExec (
+  UINT16 SmbusBase,
+  UINT8 SlvAddr,
+  UINT8 Operation,
+  UINT8 Offset,
+  UINT8 *Length,
+  UINT8 *Buffer
+  );
+
+
+/**
+
+  Detemine Turbot board 
+  @return 0: Not Turbot board
+          1: Turbot board 
+
+**/
+UINT32 
+DetermineTurbotBoard (
+  void
+  )
+{
+  UINTN PciD31F0RegBase = 0;
+  UINT32 GpioValue = 0;
+  UINT32 TmpVal = 0;
+  UINT32 MmioConf0 = 0;
+  UINT32 MmioPadval = 0;
+  UINT32 PConf0Offset = 0x200; //GPIO_S5_4 pad_conf0 register offset
+  UINT32 PValueOffset = 0x208; //GPIO_S5_4 pad_value register offset
+  UINT32 SSUSOffset = 0x2000;
+  UINT32 IoBase = 0;
+
+  DEBUG ((EFI_D_ERROR, "DetermineTurbotBoard() Entry\n"));
+  PciD31F0RegBase = MmPciAddress (0,
+                      0,
+                      PCI_DEVICE_NUMBER_PCH_LPC,
+                      PCI_FUNCTION_NUMBER_PCH_LPC,
+                      0
+                    );
+  IoBase = MmioRead32 (PciD31F0RegBase + R_PCH_LPC_IO_BASE) & B_PCH_LPC_IO_BASE_BAR;
+  
+  MmioConf0 = IoBase + SSUSOffset + PConf0Offset;
+  MmioPadval = IoBase + SSUSOffset + PValueOffset;
+  //0xFED0E200/0xFED0E208 is pad_Conf/pad_val register address of GPIO_S5_4
+  DEBUG ((EFI_D_ERROR, "MmioConf0[0x%x], MmioPadval[0x%x]\n", MmioConf0, MmioPadval));
+  
+  MmioWrite32 (MmioConf0, 0x2003CC00);  
+
+  TmpVal = MmioRead32 (MmioPadval);
+  TmpVal &= ~0x6; //Clear bit 1:2
+  TmpVal |= 0x2; // Set the pin as GPI
+  MmioWrite32 (MmioPadval, TmpVal); 
+
+  GpioValue = MmioRead32 (MmioPadval);
+
+  DEBUG ((EFI_D_ERROR, "Gpio_S5_4 value is 0x%x\n", GpioValue));
+  return (GpioValue & 0x1);
+}
+
+
+
+EFI_STATUS
+FtpmPolicyInit (
+  IN CONST EFI_PEI_SERVICES             **PeiServices,
+  IN SYSTEM_CONFIGURATION         *pSystemConfiguration
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_PEI_PPI_DESCRIPTOR          *mFtpmPolicyPpiDesc;
+  SEC_FTPM_POLICY_PPI             *mFtpmPolicyPpi;
+
+
+  DEBUG((EFI_D_INFO, "FtpmPolicyInit Entry \n"));
+
+  if (NULL == PeiServices ||  NULL == pSystemConfiguration) {
+    DEBUG((EFI_D_ERROR, "Input error. \n"));
+    return EFI_INVALID_PARAMETER;
+  }
+  
+  Status = (*PeiServices)->AllocatePool(
+                             PeiServices,
+                             sizeof (EFI_PEI_PPI_DESCRIPTOR),
+                             (void **)&mFtpmPolicyPpiDesc
+                             );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = (*PeiServices)->AllocatePool(
+                             PeiServices,
+                             sizeof (SEC_FTPM_POLICY_PPI),
+                             (void **)&mFtpmPolicyPpi
+                             );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Initialize PPI
+  //
+  (*PeiServices)->SetMem ((VOID *)mFtpmPolicyPpi, sizeof (SEC_FTPM_POLICY_PPI), 0);
+  mFtpmPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+  mFtpmPolicyPpiDesc->Guid = &gSeCfTPMPolicyPpiGuid;
+  mFtpmPolicyPpiDesc->Ppi = mFtpmPolicyPpi;
+
+
+  DEBUG((EFI_D_INFO, "pSystemConfiguration->fTPM = 0x%x \n", pSystemConfiguration->fTPM)); 
+  if(pSystemConfiguration->fTPM == 1) {
+    mFtpmPolicyPpi->fTPMEnable = TRUE;
+  } else {
+    mFtpmPolicyPpi->fTPMEnable = FALSE;
+  }
+
+  Status = (*PeiServices)->InstallPpi(
+                             PeiServices,
+                             mFtpmPolicyPpiDesc
+                             );
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG((EFI_D_INFO, "FtpmPolicyInit done \n"));
+  
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This routine attempts to acquire the SMBus
+
+  @retval FAILURE as failed
+  @retval SUCCESS as passed
+
+**/
+EFI_STATUS
+AcquireBus (
+    UINT16	SmbusBase
+  )
+{
+  UINT8 StsReg;
+
+  StsReg  = 0;
+  StsReg  = (UINT8)IoRead8(SmbusBase + R_PCH_SMBUS_HSTS);
+  if (StsReg & B_PCH_SMBUS_IUS) {
+    return EFI_DEVICE_ERROR;
+  } else if (StsReg & B_PCH_SMBUS_HBSY) {
+    //
+    // Clear Status Register and exit
+    //
+    // Wait for HSTS.HBSY to be clear
+	  //
+    do { StsReg = (UINT8) IoRead8(SmbusBase+R_PCH_SMBUS_HSTS); } while ((StsReg & B_PCH_SMBUS_HBSY) != 0);
+
+	  //
+    // Clear all status bits
+	  //
+    IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, 0xFE);
+    return EFI_SUCCESS;
+  } else {
+    //
+    // Clear out any odd status information (Will Not Clear In Use)
+    //
+    IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, StsReg);
+    return EFI_SUCCESS;
+  }
+}
+//
+// End::Alpine Valley platform
+//
+
+/**
+  This function checks the memory range in PEI.
+
+  @param  PeiServices     Pointer to PEI Services.
+  @param  This            Pei memory test PPI pointer.
+  @param  BeginAddress    Beginning of the memory address to be checked.
+  @param  MemoryLength    Bytes of memory range to be checked.
+  @param  Operation       Type of memory check operation to be performed.
+  @param  ErrorAddress    Return the address of the error memory address.
+
+  @retval  EFI_SUCCESS         The operation completed successfully.
+  @retval  EFI_DEVICE_ERROR    Memory test failed. It's not safe to use this range of memory.
+
+**/
+EFI_STATUS
+EFIAPI
+MfgMemoryTest (
+  IN  CONST EFI_PEI_SERVICES                   **PeiServices,
+  IN  PEI_MFG_MEMORY_TEST_PPI           *This,
+  IN  UINT32                             BeginAddress,
+  IN  UINT32                             MemoryLength
+  )
+{
+  UINT32 i;
+  UINT32 memAddr;
+  UINT32 readData;
+  UINT32 xorData;
+  UINT32 TestFlag = 0;
+  memAddr = BeginAddress;
+
+  //
+  //Output Message for MFG
+  //
+  DEBUG ((EFI_D_ERROR, "MFGMODE SET\n"));
+
+  //
+  //Writting the pattern in defined location.
+  //
+  while (memAddr < (BeginAddress+MemoryLength)) {
+    for (i = 0; i < DATA_PATTERN_ARRAY_SIZE; i++) {
+      if (memAddr > (BeginAddress+MemoryLength -4)) {
+        memAddr = memAddr + 4;
+        break;
+      }
+      *((volatile UINT32*) memAddr) = DataPatternForMemoryTest[i];
+      memAddr = memAddr + 4;
+    }
+  }
+
+  //
+  //Verify the pattern.
+  //
+  memAddr = BeginAddress;
+  while (memAddr < (BeginAddress+MemoryLength)) {
+  for (i = 0; i < DATA_PATTERN_ARRAY_SIZE; i++) {
+    if (memAddr > (BeginAddress+MemoryLength -4)) {
+      memAddr = memAddr + 4;
+      break;
+    }
+    readData = *((volatile UINT32*) memAddr);
+    xorData = readData ^ DataPatternForMemoryTest[i];
+
+	  //
+    // If xorData is nonzero, this particular memAddr has a failure.
+	  //
+    if (xorData != 0x00000000) {
+      DEBUG ((EFI_D_ERROR, "Expected value....: %x\n", DataPatternForMemoryTest[i]));
+      DEBUG ((EFI_D_ERROR, "ReadData value....: %x\n", readData));
+      DEBUG ((EFI_D_ERROR, "Pattern failure at....: %x\n", memAddr));
+      TestFlag = 1;
+    }
+    memAddr = memAddr + 4;
+    }
+  }
+  if (TestFlag) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  //Output Message for MFG
+  //
+  DEBUG ((EFI_D_ERROR, "MFGMODE MEMORY TEST PASSED\n"));
+  return EFI_SUCCESS;
+}
+
+BOOLEAN
+IsRtcUipAlwaysSet (
+  IN CONST EFI_PEI_SERVICES       **PeiServices
+  )
+{
+
+  EFI_PEI_STALL_PPI *StallPpi;
+  UINTN             Count;
+
+  (**PeiServices).LocatePpi (PeiServices, &gEfiPeiStallPpiGuid, 0, NULL, (void **)&StallPpi);
+
+  for (Count = 0; Count < 500; Count++) { // Maximum waiting approximates to 1.5 seconds (= 3 msec * 500)
+    IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA);
+    if ((IoRead8 (R_PCH_RTC_TARGET2) & B_PCH_RTC_REGISTERA_UIP) == 0) {
+      return FALSE;
+    }
+
+    StallPpi->Stall (PeiServices, StallPpi, 3000);
+  }
+
+  return TRUE;
+}
+
+EFI_STATUS
+RtcPowerFailureHandler (
+  IN CONST EFI_PEI_SERVICES       **PeiServices
+  )
+{
+
+  UINT16          DataUint16;
+  UINT8           DataUint8;
+  BOOLEAN         RtcUipIsAlwaysSet;
+  DataUint16        = MmioRead16 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1);
+  RtcUipIsAlwaysSet = IsRtcUipAlwaysSet (PeiServices);
+  if ((DataUint16 & B_PCH_PMC_GEN_PMCON_RTC_PWR_STS) || (RtcUipIsAlwaysSet)) {
+    //
+    // Execute the sequence below. This will ensure that the RTC state machine has been initialized.
+    //
+    // Step 1.
+    // BIOS clears this bit by writing a '0' to it.
+    //
+    if (DataUint16 & B_PCH_PMC_GEN_PMCON_RTC_PWR_STS) {
+      //
+      // Set to invalid date in order to reset the time to
+      // BIOS build time later in the boot (SBRUN.c file).
+      //
+      IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_YEAR);
+      IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);
+      IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_MONTH);
+      IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);
+      IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_DAYOFMONTH);
+      IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);
+      IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_DAYOFWEEK);
+      IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);
+
+      IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_SECONDSALARM);
+      IoWrite8 (R_PCH_RTC_TARGET2, 0x00);
+      IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_MINUTESALARM);
+      IoWrite8 (R_PCH_RTC_TARGET2, 0x00);
+      IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_HOURSALARM);
+      IoWrite8 (R_PCH_RTC_TARGET2, 0x00);
+    }
+
+    //
+    // Step 2.
+    // Set RTC Register 0Ah[6:4] to '110' or '111'.
+    //
+    IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA);
+    IoWrite8 (R_PCH_RTC_TARGET2, (V_PCH_RTC_REGISTERA_DV_DIV_RST1 | V_PCH_RTC_REGISTERA_RS_976P5US));
+
+    //
+    // Step 3.
+    // Set RTC Register 0Bh[7].
+    //
+    IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
+    DataUint8 = (IoRead8 (R_PCH_RTC_TARGET2) | B_PCH_RTC_REGISTERB_SET);
+    IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
+    IoWrite8 (R_PCH_RTC_TARGET2, DataUint8);
+
+    //
+    // Step 4.
+    // Set RTC Register 0Ah[6:4] to '010'.
+    //
+    IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA);
+    IoWrite8 (R_PCH_RTC_TARGET2, (V_PCH_RTC_REGISTERA_DV_NORM_OP | V_PCH_RTC_REGISTERA_RS_976P5US));
+
+    //
+    // Step 5.
+    // Clear RTC Register 0Bh[7].
+    //
+    IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
+    DataUint8 = (IoRead8 (R_PCH_RTC_TARGET2) & (UINT8)~B_PCH_RTC_REGISTERB_SET);
+    IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
+    IoWrite8 (R_PCH_RTC_TARGET2, DataUint8);
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+VOID
+PchBaseInit (
+  VOID
+  )
+{
+  //
+  // Program ACPI Power Management I/O Space Base Address
+  //
+  MmioWrite16 (
+    MmPciAddress (0,
+      DEFAULT_PCI_BUS_NUMBER_PCH,
+      PCI_DEVICE_NUMBER_PCH_LPC,
+      PCI_FUNCTION_NUMBER_PCH_LPC,
+      R_PCH_LPC_ACPI_BASE
+    ),
+    (UINT16)((ACPI_BASE_ADDRESS & B_PCH_LPC_ACPI_BASE_BAR) | B_PCH_LPC_ACPI_BASE_EN)
+  );
+
+  //
+  // Program GPIO Base Address
+  //
+  MmioWrite16 (
+    MmPciAddress (0,
+      DEFAULT_PCI_BUS_NUMBER_PCH,
+      PCI_DEVICE_NUMBER_PCH_LPC,
+      PCI_FUNCTION_NUMBER_PCH_LPC,
+      R_PCH_LPC_GPIO_BASE
+    ),
+    (UINT16)((GPIO_BASE_ADDRESS & B_PCH_LPC_GPIO_BASE_BAR) | B_PCH_LPC_GPIO_BASE_EN)
+  );
+
+  //
+  // Set PMC Base Address
+  //
+  MmioWrite32 (
+    MmPciAddress (0,
+      DEFAULT_PCI_BUS_NUMBER_PCH,
+      PCI_DEVICE_NUMBER_PCH_LPC,
+      PCI_FUNCTION_NUMBER_PCH_LPC,
+      R_PCH_LPC_PMC_BASE
+    ),
+    (UINT32)((PMC_BASE_ADDRESS & B_PCH_LPC_PMC_BASE_BAR) | B_PCH_LPC_PMC_BASE_EN)
+  );
+
+  //
+  // Set IO Base Address
+  //
+  MmioWrite32 (
+    MmPciAddress (0,
+      DEFAULT_PCI_BUS_NUMBER_PCH,
+      PCI_DEVICE_NUMBER_PCH_LPC,
+      PCI_FUNCTION_NUMBER_PCH_LPC,
+      R_PCH_LPC_IO_BASE
+    ),
+    (UINT32)((IO_BASE_ADDRESS & B_PCH_LPC_IO_BASE_BAR) | B_PCH_LPC_IO_BASE_EN)
+  );
+
+  //
+  // Set ILB Base Address
+  //
+  MmioWrite32 (
+    MmPciAddress (0,
+      DEFAULT_PCI_BUS_NUMBER_PCH,
+      PCI_DEVICE_NUMBER_PCH_LPC,
+      PCI_FUNCTION_NUMBER_PCH_LPC,
+      R_PCH_LPC_ILB_BASE
+    ),
+    (UINT32)((ILB_BASE_ADDRESS & B_PCH_LPC_ILB_BASE_BAR) | B_PCH_LPC_ILB_BASE_EN)
+  );
+
+  //
+  // Set PUnit Base Address
+  //
+  MmioWrite32 (
+    MmPciAddress (0,
+      DEFAULT_PCI_BUS_NUMBER_PCH,
+      PCI_DEVICE_NUMBER_PCH_LPC,
+      PCI_FUNCTION_NUMBER_PCH_LPC,
+      R_PCH_LPC_PUNIT_BASE
+    ),
+    (UINT32)((PUNIT_BASE_ADDRESS & B_PCH_LPC_PUNIT_BASE_BAR) | B_PCH_LPC_PUNIT_BASE_EN)
+  );
+
+  //
+  // Set SPI Base Address
+  //
+  MmioWrite32 (
+    MmPciAddress (0,
+      DEFAULT_PCI_BUS_NUMBER_PCH,
+      PCI_DEVICE_NUMBER_PCH_LPC,
+      PCI_FUNCTION_NUMBER_PCH_LPC,
+      R_PCH_LPC_SPI_BASE
+    ),
+    (UINT32)((SPI_BASE_ADDRESS & B_PCH_LPC_SPI_BASE_BAR) | B_PCH_LPC_SPI_BASE_EN)
+  );
+
+  //
+  // Set Root Complex Base Address
+  //
+  MmioWrite32 (
+    MmPciAddress (0,
+      DEFAULT_PCI_BUS_NUMBER_PCH,
+      PCI_DEVICE_NUMBER_PCH_LPC,
+      PCI_FUNCTION_NUMBER_PCH_LPC,
+      R_PCH_LPC_RCBA
+    ),
+    (UINT32)((RCBA_BASE_ADDRESS & B_PCH_LPC_RCBA_BAR) | B_PCH_LPC_RCBA_EN)
+  );
+
+  //
+  // Set MPHY Base Address
+  //
+  MmioWrite32 (
+    MmPciAddress (0,
+      DEFAULT_PCI_BUS_NUMBER_PCH,
+      PCI_DEVICE_NUMBER_PCH_LPC,
+      PCI_FUNCTION_NUMBER_PCH_LPC,
+      R_PCH_LPC_MPHY_BASE
+    ),
+    (UINT32)((MPHY_BASE_ADDRESS & B_PCH_LPC_MPHY_BASE_BAR) | B_PCH_LPC_MPHY_BASE_EN)
+  );
+  MmioWrite16 (
+    MmPciAddress (0,
+      DEFAULT_PCI_BUS_NUMBER_PCH,
+      PCI_DEVICE_NUMBER_PCH_SMBUS,
+      PCI_FUNCTION_NUMBER_PCH_SMBUS,
+      R_PCH_SMBUS_BASE
+    ),
+    (UINT16)(SMBUS_BASE_ADDRESS & B_PCH_SMBUS_BASE_BAR)
+  );
+
+  MmioOr8 (
+    MmPciAddress (0,
+      DEFAULT_PCI_BUS_NUMBER_PCH,
+      PCI_DEVICE_NUMBER_PCH_SMBUS,
+      PCI_FUNCTION_NUMBER_PCH_SMBUS,
+      R_PCH_SMBUS_PCICMD
+    ),
+    B_PCH_SMBUS_PCICMD_IOSE
+  );
+
+}
+
+/**
+  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
+PeiInitPlatform (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  UINTN                            SmbusRegBase;
+  EFI_PLATFORM_INFO_HOB            PlatformInfo;
+  EFI_STATUS                       Status= EFI_SUCCESS;
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI  *Variable = NULL;
+  UINTN                            VariableSize;
+  SYSTEM_CONFIGURATION             SystemConfiguration;
+  UINT32                           GGC = 0;
+
+  EFI_PEI_PPI_DESCRIPTOR          *mVlvMmioPolicyPpiDesc;
+  VLV_MMIO_POLICY_PPI             *mVlvMmioPolicyPpi;
+
+  ZeroMem (&PlatformInfo, sizeof(PlatformInfo));
+
+  Status =  InstallMonoStatusCode(FileHandle, PeiServices);
+  ASSERT_EFI_ERROR (Status);
+
+
+  //
+  // Initialize Stall PPIs
+  //
+  Status = (*PeiServices)->InstallPpi (PeiServices, &mInstallStallPpi[0]);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = (*PeiServices)->NotifyPpi (PeiServices, &mMemoryDiscoveredNotifyList[0]);
+  ASSERT_EFI_ERROR (Status);
+  SmbusRegBase = PchPciDeviceMmBase (
+                   DEFAULT_PCI_BUS_NUMBER_PCH,
+                   PCI_DEVICE_NUMBER_PCH_SMBUS,
+                   PCI_FUNCTION_NUMBER_PCH_SMBUS
+                   );
+  //
+  // Since PEI has no PCI enumerator, set the BAR & I/O space enable ourselves
+  //
+  MmioAndThenOr32 (SmbusRegBase + R_PCH_SMBUS_BASE, B_PCH_SMBUS_BASE_BAR, SMBUS_BASE_ADDRESS);
+
+  MmioOr8 (SmbusRegBase + R_PCH_SMBUS_PCICMD, B_PCH_SMBUS_PCICMD_IOSE);
+
+  PchBaseInit();
+
+  //
+  //Todo: confirm if we need program 8254
+  //
+  // Setting 8254
+  // Program timer 1 as refresh timer
+  //
+  IoWrite8 (0x43, 0x54);
+  IoWrite8 (0x41, 0x12);
+
+  //
+  // RTC power failure handling
+  //
+  RtcPowerFailureHandler (PeiServices);
+
+
+  PchMmPci32( 0, 0, 2, 0, 0x50) = 0x210;
+
+  VariableSize = sizeof (SYSTEM_CONFIGURATION);
+  ZeroMem (&SystemConfiguration, VariableSize);
+
+  //
+  // Obtain variable services
+  //
+  Status = (*PeiServices)->LocatePpi(
+                             PeiServices,
+                             &gEfiPeiReadOnlyVariable2PpiGuid,
+                             0,
+                             NULL,
+                             (void **)&Variable
+                             );
+  ASSERT_EFI_ERROR(Status);
+  Status = Variable->GetVariable (
+                       Variable,
+                       L"Setup",
+                       &gEfiSetupVariableGuid,
+                       NULL,
+                       &VariableSize,
+                       &SystemConfiguration
+					   );
+  if (EFI_ERROR (Status) || VariableSize != sizeof(SYSTEM_CONFIGURATION)) {
+    //The setup variable is corrupted
+    VariableSize = sizeof(SYSTEM_CONFIGURATION);
+    Status = Variable->GetVariable(
+              Variable,
+              L"SetupRecovery",
+              &gEfiSetupVariableGuid,
+              NULL,
+              &VariableSize,
+              &SystemConfiguration
+              );
+    ASSERT_EFI_ERROR (Status);
+  }
+  
+  if (EFI_ERROR (Status)) {
+    GGC = ((2 << 3) | 0x200);
+    PciCfg16Write(EC_BASE, 0, 2, 0, 0x50, GGC);
+    GGC = PciCfg16Read(EC_BASE, 0, 2, 0, 0x50);
+    DEBUG((EFI_D_INFO , "GGC: 0x%08x GMSsize:0x%08x\n", GGC, (GGC & (BIT7|BIT6|BIT5|BIT4|BIT3))>>3));
+  } else {
+    if (SystemConfiguration.Igd == 1 && SystemConfiguration.PrimaryVideoAdaptor != 2) {
+      GGC = (SystemConfiguration.IgdDvmt50PreAlloc << 3) |
+            (SystemConfiguration.GTTSize == GTT_SIZE_1MB ? 0x100: 0x200);
+      PciCfg16Write(EC_BASE, 0, 2, 0, 0x50, GGC);
+      GGC = PciCfg16Read(EC_BASE, 0, 2, 0, 0x50);
+      DEBUG((EFI_D_INFO , "GGC: 0x%08x GMSsize:0x%08x\n", GGC, (GGC & (BIT7|BIT6|BIT5|BIT4|BIT3))>>3));
+    }
+  }
+
+  //
+  // Initialize PlatformInfo HOB
+  //
+  Status = ReadPlatformIds(PeiServices, &PlatformInfo);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // 0 -> Disable , 1 -> Enable
+  //
+  if(SystemConfiguration.CfioPnpSettings == 1) {
+    DEBUG((EFI_D_INFO, "CheckCfioPnpSettings: CFIO Pnp Settings Enabled\n"));
+    PlatformInfo.CfioEnabled = 1;
+  } else {
+    DEBUG((EFI_D_INFO, "CheckCfioPnpSettings: CFIO Pnp Settings Disabled\n"));
+    PlatformInfo.CfioEnabled = 0;
+  }
+
+  //
+  // Build HOB for PlatformInfo
+  //
+  BuildGuidDataHob (
+    &gEfiPlatformInfoGuid,
+    &PlatformInfo,
+    sizeof (EFI_PLATFORM_INFO_HOB)
+    );
+
+
+#ifdef FTPM_ENABLE
+  Status = FtpmPolicyInit(PeiServices, &SystemConfiguration);
+  if (EFI_ERROR (Status)) {
+    DEBUG((EFI_D_ERROR, "fTPM init failed.\n"));
+  }
+#endif
+
+
+  //
+  // Set the new boot mode for MRC
+  //
+#ifdef NOCS_S3_SUPPORT
+  Status = UpdateBootMode (PeiServices);
+  ASSERT_EFI_ERROR (Status);
+#endif
+
+  DEBUG((EFI_D_INFO, "Setup MMIO size ... \n\n"));
+
+  //
+  // Setup MMIO size
+  //
+  Status = (*PeiServices)->AllocatePool(
+                             PeiServices,
+                             sizeof (EFI_PEI_PPI_DESCRIPTOR),
+                             (void **)&mVlvMmioPolicyPpiDesc
+                             );
+  ASSERT_EFI_ERROR (Status);
+  Status = (*PeiServices)->AllocatePool(
+                             PeiServices,
+                             sizeof (VLV_MMIO_POLICY_PPI),
+                             (void **)&mVlvMmioPolicyPpi
+                             );
+  ASSERT_EFI_ERROR (Status);
+  (*PeiServices)->SetMem (
+                    (VOID *)mVlvMmioPolicyPpi,
+                    sizeof (VLV_MMIO_POLICY_PPI),
+                    0
+                    );
+  mVlvMmioPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+  mVlvMmioPolicyPpiDesc->Guid = &gVlvMmioPolicyPpiGuid;
+  mVlvMmioPolicyPpiDesc->Ppi = mVlvMmioPolicyPpi;
+  switch (SystemConfiguration.MmioSize) {
+    case 0:      // 768MB
+      mVlvMmioPolicyPpi->MmioSize = 0x300;
+      break;
+    case 1:      // 1GB
+      mVlvMmioPolicyPpi->MmioSize = 0x400;
+      break;
+    case 2:      // 1.25GB
+      mVlvMmioPolicyPpi->MmioSize = 0x500;
+      break;
+    case 3:      // 1.5GB
+      mVlvMmioPolicyPpi->MmioSize = 0x600;
+      break;
+    case 4:      // 2GB
+      mVlvMmioPolicyPpi->MmioSize = 0x800;
+      break;
+    default:
+      mVlvMmioPolicyPpi->MmioSize = 0x800;
+      break;
+  }
+  Status = (*PeiServices)->InstallPpi(
+                             PeiServices,
+                             mVlvMmioPolicyPpiDesc
+                             );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+EFI_STATUS
+ReadPlatformIds (
+  IN CONST EFI_PEI_SERVICES             **PeiServices,
+  IN OUT EFI_PLATFORM_INFO_HOB          *PlatformInfoHob
+  )
+{
+  {
+    EFI_STATUS                      Status = EFI_SUCCESS;
+    UINT8                           FabId = 0;
+    UINTN                           DataSize;
+    EFI_PLATFORM_INFO_HOB           TmpHob;
+    EFI_PEI_READ_ONLY_VARIABLE2_PPI *PeiVar;
+    UINT32                          CompatibleBoard = 0; 
+
+    Status = (**PeiServices).LocatePpi (
+                               PeiServices,
+                               &gEfiPeiReadOnlyVariable2PpiGuid,
+                               0,
+                               NULL,
+                               (void **)&PeiVar
+                               );
+    ASSERT_EFI_ERROR (Status);
+
+    DataSize = sizeof (EFI_PLATFORM_INFO_HOB);
+    Status = PeiVar->GetVariable (
+                       PeiVar,
+                       L"PlatformInfo",
+                       &gEfiVlv2VariableGuid,
+                       NULL,
+                       &DataSize,
+                       &TmpHob
+					   );
+
+    if (Status == EFI_SUCCESS) {
+      PlatformInfoHob->BoardId        = TmpHob.BoardId;
+      PlatformInfoHob->MemCfgID       = TmpHob.MemCfgID;
+      PlatformInfoHob->BoardRev       = TmpHob.BoardRev;
+      PlatformInfoHob->PlatformFlavor = TmpHob.PlatformFlavor;
+      return Status;
+    }
+
+    CompatibleBoard = DetermineTurbotBoard();
+   if (1 == CompatibleBoard) {
+     PlatformInfoHob->BoardId    = BOARD_ID_MINNOW2_TURBOT;
+     DEBUG ((EFI_D_INFO,  "I'm MinnowBoard Turbot!\n"));
+   } else {       
+     PlatformInfoHob->BoardId    = BOARD_ID_MINNOW2;
+     DEBUG ((EFI_D_INFO,  "I'm MinnowBoard Max!\n"));
+   }
+    
+
+    PlatformInfoHob->MemCfgID   = 0;
+    PlatformInfoHob->BoardRev   = FabId + 1;	// FabId = 0 means FAB1 (BoardRev = 1), FabId = 1 means FAB2 (BoardRev = 2)...
+    PlatformInfoHob->PlatformFlavor = FlavorMobile;
+  }
+
+  return EFI_SUCCESS;
+}
+
+//
+// Start::Alpine Valley platform
+//
+/**
+  This routine reads SysCtl registers
+
+  @param SmbusBase   SMBUS Base Address
+  @param SlvAddr     Targeted Smbus Slave device address
+  @param Operation   Which SMBus protocol will be used
+  @param Offset      Offset of the register
+  @param  Length     Number of bytes
+  @param  Buffer     Buffer contains values read from registers
+
+  @retval SUCCESS as passed
+  @retval Others as failed
+
+**/
+EFI_STATUS
+PeiSmbusExec (
+  UINT16 SmbusBase,
+  UINT8 SlvAddr,
+  UINT8 Operation,
+  UINT8 Offset,
+  UINT8 *Length,
+  UINT8 *Buffer
+  )
+{
+  EFI_STATUS  Status=EFI_SUCCESS;
+  UINT8       AuxcReg;
+  UINT8       SmbusOperation = 0;
+  UINT8       StsReg;
+  UINT8       SlvAddrReg;
+  UINT8       HostCmdReg;
+  UINT8       BlockCount = 0;
+  BOOLEAN     BufferTooSmall;
+  UINT8       Index;
+  UINT8       *CallBuffer;
+  UINT8  	  RetryCount = BUS_TRIES;
+
+  //
+  // MrcSmbusExec supports byte and block read.
+  // Only allow Byte or block access
+  //
+  if (!((*Length  == AV_SC_BYTE_LEN) || (*Length == AV_SC_BLOCK_LEN))) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // See if its ok to use the bus based upon INUSE_STS bit.
+  //
+  Status = AcquireBus (SmbusBase);
+  ASSERT_EFI_ERROR(Status);
+
+  CallBuffer = Buffer;
+
+  //
+  //SmbStatus Bits of interest
+  //[6] = IUS (In Use Status)
+  //[4] = FAIL
+  //[3] = BERR (Bus Error = transaction collision)
+  //[2] = DERR (Device Error = Illegal Command Field, Unclaimed Cycle, Host Device Timeout, CRC Error)
+  //[1] = INTR (Successful completion of last command)
+  //[0] = HOST BUSY
+  //
+  //
+  // This is the main operation loop.  If the operation results in a Smbus
+  // collision with another master on the bus, it attempts the requested
+  // transaction again at least BUS_TRIES attempts.
+  //
+  while (RetryCount--) {
+    //
+    // Operation Specifics (pre-execution)
+    //
+    Status          = EFI_SUCCESS;
+    SlvAddrReg      = SlvAddr;
+    HostCmdReg      = Offset;
+    AuxcReg         = 0;
+
+	switch (Operation) {
+
+	case SMBUS_WRITE_BYTE:
+    IoWrite8 (SmbusBase+R_PCH_SMBUS_HD0, CallBuffer[0]);
+		SmbusOperation = V_PCH_SMBUS_SMB_CMD_BYTE_DATA;
+	break;
+
+    case SMBUS_READ_BYTE:
+      SmbusOperation = V_PCH_SMBUS_SMB_CMD_BYTE_DATA;
+	  	SlvAddrReg |= B_PCH_SMBUS_RW_SEL_READ;
+      if (*Length < 1) {
+        Status = EFI_INVALID_PARAMETER;
+      }
+      	*Length = 1;
+	break;
+
+    case SMBUS_WRITE_BLOCK:
+      SmbusOperation  = V_PCH_SMBUS_SMB_CMD_BLOCK;
+      IoWrite8 (SmbusBase+R_PCH_SMBUS_HD0, *(UINT8 *) Length);
+     	BlockCount = (UINT8) (*Length);
+     	if ((*Length < 1) || (*Length > 32)) {
+        Status = EFI_INVALID_PARAMETER;
+        break;
+    	}
+      	AuxcReg |= B_PCH_SMBUS_E32B;
+	break;
+
+    case SMBUS_READ_BLOCK:
+      SmbusOperation = V_PCH_SMBUS_SMB_CMD_BLOCK;
+     	SlvAddrReg |= B_PCH_SMBUS_RW_SEL_READ;
+     	if ((*Length < 1) || (*Length > 32)) {
+        Status = EFI_INVALID_PARAMETER;
+        break;
+     	}
+      	AuxcReg |= B_PCH_SMBUS_E32B;
+	break;
+
+    default:
+      	Status = EFI_INVALID_PARAMETER;
+	break;
+    }
+
+    //
+    // Set Auxiliary Control register
+    //
+    IoWrite8 (SmbusBase+R_PCH_SMBUS_AUXC, AuxcReg);
+
+    //
+    // Reset the pointer of the internal buffer
+    //
+    IoRead8 (SmbusBase+R_PCH_SMBUS_HCTL);
+
+    //
+    // Now that the 32 byte buffer is turned on, we can write th block data
+    // into it
+    //
+    if (Operation == SMBUS_WRITE_BLOCK) {
+      for (Index = 0; Index < BlockCount; Index++) {
+        //
+        // Write next byte
+        //
+        IoWrite8 (SmbusBase+R_PCH_SMBUS_HBD, CallBuffer[Index]);
+      }
+    }
+
+    //
+    // Set SMBus slave address for the device to read
+    //
+    IoWrite8(SmbusBase+R_PCH_SMBUS_TSA, SlvAddrReg);
+
+    //
+    //
+    // Set Command register for the offset to read
+    //
+    IoWrite8(SmbusBase+R_PCH_SMBUS_HCMD, HostCmdReg );
+
+    //
+    // Set Control Register to Set "operation command" protocol and start bit
+    //
+    IoWrite8(SmbusBase+R_PCH_SMBUS_HCTL, (UINT8) (SmbusOperation + B_PCH_SMBUS_START));
+
+    //
+    // Wait for IO to complete
+    //
+	do { StsReg = (UINT8) IoRead8(SmbusBase+0); } while ((StsReg & (BIT4|BIT3|BIT2|BIT1)) == 0);
+
+	  if (StsReg & B_PCH_SMBUS_DERR) {
+      Status = EFI_DEVICE_ERROR;
+      break;
+    } else if (StsReg & B_PCH_SMBUS_BERR) {
+      //
+      // Clear the Bus Error for another try
+      //
+      Status = EFI_DEVICE_ERROR;
+      IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BERR);
+
+      //
+      // Clear Status Registers
+      //
+      IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
+      IoWrite8(SmbusBase+R_PCH_SMBUS_AUXS, B_PCH_SMBUS_CRCE);
+
+      continue;
+    }
+
+    //
+    // successfull completion
+    // Operation Specifics (post-execution)
+    //
+    switch (Operation) {
+
+    case SMBUS_READ_BYTE:
+      CallBuffer[0] = (UINT8)(IoRead8 (SmbusBase+R_PCH_SMBUS_HD0));
+      break;
+
+    case SMBUS_WRITE_BLOCK:
+      IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BYTE_DONE_STS);
+      break;
+
+    case SMBUS_READ_BLOCK:
+      BufferTooSmall = FALSE;
+
+      //
+      // Find out how many bytes will be in the block
+      //
+      BlockCount = (UINT8)(IoRead8 (SmbusBase+R_PCH_SMBUS_HD0));
+      if (*Length < BlockCount) {
+        BufferTooSmall = TRUE;
+      } else {
+        for (Index = 0; Index < BlockCount; Index++) {
+          //
+          // Read the byte
+          //
+          CallBuffer[Index] = (UINT8)IoRead8 (SmbusBase+R_PCH_SMBUS_HBD);
+        }
+      }
+
+      *Length = BlockCount;
+      if (BufferTooSmall) {
+        Status = EFI_BUFFER_TOO_SMALL;
+      }
+      break;
+
+    default:
+      break;
+    };
+
+    if ((StsReg & B_PCH_SMBUS_BERR) && (Status == EFI_SUCCESS)) {
+      //
+      // Clear the Bus Error for another try
+      //
+      Status = EFI_DEVICE_ERROR;
+      IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BERR);
+
+      continue;
+    } else {
+      break;
+    }
+  }
+
+  //
+  // Clear Status Registers and exit
+  //
+  IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
+  IoWrite8(SmbusBase+R_PCH_SMBUS_AUXS, B_PCH_SMBUS_CRCE);
+  IoWrite8(SmbusBase+R_PCH_SMBUS_AUXC, 0);
+  return Status;
+}
+//
+// End::Alpine Valley platform
+//
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.h b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.h
new file mode 100644
index 0000000000..e1817b28c6
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.h
@@ -0,0 +1,213 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+**/
+
+
+#ifndef __PEI_PLATFORM_H__
+#define __PEI_PLATFORM_H__
+
+#define PEI_STALL_RESOLUTION            1
+#define STALL_PEIM_SIGNATURE   SIGNATURE_32('p','p','u','s')
+
+typedef struct {
+  UINT32                      Signature;
+  EFI_FFS_FILE_HEADER         *FfsHeader;
+  EFI_PEI_NOTIFY_DESCRIPTOR   StallNotify;
+} STALL_CALLBACK_STATE_INFORMATION;
+
+#define STALL_PEIM_FROM_THIS(a) CR (a, STALL_CALLBACK_STATE_INFORMATION, StallNotify, STALL_PEIM_SIGNATURE)
+
+#ifdef NOCS_S3_SUPPORT
+
+/**
+  Peform the boot mode determination logic
+  If the box is closed, then
+  1. If it's first time to boot, it's boot with full config .
+  2. If the ChassisIntrution is selected, force to be a boot with full config
+  3. Otherwise it's boot with no change.
+
+  @param  PeiServices General purpose services available to every PEIM.
+  @param  BootMode The detected boot mode.
+
+  @retval EFI_SUCCESS if the boot mode could be set
+**/
+EFI_STATUS
+UpdateBootMode (
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  );
+#endif
+
+/**
+  This function reset the entire platform, including all processor and devices, and
+  reboots the system.
+  
+  Declaration of this function goes to MdeModulePkg/Include/Library/ResetSystemLib.h
+
+  @param  PeiServices General purpose services available to every PEIM.
+
+  @retval EFI_SUCCESS if it completed successfully.
+**/
+// EFI_STATUS
+// EFIAPI
+// ResetSystem (
+  // IN CONST EFI_PEI_SERVICES          **PeiServices
+  // );
+
+/**
+  This function will be called when MRC is done.
+
+  @param  PeiServices        General purpose services available to every PEIM.
+  @param  NotifyDescriptor   Information about the notify event..
+  @param  Ppi                The notify context.
+
+  @retval EFI_SUCCESS        If the function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+MemoryDiscoveredPpiNotifyCallback (
+  IN EFI_PEI_SERVICES                     **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR            *NotifyDescriptor,
+  IN VOID                                 *Ppi
+  );
+
+/**
+  This is the callback function notified by FvFileLoader PPI, it depends on FvFileLoader PPI to load
+  the PEIM into memory.
+
+  @param  PeiServices       General purpose services available to every PEIM.
+  @param  NotifyDescriptor  The context of notification.
+  @param  Ppi               The notify PPI.
+
+  @retval EFI_SUCCESS       if it completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+FvFileLoaderPpiNotifyCallback (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+  );
+
+/**
+  This function provides a blocking stall for reset at least the given number of microseconds
+  stipulated in the final argument.
+
+  @param  PeiServices    General purpose services available to every PEIM.
+  @param  this Pointer   to the local data for the interface.
+  @param  Microseconds   number of microseconds for which to stall.
+
+  @retval EFI_SUCCESS    the function provided at least the required stall.
+**/
+EFI_STATUS
+EFIAPI
+Stall (
+  IN CONST EFI_PEI_SERVICES   **PeiServices,
+  IN CONST EFI_PEI_STALL_PPI  *This,
+  IN UINTN                    Microseconds
+  );
+
+/**
+  This function initialize recovery functionality by installing the recovery PPI.
+
+  @param  PeiServices  General purpose services available to every PEIM.
+
+  @retval EFI_SUCCESS  If the interface could be successfully installed.
+**/
+EFI_STATUS
+EFIAPI
+InitializeRecovery (
+  IN EFI_PEI_SERVICES     **PeiServices
+  );
+
+/**
+  This function
+    1. Calling MRC to initialize memory.
+    2. Install EFI Memory.
+    3. Capsule coalesce if capsule boot mode.
+    4. Create HOB of system memory.
+
+  @param  PeiServices Pointer to the PEI Service Table
+
+  @retval EFI_SUCCESS If it completes successfully.
+
+**/
+EFI_STATUS
+MemoryInit (
+  IN EFI_PEI_SERVICES          **PeiServices
+  );
+
+/**
+  This function provides the implementation of AtaController PPI Enable Channel function.
+
+  @param  PeiServices General purpose services available to every PEIM.
+  @param  this Pointer to the local data for the interface.
+  @param  ChannelMask This parameter is used to specify primary or slavery IDE channel.
+
+  @retval EFI_SUCCESS  Procedure returned successfully.
+**/
+EFI_STATUS
+EnableAtaChannel (
+  IN EFI_PEI_SERVICES               **PeiServices,
+  IN PEI_ATA_CONTROLLER_PPI         *This,
+  IN UINT8                          ChannelMask
+  );
+
+/**
+  This function provides the implementation of AtaController PPI Get IDE channel Register Base Address
+
+  @param  PeiServices      General purpose services available to every PEIM.
+  @param  this             Pointer to the local data for the interface.
+  @param  IdeRegsBaseAddr  Pointer to IDE_REGS_BASE_ADDR struct, which is used to record
+                           IDE Command and Control regeisters Base Address.
+
+  @retval EFI_SUCCESS  Procedure returned successfully.
+**/
+EFI_STATUS
+GetIdeRegsBaseAddr (
+  IN EFI_PEI_SERVICES               **PeiServices,
+  IN PEI_ATA_CONTROLLER_PPI         *This,
+  IN IDE_REGS_BASE_ADDR             *IdeRegsBaseAddr
+  );
+
+/**
+  This function provides the implementation to properly setup both LM & PDM functionality.
+
+  @param  PeiServices      General purpose services available to every PEIM.
+
+  @retval EFI_SUCCESS  Procedure returned successfully.
+
+**/
+EFI_STATUS
+ConfigureLM(
+  IN EFI_PEI_SERVICES **PeiServices
+  );
+
+#include <Ppi/VlvMmioPolicy.h>
+
+BOOLEAN
+EFIAPI
+IsFastBootEnabled (
+  IN CONST EFI_PEI_SERVICES **PeiServices
+  );
+
+EFI_STATUS
+PrioritizeBootMode (
+  IN OUT EFI_BOOT_MODE    *CurrentBootMode,
+  IN EFI_BOOT_MODE        NewBootMode
+  );
+
+EFI_STATUS
+EFIAPI
+CapsulePpiNotifyCallback (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+  );
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/PlatformPei.inf b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/PlatformPei.inf
new file mode 100644
index 0000000000..c976273ce3
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/PlatformPei.inf
@@ -0,0 +1,129 @@
+#
+#
+# Copyright (c)  1999  - 2018, Intel Corporation. All rights reserved
+#                                                                                  
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#                                                                                  
+#
+# This PEIM includes 3 parts, pre memory initialization, MRC
+#  wrapper and post memory initialization.
+#  On pre memory, following action is performed,
+#  1. Initizluize GMCH.
+#  2. Detect boot mode.
+#  3. Detect video adapter to determine whether we need pre allocated
+#  memory.
+#
+#  After that MRC wrapper calls MRC to initialize memory and install a PPI
+#  notify to do post memory
+#  initialization. MRC wrapper performance following actions,
+#  1. Install EFI Memory.
+#  2. Capsule coalesce if capsule boot mode.
+#  3. Create HOB of system memory.
+#  Note: MRC supports 3 kinds of chipsets including Lakeport, Glenwood and Mukilteo,
+#   so please don't define MACRO MUKILTEO_SUPPORT on Lakeport here.
+#
+#  On post memory, following action is performed,
+#  1. TC initialization after MRC.
+#  2. SIO initialization.
+#  3. Install ResetSystem and FinvFv PPI, relocate Stall to memory on
+#   recovery boot mode.
+#  4. Set MTRR for PEI
+#  5. Create FV HOB and Flash HOB
+#  6. Install RecoveryModule and AtaController PPI if on recovery boot mode.
+#
+#  This PEIM does not have any register access directly, it depends on
+#  IntelTCLib, TCAccess libraries to access Chipset
+#  registers.
+#
+#  Platform.c - Provide main flow and entrypoint of PEIM.
+#  MemoryCallback.c - Includes a memory call back function notified when
+#     MRC is done.
+#
+#
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformPeim
+  FILE_GUID                      = 9618C0DC-50A4-496c-994F-7241F282ED01
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = PeiInitPlatform
+  PI_SPECIFICATION_VERSION	   = 0x0001000A
+
+[sources.common]
+  Platform.c
+  Platform.h
+  MemoryCallback.c
+  CommonHeader.h
+  Stall.c
+  BootMode.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+  Vlv2SocBinPkg/Vlv2SocBinPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  CryptoPkg/CryptoPkg.dec
+
+[LibraryClasses]
+  PeimEntryPoint
+  DebugLib
+  HobLib
+  IoLib
+  MultiPlatformLib
+  MtrrLib
+  PerformanceLib
+  MonoStatusCodeLib
+  BaseCryptLib
+  PciLib
+
+[Ppis]
+  gEfiPeiStallPpiGuid
+  gPeiSpeakerInterfacePpiGuid
+  gEfiPeiMemoryDiscoveredPpiGuid
+  gVlvPolicyPpiGuid
+  gEfiPeiReadOnlyVariable2PpiGuid
+  gEfiPeiResetPpiGuid
+  gEfiEndOfPeiSignalPpiGuid
+  gEfiFindFvPpiGuid
+  gPeiCapsulePpiGuid
+  gEfiPeiBootInRecoveryModePpiGuid
+  gEfiPeiRecoveryModulePpiGuid
+  gEfiPeiDeviceRecoveryModulePpiGuid
+  gPeiCachePpiGuid
+  gEfiPeiMasterBootModePpiGuid
+  gEfiPeiSmbusPpiGuid
+  gPeiMfgMemoryTestPpiGuid
+  gPeiSha256HashPpiGuid
+  gVlvMmioPolicyPpiGuid
+  gSeCfTPMPolicyPpiGuid
+
+[Guids]
+  gEfiSetupVariableGuid
+  gEfiPlatformInfoGuid
+  gEfiPlatformBootModeGuid
+  gEfiPlatformCpuInfoGuid
+  gEfiGlobalVariableGuid
+  gRecoveryOnFatFloppyDiskGuid
+  gRecoveryOnFatUsbDiskGuid
+  gRecoveryOnFatIdeDiskGuid
+  gRecoveryOnDataCdGuid
+  gMfgModeVariableGuid
+  gEfiNormalSetupGuid
+  gEfiVlv2VariableGuid
+
+[Pcd.common]
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvMainBase
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvMainSize
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Base
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Size
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+  gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress
+  gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize
+[Depex]
+  TRUE
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Stall.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Stall.c
new file mode 100644
index 0000000000..5e68f803db
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Stall.c
@@ -0,0 +1,90 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  Stall.c
+
+Abstract:
+
+  Produce Stall Ppi.
+
+--*/
+
+
+#include "CommonHeader.h"
+#include "PlatformBaseAddresses.h"
+#include "PchRegs.h"
+
+/**
+  Waits for at least the given number of microseconds.
+
+  @param PeiServices     General purpose services available to every PEIM.
+  @param This            PPI instance structure.
+  @param Microseconds    Desired length of time to wait.
+
+  @retval EFI_SUCCESS    If the desired amount of time was passed.
+
+**/
+EFI_STATUS
+EFIAPI
+Stall (
+  IN CONST EFI_PEI_SERVICES   **PeiServices,
+  IN CONST EFI_PEI_STALL_PPI      *This,
+  IN UINTN              Microseconds
+  )
+{
+  UINTN   Ticks;
+  UINTN   Counts;
+  UINT32  CurrentTick;
+  UINT32  OriginalTick;
+  UINT32  RemainingTick;
+
+  if (Microseconds == 0) {
+    return EFI_SUCCESS;
+  }
+
+  OriginalTick = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_TMR);
+  OriginalTick &= (V_PCH_ACPI_PM1_TMR_MAX_VAL - 1);
+  CurrentTick = OriginalTick;
+
+  //
+  // The timer frequency is 3.579545MHz, so 1 ms corresponds to 3.58 clocks
+  //
+  Ticks = Microseconds * 358 / 100 + OriginalTick + 1;
+
+  //
+  // The loops needed for timer overflow
+  //
+  Counts = (UINTN)RShiftU64((UINT64)Ticks, 24);
+
+  //
+  // Remaining clocks within one loop
+  //
+  RemainingTick = Ticks & 0xFFFFFF;
+
+  //
+  // Do not intend to use TMROF_STS bit of register PM1_STS, because this add extra
+  // one I/O operation, and may generate SMI
+  //
+  while (Counts != 0) {
+    CurrentTick = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_TMR) & B_PCH_ACPI_PM1_TMR_VAL;
+    if (CurrentTick <= OriginalTick) {
+      Counts--;
+    }
+    OriginalTick = CurrentTick;
+  }
+
+  while ((RemainingTick > CurrentTick) && (OriginalTick <= CurrentTick)) {
+    OriginalTick  = CurrentTick;
+    CurrentTick   = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_TMR) & B_PCH_ACPI_PM1_TMR_VAL;
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.dec b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.dec
new file mode 100644
index 0000000000..4653f63a66
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.dec
@@ -0,0 +1,211 @@
+#/** @file
+# Platform Package
+#
+# This package provides platform specific modules.
+# Copyright (c) 2009  - 2015, Intel Corporation. All rights reserved.<BR>
+#
+
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+#
+
+#
+#
+#**/
+
+[Defines]
+  DEC_SPECIFICATION              = 0x00010005
+  PACKAGE_NAME                   = PlatformPkg
+  PACKAGE_GUID                   = 463B3B00-0D18-4a5f-90C0-D5B851D2574B
+  PACKAGE_VERSION                = 0.1
+
+[Includes]
+  .
+  Include
+  Include/Library
+
+[Ppis]
+  gPeiSpeakerInterfacePpiGuid  = { 0x30ac275e, 0xbb30, 0x4b84, { 0xa1, 0xcd, 0x0a, 0xf1, 0x32, 0x2c, 0x89, 0xc0 }}
+  gPeiUsbControllerPpiGuid     = { 0x3BC1F6DE, 0x693E, 0x4547, { 0xA3, 0x00, 0x21, 0x82, 0x3C, 0xA4, 0x20, 0xB2 }}
+  gPeiMfgMemoryTestPpiGuid     = { 0xab294a92, 0xeaf5, 0x4cf3, { 0xab, 0x2b, 0x2d, 0x4b, 0xed, 0x4d, 0xb6, 0x3d }}
+  gPeiSha256HashPpiGuid        = { 0x950e191b, 0x8524, 0x4f51, { 0x80, 0xa1, 0x5c, 0x4f, 0x1b, 0x03, 0xf3, 0x5c }}
+
+[Guids]
+  gEfiPlatformBootModeGuid                = { 0xce845704, 0x1683, 0x4d38, { 0xa4, 0xf9, 0x7d, 0x0b, 0x50, 0x77, 0x57, 0x93 } }
+  gEfiPlatformInfoGuid                    = { 0x1e2acc41, 0xe26a, 0x483d, { 0xaf, 0xc7, 0xa0, 0x56, 0xc3, 0x4e, 0x08, 0x7b } }
+  gEfiMemoryConfigDataGuid                = { 0x80dbd530, 0xb74c, 0x4f11, { 0x8c, 0x03, 0x41, 0x86, 0x65, 0x53, 0x28, 0x31 } }
+  gPlatformModuleTokenSpaceGuid           = { 0x69d13bf0, 0xaf91, 0x4d96, { 0xaa, 0x9f, 0x21, 0x84, 0xc5, 0xce, 0x3b, 0xc0 } }
+  gEfiSerialPortTokenSpaceGuid            = { 0x5fad2389, 0x2bc7, 0x4bd2, { 0x83, 0xd3, 0x42, 0x9f, 0xb6, 0xae, 0xa3, 0x3f } }
+  gEfiIchTokenSpaceGuid                   = { 0xe38c11e3, 0x968f, 0x47b8, { 0xac, 0xef, 0xac, 0xc0, 0x69, 0x3d, 0xb9, 0xff } }
+  gEfiPchTokenSpaceGuid                   = { 0x89a1b278, 0xa1a1, 0x4df7, { 0xb1, 0x37, 0xde, 0x5a, 0xd7, 0xc4, 0x79, 0x13 } }
+  gEfiSioVariableGuid                     = { 0x560bf58a, 0x1e0d, 0x4d7e, { 0x95, 0x3f, 0x29, 0x80, 0xa2, 0x61, 0xe0, 0x31 } }
+  gProcessorProducerGuid                  = { 0x1bf06aea, 0x5bec, 0x4a8d, { 0x95, 0x76, 0x74, 0x9b, 0x09, 0x56, 0x2d, 0x30 } }
+  gEfiPowerOnHobGuid                      = { 0x0468a601, 0xc535, 0x46fd, { 0xa9, 0x5d, 0xbb, 0xab, 0x99, 0x1b, 0x17, 0x8c } }
+  gEfiPlatformCpuInfoGuid                 = { 0xbb9c7ab7, 0xb8d9, 0x4bf3, { 0x9c, 0x29, 0x9b, 0xf3, 0x41, 0xe2, 0x17, 0xbc } }
+  gEfiBiosIdGuid                          = { 0xC3E36D09, 0x8294, 0x4b97, { 0xA8, 0x57, 0xD5, 0x28, 0x8F, 0xE3, 0x3E, 0x28 } }
+  gEfiPlatformBootModeGuid                = { 0xce845704, 0x1683, 0x4d38, { 0xa4, 0xf9, 0x7d, 0x0b, 0x50, 0x77, 0x57, 0x93 } }
+  gEfiBoardFeaturesGuid                   = { 0x94b9e8ae, 0x8877, 0x479a, { 0x98, 0x42, 0xf5, 0x97, 0x4b, 0x82, 0xce, 0xd3 } }
+  gItkDataVarGuid                         = { 0x3812723d, 0x7e48, 0x4e29, { 0xbc, 0x27, 0xf5, 0xa3, 0x9a, 0xc9, 0x4e, 0xf1 } }
+  gDmiDataGuid                            = { 0x70e56c5e, 0x280c, 0x44b0, { 0xa4, 0x97, 0x09, 0x68, 0x1a, 0xbc, 0x37, 0x5e } }
+  gIdccDataHubGuid                        = { 0x788e1d9f, 0x1eab, 0x47d2, { 0xa2, 0xf3, 0x78, 0xca, 0xe8, 0x7d, 0x60, 0x12 } }
+  gEfiSetupVariableGuid                   = { 0xec87d643, 0xeba4, 0x4bb5, { 0xa1, 0xe5, 0x3f, 0x3e, 0x36, 0xb2, 0x0d, 0xa9 } }
+  gEfiPlatformInfoGuid                    = { 0x1e2acc41, 0xe26a, 0x483d, { 0xaf, 0xc7, 0xa0, 0x56, 0xc3, 0x4e, 0x08, 0x7b } }
+  gMfgModeVariableGuid                    = { 0xEF14FD78, 0x0793, 0x4e2b, { 0xAC, 0x6D, 0x06, 0x28, 0x47, 0xE0, 0x17, 0x91 } }
+  gEfiAcpiTableStorageGuid                = { 0x7e374e25, 0x8e01, 0x4fee, { 0x87, 0xf2, 0x39, 0x0c, 0x23, 0xc6, 0x06, 0xcd } }
+  gACPIOSFRMfgStringVariableGuid          = { 0x72234213, 0x0fd7, 0x48a1, { 0xa5, 0x9f, 0xb4, 0x1b, 0xc1, 0x07, 0xfb, 0xcd } }
+  gACPIOSFRRefDataBlockVariableGuid       = { 0x72234213, 0x0fd7, 0x48a1, { 0xa5, 0x9f, 0xb4, 0x1b, 0xc1, 0x07, 0xfb, 0xcd } }
+  gACPIOSFRModelStringVariableGuid        = { 0xca1bcad9, 0xe021, 0x4547, { 0xa1, 0xb0, 0x5b, 0x22, 0xc7, 0xf6, 0x87, 0xf4 } }
+  gEfiAcpiTableStorageGuid                = { 0x7e374e25, 0x8e01, 0x4fee, { 0x87, 0xf2, 0x39, 0x0c, 0x23, 0xc6, 0x06, 0xcd } }
+  gEfiPciLanInfoGuid                      = { 0x0d9a1427, 0xe02a, 0x437d, { 0x92, 0x6b, 0xaa, 0x52, 0x1f, 0xd7, 0x22, 0xba } }
+  gEfiNormalSetupGuid                     = { 0xec87d643, 0xeba4, 0x4bb5, { 0xa1, 0xe5, 0x3f, 0x3e, 0x36, 0xb2, 0x0d, 0xa9 } }
+  gFirmwareIdGuid                         = { 0x5e559c23, 0x1faa, 0x4ae1, { 0x8d, 0x4a, 0xc6, 0xcf, 0x02, 0x6c, 0x76, 0x6f } }
+  gBmpImageGuid                           = { 0x878AC2CC, 0x5343, 0x46F2, { 0xB5, 0x63, 0x51, 0xF8, 0x9D, 0xAF, 0x56, 0xBA } }
+  gOsSelectionVariableGuid                = { 0x86843f56, 0x675d, 0x40a5, { 0x95, 0x30, 0xbc, 0x85, 0x83, 0x72, 0xf1, 0x03 } }
+
+[Protocols]
+  gEfiActiveBiosProtocolGuid              = { 0xebbe2d1b, 0x1647, 0x4bda, { 0xab, 0x9a, 0x78, 0x63, 0xe3, 0x96, 0xd4, 0x1a } }
+  gEfiPlatformCpuProtocolGuid             = { 0xbd26cdc9, 0xa092, 0x462a, { 0x87, 0x7a, 0x5a, 0xb6, 0xad, 0xce, 0x48, 0x12 } }
+  gDxePchPlatformPolicyProtocolGuid       = { 0x4b0165a9, 0x61d6, 0x4e23, { 0xa0, 0xb5, 0x3e, 0xc7, 0x9c, 0x2e, 0x30, 0xd5 } }
+  gEfiTpmMpDriverProtocolGuid             = { 0xde161cfe, 0x1e60, 0x42a1, { 0x8c, 0xc3, 0xee, 0x7e, 0xf0, 0x73, 0x52, 0x12 } }
+  gEfiLpcWpce791PolicyProtocolGuid        = { 0xab2bee2f, 0xc1a6, 0x4399, { 0x85, 0x3d, 0xc0, 0x7c, 0x77, 0x4f, 0xfd, 0x0d } }
+  gUsbPolicyGuid                          = { 0xf617b358, 0x12cf, 0x414a, { 0xa0, 0x69, 0x60, 0x67, 0x7b, 0xda, 0x13, 0xb4 } }
+  gEfiSpeakerInterfaceProtocolGuid        = { 0x400b4476, 0x3081, 0x11d6, { 0x87, 0xed, 0x00, 0x06, 0x29, 0x45, 0xc3, 0xb9 } }
+  gDxeVlvPlatformPolicyGuid               = { 0x5bab88ba, 0xe0e2, 0x4674, { 0xb6, 0xad, 0xb8, 0x12, 0xf6, 0x88, 0x1c, 0xd6 } }
+  gEfiSmbiosSlotPopulationGuid            = { 0xef7bf7d6, 0xf8ff, 0x4a76, { 0x82, 0x47, 0xc0, 0xd0, 0xd1, 0xcc, 0x49, 0xc0 } }
+  gObservableProtocolGuid                 = { 0xe227c522, 0xd5fe, 0x4a53, { 0x87, 0xb1, 0x0f, 0xbe, 0x57, 0x0f, 0x98, 0xe9 } }
+  gEfiCk505ClockPlatformInfoGuid          = { 0x3c485ea4, 0x449a, 0x46ce, { 0xbb, 0x08, 0x2a, 0x33, 0x6e, 0xa9, 0x6b, 0x4e } }
+  gEfiLpcWpc83627PolicyProtocolGuid       = { 0xd3ecc567, 0x9fd5, 0x44c1, { 0x86, 0xcf, 0x5d, 0xa7, 0xa2, 0x4f, 0x4b, 0x5d } }
+  gEfiTcoResetProtocolGuid                = { 0xa6a79162, 0xe325, 0x4c30, { 0xbc, 0xc3, 0x59, 0x37, 0x30, 0x64, 0xef, 0xb3 } }
+  gEfiWatchdogTimerDriverProtocolGuid     = { 0xd5b06d16, 0x2ea1, 0x4def, { 0x98, 0xd0, 0xa0, 0x5d, 0x40, 0x72, 0x84, 0x17 } }
+  gEfiPlatformIdeInitProtocolGuid         = { 0x377c66a3, 0x8fe7, 0x4ee8, { 0x85, 0xb8, 0xf1, 0xa2, 0x82, 0x56, 0x9e, 0x3b } }
+  gEfiPciPlatformProtocolGuid             = { 0x07d75280, 0x27d4, 0x4d69, { 0x90, 0xd0, 0x56, 0x43, 0xe2, 0x38, 0xb3, 0x41 } }
+  gEnhancedSpeedstepProtocolGuid          = { 0x91a1ddcf, 0x5374, 0x4939, { 0x89, 0x51, 0xd7, 0x29, 0x3f, 0x1a, 0x78, 0x6f } }
+  gEfiAcpiSupportProtocolGuid             = { 0xdbff9d55, 0x89b7, 0x46da, { 0xbd, 0xdf, 0x67, 0x7d, 0x3d, 0xc0, 0x24, 0x1d } }
+  gEfiAcpiS3SaveProtocolGuid              = { 0x125f2de1, 0xfb85, 0x440c, { 0xa5, 0x4c, 0x4d, 0x99, 0x35, 0x8a, 0x8d, 0x38 } }
+  gEfiCpuIoProtocolGuid                   = { 0xB0732526, 0x38C8, 0x4b40, { 0x88, 0x77, 0x61, 0xC7, 0xB0, 0x6A, 0xAC, 0x45 } }
+  gPlatformGOPPolicyGuid                  = { 0xec2e931b, 0x3281, 0x48a5, { 0x81, 0x07, 0xdf, 0x8a, 0x8b, 0xed, 0x3c, 0x5d } }
+  gEfiGopDisplayBrightnessProtocolGuid    = { 0x6ff23f1d, 0x877c, 0x4b1b, { 0x93, 0xfc, 0xf1, 0x42, 0xb2, 0xee, 0xa6, 0xa7 } }
+  gEfiUsbKeyboardConnectGuid              = { 0xad9c4381, 0x1ede, 0x430c, { 0x8d, 0x42, 0x23, 0x76, 0x7c, 0x46, 0x5d, 0x52 } }
+
+
+[PcdsFixedAtBuild]
+  gPlatformModuleTokenSpaceGuid.PcdFlashNvStorageBase|0xFFF60000|UINT32|0x20000007
+  gPlatformModuleTokenSpaceGuid.PcdFlashNvStorageSize|0x00010000|UINT32|0x20000008
+  gPlatformModuleTokenSpaceGuid.PcdFlashNvStorageEventLogBase|0xFFF6C000|UINT32|0x30000007
+  gPlatformModuleTokenSpaceGuid.PcdFlashNvStorageEventLogSize|0x00002000|UINT32|0x30000008
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoveryBase|0xFFF80000|UINT32|0x20000004
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoverySize|0x00080000|UINT32|0x20000005
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvShellBase|0xFFF50000|UINT32|0x20000009
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvShellSize|0x00000000|UINT32|0x20000010
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvMainBase|0xFF800000|UINT32|0x20000001
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvMainSize|0x00500000|UINT32|0x20000002
+  gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress|0xFF800000|UINT32|0x10000001
+  gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize|0x00800000|UINT32|0x10000002
+  gPlatformModuleTokenSpaceGuid.PcdFlashTestMenuBase|0xFF000000|UINT32|0x20000011
+  gPlatformModuleTokenSpaceGuid.PcdFlashTestMenuSize|0x00010000|UINT32|0x20000012
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Base|0xFFFA0000|UINT32|0x20000013
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Size|0x00040000|UINT32|0x20000014
+  gPlatformModuleTokenSpaceGuid.PcdFlashMicroCodeAddress|0xFFF90000|UINT32|0x20000015
+  gPlatformModuleTokenSpaceGuid.PcdFlashMicroCodeSize|0x00002000|UINT32|0x20000016
+  gPlatformModuleTokenSpaceGuid.PcdFlashMicroCode2Address|0xFFF92000|UINT32|0x20000017
+  gPlatformModuleTokenSpaceGuid.PcdFlashMicroCode2Size|0x0000C800|UINT32|0x20000018
+  gPlatformModuleTokenSpaceGuid.PcdIFWISigBaseAddress|0x0F00|UINT32|0x20000019
+  gPlatformModuleTokenSpaceGuid.PcdPBTNDisableInterval|0x01F4|UINT32|0x2000001A
+  gPlatformModuleTokenSpaceGuid.PcdTouchAttributes|2|UINT32|0x20000020
+  gPlatformModuleTokenSpaceGuid.PcdTouchCIDString|"I2C05\\S004A"|VOID*|0x20000021
+  gPlatformModuleTokenSpaceGuid.PcdFullIconFile             |{ 0x69, 0x00, 0x39, 0x82, 0x30, 0xa6, 0x4b, 0x4c, 0x85, 0xfc, 0x95, 0xe9, 0x49, 0xc9, 0xf0, 0x76 }|VOID*|0x20000022
+  gPlatformModuleTokenSpaceGuid.PcdSimpleIconFile           |{ 0x4b, 0xf7, 0xee, 0x4b, 0x30, 0xa3, 0x49, 0x67, 0xa4, 0xad, 0xa4, 0xb1, 0xca, 0xe4, 0x4b, 0x0d }|VOID*|0x20000023
+  gPlatformModuleTokenSpaceGuid.PcdCapitalLetterKeyboardFile|{ 0x82, 0x38, 0x75, 0xd8, 0x83, 0xa2, 0x4c, 0x37, 0xb6, 0xea, 0x04, 0xac, 0xc3, 0x06, 0x0f, 0x07 }|VOID*|0x20000024
+  gPlatformModuleTokenSpaceGuid.PcdSmallLetterKeyboardFile  |{ 0x4c, 0x66, 0x39, 0xa2, 0x09, 0x0e, 0x4d, 0xc9, 0x9f, 0x55, 0x0f, 0xcb, 0x72, 0x60, 0x26, 0x11 }|VOID*|0x20000025
+  gPlatformModuleTokenSpaceGuid.PcdDigitKeyboardFile        |{ 0x3f, 0xfe, 0x2c, 0x17, 0x92, 0x5d, 0x49, 0x7d, 0x87, 0x0a, 0x46, 0x14, 0xe4, 0x58, 0xd8, 0x5e }|VOID*|0x20000026
+  gPlatformModuleTokenSpaceGuid.PcdSimpleKeyboardFile       |{ 0x5c, 0xd4, 0xfc, 0x98, 0xbf, 0x79, 0x41, 0x10, 0xa2, 0xd3, 0x87, 0xbe, 0x82, 0xd0, 0x90, 0x52 }|VOID*|0x20000027
+
+  gPlatformModuleTokenSpaceGuid.PcdFlashSpidOffset|0x1000|UINT32|0x2000002A
+  gPlatformModuleTokenSpaceGuid.PcdFlashSpidSize|0x00001000|UINT32|0x2000002B
+  gPlatformModuleTokenSpaceGuid.PcdFlashEmOffset|0x3000|UINT32|0x2000002C
+  gPlatformModuleTokenSpaceGuid.PcdFlashEmSize|0x1000|UINT32|0x2000002D
+
+  gEfiSerialPortTokenSpaceGuid.PcdSerialRegisterBase|0x3f8|UINT64|0x00000001
+  gEfiSerialPortTokenSpaceGuid.PcdSerialBoudRate|115200|UINT32|0x00000002
+
+  gEfiPchTokenSpaceGuid.PcdPchAcpiIoPortBaseAddress|0x400|UINT16|0x0000000B
+
+   ## FFS filename to find the shell application.
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile|{ 0xB7, 0xD6, 0x7A, 0xC5, 0x15, 0x05, 0xA8, 0x40, 0x9D, 0x21, 0x55, 0x16, 0x52, 0x85, 0x4E, 0x37 }|VOID*|0x40000004
+
+  gEfiIchTokenSpaceGuid.PcdPeiIchUhciControllerIoPortBaseAddress|0x4000|UINT16|0x30000017
+  gEfiIchTokenSpaceGuid.PcdPeiIchEhciControllerMemoryBaseAddress|0xFC000000|UINT32|0x30000019
+
+
+  gPlatformModuleTokenSpaceGuid.PcdRamLogBaseAddress|0x20000|UINT32|0x00000013
+  gPlatformModuleTokenSpaceGuid.PcdRamLogBaseLength|0x80000|UINT32|0x00000014
+  gPlatformModuleTokenSpaceGuid.PcdRamLogBaseCarAddress|0xFEF86000|UINT32|0x00000015
+  gPlatformModuleTokenSpaceGuid.PcdRamLogBaseCarLength|0x2000|UINT32|0x00000016
+
+
+  #Pcd for Flash Update tool
+  gPlatformModuleTokenSpaceGuid.PcdFlashChipBase|0xFF800000|UINT32|0x40000001
+  gPlatformModuleTokenSpaceGuid.PcdFlashChipSize|0x00800000|UINT32|0x40000002
+  gPlatformModuleTokenSpaceGuid.PcdFlashDescriptorBase|0xFF800000|UINT32|0x40000003
+  gPlatformModuleTokenSpaceGuid.PcdFlashDescriptorSize|0x00001000|UINT32|0x40000004
+  gPlatformModuleTokenSpaceGuid.PcdTxeRomBase|0xFF801000|UINT32|0x40000009
+  gPlatformModuleTokenSpaceGuid.PcdTxeRomSize|0x003FF000|UINT32|0x4000000A
+  gPlatformModuleTokenSpaceGuid.PcdBiosRomBase|0xFFC00000|UINT32|0x4000000B
+  gPlatformModuleTokenSpaceGuid.PcdBiosRomSize|0x00400000|UINT32|0x4000000C
+
+  # PCDs for System Firmware FMP instance
+  gPlatformModuleTokenSpaceGuid.PcdSystemFirmwareFmpLowestSupportedVersion|0x00000000|UINT32|0x40000100
+  gPlatformModuleTokenSpaceGuid.PcdSystemFirmwareFmpVersion|0x00000000|UINT32|0x40000101
+  gPlatformModuleTokenSpaceGuid.PcdSystemFirmwareFmpVersionString|""|VOID*|0x40000102
+
+[PcdsFeatureFlag]
+  ## This PCD specifies whether StatusCode is reported via ISA Serial port.
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseIsaSerial|TRUE|BOOLEAN|0x00000020
+
+  ## This PCD specifies whether StatusCode is reported via USB Serial port.
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseUsbSerial|TRUE|BOOLEAN|0x00000021
+
+  ## This PCD specifies whether StatusCode is reported via RAM.
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseRam|FALSE|BOOLEAN|0x00000022
+
+  ## Platform BDS PCD to control whether to dispatch additional option rom, e.g.: PXE, AHCI
+  gPlatformModuleTokenSpaceGuid.PcdBdsDispatchAdditionalOprom|TRUE|BOOLEAN|0x00000024
+
+  #new added feature for BIOS usb recovery
+  gEfiIchTokenSpaceGuid.PcdEhciRecoveryEnabled|TRUE|BOOLEAN|0x00000026
+
+[PcdsDynamic,PcdsDynamicEx]
+  gPlatformModuleTokenSpaceGuid.PcdInConfigMode|FALSE|BOOLEAN|0x80000001
+  gPlatformModuleTokenSpaceGuid.PcdConnectUSBKeyboardonWaitForKeyStroke|FALSE|BOOLEAN|0x80000002
+  gPlatformModuleTokenSpaceGuid.PcdEnableWatchdogSwSmiInputValue|0|UINT8|0x80000003
+#
+#device firmware update support
+#
+#I2C and SPI support
+[Protocols]
+
+  gEfiMmioDeviceProtocolGuid = { 0x24486226, 0xf8c2, 0x41f5, { 0xb9, 0xdd, 0x78, 0x3e, 0x9e, 0x56, 0xde, 0xa0 } }
+  gEfiI2cBusConfigurationManagementProtocolGuid = { 0x75032015, 0xd156, 0x423e, { 0xbf, 0xa3, 0x7a, 0x65, 0xab, 0xa4, 0x71, 0x5 } }
+  gEfiI2cAcpiProtocolGuid = { 0xf30c2915, 0x5782, 0x4e6a, { 0xa8, 0x46, 0x5, 0xba, 0xbc, 0xe7, 0xb6, 0xa0 } }
+  gEfiI2cMasterProtocolGuid = { 0x578c315a, 0x68cf, 0x4e81, { 0xb5, 0xc6, 0x22, 0xdb, 0x40, 0xd0, 0x10, 0xbc } }
+  gEfiI2cHostProtocolGuid = { 0x70b221af, 0xfdff, 0x4fde, { 0x99, 0x68, 0x1a, 0xf6, 0x23, 0xa9, 0x56, 0xd9 } }
+  gEfiI2cBusProtocolGuid = { 0x9fa1b225, 0x3346, 0x461b, { 0xa0, 0x69, 0xed, 0x1, 0xb6, 0x73, 0xd2, 0x40 } }
+  gEfiI2cSlaveProtocolGuid = { 0xf2c1910e, 0xf5c9, 0x4b72, { 0xb2, 0x43, 0x6d, 0x59, 0x9, 0x6a, 0x79, 0xf0 } }
+
+#  gEfiSpiAcpiProtocolGuid = { 0x9f49a879, 0x3d71, 0x42b3, { 0xa0, 0xad, 0xdd, 0xb1, 0xf3, 0x30, 0x10, 0xa3 } }
+#  gEfiSpiHostProtocolGuid = { 0x951b65e5, 0x8872, 0x41ed, { 0xad, 0x1d, 0xd5, 0x68, 0x1f, 0x4a, 0xf0, 0x33 } }
+#  gEfiSpiBusProtocolGuid =  { 0x137b3044, 0xf6d7, 0x473e, { 0xa6, 0x25, 0x9f, 0xb9, 0x25, 0x5, 0xc1, 0x80 } }
+
+#  gLpssDummyProtocolGuid = { 0xaf4cc162, 0xd41c, 0x455a, { 0xab, 0x45, 0x6d, 0xbc, 0xc1, 0xcd, 0x32, 0xf3 } }
+  gEfiSpiProtocolGuid               = { 0x1156efc6, 0xea32, 0x4396, { 0xb5, 0xd5, 0x26, 0x93, 0x2e, 0x83, 0xc3, 0x13 }}
+  gEfiGpioOperationProtocolGuid     = { 0x38DDFE8F, 0x8991, 0x44AA, { 0x98, 0x89, 0x83, 0xF4, 0x91, 0x84, 0x65, 0xB0 }}
+  gEfiEsrtOperationProtocolGuid     = { 0x4549AB47, 0x6E60, 0x4293, { 0xB9, 0x1D, 0x31, 0xB6, 0x10, 0xAD, 0x80, 0x56 }}
+
+[Guids]
+  gEfiFwDisplayCapsuleGuid       = { 0x3b8c8162, 0x188c, 0x46a4, { 0xae, 0xc9, 0xbe, 0x43, 0xf1, 0xd6, 0x56, 0x97 } }
+  gEfiFirmwareClassGuid          = { 0xb122a262, 0x3551, 0x4f48, { 0x88, 0x92, 0x55, 0xf6, 0xc0, 0x61, 0x42, 0x90 } }
+  gEfiDFUVerGuid                 = { 0x0dc73aed, 0xcbf6, 0x4a25, { 0xa6, 0x8d, 0x59, 0xc8, 0x0f, 0x44, 0xc7, 0xc3 } }
+  gEfiEsrtTableGuid              = { 0xb122a263, 0x3661, 0x4f68, { 0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80 } }
+  gEfiCapsuleCrashLogVarGuid     = { 0xf3ff1468, 0x04ba, 0x4966, { 0x9f, 0xb2, 0xe4, 0xa7, 0x90, 0x05, 0x46, 0x50 } }
+  gEfiCapsuleCrashGuid           = { 0x0e1d2972, 0x65af, 0x4ac1, { 0xbf, 0xa3, 0xce, 0xf4, 0xab, 0x0c, 0x38, 0xfe } }
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf
new file mode 100644
index 0000000000..098602b9d8
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf
@@ -0,0 +1,1073 @@
+#/** @file
+# FDF file of Platform.
+#
+# Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#**/
+
+[Defines]
+DEFINE FLASH_BASE       = 0xFFC00000     #The base address of the 4Mb FLASH Device.
+DEFINE FLASH_SIZE       = 0x00400000     #The flash size in bytes of the 4Mb FLASH Device.
+DEFINE FLASH_BLOCK_SIZE = 0x1000        #The block size in bytes of the 4Mb FLASH Device.
+DEFINE FLASH_NUM_BLOCKS = 0x400           #The number of blocks in 4Mb FLASH Device.
+DEFINE FLASH_AREA_BASE_ADDRESS                                = 0xFF800000
+DEFINE FLASH_AREA_SIZE                                        = 0x00800000
+
+DEFINE FLASH_REGION_VLVMICROCODE_OFFSET                       = 0x00000000
+DEFINE FLASH_REGION_VLVMICROCODE_SIZE                         = 0x00040000
+DEFINE FLASH_REGION_VLVMICROCODE_BASE                         = 0xFFC00000
+
+DEFINE FLASH_REGION_VPD_OFFSET                                = 0x00040000
+DEFINE FLASH_REGION_VPD_SIZE                                  = 0x0003E000
+
+DEFINE FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_WORKING_OFFSET = 0x0007E000
+DEFINE FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_WORKING_SIZE   = 0x00002000
+
+
+DEFINE FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_SPARE_OFFSET   = 0x00080000
+DEFINE FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_SPARE_SIZE     = 0x00040000
+
+!if $(MINNOW2_FSP_BUILD) == TRUE
+DEFINE FLASH_REGION_FSPBIN_OFFSET                             = 0x000C0000
+DEFINE FLASH_REGION_FSPBIN_SIZE                               = 0x00048000
+DEFINE FLASH_REGION_FSPBIN_BASE                               = 0xFFCC0000
+
+DEFINE FLASH_REGION_AZALIABIN_OFFSET                          = 0x00108000
+DEFINE FLASH_REGION_AZALIABIN_SIZE                            = 0x00008000
+DEFINE FLASH_REGION_AZALIABIN_BASE                            = 0xFFD08000
+
+!endif
+
+DEFINE FLASH_REGION_FVMAIN_OFFSET                             = 0x00110000
+DEFINE FLASH_REGION_FVMAIN_SIZE                               = 0x00210000
+
+DEFINE FLASH_REGION_FV_RECOVERY2_OFFSET                       = 0x00320000
+DEFINE FLASH_REGION_FV_RECOVERY2_SIZE                         = 0x00070000
+
+DEFINE FLASH_REGION_FV_RECOVERY_OFFSET                        = 0x00390000
+DEFINE FLASH_REGION_FV_RECOVERY_SIZE                          = 0x00070000
+
+################################################################################
+#
+# FD Section
+# The [FD] Section is made up of the definition statements and a
+# description of what goes into  the Flash Device Image.  Each FD section
+# defines one flash "device" image.  A flash device image may be one of
+# the following: Removable media bootable image (like a boot floppy
+# image,) an Option ROM image (that would be "flashed" into an add-in
+# card,) a System "Flash"  image (that would be burned into a system's
+# flash) or an Update ("Capsule") image that will be used to update and
+# existing system flash.
+#
+################################################################################
+[FD.Vlv]
+BaseAddress   = $(FLASH_BASE)|gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress #The base address of the 3Mb FLASH Device.
+Size          = $(FLASH_SIZE)|gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize        #The flash size in bytes of the 3Mb FLASH Device.
+ErasePolarity = 1
+BlockSize     = $(FLASH_BLOCK_SIZE)          #The block size in bytes of the 3Mb FLASH Device.
+NumBlocks     = $(FLASH_NUM_BLOCKS)          #The number of blocks in 3Mb FLASH Device.
+
+#
+#Flash location override based on actual flash map
+#
+SET gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress            = $(FLASH_AREA_BASE_ADDRESS)
+SET gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize                   = $(FLASH_AREA_SIZE)
+
+SET gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress = $(FLASH_REGION_VLVMICROCODE_BASE) + 0x60
+SET gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize = $(FLASH_REGION_VLVMICROCODE_SIZE) - 0x60
+
+!if $(MINNOW2_FSP_BUILD) == TRUE
+# put below PCD value setting into dsc file
+#SET gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress                = $(FLASH_REGION_VLVMICROCODE_BASE)
+#SET gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize             = $(FLASH_REGION_VLVMICROCODE_SIZE)
+#SET gFspWrapperTokenSpaceGuid.PcdFlashMicroCodeOffset                    = 0x60
+#SET gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheAddress                   = $(FLASH_AREA_BASE_ADDRESS)
+#SET gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheSize                      = $(FLASH_AREA_SIZE)
+#SET gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase                          = $(FLASH_REGION_FSPBIN_BASE)
+#SET gFspWrapperTokenSpaceGuid.PcdFlashFvFspSize                          = $(FLASH_REGION_FSPBIN_SIZE)
+
+!endif
+################################################################################
+#
+# Following are lists of FD Region layout which correspond to the locations of different
+# images within the flash device.
+#
+# Regions must be defined in ascending order and may not overlap.
+#
+# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
+# the pipe "|" character, followed by the size of the region, also in hex with the leading
+# "0x" characters. Like:
+# Offset|Size
+# PcdOffsetCName|PcdSizeCName
+# RegionType <FV, DATA, or FILE>
+# Fv Size can be adjusted; FVMAIN_COMPACT can be reduced to 0x120000, and FV_RECOVERY can be enlarged to 0x80000
+#
+################################################################################
+  #
+  # CPU Microcodes
+  #
+
+$(FLASH_REGION_VLVMICROCODE_OFFSET)|$(FLASH_REGION_VLVMICROCODE_SIZE)
+gPlatformModuleTokenSpaceGuid.PcdFlashMicroCodeAddress|gPlatformModuleTokenSpaceGuid.PcdFlashMicroCodeSize
+FV = MICROCODE_FV
+$(FLASH_REGION_VPD_OFFSET)|$(FLASH_REGION_VPD_SIZE)
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+#NV_VARIABLE_STORE
+DATA = {
+  ## This is the EFI_FIRMWARE_VOLUME_HEADER
+  # ZeroVector []
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  # FileSystemGuid: gEfiSystemNvDataFvGuid         =
+  #  { 0xFFF12B8D, 0x7696, 0x4C8B, { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }}
+  0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
+  0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
+  # FvLength: 0x80000
+  0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+  #Signature "_FVH"       #Attributes
+  0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,
+  #HeaderLength #CheckSum #ExtHeaderOffset #Reserved #Revision
+  0x48, 0x00, 0x2A, 0x09, 0x00, 0x00, 0x00, 0x02,
+  #Blockmap[0]: 7 Blocks * 0x10000 Bytes / Block
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+  #Blockmap[1]: End
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  ## This is the VARIABLE_STORE_HEADER
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  #Signature: gEfiAuthenticatedVariableGuid =
+  #  { 0xaaf32c78, 0x947b, 0x439a, { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }}
+  0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,
+  0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,
+!else
+  #Signature: gEfiVariableGuid =
+  #  { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }}
+  0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41,
+  0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d,
+!endif
+  #Size: 0x3E000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x03DFB8
+  # This can speed up the Variable Dispatch a bit.
+  0xB8, 0xDF, 0x03, 0x00,
+  #FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
+  0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+
+$(FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_WORKING_OFFSET)|$(FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_WORKING_SIZE)
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+#NV_FTW_WORKING
+DATA = {
+  # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid         =
+  #  { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95 }}
+  0x2B, 0x29, 0x58, 0x9E, 0x68, 0x7C, 0x7D, 0x49,
+  0xA0, 0xCE, 0x65, 0x0,  0xFD, 0x9F, 0x1B, 0x95,
+
+  # Crc:UINT32            #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
+  0xE2, 0x33, 0xF2, 0x3,  0xFE, 0xFF, 0xFF, 0xFF,
+  # WriteQueueSize: UINT64 #Size: 0x2000 - 0x20 (FTW_WORKING_HEADER) = 0x1FE0
+  0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+$(FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_SPARE_OFFSET)|$(FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_SPARE_SIZE)
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+
+!if $(MINNOW2_FSP_BUILD) == TRUE
+
+  $(FLASH_REGION_FSPBIN_OFFSET)|$(FLASH_REGION_FSPBIN_SIZE)
+  gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase|gFspWrapperTokenSpaceGuid.PcdFlashFvFspSize
+  FILE = Vlv2SocBinPkg/FspBinary/FvFsp.bin
+
+
+  $(FLASH_REGION_AZALIABIN_OFFSET)|$(FLASH_REGION_AZALIABIN_SIZE)
+  FILE = Vlv2TbltDevicePkg/FspAzaliaConfigData/AzaliaConfig.bin
+
+!endif
+
+  #
+  # Main Block
+  #
+$(FLASH_REGION_FVMAIN_OFFSET)|$(FLASH_REGION_FVMAIN_SIZE)
+gPlatformModuleTokenSpaceGuid.PcdFlashFvMainBase|gPlatformModuleTokenSpaceGuid.PcdFlashFvMainSize
+FV = FVMAIN_COMPACT
+
+  #
+  # FV Recovery#2
+  #
+$(FLASH_REGION_FV_RECOVERY2_OFFSET)|$(FLASH_REGION_FV_RECOVERY2_SIZE)
+gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Base|gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Size
+FV = FVRECOVERY2
+
+  #
+  # FV Recovery
+  #
+$(FLASH_REGION_FV_RECOVERY_OFFSET)|$(FLASH_REGION_FV_RECOVERY_SIZE)
+gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoveryBase|gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoverySize
+FV = FVRECOVERY
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file.  This section also defines order the components and modules are positioned
+# within the image.  The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+[FV.MICROCODE_FV]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = FALSE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+FILE RAW = 197DB236-F856-4924-90F8-CDF12FB875F3 {
+  $(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/$(DXE_ARCHITECTURE)/MicrocodeUpdates.bin
+}
+
+!if $(RECOVERY_ENABLE)
+[FV.FVRECOVERY_COMPONENTS]
+FvAlignment        = 16         #FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+INF  RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchUsb.inf
+INF  MdeModulePkg/Bus/Pci/EhciPei/EhciPei.inf
+INF  MdeModulePkg/Bus/Usb/UsbBusPei/UsbBusPei.inf
+INF  MdeModulePkg/Bus/Usb/UsbBotPei/UsbBotPei.inf
+INF  FatPkg/FatPei/FatPei.inf
+INF  MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf
+INF  SignedCapsulePkg/Universal/RecoveryModuleLoadPei/RecoveryModuleLoadPei.inf
+!endif
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file.  This section also defines order the components and modules are positioned
+# within the image.  The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+[FV.FVRECOVERY2]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16         #FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = B73FE497-B92E-416e-8326-45AD0D270092
+
+
+
+INF $(PLATFORM_PACKAGE)/PlatformInitPei/PlatformInitPei.inf
+
+!if $(MINNOW2_FSP_BUILD) == FALSE
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchSmbusArpDisabled.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/VlvInitPeim.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchInitPeim.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchSpiPeim.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PeiSmmAccess.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PeiSmmControl.inf
+INF UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/MpS3.inf
+!endif
+
+# INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PiSmmCommunicationPei.inf
+!if $(TPM_ENABLED) == TRUE
+INF SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
+INF SecurityPkg/Tcg/TcgPei/TcgPei.inf
+INF SecurityPkg/Tcg/PhysicalPresencePei/PhysicalPresencePei.inf
+!endif
+!if $(FTPM_ENABLE) == TRUE
+INF  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf #use PCD config
+!endif
+INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+
+!if $(ACPI50_ENABLE) == TRUE
+ INF MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.inf
+!endif
+!if $(PERFORMANCE_ENABLE) == TRUE
+INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+!endif
+
+!if $(RECOVERY_ENABLE)
+FILE FV_IMAGE = 1E9D7604-EF45-46a0-BD8A-71AC78C17AC1 {
+  SECTION PEI_DEPEX_EXP = {gEfiPeiMemoryDiscoveredPpiGuid AND gEfiPeiBootInRecoveryModePpiGuid}
+  SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF {    # LZMA COMPRESS GUID
+    SECTION FV_IMAGE = FVRECOVERY_COMPONENTS
+  }
+}
+!endif
+
+[FV.FVRECOVERY]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16         #FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = B73FE497-B92E-416e-8326-45AD0D270091
+
+
+!if $(MINNOW2_FSP_BUILD) == TRUE
+INF IntelFspWrapperPkg/FspWrapperSecCore/FspWrapperSecCore.inf
+!else
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/SecCore.inf
+!endif
+
+INF MdeModulePkg/Core/Pei/PeiMain.inf
+!if $(MINNOW2_FSP_BUILD) == TRUE
+INF Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.inf
+INF IntelFspWrapperPkg/FspInitPei/FspInitPei.inf
+!endif
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/CpuPeim.inf
+INF MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
+INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+
+INF $(PLATFORM_PACKAGE)/PlatformPei/PlatformPei.inf
+
+!if $(MINNOW2_FSP_BUILD) == FALSE
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/SeCUma.inf
+!endif
+
+!if $(FTPM_ENABLE) == TRUE
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/fTPMInitPeim.inf
+!endif
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  INF  SourceLevelDebugPkg/DebugAgentPei/DebugAgentPei.inf
+!endif
+
+
+!if $(CAPSULE_ENABLE) == TRUE
+INF  MdeModulePkg/Universal/CapsulePei/CapsulePei.inf
+!if $(DXE_ARCHITECTURE) == "X64"
+INF  MdeModulePkg/Universal/CapsulePei/CapsuleX64.inf
+!endif
+!endif
+
+!if $(MINNOW2_FSP_BUILD) == FALSE
+!if $(PCIESC_ENABLE) == TRUE
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchEarlyInitPeim.inf
+!endif
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/MemoryInit.inf
+!endif
+
+INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+
+[FV.FVMAIN]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = A881D567-6CB0-4eee-8435-2E72D33E45B5
+
+APRIORI DXE {
+  INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+  INF  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+  INF  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+  }
+
+FILE FREEFORM = C3E36D09-8294-4b97-A857-D5288FE33E28 {
+    SECTION RAW = $(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/$(DXE_ARCHITECTURE)/BiosId.bin
+  }
+
+  #
+  # EDK II Related Platform codes
+  #
+
+  !if $(MINNOW2_FSP_BUILD) == TRUE
+  INF IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.inf
+  !endif
+
+INF MdeModulePkg/Core/Dxe/DxeMain.inf
+INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+!if $(ACPI50_ENABLE) == TRUE
+INF  MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf
+INF  MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.inf
+!endif
+
+
+INF IntelFrameworkModulePkg/Universal/CpuIoDxe/CpuIoDxe.inf
+INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
+INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+INF MdeModulePkg/Universal/ReportStatusCodeRouter/Smm/ReportStatusCodeRouterSmm.inf
+INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+INF UefiCpuPkg/CpuDxe/CpuDxe.inf
+INF $(PLATFORM_PACKAGE)/Metronome/Metronome.inf
+INF IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf
+!if $(ARCH) == IA32
+INF USE=IA32 MdeModulePkg/Logo/Logo.inf
+!else
+INF USE=X64 MdeModulePkg/Logo/Logo.inf
+!endif
+INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+INF IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3SaveDxe.inf
+
+INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
+INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
+INF $(PLATFORM_PACKAGE)/FvbRuntimeDxe/FvbSmm.inf
+INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSpiSmm.inf
+!if $(SECURE_BOOT_ENABLE)
+INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+!endif
+
+INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+
+INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+INF PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
+INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+INF $(PLATFORM_PACKAGE)/FvbRuntimeDxe/FvbRuntimeDxe.inf
+
+
+INF $(PLATFORM_PACKAGE)/PlatformSetupDxe/PlatformSetupDxe.inf
+
+!if $(DATAHUB_ENABLE) == TRUE
+INF IntelFrameworkModulePkg/Universal/DataHubDxe/DataHubDxe.inf
+!endif
+INF IntelFrameworkModulePkg/Universal/StatusCode/DatahubStatusCodeHandlerDxe/DatahubStatusCodeHandlerDxe.inf
+INF MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/Dptf.inf
+
+  #
+  # EDK II Related Silicon codes
+  #
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchS3SupportDxe.inf
+
+!if $(USE_HPET_TIMER) == TRUE
+INF PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf
+!else
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmartTimer.inf
+!endif
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmmControl.inf
+
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSmbusDxe.inf
+
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/IntelPchLegacyInterrupt.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchReset.inf
+
+!if $(MINNOW2_FSP_BUILD) == FALSE
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchInitDxe.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchInitSmm.inf
+!endif
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSmiDispatcher.inf
+!if $(PCIESC_ENABLE) == TRUE
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchPcieSmm.inf
+!endif
+
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSpiRuntime.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchPolicyInitDxe.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchBiosWriteProtect.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmmAccess.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PciHostBridge.inf
+!if $(MINNOW2_FSP_BUILD) == FALSE
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/VlvInitDxe.inf
+!else
+INF IntelFrameworkModulePkg/Universal/LegacyRegionDxe/LegacyRegionDxe.inf
+INF Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInitDxe.inf
+!endif
+!if $(MINNOW2_FSP_BUILD) == FALSE
+  !if $(SEC_ENABLE) == TRUE
+  INF  RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/HeciDrv.inf
+  INF  RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SeCPolicyInitDxe.inf
+  !endif
+!endif
+!if $(TPM_ENABLED) == TRUE
+INF SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf
+INF SecurityPkg/Tcg/TcgDxe/TcgDxe.inf
+INF RuleOverride = DRIVER_ACPITABLE SecurityPkg/Tcg/TcgSmm/TcgSmm.inf
+!endif
+!if $(FTPM_ENABLE) == TRUE
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/Tpm2DeviceSeCPei.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/Tpm2DeviceSeCDxe.inf
+INF SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf
+INF SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/FtpmSmm.inf
+!endif
+
+#
+# EDK II Related Platform codes
+#
+INF $(PLATFORM_PACKAGE)/PlatformSmm/PlatformSmm.inf
+INF $(PLATFORM_PACKAGE)/PlatformInfoDxe/PlatformInfoDxe.inf
+INF $(PLATFORM_PACKAGE)/PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf
+INF $(PLATFORM_PACKAGE)/PlatformDxe/PlatformDxe.inf
+INF $(PLATFORM_PACKAGE)/PciPlatform/PciPlatform.inf
+INF $(PLATFORM_PACKAGE)/SaveMemoryConfig/SaveMemoryConfig.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PlatformCpuPolicy.inf
+INF $(PLATFORM_PACKAGE)/PpmPolicy/PpmPolicy.inf
+INF $(PLATFORM_PACKAGE)/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.inf
+!if $(GOP_DRIVER_ENABLE) == TRUE
+ INF $(PLATFORM_PACKAGE)/PlatformGopPolicy/PlatformGopPolicy.inf
+ FILE DRIVER = FF0C8745-3270-4439-B74F-3E45F8C77064 {
+  SECTION DXE_DEPEX_EXP = {gPlatformGOPPolicyGuid}
+  SECTION PE32 = Vlv2SocBinPkg/GOP/7.2.1011/RELEASE_VS2008x86/$(DXE_ARCHITECTURE)/IntelGopDriver.efi
+  SECTION UI = "IntelGopDriver"
+}
+!endif
+
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PnpDxe.inf
+  #
+  # SMM
+  #
+INF MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
+INF MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
+INF UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+
+INF UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
+INF MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
+INF UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
+INF $(PLATFORM_PACKAGE)/SmmSwDispatch2OnSmmSwDispatchThunk/SmmSwDispatch2OnSmmSwDispatchThunk.inf
+
+#
+# Remove the following two SMM binary modules that prevent platform from booting to UEFI Shell
+#
+#INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PowerManagement2.inf
+#INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/DigitalThermalSensor.inf
+
+  #
+  # ACPI
+  #
+INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
+INF $(PLATFORM_PACKAGE)/BootScriptSaveDxe/BootScriptSaveDxe.inf
+INF IntelFrameworkModulePkg/Universal/Acpi/AcpiSupportDxe/AcpiSupportDxe.inf
+INF RuleOverride = ACPITABLE2 Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/PowerManagementAcpiTables.inf
+
+INF RuleOverride = ACPITABLE $(PLATFORM_RC_PACKAGE)/AcpiTablesPCAT/AcpiTables.inf
+
+INF $(PLATFORM_PACKAGE)/AcpiPlatform/AcpiPlatform.inf
+
+INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
+
+  #
+  # PCI
+  #
+INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/ISPDxe.inf
+
+
+#
+# ISA
+#
+INF $(PLATFORM_PACKAGE)/Wpce791/Wpce791.inf
+INF IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBusDxe.inf
+INF IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaIoDxe.inf
+!if $(SOURCE_DEBUG_ENABLE) != TRUE
+INF  IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf
+!endif
+#INF IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf
+#INF IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf
+
+#
+# SDIO
+#
+#INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/MmcHost.inf
+#INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/MmcMediaDevice.inf
+#
+# IDE/SCSI/AHCI
+#
+INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+
+INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+
+INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+!if $(SATA_ENABLE) == TRUE
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SataController.inf
+#
+
+#
+INF MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+INF MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+!if $(SCSI_ENABLE) == TRUE
+INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+!endif
+#
+!endif
+# Console
+#
+INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+INF IntelFrameworkModulePkg/Universal/Console/VgaClassDxe/VgaClassDxe.inf
+INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  #
+  # USB
+  #
+!if $(USB_ENABLE) == TRUE
+INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+INF MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
+INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+INF MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
+INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
+!endif
+
+
+  #
+  # SMBIOS
+  #
+INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+INF $(PLATFORM_PACKAGE)/SmBiosMiscDxe/SmBiosMiscDxe.inf
+
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmbiosMemory.inf
+
+
+#
+# FAT file system
+#
+INF FatPkg/EnhancedFatDxe/Fat.inf
+
+#
+# UEFI Shell
+#
+INF  ShellPkg/Application/Shell/Shell.inf
+
+#
+# dp command
+#
+!if $(PERFORMANCE_ENABLE) == TRUE
+INF ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf
+!endif
+
+!if $(GOP_DRIVER_ENABLE) == TRUE
+FILE FREEFORM = 878AC2CC-5343-46F2-B563-51F89DAF56BA {
+  SECTION RAW = Vlv2SocBinPkg/GOP/7.2.1011/VBT/MNW2/Vbt.bin
+  SECTION UI = "IntelGopVbt"
+}
+!endif
+
+#
+# Network Modules
+#
+!if $(NETWORK_ENABLE) == TRUE
+  FILE DRIVER = 22DE1691-D65D-456a-993E-A253DD1F308C {
+    SECTION PE32 = Vlv2SocBinPkg/UNDI/RtkUndiDxe/$(DXE_ARCHITECTURE)/RtkUndiDxe.efi
+    SECTION UI = "UNDI"
+  }
+  INF  MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf
+  INF  MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
+  INF  MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
+  INF  MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
+  INF  MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
+  INF  MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+  INF  MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
+  INF  MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
+  INF  NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
+  INF  NetworkPkg/TcpDxe/TcpDxe.inf
+  !if $(NETWORK_IP6_ENABLE) == TRUE
+  INF  NetworkPkg/Ip6Dxe/Ip6Dxe.inf
+  INF  NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
+  INF  NetworkPkg/Udp6Dxe/Udp6Dxe.inf
+  INF  NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
+  !endif
+  !if $(NETWORK_VLAN_ENABLE) == TRUE
+  INF  MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf
+  !endif
+  !if $(NETWORK_ISCSI_ENABLE) == TRUE
+    INF  NetworkPkg/IScsiDxe/IScsiDxe.inf
+  !endif
+!endif
+
+!if $(CAPSULE_ENABLE)
+INF  MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxe.inf
+
+#
+# Minnow Max System Firmware FMP
+#
+INF  FILE_GUID = $(FMP_MINNOW_MAX_SYSTEM) FmpDevicePkg/FmpDxe/FmpDxe.inf
+
+#
+# Sample Device FMP
+#
+INF  FILE_GUID = $(FMP_GREEN_SAMPLE_DEVICE) FmpDevicePkg/FmpDxe/FmpDxe.inf
+INF  FILE_GUID = $(FMP_BLUE_SAMPLE_DEVICE)  FmpDevicePkg/FmpDxe/FmpDxe.inf
+INF  FILE_GUID = $(FMP_RED_SAMPLE_DEVICE)   FmpDevicePkg/FmpDxe/FmpDxe.inf
+
+!endif
+
+!if $(MICOCODE_CAPSULE_ENABLE)
+INF  IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.inf
+!endif
+
+!if $(RECOVERY_ENABLE)
+FILE FREEFORM = PCD(gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiRsa2048Sha256TestPublicKeyFileGuid) {
+     SECTION RAW = BaseTools/Source/Python/Rsa2048Sha256Sign/TestSigningPublicKey.bin
+     SECTION UI = "Rsa2048Sha256TestSigningPublicKey"
+     }
+!endif
+
+[FV.FVMAIN_COMPACT]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+
+
+FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+!if $(LZMA_ENABLE) == TRUE
+# LZMA Compress
+       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+          SECTION FV_IMAGE = FVMAIN
+       }
+!else
+!if $(DXE_COMPRESS_ENABLE) == TRUE
+# Tiano Compress
+       SECTION GUIDED A31280AD-481E-41B6-95E8-127F4C984779 PROCESSING_REQUIRED = TRUE {
+          SECTION FV_IMAGE = FVMAIN
+       }
+!else
+# No Compress
+       SECTION COMPRESS PI_NONE {
+          SECTION FV_IMAGE = FVMAIN
+       }
+!endif
+!endif
+     }
+
+[FV.SETUP_DATA]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+#NumBlocks         = 0x10
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+################################################################################
+#
+# Rules are use with the [FV] section's module INF type to define
+# how an FFS file is created for a given INF file. The following Rule are the default
+# rules for the different module type. User can add the customized rules to define the
+# content of the FFS file.
+#
+################################################################################
+[Rule.Common.SEC]
+  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+    PE32  PE32    Align = 8       $(INF_OUTPUT)/$(MODULE_NAME).efi
+    RAW BIN       Align = 16      |.com
+  }
+
+[Rule.Common.SEC.BINARY]
+  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+    PE32  PE32    Align = 8       |.efi
+    RAW BIN       Align = 16      |.com
+  }
+
+[Rule.Common.PEI_CORE]
+  FILE PEI_CORE = $(NAMED_GUID)            {
+    PE32       PE32    Align = Auto      $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.PEIM]
+  FILE PEIM = $(NAMED_GUID) {
+     PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+     PE32        PE32   Align = Auto     $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI        STRING="$(MODULE_NAME)" Optional
+     VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.PEIM.BINARY]
+  FILE PEIM = $(NAMED_GUID) {
+     PEI_DEPEX PEI_DEPEX Optional        |.depex
+     PE32        PE32   Align = Auto     |.efi
+     UI        STRING="$(MODULE_NAME)" Optional
+     VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.PEIM.BIOSID]
+  FILE PEIM = $(NAMED_GUID) {
+     RAW       BIN                       BiosId.bin
+     PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+     PE32        PE32   Align = Auto     $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI        STRING="$(MODULE_NAME)" Optional
+     VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.USER_DEFINED.APINIT]
+  FILE RAW = $(NAMED_GUID) Fixed Align=4K {
+     RAW SEC_BIN |.com
+     }
+#cjia 2011-07-21
+[Rule.Common.USER_DEFINED.LEGACY16]
+  FILE FREEFORM = $(NAMED_GUID) {
+     UI  STRING="$(MODULE_NAME)" Optional
+     RAW BIN |.bin
+     }
+#cjia
+
+[Rule.Common.USER_DEFINED.ASM16]
+  FILE FREEFORM = $(NAMED_GUID) {
+     UI  STRING="$(MODULE_NAME)" Optional
+     RAW BIN |.com
+   }
+
+[Rule.Common.DXE_CORE]
+  FILE DXE_CORE = $(NAMED_GUID) {
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_DRIVER.BINARY]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       |.depex
+    PE32      PE32                     |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_DRIVER.NATIVE_BINARY]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional      $(WORKSPACE)/$(PLATFORM_PACKAGE)/IntelGopDepex/IntelGopDriver.depex
+    PE32      PE32                    |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_DRIVER.BINARY]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       |.depex
+    PE32      PE32                     |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_DRIVER.DRIVER_ACPITABLE]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+    RAW ACPI  Optional                |.acpi
+    RAW ASL   Optional                |.aml
+  }
+
+[Rule.Common.DXE_RUNTIME_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_RUNTIME_DRIVER.BINARY]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       |.depex
+    PE32      PE32                     |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_SMM_DRIVER]
+  FILE SMM = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_SMM_DRIVER.BINARY]
+  FILE SMM = $(NAMED_GUID) {
+    SMM_DEPEX SMM_DEPEX                |.depex
+    PE32      PE32                     |.efi
+    RAW       BIN  Optional            |.aml
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_SMM_DRIVER.DRIVER_ACPITABLE]
+  FILE SMM = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+    RAW ACPI  Optional                |.acpi
+    RAW ASL   Optional                |.aml
+  }
+
+[Rule.Common.SMM_CORE]
+  FILE SMM_CORE = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.SMM_CORE.BINARY]
+  FILE SMM_CORE = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       |.depex
+    PE32      PE32                     |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION]
+  FILE APPLICATION = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION.UI]
+  FILE APPLICATION = $(NAMED_GUID) {
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="Enter Setup"
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.USER_DEFINED]
+  FILE FREEFORM = $(NAMED_GUID) {
+    UI  STRING="$(MODULE_NAME)" Optional
+    RAW BIN                |.bin
+  }
+
+[Rule.Common.USER_DEFINED.BINARY]
+  FILE FREEFORM = $(NAMED_GUID) {
+    UI  STRING="$(MODULE_NAME)" Optional
+    RAW BIN                |.bin
+  }
+
+[Rule.Common.USER_DEFINED.ACPITABLE]
+  FILE FREEFORM = $(NAMED_GUID) {
+    RAW ACPI  Optional            |.acpi
+    RAW ASL   Optional            |.aml
+  }
+
+[Rule.Common.USER_DEFINED.ACPITABLE2]
+  FILE FREEFORM = $(NAMED_GUID) {
+    RAW ASL   Optional            |.aml
+  }
+
+[Rule.Common.ACPITABLE]
+  FILE FREEFORM = $(NAMED_GUID) {
+    RAW ACPI  Optional            |.acpi
+    RAW ASL   Optional            |.aml
+  }
+
+[Rule.Common.PEIM.FMP_IMAGE_DESC]
+  FILE PEIM = $(NAMED_GUID) {
+     RAW BIN                  |.acpi
+     PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+     PE32      PE32    Align=4K          $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI       STRING="$(MODULE_NAME)" Optional
+     VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgConfig.dsc b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgConfig.dsc
new file mode 100644
index 0000000000..6d556c1be2
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgConfig.dsc
@@ -0,0 +1,107 @@
+#/** @file
+# platform configuration file.
+#
+# Copyright (c) 2012  - 2016, Intel Corporation. All rights reserved.<BR>
+#                                                                                  

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

+#
+#**/
+
+#
+# TRUE is ENABLE. FASLE is DISABLE.
+#
+
+#
+# FSP selection
+#
+DEFINE MINNOW2_FSP_BUILD = FALSE
+
+
+DEFINE SCSI_ENABLE = TRUE
+
+
+#
+# To enable extra configuration for clk gen
+#
+DEFINE CLKGEN_CONFIG_EXTRA_ENABLE=TRUE
+
+#
+# Feature selection
+#
+
+#
+# Select system timer which is used to produce Timer Arch Protocol:
+# TRUE  - HPET timer is used.
+# FALSE - 8254 timer is used.
+#
+DEFINE USE_HPET_TIMER = TRUE
+
+
+#
+# Feature selection
+#
+
+DEFINE TPM_ENABLED = FALSE
+
+DEFINE ACPI50_ENABLE = TRUE
+DEFINE PERFORMANCE_ENABLE = FALSE
+
+
+DEFINE LFMA_ENABLE = FALSE              # Load module at fixed address feature
+DEFINE DXE_COMPRESS_ENABLE = TRUE
+DEFINE DXE_CRC32_SECTION_ENABLE = TRUE
+DEFINE SSE2_ENABLE = FALSE
+
+DEFINE SECURE_BOOT_ENABLE = TRUE
+DEFINE USER_IDENTIFICATION_ENABLE = FALSE
+DEFINE VARIABLE_INFO_ENABLE = FALSE
+DEFINE S3_ENABLE = TRUE
+DEFINE CAPSULE_ENABLE = TRUE
+DEFINE CAPSULE_RESET_ENABLE = TRUE
+DEFINE RECOVERY_ENABLE = FALSE
+DEFINE MICOCODE_CAPSULE_ENABLE = TRUE
+
+DEFINE GOP_DRIVER_ENABLE = TRUE
+DEFINE DATAHUB_ENABLE = TRUE
+DEFINE DATAHUB_STATUS_CODE_ENABLE = TRUE
+DEFINE USB_ENABLE = TRUE
+
+DEFINE ISA_SERIAL_STATUS_CODE_ENABLE = TRUE
+DEFINE USB_SERIAL_STATUS_CODE_ENABLE = FALSE
+DEFINE RAM_SERIAL_STATUS_CODE_ENABLE = FALSE
+
+DEFINE ENBDT_S3_SUPPORT = TRUE
+
+DEFINE LZMA_ENABLE = TRUE
+DEFINE S4_ENABLE = TRUE
+DEFINE NETWORK_ENABLE = TRUE
+DEFINE NETWORK_IP6_ENABLE = TRUE
+DEFINE NETWORK_ISCSI_ENABLE = FALSE
+DEFINE NETWORK_VLAN_ENABLE = FALSE
+
+DEFINE SATA_ENABLE       = TRUE
+DEFINE PCIESC_ENABLE     = TRUE
+
+#
+# Enable source level debug default
+#
+DEFINE SOURCE_DEBUG_ENABLE     = FALSE
+
+#
+# Capsule Pubic Certificate.  Default is EDK_TEST.  Options are:
+#   SAMPLE_DEVELOPMENT                    - Only signtool SAMPLE_DEVELOPMENT
+#   SAMPLE_DEVELOPMENT_SAMPLE_PRODUCTION  - Both signtool SAMPLE_DEVELOPMENT and SAMPLE_PRODUCTION
+#   EDKII_TEST                            - Only openssl EDK II test certificate
+#   NEW_ROOT                              - Only openssl new VLV2 certificate
+#
+DEFINE CAPSULE_PKCS7_CERT = EDKII_TEST
+
+#
+# Define ESRT GUIDs for Firmware Management Protocol instances
+#
+DEFINE FMP_MINNOW_MAX_SYSTEM   = 4096267b-da0a-42eb-b5eb-fef31d207cb4
+DEFINE FMP_RED_SAMPLE_DEVICE   = 72E2945A-00DA-448E-9AA7-075AD840F9D4
+DEFINE FMP_BLUE_SAMPLE_DEVICE  = 149DA854-7D19-4FAA-A91E-862EA1324BE6
+DEFINE FMP_GREEN_SAMPLE_DEVICE = 79179BFD-704D-4C90-9E02-0AB8D968C18A
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGcc.fdf b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGcc.fdf
new file mode 100644
index 0000000000..1ba6124a69
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGcc.fdf
@@ -0,0 +1,1033 @@
+#/** @file
+# FDF file of Platform.
+#
+# Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#**/
+
+[Defines]
+DEFINE FLASH_BASE       = 0xFFC00000     #The base address of the 4Mb FLASH Device.
+DEFINE FLASH_SIZE       = 0x00400000     #The flash size in bytes of the 4Mb FLASH Device.
+DEFINE FLASH_BLOCK_SIZE = 0x1000        #The block size in bytes of the 4Mb FLASH Device.
+DEFINE FLASH_NUM_BLOCKS = 0x400           #The number of blocks in 4Mb FLASH Device.
+DEFINE FLASH_AREA_BASE_ADDRESS                                = 0xFF800000
+DEFINE FLASH_AREA_SIZE                                        = 0x00800000
+
+DEFINE FLASH_REGION_VLVMICROCODE_OFFSET                       = 0x00000000
+DEFINE FLASH_REGION_VLVMICROCODE_SIZE                         = 0x00040000
+DEFINE FLASH_REGION_VLVMICROCODE_BASE                         = 0xFFC00000
+
+DEFINE FLASH_REGION_VPD_OFFSET                                = 0x00040000
+DEFINE FLASH_REGION_VPD_SIZE                                  = 0x0003E000
+
+DEFINE FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_WORKING_OFFSET = 0x0007E000
+DEFINE FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_WORKING_SIZE   = 0x00002000
+
+
+DEFINE FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_SPARE_OFFSET   = 0x00080000
+DEFINE FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_SPARE_SIZE     = 0x00040000
+
+!if $(MINNOW2_FSP_BUILD) == TRUE
+DEFINE FLASH_REGION_FSPBIN_OFFSET                             = 0x000C0000
+DEFINE FLASH_REGION_FSPBIN_SIZE                               = 0x00048000
+DEFINE FLASH_REGION_FSPBIN_BASE                               = 0xFFCC0000
+
+DEFINE FLASH_REGION_AZALIABIN_OFFSET                          = 0x00108000
+DEFINE FLASH_REGION_AZALIABIN_SIZE                            = 0x00008000
+DEFINE FLASH_REGION_AZALIABIN_BASE                            = 0xFFD08000
+
+!endif
+
+DEFINE FLASH_REGION_FVMAIN_OFFSET                             = 0x00110000
+DEFINE FLASH_REGION_FVMAIN_SIZE                               = 0x00215000
+
+DEFINE FLASH_REGION_FV_RECOVERY2_OFFSET                       = 0x00325000
+DEFINE FLASH_REGION_FV_RECOVERY2_SIZE                         = 0x0006B000
+
+DEFINE FLASH_REGION_FV_RECOVERY_OFFSET                        = 0x00390000
+DEFINE FLASH_REGION_FV_RECOVERY_SIZE                          = 0x00070000
+
+################################################################################
+#
+# FD Section
+# The [FD] Section is made up of the definition statements and a
+# description of what goes into  the Flash Device Image.  Each FD section
+# defines one flash "device" image.  A flash device image may be one of
+# the following: Removable media bootable image (like a boot floppy
+# image,) an Option ROM image (that would be "flashed" into an add-in
+# card,) a System "Flash"  image (that would be burned into a system's
+# flash) or an Update ("Capsule") image that will be used to update and
+# existing system flash.
+#
+################################################################################
+[FD.Vlv]
+BaseAddress   = $(FLASH_BASE)|gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress #The base address of the 3Mb FLASH Device.
+Size          = $(FLASH_SIZE)|gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize        #The flash size in bytes of the 3Mb FLASH Device.
+ErasePolarity = 1
+BlockSize     = $(FLASH_BLOCK_SIZE)          #The block size in bytes of the 3Mb FLASH Device.
+NumBlocks     = $(FLASH_NUM_BLOCKS)          #The number of blocks in 3Mb FLASH Device.
+
+#
+#Flash location override based on actual flash map
+#
+SET gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress            = $(FLASH_AREA_BASE_ADDRESS)
+SET gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize                   = $(FLASH_AREA_SIZE)
+
+SET gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress = $(FLASH_REGION_VLVMICROCODE_BASE) + 0x60
+SET gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize = $(FLASH_REGION_VLVMICROCODE_SIZE) - 0x60
+
+!if $(MINNOW2_FSP_BUILD) == TRUE
+# put below PCD value setting into dsc file
+#SET gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress                = $(FLASH_REGION_VLVMICROCODE_BASE)
+#SET gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize             = $(FLASH_REGION_VLVMICROCODE_SIZE)
+#SET gFspWrapperTokenSpaceGuid.PcdFlashMicroCodeOffset                    = 0x60
+#SET gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheAddress                   = $(FLASH_AREA_BASE_ADDRESS)
+#SET gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheSize                      = $(FLASH_AREA_SIZE)
+#SET gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase                          = $(FLASH_REGION_FSPBIN_BASE)
+#SET gFspWrapperTokenSpaceGuid.PcdFlashFvFspSize                          = $(FLASH_REGION_FSPBIN_SIZE)
+
+!endif
+################################################################################
+#
+# Following are lists of FD Region layout which correspond to the locations of different
+# images within the flash device.
+#
+# Regions must be defined in ascending order and may not overlap.
+#
+# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
+# the pipe "|" character, followed by the size of the region, also in hex with the leading
+# "0x" characters. Like:
+# Offset|Size
+# PcdOffsetCName|PcdSizeCName
+# RegionType <FV, DATA, or FILE>
+# Fv Size can be adjusted; FVMAIN_COMPACT can be reduced to 0x120000, and FV_RECOVERY can be enlarged to 0x80000
+#
+################################################################################
+# Since the Fce tool don't have gcc version, we can't handle default variable in Linux,
+# so we hardcode the default value of variable here.
+# Please note that we MUST update the binary once the default value is changed.
+
+#
+  # CPU Microcodes
+  #
+
+$(FLASH_REGION_VLVMICROCODE_OFFSET)|$(FLASH_REGION_VLVMICROCODE_SIZE)
+gPlatformModuleTokenSpaceGuid.PcdFlashMicroCodeAddress|gPlatformModuleTokenSpaceGuid.PcdFlashMicroCodeSize
+FV = MICROCODE_FV
+$(FLASH_REGION_VPD_OFFSET)|$(FLASH_REGION_VPD_SIZE)
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+FILE = Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageVariable.bin
+
+$(FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_WORKING_OFFSET)|$(FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_WORKING_SIZE)
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+FILE = Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwWorking.bin
+
+$(FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_SPARE_OFFSET)|$(FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_SPARE_SIZE)
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+FILE = Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwSpare.bin
+
+!if $(MINNOW2_FSP_BUILD) == TRUE
+
+  $(FLASH_REGION_FSPBIN_OFFSET)|$(FLASH_REGION_FSPBIN_SIZE)
+  gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase|gFspWrapperTokenSpaceGuid.PcdFlashFvFspSize
+  FILE = Vlv2SocBinPkg/FspBinary/FvFsp.bin
+
+
+  $(FLASH_REGION_AZALIABIN_OFFSET)|$(FLASH_REGION_AZALIABIN_SIZE)
+  FILE = Vlv2TbltDevicePkg/FspAzaliaConfigData/AzaliaConfig.bin
+
+!endif
+
+  #
+  # Main Block
+  #
+$(FLASH_REGION_FVMAIN_OFFSET)|$(FLASH_REGION_FVMAIN_SIZE)
+gPlatformModuleTokenSpaceGuid.PcdFlashFvMainBase|gPlatformModuleTokenSpaceGuid.PcdFlashFvMainSize
+FV = FVMAIN_COMPACT
+
+  #
+  # FV Recovery#2
+  #
+$(FLASH_REGION_FV_RECOVERY2_OFFSET)|$(FLASH_REGION_FV_RECOVERY2_SIZE)
+gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Base|gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Size
+FV = FVRECOVERY2
+
+  #
+  # FV Recovery
+  #
+$(FLASH_REGION_FV_RECOVERY_OFFSET)|$(FLASH_REGION_FV_RECOVERY_SIZE)
+gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoveryBase|gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoverySize
+FV = FVRECOVERY
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file.  This section also defines order the components and modules are positioned
+# within the image.  The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+[FV.MICROCODE_FV]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = FALSE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+FILE RAW = 197DB236-F856-4924-90F8-CDF12FB875F3 {
+  $(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/$(DXE_ARCHITECTURE)/MicrocodeUpdates.bin
+}
+
+!if $(RECOVERY_ENABLE)
+[FV.FVRECOVERY_COMPONENTS]
+FvAlignment        = 16         #FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+INF  RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchUsb.inf
+INF  MdeModulePkg/Bus/Pci/EhciPei/EhciPei.inf
+INF  MdeModulePkg/Bus/Usb/UsbBusPei/UsbBusPei.inf
+INF  MdeModulePkg/Bus/Usb/UsbBotPei/UsbBotPei.inf
+INF  FatPkg/FatPei/FatPei.inf
+INF  MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf
+INF  SignedCapsulePkg/Universal/RecoveryModuleLoadPei/RecoveryModuleLoadPei.inf
+!endif
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file.  This section also defines order the components and modules are positioned
+# within the image.  The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+[FV.FVRECOVERY2]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16         #FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = B73FE497-B92E-416e-8326-45AD0D270092
+
+
+
+INF $(PLATFORM_PACKAGE)/PlatformInitPei/PlatformInitPei.inf
+
+!if $(MINNOW2_FSP_BUILD) == FALSE
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchSmbusArpDisabled.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/VlvInitPeim.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchInitPeim.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchSpiPeim.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PeiSmmAccess.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PeiSmmControl.inf
+INF UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/MpS3.inf
+!endif
+
+# INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PiSmmCommunicationPei.inf
+!if $(TPM_ENABLED) == TRUE
+INF SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
+INF SecurityPkg/Tcg/TcgPei/TcgPei.inf
+INF SecurityPkg/Tcg/PhysicalPresencePei/PhysicalPresencePei.inf
+!endif
+!if $(FTPM_ENABLE) == TRUE
+INF  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf #use PCD config
+!endif
+INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+
+!if $(ACPI50_ENABLE) == TRUE
+ INF MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.inf
+!endif
+!if $(PERFORMANCE_ENABLE) == TRUE
+INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+!endif
+
+!if $(RECOVERY_ENABLE)
+FILE FV_IMAGE = 1E9D7604-EF45-46a0-BD8A-71AC78C17AC1 {
+  SECTION PEI_DEPEX_EXP = {gEfiPeiMemoryDiscoveredPpiGuid AND gEfiPeiBootInRecoveryModePpiGuid}
+  SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF {    # LZMA COMPRESS GUID
+    SECTION FV_IMAGE = FVRECOVERY_COMPONENTS
+  }
+}
+!endif
+
+[FV.FVRECOVERY]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16         #FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = B73FE497-B92E-416e-8326-45AD0D270091
+
+
+!if $(MINNOW2_FSP_BUILD) == TRUE
+INF IntelFspWrapperPkg/FspWrapperSecCore/FspWrapperSecCore.inf
+!else
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/SecCore.inf
+!endif
+
+INF MdeModulePkg/Core/Pei/PeiMain.inf
+!if $(MINNOW2_FSP_BUILD) == TRUE
+INF Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.inf
+INF IntelFspWrapperPkg/FspInitPei/FspInitPei.inf
+!endif
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/CpuPeim.inf
+INF MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
+INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+
+INF $(PLATFORM_PACKAGE)/PlatformPei/PlatformPei.inf
+
+!if $(MINNOW2_FSP_BUILD) == FALSE
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/SeCUma.inf
+!endif
+
+!if $(FTPM_ENABLE) == TRUE
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/fTPMInitPeim.inf
+!endif
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  INF  SourceLevelDebugPkg/DebugAgentPei/DebugAgentPei.inf
+!endif
+
+
+!if $(CAPSULE_ENABLE) == TRUE
+INF  MdeModulePkg/Universal/CapsulePei/CapsulePei.inf
+!if $(DXE_ARCHITECTURE) == "X64"
+INF  MdeModulePkg/Universal/CapsulePei/CapsuleX64.inf
+!endif
+!endif
+
+!if $(MINNOW2_FSP_BUILD) == FALSE
+!if $(PCIESC_ENABLE) == TRUE
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchEarlyInitPeim.inf
+!endif
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/MemoryInit.inf
+!endif
+
+INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+
+[FV.FVMAIN]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = A881D567-6CB0-4eee-8435-2E72D33E45B5
+
+APRIORI DXE {
+  INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+  INF  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+  INF  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+  }
+
+FILE FREEFORM = C3E36D09-8294-4b97-A857-D5288FE33E28 {
+    SECTION RAW = $(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/$(DXE_ARCHITECTURE)/BiosId.bin
+  }
+
+  #
+  # EDK II Related Platform codes
+  #
+
+  !if $(MINNOW2_FSP_BUILD) == TRUE
+  INF IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.inf
+  !endif
+
+INF MdeModulePkg/Core/Dxe/DxeMain.inf
+INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+!if $(ACPI50_ENABLE) == TRUE
+INF  MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf
+INF  MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.inf
+!endif
+
+
+INF IntelFrameworkModulePkg/Universal/CpuIoDxe/CpuIoDxe.inf
+INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
+INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+INF MdeModulePkg/Universal/ReportStatusCodeRouter/Smm/ReportStatusCodeRouterSmm.inf
+INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+INF UefiCpuPkg/CpuDxe/CpuDxe.inf
+INF $(PLATFORM_PACKAGE)/Metronome/Metronome.inf
+INF IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf
+!if $(ARCH) == IA32
+INF USE=IA32 MdeModulePkg/Logo/Logo.inf
+!else
+INF USE=X64 MdeModulePkg/Logo/Logo.inf
+!endif
+INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+INF IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3SaveDxe.inf
+
+INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
+INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
+INF $(PLATFORM_PACKAGE)/FvbRuntimeDxe/FvbSmm.inf
+INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSpiSmm.inf
+!if $(SECURE_BOOT_ENABLE)
+INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+!endif
+
+INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+
+INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+INF PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
+INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+INF $(PLATFORM_PACKAGE)/FvbRuntimeDxe/FvbRuntimeDxe.inf
+
+
+INF $(PLATFORM_PACKAGE)/PlatformSetupDxe/PlatformSetupDxe.inf
+
+!if $(DATAHUB_ENABLE) == TRUE
+INF IntelFrameworkModulePkg/Universal/DataHubDxe/DataHubDxe.inf
+!endif
+INF IntelFrameworkModulePkg/Universal/StatusCode/DatahubStatusCodeHandlerDxe/DatahubStatusCodeHandlerDxe.inf
+INF MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/Dptf.inf
+
+  #
+  # EDK II Related Silicon codes
+  #
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchS3SupportDxe.inf
+
+!if $(USE_HPET_TIMER) == TRUE
+INF PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf
+!else
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmartTimer.inf
+!endif
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmmControl.inf
+
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSmbusDxe.inf
+
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/IntelPchLegacyInterrupt.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchReset.inf
+
+!if $(MINNOW2_FSP_BUILD) == FALSE
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchInitDxe.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchInitSmm.inf
+!endif
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSmiDispatcher.inf
+!if $(PCIESC_ENABLE) == TRUE
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchPcieSmm.inf
+!endif
+
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSpiRuntime.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchPolicyInitDxe.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchBiosWriteProtect.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmmAccess.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PciHostBridge.inf
+!if $(MINNOW2_FSP_BUILD) == FALSE
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/VlvInitDxe.inf
+!else
+INF IntelFrameworkModulePkg/Universal/LegacyRegionDxe/LegacyRegionDxe.inf
+INF Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInitDxe.inf
+!endif
+!if $(MINNOW2_FSP_BUILD) == FALSE
+  !if $(SEC_ENABLE) == TRUE
+  INF  RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/HeciDrv.inf
+  INF  RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SeCPolicyInitDxe.inf
+  !endif
+!endif
+!if $(TPM_ENABLED) == TRUE
+INF SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf
+INF SecurityPkg/Tcg/TcgDxe/TcgDxe.inf
+INF RuleOverride = DRIVER_ACPITABLE SecurityPkg/Tcg/TcgSmm/TcgSmm.inf
+!endif
+!if $(FTPM_ENABLE) == TRUE
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/Tpm2DeviceSeCPei.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/Tpm2DeviceSeCDxe.inf
+INF SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf
+INF SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/FtpmSmm.inf
+!endif
+
+#
+# EDK II Related Platform codes
+#
+INF $(PLATFORM_PACKAGE)/PlatformSmm/PlatformSmm.inf
+INF $(PLATFORM_PACKAGE)/PlatformInfoDxe/PlatformInfoDxe.inf
+INF $(PLATFORM_PACKAGE)/PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf
+INF $(PLATFORM_PACKAGE)/PlatformDxe/PlatformDxe.inf
+INF $(PLATFORM_PACKAGE)/PciPlatform/PciPlatform.inf
+INF $(PLATFORM_PACKAGE)/SaveMemoryConfig/SaveMemoryConfig.inf
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PlatformCpuPolicy.inf
+INF $(PLATFORM_PACKAGE)/PpmPolicy/PpmPolicy.inf
+INF $(PLATFORM_PACKAGE)/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.inf
+!if $(GOP_DRIVER_ENABLE) == TRUE
+ INF $(PLATFORM_PACKAGE)/PlatformGopPolicy/PlatformGopPolicy.inf
+ FILE DRIVER = FF0C8745-3270-4439-B74F-3E45F8C77064 {
+  SECTION DXE_DEPEX_EXP = {gPlatformGOPPolicyGuid}
+  SECTION PE32 = Vlv2SocBinPkg/GOP/7.2.1011/RELEASE_VS2008x86/$(DXE_ARCHITECTURE)/IntelGopDriver.efi
+  SECTION UI = "IntelGopDriver"
+}
+!endif
+
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PnpDxe.inf
+  #
+  # SMM
+  #
+INF MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
+INF MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
+INF UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+
+INF UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
+INF MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
+INF UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
+INF $(PLATFORM_PACKAGE)/SmmSwDispatch2OnSmmSwDispatchThunk/SmmSwDispatch2OnSmmSwDispatchThunk.inf
+
+#
+# Remove the following two SMM binary modules that prevent platform from booting to UEFI Shell
+#
+#INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PowerManagement2.inf
+#INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/DigitalThermalSensor.inf
+
+  #
+  # ACPI
+  #
+INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
+INF $(PLATFORM_PACKAGE)/BootScriptSaveDxe/BootScriptSaveDxe.inf
+INF IntelFrameworkModulePkg/Universal/Acpi/AcpiSupportDxe/AcpiSupportDxe.inf
+INF RuleOverride = ACPITABLE2 Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/PowerManagementAcpiTables.inf
+
+INF RuleOverride = ACPITABLE $(PLATFORM_RC_PACKAGE)/AcpiTablesPCAT/AcpiTables.inf
+
+INF $(PLATFORM_PACKAGE)/AcpiPlatform/AcpiPlatform.inf
+
+INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
+
+  #
+  # PCI
+  #
+INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/ISPDxe.inf
+
+
+#
+# ISA
+#
+INF $(PLATFORM_PACKAGE)/Wpce791/Wpce791.inf
+INF IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBusDxe.inf
+INF IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaIoDxe.inf
+!if $(SOURCE_DEBUG_ENABLE) != TRUE
+INF  IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf
+!endif
+#INF IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf
+#INF IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf
+
+#
+# SDIO
+#
+#INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/MmcHost.inf
+#INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/MmcMediaDevice.inf
+#
+# IDE/SCSI/AHCI
+#
+INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+
+INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+
+INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+!if $(SATA_ENABLE) == TRUE
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SataController.inf
+#
+
+#
+INF MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+INF MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+!if $(SCSI_ENABLE) == TRUE
+INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+!endif
+#
+!endif
+# Console
+#
+INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+INF IntelFrameworkModulePkg/Universal/Console/VgaClassDxe/VgaClassDxe.inf
+INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  #
+  # USB
+  #
+!if $(USB_ENABLE) == TRUE
+INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+INF MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
+INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+INF MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
+INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
+!endif
+
+
+  #
+  # SMBIOS
+  #
+INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+INF $(PLATFORM_PACKAGE)/SmBiosMiscDxe/SmBiosMiscDxe.inf
+
+INF RuleOverride = BINARY $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmbiosMemory.inf
+
+
+#
+# FAT file system
+#
+INF FatPkg/EnhancedFatDxe/Fat.inf
+
+#
+# UEFI Shell
+#
+INF  ShellPkg/Application/Shell/Shell.inf
+
+#
+# dp command
+#
+!if $(PERFORMANCE_ENABLE) == TRUE
+INF ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf
+!endif
+
+!if $(GOP_DRIVER_ENABLE) == TRUE
+FILE FREEFORM = 878AC2CC-5343-46F2-B563-51F89DAF56BA {
+  SECTION RAW = Vlv2SocBinPkg/GOP/7.2.1011/VBT/MNW2/Vbt.bin
+  SECTION UI = "IntelGopVbt"
+}
+!endif
+
+#
+# Network Modules
+#
+!if $(NETWORK_ENABLE) == TRUE
+  FILE DRIVER = 22DE1691-D65D-456a-993E-A253DD1F308C {
+    SECTION PE32 = Vlv2SocBinPkg/UNDI/RtkUndiDxe/$(DXE_ARCHITECTURE)/RtkUndiDxe.efi
+    SECTION UI = "UNDI"
+  }
+  INF  MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf
+  INF  MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
+  INF  MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
+  INF  MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
+  INF  MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
+  INF  MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+  INF  MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
+  INF  MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
+  INF  NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
+  INF  NetworkPkg/TcpDxe/TcpDxe.inf
+  !if $(NETWORK_IP6_ENABLE) == TRUE
+  INF  NetworkPkg/Ip6Dxe/Ip6Dxe.inf
+  INF  NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
+  INF  NetworkPkg/Udp6Dxe/Udp6Dxe.inf
+  INF  NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
+  !endif
+  !if $(NETWORK_VLAN_ENABLE) == TRUE
+  INF  MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf
+  !endif
+  !if $(NETWORK_ISCSI_ENABLE) == TRUE
+    INF  NetworkPkg/IScsiDxe/IScsiDxe.inf
+  !endif
+!endif
+
+!if $(CAPSULE_ENABLE)
+INF  MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxe.inf
+
+#
+# Minnow Max System Firmware FMP
+#
+INF  FILE_GUID = $(FMP_MINNOW_MAX_SYSTEM) FmpDevicePkg/FmpDxe/FmpDxe.inf
+
+#
+# Sample Device FMP
+#
+INF  FILE_GUID = $(FMP_GREEN_SAMPLE_DEVICE) FmpDevicePkg/FmpDxe/FmpDxe.inf
+INF  FILE_GUID = $(FMP_BLUE_SAMPLE_DEVICE)  FmpDevicePkg/FmpDxe/FmpDxe.inf
+INF  FILE_GUID = $(FMP_RED_SAMPLE_DEVICE)   FmpDevicePkg/FmpDxe/FmpDxe.inf
+
+!endif
+
+!if $(MICOCODE_CAPSULE_ENABLE)
+INF  IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.inf
+!endif
+
+!if $(RECOVERY_ENABLE)
+FILE FREEFORM = PCD(gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiRsa2048Sha256TestPublicKeyFileGuid) {
+     SECTION RAW = BaseTools/Source/Python/Rsa2048Sha256Sign/TestSigningPublicKey.bin
+     SECTION UI = "Rsa2048Sha256TestSigningPublicKey"
+     }
+!endif
+
+[FV.FVMAIN_COMPACT]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+
+
+FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+!if $(LZMA_ENABLE) == TRUE
+# LZMA Compress
+       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+          SECTION FV_IMAGE = FVMAIN
+       }
+!else
+!if $(DXE_COMPRESS_ENABLE) == TRUE
+# Tiano Compress
+       SECTION GUIDED A31280AD-481E-41B6-95E8-127F4C984779 PROCESSING_REQUIRED = TRUE {
+          SECTION FV_IMAGE = FVMAIN
+       }
+!else
+# No Compress
+       SECTION COMPRESS PI_NONE {
+          SECTION FV_IMAGE = FVMAIN
+       }
+!endif
+!endif
+     }
+
+[FV.SETUP_DATA]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+#NumBlocks         = 0x10
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+################################################################################
+#
+# Rules are use with the [FV] section's module INF type to define
+# how an FFS file is created for a given INF file. The following Rule are the default
+# rules for the different module type. User can add the customized rules to define the
+# content of the FFS file.
+#
+################################################################################
+[Rule.Common.SEC]
+  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+    PE32  PE32    Align = 8       $(INF_OUTPUT)/$(MODULE_NAME).efi
+    RAW BIN       Align = 16      |.com
+  }
+
+[Rule.Common.SEC.BINARY]
+  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+    PE32  PE32    Align = 8       |.efi
+!if $(MINNOW2_FSP_BUILD) == TRUE
+    RAW   RAW                     |.raw
+!else
+    RAW   BIN     Align = 16      |.com
+!endif
+  }
+
+[Rule.Common.PEI_CORE]
+  FILE PEI_CORE = $(NAMED_GUID)            {
+    PE32       PE32    Align = Auto      $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.PEIM]
+  FILE PEIM = $(NAMED_GUID) {
+     PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+     PE32        PE32   Align = Auto     $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI        STRING="$(MODULE_NAME)" Optional
+     VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.PEIM.BINARY]
+  FILE PEIM = $(NAMED_GUID) {
+     PEI_DEPEX PEI_DEPEX Optional        |.depex
+     PE32        PE32   Align = Auto     |.efi
+     UI        STRING="$(MODULE_NAME)" Optional
+     VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.PEIM.BIOSID]
+  FILE PEIM = $(NAMED_GUID) {
+     RAW       BIN                       BiosId.bin
+     PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+     PE32        PE32   Align = Auto     $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI        STRING="$(MODULE_NAME)" Optional
+     VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.USER_DEFINED.APINIT]
+  FILE RAW = $(NAMED_GUID) Fixed Align=4K {
+     RAW SEC_BIN |.com
+     }
+#cjia 2011-07-21
+[Rule.Common.USER_DEFINED.LEGACY16]
+  FILE FREEFORM = $(NAMED_GUID) {
+     UI  STRING="$(MODULE_NAME)" Optional
+     RAW BIN |.bin
+     }
+#cjia
+
+[Rule.Common.USER_DEFINED.ASM16]
+  FILE FREEFORM = $(NAMED_GUID) {
+     UI  STRING="$(MODULE_NAME)" Optional
+     RAW BIN |.com
+   }
+
+[Rule.Common.DXE_CORE]
+  FILE DXE_CORE = $(NAMED_GUID) {
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_DRIVER.BINARY]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       |.depex
+    PE32      PE32                     |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_DRIVER.NATIVE_BINARY]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional      $(WORKSPACE)/$(PLATFORM_PACKAGE)/IntelGopDepex/IntelGopDriver.depex
+    PE32      PE32                    |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_DRIVER.BINARY]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       |.depex
+    PE32      PE32                     |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_DRIVER.DRIVER_ACPITABLE]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+    RAW ACPI  Optional                |.acpi
+    RAW ASL   Optional                |.aml
+  }
+
+[Rule.Common.DXE_RUNTIME_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_RUNTIME_DRIVER.BINARY]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       |.depex
+    PE32      PE32                     |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_SMM_DRIVER]
+  FILE SMM = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_SMM_DRIVER.BINARY]
+  FILE SMM = $(NAMED_GUID) {
+    SMM_DEPEX SMM_DEPEX                |.depex
+    PE32      PE32                     |.efi
+    RAW       BIN  Optional            |.aml
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_SMM_DRIVER.DRIVER_ACPITABLE]
+  FILE SMM = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+    RAW ACPI  Optional                |.acpi
+    RAW ASL   Optional                |.aml
+  }
+
+[Rule.Common.SMM_CORE]
+  FILE SMM_CORE = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.SMM_CORE.BINARY]
+  FILE SMM_CORE = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       |.depex
+    PE32      PE32                     |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION]
+  FILE APPLICATION = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION.UI]
+  FILE APPLICATION = $(NAMED_GUID) {
+    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI        STRING="Enter Setup"
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.USER_DEFINED]
+  FILE FREEFORM = $(NAMED_GUID) {
+    UI  STRING="$(MODULE_NAME)" Optional
+    RAW BIN                |.bin
+  }
+
+[Rule.Common.USER_DEFINED.BINARY]
+  FILE FREEFORM = $(NAMED_GUID) {
+    UI  STRING="$(MODULE_NAME)" Optional
+    RAW BIN                |.bin
+  }
+
+[Rule.Common.USER_DEFINED.ACPITABLE]
+  FILE FREEFORM = $(NAMED_GUID) {
+    RAW ACPI  Optional            |.acpi
+    RAW ASL   Optional            |.aml
+  }
+
+[Rule.Common.USER_DEFINED.ACPITABLE2]
+  FILE FREEFORM = $(NAMED_GUID) {
+    RAW ASL   Optional            |.aml
+  }
+
+[Rule.Common.ACPITABLE]
+  FILE FREEFORM = $(NAMED_GUID) {
+    RAW ACPI  Optional            |.acpi
+    RAW ASL   Optional            |.aml
+  }
+
+[Rule.Common.PEIM.FMP_IMAGE_DESC]
+  FILE PEIM = $(NAMED_GUID) {
+     RAW BIN                  |.acpi
+     PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+     PE32      PE32    Align=4K          $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI       STRING="$(MODULE_NAME)" Optional
+     VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc
new file mode 100644
index 0000000000..b9faf558b7
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc
@@ -0,0 +1,1711 @@
+#/** @file
+# Platform description.
+#
+# Copyright (c) 2012  - 2019, 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]
+  PLATFORM_NAME                       = Vlv2TbltDevicePkg
+  PLATFORM_GUID                       = 465B0A0B-7AC1-443b-8F67-7B8DEC145F90
+  PLATFORM_VERSION                    = 0.1
+  DSC_SPECIFICATION                   = 0x00010005
+
+  #
+  # Set platform specific package/folder name, same as passed from PREBUILD script.
+  # PLATFORM_PACKAGE would be the same as PLATFORM_NAME as well as package build folder
+  # DEFINE only takes effect at R9 DSC and FDF.
+  #
+  DEFINE      PLATFORM_PACKAGE                = Vlv2TbltDevicePkg
+  DEFINE      PLATFORM_RC_PACKAGE             = Vlv2DeviceRefCodePkg
+  DEFINE      PLATFORM_BINARY_PACKAGE         = Vlv2SocBinPkg
+  OUTPUT_DIRECTORY                    = Build/$(PLATFORM_PACKAGE)
+  SUPPORTED_ARCHITECTURES             = IA32|X64
+  BUILD_TARGETS                       = DEBUG|RELEASE
+  SKUID_IDENTIFIER                    = DEFAULT
+
+  DEFINE CPU_ARCH                 =ValleyView2
+  DEFINE PROJECT_SC_FAMILY        =IntelPch
+  DEFINE PROJECT_SC_ROOT          =../$(PLATFORM_RC_PACKAGE)/ValleyView2Soc/SouthCluster
+  DEFINE PROJECT_VLV_ROOT          =../$(PLATFORM_RC_PACKAGE)/ValleyView2Soc/NorthCluster
+
+  DEFINE RC_BINARY_RELEASE        = TRUE
+  #
+  # Platform On/Off features are defined here
+  #
+  #
+  # Platform Support:: Set only one token except Crestview Hills
+  #
+  #   3.BayleyBay
+  #     ENBDT_PF_ENABLE  = TRUE
+  #
+  !include $(PLATFORM_PACKAGE)/AutoPlatformCFG.txt
+  !include $(PLATFORM_PACKAGE)/PlatformPkgConfig.dsc
+
+!if $(X64_CONFIG) == TRUE
+  DEFINE      DXE_ARCHITECTURE        = X64
+  DEFINE      EDK_DXE_ARCHITECTURE    = X64
+  DEFINE      UNDI_DXE_ARCHITECTURE   = 64
+!else
+  DEFINE      DXE_ARCHITECTURE        = IA32
+  DEFINE      EDK_DXE_ARCHITECTURE    = Ia32
+  DEFINE      UNDI_DXE_ARCHITECTURE   = 32
+!endif
+
+  FLASH_DEFINITION                    = $(PLATFORM_PACKAGE)/PlatformPkgGcc.fdf
+!if $(LFMA_ENABLE) == TRUE
+  FIX_LOAD_TOP_MEMORY_ADDRESS         = 0xFFFFFFFFFFFFFFFF
+  DEFINE   TOP_MEMORY_ADDRESS         = 0xFFFFFFFFFFFFFFFF
+!else
+  FIX_LOAD_TOP_MEMORY_ADDRESS         = 0x0
+  DEFINE   TOP_MEMORY_ADDRESS         = 0x0
+!endif
+
+  DEFINE   PLATFORM_PCIEXPRESS_BASE   = 0E0000000
+
+  DEFINE SEC_ENABLE = FALSE
+  DEFINE SEC_DEBUG_INFO_ENABLE = FALSE
+  DEFINE FTPM_ENABLE = FALSE
+
+################################################################################
+#
+# SKU Identification section - list of all SKU IDs supported by this
+#                              Platform.
+#
+################################################################################
+[SkuIds]
+  0|DEFAULT              # The entry: 0|DEFAULT is reserved and always required.
+
+################################################################################
+#
+# Library Class section - list of all Library Classes needed by this Platform.
+#
+################################################################################
+[LibraryClasses.common]
+  #
+  # Entry point
+  #
+  PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
+  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+  DxeSmmDriverEntryPoint|IntelFrameworkPkg/Library/DxeSmmDriverEntryPoint/DxeSmmDriverEntryPoint.inf
+
+  #
+  # Basic
+  #
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+!if $(SSE2_ENABLE) == TRUE
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.inf
+!else
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
+!endif
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+  PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
+  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
+  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
+  CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+!if $(RC_BINARY_RELEASE) == TRUE
+  PchPlatformLib|Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLib.inf
+!endif
+  #
+  # UEFI & PI
+  #
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  UefiDecompressLib|MdeModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf
+  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+  UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
+  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+  GenericBdsLib|$(PLATFORM_PACKAGE)/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
+  BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf
+  SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
+  PlatformBdsLib|$(PLATFORM_PACKAGE)/Library/PlatformBdsLib/PlatformBdsLib.inf
+  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+  DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
+  FlashDeviceLib|$(PLATFORM_PACKAGE)/Library/FlashDeviceLib/FlashDeviceLib.inf
+  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+  #
+  # Framework
+  #
+!if $(S3_ENABLE) == TRUE
+  S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
+!else
+  S3BootScriptLib|MdePkg/Library/BaseS3BootScriptLibNull/BaseS3BootScriptLibNull.inf
+!endif
+  S3IoLib|MdePkg/Library/BaseS3IoLib/BaseS3IoLib.inf
+  S3PciLib|MdePkg/Library/BaseS3PciLib/BaseS3PciLib.inf
+
+  #
+  # Generic Modules
+  #
+!if $(USB_ENABLE) == TRUE
+  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+!endif
+!if $(SCSI_ENABLE) == TRUE
+  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+!endif
+!if $(NETWORK_ENABLE) == TRUE
+  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+  IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
+  UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
+  TcpIoLib|MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf
+  DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
+!endif
+!if $(S3_ENABLE) == TRUE
+  S3Lib|IntelFrameworkModulePkg/Library/PeiS3Lib/PeiS3Lib.inf
+!endif
+
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+!if $(CAPSULE_ENABLE) == TRUE
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf
+!else
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+!endif
+  FmpAuthenticationLib|MdeModulePkg/Library/FmpAuthenticationLibNull/FmpAuthenticationLibNull.inf
+  IniParsingLib|SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.inf
+  PlatformFlashAccessLib|Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.inf
+  MicrocodeFlashAccessLib|Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.inf
+  DisplayUpdateProgressLib|MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.inf
+  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
+  IoApicLib|PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+
+  #
+  # CPU
+  #
+  MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf
+  LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+  MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+
+  #
+  # ICH
+  #
+  SmbusLib|$(PLATFORM_PACKAGE)/Library/SmbusLib/SmbusLib.inf
+  SmmLib|$(PLATFORM_PACKAGE)/Library/PchSmmLib/PchSmmLib.inf
+
+  #
+  # Platform
+  #
+  TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+  ResetSystemLib|$(PLATFORM_PACKAGE)/Library/ResetSystemLib/ResetSystemLib.inf
+
+  PlatformCmosLib|$(PLATFORM_PACKAGE)/Library/PlatformCmosLib/PlatformCmosLib.inf
+
+  #
+  # Misc
+  #
+  MonoStatusCodeLib|$(PLATFORM_PACKAGE)/MonoStatusCode/MonoStatusCode.inf
+!if $(TARGET) == RELEASE
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+  SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
+!else
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+  SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
+!endif
+
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+!if $(TPM_ENABLED) == TRUE
+  TpmCommLib|SecurityPkg/Library/TpmCommLib/TpmCommLib.inf
+  Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf
+  Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLibDTpm.inf
+
+!endif
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
+  DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf
+  PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf
+  SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
+!else
+  PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+!endif
+
+  #
+  # CryptLib
+  #
+!if $(TPM_ENABLED) == TRUE
+  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+!endif
+
+ BiosIdLib|$(PLATFORM_PACKAGE)/Library/BiosIdLib/BiosIdLib.inf
+ CpuIA32Lib|$(PLATFORM_PACKAGE)/Library/CpuIA32Lib/CpuIA32Lib.inf
+
+  StallSmmLib|$(PLATFORM_PACKAGE)/Library/StallSmmLib/StallSmmLib.inf
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+  PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf
+  TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
+  AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
+  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+!else
+  TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
+  AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
+!endif
+  VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
+!if $(RC_BINARY_RELEASE) == TRUE
+  I2cLib|Vlv2TbltDevicePkg/Library/I2CLib/I2CLibNull.inf
+!endif
+  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+!if $(FTPM_ENABLE) == TRUE || $(NETWORK_ISCSI_ENABLE) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+!endif
+  TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
+  Tcg2PhysicalPresenceLib|SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf
+  Tcg2PpVendorLib|SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.inf
+
+
+  Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
+!if $(MINNOW2_FSP_BUILD) == TRUE
+  FspApiLib|IntelFspWrapperPkg/Library/BaseFspApiLib/BaseFspApiLib.inf
+  FspPlatformInfoLib|IntelFspWrapperPkg/Library/BaseFspPlatformInfoLibSample/BaseFspPlatformInfoLibSample.inf
+  FspPlatformSecLib|Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/FspPlatformSecLibVlv2.inf
+  FspHobProcessLib|Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLibVlv2/FspHobProcessLibVlv2.inf
+!endif
+
+  BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
+
+[LibraryClasses.IA32.SEC]
+!if $(PERFORMANCE_ENABLE) == TRUE
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+!endif
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+
+[LibraryClasses.IA32.PEIM, LibraryClasses.IA32.PEI_CORE, LibraryClasses.IA32.SEC]
+  #
+  # PEI phase common
+  #
+
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+  MultiPlatformLib|$(PLATFORM_PACKAGE)/Library/MultiPlatformLib/MultiPlatformLib.inf
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
+  MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+
+!if $(PERFORMANCE_ENABLE) == TRUE
+  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+  TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+!endif
+
+!if $(TARGET) == RELEASE
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+  SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
+!else
+  DebugLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf
+  SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
+!endif
+
+  LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf
+  HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
+!endif
+
+ !if $(MINNOW2_FSP_BUILD) == TRUE
+ PlatformFspLib|Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.inf
+ !endif
+!if $(FTPM_ENABLE) == TRUE
+  Tpm2DeviceLib|Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.inf
+!endif
+
+[LibraryClasses.X64]
+  #
+  # DXE phase common
+  #
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+
+  TcgPhysicalPresenceLib|SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.inf
+!if $(TPM_ENABLED) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+!endif
+
+  LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf
+  EfiRegTableLib|$(PLATFORM_PACKAGE)/Library/EfiRegTableLib/EfiRegTableLib.inf
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+!endif
+
+  HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf
+
+[LibraryClasses.X64.DXE_DRIVER]
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+!if $(PERFORMANCE_ENABLE) == TRUE
+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+  TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+!endif
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+
+  FlashDeviceLib|$(PLATFORM_PACKAGE)/Library/FlashDeviceLib/FlashDeviceLibDxe.inf
+
+[LibraryClasses.X64.DXE_CORE]
+  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
+  MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+!if $(PERFORMANCE_ENABLE) == TRUE
+  PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
+  TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+!endif
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+
+[LibraryClasses.X64.DXE_SMM_DRIVER]
+  MmServicesTableLib|MdePkg/Library/MmServicesTableLib/MmServicesTableLib.inf
+  SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/SmmReportStatusCodeLib.inf
+  MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf
+  LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+  SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
+  SmmCpuPlatformHookLib|UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf
+  SmmCpuFeaturesLib|UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
+
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
+  !if $(TARGET) != RELEASE
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+  !endif
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf
+  TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+!endif
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
+
+[LibraryClasses.X64.SMM_CORE]
+  MemoryAllocationLib|MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf
+  SmmServicesTableLib|MdeModulePkg/Library/PiSmmCoreSmmServicesTableLib/PiSmmCoreSmmServicesTableLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/SmmReportStatusCodeLib.inf
+  SmmCorePlatformHookLib|MdeModulePkg/Library/SmmCorePlatformHookLibNull/SmmCorePlatformHookLibNull.inf
+  SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
+
+!if $(TPM_ENABLED) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
+!endif
+
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+
+!if $(TARGET) != RELEASE
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!endif
+
+[LibraryClasses.X64.DXE_RUNTIME_DRIVER]
+  ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+!endif
+!if $(TPM_ENABLED) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+!endif
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+
+!if $(CAPSULE_ENABLE) == TRUE
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf
+!endif
+
+[LibraryClasses.common.UEFI_DRIVER]
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+
+[LibraryClasses.X64.UEFI_APPLICATION]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+[PcdsFeatureFlag.common]
+!if $(MINI_BIOS_ENABLE) == FALSE
+  gPlatformModuleTokenSpaceGuid.PcdBdsDispatchAdditionalOprom|TRUE
+!else
+  gPlatformModuleTokenSpaceGuid.PcdBdsDispatchAdditionalOprom|FALSE
+!endif
+#
+# If PcdDxeIplSwitchToLongMode is TRUE, DxeIpl will load a 64-bit DxeCore and switch to long mode to hand over to DxeCore.
+#
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|TRUE
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserGrayOutTextStatement|TRUE
+
+!if $(CAPSULE_RESET_ENABLE) == TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|TRUE
+!else
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|FALSE
+!endif
+  gEfiCpuTokenSpaceGuid.PcdCpuSmmEnableBspElection|FALSE
+!if $(DATAHUB_STATUS_CODE_ENABLE) == TRUE
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeUseDataHub|TRUE
+!else
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeUseDataHub|FALSE
+!endif
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreImageLoaderSearchTeSectionFirst|FALSE
+!if $(TARGET) == RELEASE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
+!else
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
+!endif
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE
+!if $(ISA_SERIAL_STATUS_CODE_ENABLE) == TRUE
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseIsaSerial|TRUE
+!else
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseIsaSerial|FALSE
+!endif
+!if $(USB_SERIAL_STATUS_CODE_ENABLE) == TRUE
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseUsbSerial|TRUE
+!else
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseUsbSerial|FALSE
+!endif
+!if $(RAM_SERIAL_STATUS_CODE_ENABLE) == TRUE
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseRam|TRUE
+!else
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseRam|FALSE
+!endif
+
+
+  ## This PCD specifies whether PS2 keyboard does a extended verification during start.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPs2KbdExtendedVerification|FALSE
+
+  ## This PCD specifies whether PS2 mouse does a extended verification during start.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPs2MouseExtendedVerification|FALSE
+
+!if $(VARIABLE_INFO_ENABLE) == TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics|TRUE
+!else
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics|FALSE
+!endif
+
+  gEfiCpuTokenSpaceGuid.PcdCpuSmmBlockStartupThisAp|TRUE
+
+!if $(SOURCE_DEBUG_ENABLE)
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmDebug|TRUE
+!endif
+
+[PcdsFixedAtBuild.common]
+!if $(MINNOW2_FSP_BUILD) == TRUE
+# $(FLASH_REGION_VLVMICROCODE_BASE)
+  gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress|0xFFC00000
+# $(FLASH_REGION_VLVMICROCODE_SIZE)
+  gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize|0x00040000
+  gFspWrapperTokenSpaceGuid.PcdFlashMicroCodeOffset|0x60
+# $(FLASH_AREA_BASE_ADDRESS)
+  gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheAddress|0xFF800000
+# $(FLASH_AREA_SIZE)
+  gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheSize|0x00800000
+# $(FLASH_REGION_FSPBIN_BASE)
+  gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase|0xFFCC0000
+!endif
+
+!if $(PERFORMANCE_ENABLE) == TRUE
+!if $(MINNOW2_FSP_BUILD) == TRUE
+  # in FSP, when this got used, the memory already is up
+  gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0x00080000
+!else
+  gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0xFEF80000
+!endif
+  gEfiCpuTokenSpaceGuid.PcdTemporaryRamSize|0x00010000
+
+!else
+  !if $(MINNOW2_FSP_BUILD) == TRUE
+    gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0x00080000
+  !else
+    gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0xFEF80000
+  !endif
+  gEfiCpuTokenSpaceGuid.PcdTemporaryRamSize|0x00010000
+  gEfiCpuTokenSpaceGuid.PcdPeiTemporaryRamStackSize|0x3C00
+!endif
+
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x22000
+!else
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x4000
+!endif
+  gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize|0x00000800
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x400
+  gEfiCpuTokenSpaceGuid.PcdCpuIEDRamSize|0x400000
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemorySize|0x10000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAriSupport|FALSE
+  gEfiCpuTokenSpaceGuid.PcdCpuSmmApSyncTimeout|1000
+!if $(S4_ENABLE) == TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|TRUE
+!else
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+!endif
+!if $(TARGET) == RELEASE
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x3
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+!endif
+!if $(PERFORMANCE_ENABLE) == TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0x1
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPerformanceLogEntries|60
+!endif
+
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdEbdaReservedMemorySize|0x10000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable|$(TOP_MEMORY_ADDRESS)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserSubtitleTextColor|0x0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldTextColor|0x01
+  gEfiCpuTokenSpaceGuid.PcdCpuIEDEnabled|TRUE
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBiosVideoCheckVbeEnable|TRUE
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBiosVideoCheckVgaEnable|TRUE
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl|FALSE
+  gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod|2
+!endif
+
+  #
+  # Set SMM stack size to 16 KB.
+  #
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize|0x4000
+
+  #
+  # Clear unused single certificate PCD
+  #
+  gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer|{0}
+
+  #
+  # Lock all updatable firmware devices at End of DXE
+  #
+  gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceLockEventGuid|{GUID(gEfiEndOfDxeEventGroupGuid)}
+#  gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceLockEventGuid|{GUID(gEfiEventReadyToBootGuid)}
+
+  #
+  # Set PcdFmpDeviceTestKeySha256Digest to {0} to disable test key detection
+  #
+#  gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceTestKeySha256Digest|{0}
+
+[PcdsFixedAtBuild.IA32]
+!if $(TARGET) == RELEASE
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x3
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+!endif
+
+!if $(RECOVERY_ENABLE)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdRecoveryFileName|L"VLV2REC.Cap"
+!endif
+
+[PcdsPatchableInModule.common]
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x803805c6
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0x$(PLATFORM_PCIEXPRESS_BASE)
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLegacyBiosCacheLegacyRegion|FALSE
+
+  ## This PCD specifies whether to use the optimized timing for best PS2 detection performance.
+  #  Note this PCD could be set to TRUE for best boot performance and set to FALSE for best device compatibility.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFastPS2Detection|TRUE
+
+  #######################################################################################################
+  #
+  # Begin of MRC parameters
+  #
+
+  ## Memory Parameter Patchable.
+  #  FALSE - MRC Parameters are fixed for MinnowBoard Max<BR>
+  #  TRUE  - MRC Parameters are patchable by following PCDs<BR>
+  # @Prompt Memory Parameter Patchable.
+  # @ValidList 0x80000001 | 0, 1
+  gVlvRefCodePkgTokenSpaceGuid.PcdMemoryParameterPatchable|FALSE
+
+  ## Memory Down or DIMM slot.
+  #  0 - DIMM<BR>
+  #  1 - Memory Down<BR>
+  # @Prompt Enable Memory Down
+  # @ValidList 0x80000001 | 0, 1
+  gVlvRefCodePkgTokenSpaceGuid.PcdEnableMemoryDown|1
+
+  ## The speed of DRAM.
+  #  0 - 800 MHz<BR>
+  #  1 - 1066 MHz<BR>
+  #  2 - 1333 MHz<BR>
+  #  3 - 1600 MHz<BR>
+  # @Prompt DRAM Speed
+  # @ValidList 0x80000001 | 0, 1, 2, 3
+  gVlvRefCodePkgTokenSpaceGuid.PcdDramSpeed|1
+
+  ## DRAM Type.
+  #  0 - DDR3<BR>
+  #  1 - DDR3L<BR>
+  #  2 - DDR3U<BR>
+  #  3 - DDR3All<BR>
+  #  4 - LPDDR2<BR>
+  #  5 - LPDDR3<BR>
+  #  6 - DDR4<BR>
+  # @Prompt DRAM Type
+  # @ValidList 0x80000001 | 0, 1, 2, 3, 4, 5, 6
+  gVlvRefCodePkgTokenSpaceGuid.PcdDramType|1
+
+  ## Please populate DIMM slot 0 if only one DIMM is supported.
+  #  0 - Disable<BR>
+  #  1 - Enable<BR>
+  # @Prompt DIMM 0 Enable
+  # @ValidList 0x80000001 | 0, 1
+  gVlvRefCodePkgTokenSpaceGuid.PcdEnableDimm0|1
+
+  ## DIMM 1 has to be identical to DIMM 0.
+  #  0 - Disable<BR>
+  #  1 - Enable<BR>
+  # @Prompt DIMM 1 Enable Type
+  # @ValidList 0x80000001 | 0, 1
+  gVlvRefCodePkgTokenSpaceGuid.PcdEnableDimm1|0
+
+  ## DRAM device data width.
+  #  0 - x8<BR>
+  #  1 - x16<BR>
+  #  2 - x32<BR>
+  # @Prompt DIMM_DWIDTH
+  # @ValidList 0x80000001 | 0, 1, 2
+  gVlvRefCodePkgTokenSpaceGuid.PcdDimmDataWidth|1
+
+  ## DRAM device data density.
+  #  0 - 1 Gbit<BR>
+  #  1 - 2 Gbit<BR>
+  #  2 - 4 Gbit<BR>
+  #  3 - 8 Gbit<BR>
+  # @Prompt DIMM_Density
+  # @ValidList 0x80000001 | 0, 1, 2, 3
+  gVlvRefCodePkgTokenSpaceGuid.PcdDimmDensity|2
+
+  ## DRAM device data bus width.
+  #  0 - 8 bits<BR>
+  #  1 - 16 bits<BR>
+  #  2 - 32 bits<BR>
+  #  3 - 64 bits<BR>
+  # @Prompt DIMM_BusWidth
+  # @ValidList 0x80000001 | 0, 1, 2, 3
+  gVlvRefCodePkgTokenSpaceGuid.PcdDimmBusWidth|3
+
+  ## Ranks Per DIMM or Sides Per DIMM.
+  #  0 - 1 Rank<BR>
+  #  1 - 2 Ranks<BR>
+  # @Prompt DIMM_Sides
+  # @ValidList 0x80000001 | 0, 1
+  gVlvRefCodePkgTokenSpaceGuid.PcdRankPerDimm|0
+
+  ## tCL.<BR><BR>
+  # @Prompt tCL
+  gVlvRefCodePkgTokenSpaceGuid.PcdTcl|11
+
+  ## tRP and tRCD in DRAM clk - 5:12.5ns, 6:15ns, etc.
+  # @Prompt tRP_tRCD
+  gVlvRefCodePkgTokenSpaceGuid.PcdTrpTrcd|11
+
+  ## tWR in DRAM clk.
+  # @Prompt tWR
+  gVlvRefCodePkgTokenSpaceGuid.PcdTwr|12
+
+  ## tWTR in DRAM clk.
+  # @Prompt tWTR
+  gVlvRefCodePkgTokenSpaceGuid.PcdTwtr|6
+
+  ## tRRD in DRAM clk.
+  # @Prompt tRRD
+  gVlvRefCodePkgTokenSpaceGuid.PcdTrrd|6
+
+  ## tRTP in DRAM clk.
+  # @Prompt tRTP
+  gVlvRefCodePkgTokenSpaceGuid.PcdTrtp|6
+
+  ## tFAW in DRAM clk.
+  # @Prompt tFAW
+  gVlvRefCodePkgTokenSpaceGuid.PcdTfaw|32
+
+  #
+  # End of MRC parameters.
+  #
+  ###############################################################################################
+
+[PcdsDynamicHii.common.DEFAULT]
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|5 # Variable: L"Timeout"
+  gEfiMdePkgTokenSpaceGuid.PcdHardwareErrorRecordLevel|L"HwErrRecSupport"|gEfiGlobalVariableGuid|0x0|1 # Variable: L"HwErrRecSupport"
+
+[PcdsDynamicDefault.common.DEFAULT]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr|0x0
+  !if $(TPM_ENABLED) == TRUE
+    gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{0x7b, 0x3a, 0xcd, 0x72, 0xA5, 0xFE, 0x5e, 0x4f, 0x91, 0x65, 0x4d, 0xd1, 0x21, 0x87, 0xbb, 0x13}
+  !endif
+
+  ## This PCD defines the video horizontal resolution.
+  #  This PCD could be set to 0 then video resolution could be at highest resolution.
+  #gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|800
+  ## This PCD defines the video vertical resolution.
+  #  This PCD could be set to 0 then video resolution could be at highest resolution.
+  #gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600
+
+  ## This PCD defines the Console output column and the default value is 25 according to UEFI spec.
+  #  This PCD could be set to 0 then console output could be at max column and max row.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|31
+  ## This PCD defines the Console output row and the default value is 80 according to UEFI spec.
+  #  This PCD could be set to 0 then console output could be at max column and max row.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|100
+
+  ## The PCD is used to specify the video horizontal resolution of text setup.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|800
+  ## The PCD is used to specify the video vertical resolution of text setup.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|600
+  ## The PCD is used to specify the console output column of text setup.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutColumn|100
+  ## The PCD is used to specify the console output column of text setup.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutRow|31
+
+!if $(TPM_ENABLED) == TRUE
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInitializationPolicy|1
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmScrtmPolicy|1
+!endif
+
+[PcdsDynamicExDefault.common.DEFAULT]
+  gEfiVLVTokenSpaceGuid.PcdTCSmbaIoBaseAddress|0x1040
+  gEfiVLVTokenSpaceGuid.PcdEmmcManufacturerId|0
+  gEfiVLVTokenSpaceGuid.PcdProductSerialNumber|0
+  gEfiVLVTokenSpaceGuid.PcdMeasuredBootEnable|TRUE
+  gEfiVLVTokenSpaceGuid.PcdFTPMErrorOccur|FALSE
+  gEfiVLVTokenSpaceGuid.PcdFTPMErrorSkip|FALSE
+  gEfiVLVTokenSpaceGuid.PcdFTPMCommand|0
+  gEfiVLVTokenSpaceGuid.PcdFTPMResponse|0
+  gEfiVLVTokenSpaceGuid.PcdFTPMNotRespond|FALSE
+  gEfiVLVTokenSpaceGuid.PcdFTPMStatus|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateSmmDataPtr|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr|0
+  gEfiCpuTokenSpaceGuid.PcdCpuS3DataAddress|0
+  gEfiCpuTokenSpaceGuid.PcdCpuHotPlugDataAddress|0
+  gEfiCpuTokenSpaceGuid.PcdCpuCallbackSignal|0
+  gEfiCpuTokenSpaceGuid.PcdCpuConfigContextBuffer|0
+  gEfiVLVTokenSpaceGuid.PcdCpuLockBoxDataAddress|0
+  gEfiVLVTokenSpaceGuid.PcdCpuSmramCpuDataAddress|0
+  gEfiVLVTokenSpaceGuid.PcdCpuLockBoxSize|0
+
+[PcdsDynamicExDefault.X64.DEFAULT]
+!if $(RECOVERY_ENABLE)
+  gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareFileGuid|{GUID("AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215")}|VOID*|0x10
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSystemFmpCapsuleImageTypeIdGuid|{GUID("4096267b-da0a-42eb-b5eb-fef31d207cb4")}|VOID*|0x10
+!endif
+
+[Components.IA32]
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/SecCore.inf
+
+  !if $(MINNOW2_FSP_BUILD) == TRUE
+  IntelFspWrapperPkg/FspWrapperSecCore/FspWrapperSecCore.inf {
+    !if $(TARGET) == DEBUG
+
+    <LibraryClasses>
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+    !endif
+  }
+  Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.inf
+  IntelFspWrapperPkg/FspInitPei/FspInitPei.inf {
+    !if $(TARGET) == DEBUG
+    <LibraryClasses>
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+    !endif
+  }
+  !endif
+
+  MdeModulePkg/Core/Pei/PeiMain.inf {
+!if $(TARGET) == DEBUG
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
+!endif
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
+  }
+
+  $(PLATFORM_PACKAGE)/MonoStatusCode/MonoStatusCode.inf {
+!if $(TARGET) == DEBUG
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
+!endif
+  }
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/MemoryInit.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
+    <BuildOptions>
+      !if $(FTPM_ENABLE)==TRUE
+        *_*_IA32_CC_FLAGS = /D FTPM_ENABLE
+      !endif
+  }
+
+!if $(RC_BINARY_RELEASE) == TRUE
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/SeCUma.inf
+!endif
+
+!if $(FTPM_ENABLE) == TRUE
+$(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/fTPMInitPeim.inf
+!endif
+
+!if $(RC_BINARY_RELEASE) == TRUE
+  $(PLATFORM_PACKAGE)/PlatformPei/PlatformPei.inf {
+    <BuildOptions>
+      *_*_IA32_CC_FLAGS      = -DRC_BINARY_RELEASE
+  !if $(TARGET) == DEBUG
+      <PcdsFixedAtBuild>
+        gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
+  !endif
+  }
+!endif
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  SourceLevelDebugPkg/DebugAgentPei/DebugAgentPei.inf{
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+      DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
+      PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf
+      SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
+    }
+!endif
+
+!if $(FTPM_ENABLE) == TRUE
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/Tpm2DeviceSeCPei.inf
+!endif
+
+!if $(TPM_ENABLED) == TRUE
+  SecurityPkg/Tcg/PhysicalPresencePei/PhysicalPresencePei.inf
+  SecurityPkg/Tcg/TcgPei/TcgPei.inf {
+    <LibraryClasses>
+      NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+}
+!endif
+
+ $(PLATFORM_PACKAGE)/PlatformInitPei/PlatformInitPei.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x803805c6
+    <LibraryClasses>
+!if $(TARGET) != RELEASE
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!endif
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+  $(PLATFORM_PACKAGE)/FvInfoPei/FvInfoPei.inf
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/VlvInitPeim.inf
+!if $(PCIESC_ENABLE) == TRUE
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchEarlyInitPeim.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
+  }
+!endif
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchInitPeim.inf
+
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchSmbusArpDisabled.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchSpiPeim.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PeiSmmAccess.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PeiSmmControl.inf
+  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/CpuPeim.inf
+  UefiCpuPkg/CpuIoPei/CpuIoPei.inf
+  UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/MpS3.inf
+#  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PiSmmCommunicationPei.inf
+
+!if $(RECOVERY_ENABLE)
+  #
+  # Recovery
+  #
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchUsb.inf
+  MdeModulePkg/Bus/Pci/EhciPei/EhciPei.inf
+  MdeModulePkg/Bus/Usb/UsbBusPei/UsbBusPei.inf
+  MdeModulePkg/Bus/Usb/UsbBotPei/UsbBotPei.inf
+  FatPkg/FatPei/FatPei.inf
+  MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf
+  SignedCapsulePkg/Universal/RecoveryModuleLoadPei/RecoveryModuleLoadPei.inf {
+    <LibraryClasses>
+      FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibRsa2048Sha256/FmpAuthenticationLibRsa2048Sha256.inf
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+!endif
+
+!if $(CAPSULE_ENABLE) == TRUE
+  MdeModulePkg/Universal/CapsulePei/CapsulePei.inf
+!endif
+  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
+    <LibraryClasses>
+!if $(LZMA_ENABLE) == TRUE
+    NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+!endif
+  }
+
+ MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+ MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
+
+!if $(FTPM_ENABLE) == TRUE
+   SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
+    <LibraryClasses>
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+      NULL|SecurityPkg/Library\HashInstanceLibSha1/HashInstanceLibSha1.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+!endif
+!if $(TPM_ENABLED) == TRUE
+  SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+!endif
+!if $(ACPI50_ENABLE) == TRUE
+  MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.inf{
+    <LibraryClasses>
+      TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+  }
+
+!endif
+!if $(PERFORMANCE_ENABLE) == TRUE
+  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+!endif
+[Components.X64]
+  !if $(MINNOW2_FSP_BUILD) == TRUE
+  IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.inf {
+    !if $(TARGET) == DEBUG
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
+    <LibraryClasses>
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+    !endif
+  }
+
+  !endif
+  #
+  # EDK II Related Platform codes
+  #
+  MdeModulePkg/Core/Dxe/DxeMain.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
+    <LibraryClasses>
+!if $(DXE_CRC32_SECTION_ENABLE) == TRUE
+      NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
+!endif
+!if $(LZMA_ENABLE) == TRUE
+      NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+!endif
+!if $(TARGET) != RELEASE
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!endif
+  }
+  IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3SaveDxe.inf {
+    <PcdsPatchableInModule>
+        gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
+    <PcdsFixedAtBuild>
+        gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x27
+    <LibraryClasses>
+    !if $(TARGET) != RELEASE
+          DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+    !endif
+       <BuildOptions>
+        ICC:*_*_*_CC_FLAGS = -D MDEPKG_NDEBUG
+        GCC:RELEASE_*_*_CC_FLAGS = -D MDEPKG_NDEBUG
+  }
+  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+  IntelFrameworkModulePkg/Universal/CpuIoDxe/CpuIoDxe.inf
+  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
+
+  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf  {
+    <LibraryClasses>
+!if $(TARGET) != RELEASE
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!endif
+  }
+
+!if $(CAPSULE_ENABLE) == TRUE
+  MdeModulePkg/Universal/CapsulePei/CapsuleX64.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+      MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+      HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+      CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+      DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
+!endif
+  }
+!endif
+
+  MdeModulePkg/Universal/ReportStatusCodeRouter/Smm/ReportStatusCodeRouterSmm.inf
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf{
+    <LibraryClasses>
+!if $(SECURE_BOOT_ENABLE) == TRUE
+      NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
+!endif
+!if $(USER_IDENTIFICATION_ENABLE)
+      NULL|SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.inf
+!endif
+!if $(TPM_ENABLED) == TRUE
+      NULL|SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf
+!endif
+!if $(FTPM_ENABLE) == TRUE
+      NULL|SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf
+!endif
+  }
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/MpCpu.inf
+  $(PLATFORM_PACKAGE)/Metronome/Metronome.inf
+
+  IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf{
+    <LibraryClasses>
+      OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+      IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+      BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+      PlatformBdsLib|$(PLATFORM_PACKAGE)/Library/PlatformBdsLib/PlatformBdsLib.inf
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+      SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
+    !if $(FTPM_ENABLE) == TRUE
+      Tpm2DeviceLib|Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.inf
+    !else
+      Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf
+    !endif
+  }
+
+  $(PLATFORM_PACKAGE)/UiApp/UiApp.inf
+
+  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
+      SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
+  }
+  $(PLATFORM_PACKAGE)/FvbRuntimeDxe/FvbSmm.inf
+  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSpiSmm.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf {
+    <LibraryClasses>
+      PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf
+    <BuildOptions>
+      #
+      # Specify GUID gEfiIfrBootMaintenanceGuid, to install Secure Boot Configuration menu
+      # into Boot Maintenance Manager menu
+      #
+      *_*_*_VFR_FLAGS   = -g b2dedc91-d59f-48d2-898a-12490c74a4e0
+  }
+!endif
+   MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf {
+    <LibraryClasses>
+      FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+  }
+
+  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
+  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+
+  $(PLATFORM_PACKAGE)/FvbRuntimeDxe/FvbRuntimeDxe.inf
+
+  $(PLATFORM_PACKAGE)/PlatformSetupDxe/PlatformSetupDxe.inf
+
+!if $(DATAHUB_ENABLE) == TRUE
+  IntelFrameworkModulePkg/Universal/DataHubDxe/DataHubDxe.inf {
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|0
+  }
+!endif
+  IntelFrameworkModulePkg/Universal/StatusCode/DatahubStatusCodeHandlerDxe/DatahubStatusCodeHandlerDxe.inf
+  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchS3SupportDxe.inf
+  !if $(USE_HPET_TIMER) == TRUE
+    PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf
+  !else
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmartTimer.inf
+  !endif
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmmControl.inf
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSmbusDxe.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/IntelPchLegacyInterrupt.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchReset.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchInitDxe.inf{
+    <PcdsPatchableInModule>
+        gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
+  }
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchInitSmm.inf
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSmiDispatcher.inf
+
+!if $(PCIESC_ENABLE) == TRUE
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchPcieSmm.inf
+!endif
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSpiRuntime.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchPolicyInitDxe.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchBiosWriteProtect.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmmAccess.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PciHostBridge.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/VlvInitDxe.inf
+
+  IntelFrameworkModulePkg/Universal/LegacyRegionDxe/LegacyRegionDxe.inf
+
+  #
+  # Performance Application; Set PERFORMANCE_ENABLE=TRUE for normal boot performance and smm performance data
+  #
+!if $(PERFORMANCE_ENABLE) == TRUE
+  ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf {
+    <PcdsFixedAtBuild>
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+  }
+!endif
+
+  Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInitDxe.inf{
+    <LibraryClasses>
+!if $(TARGET) != RELEASE
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!endif
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/Dptf.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PnpDxe.inf
+
+!if $(SEC_ENABLE) == TRUE
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/HeciDrv.inf {
+!if $(SEC_DEBUG_INFO_ENABLE) == TRUE
+    <BuildOptions>
+      *_*_X64_CC_FLAGS      = /DSEC_DEBUG_INFO=1
+!else
+    <BuildOptions>
+      *_*_X64_CC_FLAGS      = /DSEC_DEBUG_INFO=0
+!endif
+  }
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SeCPolicyInitDxe.inf
+!endif
+
+!if $(FTPM_ENABLE) == TRUE
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/Tpm2DeviceSeCDxe.inf
+  SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf
+  SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf{
+    <LibraryClasses>
+      NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
+      PcdLib|MdePkg/Library\DxePcdLib/DxePcdLib.inf
+      Tpm2DeviceLib|Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.inf
+  }
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/FtpmSmm.inf
+!endif
+!if $(TPM_ENABLED) == TRUE
+  SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+
+  SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+    <BuildOptions>
+      #
+      # specify GUID gEfiIfrNotInTPVPageGuid, this page will not
+      # be showed in TPV page.
+      #
+      *_*_*_VFR_FLAGS   = -g e58809f8-fbc1-48e2-883a-a30fdc4b441e
+  }
+
+  SecurityPkg/Tcg/TcgDxe/TcgDxe.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+  SecurityPkg/Tcg/TcgSmm/TcgSmm.inf
+!endif
+  #
+  # EDK II Related Platform codes
+  #
+  $(PLATFORM_PACKAGE)/PlatformSmm/PlatformSmm.inf{
+    <LibraryClasses>
+    !if $(TARGET) != RELEASE
+          DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+    !endif
+          PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+  $(PLATFORM_PACKAGE)/PlatformInfoDxe/PlatformInfoDxe.inf
+  $(PLATFORM_PACKAGE)/PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf
+  $(PLATFORM_PACKAGE)/PlatformDxe/PlatformDxe.inf
+
+  $(PLATFORM_PACKAGE)/PciPlatform/PciPlatform.inf
+  $(PLATFORM_PACKAGE)/SaveMemoryConfig/SaveMemoryConfig.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PlatformCpuPolicy.inf
+  $(PLATFORM_PACKAGE)/PpmPolicy/PpmPolicy.inf
+  $(PLATFORM_PACKAGE)/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.inf
+!if $(GOP_DRIVER_ENABLE) == TRUE
+  $(PLATFORM_PACKAGE)/PlatformGopPolicy/PlatformGopPolicy.inf
+
+!endif
+
+
+  #
+  # SMM
+  #
+  MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
+  MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
+  UefiCpuPkg/CpuDxe/CpuDxe.inf
+  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+  UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
+  MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
+  UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
+  $(PLATFORM_PACKAGE)/SmmSwDispatch2OnSmmSwDispatchThunk/SmmSwDispatch2OnSmmSwDispatchThunk.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PowerManagement2.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/DigitalThermalSensor.inf
+
+  #
+  # ACPI
+  #
+   MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x27
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+
+  $(PLATFORM_PACKAGE)/BootScriptSaveDxe/BootScriptSaveDxe.inf
+  IntelFrameworkModulePkg/Universal/Acpi/AcpiSupportDxe/AcpiSupportDxe.inf
+  Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/PowerManagementAcpiTables.inf
+
+  $(PLATFORM_RC_PACKAGE)/AcpiTablesPCAT/AcpiTables.inf
+
+  $(PLATFORM_PACKAGE)/AcpiPlatform/AcpiPlatform.inf
+
+  MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
+
+  #
+  # PCI
+  #
+  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/ISPDxe.inf
+
+
+#
+# ISA
+#
+  $(PLATFORM_PACKAGE)/Wpce791/Wpce791.inf
+  IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBusDxe.inf
+  IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaIoDxe.inf
+  IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf
+  IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf
+  IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf
+#
+# SDIO
+#
+#  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/MmcHost.inf
+#  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/MmcMediaDevice.inf
+!if $(ACPI50_ENABLE) == TRUE
+  MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf {
+    <LibraryClasses>
+      TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+  }
+  MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.inf {
+    <LibraryClasses>
+      TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+  }
+!endif
+
+#
+# IDE/SCSI/AHCI
+#
+  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+  IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBusDxe.inf
+  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+  FatPkg/EnhancedFatDxe/Fat.inf
+  ShellPkg/Application/Shell/Shell.inf {
+    <LibraryClasses>
+      ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
+      HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+      PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+      BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+      gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
+  }
+!if $(SATA_ENABLE) == TRUE
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SataController.inf
+!endif
+  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+!if $(SCSI_ENABLE) == TRUE
+  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+!endif
+#
+# Console
+#
+  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+  IntelFrameworkModulePkg/Universal/Console/VgaClassDxe/VgaClassDxe.inf
+  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+
+  #
+  # USB
+  #
+!if $(USB_ENABLE) == TRUE
+  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+  MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
+  MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
+  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+  MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+  MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
+  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+!endif
+
+  #
+  # SMBIOS
+  #
+  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+  $(PLATFORM_PACKAGE)/SmBiosMiscDxe/SmBiosMiscDxe.inf
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmbiosMemory.inf
+  #
+  # CPU/FW Microde
+  #
+  Vlv2SocBinPkg/Microcode/MicrocodeUpdates.inf {
+    <BuildOptions>
+      *_*_*_GENFW_FLAGS = -a 0x800 -p 0xFF
+  }
+
+
+
+!if $(NETWORK_ENABLE) == TRUE
+  !if $(NETWORK_ISCSI_ENABLE) == TRUE
+    NetworkPkg/IScsiDxe/IScsiDxe.inf
+  !endif
+  !if $(NETWORK_VLAN_ENABLE) == TRUE
+    MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf
+  !endif
+  !if $(CSM_ENABLE) == TRUE
+    IntelFrameworkModulePkg/Csm/BiosThunk/Snp16Dxe/Snp16Dxe.inf
+  !endif
+!endif
+
+!if $(NETWORK_ENABLE) == TRUE
+  #
+  # UEFI network modules
+  #
+    MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
+    MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf
+
+    MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
+    MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
+    MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
+    MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
+    MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
+    NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
+    NetworkPkg/TcpDxe/TcpDxe.inf
+    MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+    !if $(NETWORK_IP6_ENABLE) == TRUE
+      NetworkPkg/Ip6Dxe/Ip6Dxe.inf
+      NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
+      NetworkPkg/Udp6Dxe/Udp6Dxe.inf
+      NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
+    !endif
+!endif
+
+!if $(CAPSULE_ENABLE) || $(MICOCODE_CAPSULE_ENABLE)
+  MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxe.inf
+  MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
+!endif
+
+!if $(CAPSULE_ENABLE)
+  !include Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc
+  !include Vlv2TbltDevicePkg/FmpGreenSampleDevice.dsc
+  !include Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc
+  !include Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc
+!endif
+
+!if $(MICOCODE_CAPSULE_ENABLE)
+  IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.inf {
+    <LibraryClasses>
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+      SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
+  }
+!endif
+
+[BuildOptions]
+#
+# Define Build Options both for EDK and EDKII drivers.
+#
+
+#
+# Define token for different Platform
+#
+!if $(MINNOW2_FSP_BUILD) == TRUE
+  DEFINE MINNOW2_FSP_OPTION = -DMINNOW2_FSP_BUILD
+!else
+  DEFINE MINNOW2_FSP_OPTION =
+!endif
+
+!if $(ENBDT_PF_BUILD) == TRUE
+  DEFINE ENBDT_PF_ENABLE = -DENBDT_PF_ENABLE=1
+!else
+  DEFINE ENBDT_PF_ENABLE = -DENBDT_PF_ENABLE=0
+!endif
+
+
+!if $(CLKGEN_CONFIG_EXTRA_ENABLE) == TRUE
+  DEFINE CLKGEN_CONFIG_EXTRA_BUILD_OPTION = -DCLKGEN_CONFIG_EXTRA=1
+!else
+  DEFINE CLKGEN_CONFIG_EXTRA_BUILD_OPTION =
+!endif
+
+
+
+!if $(PCIESC_ENABLE) == TRUE
+  DEFINE PCIESC_SUPPORT_BUILD_OPTION = -DPCIESC_SUPPORT=1
+!else
+  DEFINE PCIESC_SUPPORT_BUILD_OPTION =
+!endif
+!if $(SATA_ENABLE) == TRUE
+  DEFINE SATA_SUPPORT_BUILD_OPTION = -DSATA_SUPPORT=1
+!else
+  DEFINE SATA_SUPPORT_BUILD_OPTION =
+!endif
+!if $(ENBDT_S3_SUPPORT) == TRUE
+  DEFINE ENBDT_S3_SUPPORT_OPTIONS = -DNOCS_S3_SUPPORT
+!else
+  DEFINE ENBDT_S3_SUPPORT_OPTIONS =
+!endif
+
+!if $(X64_CONFIG) == TRUE
+  DEFINE X64_BUILD_ENABLE = -DX64_BUILD_ENABLE=1
+!else
+  DEFINE X64_BUILD_ENABLE =
+!endif
+
+!if $(FTPM_ENABLE) == TRUE
+  DEFINE DSC_FTPM_BUILD_OPTIONS = -DFTPM_ENABLE
+!else
+  DEFINE DSC_FTPM_BUILD_OPTIONS =
+!endif
+!if $(TPM_ENABLED) == TRUE
+  DEFINE DSC_TPM_BUILD_OPTIONS = -DTPM_ENABLED
+!else
+  DEFINE DSC_TPM_BUILD_OPTIONS =
+!endif
+
+
+  DEFINE EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS = $(MINNOW2_FSP_OPTION) $(MINNOW2_BUILD_OPTION) $(ENBDT_PF_ENABLE) $(EXTERNAL_VGA_BUILD_OPTION) $(PCIE_ENUM_WA_BUILD_OPTION) $(X0_WA_ENABLE_BUILD_OPTION) $(A0_WA_ENABLE_BUILD_OPTION) $(MICROCODE_FREE_BUILD_OPTIONS) $(SIMICS_BUILD_OPTIONS) $(HYBRID_BUILD_OPTIONS) $(COMPACT_BUILD_OPTIONS) $(VP_BUILD_OPTIONS) $(SYSCTL_ID_BUILD_OPTION) $(CLKGEN_CONFIG_EXTRA_BUILD_OPTION) $(SYSCTL_X0_CONVERT_BOARD_OPTION) $(ENBDT_S3_SUPPORT_OPTIONS) $(SATA_SUPPORT_BUILD_OPTION) $(PCIESC_SUPPORT_BUILD_OPTION) $(DSC_FTPM_BUILD_OPTIONS) $(DSC_FTPM_ERROR_WR_BUILD_OPTIONS) $(DSC_TPM_BUILD_OPTIONS) $(DSC_BYTI_SECURE_BOOT_BUILD_OPTIONS)
+!if $(PERFORMANCE_ENABLE) == TRUE
+  DEFINE PDB_BUILD_OPTION = /Zi
+!endif
+
+  GCC:*_*_*_CC_FLAGS = -Wno-missing-braces
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  MSFT:*_*_X64_GENFW_FLAGS  = --keepexceptiontable
+  GCC:*_*_X64_GENFW_FLAGS   = --keepexceptiontable
+  INTEL:*_*_X64_GENFW_FLAGS = --keepexceptiontable
+  DEFINE SOURCE_LEVEL_DEBUG_BUILD_OPTIONS =
+!else
+  DEFINE SOURCE_LEVEL_DEBUG_BUILD_OPTIONS =
+
+!endif
+
+#
+# Force PE/COFF sections to be aligned at 4KB boundaries to support page level
+# protection of DXE_RUNTIME_DRIVER modules
+#
+[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
+  MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
+  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+
+#
+# Force PE/COFF sections to be aligned at 4KB boundaries to support page level
+# protection of DXE_SMM_DRIVER/SMM_CORE modules
+#
+[BuildOptions.common.EDKII.DXE_SMM_DRIVER, BuildOptions.common.EDKII.SMM_CORE]
+  MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
+  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+
+[BuildOptions.Common.EDK]
+
+#
+# Define token for different Platform
+#
+!if $(ENBDT_PF_BUILD) == TRUE
+  DEFINE ENBDT_PF_ENABLE = -DENBDT_PF_ENABLE=1
+!else
+  DEFINE ENBDT_PF_ENABLE = -DENBDT_PF_ENABLE=0
+!endif
+
+!if $(PERFORMANCE_ENABLE) == TRUE
+  RELEASE_*_*_DLINK_FLAGS = -DEBUG
+!endif
+
+!if $(S3_ENABLE) == TRUE
+  DEFINE DSC_S3_BUILD_OPTIONS = -DEFI_S3_RESUME
+!else
+  DEFINE DSC_S3_BUILD_OPTIONS =
+!endif
+
+!if $(ENBDT_S3_SUPPORT) == TRUE
+  DEFINE ENBDT_S3_SUPPORT_OPTIONS = -DNOCS_S3_SUPPORT
+!else
+  DEFINE ENBDT_S3_SUPPORT_OPTIONS =
+!endif
+
+!if $(X64_CONFIG) == TRUE
+  DEFINE X64_BUILD_ENABLE = -DX64_BUILD_ENABLE=1
+!else
+  DEFINE X64_BUILD_ENABLE =
+!endif
+
+
+  DEFINE EDK_GLUE_LIB_DEBUG  =
+  DEFINE DEBUG_BUILD_OPTIONS = -D EFI_DEBUG -D DEBUG_MODE=1  /GL- $(EDK_GLUE_LIB_DEBUG) -DEDKII_GLUE_DebugPrintErrorLevel=(EFI_D_ERROR)
+  DEFINE EDK_DSC_FEATURE_BUILD_OPTIONS = $(DSC_S3_BUILD_OPTIONS) $(DSC_ACPI_BUILD_OPTIONS) $(DSC_SEC_BUILD_OPTIONS) $(DSC_FTPM_BUILD_OPTIONS) $(DSC_FTPM_ERROR_WR_BUILD_OPTIONS) $(DSC_TPM_BUILD_OPTIONS) $(SOFTSDV_BUILD_OPTIONS) $(SIMICS_BUILD_OPTIONS) $(HYBRID_BUILD_OPTIONS) $(COMPACT_BUILD_OPTIONS) $(VP_BUILD_OPTIONS) $(QT_BUILD_OPTIONS) $(DSC_BYTI_SECURE_BOOT_BUILD_OPTIONS) -D$(PROJECT_SC_CHIPSET)
+
+  DEFINE EDK_DSC_OTHER_BUILD_OPTIONS = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS) $(SV_BUILD_OPTIONS) $(INTEL_FASTBOOT_BUILD_OPTION)
+  DEFINE EDK_DSC_GLOBAL_BUILD_OPTIONS = $(ENBDT_PF_ENABLE) $(EDK_DSC_FEATURE_BUILD_OPTIONS) $(EDK_DSC_OTHER_BUILD_OPTIONS) -D EFI_SPECIFICATION_VERSION=0x00020000  -D PI_SPECIFICATION_VERSION=0x00000009  -D TIANO_RELEASE_VERSION=0x00080006 -D SUPPORT_DEPRECATED_PCI_CFG_PPI -D CSM_SMMENTRY_PORT8DATA8 -D EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE) -D MAX_VARIABLE_SIZE=0x2000 -D EFI_FIRMWARE_VENDOR="L/"INTEL/"" -D EFI_BUILD_VERSION="L/"EDKII/"" -DEFI_PEI_REPORT_STATUS_CODE_ON $(ENBDT_S3_SUPPORT_OPTIONS)
+
+  *_*_IA32_ASM_FLAGS         = -DEFI32 -D EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h -DNOCS_S3_SUPPORT
+  DEBUG_*_IA32_CC_FLAGS      = -D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_IA32_CC_FLAGS    = -D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  DEBUG_*_IA32_VFRPP_FLAGS   = -D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_IA32_VFRPP_FLAGS = -D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  DEBUG_*_IA32_APP_FLAGS     = -D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_IA32_APP_FLAGS   = -D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  DEBUG_*_IA32_PP_FLAGS      = -D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_IA32_PP_FLAGS    = -D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  *_*_IA32_ASLPP_FLAGS       = -D EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
+  *_*_IA32_ASLCC_FLAGS       = -D EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
+  *_*_IA32_ASM16_FLAGS       = -D EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h
+
+  *_*_X64_ASM_FLAGS          = -DEFIX64 -D EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h -DNOCS_S3_SUPPORT
+  DEBUG_*_X64_CC_FLAGS       = -D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_X64_CC_FLAGS     = -D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  DEBUG_*_X64_VFRPP_FLAGS    = -D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_X64_VFRPP_FLAGS  = -D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  DEBUG_*_X64_APP_FLAGS      = -D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_X64_APP_FLAGS    = -D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  DEBUG_*_X64_PP_FLAGS       = -D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_X64_PP_FLAGS     = -D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  *_*_X64_ASLPP_FLAGS        = -D EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
+  *_*_X64_ASLCC_FLAGS        = -D EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
+  *_*_X64_ASM16_FLAGS        = -D EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h
+ # *_*_*_BUILD_FLAGS = -s
+  *_*_*_VFR_FLAGS   = -c
+  *_*_*_BUILD_FLAGS = -c
+
+[BuildOptions.Common.EDKII]
+  *_*_IA32_ASM_FLAGS     = $(VP_BUILD_OPTIONS) -D EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h -DNOCS_S3_SUPPORT
+
+  *_*_IA32_CC_FLAGS      = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+  *_*_IA32_VFRPP_FLAGS   = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+  *_*_IA32_APP_FLAGS     = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+  *_*_IA32_PP_FLAGS      = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+  *_*_IA32_ASLPP_FLAGS   = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+
+  *_*_X64_CC_FLAGS       = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS) $(SOURCE_LEVEL_DEBUG_BUILD_OPTIONS)
+  *_*_X64_VFRPP_FLAGS    = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+  *_*_X64_APP_FLAGS      = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+  *_*_X64_PP_FLAGS       = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+  *_*_X64_ASLPP_FLAGS    = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+
+
+[Components.X64]
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/I2cBus.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
+  }
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/I2cHost.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
+  }
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/I2cPortA0Pio.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x00000043
+  }
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/I2cMmioDeviceDxe.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x00000043
+  }
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgIA32.dsc b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgIA32.dsc
new file mode 100644
index 0000000000..2324794841
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgIA32.dsc
@@ -0,0 +1,1699 @@
+#/** @file
+# Platform description.
+#
+# Copyright (c) 2012  - 2019, 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]
+  PLATFORM_NAME                       = Vlv2TbltDevicePkg
+  PLATFORM_GUID                       = 465B0A0B-7AC1-443b-8F67-7B8DEC145F90
+  PLATFORM_VERSION                    = 0.1
+  DSC_SPECIFICATION                   = 0x00010005
+
+  #
+  # Set platform specific package/folder name, same as passed from PREBUILD script.
+  # PLATFORM_PACKAGE would be the same as PLATFORM_NAME as well as package build folder
+  # DEFINE only takes effect at R9 DSC and FDF.
+  #
+  DEFINE      PLATFORM_PACKAGE                = Vlv2TbltDevicePkg
+  DEFINE      PLATFORM_RC_PACKAGE             = Vlv2DeviceRefCodePkg
+  DEFINE      PLATFORM_BINARY_PACKAGE         = Vlv2SocBinPkg
+  OUTPUT_DIRECTORY                    = Build/$(PLATFORM_PACKAGE)
+  SUPPORTED_ARCHITECTURES             = IA32
+  BUILD_TARGETS                       = DEBUG|RELEASE
+  SKUID_IDENTIFIER                    = DEFAULT
+
+  DEFINE CPU_ARCH                 =ValleyView2
+  DEFINE PROJECT_SC_FAMILY        =IntelPch
+  DEFINE PROJECT_SC_ROOT          =../$(PLATFORM_RC_PACKAGE)/ValleyView2Soc/SouthCluster
+  DEFINE PROJECT_VLV_ROOT          =../$(PLATFORM_RC_PACKAGE)/ValleyView2Soc/NorthCluster
+
+  DEFINE RC_BINARY_RELEASE        = TRUE
+  #
+  # Platform On/Off features are defined here
+  #
+  #
+  # Platform Support:: Set only one token except Crestview Hills
+  #
+  #   3.BayleyBay
+  #     ENBDT_PF_ENABLE  = TRUE
+  #
+  !include $(PLATFORM_PACKAGE)/AutoPlatformCFG.txt
+  !include $(PLATFORM_PACKAGE)/PlatformPkgConfig.dsc
+
+!if $(X64_CONFIG) == TRUE
+  DEFINE      DXE_ARCHITECTURE        = X64
+  DEFINE      EDK_DXE_ARCHITECTURE    = X64
+  DEFINE      UNDI_DXE_ARCHITECTURE   = 64
+!else
+  DEFINE      DXE_ARCHITECTURE        = IA32
+  DEFINE      EDK_DXE_ARCHITECTURE    = Ia32
+  DEFINE      UNDI_DXE_ARCHITECTURE   = 32
+!endif
+
+  FLASH_DEFINITION                    = $(PLATFORM_PACKAGE)/PlatformPkg.fdf
+!if $(LFMA_ENABLE) == TRUE
+  FIX_LOAD_TOP_MEMORY_ADDRESS         = 0xFFFFFFFFFFFFFFFF
+  DEFINE   TOP_MEMORY_ADDRESS         = 0xFFFFFFFFFFFFFFFF
+!else
+  FIX_LOAD_TOP_MEMORY_ADDRESS         = 0x0
+  DEFINE   TOP_MEMORY_ADDRESS         = 0x0
+!endif
+
+  DEFINE   PLATFORM_PCIEXPRESS_BASE   = 0E0000000
+
+  DEFINE SEC_ENABLE = FALSE
+  DEFINE SEC_DEBUG_INFO_ENABLE = FALSE
+  DEFINE FTPM_ENABLE = FALSE
+
+################################################################################
+#
+# SKU Identification section - list of all SKU IDs supported by this
+#                              Platform.
+#
+################################################################################
+[SkuIds]
+  0|DEFAULT              # The entry: 0|DEFAULT is reserved and always required.
+
+################################################################################
+#
+# Library Class section - list of all Library Classes needed by this Platform.
+#
+################################################################################
+[LibraryClasses.common]
+  #
+  # Entry point
+  #
+  PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
+  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+  DxeSmmDriverEntryPoint|IntelFrameworkPkg/Library/DxeSmmDriverEntryPoint/DxeSmmDriverEntryPoint.inf
+
+  #
+  # Basic
+  #
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+!if $(SSE2_ENABLE) == TRUE
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.inf
+!else
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
+!endif
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+  PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
+  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
+  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
+  CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+!if $(RC_BINARY_RELEASE) == TRUE
+  PchPlatformLib|Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLib.inf
+!endif
+  #
+  # UEFI & PI
+  #
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  UefiDecompressLib|MdeModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf
+  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+  UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
+  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+  GenericBdsLib|$(PLATFORM_PACKAGE)/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
+  BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf
+  SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
+  PlatformBdsLib|$(PLATFORM_PACKAGE)/Library/PlatformBdsLib/PlatformBdsLib.inf
+  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+  DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
+  FlashDeviceLib|$(PLATFORM_PACKAGE)/Library/FlashDeviceLib/FlashDeviceLib.inf
+  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+  #
+  # Framework
+  #
+!if $(S3_ENABLE) == TRUE
+  S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
+!else
+  S3BootScriptLib|MdePkg/Library/BaseS3BootScriptLibNull/BaseS3BootScriptLibNull.inf
+!endif
+  S3IoLib|MdePkg/Library/BaseS3IoLib/BaseS3IoLib.inf
+  S3PciLib|MdePkg/Library/BaseS3PciLib/BaseS3PciLib.inf
+
+  #
+  # Generic Modules
+  #
+!if $(USB_ENABLE) == TRUE
+  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+!endif
+!if $(SCSI_ENABLE) == TRUE
+  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+!endif
+!if $(NETWORK_ENABLE) == TRUE
+  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+  IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
+  UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
+  TcpIoLib|MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf
+  DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
+!endif
+!if $(S3_ENABLE) == TRUE
+  S3Lib|IntelFrameworkModulePkg/Library/PeiS3Lib/PeiS3Lib.inf
+!endif
+
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+!if $(CAPSULE_ENABLE) == TRUE
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf
+!else
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+!endif
+  FmpAuthenticationLib|MdeModulePkg/Library/FmpAuthenticationLibNull/FmpAuthenticationLibNull.inf
+  IniParsingLib|SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.inf
+  PlatformFlashAccessLib|Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.inf
+  MicrocodeFlashAccessLib|Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.inf
+  DisplayUpdateProgressLib|MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.inf
+  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
+  IoApicLib|PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+
+  #
+  # CPU
+  #
+  MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf
+  LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+  MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+
+  #
+  # ICH
+  #
+  SmbusLib|$(PLATFORM_PACKAGE)/Library/SmbusLib/SmbusLib.inf
+  SmmLib|$(PLATFORM_PACKAGE)/Library/PchSmmLib/PchSmmLib.inf
+
+  #
+  # Platform
+  #
+  TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+  ResetSystemLib|$(PLATFORM_PACKAGE)/Library/ResetSystemLib/ResetSystemLib.inf
+
+  PlatformCmosLib|$(PLATFORM_PACKAGE)/Library/PlatformCmosLib/PlatformCmosLib.inf
+
+  #
+  # Misc
+  #
+  MonoStatusCodeLib|$(PLATFORM_PACKAGE)/MonoStatusCode/MonoStatusCode.inf
+!if $(TARGET) == RELEASE
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+  SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
+!else
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+  SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
+!endif
+
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+!if $(TPM_ENABLED) == TRUE
+  TpmCommLib|SecurityPkg/Library/TpmCommLib/TpmCommLib.inf
+  Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf
+  Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLibDTpm.inf
+
+!endif
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
+  DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf
+  PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf
+  SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
+!else
+  PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+!endif
+
+  #
+  # CryptLib
+  #
+!if $(TPM_ENABLED) == TRUE
+  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+!endif
+
+ BiosIdLib|$(PLATFORM_PACKAGE)/Library/BiosIdLib/BiosIdLib.inf
+ CpuIA32Lib|$(PLATFORM_PACKAGE)/Library/CpuIA32Lib/CpuIA32Lib.inf
+
+  StallSmmLib|$(PLATFORM_PACKAGE)/Library/StallSmmLib/StallSmmLib.inf
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+  PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf
+  TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
+  AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
+  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+!else
+  TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
+  AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
+!endif
+  VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
+!if $(RC_BINARY_RELEASE) == TRUE
+  I2cLib|Vlv2TbltDevicePkg/Library/I2CLib/I2CLibNull.inf
+!endif
+  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+!if $(FTPM_ENABLE) == TRUE || $(NETWORK_ISCSI_ENABLE) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+!endif
+  TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
+  Tcg2PhysicalPresenceLib|SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf
+  Tcg2PpVendorLib|SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.inf
+
+
+  Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
+!if $(MINNOW2_FSP_BUILD) == TRUE
+  FspApiLib|IntelFspWrapperPkg/Library/BaseFspApiLib/BaseFspApiLib.inf
+  FspPlatformInfoLib|IntelFspWrapperPkg/Library/BaseFspPlatformInfoLibSample/BaseFspPlatformInfoLibSample.inf
+  FspPlatformSecLib|Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/FspPlatformSecLibVlv2.inf
+  FspHobProcessLib|Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLibVlv2/FspHobProcessLibVlv2.inf
+!endif
+
+  BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
+
+[LibraryClasses.IA32.SEC]
+!if $(PERFORMANCE_ENABLE) == TRUE
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+!endif
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+
+[LibraryClasses.IA32.PEIM, LibraryClasses.IA32.PEI_CORE, LibraryClasses.IA32.SEC]
+  #
+  # PEI phase common
+  #
+
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+  MultiPlatformLib|$(PLATFORM_PACKAGE)/Library/MultiPlatformLib/MultiPlatformLib.inf
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
+  MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+
+!if $(PERFORMANCE_ENABLE) == TRUE
+  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+  TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+!endif
+
+!if $(TARGET) == RELEASE
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+  SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
+!else
+  DebugLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf
+  SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
+!endif
+
+  LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf
+  HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
+!endif
+
+ !if $(MINNOW2_FSP_BUILD) == TRUE
+ PlatformFspLib|Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.inf
+ !endif
+!if $(FTPM_ENABLE) == TRUE
+  Tpm2DeviceLib|Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.inf
+!endif
+
+[LibraryClasses.IA32]
+  #
+  # DXE phase common
+  #
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+
+  TcgPhysicalPresenceLib|SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.inf
+!if $(TPM_ENABLED) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+!endif
+
+  LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf
+  EfiRegTableLib|$(PLATFORM_PACKAGE)/Library/EfiRegTableLib/EfiRegTableLib.inf
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+!endif
+
+  HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf
+
+[LibraryClasses.IA32.DXE_DRIVER]
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+!if $(PERFORMANCE_ENABLE) == TRUE
+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+  TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+!endif
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+
+  FlashDeviceLib|$(PLATFORM_PACKAGE)/Library/FlashDeviceLib/FlashDeviceLibDxe.inf
+
+[LibraryClasses.IA32.DXE_CORE]
+  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
+  MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+!if $(PERFORMANCE_ENABLE) == TRUE
+  PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
+  TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+!endif
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+
+[LibraryClasses.IA32.DXE_SMM_DRIVER]
+  MmServicesTableLib|MdePkg/Library/MmServicesTableLib/MmServicesTableLib.inf
+  SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/SmmReportStatusCodeLib.inf
+  MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf
+  LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+  SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
+  SmmCpuPlatformHookLib|UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf
+  SmmCpuFeaturesLib|UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
+
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
+  !if $(TARGET) != RELEASE
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+  !endif
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf
+  TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+!endif
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
+
+[LibraryClasses.IA32.SMM_CORE]
+  MemoryAllocationLib|MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf
+  SmmServicesTableLib|MdeModulePkg/Library/PiSmmCoreSmmServicesTableLib/PiSmmCoreSmmServicesTableLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/SmmReportStatusCodeLib.inf
+  SmmCorePlatformHookLib|MdeModulePkg/Library/SmmCorePlatformHookLibNull/SmmCorePlatformHookLibNull.inf
+  SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
+
+!if $(TPM_ENABLED) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
+!endif
+
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+
+!if $(TARGET) != RELEASE
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!endif
+
+[LibraryClasses.IA32.DXE_RUNTIME_DRIVER]
+  ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+!endif
+!if $(TPM_ENABLED) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+!endif
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+
+!if $(CAPSULE_ENABLE) == TRUE
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf
+!endif
+
+[LibraryClasses.common.UEFI_DRIVER]
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+
+[LibraryClasses.IA32.UEFI_APPLICATION]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+[PcdsFeatureFlag.common]
+!if $(MINI_BIOS_ENABLE) == FALSE
+  gPlatformModuleTokenSpaceGuid.PcdBdsDispatchAdditionalOprom|TRUE
+!else
+  gPlatformModuleTokenSpaceGuid.PcdBdsDispatchAdditionalOprom|FALSE
+!endif
+#
+# If PcdDxeIplSwitchToLongMode is TRUE, DxeIpl will load a 64-bit DxeCore and switch to long mode to hand over to DxeCore.
+#
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|FALSE
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserGrayOutTextStatement|TRUE
+
+!if $(CAPSULE_RESET_ENABLE) == TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|TRUE
+!else
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|FALSE
+!endif
+  gEfiCpuTokenSpaceGuid.PcdCpuSmmEnableBspElection|FALSE
+!if $(DATAHUB_STATUS_CODE_ENABLE) == TRUE
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeUseDataHub|TRUE
+!else
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeUseDataHub|FALSE
+!endif
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreImageLoaderSearchTeSectionFirst|FALSE
+!if $(TARGET) == RELEASE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
+!else
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
+!endif
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE
+!if $(ISA_SERIAL_STATUS_CODE_ENABLE) == TRUE
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseIsaSerial|TRUE
+!else
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseIsaSerial|FALSE
+!endif
+!if $(USB_SERIAL_STATUS_CODE_ENABLE) == TRUE
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseUsbSerial|TRUE
+!else
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseUsbSerial|FALSE
+!endif
+!if $(RAM_SERIAL_STATUS_CODE_ENABLE) == TRUE
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseRam|TRUE
+!else
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseRam|FALSE
+!endif
+
+
+  ## This PCD specifies whether PS2 keyboard does a extended verification during start.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPs2KbdExtendedVerification|FALSE
+
+  ## This PCD specifies whether PS2 mouse does a extended verification during start.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPs2MouseExtendedVerification|FALSE
+
+!if $(VARIABLE_INFO_ENABLE) == TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics|TRUE
+!else
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics|FALSE
+!endif
+
+  gEfiCpuTokenSpaceGuid.PcdCpuSmmBlockStartupThisAp|TRUE
+
+!if $(SOURCE_DEBUG_ENABLE)
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmDebug|TRUE
+!endif
+
+[PcdsFixedAtBuild.common]
+!if $(MINNOW2_FSP_BUILD) == TRUE
+# $(FLASH_REGION_VLVMICROCODE_BASE)
+  gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress|0xFFC00000
+# $(FLASH_REGION_VLVMICROCODE_SIZE)
+  gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize|0x00040000
+  gFspWrapperTokenSpaceGuid.PcdFlashMicroCodeOffset|0x60
+# $(FLASH_AREA_BASE_ADDRESS)
+  gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheAddress|0xFF800000
+# $(FLASH_AREA_SIZE)
+  gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheSize|0x00800000
+# $(FLASH_REGION_FSPBIN_BASE)
+  gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase|0xFFCC0000
+!endif
+
+!if $(PERFORMANCE_ENABLE) == TRUE
+!if $(MINNOW2_FSP_BUILD) == TRUE
+  # in FSP, when this got used, the memory already is up
+  gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0x00080000
+!else
+  gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0xFEF80000
+!endif
+  gEfiCpuTokenSpaceGuid.PcdTemporaryRamSize|0x00010000
+
+!else
+  !if $(MINNOW2_FSP_BUILD) == TRUE
+    gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0x00080000
+  !else
+    gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0xFEF80000
+  !endif
+  gEfiCpuTokenSpaceGuid.PcdTemporaryRamSize|0x00010000
+  gEfiCpuTokenSpaceGuid.PcdPeiTemporaryRamStackSize|0x3C00
+!endif
+
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x22000
+!else
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x4000
+!endif
+  gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize|0x00000800
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x400
+  gEfiCpuTokenSpaceGuid.PcdCpuIEDRamSize|0x400000
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemorySize|0x10000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAriSupport|FALSE
+  gEfiCpuTokenSpaceGuid.PcdCpuSmmApSyncTimeout|1000
+!if $(S4_ENABLE) == TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|TRUE
+!else
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+!endif
+!if $(TARGET) == RELEASE
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x3
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+!endif
+!if $(PERFORMANCE_ENABLE) == TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0x1
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPerformanceLogEntries|60
+!endif
+
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdEbdaReservedMemorySize|0x10000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable|$(TOP_MEMORY_ADDRESS)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserSubtitleTextColor|0x0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldTextColor|0x01
+  gEfiCpuTokenSpaceGuid.PcdCpuIEDEnabled|TRUE
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBiosVideoCheckVbeEnable|TRUE
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBiosVideoCheckVgaEnable|TRUE
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl|FALSE
+  gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod|2
+!endif
+
+  #
+  # Set SMM stack size to 16 KB.
+  #
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize|0x4000
+
+  #
+  # Clear unused single certificate PCD
+  #
+  gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer|{0}
+
+  #
+  # Lock all updatable firmware devices at End of DXE
+  #
+  gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceLockEventGuid|{GUID(gEfiEndOfDxeEventGroupGuid)}
+#  gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceLockEventGuid|{GUID(gEfiEventReadyToBootGuid)}
+
+  #
+  # Set PcdFmpDeviceTestKeySha256Digest to {0} to disable test key detection
+  #
+#  gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceTestKeySha256Digest|{0}
+
+[PcdsFixedAtBuild.IA32]
+!if $(TARGET) == RELEASE
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x3
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+!endif
+
+!if $(RECOVERY_ENABLE)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdRecoveryFileName|L"VLV2REC.Cap"
+!endif
+
+[PcdsPatchableInModule.common]
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x803805c6
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0x$(PLATFORM_PCIEXPRESS_BASE)
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLegacyBiosCacheLegacyRegion|FALSE
+
+  ## This PCD specifies whether to use the optimized timing for best PS2 detection performance.
+  #  Note this PCD could be set to TRUE for best boot performance and set to FALSE for best device compatibility.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFastPS2Detection|TRUE
+
+  #######################################################################################################
+  #
+  # Begin of MRC parameters
+  #
+
+  ## Memory Parameter Patchable.
+  #  FALSE - MRC Parameters are fixed for MinnowBoard Max<BR>
+  #  TRUE  - MRC Parameters are patchable by following PCDs<BR>
+  # @Prompt Memory Parameter Patchable.
+  # @ValidList 0x80000001 | 0, 1
+  gVlvRefCodePkgTokenSpaceGuid.PcdMemoryParameterPatchable|FALSE
+
+  ## Memory Down or DIMM slot.
+  #  0 - DIMM<BR>
+  #  1 - Memory Down<BR>
+  # @Prompt Enable Memory Down
+  # @ValidList 0x80000001 | 0, 1
+  gVlvRefCodePkgTokenSpaceGuid.PcdEnableMemoryDown|1
+
+  ## The speed of DRAM.
+  #  0 - 800 MHz<BR>
+  #  1 - 1066 MHz<BR>
+  #  2 - 1333 MHz<BR>
+  #  3 - 1600 MHz<BR>
+  # @Prompt DRAM Speed
+  # @ValidList 0x80000001 | 0, 1, 2, 3
+  gVlvRefCodePkgTokenSpaceGuid.PcdDramSpeed|1
+
+  ## DRAM Type.
+  #  0 - DDR3<BR>
+  #  1 - DDR3L<BR>
+  #  2 - DDR3U<BR>
+  #  3 - DDR3All<BR>
+  #  4 - LPDDR2<BR>
+  #  5 - LPDDR3<BR>
+  #  6 - DDR4<BR>
+  # @Prompt DRAM Type
+  # @ValidList 0x80000001 | 0, 1, 2, 3, 4, 5, 6
+  gVlvRefCodePkgTokenSpaceGuid.PcdDramType|1
+
+  ## Please populate DIMM slot 0 if only one DIMM is supported.
+  #  0 - Disable<BR>
+  #  1 - Enable<BR>
+  # @Prompt DIMM 0 Enable
+  # @ValidList 0x80000001 | 0, 1
+  gVlvRefCodePkgTokenSpaceGuid.PcdEnableDimm0|1
+
+  ## DIMM 1 has to be identical to DIMM 0.
+  #  0 - Disable<BR>
+  #  1 - Enable<BR>
+  # @Prompt DIMM 1 Enable Type
+  # @ValidList 0x80000001 | 0, 1
+  gVlvRefCodePkgTokenSpaceGuid.PcdEnableDimm1|0
+
+  ## DRAM device data width.
+  #  0 - x8<BR>
+  #  1 - x16<BR>
+  #  2 - x32<BR>
+  # @Prompt DIMM_DWIDTH
+  # @ValidList 0x80000001 | 0, 1, 2
+  gVlvRefCodePkgTokenSpaceGuid.PcdDimmDataWidth|1
+
+  ## DRAM device data density.
+  #  0 - 1 Gbit<BR>
+  #  1 - 2 Gbit<BR>
+  #  2 - 4 Gbit<BR>
+  #  3 - 8 Gbit<BR>
+  # @Prompt DIMM_Density
+  # @ValidList 0x80000001 | 0, 1, 2, 3
+  gVlvRefCodePkgTokenSpaceGuid.PcdDimmDensity|2
+
+  ## DRAM device data bus width.
+  #  0 - 8 bits<BR>
+  #  1 - 16 bits<BR>
+  #  2 - 32 bits<BR>
+  #  3 - 64 bits<BR>
+  # @Prompt DIMM_BusWidth
+  # @ValidList 0x80000001 | 0, 1, 2, 3
+  gVlvRefCodePkgTokenSpaceGuid.PcdDimmBusWidth|3
+
+  ## Ranks Per DIMM or Sides Per DIMM.
+  #  0 - 1 Rank<BR>
+  #  1 - 2 Ranks<BR>
+  # @Prompt DIMM_Sides
+  # @ValidList 0x80000001 | 0, 1
+  gVlvRefCodePkgTokenSpaceGuid.PcdRankPerDimm|0
+
+  ## tCL.<BR><BR>
+  # @Prompt tCL
+  gVlvRefCodePkgTokenSpaceGuid.PcdTcl|11
+
+  ## tRP and tRCD in DRAM clk - 5:12.5ns, 6:15ns, etc.
+  # @Prompt tRP_tRCD
+  gVlvRefCodePkgTokenSpaceGuid.PcdTrpTrcd|11
+
+  ## tWR in DRAM clk.
+  # @Prompt tWR
+  gVlvRefCodePkgTokenSpaceGuid.PcdTwr|12
+
+  ## tWTR in DRAM clk.
+  # @Prompt tWTR
+  gVlvRefCodePkgTokenSpaceGuid.PcdTwtr|6
+
+  ## tRRD in DRAM clk.
+  # @Prompt tRRD
+  gVlvRefCodePkgTokenSpaceGuid.PcdTrrd|6
+
+  ## tRTP in DRAM clk.
+  # @Prompt tRTP
+  gVlvRefCodePkgTokenSpaceGuid.PcdTrtp|6
+
+  ## tFAW in DRAM clk.
+  # @Prompt tFAW
+  gVlvRefCodePkgTokenSpaceGuid.PcdTfaw|32
+
+  #
+  # End of MRC parameters.
+  #
+  ###############################################################################################
+
+[PcdsDynamicHii.common.DEFAULT]
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|5 # Variable: L"Timeout"
+  gEfiMdePkgTokenSpaceGuid.PcdHardwareErrorRecordLevel|L"HwErrRecSupport"|gEfiGlobalVariableGuid|0x0|1 # Variable: L"HwErrRecSupport"
+
+[PcdsDynamicDefault.common.DEFAULT]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr|0x0
+  !if $(TPM_ENABLED) == TRUE
+    gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{0x7b, 0x3a, 0xcd, 0x72, 0xA5, 0xFE, 0x5e, 0x4f, 0x91, 0x65, 0x4d, 0xd1, 0x21, 0x87, 0xbb, 0x13}
+  !endif
+
+  ## This PCD defines the video horizontal resolution.
+  #  This PCD could be set to 0 then video resolution could be at highest resolution.
+  #gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|800
+  ## This PCD defines the video vertical resolution.
+  #  This PCD could be set to 0 then video resolution could be at highest resolution.
+  #gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600
+
+  ## This PCD defines the Console output column and the default value is 25 according to UEFI spec.
+  #  This PCD could be set to 0 then console output could be at max column and max row.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|31
+  ## This PCD defines the Console output row and the default value is 80 according to UEFI spec.
+  #  This PCD could be set to 0 then console output could be at max column and max row.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|100
+
+  ## The PCD is used to specify the video horizontal resolution of text setup.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|800
+  ## The PCD is used to specify the video vertical resolution of text setup.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|600
+  ## The PCD is used to specify the console output column of text setup.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutColumn|100
+  ## The PCD is used to specify the console output column of text setup.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutRow|31
+
+!if $(TPM_ENABLED) == TRUE
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInitializationPolicy|1
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmScrtmPolicy|1
+!endif
+
+[PcdsDynamicExDefault.common.DEFAULT]
+  gEfiVLVTokenSpaceGuid.PcdTCSmbaIoBaseAddress|0x1040
+  gEfiVLVTokenSpaceGuid.PcdEmmcManufacturerId|0
+  gEfiVLVTokenSpaceGuid.PcdProductSerialNumber|0
+  gEfiVLVTokenSpaceGuid.PcdMeasuredBootEnable|TRUE
+  gEfiVLVTokenSpaceGuid.PcdFTPMErrorOccur|FALSE
+  gEfiVLVTokenSpaceGuid.PcdFTPMErrorSkip|FALSE
+  gEfiVLVTokenSpaceGuid.PcdFTPMCommand|0
+  gEfiVLVTokenSpaceGuid.PcdFTPMResponse|0
+  gEfiVLVTokenSpaceGuid.PcdFTPMNotRespond|FALSE
+  gEfiVLVTokenSpaceGuid.PcdFTPMStatus|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateSmmDataPtr|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr|0
+  gEfiCpuTokenSpaceGuid.PcdCpuS3DataAddress|0
+  gEfiCpuTokenSpaceGuid.PcdCpuHotPlugDataAddress|0
+  gEfiCpuTokenSpaceGuid.PcdCpuCallbackSignal|0
+  gEfiCpuTokenSpaceGuid.PcdCpuConfigContextBuffer|0
+  gEfiVLVTokenSpaceGuid.PcdCpuLockBoxDataAddress|0
+  gEfiVLVTokenSpaceGuid.PcdCpuSmramCpuDataAddress|0
+  gEfiVLVTokenSpaceGuid.PcdCpuLockBoxSize|0
+
+[PcdsDynamicExDefault.X64.DEFAULT]
+!if $(RECOVERY_ENABLE)
+  gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareFileGuid|{GUID("AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215")}|VOID*|0x10
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSystemFmpCapsuleImageTypeIdGuid|{GUID("4096267b-da0a-42eb-b5eb-fef31d207cb4")}|VOID*|0x10
+!endif
+
+[Components.IA32]
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/SecCore.inf
+
+  !if $(MINNOW2_FSP_BUILD) == TRUE
+  IntelFspWrapperPkg/FspWrapperSecCore/FspWrapperSecCore.inf {
+    !if $(TARGET) == DEBUG
+
+    <LibraryClasses>
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+    !endif
+  }
+  Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.inf
+  IntelFspWrapperPkg/FspInitPei/FspInitPei.inf {
+    !if $(TARGET) == DEBUG
+    <LibraryClasses>
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+    !endif
+  }
+  !endif
+
+  MdeModulePkg/Core/Pei/PeiMain.inf {
+!if $(TARGET) == DEBUG
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
+!endif
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
+  }
+
+  $(PLATFORM_PACKAGE)/MonoStatusCode/MonoStatusCode.inf {
+!if $(TARGET) == DEBUG
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
+!endif
+  }
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/MemoryInit.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
+    <BuildOptions>
+      !if $(FTPM_ENABLE)==TRUE
+        *_*_IA32_CC_FLAGS = /D FTPM_ENABLE
+      !endif
+  }
+
+!if $(RC_BINARY_RELEASE) == TRUE
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/SeCUma.inf
+!endif
+
+!if $(FTPM_ENABLE) == TRUE
+$(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/fTPMInitPeim.inf
+!endif
+
+!if $(RC_BINARY_RELEASE) == TRUE
+  $(PLATFORM_PACKAGE)/PlatformPei/PlatformPei.inf {
+    <BuildOptions>
+      *_*_IA32_CC_FLAGS      = /DRC_BINARY_RELEASE
+  !if $(TARGET) == DEBUG
+      <PcdsFixedAtBuild>
+        gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
+  !endif
+  }
+!endif
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  SourceLevelDebugPkg/DebugAgentPei/DebugAgentPei.inf{
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+      DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
+      PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf
+      SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
+    }
+!endif
+
+!if $(FTPM_ENABLE) == TRUE
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/Tpm2DeviceSeCPei.inf
+!endif
+
+!if $(TPM_ENABLED) == TRUE
+  SecurityPkg/Tcg/PhysicalPresencePei/PhysicalPresencePei.inf
+  SecurityPkg/Tcg/TcgPei/TcgPei.inf {
+    <LibraryClasses>
+      NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+}
+!endif
+
+ $(PLATFORM_PACKAGE)/PlatformInitPei/PlatformInitPei.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x803805c6
+    <LibraryClasses>
+!if $(TARGET) != RELEASE
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!endif
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+  $(PLATFORM_PACKAGE)/FvInfoPei/FvInfoPei.inf
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/VlvInitPeim.inf
+!if $(PCIESC_ENABLE) == TRUE
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchEarlyInitPeim.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
+  }
+!endif
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchInitPeim.inf
+
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchSmbusArpDisabled.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchSpiPeim.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PeiSmmAccess.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PeiSmmControl.inf
+  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/CpuPeim.inf
+  UefiCpuPkg/CpuIoPei/CpuIoPei.inf
+  UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/MpS3.inf
+#  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PiSmmCommunicationPei.inf
+
+!if $(RECOVERY_ENABLE)
+  #
+  # Recovery
+  #
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchUsb.inf
+  MdeModulePkg/Bus/Pci/EhciPei/EhciPei.inf
+  MdeModulePkg/Bus/Usb/UsbBusPei/UsbBusPei.inf
+  MdeModulePkg/Bus/Usb/UsbBotPei/UsbBotPei.inf
+  FatPkg/FatPei/FatPei.inf
+  MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf
+  SignedCapsulePkg/Universal/RecoveryModuleLoadPei/RecoveryModuleLoadPei.inf {
+    <LibraryClasses>
+      FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibRsa2048Sha256/FmpAuthenticationLibRsa2048Sha256.inf
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+!endif
+
+!if $(CAPSULE_ENABLE) == TRUE
+  MdeModulePkg/Universal/CapsulePei/CapsulePei.inf
+!endif
+  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
+    <LibraryClasses>
+!if $(LZMA_ENABLE) == TRUE
+    NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+!endif
+  }
+
+ MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+ MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
+
+!if $(FTPM_ENABLE) == TRUE
+   SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
+    <LibraryClasses>
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+      NULL|SecurityPkg/Library\HashInstanceLibSha1/HashInstanceLibSha1.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+!endif
+!if $(TPM_ENABLED) == TRUE
+  SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+!endif
+!if $(ACPI50_ENABLE) == TRUE
+  MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.inf{
+    <LibraryClasses>
+      TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+  }
+
+!endif
+!if $(PERFORMANCE_ENABLE) == TRUE
+  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+!endif
+[Components.IA32]
+  !if $(MINNOW2_FSP_BUILD) == TRUE
+  IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.inf {
+    !if $(TARGET) == DEBUG
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
+    <LibraryClasses>
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+    !endif
+  }
+
+  !endif
+  #
+  # EDK II Related Platform codes
+  #
+  MdeModulePkg/Core/Dxe/DxeMain.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
+    <LibraryClasses>
+!if $(DXE_CRC32_SECTION_ENABLE) == TRUE
+      NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
+!endif
+!if $(LZMA_ENABLE) == TRUE
+      NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+!endif
+!if $(TARGET) != RELEASE
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!endif
+  }
+  IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3SaveDxe.inf {
+    <PcdsPatchableInModule>
+        gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
+    <PcdsFixedAtBuild>
+        gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x27
+    <LibraryClasses>
+    !if $(TARGET) != RELEASE
+          DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+    !endif
+       <BuildOptions>
+        ICC:*_*_*_CC_FLAGS = /D MDEPKG_NDEBUG
+        GCC:*_*_*_CC_FLAGS = -D MDEPKG_NDEBUG
+  }
+  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+  IntelFrameworkModulePkg/Universal/CpuIoDxe/CpuIoDxe.inf
+  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
+
+  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf  {
+    <LibraryClasses>
+!if $(TARGET) != RELEASE
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!endif
+  }
+
+  MdeModulePkg/Universal/ReportStatusCodeRouter/Smm/ReportStatusCodeRouterSmm.inf
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf{
+    <LibraryClasses>
+!if $(SECURE_BOOT_ENABLE) == TRUE
+      NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
+!endif
+!if $(USER_IDENTIFICATION_ENABLE)
+      NULL|SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.inf
+!endif
+!if $(TPM_ENABLED) == TRUE
+      NULL|SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf
+!endif
+!if $(FTPM_ENABLE) == TRUE
+      NULL|SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf
+!endif
+  }
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/MpCpu.inf
+  $(PLATFORM_PACKAGE)/Metronome/Metronome.inf
+
+  IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf{
+    <LibraryClasses>
+      OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+      IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+      BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+      PlatformBdsLib|$(PLATFORM_PACKAGE)/Library/PlatformBdsLib/PlatformBdsLib.inf
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+      SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
+    !if $(FTPM_ENABLE) == TRUE
+      Tpm2DeviceLib|Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.inf
+    !else
+      Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf
+    !endif
+  }
+
+  $(PLATFORM_PACKAGE)/UiApp/UiApp.inf
+
+  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
+      SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
+  }
+  $(PLATFORM_PACKAGE)/FvbRuntimeDxe/FvbSmm.inf
+  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSpiSmm.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf {
+    <LibraryClasses>
+      PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf
+    <BuildOptions>
+      #
+      # Specify GUID gEfiIfrBootMaintenanceGuid, to install Secure Boot Configuration menu
+      # into Boot Maintenance Manager menu
+      #
+      *_*_*_VFR_FLAGS   = -g b2dedc91-d59f-48d2-898a-12490c74a4e0
+  }
+!endif
+   MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf {
+    <LibraryClasses>
+      FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+  }
+
+  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
+  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+
+  $(PLATFORM_PACKAGE)/FvbRuntimeDxe/FvbRuntimeDxe.inf
+
+  $(PLATFORM_PACKAGE)/PlatformSetupDxe/PlatformSetupDxe.inf
+
+!if $(DATAHUB_ENABLE) == TRUE
+  IntelFrameworkModulePkg/Universal/DataHubDxe/DataHubDxe.inf {
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|0
+  }
+!endif
+  IntelFrameworkModulePkg/Universal/StatusCode/DatahubStatusCodeHandlerDxe/DatahubStatusCodeHandlerDxe.inf
+  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchS3SupportDxe.inf
+  !if $(USE_HPET_TIMER) == TRUE
+    PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf
+  !else
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmartTimer.inf
+  !endif
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmmControl.inf
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSmbusDxe.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/IntelPchLegacyInterrupt.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchReset.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchInitDxe.inf{
+    <PcdsPatchableInModule>
+        gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
+  }
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchInitSmm.inf
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSmiDispatcher.inf
+
+!if $(PCIESC_ENABLE) == TRUE
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchPcieSmm.inf
+!endif
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSpiRuntime.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchPolicyInitDxe.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchBiosWriteProtect.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmmAccess.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PciHostBridge.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/VlvInitDxe.inf
+
+  IntelFrameworkModulePkg/Universal/LegacyRegionDxe/LegacyRegionDxe.inf
+
+  #
+  # Performance Application; Set PERFORMANCE_ENABLE=TRUE for normal boot performance and smm performance data
+  #
+!if $(PERFORMANCE_ENABLE) == TRUE
+  ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf {
+    <PcdsFixedAtBuild>
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+  }
+!endif
+
+  Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInitDxe.inf{
+    <LibraryClasses>
+!if $(TARGET) != RELEASE
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!endif
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/Dptf.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PnpDxe.inf
+
+!if $(SEC_ENABLE) == TRUE
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/HeciDrv.inf {
+!if $(SEC_DEBUG_INFO_ENABLE) == TRUE
+    <BuildOptions>
+      *_*_X64_CC_FLAGS      = /DSEC_DEBUG_INFO=1
+!else
+    <BuildOptions>
+      *_*_X64_CC_FLAGS      = /DSEC_DEBUG_INFO=0
+!endif
+  }
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SeCPolicyInitDxe.inf
+!endif
+
+!if $(FTPM_ENABLE) == TRUE
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/Tpm2DeviceSeCDxe.inf
+  SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf
+  SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf{
+    <LibraryClasses>
+      NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
+      PcdLib|MdePkg/Library\DxePcdLib/DxePcdLib.inf
+      Tpm2DeviceLib|Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.inf
+  }
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/FtpmSmm.inf
+!endif
+!if $(TPM_ENABLED) == TRUE
+  SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+
+  SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+    <BuildOptions>
+      #
+      # specify GUID gEfiIfrNotInTPVPageGuid, this page will not
+      # be showed in TPV page.
+      #
+      *_*_*_VFR_FLAGS   = -g e58809f8-fbc1-48e2-883a-a30fdc4b441e
+  }
+
+  SecurityPkg/Tcg/TcgDxe/TcgDxe.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+  SecurityPkg/Tcg/TcgSmm/TcgSmm.inf
+!endif
+  #
+  # EDK II Related Platform codes
+  #
+  $(PLATFORM_PACKAGE)/PlatformSmm/PlatformSmm.inf{
+    <LibraryClasses>
+    !if $(TARGET) != RELEASE
+          DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+    !endif
+          PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+  $(PLATFORM_PACKAGE)/PlatformInfoDxe/PlatformInfoDxe.inf
+  $(PLATFORM_PACKAGE)/PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf
+  $(PLATFORM_PACKAGE)/PlatformDxe/PlatformDxe.inf
+
+  $(PLATFORM_PACKAGE)/PciPlatform/PciPlatform.inf
+  $(PLATFORM_PACKAGE)/SaveMemoryConfig/SaveMemoryConfig.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PlatformCpuPolicy.inf
+  $(PLATFORM_PACKAGE)/PpmPolicy/PpmPolicy.inf
+  $(PLATFORM_PACKAGE)/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.inf
+!if $(GOP_DRIVER_ENABLE) == TRUE
+  $(PLATFORM_PACKAGE)/PlatformGopPolicy/PlatformGopPolicy.inf
+
+!endif
+
+
+  #
+  # SMM
+  #
+  MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
+  MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
+  UefiCpuPkg/CpuDxe/CpuDxe.inf
+  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+  UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
+  MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
+  UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
+  $(PLATFORM_PACKAGE)/SmmSwDispatch2OnSmmSwDispatchThunk/SmmSwDispatch2OnSmmSwDispatchThunk.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PowerManagement2.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/DigitalThermalSensor.inf
+
+  #
+  # ACPI
+  #
+   MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x27
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+
+  $(PLATFORM_PACKAGE)/BootScriptSaveDxe/BootScriptSaveDxe.inf
+  IntelFrameworkModulePkg/Universal/Acpi/AcpiSupportDxe/AcpiSupportDxe.inf
+  Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/PowerManagementAcpiTables.inf
+
+  $(PLATFORM_RC_PACKAGE)/AcpiTablesPCAT/AcpiTables.inf
+
+  $(PLATFORM_PACKAGE)/AcpiPlatform/AcpiPlatform.inf
+
+  MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
+
+  #
+  # PCI
+  #
+  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/ISPDxe.inf
+
+
+#
+# ISA
+#
+  $(PLATFORM_PACKAGE)/Wpce791/Wpce791.inf
+  IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBusDxe.inf
+  IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaIoDxe.inf
+  IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf
+  IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf
+  IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf
+#
+# SDIO
+#
+#  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/MmcHost.inf
+#  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/MmcMediaDevice.inf
+!if $(ACPI50_ENABLE) == TRUE
+  MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf {
+    <LibraryClasses>
+      TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+  }
+  MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.inf {
+    <LibraryClasses>
+      TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+  }
+!endif
+
+#
+# IDE/SCSI/AHCI
+#
+  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+  IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBusDxe.inf
+  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+  FatPkg/EnhancedFatDxe/Fat.inf
+  ShellPkg/Application/Shell/Shell.inf {
+    <LibraryClasses>
+      ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
+      HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+      PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+      BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+      gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
+  }
+!if $(SATA_ENABLE) == TRUE
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SataController.inf
+!endif
+  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+!if $(SCSI_ENABLE) == TRUE
+  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+!endif
+#
+# Console
+#
+  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+  IntelFrameworkModulePkg/Universal/Console/VgaClassDxe/VgaClassDxe.inf
+  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+
+  #
+  # USB
+  #
+!if $(USB_ENABLE) == TRUE
+  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+  MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
+  MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
+  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+  MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+  MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
+  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+!endif
+
+  #
+  # SMBIOS
+  #
+  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+  $(PLATFORM_PACKAGE)/SmBiosMiscDxe/SmBiosMiscDxe.inf
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmbiosMemory.inf
+  #
+  # CPU/FW Microde
+  #
+  Vlv2SocBinPkg/Microcode/MicrocodeUpdates.inf {
+    <BuildOptions>
+      *_*_*_GENFW_FLAGS = -a 0x800 -p 0xFF
+  }
+
+
+
+!if $(NETWORK_ENABLE) == TRUE
+  !if $(NETWORK_ISCSI_ENABLE) == TRUE
+    NetworkPkg/IScsiDxe/IScsiDxe.inf
+  !endif
+  !if $(NETWORK_VLAN_ENABLE) == TRUE
+    MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf
+  !endif
+  !if $(CSM_ENABLE) == TRUE
+    IntelFrameworkModulePkg/Csm/BiosThunk/Snp16Dxe/Snp16Dxe.inf
+  !endif
+!endif
+
+!if $(NETWORK_ENABLE) == TRUE
+  #
+  # UEFI network modules
+  #
+    MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
+    MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf
+
+    MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
+    MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
+    MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
+    MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
+    MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
+    NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
+    NetworkPkg/TcpDxe/TcpDxe.inf
+    MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+    !if $(NETWORK_IP6_ENABLE) == TRUE
+      NetworkPkg/Ip6Dxe/Ip6Dxe.inf
+      NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
+      NetworkPkg/Udp6Dxe/Udp6Dxe.inf
+      NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
+    !endif
+!endif
+
+!if $(CAPSULE_ENABLE) || $(MICOCODE_CAPSULE_ENABLE)
+  MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxe.inf
+  MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
+!endif
+
+!if $(CAPSULE_ENABLE)
+  !include Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc
+  !include Vlv2TbltDevicePkg/FmpGreenSampleDevice.dsc
+  !include Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc
+  !include Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc
+!endif
+
+!if $(MICOCODE_CAPSULE_ENABLE)
+  IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.inf {
+    <LibraryClasses>
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+      SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
+  }
+!endif
+
+[BuildOptions]
+#
+# Define Build Options both for EDK and EDKII drivers.
+#
+
+#
+# Define token for different Platform
+#
+!if $(MINNOW2_FSP_BUILD) == TRUE
+  DEFINE MINNOW2_FSP_OPTION = /DMINNOW2_FSP_BUILD
+!else
+  DEFINE MINNOW2_FSP_OPTION =
+!endif
+
+!if $(ENBDT_PF_BUILD) == TRUE
+  DEFINE ENBDT_PF_ENABLE = /DENBDT_PF_ENABLE=1
+!else
+  DEFINE ENBDT_PF_ENABLE = /DENBDT_PF_ENABLE=0
+!endif
+
+
+!if $(CLKGEN_CONFIG_EXTRA_ENABLE) == TRUE
+  DEFINE CLKGEN_CONFIG_EXTRA_BUILD_OPTION = /DCLKGEN_CONFIG_EXTRA=1
+!else
+  DEFINE CLKGEN_CONFIG_EXTRA_BUILD_OPTION =
+!endif
+
+
+
+!if $(PCIESC_ENABLE) == TRUE
+  DEFINE PCIESC_SUPPORT_BUILD_OPTION = /DPCIESC_SUPPORT=1
+!else
+  DEFINE PCIESC_SUPPORT_BUILD_OPTION =
+!endif
+!if $(SATA_ENABLE) == TRUE
+  DEFINE SATA_SUPPORT_BUILD_OPTION = /DSATA_SUPPORT=1
+!else
+  DEFINE SATA_SUPPORT_BUILD_OPTION =
+!endif
+!if $(ENBDT_S3_SUPPORT) == TRUE
+  DEFINE ENBDT_S3_SUPPORT_OPTIONS = /DNOCS_S3_SUPPORT
+!else
+  DEFINE ENBDT_S3_SUPPORT_OPTIONS =
+!endif
+
+!if $(X64_CONFIG) == TRUE
+  DEFINE X64_BUILD_ENABLE = /DX64_BUILD_ENABLE=1
+!else
+  DEFINE X64_BUILD_ENABLE =
+!endif
+
+!if $(FTPM_ENABLE) == TRUE
+  DEFINE DSC_FTPM_BUILD_OPTIONS = /DFTPM_ENABLE
+!else
+  DEFINE DSC_FTPM_BUILD_OPTIONS =
+!endif
+!if $(TPM_ENABLED) == TRUE
+  DEFINE DSC_TPM_BUILD_OPTIONS = /DTPM_ENABLED
+!else
+  DEFINE DSC_TPM_BUILD_OPTIONS =
+!endif
+
+
+  DEFINE EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS = $(MINNOW2_FSP_OPTION) $(MINNOW2_BUILD_OPTION) $(ENBDT_PF_ENABLE) $(EXTERNAL_VGA_BUILD_OPTION) $(PCIE_ENUM_WA_BUILD_OPTION) $(X0_WA_ENABLE_BUILD_OPTION) $(A0_WA_ENABLE_BUILD_OPTION) $(MICROCODE_FREE_BUILD_OPTIONS) $(SIMICS_BUILD_OPTIONS) $(HYBRID_BUILD_OPTIONS) $(COMPACT_BUILD_OPTIONS) $(VP_BUILD_OPTIONS) $(SYSCTL_ID_BUILD_OPTION) $(CLKGEN_CONFIG_EXTRA_BUILD_OPTION) $(SYSCTL_X0_CONVERT_BOARD_OPTION) $(ENBDT_S3_SUPPORT_OPTIONS) $(SATA_SUPPORT_BUILD_OPTION) $(PCIESC_SUPPORT_BUILD_OPTION) $(DSC_FTPM_BUILD_OPTIONS) $(DSC_FTPM_ERROR_WR_BUILD_OPTIONS) $(DSC_TPM_BUILD_OPTIONS) $(DSC_BYTI_SECURE_BOOT_BUILD_OPTIONS)
+!if $(PERFORMANCE_ENABLE) == TRUE
+  DEFINE PDB_BUILD_OPTION = /Zi
+!endif
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  MSFT:*_*_X64_GENFW_FLAGS  = --keepexceptiontable
+  GCC:*_*_X64_GENFW_FLAGS   = --keepexceptiontable
+  INTEL:*_*_X64_GENFW_FLAGS = --keepexceptiontable
+!if $(TARGET) == DEBUG
+  DEFINE SOURCE_LEVEL_DEBUG_BUILD_OPTIONS = /Od /Oy-
+!endif
+!else
+  DEFINE SOURCE_LEVEL_DEBUG_BUILD_OPTIONS =
+
+!endif
+
+#
+# Force PE/COFF sections to be aligned at 4KB boundaries to support page level
+# protection of DXE_RUNTIME_DRIVER modules
+#
+[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
+  MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
+  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+
+#
+# Force PE/COFF sections to be aligned at 4KB boundaries to support page level
+# protection of DXE_SMM_DRIVER/SMM_CORE modules
+#
+[BuildOptions.common.EDKII.DXE_SMM_DRIVER, BuildOptions.common.EDKII.SMM_CORE]
+  MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
+  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+
+[BuildOptions.Common.EDK]
+
+#
+# Define token for different Platform
+#
+!if $(ENBDT_PF_BUILD) == TRUE
+  DEFINE ENBDT_PF_ENABLE = /DENBDT_PF_ENABLE=1
+!else
+  DEFINE ENBDT_PF_ENABLE = /DENBDT_PF_ENABLE=0
+!endif
+
+!if $(PERFORMANCE_ENABLE) == TRUE
+  RELEASE_*_*_DLINK_FLAGS = /DEBUG
+!endif
+
+!if $(S3_ENABLE) == TRUE
+  DEFINE DSC_S3_BUILD_OPTIONS = /DEFI_S3_RESUME
+!else
+  DEFINE DSC_S3_BUILD_OPTIONS =
+!endif
+
+!if $(ENBDT_S3_SUPPORT) == TRUE
+  DEFINE ENBDT_S3_SUPPORT_OPTIONS = /DNOCS_S3_SUPPORT
+!else
+  DEFINE ENBDT_S3_SUPPORT_OPTIONS =
+!endif
+
+!if $(X64_CONFIG) == TRUE
+  DEFINE X64_BUILD_ENABLE = /DX64_BUILD_ENABLE=1
+!else
+  DEFINE X64_BUILD_ENABLE =
+!endif
+
+
+  DEFINE EDK_GLUE_LIB_DEBUG  =
+  DEFINE DEBUG_BUILD_OPTIONS = /D EFI_DEBUG /D DEBUG_MODE=1  /GL- $(EDK_GLUE_LIB_DEBUG) /DEDKII_GLUE_DebugPrintErrorLevel=(EFI_D_ERROR)
+  DEFINE EDK_DSC_FEATURE_BUILD_OPTIONS = $(DSC_S3_BUILD_OPTIONS) $(DSC_ACPI_BUILD_OPTIONS) $(DSC_SEC_BUILD_OPTIONS) $(DSC_FTPM_BUILD_OPTIONS) $(DSC_FTPM_ERROR_WR_BUILD_OPTIONS) $(DSC_TPM_BUILD_OPTIONS) $(SOFTSDV_BUILD_OPTIONS) $(SIMICS_BUILD_OPTIONS) $(HYBRID_BUILD_OPTIONS) $(COMPACT_BUILD_OPTIONS) $(VP_BUILD_OPTIONS) $(QT_BUILD_OPTIONS) $(DSC_BYTI_SECURE_BOOT_BUILD_OPTIONS) /D$(PROJECT_SC_CHIPSET)
+
+  DEFINE EDK_DSC_OTHER_BUILD_OPTIONS = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS) $(SV_BUILD_OPTIONS) $(INTEL_FASTBOOT_BUILD_OPTION)
+  DEFINE EDK_DSC_GLOBAL_BUILD_OPTIONS = $(ENBDT_PF_ENABLE) $(EDK_DSC_FEATURE_BUILD_OPTIONS) $(EDK_DSC_OTHER_BUILD_OPTIONS) /D EFI_SPECIFICATION_VERSION=0x00020000  /D PI_SPECIFICATION_VERSION=0x00000009  /D TIANO_RELEASE_VERSION=0x00080006 /D SUPPORT_DEPRECATED_PCI_CFG_PPI /D CSM_SMMENTRY_PORT8DATA8 /D EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE) /D MAX_VARIABLE_SIZE=0x2000 /D EFI_FIRMWARE_VENDOR="L/"INTEL/"" /D EFI_BUILD_VERSION="L/"EDKII/"" /DEFI_PEI_REPORT_STATUS_CODE_ON $(ENBDT_S3_SUPPORT_OPTIONS)
+
+  *_*_IA32_ASM_FLAGS         = /DEFI32 /D EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h /DNOCS_S3_SUPPORT
+  DEBUG_*_IA32_CC_FLAGS      = /D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_IA32_CC_FLAGS    = /D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  DEBUG_*_IA32_VFRPP_FLAGS   = /D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_IA32_VFRPP_FLAGS = /D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  DEBUG_*_IA32_APP_FLAGS     = /D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_IA32_APP_FLAGS   = /D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  DEBUG_*_IA32_PP_FLAGS      = /D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_IA32_PP_FLAGS    = /D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  *_*_IA32_ASLPP_FLAGS       = /D EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
+  *_*_IA32_ASLCC_FLAGS       = /D EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
+  *_*_IA32_ASM16_FLAGS       = /D EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h
+
+  *_*_X64_ASM_FLAGS          = /DEFIX64 /D EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h /DNOCS_S3_SUPPORT
+  DEBUG_*_X64_CC_FLAGS       = /D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_X64_CC_FLAGS     = /D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  DEBUG_*_X64_VFRPP_FLAGS    = /D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_X64_VFRPP_FLAGS  = /D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  DEBUG_*_X64_APP_FLAGS      = /D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_X64_APP_FLAGS    = /D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  DEBUG_*_X64_PP_FLAGS       = /D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_X64_PP_FLAGS     = /D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  *_*_X64_ASLPP_FLAGS        = /D EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
+  *_*_X64_ASLCC_FLAGS        = /D EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
+  *_*_X64_ASM16_FLAGS        = /D EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h
+ # *_*_*_BUILD_FLAGS = -s
+  *_*_*_VFR_FLAGS   = -c
+  *_*_*_BUILD_FLAGS = -c
+
+[BuildOptions.Common.EDKII]
+  *_*_IA32_ASM_FLAGS     = $(VP_BUILD_OPTIONS) /D EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h /DNOCS_S3_SUPPORT
+
+  *_*_IA32_CC_FLAGS      = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+  *_*_IA32_VFRPP_FLAGS   = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+  *_*_IA32_APP_FLAGS     = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+  *_*_IA32_PP_FLAGS      = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+  *_*_IA32_ASLPP_FLAGS   = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+
+  *_*_X64_CC_FLAGS       = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS) $(SOURCE_LEVEL_DEBUG_BUILD_OPTIONS)
+  *_*_X64_VFRPP_FLAGS    = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+  *_*_X64_APP_FLAGS      = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+  *_*_X64_PP_FLAGS       = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+  *_*_X64_ASLPP_FLAGS    = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+
+
+[Components.IA32]
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/I2cBus.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
+  }
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/I2cHost.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
+  }
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/I2cPortA0Pio.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x00000043
+  }
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/I2cMmioDeviceDxe.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x00000043
+  }
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgX64.dsc b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgX64.dsc
new file mode 100644
index 0000000000..10d44d5652
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgX64.dsc
@@ -0,0 +1,1714 @@
+#/** @file
+# Platform description.
+#
+# Copyright (c) 2012  - 2019, 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]
+  PLATFORM_NAME                       = Vlv2TbltDevicePkg
+  PLATFORM_GUID                       = 465B0A0B-7AC1-443b-8F67-7B8DEC145F90
+  PLATFORM_VERSION                    = 0.1
+  DSC_SPECIFICATION                   = 0x00010005
+
+  #
+  # Set platform specific package/folder name, same as passed from PREBUILD script.
+  # PLATFORM_PACKAGE would be the same as PLATFORM_NAME as well as package build folder
+  # DEFINE only takes effect at R9 DSC and FDF.
+  #
+  DEFINE      PLATFORM_PACKAGE                = Vlv2TbltDevicePkg
+  DEFINE      PLATFORM_RC_PACKAGE             = Vlv2DeviceRefCodePkg
+  DEFINE      PLATFORM_BINARY_PACKAGE         = Vlv2SocBinPkg
+  OUTPUT_DIRECTORY                    = Build/$(PLATFORM_PACKAGE)
+  SUPPORTED_ARCHITECTURES             = IA32|X64
+  BUILD_TARGETS                       = DEBUG|RELEASE
+  SKUID_IDENTIFIER                    = DEFAULT
+
+  DEFINE CPU_ARCH                 =ValleyView2
+  DEFINE PROJECT_SC_FAMILY        =IntelPch
+  DEFINE PROJECT_SC_ROOT          =../$(PLATFORM_RC_PACKAGE)/ValleyView2Soc/SouthCluster
+  DEFINE PROJECT_VLV_ROOT          =../$(PLATFORM_RC_PACKAGE)/ValleyView2Soc/NorthCluster
+
+  DEFINE RC_BINARY_RELEASE        = TRUE
+  #
+  # Platform On/Off features are defined here
+  #
+  #
+  # Platform Support:: Set only one token except Crestview Hills
+  #
+  #   3.BayleyBay
+  #     ENBDT_PF_ENABLE  = TRUE
+  #
+  !include $(PLATFORM_PACKAGE)/AutoPlatformCFG.txt
+  !include $(PLATFORM_PACKAGE)/PlatformPkgConfig.dsc
+
+!if $(X64_CONFIG) == TRUE
+  DEFINE      DXE_ARCHITECTURE        = X64
+  DEFINE      EDK_DXE_ARCHITECTURE    = X64
+  DEFINE      UNDI_DXE_ARCHITECTURE   = 64
+!else
+  DEFINE      DXE_ARCHITECTURE        = IA32
+  DEFINE      EDK_DXE_ARCHITECTURE    = Ia32
+  DEFINE      UNDI_DXE_ARCHITECTURE   = 32
+!endif
+
+  FLASH_DEFINITION                    = $(PLATFORM_PACKAGE)/PlatformPkg.fdf
+!if $(LFMA_ENABLE) == TRUE
+  FIX_LOAD_TOP_MEMORY_ADDRESS         = 0xFFFFFFFFFFFFFFFF
+  DEFINE   TOP_MEMORY_ADDRESS         = 0xFFFFFFFFFFFFFFFF
+!else
+  FIX_LOAD_TOP_MEMORY_ADDRESS         = 0x0
+  DEFINE   TOP_MEMORY_ADDRESS         = 0x0
+!endif
+
+  DEFINE   PLATFORM_PCIEXPRESS_BASE   = 0E0000000
+
+  DEFINE SEC_ENABLE = FALSE
+  DEFINE SEC_DEBUG_INFO_ENABLE = FALSE
+  DEFINE FTPM_ENABLE = FALSE
+
+################################################################################
+#
+# SKU Identification section - list of all SKU IDs supported by this
+#                              Platform.
+#
+################################################################################
+[SkuIds]
+  0|DEFAULT              # The entry: 0|DEFAULT is reserved and always required.
+
+################################################################################
+#
+# Library Class section - list of all Library Classes needed by this Platform.
+#
+################################################################################
+[LibraryClasses.common]
+  #
+  # Entry point
+  #
+  PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
+  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+  DxeSmmDriverEntryPoint|IntelFrameworkPkg/Library/DxeSmmDriverEntryPoint/DxeSmmDriverEntryPoint.inf
+
+  #
+  # Basic
+  #
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+!if $(SSE2_ENABLE) == TRUE
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.inf
+!else
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
+!endif
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+  PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
+  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
+  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
+  CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+!if $(RC_BINARY_RELEASE) == TRUE
+  PchPlatformLib|Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLib.inf
+!endif
+  #
+  # UEFI & PI
+  #
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  UefiDecompressLib|MdeModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf
+  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+  UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
+  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+  GenericBdsLib|$(PLATFORM_PACKAGE)/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
+  BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf
+  SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
+  PlatformBdsLib|$(PLATFORM_PACKAGE)/Library/PlatformBdsLib/PlatformBdsLib.inf
+  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+  DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
+  FlashDeviceLib|$(PLATFORM_PACKAGE)/Library/FlashDeviceLib/FlashDeviceLib.inf
+  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+  #
+  # Framework
+  #
+!if $(S3_ENABLE) == TRUE
+  S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
+!else
+  S3BootScriptLib|MdePkg/Library/BaseS3BootScriptLibNull/BaseS3BootScriptLibNull.inf
+!endif
+  S3IoLib|MdePkg/Library/BaseS3IoLib/BaseS3IoLib.inf
+  S3PciLib|MdePkg/Library/BaseS3PciLib/BaseS3PciLib.inf
+
+  #
+  # Generic Modules
+  #
+!if $(USB_ENABLE) == TRUE
+  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+!endif
+!if $(SCSI_ENABLE) == TRUE
+  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+!endif
+!if $(NETWORK_ENABLE) == TRUE
+  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+  IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
+  UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
+  TcpIoLib|MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf
+  DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
+!endif
+!if $(S3_ENABLE) == TRUE
+  S3Lib|IntelFrameworkModulePkg/Library/PeiS3Lib/PeiS3Lib.inf
+!endif
+
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+!if $(CAPSULE_ENABLE) == TRUE
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf
+!else
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+!endif
+  FmpAuthenticationLib|MdeModulePkg/Library/FmpAuthenticationLibNull/FmpAuthenticationLibNull.inf
+  IniParsingLib|SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.inf
+  PlatformFlashAccessLib|Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.inf
+  MicrocodeFlashAccessLib|Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.inf
+  DisplayUpdateProgressLib|MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.inf
+  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
+  IoApicLib|PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+
+  #
+  # CPU
+  #
+  MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf
+  LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+  MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+
+  #
+  # ICH
+  #
+  SmbusLib|$(PLATFORM_PACKAGE)/Library/SmbusLib/SmbusLib.inf
+  SmmLib|$(PLATFORM_PACKAGE)/Library/PchSmmLib/PchSmmLib.inf
+
+  #
+  # Platform
+  #
+  TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+  ResetSystemLib|$(PLATFORM_PACKAGE)/Library/ResetSystemLib/ResetSystemLib.inf
+
+  PlatformCmosLib|$(PLATFORM_PACKAGE)/Library/PlatformCmosLib/PlatformCmosLib.inf
+
+  #
+  # Misc
+  #
+  MonoStatusCodeLib|$(PLATFORM_PACKAGE)/MonoStatusCode/MonoStatusCode.inf
+!if $(TARGET) == RELEASE
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+  SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
+!else
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+  SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
+!endif
+
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+!if $(TPM_ENABLED) == TRUE
+  TpmCommLib|SecurityPkg/Library/TpmCommLib/TpmCommLib.inf
+  Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf
+  Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLibDTpm.inf
+
+!endif
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
+  DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf
+  PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf
+  SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
+!else
+  PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+!endif
+
+  #
+  # CryptLib
+  #
+!if $(TPM_ENABLED) == TRUE
+  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+!endif
+
+ BiosIdLib|$(PLATFORM_PACKAGE)/Library/BiosIdLib/BiosIdLib.inf
+ CpuIA32Lib|$(PLATFORM_PACKAGE)/Library/CpuIA32Lib/CpuIA32Lib.inf
+
+  StallSmmLib|$(PLATFORM_PACKAGE)/Library/StallSmmLib/StallSmmLib.inf
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+  PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf
+  TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
+  AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
+  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+!else
+  TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
+  AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
+!endif
+  VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
+!if $(RC_BINARY_RELEASE) == TRUE
+  I2cLib|Vlv2TbltDevicePkg/Library/I2CLib/I2CLibNull.inf
+!endif
+  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+  ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
+  HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+!if $(FTPM_ENABLE) == TRUE || $(NETWORK_ISCSI_ENABLE) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+!endif
+  TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
+  Tcg2PhysicalPresenceLib|SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf
+  Tcg2PpVendorLib|SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.inf
+
+
+  Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
+!if $(MINNOW2_FSP_BUILD) == TRUE
+  FspApiLib|IntelFspWrapperPkg/Library/BaseFspApiLib/BaseFspApiLib.inf
+  FspPlatformInfoLib|IntelFspWrapperPkg/Library/BaseFspPlatformInfoLibSample/BaseFspPlatformInfoLibSample.inf
+  FspPlatformSecLib|Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/FspPlatformSecLibVlv2.inf
+  FspHobProcessLib|Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLibVlv2/FspHobProcessLibVlv2.inf
+!endif
+
+  BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
+
+[LibraryClasses.IA32.SEC]
+!if $(PERFORMANCE_ENABLE) == TRUE
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+!endif
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+
+[LibraryClasses.IA32.PEIM, LibraryClasses.IA32.PEI_CORE, LibraryClasses.IA32.SEC]
+  #
+  # PEI phase common
+  #
+
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+  MultiPlatformLib|$(PLATFORM_PACKAGE)/Library/MultiPlatformLib/MultiPlatformLib.inf
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
+  MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+
+!if $(PERFORMANCE_ENABLE) == TRUE
+  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+  TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+!endif
+
+!if $(TARGET) == RELEASE
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+  SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
+!else
+  DebugLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf
+  SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
+!endif
+
+  LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf
+  HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
+!endif
+
+ !if $(MINNOW2_FSP_BUILD) == TRUE
+ PlatformFspLib|Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.inf
+ !endif
+!if $(FTPM_ENABLE) == TRUE
+  Tpm2DeviceLib|Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.inf
+!endif
+
+[LibraryClasses.X64]
+  #
+  # DXE phase common
+  #
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+
+  TcgPhysicalPresenceLib|SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.inf
+!if $(TPM_ENABLED) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+!endif
+
+  LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf
+  EfiRegTableLib|$(PLATFORM_PACKAGE)/Library/EfiRegTableLib/EfiRegTableLib.inf
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+!endif
+
+  HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf
+
+[LibraryClasses.X64.DXE_DRIVER]
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+!if $(PERFORMANCE_ENABLE) == TRUE
+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+  TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+!endif
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+
+  FlashDeviceLib|$(PLATFORM_PACKAGE)/Library/FlashDeviceLib/FlashDeviceLibDxe.inf
+
+[LibraryClasses.X64.DXE_CORE]
+  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
+  MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+!if $(PERFORMANCE_ENABLE) == TRUE
+  PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
+  TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+!endif
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+
+[LibraryClasses.X64.DXE_SMM_DRIVER]
+  MmServicesTableLib|MdePkg/Library/MmServicesTableLib/MmServicesTableLib.inf
+  SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/SmmReportStatusCodeLib.inf
+  MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf
+  LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+  SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
+  SmmCpuPlatformHookLib|UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf
+  SmmCpuFeaturesLib|UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
+
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
+  !if $(TARGET) != RELEASE
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+  !endif
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf
+  TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+!endif
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
+
+[LibraryClasses.X64.SMM_CORE]
+  MemoryAllocationLib|MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf
+  SmmServicesTableLib|MdeModulePkg/Library/PiSmmCoreSmmServicesTableLib/PiSmmCoreSmmServicesTableLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/SmmReportStatusCodeLib.inf
+  SmmCorePlatformHookLib|MdeModulePkg/Library/SmmCorePlatformHookLibNull/SmmCorePlatformHookLibNull.inf
+  SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
+
+!if $(TPM_ENABLED) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
+!endif
+
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+
+!if $(TARGET) != RELEASE
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!endif
+
+[LibraryClasses.X64.DXE_RUNTIME_DRIVER]
+  ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+!endif
+!if $(TPM_ENABLED) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+!endif
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+
+!if $(CAPSULE_ENABLE) == TRUE
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf
+!endif
+
+[LibraryClasses.common.UEFI_DRIVER]
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+
+[LibraryClasses.X64.UEFI_APPLICATION]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+[PcdsFeatureFlag.common]
+!if $(MINI_BIOS_ENABLE) == FALSE
+  gPlatformModuleTokenSpaceGuid.PcdBdsDispatchAdditionalOprom|TRUE
+!else
+  gPlatformModuleTokenSpaceGuid.PcdBdsDispatchAdditionalOprom|FALSE
+!endif
+#
+# If PcdDxeIplSwitchToLongMode is TRUE, DxeIpl will load a 64-bit DxeCore and switch to long mode to hand over to DxeCore.
+#
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|TRUE
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserGrayOutTextStatement|TRUE
+
+!if $(CAPSULE_RESET_ENABLE) == TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|TRUE
+!else
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|FALSE
+!endif
+  gEfiCpuTokenSpaceGuid.PcdCpuSmmEnableBspElection|FALSE
+!if $(DATAHUB_STATUS_CODE_ENABLE) == TRUE
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeUseDataHub|TRUE
+!else
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeUseDataHub|FALSE
+!endif
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreImageLoaderSearchTeSectionFirst|FALSE
+!if $(TARGET) == RELEASE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
+!else
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
+!endif
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE
+!if $(ISA_SERIAL_STATUS_CODE_ENABLE) == TRUE
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseIsaSerial|TRUE
+!else
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseIsaSerial|FALSE
+!endif
+!if $(USB_SERIAL_STATUS_CODE_ENABLE) == TRUE
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseUsbSerial|TRUE
+!else
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseUsbSerial|FALSE
+!endif
+!if $(RAM_SERIAL_STATUS_CODE_ENABLE) == TRUE
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseRam|TRUE
+!else
+  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseRam|FALSE
+!endif
+
+
+  ## This PCD specifies whether PS2 keyboard does a extended verification during start.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPs2KbdExtendedVerification|FALSE
+
+  ## This PCD specifies whether PS2 mouse does a extended verification during start.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPs2MouseExtendedVerification|FALSE
+
+!if $(VARIABLE_INFO_ENABLE) == TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics|TRUE
+!else
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics|FALSE
+!endif
+
+  gEfiCpuTokenSpaceGuid.PcdCpuSmmBlockStartupThisAp|TRUE
+
+!if $(SOURCE_DEBUG_ENABLE)
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmDebug|TRUE
+!endif
+
+[PcdsFixedAtBuild.common]
+!if $(MINNOW2_FSP_BUILD) == TRUE
+# $(FLASH_REGION_VLVMICROCODE_BASE)
+  gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress|0xFFC00000
+# $(FLASH_REGION_VLVMICROCODE_SIZE)
+  gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize|0x00040000
+  gFspWrapperTokenSpaceGuid.PcdFlashMicroCodeOffset|0x60
+# $(FLASH_AREA_BASE_ADDRESS)
+  gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheAddress|0xFF800000
+# $(FLASH_AREA_SIZE)
+  gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheSize|0x00800000
+# $(FLASH_REGION_FSPBIN_BASE)
+  gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase|0xFFCC0000
+!endif
+
+!if $(PERFORMANCE_ENABLE) == TRUE
+!if $(MINNOW2_FSP_BUILD) == TRUE
+  # in FSP, when this got used, the memory already is up
+  gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0x00080000
+!else
+  gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0xFEF80000
+!endif
+  gEfiCpuTokenSpaceGuid.PcdTemporaryRamSize|0x00010000
+
+!else
+  !if $(MINNOW2_FSP_BUILD) == TRUE
+    gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0x00080000
+  !else
+    gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0xFEF80000
+  !endif
+  gEfiCpuTokenSpaceGuid.PcdTemporaryRamSize|0x00010000
+  gEfiCpuTokenSpaceGuid.PcdPeiTemporaryRamStackSize|0x3C00
+!endif
+
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x22000
+!else
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x4000
+!endif
+  gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize|0x00000800
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x400
+  gEfiCpuTokenSpaceGuid.PcdCpuIEDRamSize|0x400000
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemorySize|0x10000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAriSupport|FALSE
+  gEfiCpuTokenSpaceGuid.PcdCpuSmmApSyncTimeout|1000
+!if $(S4_ENABLE) == TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|TRUE
+!else
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+!endif
+!if $(TARGET) == RELEASE
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x3
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+!endif
+!if $(PERFORMANCE_ENABLE) == TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0x1
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPerformanceLogEntries|60
+!endif
+
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdEbdaReservedMemorySize|0x10000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable|$(TOP_MEMORY_ADDRESS)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserSubtitleTextColor|0x0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldTextColor|0x01
+  gEfiCpuTokenSpaceGuid.PcdCpuIEDEnabled|TRUE
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBiosVideoCheckVbeEnable|TRUE
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBiosVideoCheckVgaEnable|TRUE
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl|FALSE
+  gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod|2
+!endif
+
+  #
+  # Set SMM stack size to 16 KB.
+  #
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize|0x4000
+
+  #
+  # Clear unused single certificate PCD
+  #
+  gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer|{0}
+
+  #
+  # Lock all updatable firmware devices at End of DXE
+  #
+  gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceLockEventGuid|{GUID(gEfiEndOfDxeEventGroupGuid)}
+#  gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceLockEventGuid|{GUID(gEfiEventReadyToBootGuid)}
+
+  #
+  # Set PcdFmpDeviceTestKeySha256Digest to {0} to disable test key detection
+  #
+#  gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceTestKeySha256Digest|{0}
+
+[PcdsFixedAtBuild.IA32]
+!if $(TARGET) == RELEASE
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x3
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+!endif
+
+!if $(RECOVERY_ENABLE)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdRecoveryFileName|L"VLV2REC.Cap"
+!endif
+
+[PcdsPatchableInModule.common]
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x803805c6
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0x$(PLATFORM_PCIEXPRESS_BASE)
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLegacyBiosCacheLegacyRegion|FALSE
+
+  ## This PCD specifies whether to use the optimized timing for best PS2 detection performance.
+  #  Note this PCD could be set to TRUE for best boot performance and set to FALSE for best device compatibility.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFastPS2Detection|TRUE
+
+  #######################################################################################################
+  #
+  # Begin of MRC parameters
+  #
+
+  ## Memory Parameter Patchable.
+  #  FALSE - MRC Parameters are fixed for MinnowBoard Max<BR>
+  #  TRUE  - MRC Parameters are patchable by following PCDs<BR>
+  # @Prompt Memory Parameter Patchable.
+  # @ValidList 0x80000001 | 0, 1
+  gVlvRefCodePkgTokenSpaceGuid.PcdMemoryParameterPatchable|FALSE
+
+  ## Memory Down or DIMM slot.
+  #  0 - DIMM<BR>
+  #  1 - Memory Down<BR>
+  # @Prompt Enable Memory Down
+  # @ValidList 0x80000001 | 0, 1
+  gVlvRefCodePkgTokenSpaceGuid.PcdEnableMemoryDown|1
+
+  ## The speed of DRAM.
+  #  0 - 800 MHz<BR>
+  #  1 - 1066 MHz<BR>
+  #  2 - 1333 MHz<BR>
+  #  3 - 1600 MHz<BR>
+  # @Prompt DRAM Speed
+  # @ValidList 0x80000001 | 0, 1, 2, 3
+  gVlvRefCodePkgTokenSpaceGuid.PcdDramSpeed|1
+
+  ## DRAM Type.
+  #  0 - DDR3<BR>
+  #  1 - DDR3L<BR>
+  #  2 - DDR3U<BR>
+  #  3 - DDR3All<BR>
+  #  4 - LPDDR2<BR>
+  #  5 - LPDDR3<BR>
+  #  6 - DDR4<BR>
+  # @Prompt DRAM Type
+  # @ValidList 0x80000001 | 0, 1, 2, 3, 4, 5, 6
+  gVlvRefCodePkgTokenSpaceGuid.PcdDramType|1
+
+  ## Please populate DIMM slot 0 if only one DIMM is supported.
+  #  0 - Disable<BR>
+  #  1 - Enable<BR>
+  # @Prompt DIMM 0 Enable
+  # @ValidList 0x80000001 | 0, 1
+  gVlvRefCodePkgTokenSpaceGuid.PcdEnableDimm0|1
+
+  ## DIMM 1 has to be identical to DIMM 0.
+  #  0 - Disable<BR>
+  #  1 - Enable<BR>
+  # @Prompt DIMM 1 Enable Type
+  # @ValidList 0x80000001 | 0, 1
+  gVlvRefCodePkgTokenSpaceGuid.PcdEnableDimm1|0
+
+  ## DRAM device data width.
+  #  0 - x8<BR>
+  #  1 - x16<BR>
+  #  2 - x32<BR>
+  # @Prompt DIMM_DWIDTH
+  # @ValidList 0x80000001 | 0, 1, 2
+  gVlvRefCodePkgTokenSpaceGuid.PcdDimmDataWidth|1
+
+  ## DRAM device data density.
+  #  0 - 1 Gbit<BR>
+  #  1 - 2 Gbit<BR>
+  #  2 - 4 Gbit<BR>
+  #  3 - 8 Gbit<BR>
+  # @Prompt DIMM_Density
+  # @ValidList 0x80000001 | 0, 1, 2, 3
+  gVlvRefCodePkgTokenSpaceGuid.PcdDimmDensity|2
+
+  ## DRAM device data bus width.
+  #  0 - 8 bits<BR>
+  #  1 - 16 bits<BR>
+  #  2 - 32 bits<BR>
+  #  3 - 64 bits<BR>
+  # @Prompt DIMM_BusWidth
+  # @ValidList 0x80000001 | 0, 1, 2, 3
+  gVlvRefCodePkgTokenSpaceGuid.PcdDimmBusWidth|3
+
+  ## Ranks Per DIMM or Sides Per DIMM.
+  #  0 - 1 Rank<BR>
+  #  1 - 2 Ranks<BR>
+  # @Prompt DIMM_Sides
+  # @ValidList 0x80000001 | 0, 1
+  gVlvRefCodePkgTokenSpaceGuid.PcdRankPerDimm|0
+
+  ## tCL.<BR><BR>
+  # @Prompt tCL
+  gVlvRefCodePkgTokenSpaceGuid.PcdTcl|11
+
+  ## tRP and tRCD in DRAM clk - 5:12.5ns, 6:15ns, etc.
+  # @Prompt tRP_tRCD
+  gVlvRefCodePkgTokenSpaceGuid.PcdTrpTrcd|11
+
+  ## tWR in DRAM clk.
+  # @Prompt tWR
+  gVlvRefCodePkgTokenSpaceGuid.PcdTwr|12
+
+  ## tWTR in DRAM clk.
+  # @Prompt tWTR
+  gVlvRefCodePkgTokenSpaceGuid.PcdTwtr|6
+
+  ## tRRD in DRAM clk.
+  # @Prompt tRRD
+  gVlvRefCodePkgTokenSpaceGuid.PcdTrrd|6
+
+  ## tRTP in DRAM clk.
+  # @Prompt tRTP
+  gVlvRefCodePkgTokenSpaceGuid.PcdTrtp|6
+
+  ## tFAW in DRAM clk.
+  # @Prompt tFAW
+  gVlvRefCodePkgTokenSpaceGuid.PcdTfaw|32
+
+  #
+  # End of MRC parameters.
+  #
+  ###############################################################################################
+
+[PcdsDynamicHii.common.DEFAULT]
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|5 # Variable: L"Timeout"
+  gEfiMdePkgTokenSpaceGuid.PcdHardwareErrorRecordLevel|L"HwErrRecSupport"|gEfiGlobalVariableGuid|0x0|1 # Variable: L"HwErrRecSupport"
+
+[PcdsDynamicDefault.common.DEFAULT]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr|0x0
+  !if $(TPM_ENABLED) == TRUE
+    gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{0x7b, 0x3a, 0xcd, 0x72, 0xA5, 0xFE, 0x5e, 0x4f, 0x91, 0x65, 0x4d, 0xd1, 0x21, 0x87, 0xbb, 0x13}
+  !endif
+
+  ## This PCD defines the video horizontal resolution.
+  #  This PCD could be set to 0 then video resolution could be at highest resolution.
+  #gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|800
+  ## This PCD defines the video vertical resolution.
+  #  This PCD could be set to 0 then video resolution could be at highest resolution.
+  #gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600
+
+  ## This PCD defines the Console output column and the default value is 25 according to UEFI spec.
+  #  This PCD could be set to 0 then console output could be at max column and max row.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|31
+  ## This PCD defines the Console output row and the default value is 80 according to UEFI spec.
+  #  This PCD could be set to 0 then console output could be at max column and max row.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|100
+
+  ## The PCD is used to specify the video horizontal resolution of text setup.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|800
+  ## The PCD is used to specify the video vertical resolution of text setup.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|600
+  ## The PCD is used to specify the console output column of text setup.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutColumn|100
+  ## The PCD is used to specify the console output column of text setup.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutRow|31
+
+!if $(TPM_ENABLED) == TRUE
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInitializationPolicy|1
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmScrtmPolicy|1
+!endif
+
+[PcdsDynamicExDefault.common.DEFAULT]
+  gEfiVLVTokenSpaceGuid.PcdTCSmbaIoBaseAddress|0x1040
+  gEfiVLVTokenSpaceGuid.PcdEmmcManufacturerId|0
+  gEfiVLVTokenSpaceGuid.PcdProductSerialNumber|0
+  gEfiVLVTokenSpaceGuid.PcdMeasuredBootEnable|TRUE
+  gEfiVLVTokenSpaceGuid.PcdFTPMErrorOccur|FALSE
+  gEfiVLVTokenSpaceGuid.PcdFTPMErrorSkip|FALSE
+  gEfiVLVTokenSpaceGuid.PcdFTPMCommand|0
+  gEfiVLVTokenSpaceGuid.PcdFTPMResponse|0
+  gEfiVLVTokenSpaceGuid.PcdFTPMNotRespond|FALSE
+  gEfiVLVTokenSpaceGuid.PcdFTPMStatus|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateSmmDataPtr|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr|0
+  gEfiCpuTokenSpaceGuid.PcdCpuS3DataAddress|0
+  gEfiCpuTokenSpaceGuid.PcdCpuHotPlugDataAddress|0
+  gEfiCpuTokenSpaceGuid.PcdCpuCallbackSignal|0
+  gEfiCpuTokenSpaceGuid.PcdCpuConfigContextBuffer|0
+  gEfiVLVTokenSpaceGuid.PcdCpuLockBoxDataAddress|0
+  gEfiVLVTokenSpaceGuid.PcdCpuSmramCpuDataAddress|0
+  gEfiVLVTokenSpaceGuid.PcdCpuLockBoxSize|0
+
+[PcdsDynamicExDefault.X64.DEFAULT]
+!if $(RECOVERY_ENABLE)
+  gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareFileGuid|{GUID("AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215")}|VOID*|0x10
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSystemFmpCapsuleImageTypeIdGuid|{GUID("4096267b-da0a-42eb-b5eb-fef31d207cb4")}|VOID*|0x10
+!endif
+
+[Components.IA32]
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/SecCore.inf
+
+  !if $(MINNOW2_FSP_BUILD) == TRUE
+  IntelFspWrapperPkg/FspWrapperSecCore/FspWrapperSecCore.inf {
+    !if $(TARGET) == DEBUG
+
+    <LibraryClasses>
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+    !endif
+  }
+  Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.inf
+  IntelFspWrapperPkg/FspInitPei/FspInitPei.inf {
+    !if $(TARGET) == DEBUG
+    <LibraryClasses>
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+    !endif
+  }
+  !endif
+
+  MdeModulePkg/Core/Pei/PeiMain.inf {
+!if $(TARGET) == DEBUG
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
+!endif
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
+  }
+
+  $(PLATFORM_PACKAGE)/MonoStatusCode/MonoStatusCode.inf {
+!if $(TARGET) == DEBUG
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
+!endif
+  }
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/MemoryInit.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
+    <BuildOptions>
+      !if $(FTPM_ENABLE)==TRUE
+        *_*_IA32_CC_FLAGS = /D FTPM_ENABLE
+      !endif
+  }
+
+!if $(RC_BINARY_RELEASE) == TRUE
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/SeCUma.inf
+!endif
+
+!if $(FTPM_ENABLE) == TRUE
+$(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/fTPMInitPeim.inf
+!endif
+
+!if $(RC_BINARY_RELEASE) == TRUE
+  $(PLATFORM_PACKAGE)/PlatformPei/PlatformPei.inf {
+    <BuildOptions>
+      *_*_IA32_CC_FLAGS      = /DRC_BINARY_RELEASE
+  !if $(TARGET) == DEBUG
+      <PcdsFixedAtBuild>
+        gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
+  !endif
+  }
+!endif
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  SourceLevelDebugPkg/DebugAgentPei/DebugAgentPei.inf{
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+      DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
+      PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf
+      SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
+    }
+!endif
+
+!if $(FTPM_ENABLE) == TRUE
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/Tpm2DeviceSeCPei.inf
+!endif
+
+!if $(TPM_ENABLED) == TRUE
+  SecurityPkg/Tcg/PhysicalPresencePei/PhysicalPresencePei.inf
+  SecurityPkg/Tcg/TcgPei/TcgPei.inf {
+    <LibraryClasses>
+      NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+}
+!endif
+
+ $(PLATFORM_PACKAGE)/PlatformInitPei/PlatformInitPei.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x803805c6
+    <LibraryClasses>
+!if $(TARGET) != RELEASE
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!endif
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+  $(PLATFORM_PACKAGE)/FvInfoPei/FvInfoPei.inf
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/VlvInitPeim.inf
+!if $(PCIESC_ENABLE) == TRUE
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchEarlyInitPeim.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
+  }
+!endif
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchInitPeim.inf
+
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchSmbusArpDisabled.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchSpiPeim.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PeiSmmAccess.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PeiSmmControl.inf
+  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/CpuPeim.inf
+  UefiCpuPkg/CpuIoPei/CpuIoPei.inf
+  UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/MpS3.inf
+#  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PiSmmCommunicationPei.inf
+
+!if $(RECOVERY_ENABLE)
+  #
+  # Recovery
+  #
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchUsb.inf
+  MdeModulePkg/Bus/Pci/EhciPei/EhciPei.inf
+  MdeModulePkg/Bus/Usb/UsbBusPei/UsbBusPei.inf
+  MdeModulePkg/Bus/Usb/UsbBotPei/UsbBotPei.inf
+  FatPkg/FatPei/FatPei.inf
+  MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf
+  SignedCapsulePkg/Universal/RecoveryModuleLoadPei/RecoveryModuleLoadPei.inf {
+    <LibraryClasses>
+      FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibRsa2048Sha256/FmpAuthenticationLibRsa2048Sha256.inf
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+!endif
+
+!if $(CAPSULE_ENABLE) == TRUE
+  MdeModulePkg/Universal/CapsulePei/CapsulePei.inf
+!endif
+  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
+    <LibraryClasses>
+!if $(LZMA_ENABLE) == TRUE
+    NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+!endif
+  }
+
+ MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+ MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
+
+!if $(FTPM_ENABLE) == TRUE
+   SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
+    <LibraryClasses>
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+      NULL|SecurityPkg/Library\HashInstanceLibSha1/HashInstanceLibSha1.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+!endif
+!if $(TPM_ENABLED) == TRUE
+  SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+!endif
+!if $(ACPI50_ENABLE) == TRUE
+  MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.inf{
+    <LibraryClasses>
+      TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+  }
+
+!endif
+!if $(PERFORMANCE_ENABLE) == TRUE
+  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+!endif
+[Components.X64]
+  !if $(MINNOW2_FSP_BUILD) == TRUE
+  IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.inf {
+    !if $(TARGET) == DEBUG
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
+    <LibraryClasses>
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+    !endif
+  }
+
+  !endif
+  #
+  # EDK II Related Platform codes
+  #
+  MdeModulePkg/Core/Dxe/DxeMain.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
+    <LibraryClasses>
+!if $(DXE_CRC32_SECTION_ENABLE) == TRUE
+      NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
+!endif
+!if $(LZMA_ENABLE) == TRUE
+      NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+!endif
+!if $(TARGET) != RELEASE
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!endif
+  }
+  IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3SaveDxe.inf {
+    <PcdsPatchableInModule>
+        gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
+    <PcdsFixedAtBuild>
+        gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x27
+    <LibraryClasses>
+    !if $(TARGET) != RELEASE
+          DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+    !endif
+       <BuildOptions>
+        ICC:*_*_*_CC_FLAGS = /D MDEPKG_NDEBUG
+        GCC:*_*_*_CC_FLAGS = -D MDEPKG_NDEBUG
+  }
+  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+  IntelFrameworkModulePkg/Universal/CpuIoDxe/CpuIoDxe.inf
+  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
+
+  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf  {
+    <LibraryClasses>
+!if $(TARGET) != RELEASE
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!endif
+  }
+
+!if $(CAPSULE_ENABLE) == TRUE
+  MdeModulePkg/Universal/CapsulePei/CapsuleX64.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+      MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+      HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+      CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+      DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
+!endif
+  }
+!endif
+
+  MdeModulePkg/Universal/ReportStatusCodeRouter/Smm/ReportStatusCodeRouterSmm.inf
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf{
+    <LibraryClasses>
+!if $(SECURE_BOOT_ENABLE) == TRUE
+      NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
+!endif
+!if $(USER_IDENTIFICATION_ENABLE)
+      NULL|SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.inf
+!endif
+!if $(TPM_ENABLED) == TRUE
+      NULL|SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf
+!endif
+!if $(FTPM_ENABLE) == TRUE
+      NULL|SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf
+!endif
+  }
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/MpCpu.inf
+  $(PLATFORM_PACKAGE)/Metronome/Metronome.inf
+
+  IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf{
+    <LibraryClasses>
+      OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+      IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+      BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+      PlatformBdsLib|$(PLATFORM_PACKAGE)/Library/PlatformBdsLib/PlatformBdsLib.inf
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+      SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
+    !if $(FTPM_ENABLE) == TRUE
+      Tpm2DeviceLib|Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.inf
+    !else
+      Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf
+    !endif
+  }
+
+  $(PLATFORM_PACKAGE)/UiApp/UiApp.inf
+
+  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
+      SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
+  }
+  $(PLATFORM_PACKAGE)/FvbRuntimeDxe/FvbSmm.inf
+  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSpiSmm.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf {
+    <LibraryClasses>
+      PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf
+    <BuildOptions>
+      #
+      # Specify GUID gEfiIfrBootMaintenanceGuid, to install Secure Boot Configuration menu
+      # into Boot Maintenance Manager menu
+      #
+      *_*_*_VFR_FLAGS   = -g b2dedc91-d59f-48d2-898a-12490c74a4e0
+  }
+!endif
+   MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf {
+    <LibraryClasses>
+      FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+  }
+
+  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
+  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+
+  $(PLATFORM_PACKAGE)/FvbRuntimeDxe/FvbRuntimeDxe.inf
+
+  $(PLATFORM_PACKAGE)/PlatformSetupDxe/PlatformSetupDxe.inf
+
+!if $(DATAHUB_ENABLE) == TRUE
+  IntelFrameworkModulePkg/Universal/DataHubDxe/DataHubDxe.inf {
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|0
+  }
+!endif
+  IntelFrameworkModulePkg/Universal/StatusCode/DatahubStatusCodeHandlerDxe/DatahubStatusCodeHandlerDxe.inf
+  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchS3SupportDxe.inf
+  !if $(USE_HPET_TIMER) == TRUE
+    PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf
+  !else
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmartTimer.inf
+  !endif
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmmControl.inf
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSmbusDxe.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/IntelPchLegacyInterrupt.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchReset.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchInitDxe.inf{
+    <PcdsPatchableInModule>
+        gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
+  }
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchInitSmm.inf
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSmiDispatcher.inf
+
+!if $(PCIESC_ENABLE) == TRUE
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchPcieSmm.inf
+!endif
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSpiRuntime.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchPolicyInitDxe.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchBiosWriteProtect.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmmAccess.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PciHostBridge.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/VlvInitDxe.inf
+
+  IntelFrameworkModulePkg/Universal/LegacyRegionDxe/LegacyRegionDxe.inf
+
+  #
+  # Performance Application; Set PERFORMANCE_ENABLE=TRUE for normal boot performance and smm performance data
+  #
+!if $(PERFORMANCE_ENABLE) == TRUE
+  ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf {
+    <PcdsFixedAtBuild>
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+  }
+!endif
+
+  Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInitDxe.inf{
+    <LibraryClasses>
+!if $(TARGET) != RELEASE
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!endif
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/Dptf.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PnpDxe.inf
+
+!if $(SEC_ENABLE) == TRUE
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/HeciDrv.inf {
+!if $(SEC_DEBUG_INFO_ENABLE) == TRUE
+    <BuildOptions>
+      *_*_X64_CC_FLAGS      = /DSEC_DEBUG_INFO=1
+!else
+    <BuildOptions>
+      *_*_X64_CC_FLAGS      = /DSEC_DEBUG_INFO=0
+!endif
+  }
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SeCPolicyInitDxe.inf
+!endif
+
+!if $(FTPM_ENABLE) == TRUE
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/Tpm2DeviceSeCDxe.inf
+  SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf
+  SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf{
+    <LibraryClasses>
+      NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
+      NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
+      PcdLib|MdePkg/Library\DxePcdLib/DxePcdLib.inf
+      Tpm2DeviceLib|Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.inf
+  }
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/FtpmSmm.inf
+!endif
+!if $(TPM_ENABLED) == TRUE
+  SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+
+  SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+    <BuildOptions>
+      #
+      # specify GUID gEfiIfrNotInTPVPageGuid, this page will not
+      # be showed in TPV page.
+      #
+      *_*_*_VFR_FLAGS   = -g e58809f8-fbc1-48e2-883a-a30fdc4b441e
+  }
+
+  SecurityPkg/Tcg/TcgDxe/TcgDxe.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+  SecurityPkg/Tcg/TcgSmm/TcgSmm.inf
+!endif
+  #
+  # EDK II Related Platform codes
+  #
+  $(PLATFORM_PACKAGE)/PlatformSmm/PlatformSmm.inf{
+    <LibraryClasses>
+    !if $(TARGET) != RELEASE
+          DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+    !endif
+          PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+  $(PLATFORM_PACKAGE)/PlatformInfoDxe/PlatformInfoDxe.inf
+  $(PLATFORM_PACKAGE)/PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf
+  $(PLATFORM_PACKAGE)/PlatformDxe/PlatformDxe.inf
+
+  $(PLATFORM_PACKAGE)/PciPlatform/PciPlatform.inf
+  $(PLATFORM_PACKAGE)/SaveMemoryConfig/SaveMemoryConfig.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PlatformCpuPolicy.inf
+  $(PLATFORM_PACKAGE)/PpmPolicy/PpmPolicy.inf
+  $(PLATFORM_PACKAGE)/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.inf
+!if $(GOP_DRIVER_ENABLE) == TRUE
+  $(PLATFORM_PACKAGE)/PlatformGopPolicy/PlatformGopPolicy.inf
+
+!endif
+
+
+  #
+  # SMM
+  #
+  MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
+  MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
+  UefiCpuPkg/CpuDxe/CpuDxe.inf
+  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+  UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
+  MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
+  UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
+  $(PLATFORM_PACKAGE)/SmmSwDispatch2OnSmmSwDispatchThunk/SmmSwDispatch2OnSmmSwDispatchThunk.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PowerManagement2.inf
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/DigitalThermalSensor.inf
+
+  #
+  # ACPI
+  #
+   MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x27
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+
+  $(PLATFORM_PACKAGE)/BootScriptSaveDxe/BootScriptSaveDxe.inf
+  IntelFrameworkModulePkg/Universal/Acpi/AcpiSupportDxe/AcpiSupportDxe.inf
+  Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/PowerManagementAcpiTables.inf
+
+  $(PLATFORM_RC_PACKAGE)/AcpiTablesPCAT/AcpiTables.inf
+
+  $(PLATFORM_PACKAGE)/AcpiPlatform/AcpiPlatform.inf
+
+  MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
+
+  #
+  # PCI
+  #
+  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/ISPDxe.inf
+
+
+#
+# ISA
+#
+  $(PLATFORM_PACKAGE)/Wpce791/Wpce791.inf
+  IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBusDxe.inf
+  IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaIoDxe.inf
+  IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf
+  IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf
+  IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf
+#
+# SDIO
+#
+#  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/MmcHost.inf
+#  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/MmcMediaDevice.inf
+!if $(ACPI50_ENABLE) == TRUE
+  MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf {
+    <LibraryClasses>
+      TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+  }
+  MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.inf {
+    <LibraryClasses>
+      TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf
+  }
+!endif
+
+#
+# IDE/SCSI/AHCI
+#
+  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+  IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBusDxe.inf
+  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+  FatPkg/EnhancedFatDxe/Fat.inf
+  ShellPkg/Application/Shell/Shell.inf {
+    <LibraryClasses>
+      ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
+      HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+      PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+      BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+      gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
+  }
+!if $(SATA_ENABLE) == TRUE
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SataController.inf
+!endif
+  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+!if $(SCSI_ENABLE) == TRUE
+  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+!endif
+#
+# Console
+#
+  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+  IntelFrameworkModulePkg/Universal/Console/VgaClassDxe/VgaClassDxe.inf
+  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+
+  #
+  # USB
+  #
+!if $(USB_ENABLE) == TRUE
+  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+  MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
+  MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
+  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+  MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+  MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
+  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+!endif
+
+  #
+  # SMBIOS
+  #
+  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+  $(PLATFORM_PACKAGE)/SmBiosMiscDxe/SmBiosMiscDxe.inf
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmbiosMemory.inf
+  #
+  # CPU/FW Microde
+  #
+  Vlv2SocBinPkg/Microcode/MicrocodeUpdates.inf {
+    <BuildOptions>
+      *_*_*_GENFW_FLAGS = -a 0x800 -p 0xFF
+  }
+
+
+
+!if $(NETWORK_ENABLE) == TRUE
+  !if $(NETWORK_ISCSI_ENABLE) == TRUE
+    NetworkPkg/IScsiDxe/IScsiDxe.inf
+  !endif
+  !if $(NETWORK_VLAN_ENABLE) == TRUE
+    MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf
+  !endif
+  !if $(CSM_ENABLE) == TRUE
+    IntelFrameworkModulePkg/Csm/BiosThunk/Snp16Dxe/Snp16Dxe.inf
+  !endif
+!endif
+
+!if $(NETWORK_ENABLE) == TRUE
+  #
+  # UEFI network modules
+  #
+    MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
+    MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf
+
+    MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
+    MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
+    MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
+    MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
+    MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
+    NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
+    NetworkPkg/TcpDxe/TcpDxe.inf
+    MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+    !if $(NETWORK_IP6_ENABLE) == TRUE
+      NetworkPkg/Ip6Dxe/Ip6Dxe.inf
+      NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
+      NetworkPkg/Udp6Dxe/Udp6Dxe.inf
+      NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
+    !endif
+!endif
+
+!if $(CAPSULE_ENABLE) || $(MICOCODE_CAPSULE_ENABLE)
+  MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxe.inf
+  MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
+!endif
+
+!if $(CAPSULE_ENABLE)
+  !include Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc
+  !include Vlv2TbltDevicePkg/FmpGreenSampleDevice.dsc
+  !include Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc
+  !include Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc
+!endif
+
+!if $(MICOCODE_CAPSULE_ENABLE)
+  IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.inf {
+    <LibraryClasses>
+      DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+      SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
+  }
+!endif
+
+[BuildOptions]
+#
+# Define Build Options both for EDK and EDKII drivers.
+#
+
+#
+# Define token for different Platform
+#
+!if $(MINNOW2_FSP_BUILD) == TRUE
+  DEFINE MINNOW2_FSP_OPTION = /DMINNOW2_FSP_BUILD
+!else
+  DEFINE MINNOW2_FSP_OPTION =
+!endif
+
+!if $(ENBDT_PF_BUILD) == TRUE
+  DEFINE ENBDT_PF_ENABLE = /DENBDT_PF_ENABLE=1
+!else
+  DEFINE ENBDT_PF_ENABLE = /DENBDT_PF_ENABLE=0
+!endif
+
+
+!if $(CLKGEN_CONFIG_EXTRA_ENABLE) == TRUE
+  DEFINE CLKGEN_CONFIG_EXTRA_BUILD_OPTION = /DCLKGEN_CONFIG_EXTRA=1
+!else
+  DEFINE CLKGEN_CONFIG_EXTRA_BUILD_OPTION =
+!endif
+
+
+
+!if $(PCIESC_ENABLE) == TRUE
+  DEFINE PCIESC_SUPPORT_BUILD_OPTION = /DPCIESC_SUPPORT=1
+!else
+  DEFINE PCIESC_SUPPORT_BUILD_OPTION =
+!endif
+!if $(SATA_ENABLE) == TRUE
+  DEFINE SATA_SUPPORT_BUILD_OPTION = /DSATA_SUPPORT=1
+!else
+  DEFINE SATA_SUPPORT_BUILD_OPTION =
+!endif
+!if $(ENBDT_S3_SUPPORT) == TRUE
+  DEFINE ENBDT_S3_SUPPORT_OPTIONS = /DNOCS_S3_SUPPORT
+!else
+  DEFINE ENBDT_S3_SUPPORT_OPTIONS =
+!endif
+
+!if $(X64_CONFIG) == TRUE
+  DEFINE X64_BUILD_ENABLE = /DX64_BUILD_ENABLE=1
+!else
+  DEFINE X64_BUILD_ENABLE =
+!endif
+
+!if $(FTPM_ENABLE) == TRUE
+  DEFINE DSC_FTPM_BUILD_OPTIONS = /DFTPM_ENABLE
+!else
+  DEFINE DSC_FTPM_BUILD_OPTIONS =
+!endif
+!if $(TPM_ENABLED) == TRUE
+  DEFINE DSC_TPM_BUILD_OPTIONS = /DTPM_ENABLED
+!else
+  DEFINE DSC_TPM_BUILD_OPTIONS =
+!endif
+
+
+  DEFINE EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS = $(MINNOW2_FSP_OPTION) $(MINNOW2_BUILD_OPTION) $(ENBDT_PF_ENABLE) $(EXTERNAL_VGA_BUILD_OPTION) $(PCIE_ENUM_WA_BUILD_OPTION) $(X0_WA_ENABLE_BUILD_OPTION) $(A0_WA_ENABLE_BUILD_OPTION) $(MICROCODE_FREE_BUILD_OPTIONS) $(SIMICS_BUILD_OPTIONS) $(HYBRID_BUILD_OPTIONS) $(COMPACT_BUILD_OPTIONS) $(VP_BUILD_OPTIONS) $(SYSCTL_ID_BUILD_OPTION) $(CLKGEN_CONFIG_EXTRA_BUILD_OPTION) $(SYSCTL_X0_CONVERT_BOARD_OPTION) $(ENBDT_S3_SUPPORT_OPTIONS) $(SATA_SUPPORT_BUILD_OPTION) $(PCIESC_SUPPORT_BUILD_OPTION) $(DSC_FTPM_BUILD_OPTIONS) $(DSC_FTPM_ERROR_WR_BUILD_OPTIONS) $(DSC_TPM_BUILD_OPTIONS) $(DSC_BYTI_SECURE_BOOT_BUILD_OPTIONS)
+!if $(PERFORMANCE_ENABLE) == TRUE
+  DEFINE PDB_BUILD_OPTION = /Zi
+!endif
+
+!if $(SOURCE_DEBUG_ENABLE) == TRUE
+  MSFT:*_*_X64_GENFW_FLAGS  = --keepexceptiontable
+  GCC:*_*_X64_GENFW_FLAGS   = --keepexceptiontable
+  INTEL:*_*_X64_GENFW_FLAGS = --keepexceptiontable
+!if $(TARGET) == DEBUG
+  DEFINE SOURCE_LEVEL_DEBUG_BUILD_OPTIONS = /Od /Oy-
+!endif
+!else
+  DEFINE SOURCE_LEVEL_DEBUG_BUILD_OPTIONS =
+
+!endif
+
+#
+# Force PE/COFF sections to be aligned at 4KB boundaries to support page level
+# protection of DXE_RUNTIME_DRIVER modules
+#
+[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
+  MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
+  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+
+#
+# Force PE/COFF sections to be aligned at 4KB boundaries to support page level
+# protection of DXE_SMM_DRIVER/SMM_CORE modules
+#
+[BuildOptions.common.EDKII.DXE_SMM_DRIVER, BuildOptions.common.EDKII.SMM_CORE]
+  MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
+  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+
+[BuildOptions.Common.EDK]
+
+#
+# Define token for different Platform
+#
+!if $(ENBDT_PF_BUILD) == TRUE
+  DEFINE ENBDT_PF_ENABLE = /DENBDT_PF_ENABLE=1
+!else
+  DEFINE ENBDT_PF_ENABLE = /DENBDT_PF_ENABLE=0
+!endif
+
+!if $(PERFORMANCE_ENABLE) == TRUE
+  RELEASE_*_*_DLINK_FLAGS = /DEBUG
+!endif
+
+!if $(S3_ENABLE) == TRUE
+  DEFINE DSC_S3_BUILD_OPTIONS = /DEFI_S3_RESUME
+!else
+  DEFINE DSC_S3_BUILD_OPTIONS =
+!endif
+
+!if $(ENBDT_S3_SUPPORT) == TRUE
+  DEFINE ENBDT_S3_SUPPORT_OPTIONS = /DNOCS_S3_SUPPORT
+!else
+  DEFINE ENBDT_S3_SUPPORT_OPTIONS =
+!endif
+
+!if $(X64_CONFIG) == TRUE
+  DEFINE X64_BUILD_ENABLE = /DX64_BUILD_ENABLE=1
+!else
+  DEFINE X64_BUILD_ENABLE =
+!endif
+
+
+  DEFINE EDK_GLUE_LIB_DEBUG  =
+  DEFINE DEBUG_BUILD_OPTIONS = /D EFI_DEBUG /D DEBUG_MODE=1  /GL- $(EDK_GLUE_LIB_DEBUG) /DEDKII_GLUE_DebugPrintErrorLevel=(EFI_D_ERROR)
+  DEFINE EDK_DSC_FEATURE_BUILD_OPTIONS = $(DSC_S3_BUILD_OPTIONS) $(DSC_ACPI_BUILD_OPTIONS) $(DSC_SEC_BUILD_OPTIONS) $(DSC_FTPM_BUILD_OPTIONS) $(DSC_FTPM_ERROR_WR_BUILD_OPTIONS) $(DSC_TPM_BUILD_OPTIONS) $(SOFTSDV_BUILD_OPTIONS) $(SIMICS_BUILD_OPTIONS) $(HYBRID_BUILD_OPTIONS) $(COMPACT_BUILD_OPTIONS) $(VP_BUILD_OPTIONS) $(QT_BUILD_OPTIONS) $(DSC_BYTI_SECURE_BOOT_BUILD_OPTIONS) /D$(PROJECT_SC_CHIPSET)
+
+  DEFINE EDK_DSC_OTHER_BUILD_OPTIONS = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS) $(SV_BUILD_OPTIONS) $(INTEL_FASTBOOT_BUILD_OPTION)
+  DEFINE EDK_DSC_GLOBAL_BUILD_OPTIONS = $(ENBDT_PF_ENABLE) $(EDK_DSC_FEATURE_BUILD_OPTIONS) $(EDK_DSC_OTHER_BUILD_OPTIONS) /D EFI_SPECIFICATION_VERSION=0x00020000  /D PI_SPECIFICATION_VERSION=0x00000009  /D TIANO_RELEASE_VERSION=0x00080006 /D SUPPORT_DEPRECATED_PCI_CFG_PPI /D CSM_SMMENTRY_PORT8DATA8 /D EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE) /D MAX_VARIABLE_SIZE=0x2000 /D EFI_FIRMWARE_VENDOR="L/"INTEL/"" /D EFI_BUILD_VERSION="L/"EDKII/"" /DEFI_PEI_REPORT_STATUS_CODE_ON $(ENBDT_S3_SUPPORT_OPTIONS)
+
+  *_*_IA32_ASM_FLAGS         = /DEFI32 /D EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h /DNOCS_S3_SUPPORT
+  DEBUG_*_IA32_CC_FLAGS      = /D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_IA32_CC_FLAGS    = /D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  DEBUG_*_IA32_VFRPP_FLAGS   = /D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_IA32_VFRPP_FLAGS = /D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  DEBUG_*_IA32_APP_FLAGS     = /D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_IA32_APP_FLAGS   = /D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  DEBUG_*_IA32_PP_FLAGS      = /D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_IA32_PP_FLAGS    = /D EFI32 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  *_*_IA32_ASLPP_FLAGS       = /D EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
+  *_*_IA32_ASLCC_FLAGS       = /D EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
+  *_*_IA32_ASM16_FLAGS       = /D EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h
+
+  *_*_X64_ASM_FLAGS          = /DEFIX64 /D EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h /DNOCS_S3_SUPPORT
+  DEBUG_*_X64_CC_FLAGS       = /D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_X64_CC_FLAGS     = /D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  DEBUG_*_X64_VFRPP_FLAGS    = /D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_X64_VFRPP_FLAGS  = /D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  DEBUG_*_X64_APP_FLAGS      = /D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_X64_APP_FLAGS    = /D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  DEBUG_*_X64_PP_FLAGS       = /D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
+  RELEASE_*_X64_PP_FLAGS     = /D EFIX64 $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
+  *_*_X64_ASLPP_FLAGS        = /D EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
+  *_*_X64_ASLCC_FLAGS        = /D EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
+  *_*_X64_ASM16_FLAGS        = /D EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h
+ # *_*_*_BUILD_FLAGS = -s
+  *_*_*_VFR_FLAGS   = -c
+  *_*_*_BUILD_FLAGS = -c
+
+[BuildOptions.Common.EDKII]
+  *_*_IA32_ASM_FLAGS     = $(VP_BUILD_OPTIONS) /D EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h /DNOCS_S3_SUPPORT
+
+  *_*_IA32_CC_FLAGS      = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+  *_*_IA32_VFRPP_FLAGS   = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+  *_*_IA32_APP_FLAGS     = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+  *_*_IA32_PP_FLAGS      = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+  *_*_IA32_ASLPP_FLAGS   = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+
+  *_*_X64_CC_FLAGS       = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS) $(SOURCE_LEVEL_DEBUG_BUILD_OPTIONS)
+  *_*_X64_VFRPP_FLAGS    = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+  *_*_X64_APP_FLAGS      = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+  *_*_X64_PP_FLAGS       = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+  *_*_X64_ASLPP_FLAGS    = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
+
+
+[Components.X64]
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/I2cBus.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
+  }
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/I2cHost.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
+  }
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/I2cPortA0Pio.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x00000043
+  }
+
+  $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/I2cMmioDeviceDxe.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x00000043
+  }
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Boot.vfi b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Boot.vfi
new file mode 100644
index 0000000000..9c155e5328
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Boot.vfi
@@ -0,0 +1,72 @@
+//
+//
+// Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+//                                                                                  

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

+//
+//
+// Module Name:
+//
+//   Boot.vfi
+//
+// Abstract:
+//
+//   Driver Setup formset.
+//
+// Revision History:
+//
+// --*/
+
+
+form formid = BOOT_CONFIGURATION_FORM_ID,
+
+  title  = STRING_TOKEN(STR_BOOT_CONFIGURATION_TITLE);
+
+
+  oneof varid  = Setup.FastBoot,
+    prompt   = STRING_TOKEN(STR_FAST_BOOT_PROMPT),
+    help     = STRING_TOKEN(STR_FAST_BOOT_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags= DEFAULT | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE),  value=1, flags= MANUFACTURING | RESET_REQUIRED;
+  endoneof;
+
+  oneof varid  = Setup.SecureBoot,
+    prompt   = STRING_TOKEN(STR_SECURITY_BOOT_PROMPT),
+    help     = STRING_TOKEN(STR_SECURITY_BOOT_HELP),
+        option text = STRING_TOKEN(STR_DISABLE), value=0, flags= DEFAULT | MANUFACTURING | RESET_REQUIRED;
+        option text = STRING_TOKEN(STR_ENABLE),  value=1, flags= RESET_REQUIRED;
+  endoneof;
+
+
+  oneof varid  = Setup.QuietBoot,
+    prompt   = STRING_TOKEN(STR_QUIETBOOT_PROMPT),
+    help     = STRING_TOKEN(STR_QUIETBOOT_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE),  value=1, flags=0 | RESET_REQUIRED;
+  endoneof;
+
+
+
+  oneof   varid   = Setup.LogBootTime,
+      prompt      = STRING_TOKEN(STR_LOG_BOOT_TIME_PROMPT),
+      help        = STRING_TOKEN(STR_LOG_BOOT_TIME_HELP),
+      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = 0 | RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_ENABLE),  value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+  endoneof;
+
+  suppressif ideqval Setup.LogBootTime == 0x00;
+    text
+      help   = STRING_TOKEN(STR_NULL_STRING),
+      text   = STRING_TOKEN(STR_LOG_BOOT_TIME_RECORD),
+      text   = STRING_TOKEN(STR_LOG_BOOT_TIME_VALUE),
+      flags  = 0,
+      key    = 0;
+  endif;
+
+endform;
+
+
+
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Configuration.h b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Configuration.h
new file mode 100644
index 0000000000..7d7920c244
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Configuration.h
@@ -0,0 +1,56 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+    Configuration.h
+
+Abstract:
+
+    Driver configuration include file
+
+Revision History:
+  ------------------------------------------------------------------------------
+  Rev   Date<MM/DD/YYYY>    Name    Description
+  ------------------------------------------------------------------------------
+
+  ------------------------------------------------------------------------------
+--*/
+
+#ifndef _CONFIGURATION_H
+#define _CONFIGURATION_H
+
+//
+// System Setup Page. Do not have to be sequential but have to be unique
+//
+#define ROOT_FORM_ID                        1
+#define ROOT_MAIN_FORM_ID                   2
+#define CPU_CONFIGURATION_FORM_ID           3
+#define CPU_PWR_CONFIGURATION_FORM_ID       4
+#define BOOT_CONFIGURATION_FORM_ID          5
+#define IGD_FORM_ID                         6
+#define SECURITY_CONFIGURATION_FORM_ID      7
+#define SOUTH_CLUSTER_FORM_ID               8
+#define DPTF_FORM_ID                        9
+#define PLATFORM_INFORMATION_FORM_ID        10
+#define DRIVE_CONFIGURATION_ID              11
+#define SENSOR_CONFIGURATION_ID             12
+#define LPSS_CONFIGURATION_ID               13
+#define UNCORE_FORM_ID                      14
+#define TPM_FORM_ID                         15
+#define THERMAL_FORM_ID                     16
+#define PASSWORD_SETTING_ID                 17
+#define LAN_OPTIONS_FORM_ID                 18
+#define AZALIA_OPTIONS_FORM_ID              19
+#define MISC_OPTIONS_FORM_ID                20
+#define USB_OPTIONS_FORM_ID                 21
+#define PCIE_DEVICE_OPTIONS_FORM_ID         22
+#define SYSTEM_COMPONENT_FORM_ID            23
+#define DEBUG_CONFIGURATION_FORM_ID         24
+#endif // #ifndef _CONFIGURATION_H
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/DebugConfig.vfi b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/DebugConfig.vfi
new file mode 100644
index 0000000000..eea41a5202
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/DebugConfig.vfi
@@ -0,0 +1,118 @@
+//
+//
+// Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+//                                                                                  

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

+//
+//
+//
+// Module Name:
+//
+//   DebugConfiguration.vfi
+//
+// Abstract:
+//
+//   Debug Configuration formset.
+//
+
+
+// --*/
+
+form formid = DEBUG_CONFIGURATION_FORM_ID,
+  title    = STRING_TOKEN(STR_DEBUG_CONFIGURATION_TITLE);
+
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+  subtitle text = STRING_TOKEN(STR_ACPIMEMDBG_STRING);
+
+  //ACPI Memory Debug Switch
+    oneof varid   = Setup.ACPIMemDbg,
+      prompt      = STRING_TOKEN (STR_ACPIMEMDBG_SWTICH),
+      help        = STRING_TOKEN (STR_ACPIMEMDBG_SWTICH_HELP),
+      option text = STRING_TOKEN (STR_ENABLE),  value = 1, flags =  DEFAULT | MANUFACTURING | RESET_REQUIRED;
+      option text = STRING_TOKEN (STR_DISABLE), value = 0, flags =  RESET_REQUIRED;
+    endoneof;
+
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+
+    oneof varid   = Setup.ExISupport,
+      prompt      = STRING_TOKEN(STR_EXISUPPORT_PROMPT),
+      help        = STRING_TOKEN(STR_EXISUPPORT_HELP),
+      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT | RESET_REQUIRED;
+    endoneof;
+ subtitle text = STRING_TOKEN(STR_WITT_CONFIGURATION_TITLE);
+
+  oneof varid   = Setup.WittEnable,
+    prompt      = STRING_TOKEN(STR_WITT_PROMPT),
+    help        = STRING_TOKEN(STR_WITT_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE),  value = 1, flags = RESET_REQUIRED;
+  endoneof;
+
+  oneof varid   = Setup.UtsEnable,
+    prompt      = STRING_TOKEN(STR_UTS_PROMPT),
+    help        = STRING_TOKEN(STR_UTS_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE),  value = 1, flags = RESET_REQUIRED;
+  endoneof;
+
+  //
+  //Lakemore Settings
+  //
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+  subtitle text = STRING_TOKEN(STR_LM_INFORMATION_TITLE);
+
+    grayoutif ideqval Setup.PunitBIOSConfig == 0x1;
+      oneof varid   = Setup.LmMemSize,
+        prompt      = STRING_TOKEN (STR_LM_MEMORY_PROMPT),
+        help        = STRING_TOKEN (STR_LM_MEMORY_HELP),
+        option text = STRING_TOKEN (STR_LM_MEMORY_16MB),  value = 16384, flags = RESET_REQUIRED;
+        option text = STRING_TOKEN (STR_LM_MEMORY_8MB),   value = 8192,  flags = RESET_REQUIRED;
+        option text = STRING_TOKEN (STR_LM_MEMORY_1MB),   value = 1024,  flags = RESET_REQUIRED;
+        option text = STRING_TOKEN (STR_LM_MEMORY_128KB), value = 128,   flags = RESET_REQUIRED;
+        option text = STRING_TOKEN (STR_LM_MEMORY_0MB),   value = 0,     flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+      endoneof;
+    endif;
+
+    oneof varid   = Setup.PunitBIOSConfig,
+      prompt      = STRING_TOKEN (STR_PUINT_BIOS_CONFIG_DISPLAY),
+      help        = STRING_TOKEN (STR_PUINT_BIOS_CONFIG_DISPLAY_HELP),
+      option text = STRING_TOKEN (STR_PUINT_BIOS_PDM),         value = 3,  flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+      option text = STRING_TOKEN (STR_PUINT_BIOS_PERFORMANCE), value = 2,  flags = RESET_REQUIRED;
+      option text = STRING_TOKEN (STR_PUINT_BIOS_POWERSAVE),   value = 1,  flags = RESET_REQUIRED;
+	  option text = STRING_TOKEN (STR_PUINT_BIOS_RESERVED),    value = 0,  flags = RESET_REQUIRED;
+    endoneof;
+
+    suppressif NOT ideqval Setup.PunitBIOSConfig == 0x3;
+      oneof varid   = Setup.PDMConfig,
+        prompt      = STRING_TOKEN (STR_PDM_OUTPUT_CONFIG_SWTICH),
+        help        = STRING_TOKEN (STR_PDM_OUTPUT_CONFIG_SWTICH_HELP),
+        option text = STRING_TOKEN (STR_DISABLE), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+        option text = STRING_TOKEN (STR_PDM_OUTPUT_MEM), value = 1, flags = RESET_REQUIRED;
+        option text = STRING_TOKEN (STR_PDM_OUTPUT_IO),  value = 2, flags = RESET_REQUIRED;
+      endoneof;
+    endif;
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+  oneof varid   = Setup.ENDBG2,
+    prompt      = STRING_TOKEN (STR_ENABLE_DBG2),
+    help        = STRING_TOKEN (STR_ENABLE_DBG2_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE),  value = 1, flags = DEFAULT | RESET_REQUIRED;
+  endoneof;
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+  oneof varid = Setup.DisableCodec262,
+  prompt   = STRING_TOKEN(STR_CODEC262_DISABLED_PROMPT),
+  help     = STRING_TOKEN(STR_CODEC262_DISABLED_HELP),
+  option text = STRING_TOKEN(STR_YES), value = 1, flags = RESET_REQUIRED;
+  option text = STRING_TOKEN(STR_NO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+  endoneof;
+
+endform;
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/FwVersionStrings.uni b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/FwVersionStrings.uni
new file mode 100644
index 0000000000..175ceb1a16
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/FwVersionStrings.uni
@@ -0,0 +1,40 @@
+//
+// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+// Module Name:
+//
+//   InventoryStrings.uni
+// 
+// Abstract:
+// 
+//   String definitions for Inventory file.
+// 
+// Revision History:
+// 
+// --*/
+
+
+/=#
+
+#langdef en-US "English"
+#langdef fr-FR "Francais"
+
+#string STR_SOC_STRING                                  #language en-US "VLV SOC"
+#string STR_SOC_VALUE                                   #language en-US "N/A"
+#string STR_MRC_VERSION_STRING                          #language en-US "MRC Version"
+#string STR_MRC_VERSION_VALUE                           #language en-US "N/A"
+#string STR_PUNIT_FW_STRING                             #language en-US "PUNIT FW Patch"
+#string STR_PUNIT_FW_VALUE                              #language en-US "N/A"
+#string STR_ULPMC_FW_STRING                             #language en-US "ULPMC FW"
+#string STR_ULPMC_FW_VALUE                              #language en-US "N/A"
+#string STR_KSC_FW_STRING                               #language en-US "KSC FW"
+#string STR_KSC_FW_VALUE                                #language en-US "N/A"
+#string STR_SEC_FW_STRING                               #language en-US "TXE FW"
+#string STR_SEC_FW_VALUE                                #language en-US "N/A"
+#string STR_GOP_STRING                                  #language en-US "GOP"
+#string STR_GOP_VALUE                                   #language en-US "N/A"
+#string STR_PMC_FW_STRING                               #language en-US "PMC FW Patch"
+#string STR_PMC_FW_VALUE                                #language en-US "N/A"
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Main.vfi b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Main.vfi
new file mode 100644
index 0000000000..6093262e3f
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Main.vfi
@@ -0,0 +1,331 @@
+//
+//
+// Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+//                                                                                  

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

+//
+//
+//
+// Module Name:
+//
+//   Main.vfi
+//
+// Abstract:
+//
+//   Driver Setup formset.
+//
+// Revision History:
+//
+// --*/
+
+form formid = ROOT_MAIN_FORM_ID,
+
+  title    = STRING_TOKEN(STR_MAIN_TITLE);
+
+  subtitle text = STRING_TOKEN(STR_BIOS_INFORMATION_TITLE);
+
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_IFWI_VERSION_STRING),
+    text   = STRING_TOKEN(STR_IFWI_VERSION_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_BIOS_VERSION_STRING),
+    text   = STRING_TOKEN(STR_BIOS_VERSION_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_BIOS_VENDOR_STRING),
+    text   = STRING_TOKEN(STR_BIOS_VENDOR_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_CORE_VERSION_STRING),
+    text   = STRING_TOKEN(STR_CORE_VERSION_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_BIOS_BUILD_TIME_STRING),
+    text   = STRING_TOKEN(STR_BIOS_BUILD_TIME_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+
+  subtitle text = STRING_TOKEN(STR_PROCESSOR_INFO_STRING);
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_PROCESSOR_VERSION_STRING),
+    text   = STRING_TOKEN(STR_PROCESSOR_VERSION_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_PROCESSOR_SKU_STRING),
+    text   = STRING_TOKEN(STR_PROCESSOR_SKU_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_PROCESSOR_SPEED_STRING),
+    text   = STRING_TOKEN(STR_PROCESSOR_SPEED_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_PROCESSOR_ID_STRING),
+    text   = STRING_TOKEN(STR_PROCESSOR_ID_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_PROCESSOR_MICROCODE_STRING),
+    text   = STRING_TOKEN(STR_PROCESSOR_MICROCODE_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_PROCESSOR_CORE_STRING),
+    text   = STRING_TOKEN(STR_PROCESSOR_CORE_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_EM64T_CAPABILITY_STRING),
+    text   = STRING_TOKEN(STR_EM64T_CAPABILITY_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+
+  goto PLATFORM_INFORMATION_FORM_ID,
+    prompt = STRING_TOKEN(STR_PLATFORM_INFORMATION_TITLE),
+    help   = STRING_TOKEN(STR_PLATFORM_INFORMATION_HELP);
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+  //
+  // Date and Time section
+  //
+  date    year varid  = Date.Year,    // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from
+    prompt      = STRING_TOKEN(STR_DATE_PROMPT),
+    help        = STRING_TOKEN(STR_DATE_YEAR_HELP),
+    minimum     = 2003,
+    maximum     = 2100,
+    step        = 1,
+    default     = 2003,
+
+    month varid = Date.Month,    // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from
+    prompt      = STRING_TOKEN(STR_DATE_PROMPT),
+    help        = STRING_TOKEN(STR_DATE_MONTH_HELP),
+    minimum     = 1,
+    maximum     = 12,
+    step        = 1,
+    default     = 1,
+
+    day varid   = Date.Day,          // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from
+    prompt      = STRING_TOKEN(STR_DATE_PROMPT),
+    help        = STRING_TOKEN(STR_DATE_DAY_HELP),
+    minimum     = 1,
+    maximum     = 31,
+    step        = 0x1,
+    default     = 1,
+
+    // If the day is 31 AND months is any of the following 2, 4, 6, 9, 11
+    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),
+      ideqval Date.Day == 31
+      AND
+      ideqvallist Date.Month == 2 4 6 9 11
+    endif
+
+    // If the day is 30 AND month is 2
+    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),
+      ideqval Date.Day == 30
+      AND
+      ideqval Date.Month == 2
+    endif
+
+    // If the day is 29 AND month is 2 AND it year is NOT a leapyear
+    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),
+      ideqval Date.Day == 0x29
+      AND
+      ideqval Date.Month == 2
+      AND
+      NOT
+      ideqvallist Date.Year == 2004 2008 2012 2016 2020 2024 2028 2032 2036 2040 2044 2048 2052 2056 2060 2064 2068 2072 2076 2080 2084 2088 2092 2096
+    endif
+
+  enddate;
+
+  time    hour varid  = Time.Hours,         // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from
+    prompt      = STRING_TOKEN(STR_TIME_PROMPT),
+    help        = STRING_TOKEN(STR_TIME_HOUR_HELP),
+    minimum     = 0,
+    maximum     = 23,
+    step        = 1,
+    default     = 0,
+
+    minute varid  = Time.Minutes,       // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from
+    prompt        = STRING_TOKEN(STR_TIME_PROMPT),
+    help          = STRING_TOKEN(STR_TIME_MINUTE_HELP),
+    minimum       = 0,
+    maximum       = 59,
+    step          = 1,
+    default       = 0,
+
+    second varid  = Time.Seconds,       // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from
+    prompt        = STRING_TOKEN(STR_TIME_PROMPT),
+    help          = STRING_TOKEN(STR_TIME_SECOND_HELP),
+    minimum       = 0,
+    maximum       = 59,
+    step          = 1,
+    default       = 0,
+  endtime;
+
+endform;
+
+form formid = PLATFORM_INFORMATION_FORM_ID,
+
+  title    = STRING_TOKEN(STR_PLATFORM_INFORMATION_TITLE);
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+
+  subtitle text = STRING_TOKEN(STR_PLATFORM_FIRMWARE_STRING);
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_SOC_STRING),
+    text   = STRING_TOKEN(STR_SOC_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_MRC_VERSION_STRING),
+    text   = STRING_TOKEN(STR_MRC_VERSION_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_PUNIT_FW_STRING),
+    text   = STRING_TOKEN(STR_PUNIT_FW_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_PMC_FW_STRING),
+    text   = STRING_TOKEN(STR_PMC_FW_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_KSC_FW_STRING),
+    text   = STRING_TOKEN(STR_KSC_FW_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_SEC_VERSION_STRING),
+    text   = STRING_TOKEN(STR_SEC_VERSION_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  suppressif ideqval Setup.GOPEnable == 0;
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_GOP_STRING),
+    text   = STRING_TOKEN(STR_GOP_VALUE),
+    flags  = 0,
+    key    = 0;
+  endif;
+
+  suppressif ideqval Setup.GOPEnable == 1;
+  text
+    help   = STRING_TOKEN(STR_CHIP_IGD_VBIOS_REV_HELP),
+    text   = STRING_TOKEN(STR_CHIP_IGD_VBIOS_REV_NAME),
+    text   = STRING_TOKEN(STR_CHIP_IGD_VBIOS_REV_VALUE),
+    flags  = 0,
+    key    = 0;
+  endif;
+
+  text
+    help   = STRING_TOKEN(STR_CPU_FLAVOR_HELP),
+    text   = STRING_TOKEN(STR_CPU_FLAVOR_NAME),
+    text   = STRING_TOKEN(STR_CPU_FLAVOR_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  text
+    help   = STRING_TOKEN(STR_BOARD_ID_HELP),
+    text   = STRING_TOKEN(STR_BOARD_ID_NAME),
+    text   = STRING_TOKEN(STR_BOARD_ID_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  text
+    help   = STRING_TOKEN(STR_FAB_ID_HELP),
+    text   = STRING_TOKEN(STR_FAB_ID_STRING),
+    text   = STRING_TOKEN(STR_FAB_ID_VALUE),
+    flags  = 0,
+    key = 0;
+
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+
+  subtitle text = STRING_TOKEN(STR_MEMORY_INFORMATION_STRING);
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_TOTAL_MEMORY_SIZE_PROMPT),
+    text   = STRING_TOKEN(STR_TOTAL_MEMORY_SIZE_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_SYSTEM_MEMORY_SPEED_STRING),
+    text   = STRING_TOKEN(STR_SYSTEM_MEMORY_SPEED_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_PROCESSOR_L1_DATA_CACHE_STRING),
+    text   = STRING_TOKEN(STR_PROCESSOR_L1_DATA_CACHE_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_PROCESSOR_L1_INSTR_CACHE_STRING),
+    text   = STRING_TOKEN(STR_PROCESSOR_L1_INSTR_CACHE_VALUE),
+    flags  = 0,
+    key    = 0;
+
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_PROCESSOR_L2_CACHE_STRING),
+    text   = STRING_TOKEN(STR_PROCESSOR_L2_CACHE_VALUE),
+    flags  = 0,
+    key    = 0;
+
+endform;
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.c
new file mode 100644
index 0000000000..0bfa3e7cf4
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.c
@@ -0,0 +1,929 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+**/
+
+#include "PlatformSetupDxe.h"
+#include "Guid/SetupVariable.h"
+#include <Protocol/FormBrowserEx2.h>
+
+
+#define EFI_CALLBACK_INFO_SIGNATURE SIGNATURE_32 ('C', 'l', 'b', 'k')
+#define EFI_CALLBACK_INFO_FROM_THIS(a)  CR (a, EFI_CALLBACK_INFO, ConfigAccess, EFI_CALLBACK_INFO_SIGNATURE)
+
+typedef struct {
+  UINTN                           Signature;
+  EFI_HANDLE                      DriverHandle;
+  EFI_HII_HANDLE                  RegisteredHandle;
+  SYSTEM_CONFIGURATION            FakeNvData;
+  SYSTEM_CONFIGURATION            BackupNvData;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+  EFI_HII_CONFIG_ACCESS_PROTOCOL  ConfigAccess;
+} EFI_CALLBACK_INFO;
+
+#pragma pack(1)
+
+//
+// HII specific Vendor Device Path definition.
+//
+typedef struct {
+  VENDOR_DEVICE_PATH             VendorDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL       End;
+} HII_VENDOR_DEVICE_PATH;
+
+#pragma pack()
+
+//
+// uni string and Vfr Binary data.
+//
+extern UINT8  VfrBin[];
+extern UINT8  PlatformSetupDxeStrings[];
+
+EFI_HANDLE            mImageHandle;
+
+//
+// module global data
+//
+#define EFI_NORMAL_SETUP_GUID \
+  { 0xec87d643, 0xeba4, 0x4bb5, 0xa1, 0xe5, 0x3f, 0x3e, 0x36, 0xb2, 0xd, 0xa9 }
+
+EFI_GUID                     mNormalSetupGuid = EFI_NORMAL_SETUP_GUID;
+
+EFI_GUID                     mSystemConfigGuid = SYSTEM_CONFIGURATION_GUID;
+CHAR16                       mVariableName[] = L"Setup";
+CHAR16                       mSetupName[] = L"Setup";
+EFI_CALLBACK_INFO           *mCallbackInfo;
+BOOLEAN                      GlobalReset=FALSE;
+
+HII_VENDOR_DEVICE_PATH  mHiiVendorDevicePath = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      {
+        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+      }
+    },
+    EFI_CALLER_ID_GUID
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      (UINT8) (END_DEVICE_PATH_LENGTH),
+      (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
+    }
+  }
+};
+
+/**
+  This function allows a caller to extract the current configuration for one
+  or more named elements from the target driver.
+
+  @param  This         Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param  Request      A null-terminated Unicode string in <ConfigRequest> format.
+  @param  Progress     On return, points to a character in the Request string.
+                       Points to the string's null terminator if request was successful.
+                       Points to the most recent '&' before the first failing name/value
+                       pair (or the beginning of the string if the failure is in the
+                       first name/value pair) if the request was not successful.
+  @param  Results      A null-terminated Unicode string in <ConfigAltResp> format which
+                       has all values filled in for the names in the Request string.
+                       String to be allocated by the called function.
+
+  @retval EFI_SUCCESS            The Results is filled with the requested values.
+  @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
+  @retval EFI_INVALID_PARAMETER  Request is NULL, illegal syntax, or unknown name.
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.
+
+**/
+
+VOID
+CheckSystemConfigLoad(SYSTEM_CONFIGURATION *SystemConfigPtr);
+
+VOID
+CheckSystemConfigSave(SYSTEM_CONFIGURATION *SystemConfigPtr);
+
+VOID
+ConfirmSecureBootTest();
+
+VOID
+LoadLpssDefaultValues (
+  IN EFI_CALLBACK_INFO                       *Private
+  )
+{
+  //
+  // Load LPSS and SCC default configurations for Android
+  //
+  Private->FakeNvData.LpsseMMCEnabled            = FALSE;
+  Private->FakeNvData.LpssSdioEnabled            = TRUE;
+  Private->FakeNvData.LpssSdcardEnabled          = TRUE;
+  Private->FakeNvData.LpssSdCardSDR25Enabled     = FALSE;
+  Private->FakeNvData.LpssSdCardDDR50Enabled     = TRUE;
+  Private->FakeNvData.LpssMipiHsi                = FALSE;
+  Private->FakeNvData.LpsseMMC45Enabled          = TRUE;
+  Private->FakeNvData.LpsseMMC45DDR50Enabled     = TRUE;
+  Private->FakeNvData.LpsseMMC45HS200Enabled     = FALSE;
+  Private->FakeNvData.LpsseMMC45RetuneTimerValue = 8;
+  Private->FakeNvData.eMMCBootMode               = 1;     // Auto Detect
+
+  Private->FakeNvData.GOPEnable = TRUE;
+  Private->FakeNvData.SecureBoot = TRUE;
+  Private->FakeNvData.UsbAutoMode = TRUE;
+  Private->FakeNvData.UsbXhciSupport = TRUE;
+  Private->FakeNvData.PchUsb30Mode = TRUE;
+  Private->FakeNvData.LegacyUSBBooting = FALSE;
+  Private->FakeNvData.PchUsb20 = FALSE;
+}
+
+
+EFI_STATUS
+EFIAPI
+SystemConfigExtractConfig (
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
+  IN  CONST EFI_STRING                       Request,
+  OUT EFI_STRING                             *Progress,
+  OUT EFI_STRING                             *Results
+  )
+{
+  EFI_STATUS                       Status;
+  EFI_CALLBACK_INFO                *Private;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL  *HiiConfigRouting;
+  EFI_STRING                       ConfigRequestHdr;
+  EFI_STRING                       ConfigRequest;
+  BOOLEAN                          AllocatedRequest;
+  UINTN                            Size;
+  UINTN                            BufferSize;
+  VOID                             *SystemConfigPtr;
+
+
+  if (Progress == NULL || Results == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *Progress = Request;
+  if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &mSystemConfigGuid, mVariableName)) {
+    return EFI_NOT_FOUND;
+  }
+
+  ConfigRequestHdr = NULL;
+  ConfigRequest    = NULL;
+  Size             = 0;
+  AllocatedRequest = FALSE;
+
+  Private          = EFI_CALLBACK_INFO_FROM_THIS (This);
+
+  SetupInfo();
+
+  HiiConfigRouting = Private->HiiConfigRouting;
+  ConfigRequest = Request;
+  if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
+    //
+    // Request has no request element, construct full request string.
+    // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
+    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
+    //
+    ConfigRequestHdr = HiiConstructConfigHdr (&mSystemConfigGuid, mVariableName, Private->DriverHandle);
+    Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
+    ConfigRequest = AllocateZeroPool (Size);
+    ASSERT (ConfigRequest != NULL);
+    AllocatedRequest = TRUE;
+    BufferSize = sizeof (SYSTEM_CONFIGURATION);
+    UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
+    FreePool (ConfigRequestHdr);
+  }
+  SystemConfigPtr = GetVariable(mSetupName, &mNormalSetupGuid);
+
+
+  if (SystemConfigPtr == NULL) {
+    ZeroMem(&Private->FakeNvData, sizeof(SYSTEM_CONFIGURATION));
+    ZeroMem(&Private->BackupNvData, sizeof(SYSTEM_CONFIGURATION));
+  } else {
+    CheckSystemConfigLoad(SystemConfigPtr);
+    CopyMem(&Private->FakeNvData, SystemConfigPtr, sizeof(SYSTEM_CONFIGURATION));
+    CopyMem(&Private->BackupNvData, SystemConfigPtr, sizeof(SYSTEM_CONFIGURATION));
+    FreePool(SystemConfigPtr);
+  }
+
+  //
+  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
+  //
+  Status = HiiConfigRouting->BlockToConfig (
+                               HiiConfigRouting,
+                               ConfigRequest,
+                               (UINT8 *) &Private->FakeNvData,
+                               sizeof (SYSTEM_CONFIGURATION),
+                               Results,
+                               Progress
+                               );
+
+  //
+  // Free the allocated config request string.
+  //
+  if (AllocatedRequest) {
+    FreePool (ConfigRequest);
+    ConfigRequest = NULL;
+  }
+
+  //
+  // Set Progress string to the original request string.
+  //
+  if (Request == NULL) {
+    *Progress = NULL;
+  } else if (StrStr (Request, L"OFFSET") == NULL) {
+    *Progress = Request + StrLen (Request);
+  }
+
+  return Status;
+}
+
+/**
+  This function processes the results of changes in configuration.
+
+  @param  This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param  Configuration   A null-terminated Unicode string in <ConfigRequest> format.
+  @param  Progress        A pointer to a string filled in with the offset of the most
+                          recent '&' before the first failing name/value pair (or the
+                          beginning of the string if the failure is in the first
+                          name/value pair) or the terminating NULL if all was successful.
+
+  @retval EFI_SUCCESS            The Results is processed successfully.
+  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.
+
+**/
+EFI_STATUS
+EFIAPI
+SystemConfigRouteConfig (
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
+  IN  CONST EFI_STRING                       Configuration,
+  OUT EFI_STRING                             *Progress
+  )
+{
+  EFI_CALLBACK_INFO                         *Private;
+  SYSTEM_CONFIGURATION                       *FakeNvData;
+
+  if (Configuration == NULL || Progress == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  *Progress = Configuration;
+
+  if (!HiiIsConfigHdrMatch (Configuration, &mSystemConfigGuid, mVariableName)) {
+    return EFI_NOT_FOUND;
+  }
+
+  *Progress = Configuration + StrLen (Configuration);
+  Private    = EFI_CALLBACK_INFO_FROM_THIS (This);
+  FakeNvData = &Private->FakeNvData;
+  if (!HiiGetBrowserData (&mSystemConfigGuid, mVariableName, sizeof (SYSTEM_CONFIGURATION), (UINT8 *) FakeNvData)) {
+    //
+    // FakeNvData can't be got from SetupBrowser, which doesn't need to be set.
+    //
+    return EFI_SUCCESS;
+  }
+
+  if (Private->FakeNvData.ReservedO != Private->BackupNvData.ReservedO) {
+    Private->BackupNvData.ReservedO = Private->FakeNvData.ReservedO;
+    LoadLpssDefaultValues (Private);
+
+    //
+    // Pass changed uncommitted data back to Form Browser
+    //
+    HiiSetBrowserData (&mSystemConfigGuid, mVariableName, sizeof (SYSTEM_CONFIGURATION), (UINT8 *) FakeNvData, NULL);
+  }
+
+  gRT->SetVariable(
+         mSetupName,
+         &mNormalSetupGuid,
+         EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+         sizeof(SYSTEM_CONFIGURATION),
+         &Private->FakeNvData
+         );
+
+  CheckSystemConfigSave(&Private->FakeNvData);
+  return EFI_SUCCESS;
+}
+
+/**
+  This is the function that is called to provide results data to the driver.  This data
+  consists of a unique key which is used to identify what data is either being passed back
+  or being asked for.
+
+  @param  This           Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param  Action         A null-terminated Unicode string in <ConfigRequest> format.
+  @param  KeyValue       A unique Goto OpCode callback value which record user's selection.
+                         0x100 <= KeyValue <0x500 : user select a controller item in the first page;
+                         KeyValue == 0x1234       : user select 'Refresh' in first page, or user select 'Go to Previous Menu' in second page
+                         KeyValue == 0x1235       : user select 'Pci device filter' in first page
+                         KeyValue == 0x1500       : user select 'order ... priority' item in second page
+                         KeyValue == 0x1800       : user select 'commint changes' in third page
+                         KeyValue == 0x2000       : user select 'Go to Previous Menu' in third page
+  @param  Type           The type of value for the question.
+  @param  Value          A pointer to the data being sent to the original exporting driver.
+  @param  ActionRequest  On return, points to the action requested by the callback function.
+
+  @retval EFI_SUCCESS    Always returned.
+
+**/
+EFI_STATUS
+EFIAPI
+SystemConfigCallback (
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
+  IN  EFI_BROWSER_ACTION                     Action,
+  IN  EFI_QUESTION_ID                        KeyValue,
+  IN  UINT8                                  Type,
+  IN  EFI_IFR_TYPE_VALUE                     *Value,
+  OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest
+  )
+{
+  EFI_CALLBACK_INFO             *Private;
+  SYSTEM_CONFIGURATION          *FakeNvData;
+  SYSTEM_CONFIGURATION          *SetupData;
+  UINTN                         SizeOfNvStore;
+  EFI_INPUT_KEY                 Key;
+  CHAR16                        *StringBuffer1;
+  CHAR16                        *StringBuffer2;
+  CHAR16                        *StringBuffer3;
+  EFI_STATUS                    Status;
+  UINTN                         DataSize;
+  UINT8                         OsSelection;
+  EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL *FormBrowserEx2;
+
+  StringBuffer1 = AllocateZeroPool (200 * sizeof (CHAR16));
+  ASSERT (StringBuffer1 != NULL);
+  StringBuffer2 = AllocateZeroPool (200 * sizeof (CHAR16));
+  ASSERT (StringBuffer2 != NULL);
+  StringBuffer3 = AllocateZeroPool (200 * sizeof (CHAR16));
+  ASSERT (StringBuffer3 != NULL);
+
+  switch (Action) {
+  case EFI_BROWSER_ACTION_CHANGING:
+  {
+    if (KeyValue == 0x1235) {
+      StrCpy (StringBuffer1, L"Will you disable PTT ? ");
+      StrCpy (StringBuffer2, L"Enter (YES)  /   Esc (NO)");
+
+      //
+      // Popup a menu to notice user
+      //
+      do {
+        CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL);
+      } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
+
+      //
+      // If the user hits the YES Response key,
+      //
+      if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
+
+      }
+    } else if (KeyValue == 0x1236) {
+      StrCpy (StringBuffer1, L"Will you revoke trust ? ");
+      StrCpy (StringBuffer2, L"Enter (YES)  /   Esc (NO)");
+
+      //
+      // Popup a menu to notice user
+      //
+      do {
+        CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL);
+      } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
+
+      //
+      // If the user hits the YES Response key,
+      //
+      if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
+
+      }
+	 } else if (KeyValue == 0x1239) {
+	   if (Value->u8 == 0x00) {
+       StrCpy (StringBuffer1, L"WARNING: SOC may be damaged due to high temperature");
+       StrCpy (StringBuffer2, L"when DPTF is disabled and IGD turbo is enabled.");
+       StrCpy (StringBuffer3, L"Press Enter/ESC to continue...");
+
+        //
+        // Popup a menu to notice user
+        //
+        do {
+          CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, StringBuffer3, NULL);
+        } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
+    }
+    } else if (KeyValue == 0x1240) { // secure erase feature of eMMC
+	    //
+      // Popup a menu to notice user
+      //
+      StrCpy (StringBuffer1, L"WARNING: All your data on the eMMC will be lost");
+      StrCpy (StringBuffer2, L"Do you really want to enable secure erase on eMMC?");
+      StrCpy (StringBuffer3, L"       Enter (YES)    /    Esc (NO)        ");
+
+      do {
+        CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, StringBuffer3,NULL);
+      } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
+
+      //
+      // If the user hits the ESC Response key,
+      //
+      if (Key.ScanCode == SCAN_ESC) {
+        Private = EFI_CALLBACK_INFO_FROM_THIS (This);
+        FakeNvData = &Private->FakeNvData;
+
+        Status = HiiGetBrowserData (
+		               &mSystemConfigGuid,
+				           mVariableName,
+				           sizeof (SYSTEM_CONFIGURATION),
+				           (UINT8 *) FakeNvData
+				           );
+        if (!EFI_ERROR (Status)) {
+             FakeNvData->SecureErase = 0;
+             HiiSetBrowserData (
+               &mSystemConfigGuid,
+               mVariableName,
+               sizeof (SYSTEM_CONFIGURATION),
+               (UINT8 *) FakeNvData,
+               NULL
+               );
+        }
+        break;
+      }
+
+      //
+      // If the user hits the YES Response key
+      //
+      if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
+        //
+        // Save change
+        //
+        Private = EFI_CALLBACK_INFO_FROM_THIS (This);
+        FakeNvData = &Private->FakeNvData;
+
+        Status = HiiGetBrowserData (
+		               &mSystemConfigGuid,
+				           mVariableName,
+				           sizeof (SYSTEM_CONFIGURATION),
+				          (UINT8 *) FakeNvData
+				          );
+        if (!EFI_ERROR (Status)) {
+          Status = gRT->SetVariable (
+                          L"Setup",
+                          &mNormalSetupGuid,
+                          EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                          sizeof(SYSTEM_CONFIGURATION),
+                          &Private->FakeNvData
+                          );
+        }
+
+        //
+        // Reset system
+        //
+        gRT->ResetSystem(
+		           EfiResetCold,
+			         EFI_SUCCESS,
+			         0,
+			         NULL
+			         );
+
+    }
+
+
+    }
+    else if (KeyValue == 0xF001) {
+      //
+      // Popup a menu to notice user
+      //
+      StrCpy (StringBuffer1, L"Do you want to Commit Changes and Exit?");
+      StrCpy (StringBuffer2, L"         Enter (YES) / Esc (NO)        ");
+
+      do {
+        CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL);
+      } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
+
+      //
+      // If the user hits the YES Response key
+      //
+      if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
+        //
+        // Save change
+        //
+        Private = EFI_CALLBACK_INFO_FROM_THIS (This);
+        FakeNvData = &Private->FakeNvData;
+
+        Status = HiiGetBrowserData (
+		           &mSystemConfigGuid,
+				   mVariableName,
+				   sizeof (SYSTEM_CONFIGURATION),
+				   (UINT8 *) FakeNvData
+				   );
+        if (!EFI_ERROR (Status)) {
+          Status = gRT->SetVariable (
+                          L"Setup",
+                          &mNormalSetupGuid,
+                          EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                          sizeof(SYSTEM_CONFIGURATION),
+                          &Private->FakeNvData
+                          );
+        }
+
+		//
+		// Update Secure Boot configuration changes
+		//
+        CheckSystemConfigSave(FakeNvData);
+
+        //
+        // Reset system
+        //
+        if (GlobalReset == TRUE) {
+          //
+          // Issue full reset
+          //
+          IoWrite8 (
+            (UINTN) 0XCF9,
+            (UINT8) 0x02
+            );
+
+          IoWrite8 (
+            (UINTN) 0xCF9,
+            (UINT8) 0x0E
+            );
+        } else {
+        	gRT->ResetSystem(
+			       EfiResetCold,
+				   EFI_SUCCESS,
+				   0,
+				   NULL
+				   );
+        }
+      }
+    } else if (KeyValue == 0xF002) {
+      //
+      // Popup a menu to notice user
+      //
+      StrCpy (StringBuffer1, L"Do you want to Discard Changes and Exit?");
+      StrCpy (StringBuffer2, L"         Enter (YES) / Esc (NO)         ");
+
+      do {
+        CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL);
+      } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
+
+      //
+      // If the user hits the YES Response key
+      //
+      if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
+        //
+        // Reset system
+        //
+        gRT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
+      }
+    } else if (KeyValue == 0xF003) {
+      //
+      // Popup a menu to notice user
+      //
+      StrCpy (StringBuffer1, L"Do you want to load setup defaults and Exit?");
+      StrCpy (StringBuffer2, L"         Enter (YES) / Esc (NO)             ");
+
+      do {
+        CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL);
+      } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
+
+      //
+      // If the user hits the YES Response key
+      //
+      if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
+
+        Status = gBS->LocateProtocol (&gEdkiiFormBrowserEx2ProtocolGuid, NULL, (VOID **) &FormBrowserEx2);
+        FormBrowserEx2->ExecuteAction(BROWSER_ACTION_DEFAULT, EFI_HII_DEFAULT_CLASS_STANDARD);
+
+        FakeNvData = AllocateZeroPool (sizeof(SYSTEM_CONFIGURATION));
+
+        if (FakeNvData == NULL) {
+          return EFI_OUT_OF_RESOURCES;
+        }
+        
+        Status = HiiGetBrowserData (
+		           &mSystemConfigGuid,
+				   mVariableName,
+				   sizeof (SYSTEM_CONFIGURATION),
+				   (UINT8 *) FakeNvData
+				   );
+        
+        if (!EFI_ERROR (Status)) {
+          Status = gRT->SetVariable (
+                          L"Setup",
+                          &mNormalSetupGuid,
+                            EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                          sizeof(SYSTEM_CONFIGURATION),
+                          FakeNvData
+                          );
+        }
+
+        FreePool (FakeNvData);
+
+        DataSize = sizeof(OsSelection);
+        Status = gRT->GetVariable(
+                        L"OsSelection",
+                        &gOsSelectionVariableGuid,
+                        NULL,
+                        &DataSize,
+                        &OsSelection
+                        );
+
+        if (EFI_ERROR(Status) || (OsSelection != FakeNvData->ReservedO)) {
+          OsSelection = FakeNvData->ReservedO;
+          Status = gRT->SetVariable (
+                          L"OsSelection",
+                          &gOsSelectionVariableGuid,
+                          EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                          sizeof(OsSelection),
+                          &OsSelection
+                          );
+        }
+
+        //
+        // Reset system
+        //
+        gRT->ResetSystem(
+		       EfiResetCold,
+			   EFI_SUCCESS,
+			   0,
+			   NULL
+			   );
+      }
+    } else if ((KeyValue == 0x123A) || (KeyValue == 0x123B) || (KeyValue == 0x123C)) {
+        StrCpy (StringBuffer1, L"WARNING: Enable or disable USB Controllers will ");
+        StrCpy (StringBuffer2, L"make global reset to restart system.");
+        StrCpy (StringBuffer3, L"Press Enter/ESC to continue...");
+        //
+        // Popup a menu to notice user
+        //
+        do {
+          CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, StringBuffer3, NULL);
+        } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
+
+        FakeNvData = AllocateZeroPool (sizeof(SYSTEM_CONFIGURATION));
+        Status = HiiGetBrowserData (
+		           &mSystemConfigGuid,
+				   mVariableName,
+				   sizeof (SYSTEM_CONFIGURATION),
+				   (UINT8 *) FakeNvData
+				   );
+        //
+        // Get variable data
+        //
+        SizeOfNvStore = sizeof(SYSTEM_CONFIGURATION);
+        SetupData = AllocateZeroPool (sizeof(SYSTEM_CONFIGURATION));
+        Status = gRT->GetVariable(
+                        L"Setup",
+                        &mNormalSetupGuid,
+                        NULL,
+                        &SizeOfNvStore,
+                        SetupData
+                        );
+        if ((SetupData->UsbAutoMode != FakeNvData->UsbAutoMode) ||
+        	   (SetupData->UsbXhciSupport != FakeNvData->UsbXhciSupport) ||
+        	   (SetupData->PchUsb20 != FakeNvData->PchUsb20)) {
+          GlobalReset = TRUE;
+        } else {
+          GlobalReset = FALSE;
+        }
+
+    }
+  }
+  break;
+
+  default:
+    break;
+  }
+
+  FreePool (StringBuffer1);
+  FreePool (StringBuffer2);
+  FreePool (StringBuffer3);
+
+  //
+  // Workaround for Load Default for "DPTF Enable"
+  //
+  if (Action == EFI_BROWSER_ACTION_DEFAULT_STANDARD) {
+    if (KeyValue == 0x1239) {
+      return EFI_NOT_FOUND;
+    }
+  }
+
+  if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) {
+    //
+    // Do nothing for UEFI OPEN/CLOSE Action
+    //
+    return EFI_SUCCESS;
+  }
+
+  Private = EFI_CALLBACK_INFO_FROM_THIS (This);
+  FakeNvData = &Private->FakeNvData;
+  if (!HiiGetBrowserData (&mSystemConfigGuid, mVariableName, sizeof (SYSTEM_CONFIGURATION), (UINT8 *) FakeNvData)) {
+    return EFI_NOT_FOUND;
+  }
+
+  if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) && (Private->FakeNvData.ReservedO != Private->BackupNvData.ReservedO)) {
+    Private->BackupNvData.ReservedO = Private->FakeNvData.ReservedO;
+    LoadLpssDefaultValues (Private);
+  }
+
+  //
+  // When user selected the secure erase, set it to disable
+  //
+  if((KeyValue == 0x1240) && (Action == EFI_BROWSER_ACTION_CHANGED)) {
+    FakeNvData->SecureErase = 0;
+  }
+
+  if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_CHANGED)) {
+    //
+    // If function 0 is disabled, function 1 ~ 7 also required to be disabled.
+    //
+    if (Private->FakeNvData.LpssDma0Enabled == 0) {
+      Private->FakeNvData.LpssHsuart0Enabled = 0;
+      Private->FakeNvData.LpssHsuart1Enabled = 0;
+      Private->FakeNvData.LpssPwm0Enabled    = 0;
+      Private->FakeNvData.LpssPwm1Enabled    = 0;
+      Private->FakeNvData.LpssSpiEnabled     = 0;
+    }
+
+
+    //
+    // If function 0 is disabled, function 1 ~ 7 also required to be disabled.
+    //
+    if (Private->FakeNvData.LpssDma1Enabled == 0) {
+      Private->FakeNvData.LpssI2C0Enabled = 0;
+      Private->FakeNvData.LpssI2C1Enabled = 0;
+      Private->FakeNvData.LpssI2C2Enabled = 0;
+      Private->FakeNvData.LpssI2C3Enabled = 0;
+      Private->FakeNvData.LpssI2C4Enabled = 0;
+      Private->FakeNvData.LpssI2C5Enabled = 0;
+      Private->FakeNvData.LpssI2C6Enabled = 0;
+    }
+  }
+
+
+  //
+  // Pass changed uncommitted data back to Form Browser
+  //
+  HiiSetBrowserData (&mSystemConfigGuid, mVariableName, sizeof (SYSTEM_CONFIGURATION), (UINT8 *) FakeNvData, NULL);
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  The driver Entry Point. The function will export a disk device class formset and
+  its callback function to hii database.
+
+  @param  ImageHandle    The firmware allocated handle for the EFI image.
+  @param  SystemTable    A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS    The entry point is executed successfully.
+  @retval other          Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformSetupDxeInit (
+  IN EFI_HANDLE                   ImageHandle,
+  IN EFI_SYSTEM_TABLE             *SystemTable
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_FORM_BROWSER2_PROTOCOL  *FormBrowser2;
+
+  mImageHandle = ImageHandle;
+
+  //
+  // There should only be one Form Configuration protocol
+  //
+  Status = gBS->LocateProtocol (
+                 &gEfiFormBrowser2ProtocolGuid,
+                 NULL,
+                 (VOID **) &FormBrowser2
+                 );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  mCallbackInfo = AllocateZeroPool (sizeof (EFI_CALLBACK_INFO));
+  if (mCallbackInfo == NULL) {
+    return EFI_BAD_BUFFER_SIZE;
+  }
+
+  mCallbackInfo->Signature = EFI_CALLBACK_INFO_SIGNATURE;
+  mCallbackInfo->ConfigAccess.ExtractConfig = SystemConfigExtractConfig;
+  mCallbackInfo->ConfigAccess.RouteConfig   = SystemConfigRouteConfig;
+  mCallbackInfo->ConfigAccess.Callback      = SystemConfigCallback;
+
+  //
+  // Install Device Path Protocol and Config Access protocol to driver handle
+  // Install Platform Driver Override Protocol to driver handle
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mCallbackInfo->DriverHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  &mHiiVendorDevicePath,
+                  &gEfiHiiConfigAccessProtocolGuid,
+                  &mCallbackInfo->ConfigAccess,
+                  NULL
+                  );
+  if (EFI_ERROR (Status)) {
+    goto Finish;
+  }
+
+  //
+  // Publish our HII data
+  //
+  mCallbackInfo->RegisteredHandle = HiiAddPackages (
+                                      &mSystemConfigGuid,
+                                      mCallbackInfo->DriverHandle,
+                                      VfrBin,
+                                      PlatformSetupDxeStrings,
+                                      NULL
+                                      );
+  if (mCallbackInfo->RegisteredHandle == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Finish;
+  }
+
+  mHiiHandle = mCallbackInfo->RegisteredHandle;
+
+  //
+  // Locate ConfigRouting protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiHiiConfigRoutingProtocolGuid,
+                  NULL,
+                  (VOID **) &mCallbackInfo->HiiConfigRouting
+                  );
+  if (EFI_ERROR (Status)) {
+    goto Finish;
+  }
+
+  //
+  // Clear all the globle variable
+  //
+  return EFI_SUCCESS;
+
+Finish:
+  if (mCallbackInfo->DriverHandle != NULL) {
+    gBS->UninstallMultipleProtocolInterfaces (
+           mCallbackInfo->DriverHandle,
+           &gEfiDevicePathProtocolGuid,
+           &mHiiVendorDevicePath,
+           &gEfiHiiConfigAccessProtocolGuid,
+           &mCallbackInfo->ConfigAccess,
+           NULL
+           );
+  }
+
+  if (mCallbackInfo->RegisteredHandle != NULL) {
+    HiiRemovePackages (mCallbackInfo->RegisteredHandle);
+  }
+
+  if (mCallbackInfo != NULL) {
+    FreePool (mCallbackInfo);
+  }
+
+  return Status;
+}
+
+/**
+  Unload its installed protocol.
+
+  @param[in]  ImageHandle       Handle that identifies the image to be unloaded.
+
+  @retval EFI_SUCCESS           The image has been unloaded.
+**/
+EFI_STATUS
+EFIAPI
+PlatformSetupDxeUnload (
+  IN EFI_HANDLE  ImageHandle
+  )
+{
+  if (mCallbackInfo != NULL) {
+    if (mCallbackInfo->DriverHandle != NULL) {
+      gBS->UninstallMultipleProtocolInterfaces (
+             mCallbackInfo->DriverHandle,
+             &gEfiDevicePathProtocolGuid,
+             &mHiiVendorDevicePath,
+             &gEfiHiiConfigAccessProtocolGuid,
+             &mCallbackInfo->ConfigAccess,
+             NULL
+             );
+    }
+
+    if (mCallbackInfo->RegisteredHandle != NULL) {
+      HiiRemovePackages (mCallbackInfo->RegisteredHandle);
+    }
+
+    FreePool (mCallbackInfo);
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.h b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.h
new file mode 100644
index 0000000000..53372bb922
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.h
@@ -0,0 +1,97 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+**/
+
+#ifndef _PLAT_OVER_MNGR_H_
+#define _PLAT_OVER_MNGR_H_
+
+#include <FrameworkDxe.h>
+
+#include <Protocol/HiiConfigAccess.h>
+#include <Protocol/HiiConfigRouting.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/FormBrowser2.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/BusSpecificDriverOverride.h>
+#include <Protocol/ComponentName2.h>
+#include <Protocol/ComponentName.h>
+#include <Protocol/DriverBinding.h>
+#include <Protocol/DevicePathToText.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/PlatformDriverOverride.h>
+#include <Protocol/DataHub.h>
+#include <Guid/MdeModuleHii.h>
+#include <Guid/VariableFormat.h>
+#include <Guid/DataHubRecords.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/HiiLib.h>
+#include <Library/BiosIdLib.h>
+#include <Library/CpuIA32.h>
+#include <Library/HobLib.h>
+#include <Guid/PlatformInfo.h>
+#include <IndustryStandard/Pci22.h>
+
+#include "Guid/SetupVariable.h"
+#include "Guid/OsSelection.h"
+
+#include <CpuType.h>
+#include <Guid/PlatformCpuInfo.h>
+#include <Protocol/SimpleTextIn.h>
+#include <Protocol/FrameworkFormBrowser.h>
+extern EFI_HII_HANDLE   mHiiHandle;
+
+UINT32
+ConvertBase10ToRaw (
+  IN  EFI_EXP_BASE10_DATA             *Data);
+
+UINT32
+ConvertBase2ToRaw (
+  IN  EFI_EXP_BASE2_DATA             *Data);
+
+EFI_STATUS
+GetStringFromToken (
+  IN      EFI_GUID                  *ProducerGuid,
+  IN      STRING_REF                Token,
+  OUT     CHAR16                    **String
+  );
+
+VOID
+SwapEntries (
+  IN  CHAR8 *Data
+  );
+
+VOID
+AsciiToUnicode (
+  IN    CHAR8     *AsciiString,
+  IN    CHAR16    *UnicodeString
+  );
+
+VOID
+EFIAPI
+SetupInfo (
+  );
+
+
+extern EFI_HANDLE mImageHandle;
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.inf b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.inf
new file mode 100644
index 0000000000..6d7e7c3f6c
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.inf
@@ -0,0 +1,141 @@
+#
+#
+# Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
+#                                                                                  

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

+#
+#
+#  This driver produces UEFI PLATFORM_DRIVER_OVERRIDE_PROTOCOL if this protocol doesn't exist.
+#  It doesn't install again if this protocol exists.
+#  It only implements one interface GetDriver of PLATFORM_DRIVER_OVERRIDE_PROTOCOL protocol
+#  and doesn't support other two interfaces GetDriverPath, DriverLoaded.
+#
+#  This driver also offers an UI interface in device manager to let user configure
+#  platform override protocol to override the default algorithm for matching
+#  drivers to controllers.
+#
+#  The main flow:
+#  1. It dynamicly locate all controller device path.
+#  2. It dynamicly locate all drivers which support binding protocol.
+#  3. It export and dynamicly update two menu to let user select the
+#     mapping between drivers to controllers.
+#  4. It save all the mapping info in NV variables for the following boot,
+#     which will be consumed by GetDriver API of the produced the platform override protocol.
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformSetupDxe
+  FILE_GUID                      = C1A69A12-8653-4fde-A215-48FCD95288C3
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = PlatformSetupDxeInit
+  UNLOAD_IMAGE                   = PlatformSetupDxeUnload
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  VfrStrings.uni
+  FwVersionStrings.uni
+  Vfr.vfr
+  Main.vfi
+  Boot.vfi
+  PlatformSetupDxe.c
+  SetupInfoRecords.c
+  PlatformSetupDxe.h
+  Security.vfi
+  SouthClusterConfig.vfi
+  Thermal.vfi
+  SetupFunctions.c
+  UnCore.vfi
+  SystemComponent.vfi
+  DebugConfig.vfi
+  UqiList.uni
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec    #for PchAccess.h
+  SecurityPkg/SecurityPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  UefiLib
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  HiiLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  DevicePathLib
+  DxeServicesTableLib
+  UefiRuntimeServicesTableLib
+  PrintLib
+  BiosIdLib
+  CpuIA32Lib
+  IoLib
+
+[Guids]
+  ##  This GUID C Name is not required for build since it is from UefiLib and not directly used by this module source.
+  ##  gEfiGlobalVariableGuid                      ## SOMETIMES_CONSUMED ## Variable:L"PlatformLang" this variable specifies the platform supported language string (RFC 4646 format)
+  ##  gEfiGlobalVariableGuid                      ## SOMETIMES_CONSUMED ## Variable:L"Lang" this variable specifies the platform supported language string (ISO 639-2 format)
+  ##
+  # There could be more than one variables, from PlatDriOver, PlatDriOver1, PlatDriOver2,...
+  #
+  # gEfiCallerIdGuid                            ## Private  ## Variable:L"PlatDriOver"
+  gEfiIfrTianoGuid                              ## CONSUMES ## Guid
+  gEfiProcessorSubClassGuid
+  gEfiMiscSubClassGuid
+  gEfiCacheSubClassGuid
+  gEfiMemorySubClassGuid
+  gEfiPlatformInfoGuid
+  gEfiNormalSetupGuid
+  gEfiSecureBootEnableDisableGuid
+  gOsSelectionVariableGuid
+  gEfiGlobalVariableGuid
+
+[Protocols]
+  gEfiComponentName2ProtocolGuid                ## SOMETIMES_CONSUMED (Get Driver Name if ComponentName2Protocol exists)
+  gEfiComponentNameProtocolGuid                 ## SOMETIMES_CONSUMED (Get Driver Name if ComponentNameProtocol exists and ComponentName2Protocol doesn't exist)
+  gEfiFirmwareVolume2ProtocolGuid               ## SOMETIMES_CONSUMED (Get Driver Name from EFI UI section if ComponentName2Protocol and ComponentNameProtocol don't exist)
+  gEfiPciIoProtocolGuid                         ## SOMETIMES_CONSUMED (Find the PCI device if PciIo protocol is installed)
+  gEfiPciRootBridgeIoProtocolGuid
+  gEfiBusSpecificDriverOverrideProtocolGuid     ## SOMETIMES_CONSUMED (Check whether the PCI device contains one or more efi drivers in its option rom by this protocol)
+
+  gEfiDriverBindingProtocolGuid                 ## SOMETIMES_CONSUMED
+  gEfiLoadedImageProtocolGuid                   ## SOMETIMES_CONSUMED
+  gEfiLoadedImageDevicePathProtocolGuid         ## SOMETIMES_CONSUMED (Show the drivers in the second page that support DriverBindingProtocol, LoadedImageProtocol and LoadedImageDevicePathProtocol)
+  gEfiDevicePathProtocolGuid                    ## SOMETIMES_CONSUMED (Show the controller device in the first page that support DevicePathProtocol)
+
+  gEfiFormBrowser2ProtocolGuid                  ## CONSUMED
+  gEfiHiiConfigRoutingProtocolGuid              ## CONSUMED
+  gEfiHiiConfigAccessProtocolGuid               ## PRODUCED
+  gEfiDevicePathToTextProtocolGuid              ## CONSUMED
+  gEdkiiFormBrowserEx2ProtocolGuid
+
+  gEfiDataHubProtocolGuid
+  gEfiLegacyBiosProtocolGuid
+  gEfiSimpleNetworkProtocolGuid
+
+  gEfiDiskInfoProtocolGuid                      ## CONSUMED
+  gEfiMpServiceProtocolGuid
+  gDxePchPlatformPolicyProtocolGuid
+  gEfiCpuIo2ProtocolGuid
+  gEfiTdtOperationProtocolGuid
+  gEfiSmbiosProtocolGuid                        ## PROTOCOL CONSUMES
+
+[Pcd.common]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+[Depex]
+  gEfiFormBrowser2ProtocolGuid AND gEfiHiiConfigRoutingProtocolGuid
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Security.vfi b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Security.vfi
new file mode 100644
index 0000000000..49669e684d
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Security.vfi
@@ -0,0 +1,104 @@
+//
+//
+// Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+//                                                                                  

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

+//
+//
+//
+// Module Name:
+//
+//   Security.vfi
+//
+// Abstract:
+//
+//   Driver Setup formset.
+//
+// --*/
+
+//
+// Security Configuration Form
+//
+
+
+form formid = SECURITY_CONFIGURATION_FORM_ID,
+  title    = STRING_TOKEN(STR_SECURITY_CONFIGURATION_TITLE);
+
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+  //
+  //TPM related
+  //
+  subtitle text = STRING_TOKEN(STR_TPM_CONFIGURATION_PROMPT);
+grayoutif ideqval Setup.ETpm== 0x1;
+  oneof   varid   = Setup.fTPM,
+    prompt      = STRING_TOKEN(STR_PTT_PROMPT),
+    help        = STRING_TOKEN(STR_PTT_HELP),
+      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_DISABLE), value= 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+  endoneof;
+endif;
+
+grayoutif ideqval Setup.fTPM == 0x1;
+  oneof   varid   = Setup.ETpm,
+    prompt      = STRING_TOKEN(STR_TPM_PROMPT),
+    help        = STRING_TOKEN(STR_TPM_HELP),
+      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_DISABLE), value= 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+  endoneof;
+endif;
+
+suppressif ideqval Setup.fTPM == 0;
+  oneof varid = Setup.MeasuredBootEnable,
+    prompt      = STRING_TOKEN(STR_MEASURED_BOOT_ENABLE_PROMPT),
+    help        = STRING_TOKEN(STR_MEASURED_BOOT_ENABLE_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value = 1, flags =  DEFAULT | MANUFACTURING | RESET_REQUIRED;
+  endoneof;
+endif;
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+
+  subtitle text = STRING_TOKEN(STR_PASSWORD_CONFIGURATION_SUBTITLE);
+
+  password varid  = Setup.AdminPassword,
+    prompt      = STRING_TOKEN(STR_ADMIN_PASSWORD),
+    help        = STRING_TOKEN(STR_ADMIN_PASSWORD_HELP),
+    flags       = 0,
+    minsize     = 0,
+    maxsize     = PASSWORD_MAX_SIZE,
+    encoding    = 1,
+  endpassword;
+
+  password varid  = Setup.UserPassword,
+    prompt      = STRING_TOKEN(STR_USER_PASSWORD),
+    help        = STRING_TOKEN(STR_USER_PASSWORD_HELP),
+    flags       = 0,
+    minsize     = 0,
+    maxsize     = PASSWORD_MAX_SIZE,
+    encoding    = 1,
+  endpassword;
+suppressif TRUE;
+  password varid  = Setup.AdminPassword,
+    prompt      = STRING_TOKEN(STR_CHANGE_ADMIN_PASSWORD),
+    help        = STRING_TOKEN(STR_CHANGE_ADMIN_PASSWORD_HELP),
+    flags       = 0,
+    minsize     = 0,
+    maxsize     = PASSWORD_MAX_SIZE,
+    encoding    = 1,
+  endpassword;
+
+  password varid  = Setup.UserPassword,
+    prompt      = STRING_TOKEN(STR_CHANGE_USER_PASSWORD),
+    help        = STRING_TOKEN(STR_CHANGE_USER_PASSWORD_HELP),
+    flags       = 0,
+    minsize     = 0,
+    maxsize     = PASSWORD_MAX_SIZE,
+    encoding    = 1,
+  endpassword;
+endif;
+
+endform;
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupFunctions.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupFunctions.c
new file mode 100644
index 0000000000..a84b425826
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupFunctions.c
@@ -0,0 +1,85 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+    SetupFunctions.c
+
+Abstract:
+
+Revision History
+
+--*/
+
+#include "PlatformSetupDxe.h"
+
+VOID
+AsciiToUnicode (
+  IN    CHAR8     *AsciiString,
+  IN    CHAR16    *UnicodeString
+  )
+{
+  UINT8           Index;
+
+  Index = 0;
+  while (AsciiString[Index] != 0) {
+    UnicodeString[Index] = (CHAR16)AsciiString[Index];
+    Index++;
+  }
+}
+
+VOID
+SwapEntries (
+  IN  CHAR8 *Data
+  )
+{
+  UINT16  Index;
+  CHAR8   Temp8;
+
+  Index = 0;
+  while (Data[Index] != 0 && Data[Index+1] != 0) {
+    Temp8 = Data[Index];
+    Data[Index] = Data[Index+1];
+    Data[Index+1] = Temp8;
+    Index +=2;
+  }
+
+  return;
+}
+
+UINT32
+ConvertBase10ToRaw (
+  IN  EFI_EXP_BASE10_DATA             *Data)
+{
+  UINTN         Index;
+  UINT32        RawData;
+
+  RawData = Data->Value;
+  for (Index = 0; Index < (UINTN) Data->Exponent; Index++) {
+     RawData *= 10;
+  }
+
+  return  RawData;
+}
+
+UINT32
+ConvertBase2ToRaw (
+  IN  EFI_EXP_BASE2_DATA             *Data)
+{
+  UINTN         Index;
+  UINT32        RawData;
+
+  RawData = Data->Value;
+  for (Index = 0; Index < (UINTN) Data->Exponent; Index++) {
+     RawData <<= 1;
+  }
+
+  return  RawData;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupInfoRecords.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupInfoRecords.c
new file mode 100644
index 0000000000..c404ada588
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupInfoRecords.c
@@ -0,0 +1,1855 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+    SetupInfoRecords.c
+
+Abstract:
+
+    This is the filter driver to retrieve data hub entries.
+
+Revision History:
+--*/
+
+#include "PlatformSetupDxe.h"
+#include <Protocol/LegacyBios.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/SimpleNetwork.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/DiskInfo.h>
+#include <Protocol/IdeControllerInit.h>
+#include <Protocol/MpService.h>
+#include <Protocol/PchPlatformPolicy.h>
+#include <Protocol/CpuIo2.h>
+#include <Protocol/Smbios.h>
+#include <IndustryStandard/SmBios.h>
+#include <Library/IoLib.h>
+#include <Library/I2CLib.h>
+#include <Guid/GlobalVariable.h>
+
+#include "Valleyview.h"
+#include "VlvAccess.h"
+#include "PchAccess.h"
+#include "SetupMode.h"
+#include "PchCommonDefinitions.h"
+#include <PlatformBaseAddresses.h>
+
+
+typedef struct {
+  UINT8  ID;
+  CHAR8  String[16];
+} VLV_REV;
+
+typedef struct {
+  UINT8 RevId;
+  CHAR8 String[16];
+} SB_REV;
+
+//
+// Silicon Steppings
+//
+SB_REV  SBRevisionTable[] = {
+  {V_PCH_LPC_RID_0, "(A0 Stepping)"},
+  {V_PCH_LPC_RID_1, "(A0 Stepping)"},
+  {V_PCH_LPC_RID_2, "(A1 Stepping)"},
+  {V_PCH_LPC_RID_3, "(A1 Stepping)"},
+  {V_PCH_LPC_RID_4, "(B0 Stepping)"},
+  {V_PCH_LPC_RID_5, "(B0 Stepping)"},
+  {V_PCH_LPC_RID_6, "(B1 Stepping)"},
+  {V_PCH_LPC_RID_7, "(B1 Stepping)"},
+  {V_PCH_LPC_RID_8, "(B2 Stepping)"},
+  {V_PCH_LPC_RID_9, "(B2 Stepping)"},
+  {V_PCH_LPC_RID_A, "(B3 Stepping)"},
+  {V_PCH_LPC_RID_B, "(B3 Stepping)"},
+  {V_PCH_LPC_RID_C, "(C0 Stepping)"},
+  {V_PCH_LPC_RID_D, "(C0 Stepping)"}
+};
+
+#define LEFT_JUSTIFY  0x01
+#define PREFIX_SIGN   0x02
+#define PREFIX_BLANK  0x04
+#define COMMA_TYPE    0x08
+#define LONG_TYPE     0x10
+#define PREFIX_ZERO   0x20
+
+#define ICH_REG_REV                 0x08
+#define MSR_IA32_PLATFORM_ID        0x17
+
+
+BOOLEAN                         mSetupInfoDone = FALSE;
+UINT8                           mUseProductKey = 0;
+EFI_EXP_BASE10_DATA             mProcessorFrequency;
+EFI_EXP_BASE10_DATA             mProcessorFsbFrequency;
+
+EFI_GUID                        mProcessorProducerGuid;
+EFI_HII_HANDLE                  mHiiHandle;
+EFI_PLATFORM_CPU_INFO           mPlatformCpuInfo;
+SYSTEM_CONFIGURATION            mSystemConfiguration;
+EFI_PLATFORM_INFO_HOB           *mPlatformInfo;
+
+
+#define memset SetMem
+
+UINT16                mMemorySpeed         = 0xffff;
+EFI_PHYSICAL_ADDRESS  mMemorySizeChannelASlot0  = 0;
+UINT16                mMemorySpeedChannelASlot0 = 0xffff;
+EFI_PHYSICAL_ADDRESS  mMemorySizeChannelASlot1  = 0;
+UINT16                mMemorySpeedChannelASlot1 = 0xffff;
+EFI_PHYSICAL_ADDRESS  mMemorySizeChannelBSlot0  = 0;
+UINT16                mMemorySpeedChannelBSlot0 = 0xffff;
+EFI_PHYSICAL_ADDRESS  mMemorySizeChannelBSlot1  = 0;
+UINT16                mMemorySpeedChannelBSlot1 = 0xffff;
+EFI_PHYSICAL_ADDRESS  mMemorySizeChannelCSlot0  = 0;
+UINT16                mMemorySpeedChannelCSlot0 = 0xffff;
+EFI_PHYSICAL_ADDRESS  mMemorySizeChannelCSlot1  = 0;
+UINT16                mMemorySpeedChannelCSlot1 = 0xffff;
+UINTN                 mMemoryMode          = 0xff;
+
+#define CHARACTER_NUMBER_FOR_VALUE  30
+  typedef struct {
+  EFI_STRING_TOKEN            MemoryDeviceLocator;
+  EFI_STRING_TOKEN            MemoryBankLocator;
+  EFI_STRING_TOKEN            MemoryManufacturer;
+  EFI_STRING_TOKEN            MemorySerialNumber;
+  EFI_STRING_TOKEN            MemoryAssetTag;
+  EFI_STRING_TOKEN            MemoryPartNumber;
+  EFI_INTER_LINK_DATA         MemoryArrayLink;
+  EFI_INTER_LINK_DATA         MemorySubArrayLink;
+  UINT16                      MemoryTotalWidth;
+  UINT16                      MemoryDataWidth;
+  UINT64                      MemoryDeviceSize;
+  EFI_MEMORY_FORM_FACTOR      MemoryFormFactor;
+  UINT8                       MemoryDeviceSet;
+  EFI_MEMORY_ARRAY_TYPE       MemoryType;
+  EFI_MEMORY_TYPE_DETAIL      MemoryTypeDetail;
+  UINT16                      MemorySpeed;
+  EFI_MEMORY_STATE            MemoryState;
+} EFI_MEMORY_ARRAY_LINK;
+
+
+typedef struct {
+  EFI_PHYSICAL_ADDRESS        MemoryArrayStartAddress;
+  EFI_PHYSICAL_ADDRESS        MemoryArrayEndAddress;
+  EFI_INTER_LINK_DATA         PhysicalMemoryArrayLink;
+  UINT16                      MemoryArrayPartitionWidth;
+} EFI_MEMORY_ARRAY_START_ADDRESS;
+
+
+typedef enum {
+  PCH_SATA_MODE_IDE = 0,
+  PCH_SATA_MODE_AHCI,
+  PCH_SATA_MODE_RAID,
+  PCH_SATA_MODE_MAX
+} PCH_SATA_MODE;
+
+/**
+  Acquire the string associated with the Index from smbios structure and return it.
+  The caller is responsible for free the string buffer.
+
+  @param OptionalStrStart   The start position to search the string
+  @param Index              The index of the string to extract
+  @param String             The string that is extracted
+
+  @retval EFI_SUCCESS       The function returns EFI_SUCCESS always.
+
+**/
+EFI_STATUS
+GetOptionalStringByIndex (
+  IN      CHAR8                   *OptionalStrStart,
+  IN      UINT8                   Index,
+  OUT     CHAR16                  **String
+  )
+{
+  UINTN          StrSize;
+
+  if (Index == 0) {
+    *String = AllocateZeroPool (sizeof (CHAR16));
+    return EFI_SUCCESS;
+  }
+
+  StrSize = 0;
+  do {
+    Index--;
+    OptionalStrStart += StrSize;
+    StrSize           = AsciiStrSize (OptionalStrStart);
+  } while (OptionalStrStart[StrSize] != 0 && Index != 0);
+
+  if ((Index != 0) || (StrSize == 1)) {
+    //
+    // Meet the end of strings set but Index is non-zero, or
+    // Find an empty string
+    //
+    return EFI_NOT_FOUND;
+  } else {
+    *String = AllocatePool (StrSize * sizeof (CHAR16));
+    AsciiStrToUnicodeStr (OptionalStrStart, *String);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  VSPrint worker function that prints a Value as a decimal number in Buffer
+
+  @param Buffer  Location to place ascii decimal number string of Value.
+  @param Value   Decimal value to convert to a string in Buffer.
+  @param Flags   Flags to use in printing decimal string, see file header for details.
+  @param Width   Width of hex value.
+
+  Number of characters printed.
+
+**/
+UINTN
+EfiValueToString (
+  IN  OUT CHAR16  *Buffer,
+  IN  INT64       Value,
+  IN  UINTN       Flags,
+  IN  UINTN       Width
+  )
+{
+  CHAR16    TempBuffer[CHARACTER_NUMBER_FOR_VALUE];
+  CHAR16    *TempStr;
+  CHAR16    *BufferPtr;
+  UINTN     Count;
+  UINTN     ValueCharNum;
+  UINTN     Remainder;
+  CHAR16    Prefix;
+  UINTN     Index;
+  BOOLEAN   ValueIsNegative;
+  UINT64    TempValue;
+
+  TempStr         = TempBuffer;
+  BufferPtr       = Buffer;
+  Count           = 0;
+  ValueCharNum    = 0;
+  ValueIsNegative = FALSE;
+
+  if (Width > CHARACTER_NUMBER_FOR_VALUE - 1) {
+    Width = CHARACTER_NUMBER_FOR_VALUE - 1;
+  }
+
+  if (Value < 0) {
+    Value           = -Value;
+    ValueIsNegative = TRUE;
+  }
+
+  do {
+    TempValue = Value;
+    Value = (INT64)DivU64x32 ((UINT64)Value, 10);
+    Remainder = (UINTN)((UINT64)TempValue - 10 * Value);
+    *(TempStr++) = (CHAR16)(Remainder + '0');
+    ValueCharNum++;
+    Count++;
+    if ((Flags & COMMA_TYPE) == COMMA_TYPE) {
+      if (ValueCharNum % 3 == 0 && Value != 0) {
+        *(TempStr++) = ',';
+        Count++;
+      }
+    }
+  } while (Value != 0);
+
+  if (ValueIsNegative) {
+    *(TempStr++)    = '-';
+    Count++;
+  }
+
+  if ((Flags & PREFIX_ZERO) && !ValueIsNegative) {
+    Prefix = '0';
+  } else {
+    Prefix = ' ';
+  }
+
+  Index = Count;
+  if (!(Flags & LEFT_JUSTIFY)) {
+    for (; Index < Width; Index++) {
+      *(TempStr++) = Prefix;
+    }
+  }
+
+  //
+  // Reverse temp string into Buffer.
+  //
+  if (Width > 0 && (UINTN) (TempStr - TempBuffer) > Width) {
+    TempStr = TempBuffer + Width;
+  }
+  Index = 0;
+  while (TempStr != TempBuffer) {
+    *(BufferPtr++) = *(--TempStr);
+    Index++;
+  }
+
+  *BufferPtr = 0;
+  return Index;
+}
+
+static CHAR16 mHexStr[] = { L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7',
+                            L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F' };
+
+/**
+  VSPrint worker function that prints a Value as a hex number in Buffer
+
+  @param  Buffer  Location to place ascii hex string of Value.
+  @param  Value   Hex value to convert to a string in Buffer.
+  @param  Flags   Flags to use in printing Hex string, see file header for details.
+  @param  Width   Width of hex value.
+
+  @retval         Number of characters printed.
+
+**/
+UINTN
+EfiValueToHexStr (
+  IN  OUT CHAR16  *Buffer,
+  IN  UINT64      Value,
+  IN  UINTN       Flags,
+  IN  UINTN       Width
+  )
+{
+  CHAR16  TempBuffer[CHARACTER_NUMBER_FOR_VALUE];
+  CHAR16  *TempStr;
+  CHAR16  Prefix;
+  CHAR16  *BufferPtr;
+  UINTN   Count;
+  UINTN   Index;
+
+  TempStr   = TempBuffer;
+  BufferPtr = Buffer;
+
+  //
+  // Count starts at one since we will null terminate. Each iteration of the
+  // loop picks off one nibble. Oh yea TempStr ends up backwards
+  //
+  Count = 0;
+
+  if (Width > CHARACTER_NUMBER_FOR_VALUE - 1) {
+    Width = CHARACTER_NUMBER_FOR_VALUE - 1;
+  }
+
+  do {
+    Index = ((UINTN)Value & 0xf);
+    *(TempStr++) = mHexStr[Index];
+    Value = RShiftU64 (Value, 4);
+    Count++;
+  } while (Value != 0);
+
+  if (Flags & PREFIX_ZERO) {
+    Prefix = '0';
+  } else {
+    Prefix = ' ';
+  }
+
+  Index = Count;
+  if (!(Flags & LEFT_JUSTIFY)) {
+    for (; Index < Width; Index++) {
+      *(TempStr++) = Prefix;
+    }
+  }
+
+  //
+  // Reverse temp string into Buffer.
+  //
+  if (Width > 0 && (UINTN) (TempStr - TempBuffer) > Width) {
+    TempStr = TempBuffer + Width;
+  }
+  Index = 0;
+  while (TempStr != TempBuffer) {
+    *(BufferPtr++) = *(--TempStr);
+    Index++;
+  }
+
+  *BufferPtr = 0;
+  return Index;
+}
+
+/*++
+  Converts MAC address to Unicode string.
+  The value is 64-bit and the resulting string will be 12
+  digit hex number in pairs of digits separated by dashes.
+
+  @param  String    string that will contain the value
+  @param  MacAddr   add argument and description to function comment
+  @param  AddrSize  add argument and description to function comment
+
+**/
+CHAR16 *
+StrMacToString (
+  OUT CHAR16              *String,
+  IN  EFI_MAC_ADDRESS     *MacAddr,
+  IN  UINT32              AddrSize
+  )
+{
+  UINT32  i;
+
+  for (i = 0; i < AddrSize; i++) {
+
+    EfiValueToHexStr (
+      &String[2 * i],
+      MacAddr->Addr[i] & 0xFF,
+      PREFIX_ZERO,
+      2
+      );
+  }
+
+  //
+  // Terminate the string.
+  //
+  String[2 * AddrSize] = L'\0';
+
+  return String;
+}
+
+VOID UpdateLatestBootTime() {
+  UINTN                         VarSize;
+  EFI_STATUS                   Status;
+  UINT64                       TimeValue;
+  CHAR16                       Buffer[40];
+  if (mSystemConfiguration.LogBootTime != 1) {
+    return;
+  }
+  VarSize = sizeof(TimeValue);
+  Status = gRT->GetVariable(
+                  BOOT_TIME_NAME,
+                  &gEfiNormalSetupGuid,
+                  NULL,
+                  &VarSize,
+                  &TimeValue
+				          );
+  if (EFI_ERROR(Status)) {
+    return;
+  }
+  UnicodeSPrint (Buffer, sizeof (Buffer), L"%d ms", (UINT32)TimeValue);
+  HiiSetString(mHiiHandle,STRING_TOKEN(STR_LOG_BOOT_TIME_VALUE), Buffer, NULL);
+}
+
+/**
+  Get Cache Type for the specified Cache. This function is invoked when there is data records
+  available in the Data Hub.
+
+  Get Cache Type function arguments:
+
+  @param  Instance        The instance number of the subclass with the same ProducerName..
+  @param  SubInstance     The instance number of the RecordType for the same Instance.
+  @param  CacheType       Cache type, see definition of EFI_CACHE_TYPE_DATA.
+
+  @retval EFI_STATUS
+
+**/
+EFI_STATUS
+GetCacheType(
+  IN  UINT16                            Instance,
+  IN  UINT16                            SubInstance,
+  IN  EFI_CACHE_TYPE_DATA*              CacheType)
+{
+  EFI_STATUS                  Status;
+  EFI_DATA_HUB_PROTOCOL       *DataHub;
+  EFI_DATA_RECORD_HEADER      *Record;
+  UINT64                      MonotonicCount;
+  EFI_CACHE_VARIABLE_RECORD*  CacheVariableRecord;
+  EFI_SUBCLASS_TYPE1_HEADER   *DataHeader;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiDataHubProtocolGuid,
+                  NULL,
+                  (void **)&DataHub
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  // Get all available data records from data hub
+  //
+  MonotonicCount = 0;
+  Record = NULL;
+
+  do {
+    Status = DataHub->GetNextRecord (
+	                    DataHub,
+						&MonotonicCount,
+						NULL,
+						&Record
+						);
+    if (!EFI_ERROR(Status)) {
+      if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {
+        DataHeader  = (EFI_SUBCLASS_TYPE1_HEADER *)(Record + 1);
+
+        if(CompareGuid(&Record->DataRecordGuid, &gEfiCacheSubClassGuid) &&
+          (DataHeader->RecordType == CacheTypeRecordType) &&
+          (DataHeader->Instance == Instance) &&
+          (DataHeader->SubInstance == SubInstance)) {
+          CacheVariableRecord     = (EFI_CACHE_VARIABLE_RECORD  *)(DataHeader + 1);
+          if(CacheType){
+            *CacheType = CacheVariableRecord->CacheType;
+            return EFI_SUCCESS;
+          }
+        }
+      }
+    }
+  } while(!EFI_ERROR(Status) && (MonotonicCount != 0));
+
+  return EFI_NOT_FOUND;
+}
+
+/**
+  Setup data filter function. This function is invoked when there is data records
+  available in the Data Hub.
+
+
+  Standard event notification function arguments:
+  @param Event          The event that is signaled.
+  @param Context        Not used here.
+
+  @retval EFI_STATUS
+
+**/
+VOID
+PrepareSetupInformation (
+  )
+{
+
+  EFI_STATUS                  Status;
+  EFI_DATA_HUB_PROTOCOL       *DataHub;
+  EFI_DATA_RECORD_HEADER      *Record;
+  UINT8                       *SrcData;
+  EFI_SUBCLASS_TYPE1_HEADER   *DataHeader;
+  CHAR16                      *NewString;
+  CHAR16                      *NewString2;
+  CHAR16                      *NewStringToken;
+  STRING_REF                  TokenToUpdate;
+  EFI_PROCESSOR_VERSION_DATA  *ProcessorVersion;
+  UINTN                       Index;
+  UINTN                       DataOutput;
+
+  EFI_PROCESSOR_MICROCODE_REVISION_DATA   *CpuUcodeRevisionData;
+  EFI_MEMORY_ARRAY_START_ADDRESS          *MemoryArray;
+  EFI_MEMORY_ARRAY_LINK                   *MemoryArrayLink;
+  UINT64                      MonotonicCount;
+
+  CHAR16                      Version[100];         //Assuming that strings are < 100 UCHAR
+  CHAR16                      ReleaseDate[100];     //Assuming that strings are < 100 UCHAR
+  CHAR16                      ReleaseTime[100];     //Assuming that strings are < 100 UCHAR
+
+  NewString = AllocateZeroPool (0x100);
+  NewString2 = AllocateZeroPool (0x100);
+  SetMem(Version, sizeof(Version), 0);
+  SetMem(ReleaseDate, sizeof(ReleaseDate), 0);
+  SetMem(ReleaseTime, sizeof(ReleaseTime), 0);
+
+  //
+  // Get the Data Hub Protocol. Assume only one instance
+  //
+  Status = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, (void **)&DataHub);
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  // Get all available data records from data hub
+  //
+  MonotonicCount = 0;
+  Record = NULL;
+
+  do {
+    Status = DataHub->GetNextRecord (DataHub, &MonotonicCount, NULL, &Record);
+    if (!EFI_ERROR(Status)) {
+      if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {
+        DataHeader  = (EFI_SUBCLASS_TYPE1_HEADER *)(Record + 1);
+        SrcData     = (UINT8  *)(DataHeader + 1);
+
+        //
+        // Processor
+        //
+        if (CompareGuid(&Record->DataRecordGuid, &gEfiProcessorSubClassGuid)) {
+          CopyMem (&mProcessorProducerGuid, &Record->ProducerName, sizeof(EFI_GUID));
+          switch (DataHeader->RecordType) {
+            case ProcessorCoreFrequencyRecordType:
+              CopyMem(&mProcessorFrequency, SrcData, sizeof(EFI_EXP_BASE10_DATA));
+              Index = EfiValueToString (
+			            NewString,
+						ConvertBase10ToRaw ((EFI_EXP_BASE10_DATA *)SrcData)/1000000000,
+						PREFIX_ZERO,
+						0
+						);
+              StrCat (NewString, L".");
+              EfiValueToString (
+			    NewString + Index + 1,
+				((ConvertBase10ToRaw ((EFI_EXP_BASE10_DATA *)SrcData)%1000000000)/10000000),
+				PREFIX_ZERO,
+				0
+				);
+              StrCat (NewString, L" GHz");
+              TokenToUpdate = (STRING_REF)STR_PROCESSOR_SPEED_VALUE;
+              HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL);
+              break;
+
+            case ProcessorVersionRecordType:
+              ProcessorVersion = (EFI_PROCESSOR_VERSION_DATA *)SrcData;
+              NewStringToken = HiiGetPackageString(&mProcessorProducerGuid, *ProcessorVersion, NULL);
+              TokenToUpdate = (STRING_REF)STR_PROCESSOR_VERSION_VALUE;
+              HiiSetString(mHiiHandle, TokenToUpdate, NewStringToken, NULL);
+              break;
+            case CpuUcodeRevisionDataRecordType:
+              CpuUcodeRevisionData = (EFI_PROCESSOR_MICROCODE_REVISION_DATA *) SrcData;
+              if (CpuUcodeRevisionData->ProcessorMicrocodeRevisionNumber != 0) {
+                EfiValueToHexStr (
+				  NewString,
+                  CpuUcodeRevisionData->ProcessorMicrocodeRevisionNumber,
+                  PREFIX_ZERO,
+                  8
+				  );
+                TokenToUpdate = (STRING_REF)STR_PROCESSOR_MICROCODE_VALUE;
+                HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL);
+              }
+              break;
+            default:
+              break;
+          }
+
+        //
+        // Cache
+        //
+        } else if (CompareGuid(&Record->DataRecordGuid, &gEfiCacheSubClassGuid) &&
+                   (DataHeader->RecordType == CacheSizeRecordType)) {
+          if (DataHeader->SubInstance == EFI_CACHE_L1) {
+            EFI_CACHE_TYPE_DATA              CacheType;
+            if (EFI_SUCCESS == GetCacheType(DataHeader->Instance, DataHeader->SubInstance,&CacheType)){
+              if (CacheType == EfiCacheTypeData) {
+                TokenToUpdate = (STRING_REF)STR_PROCESSOR_L1_DATA_CACHE_VALUE;
+              } else if (CacheType == EfiCacheTypeInstruction) {
+                  TokenToUpdate = (STRING_REF)STR_PROCESSOR_L1_INSTR_CACHE_VALUE;
+              } else {
+                continue;
+              }
+            } else {
+              continue;
+            }
+          }
+          else if (DataHeader->SubInstance == EFI_CACHE_L2) {
+            TokenToUpdate = (STRING_REF)STR_PROCESSOR_L2_CACHE_VALUE;
+          } else {
+            continue;
+          }
+          if (ConvertBase2ToRaw((EFI_EXP_BASE2_DATA *)SrcData)) {
+            DataOutput = ConvertBase2ToRaw((EFI_EXP_BASE2_DATA *)SrcData) >> 10;
+            EfiValueToString (NewString, DataOutput, PREFIX_ZERO, 0);
+
+            StrCat (NewString, L" KB");
+            if (DataHeader->SubInstance == EFI_CACHE_L3) {
+              HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL);
+            } else if(DataHeader->SubInstance == EFI_CACHE_L2 && mPlatformCpuInfo.CpuPackage.CoresPerPhysicalPackage > 1){
+			  //
+              // Show XxL2 string
+			  //
+              EfiValueToString (
+			    NewString2,
+                mPlatformCpuInfo.CpuPackage.CoresPerPhysicalPackage,
+                PREFIX_ZERO,
+                0
+				);
+              StrCat(NewString2, L"x ");
+              StrCat(NewString2, NewString);
+              HiiSetString(mHiiHandle, TokenToUpdate, NewString2, NULL);
+            } else {
+              HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL);
+            }
+          }
+
+        //
+        // Memory
+        //
+        } else if (CompareGuid(&Record->DataRecordGuid, &gEfiMemorySubClassGuid)) {
+          switch (DataHeader->RecordType) {
+            case EFI_MEMORY_ARRAY_LINK_RECORD_NUMBER:
+              MemoryArrayLink = (EFI_MEMORY_ARRAY_LINK *)SrcData;
+
+              if (MemoryArrayLink->MemorySpeed > 0) {
+                //
+                // Save the lowest speed memory module
+                //
+                if (MemoryArrayLink->MemorySpeed < mMemorySpeed) {
+                  mMemorySpeed = MemoryArrayLink->MemorySpeed;
+                }
+                switch (DataHeader->SubInstance) {
+                  case 1:
+                    mMemorySpeedChannelASlot0 = MemoryArrayLink->MemorySpeed;
+                    mMemorySizeChannelASlot0 = MemoryArrayLink->MemoryDeviceSize;
+                    break;
+                  case 2:
+                    mMemorySpeedChannelASlot1 = MemoryArrayLink->MemorySpeed;
+                    mMemorySizeChannelASlot1 = MemoryArrayLink->MemoryDeviceSize;
+                    break;
+                  case 3:
+                    mMemorySpeedChannelBSlot0 = MemoryArrayLink->MemorySpeed;
+                    mMemorySizeChannelBSlot0 = MemoryArrayLink->MemoryDeviceSize;
+                    break;
+                  case 4:
+                    mMemorySpeedChannelBSlot1 = MemoryArrayLink->MemorySpeed;
+                    mMemorySizeChannelBSlot1 = MemoryArrayLink->MemoryDeviceSize;
+                    break;
+                  case 5:
+                    mMemorySpeedChannelCSlot0 = MemoryArrayLink->MemorySpeed;
+                    mMemorySizeChannelCSlot0 = MemoryArrayLink->MemoryDeviceSize;
+                    break;
+                  case 6:
+                    mMemorySpeedChannelCSlot1 = MemoryArrayLink->MemorySpeed;
+                    mMemorySizeChannelCSlot1 = MemoryArrayLink->MemoryDeviceSize;
+                    break;
+                  default:
+                    break;
+                  }
+              }
+              break;
+
+            case EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER:
+              MemoryArray = (EFI_MEMORY_ARRAY_START_ADDRESS *)SrcData;
+              if (MemoryArray->MemoryArrayEndAddress - MemoryArray->MemoryArrayStartAddress) {
+              	DataOutput = (UINTN)RShiftU64((MemoryArray->MemoryArrayEndAddress - MemoryArray->MemoryArrayStartAddress + 1), 20);
+              	EfiValueToString (NewString, DataOutput / 1024, PREFIX_ZERO, 0);
+              	if(DataOutput % 1024) {
+              	  StrCat (NewString, L".");
+              	  DataOutput = ((DataOutput % 1024) * 1000) / 1024;
+              	  while(!(DataOutput % 10))
+              	    DataOutput = DataOutput / 10;
+                  EfiValueToString (NewString2, DataOutput, PREFIX_ZERO, 0);
+                  StrCat (NewString, NewString2);
+                }
+                StrCat (NewString, L" GB");
+                TokenToUpdate = (STRING_REF)STR_TOTAL_MEMORY_SIZE_VALUE;
+                HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL);
+              }
+              break;
+
+            default:
+              break;
+          }
+        }
+      }
+    }
+  } while (!EFI_ERROR(Status) && (MonotonicCount != 0));
+
+  Status = GetBiosVersionDateTime (
+             Version,
+			 ReleaseDate,
+			 ReleaseTime
+			 );
+
+  DEBUG ((EFI_D_ERROR, "GetBiosVersionDateTime :%s %s %s \n", Version, ReleaseDate, ReleaseTime));
+  if (!EFI_ERROR (Status)) {
+    UINTN         Length = 0;
+    CHAR16        *BuildDateTime;
+
+    Length = StrLen(ReleaseDate) + StrLen(ReleaseTime);
+
+    BuildDateTime = AllocateZeroPool ((Length+2) * sizeof(CHAR16));
+    StrCpy (BuildDateTime, ReleaseDate);
+    StrCat (BuildDateTime, L" ");
+    StrCat (BuildDateTime, ReleaseTime);
+
+    TokenToUpdate = (STRING_REF)STR_BIOS_VERSION_VALUE;
+    DEBUG ((EFI_D_ERROR, "update STR_BIOS_VERSION_VALUE\n"));
+    HiiSetString(mHiiHandle, TokenToUpdate, Version, NULL);
+
+    TokenToUpdate = (STRING_REF)STR_BIOS_BUILD_TIME_VALUE;
+    DEBUG ((EFI_D_ERROR, "update STR_BIOS_BUILD_TIME_VALUE\n"));
+    HiiSetString(mHiiHandle, TokenToUpdate, BuildDateTime, NULL);
+  }
+
+  //
+  // Calculate and update memory speed display in Main Page
+  //
+  //
+  // Update the overall memory speed
+  //
+  if (mMemorySpeed != 0xffff) {
+    EfiValueToString (NewString, mMemorySpeed, PREFIX_ZERO, 0);
+    StrCat (NewString, L" MHz");
+
+    TokenToUpdate = (STRING_REF)STR_SYSTEM_MEMORY_SPEED_VALUE;
+    HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL);
+  }
+
+  gBS->FreePool(NewString);
+  gBS->FreePool(NewString2);
+
+  return;
+}
+
+/**
+
+  Routine Description: update the SETUP info for "Additional Information" which is SMBIOS info.
+
+  @retval EFI_STATUS
+
+**/
+EFI_STATUS
+UpdateAdditionalInformation (
+  )
+{
+  EFI_STATUS                      Status;
+  UINT64                          MonotonicCount;
+  EFI_DATA_HUB_PROTOCOL           *DataHub;
+  EFI_DATA_RECORD_HEADER          *Record;
+  EFI_SUBCLASS_TYPE1_HEADER       *DataHeader;
+  EFI_SMBIOS_PROTOCOL             *Smbios;
+  EFI_SMBIOS_HANDLE               SmbiosHandle;
+  EFI_SMBIOS_TABLE_HEADER         *SmbiosRecord;
+  SMBIOS_TABLE_TYPE0              *Type0Record;
+  UINT8                           StrIndex;
+  CHAR16                          *BiosVersion = NULL;
+  CHAR16                          *IfwiVersion = NULL;
+  UINT16                          SearchIndex;
+  EFI_STRING_ID                   TokenToUpdate;
+#if defined( RVP_SUPPORT ) && RVP_SUPPORT
+  EFI_MISC_SYSTEM_MANUFACTURER    *SystemManufacturer;
+#endif
+
+  Status = gBS->LocateProtocol (
+                  &gEfiDataHubProtocolGuid,
+                  NULL,
+                  (void **)&DataHub
+                  );
+
+  ASSERT_EFI_ERROR(Status);
+
+  MonotonicCount  = 0;
+  Record = NULL;
+  do {
+    Status = DataHub->GetNextRecord (
+                        DataHub,
+                        &MonotonicCount,
+                        NULL,
+                        &Record
+                        );
+    if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {
+      DataHeader  = (EFI_SUBCLASS_TYPE1_HEADER *)(Record + 1);
+
+      if (CompareGuid(&Record->DataRecordGuid, &gEfiMiscSubClassGuid) &&
+          (DataHeader->RecordType == EFI_MISC_SYSTEM_MANUFACTURER_RECORD_NUMBER)) {
+#if defined( RVP_SUPPORT ) && RVP_SUPPORT
+        //
+        // System Information
+        //
+        SystemManufacturer = (EFI_MISC_SYSTEM_MANUFACTURER *)(DataHeader + 1);
+
+        //
+        // UUID  (System Information)
+        //
+        SMBIOSString = EfiLibAllocateZeroPool (0x100);
+        GuidToString ( &SystemManufacturer->SystemUuid, SMBIOSString, 0x00 );
+
+        TokenToUpdate = (STRING_REF)STR_SYSTEM_UUID_VALUE;
+        HiiSetString(mHiiHandle, TokenToUpdate, SMBIOSString, NULL);
+
+        gBS->FreePool(SMBIOSString);
+#endif
+      }
+    }
+  } while (!EFI_ERROR(Status) && (MonotonicCount != 0));
+
+  Status = gBS->LocateProtocol (
+                  &gEfiSmbiosProtocolGuid,
+                  NULL,
+                  (VOID **) &Smbios
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  do {
+    Status = Smbios->GetNext (
+                       Smbios,
+                       &SmbiosHandle,
+                       NULL,
+                       &SmbiosRecord,
+                       NULL
+                       );
+    if (SmbiosRecord->Type == EFI_SMBIOS_TYPE_BIOS_INFORMATION) {
+      Type0Record = (SMBIOS_TABLE_TYPE0 *) SmbiosRecord;
+      StrIndex = Type0Record->BiosVersion;
+      GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type0Record + Type0Record->Hdr.Length), StrIndex, &BiosVersion);
+      TokenToUpdate = STRING_TOKEN (STR_BIOS_VERSION_VALUE);
+      for (SearchIndex = 0x0; SearchIndex < SMBIOS_STRING_MAX_LENGTH; SearchIndex++) {
+        if (BiosVersion[SearchIndex] == 0x0020) {
+          BiosVersion[SearchIndex] = 0x0000;
+          IfwiVersion = (CHAR16 *)(&BiosVersion[SearchIndex+1]);
+          break;
+        } else if (BiosVersion[SearchIndex] == 0x0000) {
+          break;
+        }
+      }
+      HiiSetString (mHiiHandle, TokenToUpdate, BiosVersion, NULL);
+
+      //
+      // Check IfwiVersion, to avoid no IFWI version in SMBIOS Type 0 strucntion
+      //
+      if(IfwiVersion) {
+        TokenToUpdate = STRING_TOKEN (STR_IFWI_VERSION_VALUE);
+        HiiSetString (mHiiHandle, TokenToUpdate, IfwiVersion, NULL);
+      }
+    }
+  } while (!EFI_ERROR(Status));
+
+  UpdateLatestBootTime();
+
+  return  EFI_SUCCESS;
+}
+
+VOID
+UpdateCPUInformation ()
+{
+  CHAR16								Buffer[40];
+  UINT16                                FamilyId;
+  UINT8                                 Model;
+  UINT8                                 SteppingId;
+  UINT8                                 ProcessorType;
+  EFI_STATUS                            Status;
+  EFI_MP_SERVICES_PROTOCOL              *MpService;
+  UINTN                                 MaximumNumberOfCPUs;
+  UINTN                                 NumberOfEnabledCPUs;
+  UINT32								Buffer32 = 0xFFFFFFFF;   // Keep buffer with unknown device
+
+  EfiCpuVersion (&FamilyId, &Model, &SteppingId, &ProcessorType);
+
+  //
+  //we need raw Model data
+  //
+  Model = Model & 0xf;
+
+  //
+  //Family/Model/Step
+  //
+  UnicodeSPrint (Buffer, sizeof (Buffer), L"%d/%d/%d", FamilyId,  Model, SteppingId);
+  HiiSetString(mHiiHandle,STRING_TOKEN(STR_PROCESSOR_ID_VALUE), Buffer, NULL);
+
+  Status = gBS->LocateProtocol (
+                  &gEfiMpServiceProtocolGuid,
+                  NULL,
+                  (void **)&MpService
+                  );
+  if (!EFI_ERROR (Status)) {
+    //
+    // Determine the number of processors
+    //
+    MpService->GetNumberOfProcessors (
+                 MpService,
+                 &MaximumNumberOfCPUs,
+                 &NumberOfEnabledCPUs
+                 );
+    UnicodeSPrint (Buffer, sizeof (Buffer), L"%d", MaximumNumberOfCPUs);
+    HiiSetString(mHiiHandle,STRING_TOKEN(STR_PROCESSOR_CORE_VALUE), Buffer, NULL);
+  }
+  //
+  // Update Mobile / Desktop / Tablet SKU
+  //
+  Buffer32 =(UINT32) RShiftU64 (EfiReadMsr (MSR_IA32_PLATFORM_ID), 50) & 0x07;
+
+  switch(Buffer32){
+      case 0x0:
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"(%d) - ISG SKU SOC", Buffer32);
+        break;
+      case 0x01:
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"(%d) - Mobile SKU SOC", Buffer32);
+        break;
+      case 0x02:
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"(%d) - Desktop SKU SOC", Buffer32);
+        break;
+      case 0x03:
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"(%d) - Mobile SKU SOC", Buffer32);
+        break;
+      default:
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"(%d) - Unknown SKU SOC", Buffer32);
+        break;
+    }
+  HiiSetString(mHiiHandle,STRING_TOKEN(STR_PROCESSOR_SKU_VALUE), Buffer, NULL);
+
+}
+
+
+EFI_STATUS
+SearchChildHandle(
+  EFI_HANDLE Father,
+  EFI_HANDLE *Child
+  )
+{
+  EFI_STATUS                                                 Status;
+  UINTN                                                          HandleIndex;
+  EFI_GUID                                                     **ProtocolGuidArray = NULL;
+  UINTN                                                          ArrayCount;
+  UINTN                                                          ProtocolIndex;
+  UINTN                                                          OpenInfoCount;
+  UINTN                                                          OpenInfoIndex;
+  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY  *OpenInfo = NULL;
+  UINTN                                                          mHandleCount;
+  EFI_HANDLE                                                 *mHandleBuffer= NULL;
+
+  //
+  // Retrieve the list of all handles from the handle database
+  //
+  Status = gBS->LocateHandleBuffer (
+                  AllHandles,
+                  NULL,
+                  NULL,
+                  &mHandleCount,
+                  &mHandleBuffer
+                  );
+
+  for (HandleIndex = 0; HandleIndex < mHandleCount; HandleIndex++)
+  {
+    //
+    // Retrieve the list of all the protocols on each handle
+    //
+    Status = gBS->ProtocolsPerHandle (
+                    mHandleBuffer[HandleIndex],
+                    &ProtocolGuidArray,
+                    &ArrayCount
+                    );
+    if (!EFI_ERROR (Status))
+    {
+      for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++)
+      {
+        Status = gBS->OpenProtocolInformation (
+                        mHandleBuffer[HandleIndex],
+                        ProtocolGuidArray[ProtocolIndex],
+                        &OpenInfo,
+                        &OpenInfoCount
+                        );
+        if (!EFI_ERROR (Status))
+        {
+          for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++)
+          {
+            if(OpenInfo[OpenInfoIndex].AgentHandle == Father)
+            {
+              if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER)
+              {
+                *Child = mHandleBuffer[HandleIndex];
+		  Status = EFI_SUCCESS;
+		  goto TryReturn;
+              }
+            }
+          }
+	   Status = EFI_NOT_FOUND;
+        }
+      }
+      if(OpenInfo != NULL)
+      {
+        FreePool(OpenInfo);
+	 OpenInfo = NULL;
+      }
+    }
+    FreePool (ProtocolGuidArray);
+    ProtocolGuidArray = NULL;
+  }
+TryReturn:
+  if(OpenInfo != NULL)
+  {
+    FreePool (OpenInfo);
+    OpenInfo = NULL;
+  }
+  if(ProtocolGuidArray != NULL)
+  {
+    FreePool(ProtocolGuidArray);
+    ProtocolGuidArray = NULL;
+  }
+  if(mHandleBuffer != NULL)
+  {
+    FreePool (mHandleBuffer);
+    mHandleBuffer = NULL;
+  }
+  return Status;
+}
+
+EFI_STATUS
+JudgeHandleIsPCIDevice(
+  EFI_HANDLE    Handle,
+  UINT8            Device,
+  UINT8            Funs
+  )
+{
+  EFI_STATUS  Status;
+  EFI_DEVICE_PATH   *DPath;
+
+  Status = gBS->HandleProtocol (
+                  Handle,
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID **) &DPath
+                  );
+  if(!EFI_ERROR(Status))
+  {
+    while(!IsDevicePathEnd(DPath))
+    {
+      if((DPath->Type == HARDWARE_DEVICE_PATH) && (DPath->SubType == HW_PCI_DP))
+      {
+        PCI_DEVICE_PATH   *PCIPath;
+
+        PCIPath = (PCI_DEVICE_PATH*) DPath;
+        DPath = NextDevicePathNode(DPath);
+        if(IsDevicePathEnd(DPath) && (PCIPath->Device == Device) && (PCIPath->Function == Funs))
+        {
+          return EFI_SUCCESS;
+        }
+      }
+      else
+      {
+        DPath = NextDevicePathNode(DPath);
+      }
+    }
+  }
+  return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+GetDriverName(
+  EFI_HANDLE   Handle,
+  CHAR16         *Name
+  )
+{
+  EFI_DRIVER_BINDING_PROTOCOL        *BindHandle = NULL;
+  EFI_STATUS                                        Status;
+  UINT32                                               Version;
+  UINT16                                               *Ptr;
+  Status = gBS->OpenProtocol(
+                  Handle,
+                  &gEfiDriverBindingProtocolGuid,
+                  (VOID**)&BindHandle,
+                  NULL,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+
+  if (EFI_ERROR(Status))
+  {
+    return EFI_NOT_FOUND;
+  }
+
+  Version = BindHandle->Version;
+  Ptr = (UINT16*)&Version;
+  UnicodeSPrint(Name, 40, L"%d.%d.%d", Version >> 24 , (Version >>16)& 0x0f ,*(Ptr));
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetGOPDriverName(
+  CHAR16 *Name
+  )
+{
+  UINTN                         HandleCount;
+  EFI_HANDLE                *Handles= NULL;
+  UINTN                         Index;
+  EFI_STATUS                Status;
+  EFI_HANDLE                Child = 0;
+
+  Status = gBS->LocateHandleBuffer(
+		              ByProtocol,
+		              &gEfiDriverBindingProtocolGuid,
+		              NULL,
+		              &HandleCount,
+		              &Handles
+                  );
+  for (Index = 0; Index < HandleCount ; Index++)
+  {
+    Status = SearchChildHandle(Handles[Index], &Child);
+    if(!EFI_ERROR(Status))
+    {
+      Status = JudgeHandleIsPCIDevice(
+                 Child,
+                 0x02,
+                 0x00
+                 );
+      if(!EFI_ERROR(Status))
+      {
+        return GetDriverName(Handles[Index], Name);
+      }
+    }
+  }
+  return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+UpdatePlatformInformation (
+  )
+{
+  UINT32                   MicroCodeVersion;
+  CHAR16                   Buffer[40];
+  UINT8                    IgdVBIOSRevH;
+  UINT8                    IgdVBIOSRevL;
+  UINT16                   EDX;
+  EFI_IA32_REGISTER_SET    RegSet;
+  EFI_LEGACY_BIOS_PROTOCOL *LegacyBios = NULL;
+  EFI_STATUS               Status;
+  UINT8                    CpuFlavor=0;
+  EFI_PEI_HOB_POINTERS     GuidHob;
+  UINTN                    NumHandles;
+  EFI_HANDLE                        *HandleBuffer;
+  UINTN                             Index;
+  DXE_PCH_PLATFORM_POLICY_PROTOCOL  *PchPlatformPolicy;
+  UINTN                             PciD31F0RegBase;
+  UINT8                             count;
+  UINT8                             Data8;
+  UINT8                             PIDData8;
+
+  CHAR16                            Name[40];
+  UINT32                            MrcVersion;
+
+  //
+  // 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);
+    }
+  }
+
+  //
+  //VBIOS version
+  //
+  Status = gBS->LocateProtocol(
+                  &gEfiLegacyBiosProtocolGuid,
+                  NULL,
+                  (void **)&LegacyBios
+                  );
+  if (!EFI_ERROR (Status)) {
+  RegSet.X.AX = 0x5f01;
+  Status = LegacyBios->Int86 (LegacyBios, 0x10, &RegSet);
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  // simulate AMI int15 (ax=5f01) handler
+  // check NbInt15.asm in AMI code for asm edition
+  //
+  EDX = (UINT16)((RegSet.E.EBX >> 16) & 0xffff);
+  IgdVBIOSRevH = (UINT8)(((EDX & 0x0F00) >> 4) | (EDX & 0x000F));
+  IgdVBIOSRevL = (UINT8)(((RegSet.X.BX & 0x0F00) >> 4) | (RegSet.X.BX & 0x000F));
+
+  if (IgdVBIOSRevH==0 && IgdVBIOSRevL==0){
+    HiiSetString(mHiiHandle, STRING_TOKEN(STR_CHIP_IGD_VBIOS_REV_VALUE), L"N/A", NULL);
+  } else {
+    UnicodeSPrint (Buffer, sizeof (Buffer), L"%02X%02X", IgdVBIOSRevH,IgdVBIOSRevL);
+    HiiSetString(mHiiHandle, STRING_TOKEN(STR_CHIP_IGD_VBIOS_REV_VALUE), Buffer, NULL);
+    }
+  }
+
+  Status = GetGOPDriverName(Name);
+
+  if (!EFI_ERROR(Status))
+  {
+    HiiSetString(mHiiHandle, STRING_TOKEN(STR_GOP_VALUE), Name, NULL);
+  }
+
+
+  //
+  // CpuFlavor
+  // ISG-DC Tablet        000
+  // VLV-QC Tablet        001
+  // VLV-QC Desktop       010
+  // VLV-QC Notebook      011
+  //
+  CpuFlavor = RShiftU64 (EfiReadMsr (MSR_IA32_PLATFORM_ID), 50) & 0x07;
+
+  switch(CpuFlavor){
+    case 0x0:
+      UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-DC Tablet", CpuFlavor);
+      break;
+    case 0x01:
+      UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC Notebook", CpuFlavor);
+      break;
+    case 0x02:
+      UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC Desktop", CpuFlavor);
+      break;
+    case 0x03:
+      UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC Notebook", CpuFlavor);
+      break;
+    default:
+      UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"Unknown CPU", CpuFlavor);
+      break;
+  }
+  HiiSetString(mHiiHandle,STRING_TOKEN(STR_CPU_FLAVOR_VALUE), Buffer, NULL);
+
+  if ( NULL != mPlatformInfo) {
+    //
+    //BoardId
+    //
+    switch(mPlatformInfo->BoardId){
+      case 0x2:
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"BAY LAKE RVP(%02x)", mPlatformInfo->BoardId);
+        break;
+
+      case 0x4:
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"BAY LAKE FFRD(%02x)", mPlatformInfo->BoardId);
+        break;
+
+      case 0x5:
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"BAY ROCK RVP DDR3L (%02x)", mPlatformInfo->BoardId);
+        break;
+
+      case 0x20:
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"BAYLEY BAY (%02x)", mPlatformInfo->BoardId);
+        break;
+
+      case 0x30:
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"BAKER SPORT (%02x)", mPlatformInfo->BoardId);
+        break;
+
+      case 0x0:
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"ALPINE VALLEY (%x)", mPlatformInfo->BoardId);
+        break;
+
+      case 0x3:
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"BAY LAKE FFD8 (%x)", mPlatformInfo->BoardId);
+        break;
+
+      default:
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"Unknown BOARD (%02x)", mPlatformInfo->BoardId);
+        break;
+    }
+    HiiSetString(mHiiHandle,STRING_TOKEN(STR_BOARD_ID_VALUE), Buffer, NULL);
+
+
+    //
+    // Get Board FAB ID Info from protocol, update into the NVS area.
+    // bit0~bit3 are for Fab ID, 0x0F means unknow FAB.
+    //
+    if(mPlatformInfo->BoardRev == 0x0F) {
+      UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", L"Unknown FAB");
+      HiiSetString(mHiiHandle,STRING_TOKEN(STR_FAB_ID_VALUE), Buffer, NULL);
+    } else {
+      UnicodeSPrint (Buffer, sizeof (Buffer), L"%2x", mPlatformInfo->BoardRev);
+      HiiSetString(mHiiHandle,STRING_TOKEN(STR_FAB_ID_VALUE), Buffer, NULL);
+    }
+  }
+
+  //
+  //Update MRC Version
+  //
+  MrcVersion = 0x00000000;
+  MrcVersion &= 0xffff;
+  Index = EfiValueToString (Buffer, MrcVersion/100, PREFIX_ZERO, 0);
+  StrCat (Buffer, L".");
+  EfiValueToString (Buffer + Index + 1, (MrcVersion%100)/10, PREFIX_ZERO, 0);
+  EfiValueToString (Buffer + Index + 2, (MrcVersion%100)%10, PREFIX_ZERO, 0);
+  HiiSetString(mHiiHandle,STRING_TOKEN(STR_MRC_VERSION_VALUE), Buffer, NULL);
+
+  //
+  //Update Soc Version
+  //
+
+  //
+  // Retrieve all instances of PCH Platform Policy protocol
+  //
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gDxePchPlatformPolicyProtocolGuid,
+                  NULL,
+                  &NumHandles,
+                  &HandleBuffer
+                  );
+  if (!EFI_ERROR (Status)) {
+    //
+    // Find the matching PCH Policy protocol
+    //
+    for (Index = 0; Index < NumHandles; Index++) {
+      Status = gBS->HandleProtocol (
+                      HandleBuffer[Index],
+                      &gDxePchPlatformPolicyProtocolGuid,
+                      (void **)&PchPlatformPolicy
+                      );
+      if (!EFI_ERROR (Status)) {
+        PciD31F0RegBase = MmPciAddress (
+                            0,
+                            PchPlatformPolicy->BusNumber,
+                            PCI_DEVICE_NUMBER_PCH_LPC,
+                            PCI_FUNCTION_NUMBER_PCH_LPC,
+                            0
+                            );
+
+         Data8 = MmioRead8 (PciD31F0RegBase + R_PCH_LPC_RID_CC);
+         count = ARRAY_SIZE (SBRevisionTable);
+         for (Index = 0; Index < count; Index++) {
+           if(Data8 == SBRevisionTable[Index].RevId) {
+              UnicodeSPrint (Buffer, sizeof (Buffer), L"%02x %a", Data8, SBRevisionTable[Index].String);
+              HiiSetString(mHiiHandle,STRING_TOKEN(STR_SOC_VALUE), Buffer, NULL);
+             break;
+           }
+         }
+        break;
+      }
+    }
+  }
+
+  //
+  // Microcode Revision
+  //
+  EfiWriteMsr (EFI_MSR_IA32_BIOS_SIGN_ID, 0);
+  EfiCpuid (EFI_CPUID_VERSION_INFO, NULL);
+  MicroCodeVersion = (UINT32) RShiftU64 (EfiReadMsr (EFI_MSR_IA32_BIOS_SIGN_ID), 32);
+  UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", MicroCodeVersion);
+  HiiSetString(mHiiHandle,STRING_TOKEN(STR_PROCESSOR_MICROCODE_VALUE), Buffer, NULL);
+
+  //
+  // Punit Version
+  //
+  Data8 = 0;
+  UnicodeSPrint (Buffer, sizeof (Buffer), L"0x%x", Data8);
+  HiiSetString(mHiiHandle,STRING_TOKEN(STR_PUNIT_FW_VALUE), Buffer, NULL);
+
+  //
+  //  PMC Version
+  //
+  Data8 = (UINT8)((MmioRead32 (PMC_BASE_ADDRESS + R_PCH_PMC_PRSTS)>>16)&0x00FF);
+  PIDData8 = (UINT8)((MmioRead32 (PMC_BASE_ADDRESS + R_PCH_PMC_PRSTS)>>24)&0x00FF);
+  UnicodeSPrint (Buffer, sizeof (Buffer), L"0x%X_%X",PIDData8, Data8);
+  HiiSetString(mHiiHandle,STRING_TOKEN(STR_PMC_FW_VALUE), Buffer, NULL);
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Update SATA Drivesize Strings for Setup and Boot order
+
+  @param NewString - pointer to string.
+  @param DeviceSpeed - speed of drive.
+
+**/
+VOID
+GetDeviceSpeedString (
+  CHAR16                      *NewString,
+  IN UINTN                    DeviceSpeed
+  )
+{
+  if (DeviceSpeed == 0x01) {
+    StrCat (NewString, L"1.5Gb/s");
+  } else if (DeviceSpeed == 0x02) {
+    StrCat (NewString, L"3.0Gb/s");
+  } else if (DeviceSpeed == 0x03) {
+    StrCat (NewString, L"6.0Gb/s");
+  } else if (DeviceSpeed == 0x0) {
+
+  }
+}
+
+UINT8
+GetChipsetSataPortSpeed (
+  UINTN PortNum
+  )
+{
+  UINT32                      DeviceSpeed;
+  UINT8                       DeviceConfigStatus;
+  UINT32                      IdeAhciBar;
+  EFI_PHYSICAL_ADDRESS        MemBaseAddress = 0;
+  UINT8                       FunNum;
+
+  DeviceSpeed = 0x01; // generation 1
+
+
+  //
+  // Allocate the AHCI BAR
+  //
+    FunNum = PCI_FUNCTION_NUMBER_PCH_SATA;
+    MemBaseAddress = 0x0ffffffff;
+    gDS->AllocateMemorySpace (
+           EfiGcdAllocateMaxAddressSearchBottomUp,
+           EfiGcdMemoryTypeMemoryMappedIo,
+           N_PCH_SATA_ABAR_ALIGNMENT,  // 2^11: 2K Alignment
+           V_PCH_SATA_ABAR_LENGTH,     // 2K Length
+           &MemBaseAddress,
+           mImageHandle,
+           NULL
+           );
+    IdeAhciBar = MmioRead32 (
+                   MmPciAddress (
+				     0,
+                     0,
+                     PCI_DEVICE_NUMBER_PCH_SATA,
+                     FunNum,
+                     R_PCH_SATA_ABAR
+                     )
+                   );
+    IdeAhciBar &= 0xFFFFF800;
+    DeviceConfigStatus = 0;
+    if (IdeAhciBar == 0) {
+      DeviceConfigStatus = 1;
+      IdeAhciBar = (UINT32)MemBaseAddress;
+      MmioWrite32 (
+        MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_SATA, FunNum, R_PCH_SATA_ABAR),
+        IdeAhciBar
+        );
+      MmioOr16 (
+        MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_SATA, FunNum, R_PCH_SATA_COMMAND),
+        B_PCH_SATA_COMMAND_MSE
+        );
+    }
+
+    if (mSystemConfiguration.SataType == PCH_SATA_MODE_IDE){
+      //
+      // Program the "Ports Implemented Register"
+      //
+      MmioAndThenOr32 (IdeAhciBar + R_PCH_SATA_AHCI_PI, (UINT32)~(B_PCH_SATA_PORT0_IMPLEMENTED + B_PCH_SATA_PORT1_IMPLEMENTED), (UINT32)(B_PCH_SATA_PORT0_IMPLEMENTED + B_PCH_SATA_PORT1_IMPLEMENTED));
+    }
+
+    switch (PortNum)
+    {
+      case 0:
+        DeviceSpeed = *(volatile UINT32 *)(UINTN)(IdeAhciBar + R_PCH_SATA_AHCI_P0SSTS);
+        break;
+      case 1:
+        DeviceSpeed = *(volatile UINT32 *)(UINTN)(IdeAhciBar + R_PCH_SATA_AHCI_P1SSTS);
+        break;
+    }
+
+    if (MemBaseAddress) {
+      gDS->FreeMemorySpace (
+             MemBaseAddress,
+             V_PCH_SATA_ABAR_LENGTH
+             );
+    }
+
+  if (DeviceConfigStatus) {
+    IdeAhciBar = 0;
+    MmioWrite32 (
+      MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_SATA, FunNum, R_PCH_SATA_ABAR),
+      IdeAhciBar
+      );
+  }
+
+  DeviceSpeed = (UINT8)((DeviceSpeed >> 4) & 0x0F);
+
+  return (UINT8)DeviceSpeed;
+}
+
+/**
+
+  IDE data filter function.
+
+**/
+void
+IdeDataFilter (void)
+{
+  EFI_STATUS                  Status;
+  UINTN                       HandleCount;
+  EFI_HANDLE                  *HandleBuffer;
+  EFI_DISK_INFO_PROTOCOL      *DiskInfo;
+  EFI_DEVICE_PATH_PROTOCOL    *DevicePath, *DevicePathNode;
+  PCI_DEVICE_PATH             *PciDevicePath;
+  UINTN                       Index;
+  UINT8                       Index1;
+  UINT32                      BufferSize;
+  UINT32                      DriveSize;
+  UINT32                      IdeChannel;
+  UINT32                      IdeDevice;
+  EFI_ATA_IDENTIFY_DATA       *IdentifyDriveInfo;
+  CHAR16                      *NewString;
+  CHAR16                      SizeString[20];
+  STRING_REF                  NameToUpdate;
+  CHAR8                       StringBuffer[0x100];
+  UINT32                      DeviceSpeed;
+  UINTN                       PortNumber;
+
+  //
+  // Assume no line strings is longer than 256 bytes.
+  //
+  NewString = AllocateZeroPool (0x100);
+  PciDevicePath = NULL;
+
+  //
+  // Fill IDE Infomation
+  //
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiDiskInfoProtocolGuid,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer
+				  );
+
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  for (Index = 0; Index < HandleCount; Index++) {
+
+    Status = gBS->HandleProtocol (
+                    HandleBuffer[Index],
+                    &gEfiDevicePathProtocolGuid,
+                    (VOID*)&DevicePath
+				    );
+    ASSERT_EFI_ERROR (Status);
+
+    DevicePathNode = DevicePath;
+    while (!IsDevicePathEnd (DevicePathNode) ) {
+      if  ((DevicePathType (DevicePathNode) == HARDWARE_DEVICE_PATH) &&
+           ( DevicePathSubType (DevicePathNode) == HW_PCI_DP)) {
+        PciDevicePath = (PCI_DEVICE_PATH *) DevicePathNode;
+        break;
+      }
+      DevicePathNode    = NextDevicePathNode (DevicePathNode);
+    }
+
+    if (PciDevicePath == NULL) {
+      continue;
+    }
+
+    //
+    // Check for onboard IDE
+    //
+    if (PciDevicePath->Device== PCI_DEVICE_NUMBER_PCH_SATA) {
+      Status = gBS->HandleProtocol (
+	                  HandleBuffer[Index],
+					  &gEfiDiskInfoProtocolGuid,
+					  (void **)&DiskInfo
+					  );
+      ASSERT_EFI_ERROR (Status);
+
+      Status = DiskInfo->WhichIde (
+	                       DiskInfo,
+                           &IdeChannel,
+                           &IdeDevice
+						   );
+      ASSERT_EFI_ERROR (Status);
+
+      IdentifyDriveInfo = AllocatePool (sizeof(EFI_ATA_IDENTIFY_DATA));
+
+      BufferSize = sizeof(EFI_ATA_IDENTIFY_DATA);
+      Status = DiskInfo->Identify (
+	                       DiskInfo,
+                           IdentifyDriveInfo,
+                           &BufferSize
+                           );
+      ASSERT_EFI_ERROR(Status);
+
+      //
+      // Onboard SATA Devices
+      //
+      if (PciDevicePath->Function == PCI_FUNCTION_NUMBER_PCH_SATA) {
+        if (IdeChannel == 0 && IdeDevice == 0) {
+          NameToUpdate = (STRING_REF)STR_SATA0_NAME;
+        } else if (IdeChannel == 1 && IdeDevice == 0) {
+          NameToUpdate = (STRING_REF)STR_SATA1_NAME;
+        } else {
+          continue;
+        }
+      } else {
+        continue;
+      }
+
+      ZeroMem(StringBuffer, sizeof(StringBuffer));
+      CopyMem(
+        StringBuffer,
+        (CHAR8 *)&IdentifyDriveInfo->ModelName,
+        sizeof(IdentifyDriveInfo->ModelName)
+        );
+      SwapEntries(StringBuffer);
+      AsciiToUnicode(StringBuffer, NewString);
+
+	  //
+      // Chap it off after 16 characters
+	  //
+      NewString[16] = 0;
+
+      //
+      // For HardDisk append the size. Otherwise display atapi
+      //
+      if ((IdentifyDriveInfo->config & 0x8000) == 00) {
+        //
+        // 48 bit address feature set is supported, get maximum capacity
+        //
+        if ((IdentifyDriveInfo->command_set_supported_83 & 0x0400) == 0) {
+        DriveSize = (((((IdentifyDriveInfo->user_addressable_sectors_hi << 16) +
+                      IdentifyDriveInfo->user_addressable_sectors_lo) / 1000) * 512) / 1000);
+        } else {
+          DriveSize    = IdentifyDriveInfo->maximum_lba_for_48bit_addressing[0];
+          for (Index1 = 1; Index1 < 4; Index1++) {
+            //
+            // Lower byte goes first: word[100] is the lowest word, word[103] is highest
+            //
+            DriveSize |= LShiftU64(IdentifyDriveInfo->maximum_lba_for_48bit_addressing[Index1], 16 * Index1);
+          }
+          DriveSize = (UINT32) DivU64x32(MultU64x32(DivU64x32(DriveSize, 1000), 512), 1000);
+        }
+
+        StrCat (NewString, L"(");
+        EfiValueToString (SizeString, DriveSize/1000, PREFIX_BLANK, 0);
+        StrCat (NewString, SizeString);
+        StrCat (NewString, L".");
+        EfiValueToString (SizeString, (DriveSize%1000)/100, PREFIX_BLANK, 0);
+        StrCat (NewString, SizeString);
+        StrCat (NewString, L"GB");
+      } else {
+        StrCat (NewString, L"(ATAPI");
+      }
+
+      //
+      // Update SPEED.
+      //
+      PortNumber = (IdeDevice << 1) + IdeChannel;
+      DeviceSpeed = GetChipsetSataPortSpeed(PortNumber);
+
+      if (DeviceSpeed) {
+        StrCat (NewString, L"-");
+        GetDeviceSpeedString( NewString, DeviceSpeed);
+      }
+
+      StrCat (NewString, L")");
+
+      HiiSetString(mHiiHandle, NameToUpdate, NewString, NULL);
+
+    }
+  }
+
+  if (HandleBuffer != NULL) {
+    gBS->FreePool (HandleBuffer);
+  }
+
+  gBS->FreePool(NewString);
+
+  return;
+}
+
+
+VOID
+EFIAPI
+SetupInfo (void)
+{
+  EFI_STATUS                  Status;
+  UINTN                       VarSize;
+  EFI_PEI_HOB_POINTERS        GuidHob;
+
+  if (mSetupInfoDone) {
+      return;
+  }
+
+  VarSize = sizeof(SYSTEM_CONFIGURATION);
+  Status = gRT->GetVariable(
+                  NORMAL_SETUP_NAME,
+                  &gEfiNormalSetupGuid,
+                  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",
+              &gEfiNormalSetupGuid,
+              NULL,
+              &VarSize,
+              &mSystemConfiguration
+              );
+    ASSERT_EFI_ERROR (Status);
+  }  
+
+  //
+  // 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);
+    }
+  }
+
+
+  PrepareSetupInformation();
+  UpdateAdditionalInformation ();
+  UpdatePlatformInformation();
+  UpdateCPUInformation();
+  IdeDataFilter();
+  mSetupInfoDone = TRUE;
+
+  return;
+}
+
+
+#define EFI_SECURE_BOOT_MODE_NAME                   L"SecureBoot"
+
+VOID
+CheckSystemConfigLoad(SYSTEM_CONFIGURATION *SystemConfigPtr)
+{
+  EFI_STATUS              Status;
+  UINT8                   SecureBoot;
+  UINTN                   DataSize;
+
+
+  DataSize = sizeof(SecureBoot);
+  Status = gRT->GetVariable (
+                  EFI_SECURE_BOOT_MODE_NAME,
+                  &gEfiGlobalVariableGuid,
+                  NULL,
+                  &DataSize,
+                  &SecureBoot
+                  );
+
+  if (EFI_ERROR(Status)) {
+    SystemConfigPtr->SecureBoot = 0;
+  } else {
+    SystemConfigPtr->SecureBoot = SecureBoot;
+  }
+}
+
+
+//
+// "SecureBootEnable" variable for the Secure boot feature enable/disable.
+//
+#define EFI_SECURE_BOOT_ENABLE_NAME      L"SecureBootEnable"
+extern EFI_GUID gEfiSecureBootEnableDisableGuid;
+
+
+VOID
+CheckSystemConfigSave(SYSTEM_CONFIGURATION *SystemConfigPtr)
+{
+  EFI_STATUS              Status;
+  UINT8                   SecureBootCfg;
+  BOOLEAN                 SecureBootNotFound;
+  UINTN                   DataSize;
+
+
+    //
+    // Secure Boot configuration changes
+	//
+    DataSize = sizeof(SecureBootCfg);
+    SecureBootNotFound = FALSE;
+    Status = gRT->GetVariable (
+                    EFI_SECURE_BOOT_ENABLE_NAME,
+                    &gEfiSecureBootEnableDisableGuid,
+                    NULL,
+                    &DataSize,
+                    &SecureBootCfg
+                    );
+
+    if (EFI_ERROR(Status)) {
+      SecureBootNotFound = TRUE;
+    }
+    if (SecureBootNotFound) {
+      Status = gRT->GetVariable (
+                      EFI_SECURE_BOOT_ENABLE_NAME,
+                      &gEfiSecureBootEnableDisableGuid,
+                      NULL,
+                      &DataSize,
+                      &SecureBootCfg
+                      );
+      ASSERT_EFI_ERROR(Status);
+    }
+    if ((SecureBootCfg) != SystemConfigPtr->SecureBoot) {
+      SecureBootCfg = !SecureBootCfg;
+      Status = gRT->SetVariable (
+                      EFI_SECURE_BOOT_ENABLE_NAME,
+                      &gEfiSecureBootEnableDisableGuid,
+                      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                      sizeof (UINT8),
+                      &SecureBootCfg
+                      );
+    }
+
+}
+
+VOID
+ConfirmSecureBootTest()
+{
+
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SouthClusterConfig.vfi b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SouthClusterConfig.vfi
new file mode 100644
index 0000000000..f7ed978c8b
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SouthClusterConfig.vfi
@@ -0,0 +1,933 @@
+// /** @file
+//
+// Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
+//
+
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+
+//
+
+//
+//
+//
+// Module Name:
+//
+//   SourthClusterConfig.vfi
+//
+// Abstract:
+//
+//   Driver Setup formset.
+//
+//Revision History:
+//  ------------------------------------------------------------------------------
+//  Rev   Date<MM/DD/YYYY>    Name    Description
+//  ------------------------------------------------------------------------------
+
+// **/
+
+//
+// South Cluster Configuration Form
+//
+
+form formid = SOUTH_CLUSTER_FORM_ID,
+  title    = STRING_TOKEN(STR_SOUTH_CLUSTER_TITLE);
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+
+  //
+  // Jump to PCIe Configuration Form
+  //
+  goto PCIE_DEVICE_OPTIONS_FORM_ID,
+    prompt = STRING_TOKEN(STR_PCIE_OPTIONS_FORM_TITLE),
+    help = STRING_TOKEN(STR_PCIE_OPTIONS_FORM_HELP);
+
+  //
+  // Jump to USB Configuration Form
+  //
+  goto USB_OPTIONS_FORM_ID,
+    prompt = STRING_TOKEN(STR_USB_OPTIONS_FORM_TITLE),
+    help = STRING_TOKEN(STR_USB_OPTIONS_FORM_HELP);
+  //
+  // Jump to Azalia Configuration Form
+  //
+  goto AZALIA_OPTIONS_FORM_ID,
+    prompt = STRING_TOKEN(STR_AZALIA_OPTIONS_FORM_TITLE),
+    help   = STRING_TOKEN(STR_AZALIA_OPTIONS_FORM_HELP);
+
+  //
+  // Jump to Drive Configuration Form
+  //
+  goto DRIVE_CONFIGURATION_ID,
+    prompt = STRING_TOKEN(STR_IDE_FORM_TITLE),
+    help   = STRING_TOKEN(STR_IDE_FORM_HELP);
+  //
+  // Jump to LAN Configuration Form
+  //
+
+  //
+  // Jump to LPSS Configuration Form
+  //
+  goto LPSS_CONFIGURATION_ID,
+    prompt = STRING_TOKEN(STR_LPSS_SCC_FORM_TITLE),
+    help   = STRING_TOKEN(STR_LPSS_SCC_FORM_HELP);
+
+  //
+  // Jump to Misc Configuration Form
+  //
+  goto MISC_OPTIONS_FORM_ID,
+    prompt = STRING_TOKEN(STR_MISC_OPTION_FORM_TITLE),
+    help   = STRING_TOKEN(STR_MISC_OPTION_FORM_HELP);
+endform;
+
+form formid = PCIE_DEVICE_OPTIONS_FORM_ID,
+
+  title    = STRING_TOKEN(STR_PCIE_OPTIONS_FORM_TITLE);
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+
+    oneof varid   = Setup.PcieRootPortSpeed[0],
+      prompt      = STRING_TOKEN (STR_PCIE_SPEED_PROMPT0),
+      help        = STRING_TOKEN (STR_PCIE_SPEED_HELP),
+      option text = STRING_TOKEN (STR_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+      option text = STRING_TOKEN (STR_GEN1), value = 1, flags = RESET_REQUIRED;
+      option text = STRING_TOKEN (STR_GEN2), value = 2, flags = RESET_REQUIRED;
+    endoneof;
+    oneof varid   = Setup.PcieRootPortSpeed[1],
+      prompt      = STRING_TOKEN (STR_PCIE_SPEED_PROMPT1),
+      help        = STRING_TOKEN (STR_PCIE_SPEED_HELP),
+      option text = STRING_TOKEN (STR_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+      option text = STRING_TOKEN (STR_GEN1), value = 1, flags = RESET_REQUIRED;
+      option text = STRING_TOKEN (STR_GEN2), value = 2, flags = RESET_REQUIRED;
+    endoneof;
+    oneof varid   = Setup.PcieRootPortSpeed[2],
+      prompt      = STRING_TOKEN (STR_PCIE_SPEED_PROMPT2),
+      help        = STRING_TOKEN (STR_PCIE_SPEED_HELP),
+      option text = STRING_TOKEN (STR_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+      option text = STRING_TOKEN (STR_GEN1), value = 1, flags = RESET_REQUIRED;
+      option text = STRING_TOKEN (STR_GEN2), value = 2, flags = RESET_REQUIRED;
+    endoneof;
+    oneof varid   = Setup.PcieRootPortSpeed[3],
+      prompt      = STRING_TOKEN (STR_PCIE_SPEED_PROMPT3),
+      help        = STRING_TOKEN (STR_PCIE_SPEED_HELP),
+      option text = STRING_TOKEN (STR_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+      option text = STRING_TOKEN (STR_GEN1), value = 1, flags = RESET_REQUIRED;
+      option text = STRING_TOKEN (STR_GEN2), value = 2, flags = RESET_REQUIRED;
+    endoneof;
+  //
+  //PCIe Port
+  //
+  oneof varid  = Setup.IchPciExp[0],
+    prompt   = STRING_TOKEN(STR_ICH_PCIERP1_PROMPT),
+    help     = STRING_TOKEN(STR_ICH_PCIERP_HELP),
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 | RESET_REQUIRED;
+  endoneof;
+
+  suppressif ideqval Setup.IchPciExp[0] == 0x0;
+    oneof varid    = Setup.IchPciExp[1],
+      prompt   = STRING_TOKEN(STR_ICH_PCIERP2_PROMPT),
+      help     = STRING_TOKEN(STR_ICH_PCIERP_HELP),
+      option text = STRING_TOKEN(STR_ENABLE), value=1, flags= RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_DISABLE), value=0, flags= DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    endoneof;
+  endif;
+
+  suppressif NOT ideqval Setup.IchPciExp[0] == 0x0;
+  text
+    help   = STRING_TOKEN(STR_ICH_PCIERP_HELP),
+    text   = STRING_TOKEN(STR_ICH_PCIERP2_PROMPT),
+    text   = STRING_TOKEN(STR_ICH_PCIERP_DISABLE_HELP),
+    flags  = 0,
+    key    = 0;
+  endif;
+
+  suppressif ideqval Setup.IchPciExp[0] == 0x0;
+    oneof varid    = Setup.IchPciExp[2],
+      prompt   = STRING_TOKEN(STR_ICH_PCIERP3_PROMPT),
+      help     = STRING_TOKEN(STR_ICH_PCIERP_HELP),
+      option text = STRING_TOKEN(STR_ENABLE), value=1, flags=DEFAULT | MANUFACTURING | RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 | RESET_REQUIRED;
+    endoneof;
+  endif;
+
+  suppressif NOT ideqval Setup.IchPciExp[0] == 0x0;
+  text
+    help   = STRING_TOKEN(STR_ICH_PCIERP_HELP),
+    text   = STRING_TOKEN(STR_ICH_PCIERP3_PROMPT),
+    text   = STRING_TOKEN(STR_ICH_PCIERP_DISABLE_HELP),
+    flags  = 0,
+    key    = 0;
+  endif;
+
+  suppressif ideqval Setup.IchPciExp[0] == 0x0;
+    oneof varid    = Setup.IchPciExp[3],
+      prompt   = STRING_TOKEN(STR_ICH_PCIERP4_PROMPT),
+      help     = STRING_TOKEN(STR_ICH_PCIERP_HELP),
+      option text = STRING_TOKEN(STR_ENABLE), value=1, flags= DEFAULT | MANUFACTURING | RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_DISABLE), value=0, flags= 0 | RESET_REQUIRED;
+    endoneof;
+  endif;
+
+  suppressif NOT ideqval Setup.IchPciExp[0] == 0x0;
+  text
+    help   = STRING_TOKEN(STR_ICH_PCIERP_HELP),
+    text   = STRING_TOKEN(STR_ICH_PCIERP4_PROMPT),
+    text   = STRING_TOKEN(STR_ICH_PCIERP_DISABLE_HELP),
+    flags  = 0,
+    key    = 0;
+  endif;
+
+
+endform;
+
+form formid = USB_OPTIONS_FORM_ID,
+
+  title    = STRING_TOKEN(STR_USB_OPTIONS_FORM_TITLE);
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+
+  oneof   varid   = Setup.UsbAutoMode,
+    questionid  = 0x123A,
+    prompt      = STRING_TOKEN(STR_USB_AUTO_MODE_PROMPT),
+    help        = STRING_TOKEN(STR_USB_AUTO_MODE_HELP),
+    flags       = INTERACTIVE,
+    option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =  RESET_REQUIRED;
+  endoneof;
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+  //
+  //XHCI support
+  //
+  grayoutif ideqval Setup.UsbAutoMode == 0x1;
+    grayoutif ideqval Setup.PchUsb20 == 0x1;
+      oneof   varid   = Setup.UsbXhciSupport,
+        questionid  = 0x123B,
+        prompt      = STRING_TOKEN(STR_USB_XHCI_SUPPORT_PROMPT),
+        help        = STRING_TOKEN(STR_USB_XHCI_SUPPORT_HELP),
+        flags       = INTERACTIVE,
+        option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+        option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =  RESET_REQUIRED;
+      endoneof;
+
+      suppressif ideqval Setup.UsbXhciSupport == 0x0;
+        oneof   varid   = Setup.Hsic0,
+          prompt      = STRING_TOKEN(STR_USB_HSIC_0_PROMPT),
+          help        = STRING_TOKEN(STR_USB_HSIC_0_HELP),
+          option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = RESET_REQUIRED;
+          option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+        endoneof;
+      endif;
+
+      oneof varid   = Setup.PchUsb30Mode,
+        prompt      = STRING_TOKEN(STR_PCH_USB30_MODE_PROMPT),
+        help        = STRING_TOKEN(STR_PCH_USB30_MODE_HELP),
+        option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT | MANUFACTURING |RESET_REQUIRED;
+        option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =  RESET_REQUIRED;
+      endoneof;
+
+  oneof   varid   = Setup.UsbXhciLpmSupport,
+        prompt      = STRING_TOKEN(STR_USB_XHCI_LPM_SUPPORT_PROMPT),
+        help        = STRING_TOKEN(STR_USB_XHCI_LPM_SUPPORT_HELP),
+
+        option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+        option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+
+      endoneof;
+    endif;
+  endif;
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+
+  oneof varid   = Setup.PchUsbOtg,
+    prompt      = STRING_TOKEN(STR_PCH_USB_OTG_PROMPT),
+    help        = STRING_TOKEN(STR_PCH_USB_OTG_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT | MANUFACTURING |RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_PCI_MODE_STRING), value = 1, flags =  RESET_REQUIRED;
+  endoneof;
+
+  oneof varid   = Setup.PchUsbVbusOn,
+    prompt      = STRING_TOKEN(STR_PCH_USB_VBUS_PROMPT),
+    help        = STRING_TOKEN(STR_PCH_USB_VBUS_HELP),
+    option text = STRING_TOKEN(STR_OFF), value = 0, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ON), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_AUTO), value = 2, flags = RESET_REQUIRED;
+  endoneof;
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+
+  //
+  //EHCI support
+  //
+  grayoutif ideqval Setup.UsbAutoMode == 0x1;
+    grayoutif ideqval Setup.UsbXhciSupport == 0x1;
+      oneof   varid   = Setup.PchUsb20,
+        questionid  = 0x123C,
+        prompt   = STRING_TOKEN(STR_PCH_USB21_PROMPT),
+        help     = STRING_TOKEN(STR_PCH_USB2_HELP),
+        flags    = INTERACTIVE,
+        option text = STRING_TOKEN(STR_ENABLE), value = 1, flags =  RESET_REQUIRED;
+        option text = STRING_TOKEN(STR_DISABLE), value= 0, flags= DEFAULT | MANUFACTURING |RESET_REQUIRED;
+      endoneof;
+
+      oneof varid  = Setup.PchUsbRmh,
+        prompt   = STRING_TOKEN(STR_PCH_USBRMH_PROMPT),
+        help     = STRING_TOKEN(STR_PCH_USBRMH_HELP),
+        option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+        option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+      endoneof;
+
+      oneof varid  = Setup.PchEhciDebug,
+        prompt   = STRING_TOKEN(STR_PCH_USB_EHCIDEBUG_PROMPT),
+        help     = STRING_TOKEN(STR_PCH_USB_EHCIDEBUG_HELP),
+        option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+        option text = STRING_TOKEN(STR_ENABLE),  value = 1, flags = RESET_REQUIRED;
+      endoneof;
+
+      suppressif TRUE;
+        oneof varid   = Setup.EhciPllCfgEnable,
+        prompt      = STRING_TOKEN(STR_EHCI_PLL_CFG_PROMPT),
+        help        = STRING_TOKEN(STR_EHCI_PLL_CFG_RTD3_DIS_HELP),
+        option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+        option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+        endoneof;
+      endif;
+    endif;
+
+    //
+    // Usb ports per-port disable control enable
+    //
+    oneof varid   = Setup.PchUsbPerPortCtl,
+      prompt      = STRING_TOKEN(STR_PCH_USB_PER_PORT_PROMPT),
+      help        = STRING_TOKEN(STR_PCH_USB_PER_PORT_HELP),
+      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    endoneof;
+
+    suppressif ideqval Setup.PchUsbPerPortCtl == 0x0;
+      oneof varid  = Setup.PchUsbPort[0],
+      prompt   = STRING_TOKEN(STR_PCH_USB_PORT0_PROMPT),
+      help     = STRING_TOKEN(STR_PCH_USB_PORT_DIS_HELP),
+      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+      endoneof;
+
+      oneof varid  = Setup.PchUsbPort[1],
+      prompt   = STRING_TOKEN(STR_PCH_USB_PORT1_PROMPT),
+      help     = STRING_TOKEN(STR_PCH_USB_PORT_DIS_HELP),
+      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+      endoneof;
+
+      oneof varid  = Setup.PchUsbPort[2],
+      prompt   = STRING_TOKEN(STR_PCH_USB_PORT2_PROMPT),
+      help     = STRING_TOKEN(STR_PCH_USB_PORT_DIS_HELP),
+      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+      endoneof;
+
+      oneof varid  = Setup.PchUsbPort[3],
+      prompt   = STRING_TOKEN(STR_PCH_USB_PORT3_PROMPT),
+      help     = STRING_TOKEN(STR_PCH_USB_PORT_DIS_HELP),
+      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+      endoneof;
+    endif;
+
+
+  endif;
+
+endform;
+
+//
+// SATA Controller
+//
+form formid = DRIVE_CONFIGURATION_ID,
+
+  title    = STRING_TOKEN(STR_IDE_FORM_TITLE);
+
+  //
+  // Title on Drive Configuration Page
+  //
+  text
+    help   = STRING_TOKEN(STR_NULL_STRING),
+    text   = STRING_TOKEN(STR_IDE_FORM_TITLE),
+    text   = STRING_TOKEN(STR_NULL_STRING),
+    flags  = 0,
+    key    = 0;
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+
+  subtitle text = STRING_TOKEN(STR_CHIPSET_SATA_STRING);
+
+  oneof varid   = Setup.Sata,
+    prompt      = STRING_TOKEN(STR_SATA_PROMPT),
+    help        = STRING_TOKEN(STR_SATA_HELP),
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 | RESET_REQUIRED;
+  endoneof;
+
+    oneof varid   = Setup.SataTestMode,
+      prompt      = STRING_TOKEN(STR_SATA_TEST_MODE_PROMPT),
+      help        = STRING_TOKEN(STR_SATA_TEST_MODE_HELP),
+      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    endoneof;
+
+  suppressif ideqval Setup.Sata == 0x00;
+    oneof varid   = Setup.SataType,
+      prompt      = STRING_TOKEN(STR_SATA_TYPE_PROMPT),
+      help        = STRING_TOKEN(STR_SATA_TYPE_HELP1),
+      option text = STRING_TOKEN(STR_SATA_IDE), value = 0, flags = RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_SATA_AHCI), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    endoneof;
+
+    text
+      help   = STRING_TOKEN(STR_NULL_STRING),
+      text   = STRING_TOKEN(STR_SATA0_STRING),
+      text   = STRING_TOKEN(STR_SATA0_NAME),
+      flags  = 0,
+      key    = 0;
+
+    text
+      help   = STRING_TOKEN(STR_NULL_STRING),
+      text   = STRING_TOKEN(STR_SATA1_STRING),
+      text   = STRING_TOKEN(STR_SATA1_NAME),
+      flags  = 0,
+      key    = 0;
+
+    suppressif ideqval Setup.SataType == 0x0;
+      oneof varid   = Setup.Sata0HotPlugCap,
+        prompt      = STRING_TOKEN(STR_SATA0_HOTPLUG_CAP_PROMPT),
+        help        = STRING_TOKEN(STR_SATA_HOTPLUG_CAP_HELP),
+        option text = STRING_TOKEN(STR_ENABLE), value= 1, flags=DEFAULT | MANUFACTURING | RESET_REQUIRED;
+        option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 | RESET_REQUIRED;
+      endoneof;
+
+      oneof varid   = Setup.Sata1HotPlugCap,
+        prompt      = STRING_TOKEN(STR_SATA1_HOTPLUG_CAP_PROMPT),
+        help        = STRING_TOKEN(STR_SATA_HOTPLUG_CAP_HELP),
+        option text = STRING_TOKEN(STR_ENABLE), value= 1, flags=DEFAULT | MANUFACTURING | RESET_REQUIRED;
+        option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 | RESET_REQUIRED;
+      endoneof;
+    endif;
+
+  endif;  //SATA enable
+
+endform;
+
+form formid = LPSS_CONFIGURATION_ID,
+
+  title    = STRING_TOKEN(STR_LPSS_SCC_FORM_TITLE);
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+  oneof varid   = Setup.LpssPciModeEnabled,
+    prompt      = STRING_TOKEN(STR_LPSS_PCI_PROMPT),
+    help        = STRING_TOKEN(STR_LPSS_PCI_HELP),
+    option text = STRING_TOKEN(STR_ACPI_MODE), value=0, flags=DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_PCI_MODE), value=1, flags=0| RESET_REQUIRED;
+  endoneof;
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+
+  subtitle text = STRING_TOKEN(STR_SCC_SETTING_SUBTITLE);
+  oneof varid   = Setup.eMMCBootMode,
+    prompt      = STRING_TOKEN(STR_EMMC_BOOT_PROMPT),
+    help        = STRING_TOKEN(STR_EMMC_BOOT_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_AUTO_DETECT), value=1, flags=DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_EMMC_BOOT_41), value=2, flags=0 | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_EMMC_BOOT_45), value=3, flags=0 | RESET_REQUIRED;
+  endoneof;
+
+
+
+   oneof varid   = Setup.SecureErase,
+    questionid  = 0x1240,
+    prompt      = STRING_TOKEN(STR_SECURE_ERASE_PROMPT),
+    help        = STRING_TOKEN(STR_SECURE_ERASE_HELP),
+    flags       = INTERACTIVE,
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags= DEFAULT |MANUFACTURING | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= RESET_REQUIRED;
+  endoneof;
+
+
+
+   subtitle text = STRING_TOKEN(STR_NULL_STRING);
+grayoutif NOT ideqval Setup.eMMCBootMode == 0x3;
+  oneof varid   = Setup.LpsseMMC45Enabled,
+    prompt      = STRING_TOKEN(STR_SCC_EMMC45_PROMPT),
+    help        = STRING_TOKEN(STR_SCC_EMMC45_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 | MANUFACTURING | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=DEFAULT | RESET_REQUIRED;
+  endoneof;
+  oneof varid   = Setup.LpsseMMC45DDR50Enabled,
+    prompt      = STRING_TOKEN(STR_SCC_EMMC45_DDR50_PROMPT),
+    help        = STRING_TOKEN(STR_SCC_EMMC45_DDR50_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 | MANUFACTURING | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=DEFAULT | RESET_REQUIRED;
+  endoneof;
+    oneof varid   = Setup.LpsseMMC45HS200Enabled,
+    prompt      = STRING_TOKEN(STR_SCC_EMMC45_HS200_PROMPT),
+    help        = STRING_TOKEN(STR_SCC_EMMC45_HS200_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 | MANUFACTURING | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=DEFAULT| RESET_REQUIRED;
+  endoneof;
+
+  grayoutif ideqval Setup.LpsseMMC45DDR50Enabled == 0x1;
+  oneof varid  = Setup.LpsseMMC45RetuneTimerValue,
+    prompt = STRING_TOKEN(STR_SCC_EMMC45_RE_TUNE_TIMER_VALUE),
+    help   = STRING_TOKEN(STR_SCC_EMMC45_RE_TUNE_TIMER_VALUE_HELP),
+    option text = STRING_TOKEN(STR_EMMC45_TIMER_0), value = 0, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_EMMC45_TIMER_1), value =1, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_EMMC45_TIMER_2), value =2, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_EMMC45_TIMER_3), value =3, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_EMMC45_TIMER_4), value =4, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_EMMC45_TIMER_5), value =5, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_EMMC45_TIMER_6), value =6, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_EMMC45_TIMER_7), value =7, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_EMMC45_TIMER_8), value =8, flags = MANUFACTURING| DEFAULT|RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_EMMC45_TIMER_9), value =9, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_EMMC45_TIMER_10), value =10, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_EMMC45_TIMER_11), value =11, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_EMMC45_TIMER_12), value =12, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_EMMC45_TIMER_13), value =13, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_EMMC45_TIMER_14), value =14, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_EMMC45_TIMER_15), value =15, flags = RESET_REQUIRED;
+  endoneof;
+  endif;    // grayoutif ideqval Setup.LpsseMMC45DDR50Enabled == 0x1;
+ endif;     // grayoutif NOT ideqval Setup.eMMCBootMode == 0x1;
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+  oneof varid   = Setup.LpssSdioEnabled,
+    prompt      = STRING_TOKEN(STR_SCC_SDIO_PROMPT),
+    help        = STRING_TOKEN(STR_SCC_SDIO_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=DEFAULT | MANUFACTURING | RESET_REQUIRED;
+  endoneof;
+
+  oneof varid   = Setup.LpssSdcardEnabled,
+    prompt      = STRING_TOKEN(STR_SCC_SDCARD_PROMPT),
+    help        = STRING_TOKEN(STR_SCC_SDCARD_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= DEFAULT|MANUFACTURING | RESET_REQUIRED;
+  endoneof;
+
+
+grayoutif NOT ideqval Setup.LpssSdcardEnabled == 0x1;
+  grayoutif ideqval Setup.LpssSdCardDDR50Enabled == 0x1;
+  oneof varid   = Setup.LpssSdCardSDR25Enabled,
+    prompt      = STRING_TOKEN(STR_SCC_SD_SDR25_PROMPT),
+    help        = STRING_TOKEN(STR_SCC_SD_SDR25_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=0 | RESET_REQUIRED;
+  endoneof;
+  endif; // grayoutif ideqval Setup.LpsseMMC45DDR50Enabled == 0x1;
+
+  grayoutif ideqval Setup.LpssSdCardSDR25Enabled == 0x1;
+    oneof varid   = Setup.LpssSdCardDDR50Enabled,
+    prompt      = STRING_TOKEN(STR_SCC_SD_DDR50_PROMPT),
+    help        = STRING_TOKEN(STR_SCC_SD_DDR50_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=0 | RESET_REQUIRED;
+    endoneof;
+  endif; // grayoutif ideqval Setup.LpssSdCardSDR25Enabled == 0x1;
+
+  oneof varid   = Setup.SdCardRemovable,
+    prompt      = STRING_TOKEN(STR_SCC_SDCARD_REMOVABILITY),
+    help        = STRING_TOKEN(STR_SCC_SDCARD_REMOVABILITY_HELP),
+    option text = STRING_TOKEN(STR_SCC_SDCARD_NON_REMOVABLE), value=0, flags=0 | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_SCC_SDCARD_REMOVABLE), value=1, flags=DEFAULT | MANUFACTURING | RESET_REQUIRED;
+  endoneof;
+
+endif;     // grayoutif NOT ideqval Setup.LpssSdcardEnabled == 0x1;
+
+
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+
+  subtitle text = STRING_TOKEN(STR_LPSS1_SETTING_SUBTITLE);
+
+  oneof varid   = Setup.LpssDma0Enabled,
+    prompt      = STRING_TOKEN(STR_LPSS_DMA1_PROMPT),
+    help        = STRING_TOKEN(STR_LPSS_DMA1_HELP),
+    flags       = INTERACTIVE,
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= DEFAULT | MANUFACTURING | RESET_REQUIRED;
+  endoneof;
+
+  grayoutif ideqval Setup.LpssDma0Enabled == 0x00;
+  oneof varid   = Setup.LpssHsuart0Enabled,
+    prompt      = STRING_TOKEN(STR_LPSS_HSUART1_PROMPT),
+    help        = STRING_TOKEN(STR_LPSS_HSUART1_HELP_ENBDT_DEV_LIST),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags= MANUFACTURING  | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= 0 | DEFAULT | RESET_REQUIRED;
+  endoneof;
+  endif;
+
+  //Add control flow
+  grayoutif ideqval Setup.LpssHsuart0Enabled == 0x00;
+  oneof varid   = Setup.LpssHsuart0FlowControlEnabled,
+    prompt      = STRING_TOKEN(STR_LPSS_HSUART1_FLOWCONTROL_PROMPT),
+    help        = STRING_TOKEN(STR_LPSS_HSUART1_HELP_ENBDT_DEV_LIST),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |DEFAULT | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= MANUFACTURING  | RESET_REQUIRED;
+  endoneof;
+  endif;
+
+  grayoutif ideqval Setup.LpssDma0Enabled == 0x00;
+  oneof varid   = Setup.LpssHsuart1Enabled,
+    prompt      = STRING_TOKEN(STR_LPSS_HSUART2_PROMPT),
+    help        = STRING_TOKEN(STR_LPSS_HSUART2_HELP_ENBDT_DEV_LIST),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=MANUFACTURING  | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= 0 | DEFAULT | RESET_REQUIRED;
+  endoneof;
+  endif;
+
+  //Add control flow
+  grayoutif ideqval Setup.LpssHsuart1Enabled == 0x00;
+  oneof varid   = Setup.LpssHsuart1FlowControlEnabled,
+    prompt      = STRING_TOKEN(STR_LPSS_HSUART2_FLOWCONTROL_PROMPT),
+    help        = STRING_TOKEN(STR_LPSS_HSUART1_HELP_ENBDT_DEV_LIST),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |DEFAULT | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= MANUFACTURING  | RESET_REQUIRED;
+  endoneof;
+  endif;
+
+
+  grayoutif ideqval Setup.LpssDma0Enabled == 0x00;
+  oneof varid   = Setup.LpssPwm0Enabled,
+    prompt      = STRING_TOKEN(STR_PWM1_PROMPT),
+    help        = STRING_TOKEN(STR_PWM1_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=MANUFACTURING  | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= 0 | DEFAULT | RESET_REQUIRED;
+  endoneof;
+  endif;
+
+  grayoutif ideqval Setup.LpssDma0Enabled == 0x00;
+  oneof varid   = Setup.LpssPwm1Enabled,
+    prompt      = STRING_TOKEN(STR_PWM2_PROMPT),
+    help        = STRING_TOKEN(STR_PWM2_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=MANUFACTURING  | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= 0 | DEFAULT | RESET_REQUIRED;
+  endoneof;
+  endif;
+
+  grayoutif ideqval Setup.LpssDma0Enabled == 0x00;
+  oneof varid   = Setup.LpssSpiEnabled,
+    prompt      = STRING_TOKEN(STR_LPSS_SPI_PROMPT),
+    help        = STRING_TOKEN(STR_LPSS_SPI_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=MANUFACTURING  | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= 0 |DEFAULT | RESET_REQUIRED;
+  endoneof;
+  endif;
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+
+  subtitle text = STRING_TOKEN(STR_LPSS2_SETTING_SUBTITLE);
+
+  oneof varid   = Setup.LpssDma1Enabled,
+    prompt      = STRING_TOKEN(STR_LPSS_DMA2_PROMPT),
+    help        = STRING_TOKEN(STR_LPSS_DMA2_HELP),
+    flags       = INTERACTIVE,
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= DEFAULT | MANUFACTURING | RESET_REQUIRED;
+  endoneof;
+
+/*
+  grayoutif ideqval Setup.LpssDma1Enabled == 0x00;
+  oneof varid   = Setup.LpssI2C0Enabled,
+    prompt      = STRING_TOKEN(STR_LPSS_I2C1_PROMPT),
+    help        = STRING_TOKEN(STR_LPSS_I2C1_HELP_ENBDT_DEV_LIST),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |DEFAULT |RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= MANUFACTURING | RESET_REQUIRED;
+  endoneof;
+  endif;
+
+
+  grayoutif ideqval Setup.LpssDma1Enabled == 0x00;
+  oneof varid   = Setup.LpssI2C1Enabled,
+    prompt      = STRING_TOKEN(STR_LPSS_I2C2_PROMPT),
+    help        = STRING_TOKEN(STR_LPSS_I2C2_HELP_ENBDT_DEV_LIST),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |DEFAULT | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= MANUFACTURING | RESET_REQUIRED;
+  endoneof;
+  endif;
+
+  grayoutif ideqval Setup.LpssDma1Enabled == 0x00;
+  oneof varid   = Setup.LpssI2C2Enabled,
+    prompt      = STRING_TOKEN(STR_LPSS_I2C3_PROMPT),
+    help        = STRING_TOKEN(STR_LPSS_I2C3_HELP_ENBDT_DEV_LIST),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |DEFAULT | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= MANUFACTURING | RESET_REQUIRED;
+  endoneof;
+  endif;
+
+  grayoutif ideqval Setup.LpssDma1Enabled == 0x00;
+  oneof varid   = Setup.LpssI2C3Enabled,
+    prompt      = STRING_TOKEN(STR_LPSS_I2C4_PROMPT),
+    help        = STRING_TOKEN(STR_LPSS_I2C4_HELP_ENBDT_DEV_LIST),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |DEFAULT | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= MANUFACTURING | RESET_REQUIRED;
+  endoneof;
+  endif;
+
+  grayoutif ideqval Setup.LpssDma1Enabled == 0x00;
+  oneof varid   = Setup.LpssI2C4Enabled,
+    prompt      = STRING_TOKEN(STR_LPSS_I2C5_PROMPT),
+    help        = STRING_TOKEN(STR_LPSS_I2C5_HELP_ENBDT_DEV_LIST),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |DEFAULT | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= MANUFACTURING | RESET_REQUIRED;
+  endoneof;
+  endif;
+*/
+  grayoutif ideqval Setup.LpssDma1Enabled == 0x00;
+  oneof varid   = Setup.LpssI2C5Enabled,
+    prompt      = STRING_TOKEN(STR_LPSS_I2C6_PROMPT),
+    help        = STRING_TOKEN(STR_LPSS_I2C6_HELP_ENBDT_DEV_LIST),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=  DEFAULT |MANUFACTURING | RESET_REQUIRED;
+  endoneof;
+  endif;
+
+  grayoutif ideqval Setup.LpssDma1Enabled == 0x00;
+  oneof varid   = Setup.LpssI2C6Enabled,
+    prompt      = STRING_TOKEN(STR_LPSS_I2C7_PROMPT),
+    help        = STRING_TOKEN(STR_LPSS_I2C7_HELP_ENBDT_DEV_LIST),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= DEFAULT | MANUFACTURING | RESET_REQUIRED;
+  endoneof;
+  endif;
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+
+  subtitle text = STRING_TOKEN(STR_I2C_DEVICE_SETTING_SUBTITLE);
+
+  oneof varid   = Setup.I2CTouchAd,
+    prompt      = STRING_TOKEN(STR_I2C_TOUCH_PROMPT),
+    help        = STRING_TOKEN(STR_I2C_TOUCH_HELP),
+    option text = STRING_TOKEN(STR_AUTO), value=0, flags=DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_I2C_FVP), value=0x4B, flags=0 | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_I2C_FFRD), value=0x4A, flags=0 | RESET_REQUIRED;
+  endoneof;
+
+ subtitle text = STRING_TOKEN(STR_NULL_STRING);
+
+ oneof varid = Setup.SAR1,
+    prompt         = STRING_TOKEN(STR_SAR_SENSOR_PROMPT),
+    help           = STRING_TOKEN(STR_SAR_SENSOR_HELP),
+    option text    = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT | MANUFACTURING |RESET_REQUIRED;
+    option text    = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+  endoneof;
+endform;
+
+
+//
+//LAN Controller
+//
+form formid = LAN_OPTIONS_FORM_ID,
+
+  title    = STRING_TOKEN(STR_LAN_OPTIONS_FORM_TITLE);
+
+  subtitle text = STRING_TOKEN(STR_LAN_OPTIONS_FORM_TITLE);
+
+  oneof varid = Setup.Lan,
+    prompt   = STRING_TOKEN(STR_PCH_LAN_CONTROLLER),
+    help     = STRING_TOKEN(STR_PCH_LAN_CONTROLLER_HELP),
+    option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+  endoneof;
+
+  suppressif ideqval Setup.Lan == 0;
+    oneof varid = Setup.WakeOnLanS5,
+      prompt   = STRING_TOKEN(STR_PCH_LAN_WOL_PROMPT),
+      help     = STRING_TOKEN(STR_PCH_LAN_WOL_HELP),
+      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags =  DEFAULT | MANUFACTURING | RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+    endoneof;
+
+    oneof varid = Setup.SlpLanLowDc,
+      prompt   = STRING_TOKEN(STR_PCH_SLP_LAN_LOW_DC_PROMPT),
+      help     = STRING_TOKEN(STR_PCH_SLP_LAN_LOW_DC_HELP),
+      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags =  DEFAULT | MANUFACTURING | RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+    endoneof;
+
+    oneof varid = Setup.BootNetwork,
+      prompt   = STRING_TOKEN(STR_PCH_PXEROM_CONTROL),
+      help     = STRING_TOKEN(STR_PCH_PXEROM_CONTROL_HELP),
+      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags =  RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT | MANUFACTURING |RESET_REQUIRED;
+    endoneof;
+  endif;
+
+endform;
+
+//
+// Azalia Configuration
+//
+form formid = AZALIA_OPTIONS_FORM_ID,
+
+  title    = STRING_TOKEN(STR_AZALIA_OPTIONS_FORM_TITLE);
+
+  subtitle text = STRING_TOKEN(STR_AZALIA_OPTIONS_FORM_TITLE);
+  oneof varid   = Setup.Lpe,
+      prompt      = STRING_TOKEN(STR_LPE_PROMPT),
+      help        = STRING_TOKEN(STR_LPE_HELP),
+      option text = STRING_TOKEN(STR_DISABLE), value=0, flags=DEFAULT | MANUFACTURING | RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_LPE_PCI_MODE), value=1, flags=0 | RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_LPE_ACPI_MODE), value=2, flags=0 | RESET_REQUIRED;
+  endoneof;
+
+  grayoutif NOT ideqval Setup.Lpe == 0x2;
+  oneof varid   = Setup.LpeAudioReportedByDSDT,
+      prompt      = STRING_TOKEN(STR_LPE_REPORTED_BY_DSDT_PROMPT),
+      help        = STRING_TOKEN(STR_LPE_REPORTED_BY_DSDT_HELP),
+      option text = STRING_TOKEN(STR_DISABLE), value=0, flags=DEFAULT | MANUFACTURING | RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_ENABLE), value=1, flags=RESET_REQUIRED;
+  endoneof;
+  endif;
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+  suppressif ideqval Setup.AzaliaDs == 0x1;
+    oneof varid  = Setup.PchAzalia,
+      prompt   = STRING_TOKEN(STR_PCH_AZALIA_PROMPT),
+      help     = STRING_TOKEN(STR_PCH_AZALIA_HELP),
+      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = 0 | RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    endoneof;
+  endif;
+
+  suppressif ideqval Setup.AzaliaDs == 0x0;
+    text
+      help   = STRING_TOKEN(STR_PCH_AZALIA_DS_SUPPORT),
+      text   = STRING_TOKEN(STR_PCH_AZALIA_PROMPT),
+      text   = STRING_TOKEN(STR_ENABLE),
+      flags  = 0,
+      key    = 0;
+  endif;
+
+  suppressif ideqval Setup.PchAzalia == 0x0;
+    oneof varid  = Setup.AzaliaVCiEnable,
+      prompt   = STRING_TOKEN(STR_AZALIA_VC_PROMPT),
+      help     = STRING_TOKEN(STR_AZALIA_VC_HELP),
+      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    endoneof;
+  endif;
+
+  suppressif ideqval Setup.PchAzalia == 0x0;
+    oneof varid  = Setup.AzaliaDs,
+      prompt   = STRING_TOKEN(STR_AZALIA_DS_PROMPT),
+      help     = STRING_TOKEN(STR_AZALIA_DS_HELP),
+      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = RESET_REQUIRED;
+    endoneof;
+  endif;
+
+  suppressif ideqval Setup.PchAzalia == 0x0;
+    oneof varid  = Setup.AzaliaPme,
+      prompt   = STRING_TOKEN(STR_AZALIA_PME_PROMPT),
+      help     = STRING_TOKEN(STR_AZALIA_PME_HELP),
+      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    endoneof;
+
+    oneof varid  = Setup.HdmiCodec,
+      prompt   = STRING_TOKEN(STR_HDMI_CODEC_PROMPT),
+      help     = STRING_TOKEN(STR_HDMI_CODEC_HELP),
+      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    endoneof;
+  endif;
+
+endform;
+
+//
+//  Misc Configuration
+//
+form formid = MISC_OPTIONS_FORM_ID,
+
+  title    = STRING_TOKEN(STR_MISC_OPTION_FORM_TITLE);
+
+  subtitle text = STRING_TOKEN(STR_MISC_OPTION_FORM_TITLE);
+  //
+  // HPET Disable/Enable
+  //
+  oneof   varid   = Setup.Hpet,
+    prompt      = STRING_TOKEN(STR_HPET_PROMPT),
+    help        = STRING_TOKEN(STR_HPET_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value=0x00, flags=RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value=0x01, flags=DEFAULT | RESET_REQUIRED;
+  endoneof;
+
+  oneof varid  = Setup.StateAfterG3,
+     prompt   = STRING_TOKEN(STR_STATE_AFTER_G3),
+     help     = STRING_TOKEN(STR_STATE_AFTER_G3_HELP),
+     option text = STRING_TOKEN(STR_S0_AFTER_G3_STRING), value = 0, flags = DEFAULT | RESET_REQUIRED;
+     option text = STRING_TOKEN(STR_S5_AFTER_G3_STRING), value = 1, flags = MANUFACTURING | RESET_REQUIRED;
+  endoneof;
+
+  oneof varid  = Setup.EnableClockSpreadSpec,
+     prompt   = STRING_TOKEN(STR_CLOCK_SPREAD_SPEC_ENABLE),
+     help     = STRING_TOKEN(STR_CLOCK_SPREAD_SPEC_ENABLE_HELP),
+     option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+     option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = RESET_REQUIRED;
+  endoneof;
+
+
+  oneof varid  = Setup.UartInterface,
+    prompt   = STRING_TOKEN(STR_PCH_UART_SELECT),
+    help     = STRING_TOKEN(STR_PCH_UART_SELECT_HELP),
+    option text = STRING_TOKEN(STR_UART_SELECT_PCU), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_UART_SELECT_SIO), value = 1, flags = RESET_REQUIRED;
+  endoneof;
+
+  suppressif ideqval Setup.LpssHsuart0Enabled == 1 OR ideqval Setup.UartInterface == 1;
+    oneof varid  = Setup.PcuUart1,
+      prompt   = STRING_TOKEN(STR_PCU_UART_A),
+      help     = STRING_TOKEN(STR_PCU_UART_A_HELP),
+      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    endoneof;
+  endif;
+
+  oneof varid = Setup.SpiRwProtect,
+    prompt         = STRING_TOKEN(STR_PCH_SPI_WP_PROMPT),
+    help           = STRING_TOKEN(STR_PCH_SPI_WP_HELP),
+    option text    = STRING_TOKEN(STR_PCH_SPI_WP_DISABLE), value = 0, flags = DEFAULT | MANUFACTURING |RESET_REQUIRED;
+    option text    = STRING_TOKEN(STR_PCH_SPI_WP_ENABLE), value = 1, flags = RESET_REQUIRED;
+  endoneof;
+
+  oneof varid = Setup.MmioSize,
+    prompt         = STRING_TOKEN(STR_MMIO_PROMPT),
+    help           = STRING_TOKEN(STR_MMIO_HELP),
+    option text    = STRING_TOKEN(STR_MMIO_0_75G_STRING), value = 0, flags = RESET_REQUIRED;
+    option text    = STRING_TOKEN(STR_MMIO_1G_STRING), value = 1, flags = RESET_REQUIRED;
+    option text    = STRING_TOKEN(STR_MMIO_1_25G_STRING), value = 2, flags = RESET_REQUIRED;
+    option text    = STRING_TOKEN(STR_MMIO_1_5G_STRING), value = 3, flags = RESET_REQUIRED;
+    option text    = STRING_TOKEN(STR_MMIO_2G_STRING), value = 4, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+  endoneof;
+
+  oneof varid = Setup.PcieDynamicGating,
+    prompt         = STRING_TOKEN(STR_PCIEDYNCLK_PROMPT),
+    help           = STRING_TOKEN(STR_PCIEDYNCLK_HELP),
+    option text    = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT | MANUFACTURING |RESET_REQUIRED;
+    option text    = STRING_TOKEN(STR_ENABLE), value = 1, flags = RESET_REQUIRED;
+  endoneof;
+
+  oneof varid = Setup.GpioWakeCapability,
+    prompt         = STRING_TOKEN(STR_GPIO_WAKE_CAPABILITY_ENABLE),
+    help           = STRING_TOKEN(STR_GPIO_WAKE_CAPABILITY_ENABLE_HELP),
+    option text    = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT | MANUFACTURING |RESET_REQUIRED;
+    option text    = STRING_TOKEN(STR_ENABLE), value = 1, flags = RESET_REQUIRED;
+  endoneof;
+
+  oneof varid = Setup.RtcBattery,
+    prompt         = STRING_TOKEN(STR_RTC_BATTERY),
+    help           = STRING_TOKEN(STR_RTC_BATTERY_HELP),
+    option text    = STRING_TOKEN(STR_RTC_BATTERY_NOT_PRESENT), value = 0, flags = RESET_REQUIRED;
+    option text    = STRING_TOKEN(STR_RTC_BATTERY_PRESENT), value = 1, flags = DEFAULT | MANUFACTURING |RESET_REQUIRED;
+  endoneof;
+
+endform;
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SystemComponent.vfi b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SystemComponent.vfi
new file mode 100644
index 0000000000..96cf470eaf
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SystemComponent.vfi
@@ -0,0 +1,81 @@
+//
+//
+// Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+//                                                                                  

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

+//
+//
+//
+// Module Name:
+//
+//   SystemComponent.vfr
+//
+// Abstract:
+//
+//   Driver Setup formset.
+//
+// Revision History:
+//   ------------------------------------------------------------------------------
+//   Rev   Date<MM/DD/YYYY>    Name    Description
+//   ------------------------------------------------------------------------------
+
+// --*/
+
+form formid = SYSTEM_COMPONENT_FORM_ID,
+
+  title  = STRING_TOKEN(STR_SYSTEM_COMPONENT_TITLE);
+/*
+  oneof   varid   = Setup.CRIDSettings,
+    prompt      = STRING_TOKEN(STR_CRID_PROMPT),
+    help        = STRING_TOKEN(STR_CRID_SETTING_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = MANUFACTURING | DEFAULT | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_CRID_0_STRING),  value = 1, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_CRID_1_STRING),  value = 2, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_CRID_2_STRING),  value = 3, flags = RESET_REQUIRED;
+  endoneof;
+*/
+
+  subtitle text = STRING_TOKEN(STR_PNP_CONFIGURATION_TITLE);
+  oneof   varid   = Setup.PnpSettings,
+    prompt      = STRING_TOKEN(STR_PNP_SETTING_PROMPT),
+    help        = STRING_TOKEN(STR_PNP_SETTING_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+#if (PNP_DEBUG == 1)
+    option text = STRING_TOKEN(STR_PNP_POWER_STRING),  value = 1, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_PNP_PERFORMANCE_STRING),  value = 2, flags = RESET_REQUIRED;
+#endif
+    option text = STRING_TOKEN(STR_PNP_POWER_PERFORMANCE_STRING), value = 3, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_PNP_POWER_PERFORMANCE_STRING_A0), value = 4, flags = 0 | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_PNP_POWER_PERFORMANCE_STRING_B0), value = 5, flags = 0 | RESET_REQUIRED;
+  endoneof;
+
+  oneof   varid   = Setup.CfioPnpSettings,
+    prompt      = STRING_TOKEN(STR_CFIO_PNP_SETTING_PROMPT),
+    help        = STRING_TOKEN(STR_CFIO_PNP_SETTING_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = MANUFACTURING | DEFAULT | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = 0 | RESET_REQUIRED;
+  endoneof;
+ oneof   varid   = Setup.TristateLpc,
+    prompt      = STRING_TOKEN(STR_TRISTATE_LPC_PROMPT),
+    help        = STRING_TOKEN(STR_TRISTATE_LPC_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = MANUFACTURING | DEFAULT | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = 0 | RESET_REQUIRED;
+  endoneof;
+
+
+
+
+
+
+  oneof varid   = Setup.PchFSAOn,
+    prompt      = STRING_TOKEN(STR_PCH_FSA_PROMPT),
+    help        = STRING_TOKEN(STR_PCH_FSA_HELP),
+    option text = STRING_TOKEN(STR_OFF), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ON), value = 1, flags = RESET_REQUIRED;
+  endoneof;
+
+
+
+endform;
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Thermal.vfi b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Thermal.vfi
new file mode 100644
index 0000000000..63063a73b2
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Thermal.vfi
@@ -0,0 +1,106 @@
+//
+//
+// Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+//                                                                                  

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

+//
+//
+//
+// Module Name:
+//
+//   DPTF.vfr
+//
+// Abstract:
+//
+//   Driver Setup formset.
+//
+// Revision History:
+//   ------------------------------------------------------------------------------
+//   Rev   Date<MM/DD/YYYY>    Name    Description
+//   ------------------------------------------------------------------------------
+
+// --*/
+
+form formid = THERMAL_FORM_ID,
+
+  title  = STRING_TOKEN(STR_THERMAL_TITLE);
+
+  subtitle text = STRING_TOKEN(STR_THERMAL_CONFIGURATION);
+  oneof   varid   = Setup.CriticalThermalTripPoint,
+    prompt      = STRING_TOKEN(STR_ACPI_CRITICAL_THERMAL_TRIP_POINT),
+    help        = STRING_TOKEN(STR_ACPI_CRITICAL_THERMAL_TRIP_POINT_HELP),
+    option text = STRING_TOKEN (STR_85_C), value = 85, flags=0 | RESET_REQUIRED;     
+    option text = STRING_TOKEN (STR_87_C), value = 87, flags=0 | RESET_REQUIRED; 
+    option text = STRING_TOKEN (STR_90_C), value = 90, flags=0 | RESET_REQUIRED;
+    option text = STRING_TOKEN (STR_105_C), value = 105, flags=0 | RESET_REQUIRED;
+    option text = STRING_TOKEN (STR_110_C), value = 110, flags=0 | RESET_REQUIRED;
+    option text = STRING_TOKEN (STR_200_C), value = 200, flags=DEFAULT | MANUFACTURING | RESET_REQUIRED;
+  endoneof; 
+  oneof   varid   = Setup.PassiveThermalTripPoint,
+    prompt      = STRING_TOKEN (STR_ACPI_PASSIVE_THERMAL_TRIP_POINT),
+    help        = STRING_TOKEN (STR_ACPI_PASSIVE_THERMAL_TRIP_POINT_HELP),
+    option text = STRING_TOKEN (STR_85_C), value = 85, flags=0 | RESET_REQUIRED;
+    option text = STRING_TOKEN (STR_87_C), value = 87, flags=0 | RESET_REQUIRED;   
+    option text = STRING_TOKEN (STR_90_C), value = 90, flags=0 | RESET_REQUIRED;
+    option text = STRING_TOKEN (STR_100_C), value = 100, flags=0 | RESET_REQUIRED;
+    option text = STRING_TOKEN (STR_105_C), value = 105, flags=0 | RESET_REQUIRED;
+    option text = STRING_TOKEN (STR_180_C), value = 180, flags=DEFAULT | MANUFACTURING | RESET_REQUIRED;
+  endoneof;
+
+  suppressif TRUE;
+    numeric varid = Setup.PassiveTc1Value,
+      prompt  = STRING_TOKEN (STR_ACPI_PASSIVE_TC1_VALUE),
+      help    = STRING_TOKEN (STR_ACPI_PASSIVE_TC1_VALUE_HELP),
+      flags   = 0 | RESET_REQUIRED,
+      minimum = 1,
+      maximum = 16,
+      step    = 1,
+      default = 1,
+    endnumeric;
+
+    numeric varid = Setup.PassiveTc2Value,
+      prompt  = STRING_TOKEN (STR_ACPI_PASSIVE_TC2_VALUE),
+      help    = STRING_TOKEN (STR_ACPI_PASSIVE_TC2_VALUE_HELP),
+      flags   = 0 | RESET_REQUIRED,
+      minimum = 1,
+      maximum = 16,
+      step    = 1,
+      default = 5,
+    endnumeric;
+
+    numeric varid = Setup.PassiveTspValue,
+      prompt  = STRING_TOKEN (STR_ACPI_PASSIVE_TSP_VALUE),
+      help    = STRING_TOKEN (STR_ACPI_PASSIVE_TSP_VALUE_HELP),
+      flags   = 0 | RESET_REQUIRED,
+      minimum = 2,
+      maximum = 50,
+      step    = 2,
+      default = 50,
+    endnumeric;
+  endif;
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+
+  oneof varid    = Setup.DisableActiveTripPoints,
+        prompt      = STRING_TOKEN(STR_DATP_PROMPT),
+        help        = STRING_TOKEN(STR_DATP_HELP),
+        option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+        option text = STRING_TOKEN(STR_ENABLED),  value = 1, flags = RESET_REQUIRED;
+  endoneof;
+
+  suppressif TRUE;  
+  oneof varid     = Setup.EnableDigitalThermalSensor,
+    prompt      = STRING_TOKEN(STR_DTS_PROMPT),
+    help        = STRING_TOKEN(STR_DTS_PROMPT_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE),  value = 1, flags = MANUFACTURING |RESET_REQUIRED |DEFAULT;
+  endoneof;
+  endif;
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+
+
+
+endform;
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UnCore.vfi b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UnCore.vfi
new file mode 100644
index 0000000000..ed6bb3a00b
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UnCore.vfi
@@ -0,0 +1,235 @@
+//
+//
+// Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+//                                                                                  

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

+//
+//
+//
+// Module Name:
+//
+//   UncoreConfiguration.vfi
+//
+// Abstract:
+//
+//   Driver Setup formset.
+//
+
+
+// --*/
+
+form formid = UNCORE_FORM_ID,
+  title    = STRING_TOKEN(STR_UNCORE_CONFIGURATION_TITLE);
+
+  subtitle text = STRING_TOKEN(STR_GOP_TITLE);
+
+  oneof varid    = Setup.GOPEnable,
+    prompt   = STRING_TOKEN(STR_GOP_VBIOS_SWITCH),
+    help     = STRING_TOKEN(STR_GOP_VBIOS_SWITCH_HELP),
+    option text = STRING_TOKEN(STR_ENABLE), value =1, flags = MANUFACTURING | DEFAULT | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+  endoneof;
+
+  oneof varid  = Setup.GOPBrightnessLevel,
+    prompt = STRING_TOKEN(STR_GOP_BRIGHTNESS_LEVEL),
+    help   = STRING_TOKEN(STR_GOP_BRIGHTNESS_LEVEL_HELP),
+    option text = STRING_TOKEN(STR_GOP_BRIGHT_20), value =2, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_GOP_BRIGHT_40), value =3, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_GOP_BRIGHT_60), value =4, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_GOP_BRIGHT_80), value =5, flags = MANUFACTURING| DEFAULT| RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_GOP_BRIGHT_100), value =6, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_GOP_BRIGHT_120), value =7, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_GOP_BRIGHT_140), value =8, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_GOP_BRIGHT_160), value =9, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_GOP_BRIGHT_180), value =10, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_GOP_BRIGHT_200), value =11, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_GOP_BRIGHT_220), value =12, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_GOP_BRIGHT_240), value =13, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_GOP_BRIGHT_255), value =14, flags = RESET_REQUIRED;
+  endoneof;
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+  subtitle text = STRING_TOKEN(STR_IGD_TITLE);
+
+  suppressif ideqval Setup.PrimaryVideoAdaptor == 0x2;
+    oneof varid  = Setup.Igd,
+      prompt   = STRING_TOKEN (STR_IGD_PROMPT),
+      help     = STRING_TOKEN (STR_IGD_HELP),
+      option text = STRING_TOKEN(STR_DISABLE), value=0, flags=RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_ENABLE),  value=1, flags=DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    endoneof;
+  endif;
+
+  oneof varid    = Setup.PrimaryVideoAdaptor,
+    prompt   = STRING_TOKEN(STR_PRIMARY_DISPLAY),
+    help     = STRING_TOKEN(STR_PRIMARY_DISPLAY_HELP),
+    option text = STRING_TOKEN(STR_AUTOMATIC), value = 3, flags =   RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_IGD_STRING), value = 0, flags =  DEFAULT |MANUFACTURING |RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_PCI_STRING),  value = 2, flags = RESET_REQUIRED;
+  endoneof;
+
+
+  oneof varid = Setup.PavpMode,
+    prompt   = STRING_TOKEN(STR_PAVC_PROMPT),
+    help     = STRING_TOKEN(STR_PAVC_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_PAVP_LITE_MODE), value = 1, flags = MANUFACTURING | DEFAULT | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_PAVP_SERPENT_MODE), value = 2, flags = RESET_REQUIRED;
+  endoneof;
+
+
+  oneof varid    = Setup.GTTSize,
+    prompt   = STRING_TOKEN(STR_GTT_SIZE),
+    help     = STRING_TOKEN(STR_GTT_SIZE_HELP),
+    option text = STRING_TOKEN(GTT_SIZE_1MB), value = 1, flags =  RESET_REQUIRED;
+    option text = STRING_TOKEN(GTT_SIZE_2MB), value = 2, flags =  DEFAULT | MANUFACTURING | RESET_REQUIRED;
+  endoneof;
+
+  oneof varid    = Setup.IgdApertureSize,
+    prompt   = STRING_TOKEN(STR_APERTURE_SIZE),
+    help     = STRING_TOKEN(STR_APERTURE_SIZE_HELP),
+    option text = STRING_TOKEN(APERTURE_SIZE_128MB), value = 1, flags =  RESET_REQUIRED;
+    option text = STRING_TOKEN(APERTURE_SIZE_256MB), value = 2, flags =  DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    option text = STRING_TOKEN(APERTURE_SIZE_512MB), value = 3, flags =  RESET_REQUIRED;
+  endoneof;
+
+  oneof varid   = Setup.IgdDvmt50PreAlloc,
+    prompt  = STRING_TOKEN(STR_DVMT50_PRE_ALLOC),
+    help    = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_HELP),
+//    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_32M), value = 1, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_64M), value = 2, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_96M), value = 3, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_128M), value = 4, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_160M), value = 5, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_192M), value = 6, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_224M), value = 7, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_256M), value = 8, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_288M), value = 9, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_320M), value = 10, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_352M), value = 11, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_384M), value = 12, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_416M), value = 13, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_448M), value = 14, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_480M), value = 15, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_512M), value = 16, flags = RESET_REQUIRED;
+  endoneof;
+
+  oneof   varid   = Setup.IgdDvmt50TotalAlloc,
+    prompt  = STRING_TOKEN(STR_DVMT50_DVMT ),
+    help    = STRING_TOKEN(STR_DVMT50_DVMT_HELP),
+    option text = STRING_TOKEN(STR_DVMT50_ALLOC_128), value = 1, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DVMT50_ALLOC_256), value = 2, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DVMT50_ALLOC_MAX), value = 3, flags = RESET_REQUIRED;
+  endoneof;
+
+  //
+  //Igd Thermal
+  //
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+
+  subtitle text = STRING_TOKEN(STR_IGD_LCD_CONTROL);
+
+  oneof varid    = Setup.LidStatus,
+    prompt   = STRING_TOKEN(STR_FORCE_LID_STATUS_PROMPT),
+    help     = STRING_TOKEN(STR_FORCE_LID_STATUS_ENBDT_HELP),
+    option text = STRING_TOKEN(STR_LID_STATUS__OFF_PROMPT), value = 0, flags = 0 | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_LID_STATUS__ON_PROMPT), value = 1, flags = 0 | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_LID_STATUS__AUTO_PROMPT), value = 2, flags = MANUFACTURING| DEFAULT| RESET_REQUIRED;
+  endoneof;
+
+  oneof varid    = Setup.IgdLcdIBia,
+    prompt   = STRING_TOKEN(STR_VIDEO_LCD_IBIA),
+    help     = STRING_TOKEN(STR_VIDEO_LCD_IBIAHLP),
+    option text = STRING_TOKEN(STR_VIDEO_LCD_IBIAA), value = 0, flags =MANUFACTURING| DEFAULT| RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_VIDEO_LCD_IBIAD), value = 1, flags = 0| RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_VIDEO_LCD_IBIAL1), value = 2, flags = 0| RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_VIDEO_LCD_IBIAL2), value = 3, flags = 0| RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_VIDEO_LCD_IBIAL3), value = 4, flags = 0| RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_VIDEO_LCD_IBIAL4), value = 5, flags = 0| RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_VIDEO_LCD_IBIAL5), value = 6, flags = 0| RESET_REQUIRED;
+  endoneof;
+
+  oneof varid  = Setup.AlsEnable,
+    prompt   = STRING_TOKEN (STR_ACPI_ALS_ENABLE),
+    help     = STRING_TOKEN (STR_ACPI_ALS_ENABLE_HELP),
+    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=DEFAULT | MANUFACTURING | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_ENABLE),  value=1, flags=0 | RESET_REQUIRED;
+  endoneof;
+
+
+  oneof   varid   = Setup.IgdFlatPanel,
+    prompt      = STRING_TOKEN(STR_IGD_FLAT_PANEL_PROMPT),
+    help        = STRING_TOKEN(STR_IGD_FLAT_PANEL_HELP),
+    option text = STRING_TOKEN(STR_AUTOMATIC), value=0x00, flags=DEFAULT | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_640X480), value=0x01, flags=RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_800X600), value=0x02, flags=RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_1024X768), value=0x03, flags=RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_1280X1024), value=0x04, flags=RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_1366X768), value=0x05, flags=RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_1680X1050), value=0x06, flags=RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_1920X1200), value=0x07, flags=RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_1280X800), value=0x08, flags=RESET_REQUIRED;
+  endoneof;
+
+  oneof   varid   = Setup.BootDisplayDevice,
+    prompt      = STRING_TOKEN(STR_BOOT_DISPLAY_DEVICE_PROMPT),
+    help        = STRING_TOKEN(STR_BOOT_DISPLAY_DEVICE_HELP),
+    option text = STRING_TOKEN(STR_AUTOMATIC), value=0x00, flags=DEFAULT | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_VGAPORT), value=0x01, flags=RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_HDMIPORTB), value=0x02, flags=RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DPPORTB), value=0x03, flags=RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DPPORTC), value=0x04, flags=RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_EDPPORTC), value=0x05, flags=RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DSIPORTA), value=0x06, flags=RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DSIPORTC), value=0x07, flags=RESET_REQUIRED;
+
+  endoneof;
+  //
+  //Pannel Scaling
+  //
+  oneof   varid   = Setup.PanelScaling,
+    prompt      = STRING_TOKEN(STR_PANNEL_SCALING_PROMPT),
+    help        = STRING_TOKEN(STR_PANNEL_SCALING_HELP),
+    option text = STRING_TOKEN(STR_AUTOMATIC), value=0x00, flags=DEFAULT | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_PANNEL_SCALING_STRETCH), value=0x01, flags=RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_PANNEL_SCALING_CENTER), value=0x02, flags=RESET_REQUIRED;
+  endoneof;
+
+  //
+  //GMCH BLC Control
+  //
+  oneof   varid   = Setup.IgdLcdIGmchBlc,
+    prompt      = STRING_TOKEN(STR_VIDEO_LCD_IGMCHBLC_PROMPT),
+    help        = STRING_TOKEN(STR_VIDEO_LCD_IGMCHBLC_HELP),
+    option text = STRING_TOKEN(STR_VIDEO_LCD_IGMCHBLC1), value=0x00, flags=DEFAULT | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_VIDEO_LCD_IGMCHBLC2), value=0x01, flags=RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_VIDEO_LCD_IGMCHBLC3), value=0x02, flags=RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_VIDEO_LCD_IGMCHBLC4), value=0x03, flags=RESET_REQUIRED;
+  endoneof;
+
+  subtitle text = STRING_TOKEN(STR_NULL_STRING);
+  //
+  //ISP Configuration
+  //
+  subtitle text = STRING_TOKEN(STR_ISP_CONFIGURATION_TITLE);
+
+  oneof varid   = Setup.ISPEn,
+    prompt      = STRING_TOKEN(STR_ISP_ENABLED),
+    help        = STRING_TOKEN(STR_ISP_ENABLED_HELP),
+    option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT | RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+  endoneof;
+
+  grayoutif ideqval Setup.ISPEn == 0;
+    oneof varid  = Setup.ISPDevSel,
+      prompt   = STRING_TOKEN (STR_ISP_PCICONFIGURATION_TITLE),
+      help     = STRING_TOKEN (STR_ISP_PCICONFIGURATION_HELP),
+      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_ISP_PCICONFIG_B0D2F0_TITLE), value = 1, flags = MANUFACTURING | DEFAULT | RESET_REQUIRED;
+      option text = STRING_TOKEN(STR_ISP_PCICONFIG_B0D3F0_TITLE), value = 2, flags = RESET_REQUIRED;
+   endoneof;
+  endif;
+
+endform;
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UqiList.uni b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UqiList.uni
new file mode 100644
index 0000000000..504539a02f
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UqiList.uni
@@ -0,0 +1,452 @@
+// /** @file
+//
+// Copyright (c) 2013 - 2016 Intel Corporation. All rights reserved
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+// Module Name:
+//
+//   UqiList.uni
+//
+// Abstract:
+//
+//   UQI (Universal Question Identifier) allocation for setup options.
+//
+//   This file should define UQIs in the following range only: [0x0000...0x7FFF]
+//
+// **/
+
+/=#
+
+//----------------------------------------------------------------------------
+//
+//   Purpose: The translations in this file are intended to be globally
+//   consistent.  All products should use the same translation for the
+//   same functional question.
+//
+//   Usage:
+//
+//   1. DO NOT OVERRIDE THIS FILE!
+//      The translations in this file should be globally consistent across
+//      all of our products.
+//
+//   2. Never delete tokens from this file
+//
+//   3. When adding a new question:
+//
+//      * Always do a thorough check of the tokens below to determine if
+//        a question is already represented.  This is important, because
+//        we want to generate scripts based on these tokens which will
+//        work on our entire product line.
+//
+//      * Always choose the first available new token number for your
+//        new token.  Do not worry about "grouping" your questions
+//        together.  That goal will only make it more difficult to manage
+//        the token numbering.  Always add your new token to the correct
+//        place to preserve numerical ordering.  This makes it easy to
+//        determine which token should be used next.
+//
+//----------------------------------------------------------------------------
+
+#langdef uqi "uqi"
+
+//
+// Keep in numerical order to prevent token reuse
+//
+#string STR_FAST_BOOT_PROMPT                            #language uqi  "\x0001"
+#string STR_MEMORY_CHECK_SETUP                          #language uqi  "\x0002"
+#string STR_NUM_AUTO_BOOT                               #language uqi  "\x0003"
+#string STR_LOAD_OPTION_FORCE_RECON                     #language uqi  "\x0004"
+#string STR_ONE_OF_PROMPT                               #language uqi  "\x0005"
+#string STR_CHECK_BOX_PROMPT                            #language uqi  "\x0006"
+#string STR_TEST_OPCODE                                 #language uqi  "\x0007"
+#string STR_TEST_OPCODE2                                #language uqi  "\x0008"
+#string STR_ERROR_POPUP                                 #language uqi  "\x0009"
+#string STR_NUMERIC_READONLY_PROMPT                     #language uqi  "\x000A"
+#string STR_NUMERIC_MANUAL_PROMPT                       #language uqi  "\x000B"
+#string STR_TALL_HEX_PROMPT                             #language uqi  "\x000C"
+#string STR_NAME_VALUE_VAR_NAME0                        #language uqi  "\x000D"
+#string STR_NAME_VALUE_VAR_NAME1                        #language uqi  "\x000E"
+#string STR_NUMERIC_STEP_PROMPT                         #language uqi  "\x000F"
+#string STR_DEFAULT_VALUE_FROM_ACCESS_PROMPT            #language uqi  "\x0010"
+#string STR_DEFAULT_VALUE_FROM_CALLBACK_PROMPT          #language uqi  "\x0011"
+#string STR_SERIAL_PORT                                 #language uqi  "\x0012"
+#string STR_SERIAL_PORT_STATUS                          #language uqi  "\x0013"
+#string STR_SERIAL_PORT_IO_ADDRESS                      #language uqi  "\x0014"
+#string STR_SERIAL_PORT_IRQ                             #language uqi  "\x0015"
+#string STR_TEXT_REFRESH_GUID_COUNT                     #language uqi  "\x0016"
+#string STR_IP4_CONFIGURE                               #language uqi  "\x0017"
+#string STR_IP4_ENABLE_DHCP                             #language uqi  "\x0018"
+#string STR_ISCSI_DEVICE_ENABLE                         #language uqi  "\x0019"
+#string STR_ISCSI_ENABLE_DHCP                           #language uqi  "\x001A"
+#string STR_ISCSI_ENABLE_DHCP_ON_TARGET                 #language uqi  "\x001B"
+#string STR_ISCSI_TARGET_PORT                           #language uqi  "\x001C"
+#string STR_CHAP_TYPE_PROMPT                            #language uqi  "\x001D"
+#string STR_VLAN_VID_PROMPT                             #language uqi  "\x001E"
+#string STR_VLAN_PRIORITY_PROMPT                        #language uqi  "\x001F"
+#string STR_PCI_DEVICE_FILTER_PROMPT                    #language uqi  "\x0020"
+#string STR_IP6_DAD_TRANSMIT_COUNT                      #language uqi  "\x0021"
+#string STR_POLICY_TYPE_PROMPT                          #language uqi  "\x0022"
+#string STR_ISCSI_MODE_PROMPT                           #language uqi  "\x0023"
+#string STR_IP_MODE_PROMPT                              #language uqi  "\x0024"
+#string STR_ISCSI_CONFIG_RETRY                          #language uqi  "\x0025"
+#string STR_ISCSI_CONFIG_TIMEOUT                        #language uqi  "\x0026"
+#string STR_AUTHEN_TYPE_PROMPT                          #language uqi  "\x0027"
+#string STR_NULL                                        #language uqi  "\x0028"
+#string STR_HIDE_TPM_PROMPT                             #language uqi  "\x0029"
+#string STR_TPM_OPERATION                               #language uqi  "\x002A"
+#string STR_MOR_PROMPT                                  #language uqi  "\x002B"
+#string STR_SECURE_BOOT_PROMPT                          #language uqi  "\x002C"
+#string STR_USB_SUPPORT                                 #language uqi  "\x002D"
+#string STR_USB_LEGACY_SUPPORT                          #language uqi  "\x002E"
+#string STR_USB_XHCI_SUPPORT                            #language uqi  "\x002F"
+#string STR_USB_BIOS_XHCI_HANDOFF                       #language uqi  "\x0030"
+#string STR_USB_BIOS_EHCI_HANDOFF                       #language uqi  "\x0031"
+#string STR_USB_6064                                    #language uqi  "\x0032"
+#string STR_USB_HOTPLUG_FDD                             #language uqi  "\x0033"
+#string STR_USB_HOTPLUG_HDD                             #language uqi  "\x0034"
+#string STR_USB_HOTPLUG_CDROM                           #language uqi  "\x0035"
+#string STR_USB_CONTROL_TIME_OUT                        #language uqi  "\x0036"
+#string STR_USB_MASS_RESET_DELAY                        #language uqi  "\x0037"
+#string STR_USB_POWERGOOD_DELAY                         #language uqi  "\x0038"
+#string STR_USB_DELAY_NUM_VALUE                         #language uqi  "\x0039"
+#string STR_USB_MASS_DEVICE1                            #language uqi  "\x003A"
+#string STR_USB_MASS_DEVICE2                            #language uqi  "\x003B"
+#string STR_USB_MASS_DEVICE3                            #language uqi  "\x003C"
+#string STR_USB_MASS_DEVICE4                            #language uqi  "\x003D"
+#string STR_USB_MASS_DEVICE5                            #language uqi  "\x003E"
+#string STR_USB_MASS_DEVICE6                            #language uqi  "\x003F"
+#string STR_USB_MASS_DEVICE7                            #language uqi  "\x0040"
+#string STR_USB_MASS_DEVICE8                            #language uqi  "\x0041"
+#string STR_USB_MASS_DEVICE9                            #language uqi  "\x0042"
+#string STR_USB_MASS_DEVICE10                           #language uqi  "\x0043"
+#string STR_USB_MASS_DEVICE11                           #language uqi  "\x0044"
+#string STR_USB_MASS_DEVICE12                           #language uqi  "\x0045"
+#string STR_USB_MASS_DEVICE13                           #language uqi  "\x0046"
+#string STR_USB_MASS_DEVICE14                           #language uqi  "\x0047"
+#string STR_USB_MASS_DEVICE15                           #language uqi  "\x0048"
+#string STR_USB_MASS_DEVICE16                           #language uqi  "\x0049"
+#string STR_SECURITY_BOOT_PROMPT                        #language uqi  "\x004A"
+#string STR_QUIETBOOT_PROMPT                            #language uqi  "\x004B"
+#string STR_LOG_BOOT_TIME_PROMPT                        #language uqi  "\x004C"
+#string STR_EXECUTE_DISABLE_BIT_PROMPT                  #language uqi  "\x004D"
+#string STR_LIMIT_CPUID_MAX_PROMPT                      #language uqi  "\x004E"
+#string STR_PROC_HOT_ENABLE                             #language uqi  "\x004F"
+#string STR_VTX2_PROMPT                                 #language uqi  "\x0050"
+#string STR_CORE_FRE_MULTIP_SELECT_PROMPT               #language uqi  "\x0051"
+#string STR_TM1_PROMPT                                  #language uqi  "\x0052"
+#string STR_TM2_PROMPT                                  #language uqi  "\x0053"
+#string STR_DTS_PROMPT                                  #language uqi  "\x0054"
+#string STR_ACTIVE_PROCESSOR_CORES_PROMPT               #language uqi  "\x0055"
+#string STR_CPU_IST_PROMPT                              #language uqi  "\x0056"
+#string STR_BOOT_P_STATE                                #language uqi  "\x0057"
+#string STR_PROCESSOR_TURBO_MODE                        #language uqi  "\x0058"
+#string STR_CSTATE_PROMPT                               #language uqi  "\x0059"
+#string STR_CXE_PROMPT                                  #language uqi  "\x005A"
+#string STR_HARDC4E_PROMPT                              #language uqi  "\x005B"
+#string STR_MAX_C_STATE_SUPPORT_PROMPT                  #language uqi  "\x005C"
+#string STR_PPM_C4_EXIT_PROMPT                          #language uqi  "\x005D"
+#string STR_CX_POPDOWN_PROMPT                           #language uqi  "\x005E"
+#string STR_CX_POPUP_PROMPT                             #language uqi  "\x005F"
+#string STR_SEC_SETTING_PROMPT                          #language uqi  "\x0060"
+#string STR_SEC_FLASH_UPDATE_PROMPT                     #language uqi  "\x0061"
+#string STR_SEC_FIRMWARE_UPDATE_PROMPT                  #language uqi  "\x0062"
+#string STR_FIRMWARE_TPM_PROMPT                         #language uqi  "\x0063"
+#string STR_TPM_PROMPT                                  #language uqi  "\x0064"
+#string STR_TDT_CONFIG_PROMPT                           #language uqi  "\x0065"
+#string STR_TDT_RECOVERY_PROMPT                         #language uqi  "\x0066"
+#string STR_TDT_SUSPEND_PROMPT                          #language uqi  "\x0067"
+#string STR_ICH_PCIERP1_PROMPT                          #language uqi  "\x0068"
+#string STR_ICH_PCIERP2_PROMPT                          #language uqi  "\x0069"
+#string STR_ICH_PCIERP3_PROMPT                          #language uqi  "\x006A"
+#string STR_ICH_PCIERP4_PROMPT                          #language uqi  "\x006B"
+#string STR_USB_DEBUG_PROMPT                            #language uqi  "\x006C"
+#string STR_USB_XHCI_SUPPORT_PROMPT                     #language uqi  "\x006D"
+#string STR_PCH_USB21_PROMPT                            #language uqi  "\x006E"
+#string STR_PCH_USB30_MODE_PROMPT                       #language uqi  "\x006F"
+#string STR_PCH_USB30_STREAMS                           #language uqi  "\x0070"
+#string STR_PCH_USB_PER_PORT_PROMPT                     #language uqi  "\x0071"
+#string STR_PCH_USB_PORT0_PROMPT                        #language uqi  "\x0072"
+#string STR_PCH_USB_PORT1_PROMPT                        #language uqi  "\x0073"
+#string STR_PCH_USB_PORT2_PROMPT                        #language uqi  "\x0074"
+#string STR_PCH_USB_PORT3_PROMPT                        #language uqi  "\x0075"
+#string STR_PCH_USBRMH_PROMPT                           #language uqi  "\x0076"
+#string STR_SATA_PROMPT                                 #language uqi  "\x0077"
+#string STR_SATA_TYPE_PROMPT                            #language uqi  "\x0078"
+#string STR_SATA0_HOTPLUG_CAP_PROMPT                    #language uqi  "\x0079"
+#string STR_SATA1_HOTPLUG_CAP_PROMPT                    #language uqi  "\x007A"
+#string STR_LPSS_EMMC_PROMPT                            #language uqi  "\x007B"
+#string STR_LPSS_SDIO_PROMPT                            #language uqi  "\x007C"
+#string STR_LPSS_SDCARD_PROMPT                          #language uqi  "\x007D"
+#string STR_LPSS_DMA_PROMPT                             #language uqi  "\x007E"
+#string STR_LPSS_I2C1_PROMPT                            #language uqi  "\x007F"
+#string STR_LPSS_I2C2_PROMPT                            #language uqi  "\x0080"
+#string STR_LPSS_PCM_PROMPT                             #language uqi  "\x0081"
+#string STR_LPSS_I2S_PROMPT                             #language uqi  "\x0082"
+#string STR_LPSS_HSUART1_PROMPT                         #language uqi  "\x0083"
+#string STR_LPSS_HSUART2_PROMPT                         #language uqi  "\x0084"
+#string STR_LPSS_SPI_PROMPT                             #language uqi  "\x0085"
+#string STR_PCH_LAN_CONTROLLER                          #language uqi  "\x0086"
+#string STR_PCH_LAN_WOL_PROMPT                          #language uqi  "\x0087"
+#string STR_PCH_SLP_LAN_LOW_DC_PROMPT                   #language uqi  "\x0088"
+#string STR_PCH_PXEROM_CONTROL                          #language uqi  "\x0089"
+#string STR_LPE_PROMPT                                  #language uqi  "\x008A"
+#string STR_PCH_AZALIA_PROMPT                           #language uqi  "\x008B"
+#string STR_AZALIA_VC_PROMPT                            #language uqi  "\x008C"
+#string STR_AZALIA_DS_PROMPT                            #language uqi  "\x008D"
+#string STR_AZALIA_PME_PROMPT                           #language uqi  "\x008E"
+#string STR_HDMI_CODEC_PROMPT                           #language uqi  "\x008F"
+#string STR_HPET_PROMPT                                 #language uqi  "\x0090"
+#string STR_HPET_BOOTTIME_PROMPT                        #language uqi  "\x0091"
+#string STR_STATE_AFTER_G3                              #language uqi  "\x0092"
+#string STR_PCH_UART_SELECT                             #language uqi  "\x0093"
+#string STR_PCU_UART_A                                  #language uqi  "\x0094"
+#string STR_PCU_UART_B                                  #language uqi  "\x0095"
+#string STR_ACPI_CRITICAL_THERMAL_TRIP_POINT            #language uqi  "\x0096"
+#string STR_ACPI_PASSIVE_THERMAL_TRIP_POINT             #language uqi  "\x0097"
+#string STR_ACPI_PASSIVE_TC1_VALUE                      #language uqi  "\x0098"
+#string STR_ACPI_PASSIVE_TC2_VALUE                      #language uqi  "\x0099"
+#string STR_ACPI_PASSIVE_TSP_VALUE                      #language uqi  "\x009A"
+#string STR_DPTF_PROMPT                                 #language uqi  "\x009B"
+#string STR_LPM_PROMPT                                  #language uqi  "\x009C"
+#string STR_CTDP_PROMPT                                 #language uqi  "\x009D"
+#string STR_MEMORY_PROMPT                               #language uqi  "\x009E"
+#string STR_DPTF_ACTIVE_TRIP_POINT_PROMPT               #language uqi  "\x009F"
+#string STR_DPTF_PASSIVE_TRIP_POINT_PROMPT              #language uqi  "\x00A0"
+#string STR_SKIN_SENSOR_PROMPT                          #language uqi  "\x00A1"
+#string STR_PCH_PROMPT                                  #language uqi  "\x00A2"
+#string STR_PRIMARY_DISPLAY                             #language uqi  "\x00A3"
+#string STR_VIDEO_RS2_PROMPT                            #language uqi  "\x00A4"
+#string STR_DVMT40_PRE_ALLOC                            #language uqi  "\x00A5"
+#string STR_GFX_BOOST_PROMPT                            #language uqi  "\x00A6"
+#string STR_IGD_THERMAL_PROMPT                          #language uqi  "\x00A7"
+#string STR_SPREAD_SPECTRUM_CLOCK_PROMPT                #language uqi  "\x00A8"
+#string STR_VIDEO_LCD_IBIA                              #language uqi  "\x00A9"
+#string STR_ACPI_ALS_ENABLE                             #language uqi  "\x00AA"
+#string STR_IGD_FLAT_PANEL_PROMPT                       #language uqi  "\x00AB"
+#string STR_BOOT_DISPLAY_DEVICE_PROMPT                  #language uqi  "\x00AC"
+#string STR_PANNEL_SCALING_PROMPT                       #language uqi  "\x00AD"
+#string STR_VIDEO_LCD_IGMCHBLC_PROMPT                   #language uqi  "\x00AE"
+#string STR_MEMORY_SCRAMBLER_PROMPT                     #language uqi  "\x00AF"
+#string STR_CSTATE_C4                                   #language uqi  "\x00B0"
+#string STR_CSTATE_C6                                   #language uqi  "\x00B1"
+#string STR_SEC_EOP_PROMPT                              #language uqi  "\x00B2"
+#string STR_PCH_USB_PORT4_PROMPT                        #language uqi  "\x00B3"
+#string STR_PCH_USB_PORT5_PROMPT                        #language uqi  "\x00B4"
+#string STR_PCH_USB_PORT6_PROMPT                        #language uqi  "\x00B5"
+#string STR_PCH_USB_PORT7_PROMPT                        #language uqi  "\x00B6"
+#string STR_HDMI_CODEC_PORTB_PROMPT                     #language uqi  "\x00B7"
+#string STR_HDMI_CODEC_PORTC_PROMPT                     #language uqi  "\x00B8"
+#string STR_HDMI_CODEC_PORTD_PROMPT                     #language uqi  "\x00B9"
+#string STR_CONVERT_BOARD_SELECT                        #language uqi  "\x00BA"
+#string STR_DPTF_CLPM_PROMPT                            #language uqi  "\x00BB"
+#string STR_PROCESSOR_DPTF_PROMPT                       #language uqi  "\x00BC"
+#string STR_DPTF_SYSTHERM0_PROMPT                       #language uqi  "\x00BD"
+#string STR_DPTF_SYSTHERM1_PROMPT                       #language uqi  "\x00BE"
+#string STR_DPTF_SYSTHERM2_PROMPT                       #language uqi  "\x00BF"
+#string STR_DPTF_SYSTHERM3_PROMPT                       #language uqi  "\x00C0"
+#string STR_DPTF_CHARGER_PROMPT                         #language uqi  "\x00C1"
+#string STR_DPTF_DISPLAY_PROMPT                         #language uqi  "\x00C2"
+#string STR_DPTF_SOC_PROMPT                             #language uqi  "\x00C3"
+#string STR_GOP_VBIOS_SWITCH                            #language uqi  "\x00C4"
+#string STR_PAVC_PROMPT                                 #language uqi  "\x00C5"
+#string STR_GTT_SIZE                                    #language uqi  "\x00C6"
+#string STR_APERTURE_SIZE                               #language uqi  "\x00C7"
+#string STR_DVMT50_PRE_ALLOC                            #language uqi  "\x00C8"
+#string STR_FORCE_LID_STATUS_PROMPT                     #language uqi  "\x00C9"
+#string STR_TREE_DEVICE_PROMPT                          #language uqi  "\x00CA"
+#string STR_TPM2_REVOKE_TRUST_PROMPT                    #language uqi  "\x00CB"
+#string STR_PCH_USB_OTG_PROMPT                          #language uqi  "\x00CC"
+#string STR_LPSS_PCI_PROMPT                             #language uqi  "\x00CD"
+#string STR_SCC_EMMC_PROMPT                             #language uqi  "\x00CE"
+#string STR_SCC_SDIO_PROMPT                             #language uqi  "\x00CF"
+#string STR_SCC_SDCARD_PROMPT                           #language uqi  "\x00D0"
+#string STR_MIPI_HSI_PROMPT                             #language uqi  "\x00D1"
+#string STR_LPSS_DMA1_PROMPT                            #language uqi  "\x00D2"
+#string STR_LPSS_DMA2_PROMPT                            #language uqi  "\x00D3"
+#string STR_LPSS_I2C3_PROMPT                            #language uqi  "\x00D4"
+#string STR_LPSS_I2C4_PROMPT                            #language uqi  "\x00D5"
+#string STR_LPSS_I2C5_PROMPT                            #language uqi  "\x00D6"
+#string STR_LPSS_I2C6_PROMPT                            #language uqi  "\x00D7"
+#string STR_LPSS_I2C7_PROMPT                            #language uqi  "\x00D8"
+#string STR_PWM1_PROMPT                                 #language uqi  "\x00D9"
+#string STR_PWM2_PROMPT                                 #language uqi  "\x00DA"
+#string STR_LPSS_LPE_PROMPT                             #language uqi  "\x00DB"
+#string STR_PMIC_ACPI_OBJECT_PROMPT                     #language uqi  "\x00DC"
+#string STR_S0IX_PROMPT                                 #language uqi  "\x00DD"
+#string STR_DPTF_CRITICAL_TEMP                          #language uqi  "\x00DE"
+#string STR_DPTF_PASSIVE_TEMP                           #language uqi  "\x00DF"
+#string STR_DPTF_SDBG                                   #language uqi  "\x00E0"
+#string STR_DPTF_CLPO                                   #language uqi  "\x00E1"
+#string STR_DPTF_CLPO_START_PINDEX                      #language uqi  "\x00E2"
+#string STR_DPTF_CLPO_STEP_SIZE                         #language uqi  "\x00E3"
+#string STR_DPTF_CLPO_PWR_CTRL                          #language uqi  "\x00E4"
+#string STR_DPTF_CLPO_PERF_CTRL                         #language uqi  "\x00E5"
+#string STR_DPTF_DPPM                                   #language uqi  "\x00E6"
+#string STR_ISP_ENABLED                                 #language uqi  "\x00E7"
+#string STR_ISP_PCICONFIGURATION_TITLE                  #language uqi  "\x00E8"
+#string STR_IGD_PROMPT                                  #language uqi  "\x00E9"
+#string STR_PNP_SETTING_PROMPT                          #language uqi  "\x00EA"
+#string STR_DPTF_SYSTHERM4_PROMPT                       #language uqi  "\x00EB"
+#string STR_ACPIMEMDBG_SWTICH                           #language uqi  "\x00EC"
+#string STR_SECURE_BOOT                                 #language uqi  "\x00ED"
+#string STR_SECURE_BOOT_MODE                            #language uqi  "\x00EE"
+#string STR_PCIE_SPEED_PROMPT0                          #language uqi  "\x00EF"
+#string STR_PCIE_SPEED_PROMPT1                          #language uqi  "\x00F0"
+#string STR_PCIE_SPEED_PROMPT2                          #language uqi  "\x00F1"
+#string STR_PCIE_SPEED_PROMPT3                          #language uqi  "\x00F2"
+#string STR_SATA_TEST_MODE_PROMPT                       #language uqi  "\x00F3"
+#string STR_CLOCK_SPREAD_SPEC_ENABLE                    #language uqi  "\x00F4"
+#string STR_BATTERY_ACPI_OBJECT_PROMPT                  #language uqi  "\x00F5"
+#string STR_MFGMODE                                     #language uqi  "\x00F6"
+#string STR_PCH_USB_VBUS_PROMPT                         #language uqi  "\x00F7"
+#string STR_PCH_USB_EHCIDEBUG_PROMPT                    #language uqi  "\x00F8"
+#string STR_CRID_PROMPT                                 #language uqi  "\x00F9"
+#string STR_GOP_BRIGHTNESS_LEVEL                        #language uqi  "\x00FA"
+#string STR_ULPMC_FW_LOCK_PROMPT                        #language uqi  "\x00FC"
+#string STR_SECURE_BOOT_MODE_PROMPT                     #language uqi  "\x00FD"
+#string STR_DELETE_PK                                   #language uqi  "\x00FE"
+#string STR_I2C_TOUCH_PROMPT                            #language uqi  "\x00FF"
+#string STR_PCH_SPI_WP_PROMPT                           #language uqi  "\x0100"
+#string STR_PMWEIGHTS_PROMPT                            #language uqi  "\x0101"
+#string STR_FORM_BOOT_CHG_TITLE                         #language uqi  "\x0102"
+#string STR_FORM_DRV_CHG_TITLE                          #language uqi  "\x0103"
+#string STR_TALL_MANUAL_PROMPT                          #language uqi  "\x0104"
+#string STR_NUMERIC_PROMPT                              #language uqi  "\x0105"
+#string STR_NUMERIC_PROMPT1                             #language uqi  "\x0106"
+#string STR_ACTIVE_CORE_COUNT_PROMPT                    #language uqi  "\x0107"
+#string STR_PBA_CONFIG_PROMPT                           #language uqi  "\x0108"
+#string STR_IGD_TURBO_PROMPT                            #language uqi  "\x0109"
+#string STR_IGD_TURBO_HELP                              #language uqi  "\x010A"
+#string STR_EHCI_PLL_CFG_PROMPT                         #language uqi  "\x010B"
+#string STR_EHCI_PLL_CFG_RTD3_DIS_HELP                  #language uqi  "\x010C"
+#string STR_LM_MEMORY_PROMPT                            #language uqi  "\x010D"
+#string STR_PDM_OUTPUT_CONFIG_SWTICH                    #language uqi  "\x010E"
+#string STR_PUINT_BIOS_CONFIG_DISPLAY                   #language uqi  "\x010F"
+#string STR_SCC_SDIO_MODE_PROMPT                        #language uqi  "\x0110"
+#string STR_ISCT_CONFIGURATION                          #language uqi  "\x0111"
+#string STR_ISCT_NOTIFICATION_CONTROL_PROMPT            #language uqi  "\x0112"
+#string STR_ISCT_WLAN_CONTROL_PROMPT                    #language uqi  "\x0113"
+#string STR_ISCT_WWAN_CONTROL_PROMPT                    #language uqi  "\x0114"
+#string STR_EXISUPPORT_PROMPT                           #language uqi  "\x0115"
+#string STR_PCH_FSA_PROMPT                              #language uqi  "\x0116"
+#string STR_PCH_FSA_HELP                                #language uqi  "\x0117"
+#string STR_USB_AUTO_MODE_PROMPT                        #language uqi  "\x0118"
+#string STR_SCC_EMMC45_PROMPT                           #language uqi  "\x0119"
+#string STR_SCC_EMMC45_HELP                             #language uqi  "\x011A"
+#string STR_SCC_EMMC45_DDR50_PROMPT                     #language uqi  "\x011B"
+#string STR_SCC_EMMC45_DDR50_HELP                       #language uqi  "\x011C"
+#string STR_SCC_EMMC45_HS200_PROMPT                     #language uqi  "\x011D"
+#string STR_SCC_EMMC45_HS200_HELP                       #language uqi  "\x011E"
+#string STR_SCC_EMMC45_RE_TUNE_TIMER_VALUE              #language uqi  "\x011F"
+#string STR_SCC_EMMC45_RE_TUNE_TIMER_VALUE_HELP         #language uqi  "\x0120"
+#string STR_CFIO_PNP_SETTING_PROMPT                     #language uqi  "\x0121"
+#string STR_CFIO_PNP_SETTING_HELP                       #language uqi  "\x0122"
+#string STR_EMMC_BOOT_PROMPT                            #language uqi  "\x0123"
+#string STR_EMMC_BOOT_HELP                              #language uqi  "\x0124"
+#string STR_WITT_PROMPT                                 #language uqi  "\x0125"
+#string STR_SECURE_BOOT_TEST_PROMPT                     #language uqi  "\x0126"
+#string STR_TRISTATE_LPC_PROMPT                         #language uqi  "\x0127"
+#string STR_DOP_CG_PROMPT                               #language uqi  "\x0128"
+#string STR_PSS_ENABLE_PROMPT                           #language uqi  "\x0129"
+#string STR_PSS_ENABLE_HELP                             #language uqi  "\x012A"
+#string STR_ISCT_SLEEP_DURATION_FORMAT                  #language uqi  "\x012B"
+#string STR_ISCT_RF_KILL_SUPPORT                        #language uqi  "\x012C"
+#string STR_SECURE_BOOT_UPP_PROMPT                      #language uqi  "\x012D"
+#string STR_MEASURED_BOOT_ENABLE_PROMPT                 #language uqi  "\x012E"
+#string STR_MEASURED_BOOT_ENABLE_HELP                   #language uqi  "\x012F"
+#string STR_PTT_PROMPT                                  #language uqi  "\x0130"
+#string STR_CHECK_SHA256_HASH_MASTER_BOOT_CODES         #language uqi  "\x0131"
+#string STR_USB_XHCI_LPM_SUPPORT_PROMPT      #language uqi  "\x0132"
+
+#string STR_VIRTUAL_KB_PROMPT                           #language uqi  "\x0135"
+#string STR_VIRTUAL_KB_HELP                             #language uqi  "\x0136"
+#string STR_TREE_OPERATION                              #language uqi  "\x0137"
+#string STR_SLP_S0IX_N_PROMPT                           #language uqi  "\x0138"
+#string STR_SLP_S0IX_N_HELP                             #language uqi  "\x0139"
+#string STR_DPTF_AMBIENTTRIPPOINTCHANGE_PROMPT          #language uqi  "\x013A"
+#string STR_DPTF_THERM0_PCAT_PROMPT                     #language uqi  "\x013B"
+#string STR_DPTF_THERM1_PCAT_PROMPT                     #language uqi  "\x013C"
+#string STR_DPTF_THERM2_PCAT_PROMPT                     #language uqi  "\x013D"
+#string STR_MMIO_PROMPT                                 #language uqi  "\x013E"
+#string STR_UTS_PROMPT                                 #language uqi  "\x013F"
+#string STR_UTS_HELP                                   #language uqi  "\x0140"
+#string STR_WLAN_NGFF_CARD                              #language uqi  "\x0141"
+#string STR_WLAN_UHPAM_CARD                             #language uqi  "\x0142"
+#string STR_ENABLE_DBG2                                 #language uqi  "\x0143"
+#string STR_DPTF_ALLOWHIGHERPERFORMANCE_PROMPT          #language uqi  "\x0144"
+#string STR_DATP_PROMPT                                 #language uqi  "\x0145"
+#string STR_DPTF_OFFLINING                              #language uqi  "\x0146"
+#string STR_SAR_SENSOR_PROMPT                           #language uqi  "\x0147"
+#string STR_DPTF_BRAND_STRING                           #language uqi  "\x0148"
+#string STR_CODEC262_DISABLED_PROMPT                    #language uqi  "\x0149"
+#string STR_CODEC262_DISABLED_HELP                      #language uqi  "\x014A"
+
+//SD CARD SDR25 and DDR50
+#string STR_SCC_SD_SDR25_PROMPT                         #language uqi  "\x014B"
+#string STR_SCC_SD_SDR25_HELP                           #language uqi  "\x014C"
+#string STR_SCC_SD_DDR50_PROMPT                         #language uqi  "\x014D"
+#string STR_SCC_SD_DDR50_HELP                           #language uqi  "\x014E"
+#string STR_SB_PROFILE_PROMPT                           #language uqi  "\x014F"
+#string STR_SECURE_BOOT_PRO_KEY_PROMPT                  #language uqi  "\x0150"
+
+#string STR_OS_SELETION_PROMPT                          #language uqi  "\x0151"
+#string STR_OS_SELETION_HELP                            #language uqi  "\x0152"
+#string STR_WINDOWS                                     #language uqi  "\x0153"
+#string STR_ANDROID                                     #language uqi  "\x0154"
+#string STR_AESNI_PROMPT                                #language uqi  "\x0155"
+
+#string STR_LPSS_I2C1_HELP_ENBDT_DEV_LIST               #language uqi  "\x0156"
+#string STR_LPSS_I2C2_HELP_ENBDT_DEV_LIST               #language uqi  "\x0157"
+#string STR_LPSS_I2C3_HELP_ENBDT_DEV_LIST               #language uqi  "\x0158"
+#string STR_LPSS_I2C4_HELP_ENBDT_DEV_LIST               #language uqi  "\x0159"
+#string STR_LPSS_I2C5_HELP_ENBDT_DEV_LIST               #language uqi  "\x015A"
+#string STR_LPSS_I2C6_HELP_ENBDT_DEV_LIST               #language uqi  "\x015B"
+#string STR_LPSS_I2C7_HELP_ENBDT_DEV_LIST               #language uqi  "\x015C"
+#string STR_LPSS_HSUART1_HELP_ENBDT_DEV_LIST            #language uqi  "\x015D"
+#string STR_LPSS_HSUART2_HELP_ENBDT_DEV_LIST            #language uqi  "\x015E"
+
+#string STR_SECURE_ERASE_PROMPT                         #language uqi  "\x015F"
+#string STR_SEC_FIRMWARE_WRITE_PROMPT                   #language uqi  "\x0160"
+
+#string STR_BOOT_DISPLAY_MIPIDSI_PROMPT                 #language uqi  "\x0161"
+#string STR_SEC_FIRMWARE_TOGGLE_PROMPT                  #language uqi  "\x0162"
+#string STR_PCIEDYNCLK_PROMPT                           #language uqi  "\x0163"
+#string STR_PAVP_LITE_MODE                              #language uqi  "\x0164"
+#string STR_PAVP_SERPENT_MODE                           #language uqi  "\x0165"
+#string STR_SCC_SDCARD_FORWIN_PROMPT                    #language uqi  "\x0166"
+#string STR_DROIDBOOT_PROMPT                            #language uqi  "\x0167"
+#string STR_ANDROIDBOOT_PROMPT                          #language uqi  "\x0168"
+
+#string STR_CRITICAL_BATTERY_LIMIT_PROMPT    #language uqi  "\x0169"
+#string STR_CRITICAL_BATTERY_LIMIT_HELP      #language uqi  "\x016A"
+#string STR_CRITICAL_BATTERY_LIMIT_FEATURE_PROMPT  #language uqi  "\x016B"
+#string STR_CRITICAL_BATTERY_LIMIT_FEATURE_HELP    #language uqi  "\x016C"
+#string STR_WINDOWS7                                    #language uqi  "\x016D"
+#string STR_LPSSDEVHIDE_PROMPT                          #language uqi  "\x016E"
+#string STR_EM1_IAAPPSRUN_PROMPT                        #language uqi  "\x016F"
+#string STR_EM1_IAAPPSCAP_PROMPT                        #language uqi  "\x0170"
+#string STR_EM1_CAP_OR_VOLTAGE_PROMPT                   #language uqi  "\x0171"
+#string STR_EM1_BOOT_ON_INVALID_BAT_PROMPT              #language uqi  "\x0172"
+
+#string STR_USB_HSIC_0_PROMPT                           #language uqi  "\x0173"
+#string STR_USB_HSIC_0_HELP                             #language uqi  "\x0174"
+#string STR_LEGACYUSBBOOTING_PROMPT                     #language uqi  "\x0175"
+#string STR_STR_LEGACYUSBBOOTING_HELP                   #language uqi  "\x0176"
+#string STR_LWINDOWS7                           #language uqi  "\x0177"
+#string STR_WEC7                                #language uqi  "\x0178"
+#string STR_LINUX                                #language uqi  "\x0179"
+#string STR_WARNING_POPUP                               #language uqi  "\x017A"
+#string STR_LPSS_HSUART1_FLOWCONTROL_PROMPT             #language uqi  "\x017B"
+#string STR_LPSS_HSUART2_FLOWCONTROL_PROMPT             #language uqi  "\x017C"
+#string STR_SCC_SDCARD_REMOVABILITY                     #language uqi  "\x017D"
+#string STR_SCC_SDCARD_REMOVABLE                        #language uqi  "\x017E"
+#string STR_SCC_SDCARD_NON_REMOVABLE                    #language uqi  "\x017F"
+#string STR_SCC_SDCARD_REMOVABILITY_HELP                #language uqi  "\x0180"
+#string STR_RTC_BATTERY                                 #language uqi  "\x0181"
+#string STR_RTC_BATTERY_NOT_PRESENT                     #language uqi  "\x0182"
+#string STR_RTC_BATTERY_PRESENT                         #language uqi  "\x0183"
+#string STR_RTC_BATTERY_HELP                            #language uqi  "\x0184"
+#string STR_LPE_REPORTED_BY_DSDT_PROMPT                 #language uqi  "\x0185"
+#string STR_LPE_REPORTED_BY_DSDT_HELP                   #language uqi  "\x0186"
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Vfr.vfr b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Vfr.vfr
new file mode 100644
index 0000000000..77976322de
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Vfr.vfr
@@ -0,0 +1,123 @@
+//
+//
+//
+// Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+//                                                                                  

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

+//
+//
+#include "Configuration.h"
+#include "PlatformSetupDxeStrDefs.h"
+#include "Guid/SetupVariable.h"
+
+formset
+  guid     = SYSTEM_CONFIGURATION_GUID,
+  title    = STRING_TOKEN(STR_SYSTEM_SETUP_TITLE),
+  help     = STRING_TOKEN(STR_SYSTEM_SETUP_HELP),
+  class    = 1,
+  subclass = 0,
+
+
+  varstore SYSTEM_CONFIGURATION, name = Setup, guid = SYSTEM_CONFIGURATION_GUID;
+  form formid = ROOT_FORM_ID,
+    title    = STRING_TOKEN(STR_SYSTEM_SETUP_TITLE);
+
+    //
+    // Jump to  2)Main Form
+    //
+    goto ROOT_MAIN_FORM_ID,
+      prompt = STRING_TOKEN(STR_MAIN_TITLE),
+      help   = STRING_TOKEN(STR_MAIN_HELP);
+
+    //
+    // Jump to  3)Uncore Configuration Form
+    //
+    goto UNCORE_FORM_ID,
+      prompt = STRING_TOKEN(STR_UNCORE_CONFIGURATION_TITLE),
+      help   = STRING_TOKEN(STR_UNCORE_CONFIGURATION_HELP);
+
+    //
+    // Jump to  4)South Cluster  Configuration Form
+    //
+    goto SOUTH_CLUSTER_FORM_ID,
+      prompt = STRING_TOKEN(STR_SOUTH_CLUSTER_TITLE),
+      help   = STRING_TOKEN(STR_SOUTH_CLUSTER_HELP);
+
+    // Jump to  5)Boot Form
+    //
+    goto BOOT_CONFIGURATION_FORM_ID,
+      prompt = STRING_TOKEN(STR_BOOT_CONFIGURATION_TITLE),
+      help   = STRING_TOKEN(STR_BOOT_CONFIGURATION_HELP);
+
+    //
+    // Jump to  6)Security Configuration Form
+    //
+    goto SECURITY_CONFIGURATION_FORM_ID,
+      prompt = STRING_TOKEN(STR_SECURITY_CONFIGURATION_TITLE),
+      help   = STRING_TOKEN(STR_SECURITY_CONFIGURATION_HELP);
+
+    //
+    // Jump to  7)Thermal Form
+    //
+    goto THERMAL_FORM_ID,
+      prompt = STRING_TOKEN(STR_THERMAL_TITLE),
+      help   = STRING_TOKEN(STR_THERMAL_HELP);
+
+    //
+    // Jump to 8) System Component Form
+    goto SYSTEM_COMPONENT_FORM_ID,
+      prompt = STRING_TOKEN(STR_SYSTEM_COMPONENT_TITLE),
+      help   = STRING_TOKEN(STR_SYSTEM_COMPONENT_HELP);
+
+    //
+    // Jump to  10)Debug Configuration Form
+    //
+#if (BYTI_PF_ENABLE == 0)
+    goto DEBUG_CONFIGURATION_FORM_ID,
+      prompt = STRING_TOKEN(STR_DEBUG_CONFIGURATION_TITLE),
+      help   = STRING_TOKEN(STR_DEBUG_CONFIGURATION_HELP);
+#endif
+
+    subtitle text = STRING_TOKEN(STR_NULL_STRING);
+    //
+    // Commit change and exit
+    //
+    text
+      help   = STRING_TOKEN(STR_COMMIT_CHANGE_AND_EXIT_HELP),
+      text   = STRING_TOKEN(STR_COMMIT_CHANGE_AND_EXIT_PROMPT),
+      text   = STRING_TOKEN(STR_COMMIT_CHANGE_AND_EXIT_PROMPT),
+      flags  = INTERACTIVE,
+      key    = 0xF001;
+
+    //
+    // Discard change and exit
+    //
+    text
+      help   = STRING_TOKEN(STR_DISCARD_CHANGE_AND_EXIT_HELP),
+      text   = STRING_TOKEN(STR_DISCARD_CHANGE_AND_EXIT_PROMPT),
+      text   = STRING_TOKEN(STR_DISCARD_CHANGE_AND_EXIT_PROMPT),
+      flags  = INTERACTIVE,
+      key    = 0xF002;
+
+    //
+    // Load default and exit
+    //
+    text
+      help   = STRING_TOKEN(STR_LOAD_DEFAULT_AND_EXIT_HELP),
+      text   = STRING_TOKEN(STR_LOAD_DEFAULT_AND_EXIT_PROMPT),
+      text   = STRING_TOKEN(STR_LOAD_DEFAULT_AND_EXIT_PROMPT),
+      flags  = INTERACTIVE,
+      key    = 0xF003;
+  endform;
+
+  #include "Main.vfi"
+  #include "UnCore.vfi"
+  #include "SouthClusterConfig.vfi"
+  #include "Boot.vfi"
+  #include "Security.vfi"
+  #include "Thermal.vfi"
+  #include "SystemComponent.vfi"
+  #include "DebugConfig.vfi"
+endformset;
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/VfrStrings.uni b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/VfrStrings.uni
new file mode 100644
index 0000000000..42c767e30d
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/VfrStrings.uni
@@ -0,0 +1,1417 @@
+// /** @file
+// Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+// Module Name:
+//
+//   Strings.vfr
+//
+// Abstract:
+//
+//   String definitions for Platform Setup formset.
+//
+// Revision History:
+//
+// **/
+
+//
+// NOTE: for SETUP engine spacing, the following character spaces denote how much room in each section you have.
+//       In the Help Text section "                       " -this is 23 spaces wide.
+//       In the Far left panel "                                     " -this is 37 spaces wide.
+//       In the middle section "                                     " -this is 37 spaces wide.
+//
+/=#
+
+#langdef   en-US "English"
+#langdef   fr-FR "Français"
+
+// STR_LANG_NAME is dummy for font extrace tool.  Without this,
+// some characters for language selection menu will not be displayed
+// correctly.
+#string STR_LANG_NAME #language  fr-FR "Français"
+#string STR_LANG_NAME #language  en-US "English"
+
+//Root form
+#string STR_SYSTEM_SETUP_TITLE                          #language en-US "System  Setup"
+#string STR_SYSTEM_SETUP_HELP                           #language en-US "Press <Enter> to select the System Configuration Setup options."
+
+#string STR_MAIN_TITLE                                  #language en-US "Main"
+#string STR_MAIN_HELP                                   #language en-US ""
+
+#string STR_CPU_CONFIGURATION_TITLE                     #language en-US "CPU Configuration"
+#string STR_CPU_CONFIGURATION_HELP                      #language en-US ""
+
+#string STR_CPU_POWERMNG_TITLE                          #language en-US "CPU Power Management"
+#string STR_CPU_POWERMNG_HELP                           #language en-US ""
+
+#string STR_BOOT_CONFIGURATION_TITLE                    #language en-US "Boot"
+#string STR_BOOT_CONFIGURATION_HELP                     #language en-US ""
+
+#string STR_IGD_TITLE                                   #language en-US "IGD Configuration"
+#string STR_IGD_HELP                                    #language en-US ""
+
+#string STR_MEMORY_CONFIGURATION_TITLE                  #language en-US "Memory Configuration"
+#string STR_MEMORY_CONFIGURATION_HELP                   #language en-US ""
+
+#string STR_ISP_ENABLED                                 #language en-US "ISP Enable/Disable"
+#string STR_ISP_ENABLED_HELP                            #language en-US "Enable/Disable ISP PCI Device Selection."
+
+#string STR_ISP_CONFIGURATION_TITLE                     #language en-US "ISP PCI Device Configuration"
+#string STR_ISP_PCICONFIGURATION_TITLE                  #language en-US "ISP PCI Device Selection"
+#string STR_ISP_PCICONFIGURATION_HELP                   #language en-US "Default ISP is PCI B0D2F0 for Window Boot. Linux Boot to select B0D3F0"
+#string STR_ISP_PCICONFIG_B0D2F0_TITLE                  #language en-US "ISP PCI Device as B0D2F0"
+#string STR_ISP_PCICONFIG_B0D3F0_TITLE                  #language en-US "ISP PCI Device as B0D3F0"
+
+#string STR_SECURITY_CONFIGURATION_TITLE                #language en-US "Security Configuration"
+#string STR_SECURITY_CONFIGURATION_HELP                 #language en-US ""
+
+#string STR_SOUTH_CLUSTER_TITLE                         #language en-US "South Cluster Configuration"
+#string STR_SOUTH_CLUSTER_HELP                          #language en-US ""
+
+#string STR_UNCORE_CONFIGURATION_TITLE                  #language en-US "Uncore Configuration"
+#string STR_UNCORE_CONFIGURATION_HELP                   #language en-US ""
+
+#string STR_DPTF_CONFIGURATION_TITLE                    #language en-US "DPTF"
+#string STR_DPTF_CONFIGURATION_HELP                     #language en-US ""
+
+#string STR_THERMAL_TITLE                               #language en-US "Thermal"
+#string STR_THERMAL_HELP                                #language en-US ""
+
+#string STR_SYSTEM_COMPONENT_TITLE                      #language en-US "System Component"
+#string STR_SYSTEM_COMPONENT_HELP                       #language en-US ""
+
+#string STR_DEBUG_CONFIGURATION_TITLE                  #language en-US "Debug Configuration"
+#string STR_DEBUG_CONFIGURATION_HELP                   #language en-US ""
+
+//
+// Main form definition
+//
+#string STR_DATE_PROMPT                                 #language en-US "System Date"
+
+
+#string STR_DATE_YEAR_HELP                              #language en-US  "Displays and changes the System Date from the Real-Time Clock. Format is Month/Day/Year. "
+#string STR_DATE_MONTH_HELP                             #language en-US  "Displays and changes the System Date from the Real-Time Clock. Format is Month/Day/Year. "
+#string STR_DATE_DAY_HELP                               #language en-US  "Displays and changes the System Date from the Real-Time Clock. Format is Month/Day/Year. "
+#string STR_ERROR_POPUP                                 #language en-US  "Try Again"
+#string STR_BIOS_INFORMATION_TITLE                      #language en-US  "Bios Information"
+
+#string STR_NULL_STRING                                 #language en-US  ""
+#string STR_NULL_STRING                                 #language fr-FR  ""
+
+#string STR_BIOS_VENDOR_STRING                          #language en-US "BIOS Vendor"
+#string STR_BIOS_VENDOR_STRING                          #language fr-FR "Verdor du BIOS"
+
+#string STR_BIOS_VENDOR_VALUE                           #language en-US  "Intel Corporation"
+#string STR_BIOS_VENDOR_VALUE                           #language fr-FR  ""
+
+#string STR_BIOS_VERSION_STRING                         #language en-US "BIOS Version"
+#string STR_BIOS_VERSION_STRING                         #language fr-FR "Version du BIOS"
+
+#string STR_BIOS_VERSION_VALUE                          #language en-US  ""
+#string STR_BIOS_VERSION_VALUE                          #language fr-FR  ""
+
+#string STR_IFWI_VERSION_STRING                         #language en-US "IFWI Version"
+#string STR_IFWI_VERSION_STRING                         #language fr-FR "Version du IFWI"
+
+#string STR_IFWI_VERSION_VALUE                          #language en-US  ""
+#string STR_IFWI_VERSION_VALUE                          #language fr-FR  ""
+
+#string STR_BIOS_BUILD_TIME_STRING                      #language en-US "Build Time"
+#string STR_BIOS_BUILD_TIME_VALUE                       #language en-US "NA"
+
+#string STR_CORE_VERSION_STRING                         #language en-US "Core Version"
+#string STR_CORE_VERSION_VALUE                          #language en-US "UEFI 2.40"
+
+#string STR_SEC_VERSION_STRING                          #language en-US "TXE FW Version"
+#string STR_SEC_VERSION_VALUE                           #language en-US ""
+
+#string STR_SEC_CAPABILITY_STRING                       #language en-US "TXE FW Capabilities"
+#string STR_SEC_CAPABILITY_VALUE                        #language en-US ""
+
+#string STR_SEC_FEATURE_STRING                          #language en-US "TXE FW Features"
+#string STR_SEC_FEATURE_VALUE                           #language en-US ""
+
+#string STR_SEC_OEMTAG_STRING                           #language en-US "TXE FW OEM Tag"
+#string STR_SEC_OEMTAG_VALUE                            #language en-US ""
+
+#string STR_SEC_FILE_SYSTEM_INTEGRITY_VALUE_STRING      #language en-US "TXE File System Integrity Value"
+#string STR_SEC_FILE_SYSTEM_INTEGRITY_VALUE             #language en-US ""
+
+#string STR_SEC_TEMP_DISABLE_HELP                       #language en-US "TXE Temporary Disable"
+#string STR_SEC_TEMP_DISABLE_STRING                     #language en-US "TXE Firmware Mode"
+#string STR_SEC_TEMP_DISABLE_PROMPT                     #language en-US "TXE Temporary Disable"
+
+#string STR_SEC_LOCAL_FW_UPDATE_HELP                    #language en-US "TXE Disable/Enable TXE Local Fw Update"
+#string STR_SEC_LOCAL_FW_UPDATE_STRING                  #language en-US "TXE Local Fw Update"
+#string STR_SEC_LOCAL_FW_UPDATE_PROMPT                  #language en-US "TXE Temporary Disable"
+
+#string STR_SEC_FIRMWARE_WRITE_PROMPT                   #language en-US "TXE Firmware R/W Mode"
+#string STR_SEC_FIRMWARE_WRITE_VALUE                    #language en-US ""
+
+#string STR_SEC_FIRMWARE_TOGGLE_PROMPT                   #language en-US "TXE Firmware R/W Toggle"
+#string STR_SEC_FIRMWARE_TOGGLE_HELP                     #language en-US "Use to Toggle between R/W and R/O"
+#string STR_SEC_FIRMWARE_TOGGLE_NO                       #language en-US "No"
+#string STR_SEC_FIRMWARE_TOGGLE_YES                      #language en-US "Yes"
+
+#string STR_SEC_HMRFPO_HELP                             #language en-US "TXE HMRFPO Disable"
+#string STR_SEC_HMRFPO_STRING                           #language en-US "TXE HMRFPO "
+#string STR_SEC_HMRFPO_PROMPT                           #language en-US "TXE HMRFPO Disable"
+
+#string STR_SEC_EOP_HELP                                #language en-US "Send EOP Message Befor Enter OS"
+#string STR_SEC_EOP_PROMPT                              #language en-US "TXE EOP Message"
+
+#string STR_PLATFORM_INFORMATION_TITLE                  #language en-US "Platform Information"
+#string STR_PLATFORM_INFORMATION_HELP                   #language en-US "Display platform information"
+
+#string STR_PROCESSOR_INFO_STRING                       #language en-US "Processor Information"
+#string STR_PROCESSOR_VERSION_STRING                    #language en-US "Processor Type"
+#string STR_PROCESSOR_VERSION_VALUE                     #language en-US "N/A"
+#string STR__STRING                                     #language en-US "  "
+#string STR__VALUE                                      #language en-US ""
+#string STR_PROCESSOR_SPEED_STRING                      #language en-US "Processor Speed"
+#string STR_PROCESSOR_SPEED_VALUE                       #language en-US ""
+#string STR_PROCESSOR_MICROCODE_STRING                  #language en-US "Microcode Revision"
+#string STR_PROCESSOR_MICROCODE_VALUE                   #language en-US "Not loaded"
+#string STR_PROCESSOR_CORE_STRING                       #language en-US "Number of Cores"
+#string STR_PROCESSOR_CORE_VALUE                        #language en-US "1"
+#string STR_EM64T_CAPABILITY_STRING                     #language en-US "Intel(r) 64 Architecture Capable"
+#string STR_EM64T_CAPABILITY_VALUE                      #language en-US "Support"
+
+#string STR_PLATFORM_FIRMWARE_STRING                    #language en-US "Platform firmware Information"
+
+#string STR_MFGMODE                                    #language en-US "Manufacture Mode"
+#string STR_MFGMODE_HELP                               #language en-US "Manufacture Mode Status"
+
+
+
+#string STR_MEMORY_INFORMATION_STRING                   #language en-US "Memory Information"
+#string STR_TOTAL_MEMORY_SIZE_PROMPT                    #language en-US "Total Memory"
+#string STR_TOTAL_MEMORY_SIZE_VALUE                     #language en-US ""
+#string STR_MEMORY_SPEED_PROMPT                         #language en-US "DIMM Frequency"
+#string STR_MEMORY_SPEED_PROMPT_VALUE                   #language en-US ""
+#string STR_PROCESSOR_L1_DATA_CACHE_STRING              #language en-US "L1 Data Cache"
+#string STR_PROCESSOR_L1_DATA_CACHE_VALUE               #language en-US "N/A"
+#string STR_PROCESSOR_L1_INSTR_CACHE_STRING             #language en-US "L1 Instruction Cache"
+#string STR_PROCESSOR_L1_INSTR_CACHE_VALUE              #language en-US "N/A"
+#string STR_PROCESSOR_L2_CACHE_STRING                   #language en-US "L2 Cache RAM"
+#string STR_PROCESSOR_L2_CACHE_VALUE                    #language en-US  "NO"
+#string STR_SYSTEM_MEMORY_SPEED_STRING                  #language en-US "Memory Speed"
+#string STR_SYSTEM_MEMORY_SPEED_VALUE                   #language en-US  ""
+
+#string STR_CHIP_IGD_VBIOS_REV_HELP                     #language en-US "IGD VBIOS Version"
+#string STR_CHIP_IGD_VBIOS_REV_NAME                     #language en-US "IGD VBIOS Version"
+#string STR_CHIP_IGD_VBIOS_REV_VALUE                    #language en-US "N/A"
+
+#string STR_CPU_FLAVOR_HELP                             #language en-US "CPU Flavor"
+#string STR_CPU_FLAVOR_NAME                             #language en-US "CPU Flavor"
+#string STR_CPU_FLAVOR_VALUE                            #language en-US "N/A"
+
+#string STR_BOARD_INFORMATION_STRING                    #language en-US "Board Information"
+#string STR_BOARD_ID_HELP                               #language en-US "Displays the Board ID."
+#string STR_BOARD_ID_NAME                               #language en-US "Board ID"
+#string STR_BOARD_ID_VALUE                              #language en-US "N/A"
+
+//
+// CPU INFORMATION
+//
+#string STR_CPU_FORM_SUBTITLE                           #language en-US "Processor Information"
+
+#string STR_PROCESSOR_VERSION_HELP                      #language en-US "Displays the Processor Type."
+#string STR_PROCESSOR_VERSION_STRING                    #language en-US "Type"
+#string STR_PROCESSOR_VERSION_VALUE                     #language en-US "N/A"
+
+#string STR_PROCESSOR_SKU_HELP        #language en-US "Displays the Processor SKU Type."
+#string STR_PROCESSOR_SKU_STRING      #language en-US "SKU Type"
+#string STR_PROCESSOR_SKU_VALUE        #language en-US "N/A"
+
+#string STR_PROCESSOR_SPEED_STRING                      #language en-US "Speed"
+#string STR_PROCESSOR_SPEED_VALUE                       #language en-US "N/A"
+#string STR_PROCESSOR_SPEED_HELP                        #language en-US "Displays the Processor Speed."
+
+#string STR_PROCESSOR_ID_STRING                         #language en-US "Family/Model/Step"
+#string STR_PROCESSOR_ID_VALUE                          #language en-US "N/A"
+#string STR_PROCESSOR_ID_HELP                           #language en-US "Family/Model/Step of Processor"
+
+#string STR_PROCESSOR_STEPPING_STRING                   #language en-US "Stepping"
+#string STR_PROCESSOR_STEPPING_VALUE                    #language en-US "Unknown"
+#string STR_PROCESSOR_STEPPING_HELP                     #language en-US "Displays the Processor Stepping."
+
+
+#string STR_FAB_ID_HELP                                 #language en-US "Displays the Fab ID"
+#string STR_FAB_ID_STRING                               #language en-US "Fab ID"
+#string STR_FAB_ID_VALUE                                #language en-US "N/A"
+
+#string STR_TIME_PROMPT                                 #language en-US "System Time"
+#string STR_TIME_HOUR_HELP                              #language en-US "Displays and changes the System Time from the Real-Time Clock. Clock is displayed in 24-hour format. "
+#string STR_TIME_MINUTE_HELP                            #language en-US "Displays and changes the System Time from the Real-Time Clock. Clock is displayed in 24-hour format. 9"
+#string STR_TIME_SECOND_HELP                            #language en-US "Displays and changes the System Time from the Real-Time Clock. Clock is displayed in 24-hour format. "
+
+//
+// Boot form definition
+//
+#string STR_FAST_BOOT_PROMPT                            #language en-US "Fast Boot"
+#string STR_FAST_BOOT_HELP                              #language en-US "Enable or Disable FastBoot features. \n Most probes are skipped to reduce time cost during boot."
+#string STR_SECURITY_BOOT_PROMPT                        #language en-US "UEFI Security Boot"
+#string STR_SECURITY_BOOT_HELP                          #language en-US "Disable/Enable UEFI Security boot feature"
+#string STR_LOG_BOOT_TIME_PROMPT                        #language en-US "BootTime Log"
+#string STR_LOG_BOOT_TIME_HELP                          #language en-US "BootTime for OS Booting"
+#string STR_LOG_BOOT_TIME_RECORD                        #language en-US "  Latest BootTime"
+#string STR_LOG_BOOT_TIME_VALUE                         #language en-US "No Record"
+#string STR_QUIETBOOT_PROMPT                            #language en-US "Silent Boot"
+#string STR_QUIETBOOT_HELP                              #language en-US "Disable console output and show logo if it is enabled."
+#string STR_LEGACYUSBBOOTING_PROMPT                     #language en-US "Legacy USB Booting"
+#string STR_STR_LEGACYUSBBOOTING_HELP                   #language en-US "Enable or Disable Legacy USB Booting features."
+#string STR_DROIDBOOT_PROMPT                            #language en-US "Droid Boot"
+#string STR_DROIDBOOT_HELP                              #language en-US "Go to Droidboot to flash Android Image"
+#string STR_ANDROIDBOOT_PROMPT                            #language en-US "Android Boot"
+#string STR_ANDROIDBOOT_HELP                              #language en-US "Boot android OS"
+
+// Enable or Disable or Automatic
+#string STR_ENABLE                                      #language en-US  "Enable"
+#string STR_ENABLE                                      #language fr-FR  "Activé"
+
+#string STR_DISABLE                                     #language en-US  "Disable"
+#string STR_DISABLE                                     #language fr-FR  "Désactivé"
+
+#string STR_PCI_MODE                                     #language en-US  "PCI Mode"
+#string STR_ACPI_MODE                                    #language en-US  "ACPI Mode"
+
+#string STR_ENABLED                                      #language en-US  "Enabled"
+#string STR_ENABLED                                      #language fr-FR  "Activé"
+
+#string STR_DISABLED                                     #language en-US  "Disabled"
+#string STR_DISABLED                                     #language fr-FR  "Désactivé"
+#string STR_AUTOMATIC                                   #language en-US  "Auto"
+#string STR_AUTOMATIC                                   #language fr-FR  "Auto"
+
+#string STR_ON                                          #language en-US  "ON"
+#string STR_OFF                                         #language en-US  "OFF"
+
+#string STR_YES                                         #language en-US  "YES"
+#string STR_NO                                          #language en-US  "NO"
+
+//
+//CPU Features Configuration
+//
+#string STR_ACTIVE_CORE_COUNT_PROMPT                    #language en-US "Active Processor Cores"
+#string STR_ACTIVE_CORE_COUNT_PROMPT_HELP               #language en-US "Number of cores to enable in each processor package."
+
+#string STR_AESNI_PROMPT                                #language en-US "AESNI Feature"
+#string STR_AESNI_PROMPT_HELP                           #language en-US "Enable/Disable AESNI ."
+
+#string STR_EXECUTE_DISABLE_BIT_PROMPT                  #language en-US "Execute Disable Bit"
+#string STR_EXECUTE_DISABLE_BIT_HELP                    #language en-US "Execute Disable Bit prevent certain classes of malicious buffer overflow attacks when combined with a supporting OS"
+
+#string STR_LIMIT_CPUID_MAX_PROMPT                      #language en-US "Limit CPUID Maximum"
+#string STR_LIMIT_CPUID_MAX_HELP                        #language en-US "Disabled for Windows XP"
+
+#string STR_CORE_FRE_MULTIP_SELECT_PROMPT               #language en-US "Core Frequency Multiplier select"
+#string STR_CORE_FRE_MULTIP_SELECT_HELP                 #language en-US "for Debug only"
+
+#string STR_VTX2_PROMPT                                 #language en-US "VTX-2"
+#string STR_VTX2_HELP                                   #language en-US "To enable or disable the VTX-2 Mode support"
+
+#string STR_PROC_HOT_ENABLE                             #language en-US  "Bi-directional PROCHOT#"
+#string STR_PROC_HOT_ENABLE_HELP                        #language en-US  "When a processor thermal sensor trips (either core), the PROCHOT# will be driven.\nIf bi-direction is enabled, external agents can drive PROCHOT# to throttle the processor."
+#string STR_TM1_PROMPT                                  #language en-US  "TM1 "
+#string STR_TM1_PROMPT_HELP                             #language en-US  "Enable/Disable TM1"
+#string STR_TM2_PROMPT                                  #language en-US  "TM2 "
+#string STR_TM2_PROMPT_HELP                             #language en-US  "Enable/Disable TM2"
+#string STR_DTS_PROMPT                                  #language en-US  "DTS "
+#string STR_DTS_PROMPT_HELP                             #language en-US  "Enabled/Disable Digital Thermal Sensor"
+#string STR_ACTIVE_PROCESSOR_CORES_PROMPT               #language en-US "Active Processor Cores"
+#string STR_ACTIVE_PROCESSOR_CORES_HELP                 #language en-US "Number of cores to enable in each processor package"
+#string STR_PROCESSOR_HT_MODE                           #language en-US "Intel(r) Hyper-Threading Technology"
+#string STR_PROCESSOR_HT_MODE_HELP                      #language en-US "When disabled, only one thread per active core will be available."
+#string STR_CAPABILITY_NOT_SUPPORT                      #language en-US "Not Supported"
+
+#string STR_ALL                                         #language en-US "ALL"
+#string STR_1                                           #language en-US  "1"
+
+//
+//CPU Power Option
+//
+#string STR_SYSTEM_POWER_OPTIONS                        #language en-US "System Power Options"
+#string STR_BOOT_P_STATE                                #language en-US "Boot performance mode"
+#string STR_BOOT_P_STATE_HELP                           #language en-US "Select the performance state that the BIOS will set before OS handoff."
+#string STR_BOOT_P_STATE_MAX                            #language en-US "Max Performance"
+#string STR_BOOT_P_STATE_MIN                            #language en-US "Max Battery"
+#string STR_BOOT_P_STATE_FLEX                           #language en-US "Flexible Ratio(Override)"
+#string STR_CPU_IST_PROMPT                              #language en-US "Intel(R) SpeedStep(tm)"
+#string STR_CPU_IST_HELP                                #language en-US "Allows more than two frequency ranges to be supported."
+#string STR_CSTATE_PROMPT                               #language en-US "C-States"
+#string STR_CSTATE_PROMPT_HELP                          #language en-US "Enable/Disable C States"
+#string STR_CXE_PROMPT                                  #language en-US "  Enhanced C-states"
+#string STR_CXE_PROMPT_HELP                             #language en-US "Enable/Disable C1E, C2E and C4E. When enabled, CPU will switch to minimum speed when all cores enter C-State."
+#string STR_HARDC4E_PROMPT                              #language en-US  "Hard C4E"
+#string STR_HARDC4E_PROMPT_HELP                         #language en-US  "Enable/Disable Hard C4E"
+#string STR_PROCESSOR_TURBO_MODE                        #language en-US "Intel(r) Turbo Boost Technology"
+#string STR_PROCESSOR_TURBO_MODE_HELP                   #language en-US "Enable to automatically allow processor cores to run faster than the base operating frequency if it's operating below power, current, and temperature specification limits. Turbo will be disabled under auto mode if SoC is B0 Stepping"
+#string STR_MAX_C_STATE_SUPPORT_PROMPT                  #language en-US  "  Max C State"
+#string STR_MAX_C_STATE_SUPPORT_HELP                    #language en-US  "This option controls the Max C State that the processor will support."
+#string STR_CSTATE_C7                                   #language en-US  "C7"
+#string STR_CSTATE_C6                                   #language en-US  "C6"
+#string STR_CSTATE_C4                                   #language en-US  "C4"
+#string STR_CSTATE_C1                                   #language en-US  "C1"
+#string STR_CX_POPDOWN_PROMPT                           #language en-US "C-state POPDOWN"
+#string STR_CX_POPDOWN_PROMPT_HELP                      #language en-US "Disabling the option, prevents automatic return to a previous C3 or C4 states"
+#string STR_CX_POPUP_PROMPT                             #language en-US "C-state POPUP"
+#string STR_CX_POPUP_PROMPT_HELP                        #language en-US "On enabled, SB observes bus master request, will take system from a C3/C4 state to a C2 state and auto enables bus masters."
+#string STR_PPM_C4_EXIT_PROMPT                          #language en-US "C4 Exit Timing"
+#string STR_PPM_C4_EXIT_HELP                            #language en-US "This option controls a programmable time for the CPU voltage to stabilize when exiting from a C4 state."
+#string STR_PPM_DEFAULT_C4_EXIT                         #language en-US "Default"
+#string STR_PPM_FAST_C4_EXIT                            #language en-US "Fast"
+#string STR_PPM_SLOW_C4_EXIT                            #language en-US "Slow"
+#string STR_PPM_FORCE_SLOW_C4_EXIT                      #language en-US "Force Slow"
+
+
+//
+// IGD Configuration form
+//
+#string STR_IGD_LCD_CONTROL                            #language en-US "IGD - LCD Control"
+#string STR_BOOT_DISPLAY_DEVICE_PROMPT                 #language en-US "IGD Boot Type"
+#string STR_BOOT_DISPLAY_DEVICE_HELP                   #language en-US "Select preference for Integrated Graphics Device (IGD) display interface used when system boots."
+#string STR_EDP                                        #language en-US "eDP"
+#string STR_HDMI                                       #language en-US "HDMI"
+#string STR_MIPI2DSI                                   #language en-US "MIPI-DSI"
+#string STR_VGAPORT                                    #language en-US "VGA Port"
+#string STR_HDMIPORTB                                  #language en-US "HDMI"
+#string STR_DPPORTB                                    #language en-US "DP Port B"
+#string STR_DPPORTC                                    #language en-US "DP Port C"
+#string STR_EDPPORTC                                   #language en-US "eDP"
+#string STR_DSIPORTA                                   #language en-US "DSI PORT A"
+#string STR_DSIPORTC                                   #language en-US "DSI PORT C"
+
+#string STR_IGD_FLAT_PANEL_PROMPT                      #language en-US "LCD Panel Type"
+#string STR_IGD_FLAT_PANEL_HELP                        #language en-US "Select the LCD panel used by Internal Graphics Device by selecting the appropriate setup item."
+#string STR_640X480                                    #language en-US "640 x 480"
+#string STR_800X600                                    #language en-US "800 x 600"
+#string STR_1024X768                                   #language en-US "1024 x 768"
+#string STR_1280X1024                                  #language en-US "1280 x 1024"
+#string STR_1366X768                                   #language en-US "1366 x 768"
+#string STR_1680X1050                                  #language en-US "1680 x 1050"
+#string STR_1920X1200                                  #language en-US "1920 x 1200"
+#string STR_1280X800                                   #language en-US "1280 x 800"
+
+#string STR_IGD_LCD_CONTROL                            #language en-US "IGD - LCD Control"
+#string STR_IGD_FIXED_GRAPHICS_MEMORY_SIZE             #language en-US "IGD Fixed Graphics Memory"
+#string STR_128MB                                      #language en-US "128 MB"
+#string STR_256MB                                      #language en-US "256 MB"
+
+#string STR_IGD_THERMAL_PROMPT                         #language en-US "IGD Thermal"
+#string STR_IGD_THERMAL_HELP                           #language en-US "Check to enable thermal monitoring on IGD."
+
+#string STR_GFX_BOOST_PROMPT                           #language en-US "GFX Boost"
+#string STR_GFX_BOOST_HELP                             #language en-US "Enable/Disable GFX boost"
+
+#string STR_SPREAD_SPECTRUM_CLOCK_PROMPT               #language en-US "Spread Spectrum clock"
+#string STR_SPREAD_SPECTRUM_CLOCK_HELP                 #language en-US "Enable/Disable Spread Spectrum clock"
+
+#string STR_FORCE_LID_STATUS_PROMPT                    #language en-US "Force Lid Status"
+#string STR_LID_STATUS__AUTO_PROMPT                    #language en-US "Auto"
+#string STR_LID_STATUS__ON_PROMPT                      #language en-US "ON"
+#string STR_LID_STATUS__OFF_PROMPT                     #language en-US "OFF"
+#string STR_FORCE_LID_STATUS_TABLET_HELP               #language en-US "For test: force to set lid status as on or off"
+#string STR_FORCE_LID_STATUS_ENBDT_HELP                #language en-US "For AUTO: BIOS updates LID Status as per Virtual LID Switch. For ON/OFF: BIOS force to set lid status as ON or OFF"
+
+#string STR_PANNEL_SCALING_PROMPT                      #language en-US "Panel Scaling"
+#string STR_PANNEL_SCALING_HELP                        #language en-US "Select the LCD panel scaling option used by Internal Graphics Device."
+#string STR_PANNEL_SCALING_STRETCH                     #language en-US "Centering"
+#string STR_PANNEL_SCALING_CENTER                      #language en-US "Stretching"
+
+#string STR_VIDEO_LCD_IGMCHBLC_PROMPT                  #language en-US  "GMCH BLC Control"
+#string STR_VIDEO_LCD_IGMCHBLC_HELP                    #language en-US  "Back Light Control Setting"
+#string STR_VIDEO_LCD_IGMCHBLC1                        #language en-US  "PWM-Inverted"
+#string STR_VIDEO_LCD_IGMCHBLC2                        #language en-US  "GMBus-Inverted"
+#string STR_VIDEO_LCD_IGMCHBLC3                        #language en-US  "PWM-Normal"
+#string STR_VIDEO_LCD_IGMCHBLC4                        #language en-US  "GMBus-Normal"
+
+
+#string STR_VIDEO_LCD_IBIA                             #language en-US  "BIA"
+#string STR_VIDEO_LCD_IBIAA                            #language en-US  "Auto"
+#string STR_VIDEO_LCD_IBIAD                            #language en-US  "Disabled"
+#string STR_VIDEO_LCD_IBIAL1                           #language en-US  "Level 1"
+#string STR_VIDEO_LCD_IBIAL2                           #language en-US  "Level 2"
+#string STR_VIDEO_LCD_IBIAL3                           #language en-US  "Level 3"
+#string STR_VIDEO_LCD_IBIAL4                           #language en-US  "Level 4"
+#string STR_VIDEO_LCD_IBIAL5                           #language en-US  "Level 5"
+#string STR_VIDEO_LCD_IBIAHLP                          #language en-US  ">>Auto: GMCH Use VBIOS Default;           >>Level n: Enabled with Selected Aggressiveness Level."
+
+#string STR_PRIMARY_DISPLAY                            #language en-US  "Primary Display"
+#string STR_PRIMARY_DISPLAY_HELP                       #language en-US  "Select which of IGD/PCI Graphics device should be Primary Display"
+#string STR_IGD_STRING                                 #language en-US  "IGD"
+#string STR_PCI_STRING                                 #language en-US  "PCIe"
+
+#string STR_VIDEO_RS2_PROMPT                           #language en-US  "RC6(Render Standby)"
+#string STR_VIDEO_RS2_HELP                             #language en-US  "Check to enable render standby support, RC6 should be enabled if S0ix is enabled.\n\nThis item will be read only if S0ix is enabled"
+
+#string STR_PAVC_PROMPT                                #language en-US  "PAVC"
+#string STR_PAVC_HELP                                  #language en-US  "Enable/Disable Protected Audio Video Control"
+#string STR_PAVP_LITE_MODE                             #language en-US  "LITE Mode"
+#string STR_PAVP_SERPENT_MODE                          #language en-US  "SERPENT Mode"
+#string STR_DVMT40_TITLE                               #language en-US  "DVMT4.0 Graphic memory setting"
+#string STR_DVMT40_PRE_ALLOC                           #language en-US  "DVMT Pre-Allocated"
+#string STR_DVMT40_PRE_ALLOC_1M                        #language en-US  "1M"
+#string STR_DVMT40_PRE_ALLOC_8M                        #language en-US  "8M"
+#string STR_DVMT40_PRE_ALLOC_HELP                      #language en-US  "Select DVMT 4.0 Pre-Allocated (UMA) Graphics Memory size used by the Internal Graphics Device."
+#string STR_LOCK_ECO_PROMPT                            #language en-US  "ECO Lock"
+#string STR_LOCK_ECO_HELP                              #language en-US  "Enable/Disable ECO Lock"
+#string STR_DOP_CG_PROMPT                              #language en-US  "DOP CG"
+#string STR_DOP_CG__HELP                               #language en-US  "Enable/Disable DOP Clock Gating"
+
+//
+// DVMT5.0 Graphics Memory
+//
+#string STR_DVMT50_TITLE                        #language en-US "DVMT5.0 Graphic memory setting"
+#string STR_DVMT50_PRE_ALLOC                    #language en-US "DVMT Pre-Allocated"
+#string STR_DVMT50_PRE_ALLOC_0M                 #language en-US "0M"
+#string STR_DVMT50_PRE_ALLOC_32M                #language en-US "32M"
+#string STR_DVMT50_PRE_ALLOC_64M                #language en-US "64M"
+#string STR_DVMT50_PRE_ALLOC_96M                #language en-US "96M"
+#string STR_DVMT50_PRE_ALLOC_128M               #language en-US "128M"
+#string STR_DVMT50_PRE_ALLOC_160M               #language en-US "160M"
+#string STR_DVMT50_PRE_ALLOC_192M               #language en-US "192M"
+#string STR_DVMT50_PRE_ALLOC_224M               #language en-US "224M"
+#string STR_DVMT50_PRE_ALLOC_256M               #language en-US "256M"
+#string STR_DVMT50_PRE_ALLOC_288M               #language en-US "288M"
+#string STR_DVMT50_PRE_ALLOC_320M               #language en-US "320M"
+#string STR_DVMT50_PRE_ALLOC_352M               #language en-US "352M"
+#string STR_DVMT50_PRE_ALLOC_384M               #language en-US "384M"
+#string STR_DVMT50_PRE_ALLOC_416M               #language en-US "416M"
+#string STR_DVMT50_PRE_ALLOC_448M               #language en-US "448M"
+#string STR_DVMT50_PRE_ALLOC_480M               #language en-US "480M"
+#string STR_DVMT50_PRE_ALLOC_512M               #language en-US "512M"
+
+#string STR_DVMT50_PRE_ALLOC_HELP               #language en-US "Select DVMT 5.0 Pre-Allocated (Fixed) Graphics Memory size used by the Internal Graphics Device"
+#string STR_DVMT50_DVMT                         #language en-US "DVMT Total Gfx Mem"
+#string STR_DVMT50_DVMT_HELP                    #language en-US "Select DVMT5.0 Total Graphic Memory size used by the Internal Graphics Device"
+#string STR_DVMT50_ALLOC_128                    #language en-US "128M"
+#string STR_DVMT50_ALLOC_256                    #language en-US "256M"
+#string STR_DVMT50_ALLOC_MAX                    #language en-US "MAX"
+#string STR_GTT_SIZE                            #language en-US "GTT Size"
+#string STR_GTT_SIZE_HELP                       #language en-US "Select the GTT Size "
+#string GTT_SIZE_1MB                            #language en-US "1MB"
+#string GTT_SIZE_2MB                            #language en-US "2MB"
+#string STR_APERTURE_SIZE                       #language en-US "Aperture Size"
+#string STR_APERTURE_SIZE_HELP                  #language en-US "Select the Aperture Size"
+#string APERTURE_SIZE_128MB                     #language en-US "128MB"
+#string APERTURE_SIZE_256MB                     #language en-US "256MB"
+#string APERTURE_SIZE_512MB                     #language en-US "512MB"
+
+#string STR_IGD_PROMPT                          #language en-US  "Integrated Graphics Device"
+#string STR_IGD_HELP                            #language en-US  "Enable : Enable Integrated Graphics Device (IGD) when selected as the Primary Video Adaptor. Disable: Alwarys disable IGD"
+
+#string STR_ACPI_ALS_ENABLE                            #language en-US  "ALS Support"
+#string STR_ACPI_ALS_ENABLE_HELP                       #language en-US  "Valid only for ACPI."
+
+#string STR_SEC_CONFIGURATION_SUBTITLE                 #language en-US "TXE Configuration"
+
+#string STR_SEC_SETTING_PROMPT                         #language en-US "TXE"
+#string STR_SEC_SETTING_HELP                           #language en-US ""
+
+#string STR_TPM_CONFIGURATION_PROMPT                   #language en-US "TPM Configuration"
+
+#string STR_FIRMWARE_TPM_PROMPT                        #language en-US "fTPM"
+#string STR_FIRMWARE_TPM_HELP                          #language en-US "Enable/Disable fTPM"
+
+#string STR_PTT_PROMPT                                 #language en-US "PTT"
+#string STR_PTT_HELP                                   #language en-US "Enable/Disable PTT"
+
+#string STR_TPM_PROMPT                                 #language en-US "Discrete TPM"
+#string STR_TPM_HELP                                   #language en-US "Enable/Disable TPM"
+
+#string STR_MEASURED_BOOT_ENABLE_PROMPT                #language en-US "Measured Boot"
+#string STR_MEASURED_BOOT_ENABLE_HELP                  #language en-US "Enable/Disable Measured Boot"
+
+#string STR_SEC_FLASH_UPDATE_PROMPT                    #language en-US "TXE HMRFPO "
+#string STR_SEC_FLASH_UPDATE_HELP                      #language en-US ""
+
+#string STR_SEC_FIRMWARE_UPDATE_PROMPT                 #language en-US "TXE Firmware Update"
+#string STR_SEC_FIRMWARE_UPDATE_HELP                   #language en-US ""
+#string STR_SEC_UNCONFIGURATION_PROMPT                 #language en-US "TXE Unconfiguration Perform"
+#string STR_SEC_UNCONFIGURATION_HELP                   #language en-US "Revert TXE settings to factory defaults"
+#string STR_PTT_SUBTITLE                               #language en-US "Platform Trust Technology"
+#string STR_PTT_DISABLE_PROMPT                         #language en-US "PTT Disable"
+#string STR_PTT_DISABLE_HELP                           #language en-US "Disable PTT "
+
+#string STR_REVOKE_TRUST_PROMPT                        #language en-US "Revoke Trust"
+#string STR_REVOKE_TRUST_HELP                          #language en-US "Enable/Disable Revoke Trust"
+
+#string STR_PASSWORD_CONFIGURATION_SUBTITLE            #language en-US "Password Setting"
+#string STR_PASSWORD_CONFIGURATION_HELP                #language en-US "Password Setting"
+
+#string STR_TDT_TITLE                                  #language en-US "Intel(R) Anti-Theft Technology Configuration"
+
+#string STR_TDT_CONFIG_PROMPT                          #language en-US "Intel(R) ATAM"
+#string STR_TDT_CONFIG_HELP                            #language en-US "Enable/Disable BIOS AT Code from Running."
+
+#string STR_PBA_CONFIG_PROMPT                          #language en-US "Intel(R) AT Platform PBA"
+#string STR_PBA_CONFIG_HELP                            #language en-US "Enable/Disable BIOS AT Code from Running."
+
+#string STR_TDT_RECOVERY_PROMPT                        #language en-US "AT Recovery"
+#string STR_TDT_RECOVERY_HELP                          #language en-US "Set the number of times AT Recovery attempts will be allowed"
+
+#string STR_TDT_SUSPEND_PROMPT                         #language en-US "Intel(R) AT Suspend Mode"
+#string STR_TDT_SUSPEND_HELP                           #language en-US "Request that platform enter AT Suspend Mode - Only Available when AT Enrolled"
+
+#string STR_ADMIN_PASSWORD                             #language en-US "Setup Administrator Password"
+#string STR_ADMIN_PASSWORD_HELP                        #language en-US "Set Setup Administrator Password"
+#string STR_USER_PASSWORD                              #language en-US "User Password"
+#string STR_USER_PASSWORD_HELP                         #language en-US "Set User Password"
+#string STR_CHANGE_ADMIN_PASSWORD                      #language en-US "Change Supervisor Password"
+#string STR_CHANGE_ADMIN_PASSWORD_HELP                 #language en-US "Change Setup Administrator Password"
+#string STR_CHANGE_USER_PASSWORD                       #language en-US "Change User Password"
+#string STR_CHANGE_USER_PASSWORD_HELP                  #language en-US "Change User Password"
+#string STR_SB_TITLE                                   #language en-US "Secure Boot Configuration"
+#string STR_CHECK_SHA256_HASH_MASTER_BOOT_CODES        #language en-US "Check SHA256 Hash of Master Boot Codes"
+#string STR_CHECK_SHA256_HASH_MASTER_BOOT_CODES_HELP   #language en-US "Enable/Disable the checking of SHA256 hash of Master Boot Codes"
+//
+//South Cluster Configuration
+//
+#string STR_HPET_PROMPT                                #language en-US "High Precision Timer"
+#string STR_HPET_HELP                                  #language en-US "Enable or Disable the High Precision Event Timer."
+#string STR_HPET_BOOTTIME_PROMPT                       #language en-US "Boot Time with HPET Timer"
+#string STR_HPET_BOOTTIME_HELP                         #language en-US "Boot time calculation with High Precision Event Timer enabled."
+
+#string STR_HPET_SUBTITLE                              #language en-US "High Precision Event Timer Configuration"
+
+#string STR_USB_CONFIG_SUBTITLE                        #language en-US "USB Configuration"
+#string STR_USB_DEBUG_PROMPT                           #language en-US "USB Debug"
+#string STR_USB_DEBUG_HELP                             #language en-US "Enable or Disable USB debug feature"
+#string STR_USB_XHCI_SUPPORT_PROMPT                    #language en-US "XHCI Controller"
+#string STR_USB_XHCI_SUPPORT_HELP                      #language en-US "Enable/Disable XHCI Controller "
+
+#string STR_USB_HSIC_0_PROMPT                          #language en-US "  HSIC #0"
+#string STR_USB_HSIC_0_HELP                            #language en-US "Enable/Disable HSIC #0. Enabling HSIC #0 will also enable USB4640 USB HUB with an useless card reader and impact responsiveness."
+
+#string STR_USB_XHCI_LPM_SUPPORT_PROMPT                #language en-US "USB2 Link Power Management"
+#string STR_USB_XHCI_LPM_SUPPORT_HELP                  #language en-US "Enable/Disable USB2 Link Power Management "
+
+#string STR_USB_AUTO_MODE_PROMPT                       #language en-US "USB Controller Auto Mode"
+#string STR_USB_AUTO_MODE_HELP                         #language en-US "If enabled, EHCI is enabled as default for A0. For A1 and later, XHCI is enabled as default."
+
+#string STR_PCH_USB30_MODE_PROMPT                      #language en-US "XHCI Mode"
+#string STR_PCH_USB30_MODE_HELP                        #language en-US "Mode of operation of xHCI controller."
+#string STR_PCH_USB30_STREAMS                          #language en-US "XHCI Streams"
+#string STR_PCH_USB30_STREAMS_HELP                     #language en-US "Enable/Disable XHCI Streams"
+//
+// USB Devices
+//
+#string STR_USB_OPTIONS_FORM_TITLE                     #language en-US "USB Configuration"
+#string STR_USB_OPTIONS_FORM_HELP                      #language en-US "USB Configuration Settings"
+
+#string STR_PCH_USB21_PROMPT                           #language en-US "EHCI Controller"
+#string STR_PCH_USB2_HELP                              #language en-US "Control the USB EHCI (USB 2.0) functions."
+#string STR_PCH_USB_PER_PORT_PROMPT                    #language en-US "USB Per-Port Control"
+#string STR_PCH_USB_PER_PORT_HELP                      #language en-US "Control each of the USB ports (0~3) enable/disable"
+#string STR_PCH_USB_PORT0_PROMPT                       #language en-US "USB Port #0"
+#string STR_PCH_USB_PORT1_PROMPT                       #language en-US "USB Port #1"
+#string STR_PCH_USB_PORT2_PROMPT                       #language en-US "USB Port #2"
+#string STR_PCH_USB_PORT3_PROMPT                       #language en-US "USB Port #3"
+#string STR_PCH_USB_PORT4_PROMPT                       #language en-US "USB Port #4"
+#string STR_PCH_USB_PORT5_PROMPT                       #language en-US "USB Port #5"
+#string STR_PCH_USB_PORT6_PROMPT                       #language en-US "USB Port #6"
+#string STR_PCH_USB_PORT7_PROMPT                       #language en-US "USB Port #7"
+#string STR_PCH_USB_PORT_DIS_HELP                      #language en-US "Enable/Disable USB port"
+#string STR_PCH_USBRMH_PROMPT                          #language en-US "USB RMH Mode"
+#string STR_PCH_USBRMH_HELP                            #language en-US "Enable/Disable PCH USB Rate Matching Hubs mode"
+#string STR_PCH_USB_EHCIDEBUG_PROMPT                   #language en-US "USB EHCI debug"
+#string STR_PCH_USB_EHCIDEBUG_HELP                     #language en-US "Enable/Disable PCH EHCI debug capability"
+
+#string STR_PCH_USB_OTG_PROMPT                         #language en-US "USB OTG Support"
+#string STR_PCH_USB_OTG_HELP                           #language en-US "Enable/Disable USB OTG Support"
+#string STR_PCH_USB_VBUS_PROMPT                        #language en-US "USB VBUS"
+#string STR_PCH_USB_VBUS_HELP                          #language en-US "VBUS should be ON in HOST mode. It should be OFF in OTG device mode. VBUS is forced to Auto mode for FFRD-PR1 since FSA mux will control it."
+#string STR_PCH_FSA_PROMPT                             #language en-US "FSA ON"
+#string STR_PCH_FSA_HELP                               #language en-US "FSA should be ON for PR1"
+
+#string STR_PCI_MODE_STRING                            #language en-US "PCI Mode"
+#string STR_ACPI_MODE_STRING                           #language en-US "ACPI Mode"
+
+#string STR_SMARTAUTO_STRING                           #language en-US "Smart Auto"
+
+#string STR_DEVICE_SUBTITLE                            #language en-US "Onboard Devices"
+
+#string STR_LAN_PROMPT                                 #language en-US "LAN"
+#string STR_LAN_HELP                                   #language en-US "Enables or Disables the Onboard LAN Controller."
+
+//
+// GbE
+//
+#string STR_LAN_OPTIONS_FORM_TITLE                     #language en-US  "LAN Configuration"
+#string STR_LAN_OPTIONS_FORM_HELP                      #language en-US  "LAN Configuration Settings"
+
+#string STR_PCH_LAN_CONTROLLER                         #language en-US  "LAN Controller"
+#string STR_PCH_LAN_CONTROLLER_HELP                    #language en-US  "Enable/Disable onboard NIC"
+#string STR_PCH_LAN_WOL_PROMPT                         #language en-US  "  Wake on LAN Enable"
+#string STR_PCH_LAN_WOL_HELP                           #language en-US  "Enable/Disable integrated LAN to wake the system"
+#string STR_PCH_SLP_LAN_LOW_DC_PROMPT                  #language en-US  "  SLP_LAN# Low on DC Power"
+#string STR_PCH_SLP_LAN_LOW_DC_HELP                    #language en-US  "Enable/Disable SLP_LAN# Low on DC Power"
+
+#string STR_PCH_PXEROM_CONTROL                         #language en-US "PXE ROM"
+#string STR_PCH_PXEROM_CONTROL_HELP                    #language en-US "Enable/Disable PXE Option ROM execution for onboard LAN"
+
+//
+// Azalia
+//
+#string STR_AZALIA_OPTIONS_FORM_TITLE                  #language en-US "Audio Configuration"
+#string STR_AZALIA_OPTIONS_FORM_HELP                   #language en-US "Audio Configuration Settings"
+
+#string STR_PCH_AZALIA_PROMPT                          #language en-US "Audio Controller"
+#string STR_PCH_AZALIA_HELP                            #language en-US "Control Detection of the Azalia device.\n\nDisabled = Azalia will be unconditionally disabled\n\nEnabled = Azalia will be unconditionally Enabled\n\nAuto = Azalia will be enabled if present, disabled otherwise"
+#string STR_PCH_AZALIA_DS_SUPPORT                      #language en-US "Always enable Azalia while Azalia Docking Support is enabled"
+
+#string STR_AZALIA_VC_PROMPT                           #language en-US "  Azalia VCi Enable"
+#string STR_AZALIA_VC_HELP                             #language en-US "Enable/Disable Virtual Channel 1 of Audio Controller"
+#string STR_AZALIA_DS_PROMPT                           #language en-US "  Azalia Docking Support Enable"
+#string STR_AZALIA_DS_HELP                             #language en-US "Enable/Disable Azalia Docking Support of Audio Controller"
+#string STR_AZALIA_PME_PROMPT                          #language en-US "  Azalia PME Enable"
+#string STR_AZALIA_PME_HELP                            #language en-US "Enable/Disable Power Management capability of Audio Controller"
+#string STR_HDMI_CODEC_PROMPT                          #language en-US "  Azalia HDMI Codec"
+#string STR_HDMI_CODEC_HELP                            #language en-US "Enable/Disable internal HDMI codec for Azalia"
+
+#string STR_HDMI_CODEC_PORTB_PROMPT                    #language en-US "  Azalia HDMI codec Port B"
+#string STR_HDMI_CODEC_PORTC_PROMPT                    #language en-US "  Azalia HDMI codec Port C"
+#string STR_HDMI_CODEC_PORTD_PROMPT                    #language en-US "  Azalia HDMI codec Port D"
+#string STR_HDMI_CODEC_PORT_HELP                       #language en-US "Enable/Disable internal HDMI codec Port for Azalia"
+//
+// Misc.
+//
+#string STR_MISC_OPTION_FORM_TITLE                     #language en-US "Miscellaneous Configuration"
+#string STR_MISC_OPTION_FORM_HELP                      #language en-US "Enable/Disable Misc. Features"
+
+#string STR_HPET_PROMPT                                #language en-US "High Precision Timer"
+#string STR_HPET_HELP                                  #language en-US "Enable or Disable the High Precision Event Timer"
+#string STR_HPET_BOOTTIME_PROMPT                       #language en-US "Boot Time with HPET Timer"
+#string STR_HPET_BOOTTIME_HELP                         #language en-US "Boot time calculation with High Precision Event Timer enabled"
+
+
+#string STR_CLOCK_SPREAD_SPEC_ENABLE                   #language en-US "Clock Spread Spectrum"
+#string STR_CLOCK_SPREAD_SPEC_ENABLE_HELP              #language en-US "Enable Clock Chip's Spread Spectrum feature"
+
+
+#string STR_STATE_AFTER_G3                             #language en-US "State After G3"
+#string STR_STATE_AFTER_G3_HELP                        #language en-US "Specify what state to go to when power is re-applied after a power failure (G3 state)"
+#string STR_S0_AFTER_G3_STRING                         #language en-US "S0 State"
+#string STR_S5_AFTER_G3_STRING                         #language en-US "S5 State"
+
+#string STR_PCH_UART_SELECT                            #language en-US "UART Interface Selection"
+#string STR_PCH_UART_SELECT_HELP                       #language en-US "Select which UART interface to use"
+#string STR_UART_SELECT_PCU                            #language en-US "Internal UART"
+#string STR_UART_SELECT_SIO                            #language en-US "SuperIO UART"
+
+#string STR_PCU_UART_A                                 #language en-US "PCU UART COM 1"
+#string STR_PCU_UART_A_HELP                            #language en-US "Enable/Disable Onboard PCU UART COM 1"
+#string STR_PCU_UART_B                                 #language en-US "PCU UART COM 2"
+#string STR_PCU_UART_B_HELP                            #language en-US "Enable/Disable Onboard PCU UART COM 2"
+
+#string STR_AUDIO_PROMPT                               #language en-US  "Audio"
+#string STR_AUDIO_HELP                                 #language en-US  "Enables or Disables Onboard Audio."
+
+#string STR_LPE_PROMPT                                 #language en-US  "LPE"
+#string STR_LPE_HELP                                   #language en-US  "Enables or Disables Onboard LPE Sub-System."
+
+#string STR_GPIO_WAKE_CAPABILITY_ENABLE                #language en-US "GPIO Wake Capability"
+#string STR_GPIO_WAKE_CAPABILITY_ENABLE_HELP           #language en-US "Enable or Disable GPIO Wake Capability"
+
+#string STR_RTC_BATTERY                                #language en-US "RTC Battery Presence"
+#string STR_RTC_BATTERY_PRESENT                        #language en-US "Present"
+#string STR_RTC_BATTERY_NOT_PRESENT                    #language en-US "Not Present"
+#string STR_RTC_BATTERY_HELP                           #language en-US "RTC Battery is Present or Not Present"
+
+#string STR_LPE_REPORTED_BY_DSDT_PROMPT                #language en-US  "LPE Audio Reported By DSDT"
+#string STR_LPE_REPORTED_BY_DSDT_HELP                  #language en-US  "Recommended solution is to keep option disabled and expose LPE Audio device with an EFI application that updates the SSDT"
+
+//
+// PCI Express
+//
+#string STR_PCIE_OPTIONS_FORM_TITLE                    #language en-US  "PCI Express Configuration"
+#string STR_PCIE_OPTIONS_FORM_HELP                     #language en-US  "PCI Express Configuration Settings"
+#string STR_ICH_PCIERP1_PROMPT                         #language en-US  "PCI Express Root Port 1"
+#string STR_ICH_PCIERP2_PROMPT                         #language en-US  "PCI Express Root Port 2"
+#string STR_ICH_PCIERP3_PROMPT                         #language en-US  "PCI Express Root Port 3"
+#string STR_ICH_PCIERP4_PROMPT                         #language en-US  "PCI Express Root Port 4"
+#string STR_ICH_PCIERP_HELP                            #language en-US  "Control the PCI Express Root Port."
+#string STR_ICH_PCIERP_DISABLE_HELP                    #language en-US  "This Root Port is disabled because Root Port 1 is disabled."
+#string STR_PCIEDYNCLK_PROMPT                          #language en-US  "PCI Express Dynamic Clock Gating"
+#string STR_PCIEDYNCLK_HELP                            #language en-US  "Enable/Disable PCIE Dynamic Clock Gating"
+
+#string STR_IDE_FORM_TITLE                             #language en-US "SATA Drives"
+#string STR_IDE_FORM_HELP                              #language en-US "Press <Enter> to select the SATA Device Configuration Setup options."
+
+#string STR_DISCRETE_SATA_STRING                       #language en-US "Discrete-SATA Controller Configuration"
+#string STR_CHIPSET_SATA_STRING                        #language en-US "Chipset-SATA Controller Configuration"
+
+#string STR_SATA_PROMPT                                #language en-US  " Chipset SATA"
+#string STR_SATA_HELP                                  #language en-US  "Enables or Disables the Chipset SATA Controller.  The Chipset SATA controller supports the 2 black internal SATA ports (up to 3Gb/s supported per port)."
+
+#string STR_SATA_TYPE_PROMPT                           #language en-US  " Chipset SATA Mode"
+#string STR_SATA_TYPE_PROMPT                           #language fr-FR  " Configurer SATA comme"
+
+#string STR_SATA_TYPE_HELP                             #language en-US  "This will configure SATA into the corresponding types."
+#string STR_SATA_TYPE_HELP                             #language fr-FR  "Configure SATA selon les types correspondants."
+#string STR_SATA_TYPE_HELP1                            #language en-US  "IDE: Compatibility mode disables AHCI support. AHCI: Supports advanced SATA features such as Native Command Queuing.     \nWarning: OS may not boot if this setting is changed after OS install."
+
+#string STR_SATA_IDE                                   #language en-US  "IDE"
+#string STR_SATA_AHCI                                  #language en-US  "AHCI"
+
+#string STR_SATA0_STRING                               #language en-US "  SATA Port 0"
+#string STR_SATA0_STRING                               #language fr-FR "  Port SATA 0"
+
+#string STR_SATA0_NAME                                 #language en-US  "[Not Installed]"
+#string STR_SATA0_NAME                                 #language fr-FR  "[Absent]"
+
+#string STR_MSATA_STRING                               #language en-US "  mSATA Port"
+
+#string STR_SATA1_STRING                               #language en-US "  SATA Port 1"
+#string STR_SATA1_STRING                               #language fr-FR "  Port SATA 1"
+
+#string STR_SATA1_NAME                                 #language en-US  "[Not Installed]"
+#string STR_SATA1_NAME                                 #language fr-FR  "[Absent]"
+
+#string STR_SATA0_HOTPLUG_CAP_PROMPT                   #language en-US "  SATA Port 0 Hot Plug Capability"
+#string STR_SATA1_HOTPLUG_CAP_PROMPT                   #language en-US "  SATA Port 1 Hot Plug Capability"
+#string STR_SATA_HOTPLUG_CAP_HELP                      #language en-US "If enabled, SATA port will be reported as Hot Plug capable."
+
+#string STR_SENSOR_FORM_TITLE                          #language en-US "Sensor setting"
+#string STR_SENSOR_FORM_HELP                           #language en-US "Press <Enter> to select the Sensor Configuration Setup options."
+
+//
+//Sensor Settings
+//
+#string STR_SENSOR_SUBTITLE                            #language en-US  "Sensor Modules Setting"
+#string STR_ACCELEROMETER_PROMPT                       #language en-US  "Accelerometer"
+#string STR_ACCELEROMETER_HELP                         #language en-US  "This will configure disable/enable Accelerometer."
+#string STR_GYROMETER_PROMPT                           #language en-US  "Gyrometer"
+#string STR_GYROMETER_HELP                             #language en-US  "This will configure disable/enable Gyrometer."
+#string STR_BAROMETER_PROMPT                           #language en-US  "Barometer"
+#string STR_BAROMETER_HELP                             #language en-US  "This will configure disable/enable Barometer."
+#string STR_PROXIMITY_SENSOR_PROMPT                    #language en-US  "Proximity Sensor"
+#string STR_PROXIMITY_SENSOR_HELP                      #language en-US  "This will configure disable/enable Proximity Sensor."
+#string STR_COMPASS_PROMPT                             #language en-US  "Compass"
+#string STR_COMPASS_HELP                               #language en-US  "This will configure disable/enable Compass."
+#string STR_NFS_PROMPT                                 #language en-US  "NFS"
+#string STR_NFS_HELP                                   #language en-US  "This will configure disable/enable NFS."
+
+#string STR_LPSS_SCC_FORM_TITLE                        #language en-US  "LPSS & SCC Configuration"
+#string STR_LPSS_SCC_FORM_HELP                         #language en-US  ""
+
+#string STR_LPSS_PCI_PROMPT                            #language en-US  "LPSS & SCC Devices Mode"
+#string STR_LPSS_PCI_HELP                              #language en-US  "Enable/Disable LPSS & SCC Devices Mode"
+
+#string STR_SCC_SETTING_SUBTITLE                       #language en-US  "SCC Configuration"
+#string STR_SCC_EMMC_PROMPT                            #language en-US  "SCC eMMC Support"
+#string STR_SCC_EMMC_HELP                              #language en-US  "Enable/Disable SCC eMMC Support"
+#string STR_SCC_SDIO_PROMPT                            #language en-US  "SCC SDIO Support "
+#string STR_SCC_SDIO_HELP                              #language en-US  "Enable/Disable SCC SDIO Support"
+#string STR_SCC_SDCARD_PROMPT                          #language en-US  "SCC SD Card Support"
+#string STR_SCC_SDCARD_HELP                            #language en-US  "Enable/Disable SCC SD Card Support"
+#string STR_SCC_SDCARD_FORWIN_PROMPT                   #language en-US  "SCC SD Card for Windows"
+#string STR_SCC_SDCARD_FORWIN_HELP                     #language en-US  "Enable/Disable SCC SD Card for Windows"
+#string STR_SCC_SDIO_MODE_PROMPT                       #language en-US  "SCC SDIO Mode for WIFI"
+#string STR_SCC_SDIO_MODE_HELP                         #language en-US  "Select SDIO mode for WIFI, only for A0/A1 stepping."
+#string STR_SCC_SDCARD_REMOVABILITY                    #language en-US  "ACPI Reporting MMC/SD Media As"
+#string STR_SCC_SDCARD_REMOVABLE                       #language en-US  "Removable"
+#string STR_SCC_SDCARD_NON_REMOVABLE                   #language en-US  "Non-Removable"
+#string STR_SCC_SDCARD_REMOVABILITY_HELP               #language en-US  "ACPI Reporting MMC/SD Media to Win 8 as non-Removable."
+
+#string STR_SDIO_DEFAULT_MODE                          #language en-US  "Default"
+#string STR_SDIO_DDR50_MODE                            #language en-US  "DDR50"
+
+#string STR_LPSS1_SETTING_SUBTITLE                     #language en-US  "LPSS 1 Configuration"
+#string STR_LPSS2_SETTING_SUBTITLE                     #language en-US  "LPSS 2 Configuration"
+#string STR_LPSS_DMA1_PROMPT                           #language en-US  "LPSS DMA #1 Support"
+#string STR_LPSS_DMA1_HELP                             #language en-US  "Enable/Disable LPSS DMA #1 Support"
+#string STR_LPSS_DMA2_PROMPT                           #language en-US  "LPSS DMA #2 Support"
+#string STR_LPSS_DMA2_HELP                             #language en-US  "Enable/Disable LPSS DMA #2 Support"
+#string STR_LPSS_I2C1_PROMPT                           #language en-US  "LPSS I2C #1 Support"
+#string STR_LPSS_I2C1_HELP                             #language en-US  "Enable/Disable LPSS I2C #1 Support"
+#string STR_LPSS_I2C2_PROMPT                           #language en-US  "LPSS I2C #2 Support"
+#string STR_LPSS_I2C2_HELP                             #language en-US  "Enable/Disable LPSS I2C #2 Support"
+#string STR_LPSS_I2C3_PROMPT                           #language en-US  "LPSS I2C #3 Support"
+#string STR_LPSS_I2C3_HELP                             #language en-US  "Enable/Disable LPSS I2C #3 Support"
+#string STR_LPSS_I2C4_PROMPT                           #language en-US  "LPSS I2C #4 Support"
+#string STR_LPSS_I2C4_HELP                             #language en-US  "Enable/Disable LPSS I2C #4 Support"
+#string STR_LPSS_I2C5_PROMPT                           #language en-US  "LPSS I2C #5 Support"
+#string STR_LPSS_I2C5_HELP                             #language en-US  "Enable/Disable LPSS I2C #5 Support"
+#string STR_LPSS_I2C6_PROMPT                           #language en-US  "Low Speed Expansion I2C (#5)"
+#string STR_LPSS_I2C6_HELP                             #language en-US  "Enable/Disable Low Speed Expansion I2C (#5);I2C Controller PCI device Dev24: Func6; Schematic names it I2C5, ACPI table names it I2C6"
+#string STR_LPSS_I2C7_PROMPT                           #language en-US  "High Speed Expansion I2C (#6)"
+#string STR_LPSS_I2C7_HELP                             #language en-US  "Enable/Disable High Speed Expansion I2C (#6);I2C Controller PCI device Dev24: Func7; Schematic names it I2C6, ACPI table names it I2C7"
+#string STR_LPSS_I2S_PROMPT                            #language en-US  "LPSS I2S Support"
+#string STR_LPSS_I2S_HELP                              #language en-US  "Enable/Disable LPSS I2S Support"
+#string STR_LPSS_HSUART1_PROMPT                        #language en-US  "LPSS HSUART #1 Support"
+#string STR_LPSS_HSUART1_FLOWCONTROL_PROMPT            #language en-US  "LPSS HSUART #1 FlowCtrl"
+#string STR_LPSS_HSUART2_FLOWCONTROL_PROMPT            #language en-US  "LPSS HSUART #2 FlowCtrl"
+#string STR_LPSS_HSUART1_HELP                          #language en-US  "Enable/Disable LPSS HSUART #1 Support"
+#string STR_LPSS_HSUART2_PROMPT                        #language en-US  "LPSS HSUART #2 Support"
+#string STR_LPSS_HSUART2_HELP                          #language en-US  "Enable/Disable LPSS HSUART #2 Support"
+#string STR_LPSS_SPI_PROMPT                            #language en-US  "LPSS SPI Support"
+#string STR_LPSS_SPI_HELP                              #language en-US  "Enable/Disable LPSS SPI Support"
+
+#string STR_LPSS_I2C1_HELP_ENBDT_DEV_LIST              #language en-US  "Disable/Enable LPSS I2C #1 Support\n\n  "
+#string STR_LPSS_I2C2_HELP_ENBDT_DEV_LIST              #language en-US  "Disable/Enable LPSS I2C #2 Support\n\n  "
+#string STR_LPSS_I2C3_HELP_ENBDT_DEV_LIST              #language en-US  "Disable/Enable LPSS I2C #3 Support\n\n  "
+#string STR_LPSS_I2C4_HELP_ENBDT_DEV_LIST              #language en-US  "Disable/Enable LPSS I2C #4 Support\n\n  "
+#string STR_LPSS_I2C5_HELP_ENBDT_DEV_LIST              #language en-US  "Disable/Enable LPSS I2C #5 Support\n\n  "
+#string STR_LPSS_I2C6_HELP_ENBDT_DEV_LIST              #language en-US  "Enable/Disable Low Speed Expansion I2C (#5);I2C Controller PCI device Dev24: Func6; Schematic names it I2C5, ACPI table names it I2C6\n\n  "
+#string STR_LPSS_I2C7_HELP_ENBDT_DEV_LIST              #language en-US  "Enable/Disable High Speed Expansion I2C (#6);I2C Controller PCI device Dev24: Func7; Schematic names it I2C6, ACPI table names it I2C7\n\n  "
+#string STR_LPSS_HSUART1_HELP_ENBDT_DEV_LIST           #language en-US  "Disable/Enable LPSS High Speed UART #1\n\nEnabled(RX/TX/RTS/CTS)\nW\O FlowCtrl(RX/TX+GPIOx2)\nDisabled(GPIOx4)"
+#string STR_LPSS_HSUART2_HELP_ENBDT_DEV_LIST           #language en-US  "Disable/Enable LPSS High Speed UART #2\n\nEnabled(RX/TX/RTS/CTS)\nW\O FlowCtrl(RX/TX+GPIOx2)\nDisabled(GPIOx4)"
+
+#string STR_I2C_DEVICE_SETTING_SUBTITLE                #language en-US  "I2C Devics Configuration"
+#string STR_I2C_TOUCH_PROMPT                           #language en-US  "I2C Touch Devic Address"
+#string STR_I2C_TOUCH_HELP                             #language en-US  "I2C Touch Address Select:\n  RVP/iCDK(0x4B)\n  FFRD(0x4A)"
+#string STR_I2C_FFRD                                   #language en-US  "0x4A"
+#string STR_I2C_FVP                                    #language en-US  "0x4B"
+
+
+#string STR_PWM1_PROMPT                                #language en-US  "LPSS PWM #1 Support"
+#string STR_PWM1_HELP                                  #language en-US  "Enable/DisableLPSS PWM #1 Support"
+#string STR_PWM2_PROMPT                                #language en-US  "LPSS PWM #2 Support"
+#string STR_PWM2_HELP                                  #language en-US  Enable/Disable"LPSS PWM #2 Support"
+#string STR_MIPI_HSI_PROMPT                            #language en-US  "MIPI HSI Support"
+#string STR_MIPI_HSI_HELP                              #language en-US  "Enable/Disable MIPI HSI Support \n Note: Official BIOS cannot support MIPI display directly even you select enable here. MIPI VBT is specific to different panel, user need replace VBT manually."
+#string STR_LPE_PROMPT                                 #language en-US  "LPE Audio Support"
+#string STR_LPE_HELP                                   #language en-US  "Enable/Disable LPE Audio Support"
+#string STR_LPE_PCI_MODE                               #language en-US  "LPE Audio PCI mode"
+#string STR_LPE_ACPI_MODE                              #language en-US  "LPE Audio ACPI mode"
+
+//
+// ISCT Configuration
+//
+#string STR_ISCT_FORM_TITLE                            #language en-US  "ISCT Configuration"
+#string STR_ISCT_FORM_HELP                             #language en-US  "ISCT / AOAC Configuration Settings"
+
+#string STR_ISCT_CONFIGURATION                         #language en-US  "ISCT Configuration"
+#string STR_ISCT_CONFIGURATION_HELP                    #language en-US  "Enable/Disable ISCT Feature"
+
+#string STR_ISCT_NOTIFICATION_CONTROL_PROMPT           #language en-US  "ISCT Notification Control"
+#string STR_ISCT_NOTIFICATION_CONTROL_HELP             #language en-US  "Enable/Disable ISCT Notification Control"
+#string STR_ISCT_WLAN_CONTROL_PROMPT                   #language en-US  "ISCT WLAN Power Control"
+#string STR_ISCT_WLAN_CONTROL_HELP                     #language en-US  "Enable/Disable ISCT WLAN Power Control"
+#string STR_ISCT_WWAN_CONTROL_PROMPT                   #language en-US  "ISCT WWAN Power Control"
+#string STR_ISCT_WWAN_CONTROL_HELP                     #language en-US  "Enable/Disable ISCT WWAN Power Control"
+
+#string STR_ISCT_SLEEP_DURATION_FORMAT                 #language en-US  "ISCT Sleep Duration Value Format"
+#string STR_ISCT_SLEEP_DURATION_FORMAT_HELP            #language en-US  "ISCT Sleep Duration is only in Seconds Format, Actual time format is not supported"
+
+#string STR_ISCT_RF_KILL_SUPPORT                       #language en-US  "ISCT RF Kill Support"
+#string STR_ISCT_RF_KILL_SUPPORT_HELP                  #language en-US  "ISCT RF Kill (Radio On/Off) is based on Soft switch, No physical switch available"
+
+#string STR_SECONDS                                    #language en-US  "Seconds"
+#string STR_ACTUAL_TIME                                #language en-US  "Actual Time"
+
+#string STR_RF_KILL_SOFT                               #language en-US  "Soft Switch"
+#string STR_RF_KILL_PHYSICAL                           #language en-US  "Physical Switch"
+
+#string STR_WLAN_PRESENCE_FORM_TITLE                   #language en-US  "WLAN Card Presence"
+#string STR_WLAN_NGFF_CARD                         #language en-US  "NGFF Card Inserted"
+#string STR_WLAN_NGFF_HELP                         #language en-US  "Set 'YES' If NGFF Card is Inserted"
+#string STR_WLAN_UHPAM_CARD                            #language en-US  "UHPAM Card Inserted"
+#string STR_WLAN_UHPAM_HELP                            #language en-US  "Set 'YES' If UHPAM Card is Inserted"
+
+//
+// THERMAL INFORMATION
+//
+
+//
+// S0iX supported or not
+//
+#string STR_S0IX_PROMPT                                #language en-US  "S0ix"
+#string STR_S0IX_HELP                                  #language en-US  "Set platform to configure S0ix supported or not"
+
+#string STR_THERMAL_CONFIGURATION                      #language en-US "Processor Participant"
+#string STR_THERMAL_CONFIGURATION_HELP                 #language en-US "Thermal Configuration Parameters"
+
+
+#string STR_ACPI_PASSIVE_THERMAL_TRIP_POINT            #language en-US "Passive Trip Point"
+#string STR_ACPI_PASSIVE_THERMAL_TRIP_POINT_HELP       #language en-US "This value controls the temperature of the ACPI Passive Trip Point - the point in which the OS will begin throttling the processor."
+#string STR_ACPI_CRITICAL_THERMAL_TRIP_POINT           #language en-US "Critical Trip Point"
+#string STR_ACPI_CRITICAL_THERMAL_TRIP_POINT_HELP      #language en-US "This value controls the temperature of the ACPI Critical Trip Point - the point in which the OS will shut the system off."
+#string STR_15_C                                       #language en-US "15 C"
+#string STR_23_C                                       #language en-US "23 C"
+#string STR_31_C                                       #language en-US "31 C"
+#string STR_39_C                                       #language en-US "39 C"
+#string STR_47_C                                       #language en-US "47 C"
+#string STR_55_C                                       #language en-US "55 C"
+#string STR_63_C                                       #language en-US "63 C"
+#string STR_71_C                                       #language en-US "71 C"
+#string STR_79_C                                       #language en-US "79 C"
+#string STR_85_C                                       #language en-US "85 C"
+#string STR_87_C                                       #language en-US "87 C"
+#string STR_90_C                                       #language en-US "90 C"
+#string STR_95_C                                       #language en-US "95 C"
+#string STR_100_C                                      #language en-US "100 C"
+#string STR_103_C                                      #language en-US "103 C"
+#string STR_105_C                                      #language en-US "105 C"
+#string STR_110_C                                      #language en-US "110 C"
+#string STR_111_C                                      #language en-US "111 C"
+#string STR_119_C                                      #language en-US "119 C"
+#string STR_180_C                                      #language en-US "180 C"
+#string STR_200_C                                      #language en-US "200 C"
+#string STR_POR                                        #language en-US "POR"
+#string STR_0LEN                                       #language en-US ""
+
+#string STR_ACPI_PASSIVE_TC1_VALUE                     #language en-US "  Passive TC1 Value"
+#string STR_ACPI_PASSIVE_TC1_VALUE_HELP                #language en-US "This value sets the TC1 value for the ACPI Passive Cooling Formula. Range 1 - 16"
+#string STR_ACPI_PASSIVE_TC2_VALUE                     #language en-US "  Passive TC2 Value"
+#string STR_ACPI_PASSIVE_TC2_VALUE_HELP                #language en-US "This value value sets the TC2 value for the ACPI Passive Cooling Formula. Range 1 - 16"
+#string STR_ACPI_PASSIVE_TSP_VALUE                     #language en-US "  Passive TSP Value"
+#string STR_ACPI_PASSIVE_TSP_VALUE_HELP                #language en-US "This item sets the TSP value for the ACPI Passive Cooling Formula.  It represents in tenths of a second how often the OS will read the temperature when passive cooling is enabled. Range 2 - 32"
+
+#string STR_DPTF_CONFIGURATION                         #language en-US "DPTF Configuration"
+
+#string STR_DATP_PROMPT                                #language en-US "Active Trip Points"
+#string STR_DATP_HELP                                  #language en-US "Disable Active Trip Points"
+
+
+//
+// DPTF Form
+//
+#string STR_DPTF_PROMPT                                #language en-US  "DPTF"
+#string STR_DPTF_HELP                                  #language en-US  "Enable/Disable DPTF"
+#string STR_ACTIVE_PROMPT                              #language en-US  "Active"
+#string STR_ACTIVE_HELP                                #language en-US  ""
+#string STR_CTDP_PROMPT                                #language en-US  "CTDP"
+#string STR_CTDP_HELP                                  #language en-US  ""
+#string STR_COOLING_MODE_PROMPT                        #language en-US  "Cooling Mode"
+#string STR_COOLING_MODE_HELP                          #language en-US  ""
+#string STR_CRITICAL_PROMPT                            #language en-US  "Critical"
+#string STR_CRITICAL_HELP                              #language en-US  ""
+
+#string STR_DPTF_CLPM_PROMPT                           #language en-US  "CLPM"
+
+#string STR_DPTF_CLPM_HELP                             #language en-US  "Current Low Power Mode"
+
+#string STR_DPTF_LPM_APP                               #language en-US  "Application specific"
+
+#string STR_DPTF_LPM_OS                                #language en-US  "OS level"
+
+#string STR_DPTF_SYSTHERM0_PROMPT                      #language en-US  "T1 Sensor"            // Skin Temperature Sensor 0
+#string STR_DPTF_SYSTHERM0_HELP                        #language en-US  "Enable/Disable T1 skin sensor"
+#string STR_DPTF_THERM0_PCAT_PROMPT                    #language en-US  "CPU Sensors"
+#string STR_DPTF_THERM0_PCAT_HELP                      #language en-US  "Enable/Disable CPU Temperature Sensors"
+
+#string STR_DPTF_SYSTHERM1_PROMPT                      #language en-US  "Display Board Sensor" //System Thermal Sensor 1
+#string STR_DPTF_SYSTHERM1_HELP                        #language en-US  "Enable/Disable Display Board skin Sensor"
+#string STR_DPTF_THERM1_PCAT_PROMPT                    #language en-US  "Ambient Sensors"
+#string STR_DPTF_THERM1_PCAT_HELP                      #language en-US  "Enable/Disable Ambient Temperature Sensors"
+
+#string STR_DPTF_SYSTHERM2_PROMPT                      #language en-US  "SOC Board Sensor"     //System Thermal Sensor 2
+#string STR_DPTF_SYSTHERM2_HELP                        #language en-US  "Enable/Disable SOC Board skin Sensor"
+#string STR_DPTF_THERM2_PCAT_PROMPT                    #language en-US  "DDR Sensors"
+#string STR_DPTF_THERM2_PCAT_HELP                      #language en-US  "Enable/Disable DDR Temperature Sensors"
+
+#string STR_DPTF_SYSTHERM3_PROMPT                      #language en-US  "Charger Board Sensor" //System Thermal Sensor 3
+#string STR_DPTF_SYSTHERM3_HELP                        #language en-US  "Enable/Disable ULPMC Skin Temperature Sensor"
+#string STR_DPTF_SYSTHERM4_PROMPT                      #language en-US  "Ambient Temperature"
+#string STR_DPTF_SYSTHERM4_HELP                        #language en-US  "Enable/Disable Ambient Temperature"
+#string STR_DPTF_AMBIENTTRIPPOINTCHANGE_PROMPT         #language en-US  "Ambient based Trip Point Change"
+#string STR_DPTF_AMBIENTTRIPPOINTCHANGE_HELP           #language en-US  "This controls the Action part of the Ambient participant. When disabled, trip points would not be changed when Ambient participant notifies the FW of a new ambient temperature via _ATI."
+#string STR_DPTF_ALLOWHIGHERPERFORMANCE_PROMPT         #language en-US  "Allow higher performance on AC/USB"
+#string STR_DPTF_ALLOWHIGHERPERFORMANCE_HELP           #language en-US  "On AC/USB power source allow for higher performance and relax tablet skin temperature to higher limits. Warning: Note users may feel warm tablet skin."
+#string STR_DPTF_CHARGER_PROMPT                        #language en-US  "Charger Participant"
+#string STR_DPTF_CHARGER_HELP                          #language en-US  "Enable/Disable Charger Participant Device"
+#string STR_DPTF_DISPLAY_PROMPT                        #language en-US  "Display Participant"
+#string STR_DPTF_DISPLAY_HELP                          #language en-US  "Enable/Disable Display Participant Device"
+#string STR_DPTF_SOC_PROMPT                            #language en-US  "Power Participant"
+#string STR_DPTF_SOC_HELP                              #language en-US  "Enable/Disable Power Participant Device"
+#string STR_PROCESSOR_DPTF_PROMPT                      #language en-US  "DPTF Processor"
+#string STR_PROCESSOR_DPTF_HELP                        #language en-US  "Enable/Disable Processor Participant Device"
+
+#string STR_PASSIVE_PROMPT                             #language en-US  "Passive"
+#string STR_PASSIVE_HELP                               #language en-US  ""
+
+#string STR_DPTF_GENERIC_PARTICIPANT                   #language en-US  "DPTF Generic Sensor Participant"
+#string STR_DPTF_CRITICAL_TEMP                         #language en-US  "Critical"
+#string STR_DPTF_PASSIVE_TEMP                          #language en-US  "Passive"
+#string STR_DPTF_CRITICAL_TEMP_HELP                    #language en-US  "Critical Temperature"
+#string STR_DPTF_PASSIVE_TEMP_HELP                     #language en-US  "Passive Temperature"
+#string STR_DPTF_25_C                                  #language en-US  "25 C"
+#string STR_DPTF_30_C                                  #language en-US  "30 C"
+#string STR_DPTF_35_C                                  #language en-US  "35 C"
+#string STR_DPTF_40_C                                  #language en-US  "40 C"
+#string STR_DPTF_45_C                                  #language en-US  "45 C"
+#string STR_DPTF_50_C                                  #language en-US  "50 C"
+#string STR_DPTF_55_C                                  #language en-US  "55 C"
+#string STR_DPTF_60_C                                  #language en-US  "60 C"
+#string STR_DPTF_65_C                                  #language en-US  "65 C"
+#string STR_DPTF_70_C                                  #language en-US  "70 C"
+#string STR_DPTF_75_C                                  #language en-US  "75 C"
+#string STR_DPTF_80_C                                  #language en-US  "80 C"
+#string STR_DPTF_85_C                                  #language en-US  "85 C"
+#string STR_DPTF_90_C                                  #language en-US  "90 C"
+#string STR_DPTF_95_C                                  #language en-US  "95 C"
+#string STR_DPTF_100_C                                 #language en-US  "100 C"
+#string STR_DPTF_105_C                                 #language en-US  "105 C"
+#string STR_DPTF_110_C                                 #language en-US  "110 C"
+#string STR_DPTF_115_C                                 #language en-US  "115 C"
+#string STR_DPTF_120_C                                 #language en-US  "120 C"
+#string STR_DPTF_125_C                                 #language en-US  "125 C"
+#string STR_DPTF_52_C                                  #language en-US  "52 C"
+#string STR_DPTF_61_C                                  #language en-US  "61 C"
+#string STR_DPTF_64_C                                  #language en-US  "64 C"
+#string STR_DPTF_43_C                                  #language en-US  "43 C"
+#string STR_DPTF_57_C                                  #language en-US  "57 C"
+#string STR_DPTF_62_C                                  #language en-US  "62 C"
+#string STR_DPTF_78_C                                  #language en-US  "78 C"
+#string STR_DPTF_81_C                                  #language en-US  "81 C"
+
+#string STR_DPTF_GENERIC0_PART_PCAT                    #language en-US  "CPU Sensor Participants"
+#string STR_DPTF_GENERIC1_PART_PCAT                    #language en-US  "Ambient Sensor Participants"
+#string STR_DPTF_GENERIC2_PART_PCAT                    #language en-US  "DDR Sensor Participants"
+#string STR_DPTF_GENERIC0_PARTICIPANT                  #language en-US  "DPTF T1 Sensor Participant"
+#string STR_DPTF_GENERIC1_PARTICIPANT                  #language en-US  "DPTF Display Board Sensor Participant"
+#string STR_DPTF_GENERIC2_PARTICIPANT                  #language en-US  "DPTF SOC Board Sensor Participant"
+#string STR_DPTF_SDP                                   #language en-US  "Scenario Design Power"
+
+#string STR_DPTF_BRAND_STRING                          #language en-US  "Brand String"
+#string STR_DPTF_BRAND_STRING_HELP                     #language en-US  "Brand string for the processor, example Nxxx or Jxxx"
+
+#string STR_DPTF_N3510                                 #language en-US  "N3510/20"
+#string STR_DPTF_N2910                                 #language en-US  "N2910/20"
+#string STR_DPTF_N2810                                 #language en-US  "N2810/15/20"
+#string STR_DPTF_N2805                                 #language en-US  "N2805/06"
+#string STR_DPTF_J2850                                 #language en-US  "J2850/2900"
+#string STR_DPTF_J1850                                 #language en-US  "J1850/1900"
+#string STR_DPTF_J1750                                 #language en-US  "J1750/1800"
+
+#string STR_DPTF_GENERIC3_PARTICIPANT                  #language en-US  "DPTF Charger Board Sensor Participant"
+#string STR_DPTF_GENERIC4_PARTICIPANT                  #language en-US  "DPTF Generic Sensor4 Participant"
+#string STR_DPTF_CRITICAL_TEMP                         #language en-US  "Critical"
+#string STR_DPTF_PASSIVE_TEMP                          #language en-US  "Passive"
+#string STR_DPTF_CRITICAL_TEMP_HELP                    #language en-US  "Critical Temperature"
+#string STR_DPTF_PASSIVE_TEMP_HELP                     #language en-US  "Passive Temperature"
+#string STR_DPTF_CLPM                                  #language en-US  "CLPM"
+#string STR_DPTF_CLPM_HELP                             #language en-US  "Current Low Power Mode"
+#string STR_DPTF_LPM_APP                               #language en-US  "Application specific"
+#string STR_DPTF_LPM_OS                                #language en-US  "OS level"
+#string STR_DPTF_SDBG                                  #language en-US  "Super Debug"
+#string STR_DPTF_SDBG_HELP                             #language en-US  "Super debug is for validation purpose"
+#string STR_DPTF_OFFLINING                             #language en-US  "Processor Offlining"
+#string STR_DPTF_OFFLINING_HELP                        #language en-US  "Enable or disable processor offlining, passive policy only"
+#string STR_DPTF_CLPO                                  #language en-US  "Current Logical Processor Offlining"
+#string STR_DPTF_CLPO_HELP                             #language en-US  "Controls LPO Control preferences. Used only by Passive policy"
+#string STR_DPTF_CLPO_START_PINDEX                     #language en-US  "Start P-State"
+#string STR_DPTF_CLPO_START_PINDEX_HELP                #language en-US  "Instructs the policy when to initiate Active Core control if enabled"
+#string STR_DPTF_CLPO_PSTATE_INDEX0                    #language en-US  "P0"
+#string STR_DPTF_CLPO_PSTATE_INDEX1                    #language en-US  "P1"
+#string STR_DPTF_CLPO_PSTATE_INDEX2                    #language en-US  "P2"
+#string STR_DPTF_CLPO_PSTATE_INDEX3                    #language en-US  "P3"
+#string STR_DPTF_CLPO_PSTATE_INDEX4                    #language en-US  "P4"
+#string STR_DPTF_CLPO_PSTATE_INDEX5                    #language en-US  "P5"
+#string STR_DPTF_CLPO_PSTATE_INDEX6                    #language en-US  "P6"
+#string STR_DPTF_CLPO_PSTATE_INDEX7                    #language en-US  "P7"
+#string STR_DPTF_CLPO_PSTATE_INDEX8                    #language en-US  "P8"
+#string STR_DPTF_CLPO_PSTATE_INDEX9                    #language en-US  "P9"
+#string STR_DPTF_CLPO_PSTATE_INDEX10                   #language en-US  "P10"
+#string STR_DPTF_CLPO_PSTATE_INDEX11                   #language en-US  "P11"
+#string STR_DPTF_CLPO_PSTATE_INDEX12                   #language en-US  "P12"
+#string STR_DPTF_CLPO_STEP_SIZE                        #language en-US  "Step size"
+#string STR_DPTF_CLPO_STEP_SIZE_HELP                   #language en-US  "Instructs the policy to take away logical processors in the specified percentage steps."
+#string STR_DPTF_CLPO_STEP_SIZE_VALUE_25               #language en-US  "25%"
+#string STR_DPTF_CLPO_STEP_SIZE_VALUE_50               #language en-US  "50%"
+#string STR_DPTF_CLPO_STEP_SIZE_VALUE_75               #language en-US  "75%"
+#string STR_DPTF_CLPO_PWR_CTRL                         #language en-US  "Power Control Setting"
+#string STR_DPTF_CLPO_PWR_CTRL_HELP                    #language en-US  "Instructs the policy whether to use Core offliing if Active core control is enabled to be used in P0 or when power control is applied"
+#string STR_DPTF_CLPO_PERF_CTRL                        #language en-US  "Performance Control Setting"
+#string STR_DPTF_CLPO_PERF_CTRL_HELP                   #language en-US  "Instructs the policy whether to use Core offliing if Active core control is enabled to be used in P1 or when performance control is applied"
+#string STR_DPTF_SMT_OFFFLINING                        #language en-US  "SMT Offlining"
+#string STR_DPTF_CORE_OFFFLINING                       #language en-US  "Core Offlining"
+#string STR_DPTF_DPPM                                  #language en-US  "DPPM"
+#string STR_DPTF_DPPM_HELP                             #language en-US  "Controls DPPM policies"
+
+#string STR_DYNAMIC_PLATFORM_THER_FRAME_PROMPT         #language en-US  "Dynamic Platform&Thermal Framework"
+#string STR_DYNAMIC_PLATFORM_THER_FRAME_HELP           #language en-US  ""
+#string STR_DYNAMIC_PLATFORM_THER_FRAME_PROMPT         #language en-US  "Dynamic Platform&Thermal Framework"
+#string STR_DYNAMIC_PLATFORM_THER_FRAME_HELP           #language en-US  ""
+
+#string STR_DPTF_PASSIVE_TRIP_POINT_PROMPT             #language en-US "  Passive Trip Point"
+#string STR_DPTF_PASSIVE_TRIP_POINT_HELP               #language en-US ""
+#string STR_DPTF_ACTIVE_TRIP_POINT_PROMPT              #language en-US "  Active Trip Point"
+#string STR_DPTF_ACTIVE_TRIP_POINT_HELP                #language en-US ""
+#string STR_DPTF_CRITICAL_TRIP_POINT_PROMPT            #language en-US "  Critical Trip Point"
+#string STR_DPTF_CRITICAL_TRIP_POINT_HELP              #language en-US ""
+#string STR_DPTF_HOT_TRIP_POINT_PROMPT                 #language en-US "  Hot Trip Point"
+#string STR_DPTF_HOT_TRIP_POINT_HELP                   #language en-US ""
+#string STR_NEW                                        #language en-US  "New"
+#string STR_LEGACY                                     #language en-US  "Legacy"
+#string STR_CPU                                        #language en-US  "CPU"
+#string STR_SA                                         #language en-US  "SA"
+
+//
+//Memory
+//
+#string STR_MEMORY_SCRAMBLER_PROMPT                    #language en-US "Memory Scrambler"
+#string STR_MEMORY_SCRAMBLER_HELP                      #language en-US "Enable/Disable Memory Scrambler support."
+
+#string STR_GOP_TITLE                                  #language en-US "GOP Configuration"
+#string STR_GOP_VBIOS_SWITCH                           #language en-US "GOP Driver"
+#string STR_GOP_BRIGHTNESS_LEVEL                       #language en-US "GOP Brightness Level"
+#string STR_GOP_BRIGHTNESS_LEVEL_HELP                  #language en-US "Set GOP Brightness Level; Value ranges from 0-255"
+#string STR_GOP_VBIOS_SWITCH_HELP                      #language en-US "Enable GOP Driver will unload VBIOS; Disable it will load VBIOS"
+#string STR_GOP_BRIGHT_0                               #language en-US "0"
+#string STR_GOP_BRIGHT_20                              #language en-US "20"
+#string STR_GOP_BRIGHT_40                              #language en-US "40"
+#string STR_GOP_BRIGHT_60                              #language en-US "60"
+#string STR_GOP_BRIGHT_80                              #language en-US "80"
+#string STR_GOP_BRIGHT_100                             #language en-US "100"
+#string STR_GOP_BRIGHT_120                             #language en-US "120"
+#string STR_GOP_BRIGHT_140                             #language en-US "140"
+#string STR_GOP_BRIGHT_160                             #language en-US "160"
+#string STR_GOP_BRIGHT_180                             #language en-US "180"
+#string STR_GOP_BRIGHT_200                             #language en-US "200"
+#string STR_GOP_BRIGHT_220                             #language en-US "220"
+#string STR_GOP_BRIGHT_240                             #language en-US "240"
+#string STR_GOP_BRIGHT_255                             #language en-US "255"
+
+
+//
+//System Components
+//
+#string STR_PMIC_CONFIGURATION_TITLE                   #language en-US "PMIC Configuration"
+#string STR_PMIC_ACPI_OBJECT_PROMPT                    #language en-US "PMIC ACPI OBJECT"
+#string STR_PMIC_ACPI_OBJECT_HELP                      #language en-US "Enable/Disable PMIC ACPI Device."
+
+#string STR_PNP_CONFIGURATION_TITLE                    #language en-US "System Power and Performance(PnP) Configuration"
+#string STR_PNP_SETTING_PROMPT                         #language en-US "SoC PnP Setting"
+#string STR_PNP_SETTING_HELP                           #language en-US "Select SoC PnP setting mode. Auto detect mode will load the SoC PnP table against stepping."
+#string STR_PNP_POWER_STRING                           #language en-US "Performance"
+#string STR_PNP_PERFORMANCE_STRING                     #language en-US "Power"
+#string STR_PNP_POWER_PERFORMANCE_STRING               #language en-US "Auto Detect"
+#string STR_PNP_POWER_PERFORMANCE_STRING_A0            #language en-US "Ax Stepping"
+#string STR_PNP_POWER_PERFORMANCE_STRING_B0            #language en-US "Bx Stepping"
+
+#string STR_CFIO_PNP_SETTING_PROMPT                    #language en-US "CFIO/GPIO PnP Setting"
+#string STR_CFIO_PNP_SETTING_HELP                      #language en-US "Enable/Disable CFIO/GPIO PnP setting mode. When enabled, CFIO/GPIO unused pins will be in tri-state for power saving."
+
+#string STR_TRISTATE_LPC_PROMPT                        #language en-US "LPC PnP Setting"
+#string STR_TRISTATE_LPC_HELP                          #language en-US "Enable/Disable LPC PnP Setting. When enabled, the Lpc will diable clock and be placed in tri-state for power saveing when Bios hands over control to OS. If there is device connected to LPC bus, this setting should not be enabled."
+
+#string STR_SLP_S0IX_N_PROMPT                          #language en-US "Asset SLP_S0IX_N in S0ix"
+#string STR_SLP_S0IX_N_HELP                            #language en-US "Auto/Enable/Disable Asset SLP_S0IX_N in S0ix. In Auto mode, PMC will assert SLP_S0IX_N ONLY for PR1.4 and beyond, RVP plus Rohm B3 or Dialog C0 or Maxim. In Enable mode, PMC will assert the SLP_S0IX_N to save power regardless the board type."
+
+#string STR_CRID_SETTING_HELP                          #language en-US "Select the Revision ID reflected in PCI config space"
+#string STR_CRID_PROMPT                                #language en-US "CRID Setting"
+#string STR_CRID_0_STRING                              #language en-US "CRID_0"
+#string STR_CRID_1_STRING                              #language en-US "CRID_1"
+#string STR_CRID_2_STRING                              #language en-US "CRID_2"
+
+#string STR_PCIE_SPEED_PROMPT0                         #language en-US "PCIe 0 Speed"
+#string STR_PCIE_SPEED_PROMPT1                         #language en-US "PCIe 1 Speed"
+#string STR_PCIE_SPEED_PROMPT2                         #language en-US "PCIe 2 Speed"
+#string STR_PCIE_SPEED_PROMPT3                         #language en-US "PCIe 3 Speed"
+#string STR_SATA_TEST_MODE_PROMPT                      #language en-US "SATA Test Mode"
+#string STR_PCIE_SPEED_HELP                            #language en-US "Configure PCIe Speed"
+#string STR_AUTO                                       #language en-US "Auto"
+#string STR_GEN1                                       #language en-US "Gen1"
+#string STR_GEN2                                       #language en-US "Gen2"
+#string STR_SATA_TEST_MODE_HELP                        #language en-US "Test Mode Enable/Disable"
+
+#string STR_SECURE_BOOT_MODE_HELP                      #language en-US "Secure Boot Mode - Custom & Standard"
+#string STR_SECURE_BOOT                                #language en-US "SecureBoot"
+#string STR_CLEAR_ALL_KEYS                             #language en-US "Clear all Keys"
+#string STR_CLEAR_ALL_KEYS_HELP                        #language en-US "Clears PK, KEK, DB and DBx. Clearing Keys should be done in Custom Mode"
+#string STR_LOAD_DEFAULTS_KEYS                         #language en-US "Load UEFI Secure Boot Defaults and Exit"
+#string STR_LOAD_DEFAULTS_KEYS_HELP                    #language en-US "Loads PK,KEK, DBx and DB. Should be done in Custom Mode"
+#string STR_SECURE_BOOT_UPP_PROMPT                     #language en-US "User Physical Present"
+#string STR_SECURE_BOOT_UPP_HELP                       #language en-US "User is Physical Present User"
+#string STR_SECURE_BOOT_MODE_PROMPT                    #language en-US "UEFI Secure Boot Mode"
+#string STR_SECURE_BOOT_MODE_HELP                      #language en-US "Set UEFI Secure Boot Mode to STANDARD mode or CUSTOM mode, this change is effect after save. And after reset, the mode will return to STANDARD mode"
+#string STR_SB_STANDARD_MODE                           #language en-US "STANDARD"
+#string STR_SB_CUSTOM_MODE                             #language en-US "CUSTOM"
+#string STR_SECURE_BOOT_PRO_KEY_PROMPT                 #language en-US "UEFI Secure Boot Key"
+#string STR_SECURE_BOOT_PRO_KEY_HELP                   #language en-US "Set the UEFI Secure Boot Key to Development Key or Production Key, Change Key should be done in Custom Mode"
+#string STR_DEV_KEY                                    #language en-US "Development Key"
+#string STR_PRO_KEY                                    #language en-US "Production Key"
+
+// ACPI Memory Debug
+//
+#string STR_ACPIMEMDBG_STRING                          #language en-US "ACPI Memory Debug Switch"
+#string STR_ACPIMEMDBG_SWTICH                          #language en-US "ACPI Memory Debug"
+#string STR_ACPIMEMDBG_SWTICH_HELP                     #language en-US "Enable or Disable ACPI Memory Debug"
+
+#string STR_EXISUPPORT_PROMPT                          #language en-US "ExI"
+#string STR_EXISUPPORT_HELP                            #language en-US "Enabled/Disabled ExI"
+
+#string STR_PMWEIGHTS_PROMPT                           #language en-US "PM Weights"
+#string STR_PMWEIGHTS_HELP                             #language en-US "Enabled/Disabled PM Weights"
+
+#string STR_LPSSDEVHIDE_PROMPT                         #language en-US "Unsupported LPSS Device"
+#string STR_LPSSDEVHIDE_HELP                           #language en-US "Hide unsupported LPSS devices when in ACPI Mode"
+#string STR_HIDE                                       #language en-US "Hide"
+#string STR_UNHIDE                                     #language en-US "UnHide"
+
+#string STR_BATTERY_CONFIGURATION_TITLE                #language en-US "Battery Charging Configuration"
+#string STR_BATTERY_ACPI_OBJECT_PROMPT                 #language en-US "Battery solution"
+#string STR_BATTERY_ACPI_OBJECT_HELP                   #language en-US "If it does not match, battery will not work properly."
+#string STR_NON_ULPMC                                  #language en-US "Non ULPMC solution"
+#string STR_ULPMC                                      #language en-US "ULPMC solution"
+
+#string STR_CRITICAL_BATTERY_LIMIT_PROMPT              #language en-US "Critical Battery Limit"
+#string STR_CRITICAL_BATTERY_LIMIT_HELP                #language en-US "Limit in percentage below which the system is not allowed to boot.
+
+#string STR_CRITICAL_BATTERY_LIMIT_FEATURE_PROMPT    #language en-US "Critical Battery Limit Feature"
+#string STR_CRITICAL_BATTERY_LIMIT_FEATURE_HELP      #language en-US "Enable or Disable Critical Battery Limit Feature."
+
+#string STR_ULPMC_FW_LOCK_PROMPT                       #language en-US "ULPMC Firmware Lock"
+#string STR_ULPMC_FW_LOCK_HELP                         #language en-US "Enable or Disable Lock ULPMC Firmware Update."
+#string STR_WITT_CONFIGURATION_TITLE                   #language en-US "WITT Configuration"
+#string STR_WITT_PROMPT                                #language en-US "Enable WITT"
+#string STR_WITT_HELP                                  #language en-US "Enable or Disable WITT"
+#string STR_UTS_PROMPT                                 #language en-US "Enable UTS(Uart Test Suite)"
+#string STR_UTS_HELP                                   #language en-US "Enable or Disable Uart Test suite"
+#string STR_PCH_SPI_WP_PROMPT                          #language en-US "BIOS Read/Write Protection"
+#string STR_PCH_SPI_WP_HELP                            #language en-US "Enable or Disable BIOS SPI region read/write protect."
+#string STR_PCH_SPI_WP_DISABLE                         #language en-US "Disable"
+#string STR_PCH_SPI_WP_ENABLE                          #language en-US "Enable"
+#string STR_IGD_TURBO_PROMPT                           #language en-US  "IGD Turbo"
+#string STR_IGD_TURBO_HELP                             #language en-US  "Select the IGD Turbo feature, if Auto selected, IGD Turbo will only be enabled when SOC stepping is B0 or above."
+#string STR_EHCI_PLL_CFG_PROMPT                        #language en-US "EHCI PLL Configure"
+#string STR_EHCI_PLL_CFG_RTD3_DIS_HELP                 #language en-US "Enable/Disable EHCI PLL Configure For RTD3"
+
+// Codec ALC-262 disabled
+#string STR_CODEC262_DISABLED_PROMPT                   #language en-US  "Disable Codec ALC-262"
+#string STR_CODEC262_DISABLED_HELP                     #language en-US  "Enable/Disable Codec ALC-262."
+
+// SAR Sensor
+#string STR_SAR_SENSOR_PROMPT                          #language en-US "SAR Sensor"
+#string STR_SAR_SENSOR_HELP                            #language en-US "Enable or Disable SAR sensor"
+
+//Lakemore
+//
+#string STR_LM_INFORMATION_TITLE                      #language en-US "Lakemore Configuration:"
+#string STR_LM_MEMORY_HELP                            #language en-US "Specify the amount of main memory to be reserved for Lakemore.  The memory will be allocated right after MRC initialization and its location will be stored into the Lakemore STOREMEMBAR registers."
+#string STR_LM_MEMORY_PROMPT                          #language en-US "Memory Allocation Size"
+#string STR_LM_MEMORY_16MB                            #language en-US "16000 KiB"
+#string STR_LM_MEMORY_8MB                             #language en-US "8000 KiB"
+#string STR_LM_MEMORY_1MB                             #language en-US "1000 KiB"
+#string STR_LM_MEMORY_128KB                           #language en-US "128 KiB"
+#string STR_LM_MEMORY_0MB                             #language en-US "0 KiB"
+
+#string STR_PUINT_BIOS_CONFIG_DISPLAY                 #language en-US "PDM/Dfx Setting"
+#string STR_PUINT_BIOS_CONFIG_DISPLAY_HELP            #language en-US "PDM On: Enable PDM and keep Dfx powered.\n\nPerf Mode: Disable PDM and keep Dfx powered. Allows more VISA signals to be used for HW debug.\n\nPower Save: Disable PDM, turn off Dfx power and Visa clocks.\n\nNOTE: If previous setting was POWERSAVE, then cold boot will be needed for Dfx to come back up."
+#string STR_PUINT_BIOS_PDM                            #language en-US "PDM On"
+#string STR_PUINT_BIOS_PERFORMANCE                    #language en-US "Perf Mode"
+#string STR_PUINT_BIOS_POWERSAVE                      #language en-US "Power Save"
+#string STR_PUINT_BIOS_RESERVED                       #language en-US "Debug Reserved"
+
+#string STR_PDM_OUTPUT_CONFIG_SWTICH                  #language en-US "PDM Msg Output"
+#string STR_PDM_OUTPUT_CONFIG_SWTICH_HELP             #language en-US "Configure VISA and Lakemore for PDM with the given output.\n\nIf MainMem is selected then be sure to allocate memory for the output msgs in the above setting."
+#string STR_PDM_OUTPUT_MEM                            #language en-US "Main Memory"
+#string STR_PDM_OUTPUT_IO                             #language en-US "IO - TBD"
+
+#string STR_ENABLE_DBG2                               #language en-US "Enable DBG2 Table"
+#string STR_ENABLE_DBG2_HELP                          #language en-US "Enable/Disable DBG2 ACPI Table for Windbg"
+
+//eMMC
+//
+#string STR_SCC_EMMC_PROMPT                            #language en-US  "SCC eMMC 4.41 Support"
+#string STR_SCC_EMMC_HELP                              #language en-US  "Enable/Disable SCC eMMC 4.41 Support"
+
+#string STR_SCC_EMMC45_PROMPT                         #language en-US  "SCC eMMC45 Support"
+#string STR_SCC_EMMC45_HELP                           #language en-US  "Enable/Disable SCC eMMC 4.5 Support"
+#string STR_SCC_EMMC45_DDR50_PROMPT                   #language en-US  "DDR50 Capability Support"
+#string STR_SCC_EMMC45_DDR50_HELP                     #language en-US  "Enable/Disable SCC eMMC 4.5 DDR 50 support"
+#string STR_SCC_EMMC45_HS200_PROMPT                   #language en-US  "HS200 Capability Support"
+#string STR_SCC_EMMC45_HS200_HELP                     #language en-US  "Enable/Disable SCC eMMC 4.5 HS 200 support"
+#string STR_SCC_EMMC45_RE_TUNE_TIMER_VALUE            #language en-US  "Re Tune Timer Value"
+#string STR_SCC_EMMC45_RE_TUNE_TIMER_VALUE_HELP       #language en-US  "Set the re tune timer value"
+
+#string STR_SCC_EMMC45_SETTING_SUBTITLE               #language en-US  "SCC eMMC 4.5 Configuration"
+#string STR_EMMC45_TIMER_0                            #language en-US "0"
+#string STR_EMMC45_TIMER_1                            #language en-US "1"
+#string STR_EMMC45_TIMER_2                            #language en-US "2"
+#string STR_EMMC45_TIMER_3                            #language en-US "3"
+#string STR_EMMC45_TIMER_4                            #language en-US "4"
+#string STR_EMMC45_TIMER_5                            #language en-US "5"
+#string STR_EMMC45_TIMER_6                            #language en-US "6"
+#string STR_EMMC45_TIMER_7                            #language en-US "7"
+#string STR_EMMC45_TIMER_8                            #language en-US "8"
+#string STR_EMMC45_TIMER_9                            #language en-US "9"
+#string STR_EMMC45_TIMER_10                           #language en-US "10"
+#string STR_EMMC45_TIMER_11                           #language en-US "11"
+#string STR_EMMC45_TIMER_12                           #language en-US "12"
+#string STR_EMMC45_TIMER_13                           #language en-US "13"
+#string STR_EMMC45_TIMER_14                           #language en-US "14"
+#string STR_EMMC45_TIMER_15                           #language en-US "15"
+
+#string STR_EMMC_BOOT_PROMPT                          #language en-US "SCC eMMC Boot Controller"
+#string STR_EMMC_BOOT_HELP                            #language en-US "Disable/Select eMMC Boot mode; Auto Detect mode can switch the eMMC controller against the stepping"
+#string STR_AUTO_DETECT                               #language en-US "Auto Detect"
+#string STR_EMMC_BOOT_41                              #language en-US "eMMC 4.41"
+#string STR_EMMC_BOOT_45                              #language en-US "eMMC 4.5"
+
+// SD card DDR50 and SD25
+#string STR_SCC_SD_SDR25_PROMPT                       #language en-US "SDR25 Capability Support for SDCard"
+#string STR_SCC_SD_SDR25_HELP                         #language en-US "Disable/Enable SDR25 Capability in SD Card controller;
+#string STR_SCC_SD_DDR50_PROMPT                       #language en-US "DDR50 Capability Support for SDCard"
+#string STR_SCC_SD_DDR50_HELP                         #language en-US "Disable/Enable DDR50 Capability in SD Card controller;
+
+#string STR_SECURE_ERASE_PROMPT                       #language en-US "eMMC Secure Erase"
+#string STR_SECURE_ERASE_HELP                         #language en-US "Disable/Enable eMMC Secure Erase. When enabled, all the data on eMMC will be erased."
+
+
+//
+//Exit Option
+//
+#string STR_COMMIT_CHANGE_AND_EXIT_PROMPT             #language en-US "Commit Changes and Exit"
+#string STR_COMMIT_CHANGE_AND_EXIT_HELP               #language en-US "Save the setup changes and exit"
+
+#string STR_DISCARD_CHANGE_AND_EXIT_PROMPT            #language en-US "Discard Changes and Exit"
+#string STR_DISCARD_CHANGE_AND_EXIT_HELP              #language en-US "Discard the setup changes and exit"
+
+#string STR_LOAD_DEFAULT_AND_EXIT_PROMPT              #language en-US "Load Defaults and Exit"
+#string STR_LOAD_DEFAULT_AND_EXIT_HELP                #language en-US "Load the setup defaults and Exit"
+
+#string STR_PSS_ENABLE_PROMPT                         #language en-US "PSS Storage"
+#string STR_PSS_ENABLE_HELP                           #language en-US "Disable/Enable PSS-based secure boot"
+#string STR_PSS_CONFIGURATION_TITLE                   #language en-US "PSS Settings"
+
+//
+//Virtual Keyboard Option
+//
+#string STR_VIRTUAL_KB_TITLE                          #language en-US  "Virtual Keyboard Configuration"
+#string STR_VIRTUAL_KB_PROMPT                         #language en-US  "Virtual Keyboard Support"
+#string STR_VIRTUAL_KB_HELP                           #language en-US  "Enable/Disable Virtual Keyboard"
+
+//
+// MMIO Option
+//
+#string STR_MMIO_PROMPT                               #language en-US  "PCI MMIO Size"
+#string STR_MMIO_0_75G_STRING                         #language en-US "0.75GB"
+#string STR_MMIO_1G_STRING                            #language en-US "1GB"
+#string STR_MMIO_1_25G_STRING                         #language en-US "1.25GB"
+#string STR_MMIO_1_5G_STRING                         #language en-US "1.5GB"
+#string STR_MMIO_2G_STRING                            #language en-US "2GB"
+#string STR_MMIO_HELP                                 #language en-US  "Setup PCI MMIO Size 0.75G, 1G, 1.25G, 1.5G, 2GB Size"
+
+//
+// OS Selection Option
+//
+#string STR_OS_SELETION_PROMPT                        #language en-US "OS Selection"
+#string STR_OS_SELETION_HELP                          #language en-US "OS Selection"
+#string STR_WINDOWS                                   #language en-US "Windows 8.X"
+#string STR_ANDROID                                   #language en-US "Android"
+#string STR_WINDOWS7                                  #language en-US "Windows 7 UEFI 64bit"
+#string STR_LWINDOWS7                                 #language en-US "Win7 32/64 Legacy"
+#string STR_WEC7                                      #language en-US "WEC7"
+#string STR_LINUX                                     #language en-US "Linux"
+#string STR_BOOT_DISPLAY_MIPIDSI_PROMPT               #language en-US "MIPI DSI"
+#string STR_BOOT_DISPLAY_MIPIDSI_HELP                 #language en-US "Disable/enable MIPI DSI."
+
+
+//
+// EM-1 Selection Option
+//
+#string STR_EM1_IAAPPSRUN_PROMPT                       #language en-US "IA_APPS_RUN"
+#string STR_EM1_IAAPPSRUN_HELP                         #language en-US "Voltage in mV"
+#string STR_EM1_IAAPPSCAP_PROMPT                       #language en-US "IA_APPS_CAP"
+#string STR_EM1_IAAPPSCAP_HELP                         #language en-US "Percentage"
+#string STR_EM1_CAP_OR_VOLTAGE_PROMPT                  #language en-US "USE IA_APPS_RUN or CAP"
+#string STR_EM1_CAP_OR_VOLTAGE_HELP                    #language en-US "Use Voltage or Capacity to decide boot flow"
+#string STR_EM1_BOOT_ON_INVALID_BAT_PROMPT             #language en-US "Boot on invalid battery"
+#string STR_EM1_BOOT_ON_INVALID_BAT_HELP               #language en-US "Allow to boot from invalid battery"
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/Platform.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/Platform.c
new file mode 100644
index 0000000000..8b46fbdfd1
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/Platform.c
@@ -0,0 +1,997 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+    Platform.c
+
+Abstract:
+
+    This is a generic template for a child of the IchSmm driver.
+
+
+--*/
+
+#include "SmmPlatform.h"
+#include <Protocol/CpuIo2.h>
+
+
+//
+// Local variables
+//
+typedef struct {
+  UINT8     Device;
+  UINT8     Function;
+} EFI_PCI_BUS_MASTER;
+
+EFI_PCI_BUS_MASTER  mPciBm[] = {
+  { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1 },
+  { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2 },
+  { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3 },
+  { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4 },
+  { PCI_DEVICE_NUMBER_PCH_USB, PCI_FUNCTION_NUMBER_PCH_EHCI }
+};
+
+
+UINT16                                  mAcpiBaseAddr;
+SYSTEM_CONFIGURATION                    mSystemConfiguration;
+EFI_SMM_VARIABLE_PROTOCOL               *mSmmVariable;
+EFI_GLOBAL_NVS_AREA_PROTOCOL            *mGlobalNvsAreaPtr;
+
+UINT16									                mPM1_SaveState16;
+UINT32									                mGPE_SaveState32;
+
+BOOLEAN                                 mSetSmmVariableProtocolSmiAllowed = TRUE;
+
+
+//
+// Variables. Need to initialize this from Setup
+//
+BOOLEAN                                 mWakeOnLanS5Variable;
+BOOLEAN                                 mWakeOnRtcVariable;
+UINT8                                   mWakeupDay;
+UINT8                                   mWakeupHour;
+UINT8                                   mWakeupMinute;
+UINT8                                   mWakeupSecond;
+
+//
+// Use an enum. 0 is Stay Off, 1 is Last State, 2 is Stay On
+//
+UINT8                                   mAcLossVariable;
+
+
+static
+UINT8 mTco1Sources[] = {
+  IchnNmi
+};
+
+UINTN
+DevicePathSize (
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  );
+
+VOID
+S4S5ProgClock();
+
+EFI_STATUS
+InitRuntimeScriptTable (
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  );
+
+VOID
+S5SleepWakeOnRtcCallBack (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  EFI_SMM_SX_DISPATCH_CONTEXT   *DispatchContext
+  );
+
+
+VOID
+EnableS5WakeOnRtc();
+
+UINT8
+HexToBcd(
+  UINT8 HexValue
+  );
+
+UINT8
+BcdToHex(
+  IN UINT8 BcdValue
+  );
+
+
+VOID
+CpuSmmSxWorkAround(
+  );
+
+/**
+  Initializes the SMM Handler Driver
+
+  @param ImageHandle
+  @param SystemTable
+
+  @retval None
+
+**/
+EFI_STATUS
+EFIAPI
+InitializePlatformSmm (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS                                Status;
+  UINT8                                     Index;
+  EFI_HANDLE                                Handle;
+  EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT     PowerButtonContext;
+  EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL    *PowerButtonDispatch;
+  EFI_SMM_ICHN_DISPATCH_CONTEXT             IchnContext;
+  EFI_SMM_ICHN_DISPATCH_PROTOCOL            *IchnDispatch;
+  EFI_SMM_SX_DISPATCH_PROTOCOL              *SxDispatch;
+  EFI_SMM_SX_DISPATCH_CONTEXT               EntryDispatchContext;
+  EFI_SMM_SW_DISPATCH_PROTOCOL              *SwDispatch;
+  EFI_SMM_SW_DISPATCH_CONTEXT               SwContext;
+  UINTN                                     VarSize;
+  EFI_BOOT_MODE                             BootMode;
+
+  Handle = NULL;
+
+  //
+  //  Locate the Global NVS Protocol.
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiGlobalNvsAreaProtocolGuid,
+                  NULL,
+                  (void **)&mGlobalNvsAreaPtr
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+
+  //
+  // Get the ACPI Base Address
+  //
+
+  mAcpiBaseAddr = PchLpcPciCfg16( R_PCH_LPC_ACPI_BASE ) & B_PCH_LPC_ACPI_BASE_BAR;
+
+  VarSize = sizeof(SYSTEM_CONFIGURATION);
+  Status = SystemTable->RuntimeServices->GetVariable(
+                          L"Setup",
+                          &gEfiSetupVariableGuid,
+                          NULL,
+                          &VarSize,
+                          &mSystemConfiguration
+                          );
+  if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
+    //The setup variable is corrupted
+    VarSize = sizeof(SYSTEM_CONFIGURATION);
+    Status = SystemTable->RuntimeServices->GetVariable(
+              L"SetupRecovery",
+              &gEfiSetupVariableGuid,
+              NULL,
+              &VarSize,
+              &mSystemConfiguration
+              );
+    ASSERT_EFI_ERROR (Status);
+  }  
+  if (!EFI_ERROR(Status)) {
+    mAcLossVariable = mSystemConfiguration.StateAfterG3;
+
+    //
+    // If LAN is disabled, WOL function should be disabled too.
+    //
+    if (mSystemConfiguration.Lan == 0x01){
+      mWakeOnLanS5Variable = mSystemConfiguration.WakeOnLanS5;
+    } else {
+      mWakeOnLanS5Variable = FALSE;
+    }
+
+    mWakeOnRtcVariable = mSystemConfiguration.WakeOnRtcS5;
+  }
+
+  BootMode = GetBootModeHob ();
+
+  //
+  // Get the Power Button protocol
+  //
+  Status = gBS->LocateProtocol(
+                  &gEfiSmmPowerButtonDispatchProtocolGuid,
+                  NULL,
+                  (void **)&PowerButtonDispatch
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+  if (BootMode != BOOT_ON_FLASH_UPDATE) {
+    //
+    // Register for the power button event
+    //
+    PowerButtonContext.Phase = PowerButtonEntry;
+    Status = PowerButtonDispatch->Register(
+                                    PowerButtonDispatch,
+                                    PowerButtonCallback,
+                                    &PowerButtonContext,
+                                    &Handle
+                                    );
+    ASSERT_EFI_ERROR(Status);
+  }
+  //
+  // Get the Sx dispatch protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiSmmSxDispatchProtocolGuid,
+                  NULL,
+                                  (void **)&SxDispatch
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  // Register entry phase call back function
+  //
+  EntryDispatchContext.Type  = SxS3;
+  EntryDispatchContext.Phase = SxEntry;
+
+  Status = SxDispatch->Register (
+                         SxDispatch,
+                           (EFI_SMM_SX_DISPATCH)SxSleepEntryCallBack,
+                         &EntryDispatchContext,
+                         &Handle
+                         );
+
+
+  EntryDispatchContext.Type  = SxS4;
+
+  Status = SxDispatch->Register (
+                         SxDispatch,
+                         S4S5CallBack,
+                         &EntryDispatchContext,
+                         &Handle
+                         );
+  ASSERT_EFI_ERROR(Status);
+
+
+  EntryDispatchContext.Type  = SxS5;
+
+  Status = SxDispatch->Register (
+                         SxDispatch,
+                         S4S5CallBack,
+                         &EntryDispatchContext,
+                         &Handle
+                         );
+  ASSERT_EFI_ERROR(Status);
+
+  Status = SxDispatch->Register (
+                         SxDispatch,
+                         S5SleepAcLossCallBack,
+                         &EntryDispatchContext,
+                         &Handle
+                         );
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  //  Get the Sw dispatch protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiSmmSwDispatchProtocolGuid,
+                  NULL,
+                                  (void **)&SwDispatch
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  // Register ACPI enable handler
+  //
+  SwContext.SwSmiInputValue = ACPI_ENABLE;
+  Status = SwDispatch->Register (
+                         SwDispatch,
+                         EnableAcpiCallback,
+                         &SwContext,
+                         &Handle
+                         );
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  // Register ACPI disable handler
+  //
+  SwContext.SwSmiInputValue = ACPI_DISABLE;
+  Status = SwDispatch->Register (
+                         SwDispatch,
+                         DisableAcpiCallback,
+                         &SwContext,
+                         &Handle
+                         );
+  ASSERT_EFI_ERROR(Status);
+
+
+  //
+  // Register for SmmReadyToBootCallback
+  //
+  SwContext.SwSmiInputValue = SMI_SET_SMMVARIABLE_PROTOCOL;
+  Status = SwDispatch->Register(
+                         SwDispatch,
+                         SmmReadyToBootCallback,
+                         &SwContext,
+                         &Handle
+                         );
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  // Get the ICHn protocol
+  //
+  Status = gBS->LocateProtocol(
+                  &gEfiSmmIchnDispatchProtocolGuid,
+                  NULL,
+                  (void **)&IchnDispatch
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  // Register for the events that may happen that we do not care.
+  // This is true for SMI related to TCO since TCO is enabled by BIOS WP
+  //
+  for (Index = 0; Index < sizeof(mTco1Sources)/sizeof(UINT8); Index++) {
+    IchnContext.Type = mTco1Sources[Index];
+    Status = IchnDispatch->Register(
+                             IchnDispatch,
+                             (EFI_SMM_ICHN_DISPATCH)DummyTco1Callback,
+                             &IchnContext,
+                             &Handle
+                             );
+    ASSERT_EFI_ERROR( Status );
+  }
+
+  //
+  // Lock TCO_EN bit.
+  //
+  IoWrite16( mAcpiBaseAddr + R_PCH_TCO_CNT, IoRead16( mAcpiBaseAddr + R_PCH_TCO_CNT ) | B_PCH_TCO_CNT_LOCK );
+
+  //
+  // Set to power on from G3 dependent on WOL instead of AC Loss variable in order to support WOL from G3 feature.
+  //
+  //
+  // Set wake from G3 dependent on AC Loss variable and Wake On LAN variable.
+  // This is because no matter how, if WOL enabled or AC Loss variable not disabled, the board needs to wake from G3 to program the LAN WOL settings.
+  // This needs to be done after LAN enable/disable so that the PWR_FLR state clear not impacted the WOL from G3 feature.
+  //
+  if (mAcLossVariable != 0x00) {
+    SetAfterG3On (TRUE);
+  } else {
+    SetAfterG3On (FALSE);
+  }
+
+
+
+
+  return EFI_SUCCESS;
+}
+
+VOID
+EFIAPI
+SmmReadyToBootCallback (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  EFI_SMM_SW_DISPATCH_CONTEXT   *DispatchContext
+  )
+{
+  EFI_STATUS Status;
+
+  if (mSetSmmVariableProtocolSmiAllowed)
+  {
+  	//
+    // It is okay to use gBS->LocateProtocol here because
+    // we are still in trusted execution.
+    //
+  Status = gBS->LocateProtocol(
+                  &gEfiSmmVariableProtocolGuid,
+                  NULL,
+                  (void **)&mSmmVariable
+                  );
+
+    ASSERT_EFI_ERROR(Status);
+
+    //
+    // mSetSmmVariableProtocolSmiAllowed will prevent this function from
+    // being executed more than 1 time.
+    //
+    mSetSmmVariableProtocolSmiAllowed = FALSE;
+  }
+
+}
+
+/**
+
+  @param DispatchHandle   The handle of this callback, obtained when registering
+  @param DispatchContext  The predefined context which contained sleep type and phase
+
+
+  @retval EFI_SUCCESS     Operation successfully performed
+
+**/
+EFI_STATUS
+EFIAPI    
+SxSleepEntryCallBack (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  EFI_SMM_SX_DISPATCH_CONTEXT   *DispatchContext
+  )
+{
+  EFI_STATUS              Status;
+
+  Status = SaveRuntimeScriptTable ();
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  //
+  // Workaround for S3 wake hang if C State is enabled
+  //
+  CpuSmmSxWorkAround();
+
+  return EFI_SUCCESS;
+}
+
+VOID
+CpuSmmSxWorkAround(
+  )
+{
+  UINT64           MsrValue;
+
+  MsrValue = AsmReadMsr64 (0xE2);
+
+  if (MsrValue & BIT15) {
+    return;
+  }
+
+  if (MsrValue & BIT10) {
+    MsrValue &= ~BIT10;
+    AsmWriteMsr64 (0xE2, MsrValue);
+  }
+}
+
+VOID
+ClearP2PBusMaster(
+  )
+{
+  UINT8             Command;
+  UINT8             Index;
+
+  for (Index = 0; Index < sizeof(mPciBm)/sizeof(EFI_PCI_BUS_MASTER); Index++) {
+    Command = MmioRead8 (
+                MmPciAddress (0,
+                  DEFAULT_PCI_BUS_NUMBER_PCH,
+                  mPciBm[Index].Device,
+                  mPciBm[Index].Function,
+                  PCI_COMMAND_OFFSET
+                )
+              );
+    Command &= ~EFI_PCI_COMMAND_BUS_MASTER;
+    MmioWrite8 (
+      MmPciAddress (0,
+        DEFAULT_PCI_BUS_NUMBER_PCH,
+        mPciBm[Index].Device,
+        mPciBm[Index].Function,
+        PCI_COMMAND_OFFSET
+      ),
+      Command
+    );
+  }
+}
+
+/**
+
+  Set the AC Loss to turn on or off.
+
+**/
+VOID
+SetAfterG3On (
+  BOOLEAN Enable
+  )
+{
+  UINT8             PmCon1;
+
+  //
+  // ICH handling portion
+  //
+  PmCon1 = MmioRead8 ( PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1 );
+  PmCon1 &= ~B_PCH_PMC_GEN_PMCON_AFTERG3_EN;
+  if (Enable) {
+    PmCon1 |= B_PCH_PMC_GEN_PMCON_AFTERG3_EN;
+  }
+  MmioWrite8 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1, PmCon1);
+
+}
+
+/**
+  When a power button event happens, it shuts off the machine
+
+**/
+VOID
+EFIAPI
+PowerButtonCallback (
+  IN  EFI_HANDLE                              DispatchHandle,
+  IN  EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT   *DispatchContext
+  )
+{
+  //
+  // Check what the state to return to after AC Loss. If Last State, then
+  // set it to Off.
+  //
+  UINT16  data16;
+
+  if (mWakeOnRtcVariable) {
+    EnableS5WakeOnRtc();
+  }
+
+  if (mAcLossVariable == 1) {
+    SetAfterG3On (TRUE);
+  }
+
+  ClearP2PBusMaster();
+
+  //
+  // Program clock chip
+  //
+  S4S5ProgClock();
+
+
+  data16 = (UINT16)(IoRead16(mAcpiBaseAddr + R_PCH_ACPI_GPE0a_EN));
+  data16 &= B_PCH_ACPI_GPE0a_EN_PCI_EXP;
+
+
+  //
+  // Clear Sleep SMI Status
+  //
+  IoWrite16 (mAcpiBaseAddr + R_PCH_SMI_STS,
+                (UINT16)(IoRead16 (mAcpiBaseAddr + R_PCH_SMI_STS) | B_PCH_SMI_STS_ON_SLP_EN));
+  //
+  // Clear Sleep Type Enable
+  //
+  IoWrite16 (mAcpiBaseAddr + R_PCH_SMI_EN,
+                (UINT16)(IoRead16 (mAcpiBaseAddr + R_PCH_SMI_EN) & (~B_PCH_SMI_EN_ON_SLP_EN)));
+
+  //
+  // Clear Power Button Status
+  //
+  IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_STS, B_PCH_ACPI_PM1_STS_PWRBTN);
+
+  //
+  // Shut it off now!
+  //
+  IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT, V_PCH_ACPI_PM1_CNT_S5);
+  IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT, B_PCH_ACPI_PM1_CNT_SLP_EN | V_PCH_ACPI_PM1_CNT_S5);
+
+  //
+  // Should not return
+  //
+  CpuDeadLoop();
+}
+
+
+/**
+  @param DispatchHandle  - The handle of this callback, obtained when registering
+
+  @param DispatchContext - The predefined context which contained sleep type and phase
+
+**/
+VOID
+EFIAPI
+S5SleepAcLossCallBack (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  EFI_SMM_SX_DISPATCH_CONTEXT   *DispatchContext
+  )
+{
+  //
+  // Check what the state to return to after AC Loss. If Last State, then
+  // set it to Off.
+  //
+  if (mAcLossVariable == 1) {
+    SetAfterG3On (TRUE);
+  }
+}
+
+/**
+
+  @param DispatchHandle   The handle of this callback, obtained when registering
+  @param DispatchContext  The predefined context which contained sleep type and phase
+
+  @retval Clears the Save State bit in the clock.
+
+**/
+VOID
+EFIAPI
+S4S5CallBack (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  EFI_SMM_SX_DISPATCH_CONTEXT   *DispatchContext
+  )
+{
+
+  UINT32        Data32;
+
+  //
+  // Enable/Disable USB Charging
+  //
+  if (mSystemConfiguration.UsbCharging == 0x01) {
+    Data32 = IoRead32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL);
+    Data32 |= BIT8;
+    IoWrite32(GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL, Data32);
+  }
+
+}
+
+
+VOID
+S4S5ProgClock()
+{
+}
+
+/**
+  SMI handler to enable ACPI mode
+
+  Dispatched on reads from APM port with value 0xA0
+
+  Disables the SW SMI Timer.
+  ACPI events are disabled and ACPI event status is cleared.
+  SCI mode is then enabled.
+
+   Disable SW SMI Timer
+
+   Clear all ACPI event status and disable all ACPI events
+   Disable PM sources except power button
+   Clear status bits
+
+   Disable GPE0 sources
+   Clear status bits
+
+   Disable GPE1 sources
+   Clear status bits
+
+   Guarantee day-of-month alarm is invalid (ACPI 5.0 Section 4.8.2.4 "Real Time Clock Alarm")
+
+   Enable SCI
+
+  @param DispatchHandle  - EFI Handle
+  @param DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT
+
+  @retval Nothing
+
+**/
+VOID
+EFIAPI
+EnableAcpiCallback (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  EFI_SMM_SW_DISPATCH_CONTEXT   *DispatchContext
+  )
+{
+  UINT32 SmiEn;
+  UINT16 Pm1Cnt;
+  UINT16 wordValue;
+  UINT32 RegData32;
+
+  //
+  // Disable SW SMI Timer
+  //
+  SmiEn = IoRead32(mAcpiBaseAddr + R_PCH_SMI_EN);
+  SmiEn &= ~B_PCH_SMI_STS_SWSMI_TMR;
+  IoWrite32(mAcpiBaseAddr + R_PCH_SMI_EN, SmiEn);
+
+  wordValue = IoRead16(mAcpiBaseAddr + R_PCH_ACPI_PM1_STS);
+  if(wordValue & B_PCH_ACPI_PM1_STS_WAK) {
+	  IoWrite32((mAcpiBaseAddr + R_PCH_ACPI_GPE0a_EN), 0x0000);
+	  IoWrite32((mAcpiBaseAddr + R_PCH_ACPI_GPE0a_STS), 0xffffffff);
+  }
+  else {
+		mPM1_SaveState16 = IoRead16(mAcpiBaseAddr + R_PCH_ACPI_PM1_EN);
+
+		//
+		// Disable PM sources except power button
+		//
+    // power button is enabled only for PCAT. Disabled it on Tablet platform
+    //
+    IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_EN, B_PCH_ACPI_PM1_EN_PWRBTN);
+		IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_STS, 0xffff);
+
+		mGPE_SaveState32 = IoRead16(mAcpiBaseAddr + R_PCH_ACPI_GPE0a_EN);
+		IoWrite32(mAcpiBaseAddr + R_PCH_ACPI_GPE0a_EN, 0x0000);
+		IoWrite32(mAcpiBaseAddr + R_PCH_ACPI_GPE0a_STS, 0xffffffff);
+
+  }
+
+  //
+  // Guarantee day-of-month alarm is invalid (ACPI 5.0 Section 4.8.2.4 "Real Time Clock Alarm")
+  // Clear Status D reg VM bit, Date of month Alarm to make Data in CMOS RAM is no longer Valid
+  //
+  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_D);
+  IoWrite8 (PCAT_RTC_DATA_REGISTER, 0x0);
+
+
+	RegData32 = IoRead32(ACPI_BASE_ADDRESS + R_PCH_ALT_GP_SMI_EN);
+	RegData32 &= ~(BIT7);
+    IoWrite32((ACPI_BASE_ADDRESS + R_PCH_ALT_GP_SMI_EN), RegData32);
+
+
+  //
+  // Enable SCI
+  //
+  Pm1Cnt = IoRead16(mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT);
+  Pm1Cnt |= B_PCH_ACPI_PM1_CNT_SCI_EN;
+  IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT, Pm1Cnt);
+
+
+}
+
+/**
+  SMI handler to disable ACPI mode
+
+  Dispatched on reads from APM port with value 0xA1
+
+  ACPI events are disabled and ACPI event status is cleared.
+  SCI mode is then disabled.
+   Clear all ACPI event status and disable all ACPI events
+   Disable PM sources except power button
+   Clear status bits
+   Disable GPE0 sources
+   Clear status bits
+   Disable GPE1 sources
+   Clear status bits
+   Disable SCI
+
+  @param DispatchHandle  - EFI Handle
+  @param DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT
+
+  @retval Nothing
+
+**/
+VOID
+EFIAPI
+DisableAcpiCallback (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  EFI_SMM_SW_DISPATCH_CONTEXT   *DispatchContext
+  )
+{
+  UINT16 Pm1Cnt;
+
+  IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_STS, 0xffff);
+  IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_EN, mPM1_SaveState16);
+
+  IoWrite32(mAcpiBaseAddr + R_PCH_ACPI_GPE0a_STS, 0xffffffff);
+  IoWrite32(mAcpiBaseAddr + R_PCH_ACPI_GPE0a_EN, mGPE_SaveState32);
+
+  //
+  // Disable SCI
+  //
+  Pm1Cnt = IoRead16(mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT);
+  Pm1Cnt &= ~B_PCH_ACPI_PM1_CNT_SCI_EN;
+  IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT, Pm1Cnt);
+
+}
+
+/**
+  When an unknown event happen.
+
+ @retval None
+
+**/
+VOID
+DummyTco1Callback (
+  IN  EFI_HANDLE                              DispatchHandle,
+  IN  EFI_SMM_ICHN_DISPATCH_CONTEXT           *DispatchContext
+  )
+{
+}
+
+UINTN
+DevicePathSize (
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL     *Start;
+
+  if (DevicePath == NULL) {
+    return 0;
+  }
+
+  //
+  // Search for the end of the device path structure
+  //
+  Start = DevicePath;
+  while (!IsDevicePathEnd (DevicePath)) {
+    DevicePath = NextDevicePathNode (DevicePath);
+  }
+
+  //
+  // Compute the size and add back in the size of the end device path structure
+  //
+  return ((UINTN)DevicePath - (UINTN)Start) + sizeof(EFI_DEVICE_PATH_PROTOCOL);
+}
+
+/**
+
+  @param DispatchHandle   The handle of this callback, obtained when registering
+  @param DispatchContext  The predefined context which contained sleep type and phase
+
+**/
+VOID
+S5SleepWakeOnRtcCallBack (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  EFI_SMM_SX_DISPATCH_CONTEXT   *DispatchContext
+  )
+{
+  EnableS5WakeOnRtc();
+}
+
+/**
+
+ @retval 1. Check Alarm interrupt is not set.
+         2. Clear Alarm interrupt.
+         2. Set RTC wake up date and time.
+         2. Enable RTC wake up alarm.
+         3. Enable ICH PM1 EN Bit 10(RTC_EN)
+
+**/
+VOID
+EnableS5WakeOnRtc()
+{
+  UINT8             CmosData;
+  UINTN             i;
+  EFI_STATUS        Status;
+  UINTN             VarSize;
+
+  //
+  // make sure EFI_SMM_VARIABLE_PROTOCOL is available
+  //
+  if (!mSmmVariable) {
+    return;
+  }
+
+  VarSize = sizeof(SYSTEM_CONFIGURATION);
+
+  //
+  // read the variable into the buffer
+  //
+  Status = mSmmVariable->SmmGetVariable(
+                           L"Setup",
+                           &gEfiSetupVariableGuid,
+                           NULL,
+                           &VarSize,
+                           &mSystemConfiguration
+                           );
+  if (EFI_ERROR(Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
+    //The setup variable is corrupted
+    VarSize = sizeof(SYSTEM_CONFIGURATION);
+    Status = mSmmVariable->SmmGetVariable(
+              L"SetupRecovery",
+              &gEfiSetupVariableGuid,
+              NULL,
+              &VarSize,
+              &mSystemConfiguration
+              );
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  if (!mSystemConfiguration.WakeOnRtcS5) {
+    return;
+  }
+  mWakeupDay = HexToBcd((UINT8)mSystemConfiguration.RTCWakeupDate);
+  mWakeupHour = HexToBcd((UINT8)mSystemConfiguration.RTCWakeupTimeHour);
+  mWakeupMinute = HexToBcd((UINT8)mSystemConfiguration.RTCWakeupTimeMinute);
+  mWakeupSecond = HexToBcd((UINT8)mSystemConfiguration.RTCWakeupTimeSecond);
+
+  //
+  // Check RTC alarm interrupt is enabled.  If enabled, someone already
+  // grabbed RTC alarm.  Just return.
+  //
+  IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_B);
+  if(IoRead8(PCAT_RTC_DATA_REGISTER) & B_RTC_ALARM_INT_ENABLE){
+    return;
+  }
+
+  //
+  // Set Date
+  //
+  IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_D);
+  CmosData = IoRead8(PCAT_RTC_DATA_REGISTER);
+  CmosData &= ~(B_RTC_DATE_ALARM_MASK);
+  CmosData |= mWakeupDay ;
+  for(i = 0 ; i < 0xffff ; i++){
+    IoWrite8(PCAT_RTC_DATA_REGISTER, CmosData);
+    SmmStall(1);
+    if(((CmosData = IoRead8(PCAT_RTC_DATA_REGISTER)) & B_RTC_DATE_ALARM_MASK)
+         == mWakeupDay){
+      break;
+    }
+  }
+
+  //
+  // Set Second
+  //
+  IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_SECOND_ALARM);
+  for(i = 0 ; i < 0xffff ; i++){
+    IoWrite8(PCAT_RTC_DATA_REGISTER, mWakeupSecond);
+    SmmStall(1);
+    if(IoRead8(PCAT_RTC_DATA_REGISTER) == mWakeupSecond){
+      break;
+    }
+  }
+
+  //
+  // Set Minute
+  //
+  IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_MINUTE_ALARM);
+  for(i = 0 ; i < 0xffff ; i++){
+    IoWrite8(PCAT_RTC_DATA_REGISTER, mWakeupMinute);
+    SmmStall(1);
+    if(IoRead8(PCAT_RTC_DATA_REGISTER) == mWakeupMinute){
+      break;
+    }
+  }
+
+  //
+  // Set Hour
+  //
+  IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_HOUR_ALARM);
+  for(i = 0 ; i < 0xffff ; i++){
+    IoWrite8(PCAT_RTC_DATA_REGISTER, mWakeupHour);
+    SmmStall(1);
+    if(IoRead8(PCAT_RTC_DATA_REGISTER) == mWakeupHour){
+      break;
+    }
+  }
+
+  //
+  // Wait for UIP to arm RTC alarm
+  //
+  IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_A);
+  while (IoRead8(PCAT_RTC_DATA_REGISTER) & 0x80);
+
+  //
+  // Read RTC register 0C to clear pending RTC interrupts
+  //
+  IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_C);
+  IoRead8(PCAT_RTC_DATA_REGISTER);
+
+  //
+  // Enable RTC Alarm Interrupt
+  //
+  IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_B);
+  IoWrite8(PCAT_RTC_DATA_REGISTER, IoRead8(PCAT_RTC_DATA_REGISTER) | B_RTC_ALARM_INT_ENABLE);
+
+  //
+  // Clear ICH RTC Status
+  //
+  IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_STS, B_PCH_ACPI_PM1_STS_RTC);
+
+  //
+  // Enable ICH RTC event
+  //
+  IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_EN,
+              (UINT16)(IoRead16(mAcpiBaseAddr + R_PCH_ACPI_PM1_EN) | B_PCH_ACPI_PM1_EN_RTC));
+}
+
+UINT8
+HexToBcd(
+  IN UINT8 HexValue
+  )
+{
+  UINTN   HighByte;
+  UINTN   LowByte;
+
+  HighByte    = (UINTN)HexValue / 10;
+  LowByte     = (UINTN)HexValue % 10;
+
+  return ((UINT8)(LowByte + (HighByte << 4)));
+}
+
+UINT8
+BcdToHex(
+  IN UINT8 BcdValue
+  )
+{
+  UINTN   HighByte;
+  UINTN   LowByte;
+
+  HighByte    = (UINTN)((BcdValue >> 4) * 10);
+  LowByte     = (UINTN)(BcdValue & 0x0F);
+
+  return ((UINT8)(LowByte + HighByte));
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/PlatformSmm.inf b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/PlatformSmm.inf
new file mode 100644
index 0000000000..1b7b05d9b3
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/PlatformSmm.inf
@@ -0,0 +1,93 @@
+#
+#
+# Copyright (c)  1999  - 2018, Intel Corporation. All rights reserved
+#                                                                                  

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

+#
+#
+#  Module Name:
+#
+#   Platform.inf
+#
+#  Abstract:
+#
+#    Component description file for SMM Platform handler module
+#
+#--*/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformSmm
+  FILE_GUID                      = 99C20A37-042A-46e2-80F4-E4027FDBC86F
+  MODULE_TYPE                    = DXE_SMM_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = InitializePlatformSmm
+  PI_SPECIFICATION_VERSION       = 0x0001000A
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  S3Save.c
+  Platform.c
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  DebugLib
+  IoLib
+  BaseLib
+  BaseMemoryLib
+  DevicePathLib
+  HobLib
+  S3BootScriptLib
+  StallSmmLib
+  PchPlatformLib
+
+[Guids]
+  gEfiSetupVariableGuid
+  gDmiDataGuid
+  gEfiAcpiVariableCompatiblityGuid
+  gEfiPciLanInfoGuid
+  gEfiPciLanInfoGuid
+
+[FeaturePcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode
+
+[Protocols]
+  gEfiSmmBase2ProtocolGuid
+  gEfiSmmIchnDispatchProtocolGuid
+  gEfiGlobalNvsAreaProtocolGuid
+  gEfiSmmSwDispatchProtocolGuid
+  gEfiSmmPowerButtonDispatchProtocolGuid
+  gEfiSmmSxDispatchProtocolGuid
+  gEfiSmmVariableProtocolGuid
+  gEfiCpuIo2ProtocolGuid
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+
+[Pcd.common]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+[Depex]
+  gEfiSmmBase2ProtocolGuid                 AND
+  gEfiSmmAccess2ProtocolGuid               AND
+  gEfiSmmPowerButtonDispatchProtocolGuid  AND
+  gEfiSmmSxDispatchProtocolGuid           AND
+  gEfiSmmIchnDispatchProtocolGuid         AND
+  gEfiSmmSwDispatchProtocolGuid           AND
+  gEfiVariableArchProtocolGuid            AND
+  gEfiVariableWriteArchProtocolGuid       AND
+  gEfiGlobalNvsAreaProtocolGuid
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/S3Save.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/S3Save.c
new file mode 100644
index 0000000000..19089233b2
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/S3Save.c
@@ -0,0 +1,377 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+    IchS3Save.c
+
+Abstract:
+
+    SMM S3 handler Driver implementation file
+
+Revision History
+
+**/
+#include "SmmPlatform.h"
+
+extern  UINT16                          mAcpiBaseAddr;
+EFI_PHYSICAL_ADDRESS                    mRuntimeScriptTableBase;
+
+EFI_STATUS
+InitRuntimeScriptTable (
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS        Status;
+  UINT32            VarAttrib;
+  UINTN             VarSize;
+  ACPI_VARIABLE_SET_COMPATIBILITY *AcpiVariableBase;
+
+  //
+  // Allocate runtime ACPI script table space. We need it to save some
+  // settings done by CSM, which runs after normal script table closed
+  //
+  Status = gBS->AllocatePages (
+                  AllocateAnyPages,
+                  EfiACPIReclaimMemory,
+                  1,
+                  &mRuntimeScriptTableBase
+                  );
+  if (EFI_ERROR(Status)) {
+    return EFI_OUT_OF_RESOURCES ;
+  }
+
+  //
+  // Save runtime script table base into global ACPI variable
+  //
+  VarAttrib = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS
+              | EFI_VARIABLE_NON_VOLATILE;
+  VarSize   = sizeof (UINTN);
+  Status = SystemTable->RuntimeServices->GetVariable (
+                          ACPI_GLOBAL_VARIABLE,
+                          &gEfiAcpiVariableCompatiblityGuid,
+                          &VarAttrib,
+                          &VarSize,
+                          &AcpiVariableBase
+                          );
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  AcpiVariableBase->RuntimeScriptTableBase = mRuntimeScriptTableBase;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SaveRuntimeScriptTable (
+  VOID
+  )
+{
+  SMM_PCI_IO_ADDRESS    PciAddress;
+  UINT32                Data32;
+  UINT16                Data16;
+  UINT8                 Data8;
+  UINT8                 Mask;
+  UINTN                 Index;
+  UINTN                 Offset;
+  UINT8                 RegTable[] = {
+
+	  //
+    //Bus  ,   Dev,  Func,    DMI
+	  //
+      0x00 ,  0x00,  0x00,
+
+	  //
+    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+	  //
+      0x00 ,  0x08,  0x00,  0x00,  0x30,  0x00,  0x00,  0xa0,
+
+	  //
+    //Bus  ,   Dev,  Func,    LPC device
+	  //
+      0x00 ,  0x1F,  0x00,
+
+	  //
+    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+    //
+      0x00 ,  0x08,  0x00,  0x07,  0x00,  0x00,  0x90,  0x00,
+
+	  //
+    //Bus  ,   Dev,  Func,    PCIE device
+	 //
+      0x00 ,  0x1C,  0x00,
+
+	  //
+    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+    //
+      0xC0 ,  0x83,  0x30,  0x00,  0x00,  0x00,  0x00,  0x00,
+
+	  //
+    //Bus  ,   Dev,  Func,    PCIE device
+    //
+	  0x00 ,  0x1C,  0x00,
+
+	  //
+    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+    //
+      0x03 ,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+
+	  //
+    //Bus  ,   Dev,  Func,    SATA device
+	  //
+      0x00 ,  0x13,  0x00,
+
+	  //
+    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+    //
+      0xf4 ,  0xab,  0x27,  0x10,  0xf1,  0x1d,  0x00,  0x40,
+
+    //
+    //Bus  ,   Dev,  Func,    EHCI device
+    //
+     0x00 ,  0x1D,  0x00,
+
+    //
+    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+    //
+     0x10 ,  0x88,  0x00,  0x00,  0x00,  0x00,  0x00,  0x80,
+
+    //
+    //Bus  ,   Dev,  Func,    SMBUS device
+    //
+     0x00 ,  0x1f,  0x03,
+
+    //
+    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+    //
+      0x10 ,  0x89,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+
+    //
+    //Bus  ,   Dev,  Func,    SMBUS device
+    //
+      0x00 ,  0x1f,  0x03,
+
+    //
+    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+    //
+      0x02 ,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+
+    //
+    //Bus  ,   Dev,  Func,    VGA bus1
+    //
+      0x01 ,  0x00,  0x00,
+
+    //
+    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+    //
+      0x58 ,  0x81,  0x18,  0x01,  0xb0,  0x00,  0x00,  0x00,
+
+    //
+    //Bus  ,   Dev,  Func,    VGA bus1
+    //
+      0x01 ,  0x00,  0x00,
+
+    //
+    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+    //
+      0x02 ,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+
+    //
+    //Bus  ,   Dev,  Func,    VGA bus1 function 1
+    //
+      0x01 ,  0x00,  0x01,
+
+    //
+    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+    //
+      0x51 ,  0x80,  0x80,  0x01,  0x00,  0x00,  0x00,  0x00,
+
+    //
+    //Bus  ,   Dev,  Func,    VGA bus1 function 1
+    //
+      0x01 ,  0x00,  0x01,
+
+    //
+    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+    //
+      0x02 ,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+
+    //
+    //Bus  ,   Dev,  Func,    IGD bus0 function 0
+    //
+      0x00 ,  0x02,  0x00,
+
+    //
+    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+    //
+      0x42 ,  0x81,  0x00,  0x00,  0x00,  0x00,  0x20,  0x00,
+
+    //
+    //Bus  ,   Dev,  Func,    USB bus0 function 0
+    //
+      0x00 ,  0x16,  0x00,
+
+    //
+    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+    //
+      0x32 ,  0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+
+    //
+    //Bus  ,   Dev,  Func,    HD Audio bus0 function 0
+    //
+      0x00 ,  0x1B,  0x00,
+
+    //
+    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+    //
+      0x00 ,  0x00,  0x00,  0x00,  0x00,  0x00,  0x02,  0x00,
+
+    //
+    //0xFF indicates the end of the table
+    //
+      0xFF
+ };
+
+  //
+  // These registers have to set in byte order
+  //
+  UINT8                 ExtReg[] = { 0x9E, 0x9D };  // SMRAM settings
+
+
+
+  //
+  // Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by CSM
+  // and vital to S3 resume. That's why we put save code here
+  //
+  PciAddress.Bus      = 0;
+  PciAddress.Device   = 0;
+  PciAddress.Function = 0;
+  PciAddress.ExtendedRegister = 0;
+
+  for (Index = 0; Index < 2; Index++) {
+    //
+    // Read SRAM setting from Pci(0, 0, 0)
+    //
+    PciAddress.Register = ExtReg[Index];
+    Data8 = MmioRead8 (
+              MmPciAddress (0,
+                PciAddress.Bus,
+                PciAddress.Device,
+                PciAddress.Function,
+                PciAddress.Register
+              )
+            );
+
+    //
+    // Save latest settings to runtime script table
+    //
+    S3BootScriptSavePciCfgWrite(
+      S3BootScriptWidthUint8,
+      *(UINT64*)&PciAddress,
+      1,
+      &Data8
+      );
+  }
+
+
+  //
+  // Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by CSM
+  // and vital to S3 resume. That's why we put save code here
+  //
+  Index = 0;
+  while (RegTable[Index] != 0xFF) {
+
+    PciAddress.Bus      = RegTable[Index++];
+    PciAddress.Device   = RegTable[Index++];
+    PciAddress.Function = RegTable[Index++];
+    PciAddress.Register = 0;
+    PciAddress.ExtendedRegister = 0;
+
+    Data16 = MmioRead16 (
+              MmPciAddress (0,
+                PciAddress.Bus,
+                PciAddress.Device,
+                PciAddress.Function,
+                PciAddress.Register
+              )
+            );
+
+    if (Data16 == 0xFFFF) {
+      Index+=8;
+      continue;
+    }
+
+    for (Offset = 0, Mask = 0x01; Offset < 256; Offset+=4, Mask<<=1) {
+
+      if (Mask == 0x00) {
+        Mask = 0x01;
+      }
+
+      if (RegTable[Index + Offset/32] & Mask ) {
+
+        PciAddress.Register = (UINT8)Offset;
+        Data32 = MmioRead32 (MmPciAddress (0, PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register));
+
+        //
+        // Save latest settings to runtime script table
+        //
+        S3BootScriptSavePciCfgWrite (
+          S3BootScriptWidthUint32,
+          *(UINT64*)&PciAddress,
+          1,
+          &Data32
+        );
+      }
+    }
+
+    Index += 8;
+
+  }
+
+
+  //
+  // Save I/O ports to S3 script table
+  //
+
+  //
+  // Selftest KBC
+  //
+  Data8 = 0xAA;
+  S3BootScriptSaveIoWrite (
+    S3BootScriptWidthUint8,
+    0x64,
+    (UINTN)1,
+    &Data8
+    );
+
+  Data32 = IoRead32(mAcpiBaseAddr + R_PCH_SMI_EN);
+
+  S3BootScriptSaveIoWrite (
+      S3BootScriptWidthUint32,
+      (mAcpiBaseAddr + R_PCH_SMI_EN),
+      1,
+      &Data32
+      );
+
+  //
+  // Save B_ICH_TCO_CNT_LOCK so it will be done on S3 resume path.
+  //
+  Data16 = IoRead16(mAcpiBaseAddr + R_PCH_TCO_CNT);
+
+  S3BootScriptSaveIoWrite (
+      S3BootScriptWidthUint16,
+      mAcpiBaseAddr + R_PCH_TCO_CNT,
+      1,
+      &Data16
+      );
+
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmPlatform.h b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmPlatform.h
new file mode 100644
index 0000000000..8bf2ebafc1
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmPlatform.h
@@ -0,0 +1,240 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  SmmPlatform.h
+
+Abstract:
+
+  Header file for
+
+++*/
+
+#ifndef _PLATFORM_H
+#define _PLATFORM_H
+
+#include <PiSmm.h>
+
+
+
+#include <Protocol/SmmBase.h>
+#include <Protocol/FirmwareVolume.h>
+#include <Protocol/SmmPowerButtonDispatch.h>
+#include <Protocol/SmmSxDispatch.h>
+#include <Protocol/SmmSwDispatch.h>
+#include <Protocol/SmmSwDispatch2.h>
+#include <Protocol/SmmIchnDispatch.h>
+#include <Protocol/SmmAccess.h>
+#include <Protocol/SmmVariable.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/LoadedImage.h>
+#include "Protocol/GlobalNvsArea.h"
+#include <Guid/AcpiVariableCompatibility.h>
+#include <Guid/SetupVariable.h>
+#include <Guid/EfiVpdData.h>
+#include <Guid/PciLanInfo.h>
+#include <IndustryStandard/Pci22.h>
+
+#include "PchAccess.h"
+#include "PlatformBaseAddresses.h"
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PchPlatformLib.h>
+#include <Library/StallSmmLib.h>
+
+
+
+typedef struct {
+  UINT8     Register;
+  UINT8     Function;
+  UINT8     Device;
+  UINT8     Bus;
+  UINT32    ExtendedRegister;
+} SMM_PCI_IO_ADDRESS;
+
+typedef struct {
+  CHAR8     BoardAaNumber[7];
+  UINTN     BoardFabNumber;
+} BOARD_AA_NUMBER_DECODE;
+
+//
+// BugBug -- Need to get these two values from acpi.h, but right now, they are
+//           declared in platform-specific variants of this file, so no easy
+//           way to pick-up the include file and work across platforms.
+//           Need these definitions to go into a file like common\acpi.h.
+//
+#define ACPI_ENABLE                 0xA0
+#define ACPI_DISABLE                0xA1
+
+#define APM_12_FUNCS                  0x50
+#define SMI_SET_SMMVARIABLE_PROTOCOL  0x51  // this is used in Cpu\Pentium\Smm\Base\SmmBase.c
+
+#define SMI_CMD_GET_MSEG_STATUS     0x70
+#define SMI_CMD_UPDATE_MSEG_SIZE    0x71
+#define SMI_CMD_LOAD_STM            0x72
+#define SMI_CMD_UNLOAD_STM          0x73
+#define SMI_CMD_GET_SMRAM_RANGES    0x74
+
+
+#define PCAT_RTC_ADDRESS_REGISTER   0x74
+#define PCAT_RTC_DATA_REGISTER      0x75
+
+#define RTC_ADDRESS_SECOND          0x00
+#define RTC_ADDRESS_SECOND_ALARM    0x01
+#define RTC_ADDRESS_MINUTE          0x02
+#define RTC_ADDRESS_MINUTE_ALARM    0x03
+#define RTC_ADDRESS_HOUR            0x04
+#define RTC_ADDRESS_HOUR_ALARM      0x05
+
+#define RTC_ADDRESS_REGISTER_A      0x0A
+#define RTC_ADDRESS_REGISTER_B      0x0B
+#define RTC_ADDRESS_REGISTER_C      0x0C
+#define RTC_ADDRESS_REGISTER_D      0x0D
+
+#define B_RTC_ALARM_INT_ENABLE      0x20
+#define B_RTC_ALARM_INT_STATUS      0x20
+
+#define B_RTC_DATE_ALARM_MASK       0x3F
+
+#define PCAT_CMOS_2_ADDRESS_REGISTER  0x72
+#define PCAT_CMOS_2_DATA_REGISTER     0x73
+
+#define EC_C_PORT                     0x66
+#define SMC_SMI_DISABLE               0xBC
+#define SMC_ENABLE_ACPI_MODE          0xAA  // Enable ACPI mode
+
+#define IO_MISC 156
+
+
+#define MAXIMUM_NUMBER_OF_PSTATES           12
+#define  ICH_SMM_DATA_PORT                  0xB3
+
+#define EFI_IA32_PMG_CST_CONFIG               0x000000E2
+#define   B_EFI_CST_CONTROL_LOCK                BIT15
+#define   B_EFI_IO_MWAIT_REDIRECTION_ENABLE     BIT10
+#define EFI_IA32_PMG_IO_CAPTURE_ADDR          0x000000E4
+
+extern EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *mPciRootBridgeIo;
+
+//
+// Callback function prototypes
+//
+VOID
+EFIAPI
+PowerButtonCallback (
+  IN  EFI_HANDLE                              DispatchHandle,
+  IN  EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT   *DispatchContext
+  );
+
+VOID
+S5SleepWakeOnLanCallBack (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  EFI_SMM_SX_DISPATCH_CONTEXT   *DispatchContext
+  );
+
+VOID
+EFIAPI
+S5SleepAcLossCallBack (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  EFI_SMM_SX_DISPATCH_CONTEXT   *DispatchContext
+  );
+
+
+VOID
+EFIAPI    
+S4S5CallBack (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  EFI_SMM_SX_DISPATCH_CONTEXT   *DispatchContext
+  );
+
+VOID
+EFIAPI    
+EnableAcpiCallback (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  EFI_SMM_SW_DISPATCH_CONTEXT   *DispatchContext
+  );
+
+VOID
+EFIAPI
+DisableAcpiCallback (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  EFI_SMM_SW_DISPATCH_CONTEXT   *DispatchContext
+  );
+
+VOID
+EFIAPI
+SmmReadyToBootCallback (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  EFI_SMM_SW_DISPATCH_CONTEXT   *DispatchContext
+  );
+
+VOID
+DummyTco1Callback (
+  IN  EFI_HANDLE                              DispatchHandle,
+  IN  EFI_SMM_ICHN_DISPATCH_CONTEXT           *DispatchContext
+  );
+
+
+VOID
+PerrSerrCallback (
+  IN  EFI_HANDLE                              DispatchHandle,
+  IN  EFI_SMM_ICHN_DISPATCH_CONTEXT           *DispatchContext
+  );
+
+VOID
+RiCallback (
+  IN  EFI_HANDLE                              DispatchHandle,
+  IN  EFI_SMM_ICHN_DISPATCH_CONTEXT           *DispatchContext
+  );
+
+
+VOID
+SetAfterG3On (
+  BOOLEAN Enable
+  );
+
+VOID
+TurnOffVregUsb (
+  );
+
+VOID
+PStateSupportCallback (
+  IN  EFI_HANDLE                              DispatchHandle,
+  IN  EFI_SMM_SW_DISPATCH_CONTEXT             *DispatchContext
+  );
+
+VOID
+PStateTransitionCallback (
+  IN  EFI_HANDLE                              DispatchHandle,
+  IN  EFI_SMM_SW_DISPATCH_CONTEXT             *DispatchContext
+  );
+
+EFI_STATUS
+EFIAPI    
+SxSleepEntryCallBack (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  EFI_SMM_SX_DISPATCH_CONTEXT   *DispatchContext
+  );
+
+EFI_STATUS
+SaveRuntimeScriptTable (
+  VOID
+  );
+
+
+#endif
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.c b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.c
new file mode 100644
index 0000000000..26599620ba
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.c
@@ -0,0 +1,252 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+
+    SmmScriptSave.c
+
+Abstract:
+
+    ScriptTableSave module at run time
+
+--*/
+
+#include "SmmScriptSave.h"
+
+//
+// internal functions
+//
+
+EFI_STATUS
+BootScriptIoWrite  (
+  IN EFI_SMM_SCRIPT_TABLE     *ScriptTable,
+  IN VA_LIST                  Marker
+  );
+
+EFI_STATUS
+BootScriptPciCfgWrite  (
+  IN EFI_SMM_SCRIPT_TABLE     *ScriptTable,
+  IN VA_LIST                  Marker
+  );
+
+VOID
+SmmCopyMem (
+  IN  UINT8    *Destination,
+  IN  UINT8    *Source,
+  IN  UINTN    ByteCount
+  );
+
+//
+// Function implementations
+//
+EFI_STATUS
+SmmBootScriptWrite (
+  IN OUT EFI_SMM_SCRIPT_TABLE    *ScriptTable,
+  IN UINTN                       Type,
+  IN UINT16                      OpCode,
+  ...
+  )
+{
+  EFI_STATUS    Status;
+  VA_LIST       Marker;
+
+  if (ScriptTable == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Build script according to opcode
+  //
+  switch ( OpCode ) {
+
+    case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE:
+      VA_START(Marker, OpCode);
+      Status = BootScriptIoWrite (ScriptTable, Marker);
+      VA_END(Marker);
+      break;
+
+    case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE:
+      VA_START(Marker, OpCode);
+      Status = BootScriptPciCfgWrite(ScriptTable, Marker);
+      VA_END(Marker);
+      break;
+
+    default:
+      Status = EFI_SUCCESS;
+      break;
+  }
+
+  return Status;
+}
+
+
+EFI_STATUS
+SmmBootScriptCreateTable (
+  IN OUT EFI_SMM_SCRIPT_TABLE    *ScriptTable,
+  IN UINTN                       Type
+  )
+{
+  BOOT_SCRIPT_POINTERS          Script;
+  UINT8                         *Buffer;
+
+  if (ScriptTable == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Buffer = (UINT8*) ((UINTN)(*ScriptTable));
+
+  //
+  // Fill Table Header
+  //
+  Script.Raw = Buffer;
+  Script.TableInfo->OpCode      = EFI_BOOT_SCRIPT_TABLE_OPCODE;
+  Script.TableInfo->Length      = sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER);
+  Script.TableInfo->TableLength = sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER);
+
+  //
+  // Update current table pointer
+  //
+  *ScriptTable = *ScriptTable + sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER);
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+SmmBootScriptCloseTable (
+  IN EFI_SMM_SCRIPT_TABLE        ScriptTableBase,
+  IN EFI_SMM_SCRIPT_TABLE        ScriptTablePtr,
+  IN UINTN                       Type
+  )
+{
+  BOOT_SCRIPT_POINTERS    Script;
+
+  //
+  // Add final "termination" node to script table
+  //
+  Script.Raw               = (UINT8*) ((UINTN)ScriptTablePtr);
+  Script.Terminate->OpCode = EFI_BOOT_SCRIPT_TERMINATE_OPCODE;
+  Script.Terminate->Length = sizeof (EFI_BOOT_SCRIPT_TERMINATE);
+  ScriptTablePtr          += sizeof (EFI_BOOT_SCRIPT_TERMINATE);
+
+
+  //
+  // Update Table Header
+  //
+  Script.Raw                    = (UINT8*) ((UINTN)ScriptTableBase);
+  Script.TableInfo->OpCode      = EFI_BOOT_SCRIPT_TABLE_OPCODE;
+  Script.TableInfo->Length      = sizeof (EFI_BOOT_SCRIPT_TABLE_HEADER);
+  Script.TableInfo->TableLength = (UINT32)(ScriptTablePtr - ScriptTableBase);
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+BootScriptIoWrite  (
+  IN EFI_SMM_SCRIPT_TABLE     *ScriptTable,
+  IN VA_LIST                  Marker
+  )
+{
+  BOOT_SCRIPT_POINTERS    Script;
+  EFI_BOOT_SCRIPT_WIDTH   Width;
+  UINTN                   Address;
+  UINTN                   Count;
+  UINT8                   *Buffer;
+  UINTN                   NodeLength;
+  UINT8                   WidthInByte;
+
+  Width     = VA_ARG(Marker, EFI_BOOT_SCRIPT_WIDTH);
+  Address   = VA_ARG(Marker, UINTN);
+  Count     = VA_ARG(Marker, UINTN);
+  Buffer    = VA_ARG(Marker, UINT8*);
+
+  WidthInByte = (UINT8)(0x01 << (Width & 0x03));
+  Script.Raw  = (UINT8*) ((UINTN)(*ScriptTable));
+  NodeLength  = sizeof (EFI_BOOT_SCRIPT_IO_WRITE) + (WidthInByte * Count);
+
+  //
+  // Build script data
+  //
+  Script.IoWrite->OpCode  = EFI_BOOT_SCRIPT_IO_WRITE_OPCODE;
+  Script.IoWrite->Length  = (UINT8)(NodeLength);
+  Script.IoWrite->Width   = Width;
+  Script.IoWrite->Address = Address;
+  Script.IoWrite->Count   = (UINT32)Count;
+  SmmCopyMem (
+    (UINT8*)(Script.Raw + sizeof (EFI_BOOT_SCRIPT_IO_WRITE)),
+    Buffer,
+    WidthInByte * Count
+    );
+
+  //
+  // Update Script table pointer
+  //
+  *ScriptTable = *ScriptTable + NodeLength;
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+BootScriptPciCfgWrite  (
+  IN EFI_SMM_SCRIPT_TABLE        *ScriptTable,
+  IN VA_LIST                     Marker
+  )
+{
+  BOOT_SCRIPT_POINTERS    Script;
+  EFI_BOOT_SCRIPT_WIDTH   Width;
+  UINT64                  Address;
+  UINTN                   Count;
+  UINT8                   *Buffer;
+  UINTN                   NodeLength;
+  UINT8                   WidthInByte;
+
+  Width     = VA_ARG(Marker, EFI_BOOT_SCRIPT_WIDTH);
+  Address   = VA_ARG(Marker, UINT64);
+  Count     = VA_ARG(Marker, UINTN);
+  Buffer    = VA_ARG(Marker, UINT8*);
+
+  WidthInByte = (UINT8)(0x01 << (Width & 0x03));
+  Script.Raw  = (UINT8*) ((UINTN)(*ScriptTable));
+  NodeLength  = sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE) + (WidthInByte * Count);
+
+  //
+  // Build script data
+  //
+  Script.PciWrite->OpCode  = EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE;
+  Script.PciWrite->Length  = (UINT8)(NodeLength);
+  Script.PciWrite->Width   = Width;
+  Script.PciWrite->Address = Address;
+  Script.PciWrite->Count   = (UINT32)Count;
+  SmmCopyMem (
+    (UINT8*)(Script.Raw + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE)),
+    Buffer,
+    WidthInByte * Count
+    );
+
+  //
+  // Update Script table pointer
+  //
+  *ScriptTable = *ScriptTable + NodeLength;
+  return EFI_SUCCESS;
+}
+
+VOID
+SmmCopyMem (
+  IN  UINT8    *Destination,
+  IN  UINT8    *Source,
+  IN  UINTN    ByteCount
+  )
+{
+  UINTN   Index;
+
+  for (Index = 0; Index < ByteCount; Index++, Destination++, Source++) {
+    *Destination = *Source;
+  }
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.h b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.h
new file mode 100644
index 0000000000..d3eca8cdc0
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.h
@@ -0,0 +1,50 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+    SmmScriptSave.h
+
+Abstract:
+
+  This is an implementation of the BootScript at run time.
+
+--*/
+
+#ifndef _RUNTIME_SCRIPT_SAVE_H
+#define _RUNTIME_SCRIPT_SAVE_H
+
+#include "Efi.h"
+#include "EfiBootScript.h"
+
+
+typedef EFI_PHYSICAL_ADDRESS     EFI_SMM_SCRIPT_TABLE;
+
+EFI_STATUS
+SmmBootScriptCreateTable (
+  IN OUT EFI_SMM_SCRIPT_TABLE    *ScriptTable,
+  IN UINTN                       Type
+  );
+
+EFI_STATUS
+SmmBootScriptWrite (
+  IN OUT EFI_SMM_SCRIPT_TABLE    *ScriptTable,
+  IN UINTN                       Type,
+  IN UINT16                      OpCode,
+  ...
+  );
+
+EFI_STATUS
+SmmBootScriptCloseTable (
+  IN EFI_SMM_SCRIPT_TABLE        ScriptTableBase,
+  IN EFI_SMM_SCRIPT_TABLE        ScriptTablePtr,
+  IN UINTN                       Type
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c b/Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c
new file mode 100644
index 0000000000..3583e324e6
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c
@@ -0,0 +1,148 @@
+/** 
+  Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+Module Name:
+
+
+  PpmPolicy.c
+
+Abstract:
+
+  This file is a wrapper for Intel PPM Platform Policy driver.
+  Get Setup Value to initilize Intel PPM DXE Platform Policy.
+
+--*/
+#include "PpmPolicy.h"
+#include <Protocol/MpService.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/CpuIA32.h>
+
+#include <PchRegs.h>
+#include <Library/PchPlatformLib.h>
+
+#define EFI_CPUID_FAMILY                      0x0F00
+#define EFI_CPUID_MODEL                       0x00F0
+#define EFI_CPUID_STEPPING                    0x000F
+
+EFI_STATUS 
+EFIAPI
+PpmPolicyEntry(
+  IN EFI_HANDLE ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+  EFI_BOOT_SERVICES        *pBS;
+  EFI_MP_SERVICES_PROTOCOL *MpService;
+  EFI_CPUID_REGISTER        Cpuid01 = { 0, 0, 0, 0};
+  EFI_HANDLE                Handle;
+  EFI_STATUS                Status;
+  UINTN                     CpuCount;
+  UINTN                     CpuEnabledCount;
+  UINT8                     CPUMobileFeature;
+
+  PCH_STEPPING              Stepping;
+
+  pBS = SystemTable->BootServices;
+
+  //
+  // Set PPM policy structure to known value
+  //
+  pBS->SetMem (&mDxePlatformPpmPolicy, sizeof(PPM_PLATFORM_POLICY_PROTOCOL), 0);
+
+  //
+  // Find the MpService Protocol
+  //
+  Status = pBS->LocateProtocol (&gEfiMpServiceProtocolGuid,
+                                NULL,
+                                (void **)&MpService
+                               );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Get processor count from MP service.
+  //
+  Status = MpService->GetNumberOfProcessors (MpService, &CpuCount, &CpuEnabledCount);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Store the CPUID for use by SETUP items.
+  //
+  AsmCpuid (EFI_CPUID_VERSION_INFO, &Cpuid01.RegEax, &Cpuid01.RegEbx, &Cpuid01.RegEcx, &Cpuid01.RegEdx);
+
+  mDxePlatformPpmPolicy.Revision                       = PPM_PLATFORM_POLICY_PROTOCOL_REVISION_4;
+
+  //Read CPU Mobile feature from PLATFORM_ID_MSR MSR(0x17) NOTFB_I_AM_NOT_MOBILE_FUSE_CLIAMC00H Bit 28
+  //Bit Description: { Disables Mobile features 0 = I am NOT a mobile part 1 = I am a mobile part (default)"}
+  CPUMobileFeature = ((RShiftU64 (AsmReadMsr64(EFI_MSR_IA32_PLATFORM_ID), 28)) & 0x1);
+
+  if (!EFI_ERROR(Status)) {
+    if (CPUMobileFeature == 1){//CPU mobile feature
+      mDxePlatformPpmPolicy.FunctionEnables.EnableGv       = ICH_DEVICE_ENABLE;
+      mDxePlatformPpmPolicy.FunctionEnables.EnableCx       = ICH_DEVICE_ENABLE;
+      mDxePlatformPpmPolicy.FunctionEnables.EnableCxe      = ICH_DEVICE_DISABLE;
+      mDxePlatformPpmPolicy.FunctionEnables.EnableTm       = ICH_DEVICE_ENABLE;
+      //MaxC7
+      mDxePlatformPpmPolicy.FunctionEnables.EnableC7       = ICH_DEVICE_ENABLE;
+      mDxePlatformPpmPolicy.FunctionEnables.EnableC6       = ICH_DEVICE_ENABLE;
+      mDxePlatformPpmPolicy.FunctionEnables.EnableC4       = ICH_DEVICE_ENABLE;
+       
+      
+    }else{//CPU desktop feature
+       mDxePlatformPpmPolicy.FunctionEnables.EnableGv       = ICH_DEVICE_DISABLE;
+       mDxePlatformPpmPolicy.FunctionEnables.EnableCx       = ICH_DEVICE_DISABLE;
+       mDxePlatformPpmPolicy.FunctionEnables.EnableCxe      = ICH_DEVICE_DISABLE;
+       mDxePlatformPpmPolicy.FunctionEnables.EnableTm       = ICH_DEVICE_DISABLE;
+       mDxePlatformPpmPolicy.FunctionEnables.EnableC4       = ICH_DEVICE_DISABLE;
+       mDxePlatformPpmPolicy.FunctionEnables.EnableC6       = ICH_DEVICE_DISABLE;
+       mDxePlatformPpmPolicy.FunctionEnables.EnableC7       = ICH_DEVICE_DISABLE;
+    }
+
+
+    mDxePlatformPpmPolicy.FunctionEnables.EnableProcHot  = ICH_DEVICE_ENABLE;
+    mDxePlatformPpmPolicy.FunctionEnables.TStatesEnable  = ICH_DEVICE_ENABLE;
+
+    
+    Stepping = PchStepping();
+    if (Stepping < PchB3) {
+      // If SoC is B0~B2 Stepping, disable the Turbo
+      mDxePlatformPpmPolicy.FunctionEnables.EnableTurboMode= ICH_DEVICE_DISABLE;
+    } else {
+      mDxePlatformPpmPolicy.FunctionEnables.EnableTurboMode= ICH_DEVICE_ENABLE;
+    }
+    
+    mDxePlatformPpmPolicy.FunctionEnables.EnableTm      = ICH_DEVICE_ENABLE;
+
+    mDxePlatformPpmPolicy.FunctionEnables.EnableCMP      = ICH_DEVICE_ENABLE;
+
+  } else {
+    mDxePlatformPpmPolicy.FunctionEnables.EnableGv       = ICH_DEVICE_ENABLE;
+    mDxePlatformPpmPolicy.FunctionEnables.EnableCx       = ICH_DEVICE_ENABLE;
+    mDxePlatformPpmPolicy.FunctionEnables.EnableCxe      = ICH_DEVICE_ENABLE;
+    mDxePlatformPpmPolicy.FunctionEnables.EnableTm      = ICH_DEVICE_ENABLE;
+    mDxePlatformPpmPolicy.FunctionEnables.EnableProcHot  = ICH_DEVICE_ENABLE;
+    mDxePlatformPpmPolicy.FunctionEnables.EnableCMP       = ICH_DEVICE_DISABLE;
+    mDxePlatformPpmPolicy.FunctionEnables.TStatesEnable  = ICH_DEVICE_ENABLE;
+    mDxePlatformPpmPolicy.FunctionEnables.EnableTurboMode= ICH_DEVICE_ENABLE;
+    mDxePlatformPpmPolicy.FunctionEnables.EnableC4       = ICH_DEVICE_ENABLE;
+    mDxePlatformPpmPolicy.FunctionEnables.EnableC6       = ICH_DEVICE_ENABLE;
+  }
+
+
+
+  mDxePlatformPpmPolicy.S3RestoreMsrSwSmiNumber                       = S3_RESTORE_MSR_SW_SMI;
+
+  Handle = NULL;
+  Status = pBS->InstallMultipleProtocolInterfaces (
+                                                  &Handle,
+                                                  &gPpmPlatformPolicyProtocolGuid,
+                                                  &mDxePlatformPpmPolicy,
+                                                  NULL
+                                                  );
+
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h b/Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h
new file mode 100644
index 0000000000..346bb18724
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h
@@ -0,0 +1,36 @@
+/** 
+  Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+Module Name:
+
+  PpmPolicy.h
+
+Abstract:
+
+  Header file for the PpmPolicyInitDxe Driver.
+
+--*/
+#include <PiDxe.h>
+//
+// Driver Produced Protocol Prototypes
+//
+#include <Protocol/PpmPlatformPolicy.h>
+
+PPM_PLATFORM_POLICY_PROTOCOL    mDxePlatformPpmPolicy;
+
+// Function Definition
+#define  ICH_DEVICE_ENABLE       1
+#define  ICH_DEVICE_DISABLE      0
+
+#define POWER_STATE_SWITCH_SMI                       43
+#define ENABLE_C_STATE_IO_REDIRECTION_SMI            70
+#define DISABLE_C_STATE_IO_REDIRECTION_SMI           71
+#define ENABLE_SMI_C_STATE_COORDINATION_SMI          72
+#define DISABLE_SMI_C_STATE_COORDINATION_SMI         73
+#define ENABLE_P_STATE_HARDWARE_COORDINATION_SMI     74
+#define DISABLE_P_STATE_HARDWARE_COORDINATION_SMI    75
+#define S3_RESTORE_MSR_SW_SMI                        48
+#define ENABLE_C6_RESIDENCY_SMI                      76
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf b/Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf
new file mode 100644
index 0000000000..331076a2d4
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf
@@ -0,0 +1,49 @@
+#/*++
+#
+#  Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+#                                                                                  
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#                     
+#
+#  Module Name:
+#
+#   PpmPolicy.inf
+#
+#  Abstract:
+#
+#    Implement platform power management policy
+#
+#--*/
+
+[defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PpmPolicy
+  FILE_GUID                      = 2EE72E7C-FB9E-4318-B888-33A315C7A91D
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = PpmPolicyEntry
+
+[Sources]
+  PpmPolicy.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  Vlv2SocBinPkg/Vlv2SocBinPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+
+[LibraryClasses]
+  DebugLib
+  BaseLib
+  PchPlatformLib
+  UefiDriverEntryPoint
+
+[Protocols]
+  gEfiMpServiceProtocolGuid
+  gPpmPlatformPolicyProtocolGuid
+
+[Guids]
+  gEfiSetupVariableGuid
+
+[Depex]
+  gEfiMpServiceProtocolGuid
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Readme.md b/Platform/Intel/Vlv2TbltDevicePkg/Readme.md
new file mode 100644
index 0000000000..cbbb465b69
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Readme.md
@@ -0,0 +1,233 @@
+# **EDK II firmware for Minnowboard Max/Turbot which is based on Intel Valleyview2 SoC (Byatrail platform)**
+
+----------
+# Windows Pre-requisites
+
+* GIT client: Available from https://git-scm.com/downloads
+
+* Microsoft Visual Studio.
+  - Visual Studio 2015 recommended and is used in the examples below. Visual Studio 2013 is also supported.
+
+* WINDDK
+  - Download Microsoft Windows Driver Development Kit 3790.1830 and install it to C:\WINDDK\3790.1830.
+
+* Python 3
+  - https://www.python.org/downloads/
+
+* Install iASL
+   - Install the iasl compiler by downloading iasl-win-20160527.zip from the following
+   location: "https://acpica.org/downloads/" and place the unzipped
+   content ("iasl.exe") into the directory "C:\ASL" on your local hard drive
+   (create the folder "C:\ASL" if it does not exist).
+
+* Install the NASM* assembly language compiler
+   - Download NASM* 2.12.02 binaries from
+   http://www.nasm.us/pub/nasm/releasebuilds/2.12.02/win64/nasm-2.12.02-win64.zip and place the
+   unzipped content ("nasm.exe") into the directory "C:\NASM" on your local hard drive
+   (create the folder "C:\NASM" if it does not exist). Add the path "C:\NASM\" to system environment variable **NASM_PREFIX**.
+
+* Install Openssl
+   - Download a pre-compiled Openssl Windows binary from
+   https://wiki.openssl.org/index.php/Binaries. Search for a Windows binary in the list
+   of "Third Party OpenSSL Related Binary Distributions". Go to the third party site to
+   download the latest version. Download and extract to C:\Openssl, add the path of openssl.exe
+   ("C:\openssl") to system environment variable **OPENSSL_PATH**.
+
+# Download and Build MinnowMax using Windows/Visual Studio
+
+Run the script below from an empty directory.  The script clones the EDK II
+repository from GitHub and downloads and unzips the binary support files for the
+MinnowBoard MAX.  It then sets up the environment for EDK II builds and builds
+the MinnowBoard MAX firmware and generates UEFI Capsules that can be used to
+update the MinnowBoard MAX firmware and three sample devices.
+
+```
+git clone --recurse-submodules https://github.com/tianocore/edk2.git
+
+powershell "& {[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest -Uri "https://indy.fulgan.com/SSL/openssl-1.0.2r-x64_86-win64.zip -OutFile openssl-1.0.2r-x64_86-win64.zip"}"
+powershell Expand-Archive openssl-1.0.2r-x64_86-win64.zip
+
+powershell "& {[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest -Uri "https://firmware.intel.com/sites/default/files/MinnowBoardMax-Development190216.zip -OutFile MinnowBoardMax-Development190216.zip"}"
+powershell Expand-Archive MinnowBoardMax-Development190216.zip
+sleep 1
+rename MinnowBoardMax-Development190216 Vlv2Binaries
+cd Vlv2Binaries
+powershell Expand-Archive Vlv2SocBinPkg.zip .
+sleep 1
+cd ..
+
+powershell "& {[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest -Uri "https://www.nasm.us/pub/nasm/releasebuilds/2.13.03/win64/nasm-2.13.03-win64.zip -OutFile nasm-2.13.03-win64.zip"}"
+powershell Expand-Archive nasm-2.13.03-win64.zip .
+
+mkdir Conf
+
+set WORKSPACE=%CD%
+set EDK_TOOLS_PATH=%WORKSPACE%\edk2\BaseTools
+set EDK_TOOLS_BIN=%EDK_TOOLS_PATH%\BinWrappers\WindowsLike
+set PACKAGES_PATH=%WORKSPACE%\edk2;%WORKSPACE%\Vlv2Binaries
+path=%path%;%EDK_TOOLS_PATH%\Bin\Win32;%WORKSPACE%\openssl-1.0.2r-x64_86-win64
+set NASM_PREFIX=%WORKSPACE%\nasm-2.13.03\
+
+cd %WORKSPACE%\edk2
+
+call edkSetup.bat Rebuild
+
+cd Vlv2TbltDevicePkg
+
+Build_IFWI.bat /m /y MNW2 Debug
+```
+
+Once all the code and tools are downloaded and installed, only the following
+commands are required to setup the environment.  Run these from the same
+directory used to install the source and binaries.
+
+```
+set WORKSPACE=%CD%
+set EDK_TOOLS_PATH=%WORKSPACE%\edk2\BaseTools
+set EDK_TOOLS_BIN=%EDK_TOOLS_PATH%\BinWrappers\WindowsLike
+set PACKAGES_PATH=%WORKSPACE%\edk2;%WORKSPACE%\Vlv2Binaries
+path=%path%;%EDK_TOOLS_PATH%\Bin\Win32;%WORKSPACE%\openssl-1.0.2r-x64_86-win64
+set NASM_PREFIX=%WORKSPACE%\nasm-2.13.03\
+
+cd %WORKSPACE%\edk2
+
+call edkSetup.bat Rebuild
+```
+
+Once the environment is setup, the MinnowBoard MAX firmware and capsules can be
+rebuilt using the following commands.
+
+* Build Debug Image
+
+```
+cd Vlv2TbltDevicePkg
+Build_IFWI.bat /m /y MNW2 Debug
+```
+
+* Build Release Image
+
+```
+cd Vlv2TbltDevicePkg
+Build_IFWI.bat /m /y MNW2 Release
+```
+
+The generated firmware image is the newest `.bin` file in `edk2/Vlv2TbltDevicePkg/Stitch`.
+The file is in the form `MNW2MAX1.X64.0084.D01.<DATE>.bin`.
+
+The CapsuleApp and generated UEFI Capsules are in `Build/Vlv2TbltDevicePkg/Capsules`
+
+# Linux Pre-requisites
+
+* The tool GenBiosId has a dependency on libc.so.6.  Make sure it is installed.
+  Here are a few example installation commands:
+
+    sudo dnf install libc.so.6
+
+    apt-get install libc:i386
+
+# Download and Build MinnowMax using Linux/GCC
+
+Run the script below from an empty directory.  The script clones the EDK II
+repository from GitHub and downloads and unzips the binary support files for the
+MinnowBoard MAX.  It then sets up the environment for EDK II builds and builds
+the MinnowBoard MAX firmware and generates UEFI Capsules that can be used to
+update the MinnowBoard MAX firmware and three sample devices.
+
+```
+git clone --recurse-submodules https://github.com/tianocore/edk2.git
+
+mkdir Vlv2Binaries
+cd Vlv2Binaries
+wget https://firmware.intel.com/sites/default/files/MinnowBoardMax-Development190216.zip
+unzip MinnowBoardMax-Development190216.zip
+unzip Vlv2SocBinPkg.zip
+
+cd ..
+mkdir Conf
+
+export WORKSPACE=$PWD/edk2
+export PACKAGES_PATH=$PWD/Vlv2Binaries
+export EDK_TOOLS_PATH=$WORKSPACE/BaseTools
+
+cd edk2
+cd Vlv2TbltDevicePkg
+. Build_IFWI.sh MNW2 Debug
+```
+
+Once all the code is downloaded and installed, only the following commands are
+required to setup the environment.  Run these from the same directory used to
+install the source and binaries.
+
+```
+export WORKSPACE=$PWD/edk2
+export PACKAGES_PATH=$PWD/Vlv2Binaries
+export EDK_TOOLS_PATH=$WORKSPACE/BaseTools
+
+cd edk2
+cd Vlv2TbltDevicePkg
+```
+
+Once the environment is setup, the MinnowBoard MAX firmware and capsules can be
+rebuilt using the following commands.
+
+
+* Build Debug Image
+
+```
+cd Vlv2TbltDevicePkg
+./Build_IFWI.sh MNW2 Debug
+```
+
+* Build Release Image
+
+```
+cd Vlv2TbltDevicePkg
+./Build_IFWI.sh MNW2 Release
+```
+
+The generated firmware image is the `MNW2MAX_X64_D_0084_01_GCC.bin` file in
+`edk2\Vlv2TbltDevicePkg\Stitch`
+
+The CapsuleApp and generated UEFI Capsules are in `Build\Vlv2TbltDevicePkg\Capsules`
+
+# Use DediProg to update FLASH image on a MinnowBoard MAX Target
+
+# Update MinnowBoard MAX Firmware from UEFI Capsules
+
+* Copy the `Build/Vlv2TbltDevicePkg/Capsules` directory to a USB FLASH drive
+* Connect USB FLASH Drive to MinnowBoard MAX
+* Boot MinnowBoard MAX to the Boot Manager
+* Boot the `EFI Internal Shell` boot option
+* Mount the USB FLASH Drive (usually `FS1`)
+* Use `cd` command to go to `Capsules/TestCert` directory
+* Run the following command to apply all four capsules
+
+```
+CapsuleApp.efi Red.cap Green.cap Blue.cap MinnowMax.cap
+```
+
+* The MinnowBoard MAX should reboot and the four capsules are applied in the
+  order listed.  The progress bar matches the color name of the capsule.
+  MinnowMax.cap uses the color purple.  Once all capsules are processed, the
+  MinnowBoard MAX should reboot again using the new firmware images.
+
+# Generate and Test a UX BitMap Capsule
+
+* Use bitmap editor to generate a BMP file.  Recommend resolution of 600 wide
+  by 100 tell and either 24 or 32 bits per pixel.
+* Save BMP file to USB FLASH drive
+* Use CapsuleApp.efi to convert BMP file to a UX Capsule
+
+```
+CapsuleApp.efi -G MyImage.bmp -O MyImage.cap
+```
+
+* When updating firmware using capsules, add UX capsule to the list of capsules
+  passed into CapsuleApp.efi.
+
+```
+CapsuleApp.efi MyImage.cap Red.cap Green.cap Blue.cap MinnowMax.cap
+```
+
+* When the capsules are processed the UX bitmap image should be displayed at the
+  bottom of the screen.
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.c b/Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.c
new file mode 100644
index 0000000000..69c16c5a3f
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.c
@@ -0,0 +1,181 @@
+/** 
+  Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+Module Name:
+
+  SaveMemoryConfig.c
+
+Abstract:
+  This is the driver that locates the MemoryConfigurationData HOB, if it
+  exists, and saves the data to nvRAM.
+
+ 
+
+--*/
+
+#include "SaveMemoryConfig.h"
+
+CHAR16    EfiMemoryConfigVariable[] = L"MemoryConfig";
+
+
+EFI_STATUS
+EFIAPI
+SaveMemoryConfigEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+/*++
+
+  Routine Description:
+    This is the standard EFI driver point that detects whether there is a
+    MemoryConfigurationData HOB and, if so, saves its data to nvRAM.
+
+  Arguments:
+    ImageHandle   - Handle for the image of this driver
+    SystemTable   - Pointer to the EFI System Table
+
+  Returns:
+    EFI_SUCCESS   - if the data is successfully saved or there was no data
+    EFI_NOT_FOUND - if the HOB list could not be located.
+    EFI_UNLOAD_IMAGE - It is not success
+
+--*/
+{
+  EFI_STATUS                      Status=EFI_SUCCESS;
+  VOID                            *MemHobData;
+  VOID                            *VariableData;
+  UINTN                           BufferSize;
+  BOOLEAN                         MfgMode;
+  EFI_PLATFORM_SETUP_ID           *BootModeBuffer;
+  EFI_PLATFORM_INFO_HOB           *PlatformInfoHobPtr;
+  MEM_INFO_PROTOCOL               *MemInfoProtocol;
+  EFI_HANDLE                      Handle;
+  UINT8							              Channel, Slot;
+  VOID                            *GuidHob;
+
+  VariableData   = NULL;
+  MfgMode        = FALSE;
+  Handle         = NULL;
+  BootModeBuffer = NULL;
+  MemHobData     = NULL;
+  PlatformInfoHobPtr = NULL;
+  BufferSize     = 0;
+
+  //
+  // Get Platform Info HOB
+  //
+  GuidHob = GetFirstGuidHob (&gEfiPlatformInfoGuid);
+  if (GuidHob == NULL) {
+    Status = EFI_NOT_FOUND;
+  }
+  ASSERT_EFI_ERROR (Status);
+
+  PlatformInfoHobPtr = GET_GUID_HOB_DATA (GuidHob);
+
+  //
+  // Get the BootMode guid hob
+  //
+  GuidHob = GetFirstGuidHob (&gEfiPlatformBootModeGuid);
+  if (GuidHob == NULL) {
+    Status = EFI_NOT_FOUND;
+  }
+  ASSERT_EFI_ERROR (Status);
+
+  BootModeBuffer = GET_GUID_HOB_DATA (GuidHob);
+
+
+  //
+  // Check whether in Manufacturing Mode
+  //
+  if (BootModeBuffer) {
+    if ( !CompareMem (   //EfiCompareMem
+            &BootModeBuffer->SetupName,
+            MANUFACTURE_SETUP_NAME,
+            StrSize (MANUFACTURE_SETUP_NAME)  //EfiStrSize
+            ) ) {
+      MfgMode = TRUE;
+    }
+  }
+
+  if (MfgMode) {
+    //
+    // Don't save Memory Configuration in Manufacturing Mode. Clear memory configuration.
+    //
+    Status = gRT->SetVariable (
+              EfiMemoryConfigVariable,
+              &gEfiVlv2VariableGuid,
+              EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+              0,
+              NULL
+              );      
+  } else {
+
+    MemInfoProtocol = (MEM_INFO_PROTOCOL*)AllocateZeroPool(sizeof(MEM_INFO_PROTOCOL));
+    if (PlatformInfoHobPtr != NULL) {
+      MemInfoProtocol->MemInfoData.memSize  = 0;
+      for (Channel = 0; Channel < CH_NUM; Channel ++){
+        for (Slot = 0; Slot < DIMM_NUM; Slot ++){               
+          MemInfoProtocol->MemInfoData.dimmSize[Slot + (Channel * DIMM_NUM)] = PlatformInfoHobPtr->MemData.DimmSize[Slot + (Channel * DIMM_NUM)];
+        }
+      }
+  	  MemInfoProtocol->MemInfoData.memSize       = PlatformInfoHobPtr->MemData.MemSize;        
+  	  MemInfoProtocol->MemInfoData.EccSupport    = PlatformInfoHobPtr->MemData.EccSupport;
+      MemInfoProtocol->MemInfoData.ddrFreq       = PlatformInfoHobPtr->MemData.DdrFreq;
+      MemInfoProtocol->MemInfoData.ddrType       = PlatformInfoHobPtr->MemData.DdrType;
+      if (MemInfoProtocol->MemInfoData.memSize == 0){
+        //
+        // We hardcode if MRC didn't fill these info in
+        //
+        MemInfoProtocol->MemInfoData.memSize     = 0x800; //per 1MB 
+        MemInfoProtocol->MemInfoData.dimmSize[0] = 0x800;
+        MemInfoProtocol->MemInfoData.dimmSize[1] = 0;    
+        MemInfoProtocol->MemInfoData.EccSupport  = FALSE;
+        MemInfoProtocol->MemInfoData.ddrType     = 5; //DDRType_LPDDR3
+      }
+
+      Status = gBS->InstallMultipleProtocolInterfaces (
+             &Handle,
+             &gMemInfoProtocolGuid,
+             MemInfoProtocol,
+             NULL
+             );
+    }
+
+    Status = EFI_SUCCESS;
+    if (BOOT_WITH_MINIMAL_CONFIGURATION != GetBootModeHob()){
+      //
+      // Get the Memory Config guid hob
+      //
+      GuidHob = GetFirstGuidHob (&gEfiMemoryConfigDataGuid);
+      if (GuidHob == NULL) {
+        Status = EFI_NOT_FOUND;
+      }
+      ASSERT_EFI_ERROR (Status);
+      
+      MemHobData = GET_GUID_HOB_DATA (GuidHob);
+      BufferSize = GET_GUID_HOB_DATA_SIZE (GuidHob);
+
+      Status = gRT->GetVariable (
+                  EfiMemoryConfigVariable,
+                  &gEfiVlv2VariableGuid,
+                  NULL,
+                  &BufferSize,
+                  VariableData
+                  );
+      if (EFI_ERROR(Status) && (MemHobData != NULL)) {    
+        Status = gRT->SetVariable (
+                      EfiMemoryConfigVariable,
+                      &gEfiVlv2VariableGuid,
+                      (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS),
+                      BufferSize,
+                      MemHobData
+                      );
+      } 
+    }
+
+  } // if-else MfgMode
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.h b/Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.h
new file mode 100644
index 0000000000..59ad09747a
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.h
@@ -0,0 +1,66 @@
+/** 
+  Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+Module Name:
+
+  SaveMemoryConfig.h
+
+Abstract:
+
+  Header file for Save Previous Memory Configuration Driver.
+
+ 
+
+--*/
+
+
+#ifndef _SAVE_MEMORY_CONFIG_DRIVER_H
+#define _SAVE_MEMORY_CONFIG_DRIVER_H
+
+#include "Protocol/SetupMode.h"
+#include "Guid/PlatformInfo.h"
+#include "Library/HobLib.h"
+#include "Library/DebugLib.h"
+#include "Library/UefiBootServicesTableLib.h"
+#include "Library/BaseMemoryLib.h"
+#include "PlatformBootMode.h"
+#include "Library/BaseLib.h"
+#include "Library/UefiRuntimeServicesTableLib.h"
+#include "Guid/GlobalVariable.h"
+#include "Library/UefiLib.h"
+#include "Guid/HobList.h"
+#include "Guid/MemoryConfigData.h"
+#include "Protocol/MemInfo.h"
+#include "Library/MemoryAllocationLib.h"
+#include <Guid/Vlv2Variable.h>
+
+//
+// Prototypes
+//
+EFI_STATUS
+EFIAPI
+SaveMemoryConfigEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+/*++
+  
+  Routine Description:
+    This is the standard EFI driver point that detects whether there is a
+    MemoryConfigurationData HOB and, if so, saves its data to nvRAM.
+
+  Arguments:
+    ImageHandle   - Handle for the image of this driver
+    SystemTable   - Pointer to the EFI System Table
+
+  Returns:
+    EFI_SUCCESS   - if the data is successfully saved or there was no data
+    EFI_NOT_FOUND - if the HOB list could not be located.
+    EFI_UNLOAD_IMAGE - It is not success
+    
+--*/
+;
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.inf b/Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.inf
new file mode 100644
index 0000000000..c2d693859d
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.inf
@@ -0,0 +1,60 @@
+#/*++
+#
+#  Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+#                                                                                  
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#                     
+#
+#
+#
+#  Module Name:
+#
+#   SaveMemoryConfig.inf
+#
+#  Abstract:
+#
+#
+--*/
+
+[defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SaveMemoryConfig
+  FILE_GUID                      = E0ECBEC9-B193-4351-A488-36A655F22F9F
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = SaveMemoryConfigEntryPoint
+
+[sources.common]
+  SaveMemoryConfig.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  HobLib
+  DebugLib
+  UefiRuntimeServicesTableLib
+  UefiLib
+  BaseLib
+
+[Protocols]
+  gMemInfoProtocolGuid
+
+[Guids]
+  gEfiMemoryConfigDataGuid
+  gEfiPlatformInfoGuid
+  gEfiPlatformBootModeGuid
+  gEfiVlv2VariableGuid
+  #gEfiHobListGuid
+  #gEfiPlatformInfoGuid
+  #gEfiPlatformBootModeGuid
+  #gEfiGlobalVariableGuid
+  #gEfiMemoryConfigDataGuid
+
+[Depex]
+  gEfiVariableArchProtocolGuid AND
+  gEfiVariableWriteArchProtocolGuid
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/CommonHeader.h b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/CommonHeader.h
new file mode 100644
index 0000000000..e339b31065
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/CommonHeader.h
@@ -0,0 +1,39 @@
+/**@file
+  Common header file shared by all source files.
+
+  This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+  Copyright (c) 2006  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+**/
+
+#ifndef __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+
+
+#include <FrameworkDxe.h>
+#include <IndustryStandard/SmBios.h>
+#include <Protocol/Smbios.h>
+
+#include <Guid/DataHubRecords.h>
+#include <Guid/MdeModuleHii.h>
+
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiLib.h>
+#include <PchRegs.h>
+#include <Library/PchPlatformLib.h>
+#include <Library/PrintLib.h>
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufacturer.uni b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufacturer.uni
new file mode 100644
index 0000000000..32309bd97a
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufacturer.uni
@@ -0,0 +1,33 @@
+// *++
+//
+// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// 
+// Module Name:
+//
+//   MiscBaseBoardManufacturer.uni
+// 
+// Abstract:
+// 
+//   Base board information
+// 
+// Revision History:
+// 
+// --*/
+
+
+/=#
+
+#langdef en-US "English"
+
+#string STR_MISC_BASE_BOARD_MANUFACTURER     #language en-US  "Circuitco"
+#string STR_MISC_BASE_BOARD_PRODUCT_NAME     #language en-US  "TABLET"
+#string STR_MISC_BASE_BOARD_PRODUCT_NAME_FFD8     #language en-US  "BYT-T FFD8"
+#string STR_MISC_BASE_BOARD_PRODUCT_NAME1     #language en-US  "MinnowBoard MAX"
+#string STR_MISC_BASE_BOARD_VERSION          #language en-US  "REV A"
+#string STR_MISC_BASE_BOARD_VERSION_FFD8     #language en-US  "PR0"
+#string STR_MISC_BASE_BOARD_SERIAL_NUMBER    #language en-US  "To be filled by O.E.M"
+#string STR_MISC_BASE_BOARD_ASSET_TAG        #language en-US  "To be filled by O.E.M"
+#string STR_MISC_BASE_BOARD_CHASSIS_LOCATION #language en-US  "To be filled by O.E.M"
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufacturerData.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufacturerData.c
new file mode 100644
index 0000000000..068a32f390
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufacturerData.c
@@ -0,0 +1,58 @@
+/** @file
+
+Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscBaseBoardManufacturerData.c
+
+Abstract:
+
+  Static data of Base board manufacturer information.
+  Base board manufacturer information is Misc. subclass type 4 and SMBIOS type 2.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_BASE_BOARD_MANUFACTURER_DATA, MiscBaseBoardManufacturer)
+= {
+  STRING_TOKEN(STR_MISC_BASE_BOARD_MANUFACTURER),
+  STRING_TOKEN(STR_MISC_BASE_BOARD_PRODUCT_NAME),
+  STRING_TOKEN(STR_MISC_BASE_BOARD_VERSION),
+  STRING_TOKEN(STR_MISC_BASE_BOARD_SERIAL_NUMBER),
+  STRING_TOKEN(STR_MISC_BASE_BOARD_ASSET_TAG),
+  STRING_TOKEN(STR_MISC_BASE_BOARD_CHASSIS_LOCATION),
+  {                         // BaseBoardFeatureFlags
+    1,                      // Motherboard
+    0,                      // RequiresDaughterCard
+    0,                      // Removable
+    1,                      // Replaceable,
+    0,                      // HotSwappable
+    0,                      // Reserved
+  },
+  EfiBaseBoardTypeUnknown,  // BaseBoardType
+  {                         // BaseBoardChassisLink
+    EFI_MISC_SUBCLASS_GUID, // ProducerName
+    1,                      // Instance
+    1,                      // SubInstance
+  },
+  0,                        // BaseBoardNumberLinks
+  {                         // LinkN
+    EFI_MISC_SUBCLASS_GUID, // ProducerName
+    1,                      // Instance
+    1,                      // SubInstance
+  },
+};
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufacturerFunction.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufacturerFunction.c
new file mode 100644
index 0000000000..aa8c213d83
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufacturerFunction.c
@@ -0,0 +1,238 @@
+/*++
+
+Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+                                                                                   
+
+
+Module Name:
+
+  MiscBaseBoardManufacturerFunction.c
+
+Abstract:
+
+  BaseBoard manufacturer information boot time changes.
+  SMBIOS type 2.
+
+--*/
+
+
+#include "CommonHeader.h"
+#include "MiscSubclassDriver.h"
+#include <Library/NetLib.h>
+#include "Library/DebugLib.h"
+#include <Uefi/UefiBaseType.h>
+#include <Guid/PlatformInfo.h>
+
+
+extern EFI_PLATFORM_INFO_HOB *mPlatformInfo;
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscBaseBoardManufacturer (Type 2).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscBaseBoardManufacturer)
+{
+  CHAR8                           *OptionalStrStart;
+  UINTN                           ManuStrLen;
+  UINTN                           ProductStrLen;
+  UINTN                           VerStrLen;
+  UINTN                           AssertTagStrLen;
+  UINTN                           SerialNumStrLen;
+  UINTN                           ChassisStrLen;
+  EFI_STATUS                      Status;
+  EFI_STRING                      Manufacturer;
+  EFI_STRING                      Product;
+  EFI_STRING                      Version;
+  EFI_STRING                      SerialNumber;
+  EFI_STRING                      AssertTag;
+  EFI_STRING                      Chassis;
+  STRING_REF                      TokenToGet;
+  EFI_SMBIOS_HANDLE               SmbiosHandle;
+  SMBIOS_TABLE_TYPE2              *SmbiosRecord;
+  EFI_MISC_BASE_BOARD_MANUFACTURER   *ForType2InputData;
+
+  CHAR16                          *MacStr; 
+  EFI_HANDLE                      *Handles;
+  UINTN                           BufferSize;
+  CHAR16                          Buffer[40];
+
+  ForType2InputData = (EFI_MISC_BASE_BOARD_MANUFACTURER *)RecordData;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL || mPlatformInfo == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (BOARD_ID_MINNOW2_TURBOT == mPlatformInfo->BoardId) {
+    UnicodeSPrint (Buffer, sizeof (Buffer),L"ADI");
+    HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_BASE_BOARD_MANUFACTURER), Buffer, NULL);
+  }
+  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_MANUFACTURER);
+  Manufacturer = SmbiosMiscGetString (TokenToGet);
+  ManuStrLen = StrLen(Manufacturer);
+  if (ManuStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (BOARD_ID_MINNOW2_TURBOT == mPlatformInfo->BoardId) {
+    UnicodeSPrint (Buffer, sizeof (Buffer),L"MinnowBoard Turbot");
+    HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_BASE_BOARD_PRODUCT_NAME1), Buffer, NULL);
+  }
+  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_PRODUCT_NAME1);
+  Product = SmbiosMiscGetString (TokenToGet);
+  ProductStrLen = StrLen(Product);
+  if (ProductStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_VERSION);
+  Version = SmbiosMiscGetString (TokenToGet);
+  VerStrLen = StrLen(Version);
+  if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+              
+  //
+  //Get handle infomation
+  //
+  BufferSize = 0;
+  Handles = NULL;
+  Status = gBS->LocateHandle (
+                  ByProtocol, 
+                  &gEfiSimpleNetworkProtocolGuid,
+                  NULL,
+                  &BufferSize,
+                  Handles
+                  );
+
+  if (Status == EFI_BUFFER_TOO_SMALL) {
+  	Handles = AllocateZeroPool(BufferSize);
+  	if (Handles == NULL) {
+  		return (EFI_OUT_OF_RESOURCES);
+  	}
+  	Status = gBS->LocateHandle(
+  	                ByProtocol,
+  	                &gEfiSimpleNetworkProtocolGuid,
+  	                NULL,
+  	                &BufferSize,
+  	                Handles
+  	                );
+ }
+ 	                
+  //
+  //Get the MAC string
+  //
+  Status = NetLibGetMacString (
+             *Handles,
+             NULL,
+             &MacStr
+             );
+  if (EFI_ERROR (Status)) {	
+    return Status;
+  }
+  SerialNumber = MacStr;    
+  SerialNumStrLen = StrLen(SerialNumber);
+  if (SerialNumStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+  DEBUG ((EFI_D_ERROR, "MAC Address: %S\n", MacStr)); 
+  
+  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_ASSET_TAG);
+  AssertTag = SmbiosMiscGetString (TokenToGet);
+  AssertTagStrLen = StrLen(AssertTag);
+  if (AssertTagStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_CHASSIS_LOCATION);
+  Chassis = SmbiosMiscGetString (TokenToGet);
+  ChassisStrLen = StrLen(Chassis);
+  if (ChassisStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE2) + ManuStrLen + 1 + ProductStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1 + ChassisStrLen +1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE2) + ManuStrLen + 1 + ProductStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1 + ChassisStrLen +1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_BASEBOARD_INFORMATION;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE2);
+
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle = 0;
+
+  //
+  // Manu will be the 1st optional string following the formatted structure.
+  //
+  SmbiosRecord->Manufacturer = 1;
+
+  //
+  // ProductName will be the 2st optional string following the formatted structure.
+  //
+  SmbiosRecord->ProductName  = 2;
+
+  //
+  // Version will be the 3rd optional string following the formatted structure.
+  //
+  SmbiosRecord->Version = 3;
+
+  //
+  // SerialNumber will be the 4th optional string following the formatted structure.
+  //
+  SmbiosRecord->SerialNumber = 4;
+
+  //
+  // AssertTag will be the 5th optional string following the formatted structure.
+  //
+  SmbiosRecord->AssetTag = 5;
+
+  //
+  // LocationInChassis will be the 6th optional string following the formatted structure.
+  //
+  SmbiosRecord->LocationInChassis = 6;
+  SmbiosRecord->FeatureFlag = (*(BASE_BOARD_FEATURE_FLAGS*)&(ForType2InputData->BaseBoardFeatureFlags));
+  SmbiosRecord->ChassisHandle  = 0;
+  SmbiosRecord->BoardType      = (UINT8)ForType2InputData->BaseBoardType;
+  SmbiosRecord->NumberOfContainedObjectHandles = 0;
+
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+
+  //
+  // Since we fill NumberOfContainedObjectHandles = 0 for simple, just after this filed to fill string
+  //
+  UnicodeStrToAsciiStr(Manufacturer, OptionalStrStart);
+  UnicodeStrToAsciiStr(Product, OptionalStrStart + ManuStrLen + 1);
+  UnicodeStrToAsciiStr(Version, OptionalStrStart + ManuStrLen + 1 + ProductStrLen + 1);
+  UnicodeStrToAsciiStr(SerialNumber, OptionalStrStart + ManuStrLen + 1 + ProductStrLen + 1 + VerStrLen + 1);
+  UnicodeStrToAsciiStr(AssertTag, OptionalStrStart + ManuStrLen + 1 + ProductStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1);
+  UnicodeStrToAsciiStr(Chassis, OptionalStrStart + ManuStrLen + 1 + ProductStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1);
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+
+  FreePool(SmbiosRecord);
+  return Status;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendor.uni b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendor.uni
new file mode 100644
index 0000000000..80b099d210
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendor.uni
@@ -0,0 +1,26 @@
+// *++
+//
+// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// 
+// Module Name:
+//
+//   MiscBiosVendor.uni
+// 
+// Abstract:
+// 
+//   BIOS vendor information.
+// 
+// Revision History:
+// 
+// --*/
+
+
+/=#
+
+#langdef en-US "English"
+
+#string STR_MISC_BIOS_VENDOR           #language en-US  "Intel Corp."
+#string STR_MISC_BIOS_VERSION          #language en-US  "Valleyview A0 BIOS"
+#string STR_MISC_BIOS_RELEASE_DATE     #language en-US  "08/06/2012"
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorData.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorData.c
new file mode 100644
index 0000000000..91e8efc228
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorData.c
@@ -0,0 +1,101 @@
+/** @file
+
+Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscBiosVendorData.c
+
+Abstract:
+
+  Static data of BIOS vendor information.
+  BIOS vendor information is Misc. subclass type 2 and SMBIOS type 0.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_BIOS_VENDOR_DATA, MiscBiosVendor)
+= {
+  STRING_TOKEN(STR_MISC_BIOS_VENDOR),       // BiosVendor
+  STRING_TOKEN(STR_MISC_BIOS_VERSION),      // BiosVersion
+  STRING_TOKEN(STR_MISC_BIOS_RELEASE_DATE), // BiosReleaseDate
+  0xF000, // BiosStartingAddress
+  {       // BiosPhysicalDeviceSize
+    1,    // Value
+    21 ,          // Exponent
+  },
+  {       // BiosCharacteristics1
+    0,    // Reserved1                         :2
+    0,    // Unknown                           :1
+    0,    // BiosCharacteristicsNotSupported   :1
+    0,    // IsaIsSupported                    :1
+    0,    // McaIsSupported                    :1
+    0,    // EisaIsSupported                   :1
+    1,    // PciIsSupported                    :1
+    0,    // PcmciaIsSupported                 :1
+    0,    // PlugAndPlayIsSupported            :1
+    0,    // ApmIsSupported                    :1
+    1,    // BiosIsUpgradable                  :1
+    1,    // BiosShadowingAllowed              :1
+    0,    // VlVesaIsSupported                 :1
+    0,    // EscdSupportIsAvailable            :1
+    1,    // BootFromCdIsSupported             :1
+    1,    // SelectableBootIsSupported         :1
+    0,    // RomBiosIsSocketed                 :1
+    0,    // BootFromPcmciaIsSupported         :1
+    1,    // EDDSpecificationIsSupported       :1
+    0,    // JapaneseNecFloppyIsSupported      :1
+    0,    // JapaneseToshibaFloppyIsSupported  :1
+    0,    // Floppy525_360IsSupported          :1
+    0,    // Floppy525_12IsSupported           :1
+    0,    // Floppy35_720IsSupported           :1
+    0,    // Floppy35_288IsSupported           :1
+    0,    // PrintScreenIsSupported            :1
+    1,    // Keyboard8042IsSupported           :1
+    1,    // SerialIsSupported                 :1
+    1,    // PrinterIsSupported                :1
+    1,    // CgaMonoIsSupported                :1
+    0,    // NecPc98                           :1
+
+//
+//BIOS Characteristics Extension Byte 1
+//
+    1,    // AcpiIsSupported                   :1
+    1,    // UsbLegacyIsSupported              :1
+    0,    // AgpIsSupported                    :1
+    0,    // I20BootIsSupported                :1
+    0,    // Ls120BootIsSupported              :1
+    1,    // AtapiZipDriveBootIsSupported      :1
+    0,    // Boot1394IsSupported               :1
+    0,    // SmartBatteryIsSupported           :1
+
+//
+//BIOS Characteristics Extension Byte 2
+//
+    1,    // BiosBootSpecIsSupported           :1
+    1,    // FunctionKeyNetworkBootIsSupported :1
+    0x1     // Reserved                          :19  Bit 2 is SMBiosIsTargContDistEnabled
+  },
+  {       // BiosCharacteristics2
+    0x0001,// BiosReserved                      :16  Bit 0 is BIOS Splash Screen
+    0,    // SystemReserved                    :16
+    0     // Reserved                          :32
+  },
+  0xFF,   // BiosMajorRelease;
+  0xFF,   // BiosMinorRelease;
+  0xFF,   // BiosEmbeddedFirmwareMajorRelease;
+  0xFF,   // BiosEmbeddedFirmwareMinorRelease;
+};
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorFunction.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorFunction.c
new file mode 100644
index 0000000000..1817f456cb
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorFunction.c
@@ -0,0 +1,336 @@
+/*++
+
+Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscBiosVendorFunction.c
+
+Abstract:
+
+  BIOS vendor information boot time changes.
+  Misc. subclass type 2.
+  SMBIOS type 0.
+
+--*/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+#include <Library/BiosIdLib.h>
+#include <Library/SpiFlash.H>
+
+EFI_SPI_PROTOCOL  *mSpiProtocol = NULL;
+
+
+/**
+  This function read the data from Spi Rom.
+
+  @param BaseAddress                The starting address of the read.
+  @param Byte                       The pointer to the destination buffer.
+  @param Length                     The number of bytes.
+  @param SpiRegionType              Spi Region Type.
+
+  @retval Status
+
+**/
+EFI_STATUS
+FlashRead (
+  IN  UINTN             BaseAddress,
+  IN  UINT8             *Byte,
+  IN  UINTN             Length,
+  IN  SPI_REGION_TYPE   SpiRegionType
+  )
+{
+  EFI_STATUS            Status = EFI_SUCCESS;
+  UINT32                SectorSize;
+  UINT32                SpiAddress;
+  UINT8                 Buffer[SECTOR_SIZE_4KB];
+
+  SpiAddress = (UINT32)(UINTN)(BaseAddress);
+  SectorSize = SECTOR_SIZE_4KB;
+
+  Status = mSpiProtocol->Execute (
+                           mSpiProtocol,
+                           SPI_READ,
+                           SPI_WREN,
+                           TRUE,
+                           TRUE,
+                           FALSE,
+                           (UINT32) SpiAddress,
+                           SectorSize,
+                           Buffer,
+                           SpiRegionType
+                           );
+
+  if (EFI_ERROR (Status)) {
+#ifdef _SHOW_LOG_
+    Print(L"Read SPI ROM Failed [%08x]\n", SpiAddress);
+#endif
+    return Status;
+  }
+
+  CopyMem (Byte, (void *)Buffer, Length);
+
+  return Status;
+}
+
+/**
+  This function returns the value & exponent to Base2 for a given
+  Hex value. This is used to calculate the BiosPhysicalDeviceSize.
+
+  @param Value                      The hex value which is to be converted into value-exponent form
+  @param Exponent                   The exponent out of the conversion
+
+  @retval EFI_SUCCESS               All parameters were valid and *Value & *Exponent have been set.
+  @retval EFI_INVALID_PARAMETER     Invalid parameter was found.
+
+**/
+EFI_STATUS
+GetValueExponentBase2(
+  IN OUT UINTN        *Value,
+  OUT    UINTN        *Exponent
+  )
+{
+  if ((Value == NULL) || (Exponent == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  while ((*Value % 2) == 0) {
+    *Value=*Value/2;
+    (*Exponent)++;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a byte, with '64k'
+  as the unit.
+
+  @param  Base2Data              Pointer to Base2_Data
+
+  @retval EFI_SUCCESS            Transform successfully.
+  @retval EFI_INVALID_PARAMETER  Invalid parameter was found.
+
+**/
+UINT16
+Base2ToByteWith64KUnit (
+  IN      EFI_EXP_BASE2_DATA  *Base2Data
+  )
+{
+  UINT16              Value;
+  UINT16              Exponent;
+
+  Value     = Base2Data->Value;
+  Exponent  = Base2Data->Exponent;
+  Exponent -= 16;
+  Value <<= Exponent;
+
+  return Value;
+}
+
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscBiosVendor (Type 0).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscBiosVendor)
+{
+  CHAR8                 *OptionalStrStart;
+  UINTN                 VendorStrLen;
+  UINTN                 VerStrLen;
+  UINTN                 DateStrLen;
+  CHAR16                *Version;
+  CHAR16                *ReleaseDate;
+  CHAR16                BiosVersion[100];         //Assuming that strings are < 100 UCHAR
+  CHAR16                BiosReleaseDate[100];     //Assuming that strings are < 100 UCHAR
+  CHAR16                BiosReleaseTime[100];     //Assuming that strings are < 100 UCHAR
+  EFI_STATUS            Status;
+  EFI_STRING            Char16String;
+  STRING_REF            TokenToGet;
+  STRING_REF            TokenToUpdate;
+  SMBIOS_TABLE_TYPE0    *SmbiosRecord;
+  EFI_SMBIOS_HANDLE     SmbiosHandle;
+  EFI_MISC_BIOS_VENDOR *ForType0InputData;
+  BIOS_ID_IMAGE         BiosIdImage;
+  UINT16                UVerStr[32];
+  UINTN                 LoopIndex;
+  UINTN                 CopyIndex;
+  MANIFEST_OEM_DATA     *IFWIVerStruct;
+  UINT8                 *Data8 = NULL;
+  UINT16                SpaceVer[2]={0x0020,0x0000};
+  UINT16                BIOSVersionTemp[100];
+
+  ForType0InputData        = (EFI_MISC_BIOS_VENDOR *)RecordData;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  GetBiosId (&BiosIdImage);
+
+  //
+  //  Add VLV2 BIOS Version and Release data
+  //
+  SetMem(BiosVersion, sizeof(BiosVersion), 0);
+  SetMem(BiosReleaseDate, sizeof(BiosReleaseDate), 0);
+  SetMem(BiosReleaseTime, sizeof(BiosReleaseTime), 0);
+  Status = GetBiosVersionDateTime (BiosVersion, BiosReleaseDate, BiosReleaseTime);
+  DEBUG ((EFI_D_ERROR, "GetBiosVersionDateTime :%s %s %s \n", BiosVersion, BiosReleaseDate, BiosReleaseTime));
+  if (StrLen (BiosVersion) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_VERSION);
+    HiiSetString (mHiiHandle, TokenToUpdate, BiosVersion, NULL);
+  }
+
+  if (StrLen(BiosReleaseDate) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE);
+    HiiSetString (mHiiHandle, TokenToUpdate, BiosReleaseDate, NULL);
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VENDOR);
+  Char16String = SmbiosMiscGetString (TokenToGet);
+  VendorStrLen = StrLen(Char16String);
+  if (VendorStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VERSION);
+  Version = SmbiosMiscGetString (TokenToGet);
+
+  ZeroMem (UVerStr, 2*32);
+  ZeroMem (BIOSVersionTemp, 2*100);
+  StrCat (BIOSVersionTemp,Version);
+  Data8 = AllocatePool (SECTOR_SIZE_4KB);
+  ZeroMem (Data8, SECTOR_SIZE_4KB);
+
+  Status = gBS->LocateProtocol (
+                  &gEfiSpiProtocolGuid,
+                  NULL,
+                 (VOID **)&mSpiProtocol
+                 );
+  if (!EFI_ERROR(Status)) {
+    //
+    // Get data form SPI ROM.
+    //
+    Status = FlashRead (
+               MEM_IFWIVER_START,
+               Data8,
+               SECTOR_SIZE_4KB,
+               EnumSpiRegionAll
+               );
+    if (!EFI_ERROR(Status)) {
+      for(LoopIndex = 0; LoopIndex <= SECTOR_SIZE_4KB; LoopIndex++) {
+        IFWIVerStruct = (MANIFEST_OEM_DATA *)(Data8 + LoopIndex);
+        if(IFWIVerStruct->Signature == SIGNATURE_32('$','F','U','D')) {
+          DEBUG ((EFI_D_ERROR, "the IFWI Length is:%d\n", IFWIVerStruct->IFWIVersionLen));
+          if(IFWIVerStruct->IFWIVersionLen < 32) {
+            for(CopyIndex = 0; CopyIndex < IFWIVerStruct->IFWIVersionLen; CopyIndex++) {
+              UVerStr[CopyIndex] = (UINT16)IFWIVerStruct->IFWIVersion[CopyIndex];
+            }
+            UVerStr[CopyIndex] = 0x0000;
+            DEBUG ((EFI_D_ERROR, "The IFWI Version is :%s,the IFWI Length is:%d\n", UVerStr,IFWIVerStruct->IFWIVersionLen));
+            StrCat(BIOSVersionTemp,SpaceVer);
+            StrCat(BIOSVersionTemp,UVerStr);
+            DEBUG ((EFI_D_ERROR, "The BIOS and IFWI Version is :%s\n", BIOSVersionTemp));
+          }
+          break;
+        }
+      }
+    }
+  }
+  FreePool(Data8);
+
+  VerStrLen = StrLen(BIOSVersionTemp);
+  if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE);
+  ReleaseDate = SmbiosMiscGetString (TokenToGet);
+  DateStrLen = StrLen(ReleaseDate);
+  if (DateStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE0) + VendorStrLen + 1 + VerStrLen + 1 + DateStrLen + 1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE0) + VendorStrLen + 1 + VerStrLen + 1 + DateStrLen + 1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_BIOS_INFORMATION;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE0);
+
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle = 0;
+
+  //
+  // Vendor will be the 1st optional string following the formatted structure.
+  //
+  SmbiosRecord->Vendor = 1;
+
+  //
+  // Version will be the 2nd optional string following the formatted structure.
+  //
+  SmbiosRecord->BiosVersion = 2;
+  SmbiosRecord->BiosSegment = (UINT16)ForType0InputData->BiosStartingAddress;
+
+  //
+  // ReleaseDate will be the 3rd optional string following the formatted structure.
+  //
+  SmbiosRecord->BiosReleaseDate = 3;
+
+  //
+  // Tiger has no PCD value to indicate BIOS Size, just fill 0 for simply.
+  //
+  SmbiosRecord->BiosSize = 0;
+  SmbiosRecord->BiosCharacteristics = *(MISC_BIOS_CHARACTERISTICS*)(&ForType0InputData->BiosCharacteristics1);
+
+  //
+  // CharacterExtensionBytes also store in ForType0InputData->BiosCharacteristics1 later two bytes to save size.
+  //
+  SmbiosRecord->BIOSCharacteristicsExtensionBytes[0] = *((UINT8 *) &ForType0InputData->BiosCharacteristics1 + 4);
+  SmbiosRecord->BIOSCharacteristicsExtensionBytes[1] = *((UINT8 *) &ForType0InputData->BiosCharacteristics1 + 5);
+
+  SmbiosRecord->SystemBiosMajorRelease =  ForType0InputData->BiosMajorRelease;
+  SmbiosRecord->SystemBiosMinorRelease =  ForType0InputData->BiosMinorRelease;
+  SmbiosRecord->EmbeddedControllerFirmwareMajorRelease = ForType0InputData->BiosEmbeddedFirmwareMajorRelease;
+  SmbiosRecord->EmbeddedControllerFirmwareMinorRelease = ForType0InputData->BiosEmbeddedFirmwareMinorRelease;
+
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  UnicodeStrToAsciiStr(Char16String, OptionalStrStart);
+  UnicodeStrToAsciiStr(BIOSVersionTemp, OptionalStrStart + VendorStrLen + 1);
+  UnicodeStrToAsciiStr(ReleaseDate, OptionalStrStart + VendorStrLen + 1 + VerStrLen + 1);
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+
+  FreePool(SmbiosRecord);
+  return Status;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationData.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationData.c
new file mode 100644
index 0000000000..6b0f562261
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationData.c
@@ -0,0 +1,34 @@
+/** @file
+
+Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscBootInformationData.c
+
+Abstract:
+
+  Static data of Boot information.
+  Boot information is Misc. subclass type 26 and SMBIOS type 32.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_BOOT_INFORMATION_STATUS_DATA, BootInformationStatus)
+= {
+  EfiBootInformationStatusNoError,  // BootInformationStatus
+  0                                 // BootInformationData
+};
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationFunction.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationFunction.c
new file mode 100644
index 0000000000..0d4d50c663
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationFunction.c
@@ -0,0 +1,82 @@
+/*++
+
+Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscBootInformationFunction.c
+
+Abstract:
+
+  boot information boot time changes.
+  SMBIOS type 32.
+
+--*/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscBootInformation (Type 32).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+
+MISC_SMBIOS_TABLE_FUNCTION(BootInformationStatus)
+{
+  EFI_STATUS                         Status;
+  EFI_SMBIOS_HANDLE                  SmbiosHandle;
+  SMBIOS_TABLE_TYPE32                *SmbiosRecord;
+  EFI_MISC_BOOT_INFORMATION_STATUS*  ForType32InputData;
+
+  ForType32InputData = (EFI_MISC_BOOT_INFORMATION_STATUS *)RecordData;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE32) + 1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE32) + 1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE32);
+
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle = 0;
+  SmbiosRecord->BootStatus = (UINT8)ForType32InputData->BootInformationStatus;
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+  FreePool(SmbiosRecord);
+  return Status;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturer.uni b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturer.uni
new file mode 100644
index 0000000000..1c8dd35b37
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturer.uni
@@ -0,0 +1,28 @@
+// *++
+//
+// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// 
+// Module Name:
+//
+//   MiscChassisManufacturer.uni
+// 
+// Abstract:
+// 
+//   Chassis information
+// 
+// Revision History:
+// 
+// --*/
+
+
+/=#
+
+#langdef en-US "English"
+
+#string STR_MISC_CHASSIS_MANUFACTURER  #language en-US  "Circuitco"
+#string STR_MISC_CHASSIS_VERSION       #language en-US  " "
+#string STR_MISC_CHASSIS_SERIAL_NUMBER #language en-US  " "
+#string STR_MISC_CHASSIS_ASSET_TAG     #language en-US  " "
+#string STR_MISC_CHASSIS_SKU_NUMBER    #language en-US  " "
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturerData.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturerData.c
new file mode 100644
index 0000000000..ee11c9eac4
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturerData.c
@@ -0,0 +1,57 @@
+/** @file
+
+Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscChassisManufacturerData.c
+
+Abstract:
+
+  Static data is Chassis Manufacturer information.
+  Chassis Manufacturer information is Misc. subclass type 5 and SMBIOS type 3.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+//
+// Static (possibly build generated) Chassis Manufacturer data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_CHASSIS_MANUFACTURER_DATA, MiscChassisManufacturer)
+= {
+  STRING_TOKEN(STR_MISC_CHASSIS_MANUFACTURER),  // ChassisManufactrurer
+  STRING_TOKEN(STR_MISC_CHASSIS_VERSION),       // ChassisVersion
+  STRING_TOKEN(STR_MISC_CHASSIS_SERIAL_NUMBER), // ChassisSerialNumber
+  STRING_TOKEN(STR_MISC_CHASSIS_ASSET_TAG),     // ChassisAssetTag
+  {                               // ChassisTypeStatus
+    EfiMiscChassisTypeUnknown,    // ChassisType
+    0,                            // ChassisLockPresent
+    0                             // Reserved
+  },
+  EfiChassisStateSafe,            // ChassisBootupState
+  EfiChassisStateSafe,            // ChassisPowerSupplyState
+  EfiChassisStateOther,           // ChassisThermalState
+  EfiChassisSecurityStatusOther,  // ChassisSecurityState
+  0,                              // ChassisOemDefined
+  0,                              // ChassisHeight
+  0,                              // ChassisNumberPowerCords
+  0,                              // ChassisElementCount
+  0,                              // ChassisElementRecordLength
+  {                               // ChassisElements
+    {0, 0, 0},                    // ChassisElementType
+    0,                            // ChassisElementStructure
+    EfiBaseBoardTypeUnknown,      // ChassisBaseBoard
+    0,                            // ChassisElementMinimum
+    0                             // ChassisElementMaximum
+  },
+};
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturerFunction.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturerFunction.c
new file mode 100644
index 0000000000..c42ba3d0d1
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturerFunction.c
@@ -0,0 +1,158 @@
+/*++
+
+Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscChassisManufacturerFunction.c
+
+Abstract:
+
+  Chassis manufacturer information boot time changes.
+  SMBIOS type 3.
+
+--*/
+
+
+#include "CommonHeader.h"
+#include "MiscSubclassDriver.h"
+#include <Guid/PlatformInfo.h>
+
+
+extern EFI_PLATFORM_INFO_HOB *mPlatformInfo;
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscChassisManufacturer (Type 3).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscChassisManufacturer)
+{
+  CHAR8                           *OptionalStrStart;
+  UINTN                           ManuStrLen;
+  UINTN                           VerStrLen;
+  UINTN                           AssertTagStrLen;
+  UINTN                           SerialNumStrLen;
+  EFI_STATUS                      Status;
+  EFI_STRING                      Manufacturer;
+  EFI_STRING                      Version;
+  EFI_STRING                      SerialNumber;
+  EFI_STRING                      AssertTag;
+  STRING_REF                      TokenToGet;
+  EFI_SMBIOS_HANDLE               SmbiosHandle;
+  SMBIOS_TABLE_TYPE3              *SmbiosRecord;
+  EFI_MISC_CHASSIS_MANUFACTURER   *ForType3InputData;
+  CHAR16                          Buffer[40];
+
+  ForType3InputData = (EFI_MISC_CHASSIS_MANUFACTURER *)RecordData;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL || mPlatformInfo == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (BOARD_ID_MINNOW2_TURBOT == mPlatformInfo->BoardId) {
+    UnicodeSPrint (Buffer, sizeof (Buffer),L"ADI");
+    HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_CHASSIS_MANUFACTURER), Buffer, NULL);
+  }  
+  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_MANUFACTURER);
+  Manufacturer = SmbiosMiscGetString (TokenToGet);
+  ManuStrLen = StrLen(Manufacturer);
+  if (ManuStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_VERSION);
+  Version = SmbiosMiscGetString (TokenToGet);
+  VerStrLen = StrLen(Version);
+  if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_SERIAL_NUMBER);
+  SerialNumber = SmbiosMiscGetString (TokenToGet);
+  SerialNumStrLen = StrLen(SerialNumber);
+  if (SerialNumStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_ASSET_TAG);
+  AssertTag = SmbiosMiscGetString (TokenToGet);
+  AssertTagStrLen = StrLen(AssertTag);
+  if (AssertTagStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE3) + ManuStrLen + 1  + VerStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE3) + ManuStrLen + 1  + VerStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_ENCLOSURE;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE3);
+
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle = 0;
+
+  //
+  // Manu will be the 1st optional string following the formatted structure.
+  //
+  SmbiosRecord->Manufacturer = 1;
+  SmbiosRecord->Type = (UINT8)ForType3InputData->ChassisType.ChassisType;
+
+  //
+  // Version will be the 2nd optional string following the formatted structure.
+  //
+  SmbiosRecord->Version = 2;
+
+  //
+  // SerialNumber will be the 3rd optional string following the formatted structure.
+  //
+  SmbiosRecord->SerialNumber = 3;
+
+  //
+  // AssertTag will be the 4th optional string following the formatted structure.
+  //
+  SmbiosRecord->AssetTag = 4;
+  SmbiosRecord->BootupState = (UINT8)ForType3InputData->ChassisBootupState;
+  SmbiosRecord->PowerSupplyState = (UINT8)ForType3InputData->ChassisPowerSupplyState;
+  SmbiosRecord->ThermalState = (UINT8)ForType3InputData->ChassisThermalState;
+  SmbiosRecord->SecurityStatus = (UINT8)ForType3InputData->ChassisSecurityState;
+  CopyMem (SmbiosRecord->OemDefined,(UINT8*)&ForType3InputData->ChassisOemDefined, 4);
+
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  UnicodeStrToAsciiStr(Manufacturer, OptionalStrStart);
+  UnicodeStrToAsciiStr(Version, OptionalStrStart + ManuStrLen + 1);
+  UnicodeStrToAsciiStr(SerialNumber, OptionalStrStart + ManuStrLen + 1 + VerStrLen + 1);
+  UnicodeStrToAsciiStr(AssertTag, OptionalStrStart + ManuStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1);
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+
+  FreePool(SmbiosRecord);
+  return Status;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDevice.uni b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDevice.uni
new file mode 100644
index 0000000000..9dd0b76ea2
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDevice.uni
@@ -0,0 +1,35 @@
+// *++
+//
+// Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// 
+// Module Name:
+//
+//   MiscMemoryDevice.uni
+// 
+// Abstract:
+// 
+//   Memory Device	
+//   Misc. subclass type 17.
+//   SMBIOS type 17.
+// 
+// Revision History:
+// 
+// --*/
+
+
+/=#
+
+#langdef   en-US "English"
+
+#string STR_MISC_MEM_DEV_LOCATOR_0          #language en-US  "MODULE 0"
+#string STR_MISC_MEM_DEV_LOCATOR_1          #language en-US  "MODULE 1"
+#string STR_MISC_MEM_DEV_LOCATOR0           #language en-US  "DIMM 0"
+#string STR_MISC_MEM_DEV_LOCATOR1           #language en-US  "DIMM 1"
+#string STR_MISC_MEM_BANK_LOCATOR0          #language en-US  "BANK 0"
+#string STR_MISC_MEM_BANK_LOCATOR1          #language en-US  "BANK 1"
+#string STR_MISC_MEM_MANUFACTURER          #language en-US  "Micron"
+#string STR_MISC_MEM_SERIAL_NO             #language en-US  " "
+#string STR_MISC_MEM_ASSET_TAG             #language en-US  " "
+#string STR_MISC_MEM_PART_NUMBER           #language en-US  " "
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceData.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceData.c
new file mode 100644
index 0000000000..4a416dfdeb
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceData.c
@@ -0,0 +1,45 @@
+/*++
+
+Copyright (c) 2006  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscMemoryDeviceData.c
+
+Abstract:
+
+   Memory Device
+   Misc. subclass type 17.
+   SMBIOS type 17.
+
+--*/
+
+
+#include "CommonHeader.h"
+#include "MiscSubclassDriver.h"
+
+MISC_SMBIOS_TABLE_DATA(EFI_MEMORY_ARRAY_LINK_DATA, MiscMemoryDevice) = {
+	STRING_TOKEN (STR_MISC_MEM_DEV_LOCATOR0),        // Memory Device locator
+	STRING_TOKEN (STR_MISC_MEM_BANK_LOCATOR0),       // Memory Bank Locator
+	STRING_TOKEN (STR_MISC_MEM_MANUFACTURER),        // Memory manufacturer
+	STRING_TOKEN (STR_MISC_MEM_SERIAL_NO),           // Memory serial Number
+	STRING_TOKEN (STR_MISC_MEM_ASSET_TAG),           // Memory Asset Tag
+	STRING_TOKEN (STR_MISC_MEM_PART_NUMBER),         // Memory Part Number
+	0,											    // Memory Array Link
+	0, 					                // Memory SubArray link
+	0, 					                // UINT16 MemoryTotalWidth
+	0, 					                // UINT16 MemoryDatawidth
+	0,										      // Memory Device Size
+	EfiMemoryFormFactorDip, 	  // Memory Form Factor
+    2,                        // UINT8 Memory Device type
+	EfiMemoryTypeDram, 			    // Memory Type
+    0,                        // Memory Type Detail
+    0,										    // Memory Speed
+	0 					                // Memory State
+
+};
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceFunction.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceFunction.c
new file mode 100644
index 0000000000..3872312c30
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceFunction.c
@@ -0,0 +1,319 @@
+/*++
+
+Copyright (c) 2006  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscMemoryDeviceFunction.c
+
+Abstract:
+
+   Memory Device
+   Misc. subclass type 17.
+   SMBIOS type 17.
+
+--*/
+
+
+#include "CommonHeader.h"
+#include "MiscSubclassDriver.h"
+#include <Protocol/DataHub.h>
+#include <Guid/DataHubRecords.h>
+#include <Protocol/MemInfo.h>
+
+
+#define FREQ_800           0x00
+#define FREQ_1066          0x01
+#define FREQ_1333          0x02
+#define FREQ_1600          0x03
+
+#define MAX_SOCKETS  2
+#define EfiMemoryTypeDdr3  0x18
+
+enum {
+    DDRType_DDR3 = 0,
+    DDRType_DDR3L = 1,
+    DDRType_DDR3U = 2,
+    DDRType_DDR3All = 3,
+    DDRType_LPDDR2 = 4,
+    DDRType_LPDDR3 = 5,
+    DDRType_DDR4 = 6
+};
+
+
+typedef struct {
+  EFI_PHYSICAL_ADDRESS        MemoryArrayStartAddress;
+  EFI_PHYSICAL_ADDRESS        MemoryArrayEndAddress;
+  EFI_INTER_LINK_DATA         PhysicalMemoryArrayLink;
+  UINT16                      MemoryArrayPartitionWidth;
+} EFI_MEMORY_ARRAY_START_ADDRESS;
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscBiosVendor (Type 0).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+VOID
+GetType16Hndl (
+  IN  EFI_SMBIOS_PROTOCOL      *Smbios,
+  OUT  EFI_SMBIOS_HANDLE       *Handle
+  )
+{
+  EFI_STATUS                 Status;
+  EFI_SMBIOS_TYPE            RecordType;
+  EFI_SMBIOS_TABLE_HEADER    *Buffer;
+
+  *Handle = 0;
+   RecordType = EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY;
+
+    Status = Smbios->GetNext (
+                       Smbios,
+                       Handle,
+                       &RecordType,
+                       &Buffer,
+                       NULL
+                       );
+    if (!EFI_ERROR(Status)) {
+        return;
+      }
+  *Handle = 0xFFFF;
+}
+
+MISC_SMBIOS_TABLE_FUNCTION( MiscMemoryDevice )
+{
+    CHAR8                           *OptionalStrStart;
+    UINTN                           MemDeviceStrLen;
+    UINTN                           MemBankLocatorStrLen;
+    UINTN                           MemManufacturerStrLen;
+    UINTN                           MemSerialNumberStrLen;
+    UINTN                           MemAssetTagStrLen;
+    UINTN                           MemPartNumberStrLen;
+    CHAR16                          *MemDevice;
+    CHAR16                          *MemBankLocator;
+    CHAR16                          *MemManufacturer;
+    CHAR16                          *MemSerialNumber;
+    CHAR16                          *MemAssetTag;
+    CHAR16                          *MemPartNumber;
+    EFI_STATUS                      Status;
+    STRING_REF                      TokenToGet;
+    SMBIOS_TABLE_TYPE17             *SmbiosRecord;
+    EFI_SMBIOS_HANDLE               SmbiosHandle;
+    EFI_MEMORY_ARRAY_LINK_DATA      *ForType17InputData;
+    UINT16                          DdrFreq=0;
+    UINT16                          Type16Handle=0;
+    MEM_INFO_PROTOCOL               *MemInfoHob;
+    UINT8                           MemoryType;
+
+    UINT8                           Dimm;
+    UINT8                           NumSlots;
+    STRING_REF                      DevLocator[] = {
+      STRING_TOKEN(STR_MISC_MEM_DEV_LOCATOR0), STRING_TOKEN(STR_MISC_MEM_DEV_LOCATOR1)
+    };
+    STRING_REF                      BankLocator[] = {
+      STRING_TOKEN(STR_MISC_MEM_BANK_LOCATOR0), STRING_TOKEN(STR_MISC_MEM_BANK_LOCATOR1)
+    };
+
+    //
+    // First check for invalid parameters.
+    //
+    if (RecordData == NULL) {
+        return EFI_INVALID_PARAMETER;
+    }
+    ForType17InputData        = (EFI_MEMORY_ARRAY_LINK_DATA *)RecordData;
+
+    //
+    // Get Memory size parameters for each rank from the chipset registers
+    //
+    Status = gBS->LocateProtocol (
+                    &gMemInfoProtocolGuid,
+                    NULL,
+                    (void **)&MemInfoHob
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    NumSlots = (UINT8)(MAX_SOCKETS);
+
+    //
+    // Memory Freq
+    //
+    switch (MemInfoHob->MemInfoData.ddrFreq){
+        case FREQ_800:
+          DdrFreq = 800;
+          break;
+        case FREQ_1066:
+          DdrFreq = 1066;
+          break;
+        case FREQ_1333:
+          DdrFreq = 1333;
+          break;
+        case FREQ_1600:
+          DdrFreq = 1600;
+          break;
+        default:
+          DdrFreq = 0;
+          break;
+    }
+
+    //
+    // Memory Type
+    //
+    switch  (MemInfoHob->MemInfoData.ddrType) {
+        case DDRType_LPDDR2:
+          MemoryType  = EfiMemoryTypeDdr2;
+          break;
+        case DDRType_DDR3:
+        case DDRType_DDR3L:
+        case DDRType_DDR3U:
+        case DDRType_LPDDR3:
+          MemoryType = EfiMemoryTypeDdr3;
+          break;
+        default:
+          MemoryType = EfiMemoryTypeUnknown;
+          break;
+    }
+
+    for (Dimm = 0; Dimm < NumSlots; Dimm++) {
+    //
+    // Memory Device Locator
+    //
+    TokenToGet = DevLocator[Dimm];
+    MemDevice = SmbiosMiscGetString (TokenToGet);
+    MemDeviceStrLen = StrLen(MemDevice);
+    if (MemDeviceStrLen > SMBIOS_STRING_MAX_LENGTH) {
+      return EFI_UNSUPPORTED;
+    }
+
+    TokenToGet = DevLocator[Dimm];
+    MemDevice = SmbiosMiscGetString (TokenToGet);
+    MemDeviceStrLen = StrLen(MemDevice);
+    if (MemDeviceStrLen > SMBIOS_STRING_MAX_LENGTH) {
+      return EFI_UNSUPPORTED;
+    }
+
+    //
+    // Memory Bank Locator
+    //
+    TokenToGet = BankLocator[Dimm];
+    MemBankLocator = SmbiosMiscGetString (TokenToGet);
+    MemBankLocatorStrLen = StrLen(MemBankLocator);
+    if (MemBankLocatorStrLen > SMBIOS_STRING_MAX_LENGTH) {
+      return EFI_UNSUPPORTED;
+    }
+
+    //
+    // Memory Manufacturer
+    //
+    TokenToGet = STRING_TOKEN (STR_MISC_MEM_MANUFACTURER);
+    MemManufacturer = SmbiosMiscGetString (TokenToGet);
+    MemManufacturerStrLen = StrLen(MemManufacturer);
+    if (MemManufacturerStrLen > SMBIOS_STRING_MAX_LENGTH) {
+      return EFI_UNSUPPORTED;
+    }
+
+    //
+    // Memory Serial Number
+    //
+    TokenToGet = STRING_TOKEN (STR_MISC_MEM_SERIAL_NO);
+    MemSerialNumber = SmbiosMiscGetString (TokenToGet);
+    MemSerialNumberStrLen = StrLen(MemSerialNumber);
+    if (MemSerialNumberStrLen > SMBIOS_STRING_MAX_LENGTH) {
+      return EFI_UNSUPPORTED;
+    }
+
+    //
+    // Memory Asset Tag Number
+    //
+    TokenToGet = STRING_TOKEN (STR_MISC_MEM_ASSET_TAG);
+    MemAssetTag = SmbiosMiscGetString (TokenToGet);
+    MemAssetTagStrLen = StrLen(MemAssetTag);
+    if (MemAssetTagStrLen > SMBIOS_STRING_MAX_LENGTH) {
+      return EFI_UNSUPPORTED;
+    }
+
+    //
+    // Memory Part Number
+    //
+    TokenToGet = STRING_TOKEN (STR_MISC_MEM_PART_NUMBER);
+    MemPartNumber = SmbiosMiscGetString (TokenToGet);
+    MemPartNumberStrLen = StrLen(MemPartNumber);
+    if (MemPartNumberStrLen > SMBIOS_STRING_MAX_LENGTH) {
+      return EFI_UNSUPPORTED;
+    }
+
+    //
+    // Two zeros following the last string.
+    //
+    SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE17) + MemDeviceStrLen + 1 + MemBankLocatorStrLen + 1 + MemManufacturerStrLen + 1 + MemSerialNumberStrLen + 1 + MemAssetTagStrLen+1 + MemPartNumberStrLen + 1 + 1);
+    ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE17) +  MemDeviceStrLen + 1 + MemBankLocatorStrLen + 1 + MemManufacturerStrLen + 1 + MemSerialNumberStrLen + 1 + MemAssetTagStrLen+1 + MemPartNumberStrLen + 1 + 1);
+
+    SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_DEVICE;
+    SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE17);
+
+    //
+    // Make handle chosen by smbios protocol.add automatically.
+    //
+    SmbiosRecord->Hdr.Handle = 0;
+
+    //
+    // Memory Array Handle will be the 3rd optional string following the formatted structure.
+    //
+    GetType16Hndl( Smbios, &Type16Handle);
+    SmbiosRecord->MemoryArrayHandle = Type16Handle;
+
+    //
+    // Memory Size
+    //
+    if ((MemInfoHob->MemInfoData.dimmSize[Dimm])!=0){
+    SmbiosRecord->TotalWidth = 32;
+    SmbiosRecord->DataWidth = 32;
+    SmbiosRecord->Size = MemInfoHob->MemInfoData.dimmSize[Dimm];
+    SmbiosRecord->Speed = DdrFreq;
+    SmbiosRecord->ConfiguredMemoryClockSpeed = DdrFreq;
+    SmbiosRecord->FormFactor = EfiMemoryFormFactorDimm;
+    }
+
+    SmbiosRecord->DeviceSet =(UINT8) ForType17InputData->MemoryDeviceSet;
+    SmbiosRecord->DeviceLocator= 1;
+    SmbiosRecord->BankLocator = 2;
+
+
+    SmbiosRecord->Manufacturer = 3;
+    SmbiosRecord->SerialNumber= 4;
+    SmbiosRecord->AssetTag= 5;
+    SmbiosRecord->PartNumber= 6;
+    SmbiosRecord->Attributes = (UINT8) ForType17InputData->MemoryState;
+    SmbiosRecord->MemoryType = MemoryType;
+
+    OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+    UnicodeStrToAsciiStr(MemDevice, OptionalStrStart);
+    UnicodeStrToAsciiStr(MemBankLocator, OptionalStrStart + MemDeviceStrLen + 1);
+    UnicodeStrToAsciiStr(MemManufacturer, OptionalStrStart + MemDeviceStrLen + 1 + MemBankLocatorStrLen + 1);
+    UnicodeStrToAsciiStr(MemSerialNumber, OptionalStrStart + MemDeviceStrLen + 1 + MemBankLocatorStrLen + 1 + MemManufacturerStrLen + 1);
+    UnicodeStrToAsciiStr(MemAssetTag, OptionalStrStart + MemDeviceStrLen + 1 + MemBankLocatorStrLen + 1 + MemManufacturerStrLen + 1 + MemSerialNumberStrLen + 1);
+    UnicodeStrToAsciiStr(MemPartNumber, OptionalStrStart + MemDeviceStrLen + 1 + MemBankLocatorStrLen + 1 + MemManufacturerStrLen + 1 + MemSerialNumberStrLen + 1+ MemAssetTagStrLen+1 );
+
+    //
+    // Now we have got the full smbios record, call smbios protocol to add this record.
+    //
+    SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+    Status = Smbios-> Add(
+                        Smbios,
+                        NULL,
+                        &SmbiosHandle,
+                        (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                        );
+    FreePool(SmbiosRecord);
+    }
+    return Status;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstallableLanguagesData.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstallableLanguagesData.c
new file mode 100644
index 0000000000..1b41d8fac7
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstallableLanguagesData.c
@@ -0,0 +1,38 @@
+/** @file
+
+Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscNumberOfInstallableLanguagesData.c
+
+Abstract:
+
+  Static data of the Number of installable languages information.
+  Number of installable languages information is Misc. subclass type 11 and SMBIOS type 13.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES_DATA, NumberOfInstallableLanguages)
+= {
+  1,    // NumberOfInstallableLanguages
+  {     // LanguageFlags
+    1,  // AbbreviatedLanguageFormat
+    0   // Reserved
+  },
+  STRING_TOKEN(STR_MISC_SYSTEM_LANGUAGE_EN_US)  // CurrentLanguageNumber
+};
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstallableLanguagesFunction.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstallableLanguagesFunction.c
new file mode 100644
index 0000000000..4a96a2c465
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstallableLanguagesFunction.c
@@ -0,0 +1,251 @@
+/*++
+
+Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
+
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+
+
+
+Module Name:
+
+  MiscNumberOfInstallableLanguagesFunction.c
+
+Abstract:
+
+  This driver parses the mSmbiosMiscDataTable structure and reports
+  any generated data.
+
+--*/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+/**
+  Check whether the language is supported for given HII handle
+
+  @param   HiiHandle     The HII package list handle.
+  @param   Offset        The offest of current lanague in the supported languages.
+  @param   CurrentLang   The language code.
+
+  @retval  TRUE          Supported.
+  @retval  FALSE         Not Supported.
+
+**/
+VOID
+EFIAPI
+CurrentLanguageMatch (
+  IN  EFI_HII_HANDLE                   HiiHandle,
+  OUT UINT16                           *Offset,
+  OUT CHAR8                            *CurrentLang
+  )
+{
+  CHAR8     *DefaultLang;
+  CHAR8     *BestLanguage;
+  CHAR8     *Languages;
+  CHAR8     *MatchLang;
+  CHAR8     *EndMatchLang;
+  UINTN     CompareLength;
+
+  Languages = HiiGetSupportedLanguages (HiiHandle);
+  if (Languages == NULL) {
+    return;
+  }
+
+  CurrentLang  = GetEfiGlobalVariable (L"PlatformLang");
+  DefaultLang  = (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang);
+  BestLanguage = GetBestLanguage (
+                   Languages,
+                   FALSE,
+                   (CurrentLang != NULL) ? CurrentLang : "",
+                   DefaultLang,
+                   NULL
+                   );
+  if (BestLanguage != NULL) {
+    //
+    // Find the best matching RFC 4646 language, compute the offset.
+    //
+    CompareLength = AsciiStrLen (BestLanguage);
+    for (MatchLang = Languages, (*Offset) = 0; *MatchLang != '\0'; (*Offset)++) {
+      //
+      // Seek to the end of current match language.
+      //
+      for (EndMatchLang = MatchLang; *EndMatchLang != '\0' && *EndMatchLang != ';'; EndMatchLang++);
+
+      if ((EndMatchLang == MatchLang + CompareLength) && AsciiStrnCmp(MatchLang, BestLanguage, CompareLength) == 0) {
+        //
+        // Find the current best Language in the supported languages
+        //
+        break;
+      }
+      //
+      // best language match be in the supported language.
+      //
+      ASSERT (*EndMatchLang == ';');
+      MatchLang = EndMatchLang + 1;
+    }
+    FreePool (BestLanguage);
+  }
+
+  FreePool (Languages);
+  if (CurrentLang != NULL) {
+    FreePool (CurrentLang);
+  }
+  return ;
+}
+
+
+/**
+  Get next language from language code list (with separator ';').
+
+  @param  LangCode       Input: point to first language in the list. On
+                         Otput: point to next language in the list, or
+                                NULL if no more language in the list.
+  @param  Lang           The first language in the list.
+
+**/
+VOID
+EFIAPI
+GetNextLanguage (
+  IN OUT CHAR8      **LangCode,
+  OUT CHAR8         *Lang
+  )
+{
+  UINTN  Index;
+  CHAR8  *StringPtr;
+
+  ASSERT (LangCode != NULL);
+  ASSERT (*LangCode != NULL);
+  ASSERT (Lang != NULL);
+
+  Index     = 0;
+  StringPtr = *LangCode;
+  while (StringPtr[Index] != 0 && StringPtr[Index] != ';') {
+    Index++;
+  }
+
+  CopyMem (Lang, StringPtr, Index);
+  Lang[Index] = 0;
+
+  if (StringPtr[Index] == ';') {
+    Index++;
+  }
+  *LangCode = StringPtr + Index;
+}
+
+/**
+  This function returns the number of supported languages on HiiHandle.
+
+  @param   HiiHandle    The HII package list handle.
+
+  @retval  The number of supported languages.
+
+**/
+UINT16
+EFIAPI
+GetSupportedLanguageNumber (
+  IN EFI_HII_HANDLE    HiiHandle
+  )
+{
+  CHAR8   *Lang;
+  CHAR8   *Languages;
+  CHAR8   *LanguageString;
+  UINT16  LangNumber;
+
+  Languages = HiiGetSupportedLanguages (HiiHandle);
+  if (Languages == NULL) {
+    return 0;
+  }
+
+  LangNumber = 0;
+  Lang = AllocatePool (AsciiStrSize (Languages));
+  if (Lang != NULL) {
+    LanguageString = Languages;
+    while (*LanguageString != 0) {
+      GetNextLanguage (&LanguageString, Lang);
+      LangNumber++;
+    }
+    FreePool (Lang);
+  }
+  FreePool (Languages);
+  return LangNumber;
+}
+
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscNumberOfInstallableLanguages (Type 13).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(NumberOfInstallableLanguages)
+{
+  UINTN                                     LangStrLen;
+  CHAR8                                     CurrentLang[SMBIOS_STRING_MAX_LENGTH + 1];
+  CHAR8                                     *OptionalStrStart;
+  UINT16                                    Offset;
+  EFI_STATUS                                Status;
+  EFI_SMBIOS_HANDLE                         SmbiosHandle;
+  SMBIOS_TABLE_TYPE13                       *SmbiosRecord;
+  EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES  *ForType13InputData;
+
+  ForType13InputData = (EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES *)RecordData;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ForType13InputData->NumberOfInstallableLanguages = GetSupportedLanguageNumber (mHiiHandle);
+
+  //
+  // Try to check if current langcode matches with the langcodes in installed languages
+  //
+  ZeroMem(CurrentLang, SMBIOS_STRING_MAX_LENGTH + 1);
+  CurrentLanguageMatch (mHiiHandle, &Offset, CurrentLang);
+  LangStrLen = AsciiStrLen(CurrentLang);
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE13) + LangStrLen + 1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE13) + LangStrLen + 1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_BIOS_LANGUAGE_INFORMATION;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE13);
+
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle = 0;
+
+  SmbiosRecord->InstallableLanguages = (UINT8)ForType13InputData->NumberOfInstallableLanguages;
+  SmbiosRecord->Flags = (UINT8)ForType13InputData->LanguageFlags.AbbreviatedLanguageFormat;
+  SmbiosRecord->CurrentLanguages = 1;
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  AsciiStrCpy(OptionalStrStart, CurrentLang);
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+  FreePool(SmbiosRecord);
+  return Status;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemString.uni b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemString.uni
new file mode 100644
index 0000000000..c6eb8bf498
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemString.uni
@@ -0,0 +1,25 @@
+// *++
+//
+// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// 
+// Module Name:
+//
+//   MiscOemSring.uni
+// 
+// Abstract:
+// 
+//   Language Information
+// 
+// Revision History:
+// 
+// --*/
+
+
+/=#
+
+#langdef en-US "English"
+#string STR_INTEL_ETK_VER               #language en-US  "ETK_VER_02.01"
+#string STR_INTEL_ETK_VER_FOR_ROEM      #language en-US  "ETK_VER_02.00"
+#string STR_MISC_OEM_EN_US              #language en-US  "English (US)"
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringData.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringData.c
new file mode 100644
index 0000000000..ceecaad549
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringData.c
@@ -0,0 +1,34 @@
+/** @file
+
+Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+    MiscOemStringData.c
+
+Abstract:
+
+  Static data of OEM String information.
+  OEM String information is Misc. subclass type 9 and SMBIOS type 11.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_OEM_STRING, MiscOemString) = {
+  STRING_TOKEN(STR_INTEL_ETK_VER)
+};
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_OEM_STRING_DATA, OemString)
+= { STRING_TOKEN(STR_MISC_OEM_EN_US) };
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringFunction.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringFunction.c
new file mode 100644
index 0000000000..8624481149
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringFunction.c
@@ -0,0 +1,89 @@
+/*++
+
+Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  MiscOemStringFunction.c
+
+Abstract:
+
+  boot information boot time changes.
+  SMBIOS type 11.
+
+--*/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscOemString (Type 11).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(OemString)
+{
+  UINTN                    OemStrLen;
+  CHAR8                    *OptionalStrStart;
+  EFI_STATUS               Status;
+  EFI_STRING               OemStr;
+  STRING_REF               TokenToGet;
+  EFI_SMBIOS_HANDLE        SmbiosHandle;
+  SMBIOS_TABLE_TYPE11      *SmbiosRecord;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_OEM_EN_US);
+  OemStr = SmbiosMiscGetString (TokenToGet);
+  OemStrLen = StrLen(OemStr);
+  if (OemStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE11) + OemStrLen + 1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE11) + OemStrLen + 1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_OEM_STRINGS;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE11);
+
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle = 0;
+  SmbiosRecord->StringCount = 1;
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  UnicodeStrToAsciiStr(OemStr, OptionalStrStart);
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+  FreePool(SmbiosRecord);
+  return Status;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90.uni b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90.uni
new file mode 100644
index 0000000000..917a7b9d6e
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90.uni
@@ -0,0 +1,31 @@
+// *++
+//
+// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// 
+// Module Name:
+//
+//   MiscOemType0x90.uni
+// 
+// Abstract:
+// 
+//   Firmware Version Information 
+//   SMBIOS type 0x90.
+// 
+// Revision History:
+// 
+// --*/
+
+
+/=#
+#langdef   en-US "English"
+
+#string STR_MISC_SEC_VERSION                #language en-US  "NA"
+#string STR_MISC_UCODE_VERSION              #language en-US  "NA"
+#string STR_MISC_GOP_VERSION                #language en-US  "NA"
+#string STR_MISC_PROCESSOR_STEPPING         #language en-US  "NA"
+
+        
+              
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Data.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Data.c
new file mode 100644
index 0000000000..9b348813a7
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Data.c
@@ -0,0 +1,36 @@
+/*++
+
+Copyright (c) 2012  - 2014, Intel Corporation.  All rights reserved.
+                                                                                   

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

+
+
+
+Module Name:
+
+  MiscOemType0x90Data.c
+
+Abstract:
+
+  This file contains the Misc Oem Data (SMBIOS data type 0x90)
+
+--*/
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+
+//
+// Static (possibly build generated) Oem data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_OEM_TYPE_0x90, MiscOemType0x90) = {
+
+STRING_TOKEN (STR_MISC_SEC_VERSION),
+STRING_TOKEN (STR_MISC_UCODE_VERSION),
+STRING_TOKEN (STR_MISC_GOP_VERSION),
+STRING_TOKEN (STR_MISC_PROCESSOR_STEPPING),
+
+};
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Function.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Function.c
new file mode 100644
index 0000000000..684cda83ec
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Function.c
@@ -0,0 +1,442 @@
+/*++
+
+Copyright (c) 1999  - 2014, Intel Corporation.  All rights reserved.
+                                                                                   

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

+
+
+
+Module Name:
+
+  MiscOemType0x88Function.c
+
+Abstract:
+
+  The function that processes the Smbios data type 0x88 before they
+  are submitted to Data Hub
+
+--*/
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+#include <Library/PrintLib.h>
+#include <Library/CpuIA32.h>
+#include <Protocol/DxeSmmReadyToLock.h>
+
+
+VOID
+GetCPUStepping ( )
+{
+  CHAR16    Buffer[40];
+
+  UINT16                                FamilyId;
+  UINT8                                 Model;
+  UINT8                                 SteppingId;
+  UINT8                                 ProcessorType;
+
+
+  EfiCpuVersion (&FamilyId, &Model, &SteppingId, &ProcessorType);
+
+  //
+  //we need raw Model data
+  //
+  Model = Model & 0xf;
+
+  //
+  //Family/Model/Step
+  //
+  UnicodeSPrint (Buffer, sizeof (Buffer), L"%d/%d/%d", FamilyId,  Model, SteppingId);
+  HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_PROCESSOR_STEPPING), Buffer, NULL);
+
+}
+
+EFI_STATUS
+SearchChildHandle(
+  EFI_HANDLE Father,
+  EFI_HANDLE *Child
+  )
+{
+  EFI_STATUS                                                 Status;
+  UINTN                                                          HandleIndex;
+  EFI_GUID                                                     **ProtocolGuidArray = NULL;
+  UINTN                                                          ArrayCount;
+  UINTN                                                          ProtocolIndex;
+  UINTN                                                          OpenInfoCount;
+  UINTN                                                          OpenInfoIndex;
+  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY  *OpenInfo = NULL;
+  UINTN                                                          mHandleCount;
+  EFI_HANDLE                                                 *mHandleBuffer= NULL;
+
+  //
+  // Retrieve the list of all handles from the handle database
+  //
+  Status = gBS->LocateHandleBuffer (
+                  AllHandles,
+                  NULL,
+                  NULL,
+                  &mHandleCount,
+                  &mHandleBuffer
+                  );
+
+  for (HandleIndex = 0; HandleIndex < mHandleCount; HandleIndex++) {
+    //
+    // Retrieve the list of all the protocols on each handle
+    //
+    Status = gBS->ProtocolsPerHandle (
+                    mHandleBuffer[HandleIndex],
+                    &ProtocolGuidArray,
+                    &ArrayCount
+                    );
+    if (!EFI_ERROR (Status)) {
+      for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
+        Status = gBS->OpenProtocolInformation (
+                        mHandleBuffer[HandleIndex],
+                        ProtocolGuidArray[ProtocolIndex],
+                        &OpenInfo,
+                        &OpenInfoCount
+                        );
+
+        if (!EFI_ERROR (Status)) {
+          for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
+            if(OpenInfo[OpenInfoIndex].AgentHandle == Father) {
+              if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
+                *Child = mHandleBuffer[HandleIndex];
+		  Status = EFI_SUCCESS;
+		  goto TryReturn;
+              }
+            }
+          }
+	   Status = EFI_NOT_FOUND;
+       }
+      }
+      if(OpenInfo != NULL) {
+        FreePool(OpenInfo);
+	      OpenInfo = NULL;
+      }
+    }
+    if(ProtocolGuidArray != NULL) {
+    FreePool (ProtocolGuidArray);
+    ProtocolGuidArray = NULL;
+    }
+  }
+TryReturn:
+  if(OpenInfo != NULL) {
+    FreePool (OpenInfo);
+    OpenInfo = NULL;
+  }
+  if(ProtocolGuidArray != NULL) {
+    FreePool(ProtocolGuidArray);
+    ProtocolGuidArray = NULL;
+  }
+  if(mHandleBuffer != NULL) {
+    FreePool (mHandleBuffer);
+    mHandleBuffer = NULL;
+  }
+  return Status;
+}
+
+EFI_STATUS
+JudgeHandleIsPCIDevice(
+  EFI_HANDLE    Handle,
+  UINT8            Device,
+  UINT8            Funs
+  )
+{
+  EFI_STATUS  Status;
+  EFI_DEVICE_PATH   *DPath;
+
+  Status = gBS->HandleProtocol (
+                  Handle,
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID **) &DPath
+                  );
+  if(!EFI_ERROR(Status)) {
+    while(!IsDevicePathEnd(DPath)) {
+      if((DPath->Type == HARDWARE_DEVICE_PATH) && (DPath->SubType == HW_PCI_DP)) {
+        PCI_DEVICE_PATH   *PCIPath;
+        PCIPath = (PCI_DEVICE_PATH*) DPath;
+        DPath = NextDevicePathNode(DPath);
+
+        if(IsDevicePathEnd(DPath) && (PCIPath->Device == Device) && (PCIPath->Function == Funs)) {
+          return EFI_SUCCESS;
+        }
+      } else {
+        DPath = NextDevicePathNode(DPath);
+      }
+    }
+  }
+  return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+GetDriverName(
+  EFI_HANDLE   Handle
+)
+{
+  EFI_DRIVER_BINDING_PROTOCOL        *BindHandle = NULL;
+  EFI_STATUS                         Status;
+  UINT32                             Version;
+  UINT16                             *Ptr;
+  CHAR16                             Buffer[40];
+  STRING_REF                  TokenToUpdate;
+  Status = gBS->OpenProtocol(
+                  Handle,
+                  &gEfiDriverBindingProtocolGuid,
+                  (VOID**)&BindHandle,
+                   NULL,
+                   NULL,
+                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                   );
+
+  if (EFI_ERROR(Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  Version = BindHandle->Version;
+  Ptr = (UINT16*)&Version;
+  UnicodeSPrint(Buffer, sizeof (Buffer), L"%d.%d.%d", Version >> 24 , (Version >>16)& 0x0f ,*(Ptr));
+
+  TokenToUpdate = (STRING_REF)STR_MISC_GOP_VERSION;
+  HiiSetString(mHiiHandle, TokenToUpdate, Buffer, NULL);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetGOPDriverName()
+{
+  UINTN                         HandleCount;
+  EFI_HANDLE                *Handles= NULL;
+  UINTN                         Index;
+  EFI_STATUS                Status;
+  EFI_HANDLE                Child = 0;
+
+  Status = gBS->LocateHandleBuffer(
+		              ByProtocol,
+		              &gEfiDriverBindingProtocolGuid,
+		              NULL,
+		              &HandleCount,
+		              &Handles
+                  );
+
+  for (Index = 0; Index < HandleCount ; Index++) {
+    Status = SearchChildHandle(Handles[Index], &Child);
+    if(!EFI_ERROR(Status)) {
+      Status = JudgeHandleIsPCIDevice(Child, 0x02, 0x00);
+      if(!EFI_ERROR(Status)) {
+        return GetDriverName(Handles[Index]);
+      }
+    }
+  }
+  return EFI_UNSUPPORTED;
+}
+
+VOID
+GetUcodeVersion()
+{
+  UINT32                   MicroCodeVersion;
+  CHAR16                   Buffer[40];
+
+  //
+  // Microcode Revision
+  //
+  EfiWriteMsr (EFI_MSR_IA32_BIOS_SIGN_ID, 0);
+  EfiCpuid (EFI_CPUID_VERSION_INFO, NULL);
+  MicroCodeVersion = (UINT32) RShiftU64 (EfiReadMsr (EFI_MSR_IA32_BIOS_SIGN_ID), 32);
+  UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", MicroCodeVersion);
+  HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_UCODE_VERSION), Buffer, NULL);
+}
+
+/**
+  Publish the smbios OEM type 0x90.
+
+  @param Event   - Event whose notification function is being invoked (gEfiDxeSmmReadyToLockProtocolGuid).
+  @param Context - Pointer to the notification functions context, which is implementation dependent.
+
+  @retval None
+
+**/
+EFI_STATUS
+EFIAPI
+AddSmbiosT0x90Callback (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  EFI_STATUS            Status;
+  UINTN                 SECVerStrLen = 0;
+  UINTN                 uCodeVerStrLen = 0;
+  UINTN                 GOPStrLen = 0;
+  UINTN                 SteppingStrLen = 0;
+  SMBIOS_TABLE_TYPE90    *SmbiosRecord;
+  EFI_SMBIOS_HANDLE     SmbiosHandle;
+  CHAR16                *SECVer;
+  CHAR16                *uCodeVer;
+  CHAR16                *GOPVer;
+  CHAR16                *Stepping;
+  STRING_REF            TokenToGet;
+  CHAR8                 *OptionalStrStart;
+  EFI_SMBIOS_PROTOCOL               *SmbiosProtocol;
+
+  DEBUG ((EFI_D_INFO, "Executing SMBIOS T0x90 callback.\n"));
+
+  gBS->CloseEvent (Event);    // Unload this event.
+
+  //
+  // First check for invalid parameters.
+  //
+  if (Context == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = gBS->LocateProtocol (
+                  &gEfiSmbiosProtocolGuid,
+                  NULL,
+                  (VOID *) &SmbiosProtocol
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  GetUcodeVersion();
+  GetGOPDriverName();
+  GetCPUStepping();
+
+  TokenToGet = STRING_TOKEN (STR_MISC_SEC_VERSION);
+  SECVer = SmbiosMiscGetString (TokenToGet);
+  SECVerStrLen = StrLen(SECVer);
+  if (SECVerStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_UCODE_VERSION);
+  uCodeVer = SmbiosMiscGetString (TokenToGet);
+  uCodeVerStrLen = StrLen(uCodeVer);
+  if (uCodeVerStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_GOP_VERSION);
+  GOPVer = SmbiosMiscGetString (TokenToGet);
+  GOPStrLen = StrLen(GOPVer);
+  if (GOPStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_PROCESSOR_STEPPING);
+  Stepping = SmbiosMiscGetString (TokenToGet);
+  SteppingStrLen = StrLen(Stepping);
+
+
+  if (SteppingStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE90) + SECVerStrLen + 1 + uCodeVerStrLen + 1 + GOPStrLen + 1 + SteppingStrLen + 1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE90) + SECVerStrLen + 1 + uCodeVerStrLen + 1 + GOPStrLen + 1 + SteppingStrLen + 1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_FIRMWARE_VERSION_INFO;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE90);
+
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle = 0;
+
+  //
+  // SEC VERSION will be the 1st optional string following the formatted structure.
+  //
+  SmbiosRecord->SECVersion = 0;
+
+  //
+  // Microcode VERSION will be the 2nd optional string following the formatted structure.
+  //
+  SmbiosRecord->uCodeVersion = 2;
+
+  //
+  // GOP VERSION will be the 3rd optional string following the formatted structure.
+  //
+  SmbiosRecord->GOPVersion = 3;
+
+  //
+  // CPU Stepping will be the 4th optional string following the formatted structure.
+  //
+  SmbiosRecord->CpuStepping = 4;
+
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  UnicodeStrToAsciiStr(SECVer, OptionalStrStart);
+  UnicodeStrToAsciiStr(uCodeVer, OptionalStrStart + SECVerStrLen + 1);
+  UnicodeStrToAsciiStr(GOPVer, OptionalStrStart + SECVerStrLen + 1 + uCodeVerStrLen + 1);
+  UnicodeStrToAsciiStr(Stepping, OptionalStrStart + SECVerStrLen + 1 + uCodeVerStrLen + 1 + GOPStrLen + 1);
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = SmbiosProtocol-> Add(
+                              SmbiosProtocol,
+                              NULL,
+                              &SmbiosHandle,
+                              (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                              );
+
+  FreePool(SmbiosRecord);
+  return Status;
+}
+
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscOemType0x90 (Type 0x90).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscOemType0x90)
+{
+  EFI_STATUS                    Status;
+  static BOOLEAN                CallbackIsInstalledT0x90 = FALSE;
+  VOID                           *AddSmbiosT0x90CallbackNotifyReg;
+  EFI_EVENT                      AddSmbiosT0x90CallbackEvent;
+
+  //
+  // This callback will create a OEM Type 0x90 record.
+  //
+  if (CallbackIsInstalledT0x90 == FALSE) {
+    CallbackIsInstalledT0x90 = TRUE;        	// Prevent more than 1 callback.
+    DEBUG ((EFI_D_INFO, "Create Smbios T0x90 callback.\n"));
+
+  //
+  // gEfiDxeSmmReadyToLockProtocolGuid is ready
+  //
+  Status = gBS->CreateEvent (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  (EFI_EVENT_NOTIFY)AddSmbiosT0x90Callback,
+                  RecordData,
+                  &AddSmbiosT0x90CallbackEvent
+                  );
+
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    return Status;
+
+  }
+
+  Status = gBS->RegisterProtocolNotify (
+                  &gEfiDxeSmmReadyToLockProtocolGuid,
+                  AddSmbiosT0x90CallbackEvent,
+                  &AddSmbiosT0x90CallbackNotifyReg
+                  );
+
+  return Status;
+  }
+
+  return EFI_SUCCESS;
+
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94.uni b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94.uni
new file mode 100644
index 0000000000..2c8bf4ce49
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94.uni
@@ -0,0 +1,42 @@
+// *++
+//
+// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// 
+// Module Name:
+//
+//   MiscOemType0x94.uni
+// 
+// Abstract:
+// 
+//   Firmware Version Information 
+//   SMBIOS type 0x94.
+// 
+// Revision History:
+// 
+// --*/
+
+
+/=#
+#langdef   en-US "English"
+
+#string STR_MISC_PMIC_VERSION                #language en-US  "NA"
+#string STR_MISC_TOUCH_VERSION               #language en-US  "NA"
+#string STR_MISC_PROCESSOR_MICROCODE_VALUE        #language en-US  "NA"
+#string STR_MISC_ULPMC_FW_VALUE                   #language en-US  "NA"
+#string STR_MISC_PUNIT_FW_VALUE                   #language en-US  "NA"
+#string STR_MISC_PMC_FW_VALUE                     #language en-US  "NA"        
+#string STR_MISC_SOC_VALUE                        #language en-US  "NA"
+#string STR_MISC_MRC_VERSION_VALUE                #language en-US  "NA"                
+#string STR_MISC_BOARD_ID_VALUE                   #language en-US  "NA"
+#string STR_MISC_FAB_ID_VALUE                     #language en-US  "NA"  
+#string STR_MISC_CPU_FLAVOR_VALUE                 #language en-US  "NA" 
+#string STR_MISC_SECURE_BOOT                      #language en-US  "NA" 
+#string STR_MISC_BOOT_MODE                        #language en-US  "NA"
+#string STR_MISC_SPEED_STEP                       #language en-US  "NA" 
+#string STR_MISC_CPU_TURBO                        #language en-US  "NA" 
+#string STR_MISC_CSTATE                           #language en-US  "NA" 
+#string STR_MISC_GFX_TURBO                        #language en-US  "NA"  
+#string STR_MISC_S0IX_VALUE                       #language en-US  "NA"
+#string STR_MISC_RC6_VALUE                        #language en-US  "NA"
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Data.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Data.c
new file mode 100644
index 0000000000..8709d61847
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Data.c
@@ -0,0 +1,54 @@
+/*++
+
+Copyright (c) 2012  - 2014, Intel Corporation.  All rights reserved.
+                                                                                   

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

+
+
+
+Module Name:
+
+  MiscOemType0x94Data.c
+
+Abstract:
+
+  This file contains the Misc version Data (SMBIOS data type 0x94)
+
+--*/
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+
+//
+// Static (possibly build generated) Oem data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_OEM_TYPE_0x94, MiscOemType0x94) = {
+
+STRING_TOKEN (STR_MISC_GOP_VERSION),
+STRING_TOKEN (STR_MISC_SEC_VERSION),
+STRING_TOKEN (STR_MISC_MRC_VERSION_VALUE),
+STRING_TOKEN (STR_MISC_UCODE_VERSION),
+STRING_TOKEN (STR_MISC_PUNIT_FW_VALUE),
+STRING_TOKEN (STR_MISC_PMC_FW_VALUE),
+STRING_TOKEN (STR_MISC_ULPMC_FW_VALUE),
+STRING_TOKEN (STR_MISC_SOC_VALUE),
+STRING_TOKEN (STR_MISC_BOARD_ID_VALUE),
+STRING_TOKEN (STR_MISC_FAB_ID_VALUE),
+STRING_TOKEN (STR_MISC_CPU_FLAVOR_VALUE),
+STRING_TOKEN (STR_MISC_BIOS_VERSION),
+STRING_TOKEN (STR_MISC_PMIC_VERSION),
+STRING_TOKEN (STR_MISC_TOUCH_VERSION),
+STRING_TOKEN (STR_MISC_SECURE_BOOT),
+STRING_TOKEN (STR_MISC_BOOT_MODE),
+STRING_TOKEN (STR_MISC_SPEED_STEP),
+STRING_TOKEN (STR_MISC_CPU_TURBO),
+STRING_TOKEN (STR_MISC_CSTATE),
+STRING_TOKEN (STR_MISC_GFX_TURBO),
+STRING_TOKEN (STR_MISC_S0IX_VALUE),
+STRING_TOKEN (STR_MISC_RC6_VALUE),
+
+};
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Function.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Function.c
new file mode 100644
index 0000000000..15c180129c
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Function.c
@@ -0,0 +1,1218 @@
+/*++
+
+Copyright (c) 1999  - 2014, Intel Corporation.  All rights reserved.
+                                                                                   

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

+
+
+
+Module Name:
+
+  MiscOemType0x94Function.c
+
+Abstract:
+
+  The function that processes the Smbios data type 0x94.
+
+--*/
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+#include <Protocol/DataHub.h>
+#include <Library/HiiLib.h>
+#include <Protocol/CpuIo2.h>
+#include <Library/PrintLib.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/SimpleNetwork.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/DiskInfo.h>
+#include <Protocol/IdeControllerInit.h>
+#include <Protocol/MpService.h>
+#include <Protocol/PchPlatformPolicy.h>
+#include <Protocol/CpuIo2.h>
+#include <Protocol/I2cBus.h>
+
+#include <Library/IoLib.h>
+#include <Library/I2CLib.h>
+#include <Library/CpuIA32.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Guid/PlatformInfo.h>
+#include <Guid/SetupVariable.h>
+#include <Guid/Vlv2Variable.h>
+
+#include "Valleyview.h"
+#include "VlvAccess.h"
+#include "PchAccess.h"
+#include "SetupMode.h"
+#include "PchCommonDefinitions.h"
+#include <PlatformBaseAddresses.h>
+
+typedef struct {
+  UINT8 RevId;
+  CHAR8 String[16];
+} SB_REV;
+
+//
+// Silicon Steppings
+//
+SB_REV  SBRevisionTable[] = {
+  {V_PCH_LPC_RID_0, "(A0 Stepping)"},
+  {V_PCH_LPC_RID_1, "(A0 Stepping)"},
+  {V_PCH_LPC_RID_2, "(A1 Stepping)"},
+  {V_PCH_LPC_RID_3, "(A1 Stepping)"},
+  {V_PCH_LPC_RID_4, "(B0 Stepping)"},
+  {V_PCH_LPC_RID_5, "(B0 Stepping)"},
+  {V_PCH_LPC_RID_6, "(B1 Stepping)"},
+  {V_PCH_LPC_RID_7, "(B1 Stepping)"},
+  {V_PCH_LPC_RID_8, "(B2 Stepping)"},
+  {V_PCH_LPC_RID_9, "(B2 Stepping)"},
+  {V_PCH_LPC_RID_A, "(B3 Stepping)"},
+  {V_PCH_LPC_RID_B, "(B3 Stepping)"}
+};
+
+#define LEFT_JUSTIFY  0x01
+#define PREFIX_SIGN   0x02
+#define PREFIX_BLANK  0x04
+#define COMMA_TYPE    0x08
+#define LONG_TYPE     0x10
+#define PREFIX_ZERO   0x20
+
+#define ICH_REG_REV                 0x08
+#define MSR_IA32_PLATFORM_ID        0x17
+#define CHARACTER_NUMBER_FOR_VALUE  30
+
+
+UINT8  ReadBuffer[20];  //Version report length
+UINT8  WriteBuffer[22] = {0x40,0x01,0x14,0x00,0x06,0x51,0x02,0x07,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //Version request
+
+/**
+
+  VSPrint worker function that prints a Value as a decimal number in Buffer
+
+  @param Buffer  Location to place ascii decimal number string of Value.
+  @param Value   Decimal value to convert to a string in Buffer.
+  @param Flags   Flags to use in printing decimal string, see file header for details.
+  @param Width   Width of hex value.
+
+  @retval Number of characters printed.
+
+**/
+UINTN
+EfiValueToString (
+  IN  OUT CHAR16  *Buffer,
+  IN  INT64       Value,
+  IN  UINTN       Flags,
+  IN  UINTN       Width
+  )
+{
+  CHAR16    TempBuffer[CHARACTER_NUMBER_FOR_VALUE];
+  CHAR16    *TempStr;
+  CHAR16    *BufferPtr;
+  UINTN     Count;
+  UINTN     ValueCharNum;
+  UINTN     Remainder;
+  CHAR16    Prefix;
+  UINTN     Index;
+  BOOLEAN   ValueIsNegative;
+  UINT64    TempValue;
+
+  TempStr         = TempBuffer;
+  BufferPtr       = Buffer;
+  Count           = 0;
+  ValueCharNum    = 0;
+  ValueIsNegative = FALSE;
+
+  if (Width > CHARACTER_NUMBER_FOR_VALUE - 1) {
+    Width = CHARACTER_NUMBER_FOR_VALUE - 1;
+  }
+
+  if (Value < 0) {
+    Value           = -Value;
+    ValueIsNegative = TRUE;
+  }
+
+  do {
+    TempValue = Value;
+    Value = (INT64)DivU64x32 ((UINT64)Value, 10);
+    Remainder = (UINTN)((UINT64)TempValue - 10 * Value);
+    *(TempStr++) = (CHAR16)(Remainder + '0');
+    ValueCharNum++;
+    Count++;
+    if ((Flags & COMMA_TYPE) == COMMA_TYPE) {
+      if (ValueCharNum % 3 == 0 && Value != 0) {
+        *(TempStr++) = ',';
+        Count++;
+      }
+    }
+  } while (Value != 0);
+
+  if (ValueIsNegative) {
+    *(TempStr++)    = '-';
+    Count++;
+  }
+
+  if ((Flags & PREFIX_ZERO) && !ValueIsNegative) {
+    Prefix = '0';
+  } else {
+    Prefix = ' ';
+  }
+
+  Index = Count;
+  if (!(Flags & LEFT_JUSTIFY)) {
+    for (; Index < Width; Index++) {
+      *(TempStr++) = Prefix;
+    }
+  }
+
+  //
+  // Reverse temp string into Buffer.
+  //
+  if (Width > 0 && (UINTN) (TempStr - TempBuffer) > Width) {
+    TempStr = TempBuffer + Width;
+  }
+  Index = 0;
+  while (TempStr != TempBuffer) {
+    *(BufferPtr++) = *(--TempStr);
+    Index++;
+  }
+
+  *BufferPtr = 0;
+  return Index;
+}
+
+static CHAR16 mHexStr[] = { L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7',
+                            L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F' };
+/**
+  VSPrint worker function that prints a Value as a hex number in Buffer
+
+  @param Buffer   Location to place ascii hex string of Value.
+  @param Value    Hex value to convert to a string in Buffer.
+  @param Flags    Flags to use in printing Hex string, see file header for details.
+  @param Width    Width of hex value.
+
+  @retval Number of characters printed.
+
+**/
+UINTN
+EfiValueToHexStr (
+  IN  OUT CHAR16  *Buffer,
+  IN  UINT64      Value,
+  IN  UINTN       Flags,
+  IN  UINTN       Width
+  )
+{
+  CHAR16  TempBuffer[CHARACTER_NUMBER_FOR_VALUE];
+  CHAR16  *TempStr;
+  CHAR16  Prefix;
+  CHAR16  *BufferPtr;
+  UINTN   Count;
+  UINTN   Index;
+
+  TempStr   = TempBuffer;
+  BufferPtr = Buffer;
+
+  //
+  // Count starts at one since we will null terminate. Each iteration of the
+  // loop picks off one nibble. Oh yea TempStr ends up backwards
+  //
+  Count = 0;
+
+  if (Width > CHARACTER_NUMBER_FOR_VALUE - 1) {
+    Width = CHARACTER_NUMBER_FOR_VALUE - 1;
+  }
+
+  do {
+    Index = ((UINTN)Value & 0xf);
+    *(TempStr++) = mHexStr[Index];
+    Value = RShiftU64 (Value, 4);
+    Count++;
+  } while (Value != 0);
+
+  if (Flags & PREFIX_ZERO) {
+    Prefix = '0';
+  } else {
+    Prefix = ' ';
+  }
+
+  Index = Count;
+  if (!(Flags & LEFT_JUSTIFY)) {
+    for (; Index < Width; Index++) {
+      *(TempStr++) = Prefix;
+    }
+  }
+
+  //
+  // Reverse temp string into Buffer.
+  //
+  if (Width > 0 && (UINTN) (TempStr - TempBuffer) > Width) {
+    TempStr = TempBuffer + Width;
+  }
+  Index = 0;
+  while (TempStr != TempBuffer) {
+    *(BufferPtr++) = *(--TempStr);
+    Index++;
+  }
+
+  *BufferPtr = 0;
+  return Index;
+}
+
+/**
+  Converts MAC address to Unicode string.
+  The value is 64-bit and the resulting string will be 12
+  digit hex number in pairs of digits separated by dashes.
+
+  @param String - string that will contain the value
+  @param Val    - value to convert
+
+**/
+CHAR16 *
+StrMacToString (
+  OUT CHAR16              *String,
+  IN  EFI_MAC_ADDRESS     *MacAddr,
+  IN  UINT32              AddrSize
+  )
+{
+  UINT32  i;
+
+  for (i = 0; i < AddrSize; i++) {
+
+    EfiValueToHexStr (
+      &String[2 * i],
+      MacAddr->Addr[i] & 0xFF,
+      PREFIX_ZERO,
+      2
+      );
+  }
+
+  //
+  // Terminate the string.
+  //
+  String[2 * AddrSize] = L'\0';
+
+  return String;
+}
+
+
+
+EFI_STATUS
+TJudgeHandleIsPCIDevice(
+  EFI_HANDLE    Handle,
+  UINT8            Device,
+  UINT8            Funs
+)
+{
+  EFI_STATUS  Status;
+  EFI_DEVICE_PATH   *DPath;
+  EFI_DEVICE_PATH   *DevicePath;
+
+  Status = gBS->HandleProtocol (
+                  Handle,
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID **) &DPath
+                  );
+  if(!EFI_ERROR(Status))
+  {
+    DevicePath = DPath;
+    while(!IsDevicePathEnd(DPath))
+    {
+      if((DPath->Type == HARDWARE_DEVICE_PATH) && (DPath->SubType == HW_PCI_DP))
+      {
+        PCI_DEVICE_PATH   *PCIPath;
+
+        PCIPath = (PCI_DEVICE_PATH*) DPath;
+        DPath = NextDevicePathNode(DPath);
+        if(IsDevicePathEnd(DPath) && (PCIPath->Device == Device) && (PCIPath->Function == Funs))
+        {
+          return EFI_SUCCESS;
+        }
+      }
+      else
+      {
+        DPath = NextDevicePathNode(DPath);
+      }
+    }
+  }
+  return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+TSearchChildHandle(
+  EFI_HANDLE Father,
+  EFI_HANDLE *Child
+  )
+{
+  EFI_STATUS                                                 Status;
+  UINTN                                                          HandleIndex;
+  EFI_GUID                                                     **ProtocolGuidArray = NULL;
+  UINTN                                                          ArrayCount;
+  UINTN                                                          ProtocolIndex;
+  UINTN                                                          OpenInfoCount;
+  UINTN                                                          OpenInfoIndex;
+  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY  *OpenInfo = NULL;
+  UINTN                                                          mHandleCount;
+  EFI_HANDLE                                                 *mHandleBuffer= NULL;
+
+  //
+  // Retrieve the list of all handles from the handle database
+  //
+  Status = gBS->LocateHandleBuffer (
+                  AllHandles,
+                  NULL,
+                  NULL,
+                  &mHandleCount,
+                  &mHandleBuffer
+                  );
+
+  for (HandleIndex = 0; HandleIndex < mHandleCount; HandleIndex++)
+  {
+    //
+    // Retrieve the list of all the protocols on each handle
+    //
+    Status = gBS->ProtocolsPerHandle (
+                    mHandleBuffer[HandleIndex],
+                    &ProtocolGuidArray,
+                    &ArrayCount
+                    );
+    if (!EFI_ERROR (Status))
+    {
+      for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++)
+      {
+        Status = gBS->OpenProtocolInformation (
+                        mHandleBuffer[HandleIndex],
+                        ProtocolGuidArray[ProtocolIndex],
+                        &OpenInfo,
+                        &OpenInfoCount
+                        );
+        if (!EFI_ERROR (Status))
+        {
+          for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++)
+          {
+            if(OpenInfo[OpenInfoIndex].AgentHandle == Father)
+            {
+              if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER)
+              {
+                *Child = mHandleBuffer[HandleIndex];
+		  Status = EFI_SUCCESS;
+		  goto TryReturn;
+              }
+            }
+          }
+	   Status = EFI_NOT_FOUND;
+        }
+      }
+      if(OpenInfo != NULL)
+      {
+        FreePool(OpenInfo);
+	 OpenInfo = NULL;
+      }
+    }
+    FreePool (ProtocolGuidArray);
+    ProtocolGuidArray = NULL;
+  }
+TryReturn:
+  if(OpenInfo != NULL)
+  {
+    FreePool (OpenInfo);
+    OpenInfo = NULL;
+  }
+  if(ProtocolGuidArray != NULL)
+  {
+    FreePool(ProtocolGuidArray);
+    ProtocolGuidArray = NULL;
+  }
+  if(mHandleBuffer != NULL)
+  {
+    FreePool (mHandleBuffer);
+    mHandleBuffer = NULL;
+  }
+  return Status;
+}
+
+EFI_STATUS
+TGetDriverName(
+  EFI_HANDLE   Handle,
+  CHAR16         *Name
+)
+{
+  EFI_DRIVER_BINDING_PROTOCOL        *BindHandle = NULL;
+  EFI_STATUS                                        Status;
+  UINT32                                               Version;
+  UINT16                                               *Ptr;
+  Status = gBS->OpenProtocol(
+                  Handle,
+                  &gEfiDriverBindingProtocolGuid,
+                                   (VOID**)&BindHandle,
+                  NULL,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+
+  if (EFI_ERROR(Status))
+  {
+    return EFI_NOT_FOUND;
+  }
+
+  Version = BindHandle->Version;
+  Ptr = (UINT16*)&Version;
+  UnicodeSPrint(Name, 40, L"%d.%d.%d", Version >> 24 , (Version >>16)& 0x0f ,*(Ptr));
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+TGetGOPDriverName(
+  CHAR16 *Name
+)
+{
+  UINTN                         HandleCount;
+  EFI_HANDLE                *Handles= NULL;
+  UINTN                         Index;
+  EFI_STATUS                Status;
+  EFI_HANDLE                Child = 0;
+
+  Status = gBS->LocateHandleBuffer(
+		              ByProtocol,
+		              &gEfiDriverBindingProtocolGuid,
+		              NULL,
+		              &HandleCount,
+		              &Handles
+                  );
+  for (Index = 0; Index < HandleCount ; Index++)
+  {
+    Status = TSearchChildHandle(Handles[Index], &Child);
+    if(!EFI_ERROR(Status))
+    {
+      Status = TJudgeHandleIsPCIDevice(Child, 0x02, 0x00);
+      if(!EFI_ERROR(Status))
+      {
+        return TGetDriverName(Handles[Index], Name);
+      }
+    }
+  }
+  return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+TGetTouchFirmwareVersion(
+ )
+{
+ EFI_STATUS rc=EFI_SUCCESS;
+ UINTN      TouchVer = 0;
+ UINTN     Size = sizeof(UINTN);
+
+
+ CHAR16     Buffer[40];
+
+ rc = gRT->GetVariable(
+             L"TouchVer",
+             &gEfiVlv2VariableGuid,
+             NULL,
+             &Size,
+             &TouchVer
+             );
+ if(!EFI_ERROR(rc)){
+  UnicodeSPrint(Buffer, sizeof(Buffer), L"%02x.%02x", (TouchVer&0xFFFF)>>8,TouchVer&0xFF);
+  HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_TOUCH_VERSION), Buffer, NULL);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+UpdatePlatformInformation (
+  )
+{
+  UINT32                   MicroCodeVersion;
+  CHAR16                   Buffer[40];
+  UINT8                    IgdVBIOSRevH;
+  UINT8                    IgdVBIOSRevL;
+  UINT16                   EDX;
+  EFI_IA32_REGISTER_SET    RegSet;
+  EFI_LEGACY_BIOS_PROTOCOL *LegacyBios = NULL;
+  EFI_STATUS               Status;
+  UINT8                    CpuFlavor=0;
+  EFI_PEI_HOB_POINTERS     GuidHob;
+  EFI_PLATFORM_INFO_HOB    *mPlatformInfo=NULL;
+  UINTN                    NumHandles;
+  EFI_HANDLE                        *HandleBuffer;
+  UINTN                             Index;
+  DXE_PCH_PLATFORM_POLICY_PROTOCOL  *PchPlatformPolicy;
+  UINTN                             PciD31F0RegBase;
+  UINT8                             count;
+  UINT8                             Data8;
+  UINT8                             Data8_1;
+
+  CHAR16                            Name[40];
+  UINT32                            MrcVersion;
+
+  UINT8					KscFwRevH =0;
+  UINT8					KscFwRevL =0;
+
+  //
+  // 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);
+    }
+  }
+
+  //
+  //VBIOS version
+  //
+  Status = gBS->LocateProtocol(
+                  &gEfiLegacyBiosProtocolGuid,
+                  NULL,
+                  (VOID **)&LegacyBios
+                  );
+
+  RegSet.X.AX = 0x5f01;
+  Status = LegacyBios->Int86 (LegacyBios, 0x10, &RegSet);
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  // simulate AMI int15 (ax=5f01) handler
+  // check NbInt15.asm in AMI code for asm edition
+  //
+  EDX = (UINT16)((RegSet.E.EBX >> 16) & 0xffff);
+  IgdVBIOSRevH = (UINT8)(((EDX & 0x0F00) >> 4) | (EDX & 0x000F));
+  IgdVBIOSRevL = (UINT8)(((RegSet.X.BX & 0x0F00) >> 4) | (RegSet.X.BX & 0x000F));
+
+  if (IgdVBIOSRevH==0 && IgdVBIOSRevL==0) {
+    HiiSetString(mHiiHandle, STRING_TOKEN(STR_CHIP_IGD_VBIOS_REV_VALUE), L"N/A", NULL);
+  } else {
+    UnicodeSPrint (Buffer, sizeof (Buffer), L"%02X%02X", IgdVBIOSRevH,IgdVBIOSRevL);
+    HiiSetString(mHiiHandle, STRING_TOKEN(STR_CHIP_IGD_VBIOS_REV_VALUE), Buffer, NULL);
+  }
+
+  Status = TGetGOPDriverName(Name);
+
+  if(!EFI_ERROR(Status))
+  {
+    HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_GOP_VERSION), Name, NULL);
+  }
+
+  //
+  //CpuFlavor
+  //
+  //VLV
+  //VLV-DC Tablet        000
+  //VLV-QC Notebook      001
+  //VLV-QC Desktop       010
+  //
+  //CPU flavor
+  //
+  CpuFlavor = RShiftU64 (EfiReadMsr (MSR_IA32_PLATFORM_ID), 50) & 0x07;
+
+  switch(CpuFlavor){
+    case 0x0:
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-DC Tablet", CpuFlavor);
+        break;
+    case 0x01:
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC Notebook", CpuFlavor);
+        break;
+    case 0x02:
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC Desktop", CpuFlavor);
+        break;
+    case 0x03:
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC Notebook", CpuFlavor);
+        break;
+    default:
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"Unknown CPU", CpuFlavor);
+        break;
+  }
+  HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_CPU_FLAVOR_VALUE), Buffer, NULL);
+
+  if ( NULL != mPlatformInfo) {
+    //
+    // Board Id
+    //
+    UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", mPlatformInfo->BoardId);
+    HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_BOARD_ID_VALUE), Buffer, NULL);
+
+    //
+    // FAB ID
+    //
+    UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", mPlatformInfo->BoardRev);
+    HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_FAB_ID_VALUE), Buffer, NULL);
+  }
+
+  //
+  //Update MRC Version
+  //
+  MrcVersion = MmioRead32 (MmPciAddress (0, 0, 0, 0, 0xF0));
+  MrcVersion &= 0xffff;
+  Index = EfiValueToString (Buffer, MrcVersion/100, PREFIX_ZERO, 0);
+  StrCat (Buffer, L".");
+  EfiValueToString (Buffer + Index + 1, (MrcVersion%100)/10, PREFIX_ZERO, 0);
+  EfiValueToString (Buffer + Index + 2, (MrcVersion%100)%10, PREFIX_ZERO, 0);
+  HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_MRC_VERSION_VALUE), Buffer, NULL);
+
+  //
+  //Update Soc Version
+  //
+
+  //
+  // Retrieve all instances of PCH Platform Policy protocol
+  //
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gDxePchPlatformPolicyProtocolGuid,
+                  NULL,
+                  &NumHandles,
+                  &HandleBuffer
+                  );
+  if (!EFI_ERROR (Status)) {
+    //
+    // Find the matching PCH Policy protocol
+    //
+    for (Index = 0; Index < NumHandles; Index++) {
+      Status = gBS->HandleProtocol (
+                      HandleBuffer[Index],
+                      &gDxePchPlatformPolicyProtocolGuid,
+                      (VOID **) &PchPlatformPolicy
+                      );
+      if (!EFI_ERROR (Status)) {
+        PciD31F0RegBase = MmPciAddress (
+                            0,
+                            PchPlatformPolicy->BusNumber,
+                            PCI_DEVICE_NUMBER_PCH_LPC,
+                            PCI_FUNCTION_NUMBER_PCH_LPC,
+                            0
+                            );
+
+         Data8 = MmioRead8 (PciD31F0RegBase + R_PCH_LPC_RID_CC);
+         count = ARRAY_SIZE (SBRevisionTable);
+         for (Index = 0; Index < count; Index++) {
+           if(Data8 == SBRevisionTable[Index].RevId) {
+              UnicodeSPrint (Buffer, sizeof (Buffer), L"%02x %a", Data8, SBRevisionTable[Index].String);
+              HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SOC_VALUE), Buffer, NULL);
+             break;
+           }
+         }
+        break;
+      }
+    }
+  }
+
+  //
+  // Microcode Revision
+  //
+  EfiWriteMsr (EFI_MSR_IA32_BIOS_SIGN_ID, 0);
+  EfiCpuid (EFI_CPUID_VERSION_INFO, NULL);
+  MicroCodeVersion = (UINT32) RShiftU64 (EfiReadMsr (EFI_MSR_IA32_BIOS_SIGN_ID), 32);
+  UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", MicroCodeVersion);
+  HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_PROCESSOR_MICROCODE_VALUE), Buffer, NULL);
+
+
+  //
+  //Secure boot
+  //
+  Data8 = SystemConfiguration.SecureBoot;
+  UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8);
+  HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_SECURE_BOOT), Buffer, NULL);
+
+  //
+  //Bootmode
+  //
+  BootMode = GetBootModeHob();
+  UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", BootMode);
+  HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_BOOT_MODE), Buffer, NULL);
+
+  //
+  //SpeedStep
+  //
+  Data8 = 1;
+  UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8);
+  HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_SPEED_STEP), Buffer, NULL);
+
+  //
+  //CPU Turbo
+  //
+  Data8 = 2;
+  UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8);
+  HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_CPU_TURBO), Buffer, NULL);
+
+  //
+  //CState
+  //
+  Data8 = 3;
+  UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8);
+  HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_CSTATE), Buffer, NULL);
+
+  //
+  //GFX Turbo
+  //
+  Data8 = SystemConfiguration.IgdTurboEnabled;
+  UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8);
+  HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_GFX_TURBO), Buffer, NULL);
+
+  Data8 = 0;
+  UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8);
+  HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_S0IX_VALUE), Buffer, NULL);
+
+  //
+  //RC6
+  //
+  Data8 = 0; 
+  UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8);
+  HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_RC6_VALUE), Buffer, NULL);
+
+  //
+  // Punit Version
+  //
+  Data8 = 0;
+  UnicodeSPrint (Buffer, sizeof (Buffer), L"0x%x", Data8);
+  HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_PUNIT_FW_VALUE), Buffer, NULL);
+
+  //
+  //  PMC Version
+  //
+  Data8 = (UINT8)((MmioRead32 (PMC_BASE_ADDRESS + R_PCH_PMC_PRSTS)>>16)&0x00FF);
+  Data8_1 = (UINT8)((MmioRead32 (PMC_BASE_ADDRESS + R_PCH_PMC_PRSTS)>>24)&0x00FF);
+  UnicodeSPrint (Buffer, sizeof (Buffer), L"0x%X_%X", Data8_1, Data8);
+  HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_PMC_FW_VALUE), Buffer, NULL);
+
+  //
+  //PMIC Version
+  //
+  Status = ByteReadI2C(PMICI2cBus, PMICI2cAdd, PMICVendorOffset, 1, &Data8);
+  if(!EFI_ERROR(Status)){
+  	Status = ByteReadI2C(PMICI2cBus, PMICI2cAdd, PMICRevOffset, 1, &Data8_1);
+	if(!EFI_ERROR(Status)){
+      UnicodeSPrint(Buffer, sizeof(Buffer), L"%02x.%02x", Data8, Data8_1);
+      HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_PMIC_VERSION), Buffer, NULL);
+	}
+  }
+
+  TGetTouchFirmwareVersion();
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Smbios OEM type 0x94 callback.
+
+  @param Event    Event whose notification function is being invoked.
+  @param Context  Pointer to the notification functions context, which is implementation dependent.
+
+  @retval None
+
+**/
+VOID
+AddSmbiosT0x94Callback (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  EFI_STATUS            Status;
+  UINTN                 SECVerStrLen = 0;
+  UINTN                 uCodeVerStrLen = 0;
+  UINTN                 GOPStrLen = 0;
+  UINTN                 MRCVersionStrLen = 0;
+  UINTN                 PMCVersionStrLen = 0;
+  UINTN                 ULPMCVersionStrLen = 0;
+  UINTN                 PUNITVersionStrLen = 0;
+  UINTN                 SOCVersionStrLen = 0;
+  UINTN                 BOARDVersionStrLen = 0;
+  UINTN                 FABVersionStrLen = 0;
+  UINTN                 CPUFLAVORStrLen = 0;
+  UINTN                 BIOSVersionStrLen = 0;
+  UINTN                 PMICVersionStrLen = 0;
+  UINTN                 TOUCHVersionStrLen = 0;
+  UINTN                 SecureBootModeLen = 0;
+  UINTN                 BootModeLen = 0;
+  UINTN                 SpeedStepModeLen = 0;
+  UINTN                 MaxCStateLen = 0;
+  UINTN                 CpuTurboLen = 0;
+  UINTN                 GfxTurboLen = 0;
+  UINTN                 IdleReserveLen = 0;
+  UINTN                 RC6Len = 0;
+
+  SMBIOS_TABLE_TYPE94    *SmbiosRecord;
+  EFI_SMBIOS_HANDLE     SmbiosHandle;
+  EFI_MISC_OEM_TYPE_0x94  *ForType94InputData;
+  CHAR16                *SECVer;
+  CHAR16                *uCodeVer;
+  CHAR16                *GOPVer;
+  CHAR16                *MrcVer;
+  CHAR16                *PmcVer;
+  CHAR16                *UlpmcVer;
+  CHAR16                *PunitVer;
+  CHAR16                *SocVer;
+  CHAR16                *BoardVer;
+  CHAR16                *FabVer;
+  CHAR16                *CpuFlavor;
+  CHAR16                *BiosVer;
+  CHAR16                *PmicVer;
+  CHAR16                *TouchVer = L"15.16";
+  CHAR16                *SecureBootMode;
+  CHAR16                *BootMode;
+  CHAR16                *SpeedStepMode;
+  CHAR16                *MaxCState;
+  CHAR16                *CpuTurbo;
+  CHAR16                *GfxTurbo;
+  CHAR16                *IdleReserve;
+  CHAR16                *RC6;
+
+  UINTN                 RecordLen = 0;
+  UINTN                 StrIdx = 0;
+
+
+  STRING_REF            TokenToGet;
+  CHAR8                 *OptionalStrStart;
+  EFI_SMBIOS_PROTOCOL               *SmbiosProtocol;
+
+  ForType94InputData        = (EFI_MISC_OEM_TYPE_0x94 *)Context;
+
+  DEBUG ((EFI_D_INFO, "Executing SMBIOS T0x94 callback.\n"));
+
+  gBS->CloseEvent (Event);    // Unload this event.
+
+  //
+  // First check for invalid parameters.
+  //
+  if (Context == NULL) {
+    return;
+  }
+
+  UpdatePlatformInformation();
+
+  Status = gBS->LocateProtocol (
+                  &gEfiSmbiosProtocolGuid,
+                  NULL,
+                  (VOID **) &SmbiosProtocol
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_SEC_VERSION);
+  SECVer = SmbiosMiscGetString (TokenToGet);
+  SECVerStrLen = StrLen(SECVer);
+  if (SECVerStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_UCODE_VERSION);
+  uCodeVer = SmbiosMiscGetString (TokenToGet);
+  uCodeVerStrLen = StrLen(uCodeVer);
+  if (uCodeVerStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_GOP_VERSION);
+  GOPVer = SmbiosMiscGetString (TokenToGet);
+  GOPStrLen = StrLen(GOPVer);
+  if (GOPStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_MRC_VERSION_VALUE);
+  MrcVer = SmbiosMiscGetString (TokenToGet);
+  MRCVersionStrLen = StrLen(MrcVer);
+  if (MRCVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_PMC_FW_VALUE);
+  PmcVer = SmbiosMiscGetString (TokenToGet);
+  PMCVersionStrLen = StrLen(PmcVer);
+  if (PMCVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_ULPMC_FW_VALUE);
+  UlpmcVer = SmbiosMiscGetString (TokenToGet);
+  ULPMCVersionStrLen = StrLen(UlpmcVer);
+  if (ULPMCVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_PUNIT_FW_VALUE);
+  PunitVer = SmbiosMiscGetString (TokenToGet);
+  PUNITVersionStrLen = StrLen(PunitVer);
+  if (PUNITVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_SOC_VALUE);
+  SocVer = SmbiosMiscGetString (TokenToGet);
+  SOCVersionStrLen = StrLen(SocVer);
+  if (SOCVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BOARD_ID_VALUE);
+  BoardVer = SmbiosMiscGetString (TokenToGet);
+  BOARDVersionStrLen = StrLen(BoardVer);
+  if (BOARDVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_FAB_ID_VALUE);
+  FabVer = SmbiosMiscGetString (TokenToGet);
+  FABVersionStrLen = StrLen(FabVer);
+  if (FABVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_CPU_FLAVOR_VALUE);
+  CpuFlavor = SmbiosMiscGetString (TokenToGet);
+  CPUFLAVORStrLen = StrLen(CpuFlavor);
+  if (CPUFLAVORStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VERSION);
+  BiosVer = SmbiosMiscGetString (TokenToGet);
+  BIOSVersionStrLen = StrLen(BiosVer);
+  if (BIOSVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_PMIC_VERSION);
+  PmicVer = SmbiosMiscGetString (TokenToGet);
+  PMICVersionStrLen = StrLen(PmicVer);
+  if (PMICVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_TOUCH_VERSION);
+  TouchVer = SmbiosMiscGetString (TokenToGet);
+  TOUCHVersionStrLen = StrLen(TouchVer);
+  if (TOUCHVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_SECURE_BOOT);
+  SecureBootMode = SmbiosMiscGetString(TokenToGet);
+  SecureBootModeLen = StrLen(SecureBootMode);
+  if (SecureBootModeLen > SMBIOS_STRING_MAX_LENGTH) {
+  	return;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BOOT_MODE);
+  BootMode = SmbiosMiscGetString(TokenToGet);
+  BootModeLen = StrLen(BootMode);
+  if (BootModeLen > SMBIOS_STRING_MAX_LENGTH) {
+  	return;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_SPEED_STEP);
+  SpeedStepMode = SmbiosMiscGetString(TokenToGet);
+  SpeedStepModeLen = StrLen(SpeedStepMode);
+  if (SpeedStepModeLen > SMBIOS_STRING_MAX_LENGTH) {
+  	return;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_CPU_TURBO);
+  CpuTurbo = SmbiosMiscGetString(TokenToGet);
+  CpuTurboLen = StrLen(CpuTurbo);
+  if (CpuTurboLen > SMBIOS_STRING_MAX_LENGTH) {
+  	return;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_CSTATE);
+  MaxCState = SmbiosMiscGetString(TokenToGet);
+  MaxCStateLen = StrLen(MaxCState);
+  if (MaxCStateLen > SMBIOS_STRING_MAX_LENGTH) {
+  	return;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_GFX_TURBO);
+  GfxTurbo = SmbiosMiscGetString(TokenToGet);
+  GfxTurboLen = StrLen(GfxTurbo);
+  if (GfxTurboLen > SMBIOS_STRING_MAX_LENGTH) {
+  	return;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_S0IX_VALUE);
+  IdleReserve = SmbiosMiscGetString(TokenToGet);
+  IdleReserveLen = StrLen(IdleReserve);
+  if (S0ixLen > SMBIOS_STRING_MAX_LENGTH) {
+    return;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_RC6_VALUE);
+  RC6 = SmbiosMiscGetString(TokenToGet);
+  RC6Len = StrLen(RC6);
+  if (RC6Len > SMBIOS_STRING_MAX_LENGTH) {
+    return;
+  }
+
+  RecordLen = sizeof (SMBIOS_TABLE_TYPE94) + SECVerStrLen + 1 + uCodeVerStrLen + 1 + GOPStrLen + 1 + PMCVersionStrLen + 1 + \
+                      TOUCHVersionStrLen + 1 + PMICVersionStrLen + 1 + BIOSVersionStrLen + 1 + CPUFLAVORStrLen + 1 + \
+                      BOARDVersionStrLen + 1 + FABVersionStrLen + 1 + PUNITVersionStrLen+ 1 + ULPMCVersionStrLen + 1 + \
+                      MRCVersionStrLen + 1 + SOCVersionStrLen + 1 + SecureBootModeLen + 1 + BootModeLen + 1 + \
+                      SpeedStepModeLen + 1 + CpuTurboLen + 1 + MaxCStateLen + 1 + GfxTurboLen + 1 + + RC6Len + 1 + 1;
+
+  SmbiosRecord = AllocatePool(RecordLen);
+
+  ZeroMem(SmbiosRecord, RecordLen);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_MISC_VERSION_INFO;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE94);
+
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle = 0;
+
+  SmbiosRecord->GopVersion = 1;
+
+  SmbiosRecord->SECVersion = 2;
+
+  SmbiosRecord->MRCVersion = 3;
+
+  SmbiosRecord->uCodeVersion = 4;
+
+  SmbiosRecord->PUnitVersion = 5;
+
+  SmbiosRecord->PMCVersion = 6;
+
+  SmbiosRecord->ULPMCVersion = 7;
+
+  SmbiosRecord->SoCVersion = 8;
+
+  SmbiosRecord->BoardVersion = 9;
+
+  SmbiosRecord->FabVersion = 10;
+
+  SmbiosRecord->CPUFlavor = 11;
+
+  SmbiosRecord->BiosVersion = 12;
+
+  SmbiosRecord->PmicVersion = 13;
+
+  SmbiosRecord->TouchVersion = 14;
+
+  SmbiosRecord->SecureBoot = 15;
+
+  SmbiosRecord->BootMode = 16;
+
+  SmbiosRecord->SpeedStepMode= 17;
+
+  SmbiosRecord->CPUTurboMode = 18;
+
+  SmbiosRecord->MaxCState = 19;
+
+  SmbiosRecord->GfxTurbo = 20;
+  SmbiosRecord->IdleReserve = 21;
+
+  SmbiosRecord->RC6 = 22;
+
+
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  UnicodeStrToAsciiStr(GOPVer, OptionalStrStart);
+  StrIdx +=  GOPStrLen + 1;
+
+  UnicodeStrToAsciiStr(SECVer, OptionalStrStart + StrIdx);
+  StrIdx +=  SECVerStrLen + 1;
+
+  UnicodeStrToAsciiStr(MrcVer, OptionalStrStart + StrIdx);
+  StrIdx +=  MRCVersionStrLen + 1;
+
+  UnicodeStrToAsciiStr(uCodeVer, OptionalStrStart + StrIdx);
+  StrIdx +=  uCodeVerStrLen + 1;
+
+  UnicodeStrToAsciiStr(PunitVer, OptionalStrStart + StrIdx);
+  StrIdx +=  PUNITVersionStrLen + 1;
+
+  UnicodeStrToAsciiStr(PmcVer, OptionalStrStart + StrIdx);
+  StrIdx +=  PMCVersionStrLen + 1;
+
+  UnicodeStrToAsciiStr(UlpmcVer, OptionalStrStart + StrIdx);
+  StrIdx +=  ULPMCVersionStrLen + 1;
+
+
+  UnicodeStrToAsciiStr(SocVer, OptionalStrStart + StrIdx);
+  StrIdx +=  SOCVersionStrLen +1;
+
+  UnicodeStrToAsciiStr(BoardVer, OptionalStrStart + StrIdx);
+  StrIdx +=  BOARDVersionStrLen + 1;
+
+  UnicodeStrToAsciiStr(FabVer, OptionalStrStart + StrIdx);
+  StrIdx +=  FABVersionStrLen + 1;
+
+  UnicodeStrToAsciiStr(CpuFlavor, OptionalStrStart + StrIdx);
+  StrIdx +=  CPUFLAVORStrLen + 1;
+
+  UnicodeStrToAsciiStr(BiosVer, OptionalStrStart + StrIdx);
+  StrIdx +=  BIOSVersionStrLen + 1;
+
+  UnicodeStrToAsciiStr(PmicVer, OptionalStrStart + StrIdx);
+  StrIdx +=  PMICVersionStrLen + 1;
+
+  UnicodeStrToAsciiStr(TouchVer, OptionalStrStart + StrIdx);
+  StrIdx +=  TOUCHVersionStrLen + 1;
+
+  UnicodeStrToAsciiStr(SecureBootMode, OptionalStrStart + StrIdx);
+  StrIdx +=  SecureBootModeLen + 1;
+
+  UnicodeStrToAsciiStr(BootMode, OptionalStrStart + StrIdx);
+  StrIdx +=  BootModeLen + 1;
+
+  UnicodeStrToAsciiStr(SpeedStepMode, OptionalStrStart + StrIdx);
+  StrIdx +=  SpeedStepModeLen + 1;
+
+  UnicodeStrToAsciiStr(CpuTurbo, OptionalStrStart + StrIdx);
+  StrIdx +=  CpuTurboLen + 1;
+
+  UnicodeStrToAsciiStr(MaxCState, OptionalStrStart + StrIdx);
+  StrIdx +=  MaxCStateLen + 1;
+
+  UnicodeStrToAsciiStr(GfxTurbo, OptionalStrStart + StrIdx);
+  StrIdx +=  GfxTurboLen + 1;
+
+  UnicodeStrToAsciiStr(IdleReserve, OptionalStrStart + StrIdx);
+  StrIdx +=  S0ixLen + 1;
+
+  UnicodeStrToAsciiStr(RC6, OptionalStrStart + StrIdx);
+  StrIdx +=  RC6Len + 1;
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = SmbiosProtocol-> Add (
+                              SmbiosProtocol,
+                              NULL,
+                              &SmbiosHandle,
+                              (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                              );
+
+  FreePool(SmbiosRecord);
+  return;
+}
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscOemType0x94 (Type 0x94).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscOemType0x94)
+{
+  EFI_STATUS                    Status;
+  EFI_EVENT                     AddSmbiosT0x94CallbackEvent;
+
+  Status = EfiCreateEventReadyToBootEx (
+             TPL_CALLBACK,
+             AddSmbiosT0x94Callback,
+             RecordData,
+             &AddSmbiosT0x94CallbackEvent
+             );
+
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDevice.uni b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDevice.uni
new file mode 100644
index 0000000000..85c60a06fe
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDevice.uni
@@ -0,0 +1,26 @@
+// *++
+//
+// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// 
+// Module Name:
+//
+//   MiscOnboardDevice.uni
+// 
+// Abstract:
+// 
+//   Onboard device information
+// 
+// Revision History:
+// 
+// --*/
+
+
+/=#
+
+#langdef en-US "English"
+
+#string STR_MISC_ONBOARD_DEVICE_VIDEO   #language en-US  "Intel(R) ValleyView2 HD Graphics"
+#string STR_MISC_ONBOARD_DEVICE_AUDIO   #language en-US  "Intel(R) HD Audio Device"
+#string STR_MISC_ONBOARD_DEVICE_NETWORK #language en-US  ""
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceData.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceData.c
new file mode 100644
index 0000000000..f82cfa8985
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceData.c
@@ -0,0 +1,48 @@
+/** @file
+
+Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscOnboardDeviceData.c
+
+Abstract:
+
+  Static data of Onboard device information .
+  The onboard device information is Misc. subclass type 8 and SMBIOS type 10.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_ONBOARD_DEVICE_DATA, MiscOnboardDeviceVideo) = {
+  STRING_TOKEN(STR_MISC_ONBOARD_DEVICE_VIDEO),  // OnBoardDeviceDescription
+  {                             // OnBoardDeviceStatus
+    EfiOnBoardDeviceTypeVideo,  // DeviceType
+    1,                          // DeviceEnabled
+    0                           // Reserved
+  },
+  0                             // OnBoardDevicePath
+};
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_ONBOARD_DEVICE_DATA, MiscOnboardDeviceAudio) = {
+  STRING_TOKEN(STR_MISC_ONBOARD_DEVICE_AUDIO),    // OnBoardDeviceDescription
+  {                                 // OnBoardDeviceStatus
+    EfiOnBoardDeviceTypeSound,      // DeviceType
+    1,                              // DeviceEnabled
+    0                               // Reserved
+  },
+  0                                 // OnBoardDevicePath
+};
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceFunction.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceFunction.c
new file mode 100644
index 0000000000..aef25065b8
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceFunction.c
@@ -0,0 +1,135 @@
+/** @file
+
+Copyright (c) 1999  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscOnboardDeviceFunction.c
+
+Abstract:
+
+  Create the device path for the Onboard device.
+  The Onboard device information is Misc. subclass type 8 and SMBIOS type 10.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+
+
+/**
+  This is a macro defined function, in fact, the function is
+  MiscOnboardDeviceFunction (RecordType, RecordLen, RecordData, LogRecordData)
+  This function makes boot time changes to the contents of the
+  MiscOnboardDevice structure.
+
+  @param  MiscOnboardDevice      The string which is used to create the function
+  The Arguments in fact:
+  @param  RecordType             Type of record to be processed from the Data
+                                 Table. mMiscSubclassDataTable[].RecordType
+  @param  RecordLen              Size of static RecordData from the Data Table.
+                                 mMiscSubclassDataTable[].RecordLen
+  @param  RecordData             Pointer to RecordData, which will be written to
+                                 the Data Hub
+  @param  LogRecordData          TRUE to log RecordData to Data Hub. FALSE when
+                                 there is no more data to log.
+
+  @retval EFI_SUCCESS            *RecordData and *LogRecordData have been set.
+  @retval EFI_UNSUPPORTED        Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER  One of the following parameter conditions was
+                                 true: RecordLen was zero. RecordData was NULL.
+                                 LogRecordData was NULL.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION (
+  MiscOnboardDevice
+  )
+{
+  CHAR8                         *OptionalStrStart;
+  UINT8                         StatusAndType;
+  UINTN                         DescriptionStrLen;
+  EFI_STRING                    DeviceDescription;
+  STRING_REF                    TokenToGet;
+  EFI_STATUS                    Status;
+  EFI_SMBIOS_HANDLE             SmbiosHandle;
+  SMBIOS_TABLE_TYPE10           *SmbiosRecord;
+  EFI_MISC_ONBOARD_DEVICE       *ForType10InputData;
+
+  ForType10InputData = (EFI_MISC_ONBOARD_DEVICE *)RecordData;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  TokenToGet = 0;
+  switch (ForType10InputData->OnBoardDeviceDescription) {
+    case STR_MISC_ONBOARD_DEVICE_VIDEO:
+      TokenToGet = STRING_TOKEN (STR_MISC_ONBOARD_DEVICE_VIDEO);
+      break;
+    case STR_MISC_ONBOARD_DEVICE_AUDIO:
+      TokenToGet = STRING_TOKEN (STR_MISC_ONBOARD_DEVICE_AUDIO);
+      break;
+	default:
+	break;
+  }
+
+  DeviceDescription = SmbiosMiscGetString (TokenToGet);
+  DescriptionStrLen = StrLen(DeviceDescription);
+  if (DescriptionStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE10) + DescriptionStrLen + 1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE10) + DescriptionStrLen + 1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_ONBOARD_DEVICE_INFORMATION;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE10);
+
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle = 0;
+
+  //
+  // Status & Type: Bit 7 Devicen Status, Bits 6:0 Type of Device
+  //
+  StatusAndType = (UINT8) ForType10InputData->OnBoardDeviceStatus.DeviceType;
+  if (ForType10InputData->OnBoardDeviceStatus.DeviceEnabled != 0) {
+    StatusAndType |= 0x80;
+  } else {
+    StatusAndType &= 0x7F;
+  }
+
+  SmbiosRecord->Device[0].DeviceType = StatusAndType;
+  SmbiosRecord->Device[0].DescriptionString = 1;
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  UnicodeStrToAsciiStr(DeviceDescription, OptionalStrStart);
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+  FreePool(SmbiosRecord);
+  return Status;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArray.uni b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArray.uni
new file mode 100644
index 0000000000..bed00e0de5
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArray.uni
@@ -0,0 +1,25 @@
+// *++
+//
+// Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// 
+// Module Name:
+//
+//   MiscPhysicalArray.uni
+// 
+// Abstract:
+// 
+//   BIOS Physical Memory 
+//   SMBIOS type 16.
+// 
+// Revision History:
+// 
+// --*/
+
+
+/=#
+#langdef   en-US "English"
+        
+              
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayData.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayData.c
new file mode 100644
index 0000000000..66370f7eea
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayData.c
@@ -0,0 +1,38 @@
+/*++
+
+Copyright (c) 2006  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscPhysicalArrayData.c
+
+Abstract:
+
+  BIOS Physical Array static data.
+  SMBIOS type 16.
+
+--*/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+
+
+//
+// Static (possibly build generated) Physical Memory Array Dat.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MEMORY_ARRAY_LOCATION_DATA, MiscPhysicalMemoryArray) =
+{
+	EfiMemoryArrayLocationSystemBoard,						// Memory location
+	EfiMemoryArrayUseSystemMemory, 						    // Memory array use
+	EfiMemoryErrorCorrectionNone, 						    // Memory error correction
+	0,                                                      // Maximum Memory Capacity
+	0x01						                            // Number of Devices
+};
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayFunction.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayFunction.c
new file mode 100644
index 0000000000..67fc04152c
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayFunction.c
@@ -0,0 +1,101 @@
+/*++
+
+Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscPhysicalArrayFunction.c
+
+Abstract:
+
+  BIOS system Physical Array boot time changes.
+  SMBIOS type 16.
+
+--*/
+
+
+#include "CommonHeader.h"
+#include "MiscSubclassDriver.h"
+
+
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscPhysicalArrayFunction (Type 16).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+
+MISC_SMBIOS_TABLE_FUNCTION(MiscPhysicalMemoryArray)
+{
+    EFI_STATUS                      Status;
+    EFI_SMBIOS_HANDLE               SmbiosHandle;
+    SMBIOS_TABLE_TYPE16             *SmbiosRecord;
+    EFI_MEMORY_ARRAY_LOCATION_DATA  *ForType16InputData;
+    UINT32                           TopOfMemory = 8 * 1024 * 1024;
+
+    //
+    // First check for invalid parameters.
+    //
+    if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+    }
+
+    ForType16InputData = (EFI_MEMORY_ARRAY_LOCATION_DATA *)RecordData;
+
+    //
+    // Two zeros following the last string.
+    //
+    SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE16)  + 1);
+    ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE16)  + 1);
+
+    SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY;
+    SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE16);
+
+    //
+    // Make handle chosen by smbios protocol.add automatically.
+    //
+    SmbiosRecord->Hdr.Handle = 0;
+
+    //
+    // ReleaseDate will be the 3rd optional string following the formatted structure.
+    //
+    SmbiosRecord->Location = *(UINT8 *) &ForType16InputData ->MemoryArrayLocation;
+    SmbiosRecord->Use = *(UINT8 *) &ForType16InputData ->MemoryArrayUse;
+    SmbiosRecord->MemoryErrorCorrection = *(UINT8 *) &ForType16InputData->MemoryErrorCorrection;
+
+    //
+    // System does not provide the error information structure
+    //
+    SmbiosRecord->MemoryErrorInformationHandle = 0xFFFE;
+
+    //
+    // Maximum memory capacity
+    //
+    SmbiosRecord-> MaximumCapacity = TopOfMemory;
+    SmbiosRecord-> NumberOfMemoryDevices= 0x02;
+
+    //
+    // Now we have got the full smbios record, call smbios protocol to add this record.
+    //
+    SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+    Status = Smbios-> Add(
+                        Smbios,
+                        NULL,
+                       &SmbiosHandle,
+                       (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                       );
+    FreePool(SmbiosRecord);
+    return Status;
+
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnectorDesignator.uni b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnectorDesignator.uni
new file mode 100644
index 0000000000..80fa99ecbe
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnectorDesignator.uni
@@ -0,0 +1,31 @@
+// *++
+//
+// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// 
+// Module Name:
+//
+//   MiscPortInternalConnectorDesignator.uni
+// 
+// Abstract:
+// 
+//   Port internal connector information
+// 
+// Revision History:
+// 
+// --*/
+
+
+/=#
+
+#langdef en-US "English"
+
+#string STR_MISC_PORT_INTERNAL_IDE1      #language en-US  "J4J1"
+#string STR_MISC_PORT_EXTERNAL_IDE1      #language en-US  "SATA_CON1"
+#string STR_MISC_PORT_INTERNAL_IDE2      #language en-US  "J4E3"
+#string STR_MISC_PORT_EXTERNAL_IDE2      #language en-US  "SATA_CON2"
+#string STR_MISC_PORT_INTERNAL_ATX_POWER #language en-US  "J3J1"
+#string STR_MISC_PORT_EXTERNAL_ATX_POWER #language en-US  "ATX_PWR"
+#string STR_MISC_PORT_INTERNAL_BTX_POWER #language en-US  "BTX_PWR"
+#string STR_MISC_PORT_EXTERNAL_BTX_POWER #language en-US  ""
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnectorDesignatorData.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnectorDesignatorData.c
new file mode 100644
index 0000000000..b98bab40ab
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnectorDesignatorData.c
@@ -0,0 +1,56 @@
+/** @file
+
+Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscPortInternalConnectorDesignatorData.c
+
+Abstract:
+
+  Static data of Port internal connector designator information.
+  Port internal connector designator information is Misc. subclass type 6 and
+  SMBIOS type 8.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+//
+// Static (possibly build generated) Port connector designations
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortIde1) = {
+  STRING_TOKEN(STR_MISC_PORT_INTERNAL_IDE1),
+  STRING_TOKEN(STR_MISC_PORT_EXTERNAL_IDE1),
+  EfiPortConnectorTypeOnboardIde,
+  EfiPortConnectorTypeNone,
+  EfiPortTypeOther,
+  0
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortIde2) = {
+  STRING_TOKEN(STR_MISC_PORT_INTERNAL_IDE2),
+  STRING_TOKEN(STR_MISC_PORT_EXTERNAL_IDE2),
+  EfiPortConnectorTypeOnboardIde,
+  EfiPortConnectorTypeNone,
+  EfiPortTypeOther,
+  0
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortAtxPower) = {
+  STRING_TOKEN(STR_MISC_PORT_INTERNAL_ATX_POWER),
+  STRING_TOKEN(STR_MISC_PORT_EXTERNAL_ATX_POWER),
+  EfiPortConnectorTypeOther,
+  EfiPortConnectorTypeNone,
+  EfiPortTypeOther,
+  0
+};
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnectorDesignatorFunction.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnectorDesignatorFunction.c
new file mode 100644
index 0000000000..6bc088cd13
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnectorDesignatorFunction.c
@@ -0,0 +1,152 @@
+/** @file
+
+Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscPortInternalConnectorDesignatorFunction.c
+
+Abstract:
+
+  Create the device path for the Port internal connector designator.
+  Port internal connector designator information is Misc. subclass type 6
+  and SMBIOS type 8.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+
+/**
+  This is a macro defined function, in fact, the function is
+  MiscPortInternalConnectorDesignatorFunction (RecordType, RecordLen, RecordData, LogRecordData)
+  This function makes boot time changes to the contents of the
+  MiscPortConnectorInformation.
+
+  @param  MiscPortInternalConnectorDesignator  The string which is used to create
+                                               the function
+  The Arguments in fact:
+  @param  RecordType                           Type of record to be processed from
+                                               the Data Table.
+                                               mMiscSubclassDataTable[].RecordType
+  @param  RecordLen                            Size of static RecordData from the
+                                               Data Table.
+                                               mMiscSubclassDataTable[].RecordLen
+  @param  RecordData                           Pointer to RecordData, which will be
+                                               written to the Data Hub
+  @param  LogRecordData                        TRUE to log RecordData to Data Hub.
+                                               FALSE when there is no more data to
+                                               log.
+
+  @retval EFI_SUCCESS                          *RecordData and *LogRecordData have
+                                               been set.
+  @retval EFI_UNSUPPORTED                      Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER                One of the following parameter
+                                               conditions was true: RecordLen was
+                                               zero. RecordData was NULL.
+                                               LogRecordData was NULL.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION (
+  MiscPortInternalConnectorDesignator
+  )
+{
+  CHAR8                                        *OptionalStrStart;
+  UINTN                                        InternalRefStrLen;
+  UINTN                                        ExternalRefStrLen;
+  EFI_STRING                                   InternalRef;
+  EFI_STRING                                   ExternalRef;
+  STRING_REF                                   TokenForInternal;
+  STRING_REF                                   TokenForExternal;
+  EFI_STATUS                                   Status;
+  SMBIOS_TABLE_TYPE8                           *SmbiosRecord;
+  EFI_SMBIOS_HANDLE                            SmbiosHandle;
+  EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR  *ForType8InputData;
+
+  ForType8InputData = (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR *)RecordData;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  TokenForInternal = 0;
+  TokenForExternal = 0;
+
+  switch (ForType8InputData->PortInternalConnectorDesignator) {
+
+    case STR_MISC_PORT_INTERNAL_IDE1:
+      TokenForInternal = STRING_TOKEN (STR_MISC_PORT_INTERNAL_IDE1);
+      TokenForExternal = STRING_TOKEN(STR_MISC_PORT_EXTERNAL_IDE1);
+      break;
+    case STR_MISC_PORT_INTERNAL_IDE2:
+      TokenForInternal = STRING_TOKEN (STR_MISC_PORT_INTERNAL_IDE2);
+      TokenForExternal = STRING_TOKEN(STR_MISC_PORT_EXTERNAL_IDE2);
+      break;
+    case STR_MISC_PORT_INTERNAL_ATX_POWER:
+      TokenForInternal = STRING_TOKEN (STR_MISC_PORT_INTERNAL_ATX_POWER);
+      TokenForExternal = STRING_TOKEN(STR_MISC_PORT_EXTERNAL_ATX_POWER);
+      break;
+    default:
+      break;
+  }
+
+  InternalRef = SmbiosMiscGetString (TokenForInternal);
+  InternalRefStrLen = StrLen(InternalRef);
+  if (InternalRefStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  ExternalRef = SmbiosMiscGetString (TokenForExternal);
+  ExternalRefStrLen = StrLen(ExternalRef);
+  if (ExternalRefStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE8) + InternalRefStrLen + 1 + ExternalRefStrLen + 1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE8) + InternalRefStrLen + 1 + ExternalRefStrLen + 1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE8);
+
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle = 0;
+  SmbiosRecord->InternalReferenceDesignator = 1;
+  SmbiosRecord->InternalConnectorType = (UINT8)ForType8InputData->PortInternalConnectorType;
+  SmbiosRecord->ExternalReferenceDesignator = 2;
+  SmbiosRecord->ExternalConnectorType = (UINT8)ForType8InputData->PortExternalConnectorType;
+  SmbiosRecord->PortType = (UINT8)ForType8InputData->PortType;
+
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  UnicodeStrToAsciiStr(InternalRef, OptionalStrStart);
+  UnicodeStrToAsciiStr(ExternalRef, OptionalStrStart + InternalRefStrLen + 1);
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+  FreePool(SmbiosRecord);
+  return Status;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCache.uni b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCache.uni
new file mode 100644
index 0000000000..fee69bb139
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCache.uni
@@ -0,0 +1,22 @@
+// *++
+//
+// Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// 
+// Module Name:
+//
+//   MiscProcessorCache.uni
+// 
+// Abstract:
+// 
+// 
+// Revision History:
+// 
+// --*/
+
+
+/=#
+#langdef   en-US "English"
+
+#string STR_SOCKET_DESIGNATION                #language en-US  "0x01"
\ No newline at end of file
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheData.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheData.c
new file mode 100644
index 0000000000..6af7f56107
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheData.c
@@ -0,0 +1,33 @@
+/*++
+
+Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscBiosProcessorCache.c
+
+Abstract:
+
+  Processor cache static data.
+  Misc. subclass type 7.
+  SMBIOS type 7.
+
+--*/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+
+//
+// Static (possibly build generated) Processor cache data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_CACHE_VARIABLE_RECORD, MiscProcessorCache) = {
+0
+};
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheFunction.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheFunction.c
new file mode 100644
index 0000000000..ca121525a0
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheFunction.c
@@ -0,0 +1,189 @@
+/*++
+
+Copyright (c) 2006  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscProcessorCacheFunction.c
+
+Abstract:
+
+  BIOS processor cache details.
+  Misc. subclass type 7.
+  SMBIOS type 7.
+
+--*/
+#include "CommonHeader.h"
+#include "MiscSubclassDriver.h"
+#include <Protocol/DataHub.h>
+#include <Guid/DataHubRecords.h>
+
+UINT32
+ConvertBase2ToRaw (
+  IN  EFI_EXP_BASE2_DATA             *Data)
+{
+  UINTN         Index;
+  UINT32        RawData;
+
+  RawData = Data->Value;
+  for (Index = 0; Index < (UINTN) Data->Exponent; Index++) {
+     RawData <<= 1;
+  }
+
+  return  RawData;
+}
+
+
+MISC_SMBIOS_TABLE_FUNCTION(MiscProcessorCache)
+{
+	EFI_SMBIOS_HANDLE     SmbiosHandle;
+	SMBIOS_TABLE_TYPE7            *SmbiosRecordL1;
+	SMBIOS_TABLE_TYPE7            *SmbiosRecordL2;
+
+	EFI_CACHE_SRAM_TYPE_DATA      CacheSramType;
+	CHAR16                          *SocketDesignation;
+	CHAR8                           *OptionalStrStart;
+	UINTN                           SocketStrLen;
+	STRING_REF                      TokenToGet;
+	EFI_DATA_HUB_PROTOCOL           *DataHub;
+	UINT64                          MonotonicCount;
+	EFI_DATA_RECORD_HEADER          *Record;
+	EFI_SUBCLASS_TYPE1_HEADER       *DataHeader;
+	UINT8                           *SrcData;
+	EFI_STATUS                      Status;
+
+	//
+	// Memory Device LOcator
+	//
+	DEBUG ((EFI_D_ERROR, "type 7\n"));
+
+	TokenToGet = STRING_TOKEN (STR_SOCKET_DESIGNATION);
+	SocketDesignation = SmbiosMiscGetString (TokenToGet);
+	SocketStrLen = StrLen(SocketDesignation);
+	if (SocketStrLen > SMBIOS_STRING_MAX_LENGTH) {
+	return EFI_UNSUPPORTED;
+	}
+
+	SmbiosRecordL1 = AllocatePool(sizeof (SMBIOS_TABLE_TYPE7) + 7 + 1 + 1);
+	ASSERT (SmbiosRecordL1 != NULL);
+	ZeroMem(SmbiosRecordL1, sizeof (SMBIOS_TABLE_TYPE7) + 7 + 1 + 1);
+
+	SmbiosRecordL2 = AllocatePool(sizeof (SMBIOS_TABLE_TYPE7) + 7 + 1 + 1);
+	ASSERT (SmbiosRecordL2 != NULL);
+	ZeroMem(SmbiosRecordL2, sizeof (SMBIOS_TABLE_TYPE7) + 7 + 1 + 1);
+
+	//
+	// Get the Data Hub Protocol. Assume only one instance
+	//
+	Status = gBS->LocateProtocol (
+	                &gEfiDataHubProtocolGuid,
+	                NULL,
+	                (VOID **)&DataHub
+	                );
+	ASSERT_EFI_ERROR(Status);
+
+	MonotonicCount = 0;
+	Record = NULL;
+
+	do {
+	Status = DataHub->GetNextRecord (
+	                    DataHub,
+	                    &MonotonicCount,
+	                    NULL,
+	                    &Record
+	                    );
+		if (!EFI_ERROR(Status)) {
+			if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {
+				DataHeader  = (EFI_SUBCLASS_TYPE1_HEADER *)(Record + 1);
+				SrcData     = (UINT8  *)(DataHeader + 1);
+				if (CompareGuid(&Record->DataRecordGuid, &gEfiCacheSubClassGuid) && (DataHeader->RecordType == CacheSizeRecordType)) {
+          			if (DataHeader->SubInstance == EFI_CACHE_L1) {
+						SmbiosRecordL1->InstalledSize += (UINT16) (ConvertBase2ToRaw((EFI_EXP_BASE2_DATA *)SrcData) >> 10);
+						SmbiosRecordL1->MaximumCacheSize = SmbiosRecordL1->InstalledSize;
+          			}
+         			 else if (DataHeader->SubInstance == EFI_CACHE_L2) {
+						SmbiosRecordL2->InstalledSize += (UINT16) (ConvertBase2ToRaw((EFI_EXP_BASE2_DATA *)SrcData) >> 10);
+						SmbiosRecordL2->MaximumCacheSize = SmbiosRecordL2->InstalledSize;
+          			} else {
+           				 continue;
+          			}
+		  		}
+	      	}
+    	}
+	} while (!EFI_ERROR(Status) && (MonotonicCount != 0));
+
+	//
+	//Filling SMBIOS type 7 information for different cache levels.
+	//
+
+	SmbiosRecordL1->Hdr.Type = EFI_SMBIOS_TYPE_CACHE_INFORMATION;
+	SmbiosRecordL1->Hdr.Length = (UINT8) sizeof (SMBIOS_TABLE_TYPE7);
+	SmbiosRecordL1->Hdr.Handle = 0;
+
+	SmbiosRecordL1->Associativity = CacheAssociativity8Way;
+	SmbiosRecordL1->SystemCacheType = CacheTypeUnknown;
+	SmbiosRecordL1->SocketDesignation = 0x01;
+	SmbiosRecordL1->CacheSpeed = 0;
+	SmbiosRecordL1->CacheConfiguration = 0x0180;
+	ZeroMem (&CacheSramType, sizeof (EFI_CACHE_SRAM_TYPE_DATA));
+	CacheSramType.Synchronous = 1;
+	CopyMem(&SmbiosRecordL1->SupportedSRAMType, &CacheSramType, 2);
+	CopyMem(&SmbiosRecordL1->CurrentSRAMType, &CacheSramType, 2);
+	SmbiosRecordL1->ErrorCorrectionType = EfiCacheErrorSingleBit;
+
+
+	SmbiosRecordL2->Hdr.Type = EFI_SMBIOS_TYPE_CACHE_INFORMATION;
+	SmbiosRecordL2->Hdr.Length = (UINT8) sizeof (SMBIOS_TABLE_TYPE7);
+	SmbiosRecordL2->Hdr.Handle = 0;
+
+	SmbiosRecordL2->Associativity = CacheAssociativity16Way;
+	SmbiosRecordL2->SystemCacheType = CacheTypeInstruction;
+	SmbiosRecordL2->SocketDesignation = 0x01;
+	SmbiosRecordL2->CacheSpeed = 0;
+	SmbiosRecordL2->CacheConfiguration = 0x0281;
+	ZeroMem (&CacheSramType, sizeof (EFI_CACHE_SRAM_TYPE_DATA));
+	CacheSramType.Synchronous = 1;
+	CopyMem(&SmbiosRecordL2->SupportedSRAMType, &CacheSramType, 2);
+	CopyMem(&SmbiosRecordL2->CurrentSRAMType, &CacheSramType, 2);
+	SmbiosRecordL2->ErrorCorrectionType = EfiCacheErrorSingleBit;
+
+
+
+	//
+	//Adding SMBIOS type 7 records to SMBIOS table.
+	//
+	SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+	OptionalStrStart = (CHAR8 *)(SmbiosRecordL1 + 1);
+	UnicodeStrToAsciiStr(SocketDesignation, OptionalStrStart);
+
+	Smbios-> Add(
+	           Smbios,
+	           NULL,
+	           &SmbiosHandle,
+	           (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecordL1
+	           );
+
+	//
+	//VLV2 incorporates two SLM modules (quad cores) in the SoC. 2 cores share BIU/L2 cache
+	//
+	SmbiosRecordL2->InstalledSize = (SmbiosRecordL2->InstalledSize)/2;
+	SmbiosRecordL2->MaximumCacheSize = SmbiosRecordL2->InstalledSize;
+	SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+
+	OptionalStrStart = (CHAR8 *)(SmbiosRecordL2 + 1);
+	UnicodeStrToAsciiStr(SocketDesignation, OptionalStrStart);
+
+	Smbios-> Add(
+	           Smbios,
+	           NULL,
+	           &SmbiosHandle,
+	           (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecordL2
+	           );
+
+	return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformation.uni b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformation.uni
new file mode 100644
index 0000000000..2e6c79009b
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformation.uni
@@ -0,0 +1,27 @@
+// *++
+//
+// Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// 
+// Module Name:
+//
+//   MiscProcessorInformation.uni
+// 
+// Abstract:
+// 
+// 
+// Revision History:
+// 
+// --*/
+
+
+/=#
+#langdef   en-US "English"
+
+#string STR_MISC_SOCKET_NAME                #language en-US  "VLV"
+#string STR_MISC_PROCESSOR_MAUFACTURER      #language en-US  "Intel"
+#string STR_MISC_PROCESSOR_VERSION          #language en-US  "Baytrail A0" 
+#string STR_MISC_PROCESSOR_SERIAL_NUMBER    #language en-US  " " 
+#string STR_MISC_ASSERT_TAG_DATA            #language en-US  " "
+#string STR_MISC_PART_NUMBER                #language en-US  " "
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformationData.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformationData.c
new file mode 100644
index 0000000000..846e9ec838
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformationData.c
@@ -0,0 +1,71 @@
+/*++
+
+Copyright (c) 2006  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscOnboardDeviceData.c
+
+Abstract:
+
+  This driver parses the mMiscSubclassDataTable structure and reports
+  any generated data to smbios.
+
+--*/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+
+/*
+  EFI_PROCESSOR_CORE_FREQUENCY_LIST_DATA  ProcessorCoreFrequencyList;
+  EFI_PROCESSOR_FSB_FREQUENCY_LIST_DATA   ProcessorFsbFrequencyList;
+  EFI_PROCESSOR_SERIAL_NUMBER_DATA        ProcessorSerialNumber;
+  EFI_PROCESSOR_CORE_FREQUENCY_DATA       ProcessorCoreFrequency;
+  EFI_PROCESSOR_FSB_FREQUENCY_DATA        ProcessorFsbFrequency;
+  EFI_PROCESSOR_MAX_CORE_FREQUENCY_DATA   ProcessorMaxCoreFrequency;
+  EFI_PROCESSOR_MAX_FSB_FREQUENCY_DATA    ProcessorMaxFsbFrequency;
+  EFI_PROCESSOR_VERSION_DATA              ProcessorVersion;
+  EFI_PROCESSOR_MANUFACTURER_DATA         ProcessorManufacturer;
+  EFI_PROCESSOR_ID_DATA                   ProcessorId;
+  EFI_PROCESSOR_TYPE_DATA                 ProcessorType;
+  EFI_PROCESSOR_FAMILY_DATA               ProcessorFamily;
+  EFI_PROCESSOR_VOLTAGE_DATA              ProcessorVoltage;
+  EFI_PROCESSOR_APIC_BASE_ADDRESS_DATA    ProcessorApicBase;
+  EFI_PROCESSOR_APIC_ID_DATA              ProcessorApicId;
+  EFI_PROCESSOR_APIC_VERSION_NUMBER_DATA  ProcessorApicVersionNumber;
+  EFI_PROCESSOR_MICROCODE_REVISION_DATA   CpuUcodeRevisionData;
+  EFI_PROCESSOR_STATUS_DATA               ProcessorStatus;
+  EFI_PROCESSOR_SOCKET_TYPE_DATA          ProcessorSocketType;
+  EFI_PROCESSOR_SOCKET_NAME_DATA          ProcessorSocketName;
+  EFI_PROCESSOR_ASSET_TAG_DATA            ProcessorAssetTag;
+  EFI_PROCESSOR_HEALTH_STATUS             ProcessorHealthStatus;
+  EFI_PROCESSOR_PACKAGE_NUMBER_DATA       ProcessorPackageNumber;
+} EFI_CPU_VARIABLE_RECORD;
+*/
+
+
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_CPU_DATA_RECORD, MiscProcessorInformation) = {
+
+0,
+    /*
+    STRING_TOKEN (STR_MISC_SOCKET_NAME),		            // Processor Socket Name
+    STRING_TOKEN (STR_MISC_PROCESSOR_MAUFACTURER),		    // Processor Manufacturer
+    STRING_TOKEN (STR_MISC_PROCESSOR_VERSION),		        // Processor Version Information
+	STRING_TOKEN (STR_MISC_PROCESSOR_SERIAL_NUMBER),        // Serial Number
+	STRING_TOKEN (STR_MISC_ASSERT_TAG_DATA),	            // Processor Assert TAg Data
+    STRING_TOKEN (STR_MISC_PART_NUMBER)	                    // Processor Part Numbe
+*/
+};
+
+
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformationFunction.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformationFunction.c
new file mode 100644
index 0000000000..e01693ede7
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformationFunction.c
@@ -0,0 +1,448 @@
+/*++
+
+Copyright (c) 2006  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscProcessorInformationFunction.c
+
+Abstract:
+
+  Onboard processor information boot time changes.
+  SMBIOS type 4.
+
+--*/
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+#include <Protocol/MpService.h>
+#include <Protocol/DataHub.h>
+#include <Guid/DataHubRecords.h>
+#include <Library/CpuIA32.h>
+
+#define EfiProcessorFamilyIntelAtomProcessor    0x2B
+
+EFI_GUID                        mProcessorProducerGuid;
+
+
+/**
+  Get cache SMBIOS record handle.
+
+  @param  Smbios        Pointer to SMBIOS protocol instance.
+  @param  CacheLevel    Level of cache, starting from one.
+  @param  Handle        Returned record handle.
+
+**/
+
+VOID
+GetCacheHandle (
+  IN  EFI_SMBIOS_PROTOCOL      *Smbios,
+  IN  UINT8                    CacheLevel,
+  OUT  EFI_SMBIOS_HANDLE       *Handle
+  )
+{
+  UINT16                     CacheConfig;
+  EFI_STATUS                 Status;
+  EFI_SMBIOS_TYPE            RecordType;
+  EFI_SMBIOS_TABLE_HEADER    *Buffer;
+
+  *Handle = 0;
+  RecordType = EFI_SMBIOS_TYPE_CACHE_INFORMATION;
+
+  do {
+    Status = Smbios->GetNext (
+                       Smbios,
+                       Handle,
+                       &RecordType,
+                       &Buffer,
+                       NULL
+                       );
+    if (!EFI_ERROR(Status)) {
+      CacheConfig = *(UINT16*)((UINT8*)Buffer + 5);
+      if ((CacheConfig & 0x7) == (CacheLevel -1) ) {
+        return;
+      }
+    }
+  } while (!EFI_ERROR(Status));
+
+  *Handle = 0xFFFF;
+}
+
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscProcessorInformation (Type 4).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+UINT32
+ConvertBase10ToRaw (
+  IN  EFI_EXP_BASE10_DATA             *Data)
+{
+  UINTN         Index;
+  UINT32        RawData;
+
+  RawData = Data->Value;
+  for (Index = 0; Index < (UINTN) Data->Exponent; Index++) {
+     RawData *= 10;
+  }
+
+  return  RawData;
+}
+
+#define BSEL_CR_OVERCLOCK_CONTROL	0xCD
+#define	FUSE_BSEL_MASK				0x03
+
+
+
+UINT16 miFSBFrequencyTable[4] = {
+  83,          	// 83.3MHz
+  100,          // 100MHz
+  133,          // 133MHz
+  117           // 116.7MHz
+};
+
+/**
+  Determine the processor core frequency
+
+  @param None
+
+  @retval Processor core frequency multiplied by 3
+
+
+**/
+UINT16
+DetermineiFsbFromMsr (
+  VOID
+  )
+{
+  //
+  // Determine the processor core frequency
+  //
+  UINT64	Temp;
+  Temp = (EfiReadMsr (BSEL_CR_OVERCLOCK_CONTROL)) & FUSE_BSEL_MASK;
+  return miFSBFrequencyTable[(UINT32)(Temp)];
+
+}
+
+MISC_SMBIOS_TABLE_FUNCTION (MiscProcessorInformation)
+{
+    CHAR8                           *OptionalStrStart;
+    EFI_STRING                      SerialNumber;
+    CHAR16                          *Version=NULL;
+    CHAR16                          *Manufacturer=NULL;
+    CHAR16                          *Socket=NULL;
+    CHAR16                          *AssetTag=NULL;
+    CHAR16                          *PartNumber=NULL;
+    UINTN                           SerialNumberStrLen=0;
+    UINTN                           VersionStrLen=0;
+    UINTN                           ManufacturerStrLen=0;
+    UINTN                           SocketStrLen=0;
+    UINTN                           AssetTagStrLen=0;
+    UINTN                           PartNumberStrLen=0;
+    UINTN                           ProcessorVoltage=0xAE;
+    UINT32                          Eax01;
+    UINT32                          Ebx01;
+    UINT32                          Ecx01;
+    UINT32                          Edx01;
+    STRING_REF                      TokenToGet;
+    EFI_STATUS                      Status;
+    EFI_SMBIOS_HANDLE               SmbiosHandle;
+    SMBIOS_TABLE_TYPE4              *SmbiosRecord;
+    EFI_CPU_DATA_RECORD             *ForType4InputData;
+    UINT16                          L1CacheHandle=0;
+    UINT16                          L2CacheHandle=0;
+    UINT16                          L3CacheHandle=0;
+    UINTN                           NumberOfEnabledProcessors=0 ;
+    UINTN                           NumberOfProcessors=0;
+    UINT64                          Frequency = 0;
+    EFI_MP_SERVICES_PROTOCOL        *MpService;
+    EFI_DATA_HUB_PROTOCOL           *DataHub;
+    UINT64                          MonotonicCount;
+    EFI_DATA_RECORD_HEADER          *Record;
+    EFI_SUBCLASS_TYPE1_HEADER       *DataHeader;
+    UINT8                           *SrcData;
+    EFI_PROCESSOR_VERSION_DATA      *ProcessorVersion;
+    CHAR16                          *NewStringToken;
+    STRING_REF                      TokenToUpdate;
+    PROCESSOR_ID_DATA               *ProcessorId = NULL;
+
+
+    //
+    // First check for invalid parameters.
+    //
+    if (RecordData == NULL) {
+        return EFI_INVALID_PARAMETER;
+    }
+
+    ForType4InputData = (EFI_CPU_DATA_RECORD *)RecordData;
+
+    ProcessorId = AllocateZeroPool(sizeof(PROCESSOR_ID_DATA));
+    if (ProcessorId == NULL) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    //
+    // Get the Data Hub Protocol. Assume only one instance
+    //
+    Status = gBS->LocateProtocol (
+                    &gEfiDataHubProtocolGuid,
+                    NULL,
+                    (VOID **)&DataHub
+                    );
+    ASSERT_EFI_ERROR(Status);
+
+    MonotonicCount = 0;
+    Record = NULL;
+
+    do {
+      Status = DataHub->GetNextRecord (
+                          DataHub,
+                          &MonotonicCount,
+                          NULL,
+                          &Record
+                          );
+       if (!EFI_ERROR(Status)) {
+         if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {
+
+            DataHeader  = (EFI_SUBCLASS_TYPE1_HEADER *)(Record + 1);
+            SrcData     = (UINT8  *)(DataHeader + 1);
+
+            //
+            // Processor
+            //
+            if (CompareGuid(&Record->DataRecordGuid, &gEfiProcessorSubClassGuid)) {
+              CopyMem (&mProcessorProducerGuid, &Record->ProducerName, sizeof(EFI_GUID));
+              switch (DataHeader->RecordType) {
+                case ProcessorVoltageRecordType:
+                  ProcessorVoltage = (((EFI_EXP_BASE10_DATA *)SrcData)->Value)/100 + 0x80;
+                  break;
+                case ProcessorCoreFrequencyRecordType:
+                  DEBUG ((EFI_D_ERROR, "ProcessorCoreFrequencyRecordType SrcData1 =%d\n", ConvertBase10ToRaw((EFI_EXP_BASE10_DATA *)SrcData)/1000000));
+                  Frequency = (ConvertBase10ToRaw((EFI_EXP_BASE10_DATA *)SrcData)/1000000);
+                  break;
+                case ProcessorVersionRecordType:
+                  ProcessorVersion = (EFI_PROCESSOR_VERSION_DATA *)SrcData;
+                  NewStringToken = HiiGetPackageString(&mProcessorProducerGuid, *ProcessorVersion, NULL);
+                  TokenToUpdate = (STRING_REF)STR_MISC_PROCESSOR_VERSION;
+                  HiiSetString(mHiiHandle, TokenToUpdate, NewStringToken, NULL);
+                  break;
+                default:
+                  break;
+              }
+            }
+          }
+        }
+    } while (!EFI_ERROR(Status) && (MonotonicCount != 0));
+
+    //
+    // Token to get for Socket Name
+    //
+    TokenToGet = STRING_TOKEN (STR_MISC_SOCKET_NAME);
+    Socket = SmbiosMiscGetString (TokenToGet);
+    SocketStrLen = StrLen(Socket);
+    if (SocketStrLen > SMBIOS_STRING_MAX_LENGTH) {
+         return EFI_UNSUPPORTED;
+    }
+
+    //
+    // Token to get for Processor Manufacturer
+    //
+    TokenToGet = STRING_TOKEN (STR_MISC_PROCESSOR_MAUFACTURER);
+    Manufacturer = SmbiosMiscGetString (TokenToGet);
+    ManufacturerStrLen = StrLen(Manufacturer);
+    if (ManufacturerStrLen > SMBIOS_STRING_MAX_LENGTH) {
+      return EFI_UNSUPPORTED;
+    }
+
+    //
+    // Token to get for Processor Version
+    //
+    TokenToGet = STRING_TOKEN (STR_MISC_PROCESSOR_VERSION);
+    Version = SmbiosMiscGetString (TokenToGet);
+    VersionStrLen = StrLen(Version);
+    if (VersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
+        return EFI_UNSUPPORTED;
+    }
+
+    //
+    // Token to get for Serial Number
+    //
+    TokenToGet = STRING_TOKEN (STR_MISC_PROCESSOR_SERIAL_NUMBER);
+    SerialNumber = SmbiosMiscGetString (TokenToGet);
+    SerialNumberStrLen = StrLen(SerialNumber);
+    if (SerialNumberStrLen > SMBIOS_STRING_MAX_LENGTH) {
+        return EFI_UNSUPPORTED;
+    }
+
+    //
+    // Token to get for Assert Tag Information
+    //
+    TokenToGet = STRING_TOKEN (STR_MISC_ASSERT_TAG_DATA);
+    AssetTag = SmbiosMiscGetString (TokenToGet);
+    AssetTagStrLen = StrLen(AssetTag);
+    if (AssetTagStrLen > SMBIOS_STRING_MAX_LENGTH) {
+        return EFI_UNSUPPORTED;
+    }
+
+    //
+    // Token to get for part number Information
+    //
+    TokenToGet = STRING_TOKEN (STR_MISC_PART_NUMBER);
+    PartNumber = SmbiosMiscGetString (TokenToGet);
+    PartNumberStrLen = StrLen(PartNumber);
+    if (PartNumberStrLen > SMBIOS_STRING_MAX_LENGTH) {
+         return EFI_UNSUPPORTED;
+    }
+
+    //
+    // Two zeros following the last string.
+    //
+    SmbiosRecord = AllocateZeroPool(sizeof (SMBIOS_TABLE_TYPE4) + AssetTagStrLen + 1 + SocketStrLen + 1+ ManufacturerStrLen +1 + VersionStrLen+ 1+ SerialNumberStrLen + 1 + PartNumberStrLen+ 1 + 1);
+
+    SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION;
+    SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE4);
+
+    //
+    // Make handle chosen by smbios protocol.add automatically.
+    //
+    SmbiosRecord->Hdr.Handle = 0;
+
+    SmbiosRecord-> Socket= 1;
+    SmbiosRecord -> ProcessorManufacture = 2;
+    SmbiosRecord -> ProcessorVersion = 3;
+    SmbiosRecord ->SerialNumber =4;
+
+    SmbiosRecord-> AssetTag= 5;
+    SmbiosRecord-> PartNumber= 6;
+
+    //
+    // Processor Type
+    //
+    ForType4InputData-> VariableRecord.ProcessorType= EfiCentralProcessor;
+    SmbiosRecord -> ProcessorType = ForType4InputData-> VariableRecord.ProcessorType;
+
+    //
+    // Processor Family
+    //
+    ForType4InputData-> VariableRecord.ProcessorFamily= EfiProcessorFamilyIntelAtomProcessor; //0x2B;;
+    SmbiosRecord -> ProcessorFamily = ForType4InputData-> VariableRecord.ProcessorFamily;
+    SmbiosRecord -> ExternalClock = DetermineiFsbFromMsr();
+
+    //
+    // Processor ID
+    //
+    AsmCpuid(0x001, &Eax01, &Ebx01, &Ecx01, &Edx01);
+    ProcessorId->Signature = *(PROCESSOR_SIGNATURE *)&Eax01;
+    ProcessorId->FeatureFlags = *(PROCESSOR_FEATURE_FLAGS *)&Edx01;
+    SmbiosRecord -> ProcessorId = *(PROCESSOR_ID_DATA *)ProcessorId;
+
+    //
+    // Processor Voltage
+    //
+    ForType4InputData-> VariableRecord.ProcessorVoltage= *(EFI_PROCESSOR_VOLTAGE_DATA *)&ProcessorVoltage;
+    SmbiosRecord -> Voltage = *(PROCESSOR_VOLTAGE *) &(ForType4InputData-> VariableRecord.ProcessorVoltage);
+
+    //
+    // Status
+    //
+    ForType4InputData-> VariableRecord.ProcessorHealthStatus= 0x41;//0x41;
+    SmbiosRecord -> Status = ForType4InputData-> VariableRecord.ProcessorHealthStatus;
+
+    //
+    // Processor Upgrade
+    //
+    SmbiosRecord -> ProcessorUpgrade = 0x008;
+
+    //
+    // Processor Family 2
+    //
+    SmbiosRecord -> ProcessorFamily2 = ForType4InputData-> VariableRecord.ProcessorFamily;
+
+    //
+    // Processor speed
+    //
+    SmbiosRecord-> CurrentSpeed = *(UINT16*) & Frequency;
+    SmbiosRecord-> MaxSpeed = *(UINT16*) & Frequency;
+
+    //
+    // Processor Characteristics
+    //
+    AsmCpuid(0x8000000, NULL, NULL, NULL, &Edx01);
+    Edx01= Edx01 >> 28;
+    Edx01 &= 0x01;
+    SmbiosRecord-> ProcessorCharacteristics= (UINT16)Edx01;
+
+    //
+    // Processor Core Count and Enabled core count
+    //
+    Status = gBS->LocateProtocol (
+                    &gEfiMpServiceProtocolGuid,
+                    NULL,
+                    (void **)&MpService
+                    );
+    if (!EFI_ERROR (Status)) {
+    //
+    // Determine the number of processors
+    //
+    MpService->GetNumberOfProcessors (
+                 MpService,
+                 &NumberOfProcessors,
+                 &NumberOfEnabledProcessors
+                 );
+    }
+    SmbiosRecord-> CoreCount= (UINT8)NumberOfProcessors;
+    SmbiosRecord-> EnabledCoreCount= (UINT8)NumberOfEnabledProcessors;
+    SmbiosRecord-> ThreadCount= (UINT8)NumberOfEnabledProcessors;
+    SmbiosRecord-> ProcessorCharacteristics = 0x2; // Unknown
+
+    //
+    // Processor Cache Handle
+    //
+    GetCacheHandle( Smbios,1, &L1CacheHandle);
+    GetCacheHandle( Smbios,2, &L2CacheHandle);
+    GetCacheHandle( Smbios,3, &L3CacheHandle);
+
+    //
+    // Updating Cache Handle Information
+    //
+    SmbiosRecord->L1CacheHandle  = L1CacheHandle;
+    SmbiosRecord->L2CacheHandle  = L2CacheHandle;
+    SmbiosRecord->L3CacheHandle  = L3CacheHandle;
+
+    OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+    UnicodeStrToAsciiStr(Socket, OptionalStrStart);
+    UnicodeStrToAsciiStr(Manufacturer, OptionalStrStart + SocketStrLen + 1);
+    UnicodeStrToAsciiStr(Version, OptionalStrStart + SocketStrLen + 1 + ManufacturerStrLen+ 1);
+    UnicodeStrToAsciiStr(SerialNumber, OptionalStrStart + SocketStrLen + 1 + VersionStrLen + 1 + ManufacturerStrLen + 1);
+    UnicodeStrToAsciiStr(AssetTag, OptionalStrStart + SerialNumberStrLen + 1 + VersionStrLen + 1 + ManufacturerStrLen + 1 + SocketStrLen + 1);
+    UnicodeStrToAsciiStr(PartNumber, OptionalStrStart + SerialNumberStrLen + 1 + VersionStrLen + 1 + ManufacturerStrLen + 1 + SocketStrLen + 1 + AssetTagStrLen + 1 );
+
+    //
+    // Now we have got the full Smbios record, call Smbios protocol to add this record.
+    //
+    SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+    Status = Smbios-> Add(
+                        Smbios,
+                        NULL,
+                        &SmbiosHandle,
+                        (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                        );
+    if (EFI_ERROR (Status)) return Status;
+    FreePool(SmbiosRecord);
+    return Status;
+
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesData.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesData.c
new file mode 100644
index 0000000000..e3b847f7ce
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesData.c
@@ -0,0 +1,43 @@
+/** @file
+
+Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+    MiscResetCapabilitiesData.c
+
+Abstract:
+
+  Static data of Reset Capabilities information.
+  Reset Capabilities information is Misc. subclass type 17 and SMBIOS type 23.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_RESET_CAPABILITIES, MiscResetCapabilities)
+= {
+  {       // ResetCapabilities
+    0,    // Status
+    0,    // BootOption
+    0,    // BootOptionOnLimit
+    0,    // WatchdogTimerPresent
+    0     // Reserved
+  },
+  0xFFFF, // ResetCount
+  0xFFFF, // ResetLimit
+  0xFFFF, // ResetTimerInterval
+  0xFFFF  // ResetTimeout
+};
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesFunction.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesFunction.c
new file mode 100644
index 0000000000..67a549a6ba
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesFunction.c
@@ -0,0 +1,85 @@
+/*++
+
+Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  MiscResetCapabilitiesFunction.c
+
+Abstract:
+
+  ResetCapabilities.
+  SMBIOS type 23.
+
+--*/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscOemString (Type 11).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscResetCapabilities)
+{
+  EFI_STATUS               Status;
+  EFI_SMBIOS_HANDLE        SmbiosHandle;
+  SMBIOS_TABLE_TYPE23      *SmbiosRecord;
+  EFI_MISC_RESET_CAPABILITIES   *ForType23InputData;
+
+  ForType23InputData = (EFI_MISC_RESET_CAPABILITIES *)RecordData;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE23) + 1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE23) + 1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_RESET;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE23);
+
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle    = 0;
+  SmbiosRecord->Capabilities  = *(UINT8*)&(ForType23InputData->ResetCapabilities);
+  SmbiosRecord->ResetCount    = (UINT16)ForType23InputData->ResetCount;
+  SmbiosRecord->ResetLimit    = (UINT16)ForType23InputData->ResetLimit;
+  SmbiosRecord->TimerInterval = (UINT16)ForType23InputData->ResetTimerInterval;
+  SmbiosRecord->Timeout       = (UINT16)ForType23InputData->ResetTimeout;
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+  FreePool(SmbiosRecord);
+  return Status;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.h b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.h
new file mode 100644
index 0000000000..67ea100fad
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.h
@@ -0,0 +1,188 @@
+/** @file
+
+Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscSubclassDriver.h
+
+Abstract:
+
+  Header file for MiscSubclass Driver.
+
+
+**/
+
+#ifndef _MISC_SUBCLASS_DRIVER_H
+#define _MISC_SUBCLASS_DRIVER_H
+
+
+#include "CommonHeader.h"
+
+extern UINT8  MiscSubclassStrings[];
+
+
+#define T14_FVI_STRING          "Driver/firmware version"
+#define EFI_SMBIOS_TYPE_FIRMWARE_VERSION_INFO 0x90
+#define EFI_SMBIOS_TYPE_MISC_VERSION_INFO 0x94
+#define TOUCH_ACPI_ID    "I2C05\\SFFFF\\400K"
+#define TOUCH_RESET_GPIO_MMIO  0xFED0C508
+#define EFI_SMBIOS_TYPE_SEC_INFO 0x83
+#define IntelIdentifer 0x6F725076
+
+//
+// Data table entry update function.
+//
+typedef EFI_STATUS (EFIAPI EFI_MISC_SMBIOS_DATA_FUNCTION) (
+  IN  VOID                 *RecordData,
+  IN  EFI_SMBIOS_PROTOCOL  *Smbios
+  );
+
+//
+// Data table entry definition.
+//
+typedef struct {
+  //
+  // intermediat input data for SMBIOS record
+  //
+  VOID                              *RecordData;
+  EFI_MISC_SMBIOS_DATA_FUNCTION     *Function;
+} EFI_MISC_SMBIOS_DATA_TABLE;
+
+//
+// Data Table extern definitions.
+//
+#define MISC_SMBIOS_TABLE_EXTERNS(NAME1, NAME2, NAME3) \
+extern NAME1 NAME2 ## Data; \
+extern EFI_MISC_SMBIOS_DATA_FUNCTION NAME3 ## Function
+
+
+//
+// Data Table entries
+//
+#define MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(NAME1, NAME2) \
+{ \
+  & NAME1 ## Data, \
+  & NAME2 ## Function \
+}
+
+//
+// Global definition macros.
+//
+#define MISC_SMBIOS_TABLE_DATA(NAME1, NAME2) \
+  NAME1 NAME2 ## Data
+
+#define MISC_SMBIOS_TABLE_FUNCTION(NAME2) \
+  EFI_STATUS EFIAPI NAME2 ## Function( \
+  IN  VOID                  *RecordData, \
+  IN  EFI_SMBIOS_PROTOCOL   *Smbios \
+  )
+
+#pragma pack(1)
+
+//
+// This is definition for SMBIOS Oem data type 0x90
+//
+typedef struct {
+  STRING_REF                         SECVersion;
+  STRING_REF                         uCodeVersion;
+  STRING_REF                         GOPVersion;
+  STRING_REF                         CpuStepping;
+} EFI_MISC_OEM_TYPE_0x90;
+
+//
+// This is definition for SMBIOS Oem data type 0x90
+//
+typedef struct {
+  SMBIOS_STRUCTURE          Hdr;
+  SMBIOS_TABLE_STRING       SECVersion;
+  SMBIOS_TABLE_STRING       uCodeVersion;
+  SMBIOS_TABLE_STRING       GOPVersion;
+  SMBIOS_TABLE_STRING       CpuStepping;
+} SMBIOS_TABLE_TYPE90;
+
+typedef struct {
+  STRING_REF                GopVersion;
+  STRING_REF                UCodeVersion;
+  STRING_REF                MRCVersion;
+  STRING_REF                SECVersion;
+  STRING_REF                ULPMCVersion;
+  STRING_REF                PMCVersion;
+  STRING_REF                PUnitVersion;
+  STRING_REF                SoCVersion;
+  STRING_REF                BoardVersion;
+  STRING_REF                FabVersion;
+  STRING_REF                CPUFlavor;
+  STRING_REF                BiosVersion;
+  STRING_REF                PmicVersion;
+  STRING_REF                TouchVersion;
+  STRING_REF                SecureBoot;
+  STRING_REF                BootMode;
+  STRING_REF                SpeedStepMode;
+  STRING_REF                CPUTurboMode;
+  STRING_REF                MaxCState;
+  STRING_REF                GfxTurbo;
+  STRING_REF                IdleReserve;
+  STRING_REF                RC6;
+}EFI_MISC_OEM_TYPE_0x94;
+
+typedef struct {
+  SMBIOS_STRUCTURE          Hdr;
+  SMBIOS_TABLE_STRING       GopVersion;
+  SMBIOS_TABLE_STRING       uCodeVersion;
+  SMBIOS_TABLE_STRING       MRCVersion;
+  SMBIOS_TABLE_STRING       SECVersion;
+  SMBIOS_TABLE_STRING       ULPMCVersion;
+  SMBIOS_TABLE_STRING       PMCVersion;
+  SMBIOS_TABLE_STRING       PUnitVersion;
+  SMBIOS_TABLE_STRING       SoCVersion;
+  SMBIOS_TABLE_STRING       BoardVersion;
+  SMBIOS_TABLE_STRING       FabVersion;
+  SMBIOS_TABLE_STRING       CPUFlavor;
+  SMBIOS_TABLE_STRING       BiosVersion;
+  SMBIOS_TABLE_STRING       PmicVersion;
+  SMBIOS_TABLE_STRING       TouchVersion;
+  SMBIOS_TABLE_STRING       SecureBoot;
+  SMBIOS_TABLE_STRING       BootMode;
+  SMBIOS_TABLE_STRING       SpeedStepMode;
+  SMBIOS_TABLE_STRING       CPUTurboMode;
+  SMBIOS_TABLE_STRING       MaxCState;
+  SMBIOS_TABLE_STRING       GfxTurbo;
+  SMBIOS_TABLE_STRING       IdleReserve;
+  SMBIOS_TABLE_STRING       RC6;
+}SMBIOS_TABLE_TYPE94;
+
+#pragma pack()
+//
+// Data Table Array
+//
+extern EFI_MISC_SMBIOS_DATA_TABLE mMiscSubclassDataTable[];
+
+//
+// Data Table Array Entries
+//
+extern UINTN                        mMiscSubclassDataTableEntries;
+extern EFI_HII_HANDLE               mHiiHandle;
+
+//
+// Prototypes
+//
+EFI_STATUS
+EFIAPI
+MiscSubclassDriverEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  );
+
+EFI_STRING
+EFIAPI
+SmbiosMiscGetString (
+  IN EFI_STRING_ID   StringId
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.uni b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.uni
new file mode 100644
index 0000000000..3a6ccf1d75
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.uni
@@ -0,0 +1,35 @@
+// *++
+//
+// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// 
+// Module Name:
+//
+//  MiscSubclassDriver.uni
+// 
+// Abstract:
+// 
+//   Misc Subclass information.
+// 
+// Revision History: 
+// 
+// --*/
+
+/=#
+
+#langdef en-US "English"
+
+#string STR_MISC_SUBCLASS_DRIVER_TITLE #language en-US  "Not used"
+
+#include "MiscBaseBoardManufacturer.uni"
+#include "MiscBiosVendor.uni"
+#include "MiscChassisManufacturer.uni"
+#include "MiscOemString.uni"
+#include "MiscOnboardDevice.uni"
+#include "MiscPortInternalConnectorDesignator.uni"
+#include "MiscSystemLanguageString.uni"
+#include "MiscSystemManufacturer.uni"
+#include "MiscSystemOptionString.uni"
+#include "MiscSystemSlotDesignation.uni"
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverDataTable.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverDataTable.c
new file mode 100644
index 0000000000..93347a1a04
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverDataTable.c
@@ -0,0 +1,98 @@
+/** @file
+
+Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscSubclassDriverDataTable.c
+
+Abstract:
+
+  Create the mMiscSubclassDataTable structure, and it is used to report
+  any generate data to the DataHub.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+//
+// External definitions referenced by Data Table entries.
+//
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_BIOS_VENDOR_DATA, MiscBiosVendor, MiscBiosVendor);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_MANUFACTURER_DATA, MiscSystemManufacturer, MiscSystemManufacturer);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_BASE_BOARD_MANUFACTURER_DATA, MiscBaseBoardManufacturer, MiscBaseBoardManufacturer);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_CHASSIS_MANUFACTURER_DATA, MiscChassisManufacturer, MiscChassisManufacturer);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_CACHE_VARIABLE_RECORD, MiscProcessorCache, MiscProcessorCache); //type 7
+MISC_SMBIOS_TABLE_EXTERNS(EFI_CPU_DATA_RECORD, MiscProcessorInformation, MiscProcessorInformation); //type 4
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MEMORY_ARRAY_LOCATION_DATA, MiscPhysicalMemoryArray,MiscPhysicalMemoryArray);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MEMORY_ARRAY_LINK_DATA, MiscMemoryDevice, MiscMemoryDevice);
+
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortIde1, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortIde2, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortAtxPower, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA, MiscSystemSlotPCIEx16Slot1, MiscSystemSlotDesignation);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA, MiscSystemSlotPCIEx16Slot2, MiscSystemSlotDesignation);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA, MiscSystemSlotPCIEx4, MiscSystemSlotDesignation);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA, MiscSystemSlotPCIEx1Slot1, MiscSystemSlotDesignation);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA, MiscSystemSlotPCIEx1Slot2, MiscSystemSlotDesignation);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA, MiscSystemSlotPCIEx1Slot3, MiscSystemSlotDesignation);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA, MiscSystemSlotPCI1, MiscSystemSlotDesignation);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA, MiscSystemSlotPCI2, MiscSystemSlotDesignation);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA, MiscSystemSlotPCI3, MiscSystemSlotDesignation);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_ONBOARD_DEVICE_DATA, MiscOnboardDeviceVideo, MiscOnboardDevice);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_ONBOARD_DEVICE_DATA, MiscOnboardDeviceNetwork, MiscOnboardDevice);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_ONBOARD_DEVICE_DATA, MiscOnboardDeviceAudio, MiscOnboardDevice);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES_DATA, NumberOfInstallableLanguages, NumberOfInstallableLanguages);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_LANGUAGE_STRING_DATA, SystemLanguageString, SystemLanguageString);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_BOOT_INFORMATION_STATUS_DATA, BootInformationStatus, BootInformationStatus);
+
+//
+// Data Table.
+//
+EFI_MISC_SMBIOS_DATA_TABLE  mMiscSubclassDataTable[] = {
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscBiosVendor, MiscBiosVendor),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemManufacturer, MiscSystemManufacturer),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscBaseBoardManufacturer, MiscBaseBoardManufacturer),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscChassisManufacturer, MiscChassisManufacturer),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscProcessorCache, MiscProcessorCache),  //type 7
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscProcessorInformation, MiscProcessorInformation),  //type 4
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPhysicalMemoryArray, MiscPhysicalMemoryArray),    //Type 16
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscMemoryDevice, MiscMemoryDevice), //Type 17
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortIde1, MiscPortInternalConnectorDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortIde2, MiscPortInternalConnectorDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortAtxPower, MiscPortInternalConnectorDesignator),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlotPCIEx16Slot1, MiscSystemSlotDesignation),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlotPCIEx16Slot2, MiscSystemSlotDesignation),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlotPCIEx4, MiscSystemSlotDesignation),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlotPCIEx1Slot1, MiscSystemSlotDesignation),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlotPCIEx1Slot2, MiscSystemSlotDesignation),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlotPCIEx1Slot3, MiscSystemSlotDesignation),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlotPCI1, MiscSystemSlotDesignation),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlotPCI2, MiscSystemSlotDesignation),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlotPCI3, MiscSystemSlotDesignation),
+#if defined( ALWAYS_DISABLE_ONBOARD_VIDEO ) && \
+    ( ALWAYS_DISABLE_ONBOARD_VIDEO != 0 )
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscOnboardDeviceNetwork, MiscOnboardDevice),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscOnboardDeviceAudio, MiscOnboardDevice),
+#else
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscOnboardDeviceVideo, MiscOnboardDevice),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscOnboardDeviceAudio, MiscOnboardDevice),
+#endif
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(SystemLanguageString, SystemLanguageString),
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(BootInformationStatus, BootInformationStatus),
+};
+
+//
+// Number of Data Table entries.
+//
+UINTN mMiscSubclassDataTableEntries =
+        (sizeof mMiscSubclassDataTable) / sizeof(EFI_MISC_SMBIOS_DATA_TABLE);
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverEntryPoint.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverEntryPoint.c
new file mode 100644
index 0000000000..e70732f5c2
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverEntryPoint.c
@@ -0,0 +1,182 @@
+/** @file
+
+Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscSubclassDriverEntryPoint.c
+
+Abstract:
+
+  This driver parses the mMiscSubclassDataTable structure and reports
+  any generated data to the DataHub.
+
+
+**/
+
+
+#include "CommonHeader.h"
+#include "MiscSubclassDriver.h"
+#include <Protocol/HiiString.h>
+#include <Guid/PlatformInfo.h>
+
+
+EFI_HII_HANDLE  mHiiHandle;
+EFI_HII_STRING_PROTOCOL  *mHiiString;
+EFI_PLATFORM_INFO_HOB *mPlatformInfo=NULL;
+
+EFI_STRING
+EFIAPI
+SmbiosMiscGetString (
+  IN EFI_STRING_ID   StringId
+  ){
+
+  EFI_STATUS  Status;
+  UINTN       StringSize;
+  CHAR16      TempString;
+  EFI_STRING  String;
+  String             = NULL;
+
+  //
+  // Retrieve the size of the string in the string package for the BestLanguage
+  //
+  StringSize = 0;
+  Status = mHiiString->GetString (
+                         mHiiString,
+                         "en-US",
+                         mHiiHandle,
+                         StringId,
+                         &TempString,
+                         &StringSize,
+                         NULL
+                         );
+  //
+  // If GetString() returns EFI_SUCCESS for a zero size,
+  // then there are no supported languages registered for HiiHandle.  If GetString()
+  // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present
+  // in the HII Database
+  //
+  if (Status != EFI_BUFFER_TOO_SMALL) {
+    goto Error;
+  }
+
+  //
+  // Allocate a buffer for the return string
+  //
+  String = AllocateZeroPool (StringSize);
+  if (String == NULL) {
+    goto Error;
+  }
+
+  //
+  // Retrieve the string from the string package
+  //
+  Status = mHiiString->GetString (
+                         mHiiString,
+                         "en-US",
+                         mHiiHandle,
+                         StringId,
+                         String,
+                         &StringSize,
+                         NULL
+                         );
+  if (EFI_ERROR (Status)) {
+    //
+    // Free the buffer and return NULL if the supported languages can not be retrieved.
+    //
+    FreePool (String);
+    String = NULL;
+  }
+Error:
+
+  return String;
+}
+
+/**
+  Standard EFI driver point.  This driver parses the mMiscSubclassDataTable
+  structure and reports any generated data to the DataHub.
+
+  @param ImageHandle   - Handle for the image of this driver
+  @param SystemTable   - Pointer to the EFI System Table
+
+  @retval EFI_SUCCESS      - The data was successfully reported to the Data Hub.
+  @retval EFI_DEVICE_ERROR - Can not locate any protocols
+
+**/
+EFI_STATUS
+EFIAPI
+MiscSubclassDriverEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  UINTN                Index;
+  EFI_STATUS           EfiStatus;
+  EFI_SMBIOS_PROTOCOL  *Smbios;
+  EFI_PEI_HOB_POINTERS GuidHob;
+
+
+
+  GuidHob.Raw = GetHobList ();
+  if (GuidHob.Raw != NULL) {
+    if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformInfoGuid, GuidHob.Raw)) != NULL) {
+      mPlatformInfo = GET_GUID_HOB_DATA (GuidHob.Guid);
+    }
+  }
+  
+  DEBUG ((EFI_D_ERROR, "PlatformInfoHob->BoardId [0x%x]\n", mPlatformInfo->BoardId));
+  
+  //
+  // Retrieve the pointer to the UEFI HII String Protocol
+  //
+  EfiStatus = gBS->LocateProtocol (
+                     &gEfiHiiStringProtocolGuid,
+                     NULL,
+                     (VOID **) &mHiiString
+                     );
+  ASSERT_EFI_ERROR (EfiStatus);
+
+  EfiStatus = gBS->LocateProtocol(
+                     &gEfiSmbiosProtocolGuid,
+                     NULL,
+                     (VOID**)&Smbios
+                     );
+
+  if (EFI_ERROR(EfiStatus)) {
+    DEBUG((EFI_D_ERROR, "Could not locate SMBIOS protocol.  %r\n", EfiStatus));
+    return EfiStatus;
+  }
+
+  mHiiHandle = HiiAddPackages (
+                 &gEfiCallerIdGuid,
+                 NULL,
+                 MiscSubclassStrings,
+                 NULL
+                 );
+  ASSERT (mHiiHandle != NULL);
+
+  for (Index = 0; Index < mMiscSubclassDataTableEntries; ++Index) {
+    //
+    // If the entry have a function pointer, just log the data.
+    //
+    if (mMiscSubclassDataTable[Index].Function != NULL) {
+      EfiStatus = (*mMiscSubclassDataTable[Index].Function)(
+        mMiscSubclassDataTable[Index].RecordData,
+        Smbios
+        );
+
+      if (EFI_ERROR(EfiStatus)) {
+        DEBUG((EFI_D_ERROR, "Misc smbios store error.  Index=%d, ReturnStatus=%r\n", Index, EfiStatus));
+        return EfiStatus;
+      }
+    }
+  }
+
+  return EfiStatus;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageString.uni b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageString.uni
new file mode 100644
index 0000000000..9f3fdf8a3f
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageString.uni
@@ -0,0 +1,24 @@
+// *++
+//
+// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// 
+// Module Name:
+//
+//   MiscSystemLanguageString.uni
+// 
+// Abstract:
+// 
+//   System language information
+// 
+// Revision History:
+// 
+// --*/
+
+
+/=#
+
+#langdef en-US "English"
+
+#string STR_MISC_SYSTEM_LANGUAGE_EN_US #language en-US  "enUS"
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageStringData.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageStringData.c
new file mode 100644
index 0000000000..a9def23560
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageStringData.c
@@ -0,0 +1,34 @@
+/** @file
+
+Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscSystemLanguageStringData.c
+
+Abstract:
+
+  Static data of System language string information.
+  System language string information is Misc. subclass type 12 and SMBIOS type 13.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_LANGUAGE_STRING_DATA, SystemLanguageString)
+= {
+  0,
+  STRING_TOKEN(STR_MISC_SYSTEM_LANGUAGE_EN_US)
+};
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageStringFunction.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageStringFunction.c
new file mode 100644
index 0000000000..8abfa4074a
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageStringFunction.c
@@ -0,0 +1,93 @@
+/*++
+
+Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+  MiscResetCapabilitiesFunction.c
+
+Abstract:
+
+  ResetCapabilities.
+  SMBIOS type 23.
+
+--*/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+/**
+  This function makes boot time changes to the contents of the
+  MiscOemString (Type 11).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+
+MISC_SMBIOS_TABLE_FUNCTION(SystemLanguageString)
+{
+  EFI_STATUS               Status;
+  EFI_SMBIOS_HANDLE        SmbiosHandle;
+  SMBIOS_TABLE_TYPE13      *SmbiosRecord;
+  UINTN                    StrLeng;
+  CHAR8                    *OptionalStrStart;
+  EFI_STRING               Str;
+  STRING_REF               TokenToGet;
+
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_LANGUAGE_EN_US);
+  Str = SmbiosMiscGetString (TokenToGet);
+  StrLeng = StrLen(Str);
+  if (StrLeng > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE13) + StrLeng + 1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE13) + StrLeng + 1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_BIOS_LANGUAGE_INFORMATION;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE13);
+
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle    = 0;
+  SmbiosRecord->InstallableLanguages = 1;
+  SmbiosRecord->Flags   = 1;
+  SmbiosRecord->CurrentLanguages = 1;
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  UnicodeStrToAsciiStr(Str, OptionalStrStart);
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+  FreePool(SmbiosRecord);
+  return Status;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacturer.uni b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacturer.uni
new file mode 100644
index 0000000000..d587e0d7df
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacturer.uni
@@ -0,0 +1,30 @@
+// *++
+//
+// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// 
+// Module Name:
+//
+//   MiscSystemManufacturer.uni
+// 
+// Abstract:
+// 
+//   System manufacturer information
+// 
+// Revision History:
+// 
+// --*/
+
+
+/=#
+
+#langdef en-US "English"
+
+#string STR_MISC_SYSTEM_MANUFACTURER   #language en-US  "Circuitco"
+#string STR_MISC_SYSTEM_PRODUCT_NAME   #language en-US  "VALLEYVIEW A0 PLATFORM"
+#string STR_MISC_SYSTEM_VERSION        #language en-US  "A0"
+#string STR_MISC_SYSTEM_SERIAL_NUMBER  #language en-US  "To be filled by O.E.M"
+#string STR_MISC_SYSTEM_SKU_NUMBER     #language en-US  "To be filled by O.E.M"
+#string STR_MISC_SYSTEM_FAMILY_NAME    #language en-US  "IA Tablet"
+#string STR_MISC_SYSTEM_FAMILY_NAME1   #language en-US  "IA Notebook"
\ No newline at end of file
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacturerData.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacturerData.c
new file mode 100644
index 0000000000..dc12fa8e16
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacturerData.c
@@ -0,0 +1,48 @@
+/** @file
+
+Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscSystemManufacturerData.c
+
+Abstract:
+
+  Static data of System manufacturer information.
+  System manufacturer information is Misc. subclass type 3 and SMBIOS type 1.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+//
+// Static (possibly build generated) System Manufacturer data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_MANUFACTURER_DATA, MiscSystemManufacturer)
+= {
+  STRING_TOKEN(STR_MISC_SYSTEM_MANUFACTURER),  // SystemManufactrurer
+  STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME),  // SystemProductName
+  STRING_TOKEN(STR_MISC_SYSTEM_VERSION),       // SystemVersion
+  STRING_TOKEN(STR_MISC_SYSTEM_SERIAL_NUMBER), // SystemSerialNumber
+  {                                            // SystemUuid
+  	//
+    // Undefined GUID but can be programmed later.
+    //0xFFFFFFFF, 0xFFFF, 0xFFFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+
+    // Undefined GUID that cannot be programmed later.
+    //0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	// TODO Hard code here for WHCT test.
+	0xa5000288, 0x6462, 0x4524, 0x98, 0x6a, 0x9b, 0x77, 0x37, 0xe3, 0x15, 0xcf
+	//
+  },
+  EfiSystemWakeupTypePowerSwitch  // SystemWakeupType
+};
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacturerFunction.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacturerFunction.c
new file mode 100644
index 0000000000..63c4f50ed5
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacturerFunction.c
@@ -0,0 +1,364 @@
+/*++
+
+Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+                                                                                   
+
+
+Module Name:
+
+  MiscSystemManufacturerFunction.c
+
+Abstract:
+
+  This driver parses the mMiscSubclassDataTable structure and reports
+  any generated data.
+
+--*/
+
+
+#include "CommonHeader.h"
+#include "MiscSubclassDriver.h"
+#include <Protocol/DxeSmmReadyToLock.h>
+#include <Library/NetLib.h>
+#include "Library/DebugLib.h"
+#include <Uefi/UefiBaseType.h>
+#include <Guid/PlatformInfo.h>
+
+
+extern EFI_PLATFORM_INFO_HOB *mPlatformInfo;
+
+
+/**
+
+  Publish the smbios type 1.
+
+  @param Event      Event whose notification function is being invoked (gEfiDxeSmmReadyToLockProtocolGuid).
+  @param Context    Pointer to the notification functions context, which is implementation dependent.
+
+  @retval None
+
+**/
+EFI_STATUS
+EFIAPI
+AddSmbiosManuCallback (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+
+  CHAR8                             *OptionalStrStart;
+  UINTN                             ManuStrLen;
+  UINTN                             VerStrLen;
+  UINTN                             PdNameStrLen;
+  UINTN                             SerialNumStrLen;
+  UINTN                             SkuNumberStrLen;
+  UINTN				                FamilyNameStrLen;
+  EFI_STATUS                        Status;
+  EFI_STRING                        Manufacturer;
+  EFI_STRING                        ProductName;
+  EFI_STRING                        Version;
+  EFI_STRING                        SerialNumber;
+  EFI_STRING                        SkuNumber;
+  EFI_STRING			            FamilyName;
+  STRING_REF                        TokenToGet;
+  EFI_SMBIOS_HANDLE                 SmbiosHandle;
+  SMBIOS_TABLE_TYPE1                *SmbiosRecord;
+  EFI_MISC_SYSTEM_MANUFACTURER      *ForType1InputData;
+  EFI_SMBIOS_PROTOCOL               *Smbios;
+  CHAR16                            Buffer[40];
+  
+  CHAR16                            *MacStr; 
+  EFI_HANDLE                        *Handles;
+  UINTN                             BufferSize;
+  CHAR16                            PlatformNameBuffer[40];
+
+  ForType1InputData = (EFI_MISC_SYSTEM_MANUFACTURER *)Context;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (Context == NULL || mPlatformInfo == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID *) &Smbios);
+  ASSERT_EFI_ERROR (Status);
+
+
+  if (BOARD_ID_MINNOW2_TURBOT == mPlatformInfo->BoardId) {
+    // Detect the board is Turbot board platform
+    UnicodeSPrint (PlatformNameBuffer, sizeof (PlatformNameBuffer),L"%s",L"Minnowboard Turbot ");
+  } else {
+    UnicodeSPrint (PlatformNameBuffer, sizeof (PlatformNameBuffer),L"%s",L"Minnowboard Max ");
+  }
+
+  //
+  // Silicon Steppings
+  //
+  switch (PchStepping()) {
+    case PchA0:
+      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"A0 PLATFORM");
+      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL);
+      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"A0");
+      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL);
+      DEBUG ((EFI_D_ERROR, "A0 Stepping Detected\n"));
+      break;
+    case PchA1:
+      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"A1 PLATFORM");
+      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL);
+      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"A1");
+      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL);
+      DEBUG ((EFI_D_ERROR, "A1 Stepping Detected\n"));
+      break;
+    case PchB0:
+      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"B0 PLATFORM");
+      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL);
+      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"B0");
+      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL);
+      DEBUG ((EFI_D_ERROR, "B0 Stepping Detected\n"));
+      break;
+    case PchB1:
+      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"B1 PLATFORM");
+      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL);
+      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"B1");
+      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL);
+      DEBUG ((EFI_D_ERROR, "B1 Stepping Detected\n"));
+      break;
+    case PchB2:
+      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"B2 PLATFORM");
+      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL);
+      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"B2");
+      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL);
+      DEBUG ((EFI_D_ERROR, "B2 Stepping Detected\n"));
+      break;
+    case PchB3:
+      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"B3 PLATFORM");
+      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL);
+      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"B3");
+      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL);
+      DEBUG ((EFI_D_ERROR, "B3 Stepping Detected\n"));
+      break;
+    case PchC0:
+      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"C0 PLATFORM");
+      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL);
+      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"C0");
+      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL);
+      DEBUG ((EFI_D_ERROR, "C0 Stepping Detected\n"));
+      break;
+   case PchD0:
+      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"D0 PLATFORM");
+      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL);
+      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"D0");
+      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL);
+      DEBUG ((EFI_D_ERROR, "D0 Stepping Detected\n"));
+      break;
+    default:
+      DEBUG ((EFI_D_ERROR, "Unknow Stepping Detected\n"));
+      break;
+    }
+
+  if (BOARD_ID_MINNOW2_TURBOT == mPlatformInfo->BoardId) {
+    UnicodeSPrint (Buffer, sizeof (Buffer),L"ADI");
+    HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_MANUFACTURER), Buffer, NULL);
+  }
+  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_MANUFACTURER);
+  Manufacturer = SmbiosMiscGetString (TokenToGet);
+  ManuStrLen = StrLen(Manufacturer);
+  if (ManuStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_PRODUCT_NAME);
+  ProductName = SmbiosMiscGetString (TokenToGet);
+  PdNameStrLen = StrLen(ProductName);
+  if (PdNameStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_VERSION);
+  Version = SmbiosMiscGetString (TokenToGet);
+  VerStrLen = StrLen(Version);
+  if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  //Get handle infomation
+  //
+  BufferSize = 0;
+  Handles = NULL;
+  Status = gBS->LocateHandle (
+                  ByProtocol, 
+                  &gEfiSimpleNetworkProtocolGuid,
+                  NULL,
+                  &BufferSize,
+                  Handles
+                  );
+
+  if (Status == EFI_BUFFER_TOO_SMALL) {
+  	Handles = AllocateZeroPool(BufferSize);
+  	if (Handles == NULL) {
+  		return (EFI_OUT_OF_RESOURCES);
+  	}
+  	Status = gBS->LocateHandle(
+  	                ByProtocol,
+  	                &gEfiSimpleNetworkProtocolGuid,
+  	                NULL,
+  	                &BufferSize,
+  	                Handles
+  	                );
+ }
+ 	                
+  //
+  //Get the MAC string
+  //
+  Status = NetLibGetMacString (
+             *Handles,
+             NULL,
+             &MacStr
+             );
+  if (EFI_ERROR (Status)) {	
+    return Status;
+  }
+  SerialNumber = MacStr; 
+  SerialNumStrLen = StrLen(SerialNumber);
+  if (SerialNumStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SKU_NUMBER);
+  SkuNumber = SmbiosMiscGetString (TokenToGet);
+  SkuNumberStrLen = StrLen(SkuNumber);
+  if (SkuNumberStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_FAMILY_NAME1);
+  FamilyName = SmbiosMiscGetString (TokenToGet);
+  FamilyNameStrLen = StrLen(FamilyName);
+  if (FamilyNameStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE1) + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + SkuNumberStrLen + 1 + FamilyNameStrLen + 1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE1) + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + SkuNumberStrLen + 1 + FamilyNameStrLen + 1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_INFORMATION;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE1);
+
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle = 0;
+
+  //
+  // Manu will be the 1st optional string following the formatted structure.
+  //
+  SmbiosRecord->Manufacturer = 1;
+
+  //
+  // ProductName will be the 2nd optional string following the formatted structure.
+  //
+  SmbiosRecord->ProductName = 2;
+
+  //
+  // Version will be the 3rd optional string following the formatted structure.
+  //
+  SmbiosRecord->Version = 3;
+
+  //
+  // Version will be the 4th optional string following the formatted structure.
+  //
+  SmbiosRecord->SerialNumber = 4;
+
+  SmbiosRecord->SKUNumber= 5;
+  SmbiosRecord->Family= 6;
+
+  //
+  // Unique UUID
+  //
+  ForType1InputData->SystemUuid.Data1 = PcdGet32 (PcdProductSerialNumber);
+  ForType1InputData->SystemUuid.Data4[0] = PcdGet8 (PcdEmmcManufacturerId);
+
+  CopyMem ((UINT8 *) (&SmbiosRecord->Uuid),&ForType1InputData->SystemUuid,16);
+
+  SmbiosRecord->WakeUpType = (UINT8)ForType1InputData->SystemWakeupType;
+
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  UnicodeStrToAsciiStr(Manufacturer, OptionalStrStart);
+  UnicodeStrToAsciiStr(ProductName, OptionalStrStart + ManuStrLen + 1);
+  UnicodeStrToAsciiStr(Version, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1);
+  UnicodeStrToAsciiStr(SerialNumber, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1);
+
+  UnicodeStrToAsciiStr(SkuNumber, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 +  VerStrLen + 1 + SerialNumStrLen + 1);
+  UnicodeStrToAsciiStr(FamilyName, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + SkuNumberStrLen +1);
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+  FreePool(SmbiosRecord);
+  return Status;
+}
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscSystemManufacturer (Type 1).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscSystemManufacturer)
+{
+  EFI_STATUS                    Status;
+  static BOOLEAN                CallbackIsInstalledManu = FALSE;
+  VOID                           *AddSmbiosManuCallbackNotifyReg;
+  EFI_EVENT                      AddSmbiosManuCallbackEvent;
+
+
+  if (CallbackIsInstalledManu == FALSE) {
+    CallbackIsInstalledManu = TRUE;        	// Prevent more than 1 callback.
+    DEBUG ((EFI_D_INFO, "Create Smbios Manu callback.\n"));
+
+  //
+  // gEfiDxeSmmReadyToLockProtocolGuid is ready
+  //
+  Status = gBS->CreateEvent (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  (EFI_EVENT_NOTIFY)AddSmbiosManuCallback,
+                  RecordData,
+                  &AddSmbiosManuCallbackEvent
+                  );
+
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    return Status;
+
+  }
+
+  Status = gBS->RegisterProtocolNotify (
+                  &gEfiDxeSmmReadyToLockProtocolGuid,
+                  AddSmbiosManuCallbackEvent,
+                  &AddSmbiosManuCallbackNotifyReg
+                  );
+
+  return Status;
+  }
+
+  return EFI_SUCCESS;
+
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionString.uni b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionString.uni
new file mode 100644
index 0000000000..a90fa93cd6
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionString.uni
@@ -0,0 +1,24 @@
+// *++
+//
+// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// 
+// Module Name:
+//
+//   MiscSystemOptionString.uni
+// 
+// Abstract:
+// 
+//   System option language
+// 
+// Revision History:
+// 
+// --*/
+
+
+/=#
+
+#langdef en-US "English"
+
+#string STR_MISC_SYSTEM_OPTION_EN_US   #language en-US  "English (US)"
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStringData.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStringData.c
new file mode 100644
index 0000000000..e8d5fb3ee9
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStringData.c
@@ -0,0 +1,31 @@
+/** @file
+
+Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscSystemOptionStringData.c
+
+Abstract:
+
+  Static data of System option string.
+  System option string is Miscellaneous subclass type: 10 and SMBIOS type: 13.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_OPTION_STRING_DATA, SystemOptionString)
+= { STRING_TOKEN(STR_MISC_SYSTEM_OPTION_EN_US) };
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStringFunction.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStringFunction.c
new file mode 100644
index 0000000000..ee27a75e3a
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStringFunction.c
@@ -0,0 +1,93 @@
+/*++
+
+Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscSystemOptionStringFunction.c
+
+Abstract:
+
+  BIOS system option string boot time changes.
+  SMBIOS type 12.
+
+--*/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscSystemOptionString (Type 12).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(SystemOptionString)
+{
+  CHAR8                             *OptionalStrStart;
+  UINTN                             OptStrLen;
+  EFI_STRING                        OptionString;
+  EFI_STATUS                        Status;
+  STRING_REF                        TokenToGet;
+  EFI_SMBIOS_HANDLE                 SmbiosHandle;
+  SMBIOS_TABLE_TYPE12               *SmbiosRecord;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_OPTION_EN_US);
+  OptionString = SmbiosMiscGetString (TokenToGet);
+  OptStrLen = StrLen(OptionString);
+  if (OptStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE12) + OptStrLen + 1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE12) + OptStrLen + 1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_CONFIGURATION_OPTIONS;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE12);
+
+  //
+  // Make handle chosen by smbios protocol.add automatically.
+  //
+  SmbiosRecord->Hdr.Handle = 0;
+
+  SmbiosRecord->StringCount = 1;
+  OptionalStrStart = (CHAR8*) (SmbiosRecord + 1);
+  UnicodeStrToAsciiStr(OptionString, OptionalStrStart);
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+
+  FreePool(SmbiosRecord);
+  return Status;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignation.uni b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignation.uni
new file mode 100644
index 0000000000..f1d3e866e7
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignation.uni
@@ -0,0 +1,34 @@
+// *++
+//
+// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// 
+// Module Name:
+//
+//   MiscSystemSlotDesignation.uni
+// 
+// Abstract:
+// 
+//   System slot information
+// 
+// Revision History:
+// 
+// --*/
+
+
+/=#
+
+#langdef en-US "English"
+#string STR_MISC_SYSTEM_SLOT_PCIEX16    #language en-US  "PCIE X16 SLOT"
+#string STR_MISC_SYSTEM_SLOT_PCIEX16_1  #language en-US  "PCIE X16 SLOT 1"
+#string STR_MISC_SYSTEM_SLOT_PCIEX16_2  #language en-US  "PCIE X16 SLOT 2"
+#string STR_MISC_SYSTEM_SLOT_PCIEX4     #language en-US  "PCIE X4 SLOT"
+#string STR_MISC_SYSTEM_SLOT_PCIEX1_1   #language en-US  "PCIE X1 SLOT 1"
+#string STR_MISC_SYSTEM_SLOT_PCIEX1_2   #language en-US  "PCIE X1 SLOT 2"
+#string STR_MISC_SYSTEM_SLOT_PCIEX1_3   #language en-US  "PCIE X1 SLOT 3"
+#string STR_MISC_SYSTEM_SLOT_PCI1       #language en-US  "PCI SLOT 1"
+#string STR_MISC_SYSTEM_SLOT_PCI2       #language en-US  "PCI SLOT 2"
+#string STR_MISC_SYSTEM_SLOT_PCI3       #language en-US  "PCI SLOT 3"
+
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignationData.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignationData.c
new file mode 100644
index 0000000000..48beeb52d3
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignationData.c
@@ -0,0 +1,246 @@
+/** @file
+
+Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+    MiscSystemSlotDesignationData.c
+
+Abstract:
+
+  Static data of System Slot Designation.
+  System Slot Designation is Misc. subclass type 7 and SMBIOS type 9.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "MiscSubclassDriver.h"
+
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA, MiscSystemSlotPCIEx16Slot1) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT_PCIEX16_1),    // SlotDesignation
+  EfiSlotTypePciExpress,        // SlotType
+  EfiSlotDataBusWidth16xOrx16,  // SlotDataBusWidth
+  EfiSlotUsageAvailable,        // SlotUsage
+  EfiSlotLengthShort,           // SlotLength
+  0x06,                         // SlotId
+  {                             // SlotCharacteristics
+    0,                          // CharacteristicsUnknown  :1;
+    0,                          // Provides50Volts         :1;
+    1,                          // Provides33Volts         :1;
+    0,                          // SharedSlot              :1;
+    0,                          // PcCard16Supported       :1;
+    0,                          // CardBusSupported        :1;
+    0,                          // ZoomVideoSupported      :1;
+    0,                          // ModemRingResumeSupported:1;
+    0,                          // PmeSignalSupported      :1;
+    0,                          // HotPlugDevicesSupported :1;
+    0,                          // SmbusSignalSupported    :1;
+    0                           // Reserved                :21;
+  },
+  0                             // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA, MiscSystemSlotPCIEx16Slot2) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT_PCIEX16_2),    // SlotDesignation
+  EfiSlotTypePciExpress,        // SlotType
+  EfiSlotDataBusWidth16xOrx16,  // SlotDataBusWidth
+  EfiSlotUsageAvailable,        // SlotUsage
+  EfiSlotLengthShort,           // SlotLength
+  0x04,                         // SlotId
+  {                             // SlotCharacteristics
+    0,                          // CharacteristicsUnknown  :1;
+    0,                          // Provides50Volts         :1;
+    1,                          // Provides33Volts         :1;
+    0,                          // SharedSlot              :1;
+    0,                          // PcCard16Supported       :1;
+    0,                          // CardBusSupported        :1;
+    0,                          // ZoomVideoSupported      :1;
+    0,                          // ModemRingResumeSupported:1;
+    0,                          // PmeSignalSupported      :1;
+    0,                          // HotPlugDevicesSupported :1;
+    0,                          // SmbusSignalSupported    :1;
+    0                           // Reserved                :21;
+  },
+  0                             // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA, MiscSystemSlotPCIEx4) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT_PCIEX4),    // SlotDesignation
+  EfiSlotTypePciExpress,        // SlotType
+  EfiSlotDataBusWidth4xOrx4,  // SlotDataBusWidth
+  EfiSlotUsageAvailable,        // SlotUsage
+  EfiSlotLengthShort,           // SlotLength
+  0x03,                         // SlotId
+  {                             // SlotCharacteristics
+    0,                          // CharacteristicsUnknown  :1;
+    0,                          // Provides50Volts         :1;
+    1,                          // Provides33Volts         :1;
+    0,                          // SharedSlot              :1;
+    0,                          // PcCard16Supported       :1;
+    0,                          // CardBusSupported        :1;
+    0,                          // ZoomVideoSupported      :1;
+    0,                          // ModemRingResumeSupported:1;
+    0,                          // PmeSignalSupported      :1;
+    0,                          // HotPlugDevicesSupported :1;
+    0,                          // SmbusSignalSupported    :1;
+    0                           // Reserved                :21;
+  },
+  0                             // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA, MiscSystemSlotPCIEx1Slot1) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT_PCIEX1_1),    // SlotDesignation
+  EfiSlotTypePciExpress,        // SlotType
+  EfiSlotDataBusWidth1xOrx1,    // SlotDataBusWidth
+  EfiSlotUsageAvailable,        // SlotUsage
+  EfiSlotLengthShort,           // SlotLength
+  0x02,                         // SlotId
+  {                             // SlotCharacteristics
+    0,                          // CharacteristicsUnknown  :1;
+    0,                          // Provides50Volts         :1;
+    1,                          // Provides33Volts         :1;
+    0,                          // SharedSlot              :1;
+    0,                          // PcCard16Supported       :1;
+    0,                          // CardBusSupported        :1;
+    0,                          // ZoomVideoSupported      :1;
+    0,                          // ModemRingResumeSupported:1;
+    1,                          // PmeSignalSupported      :1;
+    0,                          // HotPlugDevicesSupported :1;
+    1,                          // SmbusSignalSupported    :1;
+    0                           // Reserved                :21;
+  },
+  0                             // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA, MiscSystemSlotPCIEx1Slot2) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT_PCIEX1_2),    // SlotDesignation
+  EfiSlotTypePciExpress,        // SlotType
+  EfiSlotDataBusWidth1xOrx1,    // SlotDataBusWidth
+  EfiSlotUsageAvailable,        // SlotUsage
+  EfiSlotLengthShort,           // SlotLength
+  0x15,                         // SlotId
+  {                             // SlotCharacteristics
+    0,                          // CharacteristicsUnknown  :1;
+    0,                          // Provides50Volts         :1;
+    1,                          // Provides33Volts         :1;
+    0,                          // SharedSlot              :1;
+    0,                          // PcCard16Supported       :1;
+    0,                          // CardBusSupported        :1;
+    0,                          // ZoomVideoSupported      :1;
+    0,                          // ModemRingResumeSupported:1;
+    1,                          // PmeSignalSupported      :1;
+    0,                          // HotPlugDevicesSupported :1;
+    1,                          // SmbusSignalSupported    :1;
+    0                           // Reserved                :21;
+  },
+  0                             // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA, MiscSystemSlotPCIEx1Slot3) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT_PCIEX1_3),    // SlotDesignation
+  EfiSlotTypePciExpress,        // SlotType
+  EfiSlotDataBusWidth1xOrx1,    // SlotDataBusWidth
+  EfiSlotUsageAvailable,        // SlotUsage
+  EfiSlotLengthShort,           // SlotLength
+  0x16,                         // SlotId
+  {                             // SlotCharacteristics
+    0,                          // CharacteristicsUnknown  :1;
+    0,                          // Provides50Volts         :1;
+    1,                          // Provides33Volts         :1;
+    0,                          // SharedSlot              :1;
+    0,                          // PcCard16Supported       :1;
+    0,                          // CardBusSupported        :1;
+    0,                          // ZoomVideoSupported      :1;
+    0,                          // ModemRingResumeSupported:1;
+    1,                          // PmeSignalSupported      :1;
+    0,                          // HotPlugDevicesSupported :1;
+    1,                          // SmbusSignalSupported    :1;
+    0                           // Reserved                :21;
+  },
+  0                             // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA, MiscSystemSlotPCI1) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT_PCI1),    // SlotDesignation
+  EfiSlotTypePci,               // SlotType
+  EfiSlotDataBusWidth32Bit,     // SlotDataBusWidth
+  EfiSlotUsageAvailable,        // SlotUsage
+  EfiSlotLengthLong ,           // SlotLength
+  0x07,                         // SlotId
+  {                             // SlotCharacteristics
+    0,                          // CharacteristicsUnknown  :1;
+    0,                          // Provides50Volts         :1;
+    1,                          // Provides33Volts         :1;
+    0,                          // SharedSlot              :1;
+    0,                          // PcCard16Supported       :1;
+    0,                          // CardBusSupported        :1;
+    0,                          // ZoomVideoSupported      :1;
+    0,                          // ModemRingResumeSupported:1;
+    1,                          // PmeSignalSupported      :1;
+    0,                          // HotPlugDevicesSupported :1;
+    1,                          // SmbusSignalSupported    :1;
+    0                           // Reserved                :21;
+  },
+  0                             // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA, MiscSystemSlotPCI2) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT_PCI2),    // SlotDesignation
+  EfiSlotTypePci,               // SlotType
+  EfiSlotDataBusWidth32Bit,     // SlotDataBusWidth
+  EfiSlotUsageAvailable,        // SlotUsage
+  EfiSlotLengthLong ,           // SlotLength
+  0x18,                         // SlotId
+  {                             // SlotCharacteristics
+    0,                          // CharacteristicsUnknown  :1;
+    0,                          // Provides50Volts         :1;
+    1,                          // Provides33Volts         :1;
+    0,                          // SharedSlot              :1;
+    0,                          // PcCard16Supported       :1;
+    0,                          // CardBusSupported        :1;
+    0,                          // ZoomVideoSupported      :1;
+    0,                          // ModemRingResumeSupported:1;
+    1,                          // PmeSignalSupported      :1;
+    0,                          // HotPlugDevicesSupported :1;
+    1,                          // SmbusSignalSupported    :1;
+    0                           // Reserved                :21;
+  },
+  0                             // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA, MiscSystemSlotPCI3) = {
+  STRING_TOKEN(STR_MISC_SYSTEM_SLOT_PCI3),    // SlotDesignation
+  EfiSlotTypePci,               // SlotType
+  EfiSlotDataBusWidth32Bit,     // SlotDataBusWidth
+  EfiSlotUsageAvailable,        // SlotUsage
+  EfiSlotLengthLong ,           // SlotLength
+  0x17,                         // SlotId
+  {                             // SlotCharacteristics
+    0,                          // CharacteristicsUnknown  :1;
+    0,                          // Provides50Volts         :1;
+    1,                          // Provides33Volts         :1;
+    0,                          // SharedSlot              :1;
+    0,                          // PcCard16Supported       :1;
+    0,                          // CardBusSupported        :1;
+    0,                          // ZoomVideoSupported      :1;
+    0,                          // ModemRingResumeSupported:1;
+    1,                          // PmeSignalSupported      :1;
+    0,                          // HotPlugDevicesSupported :1;
+    1,                          // SmbusSignalSupported    :1;
+    0                           // Reserved                :21;
+  },
+  0                             // SlotDevicePath
+};
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignationFunction.c b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignationFunction.c
new file mode 100644
index 0000000000..7270ef826f
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignationFunction.c
@@ -0,0 +1,127 @@
+/*++
+
+Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+  MiscSystemSlotDesignatorFunction.c
+
+Abstract:
+
+  BIOS system slot designator information boot time changes.
+  SMBIOS type 9.
+
+--*/
+
+#include "MiscSubclassDriver.h"
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscSystemSlotDesignator structure (Type 9).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscSystemSlotDesignation)
+{
+  CHAR8                              *OptionalStrStart;
+  UINTN                              SlotDesignationStrLen;
+  EFI_STATUS                         Status;
+  EFI_STRING                         SlotDesignation;
+  STRING_REF                         TokenToGet;
+  SMBIOS_TABLE_TYPE9                 *SmbiosRecord;
+  EFI_SMBIOS_HANDLE                  SmbiosHandle;
+  EFI_MISC_SYSTEM_SLOT_DESIGNATION*  ForType9InputData;
+
+  ForType9InputData = (EFI_MISC_SYSTEM_SLOT_DESIGNATION *)RecordData;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  TokenToGet = 0;
+  switch (ForType9InputData->SlotDesignation) {
+    case STR_MISC_SYSTEM_SLOT_PCIEX16_1:
+      TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SLOT_PCIEX16_1);
+      break;
+    case STR_MISC_SYSTEM_SLOT_PCIEX16_2:
+      TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SLOT_PCIEX16_2);
+      break;
+    case STR_MISC_SYSTEM_SLOT_PCIEX4:
+      TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SLOT_PCIEX4);
+      break;
+    case STR_MISC_SYSTEM_SLOT_PCIEX1_1:
+      TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SLOT_PCIEX1_1);
+      break;
+    case STR_MISC_SYSTEM_SLOT_PCIEX1_2:
+      TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SLOT_PCIEX1_2);
+      break;
+    case STR_MISC_SYSTEM_SLOT_PCIEX1_3:
+      TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SLOT_PCIEX1_3);
+      break;
+    case STR_MISC_SYSTEM_SLOT_PCI1:
+      TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SLOT_PCI1);
+      break;
+    case STR_MISC_SYSTEM_SLOT_PCI2:
+      TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SLOT_PCI2);
+      break;
+    case STR_MISC_SYSTEM_SLOT_PCI3:
+      TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SLOT_PCI3);
+      break;
+    default:
+      break;
+  }
+
+  SlotDesignation = SmbiosMiscGetString (TokenToGet);
+  SlotDesignationStrLen = StrLen(SlotDesignation);
+  if (SlotDesignationStrLen > SMBIOS_STRING_MAX_LENGTH) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE9) + SlotDesignationStrLen + 1 + 1);
+  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE9) +SlotDesignationStrLen + 1 + 1);
+
+  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_SLOTS;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE9);
+  SmbiosRecord->Hdr.Handle = 0;
+  SmbiosRecord->SlotDesignation = 1;
+  SmbiosRecord->SlotType = (UINT8)ForType9InputData->SlotType;
+  SmbiosRecord->SlotDataBusWidth = (UINT8)ForType9InputData->SlotDataBusWidth;
+  SmbiosRecord->CurrentUsage = (UINT8)ForType9InputData->SlotUsage;
+  SmbiosRecord->SlotLength = (UINT8)ForType9InputData->SlotLength;
+  SmbiosRecord->SlotID = ForType9InputData->SlotId;
+
+  //
+  // Slot Characteristics
+  //
+  CopyMem ((UINT8 *) &SmbiosRecord->SlotCharacteristics1,(UINT8 *) &ForType9InputData->SlotCharacteristics,2);
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  UnicodeStrToAsciiStr(SlotDesignation, OptionalStrStart);
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios-> Add(
+                      Smbios,
+                      NULL,
+                      &SmbiosHandle,
+                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+                      );
+  FreePool(SmbiosRecord);
+  return Status;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/SmBiosMiscDxe.inf b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/SmBiosMiscDxe.inf
new file mode 100644
index 0000000000..37e54a92a8
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/SmBiosMiscDxe.inf
@@ -0,0 +1,139 @@
+## @file
+# Component name for module MiscSubclass
+#
+# FIX ME!
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+#                                                                                  
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#                                                                                  
+#
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = MiscSubclass
+  FILE_GUID                      = 4EFFB560-B28B-4e57-9DAD-4344E32EA3BA
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = MiscSubclassDriverEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  MiscBaseBoardManufacturer.uni
+  MiscBaseBoardManufacturerData.c
+  MiscBaseBoardManufacturerFunction.c
+  MiscBiosVendor.uni
+  MiscBiosVendorData.c
+  MiscBiosVendorFunction.c
+  MiscBootInformationData.c
+  MiscBootInformationFunction.c
+  MiscChassisManufacturer.uni
+  MiscChassisManufacturerData.c
+  MiscChassisManufacturerFunction.c
+  MiscNumberOfInstallableLanguagesData.c
+  MiscNumberOfInstallableLanguagesFunction.c
+  MiscOemString.uni
+  MiscOemStringData.c
+  MiscOemStringFunction.c
+  MiscOnboardDevice.uni
+  MiscOnboardDeviceData.c
+  MiscOnboardDeviceFunction.c
+  MiscPortInternalConnectorDesignator.uni
+  MiscPortInternalConnectorDesignatorData.c
+  MiscPortInternalConnectorDesignatorFunction.c
+  MiscResetCapabilitiesData.c
+  MiscResetCapabilitiesFunction.c
+  MiscSystemLanguageString.uni
+  MiscSystemLanguageStringData.c
+  MiscSystemLanguageStringFunction.c
+  MiscSystemManufacturer.uni
+  MiscSystemManufacturerData.c
+  MiscSystemManufacturerFunction.c
+  MiscSystemOptionString.uni
+  MiscSystemOptionStringData.c
+  MiscSystemOptionStringFunction.c
+  MiscSystemSlotDesignation.uni
+  MiscSystemSlotDesignationData.c
+  MiscSystemSlotDesignationFunction.c
+  MiscSubclassDriver.h
+  MiscSubclassDriver.uni
+  MiscSubclassDriverDataTable.c
+  MiscSubclassDriverEntryPoint.c
+  CommonHeader.h
+  MiscOemType0x90Function.c
+  MiscOemType0x90Data.c
+  MiscOemType0x90.uni
+  MiscProcessorInformation.uni
+  MiscProcessorInformationData.c
+  MiscProcessorInformationFunction.c
+  MiscProcessorCache.uni
+  MiscProcessorCacheData.c
+  MiscProcessorCacheFunction.c
+  MiscPhysicalArray.uni
+  MiscPhysicalArrayData.c
+  MiscPhysicalArrayFunction.c
+  MiscMemoryDevice.uni
+  MiscMemoryDeviceData.c
+  MiscMemoryDeviceFunction.c
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  MdePkg/MdePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+
+[LibraryClasses]
+  HiiLib
+  DevicePathLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  UefiDriverEntryPoint
+  BaseMemoryLib
+  DebugLib
+  BaseLib
+  MemoryAllocationLib
+  PcdLib
+  UefiLib
+  BiosIdLib
+  PrintLib
+  CpuIA32Lib
+  PchPlatformLib
+  I2cLib
+  NetLib
+  HobLib
+  
+[Guids]
+  gEfiProcessorSubClassGuid
+  gEfiCacheSubClassGuid
+  gEfiNormalSetupGuid
+  gEfiPlatformInfoGuid
+  gEfiVlv2VariableGuid
+
+[Protocols]
+  gEfiSmbiosProtocolGuid                        # PROTOCOL ALWAYS_CONSUMED
+  gEfiDxeSmmReadyToLockProtocolGuid             # PROTOCOL ALWAYS_CONSUMED
+  gEfiDataHubProtocolGuid
+  gEfiMpServiceProtocolGuid
+  gMemInfoProtocolGuid
+  gEfiTdtOperationProtocolGuid
+  gDxePchPlatformPolicyProtocolGuid
+  gEfiSpiProtocolGuid
+  gEfiSimpleNetworkProtocolGuid
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareReleaseDateString
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
+  gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang
+  gEfiVLVTokenSpaceGuid.PcdEmmcManufacturerId
+  gEfiVLVTokenSpaceGuid.PcdProductSerialNumber
+
+[Depex]
+ gEfiSmbiosProtocolGuid AND gMemInfoProtocolGuid AND gEfiMpServiceProtocolGuid AND gEfiSimpleNetworkProtocolGuid
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchThunk/SmmSwDispatch2OnSmmSwDispatchThunk.c b/Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchThunk/SmmSwDispatch2OnSmmSwDispatchThunk.c
new file mode 100644
index 0000000000..0dbd6f00e1
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchThunk/SmmSwDispatch2OnSmmSwDispatchThunk.c
@@ -0,0 +1,459 @@
+/** @file
+  SMM SwDispatch2 Protocol on SMM SwDispatch Protocol Thunk driver.
+
+  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+**/
+
+#include <PiDxe.h>
+#include <FrameworkSmm.h>
+
+#include <Protocol/SmmSwDispatch2.h>
+#include <Protocol/SmmSwDispatch.h>
+#include <Protocol/SmmControl.h>
+#include <Protocol/SmmCpu.h>
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+
+typedef struct {
+  LIST_ENTRY                     Link;
+  EFI_HANDLE                     DispatchHandle;
+  UINTN                          SwSmiInputValue;
+  UINTN                          DispatchFunction;
+} EFI_SMM_SW_DISPATCH2_THUNK_CONTEXT;
+
+/**
+  Register a child SMI source dispatch function for the specified software SMI.
+
+  This service registers a function (DispatchFunction) which will be called when the software
+  SMI source specified by RegisterContext->SwSmiCpuIndex is detected. On return,
+  DispatchHandle contains a unique handle which may be used later to unregister the function
+  using UnRegister().
+
+  @param[in]  This                  Pointer to the EFI_SMM_SW_DISPATCH2_PROTOCOL instance.
+  @param[in]  DispatchFunction      Function to register for handler when the specified software
+                                    SMI is generated.
+  @param[in, out]  RegisterContext  Pointer to the dispatch function's context.
+                                    The caller fills this context in before calling
+                                    the register function to indicate to the register
+                                    function which Software SMI input value the
+                                    dispatch function should be invoked for.
+  @param[out] DispatchHandle        Handle generated by the dispatcher to track the
+                                    function instance.
+
+  @retval EFI_SUCCESS            The dispatch function has been successfully
+                                 registered and the SMI source has been enabled.
+  @retval EFI_DEVICE_ERROR       The SW driver was unable to enable the SMI source.
+  @retval EFI_INVALID_PARAMETER  RegisterContext is invalid. The SW SMI input value
+                                 is not within valid range.
+  @retval EFI_OUT_OF_RESOURCES   There is not enough memory (system or SMM) to manage this
+                                 child.
+  @retval EFI_OUT_OF_RESOURCES   A unique software SMI value could not be assigned
+                                 for this dispatch.
+**/
+EFI_STATUS
+EFIAPI
+SmmSwDispatch2Register (
+  IN  CONST EFI_SMM_SW_DISPATCH2_PROTOCOL  *This,
+  IN        EFI_SMM_HANDLER_ENTRY_POINT2   DispatchFunction,
+  IN  OUT   EFI_SMM_SW_REGISTER_CONTEXT    *RegisterContext,
+  OUT       EFI_HANDLE                     *DispatchHandle
+  );
+
+/**
+  Unregister a child SMI source dispatch function for the specified software SMI.
+
+  This service removes the handler associated with DispatchHandle so that it will no longer be
+  called in response to a software SMI.
+
+  @param[in] This                Pointer to the EFI_SMM_SW_DISPATCH2_PROTOCOL instance.
+  @param[in] DispatchHandle      Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS            The dispatch function has been successfully unregistered.
+  @retval EFI_INVALID_PARAMETER  The DispatchHandle was not valid.
+**/
+EFI_STATUS
+EFIAPI
+SmmSwDispatch2UnRegister (
+  IN CONST EFI_SMM_SW_DISPATCH2_PROTOCOL  *This,
+  IN       EFI_HANDLE                     DispatchHandle
+  );
+
+EFI_SMM_SW_DISPATCH2_PROTOCOL gSmmSwDispatch2 = {
+  SmmSwDispatch2Register,
+  SmmSwDispatch2UnRegister,
+  0 // MaximumSwiValue
+};
+
+EFI_SMM_SW_DISPATCH_PROTOCOL  *mSmmSwDispatch;
+UINT8                         mSmiTriggerRegister;
+UINT8                         mSmiDataRegister;
+
+EFI_SMM_CPU_PROTOCOL          *mSmmCpuProtocol;
+LIST_ENTRY                    mSmmSwDispatch2ThunkQueue = INITIALIZE_LIST_HEAD_VARIABLE (mSmmSwDispatch2ThunkQueue);
+
+/**
+  This function find SmmSwDispatch2Context by SwSmiInputValue.
+
+  @param SwSmiInputValue The SwSmiInputValue to indentify the SmmSwDispatch2 context
+
+  @return SmmSwDispatch2 context
+**/
+EFI_SMM_SW_DISPATCH2_THUNK_CONTEXT *
+FindSmmSwDispatch2ContextBySwSmiInputValue (
+  IN UINTN   SwSmiInputValue
+  )
+{
+  LIST_ENTRY                            *Link;
+  EFI_SMM_SW_DISPATCH2_THUNK_CONTEXT    *ThunkContext;
+
+  for (Link = mSmmSwDispatch2ThunkQueue.ForwardLink;
+    Link != &mSmmSwDispatch2ThunkQueue;
+    Link = Link->ForwardLink) {
+    ThunkContext = BASE_CR (
+                     Link,
+                     EFI_SMM_SW_DISPATCH2_THUNK_CONTEXT,
+                     Link
+                     );
+    if (ThunkContext->SwSmiInputValue == SwSmiInputValue) {
+      return ThunkContext;
+    }
+  }
+  return NULL;
+}
+
+/**
+  This function find SmmSwDispatch2Context by DispatchHandle.
+
+  @param DispatchHandle The DispatchHandle to indentify the SmmSwDispatch2Thunk context
+
+  @return SmmSwDispatch2Thunk context
+**/
+EFI_SMM_SW_DISPATCH2_THUNK_CONTEXT *
+FindSmmSwDispatch2ContextByDispatchHandle (
+  IN EFI_HANDLE   DispatchHandle
+  )
+{
+  LIST_ENTRY                            *Link;
+  EFI_SMM_SW_DISPATCH2_THUNK_CONTEXT    *ThunkContext;
+
+  for (Link = mSmmSwDispatch2ThunkQueue.ForwardLink;
+       Link != &mSmmSwDispatch2ThunkQueue;
+       Link = Link->ForwardLink) {
+    ThunkContext = BASE_CR (
+                     Link,
+                     EFI_SMM_SW_DISPATCH2_THUNK_CONTEXT,
+                     Link
+                     );
+    if (ThunkContext->DispatchHandle == DispatchHandle) {
+      return ThunkContext;
+    }
+  }
+  return NULL;
+}
+
+/**
+  Framework dispatch function for a Software SMI handler.
+
+  @param  DispatchHandle        The handle of this dispatch function.
+  @param  DispatchContext       The pointer to the dispatch function's context.
+                                The SwSmiInputValue field is filled in
+                                by the software dispatch driver prior to
+                                invoking this dispatch function.
+                                The dispatch function will only be called
+                                for input values for which it is registered.
+
+  @return None
+
+**/
+VOID
+EFIAPI
+FrameworkDispatchFunction (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  EFI_SMM_SW_DISPATCH_CONTEXT   *DispatchContext
+  )
+{
+  EFI_SMM_SW_DISPATCH2_THUNK_CONTEXT    *ThunkContext;
+  EFI_SMM_HANDLER_ENTRY_POINT2          DispatchFunction;
+  EFI_SMM_SW_REGISTER_CONTEXT           RegisterContext;
+  EFI_SMM_SW_CONTEXT                    SwContext;
+  UINTN                                 Size;
+  UINTN                                 Index;
+  EFI_SMM_SAVE_STATE_IO_INFO            IoInfo;
+  EFI_STATUS                            Status;
+
+  //
+  // Search context
+  //
+  ThunkContext = FindSmmSwDispatch2ContextBySwSmiInputValue (DispatchContext->SwSmiInputValue);
+  ASSERT (ThunkContext != NULL);
+  if (ThunkContext == NULL) {
+    return ;
+  }
+
+  //
+  // Construct new context
+  //
+  RegisterContext.SwSmiInputValue = DispatchContext->SwSmiInputValue;
+  Size = sizeof(SwContext);
+  SwContext.CommandPort = IoRead8 (mSmiTriggerRegister);
+  SwContext.DataPort    = IoRead8 (mSmiDataRegister);
+
+  //
+  // Try to find which CPU trigger SWSMI
+  //
+  SwContext.SwSmiCpuIndex = 0;
+  for (Index = 0; Index < gSmst->NumberOfCpus; Index++) {
+    Status = mSmmCpuProtocol->ReadSaveState (
+                                mSmmCpuProtocol,
+                                sizeof(IoInfo),
+                                EFI_SMM_SAVE_STATE_REGISTER_IO,
+                                Index,
+                                &IoInfo
+                                );
+    if (EFI_ERROR (Status)) {
+      continue;
+    }
+    if (IoInfo.IoPort == mSmiTriggerRegister) {
+      //
+      // Great! Find it.
+      //
+      SwContext.SwSmiCpuIndex = Index;
+      break;
+    }
+  }
+
+  //
+  // Dispatch
+  //
+  DispatchFunction = (EFI_SMM_HANDLER_ENTRY_POINT2)ThunkContext->DispatchFunction;
+  DispatchFunction (
+    DispatchHandle,
+    &RegisterContext,
+    &SwContext,
+    &Size
+    );
+  return ;
+}
+
+/**
+  Register a child SMI source dispatch function for the specified software SMI.
+
+  This service registers a function (DispatchFunction) which will be called when the software
+  SMI source specified by RegisterContext->SwSmiCpuIndex is detected. On return,
+  DispatchHandle contains a unique handle which may be used later to unregister the function
+  using UnRegister().
+
+  @param[in]  This                  Pointer to the EFI_SMM_SW_DISPATCH2_PROTOCOL instance.
+  @param[in]  DispatchFunction      Function to register for handler when the specified software
+                                    SMI is generated.
+  @param[in, out]  RegisterContext  Pointer to the dispatch function's context.
+                                    The caller fills this context in before calling
+                                    the register function to indicate to the register
+                                    function which Software SMI input value the
+                                    dispatch function should be invoked for.
+  @param[out] DispatchHandle        Handle generated by the dispatcher to track the
+                                    function instance.
+
+  @retval EFI_SUCCESS            The dispatch function has been successfully
+                                 registered and the SMI source has been enabled.
+  @retval EFI_DEVICE_ERROR       The SW driver was unable to enable the SMI source.
+  @retval EFI_INVALID_PARAMETER  RegisterContext is invalid. The SW SMI input value
+                                 is not within valid range.
+  @retval EFI_OUT_OF_RESOURCES   There is not enough memory (system or SMM) to manage this
+                                 child.
+  @retval EFI_OUT_OF_RESOURCES   A unique software SMI value could not be assigned
+                                 for this dispatch.
+**/
+EFI_STATUS
+EFIAPI
+SmmSwDispatch2Register (
+  IN  CONST EFI_SMM_SW_DISPATCH2_PROTOCOL  *This,
+  IN        EFI_SMM_HANDLER_ENTRY_POINT2   DispatchFunction,
+  IN  OUT   EFI_SMM_SW_REGISTER_CONTEXT    *RegisterContext,
+  OUT       EFI_HANDLE                     *DispatchHandle
+  )
+{
+  EFI_SMM_SW_DISPATCH2_THUNK_CONTEXT    *ThunkContext;
+  EFI_SMM_SW_DISPATCH_CONTEXT           DispatchContext;
+  EFI_STATUS                            Status;
+  UINTN                                 Index;
+
+  if (RegisterContext->SwSmiInputValue == (UINTN)-1) {
+    //
+    // If SwSmiInputValue is set to (UINTN) -1 then a unique value will be assigned and returned in the structure.
+    //
+    Status = EFI_NOT_FOUND;
+    for (Index = 1; Index < gSmmSwDispatch2.MaximumSwiValue; Index++) {
+      DispatchContext.SwSmiInputValue = Index;
+      Status = mSmmSwDispatch->Register (
+                                 mSmmSwDispatch,
+                                 FrameworkDispatchFunction,
+                                 &DispatchContext,
+                                 DispatchHandle
+                                 );
+      if (!EFI_ERROR (Status)) {
+        RegisterContext->SwSmiInputValue = Index;
+        break;
+      }
+    }
+    if (RegisterContext->SwSmiInputValue == (UINTN)-1) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+  } else {
+    DispatchContext.SwSmiInputValue = RegisterContext->SwSmiInputValue;
+    Status = mSmmSwDispatch->Register (
+                               mSmmSwDispatch,
+                               FrameworkDispatchFunction,
+                               &DispatchContext,
+                               DispatchHandle
+                               );
+  }
+  if (!EFI_ERROR (Status)) {
+    //
+    // Register
+    //
+    Status = gSmst->SmmAllocatePool (
+                      EfiRuntimeServicesData,
+                      sizeof(*ThunkContext),
+                      (VOID **)&ThunkContext
+                      );
+    ASSERT_EFI_ERROR (Status);
+    if (EFI_ERROR (Status)) {
+      mSmmSwDispatch->UnRegister (mSmmSwDispatch, *DispatchHandle);
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    ThunkContext->SwSmiInputValue  = RegisterContext->SwSmiInputValue;
+    ThunkContext->DispatchFunction = (UINTN)DispatchFunction;
+    ThunkContext->DispatchHandle   = *DispatchHandle;
+    InsertTailList (&mSmmSwDispatch2ThunkQueue, &ThunkContext->Link);
+  }
+
+  return Status;
+}
+
+/**
+  Unregister a child SMI source dispatch function for the specified software SMI.
+
+  This service removes the handler associated with DispatchHandle so that it will no longer be
+  called in response to a software SMI.
+
+  @param[in] This                Pointer to the EFI_SMM_SW_DISPATCH2_PROTOCOL instance.
+  @param[in] DispatchHandle      Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS            The dispatch function has been successfully unregistered.
+  @retval EFI_INVALID_PARAMETER  The DispatchHandle was not valid.
+**/
+EFI_STATUS
+EFIAPI
+SmmSwDispatch2UnRegister (
+  IN CONST EFI_SMM_SW_DISPATCH2_PROTOCOL  *This,
+  IN       EFI_HANDLE                     DispatchHandle
+  )
+{
+  EFI_SMM_SW_DISPATCH2_THUNK_CONTEXT    *ThunkContext;
+  EFI_STATUS                            Status;
+
+  Status = mSmmSwDispatch->UnRegister (mSmmSwDispatch, DispatchHandle);
+  if (!EFI_ERROR (Status)) {
+    //
+    // Unregister
+    //
+    ThunkContext = FindSmmSwDispatch2ContextByDispatchHandle (DispatchHandle);
+    ASSERT (ThunkContext != NULL);
+    if (ThunkContext != NULL) {
+      RemoveEntryList (&ThunkContext->Link);
+      gSmst->SmmFreePool (ThunkContext);
+    }
+  }
+
+  return Status;
+}
+
+/**
+  Entry Point for this thunk driver.
+
+  @param[in] ImageHandle  Image handle of this driver.
+  @param[in] SystemTable  A Pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS  The entry point is executed successfully.
+  @retval other        Some error occurred when executing this entry point.
+**/
+EFI_STATUS
+EFIAPI
+SmmSwDispatch2ThunkMain (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS               Status;
+  EFI_SMM_CONTROL_PROTOCOL *SmmControl;
+  EFI_SMM_CONTROL_REGISTER RegisterInfo;
+
+  //
+  // Locate Framework SMM SwDispatch Protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiSmmSwDispatchProtocolGuid,
+                  NULL,
+                  (VOID **)&mSmmSwDispatch
+                  );
+  ASSERT_EFI_ERROR (Status);
+  gSmmSwDispatch2.MaximumSwiValue = mSmmSwDispatch->MaximumSwiValue;
+  if (gSmmSwDispatch2.MaximumSwiValue == 0x0) {
+    DEBUG ((EFI_D_ERROR, "BUGBUG: MaximumSwiValue is 0, work-around to make it 0xFF\n"));
+    gSmmSwDispatch2.MaximumSwiValue = 0xFF;
+  }
+
+  //
+  // Locate Framework SMM Control Protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiSmmControlProtocolGuid,
+                  NULL,
+                  (VOID **)&SmmControl
+                  );
+
+  ASSERT_EFI_ERROR (Status);
+  Status = SmmControl->GetRegisterInfo (
+                         SmmControl,
+                         &RegisterInfo
+                         );
+  ASSERT_EFI_ERROR (Status);
+  mSmiTriggerRegister = RegisterInfo.SmiTriggerRegister;
+  mSmiDataRegister    = RegisterInfo.SmiDataRegister;
+
+  //
+  // Locate PI SMM CPU protocol
+  //
+  Status = gSmst->SmmLocateProtocol (
+                    &gEfiSmmCpuProtocolGuid,
+                    NULL,
+                    (VOID **)&mSmmCpuProtocol
+                    );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Publish PI SMM SwDispatch2 Protocol
+  //
+  ImageHandle = NULL;
+  Status = gSmst->SmmInstallProtocolInterface (
+                    &ImageHandle,
+                    &gEfiSmmSwDispatch2ProtocolGuid,
+                    EFI_NATIVE_INTERFACE,
+                    &gSmmSwDispatch2
+                    );
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchThunk/SmmSwDispatch2OnSmmSwDispatchThunk.inf b/Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchThunk/SmmSwDispatch2OnSmmSwDispatchThunk.inf
new file mode 100644
index 0000000000..4f95fc281e
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchThunk/SmmSwDispatch2OnSmmSwDispatchThunk.inf
@@ -0,0 +1,54 @@
+## @file
+#  Component description file for SMM SwDispatch2 Protocol on SMM SwDispatch Protocol Thunk driver.
+#
+#  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+#                                                                                  

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

+#
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SmmSwDispatch2OnSmmSwDispatchThunk
+  FILE_GUID                      = 1410C6AC-9F4B-495b-9C23-8A5AEB0165E9
+  MODULE_TYPE                    = DXE_SMM_DRIVER
+  VERSION_STRING                 = 1.0
+  PI_SPECIFICATION_VERSION       = 0x0001000A
+  ENTRY_POINT                    = SmmSwDispatch2ThunkMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  SmmSwDispatch2OnSmmSwDispatchThunk.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  SmmServicesTableLib
+  BaseLib
+  IoLib
+  DebugLib
+
+[Protocols]
+  gEfiSmmControlProtocolGuid               # PROTOCOL ALWAYS_CONSUMED
+  gEfiSmmSwDispatchProtocolGuid            # PROTOCOL ALWAYS_CONSUMED
+  gEfiSmmCpuProtocolGuid                   # PROTOCOL ALWAYS_CONSUMED
+  gEfiSmmSwDispatch2ProtocolGuid           # PROTOCOL ALWAYS_PRODUCED
+
+[Depex]
+  gEfiSmmSwDispatchProtocolGuid AND
+  gEfiSmmControlProtocolGuid AND
+  gEfiSmmCpuProtocolGuid
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.c b/Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.c
new file mode 100644
index 0000000000..de257b35b5
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.c
@@ -0,0 +1,164 @@
+/** @file
+  A helper driver to save information to SMRAM after SMRR is enabled.
+
+  This driver is for ECP platforms.
+
+  Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+**/
+
+#include <PiSmm.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Protocol/SmmSwDispatch.h>
+#include <Protocol/SmmReadyToLock.h>
+#include <Protocol/SmmControl.h>
+#include <Guid/Vlv2DeviceRefCodePkgTokenSpace.h>
+
+#define SMM_FROM_SMBASE_DRIVER        0x55
+#define SMM_FROM_CPU_DRIVER_SAVE_INFO 0x81
+
+#define EFI_SMRAM_CPU_NVS_HEADER_GUID \
+  { \
+    0x429501d9, 0xe447, 0x40f4, 0x86, 0x7b, 0x75, 0xc9, 0x3a, 0x1d, 0xb5, 0x4e \
+  }
+
+UINT8    mSmiDataRegister;
+BOOLEAN  mLocked = FALSE;
+EFI_GUID mSmramCpuNvsHeaderGuid = EFI_SMRAM_CPU_NVS_HEADER_GUID;
+
+/**
+  Dispatch function for a Software SMI handler.
+
+  @param  DispatchHandle        The handle of this dispatch function.
+  @param  DispatchContext       The pointer to the dispatch function's context.
+                                The SwSmiInputValue field is filled in
+                                by the software dispatch driver prior to
+                                invoking this dispatch function.
+                                The dispatch function will only be called
+                                for input values for which it is registered.
+
+  @return None
+
+**/
+VOID
+EFIAPI
+SmramSaveInfoHandler (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  EFI_SMM_SW_DISPATCH_CONTEXT   *DispatchContext
+  )
+{
+  ASSERT (DispatchContext != NULL);
+  ASSERT (DispatchContext->SwSmiInputValue == SMM_FROM_SMBASE_DRIVER);
+
+  if (!mLocked && IoRead8 (mSmiDataRegister) == SMM_FROM_CPU_DRIVER_SAVE_INFO) {
+      CopyMem (
+        (VOID *)(UINTN)(PcdGetEx64 (&gEfiVLVTokenSpaceGuid, PcdCpuLockBoxDataAddress)),
+        (VOID *)(UINTN)(PcdGetEx64 (&gEfiVLVTokenSpaceGuid, PcdCpuSmramCpuDataAddress)),
+        (UINTN)(PcdGetEx64 (&gEfiVLVTokenSpaceGuid, PcdCpuLockBoxSize))
+        );
+  }
+}
+
+/**
+  Smm Ready To Lock event notification handler.
+
+  It sets a flag indicating that SMRAM has been locked.
+
+  @param[in] Protocol   Points to the protocol's unique identifier.
+  @param[in] Interface  Points to the interface instance.
+  @param[in] Handle     The handle on which the interface was installed.
+
+  @retval EFI_SUCCESS   Notification handler runs successfully.
+ **/
+EFI_STATUS
+EFIAPI
+SmmReadyToLockEventNotify (
+  IN CONST EFI_GUID  *Protocol,
+  IN VOID            *Interface,
+  IN EFI_HANDLE      Handle
+  )
+{
+  mLocked = TRUE;
+  return EFI_SUCCESS;
+}
+
+/**
+  Entry point function of this driver.
+
+  @param[in] ImageHandle  The firmware allocated handle for the EFI image.
+  @param[in] SystemTable  A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS     The entry point is executed successfully.
+  @retval other           Some error occurs when executing this entry point.
+**/
+EFI_STATUS
+EFIAPI
+SmramSaveInfoHandlerSmmMain (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_SMM_SW_DISPATCH_PROTOCOL  *SmmSwDispatch;
+  EFI_SMM_SW_DISPATCH_CONTEXT   SmmSwDispatchContext;
+  EFI_HANDLE                    DispatchHandle;
+  EFI_SMM_CONTROL_PROTOCOL      *SmmControl;
+  EFI_SMM_CONTROL_REGISTER      SmmControlRegister;
+  VOID                          *Registration;
+
+  //
+  // Get SMI data register
+  //
+  Status = SystemTable->BootServices->LocateProtocol (
+                                        &gEfiSmmControlProtocolGuid,
+                                        NULL,
+                                        (VOID **)&SmmControl
+                                        );
+  ASSERT_EFI_ERROR (Status);
+  Status = SmmControl->GetRegisterInfo (SmmControl, &SmmControlRegister);
+  ASSERT_EFI_ERROR (Status);
+  mSmiDataRegister = SmmControlRegister.SmiDataRegister;
+
+  //
+  // Register software SMI handler
+  //
+
+  Status = SystemTable->BootServices->LocateProtocol (
+                                        &gEfiSmmSwDispatchProtocolGuid,
+                                        NULL,
+                                        (VOID **)&SmmSwDispatch
+                                        );
+  ASSERT_EFI_ERROR (Status);
+
+  SmmSwDispatchContext.SwSmiInputValue = SMM_FROM_SMBASE_DRIVER;
+  Status = SmmSwDispatch->Register (
+                            SmmSwDispatch,
+                            &SmramSaveInfoHandler,
+                            &SmmSwDispatchContext,
+                            &DispatchHandle
+                            );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Register SMM Ready To Lock Protocol notification
+  //
+  Status = gSmst->SmmRegisterProtocolNotify (
+                    &gEfiSmmReadyToLockProtocolGuid,
+                    SmmReadyToLockEventNotify,
+                    &Registration
+                    );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.inf b/Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.inf
new file mode 100644
index 0000000000..ec42c84472
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.inf
@@ -0,0 +1,60 @@
+## @file
+#
+#  A helper driver to save information to SMRAM after SMRR is enabled.
+#
+#  Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+#                                                                                  

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

+#
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SmramSaveInfoHandlerSmm
+  FILE_GUID                      = 63296C52-01CF-4eea-A47C-782A14DA6894
+  MODULE_TYPE                    = DXE_SMM_DRIVER
+  VERSION_STRING                 = 1.0
+  PI_SPECIFICATION_VERSION       = 0x0001000A
+
+  ENTRY_POINT                    = SmramSaveInfoHandlerSmmMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources.common]
+  SmramSaveInfoHandlerSmm.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  UefiRuntimeServicesTableLib
+  SmmServicesTableLib
+  BaseLib
+  BaseMemoryLib
+  IoLib
+
+[Protocols]
+  gEfiSmmSwDispatchProtocolGuid      ## CONSUMED
+  gEfiSmmControlProtocolGuid         ## CONSUMED
+  gEfiSmmReadyToLockProtocolGuid     ## CONSUMED
+
+[Pcd.common]
+  gEfiVLVTokenSpaceGuid.PcdCpuLockBoxDataAddress
+  gEfiVLVTokenSpaceGuid.PcdCpuSmramCpuDataAddress
+  gEfiVLVTokenSpaceGuid.PcdCpuLockBoxSize
+  
+[Depex]
+  gEfiSmmSwDispatchProtocolGuid AND
+  gEfiSmmControlProtocolGuid
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwSpare.bin b/Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwSpare.bin
new file mode 100644
index 0000000000000000000000000000000000000000..7145947da44cf9920d9c5933187dc96540ecd5ad
GIT binary patch
literal 262144
zcmeIuF#!Mo0K%aDspoA6h(KY$fB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
Wz<>b*1`HT5V8DO@0|pEj_<;c*e>=qh

literal 0
HcmV?d00001

diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwWorking.bin b/Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwWorking.bin
new file mode 100644
index 0000000000000000000000000000000000000000..dcb92498b93463a07d6dd695cf30ae9320414671
GIT binary patch
literal 8192
zcmeIuu?;{_6hP6R7(<~Jr73J+0f`|PLyL*bAV$#hh$$53R<}M?+0OkiHtW`<Yssgh
xKC?R__9A_~D*^-v5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAVA>f0uR>?&<Owl

literal 0
HcmV?d00001

diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageVariable.bin b/Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageVariable.bin
new file mode 100644
index 0000000000000000000000000000000000000000..7f8688b099f1e70491f16161a98c7b53c6b7a412
GIT binary patch
literal 253952
zcmeI%O^8iV902hDdt-csBz8*8MwpQ%hEhIe#*B&i$RPO$VW}uzu_4JqQj&ZwrdW)P
z5+x-IiKJ}A!oo+{Ai{p0^WKcd=;4Ktn%{Zd-g)Pq`#<OW?(M$r{YUgKN2h(ro!oU~
zY4@SY&BNBTcSH;?bXecCa&fL_NGy)2BT_@Qw>48dcu)1GOZ!foY3SNNeSF*P-N&y#
ztBBP-y}K{1m>(6zo~0|(Q}c#wMDyemXWJ%BX}wT)YkS<gHn$}@VrHz5hG>trXo{9-
zj@tCQCDoUu@3vSOjj=G6r%fR+umZVUIoEP^n#7!;5yQIPWuKlJv*6T>rjZlspPbHL
z%XQyf%dX^sJ!7I1AV6TS2$b{xG&W(Z8WnMOcGc!bvuc_TZW;Id!N<K-^|3X58e?PZ
zNSi`{009C72oNAZfB=C%7bxc$WlS2TI=wW0v8iU#&7Qlh=kDB?Hu3$rHBGU_6Uv{T
z0uctAK&HHR*R{!IbJ{L;TwZtJ^~=^{XYb$aez<mgXDmuNm=!7KvMB0PE~Y(YT>58a
z^8506n3h7OW&n7<CYy@E%Ue@=)e+~@y`<ss;kOswTwBuhYW}>sE2FzR)4gOz?2K*2
zc)zNYn8L3PDY^e|#VHy5A2pU<LrUQlOTI_xUd1l|NhR~cd1kI=Dr@6j>hQDG^z9y~
z)%1>?$qX-45^7(GY&M&pSeja)B|m=tR{^~!pYPDymZ|*G`0Z)>omr<iUo*ND#Q}%(
z#qXQK??f(jOim#{fB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk
z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs
z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ
zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U
zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7
z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N
z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+
z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly
zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF
z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk
z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs
z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ
zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U
zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7
z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N
z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+
z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly
zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF
z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk
z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs
x0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5Ev{1p8>TuLd5_8

literal 0
HcmV?d00001

diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_HEADER.bin b/Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_HEADER.bin
new file mode 100644
index 0000000000000000000000000000000000000000..ca10f7af61b91e1daf79e374c6c837ee06e6ea4c
GIT binary patch
literal 4096
zcmezW9~DF`{lL%6z{14FB*3k}pva)gz`%g4LWMy9C;|Z>aWISJKRYACe`XN-zdWjX
z5D!%Z*|dRYLwo`xSy+LDfCL}I0!K!u;9+(KhQmN#xdZtiJn*g^b-`!|jE2By2#kin
zXb6mkz-S1JhQMeDjE2By2oN6vhZMvZSQS_m-a9~P11Oy!4i;B{%R~6`9t;ek3Ze=M
WyCHnyZ5sS4?*qHCgWr|3bs+!{&RygH

literal 0
HcmV?d00001

diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_HEADER_SPILOCK.bin b/Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_HEADER_SPILOCK.bin
new file mode 100644
index 0000000000000000000000000000000000000000..f2dcb0067d1a48f08b4c4048362443b5c7095aa9
GIT binary patch
literal 4096
zcmezW9~DF`{lL%6z{14FB*3k}pva)gz`%g4LWMy9C;|Z>aWISJKRYACe`XN-zdWjX
zAWsTa1lhEKXG44fBw1L2gn$Ge!vaS}sNi9C28P2xU%3PMAUyD{9d*HI2#kinXb6mk
zz-S1JhQMeDjE2By2#kinXb2D=0*4gD7+4ip72Z2QX#*&oAPyE+fXhSp@*WHfq6(r4
X3cDeE;%yrID(?fkvV-51v~?i>7>iv0

literal 0
HcmV?d00001

diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/Vacant.bin b/Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/Vacant.bin
new file mode 100644
index 0000000000000000000000000000000000000000..12d359146014baad9277a951b237fd27e819db6e
GIT binary patch
literal 3928064
zcmeIuF#!Mo0K%aDspo45h(KY$fB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK
zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
rFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFz^EdVf>G}

literal 0
HcmV?d00001

diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat b/Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat
new file mode 100644
index 0000000000..200ca05a23
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat
@@ -0,0 +1,270 @@
+@REM @file
+@REM   Windows batch file to build BIOS ROM
+@REM
+@REM Copyright (c) 2006   - 2019, Intel Corporation. All rights reserved.<BR>
+@REM 
+@REM   SPDX-License-Identifier: BSD-2-Clause-Patent
+@REM
+
+@echo off
+SetLocal EnableDelayedExpansion EnableExtensions
+
+set PLATFORM_BIN_PACKAGE=%WORKSPACE%\Vlv2SocBinPkg
+if not exist %PLATFORM_BIN_PACKAGE% (
+  if defined PACKAGES_PATH (
+    for %%i IN (%PACKAGES_PATH%) DO (
+      if exist %%~fi\Vlv2SocBinPkg (
+        set PLATFORM_BIN_PACKAGE=%%~fi\Vlv2SocBinPkg
+        goto PlatformBinPackageFound
+      )
+    )
+  ) else (
+    echo.
+    echo !!! ERROR !!! Cannot find %PLATFORM_NAME% !!!
+    echo.
+    goto BldFail
+  )
+)
+:PlatformBinPackageFound
+
+
+:: Set script defaults
+set exitCode=0
+set BackupRom=1
+set UpdateVBios=1
+set SpiLock=0
+set Stitch_Config=Stitch_Config.txt
+copy /y nul Stitching.log >nul
+
+:: Set default Suffix as:  YYYY_MM_DD_HHMM
+set hour=%time: =0%
+reg copy "HKCU\Control Panel\International" "HKCU\Control Panel\International_Temp" /f >nul
+reg add "HKCU\Control Panel\International" /v sShortDate /d "yyyy_MM_dd" /f >nul
+for /f "tokens=1" %%i in ("%date%") do set today=%%i
+reg copy "HKCU\Control Panel\International_Temp" "HKCU\Control Panel\International" /f >nul
+reg delete "HKCU\Control Panel\International_Temp" /f >nul
+set IFWI_Suffix=%today%_%hour:~0,2%%time:~3,2%
+
+:: Process input arguments
+if "%~1"=="?"       goto Usage
+if "%~1"=="/?"      goto Usage
+if /i "%~1"=="Help" goto Usage
+
+:OptLoop
+if /i "%~1"=="/nV" (
+    set UpdateVBios=0
+    shift
+    goto OptLoop
+)
+if /i "%~1"=="/nB" (
+    set BackupRom=0
+    shift
+    goto OptLoop
+)
+if /i "%~1"=="/yL" (
+    set SpiLock=1
+    shift
+    goto OptLoop
+)
+
+if /i "%~1"=="/B" (
+    if "%~2"==""  goto Usage
+    if not exist %~2 echo BIOS not found. & goto Usage
+    set BIOS_Names=%~2
+    set BIOS_File_Name=%~n2
+    shift & shift
+    goto OptLoop
+)
+if /i "%~1"=="/C" (
+    if "%~2"==""  goto Usage
+    if not exist %~2 echo ConfigFile not found. & goto Usage
+    set Stitch_Config=%~2
+    shift & shift
+    goto OptLoop
+)
+if /i "%~1"=="/S" (
+    if "%~2"==""  goto Usage
+    set IFWI_Suffix=%~2
+    shift & shift
+    goto OptLoop
+)
+
+if "%BIOS_File_Name:~0,4%"=="MNW2" (
+   set Stitch_Config= MNW2_Stitch_Config.txt
+)
+if "%BIOS_File_Name:~3,4%"=="MNW2" (
+   set Stitch_Config= MNW2_Stitch_Config.txt
+)
+
+:: if no rom specified by user, search in ./ for ROM files
+if "%BIOS_Names%"=="" (
+    set "BIOS_Names= "
+    for /f "tokens=*" %%i in ('dir /b *.rom') do set BIOS_Names=!BIOS_Names! %%i
+    if "!BIOS_Names!"==" " (
+        echo NO .ROM files found !!!
+        goto Usage
+    )
+)
+
+:: Parse the Stitch_Config File
+if not exist %Stitch_Config% (
+    echo Stitch Configuration File %Stitch_Config% not found.
+    goto ScriptFail
+)
+for /f "delims== tokens=1,2" %%i in (%Stitch_Config%) do (
+    if /i "%%i"=="HEADER"      set IFWI_HEADER=%%j
+    if /i "%%i"=="SEC_VERSION" set SEC_VERSION=%%j
+    if /i "%%i"=="Source" (
+        if /i "%%j"=="ALPHA" set Source_Prefix=A_
+        if /i "%%j"=="BF" set Source_Prefix=BF_
+        if /i "%%j"=="BE" set Source_Prefix=BE_
+        if /i "%%j"=="PV" set Source_Prefix=PV_
+        if /i "%%j"=="PR1" set Source_Prefix=PR1_
+    )
+)
+
+if %SpiLock% EQU 1 (
+  set IFWI_HEADER_FILE=IFWIHeader\!IFWI_HEADER!_SPILOCK.bin
+) else (
+  set IFWI_HEADER_FILE=IFWIHeader\!IFWI_HEADER!.bin
+)
+
+:: **********************************************************************
+:: The Main Stitching Loop
+:: **********************************************************************
+echo %date%  %time% >>Stitching.log 2>&1
+echo %date%  %time%
+echo.
+for %%i in (%BIOS_Names%) do (
+
+    REM  ----- Do NOT use :: for comments Inside of code blocks() -------
+    set BIOS_Rom=%%i
+    set BIOS_Name=%%~ni
+    set BIOS_Version=!BIOS_Name:~-7,7!
+
+    REM extract PlatformType from BIOS filename
+    set Platform_Type=!BIOS_Name:~0,4!
+
+    REM Special treat for BayLake FFD8
+    set Temp_Name=!BIOS_Name:~0,7!
+
+
+    REM Capitalize and validate the Platform_Type
+    if /i "!Platform_Type!"=="MNW2" (
+        set Platform_Type=MNW2
+    ) else (
+        echo Error - Unsupported PlatformType: !Platform_Type!
+        goto Usage
+    )
+
+
+    REM search BIOS_Name for Arch substring:  either IA32 or X64
+    if not "!BIOS_Name!"=="!BIOS_Name:_IA32_=!" (
+        set Arch=IA32
+    ) else if not "!BIOS_Name!"=="!BIOS_Name:_X64_=!" (
+        set Arch=X64
+    ) else (
+        echo Error:  Could not determine Architecture for !BIOS_Rom!
+        goto Usage
+    )
+    set IFWI_Prefix=!Platform_Type!_IFWI_%Source_Prefix%!Arch!_!!BIOS_Version!
+
+    REM search BIOS_Name for Build_Target substring: either R or D
+    if not "!BIOS_Name!"=="!BIOS_Name:_R_=!" (
+        set Build_Target=Release
+        set IFWI_Prefix=!IFWI_Prefix!_R
+    ) else if not "!BIOS_Name!"=="!BIOS_Name:_D_=!" (
+        set Build_Target=Debug
+        set IFWI_Prefix=!IFWI_Prefix!_D
+    ) else (
+        echo Error:  Could not determine Build Target for !BIOS_Rom!
+        goto Usage
+    )
+
+    REM Create a BIOS backup before Stitching
+    if %BackupRom% EQU 1 (
+        echo Creating backup of original BIOS rom.
+        copy /y !BIOS_Rom! !BIOS_Rom!.orig >nul
+    )
+
+    echo.  >>Stitching.log
+    echo ********** Stitching !BIOS_Rom! **********  >>Stitching.log
+    echo.  >>Stitching.log
+    echo.
+    echo Stitching IFWI for !BIOS_Rom! ...
+    echo ---------------------------------------------------------------------------
+    echo IFWI  Header: !IFWI_HEADER_FILE!,   SEC version: !SEC_VERSION!,   
+    echo BIOS Version: !BIOS_Version!
+
+    echo Platform Type: !Platform_Type!,     IFWI Prefix: %BIOS_ID%
+    echo ---------------------------------------------------------------------------
+
+    echo -----------------------------
+    echo.
+    echo Generating IFWI... %BIOS_ID%.bin
+    echo.
+
+    copy /b/y !IFWI_HEADER_FILE! + %PLATFORM_BIN_PACKAGE%\SEC\!SEC_VERSION!\VLV_SEC_REGION.bin + %PLATFORM_BIN_PACKAGE%\SEC\!SEC_VERSION!\Vacant.bin + !BIOS_Rom! %BIOS_ID%.bin
+    echo.
+    echo ===========================================================================
+)
+@echo off
+
+::**********************************************************************
+:: end of main loop
+::**********************************************************************
+
+echo.
+echo  -- All specified ROM files Stitched. --
+echo.
+goto Exit
+
+:Usage
+echo.
+echo **************************************************************************************************
+echo This Script is used to Stitch together BIOS, GOP Driver, Microcode Patch and TXE FW
+echo into a single Integrated Firmware Image (IFWI).
+echo.
+echo Usage: IFWIStitch.bat [flags] [/B BIOS.ROM] [/C Stitch_Config] [/S IFWI_Suffix]
+echo.
+echo    This script has NO Required arguments, so that the user can just double click from the GUI.
+echo    However, this requires that the BIOS.ROM file name is formatted correctly.
+echo.
+echo    /nG             Do NOT update the GOP driver.  (applies to all ROM files for this run)
+echo    /nV             Do NOT update the VBIOS.       (applies to all ROM files for this run)
+echo    /nM             Do NOT update the Microcode.   (applies to all ROM files for this run)
+echo    /nB             Do NOT backup BIOS.ROMs. (Default will backup to BIOS.ROM.Orig)
+echo.
+echo    BIOS.ROM:       A single BIOS ROM file to use for stitching
+echo                    (DEFAULT: ALL .ROM files inside the current directory)
+echo    Stitch_Config:  Text file containing version info of each FW component
+echo                    (DEFAULT: Stitch_Config.txt)
+echo    IFWI_Suffix:    Suffix to append to the end of the IFWI filename
+echo                    (DEFAULT: YYYY_MM_DD_HHMM)
+echo.
+echo Examples:
+echo    IFIWStitch.bat                                      : Stitch all ROMs with defaults
+echo    IFIWStitch.bat /B C:/MyRoms/testBIOS.rom            : Stitch single ROM with defaults
+echo    IFIWStitch.bat /B ../testBIOS.rom /S test123        : Stitch single ROM and add custom suffix
+echo    IFIWStitch.bat /nM /nB /B testBIOS.rom /S test456   : Stitch single ROM, keep uCode from .rom,
+echo                                                          don't create backup, and add custom suffix.
+echo ****************************************************************************************************
+pause
+exit /b 1
+
+:ScriptFail
+set exitCode=1
+
+:Exit
+echo  -- See Stitching.log for more info. --
+echo.
+echo %date%  %time%
+echo.
+if "%Platform_Type%"=="MNW2" (
+  echo .
+) else (
+  echo only support MNW2 for this project!
+pause
+)
+exit /b %exitCode%
+EndLocal
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Stitch/MNW2_Stitch_Config.txt b/Platform/Intel/Vlv2TbltDevicePkg/Stitch/MNW2_Stitch_Config.txt
new file mode 100644
index 0000000000..82abe6548f
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Stitch/MNW2_Stitch_Config.txt
@@ -0,0 +1,10 @@
+#
+# Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+
+HEADER=IFWI_HEADER
+SEC_VERSION=1.0.2.1060v5
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c b/Platform/Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c
new file mode 100644
index 0000000000..3e58a6d22a
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c
@@ -0,0 +1,33 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+
+**/
+
+/**
+  The user Entry Point for Application. The user code starts with this function
+  as the real entry point for the image goes into a library that calls this
+  function.
+
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
+  @param[in] SystemTable    A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS       The entry point is executed successfully.
+  @retval other             Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeUserInterface (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf b/Platform/Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf
new file mode 100644
index 0000000000..f7a0a83b80
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf
@@ -0,0 +1,32 @@
+#
+#
+# Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
+#                                                                                  

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

+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = UiApp
+  FILE_GUID                      = 462CAA21-7614-4503-836E-8AB6F4662331
+  MODULE_TYPE                    = UEFI_APPLICATION
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = InitializeUserInterface
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  FrontPage.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  UefiApplicationEntryPoint
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.c b/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.c
new file mode 100644
index 0000000000..ba81bd9def
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.c
@@ -0,0 +1,929 @@
+
+/*++
+
+Copyright (c)  2011  - 2018, Intel Corporation. All rights reserved
+                                                                                   

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

+
+
+Module Name:
+
+  IgdOpRegion.c
+
+Abstract:
+
+  This is part of the implementation of an Intel Graphics drivers OpRegion /
+  Software SCI interface between system BIOS, ASL code, and Graphics drivers.
+  The code in this file will load the driver and initialize the interface
+
+  Supporting Specifiction: OpRegion / Software SCI SPEC 0.70
+
+  Acronyms:
+    IGD:        Internal Graphics Device
+    NVS:        ACPI Non Volatile Storage
+    OpRegion:   ACPI Operational Region
+    VBT:        Video BIOS Table (OEM customizable data)
+
+--*/
+
+//
+// Include files
+//
+
+
+#include "IgdOpRegion.h"
+#include "VlvPlatformInit.h"
+#include <FrameworkDxe.h>
+#include <Uefi.h>
+#include <PchRegs.h>
+
+#include <Guid/DataHubRecords.h>
+
+#include <Protocol/IgdOpRegion.h>
+#include <Protocol/FrameworkHii.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/PlatformGopPolicy.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/CpuIo.h>
+#include <Protocol/GlobalNvsArea.h>
+#include <Protocol/DxeSmmReadyToLock.h>
+#include <Protocol/PciRootBridgeIo.h>
+
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/IoLib.h>
+#include <Library/DevicePathLib.h>
+#include <Protocol/DriverBinding.h>
+#include <Library/PrintLib.h>
+#include <Library/BaseMemoryLib.h>
+
+
+
+UINT8 gSVER[12] = "Intel";
+
+extern DXE_VLV_PLATFORM_POLICY_PROTOCOL  *DxePlatformSaPolicy;
+
+//
+// Global variables
+//
+
+IGD_OPREGION_PROTOCOL mIgdOpRegion;
+EFI_GUID              mMiscSubClass = EFI_MISC_SUBCLASS_GUID;
+EFI_EVENT             mConOutEvent;
+EFI_EVENT             mSetGOPverEvent;
+VOID                  *mConOutReg;
+
+#define DEFAULT_FORM_BUFFER_SIZE    0xFFFF
+#ifndef ECP_FLAG
+#if 0
+/**
+
+  Get the HII protocol interface
+
+  @param Hii     HII protocol interface
+
+  @retval        Status code
+
+**/
+static
+EFI_STATUS
+GetHiiInterface (
+  OUT     EFI_HII_PROTOCOL    **Hii
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // There should only be one HII protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiHiiProtocolGuid,
+                  NULL,
+                  (VOID **) Hii
+                  );
+
+  return Status;;
+}
+#endif
+#endif
+
+/**
+
+  Get VBT data.
+
+  @param[in] VbtFileBuffer    Pointer to VBT data buffer.
+
+  @retval EFI_SUCCESS      VBT data was returned.
+  @retval EFI_NOT_FOUND    VBT data not found.
+  @exception EFI_UNSUPPORTED  Invalid signature in VBT data.
+
+**/
+EFI_STATUS
+GetIntegratedIntelVbtPtr (
+  OUT VBIOS_VBT_STRUCTURE **VbtFileBuffer
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_PHYSICAL_ADDRESS          VbtAddress = 0;
+  UINTN                         FvProtocolCount;
+  EFI_HANDLE                    *FvHandles;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL  *Fv;
+  UINTN                         Index;
+  UINT32                        AuthenticationStatus;
+
+  UINT8                         *Buffer;
+  UINTN                         VbtBufferSize = 0;
+
+  Buffer = 0;
+  FvHandles      = NULL;
+  *VbtFileBuffer = NULL;
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiFirmwareVolume2ProtocolGuid,
+                  NULL,
+                  &FvProtocolCount,
+                  &FvHandles
+                  );
+
+  if (!EFI_ERROR (Status)) {
+    for (Index = 0; Index < FvProtocolCount; Index++) {
+      Status = gBS->HandleProtocol (
+                      FvHandles[Index],
+                      &gEfiFirmwareVolume2ProtocolGuid,
+                      (VOID **) &Fv
+                      );
+      VbtBufferSize = 0;
+      Status = Fv->ReadSection (
+                     Fv,
+                     &gBmpImageGuid,
+                     EFI_SECTION_RAW,
+                     0,
+                    (void **)&Buffer,
+                     &VbtBufferSize,
+                     &AuthenticationStatus
+                     );
+
+      if (!EFI_ERROR (Status)) {
+        VbtAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
+        Status = EFI_SUCCESS;
+        break;
+      }
+    }
+  } else {
+    Status = EFI_NOT_FOUND;
+  }
+
+  if (FvHandles != NULL) {
+    FreePool(FvHandles);
+    FvHandles = NULL;
+  }
+
+
+  //
+  // Check VBT signature
+  //
+  *VbtFileBuffer = (VBIOS_VBT_STRUCTURE *) (UINTN) VbtAddress;
+  if (*VbtFileBuffer != NULL) {
+    if ((*((UINT32 *) ((*VbtFileBuffer)->HeaderSignature))) != VBT_SIGNATURE) {
+      if (*VbtFileBuffer != NULL) {
+        *VbtFileBuffer = NULL;
+      }
+      return EFI_UNSUPPORTED;
+    }
+    //
+    // Check VBT size
+    //
+    if ((*VbtFileBuffer)->HeaderVbtSize > VbtBufferSize) {
+      (*VbtFileBuffer)->HeaderVbtSize = (UINT16) VbtBufferSize;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+//
+// Function implementations.
+//
+/**
+
+  Get a pointer to an uncompressed image of the Intel video BIOS.
+
+  Note: This function would only be called if the video BIOS at 0xC000 is
+        missing or not an Intel video BIOS.  It may not be an Intel video BIOS
+        if the Intel graphic contoller is considered a secondary adapter.
+
+
+  @param VBiosROMImage  Pointer to an uncompressed Intel video BIOS.  This pointer must
+                        be set to NULL if an uncompressed image of the Intel Video BIOS
+                        is not obtainable.
+
+
+  @retval EFI_SUCCESS   VBiosPtr is updated.
+
+**/
+EFI_STATUS
+GetIntegratedIntelVBiosPtr (
+  INTEL_VBIOS_OPTION_ROM_HEADER **VBiosImage
+  )
+{
+  EFI_HANDLE                  *HandleBuffer;
+  UINTN                       HandleCount;
+  UINTN                       Index;
+  INTEL_VBIOS_PCIR_STRUCTURE  *PcirBlockPtr;
+  EFI_STATUS                  Status;
+  EFI_PCI_IO_PROTOCOL         *PciIo;
+  INTEL_VBIOS_OPTION_ROM_HEADER *VBiosRomImage;
+
+  //
+  // Set as if an umcompressed Intel video BIOS image was not obtainable.
+  //
+  VBiosRomImage = NULL;
+  *VBiosImage = NULL;
+
+  //
+  // Get all PCI IO protocols
+  //
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiPciIoProtocolGuid,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Find the video BIOS by checking each PCI IO handle for an Intel video
+  // BIOS OPROM.
+  //
+  for (Index = 0; Index < HandleCount; Index++) {
+    Status = gBS->HandleProtocol (
+                    HandleBuffer[Index],
+                    &gEfiPciIoProtocolGuid,
+                    (void **)&PciIo
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    VBiosRomImage = PciIo->RomImage;
+
+    //
+    // If this PCI device doesn't have a ROM image, skip to the next device.
+    //
+    if (!VBiosRomImage) {
+      continue;
+    }
+
+    //
+    // Get pointer to PCIR structure
+    //
+    PcirBlockPtr = (INTEL_VBIOS_PCIR_STRUCTURE *)((UINT8 *) VBiosRomImage + VBiosRomImage->PcirOffset);
+
+    //
+    // Check if we have an Intel video BIOS OPROM.
+    //
+    if ((VBiosRomImage->Signature == OPTION_ROM_SIGNATURE) &&
+        (PcirBlockPtr->VendorId == IGD_VID) &&
+        (PcirBlockPtr->ClassCode[0] == 0x00) &&
+        (PcirBlockPtr->ClassCode[1] == 0x00) &&
+        (PcirBlockPtr->ClassCode[2] == 0x03)
+       ) {
+      //
+      // Found Intel video BIOS.
+      //
+      *VBiosImage = VBiosRomImage;
+      return EFI_SUCCESS;
+    }
+  }
+
+  //
+  // No Intel video BIOS found.
+  //
+
+  //
+  // Free any allocated buffers
+  //
+  return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+SearchChildHandle(
+  EFI_HANDLE Father,
+  EFI_HANDLE *Child
+  )
+{
+  EFI_STATUS            Status;
+  UINTN                 HandleIndex;
+  EFI_GUID              **ProtocolGuidArray = NULL;
+  UINTN                 ArrayCount;
+  UINTN                 ProtocolIndex;
+  UINTN                 OpenInfoCount;
+  UINTN                 OpenInfoIndex;
+  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY  *OpenInfo = NULL;
+  UINTN                 mHandleCount;
+  EFI_HANDLE            *mHandleBuffer= NULL;
+
+  //
+  // Retrieve the list of all handles from the handle database
+  //
+  Status = gBS->LocateHandleBuffer (
+                  AllHandles,
+                  NULL,
+                  NULL,
+                  &mHandleCount,
+                  &mHandleBuffer
+                  );
+
+  for (HandleIndex = 0; HandleIndex < mHandleCount; HandleIndex++) {
+    //
+    // Retrieve the list of all the protocols on each handle
+    //
+    Status = gBS->ProtocolsPerHandle (
+                    mHandleBuffer[HandleIndex],
+                    &ProtocolGuidArray,
+                    &ArrayCount
+                    );
+    if (!EFI_ERROR (Status)) {
+      for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
+        Status = gBS->OpenProtocolInformation (
+                        mHandleBuffer[HandleIndex],
+                        ProtocolGuidArray[ProtocolIndex],
+                        &OpenInfo,
+                        &OpenInfoCount
+                        );
+        if (!EFI_ERROR (Status)) {
+          for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
+            if(OpenInfo[OpenInfoIndex].AgentHandle == Father) {
+              if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
+                *Child = mHandleBuffer[HandleIndex];
+                Status = EFI_SUCCESS;
+                goto TryReturn;
+              }
+            }
+          }
+          Status = EFI_NOT_FOUND;
+        }
+      }
+      if(OpenInfo != NULL) {
+        FreePool(OpenInfo);
+        OpenInfo = NULL;
+      }
+    }
+    FreePool (ProtocolGuidArray);
+    ProtocolGuidArray = NULL;
+  }
+TryReturn:
+  if(OpenInfo != NULL) {
+    FreePool (OpenInfo);
+    OpenInfo = NULL;
+  }
+  if(ProtocolGuidArray != NULL) {
+    FreePool(ProtocolGuidArray);
+    ProtocolGuidArray = NULL;
+  }
+  if(mHandleBuffer != NULL) {
+    FreePool (mHandleBuffer);
+    mHandleBuffer = NULL;
+  }
+  return Status;
+}
+
+EFI_STATUS
+JudgeHandleIsPCIDevice(
+  EFI_HANDLE            Handle,
+  UINT8                 Device,
+  UINT8                 Funs
+  )
+{
+  EFI_STATUS  Status;
+  EFI_DEVICE_PATH   *DPath;
+
+  Status = gBS->HandleProtocol (
+                  Handle,
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID **) &DPath
+                  );
+  if(!EFI_ERROR(Status)) {
+    while(!IsDevicePathEnd(DPath)) {
+      if((DPath->Type == HARDWARE_DEVICE_PATH) && (DPath->SubType == HW_PCI_DP)) {
+        PCI_DEVICE_PATH   *PCIPath;
+
+        PCIPath = (PCI_DEVICE_PATH*) DPath;
+        DPath = NextDevicePathNode(DPath);
+        if(IsDevicePathEnd(DPath) && (PCIPath->Device == Device) && (PCIPath->Function == Funs)) {
+          return EFI_SUCCESS;
+        }
+      } else {
+        DPath = NextDevicePathNode(DPath);
+      }
+    }
+  }
+  return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+GetDriverName(
+  EFI_HANDLE   Handle,
+  CHAR16         *GopVersion
+  )
+{
+  EFI_DRIVER_BINDING_PROTOCOL           *BindHandle = NULL;
+  EFI_STATUS                            Status;
+  UINT32                                Version;
+  UINT16                                *Ptr;
+
+  Status = gBS->OpenProtocol(
+                  Handle,
+                  &gEfiDriverBindingProtocolGuid,
+                  (VOID**)&BindHandle,
+                  NULL,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR(Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  Version = BindHandle->Version;
+  Ptr = (UINT16*)&Version;
+  UnicodeSPrint(GopVersion, 40, L"7.0.%04d", *(Ptr));
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetGOPDriverVersion(
+  CHAR16 *GopVersion
+  )
+{
+  UINTN                 HandleCount;
+  EFI_HANDLE            *Handles= NULL;
+  UINTN                 Index;
+  EFI_STATUS            Status;
+  EFI_HANDLE            Child = 0;
+
+  Status = gBS->LocateHandleBuffer(
+                  ByProtocol,
+                  &gEfiDriverBindingProtocolGuid,
+                  NULL,
+                  &HandleCount,
+                  &Handles
+                  );
+  for (Index = 0; Index < HandleCount ; Index++) {
+    Status = SearchChildHandle(Handles[Index], &Child);
+    if(!EFI_ERROR(Status)) {
+      Status = JudgeHandleIsPCIDevice(Child, 0x02, 0x00);
+      if(!EFI_ERROR(Status)) {
+        return GetDriverName(Handles[Index], GopVersion);
+      }
+    }
+  }
+  return EFI_UNSUPPORTED;
+}
+
+
+/**
+  Get Intel GOP driver version and copy it into IGD OpRegion GVER. This version
+  is picked up by IGD driver and displayed in CUI.
+
+  @param  Event             A pointer to the Event that triggered the callback.
+  @param  Context           A pointer to private data registered with the callback function.
+
+  @retval EFI_SUCCESS       Video BIOS VBT information returned.
+  @retval EFI_UNSUPPORTED   Could not find VBT information (*VBiosVbtPtr = NULL).
+
+**/
+EFI_STATUS
+EFIAPI
+SetGOPVersionCallback (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  CHAR16                GopVersion[16] = {0};
+  EFI_STATUS            Status;
+
+  Status = GetGOPDriverVersion(GopVersion);
+  if(!EFI_ERROR(Status)) {
+    StrCpy((CHAR16*)&(mIgdOpRegion.OpRegion->Header.GOPV[0]), GopVersion);
+    return Status;
+  }
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Get Intel video BIOS VBT information (i.e. Pointer to VBT and VBT size).
+  The VBT (Video BIOS Table) is a block of customizable data that is built
+  within the video BIOS and edited by customers.
+
+  @param  Event             A pointer to the Event that triggered the callback.
+  @param  Context           A pointer to private data registered with the callback function.
+
+  @retval EFI_SUCCESS       Video BIOS VBT information returned.
+  @retval EFI_UNSUPPORTED   Could not find VBT information (*VBiosVbtPtr = NULL).
+
+**/
+EFI_STATUS
+GetVBiosVbtCallback (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  INTEL_VBIOS_PCIR_STRUCTURE    *PcirBlockPtr;
+  UINT16                        PciVenderId;
+  UINT16                        PciDeviceId;
+  INTEL_VBIOS_OPTION_ROM_HEADER *VBiosPtr;
+  VBIOS_VBT_STRUCTURE           *VBiosVbtPtr;
+  VBIOS_VBT_STRUCTURE           *VbtFileBuffer = NULL;
+
+  VBiosPtr = (INTEL_VBIOS_OPTION_ROM_HEADER *)(UINTN)(VBIOS_LOCATION_PRIMARY);
+  PcirBlockPtr = (INTEL_VBIOS_PCIR_STRUCTURE *)((UINT8 *)VBiosPtr + VBiosPtr->PcirOffset);
+  PciVenderId = PcirBlockPtr->VendorId;
+  PciDeviceId = PcirBlockPtr->DeviceId;
+
+  //
+  // If the video BIOS is not at 0xC0000 or it is not an Intel video BIOS get
+  // the integrated Intel video BIOS (must be uncompressed).
+  //
+  if ((VBiosPtr->Signature != OPTION_ROM_SIGNATURE) || (PciVenderId != IGD_VID) || (PciDeviceId != IGD_DID_VLV)) {
+    GetIntegratedIntelVBiosPtr (&VBiosPtr);
+
+    if(VBiosPtr) {
+      //
+      // Video BIOS found.
+      //
+      PcirBlockPtr = (INTEL_VBIOS_PCIR_STRUCTURE *)((UINT8 *)VBiosPtr + VBiosPtr->PcirOffset);
+      PciVenderId = PcirBlockPtr->VendorId;
+      if( (VBiosPtr->Signature != OPTION_ROM_SIGNATURE) || (PciVenderId != IGD_VID)) {
+        //
+        // Intel video BIOS not found.
+        //
+        VBiosVbtPtr = NULL;
+        return EFI_UNSUPPORTED;
+      }
+    } else {
+      //
+      // No Video BIOS found, try to get VBT from FV.
+      //
+      GetIntegratedIntelVbtPtr (&VbtFileBuffer);
+      if (VbtFileBuffer != NULL) {
+        //
+        // Video BIOS not found, use VBT from FV
+        //
+        DEBUG ((EFI_D_ERROR, "VBT data found\n"));
+        (gBS->CopyMem) (
+                mIgdOpRegion.OpRegion->VBT.GVD1,
+                VbtFileBuffer,
+                VbtFileBuffer->HeaderVbtSize
+                );
+        FreePool (VbtFileBuffer);
+        return EFI_SUCCESS;
+      }
+    }
+    if ((VBiosPtr == NULL) ) {
+      //
+      // Intel video BIOS not found.
+      //
+      VBiosVbtPtr = NULL;
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  DEBUG ((EFI_D_ERROR, "VBIOS found at 0x%X\n", VBiosPtr));
+  VBiosVbtPtr = (VBIOS_VBT_STRUCTURE *) ((UINT8 *) VBiosPtr + VBiosPtr->VbtOffset);
+
+  if ((*((UINT32 *) (VBiosVbtPtr->HeaderSignature))) != VBT_SIGNATURE) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Initialize Video BIOS version with its build number.
+  //
+  mIgdOpRegion.OpRegion->Header.VVER[0] = VBiosVbtPtr->CoreBlockBiosBuild[0];
+  mIgdOpRegion.OpRegion->Header.VVER[1] = VBiosVbtPtr->CoreBlockBiosBuild[1];
+  mIgdOpRegion.OpRegion->Header.VVER[2] = VBiosVbtPtr->CoreBlockBiosBuild[2];
+  mIgdOpRegion.OpRegion->Header.VVER[3] = VBiosVbtPtr->CoreBlockBiosBuild[3];
+  (gBS->CopyMem) (
+          mIgdOpRegion.OpRegion->VBT.GVD1,
+          VBiosVbtPtr,
+          VBiosVbtPtr->HeaderVbtSize
+          );
+
+  //
+  // Return final status
+  //
+  return EFI_SUCCESS;
+}
+
+/**
+  Graphics OpRegion / Software SCI driver installation function.
+
+  @param ImageHandle     Handle for this drivers loaded image protocol.
+  @param SystemTable     EFI system table.
+
+  @retval EFI_SUCCESS    The driver installed without error.
+  @retval EFI_ABORTED    The driver encountered an error and could not complete
+                         installation of the ACPI tables.
+
+**/
+EFI_STATUS
+IgdOpRegionInit (
+  void
+  )
+{
+  EFI_HANDLE                    Handle;
+  EFI_STATUS                    Status;
+  EFI_GLOBAL_NVS_AREA_PROTOCOL  *GlobalNvsArea;
+  UINT32                        DwordData;
+  EFI_CPU_IO_PROTOCOL           *CpuIo;
+  UINT16                        Data16;
+  UINT16                        AcpiBase;
+  VOID                          *gConOutNotifyReg;
+
+
+  //
+  //  Locate the Global NVS Protocol.
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiGlobalNvsAreaProtocolGuid,
+                  NULL,
+                  (void **)&GlobalNvsArea
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Allocate an ACPI NVS memory buffer as the IGD OpRegion, zero initialize
+  // the first 1K, and set the IGD OpRegion pointer in the Global NVS
+  // area structure.
+  //
+  Status = (gBS->AllocatePool) (
+                   EfiACPIMemoryNVS,
+                   sizeof (IGD_OPREGION_STRUC),
+                  (void **)&mIgdOpRegion.OpRegion
+                   );
+  ASSERT_EFI_ERROR (Status);
+  (gBS->SetMem) (
+          mIgdOpRegion.OpRegion,
+          sizeof (IGD_OPREGION_STRUC),
+          0
+          );
+  GlobalNvsArea->Area->IgdOpRegionAddress = (UINT32)(UINTN)(mIgdOpRegion.OpRegion);
+
+  //
+  // If IGD is disabled return
+  //
+  if (IgdMmPci32 (0) == 0xFFFFFFFF) {
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Initialize OpRegion Header
+  //
+
+  (gBS->CopyMem) (
+          mIgdOpRegion.OpRegion->Header.SIGN,
+          HEADER_SIGNATURE,
+          sizeof(HEADER_SIGNATURE)
+          );
+
+
+  //
+  // Set OpRegion Size in KBs
+  //
+  mIgdOpRegion.OpRegion->Header.SIZE = HEADER_SIZE/1024;
+
+  //
+  // FIXME: Need to check Header OVER Field and the supported version.
+  //
+  mIgdOpRegion.OpRegion->Header.OVER = (UINT32) (LShiftU64 (HEADER_OPREGION_VER, 16) + LShiftU64 (HEADER_OPREGION_REV, 8));
+#ifdef ECP_FLAG
+  CopyMem(mIgdOpRegion.OpRegion->Header.SVER, gSVER, sizeof(gSVER));
+#else
+  gBS->CopyMem(
+         mIgdOpRegion.OpRegion->Header.SVER,
+         gSVER,
+         sizeof(gSVER)
+         );
+#endif
+  DEBUG ((EFI_D_ERROR, "System BIOS ID is %a\n", mIgdOpRegion.OpRegion->Header.SVER));
+
+
+  mIgdOpRegion.OpRegion->Header.MBOX = HEADER_MBOX_SUPPORT;
+
+  if( 1 == DxePlatformSaPolicy->IdleReserve) {
+    mIgdOpRegion.OpRegion->Header.PCON = (mIgdOpRegion.OpRegion->Header.PCON & 0xFFFC) | BIT1;
+  } else {
+    mIgdOpRegion.OpRegion->Header.PCON = (mIgdOpRegion.OpRegion->Header.PCON & 0xFFFC) | (BIT1 | BIT0);
+  }
+
+  //
+  //For graphics driver to identify if LPE Audio/HD Audio is enabled on the platform
+  //
+  mIgdOpRegion.OpRegion->Header.PCON &= AUDIO_TYPE_SUPPORT_MASK;
+  mIgdOpRegion.OpRegion->Header.PCON &= AUDIO_TYPE_FIELD_MASK;
+  if ( 1 == DxePlatformSaPolicy->AudioTypeSupport ) {
+    mIgdOpRegion.OpRegion->Header.PCON = HD_AUDIO_SUPPORT;
+    mIgdOpRegion.OpRegion->Header.PCON |= AUDIO_TYPE_FIELD_VALID;
+  }
+
+  //
+  // Initialize OpRegion Mailbox 1 (Public ACPI Methods).
+  //
+  //<TODO> The initial setting of mailbox 1 fields is implementation specific.
+  // Adjust them as needed many even coming from user setting in setup.
+  //
+  //Workaround to solve LVDS is off after entering OS in desktop platform
+  //
+  mIgdOpRegion.OpRegion->MBox1.CLID = DxePlatformSaPolicy->IgdPanelFeatures.LidStatus;
+
+  //
+  // Initialize OpRegion Mailbox 3 (ASLE Interrupt and Power Conservation).
+  //
+  //<TODO> The initial setting of mailbox 3 fields is implementation specific.
+  // Adjust them as needed many even coming from user setting in setup.
+  //
+
+  //
+  // Do not initialize TCHE. This field is written by the graphics driver only.
+  //
+
+  //
+  // The ALSI field is generally initialized by ASL code by reading the embedded controller.
+  //
+
+  mIgdOpRegion.OpRegion->MBox3.BCLP = BACKLIGHT_BRIGHTNESS;
+
+  mIgdOpRegion.OpRegion->MBox3.PFIT = (FIELD_VALID_BIT | PFIT_STRETCH);
+  if ( DxePlatformSaPolicy->IgdPanelFeatures.PFITStatus == 2) {
+  	//
+    // Center
+    //
+    mIgdOpRegion.OpRegion->MBox3.PFIT = (FIELD_VALID_BIT | PFIT_CENTER);
+  } else if (DxePlatformSaPolicy->IgdPanelFeatures.PFITStatus == 1) {
+  	//
+    // Stretch
+    //
+    mIgdOpRegion.OpRegion->MBox3.PFIT = (FIELD_VALID_BIT | PFIT_STRETCH);
+  } else {
+  	//
+    // Auto
+    //
+    mIgdOpRegion.OpRegion->MBox3.PFIT = (FIELD_VALID_BIT | PFIT_SETUP_AUTO);
+  }
+
+  //
+  // Set Initial current Brightness
+  //
+  mIgdOpRegion.OpRegion->MBox3.CBLV = (INIT_BRIGHT_LEVEL | FIELD_VALID_BIT);
+
+  //
+  // <EXAMPLE> Create a static Backlight Brightness Level Duty cycle Mapping Table
+  // Possible 20 entries (example used 10), each 16 bits as follows:
+  // [15] = Field Valid bit, [14:08] = Level in Percentage (0-64h), [07:00] = Desired duty cycle (0 - FFh).
+  //
+  //                                             %            Brightness
+  mIgdOpRegion.OpRegion->MBox3.BCLM[0]   = ( (  0 << 8 ) + ( 0xFF - 0xFC ) + WORD_FIELD_VALID_BIT);
+  mIgdOpRegion.OpRegion->MBox3.BCLM[1]   = ( (  1 << 8 ) + ( 0xFF - 0xFC ) + WORD_FIELD_VALID_BIT);
+  mIgdOpRegion.OpRegion->MBox3.BCLM[2]   = ( ( 10 << 8 ) + ( 0xFF - 0xE5 ) + WORD_FIELD_VALID_BIT);
+  mIgdOpRegion.OpRegion->MBox3.BCLM[3]   = ( ( 19 << 8 ) + ( 0xFF - 0xCE ) + WORD_FIELD_VALID_BIT);
+  mIgdOpRegion.OpRegion->MBox3.BCLM[4]   = ( ( 28 << 8 ) + ( 0xFF - 0xB7 ) + WORD_FIELD_VALID_BIT);
+  mIgdOpRegion.OpRegion->MBox3.BCLM[5]   = ( ( 37 << 8 ) + ( 0xFF - 0xA0 ) + WORD_FIELD_VALID_BIT);
+  mIgdOpRegion.OpRegion->MBox3.BCLM[6]   = ( ( 46 << 8 ) + ( 0xFF - 0x89 ) + WORD_FIELD_VALID_BIT);
+  mIgdOpRegion.OpRegion->MBox3.BCLM[7]   = ( ( 55 << 8 ) + ( 0xFF - 0x72 ) + WORD_FIELD_VALID_BIT);
+  mIgdOpRegion.OpRegion->MBox3.BCLM[8]   = ( ( 64 << 8 ) + ( 0xFF - 0x5B ) + WORD_FIELD_VALID_BIT);
+  mIgdOpRegion.OpRegion->MBox3.BCLM[9]   = ( ( 73 << 8 ) + ( 0xFF - 0x44 ) + WORD_FIELD_VALID_BIT);
+  mIgdOpRegion.OpRegion->MBox3.BCLM[10]  = ( ( 82 << 8 ) + ( 0xFF - 0x2D ) + WORD_FIELD_VALID_BIT);
+  mIgdOpRegion.OpRegion->MBox3.BCLM[11]  = ( ( 91 << 8 ) + ( 0xFF - 0x16 ) + WORD_FIELD_VALID_BIT);
+  mIgdOpRegion.OpRegion->MBox3.BCLM[12]  = ( (100 << 8 ) + ( 0xFF - 0x00 ) + WORD_FIELD_VALID_BIT);
+
+  mIgdOpRegion.OpRegion->MBox3.PCFT = ((UINT32) GlobalNvsArea->Area->IgdPowerConservation) | BIT31;
+  //
+  // Create the notification and register callback function on the PciIo installation,
+  //
+  //
+  Status = gBS->CreateEvent (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  (EFI_EVENT_NOTIFY)GetVBiosVbtCallback,
+                  NULL,
+                  &mConOutEvent
+                  );
+
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    return Status;
+
+  }
+
+  Status = gBS->RegisterProtocolNotify (
+#ifdef ECP_FLAG
+                  &gExitPmAuthProtocolGuid,
+#else
+                  &gEfiDxeSmmReadyToLockProtocolGuid,
+#endif
+                  mConOutEvent,
+                  &gConOutNotifyReg
+                  );
+
+  Status = gBS->CreateEvent (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  (EFI_EVENT_NOTIFY)SetGOPVersionCallback,
+                  NULL,
+                  &mSetGOPverEvent
+                  );
+
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = gBS->RegisterProtocolNotify (
+                  &gEfiGraphicsOutputProtocolGuid,
+                  mSetGOPverEvent,
+                  &gConOutNotifyReg
+                  );
+
+
+  //
+  // Initialize hardware state:
+  //   Set ASLS Register to the OpRegion physical memory address.
+  //   Set SWSCI register bit 15 to a "1" to activate SCI interrupts.
+  //
+
+  IgdMmPci32 (IGD_ASLS_OFFSET) = (UINT32)(UINTN)(mIgdOpRegion.OpRegion);
+  IgdMmPci16AndThenOr (IGD_SWSCI_OFFSET, ~(BIT0), BIT15);
+
+  DwordData = IgdMmPci32 (IGD_ASLS_OFFSET);
+  S3BootScriptSavePciCfgWrite (
+    S3BootScriptWidthUint32,
+    (UINTN) (EFI_PCI_ADDRESS  (IGD_BUS, IGD_DEV, IGD_FUN_0, IGD_ASLS_OFFSET)),
+    1,
+    &DwordData
+    );
+
+
+  DwordData = IgdMmPci32 (IGD_SWSCI_OFFSET);
+  S3BootScriptSavePciCfgWrite (
+    S3BootScriptWidthUint32,
+    (UINTN) (EFI_PCI_ADDRESS  (IGD_BUS, IGD_DEV, IGD_FUN_0, IGD_SWSCI_OFFSET)),
+    1,
+    &DwordData
+    );
+
+  AcpiBase =  MmPci16 (
+                0,
+                DEFAULT_PCI_BUS_NUMBER_PCH,
+                PCI_DEVICE_NUMBER_PCH_LPC,
+                PCI_FUNCTION_NUMBER_PCH_LPC,
+                R_PCH_LPC_ACPI_BASE
+                ) & B_PCH_LPC_ACPI_BASE_BAR;
+
+  //
+  // Find the CPU I/O Protocol.  ASSERT if not found.
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiCpuIoProtocolGuid,
+                  NULL,
+                  (void **)&CpuIo
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  CpuIo->Io.Read (
+              CpuIo,
+              EfiCpuIoWidthUint16,
+              AcpiBase + R_PCH_ACPI_GPE0a_STS,
+              1,
+              &Data16
+              );
+  //
+  // Clear the B_PCH_ACPI_GPE0a_STS_GUNIT_SCI bit in R_PCH_ACPI_GPE0a_STS by writing a '1'.
+  //
+  Data16 |= B_PCH_ACPI_GPE0a_STS_GUNIT_SCI;
+
+  CpuIo->Io.Write (
+              CpuIo,
+              EfiCpuIoWidthUint16,
+              AcpiBase + R_PCH_ACPI_GPE0a_STS,
+              1,
+              &Data16
+              );
+
+  //
+  // Install OpRegion / Software SCI protocol
+  //
+  Handle = NULL;
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Handle,
+                  &gIgdOpRegionProtocolGuid,
+                  &mIgdOpRegion,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Return final status
+  //
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.h b/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.h
new file mode 100644
index 0000000000..cd1d208d61
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.h
@@ -0,0 +1,235 @@
+
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+                                                                                   

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

+
+
+Module Name:
+
+  IgdOpRegion.h
+
+Abstract:
+
+  This is part of the implementation of an Intel Graphics drivers OpRegion /
+  Software SCI interface between system BIOS, ASL code, and Graphics drivers.
+
+  Supporting Specifiction: OpRegion / Software SCI SPEC 0.70
+
+  Acronyms:
+    IGD:        Internal Graphics Device
+    NVS:        ACPI Non Volatile Storage
+    OpRegion:   ACPI Operational Region
+    VBT:        Video BIOS Table (OEM customizable data)
+
+--*/
+
+#ifndef _IGD_OPREGION_H_
+#define _IGD_OPREGION_H_
+
+//
+// Statements that include other header files.
+//
+#include "VlvPlatformInit.h"
+#include "VlvCommonDefinitions.h"
+#include <Uefi/UefiInternalFormRepresentation.h>
+#include <FrameworkDxe.h>
+
+//
+//
+// OpRegion (Miscellaneous) #defines.
+//
+// OpRegion Header #defines.
+//
+
+#define HEADER_SIGNATURE    "IntelGraphicsMem"
+#define HEADER_SIZE         0x2000
+#define HEADER_OPREGION_VER 0x0200
+#define HEADER_OPREGION_REV 0x00
+
+//
+//For VLV Tablet, MailBOX2(SCI)is not supported.
+//
+#define HEADER_MBOX_SUPPORT (HD_MBOX4 + HD_MBOX3 + HD_MBOX1)
+#define HD_MBOX1            BIT0
+#define HD_MBOX2            BIT1
+#define HD_MBOX3            BIT2
+#define HD_MBOX4            BIT3
+#define HD_MBOX5            BIT4
+#define SVER_SIZE           32
+
+//
+//Audio Type support for VLV2 A0
+//
+#define AUDIO_TYPE_SUPPORT_MASK    0xFFFFFFF3
+#define NO_AUDIO_SUPPORT           (0<<2)
+#define HD_AUDIO_SUPPORT           (1<<2)
+#define LPE_AUDIO_SUPPORT          (2<<2)
+#define AUDIO_TYPE_FIELD_MASK      0xFFFFFFEF
+#define AUDIO_TYPE_FIELD_VALID     (1<<4)
+#define AUDIO_TYPE_FIELD_INVALID   (0<<4)
+
+//
+// OpRegion Mailbox 1 EQUates.
+//
+// OpRegion Mailbox 3 EQUates.
+//
+#define ALS_ENABLE            BIT0
+#define BLC_ENABLE            BIT1
+#define BACKLIGHT_BRIGHTNESS  0xFF
+#define FIELD_VALID_BIT       BIT31
+#define WORD_FIELD_VALID_BIT  BIT15
+#define PFIT_ENABLE           BIT2
+#define PFIT_OPRN_AUTO        0x00000000
+#define PFIT_OPRN_SCALING     0x00000007
+#define PFIT_OPRN_OFF         0x00000000
+#define PFIT_SETUP_AUTO       0
+#define PFIT_SETUP_SCALING    1
+#define PFIT_SETUP_OFF        2
+#define INIT_BRIGHT_LEVEL     0x64
+#define PFIT_STRETCH          6
+#define PFIT_CENTER           1
+
+//
+// GMCH PCI register access #defines.
+//
+
+#define IgdMmPci32(Register)            MmPci32   (0, IGD_BUS, IGD_DEV, IGD_FUN_0, Register)
+#define IgdMmPci16Or(Register, OrData)  MmPci16Or (0, IGD_BUS, IGD_DEV, IGD_FUN_0, Register, OrData)
+#define IgdMmPci16AndThenOr(Register,AndData,OrData) MmPci16AndThenOr (0, IGD_BUS, IGD_DEV, IGD_FUN_0, Register, AndData, OrData)
+
+//
+// Video BIOS / VBT #defines
+//
+#define IGD_DID_VLV             0x0F31
+#define OPTION_ROM_SIGNATURE    0xAA55
+#define VBIOS_LOCATION_PRIMARY  0xC0000
+
+#define VBT_SIGNATURE           SIGNATURE_32 ('$', 'V', 'B', 'T')
+
+//
+// Typedef stuctures
+//
+#pragma pack (1)
+typedef struct {
+  UINT16  Signature;    // 0xAA55
+  UINT8   Size512;
+  UINT8   Reserved[21];
+  UINT16  PcirOffset;
+  UINT16  VbtOffset;
+} INTEL_VBIOS_OPTION_ROM_HEADER;
+#pragma pack ()
+
+#pragma pack (1)
+typedef struct {
+  UINT32  Signature;  // "PCIR"
+  UINT16  VendorId;   // 0x8086
+  UINT16  DeviceId;
+  UINT16  Reserved0;
+  UINT16  Length;
+  UINT8   Revision;
+  UINT8   ClassCode[3];
+  UINT16  ImageLength;
+  UINT16  CodeRevision;
+  UINT8   CodeType;
+  UINT8   Indicator;
+  UINT16  Reserved1;
+} INTEL_VBIOS_PCIR_STRUCTURE;
+#pragma pack ()
+
+#pragma pack (1)
+typedef struct {
+  UINT8   HeaderSignature[20];
+  UINT16  HeaderVersion;
+  UINT16  HeaderSize;
+  UINT16  HeaderVbtSize;
+  UINT8   HeaderVbtCheckSum;
+  UINT8   HeaderReserved;
+  UINT32  HeaderOffsetVbtDataBlock;
+  UINT32  HeaderOffsetAim1;
+  UINT32  HeaderOffsetAim2;
+  UINT32  HeaderOffsetAim3;
+  UINT32  HeaderOffsetAim4;
+  UINT8   DataHeaderSignature[16];
+  UINT16  DataHeaderVersion;
+  UINT16  DataHeaderSize;
+  UINT16  DataHeaderDataBlockSize;
+  UINT8   CoreBlockId;
+  UINT16  CoreBlockSize;
+  UINT16  CoreBlockBiosSize;
+  UINT8   CoreBlockBiosType;
+  UINT8   CoreBlockReleaseStatus;
+  UINT8   CoreBlockHWSupported;
+  UINT8   CoreBlockIntegratedHW;
+  UINT8   CoreBlockBiosBuild[4];
+  UINT8   CoreBlockBiosSignOn[155];
+} VBIOS_VBT_STRUCTURE;
+#pragma pack ()
+
+//
+// Driver Private Function definitions
+//
+EFI_STATUS
+GetSVER (
+  OUT UINT8 *SVER
+  );
+
+/**
+  Acquire the string associated with the ProducerGuid and return it.
+
+  @param ProducerGuid  The Guid to search the HII database for
+  @param Token         The token value of the string to extract
+  @param String        The string that is extracted
+
+  @retval EFI_SUCCESS       The function completed successfully
+  @retval EFI_NOT_FOUND     The requested string was not found
+
+**/
+EFI_STATUS
+GetStringFromToken (
+  IN      EFI_GUID                  *ProducerGuid,
+  IN      STRING_REF                Token,
+  OUT     CHAR16                    **String
+  );
+
+/**
+
+  Graphics OpRegion / Software SCI driver installation function.
+
+  @param Void
+
+  @retval EFI_SUCCESS     The driver installed without error.
+  @retval EFI_ABORTED     The driver encountered an error and could not complete
+                          installation of the ACPI tables.
+**/
+EFI_STATUS
+IgdOpRegionInit (
+  void
+  );
+
+/**
+  Extract information pertaining to the HiiHandle
+
+  @param HiiHandle        Hii handle
+  @param ImageLength      For input, length of DefaultImage;
+                          For output, length of actually required
+
+  @param DefaultImage     Image buffer prepared by caller
+  @param Guid             Guid information about the form
+
+  @retval EFI_OUT_OF_RESOURCES     No enough buffer to allocate
+  @retval EFI_BUFFER_TOO_SMALL     DefualtImage has no enough ImageLength
+  @retval EFI_SUCCESS              Successfully extract data from Hii database.
+
+**/
+EFI_STATUS
+ExtractDataFromHiiHandle (
+  IN      EFI_HII_HANDLE      HiiHandle,
+  IN OUT  UINT16              *ImageLength,
+  OUT     UINT8               *DefaultImage,
+  OUT     EFI_GUID            *Guid
+  );
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.c b/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.c
new file mode 100644
index 0000000000..75675fbf00
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.c
@@ -0,0 +1,287 @@
+
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+                                                                                   

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

+
+
+Module Name:
+
+  VlvPlatformInit.c
+
+Abstract:
+
+  This is the driver that initializes the Intel ValleyView.
+
+--*/
+
+#include "VlvPlatformInit.h"
+#include <Protocol/VlvPlatformPolicy.h>
+
+extern DXE_VLV_PLATFORM_POLICY_PROTOCOL  *DxePlatformSaPolicy;
+UINT64            GTTMMADR;
+
+DXE_VLV_PLATFORM_POLICY_PROTOCOL  *DxePlatformSaPolicy;
+
+/**
+  "Poll Status" for GT Readiness
+
+ @param  Base             Base address of MMIO
+ @param  Offset           MMIO Offset
+ @param  Mask             Mask
+ @param  Result           Value to wait for
+
+ @retval None
+
+**/
+VOID
+PollGtReady_hang (
+  UINT64 Base,
+  UINT32 Offset,
+  UINT32 Mask,
+  UINT32 Result
+  )
+{
+  UINT32  GtStatus;
+
+  //
+  // Register read
+  //
+  GtStatus = MmioRead32 ((UINTN)Base+ Offset);
+
+  while (((GtStatus & Mask) != Result)) {
+
+    GtStatus = MmioRead32 ((UINTN)Base + Offset);
+  }
+
+}
+
+/**
+  Do Post GT PM Init Steps after VBIOS Initialization.
+
+  @param Event             A pointer to the Event that triggered the callback.
+  @param Context           A pointer to private data registered with the callback function.
+
+  @retval EFI_SUCCESS        GC_TODO
+
+
+**/
+EFI_STATUS
+EFIAPI    
+PostPmInitCallBack (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  UINT64      OriginalGTTMMADR;
+  UINT32      LoGTBaseAddress;
+  UINT32      HiGTBaseAddress;
+
+  //
+  // Enable Bus Master, I/O and Memory access on 0:2:0
+  //
+  PciOr8 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_CMD), (BIT2 | BIT1));
+
+  //
+  // only 32bit read/write is legal for device 0:2:0
+  //
+  OriginalGTTMMADR  = (UINT64) PciRead32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR));
+  OriginalGTTMMADR  = LShiftU64 ((UINT64) PciRead32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR + 4)), 32) | (OriginalGTTMMADR);
+
+  //
+  // 64bit GTTMADR does not work for S3 save script table since it is executed in PEIM phase
+  // Program temporarily 32bits GTTMMADR for POST and S3 resume
+  //
+  LoGTBaseAddress                   = (UINT32) (GTTMMADR & 0xFFFFFFFF);
+  HiGTBaseAddress                   = (UINT32) RShiftU64 ((GTTMMADR & 0xFFFFFFFF00000000), 32);
+  S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR), LoGTBaseAddress);
+  S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR+4), HiGTBaseAddress);
+
+
+
+  //
+  // Restore original GTTMMADR
+  //
+  LoGTBaseAddress                   = (UINT32) (OriginalGTTMMADR & 0xFFFFFFFF);
+  HiGTBaseAddress                   = (UINT32) RShiftU64 ((OriginalGTTMMADR & 0xFFFFFFFF00000000), 32);
+
+  S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR), LoGTBaseAddress);
+  S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR+4), HiGTBaseAddress);
+
+
+  //
+  // Lock the following registers, GGC, BDSM, BGSM
+  //
+  PciOr32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_MGGC_OFFSET), LockBit);
+  PciOr32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_BSM_OFFSET), LockBit);
+  PciOr32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_BGSM), LockBit);
+
+  gBS->CloseEvent (Event);
+
+  //
+  // Return final status
+  //
+  return EFI_SUCCESS;
+}
+
+/**
+
+  Routine Description:
+
+  Initialize GT Post Routines.
+
+  @param ImageHandle              Handle for the image of this driver
+  @param DxePlatformSaPolicy      SA DxePlatformPolicy protocol
+
+  @retval EFI_SUCCESS             GT POST initialization complete
+
+**/
+EFI_STATUS
+IgdPmHook (
+  IN EFI_HANDLE                      ImageHandle,
+  IN DXE_VLV_PLATFORM_POLICY_PROTOCOL *DxePlatformSaPolicyParam
+  )
+{
+
+  EFI_EVENT             mConOutEvent;
+  VOID                  *gConOutNotifyReg;
+
+  EFI_STATUS            Status;
+
+  EFI_PHYSICAL_ADDRESS  MemBaseAddress;
+  UINT32                LoGTBaseAddress;
+  UINT32                HiGTBaseAddress;
+
+  GTTMMADR    = 0;
+  Status      = EFI_SUCCESS;
+
+  //
+  // If device 0:2:0 (Internal Graphics Device, or GT) is enabled, then Program GTTMMADR,
+  //
+  if (PciRead16(PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_VID))  != 0xFFFF) {
+
+    ASSERT (gDS!=NULL);
+
+    //
+    // Enable Bus Master, I/O and Memory access on 0:2:0
+    //
+    PciOr8(PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_CMD), (BIT2 | BIT1 | BIT0));
+
+    //
+    // Means Allocate 4MB for GTTMADDR
+    //
+    MemBaseAddress = 0x0ffffffff;
+
+    Status = gDS->AllocateMemorySpace (
+                    EfiGcdAllocateMaxAddressSearchBottomUp,
+                    EfiGcdMemoryTypeMemoryMappedIo,
+                    GTT_MEM_ALIGN,
+                    GTTMMADR_SIZE_4MB,
+                    &MemBaseAddress,
+                    ImageHandle,
+                    NULL
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    //
+    // Program GT PM Settings if GTTMMADR allocation is Successful
+    //
+    GTTMMADR                          = (UINTN) MemBaseAddress;
+
+    LoGTBaseAddress                   = (UINT32) (MemBaseAddress & 0xFFFFFFFF);
+    HiGTBaseAddress                   = (UINT32) RShiftU64 ((MemBaseAddress & 0xFFFFFFFF00000000), 32);
+
+    PciWrite32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_GTTMMADR), LoGTBaseAddress);
+    PciWrite32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_GTTMMADR+4), HiGTBaseAddress);
+
+
+    S3PciRead32(PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_GTTMMADR));
+
+
+    S3MmioRead32(IGD_R_GTTMMADR + 4);
+
+
+    S3PciRead8(PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_CMD));
+
+    //
+    // Do POST GT PM Init Steps after VBIOS Initialization in DoPostPmInitCallBack
+    //
+    Status = gBS->CreateEvent (
+                    EVT_NOTIFY_SIGNAL,
+                    TPL_CALLBACK,
+                    (EFI_EVENT_NOTIFY)PostPmInitCallBack,
+                    NULL,
+                    &mConOutEvent
+                    );
+
+    ASSERT_EFI_ERROR (Status);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+
+    Status = gBS->RegisterProtocolNotify (
+                    &gEfiGraphicsOutputProtocolGuid,
+                    mConOutEvent,
+                    &gConOutNotifyReg
+                    );
+
+
+
+    MmioWrite64 (IGD_R_GTTMMADR, 0);
+
+    //
+    // Free allocated resources
+    //
+    gDS->FreeMemorySpace (
+           MemBaseAddress,
+           GTTMMADR_SIZE_4MB
+           );
+
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  This is the standard EFI driver point that detects
+  whether there is an ICH southbridge in the system
+  and if so, initializes the chip.
+
+  @param  ImageHandle             Handle for the image of this driver
+  @param  SystemTable             Pointer to the EFI System Table
+
+  @retval EFI_SUCCESS             The function completed successfully
+
+**/
+EFI_STATUS
+EFIAPI
+VlvPlatformInitEntryPoint (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_STATUS                        Status;
+
+  Status = gBS->LocateProtocol (&gDxeVlvPlatformPolicyGuid, NULL, (void **)&DxePlatformSaPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // GtPostInit Initialization
+  //
+  DEBUG ((EFI_D_ERROR, "Initializing GT PowerManagement and other GT POST related\n"));
+  IgdPmHook (ImageHandle, DxePlatformSaPolicy);
+
+  //
+  // IgdOpRegion Install Initialization
+  //
+  DEBUG ((EFI_D_ERROR, "Initializing IGD OpRegion\n"));
+  IgdOpRegionInit ();
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.h b/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.h
new file mode 100644
index 0000000000..5caf54bb8a
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.h
@@ -0,0 +1,65 @@
+
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+                                                                                   

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

+
+
+Module Name:
+
+  VlvPlatformInit.h
+
+Abstract:
+
+  Header file for SA Initialization Driver.
+
+--*/
+
+#ifndef _VLV_PLATFORM_INIT_DXE_H_
+#define _VLV_PLATFORM_INIT_DXE_H_
+#include "PiDxe.h"
+
+#include <Protocol/VlvPlatformPolicy.h>
+
+#include "IgdOpRegion.h"
+
+#include <Library/DxeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include "Library/DebugLib.h"
+#include "Library/S3IoLib.h"
+#include "Library/S3PciLib.h"
+#include "Library/IoLib.h"
+#include "Library/PciLib.h"
+#include "Library/S3BootScriptLib.h"
+
+//
+// GT RELATED EQUATES
+//
+#define GTT_MEM_ALIGN        22
+#define GTTMMADR_SIZE_4MB    0x400000
+
+#define IGD_BUS             0x00
+#define IGD_DEV                  0x02
+#define IGD_FUN_0                0x00
+
+#define IGD_R_VID                0x00
+#define IGD_R_CMD                0x04
+#define IGD_R_GTTMMADR           0x10
+
+#define IGD_R_BGSM               0x70
+#define LockBit                  BIT0
+
+#define IGD_VID             0x8086
+#define IGD_DID             0xA001
+#define IGD_MGGC_OFFSET     0x0050      //GMCH Graphics Control Register 0x50
+#define IGD_BSM_OFFSET      0x005C      //Base of Stolen Memory
+#define IGD_SWSCI_OFFSET    0x00E0      //Software SCI 0xE0 2
+#define IGD_ASLE_OFFSET     0x00E4      //System Display Event Register 0xE4 4
+#define IGD_ASLS_OFFSET     0x00FC      // ASL Storage
+
+#endif
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInitDxe.inf b/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInitDxe.inf
new file mode 100644
index 0000000000..9d277dd7cf
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInitDxe.inf
@@ -0,0 +1,74 @@
+#
+#
+#/*++
+#
+#  Copyright (c)  1999  - 2018, Intel Corporation. All rights reserved
+#                                                                                  

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

+#
+#  Module Name:
+#
+#    VlvPlatformInit.inf
+#
+#  Abstract:
+#
+#    Component description file for wrapper driver of Vlv platform init part.
+#
+#--*/
+
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = VlvPlatformInitDxe
+  FILE_GUID                      = 1EC0EFC9-C93A-4b62-9B27-C059ABD80E92
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = VlvPlatformInitEntryPoint
+
+[Sources]
+  VlvPlatformInit.c
+  IgdOpRegion.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  DebugLib
+  UefiBootServicesTableLib
+  S3BootScriptLib
+  DxeServicesTableLib
+  PchPlatformLib
+  S3PciLib
+  S3IoLib
+  PciLib
+  IoLib
+
+[Guids]
+  gBmpImageGuid
+  gEfiDxeServicesTableGuid
+
+[Protocols]
+  gDxeVlvPlatformPolicyGuid
+  gEfiDxeSmmReadyToLockProtocolGuid
+  gIgdOpRegionProtocolGuid
+  gEfiGlobalNvsAreaProtocolGuid
+  gEfiPciIoProtocolGuid
+  gEfiFirmwareVolume2ProtocolGuid
+  gEfiCpuIoProtocolGuid
+
+[Depex]
+  gDxeVlvPlatformPolicyGuid              AND
+  gEfiPciRootBridgeIoProtocolGuid     AND
+  gEfiCpuIoProtocolGuid                      AND
+  gEfiDataHubProtocolGuid                 AND
+  gEfiGlobalNvsAreaProtocolGuid       AND
+  gEfiFirmwareVolume2ProtocolGuid   AND
+  gEfiHiiDatabaseProtocolGuid
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.c b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.c
new file mode 100644
index 0000000000..f98265761b
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.c
@@ -0,0 +1,340 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+
+Module Name:
+
+    LpcDriver.c
+
+Abstract:
+
+    EFI Lpc Driver for a Generic PC Platform
+
+
+
+--*/
+
+#include "LpcDriver.h"
+#include "IndustryStandard/Pci22.h"
+
+//
+// This driver is for ACPI(PNP0A03,0)/PCI(0x1f,0)
+//
+
+//
+//  Lpc Driver Global Variables
+//
+
+EFI_DRIVER_BINDING_PROTOCOL gLpcDriver = {
+  LpcDriverSupported,
+  LpcDriverStart,
+  LpcDriverStop,
+  0x10,
+  NULL,
+  NULL
+};
+
+LPC_DEV mLpc = {
+  LPC_DEV_SIGNATURE,
+  NULL,
+  {
+    IsaDeviceEnumerate,
+    IsaDeviceSetPower,
+    IsaGetCurrentResource,
+    IsaGetPossibleResource,
+    IsaSetResource,
+    IsaEnableDevice,
+    IsaInitDevice,
+    LpcInterfaceInit
+  },
+  NULL
+};
+
+BOOLEAN  InitExecuted = FALSE;
+
+/**
+    the entry point of the Lpc driver
+
+**/
+EFI_STATUS
+EFIAPI
+LpcDriverEntryPoint(
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+
+
+  return EfiLibInstallDriverBinding (ImageHandle, SystemTable, &gLpcDriver, ImageHandle);
+}
+
+/**
+
+  ControllerDriver Protocol Method
+
+**/
+EFI_STATUS
+EFIAPI
+LpcDriverSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  )
+{
+  EFI_STATUS                Status;
+  EFI_PCI_IO_PROTOCOL       *PciIo;
+  EFI_DEVICE_PATH_PROTOCOL  *IsaBridgeDevicePath;
+
+  ACPI_HID_DEVICE_PATH      *AcpiNode;
+  PCI_DEVICE_PATH           *PciNode;
+  PCI_TYPE00                Pci;
+
+  //
+  // Get the ISA bridge's Device Path and test it
+  // the following code is specific
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID **)&IsaBridgeDevicePath,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = EFI_SUCCESS;
+  AcpiNode =  (ACPI_HID_DEVICE_PATH *)IsaBridgeDevicePath;
+  if (AcpiNode->Header.Type != ACPI_DEVICE_PATH ||
+      AcpiNode->Header.SubType != ACPI_DP ||
+      DevicePathNodeLength (&AcpiNode->Header) != sizeof(ACPI_HID_DEVICE_PATH) ||
+      AcpiNode -> HID != EISA_PNP_ID(0x0A03) ||
+      AcpiNode -> UID != 0 ) {
+    Status = EFI_UNSUPPORTED;
+  } else {
+    //
+    // Get the next node
+    //
+    IsaBridgeDevicePath = NextDevicePathNode (IsaBridgeDevicePath);
+    PciNode  = (PCI_DEVICE_PATH *)IsaBridgeDevicePath;
+    if (PciNode->Header.Type != HARDWARE_DEVICE_PATH ||
+        PciNode->Header.SubType != HW_PCI_DP ||
+        DevicePathNodeLength (&PciNode->Header) != sizeof (PCI_DEVICE_PATH) ||
+        PciNode -> Function != 0x00 ||
+        PciNode -> Device != 0x1f ) {
+      Status = EFI_UNSUPPORTED;
+    }
+  }
+
+  gBS->CloseProtocol (
+         Controller,
+         &gEfiDevicePathProtocolGuid,
+         This->DriverBindingHandle,
+         Controller
+         );
+
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Get PciIo protocol instance
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **)&PciIo,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint32,
+                        0,
+                        sizeof(Pci) / sizeof(UINT32),
+                        &Pci
+                        );
+
+  if (!EFI_ERROR (Status)) {
+    Status = EFI_SUCCESS; //TODO: force return success as temp solution EFI_UNSUPPORTED;
+    if ((Pci.Hdr.Command & 0x03) == 0x03) {
+      if (Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) {
+        //
+        // See if this is a standard PCI to ISA Bridge from the Base Code
+        // and Class Code
+        //
+        if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA) {
+          Status = EFI_SUCCESS;
+        } else {
+        }
+
+        //
+        // See if this is an Intel PCI to ISA bridge in Positive Decode Mode
+        //
+        if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA_PDECODE &&
+            Pci.Hdr.VendorId == 0x8086 &&
+            Pci.Hdr.DeviceId == 0x7110) {
+          Status = EFI_SUCCESS;
+        } else {
+        }
+      } else {
+      }
+    }
+    else {
+    }
+  }
+
+  gBS->CloseProtocol (
+         Controller,
+         &gEfiPciIoProtocolGuid,
+         This->DriverBindingHandle,
+         Controller
+         );
+  return Status;
+}
+
+
+/**
+  Install EFI_ISA_ACPI_PROTOCOL
+
+**/
+EFI_STATUS
+EFIAPI
+LpcDriverStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  )
+{
+  EFI_STATUS             Status;
+  EFI_PCI_IO_PROTOCOL    *PciIo;
+
+  //
+  // Get Pci IO
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **)&PciIo,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+
+  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
+    return Status;
+  }
+
+  mLpc.PciIo = PciIo;
+
+  //
+  // Install IsaAcpi interface, the Sio interface is not installed!
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Controller,
+                  &gEfiIsaAcpiProtocolGuid,
+                  &mLpc.IsaAcpi,
+                  NULL
+                  );
+  return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+LpcDriverStop (
+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN  EFI_HANDLE                     Controller,
+  IN  UINTN                          NumberOfChildren,
+  IN  EFI_HANDLE                     *ChildHandleBuffer
+  )
+{
+  EFI_STATUS             Status;
+  EFI_ISA_ACPI_PROTOCOL  *IsaAcpi;
+  LPC_DEV                *LpcDev;
+
+  //
+  // Get EFI_ISA_ACPI_PROTOCOL interface
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiIsaAcpiProtocolGuid,
+                  (VOID **)&IsaAcpi,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  LpcDev = LPC_ISA_ACPI_FROM_THIS (IsaAcpi);
+
+  //
+  // Uninstall protocol interface: EFI_ISA_ACPI_PROTOCOL
+  //
+  Status = gBS->UninstallProtocolInterface (
+                  Controller,
+                  &gEfiIsaAcpiProtocolGuid,
+                  &LpcDev->IsaAcpi
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  gBS->CloseProtocol (
+         Controller,
+         &gEfiPciIoProtocolGuid,
+         This->DriverBindingHandle,
+         Controller
+         );
+
+  return EFI_SUCCESS;
+}
+
+VOID
+LpcIoRead8 (
+  IN  UINT16  Port,
+  OUT UINT8   *Data
+  )
+{
+  mLpc.PciIo->Io.Read(
+                   mLpc.PciIo,
+                   EfiPciWidthUint8,
+                   EFI_PCI_IO_PASS_THROUGH_BAR,
+                   Port,
+                   1,
+                   Data
+                   );
+}
+
+VOID
+LpcIoWrite8 (
+  IN  UINT16  Port,
+  IN  UINT8   Data
+  )
+{
+  mLpc.PciIo->Io.Write(
+                   mLpc.PciIo,
+                   EfiPciWidthUint8,
+                   EFI_PCI_IO_PASS_THROUGH_BAR,
+                   Port,
+                   1,
+                   &Data
+                   );
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.h b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.h
new file mode 100644
index 0000000000..5e264485e7
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.h
@@ -0,0 +1,112 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+    LpcDriver.h
+
+Abstract:
+
+    EFI Lpc Driver for a Generic PC Platform
+
+
+
+--*/
+
+#ifndef _LPC_DRIVER_H
+#define _LPC_DRIVER_H
+
+ #include "LpcSio.h"
+ #include "LpcIsaAcpi.h"
+
+#include "Protocol/IsaAcpi.h"
+#include "Protocol/PciIo.h"
+#include "Protocol/DriverBinding.h"
+#include "Library/UefiBootServicesTableLib.h"
+#include "IsaAcpiDxe/PcatIsaAcpi.h"
+#include "IndustryStandard/Pci22.h"
+#include "Protocol/LpcWpce791Policy.h"
+
+#include <Library/DebugLib.h>
+
+#define ICH_LPC_BRIDGE_BUS_DEV_FUNC 0x1F0000
+
+//
+// LPC device private data structure
+//
+//#define LPC_DEV_SIGNATURE 'W87X'
+#define LPC_DEV_SIGNATURE SIGNATURE_32('X', '7', '8', 'W') //'W87X'
+#define EFI_WPCE791_PS2_KEYBOARD_ENABLE       0x01
+#define EFI_WPCE791_PS2_KEYBOARD_DISABLE      0x00
+
+#define EFI_WPCE791_PS2_MOUSE_ENABLE       0x01
+#define EFI_WPCE791_PS2_MOUSE_DISABLE      0x00
+
+
+
+typedef struct {
+  UINTN                 Signature;
+  EFI_HANDLE            Handle;
+  EFI_ISA_ACPI_PROTOCOL IsaAcpi;
+  EFI_PCI_IO_PROTOCOL   *PciIo;
+
+} LPC_DEV;
+
+#define LPC_ISA_ACPI_FROM_THIS(a) BASE_CR (a, LPC_DEV, IsaAcpi)
+
+//
+// Driver entry point
+//
+EFI_STATUS
+EFIAPI
+LpcDriverEntryPoint (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  );
+
+//
+// Prototypes for Driver model protocol interface
+//
+EFI_STATUS
+EFIAPI
+LpcDriverSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  );
+
+EFI_STATUS
+EFIAPI
+LpcDriverStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  );
+
+EFI_STATUS
+EFIAPI
+LpcDriverStop (
+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN  EFI_HANDLE                     Controller,
+  IN  UINTN                          NumberOfChildren,
+  IN  EFI_HANDLE                     *ChildHandleBuffer
+  );
+
+VOID
+LpcIoRead8 (
+  IN  UINT16  Port,
+  OUT UINT8   *Data
+  );
+
+VOID
+LpcIoWrite8 (
+  IN  UINT16  Port,
+  IN  UINT8   Data
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c
new file mode 100644
index 0000000000..9c0b79b15c
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c
@@ -0,0 +1,366 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+    LpcIsaAcpi.c
+
+Abstract: IsaAcpi implementation
+
+
+
+--*/
+
+#include "LpcDriver.h"
+
+//
+// PS/2 Keyboard Controller
+//
+static EFI_ISA_ACPI_RESOURCE  mLpcWpce791Ps2KeyboardDeviceResources[] = {
+  {EfiIsaAcpiResourceIo,        0, 0x60, 0x64},
+  {EfiIsaAcpiResourceInterrupt, 0, 1,     0},
+  {EfiIsaAcpiResourceEndOfList, 0, 0,     0}
+};
+
+//
+// PS/2 Mouse Controller
+//
+static EFI_ISA_ACPI_RESOURCE  mLpcWpce791Ps2MouseDeviceResources[] = {
+  {EfiIsaAcpiResourceIo,        0, 0x60, 0x64},
+  {EfiIsaAcpiResourceInterrupt, 0, 12,     0},
+  {EfiIsaAcpiResourceEndOfList, 0, 0,     0}
+};
+
+//
+// COM
+//
+static EFI_ISA_ACPI_RESOURCE  mLpcWpce791ComDeviceResources[] = {
+  {EfiIsaAcpiResourceIo,        0, 0x3f8, 0x3ff},
+  {EfiIsaAcpiResourceInterrupt, 0, 4,     0},
+  {EfiIsaAcpiResourceEndOfList, 0, 0,     0}
+};
+
+//
+// Table of ISA Controllers
+//
+EFI_ISA_ACPI_RESOURCE_LIST mLpcWpce791DeviceList[] = {
+  {{EISA_PNP_ID(0x303), 0}, mLpcWpce791Ps2KeyboardDeviceResources }, // PS/2 Keyboard Controller
+  {{EISA_PNP_ID(0xF03), 0}, mLpcWpce791Ps2MouseDeviceResources	  }, // PS/2 Mouse Controller
+  {{EISA_PNP_ID(0x501), 0}, mLpcWpce791ComDeviceResources	      }, // COM
+  {{0,                  0}, NULL                                  }  // End
+};
+
+static ICH_DMA_INIT  mIchDmaInitTable [] = {
+//
+//Register OFFSET,           Value
+//
+
+            0x0D8,           0x000,   // Reset DMA Controller 2
+            0x0D0,           0x000,   // Enable DMA controller 2
+            0x00C,           0x000,   // Reset DMA Controller 1
+            0x008,           0x000,   // Enable DMA controller 1
+
+            //
+            // Channel 4
+            //
+            0x0D6,           0x0c0,   // DMA contr. 2 Cascade mode, addr. increment, disable auto init.
+            0x0D2,           0x000,   // Clear write request register
+            0x0d4,           0x000,   // Enable DREQs for channel
+
+            //
+            // Channel 0
+            //
+            0x00B,           0x040,   // DMA contr. 1 single mode, addr. increment, disable auto init.
+            0x009,           0x000,   // Clear write request register
+            0x00A,           0x000,   // Enable DREQs for channel
+
+            //
+            // Channel 1
+            //
+            0x00B,           0x041,   // DMA contr. 1 single mode, addr. increment, disable auto init.
+            0x009,           0x001,   // Clear write request register
+            0x00A,           0x001,   // Enable DREQs for channel
+
+            //
+            // Channel 2
+            //
+            0x00B,           0x042,   // DMA contr. 1 single mode, addr. increment, disable auto init.
+            0x009,           0x002,   // Clear write request register
+            0x00A,           0x002,   // Enable DREQs for channel
+
+            //
+            // Channel 3
+            //
+            0x00B,           0x043,   // DMA contr. 1 single mode, addr. increment, disable auto init.
+            0x009,           0x003,   // Clear write request register
+            0x00A,           0x003,   // Enable DREQs for channel
+
+            //
+            // Channel 5
+            //
+            0x0D6,           0x041,   // DMA contr. 2 single mode, addr. increment, disable auto init.
+            0x0D2,           0x001,   // Clear write request register
+            0x0D4,           0x001,   // Enable DREQs for channel
+
+            //
+            // Channel 6
+            //
+            0x0D6,           0x042,   // DMA contr. 2 single mode, addr. increment, disable auto init.
+            0x0D2,           0x002,   // Clear write request register
+            0x0D4,           0x002,   // Enable DREQs for channel
+
+            //
+            // Channel 7
+            //
+            0x0D6,           0x043,   // DMA contr. 2 single mode, addr. increment, disable auto init.
+            0x0D2,           0x003,   // Clear write request register
+            0x0D4,           0x003    // Enable DREQs for channel
+
+};
+
+//
+// ISA ACPI Protocol Functions
+//
+/**
+
+  Enumerate the ISA devices on the ISA bus
+
+**/
+VOID
+IsaDeviceLookup (
+  IN  EFI_ISA_ACPI_DEVICE_ID      *Device,
+  OUT EFI_ISA_ACPI_RESOURCE_LIST  **IsaAcpiDevice,
+  OUT EFI_ISA_ACPI_RESOURCE_LIST  **NextIsaAcpiDevice
+  )
+{
+  UINTN  Index;
+
+  *IsaAcpiDevice = NULL;
+  if (NextIsaAcpiDevice != NULL) {
+    *NextIsaAcpiDevice = NULL;
+  }
+  if (Device == NULL) {
+    Index = 0;
+  } else {
+    for(Index = 0; mLpcWpce791DeviceList[Index].Device.HID != 0; Index++) {
+      if (Device->HID == mLpcWpce791DeviceList[Index].Device.HID &&
+          Device->UID == mLpcWpce791DeviceList[Index].Device.UID    ) {
+        break;
+      }
+    }
+    if (mLpcWpce791DeviceList[Index].Device.HID == 0) {
+      return;
+    }
+    *IsaAcpiDevice = &(mLpcWpce791DeviceList[Index]);
+    Index++;
+  }
+  if (NextIsaAcpiDevice != NULL && mLpcWpce791DeviceList[Index].Device.HID != 0){
+    *NextIsaAcpiDevice = &(mLpcWpce791DeviceList[Index]);
+  }
+}
+
+
+/**
+  Enumerate the ISA devices on the ISA bus
+  It is hard code now and future it will get from ACPI table
+
+**/
+EFI_STATUS
+EFIAPI
+IsaDeviceEnumerate (
+  IN     EFI_ISA_ACPI_PROTOCOL       *This,
+  OUT    EFI_ISA_ACPI_DEVICE_ID      **Device
+  )
+{
+  EFI_ISA_ACPI_RESOURCE_LIST  *IsaAcpiDevice;
+  EFI_ISA_ACPI_RESOURCE_LIST  *NextIsaAcpiDevice;
+
+  IsaDeviceLookup (*Device, &IsaAcpiDevice, &NextIsaAcpiDevice);
+  if (NextIsaAcpiDevice == NULL) {
+    return EFI_NOT_FOUND;
+  }
+  *Device = &(NextIsaAcpiDevice->Device);
+  return EFI_SUCCESS;
+}
+
+/**
+  Set ISA device power use sio
+
+**/
+EFI_STATUS
+EFIAPI
+IsaDeviceSetPower (
+  IN     EFI_ISA_ACPI_PROTOCOL       *This,
+  IN     EFI_ISA_ACPI_DEVICE_ID      *Device,
+  IN     BOOLEAN                     OnOff
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+
+/**
+  Get current Resource of the specific ISA device
+  It is hardcode now and future will get from ACPI table
+
+**/
+EFI_STATUS
+EFIAPI
+IsaGetCurrentResource (
+  IN     EFI_ISA_ACPI_PROTOCOL        *This,
+  IN     EFI_ISA_ACPI_DEVICE_ID       *Device,
+  OUT    EFI_ISA_ACPI_RESOURCE_LIST   **ResourceList
+  )
+{
+  IsaDeviceLookup (Device, ResourceList, NULL);
+  if (*ResourceList == NULL || (*ResourceList)->ResourceItem == NULL) {
+    return EFI_NOT_FOUND;
+  }
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+IsaGetPossibleResource (
+  IN     EFI_ISA_ACPI_PROTOCOL       *This,
+  IN     EFI_ISA_ACPI_DEVICE_ID      *Device,
+  OUT    EFI_ISA_ACPI_RESOURCE_LIST  **ResourceList
+  )
+{
+  //
+  // Not supported yet
+  //
+  return EFI_UNSUPPORTED;
+}
+
+
+EFI_STATUS
+EFIAPI
+IsaSetResource (
+  IN     EFI_ISA_ACPI_PROTOCOL       *This,
+  IN     EFI_ISA_ACPI_DEVICE_ID      *Device,
+  IN     EFI_ISA_ACPI_RESOURCE_LIST  *ResourceList
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+IsaEnableDevice (
+  IN    EFI_ISA_ACPI_PROTOCOL        *This,
+  IN    EFI_ISA_ACPI_DEVICE_ID       *Device,
+  IN    BOOLEAN                      Enable
+  )
+{
+
+  return EFI_UNSUPPORTED;
+}
+
+/**
+
+  Clear out Resource List if device is set to disable by platform policy
+
+**/
+VOID
+EmptyResourceList (
+  IN  UINT32      DeviceHid
+  )
+{
+  UINT8     Index;
+  for (Index = 0; mLpcWpce791DeviceList[Index].Device.HID != 0; Index++) {
+    if (DeviceHid == mLpcWpce791DeviceList[Index].Device.HID) {
+      mLpcWpce791DeviceList[Index].ResourceItem = NULL;
+    }
+  }
+  return;
+}
+
+/**
+
+  Clear out Resource List if device is set to disable by platform policy
+
+**/
+VOID
+EmptyResourceListHidUid (
+  IN  UINT32      DeviceHid,
+  IN  UINT32      DeviceUid
+  )
+{
+  UINT8     Index;
+  for (Index = 0; mLpcWpce791DeviceList[Index].Device.HID != 0; Index++) {
+    if ((DeviceHid == mLpcWpce791DeviceList[Index].Device.HID) &&
+        (DeviceUid == mLpcWpce791DeviceList[Index].Device.UID)) {
+      mLpcWpce791DeviceList[Index].ResourceItem = NULL;
+    }
+  }
+  return;
+}
+
+EFI_STATUS
+EFIAPI
+IsaInitDevice (
+  IN    EFI_ISA_ACPI_PROTOCOL        *This,
+  IN    EFI_ISA_ACPI_DEVICE_ID       *Device
+  )
+{
+  EFI_WPCE791_POLICY_PROTOCOL      *LpcWpce791Policy;
+  EFI_STATUS                      Status;
+
+  //
+  // Disable configuration according to platform protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiLpcWpce791PolicyProtocolGuid,
+                  NULL,
+                  (VOID **) &LpcWpce791Policy
+                  );
+  if (!EFI_ERROR(Status)) {
+    if (LpcWpce791Policy->DeviceEnables.Ps2Keyboard == EFI_WPCE791_PS2_KEYBOARD_DISABLE) {
+      EmptyResourceList(EISA_PNP_ID(0x303));
+      DisableLogicalDevice (SIO_KEYBOARD);
+      EmptyResourceList(EISA_PNP_ID(0xF03));
+      DisableLogicalDevice (SIO_KEYBOARD);
+    }
+    if (LpcWpce791Policy->DeviceEnables.Ps2Mouse == EFI_WPCE791_PS2_MOUSE_DISABLE) {
+      EmptyResourceList(EISA_PNP_ID(0xF03));
+      DisableLogicalDevice (SIO_MOUSE);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+LpcInterfaceInit (
+  IN    EFI_ISA_ACPI_PROTOCOL        *This
+  )
+{
+  EFI_PCI_IO_PROTOCOL             *PciIo;
+  UINTN                           Index;
+
+  PciIo = (LPC_ISA_ACPI_FROM_THIS (This))->PciIo;
+
+  //
+  // DMA controller initialize
+  //
+  for (Index=0; Index < (sizeof(mIchDmaInitTable)/sizeof(ICH_DMA_INIT)); Index++) {
+    PciIo->Io.Write (
+                PciIo,
+                EfiPciIoWidthUint8,
+                EFI_PCI_IO_PASS_THROUGH_BAR,
+                mIchDmaInitTable[Index].Register,
+                1,
+                &mIchDmaInitTable[Index].Value
+                );
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h
new file mode 100644
index 0000000000..2291fd2c1d
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h
@@ -0,0 +1,103 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+    LpcIsaAcpi.h
+
+Abstract:
+
+    Isa Acpi interface
+
+
+
+--*/
+
+#ifndef _LPC_ISA_ACPI_H
+#define _LPC_ISA_ACPI_H
+
+
+
+#include "Protocol/IsaAcpi.h"
+#include "Library/DevicePathLib.h"
+
+
+typedef struct {
+  UINT8  Register;
+  UINT8  Value;
+} ICH_DMA_INIT;
+
+//
+// Prototypes for the ISA ACPI protocol interface
+//
+EFI_STATUS
+EFIAPI
+IsaDeviceEnumerate (
+  IN     EFI_ISA_ACPI_PROTOCOL       *This,
+  OUT    EFI_ISA_ACPI_DEVICE_ID      **Device
+  );
+
+EFI_STATUS
+EFIAPI
+IsaDeviceSetPower (
+  IN     EFI_ISA_ACPI_PROTOCOL       *This,
+  IN     EFI_ISA_ACPI_DEVICE_ID      *Device,
+  IN     BOOLEAN                     OnOff
+  );
+
+EFI_STATUS
+EFIAPI
+IsaGetCurrentResource (
+  IN     EFI_ISA_ACPI_PROTOCOL       *This,
+  IN     EFI_ISA_ACPI_DEVICE_ID      *Device,
+  OUT    EFI_ISA_ACPI_RESOURCE_LIST  **ResourceList
+  );
+
+EFI_STATUS
+EFIAPI
+IsaGetPossibleResource (
+  IN     EFI_ISA_ACPI_PROTOCOL       *This,
+  IN     EFI_ISA_ACPI_DEVICE_ID      *Device,
+  OUT    EFI_ISA_ACPI_RESOURCE_LIST  **ResourceList
+  );
+
+EFI_STATUS
+EFIAPI
+IsaSetResource (
+  IN     EFI_ISA_ACPI_PROTOCOL       *This,
+  IN     EFI_ISA_ACPI_DEVICE_ID      *Device,
+  IN     EFI_ISA_ACPI_RESOURCE_LIST  *ResourceList
+  );
+
+EFI_STATUS
+EFIAPI
+IsaEnableDevice (
+  IN    EFI_ISA_ACPI_PROTOCOL        *This,
+  IN    EFI_ISA_ACPI_DEVICE_ID       *Device,
+  IN    BOOLEAN                      Enable
+  );
+
+EFI_STATUS
+EFIAPI
+IsaInitDevice (
+  IN    EFI_ISA_ACPI_PROTOCOL        *This,
+  IN    EFI_ISA_ACPI_DEVICE_ID       *Device
+  );
+
+EFI_STATUS
+EFIAPI
+LpcInterfaceInit (
+  IN    EFI_ISA_ACPI_PROTOCOL        *This
+);
+
+VOID
+EmptyResourceList (
+  IN    UINT32      DeviceHid
+);
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c
new file mode 100644
index 0000000000..f23e48ccf2
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c
@@ -0,0 +1,126 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+Module Name:
+
+    LpcSio.c
+
+Abstract: Sio implementation
+
+Revision History
+
+--*/
+
+#include "LpcDriver.h"
+#include <Library/S3BootScriptLib.h>
+
+VOID
+WriteRegister (
+  IN  UINT8   Index,
+  IN  UINT8   Data
+  );
+
+typedef struct {
+  UINT8 Register;
+  UINT8 Value;
+} EFI_SIO_TABLE;
+
+EFI_SIO_TABLE mSioTable[] = {
+  //
+  // Init keyboard controller
+  //
+  { REG_LOGICAL_DEVICE, SIO_KEYBOARD },
+  { BASE_ADDRESS_HIGH, 0x00 },
+  { BASE_ADDRESS_LOW, 0x60 },
+  { BASE_ADDRESS_HIGH2, 0x00 },
+  { BASE_ADDRESS_LOW2, 0x64 },
+  { PRIMARY_INTERRUPT_SELECT, 0x01 },
+  { ACTIVATE, 0x1 },
+
+  //
+  // Init Mouse controller
+  //
+  { REG_LOGICAL_DEVICE, SIO_MOUSE },
+  { BASE_ADDRESS_HIGH, 0x00 },
+  { BASE_ADDRESS_LOW, 0x60 },
+  { BASE_ADDRESS_HIGH2, 0x00 },
+  { BASE_ADDRESS_LOW2, 0x64 },
+  { PRIMARY_INTERRUPT_SELECT, 0x0c },
+  { ACTIVATE, 0x1 },
+
+  { REG_LOGICAL_DEVICE, SIO_COM },
+  { BASE_ADDRESS_HIGH, 0x03 },
+  { BASE_ADDRESS_LOW, 0xf8 },
+  { PRIMARY_INTERRUPT_SELECT, 0x04 },
+  { ACTIVATE, 0x1 },
+
+
+};
+
+VOID
+LPCWPCE791SetDefault ()
+{
+  UINT8           Index;
+
+  for (Index = 0; Index < sizeof(mSioTable)/sizeof(EFI_SIO_TABLE); Index++) {
+    WriteRegisterAndSaveToScript (mSioTable[Index].Register, mSioTable[Index].Value);
+  }
+
+  return;
+}
+
+VOID
+DisableLogicalDevice (
+  UINT8       DeviceId
+  )
+{
+  WriteRegisterAndSaveToScript (REG_LOGICAL_DEVICE, DeviceId);
+  WriteRegisterAndSaveToScript (ACTIVATE, 0);
+  WriteRegisterAndSaveToScript (BASE_ADDRESS_HIGH, 0);
+  WriteRegisterAndSaveToScript (BASE_ADDRESS_LOW, 0);
+
+  return;
+}
+
+VOID
+WriteRegister (
+  IN  UINT8   Index,
+  IN  UINT8   Data
+  )
+{
+  LpcIoWrite8(CONFIG_PORT, Index);
+  LpcIoWrite8(DATA_PORT, Data);
+
+  return;
+}
+
+VOID
+WriteRegisterAndSaveToScript (
+  IN  UINT8   Index,
+  IN  UINT8   Data
+  )
+{
+  UINT8  Buffer[2];
+
+  LpcIoWrite8(CONFIG_PORT, Index);
+  LpcIoWrite8(DATA_PORT, Data);
+
+  Buffer[0] = Index;
+  Buffer[1] = Data;
+  S3BootScriptSaveIoWrite (
+    EfiBootScriptWidthUint8,
+    INDEX_PORT,
+    2,
+    Buffer
+    );
+
+  return;
+}
+
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h
new file mode 100644
index 0000000000..52c1499e3d
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h
@@ -0,0 +1,101 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

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

+
+Module Name:
+
+    LpcSio.h
+
+Abstract:
+
+    Lpc driver's sio interface
+
+
+
+--*/
+
+#ifndef _LPC_SIO_H
+#define _LPC_SIO_H
+
+#include "Protocol/PciRootBridgeIo.h"
+
+#define VARSIOINSTALLED L"VarSIOProcotolInstalled"
+
+//
+// Port address
+//
+#define CONFIG_PORT               0x04E
+#define INDEX_PORT                0x04E
+#define DATA_PORT                 INDEX_PORT + 1
+
+//
+// Logical Device
+//
+#define SIO_COM                   0x3
+#define SIO_MSWC                  0x4
+#define SIO_MOUSE                 0x5
+#define SIO_KEYBOARD              0x6
+#define SIO_SHM                   0xF
+#define SIO_PM1                   0x11
+#define SIO_PM2                   0x12
+#define SIO_PM3                   0x17
+#define SIO_ESHM                  0x1D
+
+//
+// Global register
+//
+#define REG_LOGICAL_DEVICE        0x07
+#define REG_DEVICE_ID             0x20
+#define SIO_CONFIG_1              0x21
+#define REG_CHIP_REV              0x24
+#define SIO_CONFIG_5              0x25
+#define SIO_CONFIG_6              0x26
+#define REG_DEVICE_REV            0x27
+#define SIO_CONFIG_9              0x29
+#define SIO_CONFIG_D              0x2D
+
+#define ACTIVATE                  0x30
+#define BASE_ADDRESS_HIGH         0x60
+#define BASE_ADDRESS_LOW          0x61
+#define BASE_ADDRESS_HIGH2        0x62
+#define BASE_ADDRESS_LOW2         0x63
+#define PRIMARY_INTERRUPT_SELECT  0x70
+#define DMA_CHANNEL_SELECT        0x74
+
+EFI_STATUS
+InitializeLpcSio (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *RootBridgeIo
+  );
+
+//
+// Prototypes for the sio internal function
+//
+//
+// Internal function
+//
+VOID
+LPCWPCE791SetDefault (
+  VOID
+  );
+
+VOID
+WriteRegisterAndSaveToScript (
+  IN  UINT8   Index,
+  IN  UINT8   Data
+  );
+
+VOID
+FloppyWriteProtect (
+  VOID
+  );
+
+VOID
+DisableLogicalDevice (
+  UINT8       DeviceId
+  );
+
+#endif
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/Wpce791.inf b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/Wpce791.inf
new file mode 100644
index 0000000000..5fd458e265
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/Wpce791.inf
@@ -0,0 +1,63 @@
+#
+#
+# Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+#                                                                                  

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

+#
+#
+#
+#  Module Name:
+#
+#    SiO791.inf
+#
+#  Abstract:
+#
+#    Component description file for SIO791 module.
+#
+--*/
+
+[defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SIO791
+  FILE_GUID                      = 04A76C80-06B9-445e-B73E-CB8C61A6A964
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = LpcDriverEntryPoint
+
+[sources.common]
+ LpcIsaAcpi.h
+ LpcSio.h
+ LpcDriver.h
+ LpcIsaAcpi.c
+ LpcSio.c
+ LpcDriver.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+  PcAtChipsetPkg/PcAtChipsetPkg.dec
+
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  DevicePathLib
+  UefiLib
+  S3BootScriptLib
+  DebugLib
+
+[Ppis]
+
+[Protocols]
+  gEfiPciIoProtocolGuid
+  gEfiIsaAcpiProtocolGuid
+  gEfiLpcWpce791PolicyProtocolGuid
+
+[Guids]
+
+[Depex]
+  TRUE
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat b/Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat
new file mode 100644
index 0000000000..d8594053b0
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat
@@ -0,0 +1,332 @@
+@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
+echo.
+echo %date%  %time%
+echo.
+
+
+::**********************************************************************
+:: Initial Setup
+::**********************************************************************
+if %WORKSPACE:~-1%==\ set WORKSPACE=%WORKSPACE:~0,-1%
+set /a build_threads=1
+set "Build_Flags= "
+set exitCode=0
+set Arch=X64
+set Source=0
+set PLATFORM_NAME=Vlv2TbltDevicePkg
+
+set CORE_PATH=%WORKSPACE%
+if not exist %CORE_PATH%\edksetup.bat (
+  if defined PACKAGES_PATH (
+    for %%i IN (%PACKAGES_PATH%) DO (
+      if exist %%~fi\edksetup.bat (
+        set CORE_PATH=%%~fi
+        goto CorePathFound
+      )
+    )
+  ) else (
+    echo.
+    echo !!! ERROR !!! Cannot find edksetup.bat !!!
+    echo.
+    goto BldFail
+  )
+)
+:CorePathFound
+
+set PLATFORM_PACKAGE=%WORKSPACE%\%PLATFORM_NAME%
+if not exist %PLATFORM_PACKAGE% (
+  if defined PACKAGES_PATH (
+    for %%i IN (%PACKAGES_PATH%) DO (
+      if exist %%~fi\%PLATFORM_NAME% (
+        set PLATFORM_PACKAGE=%%~fi\%PLATFORM_NAME%
+        goto PlatformPackageFound
+      )
+    )
+  ) else (
+    echo.
+    echo !!! ERROR !!! Cannot find %PLATFORM_NAME% !!!
+    echo.
+    goto BldFail
+  )
+)
+:PlatformPackageFound
+
+cd %CORE_PATH%
+
+:: Clean up previous build files.
+if exist %WORKSPACE%\edk2.log del %WORKSPACE%\edk2.log
+if exist %WORKSPACE%\unitool.log del %WORKSPACE%\unitool.log
+if exist %WORKSPACE%\Conf\target.txt del %WORKSPACE%\Conf\target.txt
+if exist %WORKSPACE%\Conf\tools_def.txt del %WORKSPACE%\Conf\tools_def.txt
+if exist %WORKSPACE%\Conf\build_rule.txt del %WORKSPACE%\Conf\build_rule.txt
+if exist %WORKSPACE%\Conf\.cache rmdir /q/s %WORKSPACE%\Conf\.cache
+
+:: Setup EDK environment. Edksetup puts new copies of target.txt, tools_def.txt, build_rule.txt in WorkSpace\Conf
+:: Also run edksetup as soon as possible to avoid it from changing environment variables we're overriding
+call %CORE_PATH%\edksetup.bat Rebuild
+@echo off
+
+:: Define platform specific environment variables.
+set config_file=%PLATFORM_PACKAGE%\PlatformPkgConfig.dsc
+set auto_config_inc=%PLATFORM_PACKAGE%\AutoPlatformCFG.txt
+
+
+
+::create new AutoPlatformCFG.txt file
+copy /y nul %auto_config_inc% >nul
+
+::**********************************************************************
+:: Parse command line arguments
+::**********************************************************************
+
+:: Optional arguments
+:OptLoop
+if /i "%~1"=="/?" goto Usage
+
+if /i "%~1"=="/l" (
+    set Build_Flags=%Build_Flags% -j EDK2.log
+    shift
+    goto OptLoop
+)
+if /i "%~1"=="/y" (
+    set Build_Flags=%Build_Flags% -y %PLATFORM_PACKAGE%\EDK2_%PLATFORM_PACKAGE%.report
+    shift
+    goto OptLoop
+)
+if /i "%~1"=="/m" (
+    if defined NUMBER_OF_PROCESSORS (
+        set /a build_threads=%NUMBER_OF_PROCESSORS%+1
+    )
+    shift
+    goto OptLoop
+)
+if /i "%~1" == "/c" (
+    echo Removing previous build files ...
+    if exist build (
+        del /f/s/q build > nul
+        rmdir /s/q build
+    )
+    if exist %WORKSPACE%\Conf\.cache (
+        del /f/s/q %WORKSPACE%\Conf\.cache > nul
+        rmdir /s/q %WORKSPACE%\Conf\.cache
+    )
+    echo.
+    shift
+    goto OptLoop
+)
+
+if /i "%~1"=="/x64" (
+    set Arch=X64
+    shift
+    goto OptLoop
+)
+if /i "%~1"=="/IA32" (
+    set Arch=IA32
+    shift
+    goto OptLoop
+)
+
+:: Required argument(s)
+if "%~1"=="" goto Usage
+
+::Remove the values for Platform_Type and Build_Target from BiosIdX.env and stage in Conf\
+if "%Arch%"=="IA32" (
+    findstr /b /v "BOARD_ID  BUILD_TYPE" %PLATFORM_PACKAGE%\BiosIdR.env > %WORKSPACE%\Conf\BiosId.env
+    echo DEFINE X64_CONFIG = FALSE  >> %auto_config_inc%
+) else if "%Arch%"=="X64" (
+    findstr /b /v "BOARD_ID  BUILD_TYPE" %PLATFORM_PACKAGE%\BiosIdx64R.env > %WORKSPACE%\Conf\BiosId.env
+    echo DEFINE X64_CONFIG = TRUE  >> %auto_config_inc%
+)
+
+:: -- Build flags settings for each Platform --
+echo Setting  %1  platform configuration and BIOS ID...
+if /i "%~1" == "MNW2" (
+    echo BOARD_ID = MNW2MAX >> %WORKSPACE%\Conf\BiosId.env
+    echo DEFINE ENBDT_PF_BUILD = TRUE   >> %auto_config_inc%
+    
+) else (
+    echo Error - Unsupported PlatformType: %1
+    goto Usage
+)
+set Platform_Type=%~1
+
+if /i "%~2" == "RELEASE" (
+    set target=RELEASE
+    echo BUILD_TYPE = R >> %WORKSPACE%\Conf\BiosId.env
+) else (
+    set target=DEBUG
+    echo BUILD_TYPE = D >> %WORKSPACE%\Conf\BiosId.env
+)
+
+::**********************************************************************
+:: Additional EDK Build Setup/Configuration
+::**********************************************************************
+echo.
+echo Setting the Build environment for VS2015/VS2013/VS2012/VS2010/VS2008...
+if defined VS140COMNTOOLS (
+  if not defined VSINSTALLDIR call "%VS140COMNTOOLS%\vsvars32.bat"
+  if /I "%VS140COMNTOOLS%" == "C:\Program Files\Microsoft Visual Studio 14.0\Common7\Tools\" (
+    set TOOL_CHAIN_TAG=VS2015
+  ) else (
+    set TOOL_CHAIN_TAG=VS2015x86
+  ) 
+) else if defined VS120COMNTOOLS (
+  if not defined VSINSTALLDIR call "%VS120COMNTOOLS%\vsvars32.bat"
+  if /I "%VS120COMNTOOLS%" == "C:\Program Files\Microsoft Visual Studio 12.0\Common7\Tools\" (
+    set TOOL_CHAIN_TAG=VS2013
+  ) else (
+    set TOOL_CHAIN_TAG=VS2013x86
+  )
+) else if defined VS110COMNTOOLS (
+  if not defined VSINSTALLDIR call "%VS110COMNTOOLS%\vsvars32.bat"
+  if /I "%VS110COMNTOOLS%" == "C:\Program Files\Microsoft Visual Studio 11.0\Common7\Tools\" (
+    set TOOL_CHAIN_TAG=VS2012
+  ) else (
+    set TOOL_CHAIN_TAG=VS2012x86
+  )
+) else if defined VS100COMNTOOLS (
+  if not defined VSINSTALLDIR call "%VS100COMNTOOLS%\vsvars32.bat"
+  if /I "%VS100COMNTOOLS%" == "C:\Program Files\Microsoft Visual Studio 10.0\Common7\Tools\" (
+    set TOOL_CHAIN_TAG=VS2010
+  ) else (
+    set TOOL_CHAIN_TAG=VS2010x86
+  )
+) else if defined VS90COMNTOOLS (
+  if not defined VSINSTALLDIR call "%VS90COMNTOOLS%\vsvars32.bat"
+  if /I "%VS90COMNTOOLS%" == "C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\" (
+     set TOOL_CHAIN_TAG=VS2008
+  ) else (
+     set TOOL_CHAIN_TAG=VS2008x86
+  )
+) else (
+  echo  --ERROR: VS2015/VS2013/VS2012/VS2010/VS2008 not installed correctly. VS140COMNTOOLS/VS120COMNTOOLS/VS110COMNTOOLS/VS100COMNTOOLS/VS90COMNTOOLS not defined ^^!
+  echo.
+  goto :BldFail
+)
+
+echo Ensuring correct build directory is present for GenBiosId...
+set BUILD_PATH=%WORKSPACE%\Build\%PLATFORM_NAME%\%TARGET%_%TOOL_CHAIN_TAG%
+
+echo Modifing Conf files for this build...
+:: Remove lines with these tags from target.txt
+findstr /V "TARGET  TARGET_ARCH  TOOL_CHAIN_TAG  BUILD_RULE_CONF  ACTIVE_PLATFORM  MAX_CONCURRENT_THREAD_NUMBER" %WORKSPACE%\Conf\target.txt > %WORKSPACE%\Conf\target.txt.tmp
+
+echo TARGET          = %TARGET%                                  >> %WORKSPACE%\Conf\target.txt.tmp
+if "%Arch%"=="IA32" (
+    echo TARGET_ARCH = IA32                                       >> %WORKSPACE%\Conf\target.txt.tmp
+) else if "%Arch%"=="X64" (
+    echo TARGET_ARCH = IA32 X64                                  >> %WORKSPACE%\Conf\target.txt.tmp
+)
+echo TOOL_CHAIN_TAG  = %TOOL_CHAIN_TAG%                                  >> %WORKSPACE%\Conf\target.txt.tmp
+echo BUILD_RULE_CONF = Conf/build_rule.txt                               >> %WORKSPACE%\Conf\target.txt.tmp
+if %Source% == 0 (
+  echo ACTIVE_PLATFORM = %PLATFORM_PACKAGE%/PlatformPkg%Arch%.dsc        >> %WORKSPACE%\Conf\target.txt.tmp
+) else (
+  echo ACTIVE_PLATFORM = %PLATFORM_PACKAGE%/PlatformPkg%Arch%Source.dsc  >> %WORKSPACE%\Conf\target.txt.tmp
+)
+echo MAX_CONCURRENT_THREAD_NUMBER = %build_threads%                      >> %WORKSPACE%\Conf\target.txt.tmp
+
+move /Y %WORKSPACE%\Conf\target.txt.tmp %WORKSPACE%\Conf\target.txt >nul
+
+::**********************************************************************
+:: Build BIOS
+::**********************************************************************
+
+echo Creating BiosId...
+if not exist %BUILD_PATH%\IA32  mkdir %BUILD_PATH%\IA32
+%PLATFORM_PACKAGE%\GenBiosId.exe -i %WORKSPACE%\Conf\BiosId.env -o %BUILD_PATH%\IA32\BiosId.bin -ob %WORKSPACE%\Conf\BiosId.bat
+if "%Arch%"=="X64" (
+   if not exist %BUILD_PATH%\X64  mkdir %BUILD_PATH%\X64
+   %PLATFORM_PACKAGE%\GenBiosId.exe -i %WORKSPACE%\Conf\BiosId.env -o %BUILD_PATH%\X64\BiosId.bin -ob %WORKSPACE%\Conf\BiosId.bat
+)
+
+if %ERRORLEVEL% NEQ 0 goto BldFail
+
+echo.
+echo Invoking EDK2 build...
+call build %Build_Flags%
+
+if %ERRORLEVEL% NEQ 0 goto BldFail
+
+::**********************************************************************
+:: Post Build processing and cleanup
+::**********************************************************************
+
+echo Running fce...
+
+pushd %PLATFORM_PACKAGE%
+:: Extract Hii data from build and store in HiiDefaultData.txt
+%PLATFORM_PACKAGE%\fce read -i %BUILD_PATH%\FV\Vlv.fd > %BUILD_PATH%\FV\HiiDefaultData.txt
+
+:: save changes to VlvXXX.fd
+%PLATFORM_PACKAGE%\fce update -i %BUILD_PATH%\FV\Vlv.fd -s %BUILD_PATH%\FV\HiiDefaultData.txt -o %BUILD_PATH%\FV\Vlv%Arch%.fd
+popd
+
+if %ERRORLEVEL% NEQ 0 goto BldFail
+::echo FD successfully updated with default Hii values.
+
+:: 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
+copy /y/b %BUILD_PATH%\FV\Vlv%Arch%.fd  %PLATFORM_PACKAGE%\Stitch\%BIOS_Name% >nul
+copy /y/b %BUILD_PATH%\FV\Vlv%Arch%.fd  %BUILD_PATH%\FV\Vlv.ROM >nul
+
+echo.
+echo Build location:     %BUILD_PATH%
+echo BIOS ROM Created:   %BIOS_Name%
+echo.
+echo -------------------- The EDKII BIOS build has successfully completed. --------------------
+echo.
+
+@REM build capsule here
+echo > %BUILD_PATH%\FV\SYSTEMFIRMWAREUPDATECARGO.Fv
+build -p %PLATFORM_PACKAGE%\PlatformCapsule.dsc
+
+goto Exit
+
+:Usage
+echo.
+echo ***************************************************************************
+echo Build BIOS rom for VLV platforms.
+echo.
+echo Usage: bld_vlv.bat [options] PlatformType [Build Target]
+echo.
+echo    /c    CleanAll before building
+echo    /l    Generate build log file
+echo    /y    Generate build report file
+echo    /m    Enable multi-processor build
+echo    /IA32 Set Arch to IA32 (default: X64)
+echo    /X64  Set Arch to X64 (default: X64)
+echo.
+echo        Platform Types:  MNW2
+echo        Build Targets:   Debug, Release  (default: Debug)
+echo.
+echo Examples:
+echo    bld_vlv.bat MNW2                 : X64 Debug build for MinnowMax
+echo    bld_vlv.bat /IA32 MNW2 release   : IA32 Release build for MinnowMax
+echo.
+echo ***************************************************************************
+set exitCode=1
+goto Exit
+
+:BldFail
+set exitCode=1
+echo  -- Error:  EDKII BIOS Build has failed!
+echo See EDK2.log for more details
+
+:Exit
+echo %date%  %time%
+exit /b %exitCode%
+
+EndLocal
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh b/Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh
new file mode 100644
index 0000000000..ec3a325db7
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh
@@ -0,0 +1,256 @@
+#!/usr/bin/env bash
+##**********************************************************************
+## Function define
+##**********************************************************************
+function Usage() {
+  echo
+  echo "***************************************************************************"
+  echo "Build BIOS rom for VLV platforms."
+  echo
+  echo "Usage: bld_vlv.bat  PlatformType [Build Target]"
+  echo
+  echo
+  echo "       Platform Types:  MNW2"
+  echo "       Build Targets:   Debug, Release  (default: Debug)"
+  echo
+  echo "***************************************************************************"
+  echo "Press any key......"
+  read
+  exit 0
+}
+
+
+echo -e $(date)
+##**********************************************************************
+## Initial Setup
+##**********************************************************************
+#WORKSPACE=$(pwd)
+#build_threads=($NUMBER_OF_PROCESSORS)+1
+Build_Flags=
+exitCode=0
+Arch=X64
+SpiLock=0
+
+## Clean up previous build files.
+if [ -e $(pwd)/EDK2.log ]; then
+  rm $(pwd)/EDK2.log
+fi
+
+if [ -e $(pwd)/Unitool.log ]; then
+  rm $(pwd)/Unitool.log
+fi
+
+if [ -e $(pwd)/Conf/target.txt ]; then
+  rm $(pwd)/Conf/target.txt
+fi
+
+if [ -e $(pwd)/Conf/BiosId.env ]; then
+  rm $(pwd)/Conf/BiosId.env
+fi
+
+if [ -e $(pwd)/Conf/tools_def.txt ]; then
+  rm $(pwd)/Conf/tools_def.txt
+fi
+
+if [ -e $(pwd)/Conf/build_rule.txt ]; then
+  rm $(pwd)/Conf/build_rule.txt
+fi
+
+
+## Setup EDK environment. Edksetup puts new copies of target.txt, tools_def.txt, build_rule.txt in WorkSpace\Conf
+## Also run edksetup as soon as possible to avoid it from changing environment variables we're overriding
+. edksetup.sh BaseTools
+make -C BaseTools
+
+## Define platform specific environment variables.
+PLATFORM_PACKAGE=Vlv2TbltDevicePkg
+config_file=$WORKSPACE/$PLATFORM_PACKAGE/PlatformPkgConfig.dsc
+auto_config_inc=$WORKSPACE/$PLATFORM_PACKAGE/AutoPlatformCFG.txt
+
+## default ECP (override with /ECP flag)
+EDK_SOURCE=$WORKSPACE/EdkCompatibilityPkg
+
+## create new AutoPlatformCFG.txt file
+if [ -f "$auto_config_inc" ]; then
+  rm $auto_config_inc
+fi
+touch $auto_config_inc
+
+##**********************************************************************
+## Parse command line arguments
+##**********************************************************************
+
+## Optional arguments
+for (( i=1; i<=$#; ))
+  do
+    if [ "$1" == "/?" ]; then
+      Usage
+    elif [ "$(echo $1 | tr 'a-z' 'A-Z')" == "/Q" ]; then
+      Build_Flags="$Build_Flags --quiet"
+      shift
+    elif [ "$(echo $1 | tr 'a-z' 'A-Z')" == "/L" ]; then
+      Build_Flags="$Build_Flags -j EKD2.log"
+      shift
+    elif [ "$(echo $1 | tr 'a-z' 'A-Z')" == "/C" ]; then
+      echo Removing previous build files ...
+      if [ -d "Build" ]; then
+        rm -r Build
+      fi
+      shift
+    elif [ "$(echo $1 | tr 'a-z' 'A-Z')" == "/ECP" ]; then
+      ECP_SOURCE=$WORKSPACE/EdkCompatibilityPkgEcp
+      EDK_SOURCE=$WORKSPACE/EdkCompatibilityPkgEcp
+      echo DEFINE ECP_BUILD_ENABLE = TRUE >> $auto_config_inc
+      shift
+    elif [ "$(echo $1 | tr 'a-z' 'A-Z')" == "/X64" ]; then
+      Arch=X64
+      shift
+    elif [ "$(echo $1 | tr 'a-z' 'A-Z')" == "/YL" ]; then
+      SpiLock=1
+      shift      
+    else
+      break
+    fi
+  done
+
+
+
+
+
+## Required argument(s)
+if [ "$2" == "" ]; then
+  Usage
+fi
+
+## Remove the values for Platform_Type and Build_Target from BiosIdX.env and stage in Conf
+if [ $Arch == "IA32" ]; then
+  cp $PLATFORM_PACKAGE/BiosIdR.env    Conf/BiosId.env
+  echo DEFINE X64_CONFIG = FALSE      >> $auto_config_inc
+else
+  cp $PLATFORM_PACKAGE/BiosIdx64R.env  Conf/BiosId.env
+  echo DEFINE X64_CONFIG = TRUE       >> $auto_config_inc
+fi
+sed -i '/^BOARD_ID/d' Conf/BiosId.env
+sed -i '/^BUILD_TYPE/d' Conf/BiosId.env
+
+
+
+## -- Build flags settings for each Platform --
+##    AlpineValley (ALPV):  SVP_PF_BUILD = TRUE,   ENBDT_PF_BUILD = FALSE,  TABLET_PF_BUILD = FALSE,  BYTI_PF_BUILD = FALSE, IVI_PF_BUILD = FALSE
+##       BayleyBay (BBAY):  SVP_PF_BUILD = FALSE,  ENBDT_PF_BUILD = TRUE,   TABLET_PF_BUILD = FALSE,  BYTI_PF_BUILD = FALSE, IVI_PF_BUILD = FALSE
+##         BayLake (BLAK):  SVP_PF_BUILD = FALSE,  ENBDT_PF_BUILD = FALSE,  TABLET_PF_BUILD = TRUE,   BYTI_PF_BUILD = FALSE, IVI_PF_BUILD = FALSE
+##      Bakersport (BYTI):  SVP_PF_BUILD = FALSE,  ENBDT_PF_BUILD = FALSE,  TABLET_PF_BUILD = FALSE,  BYTI_PF_BUILD = TRUE, IVI_PF_BUILD = FALSE
+## Crestview Hills (CVHS):  SVP_PF_BUILD = FALSE,  ENBDT_PF_BUILD = FALSE,  TABLET_PF_BUILD = FALSE,  BYTI_PF_BUILD = TRUE, IVI_PF_BUILD = TRUE
+##            FFD8 (BLAK):  SVP_PF_BUILD = FALSE,  ENBDT_PF_BUILD = FALSE,  TABLET_PF_BUILD = TRUE,   BYTI_PF_BUILD = FALSE, IVI_PF_BUILD = FALSE
+echo "Setting  $1  platform configuration and BIOS ID..."
+if [ "$(echo $1 | tr 'a-z' 'A-Z')" == "MNW2" ]; then
+  echo BOARD_ID = MNW2MAX             >> Conf/BiosId.env
+  echo DEFINE ENBDT_PF_BUILD = TRUE  >> $auto_config_inc
+else
+  echo "Error - Unsupported PlatformType: $1"
+  Usage
+fi
+
+Platform_Type=$1
+
+if [ "$(echo $2 | tr 'a-z' 'A-Z')" == "RELEASE" ]; then
+  TARGET=RELEASE
+  BUILD_TYPE=R
+  echo BUILD_TYPE = R >> Conf/BiosId.env
+else
+  TARGET=DEBUG
+  BUILD_TYPE=D
+  echo BUILD_TYPE = D >> Conf/BiosId.env
+fi
+
+
+##**********************************************************************
+## Additional EDK Build Setup/Configuration
+##**********************************************************************
+echo "Ensuring correct build directory is present for GenBiosId..."
+
+echo Modifing Conf files for this build...
+## Remove lines with these tags from target.txt
+sed -i '/^ACTIVE_PLATFORM/d' Conf/target.txt
+sed -i '/^TARGET /d' Conf/target.txt
+sed -i '/^TARGET_ARCH/d' Conf/target.txt
+sed -i '/^TOOL_CHAIN_TAG/d' Conf/target.txt
+sed -i '/^MAX_CONCURRENT_THREAD_NUMBER/d' Conf/target.txt
+
+gcc_version=$(gcc -v 2>&1 | tail -1 | awk '{print $3}')
+case $gcc_version in
+    4.9.*|4.1[0-9].*|5.*.*|6.*.*)
+      TARGET_TOOLS=GCC49
+      ;;
+    *)
+      TARGET_TOOLS=GCC48
+      ;;
+esac
+
+ACTIVE_PLATFORM=$PLATFORM_PACKAGE/PlatformPkgGcc"$Arch".dsc
+TOOL_CHAIN_TAG=$TARGET_TOOLS
+MAX_CONCURRENT_THREAD_NUMBER=1
+echo ACTIVE_PLATFORM = $ACTIVE_PLATFORM                           >> Conf/target.txt
+echo TARGET          = $TARGET                                    >> Conf/target.txt
+echo TOOL_CHAIN_TAG  = $TOOL_CHAIN_TAG                            >> Conf/target.txt
+echo MAX_CONCURRENT_THREAD_NUMBER = $MAX_CONCURRENT_THREAD_NUMBER >> Conf/target.txt
+if [ $Arch == "IA32" ]; then
+  echo TARGET_ARCH   = IA32                                       >> Conf/target.txt
+else
+  echo TARGET_ARCH   = IA32 X64                                   >> Conf/target.txt
+fi
+
+##**********************************************************************
+## Build BIOS
+##**********************************************************************
+echo Skip "Running UniTool..."
+echo "Make GenBiosId Tool..."
+BUILD_PATH=Build/$PLATFORM_PACKAGE/"$TARGET"_"$TOOL_CHAIN_TAG"
+if [ ! -d "$BUILD_PATH/$Arch" ]; then
+  mkdir -p $BUILD_PATH/$Arch
+fi
+if [ -e "$BUILD_PATH/$Arch/BiosId.bin" ]; then
+  rm -f $BUILD_PATH/$Arch/BiosId.bin
+fi
+
+
+./$PLATFORM_PACKAGE/GenBiosId -i Conf/BiosId.env -o $BUILD_PATH/$Arch/BiosId.bin
+
+
+echo "Invoking EDK2 build..."
+build
+
+if [ $SpiLock == "1" ]; then
+  IFWI_HEADER_FILE=./$PLATFORM_PACKAGE/Stitch/IFWIHeader/IFWI_HEADER_SPILOCK.bin
+else
+  IFWI_HEADER_FILE=./$PLATFORM_PACKAGE/Stitch/IFWIHeader/IFWI_HEADER.bin
+fi
+
+echo $IFWI_HEADER_FILE
+
+##**********************************************************************
+## Post Build processing and cleanup
+##**********************************************************************
+
+echo Skip "Running fce..."
+
+echo Skip "Running KeyEnroll..."
+
+## Set the Board_Id, Build_Type, Version_Major, and Version_Minor environment variables
+VERSION_MAJOR=$(grep '^VERSION_MAJOR' Conf/BiosId.env | cut -d ' ' -f 3 | cut -c 1-4)
+VERSION_MINOR=$(grep '^VERSION_MINOR' Conf/BiosId.env | cut -d ' ' -f 3 | cut -c 1-2)
+BOARD_ID=$(grep '^BOARD_ID' Conf/BiosId.env | cut -d ' ' -f 3 | cut -c 1-7)
+BIOS_Name="$BOARD_ID"_"$Arch"_"$BUILD_TYPE"_"$VERSION_MAJOR"_"$VERSION_MINOR".ROM
+BIOS_ID="$BOARD_ID"_"$Arch"_"$BUILD_TYPE"_"$VERSION_MAJOR"_"$VERSION_MINOR"_GCC.bin
+SEC_VERSION=1.0.2.1060v5
+cat $IFWI_HEADER_FILE ../Vlv2Binaries/Vlv2SocBinPkg/SEC/$SEC_VERSION/VLV_SEC_REGION.bin ../Vlv2Binaries/Vlv2SocBinPkg/SEC/$SEC_VERSION/Vacant.bin $BUILD_PATH/FV/VLV.fd > ./$PLATFORM_PACKAGE/Stitch/$BIOS_ID
+
+
+echo Skip "Running BIOS_Signing ..."
+
+echo
+echo Build location:     $BUILD_PATH
+echo BIOS ROM Created:   $BIOS_Name
+echo
+echo -------------------- The EDKII BIOS build has successfully completed. --------------------
+echo
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/cln.sh b/Platform/Intel/Vlv2TbltDevicePkg/cln.sh
new file mode 100644
index 0000000000..3511695f6f
--- /dev/null
+++ b/Platform/Intel/Vlv2TbltDevicePkg/cln.sh
@@ -0,0 +1,62 @@
+#!/usr/bin/env bash
+echo
+echo Run build cleanall...
+echo
+
+echo
+echo Directories to clean...
+echo
+
+cd ..
+
+if [ -d "Build" ]; then
+  rm -r Build
+fi
+
+if [ -d "Conf/.cache" ]; then
+  rm -r Conf/.cache
+fi
+
+if [ -d "RomImages" ]; then
+  rm -r RomImages
+fi
+
+echo
+echo Files to clean...
+echo
+
+if [ -e $(pwd)/EDK2.log ]; then
+  rm $(pwd)/EDK2.log
+fi
+
+if [ -e $(pwd)/Unitool.log ]; then
+  rm $(pwd)/Unitool.log
+fi
+
+if [ -e $(pwd)/Conf/target.txt ]; then
+  rm $(pwd)/Conf/target.txt
+fi
+
+if [ -e $(pwd)/Conf/BiosId.env ]; then
+  rm $(pwd)/Conf/BiosId.env
+fi
+
+if [ -e $(pwd)/Conf/tools_def.txt ]; then
+  rm $(pwd)/Conf/tools_def.txt
+fi
+
+if [ -e $(pwd)/Conf/build_rule.txt ]; then
+  rm $(pwd)/Conf/build_rule.txt
+fi
+
+if [ -e $(pwd)/Conf/BuildEnv.sh ]; then
+  rm $(pwd)/Conf/BuildEnv.sh
+fi
+
+if [ -e $(pwd)/Vlv2TbltDevicePkg/AutoPlatformCFG.txt ]; then
+  rm $(pwd)/Vlv2TbltDevicePkg/AutoPlatformCFG.txt
+fi
+
+echo
+echo All done...
+echo
-- 
2.21.0.windows.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [edk2-platforms: Patch 7/8] Drivers/OptionRomPkg: Import OptionRomPkg from edk2
  2019-05-10  3:34 [edk2-platforms: Patch 0/8] Add packages from edk2 Michael D Kinney
                   ` (5 preceding siblings ...)
  2019-05-10  3:34 ` [edk2-platforms: Patch 6/8] Platform/Vlv2TbltDevicePkg: Import Vlv2TbltDevicePkg " Michael D Kinney
@ 2019-05-10  3:34 ` Michael D Kinney
  2019-05-11  1:52   ` Ni, Ray
  2019-05-10  3:34 ` [edk2-platforms: Patch 8/8] edk2-platforms: Update Maintainers.txt/Readme.md for imported packages Michael D Kinney
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 23+ messages in thread
From: Michael D Kinney @ 2019-05-10  3:34 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Leif Lindholm, Ard Biesheuvel

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

Import OptionRomPkg from edk2/master.

Cc: Ray Ni <ray.ni@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>
---
 .../Application/BltLibSample/BltLibSample.c   |  279 ++
 .../Application/BltLibSample/BltLibSample.inf |   30 +
 .../AtapiPassThruDxe/AtapiPassThru.c          | 3410 ++++++++++++++++
 .../AtapiPassThruDxe/AtapiPassThru.h          | 1618 ++++++++
 .../AtapiPassThruDxe/AtapiPassThruDxe.inf     |   70 +
 .../AtapiPassThruDxe/ComponentName.c          |  169 +
 .../DriverSupportedEfiVersion.c               |   14 +
 .../FtdiUsbSerialDxe/CompatibleDevices.txt    |    5 +
 .../Bus/Usb/FtdiUsbSerialDxe/ComponentName.c  |  218 +
 .../FtdiUsbSerialDxe/FtdiUsbSerialDriver.c    | 2580 ++++++++++++
 .../FtdiUsbSerialDxe/FtdiUsbSerialDriver.h    |  589 +++
 .../Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf |   55 +
 .../Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt       |   32 +
 .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.c   | 1318 ++++++
 .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.h   |  969 +++++
 .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf |   61 +
 .../Usb/UsbNetworking/Ax88772/ComponentName.c |  178 +
 .../Usb/UsbNetworking/Ax88772/DriverBinding.c |  507 +++
 .../Usb/UsbNetworking/Ax88772/SimpleNetwork.c | 1503 +++++++
 .../Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c  |  875 ++++
 .../Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h  | 1026 +++++
 .../Usb/UsbNetworking/Ax88772b/Ax88772b.inf   |   61 +
 .../UsbNetworking/Ax88772b/ComponentName.c    |  175 +
 .../UsbNetworking/Ax88772b/DriverBinding.c    |  696 ++++
 .../UsbNetworking/Ax88772b/SimpleNetwork.c    | 1657 ++++++++
 .../CirrusLogic5430Dxe/CirrusLogic5430.c      |  917 +++++
 .../CirrusLogic5430Dxe/CirrusLogic5430.h      |  432 ++
 .../CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf |   84 +
 .../CirrusLogic5430GraphicsOutput.c           |  556 +++
 .../CirrusLogic5430Dxe/CirrusLogic5430I2c.c   |  427 ++
 .../CirrusLogic5430Dxe/CirrusLogic5430I2c.h   |   62 +
 .../CirrusLogic5430UgaDraw.c                  |  412 ++
 .../CirrusLogic5430Dxe/ComponentName.c        |  203 +
 .../DriverSupportedEfiVersion.c               |   14 +
 .../OptionRomPkg/CirrusLogic5430Dxe/Edid.c    |  525 +++
 Drivers/OptionRomPkg/Include/Library/BltLib.h |  253 ++
 .../FrameBufferBltLib/FrameBufferBltLib.c     |  744 ++++
 .../FrameBufferBltLib/FrameBufferBltLib.inf   |   29 +
 .../Library/GopBltLib/GopBltLib.c             |  449 +++
 .../Library/GopBltLib/GopBltLib.inf           |   31 +
 Drivers/OptionRomPkg/OptionRomPkg.dec         |   41 +
 Drivers/OptionRomPkg/OptionRomPkg.dsc         |  113 +
 Drivers/OptionRomPkg/ReadMe.txt               |   17 +
 .../UndiRuntimeDxe/ComponentName.c            |  359 ++
 Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c  | 1516 +++++++
 Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c   | 3541 +++++++++++++++++
 Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h   |  665 ++++
 Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c    | 1051 +++++
 Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h  |  439 ++
 .../OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c |  145 +
 .../UndiRuntimeDxe/UndiRuntimeDxe.inf         |   72 +
 51 files changed, 31192 insertions(+)
 create mode 100644 Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.c
 create mode 100644 Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.inf
 create mode 100644 Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.c
 create mode 100644 Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.h
 create mode 100644 Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThruDxe.inf
 create mode 100644 Drivers/OptionRomPkg/AtapiPassThruDxe/ComponentName.c
 create mode 100644 Drivers/OptionRomPkg/AtapiPassThruDxe/DriverSupportedEfiVersion.c
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/CompatibleDevices.txt
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ComponentName.c
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.c
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.h
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.c
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.h
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/ComponentName.c
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/DriverBinding.c
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/SimpleNetwork.c
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/ComponentName.c
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/DriverBinding.c
 create mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwork.c
 create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.c
 create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.h
 create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf
 create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430GraphicsOutput.c
 create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.c
 create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.h
 create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430UgaDraw.c
 create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/ComponentName.c
 create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/DriverSupportedEfiVersion.c
 create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/Edid.c
 create mode 100644 Drivers/OptionRomPkg/Include/Library/BltLib.h
 create mode 100644 Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.c
 create mode 100644 Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
 create mode 100644 Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.c
 create mode 100644 Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.inf
 create mode 100644 Drivers/OptionRomPkg/OptionRomPkg.dec
 create mode 100644 Drivers/OptionRomPkg/OptionRomPkg.dsc
 create mode 100644 Drivers/OptionRomPkg/ReadMe.txt
 create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/ComponentName.c
 create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c
 create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c
 create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h
 create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c
 create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h
 create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c
 create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf

diff --git a/Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.c b/Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.c
new file mode 100644
index 0000000000..6f901383b6
--- /dev/null
+++ b/Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.c
@@ -0,0 +1,279 @@
+/** @file
+  Example program using BltLib
+
+  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/BltLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiApplicationEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+
+UINT64
+ReadTimestamp (
+  VOID
+  )
+{
+#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
+  return AsmReadTsc ();
+#else
+#error ReadTimestamp not supported for this architecture!
+#endif
+}
+
+UINT32
+Rand32 (
+  VOID
+  )
+{
+  UINTN    Found;
+  INTN     Bits;
+  UINT64   Tsc1;
+  UINT64   Tsc2;
+  UINT64   TscBits;
+  UINT32   R32;
+
+  R32 = 0;
+  Found = 0;
+  Tsc1 = ReadTimestamp ();
+  Tsc2 = ReadTimestamp ();
+  do {
+    Tsc2 = ReadTimestamp ();
+    TscBits = Tsc2 ^ Tsc1;
+    Bits = HighBitSet64 (TscBits);
+    if (Bits > 0) {
+      Bits = Bits - 1;
+    }
+    R32 = (UINT32)((R32 << Bits) |
+                   RShiftU64 (LShiftU64 (TscBits, (UINTN) (64 - Bits)), (UINTN) (64 - Bits)));
+    Found = Found + Bits;
+  } while (Found < 32);
+
+  return R32;
+}
+
+
+VOID
+TestFills (
+  VOID
+  )
+{
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Color;
+  UINTN                          Loop;
+  UINTN                          X;
+  UINTN                          Y;
+  UINTN                          W;
+  UINTN                          H;
+  UINTN                          Width;
+  UINTN                          Height;
+
+  BltLibGetSizes (&Width, &Height);
+  for (Loop = 0; Loop < 10000; Loop++) {
+    W = Width - (Rand32 () % Width);
+    H = Height - (Rand32 () % Height);
+    if (W != Width) {
+      X = Rand32 () % (Width - W);
+    } else {
+      X = 0;
+    }
+    if (H != Height) {
+      Y = Rand32 () % (Height - H);
+    } else {
+      Y = 0;
+    }
+    *(UINT32*) (&Color) = Rand32 () & 0xffffff;
+    BltLibVideoFill (&Color, X, Y, W, H);
+  }
+}
+
+
+VOID
+TestColor1 (
+  VOID
+  )
+{
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Color;
+  UINTN                          X;
+  UINTN                          Y;
+  UINTN                          Width;
+  UINTN                          Height;
+
+  BltLibGetSizes (&Width, &Height);
+  *(UINT32*) (&Color) = 0;
+
+  for (Y = 0; Y < Height; Y++) {
+    for (X = 0; X < Width; X++) {
+      Color.Red =   (UINT8) ((X * 0x100) / Width);
+      Color.Green = (UINT8) ((Y * 0x100) / Height);
+      Color.Blue =  (UINT8) ((Y * 0x100) / Height);
+      BltLibVideoFill (&Color, X, Y, 1, 1);
+    }
+  }
+}
+
+
+UINT32
+Uint32SqRt (
+  IN  UINT32  Uint32
+  )
+{
+  UINT32 Mask;
+  UINT32 SqRt;
+  UINT32 SqRtMask;
+  UINT32 Squared;
+
+  if (Uint32 == 0) {
+    return 0;
+  }
+
+  for (SqRt = 0, Mask = (UINT32) (1 << (HighBitSet32 (Uint32) / 2));
+       Mask != 0;
+       Mask = Mask >> 1
+      ) {
+    SqRtMask = SqRt | Mask;
+    //DEBUG ((EFI_D_INFO, "Uint32=0x%x SqRtMask=0x%x\n", Uint32, SqRtMask));
+    Squared = (UINT32) (SqRtMask * SqRtMask);
+    if (Squared > Uint32) {
+      continue;
+    } else if (Squared < Uint32) {
+      SqRt = SqRtMask;
+    } else {
+      return SqRtMask;
+    }
+  }
+
+  return SqRt;
+}
+
+
+UINT32
+Uint32Dist (
+  IN UINTN X,
+  IN UINTN Y
+  )
+{
+  return Uint32SqRt ((UINT32) ((X * X) + (Y * Y)));
+}
+
+UINT8
+GetTriColor (
+  IN UINTN ColorDist,
+  IN UINTN TriWidth
+  )
+{
+  return (UINT8) (((TriWidth - ColorDist) * 0x100) / TriWidth);
+  //return (((TriWidth * TriWidth - ColorDist * ColorDist) * 0x100) / (TriWidth * TriWidth));
+}
+
+VOID
+TestColor (
+  VOID
+  )
+{
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Color;
+  UINTN                          X, Y;
+  UINTN                          X1, X2, X3;
+  UINTN                          Y1, Y2;
+  UINTN                          LineWidth, TriWidth, ScreenWidth;
+  UINTN                          TriHeight, ScreenHeight;
+  UINT32                         ColorDist;
+
+  BltLibGetSizes (&ScreenWidth, &ScreenHeight);
+  *(UINT32*) (&Color) = 0;
+  BltLibVideoFill (&Color, 0, 0, ScreenWidth, ScreenHeight);
+
+  TriWidth = (UINTN) DivU64x32 (
+                       MultU64x32 (11547005, (UINT32) ScreenHeight),
+                       10000000
+                       );
+  TriHeight = (UINTN) DivU64x32 (
+                        MultU64x32 (8660254, (UINT32) ScreenWidth),
+                        10000000
+                        );
+  if (TriWidth > ScreenWidth) {
+    DEBUG ((EFI_D_INFO, "TriWidth at %d was too big\n", TriWidth));
+    TriWidth = ScreenWidth;
+  } else if (TriHeight > ScreenHeight) {
+    DEBUG ((EFI_D_INFO, "TriHeight at %d was too big\n", TriHeight));
+    TriHeight = ScreenHeight;
+  }
+
+  DEBUG ((EFI_D_INFO, "Triangle Width: %d; Height: %d\n", TriWidth, TriHeight));
+
+  X1 = (ScreenWidth - TriWidth) / 2;
+  X3 = X1 + TriWidth - 1;
+  X2 = (X1 + X3) / 2;
+  Y2 = (ScreenHeight - TriHeight) / 2;
+  Y1 = Y2 + TriHeight - 1;
+
+  for (Y = Y2; Y <= Y1; Y++) {
+    LineWidth =
+      (UINTN) DivU64x32 (
+                MultU64x32 (11547005, (UINT32) (Y - Y2)),
+                20000000
+                );
+    for (X = X2 - LineWidth; X < (X2 + LineWidth); X++) {
+      ColorDist = Uint32Dist(X - X1, Y1 - Y);
+      Color.Red = GetTriColor (ColorDist, TriWidth);
+
+      ColorDist = Uint32Dist((X < X2) ? X2 - X : X - X2, Y - Y2);
+      Color.Green = GetTriColor (ColorDist, TriWidth);
+
+      ColorDist = Uint32Dist(X3 - X, Y1 - Y);
+      Color.Blue = GetTriColor (ColorDist, TriWidth);
+
+      BltLibVideoFill (&Color, X, Y, 1, 1);
+    }
+  }
+}
+
+
+/**
+  The user Entry Point for Application. The user code starts with this function
+  as the real entry point for the application.
+
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
+  @param[in] SystemTable    A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS       The entry point is executed successfully.
+  @retval other             Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+UefiMain (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS                     Status;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL   *Gop;
+
+  Status = gBS->HandleProtocol (
+                  gST->ConsoleOutHandle,
+                  &gEfiGraphicsOutputProtocolGuid,
+                  (VOID **) &Gop
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = BltLibConfigure (
+             (VOID*)(UINTN) Gop->Mode->FrameBufferBase,
+             Gop->Mode->Info
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  TestFills ();
+
+  TestColor ();
+
+  return EFI_SUCCESS;
+}
diff --git a/Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.inf b/Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.inf
new file mode 100644
index 0000000000..b544f960ab
--- /dev/null
+++ b/Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.inf
@@ -0,0 +1,30 @@
+## @file
+#  Test the BltLib interface
+#
+#  Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BltLibSample
+  FILE_GUID                      = f7763316-8c04-41d8-a87d-45b73c13c43c
+  MODULE_TYPE                    = UEFI_APPLICATION
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = UefiMain
+
+[Sources]
+  BltLibSample.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OptionRomPkg/OptionRomPkg.dec
+
+[LibraryClasses]
+  BltLib
+  UefiApplicationEntryPoint
+  UefiLib
+
diff --git a/Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.c b/Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.c
new file mode 100644
index 0000000000..20de2bc392
--- /dev/null
+++ b/Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.c
@@ -0,0 +1,3410 @@
+/** @file
+  Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "AtapiPassThru.h"
+
+
+SCSI_COMMAND_SET     gEndTable = { 0xff, (DATA_DIRECTION) 0xff };
+
+///
+/// This table contains all the supported ATAPI commands.
+///
+SCSI_COMMAND_SET     gSupportedATAPICommands[] = {
+  { OP_INQUIRY,                     DataIn  },
+  { OP_LOAD_UNLOAD_CD,              NoData  },
+  { OP_MECHANISM_STATUS,            DataIn  },
+  { OP_MODE_SELECT_10,              DataOut },
+  { OP_MODE_SENSE_10,               DataIn  },
+  { OP_PAUSE_RESUME,                NoData  },
+  { OP_PLAY_AUDIO_10,               DataIn  },
+  { OP_PLAY_AUDIO_MSF,              DataIn  },
+  { OP_PLAY_CD,                     DataIn  },
+  { OP_PLAY_CD_MSF,                 DataIn  },
+  { OP_PREVENT_ALLOW_MEDIUM_REMOVAL,NoData  },
+  { OP_READ_10,                     DataIn  },
+  { OP_READ_12,                     DataIn  },
+  { OP_READ_CAPACITY,               DataIn  },
+  { OP_READ_CD,                     DataIn  },
+  { OP_READ_CD_MSF,                 DataIn  },
+  { OP_READ_HEADER,                 DataIn  },
+  { OP_READ_SUB_CHANNEL,            DataIn  },
+  { OP_READ_TOC,                    DataIn  },
+  { OP_REQUEST_SENSE,               DataIn  },
+  { OP_SCAN,                        NoData  },
+  { OP_SEEK_10,                     NoData  },
+  { OP_SET_CD_SPEED,                DataOut },
+  { OP_STOPPLAY_SCAN,               NoData  },
+  { OP_START_STOP_UNIT,             NoData  },
+  { OP_TEST_UNIT_READY,             NoData  },
+  { OP_FORMAT_UNIT,                 DataOut },
+  { OP_READ_FORMAT_CAPACITIES,      DataIn  },
+  { OP_VERIFY,                      DataOut },
+  { OP_WRITE_10,                    DataOut },
+  { OP_WRITE_12,                    DataOut },
+  { OP_WRITE_AND_VERIFY,            DataOut },
+  { 0xff,                           (DATA_DIRECTION) 0xff    }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_SCSI_PASS_THRU_MODE gScsiPassThruMode = {
+  L"ATAPI Controller",
+  L"ATAPI Channel",
+  4,
+  EFI_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL,
+  0
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_SCSI_PASS_THRU_PROTOCOL gScsiPassThruProtocolTemplate = {
+  &gScsiPassThruMode,
+  AtapiScsiPassThruFunction,
+  AtapiScsiPassThruGetNextDevice,
+  AtapiScsiPassThruBuildDevicePath,
+  AtapiScsiPassThruGetTargetLun,
+  AtapiScsiPassThruResetChannel,
+  AtapiScsiPassThruResetTarget
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_EXT_SCSI_PASS_THRU_MODE gExtScsiPassThruMode = {
+  4,
+  EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL,
+  0
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_EXT_SCSI_PASS_THRU_PROTOCOL gExtScsiPassThruProtocolTemplate = {
+  &gExtScsiPassThruMode,
+  AtapiExtScsiPassThruFunction,
+  AtapiExtScsiPassThruGetNextTargetLun,
+  AtapiExtScsiPassThruBuildDevicePath,
+  AtapiExtScsiPassThruGetTargetLun,
+  AtapiExtScsiPassThruResetChannel,
+  AtapiExtScsiPassThruResetTarget,
+  AtapiExtScsiPassThruGetNextTarget
+};
+
+EFI_DRIVER_BINDING_PROTOCOL gAtapiScsiPassThruDriverBinding = {
+  AtapiScsiPassThruDriverBindingSupported,
+  AtapiScsiPassThruDriverBindingStart,
+  AtapiScsiPassThruDriverBindingStop,
+  0x10,
+  NULL,
+  NULL
+};
+
+EFI_STATUS
+EFIAPI
+AtapiScsiPassThruDriverBindingSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  )
+/*++
+
+Routine Description:
+  Test to see if this driver supports ControllerHandle. Any ControllerHandle
+  that has gEfiPciIoProtocolGuid installed and is IDE Controller it will be supported.
+
+Arguments:
+
+  This                - Protocol instance pointer.
+  Controller          - Handle of device to test
+  RemainingDevicePath - Not used
+
+Returns:
+    EFI_STATUS
+
+--*/
+{
+  EFI_STATUS          Status;
+  EFI_PCI_IO_PROTOCOL *PciIo;
+  PCI_TYPE00          Pci;
+
+
+  //
+  // Open the IO Abstraction(s) needed to perform the supported test
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **) &PciIo,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Use the PCI I/O Protocol to see if Controller is a IDE Controller that
+  // can be managed by this driver.  Read the PCI Configuration Header
+  // for this device.
+  //
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint32,
+                        0,
+                        sizeof (Pci) / sizeof (UINT32),
+                        &Pci
+                        );
+  if (EFI_ERROR (Status)) {
+    gBS->CloseProtocol (
+           Controller,
+           &gEfiPciIoProtocolGuid,
+           This->DriverBindingHandle,
+           Controller
+           );
+    return EFI_UNSUPPORTED;
+  }
+
+  if (Pci.Hdr.ClassCode[2] != PCI_CLASS_MASS_STORAGE || Pci.Hdr.ClassCode[1] != PCI_CLASS_MASS_STORAGE_IDE) {
+
+    Status = EFI_UNSUPPORTED;
+  }
+
+  gBS->CloseProtocol (
+         Controller,
+         &gEfiPciIoProtocolGuid,
+         This->DriverBindingHandle,
+         Controller
+         );
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+AtapiScsiPassThruDriverBindingStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  )
+/*++
+
+Routine Description:
+  Create handles for IDE channels specified by RemainingDevicePath.
+  Install SCSI Pass Thru Protocol onto each created handle.
+
+Arguments:
+
+  This                - Protocol instance pointer.
+  Controller          - Handle of device to test
+  RemainingDevicePath - Not used
+
+Returns:
+    EFI_STATUS
+
+--*/
+{
+  EFI_STATUS          Status;
+  EFI_PCI_IO_PROTOCOL *PciIo;
+  UINT64              Supports;
+  UINT64              OriginalPciAttributes;
+  BOOLEAN             PciAttributesSaved;
+
+  PciIo = NULL;
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **) &PciIo,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  PciAttributesSaved = FALSE;
+  //
+  // Save original PCI attributes
+  //
+  Status = PciIo->Attributes (
+                    PciIo,
+                    EfiPciIoAttributeOperationGet,
+                    0,
+                    &OriginalPciAttributes
+                    );
+
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+  PciAttributesSaved = TRUE;
+
+  Status = PciIo->Attributes (
+                    PciIo,
+                    EfiPciIoAttributeOperationSupported,
+                    0,
+                    &Supports
+                    );
+  if (!EFI_ERROR (Status)) {
+    Supports &= (EFI_PCI_DEVICE_ENABLE               |
+                 EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO |
+                 EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO);
+    Status = PciIo->Attributes (
+                      PciIo,
+                      EfiPciIoAttributeOperationEnable,
+                      Supports,
+                      NULL
+                      );
+  }
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  //
+  // Create SCSI Pass Thru instance for the IDE channel.
+  //
+  Status = RegisterAtapiScsiPassThru (This, Controller, PciIo, OriginalPciAttributes);
+
+Done:
+  if (EFI_ERROR (Status)) {
+    if (PciAttributesSaved == TRUE) {
+      //
+      // Restore original PCI attributes
+      //
+      PciIo->Attributes (
+                      PciIo,
+                      EfiPciIoAttributeOperationSet,
+                      OriginalPciAttributes,
+                      NULL
+                      );
+    }
+
+    gBS->CloseProtocol (
+           Controller,
+           &gEfiPciIoProtocolGuid,
+           This->DriverBindingHandle,
+           Controller
+           );
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+AtapiScsiPassThruDriverBindingStop (
+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
+  IN  EFI_HANDLE                      Controller,
+  IN  UINTN                           NumberOfChildren,
+  IN  EFI_HANDLE                      *ChildHandleBuffer
+  )
+/*++
+
+Routine Description:
+
+  Stop this driver on ControllerHandle. Support stopping any child handles
+  created by this driver.
+
+Arguments:
+
+  This              - Protocol instance pointer.
+  Controller        - Handle of device to stop driver on
+  NumberOfChildren  - Number of Children in the ChildHandleBuffer
+  ChildHandleBuffer - List of handles for the children we need to stop.
+
+Returns:
+
+    EFI_STATUS
+
+--*/
+{
+  EFI_STATUS                      Status;
+  EFI_SCSI_PASS_THRU_PROTOCOL     *ScsiPassThru;
+  EFI_EXT_SCSI_PASS_THRU_PROTOCOL *ExtScsiPassThru;
+  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate;
+
+  if (FeaturePcdGet (PcdSupportScsiPassThru)) {
+    Status = gBS->OpenProtocol (
+                    Controller,
+                    &gEfiScsiPassThruProtocolGuid,
+                    (VOID **) &ScsiPassThru,
+                    This->DriverBindingHandle,
+                    Controller,
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                    );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (ScsiPassThru);
+    if (FeaturePcdGet (PcdSupportExtScsiPassThru)) {
+      Status = gBS->UninstallMultipleProtocolInterfaces (
+                      Controller,
+                      &gEfiScsiPassThruProtocolGuid,
+                      &AtapiScsiPrivate->ScsiPassThru,
+                      &gEfiExtScsiPassThruProtocolGuid,
+                      &AtapiScsiPrivate->ExtScsiPassThru,
+                      NULL
+                      );
+    } else {
+      Status = gBS->UninstallMultipleProtocolInterfaces (
+                      Controller,
+                      &gEfiScsiPassThruProtocolGuid,
+                      &AtapiScsiPrivate->ScsiPassThru,
+                      NULL
+                      );
+    }
+  } else {
+    Status = gBS->OpenProtocol (
+                    Controller,
+                    &gEfiExtScsiPassThruProtocolGuid,
+                    (VOID **) &ExtScsiPassThru,
+                    This->DriverBindingHandle,
+                    Controller,
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                    );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS (ExtScsiPassThru);
+    Status = gBS->UninstallMultipleProtocolInterfaces (
+                    Controller,
+                    &gEfiExtScsiPassThruProtocolGuid,
+                    &AtapiScsiPrivate->ExtScsiPassThru,
+                    NULL
+                    );
+  }
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Restore original PCI attributes
+  //
+  AtapiScsiPrivate->PciIo->Attributes (
+                  AtapiScsiPrivate->PciIo,
+                  EfiPciIoAttributeOperationSet,
+                  AtapiScsiPrivate->OriginalPciAttributes,
+                  NULL
+                  );
+
+  gBS->CloseProtocol (
+         Controller,
+         &gEfiPciIoProtocolGuid,
+         This->DriverBindingHandle,
+         Controller
+         );
+
+  gBS->FreePool (AtapiScsiPrivate);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+RegisterAtapiScsiPassThru (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN  EFI_HANDLE                  Controller,
+  IN  EFI_PCI_IO_PROTOCOL         *PciIo,
+  IN  UINT64                      OriginalPciAttributes
+  )
+/*++
+
+Routine Description:
+  Attaches SCSI Pass Thru Protocol for specified IDE channel.
+
+Arguments:
+  This              - Protocol instance pointer.
+  Controller        - Parent device handle to the IDE channel.
+  PciIo             - PCI I/O protocol attached on the "Controller".
+
+Returns:
+  Always return EFI_SUCCESS unless installing SCSI Pass Thru Protocol failed.
+
+--*/
+{
+  EFI_STATUS                Status;
+  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate;
+  IDE_REGISTERS_BASE_ADDR   IdeRegsBaseAddr[ATAPI_MAX_CHANNEL];
+
+  AtapiScsiPrivate = AllocateZeroPool (sizeof (ATAPI_SCSI_PASS_THRU_DEV));
+  if (AtapiScsiPrivate == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  AtapiScsiPrivate->Signature = ATAPI_SCSI_PASS_THRU_DEV_SIGNATURE;
+  AtapiScsiPrivate->Handle    = Controller;
+
+  //
+  // will reset the IoPort inside each API function.
+  //
+  AtapiScsiPrivate->IoPort                = NULL;
+  AtapiScsiPrivate->PciIo                 = PciIo;
+  AtapiScsiPrivate->OriginalPciAttributes = OriginalPciAttributes;
+
+  //
+  // Obtain IDE IO port registers' base addresses
+  //
+  Status = GetIdeRegistersBaseAddr (PciIo, IdeRegsBaseAddr);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  InitAtapiIoPortRegisters(AtapiScsiPrivate, IdeRegsBaseAddr);
+
+  //
+  // Initialize the LatestTargetId to MAX_TARGET_ID.
+  //
+  AtapiScsiPrivate->LatestTargetId  = MAX_TARGET_ID;
+  AtapiScsiPrivate->LatestLun       = 0;
+
+  Status = InstallScsiPassThruProtocols (&Controller, AtapiScsiPrivate);
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+AtapiScsiPassThruFunction (
+  IN EFI_SCSI_PASS_THRU_PROTOCOL                        *This,
+  IN UINT32                                             Target,
+  IN UINT64                                             Lun,
+  IN OUT EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET         *Packet,
+  IN EFI_EVENT                                          Event OPTIONAL
+  )
+/*++
+
+Routine Description:
+
+  Implements EFI_SCSI_PASS_THRU_PROTOCOL.PassThru() function.
+
+Arguments:
+
+  This:     The EFI_SCSI_PASS_THRU_PROTOCOL instance.
+  Target:   The Target ID of the ATAPI device to send the SCSI
+            Request Packet. To ATAPI devices attached on an IDE
+            Channel, Target ID 0 indicates Master device;Target
+            ID 1 indicates Slave device.
+  Lun:      The LUN of the ATAPI device to send the SCSI Request
+            Packet. To the ATAPI device, Lun is always 0.
+  Packet:   The SCSI Request Packet to send to the ATAPI device
+            specified by Target and Lun.
+  Event:    If non-blocking I/O is not supported then Event is ignored,
+            and blocking I/O is performed.
+            If Event is NULL, then blocking I/O is performed.
+            If Event is not NULL and non blocking I/O is supported,
+            then non-blocking I/O is performed, and Event will be signaled
+            when the SCSI Request Packet completes.
+
+Returns:
+
+   EFI_STATUS
+
+--*/
+{
+  ATAPI_SCSI_PASS_THRU_DEV               *AtapiScsiPrivate;
+  EFI_STATUS                             Status;
+
+  AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);
+
+  //
+  // Target is not allowed beyond MAX_TARGET_ID
+  //
+  if ((Target > MAX_TARGET_ID) || (Lun != 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // check the data fields in Packet parameter.
+  //
+  Status = CheckSCSIRequestPacket (Packet);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // If Request Packet targets at the IDE channel itself,
+  // do nothing.
+  //
+  if (Target == This->Mode->AdapterId) {
+    Packet->TransferLength = 0;
+    return EFI_SUCCESS;
+  }
+
+  //
+  // According to Target ID, reset the Atapi I/O Register mapping
+  // (Target Id in [0,1] area, using AtapiIoPortRegisters[0],
+  //  Target Id in [2,3] area, using AtapiIoPortRegisters[1]
+  //
+  if ((Target / 2) == 0) {
+    Target = Target % 2;
+    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[0];
+  } else {
+    Target = Target % 2;
+    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[1];
+  }
+
+  //
+  // the ATAPI SCSI interface does not support non-blocking I/O
+  // ignore the Event parameter
+  //
+  // Performs blocking I/O.
+  //
+  Status = SubmitBlockingIoCommand (AtapiScsiPrivate, Target, Packet);
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+AtapiScsiPassThruGetNextDevice (
+  IN  EFI_SCSI_PASS_THRU_PROTOCOL    *This,
+  IN OUT UINT32                      *Target,
+  IN OUT UINT64                      *Lun
+  )
+/*++
+
+Routine Description:
+
+  Used to retrieve the list of legal Target IDs for SCSI devices
+  on a SCSI channel.
+
+Arguments:
+
+  This                  - Protocol instance pointer.
+  Target                - On input, a pointer to the Target ID of a SCSI
+                          device present on the SCSI channel.  On output,
+                          a pointer to the Target ID of the next SCSI device
+                          present on a SCSI channel.  An input value of
+                          0xFFFFFFFF retrieves the Target ID of the first
+                          SCSI device present on a SCSI channel.
+  Lun                   - On input, a pointer to the LUN of a SCSI device
+                          present on the SCSI channel. On output, a pointer
+                          to the LUN of the next SCSI device present on
+                          a SCSI channel.
+Returns:
+
+  EFI_SUCCESS           - The Target ID and Lun of the next SCSI device
+                          on the SCSI channel was returned in Target and Lun.
+  EFI_NOT_FOUND         - There are no more SCSI devices on this SCSI channel.
+  EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun were not
+                           returned on a previous call to GetNextDevice().
+--*/
+{
+  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate;
+
+  //
+  // Retrieve Device Private Data Structure.
+  //
+  AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);
+
+  //
+  // Check whether Target is valid.
+  //
+  if (Target == NULL || Lun == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((*Target != 0xFFFFFFFF) &&
+      ((*Target != AtapiScsiPrivate->LatestTargetId) ||
+      (*Lun != AtapiScsiPrivate->LatestLun))) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (*Target == MAX_TARGET_ID) {
+    return EFI_NOT_FOUND;
+  }
+
+  if (*Target == 0xFFFFFFFF) {
+    *Target = 0;
+  } else {
+    *Target = AtapiScsiPrivate->LatestTargetId + 1;
+  }
+
+  *Lun = 0;
+
+  //
+  // Update the LatestTargetId.
+  //
+  AtapiScsiPrivate->LatestTargetId  = *Target;
+  AtapiScsiPrivate->LatestLun       = *Lun;
+
+  return EFI_SUCCESS;
+
+}
+
+EFI_STATUS
+EFIAPI
+AtapiScsiPassThruBuildDevicePath (
+  IN     EFI_SCSI_PASS_THRU_PROTOCOL    *This,
+  IN     UINT32                         Target,
+  IN     UINT64                         Lun,
+  IN OUT EFI_DEVICE_PATH_PROTOCOL       **DevicePath
+  )
+/*++
+
+Routine Description:
+
+  Used to allocate and build a device path node for a SCSI device
+  on a SCSI channel. Would not build device path for a SCSI Host Controller.
+
+Arguments:
+
+  This                  - Protocol instance pointer.
+  Target                - The Target ID of the SCSI device for which
+                          a device path node is to be allocated and built.
+  Lun                   - The LUN of the SCSI device for which a device
+                          path node is to be allocated and built.
+  DevicePath            - A pointer to a single device path node that
+                          describes the SCSI device specified by
+                          Target and Lun. This function is responsible
+                          for allocating the buffer DevicePath with the boot
+                          service AllocatePool().  It is the caller's
+                          responsibility to free DevicePath when the caller
+                          is finished with DevicePath.
+  Returns:
+  EFI_SUCCESS           - The device path node that describes the SCSI device
+                          specified by Target and Lun was allocated and
+                          returned in DevicePath.
+  EFI_NOT_FOUND         - The SCSI devices specified by Target and Lun does
+                          not exist on the SCSI channel.
+  EFI_INVALID_PARAMETER - DevicePath is NULL.
+  EFI_OUT_OF_RESOURCES  - There are not enough resources to allocate
+                          DevicePath.
+--*/
+{
+  EFI_DEV_PATH              *Node;
+
+
+  //
+  // Validate parameters passed in.
+  //
+
+  if (DevicePath == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // can not build device path for the SCSI Host Controller.
+  //
+  if ((Target > (MAX_TARGET_ID - 1)) || (Lun != 0)) {
+    return EFI_NOT_FOUND;
+  }
+
+  Node = AllocateZeroPool (sizeof (EFI_DEV_PATH));
+  if (Node == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Node->DevPath.Type    = MESSAGING_DEVICE_PATH;
+  Node->DevPath.SubType = MSG_ATAPI_DP;
+  SetDevicePathNodeLength (&Node->DevPath, sizeof (ATAPI_DEVICE_PATH));
+
+  Node->Atapi.PrimarySecondary  = (UINT8) (Target / 2);
+  Node->Atapi.SlaveMaster       = (UINT8) (Target % 2);
+  Node->Atapi.Lun               = (UINT16) Lun;
+
+  *DevicePath                   = (EFI_DEVICE_PATH_PROTOCOL *) Node;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+AtapiScsiPassThruGetTargetLun (
+  IN  EFI_SCSI_PASS_THRU_PROTOCOL    *This,
+  IN  EFI_DEVICE_PATH_PROTOCOL       *DevicePath,
+  OUT UINT32                         *Target,
+  OUT UINT64                         *Lun
+  )
+/*++
+
+Routine Description:
+
+  Used to translate a device path node to a Target ID and LUN.
+
+Arguments:
+
+  This                  - Protocol instance pointer.
+  DevicePath            - A pointer to the device path node that
+                          describes a SCSI device on the SCSI channel.
+  Target                - A pointer to the Target ID of a SCSI device
+                          on the SCSI channel.
+  Lun                   - A pointer to the LUN of a SCSI device on
+                          the SCSI channel.
+Returns:
+
+  EFI_SUCCESS           - DevicePath was successfully translated to a
+                          Target ID and LUN, and they were returned
+                          in Target and Lun.
+  EFI_INVALID_PARAMETER - DevicePath/Target/Lun is NULL.
+  EFI_UNSUPPORTED       - This driver does not support the device path
+                          node type in DevicePath.
+  EFI_NOT_FOUND         - A valid translation from DevicePath to a
+                          Target ID and LUN does not exist.
+--*/
+{
+  EFI_DEV_PATH  *Node;
+
+  //
+  // Validate parameters passed in.
+  //
+  if (DevicePath == NULL || Target == NULL || Lun == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check whether the DevicePath belongs to SCSI_DEVICE_PATH
+  //
+  if ((DevicePath->Type != MESSAGING_DEVICE_PATH) ||
+      (DevicePath->SubType != MSG_ATAPI_DP) ||
+      (DevicePathNodeLength(DevicePath) != sizeof(ATAPI_DEVICE_PATH))) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Node    = (EFI_DEV_PATH *) DevicePath;
+
+  *Target = Node->Atapi.PrimarySecondary * 2 + Node->Atapi.SlaveMaster;
+  *Lun    = Node->Atapi.Lun;
+
+  if (*Target > (MAX_TARGET_ID - 1) || *Lun != 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+AtapiScsiPassThruResetChannel (
+  IN  EFI_SCSI_PASS_THRU_PROTOCOL   *This
+  )
+/*++
+
+Routine Description:
+
+  Resets a SCSI channel.This operation resets all the
+  SCSI devices connected to the SCSI channel.
+
+Arguments:
+
+  This                  - Protocol instance pointer.
+
+Returns:
+
+  EFI_SUCCESS           - The SCSI channel was reset.
+  EFI_UNSUPPORTED       - The SCSI channel does not support
+                          a channel reset operation.
+  EFI_DEVICE_ERROR      - A device error occurred while
+                          attempting to reset the SCSI channel.
+  EFI_TIMEOUT           - A timeout occurred while attempting
+                          to reset the SCSI channel.
+--*/
+{
+  UINT8                     DeviceControlValue;
+  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate;
+  UINT8                     Index;
+  BOOLEAN                   ResetFlag;
+
+  AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);
+  ResetFlag = FALSE;
+
+  //
+  // Reset both Primary channel and Secondary channel.
+  // so, the IoPort pointer must point to the right I/O Register group
+  //
+  for (Index = 0; Index < 2; Index++) {
+    //
+    // Reset
+    //
+    AtapiScsiPrivate->IoPort  = &AtapiScsiPrivate->AtapiIoPortRegisters[Index];
+
+    DeviceControlValue        = 0;
+    //
+    // set SRST bit to initiate soft reset
+    //
+    DeviceControlValue |= SRST;
+    //
+    // disable Interrupt
+    //
+    DeviceControlValue |= BIT1;
+    WritePortB (
+      AtapiScsiPrivate->PciIo,
+      AtapiScsiPrivate->IoPort->Alt.DeviceControl,
+      DeviceControlValue
+      );
+
+    //
+    // Wait 10us
+    //
+    gBS->Stall (10);
+
+    //
+    // Clear SRST bit
+    // 0xfb:1111,1011
+    //
+    DeviceControlValue &= 0xfb;
+
+    WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Alt.DeviceControl, DeviceControlValue);
+
+    //
+    // slave device needs at most 31s to clear BSY
+    //
+    if (StatusWaitForBSYClear (AtapiScsiPrivate, 31000000) != EFI_TIMEOUT) {
+      ResetFlag = TRUE;
+    }
+  }
+
+  if (ResetFlag) {
+    return EFI_SUCCESS;
+  }
+
+  return EFI_TIMEOUT;
+}
+
+EFI_STATUS
+EFIAPI
+AtapiScsiPassThruResetTarget (
+  IN EFI_SCSI_PASS_THRU_PROTOCOL    *This,
+  IN UINT32                         Target,
+  IN UINT64                         Lun
+  )
+/*++
+
+Routine Description:
+
+  Resets a SCSI device that is connected to a SCSI channel.
+
+Arguments:
+
+  This                  - Protocol instance pointer.
+  Target                - The Target ID of the SCSI device to reset.
+  Lun                   - The LUN of the SCSI device to reset.
+
+Returns:
+
+  EFI_SUCCESS           - The SCSI device specified by Target and
+                          Lun was reset.
+  EFI_UNSUPPORTED       - The SCSI channel does not support a target
+                          reset operation.
+  EFI_INVALID_PARAMETER - Target or Lun are invalid.
+  EFI_DEVICE_ERROR      - A device error occurred while attempting
+                          to reset the SCSI device specified by Target
+                          and Lun.
+  EFI_TIMEOUT           - A timeout occurred while attempting to reset
+                          the SCSI device specified by Target and Lun.
+--*/
+{
+  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate;
+  UINT8                     Command;
+  UINT8                     DeviceSelect;
+
+  AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);
+
+  if ((Target > MAX_TARGET_ID) || (Lun != 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Directly return EFI_SUCCESS if want to reset the host controller
+  //
+  if (Target == This->Mode->AdapterId) {
+    return EFI_SUCCESS;
+  }
+
+  //
+  // According to Target ID, reset the Atapi I/O Register mapping
+  // (Target Id in [0,1] area, using AtapiIoPortRegisters[0],
+  //  Target Id in [2,3] area, using AtapiIoPortRegisters[1]
+  //
+  if ((Target / 2) == 0) {
+    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[0];
+  } else {
+    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[1];
+  }
+
+  //
+  // for ATAPI device, no need to wait DRDY ready after device selecting.
+  //
+  // bit7 and bit5 are both set to 1 for backward compatibility
+  //
+  DeviceSelect = (UINT8) (((BIT7 | BIT5) | (Target << 4)));
+  WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Head, DeviceSelect);
+
+  Command = ATAPI_SOFT_RESET_CMD;
+  WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Reg.Command, Command);
+
+  //
+  // BSY clear is the only status return to the host by the device
+  // when reset is complete.
+  // slave device needs at most 31s to clear BSY
+  //
+  if (EFI_ERROR (StatusWaitForBSYClear (AtapiScsiPrivate, 31000000))) {
+    return EFI_TIMEOUT;
+  }
+
+  //
+  // stall 5 seconds to make the device status stable
+  //
+  gBS->Stall (5000000);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+AtapiExtScsiPassThruFunction (
+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL                    *This,
+  IN UINT8                                              *Target,
+  IN UINT64                                             Lun,
+  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET     *Packet,
+  IN EFI_EVENT                                          Event OPTIONAL
+  )
+/*++
+
+Routine Description:
+
+  Implements EFI_EXT_SCSI_PASS_THRU_PROTOCOL.PassThru() function.
+
+Arguments:
+
+  This:     The EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
+  Target:   The Target ID of the ATAPI device to send the SCSI
+            Request Packet. To ATAPI devices attached on an IDE
+            Channel, Target ID 0 indicates Master device;Target
+            ID 1 indicates Slave device.
+  Lun:      The LUN of the ATAPI device to send the SCSI Request
+            Packet. To the ATAPI device, Lun is always 0.
+  Packet:   The SCSI Request Packet to send to the ATAPI device
+            specified by Target and Lun.
+  Event:    If non-blocking I/O is not supported then Event is ignored,
+            and blocking I/O is performed.
+            If Event is NULL, then blocking I/O is performed.
+            If Event is not NULL and non blocking I/O is supported,
+            then non-blocking I/O is performed, and Event will be signaled
+            when the SCSI Request Packet completes.
+
+Returns:
+
+   EFI_STATUS
+
+--*/
+{
+  EFI_STATUS                          Status;
+  ATAPI_SCSI_PASS_THRU_DEV            *AtapiScsiPrivate;
+  UINT8                                TargetId;
+
+  AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS (This);
+
+  //
+  // For ATAPI device, UINT8 is enough to represent the SCSI ID on channel.
+  //
+  TargetId = Target[0];
+
+  //
+  // Target is not allowed beyond MAX_TARGET_ID
+  //
+  if ((TargetId > MAX_TARGET_ID) || (Lun != 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // check the data fields in Packet parameter.
+  //
+  Status = CheckExtSCSIRequestPacket (Packet);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // If Request Packet targets at the IDE channel itself,
+  // do nothing.
+  //
+  if (TargetId == (UINT8)This->Mode->AdapterId) {
+    Packet->InTransferLength = Packet->OutTransferLength = 0;
+    return EFI_SUCCESS;
+  }
+
+  //
+  // According to Target ID, reset the Atapi I/O Register mapping
+  // (Target Id in [0,1] area, using AtapiIoPortRegisters[0],
+  //  Target Id in [2,3] area, using AtapiIoPortRegisters[1]
+  //
+  if ((TargetId / 2) == 0) {
+    TargetId = (UINT8) (TargetId % 2);
+    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[0];
+  } else {
+    TargetId = (UINT8) (TargetId % 2);
+    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[1];
+  }
+
+  //
+  // the ATAPI SCSI interface does not support non-blocking I/O
+  // ignore the Event parameter
+  //
+  // Performs blocking I/O.
+  //
+  Status = SubmitExtBlockingIoCommand (AtapiScsiPrivate, TargetId, Packet);
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+AtapiExtScsiPassThruGetNextTargetLun (
+  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
+  IN OUT UINT8                           **Target,
+  IN OUT UINT64                          *Lun
+  )
+/*++
+
+Routine Description:
+
+  Used to retrieve the list of legal Target IDs for SCSI devices
+  on a SCSI channel.
+
+Arguments:
+
+  This                  - Protocol instance pointer.
+  Target                - On input, a pointer to the Target ID of a SCSI
+                          device present on the SCSI channel.  On output,
+                          a pointer to the Target ID of the next SCSI device
+                          present on a SCSI channel.  An input value of
+                          0xFFFFFFFF retrieves the Target ID of the first
+                          SCSI device present on a SCSI channel.
+  Lun                   - On input, a pointer to the LUN of a SCSI device
+                          present on the SCSI channel. On output, a pointer
+                          to the LUN of the next SCSI device present on
+                          a SCSI channel.
+Returns:
+
+  EFI_SUCCESS           - The Target ID and Lun of the next SCSI device
+                          on the SCSI channel was returned in Target and Lun.
+  EFI_NOT_FOUND         - There are no more SCSI devices on this SCSI channel.
+  EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun were not
+                           returned on a previous call to GetNextDevice().
+--*/
+{
+  UINT8                          ByteIndex;
+  UINT8                          TargetId;
+  UINT8                          ScsiId[TARGET_MAX_BYTES];
+  ATAPI_SCSI_PASS_THRU_DEV       *AtapiScsiPrivate;
+
+  //
+  // Retrieve Device Private Data Structure.
+  //
+  AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS (This);
+
+  //
+  // Check whether Target is valid.
+  //
+  if (*Target == NULL || Lun == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  SetMem (ScsiId, TARGET_MAX_BYTES, 0xFF);
+
+  TargetId = (*Target)[0];
+
+  //
+  // For ATAPI device, we use UINT8 to represent the SCSI ID on channel.
+  //
+  if (CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) != 0) {
+    for (ByteIndex = 1; ByteIndex < TARGET_MAX_BYTES; ByteIndex++) {
+      if ((*Target)[ByteIndex] != 0) {
+        return EFI_INVALID_PARAMETER;
+      }
+    }
+  }
+
+  if ((CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) != 0) &&
+      ((TargetId != AtapiScsiPrivate->LatestTargetId) ||
+      (*Lun != AtapiScsiPrivate->LatestLun))) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (TargetId == MAX_TARGET_ID) {
+    return EFI_NOT_FOUND;
+  }
+
+  if (CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) == 0) {
+    SetMem (*Target, TARGET_MAX_BYTES,0);
+  } else {
+    (*Target)[0] = (UINT8) (AtapiScsiPrivate->LatestTargetId + 1);
+  }
+
+  *Lun = 0;
+
+  //
+  // Update the LatestTargetId.
+  //
+  AtapiScsiPrivate->LatestTargetId  = (*Target)[0];
+  AtapiScsiPrivate->LatestLun       = *Lun;
+
+  return EFI_SUCCESS;
+
+}
+
+EFI_STATUS
+EFIAPI
+AtapiExtScsiPassThruBuildDevicePath (
+  IN     EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
+  IN     UINT8                              *Target,
+  IN     UINT64                             Lun,
+  IN OUT EFI_DEVICE_PATH_PROTOCOL           **DevicePath
+  )
+/*++
+
+Routine Description:
+
+  Used to allocate and build a device path node for a SCSI device
+  on a SCSI channel. Would not build device path for a SCSI Host Controller.
+
+Arguments:
+
+  This                  - Protocol instance pointer.
+  Target                - The Target ID of the SCSI device for which
+                          a device path node is to be allocated and built.
+  Lun                   - The LUN of the SCSI device for which a device
+                          path node is to be allocated and built.
+  DevicePath            - A pointer to a single device path node that
+                          describes the SCSI device specified by
+                          Target and Lun. This function is responsible
+                          for allocating the buffer DevicePath with the boot
+                          service AllocatePool().  It is the caller's
+                          responsibility to free DevicePath when the caller
+                          is finished with DevicePath.
+  Returns:
+  EFI_SUCCESS           - The device path node that describes the SCSI device
+                          specified by Target and Lun was allocated and
+                          returned in DevicePath.
+  EFI_NOT_FOUND         - The SCSI devices specified by Target and Lun does
+                          not exist on the SCSI channel.
+  EFI_INVALID_PARAMETER - DevicePath is NULL.
+  EFI_OUT_OF_RESOURCES  - There are not enough resources to allocate
+                          DevicePath.
+--*/
+{
+  EFI_DEV_PATH                   *Node;
+  UINT8                          TargetId;
+
+  TargetId = Target[0];
+
+  //
+  // Validate parameters passed in.
+  //
+
+  if (DevicePath == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // can not build device path for the SCSI Host Controller.
+  //
+  if ((TargetId > (MAX_TARGET_ID - 1)) || (Lun != 0)) {
+    return EFI_NOT_FOUND;
+  }
+
+  Node = AllocateZeroPool (sizeof (EFI_DEV_PATH));
+  if (Node == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Node->DevPath.Type    = MESSAGING_DEVICE_PATH;
+  Node->DevPath.SubType = MSG_ATAPI_DP;
+  SetDevicePathNodeLength (&Node->DevPath, sizeof (ATAPI_DEVICE_PATH));
+
+  Node->Atapi.PrimarySecondary  = (UINT8) (TargetId / 2);
+  Node->Atapi.SlaveMaster       = (UINT8) (TargetId % 2);
+  Node->Atapi.Lun               = (UINT16) Lun;
+
+  *DevicePath                   = (EFI_DEVICE_PATH_PROTOCOL *) Node;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+AtapiExtScsiPassThruGetTargetLun (
+  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
+  IN  EFI_DEVICE_PATH_PROTOCOL           *DevicePath,
+  OUT UINT8                              **Target,
+  OUT UINT64                             *Lun
+  )
+/*++
+
+Routine Description:
+
+  Used to translate a device path node to a Target ID and LUN.
+
+Arguments:
+
+  This                  - Protocol instance pointer.
+  DevicePath            - A pointer to the device path node that
+                          describes a SCSI device on the SCSI channel.
+  Target                - A pointer to the Target ID of a SCSI device
+                          on the SCSI channel.
+  Lun                   - A pointer to the LUN of a SCSI device on
+                          the SCSI channel.
+Returns:
+
+  EFI_SUCCESS           - DevicePath was successfully translated to a
+                          Target ID and LUN, and they were returned
+                          in Target and Lun.
+  EFI_INVALID_PARAMETER - DevicePath/Target/Lun is NULL.
+  EFI_UNSUPPORTED       - This driver does not support the device path
+                          node type in DevicePath.
+  EFI_NOT_FOUND         - A valid translation from DevicePath to a
+                          Target ID and LUN does not exist.
+--*/
+{
+  EFI_DEV_PATH  *Node;
+
+  //
+  // Validate parameters passed in.
+  //
+  if (DevicePath == NULL || Target == NULL || Lun == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check whether the DevicePath belongs to SCSI_DEVICE_PATH
+  //
+  if ((DevicePath->Type != MESSAGING_DEVICE_PATH) ||
+      (DevicePath->SubType != MSG_ATAPI_DP) ||
+      (DevicePathNodeLength(DevicePath) != sizeof(ATAPI_DEVICE_PATH))) {
+    return EFI_UNSUPPORTED;
+  }
+
+  ZeroMem (*Target, TARGET_MAX_BYTES);
+
+  Node    = (EFI_DEV_PATH *) DevicePath;
+
+  (*Target)[0] = (UINT8) (Node->Atapi.PrimarySecondary * 2 + Node->Atapi.SlaveMaster);
+  *Lun    = Node->Atapi.Lun;
+
+  if ((*Target)[0] > (MAX_TARGET_ID - 1) || *Lun != 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+AtapiExtScsiPassThruResetChannel (
+  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL   *This
+  )
+/*++
+
+Routine Description:
+
+  Resets a SCSI channel.This operation resets all the
+  SCSI devices connected to the SCSI channel.
+
+Arguments:
+
+  This                  - Protocol instance pointer.
+
+Returns:
+
+  EFI_SUCCESS           - The SCSI channel was reset.
+  EFI_UNSUPPORTED       - The SCSI channel does not support
+                          a channel reset operation.
+  EFI_DEVICE_ERROR      - A device error occurred while
+                          attempting to reset the SCSI channel.
+  EFI_TIMEOUT           - A timeout occurred while attempting
+                          to reset the SCSI channel.
+--*/
+{
+  UINT8                         DeviceControlValue;
+  UINT8                         Index;
+  ATAPI_SCSI_PASS_THRU_DEV      *AtapiScsiPrivate;
+  BOOLEAN                       ResetFlag;
+
+  AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS (This);
+  ResetFlag = FALSE;
+  //
+  // Reset both Primary channel and Secondary channel.
+  // so, the IoPort pointer must point to the right I/O Register group
+  // And if there is a channel reset successfully, return EFI_SUCCESS.
+  //
+  for (Index = 0; Index < 2; Index++) {
+    //
+    // Reset
+    //
+    AtapiScsiPrivate->IoPort  = &AtapiScsiPrivate->AtapiIoPortRegisters[Index];
+
+    DeviceControlValue        = 0;
+    //
+    // set SRST bit to initiate soft reset
+    //
+    DeviceControlValue |= SRST;
+    //
+    // disable Interrupt
+    //
+    DeviceControlValue |= BIT1;
+    WritePortB (
+      AtapiScsiPrivate->PciIo,
+      AtapiScsiPrivate->IoPort->Alt.DeviceControl,
+      DeviceControlValue
+      );
+
+    //
+    // Wait 10us
+    //
+    gBS->Stall (10);
+
+    //
+    // Clear SRST bit
+    // 0xfb:1111,1011
+    //
+    DeviceControlValue &= 0xfb;
+
+    WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Alt.DeviceControl, DeviceControlValue);
+
+    //
+    // slave device needs at most 31s to clear BSY
+    //
+    if (StatusWaitForBSYClear (AtapiScsiPrivate, 31000000) != EFI_TIMEOUT) {
+      ResetFlag = TRUE;
+    }
+  }
+
+  if (ResetFlag) {
+    return EFI_SUCCESS;
+  }
+
+  return EFI_TIMEOUT;
+}
+
+EFI_STATUS
+EFIAPI
+AtapiExtScsiPassThruResetTarget (
+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
+  IN UINT8                              *Target,
+  IN UINT64                             Lun
+  )
+/*++
+
+Routine Description:
+
+  Resets a SCSI device that is connected to a SCSI channel.
+
+Arguments:
+
+  This                  - Protocol instance pointer.
+  Target                - The Target ID of the SCSI device to reset.
+  Lun                   - The LUN of the SCSI device to reset.
+
+Returns:
+
+  EFI_SUCCESS           - The SCSI device specified by Target and
+                          Lun was reset.
+  EFI_UNSUPPORTED       - The SCSI channel does not support a target
+                          reset operation.
+  EFI_INVALID_PARAMETER - Target or Lun are invalid.
+  EFI_DEVICE_ERROR      - A device error occurred while attempting
+                          to reset the SCSI device specified by Target
+                          and Lun.
+  EFI_TIMEOUT           - A timeout occurred while attempting to reset
+                          the SCSI device specified by Target and Lun.
+--*/
+{
+  UINT8                         Command;
+  UINT8                         DeviceSelect;
+  UINT8                         TargetId;
+  ATAPI_SCSI_PASS_THRU_DEV      *AtapiScsiPrivate;
+
+  AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS (This);
+  TargetId = Target[0];
+
+  if ((TargetId > MAX_TARGET_ID) || (Lun != 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Directly return EFI_SUCCESS if want to reset the host controller
+  //
+  if (TargetId == This->Mode->AdapterId) {
+    return EFI_SUCCESS;
+  }
+
+  //
+  // According to Target ID, reset the Atapi I/O Register mapping
+  // (Target Id in [0,1] area, using AtapiIoPortRegisters[0],
+  //  Target Id in [2,3] area, using AtapiIoPortRegisters[1]
+  //
+  if ((TargetId / 2) == 0) {
+    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[0];
+  } else {
+    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[1];
+  }
+
+  //
+  // for ATAPI device, no need to wait DRDY ready after device selecting.
+  //
+  // bit7 and bit5 are both set to 1 for backward compatibility
+  //
+  DeviceSelect = (UINT8) ((BIT7 | BIT5) | (TargetId << 4));
+  WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Head, DeviceSelect);
+
+  Command = ATAPI_SOFT_RESET_CMD;
+  WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Reg.Command, Command);
+
+  //
+  // BSY clear is the only status return to the host by the device
+  // when reset is complete.
+  // slave device needs at most 31s to clear BSY
+  //
+  if (EFI_ERROR (StatusWaitForBSYClear (AtapiScsiPrivate, 31000000))) {
+    return EFI_TIMEOUT;
+  }
+
+  //
+  // stall 5 seconds to make the device status stable
+  //
+  gBS->Stall (5000000);
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+AtapiExtScsiPassThruGetNextTarget (
+  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
+  IN OUT UINT8                           **Target
+  )
+/*++
+
+Routine Description:
+  Used to retrieve the list of legal Target IDs for SCSI devices
+  on a SCSI channel.
+
+Arguments:
+  This                  - Protocol instance pointer.
+  Target                - On input, a pointer to the Target ID of a SCSI
+                          device present on the SCSI channel.  On output,
+                          a pointer to the Target ID of the next SCSI device
+                           present on a SCSI channel.  An input value of
+                           0xFFFFFFFF retrieves the Target ID of the first
+                           SCSI device present on a SCSI channel.
+  Lun                   - On input, a pointer to the LUN of a SCSI device
+                          present on the SCSI channel. On output, a pointer
+                          to the LUN of the next SCSI device present on
+                          a SCSI channel.
+
+Returns:
+  EFI_SUCCESS           - The Target ID and Lun of the next SCSI device
+                          on the SCSI channel was returned in Target and Lun.
+  EFI_NOT_FOUND         - There are no more SCSI devices on this SCSI channel.
+  EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun were not
+                          returned on a previous call to GetNextDevice().
+--*/
+{
+  UINT8                         TargetId;
+  UINT8                         ScsiId[TARGET_MAX_BYTES];
+  ATAPI_SCSI_PASS_THRU_DEV      *AtapiScsiPrivate;
+  UINT8                         ByteIndex;
+
+  //
+  // Retrieve Device Private Data Structure.
+  //
+  AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS (This);
+
+  //
+  // Check whether Target is valid.
+  //
+  if (*Target == NULL ) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  TargetId = (*Target)[0];
+  SetMem (ScsiId, TARGET_MAX_BYTES, 0xFF);
+
+  //
+  // For ATAPI device, we use UINT8 to represent the SCSI ID on channel.
+  //
+  if (CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) != 0) {
+    for (ByteIndex = 1; ByteIndex < TARGET_MAX_BYTES; ByteIndex++) {
+      if ((*Target)[ByteIndex] != 0) {
+        return EFI_INVALID_PARAMETER;
+      }
+    }
+  }
+
+  if ((CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) != 0) &&(TargetId != AtapiScsiPrivate->LatestTargetId)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (TargetId == MAX_TARGET_ID) {
+    return EFI_NOT_FOUND;
+  }
+
+  if ((CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) == 0)) {
+    SetMem (*Target, TARGET_MAX_BYTES, 0);
+  } else {
+    (*Target)[0] = (UINT8) (AtapiScsiPrivate->LatestTargetId + 1);
+  }
+
+  //
+  // Update the LatestTargetId.
+  //
+  AtapiScsiPrivate->LatestTargetId  = (*Target)[0];
+  AtapiScsiPrivate->LatestLun       = 0;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetIdeRegistersBaseAddr (
+  IN  EFI_PCI_IO_PROTOCOL         *PciIo,
+  OUT IDE_REGISTERS_BASE_ADDR     *IdeRegsBaseAddr
+  )
+/*++
+
+Routine Description:
+  Get IDE IO port registers' base addresses by mode. In 'Compatibility' mode,
+  use fixed addresses. In Native-PCI mode, get base addresses from BARs in
+  the PCI IDE controller's Configuration Space.
+
+Arguments:
+  PciIo             - Pointer to the EFI_PCI_IO_PROTOCOL instance
+  IdeRegsBaseAddr   - Pointer to IDE_REGISTERS_BASE_ADDR to
+                      receive IDE IO port registers' base addresses
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+{
+  EFI_STATUS  Status;
+  PCI_TYPE00  PciData;
+
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint8,
+                        0,
+                        sizeof (PciData),
+                        &PciData
+                        );
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if ((PciData.Hdr.ClassCode[0] & IDE_PRIMARY_OPERATING_MODE) == 0) {
+    IdeRegsBaseAddr[IdePrimary].CommandBlockBaseAddr  = 0x1f0;
+    IdeRegsBaseAddr[IdePrimary].ControlBlockBaseAddr  = 0x3f6;
+  } else {
+    //
+    // The BARs should be of IO type
+    //
+    if ((PciData.Device.Bar[0] & BIT0) == 0 ||
+        (PciData.Device.Bar[1] & BIT0) == 0) {
+      return EFI_UNSUPPORTED;
+    }
+
+    IdeRegsBaseAddr[IdePrimary].CommandBlockBaseAddr  =
+    (UINT16) (PciData.Device.Bar[0] & 0x0000fff8);
+    IdeRegsBaseAddr[IdePrimary].ControlBlockBaseAddr  =
+    (UINT16) ((PciData.Device.Bar[1] & 0x0000fffc) + 2);
+  }
+
+  if ((PciData.Hdr.ClassCode[0] & IDE_SECONDARY_OPERATING_MODE) == 0) {
+    IdeRegsBaseAddr[IdeSecondary].CommandBlockBaseAddr  = 0x170;
+    IdeRegsBaseAddr[IdeSecondary].ControlBlockBaseAddr  = 0x376;
+  } else {
+    //
+    // The BARs should be of IO type
+    //
+    if ((PciData.Device.Bar[2] & BIT0) == 0 ||
+        (PciData.Device.Bar[3] & BIT0) == 0) {
+      return EFI_UNSUPPORTED;
+    }
+
+    IdeRegsBaseAddr[IdeSecondary].CommandBlockBaseAddr  =
+    (UINT16) (PciData.Device.Bar[2] & 0x0000fff8);
+    IdeRegsBaseAddr[IdeSecondary].ControlBlockBaseAddr  =
+    (UINT16) ((PciData.Device.Bar[3] & 0x0000fffc) + 2);
+  }
+
+  return EFI_SUCCESS;
+}
+
+VOID
+InitAtapiIoPortRegisters (
+  IN  ATAPI_SCSI_PASS_THRU_DEV     *AtapiScsiPrivate,
+  IN  IDE_REGISTERS_BASE_ADDR      *IdeRegsBaseAddr
+  )
+/*++
+
+Routine Description:
+
+  Initialize each Channel's Base Address of CommandBlock and ControlBlock.
+
+Arguments:
+
+  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
+  IdeRegsBaseAddr             - The pointer of IDE_REGISTERS_BASE_ADDR
+
+Returns:
+
+  None
+
+--*/
+{
+
+  UINT8               IdeChannel;
+  UINT16              CommandBlockBaseAddr;
+  UINT16              ControlBlockBaseAddr;
+  IDE_BASE_REGISTERS  *RegisterPointer;
+
+
+  for (IdeChannel = 0; IdeChannel < ATAPI_MAX_CHANNEL; IdeChannel++) {
+
+    RegisterPointer =  &AtapiScsiPrivate->AtapiIoPortRegisters[IdeChannel];
+
+    //
+    // Initialize IDE IO port addresses, including Command Block registers
+    // and Control Block registers
+    //
+    CommandBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].CommandBlockBaseAddr;
+    ControlBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].ControlBlockBaseAddr;
+
+    RegisterPointer->Data = CommandBlockBaseAddr;
+    (*(UINT16 *) &RegisterPointer->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01);
+    RegisterPointer->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02);
+    RegisterPointer->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03);
+    RegisterPointer->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04);
+    RegisterPointer->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05);
+    RegisterPointer->Head = (UINT16) (CommandBlockBaseAddr + 0x06);
+    (*(UINT16 *) &RegisterPointer->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07);
+
+    (*(UINT16 *) &RegisterPointer->Alt) = ControlBlockBaseAddr;
+    RegisterPointer->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01);
+  }
+
+}
+
+
+EFI_STATUS
+CheckSCSIRequestPacket (
+  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET      *Packet
+  )
+/*++
+
+Routine Description:
+
+  Checks the parameters in the SCSI Request Packet to make sure
+  they are valid for a SCSI Pass Thru request.
+
+Arguments:
+
+  Packet         -  The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+{
+  if (Packet == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!ValidCdbLength (Packet->CdbLength)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Packet->Cdb == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Checks whether the request command is supported.
+  //
+  if (!IsCommandValid (Packet)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+BOOLEAN
+IsCommandValid (
+  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET   *Packet
+  )
+/*++
+
+Routine Description:
+
+  Checks the requested SCSI command:
+  Is it supported by this driver?
+  Is the Data transfer direction reasonable?
+
+Arguments:
+
+  Packet         -  The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+{
+  UINT8 Index;
+  UINT8 *OpCode;
+  UINT8 ArrayLen;
+
+  OpCode = (UINT8 *) (Packet->Cdb);
+  ArrayLen = (UINT8) (ARRAY_SIZE (gSupportedATAPICommands));
+
+  for (Index = 0; (Index < ArrayLen) && (CompareMem (&gSupportedATAPICommands[Index], &gEndTable, sizeof (SCSI_COMMAND_SET)) != 0); Index++) {
+
+    if (*OpCode == gSupportedATAPICommands[Index].OpCode) {
+      //
+      // Check whether the requested Command is supported by this driver
+      //
+      if (Packet->DataDirection == DataIn) {
+        //
+        // Check whether the requested data direction conforms to
+        // what it should be.
+        //
+        if (gSupportedATAPICommands[Index].Direction == DataOut) {
+          return FALSE;
+        }
+      }
+
+      if (Packet->DataDirection == DataOut) {
+        //
+        // Check whether the requested data direction conforms to
+        // what it should be.
+        //
+        if (gSupportedATAPICommands[Index].Direction == DataIn) {
+          return FALSE;
+        }
+      }
+
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
+EFI_STATUS
+SubmitBlockingIoCommand (
+  ATAPI_SCSI_PASS_THRU_DEV                  *AtapiScsiPrivate,
+  UINT32                                    Target,
+  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET    *Packet
+  )
+/*++
+
+Routine Description:
+
+  Performs blocking I/O request.
+
+Arguments:
+
+  AtapiScsiPrivate:   Private data structure for the specified channel.
+  Target:             The Target ID of the ATAPI device to send the SCSI
+                      Request Packet. To ATAPI devices attached on an IDE
+                      Channel, Target ID 0 indicates Master device;Target
+                      ID 1 indicates Slave device.
+  Packet:             The SCSI Request Packet to send to the ATAPI device
+                      specified by Target.
+
+  Returns:            EFI_STATUS
+
+--*/
+{
+  UINT8       PacketCommand[12];
+  UINT64      TimeoutInMicroSeconds;
+  EFI_STATUS  PacketCommandStatus;
+
+  //
+  // Fill ATAPI Command Packet according to CDB
+  //
+  ZeroMem (&PacketCommand, 12);
+  CopyMem (&PacketCommand, Packet->Cdb, Packet->CdbLength);
+
+  //
+  // Timeout is 100ns unit, convert it to 1000ns (1us) unit.
+  //
+  TimeoutInMicroSeconds = DivU64x32 (Packet->Timeout, (UINT32) 10);
+
+  //
+  // Submit ATAPI Command Packet
+  //
+  PacketCommandStatus = AtapiPacketCommand (
+                          AtapiScsiPrivate,
+                          Target,
+                          PacketCommand,
+                          Packet->DataBuffer,
+                          &(Packet->TransferLength),
+                          (DATA_DIRECTION) Packet->DataDirection,
+                          TimeoutInMicroSeconds
+                          );
+  if (!EFI_ERROR (PacketCommandStatus) || (Packet->SenseData == NULL)) {
+    Packet->SenseDataLength = 0;
+    return PacketCommandStatus;
+  }
+
+  //
+  // Return SenseData if PacketCommandStatus matches
+  // the following return codes.
+  //
+  if ((PacketCommandStatus ==  EFI_BAD_BUFFER_SIZE) ||
+      (PacketCommandStatus == EFI_DEVICE_ERROR) ||
+      (PacketCommandStatus == EFI_TIMEOUT)) {
+
+    //
+    // avoid submit request sense command continuously.
+    //
+    if (PacketCommand[0] == OP_REQUEST_SENSE) {
+      Packet->SenseDataLength = 0;
+      return PacketCommandStatus;
+    }
+
+    RequestSenseCommand (
+      AtapiScsiPrivate,
+      Target,
+      Packet->Timeout,
+      Packet->SenseData,
+      &Packet->SenseDataLength
+      );
+  }
+
+  return PacketCommandStatus;
+}
+
+EFI_STATUS
+RequestSenseCommand (
+  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,
+  UINT32                      Target,
+  UINT64                      Timeout,
+  VOID                        *SenseData,
+  UINT8                       *SenseDataLength
+  )
+/*++
+
+Routine Description:
+
+  Submit request sense command
+
+Arguments:
+
+  AtapiScsiPrivate  - The pointer of ATAPI_SCSI_PASS_THRU_DEV
+  Target            - The target ID
+  Timeout           - The time to complete the command
+  SenseData         - The buffer to fill in sense data
+  SenseDataLength   - The length of buffer
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+{
+  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  Packet;
+  UINT8                                   Cdb[12];
+  EFI_STATUS                              Status;
+
+  ZeroMem (&Packet, sizeof (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET));
+  ZeroMem (Cdb, 12);
+
+  Cdb[0]                = OP_REQUEST_SENSE;
+  Cdb[4]                = (UINT8) (*SenseDataLength);
+
+  Packet.Timeout        = Timeout;
+  Packet.DataBuffer     = SenseData;
+  Packet.SenseData      = NULL;
+  Packet.Cdb            = Cdb;
+  Packet.TransferLength = *SenseDataLength;
+  Packet.CdbLength      = 12;
+  Packet.DataDirection  = DataIn;
+
+  Status                = SubmitBlockingIoCommand (AtapiScsiPrivate, Target, &Packet);
+  *SenseDataLength      = (UINT8) (Packet.TransferLength);
+  return Status;
+}
+
+EFI_STATUS
+CheckExtSCSIRequestPacket (
+  EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET      *Packet
+  )
+/*++
+
+Routine Description:
+
+  Checks the parameters in the SCSI Request Packet to make sure
+  they are valid for a SCSI Pass Thru request.
+
+Arguments:
+
+  Packet       - The pointer of EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+{
+  if (Packet == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!ValidCdbLength (Packet->CdbLength)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Packet->Cdb == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Checks whether the request command is supported.
+  //
+  if (!IsExtCommandValid (Packet)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+BOOLEAN
+IsExtCommandValid (
+  EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET   *Packet
+  )
+/*++
+
+Routine Description:
+
+  Checks the requested SCSI command:
+  Is it supported by this driver?
+  Is the Data transfer direction reasonable?
+
+Arguments:
+
+  Packet         -  The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+{
+  UINT8 Index;
+  UINT8 *OpCode;
+  UINT8 ArrayLen;
+
+  OpCode = (UINT8 *) (Packet->Cdb);
+  ArrayLen = (UINT8) (ARRAY_SIZE (gSupportedATAPICommands));
+
+  for (Index = 0; (Index < ArrayLen) && (CompareMem (&gSupportedATAPICommands[Index], &gEndTable, sizeof (SCSI_COMMAND_SET)) != 0); Index++) {
+
+    if (*OpCode == gSupportedATAPICommands[Index].OpCode) {
+      //
+      // Check whether the requested Command is supported by this driver
+      //
+      if (Packet->DataDirection == DataIn) {
+        //
+        // Check whether the requested data direction conforms to
+        // what it should be.
+        //
+        if (gSupportedATAPICommands[Index].Direction == DataOut) {
+          return FALSE;
+        }
+      }
+
+      if (Packet->DataDirection == DataOut) {
+        //
+        // Check whether the requested data direction conforms to
+        // what it should be.
+        //
+        if (gSupportedATAPICommands[Index].Direction == DataIn) {
+          return FALSE;
+        }
+      }
+
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
+EFI_STATUS
+SubmitExtBlockingIoCommand (
+  ATAPI_SCSI_PASS_THRU_DEV                      *AtapiScsiPrivate,
+  UINT8                                         Target,
+  EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET    *Packet
+  )
+/*++
+
+Routine Description:
+
+  Performs blocking I/O request.
+
+Arguments:
+
+  AtapiScsiPrivate:   Private data structure for the specified channel.
+  Target:             The Target ID of the ATAPI device to send the SCSI
+                      Request Packet. To ATAPI devices attached on an IDE
+                      Channel, Target ID 0 indicates Master device;Target
+                      ID 1 indicates Slave device.
+  Packet:             The SCSI Request Packet to send to the ATAPI device
+                      specified by Target.
+
+  Returns:            EFI_STATUS
+
+--*/
+{
+  UINT8       PacketCommand[12];
+  UINT64      TimeoutInMicroSeconds;
+  EFI_STATUS  PacketCommandStatus;
+
+  //
+  // Fill ATAPI Command Packet according to CDB
+  //
+  ZeroMem (&PacketCommand, 12);
+  CopyMem (&PacketCommand, Packet->Cdb, Packet->CdbLength);
+
+  //
+  // Timeout is 100ns unit, convert it to 1000ns (1us) unit.
+  //
+  TimeoutInMicroSeconds = DivU64x32 (Packet->Timeout, (UINT32) 10);
+
+  //
+  // Submit ATAPI Command Packet
+  //
+  if (Packet->DataDirection == DataIn) {
+    PacketCommandStatus = AtapiPacketCommand (
+                              AtapiScsiPrivate,
+                              Target,
+                              PacketCommand,
+                              Packet->InDataBuffer,
+                              &(Packet->InTransferLength),
+                              DataIn,
+                              TimeoutInMicroSeconds
+                              );
+  } else {
+
+    PacketCommandStatus = AtapiPacketCommand (
+                            AtapiScsiPrivate,
+                            Target,
+                            PacketCommand,
+                            Packet->OutDataBuffer,
+                            &(Packet->OutTransferLength),
+                            DataOut,
+                            TimeoutInMicroSeconds
+                            );
+  }
+
+  if (!EFI_ERROR (PacketCommandStatus) || (Packet->SenseData == NULL)) {
+    Packet->SenseDataLength = 0;
+    return PacketCommandStatus;
+  }
+
+  //
+  // Return SenseData if PacketCommandStatus matches
+  // the following return codes.
+  //
+  if ((PacketCommandStatus == EFI_BAD_BUFFER_SIZE) ||
+      (PacketCommandStatus == EFI_DEVICE_ERROR) ||
+      (PacketCommandStatus == EFI_TIMEOUT)) {
+
+    //
+    // avoid submit request sense command continuously.
+    //
+    if (PacketCommand[0] == OP_REQUEST_SENSE) {
+      Packet->SenseDataLength = 0;
+      return PacketCommandStatus;
+    }
+
+    RequestSenseCommand (
+      AtapiScsiPrivate,
+      Target,
+      Packet->Timeout,
+      Packet->SenseData,
+      &Packet->SenseDataLength
+      );
+  }
+
+  return PacketCommandStatus;
+}
+
+
+EFI_STATUS
+AtapiPacketCommand (
+  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,
+  UINT32                      Target,
+  UINT8                       *PacketCommand,
+  VOID                        *Buffer,
+  UINT32                      *ByteCount,
+  DATA_DIRECTION              Direction,
+  UINT64                      TimeoutInMicroSeconds
+  )
+/*++
+
+Routine Description:
+
+  Submits ATAPI command packet to the specified ATAPI device.
+
+Arguments:
+
+  AtapiScsiPrivate:   Private data structure for the specified channel.
+  Target:             The Target ID of the ATAPI device to send the SCSI
+                      Request Packet. To ATAPI devices attached on an IDE
+                      Channel, Target ID 0 indicates Master device;Target
+                      ID 1 indicates Slave device.
+  PacketCommand:      Points to the ATAPI command packet.
+  Buffer:             Points to the transferred data.
+  ByteCount:          When input,indicates the buffer size; when output,
+                      indicates the actually transferred data size.
+  Direction:          Indicates the data transfer direction.
+  TimeoutInMicroSeconds:
+                      The timeout, in micro second units, to use for the
+                      execution of this ATAPI command.
+                      A TimeoutInMicroSeconds value of 0 means that
+                      this function will wait indefinitely for the ATAPI
+                      command to execute.
+                      If TimeoutInMicroSeconds is greater than zero, then
+                      this function will return EFI_TIMEOUT if the time
+                      required to execute the ATAPI command is greater
+                      than TimeoutInMicroSeconds.
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+{
+
+  UINT16      *CommandIndex;
+  UINT8       Count;
+  EFI_STATUS  Status;
+
+  //
+  // Set all the command parameters by fill related registers.
+  // Before write to all the following registers, BSY must be 0.
+  //
+  Status = StatusWaitForBSYClear (AtapiScsiPrivate, TimeoutInMicroSeconds);
+  if (EFI_ERROR (Status)) {
+    return EFI_DEVICE_ERROR;
+  }
+
+
+  //
+  // Select device via Device/Head Register.
+  // "Target = 0" indicates device 0; "Target = 1" indicates device 1
+  //
+  WritePortB (
+    AtapiScsiPrivate->PciIo,
+    AtapiScsiPrivate->IoPort->Head,
+    (UINT8) ((Target << 4) | DEFAULT_CMD) // DEFAULT_CMD: 0xa0 (1010,0000)
+    );
+
+  //
+  // Set all the command parameters by fill related registers.
+  // Before write to all the following registers, BSY DRQ must be 0.
+  //
+  Status =  StatusDRQClear(AtapiScsiPrivate,  TimeoutInMicroSeconds);
+
+  if (EFI_ERROR (Status)) {
+    if (Status == EFI_ABORTED) {
+      Status = EFI_DEVICE_ERROR;
+    }
+    *ByteCount = 0;
+    return Status;
+  }
+
+  //
+  // No OVL; No DMA (by setting feature register)
+  //
+  WritePortB (
+    AtapiScsiPrivate->PciIo,
+    AtapiScsiPrivate->IoPort->Reg1.Feature,
+    0x00
+    );
+
+  //
+  // set the transfersize to MAX_ATAPI_BYTE_COUNT to let the device
+  // determine how much data should be transfered.
+  //
+  WritePortB (
+    AtapiScsiPrivate->PciIo,
+    AtapiScsiPrivate->IoPort->CylinderLsb,
+    (UINT8) (MAX_ATAPI_BYTE_COUNT & 0x00ff)
+    );
+  WritePortB (
+    AtapiScsiPrivate->PciIo,
+    AtapiScsiPrivate->IoPort->CylinderMsb,
+    (UINT8) (MAX_ATAPI_BYTE_COUNT >> 8)
+    );
+
+  //
+  //  DEFAULT_CTL:0x0a (0000,1010)
+  //  Disable interrupt
+  //
+  WritePortB (
+    AtapiScsiPrivate->PciIo,
+    AtapiScsiPrivate->IoPort->Alt.DeviceControl,
+    DEFAULT_CTL
+    );
+
+  //
+  // Send Packet command to inform device
+  // that the following data bytes are command packet.
+  //
+  WritePortB (
+    AtapiScsiPrivate->PciIo,
+    AtapiScsiPrivate->IoPort->Reg.Command,
+    PACKET_CMD
+    );
+
+  //
+  // Before data transfer, BSY should be 0 and DRQ should be 1.
+  // if they are not in specified time frame,
+  // retrieve Sense Key from Error Register before return.
+  //
+  Status = StatusDRQReady (AtapiScsiPrivate, TimeoutInMicroSeconds);
+  if (EFI_ERROR (Status)) {
+    if (Status == EFI_ABORTED) {
+      Status = EFI_DEVICE_ERROR;
+    }
+
+    *ByteCount = 0;
+    return Status;
+  }
+
+  //
+  // Send out command packet
+  //
+  CommandIndex = (UINT16 *) PacketCommand;
+  for (Count = 0; Count < 6; Count++, CommandIndex++) {
+    WritePortW (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Data, *CommandIndex);
+  }
+
+  //
+  // call AtapiPassThruPioReadWriteData() function to get
+  // requested transfer data form device.
+  //
+  return AtapiPassThruPioReadWriteData (
+          AtapiScsiPrivate,
+          Buffer,
+          ByteCount,
+          Direction,
+          TimeoutInMicroSeconds
+          );
+}
+
+EFI_STATUS
+AtapiPassThruPioReadWriteData (
+  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate,
+  UINT16                    *Buffer,
+  UINT32                    *ByteCount,
+  DATA_DIRECTION            Direction,
+  UINT64                    TimeoutInMicroSeconds
+  )
+/*++
+
+Routine Description:
+
+  Performs data transfer between ATAPI device and host after the
+  ATAPI command packet is sent.
+
+Arguments:
+
+  AtapiScsiPrivate:   Private data structure for the specified channel.
+  Buffer:             Points to the transferred data.
+  ByteCount:          When input,indicates the buffer size; when output,
+                      indicates the actually transferred data size.
+  Direction:          Indicates the data transfer direction.
+  TimeoutInMicroSeconds:
+                      The timeout, in micro second units, to use for the
+                      execution of this ATAPI command.
+                      A TimeoutInMicroSeconds value of 0 means that
+                      this function will wait indefinitely for the ATAPI
+                      command to execute.
+                      If TimeoutInMicroSeconds is greater than zero, then
+                      this function will return EFI_TIMEOUT if the time
+                      required to execute the ATAPI command is greater
+                      than TimeoutInMicroSeconds.
+ Returns:
+
+  EFI_STATUS
+
+--*/
+{
+  UINT32      Index;
+  UINT32      RequiredWordCount;
+  UINT32      ActualWordCount;
+  UINT32      WordCount;
+  EFI_STATUS  Status;
+  UINT16      *ptrBuffer;
+
+  Status = EFI_SUCCESS;
+
+  //
+  // Non Data transfer request is also supported.
+  //
+  if (*ByteCount == 0 || Buffer == NULL) {
+    *ByteCount = 0;
+    if (EFI_ERROR (StatusWaitForBSYClear (AtapiScsiPrivate, TimeoutInMicroSeconds))) {
+      return EFI_DEVICE_ERROR;
+    }
+  }
+
+  ptrBuffer         = Buffer;
+  RequiredWordCount = *ByteCount / 2;
+
+  //
+  // ActuralWordCount means the word count of data really transfered.
+  //
+  ActualWordCount = 0;
+
+  while (ActualWordCount < RequiredWordCount) {
+    //
+    // before each data transfer stream, the host should poll DRQ bit ready,
+    // which indicates device's ready for data transfer .
+    //
+    Status = StatusDRQReady (AtapiScsiPrivate, TimeoutInMicroSeconds);
+    if (EFI_ERROR (Status)) {
+      *ByteCount = ActualWordCount * 2;
+
+      AtapiPassThruCheckErrorStatus (AtapiScsiPrivate);
+
+      if (ActualWordCount == 0) {
+        return EFI_DEVICE_ERROR;
+      }
+      //
+      // ActualWordCount > 0
+      //
+      if (ActualWordCount < RequiredWordCount) {
+        return EFI_BAD_BUFFER_SIZE;
+      }
+    }
+    //
+    // get current data transfer size from Cylinder Registers.
+    //
+    WordCount = ReadPortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->CylinderMsb) << 8;
+    WordCount = WordCount | ReadPortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->CylinderLsb);
+    WordCount = WordCount & 0xffff;
+    WordCount /= 2;
+
+    //
+    // perform a series data In/Out.
+    //
+    for (Index = 0; (Index < WordCount) && (ActualWordCount < RequiredWordCount); Index++, ActualWordCount++) {
+
+      if (Direction == DataIn) {
+
+        *ptrBuffer = ReadPortW (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Data);
+      } else {
+
+        WritePortW (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Data, *ptrBuffer);
+      }
+
+      ptrBuffer++;
+
+    }
+  }
+  //
+  // After data transfer is completed, normally, DRQ bit should clear.
+  //
+  StatusDRQClear (AtapiScsiPrivate, TimeoutInMicroSeconds);
+
+  //
+  // read status register to check whether error happens.
+  //
+  Status      = AtapiPassThruCheckErrorStatus (AtapiScsiPrivate);
+
+  *ByteCount  = ActualWordCount * 2;
+
+  return Status;
+}
+
+
+UINT8
+ReadPortB (
+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
+  IN  UINT16                Port
+  )
+/*++
+
+Routine Description:
+
+  Read one byte from a specified I/O port.
+
+Arguments:
+
+  PciIo      - The pointer of EFI_PCI_IO_PROTOCOL
+  Port       - IO port
+
+Returns:
+
+  A byte read out
+
+--*/
+{
+  UINT8 Data;
+
+  Data = 0;
+  PciIo->Io.Read (
+              PciIo,
+              EfiPciIoWidthUint8,
+              EFI_PCI_IO_PASS_THROUGH_BAR,
+              (UINT64) Port,
+              1,
+              &Data
+              );
+  return Data;
+}
+
+
+UINT16
+ReadPortW (
+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
+  IN  UINT16                Port
+  )
+/*++
+
+Routine Description:
+
+  Read one word from a specified I/O port.
+
+Arguments:
+
+  PciIo      - The pointer of EFI_PCI_IO_PROTOCOL
+  Port       - IO port
+
+Returns:
+
+  A word read out
+--*/
+{
+  UINT16  Data;
+
+  Data = 0;
+  PciIo->Io.Read (
+              PciIo,
+              EfiPciIoWidthUint16,
+              EFI_PCI_IO_PASS_THROUGH_BAR,
+              (UINT64) Port,
+              1,
+              &Data
+              );
+  return Data;
+}
+
+
+VOID
+WritePortB (
+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
+  IN  UINT16                Port,
+  IN  UINT8                 Data
+  )
+/*++
+
+Routine Description:
+
+  Write one byte to a specified I/O port.
+
+Arguments:
+
+  PciIo      - The pointer of EFI_PCI_IO_PROTOCOL
+  Port       - IO port
+  Data       - The data to write
+
+Returns:
+
+   NONE
+
+--*/
+{
+  PciIo->Io.Write (
+              PciIo,
+              EfiPciIoWidthUint8,
+              EFI_PCI_IO_PASS_THROUGH_BAR,
+              (UINT64) Port,
+              1,
+              &Data
+              );
+}
+
+
+VOID
+WritePortW (
+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
+  IN  UINT16                Port,
+  IN  UINT16                Data
+  )
+/*++
+
+Routine Description:
+
+  Write one word to a specified I/O port.
+
+Arguments:
+
+  PciIo      - The pointer of EFI_PCI_IO_PROTOCOL
+  Port       - IO port
+  Data       - The data to write
+
+Returns:
+
+   NONE
+
+--*/
+{
+  PciIo->Io.Write (
+              PciIo,
+              EfiPciIoWidthUint16,
+              EFI_PCI_IO_PASS_THROUGH_BAR,
+              (UINT64) Port,
+              1,
+              &Data
+              );
+}
+
+EFI_STATUS
+StatusDRQClear (
+  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,
+  UINT64                          TimeoutInMicroSeconds
+  )
+/*++
+
+Routine Description:
+
+  Check whether DRQ is clear in the Status Register. (BSY must also be cleared)
+  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
+  DRQ clear. Otherwise, it will return EFI_TIMEOUT when specified time is
+  elapsed.
+
+Arguments:
+
+  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
+  TimeoutInMicroSeconds       - The time to wait for
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+{
+  UINT64  Delay;
+  UINT8   StatusRegister;
+  UINT8   ErrRegister;
+
+  if (TimeoutInMicroSeconds == 0) {
+    Delay = 2;
+  } else {
+    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
+  }
+
+  do {
+
+    StatusRegister = ReadPortB (
+                      AtapiScsiPrivate->PciIo,
+                      AtapiScsiPrivate->IoPort->Reg.Status
+                      );
+
+    //
+    // wait for BSY == 0 and DRQ == 0
+    //
+    if ((StatusRegister & (DRQ | BSY)) == 0) {
+      break;
+    }
+    //
+    // check whether the command is aborted by the device
+    //
+    if ((StatusRegister & (BSY | ERR)) == ERR) {
+
+      ErrRegister = ReadPortB (
+                      AtapiScsiPrivate->PciIo,
+                      AtapiScsiPrivate->IoPort->Reg1.Error
+                      );
+      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {
+
+        return EFI_ABORTED;
+      }
+    }
+    //
+    //  Stall for 30 us
+    //
+    gBS->Stall (30);
+
+    //
+    // Loop infinitely if not meeting expected condition
+    //
+    if (TimeoutInMicroSeconds == 0) {
+      Delay = 2;
+    }
+
+    Delay--;
+  } while (Delay);
+
+  if (Delay == 0) {
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+AltStatusDRQClear (
+  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,
+  UINT64                          TimeoutInMicroSeconds
+  )
+/*++
+
+Routine Description:
+
+  Check whether DRQ is clear in the Alternate Status Register.
+  (BSY must also be cleared).If TimeoutInMicroSeconds is zero, this routine should
+  wait infinitely for DRQ clear. Otherwise, it will return EFI_TIMEOUT when specified time is
+  elapsed.
+
+Arguments:
+
+  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
+  TimeoutInMicroSeconds       - The time to wait for
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+{
+  UINT64  Delay;
+  UINT8   AltStatusRegister;
+  UINT8   ErrRegister;
+
+  if (TimeoutInMicroSeconds == 0) {
+    Delay = 2;
+  } else {
+    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
+  }
+
+  do {
+
+    AltStatusRegister = ReadPortB (
+                          AtapiScsiPrivate->PciIo,
+                          AtapiScsiPrivate->IoPort->Alt.AltStatus
+                          );
+
+    //
+    // wait for BSY == 0 and DRQ == 0
+    //
+    if ((AltStatusRegister & (DRQ | BSY)) == 0) {
+      break;
+    }
+
+    if ((AltStatusRegister & (BSY | ERR)) == ERR) {
+
+      ErrRegister = ReadPortB (
+                      AtapiScsiPrivate->PciIo,
+                      AtapiScsiPrivate->IoPort->Reg1.Error
+                      );
+      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {
+
+        return EFI_ABORTED;
+      }
+    }
+    //
+    //  Stall for 30 us
+    //
+    gBS->Stall (30);
+
+    //
+    // Loop infinitely if not meeting expected condition
+    //
+    if (TimeoutInMicroSeconds == 0) {
+      Delay = 2;
+    }
+
+    Delay--;
+  } while (Delay);
+
+  if (Delay == 0) {
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+StatusDRQReady (
+  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,
+  UINT64                          TimeoutInMicroSeconds
+  )
+/*++
+
+Routine Description:
+
+  Check whether DRQ is ready in the Status Register. (BSY must also be cleared)
+  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
+  DRQ ready. Otherwise, it will return EFI_TIMEOUT when specified time is
+  elapsed.
+
+Arguments:
+
+  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
+  TimeoutInMicroSeconds       - The time to wait for
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+{
+  UINT64  Delay;
+  UINT8   StatusRegister;
+  UINT8   ErrRegister;
+
+  if (TimeoutInMicroSeconds == 0) {
+    Delay = 2;
+  } else {
+    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
+  }
+
+  do {
+    //
+    //  read Status Register will clear interrupt
+    //
+    StatusRegister = ReadPortB (
+                      AtapiScsiPrivate->PciIo,
+                      AtapiScsiPrivate->IoPort->Reg.Status
+                      );
+
+    //
+    //  BSY==0,DRQ==1
+    //
+    if ((StatusRegister & (BSY | DRQ)) == DRQ) {
+      break;
+    }
+
+    if ((StatusRegister & (BSY | ERR)) == ERR) {
+
+      ErrRegister = ReadPortB (
+                      AtapiScsiPrivate->PciIo,
+                      AtapiScsiPrivate->IoPort->Reg1.Error
+                      );
+      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {
+        return EFI_ABORTED;
+      }
+    }
+
+    //
+    // Stall for 30 us
+    //
+    gBS->Stall (30);
+
+    //
+    // Loop infinitely if not meeting expected condition
+    //
+    if (TimeoutInMicroSeconds == 0) {
+      Delay = 2;
+    }
+
+    Delay--;
+  } while (Delay);
+
+  if (Delay == 0) {
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+AltStatusDRQReady (
+  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,
+  UINT64                          TimeoutInMicroSeconds
+  )
+/*++
+
+Routine Description:
+
+  Check whether DRQ is ready in the Alternate Status Register.
+  (BSY must also be cleared)
+  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
+  DRQ ready. Otherwise, it will return EFI_TIMEOUT when specified time is
+  elapsed.
+
+Arguments:
+
+  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
+  TimeoutInMicroSeconds       - The time to wait for
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+{
+  UINT64  Delay;
+  UINT8   AltStatusRegister;
+  UINT8   ErrRegister;
+
+  if (TimeoutInMicroSeconds == 0) {
+    Delay = 2;
+  } else {
+    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
+  }
+
+  do {
+    //
+    //  read Status Register will clear interrupt
+    //
+    AltStatusRegister = ReadPortB (
+                          AtapiScsiPrivate->PciIo,
+                          AtapiScsiPrivate->IoPort->Alt.AltStatus
+                          );
+    //
+    //  BSY==0,DRQ==1
+    //
+    if ((AltStatusRegister & (BSY | DRQ)) == DRQ) {
+      break;
+    }
+
+    if ((AltStatusRegister & (BSY | ERR)) == ERR) {
+
+      ErrRegister = ReadPortB (
+                      AtapiScsiPrivate->PciIo,
+                      AtapiScsiPrivate->IoPort->Reg1.Error
+                      );
+      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {
+        return EFI_ABORTED;
+      }
+    }
+
+    //
+    // Stall for 30 us
+    //
+    gBS->Stall (30);
+
+    //
+    // Loop infinitely if not meeting expected condition
+    //
+    if (TimeoutInMicroSeconds == 0) {
+      Delay = 2;
+    }
+
+    Delay--;
+  } while (Delay);
+
+  if (Delay == 0) {
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+StatusWaitForBSYClear (
+  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,
+  UINT64                      TimeoutInMicroSeconds
+  )
+/*++
+
+Routine Description:
+
+  Check whether BSY is clear in the Status Register.
+  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
+  BSY clear. Otherwise, it will return EFI_TIMEOUT when specified time is
+  elapsed.
+
+Arguments:
+
+  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
+  TimeoutInMicroSeconds       - The time to wait for
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+{
+  UINT64  Delay;
+  UINT8   StatusRegister;
+
+  if (TimeoutInMicroSeconds == 0) {
+    Delay = 2;
+  } else {
+    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
+  }
+
+  do {
+
+    StatusRegister = ReadPortB (
+                      AtapiScsiPrivate->PciIo,
+                      AtapiScsiPrivate->IoPort->Reg.Status
+                      );
+    if ((StatusRegister & BSY) == 0x00) {
+      break;
+    }
+
+    //
+    // Stall for 30 us
+    //
+    gBS->Stall (30);
+
+    //
+    // Loop infinitely if not meeting expected condition
+    //
+    if (TimeoutInMicroSeconds == 0) {
+      Delay = 2;
+    }
+
+    Delay--;
+  } while (Delay);
+
+  if (Delay == 0) {
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+AltStatusWaitForBSYClear (
+  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,
+  UINT64                      TimeoutInMicroSeconds
+  )
+/*++
+
+Routine Description:
+
+  Check whether BSY is clear in the Alternate Status Register.
+  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
+  BSY clear. Otherwise, it will return EFI_TIMEOUT when specified time is
+  elapsed.
+
+Arguments:
+
+  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
+  TimeoutInMicroSeconds       - The time to wait for
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+{
+  UINT64  Delay;
+  UINT8   AltStatusRegister;
+
+  if (TimeoutInMicroSeconds == 0) {
+    Delay = 2;
+  } else {
+    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
+  }
+
+  do {
+
+    AltStatusRegister = ReadPortB (
+                          AtapiScsiPrivate->PciIo,
+                          AtapiScsiPrivate->IoPort->Alt.AltStatus
+                          );
+    if ((AltStatusRegister & BSY) == 0x00) {
+      break;
+    }
+
+    //
+    // Stall for 30 us
+    //
+    gBS->Stall (30);
+    //
+    // Loop infinitely if not meeting expected condition
+    //
+    if (TimeoutInMicroSeconds == 0) {
+      Delay = 2;
+    }
+
+    Delay--;
+  } while (Delay);
+
+  if (Delay == 0) {
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+StatusDRDYReady (
+  ATAPI_SCSI_PASS_THRU_DEV     *AtapiScsiPrivate,
+  UINT64                       TimeoutInMicroSeconds
+  )
+/*++
+
+Routine Description:
+
+  Check whether DRDY is ready in the Status Register.
+  (BSY must also be cleared)
+  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
+  DRDY ready. Otherwise, it will return EFI_TIMEOUT when specified time is
+  elapsed.
+
+Arguments:
+
+  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
+  TimeoutInMicroSeconds       - The time to wait for
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+{
+  UINT64  Delay;
+  UINT8   StatusRegister;
+  UINT8   ErrRegister;
+
+  if (TimeoutInMicroSeconds == 0) {
+    Delay = 2;
+  } else {
+    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
+  }
+
+  do {
+    StatusRegister = ReadPortB (
+                      AtapiScsiPrivate->PciIo,
+                      AtapiScsiPrivate->IoPort->Reg.Status
+                      );
+    //
+    //  BSY == 0 , DRDY == 1
+    //
+    if ((StatusRegister & (DRDY | BSY)) == DRDY) {
+      break;
+    }
+
+    if ((StatusRegister & (BSY | ERR)) == ERR) {
+
+      ErrRegister = ReadPortB (
+                      AtapiScsiPrivate->PciIo,
+                      AtapiScsiPrivate->IoPort->Reg1.Error
+                      );
+      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {
+        return EFI_ABORTED;
+      }
+    }
+
+    //
+    // Stall for 30 us
+    //
+    gBS->Stall (30);
+    //
+    // Loop infinitely if not meeting expected condition
+    //
+    if (TimeoutInMicroSeconds == 0) {
+      Delay = 2;
+    }
+
+    Delay--;
+  } while (Delay);
+
+  if (Delay == 0) {
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+AltStatusDRDYReady (
+  ATAPI_SCSI_PASS_THRU_DEV     *AtapiScsiPrivate,
+  UINT64                       TimeoutInMicroSeconds
+  )
+/*++
+
+Routine Description:
+
+  Check whether DRDY is ready in the Alternate Status Register.
+  (BSY must also be cleared)
+  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
+  DRDY ready. Otherwise, it will return EFI_TIMEOUT when specified time is
+  elapsed.
+
+Arguments:
+
+  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
+  TimeoutInMicroSeconds       - The time to wait for
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+{
+  UINT64  Delay;
+  UINT8   AltStatusRegister;
+  UINT8   ErrRegister;
+
+  if (TimeoutInMicroSeconds == 0) {
+    Delay = 2;
+  } else {
+    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
+  }
+
+  do {
+    AltStatusRegister = ReadPortB (
+                          AtapiScsiPrivate->PciIo,
+                          AtapiScsiPrivate->IoPort->Alt.AltStatus
+                          );
+    //
+    //  BSY == 0 , DRDY == 1
+    //
+    if ((AltStatusRegister & (DRDY | BSY)) == DRDY) {
+      break;
+    }
+
+    if ((AltStatusRegister & (BSY | ERR)) == ERR) {
+
+      ErrRegister = ReadPortB (
+                      AtapiScsiPrivate->PciIo,
+                      AtapiScsiPrivate->IoPort->Reg1.Error
+                      );
+      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {
+        return EFI_ABORTED;
+      }
+    }
+
+    //
+    // Stall for 30 us
+    //
+    gBS->Stall (30);
+    //
+    // Loop infinitely if not meeting expected condition
+    //
+    if (TimeoutInMicroSeconds == 0) {
+      Delay = 2;
+    }
+
+    Delay--;
+  } while (Delay);
+
+  if (Delay == 0) {
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+AtapiPassThruCheckErrorStatus (
+  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate
+  )
+/*++
+
+Routine Description:
+
+  Check Error Register for Error Information.
+
+Arguments:
+
+  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+{
+  UINT8 StatusRegister;
+  UINT8 ErrorRegister;
+
+  StatusRegister = ReadPortB (
+                    AtapiScsiPrivate->PciIo,
+                    AtapiScsiPrivate->IoPort->Reg.Status
+                    );
+
+  DEBUG_CODE_BEGIN ();
+
+    if (StatusRegister & DWF) {
+      DEBUG (
+        (EFI_D_BLKIO,
+        "AtapiPassThruCheckErrorStatus()-- %02x : Error : Write Fault\n",
+        StatusRegister)
+        );
+    }
+
+    if (StatusRegister & CORR) {
+      DEBUG (
+        (EFI_D_BLKIO,
+        "AtapiPassThruCheckErrorStatus()-- %02x : Error : Corrected Data\n",
+        StatusRegister)
+        );
+    }
+
+    if (StatusRegister & ERR) {
+      ErrorRegister = ReadPortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Reg1.Error);
+
+
+      if (ErrorRegister & BBK_ERR) {
+        DEBUG (
+          (EFI_D_BLKIO,
+          "AtapiPassThruCheckErrorStatus()-- %02x : Error : Bad Block Detected\n",
+          ErrorRegister)
+          );
+      }
+
+      if (ErrorRegister & UNC_ERR) {
+        DEBUG (
+          (EFI_D_BLKIO,
+          "AtapiPassThruCheckErrorStatus()-- %02x : Error : Uncorrectable Data\n",
+          ErrorRegister)
+          );
+      }
+
+      if (ErrorRegister & MC_ERR) {
+        DEBUG (
+          (EFI_D_BLKIO,
+          "AtapiPassThruCheckErrorStatus()-- %02x : Error : Media Change\n",
+          ErrorRegister)
+          );
+      }
+
+      if (ErrorRegister & ABRT_ERR) {
+        DEBUG (
+          (EFI_D_BLKIO,
+          "AtapiPassThruCheckErrorStatus()-- %02x : Error : Abort\n",
+          ErrorRegister)
+          );
+      }
+
+      if (ErrorRegister & TK0NF_ERR) {
+        DEBUG (
+          (EFI_D_BLKIO,
+          "AtapiPassThruCheckErrorStatus()-- %02x : Error : Track 0 Not Found\n",
+          ErrorRegister)
+          );
+      }
+
+      if (ErrorRegister & AMNF_ERR) {
+        DEBUG (
+          (EFI_D_BLKIO,
+          "AtapiPassThruCheckErrorStatus()-- %02x : Error : Address Mark Not Found\n",
+          ErrorRegister)
+          );
+       }
+    }
+
+  DEBUG_CODE_END ();
+
+  if ((StatusRegister & (ERR | DWF | CORR)) == 0) {
+    return EFI_SUCCESS;
+  }
+
+
+  return EFI_DEVICE_ERROR;
+}
+
+
+/**
+  Installs Scsi Pass Thru and/or Ext Scsi Pass Thru
+  protocols based on feature flags.
+
+  @param Controller         The controller handle to
+                            install these protocols on.
+  @param AtapiScsiPrivate   A pointer to the protocol private
+                            data structure.
+
+  @retval EFI_SUCCESS       The installation succeeds.
+  @retval other             The installation fails.
+
+**/
+EFI_STATUS
+InstallScsiPassThruProtocols (
+  IN EFI_HANDLE                     *ControllerHandle,
+  IN ATAPI_SCSI_PASS_THRU_DEV       *AtapiScsiPrivate
+  )
+{
+  EFI_STATUS                        Status;
+  EFI_SCSI_PASS_THRU_PROTOCOL       *ScsiPassThru;
+  EFI_EXT_SCSI_PASS_THRU_PROTOCOL   *ExtScsiPassThru;
+
+  ScsiPassThru = &AtapiScsiPrivate->ScsiPassThru;
+  ExtScsiPassThru = &AtapiScsiPrivate->ExtScsiPassThru;
+
+  if (FeaturePcdGet (PcdSupportScsiPassThru)) {
+    ScsiPassThru = CopyMem (ScsiPassThru, &gScsiPassThruProtocolTemplate, sizeof (*ScsiPassThru));
+    if (FeaturePcdGet (PcdSupportExtScsiPassThru)) {
+      ExtScsiPassThru = CopyMem (ExtScsiPassThru, &gExtScsiPassThruProtocolTemplate, sizeof (*ExtScsiPassThru));
+      Status = gBS->InstallMultipleProtocolInterfaces (
+                      ControllerHandle,
+                      &gEfiScsiPassThruProtocolGuid,
+                      ScsiPassThru,
+                      &gEfiExtScsiPassThruProtocolGuid,
+                      ExtScsiPassThru,
+                      NULL
+                      );
+    } else {
+      Status = gBS->InstallMultipleProtocolInterfaces (
+                      ControllerHandle,
+                      &gEfiScsiPassThruProtocolGuid,
+                      ScsiPassThru,
+                      NULL
+                      );
+    }
+  } else {
+    if (FeaturePcdGet (PcdSupportExtScsiPassThru)) {
+      ExtScsiPassThru = CopyMem (ExtScsiPassThru, &gExtScsiPassThruProtocolTemplate, sizeof (*ExtScsiPassThru));
+      Status = gBS->InstallMultipleProtocolInterfaces (
+                      ControllerHandle,
+                      &gEfiExtScsiPassThruProtocolGuid,
+                      ExtScsiPassThru,
+                      NULL
+                      );
+    } else {
+      //
+      // This driver must support either ScsiPassThru or
+      // ExtScsiPassThru protocols
+      //
+      ASSERT (FALSE);
+      Status = EFI_UNSUPPORTED;
+    }
+  }
+
+  return Status;
+}
+
+/**
+  The user Entry Point for module AtapiPassThru. The user code starts with this function.
+
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
+  @param[in] SystemTable    A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS       The entry point is executed successfully.
+  @retval other             Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeAtapiPassThru(
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+  EFI_STATUS              Status;
+
+  //
+  // Install driver model protocol(s).
+  //
+  Status = EfiLibInstallDriverBindingComponentName2 (
+             ImageHandle,
+             SystemTable,
+             &gAtapiScsiPassThruDriverBinding,
+             ImageHandle,
+             &gAtapiScsiPassThruComponentName,
+             &gAtapiScsiPassThruComponentName2
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Install EFI Driver Supported EFI Version Protocol required for
+  // EFI drivers that are on PCI and other plug in cards.
+  //
+  gAtapiScsiPassThruDriverSupportedEfiVersion.FirmwareVersion = PcdGet32 (PcdDriverSupportedEfiVersion);
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gEfiDriverSupportedEfiVersionProtocolGuid,
+                  &gAtapiScsiPassThruDriverSupportedEfiVersion,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.h b/Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.h
new file mode 100644
index 0000000000..9fca7b6ac2
--- /dev/null
+++ b/Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.h
@@ -0,0 +1,1618 @@
+/** @file
+  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  Module Name:  AtapiPassThru.h
+
+**/
+
+#ifndef _APT_H
+#define _APT_H
+
+
+
+#include <Uefi.h>
+
+#include <Protocol/ScsiPassThru.h>
+#include <Protocol/ScsiPassThruExt.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/DriverSupportedEfiVersion.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DevicePathLib.h>
+
+#include <IndustryStandard/Pci.h>
+
+#define MAX_TARGET_ID 4
+
+//
+// IDE Registers
+//
+typedef union {
+  UINT16  Command;        /* when write */
+  UINT16  Status;         /* when read */
+} IDE_CMD_OR_STATUS;
+
+typedef union {
+  UINT16  Error;          /* when read */
+  UINT16  Feature;        /* when write */
+} IDE_ERROR_OR_FEATURE;
+
+typedef union {
+  UINT16  AltStatus;      /* when read */
+  UINT16  DeviceControl;  /* when write */
+} IDE_AltStatus_OR_DeviceControl;
+
+
+typedef enum {
+  IdePrimary    = 0,
+  IdeSecondary  = 1,
+  IdeMaxChannel = 2
+} EFI_IDE_CHANNEL;
+
+///
+
+
+//
+// Bit definitions in Programming Interface byte of the Class Code field
+// in PCI IDE controller's Configuration Space
+//
+#define IDE_PRIMARY_OPERATING_MODE            BIT0
+#define IDE_PRIMARY_PROGRAMMABLE_INDICATOR    BIT1
+#define IDE_SECONDARY_OPERATING_MODE          BIT2
+#define IDE_SECONDARY_PROGRAMMABLE_INDICATOR  BIT3
+
+
+#define ATAPI_MAX_CHANNEL 2
+
+///
+/// IDE registers set
+///
+typedef struct {
+  UINT16                          Data;
+  IDE_ERROR_OR_FEATURE            Reg1;
+  UINT16                          SectorCount;
+  UINT16                          SectorNumber;
+  UINT16                          CylinderLsb;
+  UINT16                          CylinderMsb;
+  UINT16                          Head;
+  IDE_CMD_OR_STATUS               Reg;
+  IDE_AltStatus_OR_DeviceControl  Alt;
+  UINT16                          DriveAddress;
+} IDE_BASE_REGISTERS;
+
+#define ATAPI_SCSI_PASS_THRU_DEV_SIGNATURE  SIGNATURE_32 ('a', 's', 'p', 't')
+
+typedef struct {
+  UINTN                            Signature;
+  EFI_HANDLE                       Handle;
+  EFI_SCSI_PASS_THRU_PROTOCOL      ScsiPassThru;
+  EFI_EXT_SCSI_PASS_THRU_PROTOCOL  ExtScsiPassThru;
+  EFI_PCI_IO_PROTOCOL              *PciIo;
+  UINT64                           OriginalPciAttributes;
+  //
+  // Local Data goes here
+  //
+  IDE_BASE_REGISTERS               *IoPort;
+  IDE_BASE_REGISTERS               AtapiIoPortRegisters[2];
+  UINT32                           LatestTargetId;
+  UINT64                           LatestLun;
+} ATAPI_SCSI_PASS_THRU_DEV;
+
+//
+// IDE registers' base addresses
+//
+typedef struct {
+  UINT16  CommandBlockBaseAddr;
+  UINT16  ControlBlockBaseAddr;
+} IDE_REGISTERS_BASE_ADDR;
+
+#define ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS(a) \
+  CR (a, \
+      ATAPI_SCSI_PASS_THRU_DEV, \
+      ScsiPassThru, \
+      ATAPI_SCSI_PASS_THRU_DEV_SIGNATURE \
+      )
+
+#define ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS(a) \
+  CR (a, \
+      ATAPI_SCSI_PASS_THRU_DEV, \
+      ExtScsiPassThru, \
+      ATAPI_SCSI_PASS_THRU_DEV_SIGNATURE \
+      )
+
+//
+// Global Variables
+//
+extern EFI_DRIVER_BINDING_PROTOCOL                gAtapiScsiPassThruDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL                gAtapiScsiPassThruComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL               gAtapiScsiPassThruComponentName2;
+extern EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL  gAtapiScsiPassThruDriverSupportedEfiVersion;
+
+//
+// ATAPI Command op code
+//
+#define OP_INQUIRY                      0x12
+#define OP_LOAD_UNLOAD_CD               0xa6
+#define OP_MECHANISM_STATUS             0xbd
+#define OP_MODE_SELECT_10               0x55
+#define OP_MODE_SENSE_10                0x5a
+#define OP_PAUSE_RESUME                 0x4b
+#define OP_PLAY_AUDIO_10                0x45
+#define OP_PLAY_AUDIO_MSF               0x47
+#define OP_PLAY_CD                      0xbc
+#define OP_PLAY_CD_MSF                  0xb4
+#define OP_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
+#define OP_READ_10                      0x28
+#define OP_READ_12                      0xa8
+#define OP_READ_CAPACITY                0x25
+#define OP_READ_CD                      0xbe
+#define OP_READ_CD_MSF                  0xb9
+#define OP_READ_HEADER                  0x44
+#define OP_READ_SUB_CHANNEL             0x42
+#define OP_READ_TOC                     0x43
+#define OP_REQUEST_SENSE                0x03
+#define OP_SCAN                         0xba
+#define OP_SEEK_10                      0x2b
+#define OP_SET_CD_SPEED                 0xbb
+#define OP_STOPPLAY_SCAN                0x4e
+#define OP_START_STOP_UNIT              0x1b
+#define OP_TEST_UNIT_READY              0x00
+
+#define OP_FORMAT_UNIT                  0x04
+#define OP_READ_FORMAT_CAPACITIES       0x23
+#define OP_VERIFY                       0x2f
+#define OP_WRITE_10                     0x2a
+#define OP_WRITE_12                     0xaa
+#define OP_WRITE_AND_VERIFY             0x2e
+
+//
+// ATA Command
+//
+#define ATAPI_SOFT_RESET_CMD  0x08
+
+typedef enum {
+  DataIn  = 0,
+  DataOut = 1,
+  DataBi  = 2,
+  NoData  = 3,
+  End     = 0xff
+} DATA_DIRECTION;
+
+typedef struct {
+  UINT8           OpCode;
+  DATA_DIRECTION  Direction;
+} SCSI_COMMAND_SET;
+
+#define MAX_CHANNEL         2
+
+#define ValidCdbLength(Len) ((Len) == 6 || (Len) == 10 || (Len) == 12) ? 1 : 0
+
+//
+// IDE registers bit definitions
+//
+// ATA Err Reg bitmap
+//
+#define BBK_ERR   BIT7 ///< Bad block detected
+#define UNC_ERR   BIT6 ///< Uncorrectable Data
+#define MC_ERR    BIT5 ///< Media Change
+#define IDNF_ERR  BIT4 ///< ID Not Found
+#define MCR_ERR   BIT3 ///< Media Change Requested
+#define ABRT_ERR  BIT2 ///< Aborted Command
+#define TK0NF_ERR BIT1 ///< Track 0 Not Found
+#define AMNF_ERR  BIT0 ///< Address Mark Not Found
+
+//
+// ATAPI Err Reg bitmap
+//
+#define SENSE_KEY_ERR (BIT7 | BIT6 | BIT5 | BIT4)
+#define EOM_ERR BIT1 ///< End of Media Detected
+#define ILI_ERR BIT0 ///< Illegal Length Indication
+
+//
+// Device/Head Reg
+//
+#define LBA_MODE  BIT6
+#define DEV       BIT4
+#define HS3       BIT3
+#define HS2       BIT2
+#define HS1       BIT1
+#define HS0       BIT0
+#define CHS_MODE  (0)
+#define DRV0      (0)
+#define DRV1      (1)
+#define MST_DRV   DRV0
+#define SLV_DRV   DRV1
+
+//
+// Status Reg
+//
+#define BSY   BIT7 ///< Controller Busy
+#define DRDY  BIT6 ///< Drive Ready
+#define DWF   BIT5 ///< Drive Write Fault
+#define DSC   BIT4 ///< Disk Seek Complete
+#define DRQ   BIT3 ///< Data Request
+#define CORR  BIT2 ///< Corrected Data
+#define IDX   BIT1 ///< Index
+#define ERR   BIT0 ///< Error
+#define CHECK BIT0 ///< Check bit for ATAPI Status Reg
+
+//
+// Device Control Reg
+//
+#define SRST  BIT2 ///< Software Reset
+#define IEN_L BIT1 ///< Interrupt Enable
+
+//
+// ATAPI Feature Register
+//
+#define OVERLAP BIT1
+#define DMA     BIT0
+
+//
+// ATAPI Interrupt Reason Reson Reg (ATA Sector Count Register)
+//
+#define RELEASE     BIT2
+#define IO          BIT1
+#define CoD         BIT0
+
+#define PACKET_CMD  0xA0
+
+#define DEFAULT_CMD (0xa0)
+//
+// default content of device control register, disable INT
+//
+#define DEFAULT_CTL           (0x0a)
+#define MAX_ATAPI_BYTE_COUNT  (0xfffe)
+
+//
+// function prototype
+//
+
+EFI_STATUS
+EFIAPI
+AtapiScsiPassThruDriverBindingSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  );
+
+EFI_STATUS
+EFIAPI
+AtapiScsiPassThruDriverBindingStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  );
+
+EFI_STATUS
+EFIAPI
+AtapiScsiPassThruDriverBindingStop (
+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
+  IN  EFI_HANDLE                      Controller,
+  IN  UINTN                           NumberOfChildren,
+  IN  EFI_HANDLE                      *ChildHandleBuffer
+  );
+
+//
+// EFI Component Name Functions
+//
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 4646 or ISO 639-2 language code format.
+
+  @param  DriverName[out]       A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+AtapiScsiPassThruComponentNameGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **DriverName
+  );
+
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  ControllerHandle[in]  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+
+  @param  ChildHandle[in]       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 4646 or ISO 639-2 language code format.
+
+  @param  ControllerName[out]   A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                controller specified by ControllerHandle and
+                                ChildHandle in the language specified by
+                                Language from the point of view of the driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+
+  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+AtapiScsiPassThruComponentNameGetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
+  IN  EFI_HANDLE                                      ControllerHandle,
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
+  IN  CHAR8                                           *Language,
+  OUT CHAR16                                          **ControllerName
+  );
+
+
+EFI_STATUS
+EFIAPI
+AtapiScsiPassThruDriverEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+ /*++
+
+Routine Description:
+
+  Entry point for EFI drivers.
+
+Arguments:
+
+  ImageHandle - EFI_HANDLE
+  SystemTable - EFI_SYSTEM_TABLE
+
+Returns:
+
+  EFI_SUCCESS
+  Others 
+
+--*/
+;
+
+EFI_STATUS
+RegisterAtapiScsiPassThru (
+  IN  EFI_DRIVER_BINDING_PROTOCOL *This,
+  IN  EFI_HANDLE                  Controller,
+  IN  EFI_PCI_IO_PROTOCOL         *PciIo,
+  IN  UINT64                      OriginalPciAttributes
+  )
+/*++
+
+Routine Description:
+  Attaches SCSI Pass Thru Protocol for specified IDE channel.
+    
+Arguments:
+  This              - Protocol instance pointer.
+  Controller        - Parent device handle to the IDE channel.    
+  PciIo             - PCI I/O protocol attached on the "Controller".                        
+  
+Returns:
+  Always return EFI_SUCCESS unless installing SCSI Pass Thru Protocol failed.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+AtapiScsiPassThruFunction (
+  IN EFI_SCSI_PASS_THRU_PROTOCOL                        *This,
+  IN UINT32                                             Target,
+  IN UINT64                                             Lun,
+  IN OUT EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET         *Packet,
+  IN EFI_EVENT                                          Event OPTIONAL
+  )
+/*++
+
+Routine Description:
+
+  Implements EFI_SCSI_PASS_THRU_PROTOCOL.PassThru() function.
+
+Arguments:
+
+  This:     The EFI_SCSI_PASS_THRU_PROTOCOL instance.
+  Target:   The Target ID of the ATAPI device to send the SCSI 
+            Request Packet. To ATAPI devices attached on an IDE
+            Channel, Target ID 0 indicates Master device;Target
+            ID 1 indicates Slave device.
+  Lun:      The LUN of the ATAPI device to send the SCSI Request
+            Packet. To the ATAPI device, Lun is always 0.
+  Packet:   The SCSI Request Packet to send to the ATAPI device 
+            specified by Target and Lun.
+  Event:    If non-blocking I/O is not supported then Event is ignored, 
+            and blocking I/O is performed.
+            If Event is NULL, then blocking I/O is performed.
+            If Event is not NULL and non blocking I/O is supported, 
+            then non-blocking I/O is performed, and Event will be signaled 
+            when the SCSI Request Packet completes.      
+
+Returns:  
+
+   EFI_STATUS
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+AtapiScsiPassThruGetNextDevice (
+  IN  EFI_SCSI_PASS_THRU_PROTOCOL    *This,
+  IN OUT UINT32                      *Target,
+  IN OUT UINT64                      *Lun
+  )
+/*++
+
+Routine Description:
+
+  Used to retrieve the list of legal Target IDs for SCSI devices 
+  on a SCSI channel.
+
+Arguments:
+
+  This                  - Protocol instance pointer.
+  Target                - On input, a pointer to the Target ID of a SCSI 
+                          device present on the SCSI channel.  On output, 
+                          a pointer to the Target ID of the next SCSI device
+                          present on a SCSI channel.  An input value of 
+                          0xFFFFFFFF retrieves the Target ID of the first 
+                          SCSI device present on a SCSI channel.
+  Lun                   - On input, a pointer to the LUN of a SCSI device
+                          present on the SCSI channel. On output, a pointer
+                          to the LUN of the next SCSI device present on 
+                          a SCSI channel.
+Returns:
+
+  EFI_SUCCESS           - The Target ID and Lun of the next SCSI device 
+                          on the SCSI channel was returned in Target and Lun.
+  EFI_NOT_FOUND         - There are no more SCSI devices on this SCSI channel.
+  EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun were not
+                           returned on a previous call to GetNextDevice().
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+AtapiScsiPassThruBuildDevicePath (
+  IN     EFI_SCSI_PASS_THRU_PROTOCOL    *This,
+  IN     UINT32                         Target,
+  IN     UINT64                         Lun,
+  IN OUT EFI_DEVICE_PATH_PROTOCOL       **DevicePath
+  )
+/*++
+
+Routine Description:
+
+  Used to allocate and build a device path node for a SCSI device 
+  on a SCSI channel. Would not build device path for a SCSI Host Controller.
+
+Arguments:
+
+  This                  - Protocol instance pointer.
+  Target                - The Target ID of the SCSI device for which
+                          a device path node is to be allocated and built.
+  Lun                   - The LUN of the SCSI device for which a device 
+                          path node is to be allocated and built.
+  DevicePath            - A pointer to a single device path node that 
+                          describes the SCSI device specified by 
+                          Target and Lun. This function is responsible 
+                          for allocating the buffer DevicePath with the boot
+                          service AllocatePool().  It is the caller's 
+                          responsibility to free DevicePath when the caller
+                          is finished with DevicePath.    
+  Returns:
+  EFI_SUCCESS           - The device path node that describes the SCSI device
+                          specified by Target and Lun was allocated and 
+                          returned in DevicePath.
+  EFI_NOT_FOUND         - The SCSI devices specified by Target and Lun does
+                          not exist on the SCSI channel.
+  EFI_INVALID_PARAMETER - DevicePath is NULL.
+  EFI_OUT_OF_RESOURCES  - There are not enough resources to allocate 
+                          DevicePath.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+AtapiScsiPassThruGetTargetLun (
+  IN  EFI_SCSI_PASS_THRU_PROTOCOL    *This,
+  IN  EFI_DEVICE_PATH_PROTOCOL       *DevicePath,
+  OUT UINT32                         *Target,
+  OUT UINT64                         *Lun
+  )
+/*++
+
+Routine Description:
+
+  Used to translate a device path node to a Target ID and LUN.
+
+Arguments:
+
+  This                  - Protocol instance pointer.
+  DevicePath            - A pointer to the device path node that 
+                          describes a SCSI device on the SCSI channel.
+  Target                - A pointer to the Target ID of a SCSI device 
+                          on the SCSI channel. 
+  Lun                   - A pointer to the LUN of a SCSI device on 
+                          the SCSI channel.    
+Returns:
+
+  EFI_SUCCESS           - DevicePath was successfully translated to a 
+                          Target ID and LUN, and they were returned 
+                          in Target and Lun.
+  EFI_INVALID_PARAMETER - DevicePath/Target/Lun is NULL.
+  EFI_UNSUPPORTED       - This driver does not support the device path 
+                          node type in DevicePath.
+  EFI_NOT_FOUND         - A valid translation from DevicePath to a 
+                          Target ID and LUN does not exist.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+AtapiScsiPassThruResetChannel (
+  IN  EFI_SCSI_PASS_THRU_PROTOCOL   *This
+  )
+/*++
+
+Routine Description:
+
+  Resets a SCSI channel.This operation resets all the 
+  SCSI devices connected to the SCSI channel.
+
+Arguments:
+
+  This                  - Protocol instance pointer.
+
+Returns:
+
+  EFI_SUCCESS           - The SCSI channel was reset.
+  EFI_UNSUPPORTED       - The SCSI channel does not support 
+                          a channel reset operation.
+  EFI_DEVICE_ERROR      - A device error occurred while 
+                          attempting to reset the SCSI channel.
+  EFI_TIMEOUT           - A timeout occurred while attempting 
+                          to reset the SCSI channel.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+AtapiScsiPassThruResetTarget (
+  IN EFI_SCSI_PASS_THRU_PROTOCOL    *This,
+  IN UINT32                         Target,
+  IN UINT64                         Lun
+  )
+/*++
+
+Routine Description:
+
+  Resets a SCSI device that is connected to a SCSI channel.
+
+Arguments:
+
+  This                  - Protocol instance pointer.
+  Target                - The Target ID of the SCSI device to reset. 
+  Lun                   - The LUN of the SCSI device to reset.
+    
+Returns:
+
+  EFI_SUCCESS           - The SCSI device specified by Target and 
+                          Lun was reset.
+  EFI_UNSUPPORTED       - The SCSI channel does not support a target
+                          reset operation.
+  EFI_INVALID_PARAMETER - Target or Lun are invalid.
+  EFI_DEVICE_ERROR      - A device error occurred while attempting 
+                          to reset the SCSI device specified by Target 
+                          and Lun.
+  EFI_TIMEOUT           - A timeout occurred while attempting to reset 
+                          the SCSI device specified by Target and Lun.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+AtapiExtScsiPassThruFunction (
+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL                    *This,
+  IN UINT8                                              *Target,
+  IN UINT64                                             Lun,
+  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET     *Packet,
+  IN EFI_EVENT                                          Event OPTIONAL
+  )
+/*++
+
+Routine Description:
+
+  Implements EFI_EXT_SCSI_PASS_THRU_PROTOCOL.PassThru() function.
+
+Arguments:
+
+  This:     The EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
+  Target:   The Target ID of the ATAPI device to send the SCSI 
+            Request Packet. To ATAPI devices attached on an IDE
+            Channel, Target ID 0 indicates Master device;Target
+            ID 1 indicates Slave device.
+  Lun:      The LUN of the ATAPI device to send the SCSI Request
+            Packet. To the ATAPI device, Lun is always 0.
+  Packet:   The SCSI Request Packet to send to the ATAPI device 
+            specified by Target and Lun.
+  Event:    If non-blocking I/O is not supported then Event is ignored, 
+            and blocking I/O is performed.
+            If Event is NULL, then blocking I/O is performed.
+            If Event is not NULL and non blocking I/O is supported, 
+            then non-blocking I/O is performed, and Event will be signaled 
+            when the SCSI Request Packet completes.      
+
+Returns:  
+
+  EFI_STATUS
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+AtapiExtScsiPassThruGetNextTargetLun (
+  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
+  IN OUT UINT8                           **Target,
+  IN OUT UINT64                          *Lun
+  )
+/*++
+
+Routine Description:
+
+  Used to retrieve the list of legal Target IDs for SCSI devices 
+  on a SCSI channel.
+
+Arguments:
+
+  This                  - Protocol instance pointer.
+  Target                - On input, a pointer to the Target ID of a SCSI 
+                          device present on the SCSI channel.  On output, 
+                          a pointer to the Target ID of the next SCSI device
+                          present on a SCSI channel.  An input value of 
+                          0xFFFFFFFF retrieves the Target ID of the first 
+                          SCSI device present on a SCSI channel.
+  Lun                   - On input, a pointer to the LUN of a SCSI device
+                          present on the SCSI channel. On output, a pointer
+                          to the LUN of the next SCSI device present on 
+                          a SCSI channel.
+Returns:
+
+  EFI_SUCCESS           - The Target ID and Lun of the next SCSI device 
+                          on the SCSI channel was returned in Target and Lun.
+  EFI_NOT_FOUND         - There are no more SCSI devices on this SCSI channel.
+  EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun were not
+                           returned on a previous call to GetNextDevice().
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+AtapiExtScsiPassThruBuildDevicePath (
+  IN     EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
+  IN     UINT8                              *Target,
+  IN     UINT64                             Lun,
+  IN OUT EFI_DEVICE_PATH_PROTOCOL           **DevicePath
+  )
+/*++
+
+Routine Description:
+
+  Used to allocate and build a device path node for a SCSI device 
+  on a SCSI channel. Would not build device path for a SCSI Host Controller.
+
+Arguments:
+
+  This                  - Protocol instance pointer.
+  Target                - The Target ID of the SCSI device for which
+                          a device path node is to be allocated and built.
+  Lun                   - The LUN of the SCSI device for which a device 
+                          path node is to be allocated and built.
+  DevicePath            - A pointer to a single device path node that 
+                          describes the SCSI device specified by 
+                          Target and Lun. This function is responsible 
+                          for allocating the buffer DevicePath with the boot
+                          service AllocatePool().  It is the caller's 
+                          responsibility to free DevicePath when the caller
+                          is finished with DevicePath.    
+  Returns:
+  EFI_SUCCESS           - The device path node that describes the SCSI device
+                          specified by Target and Lun was allocated and 
+                          returned in DevicePath.
+  EFI_NOT_FOUND         - The SCSI devices specified by Target and Lun does
+                          not exist on the SCSI channel.
+  EFI_INVALID_PARAMETER - DevicePath is NULL.
+  EFI_OUT_OF_RESOURCES  - There are not enough resources to allocate 
+                          DevicePath.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+AtapiExtScsiPassThruGetTargetLun (
+  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
+  IN  EFI_DEVICE_PATH_PROTOCOL       *DevicePath,
+  OUT UINT8                          **Target,
+  OUT UINT64                         *Lun
+  )
+/*++
+
+Routine Description:
+
+  Used to translate a device path node to a Target ID and LUN.
+
+Arguments:
+
+  This                  - Protocol instance pointer.
+  DevicePath            - A pointer to the device path node that 
+                          describes a SCSI device on the SCSI channel.
+  Target                - A pointer to the Target ID of a SCSI device 
+                          on the SCSI channel. 
+  Lun                   - A pointer to the LUN of a SCSI device on 
+                          the SCSI channel.    
+Returns:
+
+  EFI_SUCCESS           - DevicePath was successfully translated to a 
+                          Target ID and LUN, and they were returned 
+                          in Target and Lun.
+  EFI_INVALID_PARAMETER - DevicePath/Target/Lun is NULL.
+  EFI_UNSUPPORTED       - This driver does not support the device path 
+                          node type in DevicePath.
+  EFI_NOT_FOUND         - A valid translation from DevicePath to a 
+                          Target ID and LUN does not exist.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+AtapiExtScsiPassThruResetChannel (
+  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL   *This
+  )
+/*++
+
+Routine Description:
+
+  Resets a SCSI channel.This operation resets all the 
+  SCSI devices connected to the SCSI channel.
+
+Arguments:
+
+  This                  - Protocol instance pointer.
+
+Returns:
+
+  EFI_SUCCESS           - The SCSI channel was reset.
+  EFI_UNSUPPORTED       - The SCSI channel does not support 
+                          a channel reset operation.
+  EFI_DEVICE_ERROR      - A device error occurred while 
+                          attempting to reset the SCSI channel.
+  EFI_TIMEOUT           - A timeout occurred while attempting 
+                          to reset the SCSI channel.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+AtapiExtScsiPassThruResetTarget (
+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
+  IN UINT8                              *Target,
+  IN UINT64                             Lun
+  )
+/*++
+
+Routine Description:
+
+  Resets a SCSI device that is connected to a SCSI channel.
+
+Arguments:
+
+  This                  - Protocol instance pointer.
+  Target                - The Target ID of the SCSI device to reset. 
+  Lun                   - The LUN of the SCSI device to reset.
+    
+Returns:
+
+  EFI_SUCCESS           - The SCSI device specified by Target and 
+                          Lun was reset.
+  EFI_UNSUPPORTED       - The SCSI channel does not support a target
+                          reset operation.
+  EFI_INVALID_PARAMETER - Target or Lun are invalid.
+  EFI_DEVICE_ERROR      - A device error occurred while attempting 
+                          to reset the SCSI device specified by Target 
+                          and Lun.
+  EFI_TIMEOUT           - A timeout occurred while attempting to reset 
+                          the SCSI device specified by Target and Lun.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+AtapiExtScsiPassThruGetNextTarget (
+  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
+  IN OUT UINT8                           **Target
+  )
+/*++
+
+Routine Description:
+  Used to retrieve the list of legal Target IDs for SCSI devices 
+  on a SCSI channel.
+
+Arguments:
+  This                  - Protocol instance pointer.
+  Target                - On input, a pointer to the Target ID of a SCSI 
+                          device present on the SCSI channel.  On output, 
+                          a pointer to the Target ID of the next SCSI device
+                           present on a SCSI channel.  An input value of 
+                           0xFFFFFFFF retrieves the Target ID of the first 
+                           SCSI device present on a SCSI channel.
+  Lun                   - On input, a pointer to the LUN of a SCSI device
+                          present on the SCSI channel. On output, a pointer
+                          to the LUN of the next SCSI device present on 
+                          a SCSI channel.
+    
+Returns:
+  EFI_SUCCESS           - The Target ID and Lun of the next SCSI device 
+                          on the SCSI channel was returned in Target and Lun.
+  EFI_NOT_FOUND         - There are no more SCSI devices on this SCSI channel.
+  EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun were not
+                          returned on a previous call to GetNextDevice().
+
+--*/
+;
+
+EFI_STATUS
+CheckSCSIRequestPacket (
+  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET      *Packet
+  )
+/*++
+
+Routine Description:
+
+  Checks the parameters in the SCSI Request Packet to make sure
+  they are valid for a SCSI Pass Thru request.
+
+Arguments:
+
+  Packet         -  The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET   
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+;
+
+EFI_STATUS
+SubmitBlockingIoCommand (
+  ATAPI_SCSI_PASS_THRU_DEV                  *AtapiScsiPrivate,
+  UINT32                                    Target,
+  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET    *Packet
+  )
+/*++
+
+Routine Description:
+
+  Performs blocking I/O request.
+    
+Arguments:
+
+  AtapiScsiPrivate:   Private data structure for the specified channel.
+  Target:             The Target ID of the ATAPI device to send the SCSI 
+                      Request Packet. To ATAPI devices attached on an IDE
+                      Channel, Target ID 0 indicates Master device;Target
+                      ID 1 indicates Slave device.
+  Packet:             The SCSI Request Packet to send to the ATAPI device 
+                      specified by Target.
+  
+  Returns:            EFI_STATUS  
+
+--*/
+;
+
+BOOLEAN
+IsCommandValid (
+  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET   *Packet
+  )
+ /*++
+
+Routine Description:
+
+  Checks the requested SCSI command: 
+  Is it supported by this driver?
+  Is the Data transfer direction reasonable?
+
+Arguments:
+
+  Packet         -  The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET   
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+;
+
+EFI_STATUS
+CheckExtSCSIRequestPacket (
+  EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET      *Packet
+  )
+/*++
+
+Routine Description:
+
+  Checks the parameters in the SCSI Request Packet to make sure
+  they are valid for a SCSI Pass Thru request.
+
+Arguments:
+
+  Packet       - The pointer of EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
+  
+Returns:
+  
+  EFI_STATUS
+
+--*/
+;
+
+
+BOOLEAN
+IsExtCommandValid (
+  EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET   *Packet
+  )
+/*++
+  
+Routine Description:
+
+  Checks the requested SCSI command: 
+  Is it supported by this driver?
+  Is the Data transfer direction reasonable?
+
+Arguments:
+
+  Packet         -  The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET   
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+;
+
+EFI_STATUS
+SubmitExtBlockingIoCommand (
+  ATAPI_SCSI_PASS_THRU_DEV                      *AtapiScsiPrivate,
+  UINT8                                         Target,
+  EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET    *Packet
+  )
+/*++
+
+Routine Description:
+
+  Performs blocking I/O request.
+    
+Arguments:
+
+  AtapiScsiPrivate:   Private data structure for the specified channel.
+  Target:             The Target ID of the ATAPI device to send the SCSI 
+                      Request Packet. To ATAPI devices attached on an IDE
+                      Channel, Target ID 0 indicates Master device;Target
+                      ID 1 indicates Slave device.
+  Packet:             The SCSI Request Packet to send to the ATAPI device 
+                      specified by Target.
+  
+  Returns:            EFI_STATUS  
+  
+--*/
+;
+
+EFI_STATUS
+RequestSenseCommand (
+  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,
+  UINT32                      Target,
+  UINT64                      Timeout,
+  VOID                        *SenseData,
+  UINT8                       *SenseDataLength
+  )
+/*++
+
+Routine Description:
+
+  Submit request sense command
+
+Arguments:
+
+  AtapiScsiPrivate  - The pointer of ATAPI_SCSI_PASS_THRU_DEV
+  Target            - The target ID
+  Timeout           - The time to complete the command
+  SenseData         - The buffer to fill in sense data
+  SenseDataLength   - The length of buffer
+
+Returns:
+
+  EFI_STATUS
+
+--*/
+;
+
+EFI_STATUS
+AtapiPacketCommand (
+  ATAPI_SCSI_PASS_THRU_DEV                  *AtapiScsiPrivate,
+  UINT32                                    Target,
+  UINT8                                     *PacketCommand,
+  VOID                                      *Buffer,
+  UINT32                                    *ByteCount,
+  DATA_DIRECTION                            Direction,
+  UINT64                                    TimeOutInMicroSeconds
+  )
+/*++
+
+Routine Description:
+
+  Submits ATAPI command packet to the specified ATAPI device.
+    
+Arguments:
+
+  AtapiScsiPrivate:   Private data structure for the specified channel.
+  Target:             The Target ID of the ATAPI device to send the SCSI 
+                      Request Packet. To ATAPI devices attached on an IDE
+                      Channel, Target ID 0 indicates Master device;Target
+                      ID 1 indicates Slave device.
+  PacketCommand:      Points to the ATAPI command packet.
+  Buffer:             Points to the transferred data.
+  ByteCount:          When input,indicates the buffer size; when output,
+                      indicates the actually transferred data size.
+  Direction:          Indicates the data transfer direction. 
+  TimeoutInMicroSeconds:
+                      The timeout, in micro second units, to use for the 
+                      execution of this ATAPI command.
+                      A TimeoutInMicroSeconds value of 0 means that 
+                      this function will wait indefinitely for the ATAPI 
+                      command to execute.
+                      If TimeoutInMicroSeconds is greater than zero, then 
+                      this function will return EFI_TIMEOUT if the time 
+                      required to execute the ATAPI command is greater 
+                      than TimeoutInMicroSeconds.
+  
+Returns:
+
+  EFI_STATUS
+
+--*/
+;
+
+
+UINT8
+ReadPortB (
+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
+  IN  UINT16                Port
+  )
+/*++
+
+Routine Description:
+
+  Read one byte from a specified I/O port.
+
+Arguments:
+
+  PciIo      - The pointer of EFI_PCI_IO_PROTOCOL
+  Port       - IO port
+  
+Returns:
+
+  A byte read out
+
+--*/
+;
+
+
+UINT16
+ReadPortW (
+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
+  IN  UINT16                Port
+  )
+/*++
+
+Routine Description:
+
+  Read one word from a specified I/O port.
+
+Arguments:
+
+  PciIo      - The pointer of EFI_PCI_IO_PROTOCOL
+  Port       - IO port
+  
+Returns:     
+
+  A word read out
+
+--*/
+;
+
+
+VOID
+WritePortB (
+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
+  IN  UINT16                Port,
+  IN  UINT8                 Data
+  )
+/*++
+
+Routine Description:
+
+  Write one byte to a specified I/O port.
+
+Arguments:
+
+  PciIo      - The pointer of EFI_PCI_IO_PROTOCOL
+  Port       - IO port
+  Data       - The data to write
+  
+Returns:
+ 
+  NONE
+ 
+--*/
+;
+
+
+VOID
+WritePortW (
+  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
+  IN  UINT16                Port,
+  IN  UINT16                Data
+  )
+/*++
+
+Routine Description:
+
+  Write one word to a specified I/O port.
+
+Arguments:
+
+  PciIo      - The pointer of EFI_PCI_IO_PROTOCOL
+  Port       - IO port
+  Data       - The data to write
+  
+Returns:
+
+  NONE
+  
+--*/
+;
+
+EFI_STATUS
+StatusDRQClear (
+  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,
+  UINT64                          TimeOutInMicroSeconds
+  )
+/*++
+
+Routine Description:
+
+  Check whether DRQ is clear in the Status Register. (BSY must also be cleared)
+  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
+  DRQ clear. Otherwise, it will return EFI_TIMEOUT when specified time is 
+  elapsed.
+
+Arguments:
+
+  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
+  TimeoutInMicroSeconds       - The time to wait for
+   
+Returns:
+
+  EFI_STATUS
+
+--*/
+;
+
+EFI_STATUS
+AltStatusDRQClear (
+  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,
+  UINT64                          TimeOutInMicroSeconds
+  )
+/*++
+
+Routine Description:
+
+  Check whether DRQ is clear in the Alternate Status Register. 
+  (BSY must also be cleared).If TimeoutInMicroSeconds is zero, this routine should 
+  wait infinitely for DRQ clear. Otherwise, it will return EFI_TIMEOUT when specified time is 
+  elapsed.
+
+Arguments:
+
+  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
+  TimeoutInMicroSeconds       - The time to wait for
+   
+Returns:
+
+  EFI_STATUS
+
+--*/
+;
+
+EFI_STATUS
+StatusDRQReady (
+  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,
+  UINT64                          TimeOutInMicroSeconds
+  )
+/*++
+
+Routine Description:
+
+  Check whether DRQ is ready in the Status Register. (BSY must also be cleared)
+  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
+  DRQ ready. Otherwise, it will return EFI_TIMEOUT when specified time is 
+  elapsed.
+
+Arguments:
+
+  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
+  TimeoutInMicroSeconds       - The time to wait for
+   
+Returns:
+
+  EFI_STATUS
+
+--*/
+;
+
+EFI_STATUS
+AltStatusDRQReady (
+  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,
+  UINT64                          TimeOutInMicroSeconds
+  )
+/*++
+
+Routine Description:
+
+  Check whether DRQ is ready in the Alternate Status Register. 
+  (BSY must also be cleared)
+  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
+  DRQ ready. Otherwise, it will return EFI_TIMEOUT when specified time is 
+  elapsed.
+
+Arguments:
+
+  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
+  TimeoutInMicroSeconds       - The time to wait for
+   
+Returns:
+
+  EFI_STATUS
+
+--*/
+;
+
+EFI_STATUS
+StatusWaitForBSYClear (
+  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,
+  UINT64                      TimeoutInMicroSeconds
+  )
+/*++
+
+Routine Description:
+
+  Check whether BSY is clear in the Status Register.
+  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
+  BSY clear. Otherwise, it will return EFI_TIMEOUT when specified time is 
+  elapsed.
+
+Arguments:
+
+  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
+  TimeoutInMicroSeconds       - The time to wait for
+   
+Returns:
+
+  EFI_STATUS
+
+--*/
+;
+
+EFI_STATUS
+AltStatusWaitForBSYClear (
+  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,
+  UINT64                      TimeoutInMicroSeconds
+  )
+/*++
+
+Routine Description:
+
+  Check whether BSY is clear in the Alternate Status Register.
+  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
+  BSY clear. Otherwise, it will return EFI_TIMEOUT when specified time is 
+  elapsed.
+
+Arguments:
+
+  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
+  TimeoutInMicroSeconds       - The time to wait for
+   
+Returns:
+
+  EFI_STATUS
+
+--*/
+;
+
+EFI_STATUS
+StatusDRDYReady (
+  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,
+  UINT64                      TimeoutInMicroSeconds
+  )
+/*++
+
+Routine Description:
+
+  Check whether DRDY is ready in the Status Register. 
+  (BSY must also be cleared)
+  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
+  DRDY ready. Otherwise, it will return EFI_TIMEOUT when specified time is 
+  elapsed.
+
+Arguments:
+
+  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
+  TimeoutInMicroSeconds       - The time to wait for
+   
+Returns:
+
+  EFI_STATUS
+
+--*/
+;
+
+EFI_STATUS
+AltStatusDRDYReady (
+  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,
+  UINT64                      TimeoutInMicroSeconds
+  )
+/*++
+
+Routine Description:
+
+  Check whether DRDY is ready in the Alternate Status Register. 
+  (BSY must also be cleared)
+  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
+  DRDY ready. Otherwise, it will return EFI_TIMEOUT when specified time is 
+  elapsed.
+
+Arguments:
+
+  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
+  TimeoutInMicroSeconds       - The time to wait for
+   
+Returns:
+
+  EFI_STATUS
+
+--*/
+;
+
+EFI_STATUS
+AtapiPassThruPioReadWriteData (
+  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate,
+  UINT16                    *Buffer,
+  UINT32                    *ByteCount,
+  DATA_DIRECTION            Direction,
+  UINT64                    TimeOutInMicroSeconds
+  )
+/*++
+
+Routine Description:
+
+  Performs data transfer between ATAPI device and host after the
+  ATAPI command packet is sent.
+    
+Arguments:
+
+  AtapiScsiPrivate:   Private data structure for the specified channel.    
+  Buffer:             Points to the transferred data.
+  ByteCount:          When input,indicates the buffer size; when output,
+                      indicates the actually transferred data size.
+  Direction:          Indicates the data transfer direction. 
+  TimeoutInMicroSeconds:
+                      The timeout, in micro second units, to use for the 
+                      execution of this ATAPI command.
+                      A TimeoutInMicroSeconds value of 0 means that 
+                      this function will wait indefinitely for the ATAPI 
+                      command to execute.
+                      If TimeoutInMicroSeconds is greater than zero, then 
+                      this function will return EFI_TIMEOUT if the time 
+                      required to execute the ATAPI command is greater 
+                      than TimeoutInMicroSeconds.
+ Returns:
+
+  EFI_STATUS
+
+--*/
+;
+
+EFI_STATUS
+AtapiPassThruCheckErrorStatus (
+  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate
+  )
+/*++
+
+Routine Description:
+
+  Check Error Register for Error Information. 
+  
+Arguments:
+
+  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
+   
+Returns:
+
+  EFI_STATUS
+
+--*/
+;
+
+
+EFI_STATUS
+GetIdeRegistersBaseAddr (
+  IN  EFI_PCI_IO_PROTOCOL         *PciIo,
+  OUT IDE_REGISTERS_BASE_ADDR     *IdeRegsBaseAddr
+  )
+/*++
+
+Routine Description:
+  Get IDE IO port registers' base addresses by mode. In 'Compatibility' mode,
+  use fixed addresses. In Native-PCI mode, get base addresses from BARs in
+  the PCI IDE controller's Configuration Space.
+
+Arguments:
+  PciIo             - Pointer to the EFI_PCI_IO_PROTOCOL instance
+  IdeRegsBaseAddr   - Pointer to IDE_REGISTERS_BASE_ADDR to 
+                      receive IDE IO port registers' base addresses
+                      
+Returns:
+
+  EFI_STATUS
+    
+--*/
+;
+
+
+VOID
+InitAtapiIoPortRegisters (
+  IN  ATAPI_SCSI_PASS_THRU_DEV     *AtapiScsiPrivate,
+  IN  IDE_REGISTERS_BASE_ADDR      *IdeRegsBaseAddr
+  )
+/*++
+
+Routine Description:
+
+  Initialize each Channel's Base Address of CommandBlock and ControlBlock.
+
+Arguments:
+    
+  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
+  IdeRegsBaseAddr             - The pointer of IDE_REGISTERS_BASE_ADDR
+  
+Returns:
+  
+  None
+
+--*/  
+;
+
+/**
+  Installs Scsi Pass Thru and/or Ext Scsi Pass Thru 
+  protocols based on feature flags. 
+
+  @param Controller         The controller handle to 
+                            install these protocols on.
+  @param AtapiScsiPrivate   A pointer to the protocol private
+                            data structure.
+
+  @retval EFI_SUCCESS       The installation succeeds. 
+  @retval other             The installation fails. 
+   
+**/
+EFI_STATUS
+InstallScsiPassThruProtocols (
+  IN EFI_HANDLE                 *ControllerHandle,
+  IN ATAPI_SCSI_PASS_THRU_DEV   *AtapiScsiPrivate
+  );
+
+#endif
diff --git a/Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThruDxe.inf b/Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThruDxe.inf
new file mode 100644
index 0000000000..750136275a
--- /dev/null
+++ b/Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThruDxe.inf
@@ -0,0 +1,70 @@
+## @file
+# Description file for the Atapi Pass Thru driver.
+#
+# This driver simulates SCSI devices with Atapi devices to test the SCSI io
+#  protocol.
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = AtapiPassThruDxe
+  FILE_GUID                      = E49061CE-99A7-41d3-AB3A-36E5CFBAD63E
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = InitializeAtapiPassThru
+
+  PCI_VENDOR_ID                  = 0x8086
+  PCI_DEVICE_ID                  = 0x2921
+  PCI_CLASS_CODE                 = 0x010100
+  PCI_REVISION                   = 0x0003
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+#  DRIVER_BINDING                =  gAtapiScsiPassThruDriverBinding              
+#  COMPONENT_NAME                =  gAtapiScsiPassThruComponentName              
+#
+
+[Sources]
+  DriverSupportedEfiVersion.c
+  ComponentName.c
+  AtapiPassThru.c
+  AtapiPassThru.h
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OptionRomPkg/OptionRomPkg.dec
+
+[LibraryClasses]
+  UefiBootServicesTableLib
+  MemoryAllocationLib
+  BaseMemoryLib
+  UefiLib
+  BaseLib
+  UefiDriverEntryPoint
+  DebugLib
+  DevicePathLib
+
+
+[Protocols]
+  gEfiScsiPassThruProtocolGuid                  # PROTOCOL BY_START
+  gEfiExtScsiPassThruProtocolGuid               # PROTOCOL BY_START
+  gEfiPciIoProtocolGuid                         # PROTOCOL TO_START
+  gEfiDriverSupportedEfiVersionProtocolGuid     # PROTOCOL ALWAYS_PRODUCED
+
+[FeaturePcd]
+  gOptionRomPkgTokenSpaceGuid.PcdSupportScsiPassThru
+  gOptionRomPkgTokenSpaceGuid.PcdSupportExtScsiPassThru
+
+[Pcd]
+  gOptionRomPkgTokenSpaceGuid.PcdDriverSupportedEfiVersion
+
diff --git a/Drivers/OptionRomPkg/AtapiPassThruDxe/ComponentName.c b/Drivers/OptionRomPkg/AtapiPassThruDxe/ComponentName.c
new file mode 100644
index 0000000000..007cb5f195
--- /dev/null
+++ b/Drivers/OptionRomPkg/AtapiPassThruDxe/ComponentName.c
@@ -0,0 +1,169 @@
+/** @file
+  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  Module Name:  ComponentName.c
+
+**/
+#include "AtapiPassThru.h"
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gAtapiScsiPassThruComponentName = {
+  AtapiScsiPassThruComponentNameGetDriverName,
+  AtapiScsiPassThruComponentNameGetControllerName,
+  "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gAtapiScsiPassThruComponentName2 = {
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) AtapiScsiPassThruComponentNameGetDriverName,
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) AtapiScsiPassThruComponentNameGetControllerName,
+  "en"
+};
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mAtapiScsiPassThruDriverNameTable[] = {
+  { "eng;en", (CHAR16 *) L"ATAPI SCSI Pass Thru Driver" },
+  { NULL , NULL }
+};
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 4646 or ISO 639-2 language code format.
+
+  @param  DriverName[out]       A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+AtapiScsiPassThruComponentNameGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **DriverName
+  )
+{
+  return LookupUnicodeString2 (
+           Language,
+           This->SupportedLanguages,
+           mAtapiScsiPassThruDriverNameTable,
+           DriverName,
+           (BOOLEAN)(This == &gAtapiScsiPassThruComponentName)
+           );
+}
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  ControllerHandle[in]  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+
+  @param  ChildHandle[in]       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 4646 or ISO 639-2 language code format.
+
+  @param  ControllerName[out]   A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                controller specified by ControllerHandle and
+                                ChildHandle in the language specified by
+                                Language from the point of view of the driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+
+  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+AtapiScsiPassThruComponentNameGetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
+  IN  EFI_HANDLE                                      ControllerHandle,
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
+  IN  CHAR8                                           *Language,
+  OUT CHAR16                                          **ControllerName
+  )
+{
+  return EFI_UNSUPPORTED;
+}
diff --git a/Drivers/OptionRomPkg/AtapiPassThruDxe/DriverSupportedEfiVersion.c b/Drivers/OptionRomPkg/AtapiPassThruDxe/DriverSupportedEfiVersion.c
new file mode 100644
index 0000000000..84a9badad2
--- /dev/null
+++ b/Drivers/OptionRomPkg/AtapiPassThruDxe/DriverSupportedEfiVersion.c
@@ -0,0 +1,14 @@
+/** @file
+  Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  Module Name:  DriverSupportEfiVersion.c
+
+**/
+#include "AtapiPassThru.h"
+
+EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL gAtapiScsiPassThruDriverSupportedEfiVersion = {
+  sizeof (EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL), // Size of Protocol structure.
+  0                                                   // Version number to be filled at start up.
+};
+
diff --git a/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/CompatibleDevices.txt b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/CompatibleDevices.txt
new file mode 100644
index 0000000000..1ec1cce0d1
--- /dev/null
+++ b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/CompatibleDevices.txt
@@ -0,0 +1,5 @@
+The following devices have been confirmed to work with the USB Serial Driver:
+
+Brand        Model Name        Product Name          Vendor ID    Device ID
+Gearmo       USA_FTDI-36       USB to RS-232         0x0403       0x6001
+Sabrent      CB-FTDI                                 0x0403       0x6001
\ No newline at end of file
diff --git a/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ComponentName.c b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ComponentName.c
new file mode 100644
index 0000000000..d15abf5090
--- /dev/null
+++ b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ComponentName.c
@@ -0,0 +1,218 @@
+/** @file
+  UEFI Component Name(2) protocol implementation for USB Serial driver.
+
+Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "FtdiUsbSerialDriver.h"
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gUsbSerialComponentName = {
+  (EFI_COMPONENT_NAME_GET_DRIVER_NAME) UsbSerialComponentNameGetDriverName,
+  (EFI_COMPONENT_NAME_GET_CONTROLLER_NAME) UsbSerialComponentNameGetControllerName,
+  "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gUsbSerialComponentName2 = {
+  UsbSerialComponentNameGetDriverName,
+  UsbSerialComponentNameGetControllerName,
+  "en"
+};
+
+//
+// Driver name string table
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUsbSerialDriverNameTable[] = {
+  { "eng;en", L"FTDI-232 USB Serial Driver" },
+  { NULL , NULL }
+};
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param  This                  A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+  @param  Language              A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 4646 or ISO 639-2 language code format.
+  @param  DriverName            A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbSerialComponentNameGetDriverName (
+  IN  EFI_COMPONENT_NAME2_PROTOCOL  *This,
+  IN  CHAR8                         *Language,
+  OUT CHAR16                        **DriverName
+  )
+{
+  return LookupUnicodeString2 (
+           Language,
+           This->SupportedLanguages,
+           mUsbSerialDriverNameTable,
+           DriverName,
+           (BOOLEAN)(This == &gUsbSerialComponentName2)
+           );
+}
+
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param  This                  A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+  @param  ControllerHandle      The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+  @param  ChildHandle           The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+  @param  Language              A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 4646 or ISO 639-2 language code format.
+  @param  ControllerName        A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                controller specified by ControllerHandle and
+                                ChildHandle in the language specified by
+                                Language from the point of view of the driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbSerialComponentNameGetControllerName (
+  IN  EFI_COMPONENT_NAME2_PROTOCOL  *This,
+  IN  EFI_HANDLE                    ControllerHandle,
+  IN  EFI_HANDLE                    ChildHandle      OPTIONAL,
+  IN  CHAR8                         *Language,
+  OUT CHAR16                        **ControllerName
+  )
+{
+  EFI_STATUS              Status;
+  USB_SER_DEV             *UsbSerDev;
+  EFI_SERIAL_IO_PROTOCOL  *SerialIo;
+  EFI_USB_IO_PROTOCOL     *UsbIoProtocol;
+  
+  //
+  // This is a device driver, so ChildHandle must be NULL.
+  //
+  if (ChildHandle != NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Check Controller's handle
+  //
+  Status = gBS->OpenProtocol (
+                  ControllerHandle,
+                  &gEfiUsbIoProtocolGuid,
+                  (VOID **) &UsbIoProtocol,
+                  gUsbSerialDriverBinding.DriverBindingHandle,
+                  ControllerHandle,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (!EFI_ERROR (Status)) {
+    gBS->CloseProtocol (
+           ControllerHandle,
+           &gEfiUsbIoProtocolGuid,
+           gUsbSerialDriverBinding.DriverBindingHandle,
+           ControllerHandle
+           );
+
+    return EFI_UNSUPPORTED;
+  }
+
+  if (Status != EFI_ALREADY_STARTED) {
+    return EFI_UNSUPPORTED;
+  }
+  //
+  // Get the device context
+  //
+  Status = gBS->OpenProtocol (
+                  ControllerHandle,
+                  &gEfiSerialIoProtocolGuid,
+                  (VOID **) &SerialIo,
+                  gUsbSerialDriverBinding.DriverBindingHandle,
+                  ControllerHandle,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  UsbSerDev = USB_SER_DEV_FROM_THIS (SerialIo);
+
+  return LookupUnicodeString2 (
+           Language,
+           This->SupportedLanguages,
+           UsbSerDev->ControllerNameTable,
+           ControllerName,
+           (BOOLEAN)(This == &gUsbSerialComponentName2)
+           );
+}
diff --git a/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.c b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.c
new file mode 100644
index 0000000000..ac09fae014
--- /dev/null
+++ b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.c
@@ -0,0 +1,2580 @@
+/** @file
+  USB Serial Driver that manages USB to Serial and produces Serial IO Protocol.
+
+Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.
+Portions Copyright 2012 Ashley DeSimone
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+
+// Tested with VEND_ID 0x0403, DEVICE_ID 0x6001
+//
+// Driver starts the device with the following values:
+// 115200, No parity, 8 data bits, 1 stop bit, No Flow control
+//
+
+#include "FtdiUsbSerialDriver.h"
+
+//
+// Table of supported devices. This is the device information that this
+// driver was developed with. Add other FTDI devices as needed.
+//
+USB_DEVICE gUSBDeviceList[] = {
+  {VID_FTDI, DID_FTDI_FT232},
+  {0,0}
+};
+
+//
+// USB Serial Driver Global Variables
+//
+EFI_DRIVER_BINDING_PROTOCOL  gUsbSerialDriverBinding = {
+  UsbSerialDriverBindingSupported,
+  UsbSerialDriverBindingStart,
+  UsbSerialDriverBindingStop,
+  0xa,
+  NULL,
+  NULL
+};
+
+//
+// Table with the nearest power of 2 for the numbers 0-15
+//
+UINT8 gRoundedPowersOf2[16] = { 0, 2, 2, 4, 4, 4, 8, 8, 8, 8, 8, 8, 16, 16, 16, 16 };
+
+/**
+  Check to see if the device path node is the Flow control node
+
+  @param[in] FlowControl    The device path node to be checked
+
+  @retval    TRUE           It is the flow control node
+  @retval    FALSE          It is not the flow control node
+
+**/
+BOOLEAN
+IsUartFlowControlNode (
+  IN UART_FLOW_CONTROL_DEVICE_PATH *FlowControl
+  )
+{
+  return (BOOLEAN) (
+           (DevicePathType (FlowControl) == MESSAGING_DEVICE_PATH) &&
+           (DevicePathSubType (FlowControl) == MSG_VENDOR_DP) &&
+           (CompareGuid (&FlowControl->Guid, &gEfiUartDevicePathGuid))
+           );
+}
+
+/**
+  Checks the device path to see if it contains flow control.
+
+  @param[in] DevicePath    The device path to be checked
+
+  @retval    TRUE          It contains flow control
+  @retval    FALSE         It does not contain flow control
+
+**/
+BOOLEAN
+ContainsFlowControl (
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  )
+{
+  while (!IsDevicePathEnd (DevicePath)) {
+    if (IsUartFlowControlNode ((UART_FLOW_CONTROL_DEVICE_PATH *) DevicePath)) {
+      return TRUE;
+    }
+    DevicePath = NextDevicePathNode (DevicePath);
+  }
+  return FALSE;
+}
+
+/**
+  Transfer the data between the device and host.
+
+  This function transfers the data between the device and host.
+  BOT transfer is composed of three phases: Command, Data, and Status.
+  This is the Data phase.
+
+  @param  UsbBot[in]                     The USB BOT device
+  @param  DataDir[in]                    The direction of the data
+  @param  Data[in, out]                  The buffer to hold data
+  @param  TransLen[in, out]              The expected length of the data
+  @param  Timeout[in]                    The time to wait the command to complete
+
+  @retval EFI_SUCCESS                    The data is transferred
+  @retval EFI_SUCCESS                    No data to transfer
+  @retval EFI_NOT_READY                  The device return NAK to the transfer
+  @retval Others                         Failed to transfer data
+
+**/
+EFI_STATUS
+UsbSerialDataTransfer (
+  IN USB_SER_DEV             *UsbBot,
+  IN EFI_USB_DATA_DIRECTION  DataDir,
+  IN OUT VOID                *Data,
+  IN OUT UINTN               *TransLen,
+  IN UINT32                  Timeout
+  )
+{
+  EFI_USB_ENDPOINT_DESCRIPTOR  *Endpoint;
+  EFI_STATUS                   Status;
+  UINT32                       Result;
+
+  //
+  // If no data to transfer, just return EFI_SUCCESS.
+  //
+  if ((DataDir == EfiUsbNoData) || (*TransLen == 0)) {
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Select the endpoint then issue the transfer
+  //
+  if (DataDir == EfiUsbDataIn) {
+    Endpoint = &UsbBot->InEndpointDescriptor;
+  } else {
+    Endpoint = &UsbBot->OutEndpointDescriptor;
+  }
+
+  Result = 0;
+  Status = UsbBot->UsbIo->UsbBulkTransfer (
+                            UsbBot->UsbIo,
+                            Endpoint->EndpointAddress,
+                            Data,
+                            TransLen,
+                            Timeout,
+                            &Result
+                            );
+  if (EFI_ERROR (Status)) {
+    if (USB_IS_ERROR (Result, EFI_USB_ERR_NAK)) {
+      Status = EFI_NOT_READY;
+    } else {
+      UsbBot->Shutdown = TRUE; // Fixes infinite loop in older EFI
+    }
+    return Status;
+  }
+  return Status;
+}
+
+/**
+  Sets the status values of the Usb Serial Device.
+
+  @param  UsbSerialDevice[in]  Handle to the Usb Serial Device to set the status
+                               for
+  @param  StatusBuffer[in]     Buffer holding the status values
+
+  @retval EFI_SUCCESS          The status values were read and set correctly
+
+**/
+EFI_STATUS
+EFIAPI
+SetStatusInternal (
+  IN USB_SER_DEV  *UsbSerialDevice,
+  IN UINT8        *StatusBuffer
+  )
+{
+  UINT8  Msr;
+
+  Msr = (StatusBuffer[0] & MSR_MASK);
+
+  //
+  // set the Status values to disabled
+  //
+  UsbSerialDevice->StatusValues.CtsState = FALSE;
+  UsbSerialDevice->StatusValues.DsrState = FALSE;
+  UsbSerialDevice->StatusValues.RiState  = FALSE;
+  UsbSerialDevice->StatusValues.SdState  = FALSE;
+
+  //
+  // Check the values from the status buffer and set the appropriate status
+  // values to enabled
+  //
+  if ((Msr & CTS_MASK) == CTS_MASK) {
+    UsbSerialDevice->StatusValues.CtsState = TRUE;
+  }
+  if ((Msr & DSR_MASK) == DSR_MASK) {
+    UsbSerialDevice->StatusValues.DsrState = TRUE;
+  }
+  if ((Msr & RI_MASK) == RI_MASK) {
+    UsbSerialDevice->StatusValues.RiState = TRUE;
+  }
+  if ((Msr & SD_MASK) == SD_MASK) {
+    UsbSerialDevice->StatusValues.SdState = TRUE;
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  Initiates a read operation on the Usb Serial Device.
+
+  @param  UsbSerialDevice[in]        Handle to the USB device to read
+  @param  BufferSize[in, out]        On input, the size of the Buffer. On output,
+                                     the amount of data returned in Buffer.
+                                     Setting this to zero will initiate a read
+                                     and store all data returned in the internal
+                                     buffer.
+  @param  Buffer [out]               The buffer to return the data into.
+
+  @retval EFI_SUCCESS                The data was read.
+  @retval EFI_DEVICE_ERROR           The device reported an error.
+  @retval EFI_TIMEOUT                The data write was stopped due to a timeout.
+
+**/
+EFI_STATUS
+EFIAPI
+ReadDataFromUsb (
+  IN USB_SER_DEV  *UsbSerialDevice,
+  IN OUT UINTN    *BufferSize,
+  OUT VOID        *Buffer
+  )
+{
+  EFI_STATUS  Status;
+  UINTN       ReadBufferSize;
+  UINT8       *ReadBuffer;
+  UINTN       Index;
+  EFI_TPL     Tpl;
+  UINT8       StatusBuffer[2]; // buffer to store the status bytes
+
+  ReadBufferSize = 512;
+  ReadBuffer     = &(UsbSerialDevice->ReadBuffer[0]);
+
+  if (UsbSerialDevice->Shutdown) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  Tpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+  Status = UsbSerialDataTransfer (
+             UsbSerialDevice,
+             EfiUsbDataIn,
+             ReadBuffer,
+             &ReadBufferSize,
+             FTDI_TIMEOUT*2  //Padded because timers won't be exactly aligned
+             );
+  if (EFI_ERROR (Status)) {
+    gBS->RestoreTPL (Tpl);
+    if (Status == EFI_TIMEOUT) {
+      return EFI_TIMEOUT;
+    } else {
+      return EFI_DEVICE_ERROR;
+    }
+  }
+
+  //
+  // Store the status bytes in the status buffer
+  //
+  for (Index = 0; Index < 2; Index++) {//only the first 2 bytes are status bytes
+    StatusBuffer[Index] = ReadBuffer[Index];
+  }
+  //
+  // update the statusvalue field of the usbserialdevice
+  //
+  Status = SetStatusInternal (UsbSerialDevice, StatusBuffer);
+  if (Status != EFI_SUCCESS) {
+  }
+
+  //
+  // Store the read data in the read buffer, start at 2 to ignore status bytes
+  //
+  for (Index = 2; Index < ReadBufferSize; Index++) {
+    if (((UsbSerialDevice->DataBufferTail + 1) % SW_FIFO_DEPTH) == UsbSerialDevice->DataBufferHead) {
+      break;
+    }
+    if (ReadBuffer[Index] == 0x00) {
+      //
+      // This is null, do not add
+      //
+    } else {
+      UsbSerialDevice->DataBuffer[UsbSerialDevice->DataBufferTail] = ReadBuffer[Index];
+      UsbSerialDevice->DataBufferTail = (UsbSerialDevice->DataBufferTail + 1) % SW_FIFO_DEPTH;
+    }
+  }
+
+  //
+  // Read characters out of the buffer to satisfy caller's request.
+  //
+  for (Index = 0; Index < *BufferSize; Index++) {
+    if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {
+      break;
+    }
+    //
+    // Still have characters in the buffer to return
+    //
+    ((UINT8 *)Buffer)[Index]        = UsbSerialDevice->DataBuffer[UsbSerialDevice->DataBufferHead];
+    UsbSerialDevice->DataBufferHead = (UsbSerialDevice->DataBufferHead + 1) % SW_FIFO_DEPTH;
+  }
+  //
+  // Return actual number of bytes returned.
+  //
+  *BufferSize = Index;
+  gBS->RestoreTPL (Tpl);
+  return EFI_SUCCESS;
+}
+
+/**
+  Sets the initial status values of the Usb Serial Device by reading the status
+  bytes from the device.
+
+  @param  UsbSerialDevice[in]  Handle to the Usb Serial Device that needs its
+                               initial status values set
+
+  @retval EFI_SUCCESS          The status bytes were read successfully and the
+                               initial status values were set correctly
+  @retval EFI_TIMEOUT          The read of the status bytes was stopped due to a
+                               timeout
+  @retval EFI_DEVICE_ERROR     The device reported an error during the read of
+                               the status bytes
+
+**/
+EFI_STATUS
+EFIAPI
+SetInitialStatus (
+  IN USB_SER_DEV          *UsbSerialDevice
+  )
+{
+  EFI_STATUS      Status;
+  UINTN           BufferSize;
+  EFI_TPL         Tpl;
+  UINT8           StatusBuffer[2];
+
+  Status          = EFI_UNSUPPORTED;
+  BufferSize      = sizeof (StatusBuffer);
+
+  if (UsbSerialDevice->Shutdown) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  Tpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+  Status = UsbSerialDataTransfer (
+             UsbSerialDevice,
+             EfiUsbDataIn,
+             StatusBuffer,
+             &BufferSize,
+             40    //Slightly more than 2x the FTDI polling frequency to make sure that data will be returned
+             );
+
+  Status = SetStatusInternal (UsbSerialDevice, StatusBuffer);
+
+  gBS->RestoreTPL (Tpl);
+
+  return Status;
+}
+
+/**
+  UsbSerialDriverCheckInput.
+  attempts to read data in from the device periodically, stores any read data
+  and updates the control attributes.
+
+  @param  Event[in]
+  @param  Context[in]....The current instance of the USB serial device
+
+**/
+VOID
+EFIAPI
+UsbSerialDriverCheckInput (
+  IN  EFI_EVENT  Event,
+  IN  VOID       *Context
+  )
+{
+  UINTN        BufferSize;
+  USB_SER_DEV  *UsbSerialDevice;
+
+  UsbSerialDevice = (USB_SER_DEV*)Context;
+
+  if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {
+    //
+    // Data buffer is empty, try to read from device
+    //
+    BufferSize = 0;
+    ReadDataFromUsb (UsbSerialDevice, &BufferSize, NULL);
+    if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {
+      //
+      // Data buffer still has no data, set the EFI_SERIAL_INPUT_BUFFER_EMPTY
+      // flag
+      //
+      UsbSerialDevice->ControlBits |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
+    } else {
+      //
+      // Read has returned some data, clear the EFI_SERIAL_INPUT_BUFFER_EMPTY
+      // flag
+      //
+      UsbSerialDevice->ControlBits &= ~(EFI_SERIAL_INPUT_BUFFER_EMPTY);
+    }
+  } else {
+    //
+    // Data buffer has data, no read attempt required
+    //
+    UsbSerialDevice->ControlBits &= ~(EFI_SERIAL_INPUT_BUFFER_EMPTY);
+  }
+}
+
+/**
+  Encodes the baud rate into the format expected by the Ftdi device.
+
+  @param  BaudRate[in]                The baudrate to be set on the device
+  @param  EncodedBaudRate[out]        The baud rate encoded in the format
+                                      expected by the Ftdi device
+
+  @return EFI_SUCCESS                 Baudrate encoding was calculated
+                                      successfully
+  @return EFI_INVALID_PARAMETER       An invalid value of BaudRate was received
+
+**/
+EFI_STATUS
+EFIAPI
+EncodeBaudRateForFtdi (
+  IN  UINT64  BaudRate,
+  OUT UINT16  *EncodedBaudRate
+  )
+{
+  UINT32 Divisor;
+  UINT32 AdjustedFrequency;
+  UINT16 Result;
+
+  //
+  // Check to make sure we won't get an integer overflow
+  //
+  if ((BaudRate < 178) || ( BaudRate > ((FTDI_UART_FREQUENCY * 100) / 97))) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Baud Rates of 2000000 and 3000000 are special cases
+  //
+  if ((BaudRate >= FTDI_SPECIAL_CASE_300_MIN) && (BaudRate <= FTDI_SPECIAL_CASE_300_MAX)) {
+    *EncodedBaudRate = 0;
+    return EFI_SUCCESS;
+  }
+  if ((BaudRate >= FTDI_SPECIAL_CASE_200_MIN) && (BaudRate <= FTDI_SPECIAL_CASE_200_MAX)) {
+    *EncodedBaudRate = 1;
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Compute divisor
+  //
+  Divisor = (FTDI_UART_FREQUENCY << 4) / (UINT32)BaudRate;
+
+  //
+  // Round the last 4 bits to the nearest power of 2
+  //
+  Divisor = (Divisor & ~(0xF)) + (gRoundedPowersOf2[Divisor & 0xF]);
+
+  //
+  // Check to make sure computed divisor is within 
+  // the min and max that FTDI controller will accept
+  //
+  if (Divisor < FTDI_MIN_DIVISOR) {
+    Divisor = FTDI_MIN_DIVISOR;
+  } else if (Divisor > FTDI_MAX_DIVISOR) {
+    Divisor = FTDI_MAX_DIVISOR;
+  }
+
+  //
+  // Check to make sure the frequency that the FTDI chip will need to
+  // generate to attain the requested Baud Rate is within 3% of the
+  // 3MHz clock frequency that the FTDI chip runs at.
+  //
+  // (3MHz * 1600) / 103 = 46601941
+  // (3MHz * 1600) / 97  = 49484536
+  //
+  AdjustedFrequency = (((UINT32)BaudRate) * Divisor);
+  if ((AdjustedFrequency < FTDI_MIN_FREQUENCY) || (AdjustedFrequency > FTDI_MAX_FREQUENCY)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Encode the Divisor into the format FTDI expects
+  //
+  Result = (UINT16)(Divisor >> 4);
+  if ((Divisor & 0x8) != 0) {
+    Result |= 0x4000;
+  } else if ((Divisor & 0x4) != 0) {
+    Result |= 0x8000;
+  } else if ((Divisor & 0x2) != 0) {
+    Result |= 0xC000;
+  }
+
+  *EncodedBaudRate = Result;
+  return EFI_SUCCESS;
+}
+
+/**
+  Uses USB I/O to check whether the device is a USB Serial device.
+
+  @param  UsbIo[in]    Pointer to a USB I/O protocol instance.
+
+  @retval TRUE         Device is a USB Serial device.
+  @retval FALSE        Device is a not USB Serial device.
+
+**/
+BOOLEAN
+IsUsbSerial (
+  IN  EFI_USB_IO_PROTOCOL  *UsbIo
+  )
+{
+  EFI_STATUS                 Status;
+  EFI_USB_DEVICE_DESCRIPTOR  DeviceDescriptor;
+  CHAR16                     *StrMfg;
+  BOOLEAN                    Found;
+  UINT32                     Index;
+
+  //
+  // Get the default device descriptor
+  //
+  Status = UsbIo->UsbGetDeviceDescriptor (
+                    UsbIo,
+                    &DeviceDescriptor
+                    );
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+
+  Found = FALSE;
+  Index = 0;
+  while (gUSBDeviceList[Index].VendorId != 0 &&
+         gUSBDeviceList[Index].DeviceId != 0 &&
+         !Found                                  ) {
+    if (DeviceDescriptor.IdProduct == gUSBDeviceList[Index].DeviceId &&
+        DeviceDescriptor.IdVendor  == gUSBDeviceList[Index].VendorId      ){
+        //
+        // Checks to see if a string descriptor can be pulled from the device in
+        // the selected language. If not False is returned indicating that this
+        // is not a Usb Serial Device that can be managegd by this driver
+        //
+        StrMfg = NULL;
+        Status = UsbIo->UsbGetStringDescriptor (
+                          UsbIo,
+                          USB_US_LANG_ID, // LANGID selector, should make this
+                                          // more robust to verify lang support
+                                          // for device
+                          DeviceDescriptor.StrManufacturer,
+                          &StrMfg
+                          );
+        if (StrMfg != NULL) {
+          FreePool (StrMfg);
+        }
+        if (EFI_ERROR (Status)) {
+          return FALSE;
+        }
+        return TRUE;
+    }
+    Index++;
+  }
+  return FALSE;
+}
+
+/**
+  Internal function that sets the Data Bits, Stop Bits and Parity values on the
+  Usb Serial Device with a single usb control transfer.
+
+  @param  UsbIo[in]                  Usb Io Protocol instance pointer
+  @param  DataBits[in]               The data bits value to be set on the Usb
+                                     Serial Device
+  @param  Parity[in]                 The parity type that will be set on the Usb
+                                     Serial Device
+  @param  StopBits[in]               The stop bits type that will be set on the
+                                     Usb Serial Device
+  @param  LastSettings[in]           A pointer to the Usb Serial Device's
+                                     PREVIOUS_ATTRIBUTES item
+
+  @retval EFI_SUCCESS                The data items were correctly set on the
+                                     USB Serial Device
+  @retval EFI_INVALID_PARAMETER      An invalid data parameter or an invalid
+                                     combination or parameters was used
+  @retval EFI_DEVICE_ERROR           The device is not functioning correctly and
+                                     the data values were unable to be set
+
+**/
+EFI_STATUS
+EFIAPI
+SetDataInternal (
+  IN EFI_USB_IO_PROTOCOL  *UsbIo,
+  IN UINT8                DataBits,
+  IN EFI_PARITY_TYPE      Parity,
+  IN EFI_STOP_BITS_TYPE   StopBits,
+  IN PREVIOUS_ATTRIBUTES  *LastSettings
+  )
+{
+  EFI_STATUS              Status;
+  EFI_USB_DEVICE_REQUEST  DevReq;
+  UINT32                  ReturnValue;
+  UINT8                   ConfigurationValue;
+
+  //
+  // Since data bits settings of 6,7,8 cannot be set with a stop bits setting of
+  // 1.5 check to see if this happens when the values of last settings are used
+  //
+  if ((DataBits == 0) && (StopBits == OneFiveStopBits)) {
+    if ((LastSettings->DataBits == 6) || (LastSettings->DataBits == 7) || (LastSettings->DataBits == 8)) {
+      return EFI_INVALID_PARAMETER;
+    }
+  } else if ((StopBits == DefaultStopBits) && ((DataBits == 6) || (DataBits == 7) || (DataBits == 8))) {
+    if (LastSettings->StopBits == OneFiveStopBits) {
+      return EFI_INVALID_PARAMETER;
+    }
+  } else if ((DataBits == 0) && (StopBits == DefaultStopBits)) {
+    if (LastSettings->StopBits == OneFiveStopBits) {
+      if ((LastSettings->DataBits == 6) || (LastSettings->DataBits == 7) || (LastSettings->DataBits == 8)) {
+        return EFI_INVALID_PARAMETER;
+      }
+    }
+  }
+
+  //
+  // set the DevReq.Value for the usb control transfer to the correct value
+  // based on the seleceted number of data bits if there is an invalid number of
+  // data bits requested return EFI_INVALID_PARAMETER
+  //
+  if (((DataBits < 5 ) || (DataBits > 8)) && (DataBits != 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+  if (DataBits == 0) {
+    //
+    // use the value of LastDataBits
+    //
+    DevReq.Value = SET_DATA_BITS (LastSettings->DataBits);
+  } else {
+    //
+    // use the value of DataBits
+    //
+    DevReq.Value = SET_DATA_BITS (DataBits);
+  }
+
+  //
+  // Set Parity
+  //
+  if (Parity == DefaultParity) {
+    Parity = LastSettings->Parity;
+  }
+
+  if (Parity == NoParity) {
+    DevReq.Value |= SET_PARITY_NONE;
+  } else if (Parity == EvenParity) {
+    DevReq.Value |= SET_PARITY_EVEN;
+  } else if (Parity == OddParity){
+    DevReq.Value |= SET_PARITY_ODD;
+  } else if (Parity == MarkParity) {
+    DevReq.Value |= SET_PARITY_MARK;
+  } else if (Parity == SpaceParity) {
+    DevReq.Value |= SET_PARITY_SPACE;
+  }
+
+  //
+  // Set Stop Bits
+  //
+  if (StopBits == DefaultStopBits) {
+    StopBits = LastSettings->StopBits;
+  }
+
+  if (StopBits == OneStopBit) {
+    DevReq.Value |= SET_STOP_BITS_1;
+  } else if (StopBits == OneFiveStopBits) {
+    DevReq.Value |= SET_STOP_BITS_15;
+  } else if (StopBits == TwoStopBits) {
+    DevReq.Value |= SET_STOP_BITS_2;
+  }
+
+  //
+  // set the rest of the DevReq parameters and perform the usb control transfer
+  // to set the data bits on the device
+  //
+  DevReq.Request     = FTDI_COMMAND_SET_DATA;
+  DevReq.RequestType = USB_REQ_TYPE_VENDOR;
+  DevReq.Index       = FTDI_PORT_IDENTIFIER;
+  DevReq.Length      = 0; // indicates that there is no data phase in this request
+
+  Status = UsbIo->UsbControlTransfer (
+                    UsbIo,
+                    &DevReq,
+                    EfiUsbDataOut,
+                    WDR_SHORT_TIMEOUT,
+                    &ConfigurationValue,
+                    1,
+                    &ReturnValue
+                    );
+  if (EFI_ERROR (Status)) {
+    goto StatusError;
+  }
+  return Status;
+
+StatusError:
+  if ((Status != EFI_INVALID_PARAMETER) || (Status != EFI_DEVICE_ERROR)) {
+    return EFI_DEVICE_ERROR;
+  } else {
+    return Status;
+  }
+}
+
+/**
+  Internal function that sets the baudrate on the Usb Serial Device.
+
+  @param  UsbIo[in]                  Usb Io Protocol instance pointer
+  @param  BaudRate[in]               The baudrate value to be set on the device.
+                                     If this value is 0 the value of LastBaudRate
+                                     will be used instead
+  @param  LastBaudRate[in]           The baud rate value that was previously set
+                                     on the Usb Serial Device
+
+  @retval EFI_SUCCESS                The baudrate was set succesfully
+  @retval EFI_INVALID_PARAMETER      An invalid baudrate was used
+  @retval EFI_DEVICE_ERROR           The device is not functioning correctly and
+                                     the baudrate was unable to be set
+
+**/
+EFI_STATUS
+EFIAPI
+SetBaudRateInternal (
+  IN EFI_USB_IO_PROTOCOL  *UsbIo,
+  IN UINT64               BaudRate,
+  IN UINT64               LastBaudRate
+  )
+{
+  EFI_STATUS              Status;
+  EFI_USB_DEVICE_REQUEST  DevReq;
+  UINT32                  ReturnValue;
+  UINT8                   ConfigurationValue;
+  UINT16                  EncodedBaudRate;
+  EFI_TPL                 Tpl;
+
+  Tpl    = gBS->RaiseTPL(TPL_NOTIFY);
+
+  //
+  // set the value of DevReq.Value based on the value of BaudRate
+  // if 0 is selected as baud rate use the value of LastBaudRate
+  //
+  if (BaudRate == 0) {
+    Status = EncodeBaudRateForFtdi (LastBaudRate, &EncodedBaudRate);
+    if (EFI_ERROR (Status)) {
+      gBS->RestoreTPL (Tpl);
+      //
+      // EncodeBaudRateForFtdi returns EFI_INVALID_PARAMETER when not
+      // succesfull
+      //
+      return Status;
+    }
+    DevReq.Value = EncodedBaudRate;
+  } else {
+    Status = EncodeBaudRateForFtdi (BaudRate, &EncodedBaudRate);
+    if (EFI_ERROR (Status)) {
+      gBS->RestoreTPL (Tpl);
+      //
+      // EncodeBaudRateForFtdi returns EFI_INVALID_PARAMETER when not
+      // successfull
+      //
+      return Status;
+    }
+    DevReq.Value = EncodedBaudRate;
+  }
+
+  //
+  // set the remaining parameters of DevReq and perform the usb control transfer
+  // to set the device
+  //
+  DevReq.Request     = FTDI_COMMAND_SET_BAUDRATE;
+  DevReq.RequestType = USB_REQ_TYPE_VENDOR;
+  DevReq.Index       = FTDI_PORT_IDENTIFIER;
+  DevReq.Length      = 0; // indicates that there is no data phase in this request
+
+  Status = UsbIo->UsbControlTransfer (
+                    UsbIo,
+                    &DevReq,
+                    EfiUsbDataOut,
+                    WDR_SHORT_TIMEOUT,
+                    &ConfigurationValue,
+                    1,
+                    &ReturnValue
+                    );
+  if (EFI_ERROR (Status)) {
+    goto StatusError;
+  }
+  gBS->RestoreTPL (Tpl);
+  return Status;
+
+StatusError:
+  gBS->RestoreTPL (Tpl);
+  if ((Status != EFI_INVALID_PARAMETER) || (Status != EFI_DEVICE_ERROR)) {
+    return EFI_DEVICE_ERROR;
+  } else {
+    return Status;
+  }
+}
+
+/**
+  Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,
+  data bits, and stop bits on a serial device.
+
+  @param  UsbSerialDevice[in]  Pointer to the current instance of the USB Serial
+                               Device.
+  @param  BaudRate[in]         The requested baud rate. A BaudRate value of 0
+                               will use the device's default interface speed.
+  @param  ReveiveFifoDepth[in] The requested depth of the FIFO on the receive
+                               side of the serial interface. A ReceiveFifoDepth
+                               value of 0 will use the device's default FIFO
+                               depth.
+  @param  Timeout[in]          The requested time out for a single character in
+                               microseconds.This timeout applies to both the
+                               transmit and receive side of the interface.A
+                               Timeout value of 0 will use the device's default
+                               time out value.
+  @param  Parity[in]           The type of parity to use on this serial device.
+                               A Parity value of DefaultParity will use the
+                               device's default parity value.
+  @param  DataBits[in]         The number of data bits to use on the serial
+                               device. A DataBits value of 0 will use the
+                               device's default data bit setting.
+  @param  StopBits[in]         The number of stop bits to use on this serial
+                               device. A StopBits value of DefaultStopBits will
+                               use the device's default number of stop bits.
+
+  @retval EFI_SUCCESS          The attributes were set
+  @retval EFI_DEVICE_ERROR     The attributes were not able to be set
+
+**/
+EFI_STATUS
+EFIAPI
+SetAttributesInternal (
+  IN USB_SER_DEV         *UsbSerialDevice,
+  IN UINT64              BaudRate,
+  IN UINT32              ReceiveFifoDepth,
+  IN UINT32              Timeout,
+  IN EFI_PARITY_TYPE     Parity,
+  IN UINT8               DataBits,
+  IN EFI_STOP_BITS_TYPE  StopBits
+  )
+{
+  EFI_STATUS                Status;
+  EFI_TPL                   Tpl;
+  UART_DEVICE_PATH          *Uart;
+  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath;
+
+  Status = EFI_UNSUPPORTED;
+  Tpl    = gBS->RaiseTPL(TPL_NOTIFY);
+  Uart   = NULL;
+
+  //
+  // check for invalid combinations of parameters
+  //
+  if (((DataBits >= 6) && (DataBits <= 8)) && (StopBits == OneFiveStopBits)) {
+    return  EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // set data bits, parity and stop bits
+  //
+  Status = SetDataInternal (
+             UsbSerialDevice->UsbIo,
+             DataBits,
+             Parity,
+             StopBits,
+             &(UsbSerialDevice->LastSettings)
+             );
+  if (EFI_ERROR (Status)) {
+    goto StatusError;
+  }
+  //
+  // set baudrate
+  //
+  Status = SetBaudRateInternal (
+             UsbSerialDevice->UsbIo,
+             BaudRate,
+             UsbSerialDevice->LastSettings.BaudRate
+             );
+  if (EFI_ERROR (Status)){
+    goto StatusError;
+  }
+
+  //
+  // update the values of UsbSerialDevice->LastSettings and UsbSerialDevice->SerialIo.Mode
+  //
+  if (BaudRate == 0) {
+    UsbSerialDevice->LastSettings.BaudRate   = UsbSerialDevice->LastSettings.BaudRate;
+    UsbSerialDevice->SerialIo.Mode->BaudRate = UsbSerialDevice->LastSettings.BaudRate;
+  } else {
+    UsbSerialDevice->LastSettings.BaudRate   = BaudRate;
+    UsbSerialDevice->SerialIo.Mode->BaudRate = BaudRate;
+  }
+
+  UsbSerialDevice->LastSettings.Timeout          = FTDI_TIMEOUT;
+  UsbSerialDevice->LastSettings.ReceiveFifoDepth = FTDI_MAX_RECEIVE_FIFO_DEPTH;
+
+  if (Parity == DefaultParity) {
+    UsbSerialDevice->LastSettings.Parity   = UsbSerialDevice->LastSettings.Parity;
+    UsbSerialDevice->SerialIo.Mode->Parity = UsbSerialDevice->LastSettings.Parity;
+  } else {
+    UsbSerialDevice->LastSettings.Parity   = Parity;
+    UsbSerialDevice->SerialIo.Mode->Parity = Parity;
+  }
+  if (DataBits == 0) {
+    UsbSerialDevice->LastSettings.DataBits   = UsbSerialDevice->LastSettings.DataBits;
+    UsbSerialDevice->SerialIo.Mode->DataBits = UsbSerialDevice->LastSettings.DataBits;
+  } else {
+    UsbSerialDevice->LastSettings.DataBits   = DataBits;
+    UsbSerialDevice->SerialIo.Mode->DataBits = DataBits;
+  }
+  if (StopBits == DefaultStopBits) {
+    UsbSerialDevice->LastSettings.StopBits   = UsbSerialDevice->LastSettings.StopBits;
+    UsbSerialDevice->SerialIo.Mode->StopBits = UsbSerialDevice->LastSettings.StopBits;
+  } else {
+    UsbSerialDevice->LastSettings.StopBits   = StopBits;
+    UsbSerialDevice->SerialIo.Mode->StopBits = StopBits;
+  }
+
+  //
+  // See if the device path node has changed
+  //
+  if (UsbSerialDevice->UartDevicePath.BaudRate == BaudRate &&
+      UsbSerialDevice->UartDevicePath.DataBits == DataBits &&
+      UsbSerialDevice->UartDevicePath.StopBits == StopBits &&
+      UsbSerialDevice->UartDevicePath.Parity == Parity
+      ) {
+    gBS->RestoreTPL (Tpl);
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Update the device path
+  //
+  UsbSerialDevice->UartDevicePath.BaudRate = BaudRate;
+  UsbSerialDevice->UartDevicePath.DataBits = DataBits;
+  UsbSerialDevice->UartDevicePath.StopBits = (UINT8) StopBits;
+  UsbSerialDevice->UartDevicePath.Parity   = (UINT8) Parity;
+
+  Status = EFI_SUCCESS;
+  if (UsbSerialDevice->ControllerHandle != NULL) {
+    RemainingDevicePath = UsbSerialDevice->DevicePath;
+    while (!IsDevicePathEnd (RemainingDevicePath)) {
+      Uart = (UART_DEVICE_PATH *) NextDevicePathNode (RemainingDevicePath);
+      if (Uart->Header.Type == MESSAGING_DEVICE_PATH &&
+          Uart->Header.SubType == MSG_UART_DP &&
+          sizeof (UART_DEVICE_PATH) == DevicePathNodeLength ((EFI_DEVICE_PATH *) Uart)) {
+        Uart->BaudRate = BaudRate;
+        Uart->DataBits = DataBits;
+        Uart->StopBits = (UINT8)StopBits;
+        Uart->Parity   = (UINT8) Parity;
+        break;
+        }
+        RemainingDevicePath = NextDevicePathNode (RemainingDevicePath);
+    }
+  }
+
+  gBS->RestoreTPL (Tpl);
+  return Status;
+
+StatusError:
+  gBS->RestoreTPL (Tpl);
+  if ((Status != EFI_INVALID_PARAMETER) || (Status != EFI_DEVICE_ERROR)) {
+    return EFI_DEVICE_ERROR;
+  } else {
+    return Status;
+  }
+}
+
+/**
+  Internal function that performs a Usb Control Transfer to set the flow control
+  on the Usb Serial Device.
+
+  @param  UsbIo[in]                  Usb Io Protocol instance pointer
+  @param  FlowControlEnable[in]      Data on the Enable/Disable status of Flow
+                                     Control on the Usb Serial Device
+
+  @retval EFI_SUCCESS                The flow control was set on the Usb Serial
+                                     device
+  @retval EFI_INVALID_PARAMETER      An invalid flow control value was used
+  @retval EFI_EFI_UNSUPPORTED        The operation is not supported
+  @retval EFI_DEVICE_ERROR           The device is not functioning correctly
+
+**/
+EFI_STATUS
+EFIAPI
+SetFlowControlInternal (
+  IN EFI_USB_IO_PROTOCOL  *UsbIo,
+  IN BOOLEAN              FlowControlEnable
+  )
+{
+  EFI_STATUS               Status;
+  EFI_USB_DEVICE_REQUEST   DevReq;
+  UINT32                   ReturnValue;
+  UINT8                    ConfigurationValue;
+
+  //
+  // set DevReq.Value based on the value of FlowControlEnable
+  //
+  if (!FlowControlEnable) {
+    DevReq.Value = NO_FLOW_CTRL;
+  }
+  if (FlowControlEnable) {
+    DevReq.Value = XON_XOFF_CTRL;
+  }
+  //
+  // set the remaining DevReq parameters and perform the usb control transfer to
+  // set the flow control on the device
+  //
+  DevReq.Request      = FTDI_COMMAND_SET_FLOW_CTRL;
+  DevReq.RequestType  = USB_REQ_TYPE_VENDOR;
+  DevReq.Index        = FTDI_PORT_IDENTIFIER;
+  DevReq.Length       = 0; // indicates that this transfer has no data phase
+  Status              = UsbIo->UsbControlTransfer (
+                                 UsbIo,
+                                 &DevReq,
+                                 EfiUsbDataOut,
+                                 WDR_TIMEOUT,
+                                 &ConfigurationValue,
+                                 1,
+                                 &ReturnValue
+                                 );
+  if (EFI_ERROR (Status)) {
+    goto StatusError;
+  }
+
+  return Status;
+
+StatusError:
+  if ((Status != EFI_INVALID_PARAMETER) ||
+      (Status != EFI_DEVICE_ERROR)      ||
+      (Status != EFI_UNSUPPORTED)          ) {
+    return EFI_DEVICE_ERROR;
+  } else {
+    return Status;
+  }
+}
+
+/**
+  Internal function that performs a Usb Control Transfer to set the Dtr value on
+  the Usb Serial Device.
+
+  @param  UsbIo[in]                  Usb Io Protocol instance pointer
+  @param  DtrEnable[in]              Data on the Enable/Disable status of the
+                                     Dtr for the Usb Serial Device
+
+  @retval EFI_SUCCESS                The Dtr value was set on the Usb Serial
+                                     Device
+  @retval EFI_INVALID_PARAMETER      An invalid Dtr value was used
+  @retval EFI_UNSUPPORTED            The operation is not supported
+  @retval EFI_DEVICE_ERROR           The device is not functioning correctly
+
+**/
+EFI_STATUS
+EFIAPI
+SetDtrInternal (
+  IN EFI_USB_IO_PROTOCOL  *UsbIo,
+  IN BOOLEAN              DtrEnable
+  )
+{
+  EFI_STATUS              Status;
+  EFI_USB_DEVICE_REQUEST  DevReq;
+  UINT32                  ReturnValue;
+  UINT8                   ConfigurationValue;
+
+  //
+  // set the value of DevReq.Value based on the value of DtrEnable
+  //
+  if (!DtrEnable) {
+    DevReq.Value = SET_DTR_LOW;
+  }
+  if (DtrEnable) {
+    DevReq.Value = SET_DTR_HIGH;
+  }
+  //
+  // set the remaining attributes of DevReq and perform the usb control transfer
+  // to set the device
+  //
+  DevReq.Request      = FTDI_COMMAND_MODEM_CTRL;
+  DevReq.RequestType  = USB_REQ_TYPE_VENDOR;
+  DevReq.Index        = FTDI_PORT_IDENTIFIER;
+  DevReq.Length       = 0; // indicates that there is no data phase in this transfer
+
+  Status = UsbIo->UsbControlTransfer (
+                    UsbIo,
+                    &DevReq,
+                    EfiUsbDataOut,
+                    WDR_TIMEOUT,
+                    &ConfigurationValue,
+                    1,
+                    &ReturnValue
+                    );
+  if (EFI_ERROR (Status)) {
+    goto StatusError;
+  }
+  return Status;
+
+StatusError:
+  if ((Status != EFI_INVALID_PARAMETER) ||
+      (Status != EFI_DEVICE_ERROR)      ||
+      (Status != EFI_UNSUPPORTED)          ) {
+    return EFI_DEVICE_ERROR;
+  } else {
+    return Status;
+  }
+}
+
+/**
+  Internal function that performs a Usb Control Transfer to set the Dtr value on
+  the Usb Serial Device.
+  
+  @param  UsbIo[in]                  Usb Io Protocol instance pointer
+  @param  RtsEnable[in]              Data on the Enable/Disable status of the
+                                     Rts for the Usb Serial Device
+
+  @retval EFI_SUCCESS                The Rts value was set on the Usb Serial
+                                     Device
+  @retval EFI_INVALID_PARAMETER      An invalid Rts value was used
+  @retval EFI_UNSUPPORTED            The operation is not supported
+  @retval EFI_DEVICE_ERROR           The device is not functioning correctly
+
+**/
+EFI_STATUS
+EFIAPI
+SetRtsInternal (
+  IN EFI_USB_IO_PROTOCOL  *UsbIo,
+  IN BOOLEAN              RtsEnable
+  )
+{
+  EFI_STATUS              Status;
+  EFI_USB_DEVICE_REQUEST  DevReq;
+  UINT32                  ReturnValue;
+  UINT8                   ConfigurationValue;
+
+  //
+  // set DevReq.Value based on the value of RtsEnable
+  //
+  if (!RtsEnable) {
+    DevReq.Value = SET_RTS_LOW;
+  }
+  if (RtsEnable) {
+    DevReq.Value = SET_RTS_HIGH;
+  }
+
+  //
+  // set the remaining parameters of DevReq and perform the usb control transfer
+  // to set the values on the device
+  //
+  DevReq.Request     = FTDI_COMMAND_MODEM_CTRL;
+  DevReq.RequestType = USB_REQ_TYPE_VENDOR;
+  DevReq.Index       = FTDI_PORT_IDENTIFIER;
+  DevReq.Length      = 0; // indicates that there is no data phase in this request
+
+  Status = UsbIo->UsbControlTransfer (
+                    UsbIo,
+                    &DevReq,
+                    EfiUsbDataOut,
+                    WDR_TIMEOUT,
+                    &ConfigurationValue,
+                    1,
+                    &ReturnValue
+                    );
+  if (EFI_ERROR (Status)) {
+    goto StatusError;
+  }
+
+  return Status;
+
+StatusError:
+  if ((Status != EFI_INVALID_PARAMETER) ||
+      (Status != EFI_DEVICE_ERROR)      ||
+      (Status != EFI_UNSUPPORTED)          ) {
+    return EFI_DEVICE_ERROR;
+  } else {
+    return Status;
+  }
+}
+
+/**
+  Internal function that checks for valid control values and sets the control
+  bits on the Usb Serial Device.
+
+  @param  UsbSerialDevice[in]        Handle to the Usb Serial Device whose
+                                     control bits are being set
+  @param  Control[in]                The control value passed to the function
+                                     that contains the values of the control
+                                     bits that are being set
+
+  @retval EFI_SUCCESS                The control bits were set on the Usb Serial
+                                     Device
+  @retval EFI_INVALID_PARAMETER      An invalid control value was encountered
+  @retval EFI_EFI_UNSUPPORTED        The operation is not supported
+  @retval EFI_DEVICE_ERROR           The device is not functioning correctly
+
+**/
+EFI_STATUS
+EFIAPI
+SetControlBitsInternal (
+  IN USB_SER_DEV   *UsbSerialDevice,
+  IN CONTROL_BITS  *Control
+  )
+{
+  EFI_STATUS                    Status;
+  UART_FLOW_CONTROL_DEVICE_PATH *FlowControl;
+  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath;
+
+  //
+  // check for invalid control parameters hardware and software loopback enabled
+  // must always be set to FALSE
+  //
+  Control->HardwareLoopBack = FALSE;
+  Control->SoftwareLoopBack = FALSE;
+
+  //
+  // set hardware flow control
+  //
+  Status  = SetFlowControlInternal (
+              UsbSerialDevice->UsbIo,
+              Control->HardwareFlowControl
+              );
+  if (EFI_ERROR (Status)) {
+    goto StatusError;
+  }
+
+  //
+  // set Dtr state
+  //
+  Status = SetDtrInternal (UsbSerialDevice->UsbIo, Control->DtrState);
+  if (EFI_ERROR (Status)) {
+    goto StatusError;
+  }
+
+  //
+  // set Rts state
+  //
+  Status = SetRtsInternal (UsbSerialDevice->UsbIo, Control->RtsState);
+  if (EFI_ERROR (Status)){
+    goto StatusError;
+  }
+
+  //
+  // update the remaining control values for UsbSerialDevice->ControlValues
+  //
+  UsbSerialDevice->ControlValues.DtrState            = Control->DtrState;
+  UsbSerialDevice->ControlValues.RtsState            = Control->RtsState;
+  UsbSerialDevice->ControlValues.HardwareFlowControl = Control->HardwareFlowControl;
+  UsbSerialDevice->ControlValues.HardwareLoopBack    = FALSE;
+  UsbSerialDevice->ControlValues.SoftwareLoopBack    = FALSE;
+
+  Status = EFI_SUCCESS;
+  //
+  // Update the device path to have the correct flow control values
+  //
+  if (UsbSerialDevice->ControllerHandle != NULL) {
+    RemainingDevicePath = UsbSerialDevice->DevicePath;
+    while (!IsDevicePathEnd (RemainingDevicePath)) {
+      FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (RemainingDevicePath);
+      if (FlowControl->Header.Type == MESSAGING_DEVICE_PATH &&
+          FlowControl->Header.SubType == MSG_VENDOR_DP &&
+          sizeof (UART_FLOW_CONTROL_DEVICE_PATH) == DevicePathNodeLength ((EFI_DEVICE_PATH *) FlowControl)){
+        if (UsbSerialDevice->ControlValues.HardwareFlowControl == TRUE) {
+          FlowControl->FlowControlMap = UART_FLOW_CONTROL_HARDWARE;
+        } else if (UsbSerialDevice->ControlValues.HardwareFlowControl == FALSE) {
+          FlowControl->FlowControlMap = 0;
+        }
+        break;
+      }
+      RemainingDevicePath = NextDevicePathNode (RemainingDevicePath);
+    }
+  }
+
+  return Status;
+
+StatusError:
+  if ((Status != EFI_INVALID_PARAMETER) ||
+      (Status != EFI_DEVICE_ERROR)      ||
+      (Status != EFI_UNSUPPORTED)          ) {
+    return EFI_DEVICE_ERROR;
+  } else {
+    return Status;
+  }
+}
+
+/**
+  Internal function that calculates the Control value used by GetControlBits()
+  based on the status and control values of the Usb Serial Device.
+
+  @param  UsbSerialDevice[in]        Handle to the Usb Serial Devie whose status
+                                     and control values are being used to set
+                                     Control
+  @param  Control[out]               On output the formated value of Control
+                                     that has been calculated based on the
+                                     control and status values of the Usb Serial
+                                     Device
+
+  @retval EFI_SUCCESS                The value of Control was successfully
+                                     calculated
+
+**/
+EFI_STATUS
+EFIAPI
+GetControlBitsInternal (
+  IN USB_SER_DEV  *UsbSerialDevice,
+  OUT UINT32      *Control
+  )
+{
+  *Control = 0;
+
+  //
+  // Check the values of UsbSerialDevice->Status Values and modify control
+  // accordingly these values correspond to the modem status register
+  //
+  if (UsbSerialDevice->StatusValues.CtsState) {
+    *Control |= EFI_SERIAL_CLEAR_TO_SEND;
+  }
+  if (UsbSerialDevice->StatusValues.DsrState) {
+    *Control |= EFI_SERIAL_DATA_SET_READY;
+  }
+  if (UsbSerialDevice->StatusValues.RiState) {
+    *Control |= EFI_SERIAL_RING_INDICATE;
+  }
+  if (UsbSerialDevice->StatusValues.SdState) {
+    *Control |= EFI_SERIAL_CARRIER_DETECT;
+  }
+
+  //
+  // check the values of UsbSerialDevice->ControlValues and modify control
+  // accordingly these values correspond to the values of the Modem Control
+  // Register
+  //
+  if (UsbSerialDevice->ControlValues.DtrState) {
+    *Control |= EFI_SERIAL_DATA_TERMINAL_READY;
+  }
+  if (UsbSerialDevice->ControlValues.RtsState) {
+    *Control |= EFI_SERIAL_REQUEST_TO_SEND;
+  }
+  if (UsbSerialDevice->ControlValues.HardwareLoopBack) {
+    *Control |= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE;
+  }
+  if (UsbSerialDevice->ControlValues.HardwareFlowControl) {
+    *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
+  }
+  //
+  // check if the buffer is empty since only one is being used if it is empty
+  // set both the receive and transmit buffers to empty
+  //
+  if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {
+    *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY;
+    *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
+  }
+  //
+  // check for software loopback enable in UsbSerialDevice->ControlValues
+  //
+  if (UsbSerialDevice->ControlValues.SoftwareLoopBack) {
+    *Control |= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Resets the USB Serial Device
+
+  This function is the internal method for resetting the device and is called by
+  SerialReset()
+
+  @param  UsbSerialDevice[in]  A pointer to the USB Serial device
+
+  @retval EFI_SUCCESS          The device was reset
+  @retval EFI_DEVICE_ERROR     The device could not be reset
+
+**/
+EFI_STATUS
+EFIAPI
+ResetInternal (
+  IN USB_SER_DEV  *UsbSerialDevice
+  )
+{
+  EFI_STATUS              Status;
+  EFI_USB_DEVICE_REQUEST  DevReq;
+  UINT8                   ConfigurationValue;
+  UINT32                  ReturnValue;
+
+  DevReq.Request     = FTDI_COMMAND_RESET_PORT;
+  DevReq.RequestType = USB_REQ_TYPE_VENDOR;
+  DevReq.Value       = RESET_PORT_PURGE_RX;
+  DevReq.Index       = FTDI_PORT_IDENTIFIER;
+  DevReq.Length      = 0; //indicates that there is not data phase in this request
+
+  Status = UsbSerialDevice->UsbIo->UsbControlTransfer (
+                                     UsbSerialDevice->UsbIo,
+                                     &DevReq,
+                                     EfiUsbDataIn,
+                                     WDR_TIMEOUT,
+                                     &ConfigurationValue,
+                                     1,
+                                     &ReturnValue
+                                     );
+  if (EFI_ERROR (Status)) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  DevReq.Request     = FTDI_COMMAND_RESET_PORT;
+  DevReq.RequestType = USB_REQ_TYPE_VENDOR;
+  DevReq.Value       = RESET_PORT_PURGE_TX;
+  DevReq.Index       = FTDI_PORT_IDENTIFIER;
+  DevReq.Length      = 0; //indicates that there is no data phase in this request
+
+  Status = UsbSerialDevice->UsbIo->UsbControlTransfer (
+                                     UsbSerialDevice->UsbIo,
+                                     &DevReq,
+                                     EfiUsbDataIn,
+                                     WDR_TIMEOUT,
+                                     &ConfigurationValue,
+                                     1,
+                                     &ReturnValue
+                                     );
+  if (EFI_ERROR (Status)) {
+    return EFI_DEVICE_ERROR;
+  }
+  return Status;
+}
+
+/**
+  Entrypoint of USB Serial Driver.
+
+  This function is the entrypoint of USB Serial Driver. It installs
+  Driver Binding Protocols together with Component Name Protocols.
+
+  @param  ImageHandle[in]       The firmware allocated handle for the EFI image.
+  @param  SystemTable[in]       A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS           The entry point is executed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+FtdiUsbSerialEntryPoint (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = EfiLibInstallDriverBindingComponentName2 (
+             ImageHandle,
+             SystemTable,
+             &gUsbSerialDriverBinding,
+             ImageHandle,
+             &gUsbSerialComponentName,
+             &gUsbSerialComponentName2
+             );
+  ASSERT_EFI_ERROR (Status);
+  return EFI_SUCCESS;
+}
+
+/**
+  Unload function for the Usb Serial Driver.
+
+  @param  ImageHandle[in]    The allocated handle for the EFI image
+
+  @retval EFI_SUCCESS        The driver was unloaded successfully
+**/
+EFI_STATUS
+EFIAPI
+FtdiUsbSerialUnload (
+  IN EFI_HANDLE  ImageHandle
+  )
+{
+  EFI_STATUS  Status;
+  EFI_HANDLE  *HandleBuffer;
+  UINTN       HandleCount;
+  UINTN       Index;
+
+  //
+  // Retrieve all handles in the handle database
+  //
+  Status = gBS->LocateHandleBuffer (
+                  AllHandles,
+                  NULL,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Disconnect the driver from the handles in the handle database
+  //
+  for (Index = 0; Index < HandleCount; Index++) {
+    Status = gBS->DisconnectController (
+                    HandleBuffer[Index],
+                    gImageHandle,
+                    NULL
+                    );
+  }
+
+  //
+  // Free the handle array
+  //
+  FreePool (HandleBuffer);
+
+  //
+  // Uninstall protocols installed by the driver in its entrypoint
+  //
+  Status = gBS->UninstallMultipleProtocolInterfaces (
+                  ImageHandle,
+                  &gEfiDriverBindingProtocolGuid,
+                  &gUsbSerialDriverBinding,
+                  &gEfiComponentNameProtocolGuid,
+                  &gUsbSerialComponentName,
+                  &gEfiComponentName2ProtocolGuid,
+                  &gUsbSerialComponentName2,
+                  NULL
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Check whether USB Serial driver supports this device.
+
+  @param  This[in]                   The USB Serial driver binding protocol.
+  @param  Controller[in]             The controller handle to check.
+  @param  RemainingDevicePath[in]    The remaining device path.
+
+  @retval EFI_SUCCESS                The driver supports this controller.
+  @retval other                      This device isn't supported.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbSerialDriverBindingSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  )
+{
+  EFI_STATUS           Status;
+  EFI_USB_IO_PROTOCOL  *UsbIo;
+  UART_DEVICE_PATH     *UartNode;
+  UART_FLOW_CONTROL_DEVICE_PATH        *FlowControlNode;
+  UINTN                                Index;
+  UINTN                                EntryCount;
+  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY  *OpenInfoBuffer;
+  BOOLEAN                              HasFlowControl;
+  EFI_DEVICE_PATH_PROTOCOL             *DevicePath;
+  EFI_DEVICE_PATH_PROTOCOL             *ParentDevicePath;
+
+  if (RemainingDevicePath != NULL) {
+    if (!IsDevicePathEnd (RemainingDevicePath)) {
+      Status = EFI_UNSUPPORTED;
+      UartNode = (UART_DEVICE_PATH *) NextDevicePathNode (RemainingDevicePath);
+      if (UartNode->Header.Type != MESSAGING_DEVICE_PATH ||
+          UartNode->Header.SubType != MSG_UART_DP ||
+          sizeof (UART_DEVICE_PATH) != DevicePathNodeLength ((EFI_DEVICE_PATH *) UartNode)) {
+        goto Error;
+      }
+      FlowControlNode = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (UartNode);
+      if ((ReadUnaligned32 (&FlowControlNode->FlowControlMap) & ~UART_FLOW_CONTROL_HARDWARE) != 0) {
+        goto Error;
+      }
+    }
+  }
+
+  //
+  // Check if USB I/O Protocol is attached on the controller handle.
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiUsbIoProtocolGuid,
+                  (VOID **) &UsbIo,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (Status == EFI_ALREADY_STARTED) {
+    if (RemainingDevicePath == NULL || IsDevicePathEnd (RemainingDevicePath)) {
+      return EFI_SUCCESS;
+    }
+    Status = gBS->OpenProtocolInformation (
+                    Controller,
+                    &gEfiUsbIoProtocolGuid,
+                    &OpenInfoBuffer,
+                    &EntryCount
+                    );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    for (Index = 0; Index < EntryCount; Index++) {
+      if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
+        Status = gBS->OpenProtocol (
+                        OpenInfoBuffer[Index].ControllerHandle,
+                        &gEfiDevicePathProtocolGuid,
+                        (VOID **) &DevicePath,
+                        This->DriverBindingHandle,
+                        Controller,
+                        EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                        );
+        if (!EFI_ERROR (Status)) {
+          HasFlowControl = ContainsFlowControl (RemainingDevicePath);
+          if (HasFlowControl ^ ContainsFlowControl (DevicePath)) {
+            Status = EFI_UNSUPPORTED;
+          }
+        }
+        break;
+      }
+    }
+    FreePool (OpenInfoBuffer);
+    return Status;
+  }
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  gBS->CloseProtocol (
+         Controller,
+         &gEfiUsbIoProtocolGuid,
+         This->DriverBindingHandle,
+         Controller
+         );
+
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID **) &ParentDevicePath,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (Status == EFI_ALREADY_STARTED) {
+    return EFI_SUCCESS;
+  }
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Use the USB I/O Protocol interface to check whether Controller is
+  // a USB Serial device that can be managed by this driver.
+  //
+  Status = EFI_SUCCESS;
+
+  if (!IsUsbSerial (UsbIo)) {
+    Status = EFI_UNSUPPORTED;
+    goto Error;
+  }
+
+Error:
+  gBS->CloseProtocol (
+         Controller,
+         &gEfiDevicePathProtocolGuid,
+         This->DriverBindingHandle,
+         Controller
+         );
+  return Status;
+}
+
+/**
+  Starts the USB Serial device with this driver.
+
+  This function produces initializes the USB Serial device and
+  produces the Serial IO Protocol.
+
+  @param  This[in]                   The USB Serial driver binding instance.
+  @param  Controller[in]             Handle of device to bind driver to.
+  @param  RemainingDevicePath[in]    Optional parameter use to pick a specific
+                                     child device to start.
+
+  @retval EFI_SUCCESS                The controller is controlled by the usb USB
+                                     Serial driver.
+  @retval EFI_UNSUPPORTED            No interrupt endpoint can be found.
+  @retval Other                      This controller cannot be started.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbSerialDriverBindingStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  )
+{
+  EFI_STATUS                          Status;
+  EFI_USB_IO_PROTOCOL                 *UsbIo;
+  USB_SER_DEV                         *UsbSerialDevice;
+  UINT8                               EndpointNumber;
+  EFI_USB_ENDPOINT_DESCRIPTOR         EndpointDescriptor;
+  UINT8                               Index;
+  BOOLEAN                             FoundIn;
+  BOOLEAN                             FoundOut;
+  EFI_DEVICE_PATH_PROTOCOL            *ParentDevicePath;
+  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
+  UINTN                               EntryCount;
+  EFI_SERIAL_IO_PROTOCOL              *SerialIo;
+  UART_DEVICE_PATH                    *Uart;
+  UART_FLOW_CONTROL_DEVICE_PATH       *FlowControl;
+  UINT32                              Control;
+  EFI_DEVICE_PATH_PROTOCOL            *TempDevicePath;
+
+  UsbSerialDevice = AllocateZeroPool (sizeof (USB_SER_DEV));
+  ASSERT (UsbSerialDevice != NULL);
+
+  //
+  // Get the Parent Device path
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID **) &ParentDevicePath,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
+    goto ErrorExit1;
+  }
+
+  //
+  // Open USB I/O Protocol
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiUsbIoProtocolGuid,
+                  (VOID **) &UsbIo,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
+    goto ErrorExit1;
+  }
+
+  if (Status == EFI_ALREADY_STARTED) {
+    if (RemainingDevicePath == NULL || IsDevicePathEnd (RemainingDevicePath)) {
+      FreePool (UsbSerialDevice);
+      return EFI_SUCCESS;
+    }
+
+    //
+    // Check to see if a child handle exists
+    //
+    Status = gBS->OpenProtocolInformation (
+                    Controller,
+                    &gEfiSerialIoProtocolGuid,
+                    &OpenInfoBuffer,
+                    &EntryCount
+                    );
+    if (EFI_ERROR (Status)) {
+      goto ErrorExit1;
+    }
+
+    Status = EFI_ALREADY_STARTED;
+    for (Index = 0; Index < EntryCount; Index++) {
+      if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
+        Status = gBS->OpenProtocol (
+                        OpenInfoBuffer[Index].ControllerHandle,
+                        &gEfiSerialIoProtocolGuid,
+                        (VOID **) &SerialIo,
+                        This->DriverBindingHandle,
+                        Controller,
+                        EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                        );
+        if (EFI_ERROR (Status)) {
+        }
+        if (!EFI_ERROR (Status)) {
+          Uart = (UART_DEVICE_PATH *) RemainingDevicePath;
+          Status = SerialIo->SetAttributes (
+                               SerialIo,
+                               Uart->BaudRate,
+                               SerialIo->Mode->ReceiveFifoDepth,
+                               SerialIo->Mode->Timeout,
+                               (EFI_PARITY_TYPE) Uart->Parity,
+                               Uart->DataBits,
+                               (EFI_STOP_BITS_TYPE) Uart->StopBits
+                               );
+          FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (Uart);
+          if (!EFI_ERROR (Status) && IsUartFlowControlNode (FlowControl)) {
+            Status = SerialIo->GetControl (
+                                 SerialIo,
+                                 &Control
+                                 );
+            if (!EFI_ERROR (Status)) {
+              if (ReadUnaligned32 (&FlowControl->FlowControlMap) == UART_FLOW_CONTROL_HARDWARE) {
+                Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
+              } else {
+                Control &= ~EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
+              }
+              //
+              // Clear bits that are not allowed to be passed to SetControl
+              //
+              Control &= (EFI_SERIAL_REQUEST_TO_SEND | 
+                          EFI_SERIAL_DATA_TERMINAL_READY |
+                          EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE |
+                          EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE |
+                          EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE);
+              Status = SerialIo->SetControl (SerialIo, Control);
+            }
+          }
+        }
+        break;
+      }
+    }
+    FreePool (OpenInfoBuffer);
+    return Status;
+  }
+
+  if (RemainingDevicePath != NULL) {
+    if (IsDevicePathEnd (RemainingDevicePath)) {
+      return EFI_SUCCESS;
+    }
+  }
+
+  UsbSerialDevice->UsbIo = UsbIo;
+
+  //
+  // Get interface & endpoint descriptor
+  //
+  UsbIo->UsbGetInterfaceDescriptor (
+           UsbIo,
+           &UsbSerialDevice->InterfaceDescriptor
+           );
+
+  EndpointNumber = UsbSerialDevice->InterfaceDescriptor.NumEndpoints;
+
+  //
+  // Traverse endpoints to find the IN and OUT endpoints that will send and
+  // receive data.
+  //
+  FoundIn = FALSE;
+  FoundOut = FALSE;
+  for (Index = 0; Index < EndpointNumber; Index++) {
+
+    Status = UsbIo->UsbGetEndpointDescriptor (
+                      UsbIo,
+                      Index,
+                      &EndpointDescriptor
+                      );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    if (EndpointDescriptor.EndpointAddress == FTDI_ENDPOINT_ADDRESS_OUT) {
+      //
+      // Set the Out endpoint device
+      //
+      CopyMem (
+        &UsbSerialDevice->OutEndpointDescriptor,
+        &EndpointDescriptor,
+        sizeof(EndpointDescriptor)
+        );
+      FoundOut = TRUE;
+    }
+
+    if (EndpointDescriptor.EndpointAddress == FTDI_ENDPOINT_ADDRESS_IN) {
+      //
+      // Set the In endpoint device
+      //
+      CopyMem (
+        &UsbSerialDevice->InEndpointDescriptor,
+        &EndpointDescriptor,
+        sizeof(EndpointDescriptor)
+        );
+      FoundIn = TRUE;
+    }
+  }
+
+  if (!FoundIn || !FoundOut) {
+    //
+    // No interrupt endpoint found, then return unsupported.
+    //
+    Status = EFI_UNSUPPORTED;
+    goto ErrorExit;
+  }
+  //
+  // set the initial values of UsbSerialDevice->LastSettings to the default
+  // values
+  //
+  UsbSerialDevice->LastSettings.BaudRate         = 115200;
+  UsbSerialDevice->LastSettings.DataBits         = 8;
+  UsbSerialDevice->LastSettings.Parity           = NoParity;
+  UsbSerialDevice->LastSettings.ReceiveFifoDepth = FTDI_MAX_RECEIVE_FIFO_DEPTH;
+  UsbSerialDevice->LastSettings.StopBits         = OneStopBit;
+  UsbSerialDevice->LastSettings.Timeout          = FTDI_TIMEOUT;
+
+  //
+  // set the initial values of UsbSerialDevice->ControlValues
+  //
+  UsbSerialDevice->ControlValues.DtrState            = FALSE;
+  UsbSerialDevice->ControlValues.RtsState            = FALSE;
+  UsbSerialDevice->ControlValues.HardwareFlowControl = FALSE;
+  UsbSerialDevice->ControlValues.HardwareLoopBack    = FALSE;
+  UsbSerialDevice->ControlValues.SoftwareLoopBack    = FALSE;
+
+  //
+  // set the values of UsbSerialDevice->UartDevicePath
+  //
+  UsbSerialDevice->UartDevicePath.Header.Type    = MESSAGING_DEVICE_PATH;
+  UsbSerialDevice->UartDevicePath.Header.SubType = MSG_UART_DP;
+  UsbSerialDevice->UartDevicePath.Header.Length[0] = (UINT8) (sizeof (UART_DEVICE_PATH));
+  UsbSerialDevice->UartDevicePath.Header.Length[1] = (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8);
+
+  //
+  // set the values of UsbSerialDevice->FlowControlDevicePath
+  UsbSerialDevice->FlowControlDevicePath.Header.Type = MESSAGING_DEVICE_PATH;
+  UsbSerialDevice->FlowControlDevicePath.Header.SubType = MSG_VENDOR_DP;
+  UsbSerialDevice->FlowControlDevicePath.Header.Length[0] = (UINT8) (sizeof (UART_FLOW_CONTROL_DEVICE_PATH));
+  UsbSerialDevice->FlowControlDevicePath.Header.Length[1] = (UINT8) ((sizeof (UART_FLOW_CONTROL_DEVICE_PATH)) >> 8);
+  UsbSerialDevice->FlowControlDevicePath.FlowControlMap = 0;
+
+  Status = SetAttributesInternal (
+             UsbSerialDevice, 
+             UsbSerialDevice->LastSettings.BaudRate,
+             UsbSerialDevice->LastSettings.ReceiveFifoDepth, 
+             UsbSerialDevice->LastSettings.Timeout,
+             UsbSerialDevice->LastSettings.Parity, 
+             UsbSerialDevice->LastSettings.DataBits,
+             UsbSerialDevice->LastSettings.StopBits
+             );
+
+  ASSERT_EFI_ERROR (Status);
+
+  Status = SetControlBitsInternal (
+             UsbSerialDevice,
+             &(UsbSerialDevice->ControlValues)
+             );
+
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Publish Serial GUID and protocol
+  //
+
+  UsbSerialDevice->Signature              = USB_SER_DEV_SIGNATURE;
+  UsbSerialDevice->SerialIo.Reset         = SerialReset;
+  UsbSerialDevice->SerialIo.SetControl    = SetControlBits;
+  UsbSerialDevice->SerialIo.SetAttributes = SetAttributes;
+  UsbSerialDevice->SerialIo.GetControl    = GetControlBits;
+  UsbSerialDevice->SerialIo.Read          = ReadSerialIo;
+  UsbSerialDevice->SerialIo.Write         = WriteSerialIo;
+
+  //
+  // Set the static Serial IO modes that will display when running
+  // "sermode" within the UEFI shell.
+  //
+
+  UsbSerialDevice->SerialIo.Mode->Timeout  = 0;
+  UsbSerialDevice->SerialIo.Mode->BaudRate = 115200;
+  UsbSerialDevice->SerialIo.Mode->DataBits = 8;
+  UsbSerialDevice->SerialIo.Mode->Parity   = 1;
+  UsbSerialDevice->SerialIo.Mode->StopBits = 1;
+
+  UsbSerialDevice->ParentDevicePath = ParentDevicePath;
+  UsbSerialDevice->ControllerHandle = NULL;
+  FlowControl                       = NULL;
+
+  //
+  // Allocate space for the receive buffer
+  //
+  UsbSerialDevice->DataBuffer = AllocateZeroPool (SW_FIFO_DEPTH);
+
+  //
+  // Initialize data buffer pointers.
+  // Head==Tail = true means buffer is empty.
+  //
+  UsbSerialDevice->DataBufferHead = 0;
+  UsbSerialDevice->DataBufferTail = 0;
+
+  UsbSerialDevice->ControllerNameTable = NULL;
+  AddUnicodeString2 (
+    "eng",
+    gUsbSerialComponentName.SupportedLanguages,
+    &UsbSerialDevice->ControllerNameTable,
+    L"FTDI USB Serial Adapter",
+    TRUE
+    );
+  AddUnicodeString2 (
+    "en",
+    gUsbSerialComponentName2.SupportedLanguages,
+    &UsbSerialDevice->ControllerNameTable,
+    L"FTDI USB Serial Adapter",
+    FALSE
+    );
+
+  Status = SetInitialStatus (UsbSerialDevice);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Create a polling loop to check for input
+  //
+
+  gBS->CreateEvent (
+         EVT_TIMER | EVT_NOTIFY_SIGNAL,
+         TPL_CALLBACK,
+         UsbSerialDriverCheckInput,
+         UsbSerialDevice,
+         &(UsbSerialDevice->PollingLoop)
+         );
+  //
+  // add code to set trigger time based on baud rate
+  // setting to 0.5s for now
+  //
+  gBS->SetTimer (
+         UsbSerialDevice->PollingLoop,
+         TimerPeriodic,
+         EFI_TIMER_PERIOD_MILLISECONDS (500)
+         );
+
+  //
+  // Check if the remaining device path is null. If it is not null change the settings
+  // of the device to match those on the device path
+  //
+  if (RemainingDevicePath != NULL) {
+    CopyMem (
+      &UsbSerialDevice->UartDevicePath,
+      RemainingDevicePath,
+      sizeof (UART_DEVICE_PATH)
+      );
+    FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (RemainingDevicePath);
+    if (IsUartFlowControlNode (FlowControl)) {
+      UsbSerialDevice->FlowControlDevicePath.FlowControlMap = ReadUnaligned32 (&FlowControl->FlowControlMap);
+    } else {
+      FlowControl = NULL;
+    }
+  }
+
+  //
+  // Build the device path by appending the UART node to the parent device path
+  //
+  UsbSerialDevice->DevicePath = AppendDevicePathNode (
+                                  ParentDevicePath,
+                                  (EFI_DEVICE_PATH_PROTOCOL *) &UsbSerialDevice->UartDevicePath
+                                  );
+  //
+  // Continue building the device path by appending the flow control node
+  //
+  TempDevicePath = UsbSerialDevice->DevicePath;
+  UsbSerialDevice->DevicePath = AppendDevicePathNode (
+                                  TempDevicePath,
+                                  (EFI_DEVICE_PATH_PROTOCOL *) &UsbSerialDevice->FlowControlDevicePath
+                                  );
+  FreePool (TempDevicePath);
+
+  if (UsbSerialDevice->DevicePath == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ErrorExit;
+  }
+
+  //
+  // Install protocol interfaces for the device
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &UsbSerialDevice->ControllerHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  UsbSerialDevice->DevicePath,
+                  &gEfiSerialIoProtocolGuid,
+                  &UsbSerialDevice->SerialIo,
+                  NULL
+                  );
+  if (EFI_ERROR (Status)){
+    goto ErrorExit;
+  }
+
+  //
+  // Open for child device
+  //
+  Status = gBS->OpenProtocol (
+                 Controller,
+                 &gEfiUsbIoProtocolGuid,
+                 (VOID **) &UsbIo,
+                 This->DriverBindingHandle,
+                 UsbSerialDevice->ControllerHandle,
+                 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+                 );
+
+  UsbSerialDevice->Shutdown = FALSE;
+
+  return EFI_SUCCESS;
+
+ErrorExit:
+  //
+  // Error handler
+  //
+
+  Status = gBS->UninstallMultipleProtocolInterfaces (
+                  Controller,
+                  &gEfiSerialIoProtocolGuid,
+                  &UsbSerialDevice->SerialIo,
+                  NULL
+                  );
+  if (EFI_ERROR (Status)) {
+    goto ErrorExit1;
+  }
+
+  FreePool (UsbSerialDevice->DataBuffer);
+  FreePool (UsbSerialDevice);
+
+  UsbSerialDevice = NULL;
+  gBS->CloseProtocol (
+         Controller,
+         &gEfiUsbIoProtocolGuid,
+         This->DriverBindingHandle,
+         Controller
+         );
+
+ErrorExit1:
+  return Status;
+}
+
+/**
+  Stop the USB Serial device handled by this driver.
+
+  @param  This[in]                   The USB Serial driver binding protocol.
+  @param  Controller[in]             The controller to release.
+  @param  NumberOfChildren[in]       The number of handles in ChildHandleBuffer.
+  @param  ChildHandleBuffer[in]      The array of child handle.
+
+  @retval EFI_SUCCESS                The device was stopped.
+  @retval EFI_UNSUPPORTED            Serial IO Protocol is not installed on
+                                     Controller.
+  @retval EFI_DEVICE_ERROR           The device could not be stopped due to a
+                                     device error.
+  @retval Others                     Fail to uninstall protocols attached on the
+                                     device.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbSerialDriverBindingStop (
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN  EFI_HANDLE                   Controller,
+  IN  UINTN                        NumberOfChildren,
+  IN  EFI_HANDLE                   *ChildHandleBuffer
+  )
+{
+  EFI_STATUS                Status;
+  EFI_SERIAL_IO_PROTOCOL    *SerialIo;
+  EFI_USB_IO_PROTOCOL       *UsbIo;
+  USB_SER_DEV               *UsbSerialDevice;
+  UINTN                     Index;
+  BOOLEAN                   AllChildrenStopped;
+
+  Status = EFI_SUCCESS;
+  UsbSerialDevice = NULL;
+
+  if (NumberOfChildren == 0) {
+    //
+    // Close the driver
+    //
+    Status = gBS->CloseProtocol (
+                    Controller,
+                    &gEfiUsbIoProtocolGuid,
+                    This->DriverBindingHandle,
+                    Controller
+                    );
+    Status = gBS->CloseProtocol (
+                    Controller,
+                    &gEfiDevicePathProtocolGuid,
+                    This->DriverBindingHandle,
+                    Controller
+                    );
+    return Status;
+  }
+
+  AllChildrenStopped = TRUE;
+
+  for (Index = 0; Index < NumberOfChildren ;Index++) {
+    Status = gBS->OpenProtocol (
+                    ChildHandleBuffer[Index],
+                    &gEfiSerialIoProtocolGuid,
+                    (VOID **) &SerialIo,
+                    This->DriverBindingHandle,
+                    Controller,
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                    );
+    if (Status == EFI_SUCCESS) {//!EFI_ERROR (Status)) {
+      UsbSerialDevice = USB_SER_DEV_FROM_THIS (SerialIo);
+      Status = gBS->CloseProtocol (
+                      Controller,
+                      &gEfiUsbIoProtocolGuid,
+                      This->DriverBindingHandle,
+                      ChildHandleBuffer[Index]
+                      );
+      Status = gBS->UninstallMultipleProtocolInterfaces (
+                      ChildHandleBuffer[Index],
+                      &gEfiDevicePathProtocolGuid,
+                      UsbSerialDevice->DevicePath,
+                      &gEfiSerialIoProtocolGuid,
+                      &UsbSerialDevice->SerialIo,
+                      NULL
+                      );
+
+      if (EFI_ERROR (Status)) {
+        gBS->OpenProtocol (
+               Controller,
+               &gEfiUsbIoProtocolGuid,
+               (VOID **) &UsbIo,
+               This->DriverBindingHandle,
+               ChildHandleBuffer[Index],
+               EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+               );
+      } else {
+        if (UsbSerialDevice->DevicePath != NULL) {
+          gBS->FreePool (UsbSerialDevice->DevicePath);
+        }
+        gBS->SetTimer (
+               UsbSerialDevice->PollingLoop,
+               TimerCancel,
+               0
+               );
+        gBS->CloseEvent (UsbSerialDevice->PollingLoop);
+        UsbSerialDevice->Shutdown = TRUE;
+        FreeUnicodeStringTable (UsbSerialDevice->ControllerNameTable);
+        FreePool (UsbSerialDevice->DataBuffer);
+        FreePool (UsbSerialDevice);
+      }
+    }
+    if (EFI_ERROR (Status)) {
+      AllChildrenStopped = FALSE;
+    }
+  }
+
+  if (!AllChildrenStopped) {
+    return EFI_DEVICE_ERROR;
+  }
+  return EFI_SUCCESS;
+}
+
+//
+// Serial IO Member Functions
+//
+
+/**
+  Reset the serial device.
+
+  @param  This[in]              Protocol instance pointer.
+
+  @retval EFI_SUCCESS           The device was reset.
+  @retval EFI_DEVICE_ERROR      The serial device could not be reset.
+
+**/
+EFI_STATUS
+EFIAPI
+SerialReset (
+  IN EFI_SERIAL_IO_PROTOCOL  *This
+  )
+{
+  EFI_STATUS    Status;
+  USB_SER_DEV  *UsbSerialDevice;
+
+  UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
+  Status          = ResetInternal (UsbSerialDevice);
+  if (EFI_ERROR (Status)){
+    return EFI_DEVICE_ERROR;
+  }
+  return Status;
+}
+
+/**
+  Set the control bits on a serial device.
+
+  @param  This[in]             Protocol instance pointer.
+  @param  Control[in]          Set the bits of Control that are settable.
+
+  @retval EFI_SUCCESS          The new control bits were set on the serial device.
+  @retval EFI_UNSUPPORTED      The serial device does not support this operation.
+  @retval EFI_DEVICE_ERROR     The serial device is not functioning correctly.
+
+**/
+EFI_STATUS
+EFIAPI
+SetControlBits (
+  IN EFI_SERIAL_IO_PROTOCOL  *This,
+  IN UINT32                  Control
+  )
+{
+  EFI_STATUS    Status;
+  USB_SER_DEV   *UsbSerialDevice;
+  CONTROL_BITS  ControlBits;
+  
+  UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
+  
+  //
+  // check for invalid control parameters 
+  //
+  if ((Control & (~(EFI_SERIAL_REQUEST_TO_SEND          |
+                    EFI_SERIAL_DATA_TERMINAL_READY      |
+                    EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE |
+                    EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE |
+                    EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE))) != 0 ) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // check the control parameters and set the correct setting for
+  // the paramerts of ControlBits
+  // both loopback enables are always set to FALSE
+  //
+  ControlBits.HardwareLoopBack = FALSE;
+  ControlBits.SoftwareLoopBack = FALSE;
+  //
+  // check for hardware flow control
+  //
+  if ((Control & EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) == EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) {
+    ControlBits.HardwareFlowControl = TRUE;
+  } else {
+    ControlBits.HardwareFlowControl = FALSE;
+  }
+  //
+  // check for DTR enabled
+  //
+  if ((Control & EFI_SERIAL_DATA_TERMINAL_READY) == EFI_SERIAL_DATA_TERMINAL_READY) {
+    ControlBits.DtrState = TRUE;
+  } else {
+    ControlBits.DtrState = FALSE;
+  }
+  //
+  // check for RTS enabled
+  //
+  if ((Control & EFI_SERIAL_REQUEST_TO_SEND) == EFI_SERIAL_REQUEST_TO_SEND) {
+    ControlBits.RtsState = TRUE;
+  } else {
+    ControlBits.RtsState = FALSE;
+  }
+
+  //
+  // set the control values with a call to SetControlBitsInternal()
+  //
+  Status = SetControlBitsInternal (UsbSerialDevice, &ControlBits);
+
+  return Status;
+}
+
+/**
+  calls SetAttributesInternal() to set the baud rate, receive FIFO depth,
+  transmit/receive time out, parity, data buts, and stop bits on a serial
+  device.
+
+  @param  This[in]             Protocol instance pointer.
+  @param  BaudRate[in]         The requested baud rate. A BaudRate value of 0
+                               will use the device's default interface speed.
+  @param  ReveiveFifoDepth[in] The requested depth of the FIFO on the receive
+                               side of the serial interface. A ReceiveFifoDepth
+                               value of 0 will use the device's default FIFO
+                               depth.
+  @param  Timeout[in]          The requested time out for a single character in
+                               microseconds.This timeout applies to both the
+                               transmit and receive side of the interface. A
+                               Timeout value of 0 will use the device's default
+                               time out value.
+  @param  Parity[in]           The type of parity to use on this serial device.
+                               A Parity value of DefaultParity will use the
+                               device's default parity value.
+  @param  DataBits[in]         The number of data bits to use on the serial
+                               device. A DataBit vaule of 0 will use the
+                               device's default data bit setting.
+  @param  StopBits[in]         The number of stop bits to use on this serial
+                               device. A StopBits value of DefaultStopBits will
+                               use the device's default number of stop bits.
+
+  @retval EFI_SUCCESS          The attributes were set
+  @retval EFI_DEVICE_ERROR     The attributes were not able to be
+
+**/
+EFI_STATUS
+EFIAPI
+SetAttributes (
+  IN EFI_SERIAL_IO_PROTOCOL  *This,
+  IN UINT64                  BaudRate,
+  IN UINT32                  ReceiveFifoDepth,
+  IN UINT32                  Timeout,
+  IN EFI_PARITY_TYPE         Parity,
+  IN UINT8                   DataBits,
+  IN EFI_STOP_BITS_TYPE      StopBits
+  )
+{
+
+  EFI_STATUS   Status;
+  USB_SER_DEV  *UsbSerialDevice;
+
+  UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
+
+  Status = SetAttributesInternal (
+             UsbSerialDevice,
+             BaudRate,
+             ReceiveFifoDepth,
+             Timeout,
+             Parity,
+             DataBits,
+             StopBits
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  return Status;
+}
+
+
+/**
+  Retrieves the status of the control bits on a serial device.
+
+  @param  This[in]               Protocol instance pointer.
+  @param  Control[out]           A pointer to return the current Control signals
+                                 from the serial device.
+
+  @retval EFI_SUCCESS            The control bits were read from the serial
+                                 device.
+  @retval EFI_DEVICE_ERROR       The serial device is not functioning correctly.
+
+**/
+EFI_STATUS
+EFIAPI
+GetControlBits (
+  IN EFI_SERIAL_IO_PROTOCOL  *This,
+  OUT UINT32                 *Control
+  )
+{
+  USB_SER_DEV  *UsbSerialDevice;
+  EFI_STATUS   Status;
+
+  UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
+
+  *Control        = 0;
+
+  Status = GetControlBitsInternal (UsbSerialDevice, Control);
+
+  if (EFI_ERROR (Status)) {
+    return EFI_DEVICE_ERROR;
+  }
+  return Status;
+}
+
+/**
+  Reads data from a serial device.
+
+  @param  This[in]                   Protocol instance pointer.
+  @param  BufferSize[in, out]        On input, the size of the Buffer. On output,
+                                     the amount of data returned in Buffer.
+  @param  Buffer[out]                The buffer to return the data into.
+
+  @retval EFI_SUCCESS                The data was read.
+  @retval EFI_DEVICE_ERROR           The device reported an error.
+  @retval EFI_TIMEOUT                The data write was stopped due to a timeout.
+
+**/
+EFI_STATUS
+EFIAPI
+ReadSerialIo (
+  IN EFI_SERIAL_IO_PROTOCOL  *This,
+  IN OUT UINTN               *BufferSize,
+  OUT VOID                   *Buffer
+  )
+{
+  UINTN        Index;
+  UINTN        RemainingCallerBufferSize;
+  USB_SER_DEV  *UsbSerialDevice;
+  EFI_STATUS   Status;
+
+
+  if (*BufferSize == 0) {
+    return EFI_SUCCESS;
+  }
+
+  if (Buffer == NULL) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  Status          = EFI_SUCCESS;
+  UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
+
+  //
+  // Clear out any data that we already have in our internal buffer
+  //
+  for (Index = 0; Index < *BufferSize; Index++) {
+    if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {
+      break;
+    }
+
+    //
+    // Still have characters in the buffer to return
+    //
+    ((UINT8 *)Buffer)[Index] = UsbSerialDevice->DataBuffer[UsbSerialDevice->DataBufferHead];
+    UsbSerialDevice->DataBufferHead = (UsbSerialDevice->DataBufferHead + 1) % SW_FIFO_DEPTH;
+  }
+
+  //
+  // If we haven't filled the caller's buffer using data that we already had on
+  // hand We need to generate an additional USB request to try and fill the
+  // caller's buffer
+  //
+  if (Index != *BufferSize) {
+    RemainingCallerBufferSize = *BufferSize - Index;
+    Status = ReadDataFromUsb (
+               UsbSerialDevice,
+               &RemainingCallerBufferSize,
+               (VOID *)(((CHAR8 *)Buffer) + Index)
+               );
+    if (!EFI_ERROR (Status)) {
+      *BufferSize = RemainingCallerBufferSize + Index;
+    } else {
+      *BufferSize = Index;
+    }
+  }
+
+  if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {
+    //
+    // Data buffer has no data, set the EFI_SERIAL_INPUT_BUFFER_EMPTY flag
+    //
+    UsbSerialDevice->ControlBits |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
+  } else {
+    //
+    // There is some leftover data, clear EFI_SERIAL_INPUT_BUFFER_EMPTY flag
+    //
+    UsbSerialDevice->ControlBits &= ~(EFI_SERIAL_INPUT_BUFFER_EMPTY);
+  }
+  return Status;
+}
+
+/**
+  Writes data to a serial device.
+
+  @param  This[in]                   Protocol instance pointer.
+  @param  BufferSize[in, out]        On input, the size of the Buffer. On output,
+                                     the amount of data actually written.
+  @param  Buffer[in]                 The buffer of data to write
+
+  @retval EFI_SUCCESS                The data was written.
+  @retval EFI_DEVICE_ERROR           The device reported an error.
+  @retval EFI_TIMEOUT                The data write was stopped due to a timeout.
+
+**/
+EFI_STATUS
+EFIAPI
+WriteSerialIo (
+  IN EFI_SERIAL_IO_PROTOCOL  *This,
+  IN OUT UINTN               *BufferSize,
+  IN VOID                    *Buffer
+  )
+{
+  EFI_STATUS   Status;
+  USB_SER_DEV  *UsbSerialDevice;
+  EFI_TPL      Tpl;
+
+  UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
+
+  if (UsbSerialDevice->Shutdown) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  Tpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+  Status = UsbSerialDataTransfer (
+             UsbSerialDevice,
+             EfiUsbDataOut,
+             Buffer,
+             BufferSize,
+             FTDI_TIMEOUT
+             );
+
+  gBS->RestoreTPL (Tpl);
+  if (EFI_ERROR (Status)) {
+    if (Status == EFI_TIMEOUT){
+      return Status;
+    } else {
+      return EFI_DEVICE_ERROR;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.h b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.h
new file mode 100644
index 0000000000..6048923d6f
--- /dev/null
+++ b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.h
@@ -0,0 +1,589 @@
+/** @file
+  Header file for USB Serial Driver's Data Structures.
+
+Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.
+Portions Copyright 2012 Ashley DeSimone
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _FTDI_USB_SERIAL_DRIVER_H_
+#define _FTDI_USB_SERIAL_DRIVER_H_
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DevicePathLib.h>
+
+#include <Protocol/DevicePath.h>
+#include <Protocol/UsbIo.h>
+#include <Protocol/SerialIo.h>
+
+//
+// US English LangID
+//
+#define USB_US_LANG_ID  0x0409
+
+//
+// Supported Vendor Ids
+//
+#define VID_FTDI    0x0403
+
+//
+// Supported product ids
+//
+#define DID_FTDI_FT232    0x6001
+
+//
+// FTDI Commands
+//
+#define FTDI_COMMAND_RESET_PORT          0
+#define FTDI_COMMAND_MODEM_CTRL          1
+#define FTDI_COMMAND_SET_FLOW_CTRL       2
+#define FTDI_COMMAND_SET_BAUDRATE        3
+#define FTDI_COMMAND_SET_DATA            4
+#define FTDI_COMMAND_GET_MODEM_STATUS    5
+#define FTDI_COMMAND_SET_EVENT_CHAR      6
+#define FTDI_COMMAND_SET_ERROR_CHAR      7
+#define FTDI_COMMAND_SET_LATENCY_TIMER   9
+#define FTDI_COMMAND_GET_LATENCY_TIMER   10
+
+//
+// FTDI_PORT_IDENTIFIER
+// Used in the usb control transfers that issue FTDI commands as the index value.
+//
+#define FTDI_PORT_IDENTIFIER    0x1 // For FTDI USB serial adapter the port
+                                    // identifier is always 1.
+
+//
+// RESET_PORT
+//
+#define RESET_PORT_RESET        0x0 // Purges RX and TX, clears DTR and RTS sets
+                                    // flow control to none, disables event
+                                    // trigger, sets the event char to 0x0d and
+                                    // does nothing to baudrate or data settings
+#define RESET_PORT_PURGE_RX     0x1
+#define RESET_PORT_PURGE_TX     0x2
+
+//
+// SET_FLOW_CONTROL
+//
+#define NO_FLOW_CTRL                     0x0
+#define XON_XOFF_CTRL                    0x4
+
+//
+// SET_BAUD_RATE
+// To set baud rate, one must calculate an encoding of the baud rate from
+// UINT32 to UINT16.See EncodeBaudRateForFtdi() for details
+//
+#define FTDI_UART_FREQUENCY              3000000
+#define FTDI_MIN_DIVISOR                 0x20
+#define FTDI_MAX_DIVISOR                 0x3FFF8
+//
+// Special case baudrate values
+// 300,000 and 200,000 are special cases for calculating the encoded baudrate
+//
+#define FTDI_SPECIAL_CASE_300_MIN        (3000000 * 100) / 103 // minimum adjusted
+                                                               // value for 300,000
+#define FTDI_SPECIAL_CASE_300_MAX        (3000000 * 100) / 97  // maximum adjusted
+                                                               // value for 300,000
+#define FTDI_SPECIAL_CASE_200_MIN        (2000000 * 100) / 103 // minimum adjusted
+                                                               // value for 200,000
+#define FTDI_SPECIAL_CASE_200_MAX        (2000000 * 100) / 97  // maximum adjusted
+                                                               // value for 200,000
+//
+// Min and max frequency values that the FTDI chip can attain
+//.all generated frequencies must be between these values
+//
+#define FTDI_MIN_FREQUENCY              46601941 // (3MHz * 1600) / 103 = 46601941
+#define FTDI_MAX_FREQUENCY              49484536 // (3MHz * 1600) / 97 = 49484536
+
+//
+// SET_DATA_BITS
+//
+#define SET_DATA_BITS(n)                 (n)
+
+//
+// SET_PARITY
+//
+#define SET_PARITY_NONE                   0x0
+#define SET_PARITY_ODD                    BIT8 // (0x1 << 8)
+#define SET_PARITY_EVEN                   BIT9 // (0x2 << 8)
+#define SET_PARITY_MARK                   BIT9 | BIT8 // (0x3 << 8)
+#define SET_PARITY_SPACE                  BIT10 // (0x4 << 8)
+
+//
+// SET_STOP_BITS
+//
+#define SET_STOP_BITS_1                   0x0
+#define SET_STOP_BITS_15                  BIT11 // (0x1 << 11)
+#define SET_STOP_BITS_2                   BIT12 // (0x2 << 11)
+
+//
+// SET_MODEM_CTRL
+// SET_DTR_HIGH = (1 | (1 << 8)), SET_DTR_LOW = (0 | (1 << 8)
+// SET_RTS_HIGH = (2 | (2 << 8)), SET_RTS_LOW = (0 | (2 << 8)
+//
+#define SET_DTR_HIGH                     (BIT8 | BIT0)
+#define SET_DTR_LOW                      (BIT8)
+#define SET_RTS_HIGH                     (BIT9 | BIT1)
+#define SET_RTS_LOW                      (BIT9)
+
+//
+// MODEM_STATUS
+//
+#define CTS_MASK                         BIT4
+#define DSR_MASK                         BIT5
+#define RI_MASK                          BIT6
+#define SD_MASK                          BIT7
+#define MSR_MASK                         (CTS_MASK | DSR_MASK | RI_MASK | SD_MASK)
+
+//
+// Macro used to check for USB transfer errors
+//
+#define USB_IS_ERROR(Result, Error)           (((Result) & (Error)) != 0)
+
+//
+// USB request timeouts
+//
+#define WDR_TIMEOUT        5000  // default urb timeout in ms
+#define WDR_SHORT_TIMEOUT  1000  // shorter urb timeout in ms
+
+//
+// FTDI timeout
+//
+#define FTDI_TIMEOUT       16
+
+//
+// FTDI FIFO depth
+//
+#define FTDI_MAX_RECEIVE_FIFO_DEPTH  384
+
+//
+// FTDI Endpoint Descriptors
+//
+#define FTDI_ENDPOINT_ADDRESS_IN   0x81 //the endpoint address for the in enpoint generated by the device
+#define FTDI_ENDPOINT_ADDRESS_OUT  0x02 //the endpoint address for the out endpoint generated by the device
+
+//
+// Max buffer size for USB transfers
+//
+#define SW_FIFO_DEPTH 1024
+
+//
+// struct to define a usb device as a vendor and product id pair
+//
+typedef struct {
+  UINTN     VendorId;
+  UINTN     DeviceId;
+} USB_DEVICE;
+
+//
+//struct to describe the control bits of the device
+//true indicates enabled
+//false indicates disabled
+// 
+typedef struct {
+  BOOLEAN    HardwareFlowControl;
+  BOOLEAN    DtrState;
+  BOOLEAN    RtsState;
+  BOOLEAN    HardwareLoopBack;
+  BOOLEAN    SoftwareLoopBack;
+} CONTROL_BITS;
+
+//
+//struct to describe the status bits of the device 
+//true indicates enabled
+//false indicated disabled
+//
+typedef struct {
+  BOOLEAN    CtsState;
+  BOOLEAN    DsrState;
+  BOOLEAN    RiState;
+  BOOLEAN    SdState;
+} STATUS_BITS;
+
+//
+// Structure to describe the last attributes of the Usb Serial device
+//
+typedef struct {
+  UINT64              BaudRate;
+  UINT32              ReceiveFifoDepth;
+  UINT32              Timeout;
+  EFI_PARITY_TYPE     Parity;
+  UINT8               DataBits;
+  EFI_STOP_BITS_TYPE  StopBits;
+} PREVIOUS_ATTRIBUTES;
+
+//
+// Structure to describe USB serial device
+//
+#define USB_SER_DEV_SIGNATURE  SIGNATURE_32 ('u', 's', 'b', 's')
+
+typedef struct {
+  UINTN                         Signature;
+  EFI_HANDLE                    ControllerHandle;
+  EFI_DEVICE_PATH_PROTOCOL      *DevicePath;
+  EFI_DEVICE_PATH_PROTOCOL      *ParentDevicePath;
+  UART_DEVICE_PATH              UartDevicePath;
+  UART_FLOW_CONTROL_DEVICE_PATH FlowControlDevicePath;
+  EFI_USB_IO_PROTOCOL           *UsbIo;
+  EFI_USB_INTERFACE_DESCRIPTOR  InterfaceDescriptor;
+  EFI_USB_ENDPOINT_DESCRIPTOR   InEndpointDescriptor;
+  EFI_USB_ENDPOINT_DESCRIPTOR   OutEndpointDescriptor;
+  EFI_UNICODE_STRING_TABLE      *ControllerNameTable;
+  UINT32                        DataBufferHead;
+  UINT32                        DataBufferTail;
+  UINT8                         *DataBuffer;
+  EFI_SERIAL_IO_PROTOCOL        SerialIo;
+  BOOLEAN                       Shutdown;
+  EFI_EVENT                     PollingLoop;
+  UINT32                        ControlBits;
+  PREVIOUS_ATTRIBUTES           LastSettings;
+  CONTROL_BITS                  ControlValues;
+  STATUS_BITS                   StatusValues;
+  UINT8                         ReadBuffer[512];
+} USB_SER_DEV;
+
+#define USB_SER_DEV_FROM_THIS(a) \
+  CR(a, USB_SER_DEV, SerialIo, USB_SER_DEV_SIGNATURE)
+
+//
+// Global Variables
+//
+extern EFI_DRIVER_BINDING_PROTOCOL   gUsbSerialDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL   gUsbSerialComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL  gUsbSerialComponentName2;
+
+//
+// Functions of Driver Binding Protocol
+//
+/**
+  Check whether USB Serial driver supports this device.
+
+  @param  This[in]                   The USB Serial driver binding protocol.
+  @param  Controller[in]             The controller handle to check.
+  @param  RemainingDevicePath[in]    The remaining device path.
+
+  @retval EFI_SUCCESS                The driver supports this controller.
+  @retval other                      This device isn't supported.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbSerialDriverBindingSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  );
+
+/**
+  Starts the Serial device with this driver.
+
+  This function produces Serial IO Protocol and initializes the USB
+  Serial device to manage this USB Serial device.
+
+  @param  This[in]                   The USB Serial driver binding instance.
+  @param  Controller[in]             Handle of device to bind driver to.
+  @param  RemainingDevicePath[in]    Optional parameter use to pick a specific
+                                     child device to start.
+
+  @retval EFI_SUCCESS                The controller is controlled by the USB
+                                     Serial driver.
+  @retval EFI_UNSUPPORTED            No interrupt endpoint can be found.
+  @retval Other                      This controller cannot be started.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbSerialDriverBindingStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  );
+
+/**
+  Stop the USB Serial device handled by this driver.
+
+  @param  This[in]                   The USB Serial driver binding protocol.
+  @param  Controller[in]             The controller to release.
+  @param  NumberOfChildren[in]       The number of handles in ChildHandleBuffer.
+  @param  ChildHandleBuffer[in]      The array of child handle.
+
+  @retval EFI_SUCCESS                The device was stopped.
+  @retval EFI_UNSUPPORTED            Simple Text In Protocol or Simple Text In Ex
+                                     Protocol is not installed on Controller.
+  @retval EFI_DEVICE_ERROR           The device could not be stopped due to a
+                                     device error.
+  @retval Others                     Fail to uninstall protocols attached on the
+                                     device.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbSerialDriverBindingStop (
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN  EFI_HANDLE                   Controller,
+  IN  UINTN                        NumberOfChildren,
+  IN  EFI_HANDLE                   *ChildHandleBuffer
+  );
+
+//
+// Serial IO Member Functions
+//
+
+/**
+  Writes data to a serial device.
+
+  @param  This[in]                   Protocol instance pointer.
+  @param  BufferSize[in, out]        On input, the size of the Buffer. On output,
+                                     the amount of data actually written.
+  @param  Buffer[in]                 The buffer of data to write
+
+  @retval EFI_SUCCESS                The data was written.
+  @retval EFI_DEVICE_ERROR           The device reported an error.
+  @retval EFI_TIMEOUT                The data write was stopped due to a timeout.
+
+**/
+EFI_STATUS
+EFIAPI
+WriteSerialIo (
+  IN EFI_SERIAL_IO_PROTOCOL  *This,
+  IN OUT UINTN               *BufferSize,
+  IN VOID                    *Buffer
+  );
+
+/**
+  Reads data from a serial device.
+
+  @param  This[in]                   Protocol instance pointer.
+  @param  BufferSize[in, out]        On input, the size of the Buffer. On output,
+                                     the amount of data returned in Buffer.
+  @param  Buffer[out]                The buffer to return the data into.
+
+  @retval EFI_SUCCESS                The data was read.
+  @retval EFI_DEVICE_ERROR           The device reported an error.
+  @retval EFI_TIMEOUT                The data write was stopped due to a timeout.
+
+**/
+EFI_STATUS
+EFIAPI
+ReadSerialIo (
+  IN EFI_SERIAL_IO_PROTOCOL  *This,
+  IN OUT UINTN               *BufferSize,
+  OUT VOID                   *Buffer
+  );
+
+/**
+  Retrieves the status of the control bits on a serial device.
+
+  @param  This[in]               Protocol instance pointer.
+  @param  Control[out]           A pointer to return the current Control signals
+                                 from the serial device.
+
+  @retval EFI_SUCCESS            The control bits were read from the serial
+                                 device.
+  @retval EFI_DEVICE_ERROR       The serial device is not functioning correctly.
+
+**/
+EFI_STATUS
+EFIAPI
+GetControlBits (
+  IN EFI_SERIAL_IO_PROTOCOL  *This,
+  OUT UINT32                 *Control
+  );
+
+/**
+  Set the control bits on a serial device.
+
+  @param  This[in]             Protocol instance pointer.
+  @param  Control[in]          Set the bits of Control that are settable.
+
+  @retval EFI_SUCCESS          The new control bits were set on the serial device.
+  @retval EFI_UNSUPPORTED      The serial device does not support this operation.
+  @retval EFI_DEVICE_ERROR     The serial device is not functioning correctly.
+
+**/
+EFI_STATUS
+EFIAPI
+SetControlBits (
+  IN EFI_SERIAL_IO_PROTOCOL  *This,
+  IN UINT32                  Control
+  );
+
+/**
+  Calls SetAttributesInternal() to set the baud rate, receive FIFO depth,
+  transmit/receice time out, parity, data buts, and stop bits on a serial device.
+
+  @param  This[in]             Protocol instance pointer.
+  @param  BaudRate[in]         The requested baud rate. A BaudRate value of 0
+                               will use the device's default interface speed.
+  @param  ReveiveFifoDepth[in] The requested depth of the FIFO on the receive
+                               side of the serial interface. A ReceiveFifoDepth
+                               value of 0 will use the device's default FIFO
+                               depth.
+  @param  Timeout[in]          The requested time out for a single character in
+                               microseconds.This timeout applies to both the
+                               transmit and receive side of the interface.A
+                               Timeout value of 0 will use the device's default
+                               time out value.
+  @param  Parity[in]           The type of parity to use on this serial device.A
+                               Parity value of DefaultParity will use the
+                               device's default parity value.
+  @param  DataBits[in]         The number of data bits to use on the serial
+                               device. A DataBits value of 0 will use the
+                               device's default data bit setting.
+  @param  StopBits[in]         The number of stop bits to use on this serial
+                               device. A StopBits value of DefaultStopBits will
+                               use the device's default number of stop bits.
+
+  @retval EFI_SUCCESS          The attributes were set
+  @retval EFI_DEVICE_ERROR     The attributes were not able to be
+
+**/
+EFI_STATUS
+EFIAPI
+SetAttributes (
+  IN EFI_SERIAL_IO_PROTOCOL  *This,
+  IN UINT64                  BaudRate,
+  IN UINT32                  ReceiveFifoDepth,
+  IN UINT32                  Timeout,
+  IN EFI_PARITY_TYPE         Parity,
+  IN UINT8                   DataBits,
+  IN EFI_STOP_BITS_TYPE      StopBits
+  );
+
+/**
+  Reset the serial device.
+
+  @param  This              Protocol instance pointer.
+
+  @retval EFI_SUCCESS       The device was reset.
+  @retval EFI_DEVICE_ERROR  The serial device could not be reset.
+
+**/
+EFI_STATUS
+EFIAPI
+SerialReset (
+  IN EFI_SERIAL_IO_PROTOCOL  *This
+  );
+
+//
+// EFI Component Name Functions
+//
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]                   A pointer to the EFI_COMPONENT_NAME2_PROTOCOL
+                                     or EFI_COMPONENT_NAME_PROTOCOL instance.
+  @param  Language[in]               A pointer to a Null-terminated ASCII string
+                                     array indicating the language. This is the
+                                     language of the driver name that the caller
+                                     is requesting, and it must match one of the
+                                     languages specified in SupportedLanguages.
+                                     The number of languages supported by a
+                                     driver is up to the driver writer. Language
+                                     is specified in RFC 4646 or ISO 639-2
+                                     language code format.
+  @param  DriverName[out]            A pointer to the Unicode string to return.
+                                     This Unicode string is the name of the
+                                     driver specified by This in the language
+                                     specified by Language.
+
+  @retval EFI_SUCCESS                The Unicode string for the Driver specified
+                                     by This and the language specified by
+                                     Language was returned in DriverName.
+  @retval EFI_INVALID_PARAMETER      Language is NULL.
+  @retval EFI_INVALID_PARAMETER      DriverName is NULL.
+  @retval EFI_UNSUPPORTED            The driver specified by This does not
+                                     support the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbSerialComponentNameGetDriverName (
+  IN  EFI_COMPONENT_NAME2_PROTOCOL  *This,
+  IN  CHAR8                         *Language,
+  OUT CHAR16                        **DriverName
+  );
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]                   A pointer to the EFI_COMPONENT_NAME2_PROTOCOL
+                                     or EFI_COMPONENT_NAME_PROTOCOL instance.
+  @param  ControllerHandle[in]       The handle of a controller that the driver
+                                     specified by This is managing.  This handle
+                                     specifies the controller whose name is to
+                                     be returned.
+  @param  ChildHandle[in]            The handle of the child controller to
+                                     retrieve the name of. This is an optional
+                                     parameter that may be NULL. It will be NULL
+                                     for device drivers. It will also be NULL
+                                     for a bus drivers that wish to retrieve the
+                                     name of the bus controller. It will not be
+                                     NULL for a bus driver that wishes to
+                                     retrieve the name of a child controller.
+  @param  Language[in]               A pointer to a Null-terminated ASCII string
+                                     array indicating the language.  This is the
+                                     language of the driver name that the caller
+                                     is requesting, and it must match one of the
+                                     languages specified in SupportedLanguages.
+                                     The number of languages supported by a
+                                     driver is up to the driver writer. Language
+                                     is specified in RFC 4646 or ISO 639-2
+                                     language code format.
+  @param  ControllerName[out]        A pointer to the Unicode string to return.
+                                     This Unicode string is the name of the
+                                     controller specified by ControllerHandle
+                                     and ChildHandle in the language specified
+                                     by Language from the point of view of the
+                                     driver specified by This.
+
+  @retval EFI_SUCCESS                The Unicode string for the user readable
+                                     name in the language specified by Language
+                                     for the driver specified by This was
+                                     returned in DriverName.
+  @retval EFI_INVALID_PARAMETER      ControllerHandle is not a valid EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER      ChildHandle is not NULL and it is not a
+                                     valid EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER      Language is NULL.
+  @retval EFI_INVALID_PARAMETER      ControllerName is NULL.
+  @retval EFI_UNSUPPORTED            The driver specified by This is not
+                                     currently managing the controller specified
+                                     by ControllerHandle and ChildHandle.
+  @retval EFI_UNSUPPORTED            The driver specified by This does not
+                                     support the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbSerialComponentNameGetControllerName (
+  IN  EFI_COMPONENT_NAME2_PROTOCOL  *This,
+  IN  EFI_HANDLE                    ControllerHandle,
+  IN  EFI_HANDLE                    ChildHandle      OPTIONAL,
+  IN  CHAR8                         *Language,
+  OUT CHAR16                        **ControllerName
+  );
+
+#endif
diff --git a/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf
new file mode 100644
index 0000000000..67c1d36470
--- /dev/null
+++ b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf
@@ -0,0 +1,55 @@
+## @file
+#  USB Serial Driver that manages USB Serial device and produces Serial IO
+#  Protocol.
+#
+#  USB Serial Driver consumes USB I/O Protocol and Device Path Protocol, and
+#  produces Serial IO Protocol on USB Serial devices.
+#  It manages the USB Serial device via USB Bulk Transfer of USB I/O Protocol.
+#  This module refers to following specifications:
+#  1. UEFI Specification, v2.1
+#
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = FtdiUsbSerialDxe
+  FILE_GUID                      = A8154B55-2021-4D40-AE81-2E23A02dCC46
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = FtdiUsbSerialEntryPoint
+  UNLOAD_IMAGE                   = FtdiUsbSerialUnload
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  FtdiUsbSerialDriver.c
+  FtdiUsbSerialDriver.h
+  ComponentName.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  BaseMemoryLib
+  DebugLib
+  MemoryAllocationLib
+  UefiBootServicesTableLib
+  UefiLib
+  DevicePathLib
+
+[Guids]
+  gEfiUartDevicePathGuid
+
+[Protocols]
+  ## TO_START
+  ## BY_START
+  gEfiDevicePathProtocolGuid
+  gEfiUsbIoProtocolGuid                         ## TO_START
+  gEfiSerialIoProtocolGuid                      ## BY_START
diff --git a/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt
new file mode 100644
index 0000000000..d8ca227a41
--- /dev/null
+++ b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt
@@ -0,0 +1,32 @@
+
+=== FTDI USB SERIAL OVERVIEW ===
+
+This is a bus driver that enables the EfiSerialIoProtocol interface
+for FTDI8U232AM based USB-to-Serial adapters.
+
+=== STATUS ===
+
+Serial Input: Functional on real hardware.
+Serial Output: Functional on real hardware.
+
+Operating Modes: Currently the user is able to change all operating modes
+except timeout and FIFO depth.
+The default operating mode is:
+	Baudrate:     115200
+	Parity:       None
+	Flow Control: None
+	Data Bits:    8
+	Stop Bits:    1
+Notes: 
+	Data Bits setting of 6,7,8 can not be combined with a Stop Bits setting of 1.5
+
+        At baudrates less than 9600 some of the characters may be transmitted incorrectly.
+
+=== COMPATIBILITY ===
+
+Tested with:
+An FTDI8U232AM based USB-To-Serial adapter, the UEFI Shell, and the SerialTest application 
+using a PuTTY Terminal
+
+See CompatibleDevices.txt for a list of devices which have been confirmed to work with this 
+driver.
\ No newline at end of file
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.c b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.c
new file mode 100644
index 0000000000..c9329f506d
--- /dev/null
+++ b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.c
@@ -0,0 +1,1318 @@
+/** @file
+  Implement the interface to the AX88772 Ethernet controller.
+
+  This module implements the interface to the ASIX AX88772
+  USB to Ethernet MAC with integrated 10/100 PHY.  Note that this implementation
+  only supports the integrated PHY since no other test cases were available.
+
+  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Ax88772.h"
+
+
+/**
+  Compute the CRC
+
+  @param [in] pMacAddress      Address of a six byte buffer to containing the MAC address.
+
+  @returns The CRC-32 value associated with this MAC address
+
+**/
+UINT32
+Ax88772Crc (
+  IN UINT8 * pMacAddress
+  )
+{
+  UINT32 BitNumber;
+  INT32 Carry;
+  INT32 Crc;
+  UINT32 Data;
+  UINT8 * pEnd;
+
+  DBG_ENTER ( );
+
+  //
+  //  Walk the MAC address
+  //
+  Crc = -1;
+  pEnd = &pMacAddress[ PXE_HWADDR_LEN_ETHER ];
+  while ( pEnd > pMacAddress ) {
+    Data = *pMacAddress++;
+    
+    
+    //
+    //  CRC32: x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
+    //
+    //          1 0000 0100 1100 0001 0001 1101 1011 0111
+    //
+    for ( BitNumber = 0; 8 > BitNumber; BitNumber++ ) {
+      Carry = (( Crc >> 31 ) & 1 ) ^ ( Data & 1 );
+      Crc <<= 1;
+      if ( 0 != Carry ) {
+        Crc ^= 0x04c11db7;
+      }
+      Data >>= 1;
+    }
+  }
+
+  //
+  //  Return the CRC value
+  //
+  DBG_EXIT_HEX ( Crc );
+  return (UINT32) Crc;
+}
+
+
+/**
+  Get the MAC address
+
+  This routine calls ::Ax88772UsbCommand to request the MAC
+  address from the network adapter.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [out] pMacAddress      Address of a six byte buffer to receive the MAC address.
+
+  @retval EFI_SUCCESS          The MAC address is available.
+  @retval other                The MAC address is not valid.
+
+**/
+EFI_STATUS
+Ax88772MacAddressGet (
+  IN NIC_DEVICE * pNicDevice,
+  OUT UINT8 * pMacAddress
+  )
+{
+  USB_DEVICE_REQUEST SetupMsg;
+  EFI_STATUS Status;
+  
+  DBG_ENTER ( );
+  
+  //
+  //  Set the register address.
+  //
+  SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
+                       | USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_MAC_ADDRESS_READ;
+  SetupMsg.Value = 0;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = PXE_HWADDR_LEN_ETHER;
+
+  //
+  //  Read the PHY register
+  //
+  Status = Ax88772UsbCommand ( pNicDevice,
+                               &SetupMsg,
+                               pMacAddress );
+
+  //
+  // Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Set the MAC address
+
+  This routine calls ::Ax88772UsbCommand to set the MAC address
+  in the network adapter.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] pMacAddress      Address of a six byte buffer to containing the new MAC address.
+
+  @retval EFI_SUCCESS          The MAC address was set.
+  @retval other                The MAC address was not set.
+
+**/
+EFI_STATUS
+Ax88772MacAddressSet (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT8 * pMacAddress
+  )
+{
+  USB_DEVICE_REQUEST SetupMsg;
+  EFI_STATUS Status;
+  
+  DBG_ENTER ( );
+  
+  //
+  //  Set the register address.
+  //
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_MAC_ADDRESS_WRITE;
+  SetupMsg.Value = 0;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = PXE_HWADDR_LEN_ETHER;
+  
+  //
+  //  Read the PHY register
+  //
+  Status = Ax88772UsbCommand ( pNicDevice,
+                               &SetupMsg,
+                               pMacAddress );
+  
+  //
+  // Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Clear the multicast hash table
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+
+**/
+VOID
+Ax88772MulticastClear (
+  IN NIC_DEVICE * pNicDevice
+  )
+{
+  DBG_ENTER ( );
+
+  //
+  // Clear the multicast hash table
+  //
+  pNicDevice->MulticastHash[0] = 0;
+  pNicDevice->MulticastHash[1] = 0;
+
+  DBG_EXIT ( );
+}
+
+
+/**
+  Enable a multicast address in the multicast hash table
+
+  This routine calls ::Ax88772Crc to compute the hash bit for
+  this MAC address.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] pMacAddress      Address of a six byte buffer to containing the MAC address.
+
+**/
+VOID
+Ax88772MulticastSet (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT8 * pMacAddress
+  )
+{
+  UINT32 BitNumber;
+  UINT32 Crc;
+  UINT32 Mask;
+
+  DBG_ENTER ( );
+
+  //
+  //  Compute the CRC on the destination address
+  //
+  Crc = Ax88772Crc ( pMacAddress );
+
+  //
+  //  Set the bit corresponding to the destination address
+  //
+  BitNumber = Crc >> 26;
+  if ( 32 > BitNumber ) {
+    Mask = 1 << BitNumber;
+    pNicDevice->MulticastHash[0] |= Mask;
+  }
+  else {
+    Mask = 1 << ( BitNumber - 32 );
+    pNicDevice->MulticastHash[1] |= Mask;
+  }
+
+  //
+  //  Display the multicast address
+  //
+  DEBUG (( DEBUG_RX_MULTICAST | DEBUG_INFO,
+            "Enable multicast: 0x%02x-%02x-%02x-%02x-%02x-%02x, CRC: 0x%08x, Bit number: 0x%02x\r\n",
+            pMacAddress[0],
+            pMacAddress[1],
+            pMacAddress[2],
+            pMacAddress[3],
+            pMacAddress[4],
+            pMacAddress[5],
+            Crc,
+            BitNumber ));
+
+  DBG_EXIT ( );
+}
+
+
+/**
+  Start the link negotiation
+
+  This routine calls ::Ax88772PhyWrite to start the PHY's link
+  negotiation.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+
+  @retval EFI_SUCCESS          The link negotiation was started.
+  @retval other                Failed to start the link negotiation.
+
+**/
+EFI_STATUS
+Ax88772NegotiateLinkStart (
+  IN NIC_DEVICE * pNicDevice
+  )
+{
+  UINT16 Control;
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  // Set the supported capabilities.
+  //
+  Status = Ax88772PhyWrite ( pNicDevice,
+                             PHY_ANAR,
+                             AN_CSMA_CD
+                             | AN_TX_FDX | AN_TX_HDX
+                             | AN_10_FDX | AN_10_HDX );
+  if ( !EFI_ERROR ( Status )) {
+    //
+    // Set the link speed and duplex
+    //
+    Control = BMCR_AUTONEGOTIATION_ENABLE
+            | BMCR_RESTART_AUTONEGOTIATION;
+    if ( pNicDevice->b100Mbps ) {
+      Control |= BMCR_100MBPS;
+    }
+    if ( pNicDevice->bFullDuplex ) {
+      Control |= BMCR_FULL_DUPLEX;
+    }
+    Status = Ax88772PhyWrite ( pNicDevice, PHY_BMCR, Control );
+  }
+
+  //
+  // Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Complete the negotiation of the PHY link
+
+  This routine calls ::Ax88772PhyRead to determine if the
+  link negotiation is complete.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in, out] pPollCount  Address of number of times this routine was polled
+  @param [out] pbComplete      Address of boolean to receive complate status.
+  @param [out] pbLinkUp        Address of boolean to receive link status, TRUE=up.
+  @param [out] pbHiSpeed       Address of boolean to receive link speed, TRUE=100Mbps.
+  @param [out] pbFullDuplex    Address of boolean to receive link duplex, TRUE=full.
+
+  @retval EFI_SUCCESS          The MAC address is available.
+  @retval other                The MAC address is not valid.
+
+**/
+EFI_STATUS
+Ax88772NegotiateLinkComplete (
+  IN NIC_DEVICE * pNicDevice,
+  IN OUT UINTN * pPollCount,
+  OUT BOOLEAN * pbComplete,
+  OUT BOOLEAN * pbLinkUp,
+  OUT BOOLEAN * pbHiSpeed,
+  OUT BOOLEAN * pbFullDuplex
+  )
+{
+  UINT16 Mask;
+  UINT16 PhyData;
+  EFI_STATUS  Status;
+
+  DBG_ENTER ( );
+  
+  //
+  //  Determine if the link is up.
+  //
+  *pbComplete = FALSE;
+
+  //
+  //  Get the link status
+  //
+  Status = Ax88772PhyRead ( pNicDevice,
+                            PHY_BMSR,
+                            &PhyData );
+  if ( !EFI_ERROR ( Status )) {
+    //
+    //  Determine if the autonegotiation is complete.
+    //
+    *pbLinkUp = (BOOLEAN)( 0 != ( PhyData & BMSR_LINKST ));
+    *pbComplete = *pbLinkUp;
+    if ( 0 != *pbComplete ) {
+      //
+      //  Get the partners capabilities.
+      //
+      Status = Ax88772PhyRead ( pNicDevice,
+                                PHY_ANLPAR,
+                                &PhyData );
+      if ( !EFI_ERROR ( Status )) {
+        //
+        //  Autonegotiation is complete
+        //  Determine the link speed.
+        //
+        *pbHiSpeed = (BOOLEAN)( 0 != ( PhyData & ( AN_TX_FDX | AN_TX_HDX )));
+
+        //
+        //  Determine the link duplex.
+        //
+        Mask = ( *pbHiSpeed ) ? AN_TX_FDX : AN_10_FDX;
+        *pbFullDuplex = (BOOLEAN)( 0 != ( PhyData & Mask ));
+      }
+    }
+  }
+
+  //
+  // Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Read a register from the PHY
+
+  This routine calls ::Ax88772UsbCommand to read a PHY register.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] RegisterAddress  Number of the register to read.
+  @param [in, out] pPhyData    Address of a buffer to receive the PHY register value
+
+  @retval EFI_SUCCESS          The PHY data is available.
+  @retval other                The PHY data is not valid.
+
+**/
+EFI_STATUS
+Ax88772PhyRead (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT8 RegisterAddress,
+  IN OUT UINT16 * pPhyData
+  )
+{
+  USB_DEVICE_REQUEST SetupMsg;
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  //  Request access to the PHY
+  //
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_PHY_ACCESS_SOFTWARE;
+  SetupMsg.Value = 0;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand ( pNicDevice,
+                               &SetupMsg,
+                               NULL );
+  if ( !EFI_ERROR ( Status )) {
+    //
+    //  Read the PHY register address.
+    //
+    SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
+                         | USB_REQ_TYPE_VENDOR
+                         | USB_TARGET_DEVICE;
+    SetupMsg.Request = CMD_PHY_REG_READ;
+    SetupMsg.Value = pNicDevice->PhyId;
+    SetupMsg.Index = RegisterAddress;
+    SetupMsg.Length = sizeof ( *pPhyData );
+    Status = Ax88772UsbCommand ( pNicDevice,
+                                 &SetupMsg,
+                                 pPhyData );
+    if ( !EFI_ERROR ( Status )) {
+      DEBUG (( DEBUG_PHY | DEBUG_INFO,
+                "PHY %d: 0x%02x --> 0x%04x\r\n",
+                pNicDevice->PhyId,
+                RegisterAddress,
+                *pPhyData ));
+
+      //
+      //  Release the PHY to the hardware
+      //
+      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                           | USB_TARGET_DEVICE;
+      SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
+      SetupMsg.Value = 0;
+      SetupMsg.Index = 0;
+      SetupMsg.Length = 0;
+      Status = Ax88772UsbCommand ( pNicDevice,
+                                   &SetupMsg,
+                                   NULL );
+    }
+  }
+
+  //
+  //  Return the operation status.
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Write to a PHY register
+
+  This routine calls ::Ax88772UsbCommand to write a PHY register.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] RegisterAddress  Number of the register to read.
+  @param [in] PhyData          Address of a buffer to receive the PHY register value
+
+  @retval EFI_SUCCESS          The PHY data was written.
+  @retval other                Failed to wwrite the PHY register.
+
+**/
+EFI_STATUS
+Ax88772PhyWrite (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT8 RegisterAddress,
+  IN UINT16 PhyData
+  )
+{
+  USB_DEVICE_REQUEST SetupMsg;
+  EFI_STATUS Status;
+  
+  DBG_ENTER ( );
+  
+  //
+  //  Request access to the PHY
+  //
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_PHY_ACCESS_SOFTWARE;
+  SetupMsg.Value = 0;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand ( pNicDevice,
+                               &SetupMsg,
+                               NULL );
+  if ( !EFI_ERROR ( Status )) {
+    //
+    //  Write the PHY register
+    //
+    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                         | USB_TARGET_DEVICE;
+    SetupMsg.Request = CMD_PHY_REG_WRITE;
+    SetupMsg.Value = pNicDevice->PhyId;
+    SetupMsg.Index = RegisterAddress;
+    SetupMsg.Length = sizeof ( PhyData );
+    Status = Ax88772UsbCommand ( pNicDevice,
+                                 &SetupMsg,
+                                 &PhyData );
+    if ( !EFI_ERROR ( Status )) {
+      DEBUG (( DEBUG_PHY | DEBUG_INFO,
+                "PHY %d: 0x%02x <-- 0x%04x\r\n",
+                pNicDevice->PhyId,
+                RegisterAddress,
+                PhyData ));
+
+      //
+      //  Release the PHY to the hardware
+      //
+      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                           | USB_TARGET_DEVICE;
+      SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
+      SetupMsg.Value = 0;
+      SetupMsg.Index = 0;
+      SetupMsg.Length = 0;
+      Status = Ax88772UsbCommand ( pNicDevice,
+                                   &SetupMsg,
+                                   NULL );
+    }
+  }
+
+  //
+  //  Return the operation status.
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Reset the AX88772
+
+  This routine uses ::Ax88772UsbCommand to reset the network
+  adapter.  This routine also uses ::Ax88772PhyWrite to reset
+  the PHY.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+
+  @retval EFI_SUCCESS          The MAC address is available.
+  @retval other                The MAC address is not valid.
+
+**/
+EFI_STATUS
+Ax88772Reset (
+  IN NIC_DEVICE * pNicDevice
+  )
+{
+  USB_DEVICE_REQUEST SetupMsg;
+  EFI_STATUS Status;
+  
+  DBG_ENTER ( );
+
+  //
+  //  Turn off the MAC
+  //
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_RX_CONTROL_WRITE;
+  SetupMsg.Value = 0;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand ( pNicDevice,
+                               &SetupMsg,
+                               NULL );
+  if ( !EFI_ERROR ( Status )) {
+    DEBUG (( DEBUG_PHY | DEBUG_RX_BROADCAST | DEBUG_RX_MULTICAST
+              | DEBUG_RX_UNICAST | DEBUG_TX | DEBUG_INFO,
+              "MAC reset\r\n" ));
+
+    //
+    //  The link is now idle
+    //
+    pNicDevice->bLinkIdle = TRUE;
+
+    //
+    //  Delay for a bit
+    //
+    gBS->Stall ( RESET_MSEC );
+
+    //
+    //  Select the internal PHY
+    //
+    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                         | USB_TARGET_DEVICE;
+    SetupMsg.Request = CMD_PHY_SELECT;
+    SetupMsg.Value = SPHY_PSEL;
+    SetupMsg.Index = 0;
+    SetupMsg.Length = 0;
+    Status = Ax88772UsbCommand ( pNicDevice,
+                                 &SetupMsg,
+                                 NULL );
+    if ( !EFI_ERROR ( Status )) {
+      //
+      //  Delay for a bit
+      //
+      gBS->Stall ( PHY_RESET_MSEC );
+
+      //
+      //  Clear the internal PHY reset
+      //
+      SetupMsg.Request = CMD_RESET;
+      SetupMsg.Value = SRR_IPRL | SRR_PRL;
+      Status = Ax88772UsbCommand ( pNicDevice,
+                                   &SetupMsg,
+                                   NULL );
+      if ( !EFI_ERROR ( Status )) {
+        //
+        //  Reset the PHY
+        //
+        Status = Ax88772PhyWrite ( pNicDevice,
+                                   PHY_BMCR,
+                                   BMCR_RESET );
+        if ( !EFI_ERROR ( Status )) {
+          //
+          //  Set the gaps
+          //
+          SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                               | USB_TARGET_DEVICE;
+          SetupMsg.Request = CMD_GAPS_WRITE;
+          SetupMsg.Value = 0x0c15;
+          SetupMsg.Index = 0x0e;
+          SetupMsg.Length = 0;
+          Status = Ax88772UsbCommand ( pNicDevice,
+                                       &SetupMsg,
+                                       NULL );
+        }
+      }
+    }
+  }
+
+  //
+  //  Return the operation status.
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+VOID 
+FillPkt2Queue (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINTN BufLength)
+{
+
+  UINT16 * pLength;
+  UINT16 * pLengthBar;
+  UINT8* pData;
+  UINT32 offset;
+  RX_TX_PACKET * pRxPacket;
+  EFI_STATUS Status;
+  
+  for ( offset = 0; offset < BufLength; ){
+    pLength = (UINT16*) (pNicDevice->pBulkInBuff + offset);
+    pLengthBar = (UINT16*) (pNicDevice->pBulkInBuff + offset +2);
+    
+    *pLength &= 0x7ff;
+    *pLengthBar &= 0x7ff;
+    *pLengthBar |= 0xf800;
+      
+    if ((*pLength ^ *pLengthBar ) != 0xFFFF) {
+      DEBUG (( EFI_D_ERROR , "Pkt length error. BufLength = %d\n", BufLength));
+      return;
+    }
+      
+    pRxPacket = pNicDevice->pRxFree;
+    if ( NULL == pRxPacket ) {
+      Status = gBS->AllocatePool ( EfiRuntimeServicesData,
+                                   sizeof( RX_TX_PACKET ),
+                                   (VOID **) &pRxPacket );
+      if ( !EFI_ERROR ( Status )) {
+        //
+        //  Add this packet to the free packet list
+        //
+        pNicDevice->pRxFree = pRxPacket;
+        pRxPacket->pNext = NULL;
+      }
+      else {
+        //
+        //  Use the discard packet buffer
+        //
+        //pRxPacket = &Packet;
+      }
+    }
+      
+
+    pData = pNicDevice->pBulkInBuff + offset + 4;
+    pRxPacket->Length = *pLength;
+    pRxPacket->LengthBar = *(UINT16*) (pNicDevice->pBulkInBuff + offset +2);
+    CopyMem (&pRxPacket->Data[0], pData, *pLength);
+    //DEBUG((DEBUG_INFO, "Packet [%d]\n", *pLength));
+    
+    pNicDevice->pRxFree = pRxPacket->pNext;
+    pRxPacket->pNext = NULL;
+    
+    if ( NULL == pNicDevice->pRxTail ) {
+      pNicDevice->pRxHead = pRxPacket;
+    }
+    else {
+      pNicDevice->pRxTail->pNext = pRxPacket;
+    }
+    pNicDevice->pRxTail = pRxPacket;
+    offset += (*pLength + 4);
+              
+  }
+}
+
+
+
+/**
+  Receive a frame from the network.
+
+  This routine polls the USB receive interface for a packet.  If a packet
+  is available, this routine adds the receive packet to the list of
+  pending receive packets.
+
+  This routine calls ::Ax88772NegotiateLinkComplete to verify
+  that the link is up.  This routine also calls ::SN_Reset to
+  reset the network adapter when necessary.  Finally this
+  routine attempts to receive one or more packets from the
+  network adapter.
+
+  @param [in] pNicDevice  Pointer to the NIC_DEVICE structure
+  @param [in] bUpdateLink TRUE = Update link status
+
+**/
+VOID
+Ax88772Rx (
+  IN NIC_DEVICE * pNicDevice,
+  IN BOOLEAN bUpdateLink
+  )
+{
+  BOOLEAN bFullDuplex;
+  BOOLEAN bLinkUp;
+  BOOLEAN bRxPacket;
+  BOOLEAN bSpeed100;
+  UINTN LengthInBytes;
+  RX_TX_PACKET Packet;
+  RX_TX_PACKET * pRxPacket;
+  EFI_USB_IO_PROTOCOL *pUsbIo;
+  EFI_STATUS Status;
+  EFI_TPL TplPrevious;
+  UINT32 TransferStatus;
+
+  //
+  //  Synchronize with Ax88772Timer
+  //
+  VERIFY_TPL ( TPL_AX88772 );
+  TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
+  DEBUG (( DEBUG_TPL | DEBUG_INFO,
+            "%d: TPL\r\n",
+            TPL_AX88772 ));
+
+  //
+  //  Get the link status
+  //
+  if ( bUpdateLink ) {
+    bLinkUp = pNicDevice->bLinkUp;
+    bSpeed100 = pNicDevice->b100Mbps;
+    bFullDuplex = pNicDevice->bFullDuplex;
+    Status = Ax88772NegotiateLinkComplete ( pNicDevice,
+                                            &pNicDevice->PollCount,
+                                            &pNicDevice->bComplete,
+                                            &pNicDevice->bLinkUp,
+                                            &pNicDevice->b100Mbps,
+                                            &pNicDevice->bFullDuplex );
+
+    //
+    // Determine if the autonegotiation is complete
+    //
+    if ( pNicDevice->bComplete ) {
+      if ( pNicDevice->bLinkUp ) {
+        if (( bSpeed100 && ( !pNicDevice->b100Mbps ))
+          || (( !bSpeed100 ) && pNicDevice->b100Mbps )
+          || ( bFullDuplex && ( !pNicDevice->bFullDuplex ))
+          || (( !bFullDuplex ) && pNicDevice->bFullDuplex )) {
+          pNicDevice->PollCount = 0;
+          DEBUG (( DEBUG_LINK | DEBUG_INFO,
+                    "Reset to establish proper link setup: %d Mbps, %s duplex\r\n",
+                    pNicDevice->b100Mbps ? 100 : 10,
+                    pNicDevice->bFullDuplex ? L"Full" : L"Half" ));
+          Status = SN_Reset ( &pNicDevice->SimpleNetwork, FALSE );
+        }
+        if (( !bLinkUp ) && pNicDevice->bLinkUp ) {
+          //
+          // Display the autonegotiation status
+          //
+          DEBUG (( DEBUG_LINK | DEBUG_INFO,
+                    "Link: Up, %d Mbps, %s duplex\r\n",
+                    pNicDevice->b100Mbps ? 100 : 10,
+                    pNicDevice->bFullDuplex ? L"Full" : L"Half" ));
+        }
+      }
+    }
+
+    //
+    //  Update the link status
+    //
+    if ( bLinkUp && ( !pNicDevice->bLinkUp )) {
+      DEBUG (( DEBUG_LINK | DEBUG_INFO, "Link: Down\r\n" ));
+    }
+  }
+
+  //
+  //  Loop until all the packets are emptied from the receiver
+  //
+  do {
+    bRxPacket = FALSE;
+
+    //
+    //  Locate a packet for use
+    //
+    pRxPacket = pNicDevice->pRxFree;
+    LengthInBytes = MAX_BULKIN_SIZE;
+    if ( NULL == pRxPacket ) {
+      Status = gBS->AllocatePool ( EfiRuntimeServicesData,
+                                   sizeof ( *pRxPacket ),
+                                   (VOID **) &pRxPacket );
+      if ( !EFI_ERROR ( Status )) {
+        //
+        //  Add this packet to the free packet list
+        //
+        pNicDevice->pRxFree = pRxPacket;
+        pRxPacket->pNext = NULL;
+      }
+      else {
+        //
+        //  Use the discard packet buffer
+        //
+        pRxPacket = &Packet;
+      }
+    }
+
+    //
+    //  Attempt to receive a packet
+    //
+    SetMem (&pNicDevice->pBulkInBuff[0], MAX_BULKIN_SIZE, 0);
+    pUsbIo = pNicDevice->pUsbIo;
+    Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
+                                       USB_ENDPOINT_DIR_IN | BULK_IN_ENDPOINT,
+                                       &pNicDevice->pBulkInBuff[0],
+                                       &LengthInBytes,
+                                       2,
+                                       &TransferStatus );
+    if ( LengthInBytes > 0 ) {
+      FillPkt2Queue(pNicDevice, LengthInBytes);
+    }
+    pRxPacket = pNicDevice->pRxHead;
+    if (( !EFI_ERROR ( Status ))
+      && ( 0 < pRxPacket->Length )
+      && ( pRxPacket->Length <= sizeof ( pRxPacket->Data ))
+      && ( LengthInBytes > 0)) {
+
+      //
+      //  Determine if the packet should be received
+      //
+      bRxPacket = TRUE;
+      LengthInBytes = pRxPacket->Length;
+      pNicDevice->bLinkIdle = FALSE;
+      if ( pNicDevice->pRxFree == pRxPacket ) {
+        //
+        //  Display the received packet
+        //
+        if ( 0 != ( pRxPacket->Data[0] & 1 )) {
+          if (( 0xff == pRxPacket->Data[0])
+            && ( 0xff == pRxPacket->Data[1])
+            && ( 0xff == pRxPacket->Data[2])
+            && ( 0xff == pRxPacket->Data[3])
+            && ( 0xff == pRxPacket->Data[4])
+            && ( 0xff == pRxPacket->Data[5])) {
+            DEBUG (( DEBUG_RX_BROADCAST | DEBUG_INFO,
+                      "RX: %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x  %d bytes\r\n",
+                      pRxPacket->Data[0],
+                      pRxPacket->Data[1],
+                      pRxPacket->Data[2],
+                      pRxPacket->Data[3],
+                      pRxPacket->Data[4],
+                      pRxPacket->Data[5],
+                      pRxPacket->Data[6],
+                      pRxPacket->Data[7],
+                      pRxPacket->Data[8],
+                      pRxPacket->Data[9],
+                      pRxPacket->Data[10],
+                      pRxPacket->Data[11],
+                      pRxPacket->Data[12],
+                      pRxPacket->Data[13],
+                      LengthInBytes ));
+          }
+          else {
+            DEBUG (( DEBUG_RX_MULTICAST | DEBUG_INFO,
+                      "RX: %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x  %d bytes\r\n",
+                      pRxPacket->Data[0],
+                      pRxPacket->Data[1],
+                      pRxPacket->Data[2],
+                      pRxPacket->Data[3],
+                      pRxPacket->Data[4],
+                      pRxPacket->Data[5],
+                      pRxPacket->Data[6],
+                      pRxPacket->Data[7],
+                      pRxPacket->Data[8],
+                      pRxPacket->Data[9],
+                      pRxPacket->Data[10],
+                      pRxPacket->Data[11],
+                      pRxPacket->Data[12],
+                      pRxPacket->Data[13],
+                      LengthInBytes ));
+          }
+        }
+        else {
+          DEBUG (( DEBUG_RX_UNICAST | DEBUG_INFO,
+                    "RX: %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x  %d bytes\r\n",
+                    pRxPacket->Data[0],
+                    pRxPacket->Data[1],
+                    pRxPacket->Data[2],
+                    pRxPacket->Data[3],
+                    pRxPacket->Data[4],
+                    pRxPacket->Data[5],
+                    pRxPacket->Data[6],
+                    pRxPacket->Data[7],
+                    pRxPacket->Data[8],
+                    pRxPacket->Data[9],
+                    pRxPacket->Data[10],
+                    pRxPacket->Data[11],
+                    pRxPacket->Data[12],
+                    pRxPacket->Data[13],
+                    LengthInBytes ));
+        }
+        
+      }
+      else {
+        //
+        //  Error, not enough buffers for this packet, discard packet
+        //
+        DEBUG (( DEBUG_WARN | DEBUG_INFO,
+                  "WARNING - No buffer, discarding RX packet: %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x  %d bytes\r\n",
+                  pRxPacket->Data[0],
+                  pRxPacket->Data[1],
+                  pRxPacket->Data[2],
+                  pRxPacket->Data[3],
+                  pRxPacket->Data[4],
+                  pRxPacket->Data[5],
+                  pRxPacket->Data[6],
+                  pRxPacket->Data[7],
+                  pRxPacket->Data[8],
+                  pRxPacket->Data[9],
+                  pRxPacket->Data[10],
+                  pRxPacket->Data[11],
+                  pRxPacket->Data[12],
+                  pRxPacket->Data[13],
+                  LengthInBytes ));
+      }
+    }
+  }while ( bRxPacket );
+
+  //
+  //  Release the synchronization withhe Ax88772Timer
+  //
+  gBS->RestoreTPL ( TplPrevious );
+  DEBUG (( DEBUG_TPL | DEBUG_INFO,
+            "%d: TPL\r\n",
+            TplPrevious ));
+}
+
+
+/**
+  Enable or disable the receiver
+
+  This routine calls ::Ax88772UsbCommand to update the
+  receiver state.  This routine also calls ::Ax88772MacAddressSet
+  to establish the MAC address for the network adapter.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] RxFilter         Simple network RX filter mask value
+
+  @retval EFI_SUCCESS          The MAC address was set.
+  @retval other                The MAC address was not set.
+
+**/
+EFI_STATUS
+Ax88772RxControl (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT32 RxFilter
+  )
+{
+  UINT16 MediumStatus;
+  INT32 MulticastHash[2];
+  UINT16 RxControl;
+  USB_DEVICE_REQUEST SetupMsg;
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  //  Disable all multicast
+  //
+  MulticastHash[0] = 0;
+  MulticastHash[1] = 0;
+
+  //
+  // Enable the receiver if something is to be received
+  //
+  Status = EFI_SUCCESS;
+  RxControl = RXC_SO | RXC_MFB_16384;
+  if ( 0 != RxFilter ) {
+    //
+    //  Enable the receiver
+    //
+    SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
+                         | USB_REQ_TYPE_VENDOR
+                         | USB_TARGET_DEVICE;
+    SetupMsg.Request = CMD_MEDIUM_STATUS_READ;
+    SetupMsg.Value = 0;
+    SetupMsg.Index = 0;
+    SetupMsg.Length = sizeof ( MediumStatus );
+    Status = Ax88772UsbCommand ( pNicDevice,
+                                 &SetupMsg,
+                                 &MediumStatus );
+    if ( !EFI_ERROR ( Status )) {
+      if ( 0 == ( MediumStatus & MS_RE )) {
+        MediumStatus |= MS_RE | MS_ONE;
+        if ( pNicDevice->bFullDuplex ) {
+          MediumStatus |= MS_TFC | MS_RFC;
+        }
+        SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                             | USB_TARGET_DEVICE;
+        SetupMsg.Request = CMD_MEDIUM_STATUS_WRITE;
+        SetupMsg.Value = MediumStatus;
+        SetupMsg.Index = 0;
+        SetupMsg.Length = 0;
+        Status = Ax88772UsbCommand ( pNicDevice,
+                                     &SetupMsg,
+                                     NULL );
+        if ( EFI_ERROR ( Status )) {
+          DEBUG (( DEBUG_ERROR | DEBUG_INFO,
+                    "ERROR - Failed to enable receiver, Status: %r\r\n",
+                    Status ));
+        }
+      }
+    }
+    else {
+      DEBUG (( DEBUG_ERROR | DEBUG_INFO,
+                "ERROR - Failed to read receiver status, Status: %r\r\n",
+                Status ));
+    }
+
+    //
+    //  Enable multicast if requested
+    //
+    if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST )) {
+      RxControl |= RXC_AM;
+      MulticastHash[0] = pNicDevice->MulticastHash[0];
+      MulticastHash[1] = pNicDevice->MulticastHash[1];
+    }
+
+    //
+    //  Enable all multicast if requested
+    //
+    if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST )) {
+      RxControl |= RXC_AMALL;
+      MulticastHash[0] = -1;
+      MulticastHash[1] = -1;
+    }
+
+    //
+    //  Enable broadcast if requested
+    //
+    if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST )) {
+      RxControl |= RXC_AB;
+    }
+
+    //
+    //  Enable promiscuous mode if requested
+    //
+    if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS )) {
+      RxControl |= RXC_PRO;
+      MulticastHash[0] = -1;
+      MulticastHash[1] = -1;
+    }
+  }
+
+  //
+  //  Update the MAC address
+  //
+  if ( !EFI_ERROR ( Status )) {
+    Status = Ax88772MacAddressSet ( pNicDevice, &pNicDevice->SimpleNetworkData.CurrentAddress.Addr[0]);
+  }
+
+  //
+  //  Update the receiver control
+  //
+  if ( !EFI_ERROR ( Status )) {
+    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                         | USB_TARGET_DEVICE;
+    SetupMsg.Request = CMD_RX_CONTROL_WRITE;
+    SetupMsg.Value = RxControl;
+    SetupMsg.Index = 0;
+    SetupMsg.Length = 0;
+    Status = Ax88772UsbCommand ( pNicDevice,
+                                 &SetupMsg,
+                                 NULL );
+    if ( !EFI_ERROR ( Status )) {
+      DEBUG (( DEBUG_RX_BROADCAST | DEBUG_RX_MULTICAST | DEBUG_RX_UNICAST | DEBUG_INFO,
+                "RxControl: 0x%04x\r\n",
+                RxControl ));
+
+      //
+      //  Update the multicast hash table
+      //
+      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                           | USB_TARGET_DEVICE;
+      SetupMsg.Request = CMD_MULTICAST_HASH_WRITE;
+      SetupMsg.Value = 0;
+      SetupMsg.Index = 0;
+      SetupMsg.Length = sizeof ( pNicDevice ->MulticastHash );
+      Status = Ax88772UsbCommand ( pNicDevice,
+                                   &SetupMsg,
+                                   &pNicDevice->MulticastHash );
+      if ( !EFI_ERROR ( Status )) {
+        DEBUG (( DEBUG_RX_MULTICAST | DEBUG_INFO,
+                  "Multicast Hash: 0x%02x %02x %02x %02x %02x %02x %02x %02x\r\n",
+                  (UINT8) MulticastHash[0],
+                  (UINT8)( MulticastHash[0] >> 8 ),
+                  (UINT8)( MulticastHash[0] >> 16 ),
+                  (UINT8)( MulticastHash[0] >> 24 ),
+                  (UINT8) MulticastHash[1],
+                  (UINT8)( MulticastHash[1] >> 8 ),
+                  (UINT8)( MulticastHash[1] >> 16 ),
+                  (UINT8)( MulticastHash[1] >> 24 )));
+      }
+      else {
+        DEBUG (( DEBUG_ERROR | DEBUG_INFO,
+                  "ERROR - Failed to update multicast hash table, Status: %r\r\n",
+                  Status ));
+      }
+    }
+    else {
+      DEBUG (( DEBUG_ERROR | DEBUG_INFO,
+                "ERROR - Failed to set receiver control, Status: %r\r\n",
+                Status ));
+    }
+  }
+
+  //
+  // Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Read an SROM location
+
+  This routine calls ::Ax88772UsbCommand to read data from the
+  SROM.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] Address          SROM address
+  @param [out] pData           Buffer to receive the data
+
+  @retval EFI_SUCCESS          The read was successful
+  @retval other                The read failed
+
+**/
+EFI_STATUS
+Ax88772SromRead (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT32 Address,
+  OUT UINT16 * pData
+  )
+{
+  USB_DEVICE_REQUEST SetupMsg;
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  //  Read a value from the SROM
+  //
+  SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
+                       | USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_SROM_READ;
+  SetupMsg.Value = (UINT16) Address;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = sizeof ( *pData );
+  Status = Ax88772UsbCommand ( pNicDevice,
+                               &SetupMsg,
+                               pData );
+
+  //
+  // Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  This routine is called at a regular interval to poll for
+  receive packets.
+
+  This routine polls the link state and gets any receive packets
+  by calling ::Ax88772Rx.
+
+  @param [in] Event            Timer event
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+
+**/
+VOID
+Ax88772Timer (
+  IN EFI_EVENT Event,
+  IN NIC_DEVICE * pNicDevice
+  )
+{
+  //
+  //  Use explicit DEBUG messages since the output frequency is too
+  //  high for DEBUG_INFO to keep up and have spare cycles for the
+  //  shell
+  //
+  DEBUG (( DEBUG_TIMER, "Entering Ax88772Timer\r\n" ));
+
+  //
+  //  Poll the link state and get any receive packets
+  //
+  Ax88772Rx ( pNicDevice, FALSE );
+
+  DEBUG (( DEBUG_TIMER, "Exiting Ax88772Timer\r\n" ));
+}
+
+
+/**
+  Send a command to the USB device.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] pRequest         Pointer to the request structure
+  @param [in, out] pBuffer     Data buffer address
+
+  @retval EFI_SUCCESS          The USB transfer was successful
+  @retval other                The USB transfer failed
+
+**/
+EFI_STATUS
+Ax88772UsbCommand (
+  IN NIC_DEVICE * pNicDevice,
+  IN USB_DEVICE_REQUEST * pRequest,
+  IN OUT VOID * pBuffer
+  )
+{
+  UINT32 CmdStatus;
+  EFI_USB_DATA_DIRECTION Direction;
+  EFI_USB_IO_PROTOCOL * pUsbIo;
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  // Determine the transfer direction
+  //
+  Direction = EfiUsbNoData;
+  if ( 0 != pRequest->Length ) {
+    Direction = ( 0 != ( pRequest->RequestType & USB_ENDPOINT_DIR_IN ))
+              ? EfiUsbDataIn : EfiUsbDataOut;
+  }
+
+  //
+  // Issue the command
+  //
+  pUsbIo = pNicDevice->pUsbIo;
+  Status = pUsbIo->UsbControlTransfer ( pUsbIo,
+                                        pRequest,
+                                        Direction,
+                                        USB_BUS_TIMEOUT,
+                                        pBuffer,
+                                        pRequest->Length,
+                                        &CmdStatus );
+
+  //
+  // Determine the operation status
+  //
+  if ( !EFI_ERROR ( Status )) {
+    Status = CmdStatus;
+  }
+  else {
+    //
+    // Display any errors
+    //
+    DEBUG (( DEBUG_INFO,
+              "Ax88772UsbCommand - Status: %r\n",
+              Status ));
+
+    //
+    // Only use status values associated with the Simple Network protocol
+    //
+    if ( EFI_TIMEOUT == Status ) {
+      Status = EFI_DEVICE_ERROR;
+    }
+  }
+
+  //
+  // Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.h b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.h
new file mode 100644
index 0000000000..8840a4f464
--- /dev/null
+++ b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.h
@@ -0,0 +1,969 @@
+/** @file
+  Definitions for ASIX AX88772 Ethernet adapter.
+
+  Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _AX88772_H_
+#define _AX88772_H_
+
+#include <Uefi.h>
+
+#include <Guid/EventGroup.h>
+
+#include <IndustryStandard/Pci.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeLib.h>
+
+#include <Protocol/DevicePath.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/NetworkInterfaceIdentifier.h>
+#include <Protocol/SimpleNetwork.h>
+#include <Protocol/UsbIo.h>
+
+//------------------------------------------------------------------------------
+//  Macros
+//------------------------------------------------------------------------------
+//
+//Too many output debug info hangs system in Debug tip
+//
+//#if defined(_MSC_VER)           /* Handle Microsoft VC++ compiler specifics. */
+//#define DBG_ENTER()             DEBUG (( DEBUG_INFO, "Entering " __FUNCTION__ "\n" )) ///<  Display routine entry
+//#define DBG_EXIT()              DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ "\n" ))  ///<  Display routine exit
+//#define DBG_EXIT_DEC(Status)    DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: %d\n", Status ))      ///<  Display routine exit with decimal value
+//#define DBG_EXIT_HEX(Status)    DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: 0x%08x\n", Status ))  ///<  Display routine exit with hex value
+//#define DBG_EXIT_STATUS(Status) DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: %r\n", Status ))      ///<  Display routine exit with status value
+//#define DBG_EXIT_TF(Status)     DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", returning %s\n", (FALSE == Status) ? L"FALSE" : L"TRUE" ))  ///<  Display routine with TRUE/FALSE value
+//#else   //  _MSC_VER
+#define DBG_ENTER()               ///<  Display routine entry
+#define DBG_EXIT()                ///<  Display routine exit
+#define DBG_EXIT_DEC(Status)      ///<  Display routine exit with decimal value
+#define DBG_EXIT_HEX(Status)      ///<  Display routine exit with hex value
+#define DBG_EXIT_STATUS(Status)   ///<  Display routine exit with status value
+#define DBG_EXIT_TF(Status)       ///<  Display routine with TRUE/FALSE value
+//#endif  //  _MSC_VER
+
+#define USB_IS_IN_ENDPOINT(EndPointAddr)      (((EndPointAddr) & BIT7) != 0)  ///<  Return TRUE/FALSE for IN direction
+#define USB_IS_OUT_ENDPOINT(EndPointAddr)     (((EndPointAddr) & BIT7) == 0)  ///<  Return TRUE/FALSE for OUT direction
+#define USB_IS_BULK_ENDPOINT(Attribute)       (((Attribute) & (BIT0 | BIT1)) == USB_ENDPOINT_BULK)      ///<  Return TRUE/FALSE for BULK type
+#define USB_IS_INTERRUPT_ENDPOINT(Attribute)  (((Attribute) & (BIT0 | BIT1)) == USB_ENDPOINT_INTERRUPT) ///<  Return TRUE/FALSE for INTERRUPT type
+
+//------------------------------------------------------------------------------
+//  Constants
+//------------------------------------------------------------------------------
+
+#define DEBUG_RX_BROADCAST  0x40000000  ///<  Display RX broadcast messages
+#define DEBUG_RX_MULTICAST  0x20000000  ///<  Display RX multicast messages
+#define DEBUG_RX_UNICAST    0x10000000  ///<  Display RX unicast messages
+#define DEBUG_MAC_ADDRESS   0x08000000  ///<  Display the MAC address
+#define DEBUG_LINK          0x04000000  ///<  Display the link status
+#define DEBUG_TX            0x02000000  ///<  Display the TX messages
+#define DEBUG_PHY           0x01000000  ///<  Display the PHY register values
+#define DEBUG_SROM          0x00800000  ///<  Display the SROM contents
+#define DEBUG_TIMER         0x00400000  ///<  Display the timer routine entry/exit
+#define DEBUG_TPL           0x00200000  ///<  Display the timer routine entry/exit
+
+#define AX88772_MAX_PKT_SIZE  ( 2048 - 4 )  ///< Maximum packet size
+#define ETHERNET_HEADER_SIZE  sizeof ( ETHERNET_HEADER )  ///<  Size in bytes of the Ethernet header
+#define MIN_ETHERNET_PKT_SIZE 60    ///<  Minimum packet size including Ethernet header
+#define MAX_ETHERNET_PKT_SIZE 1500  ///<  Ethernet spec 3.1.1: Minimum packet size
+#define MAX_BULKIN_SIZE       2048  ///<  Maximum size of one UsbBulk 
+
+
+#define USB_NETWORK_CLASS   0x09    ///<  USB Network class code
+#define USB_BUS_TIMEOUT     1000    ///<  USB timeout in milliseconds
+
+#define TIMER_MSEC          20              ///<  Polling interval for the NIC
+#define TPL_AX88772         TPL_CALLBACK    ///<  TPL for routine synchronization
+
+/**
+  Verify new TPL value
+
+  This macro which is enabled when debug is enabled verifies that
+  the new TPL value is >= the current TPL value.
+**/
+#ifdef VERIFY_TPL
+#undef VERIFY_TPL
+#endif  //  VERIFY_TPL
+
+#if !defined(MDEPKG_NDEBUG)
+
+#define VERIFY_TPL(tpl)                           \
+{                                                 \
+  EFI_TPL PreviousTpl;                            \
+                                                  \
+  PreviousTpl = gBS->RaiseTPL ( TPL_HIGH_LEVEL ); \
+  gBS->RestoreTPL ( PreviousTpl );                \
+  if ( PreviousTpl > tpl ) {                      \
+    DEBUG (( DEBUG_ERROR, "Current TPL: %d, New TPL: %d\r\n", PreviousTpl, tpl ));  \
+    ASSERT ( PreviousTpl <= tpl );                \
+  }                                               \
+}
+
+#else   //  MDEPKG_NDEBUG
+
+#define VERIFY_TPL(tpl)
+
+#endif  //  MDEPKG_NDEBUG
+
+//------------------------------------------------------------------------------
+//  Hardware Definition
+//------------------------------------------------------------------------------
+
+#define DEV_SIGNATURE     SIGNATURE_32 ('A','X','8','8')  ///<  Signature of data structures in memory
+
+#define VENDOR_ID         0x0b95  ///<  Vendor ID for Asix
+#define PRODUCT_ID        0x7720  ///<  Product ID for the AX88772 USB 10/100 Ethernet controller
+
+#define RESET_MSEC        1000    ///<  Reset duration
+#define PHY_RESET_MSEC     500    ///<  PHY reset duration
+
+//
+//  RX Control register
+//
+
+#define RXC_PRO           0x0001  ///<  Receive all packets
+#define RXC_AMALL         0x0002  ///<  Receive all multicast packets
+#define RXC_SEP           0x0004  ///<  Save error packets
+#define RXC_AB            0x0008  ///<  Receive broadcast packets
+#define RXC_AM            0x0010  ///<  Use multicast destination address hash table
+#define RXC_AP            0x0020  ///<  Accept physical address from Multicast Filter
+#define RXC_SO            0x0080  ///<  Start operation
+#define RXC_MFB           0x0300  ///<  Maximum frame burst
+#define RXC_MFB_2048      0       ///<  Maximum frame size:  2048 bytes
+#define RXC_MFB_4096      0x0100  ///<  Maximum frame size:  4096 bytes
+#define RXC_MFB_8192      0x0200  ///<  Maximum frame size:  8192 bytes
+#define RXC_MFB_16384     0x0300  ///<  Maximum frame size: 16384 bytes
+
+//
+//  Medium Status register
+//
+
+#define MS_FD             0x0002  ///<  Full duplex
+#define MS_ONE            0x0004  ///<  Must be one
+#define MS_RFC            0x0010  ///<  RX flow control enable
+#define MS_TFC            0x0020  ///<  TX flow control enable
+#define MS_PF             0x0080  ///<  Pause frame enable
+#define MS_RE             0x0100  ///<  Receive enable
+#define MS_PS             0x0200  ///<  Port speed 1=100, 0=10 Mbps
+#define MS_SBP            0x0800  ///<  Stop back pressure
+#define MS_SM             0x1000  ///<  Super MAC support
+
+//
+//  Software PHY Select register
+//
+
+#define SPHY_PSEL         0x01    ///<  Select internal PHY
+#define SPHY_ASEL         0x02    ///<  1=Auto select, 0=Manual select
+
+//
+//  Software Reset register
+//
+
+#define SRR_RR            0x01    ///<  Clear receive frame length error
+#define SRR_RT            0x02    ///<  Clear transmit frame length error
+#define SRR_PRTE          0x04    ///<  External PHY reset pin tri-state enable
+#define SRR_PRL           0x08    ///<  External PHY reset pin level
+#define SRR_BZ            0x10    ///<  Force Bulk to return zero length packet
+#define SRR_IPRL          0x20    ///<  Internal PHY reset control
+#define SRR_IPPD          0x40    ///<  Internal PHY power down
+
+//
+//  PHY ID values
+//
+
+#define PHY_ID_INTERNAL   0x0010  ///<  Internal PHY
+
+//
+//  USB Commands
+//
+
+#define CMD_PHY_ACCESS_SOFTWARE   0x06  ///<  Software in control of PHY
+#define CMD_PHY_REG_READ          0x07  ///<  Read PHY register, Value: PHY, Index: Register, Data: Register value
+#define CMD_PHY_REG_WRITE         0x08  ///<  Write PHY register, Value: PHY, Index: Register, Data: New 16-bit value
+#define CMD_PHY_ACCESS_HARDWARE   0x0a  ///<  Hardware in control of PHY
+#define CMD_SROM_READ             0x0b  ///<  Read SROM register: Value: Address, Data: Value
+#define CMD_RX_CONTROL_WRITE      0x10  ///<  Set the RX control register, Value: New value
+#define CMD_GAPS_WRITE            0x12  ///<  Write the gaps register, Value: New value
+#define CMD_MAC_ADDRESS_READ      0x13  ///<  Read the MAC address, Data: 6 byte MAC address
+#define CMD_MAC_ADDRESS_WRITE     0x14  ///<  Set the MAC address, Data: New 6 byte MAC address
+#define CMD_MULTICAST_HASH_WRITE  0x16  ///<  Write the multicast hash table, Data: New 8 byte value
+#define CMD_MEDIUM_STATUS_READ    0x1a  ///<  Read medium status register, Data: Register value
+#define CMD_MEDIUM_STATUS_WRITE   0x1b  ///<  Write medium status register, Value: New value
+#define CMD_RESET                 0x20  ///<  Reset register, Value: New value
+#define CMD_PHY_SELECT            0x22  ///<  PHY select register, Value: New value
+
+//------------------------------
+//  USB Endpoints
+//------------------------------
+
+#define CONTROL_ENDPOINT                0       ///<  Control endpoint
+#define INTERRUPT_ENDPOINT              1       ///<  Interrupt endpoint
+#define BULK_IN_ENDPOINT                2       ///<  Receive endpoint
+#define BULK_OUT_ENDPOINT               3       ///<  Transmit endpoint
+
+//------------------------------
+//  PHY Registers
+//------------------------------
+
+#define PHY_BMCR                        0       ///<  Control register
+#define PHY_BMSR                        1       ///<  Status register
+#define PHY_ANAR                        4       ///<  Autonegotiation advertisement register
+#define PHY_ANLPAR                      5       ///<  Autonegotiation link parter ability register
+#define PHY_ANER                        6       ///<  Autonegotiation expansion register
+
+//  BMCR - Register 0
+
+#define BMCR_RESET                      0x8000  ///<  1 = Reset the PHY, bit clears after reset
+#define BMCR_LOOPBACK                   0x4000  ///<  1 = Loopback enabled
+#define BMCR_100MBPS                    0x2000  ///<  100 Mbits/Sec
+#define BMCR_10MBPS                     0       ///<  10 Mbits/Sec
+#define BMCR_AUTONEGOTIATION_ENABLE     0x1000  ///<  1 = Enable autonegotiation
+#define BMCR_POWER_DOWN                 0x0800  ///<  1 = Power down
+#define BMCR_ISOLATE                    0x0400  ///<  0 = Isolate PHY
+#define BMCR_RESTART_AUTONEGOTIATION    0x0200  ///<  1 = Restart autonegotiation
+#define BMCR_FULL_DUPLEX                0x0100  ///<  Full duplex operation
+#define BMCR_HALF_DUPLEX                0       ///<  Half duplex operation
+#define BMCR_COLLISION_TEST             0x0080  ///<  1 = Collision test enabled
+
+//  BSMR - Register 1
+
+#define BMSR_100BASET4                  0x8000  ///<  1 = 100BASE-T4 mode
+#define BMSR_100BASETX_FDX              0x4000  ///<  1 = 100BASE-TX full duplex
+#define BMSR_100BASETX_HDX              0x2000  ///<  1 = 100BASE-TX half duplex
+#define BMSR_10BASET_FDX                0x1000  ///<  1 = 10BASE-T full duplex
+#define BMSR_10BASET_HDX                0x0800  ///<  1 = 10BASE-T half duplex
+#define BMSR_MF                         0x0040  ///<  1 = PHY accepts frames with preamble suppressed
+#define BMSR_AUTONEG_CMPLT              0x0020  ///<  1 = Autonegotiation complete
+#define BMSR_RF                         0x0010  ///<  1 = Remote fault
+#define BMSR_AUTONEG                    0x0008  ///<  1 = Able to perform autonegotiation
+#define BMSR_LINKST                     0x0004  ///<  1 = Link up
+#define BMSR_JABBER_DETECT              0x0002  ///<  1 = jabber condition detected
+#define BMSR_EXTENDED_CAPABILITY        0x0001  ///<  1 = Extended register capable
+
+//  ANAR and ANLPAR Registers 4, 5
+
+#define AN_NP                           0x8000  ///<  1 = Next page available
+#define AN_ACK                          0x4000  ///<  1 = Link partner acknowledged
+#define AN_RF                           0x2000  ///<  1 = Remote fault indicated by link partner
+#define AN_FCS                          0x0400  ///<  1 = Flow control ability
+#define AN_T4                           0x0200  ///<  1 = 100BASE-T4 support
+#define AN_TX_FDX                       0x0100  ///<  1 = 100BASE-TX Full duplex
+#define AN_TX_HDX                       0x0080  ///<  1 = 100BASE-TX support
+#define AN_10_FDX                       0x0040  ///<  1 = 10BASE-T Full duplex
+#define AN_10_HDX                       0x0020  ///<  1 = 10BASE-T support
+#define AN_CSMA_CD                      0x0001  ///<  1 = IEEE 802.3 CSMA/CD support
+
+//------------------------------------------------------------------------------
+//  Data Types
+//------------------------------------------------------------------------------
+
+/**
+  Ethernet header layout
+
+  IEEE 802.3-2002 Part 3 specification, section 3.1.1.
+**/
+#pragma pack(1)
+typedef struct {
+  UINT8 dest_addr[PXE_HWADDR_LEN_ETHER];  ///<  Destination LAN address
+  UINT8 src_addr[PXE_HWADDR_LEN_ETHER];   ///<  Source LAN address
+  UINT16 type;                            ///<  Protocol or length
+} ETHERNET_HEADER;
+#pragma pack()
+
+/**
+  Receive and Transmit packet structure
+**/
+#pragma pack(1)
+typedef struct _RX_TX_PACKET {
+  struct _RX_TX_PACKET * pNext;       ///<  Next receive packet
+  UINT16 Length;                      ///<  Packet length
+  UINT16 LengthBar;                   ///<  Complement of the length
+  UINT8 Data[ AX88772_MAX_PKT_SIZE ]; ///<  Received packet data
+} RX_TX_PACKET;
+#pragma pack()
+
+/**
+  AX88772 control structure
+
+  The driver uses this structure to manage the Asix AX88772 10/100
+  Ethernet controller.
+**/
+typedef struct {
+  UINTN Signature;          ///<  Structure identification
+
+  //
+  //  USB data
+  //
+  EFI_HANDLE Controller;        ///<  Controller handle
+  EFI_USB_IO_PROTOCOL * pUsbIo; ///<  USB driver interface
+
+  //
+  //  Simple network protocol data
+  //
+  EFI_SIMPLE_NETWORK_PROTOCOL SimpleNetwork;  ///<  Driver's network stack interface
+  EFI_SIMPLE_NETWORK_MODE SimpleNetworkData;  ///<  Data for simple network
+
+  //
+  // Ethernet controller data
+  //
+  BOOLEAN bInitialized;     ///<  Controller initialized
+  VOID * pTxBuffer;         ///<  Last transmit buffer
+  UINT16 PhyId;             ///<  PHY ID
+
+  //
+  //  Link state
+  //
+  BOOLEAN b100Mbps;         ///<  Current link speed, FALSE = 10 Mbps
+  BOOLEAN bComplete;        ///<  Current state of auto-negotiation
+  BOOLEAN bFullDuplex;      ///<  Current duplex
+  BOOLEAN bLinkUp;          ///<  Current link state
+  BOOLEAN bLinkIdle;        ///<  TRUE = No received traffic
+  EFI_EVENT Timer;          ///<  Timer to monitor link state and receive packets
+  UINTN PollCount;          ///<  Number of times the autonegotiation status was polled
+
+  //
+  //  Receive buffer list
+  //
+  RX_TX_PACKET * pRxHead;   ///<  Head of receive packet list
+  RX_TX_PACKET * pRxTail;   ///<  Tail of receive packet list
+  RX_TX_PACKET * pRxFree;   ///<  Free packet list
+  INT32 MulticastHash[2];   ///<  Hash table for multicast destination addresses
+  UINT8 * pBulkInBuff;      ///<  Buffer for Usb Bulk
+} NIC_DEVICE;
+
+#define DEV_FROM_SIMPLE_NETWORK(a)  CR (a, NIC_DEVICE, SimpleNetwork, DEV_SIGNATURE)  ///< Locate NIC_DEVICE from Simple Network Protocol
+
+//------------------------------------------------------------------------------
+// Simple Network Protocol
+//------------------------------------------------------------------------------
+
+/**
+  Reset the network adapter.
+
+  Resets a network adapter and reinitializes it with the parameters that
+  were provided in the previous call to Initialize ().  The transmit and
+  receive queues are cleared.  Receive filters, the station address, the
+  statistics, and the multicast-IP-to-HW MAC addresses are not reset by
+  this call.
+
+  This routine calls ::Ax88772Reset to perform the adapter specific
+  reset operation.  This routine also starts the link negotiation
+  by calling ::Ax88772NegotiateLinkStart.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] bExtendedVerification  Indicates that the driver may perform a more
+                                exhaustive verification operation of the device
+                                during reset.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Reset (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN BOOLEAN bExtendedVerification
+  );
+
+/**
+  Initialize the simple network protocol.
+
+  This routine calls ::Ax88772MacAddressGet to obtain the
+  MAC address.
+
+  @param [in] pNicDevice       NIC_DEVICE_INSTANCE pointer
+
+  @retval EFI_SUCCESS     Setup was successful
+
+**/
+EFI_STATUS
+SN_Setup (
+  IN NIC_DEVICE * pNicDevice
+  );
+
+/**
+  This routine starts the network interface.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_ALREADY_STARTED   The network interface was already started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Start (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
+  );
+
+/**
+  Set the MAC address.
+  
+  This function modifies or resets the current station address of a
+  network interface.  If Reset is TRUE, then the current station address
+  is set ot the network interface's permanent address.  If Reset if FALSE
+  then the current station address is changed to the address specified by
+  pNew.
+
+  This routine calls ::Ax88772MacAddressSet to update the MAC address
+  in the network adapter.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] bReset            Flag used to reset the station address to the
+                                network interface's permanent address.
+  @param [in] pNew              New station address to be used for the network
+                                interface.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_StationAddress (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN BOOLEAN bReset,
+  IN EFI_MAC_ADDRESS * pNew
+  );
+
+/**
+  This function resets or collects the statistics on a network interface.
+  If the size of the statistics table specified by StatisticsSize is not
+  big enough for all of the statistics that are collected by the network
+  interface, then a partial buffer of statistics is returned in
+  StatisticsTable.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] bReset            Set to TRUE to reset the statistics for the network interface.
+  @param [in, out] pStatisticsSize  On input the size, in bytes, of StatisticsTable.  On output
+                                the size, in bytes, of the resulting table of statistics.
+  @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
+                                conains the statistics.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_BUFFER_TOO_SMALL  The pStatisticsTable is NULL or the buffer is too small.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Statistics (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN BOOLEAN bReset,
+  IN OUT UINTN * pStatisticsSize,
+  OUT EFI_NETWORK_STATISTICS * pStatisticsTable
+  );
+
+/**
+  This function stops a network interface.  This call is only valid
+  if the network interface is in the started state.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Stop (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
+  );
+
+/**
+  This function releases the memory buffers assigned in the Initialize() call.
+  Pending transmits and receives are lost, and interrupts are cleared and disabled.
+  After this call, only Initialize() and Stop() calls may be used.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Shutdown (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
+  );
+
+/**
+  Send a packet over the network.
+
+  This function places the packet specified by Header and Buffer on
+  the transmit queue.  This function performs a non-blocking transmit
+  operation.  When the transmit is complete, the buffer is returned
+  via the GetStatus() call.
+
+  This routine calls ::Ax88772Rx to empty the network adapter of
+  receive packets.  The routine then passes the transmit packet
+  to the network adapter.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] HeaderSize        The size, in bytes, of the media header to be filled in by
+                                the Transmit() function.  If HeaderSize is non-zero, then
+                                it must be equal to SimpleNetwork->Mode->MediaHeaderSize
+                                and DestAddr and Protocol parameters must not be NULL.
+  @param [in] BufferSize        The size, in bytes, of the entire packet (media header and
+                                data) to be transmitted through the network interface.
+  @param [in] pBuffer           A pointer to the packet (media header followed by data) to
+                                to be transmitted.  This parameter can not be NULL.  If
+                                HeaderSize is zero, then the media header is Buffer must
+                                already be filled in by the caller.  If HeaderSize is nonzero,
+                                then the media header will be filled in by the Transmit()
+                                function.
+  @param [in] pSrcAddr          The source HW MAC address.  If HeaderSize is zero, then
+                                this parameter is ignored.  If HeaderSize is nonzero and
+                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
+                                is used for the source HW MAC address.
+  @param [in] pDestAddr         The destination HW MAC address.  If HeaderSize is zero, then
+                                this parameter is ignored.
+  @param [in] pProtocol         The type of header to build.  If HeaderSize is zero, then
+                                this parameter is ignored.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_NOT_READY         The network interface is too busy to accept this transmit request.
+  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Transmit (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN UINTN HeaderSize,
+  IN UINTN BufferSize,
+  IN VOID * pBuffer,
+  IN EFI_MAC_ADDRESS * pSrcAddr,
+  IN EFI_MAC_ADDRESS * pDestAddr,
+  IN UINT16 * pProtocol
+  );
+
+//------------------------------------------------------------------------------
+// Support Routines
+//------------------------------------------------------------------------------
+
+/**
+  Get the MAC address
+
+  This routine calls ::Ax88772UsbCommand to request the MAC
+  address from the network adapter.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [out] pMacAddress      Address of a six byte buffer to receive the MAC address.
+
+  @retval EFI_SUCCESS          The MAC address is available.
+  @retval other                The MAC address is not valid.
+
+**/
+EFI_STATUS
+Ax88772MacAddressGet (
+  IN NIC_DEVICE * pNicDevice,
+  OUT UINT8 * pMacAddress
+  );
+
+/**
+  Set the MAC address
+
+  This routine calls ::Ax88772UsbCommand to set the MAC address
+  in the network adapter.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] pMacAddress      Address of a six byte buffer to containing the new MAC address.
+
+  @retval EFI_SUCCESS          The MAC address was set.
+  @retval other                The MAC address was not set.
+
+**/
+EFI_STATUS
+Ax88772MacAddressSet (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT8 * pMacAddress
+  );
+
+/**
+  Clear the multicast hash table
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+
+**/
+VOID
+Ax88772MulticastClear (
+  IN NIC_DEVICE * pNicDevice
+  );
+
+/**
+  Enable a multicast address in the multicast hash table
+
+  This routine calls ::Ax88772Crc to compute the hash bit for
+  this MAC address.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] pMacAddress      Address of a six byte buffer to containing the MAC address.
+
+**/
+VOID
+Ax88772MulticastSet (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT8 * pMacAddress
+  );
+
+/**
+  Start the link negotiation
+
+  This routine calls ::Ax88772PhyWrite to start the PHY's link
+  negotiation.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+
+  @retval EFI_SUCCESS          The link negotiation was started.
+  @retval other                Failed to start the link negotiation.
+
+**/
+EFI_STATUS
+Ax88772NegotiateLinkStart (
+  IN NIC_DEVICE * pNicDevice
+  );
+
+/**
+  Complete the negotiation of the PHY link
+
+  This routine calls ::Ax88772PhyRead to determine if the
+  link negotiation is complete.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in, out] pPollCount  Address of number of times this routine was polled
+  @param [out] pbComplete      Address of boolean to receive complate status.
+  @param [out] pbLinkUp        Address of boolean to receive link status, TRUE=up.
+  @param [out] pbHiSpeed       Address of boolean to receive link speed, TRUE=100Mbps.
+  @param [out] pbFullDuplex    Address of boolean to receive link duplex, TRUE=full.
+
+  @retval EFI_SUCCESS          The MAC address is available.
+  @retval other                The MAC address is not valid.
+
+**/
+EFI_STATUS
+Ax88772NegotiateLinkComplete (
+  IN NIC_DEVICE * pNicDevice,
+  IN OUT UINTN * pPollCount,
+  OUT BOOLEAN * pbComplete,
+  OUT BOOLEAN * pbLinkUp,
+  OUT BOOLEAN * pbHiSpeed,
+  OUT BOOLEAN * pbFullDuplex
+  );
+
+/**
+  Read a register from the PHY
+
+  This routine calls ::Ax88772UsbCommand to read a PHY register.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] RegisterAddress  Number of the register to read.
+  @param [in, out] pPhyData    Address of a buffer to receive the PHY register value
+
+  @retval EFI_SUCCESS          The PHY data is available.
+  @retval other                The PHY data is not valid.
+
+**/
+EFI_STATUS
+Ax88772PhyRead (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT8 RegisterAddress,
+  IN OUT UINT16 * pPhyData
+  );
+
+/**
+  Write to a PHY register
+
+  This routine calls ::Ax88772UsbCommand to write a PHY register.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] RegisterAddress  Number of the register to read.
+  @param [in] PhyData          Address of a buffer to receive the PHY register value
+
+  @retval EFI_SUCCESS          The PHY data was written.
+  @retval other                Failed to wwrite the PHY register.
+
+**/
+EFI_STATUS
+Ax88772PhyWrite (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT8 RegisterAddress,
+  IN UINT16 PhyData
+  );
+
+/**
+  Reset the AX88772
+
+  This routine uses ::Ax88772UsbCommand to reset the network
+  adapter.  This routine also uses ::Ax88772PhyWrite to reset
+  the PHY.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+
+  @retval EFI_SUCCESS          The MAC address is available.
+  @retval other                The MAC address is not valid.
+
+**/
+EFI_STATUS
+Ax88772Reset (
+  IN NIC_DEVICE * pNicDevice
+  );
+
+/**
+  Receive a frame from the network.
+
+  This routine polls the USB receive interface for a packet.  If a packet
+  is available, this routine adds the receive packet to the list of
+  pending receive packets.
+
+  This routine calls ::Ax88772NegotiateLinkComplete to verify
+  that the link is up.  This routine also calls ::SN_Reset to
+  reset the network adapter when necessary.  Finally this
+  routine attempts to receive one or more packets from the
+  network adapter.
+
+  @param [in] pNicDevice  Pointer to the NIC_DEVICE structure
+  @param [in] bUpdateLink TRUE = Update link status
+
+**/
+VOID
+Ax88772Rx (
+  IN NIC_DEVICE * pNicDevice,
+  IN BOOLEAN bUpdateLink
+  );
+
+/**
+  Enable or disable the receiver
+
+  This routine calls ::Ax88772UsbCommand to update the
+  receiver state.  This routine also calls ::Ax88772MacAddressSet
+  to establish the MAC address for the network adapter.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] RxFilter         Simple network RX filter mask value
+
+  @retval EFI_SUCCESS          The MAC address was set.
+  @retval other                The MAC address was not set.
+
+**/
+EFI_STATUS
+Ax88772RxControl (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT32 RxFilter
+  );
+
+/**
+  Read an SROM location
+
+  This routine calls ::Ax88772UsbCommand to read data from the
+  SROM.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] Address          SROM address
+  @param [out] pData           Buffer to receive the data
+
+  @retval EFI_SUCCESS          The read was successful
+  @retval other                The read failed
+
+**/
+EFI_STATUS
+Ax88772SromRead (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT32 Address,
+  OUT UINT16 * pData
+  );
+
+/**
+  This routine is called at a regular interval to poll for
+  receive packets.
+
+  This routine polls the link state and gets any receive packets
+  by calling ::Ax88772Rx.
+
+  @param [in] Event            Timer event
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+
+**/
+VOID
+Ax88772Timer (
+  IN EFI_EVENT Event,
+  IN NIC_DEVICE * pNicDevice
+  );
+
+/**
+  Send a command to the USB device.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] pRequest         Pointer to the request structure
+  @param [in, out] pBuffer     Data buffer address
+
+  @retval EFI_SUCCESS          The USB transfer was successful
+  @retval other                The USB transfer failed
+
+**/
+EFI_STATUS
+Ax88772UsbCommand (
+  IN NIC_DEVICE * pNicDevice,
+  IN USB_DEVICE_REQUEST * pRequest,
+  IN OUT VOID * pBuffer
+  );
+
+//------------------------------------------------------------------------------
+// EFI Component Name Protocol Support
+//------------------------------------------------------------------------------
+
+extern EFI_COMPONENT_NAME_PROTOCOL   gComponentName;  ///<  Component name protocol declaration
+extern EFI_COMPONENT_NAME2_PROTOCOL  gComponentName2; ///<  Component name 2 protocol declaration
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 3066 or ISO 639-2 language code format.
+  @param [out] ppDriverName     A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+GetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
+  IN  CHAR8 * pLanguage,
+  OUT CHAR16 ** ppDriverName
+  );
+
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+  @param [in] ControllerHandle  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+  @param [in] ChildHandle       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 3066 or ISO 639-2 language code format.
+  @param [out] ppControllerName A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                controller specified by ControllerHandle and
+                                ChildHandle in the language specified by
+                                Language from the point of view of the driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+GetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
+  IN  EFI_HANDLE ControllerHandle,
+  IN OPTIONAL EFI_HANDLE ChildHandle,
+  IN  CHAR8 * pLanguage,
+  OUT CHAR16 ** ppControllerName
+  );
+
+//------------------------------------------------------------------------------
+
+#endif  //  _AX88772_H_
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf
new file mode 100644
index 0000000000..12e7ebc5a2
--- /dev/null
+++ b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf
@@ -0,0 +1,61 @@
+## @file
+# Component description file for ASIX AX88772 USB/Ethernet driver.
+#
+# This module provides support for the ASIX AX88772 USB/Ethernet adapter.
+# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010018
+  BASE_NAME                      = Ax88772
+  FILE_GUID                      = B15239D6-6A01-4808-A0F7-B7F20F073555
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = EntryPoint
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources.common]
+  Ax88772.h
+  Ax88772.c
+  ComponentName.c
+  DriverBinding.c
+  SimpleNetwork.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+  UefiLib
+  UefiBootServicesTableLib
+  BaseMemoryLib
+  DebugLib
+  UefiRuntimeLib
+  UefiDriverEntryPoint
+
+[Protocols]
+  gEfiDevicePathProtocolGuid           ## BY_START
+  gEfiSimpleNetworkProtocolGuid        ## BY_START
+  gEfiUsbIoProtocolGuid                ## TO_START
+
+[Depex]
+  gEfiBdsArchProtocolGuid AND
+  gEfiCpuArchProtocolGuid AND
+  gEfiMetronomeArchProtocolGuid AND
+  gEfiMonotonicCounterArchProtocolGuid AND
+  gEfiRealTimeClockArchProtocolGuid AND
+  gEfiResetArchProtocolGuid AND
+  gEfiRuntimeArchProtocolGuid AND
+  gEfiSecurityArchProtocolGuid AND
+  gEfiTimerArchProtocolGuid AND
+  gEfiVariableWriteArchProtocolGuid AND
+  gEfiVariableArchProtocolGuid AND
+  gEfiWatchdogTimerArchProtocolGuid
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/ComponentName.c b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/ComponentName.c
new file mode 100644
index 0000000000..b6dce7e7cb
--- /dev/null
+++ b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/ComponentName.c
@@ -0,0 +1,178 @@
+/** @file
+  UEFI Component Name(2) protocol implementation.
+
+  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Ax88772.h"
+
+/**
+  EFI Component Name Protocol declaration
+**/
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gComponentName = {
+  GetDriverName,
+  GetControllerName,
+  "eng"
+};
+
+/**
+  EFI Component Name 2 Protocol declaration
+**/
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) GetDriverName,
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) GetControllerName,
+  "en"
+};
+
+
+/**
+  Driver name table declaration
+**/
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
+mDriverNameTable[] = {
+  {"eng;en", L"AX88772 Ethernet Driver"},
+  {NULL,  NULL}
+};
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 3066 or ISO 639-2 language code format.
+  @param [out] ppDriverName     A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+GetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
+  IN  CHAR8 * pLanguage,
+  OUT CHAR16 ** ppDriverName
+  )
+{
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+  Status = LookupUnicodeString2 (
+             pLanguage,
+             pThis->SupportedLanguages,
+             mDriverNameTable,
+             ppDriverName,
+             (BOOLEAN)(pThis == &gComponentName)
+             );
+  DBG_EXIT_HEX ( Status );
+  return Status;
+}
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+  @param [in] ControllerHandle  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+  @param [in] ChildHandle       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 3066 or ISO 639-2 language code format.
+  @param [out] ppControllerName A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                controller specified by ControllerHandle and
+                                ChildHandle in the language specified by
+                                Language from the point of view of the driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+GetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
+  IN  EFI_HANDLE ControllerHandle,
+  IN OPTIONAL EFI_HANDLE ChildHandle,
+  IN  CHAR8 * pLanguage,
+  OUT CHAR16 ** ppControllerName
+  )
+{
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  // Set the controller name
+  //
+  *ppControllerName = L"AX88772 10/100 Ethernet";
+  Status = EFI_SUCCESS;
+
+  //
+  // Return the operation status
+  //
+  DBG_EXIT_HEX ( Status );
+  return Status;
+}
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/DriverBinding.c b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/DriverBinding.c
new file mode 100644
index 0000000000..5bcde4b211
--- /dev/null
+++ b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/DriverBinding.c
@@ -0,0 +1,507 @@
+/** @file
+  Implement the driver binding protocol for Asix AX88772 Ethernet driver.
+
+  Copyright (c) 2011-2013, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Ax88772.h"
+
+/**
+  Verify the controller type
+
+  @param [in] pThis                Protocol instance pointer.
+  @param [in] Controller           Handle of device to test.
+  @param [in] pRemainingDevicePath Not used.
+
+  @retval EFI_SUCCESS          This driver supports this device.
+  @retval other                This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+DriverSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
+  IN EFI_HANDLE Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
+  )
+{
+  EFI_USB_DEVICE_DESCRIPTOR Device;
+  EFI_USB_IO_PROTOCOL * pUsbIo;
+  EFI_STATUS Status;
+
+  //
+  //  Connect to the USB stack
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiUsbIoProtocolGuid,
+                  (VOID **) &pUsbIo,
+                  pThis->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (!EFI_ERROR ( Status )) {
+
+    //
+    //  Get the interface descriptor to check the USB class and find a transport
+    //  protocol handler.
+    //
+    Status = pUsbIo->UsbGetDeviceDescriptor ( pUsbIo, &Device );
+    if (!EFI_ERROR ( Status )) {
+
+      //
+      //  Validate the adapter
+      //
+      if (( VENDOR_ID != Device.IdVendor )
+        || ( PRODUCT_ID != Device.IdProduct )) {
+        Status = EFI_UNSUPPORTED;
+      }
+    }
+
+    //
+    //  Done with the USB stack
+    //
+    gBS->CloseProtocol (
+           Controller,
+           &gEfiUsbIoProtocolGuid,
+           pThis->DriverBindingHandle,
+           Controller
+           );
+  }
+
+  //
+  //  Return the device supported status
+  //
+  return Status;
+}
+
+
+/**
+  Start this driver on Controller by opening UsbIo and DevicePath protocols.
+  Initialize PXE structures, create a copy of the Controller Device Path with the
+  NIC's MAC address appended to it, install the NetworkInterfaceIdentifier protocol
+  on the newly created Device Path.
+
+  @param [in] pThis                Protocol instance pointer.
+  @param [in] Controller           Handle of device to work with.
+  @param [in] pRemainingDevicePath Not used, always produce all possible children.
+
+  @retval EFI_SUCCESS          This driver is added to Controller.
+  @retval other                This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+DriverStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
+  IN EFI_HANDLE Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
+  )
+{
+  EFI_STATUS Status;
+  NIC_DEVICE * pNicDevice;
+  UINTN LengthInBytes;
+
+  DBG_ENTER ( );
+
+  //
+  //  Allocate the device structure
+  //
+  LengthInBytes = sizeof ( *pNicDevice );
+  Status = gBS->AllocatePool (
+                  EfiRuntimeServicesData,
+                  LengthInBytes,
+                  (VOID **) &pNicDevice
+                  );
+  if ( !EFI_ERROR ( Status )) {
+    DEBUG (( DEBUG_POOL | DEBUG_INIT,
+              "0x%08x: Allocate pNicDevice, %d bytes\r\n",
+              pNicDevice,
+              sizeof ( *pNicDevice )));
+
+    //
+    //  Set the structure signature
+    //
+    ZeroMem ( pNicDevice, LengthInBytes );
+    pNicDevice->Signature = DEV_SIGNATURE;
+
+    //
+    //  Connect to the USB I/O protocol
+    //
+    Status = gBS->OpenProtocol (
+                    Controller,
+                    &gEfiUsbIoProtocolGuid,
+                    (VOID **) &pNicDevice->pUsbIo,
+                    pThis->DriverBindingHandle,
+                    Controller,
+                    EFI_OPEN_PROTOCOL_BY_DRIVER
+                    );
+
+    if ( !EFI_ERROR ( Status )) {
+      //
+      //  Allocate the necessary events
+      //
+      Status = gBS->CreateEvent ( EVT_TIMER,
+                                  TPL_AX88772,
+                                  (EFI_EVENT_NOTIFY)Ax88772Timer,
+                                  pNicDevice,
+                                  (VOID **)&pNicDevice->Timer );
+      if ( !EFI_ERROR ( Status )) {
+        DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
+                  "0x%08x: Allocated timer\r\n",
+                  pNicDevice->Timer ));
+
+        //
+        //  Initialize the simple network protocol
+        //
+        pNicDevice->Controller = Controller;
+        SN_Setup ( pNicDevice );
+
+        //
+        //  Start the timer
+        //
+        Status = gBS->SetTimer ( pNicDevice->Timer,
+                                 TimerPeriodic,
+                                 TIMER_MSEC );
+        if ( !EFI_ERROR ( Status )) {
+          //
+          //  Install both the simple network and device path protocols.
+          //
+          Status = gBS->InstallMultipleProtocolInterfaces (
+                          &Controller,
+                          &gEfiCallerIdGuid,
+                          pNicDevice,
+                          &gEfiSimpleNetworkProtocolGuid,
+                          &pNicDevice->SimpleNetwork,
+                          NULL
+                          );
+
+          if ( !EFI_ERROR ( Status )) {
+            DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
+                      "Installed: gEfiCallerIdGuid on   0x%08x\r\n",
+                      Controller ));
+            DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
+                      "Installed: gEfiSimpleNetworkProtocolGuid on   0x%08x\r\n",
+                      Controller ));
+            DBG_EXIT_STATUS ( Status );
+            return Status;
+          }
+          DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
+                    "ERROR - Failed to install gEfiSimpleNetworkProtocol on 0x%08x\r\n",
+                    Controller ));
+        }
+        else {
+          DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
+                    "ERROR - Failed to start the timer, Status: %r\r\n",
+                    Status ));
+        }
+      }
+      else {
+        DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
+                  "ERROR - Failed to create timer event, Status: %r\r\n",
+                  Status ));
+      }
+
+      //
+      //  Done with the USB stack
+      //
+      gBS->CloseProtocol (
+             Controller,
+             &gEfiUsbIoProtocolGuid,
+             pThis->DriverBindingHandle,
+             Controller
+             );
+    }
+
+    //
+    //  Done with the device
+    //
+    gBS->FreePool ( pNicDevice );
+  }
+
+  //
+  //  Display the driver start status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and
+  closing the DevicePath and PciIo protocols on Controller.
+
+  @param [in] pThis                Protocol instance pointer.
+  @param [in] Controller           Handle of device to stop driver on.
+  @param [in] NumberOfChildren     How many children need to be stopped.
+  @param [in] pChildHandleBuffer   Not used.
+
+  @retval EFI_SUCCESS          This driver is removed Controller.
+  @retval EFI_DEVICE_ERROR     The device could not be stopped due to a device error.
+  @retval other                This driver was not removed from this device.
+
+**/
+EFI_STATUS
+EFIAPI
+DriverStop (
+  IN  EFI_DRIVER_BINDING_PROTOCOL * pThis,
+  IN  EFI_HANDLE Controller,
+  IN  UINTN NumberOfChildren,
+  IN  EFI_HANDLE * pChildHandleBuffer
+  )
+{
+  NIC_DEVICE * pNicDevice;
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  //  Determine if this driver is already attached
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiCallerIdGuid,
+                  (VOID **) &pNicDevice,
+                  pThis->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if ( !EFI_ERROR ( Status )) {
+    //
+    //  AX88772 driver is no longer running on this device
+    //
+    gBS->UninstallMultipleProtocolInterfaces (
+              Controller,
+              &gEfiSimpleNetworkProtocolGuid,
+              &pNicDevice->SimpleNetwork,
+              &gEfiCallerIdGuid,
+              pNicDevice,
+              NULL );
+    DEBUG (( DEBUG_POOL | DEBUG_INIT,
+                "Removed:   gEfiSimpleNetworkProtocolGuid from 0x%08x\r\n",
+                Controller ));
+    DEBUG (( DEBUG_POOL | DEBUG_INIT,
+                "Removed:   gEfiCallerIdGuid from 0x%08x\r\n",
+                Controller ));
+
+    //
+    //  Stop the timer
+    //
+    if ( NULL != pNicDevice->Timer ) {
+      gBS->SetTimer ( pNicDevice->Timer, TimerCancel, 0 );
+      gBS->CloseEvent ( pNicDevice->Timer );
+      DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
+                "0x%08x: Released timer\r\n",
+                pNicDevice->Timer ));
+    }
+
+    //
+    //  Done with the device context
+    //
+    DEBUG (( DEBUG_POOL | DEBUG_INIT,
+              "0x%08x: Free pNicDevice, %d bytes\r\n",
+              pNicDevice,
+              sizeof ( *pNicDevice )));
+    gBS->FreePool ( pNicDevice );
+  }
+
+  //
+  //  Return the shutdown status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Driver binding protocol declaration
+**/
+EFI_DRIVER_BINDING_PROTOCOL  gDriverBinding = {
+  DriverSupported,
+  DriverStart,
+  DriverStop,
+  0xa,
+  NULL,
+  NULL
+};
+
+
+/**
+  Ax88772 driver unload routine.
+
+  @param [in] ImageHandle       Handle for the image.
+
+  @retval EFI_SUCCESS           Image may be unloaded
+
+**/
+EFI_STATUS
+EFIAPI
+DriverUnload (
+  IN EFI_HANDLE ImageHandle
+  )
+{
+  UINTN BufferSize;
+  UINTN Index;
+  UINTN Max;
+  EFI_HANDLE * pHandle;
+  EFI_STATUS Status;
+
+  //
+  //  Determine which devices are using this driver
+  //
+  BufferSize = 0;
+  pHandle = NULL;
+  Status = gBS->LocateHandle (
+                  ByProtocol,
+                  &gEfiCallerIdGuid,
+                  NULL,
+                  &BufferSize,
+                  NULL );
+  if ( EFI_BUFFER_TOO_SMALL == Status ) {
+    for ( ; ; ) {
+      //
+      //  One or more block IO devices are present
+      //
+      Status = gBS->AllocatePool (
+                      EfiRuntimeServicesData,
+                      BufferSize,
+                      (VOID **) &pHandle
+                      );
+      if ( EFI_ERROR ( Status )) {
+        DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
+                  "Insufficient memory, failed handle buffer allocation\r\n" ));
+        break;
+      }
+
+      //
+      //  Locate the block IO devices
+      //
+      Status = gBS->LocateHandle (
+                      ByProtocol,
+                      &gEfiCallerIdGuid,
+                      NULL,
+                      &BufferSize,
+                      pHandle );
+      if ( EFI_ERROR ( Status )) {
+        //
+        //  Error getting handles
+        //
+        DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
+                "Failure getting Telnet handles\r\n" ));
+        break;
+      }
+      
+      //
+      //  Remove any use of the driver
+      //
+      Max = BufferSize / sizeof ( pHandle[ 0 ]);
+      for ( Index = 0; Max > Index; Index++ ) {
+        Status = DriverStop ( &gDriverBinding,
+                              pHandle[ Index ],
+                              0,
+                              NULL );
+        if ( EFI_ERROR ( Status )) {
+          DEBUG (( DEBUG_WARN | DEBUG_INIT | DEBUG_INFO,
+                    "WARNING - Failed to shutdown the driver on handle %08x\r\n", pHandle[ Index ]));
+          break;
+        }
+      }
+      break;
+    }
+  }
+  else {
+    if ( EFI_NOT_FOUND == Status ) {
+      //
+      //  No devices were found
+      //
+      Status = EFI_SUCCESS;
+    }
+  }
+
+  //
+  //  Free the handle array
+  //
+  if ( NULL != pHandle ) {
+    gBS->FreePool ( pHandle );
+  }
+
+  //
+  //  Remove the protocols installed by the EntryPoint routine.
+  //
+  if ( !EFI_ERROR ( Status )) {
+    gBS->UninstallMultipleProtocolInterfaces (
+            ImageHandle,
+            &gEfiDriverBindingProtocolGuid,
+            &gDriverBinding,
+            &gEfiComponentNameProtocolGuid,
+            &gComponentName,
+            &gEfiComponentName2ProtocolGuid,
+            &gComponentName2,
+            NULL
+            );
+    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
+            "Removed:   gEfiComponentName2ProtocolGuid from 0x%08x\r\n",
+            ImageHandle ));
+    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
+              "Removed:   gEfiComponentNameProtocolGuid from 0x%08x\r\n",
+              ImageHandle ));
+    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
+              "Removed:   gEfiDriverBindingProtocolGuid from 0x%08x\r\n",
+              ImageHandle ));
+  }
+
+  //
+  //  Return the unload status
+  //
+  return Status;
+}
+
+
+/**
+Ax88772 driver entry point.
+
+@param [in] ImageHandle       Handle for the image.
+@param [in] pSystemTable      Address of the system table.
+
+@retval EFI_SUCCESS           Image successfully loaded.
+
+**/
+EFI_STATUS
+EFIAPI
+EntryPoint (
+  IN EFI_HANDLE ImageHandle,
+  IN EFI_SYSTEM_TABLE * pSystemTable
+  )
+{
+  EFI_STATUS    Status;
+
+  DBG_ENTER ( );
+
+  //
+  //  Add the driver to the list of drivers
+  //
+  Status = EfiLibInstallDriverBindingComponentName2 (
+             ImageHandle,
+             pSystemTable,
+             &gDriverBinding,
+             ImageHandle,
+             &gComponentName,
+             &gComponentName2
+             );
+  ASSERT_EFI_ERROR (Status);
+  if ( !EFI_ERROR ( Status )) {
+    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
+              "Installed: gEfiDriverBindingProtocolGuid on   0x%08x\r\n",
+              ImageHandle ));
+    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
+              "Installed: gEfiComponentNameProtocolGuid on   0x%08x\r\n",
+              ImageHandle ));
+    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
+              "Installed: gEfiComponentName2ProtocolGuid on   0x%08x\r\n",
+              ImageHandle ));
+  }
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/SimpleNetwork.c b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/SimpleNetwork.c
new file mode 100644
index 0000000000..0105d04f5d
--- /dev/null
+++ b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/SimpleNetwork.c
@@ -0,0 +1,1503 @@
+/** @file
+  Provides the Simple Network functions.
+
+  Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Ax88772.h"
+
+/**
+  This function updates the filtering on the receiver.
+
+  This support routine calls ::Ax88772MacAddressSet to update
+  the MAC address.  This routine then rebuilds the multicast
+  hash by calling ::Ax88772MulticastClear and ::Ax88772MulticastSet.
+  Finally this routine enables the receiver by calling
+  ::Ax88772RxControl.
+
+  @param [in] pSimpleNetwork    Simple network mode pointer
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+ReceiveFilterUpdate (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
+  )
+{
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  NIC_DEVICE * pNicDevice;
+  EFI_STATUS Status;
+  UINT32 Index;
+
+  DBG_ENTER ( );
+
+  //
+  // Set the MAC address
+  //
+  pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
+  pMode = pSimpleNetwork->Mode;
+  Status = Ax88772MacAddressSet ( pNicDevice,
+                                  &pMode->CurrentAddress.Addr[0]);
+  if ( !EFI_ERROR ( Status )) {
+    //
+    // Clear the multicast hash table
+    //
+    Ax88772MulticastClear ( pNicDevice );
+
+    //
+    // Load the multicast hash table
+    //
+    if ( 0 != ( pMode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST )) {
+      for ( Index = 0;
+            ( !EFI_ERROR ( Status )) && ( Index < pMode->MCastFilterCount );
+            Index++ ) {
+        //
+        // Enable the next multicast address
+        //
+        Ax88772MulticastSet ( pNicDevice,
+                              &pMode->MCastFilter[ Index ].Addr[0]);
+      }
+    }
+
+    //
+    // Enable the receiver
+    //
+    if ( !EFI_ERROR ( Status )) {
+      Status = Ax88772RxControl ( pNicDevice, pMode->ReceiveFilterSetting );
+    }
+  }
+
+  //
+  // Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  This function updates the SNP driver status.
+  
+  This function gets the current interrupt and recycled transmit
+  buffer status from the network interface.  The interrupt status
+  and the media status are returned as a bit mask in InterruptStatus.
+  If InterruptStatus is NULL, the interrupt status will not be read.
+  Upon successful return of the media status, the MediaPresent field
+  of EFI_SIMPLE_NETWORK_MODE will be updated to reflect any change
+  of media status.  If TxBuf is not NULL, a recycled transmit buffer
+  address will be retrived.  If a recycled transmit buffer address
+  is returned in TxBuf, then the buffer has been successfully
+  transmitted, and the status for that buffer is cleared.
+
+  This function calls ::Ax88772Rx to update the media status and
+  queue any receive packets.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] pInterruptStatus  A pointer to the bit mask of the current active interrupts.
+                                If this is NULL, the interrupt status will not be read from
+                                the device.  If this is not NULL, the interrupt status will
+                                be read from teh device.  When the interrupt status is read,
+                                it will also be cleared.  Clearing the transmit interrupt
+                                does not empty the recycled transmit buffer array.
+  @param [out] ppTxBuf          Recycled transmit buffer address.  The network interface will
+                                not transmit if its internal recycled transmit buffer array is
+                                full.  Reading the transmit buffer does not clear the transmit
+                                interrupt.  If this is NULL, then the transmit buffer status
+                                will not be read.  If there are not transmit buffers to recycle
+                                and TxBuf is not NULL, *TxBuf will be set to NULL.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_GetStatus (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  OUT UINT32 * pInterruptStatus,
+  OUT VOID ** ppTxBuf
+  )
+{
+  BOOLEAN bLinkIdle;
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  NIC_DEVICE * pNicDevice;
+  EFI_STATUS Status;
+  EFI_TPL TplPrevious;
+
+  DBG_ENTER ( );
+
+  //
+  // Verify the parameters
+  //
+  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
+    //
+    // Return the transmit buffer
+    //
+    pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
+    if (( NULL != ppTxBuf ) && ( NULL != pNicDevice->pTxBuffer )) {
+      *ppTxBuf = pNicDevice->pTxBuffer;
+      pNicDevice->pTxBuffer = NULL;
+    }
+
+    //
+    // Determine if interface is running
+    //
+    pMode = pSimpleNetwork->Mode;
+    if ( EfiSimpleNetworkStopped != pMode->State ) {
+      //
+      //  Synchronize with Ax88772Timer
+      //
+      VERIFY_TPL ( TPL_AX88772 );
+      TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
+
+      //
+      // Update the link status
+      //
+      bLinkIdle = pNicDevice->bLinkIdle;
+      pNicDevice->bLinkIdle = TRUE;
+      Ax88772Rx ( pNicDevice, bLinkIdle );
+      pMode->MediaPresent = pNicDevice->bLinkUp;
+
+      //
+      //  Release the synchronization with Ax88772Timer
+      //
+      gBS->RestoreTPL ( TplPrevious );
+
+      //
+      // Return the interrupt status
+      //
+      if ( NULL != pInterruptStatus ) {
+        *pInterruptStatus = 0;
+      }
+      Status = EFI_SUCCESS;
+    }
+    else {
+      Status = EFI_NOT_STARTED;
+    }
+  }
+  else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Resets the network adapter and allocates the transmit and receive buffers
+  required by the network interface; optionally, also requests allocation of
+  additional transmit and receive buffers.  This routine must be called before
+  any other routine in the Simple Network protocol is called.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] ExtraRxBufferSize Size in bytes to add to the receive buffer allocation
+  @param [in] ExtraTxBufferSize Size in bytes to add to the transmit buffer allocation
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_OUT_OF_RESOURCES  There was not enough memory for the transmit and receive buffers
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Initialize (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN UINTN ExtraRxBufferSize,
+  IN UINTN ExtraTxBufferSize
+  )
+{
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+  
+  //
+  // Verify the parameters
+  //
+  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
+    //
+    // Determine if the interface is already started
+    //
+    pMode = pSimpleNetwork->Mode;
+    if ( EfiSimpleNetworkStarted == pMode->State ) {
+      if (( 0 == ExtraRxBufferSize ) && ( 0 == ExtraTxBufferSize )) {
+        //
+        // Start the adapter
+        //
+        Status = SN_Reset ( pSimpleNetwork, FALSE );
+        if ( !EFI_ERROR ( Status )) {
+          //
+          // Update the network state
+          //
+          pMode->State = EfiSimpleNetworkInitialized;
+        }
+      }
+      else {
+        Status = EFI_UNSUPPORTED;
+      }
+    }
+    else {
+      Status = EFI_NOT_STARTED;
+    }
+  }
+  else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+  
+  //
+  // Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  This function converts a multicast IP address to a multicast HW MAC address
+  for all packet transactions.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] bIPv6             Set to TRUE if the multicast IP address is IPv6 [RFC2460].
+                                Set to FALSE if the multicast IP address is IPv4 [RFC 791].
+  @param [in] pIP               The multicast IP address that is to be converted to a
+                                multicast HW MAC address.
+  @param [in] pMAC              The multicast HW MAC address that is to be generated from IP.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_MCastIPtoMAC (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN BOOLEAN bIPv6,
+  IN EFI_IP_ADDRESS * pIP,
+  IN EFI_MAC_ADDRESS * pMAC
+  )
+{
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  // This is not currently supported
+  //
+  Status = EFI_UNSUPPORTED;
+
+  //
+  // Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  This function performs read and write operations on the NVRAM device
+  attached to a network interface.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] ReadWrite         TRUE for read operations, FALSE for write operations.
+  @param [in] Offset            Byte offset in the NVRAM device at which to start the
+                                read or write operation.  This must be a multiple of
+                                NvRamAccessSize and less than NvRamSize.
+  @param [in] BufferSize        The number of bytes to read or write from the NVRAM device.
+                                This must also be a multiple of NvramAccessSize.
+  @param [in, out] pBuffer      A pointer to the data buffer.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_NvData (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN BOOLEAN ReadWrite,
+  IN UINTN Offset,
+  IN UINTN BufferSize,
+  IN OUT VOID * pBuffer
+  )
+{
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  // This is not currently supported
+  //
+  Status = EFI_UNSUPPORTED;
+
+  //
+  // Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Attempt to receive a packet from the network adapter.
+
+  This function retrieves one packet from the receive queue of the network
+  interface.  If there are no packets on the receive queue, then EFI_NOT_READY
+  will be returned.  If there is a packet on the receive queue, and the size
+  of the packet is smaller than BufferSize, then the contents of the packet
+  will be placed in Buffer, and BufferSize will be udpated with the actual
+  size of the packet.  In addition, if SrcAddr, DestAddr, and Protocol are
+  not NULL, then these values will be extracted from the media header and
+  returned.  If BufferSize is smaller than the received packet, then the
+  size of the receive packet will be placed in BufferSize and
+  EFI_BUFFER_TOO_SMALL will be returned.
+
+  This routine calls ::Ax88772Rx to update the media status and
+  empty the network adapter of receive packets.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [out] pHeaderSize      The size, in bytes, of the media header to be filled in by
+                                the Transmit() function.  If HeaderSize is non-zero, then
+                                it must be equal to SimpleNetwork->Mode->MediaHeaderSize
+                                and DestAddr and Protocol parameters must not be NULL.
+  @param [out] pBufferSize      The size, in bytes, of the entire packet (media header and
+                                data) to be transmitted through the network interface.
+  @param [out] pBuffer          A pointer to the packet (media header followed by data) to
+                                to be transmitted.  This parameter can not be NULL.  If
+                                HeaderSize is zero, then the media header is Buffer must
+                                already be filled in by the caller.  If HeaderSize is nonzero,
+                                then the media header will be filled in by the Transmit()
+                                function.
+  @param [out] pSrcAddr         The source HW MAC address.  If HeaderSize is zero, then
+                                this parameter is ignored.  If HeaderSize is nonzero and
+                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
+                                is used for the source HW MAC address.
+  @param [out] pDestAddr        The destination HW MAC address.  If HeaderSize is zero, then
+                                this parameter is ignored.
+  @param [out] pProtocol        The type of header to build.  If HeaderSize is zero, then
+                                this parameter is ignored.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_NOT_READY         No packets have been received on the network interface.
+  @retval EFI_BUFFER_TOO_SMALL  The packet is larger than BufferSize bytes.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Receive (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  OUT UINTN                      * pHeaderSize,
+  OUT UINTN                      * pBufferSize,
+  OUT VOID                       * pBuffer,
+  OUT EFI_MAC_ADDRESS            * pSrcAddr,
+  OUT EFI_MAC_ADDRESS            * pDestAddr,
+  OUT UINT16                     * pProtocol
+  )
+{
+  ETHERNET_HEADER * pHeader;
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  NIC_DEVICE * pNicDevice;
+  RX_TX_PACKET * pRxPacket;
+  EFI_STATUS Status;
+  EFI_TPL TplPrevious;
+  UINT16 Type;
+
+  DBG_ENTER ( );
+
+  //
+  // Verify the parameters
+  //
+  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
+    //
+    // The interface must be running
+    //
+    pMode = pSimpleNetwork->Mode;
+    if ( EfiSimpleNetworkInitialized == pMode->State ) {
+      //
+      //  Synchronize with Ax88772Timer
+      //
+      VERIFY_TPL ( TPL_AX88772 );
+      TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
+
+      //
+      // Update the link status
+      //
+      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
+      Ax88772Rx ( pNicDevice, FALSE );
+      pMode->MediaPresent = pNicDevice->bLinkUp;
+      if ( pMode->MediaPresent ) {
+        //
+        //  Attempt to receive a packet
+        //
+        pRxPacket = pNicDevice->pRxHead;
+        if ( NULL != pRxPacket ) {
+          pNicDevice->pRxHead = pRxPacket->pNext;
+          if ( NULL == pNicDevice->pRxHead ) {
+            pNicDevice->pRxTail = NULL;
+          }
+
+          //
+          // Copy the received packet into the receive buffer
+          //
+          *pBufferSize = pRxPacket->Length;
+          CopyMem ( pBuffer, &pRxPacket->Data[0], pRxPacket->Length );
+          pHeader = (ETHERNET_HEADER *) &pRxPacket->Data[0];
+          if ( NULL != pHeaderSize ) {
+            *pHeaderSize = sizeof ( *pHeader );
+          }
+          if ( NULL != pDestAddr ) {
+            CopyMem ( pDestAddr, &pHeader->dest_addr, PXE_HWADDR_LEN_ETHER );
+          }
+          if ( NULL != pSrcAddr ) {
+            CopyMem ( pSrcAddr, &pHeader->src_addr, PXE_HWADDR_LEN_ETHER );
+          }
+          if ( NULL != pProtocol ) {
+            Type = pHeader->type;
+            Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
+            *pProtocol = Type;
+          }
+          Status = EFI_SUCCESS;
+        }
+        else {
+          //
+          //  No receive packets available
+          //
+          Status = EFI_NOT_READY;
+        }
+      }
+      else {
+        //
+        //  Link no up
+        //
+        Status = EFI_NOT_READY;
+      }
+
+      //
+      //  Release the synchronization with Ax88772Timer
+      //
+      gBS->RestoreTPL ( TplPrevious );
+    }
+    else {
+      Status = EFI_NOT_STARTED;
+    }
+  }
+  else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  This function is used to enable and disable the hardware and software receive
+  filters for the underlying network device.
+
+  The receive filter change is broken down into three steps:
+
+    1.  The filter mask bits that are set (ON) in the Enable parameter
+        are added to the current receive filter settings.
+
+    2.  The filter mask bits that are set (ON) in the Disable parameter
+        are subtracted from the updated receive filter settins.
+
+    3.  If the resulting filter settigns is not supported by the hardware
+        a more liberal setting is selected.
+
+  If the same bits are set in the Enable and Disable parameters, then the bits
+  in the Disable parameter takes precedence.
+
+  If the ResetMCastFilter parameter is TRUE, then the multicast address list
+  filter is disabled (irregardless of what other multicast bits are set in
+  the enable and Disable parameters).  The SNP->Mode->MCastFilterCount field
+  is set to zero.  The SNP->Mode->MCastFilter contents are undefined.
+
+  After enableing or disabling receive filter settings, software should
+  verify the new settings by checking the SNP->Mode->ReceeiveFilterSettings,
+  SNP->Mode->MCastFilterCount and SNP->Mode->MCastFilter fields.
+
+  Note: Some network drivers and/or devices will automatically promote
+  receive filter settings if the requested setting can not be honored.
+  For example, if a request for four multicast addresses is made and
+  the underlying hardware only supports two multicast addresses the
+  driver might set the promiscuous or promiscuous multicast receive filters
+  instead.  The receiving software is responsible for discarding any extra
+  packets that get through the hardware receive filters.
+
+  If ResetMCastFilter is TRUE, then the multicast receive filter list
+  on the network interface will be reset to the default multicast receive
+  filter list.  If ResetMCastFilter is FALSE, and this network interface
+  allows the multicast receive filter list to be modified, then the
+  MCastFilterCnt and MCastFilter are used to update the current multicast
+  receive filter list.  The modified receive filter list settings can be
+  found in the MCastFilter field of EFI_SIMPLE_NETWORK_MODE.
+
+  This routine calls ::ReceiveFilterUpdate to update the receive
+  state in the network adapter.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] Enable            A bit mask of receive filters to enable on the network interface.
+  @param [in] Disable           A bit mask of receive filters to disable on the network interface.
+                                For backward compatibility with EFI 1.1 platforms, the
+                                EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit must be set
+                                when the ResetMCastFilter parameter is TRUE.
+  @param [in] bResetMCastFilter Set to TRUE to reset the contents of the multicast receive
+                                filters on the network interface to their default values.
+  @param [in] MCastFilterCnt    Number of multicast HW MAC address in the new MCastFilter list.
+                                This value must be less than or equal to the MaxMCastFilterCnt
+                                field of EFI_SIMPLE_NETWORK_MODE.  This field is optional if
+                                ResetMCastFilter is TRUE.
+  @param [in] pMCastFilter      A pointer to a list of new multicast receive filter HW MAC
+                                addresses.  This list will replace any existing multicast
+                                HW MAC address list.  This field is optional if ResetMCastFilter
+                                is TRUE.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_ReceiveFilters (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN UINT32 Enable,
+  IN UINT32 Disable,
+  IN BOOLEAN bResetMCastFilter,
+  IN UINTN MCastFilterCnt,
+  IN EFI_MAC_ADDRESS * pMCastFilter
+  )
+{
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  EFI_MAC_ADDRESS * pMulticastAddress;
+  EFI_MAC_ADDRESS * pTableEnd;
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  // Verify the parameters
+  //
+  Status = EFI_INVALID_PARAMETER;
+  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
+    pMode = pSimpleNetwork->Mode;
+
+    //
+    //  Update the multicast list if necessary
+    //
+    if ( !bResetMCastFilter ) {
+      if ( 0 != MCastFilterCnt ) {
+        if (( MAX_MCAST_FILTER_CNT >= MCastFilterCnt )
+          && ( NULL != pMCastFilter )) {
+          //
+          // Verify the multicast addresses
+          //
+          pMulticastAddress = pMCastFilter;
+          pTableEnd = pMulticastAddress + MCastFilterCnt;
+          while ( pTableEnd > pMulticastAddress ) {
+            //
+            // The first digit of the multicast address must have the LSB set
+            //
+            if ( 0 == ( pMulticastAddress->Addr[0] & 1 )) {
+              //
+              // Invalid multicast address
+              //
+              break;
+            }
+            pMulticastAddress += 1;
+          }
+          if ( pTableEnd == pMulticastAddress ) {
+            //
+            // Update the multicast filter list.
+            //
+            CopyMem (&pMode->MCastFilter[0],
+                     pMCastFilter,
+                     MCastFilterCnt * sizeof ( *pMCastFilter ));
+            Status = EFI_SUCCESS;
+          }
+        }
+      }
+      else {
+        Status = EFI_SUCCESS;
+      }
+    }
+    else {
+      //
+      // No multicast address list is specified
+      //
+      MCastFilterCnt = 0;
+      Status = EFI_SUCCESS;
+    }
+    if ( !EFI_ERROR ( Status )) {
+      //
+      // The parameters are valid!
+      //
+      pMode->ReceiveFilterSetting |= Enable;
+      pMode->ReceiveFilterSetting &= ~Disable;
+      pMode->MCastFilterCount = (UINT32)MCastFilterCnt;
+
+      //
+      // Update the receive filters in the adapter
+      //
+      Status = ReceiveFilterUpdate ( pSimpleNetwork );
+    }
+  }
+
+  //
+  // Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Reset the network adapter.
+
+  Resets a network adapter and reinitializes it with the parameters that
+  were provided in the previous call to Initialize ().  The transmit and
+  receive queues are cleared.  Receive filters, the station address, the
+  statistics, and the multicast-IP-to-HW MAC addresses are not reset by
+  this call.
+
+  This routine calls ::Ax88772Reset to perform the adapter specific
+  reset operation.  This routine also starts the link negotiation
+  by calling ::Ax88772NegotiateLinkStart.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] bExtendedVerification  Indicates that the driver may perform a more
+                                exhaustive verification operation of the device
+                                during reset.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Reset (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN BOOLEAN bExtendedVerification
+  )
+{
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  NIC_DEVICE * pNicDevice;
+  RX_TX_PACKET * pRxPacket;
+  EFI_STATUS Status;
+  EFI_TPL TplPrevious;
+
+  DBG_ENTER ( );
+
+  //
+  //  Verify the parameters
+  //
+  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
+    //
+    //  Synchronize with Ax88772Timer
+    //
+    VERIFY_TPL ( TPL_AX88772 );
+    TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
+
+    //
+    //  Update the device state
+    //
+    pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
+    pNicDevice->bComplete = FALSE;
+    pNicDevice->bLinkUp = FALSE;
+
+    pMode = pSimpleNetwork->Mode;
+    pMode->MediaPresent = FALSE;
+
+    //
+    //  Discard any received packets
+    //
+    while ( NULL != pNicDevice->pRxHead ) {
+      //
+      //  Remove the packet from the received packet list
+      //
+      pRxPacket = pNicDevice->pRxHead;
+      pNicDevice->pRxHead = pRxPacket->pNext;
+
+      //
+      //  Queue the packet to the free list
+      //
+      pRxPacket->pNext = pNicDevice->pRxFree;
+      pNicDevice->pRxFree = pRxPacket;
+    }
+    pNicDevice->pRxTail = NULL;
+
+    //
+    //  Reset the device
+    //
+    Status = Ax88772Reset ( pNicDevice );
+    if ( !EFI_ERROR ( Status )) {
+      //
+      //  Update the receive filters in the adapter
+      //
+      Status = ReceiveFilterUpdate ( pSimpleNetwork );
+
+      //
+      //  Try to get a connection to the network
+      //
+      if ( !EFI_ERROR ( Status )) {
+        //
+        //  Start the autonegotiation
+        //
+        Status = Ax88772NegotiateLinkStart ( pNicDevice );
+      }
+    }
+
+    //
+    //  Release the synchronization with Ax88772Timer
+    //
+    gBS->RestoreTPL ( TplPrevious );
+  }
+  else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Initialize the simple network protocol.
+
+  This routine calls ::Ax88772MacAddressGet to obtain the
+  MAC address.
+
+  @param [in] pNicDevice       NIC_DEVICE_INSTANCE pointer
+
+  @retval EFI_SUCCESS     Setup was successful
+
+**/
+EFI_STATUS
+SN_Setup (
+  IN NIC_DEVICE * pNicDevice
+  )
+{
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork;
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  // Initialize the simple network protocol
+  //
+  pSimpleNetwork = &pNicDevice->SimpleNetwork;
+  pSimpleNetwork->Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;
+  pSimpleNetwork->Start = (EFI_SIMPLE_NETWORK_START)SN_Start;
+  pSimpleNetwork->Stop = (EFI_SIMPLE_NETWORK_STOP)SN_Stop;
+  pSimpleNetwork->Initialize = (EFI_SIMPLE_NETWORK_INITIALIZE)SN_Initialize;
+  pSimpleNetwork->Reset = (EFI_SIMPLE_NETWORK_RESET)SN_Reset;
+  pSimpleNetwork->Shutdown = (EFI_SIMPLE_NETWORK_SHUTDOWN)SN_Shutdown;
+  pSimpleNetwork->ReceiveFilters = (EFI_SIMPLE_NETWORK_RECEIVE_FILTERS)SN_ReceiveFilters;
+  pSimpleNetwork->StationAddress = (EFI_SIMPLE_NETWORK_STATION_ADDRESS)SN_StationAddress;
+  pSimpleNetwork->Statistics = (EFI_SIMPLE_NETWORK_STATISTICS)SN_Statistics;
+  pSimpleNetwork->MCastIpToMac = (EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC)SN_MCastIPtoMAC;
+  pSimpleNetwork->NvData = (EFI_SIMPLE_NETWORK_NVDATA)SN_NvData;
+  pSimpleNetwork->GetStatus = (EFI_SIMPLE_NETWORK_GET_STATUS)SN_GetStatus;
+  pSimpleNetwork->Transmit = (EFI_SIMPLE_NETWORK_TRANSMIT)SN_Transmit;
+  pSimpleNetwork->Receive = (EFI_SIMPLE_NETWORK_RECEIVE)SN_Receive;
+  pSimpleNetwork->WaitForPacket = NULL;
+  pMode = &pNicDevice->SimpleNetworkData;
+  pSimpleNetwork->Mode = pMode;
+
+  pMode->State = EfiSimpleNetworkStopped;
+  pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
+  pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
+  pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
+  pMode->NvRamSize = 0;
+  pMode->NvRamAccessSize = 0;
+  pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
+                           | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
+                           | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
+                           | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
+                           | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
+  pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
+                              | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
+  pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
+  pMode->MCastFilterCount = 0;
+  SetMem ( &pMode->BroadcastAddress,
+           PXE_HWADDR_LEN_ETHER,
+           0xff );
+  pMode->IfType = EfiNetworkInterfaceUndi;
+  pMode->MacAddressChangeable = TRUE;
+  pMode->MultipleTxSupported = TRUE;
+  pMode->MediaPresentSupported = TRUE;
+  pMode->MediaPresent = FALSE;
+
+  //
+  //  Read the MAC address
+  //
+  pNicDevice->PhyId = PHY_ID_INTERNAL;
+  pNicDevice->b100Mbps = TRUE;
+  pNicDevice->bFullDuplex = TRUE;
+
+  Status = gBS->AllocatePool ( EfiRuntimeServicesData, 
+                               MAX_BULKIN_SIZE,
+                               (VOID **) &pNicDevice->pBulkInBuff);
+  if ( EFI_ERROR(Status)) {
+    DEBUG (( EFI_D_ERROR, "Memory are not enough\n"));
+    return Status;
+  }
+        
+  Status = Ax88772MacAddressGet (
+                pNicDevice,
+                &pMode->PermanentAddress.Addr[0]);
+  if ( !EFI_ERROR ( Status )) {
+    //
+    //  Display the MAC address
+    //
+    DEBUG (( DEBUG_MAC_ADDRESS | DEBUG_INFO,
+              "MAC: %02x-%02x-%02x-%02x-%02x-%02x\n",
+              pMode->PermanentAddress.Addr[0],
+              pMode->PermanentAddress.Addr[1],
+              pMode->PermanentAddress.Addr[2],
+              pMode->PermanentAddress.Addr[3],
+              pMode->PermanentAddress.Addr[4],
+              pMode->PermanentAddress.Addr[5]));
+
+    //
+    //  Use the hardware address as the current address
+    //
+    CopyMem ( &pMode->CurrentAddress,
+              &pMode->PermanentAddress,
+              PXE_HWADDR_LEN_ETHER );
+  }
+
+  //
+  //  Return the setup status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  This routine starts the network interface.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_ALREADY_STARTED   The network interface was already started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Start (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
+  )
+{
+  NIC_DEVICE * pNicDevice;
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  EFI_STATUS Status;
+  
+  DBG_ENTER ( );
+  
+  //
+  // Verify the parameters
+  //
+  Status = EFI_INVALID_PARAMETER;
+  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
+    pMode = pSimpleNetwork->Mode;
+    if ( EfiSimpleNetworkStopped == pMode->State ) {
+      //
+      // Initialize the mode structure
+      // NVRAM access is not supported
+      //
+      ZeroMem ( pMode, sizeof ( *pMode ));
+  
+      pMode->State = EfiSimpleNetworkStarted;
+      pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
+      pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
+      pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
+      pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
+                               | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
+                               | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
+                               | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
+                               | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
+      pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
+      pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
+      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
+      Status = Ax88772MacAddressGet ( pNicDevice, &pMode->PermanentAddress.Addr[0]);
+      CopyMem ( &pMode->CurrentAddress,
+                &pMode->PermanentAddress,
+                sizeof ( pMode->CurrentAddress ));
+      pMode->BroadcastAddress.Addr[0] = 0xff;
+      pMode->BroadcastAddress.Addr[1] = 0xff;
+      pMode->BroadcastAddress.Addr[2] = 0xff;
+      pMode->BroadcastAddress.Addr[3] = 0xff;
+      pMode->BroadcastAddress.Addr[4] = 0xff;
+      pMode->BroadcastAddress.Addr[5] = 0xff;
+      pMode->IfType = 1;
+      pMode->MacAddressChangeable = TRUE;
+      pMode->MultipleTxSupported = TRUE;
+      pMode->MediaPresentSupported = TRUE;
+      pMode->MediaPresent = FALSE;
+    }
+    else {
+      Status = EFI_ALREADY_STARTED;
+    }
+  }
+  
+  //
+  // Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Set the MAC address.
+  
+  This function modifies or resets the current station address of a
+  network interface.  If Reset is TRUE, then the current station address
+  is set ot the network interface's permanent address.  If Reset if FALSE
+  then the current station address is changed to the address specified by
+  pNew.
+
+  This routine calls ::Ax88772MacAddressSet to update the MAC address
+  in the network adapter.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] bReset            Flag used to reset the station address to the
+                                network interface's permanent address.
+  @param [in] pNew              New station address to be used for the network
+                                interface.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_StationAddress (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN BOOLEAN bReset,
+  IN EFI_MAC_ADDRESS * pNew
+  )
+{
+  NIC_DEVICE * pNicDevice;
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  // Verify the parameters
+  //
+  if (( NULL != pSimpleNetwork )
+    && ( NULL != pSimpleNetwork->Mode )
+    && (( !bReset ) || ( bReset && ( NULL != pNew )))) {
+    //
+    // Verify that the adapter is already started
+    //
+    pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
+    pMode = pSimpleNetwork->Mode;
+    if ( EfiSimpleNetworkStarted == pMode->State ) {
+      //
+      // Determine the adapter MAC address
+      //
+      if ( bReset ) {
+        //
+        // Use the permanent address
+        //
+        CopyMem ( &pMode->CurrentAddress,
+                  &pMode->PermanentAddress,
+                  sizeof ( pMode->CurrentAddress ));
+      }
+      else {
+        //
+        // Use the specified address
+        //
+        CopyMem ( &pMode->CurrentAddress,
+                  pNew,
+                  sizeof ( pMode->CurrentAddress ));
+      }
+
+      //
+      // Update the address on the adapter
+      //
+      Status = Ax88772MacAddressSet ( pNicDevice, &pMode->CurrentAddress.Addr[0]);
+    }
+    else {
+      Status = EFI_NOT_STARTED;
+    }
+  }
+  else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  This function resets or collects the statistics on a network interface.
+  If the size of the statistics table specified by StatisticsSize is not
+  big enough for all of the statistics that are collected by the network
+  interface, then a partial buffer of statistics is returned in
+  StatisticsTable.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] bReset            Set to TRUE to reset the statistics for the network interface.
+  @param [in, out] pStatisticsSize  On input the size, in bytes, of StatisticsTable.  On output
+                                the size, in bytes, of the resulting table of statistics.
+  @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
+                                conains the statistics.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_BUFFER_TOO_SMALL  The pStatisticsTable is NULL or the buffer is too small.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Statistics (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN BOOLEAN bReset,
+  IN OUT UINTN * pStatisticsSize,
+  OUT EFI_NETWORK_STATISTICS * pStatisticsTable
+  )
+{
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  // This is not currently supported
+  //
+  Status = EFI_UNSUPPORTED;
+
+  //
+  // Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  This function stops a network interface.  This call is only valid
+  if the network interface is in the started state.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Stop (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
+  )
+{
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  EFI_STATUS Status;
+  
+  DBG_ENTER ( );
+  
+  //
+  // Verify the parameters
+  //
+  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
+    //
+    // Determine if the interface is started
+    //
+    pMode = pSimpleNetwork->Mode;
+    if ( EfiSimpleNetworkStopped != pMode->State ) {
+      if ( EfiSimpleNetworkStarted == pMode->State ) {
+        //
+        //  Release the resources acquired in SN_Start
+        //
+
+        //
+        //  Mark the adapter as stopped
+        //
+        pMode->State = EfiSimpleNetworkStopped;
+        Status = EFI_SUCCESS;
+      }
+      else {
+        Status = EFI_UNSUPPORTED;
+      }
+    }
+    else {
+      Status = EFI_NOT_STARTED;
+    }
+  }
+  else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+  
+  //
+  // Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  This function releases the memory buffers assigned in the Initialize() call.
+  Pending transmits and receives are lost, and interrupts are cleared and disabled.
+  After this call, only Initialize() and Stop() calls may be used.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Shutdown (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
+  )
+{
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  UINT32 RxFilter;
+  EFI_STATUS Status;
+  
+  DBG_ENTER ( );
+  
+  //
+  // Verify the parameters
+  //
+  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
+    //
+    // Determine if the interface is already started
+    //
+    pMode = pSimpleNetwork->Mode;
+    if ( EfiSimpleNetworkInitialized == pMode->State ) {
+      //
+      // Stop the adapter
+      //
+      RxFilter = pMode->ReceiveFilterSetting;
+      pMode->ReceiveFilterSetting = 0;
+      Status = SN_Reset ( pSimpleNetwork, FALSE );
+      pMode->ReceiveFilterSetting = RxFilter;
+      if ( !EFI_ERROR ( Status )) {
+        //
+        // Release the resources acquired by SN_Initialize
+        //
+
+        //
+        // Update the network state
+        //
+        pMode->State = EfiSimpleNetworkStarted;
+      }
+    }
+    else {
+      Status = EFI_NOT_STARTED;
+    }
+  }
+  else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+  
+  //
+  // Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Send a packet over the network.
+
+  This function places the packet specified by Header and Buffer on
+  the transmit queue.  This function performs a non-blocking transmit
+  operation.  When the transmit is complete, the buffer is returned
+  via the GetStatus() call.
+
+  This routine calls ::Ax88772Rx to empty the network adapter of
+  receive packets.  The routine then passes the transmit packet
+  to the network adapter.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] HeaderSize        The size, in bytes, of the media header to be filled in by
+                                the Transmit() function.  If HeaderSize is non-zero, then
+                                it must be equal to SimpleNetwork->Mode->MediaHeaderSize
+                                and DestAddr and Protocol parameters must not be NULL.
+  @param [in] BufferSize        The size, in bytes, of the entire packet (media header and
+                                data) to be transmitted through the network interface.
+  @param [in] pBuffer           A pointer to the packet (media header followed by data) to
+                                to be transmitted.  This parameter can not be NULL.  If
+                                HeaderSize is zero, then the media header is Buffer must
+                                already be filled in by the caller.  If HeaderSize is nonzero,
+                                then the media header will be filled in by the Transmit()
+                                function.
+  @param [in] pSrcAddr          The source HW MAC address.  If HeaderSize is zero, then
+                                this parameter is ignored.  If HeaderSize is nonzero and
+                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
+                                is used for the source HW MAC address.
+  @param [in] pDestAddr         The destination HW MAC address.  If HeaderSize is zero, then
+                                this parameter is ignored.
+  @param [in] pProtocol         The type of header to build.  If HeaderSize is zero, then
+                                this parameter is ignored.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_NOT_READY         The network interface is too busy to accept this transmit request.
+  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Transmit (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN UINTN HeaderSize,
+  IN UINTN BufferSize,
+  IN VOID * pBuffer,
+  IN EFI_MAC_ADDRESS * pSrcAddr,
+  IN EFI_MAC_ADDRESS * pDestAddr,
+  IN UINT16 * pProtocol
+  )
+{
+  RX_TX_PACKET Packet;
+  ETHERNET_HEADER * pHeader;
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  NIC_DEVICE * pNicDevice;
+  EFI_USB_IO_PROTOCOL * pUsbIo;
+  EFI_STATUS Status;
+  EFI_TPL TplPrevious;
+  UINTN TransferLength;
+  UINT32 TransferStatus;
+  UINT16 Type;
+
+  DBG_ENTER ( );
+
+  //
+  // Verify the parameters
+  //
+  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
+    //
+    // The interface must be running
+    //
+    pMode = pSimpleNetwork->Mode;
+    if ( EfiSimpleNetworkInitialized == pMode->State ) {
+      //
+      //  Synchronize with Ax88772Timer
+      //
+      VERIFY_TPL ( TPL_AX88772 );
+      TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
+
+      //
+      // Update the link status
+      //
+      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
+
+      //
+      //No need to call receive to receive packet
+      //
+      //Ax88772Rx ( pNicDevice, FALSE );
+      pMode->MediaPresent = pNicDevice->bLinkUp;
+
+      //
+      //  Release the synchronization with Ax88772Timer
+      //
+      gBS->RestoreTPL ( TplPrevious );
+      if ( pMode->MediaPresent ) {
+        //
+        //  Copy the packet into the USB buffer
+        //
+        CopyMem ( &Packet.Data[0], pBuffer, BufferSize );
+        Packet.Length = (UINT16) BufferSize;
+
+        //
+        //  Transmit the packet
+        //
+        pHeader = (ETHERNET_HEADER *) &Packet.Data[0];
+        if ( 0 != HeaderSize ) {
+          if ( NULL != pDestAddr ) {
+            CopyMem ( &pHeader->dest_addr, pDestAddr, PXE_HWADDR_LEN_ETHER );
+          }
+          if ( NULL != pSrcAddr ) {
+            CopyMem ( &pHeader->src_addr, pSrcAddr, PXE_HWADDR_LEN_ETHER );
+          }
+          else {
+            CopyMem ( &pHeader->src_addr, &pMode->CurrentAddress.Addr[0], PXE_HWADDR_LEN_ETHER );
+          }
+          if ( NULL != pProtocol ) {
+            Type = *pProtocol;
+          }
+          else {
+            Type = Packet.Length;
+          }
+          Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
+          pHeader->type = Type;
+        }
+        if ( Packet.Length < MIN_ETHERNET_PKT_SIZE ) {
+          Packet.Length = MIN_ETHERNET_PKT_SIZE;
+          ZeroMem ( &Packet.Data[ BufferSize ],
+                    Packet.Length - BufferSize );
+        }
+        DEBUG (( DEBUG_TX | DEBUG_INFO,
+                  "TX: %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x  %d bytes\r\n",
+                  Packet.Data[0],
+                  Packet.Data[1],
+                  Packet.Data[2],
+                  Packet.Data[3],
+                  Packet.Data[4],
+                  Packet.Data[5],
+                  Packet.Data[6],
+                  Packet.Data[7],
+                  Packet.Data[8],
+                  Packet.Data[9],
+                  Packet.Data[10],
+                  Packet.Data[11],
+                  Packet.Data[12],
+                  Packet.Data[13],
+                  Packet.Length ));
+        Packet.LengthBar = ~Packet.Length;
+        TransferLength = sizeof ( Packet.Length )
+                       + sizeof ( Packet.LengthBar )
+                       + Packet.Length;
+
+        //
+        //  Work around USB bus driver bug where a timeout set by receive
+        //  succeeds but the timeout expires immediately after, causing the
+        //  transmit operation to timeout.
+        //
+        pUsbIo = pNicDevice->pUsbIo;
+        Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
+                                           BULK_OUT_ENDPOINT,
+                                           &Packet.Length,
+                                           &TransferLength,
+                                           0xfffffffe,
+                                           &TransferStatus );
+        if ( !EFI_ERROR ( Status )) {
+          Status = TransferStatus;
+        }
+        if (( !EFI_ERROR ( Status ))
+          && ( TransferLength != (UINTN)( Packet.Length + 4 ))) {
+          Status = EFI_WARN_WRITE_FAILURE;
+        }
+        if ( EFI_SUCCESS == Status ) {
+          pNicDevice->pTxBuffer = pBuffer;
+        }
+        else {
+          DEBUG (( DEBUG_ERROR | DEBUG_INFO,
+                    "Ax88772 USB transmit error, TransferLength: %d, Status: %r\r\n",
+                    sizeof ( Packet.Length ) + Packet.Length,
+                    Status ));
+          //
+          //  Reset the controller to fix the error
+          //
+          if ( EFI_DEVICE_ERROR == Status ) {
+            SN_Reset ( pSimpleNetwork, FALSE );
+          }
+        }
+      }
+      else {
+        //
+        // No packets available.
+        //
+        Status = EFI_NOT_READY;
+      }
+    }
+    else {
+      Status = EFI_NOT_STARTED;
+    }
+  }
+  else {
+    DEBUG (( DEBUG_ERROR | DEBUG_INFO,
+              "Ax88772 invalid transmit parameter\r\n"
+              "  0x%08x: HeaderSize\r\n"
+              "  0x%08x: BufferSize\r\n"
+              "  0x%08x: Buffer\r\n"
+              "  0x%08x: SrcAddr\r\n"
+              "  0x%08x: DestAddr\r\n"
+              "  0x%04x:     Protocol\r\n",
+              HeaderSize,
+              BufferSize,
+              pBuffer,
+              pSrcAddr,
+              pDestAddr,
+              pProtocol ));
+    Status = EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c
new file mode 100644
index 0000000000..12684a6bd1
--- /dev/null
+++ b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c
@@ -0,0 +1,875 @@
+/** @file
+  Implement the interface to the AX88772 Ethernet controller.
+
+  This module implements the interface to the ASIX AX88772
+  USB to Ethernet MAC with integrated 10/100 PHY.  Note that this implementation
+  only supports the integrated PHY since no other test cases were available.
+
+  Copyright (c) 2011, Intel Corporation. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Ax88772.h"
+
+
+/**
+  Compute the CRC 
+
+  @param [in] pMacAddress      Address of a six byte buffer to containing the MAC address.
+
+  @returns The CRC-32 value associated with this MAC address
+
+**/
+UINT32
+Ax88772Crc (
+  IN UINT8 * pMacAddress
+  )
+{
+  UINT32 BitNumber;
+  INT32 Carry;
+  INT32 Crc;
+  UINT32 Data;
+  UINT8 * pEnd;
+
+  //
+  //  Walk the MAC address
+  //
+  Crc = -1;
+  pEnd = &pMacAddress[ PXE_HWADDR_LEN_ETHER ];
+  while ( pEnd > pMacAddress ) {
+    Data = *pMacAddress++;
+    //
+    //  CRC32: x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
+    //
+    //          1 0000 0100 1100 0001 0001 1101 1011 0111
+    //
+    for ( BitNumber = 0; 8 > BitNumber; BitNumber++ ) {
+      Carry = (( Crc >> 31 ) & 1 ) ^ ( Data & 1 );
+      Crc <<= 1;
+      if ( 0 != Carry ) {
+        Crc ^= 0x04c11db7;
+      }
+      Data >>= 1;
+    }
+  }
+  //
+  //  Return the CRC value
+  //
+  return (UINT32) Crc;
+}
+
+
+/**
+  Get the MAC address
+
+  This routine calls ::Ax88772UsbCommand to request the MAC
+  address from the network adapter.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [out] pMacAddress      Address of a six byte buffer to receive the MAC address.
+
+  @retval EFI_SUCCESS          The MAC address is available.
+  @retval other                The MAC address is not valid.
+
+**/
+EFI_STATUS
+Ax88772MacAddressGet (
+  IN NIC_DEVICE * pNicDevice,
+  OUT UINT8 * pMacAddress
+  )
+{
+  USB_DEVICE_REQUEST SetupMsg;
+  EFI_STATUS Status;
+
+  //
+  //  Set the register address.
+  //
+  SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
+                       | USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_MAC_ADDRESS_READ;
+  SetupMsg.Value = 0;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = PXE_HWADDR_LEN_ETHER;
+
+  //
+  //  Read the PHY register
+  //
+  Status = Ax88772UsbCommand ( pNicDevice,
+                               &SetupMsg,
+                               pMacAddress );
+  return Status;
+}
+
+
+/**
+  Set the MAC address
+
+  This routine calls ::Ax88772UsbCommand to set the MAC address
+  in the network adapter.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] pMacAddress      Address of a six byte buffer to containing the new MAC address.
+
+  @retval EFI_SUCCESS          The MAC address was set.
+  @retval other                The MAC address was not set.
+
+**/
+EFI_STATUS
+Ax88772MacAddressSet (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT8 * pMacAddress
+  )
+{
+  USB_DEVICE_REQUEST SetupMsg;
+  EFI_STATUS Status;
+
+  //
+  //  Set the register address.
+  //
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_MAC_ADDRESS_WRITE;
+  SetupMsg.Value = 0;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = PXE_HWADDR_LEN_ETHER;
+  
+  //
+  //  Read the PHY register
+  //
+  Status = Ax88772UsbCommand ( pNicDevice,
+                               &SetupMsg,
+                               pMacAddress );
+  return Status;
+}
+
+/**
+  Clear the multicast hash table
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+
+**/
+VOID
+Ax88772MulticastClear (
+  IN NIC_DEVICE * pNicDevice
+  )
+{
+  int i = 0;
+  //
+  // Clear the multicast hash table
+  //
+  for ( i = 0 ; i < 8 ; i ++ )
+     pNicDevice->MulticastHash[0] = 0;
+}
+
+/**
+  Enable a multicast address in the multicast hash table
+
+  This routine calls ::Ax88772Crc to compute the hash bit for
+  this MAC address.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] pMacAddress      Address of a six byte buffer to containing the MAC address.
+
+**/
+VOID
+Ax88772MulticastSet (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT8 * pMacAddress
+  )
+{
+  UINT32 Crc;
+
+  //
+  //  Compute the CRC on the destination address
+  //
+  Crc = Ax88772Crc ( pMacAddress ) >> 26;
+
+  //
+  //  Set the bit corresponding to the destination address
+  //
+   pNicDevice->MulticastHash [ Crc >> 3 ] |= ( 1<< (Crc& 7));
+}
+
+/**
+  Start the link negotiation
+
+  This routine calls ::Ax88772PhyWrite to start the PHY's link
+  negotiation.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+
+  @retval EFI_SUCCESS          The link negotiation was started.
+  @retval other                Failed to start the link negotiation.
+
+**/
+EFI_STATUS
+Ax88772NegotiateLinkStart (
+  IN NIC_DEVICE * pNicDevice
+  )
+{
+  UINT16 Control;
+  EFI_STATUS Status;
+  int i; 
+  //
+  // Set the supported capabilities.
+  //
+  Status = Ax88772PhyWrite ( pNicDevice,
+                             PHY_ANAR,
+                             AN_CSMA_CD
+                             | AN_TX_FDX | AN_TX_HDX
+                             | AN_10_FDX | AN_10_HDX );
+  if ( !EFI_ERROR ( Status )) {
+    //
+    // Set the link speed and duplex
+    //
+    Control = BMCR_AUTONEGOTIATION_ENABLE
+            | BMCR_RESTART_AUTONEGOTIATION;
+    if ( pNicDevice->b100Mbps ) {
+      Control |= BMCR_100MBPS;
+    }
+    if ( pNicDevice->bFullDuplex ) {
+      Control |= BMCR_FULL_DUPLEX;
+    }
+    Status = Ax88772PhyWrite ( pNicDevice, PHY_BMCR, Control );
+  }
+  
+  if (!EFI_ERROR(Status)) {
+    i = 0;
+    do {
+      
+        if (pNicDevice->bComplete && pNicDevice->bLinkUp) {
+            pNicDevice->SimpleNetwork.Mode->MediaPresent 
+               = pNicDevice->bLinkUp & pNicDevice->bComplete;
+           break;
+       }
+       else {
+            gBS->Stall(AUTONEG_DELAY);
+            Status = Ax88772NegotiateLinkComplete ( pNicDevice,
+                                            &pNicDevice->PollCount,
+                                            &pNicDevice->bComplete,
+                                            &pNicDevice->bLinkUp,
+                                            &pNicDevice->b100Mbps,
+                                            &pNicDevice->bFullDuplex );
+            i++;
+        }
+    }while(!pNicDevice->bLinkUp && i < AUTONEG_POLLCNT);
+  }
+  return Status;
+}
+
+
+/**
+  Complete the negotiation of the PHY link
+
+  This routine calls ::Ax88772PhyRead to determine if the
+  link negotiation is complete.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in, out] pPollCount  Address of number of times this routine was polled
+  @param [out] pbComplete      Address of boolean to receive complate status.
+  @param [out] pbLinkUp        Address of boolean to receive link status, TRUE=up.
+  @param [out] pbHiSpeed       Address of boolean to receive link speed, TRUE=100Mbps.
+  @param [out] pbFullDuplex    Address of boolean to receive link duplex, TRUE=full.
+
+  @retval EFI_SUCCESS          The MAC address is available.
+  @retval other                The MAC address is not valid.
+
+**/
+EFI_STATUS
+Ax88772NegotiateLinkComplete (
+  IN NIC_DEVICE * pNicDevice,
+  IN OUT UINTN * pPollCount,
+  OUT BOOLEAN * pbComplete,
+  OUT BOOLEAN * pbLinkUp,
+  OUT BOOLEAN * pbHiSpeed,
+  OUT BOOLEAN * pbFullDuplex
+  )
+{
+  UINT16 Mask;
+  UINT16 PhyData;
+  EFI_STATUS  Status;
+ 
+  //
+  //  Determine if the link is up.
+  //
+  *pbComplete = FALSE;  
+
+  //
+  //  Get the link status
+  //
+  Status = Ax88772PhyRead ( pNicDevice,
+                            PHY_BMSR,
+                            &PhyData );
+
+  if ( !EFI_ERROR ( Status )) {
+      *pbLinkUp = (BOOLEAN)( 0 != ( PhyData & BMSR_LINKST ));
+      if ( 0 == *pbLinkUp ) {
+        DEBUG (( EFI_D_INFO, "Link Down\n" ));
+      }      
+      else {
+         *pbComplete = (BOOLEAN)( 0 != ( PhyData & 0x20 ));
+         if ( 0 == *pbComplete ) {
+              DEBUG (( EFI_D_INFO, "Autoneg is not yet Complete\n" ));
+        }
+        else {
+          Status = Ax88772PhyRead ( pNicDevice,
+                                PHY_ANLPAR,
+                                &PhyData );
+          if ( !EFI_ERROR ( Status )) {
+            //
+            //  Autonegotiation is complete
+            //  Determine the link speed.
+            //
+            *pbHiSpeed = (BOOLEAN)( 0 != ( PhyData & ( AN_TX_FDX | AN_TX_HDX )));
+
+            //
+            //  Determine the link duplex.
+            //
+            Mask = ( *pbHiSpeed ) ? AN_TX_FDX : AN_10_FDX;
+            *pbFullDuplex = (BOOLEAN)( 0 != ( PhyData & Mask ));
+          }
+        } 
+      }
+  } 
+  else {
+      DEBUG (( EFI_D_ERROR, "Failed to read BMCR\n" ));
+  }
+  return Status;
+}
+
+
+/**
+  Read a register from the PHY
+
+  This routine calls ::Ax88772UsbCommand to read a PHY register.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] RegisterAddress  Number of the register to read.
+  @param [in, out] pPhyData    Address of a buffer to receive the PHY register value
+
+  @retval EFI_SUCCESS          The PHY data is available.
+  @retval other                The PHY data is not valid.
+
+**/
+EFI_STATUS
+Ax88772PhyRead (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT8 RegisterAddress,
+  IN OUT UINT16 * pPhyData
+  )
+{
+  USB_DEVICE_REQUEST SetupMsg;
+  EFI_STATUS Status;
+
+  //
+  //  Request access to the PHY
+  //
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_PHY_ACCESS_SOFTWARE;   
+  SetupMsg.Value = 0;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand ( pNicDevice,
+                               &SetupMsg,
+                               NULL );
+  if ( !EFI_ERROR ( Status )) {
+    //
+    //  Read the PHY register address.
+    //
+    SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
+                         | USB_REQ_TYPE_VENDOR
+                         | USB_TARGET_DEVICE;
+    SetupMsg.Request = CMD_PHY_REG_READ;
+    SetupMsg.Value = pNicDevice->PhyId;
+    SetupMsg.Index = RegisterAddress;
+    SetupMsg.Length = sizeof ( *pPhyData );
+    Status = Ax88772UsbCommand ( pNicDevice,
+                                 &SetupMsg,
+                                 pPhyData );
+    if ( !EFI_ERROR ( Status )) {
+
+      //
+      //  Release the PHY to the hardware
+      //
+      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                           | USB_TARGET_DEVICE;
+      SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
+      SetupMsg.Value = 0;
+      SetupMsg.Index = 0;
+      SetupMsg.Length = 0;
+      Status = Ax88772UsbCommand ( pNicDevice,
+                                   &SetupMsg,
+                                   NULL );
+    }
+  }
+  return Status;
+}
+
+
+/**
+  Write to a PHY register
+
+  This routine calls ::Ax88772UsbCommand to write a PHY register.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] RegisterAddress  Number of the register to read.
+  @param [in] PhyData          Address of a buffer to receive the PHY register value
+
+  @retval EFI_SUCCESS          The PHY data was written.
+  @retval other                Failed to wwrite the PHY register.
+
+**/
+EFI_STATUS
+Ax88772PhyWrite (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT8 RegisterAddress,
+  IN UINT16 PhyData
+  )
+{
+  USB_DEVICE_REQUEST SetupMsg;
+  EFI_STATUS Status;
+
+  //
+  //  Request access to the PHY
+  //
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_PHY_ACCESS_SOFTWARE;
+  SetupMsg.Value = 0;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand ( pNicDevice,
+                               &SetupMsg,
+                               NULL );
+  if ( !EFI_ERROR ( Status )) {
+    //
+    //  Write the PHY register
+    //
+    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                         | USB_TARGET_DEVICE;
+    SetupMsg.Request = CMD_PHY_REG_WRITE;
+    SetupMsg.Value = pNicDevice->PhyId;
+    SetupMsg.Index = RegisterAddress;
+    SetupMsg.Length = sizeof ( PhyData );
+    Status = Ax88772UsbCommand ( pNicDevice,
+                                 &SetupMsg,
+                                 &PhyData );
+    if ( !EFI_ERROR ( Status )) {
+
+      //
+      //  Release the PHY to the hardware
+      //
+      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                           | USB_TARGET_DEVICE;
+      SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
+      SetupMsg.Value = 0;
+      SetupMsg.Index = 0;
+      SetupMsg.Length = 0;
+      Status = Ax88772UsbCommand ( pNicDevice,
+                                   &SetupMsg,
+                                   NULL );
+    }
+  }
+
+  return Status;
+}
+
+
+/**
+  Reset the AX88772
+
+  This routine uses ::Ax88772UsbCommand to reset the network
+  adapter.  This routine also uses ::Ax88772PhyWrite to reset
+  the PHY.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+
+  @retval EFI_SUCCESS          The MAC address is available.
+  @retval other                The MAC address is not valid.
+
+**/
+EFI_STATUS
+Ax88772Reset (
+  IN NIC_DEVICE * pNicDevice
+  )
+{
+  USB_DEVICE_REQUEST SetupMsg;
+  EFI_STATUS Status;
+  
+  EFI_USB_IO_PROTOCOL *pUsbIo;
+  EFI_USB_DEVICE_DESCRIPTOR Device;
+  
+  pUsbIo = pNicDevice->pUsbIo;
+  Status = pUsbIo->UsbGetDeviceDescriptor ( pUsbIo, &Device );
+
+	if (EFI_ERROR(Status)) goto err; 
+
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                           | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
+  SetupMsg.Value = 0;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand ( pNicDevice,
+                                &SetupMsg,
+                                NULL );
+                                   
+  if (EFI_ERROR(Status)) goto err;                                 
+                                   
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                          | USB_TARGET_DEVICE;
+      SetupMsg.Request = CMD_PHY_SELECT;
+      SetupMsg.Value = SPHY_PSEL;
+      SetupMsg.Index = 0;
+      SetupMsg.Length = 0;
+      Status = Ax88772UsbCommand ( pNicDevice,
+                                    &SetupMsg,
+                                    NULL );
+                                    
+  if (EFI_ERROR(Status)) goto err;  
+                                     
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                          | USB_TARGET_DEVICE;                                
+  SetupMsg.Request = CMD_RESET;
+      SetupMsg.Value = SRR_IPRL ;
+      SetupMsg.Index = 0;
+      SetupMsg.Length = 0;
+      Status = Ax88772UsbCommand ( pNicDevice,
+                                   &SetupMsg,
+                                   NULL );  
+                                   
+  if (EFI_ERROR(Status)) goto err;  
+                                   
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                          | USB_TARGET_DEVICE;                                
+  SetupMsg.Request = CMD_RESET;
+        SetupMsg.Value = SRR_IPPD | SRR_IPRL ;
+        SetupMsg.Index = 0;
+        SetupMsg.Length = 0;
+        Status = Ax88772UsbCommand ( pNicDevice,
+                                    &SetupMsg,
+                                    NULL );
+                                   
+  gBS->Stall ( 200000 );
+    
+  if (EFI_ERROR(Status)) goto err;  
+    
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                          | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_RESET;
+  SetupMsg.Value =  SRR_IPRL  ;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand ( pNicDevice,
+                                &SetupMsg,
+                                NULL );   
+                                    
+  gBS->Stall ( 200000 ); 
+     
+  if (EFI_ERROR(Status)) goto err;  
+     
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                          | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_RESET;
+  SetupMsg.Value = 0;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand ( pNicDevice,
+                                    &SetupMsg,
+                                    NULL );
+                                    
+  if (EFI_ERROR(Status)) goto err;                                
+                                    
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                          | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_PHY_SELECT;
+  SetupMsg.Value = SPHY_PSEL;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand ( pNicDevice,
+                                    &SetupMsg,
+                                    NULL ); 
+                                    
+  if (EFI_ERROR(Status)) goto err;                                
+                                    
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                          | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_RESET;
+  SetupMsg.Value =  SRR_IPRL | SRR_BZ | SRR_BZTYPE;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand ( pNicDevice,
+                                    &SetupMsg,
+                                    NULL );
+                                    
+  if (EFI_ERROR(Status)) goto err;                                
+                                    
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                        | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_RX_CONTROL_WRITE;
+  SetupMsg.Value = 0;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand ( pNicDevice,
+                                  &SetupMsg,
+                                  NULL );
+                                  
+  if (EFI_ERROR(Status)) goto err;  
+
+  if (pNicDevice->Flags != FLAG_TYPE_AX88772) {
+        SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                        | USB_TARGET_DEVICE;
+        SetupMsg.Request = CMD_RXQTC;
+        SetupMsg.Value = 0x8000;
+        SetupMsg.Index = 0x8001;
+        SetupMsg.Length = 0;
+        Status = Ax88772UsbCommand ( pNicDevice,
+                                  &SetupMsg,
+                                  NULL );
+  }
+
+err:
+  return Status;
+}
+
+/**
+  Enable or disable the receiver
+
+  This routine calls ::Ax88772UsbCommand to update the
+  receiver state.  This routine also calls ::Ax88772MacAddressSet
+  to establish the MAC address for the network adapter.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] RxFilter         Simple network RX filter mask value
+
+  @retval EFI_SUCCESS          The MAC address was set.
+  @retval other                The MAC address was not set.
+
+**/
+EFI_STATUS
+Ax88772RxControl (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT32 RxFilter
+  )
+{
+  UINT16 MediumStatus;
+  UINT16 RxControl;
+  USB_DEVICE_REQUEST SetupMsg;
+  EFI_STATUS Status;
+  EFI_USB_IO_PROTOCOL *pUsbIo;
+  EFI_USB_DEVICE_DESCRIPTOR Device;
+  
+  pUsbIo = pNicDevice->pUsbIo;
+  Status = pUsbIo->UsbGetDeviceDescriptor ( pUsbIo, &Device );
+  
+  if (EFI_ERROR(Status)) {
+    DEBUG (( EFI_D_ERROR, "Failed to get device descriptor\n" ));
+    return Status;
+  }
+
+  //
+  // Enable the receiver if something is to be received
+  //
+  
+  if ( 0 != RxFilter ) {
+    //
+    //  Enable the receiver
+    //
+    SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
+                         | USB_REQ_TYPE_VENDOR
+                         | USB_TARGET_DEVICE;
+    SetupMsg.Request = CMD_MEDIUM_STATUS_READ;    
+    SetupMsg.Value = 0;
+    SetupMsg.Index = 0;
+    SetupMsg.Length = sizeof ( MediumStatus );
+    Status = Ax88772UsbCommand ( pNicDevice,
+                                 &SetupMsg,
+                                 &MediumStatus );
+    if ( !EFI_ERROR ( Status )) {
+      if ( 0 == ( MediumStatus & MS_RE )) {
+        MediumStatus |= MS_RE | MS_ONE;
+        
+        if ( pNicDevice->bFullDuplex )
+          MediumStatus |= MS_TFC | MS_RFC | MS_FD;
+        else
+          MediumStatus &= ~(MS_TFC | MS_RFC | MS_FD);
+        
+        if ( pNicDevice->b100Mbps )
+          MediumStatus |= MS_PS;
+        else
+          MediumStatus &= ~MS_PS;
+        
+        SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                             | USB_TARGET_DEVICE;
+        SetupMsg.Request = CMD_MEDIUM_STATUS_WRITE;
+        SetupMsg.Value = MediumStatus;
+        SetupMsg.Index = 0;
+        SetupMsg.Length = 0;
+        Status = Ax88772UsbCommand ( pNicDevice,
+                                     &SetupMsg,
+                                     NULL );
+        if ( EFI_ERROR ( Status )) {
+            DEBUG (( EFI_D_ERROR, "Failed to enable receiver, Status: %r\r\n",
+              Status ));
+        }
+      }
+    }
+    else {
+        DEBUG (( EFI_D_ERROR, "Failed to read receiver status, Status: %r\r\n",
+              Status ));
+    }
+  }
+  
+  RxControl = RXC_SO | RXC_RH1M;  
+  //
+  //  Enable multicast if requested
+  //
+  if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST )) {
+      RxControl |= RXC_AM;
+      //
+      //  Update the multicast hash table
+      //
+      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                           | USB_TARGET_DEVICE;
+      SetupMsg.Request = CMD_MULTICAST_HASH_WRITE;
+      SetupMsg.Value = 0;
+      SetupMsg.Index = 0;
+      SetupMsg.Length = sizeof ( pNicDevice ->MulticastHash );
+      Status = Ax88772UsbCommand ( pNicDevice,
+                                   &SetupMsg,
+                                   &pNicDevice->MulticastHash );
+  }
+  //
+  //  Enable all multicast if requested
+  //
+  if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST )) {
+      RxControl |= RXC_AMALL;
+  }
+
+  //
+  //  Enable broadcast if requested
+  //
+  if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST )) {
+      RxControl |= RXC_AB;
+  }
+
+  //
+  //  Enable promiscuous mode if requested
+  //
+  if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS )) {
+      RxControl |= RXC_PRO;
+  }
+    
+  //
+  //  Update the receiver control
+  //
+  if (pNicDevice->CurRxControl != RxControl) {
+    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                         | USB_TARGET_DEVICE;
+    SetupMsg.Request = CMD_RX_CONTROL_WRITE;
+    SetupMsg.Value = RxControl;
+    SetupMsg.Index = 0;
+    SetupMsg.Length = 0;
+    Status = Ax88772UsbCommand ( pNicDevice,
+                                 &SetupMsg,
+                                 NULL );
+    if ( !EFI_ERROR ( Status )) {
+      pNicDevice->CurRxControl = RxControl;
+      
+    }
+    else {
+        DEBUG (( EFI_D_ERROR, "ERROR - Failed to set receiver control, Status: %r\r\n",
+            Status ));
+    }
+  }
+  return Status;
+}
+
+
+/**
+  Read an SROM location
+
+  This routine calls ::Ax88772UsbCommand to read data from the
+  SROM.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] Address          SROM address
+  @param [out] pData           Buffer to receive the data
+
+  @retval EFI_SUCCESS          The read was successful
+  @retval other                The read failed
+
+**/
+EFI_STATUS
+Ax88772SromRead (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT32 Address,
+  OUT UINT16 * pData
+  )
+{ 
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Send a command to the USB device.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] pRequest         Pointer to the request structure
+  @param [in, out] pBuffer     Data buffer address
+
+  @retval EFI_SUCCESS          The USB transfer was successful
+  @retval other                The USB transfer failed
+
+**/
+EFI_STATUS
+Ax88772UsbCommand (
+  IN NIC_DEVICE * pNicDevice,
+  IN USB_DEVICE_REQUEST * pRequest,
+  IN OUT VOID * pBuffer
+  )
+{
+  UINT32 CmdStatus;
+  EFI_USB_DATA_DIRECTION Direction;
+  EFI_USB_IO_PROTOCOL * pUsbIo;
+  EFI_STATUS Status;
+
+  //
+  // Determine the transfer direction
+  //
+  Direction = EfiUsbNoData;
+  if ( 0 != pRequest->Length ) {
+    Direction = ( 0 != ( pRequest->RequestType & USB_ENDPOINT_DIR_IN ))
+              ? EfiUsbDataIn : EfiUsbDataOut;
+  }
+
+  //
+  // Issue the command
+  //
+  pUsbIo = pNicDevice->pUsbIo;
+  Status = pUsbIo->UsbControlTransfer ( pUsbIo,
+                                        pRequest,
+                                        Direction,
+                                        USB_BUS_TIMEOUT,
+                                        pBuffer,
+                                        pRequest->Length,
+                                        &CmdStatus );
+  //
+  // Determine the operation status
+  //
+  if ( !EFI_ERROR ( Status )) {
+    Status = CmdStatus;
+  }
+  else {
+    //
+    // Only use status values associated with the Simple Network protocol
+    //
+    if ( EFI_TIMEOUT == Status ) {
+      Status = EFI_DEVICE_ERROR;
+    }
+  }
+  return Status;
+}
+
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h
new file mode 100644
index 0000000000..365929489b
--- /dev/null
+++ b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h
@@ -0,0 +1,1026 @@
+/** @file
+  Definitions for ASIX AX88772 Ethernet adapter.
+
+  Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _AX88772_H_
+#define _AX88772_H_
+
+#include <Uefi.h>
+
+#include <Guid/EventGroup.h>
+
+#include <IndustryStandard/Pci.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeLib.h>
+
+#include <Protocol/DevicePath.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/NetworkInterfaceIdentifier.h>
+#include <Protocol/SimpleNetwork.h>
+#include <Protocol/UsbIo.h>
+
+#define MAX_QUEUE_SIZE 50
+#define MAX_BULKIN_SIZE 16384
+#define HW_HDR_LENGTH 8
+
+
+#define MAX_LINKIDLE_THRESHOLD  20000
+
+
+
+//------------------------------------------------------------------------------
+//  Macros
+//------------------------------------------------------------------------------
+
+#if defined(_MSC_VER)           /* Handle Microsoft VC++ compiler specifics. */
+#define DBG_ENTER()             DEBUG (( 0xffffffff, "Entering " __FUNCTION__ "\n" )) ///<  Display routine entry
+#define DBG_EXIT()              DEBUG (( 0xffffffff, "Exiting " __FUNCTION__ "\n" ))  ///<  Display routine exit
+#define DBG_EXIT_DEC(Status)    DEBUG (( 0xffffffff, "Exiting " __FUNCTION__ ", Status: %d\n", Status ))      ///<  Display routine exit with decimal value
+#define DBG_EXIT_HEX(Status)    DEBUG (( 0xffffffff, "Exiting " __FUNCTION__ ", Status: 0x%08x\n", Status ))  ///<  Display routine exit with hex value
+#define DBG_EXIT_STATUS(Status) DEBUG (( 0xffffffff, "Exiting " __FUNCTION__ ", Status: %r\n", Status ))      ///<  Display routine exit with status value
+#define DBG_EXIT_TF(Status)     DEBUG (( 0xffffffff, "Exiting " __FUNCTION__ ", returning %s\n", (FALSE == Status) ? L"FALSE" : L"TRUE" ))  ///<  Display routine with TRUE/FALSE value
+#else   //  _MSC_VER
+#define DBG_ENTER()               ///<  Display routine entry
+#define DBG_EXIT()                ///<  Display routine exit
+#define DBG_EXIT_DEC(Status)      ///<  Display routine exit with decimal value
+#define DBG_EXIT_HEX(Status)      ///<  Display routine exit with hex value
+#define DBG_EXIT_STATUS(Status)   ///<  Display routine exit with status value
+#define DBG_EXIT_TF(Status)       ///<  Display routine with TRUE/FALSE value
+#endif  //  _MSC_VER
+
+#define USB_IS_IN_ENDPOINT(EndPointAddr)      (((EndPointAddr) & BIT7) != 0)  ///<  Return TRUE/FALSE for IN direction
+#define USB_IS_OUT_ENDPOINT(EndPointAddr)     (((EndPointAddr) & BIT7) == 0)  ///<  Return TRUE/FALSE for OUT direction
+#define USB_IS_BULK_ENDPOINT(Attribute)       (((Attribute) & (BIT0 | BIT1)) == USB_ENDPOINT_BULK)      ///<  Return TRUE/FALSE for BULK type
+#define USB_IS_INTERRUPT_ENDPOINT(Attribute)  (((Attribute) & (BIT0 | BIT1)) == USB_ENDPOINT_INTERRUPT) ///<  Return TRUE/FALSE for INTERRUPT type
+
+
+#define PRINT(_L_STR) (gST->ConOut->OutputString(gST->ConOut,(_L_STR)))
+//------------------------------------------------------------------------------
+//  Constants
+//------------------------------------------------------------------------------
+
+#define DEBUG_RX_BROADCAST  0x40000000  ///<  Display RX broadcast messages
+#define DEBUG_RX_MULTICAST  0x20000000  ///<  Display RX multicast messages
+#define DEBUG_RX_UNICAST    0x10000000  ///<  Display RX unicast messages
+#define DEBUG_MAC_ADDRESS   0x08000000  ///<  Display the MAC address
+#define DEBUG_LINK          0x04000000  ///<  Display the link status
+#define DEBUG_TX            0x02000000  ///<  Display the TX messages
+#define DEBUG_PHY           0x01000000  ///<  Display the PHY register values
+#define DEBUG_SROM          0x00800000  ///<  Display the SROM contents
+#define DEBUG_TIMER         0x00400000  ///<  Display the timer routine entry/exit
+#define DEBUG_TPL           0x00200000  ///<  Display the timer routine entry/exit
+
+#define AX88772_MAX_PKT_SIZE  2048  ///< Maximum packet size
+
+#define ETHERNET_HEADER_SIZE  sizeof ( ETHERNET_HEADER )  ///<  Size in bytes of the Ethernet header
+#define MIN_ETHERNET_PKT_SIZE 60    ///<  Minimum packet size including Ethernet header
+#define MAX_ETHERNET_PKT_SIZE 1500  ///<  Ethernet spec 3.1.1: Minimum packet size
+
+#define USB_NETWORK_CLASS   0x09    ///<  USB Network class code
+#define USB_BUS_TIMEOUT     1000    ///<  USB timeout in milliseconds
+
+#define TIMER_MSEC          20              ///<  Polling interval for the NIC
+//#define TPL_AX88772         TPL_CALLBACK    ///<  TPL for routine synchronization
+
+#define HC_DEBUG  0
+#define BULKIN_TIMEOUT  20
+#define AUTONEG_DELAY   500000
+#define AUTONEG_POLLCNT 20
+
+/**
+  Verify new TPL value
+
+  This macro which is enabled when debug is enabled verifies that
+  the new TPL value is >= the current TPL value.
+**/
+#ifdef VERIFY_TPL
+#undef VERIFY_TPL
+#endif  //  VERIFY_TPL
+
+#if !defined(MDEPKG_NDEBUG)
+
+#define VERIFY_TPL(tpl)                           \
+{                                                 \
+  EFI_TPL PreviousTpl;                            \
+                                                  \
+  PreviousTpl = gBS->RaiseTPL ( TPL_HIGH_LEVEL ); \
+  gBS->RestoreTPL ( PreviousTpl );                \
+  if ( PreviousTpl > tpl ) {                      \
+    DEBUG (( DEBUG_ERROR, "Current TPL: %d, New TPL: %d\r\n", PreviousTpl, tpl ));  \
+    ASSERT ( PreviousTpl <= tpl );                \
+  }                                               \
+}
+
+#else   //  MDEPKG_NDEBUG
+
+#define VERIFY_TPL(tpl)
+
+#endif  //  MDEPKG_NDEBUG
+
+//------------------------------------------------------------------------------
+//  Hardware Definition
+//------------------------------------------------------------------------------
+
+#define FreeQueueSize     10
+
+#define DEV_SIGNATURE     SIGNATURE_32 ('A','X','8','8')  ///<  Signature of data structures in memory
+
+#define RESET_MSEC        1000    ///<  Reset duration
+#define PHY_RESET_MSEC     500    ///<  PHY reset duration
+
+//
+//  RX Control register
+//
+
+#define RXC_PRO           0x0001  ///<  Receive all packets
+#define RXC_AMALL         0x0002  ///<  Receive all multicast packets
+#define RXC_SEP           0x0004  ///<  Save error packets
+#define RXC_AB            0x0008  ///<  Receive broadcast packets
+#define RXC_AM            0x0010  ///<  Use multicast destination address hash table
+#define RXC_AP            0x0020  ///<  Accept physical address from Multicast Filter
+#define RXC_SO            0x0080  ///<  Start operation
+#define RXC_MFB           0x0300  ///<  Maximum frame burst
+#define RXC_MFB_2048      0       ///<  Maximum frame size:  2048 bytes
+#define RXC_MFB_4096      0x0100  ///<  Maximum frame size:  4096 bytes
+#define RXC_MFB_8192      0x0200  ///<  Maximum frame size:  8192 bytes
+#define RXC_MFB_16384     0x0300  ///<  Maximum frame size: 16384 bytes
+
+/*Freddy*/
+#define RXC_RH1M          0x0100  ///<  Rx header 1
+#define RXC_RH2M          0x0200  ///<  Rx header 2
+#define RXC_RH3M          0x0400  ///<  Rx header 3
+/*Freddy*/
+
+//
+//  Medium Status register
+//
+
+#define MS_FD             0x0002  ///<  Full duplex
+#define MS_ONE            0x0004  ///<  Must be one
+#define MS_RFC            0x0010  ///<  RX flow control enable
+#define MS_TFC            0x0020  ///<  TX flow control enable
+#define MS_PF             0x0080  ///<  Pause frame enable
+#define MS_RE             0x0100  ///<  Receive enable
+#define MS_PS             0x0200  ///<  Port speed 1=100, 0=10 Mbps
+#define MS_SBP            0x0800  ///<  Stop back pressure
+#define MS_SM             0x1000  ///<  Super MAC support
+
+//
+//  Software PHY Select register
+//
+
+#define SPHY_PSEL         (1 << 0)    ///<  Select internal PHY
+#define SPHY_SSMII        (1 << 2)
+#define SPHY_SSEN         (1 << 4)
+#define SPHY_ASEL         0x02    ///<  1=Auto select, 0=Manual select
+
+//
+//  Software Reset register
+//
+
+#define SRR_RR            0x01    ///<  Clear receive frame length error
+#define SRR_RT            0x02    ///<  Clear transmit frame length error
+#define SRR_BZTYPE        0x04    ///<  External PHY reset pin tri-state enable
+#define SRR_PRL           0x08    ///<  External PHY reset pin level
+#define SRR_BZ            0x10    ///<  Force Bulk to return zero length packet
+#define SRR_IPRL          0x20    ///<  Internal PHY reset control
+#define SRR_IPPD          0x40    ///<  Internal PHY power down
+
+//
+//  PHY ID values
+//
+
+#define PHY_ID_INTERNAL   0x0010  ///<  Internal PHY
+
+//
+//  USB Commands
+//
+
+#define CMD_PHY_ACCESS_SOFTWARE   0x06  ///<  Software in control of PHY
+#define CMD_PHY_REG_READ          0x07  ///<  Read PHY register, Value: PHY, Index: Register, Data: Register value
+#define CMD_PHY_REG_WRITE         0x08  ///<  Write PHY register, Value: PHY, Index: Register, Data: New 16-bit value
+#define CMD_PHY_ACCESS_HARDWARE   0x0a  ///<  Hardware in control of PHY
+#define CMD_SROM_READ             0x0b  ///<  Read SROM register: Value: Address, Data: Value
+#define CMD_RX_CONTROL_WRITE      0x10  ///<  Set the RX control register, Value: New value
+#define CMD_GAPS_WRITE            0x12  ///<  Write the gaps register, Value: New value
+#define CMD_MAC_ADDRESS_READ      0x13  ///<  Read the MAC address, Data: 6 byte MAC address
+#define CMD_MAC_ADDRESS_WRITE     0x14  ///<  Set the MAC address, Data: New 6 byte MAC address
+#define CMD_MULTICAST_HASH_WRITE  0x16  ///<  Write the multicast hash table, Data: New 8 byte value
+#define CMD_MULTICAST_HASH_READ  0x16  ///<  Read the multicast hash table
+#define CMD_MEDIUM_STATUS_READ    0x1a  ///<  Read medium status register, Data: Register value
+#define CMD_MEDIUM_STATUS_WRITE   0x1b  ///<  Write medium status register, Value: New value
+#define CMD_WRITE_GPIOS           0x1f
+#define CMD_RESET                 0x20  ///<  Reset register, Value: New value
+#define CMD_PHY_SELECT            0x22  ///<  PHY select register, Value: New value
+
+/*Freddy*/
+#define CMD_RXQTC                 0x2a  ///<  RX Queue Cascade Threshold Control Register
+/*Freddy*/
+
+//------------------------------
+//  USB Endpoints
+//------------------------------
+
+#define CONTROL_ENDPOINT                0       ///<  Control endpoint
+#define INTERRUPT_ENDPOINT              1       ///<  Interrupt endpoint
+#define BULK_IN_ENDPOINT                2       ///<  Receive endpoint
+#define BULK_OUT_ENDPOINT               3       ///<  Transmit endpoint
+
+//------------------------------
+//  PHY Registers
+//------------------------------
+
+#define PHY_BMCR                        0       ///<  Control register
+#define PHY_BMSR                        1       ///<  Status register
+#define PHY_ANAR                        4       ///<  Autonegotiation advertisement register
+#define PHY_ANLPAR                      5       ///<  Autonegotiation link parter ability register
+#define PHY_ANER                        6       ///<  Autonegotiation expansion register
+
+//  BMCR - Register 0
+
+#define BMCR_RESET                      0x8000  ///<  1 = Reset the PHY, bit clears after reset
+#define BMCR_LOOPBACK                   0x4000  ///<  1 = Loopback enabled
+#define BMCR_100MBPS                    0x2000  ///<  100 Mbits/Sec
+#define BMCR_10MBPS                     0       ///<  10 Mbits/Sec
+#define BMCR_AUTONEGOTIATION_ENABLE     0x1000  ///<  1 = Enable autonegotiation
+#define BMCR_POWER_DOWN                 0x0800  ///<  1 = Power down
+#define BMCR_ISOLATE                    0x0400  ///<  0 = Isolate PHY
+#define BMCR_RESTART_AUTONEGOTIATION    0x0200  ///<  1 = Restart autonegotiation
+#define BMCR_FULL_DUPLEX                0x0100  ///<  Full duplex operation
+#define BMCR_HALF_DUPLEX                0       ///<  Half duplex operation
+#define BMCR_COLLISION_TEST             0x0080  ///<  1 = Collision test enabled
+
+//  BSMR - Register 1
+
+#define BMSR_100BASET4                  0x8000  ///<  1 = 100BASE-T4 mode
+#define BMSR_100BASETX_FDX              0x4000  ///<  1 = 100BASE-TX full duplex
+#define BMSR_100BASETX_HDX              0x2000  ///<  1 = 100BASE-TX half duplex
+#define BMSR_10BASET_FDX                0x1000  ///<  1 = 10BASE-T full duplex
+#define BMSR_10BASET_HDX                0x0800  ///<  1 = 10BASE-T half duplex
+#define BMSR_MF                         0x0040  ///<  1 = PHY accepts frames with preamble suppressed
+#define BMSR_AUTONEG_CMPLT              0x0020  ///<  1 = Autonegotiation complete
+#define BMSR_RF                         0x0010  ///<  1 = Remote fault
+#define BMSR_AUTONEG                    0x0008  ///<  1 = Able to perform autonegotiation
+#define BMSR_LINKST                     0x0004  ///<  1 = Link up
+#define BMSR_JABBER_DETECT              0x0002  ///<  1 = jabber condition detected
+#define BMSR_EXTENDED_CAPABILITY        0x0001  ///<  1 = Extended register capable
+
+//  ANAR and ANLPAR Registers 4, 5
+
+#define AN_NP                           0x8000  ///<  1 = Next page available
+#define AN_ACK                          0x4000  ///<  1 = Link partner acknowledged
+#define AN_RF                           0x2000  ///<  1 = Remote fault indicated by link partner
+#define AN_FCS                          0x0400  ///<  1 = Flow control ability
+#define AN_T4                           0x0200  ///<  1 = 100BASE-T4 support
+#define AN_TX_FDX                       0x0100  ///<  1 = 100BASE-TX Full duplex
+#define AN_TX_HDX                       0x0080  ///<  1 = 100BASE-TX support
+#define AN_10_FDX                       0x0040  ///<  1 = 10BASE-T Full duplex
+#define AN_10_HDX                       0x0020  ///<  1 = 10BASE-T support
+#define AN_CSMA_CD                      0x0001  ///<  1 = IEEE 802.3 CSMA/CD support
+
+// asix_flags defines
+#define FLAG_NONE               0
+#define FLAG_TYPE_AX88172       BIT0
+#define FLAG_TYPE_AX88772       BIT1
+#define FLAG_TYPE_AX88772B      BIT2
+#define FLAG_EEPROM_MAC         BIT3  // initial mac address in eeprom
+
+//------------------------------------------------------------------------------
+//  Data Types
+//------------------------------------------------------------------------------
+
+typedef struct {
+   UINT16  VendorId;
+   UINT16  ProductId;
+   INT32   Flags;
+}ASIX_DONGLE;
+
+/**
+  Ethernet header layout
+
+  IEEE 802.3-2002 Part 3 specification, section 3.1.1.
+**/
+#pragma pack(1)
+typedef struct {
+  UINT8 dest_addr[PXE_HWADDR_LEN_ETHER];  ///<  Destination LAN address
+  UINT8 src_addr[PXE_HWADDR_LEN_ETHER];   ///<  Source LAN address
+  UINT16 type;                            ///<  Protocol or length
+} ETHERNET_HEADER;
+#pragma pack()
+
+/**
+  Receive and Transmit packet structure
+**/
+#pragma pack(1)
+typedef struct _RX_TX_PACKET {
+  struct _RX_TX_PACKET * pNext;       ///<  Next receive packet
+  UINT16 Length;                      ///<  Packet length
+  UINT16 LengthBar;                   ///<  Complement of the length
+  UINT8 Data[ AX88772_MAX_PKT_SIZE ]; ///<  Received packet data
+} RX_TX_PACKET;
+#pragma pack()
+
+
+#pragma pack(1)
+typedef struct _RX_PKT {
+  struct _RX_PKT *pNext;
+  BOOLEAN f_Used;
+  UINT16 Length;
+  UINT8 Data [AX88772_MAX_PKT_SIZE] ;
+} RX_PKT;
+#pragma pack()
+
+/**
+  AX88772 control structure
+
+  The driver uses this structure to manage the Asix AX88772 10/100
+  Ethernet controller.
+**/
+typedef struct {
+  UINTN Signature;          ///<  Structure identification
+
+  //
+  //  USB data
+  //
+  EFI_HANDLE Controller;        ///<  Controller handle
+  EFI_USB_IO_PROTOCOL * pUsbIo;  ///<  USB driver interface
+
+  //
+  //  Simple network protocol data
+  //
+  EFI_SIMPLE_NETWORK_PROTOCOL SimpleNetwork;  ///<  Driver's network stack interface
+  EFI_SIMPLE_NETWORK_PROTOCOL SimpleNetwork_Backup;
+  EFI_SIMPLE_NETWORK_MODE SimpleNetworkData;  ///<  Data for simple network
+
+  //
+  // Ethernet controller data
+  //
+  BOOLEAN bInitialized;     ///<  Controller initialized
+  VOID * pTxBuffer;         ///<  Last transmit buffer
+  UINT16 PhyId;             ///<  PHY ID
+
+  //
+  //  Link state
+  //
+  BOOLEAN b100Mbps;         ///<  Current link speed, FALSE = 10 Mbps
+  BOOLEAN bComplete;        ///<  Current state of auto-negotiation
+  BOOLEAN bFullDuplex;      ///<  Current duplex
+  BOOLEAN bLinkUp;          ///<  Current link state
+  UINTN  LinkIdleCnt;
+  UINTN PollCount;          ///<  Number of times the autonegotiation status was polled
+  UINT16 CurRxControl;
+  //
+  //  Receive buffer list
+  //
+  RX_TX_PACKET * pRxTest;
+  RX_TX_PACKET * pTxTest;
+
+  INT8 MulticastHash[8];
+  EFI_MAC_ADDRESS MAC;
+  BOOLEAN bHavePkt;
+ 
+  EFI_DEVICE_PATH_PROTOCOL                  *MyDevPath;
+  
+  EFI_DRIVER_BINDING_PROTOCOL * DrvBind;
+  
+  RX_PKT * QueueHead;
+  RX_PKT * pNextFill;
+  RX_PKT * pFirstFill;
+  UINTN   PktCntInQueue;
+  UINT8 * pBulkInBuff;
+
+  INT32 Flags;
+
+} NIC_DEVICE;
+
+#define DEV_FROM_SIMPLE_NETWORK(a)  CR (a, NIC_DEVICE, SimpleNetwork, DEV_SIGNATURE)  ///< Locate NIC_DEVICE from Simple Network Protocol
+
+//------------------------------------------------------------------------------
+// Simple Network Protocol
+//------------------------------------------------------------------------------
+
+/**
+  Reset the network adapter.
+
+  Resets a network adapter and reinitializes it with the parameters that
+  were provided in the previous call to Initialize ().  The transmit and
+  receive queues are cleared.  Receive filters, the station address, the
+  statistics, and the multicast-IP-to-HW MAC addresses are not reset by
+  this call.
+
+  This routine calls ::Ax88772Reset to perform the adapter specific
+  reset operation.  This routine also starts the link negotiation
+  by calling ::Ax88772NegotiateLinkStart.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] bExtendedVerification  Indicates that the driver may perform a more
+                                exhaustive verification operation of the device
+                                during reset.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Reset (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN BOOLEAN bExtendedVerification
+  );
+
+/**
+  Initialize the simple network protocol.
+
+  This routine calls ::Ax88772MacAddressGet to obtain the
+  MAC address.
+
+  @param [in] pNicDevice       NIC_DEVICE_INSTANCE pointer
+
+  @retval EFI_SUCCESS     Setup was successful
+
+**/
+EFI_STATUS
+SN_Setup (
+  IN NIC_DEVICE * pNicDevice
+  );
+
+/**
+  This routine starts the network interface.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_ALREADY_STARTED   The network interface was already started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Start (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
+  );
+
+/**
+  Set the MAC address.
+  
+  This function modifies or resets the current station address of a
+  network interface.  If Reset is TRUE, then the current station address
+  is set ot the network interface's permanent address.  If Reset if FALSE
+  then the current station address is changed to the address specified by
+  pNew.
+
+  This routine calls ::Ax88772MacAddressSet to update the MAC address
+  in the network adapter.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] bReset            Flag used to reset the station address to the
+                                network interface's permanent address.
+  @param [in] pNew              New station address to be used for the network
+                                interface.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_StationAddress (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN BOOLEAN bReset,
+  IN EFI_MAC_ADDRESS * pNew
+  );
+
+/**
+  This function resets or collects the statistics on a network interface.
+  If the size of the statistics table specified by StatisticsSize is not
+  big enough for all of the statistics that are collected by the network
+  interface, then a partial buffer of statistics is returned in
+  StatisticsTable.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] bReset            Set to TRUE to reset the statistics for the network interface.
+  @param [in, out] pStatisticsSize  On input the size, in bytes, of StatisticsTable.  On output
+                                the size, in bytes, of the resulting table of statistics.
+  @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
+                                conains the statistics.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_BUFFER_TOO_SMALL  The pStatisticsTable is NULL or the buffer is too small.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Statistics (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN BOOLEAN bReset,
+  IN OUT UINTN * pStatisticsSize,
+  OUT EFI_NETWORK_STATISTICS * pStatisticsTable
+  );
+
+/**
+  This function stops a network interface.  This call is only valid
+  if the network interface is in the started state.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Stop (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
+  );
+
+/**
+  This function releases the memory buffers assigned in the Initialize() call.
+  Pending transmits and receives are lost, and interrupts are cleared and disabled.
+  After this call, only Initialize() and Stop() calls may be used.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Shutdown (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
+  );
+
+/**
+  Send a packet over the network.
+
+  This function places the packet specified by Header and Buffer on
+  the transmit queue.  This function performs a non-blocking transmit
+  operation.  When the transmit is complete, the buffer is returned
+  via the GetStatus() call.
+
+  This routine calls ::Ax88772Rx to empty the network adapter of
+  receive packets.  The routine then passes the transmit packet
+  to the network adapter.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] HeaderSize        The size, in bytes, of the media header to be filled in by
+                                the Transmit() function.  If HeaderSize is non-zero, then
+                                it must be equal to SimpleNetwork->Mode->MediaHeaderSize
+                                and DestAddr and Protocol parameters must not be NULL.
+  @param [in] BufferSize        The size, in bytes, of the entire packet (media header and
+                                data) to be transmitted through the network interface.
+  @param [in] pBuffer           A pointer to the packet (media header followed by data) to
+                                to be transmitted.  This parameter can not be NULL.  If
+                                HeaderSize is zero, then the media header is Buffer must
+                                already be filled in by the caller.  If HeaderSize is nonzero,
+                                then the media header will be filled in by the Transmit()
+                                function.
+  @param [in] pSrcAddr          The source HW MAC address.  If HeaderSize is zero, then
+                                this parameter is ignored.  If HeaderSize is nonzero and
+                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
+                                is used for the source HW MAC address.
+  @param [in] pDestAddr         The destination HW MAC address.  If HeaderSize is zero, then
+                                this parameter is ignored.
+  @param [in] pProtocol         The type of header to build.  If HeaderSize is zero, then
+                                this parameter is ignored.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_NOT_READY         The network interface is too busy to accept this transmit request.
+  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Transmit (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN UINTN HeaderSize,
+  IN UINTN BufferSize,
+  IN VOID * pBuffer,
+  IN EFI_MAC_ADDRESS * pSrcAddr,
+  IN EFI_MAC_ADDRESS * pDestAddr,
+  IN UINT16 * pProtocol
+  );
+
+//------------------------------------------------------------------------------
+// Support Routines
+//------------------------------------------------------------------------------
+
+/**
+  Get the MAC address
+
+  This routine calls ::Ax88772UsbCommand to request the MAC
+  address from the network adapter.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [out] pMacAddress      Address of a six byte buffer to receive the MAC address.
+
+  @retval EFI_SUCCESS          The MAC address is available.
+  @retval other                The MAC address is not valid.
+
+**/
+EFI_STATUS
+Ax88772MacAddressGet (
+  IN NIC_DEVICE * pNicDevice,
+  OUT UINT8 * pMacAddress
+  );
+
+/**
+  Set the MAC address
+
+  This routine calls ::Ax88772UsbCommand to set the MAC address
+  in the network adapter.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] pMacAddress      Address of a six byte buffer to containing the new MAC address.
+
+  @retval EFI_SUCCESS          The MAC address was set.
+  @retval other                The MAC address was not set.
+
+**/
+EFI_STATUS
+Ax88772MacAddressSet (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT8 * pMacAddress
+  );
+
+/**
+  Clear the multicast hash table
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+
+**/
+VOID
+Ax88772MulticastClear (
+  IN NIC_DEVICE * pNicDevice
+  );
+
+/**
+  Enable a multicast address in the multicast hash table
+
+  This routine calls ::Ax88772Crc to compute the hash bit for
+  this MAC address.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] pMacAddress      Address of a six byte buffer to containing the MAC address.
+
+**/
+VOID
+Ax88772MulticastSet (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT8 * pMacAddress
+  );
+
+/**
+  Start the link negotiation
+
+  This routine calls ::Ax88772PhyWrite to start the PHY's link
+  negotiation.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+
+  @retval EFI_SUCCESS          The link negotiation was started.
+  @retval other                Failed to start the link negotiation.
+
+**/
+EFI_STATUS
+Ax88772NegotiateLinkStart (
+  IN NIC_DEVICE * pNicDevice
+  );
+
+/**
+  Complete the negotiation of the PHY link
+
+  This routine calls ::Ax88772PhyRead to determine if the
+  link negotiation is complete.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in, out] pPollCount  Address of number of times this routine was polled
+  @param [out] pbComplete      Address of boolean to receive complate status.
+  @param [out] pbLinkUp        Address of boolean to receive link status, TRUE=up.
+  @param [out] pbHiSpeed       Address of boolean to receive link speed, TRUE=100Mbps.
+  @param [out] pbFullDuplex    Address of boolean to receive link duplex, TRUE=full.
+
+  @retval EFI_SUCCESS          The MAC address is available.
+  @retval other                The MAC address is not valid.
+
+**/
+EFI_STATUS
+Ax88772NegotiateLinkComplete (
+  IN NIC_DEVICE * pNicDevice,
+  IN OUT UINTN * pPollCount,
+  OUT BOOLEAN * pbComplete,
+  OUT BOOLEAN * pbLinkUp,
+  OUT BOOLEAN * pbHiSpeed,
+  OUT BOOLEAN * pbFullDuplex
+  );
+
+/**
+  Read a register from the PHY
+
+  This routine calls ::Ax88772UsbCommand to read a PHY register.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] RegisterAddress  Number of the register to read.
+  @param [in, out] pPhyData    Address of a buffer to receive the PHY register value
+
+  @retval EFI_SUCCESS          The PHY data is available.
+  @retval other                The PHY data is not valid.
+
+**/
+EFI_STATUS
+Ax88772PhyRead (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT8 RegisterAddress,
+  IN OUT UINT16 * pPhyData
+  );
+
+/**
+  Write to a PHY register
+
+  This routine calls ::Ax88772UsbCommand to write a PHY register.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] RegisterAddress  Number of the register to read.
+  @param [in] PhyData          Address of a buffer to receive the PHY register value
+
+  @retval EFI_SUCCESS          The PHY data was written.
+  @retval other                Failed to wwrite the PHY register.
+
+**/
+EFI_STATUS
+Ax88772PhyWrite (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT8 RegisterAddress,
+  IN UINT16 PhyData
+  );
+
+/**
+  Reset the AX88772
+
+  This routine uses ::Ax88772UsbCommand to reset the network
+  adapter.  This routine also uses ::Ax88772PhyWrite to reset
+  the PHY.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+
+  @retval EFI_SUCCESS          The MAC address is available.
+  @retval other                The MAC address is not valid.
+
+**/
+EFI_STATUS
+Ax88772Reset (
+  IN NIC_DEVICE * pNicDevice
+  );
+
+VOID
+Ax88772ChkLink (
+  IN NIC_DEVICE * pNicDevice,
+  IN BOOLEAN bUpdateLink
+  );
+
+/**
+  Receive a frame from the network.
+
+  This routine polls the USB receive interface for a packet.  If a packet
+  is available, this routine adds the receive packet to the list of
+  pending receive packets.
+
+  This routine calls ::Ax88772NegotiateLinkComplete to verify
+  that the link is up.  This routine also calls ::SN_Reset to
+  reset the network adapter when necessary.  Finally this
+  routine attempts to receive one or more packets from the
+  network adapter.
+
+  @param [in] pNicDevice  Pointer to the NIC_DEVICE structure
+  @param [in] bUpdateLink TRUE = Update link status
+
+**/
+VOID
+Ax88772Rx (
+  IN NIC_DEVICE * pNicDevice,
+  IN BOOLEAN bUpdateLink
+  );
+
+/**
+  Enable or disable the receiver
+
+  This routine calls ::Ax88772UsbCommand to update the
+  receiver state.  This routine also calls ::Ax88772MacAddressSet
+  to establish the MAC address for the network adapter.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] RxFilter         Simple network RX filter mask value
+
+  @retval EFI_SUCCESS          The MAC address was set.
+  @retval other                The MAC address was not set.
+
+**/
+EFI_STATUS
+Ax88772RxControl (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT32 RxFilter
+  );
+
+/**
+  Read an SROM location
+
+  This routine calls ::Ax88772UsbCommand to read data from the
+  SROM.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] Address          SROM address
+  @param [out] pData           Buffer to receive the data
+
+  @retval EFI_SUCCESS          The read was successful
+  @retval other                The read failed
+
+**/
+EFI_STATUS
+Ax88772SromRead (
+  IN NIC_DEVICE * pNicDevice,
+  IN UINT32 Address,
+  OUT UINT16 * pData
+  );
+
+/**
+  Send a command to the USB device.
+
+  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
+  @param [in] pRequest         Pointer to the request structure
+  @param [in, out] pBuffer     Data buffer address
+
+  @retval EFI_SUCCESS          The USB transfer was successful
+  @retval other                The USB transfer failed
+
+**/
+EFI_STATUS
+Ax88772UsbCommand (
+  IN NIC_DEVICE * pNicDevice,
+  IN USB_DEVICE_REQUEST * pRequest,
+  IN OUT VOID * pBuffer
+  );
+
+//------------------------------------------------------------------------------
+// EFI Component Name Protocol Support
+//------------------------------------------------------------------------------
+
+extern EFI_COMPONENT_NAME_PROTOCOL   gComponentName;  ///<  Component name protocol declaration
+extern EFI_COMPONENT_NAME2_PROTOCOL  gComponentName2; ///<  Component name 2 protocol declaration
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 3066 or ISO 639-2 language code format.
+  @param [out] ppDriverName     A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+GetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
+  IN  CHAR8 * pLanguage,
+  OUT CHAR16 ** ppDriverName
+  );
+
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+  @param [in] ControllerHandle  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+  @param [in] ChildHandle       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 3066 or ISO 639-2 language code format.
+  @param [out] ppControllerName A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                controller specified by ControllerHandle and
+                                ChildHandle in the language specified by
+                                Language from the point of view of the driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+GetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
+  IN  EFI_HANDLE ControllerHandle,
+  IN OPTIONAL EFI_HANDLE ChildHandle,
+  IN  CHAR8 * pLanguage,
+  OUT CHAR16 ** ppControllerName
+  );
+  
+VOID 
+FillPkt2Queue (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN UINTN BufLength);
+
+//------------------------------------------------------------------------------
+
+#endif  //  _AX88772_H_
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
new file mode 100644
index 0000000000..60e43fd275
--- /dev/null
+++ b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
@@ -0,0 +1,61 @@
+## @file
+# Component description file for ASIX AX88772 USB/Ethernet driver.
+#
+# This module provides support for the ASIX AX88772 USB/Ethernet adapter.
+# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010018
+  BASE_NAME                      = Ax88772b
+  FILE_GUID                      = 95C8D770-E1A4-4422-B263-E32F14FD8186
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = EntryPoint
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources.common]
+  Ax88772.h
+  Ax88772.c
+  ComponentName.c
+  DriverBinding.c
+  SimpleNetwork.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+  UefiLib
+  UefiBootServicesTableLib
+  BaseMemoryLib
+  DebugLib
+  UefiRuntimeLib
+  UefiDriverEntryPoint
+
+[Protocols]  
+  gEfiDevicePathProtocolGuid           ## BY_START
+  gEfiSimpleNetworkProtocolGuid        ## BY_START
+  gEfiUsbIoProtocolGuid                ## TO_START
+
+[Depex]
+  gEfiBdsArchProtocolGuid AND
+  gEfiCpuArchProtocolGuid AND
+  gEfiMetronomeArchProtocolGuid AND
+  gEfiMonotonicCounterArchProtocolGuid AND
+  gEfiRealTimeClockArchProtocolGuid AND
+  gEfiResetArchProtocolGuid AND
+  gEfiRuntimeArchProtocolGuid AND
+  gEfiSecurityArchProtocolGuid AND
+  gEfiTimerArchProtocolGuid AND
+  gEfiVariableWriteArchProtocolGuid AND
+  gEfiVariableArchProtocolGuid AND
+  gEfiWatchdogTimerArchProtocolGuid
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/ComponentName.c b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/ComponentName.c
new file mode 100644
index 0000000000..76a732a7b0
--- /dev/null
+++ b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/ComponentName.c
@@ -0,0 +1,175 @@
+/** @file
+  UEFI Component Name(2) protocol implementation.
+
+  Copyright (c) 2011, Intel Corporation. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Ax88772.h"
+
+/**
+  EFI Component Name Protocol declaration
+**/
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gComponentName = {
+  GetDriverName,
+  GetControllerName,
+  "eng"
+};
+
+/**
+  EFI Component Name 2 Protocol declaration
+**/
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) GetDriverName,
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) GetControllerName,
+  "en"
+};
+
+
+/**
+  Driver name table declaration
+**/
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
+mDriverNameTable[] = {
+  {"eng;en", L"ASIX AX88772B Ethernet Driver 1.0"},
+  {NULL,  NULL}
+};
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 3066 or ISO 639-2 language code format.
+  @param [out] ppDriverName     A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+GetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
+  IN  CHAR8 * pLanguage,
+  OUT CHAR16 ** ppDriverName
+  )
+{
+  EFI_STATUS Status;
+
+  Status = LookupUnicodeString2 (
+             pLanguage,
+             pThis->SupportedLanguages,
+             mDriverNameTable,
+             ppDriverName,
+             (BOOLEAN)(pThis == &gComponentName)
+             );
+
+  return Status;
+}
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+  @param [in] ControllerHandle  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+  @param [in] ChildHandle       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 3066 or ISO 639-2 language code format.
+  @param [out] ppControllerName A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                controller specified by ControllerHandle and
+                                ChildHandle in the language specified by
+                                Language from the point of view of the driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+GetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
+  IN  EFI_HANDLE ControllerHandle,
+  IN OPTIONAL EFI_HANDLE ChildHandle,
+  IN  CHAR8 * pLanguage,
+  OUT CHAR16 ** ppControllerName
+  )
+{
+  EFI_STATUS Status;
+
+  //
+  // Set the controller name
+  //
+  *ppControllerName = L"ASIX AX88772B USB Fast Ethernet Controller";
+  Status = EFI_SUCCESS;
+
+  //
+  // Return the operation status
+  //
+
+  return Status;
+}
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/DriverBinding.c b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/DriverBinding.c
new file mode 100644
index 0000000000..2bec944140
--- /dev/null
+++ b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/DriverBinding.c
@@ -0,0 +1,696 @@
+/** @file
+  Implement the driver binding protocol for Asix AX88772 Ethernet driver.
+                     
+  Copyright (c) 2011-2013, Intel Corporation. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Ax88772.h"
+
+ASIX_DONGLE ASIX_DONGLES[] = {
+  { 0x05AC, 0x1402, FLAG_TYPE_AX88772 }, // Apple USB Ethernet Adapter
+  // ASIX 88772B
+  { 0x0B95, 0x772B, FLAG_TYPE_AX88772B | FLAG_EEPROM_MAC },
+  { 0x0000, 0x0000, FLAG_NONE }   // END - Do not remove
+};
+
+/**
+  Verify the controller type
+
+  @param [in] pThis                Protocol instance pointer.
+  @param [in] Controller           Handle of device to test.
+  @param [in] pRemainingDevicePath Not used.
+
+  @retval EFI_SUCCESS          This driver supports this device.
+  @retval other                This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+DriverSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
+  IN EFI_HANDLE Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
+  )
+{
+  EFI_USB_DEVICE_DESCRIPTOR Device;
+  EFI_USB_IO_PROTOCOL * pUsbIo;
+  EFI_STATUS Status;
+  UINT32 Index;
+
+  //
+  //  Connect to the USB stack
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiUsbIoProtocolGuid,
+                  (VOID **) &pUsbIo,
+                  pThis->DriverBindingHandle,         
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (!EFI_ERROR ( Status )) {
+
+    //
+    //  Get the interface descriptor to check the USB class and find a transport
+    //  protocol handler.
+    //
+    Status = pUsbIo->UsbGetDeviceDescriptor ( pUsbIo, &Device );
+    if (EFI_ERROR ( Status )) {
+    	Status = EFI_UNSUPPORTED;
+    }
+    else {
+      //
+      //  Validate the adapter
+      //
+      for (Index = 0; ASIX_DONGLES[Index].VendorId != 0; Index++) {
+        if (ASIX_DONGLES[Index].VendorId == Device.IdVendor &&
+            ASIX_DONGLES[Index].ProductId == Device.IdProduct) {
+              DEBUG ((EFI_D_INFO, "Found the AX88772B\r\n"));
+              break;
+        }
+      }
+
+      if (ASIX_DONGLES[Index].VendorId == 0)
+         Status = EFI_UNSUPPORTED;
+    }
+   
+    //
+    //  Done with the USB stack
+    //
+    gBS->CloseProtocol (
+           Controller,
+           &gEfiUsbIoProtocolGuid,
+           pThis->DriverBindingHandle,
+           Controller
+           );
+  }
+  return Status;
+}
+
+
+/**
+  Start this driver on Controller by opening UsbIo and DevicePath protocols.
+  Initialize PXE structures, create a copy of the Controller Device Path with the
+  NIC's MAC address appended to it, install the NetworkInterfaceIdentifier protocol
+  on the newly created Device Path.
+
+  @param [in] pThis                Protocol instance pointer.
+  @param [in] Controller           Handle of device to work with.
+  @param [in] pRemainingDevicePath Not used, always produce all possible children.
+
+  @retval EFI_SUCCESS          This driver is added to Controller.
+  @retval other                This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+DriverStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
+  IN EFI_HANDLE Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
+  )
+{
+
+	EFI_STATUS						Status;
+	NIC_DEVICE						*pNicDevice;
+	UINTN							LengthInBytes;
+	EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath = NULL;
+	MAC_ADDR_DEVICE_PATH            MacDeviceNode;
+        EFI_USB_DEVICE_DESCRIPTOR       Device;
+        UINT32                          Index;
+
+  //
+	//  Allocate the device structure
+	//
+	LengthInBytes = sizeof ( *pNicDevice );
+	Status = gBS->AllocatePool (
+                  EfiRuntimeServicesData,
+                  LengthInBytes,
+                  (VOID **) &pNicDevice
+                  );
+
+	if (EFI_ERROR (Status)) {
+		DEBUG ((EFI_D_ERROR, "gBS->AllocatePool:pNicDevice ERROR Status = %r\n", Status));
+		goto EXIT;
+	}
+	
+	//
+  //  Set the structure signature
+  //
+  ZeroMem ( pNicDevice, LengthInBytes );
+  pNicDevice->Signature = DEV_SIGNATURE;
+
+	Status = gBS->OpenProtocol (
+                    Controller,
+                    &gEfiUsbIoProtocolGuid,
+                    (VOID **) &pNicDevice->pUsbIo,
+                    pThis->DriverBindingHandle,
+                    Controller,
+                    EFI_OPEN_PROTOCOL_BY_DRIVER
+                    );
+
+	if (EFI_ERROR (Status)) {
+		DEBUG ((EFI_D_ERROR, "gBS->OpenProtocol:EFI_USB_IO_PROTOCOL ERROR Status = %r\n", Status));
+		gBS->FreePool ( pNicDevice );
+		goto EXIT;
+	}
+
+	//
+  //  Initialize the simple network protocol
+  //
+	Status = SN_Setup ( pNicDevice );
+
+	if (EFI_ERROR(Status)){
+	   DEBUG ((EFI_D_ERROR, "SN_Setup ERROR Status = %r\n", Status));
+	   gBS->CloseProtocol (
+					Controller,
+					&gEfiUsbIoProtocolGuid,
+					pThis->DriverBindingHandle,
+					Controller
+					);
+		  gBS->FreePool ( pNicDevice );
+		  goto EXIT;
+  }
+
+  Status = pNicDevice->pUsbIo->UsbGetDeviceDescriptor ( pNicDevice->pUsbIo, &Device );
+  if (EFI_ERROR ( Status )) {
+     gBS->CloseProtocol (
+               Controller,
+               &gEfiUsbIoProtocolGuid,
+               pThis->DriverBindingHandle,
+               Controller
+               );
+     gBS->FreePool ( pNicDevice );
+              goto EXIT;
+  } else {
+      //
+      //  Validate the adapter
+      //
+      for (Index = 0; ASIX_DONGLES[Index].VendorId != 0; Index++) {
+          if (ASIX_DONGLES[Index].VendorId == Device.IdVendor &&
+              ASIX_DONGLES[Index].ProductId == Device.IdProduct) {
+                break;
+          }
+      }
+
+      if (ASIX_DONGLES[Index].VendorId == 0) {
+         gBS->CloseProtocol (
+                   Controller,
+                   &gEfiUsbIoProtocolGuid,
+                   pThis->DriverBindingHandle,
+                   Controller
+                   );
+          gBS->FreePool ( pNicDevice );
+                   goto EXIT;
+      }
+
+      pNicDevice->Flags = ASIX_DONGLES[Index].Flags;
+  }
+
+	//
+  // Set Device Path
+  //  			
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID **) &ParentDevicePath,
+				          pThis->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+	if (EFI_ERROR(Status)) {
+        DEBUG ((EFI_D_ERROR, "gBS->OpenProtocol:EFI_DEVICE_PATH_PROTOCOL error. Status = %r\n",
+            Status));        
+		    gBS->CloseProtocol (
+					Controller,
+					&gEfiUsbIoProtocolGuid,
+					pThis->DriverBindingHandle,
+					Controller
+					);
+		  gBS->FreePool ( pNicDevice );
+		  goto EXIT;
+	}
+
+  ZeroMem (&MacDeviceNode, sizeof (MAC_ADDR_DEVICE_PATH));
+  MacDeviceNode.Header.Type = MESSAGING_DEVICE_PATH;
+  MacDeviceNode.Header.SubType = MSG_MAC_ADDR_DP;
+
+  SetDevicePathNodeLength (&MacDeviceNode.Header, sizeof (MAC_ADDR_DEVICE_PATH));
+      			
+  CopyMem (&MacDeviceNode.MacAddress,
+      								&pNicDevice->SimpleNetworkData.CurrentAddress,
+      								PXE_HWADDR_LEN_ETHER);
+      								
+  MacDeviceNode.IfType = pNicDevice->SimpleNetworkData.IfType;
+
+  pNicDevice->MyDevPath = AppendDevicePathNode (
+                                          ParentDevicePath,
+                                          (EFI_DEVICE_PATH_PROTOCOL *) &MacDeviceNode
+                                          );
+
+	pNicDevice->Controller = NULL;
+
+	//
+  //  Install both the simple network and device path protocols.
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                          &pNicDevice->Controller,
+                          &gEfiCallerIdGuid,
+                          pNicDevice,
+                          &gEfiSimpleNetworkProtocolGuid,            
+                          &pNicDevice->SimpleNetwork,
+						              &gEfiDevicePathProtocolGuid,
+						              pNicDevice->MyDevPath,
+                          NULL
+                          );
+
+	if (EFI_ERROR(Status)){
+		DEBUG ((EFI_D_ERROR, "gBS->InstallMultipleProtocolInterfaces error. Status = %r\n",
+            Status)); 
+		gBS->CloseProtocol (
+					               Controller,
+					               &gEfiDevicePathProtocolGuid,
+					               pThis->DriverBindingHandle,
+					               Controller);
+	   gBS->CloseProtocol (
+					Controller,
+					&gEfiUsbIoProtocolGuid,
+					pThis->DriverBindingHandle,
+					Controller
+					);
+		  gBS->FreePool ( pNicDevice );
+		  goto EXIT;
+	}
+
+	//
+	// Open For Child Device
+	//
+	Status = gBS->OpenProtocol (                                                                         
+                  Controller,
+                  &gEfiUsbIoProtocolGuid,
+                  (VOID **) &pNicDevice->pUsbIo,
+                  pThis->DriverBindingHandle,
+                  pNicDevice->Controller,
+                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+                  );
+
+	if (EFI_ERROR(Status)){
+	   gBS->UninstallMultipleProtocolInterfaces (
+              &pNicDevice->Controller,
+                          &gEfiCallerIdGuid,
+                          pNicDevice,
+                          &gEfiSimpleNetworkProtocolGuid,            
+                          &pNicDevice->SimpleNetwork,
+						              &gEfiDevicePathProtocolGuid,
+						              pNicDevice->MyDevPath,
+                          NULL
+                          );
+		gBS->CloseProtocol (
+					               Controller,
+					               &gEfiDevicePathProtocolGuid,
+					               pThis->DriverBindingHandle,
+					               Controller);
+	   gBS->CloseProtocol (
+					Controller,
+					&gEfiUsbIoProtocolGuid,
+					pThis->DriverBindingHandle,
+					Controller
+					);
+		  gBS->FreePool ( pNicDevice );
+	}
+
+EXIT:
+	return Status;
+
+}
+
+/**
+  Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and
+  closing the DevicePath and PciIo protocols on Controller.
+
+  @param [in] pThis                Protocol instance pointer.
+  @param [in] Controller           Handle of device to stop driver on.
+  @param [in] NumberOfChildren     How many children need to be stopped.
+  @param [in] pChildHandleBuffer   Not used.
+
+  @retval EFI_SUCCESS          This driver is removed Controller.
+  @retval EFI_DEVICE_ERROR     The device could not be stopped due to a device error.
+  @retval other                This driver was not removed from this device.
+
+**/
+EFI_STATUS
+EFIAPI
+DriverStop (
+  IN  EFI_DRIVER_BINDING_PROTOCOL * pThis,
+  IN  EFI_HANDLE Controller,
+  IN  UINTN NumberOfChildren,
+  IN  EFI_HANDLE * ChildHandleBuffer
+  )
+{
+		BOOLEAN                                   AllChildrenStopped;
+		UINTN                                     Index;
+		EFI_SIMPLE_NETWORK_PROTOCOL				  *SimpleNetwork;
+		EFI_STATUS                                Status = EFI_SUCCESS;
+		NIC_DEVICE								  *pNicDevice;
+		
+		//
+		// Complete all outstanding transactions to Controller.
+		// Don't allow any new transaction to Controller to be started.
+		//
+		if (NumberOfChildren == 0) {
+		
+		  Status = gBS->OpenProtocol (
+				                Controller,
+				                &gEfiSimpleNetworkProtocolGuid,
+				                (VOID **) &SimpleNetwork,
+				                pThis->DriverBindingHandle,
+				                Controller,
+				                EFI_OPEN_PROTOCOL_GET_PROTOCOL
+				                );
+				                
+			if (EFI_ERROR(Status)) {
+        //
+        // This is a 2nd type handle(multi-lun root), it needs to close devicepath
+        // and usbio protocol.
+        //
+        gBS->CloseProtocol (
+            Controller,
+            &gEfiDevicePathProtocolGuid,
+            pThis->DriverBindingHandle,
+            Controller
+            );
+        gBS->CloseProtocol (
+            Controller,
+            &gEfiUsbIoProtocolGuid,
+            pThis->DriverBindingHandle,
+            Controller
+            );
+        return EFI_SUCCESS;
+      }
+      
+      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( SimpleNetwork );
+      
+      Status = gBS->UninstallMultipleProtocolInterfaces (
+				                  Controller,				                  
+				                  &gEfiCallerIdGuid,
+                          pNicDevice,
+                          &gEfiSimpleNetworkProtocolGuid,            
+                          &pNicDevice->SimpleNetwork,
+						              &gEfiDevicePathProtocolGuid,
+						              pNicDevice->MyDevPath,
+                          NULL
+                          );
+                          
+      if (EFI_ERROR (Status)) {
+        return Status;
+      }
+		  //
+		  // Close the bus driver
+		  //
+		  Status = gBS->CloseProtocol (
+		                  Controller,
+		                  &gEfiDevicePathProtocolGuid,
+		                  pThis->DriverBindingHandle,
+		                  Controller
+		                  );
+
+		  if (EFI_ERROR(Status)){
+          DEBUG ((EFI_D_ERROR, "driver stop: gBS->CloseProtocol:EfiDevicePathProtocol error. Status %r\n", Status));
+		  }
+
+		  Status = gBS->CloseProtocol (
+		                  Controller,
+		                  &gEfiUsbIoProtocolGuid,
+		                  pThis->DriverBindingHandle,
+		                  Controller
+		                  );
+
+		  if (EFI_ERROR(Status)){
+          DEBUG ((EFI_D_ERROR, "driver stop: gBS->CloseProtocol:EfiUsbIoProtocol error. Status %r\n", Status));
+		  }
+      return EFI_SUCCESS;
+		} 
+		AllChildrenStopped = TRUE;
+
+		for (Index = 0; Index < NumberOfChildren; Index++) {
+
+				Status = gBS->OpenProtocol (
+				                ChildHandleBuffer[Index],
+				                &gEfiSimpleNetworkProtocolGuid,
+				                (VOID **) &SimpleNetwork,
+				                pThis->DriverBindingHandle,
+				                Controller,
+				                EFI_OPEN_PROTOCOL_GET_PROTOCOL
+				                );
+				                
+				if (EFI_ERROR (Status)) {
+          AllChildrenStopped = FALSE;
+          DEBUG ((EFI_D_ERROR, "Fail to stop No.%d multi-lun child handle when opening SimpleNetwork\n", (UINT32)Index));
+          continue;
+        } 
+        
+        pNicDevice = DEV_FROM_SIMPLE_NETWORK ( SimpleNetwork );
+        
+        gBS->CloseProtocol (
+				                    Controller,
+				                    &gEfiUsbIoProtocolGuid,
+				                    pThis->DriverBindingHandle,
+				                    ChildHandleBuffer[Index]
+				                    ); 
+				                    
+				Status = gBS->UninstallMultipleProtocolInterfaces (
+				                  ChildHandleBuffer[Index],				                  
+				                  &gEfiCallerIdGuid,
+                          pNicDevice,
+                          &gEfiSimpleNetworkProtocolGuid,            
+                          &pNicDevice->SimpleNetwork,
+						              &gEfiDevicePathProtocolGuid,
+						              pNicDevice->MyDevPath,
+                          NULL
+                          );
+                          
+        if (EFI_ERROR (Status)) {
+            Status = gBS->OpenProtocol (                                                                         
+                  Controller,
+                  &gEfiUsbIoProtocolGuid,
+                  (VOID **) &pNicDevice->pUsbIo,
+                  pThis->DriverBindingHandle,
+                  ChildHandleBuffer[Index],
+                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+                  );
+        }
+        else {
+            int i;
+            RX_PKT * pCurr = pNicDevice->QueueHead;
+            RX_PKT * pFree;
+            
+            for ( i = 0 ; i < MAX_QUEUE_SIZE ; i++) {
+                 if ( NULL != pCurr ) {
+                    pFree = pCurr;
+                    pCurr = pCurr->pNext;
+                    gBS->FreePool (pFree);
+                 }
+            }
+            
+            if ( NULL != pNicDevice->pRxTest)
+						    gBS->FreePool (pNicDevice->pRxTest);
+
+					 if ( NULL != pNicDevice->pTxTest)
+						    gBS->FreePool (pNicDevice->pTxTest);
+
+           if ( NULL != pNicDevice->MyDevPath)
+					       gBS->FreePool (pNicDevice->MyDevPath);
+		  
+				    if ( NULL != pNicDevice)
+                  gBS->FreePool (pNicDevice);
+        }
+    }
+        
+        if (!AllChildrenStopped) {
+                return EFI_DEVICE_ERROR;
+        }
+        return EFI_SUCCESS;
+}
+
+
+/**
+  Driver binding protocol declaration
+**/
+EFI_DRIVER_BINDING_PROTOCOL  gDriverBinding = {
+  DriverSupported,
+  DriverStart,
+  DriverStop,
+  0xa,
+  NULL,
+  NULL
+};
+
+
+/**
+  Ax88772 driver unload routine.
+
+  @param [in] ImageHandle       Handle for the image.
+
+  @retval EFI_SUCCESS           Image may be unloaded
+
+**/
+EFI_STATUS
+EFIAPI
+DriverUnload (
+  IN EFI_HANDLE ImageHandle
+  )
+{
+  UINTN BufferSize;
+  UINTN Index;
+  UINTN Max;
+  EFI_HANDLE * pHandle;
+  EFI_STATUS Status;
+
+  //
+  //  Determine which devices are using this driver
+  //
+  BufferSize = 0;
+  pHandle = NULL;
+  Status = gBS->LocateHandle (
+                  ByProtocol,
+                  &gEfiCallerIdGuid,
+                  NULL,
+                  &BufferSize,
+                  NULL );
+  if ( EFI_BUFFER_TOO_SMALL == Status ) {
+    for ( ; ; ) {
+      //
+      //  One or more block IO devices are present
+      //
+      Status = gBS->AllocatePool (
+                      EfiRuntimeServicesData,
+                      BufferSize,
+                      (VOID **) &pHandle
+                      );
+      if ( EFI_ERROR ( Status )) {
+        DEBUG ((EFI_D_ERROR, "Insufficient memory, failed handle buffer allocation\r\n"));
+        break;
+      }
+
+      //
+      //  Locate the block IO devices
+      //
+      Status = gBS->LocateHandle (
+                      ByProtocol,
+                      &gEfiCallerIdGuid,
+                      NULL,
+                      &BufferSize,
+                      pHandle );
+      if ( EFI_ERROR ( Status )) {
+        //
+        //  Error getting handles
+        //
+        break;
+      }
+      
+      //
+      //  Remove any use of the driver
+      //
+      Max = BufferSize / sizeof ( pHandle[ 0 ]);
+      for ( Index = 0; Max > Index; Index++ ) {
+        Status = DriverStop ( &gDriverBinding,
+                              pHandle[ Index ],
+                              0,
+                              NULL );
+        if ( EFI_ERROR ( Status )) {
+          DEBUG ((EFI_D_ERROR, "WARNING - Failed to shutdown the driver on handle %08x\r\n", pHandle[ Index ]));
+          break;
+        }
+      }
+      break;
+    }
+  }
+  else {
+    if ( EFI_NOT_FOUND == Status ) {
+      //
+      //  No devices were found
+      //
+      Status = EFI_SUCCESS;
+    }
+  }
+
+  //
+  //  Free the handle array          
+  //
+  if ( NULL != pHandle ) {
+    gBS->FreePool ( pHandle );
+  }
+
+  //
+  //  Remove the protocols installed by the EntryPoint routine.
+  //
+  if ( !EFI_ERROR ( Status )) {
+    gBS->UninstallMultipleProtocolInterfaces (
+            ImageHandle,
+            &gEfiDriverBindingProtocolGuid,
+            &gDriverBinding,                              
+            &gEfiComponentNameProtocolGuid,
+            &gComponentName,
+            &gEfiComponentName2ProtocolGuid,
+            &gComponentName2,
+            NULL
+            );
+
+    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
+            "Removed:   gEfiComponentName2ProtocolGuid from 0x%08x\r\n",
+            ImageHandle ));
+    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
+              "Removed:   gEfiComponentNameProtocolGuid from 0x%08x\r\n",
+              ImageHandle ));
+    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
+              "Removed:   gEfiDriverBindingProtocolGuid from 0x%08x\r\n",
+              ImageHandle ));
+
+  }
+
+  return Status;
+}
+
+
+/**
+Ax88772 driver entry point.
+
+@param [in] ImageHandle       Handle for the image.
+@param [in] pSystemTable      Address of the system table.
+
+@retval EFI_SUCCESS           Image successfully loaded.
+
+**/
+EFI_STATUS
+EFIAPI
+EntryPoint (
+  IN EFI_HANDLE ImageHandle,
+  IN EFI_SYSTEM_TABLE * pSystemTable
+  )
+{
+  EFI_STATUS    Status;
+
+  //
+  //  Add the driver to the list of drivers
+  //
+  Status = EfiLibInstallDriverBindingComponentName2 (
+             ImageHandle,
+             pSystemTable,
+             &gDriverBinding,
+             ImageHandle,
+             &gComponentName,
+             &gComponentName2
+             );
+  if ( !EFI_ERROR ( Status )) {
+    DEBUG ((EFI_D_INFO, "Installed: gEfiDriverBindingProtocolGuid on   0x%08x\r\n",
+              ImageHandle));
+    DEBUG ((EFI_D_INFO, "Installed: gEfiComponentNameProtocolGuid on   0x%08x\r\n",
+              ImageHandle));
+    DEBUG ((EFI_D_INFO,"Installed: gEfiComponentName2ProtocolGuid on   0x%08x\r\n",
+              ImageHandle ));
+
+  }
+  return Status;
+}
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwork.c b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwork.c
new file mode 100644
index 0000000000..76babedb20
--- /dev/null
+++ b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwork.c
@@ -0,0 +1,1657 @@
+/** @file
+  Provides the Simple Network functions.
+
+  Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Ax88772.h"
+
+/**
+  This function updates the filtering on the receiver.
+
+  This support routine calls ::Ax88772MacAddressSet to update
+  the MAC address.  This routine then rebuilds the multicast
+  hash by calling ::Ax88772MulticastClear and ::Ax88772MulticastSet.
+  Finally this routine enables the receiver by calling
+  ::Ax88772RxControl.
+                                                                                  
+  @param [in] pSimpleNetwork    Simple network mode pointer  
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+ReceiveFilterUpdate (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
+  )
+{
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  NIC_DEVICE * pNicDevice;
+  EFI_STATUS Status;
+  UINT32 Index;
+
+  //
+  // Set the MAC address
+  //
+  pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
+  pMode = pSimpleNetwork->Mode;
+
+  //
+  // Clear the multicast hash table
+  //
+  Ax88772MulticastClear ( pNicDevice );
+
+  //
+  // Load the multicast hash table
+  //
+  if ( 0 != ( pMode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST )) {
+      for ( Index = 0; Index < pMode->MCastFilterCount; Index++ ) {
+        //
+        // Enable the next multicast address
+        //
+        Ax88772MulticastSet ( pNicDevice,
+                              &pMode->MCastFilter[ Index ].Addr[0]);
+      }
+  }
+
+  Status = Ax88772RxControl ( pNicDevice, pMode->ReceiveFilterSetting );
+
+  return Status;
+}
+
+
+/**
+  This function updates the SNP driver status.
+  
+  This function gets the current interrupt and recycled transmit
+  buffer status from the network interface.  The interrupt status
+  and the media status are returned as a bit mask in InterruptStatus.
+  If InterruptStatus is NULL, the interrupt status will not be read.
+  Upon successful return of the media status, the MediaPresent field
+  of EFI_SIMPLE_NETWORK_MODE will be updated to reflect any change
+  of media status.  If TxBuf is not NULL, a recycled transmit buffer
+  address will be retrived.  If a recycled transmit buffer address
+  is returned in TxBuf, then the buffer has been successfully
+  transmitted, and the status for that buffer is cleared.
+
+  This function calls ::Ax88772Rx to update the media status and
+  queue any receive packets.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] pInterruptStatus  A pointer to the bit mask of the current active interrupts.
+                                If this is NULL, the interrupt status will not be read from
+                                the device.  If this is not NULL, the interrupt status will
+                                be read from teh device.  When the interrupt status is read,
+                                it will also be cleared.  Clearing the transmit interrupt
+                                does not empty the recycled transmit buffer array.
+  @param [out] ppTxBuf          Recycled transmit buffer address.  The network interface will
+                                not transmit if its internal recycled transmit buffer array is
+                                full.  Reading the transmit buffer does not clear the transmit
+                                interrupt.  If this is NULL, then the transmit buffer status
+                                will not be read.  If there are not transmit buffers to recycle
+                                and TxBuf is not NULL, *TxBuf will be set to NULL.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_GetStatus (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  OUT UINT32 * pInterruptStatus,
+  OUT VOID ** ppTxBuf
+  )
+{
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  NIC_DEVICE * pNicDevice;
+  EFI_STATUS Status;
+  BOOLEAN bFullDuplex;
+  BOOLEAN bLinkUp;
+  BOOLEAN bSpeed100;
+  EFI_TPL TplPrevious;
+ 
+  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
+  //
+  // Verify the parameters
+  //
+  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
+    //
+    // Return the transmit buffer
+    //
+    
+    pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
+    if (( NULL != ppTxBuf ) && ( NULL != pNicDevice->pTxBuffer )) {
+     		 *ppTxBuf = pNicDevice->pTxBuffer;
+     		 pNicDevice->pTxBuffer = NULL;
+   	}
+    
+    //
+    // Determine if interface is running
+    //
+    pMode = pSimpleNetwork->Mode;
+    if ( EfiSimpleNetworkInitialized == pMode->State ) {
+
+      if ( pNicDevice->LinkIdleCnt > MAX_LINKIDLE_THRESHOLD) {
+
+          bLinkUp = pNicDevice->bLinkUp;
+          bSpeed100 = pNicDevice->b100Mbps;
+          bFullDuplex = pNicDevice->bFullDuplex;
+          Status = Ax88772NegotiateLinkComplete ( pNicDevice,
+                                            &pNicDevice->PollCount,
+                                            &pNicDevice->bComplete,
+                                            &pNicDevice->bLinkUp,
+                                            &pNicDevice->b100Mbps,
+                                            &pNicDevice->bFullDuplex );
+
+          //
+          // Determine if the autonegotiation is complete
+          //
+          if ( pNicDevice->bComplete ) {
+              if ( pNicDevice->bLinkUp ) {
+                  if (( bSpeed100 && ( !pNicDevice->b100Mbps ))
+                      || (( !bSpeed100 ) && pNicDevice->b100Mbps )
+                      || ( bFullDuplex && ( !pNicDevice->bFullDuplex ))
+                      || (( !bFullDuplex ) && pNicDevice->bFullDuplex )) {
+                          pNicDevice->PollCount = 0;
+                          DEBUG (( EFI_D_INFO , "Reset to establish proper link setup: %d Mbps, %a duplex\r\n",
+                                    pNicDevice->b100Mbps ? 100 : 10, pNicDevice->bFullDuplex ? "Full" : "Half"));
+                          Status = SN_Reset ( &pNicDevice->SimpleNetwork, FALSE );
+                  }
+                  if (( !bLinkUp ) && pNicDevice->bLinkUp ) {
+                      //
+                      // Display the autonegotiation status
+                      //
+                      DEBUG (( EFI_D_INFO , "Link: Up, %d Mbps, %a duplex\r\n",
+                                pNicDevice->b100Mbps ? 100 : 10, pNicDevice->bFullDuplex ? "Full" : "Half"));
+
+                  }
+                  pNicDevice->LinkIdleCnt = 0;
+            }
+        }
+        //
+        //  Update the link status
+        //
+        if ( bLinkUp && ( !pNicDevice->bLinkUp )) {
+            DEBUG (( EFI_D_INFO , "Link: Down\r\n"));
+        }
+      }
+
+      pMode->MediaPresent = pNicDevice->bLinkUp;
+      //
+      // Return the interrupt status
+      //
+      if ( NULL != pInterruptStatus ) {
+        *pInterruptStatus = 0;
+      }   
+      Status = EFI_SUCCESS;
+    }
+    else {
+      if ( EfiSimpleNetworkStarted == pMode->State ) {
+        Status = EFI_DEVICE_ERROR;
+      }
+      else {
+        Status = EFI_NOT_STARTED;
+      }
+    }
+      
+  }
+  else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+  gBS->RestoreTPL(TplPrevious) ;
+
+  return Status;
+}
+
+
+/**
+  Resets the network adapter and allocates the transmit and receive buffers
+  required by the network interface; optionally, also requests allocation of
+  additional transmit and receive buffers.  This routine must be called before
+  any other routine in the Simple Network protocol is called.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] ExtraRxBufferSize Size in bytes to add to the receive buffer allocation
+  @param [in] ExtraTxBufferSize Size in bytes to add to the transmit buffer allocation
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_OUT_OF_RESOURCES  There was not enough memory for the transmit and receive buffers
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Initialize (                                              
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN UINTN ExtraRxBufferSize,
+  IN UINTN ExtraTxBufferSize
+  )
+{
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  EFI_STATUS Status;
+  UINT32  TmpState;
+   EFI_TPL TplPrevious;
+   
+   TplPrevious = gBS->RaiseTPL (TPL_CALLBACK);
+  //
+  // Verify the parameters
+  //
+  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
+    //
+    // Determine if the interface is already started
+    //
+    pMode = pSimpleNetwork->Mode;
+    if ( EfiSimpleNetworkStarted == pMode->State ) {
+      if (( 0 == ExtraRxBufferSize ) && ( 0 == ExtraTxBufferSize )) {
+        //
+        // Start the adapter
+        //
+        TmpState = pMode->State;
+        pMode->State = EfiSimpleNetworkInitialized;
+        Status = SN_Reset ( pSimpleNetwork, FALSE );
+        if ( EFI_ERROR ( Status )) {
+          //
+          // Update the network state
+          //
+          pMode->State = TmpState;
+          DEBUG (( EFI_D_ERROR , "SN_reset failed\n"));
+        }
+      }
+      else {
+        DEBUG (( EFI_D_ERROR , "Increase ExtraRxBufferSize = %d ExtraTxBufferSize=%d\n", 
+              ExtraRxBufferSize, ExtraTxBufferSize));
+        Status = EFI_UNSUPPORTED;
+      }
+    }
+    else {
+      Status = EFI_NOT_STARTED;
+    }
+  }
+  else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+  gBS->RestoreTPL (TplPrevious);
+
+  return Status;
+}
+
+
+/**
+  This function converts a multicast IP address to a multicast HW MAC address
+  for all packet transactions.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] bIPv6             Set to TRUE if the multicast IP address is IPv6 [RFC2460].
+                                Set to FALSE if the multicast IP address is IPv4 [RFC 791].
+  @param [in] pIP               The multicast IP address that is to be converted to a
+                                multicast HW MAC address.
+  @param [in] pMAC              The multicast HW MAC address that is to be generated from IP.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_MCastIPtoMAC (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN BOOLEAN bIPv6,
+  IN EFI_IP_ADDRESS * pIP,
+  OUT EFI_MAC_ADDRESS * pMAC
+  )
+{
+  EFI_STATUS Status;
+  EFI_TPL TplPrevious;
+
+  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
+  //
+  // Get pointer to SNP driver instance for *this.
+  //
+  if (pSimpleNetwork == NULL) {
+    gBS->RestoreTPL(TplPrevious);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (pIP == NULL || pMAC == NULL) {
+    gBS->RestoreTPL(TplPrevious);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (bIPv6){
+    Status = EFI_UNSUPPORTED;
+  }  
+  else {
+      //
+      // check if the ip given is a mcast IP
+      //
+      if ((pIP->v4.Addr[0] & 0xF0) != 0xE0) {
+        gBS->RestoreTPL(TplPrevious);
+        return EFI_INVALID_PARAMETER;
+      }
+      else {
+        if (pSimpleNetwork->Mode->State == EfiSimpleNetworkInitialized)
+        {
+          pMAC->Addr[0] = 0x01;
+          pMAC->Addr[1] = 0x00;
+          pMAC->Addr[2] = 0x5e;
+          pMAC->Addr[3] = (UINT8) (pIP->v4.Addr[1] & 0x7f);
+          pMAC->Addr[4] = (UINT8) pIP->v4.Addr[2];
+          pMAC->Addr[5] = (UINT8) pIP->v4.Addr[3];
+          Status = EFI_SUCCESS;
+        }
+        else if (pSimpleNetwork->Mode->State == EfiSimpleNetworkStarted) {
+          Status = EFI_DEVICE_ERROR;
+        }
+        else {
+          Status = EFI_NOT_STARTED;
+        }
+        gBS->RestoreTPL(TplPrevious);
+      }
+  }
+  return Status;
+}
+
+
+/**
+  This function performs read and write operations on the NVRAM device
+  attached to a network interface.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] ReadWrite         TRUE for read operations, FALSE for write operations.
+  @param [in] Offset            Byte offset in the NVRAM device at which to start the
+                                read or write operation.  This must be a multiple of
+                                NvRamAccessSize and less than NvRamSize.
+  @param [in] BufferSize        The number of bytes to read or write from the NVRAM device.
+                                This must also be a multiple of NvramAccessSize.
+  @param [in, out] pBuffer      A pointer to the data buffer.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_NvData (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN BOOLEAN ReadWrite,
+  IN UINTN Offset,
+  IN UINTN BufferSize,
+  IN OUT VOID * pBuffer
+  )
+{
+  EFI_STATUS Status;
+  //
+  // This is not currently supported
+  //
+  Status = EFI_UNSUPPORTED;
+  return Status;
+}
+
+VOID 
+FillPkt2Queue (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN UINTN BufLength)
+{
+
+  UINT16 * pLength;
+  UINT16 * pLengthBar;
+  UINT8* pData;
+  UINT32 offset;
+  NIC_DEVICE * pNicDevice;
+  
+  pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork);
+  for ( offset = 0; offset < BufLength; ){
+      pLength = (UINT16*) (pNicDevice->pBulkInBuff + offset);
+      pLengthBar = (UINT16*) (pNicDevice->pBulkInBuff + offset +2);
+      
+      *pLength &= 0x7ff;
+      *pLengthBar &= 0x7ff;
+      *pLengthBar |= 0xf800;
+      
+      if ((*pLength ^ *pLengthBar ) != 0xFFFF) {
+          DEBUG (( EFI_D_ERROR , "Pkt length error. BufLength = %d\n", BufLength));
+          return;
+      }          
+      
+      if (TRUE == pNicDevice->pNextFill->f_Used) {
+        return;
+      }
+      else {
+          pData = pNicDevice->pBulkInBuff + offset + 4;
+          pNicDevice->pNextFill->f_Used = TRUE;
+          pNicDevice->pNextFill->Length = *pLength;
+          CopyMem (&pNicDevice->pNextFill->Data[0], pData, *pLength);
+          
+          pNicDevice->pNextFill = pNicDevice->pNextFill->pNext;
+          offset += ((*pLength + HW_HDR_LENGTH - 1) &~3) + 1;
+          pNicDevice->PktCntInQueue++;
+      }
+              
+  }
+}
+
+EFI_STATUS
+EFIAPI
+SN_Receive (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  OUT UINTN                      * pHeaderSize,
+  OUT UINTN                      * pBufferSize,
+  OUT VOID                       * pBuffer,
+  OUT EFI_MAC_ADDRESS            * pSrcAddr,
+  OUT EFI_MAC_ADDRESS            * pDestAddr,
+  OUT UINT16                     * pProtocol
+  )
+{
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  NIC_DEVICE * pNicDevice;
+  EFI_STATUS Status;
+  EFI_TPL TplPrevious;
+  UINT16 Type;
+  EFI_USB_IO_PROTOCOL *pUsbIo;
+  UINTN LengthInBytes;
+  UINT32 TransferStatus;
+  RX_PKT * pFirstFill;
+  TplPrevious = gBS->RaiseTPL (TPL_CALLBACK);
+  
+  //
+  // Verify the parameters
+  //
+  if (( NULL != pSimpleNetwork ) && 
+    ( NULL != pSimpleNetwork->Mode ) && 
+    (NULL != pBufferSize) && 
+    (NULL != pBuffer)) {
+    //
+    // The interface must be running
+    //
+    pMode = pSimpleNetwork->Mode;
+    if ( EfiSimpleNetworkInitialized == pMode->State ) {
+      //
+      // Update the link status
+      //
+      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
+      pNicDevice->LinkIdleCnt++;
+      pMode->MediaPresent = pNicDevice->bLinkUp;
+      
+      if ( pMode->MediaPresent && pNicDevice->bComplete) {
+      
+      
+        if (pNicDevice->PktCntInQueue != 0 ) {
+            DEBUG (( EFI_D_INFO, "pNicDevice->PktCntInQueue = %d\n",
+                pNicDevice->PktCntInQueue));
+        }
+        
+        LengthInBytes = MAX_BULKIN_SIZE;
+        if (pNicDevice->PktCntInQueue == 0 ){
+            //
+            // Attempt to do bulk in
+            //
+            SetMem (&pNicDevice->pBulkInBuff[0], 4, 0);
+            pUsbIo = pNicDevice->pUsbIo;
+            Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
+                                       USB_ENDPOINT_DIR_IN | BULK_IN_ENDPOINT,
+                                       &pNicDevice->pBulkInBuff[0],
+                                       &LengthInBytes,
+                                       BULKIN_TIMEOUT,
+                                       &TransferStatus );
+                                       
+            if (LengthInBytes != 0 && !EFI_ERROR(Status) && !EFI_ERROR(TransferStatus) ){
+                FillPkt2Queue(pSimpleNetwork, LengthInBytes);
+            }
+        }
+        
+        pFirstFill = pNicDevice->pFirstFill;
+         
+        if (TRUE == pFirstFill->f_Used) {
+            ETHERNET_HEADER * pHeader;
+            pNicDevice->LinkIdleCnt = 0;
+            CopyMem (pBuffer,  &pFirstFill->Data[0], pFirstFill->Length);
+            pHeader = (ETHERNET_HEADER *) &pFirstFill->Data[0];
+                     
+            DEBUG (( EFI_D_INFO, "RX: %02x-%02x-%02x-%02x-%02x-%02x " 
+                      "%02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x  %d bytes\r\n",
+                      pFirstFill->Data[0],
+                      pFirstFill->Data[1],
+                      pFirstFill->Data[2],
+                      pFirstFill->Data[3],
+                      pFirstFill->Data[4],
+                      pFirstFill->Data[5],
+                      pFirstFill->Data[6],
+                      pFirstFill->Data[7],
+                      pFirstFill->Data[8],
+                      pFirstFill->Data[9],
+                      pFirstFill->Data[10],
+                      pFirstFill->Data[11],
+                      pFirstFill->Data[12],
+                      pFirstFill->Data[13],
+                      pFirstFill->Length));   
+            
+            if ( NULL != pHeaderSize ) {
+              *pHeaderSize = sizeof ( *pHeader );
+            }
+            if ( NULL != pDestAddr ) {
+               CopyMem ( pDestAddr, &pHeader->dest_addr, PXE_HWADDR_LEN_ETHER );
+            }
+            if ( NULL != pSrcAddr ) {
+             CopyMem ( pSrcAddr, &pHeader->src_addr, PXE_HWADDR_LEN_ETHER );
+            }
+            if ( NULL != pProtocol ) {
+              Type = pHeader->type;
+              Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
+              *pProtocol = Type;
+            }
+            Status = EFI_SUCCESS;
+            if (*pBufferSize < pFirstFill->Length) {
+                  DEBUG (( EFI_D_ERROR, "RX: Buffer was too small"));
+                  Status = EFI_BUFFER_TOO_SMALL;
+            }
+            *pBufferSize =  pFirstFill->Length;
+            pFirstFill->f_Used = FALSE;
+            pNicDevice->pFirstFill = pFirstFill->pNext;
+            pNicDevice->PktCntInQueue--;
+        }
+        else {
+            pNicDevice->LinkIdleCnt++;
+            Status = EFI_NOT_READY;
+        }
+      }
+      else {
+        //
+        //  Link no up
+        //
+        pNicDevice->LinkIdleCnt++;
+        Status = EFI_NOT_READY; 
+      }
+      
+    }
+    else {
+      if (EfiSimpleNetworkStarted == pMode->State) {
+        Status = EFI_DEVICE_ERROR;
+      }
+      else {
+        Status = EFI_NOT_STARTED;
+      }
+    }
+  }
+  else {
+    Status = EFI_INVALID_PARAMETER;
+  }                              
+  gBS->RestoreTPL (TplPrevious);
+  return Status;
+}
+
+/**
+  This function is used to enable and disable the hardware and software receive
+  filters for the underlying network device.
+
+  The receive filter change is broken down into three steps:
+
+    1.  The filter mask bits that are set (ON) in the Enable parameter
+        are added to the current receive filter settings.
+
+    2.  The filter mask bits that are set (ON) in the Disable parameter
+        are subtracted from the updated receive filter settins.
+
+    3.  If the resulting filter settigns is not supported by the hardware
+        a more liberal setting is selected.
+
+  If the same bits are set in the Enable and Disable parameters, then the bits
+  in the Disable parameter takes precedence.
+
+  If the ResetMCastFilter parameter is TRUE, then the multicast address list
+  filter is disabled (irregardless of what other multicast bits are set in
+  the enable and Disable parameters).  The SNP->Mode->MCastFilterCount field
+  is set to zero.  The SNP->Mode->MCastFilter contents are undefined.
+
+  After enableing or disabling receive filter settings, software should
+  verify the new settings by checking the SNP->Mode->ReceeiveFilterSettings,
+  SNP->Mode->MCastFilterCount and SNP->Mode->MCastFilter fields.
+
+  Note: Some network drivers and/or devices will automatically promote
+  receive filter settings if the requested setting can not be honored.
+  For example, if a request for four multicast addresses is made and
+  the underlying hardware only supports two multicast addresses the
+  driver might set the promiscuous or promiscuous multicast receive filters
+  instead.  The receiving software is responsible for discarding any extra
+  packets that get through the hardware receive filters.
+
+  If ResetMCastFilter is TRUE, then the multicast receive filter list
+  on the network interface will be reset to the default multicast receive
+  filter list.  If ResetMCastFilter is FALSE, and this network interface
+  allows the multicast receive filter list to be modified, then the
+  MCastFilterCnt and MCastFilter are used to update the current multicast
+  receive filter list.  The modified receive filter list settings can be
+  found in the MCastFilter field of EFI_SIMPLE_NETWORK_MODE.
+
+  This routine calls ::ReceiveFilterUpdate to update the receive
+  state in the network adapter.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] Enable            A bit mask of receive filters to enable on the network interface.
+  @param [in] Disable           A bit mask of receive filters to disable on the network interface.
+                                For backward compatibility with EFI 1.1 platforms, the
+                                EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit must be set
+                                when the ResetMCastFilter parameter is TRUE.
+  @param [in] bResetMCastFilter Set to TRUE to reset the contents of the multicast receive
+                                filters on the network interface to their default values.
+  @param [in] MCastFilterCnt    Number of multicast HW MAC address in the new MCastFilter list.
+                                This value must be less than or equal to the MaxMCastFilterCnt
+                                field of EFI_SIMPLE_NETWORK_MODE.  This field is optional if
+                                ResetMCastFilter is TRUE.
+  @param [in] pMCastFilter      A pointer to a list of new multicast receive filter HW MAC
+                                addresses.  This list will replace any existing multicast
+                                HW MAC address list.  This field is optional if ResetMCastFilter
+                                is TRUE.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_ReceiveFilters (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN UINT32 Enable,
+  IN UINT32 Disable,
+/*
+#define EFI_SIMPLE_NETWORK_RECEIVE_UNICAST               0x01
+#define EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST             0x02
+#define EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST             0x04
+#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS           0x08
+#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST 0x10
+*/
+  IN BOOLEAN bResetMCastFilter,
+  IN UINTN MCastFilterCnt,
+  IN EFI_MAC_ADDRESS * pMCastFilter
+  )
+{
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  EFI_STATUS Status = EFI_SUCCESS;   
+  EFI_TPL TplPrevious; 
+
+  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
+  pMode = pSimpleNetwork->Mode;
+
+  if (pSimpleNetwork == NULL) {
+    gBS->RestoreTPL(TplPrevious);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  switch (pMode->State) {
+    case EfiSimpleNetworkInitialized:
+      break;
+    case EfiSimpleNetworkStopped:
+      Status = EFI_NOT_STARTED;
+      gBS->RestoreTPL(TplPrevious);
+      return Status;
+    default:
+      Status = EFI_DEVICE_ERROR;
+      gBS->RestoreTPL(TplPrevious);
+      return Status;
+  }
+
+  //
+  // check if we are asked to enable or disable something that the UNDI
+  // does not even support!
+  //
+  if (((Enable &~pMode->ReceiveFilterMask) != 0) ||
+    ((Disable &~pMode->ReceiveFilterMask) != 0)) {
+    Status = EFI_INVALID_PARAMETER;
+    gBS->RestoreTPL(TplPrevious);
+    return Status;
+  }
+  
+  if (bResetMCastFilter) {
+    Disable |= (EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST & pMode->ReceiveFilterMask);
+      pMode->MCastFilterCount = 0;
+      if ( (0 == (pMode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST)) 
+            && Enable == 0 && Disable == 2) {
+            gBS->RestoreTPL(TplPrevious);
+            return EFI_SUCCESS;
+      }
+  } 
+  else {
+    if (MCastFilterCnt != 0) {
+      UINTN i; 
+      EFI_MAC_ADDRESS * pMulticastAddress;
+      pMulticastAddress =  pMCastFilter;
+      
+      if ((MCastFilterCnt > pMode->MaxMCastFilterCount) ||
+          (pMCastFilter == NULL)) {
+        Status = EFI_INVALID_PARAMETER;
+        gBS->RestoreTPL(TplPrevious);
+        return Status;
+      }
+      
+      for ( i = 0 ; i < MCastFilterCnt ; i++ ) {
+          UINT8  tmp;
+          tmp = pMulticastAddress->Addr[0];
+          if ( (tmp & 0x01) != 0x01 ) {
+            gBS->RestoreTPL(TplPrevious);
+            return EFI_INVALID_PARAMETER;
+          }
+          pMulticastAddress++;
+      }
+      
+      pMode->MCastFilterCount = (UINT32)MCastFilterCnt;
+      CopyMem (&pMode->MCastFilter[0],
+                     pMCastFilter,
+                     MCastFilterCnt * sizeof ( EFI_MAC_ADDRESS));
+    }
+  }
+  
+  if (Enable == 0 && Disable == 0 && !bResetMCastFilter && MCastFilterCnt == 0) {
+    Status = EFI_SUCCESS;
+    gBS->RestoreTPL(TplPrevious);
+    return Status;
+  }
+
+  if ((Enable & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0 && MCastFilterCnt == 0) {
+    Status = EFI_INVALID_PARAMETER;
+    gBS->RestoreTPL(TplPrevious);
+    return Status;
+  }
+  
+  pMode->ReceiveFilterSetting |= Enable;
+  pMode->ReceiveFilterSetting &= ~Disable;
+  Status = ReceiveFilterUpdate (pSimpleNetwork);
+  
+  if (EFI_DEVICE_ERROR == Status || EFI_INVALID_PARAMETER == Status)
+      Status = EFI_SUCCESS;
+
+  gBS->RestoreTPL(TplPrevious);
+  return Status;
+}
+
+/**
+  Reset the network adapter.
+
+  Resets a network adapter and reinitializes it with the parameters that
+  were provided in the previous call to Initialize ().  The transmit and
+  receive queues are cleared.  Receive filters, the station address, the
+  statistics, and the multicast-IP-to-HW MAC addresses are not reset by
+  this call.
+
+  This routine calls ::Ax88772Reset to perform the adapter specific
+  reset operation.  This routine also starts the link negotiation
+  by calling ::Ax88772NegotiateLinkStart.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] bExtendedVerification  Indicates that the driver may perform a more
+                                exhaustive verification operation of the device
+                                during reset.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Reset (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN BOOLEAN bExtendedVerification
+  )
+{
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  NIC_DEVICE * pNicDevice;
+  EFI_STATUS Status;
+  EFI_TPL TplPrevious;
+
+  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
+  //
+  //  Verify the parameters
+  //
+  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
+		pMode = pSimpleNetwork->Mode;
+		if ( EfiSimpleNetworkInitialized == pMode->State ) {
+    	//
+    	//  Update the device state
+    	//
+    	pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
+    	pNicDevice->bComplete = FALSE;
+    	pNicDevice->bLinkUp = FALSE; 
+    	pNicDevice->bHavePkt = FALSE;
+    	pMode = pSimpleNetwork->Mode;
+    	pMode->MediaPresent = FALSE;
+
+    	//
+   		//  Reset the device
+    	//
+    	Status = Ax88772Reset ( pNicDevice );
+    	if ( !EFI_ERROR ( Status )) {
+     	 	//
+     	 	//  Update the receive filters in the adapter
+     	 	//
+     	 	Status = ReceiveFilterUpdate ( pSimpleNetwork );
+
+     	 	//
+     		 //  Try to get a connection to the network
+     	 	//
+     	 	if ( !EFI_ERROR ( Status )) {
+        	//
+        	//  Start the autonegotiation
+       		//
+        	Status = Ax88772NegotiateLinkStart ( pNicDevice );
+     		}
+   	 	}
+   	}
+   	else {
+      if (EfiSimpleNetworkStarted == pMode->State) {
+        Status = EFI_DEVICE_ERROR;
+      }
+      else {
+        Status = EFI_NOT_STARTED;
+      }
+   	}  
+  }
+  else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+  gBS->RestoreTPL ( TplPrevious );
+  return Status;
+}
+
+/**
+  Initialize the simple network protocol.
+
+  This routine calls ::Ax88772MacAddressGet to obtain the
+  MAC address.
+
+  @param [in] pNicDevice       NIC_DEVICE_INSTANCE pointer
+
+  @retval EFI_SUCCESS     Setup was successful
+
+**/
+EFI_STATUS
+SN_Setup (
+  IN NIC_DEVICE * pNicDevice
+  )
+{
+  
+
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork;
+  EFI_STATUS Status;
+  RX_PKT * pCurr = NULL;
+  RX_PKT * pPrev = NULL;
+
+	pSimpleNetwork = &pNicDevice->SimpleNetwork;  
+  pSimpleNetwork->Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;
+  pSimpleNetwork->Start = (EFI_SIMPLE_NETWORK_START)SN_Start;
+  pSimpleNetwork->Stop = (EFI_SIMPLE_NETWORK_STOP)SN_Stop;
+  pSimpleNetwork->Initialize = (EFI_SIMPLE_NETWORK_INITIALIZE)SN_Initialize;
+  pSimpleNetwork->Reset = (EFI_SIMPLE_NETWORK_RESET)SN_Reset;
+  pSimpleNetwork->Shutdown = (EFI_SIMPLE_NETWORK_SHUTDOWN)SN_Shutdown;
+  pSimpleNetwork->ReceiveFilters = (EFI_SIMPLE_NETWORK_RECEIVE_FILTERS)SN_ReceiveFilters;
+  pSimpleNetwork->StationAddress = (EFI_SIMPLE_NETWORK_STATION_ADDRESS)SN_StationAddress;
+  pSimpleNetwork->Statistics = (EFI_SIMPLE_NETWORK_STATISTICS)SN_Statistics;
+  pSimpleNetwork->MCastIpToMac = (EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC)SN_MCastIPtoMAC;
+  pSimpleNetwork->NvData = (EFI_SIMPLE_NETWORK_NVDATA)SN_NvData;
+  pSimpleNetwork->GetStatus = (EFI_SIMPLE_NETWORK_GET_STATUS)SN_GetStatus;
+  pSimpleNetwork->Transmit = (EFI_SIMPLE_NETWORK_TRANSMIT)SN_Transmit;
+  pSimpleNetwork->Receive = (EFI_SIMPLE_NETWORK_RECEIVE)SN_Receive;
+  pSimpleNetwork->WaitForPacket = NULL;
+  pMode = &pNicDevice->SimpleNetworkData;
+  pSimpleNetwork->Mode = pMode;
+  pMode->State = EfiSimpleNetworkStopped;
+  pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
+  pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
+  pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
+  pMode->NvRamSize = 0;
+  pMode->NvRamAccessSize = 0;
+  pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
+                           | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
+                           | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
+                           | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
+                           | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
+  pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
+                              | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
+  pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
+  pMode->MCastFilterCount = 0;
+  SetMem ( &pMode->BroadcastAddress,
+           PXE_HWADDR_LEN_ETHER,
+           0xff );
+  pMode->IfType = EfiNetworkInterfaceUndi;
+  pMode->MacAddressChangeable = TRUE;
+  pMode->MultipleTxSupported = FALSE;
+  pMode->MediaPresentSupported = TRUE;
+  pMode->MediaPresent = FALSE;
+  pNicDevice->LinkIdleCnt = 0;
+  //
+  //  Read the MAC address
+  //
+  pNicDevice->PhyId = PHY_ID_INTERNAL;
+  pNicDevice->b100Mbps = TRUE;
+  pNicDevice->bFullDuplex = TRUE;
+  
+  Status = Ax88772MacAddressGet (
+                pNicDevice,
+                &pMode->PermanentAddress.Addr[0]);
+
+  if ( !EFI_ERROR ( Status )) {
+    int i; 
+    //
+    //  Use the hardware address as the current address
+    //
+
+    CopyMem ( &pMode->CurrentAddress,
+              &pMode->PermanentAddress,
+              PXE_HWADDR_LEN_ETHER );
+              
+    CopyMem ( &pNicDevice->MAC,
+              &pMode->PermanentAddress,
+              PXE_HWADDR_LEN_ETHER );
+              
+    pNicDevice->PktCntInQueue = 0;
+    
+    for ( i = 0 ; i < MAX_QUEUE_SIZE ; i++) {
+        Status = gBS->AllocatePool ( EfiRuntimeServicesData, 
+                                      sizeof (RX_PKT),
+                                      (VOID **) &pCurr);
+        if ( EFI_ERROR(Status)) {
+            DEBUG (( EFI_D_ERROR, "Memory are not enough\n"));
+            return Status;
+        }                              
+        pCurr->f_Used = FALSE;
+        
+        if ( i ) {
+            pPrev->pNext = pCurr;
+        }
+        else {
+            pNicDevice->QueueHead = pCurr;
+        }
+        
+        if (MAX_QUEUE_SIZE - 1 == i) {
+            pCurr->pNext = pNicDevice->QueueHead;
+        }
+        
+        pPrev = pCurr;
+    }
+    
+    pNicDevice->pNextFill = pNicDevice->QueueHead;
+    pNicDevice->pFirstFill = pNicDevice->QueueHead;
+    
+    Status = gBS->AllocatePool (EfiRuntimeServicesData,
+                                MAX_BULKIN_SIZE,
+                                (VOID **) &pNicDevice->pBulkInBuff);
+                                
+    if (EFI_ERROR(Status)) {
+        DEBUG (( EFI_D_ERROR, "gBS->AllocatePool for pBulkInBuff error. Status = %r\n",
+              Status));
+        return Status;
+    }
+  }
+  else {
+    DEBUG (( EFI_D_ERROR, "Ax88772MacAddressGet error. Status = %r\n", Status));
+		return Status;
+  }
+  
+  Status = gBS->AllocatePool ( EfiRuntimeServicesData,
+                                   sizeof ( RX_TX_PACKET ),
+                                   (VOID **) &pNicDevice->pRxTest );
+
+  if (EFI_ERROR (Status)) {
+    DEBUG (( EFI_D_ERROR, "gBS->AllocatePool:pNicDevice->pRxTest error. Status = %r\n",
+              Status));
+	  return Status;
+  }
+                                   
+  Status = gBS->AllocatePool ( EfiRuntimeServicesData,
+                                   sizeof ( RX_TX_PACKET ),
+                                   (VOID **) &pNicDevice->pTxTest );
+
+  if (EFI_ERROR (Status)) {
+    DEBUG (( EFI_D_ERROR, "gBS->AllocatePool:pNicDevice->pTxTest error. Status = %r\n",
+              Status));
+	  gBS->FreePool (pNicDevice->pRxTest);
+  }
+
+  return Status;
+}
+
+
+/**
+  This routine starts the network interface.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_ALREADY_STARTED   The network interface was already started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Start (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
+  )
+{
+  NIC_DEVICE * pNicDevice;
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  EFI_STATUS Status;
+  EFI_TPL TplPrevious;
+  int i = 0;
+  RX_PKT * pCurr = NULL;
+
+  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
+  //
+  // Verify the parameters
+  //
+  Status = EFI_INVALID_PARAMETER;
+  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
+    pMode = pSimpleNetwork->Mode;
+    if ( EfiSimpleNetworkStopped == pMode->State ) {
+      //
+      // Initialize the mode structuref
+      // NVRAM access is not supported
+      //
+      ZeroMem ( pMode, sizeof ( *pMode ));
+  
+      pMode->State = EfiSimpleNetworkStarted;
+      pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
+      pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
+      pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
+      pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
+                               | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
+                               | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
+                               | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
+                               | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
+      pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
+      pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
+      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
+      Status = Ax88772MacAddressGet ( pNicDevice, &pMode->PermanentAddress.Addr[0]);
+      CopyMem ( &pMode->CurrentAddress,
+                &pMode->PermanentAddress,
+                sizeof ( pMode->CurrentAddress ));
+      SetMem(&pMode->BroadcastAddress, PXE_HWADDR_LEN_ETHER, 0xff);
+      pMode->IfType = EfiNetworkInterfaceUndi;
+      pMode->MacAddressChangeable = TRUE;
+      pMode->MultipleTxSupported = FALSE;
+      pMode->MediaPresentSupported = TRUE;
+      pMode->MediaPresent = FALSE; 
+      pNicDevice->PktCntInQueue = 0;
+      pNicDevice->pNextFill = pNicDevice->QueueHead;
+      pNicDevice->pFirstFill = pNicDevice->QueueHead;
+      pCurr = pNicDevice->QueueHead;
+      
+      for ( i = 0 ; i < MAX_QUEUE_SIZE ; i++) { 
+        pCurr->f_Used = FALSE;
+        pCurr = pCurr->pNext;
+      }
+      
+    }
+    else {
+      Status = EFI_ALREADY_STARTED;
+    }
+  }
+  gBS->RestoreTPL ( TplPrevious );
+  return Status;
+}
+
+
+/**
+  Set the MAC address.
+  
+  This function modifies or resets the current station address of a
+  network interface.  If Reset is TRUE, then the current station address
+  is set ot the network interface's permanent address.  If Reset if FALSE
+  then the current station address is changed to the address specified by
+  pNew.
+
+  This routine calls ::Ax88772MacAddressSet to update the MAC address
+  in the network adapter.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] bReset            Flag used to reset the station address to the
+                                network interface's permanent address.
+  @param [in] pNew              New station address to be used for the network
+                                interface.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_StationAddress (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN BOOLEAN bReset,
+  IN EFI_MAC_ADDRESS * pNew
+  )
+{
+  NIC_DEVICE * pNicDevice;
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  EFI_STATUS Status;
+  EFI_TPL TplPrevious;
+  
+  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
+  //
+  // Verify the parameters
+  //
+  if (( NULL != pSimpleNetwork )
+    && ( NULL != pSimpleNetwork->Mode )
+    && (( bReset ) || ( ( !bReset) && ( NULL != pNew )))) {
+    //
+    // Verify that the adapter is already started
+    //
+    pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
+    pMode = pSimpleNetwork->Mode;
+    if ( EfiSimpleNetworkInitialized == pMode->State ) {
+      //
+      // Determine the adapter MAC address
+      //
+      if ( bReset ) {
+        //
+        // Use the permanent address
+        //
+        CopyMem ( &pMode->CurrentAddress,
+                  &pMode->PermanentAddress,
+                  sizeof ( pMode->CurrentAddress ));
+      }
+      else {
+        //
+        // Use the specified address
+        //
+        CopyMem ( &pMode->CurrentAddress,
+                  pNew,
+                  sizeof ( pMode->CurrentAddress ));
+      }
+
+      //
+      // Update the address on the adapter
+      //
+      Status = Ax88772MacAddressSet ( pNicDevice, &pMode->CurrentAddress.Addr[0]);
+    }
+    else {
+      if (EfiSimpleNetworkStarted == pMode->State) {
+        Status = EFI_DEVICE_ERROR;
+      }
+      else {
+        Status = EFI_NOT_STARTED;
+      }
+    }
+  }
+  else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+  gBS->RestoreTPL ( TplPrevious );
+  return Status;
+}
+
+
+/**
+  This function resets or collects the statistics on a network interface.
+  If the size of the statistics table specified by StatisticsSize is not
+  big enough for all of the statistics that are collected by the network
+  interface, then a partial buffer of statistics is returned in
+  StatisticsTable.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] bReset            Set to TRUE to reset the statistics for the network interface.
+  @param [in, out] pStatisticsSize  On input the size, in bytes, of StatisticsTable.  On output
+                                the size, in bytes, of the resulting table of statistics.
+  @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
+                                conains the statistics.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_BUFFER_TOO_SMALL  The pStatisticsTable is NULL or the buffer is too small.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+  typedef struct {
+  UINT64 RxTotalFrames;
+  UINT64 RxGoodFrames;
+  UINT64 RxUndersizeFrames;
+  UINT64 RxOversizeFrames;
+  UINT64 RxDroppedFrames;
+  UINT64 RxUnicastFrames;
+  UINT64 RxBroadcastFrames;
+  UINT64 RxMulticastFrames;
+  UINT64 RxCrcErrorFrames;
+  UINT64 RxTotalBytes;
+  UINT64 TxTotalFrames;
+  UINT64 TxGoodFrames;
+  UINT64 TxUndersizeFrames;
+  UINT64 TxOversizeFrames;
+  UINT64 TxDroppedFrames;
+  UINT64 TxUnicastFrames;
+  UINT64 TxBroadcastFrames;
+  UINT64 TxMulticastFrames;
+  UINT64 TxCrcErrorFrames;
+  UINT64 TxTotalBytes;
+  UINT64 Collisions;
+  UINT64 UnsupportedProtocol;
+  } EFI_NETWORK_STATISTICS;
+**/
+EFI_STATUS
+EFIAPI
+SN_Statistics (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN BOOLEAN bReset,
+  IN OUT UINTN * pStatisticsSize,
+  OUT EFI_NETWORK_STATISTICS * pStatisticsTable
+  )
+{
+  EFI_STATUS Status;
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  //
+  // Verify the prarameters
+  //
+  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
+    pMode = pSimpleNetwork->Mode;
+    //
+    // Determine if the interface is started 
+    //
+    if (EfiSimpleNetworkInitialized == pMode->State){
+      //
+      // Determine if the StatisticsSize is big enough
+      //
+      if (sizeof (EFI_NETWORK_STATISTICS) <= *pStatisticsSize){
+        if (bReset) {
+          Status = EFI_SUCCESS;
+        } 
+        else {
+          Status = EFI_UNSUPPORTED;
+        }
+      }
+      else {
+        Status = EFI_BUFFER_TOO_SMALL;
+      }
+    }
+    else{
+      if (EfiSimpleNetworkStarted == pMode->State) {
+        Status = EFI_DEVICE_ERROR;
+      }
+      else {
+        Status = EFI_NOT_STARTED;
+      }
+    }
+  }
+  else {
+  	Status = EFI_INVALID_PARAMETER;
+  }
+
+  return Status;
+}
+
+
+/**
+  This function stops a network interface.  This call is only valid
+  if the network interface is in the started state.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Stop (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
+  )
+{
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  EFI_STATUS Status;
+  EFI_TPL TplPrevious;
+  
+  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
+  //
+  // Verify the parameters
+  //
+  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
+    //
+    // Determine if the interface is started
+    //
+    pMode = pSimpleNetwork->Mode;   
+    if ( EfiSimpleNetworkStarted == pMode->State ) {
+        pMode->State = EfiSimpleNetworkStopped;
+        Status = EFI_SUCCESS; 
+    }
+    else {
+        Status = EFI_NOT_STARTED;
+    }
+  } 
+  else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+  
+  gBS->RestoreTPL ( TplPrevious );
+  return Status;
+}
+
+
+/**
+  This function releases the memory buffers assigned in the Initialize() call.
+  Pending transmits and receives are lost, and interrupts are cleared and disabled.
+  After this call, only Initialize() and Stop() calls may be used.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Shutdown (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
+  )
+{
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  UINT32 RxFilter;
+  EFI_STATUS Status;
+  EFI_TPL TplPrevious;
+  
+  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
+  //
+  // Verify the parameters
+  //
+  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
+    //
+    // Determine if the interface is already started
+    //
+    pMode = pSimpleNetwork->Mode;
+    if ( EfiSimpleNetworkInitialized == pMode->State ) {
+      //
+      // Stop the adapter
+      //
+      RxFilter = pMode->ReceiveFilterSetting;
+      pMode->ReceiveFilterSetting = 0;
+      Status = SN_Reset ( pSimpleNetwork, FALSE );
+      pMode->ReceiveFilterSetting = RxFilter;
+      if ( !EFI_ERROR ( Status )) {
+
+        //
+        // Update the network state
+        //
+        pMode->State = EfiSimpleNetworkStarted;
+      }
+      else if ( EFI_DEVICE_ERROR == Status ) {
+      	pMode->State = EfiSimpleNetworkStopped;
+      }
+    }
+    else {
+      Status = EFI_NOT_STARTED;
+    }
+  }
+  else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+  gBS->RestoreTPL ( TplPrevious );
+  return Status;
+}
+
+
+/**
+  Send a packet over the network.
+
+  This function places the packet specified by Header and Buffer on
+  the transmit queue.  This function performs a non-blocking transmit
+  operation.  When the transmit is complete, the buffer is returned
+  via the GetStatus() call.
+
+  This routine calls ::Ax88772Rx to empty the network adapter of
+  receive packets.  The routine then passes the transmit packet
+  to the network adapter.
+
+  @param [in] pSimpleNetwork    Protocol instance pointer
+  @param [in] HeaderSize        The size, in bytes, of the media header to be filled in by
+                                the Transmit() function.  If HeaderSize is non-zero, then
+                                it must be equal to SimpleNetwork->Mode->MediaHeaderSize
+                                and DestAddr and Protocol parameters must not be NULL.
+  @param [in] BufferSize        The size, in bytes, of the entire packet (media header and
+                                data) to be transmitted through the network interface.
+  @param [in] pBuffer           A pointer to the packet (media header followed by data) to
+                                to be transmitted.  This parameter can not be NULL.  If
+                                HeaderSize is zero, then the media header is Buffer must
+                                already be filled in by the caller.  If HeaderSize is nonzero,
+                                then the media header will be filled in by the Transmit()
+                                function.
+  @param [in] pSrcAddr          The source HW MAC address.  If HeaderSize is zero, then
+                                this parameter is ignored.  If HeaderSize is nonzero and
+                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
+                                is used for the source HW MAC address.
+  @param [in] pDestAddr         The destination HW MAC address.  If HeaderSize is zero, then
+                                this parameter is ignored.
+  @param [in] pProtocol         The type of header to build.  If HeaderSize is zero, then
+                                this parameter is ignored.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_NOT_READY         The network interface is too busy to accept this transmit request.
+  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+
+**/
+EFI_STATUS
+EFIAPI
+SN_Transmit (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
+  IN UINTN HeaderSize,
+  IN UINTN BufferSize,
+  IN VOID * pBuffer,
+  IN EFI_MAC_ADDRESS * pSrcAddr,
+  IN EFI_MAC_ADDRESS * pDestAddr,
+  IN UINT16 * pProtocol
+  )
+{
+  ETHERNET_HEADER * pHeader;
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  NIC_DEVICE * pNicDevice;
+  EFI_USB_IO_PROTOCOL * pUsbIo;
+  EFI_STATUS Status;
+  UINTN TransferLength;
+  UINT32 TransferStatus;
+  UINT16 Type;
+  EFI_TPL TplPrevious;
+
+  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
+
+  // Verify the parameters
+  //
+  if (( NULL != pSimpleNetwork ) && 
+      ( NULL != pSimpleNetwork->Mode ) && 
+      ( NULL != pBuffer) && 
+      ( (HeaderSize == 0) || ( (NULL != pDestAddr) && (NULL != pProtocol) ))) {
+    //
+    // The interface must be running
+    //
+    pMode = pSimpleNetwork->Mode;
+    //
+    // Verify parameter of HeaderSize
+    //
+    if ((HeaderSize == 0) || (HeaderSize == pMode->MediaHeaderSize)){
+      //
+      // Determine if BufferSize is big enough
+      //
+      if (BufferSize >= pMode->MediaHeaderSize){
+        if ( EfiSimpleNetworkInitialized == pMode->State ) {
+          //
+          // Update the link status
+          //
+          pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
+          pMode->MediaPresent = pNicDevice->bLinkUp;
+
+          //
+          //  Release the synchronization with Ax88772Timer
+          //      
+          if ( pMode->MediaPresent && pNicDevice->bComplete) {
+            //
+            //  Copy the packet into the USB buffer
+            //
+
+            CopyMem ( &pNicDevice->pTxTest->Data[0], pBuffer, BufferSize ); 
+            pNicDevice->pTxTest->Length = (UINT16) BufferSize;
+
+            //
+            //  Transmit the packet
+            //
+            pHeader = (ETHERNET_HEADER *) &pNicDevice->pTxTest->Data[0];
+            if ( 0 != HeaderSize ) {
+              if ( NULL != pDestAddr ) {
+                CopyMem ( &pHeader->dest_addr, pDestAddr, PXE_HWADDR_LEN_ETHER );
+              }
+              if ( NULL != pSrcAddr ) {
+                CopyMem ( &pHeader->src_addr, pSrcAddr, PXE_HWADDR_LEN_ETHER );
+              }
+              else {
+                CopyMem ( &pHeader->src_addr, &pMode->CurrentAddress.Addr[0], PXE_HWADDR_LEN_ETHER );
+              }
+              if ( NULL != pProtocol ) {
+                Type = *pProtocol;
+              }
+              else {
+                Type = pNicDevice->pTxTest->Length;
+              }
+              Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
+              pHeader->type = Type;
+            }
+            if ( pNicDevice->pTxTest->Length < MIN_ETHERNET_PKT_SIZE ) {
+              pNicDevice->pTxTest->Length = MIN_ETHERNET_PKT_SIZE;
+              ZeroMem ( &pNicDevice->pTxTest->Data[ BufferSize ],
+                        pNicDevice->pTxTest->Length - BufferSize );
+            }
+        
+            DEBUG ((EFI_D_INFO, "TX: %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-%02x-%02x-%02x"
+                      "  %02x-%02x  %d bytes\r\n",
+                      pNicDevice->pTxTest->Data[0],
+                      pNicDevice->pTxTest->Data[1],
+                      pNicDevice->pTxTest->Data[2],
+                      pNicDevice->pTxTest->Data[3],
+                      pNicDevice->pTxTest->Data[4],
+                      pNicDevice->pTxTest->Data[5],
+                      pNicDevice->pTxTest->Data[6],
+                      pNicDevice->pTxTest->Data[7],
+                      pNicDevice->pTxTest->Data[8],
+                      pNicDevice->pTxTest->Data[9],
+                      pNicDevice->pTxTest->Data[10],
+                      pNicDevice->pTxTest->Data[11],
+                      pNicDevice->pTxTest->Data[12],
+                      pNicDevice->pTxTest->Data[13],
+                      pNicDevice->pTxTest->Length ));
+
+            pNicDevice->pTxTest->LengthBar = ~(pNicDevice->pTxTest->Length);
+            TransferLength = sizeof ( pNicDevice->pTxTest->Length )
+                           + sizeof ( pNicDevice->pTxTest->LengthBar )
+                           + pNicDevice->pTxTest->Length;
+                           
+            if (TransferLength % 512 == 0 || TransferLength % 1024 == 0)
+                TransferLength +=4;
+
+            //
+            //  Work around USB bus driver bug where a timeout set by receive
+            //  succeeds but the timeout expires immediately after, causing the
+            //  transmit operation to timeout.
+            //
+            pUsbIo = pNicDevice->pUsbIo;
+            Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
+                                               BULK_OUT_ENDPOINT,
+                                               &pNicDevice->pTxTest->Length,
+                                               &TransferLength,
+                                               0xfffffffe, 
+                                               &TransferStatus );
+            if ( !EFI_ERROR ( Status )) {
+              Status = TransferStatus;
+            }
+
+            if ( !EFI_ERROR ( Status )) {
+              pNicDevice->pTxBuffer = pBuffer;
+            }
+            else {
+              if ((TransferLength != (UINTN)( pNicDevice->pTxTest->Length + 4 )) &&
+                   (TransferLength != (UINTN)(( pNicDevice->pTxTest->Length + 4 ) + 4))) {
+                DEBUG ((EFI_D_INFO, "TransferLength didn't match Packet Length\n"));
+              }
+              //
+              //  Reset the controller to fix the error
+              //
+              if ( EFI_DEVICE_ERROR == Status ) {
+                SN_Reset ( pSimpleNetwork, FALSE );
+              }
+              Status = EFI_NOT_READY;
+            }
+          }
+          else {
+            //
+            // No packets available.
+            //
+            Status = EFI_NOT_READY;
+          }
+          
+        }
+        else {
+          if (EfiSimpleNetworkStarted == pMode->State) {
+            Status = EFI_DEVICE_ERROR;
+          }
+          else {
+            Status = EFI_NOT_STARTED ;
+          }
+        }
+      }
+      else {
+        Status = EFI_BUFFER_TOO_SMALL;
+      }
+    }
+    else {
+      Status = EFI_INVALID_PARAMETER;
+    }
+  }
+  else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+  
+  gBS->RestoreTPL (TplPrevious);
+
+  return Status;
+}
diff --git a/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.c b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.c
new file mode 100644
index 0000000000..4e7830ea94
--- /dev/null
+++ b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.c
@@ -0,0 +1,917 @@
+/** @file
+  Cirrus Logic 5430 Controller Driver.
+  This driver is a sample implementation of the UGA Draw and Graphics Output
+  Protocols for the Cirrus Logic 5430 family of PCI video controllers.
+  This driver is only usable in the EFI pre-boot environment.
+  This sample is intended to show how the UGA Draw and Graphics output Protocol
+  is able to function.
+  The UGA I/O Protocol is not implemented in this sample.
+  A fully compliant EFI UGA driver requires both
+  the UGA Draw and the UGA I/O Protocol.  Please refer to Microsoft's
+  documentation on UGA for details on how to write a UGA driver that is able
+  to function both in the EFI pre-boot environment and from the OS runtime.
+
+  Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// Cirrus Logic 5430 Controller Driver
+//
+#include "CirrusLogic5430.h"
+
+EFI_DRIVER_BINDING_PROTOCOL gCirrusLogic5430DriverBinding = {
+  CirrusLogic5430ControllerDriverSupported,
+  CirrusLogic5430ControllerDriverStart,
+  CirrusLogic5430ControllerDriverStop,
+  0x10,
+  NULL,
+  NULL
+};
+
+///
+/// Generic Attribute Controller Register Settings
+///
+UINT8  AttributeController[21] = {
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+  0x41, 0x00, 0x0F, 0x00, 0x00
+};
+
+///
+/// Generic Graphics Controller Register Settings
+///
+UINT8 GraphicsController[9] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF
+};
+
+//
+// 640 x 480 x 256 color @ 60 Hertz
+//
+UINT8 Crtc_640_480_256_60[28] = {
+  0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e,
+  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe1, 0x83, 0xdf, 0x50, 0x00, 0xe7, 0x04, 0xe3,
+  0xff, 0x00, 0x00, 0x22
+};
+
+UINT16 Seq_640_480_256_60[15] = {
+  0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
+  0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e
+};
+
+//
+// 800 x 600 x 256 color @ 60 Hertz
+//
+UINT8 Crtc_800_600_256_60[28] = {
+  0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0,
+  0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x58, 0x8C, 0x57, 0x64, 0x00, 0x5F, 0x91, 0xE3,
+  0xFF, 0x00, 0x00, 0x22
+};
+
+UINT16 Seq_800_600_256_60[15] = {
+  0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
+  0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e
+};
+
+//
+// 1024 x 768 x 256 color @ 60 Hertz
+//
+UINT8 Crtc_1024_768_256_60[28] = {
+  0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,
+  0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3,
+  0xFF, 0x4A, 0x00, 0x22
+};
+
+UINT16 Seq_1024_768_256_60[15] = {
+  0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
+  0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e
+};
+
+///
+/// Table of supported video modes
+///
+CIRRUS_LOGIC_5430_VIDEO_MODES  CirrusLogic5430VideoModes[] = {
+  {  640, 480, 8, 60, Crtc_640_480_256_60,  Seq_640_480_256_60,  0xe3 },
+  {  800, 600, 8, 60, Crtc_800_600_256_60,  Seq_800_600_256_60,  0xef },
+  { 1024, 768, 8, 60, Crtc_1024_768_256_60, Seq_1024_768_256_60, 0xef }
+};
+
+
+/**
+  CirrusLogic5430ControllerDriverSupported
+
+  TODO:    This - add argument and description to function comment
+  TODO:    Controller - add argument and description to function comment
+  TODO:    RemainingDevicePath - add argument and description to function comment
+**/
+EFI_STATUS
+EFIAPI
+CirrusLogic5430ControllerDriverSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  )
+{
+  EFI_STATUS          Status;
+  EFI_PCI_IO_PROTOCOL *PciIo;
+  PCI_TYPE00          Pci;
+  EFI_DEV_PATH        *Node;
+
+  //
+  // Open the PCI I/O Protocol
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **) &PciIo,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Read the PCI Configuration Header from the PCI Device
+  //
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint32,
+                        0,
+                        sizeof (Pci) / sizeof (UINT32),
+                        &Pci
+                        );
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  Status = EFI_UNSUPPORTED;
+  //
+  // See if the I/O enable is on.  Most systems only allow one VGA device to be turned on
+  // at a time, so see if this is one that is turned on.
+  //
+  //  if (((Pci.Hdr.Command & 0x01) == 0x01)) {
+  //
+  // See if this is a Cirrus Logic PCI controller
+  //
+  if (Pci.Hdr.VendorId == CIRRUS_LOGIC_VENDOR_ID) {
+    //
+    // See if this is a 5430 or a 5446 PCI controller
+    //
+    if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_DEVICE_ID || 
+        Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID ||
+        Pci.Hdr.DeviceId == CIRRUS_LOGIC_5446_DEVICE_ID) {
+        
+      Status = EFI_SUCCESS;
+      //
+      // If this is an Intel 945 graphics controller,
+      // go further check RemainingDevicePath validation
+      //
+      if (RemainingDevicePath != NULL) {
+        Node = (EFI_DEV_PATH *) RemainingDevicePath;
+        //
+        // Check if RemainingDevicePath is the End of Device Path Node, 
+        // if yes, return EFI_SUCCESS
+        //
+        if (!IsDevicePathEnd (Node)) {
+          //
+          // If RemainingDevicePath isn't the End of Device Path Node,
+          // check its validation
+          //
+          if (Node->DevPath.Type != ACPI_DEVICE_PATH ||
+              Node->DevPath.SubType != ACPI_ADR_DP ||
+              DevicePathNodeLength(&Node->DevPath) != sizeof(ACPI_ADR_DEVICE_PATH)) {
+            Status = EFI_UNSUPPORTED;
+          }
+        }
+      }
+    }
+  }
+
+Done:
+  //
+  // Close the PCI I/O Protocol
+  //
+  gBS->CloseProtocol (
+        Controller,
+        &gEfiPciIoProtocolGuid,
+        This->DriverBindingHandle,
+        Controller
+        );
+
+  return Status;
+}
+
+/**
+  CirrusLogic5430ControllerDriverStart
+
+  TODO:    This - add argument and description to function comment
+  TODO:    Controller - add argument and description to function comment
+  TODO:    RemainingDevicePath - add argument and description to function comment
+**/
+EFI_STATUS
+EFIAPI
+CirrusLogic5430ControllerDriverStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  )
+{
+  EFI_STATUS                      Status;
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;
+  BOOLEAN                         PciAttributesSaved;
+  EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath;
+  ACPI_ADR_DEVICE_PATH            AcpiDeviceNode;
+  UINT64                          Supports;
+
+  PciAttributesSaved = FALSE;
+  //
+  // Allocate Private context data for UGA Draw inteface.
+  //
+  Private = AllocateZeroPool (sizeof (CIRRUS_LOGIC_5430_PRIVATE_DATA));
+  if (Private == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Error;
+  }
+
+  //
+  // Set up context record
+  //
+  Private->Signature  = CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE;
+  Private->Handle     = NULL;
+
+  //
+  // Open PCI I/O Protocol
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **) &Private->PciIo,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (EFI_ERROR (Status)) {
+    goto Error;
+  }
+
+  //
+  // Get supported PCI attributes
+  //
+  Status = Private->PciIo->Attributes (
+                             Private->PciIo,
+                             EfiPciIoAttributeOperationSupported,
+                             0,
+                             &Supports
+                             );
+  if (EFI_ERROR (Status)) {
+    goto Error;
+  }
+
+  Supports &= (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16);
+  if (Supports == 0 || Supports == (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) {
+    Status = EFI_UNSUPPORTED;
+    goto Error;
+  }  
+
+  //
+  // Save original PCI attributes
+  //
+  Status = Private->PciIo->Attributes (
+                    Private->PciIo,
+                    EfiPciIoAttributeOperationGet,
+                    0,
+                    &Private->OriginalPciAttributes
+                    );
+
+  if (EFI_ERROR (Status)) {
+    goto Error;
+  }
+  PciAttributesSaved = TRUE;
+
+  Status = Private->PciIo->Attributes (
+                             Private->PciIo,
+                             EfiPciIoAttributeOperationEnable,
+                             EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | Supports,
+                             NULL
+                             );
+  if (EFI_ERROR (Status)) {
+    goto Error;
+  }
+
+  //
+  // Get ParentDevicePath
+  //
+  Status = gBS->HandleProtocol (
+                  Controller,
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID **) &ParentDevicePath
+                  );
+  if (EFI_ERROR (Status)) {
+    goto Error;
+  }
+
+  if (FeaturePcdGet (PcdSupportGop)) {
+    //
+    // Set Gop Device Path
+    //
+    if (RemainingDevicePath == NULL) {
+      ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH));
+      AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH;
+      AcpiDeviceNode.Header.SubType = ACPI_ADR_DP;
+      AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0);
+      SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE_PATH));
+
+      Private->GopDevicePath = AppendDevicePathNode (
+                                          ParentDevicePath,
+                                          (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode
+                                          );
+    } else if (!IsDevicePathEnd (RemainingDevicePath)) {
+      //
+      // If RemainingDevicePath isn't the End of Device Path Node, 
+      // only scan the specified device by RemainingDevicePath
+      //
+      Private->GopDevicePath = AppendDevicePathNode (ParentDevicePath, RemainingDevicePath);
+    } else {
+      //
+      // If RemainingDevicePath is the End of Device Path Node, 
+      // don't create child device and return EFI_SUCCESS
+      //
+      Private->GopDevicePath = NULL;
+    }
+      
+    if (Private->GopDevicePath != NULL) {
+      //
+      // Creat child handle and device path protocol firstly
+      //
+      Private->Handle = NULL;
+      Status = gBS->InstallMultipleProtocolInterfaces (
+                      &Private->Handle,
+                      &gEfiDevicePathProtocolGuid,
+                      Private->GopDevicePath,
+                      NULL
+                      );
+    }
+  }
+
+  //
+  // Construct video mode buffer
+  //
+  Status = CirrusLogic5430VideoModeSetup (Private);
+  if (EFI_ERROR (Status)) {
+    goto Error;
+  }
+
+  if (FeaturePcdGet (PcdSupportUga)) {
+    //
+    // Start the UGA Draw software stack.
+    //
+    Status = CirrusLogic5430UgaDrawConstructor (Private);
+    ASSERT_EFI_ERROR (Status);
+
+    Private->UgaDevicePath = ParentDevicePath;
+    Status = gBS->InstallMultipleProtocolInterfaces (
+                    &Controller,
+                    &gEfiUgaDrawProtocolGuid,
+                    &Private->UgaDraw,
+                    &gEfiDevicePathProtocolGuid,
+                    Private->UgaDevicePath,
+                    NULL
+                    );
+
+  } else if (FeaturePcdGet (PcdSupportGop)) {
+    if (Private->GopDevicePath == NULL) {
+      //
+      // If RemainingDevicePath is the End of Device Path Node, 
+      // don't create child device and return EFI_SUCCESS
+      //
+      Status = EFI_SUCCESS;
+    } else {
+  
+      //
+      // Start the GOP software stack.
+      //
+      Status = CirrusLogic5430GraphicsOutputConstructor (Private);
+      ASSERT_EFI_ERROR (Status);
+  
+      Status = gBS->InstallMultipleProtocolInterfaces (
+                      &Private->Handle,
+                      &gEfiGraphicsOutputProtocolGuid,
+                      &Private->GraphicsOutput,
+                      &gEfiEdidDiscoveredProtocolGuid,
+                      &Private->EdidDiscovered,
+                      &gEfiEdidActiveProtocolGuid,
+                      &Private->EdidActive,
+                      NULL
+                      );
+    }
+  } else {
+    //
+    // This driver must support eithor GOP or UGA or both.
+    //
+    ASSERT (FALSE);
+    Status = EFI_UNSUPPORTED;
+  }
+
+
+Error:
+  if (EFI_ERROR (Status)) {
+    if (Private) {
+      if (Private->PciIo) {
+        if (PciAttributesSaved == TRUE) {
+          //
+          // Restore original PCI attributes
+          //
+          Private->PciIo->Attributes (
+                          Private->PciIo,
+                          EfiPciIoAttributeOperationSet,
+                          Private->OriginalPciAttributes,
+                          NULL
+                          );
+        }
+        //
+        // Close the PCI I/O Protocol
+        //
+        gBS->CloseProtocol (
+              Private->Handle,
+              &gEfiPciIoProtocolGuid,
+              This->DriverBindingHandle,
+              Private->Handle
+              );
+      }
+
+      gBS->FreePool (Private);
+    }
+  }
+
+  return Status;
+}
+
+/**
+  CirrusLogic5430ControllerDriverStop
+
+  TODO:    This - add argument and description to function comment
+  TODO:    Controller - add argument and description to function comment
+  TODO:    NumberOfChildren - add argument and description to function comment
+  TODO:    ChildHandleBuffer - add argument and description to function comment
+  TODO:    EFI_SUCCESS - add return value to function comment
+**/
+EFI_STATUS
+EFIAPI
+CirrusLogic5430ControllerDriverStop (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN UINTN                          NumberOfChildren,
+  IN EFI_HANDLE                     *ChildHandleBuffer
+  )
+{
+  EFI_UGA_DRAW_PROTOCOL           *UgaDraw;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL    *GraphicsOutput;
+
+  EFI_STATUS                      Status;
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;
+
+  if (FeaturePcdGet (PcdSupportUga)) {
+    Status = gBS->OpenProtocol (
+                    Controller,
+                    &gEfiUgaDrawProtocolGuid,
+                    (VOID **) &UgaDraw,
+                    This->DriverBindingHandle,
+                    Controller,
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                    );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    //
+    // Get our private context information
+    //
+    Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (UgaDraw);
+    CirrusLogic5430UgaDrawDestructor (Private);
+
+    if (FeaturePcdGet (PcdSupportGop)) {
+      CirrusLogic5430GraphicsOutputDestructor (Private);
+      //
+      // Remove the UGA and GOP protocol interface from the system
+      //
+      Status = gBS->UninstallMultipleProtocolInterfaces (
+                      Private->Handle,
+                      &gEfiUgaDrawProtocolGuid,
+                      &Private->UgaDraw,
+                      &gEfiGraphicsOutputProtocolGuid,
+                      &Private->GraphicsOutput,
+                      NULL
+                      );
+    } else {
+      //
+      // Remove the UGA Draw interface from the system
+      //
+      Status = gBS->UninstallMultipleProtocolInterfaces (
+                      Private->Handle,
+                      &gEfiUgaDrawProtocolGuid,
+                      &Private->UgaDraw,
+                      NULL
+                      );
+    }
+  } else {
+    Status = gBS->OpenProtocol (
+                    Controller,
+                    &gEfiGraphicsOutputProtocolGuid,
+                    (VOID **) &GraphicsOutput,
+                    This->DriverBindingHandle,
+                    Controller,
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                    );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    //
+    // Get our private context information
+    //
+    Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput);
+
+    CirrusLogic5430GraphicsOutputDestructor (Private);
+    //
+    // Remove the GOP protocol interface from the system
+    //
+    Status = gBS->UninstallMultipleProtocolInterfaces (
+                    Private->Handle,
+                    &gEfiUgaDrawProtocolGuid,
+                    &Private->UgaDraw,
+                    &gEfiGraphicsOutputProtocolGuid,
+                    &Private->GraphicsOutput,
+                    NULL
+                    );
+  }
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Restore original PCI attributes
+  //
+  Private->PciIo->Attributes (
+                  Private->PciIo,
+                  EfiPciIoAttributeOperationSet,
+                  Private->OriginalPciAttributes,
+                  NULL
+                  );
+
+  //
+  // Close the PCI I/O Protocol
+  //
+  gBS->CloseProtocol (
+        Controller,
+        &gEfiPciIoProtocolGuid,
+        This->DriverBindingHandle,
+        Controller
+        );
+
+  //
+  // Free our instance data
+  //
+  gBS->FreePool (Private);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  CirrusLogic5430UgaDrawDestructor
+
+  TODO:    Private - add argument and description to function comment
+  TODO:    EFI_SUCCESS - add return value to function comment
+**/
+EFI_STATUS
+CirrusLogic5430UgaDrawDestructor (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  TODO: Add function description
+
+  @param  Private TODO: add argument description
+  @param  Address TODO: add argument description
+  @param  Data TODO: add argument description
+
+  TODO: add return values
+
+**/
+VOID
+outb (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
+  UINTN                           Address,
+  UINT8                           Data
+  )
+{
+  Private->PciIo->Io.Write (
+                      Private->PciIo,
+                      EfiPciIoWidthUint8,
+                      EFI_PCI_IO_PASS_THROUGH_BAR,
+                      Address,
+                      1,
+                      &Data
+                      );
+}
+
+/**
+  TODO: Add function description
+
+  @param  Private TODO: add argument description
+  @param  Address TODO: add argument description
+  @param  Data TODO: add argument description
+
+  TODO: add return values
+
+**/
+VOID
+outw (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
+  UINTN                           Address,
+  UINT16                          Data
+  )
+{
+  Private->PciIo->Io.Write (
+                      Private->PciIo,
+                      EfiPciIoWidthUint16,
+                      EFI_PCI_IO_PASS_THROUGH_BAR,
+                      Address,
+                      1,
+                      &Data
+                      );
+}
+
+/**
+  TODO: Add function description
+
+  @param  Private TODO: add argument description
+  @param  Address TODO: add argument description
+
+  TODO: add return values
+
+**/
+UINT8
+inb (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
+  UINTN                           Address
+  )
+{
+  UINT8 Data;
+
+  Private->PciIo->Io.Read (
+                      Private->PciIo,
+                      EfiPciIoWidthUint8,
+                      EFI_PCI_IO_PASS_THROUGH_BAR,
+                      Address,
+                      1,
+                      &Data
+                      );
+  return Data;
+}
+
+/**
+  TODO: Add function description
+
+  @param  Private TODO: add argument description
+  @param  Address TODO: add argument description
+
+  TODO: add return values
+
+**/
+UINT16
+inw (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
+  UINTN                           Address
+  )
+{
+  UINT16  Data;
+
+  Private->PciIo->Io.Read (
+                      Private->PciIo,
+                      EfiPciIoWidthUint16,
+                      EFI_PCI_IO_PASS_THROUGH_BAR,
+                      Address,
+                      1,
+                      &Data
+                      );
+  return Data;
+}
+
+/**
+  TODO: Add function description
+
+  @param  Private TODO: add argument description
+  @param  Index TODO: add argument description
+  @param  Red TODO: add argument description
+  @param  Green TODO: add argument description
+  @param  Blue TODO: add argument description
+
+  TODO: add return values
+
+**/
+VOID
+SetPaletteColor (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
+  UINTN                           Index,
+  UINT8                           Red,
+  UINT8                           Green,
+  UINT8                           Blue
+  )
+{
+  outb (Private, PALETTE_INDEX_REGISTER, (UINT8) Index);
+  outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Red >> 2));
+  outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Green >> 2));
+  outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Blue >> 2));
+}
+
+/**
+  TODO: Add function description
+
+  @param  Private TODO: add argument description
+
+  TODO: add return values
+
+**/
+VOID
+SetDefaultPalette (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
+  )
+{
+  UINTN Index;
+  UINTN RedIndex;
+  UINTN GreenIndex;
+  UINTN BlueIndex;
+
+  Index = 0;
+  for (RedIndex = 0; RedIndex < 8; RedIndex++) {
+    for (GreenIndex = 0; GreenIndex < 8; GreenIndex++) {
+      for (BlueIndex = 0; BlueIndex < 4; BlueIndex++) {
+        SetPaletteColor (Private, Index, (UINT8) (RedIndex << 5), (UINT8) (GreenIndex << 5), (UINT8) (BlueIndex << 6));
+        Index++;
+      }
+    }
+  }
+}
+
+/**
+  TODO: Add function description
+
+  @param  Private TODO: add argument description
+
+  TODO: add return values
+
+**/
+VOID
+ClearScreen (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
+  )
+{
+  UINT32  Color;
+
+  Color = 0;
+  Private->PciIo->Mem.Write (
+                        Private->PciIo,
+                        EfiPciIoWidthFillUint32,
+                        0,
+                        0,
+                        0x100000 >> 2,
+                        &Color
+                        );
+}
+
+/**
+  TODO: Add function description
+
+  @param  Private TODO: add argument description
+
+  TODO: add return values
+
+**/
+VOID
+DrawLogo (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
+  UINTN                           ScreenWidth,
+  UINTN                           ScreenHeight
+  )
+{
+}
+
+/**
+  TODO: Add function description
+
+  @param  Private TODO: add argument description
+  @param  ModeData TODO: add argument description
+
+  TODO: add return values
+
+**/
+VOID
+InitializeGraphicsMode (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
+  CIRRUS_LOGIC_5430_VIDEO_MODES   *ModeData
+  )
+{
+  UINT8 Byte;
+  UINTN Index;
+  UINT16 DeviceId;
+  EFI_STATUS Status;
+
+  Status = Private->PciIo->Pci.Read (
+             Private->PciIo,
+             EfiPciIoWidthUint16,
+             PCI_DEVICE_ID_OFFSET,
+             1,
+             &DeviceId
+             );
+  //
+  // Read the PCI Configuration Header from the PCI Device
+  //
+  ASSERT_EFI_ERROR (Status);
+
+  outw (Private, SEQ_ADDRESS_REGISTER, 0x1206);
+  outw (Private, SEQ_ADDRESS_REGISTER, 0x0012);
+
+  for (Index = 0; Index < 15; Index++) {
+    outw (Private, SEQ_ADDRESS_REGISTER, ModeData->SeqSettings[Index]);
+  }
+
+  if (DeviceId != CIRRUS_LOGIC_5446_DEVICE_ID) {
+    outb (Private, SEQ_ADDRESS_REGISTER, 0x0f);
+    Byte = (UINT8) ((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30);
+    outb (Private, SEQ_DATA_REGISTER, Byte);
+  }
+
+  outb (Private, MISC_OUTPUT_REGISTER, ModeData->MiscSetting);
+  outw (Private, GRAPH_ADDRESS_REGISTER, 0x0506);
+  outw (Private, SEQ_ADDRESS_REGISTER, 0x0300);
+  outw (Private, CRTC_ADDRESS_REGISTER, 0x2011);
+
+  for (Index = 0; Index < 28; Index++) {
+    outw (Private, CRTC_ADDRESS_REGISTER, (UINT16) ((ModeData->CrtcSettings[Index] << 8) | Index));
+  }
+
+  for (Index = 0; Index < 9; Index++) {
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((GraphicsController[Index] << 8) | Index));
+  }
+
+  inb (Private, INPUT_STATUS_1_REGISTER);
+
+  for (Index = 0; Index < 21; Index++) {
+    outb (Private, ATT_ADDRESS_REGISTER, (UINT8) Index);
+    outb (Private, ATT_ADDRESS_REGISTER, AttributeController[Index]);
+  }
+
+  outb (Private, ATT_ADDRESS_REGISTER, 0x20);
+
+  outw (Private, GRAPH_ADDRESS_REGISTER, 0x0009);
+  outw (Private, GRAPH_ADDRESS_REGISTER, 0x000a);
+  outw (Private, GRAPH_ADDRESS_REGISTER, 0x000b);
+  outb (Private, DAC_PIXEL_MASK_REGISTER, 0xff);
+
+  SetDefaultPalette (Private);
+  ClearScreen (Private);
+}
+
+EFI_STATUS
+EFIAPI
+InitializeCirrusLogic5430 (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+  EFI_STATUS              Status;
+
+  Status = EfiLibInstallDriverBindingComponentName2 (
+             ImageHandle,
+             SystemTable,
+             &gCirrusLogic5430DriverBinding,
+             ImageHandle,
+             &gCirrusLogic5430ComponentName,
+             &gCirrusLogic5430ComponentName2
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Install EFI Driver Supported EFI Version Protocol required for
+  // EFI drivers that are on PCI and other plug in cards.
+  //
+  gCirrusLogic5430DriverSupportedEfiVersion.FirmwareVersion = PcdGet32 (PcdDriverSupportedEfiVersion);
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gEfiDriverSupportedEfiVersionProtocolGuid,
+                  &gCirrusLogic5430DriverSupportedEfiVersion,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.h b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.h
new file mode 100644
index 0000000000..355f0418b3
--- /dev/null
+++ b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.h
@@ -0,0 +1,432 @@
+/** @file
+  Cirrus Logic 5430 Controller Driver
+
+  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// Cirrus Logic 5430 Controller Driver
+//
+
+#ifndef _CIRRUS_LOGIC_5430_H_
+#define _CIRRUS_LOGIC_5430_H_
+
+
+#include <Uefi.h>
+#include <Protocol/UgaDraw.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/DriverSupportedEfiVersion.h>
+#include <Protocol/EdidOverride.h>
+#include <Protocol/EdidDiscovered.h>
+#include <Protocol/EdidActive.h>
+#include <Protocol/DevicePath.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/TimerLib.h>
+
+#include <IndustryStandard/Pci.h>
+//
+// Cirrus Logic 5430 PCI Configuration Header values
+//
+#define CIRRUS_LOGIC_VENDOR_ID                0x1013
+#define CIRRUS_LOGIC_5430_DEVICE_ID           0x00a8
+#define CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID 0x00a0
+#define CIRRUS_LOGIC_5446_DEVICE_ID           0x00b8
+
+//
+// Cirrus Logic Graphical Mode Data
+//
+#define CIRRUS_LOGIC_5430_MODE_COUNT         3
+
+typedef struct {
+  UINT32  ModeNumber;
+  UINT32  HorizontalResolution;
+  UINT32  VerticalResolution;
+  UINT32  ColorDepth;
+  UINT32  RefreshRate;
+} CIRRUS_LOGIC_5430_MODE_DATA;
+
+#define PIXEL_RED_SHIFT   0
+#define PIXEL_GREEN_SHIFT 3
+#define PIXEL_BLUE_SHIFT  6
+
+#define PIXEL_RED_MASK    (BIT7 | BIT6 | BIT5)
+#define PIXEL_GREEN_MASK  (BIT4 | BIT3 | BIT2)
+#define PIXEL_BLUE_MASK   (BIT1 | BIT0)
+
+#define PIXEL_TO_COLOR_BYTE(pixel, mask, shift) ((UINT8) ((pixel & mask) << shift))
+#define PIXEL_TO_RED_BYTE(pixel) PIXEL_TO_COLOR_BYTE(pixel, PIXEL_RED_MASK, PIXEL_RED_SHIFT)
+#define PIXEL_TO_GREEN_BYTE(pixel) PIXEL_TO_COLOR_BYTE(pixel, PIXEL_GREEN_MASK, PIXEL_GREEN_SHIFT)
+#define PIXEL_TO_BLUE_BYTE(pixel) PIXEL_TO_COLOR_BYTE(pixel, PIXEL_BLUE_MASK, PIXEL_BLUE_SHIFT)
+
+#define RGB_BYTES_TO_PIXEL(Red, Green, Blue) \
+  (UINT8) ( (((Red) >> PIXEL_RED_SHIFT) & PIXEL_RED_MASK) | \
+            (((Green) >> PIXEL_GREEN_SHIFT) & PIXEL_GREEN_MASK) | \
+            (((Blue) >> PIXEL_BLUE_SHIFT) & PIXEL_BLUE_MASK) )
+
+#define GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER  0xffff
+
+//
+// Cirrus Logic 5440 Private Data Structure
+//
+#define CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE  SIGNATURE_32 ('C', 'L', '5', '4')
+
+typedef struct {
+  UINT64                                Signature;
+  EFI_HANDLE                            Handle;
+  EFI_PCI_IO_PROTOCOL                   *PciIo;
+  UINT64                                OriginalPciAttributes;
+  EFI_UGA_DRAW_PROTOCOL                 UgaDraw;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL          GraphicsOutput;
+  EFI_EDID_DISCOVERED_PROTOCOL          EdidDiscovered;
+  EFI_EDID_ACTIVE_PROTOCOL              EdidActive;
+  EFI_DEVICE_PATH_PROTOCOL              *GopDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL              *UgaDevicePath;
+  UINTN                                 CurrentMode;
+  UINTN                                 MaxMode;
+  CIRRUS_LOGIC_5430_MODE_DATA           ModeData[CIRRUS_LOGIC_5430_MODE_COUNT];
+  UINT8                                 *LineBuffer;
+  BOOLEAN                               HardwareNeedsStarting;
+} CIRRUS_LOGIC_5430_PRIVATE_DATA;
+
+///
+/// Video Mode structure
+///
+typedef struct {
+  UINT32  Width;
+  UINT32  Height;
+  UINT32  ColorDepth;
+  UINT32  RefreshRate;
+  UINT8   *CrtcSettings;
+  UINT16  *SeqSettings;
+  UINT8   MiscSetting;
+} CIRRUS_LOGIC_5430_VIDEO_MODES;
+
+#define CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS(a) \
+  CR(a, CIRRUS_LOGIC_5430_PRIVATE_DATA, UgaDraw, CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE)
+
+#define CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS(a) \
+  CR(a, CIRRUS_LOGIC_5430_PRIVATE_DATA, GraphicsOutput, CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE)
+
+
+//
+// Global Variables
+//
+extern UINT8                                      AttributeController[];
+extern UINT8                                      GraphicsController[];
+extern UINT8                                      Crtc_640_480_256_60[];
+extern UINT16                                     Seq_640_480_256_60[];
+extern UINT8                                      Crtc_800_600_256_60[];
+extern UINT16                                     Seq_800_600_256_60[];
+extern UINT8                                      Crtc_1024_768_256_60[];
+extern UINT16                                     Seq_1024_768_256_60[];
+extern CIRRUS_LOGIC_5430_VIDEO_MODES              CirrusLogic5430VideoModes[];
+extern EFI_DRIVER_BINDING_PROTOCOL                gCirrusLogic5430DriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL                gCirrusLogic5430ComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL               gCirrusLogic5430ComponentName2;
+extern EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL  gCirrusLogic5430DriverSupportedEfiVersion;
+
+//
+// Io Registers defined by VGA
+//
+#define CRTC_ADDRESS_REGISTER   0x3d4
+#define CRTC_DATA_REGISTER      0x3d5
+#define SEQ_ADDRESS_REGISTER    0x3c4
+#define SEQ_DATA_REGISTER       0x3c5
+#define GRAPH_ADDRESS_REGISTER  0x3ce
+#define GRAPH_DATA_REGISTER     0x3cf
+#define ATT_ADDRESS_REGISTER    0x3c0
+#define MISC_OUTPUT_REGISTER    0x3c2
+#define INPUT_STATUS_1_REGISTER 0x3da
+#define DAC_PIXEL_MASK_REGISTER 0x3c6
+#define PALETTE_INDEX_REGISTER  0x3c8
+#define PALETTE_DATA_REGISTER   0x3c9
+
+//
+// UGA Draw Hardware abstraction internal worker functions
+//
+EFI_STATUS
+CirrusLogic5430UgaDrawConstructor (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
+  );
+
+EFI_STATUS
+CirrusLogic5430UgaDrawDestructor (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
+  );
+
+//
+// Graphics Output Hardware abstraction internal worker functions
+//
+EFI_STATUS
+CirrusLogic5430GraphicsOutputConstructor (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
+  );
+
+EFI_STATUS
+CirrusLogic5430GraphicsOutputDestructor (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
+  );
+
+
+//
+// EFI_DRIVER_BINDING_PROTOCOL Protocol Interface
+//
+/**
+  TODO: Add function description
+
+  @param  This TODO: add argument description
+  @param  Controller TODO: add argument description
+  @param  RemainingDevicePath TODO: add argument description
+
+  TODO: add return values
+
+**/
+EFI_STATUS
+EFIAPI
+CirrusLogic5430ControllerDriverSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  );
+
+/**
+  TODO: Add function description
+
+  @param  This TODO: add argument description
+  @param  Controller TODO: add argument description
+  @param  RemainingDevicePath TODO: add argument description
+
+  TODO: add return values
+
+**/
+EFI_STATUS
+EFIAPI
+CirrusLogic5430ControllerDriverStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  );
+
+/**
+  TODO: Add function description
+
+  @param  This TODO: add argument description
+  @param  Controller TODO: add argument description
+  @param  NumberOfChildren TODO: add argument description
+  @param  ChildHandleBuffer TODO: add argument description
+
+  TODO: add return values
+
+**/
+EFI_STATUS
+EFIAPI
+CirrusLogic5430ControllerDriverStop (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN UINTN                        NumberOfChildren,
+  IN EFI_HANDLE                   *ChildHandleBuffer
+  );
+
+//
+// EFI Component Name Functions
+//
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 4646 or ISO 639-2 language code format.
+
+  @param  DriverName[out]       A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+CirrusLogic5430ComponentNameGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **DriverName
+  );
+
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  ControllerHandle[in]  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+
+  @param  ChildHandle[in]       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 4646 or ISO 639-2 language code format.
+
+  @param  ControllerName[out]   A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                controller specified by ControllerHandle and
+                                ChildHandle in the language specified by
+                                Language from the point of view of the driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+
+  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+CirrusLogic5430ComponentNameGetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
+  IN  EFI_HANDLE                                      ControllerHandle,
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
+  IN  CHAR8                                           *Language,
+  OUT CHAR16                                          **ControllerName
+  );
+
+
+//
+// Local Function Prototypes
+//
+VOID
+InitializeGraphicsMode (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
+  CIRRUS_LOGIC_5430_VIDEO_MODES   *ModeData
+  );
+
+VOID
+SetPaletteColor (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
+  UINTN                           Index,
+  UINT8                           Red,
+  UINT8                           Green,
+  UINT8                           Blue
+  );
+
+VOID
+SetDefaultPalette (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
+  );
+
+VOID
+DrawLogo (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
+  UINTN                           ScreenWidth,
+  UINTN                           ScreenHeight
+  );
+
+VOID
+outb (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
+  UINTN                           Address,
+  UINT8                           Data
+  );
+
+VOID
+outw (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
+  UINTN                           Address,
+  UINT16                          Data
+  );
+
+UINT8
+inb (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
+  UINTN                           Address
+  );
+
+UINT16
+inw (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
+  UINTN                           Address
+  );
+
+EFI_STATUS
+CirrusLogic5430VideoModeSetup (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
+  );
+
+#endif
diff --git a/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf
new file mode 100644
index 0000000000..3e8b7b087f
--- /dev/null
+++ b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf
@@ -0,0 +1,84 @@
+## @file
+# Component description file for CirrusLogic5430 module
+#
+# Cirrus Logic 5430 Controller Driver.This driver is a sample implementation
+#  of the UGA Draw Protocol for the Cirrus Logic 5430 family of PCI video controllers.
+#  This driver is only usable in the EFI pre-boot environment. This sample is
+#  intended to show how the UGA Draw Protocol is able to function. The UGA I/O
+#  Protocol is not implemented in this sample. A fully compliant EFI UGA driver
+#  requires both the UGA Draw and the UGA I/O Protocol. Please refer to Microsoft's
+#  documentation on UGA for details on how to write a UGA driver that is able
+#  to function both in the EFI pre-boot environment and from the OS runtime.
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = CirrusLogic5430Dxe
+  FILE_GUID                      = 555F76EA-785F-40d7-9174-153C43636C68
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = InitializeCirrusLogic5430
+
+  PCI_VENDOR_ID  = 0x1013
+  PCI_DEVICE_ID  = 0x00A8
+  PCI_CLASS_CODE = 0x030000
+  PCI_REVISION   = 0x00
+  PCI_COMPRESS   = TRUE
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+#  DRIVER_BINDING                =  gCirrusLogic5430DriverBinding
+#  COMPONENT_NAME                =  gCirrusLogic5430ComponentName
+#
+
+[Sources]
+  ComponentName.c
+  DriverSupportedEfiVersion.c
+  CirrusLogic5430UgaDraw.c
+  CirrusLogic5430GraphicsOutput.c
+  CirrusLogic5430.c
+  CirrusLogic5430.h
+  Edid.c
+  CirrusLogic5430I2c.h
+  CirrusLogic5430I2c.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OptionRomPkg/OptionRomPkg.dec
+
+[LibraryClasses]
+  UefiBootServicesTableLib
+  MemoryAllocationLib
+  UefiLib
+  UefiDriverEntryPoint
+  DebugLib
+  BaseMemoryLib
+  DevicePathLib
+  TimerLib
+
+[Protocols]
+  gEfiDriverSupportedEfiVersionProtocolGuid     # PROTOCOL ALWAYS_PRODUCED
+  gEfiUgaDrawProtocolGuid                       # PROTOCOL BY_START
+  gEfiGraphicsOutputProtocolGuid                # PROTOCOL BY_START
+  gEfiEdidDiscoveredProtocolGuid                # PROTOCOL BY_START
+  gEfiEdidActiveProtocolGuid                    # PROTOCOL BY_START
+  gEfiDevicePathProtocolGuid                    # PROTOCOL BY_START
+  gEfiPciIoProtocolGuid                         # PROTOCOL TO_START
+  gEfiEdidOverrideProtocolGuid                  # PROTOCOL TO_START
+
+
+[FeaturePcd]
+  gOptionRomPkgTokenSpaceGuid.PcdSupportGop
+  gOptionRomPkgTokenSpaceGuid.PcdSupportUga
+
+[Pcd]
+  gOptionRomPkgTokenSpaceGuid.PcdDriverSupportedEfiVersion
diff --git a/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430GraphicsOutput.c b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430GraphicsOutput.c
new file mode 100644
index 0000000000..b74d84b131
--- /dev/null
+++ b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430GraphicsOutput.c
@@ -0,0 +1,556 @@
+/** @file
+Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  UefiCirrusLogic5430GraphicsOutput.c
+
+Abstract:
+
+  This file produces the graphics abstration of Graphics Output Protocol. It is called by
+  CirrusLogic5430.c file which deals with the EFI 1.1 driver model.
+  This file just does graphics.
+
+**/
+#include "CirrusLogic5430.h"
+#include <IndustryStandard/Acpi.h>
+
+
+STATIC
+VOID
+CirrusLogic5430CompleteModeInfo (
+  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info
+  )
+{
+  Info->Version = 0;
+  Info->PixelFormat = PixelBitMask;
+  Info->PixelInformation.RedMask = PIXEL_RED_MASK;
+  Info->PixelInformation.GreenMask = PIXEL_GREEN_MASK;
+  Info->PixelInformation.BlueMask = PIXEL_BLUE_MASK;
+  Info->PixelInformation.ReservedMask = 0;
+  Info->PixelsPerScanLine = Info->HorizontalResolution;
+}
+
+
+STATIC
+EFI_STATUS
+CirrusLogic5430CompleteModeData (
+  IN  CIRRUS_LOGIC_5430_PRIVATE_DATA    *Private,
+  OUT EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode
+  )
+{
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info;
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     *FrameBufDesc;
+
+  Info = Mode->Info;
+  CirrusLogic5430CompleteModeInfo (Info);
+
+  Private->PciIo->GetBarAttributes (
+                        Private->PciIo,
+                        0,
+                        NULL,
+                        (VOID**) &FrameBufDesc
+                        );
+
+  Mode->FrameBufferBase = FrameBufDesc->AddrRangeMin;
+  Mode->FrameBufferSize = Info->HorizontalResolution * Info->VerticalResolution;
+
+  return EFI_SUCCESS;
+}
+
+
+//
+// Graphics Output Protocol Member Functions
+//
+EFI_STATUS
+EFIAPI
+CirrusLogic5430GraphicsOutputQueryMode (
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,
+  IN  UINT32                                ModeNumber,
+  OUT UINTN                                 *SizeOfInfo,
+  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  **Info
+  )
+/*++
+
+Routine Description:
+
+  Graphics Output protocol interface to query video mode
+
+  Arguments:
+    This                  - Protocol instance pointer.
+    ModeNumber            - The mode number to return information on.
+    Info                  - Caller allocated buffer that returns information about ModeNumber.
+    SizeOfInfo            - A pointer to the size, in bytes, of the Info buffer.
+
+  Returns:
+    EFI_SUCCESS           - Mode information returned.
+    EFI_BUFFER_TOO_SMALL  - The Info buffer was too small.
+    EFI_DEVICE_ERROR      - A hardware error occurred trying to retrieve the video mode.
+    EFI_NOT_STARTED       - Video display is not initialized. Call SetMode ()
+    EFI_INVALID_PARAMETER - One of the input args was NULL.
+
+--*/
+{
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;
+
+  Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
+
+  if (Private->HardwareNeedsStarting) {
+    return EFI_NOT_STARTED;
+  }
+
+  if (Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
+  if (*Info == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
+
+  (*Info)->HorizontalResolution = Private->ModeData[ModeNumber].HorizontalResolution;
+  (*Info)->VerticalResolution   = Private->ModeData[ModeNumber].VerticalResolution;
+  CirrusLogic5430CompleteModeInfo (*Info);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+CirrusLogic5430GraphicsOutputSetMode (
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+  IN  UINT32                       ModeNumber
+  )
+/*++
+
+Routine Description:
+
+  Graphics Output protocol interface to set video mode
+
+  Arguments:
+    This             - Protocol instance pointer.
+    ModeNumber       - The mode number to be set.
+
+  Returns:
+    EFI_SUCCESS      - Graphics mode was changed.
+    EFI_DEVICE_ERROR - The device had an error and could not complete the request.
+    EFI_UNSUPPORTED  - ModeNumber is not supported by this device.
+
+--*/
+{
+  CIRRUS_LOGIC_5430_PRIVATE_DATA    *Private;
+  CIRRUS_LOGIC_5430_MODE_DATA       *ModeData;
+
+  Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
+
+  if (ModeNumber >= This->Mode->MaxMode) {
+    return EFI_UNSUPPORTED;
+  }
+
+  ModeData = &Private->ModeData[ModeNumber];
+
+  if (Private->LineBuffer) {
+    gBS->FreePool (Private->LineBuffer);
+  }
+
+  Private->LineBuffer = NULL;
+  Private->LineBuffer = AllocatePool (ModeData->HorizontalResolution);
+  if (Private->LineBuffer == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  InitializeGraphicsMode (Private, &CirrusLogic5430VideoModes[ModeData->ModeNumber]);
+
+  This->Mode->Mode = ModeNumber;
+  This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;
+  This->Mode->Info->VerticalResolution = ModeData->VerticalResolution;
+  This->Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
+
+  CirrusLogic5430CompleteModeData (Private, This->Mode);
+
+  Private->HardwareNeedsStarting  = FALSE;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+CirrusLogic5430GraphicsOutputBlt (
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer, OPTIONAL
+  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION     BltOperation,
+  IN  UINTN                                 SourceX,
+  IN  UINTN                                 SourceY,
+  IN  UINTN                                 DestinationX,
+  IN  UINTN                                 DestinationY,
+  IN  UINTN                                 Width,
+  IN  UINTN                                 Height,
+  IN  UINTN                                 Delta
+  )
+/*++
+
+Routine Description:
+
+  Graphics Output protocol instance to block transfer for CirrusLogic device
+
+Arguments:
+
+  This          - Pointer to Graphics Output protocol instance
+  BltBuffer     - The data to transfer to screen
+  BltOperation  - The operation to perform
+  SourceX       - The X coordinate of the source for BltOperation
+  SourceY       - The Y coordinate of the source for BltOperation
+  DestinationX  - The X coordinate of the destination for BltOperation
+  DestinationY  - The Y coordinate of the destination for BltOperation
+  Width         - The width of a rectangle in the blt rectangle in pixels
+  Height        - The height of a rectangle in the blt rectangle in pixels
+  Delta         - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
+                  If a Delta of 0 is used, the entire BltBuffer will be operated on.
+                  If a subrectangle of the BltBuffer is used, then Delta represents
+                  the number of bytes in a row of the BltBuffer.
+
+Returns:
+
+  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  EFI_SUCCESS - Blt operation success
+
+--*/
+{
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;
+  EFI_TPL                         OriginalTPL;
+  UINTN                           DstY;
+  UINTN                           SrcY;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *Blt;
+  UINTN                           X;
+  UINT8                           Pixel;
+  UINT32                          WidePixel;
+  UINTN                           ScreenWidth;
+  UINTN                           Offset;
+  UINTN                           SourceOffset;
+  UINT32                          CurrentMode;
+
+  Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
+
+  if ((UINT32)BltOperation >= EfiGraphicsOutputBltOperationMax) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width == 0 || Height == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // If Delta is zero, then the entire BltBuffer is being used, so Delta
+  // is the number of bytes in each row of BltBuffer.  Since BltBuffer is Width pixels size,
+  // the number of bytes in each row can be computed.
+  //
+  if (Delta == 0) {
+    Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+  }
+
+  //
+  // We need to fill the Virtual Screen buffer with the blt data.
+  // The virtual screen is upside down, as the first row is the bootom row of
+  // the image.
+  //
+
+  CurrentMode = This->Mode->Mode;
+  //
+  // Make sure the SourceX, SourceY, DestinationX, DestinationY, Width, and Height parameters
+  // are valid for the operation and the current screen geometry.
+  //
+  if (BltOperation == EfiBltVideoToBltBuffer) {
+    //
+    // Video to BltBuffer: Source is Video, destination is BltBuffer
+    //
+    if (SourceY + Height > Private->ModeData[CurrentMode].VerticalResolution) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    if (SourceX + Width > Private->ModeData[CurrentMode].HorizontalResolution) {
+      return EFI_INVALID_PARAMETER;
+    }
+  } else {
+    //
+    // BltBuffer to Video: Source is BltBuffer, destination is Video
+    //
+    if (DestinationY + Height > Private->ModeData[CurrentMode].VerticalResolution) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    if (DestinationX + Width > Private->ModeData[CurrentMode].HorizontalResolution) {
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+  //
+  // We have to raise to TPL Notify, so we make an atomic write the frame buffer.
+  // We would not want a timer based event (Cursor, ...) to come in while we are
+  // doing this operation.
+  //
+  OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);
+
+  switch (BltOperation) {
+  case EfiBltVideoToBltBuffer:
+    //
+    // Video to BltBuffer: Source is Video, destination is BltBuffer
+    //
+    for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) {
+
+      Offset = (SrcY * Private->ModeData[CurrentMode].HorizontalResolution) + SourceX;
+      if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {
+        Private->PciIo->Mem.Read (
+                              Private->PciIo,
+                              EfiPciIoWidthUint32,
+                              0,
+                              Offset,
+                              Width >> 2,
+                              Private->LineBuffer
+                              );
+      } else {
+        Private->PciIo->Mem.Read (
+                              Private->PciIo,
+                              EfiPciIoWidthUint8,
+                              0,
+                              Offset,
+                              Width,
+                              Private->LineBuffer
+                              );
+      }
+
+      for (X = 0; X < Width; X++) {
+        Blt         = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+
+        Blt->Red    = PIXEL_TO_RED_BYTE (Private->LineBuffer[X]);
+        Blt->Green  = PIXEL_TO_GREEN_BYTE (Private->LineBuffer[X]);
+        Blt->Blue   = PIXEL_TO_BLUE_BYTE (Private->LineBuffer[X]);
+      }
+    }
+    break;
+
+  case EfiBltVideoToVideo:
+    //
+    // Perform hardware acceleration for Video to Video operations
+    //
+    ScreenWidth   = Private->ModeData[CurrentMode].HorizontalResolution;
+    SourceOffset  = (SourceY * Private->ModeData[CurrentMode].HorizontalResolution) + (SourceX);
+    Offset        = (DestinationY * Private->ModeData[CurrentMode].HorizontalResolution) + (DestinationX);
+
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0000);
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0010);
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0012);
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0014);
+
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0001);
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0011);
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0013);
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0015);
+
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Width << 8) & 0xff00) | 0x20));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Width & 0xff00) | 0x21));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Height << 8) & 0xff00) | 0x22));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Height & 0xff00) | 0x23));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8) & 0xff00) | 0x24));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth & 0xff00) | 0x25));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8) & 0xff00) | 0x26));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth & 0xff00) | 0x27));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) << 8) & 0xff00) | 0x28));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 0) & 0xff00) | 0x29));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 8) & 0xff00) | 0x2a));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) << 8) & 0xff00) | 0x2c));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >> 0) & 0xff00) | 0x2d));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >> 8) & 0xff00) | 0x2e));
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x002f);
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0030);
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0d32);
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0033);
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0034);
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0035);
+
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0231);
+
+    outb (Private, GRAPH_ADDRESS_REGISTER, 0x31);
+    while ((inb (Private, GRAPH_DATA_REGISTER) & 0x01) == 0x01)
+      ;
+    break;
+
+  case EfiBltVideoFill:
+    Blt       = BltBuffer;
+    Pixel     = RGB_BYTES_TO_PIXEL (Blt->Red, Blt->Green, Blt->Blue);
+    WidePixel = (Pixel << 8) | Pixel;
+    WidePixel = (WidePixel << 16) | WidePixel;
+
+    if (DestinationX == 0 && Width == Private->ModeData[CurrentMode].HorizontalResolution) {
+      Offset = DestinationY * Private->ModeData[CurrentMode].HorizontalResolution;
+      if (((Offset & 0x03) == 0) && (((Width * Height) & 0x03) == 0)) {
+        Private->PciIo->Mem.Write (
+                              Private->PciIo,
+                              EfiPciIoWidthFillUint32,
+                              0,
+                              Offset,
+                              (Width * Height) >> 2,
+                              &WidePixel
+                              );
+      } else {
+        Private->PciIo->Mem.Write (
+                              Private->PciIo,
+                              EfiPciIoWidthFillUint8,
+                              0,
+                              Offset,
+                              Width * Height,
+                              &Pixel
+                              );
+      }
+    } else {
+      for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {
+        Offset = (DstY * Private->ModeData[CurrentMode].HorizontalResolution) + DestinationX;
+        if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {
+          Private->PciIo->Mem.Write (
+                                Private->PciIo,
+                                EfiPciIoWidthFillUint32,
+                                0,
+                                Offset,
+                                Width >> 2,
+                                &WidePixel
+                                );
+        } else {
+          Private->PciIo->Mem.Write (
+                                Private->PciIo,
+                                EfiPciIoWidthFillUint8,
+                                0,
+                                Offset,
+                                Width,
+                                &Pixel
+                                );
+        }
+      }
+    }
+    break;
+
+  case EfiBltBufferToVideo:
+    for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {
+
+      for (X = 0; X < Width; X++) {
+        Blt =
+          (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) (
+              (UINT8 *) BltBuffer +
+              (SrcY * Delta) +
+              ((SourceX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))
+            );
+        Private->LineBuffer[X]  =
+          RGB_BYTES_TO_PIXEL (Blt->Red, Blt->Green, Blt->Blue);
+      }
+
+      Offset = (DstY * Private->ModeData[CurrentMode].HorizontalResolution) + DestinationX;
+
+      if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {
+        Private->PciIo->Mem.Write (
+                              Private->PciIo,
+                              EfiPciIoWidthUint32,
+                              0,
+                              Offset,
+                              Width >> 2,
+                              Private->LineBuffer
+                              );
+      } else {
+        Private->PciIo->Mem.Write (
+                              Private->PciIo,
+                              EfiPciIoWidthUint8,
+                              0,
+                              Offset,
+                              Width,
+                              Private->LineBuffer
+                              );
+      }
+    }
+    break;
+  default:
+    ASSERT (FALSE);
+  }
+
+  gBS->RestoreTPL (OriginalTPL);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CirrusLogic5430GraphicsOutputConstructor (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
+  )
+{
+  EFI_STATUS                   Status;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
+
+
+  GraphicsOutput            = &Private->GraphicsOutput;
+  GraphicsOutput->QueryMode = CirrusLogic5430GraphicsOutputQueryMode;
+  GraphicsOutput->SetMode   = CirrusLogic5430GraphicsOutputSetMode;
+  GraphicsOutput->Blt       = CirrusLogic5430GraphicsOutputBlt;
+
+  //
+  // Initialize the private data
+  //
+  Status = gBS->AllocatePool (
+                  EfiBootServicesData,
+                  sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE),
+                  (VOID **) &Private->GraphicsOutput.Mode
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  Status = gBS->AllocatePool (
+                  EfiBootServicesData,
+                  sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),
+                  (VOID **) &Private->GraphicsOutput.Mode->Info
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  Private->GraphicsOutput.Mode->MaxMode = (UINT32) Private->MaxMode;
+  Private->GraphicsOutput.Mode->Mode    = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;
+  Private->HardwareNeedsStarting        = TRUE;
+  Private->LineBuffer                   = NULL;
+
+  //
+  // Initialize the hardware
+  //
+  GraphicsOutput->SetMode (GraphicsOutput, 0);
+  ASSERT (Private->GraphicsOutput.Mode->Mode < CIRRUS_LOGIC_5430_MODE_COUNT);
+  DrawLogo (
+    Private,
+    Private->ModeData[Private->GraphicsOutput.Mode->Mode].HorizontalResolution,
+    Private->ModeData[Private->GraphicsOutput.Mode->Mode].VerticalResolution
+    );
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CirrusLogic5430GraphicsOutputDestructor (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+  None
+
+--*/
+{
+  if (Private->GraphicsOutput.Mode != NULL) {
+    if (Private->GraphicsOutput.Mode->Info != NULL) {
+      gBS->FreePool (Private->GraphicsOutput.Mode->Info);
+    }
+    gBS->FreePool (Private->GraphicsOutput.Mode);
+  }
+
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.c b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.c
new file mode 100644
index 0000000000..0cec8670b7
--- /dev/null
+++ b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.c
@@ -0,0 +1,427 @@
+/** @file
+  I2C Bus implementation upon CirrusLogic.
+
+  Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CirrusLogic5430.h"
+#include "CirrusLogic5430I2c.h"
+
+#define SEQ_ADDRESS_REGISTER    0x3c4
+#define SEQ_DATA_REGISTER       0x3c5
+
+#define I2C_CONTROL             0x08
+#define I2CDAT_IN               7
+#define I2CCLK_IN               2
+#define I2CDAT_OUT              1
+#define I2CCLK_OUT              0
+
+#define I2C_BUS_SPEED           100  //100kbps
+
+/**
+  PCI I/O byte write function.
+
+  @param  PciIo        The pointer to PCI_IO_PROTOCOL.
+  @param  Address      The bit map of I2C Data or I2C Clock pins.
+  @param  Data         The date to write.
+
+**/
+VOID
+I2cOutb (
+  EFI_PCI_IO_PROTOCOL    *PciIo,
+  UINTN                  Address,
+  UINT8                  Data
+  )
+{
+  PciIo->Io.Write (
+             PciIo,
+             EfiPciIoWidthUint8,
+             EFI_PCI_IO_PASS_THROUGH_BAR,
+             Address,
+             1,
+             &Data
+             );
+}
+/**
+  PCI I/O byte read function.
+
+  @param  PciIo        The pointer to PCI_IO_PROTOCOL.
+  @param  Address      The bit map of I2C Data or I2C Clock pins.
+
+  return byte value read from PCI I/O space.
+
+**/
+UINT8
+I2cInb (
+  EFI_PCI_IO_PROTOCOL    *PciIo,
+  UINTN                  Address
+  )
+{
+  UINT8 Data;
+
+  PciIo->Io.Read (
+             PciIo,
+             EfiPciIoWidthUint8,
+             EFI_PCI_IO_PASS_THROUGH_BAR,
+             Address,
+             1,
+             &Data
+             );
+  return Data;
+}
+
+/**
+  Read status of I2C Data and I2C Clock Pins.
+
+  @param  PciIo        The pointer to PCI_IO_PROTOCOL.
+  @param  Blt          The bit map of I2C Data or I2C Clock pins.
+
+  @retval 0            Low on I2C Data or I2C Clock Pin.
+  @retval 1            High on I2C Data or I2C Clock Pin.
+
+**/
+UINT8
+I2cPinRead (
+  EFI_PCI_IO_PROTOCOL    *PciIo,
+  UINT8                  Bit
+  )
+{
+  I2cOutb (PciIo, SEQ_ADDRESS_REGISTER, I2C_CONTROL);
+  return (UINT8) ((I2cInb (PciIo, SEQ_DATA_REGISTER) >> Bit ) & 0xfe);
+}
+
+
+/**
+  Set/Clear I2C Data and I2C Clock Pins.
+
+  @param  PciIo              The pointer to PCI_IO_PROTOCOL.
+  @param  Blt                The bit map to controller I2C Data or I2C Clock pins.
+  @param  Value              1 or 0 stands for Set or Clear I2C Data and I2C Clock Pins.
+
+**/
+VOID
+I2cPinWrite (
+  EFI_PCI_IO_PROTOCOL    *PciIo,
+  UINT8                  Bit,
+  UINT8                  Value
+  )
+{
+  UINT8        Byte;
+  I2cOutb (PciIo, SEQ_ADDRESS_REGISTER, I2C_CONTROL);
+  Byte = (UINT8) (I2cInb (PciIo, SEQ_DATA_REGISTER) & (UINT8) ~(1 << Bit)) ;
+  Byte = (UINT8) (Byte | ((Value & 0x01) << Bit));
+  I2cOutb (PciIo, SEQ_DATA_REGISTER, (UINT8) (Byte | 0x40));
+  return;
+}
+
+/**
+  Read/write delay acoording to I2C Bus Speed.
+
+**/
+VOID
+I2cDelay (
+  VOID
+  )
+{
+  MicroSecondDelay (1000 / I2C_BUS_SPEED);
+}
+
+/**
+  Write a 8-bit data onto I2C Data Pin.
+
+  @param  PciIo              The pointer to PCI_IO_PROTOCOL.
+  @param  Data               The byte data to write.
+
+**/
+VOID
+I2cSendByte (
+  EFI_PCI_IO_PROTOCOL    *PciIo,
+  UINT8                  Data
+  )
+{
+  UINTN                  Index;
+  //
+  // Send byte data onto I2C Bus
+  //
+  for (Index = 0; Index < 8; Index --) {
+    I2cPinWrite (PciIo, I2CDAT_OUT, (UINT8) (Data >> (7 - Index)));
+    I2cPinWrite (PciIo, I2CCLK_OUT, 1);
+    I2cDelay ();
+    I2cPinWrite (PciIo, I2CCLK_OUT, 0);
+  }
+}
+
+/**
+  Read a 8-bit data from I2C Data Pin.
+
+  @param  PciIo              The pointer to PCI_IO_PROTOCOL.
+
+  Return the byte data read from I2C Data Pin.
+**/
+UINT8
+I2cReceiveByte (
+  EFI_PCI_IO_PROTOCOL    *PciIo
+  )
+{
+  UINT8          Data;
+  UINTN          Index;
+
+  Data = 0;
+  //
+  // Read byte data from I2C Bus
+  //
+  for (Index = 0; Index < 8; Index --) {
+    I2cPinWrite (PciIo, I2CCLK_OUT, 1);
+    I2cDelay ();
+    Data = (UINT8) (Data << 1);
+    Data = (UINT8) (Data | I2cPinRead (PciIo, I2CDAT_IN));
+    I2cPinWrite (PciIo, I2CCLK_OUT, 0);
+  }
+
+  return Data;
+}
+
+/**
+  Receive an ACK signal from I2C Bus.
+
+  @param  PciIo              The pointer to PCI_IO_PROTOCOL.
+
+**/
+BOOLEAN
+I2cWaitAck (
+  EFI_PCI_IO_PROTOCOL    *PciIo
+  )
+{
+  //
+  // Wait for ACK signal
+  //
+  I2cPinWrite (PciIo, I2CDAT_OUT, 1);
+  I2cPinWrite (PciIo, I2CCLK_OUT, 1);
+  I2cDelay ();
+  if (I2cPinRead (PciIo, I2CDAT_IN) == 0) {
+    I2cPinWrite (PciIo, I2CDAT_OUT, 1);
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
+
+/**
+  Send an ACK signal onto I2C Bus.
+
+  @param  PciIo              The pointer to PCI_IO_PROTOCOL.
+
+**/
+VOID
+I2cSendAck (
+  EFI_PCI_IO_PROTOCOL    *PciIo
+  )
+{
+  I2cPinWrite (PciIo, I2CCLK_OUT, 1);
+  I2cPinWrite (PciIo, I2CDAT_OUT, 1);
+  I2cPinWrite (PciIo, I2CDAT_OUT, 0);
+  I2cPinWrite (PciIo, I2CCLK_OUT, 0);
+}
+
+/**
+  Start a I2C transfer on I2C Bus.
+
+  @param  PciIo              The pointer to PCI_IO_PROTOCOL.
+
+**/
+VOID
+I2cStart (
+  EFI_PCI_IO_PROTOCOL    *PciIo
+  )
+{
+  //
+  // Init CLK and DAT pins
+  //
+  I2cPinWrite (PciIo, I2CCLK_OUT, 1);
+  I2cPinWrite (PciIo, I2CDAT_OUT, 1);
+  //
+  // Start a I2C transfer, set SDA low from high, when SCL is high
+  //
+  I2cPinWrite (PciIo, I2CDAT_OUT, 0);
+  I2cPinWrite (PciIo, I2CCLK_OUT, 0);
+}
+
+/**
+  Stop a I2C transfer on I2C Bus.
+
+  @param  PciIo              The pointer to PCI_IO_PROTOCOL.
+
+**/
+VOID
+I2cStop (
+  EFI_PCI_IO_PROTOCOL    *PciIo
+  )
+{
+  //
+  // Stop a I2C transfer, set SDA high from low, when SCL is high
+  //
+  I2cPinWrite (PciIo, I2CDAT_OUT, 0);
+  I2cPinWrite (PciIo, I2CCLK_OUT, 1);
+  I2cPinWrite (PciIo, I2CDAT_OUT, 1);
+}
+
+/**
+  Read one byte data on I2C Bus.
+
+  Read one byte data from the slave device connectet to I2C Bus.
+  If Data is NULL, then ASSERT().
+
+  @param  PciIo              The pointer to PCI_IO_PROTOCOL.
+  @param  DeviceAddress      Slave device's address.
+  @param  RegisterAddress    The register address on slave device.
+  @param  Data               The pointer to returned data if EFI_SUCCESS returned.
+
+  @retval EFI_DEVICE_ERROR
+  @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EFIAPI
+I2cReadByte (
+  EFI_PCI_IO_PROTOCOL    *PciIo,
+  UINT8                  DeviceAddress,
+  UINT8                  RegisterAddress,
+  UINT8                  *Data
+  )
+{
+  ASSERT (Data != NULL);
+
+  //
+  // Start I2C transfer
+  //
+  I2cStart (PciIo);
+
+  //
+  // Send slave address with enabling write flag
+  //
+  I2cSendByte (PciIo, (UINT8) (DeviceAddress & 0xfe));
+
+  //
+  // Wait for ACK signal
+  //
+  if (I2cWaitAck (PciIo) == FALSE) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Send register address
+  //
+  I2cSendByte (PciIo, RegisterAddress);
+
+  //
+  // Wait for ACK signal
+  //
+  if (I2cWaitAck (PciIo) == FALSE) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Send slave address with enabling read flag
+  //
+  I2cSendByte (PciIo, (UINT8) (DeviceAddress | 0x01));
+
+  //
+  // Wait for ACK signal
+  //
+  if (I2cWaitAck (PciIo) == FALSE) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Read byte data from I2C Bus
+  //
+  *Data = I2cReceiveByte (PciIo);
+
+  //
+  // Send ACK signal onto I2C Bus
+  //
+  I2cSendAck (PciIo);
+
+  //
+  // Stop a I2C transfer
+  //
+  I2cStop (PciIo);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Write one byte data onto I2C Bus.
+
+  Write one byte data to the slave device connectet to I2C Bus.
+  If Data is NULL, then ASSERT().
+
+  @param  PciIo              The pointer to PCI_IO_PROTOCOL.
+  @param  DeviceAddress      Slave device's address.
+  @param  RegisterAddress    The register address on slave device.
+  @param  Data               The pointer to write data.
+
+  @retval EFI_DEVICE_ERROR
+  @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EFIAPI
+I2cWriteByte (
+  EFI_PCI_IO_PROTOCOL    *PciIo,
+  UINT8                  DeviceAddress,
+  UINT8                  RegisterAddress,
+  UINT8                  *Data
+  )
+{
+  ASSERT (Data != NULL);
+
+  I2cStart (PciIo);
+  //
+  // Send slave address with enabling write flag
+  //
+  I2cSendByte (PciIo, (UINT8) (DeviceAddress & 0xfe));
+
+  //
+  // Wait for ACK signal
+  //
+  if (I2cWaitAck (PciIo) == FALSE) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Send register address
+  //
+  I2cSendByte (PciIo, RegisterAddress);
+
+  //
+  // Wait for ACK signal
+  //
+  if (I2cWaitAck (PciIo) == FALSE) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Send byte data onto I2C Bus
+  //
+  I2cSendByte (PciIo, *Data);
+
+  //
+  // Wait for ACK signal
+  //
+  if (I2cWaitAck (PciIo) == FALSE) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Stop a I2C transfer
+  //
+  I2cStop (PciIo);
+
+  return EFI_SUCCESS;
+}
+
+
+
diff --git a/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.h b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.h
new file mode 100644
index 0000000000..505575cc99
--- /dev/null
+++ b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.h
@@ -0,0 +1,62 @@
+/** @file
+  I2c Bus byte read/write functions.
+
+  Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _CIRRUS_LOGIC_I2C_H_
+#define _CIRRUS_LOGIC_I2C_H_
+
+#include <Protocol/PciIo.h>
+
+/**
+  Read one byte data on I2C Bus.
+
+  Read one byte data from the slave device connectet to I2C Bus.
+  If Data is NULL, then ASSERT().
+
+  @param  PciIo              The pointer to PCI_IO_PROTOCOL.
+  @param  DeviceAddress      Slave device's address.
+  @param  RegisterAddress    The register address on slave device.
+  @param  Data               The pointer to returned data if EFI_SUCCESS returned.
+
+  @retval EFI_DEVICE_ERROR
+  @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EFIAPI
+I2cReadByte (
+  EFI_PCI_IO_PROTOCOL    *PciIo,
+  UINT8                  DeviceAddress,
+  UINT8                  RegisterAddress,
+  UINT8                  *Data
+  );
+
+/**
+  Write one byte data onto I2C Bus.
+
+  Write one byte data to the slave device connectet to I2C Bus.
+  If Data is NULL, then ASSERT().
+
+  @param  PciIo              The pointer to PCI_IO_PROTOCOL.
+  @param  DeviceAddress      Slave device's address.
+  @param  RegisterAddress    The register address on slave device.
+  @param  Data               The pointer to write data.
+
+  @retval EFI_DEVICE_ERROR
+  @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EFIAPI
+I2cWriteByte (
+  EFI_PCI_IO_PROTOCOL    *PciIo,
+  UINT8                  DeviceAddress,
+  UINT8                  RegisterAddress,
+  UINT8                  *Data
+  );
+
+#endif
diff --git a/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430UgaDraw.c b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430UgaDraw.c
new file mode 100644
index 0000000000..bdcbd3450c
--- /dev/null
+++ b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430UgaDraw.c
@@ -0,0 +1,412 @@
+/** @file
+  This file produces the graphics abstration of UGA Draw. It is called by
+  CirrusLogic5430.c file which deals with the EFI 1.1 driver model.
+  This file just does graphics.
+
+  Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CirrusLogic5430.h"
+
+//
+// UGA Draw Protocol Member Functions
+//
+EFI_STATUS
+EFIAPI
+CirrusLogic5430UgaDrawGetMode (
+  IN  EFI_UGA_DRAW_PROTOCOL *This,
+  OUT UINT32                *HorizontalResolution,
+  OUT UINT32                *VerticalResolution,
+  OUT UINT32                *ColorDepth,
+  OUT UINT32                *RefreshRate
+  )
+{
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;
+
+  Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This);
+
+  if (Private->HardwareNeedsStarting) {
+    return EFI_NOT_STARTED;
+  }
+
+  if ((HorizontalResolution == NULL) ||
+      (VerticalResolution == NULL)   ||
+      (ColorDepth == NULL)           ||
+      (RefreshRate == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *HorizontalResolution = Private->ModeData[Private->CurrentMode].HorizontalResolution;
+  *VerticalResolution   = Private->ModeData[Private->CurrentMode].VerticalResolution;
+  *ColorDepth           = Private->ModeData[Private->CurrentMode].ColorDepth;
+  *RefreshRate          = Private->ModeData[Private->CurrentMode].RefreshRate;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+CirrusLogic5430UgaDrawSetMode (
+  IN  EFI_UGA_DRAW_PROTOCOL *This,
+  IN  UINT32                HorizontalResolution,
+  IN  UINT32                VerticalResolution,
+  IN  UINT32                ColorDepth,
+  IN  UINT32                RefreshRate
+  )
+{
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;
+  UINTN                           Index;
+
+  Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This);
+
+  for (Index = 0; Index < Private->MaxMode; Index++) {
+
+    if (HorizontalResolution != Private->ModeData[Index].HorizontalResolution) {
+      continue;
+    }
+
+    if (VerticalResolution != Private->ModeData[Index].VerticalResolution) {
+      continue;
+    }
+
+    if (ColorDepth != Private->ModeData[Index].ColorDepth) {
+      continue;
+    }
+
+    if (RefreshRate != Private->ModeData[Index].RefreshRate) {
+      continue;
+    }
+
+    if (Private->LineBuffer) {
+      gBS->FreePool (Private->LineBuffer);
+    }
+
+    Private->LineBuffer = NULL;
+    Private->LineBuffer = AllocatePool (HorizontalResolution);
+    if (Private->LineBuffer == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    InitializeGraphicsMode (Private, &CirrusLogic5430VideoModes[Private->ModeData[Index].ModeNumber]);
+
+    Private->CurrentMode            = Index;
+
+    Private->HardwareNeedsStarting  = FALSE;
+
+    return EFI_SUCCESS;
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+EFIAPI
+CirrusLogic5430UgaDrawBlt (
+  IN  EFI_UGA_DRAW_PROTOCOL     *This,
+  IN  EFI_UGA_PIXEL             *BltBuffer, OPTIONAL
+  IN  EFI_UGA_BLT_OPERATION     BltOperation,
+  IN  UINTN                     SourceX,
+  IN  UINTN                     SourceY,
+  IN  UINTN                     DestinationX,
+  IN  UINTN                     DestinationY,
+  IN  UINTN                     Width,
+  IN  UINTN                     Height,
+  IN  UINTN                     Delta
+  )
+{
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;
+  EFI_TPL                         OriginalTPL;
+  UINTN                           DstY;
+  UINTN                           SrcY;
+  EFI_UGA_PIXEL                   *Blt;
+  UINTN                           X;
+  UINT8                           Pixel;
+  UINT32                          WidePixel;
+  UINTN                           ScreenWidth;
+  UINTN                           Offset;
+  UINTN                           SourceOffset;
+
+  Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This);
+
+  if ((UINT32)BltOperation >= EfiUgaBltMax) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width == 0 || Height == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // If Delta is zero, then the entire BltBuffer is being used, so Delta
+  // is the number of bytes in each row of BltBuffer.  Since BltBuffer is Width pixels size,
+  // the number of bytes in each row can be computed.
+  //
+  if (Delta == 0) {
+    Delta = Width * sizeof (EFI_UGA_PIXEL);
+  }
+
+  //
+  // We need to fill the Virtual Screen buffer with the blt data.
+  // The virtual screen is upside down, as the first row is the bootom row of
+  // the image.
+  //
+
+  //
+  // Make sure the SourceX, SourceY, DestinationX, DestinationY, Width, and Height parameters
+  // are valid for the operation and the current screen geometry.
+  //
+  if (BltOperation == EfiUgaVideoToBltBuffer) {
+    //
+    // Video to BltBuffer: Source is Video, destination is BltBuffer
+    //
+    if (SourceY + Height > Private->ModeData[Private->CurrentMode].VerticalResolution) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    if (SourceX + Width > Private->ModeData[Private->CurrentMode].HorizontalResolution) {
+      return EFI_INVALID_PARAMETER;
+    }
+  } else {
+    //
+    // BltBuffer to Video: Source is BltBuffer, destination is Video
+    //
+    if (DestinationY + Height > Private->ModeData[Private->CurrentMode].VerticalResolution) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    if (DestinationX + Width > Private->ModeData[Private->CurrentMode].HorizontalResolution) {
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+  //
+  // We have to raise to TPL Notify, so we make an atomic write the frame buffer.
+  // We would not want a timer based event (Cursor, ...) to come in while we are
+  // doing this operation.
+  //
+  OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);
+
+  switch (BltOperation) {
+  case EfiUgaVideoToBltBuffer:
+    //
+    // Video to BltBuffer: Source is Video, destination is BltBuffer
+    //
+    for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) {
+
+      Offset = (SrcY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + SourceX;
+      if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {
+        Private->PciIo->Mem.Read (
+                              Private->PciIo,
+                              EfiPciIoWidthUint32,
+                              0,
+                              Offset,
+                              Width >> 2,
+                              Private->LineBuffer
+                              );
+      } else {
+        Private->PciIo->Mem.Read (
+                              Private->PciIo,
+                              EfiPciIoWidthUint8,
+                              0,
+                              Offset,
+                              Width,
+                              Private->LineBuffer
+                              );
+      }
+
+      for (X = 0; X < Width; X++) {
+        Blt         = (EFI_UGA_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX + X) * sizeof (EFI_UGA_PIXEL));
+
+        Blt->Red    = (UINT8) (Private->LineBuffer[X] & 0xe0);
+        Blt->Green  = (UINT8) ((Private->LineBuffer[X] & 0x1c) << 3);
+        Blt->Blue   = (UINT8) ((Private->LineBuffer[X] & 0x03) << 6);
+      }
+    }
+    break;
+
+  case EfiUgaVideoToVideo:
+    //
+    // Perform hardware acceleration for Video to Video operations
+    //
+    ScreenWidth   = Private->ModeData[Private->CurrentMode].HorizontalResolution;
+    SourceOffset  = (SourceY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + (SourceX);
+    Offset        = (DestinationY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + (DestinationX);
+
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0000);
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0010);
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0012);
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0014);
+
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0001);
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0011);
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0013);
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0015);
+
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Width << 8) & 0xff00) | 0x20));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Width & 0xff00) | 0x21));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Height << 8) & 0xff00) | 0x22));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Height & 0xff00) | 0x23));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8) & 0xff00) | 0x24));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth & 0xff00) | 0x25));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8) & 0xff00) | 0x26));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth & 0xff00) | 0x27));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) << 8) & 0xff00) | 0x28));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 0) & 0xff00) | 0x29));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 8) & 0xff00) | 0x2a));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) << 8) & 0xff00) | 0x2c));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >> 0) & 0xff00) | 0x2d));
+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >> 8) & 0xff00) | 0x2e));
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x002f);
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0030);
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0d32);
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0033);
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0034);
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0035);
+
+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0231);
+
+    outb (Private, GRAPH_ADDRESS_REGISTER, 0x31);
+    while ((inb (Private, GRAPH_DATA_REGISTER) & 0x01) == 0x01)
+      ;
+    break;
+
+  case EfiUgaVideoFill:
+    Blt       = BltBuffer;
+    Pixel     = (UINT8) ((Blt->Red & 0xe0) | ((Blt->Green >> 3) & 0x1c) | ((Blt->Blue >> 6) & 0x03));
+    WidePixel = (Pixel << 8) | Pixel;
+    WidePixel = (WidePixel << 16) | WidePixel;
+
+    if (DestinationX == 0 && Width == Private->ModeData[Private->CurrentMode].HorizontalResolution) {
+      Offset = DestinationY * Private->ModeData[Private->CurrentMode].HorizontalResolution;
+      if (((Offset & 0x03) == 0) && (((Width * Height) & 0x03) == 0)) {
+        Private->PciIo->Mem.Write (
+                              Private->PciIo,
+                              EfiPciIoWidthFillUint32,
+                              0,
+                              Offset,
+                              (Width * Height) >> 2,
+                              &WidePixel
+                              );
+      } else {
+        Private->PciIo->Mem.Write (
+                              Private->PciIo,
+                              EfiPciIoWidthFillUint8,
+                              0,
+                              Offset,
+                              Width * Height,
+                              &Pixel
+                              );
+      }
+    } else {
+      for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {
+        Offset = (DstY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + DestinationX;
+        if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {
+          Private->PciIo->Mem.Write (
+                                Private->PciIo,
+                                EfiPciIoWidthFillUint32,
+                                0,
+                                Offset,
+                                Width >> 2,
+                                &WidePixel
+                                );
+        } else {
+          Private->PciIo->Mem.Write (
+                                Private->PciIo,
+                                EfiPciIoWidthFillUint8,
+                                0,
+                                Offset,
+                                Width,
+                                &Pixel
+                                );
+        }
+      }
+    }
+    break;
+
+  case EfiUgaBltBufferToVideo:
+    for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {
+
+      for (X = 0; X < Width; X++) {
+        Blt                     = (EFI_UGA_PIXEL *) ((UINT8 *) BltBuffer + (SrcY * Delta) + (SourceX + X) * sizeof (EFI_UGA_PIXEL));
+        Private->LineBuffer[X]  = (UINT8) ((Blt->Red & 0xe0) | ((Blt->Green >> 3) & 0x1c) | ((Blt->Blue >> 6) & 0x03));
+      }
+
+      Offset = (DstY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + DestinationX;
+
+      if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {
+        Private->PciIo->Mem.Write (
+                              Private->PciIo,
+                              EfiPciIoWidthUint32,
+                              0,
+                              Offset,
+                              Width >> 2,
+                              Private->LineBuffer
+                              );
+      } else {
+        Private->PciIo->Mem.Write (
+                              Private->PciIo,
+                              EfiPciIoWidthUint8,
+                              0,
+                              Offset,
+                              Width,
+                              Private->LineBuffer
+                              );
+      }
+    }
+    break;
+
+  default:
+    break;
+  }
+
+  gBS->RestoreTPL (OriginalTPL);
+
+  return EFI_SUCCESS;
+}
+
+//
+// Construction and Destruction functions
+//
+EFI_STATUS
+CirrusLogic5430UgaDrawConstructor (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
+  )
+{
+  EFI_UGA_DRAW_PROTOCOL *UgaDraw;
+
+  //
+  // Fill in Private->UgaDraw protocol
+  //
+  UgaDraw           = &Private->UgaDraw;
+
+  UgaDraw->GetMode  = CirrusLogic5430UgaDrawGetMode;
+  UgaDraw->SetMode  = CirrusLogic5430UgaDrawSetMode;
+  UgaDraw->Blt      = CirrusLogic5430UgaDrawBlt;
+
+  //
+  // Initialize the private data
+  //
+  Private->CurrentMode            = 0;
+  Private->HardwareNeedsStarting  = TRUE;
+  Private->LineBuffer             = NULL;
+
+  //
+  // Initialize the hardware
+  //
+  UgaDraw->SetMode (
+            UgaDraw,
+            Private->ModeData[Private->CurrentMode].HorizontalResolution,
+            Private->ModeData[Private->CurrentMode].VerticalResolution,
+            Private->ModeData[Private->CurrentMode].ColorDepth,
+            Private->ModeData[Private->CurrentMode].RefreshRate
+            );
+  DrawLogo (
+    Private,
+    Private->ModeData[Private->CurrentMode].HorizontalResolution,
+    Private->ModeData[Private->CurrentMode].VerticalResolution
+    );
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Drivers/OptionRomPkg/CirrusLogic5430Dxe/ComponentName.c b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/ComponentName.c
new file mode 100644
index 0000000000..3792937bed
--- /dev/null
+++ b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/ComponentName.c
@@ -0,0 +1,203 @@
+/** @file
+  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CirrusLogic5430.h"
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gCirrusLogic5430ComponentName = {
+  CirrusLogic5430ComponentNameGetDriverName,
+  CirrusLogic5430ComponentNameGetControllerName,
+  "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gCirrusLogic5430ComponentName2 = {
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) CirrusLogic5430ComponentNameGetDriverName,
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) CirrusLogic5430ComponentNameGetControllerName,
+  "en"
+};
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mCirrusLogic5430DriverNameTable[] = {
+  { "eng;en", L"Cirrus Logic 5430 Driver" },
+  { NULL , NULL }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mCirrusLogic5430ControllerNameTable[] = {
+  { "eng;en", L"Cirrus Logic 5430 PCI Adapter" },
+  { NULL , NULL }
+};
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 4646 or ISO 639-2 language code format.
+
+  @param  DriverName[out]       A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+CirrusLogic5430ComponentNameGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **DriverName
+  )
+{
+  return LookupUnicodeString2 (
+           Language,
+           This->SupportedLanguages,
+           mCirrusLogic5430DriverNameTable,
+           DriverName,
+           (BOOLEAN)(This == &gCirrusLogic5430ComponentName)
+           );
+}
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  ControllerHandle[in]  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+
+  @param  ChildHandle[in]       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 4646 or ISO 639-2 language code format.
+
+  @param  ControllerName[out]   A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                controller specified by ControllerHandle and
+                                ChildHandle in the language specified by
+                                Language from the point of view of the driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+
+  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+CirrusLogic5430ComponentNameGetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
+  IN  EFI_HANDLE                                      ControllerHandle,
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
+  IN  CHAR8                                           *Language,
+  OUT CHAR16                                          **ControllerName
+  )
+{
+  EFI_STATUS                      Status;
+
+  //
+  // This is a device driver, so ChildHandle must be NULL.
+  //
+  if (ChildHandle != NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Make sure this driver is currently managing ControllHandle
+  //
+  Status = EfiTestManagedDevice (
+             ControllerHandle,
+             gCirrusLogic5430DriverBinding.DriverBindingHandle,
+             &gEfiPciIoProtocolGuid
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Get the Cirrus Logic 5430's Device structure
+  //
+  return LookupUnicodeString2 (
+           Language,
+           This->SupportedLanguages,
+           mCirrusLogic5430ControllerNameTable,
+           ControllerName,
+           (BOOLEAN)(This == &gCirrusLogic5430ComponentName)
+           );
+}
diff --git a/Drivers/OptionRomPkg/CirrusLogic5430Dxe/DriverSupportedEfiVersion.c b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/DriverSupportedEfiVersion.c
new file mode 100644
index 0000000000..2d8412bf53
--- /dev/null
+++ b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/DriverSupportedEfiVersion.c
@@ -0,0 +1,14 @@
+/** @file
+  Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  Module Name:  DriverSupportEfiVersion.c
+
+**/
+#include "CirrusLogic5430.h"
+
+EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL gCirrusLogic5430DriverSupportedEfiVersion = {
+  sizeof (EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL), // Size of Protocol structure.
+  0                                                   // Version number to be filled at start up.
+};
+
diff --git a/Drivers/OptionRomPkg/CirrusLogic5430Dxe/Edid.c b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/Edid.c
new file mode 100644
index 0000000000..5f288d219e
--- /dev/null
+++ b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/Edid.c
@@ -0,0 +1,525 @@
+/** @file
+  Read EDID information and parse EDID information.
+
+  Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CirrusLogic5430.h"
+#include "CirrusLogic5430I2c.h"
+
+//
+// EDID block
+//
+typedef struct {
+  UINT8   Header[8];                        //EDID header "00 FF FF FF FF FF FF 00"
+  UINT16  ManufactureName;                  //EISA 3-character ID
+  UINT16  ProductCode;                      //Vendor assigned code
+  UINT32  SerialNumber;                     //32-bit serial number
+  UINT8   WeekOfManufacture;                //Week number
+  UINT8   YearOfManufacture;                //Year
+  UINT8   EdidVersion;                      //EDID Structure Version
+  UINT8   EdidRevision;                     //EDID Structure Revision
+  UINT8   VideoInputDefinition;
+  UINT8   MaxHorizontalImageSize;           //cm
+  UINT8   MaxVerticalImageSize;             //cm
+  UINT8   DisplayTransferCharacteristic;
+  UINT8   FeatureSupport;
+  UINT8   RedGreenLowBits;                  //Rx1 Rx0 Ry1 Ry0 Gx1 Gx0 Gy1Gy0
+  UINT8   BlueWhiteLowBits;                 //Bx1 Bx0 By1 By0 Wx1 Wx0 Wy1 Wy0
+  UINT8   RedX;                             //Red-x Bits 9 - 2
+  UINT8   RedY;                             //Red-y Bits 9 - 2
+  UINT8   GreenX;                           //Green-x Bits 9 - 2
+  UINT8   GreenY;                           //Green-y Bits 9 - 2
+  UINT8   BlueX;                            //Blue-x Bits 9 - 2
+  UINT8   BlueY;                            //Blue-y Bits 9 - 2
+  UINT8   WhiteX;                           //White-x Bits 9 - 2
+  UINT8   WhiteY;                           //White-x Bits 9 - 2
+  UINT8   EstablishedTimings[3];
+  UINT8   StandardTimingIdentification[16];
+  UINT8   DetailedTimingDescriptions[72];
+  UINT8   ExtensionFlag;                    //Number of (optional) 128-byte EDID extension blocks to follow
+  UINT8   Checksum;
+} EDID_BLOCK;
+
+#define EDID_BLOCK_SIZE                        128
+#define VBE_EDID_ESTABLISHED_TIMING_MAX_NUMBER 17
+
+typedef struct {
+  UINT16  HorizontalResolution;
+  UINT16  VerticalResolution;
+  UINT16  RefreshRate;
+} EDID_TIMING;
+
+typedef struct {
+  UINT32  ValidNumber;
+  UINT32  Key[VBE_EDID_ESTABLISHED_TIMING_MAX_NUMBER];
+} VALID_EDID_TIMING;
+
+//
+// Standard timing defined by VESA EDID
+//
+EDID_TIMING mVbeEstablishedEdidTiming[] = {
+  //
+  // Established Timing I
+  //
+  {800, 600, 60},
+  {800, 600, 56},
+  {640, 480, 75},
+  {640, 480, 72},
+  {640, 480, 67},
+  {640, 480, 60},
+  {720, 400, 88},
+  {720, 400, 70},
+  //
+  // Established Timing II
+  //
+  {1280, 1024, 75},
+  {1024,  768, 75},
+  {1024,  768, 70},
+  {1024,  768, 60},
+  {1024,  768, 87},
+  {832,   624, 75},
+  {800,   600, 75},
+  {800,   600, 72},
+  //
+  // Established Timing III
+  //
+  {1152, 870, 75}
+};
+
+/**
+  Read EDID information from I2C Bus on CirrusLogic.
+
+  @param  Private             Pointer to CIRRUS_LOGIC_5430_PRIVATE_DATA.
+  @param  EdidDataBlock       Pointer to EDID data block.
+  @param  EdidSize            Returned EDID block size.
+
+  @retval EFI_UNSUPPORTED
+  @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+ReadEdidData (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA     *Private,
+  UINT8                              **EdidDataBlock,
+  UINTN                              *EdidSize
+  )
+{
+  UINTN             Index;
+  UINT8             EdidData[EDID_BLOCK_SIZE * 2];
+  UINT8             *ValidEdid;
+  UINT64            Signature;
+
+  for (Index = 0; Index < EDID_BLOCK_SIZE * 2; Index ++) {
+    I2cReadByte (Private->PciIo, 0xa0, (UINT8)Index, &EdidData[Index]);
+  }
+
+  //
+  // Search for the EDID signature
+  //
+  ValidEdid = &EdidData[0];
+  Signature = 0x00ffffffffffff00ull;
+  for (Index = 0; Index < EDID_BLOCK_SIZE * 2; Index ++, ValidEdid ++) {
+    if (CompareMem (ValidEdid, &Signature, 8) == 0) {
+      break;
+    }
+  }
+
+  if (Index == 256) {
+    //
+    // No EDID signature found
+    //
+    return EFI_UNSUPPORTED;
+  }
+
+  *EdidDataBlock = AllocateCopyPool (
+                     EDID_BLOCK_SIZE,
+                     ValidEdid
+                     );
+  if (*EdidDataBlock == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Currently only support EDID 1.x
+  //
+  *EdidSize = EDID_BLOCK_SIZE;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Generate a search key for a specified timing data.
+
+  @param  EdidTiming             Pointer to EDID timing
+
+  @return The 32 bit unique key for search.
+
+**/
+UINT32
+CalculateEdidKey (
+  EDID_TIMING       *EdidTiming
+  )
+{
+  UINT32 Key;
+
+  //
+  // Be sure no conflicts for all standard timing defined by VESA.
+  //
+  Key = (EdidTiming->HorizontalResolution * 2) + EdidTiming->VerticalResolution;
+  return Key;
+}
+
+/**
+  Search a specified Timing in all the valid EDID timings.
+
+  @param  ValidEdidTiming        All valid EDID timing information.
+  @param  EdidTiming             The Timing to search for.
+
+  @retval TRUE                   Found.
+  @retval FALSE                  Not found.
+
+**/
+BOOLEAN
+SearchEdidTiming (
+  VALID_EDID_TIMING *ValidEdidTiming,
+  EDID_TIMING       *EdidTiming
+  )
+{
+  UINT32 Index;
+  UINT32 Key;
+
+  Key = CalculateEdidKey (EdidTiming);
+
+  for (Index = 0; Index < ValidEdidTiming->ValidNumber; Index ++) {
+    if (Key == ValidEdidTiming->Key[Index]) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+  Parse the Established Timing and Standard Timing in EDID data block.
+
+  @param  EdidBuffer             Pointer to EDID data block
+  @param  ValidEdidTiming        Valid EDID timing information
+
+  @retval TRUE                   The EDID data is valid.
+  @retval FALSE                  The EDID data is invalid.
+
+**/
+BOOLEAN
+ParseEdidData (
+  UINT8                         *EdidBuffer,
+  VALID_EDID_TIMING             *ValidEdidTiming
+  )
+{
+  UINT8        CheckSum;
+  UINT32       Index;
+  UINT32       ValidNumber;
+  UINT32       TimingBits;
+  UINT8        *BufferIndex;
+  UINT16       HorizontalResolution;
+  UINT16       VerticalResolution;
+  UINT8        AspectRatio;
+  UINT8        RefreshRate;
+  EDID_TIMING  TempTiming;
+  EDID_BLOCK   *EdidDataBlock;
+
+  EdidDataBlock = (EDID_BLOCK *) EdidBuffer;
+
+  //
+  // Check the checksum of EDID data
+  //
+  CheckSum = 0;
+  for (Index = 0; Index < EDID_BLOCK_SIZE; Index ++) {
+    CheckSum = (UINT8) (CheckSum + EdidBuffer[Index]);
+  }
+  if (CheckSum != 0) {
+    return FALSE;
+  }
+
+  ValidNumber = 0;
+  SetMem (ValidEdidTiming, sizeof (VALID_EDID_TIMING), 0);
+
+  if ((EdidDataBlock->EstablishedTimings[0] != 0) ||
+      (EdidDataBlock->EstablishedTimings[1] != 0) ||
+      (EdidDataBlock->EstablishedTimings[2] != 0)
+      ) {
+    //
+    // Established timing data
+    //
+    TimingBits = EdidDataBlock->EstablishedTimings[0] |
+                 (EdidDataBlock->EstablishedTimings[1] << 8) |
+                 ((EdidDataBlock->EstablishedTimings[2] & 0x80) << 9) ;
+    for (Index = 0; Index < VBE_EDID_ESTABLISHED_TIMING_MAX_NUMBER; Index ++) {
+      if (TimingBits & 0x1) {
+        ValidEdidTiming->Key[ValidNumber] = CalculateEdidKey (&mVbeEstablishedEdidTiming[Index]);
+        ValidNumber ++;
+      }
+      TimingBits = TimingBits >> 1;
+    }
+  } else {
+    //
+    // If no Established timing data, read the standard timing data
+    //
+    BufferIndex = &EdidDataBlock->StandardTimingIdentification[0];
+    for (Index = 0; Index < 8; Index ++) {
+      if ((BufferIndex[0] != 0x1) && (BufferIndex[1] != 0x1)){
+        //
+        // A valid Standard Timing
+        //
+        HorizontalResolution = (UINT16) (BufferIndex[0] * 8 + 248);
+        AspectRatio = (UINT8) (BufferIndex[1] >> 6);
+        switch (AspectRatio) {
+          case 0:
+            VerticalResolution = (UINT16) (HorizontalResolution / 16 * 10);
+            break;
+          case 1:
+            VerticalResolution = (UINT16) (HorizontalResolution / 4 * 3);
+            break;
+          case 2:
+            VerticalResolution = (UINT16) (HorizontalResolution / 5 * 4);
+            break;
+          case 3:
+            VerticalResolution = (UINT16) (HorizontalResolution / 16 * 9);
+            break;
+          default:
+            VerticalResolution = (UINT16) (HorizontalResolution / 4 * 3);
+            break;
+        }
+        RefreshRate = (UINT8) ((BufferIndex[1] & 0x1f) + 60);
+        TempTiming.HorizontalResolution = HorizontalResolution;
+        TempTiming.VerticalResolution = VerticalResolution;
+        TempTiming.RefreshRate = RefreshRate;
+        ValidEdidTiming->Key[ValidNumber] = CalculateEdidKey (&TempTiming);
+        ValidNumber ++;
+      }
+      BufferIndex += 2;
+    }
+  }
+
+  ValidEdidTiming->ValidNumber = ValidNumber;
+  return TRUE;
+}
+
+/**
+  Construct the valid video modes for CirrusLogic5430.
+
+**/
+EFI_STATUS
+CirrusLogic5430VideoModeSetup (
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
+  )
+{
+  EFI_STATUS                             Status;
+  UINT32                                 Index;
+  BOOLEAN                                EdidFound;
+  EFI_EDID_OVERRIDE_PROTOCOL             *EdidOverride;
+  UINT32                                 EdidAttributes;
+  BOOLEAN                                EdidOverrideFound;
+  UINTN                                  EdidOverrideDataSize;
+  UINT8                                  *EdidOverrideDataBlock;
+  UINTN                                  EdidDiscoveredDataSize;
+  UINT8                                  *EdidDiscoveredDataBlock;
+  UINTN                                  EdidActiveDataSize;
+  UINT8                                  *EdidActiveDataBlock;
+  VALID_EDID_TIMING                      ValidEdidTiming;
+  UINT32                                 ValidModeCount;
+  CIRRUS_LOGIC_5430_MODE_DATA            *ModeData;
+  BOOLEAN                                TimingMatch;
+  CIRRUS_LOGIC_5430_VIDEO_MODES          *VideoMode;
+  EDID_TIMING                            TempTiming;
+
+  //
+  // setup EDID information
+  //
+  Private->EdidDiscovered.Edid       = NULL;
+  Private->EdidDiscovered.SizeOfEdid = 0;
+  Private->EdidActive.Edid           = NULL;
+  Private->EdidActive.SizeOfEdid     = 0;
+
+  EdidFound               = FALSE;
+  EdidOverrideFound       = FALSE;
+  EdidAttributes          = 0xff;
+  EdidOverrideDataSize    = 0;
+  EdidOverrideDataBlock   = NULL;
+  EdidActiveDataSize      = 0;
+  EdidActiveDataBlock     = NULL;
+  EdidDiscoveredDataBlock = NULL;
+
+  //
+  // Find EDID Override protocol firstly, this protocol is installed by platform if needed.
+  //
+  Status = gBS->LocateProtocol (
+                   &gEfiEdidOverrideProtocolGuid,
+                   NULL,
+                   (VOID **) &EdidOverride
+                   );
+  if (!EFI_ERROR (Status)) {
+    //
+    // Allocate double size of VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE to avoid overflow
+    //
+    EdidOverrideDataBlock = AllocatePool (EDID_BLOCK_SIZE * 2);
+    if (NULL == EdidOverrideDataBlock) {
+  		Status = EFI_OUT_OF_RESOURCES;
+      goto Done;
+    }
+
+    Status = EdidOverride->GetEdid (
+                             EdidOverride,
+                             Private->Handle,
+                             &EdidAttributes,
+                             &EdidOverrideDataSize,
+                             (UINT8 **) &EdidOverrideDataBlock
+                             );
+    if (!EFI_ERROR (Status)  &&
+         EdidAttributes == 0 &&
+         EdidOverrideDataSize != 0) {
+      //
+      // Succeeded to get EDID Override Data
+      //
+      EdidOverrideFound = TRUE;
+    }
+  }
+
+  if (EdidOverrideFound != TRUE || EdidAttributes == EFI_EDID_OVERRIDE_DONT_OVERRIDE) {
+    //
+    // If EDID Override data doesn't exist or EFI_EDID_OVERRIDE_DONT_OVERRIDE returned,
+    // read EDID information through I2C Bus
+    //
+    if (ReadEdidData (Private, &EdidDiscoveredDataBlock, &EdidDiscoveredDataSize) == EFI_SUCCESS) {
+      Private->EdidDiscovered.SizeOfEdid = (UINT32) EdidDiscoveredDataSize;
+     	Private->EdidDiscovered.Edid = (UINT8 *) AllocateCopyPool (
+                                                          EdidDiscoveredDataSize,
+                                                          EdidDiscoveredDataBlock
+     																										  );
+
+      if (NULL == Private->EdidDiscovered.Edid) {
+     	  Status = EFI_OUT_OF_RESOURCES;
+        goto Done;
+      }
+
+      EdidActiveDataSize  = Private->EdidDiscovered.SizeOfEdid;
+      EdidActiveDataBlock = Private->EdidDiscovered.Edid;
+
+      EdidFound = TRUE;
+    }
+  }
+
+  if (EdidFound != TRUE && EdidOverrideFound == TRUE) {
+    EdidActiveDataSize  = EdidOverrideDataSize;
+    EdidActiveDataBlock = EdidOverrideDataBlock;
+    EdidFound = TRUE;
+ 	}
+
+ 	if (EdidFound == TRUE) {
+    //
+    // Parse EDID data structure to retrieve modes supported by monitor
+    //
+    if (ParseEdidData ((UINT8 *) EdidActiveDataBlock, &ValidEdidTiming) == TRUE) {
+      //
+      // Copy EDID Override Data to EDID Active Data
+      //
+      Private->EdidActive.SizeOfEdid = (UINT32) EdidActiveDataSize;
+      Private->EdidActive.Edid = (UINT8 *) AllocateCopyPool (
+                                             EdidActiveDataSize,
+                                             EdidActiveDataBlock
+                                             );
+      if (NULL == Private->EdidActive.Edid) {
+   		  Status = EFI_OUT_OF_RESOURCES;
+        goto Done;
+      }
+    }
+  } else {
+    Private->EdidActive.SizeOfEdid = 0;
+    Private->EdidActive.Edid = NULL;
+    EdidFound = FALSE;
+  }
+
+  if (EdidFound) {
+    //
+    // Initialize the private mode data with the supported modes.
+    //
+    ValidModeCount = 0;
+    ModeData = &Private->ModeData[0];
+    VideoMode = &CirrusLogic5430VideoModes[0];
+    for (Index = 0; Index < CIRRUS_LOGIC_5430_MODE_COUNT; Index++) {
+
+      TimingMatch = TRUE;
+
+      //
+      // Check whether match with CirrusLogic5430 video mode
+      //
+      TempTiming.HorizontalResolution = (UINT16) VideoMode->Width;
+      TempTiming.VerticalResolution   = (UINT16) VideoMode->Height;
+      TempTiming.RefreshRate          = (UINT16) VideoMode->RefreshRate;
+      if (SearchEdidTiming (&ValidEdidTiming, &TempTiming) != TRUE) {
+        TimingMatch = FALSE;
+      }
+
+      //
+      // Not export Mode 0x0 as GOP mode, this is not defined in spec.
+      //
+      if ((VideoMode->Width == 0) || (VideoMode->Height == 0)) {
+        TimingMatch = FALSE;
+      }
+
+      if (TimingMatch) {
+        ModeData->ModeNumber = Index;
+        ModeData->HorizontalResolution          = VideoMode->Width;
+        ModeData->VerticalResolution            = VideoMode->Height;
+        ModeData->ColorDepth                    = VideoMode->ColorDepth;
+        ModeData->RefreshRate                   = VideoMode->RefreshRate;
+
+        ModeData ++;
+        ValidModeCount ++;
+      }
+
+      VideoMode ++;
+    }
+
+    Private->MaxMode = ValidModeCount;
+
+  } else {
+    //
+    // If EDID information wasn't found
+    //
+    ModeData = &Private->ModeData[0];
+    VideoMode = &CirrusLogic5430VideoModes[0];
+    for (Index = 0; Index < CIRRUS_LOGIC_5430_MODE_COUNT; Index ++) {
+      ModeData->ModeNumber = Index;
+      ModeData->HorizontalResolution          = VideoMode->Width;
+      ModeData->VerticalResolution            = VideoMode->Height;
+      ModeData->ColorDepth                    = VideoMode->ColorDepth;
+      ModeData->RefreshRate                   = VideoMode->RefreshRate;
+
+      ModeData ++ ;
+      VideoMode ++;
+    }
+    Private->MaxMode = CIRRUS_LOGIC_5430_MODE_COUNT;
+  }
+
+  if (EdidOverrideDataBlock != NULL) {
+    FreePool (EdidOverrideDataBlock);
+  }
+
+  return EFI_SUCCESS;
+
+Done:
+  if (EdidOverrideDataBlock != NULL) {
+    FreePool (EdidOverrideDataBlock);
+  }
+  if (Private->EdidDiscovered.Edid != NULL) {
+    FreePool (Private->EdidDiscovered.Edid);
+  }
+  if (Private->EdidDiscovered.Edid != NULL) {
+    FreePool (Private->EdidActive.Edid);
+  }
+
+  return EFI_DEVICE_ERROR;
+}
diff --git a/Drivers/OptionRomPkg/Include/Library/BltLib.h b/Drivers/OptionRomPkg/Include/Library/BltLib.h
new file mode 100644
index 0000000000..48990a296d
--- /dev/null
+++ b/Drivers/OptionRomPkg/Include/Library/BltLib.h
@@ -0,0 +1,253 @@
+/** @file
+  Library for performing video blt operations
+
+  Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __BLT_LIB__
+#define __BLT_LIB__
+
+#include <Protocol/GraphicsOutput.h>
+
+
+/**
+  Configure the BltLib for a frame-buffer
+
+  @param[in] FrameBuffer      Pointer to the start of the frame buffer
+  @param[in] FrameBufferInfo  Describes the frame buffer characteristics
+
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - Blt operation success
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibConfigure (
+  IN  VOID                                 *FrameBuffer,
+  IN  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo
+  );
+
+
+/**
+  Performs a UEFI Graphics Output Protocol Blt operation.
+
+  @param[in,out] BltBuffer     - The data to transfer to screen
+  @param[in]     BltOperation  - The operation to perform
+  @param[in]     SourceX       - The X coordinate of the source for BltOperation
+  @param[in]     SourceY       - The Y coordinate of the source for BltOperation
+  @param[in]     DestinationX  - The X coordinate of the destination for BltOperation
+  @param[in]     DestinationY  - The Y coordinate of the destination for BltOperation
+  @param[in]     Width         - The width of a rectangle in the blt rectangle in pixels
+  @param[in]     Height        - The height of a rectangle in the blt rectangle in pixels
+  @param[in]     Delta         - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
+                                 If a Delta of 0 is used, the entire BltBuffer will be operated on.
+                                 If a subrectangle of the BltBuffer is used, then Delta represents
+                                 the number of bytes in a row of the BltBuffer.
+
+  @retval  EFI_DEVICE_ERROR - A hardware error occured
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - Blt operation success
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibGopBlt (
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL      *BltBuffer, OPTIONAL
+  IN     EFI_GRAPHICS_OUTPUT_BLT_OPERATION  BltOperation,
+  IN     UINTN                              SourceX,
+  IN     UINTN                              SourceY,
+  IN     UINTN                              DestinationX,
+  IN     UINTN                              DestinationY,
+  IN     UINTN                              Width,
+  IN     UINTN                              Height,
+  IN     UINTN                              Delta
+  );
+
+
+/**
+  Performs a UEFI Graphics Output Protocol Blt Video Fill.
+
+  @param[in]  Color         Color to fill the region with
+  @param[in]  DestinationX  X location to start fill operation
+  @param[in]  DestinationY  Y location to start fill operation
+  @param[in]  Width         Width (in pixels) to fill
+  @param[in]  Height        Height to fill
+
+  @retval  EFI_DEVICE_ERROR - A hardware error occured
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - Blt operation success
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibVideoFill (
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *Color,
+  IN  UINTN                                 DestinationX,
+  IN  UINTN                                 DestinationY,
+  IN  UINTN                                 Width,
+  IN  UINTN                                 Height
+  );
+
+
+/**
+  Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation.
+
+  @param[out] BltBuffer     Output buffer for pixel color data
+  @param[in]  SourceX       X location within video
+  @param[in]  SourceY       Y location within video
+  @param[in]  Width         Width (in pixels)
+  @param[in]  Height        Height
+
+  @retval  EFI_DEVICE_ERROR - A hardware error occured
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - Blt operation success
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibVideoToBltBuffer (
+  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
+  IN  UINTN                                 SourceX,
+  IN  UINTN                                 SourceY,
+  IN  UINTN                                 Width,
+  IN  UINTN                                 Height
+  );
+
+
+/**
+  Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation
+  with extended parameters.
+
+  @param[out] BltBuffer     Output buffer for pixel color data
+  @param[in]  SourceX       X location within video
+  @param[in]  SourceY       Y location within video
+  @param[in]  DestinationX  X location within BltBuffer
+  @param[in]  DestinationY  Y location within BltBuffer
+  @param[in]  Width         Width (in pixels)
+  @param[in]  Height        Height
+  @param[in]  Delta         Number of bytes in a row of BltBuffer
+
+  @retval  EFI_DEVICE_ERROR - A hardware error occured
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - Blt operation success
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibVideoToBltBufferEx (
+  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
+  IN  UINTN                                 SourceX,
+  IN  UINTN                                 SourceY,
+  IN  UINTN                                 DestinationX,
+  IN  UINTN                                 DestinationY,
+  IN  UINTN                                 Width,
+  IN  UINTN                                 Height,
+  IN  UINTN                                 Delta
+  );
+
+
+/**
+  Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation.
+
+  @param[in]  BltBuffer     Output buffer for pixel color data
+  @param[in]  DestinationX  X location within video
+  @param[in]  DestinationY  Y location within video
+  @param[in]  Width         Width (in pixels)
+  @param[in]  Height        Height
+
+  @retval  EFI_DEVICE_ERROR - A hardware error occured
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - Blt operation success
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibBufferToVideo (
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
+  IN  UINTN                                 DestinationX,
+  IN  UINTN                                 DestinationY,
+  IN  UINTN                                 Width,
+  IN  UINTN                                 Height
+  );
+
+
+/**
+  Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation
+  with extended parameters.
+
+  @param[in]  BltBuffer     Output buffer for pixel color data
+  @param[in]  SourceX       X location within BltBuffer
+  @param[in]  SourceY       Y location within BltBuffer
+  @param[in]  DestinationX  X location within video
+  @param[in]  DestinationY  Y location within video
+  @param[in]  Width         Width (in pixels)
+  @param[in]  Height        Height
+  @param[in]  Delta         Number of bytes in a row of BltBuffer
+
+  @retval  EFI_DEVICE_ERROR - A hardware error occured
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - Blt operation success
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibBufferToVideoEx (
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
+  IN  UINTN                                 SourceX,
+  IN  UINTN                                 SourceY,
+  IN  UINTN                                 DestinationX,
+  IN  UINTN                                 DestinationY,
+  IN  UINTN                                 Width,
+  IN  UINTN                                 Height,
+  IN  UINTN                                 Delta
+  );
+
+
+/**
+  Performs a UEFI Graphics Output Protocol Blt Video to Video operation
+
+  @param[in]  SourceX       X location within video
+  @param[in]  SourceY       Y location within video
+  @param[in]  DestinationX  X location within video
+  @param[in]  DestinationY  Y location within video
+  @param[in]  Width         Width (in pixels)
+  @param[in]  Height        Height
+
+  @retval  EFI_DEVICE_ERROR - A hardware error occured
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - Blt operation success
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibVideoToVideo (
+  IN  UINTN                                 SourceX,
+  IN  UINTN                                 SourceY,
+  IN  UINTN                                 DestinationX,
+  IN  UINTN                                 DestinationY,
+  IN  UINTN                                 Width,
+  IN  UINTN                                 Height
+  );
+
+
+/**
+  Returns the sizes related to the video device
+
+  @param[out]  Width   Width (in pixels)
+  @param[out]  Height  Height (in pixels)
+
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - The sizes were returned
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibGetSizes (
+  OUT UINTN                                 *Width,  OPTIONAL
+  OUT UINTN                                 *Height  OPTIONAL
+  );
+
+#endif
+
diff --git a/Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.c b/Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.c
new file mode 100644
index 0000000000..520fac4c63
--- /dev/null
+++ b/Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.c
@@ -0,0 +1,744 @@
+/** @file
+  FrameBufferBltLib - Library to perform blt operations on a frame buffer.
+
+  Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PiDxe.h"
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BltLib.h>
+#include <Library/DebugLib.h>
+
+#if 0
+#define VDEBUG DEBUG
+#else
+#define VDEBUG(x)
+#endif
+
+#define MAX_LINE_BUFFER_SIZE (SIZE_4KB * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))
+
+UINTN                           mBltLibColorDepth;
+UINTN                           mBltLibWidthInBytes;
+UINTN                           mBltLibBytesPerPixel;
+UINTN                           mBltLibWidthInPixels;
+UINTN                           mBltLibHeight;
+UINT8                           mBltLibLineBuffer[MAX_LINE_BUFFER_SIZE];
+UINT8                           *mBltLibFrameBuffer;
+EFI_GRAPHICS_PIXEL_FORMAT       mPixelFormat;
+EFI_PIXEL_BITMASK               mPixelBitMasks;
+INTN                            mPixelShl[4]; // R-G-B-Rsvd
+INTN                            mPixelShr[4]; // R-G-B-Rsvd
+
+
+VOID
+ConfigurePixelBitMaskFormat (
+  IN EFI_PIXEL_BITMASK          *BitMask
+  )
+{
+  UINTN   Loop;
+  UINT32  *Masks;
+  UINT32  MergedMasks;
+
+  MergedMasks = 0;
+  Masks = (UINT32*) BitMask;
+  for (Loop = 0; Loop < 3; Loop++) {
+    ASSERT ((Loop == 3) || (Masks[Loop] != 0));
+    ASSERT ((MergedMasks & Masks[Loop]) == 0);
+    mPixelShl[Loop] = HighBitSet32 (Masks[Loop]) - 23 + (Loop * 8);
+    if (mPixelShl[Loop] < 0) {
+      mPixelShr[Loop] = -mPixelShl[Loop];
+      mPixelShl[Loop] = 0;
+    } else {
+      mPixelShr[Loop] = 0;
+    }
+    MergedMasks = (UINT32) (MergedMasks | Masks[Loop]);
+    DEBUG ((EFI_D_INFO, "%d: shl:%d shr:%d mask:%x\n", Loop, mPixelShl[Loop], mPixelShr[Loop], Masks[Loop]));
+  }
+  MergedMasks = (UINT32) (MergedMasks | Masks[3]);
+
+  ASSERT (MergedMasks != 0);
+  mBltLibBytesPerPixel = (UINTN) ((HighBitSet32 (MergedMasks) + 7) / 8);
+
+  DEBUG ((EFI_D_INFO, "Bytes per pixel: %d\n", mBltLibBytesPerPixel));
+
+  CopyMem (&mPixelBitMasks, BitMask, sizeof (*BitMask));
+}
+
+
+/**
+  Configure the FrameBufferLib instance
+
+  @param[in] FrameBuffer      Pointer to the start of the frame buffer
+  @param[in] FrameBufferInfo  Describes the frame buffer characteristics
+
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter
+  @retval  EFI_UNSUPPORTED - The BltLib does not support this configuration
+  @retval  EFI_SUCCESS - Blt operation success
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibConfigure (
+  IN  VOID                                 *FrameBuffer,
+  IN  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo
+  )
+{
+  STATIC EFI_PIXEL_BITMASK  RgbPixelMasks =
+    { 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 };
+  STATIC EFI_PIXEL_BITMASK  BgrPixelMasks =
+    { 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 };
+
+  switch (FrameBufferInfo->PixelFormat) {
+  case PixelRedGreenBlueReserved8BitPerColor:
+    ConfigurePixelBitMaskFormat (&RgbPixelMasks);
+    break;
+  case PixelBlueGreenRedReserved8BitPerColor:
+    ConfigurePixelBitMaskFormat (&BgrPixelMasks);
+    break;
+  case PixelBitMask:
+    ConfigurePixelBitMaskFormat (&(FrameBufferInfo->PixelInformation));
+    break;
+  case PixelBltOnly:
+    ASSERT (FrameBufferInfo->PixelFormat != PixelBltOnly);
+    return EFI_UNSUPPORTED;
+  default:
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+  mPixelFormat = FrameBufferInfo->PixelFormat;
+
+  mBltLibFrameBuffer = (UINT8*) FrameBuffer;
+  mBltLibWidthInPixels = (UINTN) FrameBufferInfo->HorizontalResolution;
+  mBltLibHeight = (UINTN) FrameBufferInfo->VerticalResolution;
+  mBltLibWidthInBytes = mBltLibWidthInPixels * mBltLibBytesPerPixel;
+
+  ASSERT (mBltLibWidthInBytes < sizeof (mBltLibLineBuffer));
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Performs a UEFI Graphics Output Protocol Blt operation.
+
+  @param[in,out] BltBuffer     - The data to transfer to screen
+  @param[in]     BltOperation  - The operation to perform
+  @param[in]     SourceX       - The X coordinate of the source for BltOperation
+  @param[in]     SourceY       - The Y coordinate of the source for BltOperation
+  @param[in]     DestinationX  - The X coordinate of the destination for BltOperation
+  @param[in]     DestinationY  - The Y coordinate of the destination for BltOperation
+  @param[in]     Width         - The width of a rectangle in the blt rectangle in pixels
+  @param[in]     Height        - The height of a rectangle in the blt rectangle in pixels
+  @param[in]     Delta         - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
+                                 If a Delta of 0 is used, the entire BltBuffer will be operated on.
+                                 If a subrectangle of the BltBuffer is used, then Delta represents
+                                 the number of bytes in a row of the BltBuffer.
+
+  @retval  EFI_DEVICE_ERROR - A hardware error occured
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - Blt operation success
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibGopBlt (
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer, OPTIONAL
+  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION     BltOperation,
+  IN  UINTN                                 SourceX,
+  IN  UINTN                                 SourceY,
+  IN  UINTN                                 DestinationX,
+  IN  UINTN                                 DestinationY,
+  IN  UINTN                                 Width,
+  IN  UINTN                                 Height,
+  IN  UINTN                                 Delta
+  )
+{
+  switch (BltOperation) {
+  case EfiBltVideoToBltBuffer:
+    return BltLibVideoToBltBufferEx (
+             BltBuffer,
+             SourceX,
+             SourceY,
+             DestinationX,
+             DestinationY,
+             Width,
+             Height,
+             Delta
+             );
+
+  case EfiBltVideoToVideo:
+    return BltLibVideoToVideo (
+             SourceX,
+             SourceY,
+             DestinationX,
+             DestinationY,
+             Width,
+             Height
+             );
+
+  case EfiBltVideoFill:
+    return BltLibVideoFill (
+             BltBuffer,
+             DestinationX,
+             DestinationY,
+             Width,
+             Height
+             );
+
+  case EfiBltBufferToVideo:
+    return BltLibBufferToVideoEx (
+             BltBuffer,
+             SourceX,
+             SourceY,
+             DestinationX,
+             DestinationY,
+             Width,
+             Height,
+             Delta
+             );
+  default:
+    return EFI_INVALID_PARAMETER;
+  }
+}
+
+
+/**
+  Performs a UEFI Graphics Output Protocol Blt Video Fill.
+
+  @param[in]  Color         Color to fill the region with
+  @param[in]  DestinationX  X location to start fill operation
+  @param[in]  DestinationY  Y location to start fill operation
+  @param[in]  Width         Width (in pixels) to fill
+  @param[in]  Height        Height to fill
+
+  @retval  EFI_DEVICE_ERROR - A hardware error occured
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - The sizes were returned
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibVideoFill (
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *Color,
+  IN  UINTN                                 DestinationX,
+  IN  UINTN                                 DestinationY,
+  IN  UINTN                                 Width,
+  IN  UINTN                                 Height
+  )
+{
+  UINTN                           DstY;
+  VOID                            *BltMemDst;
+  UINTN                           X;
+  UINT8                           Uint8;
+  UINT32                          Uint32;
+  UINT64                          WideFill;
+  BOOLEAN                         UseWideFill;
+  BOOLEAN                         LineBufferReady;
+  UINTN                           Offset;
+  UINTN                           WidthInBytes;
+  UINTN                           SizeInBytes;
+
+  //
+  // BltBuffer to Video: Source is BltBuffer, destination is Video
+  //
+  if (DestinationY + Height > mBltLibHeight) {
+    DEBUG ((EFI_D_INFO, "VideoFill: Past screen (Y)\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (DestinationX + Width > mBltLibWidthInPixels) {
+    DEBUG ((EFI_D_INFO, "VideoFill: Past screen (X)\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width == 0 || Height == 0) {
+    DEBUG ((EFI_D_INFO, "VideoFill: Width or Height is 0\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  WidthInBytes = Width * mBltLibBytesPerPixel;
+
+  Uint32 = *(UINT32*) Color;
+  WideFill =
+    (UINT32) (
+        (((Uint32 << mPixelShl[0]) >> mPixelShr[0]) & mPixelBitMasks.RedMask) |
+        (((Uint32 << mPixelShl[1]) >> mPixelShr[1]) & mPixelBitMasks.GreenMask) |
+        (((Uint32 << mPixelShl[2]) >> mPixelShr[2]) & mPixelBitMasks.BlueMask)
+      );
+  VDEBUG ((EFI_D_INFO, "VideoFill: color=0x%x, wide-fill=0x%x\n", Uint32, WideFill));
+
+  //
+  // If the size of the pixel data evenly divides the sizeof
+  // WideFill, then a wide fill operation can be used
+  //
+  UseWideFill = TRUE;
+  if ((sizeof (WideFill) % mBltLibBytesPerPixel) == 0) {
+    for (X = mBltLibBytesPerPixel; X < sizeof (WideFill); X++) {
+      ((UINT8*)&WideFill)[X] = ((UINT8*)&WideFill)[X % mBltLibBytesPerPixel];
+    }
+  } else {
+    //
+    // If all the bytes in the pixel are the same value, then use
+    // a wide fill operation.
+    //
+    for (
+      X = 1, Uint8 = ((UINT8*)&WideFill)[0];
+      X < mBltLibBytesPerPixel;
+      X++) {
+      if (Uint8 != ((UINT8*)&WideFill)[X]) {
+        UseWideFill = FALSE;
+        break;
+      }
+    }
+    if (UseWideFill) {
+      SetMem ((VOID*) &WideFill, sizeof (WideFill), Uint8);
+    }
+  }
+
+  if (UseWideFill && (DestinationX == 0) && (Width == mBltLibWidthInPixels)) {
+    VDEBUG ((EFI_D_INFO, "VideoFill (wide, one-shot)\n"));
+    Offset = DestinationY * mBltLibWidthInPixels;
+    Offset = mBltLibBytesPerPixel * Offset;
+    BltMemDst = (VOID*) (mBltLibFrameBuffer + Offset);
+    SizeInBytes = WidthInBytes * Height;
+    if (SizeInBytes >= 8) {
+      SetMem32 (BltMemDst, SizeInBytes & ~3, (UINT32) WideFill);
+      SizeInBytes = SizeInBytes & 3;
+    }
+    if (SizeInBytes > 0) {
+      SetMem (BltMemDst, SizeInBytes, (UINT8)(UINTN) WideFill);
+    }
+  } else {
+    LineBufferReady = FALSE;
+    for (DstY = DestinationY; DstY < (Height + DestinationY); DstY++) {
+      Offset = (DstY * mBltLibWidthInPixels) + DestinationX;
+      Offset = mBltLibBytesPerPixel * Offset;
+      BltMemDst = (VOID*) (mBltLibFrameBuffer + Offset);
+
+      if (UseWideFill && (((UINTN) BltMemDst & 7) == 0)) {
+        VDEBUG ((EFI_D_INFO, "VideoFill (wide)\n"));
+        SizeInBytes = WidthInBytes;
+        if (SizeInBytes >= 8) {
+          SetMem64 (BltMemDst, SizeInBytes & ~7, WideFill);
+          SizeInBytes = SizeInBytes & 7;
+        }
+        if (SizeInBytes > 0) {
+          CopyMem (BltMemDst, (VOID*) &WideFill, SizeInBytes);
+        }
+      } else {
+        VDEBUG ((EFI_D_INFO, "VideoFill (not wide)\n"));
+        if (!LineBufferReady) {
+          CopyMem (mBltLibLineBuffer, &WideFill, mBltLibBytesPerPixel);
+          for (X = 1; X < Width; ) {
+            CopyMem(
+              (mBltLibLineBuffer + (X * mBltLibBytesPerPixel)),
+              mBltLibLineBuffer,
+              MIN (X, Width - X) * mBltLibBytesPerPixel
+              );
+            X = X + MIN (X, Width - X);
+          }
+          LineBufferReady = TRUE;
+        }
+        CopyMem (BltMemDst, mBltLibLineBuffer, WidthInBytes);
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation.
+
+  @param[out] BltBuffer     Output buffer for pixel color data
+  @param[in]  SourceX       X location within video
+  @param[in]  SourceY       Y location within video
+  @param[in]  Width         Width (in pixels)
+  @param[in]  Height        Height
+
+  @retval  EFI_DEVICE_ERROR - A hardware error occured
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - The sizes were returned
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibVideoToBltBuffer (
+  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
+  IN  UINTN                                 SourceX,
+  IN  UINTN                                 SourceY,
+  IN  UINTN                                 Width,
+  IN  UINTN                                 Height
+  )
+{
+  return BltLibVideoToBltBufferEx (
+           BltBuffer,
+           SourceX,
+           SourceY,
+           0,
+           0,
+           Width,
+           Height,
+           0
+           );
+}
+
+
+/**
+  Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation
+  with extended parameters.
+
+  @param[out] BltBuffer     Output buffer for pixel color data
+  @param[in]  SourceX       X location within video
+  @param[in]  SourceY       Y location within video
+  @param[in]  DestinationX  X location within BltBuffer
+  @param[in]  DestinationY  Y location within BltBuffer
+  @param[in]  Width         Width (in pixels)
+  @param[in]  Height        Height
+  @param[in]  Delta         Number of bytes in a row of BltBuffer
+
+  @retval  EFI_DEVICE_ERROR - A hardware error occured
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - The sizes were returned
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibVideoToBltBufferEx (
+  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
+  IN  UINTN                                 SourceX,
+  IN  UINTN                                 SourceY,
+  IN  UINTN                                 DestinationX,
+  IN  UINTN                                 DestinationY,
+  IN  UINTN                                 Width,
+  IN  UINTN                                 Height,
+  IN  UINTN                                 Delta
+  )
+{
+  UINTN                           DstY;
+  UINTN                           SrcY;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *Blt;
+  VOID                            *BltMemSrc;
+  VOID                            *BltMemDst;
+  UINTN                           X;
+  UINT32                          Uint32;
+  UINTN                           Offset;
+  UINTN                           WidthInBytes;
+
+  //
+  // Video to BltBuffer: Source is Video, destination is BltBuffer
+  //
+  if (SourceY + Height > mBltLibHeight) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (SourceX + Width > mBltLibWidthInPixels) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width == 0 || Height == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // If Delta is zero, then the entire BltBuffer is being used, so Delta
+  // is the number of bytes in each row of BltBuffer.  Since BltBuffer is Width pixels size,
+  // the number of bytes in each row can be computed.
+  //
+  if (Delta == 0) {
+    Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+  }
+
+  WidthInBytes = Width * mBltLibBytesPerPixel;
+
+  //
+  // Video to BltBuffer: Source is Video, destination is BltBuffer
+  //
+  for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) {
+
+    Offset = (SrcY * mBltLibWidthInPixels) + SourceX;
+    Offset = mBltLibBytesPerPixel * Offset;
+    BltMemSrc = (VOID *) (mBltLibFrameBuffer + Offset);
+
+    if (mPixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
+      BltMemDst =
+        (VOID *) (
+            (UINT8 *) BltBuffer +
+            (DstY * Delta) +
+            (DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))
+          );
+    } else {
+      BltMemDst = (VOID *) mBltLibLineBuffer;
+    }
+
+    CopyMem (BltMemDst, BltMemSrc, WidthInBytes);
+
+    if (mPixelFormat != PixelBlueGreenRedReserved8BitPerColor) {
+      for (X = 0; X < Width; X++) {
+        Blt         = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+        Uint32 = *(UINT32*) (mBltLibLineBuffer + (X * mBltLibBytesPerPixel));
+        *(UINT32*) Blt =
+          (UINT32) (
+              (((Uint32 & mPixelBitMasks.RedMask)   >> mPixelShl[0]) << mPixelShr[0]) |
+              (((Uint32 & mPixelBitMasks.GreenMask) >> mPixelShl[1]) << mPixelShr[1]) |
+              (((Uint32 & mPixelBitMasks.BlueMask)  >> mPixelShl[2]) << mPixelShr[2])
+            );
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation.
+
+  @param[in]  BltBuffer     Output buffer for pixel color data
+  @param[in]  DestinationX  X location within video
+  @param[in]  DestinationY  Y location within video
+  @param[in]  Width         Width (in pixels)
+  @param[in]  Height        Height
+
+  @retval  EFI_DEVICE_ERROR - A hardware error occured
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - The sizes were returned
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibBufferToVideo (
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
+  IN  UINTN                                 DestinationX,
+  IN  UINTN                                 DestinationY,
+  IN  UINTN                                 Width,
+  IN  UINTN                                 Height
+  )
+{
+  return BltLibBufferToVideoEx (
+           BltBuffer,
+           0,
+           0,
+           DestinationX,
+           DestinationY,
+           Width,
+           Height,
+           0
+           );
+}
+
+
+/**
+  Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation
+  with extended parameters.
+
+  @param[in]  BltBuffer     Output buffer for pixel color data
+  @param[in]  SourceX       X location within BltBuffer
+  @param[in]  SourceY       Y location within BltBuffer
+  @param[in]  DestinationX  X location within video
+  @param[in]  DestinationY  Y location within video
+  @param[in]  Width         Width (in pixels)
+  @param[in]  Height        Height
+  @param[in]  Delta         Number of bytes in a row of BltBuffer
+
+  @retval  EFI_DEVICE_ERROR - A hardware error occured
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - The sizes were returned
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibBufferToVideoEx (
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
+  IN  UINTN                                 SourceX,
+  IN  UINTN                                 SourceY,
+  IN  UINTN                                 DestinationX,
+  IN  UINTN                                 DestinationY,
+  IN  UINTN                                 Width,
+  IN  UINTN                                 Height,
+  IN  UINTN                                 Delta
+  )
+{
+  UINTN                           DstY;
+  UINTN                           SrcY;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *Blt;
+  VOID                            *BltMemSrc;
+  VOID                            *BltMemDst;
+  UINTN                           X;
+  UINT32                          Uint32;
+  UINTN                           Offset;
+  UINTN                           WidthInBytes;
+
+  //
+  // BltBuffer to Video: Source is BltBuffer, destination is Video
+  //
+  if (DestinationY + Height > mBltLibHeight) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (DestinationX + Width > mBltLibWidthInPixels) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width == 0 || Height == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // If Delta is zero, then the entire BltBuffer is being used, so Delta
+  // is the number of bytes in each row of BltBuffer.  Since BltBuffer is Width pixels size,
+  // the number of bytes in each row can be computed.
+  //
+  if (Delta == 0) {
+    Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+  }
+
+  WidthInBytes = Width * mBltLibBytesPerPixel;
+
+  for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {
+
+    Offset = (DstY * mBltLibWidthInPixels) + DestinationX;
+    Offset = mBltLibBytesPerPixel * Offset;
+    BltMemDst = (VOID*) (mBltLibFrameBuffer + Offset);
+
+    if (mPixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
+      BltMemSrc = (VOID *) ((UINT8 *) BltBuffer + (SrcY * Delta));
+    } else {
+      for (X = 0; X < Width; X++) {
+        Blt =
+          (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) (
+              (UINT8 *) BltBuffer +
+              (SrcY * Delta) +
+              ((SourceX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))
+            );
+        Uint32 = *(UINT32*) Blt;
+        *(UINT32*) (mBltLibLineBuffer + (X * mBltLibBytesPerPixel)) =
+          (UINT32) (
+              (((Uint32 << mPixelShl[0]) >> mPixelShr[0]) & mPixelBitMasks.RedMask) |
+              (((Uint32 << mPixelShl[1]) >> mPixelShr[1]) & mPixelBitMasks.GreenMask) |
+              (((Uint32 << mPixelShl[2]) >> mPixelShr[2]) & mPixelBitMasks.BlueMask)
+            );
+      }
+      BltMemSrc = (VOID *) mBltLibLineBuffer;
+    }
+
+    CopyMem (BltMemDst, BltMemSrc, WidthInBytes);
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Performs a UEFI Graphics Output Protocol Blt Video to Video operation
+
+  @param[in]  SourceX       X location within video
+  @param[in]  SourceY       Y location within video
+  @param[in]  DestinationX  X location within video
+  @param[in]  DestinationY  Y location within video
+  @param[in]  Width         Width (in pixels)
+  @param[in]  Height        Height
+
+  @retval  EFI_DEVICE_ERROR - A hardware error occured
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - The sizes were returned
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibVideoToVideo (
+  IN  UINTN                                 SourceX,
+  IN  UINTN                                 SourceY,
+  IN  UINTN                                 DestinationX,
+  IN  UINTN                                 DestinationY,
+  IN  UINTN                                 Width,
+  IN  UINTN                                 Height
+  )
+{
+  VOID                            *BltMemSrc;
+  VOID                            *BltMemDst;
+  UINTN                           Offset;
+  UINTN                           WidthInBytes;
+  INTN                            LineStride;
+
+  //
+  // Video to Video: Source is Video, destination is Video
+  //
+  if (SourceY + Height > mBltLibHeight) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (SourceX + Width > mBltLibWidthInPixels) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (DestinationY + Height > mBltLibHeight) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (DestinationX + Width > mBltLibWidthInPixels) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Width == 0 || Height == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  WidthInBytes = Width * mBltLibBytesPerPixel;
+
+  Offset = (SourceY * mBltLibWidthInPixels) + SourceX;
+  Offset = mBltLibBytesPerPixel * Offset;
+  BltMemSrc = (VOID *) (mBltLibFrameBuffer + Offset);
+
+  Offset = (DestinationY * mBltLibWidthInPixels) + DestinationX;
+  Offset = mBltLibBytesPerPixel * Offset;
+  BltMemDst = (VOID *) (mBltLibFrameBuffer + Offset);
+
+  LineStride = mBltLibWidthInBytes;
+  if ((UINTN) BltMemDst > (UINTN) BltMemSrc) {
+    LineStride = -LineStride;
+  }
+
+  while (Height > 0) {
+    CopyMem (BltMemDst, BltMemSrc, WidthInBytes);
+
+    BltMemSrc = (VOID*) ((UINT8*) BltMemSrc + LineStride);
+    BltMemDst = (VOID*) ((UINT8*) BltMemDst + LineStride);
+    Height--;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Returns the sizes related to the video device
+
+  @param[out]  Width   Width (in pixels)
+  @param[out]  Height  Height (in pixels)
+
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - The sizes were returned
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibGetSizes (
+  OUT UINTN                                 *Width,  OPTIONAL
+  OUT UINTN                                 *Height  OPTIONAL
+  )
+{
+  if (Width != NULL) {
+    *Width = mBltLibWidthInPixels;
+  }
+  if (Height != NULL) {
+    *Height = mBltLibHeight;
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf b/Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
new file mode 100644
index 0000000000..7af8a1baa0
--- /dev/null
+++ b/Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
@@ -0,0 +1,29 @@
+## @file
+#  FrameBufferBltLib - Library to perform blt operations on a frame buffer.
+#
+#  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = FrameBufferBltLib
+  FILE_GUID                      = 2a40f516-c852-4baa-b7a8-0e9ea090d659
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = BltLib
+
+[Sources.common]
+  FrameBufferBltLib.c
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OptionRomPkg/OptionRomPkg.dec
+
diff --git a/Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.c b/Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.c
new file mode 100644
index 0000000000..f28affd26b
--- /dev/null
+++ b/Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.c
@@ -0,0 +1,449 @@
+/** @file
+  GopBltLib - Library to perform blt using the UEFI Graphics Output Protocol.
+
+  Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PiDxe.h"
+
+#include <Protocol/GraphicsOutput.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BltLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+EFI_GRAPHICS_OUTPUT_PROTOCOL         *mGop = NULL;
+
+
+/**
+  Configure the FrameBufferLib instance
+
+  @param[in] FrameBuffer      Pointer to the start of the frame buffer
+  @param[in] FrameBufferInfo  Describes the frame buffer characteristics
+
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter
+  @retval  EFI_UNSUPPORTED - The BltLib does not support this configuration
+  @retval  EFI_SUCCESS - Blt operation success
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibConfigure (
+  IN  VOID                                 *FrameBuffer,
+  IN  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_HANDLE                      *HandleBuffer;
+  UINTN                           HandleCount;
+  UINTN                           Index;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL    *Gop;
+
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiGraphicsOutputProtocolGuid,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer
+                  );
+  if (!EFI_ERROR (Status)) {
+    for (Index = 0; Index < HandleCount; Index++) {
+      Status = gBS->HandleProtocol (
+                      HandleBuffer[Index],
+                      &gEfiGraphicsOutputProtocolGuid,
+                      (VOID*) &Gop
+                      );
+      if (!EFI_ERROR (Status) &&
+          (FrameBuffer == (VOID*)(UINTN) Gop->Mode->FrameBufferBase)) {
+        mGop = Gop;
+        FreePool (HandleBuffer);
+        return EFI_SUCCESS;
+      }
+    }
+
+    FreePool (HandleBuffer);
+  }
+
+  return EFI_UNSUPPORTED;
+}
+
+
+/**
+  Performs a UEFI Graphics Output Protocol Blt operation.
+
+  @param[in,out] BltBuffer     - The data to transfer to screen
+  @param[in]     BltOperation  - The operation to perform
+  @param[in]     SourceX       - The X coordinate of the source for BltOperation
+  @param[in]     SourceY       - The Y coordinate of the source for BltOperation
+  @param[in]     DestinationX  - The X coordinate of the destination for BltOperation
+  @param[in]     DestinationY  - The Y coordinate of the destination for BltOperation
+  @param[in]     Width         - The width of a rectangle in the blt rectangle in pixels
+  @param[in]     Height        - The height of a rectangle in the blt rectangle in pixels
+  @param[in]     Delta         - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
+                                 If a Delta of 0 is used, the entire BltBuffer will be operated on.
+                                 If a subrectangle of the BltBuffer is used, then Delta represents
+                                 the number of bytes in a row of the BltBuffer.
+
+  @retval  EFI_DEVICE_ERROR - A hardware error occured
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - Blt operation success
+
+**/
+EFI_STATUS
+InternalGopBltCommon (
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer, OPTIONAL
+  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION     BltOperation,
+  IN  UINTN                                 SourceX,
+  IN  UINTN                                 SourceY,
+  IN  UINTN                                 DestinationX,
+  IN  UINTN                                 DestinationY,
+  IN  UINTN                                 Width,
+  IN  UINTN                                 Height,
+  IN  UINTN                                 Delta
+  )
+{
+  if (mGop == NULL) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  return mGop->Blt (
+                 mGop,
+                 BltBuffer,
+                 BltOperation,
+                 SourceX,
+                 SourceY,
+                 DestinationX,
+                 DestinationY,
+                 Width,
+                 Height,
+                 Delta
+                 );
+}
+
+
+/**
+  Performs a UEFI Graphics Output Protocol Blt operation.
+
+  @param[in,out] BltBuffer     - The data to transfer to screen
+  @param[in]     BltOperation  - The operation to perform
+  @param[in]     SourceX       - The X coordinate of the source for BltOperation
+  @param[in]     SourceY       - The Y coordinate of the source for BltOperation
+  @param[in]     DestinationX  - The X coordinate of the destination for BltOperation
+  @param[in]     DestinationY  - The Y coordinate of the destination for BltOperation
+  @param[in]     Width         - The width of a rectangle in the blt rectangle in pixels
+  @param[in]     Height        - The height of a rectangle in the blt rectangle in pixels
+  @param[in]     Delta         - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
+                                 If a Delta of 0 is used, the entire BltBuffer will be operated on.
+                                 If a subrectangle of the BltBuffer is used, then Delta represents
+                                 the number of bytes in a row of the BltBuffer.
+
+  @retval  EFI_DEVICE_ERROR - A hardware error occured
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - Blt operation success
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibGopBlt (
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer, OPTIONAL
+  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION     BltOperation,
+  IN  UINTN                                 SourceX,
+  IN  UINTN                                 SourceY,
+  IN  UINTN                                 DestinationX,
+  IN  UINTN                                 DestinationY,
+  IN  UINTN                                 Width,
+  IN  UINTN                                 Height,
+  IN  UINTN                                 Delta
+  )
+{
+  return InternalGopBltCommon (
+           BltBuffer,
+           BltOperation,
+           SourceX,
+           SourceY,
+           DestinationX,
+           DestinationY,
+           Width,
+           Height,
+           Delta
+           );
+}
+
+
+/**
+  Performs a UEFI Graphics Output Protocol Blt Video Fill.
+
+  @param[in]  Color         Color to fill the region with
+  @param[in]  DestinationX  X location to start fill operation
+  @param[in]  DestinationY  Y location to start fill operation
+  @param[in]  Width         Width (in pixels) to fill
+  @param[in]  Height        Height to fill
+
+  @retval  EFI_DEVICE_ERROR - A hardware error occured
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - The sizes were returned
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibVideoFill (
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *Color,
+  IN  UINTN                                 DestinationX,
+  IN  UINTN                                 DestinationY,
+  IN  UINTN                                 Width,
+  IN  UINTN                                 Height
+  )
+{
+  return InternalGopBltCommon (
+           Color,
+           EfiBltVideoFill,
+           0,
+           0,
+           DestinationX,
+           DestinationY,
+           Width,
+           Height,
+           0
+           );
+}
+
+
+/**
+  Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation.
+
+  @param[out] BltBuffer     Output buffer for pixel color data
+  @param[in]  SourceX       X location within video
+  @param[in]  SourceY       Y location within video
+  @param[in]  Width         Width (in pixels)
+  @param[in]  Height        Height
+
+  @retval  EFI_DEVICE_ERROR - A hardware error occured
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - The sizes were returned
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibVideoToBltBuffer (
+  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
+  IN  UINTN                                 SourceX,
+  IN  UINTN                                 SourceY,
+  IN  UINTN                                 Width,
+  IN  UINTN                                 Height
+  )
+{
+  return InternalGopBltCommon (
+           BltBuffer,
+           EfiBltVideoToBltBuffer,
+           SourceX,
+           SourceY,
+           0,
+           0,
+           Width,
+           Height,
+           0
+           );
+}
+
+
+/**
+  Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation
+  with extended parameters.
+
+  @param[out] BltBuffer     Output buffer for pixel color data
+  @param[in]  SourceX       X location within video
+  @param[in]  SourceY       Y location within video
+  @param[in]  DestinationX  X location within BltBuffer
+  @param[in]  DestinationY  Y location within BltBuffer
+  @param[in]  Width         Width (in pixels)
+  @param[in]  Height        Height
+  @param[in]  Delta         Number of bytes in a row of BltBuffer
+
+  @retval  EFI_DEVICE_ERROR - A hardware error occured
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - The sizes were returned
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibVideoToBltBufferEx (
+  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
+  IN  UINTN                                 SourceX,
+  IN  UINTN                                 SourceY,
+  IN  UINTN                                 DestinationX,
+  IN  UINTN                                 DestinationY,
+  IN  UINTN                                 Width,
+  IN  UINTN                                 Height,
+  IN  UINTN                                 Delta
+  )
+{
+  return InternalGopBltCommon (
+           BltBuffer,
+           EfiBltVideoToBltBuffer,
+           SourceX,
+           SourceY,
+           DestinationX,
+           DestinationY,
+           Width,
+           Height,
+           Delta
+           );
+}
+
+
+/**
+  Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation.
+
+  @param[in]  BltBuffer     Output buffer for pixel color data
+  @param[in]  DestinationX  X location within video
+  @param[in]  DestinationY  Y location within video
+  @param[in]  Width         Width (in pixels)
+  @param[in]  Height        Height
+
+  @retval  EFI_DEVICE_ERROR - A hardware error occured
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - The sizes were returned
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibBufferToVideo (
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
+  IN  UINTN                                 DestinationX,
+  IN  UINTN                                 DestinationY,
+  IN  UINTN                                 Width,
+  IN  UINTN                                 Height
+  )
+{
+  return InternalGopBltCommon (
+           BltBuffer,
+           EfiBltBufferToVideo,
+           0,
+           0,
+           DestinationX,
+           DestinationY,
+           Width,
+           Height,
+           0
+           );
+}
+
+
+/**
+  Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation
+  with extended parameters.
+
+  @param[in]  BltBuffer     Output buffer for pixel color data
+  @param[in]  SourceX       X location within BltBuffer
+  @param[in]  SourceY       Y location within BltBuffer
+  @param[in]  DestinationX  X location within video
+  @param[in]  DestinationY  Y location within video
+  @param[in]  Width         Width (in pixels)
+  @param[in]  Height        Height
+  @param[in]  Delta         Number of bytes in a row of BltBuffer
+
+  @retval  EFI_DEVICE_ERROR - A hardware error occured
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - The sizes were returned
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibBufferToVideoEx (
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
+  IN  UINTN                                 SourceX,
+  IN  UINTN                                 SourceY,
+  IN  UINTN                                 DestinationX,
+  IN  UINTN                                 DestinationY,
+  IN  UINTN                                 Width,
+  IN  UINTN                                 Height,
+  IN  UINTN                                 Delta
+  )
+{
+  return InternalGopBltCommon (
+           BltBuffer,
+           EfiBltBufferToVideo,
+           SourceX,
+           SourceY,
+           DestinationX,
+           DestinationY,
+           Width,
+           Height,
+           Delta
+           );
+}
+
+
+/**
+  Performs a UEFI Graphics Output Protocol Blt Video to Video operation
+
+  @param[in]  SourceX       X location within video
+  @param[in]  SourceY       Y location within video
+  @param[in]  DestinationX  X location within video
+  @param[in]  DestinationY  Y location within video
+  @param[in]  Width         Width (in pixels)
+  @param[in]  Height        Height
+
+  @retval  EFI_DEVICE_ERROR - A hardware error occured
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - The sizes were returned
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibVideoToVideo (
+  IN  UINTN                                 SourceX,
+  IN  UINTN                                 SourceY,
+  IN  UINTN                                 DestinationX,
+  IN  UINTN                                 DestinationY,
+  IN  UINTN                                 Width,
+  IN  UINTN                                 Height
+  )
+{
+  return InternalGopBltCommon (
+           NULL,
+           EfiBltVideoToVideo,
+           SourceX,
+           SourceY,
+           DestinationX,
+           DestinationY,
+           Width,
+           Height,
+           0
+           );
+}
+
+/**
+  Returns the sizes related to the video device
+
+  @param[out]  Width   Width (in pixels)
+  @param[out]  Height  Height (in pixels)
+
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
+  @retval  EFI_SUCCESS - The sizes were returned
+
+**/
+EFI_STATUS
+EFIAPI
+BltLibGetSizes (
+  OUT UINTN                                 *Width,  OPTIONAL
+  OUT UINTN                                 *Height  OPTIONAL
+  )
+{
+  ASSERT (mGop != NULL);
+
+  if (Width != NULL) {
+    *Width = mGop->Mode->Info->HorizontalResolution;
+  }
+  if (Height != NULL) {
+    *Height = mGop->Mode->Info->VerticalResolution;
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.inf b/Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.inf
new file mode 100644
index 0000000000..c5559133f9
--- /dev/null
+++ b/Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.inf
@@ -0,0 +1,31 @@
+## @file
+#  GopBltLib - Library to perform blt using the UEFI Graphics Output Protocol.
+#
+#  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = GopBltLib
+  FILE_GUID                      = b75b91f0-a0b4-42fe-ba62-849027999b39
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = BltLib
+
+[Sources.common]
+  GopBltLib.c
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  MemoryAllocationLib
+  UefiBootServicesTableLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OptionRomPkg/OptionRomPkg.dec
+
diff --git a/Drivers/OptionRomPkg/OptionRomPkg.dec b/Drivers/OptionRomPkg/OptionRomPkg.dec
new file mode 100644
index 0000000000..6881f3648e
--- /dev/null
+++ b/Drivers/OptionRomPkg/OptionRomPkg.dec
@@ -0,0 +1,41 @@
+## @file
+# Option Rom Package Reference Implementations.
+#
+# This package is designed to interoperate with the EDK II open source project
+# at http://www.tianocore.org, and this package is required to build PCI compliant
+# Option ROM image for all CPU architectures, including EBC target.
+# A single driver can support mixes of EFI 1.1, UEFI 2.0 and UEFI 2.1.
+#
+# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  DEC_SPECIFICATION              = 0x00010005
+  PACKAGE_NAME                   = OptionRomPkg
+  PACKAGE_GUID                   = AA3865E8-7F30-4f59-8696-99F560101852
+  PACKAGE_VERSION                = 0.1
+
+[Includes]
+  Include
+
+[LibraryClasses]
+  ##  @libraryclass  Provides an interface for performing UEFI Graphics
+  ##                 Output Protocol Video blt operations
+  ##
+  BltLib|Include/Library/BltLib.h
+
+[Guids]
+  gOptionRomPkgTokenSpaceGuid = { 0x1e43298f, 0x3478, 0x41a7, { 0xb5, 0x77, 0x86, 0x6, 0x46, 0x35, 0xc7, 0x28 } }
+
+[PcdsFeatureFlag]
+  gOptionRomPkgTokenSpaceGuid.PcdSupportScsiPassThru|TRUE|BOOLEAN|0x00010001
+  gOptionRomPkgTokenSpaceGuid.PcdSupportExtScsiPassThru|TRUE|BOOLEAN|0x00010002
+  gOptionRomPkgTokenSpaceGuid.PcdSupportGop|TRUE|BOOLEAN|0x00010004
+  gOptionRomPkgTokenSpaceGuid.PcdSupportUga|TRUE|BOOLEAN|0x00010005
+
+[PcdsFixedAtBuild, PcdsPatchableInModule]
+  gOptionRomPkgTokenSpaceGuid.PcdDriverSupportedEfiVersion|0x0002000a|UINT32|0x00010003
+
diff --git a/Drivers/OptionRomPkg/OptionRomPkg.dsc b/Drivers/OptionRomPkg/OptionRomPkg.dsc
new file mode 100644
index 0000000000..bea64b585e
--- /dev/null
+++ b/Drivers/OptionRomPkg/OptionRomPkg.dsc
@@ -0,0 +1,113 @@
+## @file
+# Option Rom Package build validation file for All Architectures.
+#
+# This package is designed to interoperate with the EDK II open source project
+# at http://www.tianocore.org, and this package is required to build PCI compliant
+# Option ROM image for all CPU architectures, including EBC target.
+# A single driver can support mixes of EFI 1.1, UEFI 2.0 and UEFI 2.1.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  PLATFORM_NAME                  = OptionRomPkg
+  PLATFORM_GUID                  = C7B25F37-B1F4-4c46-99CB-3EA7DCF5FCDC
+  PLATFORM_VERSION               = 0.1
+  DSC_SPECIFICATION              = 0x00010005
+  OUTPUT_DIRECTORY               = Build/OptionRomPkg
+  SUPPORTED_ARCHITECTURES        = IA32|X64|EBC|ARM|AARCH64
+  BUILD_TARGETS                  = DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+
+################################################################################
+#
+# SKU Identification section - list of all SKU IDs supported by this
+#                              Platform.
+#
+################################################################################
+[SkuIds]
+  0|DEFAULT              # The entry: 0|DEFAULT is reserved and always required.
+
+[LibraryClasses]
+  DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf  
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+  BltLib|OptionRomPkg/Library/GopBltLib/GopBltLib.inf
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+  TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+
+[LibraryClasses.AARCH64, LibraryClasses.ARM]
+  NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+
+[LibraryClasses.ARM]
+  NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+[PcdsFeatureFlag]
+  gOptionRomPkgTokenSpaceGuid.PcdSupportScsiPassThru|TRUE
+  gOptionRomPkgTokenSpaceGuid.PcdSupportExtScsiPassThru|TRUE
+
+[PcdsFixedAtBuild]
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x27
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000042
+  gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue|0x0
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|0x0
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|0x0
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|0x0
+  gOptionRomPkgTokenSpaceGuid.PcdDriverSupportedEfiVersion|0x0002000a # EFI_2_10_SYSTEM_TABLE_REVISION
+
+###################################################################################################
+#
+# Components Section - list of the modules and components that will be processed by compilation
+#                      tools and the EDK II tools to generate PE32/PE32+/Coff image files.
+#
+# Note: The EDK II DSC file is not used to specify how compiled binary images get placed
+#       into firmware volume images. This section is just a list of modules to compile from
+#       source into UEFI-compliant binaries.
+#       It is the FDF file that contains information on combining binary files into firmware
+#       volume images, whose concept is beyond UEFI and is described in PI specification.
+#       Binary modules do not need to be listed in this section, as they should be
+#       specified in the FDF file. For example: Shell binary (Shell_Full.efi), FAT binary (Fat.efi),
+#       Logo (Logo.bmp), and etc.
+#       There may also be modules listed in this section that are not required in the FDF file,
+#       When a module listed here is excluded from FDF file, then UEFI-compliant binary will be
+#       generated for it, but the binary will not be put into any firmware volume.
+#
+###################################################################################################
+
+[Components]
+  OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
+  OptionRomPkg/Library/GopBltLib/GopBltLib.inf
+
+  OptionRomPkg/AtapiPassThruDxe/AtapiPassThruDxe.inf
+  OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf
+  OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf
+  OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf
+  OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf
+  OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
+
+[Components.IA32, Components.X64]
+  OptionRomPkg/Application/BltLibSample/BltLibSample.inf
diff --git a/Drivers/OptionRomPkg/ReadMe.txt b/Drivers/OptionRomPkg/ReadMe.txt
new file mode 100644
index 0000000000..99f97896da
--- /dev/null
+++ b/Drivers/OptionRomPkg/ReadMe.txt
@@ -0,0 +1,17 @@
+AtapiPassThru:
+  For now, AtapiPassThru driver in this package is to test Scsi Bus support:
+  ScsiBus driver should support both/either ScsiPassThru and ExtScsiPassThru
+  installed on a controller handle.
+   
+  AtapiPassThru driver in this package can selectively produce ScsiPassThru
+  and/or ExtScsiPassThru protocol based on feature flags of PcdSupportScsiPassThru
+  and PcdSupportExtScsiPassThru.
+
+CirrusLogic5430:
+  Sample implementation of UGA Draw or Graphics Output Protocol for the Cirrus
+  Logic 5430 family of PCI video card. It provides reference code for the GOP/UGA,
+  Component Name (2), EFI driver supported Verison protocol.
+
+Build Validation:
+ICC             IA32 X64 IPF
+
diff --git a/Drivers/OptionRomPkg/UndiRuntimeDxe/ComponentName.c b/Drivers/OptionRomPkg/UndiRuntimeDxe/ComponentName.c
new file mode 100644
index 0000000000..b310143271
--- /dev/null
+++ b/Drivers/OptionRomPkg/UndiRuntimeDxe/ComponentName.c
@@ -0,0 +1,359 @@
+/** @file
+    UEFI Component Name(2) protocol implementation for EFI UNDI32 driver.
+
+Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "Undi32.h"
+
+//
+// EFI Component Name Functions
+//
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 4646 or ISO 639-2 language code format.
+
+  @param  DriverName[out]       A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+UndiComponentNameGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **DriverName
+  );
+
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  ControllerHandle[in]  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+
+  @param  ChildHandle[in]       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 4646 or ISO 639-2 language code format.
+
+  @param  ControllerName[out]   A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                controller specified by ControllerHandle and
+                                ChildHandle in the language specified by
+                                Language from the point of view of the driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+
+  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+UndiComponentNameGetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
+  IN  EFI_HANDLE                                      ControllerHandle,
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
+  IN  CHAR8                                           *Language,
+  OUT CHAR16                                          **ControllerName
+  );
+
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gUndiComponentName = {
+  UndiComponentNameGetDriverName,
+  UndiComponentNameGetControllerName,
+  "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gUndiComponentName2 = {
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) UndiComponentNameGetDriverName,
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) UndiComponentNameGetControllerName,
+  "en"
+};
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUndiDriverNameTable[] = {
+  {
+    "eng;en",
+    L"UNDI32 Driver"
+  },
+  {
+    NULL,
+    NULL
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUndiControllerNameTable[] = {
+  {
+    "eng;en",
+    L"UNDI32 Controller"
+  },
+  {
+    NULL,
+    NULL
+  }
+};
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 4646 or ISO 639-2 language code format.
+
+  @param  DriverName[out]       A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+UndiComponentNameGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **DriverName
+  )
+{
+  return LookupUnicodeString2 (
+           Language,
+           This->SupportedLanguages,
+           mUndiDriverNameTable,
+           DriverName,
+           (BOOLEAN)(This == &gUndiComponentName)
+           );
+}
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+  Currently not implemented.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  ControllerHandle[in]  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+
+  @param  ChildHandle[in]       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 4646 or ISO 639-2 language code format.
+
+  @param  ControllerName[out]   A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                controller specified by ControllerHandle and
+                                ChildHandle in the language specified by
+                                Language from the point of view of the driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+
+  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+UndiComponentNameGetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
+  IN  EFI_HANDLE                                      ControllerHandle,
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
+  IN  CHAR8                                           *Language,
+  OUT CHAR16                                          **ControllerName
+  )
+{
+  EFI_STATUS                                Status;
+  EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *Nii;
+
+  if (ChildHandle != NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Make sure this driver is currently managing ControllHandle
+  //
+  Status = EfiTestManagedDevice (
+             ControllerHandle,
+             gUndiDriverBinding.DriverBindingHandle,
+             &gEfiPciIoProtocolGuid
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Retrieve an instance of a produced protocol from ControllerHandle
+  //
+  Status = gBS->OpenProtocol (
+                   ControllerHandle,
+                   &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
+                  (VOID **)&Nii,
+                   NULL,
+                   NULL,
+                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                   );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  return LookupUnicodeString2 (
+           Language,
+           This->SupportedLanguages,
+           mUndiControllerNameTable,
+           ControllerName,
+           (BOOLEAN)(This == &gUndiComponentName)
+           );
+}
diff --git a/Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c b/Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c
new file mode 100644
index 0000000000..b7a2d16bc6
--- /dev/null
+++ b/Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c
@@ -0,0 +1,1516 @@
+/** @file
+  Provides the basic UNID functions.
+
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Undi32.h"
+
+//
+// Global variables defined in this file
+//
+UNDI_CALL_TABLE api_table[PXE_OPCODE_LAST_VALID+1] = { \
+  {PXE_CPBSIZE_NOT_USED,PXE_DBSIZE_NOT_USED,0, (UINT16)(ANY_STATE),UNDI_GetState },\
+  {(UINT16)(DONT_CHECK),PXE_DBSIZE_NOT_USED,0,(UINT16)(ANY_STATE),UNDI_Start },\
+  {PXE_CPBSIZE_NOT_USED,PXE_DBSIZE_NOT_USED,0,MUST_BE_STARTED,UNDI_Stop },\
+  {PXE_CPBSIZE_NOT_USED,sizeof(PXE_DB_GET_INIT_INFO),0,MUST_BE_STARTED, UNDI_GetInitInfo },\
+  {PXE_CPBSIZE_NOT_USED,sizeof(PXE_DB_GET_CONFIG_INFO),0,MUST_BE_STARTED, UNDI_GetConfigInfo },\
+  {sizeof(PXE_CPB_INITIALIZE),(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK),MUST_BE_STARTED,UNDI_Initialize },\
+  {PXE_CPBSIZE_NOT_USED,PXE_DBSIZE_NOT_USED,(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED,UNDI_Reset },\
+  {PXE_CPBSIZE_NOT_USED,PXE_DBSIZE_NOT_USED,0, MUST_BE_INITIALIZED,UNDI_Shutdown },\
+  {PXE_CPBSIZE_NOT_USED,PXE_DBSIZE_NOT_USED,(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED,UNDI_Interrupt },\
+  {(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED, UNDI_RecFilter },\
+  {(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED, UNDI_StnAddr },\
+  {PXE_CPBSIZE_NOT_USED, (UINT16)(DONT_CHECK), (UINT16)(DONT_CHECK), MUST_BE_INITIALIZED, UNDI_Statistics },\
+  {sizeof(PXE_CPB_MCAST_IP_TO_MAC),sizeof(PXE_DB_MCAST_IP_TO_MAC), (UINT16)(DONT_CHECK),MUST_BE_INITIALIZED, UNDI_ip2mac },\
+  {(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED, UNDI_NVData },\
+  {PXE_CPBSIZE_NOT_USED,(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED, UNDI_Status },\
+  {(UINT16)(DONT_CHECK),PXE_DBSIZE_NOT_USED,(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED, UNDI_FillHeader },\
+  {(UINT16)(DONT_CHECK),PXE_DBSIZE_NOT_USED,(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED, UNDI_Transmit },\
+  {sizeof(PXE_CPB_RECEIVE),sizeof(PXE_DB_RECEIVE),0,MUST_BE_INITIALIZED, UNDI_Receive } \
+};
+
+//
+// end of global variables
+//
+
+
+/**
+  This routine determines the operational state of the UNDI.  It updates the state flags in the
+  Command Descriptor Block based on information derived from the AdapterInfo instance data.
+  To ensure the command has completed successfully, CdbPtr->StatCode will contain the result of
+  the command execution.
+  The CdbPtr->StatFlags will contain a STOPPED, STARTED, or INITIALIZED state once the command
+  has successfully completed.
+  Keep in mind the AdapterInfo->State is the active state of the adapter (based on software
+  interrogation), and the CdbPtr->StateFlags is the passed back information that is reflected
+  to the caller of the UNDI API.
+
+  @param  CdbPtr               Pointer to the command descriptor block.
+  @param  AdapterInfo          Pointer to the NIC data structure information which
+                               the UNDI driver is layering on..
+
+  @return None
+
+**/
+VOID
+UNDI_GetState (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  CdbPtr->StatFlags = (PXE_STATFLAGS) (CdbPtr->StatFlags | AdapterInfo->State);
+  return ;
+}
+
+
+/**
+  This routine is used to change the operational state of the UNDI from stopped to started.
+  It will do this as long as the adapter's state is PXE_STATFLAGS_GET_STATE_STOPPED, otherwise
+  the CdbPtr->StatFlags will reflect a command failure, and the CdbPtr->StatCode will reflect the
+  UNDI as having already been started.
+  This routine is modified to reflect the undi 1.1 specification changes. The
+  changes in the spec are mainly in the callback routines, the new spec adds
+  3 more callbacks and a unique id.
+  Since this UNDI supports both old and new undi specifications,
+  The NIC's data structure is filled in with the callback routines (depending
+  on the version) pointed to in the caller's CpbPtr.  This seeds the Delay,
+  Virt2Phys, Block, and Mem_IO for old and new versions and Map_Mem, UnMap_Mem
+  and Sync_Mem routines and a unique id variable for the new version.
+  This is the function which an external entity (SNP, O/S, etc) would call
+  to provide it's I/O abstraction to the UNDI.
+  It's final action is to change the AdapterInfo->State to PXE_STATFLAGS_GET_STATE_STARTED.
+
+  @param  CdbPtr               Pointer to the command descriptor block.
+  @param  AdapterInfo          Pointer to the NIC data structure information which
+                               the UNDI driver is layering on..
+
+  @return None
+
+**/
+VOID
+UNDI_Start (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  PXE_CPB_START_30  *CpbPtr;
+  PXE_CPB_START_31  *CpbPtr_31;
+
+  //
+  // check if it is already started.
+  //
+  if (AdapterInfo->State != PXE_STATFLAGS_GET_STATE_STOPPED) {
+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+    CdbPtr->StatCode  = PXE_STATCODE_ALREADY_STARTED;
+    return ;
+  }
+
+  if (CdbPtr->CPBsize != sizeof(PXE_CPB_START_30) &&
+      CdbPtr->CPBsize != sizeof(PXE_CPB_START_31)) {
+
+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
+    return ;
+  }
+
+  CpbPtr    = (PXE_CPB_START_30 *) (UINTN) (CdbPtr->CPBaddr);
+  CpbPtr_31 = (PXE_CPB_START_31 *) (UINTN) (CdbPtr->CPBaddr);
+
+  if (AdapterInfo->VersionFlag == 0x30) {
+    AdapterInfo->Delay_30     = (bsptr_30) (UINTN) CpbPtr->Delay;
+    AdapterInfo->Virt2Phys_30 = (virtphys_30) (UINTN) CpbPtr->Virt2Phys;
+    AdapterInfo->Block_30     = (block_30) (UINTN) CpbPtr->Block;
+    //
+    // patch for old buggy 3.0 code:
+    // In EFI1.0 undi used to provide the full (absolute) I/O address to the
+    // i/o calls and SNP used to provide a callback that used GlobalIoFncs and
+    // everything worked fine! In EFI 1.1, UNDI is not using the full
+    // i/o or memory address to access the device, The base values for the i/o
+    // and memory address is abstracted by the device specific PciIoFncs and
+    // UNDI only uses the offset values. Since UNDI3.0 cannot provide any
+    // identification to SNP, SNP cannot use nic specific PciIoFncs callback!
+    //
+    // To fix this and make undi3.0 work with SNP in EFI1.1 we
+    // use a TmpMemIo function that is defined in init.c
+    // This breaks the runtime driver feature of undi, but what to do
+    // if we have to provide the 3.0 compatibility (including the 3.0 bugs)
+    //
+    // This TmpMemIo function also takes a UniqueId parameter
+    // (as in undi3.1 design) and so initialize the UniqueId as well here
+    // Note: AdapterInfo->Mem_Io_30 is just filled for consistency with other
+    // parameters but never used, we only use Mem_Io field in the In/Out routines
+    // inside e100b.c.
+    //
+    AdapterInfo->Mem_Io_30  = (mem_io_30) (UINTN) CpbPtr->Mem_IO;
+    AdapterInfo->Mem_Io     = (mem_io) (UINTN) TmpMemIo;
+    AdapterInfo->Unique_ID  = (UINT64) (UINTN) AdapterInfo;
+
+  } else {
+    AdapterInfo->Delay      = (bsptr) (UINTN) CpbPtr_31->Delay;
+    AdapterInfo->Virt2Phys  = (virtphys) (UINTN) CpbPtr_31->Virt2Phys;
+    AdapterInfo->Block      = (block) (UINTN) CpbPtr_31->Block;
+    AdapterInfo->Mem_Io     = (mem_io) (UINTN) CpbPtr_31->Mem_IO;
+
+    AdapterInfo->Map_Mem    = (map_mem) (UINTN) CpbPtr_31->Map_Mem;
+    AdapterInfo->UnMap_Mem  = (unmap_mem) (UINTN) CpbPtr_31->UnMap_Mem;
+    AdapterInfo->Sync_Mem   = (sync_mem) (UINTN) CpbPtr_31->Sync_Mem;
+    AdapterInfo->Unique_ID  = CpbPtr_31->Unique_ID;
+  }
+
+  AdapterInfo->State = PXE_STATFLAGS_GET_STATE_STARTED;
+
+  return ;
+}
+
+
+/**
+  This routine is used to change the operational state of the UNDI from started to stopped.
+  It will not do this if the adapter's state is PXE_STATFLAGS_GET_STATE_INITIALIZED, otherwise
+  the CdbPtr->StatFlags will reflect a command failure, and the CdbPtr->StatCode will reflect the
+  UNDI as having already not been shut down.
+  The NIC's data structure will have the Delay, Virt2Phys, and Block, pointers zero'd out..
+  It's final action is to change the AdapterInfo->State to PXE_STATFLAGS_GET_STATE_STOPPED.
+
+  @param  CdbPtr               Pointer to the command descriptor block.
+  @param  AdapterInfo          Pointer to the NIC data structure information which
+                               the UNDI driver is layering on..
+
+  @return None
+
+**/
+VOID
+UNDI_Stop (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  if (AdapterInfo->State == PXE_STATFLAGS_GET_STATE_INITIALIZED) {
+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+    CdbPtr->StatCode  = PXE_STATCODE_NOT_SHUTDOWN;
+    return ;
+  }
+
+  AdapterInfo->Delay_30     = 0;
+  AdapterInfo->Virt2Phys_30 = 0;
+  AdapterInfo->Block_30     = 0;
+
+  AdapterInfo->Delay        = 0;
+  AdapterInfo->Virt2Phys    = 0;
+  AdapterInfo->Block        = 0;
+
+  AdapterInfo->Map_Mem      = 0;
+  AdapterInfo->UnMap_Mem    = 0;
+  AdapterInfo->Sync_Mem     = 0;
+
+  AdapterInfo->State        = PXE_STATFLAGS_GET_STATE_STOPPED;
+
+  return ;
+}
+
+
+/**
+  This routine is used to retrieve the initialization information that is needed by drivers and
+  applications to initialize the UNDI.  This will fill in data in the Data Block structure that is
+  pointed to by the caller's CdbPtr->DBaddr.  The fields filled in are as follows:
+  MemoryRequired, FrameDataLen, LinkSpeeds[0-3], NvCount, NvWidth, MediaHeaderLen, HWaddrLen,
+  MCastFilterCnt, TxBufCnt, TxBufSize, RxBufCnt, RxBufSize, IFtype, Duplex, and LoopBack.
+  In addition, the CdbPtr->StatFlags ORs in that this NIC supports cable detection.  (APRIORI knowledge)
+
+  @param  CdbPtr               Pointer to the command descriptor block.
+  @param  AdapterInfo          Pointer to the NIC data structure information which
+                               the UNDI driver is layering on..
+
+  @return None
+
+**/
+VOID
+UNDI_GetInitInfo (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  PXE_DB_GET_INIT_INFO  *DbPtr;
+
+  DbPtr = (PXE_DB_GET_INIT_INFO *) (UINTN) (CdbPtr->DBaddr);
+
+  DbPtr->MemoryRequired = MEMORY_NEEDED;
+  DbPtr->FrameDataLen = PXE_MAX_TXRX_UNIT_ETHER;
+  DbPtr->LinkSpeeds[0] = 10;
+  DbPtr->LinkSpeeds[1] = 100;
+  DbPtr->LinkSpeeds[2] = DbPtr->LinkSpeeds[3] = 0;
+  DbPtr->NvCount = MAX_EEPROM_LEN;
+  DbPtr->NvWidth = 4;
+  DbPtr->MediaHeaderLen = PXE_MAC_HEADER_LEN_ETHER;
+  DbPtr->HWaddrLen = PXE_HWADDR_LEN_ETHER;
+  DbPtr->MCastFilterCnt = MAX_MCAST_ADDRESS_CNT;
+
+  DbPtr->TxBufCnt = TX_BUFFER_COUNT;
+  DbPtr->TxBufSize = (UINT16) sizeof (TxCB);
+  DbPtr->RxBufCnt = RX_BUFFER_COUNT;
+  DbPtr->RxBufSize = (UINT16) sizeof (RxFD);
+
+  DbPtr->IFtype = PXE_IFTYPE_ETHERNET;
+  DbPtr->SupportedDuplexModes = PXE_DUPLEX_ENABLE_FULL_SUPPORTED |
+                  PXE_DUPLEX_FORCE_FULL_SUPPORTED;
+  DbPtr->SupportedLoopBackModes = PXE_LOOPBACK_INTERNAL_SUPPORTED |
+                    PXE_LOOPBACK_EXTERNAL_SUPPORTED;
+
+  CdbPtr->StatFlags |= (PXE_STATFLAGS_CABLE_DETECT_SUPPORTED |
+                        PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED);
+  return ;
+}
+
+
+/**
+  This routine is used to retrieve the configuration information about the NIC being controlled by
+  this driver.  This will fill in data in the Data Block structure that is pointed to by the caller's CdbPtr->DBaddr.
+  The fields filled in are as follows:
+  DbPtr->pci.BusType, DbPtr->pci.Bus, DbPtr->pci.Device, and DbPtr->pci.
+  In addition, the DbPtr->pci.Config.Dword[0-63] grabs a copy of this NIC's PCI configuration space.
+
+  @param  CdbPtr               Pointer to the command descriptor block.
+  @param  AdapterInfo          Pointer to the NIC data structure information which
+                               the UNDI driver is layering on..
+
+  @return None
+
+**/
+VOID
+UNDI_GetConfigInfo (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  UINT16                  Index;
+  PXE_DB_GET_CONFIG_INFO  *DbPtr;
+
+  DbPtr               = (PXE_DB_GET_CONFIG_INFO *) (UINTN) (CdbPtr->DBaddr);
+
+  DbPtr->pci.BusType  = PXE_BUSTYPE_PCI;
+  DbPtr->pci.Bus      = AdapterInfo->Bus;
+  DbPtr->pci.Device   = AdapterInfo->Device;
+  DbPtr->pci.Function = AdapterInfo->Function;
+
+  for (Index = 0; Index < MAX_PCI_CONFIG_LEN; Index++) {
+    DbPtr->pci.Config.Dword[Index] = AdapterInfo->Config[Index];
+  }
+
+  return ;
+}
+
+
+/**
+  This routine resets the network adapter and initializes the UNDI using the parameters supplied in
+  the CPB.  This command must be issued before the network adapter can be setup to transmit and
+  receive packets.
+  Once the memory requirements of the UNDI are obtained by using the GetInitInfo command, a block
+  of non-swappable memory may need to be allocated.  The address of this memory must be passed to
+  UNDI during the Initialize in the CPB.  This memory is used primarily for transmit and receive buffers.
+  The fields CableDetect, LinkSpeed, Duplex, LoopBack, MemoryPtr, and MemoryLength are set with information
+  that was passed in the CPB and the NIC is initialized.
+  If the NIC initialization fails, the CdbPtr->StatFlags are updated with PXE_STATFLAGS_COMMAND_FAILED
+  Otherwise, AdapterInfo->State is updated with PXE_STATFLAGS_GET_STATE_INITIALIZED showing the state of
+  the UNDI is now initialized.
+
+  @param  CdbPtr               Pointer to the command descriptor block.
+  @param  AdapterInfo          Pointer to the NIC data structure information which
+                               the UNDI driver is layering on..
+
+  @return None
+
+**/
+VOID
+UNDI_Initialize (
+  IN  PXE_CDB       *CdbPtr,
+  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  PXE_CPB_INITIALIZE  *CpbPtr;
+
+  if ((CdbPtr->OpFlags != PXE_OPFLAGS_INITIALIZE_DETECT_CABLE) &&
+      (CdbPtr->OpFlags != PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE)) {
+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
+    return ;
+  }
+
+  //
+  // check if it is already initialized
+  //
+  if (AdapterInfo->State == PXE_STATFLAGS_GET_STATE_INITIALIZED) {
+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+    CdbPtr->StatCode  = PXE_STATCODE_ALREADY_INITIALIZED;
+    return ;
+  }
+
+  CpbPtr  = (PXE_CPB_INITIALIZE *) (UINTN) CdbPtr->CPBaddr;
+
+  if (CpbPtr->MemoryLength < (UINT32) MEMORY_NEEDED) {
+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CPB;
+    return ;
+  }
+
+  //
+  // default behaviour is to detect the cable, if the 3rd param is 1,
+  // do not do that
+  //
+  AdapterInfo->CableDetect = (UINT8) ((CdbPtr->OpFlags == (UINT16) PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE) ? (UINT8) 0 : (UINT8) 1);
+  AdapterInfo->LinkSpeedReq = (UINT16) CpbPtr->LinkSpeed;
+  AdapterInfo->DuplexReq    = CpbPtr->DuplexMode;
+  AdapterInfo->LoopBack     = CpbPtr->LoopBackMode;
+  AdapterInfo->MemoryPtr    = CpbPtr->MemoryAddr;
+  AdapterInfo->MemoryLength = CpbPtr->MemoryLength;
+
+  CdbPtr->StatCode          = (PXE_STATCODE) E100bInit (AdapterInfo);
+
+  if (CdbPtr->StatCode != PXE_STATCODE_SUCCESS) {
+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+  } else {
+    AdapterInfo->State = PXE_STATFLAGS_GET_STATE_INITIALIZED;
+  }
+
+  return ;
+}
+
+
+/**
+  This routine resets the network adapter and initializes the UNDI using the parameters supplied in
+  the CPB.  The transmit and receive queues are emptied and any pending interrupts are cleared.
+  If the NIC reset fails, the CdbPtr->StatFlags are updated with PXE_STATFLAGS_COMMAND_FAILED
+
+  @param  CdbPtr               Pointer to the command descriptor block.
+  @param  AdapterInfo          Pointer to the NIC data structure information which
+                               the UNDI driver is layering on..
+
+  @return None
+
+**/
+VOID
+UNDI_Reset (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  if (CdbPtr->OpFlags != PXE_OPFLAGS_NOT_USED &&
+      CdbPtr->OpFlags != PXE_OPFLAGS_RESET_DISABLE_INTERRUPTS &&
+      CdbPtr->OpFlags != PXE_OPFLAGS_RESET_DISABLE_FILTERS ) {
+
+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
+    return ;
+  }
+
+  CdbPtr->StatCode = (UINT16) E100bReset (AdapterInfo, CdbPtr->OpFlags);
+
+  if (CdbPtr->StatCode != PXE_STATCODE_SUCCESS) {
+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+  }
+}
+
+
+/**
+  This routine resets the network adapter and leaves it in a safe state for another driver to
+  initialize.  Any pending transmits or receives are lost.  Receive filters and external
+  interrupt enables are disabled.  Once the UNDI has been shutdown, it can then be stopped
+  or initialized again.
+  If the NIC reset fails, the CdbPtr->StatFlags are updated with PXE_STATFLAGS_COMMAND_FAILED
+  Otherwise, AdapterInfo->State is updated with PXE_STATFLAGS_GET_STATE_STARTED showing the state of
+  the NIC as being started.
+
+  @param  CdbPtr               Pointer to the command descriptor block.
+  @param  AdapterInfo          Pointer to the NIC data structure information which
+                               the UNDI driver is layering on..
+
+  @return None
+
+**/
+VOID
+UNDI_Shutdown (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  //
+  // do the shutdown stuff here
+  //
+  CdbPtr->StatCode = (UINT16) E100bShutdown (AdapterInfo);
+
+  if (CdbPtr->StatCode != PXE_STATCODE_SUCCESS) {
+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+  } else {
+    AdapterInfo->State = PXE_STATFLAGS_GET_STATE_STARTED;
+  }
+
+  return ;
+}
+
+
+/**
+  This routine can be used to read and/or change the current external interrupt enable
+  settings.  Disabling an external interrupt enable prevents and external (hardware)
+  interrupt from being signaled by the network device.  Internally the interrupt events
+  can still be polled by using the UNDI_GetState command.
+  The resulting information on the interrupt state will be passed back in the CdbPtr->StatFlags.
+
+  @param  CdbPtr               Pointer to the command descriptor block.
+  @param  AdapterInfo          Pointer to the NIC data structure information which
+                               the UNDI driver is layering on..
+
+  @return None
+
+**/
+VOID
+UNDI_Interrupt (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  UINT8 IntMask;
+
+  IntMask = (UINT8)(UINTN)(CdbPtr->OpFlags & (PXE_OPFLAGS_INTERRUPT_RECEIVE |
+                                              PXE_OPFLAGS_INTERRUPT_TRANSMIT |
+                                              PXE_OPFLAGS_INTERRUPT_COMMAND |
+                                              PXE_OPFLAGS_INTERRUPT_SOFTWARE));
+
+  switch (CdbPtr->OpFlags & PXE_OPFLAGS_INTERRUPT_OPMASK) {
+  case PXE_OPFLAGS_INTERRUPT_READ:
+    break;
+
+  case PXE_OPFLAGS_INTERRUPT_ENABLE:
+    if (IntMask == 0) {
+      CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+      CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
+      return ;
+    }
+
+    AdapterInfo->int_mask = IntMask;
+    E100bSetInterruptState (AdapterInfo);
+    break;
+
+  case PXE_OPFLAGS_INTERRUPT_DISABLE:
+    if (IntMask != 0) {
+      AdapterInfo->int_mask = (UINT16) (AdapterInfo->int_mask & ~(IntMask));
+      E100bSetInterruptState (AdapterInfo);
+      break;
+    }
+
+  //
+  // else fall thru.
+  //
+  default:
+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
+    return ;
+  }
+
+  if ((AdapterInfo->int_mask & PXE_OPFLAGS_INTERRUPT_RECEIVE) != 0) {
+    CdbPtr->StatFlags |= PXE_STATFLAGS_INTERRUPT_RECEIVE;
+
+  }
+
+  if ((AdapterInfo->int_mask & PXE_OPFLAGS_INTERRUPT_TRANSMIT) != 0) {
+    CdbPtr->StatFlags |= PXE_STATFLAGS_INTERRUPT_TRANSMIT;
+
+  }
+
+  if ((AdapterInfo->int_mask & PXE_OPFLAGS_INTERRUPT_COMMAND) != 0) {
+    CdbPtr->StatFlags |= PXE_STATFLAGS_INTERRUPT_COMMAND;
+
+  }
+
+  return ;
+}
+
+
+/**
+  This routine is used to read and change receive filters and, if supported, read
+  and change multicast MAC address filter list.
+
+  @param  CdbPtr               Pointer to the command descriptor block.
+  @param  AdapterInfo          Pointer to the NIC data structure information which
+                               the UNDI driver is layering on..
+
+  @return None
+
+**/
+VOID
+UNDI_RecFilter (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  UINT16                  NewFilter;
+  UINT16                  OpFlags;
+  PXE_DB_RECEIVE_FILTERS  *DbPtr;
+  UINT8                   *MacAddr;
+  UINTN                   MacCount;
+  UINT16                  Index;
+  UINT16                  copy_len;
+  UINT8                   *ptr1;
+  UINT8                   *ptr2;
+  BOOLEAN                 InvalidMacAddr;
+    
+  OpFlags   = CdbPtr->OpFlags;
+  NewFilter = (UINT16) (OpFlags & 0x1F);
+
+  switch (OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_OPMASK) {
+  case PXE_OPFLAGS_RECEIVE_FILTER_READ:
+
+    //
+    // not expecting a cpb, not expecting any filter bits
+    //
+    if ((NewFilter != 0) || (CdbPtr->CPBsize != 0)) {
+      goto BadCdb;
+
+    }
+
+    if ((NewFilter & PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST) == 0) {
+      goto JustRead;
+
+    }
+
+    NewFilter = (UINT16) (NewFilter | AdapterInfo->Rx_Filter);
+    //
+    // all other flags are ignored except mcast_reset
+    //
+    break;
+
+  case PXE_OPFLAGS_RECEIVE_FILTER_ENABLE:
+    //
+    // there should be atleast one other filter bit set.
+    //
+    if (NewFilter == 0) {
+      //
+      // nothing to enable
+      //
+      goto BadCdb;
+    }
+
+    if (CdbPtr->CPBsize != 0) {
+      //
+      // this must be a multicast address list!
+      // don't accept the list unless selective_mcast is set
+      // don't accept confusing mcast settings with this
+      //
+      if (((NewFilter & PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) == 0) ||
+          ((NewFilter & PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST) != 0) ||
+          ((NewFilter & PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST) != 0) ||
+          ((CdbPtr->CPBsize % sizeof (PXE_MAC_ADDR)) != 0) ) {
+        goto BadCdb;
+      }
+
+      MacAddr   = (UINT8 *) ((UINTN) (CdbPtr->CPBaddr));
+      MacCount  = CdbPtr->CPBsize / sizeof (PXE_MAC_ADDR);
+
+      //
+      // The format of Ethernet multicast address for IPv6 is defined in RFC2464,
+      // for IPv4 is defined in RFC1112. Check whether the address is valid.
+      //
+      InvalidMacAddr = FALSE;
+      
+      for (; MacCount-- != 0; MacAddr += sizeof (PXE_MAC_ADDR)) {
+        if (MacAddr[0] == 0x01) {
+          //
+          // This multicast MAC address is mapped from IPv4 address.
+          //
+          if (MacAddr[1] != 0x00 || MacAddr[2] != 0x5E || (MacAddr[3] & 0x80) != 0) {
+            InvalidMacAddr = TRUE;
+          }          
+        } else if (MacAddr[0] == 0x33) {
+          //
+          // This multicast MAC address is mapped from IPv6 address.
+          //
+          if (MacAddr[1] != 0x33) {
+            InvalidMacAddr = TRUE;
+          }
+        } else {
+          InvalidMacAddr = TRUE;
+        }
+
+        if (InvalidMacAddr) {
+          CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+          CdbPtr->StatCode  = PXE_STATCODE_INVALID_CPB;
+          return ;
+        }
+      }
+    }
+
+    //
+    // check selective mcast case enable case
+    //
+    if ((OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) != 0) {
+      if (((OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST) != 0) ||
+          ((OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST) != 0) ) {
+        goto BadCdb;
+
+      }
+      //
+      // if no cpb, make sure we have an old list
+      //
+      if ((CdbPtr->CPBsize == 0) && (AdapterInfo->mcast_list.list_len == 0)) {
+        goto BadCdb;
+      }
+    }
+    //
+    // if you want to enable anything, you got to have unicast
+    // and you have what you already enabled!
+    //
+    NewFilter = (UINT16) (NewFilter | (PXE_OPFLAGS_RECEIVE_FILTER_UNICAST | AdapterInfo->Rx_Filter));
+
+    break;
+
+  case PXE_OPFLAGS_RECEIVE_FILTER_DISABLE:
+
+    //
+    // mcast list not expected, i.e. no cpb here!
+    //
+    if (CdbPtr->CPBsize != PXE_CPBSIZE_NOT_USED) {
+      goto BadCdb;
+    }
+
+    NewFilter = (UINT16) ((~(CdbPtr->OpFlags & 0x1F)) & AdapterInfo->Rx_Filter);
+
+    break;
+
+  default:
+    goto BadCdb;
+  }
+
+  if ((OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST) != 0) {
+    AdapterInfo->mcast_list.list_len = 0;
+    NewFilter &= (~PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST);
+  }
+
+  E100bSetfilter (AdapterInfo, NewFilter, CdbPtr->CPBaddr, CdbPtr->CPBsize);
+
+JustRead:
+  //
+  // give the current mcast list
+  //
+  if ((CdbPtr->DBsize != 0) && (AdapterInfo->mcast_list.list_len != 0)) {
+    //
+    // copy the mc list to db
+    //
+
+    DbPtr = (PXE_DB_RECEIVE_FILTERS *) (UINTN) CdbPtr->DBaddr;
+    ptr1  = (UINT8 *) (&DbPtr->MCastList[0]);
+
+    //
+    // DbPtr->mc_count = AdapterInfo->mcast_list.list_len;
+    //
+    copy_len = (UINT16) (AdapterInfo->mcast_list.list_len * PXE_MAC_LENGTH);
+
+    if (copy_len > CdbPtr->DBsize) {
+      copy_len = CdbPtr->DBsize;
+
+    }
+
+    ptr2 = (UINT8 *) (&AdapterInfo->mcast_list.mc_list[0]);
+    for (Index = 0; Index < copy_len; Index++) {
+      ptr1[Index] = ptr2[Index];
+    }
+  }
+  //
+  // give the stat flags here
+  //
+  if (AdapterInfo->Receive_Started) {
+    CdbPtr->StatFlags = (PXE_STATFLAGS) (CdbPtr->StatFlags | AdapterInfo->Rx_Filter);
+
+  }
+
+  return ;
+
+BadCdb:
+  CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+  CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
+}
+
+
+/**
+  This routine is used to get the current station and broadcast MAC addresses, and to change the
+  current station MAC address.
+
+  @param  CdbPtr               Pointer to the command descriptor block.
+  @param  AdapterInfo          Pointer to the NIC data structure information which
+                               the UNDI driver is layering on..
+
+  @return None
+
+**/
+VOID
+UNDI_StnAddr (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  PXE_CPB_STATION_ADDRESS *CpbPtr;
+  PXE_DB_STATION_ADDRESS  *DbPtr;
+  UINT16                  Index;
+
+  if (CdbPtr->OpFlags == PXE_OPFLAGS_STATION_ADDRESS_RESET) {
+    //
+    // configure the permanent address.
+    // change the AdapterInfo->CurrentNodeAddress field.
+    //
+    if (CompareMem (
+          &AdapterInfo->CurrentNodeAddress[0],
+          &AdapterInfo->PermNodeAddress[0],
+          PXE_MAC_LENGTH
+          ) != 0) {
+      for (Index = 0; Index < PXE_MAC_LENGTH; Index++) {
+        AdapterInfo->CurrentNodeAddress[Index] = AdapterInfo->PermNodeAddress[Index];
+      }
+
+      E100bSetupIAAddr (AdapterInfo);
+    }
+  }
+
+  if (CdbPtr->CPBaddr != (UINT64) 0) {
+    CpbPtr = (PXE_CPB_STATION_ADDRESS *) (UINTN) (CdbPtr->CPBaddr);
+    //
+    // configure the new address
+    //
+    for (Index = 0; Index < PXE_MAC_LENGTH; Index++) {
+      AdapterInfo->CurrentNodeAddress[Index] = CpbPtr->StationAddr[Index];
+    }
+
+    E100bSetupIAAddr (AdapterInfo);
+  }
+
+  if (CdbPtr->DBaddr != (UINT64) 0) {
+    DbPtr = (PXE_DB_STATION_ADDRESS *) (UINTN) (CdbPtr->DBaddr);
+    //
+    // fill it with the new values
+    //
+    for (Index = 0; Index < PXE_MAC_LENGTH; Index++) {
+      DbPtr->StationAddr[Index]   = AdapterInfo->CurrentNodeAddress[Index];
+      DbPtr->BroadcastAddr[Index] = AdapterInfo->BroadcastNodeAddress[Index];
+      DbPtr->PermanentAddr[Index] = AdapterInfo->PermNodeAddress[Index];
+    }
+  }
+
+  return ;
+}
+
+
+/**
+  This routine is used to read and clear the NIC traffic statistics.  This command is supported only
+  if the !PXE structure's Implementation flags say so.
+  Results will be parsed out in the following manner:
+  CdbPtr->DBaddr.Data[0]   R  Total Frames (Including frames with errors and dropped frames)
+  CdbPtr->DBaddr.Data[1]   R  Good Frames (All frames copied into receive buffer)
+  CdbPtr->DBaddr.Data[2]   R  Undersize Frames (Frames below minimum length for media <64 for ethernet)
+  CdbPtr->DBaddr.Data[4]   R  Dropped Frames (Frames that were dropped because receive buffers were full)
+  CdbPtr->DBaddr.Data[8]   R  CRC Error Frames (Frames with alignment or CRC errors)
+  CdbPtr->DBaddr.Data[A]   T  Total Frames (Including frames with errors and dropped frames)
+  CdbPtr->DBaddr.Data[B]   T  Good Frames (All frames copied into transmit buffer)
+  CdbPtr->DBaddr.Data[C]   T  Undersize Frames (Frames below minimum length for media <64 for ethernet)
+  CdbPtr->DBaddr.Data[E]   T  Dropped Frames (Frames that were dropped because of collisions)
+  CdbPtr->DBaddr.Data[14]  T  Total Collision Frames (Total collisions on this subnet)
+
+  @param  CdbPtr               Pointer to the command descriptor block.
+  @param  AdapterInfo          Pointer to the NIC data structure information which
+                               the UNDI driver is layering on..
+
+  @return None
+
+**/
+VOID
+UNDI_Statistics (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  if ((CdbPtr->OpFlags &~(PXE_OPFLAGS_STATISTICS_RESET)) != 0) {
+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
+    return ;
+  }
+
+  if ((CdbPtr->OpFlags & PXE_OPFLAGS_STATISTICS_RESET) != 0) {
+    //
+    // Reset the statistics
+    //
+    CdbPtr->StatCode = (UINT16) E100bStatistics (AdapterInfo, 0, 0);
+  } else {
+    CdbPtr->StatCode = (UINT16) E100bStatistics (AdapterInfo, CdbPtr->DBaddr, CdbPtr->DBsize);
+  }
+
+  return ;
+}
+
+
+/**
+  This routine is used to translate a multicast IP address to a multicast MAC address.
+  This results in a MAC address composed of 25 bits of fixed data with the upper 23 bits of the IP
+  address being appended to it.  Results passed back in the equivalent of CdbPtr->DBaddr->MAC[0-5].
+
+  @param  CdbPtr               Pointer to the command descriptor block.
+  @param  AdapterInfo          Pointer to the NIC data structure information which
+                               the UNDI driver is layering on..
+
+  @return None
+
+**/
+VOID
+UNDI_ip2mac (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  PXE_CPB_MCAST_IP_TO_MAC *CpbPtr;
+  PXE_DB_MCAST_IP_TO_MAC  *DbPtr;
+  UINT8                   *TmpPtr;
+
+  CpbPtr  = (PXE_CPB_MCAST_IP_TO_MAC *) (UINTN) CdbPtr->CPBaddr;
+  DbPtr   = (PXE_DB_MCAST_IP_TO_MAC *) (UINTN) CdbPtr->DBaddr;
+
+  if ((CdbPtr->OpFlags & PXE_OPFLAGS_MCAST_IPV6_TO_MAC) != 0) {
+    //
+    // for now this is not supported
+    //
+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+    CdbPtr->StatCode  = PXE_STATCODE_UNSUPPORTED;
+    return ;
+  }
+
+  TmpPtr = (UINT8 *) (&CpbPtr->IP.IPv4);
+  //
+  // check if the ip given is a mcast IP
+  //
+  if ((TmpPtr[0] & 0xF0) != 0xE0) {
+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CPB;
+  }
+  //
+  // take the last 23 bits in IP.
+  // be very careful. accessing word on a non-word boundary will hang motherboard codenamed Big Sur
+  // casting the mac array (in the middle) to a UINT32 pointer and accessing
+  // the UINT32 content hung the system...
+  //
+  DbPtr->MAC[0] = 0x01;
+  DbPtr->MAC[1] = 0x00;
+  DbPtr->MAC[2] = 0x5e;
+  DbPtr->MAC[3] = (UINT8) (TmpPtr[1] & 0x7f);
+  DbPtr->MAC[4] = (UINT8) TmpPtr[2];
+  DbPtr->MAC[5] = (UINT8) TmpPtr[3];
+
+  return ;
+}
+
+
+/**
+  This routine is used to read and write non-volatile storage on the NIC (if supported).  The NVRAM
+  could be EEPROM, FLASH, or battery backed RAM.
+  This is an optional function according to the UNDI specification  (or will be......)
+
+  @param  CdbPtr               Pointer to the command descriptor block.
+  @param  AdapterInfo          Pointer to the NIC data structure information which
+                               the UNDI driver is layering on..
+
+  @return None
+
+**/
+VOID
+UNDI_NVData (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  PXE_DB_NVDATA *DbPtr;
+  UINT16        Index;
+
+  if ((CdbPtr->OpFlags == PXE_OPFLAGS_NVDATA_READ) != 0) {
+
+    if ((CdbPtr->DBsize == PXE_DBSIZE_NOT_USED) != 0) {
+      CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+      CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
+      return ;
+    }
+
+    DbPtr = (PXE_DB_NVDATA *) (UINTN) CdbPtr->DBaddr;
+
+    for (Index = 0; Index < MAX_PCI_CONFIG_LEN; Index++) {
+      DbPtr->Data.Dword[Index] = AdapterInfo->NVData[Index];
+
+    }
+
+  } else {
+    //
+    // no write for now
+    //
+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+    CdbPtr->StatCode  = PXE_STATCODE_UNSUPPORTED;
+  }
+
+  return ;
+}
+
+
+/**
+  This routine returns the current interrupt status and/or the transmitted buffer addresses.
+  If the current interrupt status is returned, pending interrupts will be acknowledged by this
+  command.  Transmitted buffer addresses that are written to the DB are removed from the transmit
+  buffer queue.
+  Normally, this command would be polled with interrupts disabled.
+  The transmit buffers are returned in CdbPtr->DBaddr->TxBufer[0 - NumEntries].
+  The interrupt status is returned in CdbPtr->StatFlags.
+
+  @param  CdbPtr               Pointer to the command descriptor block.
+  @param  AdapterInfo          Pointer to the NIC data structure information which
+                               the UNDI driver is layering on..
+
+  @return None
+
+**/
+VOID
+UNDI_Status (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  PXE_DB_GET_STATUS *DbPtr;
+  PXE_DB_GET_STATUS TmpGetStatus;
+  UINT16            Index;
+  UINT16            Status;
+  UINT16            NumEntries;
+  RxFD              *RxPtr;
+
+  //
+  // Fill in temporary GetStatus storage.
+  //
+  RxPtr = &AdapterInfo->rx_ring[AdapterInfo->cur_rx_ind];
+
+  if ((RxPtr->cb_header.status & RX_COMPLETE) != 0) {
+    TmpGetStatus.RxFrameLen = RxPtr->ActualCount & 0x3fff;
+  } else {
+    TmpGetStatus.RxFrameLen = 0;
+  }
+
+  TmpGetStatus.reserved = 0;
+
+  //
+  // Fill in size of next available receive packet and
+  // reserved field in caller's DB storage.
+  //
+  DbPtr = (PXE_DB_GET_STATUS *) (UINTN) CdbPtr->DBaddr;
+
+  if (CdbPtr->DBsize > 0 && CdbPtr->DBsize < sizeof (UINT32) * 2) {
+    CopyMem (DbPtr, &TmpGetStatus, CdbPtr->DBsize);
+  } else {
+    CopyMem (DbPtr, &TmpGetStatus, sizeof (UINT32) * 2);
+  }
+
+  //
+  //
+  //
+  if ((CdbPtr->OpFlags & PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS) != 0) {
+    //
+    // DBsize of zero is invalid if Tx buffers are requested.
+    //
+    if (CdbPtr->DBsize == 0) {
+      CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+      CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
+      return ;
+    }
+
+    //
+    // remember this b4 we overwrite
+    //
+    NumEntries = (UINT16) (CdbPtr->DBsize - sizeof (UINT64));
+
+    //
+    // We already filled in 2 UINT32s.
+    //
+    CdbPtr->DBsize = (UINT16) (sizeof (UINT32) * 2);
+
+    //
+    // will claim any hanging free CBs
+    //
+    CheckCBList (AdapterInfo);
+
+    if (AdapterInfo->xmit_done_head == AdapterInfo->xmit_done_tail) {
+      CdbPtr->StatFlags |= PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY;
+    } else {
+      for (Index = 0; ((Index < MAX_XMIT_BUFFERS) && (NumEntries >= sizeof (UINT64))); Index++, NumEntries -= sizeof (UINT64)) {
+        if (AdapterInfo->xmit_done_head != AdapterInfo->xmit_done_tail) {
+          DbPtr->TxBuffer[Index]      = AdapterInfo->xmit_done[AdapterInfo->xmit_done_head];
+          AdapterInfo->xmit_done_head = next (AdapterInfo->xmit_done_head);
+          CdbPtr->DBsize += sizeof (UINT64);
+        } else {
+          break;
+        }
+      }
+    }
+
+    if (AdapterInfo->xmit_done_head != AdapterInfo->xmit_done_tail) {
+      CdbPtr->StatFlags |= PXE_STATFLAGS_DB_WRITE_TRUNCATED;
+
+    }
+    //
+    // check for a receive buffer and give it's size in db
+    //
+  }
+  //
+  //
+  //
+  if ((CdbPtr->OpFlags & PXE_OPFLAGS_GET_INTERRUPT_STATUS) != 0) {
+
+    Status = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBStatus);
+    AdapterInfo->Int_Status = (UINT16) (AdapterInfo->Int_Status | Status);
+
+    //
+    // acknoledge the interrupts
+    //
+    OutWord (AdapterInfo, (UINT16) (Status & 0xfc00), (UINT32) (AdapterInfo->ioaddr + SCBStatus));
+
+    //
+    // report all the outstanding interrupts
+    //
+    Status = AdapterInfo->Int_Status;
+    if ((Status & SCB_STATUS_FR) != 0) {
+      CdbPtr->StatFlags |= PXE_STATFLAGS_GET_STATUS_RECEIVE;
+    }
+
+    if ((Status & SCB_STATUS_SWI) != 0) {
+      CdbPtr->StatFlags |= PXE_STATFLAGS_GET_STATUS_SOFTWARE;
+    }
+  }
+
+  //
+  // Return current media status
+  //
+  if ((CdbPtr->OpFlags & PXE_OPFLAGS_GET_MEDIA_STATUS) != 0) {
+    AdapterInfo->PhyAddress = 0xFF;
+    AdapterInfo->CableDetect = 1;
+
+    if (!PhyDetect (AdapterInfo)) {
+      CdbPtr->StatFlags |= PXE_STATFLAGS_GET_STATUS_NO_MEDIA;
+    }
+  }
+
+  return ;
+}
+
+
+/**
+  This routine is used to fill media header(s) in transmit packet(s).
+  Copies the MAC address into the media header whether it is dealing
+  with fragmented or non-fragmented packets.
+
+  @param  CdbPtr               Pointer to the command descriptor block.
+  @param  AdapterInfo          Pointer to the NIC data structure information which
+                               the UNDI driver is layering on..
+
+  @return None
+
+**/
+VOID
+UNDI_FillHeader (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  PXE_CPB_FILL_HEADER             *Cpb;
+  PXE_CPB_FILL_HEADER_FRAGMENTED  *Cpbf;
+  EtherHeader                     *MacHeader;
+  UINTN                           Index;
+
+  if (CdbPtr->CPBsize == PXE_CPBSIZE_NOT_USED) {
+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
+    return ;
+  }
+
+  if ((CdbPtr->OpFlags & PXE_OPFLAGS_FILL_HEADER_FRAGMENTED) != 0) {
+    Cpbf = (PXE_CPB_FILL_HEADER_FRAGMENTED *) (UINTN) CdbPtr->CPBaddr;
+
+    //
+    // assume 1st fragment is big enough for the mac header
+    //
+    if ((Cpbf->FragCnt == 0) || (Cpbf->FragDesc[0].FragLen < PXE_MAC_HEADER_LEN_ETHER)) {
+      //
+      // no buffers given
+      //
+      CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+      CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
+      return ;
+    }
+
+    MacHeader = (EtherHeader *) (UINTN) Cpbf->FragDesc[0].FragAddr;
+    //
+    // we don't swap the protocol bytes
+    //
+    MacHeader->type = Cpbf->Protocol;
+
+    for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
+      MacHeader->dest_addr[Index] = Cpbf->DestAddr[Index];
+      MacHeader->src_addr[Index]  = Cpbf->SrcAddr[Index];
+    }
+  } else {
+    Cpb       = (PXE_CPB_FILL_HEADER *) (UINTN) CdbPtr->CPBaddr;
+
+    MacHeader = (EtherHeader *) (UINTN) Cpb->MediaHeader;
+    //
+    // we don't swap the protocol bytes
+    //
+    MacHeader->type = Cpb->Protocol;
+
+    for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
+      MacHeader->dest_addr[Index] = Cpb->DestAddr[Index];
+      MacHeader->src_addr[Index]  = Cpb->SrcAddr[Index];
+    }
+  }
+
+  return ;
+}
+
+
+/**
+  This routine is used to place a packet into the transmit queue.  The data buffers given to
+  this command are to be considered locked and the application or network driver loses
+  ownership of these buffers and must not free or relocate them until the ownership returns.
+  When the packets are transmitted, a transmit complete interrupt is generated (if interrupts
+  are disabled, the transmit interrupt status is still set and can be checked using the UNDI_Status
+  command.
+  Some implementations and adapters support transmitting multiple packets with one transmit
+  command.  If this feature is supported, the transmit CPBs can be linked in one transmit
+  command.
+  All UNDIs support fragmented frames, now all network devices or protocols do.  If a fragmented
+  frame CPB is given to UNDI and the network device does not support fragmented frames
+  (see !PXE.Implementation flag), the UNDI will have to copy the fragments into a local buffer
+  before transmitting.
+
+  @param  CdbPtr               Pointer to the command descriptor block.
+  @param  AdapterInfo          Pointer to the NIC data structure information which
+                               the UNDI driver is layering on..
+
+  @return None
+
+**/
+VOID
+UNDI_Transmit (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+
+  if (CdbPtr->CPBsize == PXE_CPBSIZE_NOT_USED) {
+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
+    return ;
+  }
+
+  CdbPtr->StatCode = (PXE_STATCODE) E100bTransmit (AdapterInfo, CdbPtr->CPBaddr, CdbPtr->OpFlags);
+
+  if (CdbPtr->StatCode != PXE_STATCODE_SUCCESS) {
+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+  }
+
+  return ;
+}
+
+
+/**
+  When the network adapter has received a frame, this command is used to copy the frame
+  into the driver/application storage location.  Once a frame has been copied, it is
+  removed from the receive queue.
+
+  @param  CdbPtr               Pointer to the command descriptor block.
+  @param  AdapterInfo          Pointer to the NIC data structure information which
+                               the UNDI driver is layering on..
+
+  @return None
+
+**/
+VOID
+UNDI_Receive (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+
+  //
+  // check if RU has started...
+  //
+  if (!AdapterInfo->Receive_Started) {
+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+    CdbPtr->StatCode  = PXE_STATCODE_NOT_INITIALIZED;
+    return ;
+  }
+
+
+  CdbPtr->StatCode  = (UINT16) E100bReceive (AdapterInfo, CdbPtr->CPBaddr, CdbPtr->DBaddr);
+  if (CdbPtr->StatCode != PXE_STATCODE_SUCCESS) {
+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+
+  }
+
+  return ;
+}
+
+
+
+/**
+  This is the main SW UNDI API entry using the newer nii protocol.
+  The parameter passed in is a 64 bit flat model virtual
+  address of the cdb.  We then jump into the common routine for both old and
+  new nii protocol entries.
+
+  @param  CdbPtr               Pointer to the command descriptor block.
+  @param  AdapterInfo          Pointer to the NIC data structure information which
+                               the UNDI driver is layering on..
+
+  @return None
+
+**/
+// TODO:    cdb - add argument and description to function comment
+VOID
+EFIAPI
+UNDI_APIEntry_new (
+  IN  UINT64 cdb
+  )
+{
+  PXE_CDB           *CdbPtr;
+  NIC_DATA_INSTANCE *AdapterInfo;
+
+  if (cdb == (UINT64) 0) {
+    return ;
+
+  }
+
+  CdbPtr = (PXE_CDB *) (UINTN) cdb;
+
+  if (CdbPtr->IFnum >= (pxe_31->IFcnt | pxe_31->IFcntExt << 8) ) {
+    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
+    return ;
+  }
+
+  AdapterInfo               = &(UNDI32DeviceList[CdbPtr->IFnum]->NicInfo);
+  //
+  // entering from older entry point
+  //
+  AdapterInfo->VersionFlag  = 0x31;
+  UNDI_APIEntry_Common (cdb);
+}
+
+
+/**
+  This is the common routine for both old and new entry point procedures.
+  The parameter passed in is a 64 bit flat model virtual
+  address of the cdb.  We then jump into the service routine pointed to by the
+  Api_Table[OpCode].
+
+  @param  CdbPtr               Pointer to the command descriptor block.
+  @param  AdapterInfo          Pointer to the NIC data structure information which
+                               the UNDI driver is layering on..
+
+  @return None
+
+**/
+// TODO:    cdb - add argument and description to function comment
+VOID
+UNDI_APIEntry_Common (
+  IN  UINT64 cdb
+  )
+{
+  PXE_CDB           *CdbPtr;
+  NIC_DATA_INSTANCE *AdapterInfo;
+  UNDI_CALL_TABLE   *tab_ptr;
+
+  CdbPtr = (PXE_CDB *) (UINTN) cdb;
+
+  //
+  // check the OPCODE range
+  //
+  if ((CdbPtr->OpCode > PXE_OPCODE_LAST_VALID) ||
+      (CdbPtr->StatCode != PXE_STATCODE_INITIALIZE) ||
+      (CdbPtr->StatFlags != PXE_STATFLAGS_INITIALIZE) ||
+      (CdbPtr->IFnum >= (pxe_31->IFcnt |  pxe_31->IFcntExt << 8))) {
+    goto badcdb;
+
+  }
+
+  if (CdbPtr->CPBsize == PXE_CPBSIZE_NOT_USED) {
+    if (CdbPtr->CPBaddr != PXE_CPBADDR_NOT_USED) {
+      goto badcdb;
+    }
+  } else if (CdbPtr->CPBaddr == PXE_CPBADDR_NOT_USED) {
+    goto badcdb;
+  }
+
+  if (CdbPtr->DBsize == PXE_DBSIZE_NOT_USED) {
+    if (CdbPtr->DBaddr != PXE_DBADDR_NOT_USED) {
+      goto badcdb;
+    }
+  } else if (CdbPtr->DBaddr == PXE_DBADDR_NOT_USED) {
+    goto badcdb;
+  }
+
+  //
+  // check if cpbsize and dbsize are as needed
+  // check if opflags are as expected
+  //
+  tab_ptr = &api_table[CdbPtr->OpCode];
+
+  if (tab_ptr->cpbsize != (UINT16) (DONT_CHECK) && tab_ptr->cpbsize != CdbPtr->CPBsize) {
+    goto badcdb;
+  }
+
+  if (tab_ptr->dbsize != (UINT16) (DONT_CHECK) && tab_ptr->dbsize != CdbPtr->DBsize) {
+    goto badcdb;
+  }
+
+  if (tab_ptr->opflags != (UINT16) (DONT_CHECK) && tab_ptr->opflags != CdbPtr->OpFlags) {
+    goto badcdb;
+
+  }
+
+  AdapterInfo = &(UNDI32DeviceList[CdbPtr->IFnum]->NicInfo);
+
+  //
+  // check if UNDI_State is valid for this call
+  //
+  if (tab_ptr->state != (UINT16) (-1)) {
+    //
+    // should atleast be started
+    //
+    if (AdapterInfo->State == PXE_STATFLAGS_GET_STATE_STOPPED) {
+      CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+      CdbPtr->StatCode  = PXE_STATCODE_NOT_STARTED;
+      return ;
+    }
+    //
+    // check if it should be initialized
+    //
+    if (tab_ptr->state == 2) {
+      if (AdapterInfo->State != PXE_STATFLAGS_GET_STATE_INITIALIZED) {
+        CdbPtr->StatCode  = PXE_STATCODE_NOT_INITIALIZED;
+        CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+        return ;
+      }
+    }
+  }
+  //
+  // set the return variable for success case here
+  //
+  CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
+  CdbPtr->StatCode  = PXE_STATCODE_SUCCESS;
+
+  tab_ptr->api_ptr (CdbPtr, AdapterInfo);
+  return ;
+  //
+  // %% AVL - check for command linking
+  //
+badcdb:
+  CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
+  CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
+  return ;
+}
+
+
+/**
+  When called with a null NicPtr, this routine decrements the number of NICs
+  this UNDI is supporting and removes the NIC_DATA_POINTER from the array.
+  Otherwise, it increments the number of NICs this UNDI is supported and
+  updates the pxe.Fudge to ensure a proper check sum results.
+
+  @param  NicPtr               Pointer to the NIC data structure.
+
+  @return None
+
+**/
+VOID
+PxeUpdate (
+  IN  NIC_DATA_INSTANCE *NicPtr,
+  IN PXE_SW_UNDI        *PxePtr
+  )
+{
+  UINT16 NicNum;
+  NicNum = (PxePtr->IFcnt | PxePtr->IFcntExt << 8);
+  
+  if (NicPtr == NULL) {
+    if (NicNum > 0) {
+      //
+      // number of NICs this undi supports
+      //
+      NicNum --;
+    }
+    goto done;
+  }
+
+  //
+  // number of NICs this undi supports
+  //
+  NicNum++;
+  
+done: 
+  PxePtr->IFcnt = (UINT8)(NicNum & 0xFF);
+  PxePtr->IFcntExt = (UINT8) ((NicNum & 0xFF00) >> 8);
+  PxePtr->Fudge = (UINT8) (PxePtr->Fudge - CalculateSum8 ((VOID *) PxePtr, PxePtr->Len));
+  return ;
+}
+
+
+/**
+  Initialize the !PXE structure
+
+  @param  PxePtr               Pointer to SW_UNDI data structure.
+
+  @retval EFI_SUCCESS          This driver is added to Controller.
+  @retval other                This driver does not support this device.
+
+**/
+VOID
+PxeStructInit (
+  IN PXE_SW_UNDI *PxePtr
+  )
+{
+  //
+  // Initialize the !PXE structure
+  //
+  PxePtr->Signature = PXE_ROMID_SIGNATURE;
+  PxePtr->Len       = (UINT8) sizeof (PXE_SW_UNDI);
+  //
+  // cksum
+  //
+  PxePtr->Fudge     = 0;
+  //
+  // number of NICs this undi supports
+  //
+  PxePtr->IFcnt = 0;
+  PxePtr->IFcntExt = 0;
+  PxePtr->Rev       = PXE_ROMID_REV;
+  PxePtr->MajorVer  = PXE_ROMID_MAJORVER;
+  PxePtr->MinorVer  = PXE_ROMID_MINORVER;
+  PxePtr->reserved1 = 0;
+
+  PxePtr->Implementation = PXE_ROMID_IMP_SW_VIRT_ADDR |
+    PXE_ROMID_IMP_FRAG_SUPPORTED |
+    PXE_ROMID_IMP_CMD_LINK_SUPPORTED |
+    PXE_ROMID_IMP_NVDATA_READ_ONLY |
+    PXE_ROMID_IMP_STATION_ADDR_SETTABLE |
+    PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED |
+    PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED |
+    PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED |
+    PXE_ROMID_IMP_FILTERED_MULTICAST_RX_SUPPORTED |
+    PXE_ROMID_IMP_SOFTWARE_INT_SUPPORTED |
+    PXE_ROMID_IMP_PACKET_RX_INT_SUPPORTED;
+
+  PxePtr->EntryPoint  = (UINT64) (UINTN) UNDI_APIEntry_new;
+  PxePtr->MinorVer    = PXE_ROMID_MINORVER_31;
+
+  PxePtr->reserved2[0]  = 0;
+  PxePtr->reserved2[1]  = 0;
+  PxePtr->reserved2[2]  = 0;
+  PxePtr->BusCnt        = 1;
+  PxePtr->BusType[0]    = PXE_BUSTYPE_PCI;
+
+  PxePtr->Fudge         = (UINT8) (PxePtr->Fudge - CalculateSum8 ((VOID *) PxePtr, PxePtr->Len));
+}
+
diff --git a/Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c b/Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c
new file mode 100644
index 0000000000..199f5430ad
--- /dev/null
+++ b/Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c
@@ -0,0 +1,3541 @@
+/** @file
+  Provides basic function upon network adapter card.
+
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Undi32.h"
+
+UINT8 basic_config_cmd[22] = {
+                    22,        0x08,
+                    0,           0,
+                    0, (UINT8)0x80,
+                    0x32,        0x03,
+                    1,            0,
+                    0x2E,           0,
+                    0x60,           0,
+                    (UINT8)0xf2,        0x48,
+                    0,        0x40,
+                    (UINT8)0xf2, (UINT8)0x80, // 0x40=Force full-duplex
+                    0x3f,       0x05,
+};
+
+//
+// How to wait for the command unit to accept a command.
+// Typically this takes 0 ticks.
+//
+#define wait_for_cmd_done(cmd_ioaddr) \
+{                      \
+  INT16 wait_count = 2000;              \
+  while ((InByte (AdapterInfo, cmd_ioaddr) != 0) && --wait_count >= 0)  \
+    DelayIt (AdapterInfo, 10);  \
+  if (wait_count == 0) \
+    DelayIt (AdapterInfo, 50);    \
+}
+
+
+/**
+  This function calls the MemIo callback to read a byte from the device's
+  address space
+  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)
+  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have
+  to make undi3.0 a special case
+
+  @param  Port                            Which port to read from.
+
+  @retval Results                         The data read from the port.
+
+**/
+// TODO:    AdapterInfo - add argument and description to function comment
+UINT8
+InByte (
+  IN NIC_DATA_INSTANCE *AdapterInfo,
+  IN UINT32            Port
+  )
+{
+  UINT8 Results;
+
+  (*AdapterInfo->Mem_Io) (
+    AdapterInfo->Unique_ID,
+    PXE_MEM_READ,
+    1,
+    (UINT64)Port,
+    (UINT64) (UINTN) &Results
+    );
+  return Results;
+}
+
+
+/**
+  This function calls the MemIo callback to read a word from the device's
+  address space
+  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)
+  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have
+  to make undi3.0 a special case
+
+  @param  Port                            Which port to read from.
+
+  @retval Results                         The data read from the port.
+
+**/
+// TODO:    AdapterInfo - add argument and description to function comment
+UINT16
+InWord (
+  IN NIC_DATA_INSTANCE *AdapterInfo,
+  IN UINT32            Port
+  )
+{
+  UINT16  Results;
+
+  (*AdapterInfo->Mem_Io) (
+    AdapterInfo->Unique_ID,
+    PXE_MEM_READ,
+    2,
+    (UINT64)Port,
+    (UINT64)(UINTN)&Results
+    );
+  return Results;
+}
+
+
+/**
+  This function calls the MemIo callback to read a dword from the device's
+  address space
+  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)
+  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have
+  to make undi3.0 a special case
+
+  @param  Port                            Which port to read from.
+
+  @retval Results                         The data read from the port.
+
+**/
+// TODO:    AdapterInfo - add argument and description to function comment
+UINT32
+InLong (
+  IN NIC_DATA_INSTANCE *AdapterInfo,
+  IN UINT32            Port
+  )
+{
+  UINT32  Results;
+
+  (*AdapterInfo->Mem_Io) (
+    AdapterInfo->Unique_ID,
+    PXE_MEM_READ,
+    4,
+    (UINT64)Port,
+    (UINT64)(UINTN)&Results
+    );
+  return Results;
+}
+
+
+/**
+  This function calls the MemIo callback to write a byte from the device's
+  address space
+  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)
+  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have
+  to make undi3.0 a special case
+
+  @param  Data                            Data to write to Port.
+  @param  Port                            Which port to write to.
+
+  @return none
+
+**/
+// TODO:    AdapterInfo - add argument and description to function comment
+VOID
+OutByte (
+  IN NIC_DATA_INSTANCE *AdapterInfo,
+  IN UINT8             Data,
+  IN UINT32            Port
+  )
+{
+  UINT8 Val;
+
+  Val = Data;
+  (*AdapterInfo->Mem_Io) (
+     AdapterInfo->Unique_ID,
+     PXE_MEM_WRITE,
+     1,
+     (UINT64)Port,
+     (UINT64)(UINTN)(UINTN)&Val
+     );
+  return ;
+}
+
+
+/**
+  This function calls the MemIo callback to write a word from the device's
+  address space
+  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)
+  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have
+  to make undi3.0 a special case
+
+  @param  Data                            Data to write to Port.
+  @param  Port                            Which port to write to.
+
+  @return none
+
+**/
+// TODO:    AdapterInfo - add argument and description to function comment
+VOID
+OutWord (
+  IN NIC_DATA_INSTANCE *AdapterInfo,
+  IN UINT16            Data,
+  IN UINT32            Port
+  )
+{
+  UINT16  Val;
+
+  Val = Data;
+  (*AdapterInfo->Mem_Io) (
+     AdapterInfo->Unique_ID,
+     PXE_MEM_WRITE,
+     2,
+     (UINT64)Port,
+     (UINT64)(UINTN)&Val
+     );
+  return ;
+}
+
+
+/**
+  This function calls the MemIo callback to write a dword from the device's
+  address space
+  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)
+  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have
+  to make undi3.0 a special case
+
+  @param  Data                            Data to write to Port.
+  @param  Port                            Which port to write to.
+
+  @return none
+
+**/
+// TODO:    AdapterInfo - add argument and description to function comment
+VOID
+OutLong (
+  IN NIC_DATA_INSTANCE *AdapterInfo,
+  IN UINT32            Data,
+  IN UINT32            Port
+  )
+{
+  UINT32  Val;
+
+  Val = Data;
+  (*AdapterInfo->Mem_Io) (
+     AdapterInfo->Unique_ID,
+     PXE_MEM_WRITE,
+     4,
+     (UINT64)Port,
+     (UINT64)(UINTN)&Val
+     );
+  return ;
+}
+
+
+/**
+  TODO: Add function description
+
+  @param  AdapterInfo                     TODO: add argument description
+  @param  MemAddr                         TODO: add argument description
+  @param  Size                            TODO: add argument description
+  @param  Direction                       TODO: add argument description
+  @param  MappedAddr                      TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+UINTN
+MapIt (
+  IN NIC_DATA_INSTANCE *AdapterInfo,
+  IN UINT64            MemAddr,
+  IN UINT32            Size,
+  IN UINT32            Direction,
+  OUT UINT64           MappedAddr
+  )
+{
+  UINT64  *PhyAddr;
+
+  PhyAddr = (UINT64 *) (UINTN) MappedAddr;
+  //
+  // mapping is different for theold and new NII protocols
+  //
+  if (AdapterInfo->VersionFlag == 0x30) {
+    if (AdapterInfo->Virt2Phys_30 == (VOID *) NULL) {
+      *PhyAddr = (UINT64) AdapterInfo->MemoryPtr;
+    } else {
+      (*AdapterInfo->Virt2Phys_30) (MemAddr, (UINT64) (UINTN) PhyAddr);
+    }
+
+    if (*PhyAddr > FOUR_GIGABYTE) {
+      return PXE_STATCODE_INVALID_PARAMETER;
+    }
+  } else {
+    if (AdapterInfo->Map_Mem == (VOID *) NULL) {
+      //
+      // this UNDI cannot handle addresses beyond 4 GB without a map routine
+      //
+      if (MemAddr > FOUR_GIGABYTE) {
+        return PXE_STATCODE_INVALID_PARAMETER;
+      } else {
+        *PhyAddr = MemAddr;
+      }
+    } else {
+      (*AdapterInfo->Map_Mem) (
+        AdapterInfo->Unique_ID,
+        MemAddr,
+        Size,
+        Direction,
+        MappedAddr
+        );
+    }
+  }
+
+  return PXE_STATCODE_SUCCESS;
+}
+
+
+/**
+  TODO: Add function description
+
+  @param  AdapterInfo                     TODO: add argument description
+  @param  MemAddr                         TODO: add argument description
+  @param  Size                            TODO: add argument description
+  @param  Direction                       TODO: add argument description
+  @param  MappedAddr                      TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+VOID
+UnMapIt (
+  IN NIC_DATA_INSTANCE *AdapterInfo,
+  IN UINT64            MemAddr,
+  IN UINT32            Size,
+  IN UINT32            Direction,
+  IN UINT64            MappedAddr
+  )
+{
+  if (AdapterInfo->VersionFlag > 0x30) {
+    //
+    // no mapping service
+    //
+    if (AdapterInfo->UnMap_Mem != (VOID *) NULL) {
+      (*AdapterInfo->UnMap_Mem) (
+        AdapterInfo->Unique_ID,
+        MemAddr,
+        Size,
+        Direction,
+        MappedAddr
+        );
+
+    }
+  }
+
+  return ;
+}
+
+
+/**
+
+  @param  AdapterInfo                     Pointer to the NIC data structure
+                                          information which the UNDI driver is
+                                          layering on..
+
+
+**/
+// TODO:    MicroSeconds - add argument and description to function comment
+VOID
+DelayIt (
+  IN NIC_DATA_INSTANCE *AdapterInfo,
+  UINT16               MicroSeconds
+  )
+{
+  if (AdapterInfo->VersionFlag == 0x30) {
+    (*AdapterInfo->Delay_30) (MicroSeconds);
+  } else {
+    (*AdapterInfo->Delay) (AdapterInfo->Unique_ID, MicroSeconds);
+  }
+}
+
+
+/**
+
+  @param  AdapterInfo                     Pointer to the NIC data structure
+                                          information which the UNDI driver is
+                                          layering on..
+
+
+**/
+// TODO:    flag - add argument and description to function comment
+VOID
+BlockIt (
+  IN NIC_DATA_INSTANCE *AdapterInfo,
+  UINT32               flag
+  )
+{
+  if (AdapterInfo->VersionFlag == 0x30) {
+    (*AdapterInfo->Block_30) (flag);
+  } else {
+    (*AdapterInfo->Block) (AdapterInfo->Unique_ID, flag);
+  }
+}
+
+
+/**
+  TODO: Add function description
+
+  @param  AdapterInfo                     TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+UINT8
+Load_Base_Regs (
+  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  //
+  // we will use the linear (flat) memory model and fill our base registers
+  // with 0's so that the entire physical address is our offset
+  //
+  //
+  // we reset the statistics totals here because this is where we are loading stats addr
+  //
+  AdapterInfo->RxTotals = 0;
+  AdapterInfo->TxTotals = 0;
+
+  //
+  // Load the statistics block address.
+  //
+  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
+  OutLong (AdapterInfo, (UINT32) AdapterInfo->stat_phy_addr, AdapterInfo->ioaddr + SCBPointer);
+  OutByte (AdapterInfo, CU_STATSADDR, AdapterInfo->ioaddr + SCBCmd);
+  AdapterInfo->statistics->done_marker = 0;
+
+  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
+  OutLong (AdapterInfo, 0, AdapterInfo->ioaddr + SCBPointer);
+  OutByte (AdapterInfo, RX_ADDR_LOAD, AdapterInfo->ioaddr + SCBCmd);
+
+  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
+  OutLong (AdapterInfo, 0, AdapterInfo->ioaddr + SCBPointer);
+  OutByte (AdapterInfo, CU_CMD_BASE, AdapterInfo->ioaddr + SCBCmd);
+
+  return 0;
+}
+
+
+/**
+  TODO: Add function description
+
+  @param  AdapterInfo                     TODO: add argument description
+  @param  cmd_ptr                         TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+UINT8
+IssueCB (
+  NIC_DATA_INSTANCE *AdapterInfo,
+  TxCB              *cmd_ptr
+  )
+{
+  UINT16  status;
+
+  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
+
+  //
+  // read the CU status, if it is idle, write the address of cb_ptr
+  // in the scbpointer and issue a cu_start,
+  // if it is suspended, remove the suspend bit in the previous command
+  // block and issue a resume
+  //
+  // Ensure that the CU Active Status bit is not on from previous CBs.
+  //
+  status = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBStatus);
+
+  //
+  // Skip acknowledging the interrupt if it is not already set
+  //
+
+  //
+  // ack only the cna the integer
+  //
+  if ((status & SCB_STATUS_CNA) != 0) {
+    OutWord (AdapterInfo, SCB_STATUS_CNA, AdapterInfo->ioaddr + SCBStatus);
+
+  }
+
+  if ((status & SCB_STATUS_CU_MASK) == SCB_STATUS_CU_IDLE) {
+    //
+    // give a cu_start
+    //
+    OutLong (AdapterInfo, cmd_ptr->PhysTCBAddress, AdapterInfo->ioaddr + SCBPointer);
+    OutByte (AdapterInfo, CU_START, AdapterInfo->ioaddr + SCBCmd);
+  } else {
+    //
+    // either active or suspended, give a resume
+    //
+
+    cmd_ptr->PrevTCBVirtualLinkPtr->cb_header.command &= ~(CmdSuspend | CmdIntr);
+    OutByte (AdapterInfo, CU_RESUME, AdapterInfo->ioaddr + SCBCmd);
+  }
+
+  return 0;
+}
+
+
+/**
+  TODO: Add function description
+
+  @param  AdapterInfo                     TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+UINT8
+Configure (
+  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  //
+  // all command blocks are of TxCB format
+  //
+  TxCB  *cmd_ptr;
+  UINT8 *data_ptr;
+  volatile INT16 Index;
+  UINT8 my_filter;
+
+  cmd_ptr   = GetFreeCB (AdapterInfo);
+  ASSERT (cmd_ptr != NULL);
+  data_ptr  = (UINT8 *) cmd_ptr + sizeof (struct CB_Header);
+
+  //
+  // start the config data right after the command header
+  //
+  for (Index = 0; Index < sizeof (basic_config_cmd); Index++) {
+    data_ptr[Index] = basic_config_cmd[Index];
+  }
+
+  my_filter = (UINT8) ((AdapterInfo->Rx_Filter & PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS) ? 1 : 0);
+  my_filter = (UINT8) (my_filter | ((AdapterInfo->Rx_Filter & PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST) ? 0 : 2));
+
+  data_ptr[15]  = (UINT8) (data_ptr[15] | my_filter);
+  data_ptr[19]  = (UINT8) (AdapterInfo->Duplex ? 0xC0 : 0x80);
+  data_ptr[21]  = (UINT8) ((AdapterInfo->Rx_Filter & PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST) ? 0x0D : 0x05);
+
+  //
+  // check if we have to use the AUI port instead
+  //
+  if ((AdapterInfo->PhyRecord[0] & 0x8000) != 0) {
+    data_ptr[15] |= 0x80;
+    data_ptr[8] = 0;
+  }
+
+  BlockIt (AdapterInfo, TRUE);
+  cmd_ptr->cb_header.command = CmdSuspend | CmdConfigure;
+
+  IssueCB (AdapterInfo, cmd_ptr);
+  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
+
+  BlockIt (AdapterInfo, FALSE);
+
+  CommandWaitForCompletion (cmd_ptr, AdapterInfo);
+
+  //
+  // restore the cb values for tx
+  //
+  cmd_ptr->PhysTBDArrayAddres = cmd_ptr->PhysArrayAddr;
+  cmd_ptr->ByteCount = cmd_ptr->Threshold = cmd_ptr->TBDCount = 0;
+  //
+  // fields beyond the immediatedata are assumed to be safe
+  // add the CB to the free list again
+  //
+  SetFreeCB (AdapterInfo, cmd_ptr);
+  return 0;
+}
+
+
+/**
+  TODO: Add function description
+
+  @param  AdapterInfo                     TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+UINT8
+E100bSetupIAAddr (
+  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  //
+  // all command blocks are of TxCB format
+  //
+  TxCB    *cmd_ptr;
+  UINT16  *data_ptr;
+  UINT16  *eaddrs;
+
+  eaddrs    = (UINT16 *) AdapterInfo->CurrentNodeAddress;
+
+  cmd_ptr   = GetFreeCB (AdapterInfo);
+  ASSERT (cmd_ptr != NULL);
+  data_ptr  = (UINT16 *) ((UINT8 *) cmd_ptr +sizeof (struct CB_Header));
+
+  //
+  // AVOID a bug (?!) here by marking the command already completed.
+  //
+  cmd_ptr->cb_header.command  = (CmdSuspend | CmdIASetup);
+  cmd_ptr->cb_header.status   = 0;
+  data_ptr[0]                 = eaddrs[0];
+  data_ptr[1]                 = eaddrs[1];
+  data_ptr[2]                 = eaddrs[2];
+
+  BlockIt (AdapterInfo, TRUE);
+  IssueCB (AdapterInfo, cmd_ptr);
+  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
+  BlockIt (AdapterInfo, FALSE);
+
+  CommandWaitForCompletion (cmd_ptr, AdapterInfo);
+
+  //
+  // restore the cb values for tx
+  //
+  cmd_ptr->PhysTBDArrayAddres = cmd_ptr->PhysArrayAddr;
+  cmd_ptr->ByteCount = cmd_ptr->Threshold = cmd_ptr->TBDCount = 0;
+  //
+  // fields beyond the immediatedata are assumed to be safe
+  // add the CB to the free list again
+  //
+  SetFreeCB (AdapterInfo, cmd_ptr);
+  return 0;
+}
+
+
+/**
+  Instructs the NIC to stop receiving packets.
+
+  @param  AdapterInfo                     Pointer to the NIC data structure
+                                          information which the UNDI driver is
+                                          layering on..
+
+
+**/
+VOID
+StopRU (
+  IN NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  if (AdapterInfo->Receive_Started) {
+
+    //
+    // Todo: verify that we must wait for previous command completion.
+    //
+    wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
+
+    //
+    // Disable interrupts, and stop the chip's Rx process.
+    //
+    OutWord (AdapterInfo, INT_MASK, AdapterInfo->ioaddr + SCBCmd);
+    OutWord (AdapterInfo, INT_MASK | RX_ABORT, AdapterInfo->ioaddr + SCBCmd);
+
+    AdapterInfo->Receive_Started = FALSE;
+  }
+
+  return ;
+}
+
+
+/**
+  Instructs the NIC to start receiving packets.
+
+  @param  AdapterInfo                     Pointer to the NIC data structure
+                                          information which the UNDI driver is
+                                          layering on..
+
+  @retval 0                               Successful
+  @retval -1                              Already Started
+
+**/
+INT8
+StartRU (
+  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+
+  if (AdapterInfo->Receive_Started) {
+    //
+    // already started
+    //
+    return -1;
+  }
+
+  AdapterInfo->cur_rx_ind = 0;
+  AdapterInfo->Int_Status = 0;
+
+  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
+
+  OutLong (AdapterInfo, (UINT32) AdapterInfo->rx_phy_addr, AdapterInfo->ioaddr + SCBPointer);
+  OutByte (AdapterInfo, RX_START, AdapterInfo->ioaddr + SCBCmd);
+
+  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
+
+  AdapterInfo->Receive_Started = TRUE;
+  return 0;
+}
+
+
+/**
+  Configures the chip.  This routine expects the NIC_DATA_INSTANCE structure to be filled in.
+
+  @param  AdapterInfo                     Pointer to the NIC data structure
+                                          information which the UNDI driver is
+                                          layering on..
+
+  @retval 0                               Successful
+  @retval PXE_STATCODE_NOT_ENOUGH_MEMORY  Insufficient length of locked memory
+  @retval other                           Failure initializing chip
+
+**/
+UINTN
+E100bInit (
+  IN NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  PCI_CONFIG_HEADER *CfgHdr;
+  UINTN             stat;
+  UINTN             rx_size;
+  UINTN             tx_size;
+
+  if (AdapterInfo->MemoryLength < MEMORY_NEEDED) {
+    return PXE_STATCODE_NOT_ENOUGH_MEMORY;
+  }
+
+  stat = MapIt (
+          AdapterInfo,
+          AdapterInfo->MemoryPtr,
+          AdapterInfo->MemoryLength,
+          TO_AND_FROM_DEVICE,
+          (UINT64)(UINTN) &AdapterInfo->Mapped_MemoryPtr
+          );
+
+  if (stat != 0) {
+    return stat;
+  }
+
+  CfgHdr = (PCI_CONFIG_HEADER *) &(AdapterInfo->Config[0]);
+
+  //
+  // fill in the ioaddr, int... from the config space
+  //
+  AdapterInfo->int_num = CfgHdr->int_line;
+
+  //
+  // we don't need to validate integer number, what if they don't want to assign one?
+  // if (AdapterInfo->int_num == 0 || AdapterInfo->int_num == 0xff)
+  // return PXE_STATCODE_DEVICE_FAILURE;
+  //
+  AdapterInfo->ioaddr       = 0;
+  AdapterInfo->VendorID     = CfgHdr->VendorID;
+  AdapterInfo->DeviceID     = CfgHdr->DeviceID;
+  AdapterInfo->RevID        = CfgHdr->RevID;
+  AdapterInfo->SubVendorID  = CfgHdr->SubVendorID;
+  AdapterInfo->SubSystemID  = CfgHdr->SubSystemID;
+  AdapterInfo->flash_addr   = 0;
+
+  //
+  // Read the station address EEPROM before doing the reset.
+  // Perhaps this should even be done before accepting the device,
+  // then we wouldn't have a device name with which to report the error.
+  //
+  if (E100bReadEepromAndStationAddress (AdapterInfo) != 0) {
+    return PXE_STATCODE_DEVICE_FAILURE;
+
+  }
+  //
+  // ## calculate the buffer #s depending on memory given
+  // ## calculate the rx and tx ring pointers
+  //
+
+  AdapterInfo->TxBufCnt       = TX_BUFFER_COUNT;
+  AdapterInfo->RxBufCnt       = RX_BUFFER_COUNT;
+  rx_size                     = (AdapterInfo->RxBufCnt * sizeof (RxFD));
+  tx_size                     = (AdapterInfo->TxBufCnt * sizeof (TxCB));
+  AdapterInfo->rx_ring        = (RxFD *) (UINTN) (AdapterInfo->MemoryPtr);
+  AdapterInfo->tx_ring        = (TxCB *) (UINTN) (AdapterInfo->MemoryPtr + rx_size);
+  AdapterInfo->statistics     = (struct speedo_stats *) (UINTN) (AdapterInfo->MemoryPtr + rx_size + tx_size);
+
+  AdapterInfo->rx_phy_addr    = AdapterInfo->Mapped_MemoryPtr;
+  AdapterInfo->tx_phy_addr    = AdapterInfo->Mapped_MemoryPtr + rx_size;
+  AdapterInfo->stat_phy_addr  = AdapterInfo->tx_phy_addr + tx_size;
+
+  //
+  // auto detect.
+  //
+  AdapterInfo->PhyAddress     = 0xFF;
+  AdapterInfo->Rx_Filter            = PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
+  AdapterInfo->Receive_Started      = FALSE;
+  AdapterInfo->mcast_list.list_len  = 0;
+  return InitializeChip (AdapterInfo);
+}
+
+
+/**
+  Sets the interrupt state for the NIC.
+
+  @param  AdapterInfo                     Pointer to the NIC data structure
+                                          information which the UNDI driver is
+                                          layering on..
+
+  @retval 0                               Successful
+
+**/
+UINT8
+E100bSetInterruptState (
+  IN NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  //
+  // don't set receive interrupt if receiver is disabled...
+  //
+  UINT16  cmd_word;
+
+  if ((AdapterInfo->int_mask & PXE_OPFLAGS_INTERRUPT_RECEIVE) != 0) {
+    cmd_word = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBCmd);
+    cmd_word &= ~INT_MASK;
+    OutWord (AdapterInfo, cmd_word, AdapterInfo->ioaddr + SCBCmd);
+  } else {
+    //
+    // disable ints, should not be given for SW Int.
+    //
+    OutWord (AdapterInfo, INT_MASK, AdapterInfo->ioaddr + SCBCmd);
+  }
+
+  if ((AdapterInfo->int_mask & PXE_OPFLAGS_INTERRUPT_SOFTWARE) != 0) {
+    //
+    // reset the bit in our mask, it is only one time!!
+    //
+    AdapterInfo->int_mask &= ~(PXE_OPFLAGS_INTERRUPT_SOFTWARE);
+    cmd_word = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBCmd);
+    cmd_word |= DRVR_INT;
+    OutWord (AdapterInfo, cmd_word, AdapterInfo->ioaddr + SCBCmd);
+  }
+
+  return 0;
+}
+//
+// we are not going to disable broadcast for the WOL's sake!
+//
+
+/**
+  Instructs the NIC to start receiving packets.
+
+  @param  AdapterInfo                     Pointer to the NIC data structure
+                                          information which the UNDI driver is
+                                          layering on.. new_filter
+                                              - cpb                             -
+                                          cpbsize                         -
+
+  @retval 0                               Successful
+  @retval -1                              Already Started
+
+**/
+UINTN
+E100bSetfilter (
+  NIC_DATA_INSTANCE *AdapterInfo,
+  UINT16            new_filter,
+  UINT64            cpb,
+  UINT32            cpbsize
+  )
+{
+  PXE_CPB_RECEIVE_FILTERS *mc_list = (PXE_CPB_RECEIVE_FILTERS *) (UINTN)cpb;
+  UINT16                  cfg_flt;
+  UINT16                  old_filter;
+  UINT16                  Index;
+  UINT16                  Index2;
+  UINT16                  mc_count;
+  TxCB                    *cmd_ptr;
+  struct MC_CB_STRUCT     *data_ptr;
+  UINT16                  mc_byte_cnt;
+
+  old_filter  = AdapterInfo->Rx_Filter;
+
+  //
+  // only these bits need a change in the configuration
+  // actually change in bcast requires configure but we ignore that change
+  //
+  cfg_flt = PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS |
+            PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;
+
+  if ((old_filter & cfg_flt) != (new_filter & cfg_flt)) {
+    XmitWaitForCompletion (AdapterInfo);
+
+    if (AdapterInfo->Receive_Started) {
+      StopRU (AdapterInfo);
+    }
+
+    AdapterInfo->Rx_Filter = (UINT8) (new_filter | PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST);
+    Configure (AdapterInfo);
+  }
+
+  //
+  // check if mcast setting changed
+  //
+  if ( ((new_filter & PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) !=
+       (old_filter & PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) ) ||
+       (mc_list != NULL) ) {
+
+
+    if (mc_list != NULL) {
+      mc_count = AdapterInfo->mcast_list.list_len = (UINT16) (cpbsize / PXE_MAC_LENGTH);
+
+      for (Index = 0; (Index < mc_count && Index < MAX_MCAST_ADDRESS_CNT); Index++) {
+        for (Index2 = 0; Index2 < PXE_MAC_LENGTH; Index2++) {
+          AdapterInfo->mcast_list.mc_list[Index][Index2] = mc_list->MCastList[Index][Index2];
+        }
+      }
+    }
+
+    //
+    // are we setting the list or resetting??
+    //
+    if ((new_filter & PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) != 0) {
+      //
+      // we are setting a new list!
+      //
+      mc_count = AdapterInfo->mcast_list.list_len;
+      //
+      // count should be the actual # of bytes in the list
+      // so multiply this with 6
+      //
+      mc_byte_cnt = (UINT16) ((mc_count << 2) + (mc_count << 1));
+      AdapterInfo->Rx_Filter |= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST;
+    } else {
+      //
+      // disabling the list in the NIC.
+      //
+      mc_byte_cnt = mc_count = 0;
+      AdapterInfo->Rx_Filter &= (~PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST);
+    }
+
+    //
+    // before issuing any new command!
+    //
+    XmitWaitForCompletion (AdapterInfo);
+
+    if (AdapterInfo->Receive_Started) {
+      StopRU (AdapterInfo);
+
+    }
+
+    cmd_ptr = GetFreeCB (AdapterInfo);
+    if (cmd_ptr == NULL) {
+      return PXE_STATCODE_QUEUE_FULL;
+    }
+    //
+    // fill the command structure and issue
+    //
+    data_ptr = (struct MC_CB_STRUCT *) (&cmd_ptr->PhysTBDArrayAddres);
+    //
+    // first 2 bytes are the count;
+    //
+    data_ptr->count = mc_byte_cnt;
+    for (Index = 0; Index < mc_count; Index++) {
+      for (Index2 = 0; Index2 < PXE_HWADDR_LEN_ETHER; Index2++) {
+        data_ptr->m_list[Index][Index2] = AdapterInfo->mcast_list.mc_list[Index][Index2];
+      }
+    }
+
+    cmd_ptr->cb_header.command  = CmdSuspend | CmdMulticastList;
+    cmd_ptr->cb_header.status   = 0;
+
+    BlockIt (AdapterInfo, TRUE);
+    IssueCB (AdapterInfo, cmd_ptr);
+    wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
+
+    BlockIt (AdapterInfo, FALSE);
+
+    CommandWaitForCompletion (cmd_ptr, AdapterInfo);
+
+    cmd_ptr->PhysTBDArrayAddres = cmd_ptr->PhysArrayAddr;
+    cmd_ptr->ByteCount = cmd_ptr->Threshold = cmd_ptr->TBDCount = 0;
+    //
+    // fields beyond the immediatedata are assumed to be safe
+    // add the CB to the free list again
+    //
+    SetFreeCB (AdapterInfo, cmd_ptr);
+  }
+
+  if (new_filter != 0) {
+    //
+    // enable unicast and start the RU
+    //
+    AdapterInfo->Rx_Filter = (UINT8) (AdapterInfo->Rx_Filter | (new_filter | PXE_OPFLAGS_RECEIVE_FILTER_UNICAST));
+    StartRU (AdapterInfo);
+  } else {
+    //
+    // may be disabling everything!
+    //
+    if (AdapterInfo->Receive_Started) {
+      StopRU (AdapterInfo);
+    }
+
+    AdapterInfo->Rx_Filter |= (~PXE_OPFLAGS_RECEIVE_FILTER_UNICAST);
+  }
+
+  return 0;
+}
+
+
+/**
+  TODO: Add function description
+
+  @param  AdapterInfo                     TODO: add argument description
+  @param  cpb                             TODO: add argument description
+  @param  opflags                         TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+UINTN
+E100bTransmit (
+  NIC_DATA_INSTANCE *AdapterInfo,
+  UINT64            cpb,
+  UINT16            opflags
+  )
+{
+  PXE_CPB_TRANSMIT_FRAGMENTS  *tx_ptr_f;
+  PXE_CPB_TRANSMIT            *tx_ptr_1;
+  TxCB                        *tcb_ptr;
+  UINT64                      Tmp_ptr;
+  UINTN                       stat;
+  INT32                       Index;
+  UINT16                      wait_sec;
+
+  tx_ptr_1  = (PXE_CPB_TRANSMIT *) (UINTN) cpb;
+  tx_ptr_f  = (PXE_CPB_TRANSMIT_FRAGMENTS *) (UINTN) cpb;
+  Tmp_ptr = 0;
+
+  //
+  // stop reentrancy here
+  //
+  if (AdapterInfo->in_transmit) {
+    return PXE_STATCODE_BUSY;
+
+  }
+
+  AdapterInfo->in_transmit = TRUE;
+
+  //
+  // Prevent interrupts from changing the Tx ring from underneath us.
+  //
+  // Calculate the Tx descriptor entry.
+  //
+  if ((tcb_ptr = GetFreeCB (AdapterInfo)) == NULL) {
+    AdapterInfo->in_transmit = FALSE;
+    return PXE_STATCODE_QUEUE_FULL;
+  }
+
+  AdapterInfo->TxTotals++;
+
+  tcb_ptr->cb_header.command  = (CmdSuspend | CmdTx | CmdTxFlex);
+  tcb_ptr->cb_header.status   = 0;
+
+  //
+  // no immediate data, set EOF in the ByteCount
+  //
+  tcb_ptr->ByteCount = 0x8000;
+
+  //
+  // The data region is always in one buffer descriptor, Tx FIFO
+  // threshold of 256.
+  // 82557 multiplies the threashold value by 8, so give 256/8
+  //
+  tcb_ptr->Threshold = 32;
+  if ((opflags & PXE_OPFLAGS_TRANSMIT_FRAGMENTED) != 0) {
+
+    if (tx_ptr_f->FragCnt > MAX_XMIT_FRAGMENTS) {
+      SetFreeCB (AdapterInfo, tcb_ptr);
+      AdapterInfo->in_transmit = FALSE;
+      return PXE_STATCODE_INVALID_PARAMETER;
+    }
+
+    tcb_ptr->TBDCount = (UINT8) tx_ptr_f->FragCnt;
+
+    for (Index = 0; Index < tx_ptr_f->FragCnt; Index++) {
+      stat = MapIt (
+              AdapterInfo,
+              tx_ptr_f->FragDesc[Index].FragAddr,
+              tx_ptr_f->FragDesc[Index].FragLen,
+              TO_DEVICE,
+              (UINT64)(UINTN) &Tmp_ptr
+              );
+      if (stat != 0) {
+        SetFreeCB (AdapterInfo, tcb_ptr);
+        AdapterInfo->in_transmit = FALSE;
+        return PXE_STATCODE_INVALID_PARAMETER;
+      }
+
+      tcb_ptr->TBDArray[Index].phys_buf_addr  = (UINT32) Tmp_ptr;
+      tcb_ptr->TBDArray[Index].buf_len        = tx_ptr_f->FragDesc[Index].FragLen;
+    }
+
+    tcb_ptr->free_data_ptr = tx_ptr_f->FragDesc[0].FragAddr;
+
+  } else {
+    //
+    // non fragmented case
+    //
+    tcb_ptr->TBDCount = 1;
+    stat = MapIt (
+            AdapterInfo,
+            tx_ptr_1->FrameAddr,
+            tx_ptr_1->DataLen + tx_ptr_1->MediaheaderLen,
+            TO_DEVICE,
+            (UINT64)(UINTN) &Tmp_ptr
+            );
+    if (stat != 0) {
+      SetFreeCB (AdapterInfo, tcb_ptr);
+      AdapterInfo->in_transmit = FALSE;
+      return PXE_STATCODE_INVALID_PARAMETER;
+    }
+
+    tcb_ptr->TBDArray[0].phys_buf_addr  = (UINT32) (Tmp_ptr);
+    tcb_ptr->TBDArray[0].buf_len        = tx_ptr_1->DataLen + tx_ptr_1->MediaheaderLen;
+    tcb_ptr->free_data_ptr              = tx_ptr_1->FrameAddr;
+  }
+
+  //
+  // must wait for previous command completion only if it was a non-transmit
+  //
+  BlockIt (AdapterInfo, TRUE);
+  IssueCB (AdapterInfo, tcb_ptr);
+  BlockIt (AdapterInfo, FALSE);
+
+  //
+  // see if we need to wait for completion here
+  //
+  if ((opflags & PXE_OPFLAGS_TRANSMIT_BLOCK) != 0) {
+    //
+    // don't wait for more than 1 second!!!
+    //
+    wait_sec = 1000;
+    while (tcb_ptr->cb_header.status == 0) {
+      DelayIt (AdapterInfo, 10);
+      wait_sec--;
+      if (wait_sec == 0) {
+        break;
+      }
+    }
+    //
+    // we need to un-map any mapped buffers here
+    //
+    if ((opflags & PXE_OPFLAGS_TRANSMIT_FRAGMENTED) != 0) {
+
+      for (Index = 0; Index < tx_ptr_f->FragCnt; Index++) {
+        Tmp_ptr = tcb_ptr->TBDArray[Index].phys_buf_addr;
+        UnMapIt (
+          AdapterInfo,
+          tx_ptr_f->FragDesc[Index].FragAddr,
+          tx_ptr_f->FragDesc[Index].FragLen,
+          TO_DEVICE,
+          (UINT64) Tmp_ptr
+          );
+      }
+    } else {
+      Tmp_ptr = tcb_ptr->TBDArray[0].phys_buf_addr;
+      UnMapIt (
+        AdapterInfo,
+        tx_ptr_1->FrameAddr,
+        tx_ptr_1->DataLen + tx_ptr_1->MediaheaderLen,
+        TO_DEVICE,
+        (UINT64) Tmp_ptr
+        );
+    }
+
+    if (tcb_ptr->cb_header.status == 0) {
+      SetFreeCB (AdapterInfo, tcb_ptr);
+      AdapterInfo->in_transmit = FALSE;
+      return PXE_STATCODE_DEVICE_FAILURE;
+    }
+
+    SetFreeCB (AdapterInfo, tcb_ptr);
+  }
+  //
+  // CB will be set free later in get_status (or when we run out of xmit buffers
+  //
+  AdapterInfo->in_transmit = FALSE;
+
+  return 0;
+}
+
+
+/**
+  TODO: Add function description
+
+  @param  AdapterInfo                     TODO: add argument description
+  @param  cpb                             TODO: add argument description
+  @param  db                              TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+UINTN
+E100bReceive (
+  NIC_DATA_INSTANCE *AdapterInfo,
+  UINT64            cpb,
+  UINT64            db
+  )
+{
+  PXE_CPB_RECEIVE *rx_cpbptr;
+  PXE_DB_RECEIVE  *rx_dbptr;
+  RxFD            *rx_ptr;
+  INT32           status;
+  INT32           Index;
+  UINT16          pkt_len;
+  UINT16          ret_code;
+  PXE_FRAME_TYPE  pkt_type;
+  UINT16          Tmp_len;
+  EtherHeader     *hdr_ptr;
+  ret_code  = PXE_STATCODE_NO_DATA;
+  pkt_type  = PXE_FRAME_TYPE_NONE;
+  status    = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBStatus);
+  AdapterInfo->Int_Status = (UINT16) (AdapterInfo->Int_Status | status);
+  //
+  // acknoledge the interrupts
+  //
+  OutWord (AdapterInfo, (UINT16) (status & 0xfc00), (UINT32) (AdapterInfo->ioaddr + SCBStatus));
+
+  //
+  // include the prev ints as well
+  //
+  status = AdapterInfo->Int_Status;
+  rx_cpbptr = (PXE_CPB_RECEIVE *) (UINTN) cpb;
+  rx_dbptr  = (PXE_DB_RECEIVE *) (UINTN) db;
+
+  rx_ptr    = &AdapterInfo->rx_ring[AdapterInfo->cur_rx_ind];
+
+  //
+  // be in a loop just in case (we may drop a pkt)
+  //
+  while ((status = rx_ptr->cb_header.status) & RX_COMPLETE) {
+
+    AdapterInfo->RxTotals++;
+    //
+    // If we own the next entry, it's a new packet. Send it up.
+    //
+    if (rx_ptr->forwarded) {
+      goto FreeRFD;
+
+    }
+
+    //
+    // discard bad frames
+    //
+
+    //
+    // crc, align, dma overrun, too short, receive error (v22 no coll)
+    //
+    if ((status & 0x0D90) != 0) {
+      goto FreeRFD;
+
+    }
+
+    //
+    // make sure the status is OK
+    //
+    if ((status & 0x02000) == 0) {
+      goto FreeRFD;
+    }
+
+    pkt_len = (UINT16) (rx_ptr->ActualCount & 0x3fff);
+
+    if (pkt_len != 0) {
+
+      Tmp_len = pkt_len;
+      if (pkt_len > rx_cpbptr->BufferLen) {
+        Tmp_len = (UINT16) rx_cpbptr->BufferLen;
+      }
+
+      CopyMem ((INT8 *) (UINTN) rx_cpbptr->BufferAddr, (INT8 *) &rx_ptr->RFDBuffer, Tmp_len);
+
+      hdr_ptr = (EtherHeader *) &rx_ptr->RFDBuffer;
+      //
+      // fill the CDB and break the loop
+      //
+
+      //
+      // includes header
+      //
+      rx_dbptr->FrameLen = pkt_len;
+      rx_dbptr->MediaHeaderLen = PXE_MAC_HEADER_LEN_ETHER;
+
+      for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
+        if (hdr_ptr->dest_addr[Index] != AdapterInfo->CurrentNodeAddress[Index]) {
+          break;
+        }
+      }
+
+      if (Index >= PXE_HWADDR_LEN_ETHER) {
+        pkt_type = PXE_FRAME_TYPE_UNICAST;
+      } else {
+        for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
+          if (hdr_ptr->dest_addr[Index] != AdapterInfo->BroadcastNodeAddress[Index]) {
+            break;
+          }
+        }
+
+        if (Index >= PXE_HWADDR_LEN_ETHER) {
+          pkt_type = PXE_FRAME_TYPE_BROADCAST;
+        } else {
+          if ((hdr_ptr->dest_addr[0] & 1) == 1) {
+            //
+            // mcast
+            //
+
+            pkt_type = PXE_FRAME_TYPE_FILTERED_MULTICAST;
+          } else {
+            pkt_type = PXE_FRAME_TYPE_PROMISCUOUS;
+          }
+        }
+      }
+
+      rx_dbptr->Type      = pkt_type;
+      rx_dbptr->Protocol  = hdr_ptr->type;
+
+      for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
+        rx_dbptr->SrcAddr[Index]  = hdr_ptr->src_addr[Index];
+        rx_dbptr->DestAddr[Index] = hdr_ptr->dest_addr[Index];
+      }
+
+      rx_ptr->forwarded = TRUE;
+      //
+      // success
+      //
+      ret_code          = 0;
+      Recycle_RFD (AdapterInfo, AdapterInfo->cur_rx_ind);
+      AdapterInfo->cur_rx_ind++;
+      if (AdapterInfo->cur_rx_ind == AdapterInfo->RxBufCnt) {
+        AdapterInfo->cur_rx_ind = 0;
+      }
+      break;
+    }
+
+FreeRFD:
+    Recycle_RFD (AdapterInfo, AdapterInfo->cur_rx_ind);
+    AdapterInfo->cur_rx_ind++;
+    if (AdapterInfo->cur_rx_ind == AdapterInfo->RxBufCnt) {
+      AdapterInfo->cur_rx_ind = 0;
+    }
+
+    rx_ptr = &AdapterInfo->rx_ring[AdapterInfo->cur_rx_ind];
+  }
+
+  if (pkt_type == PXE_FRAME_TYPE_NONE) {
+    AdapterInfo->Int_Status &= (~SCB_STATUS_FR);
+  }
+
+  status = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBStatus);
+  if ((status & SCB_RUS_NO_RESOURCES) != 0) {
+    //
+    // start the receive unit here!
+    // leave all the filled frames,
+    //
+    SetupReceiveQueues (AdapterInfo);
+    OutLong (AdapterInfo, (UINT32) AdapterInfo->rx_phy_addr, AdapterInfo->ioaddr + SCBPointer);
+    OutWord (AdapterInfo, RX_START, AdapterInfo->ioaddr + SCBCmd);
+    AdapterInfo->cur_rx_ind = 0;
+  }
+
+  return ret_code;
+}
+
+
+/**
+  TODO: Add function description
+
+  @param  AdapterInfo                     TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+INT16
+E100bReadEepromAndStationAddress (
+  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  INT32   Index;
+  INT32   Index2;
+  UINT16  sum;
+  UINT16  eeprom_len;
+  UINT8   addr_len;
+  UINT16  *eedata;
+
+  eedata    = (UINT16 *) (&AdapterInfo->NVData[0]);
+
+  sum       = 0;
+  addr_len  = E100bGetEepromAddrLen (AdapterInfo);
+
+  //
+  // in words
+  //
+  AdapterInfo->NVData_Len = eeprom_len = (UINT16) (1 << addr_len);
+  for (Index2 = 0, Index = 0; ((Index2 < PXE_MAC_LENGTH - 1) && (Index < eeprom_len)); Index++) {
+    UINT16  value;
+    value         = E100bReadEeprom (AdapterInfo, Index, addr_len);
+    eedata[Index] = value;
+    sum           = (UINT16) (sum + value);
+    if (Index < 3) {
+      AdapterInfo->PermNodeAddress[Index2++]  = (UINT8) value;
+      AdapterInfo->PermNodeAddress[Index2++]  = (UINT8) (value >> 8);
+    }
+  }
+
+  if (sum != 0xBABA) {
+    return -1;
+  }
+
+  for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
+    AdapterInfo->CurrentNodeAddress[Index] = AdapterInfo->PermNodeAddress[Index];
+  }
+
+  for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
+    AdapterInfo->BroadcastNodeAddress[Index] = 0xff;
+  }
+
+  for (Index = PXE_HWADDR_LEN_ETHER; Index < PXE_MAC_LENGTH; Index++) {
+    AdapterInfo->CurrentNodeAddress[Index]    = 0;
+    AdapterInfo->PermNodeAddress[Index]       = 0;
+    AdapterInfo->BroadcastNodeAddress[Index]  = 0;
+  }
+
+  return 0;
+}
+
+//
+//  CBList is a circular linked list
+//  1) When all are free, Tail->next == Head and FreeCount == # allocated
+//  2) When none are free, Tail == Head and FreeCount == 0
+//  3) when one is free, Tail == Head and Freecount == 1
+//  4) First non-Free frame is always at Tail->next
+//
+
+/**
+  TODO: Add function description
+
+  @param  AdapterInfo                     TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+UINT8
+SetupCBlink (
+  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  TxCB  *head_ptr;
+  TxCB  *tail_ptr;
+  TxCB  *cur_ptr;
+  INT32 Index;
+  UINTN array_off;
+
+  cur_ptr   = &(AdapterInfo->tx_ring[0]);
+  array_off = (UINTN) (&cur_ptr->TBDArray) - (UINTN) cur_ptr;
+  for (Index = 0; Index < AdapterInfo->TxBufCnt; Index++) {
+    cur_ptr[Index].cb_header.status   = 0;
+    cur_ptr[Index].cb_header.command  = 0;
+
+    cur_ptr[Index].PhysTCBAddress     =
+    (UINT32) AdapterInfo->tx_phy_addr + (Index * sizeof (TxCB));
+
+    cur_ptr[Index].PhysArrayAddr      = (UINT32)(cur_ptr[Index].PhysTCBAddress + array_off);
+    cur_ptr[Index].PhysTBDArrayAddres = (UINT32)(cur_ptr[Index].PhysTCBAddress + array_off);
+
+    cur_ptr->free_data_ptr = (UINT64) 0;
+
+    if (Index < AdapterInfo->TxBufCnt - 1) {
+      cur_ptr[Index].cb_header.link             = cur_ptr[Index].PhysTCBAddress + sizeof (TxCB);
+      cur_ptr[Index].NextTCBVirtualLinkPtr      = &cur_ptr[Index + 1];
+      cur_ptr[Index + 1].PrevTCBVirtualLinkPtr  = &cur_ptr[Index];
+    }
+  }
+
+  head_ptr                        = &cur_ptr[0];
+  tail_ptr                        = &cur_ptr[AdapterInfo->TxBufCnt - 1];
+  tail_ptr->cb_header.link        = head_ptr->PhysTCBAddress;
+  tail_ptr->NextTCBVirtualLinkPtr = head_ptr;
+  head_ptr->PrevTCBVirtualLinkPtr = tail_ptr;
+
+  AdapterInfo->FreeCBCount        = AdapterInfo->TxBufCnt;
+  AdapterInfo->FreeTxHeadPtr      = head_ptr;
+  //
+  // set tail of the free list, next to this would be either in use
+  // or the head itself
+  //
+  AdapterInfo->FreeTxTailPtr  = tail_ptr;
+
+  AdapterInfo->xmit_done_head = AdapterInfo->xmit_done_tail = 0;
+
+  return 0;
+}
+
+
+/**
+  TODO: Add function description
+
+  @param  AdapterInfo                     TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+TxCB *
+GetFreeCB (
+  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  TxCB  *free_cb_ptr;
+
+  //
+  // claim any hanging free CBs
+  //
+  if (AdapterInfo->FreeCBCount <= 1) {
+    CheckCBList (AdapterInfo);
+  }
+
+  //
+  // don't use up the last CB problem if the previous CB that the CU used
+  // becomes the last CB we submit because of the SUSPEND bit we set.
+  // the CU thinks it was never cleared.
+  //
+
+  if (AdapterInfo->FreeCBCount <= 1) {
+    return NULL;
+  }
+
+  BlockIt (AdapterInfo, TRUE);
+  free_cb_ptr                 = AdapterInfo->FreeTxHeadPtr;
+  AdapterInfo->FreeTxHeadPtr  = free_cb_ptr->NextTCBVirtualLinkPtr;
+  --AdapterInfo->FreeCBCount;
+  BlockIt (AdapterInfo, FALSE);
+  return free_cb_ptr;
+}
+
+
+/**
+  TODO: Add function description
+
+  @param  AdapterInfo                     TODO: add argument description
+  @param  cb_ptr                          TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+VOID
+SetFreeCB (
+  IN NIC_DATA_INSTANCE *AdapterInfo,
+  IN TxCB              *cb_ptr
+  )
+{
+  //
+  // here we assume cb are returned in the order they are taken out
+  // and we link the newly freed cb at the tail of free cb list
+  //
+  cb_ptr->cb_header.status    = 0;
+  cb_ptr->free_data_ptr       = (UINT64) 0;
+
+  AdapterInfo->FreeTxTailPtr  = cb_ptr;
+  ++AdapterInfo->FreeCBCount;
+  return ;
+}
+
+
+/**
+  TODO: Add function description
+
+  @param  ind                             TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+UINT16
+next (
+  IN UINT16 ind
+  )
+{
+  UINT16  Tmp;
+
+  Tmp = (UINT16) (ind + 1);
+  if (Tmp >= (TX_BUFFER_COUNT << 1)) {
+    Tmp = 0;
+  }
+
+  return Tmp;
+}
+
+
+/**
+  TODO: Add function description
+
+  @param  AdapterInfo                     TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+UINT16
+CheckCBList (
+  IN NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  TxCB    *Tmp_ptr;
+  UINT16  cnt;
+
+  cnt = 0;
+  while (1) {
+    Tmp_ptr = AdapterInfo->FreeTxTailPtr->NextTCBVirtualLinkPtr;
+    if ((Tmp_ptr->cb_header.status & CMD_STATUS_MASK) != 0) {
+      //
+      // check if Q is full
+      //
+      if (next (AdapterInfo->xmit_done_tail) != AdapterInfo->xmit_done_head) {
+        ASSERT (AdapterInfo->xmit_done_tail < TX_BUFFER_COUNT << 1);
+        AdapterInfo->xmit_done[AdapterInfo->xmit_done_tail] = Tmp_ptr->free_data_ptr;
+
+        UnMapIt (
+          AdapterInfo,
+          Tmp_ptr->free_data_ptr,
+          Tmp_ptr->TBDArray[0].buf_len,
+          TO_DEVICE,
+          (UINT64) Tmp_ptr->TBDArray[0].phys_buf_addr
+          );
+
+        AdapterInfo->xmit_done_tail = next (AdapterInfo->xmit_done_tail);
+      }
+
+      SetFreeCB (AdapterInfo, Tmp_ptr);
+    } else {
+      break;
+    }
+  }
+
+  return cnt;
+}
+//
+// Description : Initialize the RFD list list by linking each element together
+//               in a circular list.  The simplified memory model is used.
+//               All data is in the RFD.  The RFDs are linked together and the
+//               last one points back to the first one.  When the current RFD
+//               is processed (frame received), its EL bit is set and the EL
+//               bit in the previous RXFD is cleared.
+//               Allocation done during INIT, this is making linked list.
+//
+
+/**
+  TODO: Add function description
+
+  @param  AdapterInfo                     TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+UINT8
+SetupReceiveQueues (
+  IN NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  RxFD    *rx_ptr;
+  RxFD    *tail_ptr;
+  UINT16  Index;
+
+  AdapterInfo->cur_rx_ind = 0;
+  rx_ptr                  = (&AdapterInfo->rx_ring[0]);
+
+  for (Index = 0; Index < AdapterInfo->RxBufCnt; Index++) {
+    rx_ptr[Index].cb_header.status  = 0;
+    rx_ptr[Index].cb_header.command = 0;
+    rx_ptr[Index].RFDSize           = RX_BUFFER_SIZE;
+    rx_ptr[Index].ActualCount       = 0;
+    //
+    // RBDs not used, simple memory model
+    //
+    rx_ptr[Index].rx_buf_addr       = (UINT32) (-1);
+
+    //
+    // RBDs not used, simple memory model
+    //
+    rx_ptr[Index].forwarded = FALSE;
+
+    //
+    // don't use Tmp_ptr if it is beyond the last one
+    //
+    if (Index < AdapterInfo->RxBufCnt - 1) {
+      rx_ptr[Index].cb_header.link = (UINT32) AdapterInfo->rx_phy_addr + ((Index + 1) * sizeof (RxFD));
+    }
+  }
+
+  tail_ptr                    = (&AdapterInfo->rx_ring[AdapterInfo->RxBufCnt - 1]);
+  tail_ptr->cb_header.link    = (UINT32) AdapterInfo->rx_phy_addr;
+
+  //
+  // set the EL bit
+  //
+  tail_ptr->cb_header.command = 0xC000;
+  AdapterInfo->RFDTailPtr = tail_ptr;
+  return 0;
+}
+
+
+/**
+  TODO: Add function description
+
+  @param  AdapterInfo                     TODO: add argument description
+  @param  rx_index                        TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+VOID
+Recycle_RFD (
+  IN NIC_DATA_INSTANCE *AdapterInfo,
+  IN UINT16            rx_index
+  )
+{
+  RxFD  *rx_ptr;
+  RxFD  *tail_ptr;
+  //
+  // change the EL bit and change the AdapterInfo->RxTailPtr
+  // rx_ptr is assumed to be the head of the Q
+  // AdapterInfo->rx_forwarded[rx_index] = FALSE;
+  //
+  rx_ptr                    = &AdapterInfo->rx_ring[rx_index];
+  tail_ptr                  = AdapterInfo->RFDTailPtr;
+  //
+  // set el_bit and suspend bit
+  //
+  rx_ptr->cb_header.command = 0xc000;
+  rx_ptr->cb_header.status    = 0;
+  rx_ptr->ActualCount         = 0;
+  rx_ptr->forwarded           = FALSE;
+  AdapterInfo->RFDTailPtr     = rx_ptr;
+  //
+  // resetting the el_bit.
+  //
+  tail_ptr->cb_header.command = 0;
+  //
+  // check the receive unit, fix if there is any problem
+  //
+  return ;
+}
+//
+// Serial EEPROM section.
+//
+//  EEPROM_Ctrl bits.
+//
+#define EE_SHIFT_CLK  0x01  /* EEPROM shift clock. */
+#define EE_CS         0x02  /* EEPROM chip select. */
+#define EE_DI         0x04  /* EEPROM chip data in. */
+#define EE_WRITE_0    0x01
+#define EE_WRITE_1    0x05
+#define EE_DO         0x08  /* EEPROM chip data out. */
+#define EE_ENB        (0x4800 | EE_CS)
+
+//
+// Delay between EEPROM clock transitions.
+// This will actually work with no delay on 33Mhz PCI.
+//
+#define eeprom_delay(nanosec) DelayIt (AdapterInfo, nanosec);
+
+//
+// The EEPROM commands include the alway-set leading bit.
+//
+#define EE_WRITE_CMD  5 // 101b
+#define EE_READ_CMD   6 // 110b
+#define EE_ERASE_CMD  (7 << 6)
+
+VOID
+shift_bits_out (
+  IN NIC_DATA_INSTANCE *AdapterInfo,
+  IN UINT16            val,
+  IN UINT8             num_bits
+  )
+/*++
+
+Routine Description:
+
+  TODO: Add function description
+
+Arguments:
+
+  AdapterInfo - TODO: add argument description
+  val         - TODO: add argument description
+  num_bits    - TODO: add argument description
+
+Returns:
+
+  TODO: add return values
+
+--*/
+{
+  INT32   Index;
+  UINT8   Tmp;
+  UINT32  EEAddr;
+
+  EEAddr = AdapterInfo->ioaddr + SCBeeprom;
+
+  for (Index = num_bits; Index >= 0; Index--) {
+    INT16 dataval;
+
+    //
+    // will be 0 or 4
+    //
+    dataval = (INT16) ((val & (1 << Index)) ? EE_DI : 0);
+
+    //
+    // mask off the data_in bit
+    //
+    Tmp = (UINT8) (InByte (AdapterInfo, EEAddr) &~EE_DI);
+    Tmp = (UINT8) (Tmp | dataval);
+    OutByte (AdapterInfo, Tmp, EEAddr);
+    eeprom_delay (100);
+    //
+    // raise the eeprom clock
+    //
+    OutByte (AdapterInfo, (UINT8) (Tmp | EE_SHIFT_CLK), EEAddr);
+    eeprom_delay (150);
+    //
+    // lower the eeprom clock
+    //
+    OutByte (AdapterInfo, (UINT8) (Tmp &~EE_SHIFT_CLK), EEAddr);
+    eeprom_delay (150);
+  }
+}
+
+
+/**
+  TODO: Add function description
+
+  @param  AdapterInfo                     TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+UINT16
+shift_bits_in (
+  IN NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  UINT8   Tmp;
+  INT32   Index;
+  UINT16  retval;
+  UINT32  EEAddr;
+
+  EEAddr  = AdapterInfo->ioaddr + SCBeeprom;
+
+  retval  = 0;
+  for (Index = 15; Index >= 0; Index--) {
+    //
+    // raise the clock
+    //
+
+    //
+    // mask off the data_in bit
+    //
+    Tmp = InByte (AdapterInfo, EEAddr);
+    OutByte (AdapterInfo, (UINT8) (Tmp | EE_SHIFT_CLK), EEAddr);
+    eeprom_delay (100);
+    Tmp     = InByte (AdapterInfo, EEAddr);
+    retval  = (UINT16) ((retval << 1) | ((Tmp & EE_DO) ? 1 : 0));
+    //
+    // lower the clock
+    //
+    OutByte (AdapterInfo, (UINT8) (Tmp &~EE_SHIFT_CLK), EEAddr);
+    eeprom_delay (100);
+  }
+
+  return retval;
+}
+
+
+/**
+  This routine sets the EEPROM lockout bit to gain exclusive access to the
+  eeprom. the access bit is the most significant bit in the General Control
+  Register 2 in the SCB space.
+
+  @param  AdapterInfo                     Pointer to the NIC data structure
+                                          information which the UNDI driver is
+                                          layering on..
+
+  @retval TRUE                            if it got the access
+  @retval FALSE                           if it fails to get the exclusive access
+
+**/
+BOOLEAN
+E100bSetEepromLockOut (
+  IN NIC_DATA_INSTANCE  *AdapterInfo
+  )
+{
+  UINTN wait;
+  UINT8 tmp;
+
+  if ((AdapterInfo->DeviceID == D102_DEVICE_ID) ||
+      (AdapterInfo->RevID >= D102_REVID)) {
+
+    wait = 500;
+
+    while (wait--) {
+
+      tmp = InByte (AdapterInfo, AdapterInfo->ioaddr + SCBGenCtrl2);
+      tmp |= GCR2_EEPROM_ACCESS_SEMAPHORE;
+      OutByte (AdapterInfo, tmp, AdapterInfo->ioaddr + SCBGenCtrl2);
+
+      DelayIt (AdapterInfo, 50);
+      tmp = InByte (AdapterInfo, AdapterInfo->ioaddr + SCBGenCtrl2);
+
+      if (tmp & GCR2_EEPROM_ACCESS_SEMAPHORE) {
+        return TRUE;
+      }
+    }
+
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+
+/**
+  This routine Resets the EEPROM lockout bit to giveup access to the
+  eeprom. the access bit is the most significant bit in the General Control
+  Register 2 in the SCB space.
+
+  @param  AdapterInfo                     Pointer to the NIC data structure
+                                          information which the UNDI driver is
+                                          layering on..
+
+  @return None
+
+**/
+VOID
+E100bReSetEepromLockOut (
+  IN NIC_DATA_INSTANCE  *AdapterInfo
+  )
+{
+  UINT8 tmp;
+
+  if ((AdapterInfo->DeviceID == D102_DEVICE_ID) ||
+      (AdapterInfo->RevID >= D102_REVID)) {
+
+    tmp = InByte (AdapterInfo, AdapterInfo->ioaddr + SCBGenCtrl2);
+    tmp &= ~(GCR2_EEPROM_ACCESS_SEMAPHORE);
+    OutByte (AdapterInfo, tmp, AdapterInfo->ioaddr + SCBGenCtrl2);
+
+    DelayIt (AdapterInfo, 50);
+  }
+}
+
+
+/**
+  Using the NIC data structure information, read the EEPROM to get a Word of data for the MAC address.
+
+  @param  AdapterInfo                     Pointer to the NIC data structure
+                                          information which the UNDI driver is
+                                          layering on..
+  @param  Location                        Word offset into the MAC address to read.
+  @param  AddrLen                         Number of bits of address length.
+
+  @retval RetVal                          The word read from the EEPROM.
+
+**/
+UINT16
+E100bReadEeprom (
+  IN NIC_DATA_INSTANCE  *AdapterInfo,
+  IN INT32              Location,
+  IN UINT8              AddrLen
+  )
+{
+  UINT16  RetVal;
+  UINT8   Tmp;
+
+  UINT32  EEAddr;
+  UINT16  ReadCmd;
+
+  EEAddr  = AdapterInfo->ioaddr + SCBeeprom;
+  ReadCmd = (UINT16) (Location | (EE_READ_CMD << AddrLen));
+
+  RetVal  = 0;
+
+  //
+  // get exclusive access to the eeprom first!
+  //
+  E100bSetEepromLockOut (AdapterInfo);
+
+  //
+  // eeprom control reg bits: x,x,x,x,DO,DI,CS,SK
+  // to write the opcode+data value out one bit at a time in DI starting at msb
+  // and then out a 1 to sk, wait, out 0 to SK and wait
+  // repeat this for all the bits to be written
+  //
+
+  //
+  // 11110010b
+  //
+  Tmp = (UINT8) (InByte (AdapterInfo, EEAddr) & 0xF2);
+  OutByte (AdapterInfo, (UINT8) (Tmp | EE_CS), EEAddr);
+
+  //
+  // 3 for the read opcode 110b
+  //
+  shift_bits_out (AdapterInfo, ReadCmd, (UINT8) (3 + AddrLen));
+
+  //
+  // read the eeprom word one bit at a time
+  //
+  RetVal = shift_bits_in (AdapterInfo);
+
+  //
+  // Terminate the EEPROM access and leave eeprom in a clean state.
+  //
+  Tmp = InByte (AdapterInfo, EEAddr);
+  Tmp &= ~(EE_CS | EE_DI);
+  OutByte (AdapterInfo, Tmp, EEAddr);
+
+  //
+  // raise the clock and lower the eeprom shift clock
+  //
+  OutByte (AdapterInfo, (UINT8) (Tmp | EE_SHIFT_CLK), EEAddr);
+  eeprom_delay (100);
+
+  OutByte (AdapterInfo, (UINT8) (Tmp &~EE_SHIFT_CLK), EEAddr);
+  eeprom_delay (100);
+
+  //
+  // giveup access to the eeprom
+  //
+  E100bReSetEepromLockOut (AdapterInfo);
+
+  return RetVal;
+}
+
+
+/**
+  Using the NIC data structure information, read the EEPROM to determine how many bits of address length
+  this EEPROM is in Words.
+
+  @param  AdapterInfo                     Pointer to the NIC data structure
+                                          information which the UNDI driver is
+                                          layering on..
+
+  @retval RetVal                          The word read from the EEPROM.
+
+**/
+UINT8
+E100bGetEepromAddrLen (
+  IN NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  UINT8   Tmp;
+  UINT8   AddrLen;
+  UINT32  EEAddr;
+  //
+  // assume 64word eeprom (so,6 bits of address_length)
+  //
+  UINT16  ReadCmd;
+
+  EEAddr  = AdapterInfo->ioaddr + SCBeeprom;
+  ReadCmd = (EE_READ_CMD << 6);
+
+  //
+  // get exclusive access to the eeprom first!
+  //
+  E100bSetEepromLockOut (AdapterInfo);
+
+  //
+  // address we are trying to read is 0
+  // eeprom control reg bits: x,x,x,x,DO,,DI,,CS,SK
+  // to write the opcode+data value out one bit at a time in DI starting at msb
+  // and then out a 1 to sk, wait, out 0 to SK and wait
+  // repeat this for all the bits to be written
+  //
+  Tmp = (UINT8) (InByte (AdapterInfo, EEAddr) & 0xF2);
+
+  //
+  // enable eeprom access
+  //
+  OutByte (AdapterInfo, (UINT8) (Tmp | EE_CS), EEAddr);
+
+  //
+  // 3 for opcode, 6 for the default address len
+  //
+  shift_bits_out (AdapterInfo, ReadCmd, (UINT8) (3 + 6));
+
+  //
+  // (in case of a 64 word eeprom).
+  // read the "dummy zero" from EE_DO to say that the address we wrote
+  // (six 0s) is accepted, write more zeros (until 8) to get a "dummy zero"
+  //
+
+  //
+  // assume the smallest
+  //
+  AddrLen = 6;
+  Tmp     = InByte (AdapterInfo, EEAddr);
+  while ((AddrLen < 8) && ((Tmp & EE_DO) != 0)) {
+    OutByte (AdapterInfo, (UINT8) (Tmp &~EE_DI), EEAddr);
+    eeprom_delay (100);
+
+    //
+    // raise the eeprom clock
+    //
+    OutByte (AdapterInfo, (UINT8) (Tmp | EE_SHIFT_CLK), EEAddr);
+    eeprom_delay (150);
+
+    //
+    // lower the eeprom clock
+    //
+    OutByte (AdapterInfo, (UINT8) (Tmp &~EE_SHIFT_CLK), EEAddr);
+    eeprom_delay (150);
+    Tmp = InByte (AdapterInfo, EEAddr);
+    AddrLen++;
+  }
+
+  //
+  // read the eeprom word, even though we don't need this
+  //
+  shift_bits_in (AdapterInfo);
+
+  //
+  // Terminate the EEPROM access.
+  //
+  Tmp = InByte (AdapterInfo, EEAddr);
+  Tmp &= ~(EE_CS | EE_DI);
+  OutByte (AdapterInfo, Tmp, EEAddr);
+
+  //
+  // raise the clock and lower the eeprom shift clock
+  //
+  OutByte (AdapterInfo, (UINT8) (Tmp | EE_SHIFT_CLK), EEAddr);
+  eeprom_delay (100);
+
+  OutByte (AdapterInfo, (UINT8) (Tmp &~EE_SHIFT_CLK), EEAddr);
+  eeprom_delay (100);
+
+  //
+  // giveup access to the eeprom!
+  //
+  E100bReSetEepromLockOut (AdapterInfo);
+
+  return AddrLen;
+}
+
+
+/**
+  TODO: Add function description
+
+  @param  AdapterInfo                     TODO: add argument description
+  @param  DBaddr                          TODO: add argument description
+  @param  DBsize                          TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+UINTN
+E100bStatistics (
+  NIC_DATA_INSTANCE *AdapterInfo,
+  UINT64            DBaddr,
+  UINT16            DBsize
+  )
+{
+  PXE_DB_STATISTICS db;
+  //
+  // wait upto one second (each wait is 100 micro s)
+  //
+  UINT32            Wait;
+  Wait = 10000;
+  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
+
+  //
+  // Clear statistics done marker.
+  //
+  AdapterInfo->statistics->done_marker = 0;
+
+  //
+  // Issue statistics dump (or dump w/ reset) command.
+  //
+  OutByte (
+    AdapterInfo,
+    (UINT8) (DBsize ? CU_SHOWSTATS : CU_DUMPSTATS),
+    (UINT32) (AdapterInfo->ioaddr + SCBCmd)
+    );
+
+  //
+  // Wait for command to complete.
+  //
+  // zero the db here just to chew up a little more time.
+  //
+
+  ZeroMem ((VOID *) &db, sizeof db);
+
+  while (Wait != 0) {
+    //
+    // Wait a bit before checking.
+    //
+
+    DelayIt (AdapterInfo, 100);
+
+    //
+    // Look for done marker at end of statistics.
+    //
+
+    switch (AdapterInfo->statistics->done_marker) {
+    case 0xA005:
+    case 0xA007:
+      break;
+
+    default:
+      Wait--;
+      continue;
+    }
+
+    //
+    // if we did not "continue" from the above switch, we are done,
+    //
+    break;
+  }
+
+  //
+  // If this is a reset, we are out of here!
+  //
+  if (DBsize == 0) {
+    return PXE_STATCODE_SUCCESS;
+  }
+
+  //
+  // Convert NIC statistics counter format to EFI/UNDI
+  // specification statistics counter format.
+  //
+
+  //
+  //                54 3210 fedc ba98 7654 3210
+  // db.Supported = 01 0000 0100 1101 0001 0111;
+  //
+  db.Supported = 0x104D17;
+
+  //
+  // Statistics from the NIC
+  //
+
+  db.Data[0x01] = AdapterInfo->statistics->rx_good_frames;
+
+  db.Data[0x02] = AdapterInfo->statistics->rx_runt_errs;
+
+  db.Data[0x08] = AdapterInfo->statistics->rx_crc_errs +
+                  AdapterInfo->statistics->rx_align_errs;
+
+  db.Data[0x04] = db.Data[0x02] +
+                  db.Data[0x08] +
+                  AdapterInfo->statistics->rx_resource_errs +
+                  AdapterInfo->statistics->rx_overrun_errs;
+
+  db.Data[0x00] = db.Data[0x01] + db.Data[0x04];
+
+  db.Data[0x0B] = AdapterInfo->statistics->tx_good_frames;
+
+  db.Data[0x0E] = AdapterInfo->statistics->tx_coll16_errs +
+    AdapterInfo->statistics->tx_late_colls +
+    AdapterInfo->statistics->tx_underruns +
+    AdapterInfo->statistics->tx_one_colls +
+    AdapterInfo->statistics->tx_multi_colls;
+
+  db.Data[0x14] = AdapterInfo->statistics->tx_total_colls;
+
+  db.Data[0x0A] = db.Data[0x0B] +
+                  db.Data[0x0E] +
+                  AdapterInfo->statistics->tx_lost_carrier;
+
+  if (DBsize > sizeof db) {
+    DBsize = (UINT16) sizeof (db);
+  }
+
+  CopyMem ((VOID *) (UINTN) DBaddr, (VOID *) &db, (UINTN) DBsize);
+
+  return PXE_STATCODE_SUCCESS;
+}
+
+
+/**
+  TODO: Add function description
+
+  @param  AdapterInfo                     TODO: add argument description
+  @param  OpFlags                         TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+UINTN
+E100bReset (
+  IN NIC_DATA_INSTANCE *AdapterInfo,
+  IN INT32             OpFlags
+  )
+{
+
+  UINT16  save_filter;
+  //
+  // disable the interrupts
+  //
+  OutWord (AdapterInfo, INT_MASK, AdapterInfo->ioaddr + SCBCmd);
+
+  //
+  // wait for the tx queue to complete
+  //
+  CheckCBList (AdapterInfo);
+
+  XmitWaitForCompletion (AdapterInfo);
+
+  if (AdapterInfo->Receive_Started) {
+    StopRU (AdapterInfo);
+  }
+
+  InitializeChip (AdapterInfo);
+
+  //
+  // check the opflags and restart receive filters
+  //
+  if ((OpFlags & PXE_OPFLAGS_RESET_DISABLE_FILTERS) == 0) {
+
+    save_filter = AdapterInfo->Rx_Filter;
+    //
+    // if we give the filter same as Rx_Filter,
+    // this routine will not set mcast list (it thinks there is no change)
+    // to force it, we will reset that flag in the Rx_Filter
+    //
+    AdapterInfo->Rx_Filter &= (~PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST);
+    E100bSetfilter (AdapterInfo, save_filter, (UINT64) 0, (UINT32) 0);
+  }
+
+  if ((OpFlags & PXE_OPFLAGS_RESET_DISABLE_INTERRUPTS) != 0) {
+    //
+    // disable the interrupts
+    //
+    AdapterInfo->int_mask = 0;
+  }
+  //
+  // else leave the interrupt in the pre-set state!!!
+  //
+  E100bSetInterruptState (AdapterInfo);
+
+  return 0;
+}
+
+
+/**
+  TODO: Add function description
+
+  @param  AdapterInfo                     TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+UINTN
+E100bShutdown (
+  IN NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  //
+  // disable the interrupts
+  //
+  OutWord (AdapterInfo, INT_MASK, AdapterInfo->ioaddr + SCBCmd);
+
+  //
+  // stop the receive unit
+  //
+  if (AdapterInfo->Receive_Started) {
+    StopRU (AdapterInfo);
+  }
+
+  //
+  // wait for the tx queue to complete
+  //
+  CheckCBList (AdapterInfo);
+  if (AdapterInfo->FreeCBCount != AdapterInfo->TxBufCnt) {
+    wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
+  }
+
+  //
+  // we do not want to reset the phy, it takes a long time to renegotiate the
+  // link after that (3-4 seconds)
+  //
+  InitializeChip (AdapterInfo);
+  SelectiveReset (AdapterInfo);
+  return 0;
+}
+
+
+/**
+  This routine will write a value to the specified MII register
+  of an external MDI compliant device (e.g. PHY 100).  The command will
+  execute in polled mode.
+
+  @param  AdapterInfo                     pointer to the structure that contains
+                                          the NIC's context.
+  @param  RegAddress                      The MII register that we are writing to
+  @param  PhyAddress                      The MDI address of the Phy component.
+  @param  DataValue                       The value that we are writing to the MII
+                                          register.
+
+  @return nothing
+
+**/
+VOID
+MdiWrite (
+  IN NIC_DATA_INSTANCE *AdapterInfo,
+  IN UINT8             RegAddress,
+  IN UINT8             PhyAddress,
+  IN UINT16            DataValue
+  )
+{
+  UINT32  WriteCommand;
+
+  WriteCommand = ((UINT32) DataValue) |
+                 ((UINT32)(RegAddress << 16)) |
+                 ((UINT32)(PhyAddress << 21)) |
+                 ((UINT32)(MDI_WRITE << 26));
+
+  //
+  // Issue the write command to the MDI control register.
+  //
+  OutLong (AdapterInfo, WriteCommand, AdapterInfo->ioaddr + SCBCtrlMDI);
+
+  //
+  // wait 20usec before checking status
+  //
+  DelayIt (AdapterInfo, 20);
+
+  //
+  // poll for the mdi write to complete
+  while ((InLong (AdapterInfo, AdapterInfo->ioaddr + SCBCtrlMDI) &
+                    MDI_PHY_READY) == 0){
+    DelayIt (AdapterInfo, 20);
+  }
+}
+
+
+/**
+  This routine will read a value from the specified MII register
+  of an external MDI compliant device (e.g. PHY 100), and return
+  it to the calling routine.  The command will execute in polled mode.
+
+  @param  AdapterInfo                     pointer to the structure that contains
+                                          the NIC's context.
+  @param  RegAddress                      The MII register that we are reading from
+  @param  PhyAddress                      The MDI address of the Phy component.
+  @param  DataValue                       pointer to the value that we read from
+                                          the MII register.
+
+
+**/
+VOID
+MdiRead (
+  IN NIC_DATA_INSTANCE *AdapterInfo,
+  IN UINT8             RegAddress,
+  IN UINT8             PhyAddress,
+  IN OUT UINT16        *DataValue
+  )
+{
+  UINT32  ReadCommand;
+
+  ReadCommand = ((UINT32) (RegAddress << 16)) |
+                ((UINT32) (PhyAddress << 21)) |
+                ((UINT32) (MDI_READ << 26));
+
+  //
+  // Issue the read command to the MDI control register.
+  //
+  OutLong (AdapterInfo, ReadCommand, AdapterInfo->ioaddr + SCBCtrlMDI);
+
+  //
+  // wait 20usec before checking status
+  //
+  DelayIt (AdapterInfo, 20);
+
+  //
+  // poll for the mdi read to complete
+  //
+  while ((InLong (AdapterInfo, AdapterInfo->ioaddr + SCBCtrlMDI) &
+          MDI_PHY_READY) == 0) {
+    DelayIt (AdapterInfo, 20);
+
+  }
+
+  *DataValue = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBCtrlMDI);
+}
+
+
+/**
+  This routine will reset the PHY that the adapter is currently
+  configured to use.
+
+  @param  AdapterInfo                     pointer to the structure that contains
+                                          the NIC's context.
+
+
+**/
+VOID
+PhyReset (
+  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  UINT16  MdiControlReg;
+
+  MdiControlReg = (MDI_CR_AUTO_SELECT |
+                  MDI_CR_RESTART_AUTO_NEG |
+                  MDI_CR_RESET);
+
+  //
+  // Write the MDI control register with our new Phy configuration
+  //
+  MdiWrite (
+    AdapterInfo,
+    MDI_CONTROL_REG,
+    AdapterInfo->PhyAddress,
+    MdiControlReg
+    );
+
+  return ;
+}
+
+
+/**
+  This routine will detect what phy we are using, set the line
+  speed, FDX or HDX, and configure the phy if necessary.
+  The following combinations are supported:
+  - TX or T4 PHY alone at PHY address 1
+  - T4 or TX PHY at address 1 and MII PHY at address 0
+  - 82503 alone (10Base-T mode, no full duplex support)
+  - 82503 and MII PHY (TX or T4) at address 0
+  The sequence / priority of detection is as follows:
+  - PHY 1 with cable termination
+  - PHY 0 with cable termination
+  - PHY 1 (if found) without cable termination
+  - 503 interface
+  Additionally auto-negotiation capable (NWAY) and parallel
+  detection PHYs are supported. The flow-chart is described in
+  the 82557 software writer's manual.
+  NOTE:  1.  All PHY MDI registers are read in polled mode.
+  2.  The routines assume that the 82557 has been RESET and we have
+  obtained the virtual memory address of the CSR.
+  3.  PhyDetect will not RESET the PHY.
+  4.  If FORCEFDX is set, SPEED should also be set. The driver will
+  check the values for inconsistency with the detected PHY
+  technology.
+  5.  PHY 1 (the PHY on the adapter) may have an address in the range
+  1 through 31 inclusive. The driver will accept addresses in
+  this range.
+  6.  Driver ignores FORCEFDX and SPEED overrides if a 503 interface
+  is detected.
+
+  @param  AdapterInfo                     pointer to the structure that contains
+                                          the NIC's context.
+
+  @retval TRUE                            If a Phy was detected, and configured
+                                          correctly.
+  @retval FALSE                           If a valid phy could not be detected and
+                                          configured.
+
+**/
+BOOLEAN
+PhyDetect (
+  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  UINT16  *eedata;
+  UINT16  MdiControlReg;
+  UINT16  MdiStatusReg;
+  BOOLEAN FoundPhy1;
+  UINT8   ReNegotiateTime;
+
+  eedata          = (UINT16 *) (&AdapterInfo->NVData[0]);
+
+  FoundPhy1       = FALSE;
+  ReNegotiateTime = 35;
+  //
+  // EEPROM word [6] contains the Primary PHY record in which the least 3 bits
+  // indicate the PHY address
+  // and word [7] contains the secondary PHY record
+  //
+  AdapterInfo->PhyRecord[0] = eedata[6];
+  AdapterInfo->PhyRecord[1] = eedata[7];
+  AdapterInfo->PhyAddress   = (UINT8) (AdapterInfo->PhyRecord[0] & 7);
+
+  //
+  // Check for a phy address over-ride of 32 which indicates force use of 82503
+  // not detecting the link in this case
+  //
+  if (AdapterInfo->PhyAddress == 32) {
+    //
+    // 503 interface over-ride
+    // Record the current speed and duplex.  We will be in half duplex
+    // mode unless the user used the force full duplex over-ride.
+    //
+    AdapterInfo->LinkSpeed = 10;
+    return (TRUE);
+  }
+
+  //
+  // If the Phy Address is between 1-31 then we must first look for phy 1,
+  // at that address.
+  //
+  if ((AdapterInfo->PhyAddress > 0) && (AdapterInfo->PhyAddress < 32)) {
+
+    //
+    // Read the MDI control and status registers at phy 1
+    // and check if we found a valid phy
+    //
+    MdiRead (
+      AdapterInfo,
+      MDI_CONTROL_REG,
+      AdapterInfo->PhyAddress,
+      &MdiControlReg
+      );
+
+    MdiRead (
+      AdapterInfo,
+      MDI_STATUS_REG,
+      AdapterInfo->PhyAddress,
+      &MdiStatusReg
+      );
+
+    if (!((MdiControlReg == 0xffff) ||
+          ((MdiStatusReg == 0) && (MdiControlReg == 0)))) {
+
+      //
+      // we have a valid phy1
+      // Read the status register again because of sticky bits
+      //
+      FoundPhy1 = TRUE;
+      MdiRead (
+        AdapterInfo,
+        MDI_STATUS_REG,
+        AdapterInfo->PhyAddress,
+        &MdiStatusReg
+        );
+
+      //
+      // If there is a valid link then use this Phy.
+      //
+      if (MdiStatusReg & MDI_SR_LINK_STATUS) {
+        return (SetupPhy(AdapterInfo));
+      }
+    }
+  }
+
+  //
+  // Next try to detect a PHY at address 0x00 because there was no Phy 1,
+  // or Phy 1 didn't have link, or we had a phy 0 over-ride
+  //
+
+  //
+  // Read the MDI control and status registers at phy 0
+  //
+  MdiRead (AdapterInfo, MDI_CONTROL_REG, 0, &MdiControlReg);
+  MdiRead (AdapterInfo, MDI_STATUS_REG, 0, &MdiStatusReg);
+
+  //
+  // check if we found a valid phy 0
+  //
+  if (((MdiControlReg == 0xffff) ||
+       ((MdiStatusReg == 0) && (MdiControlReg == 0)))) {
+
+    //
+    // we don't have a valid phy at address 0
+    // if phy address was forced to 0, then error out because we
+    // didn't find a phy at that address
+    //
+    if (AdapterInfo->PhyAddress == 0x0000) {
+      return (FALSE);
+    } else {
+      //
+      // at this point phy1 does not have link and there is no phy 0 at all
+      // if we are forced to detect the cable, error out here!
+      //
+      if (AdapterInfo->CableDetect != 0) {
+        return FALSE;
+
+      }
+
+      if (FoundPhy1) {
+        //
+        // no phy 0, but there is a phy 1 (no link I guess), so use phy 1
+        //
+        return SetupPhy (AdapterInfo);
+      } else {
+        //
+        // didn't find phy 0 or phy 1, so assume a 503 interface
+        //
+        AdapterInfo->PhyAddress = 32;
+
+        //
+        // Record the current speed and duplex.  We'll be in half duplex
+        // mode unless the user used the force full duplex over-ride.
+        //
+        AdapterInfo->LinkSpeed = 10;
+        return (TRUE);
+      }
+    }
+  } else {
+    //
+    // We have a valid phy at address 0.  If phy 0 has a link then we use
+    // phy 0.  If Phy 0 doesn't have a link then we use Phy 1 (no link)
+    // if phy 1 is present, or phy 0 if phy 1 is not present
+    // If phy 1 was present, then we must isolate phy 1 before we enable
+    // phy 0 to see if Phy 0 has a link.
+    //
+    if (FoundPhy1) {
+      //
+      // isolate phy 1
+      //
+      MdiWrite (
+        AdapterInfo,
+        MDI_CONTROL_REG,
+        AdapterInfo->PhyAddress,
+        MDI_CR_ISOLATE
+        );
+
+      //
+      // wait 100 microseconds for the phy to isolate.
+      //
+      DelayIt (AdapterInfo, 100);
+    }
+
+    //
+    // Since this Phy is at address 0, we must enable it.  So clear
+    // the isolate bit, and set the auto-speed select bit
+    //
+    MdiWrite (
+      AdapterInfo,
+      MDI_CONTROL_REG,
+      0,
+      MDI_CR_AUTO_SELECT
+      );
+
+    //
+    // wait 100 microseconds for the phy to be enabled.
+    //
+    DelayIt (AdapterInfo, 100);
+
+    //
+    // restart the auto-negotion process
+    //
+    MdiWrite (
+      AdapterInfo,
+      MDI_CONTROL_REG,
+      0,
+      MDI_CR_RESTART_AUTO_NEG | MDI_CR_AUTO_SELECT
+      );
+
+    //
+    // wait no more than 3.5 seconds for auto-negotiation to complete
+    //
+    while (ReNegotiateTime) {
+      //
+      // Read the status register twice because of sticky bits
+      //
+      MdiRead (AdapterInfo, MDI_STATUS_REG, 0, &MdiStatusReg);
+      MdiRead (AdapterInfo, MDI_STATUS_REG, 0, &MdiStatusReg);
+
+      if (MdiStatusReg & MDI_SR_AUTO_NEG_COMPLETE) {
+        break;
+      }
+
+      DelayIt (AdapterInfo, 100);
+      ReNegotiateTime--;
+    }
+
+    //
+    // Read the status register again because of sticky bits
+    //
+    MdiRead (AdapterInfo, MDI_STATUS_REG, 0, &MdiStatusReg);
+
+    //
+    // If the link was not set
+    //
+    if ((MdiStatusReg & MDI_SR_LINK_STATUS) == 0) {
+      //
+      // PHY1 does not have a link and phy 0 does not have a link
+      // do not proceed if we need to detect the link!
+      //
+      if (AdapterInfo->CableDetect != 0) {
+        return FALSE;
+      }
+
+      //
+      // the link wasn't set, so use phy 1 if phy 1 was present
+      //
+      if (FoundPhy1) {
+        //
+        // isolate phy 0
+        //
+        MdiWrite (AdapterInfo, MDI_CONTROL_REG, 0, MDI_CR_ISOLATE);
+
+        //
+        // wait 100 microseconds for the phy to isolate.
+        //
+        DelayIt (AdapterInfo, 100);
+
+        //
+        // Now re-enable PHY 1
+        //
+        MdiWrite (
+          AdapterInfo,
+          MDI_CONTROL_REG,
+          AdapterInfo->PhyAddress,
+          MDI_CR_AUTO_SELECT
+          );
+
+        //
+        // wait 100 microseconds for the phy to be enabled
+        //
+        DelayIt (AdapterInfo, 100);
+
+        //
+        // restart the auto-negotion process
+        //
+        MdiWrite (
+          AdapterInfo,
+          MDI_CONTROL_REG,
+          AdapterInfo->PhyAddress,
+          MDI_CR_RESTART_AUTO_NEG | MDI_CR_AUTO_SELECT
+          );
+
+        //
+        // Don't wait for it to complete (we didn't have link earlier)
+        //
+        return (SetupPhy (AdapterInfo));
+      }
+    }
+
+    //
+    // Definitely using Phy 0
+    //
+    AdapterInfo->PhyAddress = 0;
+    return (SetupPhy(AdapterInfo));
+  }
+}
+
+
+/**
+  This routine will setup phy 1 or phy 0 so that it is configured
+  to match a speed and duplex over-ride option.  If speed or
+  duplex mode is not explicitly specified in the registry, the
+  driver will skip the speed and duplex over-ride code, and
+  assume the adapter is automatically setting the line speed, and
+  the duplex mode.  At the end of this routine, any truly Phy
+  specific code will be executed (each Phy has its own quirks,
+  and some require that certain special bits are set).
+  NOTE:  The driver assumes that SPEED and FORCEFDX are specified at the
+  same time. If FORCEDPX is set without speed being set, the driver
+  will encouter a fatal error and log a message into the event viewer.
+
+  @param  AdapterInfo                     pointer to the structure that contains
+                                          the NIC's context.
+
+  @retval TRUE                            If the phy could be configured correctly
+  @retval FALSE                           If the phy couldn't be configured
+                                          correctly, because an unsupported
+                                          over-ride option was used
+
+**/
+BOOLEAN
+SetupPhy (
+  IN NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  UINT16  MdiControlReg;
+  UINT16  MdiStatusReg;
+  UINT16  MdiIdLowReg;
+  UINT16  MdiIdHighReg;
+  UINT16  MdiMiscReg;
+  UINT32  PhyId;
+  BOOLEAN ForcePhySetting;
+
+  ForcePhySetting = FALSE;
+
+  //
+  // If we are NOT forcing a setting for line speed or full duplex, then
+  // we won't force a link setting, and we'll jump down to the phy
+  // specific code.
+  //
+  if (((AdapterInfo->LinkSpeedReq) || (AdapterInfo->DuplexReq))) {
+    //
+    // Find out what kind of technology this Phy is capable of.
+    //
+    MdiRead (
+      AdapterInfo,
+      MDI_STATUS_REG,
+      AdapterInfo->PhyAddress,
+      &MdiStatusReg
+      );
+
+    //
+    // Read the MDI control register at our phy
+    //
+    MdiRead (
+      AdapterInfo,
+      MDI_CONTROL_REG,
+      AdapterInfo->PhyAddress,
+      &MdiControlReg
+      );
+
+    //
+    // Now check the validity of our forced option.  If the force option is
+    // valid, then force the setting.  If the force option is not valid,
+    // we'll set a flag indicating that we should error out.
+    //
+
+    //
+    // If speed is forced to 10mb
+    //
+    if (AdapterInfo->LinkSpeedReq == 10) {
+      //
+      // If half duplex is forced
+      //
+      if ((AdapterInfo->DuplexReq & PXE_FORCE_HALF_DUPLEX) != 0) {
+        if (MdiStatusReg & MDI_SR_10T_HALF_DPX) {
+
+          MdiControlReg &= ~(MDI_CR_10_100 | MDI_CR_AUTO_SELECT | MDI_CR_FULL_HALF);
+          ForcePhySetting = TRUE;
+        }
+      } else if ((AdapterInfo->DuplexReq & PXE_FORCE_FULL_DUPLEX) != 0) {
+
+        //
+        // If full duplex is forced
+        //
+        if (MdiStatusReg & MDI_SR_10T_FULL_DPX) {
+
+          MdiControlReg &= ~(MDI_CR_10_100 | MDI_CR_AUTO_SELECT);
+          MdiControlReg |= MDI_CR_FULL_HALF;
+          ForcePhySetting = TRUE;
+        }
+      } else {
+        //
+        // If auto duplex (we actually set phy to 1/2)
+        //
+        if (MdiStatusReg & (MDI_SR_10T_FULL_DPX | MDI_SR_10T_HALF_DPX)) {
+
+          MdiControlReg &= ~(MDI_CR_10_100 | MDI_CR_AUTO_SELECT | MDI_CR_FULL_HALF);
+          ForcePhySetting = TRUE;
+        }
+      }
+    }
+
+    //
+    // If speed is forced to 100mb
+    //
+    else if (AdapterInfo->LinkSpeedReq == 100) {
+      //
+      // If half duplex is forced
+      //
+      if ((AdapterInfo->DuplexReq & PXE_FORCE_HALF_DUPLEX) != 0) {
+        if (MdiStatusReg & (MDI_SR_TX_HALF_DPX | MDI_SR_T4_CAPABLE)) {
+
+          MdiControlReg &= ~(MDI_CR_AUTO_SELECT | MDI_CR_FULL_HALF);
+          MdiControlReg |= MDI_CR_10_100;
+          ForcePhySetting = TRUE;
+        }
+      } else if ((AdapterInfo->DuplexReq & PXE_FORCE_FULL_DUPLEX) != 0) {
+        //
+        // If full duplex is forced
+        //
+        if (MdiStatusReg & MDI_SR_TX_FULL_DPX) {
+          MdiControlReg &= ~MDI_CR_AUTO_SELECT;
+          MdiControlReg |= (MDI_CR_10_100 | MDI_CR_FULL_HALF);
+          ForcePhySetting = TRUE;
+        }
+      } else {
+        //
+        // If auto duplex (we set phy to 1/2)
+        //
+        if (MdiStatusReg & (MDI_SR_TX_HALF_DPX | MDI_SR_T4_CAPABLE)) {
+
+          MdiControlReg &= ~(MDI_CR_AUTO_SELECT | MDI_CR_FULL_HALF);
+          MdiControlReg |= MDI_CR_10_100;
+          ForcePhySetting = TRUE;
+        }
+      }
+    }
+
+    if (!ForcePhySetting) {
+      return (FALSE);
+    }
+
+    //
+    // Write the MDI control register with our new Phy configuration
+    //
+    MdiWrite (
+      AdapterInfo,
+      MDI_CONTROL_REG,
+      AdapterInfo->PhyAddress,
+      MdiControlReg
+      );
+
+    //
+    // wait 100 milliseconds for auto-negotiation to complete
+    //
+    DelayIt (AdapterInfo, 100);
+  }
+
+  //
+  // Find out specifically what Phy this is.  We do this because for certain
+  // phys there are specific bits that must be set so that the phy and the
+  // 82557 work together properly.
+  //
+
+  MdiRead (
+    AdapterInfo,
+    PHY_ID_REG_1,
+    AdapterInfo->PhyAddress,
+    &MdiIdLowReg
+    );
+  MdiRead (
+    AdapterInfo,
+    PHY_ID_REG_2,
+    AdapterInfo->PhyAddress,
+    &MdiIdHighReg
+    );
+
+  PhyId = ((UINT32) MdiIdLowReg | ((UINT32) MdiIdHighReg << 16));
+
+  //
+  // And out the revsion field of the Phy ID so that we'll be able to detect
+  // future revs of the same Phy.
+  //
+  PhyId &= PHY_MODEL_REV_ID_MASK;
+
+  //
+  // Handle the National TX
+  //
+  if (PhyId == PHY_NSC_TX) {
+
+    MdiRead (
+      AdapterInfo,
+      NSC_CONG_CONTROL_REG,
+      AdapterInfo->PhyAddress,
+      &MdiMiscReg
+      );
+
+    MdiMiscReg |= (NSC_TX_CONG_TXREADY | NSC_TX_CONG_F_CONNECT);
+
+    MdiWrite (
+      AdapterInfo,
+      NSC_CONG_CONTROL_REG,
+      AdapterInfo->PhyAddress,
+      MdiMiscReg
+      );
+  }
+
+  FindPhySpeedAndDpx (AdapterInfo, PhyId);
+
+  //
+  // We put a hardware fix on to our adapters to work-around the PHY_100 errata
+  // described below.  The following code is only compiled in, if we wanted
+  // to attempt a software workaround to the PHY_100 A/B step problem.
+  //
+
+  return (TRUE);
+}
+
+
+/**
+  This routine will figure out what line speed and duplex mode
+  the PHY is currently using.
+
+  @param  AdapterInfo                     pointer to the structure that contains
+                                          the NIC's context.
+  @param  PhyId                           The ID of the PHY in question.
+
+  @return NOTHING
+
+**/
+VOID
+FindPhySpeedAndDpx (
+  IN NIC_DATA_INSTANCE *AdapterInfo,
+  IN UINT32            PhyId
+  )
+{
+  UINT16  MdiStatusReg;
+  UINT16  MdiMiscReg;
+  UINT16  MdiOwnAdReg;
+  UINT16  MdiLinkPartnerAdReg;
+
+  //
+  // If there was a speed and/or duplex override, then set our current
+  // value accordingly
+  //
+  AdapterInfo->LinkSpeed  = AdapterInfo->LinkSpeedReq;
+  AdapterInfo->Duplex = (UINT8) ((AdapterInfo->DuplexReq & PXE_FORCE_FULL_DUPLEX) ?
+                        FULL_DUPLEX : HALF_DUPLEX);
+
+  //
+  // If speed and duplex were forced, then we know our current settings, so
+  // we'll just return.  Otherwise, we'll need to figure out what NWAY set
+  // us to.
+  //
+  if (AdapterInfo->LinkSpeed && AdapterInfo->Duplex) {
+    return ;
+
+  }
+  //
+  // If we didn't have a valid link, then we'll assume that our current
+  // speed is 10mb half-duplex.
+  //
+
+  //
+  // Read the status register twice because of sticky bits
+  //
+  MdiRead (
+    AdapterInfo,
+    MDI_STATUS_REG,
+    AdapterInfo->PhyAddress,
+    &MdiStatusReg
+    );
+  MdiRead (
+    AdapterInfo,
+    MDI_STATUS_REG,
+    AdapterInfo->PhyAddress,
+    &MdiStatusReg
+    );
+
+  //
+  // If there wasn't a valid link then use default speed & duplex
+  //
+  if (!(MdiStatusReg & MDI_SR_LINK_STATUS)) {
+
+    AdapterInfo->LinkSpeed  = 10;
+    AdapterInfo->Duplex     = HALF_DUPLEX;
+    return ;
+  }
+
+  //
+  // If this is an Intel PHY (a T4 PHY_100 or a TX PHY_TX), then read bits
+  // 1 and 0 of extended register 0, to get the current speed and duplex
+  // settings.
+  //
+  if ((PhyId == PHY_100_A) || (PhyId == PHY_100_C) || (PhyId == PHY_TX_ID)) {
+    //
+    // Read extended register 0
+    //
+    MdiRead (
+      AdapterInfo,
+      EXTENDED_REG_0,
+      AdapterInfo->PhyAddress,
+      &MdiMiscReg
+      );
+
+    //
+    // Get current speed setting
+    //
+    if (MdiMiscReg & PHY_100_ER0_SPEED_INDIC) {
+      AdapterInfo->LinkSpeed = 100;
+    } else {
+      AdapterInfo->LinkSpeed = 10;
+    }
+
+    //
+    // Get current duplex setting -- if bit is set then FDX is enabled
+    //
+    if (MdiMiscReg & PHY_100_ER0_FDX_INDIC) {
+      AdapterInfo->Duplex = FULL_DUPLEX;
+    } else {
+      AdapterInfo->Duplex = HALF_DUPLEX;
+    }
+
+    return ;
+  }
+  //
+  // Read our link partner's advertisement register
+  //
+  MdiRead (
+    AdapterInfo,
+    AUTO_NEG_LINK_PARTNER_REG,
+    AdapterInfo->PhyAddress,
+    &MdiLinkPartnerAdReg
+    );
+
+  //
+  // See if Auto-Negotiation was complete (bit 5, reg 1)
+  //
+  MdiRead (
+    AdapterInfo,
+    MDI_STATUS_REG,
+    AdapterInfo->PhyAddress,
+    &MdiStatusReg
+    );
+
+  //
+  // If a True NWAY connection was made, then we can detect speed/duplex by
+  // ANDing our adapter's advertised abilities with our link partner's
+  // advertised ablilities, and then assuming that the highest common
+  // denominator was chosed by NWAY.
+  //
+  if ((MdiLinkPartnerAdReg & NWAY_LP_ABILITY) &&
+      (MdiStatusReg & MDI_SR_AUTO_NEG_COMPLETE)) {
+
+    //
+    // Read our advertisement register
+    //
+    MdiRead (
+      AdapterInfo,
+      AUTO_NEG_ADVERTISE_REG,
+      AdapterInfo->PhyAddress,
+      &MdiOwnAdReg
+      );
+
+    //
+    // AND the two advertisement registers together, and get rid of any
+    // extraneous bits.
+    //
+    MdiOwnAdReg = (UINT16) (MdiOwnAdReg & (MdiLinkPartnerAdReg & NWAY_LP_ABILITY));
+
+    //
+    // Get speed setting
+    //
+    if (MdiOwnAdReg & (NWAY_AD_TX_HALF_DPX | NWAY_AD_TX_FULL_DPX | NWAY_AD_T4_CAPABLE)) {
+      AdapterInfo->LinkSpeed = 100;
+    } else {
+      AdapterInfo->LinkSpeed = 10;
+    }
+
+    //
+    // Get duplex setting -- use priority resolution algorithm
+    //
+    if (MdiOwnAdReg & (NWAY_AD_T4_CAPABLE)) {
+      AdapterInfo->Duplex = HALF_DUPLEX;
+      return ;
+    } else if (MdiOwnAdReg & (NWAY_AD_TX_FULL_DPX)) {
+      AdapterInfo->Duplex = FULL_DUPLEX;
+      return ;
+    } else if (MdiOwnAdReg & (NWAY_AD_TX_HALF_DPX)) {
+      AdapterInfo->Duplex = HALF_DUPLEX;
+      return ;
+    } else if (MdiOwnAdReg & (NWAY_AD_10T_FULL_DPX)) {
+      AdapterInfo->Duplex = FULL_DUPLEX;
+      return ;
+    } else {
+      AdapterInfo->Duplex = HALF_DUPLEX;
+      return ;
+    }
+  }
+
+  //
+  // If we are connected to a dumb (non-NWAY) repeater or hub, and the line
+  // speed was determined automatically by parallel detection, then we have
+  // no way of knowing exactly what speed the PHY is set to unless that PHY
+  // has a propietary register which indicates speed in this situation.  The
+  // NSC TX PHY does have such a register.  Also, since NWAY didn't establish
+  // the connection, the duplex setting should HALF duplex.
+  //
+  AdapterInfo->Duplex = HALF_DUPLEX;
+
+  if (PhyId == PHY_NSC_TX) {
+    //
+    // Read register 25 to get the SPEED_10 bit
+    //
+    MdiRead (
+      AdapterInfo,
+      NSC_SPEED_IND_REG,
+      AdapterInfo->PhyAddress,
+      &MdiMiscReg
+      );
+
+    //
+    // If bit 6 was set then we're at 10mb
+    //
+    if (MdiMiscReg & NSC_TX_SPD_INDC_SPEED) {
+      AdapterInfo->LinkSpeed = 10;
+    } else {
+      AdapterInfo->LinkSpeed = 100;
+    }
+  }
+
+  //
+  // If we don't know what line speed we are set at, then we'll default to
+  // 10mbs
+  //
+  else {
+    AdapterInfo->LinkSpeed = 10;
+  }
+}
+
+
+/**
+  TODO: Add function description
+
+  @param  AdapterInfo                     TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+VOID
+XmitWaitForCompletion (
+  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  TxCB  *TxPtr;
+
+  if (AdapterInfo->FreeCBCount == AdapterInfo->TxBufCnt) {
+    return ;
+  }
+
+  //
+  // used xmit cb list starts right after the free tail (ends before the
+  // free head ptr)
+  //
+  TxPtr = AdapterInfo->FreeTxTailPtr->NextTCBVirtualLinkPtr;
+  while (TxPtr != AdapterInfo->FreeTxHeadPtr) {
+    CommandWaitForCompletion (TxPtr, AdapterInfo);
+    SetFreeCB (AdapterInfo, TxPtr);
+    TxPtr = TxPtr->NextTCBVirtualLinkPtr;
+  }
+}
+
+
+/**
+  TODO: Add function description
+
+  @param  cmd_ptr                         TODO: add argument description
+  @param  AdapterInfo                     TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+INT8
+CommandWaitForCompletion (
+  TxCB              *cmd_ptr,
+  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  INT16 wait;
+  wait = 5000;
+  while ((cmd_ptr->cb_header.status == 0) && (--wait > 0)) {
+    DelayIt (AdapterInfo, 10);
+  }
+
+  if (cmd_ptr->cb_header.status == 0) {
+    return -1;
+  }
+
+  return 0;
+}
+
+
+/**
+  TODO: Add function description
+
+  @param  AdapterInfo                     TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+INT8
+SoftwareReset (
+  NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  UINT8   tco_stat;
+  UINT16  wait;
+
+  tco_stat = 0;
+
+  //
+  // Reset the chip: stop Tx and Rx processes and clear counters.
+  // This takes less than 10usec and will easily finish before the next
+  // action.
+  //
+
+  OutLong (AdapterInfo, PORT_RESET, AdapterInfo->ioaddr + SCBPort);
+  //
+  // wait for 5 milli seconds here!
+  //
+  DelayIt (AdapterInfo, 5000);
+  //
+  // TCO Errata work around for 559s only
+  // -----------------------------------------------------------------------------------
+  // TCO Workaround Code
+  //  haifa workaround
+  // -----------------------------------------------------------------------------------
+  //    1. Issue SW-RST ^^^ (already done above)
+  //    2. Issue a redundant Set CU Base CMD immediately
+  //       Do not set the General Pointer before the Set CU Base cycle
+  //       Do not check the SCB CMD before the Set CU Base cycle
+  //    3. Wait for the SCB-CMD to be cleared
+  //       this indicates the transition to post-driver
+  //    4. Poll the TCO-Req bit in the PMDR to be cleared
+  //       this indicates the tco activity has stopped for real
+  //    5. Proceed with the nominal Driver Init:
+  //       Actual Set CU & RU Base ...
+  //
+  // Check for ICH2 device ID.  If this is an ICH2,
+  // do the TCO workaround code.
+  //
+  if (AdapterInfo->VendorID == D102_DEVICE_ID ||
+      AdapterInfo->VendorID == ICH3_DEVICE_ID_1 ||
+      AdapterInfo->VendorID == ICH3_DEVICE_ID_2 ||
+      AdapterInfo->VendorID == ICH3_DEVICE_ID_3 ||
+      AdapterInfo->VendorID == ICH3_DEVICE_ID_4 ||
+      AdapterInfo->VendorID == ICH3_DEVICE_ID_5 ||
+      AdapterInfo->VendorID == ICH3_DEVICE_ID_6 ||
+      AdapterInfo->VendorID == ICH3_DEVICE_ID_7 ||
+      AdapterInfo->VendorID == ICH3_DEVICE_ID_8 ||
+      AdapterInfo->RevID >= 8) {  // do the TCO fix
+    //
+    // donot load the scb pointer but just give load_cu cmd.
+    //
+    OutByte (AdapterInfo, CU_CMD_BASE, AdapterInfo->ioaddr + SCBCmd);
+    //
+    // wait for command to be accepted.
+    //
+    wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
+    //
+    // read PMDR register and check bit 1 in it to see if TCO is active
+    //
+
+    //
+    // wait for 5 milli seconds
+    //
+    wait = 5000;
+    while (wait) {
+      tco_stat = InByte (AdapterInfo, AdapterInfo->ioaddr + 0x1b);
+      if ((tco_stat & 2) == 0) {
+        //
+        // is the activity bit clear??
+        //
+        break;
+      }
+
+      wait--;
+      DelayIt (AdapterInfo, 1);
+    }
+
+    if ((tco_stat & 2) != 0) {
+      //
+      // not zero??
+      //
+      return -1;
+    }
+  }
+
+  return 0;
+}
+
+
+/**
+  TODO: Add function description
+
+  @param  AdapterInfo                     TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+UINT8
+SelectiveReset (
+  IN NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  UINT16  wait;
+  UINT32  stat;
+
+  wait  = 10;
+  stat  = 0;
+  OutLong (AdapterInfo, POR_SELECTIVE_RESET, AdapterInfo->ioaddr + SCBPort);
+  //
+  // wait for this to complete
+  //
+
+  //
+  // wait for 2 milli seconds here!
+  //
+  DelayIt (AdapterInfo, 2000);
+  while (wait > 0) {
+    wait--;
+    stat = InLong (AdapterInfo, AdapterInfo->ioaddr + SCBPort);
+    if (stat == 0) {
+      break;
+    }
+
+    //
+    // wait for 1 milli second
+    //
+    DelayIt (AdapterInfo, 1000);
+  }
+
+  if (stat != 0) {
+    return PXE_STATCODE_DEVICE_FAILURE;
+  }
+
+  return 0;
+}
+
+
+/**
+  TODO: Add function description
+
+  @param  AdapterInfo                     TODO: add argument description
+
+  @return TODO: add return values
+
+**/
+UINT16
+InitializeChip (
+  IN NIC_DATA_INSTANCE *AdapterInfo
+  )
+{
+  UINT16  ret_val;
+  if (SoftwareReset (AdapterInfo) != 0) {
+    return PXE_STATCODE_DEVICE_FAILURE;
+  }
+
+  //
+  // disable interrupts
+  //
+  OutWord (AdapterInfo, INT_MASK, AdapterInfo->ioaddr + SCBCmd);
+
+  //
+  // Load the base registers with 0s (we will give the complete address as
+  // offset later when we issue any command
+  //
+  if ((ret_val = Load_Base_Regs (AdapterInfo)) != 0) {
+    return ret_val;
+  }
+
+  if ((ret_val = SetupCBlink (AdapterInfo)) != 0) {
+    return ret_val;
+  }
+
+  if ((ret_val = SetupReceiveQueues (AdapterInfo)) != 0) {
+    return ret_val;
+  }
+
+  //
+  // detect the PHY only if we need to detect the cable as requested by the
+  // initialize parameters
+  //
+  AdapterInfo->PhyAddress = 0xFF;
+
+  if (AdapterInfo->CableDetect != 0) {
+    if (!PhyDetect (AdapterInfo)) {
+      return PXE_STATCODE_DEVICE_FAILURE;
+    }
+  }
+
+  if ((ret_val = E100bSetupIAAddr (AdapterInfo)) != 0) {
+    return ret_val;
+  }
+
+  if ((ret_val = Configure (AdapterInfo)) != 0) {
+    return ret_val;
+  }
+
+  return 0;
+}
diff --git a/Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h b/Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h
new file mode 100644
index 0000000000..18ff7aa94d
--- /dev/null
+++ b/Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h
@@ -0,0 +1,665 @@
+/** @file
+  Definitions for network adapter card.
+
+Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _E100B_H_
+#define _E100B_H_
+
+// pci config offsets:
+
+#define RX_BUFFER_COUNT 32
+#define TX_BUFFER_COUNT 32
+
+#define PCI_VENDOR_ID_INTEL 0x8086
+#define PCI_DEVICE_ID_INTEL_82557 0x1229
+#define D100_VENDOR_ID   0x8086
+#define D100_DEVICE_ID   0x1229
+#define D102_DEVICE_ID   0x2449
+
+#define ICH3_DEVICE_ID_1   0x1031
+#define ICH3_DEVICE_ID_2   0x1032
+#define ICH3_DEVICE_ID_3   0x1033
+#define ICH3_DEVICE_ID_4   0x1034
+#define ICH3_DEVICE_ID_5   0x1035
+#define ICH3_DEVICE_ID_6   0x1036
+#define ICH3_DEVICE_ID_7   0x1037
+#define ICH3_DEVICE_ID_8   0x1038
+
+#define SPEEDO_DEVICE_ID   0x1227
+#define SPLASH1_DEVICE_ID   0x1226
+
+
+// bit fields for the command
+#define PCI_COMMAND_MASTER  0x04  // bit 2
+#define PCI_COMMAND_IO    0x01  // bit 0
+#define PCI_COMMAND  0x04
+#define PCI_LATENCY_TIMER  0x0D
+
+#define ETHER_MAC_ADDR_LEN 6
+#ifdef AVL_XXX
+#define ETHER_HEADER_LEN 14
+// media interface type
+// #define INTERFACE_TYPE "
+
+// Hardware type values
+#define HW_ETHER_TYPE    1
+#define HW_EXPERIMENTAL_ETHER_TYPE 2
+#define HW_IEEE_TYPE    6
+#define HW_ARCNET_TYPE     7
+
+#endif  // AVL_XXX
+
+#define MAX_ETHERNET_PKT_SIZE 1514  // including eth header
+#define RX_BUFFER_SIZE 1536  // including crc and padding
+#define TX_BUFFER_SIZE 64
+#define ETH_MTU 1500  // does not include ethernet header length
+
+#define SPEEDO3_TOTAL_SIZE 0x20
+
+#pragma pack(1)
+
+typedef struct eth {
+  UINT8 dest_addr[PXE_HWADDR_LEN_ETHER];
+  UINT8 src_addr[PXE_HWADDR_LEN_ETHER];
+  UINT16 type;
+} EtherHeader;
+
+#pragma pack(1)
+typedef struct CONFIG_HEADER {
+  UINT16 VendorID;
+  UINT16 DeviceID;
+  UINT16 Command;
+  UINT16 Status;
+  UINT16 RevID;
+  UINT16 ClassID;
+  UINT8  CacheLineSize;
+  UINT8  LatencyTimer;
+  UINT8  HeaderType;    // must be zero to impose this structure...
+  UINT8  BIST;  // built-in self test
+  UINT32 BaseAddressReg_0;  // memory mapped address
+  UINT32 BaseAddressReg_1;  //io mapped address, Base IO address
+  UINT32 BaseAddressReg_2;  // option rom address
+  UINT32 BaseAddressReg_3;
+  UINT32 BaseAddressReg_4;
+  UINT32 BaseAddressReg_5;
+  UINT32 CardBusCISPtr;
+  UINT16 SubVendorID;
+  UINT16 SubSystemID;
+  UINT32 ExpansionROMBaseAddr;
+  UINT8 CapabilitiesPtr;
+  UINT8 reserved1;
+  UINT16 Reserved2;
+  UINT32 Reserved3;
+  UINT8 int_line;
+  UINT8 int_pin;
+  UINT8 Min_gnt;
+  UINT8 Max_lat;
+} PCI_CONFIG_HEADER;
+#pragma pack()
+
+//-------------------------------------------------------------------------
+// Offsets to the various registers.
+//   All accesses need not be longword aligned.
+//-------------------------------------------------------------------------
+enum speedo_offsets {
+  SCBStatus = 0, SCBCmd = 2,     // Rx/Command Unit command and status.
+  SCBPointer = 4,                // General purpose pointer.
+  SCBPort = 8,                   // Misc. commands and operands.
+  SCBflash = 12, SCBeeprom = 14, // EEPROM and flash memory control.
+  SCBCtrlMDI = 16,               // MDI interface control.
+  SCBEarlyRx = 20,               // Early receive byte count.
+  SCBEarlyRxInt = 24, SCBFlowCtrlReg = 25, SCBPmdr = 27,
+  // offsets for general control registers (GCRs)
+  SCBGenCtrl = 28, SCBGenStatus = 29, SCBGenCtrl2 = 30, SCBRsvd = 31
+};
+
+#define GCR2_EEPROM_ACCESS_SEMAPHORE 0x80 // bit offset into the gcr2
+
+//-------------------------------------------------------------------------
+// Action commands - Commands that can be put in a command list entry.
+//-------------------------------------------------------------------------
+enum commands {
+  CmdNOp = 0, CmdIASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
+  CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7,
+  CmdSuspend = 0x4000,    /* Suspend after completion. */
+  CmdIntr = 0x2000,      /* Interrupt after completion. */
+  CmdTxFlex = 0x0008      /* Use "Flexible mode" for CmdTx command. */
+};
+
+//-------------------------------------------------------------------------
+// port commands
+//-------------------------------------------------------------------------
+#define PORT_RESET 0
+#define PORT_SELF_TEST 1
+#define POR_SELECTIVE_RESET 2
+#define PORT_DUMP_POINTER 2
+
+//-------------------------------------------------------------------------
+// SCB Command Word bit definitions
+//-------------------------------------------------------------------------
+//- CUC fields
+#define   CU_START    0x0010
+#define   CU_RESUME    0x0020
+#define   CU_STATSADDR  0x0040
+#define   CU_SHOWSTATS  0x0050  /* Dump statistics counters. */
+#define   CU_CMD_BASE  0x0060  /* Base address to add to add CU commands. */
+#define   CU_DUMPSTATS  0x0070  /* Dump then reset stats counters. */
+
+//- RUC fields
+#define   RX_START  0x0001
+#define   RX_RESUME  0x0002
+#define   RX_ABORT  0x0004
+#define   RX_ADDR_LOAD  0x0006  /* load ru_base_reg */
+#define   RX_RESUMENR  0x0007
+
+// Interrupt fields (assuming byte addressing)
+#define INT_MASK  0x0100
+#define DRVR_INT  0x0200    /* Driver generated interrupt. */
+
+//- CB Status Word
+#define CMD_STATUS_COMPLETE 0x8000
+#define RX_STATUS_COMPLETE 0x8000
+#define CMD_STATUS_MASK 0xF000
+
+//-------------------------------------------------------------------------
+//- SCB Status bits:
+// Interrupts are ACKed by writing to the upper 6 interrupt bits
+//-------------------------------------------------------------------------
+#define SCB_STATUS_MASK        0xFC00 // bits 2-7 - STATUS/ACK Mask
+#define SCB_STATUS_CX_TNO      0x8000 // BIT_15  - CX or TNO Interrupt
+#define SCB_STATUS_FR          0x4000 // BIT_14 - FR Interrupt
+#define SCB_STATUS_CNA         0x2000 // BIT_13 - CNA Interrupt
+#define SCB_STATUS_RNR         0x1000 // BIT_12  - RNR Interrupt
+#define SCB_STATUS_MDI         0x0800 // BIT_11  - MDI R/W Done Interrupt
+#define SCB_STATUS_SWI         0x0400 // BIT_10  - SWI Interrupt
+
+// CU STATUS: bits 6 & 7
+#define SCB_STATUS_CU_MASK     0x00C0 // bits 6 & 7
+#define SCB_STATUS_CU_IDLE     0x0000 // 00
+#define SCB_STATUS_CU_SUSPEND  0x0040 // 01
+#define SCB_STATUS_CU_ACTIVE   0x0080 // 10
+
+// RU STATUS: bits 2-5
+#define SCB_RUS_IDLE         0x0000
+#define SCB_RUS_SUSPENDED    0x0004  // bit 2
+#define SCB_RUS_NO_RESOURCES   0x0008 // bit 3
+#define SCB_RUS_READY       0x0010 // bit 4
+
+//-------------------------------------------------------------------------
+// Bit Mask definitions
+//-------------------------------------------------------------------------
+#define BIT_0       0x0001
+#define BIT_1       0x0002
+#define BIT_2       0x0004
+#define BIT_3       0x0008
+#define BIT_4       0x0010
+#define BIT_5       0x0020
+#define BIT_6       0x0040
+#define BIT_7       0x0080
+#define BIT_8       0x0100
+#define BIT_9       0x0200
+#define BIT_10      0x0400
+#define BIT_11      0x0800
+#define BIT_12      0x1000
+#define BIT_13      0x2000
+#define BIT_14      0x4000
+#define BIT_15      0x8000
+#define BIT_24      0x01000000
+#define BIT_28      0x10000000
+
+
+//-------------------------------------------------------------------------
+// MDI Control register bit definitions
+//-------------------------------------------------------------------------
+#define MDI_DATA_MASK           BIT_0_15        // MDI Data port
+#define MDI_REG_ADDR            BIT_16_20       // which MDI register to read/write
+#define MDI_PHY_ADDR            BIT_21_25       // which PHY to read/write
+#define MDI_PHY_OPCODE          BIT_26_27       // which PHY to read/write
+#define MDI_PHY_READY           BIT_28          // PHY is ready for another MDI cycle
+#define MDI_PHY_INT_ENABLE      BIT_29          // Assert INT at MDI cycle completion
+
+#define BIT_0_2     0x0007
+#define BIT_0_3     0x000F
+#define BIT_0_4     0x001F
+#define BIT_0_5     0x003F
+#define BIT_0_6     0x007F
+#define BIT_0_7     0x00FF
+#define BIT_0_8     0x01FF
+#define BIT_0_13    0x3FFF
+#define BIT_0_15    0xFFFF
+#define BIT_1_2     0x0006
+#define BIT_1_3     0x000E
+#define BIT_2_5     0x003C
+#define BIT_3_4     0x0018
+#define BIT_4_5     0x0030
+#define BIT_4_6     0x0070
+#define BIT_4_7     0x00F0
+#define BIT_5_7     0x00E0
+#define BIT_5_9     0x03E0
+#define BIT_5_12    0x1FE0
+#define BIT_5_15    0xFFE0
+#define BIT_6_7     0x00c0
+#define BIT_7_11    0x0F80
+#define BIT_8_10    0x0700
+#define BIT_9_13    0x3E00
+#define BIT_12_15   0xF000
+
+#define BIT_16_20   0x001F0000
+#define BIT_21_25   0x03E00000
+#define BIT_26_27   0x0C000000
+
+//-------------------------------------------------------------------------
+// MDI Control register opcode definitions
+//-------------------------------------------------------------------------
+#define MDI_WRITE               1               // Phy Write
+#define MDI_READ                2               // Phy read
+
+//-------------------------------------------------------------------------
+// PHY 100 MDI Register/Bit Definitions
+//-------------------------------------------------------------------------
+// MDI register set
+#define MDI_CONTROL_REG             0x00        // MDI control register
+#define MDI_STATUS_REG              0x01        // MDI Status regiser
+#define PHY_ID_REG_1                0x02        // Phy indentification reg (word 1)
+#define PHY_ID_REG_2                0x03        // Phy indentification reg (word 2)
+#define AUTO_NEG_ADVERTISE_REG      0x04        // Auto-negotiation advertisement
+#define AUTO_NEG_LINK_PARTNER_REG   0x05        // Auto-negotiation link partner ability
+#define AUTO_NEG_EXPANSION_REG      0x06        // Auto-negotiation expansion
+#define AUTO_NEG_NEXT_PAGE_REG      0x07        // Auto-negotiation next page transmit
+#define EXTENDED_REG_0              0x10        // Extended reg 0 (Phy 100 modes)
+#define EXTENDED_REG_1              0x14        // Extended reg 1 (Phy 100 error indications)
+#define NSC_CONG_CONTROL_REG        0x17        // National (TX) congestion control
+#define NSC_SPEED_IND_REG           0x19        // National (TX) speed indication
+
+// MDI Control register bit definitions
+#define MDI_CR_COLL_TEST_ENABLE     BIT_7       // Collision test enable
+#define MDI_CR_FULL_HALF            BIT_8       // FDX =1, half duplex =0
+#define MDI_CR_RESTART_AUTO_NEG     BIT_9       // Restart auto negotiation
+#define MDI_CR_ISOLATE              BIT_10      // Isolate PHY from MII
+#define MDI_CR_POWER_DOWN           BIT_11      // Power down
+#define MDI_CR_AUTO_SELECT          BIT_12      // Auto speed select enable
+#define MDI_CR_10_100               BIT_13      // 0 = 10Mbs, 1 = 100Mbs
+#define MDI_CR_LOOPBACK             BIT_14      // 0 = normal, 1 = loopback
+#define MDI_CR_RESET                BIT_15      // 0 = normal, 1 = PHY reset
+
+// MDI Status register bit definitions
+#define MDI_SR_EXT_REG_CAPABLE      BIT_0       // Extended register capabilities
+#define MDI_SR_JABBER_DETECT        BIT_1       // Jabber detected
+#define MDI_SR_LINK_STATUS          BIT_2       // Link Status -- 1 = link
+#define MDI_SR_AUTO_SELECT_CAPABLE  BIT_3       // Auto speed select capable
+#define MDI_SR_REMOTE_FAULT_DETECT  BIT_4       // Remote fault detect
+#define MDI_SR_AUTO_NEG_COMPLETE    BIT_5       // Auto negotiation complete
+#define MDI_SR_10T_HALF_DPX         BIT_11      // 10BaseT Half Duplex capable
+#define MDI_SR_10T_FULL_DPX         BIT_12      // 10BaseT full duplex capable
+#define MDI_SR_TX_HALF_DPX          BIT_13      // TX Half Duplex capable
+#define MDI_SR_TX_FULL_DPX          BIT_14      // TX full duplex capable
+#define MDI_SR_T4_CAPABLE           BIT_15      // T4 capable
+
+// Auto-Negotiation advertisement register bit definitions
+#define NWAY_AD_SELCTOR_FIELD       BIT_0_4     // identifies supported protocol
+#define NWAY_AD_ABILITY             BIT_5_12    // technologies that are supported
+#define NWAY_AD_10T_HALF_DPX        BIT_5       // 10BaseT Half Duplex capable
+#define NWAY_AD_10T_FULL_DPX        BIT_6       // 10BaseT full duplex capable
+#define NWAY_AD_TX_HALF_DPX         BIT_7       // TX Half Duplex capable
+#define NWAY_AD_TX_FULL_DPX         BIT_8       // TX full duplex capable
+#define NWAY_AD_T4_CAPABLE          BIT_9       // T4 capable
+#define NWAY_AD_REMOTE_FAULT        BIT_13      // indicates local remote fault
+#define NWAY_AD_RESERVED            BIT_14      // reserved
+#define NWAY_AD_NEXT_PAGE           BIT_15      // Next page (not supported)
+
+// Auto-Negotiation link partner ability register bit definitions
+#define NWAY_LP_SELCTOR_FIELD       BIT_0_4     // identifies supported protocol
+#define NWAY_LP_ABILITY             BIT_5_9     // technologies that are supported
+#define NWAY_LP_REMOTE_FAULT        BIT_13      // indicates partner remote fault
+#define NWAY_LP_ACKNOWLEDGE         BIT_14      // acknowledge
+#define NWAY_LP_NEXT_PAGE           BIT_15      // Next page (not supported)
+
+// Auto-Negotiation expansion register bit definitions
+#define NWAY_EX_LP_NWAY             BIT_0       // link partner is NWAY
+#define NWAY_EX_PAGE_RECEIVED       BIT_1       // link code word received
+#define NWAY_EX_NEXT_PAGE_ABLE      BIT_2       // local is next page able
+#define NWAY_EX_LP_NEXT_PAGE_ABLE   BIT_3       // partner is next page able
+#define NWAY_EX_PARALLEL_DET_FLT    BIT_4       // parallel detection fault
+#define NWAY_EX_RESERVED            BIT_5_15    // reserved
+
+
+// PHY 100 Extended Register 0 bit definitions
+#define PHY_100_ER0_FDX_INDIC       BIT_0       // 1 = FDX, 0 = half duplex
+#define PHY_100_ER0_SPEED_INDIC     BIT_1       // 1 = 100mbs, 0= 10mbs
+#define PHY_100_ER0_WAKE_UP         BIT_2       // Wake up DAC
+#define PHY_100_ER0_RESERVED        BIT_3_4     // Reserved
+#define PHY_100_ER0_REV_CNTRL       BIT_5_7     // Revsion control (A step = 000)
+#define PHY_100_ER0_FORCE_FAIL      BIT_8       // Force Fail is enabled
+#define PHY_100_ER0_TEST            BIT_9_13    // Revsion control (A step = 000)
+#define PHY_100_ER0_LINKDIS         BIT_14      // Link integrity test is disabled
+#define PHY_100_ER0_JABDIS          BIT_15      // Jabber function is disabled
+
+
+// PHY 100 Extended Register 1 bit definitions
+#define PHY_100_ER1_RESERVED        BIT_0_8     // Reserved
+#define PHY_100_ER1_CH2_DET_ERR     BIT_9       // Channel 2 EOF detection error
+#define PHY_100_ER1_MANCH_CODE_ERR  BIT_10      // Manchester code error
+#define PHY_100_ER1_EOP_ERR         BIT_11      // EOP error
+#define PHY_100_ER1_BAD_CODE_ERR    BIT_12      // bad code error
+#define PHY_100_ER1_INV_CODE_ERR    BIT_13      // invalid code error
+#define PHY_100_ER1_DC_BAL_ERR      BIT_14      // DC balance error
+#define PHY_100_ER1_PAIR_SKEW_ERR   BIT_15      // Pair skew error
+
+// National Semiconductor TX phy congestion control register bit definitions
+#define NSC_TX_CONG_TXREADY         BIT_10      // Makes TxReady an input
+#define NSC_TX_CONG_ENABLE          BIT_8       // Enables congestion control
+#define NSC_TX_CONG_F_CONNECT       BIT_5       // Enables congestion control
+
+// National Semiconductor TX phy speed indication register bit definitions
+#define NSC_TX_SPD_INDC_SPEED       BIT_6       // 0 = 100mb, 1=10mb
+
+//-------------------------------------------------------------------------
+// Phy related constants
+//-------------------------------------------------------------------------
+#define PHY_503                 0
+#define PHY_100_A               0x000003E0
+#define PHY_100_C               0x035002A8
+#define PHY_TX_ID               0x015002A8
+#define PHY_NSC_TX              0x5c002000
+#define PHY_OTHER               0xFFFF
+
+#define PHY_MODEL_REV_ID_MASK   0xFFF0FFFF
+#define PARALLEL_DETECT         0
+#define N_WAY                   1
+
+#define RENEGOTIATE_TIME        35 // (3.5 Seconds)
+
+#define CONNECTOR_AUTO          0
+#define CONNECTOR_TPE           1
+#define CONNECTOR_MII           2
+
+//-------------------------------------------------------------------------
+
+/* The Speedo3 Rx and Tx frame/buffer descriptors. */
+#pragma pack(1)
+struct CB_Header {      /* A generic descriptor. */
+  UINT16 status;    /* Offset 0. */
+  UINT16 command;    /* Offset 2. */
+  UINT32 link;          /* struct descriptor *  */
+};
+
+/* transmit command block structure */
+#pragma pack(1)
+typedef struct s_TxCB {
+  struct CB_Header cb_header;
+  UINT32 PhysTBDArrayAddres;  /* address of an array that contains
+                physical TBD pointers */
+  UINT16 ByteCount;  /* immediate data count = 0 always */
+  UINT8 Threshold;
+  UINT8 TBDCount;
+  UINT8 ImmediateData[TX_BUFFER_SIZE];
+  /* following fields are not seen by the 82557 */
+  struct TBD {
+    UINT32 phys_buf_addr;
+    UINT32 buf_len;
+    } TBDArray[MAX_XMIT_FRAGMENTS];
+  UINT32 PhysArrayAddr;  /* in case the one in the header is lost */
+  UINT32 PhysTCBAddress;    /* for this TCB */
+  struct s_TxCB *NextTCBVirtualLinkPtr;
+  struct s_TxCB *PrevTCBVirtualLinkPtr;
+  UINT64 free_data_ptr;  // to be given to the upper layer when this xmit completes1
+}TxCB;
+
+/* The Speedo3 Rx and Tx buffer descriptors. */
+#pragma pack(1)
+typedef struct s_RxFD {          /* Receive frame descriptor. */
+  struct CB_Header cb_header;
+  UINT32 rx_buf_addr;      /* VOID * */
+  UINT16 ActualCount;
+  UINT16 RFDSize;
+  UINT8 RFDBuffer[RX_BUFFER_SIZE];
+  UINT8 forwarded;
+  UINT8 junk[3];
+}RxFD;
+
+/* Elements of the RxFD.status word. */
+#define RX_COMPLETE 0x8000
+#define RX_FRAME_OK 0x2000
+
+/* Elements of the dump_statistics block. This block must be lword aligned. */
+#pragma pack(1)
+struct speedo_stats {
+  UINT32 tx_good_frames;
+  UINT32 tx_coll16_errs;
+  UINT32 tx_late_colls;
+  UINT32 tx_underruns;
+  UINT32 tx_lost_carrier;
+  UINT32 tx_deferred;
+  UINT32 tx_one_colls;
+  UINT32 tx_multi_colls;
+  UINT32 tx_total_colls;
+  UINT32 rx_good_frames;
+  UINT32 rx_crc_errs;
+  UINT32 rx_align_errs;
+  UINT32 rx_resource_errs;
+  UINT32 rx_overrun_errs;
+  UINT32 rx_colls_errs;
+  UINT32 rx_runt_errs;
+  UINT32 done_marker;
+};
+#pragma pack()
+
+
+struct Krn_Mem{
+  RxFD rx_ring[RX_BUFFER_COUNT];
+  TxCB tx_ring[TX_BUFFER_COUNT];
+  struct speedo_stats statistics;
+};
+#define MEMORY_NEEDED  sizeof(struct Krn_Mem)
+
+/* The parameters for a CmdConfigure operation.
+   There are so many options that it would be difficult to document each bit.
+   We mostly use the default or recommended settings.
+*/
+
+/*
+ *--------------------------------------------------------------------------
+ * Configuration CB Parameter Bit Definitions
+ *--------------------------------------------------------------------------
+ */
+// - Byte 0  (Default Value = 16h)
+#define CFIG_BYTE_COUNT    0x16       // 22 Configuration Bytes
+
+//- Byte 1  (Default Value = 88h)
+#define CFIG_TXRX_FIFO_LIMIT  0x88
+
+//- Byte 2  (Default Value = 0)
+#define CFIG_ADAPTIVE_IFS    0
+
+//- Byte 3  (Default Value = 0, ALWAYS. This byte is RESERVED)
+#define CFIG_RESERVED        0
+
+//- Byte 4  (Default Value = 0. Default implies that Rx DMA cannot be
+//-          preempted).
+#define CFIG_RXDMA_BYTE_COUNT      0
+
+//- Byte 5  (Default Value = 80h. Default implies that Tx DMA cannot be
+//-          preempted. However, setting these counters is enabled.)
+#define CFIG_DMBC_ENABLE            0x80
+
+//- Byte 6  (Default Value = 33h. Late SCB enabled, No TNO interrupts,
+//-          CNA interrupts and do not save bad frames.)
+#define CFIG_LATE_SCB               1  // BIT 0
+#define CFIG_TNO_INTERRUPT          0x4  // BIT 2
+#define CFIG_CI_INTERRUPT           0x8  // BIT 3
+#define CFIG_SAVE_BAD_FRAMES        0x80  // BIT_7
+
+//- Byte 7  (Default Value = 7h. Discard short frames automatically and
+//-          attempt upto 3 retries on transmit.)
+#define CFIG_DISCARD_SHORTRX         0x00001
+#define CFIG_URUN_RETRY              BIT_1 OR BIT_2
+
+//- Byte 8  (Default Value = 1. Enable MII mode.)
+#define CFIG_503_MII              BIT_0
+
+//- Byte 9  (Default Value = 0, ALWAYS)
+
+//- Byte 10 (Default Value = 2Eh)
+#define CFIG_NSAI                   BIT_3
+#define CFIG_PREAMBLE_LENGTH         BIT_5      ;- Bit 5-4  = 1-0
+#define CFIG_NO_LOOPBACK             0
+#define CFIG_INTERNAL_LOOPBACK       BIT_6
+#define CFIG_EXT_LOOPBACK            BIT_7
+#define CFIG_EXT_PIN_LOOPBACK        BIT_6 OR BIT_7
+
+//- Byte 11 (Default Value = 0)
+#define CFIG_LINEAR_PRIORITY         0
+
+//- Byte 12 (Default Value = 60h)
+#define CFIG_LPRIORITY_MODE          0
+#define CFIG_IFS                     6          ;- 6 * 16 = 96
+
+//- Byte 13 (Default Value = 0, ALWAYS)
+
+//- Byte 14 (Default Value = 0F2h, ALWAYS)
+
+//- Byte 15 (Default Value = E8h)
+#define CFIG_PROMISCUOUS_MODE        BIT_0
+#define CFIG_BROADCAST_DISABLE       BIT_1
+#define CFIG_CRS_CDT                 BIT_7
+
+//- Byte 16 (Default Value = 0, ALWAYS)
+
+//- Byte 17 (Default Value = 40h, ALWAYS)
+
+//- Byte 18 (Default Value = F2h)
+#define CFIG_STRIPPING               BIT_0
+#define CFIG_PADDING                 BIT_1
+#define CFIG_RX_CRC_TRANSFER         BIT_2
+
+//- Byte 19 (Default Value = 80h)
+#define CFIG_FORCE_FDX               BIT_6
+#define CFIG_FDX_PIN_ENABLE          BIT_7
+
+//- Byte 20 (Default Value = 3Fh)
+#define CFIG_MULTI_IA                BIT_6
+
+//- Byte 21 (Default Value = 05)
+#define CFIG_MC_ALL                  BIT_3
+
+/*-----------------------------------------------------------------------*/
+#define D102_REVID 0x0b
+
+#define HALF_DUPLEX 1
+#define FULL_DUPLEX 2
+
+typedef struct s_data_instance {
+
+  UINT16 State;  // stopped, started or initialized
+  UINT16 Bus;
+  UINT8 Device;
+  UINT8 Function;
+  UINT16 VendorID;
+  UINT16 DeviceID;
+  UINT16 RevID;
+  UINT16 SubVendorID;
+  UINT16 SubSystemID;
+
+  UINT8 PermNodeAddress[PXE_MAC_LENGTH];
+  UINT8 CurrentNodeAddress[PXE_MAC_LENGTH];
+  UINT8 BroadcastNodeAddress[PXE_MAC_LENGTH];
+  UINT32 Config[MAX_PCI_CONFIG_LEN];
+  UINT32 NVData[MAX_EEPROM_LEN];
+
+  UINT32 ioaddr;
+  UINT32 flash_addr;
+
+  UINT16 LinkSpeed;     // actual link speed setting
+  UINT16 LinkSpeedReq;  // requested (forced) link speed
+  UINT8  DuplexReq;     // requested duplex
+  UINT8  Duplex;        // Duplex set
+  UINT8  CableDetect;   // 1 to detect and 0 not to detect the cable
+  UINT8  LoopBack;
+
+  UINT16 TxBufCnt;
+  UINT16 TxBufSize;
+  UINT16 RxBufCnt;
+  UINT16 RxBufSize;
+  UINT32 RxTotals;
+  UINT32 TxTotals;
+
+  UINT16 int_mask;
+  UINT16 Int_Status;
+  UINT16 PhyRecord[2];  // primary and secondary PHY record registers from eeprom
+  UINT8  PhyAddress;
+  UINT8  int_num;
+  UINT16 NVData_Len;
+  UINT32 MemoryLength;
+
+  RxFD *rx_ring;  // array of rx buffers
+  TxCB *tx_ring;  // array of tx buffers
+  struct speedo_stats *statistics;
+  TxCB *FreeTxHeadPtr;
+  TxCB *FreeTxTailPtr;
+  RxFD *RFDTailPtr;
+
+  UINT64 rx_phy_addr;  // physical addresses
+  UINT64 tx_phy_addr;
+  UINT64 stat_phy_addr;
+  UINT64 MemoryPtr;
+  UINT64 Mapped_MemoryPtr;
+
+  UINT64 xmit_done[TX_BUFFER_COUNT << 1]; // circular buffer
+  UINT16 xmit_done_head;  // index into the xmit_done array
+  UINT16 xmit_done_tail;  // where are we filling now (index into xmit_done)
+  UINT16 cur_rx_ind;  // current RX Q head index
+  UINT16 FreeCBCount;
+
+  BOOLEAN in_interrupt;
+  BOOLEAN in_transmit;
+  BOOLEAN Receive_Started;
+  UINT8 Rx_Filter;
+  UINT8 VersionFlag;  // UNDI30 or UNDI31??
+  UINT8 rsvd[3];
+
+  struct mc{
+    UINT16 reserved [3]; // padding for this structure to make it 8 byte aligned
+    UINT16 list_len;
+    UINT8 mc_list[MAX_MCAST_ADDRESS_CNT][PXE_MAC_LENGTH]; // 8*32 is the size
+  } mcast_list;
+
+  UINT64 Unique_ID;
+
+  EFI_PCI_IO_PROTOCOL   *Io_Function;
+  //
+  // Original PCI attributes
+  //
+  UINT64                OriginalPciAttributes;
+
+  VOID (*Delay_30)(UINTN);  // call back routine
+  VOID (*Virt2Phys_30)(UINT64 virtual_addr, UINT64 physical_ptr);  // call back routine
+  VOID (*Block_30)(UINT32 enable);  // call back routine
+  VOID (*Mem_Io_30)(UINT8 read_write, UINT8 len, UINT64 port, UINT64 buf_addr);
+  VOID (*Delay)(UINT64, UINTN);  // call back routine
+  VOID (*Virt2Phys)(UINT64 unq_id, UINT64 virtual_addr, UINT64 physical_ptr);  // call back routine
+  VOID (*Block)(UINT64 unq_id, UINT32 enable);  // call back routine
+  VOID (*Mem_Io)(UINT64 unq_id, UINT8 read_write, UINT8 len, UINT64 port,
+          UINT64 buf_addr);
+  VOID (*Map_Mem)(UINT64 unq_id, UINT64 virtual_addr, UINT32 size,
+                   UINT32 Direction, UINT64 mapped_addr);
+  VOID (*UnMap_Mem)(UINT64 unq_id, UINT64 virtual_addr, UINT32 size,
+            UINT32 Direction, UINT64 mapped_addr);
+  VOID (*Sync_Mem)(UINT64 unq_id, UINT64 virtual_addr,
+            UINT32 size, UINT32 Direction, UINT64 mapped_addr);
+} NIC_DATA_INSTANCE;
+
+#pragma pack(1)
+struct MC_CB_STRUCT{
+  UINT16 count;
+  UINT8 m_list[MAX_MCAST_ADDRESS_CNT][ETHER_MAC_ADDR_LEN];
+};
+#pragma pack()
+
+#define FOUR_GIGABYTE (UINT64)0x100000000ULL
+
+#endif
+
diff --git a/Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c b/Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c
new file mode 100644
index 0000000000..2625a6cc5c
--- /dev/null
+++ b/Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c
@@ -0,0 +1,1051 @@
+/** @file
+  Initialization functions for EFI UNDI32 driver.
+
+Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Undi32.h"
+//
+// Global Variables
+//
+
+PXE_SW_UNDI             *pxe_31 = NULL;  // 3.1 entry
+UNDI32_DEV              *UNDI32DeviceList[MAX_NIC_INTERFACES];
+UNDI_CONFIG_TABLE       *UndiDataPointer = NULL;
+
+//
+// UNDI Class Driver Global Variables
+//
+EFI_DRIVER_BINDING_PROTOCOL  gUndiDriverBinding = {
+  UndiDriverSupported,
+  UndiDriverStart,
+  UndiDriverStop,
+  0xa,
+  NULL,
+  NULL
+};
+
+
+/**
+  When address mapping changes to virtual this should make the appropriate
+  address conversions.
+
+  (Standard Event handler)
+
+  @return None
+
+**/
+VOID
+EFIAPI
+UndiNotifyVirtual (
+  EFI_EVENT Event,
+  VOID      *Context
+  )
+{
+  UINT16  Index;
+  VOID    *Pxe31Pointer;
+
+  if (pxe_31 != NULL) {
+    Pxe31Pointer = (VOID *) pxe_31;
+
+    EfiConvertPointer (
+      EFI_OPTIONAL_PTR,
+      (VOID **) &Pxe31Pointer
+      );
+
+    //
+    // UNDI32DeviceList is an array of pointers
+    //
+    for (Index = 0; Index < (pxe_31->IFcnt | pxe_31->IFcntExt << 8); Index++) {
+      UNDI32DeviceList[Index]->NIIProtocol_31.Id = (UINT64) (UINTN) Pxe31Pointer;
+      EfiConvertPointer (
+        EFI_OPTIONAL_PTR,
+        (VOID **) &(UNDI32DeviceList[Index])
+        );
+    }
+
+    EfiConvertPointer (
+      EFI_OPTIONAL_PTR,
+      (VOID **) &(pxe_31->EntryPoint)
+      );
+    pxe_31 = Pxe31Pointer;
+  }
+
+  for (Index = 0; Index <= PXE_OPCODE_LAST_VALID; Index++) {
+    EfiConvertPointer (
+      EFI_OPTIONAL_PTR,
+      (VOID **) &api_table[Index].api_ptr
+      );
+  }
+}
+
+
+/**
+  When EFI is shuting down the boot services, we need to install a
+  configuration table for UNDI to work at runtime!
+
+  (Standard Event handler)
+
+  @return None
+
+**/
+VOID
+EFIAPI
+UndiNotifyReadyToBoot (
+  EFI_EVENT Event,
+  VOID      *Context
+  )
+{
+  InstallConfigTable ();
+}
+
+
+/**
+  Test to see if this driver supports ControllerHandle. Any ControllerHandle
+  than contains a  DevicePath, PciIo protocol, Class code of 2, Vendor ID of 0x8086,
+  and DeviceId of (D100_DEVICE_ID || D102_DEVICE_ID || ICH3_DEVICE_ID_1 ||
+  ICH3_DEVICE_ID_2 || ICH3_DEVICE_ID_3 || ICH3_DEVICE_ID_4 || ICH3_DEVICE_ID_5 ||
+  ICH3_DEVICE_ID_6 || ICH3_DEVICE_ID_7 || ICH3_DEVICE_ID_8) can be supported.
+
+  @param  This                 Protocol instance pointer.
+  @param  Controller           Handle of device to test.
+  @param  RemainingDevicePath  Not used.
+
+  @retval EFI_SUCCESS          This driver supports this device.
+  @retval other                This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+UndiDriverSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  )
+{
+  EFI_STATUS          Status;
+  EFI_PCI_IO_PROTOCOL *PciIo;
+  PCI_TYPE00          Pci;
+
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiDevicePathProtocolGuid,
+                  NULL,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **) &PciIo,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint8,
+                        0,
+                        sizeof (PCI_CONFIG_HEADER),
+                        &Pci
+                        );
+
+  if (!EFI_ERROR (Status)) {
+    Status = EFI_UNSUPPORTED;
+
+    if (Pci.Hdr.ClassCode[2] == 0x02 && Pci.Hdr.VendorId == PCI_VENDOR_ID_INTEL) {
+      switch (Pci.Hdr.DeviceId) {
+      case D100_DEVICE_ID:
+      case D102_DEVICE_ID:
+      case ICH3_DEVICE_ID_1:
+      case ICH3_DEVICE_ID_2:
+      case ICH3_DEVICE_ID_3:
+      case ICH3_DEVICE_ID_4:
+      case ICH3_DEVICE_ID_5:
+      case ICH3_DEVICE_ID_6:
+      case ICH3_DEVICE_ID_7:
+      case ICH3_DEVICE_ID_8:
+      case 0x1039:
+      case 0x103A:
+      case 0x103B:
+      case 0x103C:
+      case 0x103D:
+      case 0x103E:
+      case 0x1050:
+      case 0x1051:
+      case 0x1052:
+      case 0x1053:
+      case 0x1054:
+      case 0x1055:
+      case 0x1056:
+      case 0x1057:
+      case 0x1059:
+      case 0x1064:
+        Status = EFI_SUCCESS;
+      }
+    }
+  }
+
+  gBS->CloseProtocol (
+        Controller,
+        &gEfiPciIoProtocolGuid,
+        This->DriverBindingHandle,
+        Controller
+        );
+
+  return Status;
+}
+
+
+/**
+  Start this driver on Controller by opening PciIo and DevicePath protocol.
+  Initialize PXE structures, create a copy of the Controller Device Path with the
+  NIC's MAC address appended to it, install the NetworkInterfaceIdentifier protocol
+  on the newly created Device Path.
+
+  @param  This                 Protocol instance pointer.
+  @param  Controller           Handle of device to work with.
+  @param  RemainingDevicePath  Not used, always produce all possible children.
+
+  @retval EFI_SUCCESS          This driver is added to Controller.
+  @retval other                This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+UndiDriverStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  )
+{
+  EFI_STATUS                Status;
+  EFI_DEVICE_PATH_PROTOCOL  *UndiDevicePath;
+  PCI_CONFIG_HEADER         *CfgHdr;
+  UNDI32_DEV                *UNDI32Device;
+  UINT16                    NewCommand;
+  UINT8                     *TmpPxePointer;
+  EFI_PCI_IO_PROTOCOL       *PciIoFncs;
+  UINTN                     Len;
+  UINT64                    Supports;
+  BOOLEAN                   PciAttributesSaved;
+
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **) &PciIoFncs,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID **) &UndiDevicePath,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+
+  if (EFI_ERROR (Status)) {
+    gBS->CloseProtocol (
+          Controller,
+          &gEfiPciIoProtocolGuid,
+          This->DriverBindingHandle,
+          Controller
+          );
+
+    return Status;
+  }
+
+  PciAttributesSaved = FALSE;
+
+  Status = gBS->AllocatePool (
+                  EfiRuntimeServicesData,
+                  sizeof (UNDI32_DEV),
+                  (VOID **) &UNDI32Device
+                  );
+
+  if (EFI_ERROR (Status)) {
+    goto UndiError;
+  }
+
+  ZeroMem ((CHAR8 *) UNDI32Device, sizeof (UNDI32_DEV));
+
+  //
+  // Get original PCI attributes
+  //
+  Status = PciIoFncs->Attributes (
+                    PciIoFncs,
+                    EfiPciIoAttributeOperationGet,
+                    0,
+                    &UNDI32Device->NicInfo.OriginalPciAttributes
+                    );
+
+  if (EFI_ERROR (Status)) {
+    goto UndiErrorDeleteDevice;
+  }
+  PciAttributesSaved = TRUE;
+
+  //
+  // allocate and initialize both (old and new) the !pxe structures here,
+  // there should only be one copy of each of these structure for any number
+  // of NICs this undi supports. Also, these structures need to be on a
+  // paragraph boundary as per the spec. so, while allocating space for these,
+  // make sure that there is space for 2 !pxe structures (old and new) and a
+  // 32 bytes padding for alignment adjustment (in case)
+  //
+  TmpPxePointer = NULL;
+  if (pxe_31 == NULL) {
+    Status = gBS->AllocatePool (
+                    EfiRuntimeServicesData,
+                    (sizeof (PXE_SW_UNDI) + sizeof (PXE_SW_UNDI) + 32),
+                    (VOID **) &TmpPxePointer
+                    );
+
+    if (EFI_ERROR (Status)) {
+      goto UndiErrorDeleteDevice;
+    }
+
+    ZeroMem (
+      TmpPxePointer,
+      sizeof (PXE_SW_UNDI) + sizeof (PXE_SW_UNDI) + 32
+      );
+    //
+    // check for paragraph alignment here, assuming that the pointer is
+    // already 8 byte aligned.
+    //
+    if (((UINTN) TmpPxePointer & 0x0F) != 0) {
+      pxe_31 = (PXE_SW_UNDI *) ((UINTN) (TmpPxePointer + 8));
+    } else {
+      pxe_31 = (PXE_SW_UNDI *) TmpPxePointer;
+    }
+
+    PxeStructInit (pxe_31);
+  }
+
+  UNDI32Device->NIIProtocol_31.Id = (UINT64) (UINTN) (pxe_31);
+
+  Status = PciIoFncs->Attributes (
+                        PciIoFncs,
+                        EfiPciIoAttributeOperationSupported,
+                        0,
+                        &Supports
+                        );
+  if (!EFI_ERROR (Status)) {
+    Supports &= EFI_PCI_DEVICE_ENABLE;
+    Status = PciIoFncs->Attributes (
+                          PciIoFncs,
+                          EfiPciIoAttributeOperationEnable,
+                          Supports,
+                          NULL
+                          );
+  }
+  //
+  // Read all the registers from device's PCI Configuration space
+  //
+  Status = PciIoFncs->Pci.Read (
+                            PciIoFncs,
+                            EfiPciIoWidthUint32,
+                            0,
+                            MAX_PCI_CONFIG_LEN,
+                            &UNDI32Device->NicInfo.Config
+                            );
+
+  CfgHdr = (PCI_CONFIG_HEADER *) &(UNDI32Device->NicInfo.Config[0]);
+
+  //
+  // make sure that this device is a PCI bus master
+  //
+
+  NewCommand = (UINT16) (CfgHdr->Command | PCI_COMMAND_MASTER | PCI_COMMAND_IO);
+  if (CfgHdr->Command != NewCommand) {
+    PciIoFncs->Pci.Write (
+                    PciIoFncs,
+                    EfiPciIoWidthUint16,
+                    PCI_COMMAND,
+                    1,
+                    &NewCommand
+                    );
+    CfgHdr->Command = NewCommand;
+  }
+
+  //
+  // make sure that the latency timer is at least 32
+  //
+  if (CfgHdr->LatencyTimer < 32) {
+    CfgHdr->LatencyTimer = 32;
+    PciIoFncs->Pci.Write (
+                    PciIoFncs,
+                    EfiPciIoWidthUint8,
+                    PCI_LATENCY_TIMER,
+                    1,
+                    &CfgHdr->LatencyTimer
+                    );
+  }
+  //
+  // the IfNum index for the current interface will be the total number
+  // of interfaces initialized so far
+  //
+  UNDI32Device->NIIProtocol_31.IfNum  = pxe_31->IFcnt | pxe_31->IFcntExt << 8;
+
+  PxeUpdate (&UNDI32Device->NicInfo, pxe_31);
+
+  UNDI32Device->NicInfo.Io_Function                    = PciIoFncs;
+  UNDI32DeviceList[UNDI32Device->NIIProtocol_31.IfNum] = UNDI32Device;
+  UNDI32Device->Undi32BaseDevPath                      = UndiDevicePath;
+
+  Status = AppendMac2DevPath (
+            &UNDI32Device->Undi32DevPath,
+            UNDI32Device->Undi32BaseDevPath,
+            &UNDI32Device->NicInfo
+            );
+
+  if (Status != 0) {
+    goto UndiErrorDeletePxe;
+  }
+
+  UNDI32Device->Signature                     = UNDI_DEV_SIGNATURE;
+
+  UNDI32Device->NIIProtocol_31.Revision       = EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION_31;
+  UNDI32Device->NIIProtocol_31.Type           = EfiNetworkInterfaceUndi;
+  UNDI32Device->NIIProtocol_31.MajorVer       = PXE_ROMID_MAJORVER;
+  UNDI32Device->NIIProtocol_31.MinorVer       = PXE_ROMID_MINORVER_31;
+  UNDI32Device->NIIProtocol_31.ImageSize      = 0;
+  UNDI32Device->NIIProtocol_31.ImageAddr      = 0;
+  UNDI32Device->NIIProtocol_31.Ipv6Supported  = TRUE;
+
+  UNDI32Device->NIIProtocol_31.StringId[0]    = 'U';
+  UNDI32Device->NIIProtocol_31.StringId[1]    = 'N';
+  UNDI32Device->NIIProtocol_31.StringId[2]    = 'D';
+  UNDI32Device->NIIProtocol_31.StringId[3]    = 'I';
+
+  UNDI32Device->DeviceHandle                  = NULL;
+
+  UNDI32Device->Aip.GetInformation            = UndiAipGetInfo;
+  UNDI32Device->Aip.SetInformation            = UndiAipSetInfo;
+  UNDI32Device->Aip.GetSupportedTypes         = UndiAipGetSupportedTypes;
+
+  //
+  // install both the 3.0 and 3.1 NII protocols.
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &UNDI32Device->DeviceHandle,
+                  &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
+                  &UNDI32Device->NIIProtocol_31,
+                  &gEfiDevicePathProtocolGuid,
+                  UNDI32Device->Undi32DevPath,
+                  &gEfiAdapterInformationProtocolGuid,
+                  &UNDI32Device->Aip,
+                  NULL
+                  );
+
+  if (EFI_ERROR (Status)) {
+    goto UndiErrorDeleteDevicePath;
+  }
+
+  //
+  // if the table exists, free it and alloc again, or alloc it directly
+  //
+  if (UndiDataPointer != NULL) {
+    Status = gBS->FreePool(UndiDataPointer);
+  }
+  if (EFI_ERROR (Status)) {
+    goto UndiErrorDeleteDevicePath;
+  }
+
+  Len = ((pxe_31->IFcnt|pxe_31->IFcntExt << 8)* sizeof (UndiDataPointer->NII_entry)) + sizeof (UndiDataPointer);
+  Status = gBS->AllocatePool (EfiRuntimeServicesData, Len, (VOID **) &UndiDataPointer);
+
+  if (EFI_ERROR (Status)) {
+    goto UndiErrorAllocDataPointer;
+  }
+
+  //
+  // Open For Child Device
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **) &PciIoFncs,
+                  This->DriverBindingHandle,
+                  UNDI32Device->DeviceHandle,
+                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+                  );
+
+  return EFI_SUCCESS;
+UndiErrorAllocDataPointer:
+  gBS->UninstallMultipleProtocolInterfaces (
+                  &UNDI32Device->DeviceHandle,
+                  &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
+                  &UNDI32Device->NIIProtocol_31,
+                  &gEfiDevicePathProtocolGuid,
+                  UNDI32Device->Undi32DevPath,
+                  &gEfiAdapterInformationProtocolGuid,
+                  &UNDI32Device->Aip,
+                  NULL
+                  );
+
+UndiErrorDeleteDevicePath:
+  UNDI32DeviceList[UNDI32Device->NIIProtocol_31.IfNum] = NULL;
+  gBS->FreePool (UNDI32Device->Undi32DevPath);
+
+UndiErrorDeletePxe:
+  PxeUpdate (NULL, pxe_31);
+  if (TmpPxePointer != NULL) {
+    gBS->FreePool (TmpPxePointer);
+
+  }
+
+UndiErrorDeleteDevice:
+  if (PciAttributesSaved) {
+    //
+    // Restore original PCI attributes
+    //
+    PciIoFncs->Attributes (
+                    PciIoFncs,
+                    EfiPciIoAttributeOperationSet,
+                    UNDI32Device->NicInfo.OriginalPciAttributes,
+                    NULL
+                    );
+  }
+
+  gBS->FreePool (UNDI32Device);
+
+UndiError:
+  gBS->CloseProtocol (
+        Controller,
+        &gEfiDevicePathProtocolGuid,
+        This->DriverBindingHandle,
+        Controller
+        );
+
+  gBS->CloseProtocol (
+        Controller,
+        &gEfiPciIoProtocolGuid,
+        This->DriverBindingHandle,
+        Controller
+        );
+
+  return Status;
+}
+
+
+/**
+  Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and
+  closing the DevicePath and PciIo protocols on Controller.
+
+  @param  This                 Protocol instance pointer.
+  @param  Controller           Handle of device to stop driver on.
+  @param  NumberOfChildren     How many children need to be stopped.
+  @param  ChildHandleBuffer    Not used.
+
+  @retval EFI_SUCCESS          This driver is removed Controller.
+  @retval other                This driver was not removed from this device.
+
+**/
+// TODO:    EFI_DEVICE_ERROR - add return value to function comment
+EFI_STATUS
+EFIAPI
+UndiDriverStop (
+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN  EFI_HANDLE                     Controller,
+  IN  UINTN                          NumberOfChildren,
+  IN  EFI_HANDLE                     *ChildHandleBuffer
+  )
+{
+  EFI_STATUS                                Status;
+  BOOLEAN                                   AllChildrenStopped;
+  UINTN                                     Index;
+  UNDI32_DEV                                *UNDI32Device;
+  EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *NIIProtocol;
+
+  //
+  // Complete all outstanding transactions to Controller.
+  // Don't allow any new transaction to Controller to be started.
+  //
+  if (NumberOfChildren == 0) {
+
+    //
+    // Close the bus driver
+    //
+    Status = gBS->CloseProtocol (
+                    Controller,
+                    &gEfiDevicePathProtocolGuid,
+                    This->DriverBindingHandle,
+                    Controller
+                    );
+
+    Status = gBS->CloseProtocol (
+                    Controller,
+                    &gEfiPciIoProtocolGuid,
+                    This->DriverBindingHandle,
+                    Controller
+                    );
+
+    return Status;
+  }
+
+  AllChildrenStopped = TRUE;
+
+  for (Index = 0; Index < NumberOfChildren; Index++) {
+
+    Status = gBS->OpenProtocol (
+                    ChildHandleBuffer[Index],
+                    &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
+                    (VOID **) &NIIProtocol,
+                    This->DriverBindingHandle,
+                    Controller,
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                    );
+    if (!EFI_ERROR (Status)) {
+
+      UNDI32Device = UNDI_DEV_FROM_THIS (NIIProtocol);
+
+      Status = gBS->CloseProtocol (
+                      Controller,
+                      &gEfiPciIoProtocolGuid,
+                      This->DriverBindingHandle,
+                      ChildHandleBuffer[Index]
+                      );
+      if (!EFI_ERROR (Status)) {
+        Status = gBS->UninstallMultipleProtocolInterfaces (
+                        ChildHandleBuffer[Index],
+                        &gEfiDevicePathProtocolGuid,
+                        UNDI32Device->Undi32DevPath,
+                        &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
+                        &UNDI32Device->NIIProtocol_31,
+                        NULL
+                        );
+        if (!EFI_ERROR (Status)) {
+          //
+          // Restore original PCI attributes
+          //
+          Status = UNDI32Device->NicInfo.Io_Function->Attributes (
+                                                        UNDI32Device->NicInfo.Io_Function,
+                                                        EfiPciIoAttributeOperationSet,
+                                                        UNDI32Device->NicInfo.OriginalPciAttributes,
+                                                        NULL
+                                                        );
+
+          ASSERT_EFI_ERROR (Status);
+
+          gBS->FreePool (UNDI32Device->Undi32DevPath);
+          gBS->FreePool (UNDI32Device);
+
+        }
+      }
+    }
+
+    if (EFI_ERROR (Status)) {
+      AllChildrenStopped = FALSE;
+    }
+  }
+
+  if (!AllChildrenStopped) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+
+}
+
+
+/**
+  Use the EFI boot services to produce a pause. This is also the routine which
+  gets replaced during RunTime by the O/S in the NIC_DATA_INSTANCE so it can
+  do it's own pause.
+
+  @param  UnqId                Runtime O/S routine might use this, this temp
+                               routine does not use it
+  @param  MicroSeconds         Determines the length of pause.
+
+  @return none
+
+**/
+VOID
+TmpDelay (
+  IN UINT64 UnqId,
+  IN UINTN  MicroSeconds
+  )
+{
+  gBS->Stall ((UINT32) MicroSeconds);
+}
+
+
+/**
+  Use the PCI IO abstraction to issue memory or I/O reads and writes.  This is also the routine which
+  gets replaced during RunTime by the O/S in the NIC_DATA_INSTANCE so it can do it's own I/O abstractions.
+
+  @param  UnqId                Runtime O/S routine may use this field, this temp
+                               routine does not.
+  @param  ReadWrite            Determine if it is an I/O or Memory Read/Write
+                               Operation.
+  @param  Len                  Determines the width of the data operation.
+  @param  Port                 What port to Read/Write from.
+  @param  BuffAddr             Address to read to or write from.
+
+  @return none
+
+**/
+VOID
+TmpMemIo (
+  IN UINT64 UnqId,
+  IN UINT8  ReadWrite,
+  IN UINT8  Len,
+  IN UINT64 Port,
+  IN UINT64 BuffAddr
+  )
+{
+  EFI_PCI_IO_PROTOCOL_WIDTH Width;
+  NIC_DATA_INSTANCE         *AdapterInfo;
+
+  Width       = (EFI_PCI_IO_PROTOCOL_WIDTH) 0;
+  AdapterInfo = (NIC_DATA_INSTANCE *) (UINTN) UnqId;
+  switch (Len) {
+  case 2:
+    Width = (EFI_PCI_IO_PROTOCOL_WIDTH) 1;
+    break;
+
+  case 4:
+    Width = (EFI_PCI_IO_PROTOCOL_WIDTH) 2;
+    break;
+
+  case 8:
+    Width = (EFI_PCI_IO_PROTOCOL_WIDTH) 3;
+    break;
+  }
+
+  switch (ReadWrite) {
+  case PXE_IO_READ:
+    AdapterInfo->Io_Function->Io.Read (
+                                  AdapterInfo->Io_Function,
+                                  Width,
+                                  1,
+                                  Port,
+                                  1,
+                                  (VOID *) (UINTN) (BuffAddr)
+                                  );
+    break;
+
+  case PXE_IO_WRITE:
+    AdapterInfo->Io_Function->Io.Write (
+                                  AdapterInfo->Io_Function,
+                                  Width,
+                                  1,
+                                  Port,
+                                  1,
+                                  (VOID *) (UINTN) (BuffAddr)
+                                  );
+    break;
+
+  case PXE_MEM_READ:
+    AdapterInfo->Io_Function->Mem.Read (
+                                    AdapterInfo->Io_Function,
+                                    Width,
+                                    0,
+                                    Port,
+                                    1,
+                                    (VOID *) (UINTN) (BuffAddr)
+                                    );
+    break;
+
+  case PXE_MEM_WRITE:
+    AdapterInfo->Io_Function->Mem.Write (
+                                    AdapterInfo->Io_Function,
+                                    Width,
+                                    0,
+                                    Port,
+                                    1,
+                                    (VOID *) (UINTN) (BuffAddr)
+                                    );
+    break;
+  }
+
+  return ;
+}
+
+
+/**
+  Using the NIC data structure information, read the EEPROM to get the MAC address and then allocate space
+  for a new devicepath (**DevPtr) which will contain the original device path the NIC was found on (*BaseDevPtr)
+  and an added MAC node.
+
+  @param  DevPtr               Pointer which will point to the newly created device
+                               path with the MAC node attached.
+  @param  BaseDevPtr           Pointer to the device path which the UNDI device
+                               driver is latching on to.
+  @param  AdapterInfo          Pointer to the NIC data structure information which
+                               the UNDI driver is layering on..
+
+  @retval EFI_SUCCESS          A MAC address was successfully appended to the Base
+                               Device Path.
+  @retval other                Not enough resources available to create new Device
+                               Path node.
+
+**/
+EFI_STATUS
+AppendMac2DevPath (
+  IN OUT  EFI_DEVICE_PATH_PROTOCOL **DevPtr,
+  IN      EFI_DEVICE_PATH_PROTOCOL *BaseDevPtr,
+  IN      NIC_DATA_INSTANCE        *AdapterInfo
+  )
+{
+  EFI_MAC_ADDRESS           MACAddress;
+  PCI_CONFIG_HEADER         *CfgHdr;
+  INT32                     Val;
+  INT32                     Index;
+  INT32                     Index2;
+  UINT8                     AddrLen;
+  MAC_ADDR_DEVICE_PATH      MacAddrNode;
+  EFI_DEVICE_PATH_PROTOCOL  *EndNode;
+  UINT8                     *DevicePtr;
+  UINT16                    TotalPathLen;
+  UINT16                    BasePathLen;
+  EFI_STATUS                Status;
+
+  //
+  // set the environment ready (similar to UNDI_Start call) so that we can
+  // execute the other UNDI_ calls to get the mac address
+  // we are using undi 3.1 style
+  //
+  AdapterInfo->Delay      = TmpDelay;
+  AdapterInfo->Virt2Phys  = (VOID *) 0;
+  AdapterInfo->Block      = (VOID *) 0;
+  AdapterInfo->Map_Mem    = (VOID *) 0;
+  AdapterInfo->UnMap_Mem  = (VOID *) 0;
+  AdapterInfo->Sync_Mem   = (VOID *) 0;
+  AdapterInfo->Mem_Io     = TmpMemIo;
+  //
+  // these tmp call-backs follow 3.1 undi style
+  // i.e. they have the unique_id parameter.
+  //
+  AdapterInfo->VersionFlag  = 0x31;
+  AdapterInfo->Unique_ID    = (UINT64) (UINTN) AdapterInfo;
+
+  //
+  // undi init portion
+  //
+  CfgHdr              = (PCI_CONFIG_HEADER *) &(AdapterInfo->Config[0]);
+  AdapterInfo->ioaddr = 0;
+  AdapterInfo->RevID  = CfgHdr->RevID;
+
+  AddrLen             = E100bGetEepromAddrLen (AdapterInfo);
+
+  for (Index = 0, Index2 = 0; Index < 3; Index++) {
+    Val                       = E100bReadEeprom (AdapterInfo, Index, AddrLen);
+    MACAddress.Addr[Index2++] = (UINT8) Val;
+    MACAddress.Addr[Index2++] = (UINT8) (Val >> 8);
+  }
+
+  SetMem (MACAddress.Addr + Index2, sizeof (EFI_MAC_ADDRESS) - Index2, 0);
+  //for (; Index2 < sizeof (EFI_MAC_ADDRESS); Index2++) {
+  //  MACAddress.Addr[Index2] = 0;
+  //}
+  //
+  // stop undi
+  //
+  AdapterInfo->Delay  = (VOID *) 0;
+  AdapterInfo->Mem_Io = (VOID *) 0;
+
+  //
+  // fill the mac address node first
+  //
+  ZeroMem ((CHAR8 *) &MacAddrNode, sizeof MacAddrNode);
+  CopyMem (
+    (CHAR8 *) &MacAddrNode.MacAddress,
+    (CHAR8 *) &MACAddress,
+    sizeof (EFI_MAC_ADDRESS)
+    );
+
+  MacAddrNode.Header.Type       = MESSAGING_DEVICE_PATH;
+  MacAddrNode.Header.SubType    = MSG_MAC_ADDR_DP;
+  MacAddrNode.Header.Length[0]  = (UINT8) sizeof (MacAddrNode);
+  MacAddrNode.Header.Length[1]  = 0;
+
+  //
+  // find the size of the base dev path.
+  //
+  EndNode = BaseDevPtr;
+
+  while (!IsDevicePathEnd (EndNode)) {
+    EndNode = NextDevicePathNode (EndNode);
+  }
+
+  BasePathLen = (UINT16) ((UINTN) (EndNode) - (UINTN) (BaseDevPtr));
+
+  //
+  // create space for full dev path
+  //
+  TotalPathLen = (UINT16) (BasePathLen + sizeof (MacAddrNode) + sizeof (EFI_DEVICE_PATH_PROTOCOL));
+
+  Status = gBS->AllocatePool (
+                  EfiRuntimeServicesData,
+                  TotalPathLen,
+                  (VOID **) &DevicePtr
+                  );
+
+  if (Status != EFI_SUCCESS) {
+    return Status;
+  }
+  //
+  // copy the base path, mac addr and end_dev_path nodes
+  //
+  *DevPtr = (EFI_DEVICE_PATH_PROTOCOL *) DevicePtr;
+  CopyMem (DevicePtr, (CHAR8 *) BaseDevPtr, BasePathLen);
+  DevicePtr += BasePathLen;
+  CopyMem (DevicePtr, (CHAR8 *) &MacAddrNode, sizeof (MacAddrNode));
+  DevicePtr += sizeof (MacAddrNode);
+  CopyMem (DevicePtr, (CHAR8 *) EndNode, sizeof (EFI_DEVICE_PATH_PROTOCOL));
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Install a GUID/Pointer pair into the system's configuration table.
+
+  none
+
+  @retval EFI_SUCCESS          Install a GUID/Pointer pair into the system's
+                               configuration table.
+  @retval other                Did not successfully install the GUID/Pointer pair
+                               into the configuration table.
+
+**/
+// TODO:    VOID - add argument and description to function comment
+EFI_STATUS
+InstallConfigTable (
+  IN VOID
+  )
+{
+  EFI_STATUS              Status;
+  EFI_CONFIGURATION_TABLE *CfgPtr;
+  UNDI_CONFIG_TABLE       *TmpData;
+  UINT16                  Index;
+  UNDI_CONFIG_TABLE       *UndiData;
+
+  if (pxe_31 == NULL) {
+    return EFI_SUCCESS;
+  }
+
+  if(UndiDataPointer == NULL) {
+    return EFI_SUCCESS;
+  }
+
+  UndiData = (UNDI_CONFIG_TABLE *)UndiDataPointer;
+
+  UndiData->NumberOfInterfaces  = (pxe_31->IFcnt | pxe_31->IFcntExt << 8);
+  UndiData->nextlink            = NULL;
+
+  for (Index = 0; Index < (pxe_31->IFcnt | pxe_31->IFcntExt << 8); Index++) {
+    UndiData->NII_entry[Index].NII_InterfacePointer = &UNDI32DeviceList[Index]->NIIProtocol_31;
+    UndiData->NII_entry[Index].DevicePathPointer    = UNDI32DeviceList[Index]->Undi32DevPath;
+  }
+
+  //
+  // see if there is an entry in the config table already
+  //
+  CfgPtr = gST->ConfigurationTable;
+
+  for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
+    Status = CompareGuid (
+              &CfgPtr->VendorGuid,
+              &gEfiNetworkInterfaceIdentifierProtocolGuid_31
+              );
+    if (Status != EFI_SUCCESS) {
+      break;
+    }
+
+    CfgPtr++;
+  }
+
+  if (Index < gST->NumberOfTableEntries) {
+    TmpData = (UNDI_CONFIG_TABLE *) CfgPtr->VendorTable;
+
+    //
+    // go to the last link
+    //
+    while (TmpData->nextlink != NULL) {
+      TmpData = TmpData->nextlink;
+    }
+
+    TmpData->nextlink = UndiData;
+
+    //
+    // 1st one in chain
+    //
+    UndiData = (UNDI_CONFIG_TABLE *) CfgPtr->VendorTable;
+  }
+
+  //
+  // create an entry in the configuration table for our GUID
+  //
+  Status = gBS->InstallConfigurationTable (
+                  &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
+                  UndiData
+                  );
+  return Status;
+}
+
+/**
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeUndi(
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+  EFI_EVENT     Event;
+  EFI_STATUS    Status;
+
+  Status = EfiLibInstallDriverBindingComponentName2 (
+             ImageHandle,
+             SystemTable,
+             &gUndiDriverBinding,
+             ImageHandle,
+             &gUndiComponentName,
+             &gUndiComponentName2
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  UndiNotifyReadyToBoot,
+                  NULL,
+                  &gEfiEventReadyToBootGuid,
+                  &Event
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  UndiNotifyVirtual,
+                  NULL,
+                  &gEfiEventVirtualAddressChangeGuid,
+                  &Event
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h b/Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h
new file mode 100644
index 0000000000..31c55a8e11
--- /dev/null
+++ b/Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h
@@ -0,0 +1,439 @@
+/** @file
+  EFI internal structures for the EFI UNDI driver.
+
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _UNDI_32_H_
+#define _UNDI_32_H_
+
+#include <Uefi.h>
+
+#include <Guid/EventGroup.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/NetworkInterfaceIdentifier.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/AdapterInformation.h>
+
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <IndustryStandard/Pci.h>
+
+
+#include "E100b.h"
+
+extern EFI_DRIVER_BINDING_PROTOCOL  gUndiDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL  gUndiComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL gUndiComponentName2;
+
+#define MAX_NIC_INTERFACES 16
+
+#define EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION_31 0x00010001
+#define PXE_ROMID_MINORVER_31 0x10
+#define PXE_STATFLAGS_DB_WRITE_TRUNCATED  0x2000
+
+//
+// UNDI_CALL_TABLE.state can have the following values
+//
+#define DONT_CHECK -1
+#define ANY_STATE -1
+#define MUST_BE_STARTED 1
+#define MUST_BE_INITIALIZED 2
+
+#define UNDI_DEV_SIGNATURE   SIGNATURE_32('u','n','d','i')
+#define UNDI_DEV_FROM_THIS(a) CR(a, UNDI32_DEV, NIIProtocol_31, UNDI_DEV_SIGNATURE)
+#define UNDI_DEV_FROM_NIC(a) CR(a, UNDI32_DEV, NicInfo, UNDI_DEV_SIGNATURE)
+#define UNDI_DEV_FROM_AIP(a) CR(a, UNDI32_DEV, Aip, UNDI_DEV_SIGNATURE)
+
+typedef struct {
+  UINTN                                     Signature;
+  EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL NIIProtocol_31;
+  EFI_ADAPTER_INFORMATION_PROTOCOL          Aip;
+  EFI_HANDLE                                DeviceHandle;
+  EFI_DEVICE_PATH_PROTOCOL                  *Undi32BaseDevPath;
+  EFI_DEVICE_PATH_PROTOCOL                  *Undi32DevPath;
+  NIC_DATA_INSTANCE                         NicInfo;
+} UNDI32_DEV;
+
+typedef struct {
+  UINT16 cpbsize;
+  UINT16 dbsize;
+  UINT16 opflags;
+  UINT16 state;
+  VOID (*api_ptr)();
+} UNDI_CALL_TABLE;
+
+typedef VOID (*ptr)(VOID);
+typedef VOID (*bsptr_30)(UINTN);
+typedef VOID (*virtphys_30)(UINT64, UINT64);
+typedef VOID (*block_30)(UINT32);
+typedef VOID (*mem_io_30)(UINT8, UINT8, UINT64, UINT64);
+
+typedef VOID (*bsptr)(UINT64, UINTN);
+typedef VOID (*virtphys)(UINT64, UINT64, UINT64);
+typedef VOID (*block)(UINT64, UINT32);
+typedef VOID (*mem_io)(UINT64, UINT8, UINT8, UINT64, UINT64);
+
+typedef VOID (*map_mem)(UINT64, UINT64, UINT32, UINT32, UINT64);
+typedef VOID (*unmap_mem)(UINT64, UINT64, UINT32, UINT32, UINT64);
+typedef VOID (*sync_mem)(UINT64, UINT64, UINT32, UINT32, UINT64);
+
+extern UNDI_CALL_TABLE  api_table[];
+extern PXE_SW_UNDI      *pxe_31;  // !pxe structure for 3.1 drivers
+extern UNDI32_DEV       *UNDI32DeviceList[MAX_NIC_INTERFACES];
+
+//
+// functions defined in e100b.c
+//
+UINT8 InByte (NIC_DATA_INSTANCE *AdapterInfo, UINT32 Port);
+UINT16 InWord (NIC_DATA_INSTANCE *AdapterInfo, UINT32 Port);
+UINT32 InLong (NIC_DATA_INSTANCE *AdapterInfo, UINT32 Port);
+VOID  OutByte (NIC_DATA_INSTANCE *AdapterInfo, UINT8 Data, UINT32 Port);
+VOID  OutWord (NIC_DATA_INSTANCE *AdapterInfo, UINT16 Data, UINT32 Port);
+VOID  OutLong (NIC_DATA_INSTANCE *AdapterInfo, UINT32 Data, UINT32 Port);
+
+UINTN E100bInit (NIC_DATA_INSTANCE *AdapterInfo);
+UINTN E100bReset (NIC_DATA_INSTANCE *AdapterInfo, INT32 OpFlags);
+UINTN E100bShutdown (NIC_DATA_INSTANCE *AdapterInfo);
+UINTN E100bTransmit (NIC_DATA_INSTANCE *AdapterInfo, UINT64 cpb, UINT16 opflags);
+UINTN E100bReceive (NIC_DATA_INSTANCE *AdapterInfo, UINT64 cpb, UINT64 db);
+UINTN E100bSetfilter (NIC_DATA_INSTANCE *AdapterInfo, UINT16 New_filter,
+                      UINT64 cpb, UINT32 cpbsize);
+UINTN E100bStatistics(NIC_DATA_INSTANCE *AdapterInfo, UINT64 db, UINT16 dbsize);
+UINT8 E100bSetupIAAddr (NIC_DATA_INSTANCE *AdapterInfo);
+UINT8 E100bSetInterruptState (NIC_DATA_INSTANCE *AdapterInfo);
+
+UINT8 E100bGetEepromAddrLen (NIC_DATA_INSTANCE *AdapterInfo);
+UINT16 E100bReadEeprom (NIC_DATA_INSTANCE *AdapterInfo, INT32 Location, UINT8 address_len);
+INT16 E100bReadEepromAndStationAddress (NIC_DATA_INSTANCE *AdapterInfo);
+
+UINT16 next(UINT16);
+UINT8 SetupCBlink (NIC_DATA_INSTANCE *AdapterInfo);
+VOID SetFreeCB (NIC_DATA_INSTANCE *AdapterInfo,TxCB *);
+TxCB *GetFreeCB (NIC_DATA_INSTANCE *AdapterInfo);
+UINT16 CheckCBList (NIC_DATA_INSTANCE *AdapterInfo);
+
+UINT8 SelectiveReset (NIC_DATA_INSTANCE *AdapterInfo);
+UINT16 InitializeChip (NIC_DATA_INSTANCE *AdapterInfo);
+UINT8 SetupReceiveQueues (NIC_DATA_INSTANCE *AdapterInfo);
+VOID  Recycle_RFD (NIC_DATA_INSTANCE *AdapterInfo, UINT16);
+VOID XmitWaitForCompletion (NIC_DATA_INSTANCE *AdapterInfo);
+INT8 CommandWaitForCompletion (TxCB *cmd_ptr, NIC_DATA_INSTANCE *AdapterInfo);
+
+BOOLEAN PhyDetect (NIC_DATA_INSTANCE *AdapterInfo);
+VOID PhyReset (NIC_DATA_INSTANCE *AdapterInfo);
+VOID
+MdiWrite (
+  IN NIC_DATA_INSTANCE *AdapterInfo,
+  IN UINT8 RegAddress,
+  IN UINT8 PhyAddress,
+  IN UINT16 DataValue
+  );
+
+VOID
+MdiRead(
+  IN NIC_DATA_INSTANCE *AdapterInfo,
+  IN UINT8 RegAddress,
+  IN UINT8 PhyAddress,
+  IN OUT UINT16 *DataValue
+  );
+
+BOOLEAN SetupPhy (NIC_DATA_INSTANCE *AdapterInfo);
+VOID FindPhySpeedAndDpx (NIC_DATA_INSTANCE *AdapterInfo, UINT32 PhyId);
+
+
+
+//
+// functions defined in init.c
+//
+EFI_STATUS
+InstallConfigTable (
+  IN VOID
+  );
+
+EFI_STATUS
+EFIAPI
+InitializeUNDIDriver (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  );
+
+VOID
+UNDI_notify_virtual (
+  EFI_EVENT event,
+  VOID      *context
+  );
+
+EFI_STATUS
+EFIAPI
+UndiDriverSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  );
+
+EFI_STATUS
+EFIAPI
+UndiDriverStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  );
+
+EFI_STATUS
+EFIAPI
+UndiDriverStop (
+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN  EFI_HANDLE                     Controller,
+  IN  UINTN                          NumberOfChildren,
+  IN  EFI_HANDLE                     *ChildHandleBuffer
+  );
+
+EFI_STATUS
+AppendMac2DevPath (
+  IN OUT  EFI_DEVICE_PATH_PROTOCOL **DevPtr,
+  IN      EFI_DEVICE_PATH_PROTOCOL *BaseDevPtr,
+  IN      NIC_DATA_INSTANCE        *AdapterInfo
+  );
+
+VOID
+TmpDelay (
+  IN UINT64 UnqId,
+  IN UINTN MicroSeconds
+  );
+
+VOID
+TmpMemIo (
+  IN UINT64 UnqId,
+  IN UINT8 ReadWrite,
+  IN UINT8 Len,
+  IN UINT64 Port,
+  IN UINT64 BufAddr
+  );
+
+//
+// functions defined in decode.c
+//
+VOID
+UNDI_GetState (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  );
+
+VOID
+UNDI_Start (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  );
+
+VOID
+UNDI_Stop (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  );
+
+VOID
+UNDI_GetInitInfo (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  );
+
+VOID
+UNDI_GetConfigInfo (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  );
+
+VOID
+UNDI_Initialize (
+  IN  PXE_CDB       *CdbPtr,
+  NIC_DATA_INSTANCE *AdapterInfo
+  );
+
+VOID
+UNDI_Reset (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  );
+
+VOID
+UNDI_Shutdown (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  );
+
+VOID
+UNDI_Interrupt (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  );
+
+VOID
+UNDI_RecFilter (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  );
+
+VOID
+UNDI_StnAddr (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  );
+
+VOID
+UNDI_Statistics (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  );
+
+VOID
+UNDI_ip2mac (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  );
+
+VOID
+UNDI_NVData (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  );
+
+VOID
+UNDI_Status (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  );
+
+VOID
+UNDI_FillHeader (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  );
+
+VOID
+UNDI_Transmit (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  );
+
+VOID
+UNDI_Receive (
+  IN  PXE_CDB           *CdbPtr,
+  IN  NIC_DATA_INSTANCE *AdapterInfo
+  );
+
+VOID EFIAPI UNDI_APIEntry_new(UINT64);
+VOID UNDI_APIEntry_Common(UINT64);
+
+PXE_IPV4 convert_mcip(PXE_MAC_ADDR *);
+INT32 validate_mcip (PXE_MAC_ADDR *MCastAddr);
+
+VOID PxeStructInit (PXE_SW_UNDI *PxePtr);
+VOID PxeUpdate (NIC_DATA_INSTANCE *NicPtr, PXE_SW_UNDI *PxePtr);
+
+//
+// functions defined in UndiAipImpl.c
+//
+
+/**
+  Returns the current state information for the adapter.
+
+  This function returns information of type InformationType from the adapter.
+  If an adapter does not support the requested informational type, then
+  EFI_UNSUPPORTED is returned. 
+
+  @param[in]  This                   A pointer to the EFI_ADAPTER_INFORMATION_PROTOCOL instance.
+  @param[in]  InformationType        A pointer to an EFI_GUID that defines the contents of InformationBlock.
+  @param[out] InforamtionBlock       The service returns a pointer to the buffer with the InformationBlock
+                                     structure which contains details about the data specific to InformationType.
+  @param[out] InforamtionBlockSize   The driver returns the size of the InformationBlock in bytes.
+
+  @retval EFI_SUCCESS                The InformationType information was retrieved.
+  @retval EFI_UNSUPPORTED            The InformationType is not known.
+  @retval EFI_DEVICE_ERROR           The device reported an error.
+  @retval EFI_OUT_OF_RESOURCES       The request could not be completed due to a lack of resources.
+  @retval EFI_INVALID_PARAMETER      This is NULL. 
+  @retval EFI_INVALID_PARAMETER      InformationBlock is NULL. 
+  @retval EFI_INVALID_PARAMETER      InformationBlockSize is NULL.
+
+**/  
+EFI_STATUS
+EFIAPI
+UndiAipGetInfo (
+  IN   EFI_ADAPTER_INFORMATION_PROTOCOL *This,
+  IN   EFI_GUID                         *InformationType,
+  OUT  VOID                             **InformationBlock,
+  OUT  UINTN                            *InformationBlockSize
+  );
+
+/**
+  Sets state information for an adapter.
+
+  This function sends information of type InformationType for an adapter.
+  If an adapter does not support the requested information type, then EFI_UNSUPPORTED
+  is returned.
+
+  @param[in]  This                   A pointer to the EFI_ADAPTER_INFORMATION_PROTOCOL instance.
+  @param[in]  InformationType        A pointer to an EFI_GUID that defines the contents of InformationBlock.
+  @param[in]  InforamtionBlock       A pointer to the InformationBlock structure which contains details
+                                     about the data specific to InformationType.
+  @param[in]  InforamtionBlockSize   The size of the InformationBlock in bytes.
+
+  @retval EFI_SUCCESS                The information was received and interpreted successfully.
+  @retval EFI_UNSUPPORTED            The InformationType is not known.
+  @retval EFI_DEVICE_ERROR           The device reported an error.
+  @retval EFI_INVALID_PARAMETER      This is NULL.
+  @retval EFI_INVALID_PARAMETER      InformationBlock is NULL.
+  @retval EFI_WRITE_PROTECTED        The InformationType cannot be modified using EFI_ADAPTER_INFO_SET_INFO().
+
+**/                        
+EFI_STATUS
+EFIAPI
+UndiAipSetInfo (
+  IN   EFI_ADAPTER_INFORMATION_PROTOCOL *This,
+  IN   EFI_GUID                         *InformationType,
+  IN   VOID                             *InformationBlock,
+  IN   UINTN                            InformationBlockSize
+  );
+
+/**
+  Get a list of supported information types for this instance of the protocol.
+
+  This function returns a list of InformationType GUIDs that are supported on an
+  adapter with this instance of EFI_ADAPTER_INFORMATION_PROTOCOL. The list is returned
+  in InfoTypesBuffer, and the number of GUID pointers in InfoTypesBuffer is returned in
+  InfoTypesBufferCount.
+
+  @param[in]  This                  A pointer to the EFI_ADAPTER_INFORMATION_PROTOCOL instance.
+  @param[out] InfoTypesBuffer       A pointer to the list of InformationType GUID pointers that are supported
+                                    by This.
+  @param[out] InfoTypesBufferCount  A pointer to the number of GUID pointers present in InfoTypesBuffer.
+
+  @retval EFI_SUCCESS               The list of information type GUIDs that are supported on this adapter was
+                                    returned in InfoTypesBuffer. The number of information type GUIDs was
+                                    returned in InfoTypesBufferCount.
+  @retval EFI_INVALID_PARAMETER     This is NULL.
+  @retval EFI_INVALID_PARAMETER     InfoTypesBuffer is NULL.
+  @retval EFI_INVALID_PARAMETER     InfoTypesBufferCount is NULL.
+  @retval EFI_OUT_OF_RESOURCES      There is not enough pool memory to store the results.
+
+**/                        
+EFI_STATUS
+EFIAPI
+UndiAipGetSupportedTypes (
+  IN    EFI_ADAPTER_INFORMATION_PROTOCOL *This,
+  OUT   EFI_GUID                         **InfoTypesBuffer,
+  OUT   UINTN                            *InfoTypesBufferCount
+  );
+
+#endif
diff --git a/Drivers/OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c b/Drivers/OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c
new file mode 100644
index 0000000000..21151a076f
--- /dev/null
+++ b/Drivers/OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c
@@ -0,0 +1,145 @@
+/** @file
+
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+
+#include "Undi32.h"
+
+
+UINTN      mSupportedInfoTypesCount = 1;
+EFI_GUID   mSupportedInfoTypes[] = {
+  EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT_GUID
+};
+
+/**
+  Returns the current state information for the adapter.
+
+  This function returns information of type InformationType from the adapter.
+  If an adapter does not support the requested informational type, then
+  EFI_UNSUPPORTED is returned. 
+
+  @param[in]  This                   A pointer to the EFI_ADAPTER_INFORMATION_PROTOCOL instance.
+  @param[in]  InformationType        A pointer to an EFI_GUID that defines the contents of InformationBlock.
+  @param[out] InforamtionBlock       The service returns a pointer to the buffer with the InformationBlock
+                                     structure which contains details about the data specific to InformationType.
+  @param[out] InforamtionBlockSize   The driver returns the size of the InformationBlock in bytes.
+
+  @retval EFI_SUCCESS                The InformationType information was retrieved.
+  @retval EFI_UNSUPPORTED            The InformationType is not known.
+  @retval EFI_DEVICE_ERROR           The device reported an error.
+  @retval EFI_OUT_OF_RESOURCES       The request could not be completed due to a lack of resources.
+  @retval EFI_INVALID_PARAMETER      This is NULL. 
+  @retval EFI_INVALID_PARAMETER      InformationBlock is NULL. 
+  @retval EFI_INVALID_PARAMETER      InformationBlockSize is NULL.
+
+**/  
+EFI_STATUS
+EFIAPI
+UndiAipGetInfo (
+  IN   EFI_ADAPTER_INFORMATION_PROTOCOL *This,
+  IN   EFI_GUID                         *InformationType,
+  OUT  VOID                             **InformationBlock,
+  OUT  UINTN                            *InformationBlockSize
+  )
+{
+  UNDI32_DEV                            *UNDI32Device;
+  EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT    *UndiIpv6Support;
+
+  if (This == NULL || InformationBlock == NULL || InformationBlockSize == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!CompareGuid (InformationType, &gEfiAdapterInfoUndiIpv6SupportGuid)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  UNDI32Device = UNDI_DEV_FROM_AIP (This);
+  *InformationBlockSize = sizeof (EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT);
+  *InformationBlock = AllocateZeroPool (*InformationBlockSize);
+  if (*InformationBlock == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  UndiIpv6Support = (EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT *) (*InformationBlock);
+  UndiIpv6Support->Ipv6Support = UNDI32Device->NIIProtocol_31.Ipv6Supported;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Sets state information for an adapter.
+
+  This function sends information of type InformationType for an adapter.
+  If an adapter does not support the requested information type, then EFI_UNSUPPORTED
+  is returned.
+
+  @param[in]  This                   A pointer to the EFI_ADAPTER_INFORMATION_PROTOCOL instance.
+  @param[in]  InformationType        A pointer to an EFI_GUID that defines the contents of InformationBlock.
+  @param[in]  InforamtionBlock       A pointer to the InformationBlock structure which contains details
+                                     about the data specific to InformationType.
+  @param[in]  InforamtionBlockSize   The size of the InformationBlock in bytes.
+
+  @retval EFI_SUCCESS                The information was received and interpreted successfully.
+  @retval EFI_UNSUPPORTED            The InformationType is not known.
+  @retval EFI_DEVICE_ERROR           The device reported an error.
+  @retval EFI_INVALID_PARAMETER      This is NULL.
+  @retval EFI_INVALID_PARAMETER      InformationBlock is NULL.
+  @retval EFI_WRITE_PROTECTED        The InformationType cannot be modified using EFI_ADAPTER_INFO_SET_INFO().
+
+**/                        
+EFI_STATUS
+EFIAPI
+UndiAipSetInfo (
+  IN   EFI_ADAPTER_INFORMATION_PROTOCOL *This,
+  IN   EFI_GUID                         *InformationType,
+  IN   VOID                             *InformationBlock,
+  IN   UINTN                            InformationBlockSize
+  )
+{
+  return EFI_WRITE_PROTECTED;
+}
+
+/**
+  Get a list of supported information types for this instance of the protocol.
+
+  This function returns a list of InformationType GUIDs that are supported on an
+  adapter with this instance of EFI_ADAPTER_INFORMATION_PROTOCOL. The list is returned
+  in InfoTypesBuffer, and the number of GUID pointers in InfoTypesBuffer is returned in
+  InfoTypesBufferCount.
+
+  @param[in]  This                  A pointer to the EFI_ADAPTER_INFORMATION_PROTOCOL instance.
+  @param[out] InfoTypesBuffer       A pointer to the list of InformationType GUID pointers that are supported
+                                    by This.
+  @param[out] InfoTypesBufferCount  A pointer to the number of GUID pointers present in InfoTypesBuffer.
+
+  @retval EFI_SUCCESS               The list of information type GUIDs that are supported on this adapter was
+                                    returned in InfoTypesBuffer. The number of information type GUIDs was
+                                    returned in InfoTypesBufferCount.
+  @retval EFI_INVALID_PARAMETER     This is NULL.
+  @retval EFI_INVALID_PARAMETER     InfoTypesBuffer is NULL.
+  @retval EFI_INVALID_PARAMETER     InfoTypesBufferCount is NULL.
+  @retval EFI_OUT_OF_RESOURCES      There is not enough pool memory to store the results.
+
+**/                        
+EFI_STATUS
+EFIAPI
+UndiAipGetSupportedTypes (
+  IN    EFI_ADAPTER_INFORMATION_PROTOCOL *This,
+  OUT   EFI_GUID                         **InfoTypesBuffer,
+  OUT   UINTN                            *InfoTypesBufferCount
+  )
+{
+  if (This == NULL || InfoTypesBuffer == NULL || InfoTypesBufferCount == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *InfoTypesBufferCount = 1;
+  *InfoTypesBuffer = AllocateCopyPool (sizeof (EFI_GUID), &gEfiAdapterInfoUndiIpv6SupportGuid);
+  if (InfoTypesBuffer == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Drivers/OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf b/Drivers/OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf
new file mode 100644
index 0000000000..96666dc88a
--- /dev/null
+++ b/Drivers/OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf
@@ -0,0 +1,72 @@
+## @file
+# Component description file for Undi module.
+#
+# This module provides support for Universal Network Driver Interface. 
+# Notes: this module is no longer regular maintained/validated.
+#
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = UndiRuntimeDxe
+  FILE_GUID                      = A1f436EA-A127-4EF8-957C-8048606FF670
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = InitializeUndi
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  Undi32.h
+  E100b.h
+  E100b.c
+  Decode.c
+  Init.c
+  ComponentName.c
+  UndiAipImpl.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  UefiLib
+  UefiBootServicesTableLib
+  BaseMemoryLib
+  DebugLib
+  UefiRuntimeLib
+  UefiDriverEntryPoint
+  BaseLib
+  MemoryAllocationLib
+
+[Protocols]
+  gEfiNetworkInterfaceIdentifierProtocolGuid_31
+  gEfiPciIoProtocolGuid
+  gEfiDevicePathProtocolGuid
+  gEfiAdapterInformationProtocolGuid
+
+[Guids]
+  gEfiEventExitBootServicesGuid        ## PRODUCES ## Event
+  gEfiEventVirtualAddressChangeGuid    ## PRODUCES ## Event
+  gEfiAdapterInfoUndiIpv6SupportGuid   ## PRODUCES
+
+[Depex]
+  gEfiBdsArchProtocolGuid AND
+  gEfiCpuArchProtocolGuid AND
+  gEfiMetronomeArchProtocolGuid AND
+  gEfiMonotonicCounterArchProtocolGuid AND
+  gEfiRealTimeClockArchProtocolGuid AND
+  gEfiResetArchProtocolGuid AND
+  gEfiRuntimeArchProtocolGuid AND
+  gEfiSecurityArchProtocolGuid AND
+  gEfiTimerArchProtocolGuid AND
+  gEfiVariableWriteArchProtocolGuid AND
+  gEfiVariableArchProtocolGuid AND
+  gEfiWatchdogTimerArchProtocolGuid
-- 
2.21.0.windows.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [edk2-platforms: Patch 8/8] edk2-platforms: Update Maintainers.txt/Readme.md for imported packages
  2019-05-10  3:34 [edk2-platforms: Patch 0/8] Add packages from edk2 Michael D Kinney
                   ` (6 preceding siblings ...)
  2019-05-10  3:34 ` [edk2-platforms: Patch 7/8] Drivers/OptionRomPkg: Import OptionRomPkg " Michael D Kinney
@ 2019-05-10  3:34 ` Michael D Kinney
  2019-05-10 18:04   ` [edk2-devel] " Leif Lindholm
  2019-05-13  2:52   ` Sun, Zailiang
  2019-05-10  5:14 ` [edk2-devel] [edk2-platforms: Patch 0/8] Add packages from edk2 Liming Gao
                   ` (2 subsequent siblings)
  10 siblings, 2 replies; 23+ messages in thread
From: Michael D Kinney @ 2019-05-10  3:34 UTC (permalink / raw)
  To: devel
  Cc: Zailiang Sun, Yi Qian, Kelly Steele, Ray Ni, Michael Kubacki,
	Leif Lindholm, Ard Biesheuvel

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

Update Maintainers.txt for the following packages:
* Drivers/OptionRomPkg
* Platform/BeagleBoard/BeagleBoardPkg
* Platform/Intel/QuarkPlatformPkg
* Platform/Intel/Vlv2TbltDevicePkg
* Silicon/Intel/QuarkSocPkg
* Silicon/Intel/Vlv2DeviceRefCodePkg
* Silicon/TexasInsturments/Omap35xxPkg

Add the following platforms to Readme.md
* BeagleBoard
* MinnowBoard Max/Turbot
* Galileo

Cc: Zailiang Sun <zailiang.sun@intel.com>
Cc: Yi Qian <yi.qian@intel.com>
Cc: Kelly Steele <kelly.steele@intel.com>
Cc: Ray Ni <ray.ni@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>
---
 Maintainers.txt | 20 ++++++++++++++++++++
 Readme.md       |  9 +++++++++
 2 files changed, 29 insertions(+)

diff --git a/Maintainers.txt b/Maintainers.txt
index 6477591e68..7dd403a170 100644
--- a/Maintainers.txt
+++ b/Maintainers.txt
@@ -38,12 +38,32 @@ W: https://github.com/tianocore/tianocore.github.io/wiki/Security
 EDK II Packages:
 ----------------
 
+Drivers/OptionRomPkg
+W: https://github.com/tianocore/tianocore.github.io/wiki/OptionRomPkg
+M: Ray Ni <ray.ni@intel.com>
+
 Platform
 M: Ard Biesheuvel <ard.biesheuvel@linaro.org>
 M: Leif Lindholm <leif.lindholm@linaro.org>
 M: Michael D Kinney <michael.d.kinney@intel.com>
 
+Platform/Intel/QuarkPlatformPkg
+M: Michael D Kinney <michael.d.kinney@intel.com>
+M: Kelly Steele <kelly.steele@intel.com>
+
+Platform/Intel/Vlv2TbltDevicePkg
+M: Zailiang Sun <zailiang.sun@intel.com>
+M: Yi Qian <yi.qian@intel.com>
+
 Silicon
 M: Ard Biesheuvel <ard.biesheuvel@linaro.org>
 M: Leif Lindholm <leif.lindholm@linaro.org>
 M: Michael D Kinney <michael.d.kinney@intel.com>
+
+Silicon/Intel/QuarkSocPkg
+M: Michael D Kinney <michael.d.kinney@intel.com>
+M: Kelly Steele <kelly.steele@intel.com>
+
+Silicon/Intel/Vlv2DeviceRefCodePkg
+M: Zailiang Sun <zailiang.sun@intel.com>
+M: Yi Qian <yi.qian@intel.com>
diff --git a/Readme.md b/Readme.md
index 95c0c14522..aac9f69d46 100644
--- a/Readme.md
+++ b/Readme.md
@@ -208,6 +208,9 @@ they will be documented with the platform.
 
 ## [ARM](Platform/ARM/Readme.md)
 
+## BeagleBoard
+* [BeagleBoard](Platform\BeagleBoard\BeagleBoardPkg)
+
 ## Hisilicon
 * [D02](Platform/Hisilicon/D02)
 * [D03](Platform/Hisilicon/D03)
@@ -223,6 +226,12 @@ they will be documented with the platform.
 ## Socionext
 * [SynQuacer](Platform/Socionext/DeveloperBox)
 
+## Intel(R) Quark SoC X1000 based platforms
+* [Galileo](Platform/Intel/QuarkPlatformPkg)
+
+## Minnowboard Max/Turbot based on Intel Valleyview2 SoC
+* [Minnowboard Max](Platform/Intel/Vlv2TbltDevicePkg)
+
 # Maintainers
 
 See [Maintainers.txt](Maintainers.txt).
-- 
2.21.0.windows.1


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [edk2-devel] [edk2-platforms: Patch 0/8] Add packages from edk2
  2019-05-10  3:34 [edk2-platforms: Patch 0/8] Add packages from edk2 Michael D Kinney
                   ` (7 preceding siblings ...)
  2019-05-10  3:34 ` [edk2-platforms: Patch 8/8] edk2-platforms: Update Maintainers.txt/Readme.md for imported packages Michael D Kinney
@ 2019-05-10  5:14 ` Liming Gao
  2019-05-10  6:17   ` Michael D Kinney
  2019-05-11  2:12 ` Ni, Ray
  2019-05-13 21:03 ` Steele, Kelly
  10 siblings, 1 reply; 23+ messages in thread
From: Liming Gao @ 2019-05-10  5:14 UTC (permalink / raw)
  To: devel@edk2.groups.io, Kinney, Michael D
  Cc: Sun, Zailiang, Qian, Yi, Steele, Kelly, Ni, Ray,
	Kubacki, Michael A, Leif Lindholm, Ard Biesheuvel

Mike:
  I have two questions here. 
1. Those module in edk2 has BSD + Patent License. But, edk2 platform code uses BSD license. That means the codes in edk2 platform will have the mix license. What's the plan to update edk2 platform code license to BSD + Patent?
2. What's plan for this change? This change impacts edk2 project. Does it catch edk2 stable tag?

Thanks
Liming
>-----Original Message-----
>From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
>Michael D Kinney
>Sent: Friday, May 10, 2019 11:34 AM
>To: devel@edk2.groups.io
>Cc: Sun, Zailiang <zailiang.sun@intel.com>; Qian, Yi <yi.qian@intel.com>;
>Steele, Kelly <kelly.steele@intel.com>; Ni, Ray <ray.ni@intel.com>; Kubacki,
>Michael A <michael.a.kubacki@intel.com>; Leif Lindholm
><leif.lindholm@linaro.org>; Ard Biesheuvel <ard.biesheuvel@linaro.org>
>Subject: [edk2-devel] [edk2-platforms: Patch 0/8] Add packages from edk2
>
>https://bugzilla.tianocore.org/show_bug.cgi?id=1467
>https://bugzilla.tianocore.org/show_bug.cgi?id=1374
>https://bugzilla.tianocore.org/show_bug.cgi?id=1793
>
>Add the following platform, silicon, and driver packages from the edk2 repo
>to the edk2-platforms repo
>* Drivers/OptionRomPkg
>* Platform/BeagleBoard/BeagleBoardPkg
>* Platform/Intel/QuarkPlatformPkg
>* Platform/Intel/Vlv2TbltDevicePkg
>* Silicon/Intel/QuarkSocPkg
>* Silicon/Intel/Vlv2DeviceRefCodePkg
>* Silicon/TexasInsturments/Omap35xxPkg
>
>Cc: Zailiang Sun <zailiang.sun@intel.com>
>Cc: Yi Qian <yi.qian@intel.com>
>Cc: Kelly Steele <kelly.steele@intel.com>
>Cc: Ray Ni <ray.ni@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>
>
>Michael D Kinney (8):
>  Silicon/TexasInsturments: Import Omap35xxPkg from edk2
>  Platform/BeagleBoard: Import BeagleBoardPkg from edk2
>  Silicon/Intel: Import QuarkSocPkg from edk2
>  Platform/QuarkPlatformPkg: Import QuarkPlatformPkg from edk2
>  Platform/Vlv2DeviceRefCodePkg: Import Vlv2DeviceRefCodePkg from edk2
>  Platform/Vlv2TbltDevicePkg: Import Vlv2TbltDevicePkg from edk2
>  Drivers/OptionRomPkg: Import OptionRomPkg from edk2
>  edk2-platforms: Update Maintainers.txt/Readme.md for imported packages
>
> .../Application/BltLibSample/BltLibSample.c   |  279 +
> .../Application/BltLibSample/BltLibSample.inf |   30 +
> .../AtapiPassThruDxe/AtapiPassThru.c          | 3410 +++++++++++++
> .../AtapiPassThruDxe/AtapiPassThru.h          | 1618 ++++++
> .../AtapiPassThruDxe/AtapiPassThruDxe.inf     |   70 +
> .../AtapiPassThruDxe/ComponentName.c          |  169 +
> .../DriverSupportedEfiVersion.c               |   14 +
> .../FtdiUsbSerialDxe/CompatibleDevices.txt    |    5 +
> .../Bus/Usb/FtdiUsbSerialDxe/ComponentName.c  |  218 +
> .../FtdiUsbSerialDxe/FtdiUsbSerialDriver.c    | 2580 ++++++++++
> .../FtdiUsbSerialDxe/FtdiUsbSerialDriver.h    |  589 +++
> .../Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf |   55 +
> .../Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt       |   32 +
> .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.c   | 1318 +++++
> .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.h   |  969 ++++
> .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf |   61 +
> .../Usb/UsbNetworking/Ax88772/ComponentName.c |  178 +
> .../Usb/UsbNetworking/Ax88772/DriverBinding.c |  507 ++
> .../Usb/UsbNetworking/Ax88772/SimpleNetwork.c | 1503 ++++++
> .../Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c  |  875 ++++
> .../Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h  | 1026 ++++
> .../Usb/UsbNetworking/Ax88772b/Ax88772b.inf   |   61 +
> .../UsbNetworking/Ax88772b/ComponentName.c    |  175 +
> .../UsbNetworking/Ax88772b/DriverBinding.c    |  696 +++
> .../UsbNetworking/Ax88772b/SimpleNetwork.c    | 1657 ++++++
> .../CirrusLogic5430Dxe/CirrusLogic5430.c      |  917 ++++
> .../CirrusLogic5430Dxe/CirrusLogic5430.h      |  432 ++
> .../CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf |   84 +
> .../CirrusLogic5430GraphicsOutput.c           |  556 ++
> .../CirrusLogic5430Dxe/CirrusLogic5430I2c.c   |  427 ++
> .../CirrusLogic5430Dxe/CirrusLogic5430I2c.h   |   62 +
> .../CirrusLogic5430UgaDraw.c                  |  412 ++
> .../CirrusLogic5430Dxe/ComponentName.c        |  203 +
> .../DriverSupportedEfiVersion.c               |   14 +
> .../OptionRomPkg/CirrusLogic5430Dxe/Edid.c    |  525 ++
> Drivers/OptionRomPkg/Include/Library/BltLib.h |  253 +
> .../FrameBufferBltLib/FrameBufferBltLib.c     |  744 +++
> .../FrameBufferBltLib/FrameBufferBltLib.inf   |   29 +
> .../Library/GopBltLib/GopBltLib.c             |  449 ++
> .../Library/GopBltLib/GopBltLib.inf           |   31 +
> Drivers/OptionRomPkg/OptionRomPkg.dec         |   41 +
> Drivers/OptionRomPkg/OptionRomPkg.dsc         |  113 +
> Drivers/OptionRomPkg/ReadMe.txt               |   17 +
> .../UndiRuntimeDxe/ComponentName.c            |  359 ++
> Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c  | 1516 ++++++
> Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c   | 3541 +++++++++++++
> Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h   |  665 +++
> Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c    | 1051 ++++
> Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h  |  439 ++
> .../OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c |  145 +
> .../UndiRuntimeDxe/UndiRuntimeDxe.inf         |   72 +
> Maintainers.txt                               |   20 +
> .../BeagleBoardPkg/BeagleBoardPkg.dec         |   30 +
> .../BeagleBoardPkg/BeagleBoardPkg.dsc         |  496 ++
> .../BeagleBoardPkg/BeagleBoardPkg.fdf         |  308 ++
> .../BeagleBoardPkg/ConfigurationHeader.bin    |  Bin 0 -> 512 bytes
> .../BeagleBoardPkg/ConfigurationHeader.dat    |   41 +
> .../Debugger_scripts/rvi_boot_from_ram.inc    |   15 +
> .../Debugger_scripts/rvi_convert_symbols.sh   |   17 +
> .../Debugger_scripts/rvi_dummy.axf            |  Bin 0 -> 7984 bytes
> .../Debugger_scripts/rvi_hw_setup.inc         |   61 +
> .../Debugger_scripts/rvi_load_symbols.inc     |   17 +
> .../Debugger_scripts/rvi_symbols_macros.inc   |  188 +
> .../Debugger_scripts/rvi_unload_symbols.inc   |  112 +
> .../Debugger_scripts/trace32_load_symbols.cmm |  205 +
> .../trace32_load_symbols_cygwin.cmm           |  182 +
> .../BeagleBoardPkg/Include/BeagleBoard.h      |  173 +
> .../Library/BeagleBoardLib/BeagleBoard.c      |  115 +
> .../BeagleBoardLib/BeagleBoardHelper.S        |   41 +
> .../BeagleBoardLib/BeagleBoardHelper.asm      |   47 +
> .../Library/BeagleBoardLib/BeagleBoardLib.inf |   48 +
> .../Library/BeagleBoardLib/BeagleBoardMem.c   |   74 +
> .../Library/BeagleBoardLib/Clock.c            |   63 +
> .../Library/BeagleBoardLib/PadConfiguration.c |  316 ++
> .../Library/DxeHobPeCoffLib/DxeHobPeCoff.c    |  282 ++
> .../DxeHobPeCoffLib/DxeHobPeCoffLib.inf       |   39 +
> .../LzmaHobCustomDecompressLib.c              |   44 +
> .../LzmaHobCustomDecompressLib.inf            |   45 +
> .../MemoryInitPeiLib/MemoryInitPeiLib.c       |  192 +
> .../MemoryInitPeiLib/MemoryInitPeiLib.inf     |   58 +
> .../Library/ResetSystemLib/ResetSystemLib.c   |  149 +
> .../Library/ResetSystemLib/ResetSystemLib.inf |   37 +
> .../BeagleBoardPkg/PrePi/Arm/ArchPrePi.c      |   23 +
> .../PrePi/Arm/ModuleEntryPoint.S              |  124 +
> .../PrePi/Arm/ModuleEntryPoint.asm            |  142 +
> .../BeagleBoardPkg/PrePi/LzmaDecompress.h     |   97 +
> .../BeagleBoardPkg/PrePi/MainUniCore.c        |   33 +
> .../BeagleBoardPkg/PrePi/PeiUniCore.inf       |   97 +
> .../BeagleBoard/BeagleBoardPkg/PrePi/PrePi.c  |  179 +
> .../BeagleBoard/BeagleBoardPkg/PrePi/PrePi.h  |   90 +
> .../BeagleBoardPkg/Tools/GNUmakefile          |   14 +
> .../BeagleBoardPkg/Tools/generate_image.c     |  402 ++
> .../BeagleBoard/BeagleBoardPkg/Tools/makefile |   16 +
> .../BeagleBoardPkg/Tools/replace.c            |  140 +
> .../Acpi/AcpiTables/AcpiTables.inf            |   42 +
> .../Acpi/AcpiTables/Cpu0Cst/Cpu0Cst.asl       |  399 ++
> .../Acpi/AcpiTables/Cpu0Ist/Cpu0Ist.asl       |  159 +
> .../Acpi/AcpiTables/Cpu0Tst/Cpu0Tst.asl       |  133 +
> .../Acpi/AcpiTables/CpuPm/CpuPm.asl           |   73 +
> .../Acpi/AcpiTables/Dsdt/AD7298.asi           |   38 +
> .../Acpi/AcpiTables/Dsdt/ADC108S102.asi       |   33 +
> .../Acpi/AcpiTables/Dsdt/CAT24C08.asi         |   34 +
> .../Acpi/AcpiTables/Dsdt/CY8C9540A.asi        |   47 +
> .../Acpi/AcpiTables/Dsdt/GpioClient.asi       |   89 +
> .../Acpi/AcpiTables/Dsdt/LpcDev.asi           |  248 +
> .../Acpi/AcpiTables/Dsdt/PCA9685.asi          |   34 +
> .../Acpi/AcpiTables/Dsdt/PCAL9555A.asi        |   90 +
> .../Acpi/AcpiTables/Dsdt/PciHostBridge.asi    |  195 +
> .../Acpi/AcpiTables/Dsdt/PciIrq.asi           |  552 ++
> .../Acpi/AcpiTables/Dsdt/PcieExpansionPrt.asi |  127 +
> .../Acpi/AcpiTables/Dsdt/Platform.asl         |  347 ++
> .../Acpi/AcpiTables/Dsdt/QNC.asi              |   49 +
> .../Acpi/AcpiTables/Dsdt/QNCApic.asi          |   32 +
> .../Acpi/AcpiTables/Dsdt/QNCLpc.asi           |   23 +
> .../AcpiTables/Dsdt/QuarkSouthCluster.asi     |  110 +
> .../Acpi/AcpiTables/Dsdt/Tpm.asi              |   45 +
> .../Acpi/AcpiTables/Facs/Facs.aslc            |   74 +
> .../Acpi/AcpiTables/Facs/Facs.h               |   29 +
> .../Acpi/AcpiTables/Fadt/Fadt.h               |  102 +
> .../Acpi/AcpiTables/Fadt/Fadt1.0.aslc         |   76 +
> .../Acpi/AcpiTables/Fadt/Fadt2.0.aslc         |  157 +
> .../Acpi/AcpiTables/Hpet/Hpet.aslc            |   68 +
> .../Acpi/AcpiTables/Hpet/Hpet.h               |   45 +
> .../Acpi/AcpiTables/Mcfg/Mcfg.aslc            |   75 +
> .../Acpi/AcpiTables/Mcfg/Mcfg.h               |   56 +
> .../Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.c     | 1402 +++++
> .../Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.h     |  316 ++
> .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.c      |  805 +++
> .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.h      |  120 +
> .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.inf    |  196 +
> .../Acpi/Dxe/AcpiPlatform/Madt.h              |  207 +
> .../Acpi/Dxe/AcpiPlatform/MadtPlatform.c      |  300 ++
> .../BootScriptExecutorDxe.inf                 |   77 +
> .../Dxe/BootScriptExecutorDxe/IA32/S3Asm.S    |   44 +
> .../Dxe/BootScriptExecutorDxe/IA32/S3Asm.asm  |   51 +
> .../BootScriptExecutorDxe/IA32/SetIdtEntry.c  |   57 +
> .../Dxe/BootScriptExecutorDxe/ScriptExecute.c |  379 ++
> .../Dxe/BootScriptExecutorDxe/ScriptExecute.h |   70 +
> .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.c     | 1011 ++++
> .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.h     |  167 +
> .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.inf   |   78 +
> .../Acpi/DxeSmm/SmmPowerManagement/Ppm.c      |  372 ++
> .../Acpi/DxeSmm/SmmPowerManagement/Ppm.h      |  150 +
> .../SmmPowerManagement/SmmPowerManagement.c   |  113 +
> .../SmmPowerManagement/SmmPowerManagement.h   |   52 +
> .../SmmPowerManagement/SmmPowerManagement.inf |   74 +
> .../Application/ForceRecovery/ForceRecovery.c |   47 +
> .../ForceRecovery/ForceRecovery.inf           |   34 +
> .../PlatformFlashAccessLibDxe.c               |  262 +
> .../PlatformFlashAccessLibDxe.inf             |   47 +
> .../PlatformFlashAccessLib/SpiFlashDevice.c   |  330 ++
> .../PlatformFlashAccessLib/SpiFlashDevice.h   |  180 +
> .../SystemFirmwareDescriptor.aslc             |   83 +
> .../SystemFirmwareDescriptor.inf              |   40 +
> .../SystemFirmwareDescriptorPei.c             |   60 +
> .../SystemFirmwareUpdateConfig.ini            |   57 +
> .../Include/Guid/CapsuleOnDataCD.h            |   23 +
> .../Include/Guid/CapsuleOnFatFloppyDisk.h     |   23 +
> .../Include/Guid/CapsuleOnFatIdeDisk.h        |   24 +
> .../Include/Guid/CapsuleOnFatUsbDisk.h        |   24 +
> .../Include/Guid/MemoryConfigData.h           |   23 +
> .../Include/Guid/QuarkCapsuleGuid.h           |   46 +
> .../Include/Guid/QuarkVariableLock.h          |   23 +
> .../Include/Guid/SystemNvDataHobGuid.h        |   29 +
> .../Include/Library/PlatformHelperLib.h       |  266 +
> .../Include/Library/PlatformPcieHelperLib.h   |   56 +
> .../Intel/QuarkPlatformPkg/Include/Pcal9555.h |   24 +
> .../Intel/QuarkPlatformPkg/Include/Platform.h |  119 +
> .../QuarkPlatformPkg/Include/PlatformBoards.h |  166 +
> .../Include/Protocol/GlobalNvsArea.h          |   82 +
> .../Include/Protocol/PlatformSmmSpiReady.h    |   23 +
> .../PlatformBootManager.c                     |  472 ++
> .../PlatformBootManager.h                     |   49 +
> .../PlatformBootManagerLib.inf                |   83 +
> .../PlatformBootManagerLib/PlatformData.c     |  275 +
> .../Library/PlatformHelperLib/CommonHeader.h  |   51 +
> .../DxePlatformHelperLib.inf                  |   70 +
> .../PeiPlatformHelperLib.inf                  |   45 +
> .../PlatformHelperLib/PlatformHelperDxe.c     |  337 ++
> .../PlatformHelperLib/PlatformHelperLib.c     |  481 ++
> .../PlatformHelperLib/PlatformHelperPei.c     |  159 +
> .../Library/PlatformHelperLib/PlatformLeds.c  |  146 +
> .../PlatformPcieHelperLib/CommonHeader.h      |   55 +
> .../PlatformPcieHelperLib.c                   |  114 +
> .../PlatformPcieHelperLib.inf                 |   41 +
> .../Library/PlatformPcieHelperLib/SocUnit.c   |  125 +
> .../Library/PlatformSecLib/Ia32/Flat32.S      |  796 +++
> .../Library/PlatformSecLib/Ia32/Flat32.asm    |  685 +++
> .../Library/PlatformSecLib/Ia32/Platform.inc  |  134 +
> .../Library/PlatformSecLib/PlatformSecLib.c   |  207 +
> .../Library/PlatformSecLib/PlatformSecLib.inf |   54 +
> .../PlatformSecLib/PlatformSecLibModStrs.uni  |   18 +
> .../PlatformSecureLib/PlatformSecureLib.c     |  164 +
> .../PlatformSecureLib/PlatformSecureLib.inf   |   41 +
> .../Library/Tpm12DeviceLibAtmelI2c/TisPc.c    |  408 ++
> .../Tpm12DeviceLibAtmelI2c.inf                |   39 +
> .../Tpm12DeviceLibAtmelI2c.uni                |   16 +
> .../Library/Tpm12DeviceLibInfineonI2c/TisPc.c |  612 +++
> .../Tpm12DeviceLibInfineonI2c.inf             |   39 +
> .../Tpm12DeviceLibInfineonI2c.uni             |   16 +
> .../Pci/Dxe/PciHostBridge/PciHostBridge.c     | 1397 +++++
> .../Pci/Dxe/PciHostBridge/PciHostBridge.h     |  389 ++
> .../Pci/Dxe/PciHostBridge/PciHostBridge.inf   |   61 +
> .../Dxe/PciHostBridge/PciHostBridgeSupport.c  |  140 +
> .../Pci/Dxe/PciHostBridge/PciHostResource.h   |   60 +
> .../Pci/Dxe/PciHostBridge/PciRootBridge.h     |  693 +++
> .../Pci/Dxe/PciHostBridge/PciRootBridgeIo.c   | 1610 ++++++
> .../Pci/Dxe/PciPlatform/CommonHeader.h        |   31 +
> .../Pci/Dxe/PciPlatform/PciPlatform.c         |  194 +
> .../Pci/Dxe/PciPlatform/PciPlatform.h         |   82 +
> .../Pci/Dxe/PciPlatform/PciPlatform.inf       |   54 +
> .../Dxe/MemorySubClass/MemorySubClass.c       |  435 ++
> .../Dxe/MemorySubClass/MemorySubClass.h       |   65 +
> .../Dxe/MemorySubClass/MemorySubClass.inf     |   60 +
> .../MemorySubClass/MemorySubClassStrings.uni  |   29 +
> .../Dxe/PlatformInit/PlatformConfig.c         |  443 ++
> .../Dxe/PlatformInit/PlatformInitDxe.c        |   87 +
> .../Dxe/PlatformInit/PlatformInitDxe.h        |   58 +
> .../Dxe/PlatformInit/PlatformInitDxe.inf      |   56 +
> .../Dxe/SaveMemoryConfig/SaveMemoryConfig.c   |  118 +
> .../Dxe/SaveMemoryConfig/SaveMemoryConfig.inf |   44 +
> .../Platform/Dxe/Setup/CommonHeader.h         |   55 +
> .../Platform/Dxe/Setup/DxePlatform.inf        |   76 +
> .../Platform/Dxe/Setup/KeyboardLayout.c       |  262 +
> .../Platform/Dxe/Setup/QNCRegTable.c          |   80 +
> .../Platform/Dxe/Setup/SetupPlatform.c        |   97 +
> .../Platform/Dxe/Setup/SetupPlatform.h        |   71 +
> .../Platform/Dxe/Setup/Strings.uni            |   47 +
> .../Platform/Dxe/Setup/processor.c            |   40 +
> .../Platform/Dxe/SmbiosMiscDxe/CommonHeader.h |   34 +
> .../MiscBaseBoardManufacturer.uni             |   19 +
> .../MiscBaseBoardManufacturerData.c           |   45 +
> .../MiscBaseBoardManufacturerFunction.c       |  181 +
> .../Dxe/SmbiosMiscDxe/MiscBiosVendor.uni      |   18 +
> .../Dxe/SmbiosMiscDxe/MiscBiosVendorData.c    |   92 +
> .../SmbiosMiscDxe/MiscBiosVendorFunction.c    |  222 +
> .../SmbiosMiscDxe/MiscBootInformationData.c   |   24 +
> .../MiscBootInformationFunction.c             |   71 +
> .../SmbiosMiscDxe/MiscChassisManufacturer.uni |   17 +
> .../MiscChassisManufacturerData.c             |   36 +
> .../MiscChassisManufacturerFunction.c         |  168 +
> .../Dxe/SmbiosMiscDxe/MiscDevicePath.h        |   42 +
> .../MiscNumberOfInstallableLanguagesData.c    |   28 +
> ...MiscNumberOfInstallableLanguagesFunction.c |  240 +
> .../Dxe/SmbiosMiscDxe/MiscOemString.uni       |   12 +
> .../Dxe/SmbiosMiscDxe/MiscOemStringData.c     |   20 +
> .../Dxe/SmbiosMiscDxe/MiscOemStringFunction.c |   78 +
> .../Dxe/SmbiosMiscDxe/MiscOnboardDevice.uni   |   18 +
> .../Dxe/SmbiosMiscDxe/MiscOnboardDeviceData.c |   49 +
> .../SmbiosMiscDxe/MiscOnboardDeviceFunction.c |  105 +
> .../MiscPortInternalConnectorDesignator.uni   |   53 +
> .../MiscPortInternalConnectorDesignatorData.c |  184 +
> ...cPortInternalConnectorDesignatorFunction.c |  292 ++
> .../SmbiosMiscDxe/MiscSystemManufacturer.uni  |   20 +
> .../MiscSystemManufacturerData.c              |   32 +
> .../MiscSystemManufacturerFunction.c          |  198 +
> .../SmbiosMiscDxe/MiscSystemOptionString.uni  |   14 +
> .../MiscSystemOptionStringData.c              |   23 +
> .../MiscSystemOptionStringFunction.c          |   81 +
> .../MiscSystemSlotDesignation.uni             |   27 +
> .../MiscSystemSlotDesignationData.c           |  357 ++
> .../MiscSystemSlotDesignationFunction.c       |  285 ++
> .../MiscSystemSlotOnboardDevices.uni          |   23 +
> .../Platform/Dxe/SmbiosMiscDxe/SmbiosMisc.h   |  137 +
> .../Dxe/SmbiosMiscDxe/SmbiosMiscDataTable.c   |  109 +
> .../Dxe/SmbiosMiscDxe/SmbiosMiscDxe.inf       |  308 ++
> .../Dxe/SmbiosMiscDxe/SmbiosMiscEntryPoint.c  |   82 +
> .../Dxe/SmbiosMiscDxe/SmbiosMiscStrings.uni   |   26 +
> .../Pei/PlatformConfig/PlatformConfigPei.c    |   81 +
> .../Pei/PlatformConfig/PlatformConfigPei.inf  |   45 +
> .../Platform/Pei/PlatformInit/BootMode.c      |  218 +
> .../Platform/Pei/PlatformInit/CommonHeader.h  |   81 +
> .../Pei/PlatformInit/Generic/Recovery.c       |  467 ++
> .../Pei/PlatformInit/MemoryCallback.c         |  279 +
> .../Platform/Pei/PlatformInit/MrcWrapper.c    | 1565 ++++++
> .../Platform/Pei/PlatformInit/MrcWrapper.h    |  225 +
> .../Platform/Pei/PlatformInit/PeiFvSecurity.c |  111 +
> .../Platform/Pei/PlatformInit/PeiFvSecurity.h |   67 +
> .../Pei/PlatformInit/PlatformEarlyInit.c      | 1227 +++++
> .../Pei/PlatformInit/PlatformEarlyInit.h      |  301 ++
> .../Pei/PlatformInit/PlatformEarlyInit.inf    |  193 +
> .../Pei/PlatformInit/PlatformErratas.c        |  178 +
> .../Platform/SpiFvbServices/FvbInfo.c         |  332 ++
> .../Platform/SpiFvbServices/FwBlockService.c  | 2053 ++++++++
> .../Platform/SpiFvbServices/FwBlockService.h  |  308 ++
> .../Platform/SpiFvbServices/PlatformSmmSpi.c  |   31 +
> .../SpiFvbServices/PlatformSmmSpi.inf         |   80 +
> .../Platform/SpiFvbServices/PlatformSpi.inf   |   79 +
> .../Platform/SpiFvbServices/SpiFlashDevice.c  |  331 ++
> .../Platform/SpiFvbServices/SpiFlashDevice.h  |  181 +
> Platform/Intel/QuarkPlatformPkg/Quark.dsc     |  948 ++++
> Platform/Intel/QuarkPlatformPkg/Quark.fdf     |  907 ++++
> Platform/Intel/QuarkPlatformPkg/QuarkMin.dsc  |  648 +++
> Platform/Intel/QuarkPlatformPkg/QuarkMin.fdf  |  608 +++
> .../QuarkPlatformPkg/QuarkPlatformPkg.dec     |  933 ++++
> Platform/Intel/QuarkPlatformPkg/Readme.md     |  685 +++
> Platform/Intel/Vlv2TbltDevicePkg/.gitignore   |    5 +
> .../AcpiPlatform/AcpiPlatform.c               | 1338 +++++
> .../AcpiPlatform/AcpiPlatform.h               |  219 +
> .../AcpiPlatform/AcpiPlatform.inf             |   89 +
> .../AcpiPlatform/AcpiPlatformHooks.c          |  493 ++
> .../AcpiPlatform/AcpiPlatformHooks.h          |  127 +
> .../AcpiPlatform/AcpiPlatformHooksLib.h       |   91 +
> .../Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h     |   56 +
> .../FirmwareUpdate/FirmwareUpdate.c           |  922 ++++
> .../FirmwareUpdate/FirmwareUpdate.h           |  185 +
> .../FirmwareUpdate/FirmwareUpdate.inf         |   83 +
> .../FirmwareUpdate/FirmwareUpdateStrings.uni  |   45 +
> Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe   |  Bin 0 -> 499712 bytes
> Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env  |   25 +
> Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env  |   25 +
> .../Intel/Vlv2TbltDevicePkg/BiosIdx64D.env    |   25 +
> .../Intel/Vlv2TbltDevicePkg/BiosIdx64R.env    |   25 +
> .../BootScriptSaveDxe/BootScriptSaveDxe.inf   |   60 +
> .../InternalBootScriptSave.h                  |  102 +
> .../BootScriptSaveDxe/ScriptSave.c            |  626 +++
> .../Intel/Vlv2TbltDevicePkg/Build_IFWI.bat    |  200 +
> .../Intel/Vlv2TbltDevicePkg/Build_IFWI.sh     |  104 +
> Platform/Intel/Vlv2TbltDevicePkg/FCE.exe      |  Bin 0 -> 632832 bytes
> .../Capsule/GenerateCapsule/GenCapsuleAll.bat |   35 +
> .../Capsule/GenerateCapsule/GenCapsuleAll.sh  |   28 +
> .../GenerateCapsule/GenCapsuleMinnowMax.bat   |  131 +
> .../GenerateCapsule/GenCapsuleMinnowMax.sh    |   65 +
> .../GenCapsuleMinnowMaxRelease.bat            |  131 +
> .../GenCapsuleMinnowMaxRelease.sh             |   65 +
> .../GenerateCapsule/GenCapsuleSampleColor.bat |  137 +
> .../GenerateCapsule/GenCapsuleSampleColor.sh  |   70 +
> .../Feature/Capsule/GenerateCapsule/Lvfs.ddf  |   14 +
> .../LvfsGenCapsuleMinnowMax.bat               |  139 +
> .../LvfsGenCapsuleMinnowMaxRelease.bat        |  139 +
> .../LvfsGenCapsuleSampleColor.bat             |  145 +
> ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
> ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
> ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
> .../GenerateCapsule/template.metainfo.xml     |   27 +
> .../Library/FmpDeviceLib/FmpDeviceLib.c       |  589 +++
> .../Library/FmpDeviceLib/FmpDeviceLib.inf     |   46 +
> .../Library/FmpDeviceLibSample/FmpDeviceLib.c |  412 ++
> .../FmpDeviceLibSample/FmpDeviceLib.inf       |   34 +
> .../PlatformFlashAccessLib.c                  |  685 +++
> .../PlatformFlashAccessLib.inf                |   54 +
> .../SystemFirmwareDescriptor.aslc             |   83 +
> .../SystemFirmwareDescriptor.inf              |   40 +
> .../SystemFirmwareDescriptorPei.c             |   60 +
> .../SystemFirmwareUpdateConfig.ini            |   66 +
> .../SystemFirmwareUpdateConfigGcc.ini         |   66 +
> .../Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc |   55 +
> .../Vlv2TbltDevicePkg/FmpCertificate.dsc      |   22 +
> .../FmpGreenSampleDevice.dsc                  |   55 +
> .../Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc  |   59 +
> .../Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc  |   55 +
> .../FspAzaliaConfigData/AzaliaConfig.bin      |  Bin 0 -> 3708 bytes
> .../FspSupport/BootModePei/BootModePei.c      |   42 +
> .../FspSupport/BootModePei/BootModePei.inf    |   40 +
> .../FspHobProcessLibVlv2.c                    |  421 ++
> .../FspHobProcessLibVlv2.inf                  |   74 +
> .../FspPlatformSecLibVlv2.c                   |  144 +
> .../FspPlatformSecLibVlv2.inf                 |   82 +
> .../Ia32/AsmSaveSecContext.asm                |   45 +
> .../SecFspPlatformSecLibVlv2/Ia32/Fsp.inc     |   45 +
> .../Ia32/PeiCoreEntry.asm                     |  135 +
> .../Ia32/SecEntry.asm                         |  338 ++
> .../SecFspPlatformSecLibVlv2/Ia32/Stack.S     |   71 +
> .../SecFspPlatformSecLibVlv2/Ia32/Stack.asm   |   76 +
> .../SecFspPlatformSecLibVlv2/PlatformInit.c   |   36 +
> .../SecFspPlatformSecLibVlv2/SaveSecContext.c |  108 +
> .../SecGetPerformance.c                       |   83 +
> .../SecPlatformInformation.c                  |   77 +
> .../SecFspPlatformSecLibVlv2/SecRamInitData.c |   16 +
> .../SecTempRamSupport.c                       |  149 +
> .../SecFspPlatformSecLibVlv2/UartInit.c       |  192 +
> .../Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c   |   68 +
> .../Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf |   49 +
> .../Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c |  170 +
> .../FvbRuntimeDxe/FvbRuntimeDxe.inf           |   80 +
> .../FvbRuntimeDxe/FvbService.c                | 1098 ++++
> .../FvbRuntimeDxe/FvbService.h                |  182 +
> .../FvbRuntimeDxe/FvbServiceDxe.c             |  199 +
> .../FvbRuntimeDxe/FvbServiceSmm.c             |  127 +
> .../FvbRuntimeDxe/FvbSmm.inf                  |   82 +
> .../FvbRuntimeDxe/FvbSmmCommon.h              |   73 +
> .../FvbRuntimeDxe/FvbSmmDxe.c                 |  944 ++++
> .../FvbRuntimeDxe/FvbSmmDxe.h                 |  232 +
> .../FvbRuntimeDxe/FvbSmmDxe.inf               |   50 +
> Platform/Intel/Vlv2TbltDevicePkg/GenBiosId    |  Bin 0 -> 12236 bytes
> .../Intel/Vlv2TbltDevicePkg/GenBiosId.exe     |  Bin 0 -> 384000 bytes
> .../Include/AlertStandardFormatTable.h        |  122 +
> .../Vlv2TbltDevicePkg/Include/ChipsetAccess.h |   28 +
> .../Include/CommonIncludes.h                  |  115 +
> .../Intel/Vlv2TbltDevicePkg/Include/CpuType.h |   59 +
> .../Vlv2TbltDevicePkg/Include/FileHandleLib.h |  499 ++
> .../Include/Guid/AcpiTableStorage.h           |   30 +
> .../Include/Guid/AlertStandardFormat.h        |   86 +
> .../Vlv2TbltDevicePkg/Include/Guid/BiosId.h   |   30 +
> .../Include/Guid/BoardFeatures.h              |  214 +
> .../Include/Guid/EfiVpdData.h                 |  156 +
> .../Include/Guid/FirmwareId.h                 |   61 +
> .../Include/Guid/HwWatchdogTimerHob.h         |  134 +
> .../Vlv2TbltDevicePkg/Include/Guid/IdccData.h |  104 +
> .../Vlv2TbltDevicePkg/Include/Guid/ItkData.h  |   70 +
> .../Include/Guid/MemoryConfigData.h           |   32 +
> .../Include/Guid/OsSelection.h                |   85 +
> .../Include/Guid/PciLanInfo.h                 |   39 +
> .../Include/Guid/PlatformCpuInfo.h            |  180 +
> .../Include/Guid/PlatformInfo.h               |  433 ++
> .../Include/Guid/SensorInfoVariable.h         |  279 +
> .../Include/Guid/SetupVariable.h              | 1344 +++++
> .../Intel/Vlv2TbltDevicePkg/Include/Hpet.h    |   40 +
> .../Include/Library/BiosIdLib.h               |  104 +
> .../Include/Library/CpuIA32.h                 |  345 ++
> .../Include/Library/EfiRegTableLib.h          |  196 +
> .../Vlv2TbltDevicePkg/Include/Library/Esrt.h  |   74 +
> .../Vlv2TbltDevicePkg/Include/Library/Fd.h    |  264 +
> .../Include/Library/FlashDeviceLib.h          |  122 +
> .../Include/Library/I2CLib.h                  |   58 +
> .../Include/Library/I2cMmioConfigLib.h        |   23 +
> .../Include/Library/I2cPort_platform.h        |   26 +
> .../Include/Library/PlatformFsaLib.h          |   50 +
> .../Include/Library/PlatformFspLib.h          |   23 +
> .../Include/Library/SpiFlash.H                |  239 +
> .../Include/Library/StallSmmLib.h             |   40 +
> .../Include/Library/UsbDeviceModeLib.h        |  181 +
> .../Intel/Vlv2TbltDevicePkg/Include/Mcfg.h    |   69 +
> .../Vlv2TbltDevicePkg/Include/McfgTable.h     |   65 +
> .../Vlv2TbltDevicePkg/Include/Platform.h      |  133 +
> .../Include/PlatformBootMode.h                |   35 +
> .../Include/PlatformDefinitions.h             |   43 +
> .../Include/Ppi/MfgMemoryTest.h               |   42 +
> .../Include/Ppi/Sha256Hash.h                  |  131 +
> .../Vlv2TbltDevicePkg/Include/Ppi/Speaker.h   |   65 +
> .../Include/Ppi/UsbController.h               |   85 +
> .../Include/Protocol/CK505ClockPlatformInfo.h |  126 +
> .../Include/Protocol/EnhancedSpeedstep.h      |   76 +
> .../Include/Protocol/GlobalNvsArea.h          |  475 ++
> .../Include/Protocol/HwWatchdogTimer.h        |  235 +
> .../Include/Protocol/I2cAcpi.h                |  107 +
> .../Include/Protocol/I2cBus.h                 |  164 +
> .../Include/Protocol/I2cBusMcg.h              |  163 +
> .../Include/Protocol/I2cHostMcg.h             |  138 +
> .../Include/Protocol/I2cMasterMcg.h           |  519 ++
> .../Include/Protocol/I2cSlave.h               |  194 +
> .../Include/Protocol/LpcWpc83627Policy.h      |   92 +
> .../Include/Protocol/LpcWpce791Policy.h       |   55 +
> .../Include/Protocol/MmioDevice.h             |   84 +
> .../Include/Protocol/Observable.h             |  186 +
> .../Include/Protocol/PlatformGopPolicy.h      |   68 +
> .../Include/Protocol/PlatformIdeInit.h        |   43 +
> .../Include/Protocol/SetupMode.h              |   79 +
> .../Include/Protocol/SmbiosSlotPopulation.h   |   47 +
> .../Include/Protocol/Speaker.h                |   65 +
> .../Include/Protocol/TcoReset.h               |   67 +
> .../Include/Protocol/TpmMp.h                  |  136 +
> .../Include/Protocol/UsbPolicy.h              |  126 +
> .../Include/Protocol/VlvPlatformPolicy.h      |  102 +
> .../Vlv2TbltDevicePkg/Include/SetupMode.h     |   85 +
> .../IntelGopDepex/IntelGopDriver.depex        |    1 +
> .../Library/BiosIdLib/BiosIdLib.c             |  337 ++
> .../Library/BiosIdLib/BiosIdLib.inf           |   50 +
> .../Library/CpuIA32Lib/CpuIA32Lib.inf         |   41 +
> .../Library/CpuIA32Lib/EfiCpuVersion.c        |   70 +
> .../Library/CpuIA32Lib/IA32/CpuIA32.S         |  223 +
> .../Library/CpuIA32Lib/IA32/CpuIA32.asm       |  206 +
> .../Library/CpuIA32Lib/IA32/CpuIA32.c         |  177 +
> .../Library/CpuIA32Lib/X64/Cpu.S              |  207 +
> .../Library/CpuIA32Lib/X64/Cpu.asm            |  222 +
> .../Library/EfiRegTableLib/EfiRegTableLib.c   |  282 ++
> .../Library/EfiRegTableLib/EfiRegTableLib.inf |   47 +
> .../Library/FlashDeviceLib/FlashDeviceLib.c   |  461 ++
> .../Library/FlashDeviceLib/FlashDeviceLib.inf |   44 +
> .../FlashDeviceLib/FlashDeviceLibDxe.c        |   56 +
> .../FlashDeviceLib/FlashDeviceLibDxe.inf      |   43 +
> .../FlashDeviceLibDxeRuntimeSmm.c             |  173 +
> .../FlashDeviceLib/SpiChipDefinitions.h       |  835 +++
> .../Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c |   46 +
> .../Library/I2CLib/I2CLibNull.inf             |   39 +
> .../Library/I2CLibDxe/I2CLib.c                |  735 +++
> .../Library/I2CLibDxe/I2CLibDxe.inf           |   39 +
> .../Library/I2CLibDxe/I2CRegs.h               |  126 +
> .../Library/I2CLibPei/I2CAccess.h             |   44 +
> .../Library/I2CLibPei/I2CDelayPei.c           |   46 +
> .../Library/I2CLibPei/I2CDelayPei.h           |   30 +
> .../Library/I2CLibPei/I2CIoLibPei.c           |  178 +
> .../Library/I2CLibPei/I2CIoLibPei.h           |  153 +
> .../Library/I2CLibPei/I2CLibPei.c             |  638 +++
> .../Library/I2CLibPei/I2CLibPei.h             |  280 +
> .../Library/I2CLibPei/I2CLibPei.inf           |   40 +
> .../IntelPchAcpiTimerLib/CommonHeader.h       |   27 +
> .../IntelPchAcpiTimerLib.c                    |  255 +
> .../IntelPchAcpiTimerLib.inf                  |   51 +
> .../BoardClkGens/BoardClkGens.c               |  430 ++
> .../BoardClkGens/BoardClkGens.h               |  255 +
> .../MultiPlatformLib/BoardGpios/BoardGpios.c  |  531 ++
> .../MultiPlatformLib/BoardGpios/BoardGpios.h  |  324 ++
> .../BoardJumpers/BoardJumpers.c               |   30 +
> .../BoardJumpers/BoardJumpers.h               |   30 +
> .../BoardOemIds/BoardOemIds.c                 |   43 +
> .../BoardOemIds/BoardOemIds.h                 |   29 +
> .../BoardSsidSvid/BoardSsidSvid.c             |   38 +
> .../BoardSsidSvid/BoardSsidSvid.h             |   35 +
> .../MultiPlatformLib/MultiPlatformLib.c       |  120 +
> .../MultiPlatformLib/MultiPlatformLib.h       |   89 +
> .../MultiPlatformLib/MultiPlatformLib.inf     |   77 +
> .../MultiPlatformLib/PlatformInfoHob.c        |   54 +
> .../Library/PchPlatformLib/PchPlatformLib.inf |   50 +
> .../PchPlatformLib/PchPlatformLibrary.c       |  131 +
> .../PchPlatformLib/PchPlatformLibrary.h       |   35 +
> .../Library/PchSmmLib/CommonHeader.h          |   32 +
> .../Library/PchSmmLib/PchSmmLib.c             |  157 +
> .../Library/PchSmmLib/PchSmmLib.inf           |   46 +
> .../Library/PlatformBdsLib/BdsPlatform.c      | 3098 ++++++++++++
> .../Library/PlatformBdsLib/BdsPlatform.h      |  516 ++
> .../Library/PlatformBdsLib/PlatformBdsLib.inf |  127 +
> .../PlatformBdsLib/PlatformBdsStrings.uni     |   30 +
> .../Library/PlatformBdsLib/PlatformData.c     |  306 ++
> .../Library/PlatformCmosLib/PlatformCmosLib.c |  106 +
> .../PlatformCmosLib/PlatformCmosLib.inf       |   30 +
> .../Library/PlatformFspLib/PlatformFspLib.c   |   44 +
> .../Library/PlatformFspLib/PlatformFspLib.inf |   49 +
> .../Library/ResetSystemLib/ResetSystemLib.c   |  235 +
> .../Library/ResetSystemLib/ResetSystemLib.inf |   47 +
> .../SerialPortLib/PlatformSerialPortLib.h     |   53 +
> .../Library/SerialPortLib/SerialPortLib.c     |  246 +
> .../Library/SerialPortLib/SerialPortLib.inf   |   52 +
> .../Library/SerialPortLib/SioInit.c           |  127 +
> .../Library/SerialPortLib/SioInit.h           |   62 +
> .../Library/SmbusLib/CommonHeader.h           |   26 +
> .../Library/SmbusLib/SmbusLib.c               |  873 ++++
> .../Library/SmbusLib/SmbusLib.inf             |   46 +
> .../Library/StallSmmLib/StallSmm.c            |   89 +
> .../Library/StallSmmLib/StallSmmLib.inf       |   51 +
> .../Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.c    |  117 +
> .../Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.inf  |   61 +
> .../Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.c    |  145 +
> .../Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.inf  |   60 +
> .../Intel/Vlv2TbltDevicePkg/Logo/Logo.bmp     |  Bin 0 -> 94434 bytes
> .../Metronome/LegacyMetronome.c               |  185 +
> .../Metronome/LegacyMetronome.h               |   64 +
> .../Vlv2TbltDevicePkg/Metronome/Metronome.inf |   49 +
> .../MonoStatusCode/EfiStatusCode.h            |  178 +
> .../MonoStatusCode/MonoStatusCode.c           |  132 +
> .../MonoStatusCode/MonoStatusCode.h           |  128 +
> .../MonoStatusCode/MonoStatusCode.inf         |   72 +
> .../MonoStatusCode/PeiPostCode.c              |  121 +
> .../MonoStatusCode/PlatformStatusCode.c       |  381 ++
> .../MonoStatusCode/PlatformStatusCode.h       |  138 +
> .../Library/GenericBdsLib/BdsBoot.c           | 4490 +++++++++++++++++
> .../Library/GenericBdsLib/BdsConnect.c        |  429 ++
> .../Library/GenericBdsLib/BdsConsole.c        | 1061 ++++
> .../Library/GenericBdsLib/BdsMisc.c           | 1575 ++++++
> .../Library/GenericBdsLib/DevicePath.c        |   27 +
> .../Library/GenericBdsLib/GenericBdsLib.inf   |  142 +
> .../Library/GenericBdsLib/GenericBdsLib.uni   |   19 +
> .../GenericBdsLib/GenericBdsStrings.uni       |   30 +
> .../Library/GenericBdsLib/InternalBdsLib.h    |  173 +
> .../Library/GenericBdsLib/String.c            |   26 +
> .../Library/GenericBdsLib/String.h            |   42 +
> .../PciPlatform/BoardPciPlatform.c            |   55 +
> .../PciPlatform/PciPlatform.c                 |  367 ++
> .../PciPlatform/PciPlatform.h                 |   83 +
> .../PciPlatform/PciPlatform.inf               |   65 +
> .../Vlv2TbltDevicePkg/PlatformCapsule.dsc     |   39 +
> .../Vlv2TbltDevicePkg/PlatformCapsule.fdf     |   52 +
> .../Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc  |   38 +
> .../Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf  |   52 +
> .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.c   |   60 +
> .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.h   |   29 +
> .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf |   55 +
> .../PlatformDxe/AzaliaVerbTable.h             |  247 +
> .../Vlv2TbltDevicePkg/PlatformDxe/BoardId.c   |  223 +
> .../PlatformDxe/BoardIdDecode.c               |  129 +
> .../PlatformDxe/BoardIdDecode.h               |   61 +
> .../PlatformDxe/ClockControl.c                |  202 +
> .../PlatformDxe/Configuration.h               |  692 +++
> .../Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c |   89 +
> .../PlatformDxe/IchPlatformPolicy.c           |  484 ++
> .../PlatformDxe/IchRegTable.c                 |  134 +
> .../PlatformDxe/IchTcoReset.c                 |  211 +
> .../Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c  |   72 +
> .../PlatformDxe/LegacySpeaker.c               |  161 +
> .../PlatformDxe/LegacySpeaker.h               |   69 +
> .../PlatformDxe/Observable/Observable.c       |  582 +++
> .../PlatformDxe/Observable/Observable.h       |  137 +
> .../Vlv2TbltDevicePkg/PlatformDxe/PciBus.h    |  379 ++
> .../Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c |  506 ++
> .../Vlv2TbltDevicePkg/PlatformDxe/Platform.c  | 1820 +++++++
> .../PlatformDxe/PlatformDxe.h                 |  722 +++
> .../PlatformDxe/PlatformDxe.inf               |  149 +
> .../Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c |  154 +
> .../Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c |  112 +
> .../PlatformDxe/SioPlatformPolicy.c           |   82 +
> .../PlatformDxe/SlotConfig.c                  |  148 +
> .../PlatformDxe/SlotConfig.h                  |   80 +
> .../PlatformGopPolicy/PlatformGopPolicy.c     |  201 +
> .../PlatformGopPolicy/PlatformGopPolicy.inf   |   51 +
> .../PlatformInfoDxe/PlatformInfoDxe.c         |  169 +
> .../PlatformInfoDxe/PlatformInfoDxe.h         |   30 +
> .../PlatformInfoDxe/PlatformInfoDxe.inf       |   52 +
> .../PlatformInitPei/BootMode.c                |  434 ++
> .../PlatformInitPei/CpuInitPeim.c             |   44 +
> .../Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c  |  319 ++
> .../PlatformInitPei/FlashMap.c                |  143 +
> .../PlatformInitPei/LegacySpeaker.c           |  168 +
> .../PlatformInitPei/LegacySpeaker.h           |   71 +
> .../PlatformInitPei/MchInit.c                 |   72 +
> .../PlatformInitPei/MemoryCallback.c          |  338 ++
> .../PlatformInitPei/MemoryPeim.c              |  408 ++
> .../PlatformInitPei/PchInitPeim.c             |  808 +++
> .../PlatformInitPei/PlatformEarlyInit.c       | 1195 +++++
> .../PlatformInitPei/PlatformEarlyInit.h       | 1499 ++++++
> .../PlatformInitPei/PlatformInfoInit.c        |  181 +
> .../PlatformInitPei/PlatformInitPei.inf       |  117 +
> .../PlatformInitPei/PlatformSsaInitPeim.c     |   58 +
> .../PlatformInitPei/Recovery.c                |  361 ++
> .../Vlv2TbltDevicePkg/PlatformInitPei/Stall.c |   91 +
> .../Vlv2TbltDevicePkg/PlatformPei/BootMode.c  |  346 ++
> .../PlatformPei/CommonHeader.h                |   60 +
> .../PlatformPei/MemoryCallback.c              |  154 +
> .../Vlv2TbltDevicePkg/PlatformPei/Platform.c  | 1198 +++++
> .../Vlv2TbltDevicePkg/PlatformPei/Platform.h  |  213 +
> .../PlatformPei/PlatformPei.inf               |  129 +
> .../Vlv2TbltDevicePkg/PlatformPei/Stall.c     |   90 +
> .../Intel/Vlv2TbltDevicePkg/PlatformPkg.dec   |  211 +
> .../Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf   | 1073 ++++
> .../Vlv2TbltDevicePkg/PlatformPkgConfig.dsc   |  107 +
> .../Vlv2TbltDevicePkg/PlatformPkgGcc.fdf      | 1033 ++++
> .../Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc   | 1711 +++++++
> .../Vlv2TbltDevicePkg/PlatformPkgIA32.dsc     | 1699 +++++++
> .../Vlv2TbltDevicePkg/PlatformPkgX64.dsc      | 1714 +++++++
> .../PlatformSetupDxe/Boot.vfi                 |   72 +
> .../PlatformSetupDxe/Configuration.h          |   56 +
> .../PlatformSetupDxe/DebugConfig.vfi          |  118 +
> .../PlatformSetupDxe/FwVersionStrings.uni     |   40 +
> .../PlatformSetupDxe/Main.vfi                 |  331 ++
> .../PlatformSetupDxe/PlatformSetupDxe.c       |  929 ++++
> .../PlatformSetupDxe/PlatformSetupDxe.h       |   97 +
> .../PlatformSetupDxe/PlatformSetupDxe.inf     |  141 +
> .../PlatformSetupDxe/Security.vfi             |  104 +
> .../PlatformSetupDxe/SetupFunctions.c         |   85 +
> .../PlatformSetupDxe/SetupInfoRecords.c       | 1855 +++++++
> .../PlatformSetupDxe/SouthClusterConfig.vfi   |  933 ++++
> .../PlatformSetupDxe/SystemComponent.vfi      |   81 +
> .../PlatformSetupDxe/Thermal.vfi              |  106 +
> .../PlatformSetupDxe/UnCore.vfi               |  235 +
> .../PlatformSetupDxe/UqiList.uni              |  452 ++
> .../PlatformSetupDxe/Vfr.vfr                  |  123 +
> .../PlatformSetupDxe/VfrStrings.uni           | 1417 ++++++
> .../Vlv2TbltDevicePkg/PlatformSmm/Platform.c  |  997 ++++
> .../PlatformSmm/PlatformSmm.inf               |   93 +
> .../Vlv2TbltDevicePkg/PlatformSmm/S3Save.c    |  377 ++
> .../PlatformSmm/SmmPlatform.h                 |  240 +
> .../PlatformSmm/SmmScriptSave.c               |  252 +
> .../PlatformSmm/SmmScriptSave.h               |   50 +
> .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c   |  148 +
> .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h   |   36 +
> .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf |   49 +
> Platform/Intel/Vlv2TbltDevicePkg/Readme.md    |  233 +
> .../SaveMemoryConfig/SaveMemoryConfig.c       |  181 +
> .../SaveMemoryConfig/SaveMemoryConfig.h       |   66 +
> .../SaveMemoryConfig/SaveMemoryConfig.inf     |   60 +
> .../SmBiosMiscDxe/CommonHeader.h              |   39 +
> .../MiscBaseBoardManufacturer.uni             |   33 +
> .../MiscBaseBoardManufacturerData.c           |   58 +
> .../MiscBaseBoardManufacturerFunction.c       |  238 +
> .../SmBiosMiscDxe/MiscBiosVendor.uni          |   26 +
> .../SmBiosMiscDxe/MiscBiosVendorData.c        |  101 +
> .../SmBiosMiscDxe/MiscBiosVendorFunction.c    |  336 ++
> .../SmBiosMiscDxe/MiscBootInformationData.c   |   34 +
> .../MiscBootInformationFunction.c             |   82 +
> .../SmBiosMiscDxe/MiscChassisManufacturer.uni |   28 +
> .../MiscChassisManufacturerData.c             |   57 +
> .../MiscChassisManufacturerFunction.c         |  158 +
> .../SmBiosMiscDxe/MiscMemoryDevice.uni        |   35 +
> .../SmBiosMiscDxe/MiscMemoryDeviceData.c      |   45 +
> .../SmBiosMiscDxe/MiscMemoryDeviceFunction.c  |  319 ++
> .../MiscNumberOfInstallableLanguagesData.c    |   38 +
> ...MiscNumberOfInstallableLanguagesFunction.c |  251 +
> .../SmBiosMiscDxe/MiscOemString.uni           |   25 +
> .../SmBiosMiscDxe/MiscOemStringData.c         |   34 +
> .../SmBiosMiscDxe/MiscOemStringFunction.c     |   89 +
> .../SmBiosMiscDxe/MiscOemType0x90.uni         |   31 +
> .../SmBiosMiscDxe/MiscOemType0x90Data.c       |   36 +
> .../SmBiosMiscDxe/MiscOemType0x90Function.c   |  442 ++
> .../SmBiosMiscDxe/MiscOemType0x94.uni         |   42 +
> .../SmBiosMiscDxe/MiscOemType0x94Data.c       |   54 +
> .../SmBiosMiscDxe/MiscOemType0x94Function.c   | 1218 +++++
> .../SmBiosMiscDxe/MiscOnboardDevice.uni       |   26 +
> .../SmBiosMiscDxe/MiscOnboardDeviceData.c     |   48 +
> .../SmBiosMiscDxe/MiscOnboardDeviceFunction.c |  135 +
> .../SmBiosMiscDxe/MiscPhysicalArray.uni       |   25 +
> .../SmBiosMiscDxe/MiscPhysicalArrayData.c     |   38 +
> .../SmBiosMiscDxe/MiscPhysicalArrayFunction.c |  101 +
> .../MiscPortInternalConnectorDesignator.uni   |   31 +
> .../MiscPortInternalConnectorDesignatorData.c |   56 +
> ...cPortInternalConnectorDesignatorFunction.c |  152 +
> .../SmBiosMiscDxe/MiscProcessorCache.uni      |   22 +
> .../SmBiosMiscDxe/MiscProcessorCacheData.c    |   33 +
> .../MiscProcessorCacheFunction.c              |  189 +
> .../MiscProcessorInformation.uni              |   27 +
> .../MiscProcessorInformationData.c            |   71 +
> .../MiscProcessorInformationFunction.c        |  448 ++
> .../SmBiosMiscDxe/MiscResetCapabilitiesData.c |   43 +
> .../MiscResetCapabilitiesFunction.c           |   85 +
> .../SmBiosMiscDxe/MiscSubclassDriver.h        |  188 +
> .../SmBiosMiscDxe/MiscSubclassDriver.uni      |   35 +
> .../MiscSubclassDriverDataTable.c             |   98 +
> .../MiscSubclassDriverEntryPoint.c            |  182 +
> .../MiscSystemLanguageString.uni              |   24 +
> .../MiscSystemLanguageStringData.c            |   34 +
> .../MiscSystemLanguageStringFunction.c        |   93 +
> .../SmBiosMiscDxe/MiscSystemManufacturer.uni  |   30 +
> .../MiscSystemManufacturerData.c              |   48 +
> .../MiscSystemManufacturerFunction.c          |  364 ++
> .../SmBiosMiscDxe/MiscSystemOptionString.uni  |   24 +
> .../MiscSystemOptionStringData.c              |   31 +
> .../MiscSystemOptionStringFunction.c          |   93 +
> .../MiscSystemSlotDesignation.uni             |   34 +
> .../MiscSystemSlotDesignationData.c           |  246 +
> .../MiscSystemSlotDesignationFunction.c       |  127 +
> .../SmBiosMiscDxe/SmBiosMiscDxe.inf           |  139 +
> .../SmmSwDispatch2OnSmmSwDispatchThunk.c      |  459 ++
> .../SmmSwDispatch2OnSmmSwDispatchThunk.inf    |   54 +
> .../SmramSaveInfoHandlerSmm.c                 |  164 +
> .../SmramSaveInfoHandlerSmm.inf               |   60 +
> .../Stitch/Gcc/NvStorageFtwSpare.bin          |  Bin 0 -> 262144 bytes
> .../Stitch/Gcc/NvStorageFtwWorking.bin        |  Bin 0 -> 8192 bytes
> .../Stitch/Gcc/NvStorageVariable.bin          |  Bin 0 -> 253952 bytes
> .../Stitch/IFWIHeader/IFWI_HEADER.bin         |  Bin 0 -> 4096 bytes
> .../Stitch/IFWIHeader/IFWI_HEADER_SPILOCK.bin |  Bin 0 -> 4096 bytes
> .../Stitch/IFWIHeader/Vacant.bin              |  Bin 0 -> 3928064 bytes
> .../Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat   |  270 +
> .../Stitch/MNW2_Stitch_Config.txt             |   10 +
> .../Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c |   33 +
> .../Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf   |   32 +
> .../VlvPlatformInitDxe/IgdOpRegion.c          |  929 ++++
> .../VlvPlatformInitDxe/IgdOpRegion.h          |  235 +
> .../VlvPlatformInitDxe/VlvPlatformInit.c      |  287 ++
> .../VlvPlatformInitDxe/VlvPlatformInit.h      |   65 +
> .../VlvPlatformInitDxe/VlvPlatformInitDxe.inf |   74 +
> .../Vlv2TbltDevicePkg/Wpce791/LpcDriver.c     |  340 ++
> .../Vlv2TbltDevicePkg/Wpce791/LpcDriver.h     |  112 +
> .../Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c    |  366 ++
> .../Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h    |  103 +
> .../Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c  |  126 +
> .../Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h  |  101 +
> .../Vlv2TbltDevicePkg/Wpce791/Wpce791.inf     |   63 +
> Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat  |  332 ++
> Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh   |  256 +
> Platform/Intel/Vlv2TbltDevicePkg/cln.sh       |   62 +
> Readme.md                                     |    9 +
> .../Include/DdrMemoryController.h             |  251 +
> .../QuarkNorthCluster/Include/IntelQNCBase.h  |   17 +
> .../Include/IntelQNCConfig.h                  |  100 +
> .../QuarkNorthCluster/Include/IntelQNCDxe.h   |   17 +
> .../QuarkNorthCluster/Include/IntelQNCPeim.h  |   17 +
> .../QuarkNorthCluster/Include/IntelQNCRegs.h  |   48 +
> .../Include/Library/IntelQNCLib.h             |  284 ++
> .../Include/Library/QNCAccessLib.h            |  161 +
> .../Include/Library/QNCSmmLib.h               |   57 +
> .../Include/Ppi/QNCMemoryInit.h               |   36 +
> .../Include/Protocol/PchInfo.h                |   48 +
> .../Include/Protocol/PlatformPolicy.h         |   31 +
> .../Include/Protocol/QncS3Support.h           |   84 +
> .../Include/Protocol/SmmIchnDispatch2.h       |  115 +
> .../QuarkNorthCluster/Include/Protocol/Spi.h  |  345 ++
> .../QuarkNorthCluster/Include/QNCAccess.h     |  177 +
> .../Include/QNCCommonDefinitions.h            |  350 ++
> .../QuarkNorthCluster/Include/QuarkNcSocId.h  |  751 +++
> .../Library/IntelQNCLib/CommonHeader.h        |   32 +
> .../Library/IntelQNCLib/IntelQNCLib.c         |  771 +++
> .../Library/IntelQNCLib/IntelQNCLib.inf       |   57 +
> .../Library/IntelQNCLib/PciExpress.c          |  932 ++++
> .../Library/MtrrLib/MtrrLib.c                 | 2112 ++++++++
> .../Library/MtrrLib/MtrrLib.inf               |   42 +
> .../Library/MtrrLib/MtrrLib.uni               |   18 +
> .../Library/QNCAccessLib/BaseAccess.c         |   28 +
> .../Library/QNCAccessLib/QNCAccessLib.c       |  327 ++
> .../Library/QNCAccessLib/QNCAccessLib.inf     |   37 +
> .../Library/QNCAccessLib/RuntimeAccess.c      |  142 +
> .../QNCAccessLib/RuntimeQNCAccessLib.inf      |   43 +
> .../Library/QNCSmmLib/QNCSmmLib.c             |  313 ++
> .../Library/QNCSmmLib/QNCSmmLib.inf           |   44 +
> .../Library/ResetSystemLib/ResetSystemLib.c   |  379 ++
> .../Library/ResetSystemLib/ResetSystemLib.inf |   46 +
> .../Library/SmbusLib/CommonHeader.h           |   25 +
> .../Library/SmbusLib/SmbusLib.c               |  797 +++
> .../Library/SmbusLib/SmbusLib.inf             |   47 +
> .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.c     |  446 ++
> .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf   |   30 +
> .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.uni   |   12 +
> .../MemoryInit/Pei/MemoryInit.c               |   59 +
> .../MemoryInit/Pei/MemoryInit.h               |   35 +
> .../MemoryInit/Pei/MemoryInitPei.inf          |   70 +
> .../MemoryInit/Pei/core_types.h               |   43 +
> .../MemoryInit/Pei/gen5_iosf_sb_definitions.h |  738 +++
> .../MemoryInit/Pei/general_definitions.h      |   84 +
> .../QuarkNorthCluster/MemoryInit/Pei/hte.c    |  536 ++
> .../QuarkNorthCluster/MemoryInit/Pei/hte.h    |   66 +
> .../QuarkNorthCluster/MemoryInit/Pei/io.h     |  132 +
> .../QuarkNorthCluster/MemoryInit/Pei/lprint.c |  382 ++
> .../MemoryInit/Pei/meminit.c                  | 2638 ++++++++++
> .../MemoryInit/Pei/meminit.h                  |   22 +
> .../MemoryInit/Pei/meminit_utils.c            | 1574 ++++++
> .../MemoryInit/Pei/meminit_utils.h            |   95 +
> .../MemoryInit/Pei/memory_options.h           |   77 +
> .../QuarkNorthCluster/MemoryInit/Pei/mrc.c    |   40 +
> .../QuarkNorthCluster/MemoryInit/Pei/mrc.h    |  160 +
> .../MemoryInit/Pei/platform.c                 |  186 +
> .../MemoryInit/Pei/prememinit.c               |  187 +
> .../MemoryInit/Pei/prememinit.h               |   15 +
> .../QNCInit/Dxe/CommonHeader.h                |   49 +
> .../QNCInit/Dxe/DxeQNCSmbus.c                 |  612 +++
> .../QNCInit/Dxe/DxeQNCSmbus.h                 |  205 +
> .../QNCInit/Dxe/LegacyRegion.c                |  237 +
> .../QNCInit/Dxe/LegacyRegion.h                |  198 +
> .../QuarkNorthCluster/QNCInit/Dxe/QNCInit.c   |  518 ++
> .../QuarkNorthCluster/QNCInit/Dxe/QNCInit.h   |   49 +
> .../QNCInit/Dxe/QNCInitDxe.inf                |   92 +
> .../QNCInit/Dxe/QNCRootPorts.c                |   76 +
> .../QuarkNorthCluster/QNCInit/Dxe/QNCSmbus.h  |   80 +
> .../QNCInit/Dxe/QNCSmbusExec.c                |  246 +
> .../S3Support/Dxe/QncS3Support.c              |  417 ++
> .../S3Support/Dxe/QncS3Support.h              |  117 +
> .../S3Support/Dxe/QncS3Support.inf            |   64 +
> .../Smm/Dxe/SmmAccessDxe/SmmAccess.inf        |   49 +
> .../Smm/Dxe/SmmAccessDxe/SmmAccessDriver.c    |  405 ++
> .../Smm/Dxe/SmmAccessDxe/SmmAccessDriver.h    |  230 +
> .../Smm/Dxe/SmmControlDxe/SmmControlDriver.c  |  358 ++
> .../Smm/Dxe/SmmControlDxe/SmmControlDxe.inf   |   55 +
> .../DxeSmm/QncSmmDispatcher/CommonHeader.h    |   45 +
> .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmGpi.c   |   32 +
> .../QncSmmDispatcher/QNC/QNCSmmHelpers.c      |  549 ++
> .../QNC/QNCSmmPeriodicTimer.c                 |  424 ++
> .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmQncn.c  |  211 +
> .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmSw.c    |   90 +
> .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmSx.c    |  147 +
> .../Smm/DxeSmm/QncSmmDispatcher/QNCSmm.h      |  868 ++++
> .../Smm/DxeSmm/QncSmmDispatcher/QNCSmmCore.c  |  825 +++
> .../QncSmmDispatcher/QNCSmmDispatcher.inf     |   81 +
> .../DxeSmm/QncSmmDispatcher/QNCSmmHelpers.c   |  367 ++
> .../DxeSmm/QncSmmDispatcher/QNCSmmHelpers.h   |  219 +
> .../DxeSmm/QncSmmDispatcher/QNCSmmRegisters.h |   13 +
> .../DxeSmm/QncSmmDispatcher/QNCxSmmHelpers.h  |  178 +
> .../Smm/Pei/SmmAccessPei/SmmAccessPei.c       |  376 ++
> .../Smm/Pei/SmmAccessPei/SmmAccessPei.inf     |   45 +
> .../Smm/Pei/SmmControlPei/SmmControlPei.c     |  274 +
> .../Smm/Pei/SmmControlPei/SmmControlPei.inf   |   51 +
> .../QuarkNorthCluster/Spi/Common/SpiCommon.c  |  927 ++++
> .../QuarkNorthCluster/Spi/Common/SpiCommon.h  |  317 ++
> .../QuarkNorthCluster/Spi/PchSpiRuntime.inf   |   84 +
> .../QuarkNorthCluster/Spi/PchSpiSmm.inf       |   50 +
> .../QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.c |  205 +
> .../QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.h |   79 +
> .../QuarkNorthCluster/Spi/Smm/PchSpi.c        |  123 +
> .../QuarkNorthCluster/Spi/Smm/PchSpi.h        |   47 +
> Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dec     |  234 +
> Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dsc     |  254 +
> .../QuarkSouthCluster/Include/CEATA.h         |  114 +
> .../QuarkSouthCluster/Include/I2cRegs.h       |   95 +
> .../QuarkSouthCluster/Include/Ioh.h           |  248 +
> .../QuarkSouthCluster/Include/IohAccess.h     |   18 +
> .../Include/IohCommonDefinitions.h            |  342 ++
> .../Include/Library/I2cLib.h                  |  152 +
> .../Include/Library/IohLib.h                  |   36 +
> .../QuarkSouthCluster/Include/MMC.h           |  274 +
> .../QuarkSouthCluster/Include/SDCard.h        |  146 +
> .../QuarkSouthCluster/Include/SDHostIo.h      |  333 ++
> .../IohInit/Dxe/CommonHeader.h                |   55 +
> .../QuarkSouthCluster/IohInit/Dxe/IohBds.h    |   83 +
> .../QuarkSouthCluster/IohInit/Dxe/IohData.c   |   42 +
> .../QuarkSouthCluster/IohInit/Dxe/IohInit.c   |   37 +
> .../IohInit/Dxe/IohInitDxe.inf                |   76 +
> .../Library/I2cLib/CommonHeader.h             |  214 +
> .../QuarkSouthCluster/Library/I2cLib/I2cLib.c |  998 ++++
> .../Library/I2cLib/I2cLib.inf                 |   62 +
> .../Library/IohLib/CommonHeader.h             |   29 +
> .../QuarkSouthCluster/Library/IohLib/IohLib.c |   99 +
> .../Library/IohLib/IohLib.inf                 |   49 +
> .../Sdio/Dxe/SDControllerDxe/ComponentName.c  |  227 +
> .../Sdio/Dxe/SDControllerDxe/ComponentName.h  |  141 +
> .../Sdio/Dxe/SDControllerDxe/SDController.c   | 1784 +++++++
> .../Sdio/Dxe/SDControllerDxe/SDController.h   |  316 ++
> .../Dxe/SDControllerDxe/SDControllerDxe.inf   |   56 +
> .../Sdio/Dxe/SDMediaDeviceDxe/CEATA.c         |  647 +++
> .../Sdio/Dxe/SDMediaDeviceDxe/CEATABlockIo.c  |  389 ++
> .../Sdio/Dxe/SDMediaDeviceDxe/ComponentName.c |  215 +
> .../Sdio/Dxe/SDMediaDeviceDxe/ComponentName.h |  139 +
> .../Sdio/Dxe/SDMediaDeviceDxe/MMCSDBlockIo.c  |  538 ++
> .../Sdio/Dxe/SDMediaDeviceDxe/MMCSDTransfer.c | 1708 +++++++
> .../Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.c |  317 ++
> .../Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.h |  462 ++
> .../Dxe/SDMediaDeviceDxe/SDMediaDeviceDxe.inf |   60 +
> .../QuarkSouthCluster/Usb/Common/Pei/UsbPei.c |  320 ++
> .../QuarkSouthCluster/Usb/Common/Pei/UsbPei.h |   38 +
> .../Usb/Common/Pei/UsbPei.inf                 |   53 +
> .../Usb/Ohci/Dxe/ComponentName.c              |  219 +
> .../Usb/Ohci/Dxe/ComponentName.h              |  141 +
> .../Usb/Ohci/Dxe/Descriptor.h                 |  132 +
> .../QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.c     | 2473 +++++++++
> .../QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.h     |  663 +++
> .../Usb/Ohci/Dxe/OhciDebug.c                  |   78 +
> .../Usb/Ohci/Dxe/OhciDebug.h                  |   42 +
> .../Usb/Ohci/Dxe/OhciDxe.inf                  |   71 +
> .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.c  | 1390 +++++
> .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.h  |  920 ++++
> .../Usb/Ohci/Dxe/OhciSched.c                  |  528 ++
> .../Usb/Ohci/Dxe/OhciSched.h                  |  225 +
> .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.c  |  889 ++++
> .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.h  |  387 ++
> .../QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.c |  560 ++
> .../QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.h |  152 +
> .../Usb/Ohci/Pei/Descriptor.h                 |  131 +
> .../QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.c  | 1386 +++++
> .../QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.h  |  252 +
> .../Usb/Ohci/Pei/OhciPei.inf                  |   56 +
> .../QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.c  | 1386 +++++
> .../QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.h  |  875 ++++
> .../Usb/Ohci/Pei/OhciSched.c                  |  223 +
> .../Usb/Ohci/Pei/OhciSched.h                  |  108 +
> .../QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.c  |  560 ++
> .../QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.h  |  231 +
> .../QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.c |  491 ++
> .../QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.h |  134 +
> .../AcpiTablesPCAT/98_LINK.ASL                |  617 +++
> .../AcpiTablesPCAT/AcpiTablePlatform.h        |   70 +
> .../AcpiTablesPCAT/AcpiTables.inf             |   40 +
> .../AcpiTablesPCAT/CPU.asl                    |   49 +
> .../AcpiTablesPCAT/DSDT.ASL                   |   75 +
> .../AcpiTablesPCAT/Facp/Facp.aslc             |  188 +
> .../AcpiTablesPCAT/Facs/Facs.aslc             |   84 +
> .../AcpiTablesPCAT/GloblNvs.asl               |  348 ++
> .../AcpiTablesPCAT/Gpe.asl                    |   99 +
> .../AcpiTablesPCAT/HOST_BUS.ASL               |  347 ++
> .../AcpiTablesPCAT/Hpet/Hpet.aslc             |   63 +
> .../AcpiTablesPCAT/INTELGFX.ASL               |  879 ++++
> .../AcpiTablesPCAT/INTELISPDev2.ASL           |   71 +
> .../AcpiTablesPCAT/IgdOGBDA.ASL               |  155 +
> .../AcpiTablesPCAT/IgdOMOBF.ASL               |  485 ++
> .../AcpiTablesPCAT/IgdOSBCB.ASL               |  274 +
> .../AcpiTablesPCAT/IgdOpRn.ASL                |  299 ++
> .../AcpiTablesPCAT/IoTVirtualDevice.asl       |  171 +
> .../AcpiTablesPCAT/LPC_DEV.ASL                |  151 +
> .../AcpiTablesPCAT/LpcB.asl                   |   59 +
> .../AcpiTablesPCAT/Lpit/Lpit.aslc             |  223 +
> .../AcpiTablesPCAT/Madt/Madt.h                |  189 +
> .../AcpiTablesPCAT/Madt/Madt30.aslc           |  178 +
> .../AcpiTablesPCAT/Mcfg/Mcfg.aslc             |   86 +
> .../AcpiTablesPCAT/PCI_DRC.ASL                |   90 +
> .../AcpiTablesPCAT/Pch.asl                    |  686 +++
> .../AcpiTablesPCAT/PchAudio.asl               |   36 +
> .../AcpiTablesPCAT/PchEhci.asl                |  269 +
> .../AcpiTablesPCAT/PchLpss.asl                | 1093 ++++
> .../AcpiTablesPCAT/PchPcie.asl                |   50 +
> .../AcpiTablesPCAT/PchScc.asl                 |  610 +++
> .../AcpiTablesPCAT/PchSmb.asl                 |  833 +++
> .../AcpiTablesPCAT/PchXhci.asl                |  379 ++
> .../AcpiTablesPCAT/PciTree.asl                |  377 ++
> .../AcpiTablesPCAT/Platform.asl               |  703 +++
> .../AcpiTablesPCAT/RTD3.asl                   |  197 +
> .../AcpiTablesPCAT/RhProxy.asl                |  160 +
> .../AcpiTablesPCAT/THERMAL.ASL                |  137 +
> .../AcpiTablesPCAT/UsbSbd.asl                 |   93 +
> .../AcpiTablesPCAT/Video.asl                  |   34 +
> .../AcpiTablesPCAT/Vlv.asl                    |   39 +
> .../AcpiTablesPCAT/Wsmt/Wsmt.aslc             |   54 +
> .../AcpiTablesPCAT/token.asl                  |   39 +
> .../Guid/Vlv2DeviceRefCodePkgTokenSpace.h     |   24 +
> .../Include/Ppi/PttPassThruPpi.h              |   92 +
> .../Include/Ppi/fTPMPolicy.h                  |   26 +
> .../Include/Protocol/PttPassThru.h            |   91 +
> .../Guid/PowerManagementAcpiTableStorage.h    |   27 +
> .../CPU/Include/Ppi/VlvPolicy.h               |  104 +
> .../CPU/Include/Protocol/PpmPlatformPolicy.h  |  132 +
> .../ValleyView2Soc/CPU/Include/Types.h        |   55 +
> .../AcpiTables/PowerManagementAcpiTables.inf  |   39 +
> .../PowerManagement/AcpiTables/Ssdt/ApCst.asl |  110 +
> .../PowerManagement/AcpiTables/Ssdt/ApIst.asl |  166 +
> .../PowerManagement/AcpiTables/Ssdt/ApTst.asl |  262 +
> .../AcpiTables/Ssdt/Cpu0Cst.asl               |  274 +
> .../AcpiTables/Ssdt/Cpu0Ist.asl               |  260 +
> .../AcpiTables/Ssdt/Cpu0Tst.asl               |  235 +
> .../PowerManagement/AcpiTables/Ssdt/CpuPm.asl |  793 +++
> .../Include/PlatformBaseAddresses.h           |   92 +
> .../NorthCluster/Include/Ppi/Capsule.h        |   60 +
> .../Include/Ppi/PlatformMemoryRange.h         |  144 +
> .../Include/Ppi/PlatformMemorySize.h          |   46 +
> .../NorthCluster/Include/Ppi/SmmAccess.h      |  165 +
> .../NorthCluster/Include/Ppi/VlvMmioPolicy.h  |   39 +
> .../NorthCluster/Include/Ppi/VlvPeiInit.h     |   35 +
> .../NorthCluster/Include/Ppi/VlvPolicy.h      |  106 +
> .../Include/Protocol/IgdOpRegion.h            |  213 +
> .../NorthCluster/Include/Protocol/MemInfo.h   |   83 +
> .../Include/Protocol/PlatformGopPolicy.h      |   67 +
> .../Include/Protocol/VlvPlatformPolicy.h      |  105 +
> .../NorthCluster/Include/Valleyview.h         |   55 +
> .../NorthCluster/Include/VlvAccess.h          |  254 +
> .../Include/VlvCommonDefinitions.h            |  252 +
> .../SouthCluster/Include/Guid/PchInitVar.h    |   48 +
> .../Include/Guid/SataControllerGuid.h         |   34 +
> .../SouthCluster/Include/Guid/SmbusArpMap.h   |   30 +
> .../SouthCluster/Include/Guid/Vlv2Variable.h  |   28 +
> .../Include/IndustryStandard/CeAta.h          |  126 +
> .../Include/IndustryStandard/Mmc.h            |  349 ++
> .../Include/IndustryStandard/SdCard.h         |  157 +
> .../SouthCluster/Include/Library/I2CLib.h     |  169 +
> .../Include/Library/PchPlatformLib.h          |  115 +
> .../SouthCluster/Include/PchAccess.h          |  471 ++
> .../Include/PchCommonDefinitions.h            |  210 +
> .../SouthCluster/Include/PchRegs.h            |  205 +
> .../SouthCluster/Include/PchRegs/PchRegsHda.h |   50 +
> .../Include/PchRegs/PchRegsLpss.h             |  486 ++
> .../Include/PchRegs/PchRegsPcie.h             |   83 +
> .../SouthCluster/Include/PchRegs/PchRegsPcu.h | 1201 +++++
> .../Include/PchRegs/PchRegsRcrb.h             |   48 +
> .../Include/PchRegs/PchRegsSata.h             |  245 +
> .../SouthCluster/Include/PchRegs/PchRegsScc.h |   53 +
> .../Include/PchRegs/PchRegsSmbus.h            |  149 +
> .../SouthCluster/Include/PchRegs/PchRegsSpi.h |  119 +
> .../SouthCluster/Include/PchRegs/PchRegsUsb.h |   92 +
> .../SouthCluster/Include/Ppi/PchInit.h        |   75 +
> .../SouthCluster/Include/Ppi/PchPeiInit.h     |   34 +
> .../Include/Ppi/PchPlatformPolicy.h           |  161 +
> .../SouthCluster/Include/Ppi/PchUsbPolicy.h   |   69 +
> .../SouthCluster/Include/Ppi/PeiBlockIo.h     |  230 +
> .../SouthCluster/Include/Ppi/Sdhc.h           |  359 ++
> .../SouthCluster/Include/Ppi/SmbusPolicy.h    |   40 +
> .../SouthCluster/Include/Ppi/Spi.h            |   42 +
> .../Include/Protocol/ActiveBios.h             |  123 +
> .../Include/Protocol/ActiveBiosProtocol.h     |  125 +
> .../Protocol/DxePchPolicyUpdateProtocol.h     |   51 +
> .../Include/Protocol/EmmcCardInfoProtocol.h   |   42 +
> .../SouthCluster/Include/Protocol/Gpio.h      |  161 +
> .../Include/Protocol/HwWatchdogTimer.h        |  294 ++
> .../SouthCluster/Include/Protocol/I2cBus.h    |  164 +
> .../Include/Protocol/PchExtendedReset.h       |   84 +
> .../SouthCluster/Include/Protocol/PchInfo.h   |   60 +
> .../Include/Protocol/PchPlatformPolicy.h      |  550 ++
> .../SouthCluster/Include/Protocol/PchReset.h  |  114 +
> .../Include/Protocol/PchS3Support.h           |  132 +
> .../SouthCluster/Include/Protocol/SdHostIo.h  |  409 ++
> .../Include/Protocol/SmbiosSlotPopulation.h   |   47 +
> .../Include/Protocol/SmmIchnDispatchEx.h      |  159 +
> .../SouthCluster/Include/Protocol/SmmSmbus.h  |   39 +
> .../SouthCluster/Include/Protocol/Spi.h       |  260 +
> .../SouthCluster/Include/Protocol/TcoReset.h  |   88 +
> .../SouthCluster/Include/Rsci.h               |   28 +
> .../SouthCluster/Include/TianoApi.h           |   61 +
> .../Vlv2DeviceRefCodePkg.dec                  |  231 +
> .../Omap35xxPkg/Flash/Flash.c                 |  768 +++
> .../Omap35xxPkg/Flash/Flash.h                 |  100 +
> .../Omap35xxPkg/Flash/Flash.inf               |   42 +
> .../TexasInsturments/Omap35xxPkg/Gpio/Gpio.c  |  129 +
> .../Omap35xxPkg/Gpio/Gpio.inf                 |   39 +
> .../Omap35xxPkg/Include/Library/OmapDmaLib.h  |   84 +
> .../Omap35xxPkg/Include/Library/OmapLib.h     |   38 +
> .../Omap35xxPkg/Include/Omap3530/Omap3530.h   |   34 +
> .../Include/Omap3530/Omap3530Dma.h            |  124 +
> .../Include/Omap3530/Omap3530Gpio.h           |  125 +
> .../Include/Omap3530/Omap3530Gpmc.h           |  101 +
> .../Include/Omap3530/Omap3530I2c.h            |   56 +
> .../Include/Omap3530/Omap3530Interrupt.h      |   45 +
> .../Include/Omap3530/Omap3530MMCHS.h          |  208 +
> .../Omap3530/Omap3530PadConfiguration.h       |  297 ++
> .../Include/Omap3530/Omap3530Prcm.h           |  159 +
> .../Include/Omap3530/Omap3530Timer.h          |   76 +
> .../Include/Omap3530/Omap3530Uart.h           |   48 +
> .../Include/Omap3530/Omap3530Usb.h            |   42 +
> .../Omap35xxPkg/Include/TPS65950.h            |   74 +
> .../InterruptDxe/HardwareInterrupt.c          |  396 ++
> .../Omap35xxPkg/InterruptDxe/InterruptDxe.inf |   48 +
> .../LcdGraphicsOutputBlt.c                    |  439 ++
> .../LcdGraphicsOutputDxe.c                    |  394 ++
> .../LcdGraphicsOutputDxe.h                    |  151 +
> .../LcdGraphicsOutputDxe.inf                  |   46 +
> .../DebugAgentTimerLib/DebugAgentTimerLib.c   |  159 +
> .../DebugAgentTimerLib/DebugAgentTimerLib.inf |   42 +
> .../Library/GdbSerialLib/GdbSerialLib.c       |   96 +
> .../Library/GdbSerialLib/GdbSerialLib.inf     |   35 +
> .../Omap35xxTimerLib/Omap35xxTimerLib.inf     |   40 +
> .../Library/Omap35xxTimerLib/TimerLib.c       |  151 +
> .../Library/OmapDmaLib/OmapDmaLib.c           |  170 +
> .../Library/OmapDmaLib/OmapDmaLib.inf         |   43 +
> .../Omap35xxPkg/Library/OmapLib/OmapLib.c     |   77 +
> .../Omap35xxPkg/Library/OmapLib/OmapLib.inf   |   31 +
> .../RealTimeClockLib/RealTimeClockLib.c       |  291 ++
> .../RealTimeClockLib/RealTimeClockLib.inf     |   32 +
> .../Library/SerialPortLib/SerialPortLib.c     |  208 +
> .../Library/SerialPortLib/SerialPortLib.inf   |   40 +
> .../Omap35xxPkg/MMCHSDxe/MMCHS.c              | 1492 ++++++
> .../Omap35xxPkg/MMCHSDxe/MMCHS.h              |  169 +
> .../Omap35xxPkg/MMCHSDxe/MMCHS.inf            |   48 +
> .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.c       |  671 +++
> .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.h       |   38 +
> .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf     |   47 +
> .../Omap35xxPkg/Omap35xxPkg.dec               |   52 +
> .../Omap35xxPkg/Omap35xxPkg.dsc               |  183 +
> .../Omap35xxPkg/PciEmulation/PciEmulation.c   |  107 +
> .../Omap35xxPkg/PciEmulation/PciEmulation.inf |   41 +
> .../Omap35xxPkg/SmbusDxe/Smbus.c              |  319 ++
> .../Omap35xxPkg/SmbusDxe/Smbus.inf            |   39 +
> .../Omap35xxPkg/TPS65950Dxe/TPS65950.c        |  110 +
> .../Omap35xxPkg/TPS65950Dxe/TPS65950.inf      |   42 +
> .../Omap35xxPkg/TimerDxe/Timer.c              |  370 ++
> .../Omap35xxPkg/TimerDxe/TimerDxe.inf         |   51 +
> 1103 files changed, 259532 insertions(+)
> create mode 100644
>Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.c
> create mode 100644
>Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.inf
> create mode 100644
>Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.c
> create mode 100644
>Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.h
> create mode 100644
>Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThruDxe.inf
> create mode 100644
>Drivers/OptionRomPkg/AtapiPassThruDxe/ComponentName.c
> create mode 100644
>Drivers/OptionRomPkg/AtapiPassThruDxe/DriverSupportedEfiVersion.c
> create mode 100644
>Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/CompatibleDevices.txt
> create mode 100644
>Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ComponentName.c
> create mode 100644
>Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.c
> create mode 100644
>Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.h
> create mode 100644
>Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf
> create mode 100644
>Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt
> create mode 100644
>Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.c
> create mode 100644
>Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.h
> create mode 100644
>Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf
> create mode 100644
>Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/ComponentName
>.c
> create mode 100644
>Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/DriverBinding.c
> create mode 100644
>Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/SimpleNetwork.c
> create mode 100644
>Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c
> create mode 100644
>Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h
> create mode 100644
>Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
> create mode 100644
>Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/ComponentNam
>e.c
> create mode 100644
>Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/DriverBinding.c
> create mode 100644
>Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwork.
>c
> create mode 100644
>Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.c
> create mode 100644
>Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.h
> create mode 100644
>Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf
> create mode 100644
>Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430GraphicsOutput.c
> create mode 100644
>Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.c
> create mode 100644
>Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.h
> create mode 100644
>Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430UgaDraw.c
> create mode 100644
>Drivers/OptionRomPkg/CirrusLogic5430Dxe/ComponentName.c
> create mode 100644
>Drivers/OptionRomPkg/CirrusLogic5430Dxe/DriverSupportedEfiVersion.c
> create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/Edid.c
> create mode 100644 Drivers/OptionRomPkg/Include/Library/BltLib.h
> create mode 100644
>Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.c
> create mode 100644
>Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
> create mode 100644 Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.c
> create mode 100644 Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.inf
> create mode 100644 Drivers/OptionRomPkg/OptionRomPkg.dec
> create mode 100644 Drivers/OptionRomPkg/OptionRomPkg.dsc
> create mode 100644 Drivers/OptionRomPkg/ReadMe.txt
> create mode 100644
>Drivers/OptionRomPkg/UndiRuntimeDxe/ComponentName.c
> create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c
> create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c
> create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h
> create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c
> create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h
> create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c
> create mode 100644
>Drivers/OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.dec
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.dsc
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.fdf
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/ConfigurationHeader.bin
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/ConfigurationHeader.dat
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_boot_from_ra
>m.inc
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_convert_symb
>ols.sh
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_dummy.axf
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_hw_setup.inc
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_load_symbols.i
>nc
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_symbols_macr
>os.inc
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_unload_symbo
>ls.inc
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/trace32_load_sym
>bols.cmm
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/trace32_load_sym
>bols_cygwin.cmm
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Include/BeagleBoard.h
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoard.
>c
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoard
>Helper.S
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoard
>Helper.asm
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoard
>Lib.inf
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoard
>Mem.c
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/Clock.c
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/PadConfigura
>tion.c
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Library/DxeHobPeCoffLib/DxeHobPe
>Coff.c
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Library/DxeHobPeCoffLib/DxeHobPe
>CoffLib.inf
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Library/LzmaHobCustomDecompress
>Lib/LzmaHobCustomDecompressLib.c
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Library/LzmaHobCustomDecompress
>Lib/LzmaHobCustomDecompressLib.inf
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Library/MemoryInitPeiLib/MemoryIn
>itPeiLib.c
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Library/MemoryInitPeiLib/MemoryIn
>itPeiLib.inf
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Library/ResetSystemLib/ResetSyste
>mLib.c
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Library/ResetSystemLib/ResetSyste
>mLib.inf
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ArchPrePi.c
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ModuleEntryPoint.S
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ModuleEntryPoint.asm
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/PrePi/LzmaDecompress.h
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/PrePi/MainUniCore.c
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/PrePi/PeiUniCore.inf
> create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/PrePi/PrePi.c
> create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/PrePi/PrePi.h
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Tools/GNUmakefile
> create mode 100644
>Platform/BeagleBoard/BeagleBoardPkg/Tools/generate_image.c
> create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Tools/makefile
> create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Tools/replace.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/AcpiTables.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Cst/Cpu0Cst.asl
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Ist/Cpu0Ist.asl
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Tst/Cpu0Tst.asl
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/CpuPm/CpuPm.asl
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/AD7298.asi
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/ADC108S102.asi
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/CAT24C08.asi
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/CY8C9540A.asi
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/GpioClient.asi
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/LpcDev.asi
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PCA9685.asi
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PCAL9555A.asi
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PciHostBridge.asi
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PciIrq.asi
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PcieExpansionPrt.asi
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Platform.asl
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNC.asi
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNCApic.asi
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNCLpc.asi
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QuarkSouthCluster.a
>si
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Tpm.asi
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Facs/Facs.aslc
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Facs/Facs.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt1.0.aslc
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt2.0.aslc
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.aslc
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Mcfg/Mcfg.aslc
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Mcfg/Mcfg.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Madt.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/MadtPlatform.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/BootScri
>ptExecutorDxe.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/S3A
>sm.S
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/S3A
>sm.asm
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/Set
>IdtEntry.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/ScriptExe
>cute.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/ScriptExe
>cute.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatfor
>m.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatfor
>m.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatfor
>m.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/P
>pm.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/P
>pm.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/S
>mmPowerManagement.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/S
>mmPowerManagement.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/S
>mmPowerManagement.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Application/ForceRecovery/ForceRecovery
>.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Application/ForceRecovery/ForceRecovery
>.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAcc
>essLib/PlatformFlashAccessLibDxe.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAcc
>essLib/PlatformFlashAccessLibDxe.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAcc
>essLib/SpiFlashDevice.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAcc
>essLib/SpiFlashDevice.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareDescript
>or/SystemFirmwareDescriptor.aslc
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareDescript
>or/SystemFirmwareDescriptor.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareDescript
>or/SystemFirmwareDescriptorPei.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareUpdateC
>onfig/SystemFirmwareUpdateConfig.ini
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnDataCD.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatFloppyDisk.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatIdeDisk.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatUsbDisk.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Include/Guid/MemoryConfigData.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Include/Guid/QuarkCapsuleGuid.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Include/Guid/QuarkVariableLock.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Include/Guid/SystemNvDataHobGuid.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Include/Library/PlatformHelperLib.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Include/Library/PlatformPcieHelperLib.h
> create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Pcal9555.h
> create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Platform.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Include/PlatformBoards.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Include/Protocol/GlobalNvsArea.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Include/Protocol/PlatformSmmSpiReady.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/Platform
>BootManager.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/Platform
>BootManager.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/Platform
>BootManagerLib.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/Platform
>Data.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/CommonHeader
>.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/DxePlatformHel
>perLib.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PeiPlatformHelp
>erLib.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelper
>Dxe.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperL
>ib.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelper
>Pei.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformLeds.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/CommonHe
>ader.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPci
>eHelperLib.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPci
>eHelperLib.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/SocUnit.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Flat32.S
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Flat32.asm
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Platform.inc
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLibMod
>Strs.uni
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecure
>Lib.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecure
>Lib.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/TisPc.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12De
>viceLibAtmelI2c.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12De
>viceLibAtmelI2c.uni
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/TisPc.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/Tpm12
>DeviceLibInfineonI2c.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/Tpm12
>DeviceLibInfineonI2c.uni
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridgeSupp
>ort.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostResource.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridge.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridgeIo.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/CommonHeader.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemoryS
>ubClass.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemoryS
>ubClass.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemoryS
>ubClass.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemoryS
>ubClassStrings.uni
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformConfig.
>c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe
>.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe
>.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe
>.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveM
>emoryConfig.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveM
>emoryConfig.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/CommonHeader.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/DxePlatform.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/KeyboardLayout.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/QNCRegTable.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/Strings.uni
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/processor.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/CommonHe
>ader.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBo
>ardManufacturer.uni
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBo
>ardManufacturerData.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBo
>ardManufacturerFunction.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVe
>ndor.uni
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVe
>ndorData.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVe
>ndorFunction.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootInf
>ormationData.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootInf
>ormationFunction.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassis
>Manufacturer.uni
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassis
>ManufacturerData.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassis
>ManufacturerFunction.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscDevice
>Path.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumbe
>rOfInstallableLanguagesData.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumbe
>rOfInstallableLanguagesFunction.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemSt
>ring.uni
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemSt
>ringData.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemSt
>ringFunction.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboar
>dDevice.uni
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboar
>dDeviceData.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboar
>dDeviceFunction.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInt
>ernalConnectorDesignator.uni
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInt
>ernalConnectorDesignatorData.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInt
>ernalConnectorDesignatorFunction.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystem
>Manufacturer.uni
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystem
>ManufacturerData.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystem
>ManufacturerFunction.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystem
>OptionString.uni
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystem
>OptionStringData.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystem
>OptionStringFunction.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystem
>SlotDesignation.uni
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystem
>SlotDesignationData.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystem
>SlotDesignationFunction.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystem
>SlotOnboardDevices.uni
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMisc
>.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMisc
>DataTable.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMisc
>Dxe.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMisc
>EntryPoint.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMisc
>Strings.uni
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConf
>igPei.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConf
>igPei.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/BootMode.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/CommonHeader
>.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/Generic/Recove
>ry.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MemoryCallback
>.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit
>.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit
>.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit
>.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformErratas.
>c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FvbInfo.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.h
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.
>c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.i
>nf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSpi.inf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.c
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.h
> create mode 100644 Platform/Intel/QuarkPlatformPkg/Quark.dsc
> create mode 100644 Platform/Intel/QuarkPlatformPkg/Quark.fdf
> create mode 100644 Platform/Intel/QuarkPlatformPkg/QuarkMin.dsc
> create mode 100644 Platform/Intel/QuarkPlatformPkg/QuarkMin.fdf
> create mode 100644
>Platform/Intel/QuarkPlatformPkg/QuarkPlatformPkg.dec
> create mode 100644 Platform/Intel/QuarkPlatformPkg/Readme.md
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/.gitignore
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooksLib.h
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUp
>date.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUp
>date.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUp
>date.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUp
>dateStrings.uni
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64D.env
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64R.env
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/BootScriptSaveDxe.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/InternalBootScriptSave
>.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/ScriptSave.c
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.bat
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.sh
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FCE.exe
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCa
>psuleAll.bat
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCa
>psuleAll.sh
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCa
>psuleMinnowMax.bat
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCa
>psuleMinnowMax.sh
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCa
>psuleMinnowMaxRelease.bat
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCa
>psuleMinnowMaxRelease.sh
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCa
>psuleSampleColor.bat
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCa
>psuleSampleColor.sh
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Lvfs.dd
>f
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGe
>nCapsuleMinnowMax.bat
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGe
>nCapsuleMinnowMaxRelease.bat
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGe
>nCapsuleSampleColor.bat
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/NewR
>oot.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.i
>nc
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMPL
>E_DEVELOPMENT.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7C
>ertBufferXdr.inc
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMPL
>E_DEVELOPMENT_SAMPLE_PRODUCTION.cer.gFmpDevicePkgTokenSpaceGu
>id.PcdFmpDevicePkcs7CertBufferXdr.inc
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/templa
>te.metainfo.xml
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/Fm
>pDeviceLib.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/Fm
>pDeviceLib.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSa
>mple/FmpDeviceLib.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSa
>mple/FmpDeviceLib.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAcc
>essLib/PlatformFlashAccessLib.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAcc
>essLib/PlatformFlashAccessLib.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescript
>or/SystemFirmwareDescriptor.aslc
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescript
>or/SystemFirmwareDescriptor.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescript
>or/SystemFirmwareDescriptorPei.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdateC
>onfig/SystemFirmwareUpdateConfig.ini
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdateC
>onfig/SystemFirmwareUpdateConfigGcc.ini
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FmpCertificate.dsc
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FmpGreenSampleDevice.dsc
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FspAzaliaConfigData/AzaliaConfig.bin
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.i
>nf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLibVl
>v2/FspHobProcessLibVlv2.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLibVl
>v2/FspHobProcessLibVlv2.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibV
>lv2/FspPlatformSecLibVlv2.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibV
>lv2/FspPlatformSecLibVlv2.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibV
>lv2/Ia32/AsmSaveSecContext.asm
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibV
>lv2/Ia32/Fsp.inc
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibV
>lv2/Ia32/PeiCoreEntry.asm
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibV
>lv2/Ia32/SecEntry.asm
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibV
>lv2/Ia32/Stack.S
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibV
>lv2/Ia32/Stack.asm
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibV
>lv2/PlatformInit.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibV
>lv2/SaveSecContext.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibV
>lv2/SecGetPerformance.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibV
>lv2/SecPlatformInformation.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibV
>lv2/SecRamInitData.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibV
>lv2/SecTempRamSupport.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibV
>lv2/UartInit.c
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbRuntimeDxe.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceDxe.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceSmm.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmm.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmCommon.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.inf
> create mode 100755 Platform/Intel/Vlv2TbltDevicePkg/GenBiosId
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/GenBiosId.exe
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/AlertStandardFormatTable.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/ChipsetAccess.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/CommonIncludes.h
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/CpuType.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/FileHandleLib.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AcpiTableStorage.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AlertStandardFormat.h
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BiosId.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BoardFeatures.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/EfiVpdData.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/FirmwareId.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/HwWatchdogTimerHob.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/IdccData.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/ItkData.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/MemoryConfigData.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/OsSelection.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PciLanInfo.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformCpuInfo.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformInfo.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SensorInfoVariable.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SetupVariable.h
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Hpet.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Library/BiosIdLib.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Library/CpuIA32.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Library/EfiRegTableLib.h
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Esrt.h
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Fd.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Library/FlashDeviceLib.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2CLib.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cMmioConfigLib.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cPort_platform.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFsaLib.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFspLib.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Library/SpiFlash.H
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Library/StallSmmLib.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Library/UsbDeviceModeLib.h
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Mcfg.h
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/McfgTable.h
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Platform.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformBootMode.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformDefinitions.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/MfgMemoryTest.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Sha256Hash.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Speaker.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/UsbController.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/CK505ClockPlatformInfo.
>h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/EnhancedSpeedstep.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/GlobalNvsArea.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/HwWatchdogTimer.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cAcpi.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBus.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBusMcg.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cHostMcg.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cMasterMcg.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cSlave.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpc83627Policy.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpce791Policy.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/MmioDevice.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Observable.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformGopPolicy.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformIdeInit.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SetupMode.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SmbiosSlotPopulation.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Speaker.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TcoReset.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TpmMp.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/UsbPolicy.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/VlvPlatformPolicy.h
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/SetupMode.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/IntelGopDepex/IntelGopDriver.depex
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/CpuIA32Lib.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/EfiCpuVersion.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.S
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.asm
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.S
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.asm
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxe.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxe.i
>nf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxeR
>untimeSmm.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/SpiChipDefinitions.h
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLibNull.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLib.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLibDxe.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CRegs.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CAccess.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/CommonHea
>der.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpiT
>imerLib.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpiT
>imerLib.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens/Bo
>ardClkGens.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens/Bo
>ardClkGens.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/Boar
>dGpios.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/Boar
>dGpios.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers/Bo
>ardJumpers.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers/Bo
>ardJumpers.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/Bo
>ardOemIds.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/Bo
>ardOemIds.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid/Bo
>ardSsidSvid.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid/Bo
>ardSsidSvid.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib.
>c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib.
>h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib.i
>nf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/PlatformInfoHob.
>c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLib.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibrary.
>c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibrary.
>h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/CommonHeader.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsLib.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsStrings.
>uni
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformData.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmosLib.
>c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmosLib.
>inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLib.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLib.in
>f
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/PlatformSerialPortLib.
>h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/CommonHeader.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmm.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmmLib.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2Devic
>eLibSeC.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2Devic
>eLibSeC.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2Device
>LibSeC.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2Device
>LibSeC.inf
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Logo/Logo.bmp
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Metronome/Metronome.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/EfiStatusCode.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PeiPostCode.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libra
>ry/GenericBdsLib/BdsBoot.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libra
>ry/GenericBdsLib/BdsConnect.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libra
>ry/GenericBdsLib/BdsConsole.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libra
>ry/GenericBdsLib/BdsMisc.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libra
>ry/GenericBdsLib/DevicePath.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libra
>ry/GenericBdsLib/GenericBdsLib.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libra
>ry/GenericBdsLib/GenericBdsLib.uni
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libra
>ry/GenericBdsLib/GenericBdsStrings.uni
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libra
>ry/GenericBdsLib/InternalBdsLib.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libra
>ry/GenericBdsLib/String.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libra
>ry/GenericBdsLib/String.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/BoardPciPlatform.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.inf
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.dsc
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.fdf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe.
>c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe.
>h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe.i
>nf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/AzaliaVerbTable.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardId.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ClockControl.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Configuration.h
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchPlatformPolicy.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchRegTable.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchTcoReset.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.h
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciBus.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Platform.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.inf
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SioPlatformPolicy.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/BootMode.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/CpuInitPeim.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/FlashMap.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MchInit.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryCallback.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryPeim.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PchInitPeim.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInfoInit.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInitPei.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformSsaInitPeim.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Recovery.c
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Stall.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/BootMode.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/CommonHeader.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/MemoryCallback.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/PlatformPei.inf
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Stall.c
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.dec
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgConfig.dsc
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGcc.fdf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgIA32.dsc
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgX64.dsc
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Boot.vfi
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Configuration.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/DebugConfig.vfi
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/FwVersionStrings.uni
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Main.vfi
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Security.vfi
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupFunctions.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupInfoRecords.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SouthClusterConfig.vfi
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SystemComponent.vfi
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Thermal.vfi
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UnCore.vfi
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UqiList.uni
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Vfr.vfr
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/VfrStrings.uni
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/Platform.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/PlatformSmm.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/S3Save.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmPlatform.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Readme.md
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.in
>f
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/CommonHeader.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufactu
>rer.uni
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufactu
>rerData.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufactu
>rerFunction.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendor.uni
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorData.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorFunction.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationData.
>c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationFunc
>tion.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturer.
>uni
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturer
>Data.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturer
>Function.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDevice.uni
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceData.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceFuncti
>on.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstallableL
>anguagesData.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstallableL
>anguagesFunction.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemString.uni
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringData.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringFunction.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90.uni
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Data.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Functio
>n.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94.uni
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Data.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Functio
>n.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDevice.uni
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceData.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceFuncti
>on.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArray.uni
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayData.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayFunction
>.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnecto
>rDesignator.uni
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnecto
>rDesignatorData.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnecto
>rDesignatorFunction.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCache.uni
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheData.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheFuncti
>on.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformation
>.uni
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformation
>Data.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformation
>Function.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesData
>.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesFunc
>tion.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.uni
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverDataTa
>ble.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverEntryP
>oint.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageStrin
>g.uni
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageStrin
>gData.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageStrin
>gFunction.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacturer.
>uni
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacturer
>Data.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacturer
>Function.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionString.u
>ni
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStringD
>ata.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStringF
>unction.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignatio
>n.uni
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignatio
>nData.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignatio
>nFunction.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/SmBiosMiscDxe.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchThunk
>/SmmSwDispatch2OnSmmSwDispatchThunk.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchThunk
>/SmmSwDispatch2OnSmmSwDispatchThunk.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSaveI
>nfoHandlerSmm.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSaveI
>nfoHandlerSmm.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwSpare.bin
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwWorking.bin
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageVariable.bin
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_HEADER.bin
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_HEADER_SPILOCK
>.bin
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/Vacant.bin
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Stitch/MNW2_Stitch_Config.txt
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInitDxe.inf
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.c
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.h
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h
> create mode 100644
>Platform/Intel/Vlv2TbltDevicePkg/Wpce791/Wpce791.inf
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh
> create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/cln.sh
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/DdrMemoryController
>.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCBase.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCConfig.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCDxe.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCPeim.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCRegs.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/IntelQNCLib.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/QNCAccessLib.
>h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/QNCSmmLib.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Ppi/QNCMemoryInit.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/PchInfo.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/PlatformPolic
>y.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/QncS3Suppor
>t.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/SmmIchnDis
>patch2.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/Spi.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QNCAccess.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QNCCommonDefinitio
>ns.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QuarkNcSocId.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/Common
>Header.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNCL
>ib.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNCL
>ib.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/PciExpress
>.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.uni
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/BaseAcc
>ess.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/QNCAcc
>essLib.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/QNCAcc
>essLib.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/Runtim
>eAccess.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/Runtim
>eQNCAccessLib.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCSmmLib/QNCSmm
>Lib.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCSmmLib/QNCSmm
>Lib.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/Reset
>SystemLib.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/Reset
>SystemLib.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/CommonHe
>ader.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/SmbusLib.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/SmbusLib.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/S
>mmCpuFeaturesLib.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/S
>mmCpuFeaturesLib.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/S
>mmCpuFeaturesLib.uni
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInit.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInit.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInitP
>ei.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/core_types.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/gen5_iosf_sb
>_definitions.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/general_defin
>itions.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/hte.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/hte.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/io.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/lprint.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit_utils
>.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit_utils
>.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/memory_opti
>ons.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/mrc.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/mrc.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/platform.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/prememinit.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/prememinit.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/CommonHeader.
>h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInitDxe.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCRootPorts.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbus.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbusExec.
>c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.
>c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.
>h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.
>inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/Sm
>mAccess.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/Sm
>mAccessDriver.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/Sm
>mAccessDriver.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmControlDxe/S
>mmControlDriver.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmControlDxe/S
>mmControlDxe.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
>tcher/CommonHeader.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
>tcher/QNC/QNCSmmGpi.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
>tcher/QNC/QNCSmmHelpers.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
>tcher/QNC/QNCSmmPeriodicTimer.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
>tcher/QNC/QNCSmmQncn.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
>tcher/QNC/QNCSmmSw.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
>tcher/QNC/QNCSmmSx.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
>tcher/QNCSmm.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
>tcher/QNCSmmCore.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
>tcher/QNCSmmDispatcher.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
>tcher/QNCSmmHelpers.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
>tcher/QNCSmmHelpers.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
>tcher/QNCSmmRegisters.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
>tcher/QNCxSmmHelpers.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmAccessPei/Smm
>AccessPei.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmAccessPei/Smm
>AccessPei.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/Sm
>mControlPei.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/Sm
>mControlPei.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Common/SpiCommon.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Common/SpiCommon.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiRuntime.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiSmm.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchSpi.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchSpi.h
> create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dec
> create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dsc
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/CEATA.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/I2cRegs.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Ioh.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/IohAccess.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/IohCommonDefinition
>s.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Library/I2cLib.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Library/IohLib.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/MMC.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/SDCard.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/SDHostIo.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/CommonHeader.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohBds.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohData.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohInit.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohInitDxe.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/CommonHeader
>.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/I2cLib.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/I2cLib.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/CommonHeade
>r.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/IohLib.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/IohLib.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/Co
>mponentName.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/Co
>mponentName.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SD
>Controller.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SD
>Controller.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SD
>ControllerDxe.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/
>CEATA.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/
>CEATABlockIo.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/
>ComponentName.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/
>ComponentName.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/
>MMCSDBlockIo.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/
>MMCSDTransfer.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/
>SDMediaDevice.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/
>SDMediaDevice.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/
>SDMediaDeviceDxe.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/ComponentNa
>me.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/ComponentNa
>me.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Descriptor.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDebug.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDebug.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDxe.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciSched.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciSched.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/Descriptor.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciPei.inf
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciSched.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciSched.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.h
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.c
> create mode 100644
>Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/98_LINK.ASL
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTablePlatform.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTables.inf
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/CPU.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/DSDT.ASL
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facp/Facp.aslc
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facs/Facs.aslc
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/GloblNvs.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Gpe.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/HOST_BUS.ASL
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Hpet/Hpet.aslc
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELGFX.ASL
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELISPDev2.ASL
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOGBDA.ASL
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOMOBF.ASL
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOSBCB.ASL
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOpRn.ASL
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IoTVirtualDevice.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LPC_DEV.ASL
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LpcB.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Lpit/Lpit.aslc
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt30.aslc
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Mcfg/Mcfg.aslc
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PCI_DRC.ASL
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Pch.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchAudio.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchEhci.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchLpss.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchPcie.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchScc.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchSmb.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchXhci.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PciTree.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Platform.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RTD3.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RhProxy.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/THERMAL.ASL
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/UsbSbd.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Video.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Vlv.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Wsmt/Wsmt.aslc
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/token.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Guid/Vlv2DeviceRefCodePkgTok
>enSpace.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/PttPassThruPpi.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/fTPMPolicy.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Protocol/PttPassThru.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Guid/Pow
>erManagementAcpiTableStorage.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Ppi/VlvPol
>icy.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Protocol/P
>pmPlatformPolicy.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Types.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
>nt/AcpiTables/PowerManagementAcpiTables.inf
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
>nt/AcpiTables/Ssdt/ApCst.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
>nt/AcpiTables/Ssdt/ApIst.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
>nt/AcpiTables/Ssdt/ApTst.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
>nt/AcpiTables/Ssdt/Cpu0Cst.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
>nt/AcpiTables/Ssdt/Cpu0Ist.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
>nt/AcpiTables/Ssdt/Cpu0Tst.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
>nt/AcpiTables/Ssdt/CpuPm.asl
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Pl
>atformBaseAddresses.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/P
>pi/Capsule.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/P
>pi/PlatformMemoryRange.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/P
>pi/PlatformMemorySize.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/P
>pi/SmmAccess.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/P
>pi/VlvMmioPolicy.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/P
>pi/VlvPeiInit.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/P
>pi/VlvPolicy.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/P
>rotocol/IgdOpRegion.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/P
>rotocol/MemInfo.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/P
>rotocol/PlatformGopPolicy.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/P
>rotocol/VlvPlatformPolicy.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/V
>alleyview.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Vl
>vAccess.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/Vl
>vCommonDefinitions.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/G
>uid/PchInitVar.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/G
>uid/SataControllerGuid.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/G
>uid/SmbusArpMap.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/G
>uid/Vlv2Variable.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/In
>dustryStandard/CeAta.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/In
>dustryStandard/Mmc.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/In
>dustryStandard/SdCard.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Li
>brary/I2CLib.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Li
>brary/PchPlatformLib.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>chAccess.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>chCommonDefinitions.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>chRegs.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>chRegs/PchRegsHda.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>chRegs/PchRegsLpss.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>chRegs/PchRegsPcie.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>chRegs/PchRegsPcu.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>chRegs/PchRegsRcrb.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>chRegs/PchRegsSata.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>chRegs/PchRegsScc.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>chRegs/PchRegsSmbus.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>chRegs/PchRegsSpi.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>chRegs/PchRegsUsb.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>pi/PchInit.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>pi/PchPeiInit.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>pi/PchPlatformPolicy.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>pi/PchUsbPolicy.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>pi/PeiBlockIo.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>pi/Sdhc.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>pi/SmbusPolicy.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>pi/Spi.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>rotocol/ActiveBios.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>rotocol/ActiveBiosProtocol.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>rotocol/DxePchPolicyUpdateProtocol.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>rotocol/EmmcCardInfoProtocol.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>rotocol/Gpio.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>rotocol/HwWatchdogTimer.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>rotocol/I2cBus.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>rotocol/PchExtendedReset.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>rotocol/PchInfo.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>rotocol/PchPlatformPolicy.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>rotocol/PchReset.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>rotocol/PchS3Support.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>rotocol/SdHostIo.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>rotocol/SmbiosSlotPopulation.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>rotocol/SmmIchnDispatchEx.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>rotocol/SmmSmbus.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>rotocol/Spi.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
>rotocol/TcoReset.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/R
>sci.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Ti
>anoApi.h
> create mode 100644
>Silicon/Intel/Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.c
> create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.h
> create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.inf
> create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.c
> create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.inf
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapDmaLib.h
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapLib.h
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530.h
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Dma.
>h
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpio.
>h
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpmc
>.h
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530I2c.h
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Interr
>upt.h
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530MMC
>HS.h
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530PadC
>onfiguration.h
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Prcm.
>h
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Timer
>.h
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Uart.
>h
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Usb.h
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Include/TPS65950.h
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/HardwareInterrupt.c
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/InterruptDxe.inf
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphics
>OutputBlt.c
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphics
>OutputDxe.c
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphics
>OutputDxe.h
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphics
>OutputDxe.inf
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/Debug
>AgentTimerLib.c
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/Debug
>AgentTimerLib.inf
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.c
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.in
>f
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/Omap35
>xxTimerLib.inf
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/TimerLib
>.c
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.
>c
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.
>inf
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.c
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.inf
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTimeC
>lockLib.c
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTimeC
>lockLib.inf
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.c
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.in
>f
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.c
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.h
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.inf
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.c
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.h
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dec
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dsc
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.c
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.inf
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.c
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.inf
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.c
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.inf
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/Timer.c
> create mode 100644
>Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/TimerDxe.inf
>
>--
>2.21.0.windows.1
>
>
>


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [edk2-devel] [edk2-platforms: Patch 0/8] Add packages from edk2
  2019-05-10  5:14 ` [edk2-devel] [edk2-platforms: Patch 0/8] Add packages from edk2 Liming Gao
@ 2019-05-10  6:17   ` Michael D Kinney
  2019-05-10  7:32     ` Liming Gao
  0 siblings, 1 reply; 23+ messages in thread
From: Michael D Kinney @ 2019-05-10  6:17 UTC (permalink / raw)
  To: Gao, Liming, devel@edk2.groups.io, Kinney, Michael D
  Cc: Sun, Zailiang, Qian, Yi, Steele, Kelly, Ni, Ray,
	Kubacki, Michael A, Leif Lindholm, Ard Biesheuvel

Liming,

I will update license in edk2-plaforms after this patch is checked in.

Yes.  The plan is to catch the stable tag.

Mike

> -----Original Message-----
> From: Gao, Liming
> Sent: Thursday, May 9, 2019 10:15 PM
> To: devel@edk2.groups.io; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Cc: Sun, Zailiang <zailiang.sun@intel.com>; Qian, Yi
> <yi.qian@intel.com>; Steele, Kelly
> <kelly.steele@intel.com>; Ni, Ray <ray.ni@intel.com>;
> Kubacki, Michael A <michael.a.kubacki@intel.com>; Leif
> Lindholm <leif.lindholm@linaro.org>; Ard Biesheuvel
> <ard.biesheuvel@linaro.org>
> Subject: RE: [edk2-devel] [edk2-platforms: Patch 0/8] Add
> packages from edk2
> 
> Mike:
>   I have two questions here.
> 1. Those module in edk2 has BSD + Patent License. But,
> edk2 platform code uses BSD license. That means the codes
> in edk2 platform will have the mix license. What's the
> plan to update edk2 platform code license to BSD +
> Patent?
> 2. What's plan for this change? This change impacts edk2
> project. Does it catch edk2 stable tag?
> 
> Thanks
> Liming
> >-----Original Message-----
> >From: devel@edk2.groups.io [mailto:devel@edk2.groups.io]
> On Behalf Of
> >Michael D Kinney
> >Sent: Friday, May 10, 2019 11:34 AM
> >To: devel@edk2.groups.io
> >Cc: Sun, Zailiang <zailiang.sun@intel.com>; Qian, Yi
> <yi.qian@intel.com>;
> >Steele, Kelly <kelly.steele@intel.com>; Ni, Ray
> <ray.ni@intel.com>; Kubacki,
> >Michael A <michael.a.kubacki@intel.com>; Leif Lindholm
> ><leif.lindholm@linaro.org>; Ard Biesheuvel
> <ard.biesheuvel@linaro.org>
> >Subject: [edk2-devel] [edk2-platforms: Patch 0/8] Add
> packages from edk2
> >
> >https://bugzilla.tianocore.org/show_bug.cgi?id=1467
> >https://bugzilla.tianocore.org/show_bug.cgi?id=1374
> >https://bugzilla.tianocore.org/show_bug.cgi?id=1793
> >
> >Add the following platform, silicon, and driver packages
> from the edk2 repo
> >to the edk2-platforms repo
> >* Drivers/OptionRomPkg
> >* Platform/BeagleBoard/BeagleBoardPkg
> >* Platform/Intel/QuarkPlatformPkg
> >* Platform/Intel/Vlv2TbltDevicePkg
> >* Silicon/Intel/QuarkSocPkg
> >* Silicon/Intel/Vlv2DeviceRefCodePkg
> >* Silicon/TexasInsturments/Omap35xxPkg
> >
> >Cc: Zailiang Sun <zailiang.sun@intel.com>
> >Cc: Yi Qian <yi.qian@intel.com>
> >Cc: Kelly Steele <kelly.steele@intel.com>
> >Cc: Ray Ni <ray.ni@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>
> >
> >Michael D Kinney (8):
> >  Silicon/TexasInsturments: Import Omap35xxPkg from edk2
> >  Platform/BeagleBoard: Import BeagleBoardPkg from edk2
> >  Silicon/Intel: Import QuarkSocPkg from edk2
> >  Platform/QuarkPlatformPkg: Import QuarkPlatformPkg
> from edk2
> >  Platform/Vlv2DeviceRefCodePkg: Import
> Vlv2DeviceRefCodePkg from edk2
> >  Platform/Vlv2TbltDevicePkg: Import Vlv2TbltDevicePkg
> from edk2
> >  Drivers/OptionRomPkg: Import OptionRomPkg from edk2
> >  edk2-platforms: Update Maintainers.txt/Readme.md for
> imported packages
> >
> > .../Application/BltLibSample/BltLibSample.c   |  279 +
> > .../Application/BltLibSample/BltLibSample.inf |   30 +
> > .../AtapiPassThruDxe/AtapiPassThru.c          | 3410
> +++++++++++++
> > .../AtapiPassThruDxe/AtapiPassThru.h          | 1618
> ++++++
> > .../AtapiPassThruDxe/AtapiPassThruDxe.inf     |   70 +
> > .../AtapiPassThruDxe/ComponentName.c          |  169 +
> > .../DriverSupportedEfiVersion.c               |   14 +
> > .../FtdiUsbSerialDxe/CompatibleDevices.txt    |    5 +
> > .../Bus/Usb/FtdiUsbSerialDxe/ComponentName.c  |  218 +
> > .../FtdiUsbSerialDxe/FtdiUsbSerialDriver.c    | 2580
> ++++++++++
> > .../FtdiUsbSerialDxe/FtdiUsbSerialDriver.h    |  589
> +++
> > .../Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf |   55 +
> > .../Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt       |   32 +
> > .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.c   | 1318
> +++++
> > .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.h   |  969
> ++++
> > .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf |   61 +
> > .../Usb/UsbNetworking/Ax88772/ComponentName.c |  178 +
> > .../Usb/UsbNetworking/Ax88772/DriverBinding.c |  507 ++
> > .../Usb/UsbNetworking/Ax88772/SimpleNetwork.c | 1503
> ++++++
> > .../Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c  |  875
> ++++
> > .../Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h  | 1026
> ++++
> > .../Usb/UsbNetworking/Ax88772b/Ax88772b.inf   |   61 +
> > .../UsbNetworking/Ax88772b/ComponentName.c    |  175 +
> > .../UsbNetworking/Ax88772b/DriverBinding.c    |  696
> +++
> > .../UsbNetworking/Ax88772b/SimpleNetwork.c    | 1657
> ++++++
> > .../CirrusLogic5430Dxe/CirrusLogic5430.c      |  917
> ++++
> > .../CirrusLogic5430Dxe/CirrusLogic5430.h      |  432 ++
> > .../CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf |   84 +
> > .../CirrusLogic5430GraphicsOutput.c           |  556 ++
> > .../CirrusLogic5430Dxe/CirrusLogic5430I2c.c   |  427 ++
> > .../CirrusLogic5430Dxe/CirrusLogic5430I2c.h   |   62 +
> > .../CirrusLogic5430UgaDraw.c                  |  412 ++
> > .../CirrusLogic5430Dxe/ComponentName.c        |  203 +
> > .../DriverSupportedEfiVersion.c               |   14 +
> > .../OptionRomPkg/CirrusLogic5430Dxe/Edid.c    |  525 ++
> > Drivers/OptionRomPkg/Include/Library/BltLib.h |  253 +
> > .../FrameBufferBltLib/FrameBufferBltLib.c     |  744
> +++
> > .../FrameBufferBltLib/FrameBufferBltLib.inf   |   29 +
> > .../Library/GopBltLib/GopBltLib.c             |  449 ++
> > .../Library/GopBltLib/GopBltLib.inf           |   31 +
> > Drivers/OptionRomPkg/OptionRomPkg.dec         |   41 +
> > Drivers/OptionRomPkg/OptionRomPkg.dsc         |  113 +
> > Drivers/OptionRomPkg/ReadMe.txt               |   17 +
> > .../UndiRuntimeDxe/ComponentName.c            |  359 ++
> > Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c  | 1516
> ++++++
> > Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c   | 3541
> +++++++++++++
> > Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h   |  665
> +++
> > Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c    | 1051
> ++++
> > Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h  |  439 ++
> > .../OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c |  145 +
> > .../UndiRuntimeDxe/UndiRuntimeDxe.inf         |   72 +
> > Maintainers.txt                               |   20 +
> > .../BeagleBoardPkg/BeagleBoardPkg.dec         |   30 +
> > .../BeagleBoardPkg/BeagleBoardPkg.dsc         |  496 ++
> > .../BeagleBoardPkg/BeagleBoardPkg.fdf         |  308 ++
> > .../BeagleBoardPkg/ConfigurationHeader.bin    |  Bin 0
> -> 512 bytes
> > .../BeagleBoardPkg/ConfigurationHeader.dat    |   41 +
> > .../Debugger_scripts/rvi_boot_from_ram.inc    |   15 +
> > .../Debugger_scripts/rvi_convert_symbols.sh   |   17 +
> > .../Debugger_scripts/rvi_dummy.axf            |  Bin 0
> -> 7984 bytes
> > .../Debugger_scripts/rvi_hw_setup.inc         |   61 +
> > .../Debugger_scripts/rvi_load_symbols.inc     |   17 +
> > .../Debugger_scripts/rvi_symbols_macros.inc   |  188 +
> > .../Debugger_scripts/rvi_unload_symbols.inc   |  112 +
> > .../Debugger_scripts/trace32_load_symbols.cmm |  205 +
> > .../trace32_load_symbols_cygwin.cmm           |  182 +
> > .../BeagleBoardPkg/Include/BeagleBoard.h      |  173 +
> > .../Library/BeagleBoardLib/BeagleBoard.c      |  115 +
> > .../BeagleBoardLib/BeagleBoardHelper.S        |   41 +
> > .../BeagleBoardLib/BeagleBoardHelper.asm      |   47 +
> > .../Library/BeagleBoardLib/BeagleBoardLib.inf |   48 +
> > .../Library/BeagleBoardLib/BeagleBoardMem.c   |   74 +
> > .../Library/BeagleBoardLib/Clock.c            |   63 +
> > .../Library/BeagleBoardLib/PadConfiguration.c |  316 ++
> > .../Library/DxeHobPeCoffLib/DxeHobPeCoff.c    |  282 ++
> > .../DxeHobPeCoffLib/DxeHobPeCoffLib.inf       |   39 +
> > .../LzmaHobCustomDecompressLib.c              |   44 +
> > .../LzmaHobCustomDecompressLib.inf            |   45 +
> > .../MemoryInitPeiLib/MemoryInitPeiLib.c       |  192 +
> > .../MemoryInitPeiLib/MemoryInitPeiLib.inf     |   58 +
> > .../Library/ResetSystemLib/ResetSystemLib.c   |  149 +
> > .../Library/ResetSystemLib/ResetSystemLib.inf |   37 +
> > .../BeagleBoardPkg/PrePi/Arm/ArchPrePi.c      |   23 +
> > .../PrePi/Arm/ModuleEntryPoint.S              |  124 +
> > .../PrePi/Arm/ModuleEntryPoint.asm            |  142 +
> > .../BeagleBoardPkg/PrePi/LzmaDecompress.h     |   97 +
> > .../BeagleBoardPkg/PrePi/MainUniCore.c        |   33 +
> > .../BeagleBoardPkg/PrePi/PeiUniCore.inf       |   97 +
> > .../BeagleBoard/BeagleBoardPkg/PrePi/PrePi.c  |  179 +
> > .../BeagleBoard/BeagleBoardPkg/PrePi/PrePi.h  |   90 +
> > .../BeagleBoardPkg/Tools/GNUmakefile          |   14 +
> > .../BeagleBoardPkg/Tools/generate_image.c     |  402 ++
> > .../BeagleBoard/BeagleBoardPkg/Tools/makefile |   16 +
> > .../BeagleBoardPkg/Tools/replace.c            |  140 +
> > .../Acpi/AcpiTables/AcpiTables.inf            |   42 +
> > .../Acpi/AcpiTables/Cpu0Cst/Cpu0Cst.asl       |  399 ++
> > .../Acpi/AcpiTables/Cpu0Ist/Cpu0Ist.asl       |  159 +
> > .../Acpi/AcpiTables/Cpu0Tst/Cpu0Tst.asl       |  133 +
> > .../Acpi/AcpiTables/CpuPm/CpuPm.asl           |   73 +
> > .../Acpi/AcpiTables/Dsdt/AD7298.asi           |   38 +
> > .../Acpi/AcpiTables/Dsdt/ADC108S102.asi       |   33 +
> > .../Acpi/AcpiTables/Dsdt/CAT24C08.asi         |   34 +
> > .../Acpi/AcpiTables/Dsdt/CY8C9540A.asi        |   47 +
> > .../Acpi/AcpiTables/Dsdt/GpioClient.asi       |   89 +
> > .../Acpi/AcpiTables/Dsdt/LpcDev.asi           |  248 +
> > .../Acpi/AcpiTables/Dsdt/PCA9685.asi          |   34 +
> > .../Acpi/AcpiTables/Dsdt/PCAL9555A.asi        |   90 +
> > .../Acpi/AcpiTables/Dsdt/PciHostBridge.asi    |  195 +
> > .../Acpi/AcpiTables/Dsdt/PciIrq.asi           |  552 ++
> > .../Acpi/AcpiTables/Dsdt/PcieExpansionPrt.asi |  127 +
> > .../Acpi/AcpiTables/Dsdt/Platform.asl         |  347 ++
> > .../Acpi/AcpiTables/Dsdt/QNC.asi              |   49 +
> > .../Acpi/AcpiTables/Dsdt/QNCApic.asi          |   32 +
> > .../Acpi/AcpiTables/Dsdt/QNCLpc.asi           |   23 +
> > .../AcpiTables/Dsdt/QuarkSouthCluster.asi     |  110 +
> > .../Acpi/AcpiTables/Dsdt/Tpm.asi              |   45 +
> > .../Acpi/AcpiTables/Facs/Facs.aslc            |   74 +
> > .../Acpi/AcpiTables/Facs/Facs.h               |   29 +
> > .../Acpi/AcpiTables/Fadt/Fadt.h               |  102 +
> > .../Acpi/AcpiTables/Fadt/Fadt1.0.aslc         |   76 +
> > .../Acpi/AcpiTables/Fadt/Fadt2.0.aslc         |  157 +
> > .../Acpi/AcpiTables/Hpet/Hpet.aslc            |   68 +
> > .../Acpi/AcpiTables/Hpet/Hpet.h               |   45 +
> > .../Acpi/AcpiTables/Mcfg/Mcfg.aslc            |   75 +
> > .../Acpi/AcpiTables/Mcfg/Mcfg.h               |   56 +
> > .../Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.c     | 1402
> +++++
> > .../Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.h     |  316 ++
> > .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.c      |  805
> +++
> > .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.h      |  120 +
> > .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.inf    |  196 +
> > .../Acpi/Dxe/AcpiPlatform/Madt.h              |  207 +
> > .../Acpi/Dxe/AcpiPlatform/MadtPlatform.c      |  300 ++
> > .../BootScriptExecutorDxe.inf                 |   77 +
> > .../Dxe/BootScriptExecutorDxe/IA32/S3Asm.S    |   44 +
> > .../Dxe/BootScriptExecutorDxe/IA32/S3Asm.asm  |   51 +
> > .../BootScriptExecutorDxe/IA32/SetIdtEntry.c  |   57 +
> > .../Dxe/BootScriptExecutorDxe/ScriptExecute.c |  379 ++
> > .../Dxe/BootScriptExecutorDxe/ScriptExecute.h |   70 +
> > .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.c     | 1011
> ++++
> > .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.h     |  167 +
> > .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.inf   |   78 +
> > .../Acpi/DxeSmm/SmmPowerManagement/Ppm.c      |  372 ++
> > .../Acpi/DxeSmm/SmmPowerManagement/Ppm.h      |  150 +
> > .../SmmPowerManagement/SmmPowerManagement.c   |  113 +
> > .../SmmPowerManagement/SmmPowerManagement.h   |   52 +
> > .../SmmPowerManagement/SmmPowerManagement.inf |   74 +
> > .../Application/ForceRecovery/ForceRecovery.c |   47 +
> > .../ForceRecovery/ForceRecovery.inf           |   34 +
> > .../PlatformFlashAccessLibDxe.c               |  262 +
> > .../PlatformFlashAccessLibDxe.inf             |   47 +
> > .../PlatformFlashAccessLib/SpiFlashDevice.c   |  330 ++
> > .../PlatformFlashAccessLib/SpiFlashDevice.h   |  180 +
> > .../SystemFirmwareDescriptor.aslc             |   83 +
> > .../SystemFirmwareDescriptor.inf              |   40 +
> > .../SystemFirmwareDescriptorPei.c             |   60 +
> > .../SystemFirmwareUpdateConfig.ini            |   57 +
> > .../Include/Guid/CapsuleOnDataCD.h            |   23 +
> > .../Include/Guid/CapsuleOnFatFloppyDisk.h     |   23 +
> > .../Include/Guid/CapsuleOnFatIdeDisk.h        |   24 +
> > .../Include/Guid/CapsuleOnFatUsbDisk.h        |   24 +
> > .../Include/Guid/MemoryConfigData.h           |   23 +
> > .../Include/Guid/QuarkCapsuleGuid.h           |   46 +
> > .../Include/Guid/QuarkVariableLock.h          |   23 +
> > .../Include/Guid/SystemNvDataHobGuid.h        |   29 +
> > .../Include/Library/PlatformHelperLib.h       |  266 +
> > .../Include/Library/PlatformPcieHelperLib.h   |   56 +
> > .../Intel/QuarkPlatformPkg/Include/Pcal9555.h |   24 +
> > .../Intel/QuarkPlatformPkg/Include/Platform.h |  119 +
> > .../QuarkPlatformPkg/Include/PlatformBoards.h |  166 +
> > .../Include/Protocol/GlobalNvsArea.h          |   82 +
> > .../Include/Protocol/PlatformSmmSpiReady.h    |   23 +
> > .../PlatformBootManager.c                     |  472 ++
> > .../PlatformBootManager.h                     |   49 +
> > .../PlatformBootManagerLib.inf                |   83 +
> > .../PlatformBootManagerLib/PlatformData.c     |  275 +
> > .../Library/PlatformHelperLib/CommonHeader.h  |   51 +
> > .../DxePlatformHelperLib.inf                  |   70 +
> > .../PeiPlatformHelperLib.inf                  |   45 +
> > .../PlatformHelperLib/PlatformHelperDxe.c     |  337 ++
> > .../PlatformHelperLib/PlatformHelperLib.c     |  481 ++
> > .../PlatformHelperLib/PlatformHelperPei.c     |  159 +
> > .../Library/PlatformHelperLib/PlatformLeds.c  |  146 +
> > .../PlatformPcieHelperLib/CommonHeader.h      |   55 +
> > .../PlatformPcieHelperLib.c                   |  114 +
> > .../PlatformPcieHelperLib.inf                 |   41 +
> > .../Library/PlatformPcieHelperLib/SocUnit.c   |  125 +
> > .../Library/PlatformSecLib/Ia32/Flat32.S      |  796
> +++
> > .../Library/PlatformSecLib/Ia32/Flat32.asm    |  685
> +++
> > .../Library/PlatformSecLib/Ia32/Platform.inc  |  134 +
> > .../Library/PlatformSecLib/PlatformSecLib.c   |  207 +
> > .../Library/PlatformSecLib/PlatformSecLib.inf |   54 +
> > .../PlatformSecLib/PlatformSecLibModStrs.uni  |   18 +
> > .../PlatformSecureLib/PlatformSecureLib.c     |  164 +
> > .../PlatformSecureLib/PlatformSecureLib.inf   |   41 +
> > .../Library/Tpm12DeviceLibAtmelI2c/TisPc.c    |  408 ++
> > .../Tpm12DeviceLibAtmelI2c.inf                |   39 +
> > .../Tpm12DeviceLibAtmelI2c.uni                |   16 +
> > .../Library/Tpm12DeviceLibInfineonI2c/TisPc.c |  612
> +++
> > .../Tpm12DeviceLibInfineonI2c.inf             |   39 +
> > .../Tpm12DeviceLibInfineonI2c.uni             |   16 +
> > .../Pci/Dxe/PciHostBridge/PciHostBridge.c     | 1397
> +++++
> > .../Pci/Dxe/PciHostBridge/PciHostBridge.h     |  389 ++
> > .../Pci/Dxe/PciHostBridge/PciHostBridge.inf   |   61 +
> > .../Dxe/PciHostBridge/PciHostBridgeSupport.c  |  140 +
> > .../Pci/Dxe/PciHostBridge/PciHostResource.h   |   60 +
> > .../Pci/Dxe/PciHostBridge/PciRootBridge.h     |  693
> +++
> > .../Pci/Dxe/PciHostBridge/PciRootBridgeIo.c   | 1610
> ++++++
> > .../Pci/Dxe/PciPlatform/CommonHeader.h        |   31 +
> > .../Pci/Dxe/PciPlatform/PciPlatform.c         |  194 +
> > .../Pci/Dxe/PciPlatform/PciPlatform.h         |   82 +
> > .../Pci/Dxe/PciPlatform/PciPlatform.inf       |   54 +
> > .../Dxe/MemorySubClass/MemorySubClass.c       |  435 ++
> > .../Dxe/MemorySubClass/MemorySubClass.h       |   65 +
> > .../Dxe/MemorySubClass/MemorySubClass.inf     |   60 +
> > .../MemorySubClass/MemorySubClassStrings.uni  |   29 +
> > .../Dxe/PlatformInit/PlatformConfig.c         |  443 ++
> > .../Dxe/PlatformInit/PlatformInitDxe.c        |   87 +
> > .../Dxe/PlatformInit/PlatformInitDxe.h        |   58 +
> > .../Dxe/PlatformInit/PlatformInitDxe.inf      |   56 +
> > .../Dxe/SaveMemoryConfig/SaveMemoryConfig.c   |  118 +
> > .../Dxe/SaveMemoryConfig/SaveMemoryConfig.inf |   44 +
> > .../Platform/Dxe/Setup/CommonHeader.h         |   55 +
> > .../Platform/Dxe/Setup/DxePlatform.inf        |   76 +
> > .../Platform/Dxe/Setup/KeyboardLayout.c       |  262 +
> > .../Platform/Dxe/Setup/QNCRegTable.c          |   80 +
> > .../Platform/Dxe/Setup/SetupPlatform.c        |   97 +
> > .../Platform/Dxe/Setup/SetupPlatform.h        |   71 +
> > .../Platform/Dxe/Setup/Strings.uni            |   47 +
> > .../Platform/Dxe/Setup/processor.c            |   40 +
> > .../Platform/Dxe/SmbiosMiscDxe/CommonHeader.h |   34 +
> > .../MiscBaseBoardManufacturer.uni             |   19 +
> > .../MiscBaseBoardManufacturerData.c           |   45 +
> > .../MiscBaseBoardManufacturerFunction.c       |  181 +
> > .../Dxe/SmbiosMiscDxe/MiscBiosVendor.uni      |   18 +
> > .../Dxe/SmbiosMiscDxe/MiscBiosVendorData.c    |   92 +
> > .../SmbiosMiscDxe/MiscBiosVendorFunction.c    |  222 +
> > .../SmbiosMiscDxe/MiscBootInformationData.c   |   24 +
> > .../MiscBootInformationFunction.c             |   71 +
> > .../SmbiosMiscDxe/MiscChassisManufacturer.uni |   17 +
> > .../MiscChassisManufacturerData.c             |   36 +
> > .../MiscChassisManufacturerFunction.c         |  168 +
> > .../Dxe/SmbiosMiscDxe/MiscDevicePath.h        |   42 +
> > .../MiscNumberOfInstallableLanguagesData.c    |   28 +
> > ...MiscNumberOfInstallableLanguagesFunction.c |  240 +
> > .../Dxe/SmbiosMiscDxe/MiscOemString.uni       |   12 +
> > .../Dxe/SmbiosMiscDxe/MiscOemStringData.c     |   20 +
> > .../Dxe/SmbiosMiscDxe/MiscOemStringFunction.c |   78 +
> > .../Dxe/SmbiosMiscDxe/MiscOnboardDevice.uni   |   18 +
> > .../Dxe/SmbiosMiscDxe/MiscOnboardDeviceData.c |   49 +
> > .../SmbiosMiscDxe/MiscOnboardDeviceFunction.c |  105 +
> > .../MiscPortInternalConnectorDesignator.uni   |   53 +
> > .../MiscPortInternalConnectorDesignatorData.c |  184 +
> > ...cPortInternalConnectorDesignatorFunction.c |  292 ++
> > .../SmbiosMiscDxe/MiscSystemManufacturer.uni  |   20 +
> > .../MiscSystemManufacturerData.c              |   32 +
> > .../MiscSystemManufacturerFunction.c          |  198 +
> > .../SmbiosMiscDxe/MiscSystemOptionString.uni  |   14 +
> > .../MiscSystemOptionStringData.c              |   23 +
> > .../MiscSystemOptionStringFunction.c          |   81 +
> > .../MiscSystemSlotDesignation.uni             |   27 +
> > .../MiscSystemSlotDesignationData.c           |  357 ++
> > .../MiscSystemSlotDesignationFunction.c       |  285 ++
> > .../MiscSystemSlotOnboardDevices.uni          |   23 +
> > .../Platform/Dxe/SmbiosMiscDxe/SmbiosMisc.h   |  137 +
> > .../Dxe/SmbiosMiscDxe/SmbiosMiscDataTable.c   |  109 +
> > .../Dxe/SmbiosMiscDxe/SmbiosMiscDxe.inf       |  308 ++
> > .../Dxe/SmbiosMiscDxe/SmbiosMiscEntryPoint.c  |   82 +
> > .../Dxe/SmbiosMiscDxe/SmbiosMiscStrings.uni   |   26 +
> > .../Pei/PlatformConfig/PlatformConfigPei.c    |   81 +
> > .../Pei/PlatformConfig/PlatformConfigPei.inf  |   45 +
> > .../Platform/Pei/PlatformInit/BootMode.c      |  218 +
> > .../Platform/Pei/PlatformInit/CommonHeader.h  |   81 +
> > .../Pei/PlatformInit/Generic/Recovery.c       |  467 ++
> > .../Pei/PlatformInit/MemoryCallback.c         |  279 +
> > .../Platform/Pei/PlatformInit/MrcWrapper.c    | 1565
> ++++++
> > .../Platform/Pei/PlatformInit/MrcWrapper.h    |  225 +
> > .../Platform/Pei/PlatformInit/PeiFvSecurity.c |  111 +
> > .../Platform/Pei/PlatformInit/PeiFvSecurity.h |   67 +
> > .../Pei/PlatformInit/PlatformEarlyInit.c      | 1227
> +++++
> > .../Pei/PlatformInit/PlatformEarlyInit.h      |  301 ++
> > .../Pei/PlatformInit/PlatformEarlyInit.inf    |  193 +
> > .../Pei/PlatformInit/PlatformErratas.c        |  178 +
> > .../Platform/SpiFvbServices/FvbInfo.c         |  332 ++
> > .../Platform/SpiFvbServices/FwBlockService.c  | 2053
> ++++++++
> > .../Platform/SpiFvbServices/FwBlockService.h  |  308 ++
> > .../Platform/SpiFvbServices/PlatformSmmSpi.c  |   31 +
> > .../SpiFvbServices/PlatformSmmSpi.inf         |   80 +
> > .../Platform/SpiFvbServices/PlatformSpi.inf   |   79 +
> > .../Platform/SpiFvbServices/SpiFlashDevice.c  |  331 ++
> > .../Platform/SpiFvbServices/SpiFlashDevice.h  |  181 +
> > Platform/Intel/QuarkPlatformPkg/Quark.dsc     |  948
> ++++
> > Platform/Intel/QuarkPlatformPkg/Quark.fdf     |  907
> ++++
> > Platform/Intel/QuarkPlatformPkg/QuarkMin.dsc  |  648
> +++
> > Platform/Intel/QuarkPlatformPkg/QuarkMin.fdf  |  608
> +++
> > .../QuarkPlatformPkg/QuarkPlatformPkg.dec     |  933
> ++++
> > Platform/Intel/QuarkPlatformPkg/Readme.md     |  685
> +++
> > Platform/Intel/Vlv2TbltDevicePkg/.gitignore   |    5 +
> > .../AcpiPlatform/AcpiPlatform.c               | 1338
> +++++
> > .../AcpiPlatform/AcpiPlatform.h               |  219 +
> > .../AcpiPlatform/AcpiPlatform.inf             |   89 +
> > .../AcpiPlatform/AcpiPlatformHooks.c          |  493 ++
> > .../AcpiPlatform/AcpiPlatformHooks.h          |  127 +
> > .../AcpiPlatform/AcpiPlatformHooksLib.h       |   91 +
> > .../Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h     |   56 +
> > .../FirmwareUpdate/FirmwareUpdate.c           |  922
> ++++
> > .../FirmwareUpdate/FirmwareUpdate.h           |  185 +
> > .../FirmwareUpdate/FirmwareUpdate.inf         |   83 +
> > .../FirmwareUpdate/FirmwareUpdateStrings.uni  |   45 +
> > Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe   |  Bin 0
> -> 499712 bytes
> > Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env  |   25 +
> > Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env  |   25 +
> > .../Intel/Vlv2TbltDevicePkg/BiosIdx64D.env    |   25 +
> > .../Intel/Vlv2TbltDevicePkg/BiosIdx64R.env    |   25 +
> > .../BootScriptSaveDxe/BootScriptSaveDxe.inf   |   60 +
> > .../InternalBootScriptSave.h                  |  102 +
> > .../BootScriptSaveDxe/ScriptSave.c            |  626
> +++
> > .../Intel/Vlv2TbltDevicePkg/Build_IFWI.bat    |  200 +
> > .../Intel/Vlv2TbltDevicePkg/Build_IFWI.sh     |  104 +
> > Platform/Intel/Vlv2TbltDevicePkg/FCE.exe      |  Bin 0
> -> 632832 bytes
> > .../Capsule/GenerateCapsule/GenCapsuleAll.bat |   35 +
> > .../Capsule/GenerateCapsule/GenCapsuleAll.sh  |   28 +
> > .../GenerateCapsule/GenCapsuleMinnowMax.bat   |  131 +
> > .../GenerateCapsule/GenCapsuleMinnowMax.sh    |   65 +
> > .../GenCapsuleMinnowMaxRelease.bat            |  131 +
> > .../GenCapsuleMinnowMaxRelease.sh             |   65 +
> > .../GenerateCapsule/GenCapsuleSampleColor.bat |  137 +
> > .../GenerateCapsule/GenCapsuleSampleColor.sh  |   70 +
> > .../Feature/Capsule/GenerateCapsule/Lvfs.ddf  |   14 +
> > .../LvfsGenCapsuleMinnowMax.bat               |  139 +
> > .../LvfsGenCapsuleMinnowMaxRelease.bat        |  139 +
> > .../LvfsGenCapsuleSampleColor.bat             |  145 +
> > ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
> > ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
> > ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
> > .../GenerateCapsule/template.metainfo.xml     |   27 +
> > .../Library/FmpDeviceLib/FmpDeviceLib.c       |  589
> +++
> > .../Library/FmpDeviceLib/FmpDeviceLib.inf     |   46 +
> > .../Library/FmpDeviceLibSample/FmpDeviceLib.c |  412 ++
> > .../FmpDeviceLibSample/FmpDeviceLib.inf       |   34 +
> > .../PlatformFlashAccessLib.c                  |  685
> +++
> > .../PlatformFlashAccessLib.inf                |   54 +
> > .../SystemFirmwareDescriptor.aslc             |   83 +
> > .../SystemFirmwareDescriptor.inf              |   40 +
> > .../SystemFirmwareDescriptorPei.c             |   60 +
> > .../SystemFirmwareUpdateConfig.ini            |   66 +
> > .../SystemFirmwareUpdateConfigGcc.ini         |   66 +
> > .../Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc |   55 +
> > .../Vlv2TbltDevicePkg/FmpCertificate.dsc      |   22 +
> > .../FmpGreenSampleDevice.dsc                  |   55 +
> > .../Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc  |   59 +
> > .../Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc  |   55 +
> > .../FspAzaliaConfigData/AzaliaConfig.bin      |  Bin 0
> -> 3708 bytes
> > .../FspSupport/BootModePei/BootModePei.c      |   42 +
> > .../FspSupport/BootModePei/BootModePei.inf    |   40 +
> > .../FspHobProcessLibVlv2.c                    |  421 ++
> > .../FspHobProcessLibVlv2.inf                  |   74 +
> > .../FspPlatformSecLibVlv2.c                   |  144 +
> > .../FspPlatformSecLibVlv2.inf                 |   82 +
> > .../Ia32/AsmSaveSecContext.asm                |   45 +
> > .../SecFspPlatformSecLibVlv2/Ia32/Fsp.inc     |   45 +
> > .../Ia32/PeiCoreEntry.asm                     |  135 +
> > .../Ia32/SecEntry.asm                         |  338 ++
> > .../SecFspPlatformSecLibVlv2/Ia32/Stack.S     |   71 +
> > .../SecFspPlatformSecLibVlv2/Ia32/Stack.asm   |   76 +
> > .../SecFspPlatformSecLibVlv2/PlatformInit.c   |   36 +
> > .../SecFspPlatformSecLibVlv2/SaveSecContext.c |  108 +
> > .../SecGetPerformance.c                       |   83 +
> > .../SecPlatformInformation.c                  |   77 +
> > .../SecFspPlatformSecLibVlv2/SecRamInitData.c |   16 +
> > .../SecTempRamSupport.c                       |  149 +
> > .../SecFspPlatformSecLibVlv2/UartInit.c       |  192 +
> > .../Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c   |   68 +
> > .../Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf |   49 +
> > .../Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c |  170 +
> > .../FvbRuntimeDxe/FvbRuntimeDxe.inf           |   80 +
> > .../FvbRuntimeDxe/FvbService.c                | 1098
> ++++
> > .../FvbRuntimeDxe/FvbService.h                |  182 +
> > .../FvbRuntimeDxe/FvbServiceDxe.c             |  199 +
> > .../FvbRuntimeDxe/FvbServiceSmm.c             |  127 +
> > .../FvbRuntimeDxe/FvbSmm.inf                  |   82 +
> > .../FvbRuntimeDxe/FvbSmmCommon.h              |   73 +
> > .../FvbRuntimeDxe/FvbSmmDxe.c                 |  944
> ++++
> > .../FvbRuntimeDxe/FvbSmmDxe.h                 |  232 +
> > .../FvbRuntimeDxe/FvbSmmDxe.inf               |   50 +
> > Platform/Intel/Vlv2TbltDevicePkg/GenBiosId    |  Bin 0
> -> 12236 bytes
> > .../Intel/Vlv2TbltDevicePkg/GenBiosId.exe     |  Bin 0
> -> 384000 bytes
> > .../Include/AlertStandardFormatTable.h        |  122 +
> > .../Vlv2TbltDevicePkg/Include/ChipsetAccess.h |   28 +
> > .../Include/CommonIncludes.h                  |  115 +
> > .../Intel/Vlv2TbltDevicePkg/Include/CpuType.h |   59 +
> > .../Vlv2TbltDevicePkg/Include/FileHandleLib.h |  499 ++
> > .../Include/Guid/AcpiTableStorage.h           |   30 +
> > .../Include/Guid/AlertStandardFormat.h        |   86 +
> > .../Vlv2TbltDevicePkg/Include/Guid/BiosId.h   |   30 +
> > .../Include/Guid/BoardFeatures.h              |  214 +
> > .../Include/Guid/EfiVpdData.h                 |  156 +
> > .../Include/Guid/FirmwareId.h                 |   61 +
> > .../Include/Guid/HwWatchdogTimerHob.h         |  134 +
> > .../Vlv2TbltDevicePkg/Include/Guid/IdccData.h |  104 +
> > .../Vlv2TbltDevicePkg/Include/Guid/ItkData.h  |   70 +
> > .../Include/Guid/MemoryConfigData.h           |   32 +
> > .../Include/Guid/OsSelection.h                |   85 +
> > .../Include/Guid/PciLanInfo.h                 |   39 +
> > .../Include/Guid/PlatformCpuInfo.h            |  180 +
> > .../Include/Guid/PlatformInfo.h               |  433 ++
> > .../Include/Guid/SensorInfoVariable.h         |  279 +
> > .../Include/Guid/SetupVariable.h              | 1344
> +++++
> > .../Intel/Vlv2TbltDevicePkg/Include/Hpet.h    |   40 +
> > .../Include/Library/BiosIdLib.h               |  104 +
> > .../Include/Library/CpuIA32.h                 |  345 ++
> > .../Include/Library/EfiRegTableLib.h          |  196 +
> > .../Vlv2TbltDevicePkg/Include/Library/Esrt.h  |   74 +
> > .../Vlv2TbltDevicePkg/Include/Library/Fd.h    |  264 +
> > .../Include/Library/FlashDeviceLib.h          |  122 +
> > .../Include/Library/I2CLib.h                  |   58 +
> > .../Include/Library/I2cMmioConfigLib.h        |   23 +
> > .../Include/Library/I2cPort_platform.h        |   26 +
> > .../Include/Library/PlatformFsaLib.h          |   50 +
> > .../Include/Library/PlatformFspLib.h          |   23 +
> > .../Include/Library/SpiFlash.H                |  239 +
> > .../Include/Library/StallSmmLib.h             |   40 +
> > .../Include/Library/UsbDeviceModeLib.h        |  181 +
> > .../Intel/Vlv2TbltDevicePkg/Include/Mcfg.h    |   69 +
> > .../Vlv2TbltDevicePkg/Include/McfgTable.h     |   65 +
> > .../Vlv2TbltDevicePkg/Include/Platform.h      |  133 +
> > .../Include/PlatformBootMode.h                |   35 +
> > .../Include/PlatformDefinitions.h             |   43 +
> > .../Include/Ppi/MfgMemoryTest.h               |   42 +
> > .../Include/Ppi/Sha256Hash.h                  |  131 +
> > .../Vlv2TbltDevicePkg/Include/Ppi/Speaker.h   |   65 +
> > .../Include/Ppi/UsbController.h               |   85 +
> > .../Include/Protocol/CK505ClockPlatformInfo.h |  126 +
> > .../Include/Protocol/EnhancedSpeedstep.h      |   76 +
> > .../Include/Protocol/GlobalNvsArea.h          |  475 ++
> > .../Include/Protocol/HwWatchdogTimer.h        |  235 +
> > .../Include/Protocol/I2cAcpi.h                |  107 +
> > .../Include/Protocol/I2cBus.h                 |  164 +
> > .../Include/Protocol/I2cBusMcg.h              |  163 +
> > .../Include/Protocol/I2cHostMcg.h             |  138 +
> > .../Include/Protocol/I2cMasterMcg.h           |  519 ++
> > .../Include/Protocol/I2cSlave.h               |  194 +
> > .../Include/Protocol/LpcWpc83627Policy.h      |   92 +
> > .../Include/Protocol/LpcWpce791Policy.h       |   55 +
> > .../Include/Protocol/MmioDevice.h             |   84 +
> > .../Include/Protocol/Observable.h             |  186 +
> > .../Include/Protocol/PlatformGopPolicy.h      |   68 +
> > .../Include/Protocol/PlatformIdeInit.h        |   43 +
> > .../Include/Protocol/SetupMode.h              |   79 +
> > .../Include/Protocol/SmbiosSlotPopulation.h   |   47 +
> > .../Include/Protocol/Speaker.h                |   65 +
> > .../Include/Protocol/TcoReset.h               |   67 +
> > .../Include/Protocol/TpmMp.h                  |  136 +
> > .../Include/Protocol/UsbPolicy.h              |  126 +
> > .../Include/Protocol/VlvPlatformPolicy.h      |  102 +
> > .../Vlv2TbltDevicePkg/Include/SetupMode.h     |   85 +
> > .../IntelGopDepex/IntelGopDriver.depex        |    1 +
> > .../Library/BiosIdLib/BiosIdLib.c             |  337 ++
> > .../Library/BiosIdLib/BiosIdLib.inf           |   50 +
> > .../Library/CpuIA32Lib/CpuIA32Lib.inf         |   41 +
> > .../Library/CpuIA32Lib/EfiCpuVersion.c        |   70 +
> > .../Library/CpuIA32Lib/IA32/CpuIA32.S         |  223 +
> > .../Library/CpuIA32Lib/IA32/CpuIA32.asm       |  206 +
> > .../Library/CpuIA32Lib/IA32/CpuIA32.c         |  177 +
> > .../Library/CpuIA32Lib/X64/Cpu.S              |  207 +
> > .../Library/CpuIA32Lib/X64/Cpu.asm            |  222 +
> > .../Library/EfiRegTableLib/EfiRegTableLib.c   |  282 ++
> > .../Library/EfiRegTableLib/EfiRegTableLib.inf |   47 +
> > .../Library/FlashDeviceLib/FlashDeviceLib.c   |  461 ++
> > .../Library/FlashDeviceLib/FlashDeviceLib.inf |   44 +
> > .../FlashDeviceLib/FlashDeviceLibDxe.c        |   56 +
> > .../FlashDeviceLib/FlashDeviceLibDxe.inf      |   43 +
> > .../FlashDeviceLibDxeRuntimeSmm.c             |  173 +
> > .../FlashDeviceLib/SpiChipDefinitions.h       |  835
> +++
> > .../Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c |   46 +
> > .../Library/I2CLib/I2CLibNull.inf             |   39 +
> > .../Library/I2CLibDxe/I2CLib.c                |  735
> +++
> > .../Library/I2CLibDxe/I2CLibDxe.inf           |   39 +
> > .../Library/I2CLibDxe/I2CRegs.h               |  126 +
> > .../Library/I2CLibPei/I2CAccess.h             |   44 +
> > .../Library/I2CLibPei/I2CDelayPei.c           |   46 +
> > .../Library/I2CLibPei/I2CDelayPei.h           |   30 +
> > .../Library/I2CLibPei/I2CIoLibPei.c           |  178 +
> > .../Library/I2CLibPei/I2CIoLibPei.h           |  153 +
> > .../Library/I2CLibPei/I2CLibPei.c             |  638
> +++
> > .../Library/I2CLibPei/I2CLibPei.h             |  280 +
> > .../Library/I2CLibPei/I2CLibPei.inf           |   40 +
> > .../IntelPchAcpiTimerLib/CommonHeader.h       |   27 +
> > .../IntelPchAcpiTimerLib.c                    |  255 +
> > .../IntelPchAcpiTimerLib.inf                  |   51 +
> > .../BoardClkGens/BoardClkGens.c               |  430 ++
> > .../BoardClkGens/BoardClkGens.h               |  255 +
> > .../MultiPlatformLib/BoardGpios/BoardGpios.c  |  531 ++
> > .../MultiPlatformLib/BoardGpios/BoardGpios.h  |  324 ++
> > .../BoardJumpers/BoardJumpers.c               |   30 +
> > .../BoardJumpers/BoardJumpers.h               |   30 +
> > .../BoardOemIds/BoardOemIds.c                 |   43 +
> > .../BoardOemIds/BoardOemIds.h                 |   29 +
> > .../BoardSsidSvid/BoardSsidSvid.c             |   38 +
> > .../BoardSsidSvid/BoardSsidSvid.h             |   35 +
> > .../MultiPlatformLib/MultiPlatformLib.c       |  120 +
> > .../MultiPlatformLib/MultiPlatformLib.h       |   89 +
> > .../MultiPlatformLib/MultiPlatformLib.inf     |   77 +
> > .../MultiPlatformLib/PlatformInfoHob.c        |   54 +
> > .../Library/PchPlatformLib/PchPlatformLib.inf |   50 +
> > .../PchPlatformLib/PchPlatformLibrary.c       |  131 +
> > .../PchPlatformLib/PchPlatformLibrary.h       |   35 +
> > .../Library/PchSmmLib/CommonHeader.h          |   32 +
> > .../Library/PchSmmLib/PchSmmLib.c             |  157 +
> > .../Library/PchSmmLib/PchSmmLib.inf           |   46 +
> > .../Library/PlatformBdsLib/BdsPlatform.c      | 3098
> ++++++++++++
> > .../Library/PlatformBdsLib/BdsPlatform.h      |  516 ++
> > .../Library/PlatformBdsLib/PlatformBdsLib.inf |  127 +
> > .../PlatformBdsLib/PlatformBdsStrings.uni     |   30 +
> > .../Library/PlatformBdsLib/PlatformData.c     |  306 ++
> > .../Library/PlatformCmosLib/PlatformCmosLib.c |  106 +
> > .../PlatformCmosLib/PlatformCmosLib.inf       |   30 +
> > .../Library/PlatformFspLib/PlatformFspLib.c   |   44 +
> > .../Library/PlatformFspLib/PlatformFspLib.inf |   49 +
> > .../Library/ResetSystemLib/ResetSystemLib.c   |  235 +
> > .../Library/ResetSystemLib/ResetSystemLib.inf |   47 +
> > .../SerialPortLib/PlatformSerialPortLib.h     |   53 +
> > .../Library/SerialPortLib/SerialPortLib.c     |  246 +
> > .../Library/SerialPortLib/SerialPortLib.inf   |   52 +
> > .../Library/SerialPortLib/SioInit.c           |  127 +
> > .../Library/SerialPortLib/SioInit.h           |   62 +
> > .../Library/SmbusLib/CommonHeader.h           |   26 +
> > .../Library/SmbusLib/SmbusLib.c               |  873
> ++++
> > .../Library/SmbusLib/SmbusLib.inf             |   46 +
> > .../Library/StallSmmLib/StallSmm.c            |   89 +
> > .../Library/StallSmmLib/StallSmmLib.inf       |   51 +
> > .../Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.c    |  117 +
> > .../Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.inf  |   61 +
> > .../Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.c    |  145 +
> > .../Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.inf  |   60 +
> > .../Intel/Vlv2TbltDevicePkg/Logo/Logo.bmp     |  Bin 0
> -> 94434 bytes
> > .../Metronome/LegacyMetronome.c               |  185 +
> > .../Metronome/LegacyMetronome.h               |   64 +
> > .../Vlv2TbltDevicePkg/Metronome/Metronome.inf |   49 +
> > .../MonoStatusCode/EfiStatusCode.h            |  178 +
> > .../MonoStatusCode/MonoStatusCode.c           |  132 +
> > .../MonoStatusCode/MonoStatusCode.h           |  128 +
> > .../MonoStatusCode/MonoStatusCode.inf         |   72 +
> > .../MonoStatusCode/PeiPostCode.c              |  121 +
> > .../MonoStatusCode/PlatformStatusCode.c       |  381 ++
> > .../MonoStatusCode/PlatformStatusCode.h       |  138 +
> > .../Library/GenericBdsLib/BdsBoot.c           | 4490
> +++++++++++++++++
> > .../Library/GenericBdsLib/BdsConnect.c        |  429 ++
> > .../Library/GenericBdsLib/BdsConsole.c        | 1061
> ++++
> > .../Library/GenericBdsLib/BdsMisc.c           | 1575
> ++++++
> > .../Library/GenericBdsLib/DevicePath.c        |   27 +
> > .../Library/GenericBdsLib/GenericBdsLib.inf   |  142 +
> > .../Library/GenericBdsLib/GenericBdsLib.uni   |   19 +
> > .../GenericBdsLib/GenericBdsStrings.uni       |   30 +
> > .../Library/GenericBdsLib/InternalBdsLib.h    |  173 +
> > .../Library/GenericBdsLib/String.c            |   26 +
> > .../Library/GenericBdsLib/String.h            |   42 +
> > .../PciPlatform/BoardPciPlatform.c            |   55 +
> > .../PciPlatform/PciPlatform.c                 |  367 ++
> > .../PciPlatform/PciPlatform.h                 |   83 +
> > .../PciPlatform/PciPlatform.inf               |   65 +
> > .../Vlv2TbltDevicePkg/PlatformCapsule.dsc     |   39 +
> > .../Vlv2TbltDevicePkg/PlatformCapsule.fdf     |   52 +
> > .../Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc  |   38 +
> > .../Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf  |   52 +
> > .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.c   |   60 +
> > .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.h   |   29 +
> > .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf |   55 +
> > .../PlatformDxe/AzaliaVerbTable.h             |  247 +
> > .../Vlv2TbltDevicePkg/PlatformDxe/BoardId.c   |  223 +
> > .../PlatformDxe/BoardIdDecode.c               |  129 +
> > .../PlatformDxe/BoardIdDecode.h               |   61 +
> > .../PlatformDxe/ClockControl.c                |  202 +
> > .../PlatformDxe/Configuration.h               |  692
> +++
> > .../Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c |   89 +
> > .../PlatformDxe/IchPlatformPolicy.c           |  484 ++
> > .../PlatformDxe/IchRegTable.c                 |  134 +
> > .../PlatformDxe/IchTcoReset.c                 |  211 +
> > .../Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c  |   72 +
> > .../PlatformDxe/LegacySpeaker.c               |  161 +
> > .../PlatformDxe/LegacySpeaker.h               |   69 +
> > .../PlatformDxe/Observable/Observable.c       |  582
> +++
> > .../PlatformDxe/Observable/Observable.h       |  137 +
> > .../Vlv2TbltDevicePkg/PlatformDxe/PciBus.h    |  379 ++
> > .../Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c |  506 ++
> > .../Vlv2TbltDevicePkg/PlatformDxe/Platform.c  | 1820
> +++++++
> > .../PlatformDxe/PlatformDxe.h                 |  722
> +++
> > .../PlatformDxe/PlatformDxe.inf               |  149 +
> > .../Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c |  154 +
> > .../Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c |  112 +
> > .../PlatformDxe/SioPlatformPolicy.c           |   82 +
> > .../PlatformDxe/SlotConfig.c                  |  148 +
> > .../PlatformDxe/SlotConfig.h                  |   80 +
> > .../PlatformGopPolicy/PlatformGopPolicy.c     |  201 +
> > .../PlatformGopPolicy/PlatformGopPolicy.inf   |   51 +
> > .../PlatformInfoDxe/PlatformInfoDxe.c         |  169 +
> > .../PlatformInfoDxe/PlatformInfoDxe.h         |   30 +
> > .../PlatformInfoDxe/PlatformInfoDxe.inf       |   52 +
> > .../PlatformInitPei/BootMode.c                |  434 ++
> > .../PlatformInitPei/CpuInitPeim.c             |   44 +
> > .../Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c  |  319 ++
> > .../PlatformInitPei/FlashMap.c                |  143 +
> > .../PlatformInitPei/LegacySpeaker.c           |  168 +
> > .../PlatformInitPei/LegacySpeaker.h           |   71 +
> > .../PlatformInitPei/MchInit.c                 |   72 +
> > .../PlatformInitPei/MemoryCallback.c          |  338 ++
> > .../PlatformInitPei/MemoryPeim.c              |  408 ++
> > .../PlatformInitPei/PchInitPeim.c             |  808
> +++
> > .../PlatformInitPei/PlatformEarlyInit.c       | 1195
> +++++
> > .../PlatformInitPei/PlatformEarlyInit.h       | 1499
> ++++++
> > .../PlatformInitPei/PlatformInfoInit.c        |  181 +
> > .../PlatformInitPei/PlatformInitPei.inf       |  117 +
> > .../PlatformInitPei/PlatformSsaInitPeim.c     |   58 +
> > .../PlatformInitPei/Recovery.c                |  361 ++
> > .../Vlv2TbltDevicePkg/PlatformInitPei/Stall.c |   91 +
> > .../Vlv2TbltDevicePkg/PlatformPei/BootMode.c  |  346 ++
> > .../PlatformPei/CommonHeader.h                |   60 +
> > .../PlatformPei/MemoryCallback.c              |  154 +
> > .../Vlv2TbltDevicePkg/PlatformPei/Platform.c  | 1198
> +++++
> > .../Vlv2TbltDevicePkg/PlatformPei/Platform.h  |  213 +
> > .../PlatformPei/PlatformPei.inf               |  129 +
> > .../Vlv2TbltDevicePkg/PlatformPei/Stall.c     |   90 +
> > .../Intel/Vlv2TbltDevicePkg/PlatformPkg.dec   |  211 +
> > .../Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf   | 1073
> ++++
> > .../Vlv2TbltDevicePkg/PlatformPkgConfig.dsc   |  107 +
> > .../Vlv2TbltDevicePkg/PlatformPkgGcc.fdf      | 1033
> ++++
> > .../Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc   | 1711
> +++++++
> > .../Vlv2TbltDevicePkg/PlatformPkgIA32.dsc     | 1699
> +++++++
> > .../Vlv2TbltDevicePkg/PlatformPkgX64.dsc      | 1714
> +++++++
> > .../PlatformSetupDxe/Boot.vfi                 |   72 +
> > .../PlatformSetupDxe/Configuration.h          |   56 +
> > .../PlatformSetupDxe/DebugConfig.vfi          |  118 +
> > .../PlatformSetupDxe/FwVersionStrings.uni     |   40 +
> > .../PlatformSetupDxe/Main.vfi                 |  331 ++
> > .../PlatformSetupDxe/PlatformSetupDxe.c       |  929
> ++++
> > .../PlatformSetupDxe/PlatformSetupDxe.h       |   97 +
> > .../PlatformSetupDxe/PlatformSetupDxe.inf     |  141 +
> > .../PlatformSetupDxe/Security.vfi             |  104 +
> > .../PlatformSetupDxe/SetupFunctions.c         |   85 +
> > .../PlatformSetupDxe/SetupInfoRecords.c       | 1855
> +++++++
> > .../PlatformSetupDxe/SouthClusterConfig.vfi   |  933
> ++++
> > .../PlatformSetupDxe/SystemComponent.vfi      |   81 +
> > .../PlatformSetupDxe/Thermal.vfi              |  106 +
> > .../PlatformSetupDxe/UnCore.vfi               |  235 +
> > .../PlatformSetupDxe/UqiList.uni              |  452 ++
> > .../PlatformSetupDxe/Vfr.vfr                  |  123 +
> > .../PlatformSetupDxe/VfrStrings.uni           | 1417
> ++++++
> > .../Vlv2TbltDevicePkg/PlatformSmm/Platform.c  |  997
> ++++
> > .../PlatformSmm/PlatformSmm.inf               |   93 +
> > .../Vlv2TbltDevicePkg/PlatformSmm/S3Save.c    |  377 ++
> > .../PlatformSmm/SmmPlatform.h                 |  240 +
> > .../PlatformSmm/SmmScriptSave.c               |  252 +
> > .../PlatformSmm/SmmScriptSave.h               |   50 +
> > .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c   |  148 +
> > .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h   |   36 +
> > .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf |   49 +
> > Platform/Intel/Vlv2TbltDevicePkg/Readme.md    |  233 +
> > .../SaveMemoryConfig/SaveMemoryConfig.c       |  181 +
> > .../SaveMemoryConfig/SaveMemoryConfig.h       |   66 +
> > .../SaveMemoryConfig/SaveMemoryConfig.inf     |   60 +
> > .../SmBiosMiscDxe/CommonHeader.h              |   39 +
> > .../MiscBaseBoardManufacturer.uni             |   33 +
> > .../MiscBaseBoardManufacturerData.c           |   58 +
> > .../MiscBaseBoardManufacturerFunction.c       |  238 +
> > .../SmBiosMiscDxe/MiscBiosVendor.uni          |   26 +
> > .../SmBiosMiscDxe/MiscBiosVendorData.c        |  101 +
> > .../SmBiosMiscDxe/MiscBiosVendorFunction.c    |  336 ++
> > .../SmBiosMiscDxe/MiscBootInformationData.c   |   34 +
> > .../MiscBootInformationFunction.c             |   82 +
> > .../SmBiosMiscDxe/MiscChassisManufacturer.uni |   28 +
> > .../MiscChassisManufacturerData.c             |   57 +
> > .../MiscChassisManufacturerFunction.c         |  158 +
> > .../SmBiosMiscDxe/MiscMemoryDevice.uni        |   35 +
> > .../SmBiosMiscDxe/MiscMemoryDeviceData.c      |   45 +
> > .../SmBiosMiscDxe/MiscMemoryDeviceFunction.c  |  319 ++
> > .../MiscNumberOfInstallableLanguagesData.c    |   38 +
> > ...MiscNumberOfInstallableLanguagesFunction.c |  251 +
> > .../SmBiosMiscDxe/MiscOemString.uni           |   25 +
> > .../SmBiosMiscDxe/MiscOemStringData.c         |   34 +
> > .../SmBiosMiscDxe/MiscOemStringFunction.c     |   89 +
> > .../SmBiosMiscDxe/MiscOemType0x90.uni         |   31 +
> > .../SmBiosMiscDxe/MiscOemType0x90Data.c       |   36 +
> > .../SmBiosMiscDxe/MiscOemType0x90Function.c   |  442 ++
> > .../SmBiosMiscDxe/MiscOemType0x94.uni         |   42 +
> > .../SmBiosMiscDxe/MiscOemType0x94Data.c       |   54 +
> > .../SmBiosMiscDxe/MiscOemType0x94Function.c   | 1218
> +++++
> > .../SmBiosMiscDxe/MiscOnboardDevice.uni       |   26 +
> > .../SmBiosMiscDxe/MiscOnboardDeviceData.c     |   48 +
> > .../SmBiosMiscDxe/MiscOnboardDeviceFunction.c |  135 +
> > .../SmBiosMiscDxe/MiscPhysicalArray.uni       |   25 +
> > .../SmBiosMiscDxe/MiscPhysicalArrayData.c     |   38 +
> > .../SmBiosMiscDxe/MiscPhysicalArrayFunction.c |  101 +
> > .../MiscPortInternalConnectorDesignator.uni   |   31 +
> > .../MiscPortInternalConnectorDesignatorData.c |   56 +
> > ...cPortInternalConnectorDesignatorFunction.c |  152 +
> > .../SmBiosMiscDxe/MiscProcessorCache.uni      |   22 +
> > .../SmBiosMiscDxe/MiscProcessorCacheData.c    |   33 +
> > .../MiscProcessorCacheFunction.c              |  189 +
> > .../MiscProcessorInformation.uni              |   27 +
> > .../MiscProcessorInformationData.c            |   71 +
> > .../MiscProcessorInformationFunction.c        |  448 ++
> > .../SmBiosMiscDxe/MiscResetCapabilitiesData.c |   43 +
> > .../MiscResetCapabilitiesFunction.c           |   85 +
> > .../SmBiosMiscDxe/MiscSubclassDriver.h        |  188 +
> > .../SmBiosMiscDxe/MiscSubclassDriver.uni      |   35 +
> > .../MiscSubclassDriverDataTable.c             |   98 +
> > .../MiscSubclassDriverEntryPoint.c            |  182 +
> > .../MiscSystemLanguageString.uni              |   24 +
> > .../MiscSystemLanguageStringData.c            |   34 +
> > .../MiscSystemLanguageStringFunction.c        |   93 +
> > .../SmBiosMiscDxe/MiscSystemManufacturer.uni  |   30 +
> > .../MiscSystemManufacturerData.c              |   48 +
> > .../MiscSystemManufacturerFunction.c          |  364 ++
> > .../SmBiosMiscDxe/MiscSystemOptionString.uni  |   24 +
> > .../MiscSystemOptionStringData.c              |   31 +
> > .../MiscSystemOptionStringFunction.c          |   93 +
> > .../MiscSystemSlotDesignation.uni             |   34 +
> > .../MiscSystemSlotDesignationData.c           |  246 +
> > .../MiscSystemSlotDesignationFunction.c       |  127 +
> > .../SmBiosMiscDxe/SmBiosMiscDxe.inf           |  139 +
> > .../SmmSwDispatch2OnSmmSwDispatchThunk.c      |  459 ++
> > .../SmmSwDispatch2OnSmmSwDispatchThunk.inf    |   54 +
> > .../SmramSaveInfoHandlerSmm.c                 |  164 +
> > .../SmramSaveInfoHandlerSmm.inf               |   60 +
> > .../Stitch/Gcc/NvStorageFtwSpare.bin          |  Bin 0
> -> 262144 bytes
> > .../Stitch/Gcc/NvStorageFtwWorking.bin        |  Bin 0
> -> 8192 bytes
> > .../Stitch/Gcc/NvStorageVariable.bin          |  Bin 0
> -> 253952 bytes
> > .../Stitch/IFWIHeader/IFWI_HEADER.bin         |  Bin 0
> -> 4096 bytes
> > .../Stitch/IFWIHeader/IFWI_HEADER_SPILOCK.bin |  Bin 0
> -> 4096 bytes
> > .../Stitch/IFWIHeader/Vacant.bin              |  Bin 0
> -> 3928064 bytes
> > .../Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat   |  270 +
> > .../Stitch/MNW2_Stitch_Config.txt             |   10 +
> > .../Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c |   33 +
> > .../Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf   |   32 +
> > .../VlvPlatformInitDxe/IgdOpRegion.c          |  929
> ++++
> > .../VlvPlatformInitDxe/IgdOpRegion.h          |  235 +
> > .../VlvPlatformInitDxe/VlvPlatformInit.c      |  287 ++
> > .../VlvPlatformInitDxe/VlvPlatformInit.h      |   65 +
> > .../VlvPlatformInitDxe/VlvPlatformInitDxe.inf |   74 +
> > .../Vlv2TbltDevicePkg/Wpce791/LpcDriver.c     |  340 ++
> > .../Vlv2TbltDevicePkg/Wpce791/LpcDriver.h     |  112 +
> > .../Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c    |  366 ++
> > .../Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h    |  103 +
> > .../Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c  |  126 +
> > .../Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h  |  101 +
> > .../Vlv2TbltDevicePkg/Wpce791/Wpce791.inf     |   63 +
> > Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat  |  332 ++
> > Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh   |  256 +
> > Platform/Intel/Vlv2TbltDevicePkg/cln.sh       |   62 +
> > Readme.md                                     |    9 +
> > .../Include/DdrMemoryController.h             |  251 +
> > .../QuarkNorthCluster/Include/IntelQNCBase.h  |   17 +
> > .../Include/IntelQNCConfig.h                  |  100 +
> > .../QuarkNorthCluster/Include/IntelQNCDxe.h   |   17 +
> > .../QuarkNorthCluster/Include/IntelQNCPeim.h  |   17 +
> > .../QuarkNorthCluster/Include/IntelQNCRegs.h  |   48 +
> > .../Include/Library/IntelQNCLib.h             |  284 ++
> > .../Include/Library/QNCAccessLib.h            |  161 +
> > .../Include/Library/QNCSmmLib.h               |   57 +
> > .../Include/Ppi/QNCMemoryInit.h               |   36 +
> > .../Include/Protocol/PchInfo.h                |   48 +
> > .../Include/Protocol/PlatformPolicy.h         |   31 +
> > .../Include/Protocol/QncS3Support.h           |   84 +
> > .../Include/Protocol/SmmIchnDispatch2.h       |  115 +
> > .../QuarkNorthCluster/Include/Protocol/Spi.h  |  345 ++
> > .../QuarkNorthCluster/Include/QNCAccess.h     |  177 +
> > .../Include/QNCCommonDefinitions.h            |  350 ++
> > .../QuarkNorthCluster/Include/QuarkNcSocId.h  |  751
> +++
> > .../Library/IntelQNCLib/CommonHeader.h        |   32 +
> > .../Library/IntelQNCLib/IntelQNCLib.c         |  771
> +++
> > .../Library/IntelQNCLib/IntelQNCLib.inf       |   57 +
> > .../Library/IntelQNCLib/PciExpress.c          |  932
> ++++
> > .../Library/MtrrLib/MtrrLib.c                 | 2112
> ++++++++
> > .../Library/MtrrLib/MtrrLib.inf               |   42 +
> > .../Library/MtrrLib/MtrrLib.uni               |   18 +
> > .../Library/QNCAccessLib/BaseAccess.c         |   28 +
> > .../Library/QNCAccessLib/QNCAccessLib.c       |  327 ++
> > .../Library/QNCAccessLib/QNCAccessLib.inf     |   37 +
> > .../Library/QNCAccessLib/RuntimeAccess.c      |  142 +
> > .../QNCAccessLib/RuntimeQNCAccessLib.inf      |   43 +
> > .../Library/QNCSmmLib/QNCSmmLib.c             |  313 ++
> > .../Library/QNCSmmLib/QNCSmmLib.inf           |   44 +
> > .../Library/ResetSystemLib/ResetSystemLib.c   |  379 ++
> > .../Library/ResetSystemLib/ResetSystemLib.inf |   46 +
> > .../Library/SmbusLib/CommonHeader.h           |   25 +
> > .../Library/SmbusLib/SmbusLib.c               |  797
> +++
> > .../Library/SmbusLib/SmbusLib.inf             |   47 +
> > .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.c     |  446 ++
> > .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf   |   30 +
> > .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.uni   |   12 +
> > .../MemoryInit/Pei/MemoryInit.c               |   59 +
> > .../MemoryInit/Pei/MemoryInit.h               |   35 +
> > .../MemoryInit/Pei/MemoryInitPei.inf          |   70 +
> > .../MemoryInit/Pei/core_types.h               |   43 +
> > .../MemoryInit/Pei/gen5_iosf_sb_definitions.h |  738
> +++
> > .../MemoryInit/Pei/general_definitions.h      |   84 +
> > .../QuarkNorthCluster/MemoryInit/Pei/hte.c    |  536 ++
> > .../QuarkNorthCluster/MemoryInit/Pei/hte.h    |   66 +
> > .../QuarkNorthCluster/MemoryInit/Pei/io.h     |  132 +
> > .../QuarkNorthCluster/MemoryInit/Pei/lprint.c |  382 ++
> > .../MemoryInit/Pei/meminit.c                  | 2638
> ++++++++++
> > .../MemoryInit/Pei/meminit.h                  |   22 +
> > .../MemoryInit/Pei/meminit_utils.c            | 1574
> ++++++
> > .../MemoryInit/Pei/meminit_utils.h            |   95 +
> > .../MemoryInit/Pei/memory_options.h           |   77 +
> > .../QuarkNorthCluster/MemoryInit/Pei/mrc.c    |   40 +
> > .../QuarkNorthCluster/MemoryInit/Pei/mrc.h    |  160 +
> > .../MemoryInit/Pei/platform.c                 |  186 +
> > .../MemoryInit/Pei/prememinit.c               |  187 +
> > .../MemoryInit/Pei/prememinit.h               |   15 +
> > .../QNCInit/Dxe/CommonHeader.h                |   49 +
> > .../QNCInit/Dxe/DxeQNCSmbus.c                 |  612
> +++
> > .../QNCInit/Dxe/DxeQNCSmbus.h                 |  205 +
> > .../QNCInit/Dxe/LegacyRegion.c                |  237 +
> > .../QNCInit/Dxe/LegacyRegion.h                |  198 +
> > .../QuarkNorthCluster/QNCInit/Dxe/QNCInit.c   |  518 ++
> > .../QuarkNorthCluster/QNCInit/Dxe/QNCInit.h   |   49 +
> > .../QNCInit/Dxe/QNCInitDxe.inf                |   92 +
> > .../QNCInit/Dxe/QNCRootPorts.c                |   76 +
> > .../QuarkNorthCluster/QNCInit/Dxe/QNCSmbus.h  |   80 +
> > .../QNCInit/Dxe/QNCSmbusExec.c                |  246 +
> > .../S3Support/Dxe/QncS3Support.c              |  417 ++
> > .../S3Support/Dxe/QncS3Support.h              |  117 +
> > .../S3Support/Dxe/QncS3Support.inf            |   64 +
> > .../Smm/Dxe/SmmAccessDxe/SmmAccess.inf        |   49 +
> > .../Smm/Dxe/SmmAccessDxe/SmmAccessDriver.c    |  405 ++
> > .../Smm/Dxe/SmmAccessDxe/SmmAccessDriver.h    |  230 +
> > .../Smm/Dxe/SmmControlDxe/SmmControlDriver.c  |  358 ++
> > .../Smm/Dxe/SmmControlDxe/SmmControlDxe.inf   |   55 +
> > .../DxeSmm/QncSmmDispatcher/CommonHeader.h    |   45 +
> > .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmGpi.c   |   32 +
> > .../QncSmmDispatcher/QNC/QNCSmmHelpers.c      |  549 ++
> > .../QNC/QNCSmmPeriodicTimer.c                 |  424 ++
> > .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmQncn.c  |  211 +
> > .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmSw.c    |   90 +
> > .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmSx.c    |  147 +
> > .../Smm/DxeSmm/QncSmmDispatcher/QNCSmm.h      |  868
> ++++
> > .../Smm/DxeSmm/QncSmmDispatcher/QNCSmmCore.c  |  825
> +++
> > .../QncSmmDispatcher/QNCSmmDispatcher.inf     |   81 +
> > .../DxeSmm/QncSmmDispatcher/QNCSmmHelpers.c   |  367 ++
> > .../DxeSmm/QncSmmDispatcher/QNCSmmHelpers.h   |  219 +
> > .../DxeSmm/QncSmmDispatcher/QNCSmmRegisters.h |   13 +
> > .../DxeSmm/QncSmmDispatcher/QNCxSmmHelpers.h  |  178 +
> > .../Smm/Pei/SmmAccessPei/SmmAccessPei.c       |  376 ++
> > .../Smm/Pei/SmmAccessPei/SmmAccessPei.inf     |   45 +
> > .../Smm/Pei/SmmControlPei/SmmControlPei.c     |  274 +
> > .../Smm/Pei/SmmControlPei/SmmControlPei.inf   |   51 +
> > .../QuarkNorthCluster/Spi/Common/SpiCommon.c  |  927
> ++++
> > .../QuarkNorthCluster/Spi/Common/SpiCommon.h  |  317 ++
> > .../QuarkNorthCluster/Spi/PchSpiRuntime.inf   |   84 +
> > .../QuarkNorthCluster/Spi/PchSpiSmm.inf       |   50 +
> > .../QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.c |  205 +
> > .../QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.h |   79 +
> > .../QuarkNorthCluster/Spi/Smm/PchSpi.c        |  123 +
> > .../QuarkNorthCluster/Spi/Smm/PchSpi.h        |   47 +
> > Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dec     |  234 +
> > Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dsc     |  254 +
> > .../QuarkSouthCluster/Include/CEATA.h         |  114 +
> > .../QuarkSouthCluster/Include/I2cRegs.h       |   95 +
> > .../QuarkSouthCluster/Include/Ioh.h           |  248 +
> > .../QuarkSouthCluster/Include/IohAccess.h     |   18 +
> > .../Include/IohCommonDefinitions.h            |  342 ++
> > .../Include/Library/I2cLib.h                  |  152 +
> > .../Include/Library/IohLib.h                  |   36 +
> > .../QuarkSouthCluster/Include/MMC.h           |  274 +
> > .../QuarkSouthCluster/Include/SDCard.h        |  146 +
> > .../QuarkSouthCluster/Include/SDHostIo.h      |  333 ++
> > .../IohInit/Dxe/CommonHeader.h                |   55 +
> > .../QuarkSouthCluster/IohInit/Dxe/IohBds.h    |   83 +
> > .../QuarkSouthCluster/IohInit/Dxe/IohData.c   |   42 +
> > .../QuarkSouthCluster/IohInit/Dxe/IohInit.c   |   37 +
> > .../IohInit/Dxe/IohInitDxe.inf                |   76 +
> > .../Library/I2cLib/CommonHeader.h             |  214 +
> > .../QuarkSouthCluster/Library/I2cLib/I2cLib.c |  998
> ++++
> > .../Library/I2cLib/I2cLib.inf                 |   62 +
> > .../Library/IohLib/CommonHeader.h             |   29 +
> > .../QuarkSouthCluster/Library/IohLib/IohLib.c |   99 +
> > .../Library/IohLib/IohLib.inf                 |   49 +
> > .../Sdio/Dxe/SDControllerDxe/ComponentName.c  |  227 +
> > .../Sdio/Dxe/SDControllerDxe/ComponentName.h  |  141 +
> > .../Sdio/Dxe/SDControllerDxe/SDController.c   | 1784
> +++++++
> > .../Sdio/Dxe/SDControllerDxe/SDController.h   |  316 ++
> > .../Dxe/SDControllerDxe/SDControllerDxe.inf   |   56 +
> > .../Sdio/Dxe/SDMediaDeviceDxe/CEATA.c         |  647
> +++
> > .../Sdio/Dxe/SDMediaDeviceDxe/CEATABlockIo.c  |  389 ++
> > .../Sdio/Dxe/SDMediaDeviceDxe/ComponentName.c |  215 +
> > .../Sdio/Dxe/SDMediaDeviceDxe/ComponentName.h |  139 +
> > .../Sdio/Dxe/SDMediaDeviceDxe/MMCSDBlockIo.c  |  538 ++
> > .../Sdio/Dxe/SDMediaDeviceDxe/MMCSDTransfer.c | 1708
> +++++++
> > .../Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.c |  317 ++
> > .../Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.h |  462 ++
> > .../Dxe/SDMediaDeviceDxe/SDMediaDeviceDxe.inf |   60 +
> > .../QuarkSouthCluster/Usb/Common/Pei/UsbPei.c |  320 ++
> > .../QuarkSouthCluster/Usb/Common/Pei/UsbPei.h |   38 +
> > .../Usb/Common/Pei/UsbPei.inf                 |   53 +
> > .../Usb/Ohci/Dxe/ComponentName.c              |  219 +
> > .../Usb/Ohci/Dxe/ComponentName.h              |  141 +
> > .../Usb/Ohci/Dxe/Descriptor.h                 |  132 +
> > .../QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.c     | 2473
> +++++++++
> > .../QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.h     |  663
> +++
> > .../Usb/Ohci/Dxe/OhciDebug.c                  |   78 +
> > .../Usb/Ohci/Dxe/OhciDebug.h                  |   42 +
> > .../Usb/Ohci/Dxe/OhciDxe.inf                  |   71 +
> > .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.c  | 1390
> +++++
> > .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.h  |  920
> ++++
> > .../Usb/Ohci/Dxe/OhciSched.c                  |  528 ++
> > .../Usb/Ohci/Dxe/OhciSched.h                  |  225 +
> > .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.c  |  889
> ++++
> > .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.h  |  387 ++
> > .../QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.c |  560 ++
> > .../QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.h |  152 +
> > .../Usb/Ohci/Pei/Descriptor.h                 |  131 +
> > .../QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.c  | 1386
> +++++
> > .../QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.h  |  252 +
> > .../Usb/Ohci/Pei/OhciPei.inf                  |   56 +
> > .../QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.c  | 1386
> +++++
> > .../QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.h  |  875
> ++++
> > .../Usb/Ohci/Pei/OhciSched.c                  |  223 +
> > .../Usb/Ohci/Pei/OhciSched.h                  |  108 +
> > .../QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.c  |  560 ++
> > .../QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.h  |  231 +
> > .../QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.c |  491 ++
> > .../QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.h |  134 +
> > .../AcpiTablesPCAT/98_LINK.ASL                |  617
> +++
> > .../AcpiTablesPCAT/AcpiTablePlatform.h        |   70 +
> > .../AcpiTablesPCAT/AcpiTables.inf             |   40 +
> > .../AcpiTablesPCAT/CPU.asl                    |   49 +
> > .../AcpiTablesPCAT/DSDT.ASL                   |   75 +
> > .../AcpiTablesPCAT/Facp/Facp.aslc             |  188 +
> > .../AcpiTablesPCAT/Facs/Facs.aslc             |   84 +
> > .../AcpiTablesPCAT/GloblNvs.asl               |  348 ++
> > .../AcpiTablesPCAT/Gpe.asl                    |   99 +
> > .../AcpiTablesPCAT/HOST_BUS.ASL               |  347 ++
> > .../AcpiTablesPCAT/Hpet/Hpet.aslc             |   63 +
> > .../AcpiTablesPCAT/INTELGFX.ASL               |  879
> ++++
> > .../AcpiTablesPCAT/INTELISPDev2.ASL           |   71 +
> > .../AcpiTablesPCAT/IgdOGBDA.ASL               |  155 +
> > .../AcpiTablesPCAT/IgdOMOBF.ASL               |  485 ++
> > .../AcpiTablesPCAT/IgdOSBCB.ASL               |  274 +
> > .../AcpiTablesPCAT/IgdOpRn.ASL                |  299 ++
> > .../AcpiTablesPCAT/IoTVirtualDevice.asl       |  171 +
> > .../AcpiTablesPCAT/LPC_DEV.ASL                |  151 +
> > .../AcpiTablesPCAT/LpcB.asl                   |   59 +
> > .../AcpiTablesPCAT/Lpit/Lpit.aslc             |  223 +
> > .../AcpiTablesPCAT/Madt/Madt.h                |  189 +
> > .../AcpiTablesPCAT/Madt/Madt30.aslc           |  178 +
> > .../AcpiTablesPCAT/Mcfg/Mcfg.aslc             |   86 +
> > .../AcpiTablesPCAT/PCI_DRC.ASL                |   90 +
> > .../AcpiTablesPCAT/Pch.asl                    |  686
> +++
> > .../AcpiTablesPCAT/PchAudio.asl               |   36 +
> > .../AcpiTablesPCAT/PchEhci.asl                |  269 +
> > .../AcpiTablesPCAT/PchLpss.asl                | 1093
> ++++
> > .../AcpiTablesPCAT/PchPcie.asl                |   50 +
> > .../AcpiTablesPCAT/PchScc.asl                 |  610
> +++
> > .../AcpiTablesPCAT/PchSmb.asl                 |  833
> +++
> > .../AcpiTablesPCAT/PchXhci.asl                |  379 ++
> > .../AcpiTablesPCAT/PciTree.asl                |  377 ++
> > .../AcpiTablesPCAT/Platform.asl               |  703
> +++
> > .../AcpiTablesPCAT/RTD3.asl                   |  197 +
> > .../AcpiTablesPCAT/RhProxy.asl                |  160 +
> > .../AcpiTablesPCAT/THERMAL.ASL                |  137 +
> > .../AcpiTablesPCAT/UsbSbd.asl                 |   93 +
> > .../AcpiTablesPCAT/Video.asl                  |   34 +
> > .../AcpiTablesPCAT/Vlv.asl                    |   39 +
> > .../AcpiTablesPCAT/Wsmt/Wsmt.aslc             |   54 +
> > .../AcpiTablesPCAT/token.asl                  |   39 +
> > .../Guid/Vlv2DeviceRefCodePkgTokenSpace.h     |   24 +
> > .../Include/Ppi/PttPassThruPpi.h              |   92 +
> > .../Include/Ppi/fTPMPolicy.h                  |   26 +
> > .../Include/Protocol/PttPassThru.h            |   91 +
> > .../Guid/PowerManagementAcpiTableStorage.h    |   27 +
> > .../CPU/Include/Ppi/VlvPolicy.h               |  104 +
> > .../CPU/Include/Protocol/PpmPlatformPolicy.h  |  132 +
> > .../ValleyView2Soc/CPU/Include/Types.h        |   55 +
> > .../AcpiTables/PowerManagementAcpiTables.inf  |   39 +
> > .../PowerManagement/AcpiTables/Ssdt/ApCst.asl |  110 +
> > .../PowerManagement/AcpiTables/Ssdt/ApIst.asl |  166 +
> > .../PowerManagement/AcpiTables/Ssdt/ApTst.asl |  262 +
> > .../AcpiTables/Ssdt/Cpu0Cst.asl               |  274 +
> > .../AcpiTables/Ssdt/Cpu0Ist.asl               |  260 +
> > .../AcpiTables/Ssdt/Cpu0Tst.asl               |  235 +
> > .../PowerManagement/AcpiTables/Ssdt/CpuPm.asl |  793
> +++
> > .../Include/PlatformBaseAddresses.h           |   92 +
> > .../NorthCluster/Include/Ppi/Capsule.h        |   60 +
> > .../Include/Ppi/PlatformMemoryRange.h         |  144 +
> > .../Include/Ppi/PlatformMemorySize.h          |   46 +
> > .../NorthCluster/Include/Ppi/SmmAccess.h      |  165 +
> > .../NorthCluster/Include/Ppi/VlvMmioPolicy.h  |   39 +
> > .../NorthCluster/Include/Ppi/VlvPeiInit.h     |   35 +
> > .../NorthCluster/Include/Ppi/VlvPolicy.h      |  106 +
> > .../Include/Protocol/IgdOpRegion.h            |  213 +
> > .../NorthCluster/Include/Protocol/MemInfo.h   |   83 +
> > .../Include/Protocol/PlatformGopPolicy.h      |   67 +
> > .../Include/Protocol/VlvPlatformPolicy.h      |  105 +
> > .../NorthCluster/Include/Valleyview.h         |   55 +
> > .../NorthCluster/Include/VlvAccess.h          |  254 +
> > .../Include/VlvCommonDefinitions.h            |  252 +
> > .../SouthCluster/Include/Guid/PchInitVar.h    |   48 +
> > .../Include/Guid/SataControllerGuid.h         |   34 +
> > .../SouthCluster/Include/Guid/SmbusArpMap.h   |   30 +
> > .../SouthCluster/Include/Guid/Vlv2Variable.h  |   28 +
> > .../Include/IndustryStandard/CeAta.h          |  126 +
> > .../Include/IndustryStandard/Mmc.h            |  349 ++
> > .../Include/IndustryStandard/SdCard.h         |  157 +
> > .../SouthCluster/Include/Library/I2CLib.h     |  169 +
> > .../Include/Library/PchPlatformLib.h          |  115 +
> > .../SouthCluster/Include/PchAccess.h          |  471 ++
> > .../Include/PchCommonDefinitions.h            |  210 +
> > .../SouthCluster/Include/PchRegs.h            |  205 +
> > .../SouthCluster/Include/PchRegs/PchRegsHda.h |   50 +
> > .../Include/PchRegs/PchRegsLpss.h             |  486 ++
> > .../Include/PchRegs/PchRegsPcie.h             |   83 +
> > .../SouthCluster/Include/PchRegs/PchRegsPcu.h | 1201
> +++++
> > .../Include/PchRegs/PchRegsRcrb.h             |   48 +
> > .../Include/PchRegs/PchRegsSata.h             |  245 +
> > .../SouthCluster/Include/PchRegs/PchRegsScc.h |   53 +
> > .../Include/PchRegs/PchRegsSmbus.h            |  149 +
> > .../SouthCluster/Include/PchRegs/PchRegsSpi.h |  119 +
> > .../SouthCluster/Include/PchRegs/PchRegsUsb.h |   92 +
> > .../SouthCluster/Include/Ppi/PchInit.h        |   75 +
> > .../SouthCluster/Include/Ppi/PchPeiInit.h     |   34 +
> > .../Include/Ppi/PchPlatformPolicy.h           |  161 +
> > .../SouthCluster/Include/Ppi/PchUsbPolicy.h   |   69 +
> > .../SouthCluster/Include/Ppi/PeiBlockIo.h     |  230 +
> > .../SouthCluster/Include/Ppi/Sdhc.h           |  359 ++
> > .../SouthCluster/Include/Ppi/SmbusPolicy.h    |   40 +
> > .../SouthCluster/Include/Ppi/Spi.h            |   42 +
> > .../Include/Protocol/ActiveBios.h             |  123 +
> > .../Include/Protocol/ActiveBiosProtocol.h     |  125 +
> > .../Protocol/DxePchPolicyUpdateProtocol.h     |   51 +
> > .../Include/Protocol/EmmcCardInfoProtocol.h   |   42 +
> > .../SouthCluster/Include/Protocol/Gpio.h      |  161 +
> > .../Include/Protocol/HwWatchdogTimer.h        |  294 ++
> > .../SouthCluster/Include/Protocol/I2cBus.h    |  164 +
> > .../Include/Protocol/PchExtendedReset.h       |   84 +
> > .../SouthCluster/Include/Protocol/PchInfo.h   |   60 +
> > .../Include/Protocol/PchPlatformPolicy.h      |  550 ++
> > .../SouthCluster/Include/Protocol/PchReset.h  |  114 +
> > .../Include/Protocol/PchS3Support.h           |  132 +
> > .../SouthCluster/Include/Protocol/SdHostIo.h  |  409 ++
> > .../Include/Protocol/SmbiosSlotPopulation.h   |   47 +
> > .../Include/Protocol/SmmIchnDispatchEx.h      |  159 +
> > .../SouthCluster/Include/Protocol/SmmSmbus.h  |   39 +
> > .../SouthCluster/Include/Protocol/Spi.h       |  260 +
> > .../SouthCluster/Include/Protocol/TcoReset.h  |   88 +
> > .../SouthCluster/Include/Rsci.h               |   28 +
> > .../SouthCluster/Include/TianoApi.h           |   61 +
> > .../Vlv2DeviceRefCodePkg.dec                  |  231 +
> > .../Omap35xxPkg/Flash/Flash.c                 |  768
> +++
> > .../Omap35xxPkg/Flash/Flash.h                 |  100 +
> > .../Omap35xxPkg/Flash/Flash.inf               |   42 +
> > .../TexasInsturments/Omap35xxPkg/Gpio/Gpio.c  |  129 +
> > .../Omap35xxPkg/Gpio/Gpio.inf                 |   39 +
> > .../Omap35xxPkg/Include/Library/OmapDmaLib.h  |   84 +
> > .../Omap35xxPkg/Include/Library/OmapLib.h     |   38 +
> > .../Omap35xxPkg/Include/Omap3530/Omap3530.h   |   34 +
> > .../Include/Omap3530/Omap3530Dma.h            |  124 +
> > .../Include/Omap3530/Omap3530Gpio.h           |  125 +
> > .../Include/Omap3530/Omap3530Gpmc.h           |  101 +
> > .../Include/Omap3530/Omap3530I2c.h            |   56 +
> > .../Include/Omap3530/Omap3530Interrupt.h      |   45 +
> > .../Include/Omap3530/Omap3530MMCHS.h          |  208 +
> > .../Omap3530/Omap3530PadConfiguration.h       |  297 ++
> > .../Include/Omap3530/Omap3530Prcm.h           |  159 +
> > .../Include/Omap3530/Omap3530Timer.h          |   76 +
> > .../Include/Omap3530/Omap3530Uart.h           |   48 +
> > .../Include/Omap3530/Omap3530Usb.h            |   42 +
> > .../Omap35xxPkg/Include/TPS65950.h            |   74 +
> > .../InterruptDxe/HardwareInterrupt.c          |  396 ++
> > .../Omap35xxPkg/InterruptDxe/InterruptDxe.inf |   48 +
> > .../LcdGraphicsOutputBlt.c                    |  439 ++
> > .../LcdGraphicsOutputDxe.c                    |  394 ++
> > .../LcdGraphicsOutputDxe.h                    |  151 +
> > .../LcdGraphicsOutputDxe.inf                  |   46 +
> > .../DebugAgentTimerLib/DebugAgentTimerLib.c   |  159 +
> > .../DebugAgentTimerLib/DebugAgentTimerLib.inf |   42 +
> > .../Library/GdbSerialLib/GdbSerialLib.c       |   96 +
> > .../Library/GdbSerialLib/GdbSerialLib.inf     |   35 +
> > .../Omap35xxTimerLib/Omap35xxTimerLib.inf     |   40 +
> > .../Library/Omap35xxTimerLib/TimerLib.c       |  151 +
> > .../Library/OmapDmaLib/OmapDmaLib.c           |  170 +
> > .../Library/OmapDmaLib/OmapDmaLib.inf         |   43 +
> > .../Omap35xxPkg/Library/OmapLib/OmapLib.c     |   77 +
> > .../Omap35xxPkg/Library/OmapLib/OmapLib.inf   |   31 +
> > .../RealTimeClockLib/RealTimeClockLib.c       |  291 ++
> > .../RealTimeClockLib/RealTimeClockLib.inf     |   32 +
> > .../Library/SerialPortLib/SerialPortLib.c     |  208 +
> > .../Library/SerialPortLib/SerialPortLib.inf   |   40 +
> > .../Omap35xxPkg/MMCHSDxe/MMCHS.c              | 1492
> ++++++
> > .../Omap35xxPkg/MMCHSDxe/MMCHS.h              |  169 +
> > .../Omap35xxPkg/MMCHSDxe/MMCHS.inf            |   48 +
> > .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.c       |  671
> +++
> > .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.h       |   38 +
> > .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf     |   47 +
> > .../Omap35xxPkg/Omap35xxPkg.dec               |   52 +
> > .../Omap35xxPkg/Omap35xxPkg.dsc               |  183 +
> > .../Omap35xxPkg/PciEmulation/PciEmulation.c   |  107 +
> > .../Omap35xxPkg/PciEmulation/PciEmulation.inf |   41 +
> > .../Omap35xxPkg/SmbusDxe/Smbus.c              |  319 ++
> > .../Omap35xxPkg/SmbusDxe/Smbus.inf            |   39 +
> > .../Omap35xxPkg/TPS65950Dxe/TPS65950.c        |  110 +
> > .../Omap35xxPkg/TPS65950Dxe/TPS65950.inf      |   42 +
> > .../Omap35xxPkg/TimerDxe/Timer.c              |  370 ++
> > .../Omap35xxPkg/TimerDxe/TimerDxe.inf         |   51 +
> > 1103 files changed, 259532 insertions(+)
> > create mode 100644
> >Drivers/OptionRomPkg/Application/BltLibSample/BltLibSamp
> le.c
> > create mode 100644
> >Drivers/OptionRomPkg/Application/BltLibSample/BltLibSamp
> le.inf
> > create mode 100644
> >Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.c
> > create mode 100644
> >Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.h
> > create mode 100644
> >Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThruDxe.i
> nf
> > create mode 100644
> >Drivers/OptionRomPkg/AtapiPassThruDxe/ComponentName.c
> > create mode 100644
> >Drivers/OptionRomPkg/AtapiPassThruDxe/DriverSupportedEfi
> Version.c
> > create mode 100644
> >Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/Compatible
> Devices.txt
> > create mode 100644
> >Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ComponentN
> ame.c
> > create mode 100644
> >Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSer
> ialDriver.c
> > create mode 100644
> >Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSer
> ialDriver.h
> > create mode 100644
> >Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSer
> ialDxe.inf
> > create mode 100644
> >Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt
> > create mode 100644
> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax887
> 72.c
> > create mode 100644
> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax887
> 72.h
> > create mode 100644
> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax887
> 72.inf
> > create mode 100644
> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Compo
> nentName
> >.c
> > create mode 100644
> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Drive
> rBinding.c
> > create mode 100644
> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Simpl
> eNetwork.c
> > create mode 100644
> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88
> 772.c
> > create mode 100644
> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88
> 772.h
> > create mode 100644
> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88
> 772b.inf
> > create mode 100644
> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Comp
> onentNam
> >e.c
> > create mode 100644
> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Driv
> erBinding.c
> > create mode 100644
> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Simp
> leNetwork.
> >c
> > create mode 100644
> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.
> c
> > create mode 100644
> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.
> h
> > create mode 100644
> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430D
> xe.inf
> > create mode 100644
> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430G
> raphicsOutput.c
> > create mode 100644
> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I
> 2c.c
> > create mode 100644
> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I
> 2c.h
> > create mode 100644
> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430U
> gaDraw.c
> > create mode 100644
> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/ComponentName.c
> > create mode 100644
> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/DriverSupportedE
> fiVersion.c
> > create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/Edid.c
> > create mode 100644
> Drivers/OptionRomPkg/Include/Library/BltLib.h
> > create mode 100644
> >Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBuff
> erBltLib.c
> > create mode 100644
> >Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBuff
> erBltLib.inf
> > create mode 100644
> Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.c
> > create mode 100644
> Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.inf
> > create mode 100644
> Drivers/OptionRomPkg/OptionRomPkg.dec
> > create mode 100644
> Drivers/OptionRomPkg/OptionRomPkg.dsc
> > create mode 100644 Drivers/OptionRomPkg/ReadMe.txt
> > create mode 100644
> >Drivers/OptionRomPkg/UndiRuntimeDxe/ComponentName.c
> > create mode 100644
> Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c
> > create mode 100644
> Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c
> > create mode 100644
> Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h
> > create mode 100644
> Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c
> > create mode 100644
> Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h
> > create mode 100644
> Drivers/OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c
> > create mode 100644
> >Drivers/OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.dec
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.dsc
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.fdf
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/ConfigurationHeader.
> bin
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/ConfigurationHeader.
> dat
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi
> _boot_from_ra
> >m.inc
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi
> _convert_symb
> >ols.sh
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi
> _dummy.axf
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi
> _hw_setup.inc
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi
> _load_symbols.i
> >nc
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi
> _symbols_macr
> >os.inc
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi
> _unload_symbo
> >ls.inc
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/tra
> ce32_load_sym
> >bols.cmm
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/tra
> ce32_load_sym
> >bols_cygwin.cmm
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Include/BeagleBoard.
> h
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardL
> ib/BeagleBoard.
> >c
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardL
> ib/BeagleBoard
> >Helper.S
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardL
> ib/BeagleBoard
> >Helper.asm
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardL
> ib/BeagleBoard
> >Lib.inf
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardL
> ib/BeagleBoard
> >Mem.c
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardL
> ib/Clock.c
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardL
> ib/PadConfigura
> >tion.c
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Library/DxeHobPeCoff
> Lib/DxeHobPe
> >Coff.c
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Library/DxeHobPeCoff
> Lib/DxeHobPe
> >CoffLib.inf
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Library/LzmaHobCusto
> mDecompress
> >Lib/LzmaHobCustomDecompressLib.c
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Library/LzmaHobCusto
> mDecompress
> >Lib/LzmaHobCustomDecompressLib.inf
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Library/MemoryInitPe
> iLib/MemoryIn
> >itPeiLib.c
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Library/MemoryInitPe
> iLib/MemoryIn
> >itPeiLib.inf
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Library/ResetSystemL
> ib/ResetSyste
> >mLib.c
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Library/ResetSystemL
> ib/ResetSyste
> >mLib.inf
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ArchPrePi.
> c
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ModuleEntr
> yPoint.S
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ModuleEntr
> yPoint.asm
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/PrePi/LzmaDecompress
> .h
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/PrePi/MainUniCore.c
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/PrePi/PeiUniCore.inf
> > create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/PrePi/PrePi.c
> > create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/PrePi/PrePi.h
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Tools/GNUmakefile
> > create mode 100644
> >Platform/BeagleBoard/BeagleBoardPkg/Tools/generate_image
> .c
> > create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Tools/makefile
> > create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Tools/replace.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/AcpiTabl
> es.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Cst/
> Cpu0Cst.asl
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Ist/
> Cpu0Ist.asl
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Tst/
> Cpu0Tst.asl
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/CpuPm/Cp
> uPm.asl
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/AD7
> 298.asi
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/ADC
> 108S102.asi
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/CAT
> 24C08.asi
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/CY8
> C9540A.asi
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Gpi
> oClient.asi
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Lpc
> Dev.asi
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PCA
> 9685.asi
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PCA
> L9555A.asi
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Pci
> HostBridge.asi
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Pci
> Irq.asi
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Pci
> eExpansionPrt.asi
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Pla
> tform.asl
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNC
> .asi
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNC
> Apic.asi
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNC
> Lpc.asi
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Qua
> rkSouthCluster.a
> >si
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Tpm
> .asi
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Facs/Fac
> s.aslc
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Facs/Fac
> s.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fad
> t.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fad
> t1.0.aslc
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fad
> t2.0.aslc
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Hpet/Hpe
> t.aslc
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Hpet/Hpe
> t.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Mcfg/Mcf
> g.aslc
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Mcfg/Mcf
> g.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Ac
> piPciUpdate.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Ac
> piPciUpdate.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Ac
> piPlatform.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Ac
> piPlatform.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Ac
> piPlatform.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Ma
> dt.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Ma
> dtPlatform.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecu
> torDxe/BootScri
> >ptExecutorDxe.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecu
> torDxe/IA32/S3A
> >sm.S
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecu
> torDxe/IA32/S3A
> >sm.asm
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecu
> torDxe/IA32/Set
> >IdtEntry.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecu
> torDxe/ScriptExe
> >cute.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecu
> torDxe/ScriptExe
> >cute.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/Acpi
> SmmPlatfor
> >m.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/Acpi
> SmmPlatfor
> >m.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/Acpi
> SmmPlatfor
> >m.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerMana
> gement/P
> >pm.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerMana
> gement/P
> >pm.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerMana
> gement/S
> >mmPowerManagement.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerMana
> gement/S
> >mmPowerManagement.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerMana
> gement/S
> >mmPowerManagement.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Application/ForceRecover
> y/ForceRecovery
> >.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Application/ForceRecover
> y/ForceRecovery
> >.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/
> PlatformFlashAcc
> >essLib/PlatformFlashAccessLibDxe.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/
> PlatformFlashAcc
> >essLib/PlatformFlashAccessLibDxe.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/
> PlatformFlashAcc
> >essLib/SpiFlashDevice.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/
> PlatformFlashAcc
> >essLib/SpiFlashDevice.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFi
> rmwareDescript
> >or/SystemFirmwareDescriptor.aslc
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFi
> rmwareDescript
> >or/SystemFirmwareDescriptor.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFi
> rmwareDescript
> >or/SystemFirmwareDescriptorPei.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFi
> rmwareUpdateC
> >onfig/SystemFirmwareUpdateConfig.ini
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnDa
> taCD.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFa
> tFloppyDisk.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFa
> tIdeDisk.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFa
> tUsbDisk.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Include/Guid/MemoryConfi
> gData.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Include/Guid/QuarkCapsul
> eGuid.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Include/Guid/QuarkVariab
> leLock.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Include/Guid/SystemNvDat
> aHobGuid.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Include/Library/Platform
> HelperLib.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Include/Library/Platform
> PcieHelperLib.h
> > create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Pcal9555.h
> > create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Platform.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Include/PlatformBoards.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Include/Protocol/GlobalN
> vsArea.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Include/Protocol/Platfor
> mSmmSpiReady.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/PlatformBootMana
> gerLib/Platform
> >BootManager.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/PlatformBootMana
> gerLib/Platform
> >BootManager.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/PlatformBootMana
> gerLib/Platform
> >BootManagerLib.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/PlatformBootMana
> gerLib/Platform
> >Data.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLi
> b/CommonHeader
> >.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLi
> b/DxePlatformHel
> >perLib.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLi
> b/PeiPlatformHelp
> >erLib.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLi
> b/PlatformHelper
> >Dxe.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLi
> b/PlatformHelperL
> >ib.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLi
> b/PlatformHelper
> >Pei.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLi
> b/PlatformLeds.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelp
> erLib/CommonHe
> >ader.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelp
> erLib/PlatformPci
> >eHelperLib.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelp
> erLib/PlatformPci
> >eHelperLib.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelp
> erLib/SocUnit.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/I
> a32/Flat32.S
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/I
> a32/Flat32.asm
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/I
> a32/Platform.inc
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/P
> latformSecLib.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/P
> latformSecLib.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/P
> latformSecLibMod
> >Strs.uni
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecureLi
> b/PlatformSecure
> >Lib.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecureLi
> b/PlatformSecure
> >Lib.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAt
> melI2c/TisPc.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAt
> melI2c/Tpm12De
> >viceLibAtmelI2c.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAt
> melI2c/Tpm12De
> >viceLibAtmelI2c.uni
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibIn
> fineonI2c/TisPc.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibIn
> fineonI2c/Tpm12
> >DeviceLibInfineonI2c.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibIn
> fineonI2c/Tpm12
> >DeviceLibInfineonI2c.uni
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/Pc
> iHostBridge.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/Pc
> iHostBridge.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/Pc
> iHostBridge.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/Pc
> iHostBridgeSupp
> >ort.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/Pc
> iHostResource.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/Pc
> iRootBridge.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/Pc
> iRootBridgeIo.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/Comm
> onHeader.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciP
> latform.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciP
> latform.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciP
> latform.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubCl
> ass/MemoryS
> >ubClass.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubCl
> ass/MemoryS
> >ubClass.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubCl
> ass/MemoryS
> >ubClass.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubCl
> ass/MemoryS
> >ubClassStrings.uni
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformIni
> t/PlatformConfig.
> >c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformIni
> t/PlatformInitDxe
> >.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformIni
> t/PlatformInitDxe
> >.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformIni
> t/PlatformInitDxe
> >.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SaveMemoryC
> onfig/SaveM
> >emoryConfig.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SaveMemoryC
> onfig/SaveM
> >emoryConfig.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/Commo
> nHeader.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/DxePl
> atform.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/Keybo
> ardLayout.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/QNCRe
> gTable.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/Setup
> Platform.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/Setup
> Platform.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/Strin
> gs.uni
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/proce
> ssor.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/CommonHe
> >ader.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscBaseBo
> >ardManufacturer.uni
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscBaseBo
> >ardManufacturerData.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscBaseBo
> >ardManufacturerFunction.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscBiosVe
> >ndor.uni
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscBiosVe
> >ndorData.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscBiosVe
> >ndorFunction.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscBootInf
> >ormationData.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscBootInf
> >ormationFunction.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscChassis
> >Manufacturer.uni
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscChassis
> >ManufacturerData.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscChassis
> >ManufacturerFunction.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscDevice
> >Path.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscNumbe
> >rOfInstallableLanguagesData.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscNumbe
> >rOfInstallableLanguagesFunction.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscOemSt
> >ring.uni
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscOemSt
> >ringData.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscOemSt
> >ringFunction.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscOnboar
> >dDevice.uni
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscOnboar
> >dDeviceData.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscOnboar
> >dDeviceFunction.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscPortInt
> >ernalConnectorDesignator.uni
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscPortInt
> >ernalConnectorDesignatorData.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscPortInt
> >ernalConnectorDesignatorFunction.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscSystem
> >Manufacturer.uni
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscSystem
> >ManufacturerData.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscSystem
> >ManufacturerFunction.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscSystem
> >OptionString.uni
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscSystem
> >OptionStringData.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscSystem
> >OptionStringFunction.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscSystem
> >SlotDesignation.uni
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscSystem
> >SlotDesignationData.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscSystem
> >SlotDesignationFunction.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/MiscSystem
> >SlotOnboardDevices.uni
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/SmbiosMisc
> >.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/SmbiosMisc
> >DataTable.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/SmbiosMisc
> >Dxe.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/SmbiosMisc
> >EntryPoint.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> xe/SmbiosMisc
> >Strings.uni
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformCon
> fig/PlatformConf
> >igPei.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformCon
> fig/PlatformConf
> >igPei.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> t/BootMode.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> t/CommonHeader
> >.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> t/Generic/Recove
> >ry.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> t/MemoryCallback
> >.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> t/MrcWrapper.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> t/MrcWrapper.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> t/PeiFvSecurity.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> t/PeiFvSecurity.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> t/PlatformEarlyInit
> >.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> t/PlatformEarlyInit
> >.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> t/PlatformEarlyInit
> >.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> t/PlatformErratas.
> >c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
> FvbInfo.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
> FwBlockService.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
> FwBlockService.h
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
> PlatformSmmSpi.
> >c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
> PlatformSmmSpi.i
> >nf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
> PlatformSpi.inf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
> SpiFlashDevice.c
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
> SpiFlashDevice.h
> > create mode 100644
> Platform/Intel/QuarkPlatformPkg/Quark.dsc
> > create mode 100644
> Platform/Intel/QuarkPlatformPkg/Quark.fdf
> > create mode 100644
> Platform/Intel/QuarkPlatformPkg/QuarkMin.dsc
> > create mode 100644
> Platform/Intel/QuarkPlatformPkg/QuarkMin.fdf
> > create mode 100644
> >Platform/Intel/QuarkPlatformPkg/QuarkPlatformPkg.dec
> > create mode 100644
> Platform/Intel/QuarkPlatformPkg/Readme.md
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/.gitignore
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatfo
> rm.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatfo
> rm.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatfo
> rm.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatfo
> rmHooks.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatfo
> rmHooks.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatfo
> rmHooksLib.h
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpd
> ate/FirmwareUp
> >date.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpd
> ate/FirmwareUp
> >date.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpd
> ate/FirmwareUp
> >date.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpd
> ate/FirmwareUp
> >dateStrings.uni
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64D.env
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64R.env
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/BootS
> criptSaveDxe.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/Inter
> nalBootScriptSave
> >.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/Scrip
> tSave.c
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.bat
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.sh
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FCE.exe
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> eCapsule/GenCa
> >psuleAll.bat
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> eCapsule/GenCa
> >psuleAll.sh
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> eCapsule/GenCa
> >psuleMinnowMax.bat
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> eCapsule/GenCa
> >psuleMinnowMax.sh
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> eCapsule/GenCa
> >psuleMinnowMaxRelease.bat
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> eCapsule/GenCa
> >psuleMinnowMaxRelease.sh
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> eCapsule/GenCa
> >psuleSampleColor.bat
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> eCapsule/GenCa
> >psuleSampleColor.sh
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> eCapsule/Lvfs.dd
> >f
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> eCapsule/LvfsGe
> >nCapsuleMinnowMax.bat
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> eCapsule/LvfsGe
> >nCapsuleMinnowMaxRelease.bat
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> eCapsule/LvfsGe
> >nCapsuleSampleColor.bat
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> eCapsule/NewR
> >oot.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7Cer
> tBufferXdr.i
> >nc
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> eCapsule/SAMPL
> >E_DEVELOPMENT.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevi
> cePkcs7C
> >ertBufferXdr.inc
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> eCapsule/SAMPL
> >E_DEVELOPMENT_SAMPLE_PRODUCTION.cer.gFmpDevicePkgTokenSp
> aceGu
> >id.PcdFmpDevicePkcs7CertBufferXdr.inc
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> eCapsule/templa
> >te.metainfo.xml
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library
> /FmpDeviceLib/Fm
> >pDeviceLib.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library
> /FmpDeviceLib/Fm
> >pDeviceLib.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library
> /FmpDeviceLibSa
> >mple/FmpDeviceLib.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library
> /FmpDeviceLibSa
> >mple/FmpDeviceLib.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library
> /PlatformFlashAcc
> >essLib/PlatformFlashAccessLib.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library
> /PlatformFlashAcc
> >essLib/PlatformFlashAccessLib.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemF
> irmwareDescript
> >or/SystemFirmwareDescriptor.aslc
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemF
> irmwareDescript
> >or/SystemFirmwareDescriptor.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemF
> irmwareDescript
> >or/SystemFirmwareDescriptorPei.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemF
> irmwareUpdateC
> >onfig/SystemFirmwareUpdateConfig.ini
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemF
> irmwareUpdateC
> >onfig/SystemFirmwareUpdateConfigGcc.ini
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FmpCertificate.dsc
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FmpGreenSampleDevice.ds
> c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FspAzaliaConfigData/Aza
> liaConfig.bin
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/
> BootModePei.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/
> BootModePei.i
> >nf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiF
> spHobProcessLibVl
> >v2/FspHobProcessLibVlv2.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiF
> spHobProcessLibVl
> >v2/FspHobProcessLibVlv2.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> spPlatformSecLibV
> >lv2/FspPlatformSecLibVlv2.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> spPlatformSecLibV
> >lv2/FspPlatformSecLibVlv2.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> spPlatformSecLibV
> >lv2/Ia32/AsmSaveSecContext.asm
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> spPlatformSecLibV
> >lv2/Ia32/Fsp.inc
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> spPlatformSecLibV
> >lv2/Ia32/PeiCoreEntry.asm
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> spPlatformSecLibV
> >lv2/Ia32/SecEntry.asm
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> spPlatformSecLibV
> >lv2/Ia32/Stack.S
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> spPlatformSecLibV
> >lv2/Ia32/Stack.asm
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> spPlatformSecLibV
> >lv2/PlatformInit.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> spPlatformSecLibV
> >lv2/SaveSecContext.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> spPlatformSecLibV
> >lv2/SecGetPerformance.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> spPlatformSecLibV
> >lv2/SecPlatformInformation.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> spPlatformSecLibV
> >lv2/SecRamInitData.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> spPlatformSecLibV
> >lv2/SecTempRamSupport.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> spPlatformSecLibV
> >lv2/UartInit.c
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbRuntim
> eDxe.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServic
> e.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServic
> e.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServic
> eDxe.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServic
> eSmm.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmm.in
> f
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmCom
> mon.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe
> .c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe
> .h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe
> .inf
> > create mode 100755
> Platform/Intel/Vlv2TbltDevicePkg/GenBiosId
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/GenBiosId.exe
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/AlertStandardFo
> rmatTable.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/ChipsetAccess.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/CommonIncludes.
> h
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/CpuType.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/FileHandleLib.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AcpiTableS
> torage.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AlertStand
> ardFormat.h
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BiosId.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BoardFeatu
> res.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/EfiVpdData
> .h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/FirmwareId
> .h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/HwWatchdog
> TimerHob.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/IdccData.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/ItkData.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/MemoryConf
> igData.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/OsSelectio
> n.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PciLanInfo
> .h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformCp
> uInfo.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformIn
> fo.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SensorInfo
> Variable.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SetupVaria
> ble.h
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Hpet.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/BiosIdL
> ib.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/CpuIA32
> .h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/EfiRegT
> ableLib.h
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Esrt.h
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Fd.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/FlashDe
> viceLib.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2CLib.
> h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cMmio
> ConfigLib.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cPort
> _platform.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Platfor
> mFsaLib.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Platfor
> mFspLib.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/SpiFlas
> h.H
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/StallSm
> mLib.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/UsbDevi
> ceModeLib.h
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Mcfg.h
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/McfgTable.h
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Platform.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformBootMod
> e.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformDefinit
> ions.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/MfgMemoryTe
> st.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Sha256Hash.
> h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Speaker.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/UsbControll
> er.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/CK505C
> lockPlatformInfo.
> >h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Enhanc
> edSpeedstep.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Global
> NvsArea.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/HwWatc
> hdogTimer.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cAcp
> i.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBus
> .h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBus
> Mcg.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cHos
> tMcg.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cMas
> terMcg.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cSla
> ve.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpc
> 83627Policy.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpc
> e791Policy.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/MmioDe
> vice.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Observ
> able.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Platfo
> rmGopPolicy.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Platfo
> rmIdeInit.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SetupM
> ode.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Smbios
> SlotPopulation.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Speake
> r.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TcoRes
> et.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TpmMp.
> h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/UsbPol
> icy.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/VlvPla
> tformPolicy.h
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/SetupMode.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/IntelGopDepex/IntelGopD
> river.depex
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosI
> dLib.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosI
> dLib.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/CpuI
> A32Lib.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/EfiC
> puVersion.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32
> /CpuIA32.S
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32
> /CpuIA32.asm
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32
> /CpuIA32.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/
> Cpu.S
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/
> Cpu.asm
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/
> EfiRegTableLib.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/
> EfiRegTableLib.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/
> FlashDeviceLib.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/
> FlashDeviceLib.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/
> FlashDeviceLibDxe.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/
> FlashDeviceLibDxe.i
> >nf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/
> FlashDeviceLibDxeR
> >untimeSmm.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/
> SpiChipDefinitions.h
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLibNu
> ll.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLi
> b.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLi
> bDxe.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CRe
> gs.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CAc
> cess.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDe
> layPei.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDe
> layPei.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIo
> LibPei.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIo
> LibPei.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLi
> bPei.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLi
> bPei.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLi
> bPei.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTim
> erLib/CommonHea
> >der.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTim
> erLib/IntelPchAcpiT
> >imerLib.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTim
> erLib/IntelPchAcpiT
> >imerLib.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> b/BoardClkGens/Bo
> >ardClkGens.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> b/BoardClkGens/Bo
> >ardClkGens.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> b/BoardGpios/Boar
> >dGpios.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> b/BoardGpios/Boar
> >dGpios.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> b/BoardJumpers/Bo
> >ardJumpers.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> b/BoardJumpers/Bo
> >ardJumpers.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> b/BoardOemIds/Bo
> >ardOemIds.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> b/BoardOemIds/Bo
> >ardOemIds.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> b/BoardSsidSvid/Bo
> >ardSsidSvid.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> b/BoardSsidSvid/Bo
> >ardSsidSvid.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> b/MultiPlatformLib.
> >c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> b/MultiPlatformLib.
> >h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> b/MultiPlatformLib.i
> >nf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> b/PlatformInfoHob.
> >c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/
> PchPlatformLib.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/
> PchPlatformLibrary.
> >c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/
> PchPlatformLibrary.
> >h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/Commo
> nHeader.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSm
> mLib.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSm
> mLib.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/
> BdsPlatform.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/
> BdsPlatform.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/
> PlatformBdsLib.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/
> PlatformBdsStrings.
> >uni
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/
> PlatformData.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib
> /PlatformCmosLib.
> >c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib
> /PlatformCmosLib.
> >inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/
> PlatformFspLib.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/
> PlatformFspLib.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/
> ResetSystemLib.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/
> ResetSystemLib.in
> >f
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/P
> latformSerialPortLib.
> >h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/S
> erialPortLib.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/S
> erialPortLib.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/S
> ioInit.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/S
> ioInit.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/Common
> Header.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusL
> ib.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusL
> ib.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/Sta
> llSmm.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/Sta
> llSmmLib.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSe
> CDxe/Tpm2Devic
> >eLibSeC.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSe
> CDxe/Tpm2Devic
> >eLibSeC.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSe
> CPei/Tpm2Device
> >LibSeC.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSe
> CPei/Tpm2Device
> >LibSeC.inf
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Logo/Logo.bmp
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetrono
> me.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetrono
> me.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Metronome/Metronome.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/EfiStatu
> sCode.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStat
> usCode.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStat
> usCode.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStat
> usCode.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PeiPostC
> ode.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/Platform
> StatusCode.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/Platform
> StatusCode.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
> ModulePkg/Libra
> >ry/GenericBdsLib/BdsBoot.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
> ModulePkg/Libra
> >ry/GenericBdsLib/BdsConnect.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
> ModulePkg/Libra
> >ry/GenericBdsLib/BdsConsole.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
> ModulePkg/Libra
> >ry/GenericBdsLib/BdsMisc.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
> ModulePkg/Libra
> >ry/GenericBdsLib/DevicePath.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
> ModulePkg/Libra
> >ry/GenericBdsLib/GenericBdsLib.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
> ModulePkg/Libra
> >ry/GenericBdsLib/GenericBdsLib.uni
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
> ModulePkg/Libra
> >ry/GenericBdsLib/GenericBdsStrings.uni
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
> ModulePkg/Libra
> >ry/GenericBdsLib/InternalBdsLib.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
> ModulePkg/Libra
> >ry/GenericBdsLib/String.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
> ModulePkg/Libra
> >ry/GenericBdsLib/String.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/BoardPciPla
> tform.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform
> .c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform
> .h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform
> .inf
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.dsc
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.fdf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/Plat
> formCpuInfoDxe.
> >c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/Plat
> formCpuInfoDxe.
> >h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/Plat
> formCpuInfoDxe.i
> >nf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/AzaliaVerbT
> able.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardId.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDeco
> de.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDeco
> de.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ClockContro
> l.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Configurati
> on.h
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchPlatform
> Policy.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchRegTable
> .c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchTcoReset
> .c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeak
> er.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeak
> er.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/
> Observable.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/
> Observable.h
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciBus.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Platform.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe
> .h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe
> .inf
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SioPlatform
> Policy.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.
> c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.
> h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/Platf
> ormGopPolicy.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/Platf
> ormGopPolicy.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/Platfor
> mInfoDxe.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/Platfor
> mInfoDxe.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/Platfor
> mInfoDxe.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/BootMod
> e.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/CpuInit
> Peim.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/FlashMa
> p.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacyS
> peaker.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacyS
> peaker.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MchInit
> .c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryC
> allback.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryP
> eim.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PchInit
> Peim.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Platfor
> mEarlyInit.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Platfor
> mEarlyInit.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Platfor
> mInfoInit.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Platfor
> mInitPei.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Platfor
> mSsaInitPeim.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Recover
> y.c
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Stall.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/BootMode.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/CommonHeade
> r.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/MemoryCallb
> ack.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/PlatformPei
> .inf
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Stall.c
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.dec
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgConfig.dsc
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGcc.fdf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgIA32.dsc
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgX64.dsc
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Boot.v
> fi
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Config
> uration.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/DebugC
> onfig.vfi
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/FwVers
> ionStrings.uni
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Main.v
> fi
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Platfo
> rmSetupDxe.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Platfo
> rmSetupDxe.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Platfo
> rmSetupDxe.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Securi
> ty.vfi
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupF
> unctions.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupI
> nfoRecords.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SouthC
> lusterConfig.vfi
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/System
> Component.vfi
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Therma
> l.vfi
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UnCore
> .vfi
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UqiLis
> t.uni
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Vfr.vf
> r
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/VfrStr
> ings.uni
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/Platform.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/PlatformSmm
> .inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/S3Save.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmPlatform
> .h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSa
> ve.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSa
> ve.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Readme.md
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMe
> moryConfig.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMe
> moryConfig.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMe
> moryConfig.in
> >f
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/CommonHea
> der.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseB
> oardManufactu
> >rer.uni
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseB
> oardManufactu
> >rerData.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseB
> oardManufactu
> >rerFunction.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosV
> endor.uni
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosV
> endorData.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosV
> endorFunction.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootI
> nformationData.
> >c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootI
> nformationFunc
> >tion.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChass
> isManufacturer.
> >uni
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChass
> isManufacturer
> >Data.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChass
> isManufacturer
> >Function.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemor
> yDevice.uni
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemor
> yDeviceData.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemor
> yDeviceFuncti
> >on.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumbe
> rOfInstallableL
> >anguagesData.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumbe
> rOfInstallableL
> >anguagesFunction.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemSt
> ring.uni
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemSt
> ringData.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemSt
> ringFunction.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemTy
> pe0x90.uni
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemTy
> pe0x90Data.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemTy
> pe0x90Functio
> >n.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemTy
> pe0x94.uni
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemTy
> pe0x94Data.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemTy
> pe0x94Functio
> >n.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboa
> rdDevice.uni
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboa
> rdDeviceData.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboa
> rdDeviceFuncti
> >on.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysi
> calArray.uni
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysi
> calArrayData.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysi
> calArrayFunction
> >.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortI
> nternalConnecto
> >rDesignator.uni
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortI
> nternalConnecto
> >rDesignatorData.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortI
> nternalConnecto
> >rDesignatorFunction.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProce
> ssorCache.uni
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProce
> ssorCacheData.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProce
> ssorCacheFuncti
> >on.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProce
> ssorInformation
> >.uni
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProce
> ssorInformation
> >Data.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProce
> ssorInformation
> >Function.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscReset
> CapabilitiesData
> >.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscReset
> CapabilitiesFunc
> >tion.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubcl
> assDriver.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubcl
> assDriver.uni
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubcl
> assDriverDataTa
> >ble.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubcl
> assDriverEntryP
> >oint.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> mLanguageStrin
> >g.uni
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> mLanguageStrin
> >gData.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> mLanguageStrin
> >gFunction.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> mManufacturer.
> >uni
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> mManufacturer
> >Data.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> mManufacturer
> >Function.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> mOptionString.u
> >ni
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> mOptionStringD
> >ata.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> mOptionStringF
> >unction.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> mSlotDesignatio
> >n.uni
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> mSlotDesignatio
> >nData.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> mSlotDesignatio
> >nFunction.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/SmBiosMis
> cDxe.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDi
> spatchThunk
> >/SmmSwDispatch2OnSmmSwDispatchThunk.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDi
> spatchThunk
> >/SmmSwDispatch2OnSmmSwDispatchThunk.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm
> /SmramSaveI
> >nfoHandlerSmm.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm
> /SmramSaveI
> >nfoHandlerSmm.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtw
> Spare.bin
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtw
> Working.bin
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageVar
> iable.bin
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_
> HEADER.bin
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_
> HEADER_SPILOCK
> >.bin
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/Vacan
> t.bin
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Stitch/MNW2_Stitch_Conf
> ig.txt
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdO
> pRegion.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdO
> pRegion.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvP
> latformInit.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvP
> latformInit.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvP
> latformInitDxe.inf
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.c
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.h
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h
> > create mode 100644
> >Platform/Intel/Vlv2TbltDevicePkg/Wpce791/Wpce791.inf
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh
> > create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/cln.sh
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/DdrM
> emoryController
> >.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Inte
> lQNCBase.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Inte
> lQNCConfig.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Inte
> lQNCDxe.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Inte
> lQNCPeim.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Inte
> lQNCRegs.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Libr
> ary/IntelQNCLib.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Libr
> ary/QNCAccessLib.
> >h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Libr
> ary/QNCSmmLib.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Ppi/
> QNCMemoryInit.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Prot
> ocol/PchInfo.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Prot
> ocol/PlatformPolic
> >y.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Prot
> ocol/QncS3Suppor
> >t.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Prot
> ocol/SmmIchnDis
> >patch2.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Prot
> ocol/Spi.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QNCA
> ccess.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QNCC
> ommonDefinitio
> >ns.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Quar
> kNcSocId.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Inte
> lQNCLib/Common
> >Header.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Inte
> lQNCLib/IntelQNCL
> >ib.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Inte
> lQNCLib/IntelQNCL
> >ib.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Inte
> lQNCLib/PciExpress
> >.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Mtrr
> Lib/MtrrLib.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Mtrr
> Lib/MtrrLib.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Mtrr
> Lib/MtrrLib.uni
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCA
> ccessLib/BaseAcc
> >ess.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCA
> ccessLib/QNCAcc
> >essLib.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCA
> ccessLib/QNCAcc
> >essLib.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCA
> ccessLib/Runtim
> >eAccess.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCA
> ccessLib/Runtim
> >eQNCAccessLib.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCS
> mmLib/QNCSmm
> >Lib.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCS
> mmLib/QNCSmm
> >Lib.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Rese
> tSystemLib/Reset
> >SystemLib.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Rese
> tSystemLib/Reset
> >SystemLib.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Smbu
> sLib/CommonHe
> >ader.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Smbu
> sLib/SmbusLib.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Smbu
> sLib/SmbusLib.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmC
> puFeaturesLib/S
> >mmCpuFeaturesLib.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmC
> puFeaturesLib/S
> >mmCpuFeaturesLib.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmC
> puFeaturesLib/S
> >mmCpuFeaturesLib.uni
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> ei/MemoryInit.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> ei/MemoryInit.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> ei/MemoryInitP
> >ei.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> ei/core_types.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> ei/gen5_iosf_sb
> >_definitions.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> ei/general_defin
> >itions.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> ei/hte.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> ei/hte.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> ei/io.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> ei/lprint.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> ei/meminit.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> ei/meminit.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> ei/meminit_utils
> >.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> ei/meminit_utils
> >.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> ei/memory_opti
> >ons.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> ei/mrc.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> ei/mrc.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> ei/platform.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> ei/prememinit.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> ei/prememinit.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
> CommonHeader.
> >h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
> DxeQNCSmbus.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
> DxeQNCSmbus.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
> LegacyRegion.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
> LegacyRegion.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
> QNCInit.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
> QNCInit.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
> QNCInitDxe.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
> QNCRootPorts.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
> QNCSmbus.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
> QNCSmbusExec.
> >c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dx
> e/QncS3Support.
> >c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dx
> e/QncS3Support.
> >h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dx
> e/QncS3Support.
> >inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmA
> ccessDxe/Sm
> >mAccess.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmA
> ccessDxe/Sm
> >mAccessDriver.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmA
> ccessDxe/Sm
> >mAccessDriver.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmC
> ontrolDxe/S
> >mmControlDriver.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmC
> ontrolDxe/S
> >mmControlDxe.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> ncSmmDispa
> >tcher/CommonHeader.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> ncSmmDispa
> >tcher/QNC/QNCSmmGpi.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> ncSmmDispa
> >tcher/QNC/QNCSmmHelpers.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> ncSmmDispa
> >tcher/QNC/QNCSmmPeriodicTimer.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> ncSmmDispa
> >tcher/QNC/QNCSmmQncn.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> ncSmmDispa
> >tcher/QNC/QNCSmmSw.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> ncSmmDispa
> >tcher/QNC/QNCSmmSx.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> ncSmmDispa
> >tcher/QNCSmm.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> ncSmmDispa
> >tcher/QNCSmmCore.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> ncSmmDispa
> >tcher/QNCSmmDispatcher.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> ncSmmDispa
> >tcher/QNCSmmHelpers.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> ncSmmDispa
> >tcher/QNCSmmHelpers.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> ncSmmDispa
> >tcher/QNCSmmRegisters.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> ncSmmDispa
> >tcher/QNCxSmmHelpers.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmA
> ccessPei/Smm
> >AccessPei.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmA
> ccessPei/Smm
> >AccessPei.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmC
> ontrolPei/Sm
> >mControlPei.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmC
> ontrolPei/Sm
> >mControlPei.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Common/S
> piCommon.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Common/S
> piCommon.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiRu
> ntime.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiSm
> m.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeD
> xe/PchSpi.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeD
> xe/PchSpi.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchS
> pi.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchS
> pi.h
> > create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dec
> > create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dsc
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/CEAT
> A.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/I2cR
> egs.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Ioh.
> h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/IohA
> ccess.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/IohC
> ommonDefinition
> >s.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Libr
> ary/I2cLib.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Libr
> ary/IohLib.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/MMC.
> h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/SDCa
> rd.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/SDHo
> stIo.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/
> CommonHeader.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/
> IohBds.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/
> IohData.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/
> IohInit.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/
> IohInitDxe.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cL
> ib/CommonHeader
> >.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cL
> ib/I2cLib.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cL
> ib/I2cLib.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohL
> ib/CommonHeade
> >r.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohL
> ib/IohLib.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohL
> ib/IohLib.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDC
> ontrollerDxe/Co
> >mponentName.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDC
> ontrollerDxe/Co
> >mponentName.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDC
> ontrollerDxe/SD
> >Controller.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDC
> ontrollerDxe/SD
> >Controller.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDC
> ontrollerDxe/SD
> >ControllerDxe.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
> ediaDeviceDxe/
> >CEATA.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
> ediaDeviceDxe/
> >CEATABlockIo.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
> ediaDeviceDxe/
> >ComponentName.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
> ediaDeviceDxe/
> >ComponentName.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
> ediaDeviceDxe/
> >MMCSDBlockIo.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
> ediaDeviceDxe/
> >MMCSDTransfer.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
> ediaDeviceDxe/
> >SDMediaDevice.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
> ediaDeviceDxe/
> >SDMediaDevice.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
> ediaDeviceDxe/
> >SDMediaDeviceDxe.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/P
> ei/UsbPei.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/P
> ei/UsbPei.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/P
> ei/UsbPei.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> /ComponentNa
> >me.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> /ComponentNa
> >me.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> /Descriptor.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> /Ohci.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> /Ohci.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> /OhciDebug.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> /OhciDebug.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> /OhciDxe.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> /OhciReg.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> /OhciReg.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> /OhciSched.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> /OhciSched.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> /OhciUrb.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> /OhciUrb.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> /UsbHcMem.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> /UsbHcMem.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> /Descriptor.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> /OhcPeim.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> /OhcPeim.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> /OhciPei.inf
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> /OhciReg.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> /OhciReg.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> /OhciSched.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> /OhciSched.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> /OhciUrb.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> /OhciUrb.h
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> /UsbHcMem.c
> > create mode 100644
> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> /UsbHcMem.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/98_LIN
> K.ASL
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTa
> blePlatform.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTa
> bles.inf
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/CPU.as
> l
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/DSDT.A
> SL
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facp/F
> acp.aslc
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facs/F
> acs.aslc
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/GloblN
> vs.asl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Gpe.as
> l
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/HOST_B
> US.ASL
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Hpet/H
> pet.aslc
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELG
> FX.ASL
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELI
> SPDev2.ASL
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOGB
> DA.ASL
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOMO
> BF.ASL
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOSB
> CB.ASL
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOpR
> n.ASL
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IoTVir
> tualDevice.asl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LPC_DE
> V.ASL
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LpcB.a
> sl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Lpit/L
> pit.aslc
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/M
> adt.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/M
> adt30.aslc
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Mcfg/M
> cfg.aslc
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PCI_DR
> C.ASL
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Pch.as
> l
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchAud
> io.asl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchEhc
> i.asl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchLps
> s.asl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchPci
> e.asl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchScc
> .asl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchSmb
> .asl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchXhc
> i.asl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PciTre
> e.asl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Platfo
> rm.asl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RTD3.a
> sl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RhProx
> y.asl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/THERMA
> L.ASL
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/UsbSbd
> .asl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Video.
> asl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Vlv.as
> l
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Wsmt/W
> smt.aslc
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/token.
> asl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Guid/Vlv2Devi
> ceRefCodePkgTok
> >enSpace.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/PttPassTh
> ruPpi.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/fTPMPolic
> y.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Protocol/PttP
> assThru.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/In
> clude/Guid/Pow
> >erManagementAcpiTableStorage.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/In
> clude/Ppi/VlvPol
> >icy.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/In
> clude/Protocol/P
> >pmPlatformPolicy.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/In
> clude/Types.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
> werManageme
> >nt/AcpiTables/PowerManagementAcpiTables.inf
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
> werManageme
> >nt/AcpiTables/Ssdt/ApCst.asl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
> werManageme
> >nt/AcpiTables/Ssdt/ApIst.asl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
> werManageme
> >nt/AcpiTables/Ssdt/ApTst.asl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
> werManageme
> >nt/AcpiTables/Ssdt/Cpu0Cst.asl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
> werManageme
> >nt/AcpiTables/Ssdt/Cpu0Ist.asl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
> werManageme
> >nt/AcpiTables/Ssdt/Cpu0Tst.asl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
> werManageme
> >nt/AcpiTables/Ssdt/CpuPm.asl
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> luster/Include/Pl
> >atformBaseAddresses.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> luster/Include/P
> >pi/Capsule.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> luster/Include/P
> >pi/PlatformMemoryRange.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> luster/Include/P
> >pi/PlatformMemorySize.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> luster/Include/P
> >pi/SmmAccess.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> luster/Include/P
> >pi/VlvMmioPolicy.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> luster/Include/P
> >pi/VlvPeiInit.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> luster/Include/P
> >pi/VlvPolicy.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> luster/Include/P
> >rotocol/IgdOpRegion.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> luster/Include/P
> >rotocol/MemInfo.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> luster/Include/P
> >rotocol/PlatformGopPolicy.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> luster/Include/P
> >rotocol/VlvPlatformPolicy.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> luster/Include/V
> >alleyview.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> luster/Include/Vl
> >vAccess.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> luster/Include/Vl
> >vCommonDefinitions.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/G
> >uid/PchInitVar.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/G
> >uid/SataControllerGuid.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/G
> >uid/SmbusArpMap.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/G
> >uid/Vlv2Variable.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/In
> >dustryStandard/CeAta.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/In
> >dustryStandard/Mmc.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/In
> >dustryStandard/SdCard.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/Li
> >brary/I2CLib.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/Li
> >brary/PchPlatformLib.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >chAccess.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >chCommonDefinitions.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >chRegs.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >chRegs/PchRegsHda.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >chRegs/PchRegsLpss.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >chRegs/PchRegsPcie.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >chRegs/PchRegsPcu.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >chRegs/PchRegsRcrb.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >chRegs/PchRegsSata.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >chRegs/PchRegsScc.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >chRegs/PchRegsSmbus.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >chRegs/PchRegsSpi.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >chRegs/PchRegsUsb.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >pi/PchInit.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >pi/PchPeiInit.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >pi/PchPlatformPolicy.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >pi/PchUsbPolicy.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >pi/PeiBlockIo.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >pi/Sdhc.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >pi/SmbusPolicy.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >pi/Spi.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >rotocol/ActiveBios.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >rotocol/ActiveBiosProtocol.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >rotocol/DxePchPolicyUpdateProtocol.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >rotocol/EmmcCardInfoProtocol.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >rotocol/Gpio.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >rotocol/HwWatchdogTimer.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >rotocol/I2cBus.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >rotocol/PchExtendedReset.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >rotocol/PchInfo.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >rotocol/PchPlatformPolicy.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >rotocol/PchReset.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >rotocol/PchS3Support.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >rotocol/SdHostIo.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >rotocol/SmbiosSlotPopulation.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >rotocol/SmmIchnDispatchEx.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >rotocol/SmmSmbus.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >rotocol/Spi.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/P
> >rotocol/TcoReset.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/R
> >sci.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> luster/Include/Ti
> >anoApi.h
> > create mode 100644
> >Silicon/Intel/Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.
> dec
> > create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.c
> > create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.h
> > create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.inf
> > create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.c
> > create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.inf
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Include/Library/Oma
> pDmaLib.h
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Include/Library/Oma
> pLib.h
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> ap3530.h
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> ap3530Dma.
> >h
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> ap3530Gpio.
> >h
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> ap3530Gpmc
> >.h
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> ap3530I2c.h
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> ap3530Interr
> >upt.h
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> ap3530MMC
> >HS.h
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> ap3530PadC
> >onfiguration.h
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> ap3530Prcm.
> >h
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> ap3530Timer
> >.h
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> ap3530Uart.
> >h
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> ap3530Usb.h
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Include/TPS65950.h
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/Hardwa
> reInterrupt.c
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/Interr
> uptDxe.inf
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDx
> e/LcdGraphics
> >OutputBlt.c
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDx
> e/LcdGraphics
> >OutputDxe.c
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDx
> e/LcdGraphics
> >OutputDxe.h
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDx
> e/LcdGraphics
> >OutputDxe.inf
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentT
> imerLib/Debug
> >AgentTimerLib.c
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentT
> imerLib/Debug
> >AgentTimerLib.inf
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLi
> b/GdbSerialLib.c
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLi
> b/GdbSerialLib.in
> >f
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTim
> erLib/Omap35
> >xxTimerLib.inf
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTim
> erLib/TimerLib
> >.c
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/
> OmapDmaLib.
> >c
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/
> OmapDmaLib.
> >inf
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/Oma
> pLib.c
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/Oma
> pLib.inf
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClo
> ckLib/RealTimeC
> >lockLib.c
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClo
> ckLib/RealTimeC
> >lockLib.inf
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortL
> ib/SerialPortLib.c
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortL
> ib/SerialPortLib.in
> >f
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.c
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.h
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.inf
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostD
> xe.c
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostD
> xe.h
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostD
> xe.inf
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dec
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dsc
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmu
> lation.c
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmu
> lation.inf
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.c
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.inf
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS6595
> 0.c
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS6595
> 0.inf
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/Timer.c
> > create mode 100644
> >Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/TimerDxe.i
> nf
> >
> >--
> >2.21.0.windows.1
> >
> >
> >


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [edk2-devel] [edk2-platforms: Patch 0/8] Add packages from edk2
  2019-05-10  6:17   ` Michael D Kinney
@ 2019-05-10  7:32     ` Liming Gao
  2019-05-10 18:49       ` Kubacki, Michael A
  0 siblings, 1 reply; 23+ messages in thread
From: Liming Gao @ 2019-05-10  7:32 UTC (permalink / raw)
  To: Kinney, Michael D, devel@edk2.groups.io
  Cc: Sun, Zailiang, Qian, Yi, Steele, Kelly, Ni, Ray,
	Kubacki, Michael A, Leif Lindholm, Ard Biesheuvel

OK. I add them into edk2 planning wiki. 

Besides, I sent the patch to migrate devel-MinPlatform branch to master branch in edk2 platform repo. 
This change will be done next Monday. Please aware it. 

Thanks
Liming
>-----Original Message-----
>From: Kinney, Michael D
>Sent: Friday, May 10, 2019 2:18 PM
>To: Gao, Liming <liming.gao@intel.com>; devel@edk2.groups.io; Kinney,
>Michael D <michael.d.kinney@intel.com>
>Cc: Sun, Zailiang <zailiang.sun@intel.com>; Qian, Yi <yi.qian@intel.com>;
>Steele, Kelly <kelly.steele@intel.com>; Ni, Ray <ray.ni@intel.com>; Kubacki,
>Michael A <michael.a.kubacki@intel.com>; Leif Lindholm
><leif.lindholm@linaro.org>; Ard Biesheuvel <ard.biesheuvel@linaro.org>
>Subject: RE: [edk2-devel] [edk2-platforms: Patch 0/8] Add packages from
>edk2
>
>Liming,
>
>I will update license in edk2-plaforms after this patch is checked in.
>
>Yes.  The plan is to catch the stable tag.
>
>Mike
>
>> -----Original Message-----
>> From: Gao, Liming
>> Sent: Thursday, May 9, 2019 10:15 PM
>> To: devel@edk2.groups.io; Kinney, Michael D
>> <michael.d.kinney@intel.com>
>> Cc: Sun, Zailiang <zailiang.sun@intel.com>; Qian, Yi
>> <yi.qian@intel.com>; Steele, Kelly
>> <kelly.steele@intel.com>; Ni, Ray <ray.ni@intel.com>;
>> Kubacki, Michael A <michael.a.kubacki@intel.com>; Leif
>> Lindholm <leif.lindholm@linaro.org>; Ard Biesheuvel
>> <ard.biesheuvel@linaro.org>
>> Subject: RE: [edk2-devel] [edk2-platforms: Patch 0/8] Add
>> packages from edk2
>>
>> Mike:
>>   I have two questions here.
>> 1. Those module in edk2 has BSD + Patent License. But,
>> edk2 platform code uses BSD license. That means the codes
>> in edk2 platform will have the mix license. What's the
>> plan to update edk2 platform code license to BSD +
>> Patent?
>> 2. What's plan for this change? This change impacts edk2
>> project. Does it catch edk2 stable tag?
>>
>> Thanks
>> Liming
>> >-----Original Message-----
>> >From: devel@edk2.groups.io [mailto:devel@edk2.groups.io]
>> On Behalf Of
>> >Michael D Kinney
>> >Sent: Friday, May 10, 2019 11:34 AM
>> >To: devel@edk2.groups.io
>> >Cc: Sun, Zailiang <zailiang.sun@intel.com>; Qian, Yi
>> <yi.qian@intel.com>;
>> >Steele, Kelly <kelly.steele@intel.com>; Ni, Ray
>> <ray.ni@intel.com>; Kubacki,
>> >Michael A <michael.a.kubacki@intel.com>; Leif Lindholm
>> ><leif.lindholm@linaro.org>; Ard Biesheuvel
>> <ard.biesheuvel@linaro.org>
>> >Subject: [edk2-devel] [edk2-platforms: Patch 0/8] Add
>> packages from edk2
>> >
>> >https://bugzilla.tianocore.org/show_bug.cgi?id=1467
>> >https://bugzilla.tianocore.org/show_bug.cgi?id=1374
>> >https://bugzilla.tianocore.org/show_bug.cgi?id=1793
>> >
>> >Add the following platform, silicon, and driver packages
>> from the edk2 repo
>> >to the edk2-platforms repo
>> >* Drivers/OptionRomPkg
>> >* Platform/BeagleBoard/BeagleBoardPkg
>> >* Platform/Intel/QuarkPlatformPkg
>> >* Platform/Intel/Vlv2TbltDevicePkg
>> >* Silicon/Intel/QuarkSocPkg
>> >* Silicon/Intel/Vlv2DeviceRefCodePkg
>> >* Silicon/TexasInsturments/Omap35xxPkg
>> >
>> >Cc: Zailiang Sun <zailiang.sun@intel.com>
>> >Cc: Yi Qian <yi.qian@intel.com>
>> >Cc: Kelly Steele <kelly.steele@intel.com>
>> >Cc: Ray Ni <ray.ni@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>
>> >
>> >Michael D Kinney (8):
>> >  Silicon/TexasInsturments: Import Omap35xxPkg from edk2
>> >  Platform/BeagleBoard: Import BeagleBoardPkg from edk2
>> >  Silicon/Intel: Import QuarkSocPkg from edk2
>> >  Platform/QuarkPlatformPkg: Import QuarkPlatformPkg
>> from edk2
>> >  Platform/Vlv2DeviceRefCodePkg: Import
>> Vlv2DeviceRefCodePkg from edk2
>> >  Platform/Vlv2TbltDevicePkg: Import Vlv2TbltDevicePkg
>> from edk2
>> >  Drivers/OptionRomPkg: Import OptionRomPkg from edk2
>> >  edk2-platforms: Update Maintainers.txt/Readme.md for
>> imported packages
>> >
>> > .../Application/BltLibSample/BltLibSample.c   |  279 +
>> > .../Application/BltLibSample/BltLibSample.inf |   30 +
>> > .../AtapiPassThruDxe/AtapiPassThru.c          | 3410
>> +++++++++++++
>> > .../AtapiPassThruDxe/AtapiPassThru.h          | 1618
>> ++++++
>> > .../AtapiPassThruDxe/AtapiPassThruDxe.inf     |   70 +
>> > .../AtapiPassThruDxe/ComponentName.c          |  169 +
>> > .../DriverSupportedEfiVersion.c               |   14 +
>> > .../FtdiUsbSerialDxe/CompatibleDevices.txt    |    5 +
>> > .../Bus/Usb/FtdiUsbSerialDxe/ComponentName.c  |  218 +
>> > .../FtdiUsbSerialDxe/FtdiUsbSerialDriver.c    | 2580
>> ++++++++++
>> > .../FtdiUsbSerialDxe/FtdiUsbSerialDriver.h    |  589
>> +++
>> > .../Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf |   55 +
>> > .../Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt       |   32 +
>> > .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.c   | 1318
>> +++++
>> > .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.h   |  969
>> ++++
>> > .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf |   61 +
>> > .../Usb/UsbNetworking/Ax88772/ComponentName.c |  178 +
>> > .../Usb/UsbNetworking/Ax88772/DriverBinding.c |  507 ++
>> > .../Usb/UsbNetworking/Ax88772/SimpleNetwork.c | 1503
>> ++++++
>> > .../Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c  |  875
>> ++++
>> > .../Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h  | 1026
>> ++++
>> > .../Usb/UsbNetworking/Ax88772b/Ax88772b.inf   |   61 +
>> > .../UsbNetworking/Ax88772b/ComponentName.c    |  175 +
>> > .../UsbNetworking/Ax88772b/DriverBinding.c    |  696
>> +++
>> > .../UsbNetworking/Ax88772b/SimpleNetwork.c    | 1657
>> ++++++
>> > .../CirrusLogic5430Dxe/CirrusLogic5430.c      |  917
>> ++++
>> > .../CirrusLogic5430Dxe/CirrusLogic5430.h      |  432 ++
>> > .../CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf |   84 +
>> > .../CirrusLogic5430GraphicsOutput.c           |  556 ++
>> > .../CirrusLogic5430Dxe/CirrusLogic5430I2c.c   |  427 ++
>> > .../CirrusLogic5430Dxe/CirrusLogic5430I2c.h   |   62 +
>> > .../CirrusLogic5430UgaDraw.c                  |  412 ++
>> > .../CirrusLogic5430Dxe/ComponentName.c        |  203 +
>> > .../DriverSupportedEfiVersion.c               |   14 +
>> > .../OptionRomPkg/CirrusLogic5430Dxe/Edid.c    |  525 ++
>> > Drivers/OptionRomPkg/Include/Library/BltLib.h |  253 +
>> > .../FrameBufferBltLib/FrameBufferBltLib.c     |  744
>> +++
>> > .../FrameBufferBltLib/FrameBufferBltLib.inf   |   29 +
>> > .../Library/GopBltLib/GopBltLib.c             |  449 ++
>> > .../Library/GopBltLib/GopBltLib.inf           |   31 +
>> > Drivers/OptionRomPkg/OptionRomPkg.dec         |   41 +
>> > Drivers/OptionRomPkg/OptionRomPkg.dsc         |  113 +
>> > Drivers/OptionRomPkg/ReadMe.txt               |   17 +
>> > .../UndiRuntimeDxe/ComponentName.c            |  359 ++
>> > Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c  | 1516
>> ++++++
>> > Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c   | 3541
>> +++++++++++++
>> > Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h   |  665
>> +++
>> > Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c    | 1051
>> ++++
>> > Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h  |  439 ++
>> > .../OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c |  145 +
>> > .../UndiRuntimeDxe/UndiRuntimeDxe.inf         |   72 +
>> > Maintainers.txt                               |   20 +
>> > .../BeagleBoardPkg/BeagleBoardPkg.dec         |   30 +
>> > .../BeagleBoardPkg/BeagleBoardPkg.dsc         |  496 ++
>> > .../BeagleBoardPkg/BeagleBoardPkg.fdf         |  308 ++
>> > .../BeagleBoardPkg/ConfigurationHeader.bin    |  Bin 0
>> -> 512 bytes
>> > .../BeagleBoardPkg/ConfigurationHeader.dat    |   41 +
>> > .../Debugger_scripts/rvi_boot_from_ram.inc    |   15 +
>> > .../Debugger_scripts/rvi_convert_symbols.sh   |   17 +
>> > .../Debugger_scripts/rvi_dummy.axf            |  Bin 0
>> -> 7984 bytes
>> > .../Debugger_scripts/rvi_hw_setup.inc         |   61 +
>> > .../Debugger_scripts/rvi_load_symbols.inc     |   17 +
>> > .../Debugger_scripts/rvi_symbols_macros.inc   |  188 +
>> > .../Debugger_scripts/rvi_unload_symbols.inc   |  112 +
>> > .../Debugger_scripts/trace32_load_symbols.cmm |  205 +
>> > .../trace32_load_symbols_cygwin.cmm           |  182 +
>> > .../BeagleBoardPkg/Include/BeagleBoard.h      |  173 +
>> > .../Library/BeagleBoardLib/BeagleBoard.c      |  115 +
>> > .../BeagleBoardLib/BeagleBoardHelper.S        |   41 +
>> > .../BeagleBoardLib/BeagleBoardHelper.asm      |   47 +
>> > .../Library/BeagleBoardLib/BeagleBoardLib.inf |   48 +
>> > .../Library/BeagleBoardLib/BeagleBoardMem.c   |   74 +
>> > .../Library/BeagleBoardLib/Clock.c            |   63 +
>> > .../Library/BeagleBoardLib/PadConfiguration.c |  316 ++
>> > .../Library/DxeHobPeCoffLib/DxeHobPeCoff.c    |  282 ++
>> > .../DxeHobPeCoffLib/DxeHobPeCoffLib.inf       |   39 +
>> > .../LzmaHobCustomDecompressLib.c              |   44 +
>> > .../LzmaHobCustomDecompressLib.inf            |   45 +
>> > .../MemoryInitPeiLib/MemoryInitPeiLib.c       |  192 +
>> > .../MemoryInitPeiLib/MemoryInitPeiLib.inf     |   58 +
>> > .../Library/ResetSystemLib/ResetSystemLib.c   |  149 +
>> > .../Library/ResetSystemLib/ResetSystemLib.inf |   37 +
>> > .../BeagleBoardPkg/PrePi/Arm/ArchPrePi.c      |   23 +
>> > .../PrePi/Arm/ModuleEntryPoint.S              |  124 +
>> > .../PrePi/Arm/ModuleEntryPoint.asm            |  142 +
>> > .../BeagleBoardPkg/PrePi/LzmaDecompress.h     |   97 +
>> > .../BeagleBoardPkg/PrePi/MainUniCore.c        |   33 +
>> > .../BeagleBoardPkg/PrePi/PeiUniCore.inf       |   97 +
>> > .../BeagleBoard/BeagleBoardPkg/PrePi/PrePi.c  |  179 +
>> > .../BeagleBoard/BeagleBoardPkg/PrePi/PrePi.h  |   90 +
>> > .../BeagleBoardPkg/Tools/GNUmakefile          |   14 +
>> > .../BeagleBoardPkg/Tools/generate_image.c     |  402 ++
>> > .../BeagleBoard/BeagleBoardPkg/Tools/makefile |   16 +
>> > .../BeagleBoardPkg/Tools/replace.c            |  140 +
>> > .../Acpi/AcpiTables/AcpiTables.inf            |   42 +
>> > .../Acpi/AcpiTables/Cpu0Cst/Cpu0Cst.asl       |  399 ++
>> > .../Acpi/AcpiTables/Cpu0Ist/Cpu0Ist.asl       |  159 +
>> > .../Acpi/AcpiTables/Cpu0Tst/Cpu0Tst.asl       |  133 +
>> > .../Acpi/AcpiTables/CpuPm/CpuPm.asl           |   73 +
>> > .../Acpi/AcpiTables/Dsdt/AD7298.asi           |   38 +
>> > .../Acpi/AcpiTables/Dsdt/ADC108S102.asi       |   33 +
>> > .../Acpi/AcpiTables/Dsdt/CAT24C08.asi         |   34 +
>> > .../Acpi/AcpiTables/Dsdt/CY8C9540A.asi        |   47 +
>> > .../Acpi/AcpiTables/Dsdt/GpioClient.asi       |   89 +
>> > .../Acpi/AcpiTables/Dsdt/LpcDev.asi           |  248 +
>> > .../Acpi/AcpiTables/Dsdt/PCA9685.asi          |   34 +
>> > .../Acpi/AcpiTables/Dsdt/PCAL9555A.asi        |   90 +
>> > .../Acpi/AcpiTables/Dsdt/PciHostBridge.asi    |  195 +
>> > .../Acpi/AcpiTables/Dsdt/PciIrq.asi           |  552 ++
>> > .../Acpi/AcpiTables/Dsdt/PcieExpansionPrt.asi |  127 +
>> > .../Acpi/AcpiTables/Dsdt/Platform.asl         |  347 ++
>> > .../Acpi/AcpiTables/Dsdt/QNC.asi              |   49 +
>> > .../Acpi/AcpiTables/Dsdt/QNCApic.asi          |   32 +
>> > .../Acpi/AcpiTables/Dsdt/QNCLpc.asi           |   23 +
>> > .../AcpiTables/Dsdt/QuarkSouthCluster.asi     |  110 +
>> > .../Acpi/AcpiTables/Dsdt/Tpm.asi              |   45 +
>> > .../Acpi/AcpiTables/Facs/Facs.aslc            |   74 +
>> > .../Acpi/AcpiTables/Facs/Facs.h               |   29 +
>> > .../Acpi/AcpiTables/Fadt/Fadt.h               |  102 +
>> > .../Acpi/AcpiTables/Fadt/Fadt1.0.aslc         |   76 +
>> > .../Acpi/AcpiTables/Fadt/Fadt2.0.aslc         |  157 +
>> > .../Acpi/AcpiTables/Hpet/Hpet.aslc            |   68 +
>> > .../Acpi/AcpiTables/Hpet/Hpet.h               |   45 +
>> > .../Acpi/AcpiTables/Mcfg/Mcfg.aslc            |   75 +
>> > .../Acpi/AcpiTables/Mcfg/Mcfg.h               |   56 +
>> > .../Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.c     | 1402
>> +++++
>> > .../Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.h     |  316 ++
>> > .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.c      |  805
>> +++
>> > .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.h      |  120 +
>> > .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.inf    |  196 +
>> > .../Acpi/Dxe/AcpiPlatform/Madt.h              |  207 +
>> > .../Acpi/Dxe/AcpiPlatform/MadtPlatform.c      |  300 ++
>> > .../BootScriptExecutorDxe.inf                 |   77 +
>> > .../Dxe/BootScriptExecutorDxe/IA32/S3Asm.S    |   44 +
>> > .../Dxe/BootScriptExecutorDxe/IA32/S3Asm.asm  |   51 +
>> > .../BootScriptExecutorDxe/IA32/SetIdtEntry.c  |   57 +
>> > .../Dxe/BootScriptExecutorDxe/ScriptExecute.c |  379 ++
>> > .../Dxe/BootScriptExecutorDxe/ScriptExecute.h |   70 +
>> > .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.c     | 1011
>> ++++
>> > .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.h     |  167 +
>> > .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.inf   |   78 +
>> > .../Acpi/DxeSmm/SmmPowerManagement/Ppm.c      |  372 ++
>> > .../Acpi/DxeSmm/SmmPowerManagement/Ppm.h      |  150 +
>> > .../SmmPowerManagement/SmmPowerManagement.c   |  113 +
>> > .../SmmPowerManagement/SmmPowerManagement.h   |   52 +
>> > .../SmmPowerManagement/SmmPowerManagement.inf |   74 +
>> > .../Application/ForceRecovery/ForceRecovery.c |   47 +
>> > .../ForceRecovery/ForceRecovery.inf           |   34 +
>> > .../PlatformFlashAccessLibDxe.c               |  262 +
>> > .../PlatformFlashAccessLibDxe.inf             |   47 +
>> > .../PlatformFlashAccessLib/SpiFlashDevice.c   |  330 ++
>> > .../PlatformFlashAccessLib/SpiFlashDevice.h   |  180 +
>> > .../SystemFirmwareDescriptor.aslc             |   83 +
>> > .../SystemFirmwareDescriptor.inf              |   40 +
>> > .../SystemFirmwareDescriptorPei.c             |   60 +
>> > .../SystemFirmwareUpdateConfig.ini            |   57 +
>> > .../Include/Guid/CapsuleOnDataCD.h            |   23 +
>> > .../Include/Guid/CapsuleOnFatFloppyDisk.h     |   23 +
>> > .../Include/Guid/CapsuleOnFatIdeDisk.h        |   24 +
>> > .../Include/Guid/CapsuleOnFatUsbDisk.h        |   24 +
>> > .../Include/Guid/MemoryConfigData.h           |   23 +
>> > .../Include/Guid/QuarkCapsuleGuid.h           |   46 +
>> > .../Include/Guid/QuarkVariableLock.h          |   23 +
>> > .../Include/Guid/SystemNvDataHobGuid.h        |   29 +
>> > .../Include/Library/PlatformHelperLib.h       |  266 +
>> > .../Include/Library/PlatformPcieHelperLib.h   |   56 +
>> > .../Intel/QuarkPlatformPkg/Include/Pcal9555.h |   24 +
>> > .../Intel/QuarkPlatformPkg/Include/Platform.h |  119 +
>> > .../QuarkPlatformPkg/Include/PlatformBoards.h |  166 +
>> > .../Include/Protocol/GlobalNvsArea.h          |   82 +
>> > .../Include/Protocol/PlatformSmmSpiReady.h    |   23 +
>> > .../PlatformBootManager.c                     |  472 ++
>> > .../PlatformBootManager.h                     |   49 +
>> > .../PlatformBootManagerLib.inf                |   83 +
>> > .../PlatformBootManagerLib/PlatformData.c     |  275 +
>> > .../Library/PlatformHelperLib/CommonHeader.h  |   51 +
>> > .../DxePlatformHelperLib.inf                  |   70 +
>> > .../PeiPlatformHelperLib.inf                  |   45 +
>> > .../PlatformHelperLib/PlatformHelperDxe.c     |  337 ++
>> > .../PlatformHelperLib/PlatformHelperLib.c     |  481 ++
>> > .../PlatformHelperLib/PlatformHelperPei.c     |  159 +
>> > .../Library/PlatformHelperLib/PlatformLeds.c  |  146 +
>> > .../PlatformPcieHelperLib/CommonHeader.h      |   55 +
>> > .../PlatformPcieHelperLib.c                   |  114 +
>> > .../PlatformPcieHelperLib.inf                 |   41 +
>> > .../Library/PlatformPcieHelperLib/SocUnit.c   |  125 +
>> > .../Library/PlatformSecLib/Ia32/Flat32.S      |  796
>> +++
>> > .../Library/PlatformSecLib/Ia32/Flat32.asm    |  685
>> +++
>> > .../Library/PlatformSecLib/Ia32/Platform.inc  |  134 +
>> > .../Library/PlatformSecLib/PlatformSecLib.c   |  207 +
>> > .../Library/PlatformSecLib/PlatformSecLib.inf |   54 +
>> > .../PlatformSecLib/PlatformSecLibModStrs.uni  |   18 +
>> > .../PlatformSecureLib/PlatformSecureLib.c     |  164 +
>> > .../PlatformSecureLib/PlatformSecureLib.inf   |   41 +
>> > .../Library/Tpm12DeviceLibAtmelI2c/TisPc.c    |  408 ++
>> > .../Tpm12DeviceLibAtmelI2c.inf                |   39 +
>> > .../Tpm12DeviceLibAtmelI2c.uni                |   16 +
>> > .../Library/Tpm12DeviceLibInfineonI2c/TisPc.c |  612
>> +++
>> > .../Tpm12DeviceLibInfineonI2c.inf             |   39 +
>> > .../Tpm12DeviceLibInfineonI2c.uni             |   16 +
>> > .../Pci/Dxe/PciHostBridge/PciHostBridge.c     | 1397
>> +++++
>> > .../Pci/Dxe/PciHostBridge/PciHostBridge.h     |  389 ++
>> > .../Pci/Dxe/PciHostBridge/PciHostBridge.inf   |   61 +
>> > .../Dxe/PciHostBridge/PciHostBridgeSupport.c  |  140 +
>> > .../Pci/Dxe/PciHostBridge/PciHostResource.h   |   60 +
>> > .../Pci/Dxe/PciHostBridge/PciRootBridge.h     |  693
>> +++
>> > .../Pci/Dxe/PciHostBridge/PciRootBridgeIo.c   | 1610
>> ++++++
>> > .../Pci/Dxe/PciPlatform/CommonHeader.h        |   31 +
>> > .../Pci/Dxe/PciPlatform/PciPlatform.c         |  194 +
>> > .../Pci/Dxe/PciPlatform/PciPlatform.h         |   82 +
>> > .../Pci/Dxe/PciPlatform/PciPlatform.inf       |   54 +
>> > .../Dxe/MemorySubClass/MemorySubClass.c       |  435 ++
>> > .../Dxe/MemorySubClass/MemorySubClass.h       |   65 +
>> > .../Dxe/MemorySubClass/MemorySubClass.inf     |   60 +
>> > .../MemorySubClass/MemorySubClassStrings.uni  |   29 +
>> > .../Dxe/PlatformInit/PlatformConfig.c         |  443 ++
>> > .../Dxe/PlatformInit/PlatformInitDxe.c        |   87 +
>> > .../Dxe/PlatformInit/PlatformInitDxe.h        |   58 +
>> > .../Dxe/PlatformInit/PlatformInitDxe.inf      |   56 +
>> > .../Dxe/SaveMemoryConfig/SaveMemoryConfig.c   |  118 +
>> > .../Dxe/SaveMemoryConfig/SaveMemoryConfig.inf |   44 +
>> > .../Platform/Dxe/Setup/CommonHeader.h         |   55 +
>> > .../Platform/Dxe/Setup/DxePlatform.inf        |   76 +
>> > .../Platform/Dxe/Setup/KeyboardLayout.c       |  262 +
>> > .../Platform/Dxe/Setup/QNCRegTable.c          |   80 +
>> > .../Platform/Dxe/Setup/SetupPlatform.c        |   97 +
>> > .../Platform/Dxe/Setup/SetupPlatform.h        |   71 +
>> > .../Platform/Dxe/Setup/Strings.uni            |   47 +
>> > .../Platform/Dxe/Setup/processor.c            |   40 +
>> > .../Platform/Dxe/SmbiosMiscDxe/CommonHeader.h |   34 +
>> > .../MiscBaseBoardManufacturer.uni             |   19 +
>> > .../MiscBaseBoardManufacturerData.c           |   45 +
>> > .../MiscBaseBoardManufacturerFunction.c       |  181 +
>> > .../Dxe/SmbiosMiscDxe/MiscBiosVendor.uni      |   18 +
>> > .../Dxe/SmbiosMiscDxe/MiscBiosVendorData.c    |   92 +
>> > .../SmbiosMiscDxe/MiscBiosVendorFunction.c    |  222 +
>> > .../SmbiosMiscDxe/MiscBootInformationData.c   |   24 +
>> > .../MiscBootInformationFunction.c             |   71 +
>> > .../SmbiosMiscDxe/MiscChassisManufacturer.uni |   17 +
>> > .../MiscChassisManufacturerData.c             |   36 +
>> > .../MiscChassisManufacturerFunction.c         |  168 +
>> > .../Dxe/SmbiosMiscDxe/MiscDevicePath.h        |   42 +
>> > .../MiscNumberOfInstallableLanguagesData.c    |   28 +
>> > ...MiscNumberOfInstallableLanguagesFunction.c |  240 +
>> > .../Dxe/SmbiosMiscDxe/MiscOemString.uni       |   12 +
>> > .../Dxe/SmbiosMiscDxe/MiscOemStringData.c     |   20 +
>> > .../Dxe/SmbiosMiscDxe/MiscOemStringFunction.c |   78 +
>> > .../Dxe/SmbiosMiscDxe/MiscOnboardDevice.uni   |   18 +
>> > .../Dxe/SmbiosMiscDxe/MiscOnboardDeviceData.c |   49 +
>> > .../SmbiosMiscDxe/MiscOnboardDeviceFunction.c |  105 +
>> > .../MiscPortInternalConnectorDesignator.uni   |   53 +
>> > .../MiscPortInternalConnectorDesignatorData.c |  184 +
>> > ...cPortInternalConnectorDesignatorFunction.c |  292 ++
>> > .../SmbiosMiscDxe/MiscSystemManufacturer.uni  |   20 +
>> > .../MiscSystemManufacturerData.c              |   32 +
>> > .../MiscSystemManufacturerFunction.c          |  198 +
>> > .../SmbiosMiscDxe/MiscSystemOptionString.uni  |   14 +
>> > .../MiscSystemOptionStringData.c              |   23 +
>> > .../MiscSystemOptionStringFunction.c          |   81 +
>> > .../MiscSystemSlotDesignation.uni             |   27 +
>> > .../MiscSystemSlotDesignationData.c           |  357 ++
>> > .../MiscSystemSlotDesignationFunction.c       |  285 ++
>> > .../MiscSystemSlotOnboardDevices.uni          |   23 +
>> > .../Platform/Dxe/SmbiosMiscDxe/SmbiosMisc.h   |  137 +
>> > .../Dxe/SmbiosMiscDxe/SmbiosMiscDataTable.c   |  109 +
>> > .../Dxe/SmbiosMiscDxe/SmbiosMiscDxe.inf       |  308 ++
>> > .../Dxe/SmbiosMiscDxe/SmbiosMiscEntryPoint.c  |   82 +
>> > .../Dxe/SmbiosMiscDxe/SmbiosMiscStrings.uni   |   26 +
>> > .../Pei/PlatformConfig/PlatformConfigPei.c    |   81 +
>> > .../Pei/PlatformConfig/PlatformConfigPei.inf  |   45 +
>> > .../Platform/Pei/PlatformInit/BootMode.c      |  218 +
>> > .../Platform/Pei/PlatformInit/CommonHeader.h  |   81 +
>> > .../Pei/PlatformInit/Generic/Recovery.c       |  467 ++
>> > .../Pei/PlatformInit/MemoryCallback.c         |  279 +
>> > .../Platform/Pei/PlatformInit/MrcWrapper.c    | 1565
>> ++++++
>> > .../Platform/Pei/PlatformInit/MrcWrapper.h    |  225 +
>> > .../Platform/Pei/PlatformInit/PeiFvSecurity.c |  111 +
>> > .../Platform/Pei/PlatformInit/PeiFvSecurity.h |   67 +
>> > .../Pei/PlatformInit/PlatformEarlyInit.c      | 1227
>> +++++
>> > .../Pei/PlatformInit/PlatformEarlyInit.h      |  301 ++
>> > .../Pei/PlatformInit/PlatformEarlyInit.inf    |  193 +
>> > .../Pei/PlatformInit/PlatformErratas.c        |  178 +
>> > .../Platform/SpiFvbServices/FvbInfo.c         |  332 ++
>> > .../Platform/SpiFvbServices/FwBlockService.c  | 2053
>> ++++++++
>> > .../Platform/SpiFvbServices/FwBlockService.h  |  308 ++
>> > .../Platform/SpiFvbServices/PlatformSmmSpi.c  |   31 +
>> > .../SpiFvbServices/PlatformSmmSpi.inf         |   80 +
>> > .../Platform/SpiFvbServices/PlatformSpi.inf   |   79 +
>> > .../Platform/SpiFvbServices/SpiFlashDevice.c  |  331 ++
>> > .../Platform/SpiFvbServices/SpiFlashDevice.h  |  181 +
>> > Platform/Intel/QuarkPlatformPkg/Quark.dsc     |  948
>> ++++
>> > Platform/Intel/QuarkPlatformPkg/Quark.fdf     |  907
>> ++++
>> > Platform/Intel/QuarkPlatformPkg/QuarkMin.dsc  |  648
>> +++
>> > Platform/Intel/QuarkPlatformPkg/QuarkMin.fdf  |  608
>> +++
>> > .../QuarkPlatformPkg/QuarkPlatformPkg.dec     |  933
>> ++++
>> > Platform/Intel/QuarkPlatformPkg/Readme.md     |  685
>> +++
>> > Platform/Intel/Vlv2TbltDevicePkg/.gitignore   |    5 +
>> > .../AcpiPlatform/AcpiPlatform.c               | 1338
>> +++++
>> > .../AcpiPlatform/AcpiPlatform.h               |  219 +
>> > .../AcpiPlatform/AcpiPlatform.inf             |   89 +
>> > .../AcpiPlatform/AcpiPlatformHooks.c          |  493 ++
>> > .../AcpiPlatform/AcpiPlatformHooks.h          |  127 +
>> > .../AcpiPlatform/AcpiPlatformHooksLib.h       |   91 +
>> > .../Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h     |   56 +
>> > .../FirmwareUpdate/FirmwareUpdate.c           |  922
>> ++++
>> > .../FirmwareUpdate/FirmwareUpdate.h           |  185 +
>> > .../FirmwareUpdate/FirmwareUpdate.inf         |   83 +
>> > .../FirmwareUpdate/FirmwareUpdateStrings.uni  |   45 +
>> > Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe   |  Bin 0
>> -> 499712 bytes
>> > Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env  |   25 +
>> > Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env  |   25 +
>> > .../Intel/Vlv2TbltDevicePkg/BiosIdx64D.env    |   25 +
>> > .../Intel/Vlv2TbltDevicePkg/BiosIdx64R.env    |   25 +
>> > .../BootScriptSaveDxe/BootScriptSaveDxe.inf   |   60 +
>> > .../InternalBootScriptSave.h                  |  102 +
>> > .../BootScriptSaveDxe/ScriptSave.c            |  626
>> +++
>> > .../Intel/Vlv2TbltDevicePkg/Build_IFWI.bat    |  200 +
>> > .../Intel/Vlv2TbltDevicePkg/Build_IFWI.sh     |  104 +
>> > Platform/Intel/Vlv2TbltDevicePkg/FCE.exe      |  Bin 0
>> -> 632832 bytes
>> > .../Capsule/GenerateCapsule/GenCapsuleAll.bat |   35 +
>> > .../Capsule/GenerateCapsule/GenCapsuleAll.sh  |   28 +
>> > .../GenerateCapsule/GenCapsuleMinnowMax.bat   |  131 +
>> > .../GenerateCapsule/GenCapsuleMinnowMax.sh    |   65 +
>> > .../GenCapsuleMinnowMaxRelease.bat            |  131 +
>> > .../GenCapsuleMinnowMaxRelease.sh             |   65 +
>> > .../GenerateCapsule/GenCapsuleSampleColor.bat |  137 +
>> > .../GenerateCapsule/GenCapsuleSampleColor.sh  |   70 +
>> > .../Feature/Capsule/GenerateCapsule/Lvfs.ddf  |   14 +
>> > .../LvfsGenCapsuleMinnowMax.bat               |  139 +
>> > .../LvfsGenCapsuleMinnowMaxRelease.bat        |  139 +
>> > .../LvfsGenCapsuleSampleColor.bat             |  145 +
>> > ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
>> > ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
>> > ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
>> > .../GenerateCapsule/template.metainfo.xml     |   27 +
>> > .../Library/FmpDeviceLib/FmpDeviceLib.c       |  589
>> +++
>> > .../Library/FmpDeviceLib/FmpDeviceLib.inf     |   46 +
>> > .../Library/FmpDeviceLibSample/FmpDeviceLib.c |  412 ++
>> > .../FmpDeviceLibSample/FmpDeviceLib.inf       |   34 +
>> > .../PlatformFlashAccessLib.c                  |  685
>> +++
>> > .../PlatformFlashAccessLib.inf                |   54 +
>> > .../SystemFirmwareDescriptor.aslc             |   83 +
>> > .../SystemFirmwareDescriptor.inf              |   40 +
>> > .../SystemFirmwareDescriptorPei.c             |   60 +
>> > .../SystemFirmwareUpdateConfig.ini            |   66 +
>> > .../SystemFirmwareUpdateConfigGcc.ini         |   66 +
>> > .../Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc |   55 +
>> > .../Vlv2TbltDevicePkg/FmpCertificate.dsc      |   22 +
>> > .../FmpGreenSampleDevice.dsc                  |   55 +
>> > .../Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc  |   59 +
>> > .../Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc  |   55 +
>> > .../FspAzaliaConfigData/AzaliaConfig.bin      |  Bin 0
>> -> 3708 bytes
>> > .../FspSupport/BootModePei/BootModePei.c      |   42 +
>> > .../FspSupport/BootModePei/BootModePei.inf    |   40 +
>> > .../FspHobProcessLibVlv2.c                    |  421 ++
>> > .../FspHobProcessLibVlv2.inf                  |   74 +
>> > .../FspPlatformSecLibVlv2.c                   |  144 +
>> > .../FspPlatformSecLibVlv2.inf                 |   82 +
>> > .../Ia32/AsmSaveSecContext.asm                |   45 +
>> > .../SecFspPlatformSecLibVlv2/Ia32/Fsp.inc     |   45 +
>> > .../Ia32/PeiCoreEntry.asm                     |  135 +
>> > .../Ia32/SecEntry.asm                         |  338 ++
>> > .../SecFspPlatformSecLibVlv2/Ia32/Stack.S     |   71 +
>> > .../SecFspPlatformSecLibVlv2/Ia32/Stack.asm   |   76 +
>> > .../SecFspPlatformSecLibVlv2/PlatformInit.c   |   36 +
>> > .../SecFspPlatformSecLibVlv2/SaveSecContext.c |  108 +
>> > .../SecGetPerformance.c                       |   83 +
>> > .../SecPlatformInformation.c                  |   77 +
>> > .../SecFspPlatformSecLibVlv2/SecRamInitData.c |   16 +
>> > .../SecTempRamSupport.c                       |  149 +
>> > .../SecFspPlatformSecLibVlv2/UartInit.c       |  192 +
>> > .../Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c   |   68 +
>> > .../Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf |   49 +
>> > .../Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c |  170 +
>> > .../FvbRuntimeDxe/FvbRuntimeDxe.inf           |   80 +
>> > .../FvbRuntimeDxe/FvbService.c                | 1098
>> ++++
>> > .../FvbRuntimeDxe/FvbService.h                |  182 +
>> > .../FvbRuntimeDxe/FvbServiceDxe.c             |  199 +
>> > .../FvbRuntimeDxe/FvbServiceSmm.c             |  127 +
>> > .../FvbRuntimeDxe/FvbSmm.inf                  |   82 +
>> > .../FvbRuntimeDxe/FvbSmmCommon.h              |   73 +
>> > .../FvbRuntimeDxe/FvbSmmDxe.c                 |  944
>> ++++
>> > .../FvbRuntimeDxe/FvbSmmDxe.h                 |  232 +
>> > .../FvbRuntimeDxe/FvbSmmDxe.inf               |   50 +
>> > Platform/Intel/Vlv2TbltDevicePkg/GenBiosId    |  Bin 0
>> -> 12236 bytes
>> > .../Intel/Vlv2TbltDevicePkg/GenBiosId.exe     |  Bin 0
>> -> 384000 bytes
>> > .../Include/AlertStandardFormatTable.h        |  122 +
>> > .../Vlv2TbltDevicePkg/Include/ChipsetAccess.h |   28 +
>> > .../Include/CommonIncludes.h                  |  115 +
>> > .../Intel/Vlv2TbltDevicePkg/Include/CpuType.h |   59 +
>> > .../Vlv2TbltDevicePkg/Include/FileHandleLib.h |  499 ++
>> > .../Include/Guid/AcpiTableStorage.h           |   30 +
>> > .../Include/Guid/AlertStandardFormat.h        |   86 +
>> > .../Vlv2TbltDevicePkg/Include/Guid/BiosId.h   |   30 +
>> > .../Include/Guid/BoardFeatures.h              |  214 +
>> > .../Include/Guid/EfiVpdData.h                 |  156 +
>> > .../Include/Guid/FirmwareId.h                 |   61 +
>> > .../Include/Guid/HwWatchdogTimerHob.h         |  134 +
>> > .../Vlv2TbltDevicePkg/Include/Guid/IdccData.h |  104 +
>> > .../Vlv2TbltDevicePkg/Include/Guid/ItkData.h  |   70 +
>> > .../Include/Guid/MemoryConfigData.h           |   32 +
>> > .../Include/Guid/OsSelection.h                |   85 +
>> > .../Include/Guid/PciLanInfo.h                 |   39 +
>> > .../Include/Guid/PlatformCpuInfo.h            |  180 +
>> > .../Include/Guid/PlatformInfo.h               |  433 ++
>> > .../Include/Guid/SensorInfoVariable.h         |  279 +
>> > .../Include/Guid/SetupVariable.h              | 1344
>> +++++
>> > .../Intel/Vlv2TbltDevicePkg/Include/Hpet.h    |   40 +
>> > .../Include/Library/BiosIdLib.h               |  104 +
>> > .../Include/Library/CpuIA32.h                 |  345 ++
>> > .../Include/Library/EfiRegTableLib.h          |  196 +
>> > .../Vlv2TbltDevicePkg/Include/Library/Esrt.h  |   74 +
>> > .../Vlv2TbltDevicePkg/Include/Library/Fd.h    |  264 +
>> > .../Include/Library/FlashDeviceLib.h          |  122 +
>> > .../Include/Library/I2CLib.h                  |   58 +
>> > .../Include/Library/I2cMmioConfigLib.h        |   23 +
>> > .../Include/Library/I2cPort_platform.h        |   26 +
>> > .../Include/Library/PlatformFsaLib.h          |   50 +
>> > .../Include/Library/PlatformFspLib.h          |   23 +
>> > .../Include/Library/SpiFlash.H                |  239 +
>> > .../Include/Library/StallSmmLib.h             |   40 +
>> > .../Include/Library/UsbDeviceModeLib.h        |  181 +
>> > .../Intel/Vlv2TbltDevicePkg/Include/Mcfg.h    |   69 +
>> > .../Vlv2TbltDevicePkg/Include/McfgTable.h     |   65 +
>> > .../Vlv2TbltDevicePkg/Include/Platform.h      |  133 +
>> > .../Include/PlatformBootMode.h                |   35 +
>> > .../Include/PlatformDefinitions.h             |   43 +
>> > .../Include/Ppi/MfgMemoryTest.h               |   42 +
>> > .../Include/Ppi/Sha256Hash.h                  |  131 +
>> > .../Vlv2TbltDevicePkg/Include/Ppi/Speaker.h   |   65 +
>> > .../Include/Ppi/UsbController.h               |   85 +
>> > .../Include/Protocol/CK505ClockPlatformInfo.h |  126 +
>> > .../Include/Protocol/EnhancedSpeedstep.h      |   76 +
>> > .../Include/Protocol/GlobalNvsArea.h          |  475 ++
>> > .../Include/Protocol/HwWatchdogTimer.h        |  235 +
>> > .../Include/Protocol/I2cAcpi.h                |  107 +
>> > .../Include/Protocol/I2cBus.h                 |  164 +
>> > .../Include/Protocol/I2cBusMcg.h              |  163 +
>> > .../Include/Protocol/I2cHostMcg.h             |  138 +
>> > .../Include/Protocol/I2cMasterMcg.h           |  519 ++
>> > .../Include/Protocol/I2cSlave.h               |  194 +
>> > .../Include/Protocol/LpcWpc83627Policy.h      |   92 +
>> > .../Include/Protocol/LpcWpce791Policy.h       |   55 +
>> > .../Include/Protocol/MmioDevice.h             |   84 +
>> > .../Include/Protocol/Observable.h             |  186 +
>> > .../Include/Protocol/PlatformGopPolicy.h      |   68 +
>> > .../Include/Protocol/PlatformIdeInit.h        |   43 +
>> > .../Include/Protocol/SetupMode.h              |   79 +
>> > .../Include/Protocol/SmbiosSlotPopulation.h   |   47 +
>> > .../Include/Protocol/Speaker.h                |   65 +
>> > .../Include/Protocol/TcoReset.h               |   67 +
>> > .../Include/Protocol/TpmMp.h                  |  136 +
>> > .../Include/Protocol/UsbPolicy.h              |  126 +
>> > .../Include/Protocol/VlvPlatformPolicy.h      |  102 +
>> > .../Vlv2TbltDevicePkg/Include/SetupMode.h     |   85 +
>> > .../IntelGopDepex/IntelGopDriver.depex        |    1 +
>> > .../Library/BiosIdLib/BiosIdLib.c             |  337 ++
>> > .../Library/BiosIdLib/BiosIdLib.inf           |   50 +
>> > .../Library/CpuIA32Lib/CpuIA32Lib.inf         |   41 +
>> > .../Library/CpuIA32Lib/EfiCpuVersion.c        |   70 +
>> > .../Library/CpuIA32Lib/IA32/CpuIA32.S         |  223 +
>> > .../Library/CpuIA32Lib/IA32/CpuIA32.asm       |  206 +
>> > .../Library/CpuIA32Lib/IA32/CpuIA32.c         |  177 +
>> > .../Library/CpuIA32Lib/X64/Cpu.S              |  207 +
>> > .../Library/CpuIA32Lib/X64/Cpu.asm            |  222 +
>> > .../Library/EfiRegTableLib/EfiRegTableLib.c   |  282 ++
>> > .../Library/EfiRegTableLib/EfiRegTableLib.inf |   47 +
>> > .../Library/FlashDeviceLib/FlashDeviceLib.c   |  461 ++
>> > .../Library/FlashDeviceLib/FlashDeviceLib.inf |   44 +
>> > .../FlashDeviceLib/FlashDeviceLibDxe.c        |   56 +
>> > .../FlashDeviceLib/FlashDeviceLibDxe.inf      |   43 +
>> > .../FlashDeviceLibDxeRuntimeSmm.c             |  173 +
>> > .../FlashDeviceLib/SpiChipDefinitions.h       |  835
>> +++
>> > .../Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c |   46 +
>> > .../Library/I2CLib/I2CLibNull.inf             |   39 +
>> > .../Library/I2CLibDxe/I2CLib.c                |  735
>> +++
>> > .../Library/I2CLibDxe/I2CLibDxe.inf           |   39 +
>> > .../Library/I2CLibDxe/I2CRegs.h               |  126 +
>> > .../Library/I2CLibPei/I2CAccess.h             |   44 +
>> > .../Library/I2CLibPei/I2CDelayPei.c           |   46 +
>> > .../Library/I2CLibPei/I2CDelayPei.h           |   30 +
>> > .../Library/I2CLibPei/I2CIoLibPei.c           |  178 +
>> > .../Library/I2CLibPei/I2CIoLibPei.h           |  153 +
>> > .../Library/I2CLibPei/I2CLibPei.c             |  638
>> +++
>> > .../Library/I2CLibPei/I2CLibPei.h             |  280 +
>> > .../Library/I2CLibPei/I2CLibPei.inf           |   40 +
>> > .../IntelPchAcpiTimerLib/CommonHeader.h       |   27 +
>> > .../IntelPchAcpiTimerLib.c                    |  255 +
>> > .../IntelPchAcpiTimerLib.inf                  |   51 +
>> > .../BoardClkGens/BoardClkGens.c               |  430 ++
>> > .../BoardClkGens/BoardClkGens.h               |  255 +
>> > .../MultiPlatformLib/BoardGpios/BoardGpios.c  |  531 ++
>> > .../MultiPlatformLib/BoardGpios/BoardGpios.h  |  324 ++
>> > .../BoardJumpers/BoardJumpers.c               |   30 +
>> > .../BoardJumpers/BoardJumpers.h               |   30 +
>> > .../BoardOemIds/BoardOemIds.c                 |   43 +
>> > .../BoardOemIds/BoardOemIds.h                 |   29 +
>> > .../BoardSsidSvid/BoardSsidSvid.c             |   38 +
>> > .../BoardSsidSvid/BoardSsidSvid.h             |   35 +
>> > .../MultiPlatformLib/MultiPlatformLib.c       |  120 +
>> > .../MultiPlatformLib/MultiPlatformLib.h       |   89 +
>> > .../MultiPlatformLib/MultiPlatformLib.inf     |   77 +
>> > .../MultiPlatformLib/PlatformInfoHob.c        |   54 +
>> > .../Library/PchPlatformLib/PchPlatformLib.inf |   50 +
>> > .../PchPlatformLib/PchPlatformLibrary.c       |  131 +
>> > .../PchPlatformLib/PchPlatformLibrary.h       |   35 +
>> > .../Library/PchSmmLib/CommonHeader.h          |   32 +
>> > .../Library/PchSmmLib/PchSmmLib.c             |  157 +
>> > .../Library/PchSmmLib/PchSmmLib.inf           |   46 +
>> > .../Library/PlatformBdsLib/BdsPlatform.c      | 3098
>> ++++++++++++
>> > .../Library/PlatformBdsLib/BdsPlatform.h      |  516 ++
>> > .../Library/PlatformBdsLib/PlatformBdsLib.inf |  127 +
>> > .../PlatformBdsLib/PlatformBdsStrings.uni     |   30 +
>> > .../Library/PlatformBdsLib/PlatformData.c     |  306 ++
>> > .../Library/PlatformCmosLib/PlatformCmosLib.c |  106 +
>> > .../PlatformCmosLib/PlatformCmosLib.inf       |   30 +
>> > .../Library/PlatformFspLib/PlatformFspLib.c   |   44 +
>> > .../Library/PlatformFspLib/PlatformFspLib.inf |   49 +
>> > .../Library/ResetSystemLib/ResetSystemLib.c   |  235 +
>> > .../Library/ResetSystemLib/ResetSystemLib.inf |   47 +
>> > .../SerialPortLib/PlatformSerialPortLib.h     |   53 +
>> > .../Library/SerialPortLib/SerialPortLib.c     |  246 +
>> > .../Library/SerialPortLib/SerialPortLib.inf   |   52 +
>> > .../Library/SerialPortLib/SioInit.c           |  127 +
>> > .../Library/SerialPortLib/SioInit.h           |   62 +
>> > .../Library/SmbusLib/CommonHeader.h           |   26 +
>> > .../Library/SmbusLib/SmbusLib.c               |  873
>> ++++
>> > .../Library/SmbusLib/SmbusLib.inf             |   46 +
>> > .../Library/StallSmmLib/StallSmm.c            |   89 +
>> > .../Library/StallSmmLib/StallSmmLib.inf       |   51 +
>> > .../Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.c    |  117 +
>> > .../Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.inf  |   61 +
>> > .../Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.c    |  145 +
>> > .../Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.inf  |   60 +
>> > .../Intel/Vlv2TbltDevicePkg/Logo/Logo.bmp     |  Bin 0
>> -> 94434 bytes
>> > .../Metronome/LegacyMetronome.c               |  185 +
>> > .../Metronome/LegacyMetronome.h               |   64 +
>> > .../Vlv2TbltDevicePkg/Metronome/Metronome.inf |   49 +
>> > .../MonoStatusCode/EfiStatusCode.h            |  178 +
>> > .../MonoStatusCode/MonoStatusCode.c           |  132 +
>> > .../MonoStatusCode/MonoStatusCode.h           |  128 +
>> > .../MonoStatusCode/MonoStatusCode.inf         |   72 +
>> > .../MonoStatusCode/PeiPostCode.c              |  121 +
>> > .../MonoStatusCode/PlatformStatusCode.c       |  381 ++
>> > .../MonoStatusCode/PlatformStatusCode.h       |  138 +
>> > .../Library/GenericBdsLib/BdsBoot.c           | 4490
>> +++++++++++++++++
>> > .../Library/GenericBdsLib/BdsConnect.c        |  429 ++
>> > .../Library/GenericBdsLib/BdsConsole.c        | 1061
>> ++++
>> > .../Library/GenericBdsLib/BdsMisc.c           | 1575
>> ++++++
>> > .../Library/GenericBdsLib/DevicePath.c        |   27 +
>> > .../Library/GenericBdsLib/GenericBdsLib.inf   |  142 +
>> > .../Library/GenericBdsLib/GenericBdsLib.uni   |   19 +
>> > .../GenericBdsLib/GenericBdsStrings.uni       |   30 +
>> > .../Library/GenericBdsLib/InternalBdsLib.h    |  173 +
>> > .../Library/GenericBdsLib/String.c            |   26 +
>> > .../Library/GenericBdsLib/String.h            |   42 +
>> > .../PciPlatform/BoardPciPlatform.c            |   55 +
>> > .../PciPlatform/PciPlatform.c                 |  367 ++
>> > .../PciPlatform/PciPlatform.h                 |   83 +
>> > .../PciPlatform/PciPlatform.inf               |   65 +
>> > .../Vlv2TbltDevicePkg/PlatformCapsule.dsc     |   39 +
>> > .../Vlv2TbltDevicePkg/PlatformCapsule.fdf     |   52 +
>> > .../Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc  |   38 +
>> > .../Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf  |   52 +
>> > .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.c   |   60 +
>> > .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.h   |   29 +
>> > .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf |   55 +
>> > .../PlatformDxe/AzaliaVerbTable.h             |  247 +
>> > .../Vlv2TbltDevicePkg/PlatformDxe/BoardId.c   |  223 +
>> > .../PlatformDxe/BoardIdDecode.c               |  129 +
>> > .../PlatformDxe/BoardIdDecode.h               |   61 +
>> > .../PlatformDxe/ClockControl.c                |  202 +
>> > .../PlatformDxe/Configuration.h               |  692
>> +++
>> > .../Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c |   89 +
>> > .../PlatformDxe/IchPlatformPolicy.c           |  484 ++
>> > .../PlatformDxe/IchRegTable.c                 |  134 +
>> > .../PlatformDxe/IchTcoReset.c                 |  211 +
>> > .../Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c  |   72 +
>> > .../PlatformDxe/LegacySpeaker.c               |  161 +
>> > .../PlatformDxe/LegacySpeaker.h               |   69 +
>> > .../PlatformDxe/Observable/Observable.c       |  582
>> +++
>> > .../PlatformDxe/Observable/Observable.h       |  137 +
>> > .../Vlv2TbltDevicePkg/PlatformDxe/PciBus.h    |  379 ++
>> > .../Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c |  506 ++
>> > .../Vlv2TbltDevicePkg/PlatformDxe/Platform.c  | 1820
>> +++++++
>> > .../PlatformDxe/PlatformDxe.h                 |  722
>> +++
>> > .../PlatformDxe/PlatformDxe.inf               |  149 +
>> > .../Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c |  154 +
>> > .../Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c |  112 +
>> > .../PlatformDxe/SioPlatformPolicy.c           |   82 +
>> > .../PlatformDxe/SlotConfig.c                  |  148 +
>> > .../PlatformDxe/SlotConfig.h                  |   80 +
>> > .../PlatformGopPolicy/PlatformGopPolicy.c     |  201 +
>> > .../PlatformGopPolicy/PlatformGopPolicy.inf   |   51 +
>> > .../PlatformInfoDxe/PlatformInfoDxe.c         |  169 +
>> > .../PlatformInfoDxe/PlatformInfoDxe.h         |   30 +
>> > .../PlatformInfoDxe/PlatformInfoDxe.inf       |   52 +
>> > .../PlatformInitPei/BootMode.c                |  434 ++
>> > .../PlatformInitPei/CpuInitPeim.c             |   44 +
>> > .../Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c  |  319 ++
>> > .../PlatformInitPei/FlashMap.c                |  143 +
>> > .../PlatformInitPei/LegacySpeaker.c           |  168 +
>> > .../PlatformInitPei/LegacySpeaker.h           |   71 +
>> > .../PlatformInitPei/MchInit.c                 |   72 +
>> > .../PlatformInitPei/MemoryCallback.c          |  338 ++
>> > .../PlatformInitPei/MemoryPeim.c              |  408 ++
>> > .../PlatformInitPei/PchInitPeim.c             |  808
>> +++
>> > .../PlatformInitPei/PlatformEarlyInit.c       | 1195
>> +++++
>> > .../PlatformInitPei/PlatformEarlyInit.h       | 1499
>> ++++++
>> > .../PlatformInitPei/PlatformInfoInit.c        |  181 +
>> > .../PlatformInitPei/PlatformInitPei.inf       |  117 +
>> > .../PlatformInitPei/PlatformSsaInitPeim.c     |   58 +
>> > .../PlatformInitPei/Recovery.c                |  361 ++
>> > .../Vlv2TbltDevicePkg/PlatformInitPei/Stall.c |   91 +
>> > .../Vlv2TbltDevicePkg/PlatformPei/BootMode.c  |  346 ++
>> > .../PlatformPei/CommonHeader.h                |   60 +
>> > .../PlatformPei/MemoryCallback.c              |  154 +
>> > .../Vlv2TbltDevicePkg/PlatformPei/Platform.c  | 1198
>> +++++
>> > .../Vlv2TbltDevicePkg/PlatformPei/Platform.h  |  213 +
>> > .../PlatformPei/PlatformPei.inf               |  129 +
>> > .../Vlv2TbltDevicePkg/PlatformPei/Stall.c     |   90 +
>> > .../Intel/Vlv2TbltDevicePkg/PlatformPkg.dec   |  211 +
>> > .../Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf   | 1073
>> ++++
>> > .../Vlv2TbltDevicePkg/PlatformPkgConfig.dsc   |  107 +
>> > .../Vlv2TbltDevicePkg/PlatformPkgGcc.fdf      | 1033
>> ++++
>> > .../Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc   | 1711
>> +++++++
>> > .../Vlv2TbltDevicePkg/PlatformPkgIA32.dsc     | 1699
>> +++++++
>> > .../Vlv2TbltDevicePkg/PlatformPkgX64.dsc      | 1714
>> +++++++
>> > .../PlatformSetupDxe/Boot.vfi                 |   72 +
>> > .../PlatformSetupDxe/Configuration.h          |   56 +
>> > .../PlatformSetupDxe/DebugConfig.vfi          |  118 +
>> > .../PlatformSetupDxe/FwVersionStrings.uni     |   40 +
>> > .../PlatformSetupDxe/Main.vfi                 |  331 ++
>> > .../PlatformSetupDxe/PlatformSetupDxe.c       |  929
>> ++++
>> > .../PlatformSetupDxe/PlatformSetupDxe.h       |   97 +
>> > .../PlatformSetupDxe/PlatformSetupDxe.inf     |  141 +
>> > .../PlatformSetupDxe/Security.vfi             |  104 +
>> > .../PlatformSetupDxe/SetupFunctions.c         |   85 +
>> > .../PlatformSetupDxe/SetupInfoRecords.c       | 1855
>> +++++++
>> > .../PlatformSetupDxe/SouthClusterConfig.vfi   |  933
>> ++++
>> > .../PlatformSetupDxe/SystemComponent.vfi      |   81 +
>> > .../PlatformSetupDxe/Thermal.vfi              |  106 +
>> > .../PlatformSetupDxe/UnCore.vfi               |  235 +
>> > .../PlatformSetupDxe/UqiList.uni              |  452 ++
>> > .../PlatformSetupDxe/Vfr.vfr                  |  123 +
>> > .../PlatformSetupDxe/VfrStrings.uni           | 1417
>> ++++++
>> > .../Vlv2TbltDevicePkg/PlatformSmm/Platform.c  |  997
>> ++++
>> > .../PlatformSmm/PlatformSmm.inf               |   93 +
>> > .../Vlv2TbltDevicePkg/PlatformSmm/S3Save.c    |  377 ++
>> > .../PlatformSmm/SmmPlatform.h                 |  240 +
>> > .../PlatformSmm/SmmScriptSave.c               |  252 +
>> > .../PlatformSmm/SmmScriptSave.h               |   50 +
>> > .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c   |  148 +
>> > .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h   |   36 +
>> > .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf |   49 +
>> > Platform/Intel/Vlv2TbltDevicePkg/Readme.md    |  233 +
>> > .../SaveMemoryConfig/SaveMemoryConfig.c       |  181 +
>> > .../SaveMemoryConfig/SaveMemoryConfig.h       |   66 +
>> > .../SaveMemoryConfig/SaveMemoryConfig.inf     |   60 +
>> > .../SmBiosMiscDxe/CommonHeader.h              |   39 +
>> > .../MiscBaseBoardManufacturer.uni             |   33 +
>> > .../MiscBaseBoardManufacturerData.c           |   58 +
>> > .../MiscBaseBoardManufacturerFunction.c       |  238 +
>> > .../SmBiosMiscDxe/MiscBiosVendor.uni          |   26 +
>> > .../SmBiosMiscDxe/MiscBiosVendorData.c        |  101 +
>> > .../SmBiosMiscDxe/MiscBiosVendorFunction.c    |  336 ++
>> > .../SmBiosMiscDxe/MiscBootInformationData.c   |   34 +
>> > .../MiscBootInformationFunction.c             |   82 +
>> > .../SmBiosMiscDxe/MiscChassisManufacturer.uni |   28 +
>> > .../MiscChassisManufacturerData.c             |   57 +
>> > .../MiscChassisManufacturerFunction.c         |  158 +
>> > .../SmBiosMiscDxe/MiscMemoryDevice.uni        |   35 +
>> > .../SmBiosMiscDxe/MiscMemoryDeviceData.c      |   45 +
>> > .../SmBiosMiscDxe/MiscMemoryDeviceFunction.c  |  319 ++
>> > .../MiscNumberOfInstallableLanguagesData.c    |   38 +
>> > ...MiscNumberOfInstallableLanguagesFunction.c |  251 +
>> > .../SmBiosMiscDxe/MiscOemString.uni           |   25 +
>> > .../SmBiosMiscDxe/MiscOemStringData.c         |   34 +
>> > .../SmBiosMiscDxe/MiscOemStringFunction.c     |   89 +
>> > .../SmBiosMiscDxe/MiscOemType0x90.uni         |   31 +
>> > .../SmBiosMiscDxe/MiscOemType0x90Data.c       |   36 +
>> > .../SmBiosMiscDxe/MiscOemType0x90Function.c   |  442 ++
>> > .../SmBiosMiscDxe/MiscOemType0x94.uni         |   42 +
>> > .../SmBiosMiscDxe/MiscOemType0x94Data.c       |   54 +
>> > .../SmBiosMiscDxe/MiscOemType0x94Function.c   | 1218
>> +++++
>> > .../SmBiosMiscDxe/MiscOnboardDevice.uni       |   26 +
>> > .../SmBiosMiscDxe/MiscOnboardDeviceData.c     |   48 +
>> > .../SmBiosMiscDxe/MiscOnboardDeviceFunction.c |  135 +
>> > .../SmBiosMiscDxe/MiscPhysicalArray.uni       |   25 +
>> > .../SmBiosMiscDxe/MiscPhysicalArrayData.c     |   38 +
>> > .../SmBiosMiscDxe/MiscPhysicalArrayFunction.c |  101 +
>> > .../MiscPortInternalConnectorDesignator.uni   |   31 +
>> > .../MiscPortInternalConnectorDesignatorData.c |   56 +
>> > ...cPortInternalConnectorDesignatorFunction.c |  152 +
>> > .../SmBiosMiscDxe/MiscProcessorCache.uni      |   22 +
>> > .../SmBiosMiscDxe/MiscProcessorCacheData.c    |   33 +
>> > .../MiscProcessorCacheFunction.c              |  189 +
>> > .../MiscProcessorInformation.uni              |   27 +
>> > .../MiscProcessorInformationData.c            |   71 +
>> > .../MiscProcessorInformationFunction.c        |  448 ++
>> > .../SmBiosMiscDxe/MiscResetCapabilitiesData.c |   43 +
>> > .../MiscResetCapabilitiesFunction.c           |   85 +
>> > .../SmBiosMiscDxe/MiscSubclassDriver.h        |  188 +
>> > .../SmBiosMiscDxe/MiscSubclassDriver.uni      |   35 +
>> > .../MiscSubclassDriverDataTable.c             |   98 +
>> > .../MiscSubclassDriverEntryPoint.c            |  182 +
>> > .../MiscSystemLanguageString.uni              |   24 +
>> > .../MiscSystemLanguageStringData.c            |   34 +
>> > .../MiscSystemLanguageStringFunction.c        |   93 +
>> > .../SmBiosMiscDxe/MiscSystemManufacturer.uni  |   30 +
>> > .../MiscSystemManufacturerData.c              |   48 +
>> > .../MiscSystemManufacturerFunction.c          |  364 ++
>> > .../SmBiosMiscDxe/MiscSystemOptionString.uni  |   24 +
>> > .../MiscSystemOptionStringData.c              |   31 +
>> > .../MiscSystemOptionStringFunction.c          |   93 +
>> > .../MiscSystemSlotDesignation.uni             |   34 +
>> > .../MiscSystemSlotDesignationData.c           |  246 +
>> > .../MiscSystemSlotDesignationFunction.c       |  127 +
>> > .../SmBiosMiscDxe/SmBiosMiscDxe.inf           |  139 +
>> > .../SmmSwDispatch2OnSmmSwDispatchThunk.c      |  459 ++
>> > .../SmmSwDispatch2OnSmmSwDispatchThunk.inf    |   54 +
>> > .../SmramSaveInfoHandlerSmm.c                 |  164 +
>> > .../SmramSaveInfoHandlerSmm.inf               |   60 +
>> > .../Stitch/Gcc/NvStorageFtwSpare.bin          |  Bin 0
>> -> 262144 bytes
>> > .../Stitch/Gcc/NvStorageFtwWorking.bin        |  Bin 0
>> -> 8192 bytes
>> > .../Stitch/Gcc/NvStorageVariable.bin          |  Bin 0
>> -> 253952 bytes
>> > .../Stitch/IFWIHeader/IFWI_HEADER.bin         |  Bin 0
>> -> 4096 bytes
>> > .../Stitch/IFWIHeader/IFWI_HEADER_SPILOCK.bin |  Bin 0
>> -> 4096 bytes
>> > .../Stitch/IFWIHeader/Vacant.bin              |  Bin 0
>> -> 3928064 bytes
>> > .../Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat   |  270 +
>> > .../Stitch/MNW2_Stitch_Config.txt             |   10 +
>> > .../Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c |   33 +
>> > .../Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf   |   32 +
>> > .../VlvPlatformInitDxe/IgdOpRegion.c          |  929
>> ++++
>> > .../VlvPlatformInitDxe/IgdOpRegion.h          |  235 +
>> > .../VlvPlatformInitDxe/VlvPlatformInit.c      |  287 ++
>> > .../VlvPlatformInitDxe/VlvPlatformInit.h      |   65 +
>> > .../VlvPlatformInitDxe/VlvPlatformInitDxe.inf |   74 +
>> > .../Vlv2TbltDevicePkg/Wpce791/LpcDriver.c     |  340 ++
>> > .../Vlv2TbltDevicePkg/Wpce791/LpcDriver.h     |  112 +
>> > .../Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c    |  366 ++
>> > .../Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h    |  103 +
>> > .../Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c  |  126 +
>> > .../Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h  |  101 +
>> > .../Vlv2TbltDevicePkg/Wpce791/Wpce791.inf     |   63 +
>> > Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat  |  332 ++
>> > Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh   |  256 +
>> > Platform/Intel/Vlv2TbltDevicePkg/cln.sh       |   62 +
>> > Readme.md                                     |    9 +
>> > .../Include/DdrMemoryController.h             |  251 +
>> > .../QuarkNorthCluster/Include/IntelQNCBase.h  |   17 +
>> > .../Include/IntelQNCConfig.h                  |  100 +
>> > .../QuarkNorthCluster/Include/IntelQNCDxe.h   |   17 +
>> > .../QuarkNorthCluster/Include/IntelQNCPeim.h  |   17 +
>> > .../QuarkNorthCluster/Include/IntelQNCRegs.h  |   48 +
>> > .../Include/Library/IntelQNCLib.h             |  284 ++
>> > .../Include/Library/QNCAccessLib.h            |  161 +
>> > .../Include/Library/QNCSmmLib.h               |   57 +
>> > .../Include/Ppi/QNCMemoryInit.h               |   36 +
>> > .../Include/Protocol/PchInfo.h                |   48 +
>> > .../Include/Protocol/PlatformPolicy.h         |   31 +
>> > .../Include/Protocol/QncS3Support.h           |   84 +
>> > .../Include/Protocol/SmmIchnDispatch2.h       |  115 +
>> > .../QuarkNorthCluster/Include/Protocol/Spi.h  |  345 ++
>> > .../QuarkNorthCluster/Include/QNCAccess.h     |  177 +
>> > .../Include/QNCCommonDefinitions.h            |  350 ++
>> > .../QuarkNorthCluster/Include/QuarkNcSocId.h  |  751
>> +++
>> > .../Library/IntelQNCLib/CommonHeader.h        |   32 +
>> > .../Library/IntelQNCLib/IntelQNCLib.c         |  771
>> +++
>> > .../Library/IntelQNCLib/IntelQNCLib.inf       |   57 +
>> > .../Library/IntelQNCLib/PciExpress.c          |  932
>> ++++
>> > .../Library/MtrrLib/MtrrLib.c                 | 2112
>> ++++++++
>> > .../Library/MtrrLib/MtrrLib.inf               |   42 +
>> > .../Library/MtrrLib/MtrrLib.uni               |   18 +
>> > .../Library/QNCAccessLib/BaseAccess.c         |   28 +
>> > .../Library/QNCAccessLib/QNCAccessLib.c       |  327 ++
>> > .../Library/QNCAccessLib/QNCAccessLib.inf     |   37 +
>> > .../Library/QNCAccessLib/RuntimeAccess.c      |  142 +
>> > .../QNCAccessLib/RuntimeQNCAccessLib.inf      |   43 +
>> > .../Library/QNCSmmLib/QNCSmmLib.c             |  313 ++
>> > .../Library/QNCSmmLib/QNCSmmLib.inf           |   44 +
>> > .../Library/ResetSystemLib/ResetSystemLib.c   |  379 ++
>> > .../Library/ResetSystemLib/ResetSystemLib.inf |   46 +
>> > .../Library/SmbusLib/CommonHeader.h           |   25 +
>> > .../Library/SmbusLib/SmbusLib.c               |  797
>> +++
>> > .../Library/SmbusLib/SmbusLib.inf             |   47 +
>> > .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.c     |  446 ++
>> > .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf   |   30 +
>> > .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.uni   |   12 +
>> > .../MemoryInit/Pei/MemoryInit.c               |   59 +
>> > .../MemoryInit/Pei/MemoryInit.h               |   35 +
>> > .../MemoryInit/Pei/MemoryInitPei.inf          |   70 +
>> > .../MemoryInit/Pei/core_types.h               |   43 +
>> > .../MemoryInit/Pei/gen5_iosf_sb_definitions.h |  738
>> +++
>> > .../MemoryInit/Pei/general_definitions.h      |   84 +
>> > .../QuarkNorthCluster/MemoryInit/Pei/hte.c    |  536 ++
>> > .../QuarkNorthCluster/MemoryInit/Pei/hte.h    |   66 +
>> > .../QuarkNorthCluster/MemoryInit/Pei/io.h     |  132 +
>> > .../QuarkNorthCluster/MemoryInit/Pei/lprint.c |  382 ++
>> > .../MemoryInit/Pei/meminit.c                  | 2638
>> ++++++++++
>> > .../MemoryInit/Pei/meminit.h                  |   22 +
>> > .../MemoryInit/Pei/meminit_utils.c            | 1574
>> ++++++
>> > .../MemoryInit/Pei/meminit_utils.h            |   95 +
>> > .../MemoryInit/Pei/memory_options.h           |   77 +
>> > .../QuarkNorthCluster/MemoryInit/Pei/mrc.c    |   40 +
>> > .../QuarkNorthCluster/MemoryInit/Pei/mrc.h    |  160 +
>> > .../MemoryInit/Pei/platform.c                 |  186 +
>> > .../MemoryInit/Pei/prememinit.c               |  187 +
>> > .../MemoryInit/Pei/prememinit.h               |   15 +
>> > .../QNCInit/Dxe/CommonHeader.h                |   49 +
>> > .../QNCInit/Dxe/DxeQNCSmbus.c                 |  612
>> +++
>> > .../QNCInit/Dxe/DxeQNCSmbus.h                 |  205 +
>> > .../QNCInit/Dxe/LegacyRegion.c                |  237 +
>> > .../QNCInit/Dxe/LegacyRegion.h                |  198 +
>> > .../QuarkNorthCluster/QNCInit/Dxe/QNCInit.c   |  518 ++
>> > .../QuarkNorthCluster/QNCInit/Dxe/QNCInit.h   |   49 +
>> > .../QNCInit/Dxe/QNCInitDxe.inf                |   92 +
>> > .../QNCInit/Dxe/QNCRootPorts.c                |   76 +
>> > .../QuarkNorthCluster/QNCInit/Dxe/QNCSmbus.h  |   80 +
>> > .../QNCInit/Dxe/QNCSmbusExec.c                |  246 +
>> > .../S3Support/Dxe/QncS3Support.c              |  417 ++
>> > .../S3Support/Dxe/QncS3Support.h              |  117 +
>> > .../S3Support/Dxe/QncS3Support.inf            |   64 +
>> > .../Smm/Dxe/SmmAccessDxe/SmmAccess.inf        |   49 +
>> > .../Smm/Dxe/SmmAccessDxe/SmmAccessDriver.c    |  405 ++
>> > .../Smm/Dxe/SmmAccessDxe/SmmAccessDriver.h    |  230 +
>> > .../Smm/Dxe/SmmControlDxe/SmmControlDriver.c  |  358 ++
>> > .../Smm/Dxe/SmmControlDxe/SmmControlDxe.inf   |   55 +
>> > .../DxeSmm/QncSmmDispatcher/CommonHeader.h    |   45 +
>> > .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmGpi.c   |   32 +
>> > .../QncSmmDispatcher/QNC/QNCSmmHelpers.c      |  549 ++
>> > .../QNC/QNCSmmPeriodicTimer.c                 |  424 ++
>> > .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmQncn.c  |  211 +
>> > .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmSw.c    |   90 +
>> > .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmSx.c    |  147 +
>> > .../Smm/DxeSmm/QncSmmDispatcher/QNCSmm.h      |  868
>> ++++
>> > .../Smm/DxeSmm/QncSmmDispatcher/QNCSmmCore.c  |  825
>> +++
>> > .../QncSmmDispatcher/QNCSmmDispatcher.inf     |   81 +
>> > .../DxeSmm/QncSmmDispatcher/QNCSmmHelpers.c   |  367 ++
>> > .../DxeSmm/QncSmmDispatcher/QNCSmmHelpers.h   |  219 +
>> > .../DxeSmm/QncSmmDispatcher/QNCSmmRegisters.h |   13 +
>> > .../DxeSmm/QncSmmDispatcher/QNCxSmmHelpers.h  |  178 +
>> > .../Smm/Pei/SmmAccessPei/SmmAccessPei.c       |  376 ++
>> > .../Smm/Pei/SmmAccessPei/SmmAccessPei.inf     |   45 +
>> > .../Smm/Pei/SmmControlPei/SmmControlPei.c     |  274 +
>> > .../Smm/Pei/SmmControlPei/SmmControlPei.inf   |   51 +
>> > .../QuarkNorthCluster/Spi/Common/SpiCommon.c  |  927
>> ++++
>> > .../QuarkNorthCluster/Spi/Common/SpiCommon.h  |  317 ++
>> > .../QuarkNorthCluster/Spi/PchSpiRuntime.inf   |   84 +
>> > .../QuarkNorthCluster/Spi/PchSpiSmm.inf       |   50 +
>> > .../QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.c |  205 +
>> > .../QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.h |   79 +
>> > .../QuarkNorthCluster/Spi/Smm/PchSpi.c        |  123 +
>> > .../QuarkNorthCluster/Spi/Smm/PchSpi.h        |   47 +
>> > Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dec     |  234 +
>> > Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dsc     |  254 +
>> > .../QuarkSouthCluster/Include/CEATA.h         |  114 +
>> > .../QuarkSouthCluster/Include/I2cRegs.h       |   95 +
>> > .../QuarkSouthCluster/Include/Ioh.h           |  248 +
>> > .../QuarkSouthCluster/Include/IohAccess.h     |   18 +
>> > .../Include/IohCommonDefinitions.h            |  342 ++
>> > .../Include/Library/I2cLib.h                  |  152 +
>> > .../Include/Library/IohLib.h                  |   36 +
>> > .../QuarkSouthCluster/Include/MMC.h           |  274 +
>> > .../QuarkSouthCluster/Include/SDCard.h        |  146 +
>> > .../QuarkSouthCluster/Include/SDHostIo.h      |  333 ++
>> > .../IohInit/Dxe/CommonHeader.h                |   55 +
>> > .../QuarkSouthCluster/IohInit/Dxe/IohBds.h    |   83 +
>> > .../QuarkSouthCluster/IohInit/Dxe/IohData.c   |   42 +
>> > .../QuarkSouthCluster/IohInit/Dxe/IohInit.c   |   37 +
>> > .../IohInit/Dxe/IohInitDxe.inf                |   76 +
>> > .../Library/I2cLib/CommonHeader.h             |  214 +
>> > .../QuarkSouthCluster/Library/I2cLib/I2cLib.c |  998
>> ++++
>> > .../Library/I2cLib/I2cLib.inf                 |   62 +
>> > .../Library/IohLib/CommonHeader.h             |   29 +
>> > .../QuarkSouthCluster/Library/IohLib/IohLib.c |   99 +
>> > .../Library/IohLib/IohLib.inf                 |   49 +
>> > .../Sdio/Dxe/SDControllerDxe/ComponentName.c  |  227 +
>> > .../Sdio/Dxe/SDControllerDxe/ComponentName.h  |  141 +
>> > .../Sdio/Dxe/SDControllerDxe/SDController.c   | 1784
>> +++++++
>> > .../Sdio/Dxe/SDControllerDxe/SDController.h   |  316 ++
>> > .../Dxe/SDControllerDxe/SDControllerDxe.inf   |   56 +
>> > .../Sdio/Dxe/SDMediaDeviceDxe/CEATA.c         |  647
>> +++
>> > .../Sdio/Dxe/SDMediaDeviceDxe/CEATABlockIo.c  |  389 ++
>> > .../Sdio/Dxe/SDMediaDeviceDxe/ComponentName.c |  215 +
>> > .../Sdio/Dxe/SDMediaDeviceDxe/ComponentName.h |  139 +
>> > .../Sdio/Dxe/SDMediaDeviceDxe/MMCSDBlockIo.c  |  538 ++
>> > .../Sdio/Dxe/SDMediaDeviceDxe/MMCSDTransfer.c | 1708
>> +++++++
>> > .../Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.c |  317 ++
>> > .../Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.h |  462 ++
>> > .../Dxe/SDMediaDeviceDxe/SDMediaDeviceDxe.inf |   60 +
>> > .../QuarkSouthCluster/Usb/Common/Pei/UsbPei.c |  320 ++
>> > .../QuarkSouthCluster/Usb/Common/Pei/UsbPei.h |   38 +
>> > .../Usb/Common/Pei/UsbPei.inf                 |   53 +
>> > .../Usb/Ohci/Dxe/ComponentName.c              |  219 +
>> > .../Usb/Ohci/Dxe/ComponentName.h              |  141 +
>> > .../Usb/Ohci/Dxe/Descriptor.h                 |  132 +
>> > .../QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.c     | 2473
>> +++++++++
>> > .../QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.h     |  663
>> +++
>> > .../Usb/Ohci/Dxe/OhciDebug.c                  |   78 +
>> > .../Usb/Ohci/Dxe/OhciDebug.h                  |   42 +
>> > .../Usb/Ohci/Dxe/OhciDxe.inf                  |   71 +
>> > .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.c  | 1390
>> +++++
>> > .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.h  |  920
>> ++++
>> > .../Usb/Ohci/Dxe/OhciSched.c                  |  528 ++
>> > .../Usb/Ohci/Dxe/OhciSched.h                  |  225 +
>> > .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.c  |  889
>> ++++
>> > .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.h  |  387 ++
>> > .../QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.c |  560 ++
>> > .../QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.h |  152 +
>> > .../Usb/Ohci/Pei/Descriptor.h                 |  131 +
>> > .../QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.c  | 1386
>> +++++
>> > .../QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.h  |  252 +
>> > .../Usb/Ohci/Pei/OhciPei.inf                  |   56 +
>> > .../QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.c  | 1386
>> +++++
>> > .../QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.h  |  875
>> ++++
>> > .../Usb/Ohci/Pei/OhciSched.c                  |  223 +
>> > .../Usb/Ohci/Pei/OhciSched.h                  |  108 +
>> > .../QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.c  |  560 ++
>> > .../QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.h  |  231 +
>> > .../QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.c |  491 ++
>> > .../QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.h |  134 +
>> > .../AcpiTablesPCAT/98_LINK.ASL                |  617
>> +++
>> > .../AcpiTablesPCAT/AcpiTablePlatform.h        |   70 +
>> > .../AcpiTablesPCAT/AcpiTables.inf             |   40 +
>> > .../AcpiTablesPCAT/CPU.asl                    |   49 +
>> > .../AcpiTablesPCAT/DSDT.ASL                   |   75 +
>> > .../AcpiTablesPCAT/Facp/Facp.aslc             |  188 +
>> > .../AcpiTablesPCAT/Facs/Facs.aslc             |   84 +
>> > .../AcpiTablesPCAT/GloblNvs.asl               |  348 ++
>> > .../AcpiTablesPCAT/Gpe.asl                    |   99 +
>> > .../AcpiTablesPCAT/HOST_BUS.ASL               |  347 ++
>> > .../AcpiTablesPCAT/Hpet/Hpet.aslc             |   63 +
>> > .../AcpiTablesPCAT/INTELGFX.ASL               |  879
>> ++++
>> > .../AcpiTablesPCAT/INTELISPDev2.ASL           |   71 +
>> > .../AcpiTablesPCAT/IgdOGBDA.ASL               |  155 +
>> > .../AcpiTablesPCAT/IgdOMOBF.ASL               |  485 ++
>> > .../AcpiTablesPCAT/IgdOSBCB.ASL               |  274 +
>> > .../AcpiTablesPCAT/IgdOpRn.ASL                |  299 ++
>> > .../AcpiTablesPCAT/IoTVirtualDevice.asl       |  171 +
>> > .../AcpiTablesPCAT/LPC_DEV.ASL                |  151 +
>> > .../AcpiTablesPCAT/LpcB.asl                   |   59 +
>> > .../AcpiTablesPCAT/Lpit/Lpit.aslc             |  223 +
>> > .../AcpiTablesPCAT/Madt/Madt.h                |  189 +
>> > .../AcpiTablesPCAT/Madt/Madt30.aslc           |  178 +
>> > .../AcpiTablesPCAT/Mcfg/Mcfg.aslc             |   86 +
>> > .../AcpiTablesPCAT/PCI_DRC.ASL                |   90 +
>> > .../AcpiTablesPCAT/Pch.asl                    |  686
>> +++
>> > .../AcpiTablesPCAT/PchAudio.asl               |   36 +
>> > .../AcpiTablesPCAT/PchEhci.asl                |  269 +
>> > .../AcpiTablesPCAT/PchLpss.asl                | 1093
>> ++++
>> > .../AcpiTablesPCAT/PchPcie.asl                |   50 +
>> > .../AcpiTablesPCAT/PchScc.asl                 |  610
>> +++
>> > .../AcpiTablesPCAT/PchSmb.asl                 |  833
>> +++
>> > .../AcpiTablesPCAT/PchXhci.asl                |  379 ++
>> > .../AcpiTablesPCAT/PciTree.asl                |  377 ++
>> > .../AcpiTablesPCAT/Platform.asl               |  703
>> +++
>> > .../AcpiTablesPCAT/RTD3.asl                   |  197 +
>> > .../AcpiTablesPCAT/RhProxy.asl                |  160 +
>> > .../AcpiTablesPCAT/THERMAL.ASL                |  137 +
>> > .../AcpiTablesPCAT/UsbSbd.asl                 |   93 +
>> > .../AcpiTablesPCAT/Video.asl                  |   34 +
>> > .../AcpiTablesPCAT/Vlv.asl                    |   39 +
>> > .../AcpiTablesPCAT/Wsmt/Wsmt.aslc             |   54 +
>> > .../AcpiTablesPCAT/token.asl                  |   39 +
>> > .../Guid/Vlv2DeviceRefCodePkgTokenSpace.h     |   24 +
>> > .../Include/Ppi/PttPassThruPpi.h              |   92 +
>> > .../Include/Ppi/fTPMPolicy.h                  |   26 +
>> > .../Include/Protocol/PttPassThru.h            |   91 +
>> > .../Guid/PowerManagementAcpiTableStorage.h    |   27 +
>> > .../CPU/Include/Ppi/VlvPolicy.h               |  104 +
>> > .../CPU/Include/Protocol/PpmPlatformPolicy.h  |  132 +
>> > .../ValleyView2Soc/CPU/Include/Types.h        |   55 +
>> > .../AcpiTables/PowerManagementAcpiTables.inf  |   39 +
>> > .../PowerManagement/AcpiTables/Ssdt/ApCst.asl |  110 +
>> > .../PowerManagement/AcpiTables/Ssdt/ApIst.asl |  166 +
>> > .../PowerManagement/AcpiTables/Ssdt/ApTst.asl |  262 +
>> > .../AcpiTables/Ssdt/Cpu0Cst.asl               |  274 +
>> > .../AcpiTables/Ssdt/Cpu0Ist.asl               |  260 +
>> > .../AcpiTables/Ssdt/Cpu0Tst.asl               |  235 +
>> > .../PowerManagement/AcpiTables/Ssdt/CpuPm.asl |  793
>> +++
>> > .../Include/PlatformBaseAddresses.h           |   92 +
>> > .../NorthCluster/Include/Ppi/Capsule.h        |   60 +
>> > .../Include/Ppi/PlatformMemoryRange.h         |  144 +
>> > .../Include/Ppi/PlatformMemorySize.h          |   46 +
>> > .../NorthCluster/Include/Ppi/SmmAccess.h      |  165 +
>> > .../NorthCluster/Include/Ppi/VlvMmioPolicy.h  |   39 +
>> > .../NorthCluster/Include/Ppi/VlvPeiInit.h     |   35 +
>> > .../NorthCluster/Include/Ppi/VlvPolicy.h      |  106 +
>> > .../Include/Protocol/IgdOpRegion.h            |  213 +
>> > .../NorthCluster/Include/Protocol/MemInfo.h   |   83 +
>> > .../Include/Protocol/PlatformGopPolicy.h      |   67 +
>> > .../Include/Protocol/VlvPlatformPolicy.h      |  105 +
>> > .../NorthCluster/Include/Valleyview.h         |   55 +
>> > .../NorthCluster/Include/VlvAccess.h          |  254 +
>> > .../Include/VlvCommonDefinitions.h            |  252 +
>> > .../SouthCluster/Include/Guid/PchInitVar.h    |   48 +
>> > .../Include/Guid/SataControllerGuid.h         |   34 +
>> > .../SouthCluster/Include/Guid/SmbusArpMap.h   |   30 +
>> > .../SouthCluster/Include/Guid/Vlv2Variable.h  |   28 +
>> > .../Include/IndustryStandard/CeAta.h          |  126 +
>> > .../Include/IndustryStandard/Mmc.h            |  349 ++
>> > .../Include/IndustryStandard/SdCard.h         |  157 +
>> > .../SouthCluster/Include/Library/I2CLib.h     |  169 +
>> > .../Include/Library/PchPlatformLib.h          |  115 +
>> > .../SouthCluster/Include/PchAccess.h          |  471 ++
>> > .../Include/PchCommonDefinitions.h            |  210 +
>> > .../SouthCluster/Include/PchRegs.h            |  205 +
>> > .../SouthCluster/Include/PchRegs/PchRegsHda.h |   50 +
>> > .../Include/PchRegs/PchRegsLpss.h             |  486 ++
>> > .../Include/PchRegs/PchRegsPcie.h             |   83 +
>> > .../SouthCluster/Include/PchRegs/PchRegsPcu.h | 1201
>> +++++
>> > .../Include/PchRegs/PchRegsRcrb.h             |   48 +
>> > .../Include/PchRegs/PchRegsSata.h             |  245 +
>> > .../SouthCluster/Include/PchRegs/PchRegsScc.h |   53 +
>> > .../Include/PchRegs/PchRegsSmbus.h            |  149 +
>> > .../SouthCluster/Include/PchRegs/PchRegsSpi.h |  119 +
>> > .../SouthCluster/Include/PchRegs/PchRegsUsb.h |   92 +
>> > .../SouthCluster/Include/Ppi/PchInit.h        |   75 +
>> > .../SouthCluster/Include/Ppi/PchPeiInit.h     |   34 +
>> > .../Include/Ppi/PchPlatformPolicy.h           |  161 +
>> > .../SouthCluster/Include/Ppi/PchUsbPolicy.h   |   69 +
>> > .../SouthCluster/Include/Ppi/PeiBlockIo.h     |  230 +
>> > .../SouthCluster/Include/Ppi/Sdhc.h           |  359 ++
>> > .../SouthCluster/Include/Ppi/SmbusPolicy.h    |   40 +
>> > .../SouthCluster/Include/Ppi/Spi.h            |   42 +
>> > .../Include/Protocol/ActiveBios.h             |  123 +
>> > .../Include/Protocol/ActiveBiosProtocol.h     |  125 +
>> > .../Protocol/DxePchPolicyUpdateProtocol.h     |   51 +
>> > .../Include/Protocol/EmmcCardInfoProtocol.h   |   42 +
>> > .../SouthCluster/Include/Protocol/Gpio.h      |  161 +
>> > .../Include/Protocol/HwWatchdogTimer.h        |  294 ++
>> > .../SouthCluster/Include/Protocol/I2cBus.h    |  164 +
>> > .../Include/Protocol/PchExtendedReset.h       |   84 +
>> > .../SouthCluster/Include/Protocol/PchInfo.h   |   60 +
>> > .../Include/Protocol/PchPlatformPolicy.h      |  550 ++
>> > .../SouthCluster/Include/Protocol/PchReset.h  |  114 +
>> > .../Include/Protocol/PchS3Support.h           |  132 +
>> > .../SouthCluster/Include/Protocol/SdHostIo.h  |  409 ++
>> > .../Include/Protocol/SmbiosSlotPopulation.h   |   47 +
>> > .../Include/Protocol/SmmIchnDispatchEx.h      |  159 +
>> > .../SouthCluster/Include/Protocol/SmmSmbus.h  |   39 +
>> > .../SouthCluster/Include/Protocol/Spi.h       |  260 +
>> > .../SouthCluster/Include/Protocol/TcoReset.h  |   88 +
>> > .../SouthCluster/Include/Rsci.h               |   28 +
>> > .../SouthCluster/Include/TianoApi.h           |   61 +
>> > .../Vlv2DeviceRefCodePkg.dec                  |  231 +
>> > .../Omap35xxPkg/Flash/Flash.c                 |  768
>> +++
>> > .../Omap35xxPkg/Flash/Flash.h                 |  100 +
>> > .../Omap35xxPkg/Flash/Flash.inf               |   42 +
>> > .../TexasInsturments/Omap35xxPkg/Gpio/Gpio.c  |  129 +
>> > .../Omap35xxPkg/Gpio/Gpio.inf                 |   39 +
>> > .../Omap35xxPkg/Include/Library/OmapDmaLib.h  |   84 +
>> > .../Omap35xxPkg/Include/Library/OmapLib.h     |   38 +
>> > .../Omap35xxPkg/Include/Omap3530/Omap3530.h   |   34 +
>> > .../Include/Omap3530/Omap3530Dma.h            |  124 +
>> > .../Include/Omap3530/Omap3530Gpio.h           |  125 +
>> > .../Include/Omap3530/Omap3530Gpmc.h           |  101 +
>> > .../Include/Omap3530/Omap3530I2c.h            |   56 +
>> > .../Include/Omap3530/Omap3530Interrupt.h      |   45 +
>> > .../Include/Omap3530/Omap3530MMCHS.h          |  208 +
>> > .../Omap3530/Omap3530PadConfiguration.h       |  297 ++
>> > .../Include/Omap3530/Omap3530Prcm.h           |  159 +
>> > .../Include/Omap3530/Omap3530Timer.h          |   76 +
>> > .../Include/Omap3530/Omap3530Uart.h           |   48 +
>> > .../Include/Omap3530/Omap3530Usb.h            |   42 +
>> > .../Omap35xxPkg/Include/TPS65950.h            |   74 +
>> > .../InterruptDxe/HardwareInterrupt.c          |  396 ++
>> > .../Omap35xxPkg/InterruptDxe/InterruptDxe.inf |   48 +
>> > .../LcdGraphicsOutputBlt.c                    |  439 ++
>> > .../LcdGraphicsOutputDxe.c                    |  394 ++
>> > .../LcdGraphicsOutputDxe.h                    |  151 +
>> > .../LcdGraphicsOutputDxe.inf                  |   46 +
>> > .../DebugAgentTimerLib/DebugAgentTimerLib.c   |  159 +
>> > .../DebugAgentTimerLib/DebugAgentTimerLib.inf |   42 +
>> > .../Library/GdbSerialLib/GdbSerialLib.c       |   96 +
>> > .../Library/GdbSerialLib/GdbSerialLib.inf     |   35 +
>> > .../Omap35xxTimerLib/Omap35xxTimerLib.inf     |   40 +
>> > .../Library/Omap35xxTimerLib/TimerLib.c       |  151 +
>> > .../Library/OmapDmaLib/OmapDmaLib.c           |  170 +
>> > .../Library/OmapDmaLib/OmapDmaLib.inf         |   43 +
>> > .../Omap35xxPkg/Library/OmapLib/OmapLib.c     |   77 +
>> > .../Omap35xxPkg/Library/OmapLib/OmapLib.inf   |   31 +
>> > .../RealTimeClockLib/RealTimeClockLib.c       |  291 ++
>> > .../RealTimeClockLib/RealTimeClockLib.inf     |   32 +
>> > .../Library/SerialPortLib/SerialPortLib.c     |  208 +
>> > .../Library/SerialPortLib/SerialPortLib.inf   |   40 +
>> > .../Omap35xxPkg/MMCHSDxe/MMCHS.c              | 1492
>> ++++++
>> > .../Omap35xxPkg/MMCHSDxe/MMCHS.h              |  169 +
>> > .../Omap35xxPkg/MMCHSDxe/MMCHS.inf            |   48 +
>> > .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.c       |  671
>> +++
>> > .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.h       |   38 +
>> > .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf     |   47 +
>> > .../Omap35xxPkg/Omap35xxPkg.dec               |   52 +
>> > .../Omap35xxPkg/Omap35xxPkg.dsc               |  183 +
>> > .../Omap35xxPkg/PciEmulation/PciEmulation.c   |  107 +
>> > .../Omap35xxPkg/PciEmulation/PciEmulation.inf |   41 +
>> > .../Omap35xxPkg/SmbusDxe/Smbus.c              |  319 ++
>> > .../Omap35xxPkg/SmbusDxe/Smbus.inf            |   39 +
>> > .../Omap35xxPkg/TPS65950Dxe/TPS65950.c        |  110 +
>> > .../Omap35xxPkg/TPS65950Dxe/TPS65950.inf      |   42 +
>> > .../Omap35xxPkg/TimerDxe/Timer.c              |  370 ++
>> > .../Omap35xxPkg/TimerDxe/TimerDxe.inf         |   51 +
>> > 1103 files changed, 259532 insertions(+)
>> > create mode 100644
>> >Drivers/OptionRomPkg/Application/BltLibSample/BltLibSamp
>> le.c
>> > create mode 100644
>> >Drivers/OptionRomPkg/Application/BltLibSample/BltLibSamp
>> le.inf
>> > create mode 100644
>> >Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.c
>> > create mode 100644
>> >Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.h
>> > create mode 100644
>> >Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThruDxe.i
>> nf
>> > create mode 100644
>> >Drivers/OptionRomPkg/AtapiPassThruDxe/ComponentName.c
>> > create mode 100644
>> >Drivers/OptionRomPkg/AtapiPassThruDxe/DriverSupportedEfi
>> Version.c
>> > create mode 100644
>> >Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/Compatible
>> Devices.txt
>> > create mode 100644
>> >Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ComponentN
>> ame.c
>> > create mode 100644
>> >Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSer
>> ialDriver.c
>> > create mode 100644
>> >Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSer
>> ialDriver.h
>> > create mode 100644
>> >Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSer
>> ialDxe.inf
>> > create mode 100644
>> >Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt
>> > create mode 100644
>> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax887
>> 72.c
>> > create mode 100644
>> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax887
>> 72.h
>> > create mode 100644
>> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax887
>> 72.inf
>> > create mode 100644
>> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Compo
>> nentName
>> >.c
>> > create mode 100644
>> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Drive
>> rBinding.c
>> > create mode 100644
>> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Simpl
>> eNetwork.c
>> > create mode 100644
>> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88
>> 772.c
>> > create mode 100644
>> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88
>> 772.h
>> > create mode 100644
>> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88
>> 772b.inf
>> > create mode 100644
>> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Comp
>> onentNam
>> >e.c
>> > create mode 100644
>> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Driv
>> erBinding.c
>> > create mode 100644
>> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Simp
>> leNetwork.
>> >c
>> > create mode 100644
>> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.
>> c
>> > create mode 100644
>> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.
>> h
>> > create mode 100644
>> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430D
>> xe.inf
>> > create mode 100644
>> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430G
>> raphicsOutput.c
>> > create mode 100644
>> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I
>> 2c.c
>> > create mode 100644
>> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I
>> 2c.h
>> > create mode 100644
>> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430U
>> gaDraw.c
>> > create mode 100644
>> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/ComponentName.c
>> > create mode 100644
>> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/DriverSupportedE
>> fiVersion.c
>> > create mode 100644
>> Drivers/OptionRomPkg/CirrusLogic5430Dxe/Edid.c
>> > create mode 100644
>> Drivers/OptionRomPkg/Include/Library/BltLib.h
>> > create mode 100644
>> >Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBuff
>> erBltLib.c
>> > create mode 100644
>> >Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBuff
>> erBltLib.inf
>> > create mode 100644
>> Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.c
>> > create mode 100644
>> Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.inf
>> > create mode 100644
>> Drivers/OptionRomPkg/OptionRomPkg.dec
>> > create mode 100644
>> Drivers/OptionRomPkg/OptionRomPkg.dsc
>> > create mode 100644 Drivers/OptionRomPkg/ReadMe.txt
>> > create mode 100644
>> >Drivers/OptionRomPkg/UndiRuntimeDxe/ComponentName.c
>> > create mode 100644
>> Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c
>> > create mode 100644
>> Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c
>> > create mode 100644
>> Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h
>> > create mode 100644
>> Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c
>> > create mode 100644
>> Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h
>> > create mode 100644
>> Drivers/OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c
>> > create mode 100644
>> >Drivers/OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.dec
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.dsc
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.fdf
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/ConfigurationHeader.
>> bin
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/ConfigurationHeader.
>> dat
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi
>> _boot_from_ra
>> >m.inc
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi
>> _convert_symb
>> >ols.sh
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi
>> _dummy.axf
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi
>> _hw_setup.inc
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi
>> _load_symbols.i
>> >nc
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi
>> _symbols_macr
>> >os.inc
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi
>> _unload_symbo
>> >ls.inc
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/tra
>> ce32_load_sym
>> >bols.cmm
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/tra
>> ce32_load_sym
>> >bols_cygwin.cmm
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Include/BeagleBoard.
>> h
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardL
>> ib/BeagleBoard.
>> >c
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardL
>> ib/BeagleBoard
>> >Helper.S
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardL
>> ib/BeagleBoard
>> >Helper.asm
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardL
>> ib/BeagleBoard
>> >Lib.inf
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardL
>> ib/BeagleBoard
>> >Mem.c
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardL
>> ib/Clock.c
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardL
>> ib/PadConfigura
>> >tion.c
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Library/DxeHobPeCoff
>> Lib/DxeHobPe
>> >Coff.c
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Library/DxeHobPeCoff
>> Lib/DxeHobPe
>> >CoffLib.inf
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Library/LzmaHobCusto
>> mDecompress
>> >Lib/LzmaHobCustomDecompressLib.c
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Library/LzmaHobCusto
>> mDecompress
>> >Lib/LzmaHobCustomDecompressLib.inf
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Library/MemoryInitPe
>> iLib/MemoryIn
>> >itPeiLib.c
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Library/MemoryInitPe
>> iLib/MemoryIn
>> >itPeiLib.inf
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Library/ResetSystemL
>> ib/ResetSyste
>> >mLib.c
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Library/ResetSystemL
>> ib/ResetSyste
>> >mLib.inf
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ArchPrePi.
>> c
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ModuleEntr
>> yPoint.S
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ModuleEntr
>> yPoint.asm
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/PrePi/LzmaDecompress
>> .h
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/PrePi/MainUniCore.c
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/PrePi/PeiUniCore.inf
>> > create mode 100644
>> Platform/BeagleBoard/BeagleBoardPkg/PrePi/PrePi.c
>> > create mode 100644
>> Platform/BeagleBoard/BeagleBoardPkg/PrePi/PrePi.h
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Tools/GNUmakefile
>> > create mode 100644
>> >Platform/BeagleBoard/BeagleBoardPkg/Tools/generate_image
>> .c
>> > create mode 100644
>> Platform/BeagleBoard/BeagleBoardPkg/Tools/makefile
>> > create mode 100644
>> Platform/BeagleBoard/BeagleBoardPkg/Tools/replace.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/AcpiTabl
>> es.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Cst/
>> Cpu0Cst.asl
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Ist/
>> Cpu0Ist.asl
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Tst/
>> Cpu0Tst.asl
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/CpuPm/Cp
>> uPm.asl
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/AD7
>> 298.asi
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/ADC
>> 108S102.asi
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/CAT
>> 24C08.asi
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/CY8
>> C9540A.asi
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Gpi
>> oClient.asi
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Lpc
>> Dev.asi
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PCA
>> 9685.asi
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PCA
>> L9555A.asi
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Pci
>> HostBridge.asi
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Pci
>> Irq.asi
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Pci
>> eExpansionPrt.asi
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Pla
>> tform.asl
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNC
>> .asi
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNC
>> Apic.asi
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNC
>> Lpc.asi
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Qua
>> rkSouthCluster.a
>> >si
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Tpm
>> .asi
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Facs/Fac
>> s.aslc
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Facs/Fac
>> s.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fad
>> t.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fad
>> t1.0.aslc
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fad
>> t2.0.aslc
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Hpet/Hpe
>> t.aslc
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Hpet/Hpe
>> t.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Mcfg/Mcf
>> g.aslc
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Mcfg/Mcf
>> g.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Ac
>> piPciUpdate.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Ac
>> piPciUpdate.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Ac
>> piPlatform.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Ac
>> piPlatform.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Ac
>> piPlatform.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Ma
>> dt.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Ma
>> dtPlatform.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecu
>> torDxe/BootScri
>> >ptExecutorDxe.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecu
>> torDxe/IA32/S3A
>> >sm.S
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecu
>> torDxe/IA32/S3A
>> >sm.asm
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecu
>> torDxe/IA32/Set
>> >IdtEntry.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecu
>> torDxe/ScriptExe
>> >cute.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecu
>> torDxe/ScriptExe
>> >cute.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/Acpi
>> SmmPlatfor
>> >m.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/Acpi
>> SmmPlatfor
>> >m.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/Acpi
>> SmmPlatfor
>> >m.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerMana
>> gement/P
>> >pm.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerMana
>> gement/P
>> >pm.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerMana
>> gement/S
>> >mmPowerManagement.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerMana
>> gement/S
>> >mmPowerManagement.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerMana
>> gement/S
>> >mmPowerManagement.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Application/ForceRecover
>> y/ForceRecovery
>> >.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Application/ForceRecover
>> y/ForceRecovery
>> >.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/
>> PlatformFlashAcc
>> >essLib/PlatformFlashAccessLibDxe.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/
>> PlatformFlashAcc
>> >essLib/PlatformFlashAccessLibDxe.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/
>> PlatformFlashAcc
>> >essLib/SpiFlashDevice.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/
>> PlatformFlashAcc
>> >essLib/SpiFlashDevice.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFi
>> rmwareDescript
>> >or/SystemFirmwareDescriptor.aslc
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFi
>> rmwareDescript
>> >or/SystemFirmwareDescriptor.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFi
>> rmwareDescript
>> >or/SystemFirmwareDescriptorPei.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFi
>> rmwareUpdateC
>> >onfig/SystemFirmwareUpdateConfig.ini
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnDa
>> taCD.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFa
>> tFloppyDisk.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFa
>> tIdeDisk.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFa
>> tUsbDisk.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Include/Guid/MemoryConfi
>> gData.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Include/Guid/QuarkCapsul
>> eGuid.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Include/Guid/QuarkVariab
>> leLock.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Include/Guid/SystemNvDat
>> aHobGuid.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Include/Library/Platform
>> HelperLib.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Include/Library/Platform
>> PcieHelperLib.h
>> > create mode 100644
>> Platform/Intel/QuarkPlatformPkg/Include/Pcal9555.h
>> > create mode 100644
>> Platform/Intel/QuarkPlatformPkg/Include/Platform.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Include/PlatformBoards.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Include/Protocol/GlobalN
>> vsArea.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Include/Protocol/Platfor
>> mSmmSpiReady.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/PlatformBootMana
>> gerLib/Platform
>> >BootManager.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/PlatformBootMana
>> gerLib/Platform
>> >BootManager.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/PlatformBootMana
>> gerLib/Platform
>> >BootManagerLib.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/PlatformBootMana
>> gerLib/Platform
>> >Data.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLi
>> b/CommonHeader
>> >.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLi
>> b/DxePlatformHel
>> >perLib.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLi
>> b/PeiPlatformHelp
>> >erLib.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLi
>> b/PlatformHelper
>> >Dxe.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLi
>> b/PlatformHelperL
>> >ib.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLi
>> b/PlatformHelper
>> >Pei.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLi
>> b/PlatformLeds.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelp
>> erLib/CommonHe
>> >ader.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelp
>> erLib/PlatformPci
>> >eHelperLib.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelp
>> erLib/PlatformPci
>> >eHelperLib.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelp
>> erLib/SocUnit.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/I
>> a32/Flat32.S
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/I
>> a32/Flat32.asm
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/I
>> a32/Platform.inc
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/P
>> latformSecLib.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/P
>> latformSecLib.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/P
>> latformSecLibMod
>> >Strs.uni
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecureLi
>> b/PlatformSecure
>> >Lib.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecureLi
>> b/PlatformSecure
>> >Lib.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAt
>> melI2c/TisPc.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAt
>> melI2c/Tpm12De
>> >viceLibAtmelI2c.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAt
>> melI2c/Tpm12De
>> >viceLibAtmelI2c.uni
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibIn
>> fineonI2c/TisPc.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibIn
>> fineonI2c/Tpm12
>> >DeviceLibInfineonI2c.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibIn
>> fineonI2c/Tpm12
>> >DeviceLibInfineonI2c.uni
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/Pc
>> iHostBridge.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/Pc
>> iHostBridge.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/Pc
>> iHostBridge.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/Pc
>> iHostBridgeSupp
>> >ort.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/Pc
>> iHostResource.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/Pc
>> iRootBridge.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/Pc
>> iRootBridgeIo.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/Comm
>> onHeader.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciP
>> latform.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciP
>> latform.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciP
>> latform.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubCl
>> ass/MemoryS
>> >ubClass.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubCl
>> ass/MemoryS
>> >ubClass.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubCl
>> ass/MemoryS
>> >ubClass.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubCl
>> ass/MemoryS
>> >ubClassStrings.uni
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformIni
>> t/PlatformConfig.
>> >c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformIni
>> t/PlatformInitDxe
>> >.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformIni
>> t/PlatformInitDxe
>> >.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformIni
>> t/PlatformInitDxe
>> >.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SaveMemoryC
>> onfig/SaveM
>> >emoryConfig.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SaveMemoryC
>> onfig/SaveM
>> >emoryConfig.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/Commo
>> nHeader.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/DxePl
>> atform.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/Keybo
>> ardLayout.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/QNCRe
>> gTable.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/Setup
>> Platform.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/Setup
>> Platform.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/Strin
>> gs.uni
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/proce
>> ssor.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/CommonHe
>> >ader.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscBaseBo
>> >ardManufacturer.uni
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscBaseBo
>> >ardManufacturerData.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscBaseBo
>> >ardManufacturerFunction.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscBiosVe
>> >ndor.uni
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscBiosVe
>> >ndorData.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscBiosVe
>> >ndorFunction.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscBootInf
>> >ormationData.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscBootInf
>> >ormationFunction.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscChassis
>> >Manufacturer.uni
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscChassis
>> >ManufacturerData.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscChassis
>> >ManufacturerFunction.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscDevice
>> >Path.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscNumbe
>> >rOfInstallableLanguagesData.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscNumbe
>> >rOfInstallableLanguagesFunction.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscOemSt
>> >ring.uni
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscOemSt
>> >ringData.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscOemSt
>> >ringFunction.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscOnboar
>> >dDevice.uni
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscOnboar
>> >dDeviceData.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscOnboar
>> >dDeviceFunction.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscPortInt
>> >ernalConnectorDesignator.uni
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscPortInt
>> >ernalConnectorDesignatorData.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscPortInt
>> >ernalConnectorDesignatorFunction.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscSystem
>> >Manufacturer.uni
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscSystem
>> >ManufacturerData.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscSystem
>> >ManufacturerFunction.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscSystem
>> >OptionString.uni
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscSystem
>> >OptionStringData.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscSystem
>> >OptionStringFunction.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscSystem
>> >SlotDesignation.uni
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscSystem
>> >SlotDesignationData.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscSystem
>> >SlotDesignationFunction.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/MiscSystem
>> >SlotOnboardDevices.uni
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/SmbiosMisc
>> >.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/SmbiosMisc
>> >DataTable.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/SmbiosMisc
>> >Dxe.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/SmbiosMisc
>> >EntryPoint.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
>> xe/SmbiosMisc
>> >Strings.uni
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformCon
>> fig/PlatformConf
>> >igPei.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformCon
>> fig/PlatformConf
>> >igPei.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
>> t/BootMode.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
>> t/CommonHeader
>> >.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
>> t/Generic/Recove
>> >ry.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
>> t/MemoryCallback
>> >.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
>> t/MrcWrapper.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
>> t/MrcWrapper.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
>> t/PeiFvSecurity.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
>> t/PeiFvSecurity.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
>> t/PlatformEarlyInit
>> >.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
>> t/PlatformEarlyInit
>> >.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
>> t/PlatformEarlyInit
>> >.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
>> t/PlatformErratas.
>> >c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
>> FvbInfo.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
>> FwBlockService.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
>> FwBlockService.h
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
>> PlatformSmmSpi.
>> >c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
>> PlatformSmmSpi.i
>> >nf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
>> PlatformSpi.inf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
>> SpiFlashDevice.c
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
>> SpiFlashDevice.h
>> > create mode 100644
>> Platform/Intel/QuarkPlatformPkg/Quark.dsc
>> > create mode 100644
>> Platform/Intel/QuarkPlatformPkg/Quark.fdf
>> > create mode 100644
>> Platform/Intel/QuarkPlatformPkg/QuarkMin.dsc
>> > create mode 100644
>> Platform/Intel/QuarkPlatformPkg/QuarkMin.fdf
>> > create mode 100644
>> >Platform/Intel/QuarkPlatformPkg/QuarkPlatformPkg.dec
>> > create mode 100644
>> Platform/Intel/QuarkPlatformPkg/Readme.md
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/.gitignore
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatfo
>> rm.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatfo
>> rm.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatfo
>> rm.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatfo
>> rmHooks.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatfo
>> rmHooks.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatfo
>> rmHooksLib.h
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpd
>> ate/FirmwareUp
>> >date.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpd
>> ate/FirmwareUp
>> >date.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpd
>> ate/FirmwareUp
>> >date.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpd
>> ate/FirmwareUp
>> >dateStrings.uni
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64D.env
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64R.env
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/BootS
>> criptSaveDxe.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/Inter
>> nalBootScriptSave
>> >.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/Scrip
>> tSave.c
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.bat
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.sh
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/FCE.exe
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
>> eCapsule/GenCa
>> >psuleAll.bat
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
>> eCapsule/GenCa
>> >psuleAll.sh
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
>> eCapsule/GenCa
>> >psuleMinnowMax.bat
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
>> eCapsule/GenCa
>> >psuleMinnowMax.sh
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
>> eCapsule/GenCa
>> >psuleMinnowMaxRelease.bat
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
>> eCapsule/GenCa
>> >psuleMinnowMaxRelease.sh
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
>> eCapsule/GenCa
>> >psuleSampleColor.bat
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
>> eCapsule/GenCa
>> >psuleSampleColor.sh
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
>> eCapsule/Lvfs.dd
>> >f
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
>> eCapsule/LvfsGe
>> >nCapsuleMinnowMax.bat
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
>> eCapsule/LvfsGe
>> >nCapsuleMinnowMaxRelease.bat
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
>> eCapsule/LvfsGe
>> >nCapsuleSampleColor.bat
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
>> eCapsule/NewR
>> >oot.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7Cer
>> tBufferXdr.i
>> >nc
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
>> eCapsule/SAMPL
>> >E_DEVELOPMENT.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevi
>> cePkcs7C
>> >ertBufferXdr.inc
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
>> eCapsule/SAMPL
>> >E_DEVELOPMENT_SAMPLE_PRODUCTION.cer.gFmpDevicePkgTokenSp
>> aceGu
>> >id.PcdFmpDevicePkcs7CertBufferXdr.inc
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
>> eCapsule/templa
>> >te.metainfo.xml
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library
>> /FmpDeviceLib/Fm
>> >pDeviceLib.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library
>> /FmpDeviceLib/Fm
>> >pDeviceLib.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library
>> /FmpDeviceLibSa
>> >mple/FmpDeviceLib.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library
>> /FmpDeviceLibSa
>> >mple/FmpDeviceLib.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library
>> /PlatformFlashAcc
>> >essLib/PlatformFlashAccessLib.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library
>> /PlatformFlashAcc
>> >essLib/PlatformFlashAccessLib.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemF
>> irmwareDescript
>> >or/SystemFirmwareDescriptor.aslc
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemF
>> irmwareDescript
>> >or/SystemFirmwareDescriptor.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemF
>> irmwareDescript
>> >or/SystemFirmwareDescriptorPei.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemF
>> irmwareUpdateC
>> >onfig/SystemFirmwareUpdateConfig.ini
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemF
>> irmwareUpdateC
>> >onfig/SystemFirmwareUpdateConfigGcc.ini
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/FmpCertificate.dsc
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FmpGreenSampleDevice.ds
>> c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FspAzaliaConfigData/Aza
>> liaConfig.bin
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/
>> BootModePei.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/
>> BootModePei.i
>> >nf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiF
>> spHobProcessLibVl
>> >v2/FspHobProcessLibVlv2.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiF
>> spHobProcessLibVl
>> >v2/FspHobProcessLibVlv2.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
>> spPlatformSecLibV
>> >lv2/FspPlatformSecLibVlv2.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
>> spPlatformSecLibV
>> >lv2/FspPlatformSecLibVlv2.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
>> spPlatformSecLibV
>> >lv2/Ia32/AsmSaveSecContext.asm
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
>> spPlatformSecLibV
>> >lv2/Ia32/Fsp.inc
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
>> spPlatformSecLibV
>> >lv2/Ia32/PeiCoreEntry.asm
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
>> spPlatformSecLibV
>> >lv2/Ia32/SecEntry.asm
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
>> spPlatformSecLibV
>> >lv2/Ia32/Stack.S
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
>> spPlatformSecLibV
>> >lv2/Ia32/Stack.asm
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
>> spPlatformSecLibV
>> >lv2/PlatformInit.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
>> spPlatformSecLibV
>> >lv2/SaveSecContext.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
>> spPlatformSecLibV
>> >lv2/SecGetPerformance.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
>> spPlatformSecLibV
>> >lv2/SecPlatformInformation.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
>> spPlatformSecLibV
>> >lv2/SecRamInitData.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
>> spPlatformSecLibV
>> >lv2/SecTempRamSupport.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
>> spPlatformSecLibV
>> >lv2/UartInit.c
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbRuntim
>> eDxe.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServic
>> e.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServic
>> e.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServic
>> eDxe.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServic
>> eSmm.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmm.in
>> f
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmCom
>> mon.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe
>> .c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe
>> .h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe
>> .inf
>> > create mode 100755
>> Platform/Intel/Vlv2TbltDevicePkg/GenBiosId
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/GenBiosId.exe
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/AlertStandardFo
>> rmatTable.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/ChipsetAccess.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/CommonIncludes.
>> h
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/Include/CpuType.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/FileHandleLib.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AcpiTableS
>> torage.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AlertStand
>> ardFormat.h
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BiosId.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BoardFeatu
>> res.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/EfiVpdData
>> .h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/FirmwareId
>> .h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/HwWatchdog
>> TimerHob.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/IdccData.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/ItkData.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/MemoryConf
>> igData.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/OsSelectio
>> n.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PciLanInfo
>> .h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformCp
>> uInfo.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformIn
>> fo.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SensorInfo
>> Variable.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SetupVaria
>> ble.h
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/Include/Hpet.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/BiosIdL
>> ib.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/CpuIA32
>> .h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/EfiRegT
>> ableLib.h
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Esrt.h
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Fd.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/FlashDe
>> viceLib.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2CLib.
>> h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cMmio
>> ConfigLib.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cPort
>> _platform.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Platfor
>> mFsaLib.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Platfor
>> mFspLib.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/SpiFlas
>> h.H
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/StallSm
>> mLib.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/UsbDevi
>> ceModeLib.h
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/Include/Mcfg.h
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/Include/McfgTable.h
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/Include/Platform.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformBootMod
>> e.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformDefinit
>> ions.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/MfgMemoryTe
>> st.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Sha256Hash.
>> h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Speaker.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/UsbControll
>> er.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/CK505C
>> lockPlatformInfo.
>> >h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Enhanc
>> edSpeedstep.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Global
>> NvsArea.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/HwWatc
>> hdogTimer.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cAcp
>> i.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBus
>> .h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBus
>> Mcg.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cHos
>> tMcg.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cMas
>> terMcg.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cSla
>> ve.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpc
>> 83627Policy.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpc
>> e791Policy.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/MmioDe
>> vice.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Observ
>> able.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Platfo
>> rmGopPolicy.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Platfo
>> rmIdeInit.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SetupM
>> ode.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Smbios
>> SlotPopulation.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Speake
>> r.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TcoRes
>> et.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TpmMp.
>> h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/UsbPol
>> icy.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/VlvPla
>> tformPolicy.h
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/Include/SetupMode.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/IntelGopDepex/IntelGopD
>> river.depex
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosI
>> dLib.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosI
>> dLib.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/CpuI
>> A32Lib.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/EfiC
>> puVersion.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32
>> /CpuIA32.S
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32
>> /CpuIA32.asm
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32
>> /CpuIA32.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/
>> Cpu.S
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/
>> Cpu.asm
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/
>> EfiRegTableLib.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/
>> EfiRegTableLib.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/
>> FlashDeviceLib.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/
>> FlashDeviceLib.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/
>> FlashDeviceLibDxe.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/
>> FlashDeviceLibDxe.i
>> >nf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/
>> FlashDeviceLibDxeR
>> >untimeSmm.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/
>> SpiChipDefinitions.h
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLibNu
>> ll.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLi
>> b.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLi
>> bDxe.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CRe
>> gs.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CAc
>> cess.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDe
>> layPei.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDe
>> layPei.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIo
>> LibPei.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIo
>> LibPei.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLi
>> bPei.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLi
>> bPei.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLi
>> bPei.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTim
>> erLib/CommonHea
>> >der.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTim
>> erLib/IntelPchAcpiT
>> >imerLib.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTim
>> erLib/IntelPchAcpiT
>> >imerLib.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
>> b/BoardClkGens/Bo
>> >ardClkGens.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
>> b/BoardClkGens/Bo
>> >ardClkGens.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
>> b/BoardGpios/Boar
>> >dGpios.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
>> b/BoardGpios/Boar
>> >dGpios.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
>> b/BoardJumpers/Bo
>> >ardJumpers.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
>> b/BoardJumpers/Bo
>> >ardJumpers.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
>> b/BoardOemIds/Bo
>> >ardOemIds.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
>> b/BoardOemIds/Bo
>> >ardOemIds.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
>> b/BoardSsidSvid/Bo
>> >ardSsidSvid.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
>> b/BoardSsidSvid/Bo
>> >ardSsidSvid.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
>> b/MultiPlatformLib.
>> >c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
>> b/MultiPlatformLib.
>> >h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
>> b/MultiPlatformLib.i
>> >nf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
>> b/PlatformInfoHob.
>> >c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/
>> PchPlatformLib.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/
>> PchPlatformLibrary.
>> >c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/
>> PchPlatformLibrary.
>> >h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/Commo
>> nHeader.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSm
>> mLib.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSm
>> mLib.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/
>> BdsPlatform.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/
>> BdsPlatform.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/
>> PlatformBdsLib.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/
>> PlatformBdsStrings.
>> >uni
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/
>> PlatformData.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib
>> /PlatformCmosLib.
>> >c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib
>> /PlatformCmosLib.
>> >inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/
>> PlatformFspLib.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/
>> PlatformFspLib.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/
>> ResetSystemLib.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/
>> ResetSystemLib.in
>> >f
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/P
>> latformSerialPortLib.
>> >h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/S
>> erialPortLib.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/S
>> erialPortLib.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/S
>> ioInit.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/S
>> ioInit.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/Common
>> Header.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusL
>> ib.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusL
>> ib.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/Sta
>> llSmm.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/Sta
>> llSmmLib.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSe
>> CDxe/Tpm2Devic
>> >eLibSeC.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSe
>> CDxe/Tpm2Devic
>> >eLibSeC.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSe
>> CPei/Tpm2Device
>> >LibSeC.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSe
>> CPei/Tpm2Device
>> >LibSeC.inf
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/Logo/Logo.bmp
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetrono
>> me.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetrono
>> me.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Metronome/Metronome.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/EfiStatu
>> sCode.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStat
>> usCode.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStat
>> usCode.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStat
>> usCode.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PeiPostC
>> ode.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/Platform
>> StatusCode.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/Platform
>> StatusCode.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
>> ModulePkg/Libra
>> >ry/GenericBdsLib/BdsBoot.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
>> ModulePkg/Libra
>> >ry/GenericBdsLib/BdsConnect.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
>> ModulePkg/Libra
>> >ry/GenericBdsLib/BdsConsole.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
>> ModulePkg/Libra
>> >ry/GenericBdsLib/BdsMisc.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
>> ModulePkg/Libra
>> >ry/GenericBdsLib/DevicePath.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
>> ModulePkg/Libra
>> >ry/GenericBdsLib/GenericBdsLib.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
>> ModulePkg/Libra
>> >ry/GenericBdsLib/GenericBdsLib.uni
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
>> ModulePkg/Libra
>> >ry/GenericBdsLib/GenericBdsStrings.uni
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
>> ModulePkg/Libra
>> >ry/GenericBdsLib/InternalBdsLib.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
>> ModulePkg/Libra
>> >ry/GenericBdsLib/String.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
>> ModulePkg/Libra
>> >ry/GenericBdsLib/String.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/BoardPciPla
>> tform.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform
>> .c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform
>> .h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform
>> .inf
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.dsc
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.fdf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/Plat
>> formCpuInfoDxe.
>> >c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/Plat
>> formCpuInfoDxe.
>> >h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/Plat
>> formCpuInfoDxe.i
>> >nf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/AzaliaVerbT
>> able.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardId.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDeco
>> de.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDeco
>> de.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ClockContro
>> l.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Configurati
>> on.h
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchPlatform
>> Policy.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchRegTable
>> .c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchTcoReset
>> .c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeak
>> er.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeak
>> er.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/
>> Observable.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/
>> Observable.h
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciBus.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Platform.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe
>> .h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe
>> .inf
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SioPlatform
>> Policy.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.
>> c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.
>> h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/Platf
>> ormGopPolicy.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/Platf
>> ormGopPolicy.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/Platfor
>> mInfoDxe.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/Platfor
>> mInfoDxe.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/Platfor
>> mInfoDxe.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/BootMod
>> e.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/CpuInit
>> Peim.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/FlashMa
>> p.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacyS
>> peaker.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacyS
>> peaker.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MchInit
>> .c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryC
>> allback.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryP
>> eim.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PchInit
>> Peim.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Platfor
>> mEarlyInit.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Platfor
>> mEarlyInit.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Platfor
>> mInfoInit.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Platfor
>> mInitPei.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Platfor
>> mSsaInitPeim.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Recover
>> y.c
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Stall.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/BootMode.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/CommonHeade
>> r.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/MemoryCallb
>> ack.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/PlatformPei
>> .inf
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Stall.c
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.dec
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgConfig.dsc
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGcc.fdf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgIA32.dsc
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgX64.dsc
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Boot.v
>> fi
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Config
>> uration.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/DebugC
>> onfig.vfi
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/FwVers
>> ionStrings.uni
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Main.v
>> fi
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Platfo
>> rmSetupDxe.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Platfo
>> rmSetupDxe.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Platfo
>> rmSetupDxe.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Securi
>> ty.vfi
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupF
>> unctions.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupI
>> nfoRecords.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SouthC
>> lusterConfig.vfi
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/System
>> Component.vfi
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Therma
>> l.vfi
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UnCore
>> .vfi
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UqiLis
>> t.uni
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Vfr.vf
>> r
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/VfrStr
>> ings.uni
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/Platform.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/PlatformSmm
>> .inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/S3Save.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmPlatform
>> .h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSa
>> ve.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSa
>> ve.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/Readme.md
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMe
>> moryConfig.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMe
>> moryConfig.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMe
>> moryConfig.in
>> >f
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/CommonHea
>> der.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseB
>> oardManufactu
>> >rer.uni
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseB
>> oardManufactu
>> >rerData.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseB
>> oardManufactu
>> >rerFunction.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosV
>> endor.uni
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosV
>> endorData.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosV
>> endorFunction.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootI
>> nformationData.
>> >c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootI
>> nformationFunc
>> >tion.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChass
>> isManufacturer.
>> >uni
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChass
>> isManufacturer
>> >Data.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChass
>> isManufacturer
>> >Function.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemor
>> yDevice.uni
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemor
>> yDeviceData.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemor
>> yDeviceFuncti
>> >on.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumbe
>> rOfInstallableL
>> >anguagesData.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumbe
>> rOfInstallableL
>> >anguagesFunction.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemSt
>> ring.uni
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemSt
>> ringData.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemSt
>> ringFunction.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemTy
>> pe0x90.uni
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemTy
>> pe0x90Data.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemTy
>> pe0x90Functio
>> >n.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemTy
>> pe0x94.uni
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemTy
>> pe0x94Data.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemTy
>> pe0x94Functio
>> >n.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboa
>> rdDevice.uni
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboa
>> rdDeviceData.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboa
>> rdDeviceFuncti
>> >on.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysi
>> calArray.uni
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysi
>> calArrayData.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysi
>> calArrayFunction
>> >.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortI
>> nternalConnecto
>> >rDesignator.uni
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortI
>> nternalConnecto
>> >rDesignatorData.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortI
>> nternalConnecto
>> >rDesignatorFunction.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProce
>> ssorCache.uni
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProce
>> ssorCacheData.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProce
>> ssorCacheFuncti
>> >on.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProce
>> ssorInformation
>> >.uni
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProce
>> ssorInformation
>> >Data.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProce
>> ssorInformation
>> >Function.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscReset
>> CapabilitiesData
>> >.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscReset
>> CapabilitiesFunc
>> >tion.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubcl
>> assDriver.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubcl
>> assDriver.uni
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubcl
>> assDriverDataTa
>> >ble.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubcl
>> assDriverEntryP
>> >oint.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
>> mLanguageStrin
>> >g.uni
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
>> mLanguageStrin
>> >gData.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
>> mLanguageStrin
>> >gFunction.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
>> mManufacturer.
>> >uni
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
>> mManufacturer
>> >Data.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
>> mManufacturer
>> >Function.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
>> mOptionString.u
>> >ni
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
>> mOptionStringD
>> >ata.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
>> mOptionStringF
>> >unction.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
>> mSlotDesignatio
>> >n.uni
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
>> mSlotDesignatio
>> >nData.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
>> mSlotDesignatio
>> >nFunction.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/SmBiosMis
>> cDxe.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDi
>> spatchThunk
>> >/SmmSwDispatch2OnSmmSwDispatchThunk.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDi
>> spatchThunk
>> >/SmmSwDispatch2OnSmmSwDispatchThunk.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm
>> /SmramSaveI
>> >nfoHandlerSmm.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm
>> /SmramSaveI
>> >nfoHandlerSmm.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtw
>> Spare.bin
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtw
>> Working.bin
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageVar
>> iable.bin
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_
>> HEADER.bin
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_
>> HEADER_SPILOCK
>> >.bin
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/Vacan
>> t.bin
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Stitch/MNW2_Stitch_Conf
>> ig.txt
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdO
>> pRegion.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdO
>> pRegion.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvP
>> latformInit.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvP
>> latformInit.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvP
>> latformInitDxe.inf
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.c
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.h
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h
>> > create mode 100644
>> >Platform/Intel/Vlv2TbltDevicePkg/Wpce791/Wpce791.inf
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh
>> > create mode 100644
>> Platform/Intel/Vlv2TbltDevicePkg/cln.sh
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/DdrM
>> emoryController
>> >.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Inte
>> lQNCBase.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Inte
>> lQNCConfig.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Inte
>> lQNCDxe.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Inte
>> lQNCPeim.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Inte
>> lQNCRegs.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Libr
>> ary/IntelQNCLib.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Libr
>> ary/QNCAccessLib.
>> >h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Libr
>> ary/QNCSmmLib.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Ppi/
>> QNCMemoryInit.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Prot
>> ocol/PchInfo.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Prot
>> ocol/PlatformPolic
>> >y.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Prot
>> ocol/QncS3Suppor
>> >t.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Prot
>> ocol/SmmIchnDis
>> >patch2.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Prot
>> ocol/Spi.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QNCA
>> ccess.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QNCC
>> ommonDefinitio
>> >ns.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Quar
>> kNcSocId.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Inte
>> lQNCLib/Common
>> >Header.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Inte
>> lQNCLib/IntelQNCL
>> >ib.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Inte
>> lQNCLib/IntelQNCL
>> >ib.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Inte
>> lQNCLib/PciExpress
>> >.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Mtrr
>> Lib/MtrrLib.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Mtrr
>> Lib/MtrrLib.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Mtrr
>> Lib/MtrrLib.uni
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCA
>> ccessLib/BaseAcc
>> >ess.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCA
>> ccessLib/QNCAcc
>> >essLib.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCA
>> ccessLib/QNCAcc
>> >essLib.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCA
>> ccessLib/Runtim
>> >eAccess.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCA
>> ccessLib/Runtim
>> >eQNCAccessLib.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCS
>> mmLib/QNCSmm
>> >Lib.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCS
>> mmLib/QNCSmm
>> >Lib.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Rese
>> tSystemLib/Reset
>> >SystemLib.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Rese
>> tSystemLib/Reset
>> >SystemLib.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Smbu
>> sLib/CommonHe
>> >ader.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Smbu
>> sLib/SmbusLib.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Smbu
>> sLib/SmbusLib.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmC
>> puFeaturesLib/S
>> >mmCpuFeaturesLib.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmC
>> puFeaturesLib/S
>> >mmCpuFeaturesLib.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmC
>> puFeaturesLib/S
>> >mmCpuFeaturesLib.uni
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
>> ei/MemoryInit.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
>> ei/MemoryInit.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
>> ei/MemoryInitP
>> >ei.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
>> ei/core_types.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
>> ei/gen5_iosf_sb
>> >_definitions.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
>> ei/general_defin
>> >itions.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
>> ei/hte.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
>> ei/hte.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
>> ei/io.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
>> ei/lprint.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
>> ei/meminit.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
>> ei/meminit.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
>> ei/meminit_utils
>> >.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
>> ei/meminit_utils
>> >.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
>> ei/memory_opti
>> >ons.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
>> ei/mrc.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
>> ei/mrc.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
>> ei/platform.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
>> ei/prememinit.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
>> ei/prememinit.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
>> CommonHeader.
>> >h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
>> DxeQNCSmbus.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
>> DxeQNCSmbus.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
>> LegacyRegion.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
>> LegacyRegion.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
>> QNCInit.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
>> QNCInit.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
>> QNCInitDxe.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
>> QNCRootPorts.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
>> QNCSmbus.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
>> QNCSmbusExec.
>> >c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dx
>> e/QncS3Support.
>> >c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dx
>> e/QncS3Support.
>> >h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dx
>> e/QncS3Support.
>> >inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmA
>> ccessDxe/Sm
>> >mAccess.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmA
>> ccessDxe/Sm
>> >mAccessDriver.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmA
>> ccessDxe/Sm
>> >mAccessDriver.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmC
>> ontrolDxe/S
>> >mmControlDriver.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmC
>> ontrolDxe/S
>> >mmControlDxe.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
>> ncSmmDispa
>> >tcher/CommonHeader.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
>> ncSmmDispa
>> >tcher/QNC/QNCSmmGpi.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
>> ncSmmDispa
>> >tcher/QNC/QNCSmmHelpers.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
>> ncSmmDispa
>> >tcher/QNC/QNCSmmPeriodicTimer.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
>> ncSmmDispa
>> >tcher/QNC/QNCSmmQncn.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
>> ncSmmDispa
>> >tcher/QNC/QNCSmmSw.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
>> ncSmmDispa
>> >tcher/QNC/QNCSmmSx.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
>> ncSmmDispa
>> >tcher/QNCSmm.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
>> ncSmmDispa
>> >tcher/QNCSmmCore.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
>> ncSmmDispa
>> >tcher/QNCSmmDispatcher.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
>> ncSmmDispa
>> >tcher/QNCSmmHelpers.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
>> ncSmmDispa
>> >tcher/QNCSmmHelpers.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
>> ncSmmDispa
>> >tcher/QNCSmmRegisters.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
>> ncSmmDispa
>> >tcher/QNCxSmmHelpers.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmA
>> ccessPei/Smm
>> >AccessPei.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmA
>> ccessPei/Smm
>> >AccessPei.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmC
>> ontrolPei/Sm
>> >mControlPei.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmC
>> ontrolPei/Sm
>> >mControlPei.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Common/S
>> piCommon.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Common/S
>> piCommon.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiRu
>> ntime.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiSm
>> m.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeD
>> xe/PchSpi.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeD
>> xe/PchSpi.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchS
>> pi.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchS
>> pi.h
>> > create mode 100644
>> Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dec
>> > create mode 100644
>> Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dsc
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/CEAT
>> A.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/I2cR
>> egs.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Ioh.
>> h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/IohA
>> ccess.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/IohC
>> ommonDefinition
>> >s.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Libr
>> ary/I2cLib.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Libr
>> ary/IohLib.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/MMC.
>> h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/SDCa
>> rd.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/SDHo
>> stIo.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/
>> CommonHeader.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/
>> IohBds.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/
>> IohData.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/
>> IohInit.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/
>> IohInitDxe.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cL
>> ib/CommonHeader
>> >.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cL
>> ib/I2cLib.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cL
>> ib/I2cLib.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohL
>> ib/CommonHeade
>> >r.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohL
>> ib/IohLib.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohL
>> ib/IohLib.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDC
>> ontrollerDxe/Co
>> >mponentName.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDC
>> ontrollerDxe/Co
>> >mponentName.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDC
>> ontrollerDxe/SD
>> >Controller.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDC
>> ontrollerDxe/SD
>> >Controller.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDC
>> ontrollerDxe/SD
>> >ControllerDxe.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
>> ediaDeviceDxe/
>> >CEATA.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
>> ediaDeviceDxe/
>> >CEATABlockIo.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
>> ediaDeviceDxe/
>> >ComponentName.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
>> ediaDeviceDxe/
>> >ComponentName.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
>> ediaDeviceDxe/
>> >MMCSDBlockIo.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
>> ediaDeviceDxe/
>> >MMCSDTransfer.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
>> ediaDeviceDxe/
>> >SDMediaDevice.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
>> ediaDeviceDxe/
>> >SDMediaDevice.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
>> ediaDeviceDxe/
>> >SDMediaDeviceDxe.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/P
>> ei/UsbPei.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/P
>> ei/UsbPei.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/P
>> ei/UsbPei.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
>> /ComponentNa
>> >me.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
>> /ComponentNa
>> >me.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
>> /Descriptor.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
>> /Ohci.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
>> /Ohci.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
>> /OhciDebug.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
>> /OhciDebug.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
>> /OhciDxe.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
>> /OhciReg.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
>> /OhciReg.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
>> /OhciSched.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
>> /OhciSched.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
>> /OhciUrb.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
>> /OhciUrb.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
>> /UsbHcMem.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
>> /UsbHcMem.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
>> /Descriptor.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
>> /OhcPeim.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
>> /OhcPeim.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
>> /OhciPei.inf
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
>> /OhciReg.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
>> /OhciReg.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
>> /OhciSched.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
>> /OhciSched.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
>> /OhciUrb.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
>> /OhciUrb.h
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
>> /UsbHcMem.c
>> > create mode 100644
>> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
>> /UsbHcMem.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/98_LIN
>> K.ASL
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTa
>> blePlatform.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTa
>> bles.inf
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/CPU.as
>> l
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/DSDT.A
>> SL
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facp/F
>> acp.aslc
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facs/F
>> acs.aslc
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/GloblN
>> vs.asl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Gpe.as
>> l
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/HOST_B
>> US.ASL
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Hpet/H
>> pet.aslc
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELG
>> FX.ASL
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELI
>> SPDev2.ASL
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOGB
>> DA.ASL
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOMO
>> BF.ASL
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOSB
>> CB.ASL
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOpR
>> n.ASL
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IoTVir
>> tualDevice.asl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LPC_DE
>> V.ASL
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LpcB.a
>> sl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Lpit/L
>> pit.aslc
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/M
>> adt.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/M
>> adt30.aslc
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Mcfg/M
>> cfg.aslc
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PCI_DR
>> C.ASL
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Pch.as
>> l
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchAud
>> io.asl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchEhc
>> i.asl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchLps
>> s.asl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchPci
>> e.asl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchScc
>> .asl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchSmb
>> .asl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchXhc
>> i.asl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PciTre
>> e.asl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Platfo
>> rm.asl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RTD3.a
>> sl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RhProx
>> y.asl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/THERMA
>> L.ASL
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/UsbSbd
>> .asl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Video.
>> asl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Vlv.as
>> l
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Wsmt/W
>> smt.aslc
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/token.
>> asl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Guid/Vlv2Devi
>> ceRefCodePkgTok
>> >enSpace.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/PttPassTh
>> ruPpi.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/fTPMPolic
>> y.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Protocol/PttP
>> assThru.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/In
>> clude/Guid/Pow
>> >erManagementAcpiTableStorage.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/In
>> clude/Ppi/VlvPol
>> >icy.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/In
>> clude/Protocol/P
>> >pmPlatformPolicy.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/In
>> clude/Types.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
>> werManageme
>> >nt/AcpiTables/PowerManagementAcpiTables.inf
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
>> werManageme
>> >nt/AcpiTables/Ssdt/ApCst.asl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
>> werManageme
>> >nt/AcpiTables/Ssdt/ApIst.asl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
>> werManageme
>> >nt/AcpiTables/Ssdt/ApTst.asl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
>> werManageme
>> >nt/AcpiTables/Ssdt/Cpu0Cst.asl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
>> werManageme
>> >nt/AcpiTables/Ssdt/Cpu0Ist.asl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
>> werManageme
>> >nt/AcpiTables/Ssdt/Cpu0Tst.asl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
>> werManageme
>> >nt/AcpiTables/Ssdt/CpuPm.asl
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
>> luster/Include/Pl
>> >atformBaseAddresses.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
>> luster/Include/P
>> >pi/Capsule.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
>> luster/Include/P
>> >pi/PlatformMemoryRange.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
>> luster/Include/P
>> >pi/PlatformMemorySize.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
>> luster/Include/P
>> >pi/SmmAccess.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
>> luster/Include/P
>> >pi/VlvMmioPolicy.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
>> luster/Include/P
>> >pi/VlvPeiInit.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
>> luster/Include/P
>> >pi/VlvPolicy.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
>> luster/Include/P
>> >rotocol/IgdOpRegion.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
>> luster/Include/P
>> >rotocol/MemInfo.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
>> luster/Include/P
>> >rotocol/PlatformGopPolicy.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
>> luster/Include/P
>> >rotocol/VlvPlatformPolicy.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
>> luster/Include/V
>> >alleyview.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
>> luster/Include/Vl
>> >vAccess.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
>> luster/Include/Vl
>> >vCommonDefinitions.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/G
>> >uid/PchInitVar.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/G
>> >uid/SataControllerGuid.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/G
>> >uid/SmbusArpMap.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/G
>> >uid/Vlv2Variable.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/In
>> >dustryStandard/CeAta.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/In
>> >dustryStandard/Mmc.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/In
>> >dustryStandard/SdCard.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/Li
>> >brary/I2CLib.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/Li
>> >brary/PchPlatformLib.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >chAccess.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >chCommonDefinitions.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >chRegs.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >chRegs/PchRegsHda.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >chRegs/PchRegsLpss.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >chRegs/PchRegsPcie.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >chRegs/PchRegsPcu.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >chRegs/PchRegsRcrb.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >chRegs/PchRegsSata.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >chRegs/PchRegsScc.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >chRegs/PchRegsSmbus.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >chRegs/PchRegsSpi.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >chRegs/PchRegsUsb.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >pi/PchInit.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >pi/PchPeiInit.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >pi/PchPlatformPolicy.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >pi/PchUsbPolicy.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >pi/PeiBlockIo.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >pi/Sdhc.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >pi/SmbusPolicy.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >pi/Spi.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >rotocol/ActiveBios.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >rotocol/ActiveBiosProtocol.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >rotocol/DxePchPolicyUpdateProtocol.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >rotocol/EmmcCardInfoProtocol.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >rotocol/Gpio.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >rotocol/HwWatchdogTimer.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >rotocol/I2cBus.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >rotocol/PchExtendedReset.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >rotocol/PchInfo.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >rotocol/PchPlatformPolicy.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >rotocol/PchReset.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >rotocol/PchS3Support.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >rotocol/SdHostIo.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >rotocol/SmbiosSlotPopulation.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >rotocol/SmmIchnDispatchEx.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >rotocol/SmmSmbus.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >rotocol/Spi.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/P
>> >rotocol/TcoReset.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/R
>> >sci.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
>> luster/Include/Ti
>> >anoApi.h
>> > create mode 100644
>> >Silicon/Intel/Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.
>> dec
>> > create mode 100644
>> Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.c
>> > create mode 100644
>> Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.h
>> > create mode 100644
>> Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.inf
>> > create mode 100644
>> Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.c
>> > create mode 100644
>> Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.inf
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Include/Library/Oma
>> pDmaLib.h
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Include/Library/Oma
>> pLib.h
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
>> ap3530.h
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
>> ap3530Dma.
>> >h
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
>> ap3530Gpio.
>> >h
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
>> ap3530Gpmc
>> >.h
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
>> ap3530I2c.h
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
>> ap3530Interr
>> >upt.h
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
>> ap3530MMC
>> >HS.h
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
>> ap3530PadC
>> >onfiguration.h
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
>> ap3530Prcm.
>> >h
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
>> ap3530Timer
>> >.h
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
>> ap3530Uart.
>> >h
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
>> ap3530Usb.h
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Include/TPS65950.h
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/Hardwa
>> reInterrupt.c
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/Interr
>> uptDxe.inf
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDx
>> e/LcdGraphics
>> >OutputBlt.c
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDx
>> e/LcdGraphics
>> >OutputDxe.c
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDx
>> e/LcdGraphics
>> >OutputDxe.h
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDx
>> e/LcdGraphics
>> >OutputDxe.inf
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentT
>> imerLib/Debug
>> >AgentTimerLib.c
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentT
>> imerLib/Debug
>> >AgentTimerLib.inf
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLi
>> b/GdbSerialLib.c
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLi
>> b/GdbSerialLib.in
>> >f
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTim
>> erLib/Omap35
>> >xxTimerLib.inf
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTim
>> erLib/TimerLib
>> >.c
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/
>> OmapDmaLib.
>> >c
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/
>> OmapDmaLib.
>> >inf
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/Oma
>> pLib.c
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/Oma
>> pLib.inf
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClo
>> ckLib/RealTimeC
>> >lockLib.c
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClo
>> ckLib/RealTimeC
>> >lockLib.inf
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortL
>> ib/SerialPortLib.c
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortL
>> ib/SerialPortLib.in
>> >f
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.c
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.h
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.inf
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostD
>> xe.c
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostD
>> xe.h
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostD
>> xe.inf
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dec
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dsc
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmu
>> lation.c
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmu
>> lation.inf
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.c
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.inf
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS6595
>> 0.c
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS6595
>> 0.inf
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/Timer.c
>> > create mode 100644
>> >Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/TimerDxe.i
>> nf
>> >
>> >--
>> >2.21.0.windows.1
>> >
>> >
>> >


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [edk2-platforms: Patch 1/8] Silicon/TexasInsturments: Import Omap35xxPkg from edk2
  2019-05-10  3:34 ` [edk2-platforms: Patch 1/8] Silicon/TexasInsturments: Import Omap35xxPkg " Michael D Kinney
@ 2019-05-10 17:56   ` Leif Lindholm
  2019-05-10 19:16     ` Michael D Kinney
  0 siblings, 1 reply; 23+ messages in thread
From: Leif Lindholm @ 2019-05-10 17:56 UTC (permalink / raw)
  To: Michael D Kinney; +Cc: devel, Ard Biesheuvel

Hi Mike,

I'm afraid a typo has snuck in below:

On Thu, May 09, 2019 at 08:34:28PM -0700, Michael D Kinney wrote:
> https://bugzilla.tianocore.org/show_bug.cgi?id=1467
> 
> Import Omap35xxPkg from edk2/master.
> 
> 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>
> ---
>  .../Omap35xxPkg/Flash/Flash.c                 |  768 +++++++++
>  .../Omap35xxPkg/Flash/Flash.h                 |  100 ++
>  .../Omap35xxPkg/Flash/Flash.inf               |   42 +
>  .../TexasInsturments/Omap35xxPkg/Gpio/Gpio.c  |  129 ++
>  .../Omap35xxPkg/Gpio/Gpio.inf                 |   39 +
>  .../Omap35xxPkg/Include/Library/OmapDmaLib.h  |   84 +
>  .../Omap35xxPkg/Include/Library/OmapLib.h     |   38 +
>  .../Omap35xxPkg/Include/Omap3530/Omap3530.h   |   34 +
>  .../Include/Omap3530/Omap3530Dma.h            |  124 ++
>  .../Include/Omap3530/Omap3530Gpio.h           |  125 ++
>  .../Include/Omap3530/Omap3530Gpmc.h           |  101 ++
>  .../Include/Omap3530/Omap3530I2c.h            |   56 +
>  .../Include/Omap3530/Omap3530Interrupt.h      |   45 +
>  .../Include/Omap3530/Omap3530MMCHS.h          |  208 +++
>  .../Omap3530/Omap3530PadConfiguration.h       |  297 ++++
>  .../Include/Omap3530/Omap3530Prcm.h           |  159 ++
>  .../Include/Omap3530/Omap3530Timer.h          |   76 +
>  .../Include/Omap3530/Omap3530Uart.h           |   48 +
>  .../Include/Omap3530/Omap3530Usb.h            |   42 +
>  .../Omap35xxPkg/Include/TPS65950.h            |   74 +
>  .../InterruptDxe/HardwareInterrupt.c          |  396 +++++
>  .../Omap35xxPkg/InterruptDxe/InterruptDxe.inf |   48 +
>  .../LcdGraphicsOutputBlt.c                    |  439 +++++
>  .../LcdGraphicsOutputDxe.c                    |  394 +++++
>  .../LcdGraphicsOutputDxe.h                    |  151 ++
>  .../LcdGraphicsOutputDxe.inf                  |   46 +
>  .../DebugAgentTimerLib/DebugAgentTimerLib.c   |  159 ++
>  .../DebugAgentTimerLib/DebugAgentTimerLib.inf |   42 +
>  .../Library/GdbSerialLib/GdbSerialLib.c       |   96 ++
>  .../Library/GdbSerialLib/GdbSerialLib.inf     |   35 +
>  .../Omap35xxTimerLib/Omap35xxTimerLib.inf     |   40 +
>  .../Library/Omap35xxTimerLib/TimerLib.c       |  151 ++
>  .../Library/OmapDmaLib/OmapDmaLib.c           |  170 ++
>  .../Library/OmapDmaLib/OmapDmaLib.inf         |   43 +
>  .../Omap35xxPkg/Library/OmapLib/OmapLib.c     |   77 +
>  .../Omap35xxPkg/Library/OmapLib/OmapLib.inf   |   31 +
>  .../RealTimeClockLib/RealTimeClockLib.c       |  291 ++++
>  .../RealTimeClockLib/RealTimeClockLib.inf     |   32 +
>  .../Library/SerialPortLib/SerialPortLib.c     |  208 +++
>  .../Library/SerialPortLib/SerialPortLib.inf   |   40 +
>  .../Omap35xxPkg/MMCHSDxe/MMCHS.c              | 1492 +++++++++++++++++
>  .../Omap35xxPkg/MMCHSDxe/MMCHS.h              |  169 ++
>  .../Omap35xxPkg/MMCHSDxe/MMCHS.inf            |   48 +
>  .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.c       |  671 ++++++++
>  .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.h       |   38 +
>  .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf     |   47 +
>  .../Omap35xxPkg/Omap35xxPkg.dec               |   52 +
>  .../Omap35xxPkg/Omap35xxPkg.dsc               |  183 ++
>  .../Omap35xxPkg/PciEmulation/PciEmulation.c   |  107 ++
>  .../Omap35xxPkg/PciEmulation/PciEmulation.inf |   41 +
>  .../Omap35xxPkg/SmbusDxe/Smbus.c              |  319 ++++
>  .../Omap35xxPkg/SmbusDxe/Smbus.inf            |   39 +
>  .../Omap35xxPkg/TPS65950Dxe/TPS65950.c        |  110 ++
>  .../Omap35xxPkg/TPS65950Dxe/TPS65950.inf      |   42 +
>  .../Omap35xxPkg/TimerDxe/Timer.c              |  370 ++++
>  .../Omap35xxPkg/TimerDxe/TimerDxe.inf         |   51 +
>  56 files changed, 9257 insertions(+)
>  create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.c

TexasInsturments ->
TexasInstruments

Also, using the sortorder and --stat/--stat-graph-width from Laszlo's
guide when generating patches would be helpful here even though the
code is just moving. It makes the above more clear, and puts the .dec
and .dsc (which have actually changed) first.

Beyond that, I intend to change both this and BeagleBoardPkg to use
full pathnames relative to edk2-platforms root after the migration,
but we don't need to do that for the migration.

Best Regards,

Leif

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [edk2-devel] [edk2-platforms: Patch 8/8] edk2-platforms: Update Maintainers.txt/Readme.md for imported packages
  2019-05-10  3:34 ` [edk2-platforms: Patch 8/8] edk2-platforms: Update Maintainers.txt/Readme.md for imported packages Michael D Kinney
@ 2019-05-10 18:04   ` Leif Lindholm
  2019-05-13  2:52   ` Sun, Zailiang
  1 sibling, 0 replies; 23+ messages in thread
From: Leif Lindholm @ 2019-05-10 18:04 UTC (permalink / raw)
  To: devel, michael.d.kinney
  Cc: Zailiang Sun, Yi Qian, Kelly Steele, Ray Ni, Michael Kubacki,
	Ard Biesheuvel

Hi Mike,

Over all, looks good. One consistency comment below:

On Thu, May 09, 2019 at 08:34:35PM -0700, Michael D Kinney wrote:
> https://bugzilla.tianocore.org/show_bug.cgi?id=1467
> https://bugzilla.tianocore.org/show_bug.cgi?id=1374
> https://bugzilla.tianocore.org/show_bug.cgi?id=1793
> 
> Update Maintainers.txt for the following packages:
> * Drivers/OptionRomPkg
> * Platform/BeagleBoard/BeagleBoardPkg
> * Platform/Intel/QuarkPlatformPkg
> * Platform/Intel/Vlv2TbltDevicePkg
> * Silicon/Intel/QuarkSocPkg
> * Silicon/Intel/Vlv2DeviceRefCodePkg
> * Silicon/TexasInsturments/Omap35xxPkg
> 
> Add the following platforms to Readme.md
> * BeagleBoard
> * MinnowBoard Max/Turbot
> * Galileo
> 
> Cc: Zailiang Sun <zailiang.sun@intel.com>
> Cc: Yi Qian <yi.qian@intel.com>
> Cc: Kelly Steele <kelly.steele@intel.com>
> Cc: Ray Ni <ray.ni@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>
> ---
>  Maintainers.txt | 20 ++++++++++++++++++++
>  Readme.md       |  9 +++++++++
>  2 files changed, 29 insertions(+)
> 
> diff --git a/Maintainers.txt b/Maintainers.txt
> index 6477591e68..7dd403a170 100644
> --- a/Maintainers.txt
> +++ b/Maintainers.txt
> @@ -38,12 +38,32 @@ W: https://github.com/tianocore/tianocore.github.io/wiki/Security
>  EDK II Packages:
>  ----------------
>  
> +Drivers/OptionRomPkg
> +W: https://github.com/tianocore/tianocore.github.io/wiki/OptionRomPkg
> +M: Ray Ni <ray.ni@intel.com>
> +
>  Platform
>  M: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>  M: Leif Lindholm <leif.lindholm@linaro.org>
>  M: Michael D Kinney <michael.d.kinney@intel.com>
>  
> +Platform/Intel/QuarkPlatformPkg
> +M: Michael D Kinney <michael.d.kinney@intel.com>
> +M: Kelly Steele <kelly.steele@intel.com>
> +
> +Platform/Intel/Vlv2TbltDevicePkg
> +M: Zailiang Sun <zailiang.sun@intel.com>
> +M: Yi Qian <yi.qian@intel.com>
> +
>  Silicon
>  M: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>  M: Leif Lindholm <leif.lindholm@linaro.org>
>  M: Michael D Kinney <michael.d.kinney@intel.com>
> +
> +Silicon/Intel/QuarkSocPkg
> +M: Michael D Kinney <michael.d.kinney@intel.com>
> +M: Kelly Steele <kelly.steele@intel.com>
> +
> +Silicon/Intel/Vlv2DeviceRefCodePkg
> +M: Zailiang Sun <zailiang.sun@intel.com>
> +M: Yi Qian <yi.qian@intel.com>
> diff --git a/Readme.md b/Readme.md
> index 95c0c14522..aac9f69d46 100644
> --- a/Readme.md
> +++ b/Readme.md
> @@ -208,6 +208,9 @@ they will be documented with the platform.
>  
>  ## [ARM](Platform/ARM/Readme.md)
>  
> +## BeagleBoard
> +* [BeagleBoard](Platform\BeagleBoard\BeagleBoardPkg)

The link here uses \.

> +
>  ## Hisilicon
>  * [D02](Platform/Hisilicon/D02)
>  * [D03](Platform/Hisilicon/D03)
> @@ -223,6 +226,12 @@ they will be documented with the platform.
>  ## Socionext
>  * [SynQuacer](Platform/Socionext/DeveloperBox)
>  
> +## Intel(R) Quark SoC X1000 based platforms
> +* [Galileo](Platform/Intel/QuarkPlatformPkg)

And the other links (as well as existing links) all use /.
So change BeagleBoard link to use / too?

With that:
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>

> +
> +## Minnowboard Max/Turbot based on Intel Valleyview2 SoC
> +* [Minnowboard Max](Platform/Intel/Vlv2TbltDevicePkg)
> +
>  # Maintainers
>  
>  See [Maintainers.txt](Maintainers.txt).
> -- 
> 2.21.0.windows.1
> 
> 
> 
> 

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [edk2-devel] [edk2-platforms: Patch 0/8] Add packages from edk2
  2019-05-10  7:32     ` Liming Gao
@ 2019-05-10 18:49       ` Kubacki, Michael A
  0 siblings, 0 replies; 23+ messages in thread
From: Kubacki, Michael A @ 2019-05-10 18:49 UTC (permalink / raw)
  To: Gao, Liming, Kinney, Michael D, devel@edk2.groups.io
  Cc: Sun, Zailiang, Qian, Yi, Steele, Kelly, Ni, Ray, Leif Lindholm,
	Ard Biesheuvel

Some pending reviews are still actively going into devel-MinPlatform so do
update at the migration point.

Thanks,
Michael

> -----Original Message-----
> From: Gao, Liming
> Sent: Friday, May 10, 2019 12:33 AM
> To: Kinney, Michael D <michael.d.kinney@intel.com>; devel@edk2.groups.io
> Cc: Sun, Zailiang <zailiang.sun@intel.com>; Qian, Yi <yi.qian@intel.com>;
> Steele, Kelly <kelly.steele@intel.com>; Ni, Ray <ray.ni@intel.com>; Kubacki,
> Michael A <michael.a.kubacki@intel.com>; Leif Lindholm
> <leif.lindholm@linaro.org>; Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Subject: RE: [edk2-devel] [edk2-platforms: Patch 0/8] Add packages from
> edk2
> 
> OK. I add them into edk2 planning wiki.
> 
> Besides, I sent the patch to migrate devel-MinPlatform branch to master
> branch in edk2 platform repo.
> This change will be done next Monday. Please aware it.
> 
> Thanks
> Liming
> >-----Original Message-----
> >From: Kinney, Michael D
> >Sent: Friday, May 10, 2019 2:18 PM
> >To: Gao, Liming <liming.gao@intel.com>; devel@edk2.groups.io; Kinney,
> >Michael D <michael.d.kinney@intel.com>
> >Cc: Sun, Zailiang <zailiang.sun@intel.com>; Qian, Yi <yi.qian@intel.com>;
> >Steele, Kelly <kelly.steele@intel.com>; Ni, Ray <ray.ni@intel.com>;
> Kubacki,
> >Michael A <michael.a.kubacki@intel.com>; Leif Lindholm
> ><leif.lindholm@linaro.org>; Ard Biesheuvel <ard.biesheuvel@linaro.org>
> >Subject: RE: [edk2-devel] [edk2-platforms: Patch 0/8] Add packages from
> >edk2
> >
> >Liming,
> >
> >I will update license in edk2-plaforms after this patch is checked in.
> >
> >Yes.  The plan is to catch the stable tag.
> >
> >Mike
> >
> >> -----Original Message-----
> >> From: Gao, Liming
> >> Sent: Thursday, May 9, 2019 10:15 PM
> >> To: devel@edk2.groups.io; Kinney, Michael D
> >> <michael.d.kinney@intel.com>
> >> Cc: Sun, Zailiang <zailiang.sun@intel.com>; Qian, Yi
> >> <yi.qian@intel.com>; Steele, Kelly
> >> <kelly.steele@intel.com>; Ni, Ray <ray.ni@intel.com>;
> >> Kubacki, Michael A <michael.a.kubacki@intel.com>; Leif
> >> Lindholm <leif.lindholm@linaro.org>; Ard Biesheuvel
> >> <ard.biesheuvel@linaro.org>
> >> Subject: RE: [edk2-devel] [edk2-platforms: Patch 0/8] Add
> >> packages from edk2
> >>
> >> Mike:
> >>   I have two questions here.
> >> 1. Those module in edk2 has BSD + Patent License. But,
> >> edk2 platform code uses BSD license. That means the codes
> >> in edk2 platform will have the mix license. What's the
> >> plan to update edk2 platform code license to BSD +
> >> Patent?
> >> 2. What's plan for this change? This change impacts edk2
> >> project. Does it catch edk2 stable tag?
> >>
> >> Thanks
> >> Liming
> >> >-----Original Message-----
> >> >From: devel@edk2.groups.io [mailto:devel@edk2.groups.io]
> >> On Behalf Of
> >> >Michael D Kinney
> >> >Sent: Friday, May 10, 2019 11:34 AM
> >> >To: devel@edk2.groups.io
> >> >Cc: Sun, Zailiang <zailiang.sun@intel.com>; Qian, Yi
> >> <yi.qian@intel.com>;
> >> >Steele, Kelly <kelly.steele@intel.com>; Ni, Ray
> >> <ray.ni@intel.com>; Kubacki,
> >> >Michael A <michael.a.kubacki@intel.com>; Leif Lindholm
> >> ><leif.lindholm@linaro.org>; Ard Biesheuvel
> >> <ard.biesheuvel@linaro.org>
> >> >Subject: [edk2-devel] [edk2-platforms: Patch 0/8] Add
> >> packages from edk2
> >> >
> >> >https://bugzilla.tianocore.org/show_bug.cgi?id=1467
> >> >https://bugzilla.tianocore.org/show_bug.cgi?id=1374
> >> >https://bugzilla.tianocore.org/show_bug.cgi?id=1793
> >> >
> >> >Add the following platform, silicon, and driver packages
> >> from the edk2 repo
> >> >to the edk2-platforms repo
> >> >* Drivers/OptionRomPkg
> >> >* Platform/BeagleBoard/BeagleBoardPkg
> >> >* Platform/Intel/QuarkPlatformPkg
> >> >* Platform/Intel/Vlv2TbltDevicePkg
> >> >* Silicon/Intel/QuarkSocPkg
> >> >* Silicon/Intel/Vlv2DeviceRefCodePkg
> >> >* Silicon/TexasInsturments/Omap35xxPkg
> >> >
> >> >Cc: Zailiang Sun <zailiang.sun@intel.com>
> >> >Cc: Yi Qian <yi.qian@intel.com>
> >> >Cc: Kelly Steele <kelly.steele@intel.com>
> >> >Cc: Ray Ni <ray.ni@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>
> >> >
> >> >Michael D Kinney (8):
> >> >  Silicon/TexasInsturments: Import Omap35xxPkg from edk2
> >> >  Platform/BeagleBoard: Import BeagleBoardPkg from edk2
> >> >  Silicon/Intel: Import QuarkSocPkg from edk2
> >> >  Platform/QuarkPlatformPkg: Import QuarkPlatformPkg
> >> from edk2
> >> >  Platform/Vlv2DeviceRefCodePkg: Import
> >> Vlv2DeviceRefCodePkg from edk2
> >> >  Platform/Vlv2TbltDevicePkg: Import Vlv2TbltDevicePkg
> >> from edk2
> >> >  Drivers/OptionRomPkg: Import OptionRomPkg from edk2
> >> >  edk2-platforms: Update Maintainers.txt/Readme.md for
> >> imported packages
> >> >
> >> > .../Application/BltLibSample/BltLibSample.c   |  279 +
> >> > .../Application/BltLibSample/BltLibSample.inf |   30 +
> >> > .../AtapiPassThruDxe/AtapiPassThru.c          | 3410
> >> +++++++++++++
> >> > .../AtapiPassThruDxe/AtapiPassThru.h          | 1618
> >> ++++++
> >> > .../AtapiPassThruDxe/AtapiPassThruDxe.inf     |   70 +
> >> > .../AtapiPassThruDxe/ComponentName.c          |  169 +
> >> > .../DriverSupportedEfiVersion.c               |   14 +
> >> > .../FtdiUsbSerialDxe/CompatibleDevices.txt    |    5 +
> >> > .../Bus/Usb/FtdiUsbSerialDxe/ComponentName.c  |  218 +
> >> > .../FtdiUsbSerialDxe/FtdiUsbSerialDriver.c    | 2580
> >> ++++++++++
> >> > .../FtdiUsbSerialDxe/FtdiUsbSerialDriver.h    |  589
> >> +++
> >> > .../Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf |   55 +
> >> > .../Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt       |   32 +
> >> > .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.c   | 1318
> >> +++++
> >> > .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.h   |  969
> >> ++++
> >> > .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf |   61 +
> >> > .../Usb/UsbNetworking/Ax88772/ComponentName.c |  178 +
> >> > .../Usb/UsbNetworking/Ax88772/DriverBinding.c |  507 ++
> >> > .../Usb/UsbNetworking/Ax88772/SimpleNetwork.c | 1503
> >> ++++++
> >> > .../Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c  |  875
> >> ++++
> >> > .../Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h  | 1026
> >> ++++
> >> > .../Usb/UsbNetworking/Ax88772b/Ax88772b.inf   |   61 +
> >> > .../UsbNetworking/Ax88772b/ComponentName.c    |  175 +
> >> > .../UsbNetworking/Ax88772b/DriverBinding.c    |  696
> >> +++
> >> > .../UsbNetworking/Ax88772b/SimpleNetwork.c    | 1657
> >> ++++++
> >> > .../CirrusLogic5430Dxe/CirrusLogic5430.c      |  917
> >> ++++
> >> > .../CirrusLogic5430Dxe/CirrusLogic5430.h      |  432 ++
> >> > .../CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf |   84 +
> >> > .../CirrusLogic5430GraphicsOutput.c           |  556 ++
> >> > .../CirrusLogic5430Dxe/CirrusLogic5430I2c.c   |  427 ++
> >> > .../CirrusLogic5430Dxe/CirrusLogic5430I2c.h   |   62 +
> >> > .../CirrusLogic5430UgaDraw.c                  |  412 ++
> >> > .../CirrusLogic5430Dxe/ComponentName.c        |  203 +
> >> > .../DriverSupportedEfiVersion.c               |   14 +
> >> > .../OptionRomPkg/CirrusLogic5430Dxe/Edid.c    |  525 ++
> >> > Drivers/OptionRomPkg/Include/Library/BltLib.h |  253 +
> >> > .../FrameBufferBltLib/FrameBufferBltLib.c     |  744
> >> +++
> >> > .../FrameBufferBltLib/FrameBufferBltLib.inf   |   29 +
> >> > .../Library/GopBltLib/GopBltLib.c             |  449 ++
> >> > .../Library/GopBltLib/GopBltLib.inf           |   31 +
> >> > Drivers/OptionRomPkg/OptionRomPkg.dec         |   41 +
> >> > Drivers/OptionRomPkg/OptionRomPkg.dsc         |  113 +
> >> > Drivers/OptionRomPkg/ReadMe.txt               |   17 +
> >> > .../UndiRuntimeDxe/ComponentName.c            |  359 ++
> >> > Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c  | 1516
> >> ++++++
> >> > Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c   | 3541
> >> +++++++++++++
> >> > Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h   |  665
> >> +++
> >> > Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c    | 1051
> >> ++++
> >> > Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h  |  439 ++
> >> > .../OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c |  145 +
> >> > .../UndiRuntimeDxe/UndiRuntimeDxe.inf         |   72 +
> >> > Maintainers.txt                               |   20 +
> >> > .../BeagleBoardPkg/BeagleBoardPkg.dec         |   30 +
> >> > .../BeagleBoardPkg/BeagleBoardPkg.dsc         |  496 ++
> >> > .../BeagleBoardPkg/BeagleBoardPkg.fdf         |  308 ++
> >> > .../BeagleBoardPkg/ConfigurationHeader.bin    |  Bin 0
> >> -> 512 bytes
> >> > .../BeagleBoardPkg/ConfigurationHeader.dat    |   41 +
> >> > .../Debugger_scripts/rvi_boot_from_ram.inc    |   15 +
> >> > .../Debugger_scripts/rvi_convert_symbols.sh   |   17 +
> >> > .../Debugger_scripts/rvi_dummy.axf            |  Bin 0
> >> -> 7984 bytes
> >> > .../Debugger_scripts/rvi_hw_setup.inc         |   61 +
> >> > .../Debugger_scripts/rvi_load_symbols.inc     |   17 +
> >> > .../Debugger_scripts/rvi_symbols_macros.inc   |  188 +
> >> > .../Debugger_scripts/rvi_unload_symbols.inc   |  112 +
> >> > .../Debugger_scripts/trace32_load_symbols.cmm |  205 +
> >> > .../trace32_load_symbols_cygwin.cmm           |  182 +
> >> > .../BeagleBoardPkg/Include/BeagleBoard.h      |  173 +
> >> > .../Library/BeagleBoardLib/BeagleBoard.c      |  115 +
> >> > .../BeagleBoardLib/BeagleBoardHelper.S        |   41 +
> >> > .../BeagleBoardLib/BeagleBoardHelper.asm      |   47 +
> >> > .../Library/BeagleBoardLib/BeagleBoardLib.inf |   48 +
> >> > .../Library/BeagleBoardLib/BeagleBoardMem.c   |   74 +
> >> > .../Library/BeagleBoardLib/Clock.c            |   63 +
> >> > .../Library/BeagleBoardLib/PadConfiguration.c |  316 ++
> >> > .../Library/DxeHobPeCoffLib/DxeHobPeCoff.c    |  282 ++
> >> > .../DxeHobPeCoffLib/DxeHobPeCoffLib.inf       |   39 +
> >> > .../LzmaHobCustomDecompressLib.c              |   44 +
> >> > .../LzmaHobCustomDecompressLib.inf            |   45 +
> >> > .../MemoryInitPeiLib/MemoryInitPeiLib.c       |  192 +
> >> > .../MemoryInitPeiLib/MemoryInitPeiLib.inf     |   58 +
> >> > .../Library/ResetSystemLib/ResetSystemLib.c   |  149 +
> >> > .../Library/ResetSystemLib/ResetSystemLib.inf |   37 +
> >> > .../BeagleBoardPkg/PrePi/Arm/ArchPrePi.c      |   23 +
> >> > .../PrePi/Arm/ModuleEntryPoint.S              |  124 +
> >> > .../PrePi/Arm/ModuleEntryPoint.asm            |  142 +
> >> > .../BeagleBoardPkg/PrePi/LzmaDecompress.h     |   97 +
> >> > .../BeagleBoardPkg/PrePi/MainUniCore.c        |   33 +
> >> > .../BeagleBoardPkg/PrePi/PeiUniCore.inf       |   97 +
> >> > .../BeagleBoard/BeagleBoardPkg/PrePi/PrePi.c  |  179 +
> >> > .../BeagleBoard/BeagleBoardPkg/PrePi/PrePi.h  |   90 +
> >> > .../BeagleBoardPkg/Tools/GNUmakefile          |   14 +
> >> > .../BeagleBoardPkg/Tools/generate_image.c     |  402 ++
> >> > .../BeagleBoard/BeagleBoardPkg/Tools/makefile |   16 +
> >> > .../BeagleBoardPkg/Tools/replace.c            |  140 +
> >> > .../Acpi/AcpiTables/AcpiTables.inf            |   42 +
> >> > .../Acpi/AcpiTables/Cpu0Cst/Cpu0Cst.asl       |  399 ++
> >> > .../Acpi/AcpiTables/Cpu0Ist/Cpu0Ist.asl       |  159 +
> >> > .../Acpi/AcpiTables/Cpu0Tst/Cpu0Tst.asl       |  133 +
> >> > .../Acpi/AcpiTables/CpuPm/CpuPm.asl           |   73 +
> >> > .../Acpi/AcpiTables/Dsdt/AD7298.asi           |   38 +
> >> > .../Acpi/AcpiTables/Dsdt/ADC108S102.asi       |   33 +
> >> > .../Acpi/AcpiTables/Dsdt/CAT24C08.asi         |   34 +
> >> > .../Acpi/AcpiTables/Dsdt/CY8C9540A.asi        |   47 +
> >> > .../Acpi/AcpiTables/Dsdt/GpioClient.asi       |   89 +
> >> > .../Acpi/AcpiTables/Dsdt/LpcDev.asi           |  248 +
> >> > .../Acpi/AcpiTables/Dsdt/PCA9685.asi          |   34 +
> >> > .../Acpi/AcpiTables/Dsdt/PCAL9555A.asi        |   90 +
> >> > .../Acpi/AcpiTables/Dsdt/PciHostBridge.asi    |  195 +
> >> > .../Acpi/AcpiTables/Dsdt/PciIrq.asi           |  552 ++
> >> > .../Acpi/AcpiTables/Dsdt/PcieExpansionPrt.asi |  127 +
> >> > .../Acpi/AcpiTables/Dsdt/Platform.asl         |  347 ++
> >> > .../Acpi/AcpiTables/Dsdt/QNC.asi              |   49 +
> >> > .../Acpi/AcpiTables/Dsdt/QNCApic.asi          |   32 +
> >> > .../Acpi/AcpiTables/Dsdt/QNCLpc.asi           |   23 +
> >> > .../AcpiTables/Dsdt/QuarkSouthCluster.asi     |  110 +
> >> > .../Acpi/AcpiTables/Dsdt/Tpm.asi              |   45 +
> >> > .../Acpi/AcpiTables/Facs/Facs.aslc            |   74 +
> >> > .../Acpi/AcpiTables/Facs/Facs.h               |   29 +
> >> > .../Acpi/AcpiTables/Fadt/Fadt.h               |  102 +
> >> > .../Acpi/AcpiTables/Fadt/Fadt1.0.aslc         |   76 +
> >> > .../Acpi/AcpiTables/Fadt/Fadt2.0.aslc         |  157 +
> >> > .../Acpi/AcpiTables/Hpet/Hpet.aslc            |   68 +
> >> > .../Acpi/AcpiTables/Hpet/Hpet.h               |   45 +
> >> > .../Acpi/AcpiTables/Mcfg/Mcfg.aslc            |   75 +
> >> > .../Acpi/AcpiTables/Mcfg/Mcfg.h               |   56 +
> >> > .../Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.c     | 1402
> >> +++++
> >> > .../Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.h     |  316 ++
> >> > .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.c      |  805
> >> +++
> >> > .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.h      |  120 +
> >> > .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.inf    |  196 +
> >> > .../Acpi/Dxe/AcpiPlatform/Madt.h              |  207 +
> >> > .../Acpi/Dxe/AcpiPlatform/MadtPlatform.c      |  300 ++
> >> > .../BootScriptExecutorDxe.inf                 |   77 +
> >> > .../Dxe/BootScriptExecutorDxe/IA32/S3Asm.S    |   44 +
> >> > .../Dxe/BootScriptExecutorDxe/IA32/S3Asm.asm  |   51 +
> >> > .../BootScriptExecutorDxe/IA32/SetIdtEntry.c  |   57 +
> >> > .../Dxe/BootScriptExecutorDxe/ScriptExecute.c |  379 ++
> >> > .../Dxe/BootScriptExecutorDxe/ScriptExecute.h |   70 +
> >> > .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.c     | 1011
> >> ++++
> >> > .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.h     |  167 +
> >> > .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.inf   |   78 +
> >> > .../Acpi/DxeSmm/SmmPowerManagement/Ppm.c      |  372 ++
> >> > .../Acpi/DxeSmm/SmmPowerManagement/Ppm.h      |  150 +
> >> > .../SmmPowerManagement/SmmPowerManagement.c   |  113 +
> >> > .../SmmPowerManagement/SmmPowerManagement.h   |   52 +
> >> > .../SmmPowerManagement/SmmPowerManagement.inf |   74 +
> >> > .../Application/ForceRecovery/ForceRecovery.c |   47 +
> >> > .../ForceRecovery/ForceRecovery.inf           |   34 +
> >> > .../PlatformFlashAccessLibDxe.c               |  262 +
> >> > .../PlatformFlashAccessLibDxe.inf             |   47 +
> >> > .../PlatformFlashAccessLib/SpiFlashDevice.c   |  330 ++
> >> > .../PlatformFlashAccessLib/SpiFlashDevice.h   |  180 +
> >> > .../SystemFirmwareDescriptor.aslc             |   83 +
> >> > .../SystemFirmwareDescriptor.inf              |   40 +
> >> > .../SystemFirmwareDescriptorPei.c             |   60 +
> >> > .../SystemFirmwareUpdateConfig.ini            |   57 +
> >> > .../Include/Guid/CapsuleOnDataCD.h            |   23 +
> >> > .../Include/Guid/CapsuleOnFatFloppyDisk.h     |   23 +
> >> > .../Include/Guid/CapsuleOnFatIdeDisk.h        |   24 +
> >> > .../Include/Guid/CapsuleOnFatUsbDisk.h        |   24 +
> >> > .../Include/Guid/MemoryConfigData.h           |   23 +
> >> > .../Include/Guid/QuarkCapsuleGuid.h           |   46 +
> >> > .../Include/Guid/QuarkVariableLock.h          |   23 +
> >> > .../Include/Guid/SystemNvDataHobGuid.h        |   29 +
> >> > .../Include/Library/PlatformHelperLib.h       |  266 +
> >> > .../Include/Library/PlatformPcieHelperLib.h   |   56 +
> >> > .../Intel/QuarkPlatformPkg/Include/Pcal9555.h |   24 +
> >> > .../Intel/QuarkPlatformPkg/Include/Platform.h |  119 +
> >> > .../QuarkPlatformPkg/Include/PlatformBoards.h |  166 +
> >> > .../Include/Protocol/GlobalNvsArea.h          |   82 +
> >> > .../Include/Protocol/PlatformSmmSpiReady.h    |   23 +
> >> > .../PlatformBootManager.c                     |  472 ++
> >> > .../PlatformBootManager.h                     |   49 +
> >> > .../PlatformBootManagerLib.inf                |   83 +
> >> > .../PlatformBootManagerLib/PlatformData.c     |  275 +
> >> > .../Library/PlatformHelperLib/CommonHeader.h  |   51 +
> >> > .../DxePlatformHelperLib.inf                  |   70 +
> >> > .../PeiPlatformHelperLib.inf                  |   45 +
> >> > .../PlatformHelperLib/PlatformHelperDxe.c     |  337 ++
> >> > .../PlatformHelperLib/PlatformHelperLib.c     |  481 ++
> >> > .../PlatformHelperLib/PlatformHelperPei.c     |  159 +
> >> > .../Library/PlatformHelperLib/PlatformLeds.c  |  146 +
> >> > .../PlatformPcieHelperLib/CommonHeader.h      |   55 +
> >> > .../PlatformPcieHelperLib.c                   |  114 +
> >> > .../PlatformPcieHelperLib.inf                 |   41 +
> >> > .../Library/PlatformPcieHelperLib/SocUnit.c   |  125 +
> >> > .../Library/PlatformSecLib/Ia32/Flat32.S      |  796
> >> +++
> >> > .../Library/PlatformSecLib/Ia32/Flat32.asm    |  685
> >> +++
> >> > .../Library/PlatformSecLib/Ia32/Platform.inc  |  134 +
> >> > .../Library/PlatformSecLib/PlatformSecLib.c   |  207 +
> >> > .../Library/PlatformSecLib/PlatformSecLib.inf |   54 +
> >> > .../PlatformSecLib/PlatformSecLibModStrs.uni  |   18 +
> >> > .../PlatformSecureLib/PlatformSecureLib.c     |  164 +
> >> > .../PlatformSecureLib/PlatformSecureLib.inf   |   41 +
> >> > .../Library/Tpm12DeviceLibAtmelI2c/TisPc.c    |  408 ++
> >> > .../Tpm12DeviceLibAtmelI2c.inf                |   39 +
> >> > .../Tpm12DeviceLibAtmelI2c.uni                |   16 +
> >> > .../Library/Tpm12DeviceLibInfineonI2c/TisPc.c |  612
> >> +++
> >> > .../Tpm12DeviceLibInfineonI2c.inf             |   39 +
> >> > .../Tpm12DeviceLibInfineonI2c.uni             |   16 +
> >> > .../Pci/Dxe/PciHostBridge/PciHostBridge.c     | 1397
> >> +++++
> >> > .../Pci/Dxe/PciHostBridge/PciHostBridge.h     |  389 ++
> >> > .../Pci/Dxe/PciHostBridge/PciHostBridge.inf   |   61 +
> >> > .../Dxe/PciHostBridge/PciHostBridgeSupport.c  |  140 +
> >> > .../Pci/Dxe/PciHostBridge/PciHostResource.h   |   60 +
> >> > .../Pci/Dxe/PciHostBridge/PciRootBridge.h     |  693
> >> +++
> >> > .../Pci/Dxe/PciHostBridge/PciRootBridgeIo.c   | 1610
> >> ++++++
> >> > .../Pci/Dxe/PciPlatform/CommonHeader.h        |   31 +
> >> > .../Pci/Dxe/PciPlatform/PciPlatform.c         |  194 +
> >> > .../Pci/Dxe/PciPlatform/PciPlatform.h         |   82 +
> >> > .../Pci/Dxe/PciPlatform/PciPlatform.inf       |   54 +
> >> > .../Dxe/MemorySubClass/MemorySubClass.c       |  435 ++
> >> > .../Dxe/MemorySubClass/MemorySubClass.h       |   65 +
> >> > .../Dxe/MemorySubClass/MemorySubClass.inf     |   60 +
> >> > .../MemorySubClass/MemorySubClassStrings.uni  |   29 +
> >> > .../Dxe/PlatformInit/PlatformConfig.c         |  443 ++
> >> > .../Dxe/PlatformInit/PlatformInitDxe.c        |   87 +
> >> > .../Dxe/PlatformInit/PlatformInitDxe.h        |   58 +
> >> > .../Dxe/PlatformInit/PlatformInitDxe.inf      |   56 +
> >> > .../Dxe/SaveMemoryConfig/SaveMemoryConfig.c   |  118 +
> >> > .../Dxe/SaveMemoryConfig/SaveMemoryConfig.inf |   44 +
> >> > .../Platform/Dxe/Setup/CommonHeader.h         |   55 +
> >> > .../Platform/Dxe/Setup/DxePlatform.inf        |   76 +
> >> > .../Platform/Dxe/Setup/KeyboardLayout.c       |  262 +
> >> > .../Platform/Dxe/Setup/QNCRegTable.c          |   80 +
> >> > .../Platform/Dxe/Setup/SetupPlatform.c        |   97 +
> >> > .../Platform/Dxe/Setup/SetupPlatform.h        |   71 +
> >> > .../Platform/Dxe/Setup/Strings.uni            |   47 +
> >> > .../Platform/Dxe/Setup/processor.c            |   40 +
> >> > .../Platform/Dxe/SmbiosMiscDxe/CommonHeader.h |   34 +
> >> > .../MiscBaseBoardManufacturer.uni             |   19 +
> >> > .../MiscBaseBoardManufacturerData.c           |   45 +
> >> > .../MiscBaseBoardManufacturerFunction.c       |  181 +
> >> > .../Dxe/SmbiosMiscDxe/MiscBiosVendor.uni      |   18 +
> >> > .../Dxe/SmbiosMiscDxe/MiscBiosVendorData.c    |   92 +
> >> > .../SmbiosMiscDxe/MiscBiosVendorFunction.c    |  222 +
> >> > .../SmbiosMiscDxe/MiscBootInformationData.c   |   24 +
> >> > .../MiscBootInformationFunction.c             |   71 +
> >> > .../SmbiosMiscDxe/MiscChassisManufacturer.uni |   17 +
> >> > .../MiscChassisManufacturerData.c             |   36 +
> >> > .../MiscChassisManufacturerFunction.c         |  168 +
> >> > .../Dxe/SmbiosMiscDxe/MiscDevicePath.h        |   42 +
> >> > .../MiscNumberOfInstallableLanguagesData.c    |   28 +
> >> > ...MiscNumberOfInstallableLanguagesFunction.c |  240 +
> >> > .../Dxe/SmbiosMiscDxe/MiscOemString.uni       |   12 +
> >> > .../Dxe/SmbiosMiscDxe/MiscOemStringData.c     |   20 +
> >> > .../Dxe/SmbiosMiscDxe/MiscOemStringFunction.c |   78 +
> >> > .../Dxe/SmbiosMiscDxe/MiscOnboardDevice.uni   |   18 +
> >> > .../Dxe/SmbiosMiscDxe/MiscOnboardDeviceData.c |   49 +
> >> > .../SmbiosMiscDxe/MiscOnboardDeviceFunction.c |  105 +
> >> > .../MiscPortInternalConnectorDesignator.uni   |   53 +
> >> > .../MiscPortInternalConnectorDesignatorData.c |  184 +
> >> > ...cPortInternalConnectorDesignatorFunction.c |  292 ++
> >> > .../SmbiosMiscDxe/MiscSystemManufacturer.uni  |   20 +
> >> > .../MiscSystemManufacturerData.c              |   32 +
> >> > .../MiscSystemManufacturerFunction.c          |  198 +
> >> > .../SmbiosMiscDxe/MiscSystemOptionString.uni  |   14 +
> >> > .../MiscSystemOptionStringData.c              |   23 +
> >> > .../MiscSystemOptionStringFunction.c          |   81 +
> >> > .../MiscSystemSlotDesignation.uni             |   27 +
> >> > .../MiscSystemSlotDesignationData.c           |  357 ++
> >> > .../MiscSystemSlotDesignationFunction.c       |  285 ++
> >> > .../MiscSystemSlotOnboardDevices.uni          |   23 +
> >> > .../Platform/Dxe/SmbiosMiscDxe/SmbiosMisc.h   |  137 +
> >> > .../Dxe/SmbiosMiscDxe/SmbiosMiscDataTable.c   |  109 +
> >> > .../Dxe/SmbiosMiscDxe/SmbiosMiscDxe.inf       |  308 ++
> >> > .../Dxe/SmbiosMiscDxe/SmbiosMiscEntryPoint.c  |   82 +
> >> > .../Dxe/SmbiosMiscDxe/SmbiosMiscStrings.uni   |   26 +
> >> > .../Pei/PlatformConfig/PlatformConfigPei.c    |   81 +
> >> > .../Pei/PlatformConfig/PlatformConfigPei.inf  |   45 +
> >> > .../Platform/Pei/PlatformInit/BootMode.c      |  218 +
> >> > .../Platform/Pei/PlatformInit/CommonHeader.h  |   81 +
> >> > .../Pei/PlatformInit/Generic/Recovery.c       |  467 ++
> >> > .../Pei/PlatformInit/MemoryCallback.c         |  279 +
> >> > .../Platform/Pei/PlatformInit/MrcWrapper.c    | 1565
> >> ++++++
> >> > .../Platform/Pei/PlatformInit/MrcWrapper.h    |  225 +
> >> > .../Platform/Pei/PlatformInit/PeiFvSecurity.c |  111 +
> >> > .../Platform/Pei/PlatformInit/PeiFvSecurity.h |   67 +
> >> > .../Pei/PlatformInit/PlatformEarlyInit.c      | 1227
> >> +++++
> >> > .../Pei/PlatformInit/PlatformEarlyInit.h      |  301 ++
> >> > .../Pei/PlatformInit/PlatformEarlyInit.inf    |  193 +
> >> > .../Pei/PlatformInit/PlatformErratas.c        |  178 +
> >> > .../Platform/SpiFvbServices/FvbInfo.c         |  332 ++
> >> > .../Platform/SpiFvbServices/FwBlockService.c  | 2053
> >> ++++++++
> >> > .../Platform/SpiFvbServices/FwBlockService.h  |  308 ++
> >> > .../Platform/SpiFvbServices/PlatformSmmSpi.c  |   31 +
> >> > .../SpiFvbServices/PlatformSmmSpi.inf         |   80 +
> >> > .../Platform/SpiFvbServices/PlatformSpi.inf   |   79 +
> >> > .../Platform/SpiFvbServices/SpiFlashDevice.c  |  331 ++
> >> > .../Platform/SpiFvbServices/SpiFlashDevice.h  |  181 +
> >> > Platform/Intel/QuarkPlatformPkg/Quark.dsc     |  948
> >> ++++
> >> > Platform/Intel/QuarkPlatformPkg/Quark.fdf     |  907
> >> ++++
> >> > Platform/Intel/QuarkPlatformPkg/QuarkMin.dsc  |  648
> >> +++
> >> > Platform/Intel/QuarkPlatformPkg/QuarkMin.fdf  |  608
> >> +++
> >> > .../QuarkPlatformPkg/QuarkPlatformPkg.dec     |  933
> >> ++++
> >> > Platform/Intel/QuarkPlatformPkg/Readme.md     |  685
> >> +++
> >> > Platform/Intel/Vlv2TbltDevicePkg/.gitignore   |    5 +
> >> > .../AcpiPlatform/AcpiPlatform.c               | 1338
> >> +++++
> >> > .../AcpiPlatform/AcpiPlatform.h               |  219 +
> >> > .../AcpiPlatform/AcpiPlatform.inf             |   89 +
> >> > .../AcpiPlatform/AcpiPlatformHooks.c          |  493 ++
> >> > .../AcpiPlatform/AcpiPlatformHooks.h          |  127 +
> >> > .../AcpiPlatform/AcpiPlatformHooksLib.h       |   91 +
> >> > .../Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h     |   56 +
> >> > .../FirmwareUpdate/FirmwareUpdate.c           |  922
> >> ++++
> >> > .../FirmwareUpdate/FirmwareUpdate.h           |  185 +
> >> > .../FirmwareUpdate/FirmwareUpdate.inf         |   83 +
> >> > .../FirmwareUpdate/FirmwareUpdateStrings.uni  |   45 +
> >> > Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe   |  Bin 0
> >> -> 499712 bytes
> >> > Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env  |   25 +
> >> > Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env  |   25 +
> >> > .../Intel/Vlv2TbltDevicePkg/BiosIdx64D.env    |   25 +
> >> > .../Intel/Vlv2TbltDevicePkg/BiosIdx64R.env    |   25 +
> >> > .../BootScriptSaveDxe/BootScriptSaveDxe.inf   |   60 +
> >> > .../InternalBootScriptSave.h                  |  102 +
> >> > .../BootScriptSaveDxe/ScriptSave.c            |  626
> >> +++
> >> > .../Intel/Vlv2TbltDevicePkg/Build_IFWI.bat    |  200 +
> >> > .../Intel/Vlv2TbltDevicePkg/Build_IFWI.sh     |  104 +
> >> > Platform/Intel/Vlv2TbltDevicePkg/FCE.exe      |  Bin 0
> >> -> 632832 bytes
> >> > .../Capsule/GenerateCapsule/GenCapsuleAll.bat |   35 +
> >> > .../Capsule/GenerateCapsule/GenCapsuleAll.sh  |   28 +
> >> > .../GenerateCapsule/GenCapsuleMinnowMax.bat   |  131 +
> >> > .../GenerateCapsule/GenCapsuleMinnowMax.sh    |   65 +
> >> > .../GenCapsuleMinnowMaxRelease.bat            |  131 +
> >> > .../GenCapsuleMinnowMaxRelease.sh             |   65 +
> >> > .../GenerateCapsule/GenCapsuleSampleColor.bat |  137 +
> >> > .../GenerateCapsule/GenCapsuleSampleColor.sh  |   70 +
> >> > .../Feature/Capsule/GenerateCapsule/Lvfs.ddf  |   14 +
> >> > .../LvfsGenCapsuleMinnowMax.bat               |  139 +
> >> > .../LvfsGenCapsuleMinnowMaxRelease.bat        |  139 +
> >> > .../LvfsGenCapsuleSampleColor.bat             |  145 +
> >> > ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
> >> > ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
> >> > ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
> >> > .../GenerateCapsule/template.metainfo.xml     |   27 +
> >> > .../Library/FmpDeviceLib/FmpDeviceLib.c       |  589
> >> +++
> >> > .../Library/FmpDeviceLib/FmpDeviceLib.inf     |   46 +
> >> > .../Library/FmpDeviceLibSample/FmpDeviceLib.c |  412 ++
> >> > .../FmpDeviceLibSample/FmpDeviceLib.inf       |   34 +
> >> > .../PlatformFlashAccessLib.c                  |  685
> >> +++
> >> > .../PlatformFlashAccessLib.inf                |   54 +
> >> > .../SystemFirmwareDescriptor.aslc             |   83 +
> >> > .../SystemFirmwareDescriptor.inf              |   40 +
> >> > .../SystemFirmwareDescriptorPei.c             |   60 +
> >> > .../SystemFirmwareUpdateConfig.ini            |   66 +
> >> > .../SystemFirmwareUpdateConfigGcc.ini         |   66 +
> >> > .../Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc |   55 +
> >> > .../Vlv2TbltDevicePkg/FmpCertificate.dsc      |   22 +
> >> > .../FmpGreenSampleDevice.dsc                  |   55 +
> >> > .../Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc  |   59 +
> >> > .../Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc  |   55 +
> >> > .../FspAzaliaConfigData/AzaliaConfig.bin      |  Bin 0
> >> -> 3708 bytes
> >> > .../FspSupport/BootModePei/BootModePei.c      |   42 +
> >> > .../FspSupport/BootModePei/BootModePei.inf    |   40 +
> >> > .../FspHobProcessLibVlv2.c                    |  421 ++
> >> > .../FspHobProcessLibVlv2.inf                  |   74 +
> >> > .../FspPlatformSecLibVlv2.c                   |  144 +
> >> > .../FspPlatformSecLibVlv2.inf                 |   82 +
> >> > .../Ia32/AsmSaveSecContext.asm                |   45 +
> >> > .../SecFspPlatformSecLibVlv2/Ia32/Fsp.inc     |   45 +
> >> > .../Ia32/PeiCoreEntry.asm                     |  135 +
> >> > .../Ia32/SecEntry.asm                         |  338 ++
> >> > .../SecFspPlatformSecLibVlv2/Ia32/Stack.S     |   71 +
> >> > .../SecFspPlatformSecLibVlv2/Ia32/Stack.asm   |   76 +
> >> > .../SecFspPlatformSecLibVlv2/PlatformInit.c   |   36 +
> >> > .../SecFspPlatformSecLibVlv2/SaveSecContext.c |  108 +
> >> > .../SecGetPerformance.c                       |   83 +
> >> > .../SecPlatformInformation.c                  |   77 +
> >> > .../SecFspPlatformSecLibVlv2/SecRamInitData.c |   16 +
> >> > .../SecTempRamSupport.c                       |  149 +
> >> > .../SecFspPlatformSecLibVlv2/UartInit.c       |  192 +
> >> > .../Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c   |   68 +
> >> > .../Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf |   49 +
> >> > .../Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c |  170 +
> >> > .../FvbRuntimeDxe/FvbRuntimeDxe.inf           |   80 +
> >> > .../FvbRuntimeDxe/FvbService.c                | 1098
> >> ++++
> >> > .../FvbRuntimeDxe/FvbService.h                |  182 +
> >> > .../FvbRuntimeDxe/FvbServiceDxe.c             |  199 +
> >> > .../FvbRuntimeDxe/FvbServiceSmm.c             |  127 +
> >> > .../FvbRuntimeDxe/FvbSmm.inf                  |   82 +
> >> > .../FvbRuntimeDxe/FvbSmmCommon.h              |   73 +
> >> > .../FvbRuntimeDxe/FvbSmmDxe.c                 |  944
> >> ++++
> >> > .../FvbRuntimeDxe/FvbSmmDxe.h                 |  232 +
> >> > .../FvbRuntimeDxe/FvbSmmDxe.inf               |   50 +
> >> > Platform/Intel/Vlv2TbltDevicePkg/GenBiosId    |  Bin 0
> >> -> 12236 bytes
> >> > .../Intel/Vlv2TbltDevicePkg/GenBiosId.exe     |  Bin 0
> >> -> 384000 bytes
> >> > .../Include/AlertStandardFormatTable.h        |  122 +
> >> > .../Vlv2TbltDevicePkg/Include/ChipsetAccess.h |   28 +
> >> > .../Include/CommonIncludes.h                  |  115 +
> >> > .../Intel/Vlv2TbltDevicePkg/Include/CpuType.h |   59 +
> >> > .../Vlv2TbltDevicePkg/Include/FileHandleLib.h |  499 ++
> >> > .../Include/Guid/AcpiTableStorage.h           |   30 +
> >> > .../Include/Guid/AlertStandardFormat.h        |   86 +
> >> > .../Vlv2TbltDevicePkg/Include/Guid/BiosId.h   |   30 +
> >> > .../Include/Guid/BoardFeatures.h              |  214 +
> >> > .../Include/Guid/EfiVpdData.h                 |  156 +
> >> > .../Include/Guid/FirmwareId.h                 |   61 +
> >> > .../Include/Guid/HwWatchdogTimerHob.h         |  134 +
> >> > .../Vlv2TbltDevicePkg/Include/Guid/IdccData.h |  104 +
> >> > .../Vlv2TbltDevicePkg/Include/Guid/ItkData.h  |   70 +
> >> > .../Include/Guid/MemoryConfigData.h           |   32 +
> >> > .../Include/Guid/OsSelection.h                |   85 +
> >> > .../Include/Guid/PciLanInfo.h                 |   39 +
> >> > .../Include/Guid/PlatformCpuInfo.h            |  180 +
> >> > .../Include/Guid/PlatformInfo.h               |  433 ++
> >> > .../Include/Guid/SensorInfoVariable.h         |  279 +
> >> > .../Include/Guid/SetupVariable.h              | 1344
> >> +++++
> >> > .../Intel/Vlv2TbltDevicePkg/Include/Hpet.h    |   40 +
> >> > .../Include/Library/BiosIdLib.h               |  104 +
> >> > .../Include/Library/CpuIA32.h                 |  345 ++
> >> > .../Include/Library/EfiRegTableLib.h          |  196 +
> >> > .../Vlv2TbltDevicePkg/Include/Library/Esrt.h  |   74 +
> >> > .../Vlv2TbltDevicePkg/Include/Library/Fd.h    |  264 +
> >> > .../Include/Library/FlashDeviceLib.h          |  122 +
> >> > .../Include/Library/I2CLib.h                  |   58 +
> >> > .../Include/Library/I2cMmioConfigLib.h        |   23 +
> >> > .../Include/Library/I2cPort_platform.h        |   26 +
> >> > .../Include/Library/PlatformFsaLib.h          |   50 +
> >> > .../Include/Library/PlatformFspLib.h          |   23 +
> >> > .../Include/Library/SpiFlash.H                |  239 +
> >> > .../Include/Library/StallSmmLib.h             |   40 +
> >> > .../Include/Library/UsbDeviceModeLib.h        |  181 +
> >> > .../Intel/Vlv2TbltDevicePkg/Include/Mcfg.h    |   69 +
> >> > .../Vlv2TbltDevicePkg/Include/McfgTable.h     |   65 +
> >> > .../Vlv2TbltDevicePkg/Include/Platform.h      |  133 +
> >> > .../Include/PlatformBootMode.h                |   35 +
> >> > .../Include/PlatformDefinitions.h             |   43 +
> >> > .../Include/Ppi/MfgMemoryTest.h               |   42 +
> >> > .../Include/Ppi/Sha256Hash.h                  |  131 +
> >> > .../Vlv2TbltDevicePkg/Include/Ppi/Speaker.h   |   65 +
> >> > .../Include/Ppi/UsbController.h               |   85 +
> >> > .../Include/Protocol/CK505ClockPlatformInfo.h |  126 +
> >> > .../Include/Protocol/EnhancedSpeedstep.h      |   76 +
> >> > .../Include/Protocol/GlobalNvsArea.h          |  475 ++
> >> > .../Include/Protocol/HwWatchdogTimer.h        |  235 +
> >> > .../Include/Protocol/I2cAcpi.h                |  107 +
> >> > .../Include/Protocol/I2cBus.h                 |  164 +
> >> > .../Include/Protocol/I2cBusMcg.h              |  163 +
> >> > .../Include/Protocol/I2cHostMcg.h             |  138 +
> >> > .../Include/Protocol/I2cMasterMcg.h           |  519 ++
> >> > .../Include/Protocol/I2cSlave.h               |  194 +
> >> > .../Include/Protocol/LpcWpc83627Policy.h      |   92 +
> >> > .../Include/Protocol/LpcWpce791Policy.h       |   55 +
> >> > .../Include/Protocol/MmioDevice.h             |   84 +
> >> > .../Include/Protocol/Observable.h             |  186 +
> >> > .../Include/Protocol/PlatformGopPolicy.h      |   68 +
> >> > .../Include/Protocol/PlatformIdeInit.h        |   43 +
> >> > .../Include/Protocol/SetupMode.h              |   79 +
> >> > .../Include/Protocol/SmbiosSlotPopulation.h   |   47 +
> >> > .../Include/Protocol/Speaker.h                |   65 +
> >> > .../Include/Protocol/TcoReset.h               |   67 +
> >> > .../Include/Protocol/TpmMp.h                  |  136 +
> >> > .../Include/Protocol/UsbPolicy.h              |  126 +
> >> > .../Include/Protocol/VlvPlatformPolicy.h      |  102 +
> >> > .../Vlv2TbltDevicePkg/Include/SetupMode.h     |   85 +
> >> > .../IntelGopDepex/IntelGopDriver.depex        |    1 +
> >> > .../Library/BiosIdLib/BiosIdLib.c             |  337 ++
> >> > .../Library/BiosIdLib/BiosIdLib.inf           |   50 +
> >> > .../Library/CpuIA32Lib/CpuIA32Lib.inf         |   41 +
> >> > .../Library/CpuIA32Lib/EfiCpuVersion.c        |   70 +
> >> > .../Library/CpuIA32Lib/IA32/CpuIA32.S         |  223 +
> >> > .../Library/CpuIA32Lib/IA32/CpuIA32.asm       |  206 +
> >> > .../Library/CpuIA32Lib/IA32/CpuIA32.c         |  177 +
> >> > .../Library/CpuIA32Lib/X64/Cpu.S              |  207 +
> >> > .../Library/CpuIA32Lib/X64/Cpu.asm            |  222 +
> >> > .../Library/EfiRegTableLib/EfiRegTableLib.c   |  282 ++
> >> > .../Library/EfiRegTableLib/EfiRegTableLib.inf |   47 +
> >> > .../Library/FlashDeviceLib/FlashDeviceLib.c   |  461 ++
> >> > .../Library/FlashDeviceLib/FlashDeviceLib.inf |   44 +
> >> > .../FlashDeviceLib/FlashDeviceLibDxe.c        |   56 +
> >> > .../FlashDeviceLib/FlashDeviceLibDxe.inf      |   43 +
> >> > .../FlashDeviceLibDxeRuntimeSmm.c             |  173 +
> >> > .../FlashDeviceLib/SpiChipDefinitions.h       |  835
> >> +++
> >> > .../Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c |   46 +
> >> > .../Library/I2CLib/I2CLibNull.inf             |   39 +
> >> > .../Library/I2CLibDxe/I2CLib.c                |  735
> >> +++
> >> > .../Library/I2CLibDxe/I2CLibDxe.inf           |   39 +
> >> > .../Library/I2CLibDxe/I2CRegs.h               |  126 +
> >> > .../Library/I2CLibPei/I2CAccess.h             |   44 +
> >> > .../Library/I2CLibPei/I2CDelayPei.c           |   46 +
> >> > .../Library/I2CLibPei/I2CDelayPei.h           |   30 +
> >> > .../Library/I2CLibPei/I2CIoLibPei.c           |  178 +
> >> > .../Library/I2CLibPei/I2CIoLibPei.h           |  153 +
> >> > .../Library/I2CLibPei/I2CLibPei.c             |  638
> >> +++
> >> > .../Library/I2CLibPei/I2CLibPei.h             |  280 +
> >> > .../Library/I2CLibPei/I2CLibPei.inf           |   40 +
> >> > .../IntelPchAcpiTimerLib/CommonHeader.h       |   27 +
> >> > .../IntelPchAcpiTimerLib.c                    |  255 +
> >> > .../IntelPchAcpiTimerLib.inf                  |   51 +
> >> > .../BoardClkGens/BoardClkGens.c               |  430 ++
> >> > .../BoardClkGens/BoardClkGens.h               |  255 +
> >> > .../MultiPlatformLib/BoardGpios/BoardGpios.c  |  531 ++
> >> > .../MultiPlatformLib/BoardGpios/BoardGpios.h  |  324 ++
> >> > .../BoardJumpers/BoardJumpers.c               |   30 +
> >> > .../BoardJumpers/BoardJumpers.h               |   30 +
> >> > .../BoardOemIds/BoardOemIds.c                 |   43 +
> >> > .../BoardOemIds/BoardOemIds.h                 |   29 +
> >> > .../BoardSsidSvid/BoardSsidSvid.c             |   38 +
> >> > .../BoardSsidSvid/BoardSsidSvid.h             |   35 +
> >> > .../MultiPlatformLib/MultiPlatformLib.c       |  120 +
> >> > .../MultiPlatformLib/MultiPlatformLib.h       |   89 +
> >> > .../MultiPlatformLib/MultiPlatformLib.inf     |   77 +
> >> > .../MultiPlatformLib/PlatformInfoHob.c        |   54 +
> >> > .../Library/PchPlatformLib/PchPlatformLib.inf |   50 +
> >> > .../PchPlatformLib/PchPlatformLibrary.c       |  131 +
> >> > .../PchPlatformLib/PchPlatformLibrary.h       |   35 +
> >> > .../Library/PchSmmLib/CommonHeader.h          |   32 +
> >> > .../Library/PchSmmLib/PchSmmLib.c             |  157 +
> >> > .../Library/PchSmmLib/PchSmmLib.inf           |   46 +
> >> > .../Library/PlatformBdsLib/BdsPlatform.c      | 3098
> >> ++++++++++++
> >> > .../Library/PlatformBdsLib/BdsPlatform.h      |  516 ++
> >> > .../Library/PlatformBdsLib/PlatformBdsLib.inf |  127 +
> >> > .../PlatformBdsLib/PlatformBdsStrings.uni     |   30 +
> >> > .../Library/PlatformBdsLib/PlatformData.c     |  306 ++
> >> > .../Library/PlatformCmosLib/PlatformCmosLib.c |  106 +
> >> > .../PlatformCmosLib/PlatformCmosLib.inf       |   30 +
> >> > .../Library/PlatformFspLib/PlatformFspLib.c   |   44 +
> >> > .../Library/PlatformFspLib/PlatformFspLib.inf |   49 +
> >> > .../Library/ResetSystemLib/ResetSystemLib.c   |  235 +
> >> > .../Library/ResetSystemLib/ResetSystemLib.inf |   47 +
> >> > .../SerialPortLib/PlatformSerialPortLib.h     |   53 +
> >> > .../Library/SerialPortLib/SerialPortLib.c     |  246 +
> >> > .../Library/SerialPortLib/SerialPortLib.inf   |   52 +
> >> > .../Library/SerialPortLib/SioInit.c           |  127 +
> >> > .../Library/SerialPortLib/SioInit.h           |   62 +
> >> > .../Library/SmbusLib/CommonHeader.h           |   26 +
> >> > .../Library/SmbusLib/SmbusLib.c               |  873
> >> ++++
> >> > .../Library/SmbusLib/SmbusLib.inf             |   46 +
> >> > .../Library/StallSmmLib/StallSmm.c            |   89 +
> >> > .../Library/StallSmmLib/StallSmmLib.inf       |   51 +
> >> > .../Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.c    |  117 +
> >> > .../Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.inf  |   61 +
> >> > .../Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.c    |  145 +
> >> > .../Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.inf  |   60 +
> >> > .../Intel/Vlv2TbltDevicePkg/Logo/Logo.bmp     |  Bin 0
> >> -> 94434 bytes
> >> > .../Metronome/LegacyMetronome.c               |  185 +
> >> > .../Metronome/LegacyMetronome.h               |   64 +
> >> > .../Vlv2TbltDevicePkg/Metronome/Metronome.inf |   49 +
> >> > .../MonoStatusCode/EfiStatusCode.h            |  178 +
> >> > .../MonoStatusCode/MonoStatusCode.c           |  132 +
> >> > .../MonoStatusCode/MonoStatusCode.h           |  128 +
> >> > .../MonoStatusCode/MonoStatusCode.inf         |   72 +
> >> > .../MonoStatusCode/PeiPostCode.c              |  121 +
> >> > .../MonoStatusCode/PlatformStatusCode.c       |  381 ++
> >> > .../MonoStatusCode/PlatformStatusCode.h       |  138 +
> >> > .../Library/GenericBdsLib/BdsBoot.c           | 4490
> >> +++++++++++++++++
> >> > .../Library/GenericBdsLib/BdsConnect.c        |  429 ++
> >> > .../Library/GenericBdsLib/BdsConsole.c        | 1061
> >> ++++
> >> > .../Library/GenericBdsLib/BdsMisc.c           | 1575
> >> ++++++
> >> > .../Library/GenericBdsLib/DevicePath.c        |   27 +
> >> > .../Library/GenericBdsLib/GenericBdsLib.inf   |  142 +
> >> > .../Library/GenericBdsLib/GenericBdsLib.uni   |   19 +
> >> > .../GenericBdsLib/GenericBdsStrings.uni       |   30 +
> >> > .../Library/GenericBdsLib/InternalBdsLib.h    |  173 +
> >> > .../Library/GenericBdsLib/String.c            |   26 +
> >> > .../Library/GenericBdsLib/String.h            |   42 +
> >> > .../PciPlatform/BoardPciPlatform.c            |   55 +
> >> > .../PciPlatform/PciPlatform.c                 |  367 ++
> >> > .../PciPlatform/PciPlatform.h                 |   83 +
> >> > .../PciPlatform/PciPlatform.inf               |   65 +
> >> > .../Vlv2TbltDevicePkg/PlatformCapsule.dsc     |   39 +
> >> > .../Vlv2TbltDevicePkg/PlatformCapsule.fdf     |   52 +
> >> > .../Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc  |   38 +
> >> > .../Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf  |   52 +
> >> > .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.c   |   60 +
> >> > .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.h   |   29 +
> >> > .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf |   55 +
> >> > .../PlatformDxe/AzaliaVerbTable.h             |  247 +
> >> > .../Vlv2TbltDevicePkg/PlatformDxe/BoardId.c   |  223 +
> >> > .../PlatformDxe/BoardIdDecode.c               |  129 +
> >> > .../PlatformDxe/BoardIdDecode.h               |   61 +
> >> > .../PlatformDxe/ClockControl.c                |  202 +
> >> > .../PlatformDxe/Configuration.h               |  692
> >> +++
> >> > .../Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c |   89 +
> >> > .../PlatformDxe/IchPlatformPolicy.c           |  484 ++
> >> > .../PlatformDxe/IchRegTable.c                 |  134 +
> >> > .../PlatformDxe/IchTcoReset.c                 |  211 +
> >> > .../Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c  |   72 +
> >> > .../PlatformDxe/LegacySpeaker.c               |  161 +
> >> > .../PlatformDxe/LegacySpeaker.h               |   69 +
> >> > .../PlatformDxe/Observable/Observable.c       |  582
> >> +++
> >> > .../PlatformDxe/Observable/Observable.h       |  137 +
> >> > .../Vlv2TbltDevicePkg/PlatformDxe/PciBus.h    |  379 ++
> >> > .../Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c |  506 ++
> >> > .../Vlv2TbltDevicePkg/PlatformDxe/Platform.c  | 1820
> >> +++++++
> >> > .../PlatformDxe/PlatformDxe.h                 |  722
> >> +++
> >> > .../PlatformDxe/PlatformDxe.inf               |  149 +
> >> > .../Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c |  154 +
> >> > .../Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c |  112 +
> >> > .../PlatformDxe/SioPlatformPolicy.c           |   82 +
> >> > .../PlatformDxe/SlotConfig.c                  |  148 +
> >> > .../PlatformDxe/SlotConfig.h                  |   80 +
> >> > .../PlatformGopPolicy/PlatformGopPolicy.c     |  201 +
> >> > .../PlatformGopPolicy/PlatformGopPolicy.inf   |   51 +
> >> > .../PlatformInfoDxe/PlatformInfoDxe.c         |  169 +
> >> > .../PlatformInfoDxe/PlatformInfoDxe.h         |   30 +
> >> > .../PlatformInfoDxe/PlatformInfoDxe.inf       |   52 +
> >> > .../PlatformInitPei/BootMode.c                |  434 ++
> >> > .../PlatformInitPei/CpuInitPeim.c             |   44 +
> >> > .../Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c  |  319 ++
> >> > .../PlatformInitPei/FlashMap.c                |  143 +
> >> > .../PlatformInitPei/LegacySpeaker.c           |  168 +
> >> > .../PlatformInitPei/LegacySpeaker.h           |   71 +
> >> > .../PlatformInitPei/MchInit.c                 |   72 +
> >> > .../PlatformInitPei/MemoryCallback.c          |  338 ++
> >> > .../PlatformInitPei/MemoryPeim.c              |  408 ++
> >> > .../PlatformInitPei/PchInitPeim.c             |  808
> >> +++
> >> > .../PlatformInitPei/PlatformEarlyInit.c       | 1195
> >> +++++
> >> > .../PlatformInitPei/PlatformEarlyInit.h       | 1499
> >> ++++++
> >> > .../PlatformInitPei/PlatformInfoInit.c        |  181 +
> >> > .../PlatformInitPei/PlatformInitPei.inf       |  117 +
> >> > .../PlatformInitPei/PlatformSsaInitPeim.c     |   58 +
> >> > .../PlatformInitPei/Recovery.c                |  361 ++
> >> > .../Vlv2TbltDevicePkg/PlatformInitPei/Stall.c |   91 +
> >> > .../Vlv2TbltDevicePkg/PlatformPei/BootMode.c  |  346 ++
> >> > .../PlatformPei/CommonHeader.h                |   60 +
> >> > .../PlatformPei/MemoryCallback.c              |  154 +
> >> > .../Vlv2TbltDevicePkg/PlatformPei/Platform.c  | 1198
> >> +++++
> >> > .../Vlv2TbltDevicePkg/PlatformPei/Platform.h  |  213 +
> >> > .../PlatformPei/PlatformPei.inf               |  129 +
> >> > .../Vlv2TbltDevicePkg/PlatformPei/Stall.c     |   90 +
> >> > .../Intel/Vlv2TbltDevicePkg/PlatformPkg.dec   |  211 +
> >> > .../Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf   | 1073
> >> ++++
> >> > .../Vlv2TbltDevicePkg/PlatformPkgConfig.dsc   |  107 +
> >> > .../Vlv2TbltDevicePkg/PlatformPkgGcc.fdf      | 1033
> >> ++++
> >> > .../Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc   | 1711
> >> +++++++
> >> > .../Vlv2TbltDevicePkg/PlatformPkgIA32.dsc     | 1699
> >> +++++++
> >> > .../Vlv2TbltDevicePkg/PlatformPkgX64.dsc      | 1714
> >> +++++++
> >> > .../PlatformSetupDxe/Boot.vfi                 |   72 +
> >> > .../PlatformSetupDxe/Configuration.h          |   56 +
> >> > .../PlatformSetupDxe/DebugConfig.vfi          |  118 +
> >> > .../PlatformSetupDxe/FwVersionStrings.uni     |   40 +
> >> > .../PlatformSetupDxe/Main.vfi                 |  331 ++
> >> > .../PlatformSetupDxe/PlatformSetupDxe.c       |  929
> >> ++++
> >> > .../PlatformSetupDxe/PlatformSetupDxe.h       |   97 +
> >> > .../PlatformSetupDxe/PlatformSetupDxe.inf     |  141 +
> >> > .../PlatformSetupDxe/Security.vfi             |  104 +
> >> > .../PlatformSetupDxe/SetupFunctions.c         |   85 +
> >> > .../PlatformSetupDxe/SetupInfoRecords.c       | 1855
> >> +++++++
> >> > .../PlatformSetupDxe/SouthClusterConfig.vfi   |  933
> >> ++++
> >> > .../PlatformSetupDxe/SystemComponent.vfi      |   81 +
> >> > .../PlatformSetupDxe/Thermal.vfi              |  106 +
> >> > .../PlatformSetupDxe/UnCore.vfi               |  235 +
> >> > .../PlatformSetupDxe/UqiList.uni              |  452 ++
> >> > .../PlatformSetupDxe/Vfr.vfr                  |  123 +
> >> > .../PlatformSetupDxe/VfrStrings.uni           | 1417
> >> ++++++
> >> > .../Vlv2TbltDevicePkg/PlatformSmm/Platform.c  |  997
> >> ++++
> >> > .../PlatformSmm/PlatformSmm.inf               |   93 +
> >> > .../Vlv2TbltDevicePkg/PlatformSmm/S3Save.c    |  377 ++
> >> > .../PlatformSmm/SmmPlatform.h                 |  240 +
> >> > .../PlatformSmm/SmmScriptSave.c               |  252 +
> >> > .../PlatformSmm/SmmScriptSave.h               |   50 +
> >> > .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c   |  148 +
> >> > .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h   |   36 +
> >> > .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf |   49 +
> >> > Platform/Intel/Vlv2TbltDevicePkg/Readme.md    |  233 +
> >> > .../SaveMemoryConfig/SaveMemoryConfig.c       |  181 +
> >> > .../SaveMemoryConfig/SaveMemoryConfig.h       |   66 +
> >> > .../SaveMemoryConfig/SaveMemoryConfig.inf     |   60 +
> >> > .../SmBiosMiscDxe/CommonHeader.h              |   39 +
> >> > .../MiscBaseBoardManufacturer.uni             |   33 +
> >> > .../MiscBaseBoardManufacturerData.c           |   58 +
> >> > .../MiscBaseBoardManufacturerFunction.c       |  238 +
> >> > .../SmBiosMiscDxe/MiscBiosVendor.uni          |   26 +
> >> > .../SmBiosMiscDxe/MiscBiosVendorData.c        |  101 +
> >> > .../SmBiosMiscDxe/MiscBiosVendorFunction.c    |  336 ++
> >> > .../SmBiosMiscDxe/MiscBootInformationData.c   |   34 +
> >> > .../MiscBootInformationFunction.c             |   82 +
> >> > .../SmBiosMiscDxe/MiscChassisManufacturer.uni |   28 +
> >> > .../MiscChassisManufacturerData.c             |   57 +
> >> > .../MiscChassisManufacturerFunction.c         |  158 +
> >> > .../SmBiosMiscDxe/MiscMemoryDevice.uni        |   35 +
> >> > .../SmBiosMiscDxe/MiscMemoryDeviceData.c      |   45 +
> >> > .../SmBiosMiscDxe/MiscMemoryDeviceFunction.c  |  319 ++
> >> > .../MiscNumberOfInstallableLanguagesData.c    |   38 +
> >> > ...MiscNumberOfInstallableLanguagesFunction.c |  251 +
> >> > .../SmBiosMiscDxe/MiscOemString.uni           |   25 +
> >> > .../SmBiosMiscDxe/MiscOemStringData.c         |   34 +
> >> > .../SmBiosMiscDxe/MiscOemStringFunction.c     |   89 +
> >> > .../SmBiosMiscDxe/MiscOemType0x90.uni         |   31 +
> >> > .../SmBiosMiscDxe/MiscOemType0x90Data.c       |   36 +
> >> > .../SmBiosMiscDxe/MiscOemType0x90Function.c   |  442 ++
> >> > .../SmBiosMiscDxe/MiscOemType0x94.uni         |   42 +
> >> > .../SmBiosMiscDxe/MiscOemType0x94Data.c       |   54 +
> >> > .../SmBiosMiscDxe/MiscOemType0x94Function.c   | 1218
> >> +++++
> >> > .../SmBiosMiscDxe/MiscOnboardDevice.uni       |   26 +
> >> > .../SmBiosMiscDxe/MiscOnboardDeviceData.c     |   48 +
> >> > .../SmBiosMiscDxe/MiscOnboardDeviceFunction.c |  135 +
> >> > .../SmBiosMiscDxe/MiscPhysicalArray.uni       |   25 +
> >> > .../SmBiosMiscDxe/MiscPhysicalArrayData.c     |   38 +
> >> > .../SmBiosMiscDxe/MiscPhysicalArrayFunction.c |  101 +
> >> > .../MiscPortInternalConnectorDesignator.uni   |   31 +
> >> > .../MiscPortInternalConnectorDesignatorData.c |   56 +
> >> > ...cPortInternalConnectorDesignatorFunction.c |  152 +
> >> > .../SmBiosMiscDxe/MiscProcessorCache.uni      |   22 +
> >> > .../SmBiosMiscDxe/MiscProcessorCacheData.c    |   33 +
> >> > .../MiscProcessorCacheFunction.c              |  189 +
> >> > .../MiscProcessorInformation.uni              |   27 +
> >> > .../MiscProcessorInformationData.c            |   71 +
> >> > .../MiscProcessorInformationFunction.c        |  448 ++
> >> > .../SmBiosMiscDxe/MiscResetCapabilitiesData.c |   43 +
> >> > .../MiscResetCapabilitiesFunction.c           |   85 +
> >> > .../SmBiosMiscDxe/MiscSubclassDriver.h        |  188 +
> >> > .../SmBiosMiscDxe/MiscSubclassDriver.uni      |   35 +
> >> > .../MiscSubclassDriverDataTable.c             |   98 +
> >> > .../MiscSubclassDriverEntryPoint.c            |  182 +
> >> > .../MiscSystemLanguageString.uni              |   24 +
> >> > .../MiscSystemLanguageStringData.c            |   34 +
> >> > .../MiscSystemLanguageStringFunction.c        |   93 +
> >> > .../SmBiosMiscDxe/MiscSystemManufacturer.uni  |   30 +
> >> > .../MiscSystemManufacturerData.c              |   48 +
> >> > .../MiscSystemManufacturerFunction.c          |  364 ++
> >> > .../SmBiosMiscDxe/MiscSystemOptionString.uni  |   24 +
> >> > .../MiscSystemOptionStringData.c              |   31 +
> >> > .../MiscSystemOptionStringFunction.c          |   93 +
> >> > .../MiscSystemSlotDesignation.uni             |   34 +
> >> > .../MiscSystemSlotDesignationData.c           |  246 +
> >> > .../MiscSystemSlotDesignationFunction.c       |  127 +
> >> > .../SmBiosMiscDxe/SmBiosMiscDxe.inf           |  139 +
> >> > .../SmmSwDispatch2OnSmmSwDispatchThunk.c      |  459 ++
> >> > .../SmmSwDispatch2OnSmmSwDispatchThunk.inf    |   54 +
> >> > .../SmramSaveInfoHandlerSmm.c                 |  164 +
> >> > .../SmramSaveInfoHandlerSmm.inf               |   60 +
> >> > .../Stitch/Gcc/NvStorageFtwSpare.bin          |  Bin 0
> >> -> 262144 bytes
> >> > .../Stitch/Gcc/NvStorageFtwWorking.bin        |  Bin 0
> >> -> 8192 bytes
> >> > .../Stitch/Gcc/NvStorageVariable.bin          |  Bin 0
> >> -> 253952 bytes
> >> > .../Stitch/IFWIHeader/IFWI_HEADER.bin         |  Bin 0
> >> -> 4096 bytes
> >> > .../Stitch/IFWIHeader/IFWI_HEADER_SPILOCK.bin |  Bin 0
> >> -> 4096 bytes
> >> > .../Stitch/IFWIHeader/Vacant.bin              |  Bin 0
> >> -> 3928064 bytes
> >> > .../Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat   |  270 +
> >> > .../Stitch/MNW2_Stitch_Config.txt             |   10 +
> >> > .../Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c |   33 +
> >> > .../Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf   |   32 +
> >> > .../VlvPlatformInitDxe/IgdOpRegion.c          |  929
> >> ++++
> >> > .../VlvPlatformInitDxe/IgdOpRegion.h          |  235 +
> >> > .../VlvPlatformInitDxe/VlvPlatformInit.c      |  287 ++
> >> > .../VlvPlatformInitDxe/VlvPlatformInit.h      |   65 +
> >> > .../VlvPlatformInitDxe/VlvPlatformInitDxe.inf |   74 +
> >> > .../Vlv2TbltDevicePkg/Wpce791/LpcDriver.c     |  340 ++
> >> > .../Vlv2TbltDevicePkg/Wpce791/LpcDriver.h     |  112 +
> >> > .../Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c    |  366 ++
> >> > .../Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h    |  103 +
> >> > .../Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c  |  126 +
> >> > .../Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h  |  101 +
> >> > .../Vlv2TbltDevicePkg/Wpce791/Wpce791.inf     |   63 +
> >> > Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat  |  332 ++
> >> > Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh   |  256 +
> >> > Platform/Intel/Vlv2TbltDevicePkg/cln.sh       |   62 +
> >> > Readme.md                                     |    9 +
> >> > .../Include/DdrMemoryController.h             |  251 +
> >> > .../QuarkNorthCluster/Include/IntelQNCBase.h  |   17 +
> >> > .../Include/IntelQNCConfig.h                  |  100 +
> >> > .../QuarkNorthCluster/Include/IntelQNCDxe.h   |   17 +
> >> > .../QuarkNorthCluster/Include/IntelQNCPeim.h  |   17 +
> >> > .../QuarkNorthCluster/Include/IntelQNCRegs.h  |   48 +
> >> > .../Include/Library/IntelQNCLib.h             |  284 ++
> >> > .../Include/Library/QNCAccessLib.h            |  161 +
> >> > .../Include/Library/QNCSmmLib.h               |   57 +
> >> > .../Include/Ppi/QNCMemoryInit.h               |   36 +
> >> > .../Include/Protocol/PchInfo.h                |   48 +
> >> > .../Include/Protocol/PlatformPolicy.h         |   31 +
> >> > .../Include/Protocol/QncS3Support.h           |   84 +
> >> > .../Include/Protocol/SmmIchnDispatch2.h       |  115 +
> >> > .../QuarkNorthCluster/Include/Protocol/Spi.h  |  345 ++
> >> > .../QuarkNorthCluster/Include/QNCAccess.h     |  177 +
> >> > .../Include/QNCCommonDefinitions.h            |  350 ++
> >> > .../QuarkNorthCluster/Include/QuarkNcSocId.h  |  751
> >> +++
> >> > .../Library/IntelQNCLib/CommonHeader.h        |   32 +
> >> > .../Library/IntelQNCLib/IntelQNCLib.c         |  771
> >> +++
> >> > .../Library/IntelQNCLib/IntelQNCLib.inf       |   57 +
> >> > .../Library/IntelQNCLib/PciExpress.c          |  932
> >> ++++
> >> > .../Library/MtrrLib/MtrrLib.c                 | 2112
> >> ++++++++
> >> > .../Library/MtrrLib/MtrrLib.inf               |   42 +
> >> > .../Library/MtrrLib/MtrrLib.uni               |   18 +
> >> > .../Library/QNCAccessLib/BaseAccess.c         |   28 +
> >> > .../Library/QNCAccessLib/QNCAccessLib.c       |  327 ++
> >> > .../Library/QNCAccessLib/QNCAccessLib.inf     |   37 +
> >> > .../Library/QNCAccessLib/RuntimeAccess.c      |  142 +
> >> > .../QNCAccessLib/RuntimeQNCAccessLib.inf      |   43 +
> >> > .../Library/QNCSmmLib/QNCSmmLib.c             |  313 ++
> >> > .../Library/QNCSmmLib/QNCSmmLib.inf           |   44 +
> >> > .../Library/ResetSystemLib/ResetSystemLib.c   |  379 ++
> >> > .../Library/ResetSystemLib/ResetSystemLib.inf |   46 +
> >> > .../Library/SmbusLib/CommonHeader.h           |   25 +
> >> > .../Library/SmbusLib/SmbusLib.c               |  797
> >> +++
> >> > .../Library/SmbusLib/SmbusLib.inf             |   47 +
> >> > .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.c     |  446 ++
> >> > .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf   |   30 +
> >> > .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.uni   |   12 +
> >> > .../MemoryInit/Pei/MemoryInit.c               |   59 +
> >> > .../MemoryInit/Pei/MemoryInit.h               |   35 +
> >> > .../MemoryInit/Pei/MemoryInitPei.inf          |   70 +
> >> > .../MemoryInit/Pei/core_types.h               |   43 +
> >> > .../MemoryInit/Pei/gen5_iosf_sb_definitions.h |  738
> >> +++
> >> > .../MemoryInit/Pei/general_definitions.h      |   84 +
> >> > .../QuarkNorthCluster/MemoryInit/Pei/hte.c    |  536 ++
> >> > .../QuarkNorthCluster/MemoryInit/Pei/hte.h    |   66 +
> >> > .../QuarkNorthCluster/MemoryInit/Pei/io.h     |  132 +
> >> > .../QuarkNorthCluster/MemoryInit/Pei/lprint.c |  382 ++
> >> > .../MemoryInit/Pei/meminit.c                  | 2638
> >> ++++++++++
> >> > .../MemoryInit/Pei/meminit.h                  |   22 +
> >> > .../MemoryInit/Pei/meminit_utils.c            | 1574
> >> ++++++
> >> > .../MemoryInit/Pei/meminit_utils.h            |   95 +
> >> > .../MemoryInit/Pei/memory_options.h           |   77 +
> >> > .../QuarkNorthCluster/MemoryInit/Pei/mrc.c    |   40 +
> >> > .../QuarkNorthCluster/MemoryInit/Pei/mrc.h    |  160 +
> >> > .../MemoryInit/Pei/platform.c                 |  186 +
> >> > .../MemoryInit/Pei/prememinit.c               |  187 +
> >> > .../MemoryInit/Pei/prememinit.h               |   15 +
> >> > .../QNCInit/Dxe/CommonHeader.h                |   49 +
> >> > .../QNCInit/Dxe/DxeQNCSmbus.c                 |  612
> >> +++
> >> > .../QNCInit/Dxe/DxeQNCSmbus.h                 |  205 +
> >> > .../QNCInit/Dxe/LegacyRegion.c                |  237 +
> >> > .../QNCInit/Dxe/LegacyRegion.h                |  198 +
> >> > .../QuarkNorthCluster/QNCInit/Dxe/QNCInit.c   |  518 ++
> >> > .../QuarkNorthCluster/QNCInit/Dxe/QNCInit.h   |   49 +
> >> > .../QNCInit/Dxe/QNCInitDxe.inf                |   92 +
> >> > .../QNCInit/Dxe/QNCRootPorts.c                |   76 +
> >> > .../QuarkNorthCluster/QNCInit/Dxe/QNCSmbus.h  |   80 +
> >> > .../QNCInit/Dxe/QNCSmbusExec.c                |  246 +
> >> > .../S3Support/Dxe/QncS3Support.c              |  417 ++
> >> > .../S3Support/Dxe/QncS3Support.h              |  117 +
> >> > .../S3Support/Dxe/QncS3Support.inf            |   64 +
> >> > .../Smm/Dxe/SmmAccessDxe/SmmAccess.inf        |   49 +
> >> > .../Smm/Dxe/SmmAccessDxe/SmmAccessDriver.c    |  405 ++
> >> > .../Smm/Dxe/SmmAccessDxe/SmmAccessDriver.h    |  230 +
> >> > .../Smm/Dxe/SmmControlDxe/SmmControlDriver.c  |  358 ++
> >> > .../Smm/Dxe/SmmControlDxe/SmmControlDxe.inf   |   55 +
> >> > .../DxeSmm/QncSmmDispatcher/CommonHeader.h    |   45 +
> >> > .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmGpi.c   |   32 +
> >> > .../QncSmmDispatcher/QNC/QNCSmmHelpers.c      |  549 ++
> >> > .../QNC/QNCSmmPeriodicTimer.c                 |  424 ++
> >> > .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmQncn.c  |  211 +
> >> > .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmSw.c    |   90 +
> >> > .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmSx.c    |  147 +
> >> > .../Smm/DxeSmm/QncSmmDispatcher/QNCSmm.h      |  868
> >> ++++
> >> > .../Smm/DxeSmm/QncSmmDispatcher/QNCSmmCore.c  |  825
> >> +++
> >> > .../QncSmmDispatcher/QNCSmmDispatcher.inf     |   81 +
> >> > .../DxeSmm/QncSmmDispatcher/QNCSmmHelpers.c   |  367 ++
> >> > .../DxeSmm/QncSmmDispatcher/QNCSmmHelpers.h   |  219 +
> >> > .../DxeSmm/QncSmmDispatcher/QNCSmmRegisters.h |   13 +
> >> > .../DxeSmm/QncSmmDispatcher/QNCxSmmHelpers.h  |  178 +
> >> > .../Smm/Pei/SmmAccessPei/SmmAccessPei.c       |  376 ++
> >> > .../Smm/Pei/SmmAccessPei/SmmAccessPei.inf     |   45 +
> >> > .../Smm/Pei/SmmControlPei/SmmControlPei.c     |  274 +
> >> > .../Smm/Pei/SmmControlPei/SmmControlPei.inf   |   51 +
> >> > .../QuarkNorthCluster/Spi/Common/SpiCommon.c  |  927
> >> ++++
> >> > .../QuarkNorthCluster/Spi/Common/SpiCommon.h  |  317 ++
> >> > .../QuarkNorthCluster/Spi/PchSpiRuntime.inf   |   84 +
> >> > .../QuarkNorthCluster/Spi/PchSpiSmm.inf       |   50 +
> >> > .../QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.c |  205 +
> >> > .../QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.h |   79 +
> >> > .../QuarkNorthCluster/Spi/Smm/PchSpi.c        |  123 +
> >> > .../QuarkNorthCluster/Spi/Smm/PchSpi.h        |   47 +
> >> > Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dec     |  234 +
> >> > Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dsc     |  254 +
> >> > .../QuarkSouthCluster/Include/CEATA.h         |  114 +
> >> > .../QuarkSouthCluster/Include/I2cRegs.h       |   95 +
> >> > .../QuarkSouthCluster/Include/Ioh.h           |  248 +
> >> > .../QuarkSouthCluster/Include/IohAccess.h     |   18 +
> >> > .../Include/IohCommonDefinitions.h            |  342 ++
> >> > .../Include/Library/I2cLib.h                  |  152 +
> >> > .../Include/Library/IohLib.h                  |   36 +
> >> > .../QuarkSouthCluster/Include/MMC.h           |  274 +
> >> > .../QuarkSouthCluster/Include/SDCard.h        |  146 +
> >> > .../QuarkSouthCluster/Include/SDHostIo.h      |  333 ++
> >> > .../IohInit/Dxe/CommonHeader.h                |   55 +
> >> > .../QuarkSouthCluster/IohInit/Dxe/IohBds.h    |   83 +
> >> > .../QuarkSouthCluster/IohInit/Dxe/IohData.c   |   42 +
> >> > .../QuarkSouthCluster/IohInit/Dxe/IohInit.c   |   37 +
> >> > .../IohInit/Dxe/IohInitDxe.inf                |   76 +
> >> > .../Library/I2cLib/CommonHeader.h             |  214 +
> >> > .../QuarkSouthCluster/Library/I2cLib/I2cLib.c |  998
> >> ++++
> >> > .../Library/I2cLib/I2cLib.inf                 |   62 +
> >> > .../Library/IohLib/CommonHeader.h             |   29 +
> >> > .../QuarkSouthCluster/Library/IohLib/IohLib.c |   99 +
> >> > .../Library/IohLib/IohLib.inf                 |   49 +
> >> > .../Sdio/Dxe/SDControllerDxe/ComponentName.c  |  227 +
> >> > .../Sdio/Dxe/SDControllerDxe/ComponentName.h  |  141 +
> >> > .../Sdio/Dxe/SDControllerDxe/SDController.c   | 1784
> >> +++++++
> >> > .../Sdio/Dxe/SDControllerDxe/SDController.h   |  316 ++
> >> > .../Dxe/SDControllerDxe/SDControllerDxe.inf   |   56 +
> >> > .../Sdio/Dxe/SDMediaDeviceDxe/CEATA.c         |  647
> >> +++
> >> > .../Sdio/Dxe/SDMediaDeviceDxe/CEATABlockIo.c  |  389 ++
> >> > .../Sdio/Dxe/SDMediaDeviceDxe/ComponentName.c |  215 +
> >> > .../Sdio/Dxe/SDMediaDeviceDxe/ComponentName.h |  139 +
> >> > .../Sdio/Dxe/SDMediaDeviceDxe/MMCSDBlockIo.c  |  538 ++
> >> > .../Sdio/Dxe/SDMediaDeviceDxe/MMCSDTransfer.c | 1708
> >> +++++++
> >> > .../Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.c |  317 ++
> >> > .../Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.h |  462 ++
> >> > .../Dxe/SDMediaDeviceDxe/SDMediaDeviceDxe.inf |   60 +
> >> > .../QuarkSouthCluster/Usb/Common/Pei/UsbPei.c |  320 ++
> >> > .../QuarkSouthCluster/Usb/Common/Pei/UsbPei.h |   38 +
> >> > .../Usb/Common/Pei/UsbPei.inf                 |   53 +
> >> > .../Usb/Ohci/Dxe/ComponentName.c              |  219 +
> >> > .../Usb/Ohci/Dxe/ComponentName.h              |  141 +
> >> > .../Usb/Ohci/Dxe/Descriptor.h                 |  132 +
> >> > .../QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.c     | 2473
> >> +++++++++
> >> > .../QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.h     |  663
> >> +++
> >> > .../Usb/Ohci/Dxe/OhciDebug.c                  |   78 +
> >> > .../Usb/Ohci/Dxe/OhciDebug.h                  |   42 +
> >> > .../Usb/Ohci/Dxe/OhciDxe.inf                  |   71 +
> >> > .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.c  | 1390
> >> +++++
> >> > .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.h  |  920
> >> ++++
> >> > .../Usb/Ohci/Dxe/OhciSched.c                  |  528 ++
> >> > .../Usb/Ohci/Dxe/OhciSched.h                  |  225 +
> >> > .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.c  |  889
> >> ++++
> >> > .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.h  |  387 ++
> >> > .../QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.c |  560 ++
> >> > .../QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.h |  152 +
> >> > .../Usb/Ohci/Pei/Descriptor.h                 |  131 +
> >> > .../QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.c  | 1386
> >> +++++
> >> > .../QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.h  |  252 +
> >> > .../Usb/Ohci/Pei/OhciPei.inf                  |   56 +
> >> > .../QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.c  | 1386
> >> +++++
> >> > .../QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.h  |  875
> >> ++++
> >> > .../Usb/Ohci/Pei/OhciSched.c                  |  223 +
> >> > .../Usb/Ohci/Pei/OhciSched.h                  |  108 +
> >> > .../QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.c  |  560 ++
> >> > .../QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.h  |  231 +
> >> > .../QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.c |  491 ++
> >> > .../QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.h |  134 +
> >> > .../AcpiTablesPCAT/98_LINK.ASL                |  617
> >> +++
> >> > .../AcpiTablesPCAT/AcpiTablePlatform.h        |   70 +
> >> > .../AcpiTablesPCAT/AcpiTables.inf             |   40 +
> >> > .../AcpiTablesPCAT/CPU.asl                    |   49 +
> >> > .../AcpiTablesPCAT/DSDT.ASL                   |   75 +
> >> > .../AcpiTablesPCAT/Facp/Facp.aslc             |  188 +
> >> > .../AcpiTablesPCAT/Facs/Facs.aslc             |   84 +
> >> > .../AcpiTablesPCAT/GloblNvs.asl               |  348 ++
> >> > .../AcpiTablesPCAT/Gpe.asl                    |   99 +
> >> > .../AcpiTablesPCAT/HOST_BUS.ASL               |  347 ++
> >> > .../AcpiTablesPCAT/Hpet/Hpet.aslc             |   63 +
> >> > .../AcpiTablesPCAT/INTELGFX.ASL               |  879
> >> ++++
> >> > .../AcpiTablesPCAT/INTELISPDev2.ASL           |   71 +
> >> > .../AcpiTablesPCAT/IgdOGBDA.ASL               |  155 +
> >> > .../AcpiTablesPCAT/IgdOMOBF.ASL               |  485 ++
> >> > .../AcpiTablesPCAT/IgdOSBCB.ASL               |  274 +
> >> > .../AcpiTablesPCAT/IgdOpRn.ASL                |  299 ++
> >> > .../AcpiTablesPCAT/IoTVirtualDevice.asl       |  171 +
> >> > .../AcpiTablesPCAT/LPC_DEV.ASL                |  151 +
> >> > .../AcpiTablesPCAT/LpcB.asl                   |   59 +
> >> > .../AcpiTablesPCAT/Lpit/Lpit.aslc             |  223 +
> >> > .../AcpiTablesPCAT/Madt/Madt.h                |  189 +
> >> > .../AcpiTablesPCAT/Madt/Madt30.aslc           |  178 +
> >> > .../AcpiTablesPCAT/Mcfg/Mcfg.aslc             |   86 +
> >> > .../AcpiTablesPCAT/PCI_DRC.ASL                |   90 +
> >> > .../AcpiTablesPCAT/Pch.asl                    |  686
> >> +++
> >> > .../AcpiTablesPCAT/PchAudio.asl               |   36 +
> >> > .../AcpiTablesPCAT/PchEhci.asl                |  269 +
> >> > .../AcpiTablesPCAT/PchLpss.asl                | 1093
> >> ++++
> >> > .../AcpiTablesPCAT/PchPcie.asl                |   50 +
> >> > .../AcpiTablesPCAT/PchScc.asl                 |  610
> >> +++
> >> > .../AcpiTablesPCAT/PchSmb.asl                 |  833
> >> +++
> >> > .../AcpiTablesPCAT/PchXhci.asl                |  379 ++
> >> > .../AcpiTablesPCAT/PciTree.asl                |  377 ++
> >> > .../AcpiTablesPCAT/Platform.asl               |  703
> >> +++
> >> > .../AcpiTablesPCAT/RTD3.asl                   |  197 +
> >> > .../AcpiTablesPCAT/RhProxy.asl                |  160 +
> >> > .../AcpiTablesPCAT/THERMAL.ASL                |  137 +
> >> > .../AcpiTablesPCAT/UsbSbd.asl                 |   93 +
> >> > .../AcpiTablesPCAT/Video.asl                  |   34 +
> >> > .../AcpiTablesPCAT/Vlv.asl                    |   39 +
> >> > .../AcpiTablesPCAT/Wsmt/Wsmt.aslc             |   54 +
> >> > .../AcpiTablesPCAT/token.asl                  |   39 +
> >> > .../Guid/Vlv2DeviceRefCodePkgTokenSpace.h     |   24 +
> >> > .../Include/Ppi/PttPassThruPpi.h              |   92 +
> >> > .../Include/Ppi/fTPMPolicy.h                  |   26 +
> >> > .../Include/Protocol/PttPassThru.h            |   91 +
> >> > .../Guid/PowerManagementAcpiTableStorage.h    |   27 +
> >> > .../CPU/Include/Ppi/VlvPolicy.h               |  104 +
> >> > .../CPU/Include/Protocol/PpmPlatformPolicy.h  |  132 +
> >> > .../ValleyView2Soc/CPU/Include/Types.h        |   55 +
> >> > .../AcpiTables/PowerManagementAcpiTables.inf  |   39 +
> >> > .../PowerManagement/AcpiTables/Ssdt/ApCst.asl |  110 +
> >> > .../PowerManagement/AcpiTables/Ssdt/ApIst.asl |  166 +
> >> > .../PowerManagement/AcpiTables/Ssdt/ApTst.asl |  262 +
> >> > .../AcpiTables/Ssdt/Cpu0Cst.asl               |  274 +
> >> > .../AcpiTables/Ssdt/Cpu0Ist.asl               |  260 +
> >> > .../AcpiTables/Ssdt/Cpu0Tst.asl               |  235 +
> >> > .../PowerManagement/AcpiTables/Ssdt/CpuPm.asl |  793
> >> +++
> >> > .../Include/PlatformBaseAddresses.h           |   92 +
> >> > .../NorthCluster/Include/Ppi/Capsule.h        |   60 +
> >> > .../Include/Ppi/PlatformMemoryRange.h         |  144 +
> >> > .../Include/Ppi/PlatformMemorySize.h          |   46 +
> >> > .../NorthCluster/Include/Ppi/SmmAccess.h      |  165 +
> >> > .../NorthCluster/Include/Ppi/VlvMmioPolicy.h  |   39 +
> >> > .../NorthCluster/Include/Ppi/VlvPeiInit.h     |   35 +
> >> > .../NorthCluster/Include/Ppi/VlvPolicy.h      |  106 +
> >> > .../Include/Protocol/IgdOpRegion.h            |  213 +
> >> > .../NorthCluster/Include/Protocol/MemInfo.h   |   83 +
> >> > .../Include/Protocol/PlatformGopPolicy.h      |   67 +
> >> > .../Include/Protocol/VlvPlatformPolicy.h      |  105 +
> >> > .../NorthCluster/Include/Valleyview.h         |   55 +
> >> > .../NorthCluster/Include/VlvAccess.h          |  254 +
> >> > .../Include/VlvCommonDefinitions.h            |  252 +
> >> > .../SouthCluster/Include/Guid/PchInitVar.h    |   48 +
> >> > .../Include/Guid/SataControllerGuid.h         |   34 +
> >> > .../SouthCluster/Include/Guid/SmbusArpMap.h   |   30 +
> >> > .../SouthCluster/Include/Guid/Vlv2Variable.h  |   28 +
> >> > .../Include/IndustryStandard/CeAta.h          |  126 +
> >> > .../Include/IndustryStandard/Mmc.h            |  349 ++
> >> > .../Include/IndustryStandard/SdCard.h         |  157 +
> >> > .../SouthCluster/Include/Library/I2CLib.h     |  169 +
> >> > .../Include/Library/PchPlatformLib.h          |  115 +
> >> > .../SouthCluster/Include/PchAccess.h          |  471 ++
> >> > .../Include/PchCommonDefinitions.h            |  210 +
> >> > .../SouthCluster/Include/PchRegs.h            |  205 +
> >> > .../SouthCluster/Include/PchRegs/PchRegsHda.h |   50 +
> >> > .../Include/PchRegs/PchRegsLpss.h             |  486 ++
> >> > .../Include/PchRegs/PchRegsPcie.h             |   83 +
> >> > .../SouthCluster/Include/PchRegs/PchRegsPcu.h | 1201
> >> +++++
> >> > .../Include/PchRegs/PchRegsRcrb.h             |   48 +
> >> > .../Include/PchRegs/PchRegsSata.h             |  245 +
> >> > .../SouthCluster/Include/PchRegs/PchRegsScc.h |   53 +
> >> > .../Include/PchRegs/PchRegsSmbus.h            |  149 +
> >> > .../SouthCluster/Include/PchRegs/PchRegsSpi.h |  119 +
> >> > .../SouthCluster/Include/PchRegs/PchRegsUsb.h |   92 +
> >> > .../SouthCluster/Include/Ppi/PchInit.h        |   75 +
> >> > .../SouthCluster/Include/Ppi/PchPeiInit.h     |   34 +
> >> > .../Include/Ppi/PchPlatformPolicy.h           |  161 +
> >> > .../SouthCluster/Include/Ppi/PchUsbPolicy.h   |   69 +
> >> > .../SouthCluster/Include/Ppi/PeiBlockIo.h     |  230 +
> >> > .../SouthCluster/Include/Ppi/Sdhc.h           |  359 ++
> >> > .../SouthCluster/Include/Ppi/SmbusPolicy.h    |   40 +
> >> > .../SouthCluster/Include/Ppi/Spi.h            |   42 +
> >> > .../Include/Protocol/ActiveBios.h             |  123 +
> >> > .../Include/Protocol/ActiveBiosProtocol.h     |  125 +
> >> > .../Protocol/DxePchPolicyUpdateProtocol.h     |   51 +
> >> > .../Include/Protocol/EmmcCardInfoProtocol.h   |   42 +
> >> > .../SouthCluster/Include/Protocol/Gpio.h      |  161 +
> >> > .../Include/Protocol/HwWatchdogTimer.h        |  294 ++
> >> > .../SouthCluster/Include/Protocol/I2cBus.h    |  164 +
> >> > .../Include/Protocol/PchExtendedReset.h       |   84 +
> >> > .../SouthCluster/Include/Protocol/PchInfo.h   |   60 +
> >> > .../Include/Protocol/PchPlatformPolicy.h      |  550 ++
> >> > .../SouthCluster/Include/Protocol/PchReset.h  |  114 +
> >> > .../Include/Protocol/PchS3Support.h           |  132 +
> >> > .../SouthCluster/Include/Protocol/SdHostIo.h  |  409 ++
> >> > .../Include/Protocol/SmbiosSlotPopulation.h   |   47 +
> >> > .../Include/Protocol/SmmIchnDispatchEx.h      |  159 +
> >> > .../SouthCluster/Include/Protocol/SmmSmbus.h  |   39 +
> >> > .../SouthCluster/Include/Protocol/Spi.h       |  260 +
> >> > .../SouthCluster/Include/Protocol/TcoReset.h  |   88 +
> >> > .../SouthCluster/Include/Rsci.h               |   28 +
> >> > .../SouthCluster/Include/TianoApi.h           |   61 +
> >> > .../Vlv2DeviceRefCodePkg.dec                  |  231 +
> >> > .../Omap35xxPkg/Flash/Flash.c                 |  768
> >> +++
> >> > .../Omap35xxPkg/Flash/Flash.h                 |  100 +
> >> > .../Omap35xxPkg/Flash/Flash.inf               |   42 +
> >> > .../TexasInsturments/Omap35xxPkg/Gpio/Gpio.c  |  129 +
> >> > .../Omap35xxPkg/Gpio/Gpio.inf                 |   39 +
> >> > .../Omap35xxPkg/Include/Library/OmapDmaLib.h  |   84 +
> >> > .../Omap35xxPkg/Include/Library/OmapLib.h     |   38 +
> >> > .../Omap35xxPkg/Include/Omap3530/Omap3530.h   |   34 +
> >> > .../Include/Omap3530/Omap3530Dma.h            |  124 +
> >> > .../Include/Omap3530/Omap3530Gpio.h           |  125 +
> >> > .../Include/Omap3530/Omap3530Gpmc.h           |  101 +
> >> > .../Include/Omap3530/Omap3530I2c.h            |   56 +
> >> > .../Include/Omap3530/Omap3530Interrupt.h      |   45 +
> >> > .../Include/Omap3530/Omap3530MMCHS.h          |  208 +
> >> > .../Omap3530/Omap3530PadConfiguration.h       |  297 ++
> >> > .../Include/Omap3530/Omap3530Prcm.h           |  159 +
> >> > .../Include/Omap3530/Omap3530Timer.h          |   76 +
> >> > .../Include/Omap3530/Omap3530Uart.h           |   48 +
> >> > .../Include/Omap3530/Omap3530Usb.h            |   42 +
> >> > .../Omap35xxPkg/Include/TPS65950.h            |   74 +
> >> > .../InterruptDxe/HardwareInterrupt.c          |  396 ++
> >> > .../Omap35xxPkg/InterruptDxe/InterruptDxe.inf |   48 +
> >> > .../LcdGraphicsOutputBlt.c                    |  439 ++
> >> > .../LcdGraphicsOutputDxe.c                    |  394 ++
> >> > .../LcdGraphicsOutputDxe.h                    |  151 +
> >> > .../LcdGraphicsOutputDxe.inf                  |   46 +
> >> > .../DebugAgentTimerLib/DebugAgentTimerLib.c   |  159 +
> >> > .../DebugAgentTimerLib/DebugAgentTimerLib.inf |   42 +
> >> > .../Library/GdbSerialLib/GdbSerialLib.c       |   96 +
> >> > .../Library/GdbSerialLib/GdbSerialLib.inf     |   35 +
> >> > .../Omap35xxTimerLib/Omap35xxTimerLib.inf     |   40 +
> >> > .../Library/Omap35xxTimerLib/TimerLib.c       |  151 +
> >> > .../Library/OmapDmaLib/OmapDmaLib.c           |  170 +
> >> > .../Library/OmapDmaLib/OmapDmaLib.inf         |   43 +
> >> > .../Omap35xxPkg/Library/OmapLib/OmapLib.c     |   77 +
> >> > .../Omap35xxPkg/Library/OmapLib/OmapLib.inf   |   31 +
> >> > .../RealTimeClockLib/RealTimeClockLib.c       |  291 ++
> >> > .../RealTimeClockLib/RealTimeClockLib.inf     |   32 +
> >> > .../Library/SerialPortLib/SerialPortLib.c     |  208 +
> >> > .../Library/SerialPortLib/SerialPortLib.inf   |   40 +
> >> > .../Omap35xxPkg/MMCHSDxe/MMCHS.c              | 1492
> >> ++++++
> >> > .../Omap35xxPkg/MMCHSDxe/MMCHS.h              |  169 +
> >> > .../Omap35xxPkg/MMCHSDxe/MMCHS.inf            |   48 +
> >> > .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.c       |  671
> >> +++
> >> > .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.h       |   38 +
> >> > .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf     |   47 +
> >> > .../Omap35xxPkg/Omap35xxPkg.dec               |   52 +
> >> > .../Omap35xxPkg/Omap35xxPkg.dsc               |  183 +
> >> > .../Omap35xxPkg/PciEmulation/PciEmulation.c   |  107 +
> >> > .../Omap35xxPkg/PciEmulation/PciEmulation.inf |   41 +
> >> > .../Omap35xxPkg/SmbusDxe/Smbus.c              |  319 ++
> >> > .../Omap35xxPkg/SmbusDxe/Smbus.inf            |   39 +
> >> > .../Omap35xxPkg/TPS65950Dxe/TPS65950.c        |  110 +
> >> > .../Omap35xxPkg/TPS65950Dxe/TPS65950.inf      |   42 +
> >> > .../Omap35xxPkg/TimerDxe/Timer.c              |  370 ++
> >> > .../Omap35xxPkg/TimerDxe/TimerDxe.inf         |   51 +
> >> > 1103 files changed, 259532 insertions(+)
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/Application/BltLibSample/BltLibSamp
> >> le.c
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/Application/BltLibSample/BltLibSamp
> >> le.inf
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.c
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.h
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThruDxe.i
> >> nf
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/AtapiPassThruDxe/ComponentName.c
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/AtapiPassThruDxe/DriverSupportedEfi
> >> Version.c
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/Compatible
> >> Devices.txt
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ComponentN
> >> ame.c
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSer
> >> ialDriver.c
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSer
> >> ialDriver.h
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSer
> >> ialDxe.inf
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax887
> >> 72.c
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax887
> >> 72.h
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax887
> >> 72.inf
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Compo
> >> nentName
> >> >.c
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Drive
> >> rBinding.c
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Simpl
> >> eNetwork.c
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88
> >> 772.c
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88
> >> 772.h
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88
> >> 772b.inf
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Comp
> >> onentNam
> >> >e.c
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Driv
> >> erBinding.c
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Simp
> >> leNetwork.
> >> >c
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.
> >> c
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.
> >> h
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430D
> >> xe.inf
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430G
> >> raphicsOutput.c
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I
> >> 2c.c
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I
> >> 2c.h
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430U
> >> gaDraw.c
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/ComponentName.c
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/CirrusLogic5430Dxe/DriverSupportedE
> >> fiVersion.c
> >> > create mode 100644
> >> Drivers/OptionRomPkg/CirrusLogic5430Dxe/Edid.c
> >> > create mode 100644
> >> Drivers/OptionRomPkg/Include/Library/BltLib.h
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBuff
> >> erBltLib.c
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBuff
> >> erBltLib.inf
> >> > create mode 100644
> >> Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.c
> >> > create mode 100644
> >> Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.inf
> >> > create mode 100644
> >> Drivers/OptionRomPkg/OptionRomPkg.dec
> >> > create mode 100644
> >> Drivers/OptionRomPkg/OptionRomPkg.dsc
> >> > create mode 100644 Drivers/OptionRomPkg/ReadMe.txt
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/UndiRuntimeDxe/ComponentName.c
> >> > create mode 100644
> >> Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c
> >> > create mode 100644
> >> Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c
> >> > create mode 100644
> >> Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h
> >> > create mode 100644
> >> Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c
> >> > create mode 100644
> >> Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h
> >> > create mode 100644
> >> Drivers/OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c
> >> > create mode 100644
> >> >Drivers/OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.dec
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.dsc
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.fdf
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/ConfigurationHeader.
> >> bin
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/ConfigurationHeader.
> >> dat
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi
> >> _boot_from_ra
> >> >m.inc
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi
> >> _convert_symb
> >> >ols.sh
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi
> >> _dummy.axf
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi
> >> _hw_setup.inc
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi
> >> _load_symbols.i
> >> >nc
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi
> >> _symbols_macr
> >> >os.inc
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi
> >> _unload_symbo
> >> >ls.inc
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/tra
> >> ce32_load_sym
> >> >bols.cmm
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/tra
> >> ce32_load_sym
> >> >bols_cygwin.cmm
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Include/BeagleBoard.
> >> h
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardL
> >> ib/BeagleBoard.
> >> >c
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardL
> >> ib/BeagleBoard
> >> >Helper.S
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardL
> >> ib/BeagleBoard
> >> >Helper.asm
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardL
> >> ib/BeagleBoard
> >> >Lib.inf
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardL
> >> ib/BeagleBoard
> >> >Mem.c
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardL
> >> ib/Clock.c
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardL
> >> ib/PadConfigura
> >> >tion.c
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Library/DxeHobPeCoff
> >> Lib/DxeHobPe
> >> >Coff.c
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Library/DxeHobPeCoff
> >> Lib/DxeHobPe
> >> >CoffLib.inf
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Library/LzmaHobCusto
> >> mDecompress
> >> >Lib/LzmaHobCustomDecompressLib.c
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Library/LzmaHobCusto
> >> mDecompress
> >> >Lib/LzmaHobCustomDecompressLib.inf
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Library/MemoryInitPe
> >> iLib/MemoryIn
> >> >itPeiLib.c
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Library/MemoryInitPe
> >> iLib/MemoryIn
> >> >itPeiLib.inf
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Library/ResetSystemL
> >> ib/ResetSyste
> >> >mLib.c
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Library/ResetSystemL
> >> ib/ResetSyste
> >> >mLib.inf
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ArchPrePi.
> >> c
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ModuleEntr
> >> yPoint.S
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ModuleEntr
> >> yPoint.asm
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/PrePi/LzmaDecompress
> >> .h
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/PrePi/MainUniCore.c
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/PrePi/PeiUniCore.inf
> >> > create mode 100644
> >> Platform/BeagleBoard/BeagleBoardPkg/PrePi/PrePi.c
> >> > create mode 100644
> >> Platform/BeagleBoard/BeagleBoardPkg/PrePi/PrePi.h
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Tools/GNUmakefile
> >> > create mode 100644
> >> >Platform/BeagleBoard/BeagleBoardPkg/Tools/generate_image
> >> .c
> >> > create mode 100644
> >> Platform/BeagleBoard/BeagleBoardPkg/Tools/makefile
> >> > create mode 100644
> >> Platform/BeagleBoard/BeagleBoardPkg/Tools/replace.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/AcpiTabl
> >> es.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Cst/
> >> Cpu0Cst.asl
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Ist/
> >> Cpu0Ist.asl
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Tst/
> >> Cpu0Tst.asl
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/CpuPm/Cp
> >> uPm.asl
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/AD7
> >> 298.asi
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/ADC
> >> 108S102.asi
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/CAT
> >> 24C08.asi
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/CY8
> >> C9540A.asi
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Gpi
> >> oClient.asi
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Lpc
> >> Dev.asi
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PCA
> >> 9685.asi
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PCA
> >> L9555A.asi
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Pci
> >> HostBridge.asi
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Pci
> >> Irq.asi
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Pci
> >> eExpansionPrt.asi
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Pla
> >> tform.asl
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNC
> >> .asi
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNC
> >> Apic.asi
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNC
> >> Lpc.asi
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Qua
> >> rkSouthCluster.a
> >> >si
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Tpm
> >> .asi
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Facs/Fac
> >> s.aslc
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Facs/Fac
> >> s.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fad
> >> t.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fad
> >> t1.0.aslc
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fad
> >> t2.0.aslc
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Hpet/Hpe
> >> t.aslc
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Hpet/Hpe
> >> t.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Mcfg/Mcf
> >> g.aslc
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Mcfg/Mcf
> >> g.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Ac
> >> piPciUpdate.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Ac
> >> piPciUpdate.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Ac
> >> piPlatform.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Ac
> >> piPlatform.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Ac
> >> piPlatform.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Ma
> >> dt.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Ma
> >> dtPlatform.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecu
> >> torDxe/BootScri
> >> >ptExecutorDxe.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecu
> >> torDxe/IA32/S3A
> >> >sm.S
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecu
> >> torDxe/IA32/S3A
> >> >sm.asm
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecu
> >> torDxe/IA32/Set
> >> >IdtEntry.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecu
> >> torDxe/ScriptExe
> >> >cute.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecu
> >> torDxe/ScriptExe
> >> >cute.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/Acpi
> >> SmmPlatfor
> >> >m.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/Acpi
> >> SmmPlatfor
> >> >m.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/Acpi
> >> SmmPlatfor
> >> >m.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerMana
> >> gement/P
> >> >pm.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerMana
> >> gement/P
> >> >pm.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerMana
> >> gement/S
> >> >mmPowerManagement.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerMana
> >> gement/S
> >> >mmPowerManagement.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerMana
> >> gement/S
> >> >mmPowerManagement.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Application/ForceRecover
> >> y/ForceRecovery
> >> >.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Application/ForceRecover
> >> y/ForceRecovery
> >> >.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/
> >> PlatformFlashAcc
> >> >essLib/PlatformFlashAccessLibDxe.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/
> >> PlatformFlashAcc
> >> >essLib/PlatformFlashAccessLibDxe.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/
> >> PlatformFlashAcc
> >> >essLib/SpiFlashDevice.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/
> >> PlatformFlashAcc
> >> >essLib/SpiFlashDevice.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFi
> >> rmwareDescript
> >> >or/SystemFirmwareDescriptor.aslc
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFi
> >> rmwareDescript
> >> >or/SystemFirmwareDescriptor.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFi
> >> rmwareDescript
> >> >or/SystemFirmwareDescriptorPei.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFi
> >> rmwareUpdateC
> >> >onfig/SystemFirmwareUpdateConfig.ini
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnDa
> >> taCD.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFa
> >> tFloppyDisk.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFa
> >> tIdeDisk.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFa
> >> tUsbDisk.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Include/Guid/MemoryConfi
> >> gData.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Include/Guid/QuarkCapsul
> >> eGuid.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Include/Guid/QuarkVariab
> >> leLock.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Include/Guid/SystemNvDat
> >> aHobGuid.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Include/Library/Platform
> >> HelperLib.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Include/Library/Platform
> >> PcieHelperLib.h
> >> > create mode 100644
> >> Platform/Intel/QuarkPlatformPkg/Include/Pcal9555.h
> >> > create mode 100644
> >> Platform/Intel/QuarkPlatformPkg/Include/Platform.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Include/PlatformBoards.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Include/Protocol/GlobalN
> >> vsArea.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Include/Protocol/Platfor
> >> mSmmSpiReady.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/PlatformBootMana
> >> gerLib/Platform
> >> >BootManager.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/PlatformBootMana
> >> gerLib/Platform
> >> >BootManager.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/PlatformBootMana
> >> gerLib/Platform
> >> >BootManagerLib.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/PlatformBootMana
> >> gerLib/Platform
> >> >Data.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLi
> >> b/CommonHeader
> >> >.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLi
> >> b/DxePlatformHel
> >> >perLib.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLi
> >> b/PeiPlatformHelp
> >> >erLib.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLi
> >> b/PlatformHelper
> >> >Dxe.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLi
> >> b/PlatformHelperL
> >> >ib.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLi
> >> b/PlatformHelper
> >> >Pei.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLi
> >> b/PlatformLeds.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelp
> >> erLib/CommonHe
> >> >ader.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelp
> >> erLib/PlatformPci
> >> >eHelperLib.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelp
> >> erLib/PlatformPci
> >> >eHelperLib.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelp
> >> erLib/SocUnit.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/I
> >> a32/Flat32.S
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/I
> >> a32/Flat32.asm
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/I
> >> a32/Platform.inc
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/P
> >> latformSecLib.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/P
> >> latformSecLib.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/P
> >> latformSecLibMod
> >> >Strs.uni
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecureLi
> >> b/PlatformSecure
> >> >Lib.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/PlatformSecureLi
> >> b/PlatformSecure
> >> >Lib.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAt
> >> melI2c/TisPc.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAt
> >> melI2c/Tpm12De
> >> >viceLibAtmelI2c.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAt
> >> melI2c/Tpm12De
> >> >viceLibAtmelI2c.uni
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibIn
> >> fineonI2c/TisPc.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibIn
> >> fineonI2c/Tpm12
> >> >DeviceLibInfineonI2c.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibIn
> >> fineonI2c/Tpm12
> >> >DeviceLibInfineonI2c.uni
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/Pc
> >> iHostBridge.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/Pc
> >> iHostBridge.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/Pc
> >> iHostBridge.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/Pc
> >> iHostBridgeSupp
> >> >ort.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/Pc
> >> iHostResource.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/Pc
> >> iRootBridge.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/Pc
> >> iRootBridgeIo.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/Comm
> >> onHeader.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciP
> >> latform.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciP
> >> latform.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciP
> >> latform.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubCl
> >> ass/MemoryS
> >> >ubClass.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubCl
> >> ass/MemoryS
> >> >ubClass.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubCl
> >> ass/MemoryS
> >> >ubClass.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubCl
> >> ass/MemoryS
> >> >ubClassStrings.uni
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformIni
> >> t/PlatformConfig.
> >> >c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformIni
> >> t/PlatformInitDxe
> >> >.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformIni
> >> t/PlatformInitDxe
> >> >.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformIni
> >> t/PlatformInitDxe
> >> >.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SaveMemoryC
> >> onfig/SaveM
> >> >emoryConfig.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SaveMemoryC
> >> onfig/SaveM
> >> >emoryConfig.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/Commo
> >> nHeader.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/DxePl
> >> atform.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/Keybo
> >> ardLayout.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/QNCRe
> >> gTable.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/Setup
> >> Platform.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/Setup
> >> Platform.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/Strin
> >> gs.uni
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/proce
> >> ssor.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/CommonHe
> >> >ader.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscBaseBo
> >> >ardManufacturer.uni
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscBaseBo
> >> >ardManufacturerData.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscBaseBo
> >> >ardManufacturerFunction.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscBiosVe
> >> >ndor.uni
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscBiosVe
> >> >ndorData.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscBiosVe
> >> >ndorFunction.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscBootInf
> >> >ormationData.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscBootInf
> >> >ormationFunction.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscChassis
> >> >Manufacturer.uni
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscChassis
> >> >ManufacturerData.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscChassis
> >> >ManufacturerFunction.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscDevice
> >> >Path.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscNumbe
> >> >rOfInstallableLanguagesData.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscNumbe
> >> >rOfInstallableLanguagesFunction.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscOemSt
> >> >ring.uni
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscOemSt
> >> >ringData.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscOemSt
> >> >ringFunction.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscOnboar
> >> >dDevice.uni
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscOnboar
> >> >dDeviceData.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscOnboar
> >> >dDeviceFunction.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscPortInt
> >> >ernalConnectorDesignator.uni
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscPortInt
> >> >ernalConnectorDesignatorData.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscPortInt
> >> >ernalConnectorDesignatorFunction.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscSystem
> >> >Manufacturer.uni
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscSystem
> >> >ManufacturerData.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscSystem
> >> >ManufacturerFunction.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscSystem
> >> >OptionString.uni
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscSystem
> >> >OptionStringData.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscSystem
> >> >OptionStringFunction.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscSystem
> >> >SlotDesignation.uni
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscSystem
> >> >SlotDesignationData.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscSystem
> >> >SlotDesignationFunction.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/MiscSystem
> >> >SlotOnboardDevices.uni
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/SmbiosMisc
> >> >.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/SmbiosMisc
> >> >DataTable.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/SmbiosMisc
> >> >Dxe.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/SmbiosMisc
> >> >EntryPoint.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscD
> >> xe/SmbiosMisc
> >> >Strings.uni
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformCon
> >> fig/PlatformConf
> >> >igPei.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformCon
> >> fig/PlatformConf
> >> >igPei.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> >> t/BootMode.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> >> t/CommonHeader
> >> >.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> >> t/Generic/Recove
> >> >ry.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> >> t/MemoryCallback
> >> >.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> >> t/MrcWrapper.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> >> t/MrcWrapper.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> >> t/PeiFvSecurity.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> >> t/PeiFvSecurity.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> >> t/PlatformEarlyInit
> >> >.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> >> t/PlatformEarlyInit
> >> >.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> >> t/PlatformEarlyInit
> >> >.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformIni
> >> t/PlatformErratas.
> >> >c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
> >> FvbInfo.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
> >> FwBlockService.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
> >> FwBlockService.h
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
> >> PlatformSmmSpi.
> >> >c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
> >> PlatformSmmSpi.i
> >> >nf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
> >> PlatformSpi.inf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
> >> SpiFlashDevice.c
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/
> >> SpiFlashDevice.h
> >> > create mode 100644
> >> Platform/Intel/QuarkPlatformPkg/Quark.dsc
> >> > create mode 100644
> >> Platform/Intel/QuarkPlatformPkg/Quark.fdf
> >> > create mode 100644
> >> Platform/Intel/QuarkPlatformPkg/QuarkMin.dsc
> >> > create mode 100644
> >> Platform/Intel/QuarkPlatformPkg/QuarkMin.fdf
> >> > create mode 100644
> >> >Platform/Intel/QuarkPlatformPkg/QuarkPlatformPkg.dec
> >> > create mode 100644
> >> Platform/Intel/QuarkPlatformPkg/Readme.md
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/.gitignore
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatfo
> >> rm.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatfo
> >> rm.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatfo
> >> rm.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatfo
> >> rmHooks.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatfo
> >> rmHooks.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatfo
> >> rmHooksLib.h
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpd
> >> ate/FirmwareUp
> >> >date.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpd
> >> ate/FirmwareUp
> >> >date.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpd
> >> ate/FirmwareUp
> >> >date.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpd
> >> ate/FirmwareUp
> >> >dateStrings.uni
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64D.env
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64R.env
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/BootS
> >> criptSaveDxe.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/Inter
> >> nalBootScriptSave
> >> >.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/Scrip
> >> tSave.c
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.bat
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.sh
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/FCE.exe
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> >> eCapsule/GenCa
> >> >psuleAll.bat
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> >> eCapsule/GenCa
> >> >psuleAll.sh
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> >> eCapsule/GenCa
> >> >psuleMinnowMax.bat
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> >> eCapsule/GenCa
> >> >psuleMinnowMax.sh
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> >> eCapsule/GenCa
> >> >psuleMinnowMaxRelease.bat
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> >> eCapsule/GenCa
> >> >psuleMinnowMaxRelease.sh
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> >> eCapsule/GenCa
> >> >psuleSampleColor.bat
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> >> eCapsule/GenCa
> >> >psuleSampleColor.sh
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> >> eCapsule/Lvfs.dd
> >> >f
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> >> eCapsule/LvfsGe
> >> >nCapsuleMinnowMax.bat
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> >> eCapsule/LvfsGe
> >> >nCapsuleMinnowMaxRelease.bat
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> >> eCapsule/LvfsGe
> >> >nCapsuleSampleColor.bat
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> >> eCapsule/NewR
> >> >oot.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7Cer
> >> tBufferXdr.i
> >> >nc
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> >> eCapsule/SAMPL
> >> >E_DEVELOPMENT.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevi
> >> cePkcs7C
> >> >ertBufferXdr.inc
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> >> eCapsule/SAMPL
> >> >E_DEVELOPMENT_SAMPLE_PRODUCTION.cer.gFmpDevicePkgTokenSp
> >> aceGu
> >> >id.PcdFmpDevicePkcs7CertBufferXdr.inc
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Generat
> >> eCapsule/templa
> >> >te.metainfo.xml
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library
> >> /FmpDeviceLib/Fm
> >> >pDeviceLib.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library
> >> /FmpDeviceLib/Fm
> >> >pDeviceLib.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library
> >> /FmpDeviceLibSa
> >> >mple/FmpDeviceLib.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library
> >> /FmpDeviceLibSa
> >> >mple/FmpDeviceLib.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library
> >> /PlatformFlashAcc
> >> >essLib/PlatformFlashAccessLib.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library
> >> /PlatformFlashAcc
> >> >essLib/PlatformFlashAccessLib.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemF
> >> irmwareDescript
> >> >or/SystemFirmwareDescriptor.aslc
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemF
> >> irmwareDescript
> >> >or/SystemFirmwareDescriptor.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemF
> >> irmwareDescript
> >> >or/SystemFirmwareDescriptorPei.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemF
> >> irmwareUpdateC
> >> >onfig/SystemFirmwareUpdateConfig.ini
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemF
> >> irmwareUpdateC
> >> >onfig/SystemFirmwareUpdateConfigGcc.ini
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/FmpCertificate.dsc
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FmpGreenSampleDevice.ds
> >> c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FspAzaliaConfigData/Aza
> >> liaConfig.bin
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/
> >> BootModePei.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/
> >> BootModePei.i
> >> >nf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiF
> >> spHobProcessLibVl
> >> >v2/FspHobProcessLibVlv2.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiF
> >> spHobProcessLibVl
> >> >v2/FspHobProcessLibVlv2.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> >> spPlatformSecLibV
> >> >lv2/FspPlatformSecLibVlv2.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> >> spPlatformSecLibV
> >> >lv2/FspPlatformSecLibVlv2.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> >> spPlatformSecLibV
> >> >lv2/Ia32/AsmSaveSecContext.asm
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> >> spPlatformSecLibV
> >> >lv2/Ia32/Fsp.inc
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> >> spPlatformSecLibV
> >> >lv2/Ia32/PeiCoreEntry.asm
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> >> spPlatformSecLibV
> >> >lv2/Ia32/SecEntry.asm
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> >> spPlatformSecLibV
> >> >lv2/Ia32/Stack.S
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> >> spPlatformSecLibV
> >> >lv2/Ia32/Stack.asm
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> >> spPlatformSecLibV
> >> >lv2/PlatformInit.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> >> spPlatformSecLibV
> >> >lv2/SaveSecContext.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> >> spPlatformSecLibV
> >> >lv2/SecGetPerformance.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> >> spPlatformSecLibV
> >> >lv2/SecPlatformInformation.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> >> spPlatformSecLibV
> >> >lv2/SecRamInitData.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> >> spPlatformSecLibV
> >> >lv2/SecTempRamSupport.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecF
> >> spPlatformSecLibV
> >> >lv2/UartInit.c
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbRuntim
> >> eDxe.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServic
> >> e.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServic
> >> e.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServic
> >> eDxe.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServic
> >> eSmm.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmm.in
> >> f
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmCom
> >> mon.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe
> >> .c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe
> >> .h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe
> >> .inf
> >> > create mode 100755
> >> Platform/Intel/Vlv2TbltDevicePkg/GenBiosId
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/GenBiosId.exe
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/AlertStandardFo
> >> rmatTable.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/ChipsetAccess.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/CommonIncludes.
> >> h
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/Include/CpuType.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/FileHandleLib.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AcpiTableS
> >> torage.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AlertStand
> >> ardFormat.h
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BiosId.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BoardFeatu
> >> res.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/EfiVpdData
> >> .h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/FirmwareId
> >> .h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/HwWatchdog
> >> TimerHob.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/IdccData.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/ItkData.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/MemoryConf
> >> igData.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/OsSelectio
> >> n.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PciLanInfo
> >> .h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformCp
> >> uInfo.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformIn
> >> fo.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SensorInfo
> >> Variable.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SetupVaria
> >> ble.h
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/Include/Hpet.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/BiosIdL
> >> ib.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/CpuIA32
> >> .h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/EfiRegT
> >> ableLib.h
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Esrt.h
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Fd.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/FlashDe
> >> viceLib.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2CLib.
> >> h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cMmio
> >> ConfigLib.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cPort
> >> _platform.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Platfor
> >> mFsaLib.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Platfor
> >> mFspLib.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/SpiFlas
> >> h.H
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/StallSm
> >> mLib.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Library/UsbDevi
> >> ceModeLib.h
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/Include/Mcfg.h
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/Include/McfgTable.h
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/Include/Platform.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformBootMod
> >> e.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformDefinit
> >> ions.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/MfgMemoryTe
> >> st.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Sha256Hash.
> >> h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Speaker.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/UsbControll
> >> er.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/CK505C
> >> lockPlatformInfo.
> >> >h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Enhanc
> >> edSpeedstep.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Global
> >> NvsArea.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/HwWatc
> >> hdogTimer.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cAcp
> >> i.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBus
> >> .h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBus
> >> Mcg.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cHos
> >> tMcg.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cMas
> >> terMcg.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cSla
> >> ve.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpc
> >> 83627Policy.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpc
> >> e791Policy.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/MmioDe
> >> vice.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Observ
> >> able.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Platfo
> >> rmGopPolicy.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Platfo
> >> rmIdeInit.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SetupM
> >> ode.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Smbios
> >> SlotPopulation.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Speake
> >> r.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TcoRes
> >> et.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TpmMp.
> >> h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/UsbPol
> >> icy.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/VlvPla
> >> tformPolicy.h
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/Include/SetupMode.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/IntelGopDepex/IntelGopD
> >> river.depex
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosI
> >> dLib.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosI
> >> dLib.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/CpuI
> >> A32Lib.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/EfiC
> >> puVersion.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32
> >> /CpuIA32.S
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32
> >> /CpuIA32.asm
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32
> >> /CpuIA32.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/
> >> Cpu.S
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/
> >> Cpu.asm
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/
> >> EfiRegTableLib.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/
> >> EfiRegTableLib.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/
> >> FlashDeviceLib.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/
> >> FlashDeviceLib.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/
> >> FlashDeviceLibDxe.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/
> >> FlashDeviceLibDxe.i
> >> >nf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/
> >> FlashDeviceLibDxeR
> >> >untimeSmm.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/
> >> SpiChipDefinitions.h
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLibNu
> >> ll.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLi
> >> b.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLi
> >> bDxe.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CRe
> >> gs.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CAc
> >> cess.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDe
> >> layPei.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDe
> >> layPei.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIo
> >> LibPei.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIo
> >> LibPei.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLi
> >> bPei.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLi
> >> bPei.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLi
> >> bPei.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTim
> >> erLib/CommonHea
> >> >der.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTim
> >> erLib/IntelPchAcpiT
> >> >imerLib.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTim
> >> erLib/IntelPchAcpiT
> >> >imerLib.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> >> b/BoardClkGens/Bo
> >> >ardClkGens.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> >> b/BoardClkGens/Bo
> >> >ardClkGens.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> >> b/BoardGpios/Boar
> >> >dGpios.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> >> b/BoardGpios/Boar
> >> >dGpios.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> >> b/BoardJumpers/Bo
> >> >ardJumpers.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> >> b/BoardJumpers/Bo
> >> >ardJumpers.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> >> b/BoardOemIds/Bo
> >> >ardOemIds.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> >> b/BoardOemIds/Bo
> >> >ardOemIds.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> >> b/BoardSsidSvid/Bo
> >> >ardSsidSvid.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> >> b/BoardSsidSvid/Bo
> >> >ardSsidSvid.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> >> b/MultiPlatformLib.
> >> >c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> >> b/MultiPlatformLib.
> >> >h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> >> b/MultiPlatformLib.i
> >> >nf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLi
> >> b/PlatformInfoHob.
> >> >c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/
> >> PchPlatformLib.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/
> >> PchPlatformLibrary.
> >> >c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/
> >> PchPlatformLibrary.
> >> >h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/Commo
> >> nHeader.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSm
> >> mLib.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSm
> >> mLib.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/
> >> BdsPlatform.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/
> >> BdsPlatform.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/
> >> PlatformBdsLib.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/
> >> PlatformBdsStrings.
> >> >uni
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/
> >> PlatformData.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib
> >> /PlatformCmosLib.
> >> >c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib
> >> /PlatformCmosLib.
> >> >inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/
> >> PlatformFspLib.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/
> >> PlatformFspLib.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/
> >> ResetSystemLib.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/
> >> ResetSystemLib.in
> >> >f
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/P
> >> latformSerialPortLib.
> >> >h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/S
> >> erialPortLib.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/S
> >> erialPortLib.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/S
> >> ioInit.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/S
> >> ioInit.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/Common
> >> Header.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusL
> >> ib.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusL
> >> ib.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/Sta
> >> llSmm.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/Sta
> >> llSmmLib.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSe
> >> CDxe/Tpm2Devic
> >> >eLibSeC.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSe
> >> CDxe/Tpm2Devic
> >> >eLibSeC.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSe
> >> CPei/Tpm2Device
> >> >LibSeC.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSe
> >> CPei/Tpm2Device
> >> >LibSeC.inf
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/Logo/Logo.bmp
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetrono
> >> me.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetrono
> >> me.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Metronome/Metronome.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/EfiStatu
> >> sCode.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStat
> >> usCode.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStat
> >> usCode.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStat
> >> usCode.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PeiPostC
> >> ode.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/Platform
> >> StatusCode.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/Platform
> >> StatusCode.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
> >> ModulePkg/Libra
> >> >ry/GenericBdsLib/BdsBoot.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
> >> ModulePkg/Libra
> >> >ry/GenericBdsLib/BdsConnect.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
> >> ModulePkg/Libra
> >> >ry/GenericBdsLib/BdsConsole.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
> >> ModulePkg/Libra
> >> >ry/GenericBdsLib/BdsMisc.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
> >> ModulePkg/Libra
> >> >ry/GenericBdsLib/DevicePath.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
> >> ModulePkg/Libra
> >> >ry/GenericBdsLib/GenericBdsLib.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
> >> ModulePkg/Libra
> >> >ry/GenericBdsLib/GenericBdsLib.uni
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
> >> ModulePkg/Libra
> >> >ry/GenericBdsLib/GenericBdsStrings.uni
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
> >> ModulePkg/Libra
> >> >ry/GenericBdsLib/InternalBdsLib.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
> >> ModulePkg/Libra
> >> >ry/GenericBdsLib/String.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFramework
> >> ModulePkg/Libra
> >> >ry/GenericBdsLib/String.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/BoardPciPla
> >> tform.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform
> >> .c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform
> >> .h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform
> >> .inf
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.dsc
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.fdf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/Plat
> >> formCpuInfoDxe.
> >> >c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/Plat
> >> formCpuInfoDxe.
> >> >h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/Plat
> >> formCpuInfoDxe.i
> >> >nf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/AzaliaVerbT
> >> able.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardId.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDeco
> >> de.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDeco
> >> de.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ClockContro
> >> l.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Configurati
> >> on.h
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchPlatform
> >> Policy.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchRegTable
> >> .c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchTcoReset
> >> .c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeak
> >> er.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeak
> >> er.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/
> >> Observable.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/
> >> Observable.h
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciBus.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Platform.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe
> >> .h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe
> >> .inf
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SioPlatform
> >> Policy.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.
> >> c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.
> >> h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/Platf
> >> ormGopPolicy.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/Platf
> >> ormGopPolicy.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/Platfor
> >> mInfoDxe.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/Platfor
> >> mInfoDxe.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/Platfor
> >> mInfoDxe.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/BootMod
> >> e.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/CpuInit
> >> Peim.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/FlashMa
> >> p.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacyS
> >> peaker.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacyS
> >> peaker.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MchInit
> >> .c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryC
> >> allback.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryP
> >> eim.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PchInit
> >> Peim.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Platfor
> >> mEarlyInit.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Platfor
> >> mEarlyInit.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Platfor
> >> mInfoInit.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Platfor
> >> mInitPei.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Platfor
> >> mSsaInitPeim.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Recover
> >> y.c
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Stall.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/BootMode.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/CommonHeade
> >> r.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/MemoryCallb
> >> ack.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/PlatformPei
> >> .inf
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Stall.c
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.dec
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgConfig.dsc
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGcc.fdf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgIA32.dsc
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgX64.dsc
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Boot.v
> >> fi
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Config
> >> uration.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/DebugC
> >> onfig.vfi
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/FwVers
> >> ionStrings.uni
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Main.v
> >> fi
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Platfo
> >> rmSetupDxe.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Platfo
> >> rmSetupDxe.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Platfo
> >> rmSetupDxe.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Securi
> >> ty.vfi
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupF
> >> unctions.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupI
> >> nfoRecords.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SouthC
> >> lusterConfig.vfi
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/System
> >> Component.vfi
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Therma
> >> l.vfi
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UnCore
> >> .vfi
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UqiLis
> >> t.uni
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Vfr.vf
> >> r
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/VfrStr
> >> ings.uni
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/Platform.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/PlatformSmm
> >> .inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/S3Save.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmPlatform
> >> .h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSa
> >> ve.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSa
> >> ve.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/Readme.md
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMe
> >> moryConfig.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMe
> >> moryConfig.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMe
> >> moryConfig.in
> >> >f
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/CommonHea
> >> der.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseB
> >> oardManufactu
> >> >rer.uni
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseB
> >> oardManufactu
> >> >rerData.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseB
> >> oardManufactu
> >> >rerFunction.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosV
> >> endor.uni
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosV
> >> endorData.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosV
> >> endorFunction.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootI
> >> nformationData.
> >> >c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootI
> >> nformationFunc
> >> >tion.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChass
> >> isManufacturer.
> >> >uni
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChass
> >> isManufacturer
> >> >Data.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChass
> >> isManufacturer
> >> >Function.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemor
> >> yDevice.uni
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemor
> >> yDeviceData.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemor
> >> yDeviceFuncti
> >> >on.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumbe
> >> rOfInstallableL
> >> >anguagesData.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumbe
> >> rOfInstallableL
> >> >anguagesFunction.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemSt
> >> ring.uni
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemSt
> >> ringData.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemSt
> >> ringFunction.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemTy
> >> pe0x90.uni
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemTy
> >> pe0x90Data.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemTy
> >> pe0x90Functio
> >> >n.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemTy
> >> pe0x94.uni
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemTy
> >> pe0x94Data.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemTy
> >> pe0x94Functio
> >> >n.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboa
> >> rdDevice.uni
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboa
> >> rdDeviceData.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboa
> >> rdDeviceFuncti
> >> >on.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysi
> >> calArray.uni
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysi
> >> calArrayData.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysi
> >> calArrayFunction
> >> >.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortI
> >> nternalConnecto
> >> >rDesignator.uni
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortI
> >> nternalConnecto
> >> >rDesignatorData.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortI
> >> nternalConnecto
> >> >rDesignatorFunction.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProce
> >> ssorCache.uni
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProce
> >> ssorCacheData.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProce
> >> ssorCacheFuncti
> >> >on.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProce
> >> ssorInformation
> >> >.uni
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProce
> >> ssorInformation
> >> >Data.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProce
> >> ssorInformation
> >> >Function.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscReset
> >> CapabilitiesData
> >> >.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscReset
> >> CapabilitiesFunc
> >> >tion.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubcl
> >> assDriver.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubcl
> >> assDriver.uni
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubcl
> >> assDriverDataTa
> >> >ble.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubcl
> >> assDriverEntryP
> >> >oint.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> >> mLanguageStrin
> >> >g.uni
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> >> mLanguageStrin
> >> >gData.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> >> mLanguageStrin
> >> >gFunction.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> >> mManufacturer.
> >> >uni
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> >> mManufacturer
> >> >Data.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> >> mManufacturer
> >> >Function.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> >> mOptionString.u
> >> >ni
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> >> mOptionStringD
> >> >ata.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> >> mOptionStringF
> >> >unction.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> >> mSlotDesignatio
> >> >n.uni
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> >> mSlotDesignatio
> >> >nData.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSyste
> >> mSlotDesignatio
> >> >nFunction.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/SmBiosMis
> >> cDxe.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDi
> >> spatchThunk
> >> >/SmmSwDispatch2OnSmmSwDispatchThunk.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDi
> >> spatchThunk
> >> >/SmmSwDispatch2OnSmmSwDispatchThunk.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm
> >> /SmramSaveI
> >> >nfoHandlerSmm.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm
> >> /SmramSaveI
> >> >nfoHandlerSmm.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtw
> >> Spare.bin
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtw
> >> Working.bin
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageVar
> >> iable.bin
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_
> >> HEADER.bin
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_
> >> HEADER_SPILOCK
> >> >.bin
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/Vacan
> >> t.bin
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Stitch/MNW2_Stitch_Conf
> >> ig.txt
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdO
> >> pRegion.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdO
> >> pRegion.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvP
> >> latformInit.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvP
> >> latformInit.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvP
> >> latformInitDxe.inf
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.c
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.h
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h
> >> > create mode 100644
> >> >Platform/Intel/Vlv2TbltDevicePkg/Wpce791/Wpce791.inf
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh
> >> > create mode 100644
> >> Platform/Intel/Vlv2TbltDevicePkg/cln.sh
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/DdrM
> >> emoryController
> >> >.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Inte
> >> lQNCBase.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Inte
> >> lQNCConfig.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Inte
> >> lQNCDxe.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Inte
> >> lQNCPeim.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Inte
> >> lQNCRegs.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Libr
> >> ary/IntelQNCLib.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Libr
> >> ary/QNCAccessLib.
> >> >h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Libr
> >> ary/QNCSmmLib.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Ppi/
> >> QNCMemoryInit.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Prot
> >> ocol/PchInfo.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Prot
> >> ocol/PlatformPolic
> >> >y.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Prot
> >> ocol/QncS3Suppor
> >> >t.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Prot
> >> ocol/SmmIchnDis
> >> >patch2.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Prot
> >> ocol/Spi.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QNCA
> >> ccess.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QNCC
> >> ommonDefinitio
> >> >ns.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Quar
> >> kNcSocId.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Inte
> >> lQNCLib/Common
> >> >Header.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Inte
> >> lQNCLib/IntelQNCL
> >> >ib.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Inte
> >> lQNCLib/IntelQNCL
> >> >ib.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Inte
> >> lQNCLib/PciExpress
> >> >.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Mtrr
> >> Lib/MtrrLib.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Mtrr
> >> Lib/MtrrLib.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Mtrr
> >> Lib/MtrrLib.uni
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCA
> >> ccessLib/BaseAcc
> >> >ess.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCA
> >> ccessLib/QNCAcc
> >> >essLib.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCA
> >> ccessLib/QNCAcc
> >> >essLib.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCA
> >> ccessLib/Runtim
> >> >eAccess.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCA
> >> ccessLib/Runtim
> >> >eQNCAccessLib.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCS
> >> mmLib/QNCSmm
> >> >Lib.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCS
> >> mmLib/QNCSmm
> >> >Lib.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Rese
> >> tSystemLib/Reset
> >> >SystemLib.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Rese
> >> tSystemLib/Reset
> >> >SystemLib.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Smbu
> >> sLib/CommonHe
> >> >ader.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Smbu
> >> sLib/SmbusLib.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/Smbu
> >> sLib/SmbusLib.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmC
> >> puFeaturesLib/S
> >> >mmCpuFeaturesLib.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmC
> >> puFeaturesLib/S
> >> >mmCpuFeaturesLib.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmC
> >> puFeaturesLib/S
> >> >mmCpuFeaturesLib.uni
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> >> ei/MemoryInit.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> >> ei/MemoryInit.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> >> ei/MemoryInitP
> >> >ei.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> >> ei/core_types.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> >> ei/gen5_iosf_sb
> >> >_definitions.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> >> ei/general_defin
> >> >itions.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> >> ei/hte.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> >> ei/hte.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> >> ei/io.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> >> ei/lprint.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> >> ei/meminit.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> >> ei/meminit.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> >> ei/meminit_utils
> >> >.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> >> ei/meminit_utils
> >> >.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> >> ei/memory_opti
> >> >ons.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> >> ei/mrc.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> >> ei/mrc.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> >> ei/platform.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> >> ei/prememinit.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/P
> >> ei/prememinit.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
> >> CommonHeader.
> >> >h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
> >> DxeQNCSmbus.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
> >> DxeQNCSmbus.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
> >> LegacyRegion.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
> >> LegacyRegion.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
> >> QNCInit.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
> >> QNCInit.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
> >> QNCInitDxe.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
> >> QNCRootPorts.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
> >> QNCSmbus.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/
> >> QNCSmbusExec.
> >> >c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dx
> >> e/QncS3Support.
> >> >c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dx
> >> e/QncS3Support.
> >> >h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dx
> >> e/QncS3Support.
> >> >inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmA
> >> ccessDxe/Sm
> >> >mAccess.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmA
> >> ccessDxe/Sm
> >> >mAccessDriver.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmA
> >> ccessDxe/Sm
> >> >mAccessDriver.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmC
> >> ontrolDxe/S
> >> >mmControlDriver.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmC
> >> ontrolDxe/S
> >> >mmControlDxe.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> >> ncSmmDispa
> >> >tcher/CommonHeader.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> >> ncSmmDispa
> >> >tcher/QNC/QNCSmmGpi.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> >> ncSmmDispa
> >> >tcher/QNC/QNCSmmHelpers.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> >> ncSmmDispa
> >> >tcher/QNC/QNCSmmPeriodicTimer.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> >> ncSmmDispa
> >> >tcher/QNC/QNCSmmQncn.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> >> ncSmmDispa
> >> >tcher/QNC/QNCSmmSw.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> >> ncSmmDispa
> >> >tcher/QNC/QNCSmmSx.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> >> ncSmmDispa
> >> >tcher/QNCSmm.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> >> ncSmmDispa
> >> >tcher/QNCSmmCore.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> >> ncSmmDispa
> >> >tcher/QNCSmmDispatcher.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> >> ncSmmDispa
> >> >tcher/QNCSmmHelpers.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> >> ncSmmDispa
> >> >tcher/QNCSmmHelpers.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> >> ncSmmDispa
> >> >tcher/QNCSmmRegisters.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/Q
> >> ncSmmDispa
> >> >tcher/QNCxSmmHelpers.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmA
> >> ccessPei/Smm
> >> >AccessPei.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmA
> >> ccessPei/Smm
> >> >AccessPei.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmC
> >> ontrolPei/Sm
> >> >mControlPei.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmC
> >> ontrolPei/Sm
> >> >mControlPei.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Common/S
> >> piCommon.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Common/S
> >> piCommon.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiRu
> >> ntime.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiSm
> >> m.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeD
> >> xe/PchSpi.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeD
> >> xe/PchSpi.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchS
> >> pi.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchS
> >> pi.h
> >> > create mode 100644
> >> Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dec
> >> > create mode 100644
> >> Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dsc
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/CEAT
> >> A.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/I2cR
> >> egs.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Ioh.
> >> h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/IohA
> >> ccess.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/IohC
> >> ommonDefinition
> >> >s.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Libr
> >> ary/I2cLib.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Libr
> >> ary/IohLib.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/MMC.
> >> h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/SDCa
> >> rd.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/SDHo
> >> stIo.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/
> >> CommonHeader.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/
> >> IohBds.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/
> >> IohData.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/
> >> IohInit.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/
> >> IohInitDxe.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cL
> >> ib/CommonHeader
> >> >.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cL
> >> ib/I2cLib.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cL
> >> ib/I2cLib.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohL
> >> ib/CommonHeade
> >> >r.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohL
> >> ib/IohLib.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohL
> >> ib/IohLib.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDC
> >> ontrollerDxe/Co
> >> >mponentName.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDC
> >> ontrollerDxe/Co
> >> >mponentName.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDC
> >> ontrollerDxe/SD
> >> >Controller.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDC
> >> ontrollerDxe/SD
> >> >Controller.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDC
> >> ontrollerDxe/SD
> >> >ControllerDxe.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
> >> ediaDeviceDxe/
> >> >CEATA.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
> >> ediaDeviceDxe/
> >> >CEATABlockIo.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
> >> ediaDeviceDxe/
> >> >ComponentName.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
> >> ediaDeviceDxe/
> >> >ComponentName.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
> >> ediaDeviceDxe/
> >> >MMCSDBlockIo.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
> >> ediaDeviceDxe/
> >> >MMCSDTransfer.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
> >> ediaDeviceDxe/
> >> >SDMediaDevice.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
> >> ediaDeviceDxe/
> >> >SDMediaDevice.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDM
> >> ediaDeviceDxe/
> >> >SDMediaDeviceDxe.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/P
> >> ei/UsbPei.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/P
> >> ei/UsbPei.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/P
> >> ei/UsbPei.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> >> /ComponentNa
> >> >me.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> >> /ComponentNa
> >> >me.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> >> /Descriptor.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> >> /Ohci.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> >> /Ohci.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> >> /OhciDebug.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> >> /OhciDebug.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> >> /OhciDxe.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> >> /OhciReg.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> >> /OhciReg.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> >> /OhciSched.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> >> /OhciSched.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> >> /OhciUrb.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> >> /OhciUrb.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> >> /UsbHcMem.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe
> >> /UsbHcMem.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> >> /Descriptor.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> >> /OhcPeim.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> >> /OhcPeim.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> >> /OhciPei.inf
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> >> /OhciReg.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> >> /OhciReg.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> >> /OhciSched.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> >> /OhciSched.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> >> /OhciUrb.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> >> /OhciUrb.h
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> >> /UsbHcMem.c
> >> > create mode 100644
> >> >Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei
> >> /UsbHcMem.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/98_LIN
> >> K.ASL
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTa
> >> blePlatform.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTa
> >> bles.inf
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/CPU.as
> >> l
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/DSDT.A
> >> SL
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facp/F
> >> acp.aslc
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facs/F
> >> acs.aslc
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/GloblN
> >> vs.asl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Gpe.as
> >> l
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/HOST_B
> >> US.ASL
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Hpet/H
> >> pet.aslc
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELG
> >> FX.ASL
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELI
> >> SPDev2.ASL
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOGB
> >> DA.ASL
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOMO
> >> BF.ASL
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOSB
> >> CB.ASL
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOpR
> >> n.ASL
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IoTVir
> >> tualDevice.asl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LPC_DE
> >> V.ASL
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LpcB.a
> >> sl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Lpit/L
> >> pit.aslc
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/M
> >> adt.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/M
> >> adt30.aslc
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Mcfg/M
> >> cfg.aslc
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PCI_DR
> >> C.ASL
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Pch.as
> >> l
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchAud
> >> io.asl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchEhc
> >> i.asl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchLps
> >> s.asl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchPci
> >> e.asl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchScc
> >> .asl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchSmb
> >> .asl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchXhc
> >> i.asl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PciTre
> >> e.asl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Platfo
> >> rm.asl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RTD3.a
> >> sl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RhProx
> >> y.asl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/THERMA
> >> L.ASL
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/UsbSbd
> >> .asl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Video.
> >> asl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Vlv.as
> >> l
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Wsmt/W
> >> smt.aslc
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/token.
> >> asl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Guid/Vlv2Devi
> >> ceRefCodePkgTok
> >> >enSpace.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/PttPassTh
> >> ruPpi.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/fTPMPolic
> >> y.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Protocol/PttP
> >> assThru.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/In
> >> clude/Guid/Pow
> >> >erManagementAcpiTableStorage.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/In
> >> clude/Ppi/VlvPol
> >> >icy.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/In
> >> clude/Protocol/P
> >> >pmPlatformPolicy.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/In
> >> clude/Types.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
> >> werManageme
> >> >nt/AcpiTables/PowerManagementAcpiTables.inf
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
> >> werManageme
> >> >nt/AcpiTables/Ssdt/ApCst.asl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
> >> werManageme
> >> >nt/AcpiTables/Ssdt/ApIst.asl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
> >> werManageme
> >> >nt/AcpiTables/Ssdt/ApTst.asl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
> >> werManageme
> >> >nt/AcpiTables/Ssdt/Cpu0Cst.asl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
> >> werManageme
> >> >nt/AcpiTables/Ssdt/Cpu0Ist.asl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
> >> werManageme
> >> >nt/AcpiTables/Ssdt/Cpu0Tst.asl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Po
> >> werManageme
> >> >nt/AcpiTables/Ssdt/CpuPm.asl
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> >> luster/Include/Pl
> >> >atformBaseAddresses.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> >> luster/Include/P
> >> >pi/Capsule.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> >> luster/Include/P
> >> >pi/PlatformMemoryRange.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> >> luster/Include/P
> >> >pi/PlatformMemorySize.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> >> luster/Include/P
> >> >pi/SmmAccess.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> >> luster/Include/P
> >> >pi/VlvMmioPolicy.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> >> luster/Include/P
> >> >pi/VlvPeiInit.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> >> luster/Include/P
> >> >pi/VlvPolicy.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> >> luster/Include/P
> >> >rotocol/IgdOpRegion.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> >> luster/Include/P
> >> >rotocol/MemInfo.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> >> luster/Include/P
> >> >rotocol/PlatformGopPolicy.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> >> luster/Include/P
> >> >rotocol/VlvPlatformPolicy.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> >> luster/Include/V
> >> >alleyview.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> >> luster/Include/Vl
> >> >vAccess.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthC
> >> luster/Include/Vl
> >> >vCommonDefinitions.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/G
> >> >uid/PchInitVar.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/G
> >> >uid/SataControllerGuid.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/G
> >> >uid/SmbusArpMap.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/G
> >> >uid/Vlv2Variable.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/In
> >> >dustryStandard/CeAta.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/In
> >> >dustryStandard/Mmc.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/In
> >> >dustryStandard/SdCard.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/Li
> >> >brary/I2CLib.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/Li
> >> >brary/PchPlatformLib.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >chAccess.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >chCommonDefinitions.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >chRegs.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >chRegs/PchRegsHda.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >chRegs/PchRegsLpss.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >chRegs/PchRegsPcie.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >chRegs/PchRegsPcu.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >chRegs/PchRegsRcrb.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >chRegs/PchRegsSata.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >chRegs/PchRegsScc.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >chRegs/PchRegsSmbus.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >chRegs/PchRegsSpi.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >chRegs/PchRegsUsb.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >pi/PchInit.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >pi/PchPeiInit.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >pi/PchPlatformPolicy.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >pi/PchUsbPolicy.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >pi/PeiBlockIo.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >pi/Sdhc.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >pi/SmbusPolicy.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >pi/Spi.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >rotocol/ActiveBios.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >rotocol/ActiveBiosProtocol.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >rotocol/DxePchPolicyUpdateProtocol.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >rotocol/EmmcCardInfoProtocol.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >rotocol/Gpio.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >rotocol/HwWatchdogTimer.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >rotocol/I2cBus.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >rotocol/PchExtendedReset.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >rotocol/PchInfo.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >rotocol/PchPlatformPolicy.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >rotocol/PchReset.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >rotocol/PchS3Support.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >rotocol/SdHostIo.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >rotocol/SmbiosSlotPopulation.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >rotocol/SmmIchnDispatchEx.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >rotocol/SmmSmbus.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >rotocol/Spi.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/P
> >> >rotocol/TcoReset.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/R
> >> >sci.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthC
> >> luster/Include/Ti
> >> >anoApi.h
> >> > create mode 100644
> >> >Silicon/Intel/Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.
> >> dec
> >> > create mode 100644
> >> Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.c
> >> > create mode 100644
> >> Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.h
> >> > create mode 100644
> >> Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.inf
> >> > create mode 100644
> >> Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.c
> >> > create mode 100644
> >> Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.inf
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Include/Library/Oma
> >> pDmaLib.h
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Include/Library/Oma
> >> pLib.h
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> >> ap3530.h
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> >> ap3530Dma.
> >> >h
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> >> ap3530Gpio.
> >> >h
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> >> ap3530Gpmc
> >> >.h
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> >> ap3530I2c.h
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> >> ap3530Interr
> >> >upt.h
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> >> ap3530MMC
> >> >HS.h
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> >> ap3530PadC
> >> >onfiguration.h
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> >> ap3530Prcm.
> >> >h
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> >> ap3530Timer
> >> >.h
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> >> ap3530Uart.
> >> >h
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Om
> >> ap3530Usb.h
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Include/TPS65950.h
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/Hardwa
> >> reInterrupt.c
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/Interr
> >> uptDxe.inf
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDx
> >> e/LcdGraphics
> >> >OutputBlt.c
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDx
> >> e/LcdGraphics
> >> >OutputDxe.c
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDx
> >> e/LcdGraphics
> >> >OutputDxe.h
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDx
> >> e/LcdGraphics
> >> >OutputDxe.inf
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentT
> >> imerLib/Debug
> >> >AgentTimerLib.c
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentT
> >> imerLib/Debug
> >> >AgentTimerLib.inf
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLi
> >> b/GdbSerialLib.c
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLi
> >> b/GdbSerialLib.in
> >> >f
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTim
> >> erLib/Omap35
> >> >xxTimerLib.inf
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTim
> >> erLib/TimerLib
> >> >.c
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/
> >> OmapDmaLib.
> >> >c
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/
> >> OmapDmaLib.
> >> >inf
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/Oma
> >> pLib.c
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/Oma
> >> pLib.inf
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClo
> >> ckLib/RealTimeC
> >> >lockLib.c
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClo
> >> ckLib/RealTimeC
> >> >lockLib.inf
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortL
> >> ib/SerialPortLib.c
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortL
> >> ib/SerialPortLib.in
> >> >f
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.c
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.h
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.inf
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostD
> >> xe.c
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostD
> >> xe.h
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostD
> >> xe.inf
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dec
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dsc
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmu
> >> lation.c
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmu
> >> lation.inf
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.c
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.inf
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS6595
> >> 0.c
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS6595
> >> 0.inf
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/Timer.c
> >> > create mode 100644
> >> >Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/TimerDxe.i
> >> nf
> >> >
> >> >--
> >> >2.21.0.windows.1
> >> >
> >> >
> >> >


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [edk2-platforms: Patch 1/8] Silicon/TexasInsturments: Import Omap35xxPkg from edk2
  2019-05-10 17:56   ` Leif Lindholm
@ 2019-05-10 19:16     ` Michael D Kinney
  2019-05-10 19:54       ` Leif Lindholm
  0 siblings, 1 reply; 23+ messages in thread
From: Michael D Kinney @ 2019-05-10 19:16 UTC (permalink / raw)
  To: Leif Lindholm, Kinney, Michael D; +Cc: devel@edk2.groups.io, Ard Biesheuvel

Leif,

Thanks.  I will fix the typo.

I did not change any of the .dec or .dsc files with this series.

I tested builds by using PACKAGES_PATH.

Do you approve the change with the typo fixed or do you want 
me to send a V2?

Thanks,

Mike

> -----Original Message-----
> From: Leif Lindholm [mailto:leif.lindholm@linaro.org]
> Sent: Friday, May 10, 2019 10:57 AM
> To: Kinney, Michael D <michael.d.kinney@intel.com>
> Cc: devel@edk2.groups.io; Ard Biesheuvel
> <ard.biesheuvel@linaro.org>
> Subject: Re: [edk2-platforms: Patch 1/8]
> Silicon/TexasInsturments: Import Omap35xxPkg from edk2
> 
> Hi Mike,
> 
> I'm afraid a typo has snuck in below:
> 
> On Thu, May 09, 2019 at 08:34:28PM -0700, Michael D
> Kinney wrote:
> > https://bugzilla.tianocore.org/show_bug.cgi?id=1467
> >
> > Import Omap35xxPkg from edk2/master.
> >
> > 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>
> > ---
> >  .../Omap35xxPkg/Flash/Flash.c                 |  768
> +++++++++
> >  .../Omap35xxPkg/Flash/Flash.h                 |  100
> ++
> >  .../Omap35xxPkg/Flash/Flash.inf               |   42
> +
> >  .../TexasInsturments/Omap35xxPkg/Gpio/Gpio.c  |  129
> ++
> >  .../Omap35xxPkg/Gpio/Gpio.inf                 |   39
> +
> >  .../Omap35xxPkg/Include/Library/OmapDmaLib.h  |   84
> +
> >  .../Omap35xxPkg/Include/Library/OmapLib.h     |   38
> +
> >  .../Omap35xxPkg/Include/Omap3530/Omap3530.h   |   34
> +
> >  .../Include/Omap3530/Omap3530Dma.h            |  124
> ++
> >  .../Include/Omap3530/Omap3530Gpio.h           |  125
> ++
> >  .../Include/Omap3530/Omap3530Gpmc.h           |  101
> ++
> >  .../Include/Omap3530/Omap3530I2c.h            |   56
> +
> >  .../Include/Omap3530/Omap3530Interrupt.h      |   45
> +
> >  .../Include/Omap3530/Omap3530MMCHS.h          |  208
> +++
> >  .../Omap3530/Omap3530PadConfiguration.h       |  297
> ++++
> >  .../Include/Omap3530/Omap3530Prcm.h           |  159
> ++
> >  .../Include/Omap3530/Omap3530Timer.h          |   76
> +
> >  .../Include/Omap3530/Omap3530Uart.h           |   48
> +
> >  .../Include/Omap3530/Omap3530Usb.h            |   42
> +
> >  .../Omap35xxPkg/Include/TPS65950.h            |   74
> +
> >  .../InterruptDxe/HardwareInterrupt.c          |  396
> +++++
> >  .../Omap35xxPkg/InterruptDxe/InterruptDxe.inf |   48
> +
> >  .../LcdGraphicsOutputBlt.c                    |  439
> +++++
> >  .../LcdGraphicsOutputDxe.c                    |  394
> +++++
> >  .../LcdGraphicsOutputDxe.h                    |  151
> ++
> >  .../LcdGraphicsOutputDxe.inf                  |   46
> +
> >  .../DebugAgentTimerLib/DebugAgentTimerLib.c   |  159
> ++
> >  .../DebugAgentTimerLib/DebugAgentTimerLib.inf |   42
> +
> >  .../Library/GdbSerialLib/GdbSerialLib.c       |   96
> ++
> >  .../Library/GdbSerialLib/GdbSerialLib.inf     |   35
> +
> >  .../Omap35xxTimerLib/Omap35xxTimerLib.inf     |   40
> +
> >  .../Library/Omap35xxTimerLib/TimerLib.c       |  151
> ++
> >  .../Library/OmapDmaLib/OmapDmaLib.c           |  170
> ++
> >  .../Library/OmapDmaLib/OmapDmaLib.inf         |   43
> +
> >  .../Omap35xxPkg/Library/OmapLib/OmapLib.c     |   77
> +
> >  .../Omap35xxPkg/Library/OmapLib/OmapLib.inf   |   31
> +
> >  .../RealTimeClockLib/RealTimeClockLib.c       |  291
> ++++
> >  .../RealTimeClockLib/RealTimeClockLib.inf     |   32
> +
> >  .../Library/SerialPortLib/SerialPortLib.c     |  208
> +++
> >  .../Library/SerialPortLib/SerialPortLib.inf   |   40
> +
> >  .../Omap35xxPkg/MMCHSDxe/MMCHS.c              | 1492
> +++++++++++++++++
> >  .../Omap35xxPkg/MMCHSDxe/MMCHS.h              |  169
> ++
> >  .../Omap35xxPkg/MMCHSDxe/MMCHS.inf            |   48
> +
> >  .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.c       |  671
> ++++++++
> >  .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.h       |   38
> +
> >  .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf     |   47
> +
> >  .../Omap35xxPkg/Omap35xxPkg.dec               |   52
> +
> >  .../Omap35xxPkg/Omap35xxPkg.dsc               |  183
> ++
> >  .../Omap35xxPkg/PciEmulation/PciEmulation.c   |  107
> ++
> >  .../Omap35xxPkg/PciEmulation/PciEmulation.inf |   41
> +
> >  .../Omap35xxPkg/SmbusDxe/Smbus.c              |  319
> ++++
> >  .../Omap35xxPkg/SmbusDxe/Smbus.inf            |   39
> +
> >  .../Omap35xxPkg/TPS65950Dxe/TPS65950.c        |  110
> ++
> >  .../Omap35xxPkg/TPS65950Dxe/TPS65950.inf      |   42
> +
> >  .../Omap35xxPkg/TimerDxe/Timer.c              |  370
> ++++
> >  .../Omap35xxPkg/TimerDxe/TimerDxe.inf         |   51
> +
> >  56 files changed, 9257 insertions(+)
> >  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.c
> 
> TexasInsturments ->
> TexasInstruments
> 
> Also, using the sortorder and --stat/--stat-graph-width
> from Laszlo's
> guide when generating patches would be helpful here even
> though the
> code is just moving. It makes the above more clear, and
> puts the .dec
> and .dsc (which have actually changed) first.
> 
> Beyond that, I intend to change both this and
> BeagleBoardPkg to use
> full pathnames relative to edk2-platforms root after the
> migration,
> but we don't need to do that for the migration.
> 
> Best Regards,
> 
> Leif

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [edk2-platforms: Patch 1/8] Silicon/TexasInsturments: Import Omap35xxPkg from edk2
  2019-05-10 19:16     ` Michael D Kinney
@ 2019-05-10 19:54       ` Leif Lindholm
  0 siblings, 0 replies; 23+ messages in thread
From: Leif Lindholm @ 2019-05-10 19:54 UTC (permalink / raw)
  To: Kinney, Michael D; +Cc: devel@edk2.groups.io, Ard Biesheuvel

Hi Mike,

If you explicitly didn't change any of the files, then I'm totally
happy with the typo fixed. For Omap35xxPkg and BeagleBoardPkg:
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>

Regards,

Leif

On Fri, May 10, 2019 at 07:16:47PM +0000, Kinney, Michael D wrote:
> Leif,
> 
> Thanks.  I will fix the typo.
> 
> I did not change any of the .dec or .dsc files with this series.
> 
> I tested builds by using PACKAGES_PATH.
> 
> Do you approve the change with the typo fixed or do you want 
> me to send a V2?
> 
> Thanks,
> 
> Mike
> 
> > -----Original Message-----
> > From: Leif Lindholm [mailto:leif.lindholm@linaro.org]
> > Sent: Friday, May 10, 2019 10:57 AM
> > To: Kinney, Michael D <michael.d.kinney@intel.com>
> > Cc: devel@edk2.groups.io; Ard Biesheuvel
> > <ard.biesheuvel@linaro.org>
> > Subject: Re: [edk2-platforms: Patch 1/8]
> > Silicon/TexasInsturments: Import Omap35xxPkg from edk2
> > 
> > Hi Mike,
> > 
> > I'm afraid a typo has snuck in below:
> > 
> > On Thu, May 09, 2019 at 08:34:28PM -0700, Michael D
> > Kinney wrote:
> > > https://bugzilla.tianocore.org/show_bug.cgi?id=1467
> > >
> > > Import Omap35xxPkg from edk2/master.
> > >
> > > 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>
> > > ---
> > >  .../Omap35xxPkg/Flash/Flash.c                 |  768
> > +++++++++
> > >  .../Omap35xxPkg/Flash/Flash.h                 |  100
> > ++
> > >  .../Omap35xxPkg/Flash/Flash.inf               |   42
> > +
> > >  .../TexasInsturments/Omap35xxPkg/Gpio/Gpio.c  |  129
> > ++
> > >  .../Omap35xxPkg/Gpio/Gpio.inf                 |   39
> > +
> > >  .../Omap35xxPkg/Include/Library/OmapDmaLib.h  |   84
> > +
> > >  .../Omap35xxPkg/Include/Library/OmapLib.h     |   38
> > +
> > >  .../Omap35xxPkg/Include/Omap3530/Omap3530.h   |   34
> > +
> > >  .../Include/Omap3530/Omap3530Dma.h            |  124
> > ++
> > >  .../Include/Omap3530/Omap3530Gpio.h           |  125
> > ++
> > >  .../Include/Omap3530/Omap3530Gpmc.h           |  101
> > ++
> > >  .../Include/Omap3530/Omap3530I2c.h            |   56
> > +
> > >  .../Include/Omap3530/Omap3530Interrupt.h      |   45
> > +
> > >  .../Include/Omap3530/Omap3530MMCHS.h          |  208
> > +++
> > >  .../Omap3530/Omap3530PadConfiguration.h       |  297
> > ++++
> > >  .../Include/Omap3530/Omap3530Prcm.h           |  159
> > ++
> > >  .../Include/Omap3530/Omap3530Timer.h          |   76
> > +
> > >  .../Include/Omap3530/Omap3530Uart.h           |   48
> > +
> > >  .../Include/Omap3530/Omap3530Usb.h            |   42
> > +
> > >  .../Omap35xxPkg/Include/TPS65950.h            |   74
> > +
> > >  .../InterruptDxe/HardwareInterrupt.c          |  396
> > +++++
> > >  .../Omap35xxPkg/InterruptDxe/InterruptDxe.inf |   48
> > +
> > >  .../LcdGraphicsOutputBlt.c                    |  439
> > +++++
> > >  .../LcdGraphicsOutputDxe.c                    |  394
> > +++++
> > >  .../LcdGraphicsOutputDxe.h                    |  151
> > ++
> > >  .../LcdGraphicsOutputDxe.inf                  |   46
> > +
> > >  .../DebugAgentTimerLib/DebugAgentTimerLib.c   |  159
> > ++
> > >  .../DebugAgentTimerLib/DebugAgentTimerLib.inf |   42
> > +
> > >  .../Library/GdbSerialLib/GdbSerialLib.c       |   96
> > ++
> > >  .../Library/GdbSerialLib/GdbSerialLib.inf     |   35
> > +
> > >  .../Omap35xxTimerLib/Omap35xxTimerLib.inf     |   40
> > +
> > >  .../Library/Omap35xxTimerLib/TimerLib.c       |  151
> > ++
> > >  .../Library/OmapDmaLib/OmapDmaLib.c           |  170
> > ++
> > >  .../Library/OmapDmaLib/OmapDmaLib.inf         |   43
> > +
> > >  .../Omap35xxPkg/Library/OmapLib/OmapLib.c     |   77
> > +
> > >  .../Omap35xxPkg/Library/OmapLib/OmapLib.inf   |   31
> > +
> > >  .../RealTimeClockLib/RealTimeClockLib.c       |  291
> > ++++
> > >  .../RealTimeClockLib/RealTimeClockLib.inf     |   32
> > +
> > >  .../Library/SerialPortLib/SerialPortLib.c     |  208
> > +++
> > >  .../Library/SerialPortLib/SerialPortLib.inf   |   40
> > +
> > >  .../Omap35xxPkg/MMCHSDxe/MMCHS.c              | 1492
> > +++++++++++++++++
> > >  .../Omap35xxPkg/MMCHSDxe/MMCHS.h              |  169
> > ++
> > >  .../Omap35xxPkg/MMCHSDxe/MMCHS.inf            |   48
> > +
> > >  .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.c       |  671
> > ++++++++
> > >  .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.h       |   38
> > +
> > >  .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf     |   47
> > +
> > >  .../Omap35xxPkg/Omap35xxPkg.dec               |   52
> > +
> > >  .../Omap35xxPkg/Omap35xxPkg.dsc               |  183
> > ++
> > >  .../Omap35xxPkg/PciEmulation/PciEmulation.c   |  107
> > ++
> > >  .../Omap35xxPkg/PciEmulation/PciEmulation.inf |   41
> > +
> > >  .../Omap35xxPkg/SmbusDxe/Smbus.c              |  319
> > ++++
> > >  .../Omap35xxPkg/SmbusDxe/Smbus.inf            |   39
> > +
> > >  .../Omap35xxPkg/TPS65950Dxe/TPS65950.c        |  110
> > ++
> > >  .../Omap35xxPkg/TPS65950Dxe/TPS65950.inf      |   42
> > +
> > >  .../Omap35xxPkg/TimerDxe/Timer.c              |  370
> > ++++
> > >  .../Omap35xxPkg/TimerDxe/TimerDxe.inf         |   51
> > +
> > >  56 files changed, 9257 insertions(+)
> > >  create mode 100644
> > Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.c
> > 
> > TexasInsturments ->
> > TexasInstruments
> > 
> > Also, using the sortorder and --stat/--stat-graph-width
> > from Laszlo's
> > guide when generating patches would be helpful here even
> > though the
> > code is just moving. It makes the above more clear, and
> > puts the .dec
> > and .dsc (which have actually changed) first.
> > 
> > Beyond that, I intend to change both this and
> > BeagleBoardPkg to use
> > full pathnames relative to edk2-platforms root after the
> > migration,
> > but we don't need to do that for the migration.
> > 
> > Best Regards,
> > 
> > Leif

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [edk2-platforms: Patch 7/8] Drivers/OptionRomPkg: Import OptionRomPkg from edk2
  2019-05-10  3:34 ` [edk2-platforms: Patch 7/8] Drivers/OptionRomPkg: Import OptionRomPkg " Michael D Kinney
@ 2019-05-11  1:52   ` Ni, Ray
  0 siblings, 0 replies; 23+ messages in thread
From: Ni, Ray @ 2019-05-11  1:52 UTC (permalink / raw)
  To: Kinney, Michael D, devel@edk2.groups.io; +Cc: Leif Lindholm, Ard Biesheuvel

Reviewed-by: Ray Ni <ray.ni@intel.com>

> -----Original Message-----
> From: Kinney, Michael D
> Sent: Friday, May 10, 2019 11:35 AM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Leif Lindholm <leif.lindholm@linaro.org>;
> Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Subject: [edk2-platforms: Patch 7/8] Drivers/OptionRomPkg: Import
> OptionRomPkg from edk2
> 
> https://bugzilla.tianocore.org/show_bug.cgi?id=1793
> 
> Import OptionRomPkg from edk2/master.
> 
> Cc: Ray Ni <ray.ni@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>
> ---
>  .../Application/BltLibSample/BltLibSample.c   |  279 ++
>  .../Application/BltLibSample/BltLibSample.inf |   30 +
>  .../AtapiPassThruDxe/AtapiPassThru.c          | 3410 ++++++++++++++++
>  .../AtapiPassThruDxe/AtapiPassThru.h          | 1618 ++++++++
>  .../AtapiPassThruDxe/AtapiPassThruDxe.inf     |   70 +
>  .../AtapiPassThruDxe/ComponentName.c          |  169 +
>  .../DriverSupportedEfiVersion.c               |   14 +
>  .../FtdiUsbSerialDxe/CompatibleDevices.txt    |    5 +
>  .../Bus/Usb/FtdiUsbSerialDxe/ComponentName.c  |  218 +
>  .../FtdiUsbSerialDxe/FtdiUsbSerialDriver.c    | 2580 ++++++++++++
>  .../FtdiUsbSerialDxe/FtdiUsbSerialDriver.h    |  589 +++
>  .../Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf |   55 +
>  .../Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt       |   32 +
>  .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.c   | 1318 ++++++
>  .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.h   |  969 +++++
>  .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf |   61 +
>  .../Usb/UsbNetworking/Ax88772/ComponentName.c |  178 +
>  .../Usb/UsbNetworking/Ax88772/DriverBinding.c |  507 +++
>  .../Usb/UsbNetworking/Ax88772/SimpleNetwork.c | 1503 +++++++
>  .../Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c  |  875 ++++
>  .../Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h  | 1026 +++++
>  .../Usb/UsbNetworking/Ax88772b/Ax88772b.inf   |   61 +
>  .../UsbNetworking/Ax88772b/ComponentName.c    |  175 +
>  .../UsbNetworking/Ax88772b/DriverBinding.c    |  696 ++++
>  .../UsbNetworking/Ax88772b/SimpleNetwork.c    | 1657 ++++++++
>  .../CirrusLogic5430Dxe/CirrusLogic5430.c      |  917 +++++
>  .../CirrusLogic5430Dxe/CirrusLogic5430.h      |  432 ++
>  .../CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf |   84 +
>  .../CirrusLogic5430GraphicsOutput.c           |  556 +++
>  .../CirrusLogic5430Dxe/CirrusLogic5430I2c.c   |  427 ++
>  .../CirrusLogic5430Dxe/CirrusLogic5430I2c.h   |   62 +
>  .../CirrusLogic5430UgaDraw.c                  |  412 ++
>  .../CirrusLogic5430Dxe/ComponentName.c        |  203 +
>  .../DriverSupportedEfiVersion.c               |   14 +
>  .../OptionRomPkg/CirrusLogic5430Dxe/Edid.c    |  525 +++
>  Drivers/OptionRomPkg/Include/Library/BltLib.h |  253 ++
>  .../FrameBufferBltLib/FrameBufferBltLib.c     |  744 ++++
>  .../FrameBufferBltLib/FrameBufferBltLib.inf   |   29 +
>  .../Library/GopBltLib/GopBltLib.c             |  449 +++
>  .../Library/GopBltLib/GopBltLib.inf           |   31 +
>  Drivers/OptionRomPkg/OptionRomPkg.dec         |   41 +
>  Drivers/OptionRomPkg/OptionRomPkg.dsc         |  113 +
>  Drivers/OptionRomPkg/ReadMe.txt               |   17 +
>  .../UndiRuntimeDxe/ComponentName.c            |  359 ++
>  Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c  | 1516 +++++++
>  Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c   | 3541
> +++++++++++++++++
>  Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h   |  665 ++++
>  Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c    | 1051 +++++
>  Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h  |  439 ++
>  .../OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c |  145 +
>  .../UndiRuntimeDxe/UndiRuntimeDxe.inf         |   72 +
>  51 files changed, 31192 insertions(+)
>  create mode 100644
> Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.c
>  create mode 100644
> Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.inf
>  create mode 100644
> Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.c
>  create mode 100644
> Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.h
>  create mode 100644
> Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThruDxe.inf
>  create mode 100644
> Drivers/OptionRomPkg/AtapiPassThruDxe/ComponentName.c
>  create mode 100644
> Drivers/OptionRomPkg/AtapiPassThruDxe/DriverSupportedEfiVersion.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/CompatibleDevices.txt
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ComponentName.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.h
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.h
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/ComponentName
> .c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/DriverBinding.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/SimpleNetwork.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/ComponentNam
> e.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/DriverBinding.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwork.
> c
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.c
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.h
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430GraphicsOutput.
> c
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.c
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.h
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430UgaDraw.c
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/ComponentName.c
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/DriverSupportedEfiVersion.c
>  create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/Edid.c
>  create mode 100644 Drivers/OptionRomPkg/Include/Library/BltLib.h
>  create mode 100644
> Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.c
>  create mode 100644
> Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
>  create mode 100644 Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.c
>  create mode 100644 Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.inf
>  create mode 100644 Drivers/OptionRomPkg/OptionRomPkg.dec
>  create mode 100644 Drivers/OptionRomPkg/OptionRomPkg.dsc
>  create mode 100644 Drivers/OptionRomPkg/ReadMe.txt
>  create mode 100644
> Drivers/OptionRomPkg/UndiRuntimeDxe/ComponentName.c
>  create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c
>  create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c
>  create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h
>  create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c
>  create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h
>  create mode 100644
> Drivers/OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c
>  create mode 100644
> Drivers/OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf
> 
> diff --git a/Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.c
> b/Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.c
> new file mode 100644
> index 0000000000..6f901383b6
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.c
> @@ -0,0 +1,279 @@
> +/** @file
> +  Example program using BltLib
> +
> +  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +#include <Library/BltLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiApplicationEntryPoint.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +
> +
> +UINT64
> +ReadTimestamp (
> +  VOID
> +  )
> +{
> +#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> +  return AsmReadTsc ();
> +#else
> +#error ReadTimestamp not supported for this architecture!
> +#endif
> +}
> +
> +UINT32
> +Rand32 (
> +  VOID
> +  )
> +{
> +  UINTN    Found;
> +  INTN     Bits;
> +  UINT64   Tsc1;
> +  UINT64   Tsc2;
> +  UINT64   TscBits;
> +  UINT32   R32;
> +
> +  R32 = 0;
> +  Found = 0;
> +  Tsc1 = ReadTimestamp ();
> +  Tsc2 = ReadTimestamp ();
> +  do {
> +    Tsc2 = ReadTimestamp ();
> +    TscBits = Tsc2 ^ Tsc1;
> +    Bits = HighBitSet64 (TscBits);
> +    if (Bits > 0) {
> +      Bits = Bits - 1;
> +    }
> +    R32 = (UINT32)((R32 << Bits) |
> +                   RShiftU64 (LShiftU64 (TscBits, (UINTN) (64 - Bits)), (UINTN) (64 -
> Bits)));
> +    Found = Found + Bits;
> +  } while (Found < 32);
> +
> +  return R32;
> +}
> +
> +
> +VOID
> +TestFills (
> +  VOID
> +  )
> +{
> +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Color;
> +  UINTN                          Loop;
> +  UINTN                          X;
> +  UINTN                          Y;
> +  UINTN                          W;
> +  UINTN                          H;
> +  UINTN                          Width;
> +  UINTN                          Height;
> +
> +  BltLibGetSizes (&Width, &Height);
> +  for (Loop = 0; Loop < 10000; Loop++) {
> +    W = Width - (Rand32 () % Width);
> +    H = Height - (Rand32 () % Height);
> +    if (W != Width) {
> +      X = Rand32 () % (Width - W);
> +    } else {
> +      X = 0;
> +    }
> +    if (H != Height) {
> +      Y = Rand32 () % (Height - H);
> +    } else {
> +      Y = 0;
> +    }
> +    *(UINT32*) (&Color) = Rand32 () & 0xffffff;
> +    BltLibVideoFill (&Color, X, Y, W, H);
> +  }
> +}
> +
> +
> +VOID
> +TestColor1 (
> +  VOID
> +  )
> +{
> +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Color;
> +  UINTN                          X;
> +  UINTN                          Y;
> +  UINTN                          Width;
> +  UINTN                          Height;
> +
> +  BltLibGetSizes (&Width, &Height);
> +  *(UINT32*) (&Color) = 0;
> +
> +  for (Y = 0; Y < Height; Y++) {
> +    for (X = 0; X < Width; X++) {
> +      Color.Red =   (UINT8) ((X * 0x100) / Width);
> +      Color.Green = (UINT8) ((Y * 0x100) / Height);
> +      Color.Blue =  (UINT8) ((Y * 0x100) / Height);
> +      BltLibVideoFill (&Color, X, Y, 1, 1);
> +    }
> +  }
> +}
> +
> +
> +UINT32
> +Uint32SqRt (
> +  IN  UINT32  Uint32
> +  )
> +{
> +  UINT32 Mask;
> +  UINT32 SqRt;
> +  UINT32 SqRtMask;
> +  UINT32 Squared;
> +
> +  if (Uint32 == 0) {
> +    return 0;
> +  }
> +
> +  for (SqRt = 0, Mask = (UINT32) (1 << (HighBitSet32 (Uint32) / 2));
> +       Mask != 0;
> +       Mask = Mask >> 1
> +      ) {
> +    SqRtMask = SqRt | Mask;
> +    //DEBUG ((EFI_D_INFO, "Uint32=0x%x SqRtMask=0x%x\n", Uint32,
> SqRtMask));
> +    Squared = (UINT32) (SqRtMask * SqRtMask);
> +    if (Squared > Uint32) {
> +      continue;
> +    } else if (Squared < Uint32) {
> +      SqRt = SqRtMask;
> +    } else {
> +      return SqRtMask;
> +    }
> +  }
> +
> +  return SqRt;
> +}
> +
> +
> +UINT32
> +Uint32Dist (
> +  IN UINTN X,
> +  IN UINTN Y
> +  )
> +{
> +  return Uint32SqRt ((UINT32) ((X * X) + (Y * Y)));
> +}
> +
> +UINT8
> +GetTriColor (
> +  IN UINTN ColorDist,
> +  IN UINTN TriWidth
> +  )
> +{
> +  return (UINT8) (((TriWidth - ColorDist) * 0x100) / TriWidth);
> +  //return (((TriWidth * TriWidth - ColorDist * ColorDist) * 0x100) /
> (TriWidth * TriWidth));
> +}
> +
> +VOID
> +TestColor (
> +  VOID
> +  )
> +{
> +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Color;
> +  UINTN                          X, Y;
> +  UINTN                          X1, X2, X3;
> +  UINTN                          Y1, Y2;
> +  UINTN                          LineWidth, TriWidth, ScreenWidth;
> +  UINTN                          TriHeight, ScreenHeight;
> +  UINT32                         ColorDist;
> +
> +  BltLibGetSizes (&ScreenWidth, &ScreenHeight);
> +  *(UINT32*) (&Color) = 0;
> +  BltLibVideoFill (&Color, 0, 0, ScreenWidth, ScreenHeight);
> +
> +  TriWidth = (UINTN) DivU64x32 (
> +                       MultU64x32 (11547005, (UINT32) ScreenHeight),
> +                       10000000
> +                       );
> +  TriHeight = (UINTN) DivU64x32 (
> +                        MultU64x32 (8660254, (UINT32) ScreenWidth),
> +                        10000000
> +                        );
> +  if (TriWidth > ScreenWidth) {
> +    DEBUG ((EFI_D_INFO, "TriWidth at %d was too big\n", TriWidth));
> +    TriWidth = ScreenWidth;
> +  } else if (TriHeight > ScreenHeight) {
> +    DEBUG ((EFI_D_INFO, "TriHeight at %d was too big\n", TriHeight));
> +    TriHeight = ScreenHeight;
> +  }
> +
> +  DEBUG ((EFI_D_INFO, "Triangle Width: %d; Height: %d\n", TriWidth,
> TriHeight));
> +
> +  X1 = (ScreenWidth - TriWidth) / 2;
> +  X3 = X1 + TriWidth - 1;
> +  X2 = (X1 + X3) / 2;
> +  Y2 = (ScreenHeight - TriHeight) / 2;
> +  Y1 = Y2 + TriHeight - 1;
> +
> +  for (Y = Y2; Y <= Y1; Y++) {
> +    LineWidth =
> +      (UINTN) DivU64x32 (
> +                MultU64x32 (11547005, (UINT32) (Y - Y2)),
> +                20000000
> +                );
> +    for (X = X2 - LineWidth; X < (X2 + LineWidth); X++) {
> +      ColorDist = Uint32Dist(X - X1, Y1 - Y);
> +      Color.Red = GetTriColor (ColorDist, TriWidth);
> +
> +      ColorDist = Uint32Dist((X < X2) ? X2 - X : X - X2, Y - Y2);
> +      Color.Green = GetTriColor (ColorDist, TriWidth);
> +
> +      ColorDist = Uint32Dist(X3 - X, Y1 - Y);
> +      Color.Blue = GetTriColor (ColorDist, TriWidth);
> +
> +      BltLibVideoFill (&Color, X, Y, 1, 1);
> +    }
> +  }
> +}
> +
> +
> +/**
> +  The user Entry Point for Application. The user code starts with this
> function
> +  as the real entry point for the application.
> +
> +  @param[in] ImageHandle    The firmware allocated handle for the EFI
> image.
> +  @param[in] SystemTable    A pointer to the EFI System Table.
> +
> +  @retval EFI_SUCCESS       The entry point is executed successfully.
> +  @retval other             Some error occurs when executing this entry point.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UefiMain (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS                     Status;
> +  EFI_GRAPHICS_OUTPUT_PROTOCOL   *Gop;
> +
> +  Status = gBS->HandleProtocol (
> +                  gST->ConsoleOutHandle,
> +                  &gEfiGraphicsOutputProtocolGuid,
> +                  (VOID **) &Gop
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = BltLibConfigure (
> +             (VOID*)(UINTN) Gop->Mode->FrameBufferBase,
> +             Gop->Mode->Info
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  TestFills ();
> +
> +  TestColor ();
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.inf
> b/Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.inf
> new file mode 100644
> index 0000000000..b544f960ab
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.inf
> @@ -0,0 +1,30 @@
> +## @file
> +#  Test the BltLib interface
> +#
> +#  Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = BltLibSample
> +  FILE_GUID                      = f7763316-8c04-41d8-a87d-45b73c13c43c
> +  MODULE_TYPE                    = UEFI_APPLICATION
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = UefiMain
> +
> +[Sources]
> +  BltLibSample.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  OptionRomPkg/OptionRomPkg.dec
> +
> +[LibraryClasses]
> +  BltLib
> +  UefiApplicationEntryPoint
> +  UefiLib
> +
> diff --git a/Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.c
> b/Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.c
> new file mode 100644
> index 0000000000..20de2bc392
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.c
> @@ -0,0 +1,3410 @@
> +/** @file
> +  Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "AtapiPassThru.h"
> +
> +
> +SCSI_COMMAND_SET     gEndTable = { 0xff, (DATA_DIRECTION) 0xff };
> +
> +///
> +/// This table contains all the supported ATAPI commands.
> +///
> +SCSI_COMMAND_SET     gSupportedATAPICommands[] = {
> +  { OP_INQUIRY,                     DataIn  },
> +  { OP_LOAD_UNLOAD_CD,              NoData  },
> +  { OP_MECHANISM_STATUS,            DataIn  },
> +  { OP_MODE_SELECT_10,              DataOut },
> +  { OP_MODE_SENSE_10,               DataIn  },
> +  { OP_PAUSE_RESUME,                NoData  },
> +  { OP_PLAY_AUDIO_10,               DataIn  },
> +  { OP_PLAY_AUDIO_MSF,              DataIn  },
> +  { OP_PLAY_CD,                     DataIn  },
> +  { OP_PLAY_CD_MSF,                 DataIn  },
> +  { OP_PREVENT_ALLOW_MEDIUM_REMOVAL,NoData  },
> +  { OP_READ_10,                     DataIn  },
> +  { OP_READ_12,                     DataIn  },
> +  { OP_READ_CAPACITY,               DataIn  },
> +  { OP_READ_CD,                     DataIn  },
> +  { OP_READ_CD_MSF,                 DataIn  },
> +  { OP_READ_HEADER,                 DataIn  },
> +  { OP_READ_SUB_CHANNEL,            DataIn  },
> +  { OP_READ_TOC,                    DataIn  },
> +  { OP_REQUEST_SENSE,               DataIn  },
> +  { OP_SCAN,                        NoData  },
> +  { OP_SEEK_10,                     NoData  },
> +  { OP_SET_CD_SPEED,                DataOut },
> +  { OP_STOPPLAY_SCAN,               NoData  },
> +  { OP_START_STOP_UNIT,             NoData  },
> +  { OP_TEST_UNIT_READY,             NoData  },
> +  { OP_FORMAT_UNIT,                 DataOut },
> +  { OP_READ_FORMAT_CAPACITIES,      DataIn  },
> +  { OP_VERIFY,                      DataOut },
> +  { OP_WRITE_10,                    DataOut },
> +  { OP_WRITE_12,                    DataOut },
> +  { OP_WRITE_AND_VERIFY,            DataOut },
> +  { 0xff,                           (DATA_DIRECTION) 0xff    }
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_SCSI_PASS_THRU_MODE
> gScsiPassThruMode = {
> +  L"ATAPI Controller",
> +  L"ATAPI Channel",
> +  4,
> +  EFI_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL |
> EFI_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL,
> +  0
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_SCSI_PASS_THRU_PROTOCOL
> gScsiPassThruProtocolTemplate = {
> +  &gScsiPassThruMode,
> +  AtapiScsiPassThruFunction,
> +  AtapiScsiPassThruGetNextDevice,
> +  AtapiScsiPassThruBuildDevicePath,
> +  AtapiScsiPassThruGetTargetLun,
> +  AtapiScsiPassThruResetChannel,
> +  AtapiScsiPassThruResetTarget
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_EXT_SCSI_PASS_THRU_MODE
> gExtScsiPassThruMode = {
> +  4,
> +  EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL |
> EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL,
> +  0
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> EFI_EXT_SCSI_PASS_THRU_PROTOCOL gExtScsiPassThruProtocolTemplate = {
> +  &gExtScsiPassThruMode,
> +  AtapiExtScsiPassThruFunction,
> +  AtapiExtScsiPassThruGetNextTargetLun,
> +  AtapiExtScsiPassThruBuildDevicePath,
> +  AtapiExtScsiPassThruGetTargetLun,
> +  AtapiExtScsiPassThruResetChannel,
> +  AtapiExtScsiPassThruResetTarget,
> +  AtapiExtScsiPassThruGetNextTarget
> +};
> +
> +EFI_DRIVER_BINDING_PROTOCOL gAtapiScsiPassThruDriverBinding = {
> +  AtapiScsiPassThruDriverBindingSupported,
> +  AtapiScsiPassThruDriverBindingStart,
> +  AtapiScsiPassThruDriverBindingStop,
> +  0x10,
> +  NULL,
> +  NULL
> +};
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiScsiPassThruDriverBindingSupported (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> +  )
> +/*++
> +
> +Routine Description:
> +  Test to see if this driver supports ControllerHandle. Any ControllerHandle
> +  that has gEfiPciIoProtocolGuid installed and is IDE Controller it will be
> supported.
> +
> +Arguments:
> +
> +  This                - Protocol instance pointer.
> +  Controller          - Handle of device to test
> +  RemainingDevicePath - Not used
> +
> +Returns:
> +    EFI_STATUS
> +
> +--*/
> +{
> +  EFI_STATUS          Status;
> +  EFI_PCI_IO_PROTOCOL *PciIo;
> +  PCI_TYPE00          Pci;
> +
> +
> +  //
> +  // Open the IO Abstraction(s) needed to perform the supported test
> +  //
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiPciIoProtocolGuid,
> +                  (VOID **) &PciIo,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  //
> +  // Use the PCI I/O Protocol to see if Controller is a IDE Controller that
> +  // can be managed by this driver.  Read the PCI Configuration Header
> +  // for this device.
> +  //
> +  Status = PciIo->Pci.Read (
> +                        PciIo,
> +                        EfiPciIoWidthUint32,
> +                        0,
> +                        sizeof (Pci) / sizeof (UINT32),
> +                        &Pci
> +                        );
> +  if (EFI_ERROR (Status)) {
> +    gBS->CloseProtocol (
> +           Controller,
> +           &gEfiPciIoProtocolGuid,
> +           This->DriverBindingHandle,
> +           Controller
> +           );
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  if (Pci.Hdr.ClassCode[2] != PCI_CLASS_MASS_STORAGE ||
> Pci.Hdr.ClassCode[1] != PCI_CLASS_MASS_STORAGE_IDE) {
> +
> +    Status = EFI_UNSUPPORTED;
> +  }
> +
> +  gBS->CloseProtocol (
> +         Controller,
> +         &gEfiPciIoProtocolGuid,
> +         This->DriverBindingHandle,
> +         Controller
> +         );
> +
> +  return Status;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiScsiPassThruDriverBindingStart (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> +  )
> +/*++
> +
> +Routine Description:
> +  Create handles for IDE channels specified by RemainingDevicePath.
> +  Install SCSI Pass Thru Protocol onto each created handle.
> +
> +Arguments:
> +
> +  This                - Protocol instance pointer.
> +  Controller          - Handle of device to test
> +  RemainingDevicePath - Not used
> +
> +Returns:
> +    EFI_STATUS
> +
> +--*/
> +{
> +  EFI_STATUS          Status;
> +  EFI_PCI_IO_PROTOCOL *PciIo;
> +  UINT64              Supports;
> +  UINT64              OriginalPciAttributes;
> +  BOOLEAN             PciAttributesSaved;
> +
> +  PciIo = NULL;
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiPciIoProtocolGuid,
> +                  (VOID **) &PciIo,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  PciAttributesSaved = FALSE;
> +  //
> +  // Save original PCI attributes
> +  //
> +  Status = PciIo->Attributes (
> +                    PciIo,
> +                    EfiPciIoAttributeOperationGet,
> +                    0,
> +                    &OriginalPciAttributes
> +                    );
> +
> +  if (EFI_ERROR (Status)) {
> +    goto Done;
> +  }
> +  PciAttributesSaved = TRUE;
> +
> +  Status = PciIo->Attributes (
> +                    PciIo,
> +                    EfiPciIoAttributeOperationSupported,
> +                    0,
> +                    &Supports
> +                    );
> +  if (!EFI_ERROR (Status)) {
> +    Supports &= (EFI_PCI_DEVICE_ENABLE               |
> +                 EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO |
> +                 EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO);
> +    Status = PciIo->Attributes (
> +                      PciIo,
> +                      EfiPciIoAttributeOperationEnable,
> +                      Supports,
> +                      NULL
> +                      );
> +  }
> +  if (EFI_ERROR (Status)) {
> +    goto Done;
> +  }
> +
> +  //
> +  // Create SCSI Pass Thru instance for the IDE channel.
> +  //
> +  Status = RegisterAtapiScsiPassThru (This, Controller, PciIo,
> OriginalPciAttributes);
> +
> +Done:
> +  if (EFI_ERROR (Status)) {
> +    if (PciAttributesSaved == TRUE) {
> +      //
> +      // Restore original PCI attributes
> +      //
> +      PciIo->Attributes (
> +                      PciIo,
> +                      EfiPciIoAttributeOperationSet,
> +                      OriginalPciAttributes,
> +                      NULL
> +                      );
> +    }
> +
> +    gBS->CloseProtocol (
> +           Controller,
> +           &gEfiPciIoProtocolGuid,
> +           This->DriverBindingHandle,
> +           Controller
> +           );
> +  }
> +
> +  return Status;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiScsiPassThruDriverBindingStop (
> +  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
> +  IN  EFI_HANDLE                      Controller,
> +  IN  UINTN                           NumberOfChildren,
> +  IN  EFI_HANDLE                      *ChildHandleBuffer
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Stop this driver on ControllerHandle. Support stopping any child handles
> +  created by this driver.
> +
> +Arguments:
> +
> +  This              - Protocol instance pointer.
> +  Controller        - Handle of device to stop driver on
> +  NumberOfChildren  - Number of Children in the ChildHandleBuffer
> +  ChildHandleBuffer - List of handles for the children we need to stop.
> +
> +Returns:
> +
> +    EFI_STATUS
> +
> +--*/
> +{
> +  EFI_STATUS                      Status;
> +  EFI_SCSI_PASS_THRU_PROTOCOL     *ScsiPassThru;
> +  EFI_EXT_SCSI_PASS_THRU_PROTOCOL *ExtScsiPassThru;
> +  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate;
> +
> +  if (FeaturePcdGet (PcdSupportScsiPassThru)) {
> +    Status = gBS->OpenProtocol (
> +                    Controller,
> +                    &gEfiScsiPassThruProtocolGuid,
> +                    (VOID **) &ScsiPassThru,
> +                    This->DriverBindingHandle,
> +                    Controller,
> +                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +    AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS
> (ScsiPassThru);
> +    if (FeaturePcdGet (PcdSupportExtScsiPassThru)) {
> +      Status = gBS->UninstallMultipleProtocolInterfaces (
> +                      Controller,
> +                      &gEfiScsiPassThruProtocolGuid,
> +                      &AtapiScsiPrivate->ScsiPassThru,
> +                      &gEfiExtScsiPassThruProtocolGuid,
> +                      &AtapiScsiPrivate->ExtScsiPassThru,
> +                      NULL
> +                      );
> +    } else {
> +      Status = gBS->UninstallMultipleProtocolInterfaces (
> +                      Controller,
> +                      &gEfiScsiPassThruProtocolGuid,
> +                      &AtapiScsiPrivate->ScsiPassThru,
> +                      NULL
> +                      );
> +    }
> +  } else {
> +    Status = gBS->OpenProtocol (
> +                    Controller,
> +                    &gEfiExtScsiPassThruProtocolGuid,
> +                    (VOID **) &ExtScsiPassThru,
> +                    This->DriverBindingHandle,
> +                    Controller,
> +                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +    AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS
> (ExtScsiPassThru);
> +    Status = gBS->UninstallMultipleProtocolInterfaces (
> +                    Controller,
> +                    &gEfiExtScsiPassThruProtocolGuid,
> +                    &AtapiScsiPrivate->ExtScsiPassThru,
> +                    NULL
> +                    );
> +  }
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Restore original PCI attributes
> +  //
> +  AtapiScsiPrivate->PciIo->Attributes (
> +                  AtapiScsiPrivate->PciIo,
> +                  EfiPciIoAttributeOperationSet,
> +                  AtapiScsiPrivate->OriginalPciAttributes,
> +                  NULL
> +                  );
> +
> +  gBS->CloseProtocol (
> +         Controller,
> +         &gEfiPciIoProtocolGuid,
> +         This->DriverBindingHandle,
> +         Controller
> +         );
> +
> +  gBS->FreePool (AtapiScsiPrivate);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +RegisterAtapiScsiPassThru (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN  EFI_HANDLE                  Controller,
> +  IN  EFI_PCI_IO_PROTOCOL         *PciIo,
> +  IN  UINT64                      OriginalPciAttributes
> +  )
> +/*++
> +
> +Routine Description:
> +  Attaches SCSI Pass Thru Protocol for specified IDE channel.
> +
> +Arguments:
> +  This              - Protocol instance pointer.
> +  Controller        - Parent device handle to the IDE channel.
> +  PciIo             - PCI I/O protocol attached on the "Controller".
> +
> +Returns:
> +  Always return EFI_SUCCESS unless installing SCSI Pass Thru Protocol failed.
> +
> +--*/
> +{
> +  EFI_STATUS                Status;
> +  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate;
> +  IDE_REGISTERS_BASE_ADDR   IdeRegsBaseAddr[ATAPI_MAX_CHANNEL];
> +
> +  AtapiScsiPrivate = AllocateZeroPool (sizeof (ATAPI_SCSI_PASS_THRU_DEV));
> +  if (AtapiScsiPrivate == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  AtapiScsiPrivate->Signature = ATAPI_SCSI_PASS_THRU_DEV_SIGNATURE;
> +  AtapiScsiPrivate->Handle    = Controller;
> +
> +  //
> +  // will reset the IoPort inside each API function.
> +  //
> +  AtapiScsiPrivate->IoPort                = NULL;
> +  AtapiScsiPrivate->PciIo                 = PciIo;
> +  AtapiScsiPrivate->OriginalPciAttributes = OriginalPciAttributes;
> +
> +  //
> +  // Obtain IDE IO port registers' base addresses
> +  //
> +  Status = GetIdeRegistersBaseAddr (PciIo, IdeRegsBaseAddr);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  InitAtapiIoPortRegisters(AtapiScsiPrivate, IdeRegsBaseAddr);
> +
> +  //
> +  // Initialize the LatestTargetId to MAX_TARGET_ID.
> +  //
> +  AtapiScsiPrivate->LatestTargetId  = MAX_TARGET_ID;
> +  AtapiScsiPrivate->LatestLun       = 0;
> +
> +  Status = InstallScsiPassThruProtocols (&Controller, AtapiScsiPrivate);
> +
> +  return Status;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiScsiPassThruFunction (
> +  IN EFI_SCSI_PASS_THRU_PROTOCOL                        *This,
> +  IN UINT32                                             Target,
> +  IN UINT64                                             Lun,
> +  IN OUT EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET         *Packet,
> +  IN EFI_EVENT                                          Event OPTIONAL
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Implements EFI_SCSI_PASS_THRU_PROTOCOL.PassThru() function.
> +
> +Arguments:
> +
> +  This:     The EFI_SCSI_PASS_THRU_PROTOCOL instance.
> +  Target:   The Target ID of the ATAPI device to send the SCSI
> +            Request Packet. To ATAPI devices attached on an IDE
> +            Channel, Target ID 0 indicates Master device;Target
> +            ID 1 indicates Slave device.
> +  Lun:      The LUN of the ATAPI device to send the SCSI Request
> +            Packet. To the ATAPI device, Lun is always 0.
> +  Packet:   The SCSI Request Packet to send to the ATAPI device
> +            specified by Target and Lun.
> +  Event:    If non-blocking I/O is not supported then Event is ignored,
> +            and blocking I/O is performed.
> +            If Event is NULL, then blocking I/O is performed.
> +            If Event is not NULL and non blocking I/O is supported,
> +            then non-blocking I/O is performed, and Event will be signaled
> +            when the SCSI Request Packet completes.
> +
> +Returns:
> +
> +   EFI_STATUS
> +
> +--*/
> +{
> +  ATAPI_SCSI_PASS_THRU_DEV               *AtapiScsiPrivate;
> +  EFI_STATUS                             Status;
> +
> +  AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);
> +
> +  //
> +  // Target is not allowed beyond MAX_TARGET_ID
> +  //
> +  if ((Target > MAX_TARGET_ID) || (Lun != 0)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // check the data fields in Packet parameter.
> +  //
> +  Status = CheckSCSIRequestPacket (Packet);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // If Request Packet targets at the IDE channel itself,
> +  // do nothing.
> +  //
> +  if (Target == This->Mode->AdapterId) {
> +    Packet->TransferLength = 0;
> +    return EFI_SUCCESS;
> +  }
> +
> +  //
> +  // According to Target ID, reset the Atapi I/O Register mapping
> +  // (Target Id in [0,1] area, using AtapiIoPortRegisters[0],
> +  //  Target Id in [2,3] area, using AtapiIoPortRegisters[1]
> +  //
> +  if ((Target / 2) == 0) {
> +    Target = Target % 2;
> +    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[0];
> +  } else {
> +    Target = Target % 2;
> +    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[1];
> +  }
> +
> +  //
> +  // the ATAPI SCSI interface does not support non-blocking I/O
> +  // ignore the Event parameter
> +  //
> +  // Performs blocking I/O.
> +  //
> +  Status = SubmitBlockingIoCommand (AtapiScsiPrivate, Target, Packet);
> +  return Status;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiScsiPassThruGetNextDevice (
> +  IN  EFI_SCSI_PASS_THRU_PROTOCOL    *This,
> +  IN OUT UINT32                      *Target,
> +  IN OUT UINT64                      *Lun
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Used to retrieve the list of legal Target IDs for SCSI devices
> +  on a SCSI channel.
> +
> +Arguments:
> +
> +  This                  - Protocol instance pointer.
> +  Target                - On input, a pointer to the Target ID of a SCSI
> +                          device present on the SCSI channel.  On output,
> +                          a pointer to the Target ID of the next SCSI device
> +                          present on a SCSI channel.  An input value of
> +                          0xFFFFFFFF retrieves the Target ID of the first
> +                          SCSI device present on a SCSI channel.
> +  Lun                   - On input, a pointer to the LUN of a SCSI device
> +                          present on the SCSI channel. On output, a pointer
> +                          to the LUN of the next SCSI device present on
> +                          a SCSI channel.
> +Returns:
> +
> +  EFI_SUCCESS           - The Target ID and Lun of the next SCSI device
> +                          on the SCSI channel was returned in Target and Lun.
> +  EFI_NOT_FOUND         - There are no more SCSI devices on this SCSI
> channel.
> +  EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun
> were not
> +                           returned on a previous call to GetNextDevice().
> +--*/
> +{
> +  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate;
> +
> +  //
> +  // Retrieve Device Private Data Structure.
> +  //
> +  AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);
> +
> +  //
> +  // Check whether Target is valid.
> +  //
> +  if (Target == NULL || Lun == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if ((*Target != 0xFFFFFFFF) &&
> +      ((*Target != AtapiScsiPrivate->LatestTargetId) ||
> +      (*Lun != AtapiScsiPrivate->LatestLun))) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (*Target == MAX_TARGET_ID) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  if (*Target == 0xFFFFFFFF) {
> +    *Target = 0;
> +  } else {
> +    *Target = AtapiScsiPrivate->LatestTargetId + 1;
> +  }
> +
> +  *Lun = 0;
> +
> +  //
> +  // Update the LatestTargetId.
> +  //
> +  AtapiScsiPrivate->LatestTargetId  = *Target;
> +  AtapiScsiPrivate->LatestLun       = *Lun;
> +
> +  return EFI_SUCCESS;
> +
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiScsiPassThruBuildDevicePath (
> +  IN     EFI_SCSI_PASS_THRU_PROTOCOL    *This,
> +  IN     UINT32                         Target,
> +  IN     UINT64                         Lun,
> +  IN OUT EFI_DEVICE_PATH_PROTOCOL       **DevicePath
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Used to allocate and build a device path node for a SCSI device
> +  on a SCSI channel. Would not build device path for a SCSI Host Controller.
> +
> +Arguments:
> +
> +  This                  - Protocol instance pointer.
> +  Target                - The Target ID of the SCSI device for which
> +                          a device path node is to be allocated and built.
> +  Lun                   - The LUN of the SCSI device for which a device
> +                          path node is to be allocated and built.
> +  DevicePath            - A pointer to a single device path node that
> +                          describes the SCSI device specified by
> +                          Target and Lun. This function is responsible
> +                          for allocating the buffer DevicePath with the boot
> +                          service AllocatePool().  It is the caller's
> +                          responsibility to free DevicePath when the caller
> +                          is finished with DevicePath.
> +  Returns:
> +  EFI_SUCCESS           - The device path node that describes the SCSI device
> +                          specified by Target and Lun was allocated and
> +                          returned in DevicePath.
> +  EFI_NOT_FOUND         - The SCSI devices specified by Target and Lun does
> +                          not exist on the SCSI channel.
> +  EFI_INVALID_PARAMETER - DevicePath is NULL.
> +  EFI_OUT_OF_RESOURCES  - There are not enough resources to allocate
> +                          DevicePath.
> +--*/
> +{
> +  EFI_DEV_PATH              *Node;
> +
> +
> +  //
> +  // Validate parameters passed in.
> +  //
> +
> +  if (DevicePath == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // can not build device path for the SCSI Host Controller.
> +  //
> +  if ((Target > (MAX_TARGET_ID - 1)) || (Lun != 0)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  Node = AllocateZeroPool (sizeof (EFI_DEV_PATH));
> +  if (Node == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  Node->DevPath.Type    = MESSAGING_DEVICE_PATH;
> +  Node->DevPath.SubType = MSG_ATAPI_DP;
> +  SetDevicePathNodeLength (&Node->DevPath, sizeof
> (ATAPI_DEVICE_PATH));
> +
> +  Node->Atapi.PrimarySecondary  = (UINT8) (Target / 2);
> +  Node->Atapi.SlaveMaster       = (UINT8) (Target % 2);
> +  Node->Atapi.Lun               = (UINT16) Lun;
> +
> +  *DevicePath                   = (EFI_DEVICE_PATH_PROTOCOL *) Node;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiScsiPassThruGetTargetLun (
> +  IN  EFI_SCSI_PASS_THRU_PROTOCOL    *This,
> +  IN  EFI_DEVICE_PATH_PROTOCOL       *DevicePath,
> +  OUT UINT32                         *Target,
> +  OUT UINT64                         *Lun
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Used to translate a device path node to a Target ID and LUN.
> +
> +Arguments:
> +
> +  This                  - Protocol instance pointer.
> +  DevicePath            - A pointer to the device path node that
> +                          describes a SCSI device on the SCSI channel.
> +  Target                - A pointer to the Target ID of a SCSI device
> +                          on the SCSI channel.
> +  Lun                   - A pointer to the LUN of a SCSI device on
> +                          the SCSI channel.
> +Returns:
> +
> +  EFI_SUCCESS           - DevicePath was successfully translated to a
> +                          Target ID and LUN, and they were returned
> +                          in Target and Lun.
> +  EFI_INVALID_PARAMETER - DevicePath/Target/Lun is NULL.
> +  EFI_UNSUPPORTED       - This driver does not support the device path
> +                          node type in DevicePath.
> +  EFI_NOT_FOUND         - A valid translation from DevicePath to a
> +                          Target ID and LUN does not exist.
> +--*/
> +{
> +  EFI_DEV_PATH  *Node;
> +
> +  //
> +  // Validate parameters passed in.
> +  //
> +  if (DevicePath == NULL || Target == NULL || Lun == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Check whether the DevicePath belongs to SCSI_DEVICE_PATH
> +  //
> +  if ((DevicePath->Type != MESSAGING_DEVICE_PATH) ||
> +      (DevicePath->SubType != MSG_ATAPI_DP) ||
> +      (DevicePathNodeLength(DevicePath) != sizeof(ATAPI_DEVICE_PATH))) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  Node    = (EFI_DEV_PATH *) DevicePath;
> +
> +  *Target = Node->Atapi.PrimarySecondary * 2 + Node->Atapi.SlaveMaster;
> +  *Lun    = Node->Atapi.Lun;
> +
> +  if (*Target > (MAX_TARGET_ID - 1) || *Lun != 0) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiScsiPassThruResetChannel (
> +  IN  EFI_SCSI_PASS_THRU_PROTOCOL   *This
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Resets a SCSI channel.This operation resets all the
> +  SCSI devices connected to the SCSI channel.
> +
> +Arguments:
> +
> +  This                  - Protocol instance pointer.
> +
> +Returns:
> +
> +  EFI_SUCCESS           - The SCSI channel was reset.
> +  EFI_UNSUPPORTED       - The SCSI channel does not support
> +                          a channel reset operation.
> +  EFI_DEVICE_ERROR      - A device error occurred while
> +                          attempting to reset the SCSI channel.
> +  EFI_TIMEOUT           - A timeout occurred while attempting
> +                          to reset the SCSI channel.
> +--*/
> +{
> +  UINT8                     DeviceControlValue;
> +  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate;
> +  UINT8                     Index;
> +  BOOLEAN                   ResetFlag;
> +
> +  AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);
> +  ResetFlag = FALSE;
> +
> +  //
> +  // Reset both Primary channel and Secondary channel.
> +  // so, the IoPort pointer must point to the right I/O Register group
> +  //
> +  for (Index = 0; Index < 2; Index++) {
> +    //
> +    // Reset
> +    //
> +    AtapiScsiPrivate->IoPort  = &AtapiScsiPrivate-
> >AtapiIoPortRegisters[Index];
> +
> +    DeviceControlValue        = 0;
> +    //
> +    // set SRST bit to initiate soft reset
> +    //
> +    DeviceControlValue |= SRST;
> +    //
> +    // disable Interrupt
> +    //
> +    DeviceControlValue |= BIT1;
> +    WritePortB (
> +      AtapiScsiPrivate->PciIo,
> +      AtapiScsiPrivate->IoPort->Alt.DeviceControl,
> +      DeviceControlValue
> +      );
> +
> +    //
> +    // Wait 10us
> +    //
> +    gBS->Stall (10);
> +
> +    //
> +    // Clear SRST bit
> +    // 0xfb:1111,1011
> +    //
> +    DeviceControlValue &= 0xfb;
> +
> +    WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort-
> >Alt.DeviceControl, DeviceControlValue);
> +
> +    //
> +    // slave device needs at most 31s to clear BSY
> +    //
> +    if (StatusWaitForBSYClear (AtapiScsiPrivate, 31000000) != EFI_TIMEOUT) {
> +      ResetFlag = TRUE;
> +    }
> +  }
> +
> +  if (ResetFlag) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  return EFI_TIMEOUT;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiScsiPassThruResetTarget (
> +  IN EFI_SCSI_PASS_THRU_PROTOCOL    *This,
> +  IN UINT32                         Target,
> +  IN UINT64                         Lun
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Resets a SCSI device that is connected to a SCSI channel.
> +
> +Arguments:
> +
> +  This                  - Protocol instance pointer.
> +  Target                - The Target ID of the SCSI device to reset.
> +  Lun                   - The LUN of the SCSI device to reset.
> +
> +Returns:
> +
> +  EFI_SUCCESS           - The SCSI device specified by Target and
> +                          Lun was reset.
> +  EFI_UNSUPPORTED       - The SCSI channel does not support a target
> +                          reset operation.
> +  EFI_INVALID_PARAMETER - Target or Lun are invalid.
> +  EFI_DEVICE_ERROR      - A device error occurred while attempting
> +                          to reset the SCSI device specified by Target
> +                          and Lun.
> +  EFI_TIMEOUT           - A timeout occurred while attempting to reset
> +                          the SCSI device specified by Target and Lun.
> +--*/
> +{
> +  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate;
> +  UINT8                     Command;
> +  UINT8                     DeviceSelect;
> +
> +  AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);
> +
> +  if ((Target > MAX_TARGET_ID) || (Lun != 0)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  //
> +  // Directly return EFI_SUCCESS if want to reset the host controller
> +  //
> +  if (Target == This->Mode->AdapterId) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  //
> +  // According to Target ID, reset the Atapi I/O Register mapping
> +  // (Target Id in [0,1] area, using AtapiIoPortRegisters[0],
> +  //  Target Id in [2,3] area, using AtapiIoPortRegisters[1]
> +  //
> +  if ((Target / 2) == 0) {
> +    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[0];
> +  } else {
> +    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[1];
> +  }
> +
> +  //
> +  // for ATAPI device, no need to wait DRDY ready after device selecting.
> +  //
> +  // bit7 and bit5 are both set to 1 for backward compatibility
> +  //
> +  DeviceSelect = (UINT8) (((BIT7 | BIT5) | (Target << 4)));
> +  WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Head,
> DeviceSelect);
> +
> +  Command = ATAPI_SOFT_RESET_CMD;
> +  WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort-
> >Reg.Command, Command);
> +
> +  //
> +  // BSY clear is the only status return to the host by the device
> +  // when reset is complete.
> +  // slave device needs at most 31s to clear BSY
> +  //
> +  if (EFI_ERROR (StatusWaitForBSYClear (AtapiScsiPrivate, 31000000))) {
> +    return EFI_TIMEOUT;
> +  }
> +
> +  //
> +  // stall 5 seconds to make the device status stable
> +  //
> +  gBS->Stall (5000000);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiExtScsiPassThruFunction (
> +  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL                    *This,
> +  IN UINT8                                              *Target,
> +  IN UINT64                                             Lun,
> +  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET     *Packet,
> +  IN EFI_EVENT                                          Event OPTIONAL
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Implements EFI_EXT_SCSI_PASS_THRU_PROTOCOL.PassThru() function.
> +
> +Arguments:
> +
> +  This:     The EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
> +  Target:   The Target ID of the ATAPI device to send the SCSI
> +            Request Packet. To ATAPI devices attached on an IDE
> +            Channel, Target ID 0 indicates Master device;Target
> +            ID 1 indicates Slave device.
> +  Lun:      The LUN of the ATAPI device to send the SCSI Request
> +            Packet. To the ATAPI device, Lun is always 0.
> +  Packet:   The SCSI Request Packet to send to the ATAPI device
> +            specified by Target and Lun.
> +  Event:    If non-blocking I/O is not supported then Event is ignored,
> +            and blocking I/O is performed.
> +            If Event is NULL, then blocking I/O is performed.
> +            If Event is not NULL and non blocking I/O is supported,
> +            then non-blocking I/O is performed, and Event will be signaled
> +            when the SCSI Request Packet completes.
> +
> +Returns:
> +
> +   EFI_STATUS
> +
> +--*/
> +{
> +  EFI_STATUS                          Status;
> +  ATAPI_SCSI_PASS_THRU_DEV            *AtapiScsiPrivate;
> +  UINT8                                TargetId;
> +
> +  AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS (This);
> +
> +  //
> +  // For ATAPI device, UINT8 is enough to represent the SCSI ID on channel.
> +  //
> +  TargetId = Target[0];
> +
> +  //
> +  // Target is not allowed beyond MAX_TARGET_ID
> +  //
> +  if ((TargetId > MAX_TARGET_ID) || (Lun != 0)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // check the data fields in Packet parameter.
> +  //
> +  Status = CheckExtSCSIRequestPacket (Packet);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // If Request Packet targets at the IDE channel itself,
> +  // do nothing.
> +  //
> +  if (TargetId == (UINT8)This->Mode->AdapterId) {
> +    Packet->InTransferLength = Packet->OutTransferLength = 0;
> +    return EFI_SUCCESS;
> +  }
> +
> +  //
> +  // According to Target ID, reset the Atapi I/O Register mapping
> +  // (Target Id in [0,1] area, using AtapiIoPortRegisters[0],
> +  //  Target Id in [2,3] area, using AtapiIoPortRegisters[1]
> +  //
> +  if ((TargetId / 2) == 0) {
> +    TargetId = (UINT8) (TargetId % 2);
> +    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[0];
> +  } else {
> +    TargetId = (UINT8) (TargetId % 2);
> +    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[1];
> +  }
> +
> +  //
> +  // the ATAPI SCSI interface does not support non-blocking I/O
> +  // ignore the Event parameter
> +  //
> +  // Performs blocking I/O.
> +  //
> +  Status = SubmitExtBlockingIoCommand (AtapiScsiPrivate, TargetId, Packet);
> +  return Status;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiExtScsiPassThruGetNextTargetLun (
> +  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
> +  IN OUT UINT8                           **Target,
> +  IN OUT UINT64                          *Lun
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Used to retrieve the list of legal Target IDs for SCSI devices
> +  on a SCSI channel.
> +
> +Arguments:
> +
> +  This                  - Protocol instance pointer.
> +  Target                - On input, a pointer to the Target ID of a SCSI
> +                          device present on the SCSI channel.  On output,
> +                          a pointer to the Target ID of the next SCSI device
> +                          present on a SCSI channel.  An input value of
> +                          0xFFFFFFFF retrieves the Target ID of the first
> +                          SCSI device present on a SCSI channel.
> +  Lun                   - On input, a pointer to the LUN of a SCSI device
> +                          present on the SCSI channel. On output, a pointer
> +                          to the LUN of the next SCSI device present on
> +                          a SCSI channel.
> +Returns:
> +
> +  EFI_SUCCESS           - The Target ID and Lun of the next SCSI device
> +                          on the SCSI channel was returned in Target and Lun.
> +  EFI_NOT_FOUND         - There are no more SCSI devices on this SCSI
> channel.
> +  EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun
> were not
> +                           returned on a previous call to GetNextDevice().
> +--*/
> +{
> +  UINT8                          ByteIndex;
> +  UINT8                          TargetId;
> +  UINT8                          ScsiId[TARGET_MAX_BYTES];
> +  ATAPI_SCSI_PASS_THRU_DEV       *AtapiScsiPrivate;
> +
> +  //
> +  // Retrieve Device Private Data Structure.
> +  //
> +  AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS (This);
> +
> +  //
> +  // Check whether Target is valid.
> +  //
> +  if (*Target == NULL || Lun == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  SetMem (ScsiId, TARGET_MAX_BYTES, 0xFF);
> +
> +  TargetId = (*Target)[0];
> +
> +  //
> +  // For ATAPI device, we use UINT8 to represent the SCSI ID on channel.
> +  //
> +  if (CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) != 0) {
> +    for (ByteIndex = 1; ByteIndex < TARGET_MAX_BYTES; ByteIndex++) {
> +      if ((*Target)[ByteIndex] != 0) {
> +        return EFI_INVALID_PARAMETER;
> +      }
> +    }
> +  }
> +
> +  if ((CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) != 0) &&
> +      ((TargetId != AtapiScsiPrivate->LatestTargetId) ||
> +      (*Lun != AtapiScsiPrivate->LatestLun))) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (TargetId == MAX_TARGET_ID) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  if (CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) == 0) {
> +    SetMem (*Target, TARGET_MAX_BYTES,0);
> +  } else {
> +    (*Target)[0] = (UINT8) (AtapiScsiPrivate->LatestTargetId + 1);
> +  }
> +
> +  *Lun = 0;
> +
> +  //
> +  // Update the LatestTargetId.
> +  //
> +  AtapiScsiPrivate->LatestTargetId  = (*Target)[0];
> +  AtapiScsiPrivate->LatestLun       = *Lun;
> +
> +  return EFI_SUCCESS;
> +
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiExtScsiPassThruBuildDevicePath (
> +  IN     EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
> +  IN     UINT8                              *Target,
> +  IN     UINT64                             Lun,
> +  IN OUT EFI_DEVICE_PATH_PROTOCOL           **DevicePath
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Used to allocate and build a device path node for a SCSI device
> +  on a SCSI channel. Would not build device path for a SCSI Host Controller.
> +
> +Arguments:
> +
> +  This                  - Protocol instance pointer.
> +  Target                - The Target ID of the SCSI device for which
> +                          a device path node is to be allocated and built.
> +  Lun                   - The LUN of the SCSI device for which a device
> +                          path node is to be allocated and built.
> +  DevicePath            - A pointer to a single device path node that
> +                          describes the SCSI device specified by
> +                          Target and Lun. This function is responsible
> +                          for allocating the buffer DevicePath with the boot
> +                          service AllocatePool().  It is the caller's
> +                          responsibility to free DevicePath when the caller
> +                          is finished with DevicePath.
> +  Returns:
> +  EFI_SUCCESS           - The device path node that describes the SCSI device
> +                          specified by Target and Lun was allocated and
> +                          returned in DevicePath.
> +  EFI_NOT_FOUND         - The SCSI devices specified by Target and Lun does
> +                          not exist on the SCSI channel.
> +  EFI_INVALID_PARAMETER - DevicePath is NULL.
> +  EFI_OUT_OF_RESOURCES  - There are not enough resources to allocate
> +                          DevicePath.
> +--*/
> +{
> +  EFI_DEV_PATH                   *Node;
> +  UINT8                          TargetId;
> +
> +  TargetId = Target[0];
> +
> +  //
> +  // Validate parameters passed in.
> +  //
> +
> +  if (DevicePath == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // can not build device path for the SCSI Host Controller.
> +  //
> +  if ((TargetId > (MAX_TARGET_ID - 1)) || (Lun != 0)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  Node = AllocateZeroPool (sizeof (EFI_DEV_PATH));
> +  if (Node == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  Node->DevPath.Type    = MESSAGING_DEVICE_PATH;
> +  Node->DevPath.SubType = MSG_ATAPI_DP;
> +  SetDevicePathNodeLength (&Node->DevPath, sizeof
> (ATAPI_DEVICE_PATH));
> +
> +  Node->Atapi.PrimarySecondary  = (UINT8) (TargetId / 2);
> +  Node->Atapi.SlaveMaster       = (UINT8) (TargetId % 2);
> +  Node->Atapi.Lun               = (UINT16) Lun;
> +
> +  *DevicePath                   = (EFI_DEVICE_PATH_PROTOCOL *) Node;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiExtScsiPassThruGetTargetLun (
> +  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
> +  IN  EFI_DEVICE_PATH_PROTOCOL           *DevicePath,
> +  OUT UINT8                              **Target,
> +  OUT UINT64                             *Lun
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Used to translate a device path node to a Target ID and LUN.
> +
> +Arguments:
> +
> +  This                  - Protocol instance pointer.
> +  DevicePath            - A pointer to the device path node that
> +                          describes a SCSI device on the SCSI channel.
> +  Target                - A pointer to the Target ID of a SCSI device
> +                          on the SCSI channel.
> +  Lun                   - A pointer to the LUN of a SCSI device on
> +                          the SCSI channel.
> +Returns:
> +
> +  EFI_SUCCESS           - DevicePath was successfully translated to a
> +                          Target ID and LUN, and they were returned
> +                          in Target and Lun.
> +  EFI_INVALID_PARAMETER - DevicePath/Target/Lun is NULL.
> +  EFI_UNSUPPORTED       - This driver does not support the device path
> +                          node type in DevicePath.
> +  EFI_NOT_FOUND         - A valid translation from DevicePath to a
> +                          Target ID and LUN does not exist.
> +--*/
> +{
> +  EFI_DEV_PATH  *Node;
> +
> +  //
> +  // Validate parameters passed in.
> +  //
> +  if (DevicePath == NULL || Target == NULL || Lun == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Check whether the DevicePath belongs to SCSI_DEVICE_PATH
> +  //
> +  if ((DevicePath->Type != MESSAGING_DEVICE_PATH) ||
> +      (DevicePath->SubType != MSG_ATAPI_DP) ||
> +      (DevicePathNodeLength(DevicePath) != sizeof(ATAPI_DEVICE_PATH))) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  ZeroMem (*Target, TARGET_MAX_BYTES);
> +
> +  Node    = (EFI_DEV_PATH *) DevicePath;
> +
> +  (*Target)[0] = (UINT8) (Node->Atapi.PrimarySecondary * 2 + Node-
> >Atapi.SlaveMaster);
> +  *Lun    = Node->Atapi.Lun;
> +
> +  if ((*Target)[0] > (MAX_TARGET_ID - 1) || *Lun != 0) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiExtScsiPassThruResetChannel (
> +  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL   *This
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Resets a SCSI channel.This operation resets all the
> +  SCSI devices connected to the SCSI channel.
> +
> +Arguments:
> +
> +  This                  - Protocol instance pointer.
> +
> +Returns:
> +
> +  EFI_SUCCESS           - The SCSI channel was reset.
> +  EFI_UNSUPPORTED       - The SCSI channel does not support
> +                          a channel reset operation.
> +  EFI_DEVICE_ERROR      - A device error occurred while
> +                          attempting to reset the SCSI channel.
> +  EFI_TIMEOUT           - A timeout occurred while attempting
> +                          to reset the SCSI channel.
> +--*/
> +{
> +  UINT8                         DeviceControlValue;
> +  UINT8                         Index;
> +  ATAPI_SCSI_PASS_THRU_DEV      *AtapiScsiPrivate;
> +  BOOLEAN                       ResetFlag;
> +
> +  AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS (This);
> +  ResetFlag = FALSE;
> +  //
> +  // Reset both Primary channel and Secondary channel.
> +  // so, the IoPort pointer must point to the right I/O Register group
> +  // And if there is a channel reset successfully, return EFI_SUCCESS.
> +  //
> +  for (Index = 0; Index < 2; Index++) {
> +    //
> +    // Reset
> +    //
> +    AtapiScsiPrivate->IoPort  = &AtapiScsiPrivate-
> >AtapiIoPortRegisters[Index];
> +
> +    DeviceControlValue        = 0;
> +    //
> +    // set SRST bit to initiate soft reset
> +    //
> +    DeviceControlValue |= SRST;
> +    //
> +    // disable Interrupt
> +    //
> +    DeviceControlValue |= BIT1;
> +    WritePortB (
> +      AtapiScsiPrivate->PciIo,
> +      AtapiScsiPrivate->IoPort->Alt.DeviceControl,
> +      DeviceControlValue
> +      );
> +
> +    //
> +    // Wait 10us
> +    //
> +    gBS->Stall (10);
> +
> +    //
> +    // Clear SRST bit
> +    // 0xfb:1111,1011
> +    //
> +    DeviceControlValue &= 0xfb;
> +
> +    WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort-
> >Alt.DeviceControl, DeviceControlValue);
> +
> +    //
> +    // slave device needs at most 31s to clear BSY
> +    //
> +    if (StatusWaitForBSYClear (AtapiScsiPrivate, 31000000) != EFI_TIMEOUT) {
> +      ResetFlag = TRUE;
> +    }
> +  }
> +
> +  if (ResetFlag) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  return EFI_TIMEOUT;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiExtScsiPassThruResetTarget (
> +  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
> +  IN UINT8                              *Target,
> +  IN UINT64                             Lun
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Resets a SCSI device that is connected to a SCSI channel.
> +
> +Arguments:
> +
> +  This                  - Protocol instance pointer.
> +  Target                - The Target ID of the SCSI device to reset.
> +  Lun                   - The LUN of the SCSI device to reset.
> +
> +Returns:
> +
> +  EFI_SUCCESS           - The SCSI device specified by Target and
> +                          Lun was reset.
> +  EFI_UNSUPPORTED       - The SCSI channel does not support a target
> +                          reset operation.
> +  EFI_INVALID_PARAMETER - Target or Lun are invalid.
> +  EFI_DEVICE_ERROR      - A device error occurred while attempting
> +                          to reset the SCSI device specified by Target
> +                          and Lun.
> +  EFI_TIMEOUT           - A timeout occurred while attempting to reset
> +                          the SCSI device specified by Target and Lun.
> +--*/
> +{
> +  UINT8                         Command;
> +  UINT8                         DeviceSelect;
> +  UINT8                         TargetId;
> +  ATAPI_SCSI_PASS_THRU_DEV      *AtapiScsiPrivate;
> +
> +  AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS (This);
> +  TargetId = Target[0];
> +
> +  if ((TargetId > MAX_TARGET_ID) || (Lun != 0)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  //
> +  // Directly return EFI_SUCCESS if want to reset the host controller
> +  //
> +  if (TargetId == This->Mode->AdapterId) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  //
> +  // According to Target ID, reset the Atapi I/O Register mapping
> +  // (Target Id in [0,1] area, using AtapiIoPortRegisters[0],
> +  //  Target Id in [2,3] area, using AtapiIoPortRegisters[1]
> +  //
> +  if ((TargetId / 2) == 0) {
> +    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[0];
> +  } else {
> +    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[1];
> +  }
> +
> +  //
> +  // for ATAPI device, no need to wait DRDY ready after device selecting.
> +  //
> +  // bit7 and bit5 are both set to 1 for backward compatibility
> +  //
> +  DeviceSelect = (UINT8) ((BIT7 | BIT5) | (TargetId << 4));
> +  WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Head,
> DeviceSelect);
> +
> +  Command = ATAPI_SOFT_RESET_CMD;
> +  WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort-
> >Reg.Command, Command);
> +
> +  //
> +  // BSY clear is the only status return to the host by the device
> +  // when reset is complete.
> +  // slave device needs at most 31s to clear BSY
> +  //
> +  if (EFI_ERROR (StatusWaitForBSYClear (AtapiScsiPrivate, 31000000))) {
> +    return EFI_TIMEOUT;
> +  }
> +
> +  //
> +  // stall 5 seconds to make the device status stable
> +  //
> +  gBS->Stall (5000000);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiExtScsiPassThruGetNextTarget (
> +  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
> +  IN OUT UINT8                           **Target
> +  )
> +/*++
> +
> +Routine Description:
> +  Used to retrieve the list of legal Target IDs for SCSI devices
> +  on a SCSI channel.
> +
> +Arguments:
> +  This                  - Protocol instance pointer.
> +  Target                - On input, a pointer to the Target ID of a SCSI
> +                          device present on the SCSI channel.  On output,
> +                          a pointer to the Target ID of the next SCSI device
> +                           present on a SCSI channel.  An input value of
> +                           0xFFFFFFFF retrieves the Target ID of the first
> +                           SCSI device present on a SCSI channel.
> +  Lun                   - On input, a pointer to the LUN of a SCSI device
> +                          present on the SCSI channel. On output, a pointer
> +                          to the LUN of the next SCSI device present on
> +                          a SCSI channel.
> +
> +Returns:
> +  EFI_SUCCESS           - The Target ID and Lun of the next SCSI device
> +                          on the SCSI channel was returned in Target and Lun.
> +  EFI_NOT_FOUND         - There are no more SCSI devices on this SCSI
> channel.
> +  EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun
> were not
> +                          returned on a previous call to GetNextDevice().
> +--*/
> +{
> +  UINT8                         TargetId;
> +  UINT8                         ScsiId[TARGET_MAX_BYTES];
> +  ATAPI_SCSI_PASS_THRU_DEV      *AtapiScsiPrivate;
> +  UINT8                         ByteIndex;
> +
> +  //
> +  // Retrieve Device Private Data Structure.
> +  //
> +  AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS (This);
> +
> +  //
> +  // Check whether Target is valid.
> +  //
> +  if (*Target == NULL ) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  TargetId = (*Target)[0];
> +  SetMem (ScsiId, TARGET_MAX_BYTES, 0xFF);
> +
> +  //
> +  // For ATAPI device, we use UINT8 to represent the SCSI ID on channel.
> +  //
> +  if (CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) != 0) {
> +    for (ByteIndex = 1; ByteIndex < TARGET_MAX_BYTES; ByteIndex++) {
> +      if ((*Target)[ByteIndex] != 0) {
> +        return EFI_INVALID_PARAMETER;
> +      }
> +    }
> +  }
> +
> +  if ((CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) != 0)
> &&(TargetId != AtapiScsiPrivate->LatestTargetId)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (TargetId == MAX_TARGET_ID) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  if ((CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) == 0)) {
> +    SetMem (*Target, TARGET_MAX_BYTES, 0);
> +  } else {
> +    (*Target)[0] = (UINT8) (AtapiScsiPrivate->LatestTargetId + 1);
> +  }
> +
> +  //
> +  // Update the LatestTargetId.
> +  //
> +  AtapiScsiPrivate->LatestTargetId  = (*Target)[0];
> +  AtapiScsiPrivate->LatestLun       = 0;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +GetIdeRegistersBaseAddr (
> +  IN  EFI_PCI_IO_PROTOCOL         *PciIo,
> +  OUT IDE_REGISTERS_BASE_ADDR     *IdeRegsBaseAddr
> +  )
> +/*++
> +
> +Routine Description:
> +  Get IDE IO port registers' base addresses by mode. In 'Compatibility' mode,
> +  use fixed addresses. In Native-PCI mode, get base addresses from BARs in
> +  the PCI IDE controller's Configuration Space.
> +
> +Arguments:
> +  PciIo             - Pointer to the EFI_PCI_IO_PROTOCOL instance
> +  IdeRegsBaseAddr   - Pointer to IDE_REGISTERS_BASE_ADDR to
> +                      receive IDE IO port registers' base addresses
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +{
> +  EFI_STATUS  Status;
> +  PCI_TYPE00  PciData;
> +
> +  Status = PciIo->Pci.Read (
> +                        PciIo,
> +                        EfiPciIoWidthUint8,
> +                        0,
> +                        sizeof (PciData),
> +                        &PciData
> +                        );
> +
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  if ((PciData.Hdr.ClassCode[0] & IDE_PRIMARY_OPERATING_MODE) == 0) {
> +    IdeRegsBaseAddr[IdePrimary].CommandBlockBaseAddr  = 0x1f0;
> +    IdeRegsBaseAddr[IdePrimary].ControlBlockBaseAddr  = 0x3f6;
> +  } else {
> +    //
> +    // The BARs should be of IO type
> +    //
> +    if ((PciData.Device.Bar[0] & BIT0) == 0 ||
> +        (PciData.Device.Bar[1] & BIT0) == 0) {
> +      return EFI_UNSUPPORTED;
> +    }
> +
> +    IdeRegsBaseAddr[IdePrimary].CommandBlockBaseAddr  =
> +    (UINT16) (PciData.Device.Bar[0] & 0x0000fff8);
> +    IdeRegsBaseAddr[IdePrimary].ControlBlockBaseAddr  =
> +    (UINT16) ((PciData.Device.Bar[1] & 0x0000fffc) + 2);
> +  }
> +
> +  if ((PciData.Hdr.ClassCode[0] & IDE_SECONDARY_OPERATING_MODE) == 0)
> {
> +    IdeRegsBaseAddr[IdeSecondary].CommandBlockBaseAddr  = 0x170;
> +    IdeRegsBaseAddr[IdeSecondary].ControlBlockBaseAddr  = 0x376;
> +  } else {
> +    //
> +    // The BARs should be of IO type
> +    //
> +    if ((PciData.Device.Bar[2] & BIT0) == 0 ||
> +        (PciData.Device.Bar[3] & BIT0) == 0) {
> +      return EFI_UNSUPPORTED;
> +    }
> +
> +    IdeRegsBaseAddr[IdeSecondary].CommandBlockBaseAddr  =
> +    (UINT16) (PciData.Device.Bar[2] & 0x0000fff8);
> +    IdeRegsBaseAddr[IdeSecondary].ControlBlockBaseAddr  =
> +    (UINT16) ((PciData.Device.Bar[3] & 0x0000fffc) + 2);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +VOID
> +InitAtapiIoPortRegisters (
> +  IN  ATAPI_SCSI_PASS_THRU_DEV     *AtapiScsiPrivate,
> +  IN  IDE_REGISTERS_BASE_ADDR      *IdeRegsBaseAddr
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Initialize each Channel's Base Address of CommandBlock and ControlBlock.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
> +  IdeRegsBaseAddr             - The pointer of IDE_REGISTERS_BASE_ADDR
> +
> +Returns:
> +
> +  None
> +
> +--*/
> +{
> +
> +  UINT8               IdeChannel;
> +  UINT16              CommandBlockBaseAddr;
> +  UINT16              ControlBlockBaseAddr;
> +  IDE_BASE_REGISTERS  *RegisterPointer;
> +
> +
> +  for (IdeChannel = 0; IdeChannel < ATAPI_MAX_CHANNEL; IdeChannel++) {
> +
> +    RegisterPointer =  &AtapiScsiPrivate->AtapiIoPortRegisters[IdeChannel];
> +
> +    //
> +    // Initialize IDE IO port addresses, including Command Block registers
> +    // and Control Block registers
> +    //
> +    CommandBlockBaseAddr =
> IdeRegsBaseAddr[IdeChannel].CommandBlockBaseAddr;
> +    ControlBlockBaseAddr =
> IdeRegsBaseAddr[IdeChannel].ControlBlockBaseAddr;
> +
> +    RegisterPointer->Data = CommandBlockBaseAddr;
> +    (*(UINT16 *) &RegisterPointer->Reg1) = (UINT16)
> (CommandBlockBaseAddr + 0x01);
> +    RegisterPointer->SectorCount = (UINT16) (CommandBlockBaseAddr +
> 0x02);
> +    RegisterPointer->SectorNumber = (UINT16) (CommandBlockBaseAddr +
> 0x03);
> +    RegisterPointer->CylinderLsb = (UINT16) (CommandBlockBaseAddr +
> 0x04);
> +    RegisterPointer->CylinderMsb = (UINT16) (CommandBlockBaseAddr +
> 0x05);
> +    RegisterPointer->Head = (UINT16) (CommandBlockBaseAddr + 0x06);
> +    (*(UINT16 *) &RegisterPointer->Reg) = (UINT16)
> (CommandBlockBaseAddr + 0x07);
> +
> +    (*(UINT16 *) &RegisterPointer->Alt) = ControlBlockBaseAddr;
> +    RegisterPointer->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01);
> +  }
> +
> +}
> +
> +
> +EFI_STATUS
> +CheckSCSIRequestPacket (
> +  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET      *Packet
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Checks the parameters in the SCSI Request Packet to make sure
> +  they are valid for a SCSI Pass Thru request.
> +
> +Arguments:
> +
> +  Packet         -  The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +{
> +  if (Packet == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (!ValidCdbLength (Packet->CdbLength)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (Packet->Cdb == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Checks whether the request command is supported.
> +  //
> +  if (!IsCommandValid (Packet)) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +BOOLEAN
> +IsCommandValid (
> +  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET   *Packet
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Checks the requested SCSI command:
> +  Is it supported by this driver?
> +  Is the Data transfer direction reasonable?
> +
> +Arguments:
> +
> +  Packet         -  The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +{
> +  UINT8 Index;
> +  UINT8 *OpCode;
> +  UINT8 ArrayLen;
> +
> +  OpCode = (UINT8 *) (Packet->Cdb);
> +  ArrayLen = (UINT8) (ARRAY_SIZE (gSupportedATAPICommands));
> +
> +  for (Index = 0; (Index < ArrayLen) && (CompareMem
> (&gSupportedATAPICommands[Index], &gEndTable, sizeof
> (SCSI_COMMAND_SET)) != 0); Index++) {
> +
> +    if (*OpCode == gSupportedATAPICommands[Index].OpCode) {
> +      //
> +      // Check whether the requested Command is supported by this driver
> +      //
> +      if (Packet->DataDirection == DataIn) {
> +        //
> +        // Check whether the requested data direction conforms to
> +        // what it should be.
> +        //
> +        if (gSupportedATAPICommands[Index].Direction == DataOut) {
> +          return FALSE;
> +        }
> +      }
> +
> +      if (Packet->DataDirection == DataOut) {
> +        //
> +        // Check whether the requested data direction conforms to
> +        // what it should be.
> +        //
> +        if (gSupportedATAPICommands[Index].Direction == DataIn) {
> +          return FALSE;
> +        }
> +      }
> +
> +      return TRUE;
> +    }
> +  }
> +
> +  return FALSE;
> +}
> +
> +EFI_STATUS
> +SubmitBlockingIoCommand (
> +  ATAPI_SCSI_PASS_THRU_DEV                  *AtapiScsiPrivate,
> +  UINT32                                    Target,
> +  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET    *Packet
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Performs blocking I/O request.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate:   Private data structure for the specified channel.
> +  Target:             The Target ID of the ATAPI device to send the SCSI
> +                      Request Packet. To ATAPI devices attached on an IDE
> +                      Channel, Target ID 0 indicates Master device;Target
> +                      ID 1 indicates Slave device.
> +  Packet:             The SCSI Request Packet to send to the ATAPI device
> +                      specified by Target.
> +
> +  Returns:            EFI_STATUS
> +
> +--*/
> +{
> +  UINT8       PacketCommand[12];
> +  UINT64      TimeoutInMicroSeconds;
> +  EFI_STATUS  PacketCommandStatus;
> +
> +  //
> +  // Fill ATAPI Command Packet according to CDB
> +  //
> +  ZeroMem (&PacketCommand, 12);
> +  CopyMem (&PacketCommand, Packet->Cdb, Packet->CdbLength);
> +
> +  //
> +  // Timeout is 100ns unit, convert it to 1000ns (1us) unit.
> +  //
> +  TimeoutInMicroSeconds = DivU64x32 (Packet->Timeout, (UINT32) 10);
> +
> +  //
> +  // Submit ATAPI Command Packet
> +  //
> +  PacketCommandStatus = AtapiPacketCommand (
> +                          AtapiScsiPrivate,
> +                          Target,
> +                          PacketCommand,
> +                          Packet->DataBuffer,
> +                          &(Packet->TransferLength),
> +                          (DATA_DIRECTION) Packet->DataDirection,
> +                          TimeoutInMicroSeconds
> +                          );
> +  if (!EFI_ERROR (PacketCommandStatus) || (Packet->SenseData == NULL)) {
> +    Packet->SenseDataLength = 0;
> +    return PacketCommandStatus;
> +  }
> +
> +  //
> +  // Return SenseData if PacketCommandStatus matches
> +  // the following return codes.
> +  //
> +  if ((PacketCommandStatus ==  EFI_BAD_BUFFER_SIZE) ||
> +      (PacketCommandStatus == EFI_DEVICE_ERROR) ||
> +      (PacketCommandStatus == EFI_TIMEOUT)) {
> +
> +    //
> +    // avoid submit request sense command continuously.
> +    //
> +    if (PacketCommand[0] == OP_REQUEST_SENSE) {
> +      Packet->SenseDataLength = 0;
> +      return PacketCommandStatus;
> +    }
> +
> +    RequestSenseCommand (
> +      AtapiScsiPrivate,
> +      Target,
> +      Packet->Timeout,
> +      Packet->SenseData,
> +      &Packet->SenseDataLength
> +      );
> +  }
> +
> +  return PacketCommandStatus;
> +}
> +
> +EFI_STATUS
> +RequestSenseCommand (
> +  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,
> +  UINT32                      Target,
> +  UINT64                      Timeout,
> +  VOID                        *SenseData,
> +  UINT8                       *SenseDataLength
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Submit request sense command
> +
> +Arguments:
> +
> +  AtapiScsiPrivate  - The pointer of ATAPI_SCSI_PASS_THRU_DEV
> +  Target            - The target ID
> +  Timeout           - The time to complete the command
> +  SenseData         - The buffer to fill in sense data
> +  SenseDataLength   - The length of buffer
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +{
> +  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  Packet;
> +  UINT8                                   Cdb[12];
> +  EFI_STATUS                              Status;
> +
> +  ZeroMem (&Packet, sizeof
> (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET));
> +  ZeroMem (Cdb, 12);
> +
> +  Cdb[0]                = OP_REQUEST_SENSE;
> +  Cdb[4]                = (UINT8) (*SenseDataLength);
> +
> +  Packet.Timeout        = Timeout;
> +  Packet.DataBuffer     = SenseData;
> +  Packet.SenseData      = NULL;
> +  Packet.Cdb            = Cdb;
> +  Packet.TransferLength = *SenseDataLength;
> +  Packet.CdbLength      = 12;
> +  Packet.DataDirection  = DataIn;
> +
> +  Status                = SubmitBlockingIoCommand (AtapiScsiPrivate, Target,
> &Packet);
> +  *SenseDataLength      = (UINT8) (Packet.TransferLength);
> +  return Status;
> +}
> +
> +EFI_STATUS
> +CheckExtSCSIRequestPacket (
> +  EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET      *Packet
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Checks the parameters in the SCSI Request Packet to make sure
> +  they are valid for a SCSI Pass Thru request.
> +
> +Arguments:
> +
> +  Packet       - The pointer of
> EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +{
> +  if (Packet == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (!ValidCdbLength (Packet->CdbLength)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (Packet->Cdb == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Checks whether the request command is supported.
> +  //
> +  if (!IsExtCommandValid (Packet)) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +BOOLEAN
> +IsExtCommandValid (
> +  EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET   *Packet
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Checks the requested SCSI command:
> +  Is it supported by this driver?
> +  Is the Data transfer direction reasonable?
> +
> +Arguments:
> +
> +  Packet         -  The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +{
> +  UINT8 Index;
> +  UINT8 *OpCode;
> +  UINT8 ArrayLen;
> +
> +  OpCode = (UINT8 *) (Packet->Cdb);
> +  ArrayLen = (UINT8) (ARRAY_SIZE (gSupportedATAPICommands));
> +
> +  for (Index = 0; (Index < ArrayLen) && (CompareMem
> (&gSupportedATAPICommands[Index], &gEndTable, sizeof
> (SCSI_COMMAND_SET)) != 0); Index++) {
> +
> +    if (*OpCode == gSupportedATAPICommands[Index].OpCode) {
> +      //
> +      // Check whether the requested Command is supported by this driver
> +      //
> +      if (Packet->DataDirection == DataIn) {
> +        //
> +        // Check whether the requested data direction conforms to
> +        // what it should be.
> +        //
> +        if (gSupportedATAPICommands[Index].Direction == DataOut) {
> +          return FALSE;
> +        }
> +      }
> +
> +      if (Packet->DataDirection == DataOut) {
> +        //
> +        // Check whether the requested data direction conforms to
> +        // what it should be.
> +        //
> +        if (gSupportedATAPICommands[Index].Direction == DataIn) {
> +          return FALSE;
> +        }
> +      }
> +
> +      return TRUE;
> +    }
> +  }
> +
> +  return FALSE;
> +}
> +
> +EFI_STATUS
> +SubmitExtBlockingIoCommand (
> +  ATAPI_SCSI_PASS_THRU_DEV                      *AtapiScsiPrivate,
> +  UINT8                                         Target,
> +  EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET    *Packet
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Performs blocking I/O request.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate:   Private data structure for the specified channel.
> +  Target:             The Target ID of the ATAPI device to send the SCSI
> +                      Request Packet. To ATAPI devices attached on an IDE
> +                      Channel, Target ID 0 indicates Master device;Target
> +                      ID 1 indicates Slave device.
> +  Packet:             The SCSI Request Packet to send to the ATAPI device
> +                      specified by Target.
> +
> +  Returns:            EFI_STATUS
> +
> +--*/
> +{
> +  UINT8       PacketCommand[12];
> +  UINT64      TimeoutInMicroSeconds;
> +  EFI_STATUS  PacketCommandStatus;
> +
> +  //
> +  // Fill ATAPI Command Packet according to CDB
> +  //
> +  ZeroMem (&PacketCommand, 12);
> +  CopyMem (&PacketCommand, Packet->Cdb, Packet->CdbLength);
> +
> +  //
> +  // Timeout is 100ns unit, convert it to 1000ns (1us) unit.
> +  //
> +  TimeoutInMicroSeconds = DivU64x32 (Packet->Timeout, (UINT32) 10);
> +
> +  //
> +  // Submit ATAPI Command Packet
> +  //
> +  if (Packet->DataDirection == DataIn) {
> +    PacketCommandStatus = AtapiPacketCommand (
> +                              AtapiScsiPrivate,
> +                              Target,
> +                              PacketCommand,
> +                              Packet->InDataBuffer,
> +                              &(Packet->InTransferLength),
> +                              DataIn,
> +                              TimeoutInMicroSeconds
> +                              );
> +  } else {
> +
> +    PacketCommandStatus = AtapiPacketCommand (
> +                            AtapiScsiPrivate,
> +                            Target,
> +                            PacketCommand,
> +                            Packet->OutDataBuffer,
> +                            &(Packet->OutTransferLength),
> +                            DataOut,
> +                            TimeoutInMicroSeconds
> +                            );
> +  }
> +
> +  if (!EFI_ERROR (PacketCommandStatus) || (Packet->SenseData == NULL)) {
> +    Packet->SenseDataLength = 0;
> +    return PacketCommandStatus;
> +  }
> +
> +  //
> +  // Return SenseData if PacketCommandStatus matches
> +  // the following return codes.
> +  //
> +  if ((PacketCommandStatus == EFI_BAD_BUFFER_SIZE) ||
> +      (PacketCommandStatus == EFI_DEVICE_ERROR) ||
> +      (PacketCommandStatus == EFI_TIMEOUT)) {
> +
> +    //
> +    // avoid submit request sense command continuously.
> +    //
> +    if (PacketCommand[0] == OP_REQUEST_SENSE) {
> +      Packet->SenseDataLength = 0;
> +      return PacketCommandStatus;
> +    }
> +
> +    RequestSenseCommand (
> +      AtapiScsiPrivate,
> +      Target,
> +      Packet->Timeout,
> +      Packet->SenseData,
> +      &Packet->SenseDataLength
> +      );
> +  }
> +
> +  return PacketCommandStatus;
> +}
> +
> +
> +EFI_STATUS
> +AtapiPacketCommand (
> +  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,
> +  UINT32                      Target,
> +  UINT8                       *PacketCommand,
> +  VOID                        *Buffer,
> +  UINT32                      *ByteCount,
> +  DATA_DIRECTION              Direction,
> +  UINT64                      TimeoutInMicroSeconds
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Submits ATAPI command packet to the specified ATAPI device.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate:   Private data structure for the specified channel.
> +  Target:             The Target ID of the ATAPI device to send the SCSI
> +                      Request Packet. To ATAPI devices attached on an IDE
> +                      Channel, Target ID 0 indicates Master device;Target
> +                      ID 1 indicates Slave device.
> +  PacketCommand:      Points to the ATAPI command packet.
> +  Buffer:             Points to the transferred data.
> +  ByteCount:          When input,indicates the buffer size; when output,
> +                      indicates the actually transferred data size.
> +  Direction:          Indicates the data transfer direction.
> +  TimeoutInMicroSeconds:
> +                      The timeout, in micro second units, to use for the
> +                      execution of this ATAPI command.
> +                      A TimeoutInMicroSeconds value of 0 means that
> +                      this function will wait indefinitely for the ATAPI
> +                      command to execute.
> +                      If TimeoutInMicroSeconds is greater than zero, then
> +                      this function will return EFI_TIMEOUT if the time
> +                      required to execute the ATAPI command is greater
> +                      than TimeoutInMicroSeconds.
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +{
> +
> +  UINT16      *CommandIndex;
> +  UINT8       Count;
> +  EFI_STATUS  Status;
> +
> +  //
> +  // Set all the command parameters by fill related registers.
> +  // Before write to all the following registers, BSY must be 0.
> +  //
> +  Status = StatusWaitForBSYClear (AtapiScsiPrivate,
> TimeoutInMicroSeconds);
> +  if (EFI_ERROR (Status)) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +
> +  //
> +  // Select device via Device/Head Register.
> +  // "Target = 0" indicates device 0; "Target = 1" indicates device 1
> +  //
> +  WritePortB (
> +    AtapiScsiPrivate->PciIo,
> +    AtapiScsiPrivate->IoPort->Head,
> +    (UINT8) ((Target << 4) | DEFAULT_CMD) // DEFAULT_CMD: 0xa0
> (1010,0000)
> +    );
> +
> +  //
> +  // Set all the command parameters by fill related registers.
> +  // Before write to all the following registers, BSY DRQ must be 0.
> +  //
> +  Status =  StatusDRQClear(AtapiScsiPrivate,  TimeoutInMicroSeconds);
> +
> +  if (EFI_ERROR (Status)) {
> +    if (Status == EFI_ABORTED) {
> +      Status = EFI_DEVICE_ERROR;
> +    }
> +    *ByteCount = 0;
> +    return Status;
> +  }
> +
> +  //
> +  // No OVL; No DMA (by setting feature register)
> +  //
> +  WritePortB (
> +    AtapiScsiPrivate->PciIo,
> +    AtapiScsiPrivate->IoPort->Reg1.Feature,
> +    0x00
> +    );
> +
> +  //
> +  // set the transfersize to MAX_ATAPI_BYTE_COUNT to let the device
> +  // determine how much data should be transfered.
> +  //
> +  WritePortB (
> +    AtapiScsiPrivate->PciIo,
> +    AtapiScsiPrivate->IoPort->CylinderLsb,
> +    (UINT8) (MAX_ATAPI_BYTE_COUNT & 0x00ff)
> +    );
> +  WritePortB (
> +    AtapiScsiPrivate->PciIo,
> +    AtapiScsiPrivate->IoPort->CylinderMsb,
> +    (UINT8) (MAX_ATAPI_BYTE_COUNT >> 8)
> +    );
> +
> +  //
> +  //  DEFAULT_CTL:0x0a (0000,1010)
> +  //  Disable interrupt
> +  //
> +  WritePortB (
> +    AtapiScsiPrivate->PciIo,
> +    AtapiScsiPrivate->IoPort->Alt.DeviceControl,
> +    DEFAULT_CTL
> +    );
> +
> +  //
> +  // Send Packet command to inform device
> +  // that the following data bytes are command packet.
> +  //
> +  WritePortB (
> +    AtapiScsiPrivate->PciIo,
> +    AtapiScsiPrivate->IoPort->Reg.Command,
> +    PACKET_CMD
> +    );
> +
> +  //
> +  // Before data transfer, BSY should be 0 and DRQ should be 1.
> +  // if they are not in specified time frame,
> +  // retrieve Sense Key from Error Register before return.
> +  //
> +  Status = StatusDRQReady (AtapiScsiPrivate, TimeoutInMicroSeconds);
> +  if (EFI_ERROR (Status)) {
> +    if (Status == EFI_ABORTED) {
> +      Status = EFI_DEVICE_ERROR;
> +    }
> +
> +    *ByteCount = 0;
> +    return Status;
> +  }
> +
> +  //
> +  // Send out command packet
> +  //
> +  CommandIndex = (UINT16 *) PacketCommand;
> +  for (Count = 0; Count < 6; Count++, CommandIndex++) {
> +    WritePortW (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Data,
> *CommandIndex);
> +  }
> +
> +  //
> +  // call AtapiPassThruPioReadWriteData() function to get
> +  // requested transfer data form device.
> +  //
> +  return AtapiPassThruPioReadWriteData (
> +          AtapiScsiPrivate,
> +          Buffer,
> +          ByteCount,
> +          Direction,
> +          TimeoutInMicroSeconds
> +          );
> +}
> +
> +EFI_STATUS
> +AtapiPassThruPioReadWriteData (
> +  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate,
> +  UINT16                    *Buffer,
> +  UINT32                    *ByteCount,
> +  DATA_DIRECTION            Direction,
> +  UINT64                    TimeoutInMicroSeconds
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Performs data transfer between ATAPI device and host after the
> +  ATAPI command packet is sent.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate:   Private data structure for the specified channel.
> +  Buffer:             Points to the transferred data.
> +  ByteCount:          When input,indicates the buffer size; when output,
> +                      indicates the actually transferred data size.
> +  Direction:          Indicates the data transfer direction.
> +  TimeoutInMicroSeconds:
> +                      The timeout, in micro second units, to use for the
> +                      execution of this ATAPI command.
> +                      A TimeoutInMicroSeconds value of 0 means that
> +                      this function will wait indefinitely for the ATAPI
> +                      command to execute.
> +                      If TimeoutInMicroSeconds is greater than zero, then
> +                      this function will return EFI_TIMEOUT if the time
> +                      required to execute the ATAPI command is greater
> +                      than TimeoutInMicroSeconds.
> + Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +{
> +  UINT32      Index;
> +  UINT32      RequiredWordCount;
> +  UINT32      ActualWordCount;
> +  UINT32      WordCount;
> +  EFI_STATUS  Status;
> +  UINT16      *ptrBuffer;
> +
> +  Status = EFI_SUCCESS;
> +
> +  //
> +  // Non Data transfer request is also supported.
> +  //
> +  if (*ByteCount == 0 || Buffer == NULL) {
> +    *ByteCount = 0;
> +    if (EFI_ERROR (StatusWaitForBSYClear (AtapiScsiPrivate,
> TimeoutInMicroSeconds))) {
> +      return EFI_DEVICE_ERROR;
> +    }
> +  }
> +
> +  ptrBuffer         = Buffer;
> +  RequiredWordCount = *ByteCount / 2;
> +
> +  //
> +  // ActuralWordCount means the word count of data really transfered.
> +  //
> +  ActualWordCount = 0;
> +
> +  while (ActualWordCount < RequiredWordCount) {
> +    //
> +    // before each data transfer stream, the host should poll DRQ bit ready,
> +    // which indicates device's ready for data transfer .
> +    //
> +    Status = StatusDRQReady (AtapiScsiPrivate, TimeoutInMicroSeconds);
> +    if (EFI_ERROR (Status)) {
> +      *ByteCount = ActualWordCount * 2;
> +
> +      AtapiPassThruCheckErrorStatus (AtapiScsiPrivate);
> +
> +      if (ActualWordCount == 0) {
> +        return EFI_DEVICE_ERROR;
> +      }
> +      //
> +      // ActualWordCount > 0
> +      //
> +      if (ActualWordCount < RequiredWordCount) {
> +        return EFI_BAD_BUFFER_SIZE;
> +      }
> +    }
> +    //
> +    // get current data transfer size from Cylinder Registers.
> +    //
> +    WordCount = ReadPortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate-
> >IoPort->CylinderMsb) << 8;
> +    WordCount = WordCount | ReadPortB (AtapiScsiPrivate->PciIo,
> AtapiScsiPrivate->IoPort->CylinderLsb);
> +    WordCount = WordCount & 0xffff;
> +    WordCount /= 2;
> +
> +    //
> +    // perform a series data In/Out.
> +    //
> +    for (Index = 0; (Index < WordCount) && (ActualWordCount <
> RequiredWordCount); Index++, ActualWordCount++) {
> +
> +      if (Direction == DataIn) {
> +
> +        *ptrBuffer = ReadPortW (AtapiScsiPrivate->PciIo, AtapiScsiPrivate-
> >IoPort->Data);
> +      } else {
> +
> +        WritePortW (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Data,
> *ptrBuffer);
> +      }
> +
> +      ptrBuffer++;
> +
> +    }
> +  }
> +  //
> +  // After data transfer is completed, normally, DRQ bit should clear.
> +  //
> +  StatusDRQClear (AtapiScsiPrivate, TimeoutInMicroSeconds);
> +
> +  //
> +  // read status register to check whether error happens.
> +  //
> +  Status      = AtapiPassThruCheckErrorStatus (AtapiScsiPrivate);
> +
> +  *ByteCount  = ActualWordCount * 2;
> +
> +  return Status;
> +}
> +
> +
> +UINT8
> +ReadPortB (
> +  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
> +  IN  UINT16                Port
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Read one byte from a specified I/O port.
> +
> +Arguments:
> +
> +  PciIo      - The pointer of EFI_PCI_IO_PROTOCOL
> +  Port       - IO port
> +
> +Returns:
> +
> +  A byte read out
> +
> +--*/
> +{
> +  UINT8 Data;
> +
> +  Data = 0;
> +  PciIo->Io.Read (
> +              PciIo,
> +              EfiPciIoWidthUint8,
> +              EFI_PCI_IO_PASS_THROUGH_BAR,
> +              (UINT64) Port,
> +              1,
> +              &Data
> +              );
> +  return Data;
> +}
> +
> +
> +UINT16
> +ReadPortW (
> +  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
> +  IN  UINT16                Port
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Read one word from a specified I/O port.
> +
> +Arguments:
> +
> +  PciIo      - The pointer of EFI_PCI_IO_PROTOCOL
> +  Port       - IO port
> +
> +Returns:
> +
> +  A word read out
> +--*/
> +{
> +  UINT16  Data;
> +
> +  Data = 0;
> +  PciIo->Io.Read (
> +              PciIo,
> +              EfiPciIoWidthUint16,
> +              EFI_PCI_IO_PASS_THROUGH_BAR,
> +              (UINT64) Port,
> +              1,
> +              &Data
> +              );
> +  return Data;
> +}
> +
> +
> +VOID
> +WritePortB (
> +  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
> +  IN  UINT16                Port,
> +  IN  UINT8                 Data
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Write one byte to a specified I/O port.
> +
> +Arguments:
> +
> +  PciIo      - The pointer of EFI_PCI_IO_PROTOCOL
> +  Port       - IO port
> +  Data       - The data to write
> +
> +Returns:
> +
> +   NONE
> +
> +--*/
> +{
> +  PciIo->Io.Write (
> +              PciIo,
> +              EfiPciIoWidthUint8,
> +              EFI_PCI_IO_PASS_THROUGH_BAR,
> +              (UINT64) Port,
> +              1,
> +              &Data
> +              );
> +}
> +
> +
> +VOID
> +WritePortW (
> +  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
> +  IN  UINT16                Port,
> +  IN  UINT16                Data
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Write one word to a specified I/O port.
> +
> +Arguments:
> +
> +  PciIo      - The pointer of EFI_PCI_IO_PROTOCOL
> +  Port       - IO port
> +  Data       - The data to write
> +
> +Returns:
> +
> +   NONE
> +
> +--*/
> +{
> +  PciIo->Io.Write (
> +              PciIo,
> +              EfiPciIoWidthUint16,
> +              EFI_PCI_IO_PASS_THROUGH_BAR,
> +              (UINT64) Port,
> +              1,
> +              &Data
> +              );
> +}
> +
> +EFI_STATUS
> +StatusDRQClear (
> +  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,
> +  UINT64                          TimeoutInMicroSeconds
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Check whether DRQ is clear in the Status Register. (BSY must also be
> cleared)
> +  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
> +  DRQ clear. Otherwise, it will return EFI_TIMEOUT when specified time is
> +  elapsed.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
> +  TimeoutInMicroSeconds       - The time to wait for
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +{
> +  UINT64  Delay;
> +  UINT8   StatusRegister;
> +  UINT8   ErrRegister;
> +
> +  if (TimeoutInMicroSeconds == 0) {
> +    Delay = 2;
> +  } else {
> +    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
> +  }
> +
> +  do {
> +
> +    StatusRegister = ReadPortB (
> +                      AtapiScsiPrivate->PciIo,
> +                      AtapiScsiPrivate->IoPort->Reg.Status
> +                      );
> +
> +    //
> +    // wait for BSY == 0 and DRQ == 0
> +    //
> +    if ((StatusRegister & (DRQ | BSY)) == 0) {
> +      break;
> +    }
> +    //
> +    // check whether the command is aborted by the device
> +    //
> +    if ((StatusRegister & (BSY | ERR)) == ERR) {
> +
> +      ErrRegister = ReadPortB (
> +                      AtapiScsiPrivate->PciIo,
> +                      AtapiScsiPrivate->IoPort->Reg1.Error
> +                      );
> +      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {
> +
> +        return EFI_ABORTED;
> +      }
> +    }
> +    //
> +    //  Stall for 30 us
> +    //
> +    gBS->Stall (30);
> +
> +    //
> +    // Loop infinitely if not meeting expected condition
> +    //
> +    if (TimeoutInMicroSeconds == 0) {
> +      Delay = 2;
> +    }
> +
> +    Delay--;
> +  } while (Delay);
> +
> +  if (Delay == 0) {
> +    return EFI_TIMEOUT;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +AltStatusDRQClear (
> +  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,
> +  UINT64                          TimeoutInMicroSeconds
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Check whether DRQ is clear in the Alternate Status Register.
> +  (BSY must also be cleared).If TimeoutInMicroSeconds is zero, this routine
> should
> +  wait infinitely for DRQ clear. Otherwise, it will return EFI_TIMEOUT when
> specified time is
> +  elapsed.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
> +  TimeoutInMicroSeconds       - The time to wait for
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +{
> +  UINT64  Delay;
> +  UINT8   AltStatusRegister;
> +  UINT8   ErrRegister;
> +
> +  if (TimeoutInMicroSeconds == 0) {
> +    Delay = 2;
> +  } else {
> +    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
> +  }
> +
> +  do {
> +
> +    AltStatusRegister = ReadPortB (
> +                          AtapiScsiPrivate->PciIo,
> +                          AtapiScsiPrivate->IoPort->Alt.AltStatus
> +                          );
> +
> +    //
> +    // wait for BSY == 0 and DRQ == 0
> +    //
> +    if ((AltStatusRegister & (DRQ | BSY)) == 0) {
> +      break;
> +    }
> +
> +    if ((AltStatusRegister & (BSY | ERR)) == ERR) {
> +
> +      ErrRegister = ReadPortB (
> +                      AtapiScsiPrivate->PciIo,
> +                      AtapiScsiPrivate->IoPort->Reg1.Error
> +                      );
> +      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {
> +
> +        return EFI_ABORTED;
> +      }
> +    }
> +    //
> +    //  Stall for 30 us
> +    //
> +    gBS->Stall (30);
> +
> +    //
> +    // Loop infinitely if not meeting expected condition
> +    //
> +    if (TimeoutInMicroSeconds == 0) {
> +      Delay = 2;
> +    }
> +
> +    Delay--;
> +  } while (Delay);
> +
> +  if (Delay == 0) {
> +    return EFI_TIMEOUT;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +StatusDRQReady (
> +  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,
> +  UINT64                          TimeoutInMicroSeconds
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Check whether DRQ is ready in the Status Register. (BSY must also be
> cleared)
> +  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
> +  DRQ ready. Otherwise, it will return EFI_TIMEOUT when specified time is
> +  elapsed.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
> +  TimeoutInMicroSeconds       - The time to wait for
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +{
> +  UINT64  Delay;
> +  UINT8   StatusRegister;
> +  UINT8   ErrRegister;
> +
> +  if (TimeoutInMicroSeconds == 0) {
> +    Delay = 2;
> +  } else {
> +    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
> +  }
> +
> +  do {
> +    //
> +    //  read Status Register will clear interrupt
> +    //
> +    StatusRegister = ReadPortB (
> +                      AtapiScsiPrivate->PciIo,
> +                      AtapiScsiPrivate->IoPort->Reg.Status
> +                      );
> +
> +    //
> +    //  BSY==0,DRQ==1
> +    //
> +    if ((StatusRegister & (BSY | DRQ)) == DRQ) {
> +      break;
> +    }
> +
> +    if ((StatusRegister & (BSY | ERR)) == ERR) {
> +
> +      ErrRegister = ReadPortB (
> +                      AtapiScsiPrivate->PciIo,
> +                      AtapiScsiPrivate->IoPort->Reg1.Error
> +                      );
> +      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {
> +        return EFI_ABORTED;
> +      }
> +    }
> +
> +    //
> +    // Stall for 30 us
> +    //
> +    gBS->Stall (30);
> +
> +    //
> +    // Loop infinitely if not meeting expected condition
> +    //
> +    if (TimeoutInMicroSeconds == 0) {
> +      Delay = 2;
> +    }
> +
> +    Delay--;
> +  } while (Delay);
> +
> +  if (Delay == 0) {
> +    return EFI_TIMEOUT;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +AltStatusDRQReady (
> +  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,
> +  UINT64                          TimeoutInMicroSeconds
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Check whether DRQ is ready in the Alternate Status Register.
> +  (BSY must also be cleared)
> +  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
> +  DRQ ready. Otherwise, it will return EFI_TIMEOUT when specified time is
> +  elapsed.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
> +  TimeoutInMicroSeconds       - The time to wait for
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +{
> +  UINT64  Delay;
> +  UINT8   AltStatusRegister;
> +  UINT8   ErrRegister;
> +
> +  if (TimeoutInMicroSeconds == 0) {
> +    Delay = 2;
> +  } else {
> +    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
> +  }
> +
> +  do {
> +    //
> +    //  read Status Register will clear interrupt
> +    //
> +    AltStatusRegister = ReadPortB (
> +                          AtapiScsiPrivate->PciIo,
> +                          AtapiScsiPrivate->IoPort->Alt.AltStatus
> +                          );
> +    //
> +    //  BSY==0,DRQ==1
> +    //
> +    if ((AltStatusRegister & (BSY | DRQ)) == DRQ) {
> +      break;
> +    }
> +
> +    if ((AltStatusRegister & (BSY | ERR)) == ERR) {
> +
> +      ErrRegister = ReadPortB (
> +                      AtapiScsiPrivate->PciIo,
> +                      AtapiScsiPrivate->IoPort->Reg1.Error
> +                      );
> +      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {
> +        return EFI_ABORTED;
> +      }
> +    }
> +
> +    //
> +    // Stall for 30 us
> +    //
> +    gBS->Stall (30);
> +
> +    //
> +    // Loop infinitely if not meeting expected condition
> +    //
> +    if (TimeoutInMicroSeconds == 0) {
> +      Delay = 2;
> +    }
> +
> +    Delay--;
> +  } while (Delay);
> +
> +  if (Delay == 0) {
> +    return EFI_TIMEOUT;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +StatusWaitForBSYClear (
> +  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,
> +  UINT64                      TimeoutInMicroSeconds
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Check whether BSY is clear in the Status Register.
> +  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
> +  BSY clear. Otherwise, it will return EFI_TIMEOUT when specified time is
> +  elapsed.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
> +  TimeoutInMicroSeconds       - The time to wait for
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +{
> +  UINT64  Delay;
> +  UINT8   StatusRegister;
> +
> +  if (TimeoutInMicroSeconds == 0) {
> +    Delay = 2;
> +  } else {
> +    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
> +  }
> +
> +  do {
> +
> +    StatusRegister = ReadPortB (
> +                      AtapiScsiPrivate->PciIo,
> +                      AtapiScsiPrivate->IoPort->Reg.Status
> +                      );
> +    if ((StatusRegister & BSY) == 0x00) {
> +      break;
> +    }
> +
> +    //
> +    // Stall for 30 us
> +    //
> +    gBS->Stall (30);
> +
> +    //
> +    // Loop infinitely if not meeting expected condition
> +    //
> +    if (TimeoutInMicroSeconds == 0) {
> +      Delay = 2;
> +    }
> +
> +    Delay--;
> +  } while (Delay);
> +
> +  if (Delay == 0) {
> +    return EFI_TIMEOUT;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +AltStatusWaitForBSYClear (
> +  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,
> +  UINT64                      TimeoutInMicroSeconds
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Check whether BSY is clear in the Alternate Status Register.
> +  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
> +  BSY clear. Otherwise, it will return EFI_TIMEOUT when specified time is
> +  elapsed.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
> +  TimeoutInMicroSeconds       - The time to wait for
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +{
> +  UINT64  Delay;
> +  UINT8   AltStatusRegister;
> +
> +  if (TimeoutInMicroSeconds == 0) {
> +    Delay = 2;
> +  } else {
> +    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
> +  }
> +
> +  do {
> +
> +    AltStatusRegister = ReadPortB (
> +                          AtapiScsiPrivate->PciIo,
> +                          AtapiScsiPrivate->IoPort->Alt.AltStatus
> +                          );
> +    if ((AltStatusRegister & BSY) == 0x00) {
> +      break;
> +    }
> +
> +    //
> +    // Stall for 30 us
> +    //
> +    gBS->Stall (30);
> +    //
> +    // Loop infinitely if not meeting expected condition
> +    //
> +    if (TimeoutInMicroSeconds == 0) {
> +      Delay = 2;
> +    }
> +
> +    Delay--;
> +  } while (Delay);
> +
> +  if (Delay == 0) {
> +    return EFI_TIMEOUT;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +StatusDRDYReady (
> +  ATAPI_SCSI_PASS_THRU_DEV     *AtapiScsiPrivate,
> +  UINT64                       TimeoutInMicroSeconds
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Check whether DRDY is ready in the Status Register.
> +  (BSY must also be cleared)
> +  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
> +  DRDY ready. Otherwise, it will return EFI_TIMEOUT when specified time is
> +  elapsed.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
> +  TimeoutInMicroSeconds       - The time to wait for
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +{
> +  UINT64  Delay;
> +  UINT8   StatusRegister;
> +  UINT8   ErrRegister;
> +
> +  if (TimeoutInMicroSeconds == 0) {
> +    Delay = 2;
> +  } else {
> +    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
> +  }
> +
> +  do {
> +    StatusRegister = ReadPortB (
> +                      AtapiScsiPrivate->PciIo,
> +                      AtapiScsiPrivate->IoPort->Reg.Status
> +                      );
> +    //
> +    //  BSY == 0 , DRDY == 1
> +    //
> +    if ((StatusRegister & (DRDY | BSY)) == DRDY) {
> +      break;
> +    }
> +
> +    if ((StatusRegister & (BSY | ERR)) == ERR) {
> +
> +      ErrRegister = ReadPortB (
> +                      AtapiScsiPrivate->PciIo,
> +                      AtapiScsiPrivate->IoPort->Reg1.Error
> +                      );
> +      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {
> +        return EFI_ABORTED;
> +      }
> +    }
> +
> +    //
> +    // Stall for 30 us
> +    //
> +    gBS->Stall (30);
> +    //
> +    // Loop infinitely if not meeting expected condition
> +    //
> +    if (TimeoutInMicroSeconds == 0) {
> +      Delay = 2;
> +    }
> +
> +    Delay--;
> +  } while (Delay);
> +
> +  if (Delay == 0) {
> +    return EFI_TIMEOUT;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +AltStatusDRDYReady (
> +  ATAPI_SCSI_PASS_THRU_DEV     *AtapiScsiPrivate,
> +  UINT64                       TimeoutInMicroSeconds
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Check whether DRDY is ready in the Alternate Status Register.
> +  (BSY must also be cleared)
> +  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
> +  DRDY ready. Otherwise, it will return EFI_TIMEOUT when specified time is
> +  elapsed.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
> +  TimeoutInMicroSeconds       - The time to wait for
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +{
> +  UINT64  Delay;
> +  UINT8   AltStatusRegister;
> +  UINT8   ErrRegister;
> +
> +  if (TimeoutInMicroSeconds == 0) {
> +    Delay = 2;
> +  } else {
> +    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
> +  }
> +
> +  do {
> +    AltStatusRegister = ReadPortB (
> +                          AtapiScsiPrivate->PciIo,
> +                          AtapiScsiPrivate->IoPort->Alt.AltStatus
> +                          );
> +    //
> +    //  BSY == 0 , DRDY == 1
> +    //
> +    if ((AltStatusRegister & (DRDY | BSY)) == DRDY) {
> +      break;
> +    }
> +
> +    if ((AltStatusRegister & (BSY | ERR)) == ERR) {
> +
> +      ErrRegister = ReadPortB (
> +                      AtapiScsiPrivate->PciIo,
> +                      AtapiScsiPrivate->IoPort->Reg1.Error
> +                      );
> +      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {
> +        return EFI_ABORTED;
> +      }
> +    }
> +
> +    //
> +    // Stall for 30 us
> +    //
> +    gBS->Stall (30);
> +    //
> +    // Loop infinitely if not meeting expected condition
> +    //
> +    if (TimeoutInMicroSeconds == 0) {
> +      Delay = 2;
> +    }
> +
> +    Delay--;
> +  } while (Delay);
> +
> +  if (Delay == 0) {
> +    return EFI_TIMEOUT;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +AtapiPassThruCheckErrorStatus (
> +  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Check Error Register for Error Information.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +{
> +  UINT8 StatusRegister;
> +  UINT8 ErrorRegister;
> +
> +  StatusRegister = ReadPortB (
> +                    AtapiScsiPrivate->PciIo,
> +                    AtapiScsiPrivate->IoPort->Reg.Status
> +                    );
> +
> +  DEBUG_CODE_BEGIN ();
> +
> +    if (StatusRegister & DWF) {
> +      DEBUG (
> +        (EFI_D_BLKIO,
> +        "AtapiPassThruCheckErrorStatus()-- %02x : Error : Write Fault\n",
> +        StatusRegister)
> +        );
> +    }
> +
> +    if (StatusRegister & CORR) {
> +      DEBUG (
> +        (EFI_D_BLKIO,
> +        "AtapiPassThruCheckErrorStatus()-- %02x : Error : Corrected Data\n",
> +        StatusRegister)
> +        );
> +    }
> +
> +    if (StatusRegister & ERR) {
> +      ErrorRegister = ReadPortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate-
> >IoPort->Reg1.Error);
> +
> +
> +      if (ErrorRegister & BBK_ERR) {
> +        DEBUG (
> +          (EFI_D_BLKIO,
> +          "AtapiPassThruCheckErrorStatus()-- %02x : Error : Bad Block
> Detected\n",
> +          ErrorRegister)
> +          );
> +      }
> +
> +      if (ErrorRegister & UNC_ERR) {
> +        DEBUG (
> +          (EFI_D_BLKIO,
> +          "AtapiPassThruCheckErrorStatus()-- %02x : Error : Uncorrectable
> Data\n",
> +          ErrorRegister)
> +          );
> +      }
> +
> +      if (ErrorRegister & MC_ERR) {
> +        DEBUG (
> +          (EFI_D_BLKIO,
> +          "AtapiPassThruCheckErrorStatus()-- %02x : Error : Media Change\n",
> +          ErrorRegister)
> +          );
> +      }
> +
> +      if (ErrorRegister & ABRT_ERR) {
> +        DEBUG (
> +          (EFI_D_BLKIO,
> +          "AtapiPassThruCheckErrorStatus()-- %02x : Error : Abort\n",
> +          ErrorRegister)
> +          );
> +      }
> +
> +      if (ErrorRegister & TK0NF_ERR) {
> +        DEBUG (
> +          (EFI_D_BLKIO,
> +          "AtapiPassThruCheckErrorStatus()-- %02x : Error : Track 0 Not
> Found\n",
> +          ErrorRegister)
> +          );
> +      }
> +
> +      if (ErrorRegister & AMNF_ERR) {
> +        DEBUG (
> +          (EFI_D_BLKIO,
> +          "AtapiPassThruCheckErrorStatus()-- %02x : Error : Address Mark Not
> Found\n",
> +          ErrorRegister)
> +          );
> +       }
> +    }
> +
> +  DEBUG_CODE_END ();
> +
> +  if ((StatusRegister & (ERR | DWF | CORR)) == 0) {
> +    return EFI_SUCCESS;
> +  }
> +
> +
> +  return EFI_DEVICE_ERROR;
> +}
> +
> +
> +/**
> +  Installs Scsi Pass Thru and/or Ext Scsi Pass Thru
> +  protocols based on feature flags.
> +
> +  @param Controller         The controller handle to
> +                            install these protocols on.
> +  @param AtapiScsiPrivate   A pointer to the protocol private
> +                            data structure.
> +
> +  @retval EFI_SUCCESS       The installation succeeds.
> +  @retval other             The installation fails.
> +
> +**/
> +EFI_STATUS
> +InstallScsiPassThruProtocols (
> +  IN EFI_HANDLE                     *ControllerHandle,
> +  IN ATAPI_SCSI_PASS_THRU_DEV       *AtapiScsiPrivate
> +  )
> +{
> +  EFI_STATUS                        Status;
> +  EFI_SCSI_PASS_THRU_PROTOCOL       *ScsiPassThru;
> +  EFI_EXT_SCSI_PASS_THRU_PROTOCOL   *ExtScsiPassThru;
> +
> +  ScsiPassThru = &AtapiScsiPrivate->ScsiPassThru;
> +  ExtScsiPassThru = &AtapiScsiPrivate->ExtScsiPassThru;
> +
> +  if (FeaturePcdGet (PcdSupportScsiPassThru)) {
> +    ScsiPassThru = CopyMem (ScsiPassThru, &gScsiPassThruProtocolTemplate,
> sizeof (*ScsiPassThru));
> +    if (FeaturePcdGet (PcdSupportExtScsiPassThru)) {
> +      ExtScsiPassThru = CopyMem (ExtScsiPassThru,
> &gExtScsiPassThruProtocolTemplate, sizeof (*ExtScsiPassThru));
> +      Status = gBS->InstallMultipleProtocolInterfaces (
> +                      ControllerHandle,
> +                      &gEfiScsiPassThruProtocolGuid,
> +                      ScsiPassThru,
> +                      &gEfiExtScsiPassThruProtocolGuid,
> +                      ExtScsiPassThru,
> +                      NULL
> +                      );
> +    } else {
> +      Status = gBS->InstallMultipleProtocolInterfaces (
> +                      ControllerHandle,
> +                      &gEfiScsiPassThruProtocolGuid,
> +                      ScsiPassThru,
> +                      NULL
> +                      );
> +    }
> +  } else {
> +    if (FeaturePcdGet (PcdSupportExtScsiPassThru)) {
> +      ExtScsiPassThru = CopyMem (ExtScsiPassThru,
> &gExtScsiPassThruProtocolTemplate, sizeof (*ExtScsiPassThru));
> +      Status = gBS->InstallMultipleProtocolInterfaces (
> +                      ControllerHandle,
> +                      &gEfiExtScsiPassThruProtocolGuid,
> +                      ExtScsiPassThru,
> +                      NULL
> +                      );
> +    } else {
> +      //
> +      // This driver must support either ScsiPassThru or
> +      // ExtScsiPassThru protocols
> +      //
> +      ASSERT (FALSE);
> +      Status = EFI_UNSUPPORTED;
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  The user Entry Point for module AtapiPassThru. The user code starts with
> this function.
> +
> +  @param[in] ImageHandle    The firmware allocated handle for the EFI
> image.
> +  @param[in] SystemTable    A pointer to the EFI System Table.
> +
> +  @retval EFI_SUCCESS       The entry point is executed successfully.
> +  @retval other             Some error occurs when executing this entry point.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitializeAtapiPassThru(
> +  IN EFI_HANDLE           ImageHandle,
> +  IN EFI_SYSTEM_TABLE     *SystemTable
> +  )
> +{
> +  EFI_STATUS              Status;
> +
> +  //
> +  // Install driver model protocol(s).
> +  //
> +  Status = EfiLibInstallDriverBindingComponentName2 (
> +             ImageHandle,
> +             SystemTable,
> +             &gAtapiScsiPassThruDriverBinding,
> +             ImageHandle,
> +             &gAtapiScsiPassThruComponentName,
> +             &gAtapiScsiPassThruComponentName2
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Install EFI Driver Supported EFI Version Protocol required for
> +  // EFI drivers that are on PCI and other plug in cards.
> +  //
> +  gAtapiScsiPassThruDriverSupportedEfiVersion.FirmwareVersion =
> PcdGet32 (PcdDriverSupportedEfiVersion);
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &ImageHandle,
> +                  &gEfiDriverSupportedEfiVersionProtocolGuid,
> +                  &gAtapiScsiPassThruDriverSupportedEfiVersion,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> diff --git a/Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.h
> b/Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.h
> new file mode 100644
> index 0000000000..9fca7b6ac2
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.h
> @@ -0,0 +1,1618 @@
> +/** @file
> +  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +  Module Name:  AtapiPassThru.h
> +
> +**/
> +
> +#ifndef _APT_H
> +#define _APT_H
> +
> +
> +
> +#include <Uefi.h>
> +
> +#include <Protocol/ScsiPassThru.h>
> +#include <Protocol/ScsiPassThruExt.h>
> +#include <Protocol/PciIo.h>
> +#include <Protocol/DriverSupportedEfiVersion.h>
> +
> +#include <Library/DebugLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/BaseLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/DevicePathLib.h>
> +
> +#include <IndustryStandard/Pci.h>
> +
> +#define MAX_TARGET_ID 4
> +
> +//
> +// IDE Registers
> +//
> +typedef union {
> +  UINT16  Command;        /* when write */
> +  UINT16  Status;         /* when read */
> +} IDE_CMD_OR_STATUS;
> +
> +typedef union {
> +  UINT16  Error;          /* when read */
> +  UINT16  Feature;        /* when write */
> +} IDE_ERROR_OR_FEATURE;
> +
> +typedef union {
> +  UINT16  AltStatus;      /* when read */
> +  UINT16  DeviceControl;  /* when write */
> +} IDE_AltStatus_OR_DeviceControl;
> +
> +
> +typedef enum {
> +  IdePrimary    = 0,
> +  IdeSecondary  = 1,
> +  IdeMaxChannel = 2
> +} EFI_IDE_CHANNEL;
> +
> +///
> +
> +
> +//
> +// Bit definitions in Programming Interface byte of the Class Code field
> +// in PCI IDE controller's Configuration Space
> +//
> +#define IDE_PRIMARY_OPERATING_MODE            BIT0
> +#define IDE_PRIMARY_PROGRAMMABLE_INDICATOR    BIT1
> +#define IDE_SECONDARY_OPERATING_MODE          BIT2
> +#define IDE_SECONDARY_PROGRAMMABLE_INDICATOR  BIT3
> +
> +
> +#define ATAPI_MAX_CHANNEL 2
> +
> +///
> +/// IDE registers set
> +///
> +typedef struct {
> +  UINT16                          Data;
> +  IDE_ERROR_OR_FEATURE            Reg1;
> +  UINT16                          SectorCount;
> +  UINT16                          SectorNumber;
> +  UINT16                          CylinderLsb;
> +  UINT16                          CylinderMsb;
> +  UINT16                          Head;
> +  IDE_CMD_OR_STATUS               Reg;
> +  IDE_AltStatus_OR_DeviceControl  Alt;
> +  UINT16                          DriveAddress;
> +} IDE_BASE_REGISTERS;
> +
> +#define ATAPI_SCSI_PASS_THRU_DEV_SIGNATURE  SIGNATURE_32 ('a', 's',
> 'p', 't')
> +
> +typedef struct {
> +  UINTN                            Signature;
> +  EFI_HANDLE                       Handle;
> +  EFI_SCSI_PASS_THRU_PROTOCOL      ScsiPassThru;
> +  EFI_EXT_SCSI_PASS_THRU_PROTOCOL  ExtScsiPassThru;
> +  EFI_PCI_IO_PROTOCOL              *PciIo;
> +  UINT64                           OriginalPciAttributes;
> +  //
> +  // Local Data goes here
> +  //
> +  IDE_BASE_REGISTERS               *IoPort;
> +  IDE_BASE_REGISTERS               AtapiIoPortRegisters[2];
> +  UINT32                           LatestTargetId;
> +  UINT64                           LatestLun;
> +} ATAPI_SCSI_PASS_THRU_DEV;
> +
> +//
> +// IDE registers' base addresses
> +//
> +typedef struct {
> +  UINT16  CommandBlockBaseAddr;
> +  UINT16  ControlBlockBaseAddr;
> +} IDE_REGISTERS_BASE_ADDR;
> +
> +#define ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS(a) \
> +  CR (a, \
> +      ATAPI_SCSI_PASS_THRU_DEV, \
> +      ScsiPassThru, \
> +      ATAPI_SCSI_PASS_THRU_DEV_SIGNATURE \
> +      )
> +
> +#define ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS(a) \
> +  CR (a, \
> +      ATAPI_SCSI_PASS_THRU_DEV, \
> +      ExtScsiPassThru, \
> +      ATAPI_SCSI_PASS_THRU_DEV_SIGNATURE \
> +      )
> +
> +//
> +// Global Variables
> +//
> +extern EFI_DRIVER_BINDING_PROTOCOL
> gAtapiScsiPassThruDriverBinding;
> +extern EFI_COMPONENT_NAME_PROTOCOL
> gAtapiScsiPassThruComponentName;
> +extern EFI_COMPONENT_NAME2_PROTOCOL
> gAtapiScsiPassThruComponentName2;
> +extern EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL
> gAtapiScsiPassThruDriverSupportedEfiVersion;
> +
> +//
> +// ATAPI Command op code
> +//
> +#define OP_INQUIRY                      0x12
> +#define OP_LOAD_UNLOAD_CD               0xa6
> +#define OP_MECHANISM_STATUS             0xbd
> +#define OP_MODE_SELECT_10               0x55
> +#define OP_MODE_SENSE_10                0x5a
> +#define OP_PAUSE_RESUME                 0x4b
> +#define OP_PLAY_AUDIO_10                0x45
> +#define OP_PLAY_AUDIO_MSF               0x47
> +#define OP_PLAY_CD                      0xbc
> +#define OP_PLAY_CD_MSF                  0xb4
> +#define OP_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
> +#define OP_READ_10                      0x28
> +#define OP_READ_12                      0xa8
> +#define OP_READ_CAPACITY                0x25
> +#define OP_READ_CD                      0xbe
> +#define OP_READ_CD_MSF                  0xb9
> +#define OP_READ_HEADER                  0x44
> +#define OP_READ_SUB_CHANNEL             0x42
> +#define OP_READ_TOC                     0x43
> +#define OP_REQUEST_SENSE                0x03
> +#define OP_SCAN                         0xba
> +#define OP_SEEK_10                      0x2b
> +#define OP_SET_CD_SPEED                 0xbb
> +#define OP_STOPPLAY_SCAN                0x4e
> +#define OP_START_STOP_UNIT              0x1b
> +#define OP_TEST_UNIT_READY              0x00
> +
> +#define OP_FORMAT_UNIT                  0x04
> +#define OP_READ_FORMAT_CAPACITIES       0x23
> +#define OP_VERIFY                       0x2f
> +#define OP_WRITE_10                     0x2a
> +#define OP_WRITE_12                     0xaa
> +#define OP_WRITE_AND_VERIFY             0x2e
> +
> +//
> +// ATA Command
> +//
> +#define ATAPI_SOFT_RESET_CMD  0x08
> +
> +typedef enum {
> +  DataIn  = 0,
> +  DataOut = 1,
> +  DataBi  = 2,
> +  NoData  = 3,
> +  End     = 0xff
> +} DATA_DIRECTION;
> +
> +typedef struct {
> +  UINT8           OpCode;
> +  DATA_DIRECTION  Direction;
> +} SCSI_COMMAND_SET;
> +
> +#define MAX_CHANNEL         2
> +
> +#define ValidCdbLength(Len) ((Len) == 6 || (Len) == 10 || (Len) == 12) ? 1 :
> 0
> +
> +//
> +// IDE registers bit definitions
> +//
> +// ATA Err Reg bitmap
> +//
> +#define BBK_ERR   BIT7 ///< Bad block detected
> +#define UNC_ERR   BIT6 ///< Uncorrectable Data
> +#define MC_ERR    BIT5 ///< Media Change
> +#define IDNF_ERR  BIT4 ///< ID Not Found
> +#define MCR_ERR   BIT3 ///< Media Change Requested
> +#define ABRT_ERR  BIT2 ///< Aborted Command
> +#define TK0NF_ERR BIT1 ///< Track 0 Not Found
> +#define AMNF_ERR  BIT0 ///< Address Mark Not Found
> +
> +//
> +// ATAPI Err Reg bitmap
> +//
> +#define SENSE_KEY_ERR (BIT7 | BIT6 | BIT5 | BIT4)
> +#define EOM_ERR BIT1 ///< End of Media Detected
> +#define ILI_ERR BIT0 ///< Illegal Length Indication
> +
> +//
> +// Device/Head Reg
> +//
> +#define LBA_MODE  BIT6
> +#define DEV       BIT4
> +#define HS3       BIT3
> +#define HS2       BIT2
> +#define HS1       BIT1
> +#define HS0       BIT0
> +#define CHS_MODE  (0)
> +#define DRV0      (0)
> +#define DRV1      (1)
> +#define MST_DRV   DRV0
> +#define SLV_DRV   DRV1
> +
> +//
> +// Status Reg
> +//
> +#define BSY   BIT7 ///< Controller Busy
> +#define DRDY  BIT6 ///< Drive Ready
> +#define DWF   BIT5 ///< Drive Write Fault
> +#define DSC   BIT4 ///< Disk Seek Complete
> +#define DRQ   BIT3 ///< Data Request
> +#define CORR  BIT2 ///< Corrected Data
> +#define IDX   BIT1 ///< Index
> +#define ERR   BIT0 ///< Error
> +#define CHECK BIT0 ///< Check bit for ATAPI Status Reg
> +
> +//
> +// Device Control Reg
> +//
> +#define SRST  BIT2 ///< Software Reset
> +#define IEN_L BIT1 ///< Interrupt Enable
> +
> +//
> +// ATAPI Feature Register
> +//
> +#define OVERLAP BIT1
> +#define DMA     BIT0
> +
> +//
> +// ATAPI Interrupt Reason Reson Reg (ATA Sector Count Register)
> +//
> +#define RELEASE     BIT2
> +#define IO          BIT1
> +#define CoD         BIT0
> +
> +#define PACKET_CMD  0xA0
> +
> +#define DEFAULT_CMD (0xa0)
> +//
> +// default content of device control register, disable INT
> +//
> +#define DEFAULT_CTL           (0x0a)
> +#define MAX_ATAPI_BYTE_COUNT  (0xfffe)
> +
> +//
> +// function prototype
> +//
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiScsiPassThruDriverBindingSupported (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiScsiPassThruDriverBindingStart (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiScsiPassThruDriverBindingStop (
> +  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
> +  IN  EFI_HANDLE                      Controller,
> +  IN  UINTN                           NumberOfChildren,
> +  IN  EFI_HANDLE                      *ChildHandleBuffer
> +  );
> +
> +//
> +// EFI Component Name Functions
> +//
> +/**
> +  Retrieves a Unicode string that is the user readable name of the driver.
> +
> +  This function retrieves the user readable name of a driver in the form of a
> +  Unicode string. If the driver specified by This has a user readable name in
> +  the language specified by Language, then a pointer to the driver name is
> +  returned in DriverName, and EFI_SUCCESS is returned. If the driver
> specified
> +  by This does not support the language specified by Language,
> +  then EFI_UNSUPPORTED is returned.
> +
> +  @param  This[in]              A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> +                                array indicating the language. This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified
> +                                in RFC 4646 or ISO 639-2 language code format.
> +
> +  @param  DriverName[out]       A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                driver specified by This in the language
> +                                specified by Language.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> +                                This and the language specified by Language was
> +                                returned in DriverName.
> +
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AtapiScsiPassThruComponentNameGetDriverName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
> +  IN  CHAR8                        *Language,
> +  OUT CHAR16                       **DriverName
> +  );
> +
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the controller
> +  that is being managed by a driver.
> +
> +  This function retrieves the user readable name of the controller specified
> by
> +  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> +  driver specified by This has a user readable name in the language specified
> by
> +  Language, then a pointer to the controller name is returned in
> ControllerName,
> +  and EFI_SUCCESS is returned.  If the driver specified by This is not
> currently
> +  managing the controller specified by ControllerHandle and ChildHandle,
> +  then EFI_UNSUPPORTED is returned.  If the driver specified by This does
> not
> +  support the language specified by Language, then EFI_UNSUPPORTED is
> returned.
> +
> +  @param  This[in]              A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> +  @param  ControllerHandle[in]  The handle of a controller that the driver
> +                                specified by This is managing.  This handle
> +                                specifies the controller whose name is to be
> +                                returned.
> +
> +  @param  ChildHandle[in]       The handle of the child controller to retrieve
> +                                the name of.  This is an optional parameter that
> +                                may be NULL.  It will be NULL for device
> +                                drivers.  It will also be NULL for a bus drivers
> +                                that wish to retrieve the name of the bus
> +                                controller.  It will not be NULL for a bus
> +                                driver that wishes to retrieve the name of a
> +                                child controller.
> +
> +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> +                                array indicating the language.  This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified in
> +                                RFC 4646 or ISO 639-2 language code format.
> +
> +  @param  ControllerName[out]   A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                controller specified by ControllerHandle and
> +                                ChildHandle in the language specified by
> +                                Language from the point of view of the driver
> +                                specified by This.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the user readable name
> in
> +                                the language specified by Language for the
> +                                driver specified by This was returned in
> +                                DriverName.
> +
> +  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a
> valid
> +                                EFI_HANDLE.
> +
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> +                                managing the controller specified by
> +                                ControllerHandle and ChildHandle.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AtapiScsiPassThruComponentNameGetControllerName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
> +  IN  EFI_HANDLE                                      ControllerHandle,
> +  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
> +  IN  CHAR8                                           *Language,
> +  OUT CHAR16                                          **ControllerName
> +  );
> +
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiScsiPassThruDriverEntryPoint (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  )
> + /*++
> +
> +Routine Description:
> +
> +  Entry point for EFI drivers.
> +
> +Arguments:
> +
> +  ImageHandle - EFI_HANDLE
> +  SystemTable - EFI_SYSTEM_TABLE
> +
> +Returns:
> +
> +  EFI_SUCCESS
> +  Others
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +RegisterAtapiScsiPassThru (
> +  IN  EFI_DRIVER_BINDING_PROTOCOL *This,
> +  IN  EFI_HANDLE                  Controller,
> +  IN  EFI_PCI_IO_PROTOCOL         *PciIo,
> +  IN  UINT64                      OriginalPciAttributes
> +  )
> +/*++
> +
> +Routine Description:
> +  Attaches SCSI Pass Thru Protocol for specified IDE channel.
> +
> +Arguments:
> +  This              - Protocol instance pointer.
> +  Controller        - Parent device handle to the IDE channel.
> +  PciIo             - PCI I/O protocol attached on the "Controller".
> +
> +Returns:
> +  Always return EFI_SUCCESS unless installing SCSI Pass Thru Protocol failed.
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiScsiPassThruFunction (
> +  IN EFI_SCSI_PASS_THRU_PROTOCOL                        *This,
> +  IN UINT32                                             Target,
> +  IN UINT64                                             Lun,
> +  IN OUT EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET         *Packet,
> +  IN EFI_EVENT                                          Event OPTIONAL
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Implements EFI_SCSI_PASS_THRU_PROTOCOL.PassThru() function.
> +
> +Arguments:
> +
> +  This:     The EFI_SCSI_PASS_THRU_PROTOCOL instance.
> +  Target:   The Target ID of the ATAPI device to send the SCSI
> +            Request Packet. To ATAPI devices attached on an IDE
> +            Channel, Target ID 0 indicates Master device;Target
> +            ID 1 indicates Slave device.
> +  Lun:      The LUN of the ATAPI device to send the SCSI Request
> +            Packet. To the ATAPI device, Lun is always 0.
> +  Packet:   The SCSI Request Packet to send to the ATAPI device
> +            specified by Target and Lun.
> +  Event:    If non-blocking I/O is not supported then Event is ignored,
> +            and blocking I/O is performed.
> +            If Event is NULL, then blocking I/O is performed.
> +            If Event is not NULL and non blocking I/O is supported,
> +            then non-blocking I/O is performed, and Event will be signaled
> +            when the SCSI Request Packet completes.
> +
> +Returns:
> +
> +   EFI_STATUS
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiScsiPassThruGetNextDevice (
> +  IN  EFI_SCSI_PASS_THRU_PROTOCOL    *This,
> +  IN OUT UINT32                      *Target,
> +  IN OUT UINT64                      *Lun
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Used to retrieve the list of legal Target IDs for SCSI devices
> +  on a SCSI channel.
> +
> +Arguments:
> +
> +  This                  - Protocol instance pointer.
> +  Target                - On input, a pointer to the Target ID of a SCSI
> +                          device present on the SCSI channel.  On output,
> +                          a pointer to the Target ID of the next SCSI device
> +                          present on a SCSI channel.  An input value of
> +                          0xFFFFFFFF retrieves the Target ID of the first
> +                          SCSI device present on a SCSI channel.
> +  Lun                   - On input, a pointer to the LUN of a SCSI device
> +                          present on the SCSI channel. On output, a pointer
> +                          to the LUN of the next SCSI device present on
> +                          a SCSI channel.
> +Returns:
> +
> +  EFI_SUCCESS           - The Target ID and Lun of the next SCSI device
> +                          on the SCSI channel was returned in Target and Lun.
> +  EFI_NOT_FOUND         - There are no more SCSI devices on this SCSI
> channel.
> +  EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun
> were not
> +                           returned on a previous call to GetNextDevice().
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiScsiPassThruBuildDevicePath (
> +  IN     EFI_SCSI_PASS_THRU_PROTOCOL    *This,
> +  IN     UINT32                         Target,
> +  IN     UINT64                         Lun,
> +  IN OUT EFI_DEVICE_PATH_PROTOCOL       **DevicePath
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Used to allocate and build a device path node for a SCSI device
> +  on a SCSI channel. Would not build device path for a SCSI Host Controller.
> +
> +Arguments:
> +
> +  This                  - Protocol instance pointer.
> +  Target                - The Target ID of the SCSI device for which
> +                          a device path node is to be allocated and built.
> +  Lun                   - The LUN of the SCSI device for which a device
> +                          path node is to be allocated and built.
> +  DevicePath            - A pointer to a single device path node that
> +                          describes the SCSI device specified by
> +                          Target and Lun. This function is responsible
> +                          for allocating the buffer DevicePath with the boot
> +                          service AllocatePool().  It is the caller's
> +                          responsibility to free DevicePath when the caller
> +                          is finished with DevicePath.
> +  Returns:
> +  EFI_SUCCESS           - The device path node that describes the SCSI device
> +                          specified by Target and Lun was allocated and
> +                          returned in DevicePath.
> +  EFI_NOT_FOUND         - The SCSI devices specified by Target and Lun does
> +                          not exist on the SCSI channel.
> +  EFI_INVALID_PARAMETER - DevicePath is NULL.
> +  EFI_OUT_OF_RESOURCES  - There are not enough resources to allocate
> +                          DevicePath.
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiScsiPassThruGetTargetLun (
> +  IN  EFI_SCSI_PASS_THRU_PROTOCOL    *This,
> +  IN  EFI_DEVICE_PATH_PROTOCOL       *DevicePath,
> +  OUT UINT32                         *Target,
> +  OUT UINT64                         *Lun
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Used to translate a device path node to a Target ID and LUN.
> +
> +Arguments:
> +
> +  This                  - Protocol instance pointer.
> +  DevicePath            - A pointer to the device path node that
> +                          describes a SCSI device on the SCSI channel.
> +  Target                - A pointer to the Target ID of a SCSI device
> +                          on the SCSI channel.
> +  Lun                   - A pointer to the LUN of a SCSI device on
> +                          the SCSI channel.
> +Returns:
> +
> +  EFI_SUCCESS           - DevicePath was successfully translated to a
> +                          Target ID and LUN, and they were returned
> +                          in Target and Lun.
> +  EFI_INVALID_PARAMETER - DevicePath/Target/Lun is NULL.
> +  EFI_UNSUPPORTED       - This driver does not support the device path
> +                          node type in DevicePath.
> +  EFI_NOT_FOUND         - A valid translation from DevicePath to a
> +                          Target ID and LUN does not exist.
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiScsiPassThruResetChannel (
> +  IN  EFI_SCSI_PASS_THRU_PROTOCOL   *This
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Resets a SCSI channel.This operation resets all the
> +  SCSI devices connected to the SCSI channel.
> +
> +Arguments:
> +
> +  This                  - Protocol instance pointer.
> +
> +Returns:
> +
> +  EFI_SUCCESS           - The SCSI channel was reset.
> +  EFI_UNSUPPORTED       - The SCSI channel does not support
> +                          a channel reset operation.
> +  EFI_DEVICE_ERROR      - A device error occurred while
> +                          attempting to reset the SCSI channel.
> +  EFI_TIMEOUT           - A timeout occurred while attempting
> +                          to reset the SCSI channel.
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiScsiPassThruResetTarget (
> +  IN EFI_SCSI_PASS_THRU_PROTOCOL    *This,
> +  IN UINT32                         Target,
> +  IN UINT64                         Lun
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Resets a SCSI device that is connected to a SCSI channel.
> +
> +Arguments:
> +
> +  This                  - Protocol instance pointer.
> +  Target                - The Target ID of the SCSI device to reset.
> +  Lun                   - The LUN of the SCSI device to reset.
> +
> +Returns:
> +
> +  EFI_SUCCESS           - The SCSI device specified by Target and
> +                          Lun was reset.
> +  EFI_UNSUPPORTED       - The SCSI channel does not support a target
> +                          reset operation.
> +  EFI_INVALID_PARAMETER - Target or Lun are invalid.
> +  EFI_DEVICE_ERROR      - A device error occurred while attempting
> +                          to reset the SCSI device specified by Target
> +                          and Lun.
> +  EFI_TIMEOUT           - A timeout occurred while attempting to reset
> +                          the SCSI device specified by Target and Lun.
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiExtScsiPassThruFunction (
> +  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL                    *This,
> +  IN UINT8                                              *Target,
> +  IN UINT64                                             Lun,
> +  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET     *Packet,
> +  IN EFI_EVENT                                          Event OPTIONAL
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Implements EFI_EXT_SCSI_PASS_THRU_PROTOCOL.PassThru() function.
> +
> +Arguments:
> +
> +  This:     The EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
> +  Target:   The Target ID of the ATAPI device to send the SCSI
> +            Request Packet. To ATAPI devices attached on an IDE
> +            Channel, Target ID 0 indicates Master device;Target
> +            ID 1 indicates Slave device.
> +  Lun:      The LUN of the ATAPI device to send the SCSI Request
> +            Packet. To the ATAPI device, Lun is always 0.
> +  Packet:   The SCSI Request Packet to send to the ATAPI device
> +            specified by Target and Lun.
> +  Event:    If non-blocking I/O is not supported then Event is ignored,
> +            and blocking I/O is performed.
> +            If Event is NULL, then blocking I/O is performed.
> +            If Event is not NULL and non blocking I/O is supported,
> +            then non-blocking I/O is performed, and Event will be signaled
> +            when the SCSI Request Packet completes.
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiExtScsiPassThruGetNextTargetLun (
> +  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
> +  IN OUT UINT8                           **Target,
> +  IN OUT UINT64                          *Lun
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Used to retrieve the list of legal Target IDs for SCSI devices
> +  on a SCSI channel.
> +
> +Arguments:
> +
> +  This                  - Protocol instance pointer.
> +  Target                - On input, a pointer to the Target ID of a SCSI
> +                          device present on the SCSI channel.  On output,
> +                          a pointer to the Target ID of the next SCSI device
> +                          present on a SCSI channel.  An input value of
> +                          0xFFFFFFFF retrieves the Target ID of the first
> +                          SCSI device present on a SCSI channel.
> +  Lun                   - On input, a pointer to the LUN of a SCSI device
> +                          present on the SCSI channel. On output, a pointer
> +                          to the LUN of the next SCSI device present on
> +                          a SCSI channel.
> +Returns:
> +
> +  EFI_SUCCESS           - The Target ID and Lun of the next SCSI device
> +                          on the SCSI channel was returned in Target and Lun.
> +  EFI_NOT_FOUND         - There are no more SCSI devices on this SCSI
> channel.
> +  EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun
> were not
> +                           returned on a previous call to GetNextDevice().
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiExtScsiPassThruBuildDevicePath (
> +  IN     EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
> +  IN     UINT8                              *Target,
> +  IN     UINT64                             Lun,
> +  IN OUT EFI_DEVICE_PATH_PROTOCOL           **DevicePath
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Used to allocate and build a device path node for a SCSI device
> +  on a SCSI channel. Would not build device path for a SCSI Host Controller.
> +
> +Arguments:
> +
> +  This                  - Protocol instance pointer.
> +  Target                - The Target ID of the SCSI device for which
> +                          a device path node is to be allocated and built.
> +  Lun                   - The LUN of the SCSI device for which a device
> +                          path node is to be allocated and built.
> +  DevicePath            - A pointer to a single device path node that
> +                          describes the SCSI device specified by
> +                          Target and Lun. This function is responsible
> +                          for allocating the buffer DevicePath with the boot
> +                          service AllocatePool().  It is the caller's
> +                          responsibility to free DevicePath when the caller
> +                          is finished with DevicePath.
> +  Returns:
> +  EFI_SUCCESS           - The device path node that describes the SCSI device
> +                          specified by Target and Lun was allocated and
> +                          returned in DevicePath.
> +  EFI_NOT_FOUND         - The SCSI devices specified by Target and Lun does
> +                          not exist on the SCSI channel.
> +  EFI_INVALID_PARAMETER - DevicePath is NULL.
> +  EFI_OUT_OF_RESOURCES  - There are not enough resources to allocate
> +                          DevicePath.
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiExtScsiPassThruGetTargetLun (
> +  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
> +  IN  EFI_DEVICE_PATH_PROTOCOL       *DevicePath,
> +  OUT UINT8                          **Target,
> +  OUT UINT64                         *Lun
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Used to translate a device path node to a Target ID and LUN.
> +
> +Arguments:
> +
> +  This                  - Protocol instance pointer.
> +  DevicePath            - A pointer to the device path node that
> +                          describes a SCSI device on the SCSI channel.
> +  Target                - A pointer to the Target ID of a SCSI device
> +                          on the SCSI channel.
> +  Lun                   - A pointer to the LUN of a SCSI device on
> +                          the SCSI channel.
> +Returns:
> +
> +  EFI_SUCCESS           - DevicePath was successfully translated to a
> +                          Target ID and LUN, and they were returned
> +                          in Target and Lun.
> +  EFI_INVALID_PARAMETER - DevicePath/Target/Lun is NULL.
> +  EFI_UNSUPPORTED       - This driver does not support the device path
> +                          node type in DevicePath.
> +  EFI_NOT_FOUND         - A valid translation from DevicePath to a
> +                          Target ID and LUN does not exist.
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiExtScsiPassThruResetChannel (
> +  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL   *This
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Resets a SCSI channel.This operation resets all the
> +  SCSI devices connected to the SCSI channel.
> +
> +Arguments:
> +
> +  This                  - Protocol instance pointer.
> +
> +Returns:
> +
> +  EFI_SUCCESS           - The SCSI channel was reset.
> +  EFI_UNSUPPORTED       - The SCSI channel does not support
> +                          a channel reset operation.
> +  EFI_DEVICE_ERROR      - A device error occurred while
> +                          attempting to reset the SCSI channel.
> +  EFI_TIMEOUT           - A timeout occurred while attempting
> +                          to reset the SCSI channel.
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiExtScsiPassThruResetTarget (
> +  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
> +  IN UINT8                              *Target,
> +  IN UINT64                             Lun
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Resets a SCSI device that is connected to a SCSI channel.
> +
> +Arguments:
> +
> +  This                  - Protocol instance pointer.
> +  Target                - The Target ID of the SCSI device to reset.
> +  Lun                   - The LUN of the SCSI device to reset.
> +
> +Returns:
> +
> +  EFI_SUCCESS           - The SCSI device specified by Target and
> +                          Lun was reset.
> +  EFI_UNSUPPORTED       - The SCSI channel does not support a target
> +                          reset operation.
> +  EFI_INVALID_PARAMETER - Target or Lun are invalid.
> +  EFI_DEVICE_ERROR      - A device error occurred while attempting
> +                          to reset the SCSI device specified by Target
> +                          and Lun.
> +  EFI_TIMEOUT           - A timeout occurred while attempting to reset
> +                          the SCSI device specified by Target and Lun.
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +EFIAPI
> +AtapiExtScsiPassThruGetNextTarget (
> +  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL    *This,
> +  IN OUT UINT8                           **Target
> +  )
> +/*++
> +
> +Routine Description:
> +  Used to retrieve the list of legal Target IDs for SCSI devices
> +  on a SCSI channel.
> +
> +Arguments:
> +  This                  - Protocol instance pointer.
> +  Target                - On input, a pointer to the Target ID of a SCSI
> +                          device present on the SCSI channel.  On output,
> +                          a pointer to the Target ID of the next SCSI device
> +                           present on a SCSI channel.  An input value of
> +                           0xFFFFFFFF retrieves the Target ID of the first
> +                           SCSI device present on a SCSI channel.
> +  Lun                   - On input, a pointer to the LUN of a SCSI device
> +                          present on the SCSI channel. On output, a pointer
> +                          to the LUN of the next SCSI device present on
> +                          a SCSI channel.
> +
> +Returns:
> +  EFI_SUCCESS           - The Target ID and Lun of the next SCSI device
> +                          on the SCSI channel was returned in Target and Lun.
> +  EFI_NOT_FOUND         - There are no more SCSI devices on this SCSI
> channel.
> +  EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun
> were not
> +                          returned on a previous call to GetNextDevice().
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +CheckSCSIRequestPacket (
> +  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET      *Packet
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Checks the parameters in the SCSI Request Packet to make sure
> +  they are valid for a SCSI Pass Thru request.
> +
> +Arguments:
> +
> +  Packet         -  The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +SubmitBlockingIoCommand (
> +  ATAPI_SCSI_PASS_THRU_DEV                  *AtapiScsiPrivate,
> +  UINT32                                    Target,
> +  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET    *Packet
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Performs blocking I/O request.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate:   Private data structure for the specified channel.
> +  Target:             The Target ID of the ATAPI device to send the SCSI
> +                      Request Packet. To ATAPI devices attached on an IDE
> +                      Channel, Target ID 0 indicates Master device;Target
> +                      ID 1 indicates Slave device.
> +  Packet:             The SCSI Request Packet to send to the ATAPI device
> +                      specified by Target.
> +
> +  Returns:            EFI_STATUS
> +
> +--*/
> +;
> +
> +BOOLEAN
> +IsCommandValid (
> +  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET   *Packet
> +  )
> + /*++
> +
> +Routine Description:
> +
> +  Checks the requested SCSI command:
> +  Is it supported by this driver?
> +  Is the Data transfer direction reasonable?
> +
> +Arguments:
> +
> +  Packet         -  The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +CheckExtSCSIRequestPacket (
> +  EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET      *Packet
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Checks the parameters in the SCSI Request Packet to make sure
> +  they are valid for a SCSI Pass Thru request.
> +
> +Arguments:
> +
> +  Packet       - The pointer of
> EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +;
> +
> +
> +BOOLEAN
> +IsExtCommandValid (
> +  EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET   *Packet
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Checks the requested SCSI command:
> +  Is it supported by this driver?
> +  Is the Data transfer direction reasonable?
> +
> +Arguments:
> +
> +  Packet         -  The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +SubmitExtBlockingIoCommand (
> +  ATAPI_SCSI_PASS_THRU_DEV                      *AtapiScsiPrivate,
> +  UINT8                                         Target,
> +  EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET    *Packet
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Performs blocking I/O request.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate:   Private data structure for the specified channel.
> +  Target:             The Target ID of the ATAPI device to send the SCSI
> +                      Request Packet. To ATAPI devices attached on an IDE
> +                      Channel, Target ID 0 indicates Master device;Target
> +                      ID 1 indicates Slave device.
> +  Packet:             The SCSI Request Packet to send to the ATAPI device
> +                      specified by Target.
> +
> +  Returns:            EFI_STATUS
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +RequestSenseCommand (
> +  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,
> +  UINT32                      Target,
> +  UINT64                      Timeout,
> +  VOID                        *SenseData,
> +  UINT8                       *SenseDataLength
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Submit request sense command
> +
> +Arguments:
> +
> +  AtapiScsiPrivate  - The pointer of ATAPI_SCSI_PASS_THRU_DEV
> +  Target            - The target ID
> +  Timeout           - The time to complete the command
> +  SenseData         - The buffer to fill in sense data
> +  SenseDataLength   - The length of buffer
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +AtapiPacketCommand (
> +  ATAPI_SCSI_PASS_THRU_DEV                  *AtapiScsiPrivate,
> +  UINT32                                    Target,
> +  UINT8                                     *PacketCommand,
> +  VOID                                      *Buffer,
> +  UINT32                                    *ByteCount,
> +  DATA_DIRECTION                            Direction,
> +  UINT64                                    TimeOutInMicroSeconds
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Submits ATAPI command packet to the specified ATAPI device.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate:   Private data structure for the specified channel.
> +  Target:             The Target ID of the ATAPI device to send the SCSI
> +                      Request Packet. To ATAPI devices attached on an IDE
> +                      Channel, Target ID 0 indicates Master device;Target
> +                      ID 1 indicates Slave device.
> +  PacketCommand:      Points to the ATAPI command packet.
> +  Buffer:             Points to the transferred data.
> +  ByteCount:          When input,indicates the buffer size; when output,
> +                      indicates the actually transferred data size.
> +  Direction:          Indicates the data transfer direction.
> +  TimeoutInMicroSeconds:
> +                      The timeout, in micro second units, to use for the
> +                      execution of this ATAPI command.
> +                      A TimeoutInMicroSeconds value of 0 means that
> +                      this function will wait indefinitely for the ATAPI
> +                      command to execute.
> +                      If TimeoutInMicroSeconds is greater than zero, then
> +                      this function will return EFI_TIMEOUT if the time
> +                      required to execute the ATAPI command is greater
> +                      than TimeoutInMicroSeconds.
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +;
> +
> +
> +UINT8
> +ReadPortB (
> +  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
> +  IN  UINT16                Port
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Read one byte from a specified I/O port.
> +
> +Arguments:
> +
> +  PciIo      - The pointer of EFI_PCI_IO_PROTOCOL
> +  Port       - IO port
> +
> +Returns:
> +
> +  A byte read out
> +
> +--*/
> +;
> +
> +
> +UINT16
> +ReadPortW (
> +  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
> +  IN  UINT16                Port
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Read one word from a specified I/O port.
> +
> +Arguments:
> +
> +  PciIo      - The pointer of EFI_PCI_IO_PROTOCOL
> +  Port       - IO port
> +
> +Returns:
> +
> +  A word read out
> +
> +--*/
> +;
> +
> +
> +VOID
> +WritePortB (
> +  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
> +  IN  UINT16                Port,
> +  IN  UINT8                 Data
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Write one byte to a specified I/O port.
> +
> +Arguments:
> +
> +  PciIo      - The pointer of EFI_PCI_IO_PROTOCOL
> +  Port       - IO port
> +  Data       - The data to write
> +
> +Returns:
> +
> +  NONE
> +
> +--*/
> +;
> +
> +
> +VOID
> +WritePortW (
> +  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
> +  IN  UINT16                Port,
> +  IN  UINT16                Data
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Write one word to a specified I/O port.
> +
> +Arguments:
> +
> +  PciIo      - The pointer of EFI_PCI_IO_PROTOCOL
> +  Port       - IO port
> +  Data       - The data to write
> +
> +Returns:
> +
> +  NONE
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +StatusDRQClear (
> +  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,
> +  UINT64                          TimeOutInMicroSeconds
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Check whether DRQ is clear in the Status Register. (BSY must also be
> cleared)
> +  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
> +  DRQ clear. Otherwise, it will return EFI_TIMEOUT when specified time is
> +  elapsed.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
> +  TimeoutInMicroSeconds       - The time to wait for
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +AltStatusDRQClear (
> +  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,
> +  UINT64                          TimeOutInMicroSeconds
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Check whether DRQ is clear in the Alternate Status Register.
> +  (BSY must also be cleared).If TimeoutInMicroSeconds is zero, this routine
> should
> +  wait infinitely for DRQ clear. Otherwise, it will return EFI_TIMEOUT when
> specified time is
> +  elapsed.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
> +  TimeoutInMicroSeconds       - The time to wait for
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +StatusDRQReady (
> +  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,
> +  UINT64                          TimeOutInMicroSeconds
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Check whether DRQ is ready in the Status Register. (BSY must also be
> cleared)
> +  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
> +  DRQ ready. Otherwise, it will return EFI_TIMEOUT when specified time is
> +  elapsed.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
> +  TimeoutInMicroSeconds       - The time to wait for
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +AltStatusDRQReady (
> +  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate,
> +  UINT64                          TimeOutInMicroSeconds
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Check whether DRQ is ready in the Alternate Status Register.
> +  (BSY must also be cleared)
> +  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
> +  DRQ ready. Otherwise, it will return EFI_TIMEOUT when specified time is
> +  elapsed.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
> +  TimeoutInMicroSeconds       - The time to wait for
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +StatusWaitForBSYClear (
> +  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,
> +  UINT64                      TimeoutInMicroSeconds
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Check whether BSY is clear in the Status Register.
> +  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
> +  BSY clear. Otherwise, it will return EFI_TIMEOUT when specified time is
> +  elapsed.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
> +  TimeoutInMicroSeconds       - The time to wait for
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +AltStatusWaitForBSYClear (
> +  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,
> +  UINT64                      TimeoutInMicroSeconds
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Check whether BSY is clear in the Alternate Status Register.
> +  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
> +  BSY clear. Otherwise, it will return EFI_TIMEOUT when specified time is
> +  elapsed.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
> +  TimeoutInMicroSeconds       - The time to wait for
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +StatusDRDYReady (
> +  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,
> +  UINT64                      TimeoutInMicroSeconds
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Check whether DRDY is ready in the Status Register.
> +  (BSY must also be cleared)
> +  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
> +  DRDY ready. Otherwise, it will return EFI_TIMEOUT when specified time is
> +  elapsed.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
> +  TimeoutInMicroSeconds       - The time to wait for
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +AltStatusDRDYReady (
> +  ATAPI_SCSI_PASS_THRU_DEV    *AtapiScsiPrivate,
> +  UINT64                      TimeoutInMicroSeconds
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Check whether DRDY is ready in the Alternate Status Register.
> +  (BSY must also be cleared)
> +  If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
> +  DRDY ready. Otherwise, it will return EFI_TIMEOUT when specified time is
> +  elapsed.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
> +  TimeoutInMicroSeconds       - The time to wait for
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +AtapiPassThruPioReadWriteData (
> +  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate,
> +  UINT16                    *Buffer,
> +  UINT32                    *ByteCount,
> +  DATA_DIRECTION            Direction,
> +  UINT64                    TimeOutInMicroSeconds
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Performs data transfer between ATAPI device and host after the
> +  ATAPI command packet is sent.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate:   Private data structure for the specified channel.
> +  Buffer:             Points to the transferred data.
> +  ByteCount:          When input,indicates the buffer size; when output,
> +                      indicates the actually transferred data size.
> +  Direction:          Indicates the data transfer direction.
> +  TimeoutInMicroSeconds:
> +                      The timeout, in micro second units, to use for the
> +                      execution of this ATAPI command.
> +                      A TimeoutInMicroSeconds value of 0 means that
> +                      this function will wait indefinitely for the ATAPI
> +                      command to execute.
> +                      If TimeoutInMicroSeconds is greater than zero, then
> +                      this function will return EFI_TIMEOUT if the time
> +                      required to execute the ATAPI command is greater
> +                      than TimeoutInMicroSeconds.
> + Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +;
> +
> +EFI_STATUS
> +AtapiPassThruCheckErrorStatus (
> +  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Check Error Register for Error Information.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +;
> +
> +
> +EFI_STATUS
> +GetIdeRegistersBaseAddr (
> +  IN  EFI_PCI_IO_PROTOCOL         *PciIo,
> +  OUT IDE_REGISTERS_BASE_ADDR     *IdeRegsBaseAddr
> +  )
> +/*++
> +
> +Routine Description:
> +  Get IDE IO port registers' base addresses by mode. In 'Compatibility' mode,
> +  use fixed addresses. In Native-PCI mode, get base addresses from BARs in
> +  the PCI IDE controller's Configuration Space.
> +
> +Arguments:
> +  PciIo             - Pointer to the EFI_PCI_IO_PROTOCOL instance
> +  IdeRegsBaseAddr   - Pointer to IDE_REGISTERS_BASE_ADDR to
> +                      receive IDE IO port registers' base addresses
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +;
> +
> +
> +VOID
> +InitAtapiIoPortRegisters (
> +  IN  ATAPI_SCSI_PASS_THRU_DEV     *AtapiScsiPrivate,
> +  IN  IDE_REGISTERS_BASE_ADDR      *IdeRegsBaseAddr
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Initialize each Channel's Base Address of CommandBlock and ControlBlock.
> +
> +Arguments:
> +
> +  AtapiScsiPrivate            - The pointer of ATAPI_SCSI_PASS_THRU_DEV
> +  IdeRegsBaseAddr             - The pointer of IDE_REGISTERS_BASE_ADDR
> +
> +Returns:
> +
> +  None
> +
> +--*/
> +;
> +
> +/**
> +  Installs Scsi Pass Thru and/or Ext Scsi Pass Thru
> +  protocols based on feature flags.
> +
> +  @param Controller         The controller handle to
> +                            install these protocols on.
> +  @param AtapiScsiPrivate   A pointer to the protocol private
> +                            data structure.
> +
> +  @retval EFI_SUCCESS       The installation succeeds.
> +  @retval other             The installation fails.
> +
> +**/
> +EFI_STATUS
> +InstallScsiPassThruProtocols (
> +  IN EFI_HANDLE                 *ControllerHandle,
> +  IN ATAPI_SCSI_PASS_THRU_DEV   *AtapiScsiPrivate
> +  );
> +
> +#endif
> diff --git a/Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThruDxe.inf
> b/Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThruDxe.inf
> new file mode 100644
> index 0000000000..750136275a
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThruDxe.inf
> @@ -0,0 +1,70 @@
> +## @file
> +# Description file for the Atapi Pass Thru driver.
> +#
> +# This driver simulates SCSI devices with Atapi devices to test the SCSI io
> +#  protocol.
> +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = AtapiPassThruDxe
> +  FILE_GUID                      = E49061CE-99A7-41d3-AB3A-36E5CFBAD63E
> +  MODULE_TYPE                    = UEFI_DRIVER
> +  VERSION_STRING                 = 1.0
> +
> +  ENTRY_POINT                    = InitializeAtapiPassThru
> +
> +  PCI_VENDOR_ID                  = 0x8086
> +  PCI_DEVICE_ID                  = 0x2921
> +  PCI_CLASS_CODE                 = 0x010100
> +  PCI_REVISION                   = 0x0003
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +#  DRIVER_BINDING                =  gAtapiScsiPassThruDriverBinding
> +#  COMPONENT_NAME                =  gAtapiScsiPassThruComponentName
> +#
> +
> +[Sources]
> +  DriverSupportedEfiVersion.c
> +  ComponentName.c
> +  AtapiPassThru.c
> +  AtapiPassThru.h
> +
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  OptionRomPkg/OptionRomPkg.dec
> +
> +[LibraryClasses]
> +  UefiBootServicesTableLib
> +  MemoryAllocationLib
> +  BaseMemoryLib
> +  UefiLib
> +  BaseLib
> +  UefiDriverEntryPoint
> +  DebugLib
> +  DevicePathLib
> +
> +
> +[Protocols]
> +  gEfiScsiPassThruProtocolGuid                  # PROTOCOL BY_START
> +  gEfiExtScsiPassThruProtocolGuid               # PROTOCOL BY_START
> +  gEfiPciIoProtocolGuid                         # PROTOCOL TO_START
> +  gEfiDriverSupportedEfiVersionProtocolGuid     # PROTOCOL
> ALWAYS_PRODUCED
> +
> +[FeaturePcd]
> +  gOptionRomPkgTokenSpaceGuid.PcdSupportScsiPassThru
> +  gOptionRomPkgTokenSpaceGuid.PcdSupportExtScsiPassThru
> +
> +[Pcd]
> +  gOptionRomPkgTokenSpaceGuid.PcdDriverSupportedEfiVersion
> +
> diff --git a/Drivers/OptionRomPkg/AtapiPassThruDxe/ComponentName.c
> b/Drivers/OptionRomPkg/AtapiPassThruDxe/ComponentName.c
> new file mode 100644
> index 0000000000..007cb5f195
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/AtapiPassThruDxe/ComponentName.c
> @@ -0,0 +1,169 @@
> +/** @file
> +  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +  Module Name:  ComponentName.c
> +
> +**/
> +#include "AtapiPassThru.h"
> +
> +//
> +// EFI Component Name Protocol
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED
> EFI_COMPONENT_NAME_PROTOCOL  gAtapiScsiPassThruComponentName =
> {
> +  AtapiScsiPassThruComponentNameGetDriverName,
> +  AtapiScsiPassThruComponentNameGetControllerName,
> +  "eng"
> +};
> +
> +//
> +// EFI Component Name 2 Protocol
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED
> EFI_COMPONENT_NAME2_PROTOCOL gAtapiScsiPassThruComponentName2
> = {
> +  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)
> AtapiScsiPassThruComponentNameGetDriverName,
> +  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)
> AtapiScsiPassThruComponentNameGetControllerName,
> +  "en"
> +};
> +
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
> mAtapiScsiPassThruDriverNameTable[] = {
> +  { "eng;en", (CHAR16 *) L"ATAPI SCSI Pass Thru Driver" },
> +  { NULL , NULL }
> +};
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the driver.
> +
> +  This function retrieves the user readable name of a driver in the form of a
> +  Unicode string. If the driver specified by This has a user readable name in
> +  the language specified by Language, then a pointer to the driver name is
> +  returned in DriverName, and EFI_SUCCESS is returned. If the driver
> specified
> +  by This does not support the language specified by Language,
> +  then EFI_UNSUPPORTED is returned.
> +
> +  @param  This[in]              A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> +                                array indicating the language. This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified
> +                                in RFC 4646 or ISO 639-2 language code format.
> +
> +  @param  DriverName[out]       A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                driver specified by This in the language
> +                                specified by Language.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> +                                This and the language specified by Language was
> +                                returned in DriverName.
> +
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AtapiScsiPassThruComponentNameGetDriverName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
> +  IN  CHAR8                        *Language,
> +  OUT CHAR16                       **DriverName
> +  )
> +{
> +  return LookupUnicodeString2 (
> +           Language,
> +           This->SupportedLanguages,
> +           mAtapiScsiPassThruDriverNameTable,
> +           DriverName,
> +           (BOOLEAN)(This == &gAtapiScsiPassThruComponentName)
> +           );
> +}
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the controller
> +  that is being managed by a driver.
> +
> +  This function retrieves the user readable name of the controller specified
> by
> +  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> +  driver specified by This has a user readable name in the language specified
> by
> +  Language, then a pointer to the controller name is returned in
> ControllerName,
> +  and EFI_SUCCESS is returned.  If the driver specified by This is not
> currently
> +  managing the controller specified by ControllerHandle and ChildHandle,
> +  then EFI_UNSUPPORTED is returned.  If the driver specified by This does
> not
> +  support the language specified by Language, then EFI_UNSUPPORTED is
> returned.
> +
> +  @param  This[in]              A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> +  @param  ControllerHandle[in]  The handle of a controller that the driver
> +                                specified by This is managing.  This handle
> +                                specifies the controller whose name is to be
> +                                returned.
> +
> +  @param  ChildHandle[in]       The handle of the child controller to retrieve
> +                                the name of.  This is an optional parameter that
> +                                may be NULL.  It will be NULL for device
> +                                drivers.  It will also be NULL for a bus drivers
> +                                that wish to retrieve the name of the bus
> +                                controller.  It will not be NULL for a bus
> +                                driver that wishes to retrieve the name of a
> +                                child controller.
> +
> +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> +                                array indicating the language.  This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified in
> +                                RFC 4646 or ISO 639-2 language code format.
> +
> +  @param  ControllerName[out]   A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                controller specified by ControllerHandle and
> +                                ChildHandle in the language specified by
> +                                Language from the point of view of the driver
> +                                specified by This.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the user readable name
> in
> +                                the language specified by Language for the
> +                                driver specified by This was returned in
> +                                DriverName.
> +
> +  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a
> valid
> +                                EFI_HANDLE.
> +
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> +                                managing the controller specified by
> +                                ControllerHandle and ChildHandle.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AtapiScsiPassThruComponentNameGetControllerName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
> +  IN  EFI_HANDLE                                      ControllerHandle,
> +  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
> +  IN  CHAR8                                           *Language,
> +  OUT CHAR16                                          **ControllerName
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> diff --git
> a/Drivers/OptionRomPkg/AtapiPassThruDxe/DriverSupportedEfiVersion.c
> b/Drivers/OptionRomPkg/AtapiPassThruDxe/DriverSupportedEfiVersion.c
> new file mode 100644
> index 0000000000..84a9badad2
> --- /dev/null
> +++
> b/Drivers/OptionRomPkg/AtapiPassThruDxe/DriverSupportedEfiVersion.c
> @@ -0,0 +1,14 @@
> +/** @file
> +  Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +  Module Name:  DriverSupportEfiVersion.c
> +
> +**/
> +#include "AtapiPassThru.h"
> +
> +EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL
> gAtapiScsiPassThruDriverSupportedEfiVersion = {
> +  sizeof (EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL), // Size of
> Protocol structure.
> +  0                                                   // Version number to be filled at start up.
> +};
> +
> diff --git
> a/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/CompatibleDevices.txt
> b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/CompatibleDevices.txt
> new file mode 100644
> index 0000000000..1ec1cce0d1
> --- /dev/null
> +++
> b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/CompatibleDevices.txt
> @@ -0,0 +1,5 @@
> +The following devices have been confirmed to work with the USB Serial
> Driver:
> +
> +Brand        Model Name        Product Name          Vendor ID    Device ID
> +Gearmo       USA_FTDI-36       USB to RS-232         0x0403       0x6001
> +Sabrent      CB-FTDI                                 0x0403       0x6001
> \ No newline at end of file
> diff --git
> a/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ComponentName.c
> b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ComponentName.c
> new file mode 100644
> index 0000000000..d15abf5090
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ComponentName.c
> @@ -0,0 +1,218 @@
> +/** @file
> +  UEFI Component Name(2) protocol implementation for USB Serial driver.
> +
> +Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "FtdiUsbSerialDriver.h"
> +
> +//
> +// EFI Component Name Protocol
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED
> EFI_COMPONENT_NAME_PROTOCOL gUsbSerialComponentName = {
> +  (EFI_COMPONENT_NAME_GET_DRIVER_NAME)
> UsbSerialComponentNameGetDriverName,
> +  (EFI_COMPONENT_NAME_GET_CONTROLLER_NAME)
> UsbSerialComponentNameGetControllerName,
> +  "eng"
> +};
> +
> +//
> +// EFI Component Name 2 Protocol
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED
> EFI_COMPONENT_NAME2_PROTOCOL gUsbSerialComponentName2 = {
> +  UsbSerialComponentNameGetDriverName,
> +  UsbSerialComponentNameGetControllerName,
> +  "en"
> +};
> +
> +//
> +// Driver name string table
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
> mUsbSerialDriverNameTable[] = {
> +  { "eng;en", L"FTDI-232 USB Serial Driver" },
> +  { NULL , NULL }
> +};
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the driver.
> +
> +  This function retrieves the user readable name of a driver in the form of a
> +  Unicode string. If the driver specified by This has a user readable name in
> +  the language specified by Language, then a pointer to the driver name is
> +  returned in DriverName, and EFI_SUCCESS is returned. If the driver
> specified
> +  by This does not support the language specified by Language,
> +  then EFI_UNSUPPORTED is returned.
> +
> +  @param  This                  A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +  @param  Language              A pointer to a Null-terminated ASCII string
> +                                array indicating the language. This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified
> +                                in RFC 4646 or ISO 639-2 language code format.
> +  @param  DriverName            A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                driver specified by This in the language
> +                                specified by Language.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> +                                This and the language specified by Language was
> +                                returned in DriverName.
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbSerialComponentNameGetDriverName (
> +  IN  EFI_COMPONENT_NAME2_PROTOCOL  *This,
> +  IN  CHAR8                         *Language,
> +  OUT CHAR16                        **DriverName
> +  )
> +{
> +  return LookupUnicodeString2 (
> +           Language,
> +           This->SupportedLanguages,
> +           mUsbSerialDriverNameTable,
> +           DriverName,
> +           (BOOLEAN)(This == &gUsbSerialComponentName2)
> +           );
> +}
> +
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the controller
> +  that is being managed by a driver.
> +
> +  This function retrieves the user readable name of the controller specified
> by
> +  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> +  driver specified by This has a user readable name in the language specified
> by
> +  Language, then a pointer to the controller name is returned in
> ControllerName,
> +  and EFI_SUCCESS is returned.  If the driver specified by This is not
> currently
> +  managing the controller specified by ControllerHandle and ChildHandle,
> +  then EFI_UNSUPPORTED is returned.  If the driver specified by This does
> not
> +  support the language specified by Language, then EFI_UNSUPPORTED is
> returned.
> +
> +  @param  This                  A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +  @param  ControllerHandle      The handle of a controller that the driver
> +                                specified by This is managing.  This handle
> +                                specifies the controller whose name is to be
> +                                returned.
> +  @param  ChildHandle           The handle of the child controller to retrieve
> +                                the name of.  This is an optional parameter that
> +                                may be NULL.  It will be NULL for device
> +                                drivers.  It will also be NULL for a bus drivers
> +                                that wish to retrieve the name of the bus
> +                                controller.  It will not be NULL for a bus
> +                                driver that wishes to retrieve the name of a
> +                                child controller.
> +  @param  Language              A pointer to a Null-terminated ASCII string
> +                                array indicating the language.  This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified in
> +                                RFC 4646 or ISO 639-2 language code format.
> +  @param  ControllerName        A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                controller specified by ControllerHandle and
> +                                ChildHandle in the language specified by
> +                                Language from the point of view of the driver
> +                                specified by This.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the user readable name
> in
> +                                the language specified by Language for the
> +                                driver specified by This was returned in
> +                                DriverName.
> +  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid
> EFI_HANDLE.
> +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a
> valid
> +                                EFI_HANDLE.
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> +  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> +                                managing the controller specified by
> +                                ControllerHandle and ChildHandle.
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbSerialComponentNameGetControllerName (
> +  IN  EFI_COMPONENT_NAME2_PROTOCOL  *This,
> +  IN  EFI_HANDLE                    ControllerHandle,
> +  IN  EFI_HANDLE                    ChildHandle      OPTIONAL,
> +  IN  CHAR8                         *Language,
> +  OUT CHAR16                        **ControllerName
> +  )
> +{
> +  EFI_STATUS              Status;
> +  USB_SER_DEV             *UsbSerDev;
> +  EFI_SERIAL_IO_PROTOCOL  *SerialIo;
> +  EFI_USB_IO_PROTOCOL     *UsbIoProtocol;
> +
> +  //
> +  // This is a device driver, so ChildHandle must be NULL.
> +  //
> +  if (ChildHandle != NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Check Controller's handle
> +  //
> +  Status = gBS->OpenProtocol (
> +                  ControllerHandle,
> +                  &gEfiUsbIoProtocolGuid,
> +                  (VOID **) &UsbIoProtocol,
> +                  gUsbSerialDriverBinding.DriverBindingHandle,
> +                  ControllerHandle,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +  if (!EFI_ERROR (Status)) {
> +    gBS->CloseProtocol (
> +           ControllerHandle,
> +           &gEfiUsbIoProtocolGuid,
> +           gUsbSerialDriverBinding.DriverBindingHandle,
> +           ControllerHandle
> +           );
> +
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  if (Status != EFI_ALREADY_STARTED) {
> +    return EFI_UNSUPPORTED;
> +  }
> +  //
> +  // Get the device context
> +  //
> +  Status = gBS->OpenProtocol (
> +                  ControllerHandle,
> +                  &gEfiSerialIoProtocolGuid,
> +                  (VOID **) &SerialIo,
> +                  gUsbSerialDriverBinding.DriverBindingHandle,
> +                  ControllerHandle,
> +                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  UsbSerDev = USB_SER_DEV_FROM_THIS (SerialIo);
> +
> +  return LookupUnicodeString2 (
> +           Language,
> +           This->SupportedLanguages,
> +           UsbSerDev->ControllerNameTable,
> +           ControllerName,
> +           (BOOLEAN)(This == &gUsbSerialComponentName2)
> +           );
> +}
> diff --git
> a/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.c
> b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.c
> new file mode 100644
> index 0000000000..ac09fae014
> --- /dev/null
> +++
> b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.c
> @@ -0,0 +1,2580 @@
> +/** @file
> +  USB Serial Driver that manages USB to Serial and produces Serial IO
> Protocol.
> +
> +Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.
> +Portions Copyright 2012 Ashley DeSimone
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +//
> +
> +// Tested with VEND_ID 0x0403, DEVICE_ID 0x6001
> +//
> +// Driver starts the device with the following values:
> +// 115200, No parity, 8 data bits, 1 stop bit, No Flow control
> +//
> +
> +#include "FtdiUsbSerialDriver.h"
> +
> +//
> +// Table of supported devices. This is the device information that this
> +// driver was developed with. Add other FTDI devices as needed.
> +//
> +USB_DEVICE gUSBDeviceList[] = {
> +  {VID_FTDI, DID_FTDI_FT232},
> +  {0,0}
> +};
> +
> +//
> +// USB Serial Driver Global Variables
> +//
> +EFI_DRIVER_BINDING_PROTOCOL  gUsbSerialDriverBinding = {
> +  UsbSerialDriverBindingSupported,
> +  UsbSerialDriverBindingStart,
> +  UsbSerialDriverBindingStop,
> +  0xa,
> +  NULL,
> +  NULL
> +};
> +
> +//
> +// Table with the nearest power of 2 for the numbers 0-15
> +//
> +UINT8 gRoundedPowersOf2[16] = { 0, 2, 2, 4, 4, 4, 8, 8, 8, 8, 8, 8, 16, 16, 16,
> 16 };
> +
> +/**
> +  Check to see if the device path node is the Flow control node
> +
> +  @param[in] FlowControl    The device path node to be checked
> +
> +  @retval    TRUE           It is the flow control node
> +  @retval    FALSE          It is not the flow control node
> +
> +**/
> +BOOLEAN
> +IsUartFlowControlNode (
> +  IN UART_FLOW_CONTROL_DEVICE_PATH *FlowControl
> +  )
> +{
> +  return (BOOLEAN) (
> +           (DevicePathType (FlowControl) == MESSAGING_DEVICE_PATH) &&
> +           (DevicePathSubType (FlowControl) == MSG_VENDOR_DP) &&
> +           (CompareGuid (&FlowControl->Guid, &gEfiUartDevicePathGuid))
> +           );
> +}
> +
> +/**
> +  Checks the device path to see if it contains flow control.
> +
> +  @param[in] DevicePath    The device path to be checked
> +
> +  @retval    TRUE          It contains flow control
> +  @retval    FALSE         It does not contain flow control
> +
> +**/
> +BOOLEAN
> +ContainsFlowControl (
> +  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath
> +  )
> +{
> +  while (!IsDevicePathEnd (DevicePath)) {
> +    if (IsUartFlowControlNode ((UART_FLOW_CONTROL_DEVICE_PATH *)
> DevicePath)) {
> +      return TRUE;
> +    }
> +    DevicePath = NextDevicePathNode (DevicePath);
> +  }
> +  return FALSE;
> +}
> +
> +/**
> +  Transfer the data between the device and host.
> +
> +  This function transfers the data between the device and host.
> +  BOT transfer is composed of three phases: Command, Data, and Status.
> +  This is the Data phase.
> +
> +  @param  UsbBot[in]                     The USB BOT device
> +  @param  DataDir[in]                    The direction of the data
> +  @param  Data[in, out]                  The buffer to hold data
> +  @param  TransLen[in, out]              The expected length of the data
> +  @param  Timeout[in]                    The time to wait the command to
> complete
> +
> +  @retval EFI_SUCCESS                    The data is transferred
> +  @retval EFI_SUCCESS                    No data to transfer
> +  @retval EFI_NOT_READY                  The device return NAK to the transfer
> +  @retval Others                         Failed to transfer data
> +
> +**/
> +EFI_STATUS
> +UsbSerialDataTransfer (
> +  IN USB_SER_DEV             *UsbBot,
> +  IN EFI_USB_DATA_DIRECTION  DataDir,
> +  IN OUT VOID                *Data,
> +  IN OUT UINTN               *TransLen,
> +  IN UINT32                  Timeout
> +  )
> +{
> +  EFI_USB_ENDPOINT_DESCRIPTOR  *Endpoint;
> +  EFI_STATUS                   Status;
> +  UINT32                       Result;
> +
> +  //
> +  // If no data to transfer, just return EFI_SUCCESS.
> +  //
> +  if ((DataDir == EfiUsbNoData) || (*TransLen == 0)) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  //
> +  // Select the endpoint then issue the transfer
> +  //
> +  if (DataDir == EfiUsbDataIn) {
> +    Endpoint = &UsbBot->InEndpointDescriptor;
> +  } else {
> +    Endpoint = &UsbBot->OutEndpointDescriptor;
> +  }
> +
> +  Result = 0;
> +  Status = UsbBot->UsbIo->UsbBulkTransfer (
> +                            UsbBot->UsbIo,
> +                            Endpoint->EndpointAddress,
> +                            Data,
> +                            TransLen,
> +                            Timeout,
> +                            &Result
> +                            );
> +  if (EFI_ERROR (Status)) {
> +    if (USB_IS_ERROR (Result, EFI_USB_ERR_NAK)) {
> +      Status = EFI_NOT_READY;
> +    } else {
> +      UsbBot->Shutdown = TRUE; // Fixes infinite loop in older EFI
> +    }
> +    return Status;
> +  }
> +  return Status;
> +}
> +
> +/**
> +  Sets the status values of the Usb Serial Device.
> +
> +  @param  UsbSerialDevice[in]  Handle to the Usb Serial Device to set the
> status
> +                               for
> +  @param  StatusBuffer[in]     Buffer holding the status values
> +
> +  @retval EFI_SUCCESS          The status values were read and set correctly
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetStatusInternal (
> +  IN USB_SER_DEV  *UsbSerialDevice,
> +  IN UINT8        *StatusBuffer
> +  )
> +{
> +  UINT8  Msr;
> +
> +  Msr = (StatusBuffer[0] & MSR_MASK);
> +
> +  //
> +  // set the Status values to disabled
> +  //
> +  UsbSerialDevice->StatusValues.CtsState = FALSE;
> +  UsbSerialDevice->StatusValues.DsrState = FALSE;
> +  UsbSerialDevice->StatusValues.RiState  = FALSE;
> +  UsbSerialDevice->StatusValues.SdState  = FALSE;
> +
> +  //
> +  // Check the values from the status buffer and set the appropriate status
> +  // values to enabled
> +  //
> +  if ((Msr & CTS_MASK) == CTS_MASK) {
> +    UsbSerialDevice->StatusValues.CtsState = TRUE;
> +  }
> +  if ((Msr & DSR_MASK) == DSR_MASK) {
> +    UsbSerialDevice->StatusValues.DsrState = TRUE;
> +  }
> +  if ((Msr & RI_MASK) == RI_MASK) {
> +    UsbSerialDevice->StatusValues.RiState = TRUE;
> +  }
> +  if ((Msr & SD_MASK) == SD_MASK) {
> +    UsbSerialDevice->StatusValues.SdState = TRUE;
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Initiates a read operation on the Usb Serial Device.
> +
> +  @param  UsbSerialDevice[in]        Handle to the USB device to read
> +  @param  BufferSize[in, out]        On input, the size of the Buffer. On output,
> +                                     the amount of data returned in Buffer.
> +                                     Setting this to zero will initiate a read
> +                                     and store all data returned in the internal
> +                                     buffer.
> +  @param  Buffer [out]               The buffer to return the data into.
> +
> +  @retval EFI_SUCCESS                The data was read.
> +  @retval EFI_DEVICE_ERROR           The device reported an error.
> +  @retval EFI_TIMEOUT                The data write was stopped due to a
> timeout.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +ReadDataFromUsb (
> +  IN USB_SER_DEV  *UsbSerialDevice,
> +  IN OUT UINTN    *BufferSize,
> +  OUT VOID        *Buffer
> +  )
> +{
> +  EFI_STATUS  Status;
> +  UINTN       ReadBufferSize;
> +  UINT8       *ReadBuffer;
> +  UINTN       Index;
> +  EFI_TPL     Tpl;
> +  UINT8       StatusBuffer[2]; // buffer to store the status bytes
> +
> +  ReadBufferSize = 512;
> +  ReadBuffer     = &(UsbSerialDevice->ReadBuffer[0]);
> +
> +  if (UsbSerialDevice->Shutdown) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  Tpl = gBS->RaiseTPL (TPL_NOTIFY);
> +
> +  Status = UsbSerialDataTransfer (
> +             UsbSerialDevice,
> +             EfiUsbDataIn,
> +             ReadBuffer,
> +             &ReadBufferSize,
> +             FTDI_TIMEOUT*2  //Padded because timers won't be exactly aligned
> +             );
> +  if (EFI_ERROR (Status)) {
> +    gBS->RestoreTPL (Tpl);
> +    if (Status == EFI_TIMEOUT) {
> +      return EFI_TIMEOUT;
> +    } else {
> +      return EFI_DEVICE_ERROR;
> +    }
> +  }
> +
> +  //
> +  // Store the status bytes in the status buffer
> +  //
> +  for (Index = 0; Index < 2; Index++) {//only the first 2 bytes are status bytes
> +    StatusBuffer[Index] = ReadBuffer[Index];
> +  }
> +  //
> +  // update the statusvalue field of the usbserialdevice
> +  //
> +  Status = SetStatusInternal (UsbSerialDevice, StatusBuffer);
> +  if (Status != EFI_SUCCESS) {
> +  }
> +
> +  //
> +  // Store the read data in the read buffer, start at 2 to ignore status bytes
> +  //
> +  for (Index = 2; Index < ReadBufferSize; Index++) {
> +    if (((UsbSerialDevice->DataBufferTail + 1) % SW_FIFO_DEPTH) ==
> UsbSerialDevice->DataBufferHead) {
> +      break;
> +    }
> +    if (ReadBuffer[Index] == 0x00) {
> +      //
> +      // This is null, do not add
> +      //
> +    } else {
> +      UsbSerialDevice->DataBuffer[UsbSerialDevice->DataBufferTail] =
> ReadBuffer[Index];
> +      UsbSerialDevice->DataBufferTail = (UsbSerialDevice->DataBufferTail + 1) %
> SW_FIFO_DEPTH;
> +    }
> +  }
> +
> +  //
> +  // Read characters out of the buffer to satisfy caller's request.
> +  //
> +  for (Index = 0; Index < *BufferSize; Index++) {
> +    if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail)
> {
> +      break;
> +    }
> +    //
> +    // Still have characters in the buffer to return
> +    //
> +    ((UINT8 *)Buffer)[Index]        = UsbSerialDevice-
> >DataBuffer[UsbSerialDevice->DataBufferHead];
> +    UsbSerialDevice->DataBufferHead = (UsbSerialDevice->DataBufferHead +
> 1) % SW_FIFO_DEPTH;
> +  }
> +  //
> +  // Return actual number of bytes returned.
> +  //
> +  *BufferSize = Index;
> +  gBS->RestoreTPL (Tpl);
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Sets the initial status values of the Usb Serial Device by reading the status
> +  bytes from the device.
> +
> +  @param  UsbSerialDevice[in]  Handle to the Usb Serial Device that needs
> its
> +                               initial status values set
> +
> +  @retval EFI_SUCCESS          The status bytes were read successfully and the
> +                               initial status values were set correctly
> +  @retval EFI_TIMEOUT          The read of the status bytes was stopped due
> to a
> +                               timeout
> +  @retval EFI_DEVICE_ERROR     The device reported an error during the
> read of
> +                               the status bytes
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetInitialStatus (
> +  IN USB_SER_DEV          *UsbSerialDevice
> +  )
> +{
> +  EFI_STATUS      Status;
> +  UINTN           BufferSize;
> +  EFI_TPL         Tpl;
> +  UINT8           StatusBuffer[2];
> +
> +  Status          = EFI_UNSUPPORTED;
> +  BufferSize      = sizeof (StatusBuffer);
> +
> +  if (UsbSerialDevice->Shutdown) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  Tpl = gBS->RaiseTPL (TPL_NOTIFY);
> +
> +  Status = UsbSerialDataTransfer (
> +             UsbSerialDevice,
> +             EfiUsbDataIn,
> +             StatusBuffer,
> +             &BufferSize,
> +             40    //Slightly more than 2x the FTDI polling frequency to make sure
> that data will be returned
> +             );
> +
> +  Status = SetStatusInternal (UsbSerialDevice, StatusBuffer);
> +
> +  gBS->RestoreTPL (Tpl);
> +
> +  return Status;
> +}
> +
> +/**
> +  UsbSerialDriverCheckInput.
> +  attempts to read data in from the device periodically, stores any read data
> +  and updates the control attributes.
> +
> +  @param  Event[in]
> +  @param  Context[in]....The current instance of the USB serial device
> +
> +**/
> +VOID
> +EFIAPI
> +UsbSerialDriverCheckInput (
> +  IN  EFI_EVENT  Event,
> +  IN  VOID       *Context
> +  )
> +{
> +  UINTN        BufferSize;
> +  USB_SER_DEV  *UsbSerialDevice;
> +
> +  UsbSerialDevice = (USB_SER_DEV*)Context;
> +
> +  if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {
> +    //
> +    // Data buffer is empty, try to read from device
> +    //
> +    BufferSize = 0;
> +    ReadDataFromUsb (UsbSerialDevice, &BufferSize, NULL);
> +    if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail)
> {
> +      //
> +      // Data buffer still has no data, set the
> EFI_SERIAL_INPUT_BUFFER_EMPTY
> +      // flag
> +      //
> +      UsbSerialDevice->ControlBits |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
> +    } else {
> +      //
> +      // Read has returned some data, clear the
> EFI_SERIAL_INPUT_BUFFER_EMPTY
> +      // flag
> +      //
> +      UsbSerialDevice->ControlBits &= ~(EFI_SERIAL_INPUT_BUFFER_EMPTY);
> +    }
> +  } else {
> +    //
> +    // Data buffer has data, no read attempt required
> +    //
> +    UsbSerialDevice->ControlBits &= ~(EFI_SERIAL_INPUT_BUFFER_EMPTY);
> +  }
> +}
> +
> +/**
> +  Encodes the baud rate into the format expected by the Ftdi device.
> +
> +  @param  BaudRate[in]                The baudrate to be set on the device
> +  @param  EncodedBaudRate[out]        The baud rate encoded in the format
> +                                      expected by the Ftdi device
> +
> +  @return EFI_SUCCESS                 Baudrate encoding was calculated
> +                                      successfully
> +  @return EFI_INVALID_PARAMETER       An invalid value of BaudRate was
> received
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +EncodeBaudRateForFtdi (
> +  IN  UINT64  BaudRate,
> +  OUT UINT16  *EncodedBaudRate
> +  )
> +{
> +  UINT32 Divisor;
> +  UINT32 AdjustedFrequency;
> +  UINT16 Result;
> +
> +  //
> +  // Check to make sure we won't get an integer overflow
> +  //
> +  if ((BaudRate < 178) || ( BaudRate > ((FTDI_UART_FREQUENCY * 100) /
> 97))) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Baud Rates of 2000000 and 3000000 are special cases
> +  //
> +  if ((BaudRate >= FTDI_SPECIAL_CASE_300_MIN) && (BaudRate <=
> FTDI_SPECIAL_CASE_300_MAX)) {
> +    *EncodedBaudRate = 0;
> +    return EFI_SUCCESS;
> +  }
> +  if ((BaudRate >= FTDI_SPECIAL_CASE_200_MIN) && (BaudRate <=
> FTDI_SPECIAL_CASE_200_MAX)) {
> +    *EncodedBaudRate = 1;
> +    return EFI_SUCCESS;
> +  }
> +
> +  //
> +  // Compute divisor
> +  //
> +  Divisor = (FTDI_UART_FREQUENCY << 4) / (UINT32)BaudRate;
> +
> +  //
> +  // Round the last 4 bits to the nearest power of 2
> +  //
> +  Divisor = (Divisor & ~(0xF)) + (gRoundedPowersOf2[Divisor & 0xF]);
> +
> +  //
> +  // Check to make sure computed divisor is within
> +  // the min and max that FTDI controller will accept
> +  //
> +  if (Divisor < FTDI_MIN_DIVISOR) {
> +    Divisor = FTDI_MIN_DIVISOR;
> +  } else if (Divisor > FTDI_MAX_DIVISOR) {
> +    Divisor = FTDI_MAX_DIVISOR;
> +  }
> +
> +  //
> +  // Check to make sure the frequency that the FTDI chip will need to
> +  // generate to attain the requested Baud Rate is within 3% of the
> +  // 3MHz clock frequency that the FTDI chip runs at.
> +  //
> +  // (3MHz * 1600) / 103 = 46601941
> +  // (3MHz * 1600) / 97  = 49484536
> +  //
> +  AdjustedFrequency = (((UINT32)BaudRate) * Divisor);
> +  if ((AdjustedFrequency < FTDI_MIN_FREQUENCY) || (AdjustedFrequency >
> FTDI_MAX_FREQUENCY)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Encode the Divisor into the format FTDI expects
> +  //
> +  Result = (UINT16)(Divisor >> 4);
> +  if ((Divisor & 0x8) != 0) {
> +    Result |= 0x4000;
> +  } else if ((Divisor & 0x4) != 0) {
> +    Result |= 0x8000;
> +  } else if ((Divisor & 0x2) != 0) {
> +    Result |= 0xC000;
> +  }
> +
> +  *EncodedBaudRate = Result;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Uses USB I/O to check whether the device is a USB Serial device.
> +
> +  @param  UsbIo[in]    Pointer to a USB I/O protocol instance.
> +
> +  @retval TRUE         Device is a USB Serial device.
> +  @retval FALSE        Device is a not USB Serial device.
> +
> +**/
> +BOOLEAN
> +IsUsbSerial (
> +  IN  EFI_USB_IO_PROTOCOL  *UsbIo
> +  )
> +{
> +  EFI_STATUS                 Status;
> +  EFI_USB_DEVICE_DESCRIPTOR  DeviceDescriptor;
> +  CHAR16                     *StrMfg;
> +  BOOLEAN                    Found;
> +  UINT32                     Index;
> +
> +  //
> +  // Get the default device descriptor
> +  //
> +  Status = UsbIo->UsbGetDeviceDescriptor (
> +                    UsbIo,
> +                    &DeviceDescriptor
> +                    );
> +  if (EFI_ERROR (Status)) {
> +    return FALSE;
> +  }
> +
> +  Found = FALSE;
> +  Index = 0;
> +  while (gUSBDeviceList[Index].VendorId != 0 &&
> +         gUSBDeviceList[Index].DeviceId != 0 &&
> +         !Found                                  ) {
> +    if (DeviceDescriptor.IdProduct == gUSBDeviceList[Index].DeviceId &&
> +        DeviceDescriptor.IdVendor  == gUSBDeviceList[Index].VendorId      ){
> +        //
> +        // Checks to see if a string descriptor can be pulled from the device in
> +        // the selected language. If not False is returned indicating that this
> +        // is not a Usb Serial Device that can be managegd by this driver
> +        //
> +        StrMfg = NULL;
> +        Status = UsbIo->UsbGetStringDescriptor (
> +                          UsbIo,
> +                          USB_US_LANG_ID, // LANGID selector, should make this
> +                                          // more robust to verify lang support
> +                                          // for device
> +                          DeviceDescriptor.StrManufacturer,
> +                          &StrMfg
> +                          );
> +        if (StrMfg != NULL) {
> +          FreePool (StrMfg);
> +        }
> +        if (EFI_ERROR (Status)) {
> +          return FALSE;
> +        }
> +        return TRUE;
> +    }
> +    Index++;
> +  }
> +  return FALSE;
> +}
> +
> +/**
> +  Internal function that sets the Data Bits, Stop Bits and Parity values on the
> +  Usb Serial Device with a single usb control transfer.
> +
> +  @param  UsbIo[in]                  Usb Io Protocol instance pointer
> +  @param  DataBits[in]               The data bits value to be set on the Usb
> +                                     Serial Device
> +  @param  Parity[in]                 The parity type that will be set on the Usb
> +                                     Serial Device
> +  @param  StopBits[in]               The stop bits type that will be set on the
> +                                     Usb Serial Device
> +  @param  LastSettings[in]           A pointer to the Usb Serial Device's
> +                                     PREVIOUS_ATTRIBUTES item
> +
> +  @retval EFI_SUCCESS                The data items were correctly set on the
> +                                     USB Serial Device
> +  @retval EFI_INVALID_PARAMETER      An invalid data parameter or an
> invalid
> +                                     combination or parameters was used
> +  @retval EFI_DEVICE_ERROR           The device is not functioning correctly
> and
> +                                     the data values were unable to be set
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetDataInternal (
> +  IN EFI_USB_IO_PROTOCOL  *UsbIo,
> +  IN UINT8                DataBits,
> +  IN EFI_PARITY_TYPE      Parity,
> +  IN EFI_STOP_BITS_TYPE   StopBits,
> +  IN PREVIOUS_ATTRIBUTES  *LastSettings
> +  )
> +{
> +  EFI_STATUS              Status;
> +  EFI_USB_DEVICE_REQUEST  DevReq;
> +  UINT32                  ReturnValue;
> +  UINT8                   ConfigurationValue;
> +
> +  //
> +  // Since data bits settings of 6,7,8 cannot be set with a stop bits setting of
> +  // 1.5 check to see if this happens when the values of last settings are used
> +  //
> +  if ((DataBits == 0) && (StopBits == OneFiveStopBits)) {
> +    if ((LastSettings->DataBits == 6) || (LastSettings->DataBits == 7) ||
> (LastSettings->DataBits == 8)) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +  } else if ((StopBits == DefaultStopBits) && ((DataBits == 6) || (DataBits == 7)
> || (DataBits == 8))) {
> +    if (LastSettings->StopBits == OneFiveStopBits) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +  } else if ((DataBits == 0) && (StopBits == DefaultStopBits)) {
> +    if (LastSettings->StopBits == OneFiveStopBits) {
> +      if ((LastSettings->DataBits == 6) || (LastSettings->DataBits == 7) ||
> (LastSettings->DataBits == 8)) {
> +        return EFI_INVALID_PARAMETER;
> +      }
> +    }
> +  }
> +
> +  //
> +  // set the DevReq.Value for the usb control transfer to the correct value
> +  // based on the seleceted number of data bits if there is an invalid number
> of
> +  // data bits requested return EFI_INVALID_PARAMETER
> +  //
> +  if (((DataBits < 5 ) || (DataBits > 8)) && (DataBits != 0)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  if (DataBits == 0) {
> +    //
> +    // use the value of LastDataBits
> +    //
> +    DevReq.Value = SET_DATA_BITS (LastSettings->DataBits);
> +  } else {
> +    //
> +    // use the value of DataBits
> +    //
> +    DevReq.Value = SET_DATA_BITS (DataBits);
> +  }
> +
> +  //
> +  // Set Parity
> +  //
> +  if (Parity == DefaultParity) {
> +    Parity = LastSettings->Parity;
> +  }
> +
> +  if (Parity == NoParity) {
> +    DevReq.Value |= SET_PARITY_NONE;
> +  } else if (Parity == EvenParity) {
> +    DevReq.Value |= SET_PARITY_EVEN;
> +  } else if (Parity == OddParity){
> +    DevReq.Value |= SET_PARITY_ODD;
> +  } else if (Parity == MarkParity) {
> +    DevReq.Value |= SET_PARITY_MARK;
> +  } else if (Parity == SpaceParity) {
> +    DevReq.Value |= SET_PARITY_SPACE;
> +  }
> +
> +  //
> +  // Set Stop Bits
> +  //
> +  if (StopBits == DefaultStopBits) {
> +    StopBits = LastSettings->StopBits;
> +  }
> +
> +  if (StopBits == OneStopBit) {
> +    DevReq.Value |= SET_STOP_BITS_1;
> +  } else if (StopBits == OneFiveStopBits) {
> +    DevReq.Value |= SET_STOP_BITS_15;
> +  } else if (StopBits == TwoStopBits) {
> +    DevReq.Value |= SET_STOP_BITS_2;
> +  }
> +
> +  //
> +  // set the rest of the DevReq parameters and perform the usb control
> transfer
> +  // to set the data bits on the device
> +  //
> +  DevReq.Request     = FTDI_COMMAND_SET_DATA;
> +  DevReq.RequestType = USB_REQ_TYPE_VENDOR;
> +  DevReq.Index       = FTDI_PORT_IDENTIFIER;
> +  DevReq.Length      = 0; // indicates that there is no data phase in this
> request
> +
> +  Status = UsbIo->UsbControlTransfer (
> +                    UsbIo,
> +                    &DevReq,
> +                    EfiUsbDataOut,
> +                    WDR_SHORT_TIMEOUT,
> +                    &ConfigurationValue,
> +                    1,
> +                    &ReturnValue
> +                    );
> +  if (EFI_ERROR (Status)) {
> +    goto StatusError;
> +  }
> +  return Status;
> +
> +StatusError:
> +  if ((Status != EFI_INVALID_PARAMETER) || (Status != EFI_DEVICE_ERROR))
> {
> +    return EFI_DEVICE_ERROR;
> +  } else {
> +    return Status;
> +  }
> +}
> +
> +/**
> +  Internal function that sets the baudrate on the Usb Serial Device.
> +
> +  @param  UsbIo[in]                  Usb Io Protocol instance pointer
> +  @param  BaudRate[in]               The baudrate value to be set on the device.
> +                                     If this value is 0 the value of LastBaudRate
> +                                     will be used instead
> +  @param  LastBaudRate[in]           The baud rate value that was previously
> set
> +                                     on the Usb Serial Device
> +
> +  @retval EFI_SUCCESS                The baudrate was set succesfully
> +  @retval EFI_INVALID_PARAMETER      An invalid baudrate was used
> +  @retval EFI_DEVICE_ERROR           The device is not functioning correctly
> and
> +                                     the baudrate was unable to be set
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetBaudRateInternal (
> +  IN EFI_USB_IO_PROTOCOL  *UsbIo,
> +  IN UINT64               BaudRate,
> +  IN UINT64               LastBaudRate
> +  )
> +{
> +  EFI_STATUS              Status;
> +  EFI_USB_DEVICE_REQUEST  DevReq;
> +  UINT32                  ReturnValue;
> +  UINT8                   ConfigurationValue;
> +  UINT16                  EncodedBaudRate;
> +  EFI_TPL                 Tpl;
> +
> +  Tpl    = gBS->RaiseTPL(TPL_NOTIFY);
> +
> +  //
> +  // set the value of DevReq.Value based on the value of BaudRate
> +  // if 0 is selected as baud rate use the value of LastBaudRate
> +  //
> +  if (BaudRate == 0) {
> +    Status = EncodeBaudRateForFtdi (LastBaudRate, &EncodedBaudRate);
> +    if (EFI_ERROR (Status)) {
> +      gBS->RestoreTPL (Tpl);
> +      //
> +      // EncodeBaudRateForFtdi returns EFI_INVALID_PARAMETER when not
> +      // succesfull
> +      //
> +      return Status;
> +    }
> +    DevReq.Value = EncodedBaudRate;
> +  } else {
> +    Status = EncodeBaudRateForFtdi (BaudRate, &EncodedBaudRate);
> +    if (EFI_ERROR (Status)) {
> +      gBS->RestoreTPL (Tpl);
> +      //
> +      // EncodeBaudRateForFtdi returns EFI_INVALID_PARAMETER when not
> +      // successfull
> +      //
> +      return Status;
> +    }
> +    DevReq.Value = EncodedBaudRate;
> +  }
> +
> +  //
> +  // set the remaining parameters of DevReq and perform the usb control
> transfer
> +  // to set the device
> +  //
> +  DevReq.Request     = FTDI_COMMAND_SET_BAUDRATE;
> +  DevReq.RequestType = USB_REQ_TYPE_VENDOR;
> +  DevReq.Index       = FTDI_PORT_IDENTIFIER;
> +  DevReq.Length      = 0; // indicates that there is no data phase in this
> request
> +
> +  Status = UsbIo->UsbControlTransfer (
> +                    UsbIo,
> +                    &DevReq,
> +                    EfiUsbDataOut,
> +                    WDR_SHORT_TIMEOUT,
> +                    &ConfigurationValue,
> +                    1,
> +                    &ReturnValue
> +                    );
> +  if (EFI_ERROR (Status)) {
> +    goto StatusError;
> +  }
> +  gBS->RestoreTPL (Tpl);
> +  return Status;
> +
> +StatusError:
> +  gBS->RestoreTPL (Tpl);
> +  if ((Status != EFI_INVALID_PARAMETER) || (Status != EFI_DEVICE_ERROR))
> {
> +    return EFI_DEVICE_ERROR;
> +  } else {
> +    return Status;
> +  }
> +}
> +
> +/**
> +  Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,
> +  data bits, and stop bits on a serial device.
> +
> +  @param  UsbSerialDevice[in]  Pointer to the current instance of the USB
> Serial
> +                               Device.
> +  @param  BaudRate[in]         The requested baud rate. A BaudRate value of
> 0
> +                               will use the device's default interface speed.
> +  @param  ReveiveFifoDepth[in] The requested depth of the FIFO on the
> receive
> +                               side of the serial interface. A ReceiveFifoDepth
> +                               value of 0 will use the device's default FIFO
> +                               depth.
> +  @param  Timeout[in]          The requested time out for a single character in
> +                               microseconds.This timeout applies to both the
> +                               transmit and receive side of the interface.A
> +                               Timeout value of 0 will use the device's default
> +                               time out value.
> +  @param  Parity[in]           The type of parity to use on this serial device.
> +                               A Parity value of DefaultParity will use the
> +                               device's default parity value.
> +  @param  DataBits[in]         The number of data bits to use on the serial
> +                               device. A DataBits value of 0 will use the
> +                               device's default data bit setting.
> +  @param  StopBits[in]         The number of stop bits to use on this serial
> +                               device. A StopBits value of DefaultStopBits will
> +                               use the device's default number of stop bits.
> +
> +  @retval EFI_SUCCESS          The attributes were set
> +  @retval EFI_DEVICE_ERROR     The attributes were not able to be set
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetAttributesInternal (
> +  IN USB_SER_DEV         *UsbSerialDevice,
> +  IN UINT64              BaudRate,
> +  IN UINT32              ReceiveFifoDepth,
> +  IN UINT32              Timeout,
> +  IN EFI_PARITY_TYPE     Parity,
> +  IN UINT8               DataBits,
> +  IN EFI_STOP_BITS_TYPE  StopBits
> +  )
> +{
> +  EFI_STATUS                Status;
> +  EFI_TPL                   Tpl;
> +  UART_DEVICE_PATH          *Uart;
> +  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath;
> +
> +  Status = EFI_UNSUPPORTED;
> +  Tpl    = gBS->RaiseTPL(TPL_NOTIFY);
> +  Uart   = NULL;
> +
> +  //
> +  // check for invalid combinations of parameters
> +  //
> +  if (((DataBits >= 6) && (DataBits <= 8)) && (StopBits == OneFiveStopBits)) {
> +    return  EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // set data bits, parity and stop bits
> +  //
> +  Status = SetDataInternal (
> +             UsbSerialDevice->UsbIo,
> +             DataBits,
> +             Parity,
> +             StopBits,
> +             &(UsbSerialDevice->LastSettings)
> +             );
> +  if (EFI_ERROR (Status)) {
> +    goto StatusError;
> +  }
> +  //
> +  // set baudrate
> +  //
> +  Status = SetBaudRateInternal (
> +             UsbSerialDevice->UsbIo,
> +             BaudRate,
> +             UsbSerialDevice->LastSettings.BaudRate
> +             );
> +  if (EFI_ERROR (Status)){
> +    goto StatusError;
> +  }
> +
> +  //
> +  // update the values of UsbSerialDevice->LastSettings and
> UsbSerialDevice->SerialIo.Mode
> +  //
> +  if (BaudRate == 0) {
> +    UsbSerialDevice->LastSettings.BaudRate   = UsbSerialDevice-
> >LastSettings.BaudRate;
> +    UsbSerialDevice->SerialIo.Mode->BaudRate = UsbSerialDevice-
> >LastSettings.BaudRate;
> +  } else {
> +    UsbSerialDevice->LastSettings.BaudRate   = BaudRate;
> +    UsbSerialDevice->SerialIo.Mode->BaudRate = BaudRate;
> +  }
> +
> +  UsbSerialDevice->LastSettings.Timeout          = FTDI_TIMEOUT;
> +  UsbSerialDevice->LastSettings.ReceiveFifoDepth =
> FTDI_MAX_RECEIVE_FIFO_DEPTH;
> +
> +  if (Parity == DefaultParity) {
> +    UsbSerialDevice->LastSettings.Parity   = UsbSerialDevice-
> >LastSettings.Parity;
> +    UsbSerialDevice->SerialIo.Mode->Parity = UsbSerialDevice-
> >LastSettings.Parity;
> +  } else {
> +    UsbSerialDevice->LastSettings.Parity   = Parity;
> +    UsbSerialDevice->SerialIo.Mode->Parity = Parity;
> +  }
> +  if (DataBits == 0) {
> +    UsbSerialDevice->LastSettings.DataBits   = UsbSerialDevice-
> >LastSettings.DataBits;
> +    UsbSerialDevice->SerialIo.Mode->DataBits = UsbSerialDevice-
> >LastSettings.DataBits;
> +  } else {
> +    UsbSerialDevice->LastSettings.DataBits   = DataBits;
> +    UsbSerialDevice->SerialIo.Mode->DataBits = DataBits;
> +  }
> +  if (StopBits == DefaultStopBits) {
> +    UsbSerialDevice->LastSettings.StopBits   = UsbSerialDevice-
> >LastSettings.StopBits;
> +    UsbSerialDevice->SerialIo.Mode->StopBits = UsbSerialDevice-
> >LastSettings.StopBits;
> +  } else {
> +    UsbSerialDevice->LastSettings.StopBits   = StopBits;
> +    UsbSerialDevice->SerialIo.Mode->StopBits = StopBits;
> +  }
> +
> +  //
> +  // See if the device path node has changed
> +  //
> +  if (UsbSerialDevice->UartDevicePath.BaudRate == BaudRate &&
> +      UsbSerialDevice->UartDevicePath.DataBits == DataBits &&
> +      UsbSerialDevice->UartDevicePath.StopBits == StopBits &&
> +      UsbSerialDevice->UartDevicePath.Parity == Parity
> +      ) {
> +    gBS->RestoreTPL (Tpl);
> +    return EFI_SUCCESS;
> +  }
> +
> +  //
> +  // Update the device path
> +  //
> +  UsbSerialDevice->UartDevicePath.BaudRate = BaudRate;
> +  UsbSerialDevice->UartDevicePath.DataBits = DataBits;
> +  UsbSerialDevice->UartDevicePath.StopBits = (UINT8) StopBits;
> +  UsbSerialDevice->UartDevicePath.Parity   = (UINT8) Parity;
> +
> +  Status = EFI_SUCCESS;
> +  if (UsbSerialDevice->ControllerHandle != NULL) {
> +    RemainingDevicePath = UsbSerialDevice->DevicePath;
> +    while (!IsDevicePathEnd (RemainingDevicePath)) {
> +      Uart = (UART_DEVICE_PATH *) NextDevicePathNode
> (RemainingDevicePath);
> +      if (Uart->Header.Type == MESSAGING_DEVICE_PATH &&
> +          Uart->Header.SubType == MSG_UART_DP &&
> +          sizeof (UART_DEVICE_PATH) == DevicePathNodeLength
> ((EFI_DEVICE_PATH *) Uart)) {
> +        Uart->BaudRate = BaudRate;
> +        Uart->DataBits = DataBits;
> +        Uart->StopBits = (UINT8)StopBits;
> +        Uart->Parity   = (UINT8) Parity;
> +        break;
> +        }
> +        RemainingDevicePath = NextDevicePathNode (RemainingDevicePath);
> +    }
> +  }
> +
> +  gBS->RestoreTPL (Tpl);
> +  return Status;
> +
> +StatusError:
> +  gBS->RestoreTPL (Tpl);
> +  if ((Status != EFI_INVALID_PARAMETER) || (Status != EFI_DEVICE_ERROR))
> {
> +    return EFI_DEVICE_ERROR;
> +  } else {
> +    return Status;
> +  }
> +}
> +
> +/**
> +  Internal function that performs a Usb Control Transfer to set the flow
> control
> +  on the Usb Serial Device.
> +
> +  @param  UsbIo[in]                  Usb Io Protocol instance pointer
> +  @param  FlowControlEnable[in]      Data on the Enable/Disable status of
> Flow
> +                                     Control on the Usb Serial Device
> +
> +  @retval EFI_SUCCESS                The flow control was set on the Usb Serial
> +                                     device
> +  @retval EFI_INVALID_PARAMETER      An invalid flow control value was
> used
> +  @retval EFI_EFI_UNSUPPORTED        The operation is not supported
> +  @retval EFI_DEVICE_ERROR           The device is not functioning correctly
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetFlowControlInternal (
> +  IN EFI_USB_IO_PROTOCOL  *UsbIo,
> +  IN BOOLEAN              FlowControlEnable
> +  )
> +{
> +  EFI_STATUS               Status;
> +  EFI_USB_DEVICE_REQUEST   DevReq;
> +  UINT32                   ReturnValue;
> +  UINT8                    ConfigurationValue;
> +
> +  //
> +  // set DevReq.Value based on the value of FlowControlEnable
> +  //
> +  if (!FlowControlEnable) {
> +    DevReq.Value = NO_FLOW_CTRL;
> +  }
> +  if (FlowControlEnable) {
> +    DevReq.Value = XON_XOFF_CTRL;
> +  }
> +  //
> +  // set the remaining DevReq parameters and perform the usb control
> transfer to
> +  // set the flow control on the device
> +  //
> +  DevReq.Request      = FTDI_COMMAND_SET_FLOW_CTRL;
> +  DevReq.RequestType  = USB_REQ_TYPE_VENDOR;
> +  DevReq.Index        = FTDI_PORT_IDENTIFIER;
> +  DevReq.Length       = 0; // indicates that this transfer has no data phase
> +  Status              = UsbIo->UsbControlTransfer (
> +                                 UsbIo,
> +                                 &DevReq,
> +                                 EfiUsbDataOut,
> +                                 WDR_TIMEOUT,
> +                                 &ConfigurationValue,
> +                                 1,
> +                                 &ReturnValue
> +                                 );
> +  if (EFI_ERROR (Status)) {
> +    goto StatusError;
> +  }
> +
> +  return Status;
> +
> +StatusError:
> +  if ((Status != EFI_INVALID_PARAMETER) ||
> +      (Status != EFI_DEVICE_ERROR)      ||
> +      (Status != EFI_UNSUPPORTED)          ) {
> +    return EFI_DEVICE_ERROR;
> +  } else {
> +    return Status;
> +  }
> +}
> +
> +/**
> +  Internal function that performs a Usb Control Transfer to set the Dtr value
> on
> +  the Usb Serial Device.
> +
> +  @param  UsbIo[in]                  Usb Io Protocol instance pointer
> +  @param  DtrEnable[in]              Data on the Enable/Disable status of the
> +                                     Dtr for the Usb Serial Device
> +
> +  @retval EFI_SUCCESS                The Dtr value was set on the Usb Serial
> +                                     Device
> +  @retval EFI_INVALID_PARAMETER      An invalid Dtr value was used
> +  @retval EFI_UNSUPPORTED            The operation is not supported
> +  @retval EFI_DEVICE_ERROR           The device is not functioning correctly
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetDtrInternal (
> +  IN EFI_USB_IO_PROTOCOL  *UsbIo,
> +  IN BOOLEAN              DtrEnable
> +  )
> +{
> +  EFI_STATUS              Status;
> +  EFI_USB_DEVICE_REQUEST  DevReq;
> +  UINT32                  ReturnValue;
> +  UINT8                   ConfigurationValue;
> +
> +  //
> +  // set the value of DevReq.Value based on the value of DtrEnable
> +  //
> +  if (!DtrEnable) {
> +    DevReq.Value = SET_DTR_LOW;
> +  }
> +  if (DtrEnable) {
> +    DevReq.Value = SET_DTR_HIGH;
> +  }
> +  //
> +  // set the remaining attributes of DevReq and perform the usb control
> transfer
> +  // to set the device
> +  //
> +  DevReq.Request      = FTDI_COMMAND_MODEM_CTRL;
> +  DevReq.RequestType  = USB_REQ_TYPE_VENDOR;
> +  DevReq.Index        = FTDI_PORT_IDENTIFIER;
> +  DevReq.Length       = 0; // indicates that there is no data phase in this
> transfer
> +
> +  Status = UsbIo->UsbControlTransfer (
> +                    UsbIo,
> +                    &DevReq,
> +                    EfiUsbDataOut,
> +                    WDR_TIMEOUT,
> +                    &ConfigurationValue,
> +                    1,
> +                    &ReturnValue
> +                    );
> +  if (EFI_ERROR (Status)) {
> +    goto StatusError;
> +  }
> +  return Status;
> +
> +StatusError:
> +  if ((Status != EFI_INVALID_PARAMETER) ||
> +      (Status != EFI_DEVICE_ERROR)      ||
> +      (Status != EFI_UNSUPPORTED)          ) {
> +    return EFI_DEVICE_ERROR;
> +  } else {
> +    return Status;
> +  }
> +}
> +
> +/**
> +  Internal function that performs a Usb Control Transfer to set the Dtr value
> on
> +  the Usb Serial Device.
> +
> +  @param  UsbIo[in]                  Usb Io Protocol instance pointer
> +  @param  RtsEnable[in]              Data on the Enable/Disable status of the
> +                                     Rts for the Usb Serial Device
> +
> +  @retval EFI_SUCCESS                The Rts value was set on the Usb Serial
> +                                     Device
> +  @retval EFI_INVALID_PARAMETER      An invalid Rts value was used
> +  @retval EFI_UNSUPPORTED            The operation is not supported
> +  @retval EFI_DEVICE_ERROR           The device is not functioning correctly
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetRtsInternal (
> +  IN EFI_USB_IO_PROTOCOL  *UsbIo,
> +  IN BOOLEAN              RtsEnable
> +  )
> +{
> +  EFI_STATUS              Status;
> +  EFI_USB_DEVICE_REQUEST  DevReq;
> +  UINT32                  ReturnValue;
> +  UINT8                   ConfigurationValue;
> +
> +  //
> +  // set DevReq.Value based on the value of RtsEnable
> +  //
> +  if (!RtsEnable) {
> +    DevReq.Value = SET_RTS_LOW;
> +  }
> +  if (RtsEnable) {
> +    DevReq.Value = SET_RTS_HIGH;
> +  }
> +
> +  //
> +  // set the remaining parameters of DevReq and perform the usb control
> transfer
> +  // to set the values on the device
> +  //
> +  DevReq.Request     = FTDI_COMMAND_MODEM_CTRL;
> +  DevReq.RequestType = USB_REQ_TYPE_VENDOR;
> +  DevReq.Index       = FTDI_PORT_IDENTIFIER;
> +  DevReq.Length      = 0; // indicates that there is no data phase in this
> request
> +
> +  Status = UsbIo->UsbControlTransfer (
> +                    UsbIo,
> +                    &DevReq,
> +                    EfiUsbDataOut,
> +                    WDR_TIMEOUT,
> +                    &ConfigurationValue,
> +                    1,
> +                    &ReturnValue
> +                    );
> +  if (EFI_ERROR (Status)) {
> +    goto StatusError;
> +  }
> +
> +  return Status;
> +
> +StatusError:
> +  if ((Status != EFI_INVALID_PARAMETER) ||
> +      (Status != EFI_DEVICE_ERROR)      ||
> +      (Status != EFI_UNSUPPORTED)          ) {
> +    return EFI_DEVICE_ERROR;
> +  } else {
> +    return Status;
> +  }
> +}
> +
> +/**
> +  Internal function that checks for valid control values and sets the control
> +  bits on the Usb Serial Device.
> +
> +  @param  UsbSerialDevice[in]        Handle to the Usb Serial Device whose
> +                                     control bits are being set
> +  @param  Control[in]                The control value passed to the function
> +                                     that contains the values of the control
> +                                     bits that are being set
> +
> +  @retval EFI_SUCCESS                The control bits were set on the Usb Serial
> +                                     Device
> +  @retval EFI_INVALID_PARAMETER      An invalid control value was
> encountered
> +  @retval EFI_EFI_UNSUPPORTED        The operation is not supported
> +  @retval EFI_DEVICE_ERROR           The device is not functioning correctly
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetControlBitsInternal (
> +  IN USB_SER_DEV   *UsbSerialDevice,
> +  IN CONTROL_BITS  *Control
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  UART_FLOW_CONTROL_DEVICE_PATH *FlowControl;
> +  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath;
> +
> +  //
> +  // check for invalid control parameters hardware and software loopback
> enabled
> +  // must always be set to FALSE
> +  //
> +  Control->HardwareLoopBack = FALSE;
> +  Control->SoftwareLoopBack = FALSE;
> +
> +  //
> +  // set hardware flow control
> +  //
> +  Status  = SetFlowControlInternal (
> +              UsbSerialDevice->UsbIo,
> +              Control->HardwareFlowControl
> +              );
> +  if (EFI_ERROR (Status)) {
> +    goto StatusError;
> +  }
> +
> +  //
> +  // set Dtr state
> +  //
> +  Status = SetDtrInternal (UsbSerialDevice->UsbIo, Control->DtrState);
> +  if (EFI_ERROR (Status)) {
> +    goto StatusError;
> +  }
> +
> +  //
> +  // set Rts state
> +  //
> +  Status = SetRtsInternal (UsbSerialDevice->UsbIo, Control->RtsState);
> +  if (EFI_ERROR (Status)){
> +    goto StatusError;
> +  }
> +
> +  //
> +  // update the remaining control values for UsbSerialDevice->ControlValues
> +  //
> +  UsbSerialDevice->ControlValues.DtrState            = Control->DtrState;
> +  UsbSerialDevice->ControlValues.RtsState            = Control->RtsState;
> +  UsbSerialDevice->ControlValues.HardwareFlowControl = Control-
> >HardwareFlowControl;
> +  UsbSerialDevice->ControlValues.HardwareLoopBack    = FALSE;
> +  UsbSerialDevice->ControlValues.SoftwareLoopBack    = FALSE;
> +
> +  Status = EFI_SUCCESS;
> +  //
> +  // Update the device path to have the correct flow control values
> +  //
> +  if (UsbSerialDevice->ControllerHandle != NULL) {
> +    RemainingDevicePath = UsbSerialDevice->DevicePath;
> +    while (!IsDevicePathEnd (RemainingDevicePath)) {
> +      FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *)
> NextDevicePathNode (RemainingDevicePath);
> +      if (FlowControl->Header.Type == MESSAGING_DEVICE_PATH &&
> +          FlowControl->Header.SubType == MSG_VENDOR_DP &&
> +          sizeof (UART_FLOW_CONTROL_DEVICE_PATH) ==
> DevicePathNodeLength ((EFI_DEVICE_PATH *) FlowControl)){
> +        if (UsbSerialDevice->ControlValues.HardwareFlowControl == TRUE) {
> +          FlowControl->FlowControlMap = UART_FLOW_CONTROL_HARDWARE;
> +        } else if (UsbSerialDevice->ControlValues.HardwareFlowControl ==
> FALSE) {
> +          FlowControl->FlowControlMap = 0;
> +        }
> +        break;
> +      }
> +      RemainingDevicePath = NextDevicePathNode (RemainingDevicePath);
> +    }
> +  }
> +
> +  return Status;
> +
> +StatusError:
> +  if ((Status != EFI_INVALID_PARAMETER) ||
> +      (Status != EFI_DEVICE_ERROR)      ||
> +      (Status != EFI_UNSUPPORTED)          ) {
> +    return EFI_DEVICE_ERROR;
> +  } else {
> +    return Status;
> +  }
> +}
> +
> +/**
> +  Internal function that calculates the Control value used by GetControlBits()
> +  based on the status and control values of the Usb Serial Device.
> +
> +  @param  UsbSerialDevice[in]        Handle to the Usb Serial Devie whose
> status
> +                                     and control values are being used to set
> +                                     Control
> +  @param  Control[out]               On output the formated value of Control
> +                                     that has been calculated based on the
> +                                     control and status values of the Usb Serial
> +                                     Device
> +
> +  @retval EFI_SUCCESS                The value of Control was successfully
> +                                     calculated
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetControlBitsInternal (
> +  IN USB_SER_DEV  *UsbSerialDevice,
> +  OUT UINT32      *Control
> +  )
> +{
> +  *Control = 0;
> +
> +  //
> +  // Check the values of UsbSerialDevice->Status Values and modify control
> +  // accordingly these values correspond to the modem status register
> +  //
> +  if (UsbSerialDevice->StatusValues.CtsState) {
> +    *Control |= EFI_SERIAL_CLEAR_TO_SEND;
> +  }
> +  if (UsbSerialDevice->StatusValues.DsrState) {
> +    *Control |= EFI_SERIAL_DATA_SET_READY;
> +  }
> +  if (UsbSerialDevice->StatusValues.RiState) {
> +    *Control |= EFI_SERIAL_RING_INDICATE;
> +  }
> +  if (UsbSerialDevice->StatusValues.SdState) {
> +    *Control |= EFI_SERIAL_CARRIER_DETECT;
> +  }
> +
> +  //
> +  // check the values of UsbSerialDevice->ControlValues and modify control
> +  // accordingly these values correspond to the values of the Modem
> Control
> +  // Register
> +  //
> +  if (UsbSerialDevice->ControlValues.DtrState) {
> +    *Control |= EFI_SERIAL_DATA_TERMINAL_READY;
> +  }
> +  if (UsbSerialDevice->ControlValues.RtsState) {
> +    *Control |= EFI_SERIAL_REQUEST_TO_SEND;
> +  }
> +  if (UsbSerialDevice->ControlValues.HardwareLoopBack) {
> +    *Control |= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE;
> +  }
> +  if (UsbSerialDevice->ControlValues.HardwareFlowControl) {
> +    *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
> +  }
> +  //
> +  // check if the buffer is empty since only one is being used if it is empty
> +  // set both the receive and transmit buffers to empty
> +  //
> +  if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {
> +    *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY;
> +    *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
> +  }
> +  //
> +  // check for software loopback enable in UsbSerialDevice->ControlValues
> +  //
> +  if (UsbSerialDevice->ControlValues.SoftwareLoopBack) {
> +    *Control |= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Resets the USB Serial Device
> +
> +  This function is the internal method for resetting the device and is called
> by
> +  SerialReset()
> +
> +  @param  UsbSerialDevice[in]  A pointer to the USB Serial device
> +
> +  @retval EFI_SUCCESS          The device was reset
> +  @retval EFI_DEVICE_ERROR     The device could not be reset
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +ResetInternal (
> +  IN USB_SER_DEV  *UsbSerialDevice
> +  )
> +{
> +  EFI_STATUS              Status;
> +  EFI_USB_DEVICE_REQUEST  DevReq;
> +  UINT8                   ConfigurationValue;
> +  UINT32                  ReturnValue;
> +
> +  DevReq.Request     = FTDI_COMMAND_RESET_PORT;
> +  DevReq.RequestType = USB_REQ_TYPE_VENDOR;
> +  DevReq.Value       = RESET_PORT_PURGE_RX;
> +  DevReq.Index       = FTDI_PORT_IDENTIFIER;
> +  DevReq.Length      = 0; //indicates that there is not data phase in this
> request
> +
> +  Status = UsbSerialDevice->UsbIo->UsbControlTransfer (
> +                                     UsbSerialDevice->UsbIo,
> +                                     &DevReq,
> +                                     EfiUsbDataIn,
> +                                     WDR_TIMEOUT,
> +                                     &ConfigurationValue,
> +                                     1,
> +                                     &ReturnValue
> +                                     );
> +  if (EFI_ERROR (Status)) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  DevReq.Request     = FTDI_COMMAND_RESET_PORT;
> +  DevReq.RequestType = USB_REQ_TYPE_VENDOR;
> +  DevReq.Value       = RESET_PORT_PURGE_TX;
> +  DevReq.Index       = FTDI_PORT_IDENTIFIER;
> +  DevReq.Length      = 0; //indicates that there is no data phase in this
> request
> +
> +  Status = UsbSerialDevice->UsbIo->UsbControlTransfer (
> +                                     UsbSerialDevice->UsbIo,
> +                                     &DevReq,
> +                                     EfiUsbDataIn,
> +                                     WDR_TIMEOUT,
> +                                     &ConfigurationValue,
> +                                     1,
> +                                     &ReturnValue
> +                                     );
> +  if (EFI_ERROR (Status)) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +  return Status;
> +}
> +
> +/**
> +  Entrypoint of USB Serial Driver.
> +
> +  This function is the entrypoint of USB Serial Driver. It installs
> +  Driver Binding Protocols together with Component Name Protocols.
> +
> +  @param  ImageHandle[in]       The firmware allocated handle for the EFI
> image.
> +  @param  SystemTable[in]       A pointer to the EFI System Table.
> +
> +  @retval EFI_SUCCESS           The entry point is executed successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +FtdiUsbSerialEntryPoint (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  Status = EfiLibInstallDriverBindingComponentName2 (
> +             ImageHandle,
> +             SystemTable,
> +             &gUsbSerialDriverBinding,
> +             ImageHandle,
> +             &gUsbSerialComponentName,
> +             &gUsbSerialComponentName2
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Unload function for the Usb Serial Driver.
> +
> +  @param  ImageHandle[in]    The allocated handle for the EFI image
> +
> +  @retval EFI_SUCCESS        The driver was unloaded successfully
> +**/
> +EFI_STATUS
> +EFIAPI
> +FtdiUsbSerialUnload (
> +  IN EFI_HANDLE  ImageHandle
> +  )
> +{
> +  EFI_STATUS  Status;
> +  EFI_HANDLE  *HandleBuffer;
> +  UINTN       HandleCount;
> +  UINTN       Index;
> +
> +  //
> +  // Retrieve all handles in the handle database
> +  //
> +  Status = gBS->LocateHandleBuffer (
> +                  AllHandles,
> +                  NULL,
> +                  NULL,
> +                  &HandleCount,
> +                  &HandleBuffer
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Disconnect the driver from the handles in the handle database
> +  //
> +  for (Index = 0; Index < HandleCount; Index++) {
> +    Status = gBS->DisconnectController (
> +                    HandleBuffer[Index],
> +                    gImageHandle,
> +                    NULL
> +                    );
> +  }
> +
> +  //
> +  // Free the handle array
> +  //
> +  FreePool (HandleBuffer);
> +
> +  //
> +  // Uninstall protocols installed by the driver in its entrypoint
> +  //
> +  Status = gBS->UninstallMultipleProtocolInterfaces (
> +                  ImageHandle,
> +                  &gEfiDriverBindingProtocolGuid,
> +                  &gUsbSerialDriverBinding,
> +                  &gEfiComponentNameProtocolGuid,
> +                  &gUsbSerialComponentName,
> +                  &gEfiComponentName2ProtocolGuid,
> +                  &gUsbSerialComponentName2,
> +                  NULL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Check whether USB Serial driver supports this device.
> +
> +  @param  This[in]                   The USB Serial driver binding protocol.
> +  @param  Controller[in]             The controller handle to check.
> +  @param  RemainingDevicePath[in]    The remaining device path.
> +
> +  @retval EFI_SUCCESS                The driver supports this controller.
> +  @retval other                      This device isn't supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbSerialDriverBindingSupported (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> +  )
> +{
> +  EFI_STATUS           Status;
> +  EFI_USB_IO_PROTOCOL  *UsbIo;
> +  UART_DEVICE_PATH     *UartNode;
> +  UART_FLOW_CONTROL_DEVICE_PATH        *FlowControlNode;
> +  UINTN                                Index;
> +  UINTN                                EntryCount;
> +  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY  *OpenInfoBuffer;
> +  BOOLEAN                              HasFlowControl;
> +  EFI_DEVICE_PATH_PROTOCOL             *DevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL             *ParentDevicePath;
> +
> +  if (RemainingDevicePath != NULL) {
> +    if (!IsDevicePathEnd (RemainingDevicePath)) {
> +      Status = EFI_UNSUPPORTED;
> +      UartNode = (UART_DEVICE_PATH *) NextDevicePathNode
> (RemainingDevicePath);
> +      if (UartNode->Header.Type != MESSAGING_DEVICE_PATH ||
> +          UartNode->Header.SubType != MSG_UART_DP ||
> +          sizeof (UART_DEVICE_PATH) != DevicePathNodeLength
> ((EFI_DEVICE_PATH *) UartNode)) {
> +        goto Error;
> +      }
> +      FlowControlNode = (UART_FLOW_CONTROL_DEVICE_PATH *)
> NextDevicePathNode (UartNode);
> +      if ((ReadUnaligned32 (&FlowControlNode->FlowControlMap) &
> ~UART_FLOW_CONTROL_HARDWARE) != 0) {
> +        goto Error;
> +      }
> +    }
> +  }
> +
> +  //
> +  // Check if USB I/O Protocol is attached on the controller handle.
> +  //
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiUsbIoProtocolGuid,
> +                  (VOID **) &UsbIo,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +  if (Status == EFI_ALREADY_STARTED) {
> +    if (RemainingDevicePath == NULL || IsDevicePathEnd
> (RemainingDevicePath)) {
> +      return EFI_SUCCESS;
> +    }
> +    Status = gBS->OpenProtocolInformation (
> +                    Controller,
> +                    &gEfiUsbIoProtocolGuid,
> +                    &OpenInfoBuffer,
> +                    &EntryCount
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +    for (Index = 0; Index < EntryCount; Index++) {
> +      if ((OpenInfoBuffer[Index].Attributes &
> EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
> +        Status = gBS->OpenProtocol (
> +                        OpenInfoBuffer[Index].ControllerHandle,
> +                        &gEfiDevicePathProtocolGuid,
> +                        (VOID **) &DevicePath,
> +                        This->DriverBindingHandle,
> +                        Controller,
> +                        EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                        );
> +        if (!EFI_ERROR (Status)) {
> +          HasFlowControl = ContainsFlowControl (RemainingDevicePath);
> +          if (HasFlowControl ^ ContainsFlowControl (DevicePath)) {
> +            Status = EFI_UNSUPPORTED;
> +          }
> +        }
> +        break;
> +      }
> +    }
> +    FreePool (OpenInfoBuffer);
> +    return Status;
> +  }
> +
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  gBS->CloseProtocol (
> +         Controller,
> +         &gEfiUsbIoProtocolGuid,
> +         This->DriverBindingHandle,
> +         Controller
> +         );
> +
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiDevicePathProtocolGuid,
> +                  (VOID **) &ParentDevicePath,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +  if (Status == EFI_ALREADY_STARTED) {
> +    return EFI_SUCCESS;
> +  }
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Use the USB I/O Protocol interface to check whether Controller is
> +  // a USB Serial device that can be managed by this driver.
> +  //
> +  Status = EFI_SUCCESS;
> +
> +  if (!IsUsbSerial (UsbIo)) {
> +    Status = EFI_UNSUPPORTED;
> +    goto Error;
> +  }
> +
> +Error:
> +  gBS->CloseProtocol (
> +         Controller,
> +         &gEfiDevicePathProtocolGuid,
> +         This->DriverBindingHandle,
> +         Controller
> +         );
> +  return Status;
> +}
> +
> +/**
> +  Starts the USB Serial device with this driver.
> +
> +  This function produces initializes the USB Serial device and
> +  produces the Serial IO Protocol.
> +
> +  @param  This[in]                   The USB Serial driver binding instance.
> +  @param  Controller[in]             Handle of device to bind driver to.
> +  @param  RemainingDevicePath[in]    Optional parameter use to pick a
> specific
> +                                     child device to start.
> +
> +  @retval EFI_SUCCESS                The controller is controlled by the usb USB
> +                                     Serial driver.
> +  @retval EFI_UNSUPPORTED            No interrupt endpoint can be found.
> +  @retval Other                      This controller cannot be started.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbSerialDriverBindingStart (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> +  )
> +{
> +  EFI_STATUS                          Status;
> +  EFI_USB_IO_PROTOCOL                 *UsbIo;
> +  USB_SER_DEV                         *UsbSerialDevice;
> +  UINT8                               EndpointNumber;
> +  EFI_USB_ENDPOINT_DESCRIPTOR         EndpointDescriptor;
> +  UINT8                               Index;
> +  BOOLEAN                             FoundIn;
> +  BOOLEAN                             FoundOut;
> +  EFI_DEVICE_PATH_PROTOCOL            *ParentDevicePath;
> +  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
> +  UINTN                               EntryCount;
> +  EFI_SERIAL_IO_PROTOCOL              *SerialIo;
> +  UART_DEVICE_PATH                    *Uart;
> +  UART_FLOW_CONTROL_DEVICE_PATH       *FlowControl;
> +  UINT32                              Control;
> +  EFI_DEVICE_PATH_PROTOCOL            *TempDevicePath;
> +
> +  UsbSerialDevice = AllocateZeroPool (sizeof (USB_SER_DEV));
> +  ASSERT (UsbSerialDevice != NULL);
> +
> +  //
> +  // Get the Parent Device path
> +  //
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiDevicePathProtocolGuid,
> +                  (VOID **) &ParentDevicePath,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
> +    goto ErrorExit1;
> +  }
> +
> +  //
> +  // Open USB I/O Protocol
> +  //
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiUsbIoProtocolGuid,
> +                  (VOID **) &UsbIo,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
> +    goto ErrorExit1;
> +  }
> +
> +  if (Status == EFI_ALREADY_STARTED) {
> +    if (RemainingDevicePath == NULL || IsDevicePathEnd
> (RemainingDevicePath)) {
> +      FreePool (UsbSerialDevice);
> +      return EFI_SUCCESS;
> +    }
> +
> +    //
> +    // Check to see if a child handle exists
> +    //
> +    Status = gBS->OpenProtocolInformation (
> +                    Controller,
> +                    &gEfiSerialIoProtocolGuid,
> +                    &OpenInfoBuffer,
> +                    &EntryCount
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      goto ErrorExit1;
> +    }
> +
> +    Status = EFI_ALREADY_STARTED;
> +    for (Index = 0; Index < EntryCount; Index++) {
> +      if ((OpenInfoBuffer[Index].Attributes &
> EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
> +        Status = gBS->OpenProtocol (
> +                        OpenInfoBuffer[Index].ControllerHandle,
> +                        &gEfiSerialIoProtocolGuid,
> +                        (VOID **) &SerialIo,
> +                        This->DriverBindingHandle,
> +                        Controller,
> +                        EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                        );
> +        if (EFI_ERROR (Status)) {
> +        }
> +        if (!EFI_ERROR (Status)) {
> +          Uart = (UART_DEVICE_PATH *) RemainingDevicePath;
> +          Status = SerialIo->SetAttributes (
> +                               SerialIo,
> +                               Uart->BaudRate,
> +                               SerialIo->Mode->ReceiveFifoDepth,
> +                               SerialIo->Mode->Timeout,
> +                               (EFI_PARITY_TYPE) Uart->Parity,
> +                               Uart->DataBits,
> +                               (EFI_STOP_BITS_TYPE) Uart->StopBits
> +                               );
> +          FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *)
> NextDevicePathNode (Uart);
> +          if (!EFI_ERROR (Status) && IsUartFlowControlNode (FlowControl)) {
> +            Status = SerialIo->GetControl (
> +                                 SerialIo,
> +                                 &Control
> +                                 );
> +            if (!EFI_ERROR (Status)) {
> +              if (ReadUnaligned32 (&FlowControl->FlowControlMap) ==
> UART_FLOW_CONTROL_HARDWARE) {
> +                Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
> +              } else {
> +                Control &= ~EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
> +              }
> +              //
> +              // Clear bits that are not allowed to be passed to SetControl
> +              //
> +              Control &= (EFI_SERIAL_REQUEST_TO_SEND |
> +                          EFI_SERIAL_DATA_TERMINAL_READY |
> +                          EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE |
> +                          EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE |
> +                          EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE);
> +              Status = SerialIo->SetControl (SerialIo, Control);
> +            }
> +          }
> +        }
> +        break;
> +      }
> +    }
> +    FreePool (OpenInfoBuffer);
> +    return Status;
> +  }
> +
> +  if (RemainingDevicePath != NULL) {
> +    if (IsDevicePathEnd (RemainingDevicePath)) {
> +      return EFI_SUCCESS;
> +    }
> +  }
> +
> +  UsbSerialDevice->UsbIo = UsbIo;
> +
> +  //
> +  // Get interface & endpoint descriptor
> +  //
> +  UsbIo->UsbGetInterfaceDescriptor (
> +           UsbIo,
> +           &UsbSerialDevice->InterfaceDescriptor
> +           );
> +
> +  EndpointNumber = UsbSerialDevice->InterfaceDescriptor.NumEndpoints;
> +
> +  //
> +  // Traverse endpoints to find the IN and OUT endpoints that will send and
> +  // receive data.
> +  //
> +  FoundIn = FALSE;
> +  FoundOut = FALSE;
> +  for (Index = 0; Index < EndpointNumber; Index++) {
> +
> +    Status = UsbIo->UsbGetEndpointDescriptor (
> +                      UsbIo,
> +                      Index,
> +                      &EndpointDescriptor
> +                      );
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +
> +    if (EndpointDescriptor.EndpointAddress ==
> FTDI_ENDPOINT_ADDRESS_OUT) {
> +      //
> +      // Set the Out endpoint device
> +      //
> +      CopyMem (
> +        &UsbSerialDevice->OutEndpointDescriptor,
> +        &EndpointDescriptor,
> +        sizeof(EndpointDescriptor)
> +        );
> +      FoundOut = TRUE;
> +    }
> +
> +    if (EndpointDescriptor.EndpointAddress ==
> FTDI_ENDPOINT_ADDRESS_IN) {
> +      //
> +      // Set the In endpoint device
> +      //
> +      CopyMem (
> +        &UsbSerialDevice->InEndpointDescriptor,
> +        &EndpointDescriptor,
> +        sizeof(EndpointDescriptor)
> +        );
> +      FoundIn = TRUE;
> +    }
> +  }
> +
> +  if (!FoundIn || !FoundOut) {
> +    //
> +    // No interrupt endpoint found, then return unsupported.
> +    //
> +    Status = EFI_UNSUPPORTED;
> +    goto ErrorExit;
> +  }
> +  //
> +  // set the initial values of UsbSerialDevice->LastSettings to the default
> +  // values
> +  //
> +  UsbSerialDevice->LastSettings.BaudRate         = 115200;
> +  UsbSerialDevice->LastSettings.DataBits         = 8;
> +  UsbSerialDevice->LastSettings.Parity           = NoParity;
> +  UsbSerialDevice->LastSettings.ReceiveFifoDepth =
> FTDI_MAX_RECEIVE_FIFO_DEPTH;
> +  UsbSerialDevice->LastSettings.StopBits         = OneStopBit;
> +  UsbSerialDevice->LastSettings.Timeout          = FTDI_TIMEOUT;
> +
> +  //
> +  // set the initial values of UsbSerialDevice->ControlValues
> +  //
> +  UsbSerialDevice->ControlValues.DtrState            = FALSE;
> +  UsbSerialDevice->ControlValues.RtsState            = FALSE;
> +  UsbSerialDevice->ControlValues.HardwareFlowControl = FALSE;
> +  UsbSerialDevice->ControlValues.HardwareLoopBack    = FALSE;
> +  UsbSerialDevice->ControlValues.SoftwareLoopBack    = FALSE;
> +
> +  //
> +  // set the values of UsbSerialDevice->UartDevicePath
> +  //
> +  UsbSerialDevice->UartDevicePath.Header.Type    =
> MESSAGING_DEVICE_PATH;
> +  UsbSerialDevice->UartDevicePath.Header.SubType = MSG_UART_DP;
> +  UsbSerialDevice->UartDevicePath.Header.Length[0] = (UINT8) (sizeof
> (UART_DEVICE_PATH));
> +  UsbSerialDevice->UartDevicePath.Header.Length[1] = (UINT8) ((sizeof
> (UART_DEVICE_PATH)) >> 8);
> +
> +  //
> +  // set the values of UsbSerialDevice->FlowControlDevicePath
> +  UsbSerialDevice->FlowControlDevicePath.Header.Type =
> MESSAGING_DEVICE_PATH;
> +  UsbSerialDevice->FlowControlDevicePath.Header.SubType =
> MSG_VENDOR_DP;
> +  UsbSerialDevice->FlowControlDevicePath.Header.Length[0] = (UINT8)
> (sizeof (UART_FLOW_CONTROL_DEVICE_PATH));
> +  UsbSerialDevice->FlowControlDevicePath.Header.Length[1] = (UINT8)
> ((sizeof (UART_FLOW_CONTROL_DEVICE_PATH)) >> 8);
> +  UsbSerialDevice->FlowControlDevicePath.FlowControlMap = 0;
> +
> +  Status = SetAttributesInternal (
> +             UsbSerialDevice,
> +             UsbSerialDevice->LastSettings.BaudRate,
> +             UsbSerialDevice->LastSettings.ReceiveFifoDepth,
> +             UsbSerialDevice->LastSettings.Timeout,
> +             UsbSerialDevice->LastSettings.Parity,
> +             UsbSerialDevice->LastSettings.DataBits,
> +             UsbSerialDevice->LastSettings.StopBits
> +             );
> +
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = SetControlBitsInternal (
> +             UsbSerialDevice,
> +             &(UsbSerialDevice->ControlValues)
> +             );
> +
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Publish Serial GUID and protocol
> +  //
> +
> +  UsbSerialDevice->Signature              = USB_SER_DEV_SIGNATURE;
> +  UsbSerialDevice->SerialIo.Reset         = SerialReset;
> +  UsbSerialDevice->SerialIo.SetControl    = SetControlBits;
> +  UsbSerialDevice->SerialIo.SetAttributes = SetAttributes;
> +  UsbSerialDevice->SerialIo.GetControl    = GetControlBits;
> +  UsbSerialDevice->SerialIo.Read          = ReadSerialIo;
> +  UsbSerialDevice->SerialIo.Write         = WriteSerialIo;
> +
> +  //
> +  // Set the static Serial IO modes that will display when running
> +  // "sermode" within the UEFI shell.
> +  //
> +
> +  UsbSerialDevice->SerialIo.Mode->Timeout  = 0;
> +  UsbSerialDevice->SerialIo.Mode->BaudRate = 115200;
> +  UsbSerialDevice->SerialIo.Mode->DataBits = 8;
> +  UsbSerialDevice->SerialIo.Mode->Parity   = 1;
> +  UsbSerialDevice->SerialIo.Mode->StopBits = 1;
> +
> +  UsbSerialDevice->ParentDevicePath = ParentDevicePath;
> +  UsbSerialDevice->ControllerHandle = NULL;
> +  FlowControl                       = NULL;
> +
> +  //
> +  // Allocate space for the receive buffer
> +  //
> +  UsbSerialDevice->DataBuffer = AllocateZeroPool (SW_FIFO_DEPTH);
> +
> +  //
> +  // Initialize data buffer pointers.
> +  // Head==Tail = true means buffer is empty.
> +  //
> +  UsbSerialDevice->DataBufferHead = 0;
> +  UsbSerialDevice->DataBufferTail = 0;
> +
> +  UsbSerialDevice->ControllerNameTable = NULL;
> +  AddUnicodeString2 (
> +    "eng",
> +    gUsbSerialComponentName.SupportedLanguages,
> +    &UsbSerialDevice->ControllerNameTable,
> +    L"FTDI USB Serial Adapter",
> +    TRUE
> +    );
> +  AddUnicodeString2 (
> +    "en",
> +    gUsbSerialComponentName2.SupportedLanguages,
> +    &UsbSerialDevice->ControllerNameTable,
> +    L"FTDI USB Serial Adapter",
> +    FALSE
> +    );
> +
> +  Status = SetInitialStatus (UsbSerialDevice);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Create a polling loop to check for input
> +  //
> +
> +  gBS->CreateEvent (
> +         EVT_TIMER | EVT_NOTIFY_SIGNAL,
> +         TPL_CALLBACK,
> +         UsbSerialDriverCheckInput,
> +         UsbSerialDevice,
> +         &(UsbSerialDevice->PollingLoop)
> +         );
> +  //
> +  // add code to set trigger time based on baud rate
> +  // setting to 0.5s for now
> +  //
> +  gBS->SetTimer (
> +         UsbSerialDevice->PollingLoop,
> +         TimerPeriodic,
> +         EFI_TIMER_PERIOD_MILLISECONDS (500)
> +         );
> +
> +  //
> +  // Check if the remaining device path is null. If it is not null change the
> settings
> +  // of the device to match those on the device path
> +  //
> +  if (RemainingDevicePath != NULL) {
> +    CopyMem (
> +      &UsbSerialDevice->UartDevicePath,
> +      RemainingDevicePath,
> +      sizeof (UART_DEVICE_PATH)
> +      );
> +    FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *)
> NextDevicePathNode (RemainingDevicePath);
> +    if (IsUartFlowControlNode (FlowControl)) {
> +      UsbSerialDevice->FlowControlDevicePath.FlowControlMap =
> ReadUnaligned32 (&FlowControl->FlowControlMap);
> +    } else {
> +      FlowControl = NULL;
> +    }
> +  }
> +
> +  //
> +  // Build the device path by appending the UART node to the parent device
> path
> +  //
> +  UsbSerialDevice->DevicePath = AppendDevicePathNode (
> +                                  ParentDevicePath,
> +                                  (EFI_DEVICE_PATH_PROTOCOL *) &UsbSerialDevice-
> >UartDevicePath
> +                                  );
> +  //
> +  // Continue building the device path by appending the flow control node
> +  //
> +  TempDevicePath = UsbSerialDevice->DevicePath;
> +  UsbSerialDevice->DevicePath = AppendDevicePathNode (
> +                                  TempDevicePath,
> +                                  (EFI_DEVICE_PATH_PROTOCOL *) &UsbSerialDevice-
> >FlowControlDevicePath
> +                                  );
> +  FreePool (TempDevicePath);
> +
> +  if (UsbSerialDevice->DevicePath == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto ErrorExit;
> +  }
> +
> +  //
> +  // Install protocol interfaces for the device
> +  //
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &UsbSerialDevice->ControllerHandle,
> +                  &gEfiDevicePathProtocolGuid,
> +                  UsbSerialDevice->DevicePath,
> +                  &gEfiSerialIoProtocolGuid,
> +                  &UsbSerialDevice->SerialIo,
> +                  NULL
> +                  );
> +  if (EFI_ERROR (Status)){
> +    goto ErrorExit;
> +  }
> +
> +  //
> +  // Open for child device
> +  //
> +  Status = gBS->OpenProtocol (
> +                 Controller,
> +                 &gEfiUsbIoProtocolGuid,
> +                 (VOID **) &UsbIo,
> +                 This->DriverBindingHandle,
> +                 UsbSerialDevice->ControllerHandle,
> +                 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
> +                 );
> +
> +  UsbSerialDevice->Shutdown = FALSE;
> +
> +  return EFI_SUCCESS;
> +
> +ErrorExit:
> +  //
> +  // Error handler
> +  //
> +
> +  Status = gBS->UninstallMultipleProtocolInterfaces (
> +                  Controller,
> +                  &gEfiSerialIoProtocolGuid,
> +                  &UsbSerialDevice->SerialIo,
> +                  NULL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    goto ErrorExit1;
> +  }
> +
> +  FreePool (UsbSerialDevice->DataBuffer);
> +  FreePool (UsbSerialDevice);
> +
> +  UsbSerialDevice = NULL;
> +  gBS->CloseProtocol (
> +         Controller,
> +         &gEfiUsbIoProtocolGuid,
> +         This->DriverBindingHandle,
> +         Controller
> +         );
> +
> +ErrorExit1:
> +  return Status;
> +}
> +
> +/**
> +  Stop the USB Serial device handled by this driver.
> +
> +  @param  This[in]                   The USB Serial driver binding protocol.
> +  @param  Controller[in]             The controller to release.
> +  @param  NumberOfChildren[in]       The number of handles in
> ChildHandleBuffer.
> +  @param  ChildHandleBuffer[in]      The array of child handle.
> +
> +  @retval EFI_SUCCESS                The device was stopped.
> +  @retval EFI_UNSUPPORTED            Serial IO Protocol is not installed on
> +                                     Controller.
> +  @retval EFI_DEVICE_ERROR           The device could not be stopped due to
> a
> +                                     device error.
> +  @retval Others                     Fail to uninstall protocols attached on the
> +                                     device.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbSerialDriverBindingStop (
> +  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN  EFI_HANDLE                   Controller,
> +  IN  UINTN                        NumberOfChildren,
> +  IN  EFI_HANDLE                   *ChildHandleBuffer
> +  )
> +{
> +  EFI_STATUS                Status;
> +  EFI_SERIAL_IO_PROTOCOL    *SerialIo;
> +  EFI_USB_IO_PROTOCOL       *UsbIo;
> +  USB_SER_DEV               *UsbSerialDevice;
> +  UINTN                     Index;
> +  BOOLEAN                   AllChildrenStopped;
> +
> +  Status = EFI_SUCCESS;
> +  UsbSerialDevice = NULL;
> +
> +  if (NumberOfChildren == 0) {
> +    //
> +    // Close the driver
> +    //
> +    Status = gBS->CloseProtocol (
> +                    Controller,
> +                    &gEfiUsbIoProtocolGuid,
> +                    This->DriverBindingHandle,
> +                    Controller
> +                    );
> +    Status = gBS->CloseProtocol (
> +                    Controller,
> +                    &gEfiDevicePathProtocolGuid,
> +                    This->DriverBindingHandle,
> +                    Controller
> +                    );
> +    return Status;
> +  }
> +
> +  AllChildrenStopped = TRUE;
> +
> +  for (Index = 0; Index < NumberOfChildren ;Index++) {
> +    Status = gBS->OpenProtocol (
> +                    ChildHandleBuffer[Index],
> +                    &gEfiSerialIoProtocolGuid,
> +                    (VOID **) &SerialIo,
> +                    This->DriverBindingHandle,
> +                    Controller,
> +                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                    );
> +    if (Status == EFI_SUCCESS) {//!EFI_ERROR (Status)) {
> +      UsbSerialDevice = USB_SER_DEV_FROM_THIS (SerialIo);
> +      Status = gBS->CloseProtocol (
> +                      Controller,
> +                      &gEfiUsbIoProtocolGuid,
> +                      This->DriverBindingHandle,
> +                      ChildHandleBuffer[Index]
> +                      );
> +      Status = gBS->UninstallMultipleProtocolInterfaces (
> +                      ChildHandleBuffer[Index],
> +                      &gEfiDevicePathProtocolGuid,
> +                      UsbSerialDevice->DevicePath,
> +                      &gEfiSerialIoProtocolGuid,
> +                      &UsbSerialDevice->SerialIo,
> +                      NULL
> +                      );
> +
> +      if (EFI_ERROR (Status)) {
> +        gBS->OpenProtocol (
> +               Controller,
> +               &gEfiUsbIoProtocolGuid,
> +               (VOID **) &UsbIo,
> +               This->DriverBindingHandle,
> +               ChildHandleBuffer[Index],
> +               EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
> +               );
> +      } else {
> +        if (UsbSerialDevice->DevicePath != NULL) {
> +          gBS->FreePool (UsbSerialDevice->DevicePath);
> +        }
> +        gBS->SetTimer (
> +               UsbSerialDevice->PollingLoop,
> +               TimerCancel,
> +               0
> +               );
> +        gBS->CloseEvent (UsbSerialDevice->PollingLoop);
> +        UsbSerialDevice->Shutdown = TRUE;
> +        FreeUnicodeStringTable (UsbSerialDevice->ControllerNameTable);
> +        FreePool (UsbSerialDevice->DataBuffer);
> +        FreePool (UsbSerialDevice);
> +      }
> +    }
> +    if (EFI_ERROR (Status)) {
> +      AllChildrenStopped = FALSE;
> +    }
> +  }
> +
> +  if (!AllChildrenStopped) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +//
> +// Serial IO Member Functions
> +//
> +
> +/**
> +  Reset the serial device.
> +
> +  @param  This[in]              Protocol instance pointer.
> +
> +  @retval EFI_SUCCESS           The device was reset.
> +  @retval EFI_DEVICE_ERROR      The serial device could not be reset.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SerialReset (
> +  IN EFI_SERIAL_IO_PROTOCOL  *This
> +  )
> +{
> +  EFI_STATUS    Status;
> +  USB_SER_DEV  *UsbSerialDevice;
> +
> +  UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
> +  Status          = ResetInternal (UsbSerialDevice);
> +  if (EFI_ERROR (Status)){
> +    return EFI_DEVICE_ERROR;
> +  }
> +  return Status;
> +}
> +
> +/**
> +  Set the control bits on a serial device.
> +
> +  @param  This[in]             Protocol instance pointer.
> +  @param  Control[in]          Set the bits of Control that are settable.
> +
> +  @retval EFI_SUCCESS          The new control bits were set on the serial
> device.
> +  @retval EFI_UNSUPPORTED      The serial device does not support this
> operation.
> +  @retval EFI_DEVICE_ERROR     The serial device is not functioning correctly.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetControlBits (
> +  IN EFI_SERIAL_IO_PROTOCOL  *This,
> +  IN UINT32                  Control
> +  )
> +{
> +  EFI_STATUS    Status;
> +  USB_SER_DEV   *UsbSerialDevice;
> +  CONTROL_BITS  ControlBits;
> +
> +  UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
> +
> +  //
> +  // check for invalid control parameters
> +  //
> +  if ((Control & (~(EFI_SERIAL_REQUEST_TO_SEND          |
> +                    EFI_SERIAL_DATA_TERMINAL_READY      |
> +                    EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE |
> +                    EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE |
> +                    EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE))) != 0 ) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // check the control parameters and set the correct setting for
> +  // the paramerts of ControlBits
> +  // both loopback enables are always set to FALSE
> +  //
> +  ControlBits.HardwareLoopBack = FALSE;
> +  ControlBits.SoftwareLoopBack = FALSE;
> +  //
> +  // check for hardware flow control
> +  //
> +  if ((Control & EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) ==
> EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) {
> +    ControlBits.HardwareFlowControl = TRUE;
> +  } else {
> +    ControlBits.HardwareFlowControl = FALSE;
> +  }
> +  //
> +  // check for DTR enabled
> +  //
> +  if ((Control & EFI_SERIAL_DATA_TERMINAL_READY) ==
> EFI_SERIAL_DATA_TERMINAL_READY) {
> +    ControlBits.DtrState = TRUE;
> +  } else {
> +    ControlBits.DtrState = FALSE;
> +  }
> +  //
> +  // check for RTS enabled
> +  //
> +  if ((Control & EFI_SERIAL_REQUEST_TO_SEND) ==
> EFI_SERIAL_REQUEST_TO_SEND) {
> +    ControlBits.RtsState = TRUE;
> +  } else {
> +    ControlBits.RtsState = FALSE;
> +  }
> +
> +  //
> +  // set the control values with a call to SetControlBitsInternal()
> +  //
> +  Status = SetControlBitsInternal (UsbSerialDevice, &ControlBits);
> +
> +  return Status;
> +}
> +
> +/**
> +  calls SetAttributesInternal() to set the baud rate, receive FIFO depth,
> +  transmit/receive time out, parity, data buts, and stop bits on a serial
> +  device.
> +
> +  @param  This[in]             Protocol instance pointer.
> +  @param  BaudRate[in]         The requested baud rate. A BaudRate value of
> 0
> +                               will use the device's default interface speed.
> +  @param  ReveiveFifoDepth[in] The requested depth of the FIFO on the
> receive
> +                               side of the serial interface. A ReceiveFifoDepth
> +                               value of 0 will use the device's default FIFO
> +                               depth.
> +  @param  Timeout[in]          The requested time out for a single character in
> +                               microseconds.This timeout applies to both the
> +                               transmit and receive side of the interface. A
> +                               Timeout value of 0 will use the device's default
> +                               time out value.
> +  @param  Parity[in]           The type of parity to use on this serial device.
> +                               A Parity value of DefaultParity will use the
> +                               device's default parity value.
> +  @param  DataBits[in]         The number of data bits to use on the serial
> +                               device. A DataBit vaule of 0 will use the
> +                               device's default data bit setting.
> +  @param  StopBits[in]         The number of stop bits to use on this serial
> +                               device. A StopBits value of DefaultStopBits will
> +                               use the device's default number of stop bits.
> +
> +  @retval EFI_SUCCESS          The attributes were set
> +  @retval EFI_DEVICE_ERROR     The attributes were not able to be
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetAttributes (
> +  IN EFI_SERIAL_IO_PROTOCOL  *This,
> +  IN UINT64                  BaudRate,
> +  IN UINT32                  ReceiveFifoDepth,
> +  IN UINT32                  Timeout,
> +  IN EFI_PARITY_TYPE         Parity,
> +  IN UINT8                   DataBits,
> +  IN EFI_STOP_BITS_TYPE      StopBits
> +  )
> +{
> +
> +  EFI_STATUS   Status;
> +  USB_SER_DEV  *UsbSerialDevice;
> +
> +  UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
> +
> +  Status = SetAttributesInternal (
> +             UsbSerialDevice,
> +             BaudRate,
> +             ReceiveFifoDepth,
> +             Timeout,
> +             Parity,
> +             DataBits,
> +             StopBits
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Retrieves the status of the control bits on a serial device.
> +
> +  @param  This[in]               Protocol instance pointer.
> +  @param  Control[out]           A pointer to return the current Control signals
> +                                 from the serial device.
> +
> +  @retval EFI_SUCCESS            The control bits were read from the serial
> +                                 device.
> +  @retval EFI_DEVICE_ERROR       The serial device is not functioning
> correctly.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetControlBits (
> +  IN EFI_SERIAL_IO_PROTOCOL  *This,
> +  OUT UINT32                 *Control
> +  )
> +{
> +  USB_SER_DEV  *UsbSerialDevice;
> +  EFI_STATUS   Status;
> +
> +  UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
> +
> +  *Control        = 0;
> +
> +  Status = GetControlBitsInternal (UsbSerialDevice, Control);
> +
> +  if (EFI_ERROR (Status)) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +  return Status;
> +}
> +
> +/**
> +  Reads data from a serial device.
> +
> +  @param  This[in]                   Protocol instance pointer.
> +  @param  BufferSize[in, out]        On input, the size of the Buffer. On output,
> +                                     the amount of data returned in Buffer.
> +  @param  Buffer[out]                The buffer to return the data into.
> +
> +  @retval EFI_SUCCESS                The data was read.
> +  @retval EFI_DEVICE_ERROR           The device reported an error.
> +  @retval EFI_TIMEOUT                The data write was stopped due to a
> timeout.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +ReadSerialIo (
> +  IN EFI_SERIAL_IO_PROTOCOL  *This,
> +  IN OUT UINTN               *BufferSize,
> +  OUT VOID                   *Buffer
> +  )
> +{
> +  UINTN        Index;
> +  UINTN        RemainingCallerBufferSize;
> +  USB_SER_DEV  *UsbSerialDevice;
> +  EFI_STATUS   Status;
> +
> +
> +  if (*BufferSize == 0) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  if (Buffer == NULL) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  Status          = EFI_SUCCESS;
> +  UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
> +
> +  //
> +  // Clear out any data that we already have in our internal buffer
> +  //
> +  for (Index = 0; Index < *BufferSize; Index++) {
> +    if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail)
> {
> +      break;
> +    }
> +
> +    //
> +    // Still have characters in the buffer to return
> +    //
> +    ((UINT8 *)Buffer)[Index] = UsbSerialDevice->DataBuffer[UsbSerialDevice-
> >DataBufferHead];
> +    UsbSerialDevice->DataBufferHead = (UsbSerialDevice->DataBufferHead +
> 1) % SW_FIFO_DEPTH;
> +  }
> +
> +  //
> +  // If we haven't filled the caller's buffer using data that we already had on
> +  // hand We need to generate an additional USB request to try and fill the
> +  // caller's buffer
> +  //
> +  if (Index != *BufferSize) {
> +    RemainingCallerBufferSize = *BufferSize - Index;
> +    Status = ReadDataFromUsb (
> +               UsbSerialDevice,
> +               &RemainingCallerBufferSize,
> +               (VOID *)(((CHAR8 *)Buffer) + Index)
> +               );
> +    if (!EFI_ERROR (Status)) {
> +      *BufferSize = RemainingCallerBufferSize + Index;
> +    } else {
> +      *BufferSize = Index;
> +    }
> +  }
> +
> +  if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {
> +    //
> +    // Data buffer has no data, set the EFI_SERIAL_INPUT_BUFFER_EMPTY
> flag
> +    //
> +    UsbSerialDevice->ControlBits |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
> +  } else {
> +    //
> +    // There is some leftover data, clear EFI_SERIAL_INPUT_BUFFER_EMPTY
> flag
> +    //
> +    UsbSerialDevice->ControlBits &= ~(EFI_SERIAL_INPUT_BUFFER_EMPTY);
> +  }
> +  return Status;
> +}
> +
> +/**
> +  Writes data to a serial device.
> +
> +  @param  This[in]                   Protocol instance pointer.
> +  @param  BufferSize[in, out]        On input, the size of the Buffer. On output,
> +                                     the amount of data actually written.
> +  @param  Buffer[in]                 The buffer of data to write
> +
> +  @retval EFI_SUCCESS                The data was written.
> +  @retval EFI_DEVICE_ERROR           The device reported an error.
> +  @retval EFI_TIMEOUT                The data write was stopped due to a
> timeout.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +WriteSerialIo (
> +  IN EFI_SERIAL_IO_PROTOCOL  *This,
> +  IN OUT UINTN               *BufferSize,
> +  IN VOID                    *Buffer
> +  )
> +{
> +  EFI_STATUS   Status;
> +  USB_SER_DEV  *UsbSerialDevice;
> +  EFI_TPL      Tpl;
> +
> +  UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
> +
> +  if (UsbSerialDevice->Shutdown) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  Tpl = gBS->RaiseTPL (TPL_NOTIFY);
> +
> +  Status = UsbSerialDataTransfer (
> +             UsbSerialDevice,
> +             EfiUsbDataOut,
> +             Buffer,
> +             BufferSize,
> +             FTDI_TIMEOUT
> +             );
> +
> +  gBS->RestoreTPL (Tpl);
> +  if (EFI_ERROR (Status)) {
> +    if (Status == EFI_TIMEOUT){
> +      return Status;
> +    } else {
> +      return EFI_DEVICE_ERROR;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.h
> b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.h
> new file mode 100644
> index 0000000000..6048923d6f
> --- /dev/null
> +++
> b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.h
> @@ -0,0 +1,589 @@
> +/** @file
> +  Header file for USB Serial Driver's Data Structures.
> +
> +Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.
> +Portions Copyright 2012 Ashley DeSimone
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _FTDI_USB_SERIAL_DRIVER_H_
> +#define _FTDI_USB_SERIAL_DRIVER_H_
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/DevicePathLib.h>
> +
> +#include <Protocol/DevicePath.h>
> +#include <Protocol/UsbIo.h>
> +#include <Protocol/SerialIo.h>
> +
> +//
> +// US English LangID
> +//
> +#define USB_US_LANG_ID  0x0409
> +
> +//
> +// Supported Vendor Ids
> +//
> +#define VID_FTDI    0x0403
> +
> +//
> +// Supported product ids
> +//
> +#define DID_FTDI_FT232    0x6001
> +
> +//
> +// FTDI Commands
> +//
> +#define FTDI_COMMAND_RESET_PORT          0
> +#define FTDI_COMMAND_MODEM_CTRL          1
> +#define FTDI_COMMAND_SET_FLOW_CTRL       2
> +#define FTDI_COMMAND_SET_BAUDRATE        3
> +#define FTDI_COMMAND_SET_DATA            4
> +#define FTDI_COMMAND_GET_MODEM_STATUS    5
> +#define FTDI_COMMAND_SET_EVENT_CHAR      6
> +#define FTDI_COMMAND_SET_ERROR_CHAR      7
> +#define FTDI_COMMAND_SET_LATENCY_TIMER   9
> +#define FTDI_COMMAND_GET_LATENCY_TIMER   10
> +
> +//
> +// FTDI_PORT_IDENTIFIER
> +// Used in the usb control transfers that issue FTDI commands as the index
> value.
> +//
> +#define FTDI_PORT_IDENTIFIER    0x1 // For FTDI USB serial adapter the
> port
> +                                    // identifier is always 1.
> +
> +//
> +// RESET_PORT
> +//
> +#define RESET_PORT_RESET        0x0 // Purges RX and TX, clears DTR and
> RTS sets
> +                                    // flow control to none, disables event
> +                                    // trigger, sets the event char to 0x0d and
> +                                    // does nothing to baudrate or data settings
> +#define RESET_PORT_PURGE_RX     0x1
> +#define RESET_PORT_PURGE_TX     0x2
> +
> +//
> +// SET_FLOW_CONTROL
> +//
> +#define NO_FLOW_CTRL                     0x0
> +#define XON_XOFF_CTRL                    0x4
> +
> +//
> +// SET_BAUD_RATE
> +// To set baud rate, one must calculate an encoding of the baud rate from
> +// UINT32 to UINT16.See EncodeBaudRateForFtdi() for details
> +//
> +#define FTDI_UART_FREQUENCY              3000000
> +#define FTDI_MIN_DIVISOR                 0x20
> +#define FTDI_MAX_DIVISOR                 0x3FFF8
> +//
> +// Special case baudrate values
> +// 300,000 and 200,000 are special cases for calculating the encoded
> baudrate
> +//
> +#define FTDI_SPECIAL_CASE_300_MIN        (3000000 * 100) / 103 //
> minimum adjusted
> +                                                               // value for 300,000
> +#define FTDI_SPECIAL_CASE_300_MAX        (3000000 * 100) / 97  //
> maximum adjusted
> +                                                               // value for 300,000
> +#define FTDI_SPECIAL_CASE_200_MIN        (2000000 * 100) / 103 //
> minimum adjusted
> +                                                               // value for 200,000
> +#define FTDI_SPECIAL_CASE_200_MAX        (2000000 * 100) / 97  //
> maximum adjusted
> +                                                               // value for 200,000
> +//
> +// Min and max frequency values that the FTDI chip can attain
> +//.all generated frequencies must be between these values
> +//
> +#define FTDI_MIN_FREQUENCY              46601941 // (3MHz * 1600) / 103 =
> 46601941
> +#define FTDI_MAX_FREQUENCY              49484536 // (3MHz * 1600) / 97 =
> 49484536
> +
> +//
> +// SET_DATA_BITS
> +//
> +#define SET_DATA_BITS(n)                 (n)
> +
> +//
> +// SET_PARITY
> +//
> +#define SET_PARITY_NONE                   0x0
> +#define SET_PARITY_ODD                    BIT8 // (0x1 << 8)
> +#define SET_PARITY_EVEN                   BIT9 // (0x2 << 8)
> +#define SET_PARITY_MARK                   BIT9 | BIT8 // (0x3 << 8)
> +#define SET_PARITY_SPACE                  BIT10 // (0x4 << 8)
> +
> +//
> +// SET_STOP_BITS
> +//
> +#define SET_STOP_BITS_1                   0x0
> +#define SET_STOP_BITS_15                  BIT11 // (0x1 << 11)
> +#define SET_STOP_BITS_2                   BIT12 // (0x2 << 11)
> +
> +//
> +// SET_MODEM_CTRL
> +// SET_DTR_HIGH = (1 | (1 << 8)), SET_DTR_LOW = (0 | (1 << 8)
> +// SET_RTS_HIGH = (2 | (2 << 8)), SET_RTS_LOW = (0 | (2 << 8)
> +//
> +#define SET_DTR_HIGH                     (BIT8 | BIT0)
> +#define SET_DTR_LOW                      (BIT8)
> +#define SET_RTS_HIGH                     (BIT9 | BIT1)
> +#define SET_RTS_LOW                      (BIT9)
> +
> +//
> +// MODEM_STATUS
> +//
> +#define CTS_MASK                         BIT4
> +#define DSR_MASK                         BIT5
> +#define RI_MASK                          BIT6
> +#define SD_MASK                          BIT7
> +#define MSR_MASK                         (CTS_MASK | DSR_MASK | RI_MASK |
> SD_MASK)
> +
> +//
> +// Macro used to check for USB transfer errors
> +//
> +#define USB_IS_ERROR(Result, Error)           (((Result) & (Error)) != 0)
> +
> +//
> +// USB request timeouts
> +//
> +#define WDR_TIMEOUT        5000  // default urb timeout in ms
> +#define WDR_SHORT_TIMEOUT  1000  // shorter urb timeout in ms
> +
> +//
> +// FTDI timeout
> +//
> +#define FTDI_TIMEOUT       16
> +
> +//
> +// FTDI FIFO depth
> +//
> +#define FTDI_MAX_RECEIVE_FIFO_DEPTH  384
> +
> +//
> +// FTDI Endpoint Descriptors
> +//
> +#define FTDI_ENDPOINT_ADDRESS_IN   0x81 //the endpoint address for the
> in enpoint generated by the device
> +#define FTDI_ENDPOINT_ADDRESS_OUT  0x02 //the endpoint address for
> the out endpoint generated by the device
> +
> +//
> +// Max buffer size for USB transfers
> +//
> +#define SW_FIFO_DEPTH 1024
> +
> +//
> +// struct to define a usb device as a vendor and product id pair
> +//
> +typedef struct {
> +  UINTN     VendorId;
> +  UINTN     DeviceId;
> +} USB_DEVICE;
> +
> +//
> +//struct to describe the control bits of the device
> +//true indicates enabled
> +//false indicates disabled
> +//
> +typedef struct {
> +  BOOLEAN    HardwareFlowControl;
> +  BOOLEAN    DtrState;
> +  BOOLEAN    RtsState;
> +  BOOLEAN    HardwareLoopBack;
> +  BOOLEAN    SoftwareLoopBack;
> +} CONTROL_BITS;
> +
> +//
> +//struct to describe the status bits of the device
> +//true indicates enabled
> +//false indicated disabled
> +//
> +typedef struct {
> +  BOOLEAN    CtsState;
> +  BOOLEAN    DsrState;
> +  BOOLEAN    RiState;
> +  BOOLEAN    SdState;
> +} STATUS_BITS;
> +
> +//
> +// Structure to describe the last attributes of the Usb Serial device
> +//
> +typedef struct {
> +  UINT64              BaudRate;
> +  UINT32              ReceiveFifoDepth;
> +  UINT32              Timeout;
> +  EFI_PARITY_TYPE     Parity;
> +  UINT8               DataBits;
> +  EFI_STOP_BITS_TYPE  StopBits;
> +} PREVIOUS_ATTRIBUTES;
> +
> +//
> +// Structure to describe USB serial device
> +//
> +#define USB_SER_DEV_SIGNATURE  SIGNATURE_32 ('u', 's', 'b', 's')
> +
> +typedef struct {
> +  UINTN                         Signature;
> +  EFI_HANDLE                    ControllerHandle;
> +  EFI_DEVICE_PATH_PROTOCOL      *DevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL      *ParentDevicePath;
> +  UART_DEVICE_PATH              UartDevicePath;
> +  UART_FLOW_CONTROL_DEVICE_PATH FlowControlDevicePath;
> +  EFI_USB_IO_PROTOCOL           *UsbIo;
> +  EFI_USB_INTERFACE_DESCRIPTOR  InterfaceDescriptor;
> +  EFI_USB_ENDPOINT_DESCRIPTOR   InEndpointDescriptor;
> +  EFI_USB_ENDPOINT_DESCRIPTOR   OutEndpointDescriptor;
> +  EFI_UNICODE_STRING_TABLE      *ControllerNameTable;
> +  UINT32                        DataBufferHead;
> +  UINT32                        DataBufferTail;
> +  UINT8                         *DataBuffer;
> +  EFI_SERIAL_IO_PROTOCOL        SerialIo;
> +  BOOLEAN                       Shutdown;
> +  EFI_EVENT                     PollingLoop;
> +  UINT32                        ControlBits;
> +  PREVIOUS_ATTRIBUTES           LastSettings;
> +  CONTROL_BITS                  ControlValues;
> +  STATUS_BITS                   StatusValues;
> +  UINT8                         ReadBuffer[512];
> +} USB_SER_DEV;
> +
> +#define USB_SER_DEV_FROM_THIS(a) \
> +  CR(a, USB_SER_DEV, SerialIo, USB_SER_DEV_SIGNATURE)
> +
> +//
> +// Global Variables
> +//
> +extern EFI_DRIVER_BINDING_PROTOCOL   gUsbSerialDriverBinding;
> +extern EFI_COMPONENT_NAME_PROTOCOL   gUsbSerialComponentName;
> +extern EFI_COMPONENT_NAME2_PROTOCOL
> gUsbSerialComponentName2;
> +
> +//
> +// Functions of Driver Binding Protocol
> +//
> +/**
> +  Check whether USB Serial driver supports this device.
> +
> +  @param  This[in]                   The USB Serial driver binding protocol.
> +  @param  Controller[in]             The controller handle to check.
> +  @param  RemainingDevicePath[in]    The remaining device path.
> +
> +  @retval EFI_SUCCESS                The driver supports this controller.
> +  @retval other                      This device isn't supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbSerialDriverBindingSupported (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> +  );
> +
> +/**
> +  Starts the Serial device with this driver.
> +
> +  This function produces Serial IO Protocol and initializes the USB
> +  Serial device to manage this USB Serial device.
> +
> +  @param  This[in]                   The USB Serial driver binding instance.
> +  @param  Controller[in]             Handle of device to bind driver to.
> +  @param  RemainingDevicePath[in]    Optional parameter use to pick a
> specific
> +                                     child device to start.
> +
> +  @retval EFI_SUCCESS                The controller is controlled by the USB
> +                                     Serial driver.
> +  @retval EFI_UNSUPPORTED            No interrupt endpoint can be found.
> +  @retval Other                      This controller cannot be started.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbSerialDriverBindingStart (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> +  );
> +
> +/**
> +  Stop the USB Serial device handled by this driver.
> +
> +  @param  This[in]                   The USB Serial driver binding protocol.
> +  @param  Controller[in]             The controller to release.
> +  @param  NumberOfChildren[in]       The number of handles in
> ChildHandleBuffer.
> +  @param  ChildHandleBuffer[in]      The array of child handle.
> +
> +  @retval EFI_SUCCESS                The device was stopped.
> +  @retval EFI_UNSUPPORTED            Simple Text In Protocol or Simple Text
> In Ex
> +                                     Protocol is not installed on Controller.
> +  @retval EFI_DEVICE_ERROR           The device could not be stopped due to
> a
> +                                     device error.
> +  @retval Others                     Fail to uninstall protocols attached on the
> +                                     device.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbSerialDriverBindingStop (
> +  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN  EFI_HANDLE                   Controller,
> +  IN  UINTN                        NumberOfChildren,
> +  IN  EFI_HANDLE                   *ChildHandleBuffer
> +  );
> +
> +//
> +// Serial IO Member Functions
> +//
> +
> +/**
> +  Writes data to a serial device.
> +
> +  @param  This[in]                   Protocol instance pointer.
> +  @param  BufferSize[in, out]        On input, the size of the Buffer. On output,
> +                                     the amount of data actually written.
> +  @param  Buffer[in]                 The buffer of data to write
> +
> +  @retval EFI_SUCCESS                The data was written.
> +  @retval EFI_DEVICE_ERROR           The device reported an error.
> +  @retval EFI_TIMEOUT                The data write was stopped due to a
> timeout.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +WriteSerialIo (
> +  IN EFI_SERIAL_IO_PROTOCOL  *This,
> +  IN OUT UINTN               *BufferSize,
> +  IN VOID                    *Buffer
> +  );
> +
> +/**
> +  Reads data from a serial device.
> +
> +  @param  This[in]                   Protocol instance pointer.
> +  @param  BufferSize[in, out]        On input, the size of the Buffer. On output,
> +                                     the amount of data returned in Buffer.
> +  @param  Buffer[out]                The buffer to return the data into.
> +
> +  @retval EFI_SUCCESS                The data was read.
> +  @retval EFI_DEVICE_ERROR           The device reported an error.
> +  @retval EFI_TIMEOUT                The data write was stopped due to a
> timeout.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +ReadSerialIo (
> +  IN EFI_SERIAL_IO_PROTOCOL  *This,
> +  IN OUT UINTN               *BufferSize,
> +  OUT VOID                   *Buffer
> +  );
> +
> +/**
> +  Retrieves the status of the control bits on a serial device.
> +
> +  @param  This[in]               Protocol instance pointer.
> +  @param  Control[out]           A pointer to return the current Control signals
> +                                 from the serial device.
> +
> +  @retval EFI_SUCCESS            The control bits were read from the serial
> +                                 device.
> +  @retval EFI_DEVICE_ERROR       The serial device is not functioning
> correctly.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetControlBits (
> +  IN EFI_SERIAL_IO_PROTOCOL  *This,
> +  OUT UINT32                 *Control
> +  );
> +
> +/**
> +  Set the control bits on a serial device.
> +
> +  @param  This[in]             Protocol instance pointer.
> +  @param  Control[in]          Set the bits of Control that are settable.
> +
> +  @retval EFI_SUCCESS          The new control bits were set on the serial
> device.
> +  @retval EFI_UNSUPPORTED      The serial device does not support this
> operation.
> +  @retval EFI_DEVICE_ERROR     The serial device is not functioning correctly.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetControlBits (
> +  IN EFI_SERIAL_IO_PROTOCOL  *This,
> +  IN UINT32                  Control
> +  );
> +
> +/**
> +  Calls SetAttributesInternal() to set the baud rate, receive FIFO depth,
> +  transmit/receice time out, parity, data buts, and stop bits on a serial
> device.
> +
> +  @param  This[in]             Protocol instance pointer.
> +  @param  BaudRate[in]         The requested baud rate. A BaudRate value of
> 0
> +                               will use the device's default interface speed.
> +  @param  ReveiveFifoDepth[in] The requested depth of the FIFO on the
> receive
> +                               side of the serial interface. A ReceiveFifoDepth
> +                               value of 0 will use the device's default FIFO
> +                               depth.
> +  @param  Timeout[in]          The requested time out for a single character in
> +                               microseconds.This timeout applies to both the
> +                               transmit and receive side of the interface.A
> +                               Timeout value of 0 will use the device's default
> +                               time out value.
> +  @param  Parity[in]           The type of parity to use on this serial device.A
> +                               Parity value of DefaultParity will use the
> +                               device's default parity value.
> +  @param  DataBits[in]         The number of data bits to use on the serial
> +                               device. A DataBits value of 0 will use the
> +                               device's default data bit setting.
> +  @param  StopBits[in]         The number of stop bits to use on this serial
> +                               device. A StopBits value of DefaultStopBits will
> +                               use the device's default number of stop bits.
> +
> +  @retval EFI_SUCCESS          The attributes were set
> +  @retval EFI_DEVICE_ERROR     The attributes were not able to be
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetAttributes (
> +  IN EFI_SERIAL_IO_PROTOCOL  *This,
> +  IN UINT64                  BaudRate,
> +  IN UINT32                  ReceiveFifoDepth,
> +  IN UINT32                  Timeout,
> +  IN EFI_PARITY_TYPE         Parity,
> +  IN UINT8                   DataBits,
> +  IN EFI_STOP_BITS_TYPE      StopBits
> +  );
> +
> +/**
> +  Reset the serial device.
> +
> +  @param  This              Protocol instance pointer.
> +
> +  @retval EFI_SUCCESS       The device was reset.
> +  @retval EFI_DEVICE_ERROR  The serial device could not be reset.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SerialReset (
> +  IN EFI_SERIAL_IO_PROTOCOL  *This
> +  );
> +
> +//
> +// EFI Component Name Functions
> +//
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the driver.
> +
> +  This function retrieves the user readable name of a driver in the form of a
> +  Unicode string. If the driver specified by This has a user readable name in
> +  the language specified by Language, then a pointer to the driver name is
> +  returned in DriverName, and EFI_SUCCESS is returned. If the driver
> specified
> +  by This does not support the language specified by Language,
> +  then EFI_UNSUPPORTED is returned.
> +
> +  @param  This[in]                   A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL
> +                                     or EFI_COMPONENT_NAME_PROTOCOL instance.
> +  @param  Language[in]               A pointer to a Null-terminated ASCII string
> +                                     array indicating the language. This is the
> +                                     language of the driver name that the caller
> +                                     is requesting, and it must match one of the
> +                                     languages specified in SupportedLanguages.
> +                                     The number of languages supported by a
> +                                     driver is up to the driver writer. Language
> +                                     is specified in RFC 4646 or ISO 639-2
> +                                     language code format.
> +  @param  DriverName[out]            A pointer to the Unicode string to return.
> +                                     This Unicode string is the name of the
> +                                     driver specified by This in the language
> +                                     specified by Language.
> +
> +  @retval EFI_SUCCESS                The Unicode string for the Driver specified
> +                                     by This and the language specified by
> +                                     Language was returned in DriverName.
> +  @retval EFI_INVALID_PARAMETER      Language is NULL.
> +  @retval EFI_INVALID_PARAMETER      DriverName is NULL.
> +  @retval EFI_UNSUPPORTED            The driver specified by This does not
> +                                     support the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbSerialComponentNameGetDriverName (
> +  IN  EFI_COMPONENT_NAME2_PROTOCOL  *This,
> +  IN  CHAR8                         *Language,
> +  OUT CHAR16                        **DriverName
> +  );
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the controller
> +  that is being managed by a driver.
> +
> +  This function retrieves the user readable name of the controller specified
> by
> +  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> +  driver specified by This has a user readable name in the language specified
> by
> +  Language, then a pointer to the controller name is returned in
> ControllerName,
> +  and EFI_SUCCESS is returned.  If the driver specified by This is not
> currently
> +  managing the controller specified by ControllerHandle and ChildHandle,
> +  then EFI_UNSUPPORTED is returned.  If the driver specified by This does
> not
> +  support the language specified by Language, then EFI_UNSUPPORTED is
> returned.
> +
> +  @param  This[in]                   A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL
> +                                     or EFI_COMPONENT_NAME_PROTOCOL instance.
> +  @param  ControllerHandle[in]       The handle of a controller that the
> driver
> +                                     specified by This is managing.  This handle
> +                                     specifies the controller whose name is to
> +                                     be returned.
> +  @param  ChildHandle[in]            The handle of the child controller to
> +                                     retrieve the name of. This is an optional
> +                                     parameter that may be NULL. It will be NULL
> +                                     for device drivers. It will also be NULL
> +                                     for a bus drivers that wish to retrieve the
> +                                     name of the bus controller. It will not be
> +                                     NULL for a bus driver that wishes to
> +                                     retrieve the name of a child controller.
> +  @param  Language[in]               A pointer to a Null-terminated ASCII string
> +                                     array indicating the language.  This is the
> +                                     language of the driver name that the caller
> +                                     is requesting, and it must match one of the
> +                                     languages specified in SupportedLanguages.
> +                                     The number of languages supported by a
> +                                     driver is up to the driver writer. Language
> +                                     is specified in RFC 4646 or ISO 639-2
> +                                     language code format.
> +  @param  ControllerName[out]        A pointer to the Unicode string to
> return.
> +                                     This Unicode string is the name of the
> +                                     controller specified by ControllerHandle
> +                                     and ChildHandle in the language specified
> +                                     by Language from the point of view of the
> +                                     driver specified by This.
> +
> +  @retval EFI_SUCCESS                The Unicode string for the user readable
> +                                     name in the language specified by Language
> +                                     for the driver specified by This was
> +                                     returned in DriverName.
> +  @retval EFI_INVALID_PARAMETER      ControllerHandle is not a valid
> EFI_HANDLE.
> +  @retval EFI_INVALID_PARAMETER      ChildHandle is not NULL and it is not
> a
> +                                     valid EFI_HANDLE.
> +  @retval EFI_INVALID_PARAMETER      Language is NULL.
> +  @retval EFI_INVALID_PARAMETER      ControllerName is NULL.
> +  @retval EFI_UNSUPPORTED            The driver specified by This is not
> +                                     currently managing the controller specified
> +                                     by ControllerHandle and ChildHandle.
> +  @retval EFI_UNSUPPORTED            The driver specified by This does not
> +                                     support the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbSerialComponentNameGetControllerName (
> +  IN  EFI_COMPONENT_NAME2_PROTOCOL  *This,
> +  IN  EFI_HANDLE                    ControllerHandle,
> +  IN  EFI_HANDLE                    ChildHandle      OPTIONAL,
> +  IN  CHAR8                         *Language,
> +  OUT CHAR16                        **ControllerName
> +  );
> +
> +#endif
> diff --git
> a/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf
> b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf
> new file mode 100644
> index 0000000000..67c1d36470
> --- /dev/null
> +++
> b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf
> @@ -0,0 +1,55 @@
> +## @file
> +#  USB Serial Driver that manages USB Serial device and produces Serial IO
> +#  Protocol.
> +#
> +#  USB Serial Driver consumes USB I/O Protocol and Device Path Protocol,
> and
> +#  produces Serial IO Protocol on USB Serial devices.
> +#  It manages the USB Serial device via USB Bulk Transfer of USB I/O
> Protocol.
> +#  This module refers to following specifications:
> +#  1. UEFI Specification, v2.1
> +#
> +# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = FtdiUsbSerialDxe
> +  FILE_GUID                      = A8154B55-2021-4D40-AE81-2E23A02dCC46
> +  MODULE_TYPE                    = UEFI_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = FtdiUsbSerialEntryPoint
> +  UNLOAD_IMAGE                   = FtdiUsbSerialUnload
> +
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +
> +[Sources]
> +  FtdiUsbSerialDriver.c
> +  FtdiUsbSerialDriver.h
> +  ComponentName.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> +  UefiDriverEntryPoint
> +  BaseMemoryLib
> +  DebugLib
> +  MemoryAllocationLib
> +  UefiBootServicesTableLib
> +  UefiLib
> +  DevicePathLib
> +
> +[Guids]
> +  gEfiUartDevicePathGuid
> +
> +[Protocols]
> +  ## TO_START
> +  ## BY_START
> +  gEfiDevicePathProtocolGuid
> +  gEfiUsbIoProtocolGuid                         ## TO_START
> +  gEfiSerialIoProtocolGuid                      ## BY_START
> diff --git a/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt
> b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt
> new file mode 100644
> index 0000000000..d8ca227a41
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt
> @@ -0,0 +1,32 @@
> +
> +=== FTDI USB SERIAL OVERVIEW ===
> +
> +This is a bus driver that enables the EfiSerialIoProtocol interface
> +for FTDI8U232AM based USB-to-Serial adapters.
> +
> +=== STATUS ===
> +
> +Serial Input: Functional on real hardware.
> +Serial Output: Functional on real hardware.
> +
> +Operating Modes: Currently the user is able to change all operating modes
> +except timeout and FIFO depth.
> +The default operating mode is:
> +	Baudrate:     115200
> +	Parity:       None
> +	Flow Control: None
> +	Data Bits:    8
> +	Stop Bits:    1
> +Notes:
> +	Data Bits setting of 6,7,8 can not be combined with a Stop Bits
> setting of 1.5
> +
> +        At baudrates less than 9600 some of the characters may be transmitted
> incorrectly.
> +
> +=== COMPATIBILITY ===
> +
> +Tested with:
> +An FTDI8U232AM based USB-To-Serial adapter, the UEFI Shell, and the
> SerialTest application
> +using a PuTTY Terminal
> +
> +See CompatibleDevices.txt for a list of devices which have been confirmed
> to work with this
> +driver.
> \ No newline at end of file
> diff --git
> a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.c
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.c
> new file mode 100644
> index 0000000000..c9329f506d
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.c
> @@ -0,0 +1,1318 @@
> +/** @file
> +  Implement the interface to the AX88772 Ethernet controller.
> +
> +  This module implements the interface to the ASIX AX88772
> +  USB to Ethernet MAC with integrated 10/100 PHY.  Note that this
> implementation
> +  only supports the integrated PHY since no other test cases were available.
> +
> +  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "Ax88772.h"
> +
> +
> +/**
> +  Compute the CRC
> +
> +  @param [in] pMacAddress      Address of a six byte buffer to containing the
> MAC address.
> +
> +  @returns The CRC-32 value associated with this MAC address
> +
> +**/
> +UINT32
> +Ax88772Crc (
> +  IN UINT8 * pMacAddress
> +  )
> +{
> +  UINT32 BitNumber;
> +  INT32 Carry;
> +  INT32 Crc;
> +  UINT32 Data;
> +  UINT8 * pEnd;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  //  Walk the MAC address
> +  //
> +  Crc = -1;
> +  pEnd = &pMacAddress[ PXE_HWADDR_LEN_ETHER ];
> +  while ( pEnd > pMacAddress ) {
> +    Data = *pMacAddress++;
> +
> +
> +    //
> +    //  CRC32: x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4
> + x2 + x + 1
> +    //
> +    //          1 0000 0100 1100 0001 0001 1101 1011 0111
> +    //
> +    for ( BitNumber = 0; 8 > BitNumber; BitNumber++ ) {
> +      Carry = (( Crc >> 31 ) & 1 ) ^ ( Data & 1 );
> +      Crc <<= 1;
> +      if ( 0 != Carry ) {
> +        Crc ^= 0x04c11db7;
> +      }
> +      Data >>= 1;
> +    }
> +  }
> +
> +  //
> +  //  Return the CRC value
> +  //
> +  DBG_EXIT_HEX ( Crc );
> +  return (UINT32) Crc;
> +}
> +
> +
> +/**
> +  Get the MAC address
> +
> +  This routine calls ::Ax88772UsbCommand to request the MAC
> +  address from the network adapter.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [out] pMacAddress      Address of a six byte buffer to receive the
> MAC address.
> +
> +  @retval EFI_SUCCESS          The MAC address is available.
> +  @retval other                The MAC address is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88772MacAddressGet (
> +  IN NIC_DEVICE * pNicDevice,
> +  OUT UINT8 * pMacAddress
> +  )
> +{
> +  USB_DEVICE_REQUEST SetupMsg;
> +  EFI_STATUS Status;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  //  Set the register address.
> +  //
> +  SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
> +                       | USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_MAC_ADDRESS_READ;
> +  SetupMsg.Value = 0;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = PXE_HWADDR_LEN_ETHER;
> +
> +  //
> +  //  Read the PHY register
> +  //
> +  Status = Ax88772UsbCommand ( pNicDevice,
> +                               &SetupMsg,
> +                               pMacAddress );
> +
> +  //
> +  // Return the operation status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  Set the MAC address
> +
> +  This routine calls ::Ax88772UsbCommand to set the MAC address
> +  in the network adapter.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] pMacAddress      Address of a six byte buffer to containing the
> new MAC address.
> +
> +  @retval EFI_SUCCESS          The MAC address was set.
> +  @retval other                The MAC address was not set.
> +
> +**/
> +EFI_STATUS
> +Ax88772MacAddressSet (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT8 * pMacAddress
> +  )
> +{
> +  USB_DEVICE_REQUEST SetupMsg;
> +  EFI_STATUS Status;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  //  Set the register address.
> +  //
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_MAC_ADDRESS_WRITE;
> +  SetupMsg.Value = 0;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = PXE_HWADDR_LEN_ETHER;
> +
> +  //
> +  //  Read the PHY register
> +  //
> +  Status = Ax88772UsbCommand ( pNicDevice,
> +                               &SetupMsg,
> +                               pMacAddress );
> +
> +  //
> +  // Return the operation status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  Clear the multicast hash table
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +
> +**/
> +VOID
> +Ax88772MulticastClear (
> +  IN NIC_DEVICE * pNicDevice
> +  )
> +{
> +  DBG_ENTER ( );
> +
> +  //
> +  // Clear the multicast hash table
> +  //
> +  pNicDevice->MulticastHash[0] = 0;
> +  pNicDevice->MulticastHash[1] = 0;
> +
> +  DBG_EXIT ( );
> +}
> +
> +
> +/**
> +  Enable a multicast address in the multicast hash table
> +
> +  This routine calls ::Ax88772Crc to compute the hash bit for
> +  this MAC address.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] pMacAddress      Address of a six byte buffer to containing the
> MAC address.
> +
> +**/
> +VOID
> +Ax88772MulticastSet (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT8 * pMacAddress
> +  )
> +{
> +  UINT32 BitNumber;
> +  UINT32 Crc;
> +  UINT32 Mask;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  //  Compute the CRC on the destination address
> +  //
> +  Crc = Ax88772Crc ( pMacAddress );
> +
> +  //
> +  //  Set the bit corresponding to the destination address
> +  //
> +  BitNumber = Crc >> 26;
> +  if ( 32 > BitNumber ) {
> +    Mask = 1 << BitNumber;
> +    pNicDevice->MulticastHash[0] |= Mask;
> +  }
> +  else {
> +    Mask = 1 << ( BitNumber - 32 );
> +    pNicDevice->MulticastHash[1] |= Mask;
> +  }
> +
> +  //
> +  //  Display the multicast address
> +  //
> +  DEBUG (( DEBUG_RX_MULTICAST | DEBUG_INFO,
> +            "Enable multicast: 0x%02x-%02x-%02x-%02x-%02x-%02x, CRC:
> 0x%08x, Bit number: 0x%02x\r\n",
> +            pMacAddress[0],
> +            pMacAddress[1],
> +            pMacAddress[2],
> +            pMacAddress[3],
> +            pMacAddress[4],
> +            pMacAddress[5],
> +            Crc,
> +            BitNumber ));
> +
> +  DBG_EXIT ( );
> +}
> +
> +
> +/**
> +  Start the link negotiation
> +
> +  This routine calls ::Ax88772PhyWrite to start the PHY's link
> +  negotiation.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +
> +  @retval EFI_SUCCESS          The link negotiation was started.
> +  @retval other                Failed to start the link negotiation.
> +
> +**/
> +EFI_STATUS
> +Ax88772NegotiateLinkStart (
> +  IN NIC_DEVICE * pNicDevice
> +  )
> +{
> +  UINT16 Control;
> +  EFI_STATUS Status;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  // Set the supported capabilities.
> +  //
> +  Status = Ax88772PhyWrite ( pNicDevice,
> +                             PHY_ANAR,
> +                             AN_CSMA_CD
> +                             | AN_TX_FDX | AN_TX_HDX
> +                             | AN_10_FDX | AN_10_HDX );
> +  if ( !EFI_ERROR ( Status )) {
> +    //
> +    // Set the link speed and duplex
> +    //
> +    Control = BMCR_AUTONEGOTIATION_ENABLE
> +            | BMCR_RESTART_AUTONEGOTIATION;
> +    if ( pNicDevice->b100Mbps ) {
> +      Control |= BMCR_100MBPS;
> +    }
> +    if ( pNicDevice->bFullDuplex ) {
> +      Control |= BMCR_FULL_DUPLEX;
> +    }
> +    Status = Ax88772PhyWrite ( pNicDevice, PHY_BMCR, Control );
> +  }
> +
> +  //
> +  // Return the operation status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  Complete the negotiation of the PHY link
> +
> +  This routine calls ::Ax88772PhyRead to determine if the
> +  link negotiation is complete.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in, out] pPollCount  Address of number of times this routine was
> polled
> +  @param [out] pbComplete      Address of boolean to receive complate
> status.
> +  @param [out] pbLinkUp        Address of boolean to receive link status,
> TRUE=up.
> +  @param [out] pbHiSpeed       Address of boolean to receive link speed,
> TRUE=100Mbps.
> +  @param [out] pbFullDuplex    Address of boolean to receive link duplex,
> TRUE=full.
> +
> +  @retval EFI_SUCCESS          The MAC address is available.
> +  @retval other                The MAC address is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88772NegotiateLinkComplete (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN OUT UINTN * pPollCount,
> +  OUT BOOLEAN * pbComplete,
> +  OUT BOOLEAN * pbLinkUp,
> +  OUT BOOLEAN * pbHiSpeed,
> +  OUT BOOLEAN * pbFullDuplex
> +  )
> +{
> +  UINT16 Mask;
> +  UINT16 PhyData;
> +  EFI_STATUS  Status;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  //  Determine if the link is up.
> +  //
> +  *pbComplete = FALSE;
> +
> +  //
> +  //  Get the link status
> +  //
> +  Status = Ax88772PhyRead ( pNicDevice,
> +                            PHY_BMSR,
> +                            &PhyData );
> +  if ( !EFI_ERROR ( Status )) {
> +    //
> +    //  Determine if the autonegotiation is complete.
> +    //
> +    *pbLinkUp = (BOOLEAN)( 0 != ( PhyData & BMSR_LINKST ));
> +    *pbComplete = *pbLinkUp;
> +    if ( 0 != *pbComplete ) {
> +      //
> +      //  Get the partners capabilities.
> +      //
> +      Status = Ax88772PhyRead ( pNicDevice,
> +                                PHY_ANLPAR,
> +                                &PhyData );
> +      if ( !EFI_ERROR ( Status )) {
> +        //
> +        //  Autonegotiation is complete
> +        //  Determine the link speed.
> +        //
> +        *pbHiSpeed = (BOOLEAN)( 0 != ( PhyData & ( AN_TX_FDX |
> AN_TX_HDX )));
> +
> +        //
> +        //  Determine the link duplex.
> +        //
> +        Mask = ( *pbHiSpeed ) ? AN_TX_FDX : AN_10_FDX;
> +        *pbFullDuplex = (BOOLEAN)( 0 != ( PhyData & Mask ));
> +      }
> +    }
> +  }
> +
> +  //
> +  // Return the operation status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  Read a register from the PHY
> +
> +  This routine calls ::Ax88772UsbCommand to read a PHY register.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] RegisterAddress  Number of the register to read.
> +  @param [in, out] pPhyData    Address of a buffer to receive the PHY
> register value
> +
> +  @retval EFI_SUCCESS          The PHY data is available.
> +  @retval other                The PHY data is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88772PhyRead (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT8 RegisterAddress,
> +  IN OUT UINT16 * pPhyData
> +  )
> +{
> +  USB_DEVICE_REQUEST SetupMsg;
> +  EFI_STATUS Status;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  //  Request access to the PHY
> +  //
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_PHY_ACCESS_SOFTWARE;
> +  SetupMsg.Value = 0;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand ( pNicDevice,
> +                               &SetupMsg,
> +                               NULL );
> +  if ( !EFI_ERROR ( Status )) {
> +    //
> +    //  Read the PHY register address.
> +    //
> +    SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
> +                         | USB_REQ_TYPE_VENDOR
> +                         | USB_TARGET_DEVICE;
> +    SetupMsg.Request = CMD_PHY_REG_READ;
> +    SetupMsg.Value = pNicDevice->PhyId;
> +    SetupMsg.Index = RegisterAddress;
> +    SetupMsg.Length = sizeof ( *pPhyData );
> +    Status = Ax88772UsbCommand ( pNicDevice,
> +                                 &SetupMsg,
> +                                 pPhyData );
> +    if ( !EFI_ERROR ( Status )) {
> +      DEBUG (( DEBUG_PHY | DEBUG_INFO,
> +                "PHY %d: 0x%02x --> 0x%04x\r\n",
> +                pNicDevice->PhyId,
> +                RegisterAddress,
> +                *pPhyData ));
> +
> +      //
> +      //  Release the PHY to the hardware
> +      //
> +      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                           | USB_TARGET_DEVICE;
> +      SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
> +      SetupMsg.Value = 0;
> +      SetupMsg.Index = 0;
> +      SetupMsg.Length = 0;
> +      Status = Ax88772UsbCommand ( pNicDevice,
> +                                   &SetupMsg,
> +                                   NULL );
> +    }
> +  }
> +
> +  //
> +  //  Return the operation status.
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  Write to a PHY register
> +
> +  This routine calls ::Ax88772UsbCommand to write a PHY register.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] RegisterAddress  Number of the register to read.
> +  @param [in] PhyData          Address of a buffer to receive the PHY register
> value
> +
> +  @retval EFI_SUCCESS          The PHY data was written.
> +  @retval other                Failed to wwrite the PHY register.
> +
> +**/
> +EFI_STATUS
> +Ax88772PhyWrite (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT8 RegisterAddress,
> +  IN UINT16 PhyData
> +  )
> +{
> +  USB_DEVICE_REQUEST SetupMsg;
> +  EFI_STATUS Status;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  //  Request access to the PHY
> +  //
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_PHY_ACCESS_SOFTWARE;
> +  SetupMsg.Value = 0;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand ( pNicDevice,
> +                               &SetupMsg,
> +                               NULL );
> +  if ( !EFI_ERROR ( Status )) {
> +    //
> +    //  Write the PHY register
> +    //
> +    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                         | USB_TARGET_DEVICE;
> +    SetupMsg.Request = CMD_PHY_REG_WRITE;
> +    SetupMsg.Value = pNicDevice->PhyId;
> +    SetupMsg.Index = RegisterAddress;
> +    SetupMsg.Length = sizeof ( PhyData );
> +    Status = Ax88772UsbCommand ( pNicDevice,
> +                                 &SetupMsg,
> +                                 &PhyData );
> +    if ( !EFI_ERROR ( Status )) {
> +      DEBUG (( DEBUG_PHY | DEBUG_INFO,
> +                "PHY %d: 0x%02x <-- 0x%04x\r\n",
> +                pNicDevice->PhyId,
> +                RegisterAddress,
> +                PhyData ));
> +
> +      //
> +      //  Release the PHY to the hardware
> +      //
> +      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                           | USB_TARGET_DEVICE;
> +      SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
> +      SetupMsg.Value = 0;
> +      SetupMsg.Index = 0;
> +      SetupMsg.Length = 0;
> +      Status = Ax88772UsbCommand ( pNicDevice,
> +                                   &SetupMsg,
> +                                   NULL );
> +    }
> +  }
> +
> +  //
> +  //  Return the operation status.
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  Reset the AX88772
> +
> +  This routine uses ::Ax88772UsbCommand to reset the network
> +  adapter.  This routine also uses ::Ax88772PhyWrite to reset
> +  the PHY.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +
> +  @retval EFI_SUCCESS          The MAC address is available.
> +  @retval other                The MAC address is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88772Reset (
> +  IN NIC_DEVICE * pNicDevice
> +  )
> +{
> +  USB_DEVICE_REQUEST SetupMsg;
> +  EFI_STATUS Status;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  //  Turn off the MAC
> +  //
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_RX_CONTROL_WRITE;
> +  SetupMsg.Value = 0;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand ( pNicDevice,
> +                               &SetupMsg,
> +                               NULL );
> +  if ( !EFI_ERROR ( Status )) {
> +    DEBUG (( DEBUG_PHY | DEBUG_RX_BROADCAST |
> DEBUG_RX_MULTICAST
> +              | DEBUG_RX_UNICAST | DEBUG_TX | DEBUG_INFO,
> +              "MAC reset\r\n" ));
> +
> +    //
> +    //  The link is now idle
> +    //
> +    pNicDevice->bLinkIdle = TRUE;
> +
> +    //
> +    //  Delay for a bit
> +    //
> +    gBS->Stall ( RESET_MSEC );
> +
> +    //
> +    //  Select the internal PHY
> +    //
> +    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                         | USB_TARGET_DEVICE;
> +    SetupMsg.Request = CMD_PHY_SELECT;
> +    SetupMsg.Value = SPHY_PSEL;
> +    SetupMsg.Index = 0;
> +    SetupMsg.Length = 0;
> +    Status = Ax88772UsbCommand ( pNicDevice,
> +                                 &SetupMsg,
> +                                 NULL );
> +    if ( !EFI_ERROR ( Status )) {
> +      //
> +      //  Delay for a bit
> +      //
> +      gBS->Stall ( PHY_RESET_MSEC );
> +
> +      //
> +      //  Clear the internal PHY reset
> +      //
> +      SetupMsg.Request = CMD_RESET;
> +      SetupMsg.Value = SRR_IPRL | SRR_PRL;
> +      Status = Ax88772UsbCommand ( pNicDevice,
> +                                   &SetupMsg,
> +                                   NULL );
> +      if ( !EFI_ERROR ( Status )) {
> +        //
> +        //  Reset the PHY
> +        //
> +        Status = Ax88772PhyWrite ( pNicDevice,
> +                                   PHY_BMCR,
> +                                   BMCR_RESET );
> +        if ( !EFI_ERROR ( Status )) {
> +          //
> +          //  Set the gaps
> +          //
> +          SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                               | USB_TARGET_DEVICE;
> +          SetupMsg.Request = CMD_GAPS_WRITE;
> +          SetupMsg.Value = 0x0c15;
> +          SetupMsg.Index = 0x0e;
> +          SetupMsg.Length = 0;
> +          Status = Ax88772UsbCommand ( pNicDevice,
> +                                       &SetupMsg,
> +                                       NULL );
> +        }
> +      }
> +    }
> +  }
> +
> +  //
> +  //  Return the operation status.
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +VOID
> +FillPkt2Queue (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINTN BufLength)
> +{
> +
> +  UINT16 * pLength;
> +  UINT16 * pLengthBar;
> +  UINT8* pData;
> +  UINT32 offset;
> +  RX_TX_PACKET * pRxPacket;
> +  EFI_STATUS Status;
> +
> +  for ( offset = 0; offset < BufLength; ){
> +    pLength = (UINT16*) (pNicDevice->pBulkInBuff + offset);
> +    pLengthBar = (UINT16*) (pNicDevice->pBulkInBuff + offset +2);
> +
> +    *pLength &= 0x7ff;
> +    *pLengthBar &= 0x7ff;
> +    *pLengthBar |= 0xf800;
> +
> +    if ((*pLength ^ *pLengthBar ) != 0xFFFF) {
> +      DEBUG (( EFI_D_ERROR , "Pkt length error. BufLength = %d\n",
> BufLength));
> +      return;
> +    }
> +
> +    pRxPacket = pNicDevice->pRxFree;
> +    if ( NULL == pRxPacket ) {
> +      Status = gBS->AllocatePool ( EfiRuntimeServicesData,
> +                                   sizeof( RX_TX_PACKET ),
> +                                   (VOID **) &pRxPacket );
> +      if ( !EFI_ERROR ( Status )) {
> +        //
> +        //  Add this packet to the free packet list
> +        //
> +        pNicDevice->pRxFree = pRxPacket;
> +        pRxPacket->pNext = NULL;
> +      }
> +      else {
> +        //
> +        //  Use the discard packet buffer
> +        //
> +        //pRxPacket = &Packet;
> +      }
> +    }
> +
> +
> +    pData = pNicDevice->pBulkInBuff + offset + 4;
> +    pRxPacket->Length = *pLength;
> +    pRxPacket->LengthBar = *(UINT16*) (pNicDevice->pBulkInBuff + offset
> +2);
> +    CopyMem (&pRxPacket->Data[0], pData, *pLength);
> +    //DEBUG((DEBUG_INFO, "Packet [%d]\n", *pLength));
> +
> +    pNicDevice->pRxFree = pRxPacket->pNext;
> +    pRxPacket->pNext = NULL;
> +
> +    if ( NULL == pNicDevice->pRxTail ) {
> +      pNicDevice->pRxHead = pRxPacket;
> +    }
> +    else {
> +      pNicDevice->pRxTail->pNext = pRxPacket;
> +    }
> +    pNicDevice->pRxTail = pRxPacket;
> +    offset += (*pLength + 4);
> +
> +  }
> +}
> +
> +
> +
> +/**
> +  Receive a frame from the network.
> +
> +  This routine polls the USB receive interface for a packet.  If a packet
> +  is available, this routine adds the receive packet to the list of
> +  pending receive packets.
> +
> +  This routine calls ::Ax88772NegotiateLinkComplete to verify
> +  that the link is up.  This routine also calls ::SN_Reset to
> +  reset the network adapter when necessary.  Finally this
> +  routine attempts to receive one or more packets from the
> +  network adapter.
> +
> +  @param [in] pNicDevice  Pointer to the NIC_DEVICE structure
> +  @param [in] bUpdateLink TRUE = Update link status
> +
> +**/
> +VOID
> +Ax88772Rx (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN BOOLEAN bUpdateLink
> +  )
> +{
> +  BOOLEAN bFullDuplex;
> +  BOOLEAN bLinkUp;
> +  BOOLEAN bRxPacket;
> +  BOOLEAN bSpeed100;
> +  UINTN LengthInBytes;
> +  RX_TX_PACKET Packet;
> +  RX_TX_PACKET * pRxPacket;
> +  EFI_USB_IO_PROTOCOL *pUsbIo;
> +  EFI_STATUS Status;
> +  EFI_TPL TplPrevious;
> +  UINT32 TransferStatus;
> +
> +  //
> +  //  Synchronize with Ax88772Timer
> +  //
> +  VERIFY_TPL ( TPL_AX88772 );
> +  TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
> +  DEBUG (( DEBUG_TPL | DEBUG_INFO,
> +            "%d: TPL\r\n",
> +            TPL_AX88772 ));
> +
> +  //
> +  //  Get the link status
> +  //
> +  if ( bUpdateLink ) {
> +    bLinkUp = pNicDevice->bLinkUp;
> +    bSpeed100 = pNicDevice->b100Mbps;
> +    bFullDuplex = pNicDevice->bFullDuplex;
> +    Status = Ax88772NegotiateLinkComplete ( pNicDevice,
> +                                            &pNicDevice->PollCount,
> +                                            &pNicDevice->bComplete,
> +                                            &pNicDevice->bLinkUp,
> +                                            &pNicDevice->b100Mbps,
> +                                            &pNicDevice->bFullDuplex );
> +
> +    //
> +    // Determine if the autonegotiation is complete
> +    //
> +    if ( pNicDevice->bComplete ) {
> +      if ( pNicDevice->bLinkUp ) {
> +        if (( bSpeed100 && ( !pNicDevice->b100Mbps ))
> +          || (( !bSpeed100 ) && pNicDevice->b100Mbps )
> +          || ( bFullDuplex && ( !pNicDevice->bFullDuplex ))
> +          || (( !bFullDuplex ) && pNicDevice->bFullDuplex )) {
> +          pNicDevice->PollCount = 0;
> +          DEBUG (( DEBUG_LINK | DEBUG_INFO,
> +                    "Reset to establish proper link setup: %d Mbps, %s duplex\r\n",
> +                    pNicDevice->b100Mbps ? 100 : 10,
> +                    pNicDevice->bFullDuplex ? L"Full" : L"Half" ));
> +          Status = SN_Reset ( &pNicDevice->SimpleNetwork, FALSE );
> +        }
> +        if (( !bLinkUp ) && pNicDevice->bLinkUp ) {
> +          //
> +          // Display the autonegotiation status
> +          //
> +          DEBUG (( DEBUG_LINK | DEBUG_INFO,
> +                    "Link: Up, %d Mbps, %s duplex\r\n",
> +                    pNicDevice->b100Mbps ? 100 : 10,
> +                    pNicDevice->bFullDuplex ? L"Full" : L"Half" ));
> +        }
> +      }
> +    }
> +
> +    //
> +    //  Update the link status
> +    //
> +    if ( bLinkUp && ( !pNicDevice->bLinkUp )) {
> +      DEBUG (( DEBUG_LINK | DEBUG_INFO, "Link: Down\r\n" ));
> +    }
> +  }
> +
> +  //
> +  //  Loop until all the packets are emptied from the receiver
> +  //
> +  do {
> +    bRxPacket = FALSE;
> +
> +    //
> +    //  Locate a packet for use
> +    //
> +    pRxPacket = pNicDevice->pRxFree;
> +    LengthInBytes = MAX_BULKIN_SIZE;
> +    if ( NULL == pRxPacket ) {
> +      Status = gBS->AllocatePool ( EfiRuntimeServicesData,
> +                                   sizeof ( *pRxPacket ),
> +                                   (VOID **) &pRxPacket );
> +      if ( !EFI_ERROR ( Status )) {
> +        //
> +        //  Add this packet to the free packet list
> +        //
> +        pNicDevice->pRxFree = pRxPacket;
> +        pRxPacket->pNext = NULL;
> +      }
> +      else {
> +        //
> +        //  Use the discard packet buffer
> +        //
> +        pRxPacket = &Packet;
> +      }
> +    }
> +
> +    //
> +    //  Attempt to receive a packet
> +    //
> +    SetMem (&pNicDevice->pBulkInBuff[0], MAX_BULKIN_SIZE, 0);
> +    pUsbIo = pNicDevice->pUsbIo;
> +    Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
> +                                       USB_ENDPOINT_DIR_IN | BULK_IN_ENDPOINT,
> +                                       &pNicDevice->pBulkInBuff[0],
> +                                       &LengthInBytes,
> +                                       2,
> +                                       &TransferStatus );
> +    if ( LengthInBytes > 0 ) {
> +      FillPkt2Queue(pNicDevice, LengthInBytes);
> +    }
> +    pRxPacket = pNicDevice->pRxHead;
> +    if (( !EFI_ERROR ( Status ))
> +      && ( 0 < pRxPacket->Length )
> +      && ( pRxPacket->Length <= sizeof ( pRxPacket->Data ))
> +      && ( LengthInBytes > 0)) {
> +
> +      //
> +      //  Determine if the packet should be received
> +      //
> +      bRxPacket = TRUE;
> +      LengthInBytes = pRxPacket->Length;
> +      pNicDevice->bLinkIdle = FALSE;
> +      if ( pNicDevice->pRxFree == pRxPacket ) {
> +        //
> +        //  Display the received packet
> +        //
> +        if ( 0 != ( pRxPacket->Data[0] & 1 )) {
> +          if (( 0xff == pRxPacket->Data[0])
> +            && ( 0xff == pRxPacket->Data[1])
> +            && ( 0xff == pRxPacket->Data[2])
> +            && ( 0xff == pRxPacket->Data[3])
> +            && ( 0xff == pRxPacket->Data[4])
> +            && ( 0xff == pRxPacket->Data[5])) {
> +            DEBUG (( DEBUG_RX_BROADCAST | DEBUG_INFO,
> +                      "RX: %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-
> %02x-%02x-%02x  %02x-%02x  %d bytes\r\n",
> +                      pRxPacket->Data[0],
> +                      pRxPacket->Data[1],
> +                      pRxPacket->Data[2],
> +                      pRxPacket->Data[3],
> +                      pRxPacket->Data[4],
> +                      pRxPacket->Data[5],
> +                      pRxPacket->Data[6],
> +                      pRxPacket->Data[7],
> +                      pRxPacket->Data[8],
> +                      pRxPacket->Data[9],
> +                      pRxPacket->Data[10],
> +                      pRxPacket->Data[11],
> +                      pRxPacket->Data[12],
> +                      pRxPacket->Data[13],
> +                      LengthInBytes ));
> +          }
> +          else {
> +            DEBUG (( DEBUG_RX_MULTICAST | DEBUG_INFO,
> +                      "RX: %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-
> %02x-%02x-%02x  %02x-%02x  %d bytes\r\n",
> +                      pRxPacket->Data[0],
> +                      pRxPacket->Data[1],
> +                      pRxPacket->Data[2],
> +                      pRxPacket->Data[3],
> +                      pRxPacket->Data[4],
> +                      pRxPacket->Data[5],
> +                      pRxPacket->Data[6],
> +                      pRxPacket->Data[7],
> +                      pRxPacket->Data[8],
> +                      pRxPacket->Data[9],
> +                      pRxPacket->Data[10],
> +                      pRxPacket->Data[11],
> +                      pRxPacket->Data[12],
> +                      pRxPacket->Data[13],
> +                      LengthInBytes ));
> +          }
> +        }
> +        else {
> +          DEBUG (( DEBUG_RX_UNICAST | DEBUG_INFO,
> +                    "RX: %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-
> %02x-%02x-%02x  %02x-%02x  %d bytes\r\n",
> +                    pRxPacket->Data[0],
> +                    pRxPacket->Data[1],
> +                    pRxPacket->Data[2],
> +                    pRxPacket->Data[3],
> +                    pRxPacket->Data[4],
> +                    pRxPacket->Data[5],
> +                    pRxPacket->Data[6],
> +                    pRxPacket->Data[7],
> +                    pRxPacket->Data[8],
> +                    pRxPacket->Data[9],
> +                    pRxPacket->Data[10],
> +                    pRxPacket->Data[11],
> +                    pRxPacket->Data[12],
> +                    pRxPacket->Data[13],
> +                    LengthInBytes ));
> +        }
> +
> +      }
> +      else {
> +        //
> +        //  Error, not enough buffers for this packet, discard packet
> +        //
> +        DEBUG (( DEBUG_WARN | DEBUG_INFO,
> +                  "WARNING - No buffer, discarding RX packet: %02x-%02x-%02x-
> %02x-%02x-%02x  %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x  %d
> bytes\r\n",
> +                  pRxPacket->Data[0],
> +                  pRxPacket->Data[1],
> +                  pRxPacket->Data[2],
> +                  pRxPacket->Data[3],
> +                  pRxPacket->Data[4],
> +                  pRxPacket->Data[5],
> +                  pRxPacket->Data[6],
> +                  pRxPacket->Data[7],
> +                  pRxPacket->Data[8],
> +                  pRxPacket->Data[9],
> +                  pRxPacket->Data[10],
> +                  pRxPacket->Data[11],
> +                  pRxPacket->Data[12],
> +                  pRxPacket->Data[13],
> +                  LengthInBytes ));
> +      }
> +    }
> +  }while ( bRxPacket );
> +
> +  //
> +  //  Release the synchronization withhe Ax88772Timer
> +  //
> +  gBS->RestoreTPL ( TplPrevious );
> +  DEBUG (( DEBUG_TPL | DEBUG_INFO,
> +            "%d: TPL\r\n",
> +            TplPrevious ));
> +}
> +
> +
> +/**
> +  Enable or disable the receiver
> +
> +  This routine calls ::Ax88772UsbCommand to update the
> +  receiver state.  This routine also calls ::Ax88772MacAddressSet
> +  to establish the MAC address for the network adapter.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] RxFilter         Simple network RX filter mask value
> +
> +  @retval EFI_SUCCESS          The MAC address was set.
> +  @retval other                The MAC address was not set.
> +
> +**/
> +EFI_STATUS
> +Ax88772RxControl (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT32 RxFilter
> +  )
> +{
> +  UINT16 MediumStatus;
> +  INT32 MulticastHash[2];
> +  UINT16 RxControl;
> +  USB_DEVICE_REQUEST SetupMsg;
> +  EFI_STATUS Status;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  //  Disable all multicast
> +  //
> +  MulticastHash[0] = 0;
> +  MulticastHash[1] = 0;
> +
> +  //
> +  // Enable the receiver if something is to be received
> +  //
> +  Status = EFI_SUCCESS;
> +  RxControl = RXC_SO | RXC_MFB_16384;
> +  if ( 0 != RxFilter ) {
> +    //
> +    //  Enable the receiver
> +    //
> +    SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
> +                         | USB_REQ_TYPE_VENDOR
> +                         | USB_TARGET_DEVICE;
> +    SetupMsg.Request = CMD_MEDIUM_STATUS_READ;
> +    SetupMsg.Value = 0;
> +    SetupMsg.Index = 0;
> +    SetupMsg.Length = sizeof ( MediumStatus );
> +    Status = Ax88772UsbCommand ( pNicDevice,
> +                                 &SetupMsg,
> +                                 &MediumStatus );
> +    if ( !EFI_ERROR ( Status )) {
> +      if ( 0 == ( MediumStatus & MS_RE )) {
> +        MediumStatus |= MS_RE | MS_ONE;
> +        if ( pNicDevice->bFullDuplex ) {
> +          MediumStatus |= MS_TFC | MS_RFC;
> +        }
> +        SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                             | USB_TARGET_DEVICE;
> +        SetupMsg.Request = CMD_MEDIUM_STATUS_WRITE;
> +        SetupMsg.Value = MediumStatus;
> +        SetupMsg.Index = 0;
> +        SetupMsg.Length = 0;
> +        Status = Ax88772UsbCommand ( pNicDevice,
> +                                     &SetupMsg,
> +                                     NULL );
> +        if ( EFI_ERROR ( Status )) {
> +          DEBUG (( DEBUG_ERROR | DEBUG_INFO,
> +                    "ERROR - Failed to enable receiver, Status: %r\r\n",
> +                    Status ));
> +        }
> +      }
> +    }
> +    else {
> +      DEBUG (( DEBUG_ERROR | DEBUG_INFO,
> +                "ERROR - Failed to read receiver status, Status: %r\r\n",
> +                Status ));
> +    }
> +
> +    //
> +    //  Enable multicast if requested
> +    //
> +    if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST )) {
> +      RxControl |= RXC_AM;
> +      MulticastHash[0] = pNicDevice->MulticastHash[0];
> +      MulticastHash[1] = pNicDevice->MulticastHash[1];
> +    }
> +
> +    //
> +    //  Enable all multicast if requested
> +    //
> +    if ( 0 != ( RxFilter &
> EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST )) {
> +      RxControl |= RXC_AMALL;
> +      MulticastHash[0] = -1;
> +      MulticastHash[1] = -1;
> +    }
> +
> +    //
> +    //  Enable broadcast if requested
> +    //
> +    if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST )) {
> +      RxControl |= RXC_AB;
> +    }
> +
> +    //
> +    //  Enable promiscuous mode if requested
> +    //
> +    if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS )) {
> +      RxControl |= RXC_PRO;
> +      MulticastHash[0] = -1;
> +      MulticastHash[1] = -1;
> +    }
> +  }
> +
> +  //
> +  //  Update the MAC address
> +  //
> +  if ( !EFI_ERROR ( Status )) {
> +    Status = Ax88772MacAddressSet ( pNicDevice, &pNicDevice-
> >SimpleNetworkData.CurrentAddress.Addr[0]);
> +  }
> +
> +  //
> +  //  Update the receiver control
> +  //
> +  if ( !EFI_ERROR ( Status )) {
> +    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                         | USB_TARGET_DEVICE;
> +    SetupMsg.Request = CMD_RX_CONTROL_WRITE;
> +    SetupMsg.Value = RxControl;
> +    SetupMsg.Index = 0;
> +    SetupMsg.Length = 0;
> +    Status = Ax88772UsbCommand ( pNicDevice,
> +                                 &SetupMsg,
> +                                 NULL );
> +    if ( !EFI_ERROR ( Status )) {
> +      DEBUG (( DEBUG_RX_BROADCAST | DEBUG_RX_MULTICAST |
> DEBUG_RX_UNICAST | DEBUG_INFO,
> +                "RxControl: 0x%04x\r\n",
> +                RxControl ));
> +
> +      //
> +      //  Update the multicast hash table
> +      //
> +      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                           | USB_TARGET_DEVICE;
> +      SetupMsg.Request = CMD_MULTICAST_HASH_WRITE;
> +      SetupMsg.Value = 0;
> +      SetupMsg.Index = 0;
> +      SetupMsg.Length = sizeof ( pNicDevice ->MulticastHash );
> +      Status = Ax88772UsbCommand ( pNicDevice,
> +                                   &SetupMsg,
> +                                   &pNicDevice->MulticastHash );
> +      if ( !EFI_ERROR ( Status )) {
> +        DEBUG (( DEBUG_RX_MULTICAST | DEBUG_INFO,
> +                  "Multicast Hash:
> 0x%02x %02x %02x %02x %02x %02x %02x %02x\r\n",
> +                  (UINT8) MulticastHash[0],
> +                  (UINT8)( MulticastHash[0] >> 8 ),
> +                  (UINT8)( MulticastHash[0] >> 16 ),
> +                  (UINT8)( MulticastHash[0] >> 24 ),
> +                  (UINT8) MulticastHash[1],
> +                  (UINT8)( MulticastHash[1] >> 8 ),
> +                  (UINT8)( MulticastHash[1] >> 16 ),
> +                  (UINT8)( MulticastHash[1] >> 24 )));
> +      }
> +      else {
> +        DEBUG (( DEBUG_ERROR | DEBUG_INFO,
> +                  "ERROR - Failed to update multicast hash table, Status: %r\r\n",
> +                  Status ));
> +      }
> +    }
> +    else {
> +      DEBUG (( DEBUG_ERROR | DEBUG_INFO,
> +                "ERROR - Failed to set receiver control, Status: %r\r\n",
> +                Status ));
> +    }
> +  }
> +
> +  //
> +  // Return the operation status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  Read an SROM location
> +
> +  This routine calls ::Ax88772UsbCommand to read data from the
> +  SROM.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] Address          SROM address
> +  @param [out] pData           Buffer to receive the data
> +
> +  @retval EFI_SUCCESS          The read was successful
> +  @retval other                The read failed
> +
> +**/
> +EFI_STATUS
> +Ax88772SromRead (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT32 Address,
> +  OUT UINT16 * pData
> +  )
> +{
> +  USB_DEVICE_REQUEST SetupMsg;
> +  EFI_STATUS Status;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  //  Read a value from the SROM
> +  //
> +  SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
> +                       | USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_SROM_READ;
> +  SetupMsg.Value = (UINT16) Address;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = sizeof ( *pData );
> +  Status = Ax88772UsbCommand ( pNicDevice,
> +                               &SetupMsg,
> +                               pData );
> +
> +  //
> +  // Return the operation status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  This routine is called at a regular interval to poll for
> +  receive packets.
> +
> +  This routine polls the link state and gets any receive packets
> +  by calling ::Ax88772Rx.
> +
> +  @param [in] Event            Timer event
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +
> +**/
> +VOID
> +Ax88772Timer (
> +  IN EFI_EVENT Event,
> +  IN NIC_DEVICE * pNicDevice
> +  )
> +{
> +  //
> +  //  Use explicit DEBUG messages since the output frequency is too
> +  //  high for DEBUG_INFO to keep up and have spare cycles for the
> +  //  shell
> +  //
> +  DEBUG (( DEBUG_TIMER, "Entering Ax88772Timer\r\n" ));
> +
> +  //
> +  //  Poll the link state and get any receive packets
> +  //
> +  Ax88772Rx ( pNicDevice, FALSE );
> +
> +  DEBUG (( DEBUG_TIMER, "Exiting Ax88772Timer\r\n" ));
> +}
> +
> +
> +/**
> +  Send a command to the USB device.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] pRequest         Pointer to the request structure
> +  @param [in, out] pBuffer     Data buffer address
> +
> +  @retval EFI_SUCCESS          The USB transfer was successful
> +  @retval other                The USB transfer failed
> +
> +**/
> +EFI_STATUS
> +Ax88772UsbCommand (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN USB_DEVICE_REQUEST * pRequest,
> +  IN OUT VOID * pBuffer
> +  )
> +{
> +  UINT32 CmdStatus;
> +  EFI_USB_DATA_DIRECTION Direction;
> +  EFI_USB_IO_PROTOCOL * pUsbIo;
> +  EFI_STATUS Status;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  // Determine the transfer direction
> +  //
> +  Direction = EfiUsbNoData;
> +  if ( 0 != pRequest->Length ) {
> +    Direction = ( 0 != ( pRequest->RequestType & USB_ENDPOINT_DIR_IN ))
> +              ? EfiUsbDataIn : EfiUsbDataOut;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  pUsbIo = pNicDevice->pUsbIo;
> +  Status = pUsbIo->UsbControlTransfer ( pUsbIo,
> +                                        pRequest,
> +                                        Direction,
> +                                        USB_BUS_TIMEOUT,
> +                                        pBuffer,
> +                                        pRequest->Length,
> +                                        &CmdStatus );
> +
> +  //
> +  // Determine the operation status
> +  //
> +  if ( !EFI_ERROR ( Status )) {
> +    Status = CmdStatus;
> +  }
> +  else {
> +    //
> +    // Display any errors
> +    //
> +    DEBUG (( DEBUG_INFO,
> +              "Ax88772UsbCommand - Status: %r\n",
> +              Status ));
> +
> +    //
> +    // Only use status values associated with the Simple Network protocol
> +    //
> +    if ( EFI_TIMEOUT == Status ) {
> +      Status = EFI_DEVICE_ERROR;
> +    }
> +  }
> +
> +  //
> +  // Return the operation status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> diff --git
> a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.h
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.h
> new file mode 100644
> index 0000000000..8840a4f464
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.h
> @@ -0,0 +1,969 @@
> +/** @file
> +  Definitions for ASIX AX88772 Ethernet adapter.
> +
> +  Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _AX88772_H_
> +#define _AX88772_H_
> +
> +#include <Uefi.h>
> +
> +#include <Guid/EventGroup.h>
> +
> +#include <IndustryStandard/Pci.h>
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeLib.h>
> +
> +#include <Protocol/DevicePath.h>
> +#include <Protocol/LoadedImage.h>
> +#include <Protocol/NetworkInterfaceIdentifier.h>
> +#include <Protocol/SimpleNetwork.h>
> +#include <Protocol/UsbIo.h>
> +
> +//------------------------------------------------------------------------------
> +//  Macros
> +//------------------------------------------------------------------------------
> +//
> +//Too many output debug info hangs system in Debug tip
> +//
> +//#if defined(_MSC_VER)           /* Handle Microsoft VC++ compiler specifics.
> */
> +//#define DBG_ENTER()             DEBUG (( DEBUG_INFO, "Entering "
> __FUNCTION__ "\n" )) ///<  Display routine entry
> +//#define DBG_EXIT()              DEBUG (( DEBUG_INFO, "Exiting "
> __FUNCTION__ "\n" ))  ///<  Display routine exit
> +//#define DBG_EXIT_DEC(Status)    DEBUG (( DEBUG_INFO, "Exiting "
> __FUNCTION__ ", Status: %d\n", Status ))      ///<  Display routine exit with
> decimal value
> +//#define DBG_EXIT_HEX(Status)    DEBUG (( DEBUG_INFO, "Exiting "
> __FUNCTION__ ", Status: 0x%08x\n", Status ))  ///<  Display routine exit with
> hex value
> +//#define DBG_EXIT_STATUS(Status) DEBUG (( DEBUG_INFO, "Exiting "
> __FUNCTION__ ", Status: %r\n", Status ))      ///<  Display routine exit with
> status value
> +//#define DBG_EXIT_TF(Status)     DEBUG (( DEBUG_INFO, "Exiting "
> __FUNCTION__ ", returning %s\n", (FALSE == Status) ? L"FALSE" : L"TRUE" ))
> ///<  Display routine with TRUE/FALSE value
> +//#else   //  _MSC_VER
> +#define DBG_ENTER()               ///<  Display routine entry
> +#define DBG_EXIT()                ///<  Display routine exit
> +#define DBG_EXIT_DEC(Status)      ///<  Display routine exit with decimal
> value
> +#define DBG_EXIT_HEX(Status)      ///<  Display routine exit with hex value
> +#define DBG_EXIT_STATUS(Status)   ///<  Display routine exit with status
> value
> +#define DBG_EXIT_TF(Status)       ///<  Display routine with TRUE/FALSE
> value
> +//#endif  //  _MSC_VER
> +
> +#define USB_IS_IN_ENDPOINT(EndPointAddr)      (((EndPointAddr) &
> BIT7) != 0)  ///<  Return TRUE/FALSE for IN direction
> +#define USB_IS_OUT_ENDPOINT(EndPointAddr)     (((EndPointAddr) & BIT7)
> == 0)  ///<  Return TRUE/FALSE for OUT direction
> +#define USB_IS_BULK_ENDPOINT(Attribute)       (((Attribute) & (BIT0 | BIT1))
> == USB_ENDPOINT_BULK)      ///<  Return TRUE/FALSE for BULK type
> +#define USB_IS_INTERRUPT_ENDPOINT(Attribute)  (((Attribute) & (BIT0 |
> BIT1)) == USB_ENDPOINT_INTERRUPT) ///<  Return TRUE/FALSE for
> INTERRUPT type
> +
> +//------------------------------------------------------------------------------
> +//  Constants
> +//------------------------------------------------------------------------------
> +
> +#define DEBUG_RX_BROADCAST  0x40000000  ///<  Display RX broadcast
> messages
> +#define DEBUG_RX_MULTICAST  0x20000000  ///<  Display RX multicast
> messages
> +#define DEBUG_RX_UNICAST    0x10000000  ///<  Display RX unicast
> messages
> +#define DEBUG_MAC_ADDRESS   0x08000000  ///<  Display the MAC
> address
> +#define DEBUG_LINK          0x04000000  ///<  Display the link status
> +#define DEBUG_TX            0x02000000  ///<  Display the TX messages
> +#define DEBUG_PHY           0x01000000  ///<  Display the PHY register values
> +#define DEBUG_SROM          0x00800000  ///<  Display the SROM contents
> +#define DEBUG_TIMER         0x00400000  ///<  Display the timer routine
> entry/exit
> +#define DEBUG_TPL           0x00200000  ///<  Display the timer routine
> entry/exit
> +
> +#define AX88772_MAX_PKT_SIZE  ( 2048 - 4 )  ///< Maximum packet size
> +#define ETHERNET_HEADER_SIZE  sizeof ( ETHERNET_HEADER )  ///<  Size in
> bytes of the Ethernet header
> +#define MIN_ETHERNET_PKT_SIZE 60    ///<  Minimum packet size including
> Ethernet header
> +#define MAX_ETHERNET_PKT_SIZE 1500  ///<  Ethernet spec 3.1.1:
> Minimum packet size
> +#define MAX_BULKIN_SIZE       2048  ///<  Maximum size of one UsbBulk
> +
> +
> +#define USB_NETWORK_CLASS   0x09    ///<  USB Network class code
> +#define USB_BUS_TIMEOUT     1000    ///<  USB timeout in milliseconds
> +
> +#define TIMER_MSEC          20              ///<  Polling interval for the NIC
> +#define TPL_AX88772         TPL_CALLBACK    ///<  TPL for routine
> synchronization
> +
> +/**
> +  Verify new TPL value
> +
> +  This macro which is enabled when debug is enabled verifies that
> +  the new TPL value is >= the current TPL value.
> +**/
> +#ifdef VERIFY_TPL
> +#undef VERIFY_TPL
> +#endif  //  VERIFY_TPL
> +
> +#if !defined(MDEPKG_NDEBUG)
> +
> +#define VERIFY_TPL(tpl)                           \
> +{                                                 \
> +  EFI_TPL PreviousTpl;                            \
> +                                                  \
> +  PreviousTpl = gBS->RaiseTPL ( TPL_HIGH_LEVEL ); \
> +  gBS->RestoreTPL ( PreviousTpl );                \
> +  if ( PreviousTpl > tpl ) {                      \
> +    DEBUG (( DEBUG_ERROR, "Current TPL: %d, New TPL: %d\r\n",
> PreviousTpl, tpl ));  \
> +    ASSERT ( PreviousTpl <= tpl );                \
> +  }                                               \
> +}
> +
> +#else   //  MDEPKG_NDEBUG
> +
> +#define VERIFY_TPL(tpl)
> +
> +#endif  //  MDEPKG_NDEBUG
> +
> +//------------------------------------------------------------------------------
> +//  Hardware Definition
> +//------------------------------------------------------------------------------
> +
> +#define DEV_SIGNATURE     SIGNATURE_32 ('A','X','8','8')  ///<  Signature of
> data structures in memory
> +
> +#define VENDOR_ID         0x0b95  ///<  Vendor ID for Asix
> +#define PRODUCT_ID        0x7720  ///<  Product ID for the AX88772 USB
> 10/100 Ethernet controller
> +
> +#define RESET_MSEC        1000    ///<  Reset duration
> +#define PHY_RESET_MSEC     500    ///<  PHY reset duration
> +
> +//
> +//  RX Control register
> +//
> +
> +#define RXC_PRO           0x0001  ///<  Receive all packets
> +#define RXC_AMALL         0x0002  ///<  Receive all multicast packets
> +#define RXC_SEP           0x0004  ///<  Save error packets
> +#define RXC_AB            0x0008  ///<  Receive broadcast packets
> +#define RXC_AM            0x0010  ///<  Use multicast destination address hash
> table
> +#define RXC_AP            0x0020  ///<  Accept physical address from Multicast
> Filter
> +#define RXC_SO            0x0080  ///<  Start operation
> +#define RXC_MFB           0x0300  ///<  Maximum frame burst
> +#define RXC_MFB_2048      0       ///<  Maximum frame size:  2048 bytes
> +#define RXC_MFB_4096      0x0100  ///<  Maximum frame size:  4096 bytes
> +#define RXC_MFB_8192      0x0200  ///<  Maximum frame size:  8192 bytes
> +#define RXC_MFB_16384     0x0300  ///<  Maximum frame size: 16384 bytes
> +
> +//
> +//  Medium Status register
> +//
> +
> +#define MS_FD             0x0002  ///<  Full duplex
> +#define MS_ONE            0x0004  ///<  Must be one
> +#define MS_RFC            0x0010  ///<  RX flow control enable
> +#define MS_TFC            0x0020  ///<  TX flow control enable
> +#define MS_PF             0x0080  ///<  Pause frame enable
> +#define MS_RE             0x0100  ///<  Receive enable
> +#define MS_PS             0x0200  ///<  Port speed 1=100, 0=10 Mbps
> +#define MS_SBP            0x0800  ///<  Stop back pressure
> +#define MS_SM             0x1000  ///<  Super MAC support
> +
> +//
> +//  Software PHY Select register
> +//
> +
> +#define SPHY_PSEL         0x01    ///<  Select internal PHY
> +#define SPHY_ASEL         0x02    ///<  1=Auto select, 0=Manual select
> +
> +//
> +//  Software Reset register
> +//
> +
> +#define SRR_RR            0x01    ///<  Clear receive frame length error
> +#define SRR_RT            0x02    ///<  Clear transmit frame length error
> +#define SRR_PRTE          0x04    ///<  External PHY reset pin tri-state enable
> +#define SRR_PRL           0x08    ///<  External PHY reset pin level
> +#define SRR_BZ            0x10    ///<  Force Bulk to return zero length packet
> +#define SRR_IPRL          0x20    ///<  Internal PHY reset control
> +#define SRR_IPPD          0x40    ///<  Internal PHY power down
> +
> +//
> +//  PHY ID values
> +//
> +
> +#define PHY_ID_INTERNAL   0x0010  ///<  Internal PHY
> +
> +//
> +//  USB Commands
> +//
> +
> +#define CMD_PHY_ACCESS_SOFTWARE   0x06  ///<  Software in control of
> PHY
> +#define CMD_PHY_REG_READ          0x07  ///<  Read PHY register, Value:
> PHY, Index: Register, Data: Register value
> +#define CMD_PHY_REG_WRITE         0x08  ///<  Write PHY register, Value:
> PHY, Index: Register, Data: New 16-bit value
> +#define CMD_PHY_ACCESS_HARDWARE   0x0a  ///<  Hardware in control of
> PHY
> +#define CMD_SROM_READ             0x0b  ///<  Read SROM register: Value:
> Address, Data: Value
> +#define CMD_RX_CONTROL_WRITE      0x10  ///<  Set the RX control
> register, Value: New value
> +#define CMD_GAPS_WRITE            0x12  ///<  Write the gaps register, Value:
> New value
> +#define CMD_MAC_ADDRESS_READ      0x13  ///<  Read the MAC address,
> Data: 6 byte MAC address
> +#define CMD_MAC_ADDRESS_WRITE     0x14  ///<  Set the MAC address,
> Data: New 6 byte MAC address
> +#define CMD_MULTICAST_HASH_WRITE  0x16  ///<  Write the multicast
> hash table, Data: New 8 byte value
> +#define CMD_MEDIUM_STATUS_READ    0x1a  ///<  Read medium status
> register, Data: Register value
> +#define CMD_MEDIUM_STATUS_WRITE   0x1b  ///<  Write medium status
> register, Value: New value
> +#define CMD_RESET                 0x20  ///<  Reset register, Value: New value
> +#define CMD_PHY_SELECT            0x22  ///<  PHY select register, Value: New
> value
> +
> +//------------------------------
> +//  USB Endpoints
> +//------------------------------
> +
> +#define CONTROL_ENDPOINT                0       ///<  Control endpoint
> +#define INTERRUPT_ENDPOINT              1       ///<  Interrupt endpoint
> +#define BULK_IN_ENDPOINT                2       ///<  Receive endpoint
> +#define BULK_OUT_ENDPOINT               3       ///<  Transmit endpoint
> +
> +//------------------------------
> +//  PHY Registers
> +//------------------------------
> +
> +#define PHY_BMCR                        0       ///<  Control register
> +#define PHY_BMSR                        1       ///<  Status register
> +#define PHY_ANAR                        4       ///<  Autonegotiation advertisement
> register
> +#define PHY_ANLPAR                      5       ///<  Autonegotiation link parter
> ability register
> +#define PHY_ANER                        6       ///<  Autonegotiation expansion
> register
> +
> +//  BMCR - Register 0
> +
> +#define BMCR_RESET                      0x8000  ///<  1 = Reset the PHY, bit clears
> after reset
> +#define BMCR_LOOPBACK                   0x4000  ///<  1 = Loopback enabled
> +#define BMCR_100MBPS                    0x2000  ///<  100 Mbits/Sec
> +#define BMCR_10MBPS                     0       ///<  10 Mbits/Sec
> +#define BMCR_AUTONEGOTIATION_ENABLE     0x1000  ///<  1 = Enable
> autonegotiation
> +#define BMCR_POWER_DOWN                 0x0800  ///<  1 = Power down
> +#define BMCR_ISOLATE                    0x0400  ///<  0 = Isolate PHY
> +#define BMCR_RESTART_AUTONEGOTIATION    0x0200  ///<  1 = Restart
> autonegotiation
> +#define BMCR_FULL_DUPLEX                0x0100  ///<  Full duplex operation
> +#define BMCR_HALF_DUPLEX                0       ///<  Half duplex operation
> +#define BMCR_COLLISION_TEST             0x0080  ///<  1 = Collision test
> enabled
> +
> +//  BSMR - Register 1
> +
> +#define BMSR_100BASET4                  0x8000  ///<  1 = 100BASE-T4 mode
> +#define BMSR_100BASETX_FDX              0x4000  ///<  1 = 100BASE-TX full
> duplex
> +#define BMSR_100BASETX_HDX              0x2000  ///<  1 = 100BASE-TX half
> duplex
> +#define BMSR_10BASET_FDX                0x1000  ///<  1 = 10BASE-T full duplex
> +#define BMSR_10BASET_HDX                0x0800  ///<  1 = 10BASE-T half
> duplex
> +#define BMSR_MF                         0x0040  ///<  1 = PHY accepts frames with
> preamble suppressed
> +#define BMSR_AUTONEG_CMPLT              0x0020  ///<  1 = Autonegotiation
> complete
> +#define BMSR_RF                         0x0010  ///<  1 = Remote fault
> +#define BMSR_AUTONEG                    0x0008  ///<  1 = Able to perform
> autonegotiation
> +#define BMSR_LINKST                     0x0004  ///<  1 = Link up
> +#define BMSR_JABBER_DETECT              0x0002  ///<  1 = jabber condition
> detected
> +#define BMSR_EXTENDED_CAPABILITY        0x0001  ///<  1 = Extended
> register capable
> +
> +//  ANAR and ANLPAR Registers 4, 5
> +
> +#define AN_NP                           0x8000  ///<  1 = Next page available
> +#define AN_ACK                          0x4000  ///<  1 = Link partner acknowledged
> +#define AN_RF                           0x2000  ///<  1 = Remote fault indicated by
> link partner
> +#define AN_FCS                          0x0400  ///<  1 = Flow control ability
> +#define AN_T4                           0x0200  ///<  1 = 100BASE-T4 support
> +#define AN_TX_FDX                       0x0100  ///<  1 = 100BASE-TX Full duplex
> +#define AN_TX_HDX                       0x0080  ///<  1 = 100BASE-TX support
> +#define AN_10_FDX                       0x0040  ///<  1 = 10BASE-T Full duplex
> +#define AN_10_HDX                       0x0020  ///<  1 = 10BASE-T support
> +#define AN_CSMA_CD                      0x0001  ///<  1 = IEEE 802.3 CSMA/CD
> support
> +
> +//------------------------------------------------------------------------------
> +//  Data Types
> +//------------------------------------------------------------------------------
> +
> +/**
> +  Ethernet header layout
> +
> +  IEEE 802.3-2002 Part 3 specification, section 3.1.1.
> +**/
> +#pragma pack(1)
> +typedef struct {
> +  UINT8 dest_addr[PXE_HWADDR_LEN_ETHER];  ///<  Destination LAN
> address
> +  UINT8 src_addr[PXE_HWADDR_LEN_ETHER];   ///<  Source LAN address
> +  UINT16 type;                            ///<  Protocol or length
> +} ETHERNET_HEADER;
> +#pragma pack()
> +
> +/**
> +  Receive and Transmit packet structure
> +**/
> +#pragma pack(1)
> +typedef struct _RX_TX_PACKET {
> +  struct _RX_TX_PACKET * pNext;       ///<  Next receive packet
> +  UINT16 Length;                      ///<  Packet length
> +  UINT16 LengthBar;                   ///<  Complement of the length
> +  UINT8 Data[ AX88772_MAX_PKT_SIZE ]; ///<  Received packet data
> +} RX_TX_PACKET;
> +#pragma pack()
> +
> +/**
> +  AX88772 control structure
> +
> +  The driver uses this structure to manage the Asix AX88772 10/100
> +  Ethernet controller.
> +**/
> +typedef struct {
> +  UINTN Signature;          ///<  Structure identification
> +
> +  //
> +  //  USB data
> +  //
> +  EFI_HANDLE Controller;        ///<  Controller handle
> +  EFI_USB_IO_PROTOCOL * pUsbIo; ///<  USB driver interface
> +
> +  //
> +  //  Simple network protocol data
> +  //
> +  EFI_SIMPLE_NETWORK_PROTOCOL SimpleNetwork;  ///<  Driver's network
> stack interface
> +  EFI_SIMPLE_NETWORK_MODE SimpleNetworkData;  ///<  Data for simple
> network
> +
> +  //
> +  // Ethernet controller data
> +  //
> +  BOOLEAN bInitialized;     ///<  Controller initialized
> +  VOID * pTxBuffer;         ///<  Last transmit buffer
> +  UINT16 PhyId;             ///<  PHY ID
> +
> +  //
> +  //  Link state
> +  //
> +  BOOLEAN b100Mbps;         ///<  Current link speed, FALSE = 10 Mbps
> +  BOOLEAN bComplete;        ///<  Current state of auto-negotiation
> +  BOOLEAN bFullDuplex;      ///<  Current duplex
> +  BOOLEAN bLinkUp;          ///<  Current link state
> +  BOOLEAN bLinkIdle;        ///<  TRUE = No received traffic
> +  EFI_EVENT Timer;          ///<  Timer to monitor link state and receive
> packets
> +  UINTN PollCount;          ///<  Number of times the autonegotiation status
> was polled
> +
> +  //
> +  //  Receive buffer list
> +  //
> +  RX_TX_PACKET * pRxHead;   ///<  Head of receive packet list
> +  RX_TX_PACKET * pRxTail;   ///<  Tail of receive packet list
> +  RX_TX_PACKET * pRxFree;   ///<  Free packet list
> +  INT32 MulticastHash[2];   ///<  Hash table for multicast destination
> addresses
> +  UINT8 * pBulkInBuff;      ///<  Buffer for Usb Bulk
> +} NIC_DEVICE;
> +
> +#define DEV_FROM_SIMPLE_NETWORK(a)  CR (a, NIC_DEVICE,
> SimpleNetwork, DEV_SIGNATURE)  ///< Locate NIC_DEVICE from Simple
> Network Protocol
> +
> +//------------------------------------------------------------------------------
> +// Simple Network Protocol
> +//------------------------------------------------------------------------------
> +
> +/**
> +  Reset the network adapter.
> +
> +  Resets a network adapter and reinitializes it with the parameters that
> +  were provided in the previous call to Initialize ().  The transmit and
> +  receive queues are cleared.  Receive filters, the station address, the
> +  statistics, and the multicast-IP-to-HW MAC addresses are not reset by
> +  this call.
> +
> +  This routine calls ::Ax88772Reset to perform the adapter specific
> +  reset operation.  This routine also starts the link negotiation
> +  by calling ::Ax88772NegotiateLinkStart.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] bExtendedVerification  Indicates that the driver may perform
> a more
> +                                exhaustive verification operation of the device
> +                                during reset.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Reset (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN BOOLEAN bExtendedVerification
> +  );
> +
> +/**
> +  Initialize the simple network protocol.
> +
> +  This routine calls ::Ax88772MacAddressGet to obtain the
> +  MAC address.
> +
> +  @param [in] pNicDevice       NIC_DEVICE_INSTANCE pointer
> +
> +  @retval EFI_SUCCESS     Setup was successful
> +
> +**/
> +EFI_STATUS
> +SN_Setup (
> +  IN NIC_DEVICE * pNicDevice
> +  );
> +
> +/**
> +  This routine starts the network interface.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_ALREADY_STARTED   The network interface was already
> started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Start (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> +  );
> +
> +/**
> +  Set the MAC address.
> +
> +  This function modifies or resets the current station address of a
> +  network interface.  If Reset is TRUE, then the current station address
> +  is set ot the network interface's permanent address.  If Reset if FALSE
> +  then the current station address is changed to the address specified by
> +  pNew.
> +
> +  This routine calls ::Ax88772MacAddressSet to update the MAC address
> +  in the network adapter.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] bReset            Flag used to reset the station address to the
> +                                network interface's permanent address.
> +  @param [in] pNew              New station address to be used for the network
> +                                interface.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_StationAddress (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN BOOLEAN bReset,
> +  IN EFI_MAC_ADDRESS * pNew
> +  );
> +
> +/**
> +  This function resets or collects the statistics on a network interface.
> +  If the size of the statistics table specified by StatisticsSize is not
> +  big enough for all of the statistics that are collected by the network
> +  interface, then a partial buffer of statistics is returned in
> +  StatisticsTable.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] bReset            Set to TRUE to reset the statistics for the
> network interface.
> +  @param [in, out] pStatisticsSize  On input the size, in bytes, of
> StatisticsTable.  On output
> +                                the size, in bytes, of the resulting table of statistics.
> +  @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS
> structure that
> +                                conains the statistics.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_BUFFER_TOO_SMALL  The pStatisticsTable is NULL or the
> buffer is too small.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Statistics (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN BOOLEAN bReset,
> +  IN OUT UINTN * pStatisticsSize,
> +  OUT EFI_NETWORK_STATISTICS * pStatisticsTable
> +  );
> +
> +/**
> +  This function stops a network interface.  This call is only valid
> +  if the network interface is in the started state.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Stop (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> +  );
> +
> +/**
> +  This function releases the memory buffers assigned in the Initialize() call.
> +  Pending transmits and receives are lost, and interrupts are cleared and
> disabled.
> +  After this call, only Initialize() and Stop() calls may be used.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Shutdown (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> +  );
> +
> +/**
> +  Send a packet over the network.
> +
> +  This function places the packet specified by Header and Buffer on
> +  the transmit queue.  This function performs a non-blocking transmit
> +  operation.  When the transmit is complete, the buffer is returned
> +  via the GetStatus() call.
> +
> +  This routine calls ::Ax88772Rx to empty the network adapter of
> +  receive packets.  The routine then passes the transmit packet
> +  to the network adapter.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] HeaderSize        The size, in bytes, of the media header to be
> filled in by
> +                                the Transmit() function.  If HeaderSize is non-zero, then
> +                                it must be equal to SimpleNetwork->Mode-
> >MediaHeaderSize
> +                                and DestAddr and Protocol parameters must not be NULL.
> +  @param [in] BufferSize        The size, in bytes, of the entire packet (media
> header and
> +                                data) to be transmitted through the network interface.
> +  @param [in] pBuffer           A pointer to the packet (media header followed
> by data) to
> +                                to be transmitted.  This parameter can not be NULL.  If
> +                                HeaderSize is zero, then the media header is Buffer must
> +                                already be filled in by the caller.  If HeaderSize is nonzero,
> +                                then the media header will be filled in by the Transmit()
> +                                function.
> +  @param [in] pSrcAddr          The source HW MAC address.  If HeaderSize is
> zero, then
> +                                this parameter is ignored.  If HeaderSize is nonzero and
> +                                SrcAddr is NULL, then SimpleNetwork->Mode-
> >CurrentAddress
> +                                is used for the source HW MAC address.
> +  @param [in] pDestAddr         The destination HW MAC address.  If
> HeaderSize is zero, then
> +                                this parameter is ignored.
> +  @param [in] pProtocol         The type of header to build.  If HeaderSize is
> zero, then
> +                                this parameter is ignored.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_NOT_READY         The network interface is too busy to accept
> this transmit request.
> +  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Transmit (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN UINTN HeaderSize,
> +  IN UINTN BufferSize,
> +  IN VOID * pBuffer,
> +  IN EFI_MAC_ADDRESS * pSrcAddr,
> +  IN EFI_MAC_ADDRESS * pDestAddr,
> +  IN UINT16 * pProtocol
> +  );
> +
> +//------------------------------------------------------------------------------
> +// Support Routines
> +//------------------------------------------------------------------------------
> +
> +/**
> +  Get the MAC address
> +
> +  This routine calls ::Ax88772UsbCommand to request the MAC
> +  address from the network adapter.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [out] pMacAddress      Address of a six byte buffer to receive the
> MAC address.
> +
> +  @retval EFI_SUCCESS          The MAC address is available.
> +  @retval other                The MAC address is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88772MacAddressGet (
> +  IN NIC_DEVICE * pNicDevice,
> +  OUT UINT8 * pMacAddress
> +  );
> +
> +/**
> +  Set the MAC address
> +
> +  This routine calls ::Ax88772UsbCommand to set the MAC address
> +  in the network adapter.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] pMacAddress      Address of a six byte buffer to containing the
> new MAC address.
> +
> +  @retval EFI_SUCCESS          The MAC address was set.
> +  @retval other                The MAC address was not set.
> +
> +**/
> +EFI_STATUS
> +Ax88772MacAddressSet (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT8 * pMacAddress
> +  );
> +
> +/**
> +  Clear the multicast hash table
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +
> +**/
> +VOID
> +Ax88772MulticastClear (
> +  IN NIC_DEVICE * pNicDevice
> +  );
> +
> +/**
> +  Enable a multicast address in the multicast hash table
> +
> +  This routine calls ::Ax88772Crc to compute the hash bit for
> +  this MAC address.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] pMacAddress      Address of a six byte buffer to containing the
> MAC address.
> +
> +**/
> +VOID
> +Ax88772MulticastSet (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT8 * pMacAddress
> +  );
> +
> +/**
> +  Start the link negotiation
> +
> +  This routine calls ::Ax88772PhyWrite to start the PHY's link
> +  negotiation.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +
> +  @retval EFI_SUCCESS          The link negotiation was started.
> +  @retval other                Failed to start the link negotiation.
> +
> +**/
> +EFI_STATUS
> +Ax88772NegotiateLinkStart (
> +  IN NIC_DEVICE * pNicDevice
> +  );
> +
> +/**
> +  Complete the negotiation of the PHY link
> +
> +  This routine calls ::Ax88772PhyRead to determine if the
> +  link negotiation is complete.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in, out] pPollCount  Address of number of times this routine was
> polled
> +  @param [out] pbComplete      Address of boolean to receive complate
> status.
> +  @param [out] pbLinkUp        Address of boolean to receive link status,
> TRUE=up.
> +  @param [out] pbHiSpeed       Address of boolean to receive link speed,
> TRUE=100Mbps.
> +  @param [out] pbFullDuplex    Address of boolean to receive link duplex,
> TRUE=full.
> +
> +  @retval EFI_SUCCESS          The MAC address is available.
> +  @retval other                The MAC address is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88772NegotiateLinkComplete (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN OUT UINTN * pPollCount,
> +  OUT BOOLEAN * pbComplete,
> +  OUT BOOLEAN * pbLinkUp,
> +  OUT BOOLEAN * pbHiSpeed,
> +  OUT BOOLEAN * pbFullDuplex
> +  );
> +
> +/**
> +  Read a register from the PHY
> +
> +  This routine calls ::Ax88772UsbCommand to read a PHY register.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] RegisterAddress  Number of the register to read.
> +  @param [in, out] pPhyData    Address of a buffer to receive the PHY
> register value
> +
> +  @retval EFI_SUCCESS          The PHY data is available.
> +  @retval other                The PHY data is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88772PhyRead (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT8 RegisterAddress,
> +  IN OUT UINT16 * pPhyData
> +  );
> +
> +/**
> +  Write to a PHY register
> +
> +  This routine calls ::Ax88772UsbCommand to write a PHY register.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] RegisterAddress  Number of the register to read.
> +  @param [in] PhyData          Address of a buffer to receive the PHY register
> value
> +
> +  @retval EFI_SUCCESS          The PHY data was written.
> +  @retval other                Failed to wwrite the PHY register.
> +
> +**/
> +EFI_STATUS
> +Ax88772PhyWrite (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT8 RegisterAddress,
> +  IN UINT16 PhyData
> +  );
> +
> +/**
> +  Reset the AX88772
> +
> +  This routine uses ::Ax88772UsbCommand to reset the network
> +  adapter.  This routine also uses ::Ax88772PhyWrite to reset
> +  the PHY.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +
> +  @retval EFI_SUCCESS          The MAC address is available.
> +  @retval other                The MAC address is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88772Reset (
> +  IN NIC_DEVICE * pNicDevice
> +  );
> +
> +/**
> +  Receive a frame from the network.
> +
> +  This routine polls the USB receive interface for a packet.  If a packet
> +  is available, this routine adds the receive packet to the list of
> +  pending receive packets.
> +
> +  This routine calls ::Ax88772NegotiateLinkComplete to verify
> +  that the link is up.  This routine also calls ::SN_Reset to
> +  reset the network adapter when necessary.  Finally this
> +  routine attempts to receive one or more packets from the
> +  network adapter.
> +
> +  @param [in] pNicDevice  Pointer to the NIC_DEVICE structure
> +  @param [in] bUpdateLink TRUE = Update link status
> +
> +**/
> +VOID
> +Ax88772Rx (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN BOOLEAN bUpdateLink
> +  );
> +
> +/**
> +  Enable or disable the receiver
> +
> +  This routine calls ::Ax88772UsbCommand to update the
> +  receiver state.  This routine also calls ::Ax88772MacAddressSet
> +  to establish the MAC address for the network adapter.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] RxFilter         Simple network RX filter mask value
> +
> +  @retval EFI_SUCCESS          The MAC address was set.
> +  @retval other                The MAC address was not set.
> +
> +**/
> +EFI_STATUS
> +Ax88772RxControl (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT32 RxFilter
> +  );
> +
> +/**
> +  Read an SROM location
> +
> +  This routine calls ::Ax88772UsbCommand to read data from the
> +  SROM.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] Address          SROM address
> +  @param [out] pData           Buffer to receive the data
> +
> +  @retval EFI_SUCCESS          The read was successful
> +  @retval other                The read failed
> +
> +**/
> +EFI_STATUS
> +Ax88772SromRead (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT32 Address,
> +  OUT UINT16 * pData
> +  );
> +
> +/**
> +  This routine is called at a regular interval to poll for
> +  receive packets.
> +
> +  This routine polls the link state and gets any receive packets
> +  by calling ::Ax88772Rx.
> +
> +  @param [in] Event            Timer event
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +
> +**/
> +VOID
> +Ax88772Timer (
> +  IN EFI_EVENT Event,
> +  IN NIC_DEVICE * pNicDevice
> +  );
> +
> +/**
> +  Send a command to the USB device.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] pRequest         Pointer to the request structure
> +  @param [in, out] pBuffer     Data buffer address
> +
> +  @retval EFI_SUCCESS          The USB transfer was successful
> +  @retval other                The USB transfer failed
> +
> +**/
> +EFI_STATUS
> +Ax88772UsbCommand (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN USB_DEVICE_REQUEST * pRequest,
> +  IN OUT VOID * pBuffer
> +  );
> +
> +//------------------------------------------------------------------------------
> +// EFI Component Name Protocol Support
> +//------------------------------------------------------------------------------
> +
> +extern EFI_COMPONENT_NAME_PROTOCOL   gComponentName;  ///<
> Component name protocol declaration
> +extern EFI_COMPONENT_NAME2_PROTOCOL  gComponentName2; ///<
> Component name 2 protocol declaration
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the driver.
> +
> +  This function retrieves the user readable name of a driver in the form of a
> +  Unicode string. If the driver specified by This has a user readable name in
> +  the language specified by Language, then a pointer to the driver name is
> +  returned in DriverName, and EFI_SUCCESS is returned. If the driver
> specified
> +  by This does not support the language specified by Language,
> +  then EFI_UNSUPPORTED is returned.
> +
> +  @param [in] pThis             A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
> +                                array indicating the language. This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified
> +                                in RFC 3066 or ISO 639-2 language code format.
> +  @param [out] ppDriverName     A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                driver specified by This in the language
> +                                specified by Language.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> +                                This and the language specified by Language was
> +                                returned in DriverName.
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetDriverName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
> +  IN  CHAR8 * pLanguage,
> +  OUT CHAR16 ** ppDriverName
> +  );
> +
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the controller
> +  that is being managed by a driver.
> +
> +  This function retrieves the user readable name of the controller specified
> by
> +  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> +  driver specified by This has a user readable name in the language specified
> by
> +  Language, then a pointer to the controller name is returned in
> ControllerName,
> +  and EFI_SUCCESS is returned.  If the driver specified by This is not
> currently
> +  managing the controller specified by ControllerHandle and ChildHandle,
> +  then EFI_UNSUPPORTED is returned.  If the driver specified by This does
> not
> +  support the language specified by Language, then EFI_UNSUPPORTED is
> returned.
> +
> +  @param [in] pThis             A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +  @param [in] ControllerHandle  The handle of a controller that the driver
> +                                specified by This is managing.  This handle
> +                                specifies the controller whose name is to be
> +                                returned.
> +  @param [in] ChildHandle       The handle of the child controller to retrieve
> +                                the name of.  This is an optional parameter that
> +                                may be NULL.  It will be NULL for device
> +                                drivers.  It will also be NULL for a bus drivers
> +                                that wish to retrieve the name of the bus
> +                                controller.  It will not be NULL for a bus
> +                                driver that wishes to retrieve the name of a
> +                                child controller.
> +  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
> +                                array indicating the language.  This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified in
> +                                RFC 3066 or ISO 639-2 language code format.
> +  @param [out] ppControllerName A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                controller specified by ControllerHandle and
> +                                ChildHandle in the language specified by
> +                                Language from the point of view of the driver
> +                                specified by This.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the user readable name
> in
> +                                the language specified by Language for the
> +                                driver specified by This was returned in
> +                                DriverName.
> +  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid
> EFI_HANDLE.
> +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a
> valid
> +                                EFI_HANDLE.
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> +  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> +                                managing the controller specified by
> +                                ControllerHandle and ChildHandle.
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetControllerName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
> +  IN  EFI_HANDLE ControllerHandle,
> +  IN OPTIONAL EFI_HANDLE ChildHandle,
> +  IN  CHAR8 * pLanguage,
> +  OUT CHAR16 ** ppControllerName
> +  );
> +
> +//------------------------------------------------------------------------------
> +
> +#endif  //  _AX88772_H_
> diff --git
> a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf
> new file mode 100644
> index 0000000000..12e7ebc5a2
> --- /dev/null
> +++
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf
> @@ -0,0 +1,61 @@
> +## @file
> +# Component description file for ASIX AX88772 USB/Ethernet driver.
> +#
> +# This module provides support for the ASIX AX88772 USB/Ethernet
> adapter.
> +# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010018
> +  BASE_NAME                      = Ax88772
> +  FILE_GUID                      = B15239D6-6A01-4808-A0F7-B7F20F073555
> +  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
> +  VERSION_STRING                 = 1.0
> +
> +  ENTRY_POINT                    = EntryPoint
> +
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +
> +[Sources.common]
> +  Ax88772.h
> +  Ax88772.c
> +  ComponentName.c
> +  DriverBinding.c
> +  SimpleNetwork.c
> +
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +
> +[LibraryClasses]
> +  UefiLib
> +  UefiBootServicesTableLib
> +  BaseMemoryLib
> +  DebugLib
> +  UefiRuntimeLib
> +  UefiDriverEntryPoint
> +
> +[Protocols]
> +  gEfiDevicePathProtocolGuid           ## BY_START
> +  gEfiSimpleNetworkProtocolGuid        ## BY_START
> +  gEfiUsbIoProtocolGuid                ## TO_START
> +
> +[Depex]
> +  gEfiBdsArchProtocolGuid AND
> +  gEfiCpuArchProtocolGuid AND
> +  gEfiMetronomeArchProtocolGuid AND
> +  gEfiMonotonicCounterArchProtocolGuid AND
> +  gEfiRealTimeClockArchProtocolGuid AND
> +  gEfiResetArchProtocolGuid AND
> +  gEfiRuntimeArchProtocolGuid AND
> +  gEfiSecurityArchProtocolGuid AND
> +  gEfiTimerArchProtocolGuid AND
> +  gEfiVariableWriteArchProtocolGuid AND
> +  gEfiVariableArchProtocolGuid AND
> +  gEfiWatchdogTimerArchProtocolGuid
> diff --git
> a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/ComponentNa
> me.c
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/ComponentNa
> me.c
> new file mode 100644
> index 0000000000..b6dce7e7cb
> --- /dev/null
> +++
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/ComponentNa
> me.c
> @@ -0,0 +1,178 @@
> +/** @file
> +  UEFI Component Name(2) protocol implementation.
> +
> +  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "Ax88772.h"
> +
> +/**
> +  EFI Component Name Protocol declaration
> +**/
> +GLOBAL_REMOVE_IF_UNREFERENCED
> EFI_COMPONENT_NAME_PROTOCOL  gComponentName = {
> +  GetDriverName,
> +  GetControllerName,
> +  "eng"
> +};
> +
> +/**
> +  EFI Component Name 2 Protocol declaration
> +**/
> +GLOBAL_REMOVE_IF_UNREFERENCED
> EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
> +  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) GetDriverName,
> +  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)
> GetControllerName,
> +  "en"
> +};
> +
> +
> +/**
> +  Driver name table declaration
> +**/
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
> +mDriverNameTable[] = {
> +  {"eng;en", L"AX88772 Ethernet Driver"},
> +  {NULL,  NULL}
> +};
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the driver.
> +
> +  This function retrieves the user readable name of a driver in the form of a
> +  Unicode string. If the driver specified by This has a user readable name in
> +  the language specified by Language, then a pointer to the driver name is
> +  returned in DriverName, and EFI_SUCCESS is returned. If the driver
> specified
> +  by This does not support the language specified by Language,
> +  then EFI_UNSUPPORTED is returned.
> +
> +  @param [in] pThis             A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
> +                                array indicating the language. This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified
> +                                in RFC 3066 or ISO 639-2 language code format.
> +  @param [out] ppDriverName     A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                driver specified by This in the language
> +                                specified by Language.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> +                                This and the language specified by Language was
> +                                returned in DriverName.
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetDriverName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
> +  IN  CHAR8 * pLanguage,
> +  OUT CHAR16 ** ppDriverName
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  DBG_ENTER ( );
> +  Status = LookupUnicodeString2 (
> +             pLanguage,
> +             pThis->SupportedLanguages,
> +             mDriverNameTable,
> +             ppDriverName,
> +             (BOOLEAN)(pThis == &gComponentName)
> +             );
> +  DBG_EXIT_HEX ( Status );
> +  return Status;
> +}
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the controller
> +  that is being managed by a driver.
> +
> +  This function retrieves the user readable name of the controller specified
> by
> +  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> +  driver specified by This has a user readable name in the language specified
> by
> +  Language, then a pointer to the controller name is returned in
> ControllerName,
> +  and EFI_SUCCESS is returned.  If the driver specified by This is not
> currently
> +  managing the controller specified by ControllerHandle and ChildHandle,
> +  then EFI_UNSUPPORTED is returned.  If the driver specified by This does
> not
> +  support the language specified by Language, then EFI_UNSUPPORTED is
> returned.
> +
> +  @param [in] pThis             A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +  @param [in] ControllerHandle  The handle of a controller that the driver
> +                                specified by This is managing.  This handle
> +                                specifies the controller whose name is to be
> +                                returned.
> +  @param [in] ChildHandle       The handle of the child controller to retrieve
> +                                the name of.  This is an optional parameter that
> +                                may be NULL.  It will be NULL for device
> +                                drivers.  It will also be NULL for a bus drivers
> +                                that wish to retrieve the name of the bus
> +                                controller.  It will not be NULL for a bus
> +                                driver that wishes to retrieve the name of a
> +                                child controller.
> +  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
> +                                array indicating the language.  This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified in
> +                                RFC 3066 or ISO 639-2 language code format.
> +  @param [out] ppControllerName A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                controller specified by ControllerHandle and
> +                                ChildHandle in the language specified by
> +                                Language from the point of view of the driver
> +                                specified by This.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the user readable name
> in
> +                                the language specified by Language for the
> +                                driver specified by This was returned in
> +                                DriverName.
> +  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid
> EFI_HANDLE.
> +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a
> valid
> +                                EFI_HANDLE.
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> +  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> +                                managing the controller specified by
> +                                ControllerHandle and ChildHandle.
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetControllerName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
> +  IN  EFI_HANDLE ControllerHandle,
> +  IN OPTIONAL EFI_HANDLE ChildHandle,
> +  IN  CHAR8 * pLanguage,
> +  OUT CHAR16 ** ppControllerName
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  // Set the controller name
> +  //
> +  *ppControllerName = L"AX88772 10/100 Ethernet";
> +  Status = EFI_SUCCESS;
> +
> +  //
> +  // Return the operation status
> +  //
> +  DBG_EXIT_HEX ( Status );
> +  return Status;
> +}
> diff --git
> a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/DriverBinding.c
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/DriverBinding.c
> new file mode 100644
> index 0000000000..5bcde4b211
> --- /dev/null
> +++
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/DriverBinding.c
> @@ -0,0 +1,507 @@
> +/** @file
> +  Implement the driver binding protocol for Asix AX88772 Ethernet driver.
> +
> +  Copyright (c) 2011-2013, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "Ax88772.h"
> +
> +/**
> +  Verify the controller type
> +
> +  @param [in] pThis                Protocol instance pointer.
> +  @param [in] Controller           Handle of device to test.
> +  @param [in] pRemainingDevicePath Not used.
> +
> +  @retval EFI_SUCCESS          This driver supports this device.
> +  @retval other                This driver does not support this device.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DriverSupported (
> +  IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
> +  IN EFI_HANDLE Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
> +  )
> +{
> +  EFI_USB_DEVICE_DESCRIPTOR Device;
> +  EFI_USB_IO_PROTOCOL * pUsbIo;
> +  EFI_STATUS Status;
> +
> +  //
> +  //  Connect to the USB stack
> +  //
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiUsbIoProtocolGuid,
> +                  (VOID **) &pUsbIo,
> +                  pThis->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +  if (!EFI_ERROR ( Status )) {
> +
> +    //
> +    //  Get the interface descriptor to check the USB class and find a
> transport
> +    //  protocol handler.
> +    //
> +    Status = pUsbIo->UsbGetDeviceDescriptor ( pUsbIo, &Device );
> +    if (!EFI_ERROR ( Status )) {
> +
> +      //
> +      //  Validate the adapter
> +      //
> +      if (( VENDOR_ID != Device.IdVendor )
> +        || ( PRODUCT_ID != Device.IdProduct )) {
> +        Status = EFI_UNSUPPORTED;
> +      }
> +    }
> +
> +    //
> +    //  Done with the USB stack
> +    //
> +    gBS->CloseProtocol (
> +           Controller,
> +           &gEfiUsbIoProtocolGuid,
> +           pThis->DriverBindingHandle,
> +           Controller
> +           );
> +  }
> +
> +  //
> +  //  Return the device supported status
> +  //
> +  return Status;
> +}
> +
> +
> +/**
> +  Start this driver on Controller by opening UsbIo and DevicePath protocols.
> +  Initialize PXE structures, create a copy of the Controller Device Path with
> the
> +  NIC's MAC address appended to it, install the NetworkInterfaceIdentifier
> protocol
> +  on the newly created Device Path.
> +
> +  @param [in] pThis                Protocol instance pointer.
> +  @param [in] Controller           Handle of device to work with.
> +  @param [in] pRemainingDevicePath Not used, always produce all possible
> children.
> +
> +  @retval EFI_SUCCESS          This driver is added to Controller.
> +  @retval other                This driver does not support this device.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DriverStart (
> +  IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
> +  IN EFI_HANDLE Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
> +  )
> +{
> +  EFI_STATUS Status;
> +  NIC_DEVICE * pNicDevice;
> +  UINTN LengthInBytes;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  //  Allocate the device structure
> +  //
> +  LengthInBytes = sizeof ( *pNicDevice );
> +  Status = gBS->AllocatePool (
> +                  EfiRuntimeServicesData,
> +                  LengthInBytes,
> +                  (VOID **) &pNicDevice
> +                  );
> +  if ( !EFI_ERROR ( Status )) {
> +    DEBUG (( DEBUG_POOL | DEBUG_INIT,
> +              "0x%08x: Allocate pNicDevice, %d bytes\r\n",
> +              pNicDevice,
> +              sizeof ( *pNicDevice )));
> +
> +    //
> +    //  Set the structure signature
> +    //
> +    ZeroMem ( pNicDevice, LengthInBytes );
> +    pNicDevice->Signature = DEV_SIGNATURE;
> +
> +    //
> +    //  Connect to the USB I/O protocol
> +    //
> +    Status = gBS->OpenProtocol (
> +                    Controller,
> +                    &gEfiUsbIoProtocolGuid,
> +                    (VOID **) &pNicDevice->pUsbIo,
> +                    pThis->DriverBindingHandle,
> +                    Controller,
> +                    EFI_OPEN_PROTOCOL_BY_DRIVER
> +                    );
> +
> +    if ( !EFI_ERROR ( Status )) {
> +      //
> +      //  Allocate the necessary events
> +      //
> +      Status = gBS->CreateEvent ( EVT_TIMER,
> +                                  TPL_AX88772,
> +                                  (EFI_EVENT_NOTIFY)Ax88772Timer,
> +                                  pNicDevice,
> +                                  (VOID **)&pNicDevice->Timer );
> +      if ( !EFI_ERROR ( Status )) {
> +        DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> +                  "0x%08x: Allocated timer\r\n",
> +                  pNicDevice->Timer ));
> +
> +        //
> +        //  Initialize the simple network protocol
> +        //
> +        pNicDevice->Controller = Controller;
> +        SN_Setup ( pNicDevice );
> +
> +        //
> +        //  Start the timer
> +        //
> +        Status = gBS->SetTimer ( pNicDevice->Timer,
> +                                 TimerPeriodic,
> +                                 TIMER_MSEC );
> +        if ( !EFI_ERROR ( Status )) {
> +          //
> +          //  Install both the simple network and device path protocols.
> +          //
> +          Status = gBS->InstallMultipleProtocolInterfaces (
> +                          &Controller,
> +                          &gEfiCallerIdGuid,
> +                          pNicDevice,
> +                          &gEfiSimpleNetworkProtocolGuid,
> +                          &pNicDevice->SimpleNetwork,
> +                          NULL
> +                          );
> +
> +          if ( !EFI_ERROR ( Status )) {
> +            DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> +                      "Installed: gEfiCallerIdGuid on   0x%08x\r\n",
> +                      Controller ));
> +            DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> +                      "Installed: gEfiSimpleNetworkProtocolGuid on   0x%08x\r\n",
> +                      Controller ));
> +            DBG_EXIT_STATUS ( Status );
> +            return Status;
> +          }
> +          DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
> +                    "ERROR - Failed to install gEfiSimpleNetworkProtocol on
> 0x%08x\r\n",
> +                    Controller ));
> +        }
> +        else {
> +          DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
> +                    "ERROR - Failed to start the timer, Status: %r\r\n",
> +                    Status ));
> +        }
> +      }
> +      else {
> +        DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
> +                  "ERROR - Failed to create timer event, Status: %r\r\n",
> +                  Status ));
> +      }
> +
> +      //
> +      //  Done with the USB stack
> +      //
> +      gBS->CloseProtocol (
> +             Controller,
> +             &gEfiUsbIoProtocolGuid,
> +             pThis->DriverBindingHandle,
> +             Controller
> +             );
> +    }
> +
> +    //
> +    //  Done with the device
> +    //
> +    gBS->FreePool ( pNicDevice );
> +  }
> +
> +  //
> +  //  Display the driver start status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  Stop this driver on Controller by removing NetworkInterfaceIdentifier
> protocol and
> +  closing the DevicePath and PciIo protocols on Controller.
> +
> +  @param [in] pThis                Protocol instance pointer.
> +  @param [in] Controller           Handle of device to stop driver on.
> +  @param [in] NumberOfChildren     How many children need to be stopped.
> +  @param [in] pChildHandleBuffer   Not used.
> +
> +  @retval EFI_SUCCESS          This driver is removed Controller.
> +  @retval EFI_DEVICE_ERROR     The device could not be stopped due to a
> device error.
> +  @retval other                This driver was not removed from this device.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DriverStop (
> +  IN  EFI_DRIVER_BINDING_PROTOCOL * pThis,
> +  IN  EFI_HANDLE Controller,
> +  IN  UINTN NumberOfChildren,
> +  IN  EFI_HANDLE * pChildHandleBuffer
> +  )
> +{
> +  NIC_DEVICE * pNicDevice;
> +  EFI_STATUS Status;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  //  Determine if this driver is already attached
> +  //
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiCallerIdGuid,
> +                  (VOID **) &pNicDevice,
> +                  pThis->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                  );
> +  if ( !EFI_ERROR ( Status )) {
> +    //
> +    //  AX88772 driver is no longer running on this device
> +    //
> +    gBS->UninstallMultipleProtocolInterfaces (
> +              Controller,
> +              &gEfiSimpleNetworkProtocolGuid,
> +              &pNicDevice->SimpleNetwork,
> +              &gEfiCallerIdGuid,
> +              pNicDevice,
> +              NULL );
> +    DEBUG (( DEBUG_POOL | DEBUG_INIT,
> +                "Removed:   gEfiSimpleNetworkProtocolGuid from 0x%08x\r\n",
> +                Controller ));
> +    DEBUG (( DEBUG_POOL | DEBUG_INIT,
> +                "Removed:   gEfiCallerIdGuid from 0x%08x\r\n",
> +                Controller ));
> +
> +    //
> +    //  Stop the timer
> +    //
> +    if ( NULL != pNicDevice->Timer ) {
> +      gBS->SetTimer ( pNicDevice->Timer, TimerCancel, 0 );
> +      gBS->CloseEvent ( pNicDevice->Timer );
> +      DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> +                "0x%08x: Released timer\r\n",
> +                pNicDevice->Timer ));
> +    }
> +
> +    //
> +    //  Done with the device context
> +    //
> +    DEBUG (( DEBUG_POOL | DEBUG_INIT,
> +              "0x%08x: Free pNicDevice, %d bytes\r\n",
> +              pNicDevice,
> +              sizeof ( *pNicDevice )));
> +    gBS->FreePool ( pNicDevice );
> +  }
> +
> +  //
> +  //  Return the shutdown status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  Driver binding protocol declaration
> +**/
> +EFI_DRIVER_BINDING_PROTOCOL  gDriverBinding = {
> +  DriverSupported,
> +  DriverStart,
> +  DriverStop,
> +  0xa,
> +  NULL,
> +  NULL
> +};
> +
> +
> +/**
> +  Ax88772 driver unload routine.
> +
> +  @param [in] ImageHandle       Handle for the image.
> +
> +  @retval EFI_SUCCESS           Image may be unloaded
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DriverUnload (
> +  IN EFI_HANDLE ImageHandle
> +  )
> +{
> +  UINTN BufferSize;
> +  UINTN Index;
> +  UINTN Max;
> +  EFI_HANDLE * pHandle;
> +  EFI_STATUS Status;
> +
> +  //
> +  //  Determine which devices are using this driver
> +  //
> +  BufferSize = 0;
> +  pHandle = NULL;
> +  Status = gBS->LocateHandle (
> +                  ByProtocol,
> +                  &gEfiCallerIdGuid,
> +                  NULL,
> +                  &BufferSize,
> +                  NULL );
> +  if ( EFI_BUFFER_TOO_SMALL == Status ) {
> +    for ( ; ; ) {
> +      //
> +      //  One or more block IO devices are present
> +      //
> +      Status = gBS->AllocatePool (
> +                      EfiRuntimeServicesData,
> +                      BufferSize,
> +                      (VOID **) &pHandle
> +                      );
> +      if ( EFI_ERROR ( Status )) {
> +        DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> +                  "Insufficient memory, failed handle buffer allocation\r\n" ));
> +        break;
> +      }
> +
> +      //
> +      //  Locate the block IO devices
> +      //
> +      Status = gBS->LocateHandle (
> +                      ByProtocol,
> +                      &gEfiCallerIdGuid,
> +                      NULL,
> +                      &BufferSize,
> +                      pHandle );
> +      if ( EFI_ERROR ( Status )) {
> +        //
> +        //  Error getting handles
> +        //
> +        DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
> +                "Failure getting Telnet handles\r\n" ));
> +        break;
> +      }
> +
> +      //
> +      //  Remove any use of the driver
> +      //
> +      Max = BufferSize / sizeof ( pHandle[ 0 ]);
> +      for ( Index = 0; Max > Index; Index++ ) {
> +        Status = DriverStop ( &gDriverBinding,
> +                              pHandle[ Index ],
> +                              0,
> +                              NULL );
> +        if ( EFI_ERROR ( Status )) {
> +          DEBUG (( DEBUG_WARN | DEBUG_INIT | DEBUG_INFO,
> +                    "WARNING - Failed to shutdown the driver on handle %08x\r\n",
> pHandle[ Index ]));
> +          break;
> +        }
> +      }
> +      break;
> +    }
> +  }
> +  else {
> +    if ( EFI_NOT_FOUND == Status ) {
> +      //
> +      //  No devices were found
> +      //
> +      Status = EFI_SUCCESS;
> +    }
> +  }
> +
> +  //
> +  //  Free the handle array
> +  //
> +  if ( NULL != pHandle ) {
> +    gBS->FreePool ( pHandle );
> +  }
> +
> +  //
> +  //  Remove the protocols installed by the EntryPoint routine.
> +  //
> +  if ( !EFI_ERROR ( Status )) {
> +    gBS->UninstallMultipleProtocolInterfaces (
> +            ImageHandle,
> +            &gEfiDriverBindingProtocolGuid,
> +            &gDriverBinding,
> +            &gEfiComponentNameProtocolGuid,
> +            &gComponentName,
> +            &gEfiComponentName2ProtocolGuid,
> +            &gComponentName2,
> +            NULL
> +            );
> +    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> +            "Removed:   gEfiComponentName2ProtocolGuid from 0x%08x\r\n",
> +            ImageHandle ));
> +    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> +              "Removed:   gEfiComponentNameProtocolGuid from 0x%08x\r\n",
> +              ImageHandle ));
> +    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> +              "Removed:   gEfiDriverBindingProtocolGuid from 0x%08x\r\n",
> +              ImageHandle ));
> +  }
> +
> +  //
> +  //  Return the unload status
> +  //
> +  return Status;
> +}
> +
> +
> +/**
> +Ax88772 driver entry point.
> +
> +@param [in] ImageHandle       Handle for the image.
> +@param [in] pSystemTable      Address of the system table.
> +
> +@retval EFI_SUCCESS           Image successfully loaded.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +EntryPoint (
> +  IN EFI_HANDLE ImageHandle,
> +  IN EFI_SYSTEM_TABLE * pSystemTable
> +  )
> +{
> +  EFI_STATUS    Status;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  //  Add the driver to the list of drivers
> +  //
> +  Status = EfiLibInstallDriverBindingComponentName2 (
> +             ImageHandle,
> +             pSystemTable,
> +             &gDriverBinding,
> +             ImageHandle,
> +             &gComponentName,
> +             &gComponentName2
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +  if ( !EFI_ERROR ( Status )) {
> +    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> +              "Installed: gEfiDriverBindingProtocolGuid on   0x%08x\r\n",
> +              ImageHandle ));
> +    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> +              "Installed: gEfiComponentNameProtocolGuid on   0x%08x\r\n",
> +              ImageHandle ));
> +    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> +              "Installed: gEfiComponentName2ProtocolGuid on   0x%08x\r\n",
> +              ImageHandle ));
> +  }
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> diff --git
> a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/SimpleNetwork
> .c
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/SimpleNetwork
> .c
> new file mode 100644
> index 0000000000..0105d04f5d
> --- /dev/null
> +++
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/SimpleNetwork
> .c
> @@ -0,0 +1,1503 @@
> +/** @file
> +  Provides the Simple Network functions.
> +
> +  Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "Ax88772.h"
> +
> +/**
> +  This function updates the filtering on the receiver.
> +
> +  This support routine calls ::Ax88772MacAddressSet to update
> +  the MAC address.  This routine then rebuilds the multicast
> +  hash by calling ::Ax88772MulticastClear and ::Ax88772MulticastSet.
> +  Finally this routine enables the receiver by calling
> +  ::Ax88772RxControl.
> +
> +  @param [in] pSimpleNetwork    Simple network mode pointer
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +ReceiveFilterUpdate (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> +  )
> +{
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  NIC_DEVICE * pNicDevice;
> +  EFI_STATUS Status;
> +  UINT32 Index;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  // Set the MAC address
> +  //
> +  pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> +  pMode = pSimpleNetwork->Mode;
> +  Status = Ax88772MacAddressSet ( pNicDevice,
> +                                  &pMode->CurrentAddress.Addr[0]);
> +  if ( !EFI_ERROR ( Status )) {
> +    //
> +    // Clear the multicast hash table
> +    //
> +    Ax88772MulticastClear ( pNicDevice );
> +
> +    //
> +    // Load the multicast hash table
> +    //
> +    if ( 0 != ( pMode->ReceiveFilterSetting &
> EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST )) {
> +      for ( Index = 0;
> +            ( !EFI_ERROR ( Status )) && ( Index < pMode->MCastFilterCount );
> +            Index++ ) {
> +        //
> +        // Enable the next multicast address
> +        //
> +        Ax88772MulticastSet ( pNicDevice,
> +                              &pMode->MCastFilter[ Index ].Addr[0]);
> +      }
> +    }
> +
> +    //
> +    // Enable the receiver
> +    //
> +    if ( !EFI_ERROR ( Status )) {
> +      Status = Ax88772RxControl ( pNicDevice, pMode->ReceiveFilterSetting );
> +    }
> +  }
> +
> +  //
> +  // Return the operation status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  This function updates the SNP driver status.
> +
> +  This function gets the current interrupt and recycled transmit
> +  buffer status from the network interface.  The interrupt status
> +  and the media status are returned as a bit mask in InterruptStatus.
> +  If InterruptStatus is NULL, the interrupt status will not be read.
> +  Upon successful return of the media status, the MediaPresent field
> +  of EFI_SIMPLE_NETWORK_MODE will be updated to reflect any change
> +  of media status.  If TxBuf is not NULL, a recycled transmit buffer
> +  address will be retrived.  If a recycled transmit buffer address
> +  is returned in TxBuf, then the buffer has been successfully
> +  transmitted, and the status for that buffer is cleared.
> +
> +  This function calls ::Ax88772Rx to update the media status and
> +  queue any receive packets.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] pInterruptStatus  A pointer to the bit mask of the current
> active interrupts.
> +                                If this is NULL, the interrupt status will not be read from
> +                                the device.  If this is not NULL, the interrupt status will
> +                                be read from teh device.  When the interrupt status is
> read,
> +                                it will also be cleared.  Clearing the transmit interrupt
> +                                does not empty the recycled transmit buffer array.
> +  @param [out] ppTxBuf          Recycled transmit buffer address.  The
> network interface will
> +                                not transmit if its internal recycled transmit buffer array is
> +                                full.  Reading the transmit buffer does not clear the
> transmit
> +                                interrupt.  If this is NULL, then the transmit buffer status
> +                                will not be read.  If there are not transmit buffers to
> recycle
> +                                and TxBuf is not NULL, *TxBuf will be set to NULL.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_GetStatus (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  OUT UINT32 * pInterruptStatus,
> +  OUT VOID ** ppTxBuf
> +  )
> +{
> +  BOOLEAN bLinkIdle;
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  NIC_DEVICE * pNicDevice;
> +  EFI_STATUS Status;
> +  EFI_TPL TplPrevious;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  // Verify the parameters
> +  //
> +  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> +    //
> +    // Return the transmit buffer
> +    //
> +    pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> +    if (( NULL != ppTxBuf ) && ( NULL != pNicDevice->pTxBuffer )) {
> +      *ppTxBuf = pNicDevice->pTxBuffer;
> +      pNicDevice->pTxBuffer = NULL;
> +    }
> +
> +    //
> +    // Determine if interface is running
> +    //
> +    pMode = pSimpleNetwork->Mode;
> +    if ( EfiSimpleNetworkStopped != pMode->State ) {
> +      //
> +      //  Synchronize with Ax88772Timer
> +      //
> +      VERIFY_TPL ( TPL_AX88772 );
> +      TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
> +
> +      //
> +      // Update the link status
> +      //
> +      bLinkIdle = pNicDevice->bLinkIdle;
> +      pNicDevice->bLinkIdle = TRUE;
> +      Ax88772Rx ( pNicDevice, bLinkIdle );
> +      pMode->MediaPresent = pNicDevice->bLinkUp;
> +
> +      //
> +      //  Release the synchronization with Ax88772Timer
> +      //
> +      gBS->RestoreTPL ( TplPrevious );
> +
> +      //
> +      // Return the interrupt status
> +      //
> +      if ( NULL != pInterruptStatus ) {
> +        *pInterruptStatus = 0;
> +      }
> +      Status = EFI_SUCCESS;
> +    }
> +    else {
> +      Status = EFI_NOT_STARTED;
> +    }
> +  }
> +  else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Return the operation status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  Resets the network adapter and allocates the transmit and receive buffers
> +  required by the network interface; optionally, also requests allocation of
> +  additional transmit and receive buffers.  This routine must be called
> before
> +  any other routine in the Simple Network protocol is called.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] ExtraRxBufferSize Size in bytes to add to the receive buffer
> allocation
> +  @param [in] ExtraTxBufferSize Size in bytes to add to the transmit buffer
> allocation
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_OUT_OF_RESOURCES  There was not enough memory for the
> transmit and receive buffers
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Initialize (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN UINTN ExtraRxBufferSize,
> +  IN UINTN ExtraTxBufferSize
> +  )
> +{
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  EFI_STATUS Status;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  // Verify the parameters
> +  //
> +  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> +    //
> +    // Determine if the interface is already started
> +    //
> +    pMode = pSimpleNetwork->Mode;
> +    if ( EfiSimpleNetworkStarted == pMode->State ) {
> +      if (( 0 == ExtraRxBufferSize ) && ( 0 == ExtraTxBufferSize )) {
> +        //
> +        // Start the adapter
> +        //
> +        Status = SN_Reset ( pSimpleNetwork, FALSE );
> +        if ( !EFI_ERROR ( Status )) {
> +          //
> +          // Update the network state
> +          //
> +          pMode->State = EfiSimpleNetworkInitialized;
> +        }
> +      }
> +      else {
> +        Status = EFI_UNSUPPORTED;
> +      }
> +    }
> +    else {
> +      Status = EFI_NOT_STARTED;
> +    }
> +  }
> +  else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Return the operation status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  This function converts a multicast IP address to a multicast HW MAC
> address
> +  for all packet transactions.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] bIPv6             Set to TRUE if the multicast IP address is IPv6
> [RFC2460].
> +                                Set to FALSE if the multicast IP address is IPv4 [RFC 791].
> +  @param [in] pIP               The multicast IP address that is to be converted
> to a
> +                                multicast HW MAC address.
> +  @param [in] pMAC              The multicast HW MAC address that is to be
> generated from IP.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_MCastIPtoMAC (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN BOOLEAN bIPv6,
> +  IN EFI_IP_ADDRESS * pIP,
> +  IN EFI_MAC_ADDRESS * pMAC
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  // This is not currently supported
> +  //
> +  Status = EFI_UNSUPPORTED;
> +
> +  //
> +  // Return the operation status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  This function performs read and write operations on the NVRAM device
> +  attached to a network interface.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] ReadWrite         TRUE for read operations, FALSE for write
> operations.
> +  @param [in] Offset            Byte offset in the NVRAM device at which to
> start the
> +                                read or write operation.  This must be a multiple of
> +                                NvRamAccessSize and less than NvRamSize.
> +  @param [in] BufferSize        The number of bytes to read or write from the
> NVRAM device.
> +                                This must also be a multiple of NvramAccessSize.
> +  @param [in, out] pBuffer      A pointer to the data buffer.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_NvData (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN BOOLEAN ReadWrite,
> +  IN UINTN Offset,
> +  IN UINTN BufferSize,
> +  IN OUT VOID * pBuffer
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  // This is not currently supported
> +  //
> +  Status = EFI_UNSUPPORTED;
> +
> +  //
> +  // Return the operation status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  Attempt to receive a packet from the network adapter.
> +
> +  This function retrieves one packet from the receive queue of the network
> +  interface.  If there are no packets on the receive queue, then
> EFI_NOT_READY
> +  will be returned.  If there is a packet on the receive queue, and the size
> +  of the packet is smaller than BufferSize, then the contents of the packet
> +  will be placed in Buffer, and BufferSize will be udpated with the actual
> +  size of the packet.  In addition, if SrcAddr, DestAddr, and Protocol are
> +  not NULL, then these values will be extracted from the media header and
> +  returned.  If BufferSize is smaller than the received packet, then the
> +  size of the receive packet will be placed in BufferSize and
> +  EFI_BUFFER_TOO_SMALL will be returned.
> +
> +  This routine calls ::Ax88772Rx to update the media status and
> +  empty the network adapter of receive packets.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [out] pHeaderSize      The size, in bytes, of the media header to be
> filled in by
> +                                the Transmit() function.  If HeaderSize is non-zero, then
> +                                it must be equal to SimpleNetwork->Mode-
> >MediaHeaderSize
> +                                and DestAddr and Protocol parameters must not be NULL.
> +  @param [out] pBufferSize      The size, in bytes, of the entire packet
> (media header and
> +                                data) to be transmitted through the network interface.
> +  @param [out] pBuffer          A pointer to the packet (media header
> followed by data) to
> +                                to be transmitted.  This parameter can not be NULL.  If
> +                                HeaderSize is zero, then the media header is Buffer must
> +                                already be filled in by the caller.  If HeaderSize is nonzero,
> +                                then the media header will be filled in by the Transmit()
> +                                function.
> +  @param [out] pSrcAddr         The source HW MAC address.  If HeaderSize is
> zero, then
> +                                this parameter is ignored.  If HeaderSize is nonzero and
> +                                SrcAddr is NULL, then SimpleNetwork->Mode-
> >CurrentAddress
> +                                is used for the source HW MAC address.
> +  @param [out] pDestAddr        The destination HW MAC address.  If
> HeaderSize is zero, then
> +                                this parameter is ignored.
> +  @param [out] pProtocol        The type of header to build.  If HeaderSize is
> zero, then
> +                                this parameter is ignored.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_NOT_READY         No packets have been received on the
> network interface.
> +  @retval EFI_BUFFER_TOO_SMALL  The packet is larger than BufferSize
> bytes.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Receive (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  OUT UINTN                      * pHeaderSize,
> +  OUT UINTN                      * pBufferSize,
> +  OUT VOID                       * pBuffer,
> +  OUT EFI_MAC_ADDRESS            * pSrcAddr,
> +  OUT EFI_MAC_ADDRESS            * pDestAddr,
> +  OUT UINT16                     * pProtocol
> +  )
> +{
> +  ETHERNET_HEADER * pHeader;
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  NIC_DEVICE * pNicDevice;
> +  RX_TX_PACKET * pRxPacket;
> +  EFI_STATUS Status;
> +  EFI_TPL TplPrevious;
> +  UINT16 Type;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  // Verify the parameters
> +  //
> +  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> +    //
> +    // The interface must be running
> +    //
> +    pMode = pSimpleNetwork->Mode;
> +    if ( EfiSimpleNetworkInitialized == pMode->State ) {
> +      //
> +      //  Synchronize with Ax88772Timer
> +      //
> +      VERIFY_TPL ( TPL_AX88772 );
> +      TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
> +
> +      //
> +      // Update the link status
> +      //
> +      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> +      Ax88772Rx ( pNicDevice, FALSE );
> +      pMode->MediaPresent = pNicDevice->bLinkUp;
> +      if ( pMode->MediaPresent ) {
> +        //
> +        //  Attempt to receive a packet
> +        //
> +        pRxPacket = pNicDevice->pRxHead;
> +        if ( NULL != pRxPacket ) {
> +          pNicDevice->pRxHead = pRxPacket->pNext;
> +          if ( NULL == pNicDevice->pRxHead ) {
> +            pNicDevice->pRxTail = NULL;
> +          }
> +
> +          //
> +          // Copy the received packet into the receive buffer
> +          //
> +          *pBufferSize = pRxPacket->Length;
> +          CopyMem ( pBuffer, &pRxPacket->Data[0], pRxPacket->Length );
> +          pHeader = (ETHERNET_HEADER *) &pRxPacket->Data[0];
> +          if ( NULL != pHeaderSize ) {
> +            *pHeaderSize = sizeof ( *pHeader );
> +          }
> +          if ( NULL != pDestAddr ) {
> +            CopyMem ( pDestAddr, &pHeader->dest_addr,
> PXE_HWADDR_LEN_ETHER );
> +          }
> +          if ( NULL != pSrcAddr ) {
> +            CopyMem ( pSrcAddr, &pHeader->src_addr,
> PXE_HWADDR_LEN_ETHER );
> +          }
> +          if ( NULL != pProtocol ) {
> +            Type = pHeader->type;
> +            Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
> +            *pProtocol = Type;
> +          }
> +          Status = EFI_SUCCESS;
> +        }
> +        else {
> +          //
> +          //  No receive packets available
> +          //
> +          Status = EFI_NOT_READY;
> +        }
> +      }
> +      else {
> +        //
> +        //  Link no up
> +        //
> +        Status = EFI_NOT_READY;
> +      }
> +
> +      //
> +      //  Release the synchronization with Ax88772Timer
> +      //
> +      gBS->RestoreTPL ( TplPrevious );
> +    }
> +    else {
> +      Status = EFI_NOT_STARTED;
> +    }
> +  }
> +  else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Return the operation status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  This function is used to enable and disable the hardware and software
> receive
> +  filters for the underlying network device.
> +
> +  The receive filter change is broken down into three steps:
> +
> +    1.  The filter mask bits that are set (ON) in the Enable parameter
> +        are added to the current receive filter settings.
> +
> +    2.  The filter mask bits that are set (ON) in the Disable parameter
> +        are subtracted from the updated receive filter settins.
> +
> +    3.  If the resulting filter settigns is not supported by the hardware
> +        a more liberal setting is selected.
> +
> +  If the same bits are set in the Enable and Disable parameters, then the bits
> +  in the Disable parameter takes precedence.
> +
> +  If the ResetMCastFilter parameter is TRUE, then the multicast address list
> +  filter is disabled (irregardless of what other multicast bits are set in
> +  the enable and Disable parameters).  The SNP->Mode->MCastFilterCount
> field
> +  is set to zero.  The SNP->Mode->MCastFilter contents are undefined.
> +
> +  After enableing or disabling receive filter settings, software should
> +  verify the new settings by checking the SNP->Mode-
> >ReceeiveFilterSettings,
> +  SNP->Mode->MCastFilterCount and SNP->Mode->MCastFilter fields.
> +
> +  Note: Some network drivers and/or devices will automatically promote
> +  receive filter settings if the requested setting can not be honored.
> +  For example, if a request for four multicast addresses is made and
> +  the underlying hardware only supports two multicast addresses the
> +  driver might set the promiscuous or promiscuous multicast receive filters
> +  instead.  The receiving software is responsible for discarding any extra
> +  packets that get through the hardware receive filters.
> +
> +  If ResetMCastFilter is TRUE, then the multicast receive filter list
> +  on the network interface will be reset to the default multicast receive
> +  filter list.  If ResetMCastFilter is FALSE, and this network interface
> +  allows the multicast receive filter list to be modified, then the
> +  MCastFilterCnt and MCastFilter are used to update the current multicast
> +  receive filter list.  The modified receive filter list settings can be
> +  found in the MCastFilter field of EFI_SIMPLE_NETWORK_MODE.
> +
> +  This routine calls ::ReceiveFilterUpdate to update the receive
> +  state in the network adapter.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] Enable            A bit mask of receive filters to enable on the
> network interface.
> +  @param [in] Disable           A bit mask of receive filters to disable on the
> network interface.
> +                                For backward compatibility with EFI 1.1 platforms, the
> +                                EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit must be
> set
> +                                when the ResetMCastFilter parameter is TRUE.
> +  @param [in] bResetMCastFilter Set to TRUE to reset the contents of the
> multicast receive
> +                                filters on the network interface to their default values.
> +  @param [in] MCastFilterCnt    Number of multicast HW MAC address in
> the new MCastFilter list.
> +                                This value must be less than or equal to the
> MaxMCastFilterCnt
> +                                field of EFI_SIMPLE_NETWORK_MODE.  This field is
> optional if
> +                                ResetMCastFilter is TRUE.
> +  @param [in] pMCastFilter      A pointer to a list of new multicast receive
> filter HW MAC
> +                                addresses.  This list will replace any existing multicast
> +                                HW MAC address list.  This field is optional if
> ResetMCastFilter
> +                                is TRUE.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_ReceiveFilters (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN UINT32 Enable,
> +  IN UINT32 Disable,
> +  IN BOOLEAN bResetMCastFilter,
> +  IN UINTN MCastFilterCnt,
> +  IN EFI_MAC_ADDRESS * pMCastFilter
> +  )
> +{
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  EFI_MAC_ADDRESS * pMulticastAddress;
> +  EFI_MAC_ADDRESS * pTableEnd;
> +  EFI_STATUS Status;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  // Verify the parameters
> +  //
> +  Status = EFI_INVALID_PARAMETER;
> +  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> +    pMode = pSimpleNetwork->Mode;
> +
> +    //
> +    //  Update the multicast list if necessary
> +    //
> +    if ( !bResetMCastFilter ) {
> +      if ( 0 != MCastFilterCnt ) {
> +        if (( MAX_MCAST_FILTER_CNT >= MCastFilterCnt )
> +          && ( NULL != pMCastFilter )) {
> +          //
> +          // Verify the multicast addresses
> +          //
> +          pMulticastAddress = pMCastFilter;
> +          pTableEnd = pMulticastAddress + MCastFilterCnt;
> +          while ( pTableEnd > pMulticastAddress ) {
> +            //
> +            // The first digit of the multicast address must have the LSB set
> +            //
> +            if ( 0 == ( pMulticastAddress->Addr[0] & 1 )) {
> +              //
> +              // Invalid multicast address
> +              //
> +              break;
> +            }
> +            pMulticastAddress += 1;
> +          }
> +          if ( pTableEnd == pMulticastAddress ) {
> +            //
> +            // Update the multicast filter list.
> +            //
> +            CopyMem (&pMode->MCastFilter[0],
> +                     pMCastFilter,
> +                     MCastFilterCnt * sizeof ( *pMCastFilter ));
> +            Status = EFI_SUCCESS;
> +          }
> +        }
> +      }
> +      else {
> +        Status = EFI_SUCCESS;
> +      }
> +    }
> +    else {
> +      //
> +      // No multicast address list is specified
> +      //
> +      MCastFilterCnt = 0;
> +      Status = EFI_SUCCESS;
> +    }
> +    if ( !EFI_ERROR ( Status )) {
> +      //
> +      // The parameters are valid!
> +      //
> +      pMode->ReceiveFilterSetting |= Enable;
> +      pMode->ReceiveFilterSetting &= ~Disable;
> +      pMode->MCastFilterCount = (UINT32)MCastFilterCnt;
> +
> +      //
> +      // Update the receive filters in the adapter
> +      //
> +      Status = ReceiveFilterUpdate ( pSimpleNetwork );
> +    }
> +  }
> +
> +  //
> +  // Return the operation status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  Reset the network adapter.
> +
> +  Resets a network adapter and reinitializes it with the parameters that
> +  were provided in the previous call to Initialize ().  The transmit and
> +  receive queues are cleared.  Receive filters, the station address, the
> +  statistics, and the multicast-IP-to-HW MAC addresses are not reset by
> +  this call.
> +
> +  This routine calls ::Ax88772Reset to perform the adapter specific
> +  reset operation.  This routine also starts the link negotiation
> +  by calling ::Ax88772NegotiateLinkStart.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] bExtendedVerification  Indicates that the driver may perform
> a more
> +                                exhaustive verification operation of the device
> +                                during reset.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Reset (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN BOOLEAN bExtendedVerification
> +  )
> +{
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  NIC_DEVICE * pNicDevice;
> +  RX_TX_PACKET * pRxPacket;
> +  EFI_STATUS Status;
> +  EFI_TPL TplPrevious;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  //  Verify the parameters
> +  //
> +  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> +    //
> +    //  Synchronize with Ax88772Timer
> +    //
> +    VERIFY_TPL ( TPL_AX88772 );
> +    TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
> +
> +    //
> +    //  Update the device state
> +    //
> +    pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> +    pNicDevice->bComplete = FALSE;
> +    pNicDevice->bLinkUp = FALSE;
> +
> +    pMode = pSimpleNetwork->Mode;
> +    pMode->MediaPresent = FALSE;
> +
> +    //
> +    //  Discard any received packets
> +    //
> +    while ( NULL != pNicDevice->pRxHead ) {
> +      //
> +      //  Remove the packet from the received packet list
> +      //
> +      pRxPacket = pNicDevice->pRxHead;
> +      pNicDevice->pRxHead = pRxPacket->pNext;
> +
> +      //
> +      //  Queue the packet to the free list
> +      //
> +      pRxPacket->pNext = pNicDevice->pRxFree;
> +      pNicDevice->pRxFree = pRxPacket;
> +    }
> +    pNicDevice->pRxTail = NULL;
> +
> +    //
> +    //  Reset the device
> +    //
> +    Status = Ax88772Reset ( pNicDevice );
> +    if ( !EFI_ERROR ( Status )) {
> +      //
> +      //  Update the receive filters in the adapter
> +      //
> +      Status = ReceiveFilterUpdate ( pSimpleNetwork );
> +
> +      //
> +      //  Try to get a connection to the network
> +      //
> +      if ( !EFI_ERROR ( Status )) {
> +        //
> +        //  Start the autonegotiation
> +        //
> +        Status = Ax88772NegotiateLinkStart ( pNicDevice );
> +      }
> +    }
> +
> +    //
> +    //  Release the synchronization with Ax88772Timer
> +    //
> +    gBS->RestoreTPL ( TplPrevious );
> +  }
> +  else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Return the operation status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  Initialize the simple network protocol.
> +
> +  This routine calls ::Ax88772MacAddressGet to obtain the
> +  MAC address.
> +
> +  @param [in] pNicDevice       NIC_DEVICE_INSTANCE pointer
> +
> +  @retval EFI_SUCCESS     Setup was successful
> +
> +**/
> +EFI_STATUS
> +SN_Setup (
> +  IN NIC_DEVICE * pNicDevice
> +  )
> +{
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork;
> +  EFI_STATUS Status;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  // Initialize the simple network protocol
> +  //
> +  pSimpleNetwork = &pNicDevice->SimpleNetwork;
> +  pSimpleNetwork->Revision =
> EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;
> +  pSimpleNetwork->Start = (EFI_SIMPLE_NETWORK_START)SN_Start;
> +  pSimpleNetwork->Stop = (EFI_SIMPLE_NETWORK_STOP)SN_Stop;
> +  pSimpleNetwork->Initialize =
> (EFI_SIMPLE_NETWORK_INITIALIZE)SN_Initialize;
> +  pSimpleNetwork->Reset = (EFI_SIMPLE_NETWORK_RESET)SN_Reset;
> +  pSimpleNetwork->Shutdown =
> (EFI_SIMPLE_NETWORK_SHUTDOWN)SN_Shutdown;
> +  pSimpleNetwork->ReceiveFilters =
> (EFI_SIMPLE_NETWORK_RECEIVE_FILTERS)SN_ReceiveFilters;
> +  pSimpleNetwork->StationAddress =
> (EFI_SIMPLE_NETWORK_STATION_ADDRESS)SN_StationAddress;
> +  pSimpleNetwork->Statistics =
> (EFI_SIMPLE_NETWORK_STATISTICS)SN_Statistics;
> +  pSimpleNetwork->MCastIpToMac =
> (EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC)SN_MCastIPtoMAC;
> +  pSimpleNetwork->NvData = (EFI_SIMPLE_NETWORK_NVDATA)SN_NvData;
> +  pSimpleNetwork->GetStatus =
> (EFI_SIMPLE_NETWORK_GET_STATUS)SN_GetStatus;
> +  pSimpleNetwork->Transmit =
> (EFI_SIMPLE_NETWORK_TRANSMIT)SN_Transmit;
> +  pSimpleNetwork->Receive = (EFI_SIMPLE_NETWORK_RECEIVE)SN_Receive;
> +  pSimpleNetwork->WaitForPacket = NULL;
> +  pMode = &pNicDevice->SimpleNetworkData;
> +  pSimpleNetwork->Mode = pMode;
> +
> +  pMode->State = EfiSimpleNetworkStopped;
> +  pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
> +  pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
> +  pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
> +  pMode->NvRamSize = 0;
> +  pMode->NvRamAccessSize = 0;
> +  pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
> +                           | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
> +                           | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
> +                           | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
> +                           |
> EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
> +  pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
> +                              | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
> +  pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
> +  pMode->MCastFilterCount = 0;
> +  SetMem ( &pMode->BroadcastAddress,
> +           PXE_HWADDR_LEN_ETHER,
> +           0xff );
> +  pMode->IfType = EfiNetworkInterfaceUndi;
> +  pMode->MacAddressChangeable = TRUE;
> +  pMode->MultipleTxSupported = TRUE;
> +  pMode->MediaPresentSupported = TRUE;
> +  pMode->MediaPresent = FALSE;
> +
> +  //
> +  //  Read the MAC address
> +  //
> +  pNicDevice->PhyId = PHY_ID_INTERNAL;
> +  pNicDevice->b100Mbps = TRUE;
> +  pNicDevice->bFullDuplex = TRUE;
> +
> +  Status = gBS->AllocatePool ( EfiRuntimeServicesData,
> +                               MAX_BULKIN_SIZE,
> +                               (VOID **) &pNicDevice->pBulkInBuff);
> +  if ( EFI_ERROR(Status)) {
> +    DEBUG (( EFI_D_ERROR, "Memory are not enough\n"));
> +    return Status;
> +  }
> +
> +  Status = Ax88772MacAddressGet (
> +                pNicDevice,
> +                &pMode->PermanentAddress.Addr[0]);
> +  if ( !EFI_ERROR ( Status )) {
> +    //
> +    //  Display the MAC address
> +    //
> +    DEBUG (( DEBUG_MAC_ADDRESS | DEBUG_INFO,
> +              "MAC: %02x-%02x-%02x-%02x-%02x-%02x\n",
> +              pMode->PermanentAddress.Addr[0],
> +              pMode->PermanentAddress.Addr[1],
> +              pMode->PermanentAddress.Addr[2],
> +              pMode->PermanentAddress.Addr[3],
> +              pMode->PermanentAddress.Addr[4],
> +              pMode->PermanentAddress.Addr[5]));
> +
> +    //
> +    //  Use the hardware address as the current address
> +    //
> +    CopyMem ( &pMode->CurrentAddress,
> +              &pMode->PermanentAddress,
> +              PXE_HWADDR_LEN_ETHER );
> +  }
> +
> +  //
> +  //  Return the setup status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  This routine starts the network interface.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_ALREADY_STARTED   The network interface was already
> started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Start (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> +  )
> +{
> +  NIC_DEVICE * pNicDevice;
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  EFI_STATUS Status;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  // Verify the parameters
> +  //
> +  Status = EFI_INVALID_PARAMETER;
> +  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> +    pMode = pSimpleNetwork->Mode;
> +    if ( EfiSimpleNetworkStopped == pMode->State ) {
> +      //
> +      // Initialize the mode structure
> +      // NVRAM access is not supported
> +      //
> +      ZeroMem ( pMode, sizeof ( *pMode ));
> +
> +      pMode->State = EfiSimpleNetworkStarted;
> +      pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
> +      pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
> +      pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
> +      pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
> +                               | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
> +                               | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
> +                               | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
> +                               |
> EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
> +      pMode->ReceiveFilterSetting =
> EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
> +      pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
> +      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> +      Status = Ax88772MacAddressGet ( pNicDevice, &pMode-
> >PermanentAddress.Addr[0]);
> +      CopyMem ( &pMode->CurrentAddress,
> +                &pMode->PermanentAddress,
> +                sizeof ( pMode->CurrentAddress ));
> +      pMode->BroadcastAddress.Addr[0] = 0xff;
> +      pMode->BroadcastAddress.Addr[1] = 0xff;
> +      pMode->BroadcastAddress.Addr[2] = 0xff;
> +      pMode->BroadcastAddress.Addr[3] = 0xff;
> +      pMode->BroadcastAddress.Addr[4] = 0xff;
> +      pMode->BroadcastAddress.Addr[5] = 0xff;
> +      pMode->IfType = 1;
> +      pMode->MacAddressChangeable = TRUE;
> +      pMode->MultipleTxSupported = TRUE;
> +      pMode->MediaPresentSupported = TRUE;
> +      pMode->MediaPresent = FALSE;
> +    }
> +    else {
> +      Status = EFI_ALREADY_STARTED;
> +    }
> +  }
> +
> +  //
> +  // Return the operation status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  Set the MAC address.
> +
> +  This function modifies or resets the current station address of a
> +  network interface.  If Reset is TRUE, then the current station address
> +  is set ot the network interface's permanent address.  If Reset if FALSE
> +  then the current station address is changed to the address specified by
> +  pNew.
> +
> +  This routine calls ::Ax88772MacAddressSet to update the MAC address
> +  in the network adapter.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] bReset            Flag used to reset the station address to the
> +                                network interface's permanent address.
> +  @param [in] pNew              New station address to be used for the network
> +                                interface.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_StationAddress (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN BOOLEAN bReset,
> +  IN EFI_MAC_ADDRESS * pNew
> +  )
> +{
> +  NIC_DEVICE * pNicDevice;
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  EFI_STATUS Status;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  // Verify the parameters
> +  //
> +  if (( NULL != pSimpleNetwork )
> +    && ( NULL != pSimpleNetwork->Mode )
> +    && (( !bReset ) || ( bReset && ( NULL != pNew )))) {
> +    //
> +    // Verify that the adapter is already started
> +    //
> +    pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> +    pMode = pSimpleNetwork->Mode;
> +    if ( EfiSimpleNetworkStarted == pMode->State ) {
> +      //
> +      // Determine the adapter MAC address
> +      //
> +      if ( bReset ) {
> +        //
> +        // Use the permanent address
> +        //
> +        CopyMem ( &pMode->CurrentAddress,
> +                  &pMode->PermanentAddress,
> +                  sizeof ( pMode->CurrentAddress ));
> +      }
> +      else {
> +        //
> +        // Use the specified address
> +        //
> +        CopyMem ( &pMode->CurrentAddress,
> +                  pNew,
> +                  sizeof ( pMode->CurrentAddress ));
> +      }
> +
> +      //
> +      // Update the address on the adapter
> +      //
> +      Status = Ax88772MacAddressSet ( pNicDevice, &pMode-
> >CurrentAddress.Addr[0]);
> +    }
> +    else {
> +      Status = EFI_NOT_STARTED;
> +    }
> +  }
> +  else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Return the operation status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  This function resets or collects the statistics on a network interface.
> +  If the size of the statistics table specified by StatisticsSize is not
> +  big enough for all of the statistics that are collected by the network
> +  interface, then a partial buffer of statistics is returned in
> +  StatisticsTable.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] bReset            Set to TRUE to reset the statistics for the
> network interface.
> +  @param [in, out] pStatisticsSize  On input the size, in bytes, of
> StatisticsTable.  On output
> +                                the size, in bytes, of the resulting table of statistics.
> +  @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS
> structure that
> +                                conains the statistics.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_BUFFER_TOO_SMALL  The pStatisticsTable is NULL or the
> buffer is too small.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Statistics (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN BOOLEAN bReset,
> +  IN OUT UINTN * pStatisticsSize,
> +  OUT EFI_NETWORK_STATISTICS * pStatisticsTable
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  // This is not currently supported
> +  //
> +  Status = EFI_UNSUPPORTED;
> +
> +  //
> +  // Return the operation status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  This function stops a network interface.  This call is only valid
> +  if the network interface is in the started state.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Stop (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> +  )
> +{
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  EFI_STATUS Status;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  // Verify the parameters
> +  //
> +  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> +    //
> +    // Determine if the interface is started
> +    //
> +    pMode = pSimpleNetwork->Mode;
> +    if ( EfiSimpleNetworkStopped != pMode->State ) {
> +      if ( EfiSimpleNetworkStarted == pMode->State ) {
> +        //
> +        //  Release the resources acquired in SN_Start
> +        //
> +
> +        //
> +        //  Mark the adapter as stopped
> +        //
> +        pMode->State = EfiSimpleNetworkStopped;
> +        Status = EFI_SUCCESS;
> +      }
> +      else {
> +        Status = EFI_UNSUPPORTED;
> +      }
> +    }
> +    else {
> +      Status = EFI_NOT_STARTED;
> +    }
> +  }
> +  else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Return the operation status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  This function releases the memory buffers assigned in the Initialize() call.
> +  Pending transmits and receives are lost, and interrupts are cleared and
> disabled.
> +  After this call, only Initialize() and Stop() calls may be used.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Shutdown (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> +  )
> +{
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  UINT32 RxFilter;
> +  EFI_STATUS Status;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  // Verify the parameters
> +  //
> +  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> +    //
> +    // Determine if the interface is already started
> +    //
> +    pMode = pSimpleNetwork->Mode;
> +    if ( EfiSimpleNetworkInitialized == pMode->State ) {
> +      //
> +      // Stop the adapter
> +      //
> +      RxFilter = pMode->ReceiveFilterSetting;
> +      pMode->ReceiveFilterSetting = 0;
> +      Status = SN_Reset ( pSimpleNetwork, FALSE );
> +      pMode->ReceiveFilterSetting = RxFilter;
> +      if ( !EFI_ERROR ( Status )) {
> +        //
> +        // Release the resources acquired by SN_Initialize
> +        //
> +
> +        //
> +        // Update the network state
> +        //
> +        pMode->State = EfiSimpleNetworkStarted;
> +      }
> +    }
> +    else {
> +      Status = EFI_NOT_STARTED;
> +    }
> +  }
> +  else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Return the operation status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> +
> +
> +/**
> +  Send a packet over the network.
> +
> +  This function places the packet specified by Header and Buffer on
> +  the transmit queue.  This function performs a non-blocking transmit
> +  operation.  When the transmit is complete, the buffer is returned
> +  via the GetStatus() call.
> +
> +  This routine calls ::Ax88772Rx to empty the network adapter of
> +  receive packets.  The routine then passes the transmit packet
> +  to the network adapter.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] HeaderSize        The size, in bytes, of the media header to be
> filled in by
> +                                the Transmit() function.  If HeaderSize is non-zero, then
> +                                it must be equal to SimpleNetwork->Mode-
> >MediaHeaderSize
> +                                and DestAddr and Protocol parameters must not be NULL.
> +  @param [in] BufferSize        The size, in bytes, of the entire packet (media
> header and
> +                                data) to be transmitted through the network interface.
> +  @param [in] pBuffer           A pointer to the packet (media header followed
> by data) to
> +                                to be transmitted.  This parameter can not be NULL.  If
> +                                HeaderSize is zero, then the media header is Buffer must
> +                                already be filled in by the caller.  If HeaderSize is nonzero,
> +                                then the media header will be filled in by the Transmit()
> +                                function.
> +  @param [in] pSrcAddr          The source HW MAC address.  If HeaderSize is
> zero, then
> +                                this parameter is ignored.  If HeaderSize is nonzero and
> +                                SrcAddr is NULL, then SimpleNetwork->Mode-
> >CurrentAddress
> +                                is used for the source HW MAC address.
> +  @param [in] pDestAddr         The destination HW MAC address.  If
> HeaderSize is zero, then
> +                                this parameter is ignored.
> +  @param [in] pProtocol         The type of header to build.  If HeaderSize is
> zero, then
> +                                this parameter is ignored.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_NOT_READY         The network interface is too busy to accept
> this transmit request.
> +  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Transmit (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN UINTN HeaderSize,
> +  IN UINTN BufferSize,
> +  IN VOID * pBuffer,
> +  IN EFI_MAC_ADDRESS * pSrcAddr,
> +  IN EFI_MAC_ADDRESS * pDestAddr,
> +  IN UINT16 * pProtocol
> +  )
> +{
> +  RX_TX_PACKET Packet;
> +  ETHERNET_HEADER * pHeader;
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  NIC_DEVICE * pNicDevice;
> +  EFI_USB_IO_PROTOCOL * pUsbIo;
> +  EFI_STATUS Status;
> +  EFI_TPL TplPrevious;
> +  UINTN TransferLength;
> +  UINT32 TransferStatus;
> +  UINT16 Type;
> +
> +  DBG_ENTER ( );
> +
> +  //
> +  // Verify the parameters
> +  //
> +  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> +    //
> +    // The interface must be running
> +    //
> +    pMode = pSimpleNetwork->Mode;
> +    if ( EfiSimpleNetworkInitialized == pMode->State ) {
> +      //
> +      //  Synchronize with Ax88772Timer
> +      //
> +      VERIFY_TPL ( TPL_AX88772 );
> +      TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
> +
> +      //
> +      // Update the link status
> +      //
> +      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> +
> +      //
> +      //No need to call receive to receive packet
> +      //
> +      //Ax88772Rx ( pNicDevice, FALSE );
> +      pMode->MediaPresent = pNicDevice->bLinkUp;
> +
> +      //
> +      //  Release the synchronization with Ax88772Timer
> +      //
> +      gBS->RestoreTPL ( TplPrevious );
> +      if ( pMode->MediaPresent ) {
> +        //
> +        //  Copy the packet into the USB buffer
> +        //
> +        CopyMem ( &Packet.Data[0], pBuffer, BufferSize );
> +        Packet.Length = (UINT16) BufferSize;
> +
> +        //
> +        //  Transmit the packet
> +        //
> +        pHeader = (ETHERNET_HEADER *) &Packet.Data[0];
> +        if ( 0 != HeaderSize ) {
> +          if ( NULL != pDestAddr ) {
> +            CopyMem ( &pHeader->dest_addr, pDestAddr,
> PXE_HWADDR_LEN_ETHER );
> +          }
> +          if ( NULL != pSrcAddr ) {
> +            CopyMem ( &pHeader->src_addr, pSrcAddr,
> PXE_HWADDR_LEN_ETHER );
> +          }
> +          else {
> +            CopyMem ( &pHeader->src_addr, &pMode->CurrentAddress.Addr[0],
> PXE_HWADDR_LEN_ETHER );
> +          }
> +          if ( NULL != pProtocol ) {
> +            Type = *pProtocol;
> +          }
> +          else {
> +            Type = Packet.Length;
> +          }
> +          Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
> +          pHeader->type = Type;
> +        }
> +        if ( Packet.Length < MIN_ETHERNET_PKT_SIZE ) {
> +          Packet.Length = MIN_ETHERNET_PKT_SIZE;
> +          ZeroMem ( &Packet.Data[ BufferSize ],
> +                    Packet.Length - BufferSize );
> +        }
> +        DEBUG (( DEBUG_TX | DEBUG_INFO,
> +                  "TX: %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-%02x-
> %02x-%02x  %02x-%02x  %d bytes\r\n",
> +                  Packet.Data[0],
> +                  Packet.Data[1],
> +                  Packet.Data[2],
> +                  Packet.Data[3],
> +                  Packet.Data[4],
> +                  Packet.Data[5],
> +                  Packet.Data[6],
> +                  Packet.Data[7],
> +                  Packet.Data[8],
> +                  Packet.Data[9],
> +                  Packet.Data[10],
> +                  Packet.Data[11],
> +                  Packet.Data[12],
> +                  Packet.Data[13],
> +                  Packet.Length ));
> +        Packet.LengthBar = ~Packet.Length;
> +        TransferLength = sizeof ( Packet.Length )
> +                       + sizeof ( Packet.LengthBar )
> +                       + Packet.Length;
> +
> +        //
> +        //  Work around USB bus driver bug where a timeout set by receive
> +        //  succeeds but the timeout expires immediately after, causing the
> +        //  transmit operation to timeout.
> +        //
> +        pUsbIo = pNicDevice->pUsbIo;
> +        Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
> +                                           BULK_OUT_ENDPOINT,
> +                                           &Packet.Length,
> +                                           &TransferLength,
> +                                           0xfffffffe,
> +                                           &TransferStatus );
> +        if ( !EFI_ERROR ( Status )) {
> +          Status = TransferStatus;
> +        }
> +        if (( !EFI_ERROR ( Status ))
> +          && ( TransferLength != (UINTN)( Packet.Length + 4 ))) {
> +          Status = EFI_WARN_WRITE_FAILURE;
> +        }
> +        if ( EFI_SUCCESS == Status ) {
> +          pNicDevice->pTxBuffer = pBuffer;
> +        }
> +        else {
> +          DEBUG (( DEBUG_ERROR | DEBUG_INFO,
> +                    "Ax88772 USB transmit error, TransferLength: %d,
> Status: %r\r\n",
> +                    sizeof ( Packet.Length ) + Packet.Length,
> +                    Status ));
> +          //
> +          //  Reset the controller to fix the error
> +          //
> +          if ( EFI_DEVICE_ERROR == Status ) {
> +            SN_Reset ( pSimpleNetwork, FALSE );
> +          }
> +        }
> +      }
> +      else {
> +        //
> +        // No packets available.
> +        //
> +        Status = EFI_NOT_READY;
> +      }
> +    }
> +    else {
> +      Status = EFI_NOT_STARTED;
> +    }
> +  }
> +  else {
> +    DEBUG (( DEBUG_ERROR | DEBUG_INFO,
> +              "Ax88772 invalid transmit parameter\r\n"
> +              "  0x%08x: HeaderSize\r\n"
> +              "  0x%08x: BufferSize\r\n"
> +              "  0x%08x: Buffer\r\n"
> +              "  0x%08x: SrcAddr\r\n"
> +              "  0x%08x: DestAddr\r\n"
> +              "  0x%04x:     Protocol\r\n",
> +              HeaderSize,
> +              BufferSize,
> +              pBuffer,
> +              pSrcAddr,
> +              pDestAddr,
> +              pProtocol ));
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Return the operation status
> +  //
> +  DBG_EXIT_STATUS ( Status );
> +  return Status;
> +}
> diff --git
> a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c
> new file mode 100644
> index 0000000000..12684a6bd1
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c
> @@ -0,0 +1,875 @@
> +/** @file
> +  Implement the interface to the AX88772 Ethernet controller.
> +
> +  This module implements the interface to the ASIX AX88772
> +  USB to Ethernet MAC with integrated 10/100 PHY.  Note that this
> implementation
> +  only supports the integrated PHY since no other test cases were available.
> +
> +  Copyright (c) 2011, Intel Corporation. All rights reserved.
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "Ax88772.h"
> +
> +
> +/**
> +  Compute the CRC
> +
> +  @param [in] pMacAddress      Address of a six byte buffer to containing the
> MAC address.
> +
> +  @returns The CRC-32 value associated with this MAC address
> +
> +**/
> +UINT32
> +Ax88772Crc (
> +  IN UINT8 * pMacAddress
> +  )
> +{
> +  UINT32 BitNumber;
> +  INT32 Carry;
> +  INT32 Crc;
> +  UINT32 Data;
> +  UINT8 * pEnd;
> +
> +  //
> +  //  Walk the MAC address
> +  //
> +  Crc = -1;
> +  pEnd = &pMacAddress[ PXE_HWADDR_LEN_ETHER ];
> +  while ( pEnd > pMacAddress ) {
> +    Data = *pMacAddress++;
> +    //
> +    //  CRC32: x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4
> + x2 + x + 1
> +    //
> +    //          1 0000 0100 1100 0001 0001 1101 1011 0111
> +    //
> +    for ( BitNumber = 0; 8 > BitNumber; BitNumber++ ) {
> +      Carry = (( Crc >> 31 ) & 1 ) ^ ( Data & 1 );
> +      Crc <<= 1;
> +      if ( 0 != Carry ) {
> +        Crc ^= 0x04c11db7;
> +      }
> +      Data >>= 1;
> +    }
> +  }
> +  //
> +  //  Return the CRC value
> +  //
> +  return (UINT32) Crc;
> +}
> +
> +
> +/**
> +  Get the MAC address
> +
> +  This routine calls ::Ax88772UsbCommand to request the MAC
> +  address from the network adapter.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [out] pMacAddress      Address of a six byte buffer to receive the
> MAC address.
> +
> +  @retval EFI_SUCCESS          The MAC address is available.
> +  @retval other                The MAC address is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88772MacAddressGet (
> +  IN NIC_DEVICE * pNicDevice,
> +  OUT UINT8 * pMacAddress
> +  )
> +{
> +  USB_DEVICE_REQUEST SetupMsg;
> +  EFI_STATUS Status;
> +
> +  //
> +  //  Set the register address.
> +  //
> +  SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
> +                       | USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_MAC_ADDRESS_READ;
> +  SetupMsg.Value = 0;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = PXE_HWADDR_LEN_ETHER;
> +
> +  //
> +  //  Read the PHY register
> +  //
> +  Status = Ax88772UsbCommand ( pNicDevice,
> +                               &SetupMsg,
> +                               pMacAddress );
> +  return Status;
> +}
> +
> +
> +/**
> +  Set the MAC address
> +
> +  This routine calls ::Ax88772UsbCommand to set the MAC address
> +  in the network adapter.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] pMacAddress      Address of a six byte buffer to containing the
> new MAC address.
> +
> +  @retval EFI_SUCCESS          The MAC address was set.
> +  @retval other                The MAC address was not set.
> +
> +**/
> +EFI_STATUS
> +Ax88772MacAddressSet (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT8 * pMacAddress
> +  )
> +{
> +  USB_DEVICE_REQUEST SetupMsg;
> +  EFI_STATUS Status;
> +
> +  //
> +  //  Set the register address.
> +  //
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_MAC_ADDRESS_WRITE;
> +  SetupMsg.Value = 0;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = PXE_HWADDR_LEN_ETHER;
> +
> +  //
> +  //  Read the PHY register
> +  //
> +  Status = Ax88772UsbCommand ( pNicDevice,
> +                               &SetupMsg,
> +                               pMacAddress );
> +  return Status;
> +}
> +
> +/**
> +  Clear the multicast hash table
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +
> +**/
> +VOID
> +Ax88772MulticastClear (
> +  IN NIC_DEVICE * pNicDevice
> +  )
> +{
> +  int i = 0;
> +  //
> +  // Clear the multicast hash table
> +  //
> +  for ( i = 0 ; i < 8 ; i ++ )
> +     pNicDevice->MulticastHash[0] = 0;
> +}
> +
> +/**
> +  Enable a multicast address in the multicast hash table
> +
> +  This routine calls ::Ax88772Crc to compute the hash bit for
> +  this MAC address.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] pMacAddress      Address of a six byte buffer to containing the
> MAC address.
> +
> +**/
> +VOID
> +Ax88772MulticastSet (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT8 * pMacAddress
> +  )
> +{
> +  UINT32 Crc;
> +
> +  //
> +  //  Compute the CRC on the destination address
> +  //
> +  Crc = Ax88772Crc ( pMacAddress ) >> 26;
> +
> +  //
> +  //  Set the bit corresponding to the destination address
> +  //
> +   pNicDevice->MulticastHash [ Crc >> 3 ] |= ( 1<< (Crc& 7));
> +}
> +
> +/**
> +  Start the link negotiation
> +
> +  This routine calls ::Ax88772PhyWrite to start the PHY's link
> +  negotiation.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +
> +  @retval EFI_SUCCESS          The link negotiation was started.
> +  @retval other                Failed to start the link negotiation.
> +
> +**/
> +EFI_STATUS
> +Ax88772NegotiateLinkStart (
> +  IN NIC_DEVICE * pNicDevice
> +  )
> +{
> +  UINT16 Control;
> +  EFI_STATUS Status;
> +  int i;
> +  //
> +  // Set the supported capabilities.
> +  //
> +  Status = Ax88772PhyWrite ( pNicDevice,
> +                             PHY_ANAR,
> +                             AN_CSMA_CD
> +                             | AN_TX_FDX | AN_TX_HDX
> +                             | AN_10_FDX | AN_10_HDX );
> +  if ( !EFI_ERROR ( Status )) {
> +    //
> +    // Set the link speed and duplex
> +    //
> +    Control = BMCR_AUTONEGOTIATION_ENABLE
> +            | BMCR_RESTART_AUTONEGOTIATION;
> +    if ( pNicDevice->b100Mbps ) {
> +      Control |= BMCR_100MBPS;
> +    }
> +    if ( pNicDevice->bFullDuplex ) {
> +      Control |= BMCR_FULL_DUPLEX;
> +    }
> +    Status = Ax88772PhyWrite ( pNicDevice, PHY_BMCR, Control );
> +  }
> +
> +  if (!EFI_ERROR(Status)) {
> +    i = 0;
> +    do {
> +
> +        if (pNicDevice->bComplete && pNicDevice->bLinkUp) {
> +            pNicDevice->SimpleNetwork.Mode->MediaPresent
> +               = pNicDevice->bLinkUp & pNicDevice->bComplete;
> +           break;
> +       }
> +       else {
> +            gBS->Stall(AUTONEG_DELAY);
> +            Status = Ax88772NegotiateLinkComplete ( pNicDevice,
> +                                            &pNicDevice->PollCount,
> +                                            &pNicDevice->bComplete,
> +                                            &pNicDevice->bLinkUp,
> +                                            &pNicDevice->b100Mbps,
> +                                            &pNicDevice->bFullDuplex );
> +            i++;
> +        }
> +    }while(!pNicDevice->bLinkUp && i < AUTONEG_POLLCNT);
> +  }
> +  return Status;
> +}
> +
> +
> +/**
> +  Complete the negotiation of the PHY link
> +
> +  This routine calls ::Ax88772PhyRead to determine if the
> +  link negotiation is complete.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in, out] pPollCount  Address of number of times this routine was
> polled
> +  @param [out] pbComplete      Address of boolean to receive complate
> status.
> +  @param [out] pbLinkUp        Address of boolean to receive link status,
> TRUE=up.
> +  @param [out] pbHiSpeed       Address of boolean to receive link speed,
> TRUE=100Mbps.
> +  @param [out] pbFullDuplex    Address of boolean to receive link duplex,
> TRUE=full.
> +
> +  @retval EFI_SUCCESS          The MAC address is available.
> +  @retval other                The MAC address is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88772NegotiateLinkComplete (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN OUT UINTN * pPollCount,
> +  OUT BOOLEAN * pbComplete,
> +  OUT BOOLEAN * pbLinkUp,
> +  OUT BOOLEAN * pbHiSpeed,
> +  OUT BOOLEAN * pbFullDuplex
> +  )
> +{
> +  UINT16 Mask;
> +  UINT16 PhyData;
> +  EFI_STATUS  Status;
> +
> +  //
> +  //  Determine if the link is up.
> +  //
> +  *pbComplete = FALSE;
> +
> +  //
> +  //  Get the link status
> +  //
> +  Status = Ax88772PhyRead ( pNicDevice,
> +                            PHY_BMSR,
> +                            &PhyData );
> +
> +  if ( !EFI_ERROR ( Status )) {
> +      *pbLinkUp = (BOOLEAN)( 0 != ( PhyData & BMSR_LINKST ));
> +      if ( 0 == *pbLinkUp ) {
> +        DEBUG (( EFI_D_INFO, "Link Down\n" ));
> +      }
> +      else {
> +         *pbComplete = (BOOLEAN)( 0 != ( PhyData & 0x20 ));
> +         if ( 0 == *pbComplete ) {
> +              DEBUG (( EFI_D_INFO, "Autoneg is not yet Complete\n" ));
> +        }
> +        else {
> +          Status = Ax88772PhyRead ( pNicDevice,
> +                                PHY_ANLPAR,
> +                                &PhyData );
> +          if ( !EFI_ERROR ( Status )) {
> +            //
> +            //  Autonegotiation is complete
> +            //  Determine the link speed.
> +            //
> +            *pbHiSpeed = (BOOLEAN)( 0 != ( PhyData & ( AN_TX_FDX |
> AN_TX_HDX )));
> +
> +            //
> +            //  Determine the link duplex.
> +            //
> +            Mask = ( *pbHiSpeed ) ? AN_TX_FDX : AN_10_FDX;
> +            *pbFullDuplex = (BOOLEAN)( 0 != ( PhyData & Mask ));
> +          }
> +        }
> +      }
> +  }
> +  else {
> +      DEBUG (( EFI_D_ERROR, "Failed to read BMCR\n" ));
> +  }
> +  return Status;
> +}
> +
> +
> +/**
> +  Read a register from the PHY
> +
> +  This routine calls ::Ax88772UsbCommand to read a PHY register.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] RegisterAddress  Number of the register to read.
> +  @param [in, out] pPhyData    Address of a buffer to receive the PHY
> register value
> +
> +  @retval EFI_SUCCESS          The PHY data is available.
> +  @retval other                The PHY data is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88772PhyRead (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT8 RegisterAddress,
> +  IN OUT UINT16 * pPhyData
> +  )
> +{
> +  USB_DEVICE_REQUEST SetupMsg;
> +  EFI_STATUS Status;
> +
> +  //
> +  //  Request access to the PHY
> +  //
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_PHY_ACCESS_SOFTWARE;
> +  SetupMsg.Value = 0;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand ( pNicDevice,
> +                               &SetupMsg,
> +                               NULL );
> +  if ( !EFI_ERROR ( Status )) {
> +    //
> +    //  Read the PHY register address.
> +    //
> +    SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
> +                         | USB_REQ_TYPE_VENDOR
> +                         | USB_TARGET_DEVICE;
> +    SetupMsg.Request = CMD_PHY_REG_READ;
> +    SetupMsg.Value = pNicDevice->PhyId;
> +    SetupMsg.Index = RegisterAddress;
> +    SetupMsg.Length = sizeof ( *pPhyData );
> +    Status = Ax88772UsbCommand ( pNicDevice,
> +                                 &SetupMsg,
> +                                 pPhyData );
> +    if ( !EFI_ERROR ( Status )) {
> +
> +      //
> +      //  Release the PHY to the hardware
> +      //
> +      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                           | USB_TARGET_DEVICE;
> +      SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
> +      SetupMsg.Value = 0;
> +      SetupMsg.Index = 0;
> +      SetupMsg.Length = 0;
> +      Status = Ax88772UsbCommand ( pNicDevice,
> +                                   &SetupMsg,
> +                                   NULL );
> +    }
> +  }
> +  return Status;
> +}
> +
> +
> +/**
> +  Write to a PHY register
> +
> +  This routine calls ::Ax88772UsbCommand to write a PHY register.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] RegisterAddress  Number of the register to read.
> +  @param [in] PhyData          Address of a buffer to receive the PHY register
> value
> +
> +  @retval EFI_SUCCESS          The PHY data was written.
> +  @retval other                Failed to wwrite the PHY register.
> +
> +**/
> +EFI_STATUS
> +Ax88772PhyWrite (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT8 RegisterAddress,
> +  IN UINT16 PhyData
> +  )
> +{
> +  USB_DEVICE_REQUEST SetupMsg;
> +  EFI_STATUS Status;
> +
> +  //
> +  //  Request access to the PHY
> +  //
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_PHY_ACCESS_SOFTWARE;
> +  SetupMsg.Value = 0;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand ( pNicDevice,
> +                               &SetupMsg,
> +                               NULL );
> +  if ( !EFI_ERROR ( Status )) {
> +    //
> +    //  Write the PHY register
> +    //
> +    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                         | USB_TARGET_DEVICE;
> +    SetupMsg.Request = CMD_PHY_REG_WRITE;
> +    SetupMsg.Value = pNicDevice->PhyId;
> +    SetupMsg.Index = RegisterAddress;
> +    SetupMsg.Length = sizeof ( PhyData );
> +    Status = Ax88772UsbCommand ( pNicDevice,
> +                                 &SetupMsg,
> +                                 &PhyData );
> +    if ( !EFI_ERROR ( Status )) {
> +
> +      //
> +      //  Release the PHY to the hardware
> +      //
> +      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                           | USB_TARGET_DEVICE;
> +      SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
> +      SetupMsg.Value = 0;
> +      SetupMsg.Index = 0;
> +      SetupMsg.Length = 0;
> +      Status = Ax88772UsbCommand ( pNicDevice,
> +                                   &SetupMsg,
> +                                   NULL );
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Reset the AX88772
> +
> +  This routine uses ::Ax88772UsbCommand to reset the network
> +  adapter.  This routine also uses ::Ax88772PhyWrite to reset
> +  the PHY.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +
> +  @retval EFI_SUCCESS          The MAC address is available.
> +  @retval other                The MAC address is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88772Reset (
> +  IN NIC_DEVICE * pNicDevice
> +  )
> +{
> +  USB_DEVICE_REQUEST SetupMsg;
> +  EFI_STATUS Status;
> +
> +  EFI_USB_IO_PROTOCOL *pUsbIo;
> +  EFI_USB_DEVICE_DESCRIPTOR Device;
> +
> +  pUsbIo = pNicDevice->pUsbIo;
> +  Status = pUsbIo->UsbGetDeviceDescriptor ( pUsbIo, &Device );
> +
> +	if (EFI_ERROR(Status)) goto err;
> +
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                           | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
> +  SetupMsg.Value = 0;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand ( pNicDevice,
> +                                &SetupMsg,
> +                                NULL );
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                          | USB_TARGET_DEVICE;
> +      SetupMsg.Request = CMD_PHY_SELECT;
> +      SetupMsg.Value = SPHY_PSEL;
> +      SetupMsg.Index = 0;
> +      SetupMsg.Length = 0;
> +      Status = Ax88772UsbCommand ( pNicDevice,
> +                                    &SetupMsg,
> +                                    NULL );
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                          | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_RESET;
> +      SetupMsg.Value = SRR_IPRL ;
> +      SetupMsg.Index = 0;
> +      SetupMsg.Length = 0;
> +      Status = Ax88772UsbCommand ( pNicDevice,
> +                                   &SetupMsg,
> +                                   NULL );
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                          | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_RESET;
> +        SetupMsg.Value = SRR_IPPD | SRR_IPRL ;
> +        SetupMsg.Index = 0;
> +        SetupMsg.Length = 0;
> +        Status = Ax88772UsbCommand ( pNicDevice,
> +                                    &SetupMsg,
> +                                    NULL );
> +
> +  gBS->Stall ( 200000 );
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                          | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_RESET;
> +  SetupMsg.Value =  SRR_IPRL  ;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand ( pNicDevice,
> +                                &SetupMsg,
> +                                NULL );
> +
> +  gBS->Stall ( 200000 );
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                          | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_RESET;
> +  SetupMsg.Value = 0;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand ( pNicDevice,
> +                                    &SetupMsg,
> +                                    NULL );
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                          | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_PHY_SELECT;
> +  SetupMsg.Value = SPHY_PSEL;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand ( pNicDevice,
> +                                    &SetupMsg,
> +                                    NULL );
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                          | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_RESET;
> +  SetupMsg.Value =  SRR_IPRL | SRR_BZ | SRR_BZTYPE;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand ( pNicDevice,
> +                                    &SetupMsg,
> +                                    NULL );
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                        | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_RX_CONTROL_WRITE;
> +  SetupMsg.Value = 0;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand ( pNicDevice,
> +                                  &SetupMsg,
> +                                  NULL );
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  if (pNicDevice->Flags != FLAG_TYPE_AX88772) {
> +        SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                        | USB_TARGET_DEVICE;
> +        SetupMsg.Request = CMD_RXQTC;
> +        SetupMsg.Value = 0x8000;
> +        SetupMsg.Index = 0x8001;
> +        SetupMsg.Length = 0;
> +        Status = Ax88772UsbCommand ( pNicDevice,
> +                                  &SetupMsg,
> +                                  NULL );
> +  }
> +
> +err:
> +  return Status;
> +}
> +
> +/**
> +  Enable or disable the receiver
> +
> +  This routine calls ::Ax88772UsbCommand to update the
> +  receiver state.  This routine also calls ::Ax88772MacAddressSet
> +  to establish the MAC address for the network adapter.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] RxFilter         Simple network RX filter mask value
> +
> +  @retval EFI_SUCCESS          The MAC address was set.
> +  @retval other                The MAC address was not set.
> +
> +**/
> +EFI_STATUS
> +Ax88772RxControl (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT32 RxFilter
> +  )
> +{
> +  UINT16 MediumStatus;
> +  UINT16 RxControl;
> +  USB_DEVICE_REQUEST SetupMsg;
> +  EFI_STATUS Status;
> +  EFI_USB_IO_PROTOCOL *pUsbIo;
> +  EFI_USB_DEVICE_DESCRIPTOR Device;
> +
> +  pUsbIo = pNicDevice->pUsbIo;
> +  Status = pUsbIo->UsbGetDeviceDescriptor ( pUsbIo, &Device );
> +
> +  if (EFI_ERROR(Status)) {
> +    DEBUG (( EFI_D_ERROR, "Failed to get device descriptor\n" ));
> +    return Status;
> +  }
> +
> +  //
> +  // Enable the receiver if something is to be received
> +  //
> +
> +  if ( 0 != RxFilter ) {
> +    //
> +    //  Enable the receiver
> +    //
> +    SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
> +                         | USB_REQ_TYPE_VENDOR
> +                         | USB_TARGET_DEVICE;
> +    SetupMsg.Request = CMD_MEDIUM_STATUS_READ;
> +    SetupMsg.Value = 0;
> +    SetupMsg.Index = 0;
> +    SetupMsg.Length = sizeof ( MediumStatus );
> +    Status = Ax88772UsbCommand ( pNicDevice,
> +                                 &SetupMsg,
> +                                 &MediumStatus );
> +    if ( !EFI_ERROR ( Status )) {
> +      if ( 0 == ( MediumStatus & MS_RE )) {
> +        MediumStatus |= MS_RE | MS_ONE;
> +
> +        if ( pNicDevice->bFullDuplex )
> +          MediumStatus |= MS_TFC | MS_RFC | MS_FD;
> +        else
> +          MediumStatus &= ~(MS_TFC | MS_RFC | MS_FD);
> +
> +        if ( pNicDevice->b100Mbps )
> +          MediumStatus |= MS_PS;
> +        else
> +          MediumStatus &= ~MS_PS;
> +
> +        SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                             | USB_TARGET_DEVICE;
> +        SetupMsg.Request = CMD_MEDIUM_STATUS_WRITE;
> +        SetupMsg.Value = MediumStatus;
> +        SetupMsg.Index = 0;
> +        SetupMsg.Length = 0;
> +        Status = Ax88772UsbCommand ( pNicDevice,
> +                                     &SetupMsg,
> +                                     NULL );
> +        if ( EFI_ERROR ( Status )) {
> +            DEBUG (( EFI_D_ERROR, "Failed to enable receiver, Status: %r\r\n",
> +              Status ));
> +        }
> +      }
> +    }
> +    else {
> +        DEBUG (( EFI_D_ERROR, "Failed to read receiver status, Status: %r\r\n",
> +              Status ));
> +    }
> +  }
> +
> +  RxControl = RXC_SO | RXC_RH1M;
> +  //
> +  //  Enable multicast if requested
> +  //
> +  if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST )) {
> +      RxControl |= RXC_AM;
> +      //
> +      //  Update the multicast hash table
> +      //
> +      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                           | USB_TARGET_DEVICE;
> +      SetupMsg.Request = CMD_MULTICAST_HASH_WRITE;
> +      SetupMsg.Value = 0;
> +      SetupMsg.Index = 0;
> +      SetupMsg.Length = sizeof ( pNicDevice ->MulticastHash );
> +      Status = Ax88772UsbCommand ( pNicDevice,
> +                                   &SetupMsg,
> +                                   &pNicDevice->MulticastHash );
> +  }
> +  //
> +  //  Enable all multicast if requested
> +  //
> +  if ( 0 != ( RxFilter &
> EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST )) {
> +      RxControl |= RXC_AMALL;
> +  }
> +
> +  //
> +  //  Enable broadcast if requested
> +  //
> +  if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST )) {
> +      RxControl |= RXC_AB;
> +  }
> +
> +  //
> +  //  Enable promiscuous mode if requested
> +  //
> +  if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS )) {
> +      RxControl |= RXC_PRO;
> +  }
> +
> +  //
> +  //  Update the receiver control
> +  //
> +  if (pNicDevice->CurRxControl != RxControl) {
> +    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                         | USB_TARGET_DEVICE;
> +    SetupMsg.Request = CMD_RX_CONTROL_WRITE;
> +    SetupMsg.Value = RxControl;
> +    SetupMsg.Index = 0;
> +    SetupMsg.Length = 0;
> +    Status = Ax88772UsbCommand ( pNicDevice,
> +                                 &SetupMsg,
> +                                 NULL );
> +    if ( !EFI_ERROR ( Status )) {
> +      pNicDevice->CurRxControl = RxControl;
> +
> +    }
> +    else {
> +        DEBUG (( EFI_D_ERROR, "ERROR - Failed to set receiver control,
> Status: %r\r\n",
> +            Status ));
> +    }
> +  }
> +  return Status;
> +}
> +
> +
> +/**
> +  Read an SROM location
> +
> +  This routine calls ::Ax88772UsbCommand to read data from the
> +  SROM.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] Address          SROM address
> +  @param [out] pData           Buffer to receive the data
> +
> +  @retval EFI_SUCCESS          The read was successful
> +  @retval other                The read failed
> +
> +**/
> +EFI_STATUS
> +Ax88772SromRead (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT32 Address,
> +  OUT UINT16 * pData
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +/**
> +  Send a command to the USB device.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] pRequest         Pointer to the request structure
> +  @param [in, out] pBuffer     Data buffer address
> +
> +  @retval EFI_SUCCESS          The USB transfer was successful
> +  @retval other                The USB transfer failed
> +
> +**/
> +EFI_STATUS
> +Ax88772UsbCommand (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN USB_DEVICE_REQUEST * pRequest,
> +  IN OUT VOID * pBuffer
> +  )
> +{
> +  UINT32 CmdStatus;
> +  EFI_USB_DATA_DIRECTION Direction;
> +  EFI_USB_IO_PROTOCOL * pUsbIo;
> +  EFI_STATUS Status;
> +
> +  //
> +  // Determine the transfer direction
> +  //
> +  Direction = EfiUsbNoData;
> +  if ( 0 != pRequest->Length ) {
> +    Direction = ( 0 != ( pRequest->RequestType & USB_ENDPOINT_DIR_IN ))
> +              ? EfiUsbDataIn : EfiUsbDataOut;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  pUsbIo = pNicDevice->pUsbIo;
> +  Status = pUsbIo->UsbControlTransfer ( pUsbIo,
> +                                        pRequest,
> +                                        Direction,
> +                                        USB_BUS_TIMEOUT,
> +                                        pBuffer,
> +                                        pRequest->Length,
> +                                        &CmdStatus );
> +  //
> +  // Determine the operation status
> +  //
> +  if ( !EFI_ERROR ( Status )) {
> +    Status = CmdStatus;
> +  }
> +  else {
> +    //
> +    // Only use status values associated with the Simple Network protocol
> +    //
> +    if ( EFI_TIMEOUT == Status ) {
> +      Status = EFI_DEVICE_ERROR;
> +    }
> +  }
> +  return Status;
> +}
> +
> diff --git
> a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h
> new file mode 100644
> index 0000000000..365929489b
> --- /dev/null
> +++
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h
> @@ -0,0 +1,1026 @@
> +/** @file
> +  Definitions for ASIX AX88772 Ethernet adapter.
> +
> +  Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _AX88772_H_
> +#define _AX88772_H_
> +
> +#include <Uefi.h>
> +
> +#include <Guid/EventGroup.h>
> +
> +#include <IndustryStandard/Pci.h>
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeLib.h>
> +
> +#include <Protocol/DevicePath.h>
> +#include <Protocol/LoadedImage.h>
> +#include <Protocol/NetworkInterfaceIdentifier.h>
> +#include <Protocol/SimpleNetwork.h>
> +#include <Protocol/UsbIo.h>
> +
> +#define MAX_QUEUE_SIZE 50
> +#define MAX_BULKIN_SIZE 16384
> +#define HW_HDR_LENGTH 8
> +
> +
> +#define MAX_LINKIDLE_THRESHOLD  20000
> +
> +
> +
> +//------------------------------------------------------------------------------
> +//  Macros
> +//------------------------------------------------------------------------------
> +
> +#if defined(_MSC_VER)           /* Handle Microsoft VC++ compiler specifics.
> */
> +#define DBG_ENTER()             DEBUG (( 0xffffffff, "Entering " __FUNCTION__
> "\n" )) ///<  Display routine entry
> +#define DBG_EXIT()              DEBUG (( 0xffffffff, "Exiting " __FUNCTION__
> "\n" ))  ///<  Display routine exit
> +#define DBG_EXIT_DEC(Status)    DEBUG (( 0xffffffff, "Exiting "
> __FUNCTION__ ", Status: %d\n", Status ))      ///<  Display routine exit with
> decimal value
> +#define DBG_EXIT_HEX(Status)    DEBUG (( 0xffffffff, "Exiting "
> __FUNCTION__ ", Status: 0x%08x\n", Status ))  ///<  Display routine exit with
> hex value
> +#define DBG_EXIT_STATUS(Status) DEBUG (( 0xffffffff, "Exiting "
> __FUNCTION__ ", Status: %r\n", Status ))      ///<  Display routine exit with
> status value
> +#define DBG_EXIT_TF(Status)     DEBUG (( 0xffffffff, "Exiting "
> __FUNCTION__ ", returning %s\n", (FALSE == Status) ? L"FALSE" : L"TRUE" ))
> ///<  Display routine with TRUE/FALSE value
> +#else   //  _MSC_VER
> +#define DBG_ENTER()               ///<  Display routine entry
> +#define DBG_EXIT()                ///<  Display routine exit
> +#define DBG_EXIT_DEC(Status)      ///<  Display routine exit with decimal
> value
> +#define DBG_EXIT_HEX(Status)      ///<  Display routine exit with hex value
> +#define DBG_EXIT_STATUS(Status)   ///<  Display routine exit with status
> value
> +#define DBG_EXIT_TF(Status)       ///<  Display routine with TRUE/FALSE
> value
> +#endif  //  _MSC_VER
> +
> +#define USB_IS_IN_ENDPOINT(EndPointAddr)      (((EndPointAddr) &
> BIT7) != 0)  ///<  Return TRUE/FALSE for IN direction
> +#define USB_IS_OUT_ENDPOINT(EndPointAddr)     (((EndPointAddr) & BIT7)
> == 0)  ///<  Return TRUE/FALSE for OUT direction
> +#define USB_IS_BULK_ENDPOINT(Attribute)       (((Attribute) & (BIT0 | BIT1))
> == USB_ENDPOINT_BULK)      ///<  Return TRUE/FALSE for BULK type
> +#define USB_IS_INTERRUPT_ENDPOINT(Attribute)  (((Attribute) & (BIT0 |
> BIT1)) == USB_ENDPOINT_INTERRUPT) ///<  Return TRUE/FALSE for
> INTERRUPT type
> +
> +
> +#define PRINT(_L_STR) (gST->ConOut->OutputString(gST-
> >ConOut,(_L_STR)))
> +//------------------------------------------------------------------------------
> +//  Constants
> +//------------------------------------------------------------------------------
> +
> +#define DEBUG_RX_BROADCAST  0x40000000  ///<  Display RX broadcast
> messages
> +#define DEBUG_RX_MULTICAST  0x20000000  ///<  Display RX multicast
> messages
> +#define DEBUG_RX_UNICAST    0x10000000  ///<  Display RX unicast
> messages
> +#define DEBUG_MAC_ADDRESS   0x08000000  ///<  Display the MAC
> address
> +#define DEBUG_LINK          0x04000000  ///<  Display the link status
> +#define DEBUG_TX            0x02000000  ///<  Display the TX messages
> +#define DEBUG_PHY           0x01000000  ///<  Display the PHY register values
> +#define DEBUG_SROM          0x00800000  ///<  Display the SROM contents
> +#define DEBUG_TIMER         0x00400000  ///<  Display the timer routine
> entry/exit
> +#define DEBUG_TPL           0x00200000  ///<  Display the timer routine
> entry/exit
> +
> +#define AX88772_MAX_PKT_SIZE  2048  ///< Maximum packet size
> +
> +#define ETHERNET_HEADER_SIZE  sizeof ( ETHERNET_HEADER )  ///<  Size in
> bytes of the Ethernet header
> +#define MIN_ETHERNET_PKT_SIZE 60    ///<  Minimum packet size including
> Ethernet header
> +#define MAX_ETHERNET_PKT_SIZE 1500  ///<  Ethernet spec 3.1.1:
> Minimum packet size
> +
> +#define USB_NETWORK_CLASS   0x09    ///<  USB Network class code
> +#define USB_BUS_TIMEOUT     1000    ///<  USB timeout in milliseconds
> +
> +#define TIMER_MSEC          20              ///<  Polling interval for the NIC
> +//#define TPL_AX88772         TPL_CALLBACK    ///<  TPL for routine
> synchronization
> +
> +#define HC_DEBUG  0
> +#define BULKIN_TIMEOUT  20
> +#define AUTONEG_DELAY   500000
> +#define AUTONEG_POLLCNT 20
> +
> +/**
> +  Verify new TPL value
> +
> +  This macro which is enabled when debug is enabled verifies that
> +  the new TPL value is >= the current TPL value.
> +**/
> +#ifdef VERIFY_TPL
> +#undef VERIFY_TPL
> +#endif  //  VERIFY_TPL
> +
> +#if !defined(MDEPKG_NDEBUG)
> +
> +#define VERIFY_TPL(tpl)                           \
> +{                                                 \
> +  EFI_TPL PreviousTpl;                            \
> +                                                  \
> +  PreviousTpl = gBS->RaiseTPL ( TPL_HIGH_LEVEL ); \
> +  gBS->RestoreTPL ( PreviousTpl );                \
> +  if ( PreviousTpl > tpl ) {                      \
> +    DEBUG (( DEBUG_ERROR, "Current TPL: %d, New TPL: %d\r\n",
> PreviousTpl, tpl ));  \
> +    ASSERT ( PreviousTpl <= tpl );                \
> +  }                                               \
> +}
> +
> +#else   //  MDEPKG_NDEBUG
> +
> +#define VERIFY_TPL(tpl)
> +
> +#endif  //  MDEPKG_NDEBUG
> +
> +//------------------------------------------------------------------------------
> +//  Hardware Definition
> +//------------------------------------------------------------------------------
> +
> +#define FreeQueueSize     10
> +
> +#define DEV_SIGNATURE     SIGNATURE_32 ('A','X','8','8')  ///<  Signature of
> data structures in memory
> +
> +#define RESET_MSEC        1000    ///<  Reset duration
> +#define PHY_RESET_MSEC     500    ///<  PHY reset duration
> +
> +//
> +//  RX Control register
> +//
> +
> +#define RXC_PRO           0x0001  ///<  Receive all packets
> +#define RXC_AMALL         0x0002  ///<  Receive all multicast packets
> +#define RXC_SEP           0x0004  ///<  Save error packets
> +#define RXC_AB            0x0008  ///<  Receive broadcast packets
> +#define RXC_AM            0x0010  ///<  Use multicast destination address hash
> table
> +#define RXC_AP            0x0020  ///<  Accept physical address from Multicast
> Filter
> +#define RXC_SO            0x0080  ///<  Start operation
> +#define RXC_MFB           0x0300  ///<  Maximum frame burst
> +#define RXC_MFB_2048      0       ///<  Maximum frame size:  2048 bytes
> +#define RXC_MFB_4096      0x0100  ///<  Maximum frame size:  4096 bytes
> +#define RXC_MFB_8192      0x0200  ///<  Maximum frame size:  8192 bytes
> +#define RXC_MFB_16384     0x0300  ///<  Maximum frame size: 16384 bytes
> +
> +/*Freddy*/
> +#define RXC_RH1M          0x0100  ///<  Rx header 1
> +#define RXC_RH2M          0x0200  ///<  Rx header 2
> +#define RXC_RH3M          0x0400  ///<  Rx header 3
> +/*Freddy*/
> +
> +//
> +//  Medium Status register
> +//
> +
> +#define MS_FD             0x0002  ///<  Full duplex
> +#define MS_ONE            0x0004  ///<  Must be one
> +#define MS_RFC            0x0010  ///<  RX flow control enable
> +#define MS_TFC            0x0020  ///<  TX flow control enable
> +#define MS_PF             0x0080  ///<  Pause frame enable
> +#define MS_RE             0x0100  ///<  Receive enable
> +#define MS_PS             0x0200  ///<  Port speed 1=100, 0=10 Mbps
> +#define MS_SBP            0x0800  ///<  Stop back pressure
> +#define MS_SM             0x1000  ///<  Super MAC support
> +
> +//
> +//  Software PHY Select register
> +//
> +
> +#define SPHY_PSEL         (1 << 0)    ///<  Select internal PHY
> +#define SPHY_SSMII        (1 << 2)
> +#define SPHY_SSEN         (1 << 4)
> +#define SPHY_ASEL         0x02    ///<  1=Auto select, 0=Manual select
> +
> +//
> +//  Software Reset register
> +//
> +
> +#define SRR_RR            0x01    ///<  Clear receive frame length error
> +#define SRR_RT            0x02    ///<  Clear transmit frame length error
> +#define SRR_BZTYPE        0x04    ///<  External PHY reset pin tri-state enable
> +#define SRR_PRL           0x08    ///<  External PHY reset pin level
> +#define SRR_BZ            0x10    ///<  Force Bulk to return zero length packet
> +#define SRR_IPRL          0x20    ///<  Internal PHY reset control
> +#define SRR_IPPD          0x40    ///<  Internal PHY power down
> +
> +//
> +//  PHY ID values
> +//
> +
> +#define PHY_ID_INTERNAL   0x0010  ///<  Internal PHY
> +
> +//
> +//  USB Commands
> +//
> +
> +#define CMD_PHY_ACCESS_SOFTWARE   0x06  ///<  Software in control of
> PHY
> +#define CMD_PHY_REG_READ          0x07  ///<  Read PHY register, Value:
> PHY, Index: Register, Data: Register value
> +#define CMD_PHY_REG_WRITE         0x08  ///<  Write PHY register, Value:
> PHY, Index: Register, Data: New 16-bit value
> +#define CMD_PHY_ACCESS_HARDWARE   0x0a  ///<  Hardware in control of
> PHY
> +#define CMD_SROM_READ             0x0b  ///<  Read SROM register: Value:
> Address, Data: Value
> +#define CMD_RX_CONTROL_WRITE      0x10  ///<  Set the RX control
> register, Value: New value
> +#define CMD_GAPS_WRITE            0x12  ///<  Write the gaps register, Value:
> New value
> +#define CMD_MAC_ADDRESS_READ      0x13  ///<  Read the MAC address,
> Data: 6 byte MAC address
> +#define CMD_MAC_ADDRESS_WRITE     0x14  ///<  Set the MAC address,
> Data: New 6 byte MAC address
> +#define CMD_MULTICAST_HASH_WRITE  0x16  ///<  Write the multicast
> hash table, Data: New 8 byte value
> +#define CMD_MULTICAST_HASH_READ  0x16  ///<  Read the multicast hash
> table
> +#define CMD_MEDIUM_STATUS_READ    0x1a  ///<  Read medium status
> register, Data: Register value
> +#define CMD_MEDIUM_STATUS_WRITE   0x1b  ///<  Write medium status
> register, Value: New value
> +#define CMD_WRITE_GPIOS           0x1f
> +#define CMD_RESET                 0x20  ///<  Reset register, Value: New value
> +#define CMD_PHY_SELECT            0x22  ///<  PHY select register, Value: New
> value
> +
> +/*Freddy*/
> +#define CMD_RXQTC                 0x2a  ///<  RX Queue Cascade Threshold
> Control Register
> +/*Freddy*/
> +
> +//------------------------------
> +//  USB Endpoints
> +//------------------------------
> +
> +#define CONTROL_ENDPOINT                0       ///<  Control endpoint
> +#define INTERRUPT_ENDPOINT              1       ///<  Interrupt endpoint
> +#define BULK_IN_ENDPOINT                2       ///<  Receive endpoint
> +#define BULK_OUT_ENDPOINT               3       ///<  Transmit endpoint
> +
> +//------------------------------
> +//  PHY Registers
> +//------------------------------
> +
> +#define PHY_BMCR                        0       ///<  Control register
> +#define PHY_BMSR                        1       ///<  Status register
> +#define PHY_ANAR                        4       ///<  Autonegotiation advertisement
> register
> +#define PHY_ANLPAR                      5       ///<  Autonegotiation link parter
> ability register
> +#define PHY_ANER                        6       ///<  Autonegotiation expansion
> register
> +
> +//  BMCR - Register 0
> +
> +#define BMCR_RESET                      0x8000  ///<  1 = Reset the PHY, bit clears
> after reset
> +#define BMCR_LOOPBACK                   0x4000  ///<  1 = Loopback enabled
> +#define BMCR_100MBPS                    0x2000  ///<  100 Mbits/Sec
> +#define BMCR_10MBPS                     0       ///<  10 Mbits/Sec
> +#define BMCR_AUTONEGOTIATION_ENABLE     0x1000  ///<  1 = Enable
> autonegotiation
> +#define BMCR_POWER_DOWN                 0x0800  ///<  1 = Power down
> +#define BMCR_ISOLATE                    0x0400  ///<  0 = Isolate PHY
> +#define BMCR_RESTART_AUTONEGOTIATION    0x0200  ///<  1 = Restart
> autonegotiation
> +#define BMCR_FULL_DUPLEX                0x0100  ///<  Full duplex operation
> +#define BMCR_HALF_DUPLEX                0       ///<  Half duplex operation
> +#define BMCR_COLLISION_TEST             0x0080  ///<  1 = Collision test
> enabled
> +
> +//  BSMR - Register 1
> +
> +#define BMSR_100BASET4                  0x8000  ///<  1 = 100BASE-T4 mode
> +#define BMSR_100BASETX_FDX              0x4000  ///<  1 = 100BASE-TX full
> duplex
> +#define BMSR_100BASETX_HDX              0x2000  ///<  1 = 100BASE-TX half
> duplex
> +#define BMSR_10BASET_FDX                0x1000  ///<  1 = 10BASE-T full duplex
> +#define BMSR_10BASET_HDX                0x0800  ///<  1 = 10BASE-T half
> duplex
> +#define BMSR_MF                         0x0040  ///<  1 = PHY accepts frames with
> preamble suppressed
> +#define BMSR_AUTONEG_CMPLT              0x0020  ///<  1 = Autonegotiation
> complete
> +#define BMSR_RF                         0x0010  ///<  1 = Remote fault
> +#define BMSR_AUTONEG                    0x0008  ///<  1 = Able to perform
> autonegotiation
> +#define BMSR_LINKST                     0x0004  ///<  1 = Link up
> +#define BMSR_JABBER_DETECT              0x0002  ///<  1 = jabber condition
> detected
> +#define BMSR_EXTENDED_CAPABILITY        0x0001  ///<  1 = Extended
> register capable
> +
> +//  ANAR and ANLPAR Registers 4, 5
> +
> +#define AN_NP                           0x8000  ///<  1 = Next page available
> +#define AN_ACK                          0x4000  ///<  1 = Link partner acknowledged
> +#define AN_RF                           0x2000  ///<  1 = Remote fault indicated by
> link partner
> +#define AN_FCS                          0x0400  ///<  1 = Flow control ability
> +#define AN_T4                           0x0200  ///<  1 = 100BASE-T4 support
> +#define AN_TX_FDX                       0x0100  ///<  1 = 100BASE-TX Full duplex
> +#define AN_TX_HDX                       0x0080  ///<  1 = 100BASE-TX support
> +#define AN_10_FDX                       0x0040  ///<  1 = 10BASE-T Full duplex
> +#define AN_10_HDX                       0x0020  ///<  1 = 10BASE-T support
> +#define AN_CSMA_CD                      0x0001  ///<  1 = IEEE 802.3 CSMA/CD
> support
> +
> +// asix_flags defines
> +#define FLAG_NONE               0
> +#define FLAG_TYPE_AX88172       BIT0
> +#define FLAG_TYPE_AX88772       BIT1
> +#define FLAG_TYPE_AX88772B      BIT2
> +#define FLAG_EEPROM_MAC         BIT3  // initial mac address in eeprom
> +
> +//------------------------------------------------------------------------------
> +//  Data Types
> +//------------------------------------------------------------------------------
> +
> +typedef struct {
> +   UINT16  VendorId;
> +   UINT16  ProductId;
> +   INT32   Flags;
> +}ASIX_DONGLE;
> +
> +/**
> +  Ethernet header layout
> +
> +  IEEE 802.3-2002 Part 3 specification, section 3.1.1.
> +**/
> +#pragma pack(1)
> +typedef struct {
> +  UINT8 dest_addr[PXE_HWADDR_LEN_ETHER];  ///<  Destination LAN
> address
> +  UINT8 src_addr[PXE_HWADDR_LEN_ETHER];   ///<  Source LAN address
> +  UINT16 type;                            ///<  Protocol or length
> +} ETHERNET_HEADER;
> +#pragma pack()
> +
> +/**
> +  Receive and Transmit packet structure
> +**/
> +#pragma pack(1)
> +typedef struct _RX_TX_PACKET {
> +  struct _RX_TX_PACKET * pNext;       ///<  Next receive packet
> +  UINT16 Length;                      ///<  Packet length
> +  UINT16 LengthBar;                   ///<  Complement of the length
> +  UINT8 Data[ AX88772_MAX_PKT_SIZE ]; ///<  Received packet data
> +} RX_TX_PACKET;
> +#pragma pack()
> +
> +
> +#pragma pack(1)
> +typedef struct _RX_PKT {
> +  struct _RX_PKT *pNext;
> +  BOOLEAN f_Used;
> +  UINT16 Length;
> +  UINT8 Data [AX88772_MAX_PKT_SIZE] ;
> +} RX_PKT;
> +#pragma pack()
> +
> +/**
> +  AX88772 control structure
> +
> +  The driver uses this structure to manage the Asix AX88772 10/100
> +  Ethernet controller.
> +**/
> +typedef struct {
> +  UINTN Signature;          ///<  Structure identification
> +
> +  //
> +  //  USB data
> +  //
> +  EFI_HANDLE Controller;        ///<  Controller handle
> +  EFI_USB_IO_PROTOCOL * pUsbIo;  ///<  USB driver interface
> +
> +  //
> +  //  Simple network protocol data
> +  //
> +  EFI_SIMPLE_NETWORK_PROTOCOL SimpleNetwork;  ///<  Driver's network
> stack interface
> +  EFI_SIMPLE_NETWORK_PROTOCOL SimpleNetwork_Backup;
> +  EFI_SIMPLE_NETWORK_MODE SimpleNetworkData;  ///<  Data for simple
> network
> +
> +  //
> +  // Ethernet controller data
> +  //
> +  BOOLEAN bInitialized;     ///<  Controller initialized
> +  VOID * pTxBuffer;         ///<  Last transmit buffer
> +  UINT16 PhyId;             ///<  PHY ID
> +
> +  //
> +  //  Link state
> +  //
> +  BOOLEAN b100Mbps;         ///<  Current link speed, FALSE = 10 Mbps
> +  BOOLEAN bComplete;        ///<  Current state of auto-negotiation
> +  BOOLEAN bFullDuplex;      ///<  Current duplex
> +  BOOLEAN bLinkUp;          ///<  Current link state
> +  UINTN  LinkIdleCnt;
> +  UINTN PollCount;          ///<  Number of times the autonegotiation status
> was polled
> +  UINT16 CurRxControl;
> +  //
> +  //  Receive buffer list
> +  //
> +  RX_TX_PACKET * pRxTest;
> +  RX_TX_PACKET * pTxTest;
> +
> +  INT8 MulticastHash[8];
> +  EFI_MAC_ADDRESS MAC;
> +  BOOLEAN bHavePkt;
> +
> +  EFI_DEVICE_PATH_PROTOCOL                  *MyDevPath;
> +
> +  EFI_DRIVER_BINDING_PROTOCOL * DrvBind;
> +
> +  RX_PKT * QueueHead;
> +  RX_PKT * pNextFill;
> +  RX_PKT * pFirstFill;
> +  UINTN   PktCntInQueue;
> +  UINT8 * pBulkInBuff;
> +
> +  INT32 Flags;
> +
> +} NIC_DEVICE;
> +
> +#define DEV_FROM_SIMPLE_NETWORK(a)  CR (a, NIC_DEVICE,
> SimpleNetwork, DEV_SIGNATURE)  ///< Locate NIC_DEVICE from Simple
> Network Protocol
> +
> +//------------------------------------------------------------------------------
> +// Simple Network Protocol
> +//------------------------------------------------------------------------------
> +
> +/**
> +  Reset the network adapter.
> +
> +  Resets a network adapter and reinitializes it with the parameters that
> +  were provided in the previous call to Initialize ().  The transmit and
> +  receive queues are cleared.  Receive filters, the station address, the
> +  statistics, and the multicast-IP-to-HW MAC addresses are not reset by
> +  this call.
> +
> +  This routine calls ::Ax88772Reset to perform the adapter specific
> +  reset operation.  This routine also starts the link negotiation
> +  by calling ::Ax88772NegotiateLinkStart.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] bExtendedVerification  Indicates that the driver may perform
> a more
> +                                exhaustive verification operation of the device
> +                                during reset.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Reset (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN BOOLEAN bExtendedVerification
> +  );
> +
> +/**
> +  Initialize the simple network protocol.
> +
> +  This routine calls ::Ax88772MacAddressGet to obtain the
> +  MAC address.
> +
> +  @param [in] pNicDevice       NIC_DEVICE_INSTANCE pointer
> +
> +  @retval EFI_SUCCESS     Setup was successful
> +
> +**/
> +EFI_STATUS
> +SN_Setup (
> +  IN NIC_DEVICE * pNicDevice
> +  );
> +
> +/**
> +  This routine starts the network interface.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_ALREADY_STARTED   The network interface was already
> started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Start (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> +  );
> +
> +/**
> +  Set the MAC address.
> +
> +  This function modifies or resets the current station address of a
> +  network interface.  If Reset is TRUE, then the current station address
> +  is set ot the network interface's permanent address.  If Reset if FALSE
> +  then the current station address is changed to the address specified by
> +  pNew.
> +
> +  This routine calls ::Ax88772MacAddressSet to update the MAC address
> +  in the network adapter.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] bReset            Flag used to reset the station address to the
> +                                network interface's permanent address.
> +  @param [in] pNew              New station address to be used for the network
> +                                interface.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_StationAddress (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN BOOLEAN bReset,
> +  IN EFI_MAC_ADDRESS * pNew
> +  );
> +
> +/**
> +  This function resets or collects the statistics on a network interface.
> +  If the size of the statistics table specified by StatisticsSize is not
> +  big enough for all of the statistics that are collected by the network
> +  interface, then a partial buffer of statistics is returned in
> +  StatisticsTable.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] bReset            Set to TRUE to reset the statistics for the
> network interface.
> +  @param [in, out] pStatisticsSize  On input the size, in bytes, of
> StatisticsTable.  On output
> +                                the size, in bytes, of the resulting table of statistics.
> +  @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS
> structure that
> +                                conains the statistics.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_BUFFER_TOO_SMALL  The pStatisticsTable is NULL or the
> buffer is too small.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Statistics (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN BOOLEAN bReset,
> +  IN OUT UINTN * pStatisticsSize,
> +  OUT EFI_NETWORK_STATISTICS * pStatisticsTable
> +  );
> +
> +/**
> +  This function stops a network interface.  This call is only valid
> +  if the network interface is in the started state.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Stop (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> +  );
> +
> +/**
> +  This function releases the memory buffers assigned in the Initialize() call.
> +  Pending transmits and receives are lost, and interrupts are cleared and
> disabled.
> +  After this call, only Initialize() and Stop() calls may be used.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Shutdown (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> +  );
> +
> +/**
> +  Send a packet over the network.
> +
> +  This function places the packet specified by Header and Buffer on
> +  the transmit queue.  This function performs a non-blocking transmit
> +  operation.  When the transmit is complete, the buffer is returned
> +  via the GetStatus() call.
> +
> +  This routine calls ::Ax88772Rx to empty the network adapter of
> +  receive packets.  The routine then passes the transmit packet
> +  to the network adapter.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] HeaderSize        The size, in bytes, of the media header to be
> filled in by
> +                                the Transmit() function.  If HeaderSize is non-zero, then
> +                                it must be equal to SimpleNetwork->Mode-
> >MediaHeaderSize
> +                                and DestAddr and Protocol parameters must not be NULL.
> +  @param [in] BufferSize        The size, in bytes, of the entire packet (media
> header and
> +                                data) to be transmitted through the network interface.
> +  @param [in] pBuffer           A pointer to the packet (media header followed
> by data) to
> +                                to be transmitted.  This parameter can not be NULL.  If
> +                                HeaderSize is zero, then the media header is Buffer must
> +                                already be filled in by the caller.  If HeaderSize is nonzero,
> +                                then the media header will be filled in by the Transmit()
> +                                function.
> +  @param [in] pSrcAddr          The source HW MAC address.  If HeaderSize is
> zero, then
> +                                this parameter is ignored.  If HeaderSize is nonzero and
> +                                SrcAddr is NULL, then SimpleNetwork->Mode-
> >CurrentAddress
> +                                is used for the source HW MAC address.
> +  @param [in] pDestAddr         The destination HW MAC address.  If
> HeaderSize is zero, then
> +                                this parameter is ignored.
> +  @param [in] pProtocol         The type of header to build.  If HeaderSize is
> zero, then
> +                                this parameter is ignored.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_NOT_READY         The network interface is too busy to accept
> this transmit request.
> +  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Transmit (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN UINTN HeaderSize,
> +  IN UINTN BufferSize,
> +  IN VOID * pBuffer,
> +  IN EFI_MAC_ADDRESS * pSrcAddr,
> +  IN EFI_MAC_ADDRESS * pDestAddr,
> +  IN UINT16 * pProtocol
> +  );
> +
> +//------------------------------------------------------------------------------
> +// Support Routines
> +//------------------------------------------------------------------------------
> +
> +/**
> +  Get the MAC address
> +
> +  This routine calls ::Ax88772UsbCommand to request the MAC
> +  address from the network adapter.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [out] pMacAddress      Address of a six byte buffer to receive the
> MAC address.
> +
> +  @retval EFI_SUCCESS          The MAC address is available.
> +  @retval other                The MAC address is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88772MacAddressGet (
> +  IN NIC_DEVICE * pNicDevice,
> +  OUT UINT8 * pMacAddress
> +  );
> +
> +/**
> +  Set the MAC address
> +
> +  This routine calls ::Ax88772UsbCommand to set the MAC address
> +  in the network adapter.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] pMacAddress      Address of a six byte buffer to containing the
> new MAC address.
> +
> +  @retval EFI_SUCCESS          The MAC address was set.
> +  @retval other                The MAC address was not set.
> +
> +**/
> +EFI_STATUS
> +Ax88772MacAddressSet (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT8 * pMacAddress
> +  );
> +
> +/**
> +  Clear the multicast hash table
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +
> +**/
> +VOID
> +Ax88772MulticastClear (
> +  IN NIC_DEVICE * pNicDevice
> +  );
> +
> +/**
> +  Enable a multicast address in the multicast hash table
> +
> +  This routine calls ::Ax88772Crc to compute the hash bit for
> +  this MAC address.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] pMacAddress      Address of a six byte buffer to containing the
> MAC address.
> +
> +**/
> +VOID
> +Ax88772MulticastSet (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT8 * pMacAddress
> +  );
> +
> +/**
> +  Start the link negotiation
> +
> +  This routine calls ::Ax88772PhyWrite to start the PHY's link
> +  negotiation.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +
> +  @retval EFI_SUCCESS          The link negotiation was started.
> +  @retval other                Failed to start the link negotiation.
> +
> +**/
> +EFI_STATUS
> +Ax88772NegotiateLinkStart (
> +  IN NIC_DEVICE * pNicDevice
> +  );
> +
> +/**
> +  Complete the negotiation of the PHY link
> +
> +  This routine calls ::Ax88772PhyRead to determine if the
> +  link negotiation is complete.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in, out] pPollCount  Address of number of times this routine was
> polled
> +  @param [out] pbComplete      Address of boolean to receive complate
> status.
> +  @param [out] pbLinkUp        Address of boolean to receive link status,
> TRUE=up.
> +  @param [out] pbHiSpeed       Address of boolean to receive link speed,
> TRUE=100Mbps.
> +  @param [out] pbFullDuplex    Address of boolean to receive link duplex,
> TRUE=full.
> +
> +  @retval EFI_SUCCESS          The MAC address is available.
> +  @retval other                The MAC address is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88772NegotiateLinkComplete (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN OUT UINTN * pPollCount,
> +  OUT BOOLEAN * pbComplete,
> +  OUT BOOLEAN * pbLinkUp,
> +  OUT BOOLEAN * pbHiSpeed,
> +  OUT BOOLEAN * pbFullDuplex
> +  );
> +
> +/**
> +  Read a register from the PHY
> +
> +  This routine calls ::Ax88772UsbCommand to read a PHY register.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] RegisterAddress  Number of the register to read.
> +  @param [in, out] pPhyData    Address of a buffer to receive the PHY
> register value
> +
> +  @retval EFI_SUCCESS          The PHY data is available.
> +  @retval other                The PHY data is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88772PhyRead (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT8 RegisterAddress,
> +  IN OUT UINT16 * pPhyData
> +  );
> +
> +/**
> +  Write to a PHY register
> +
> +  This routine calls ::Ax88772UsbCommand to write a PHY register.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] RegisterAddress  Number of the register to read.
> +  @param [in] PhyData          Address of a buffer to receive the PHY register
> value
> +
> +  @retval EFI_SUCCESS          The PHY data was written.
> +  @retval other                Failed to wwrite the PHY register.
> +
> +**/
> +EFI_STATUS
> +Ax88772PhyWrite (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT8 RegisterAddress,
> +  IN UINT16 PhyData
> +  );
> +
> +/**
> +  Reset the AX88772
> +
> +  This routine uses ::Ax88772UsbCommand to reset the network
> +  adapter.  This routine also uses ::Ax88772PhyWrite to reset
> +  the PHY.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +
> +  @retval EFI_SUCCESS          The MAC address is available.
> +  @retval other                The MAC address is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88772Reset (
> +  IN NIC_DEVICE * pNicDevice
> +  );
> +
> +VOID
> +Ax88772ChkLink (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN BOOLEAN bUpdateLink
> +  );
> +
> +/**
> +  Receive a frame from the network.
> +
> +  This routine polls the USB receive interface for a packet.  If a packet
> +  is available, this routine adds the receive packet to the list of
> +  pending receive packets.
> +
> +  This routine calls ::Ax88772NegotiateLinkComplete to verify
> +  that the link is up.  This routine also calls ::SN_Reset to
> +  reset the network adapter when necessary.  Finally this
> +  routine attempts to receive one or more packets from the
> +  network adapter.
> +
> +  @param [in] pNicDevice  Pointer to the NIC_DEVICE structure
> +  @param [in] bUpdateLink TRUE = Update link status
> +
> +**/
> +VOID
> +Ax88772Rx (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN BOOLEAN bUpdateLink
> +  );
> +
> +/**
> +  Enable or disable the receiver
> +
> +  This routine calls ::Ax88772UsbCommand to update the
> +  receiver state.  This routine also calls ::Ax88772MacAddressSet
> +  to establish the MAC address for the network adapter.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] RxFilter         Simple network RX filter mask value
> +
> +  @retval EFI_SUCCESS          The MAC address was set.
> +  @retval other                The MAC address was not set.
> +
> +**/
> +EFI_STATUS
> +Ax88772RxControl (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT32 RxFilter
> +  );
> +
> +/**
> +  Read an SROM location
> +
> +  This routine calls ::Ax88772UsbCommand to read data from the
> +  SROM.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] Address          SROM address
> +  @param [out] pData           Buffer to receive the data
> +
> +  @retval EFI_SUCCESS          The read was successful
> +  @retval other                The read failed
> +
> +**/
> +EFI_STATUS
> +Ax88772SromRead (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN UINT32 Address,
> +  OUT UINT16 * pData
> +  );
> +
> +/**
> +  Send a command to the USB device.
> +
> +  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> +  @param [in] pRequest         Pointer to the request structure
> +  @param [in, out] pBuffer     Data buffer address
> +
> +  @retval EFI_SUCCESS          The USB transfer was successful
> +  @retval other                The USB transfer failed
> +
> +**/
> +EFI_STATUS
> +Ax88772UsbCommand (
> +  IN NIC_DEVICE * pNicDevice,
> +  IN USB_DEVICE_REQUEST * pRequest,
> +  IN OUT VOID * pBuffer
> +  );
> +
> +//------------------------------------------------------------------------------
> +// EFI Component Name Protocol Support
> +//------------------------------------------------------------------------------
> +
> +extern EFI_COMPONENT_NAME_PROTOCOL   gComponentName;  ///<
> Component name protocol declaration
> +extern EFI_COMPONENT_NAME2_PROTOCOL  gComponentName2; ///<
> Component name 2 protocol declaration
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the driver.
> +
> +  This function retrieves the user readable name of a driver in the form of a
> +  Unicode string. If the driver specified by This has a user readable name in
> +  the language specified by Language, then a pointer to the driver name is
> +  returned in DriverName, and EFI_SUCCESS is returned. If the driver
> specified
> +  by This does not support the language specified by Language,
> +  then EFI_UNSUPPORTED is returned.
> +
> +  @param [in] pThis             A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
> +                                array indicating the language. This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified
> +                                in RFC 3066 or ISO 639-2 language code format.
> +  @param [out] ppDriverName     A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                driver specified by This in the language
> +                                specified by Language.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> +                                This and the language specified by Language was
> +                                returned in DriverName.
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetDriverName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
> +  IN  CHAR8 * pLanguage,
> +  OUT CHAR16 ** ppDriverName
> +  );
> +
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the controller
> +  that is being managed by a driver.
> +
> +  This function retrieves the user readable name of the controller specified
> by
> +  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> +  driver specified by This has a user readable name in the language specified
> by
> +  Language, then a pointer to the controller name is returned in
> ControllerName,
> +  and EFI_SUCCESS is returned.  If the driver specified by This is not
> currently
> +  managing the controller specified by ControllerHandle and ChildHandle,
> +  then EFI_UNSUPPORTED is returned.  If the driver specified by This does
> not
> +  support the language specified by Language, then EFI_UNSUPPORTED is
> returned.
> +
> +  @param [in] pThis             A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +  @param [in] ControllerHandle  The handle of a controller that the driver
> +                                specified by This is managing.  This handle
> +                                specifies the controller whose name is to be
> +                                returned.
> +  @param [in] ChildHandle       The handle of the child controller to retrieve
> +                                the name of.  This is an optional parameter that
> +                                may be NULL.  It will be NULL for device
> +                                drivers.  It will also be NULL for a bus drivers
> +                                that wish to retrieve the name of the bus
> +                                controller.  It will not be NULL for a bus
> +                                driver that wishes to retrieve the name of a
> +                                child controller.
> +  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
> +                                array indicating the language.  This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified in
> +                                RFC 3066 or ISO 639-2 language code format.
> +  @param [out] ppControllerName A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                controller specified by ControllerHandle and
> +                                ChildHandle in the language specified by
> +                                Language from the point of view of the driver
> +                                specified by This.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the user readable name
> in
> +                                the language specified by Language for the
> +                                driver specified by This was returned in
> +                                DriverName.
> +  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid
> EFI_HANDLE.
> +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a
> valid
> +                                EFI_HANDLE.
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> +  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> +                                managing the controller specified by
> +                                ControllerHandle and ChildHandle.
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetControllerName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
> +  IN  EFI_HANDLE ControllerHandle,
> +  IN OPTIONAL EFI_HANDLE ChildHandle,
> +  IN  CHAR8 * pLanguage,
> +  OUT CHAR16 ** ppControllerName
> +  );
> +
> +VOID
> +FillPkt2Queue (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN UINTN BufLength);
> +
> +//------------------------------------------------------------------------------
> +
> +#endif  //  _AX88772_H_
> diff --git
> a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
> new file mode 100644
> index 0000000000..60e43fd275
> --- /dev/null
> +++
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
> @@ -0,0 +1,61 @@
> +## @file
> +# Component description file for ASIX AX88772 USB/Ethernet driver.
> +#
> +# This module provides support for the ASIX AX88772 USB/Ethernet
> adapter.
> +# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010018
> +  BASE_NAME                      = Ax88772b
> +  FILE_GUID                      = 95C8D770-E1A4-4422-B263-E32F14FD8186
> +  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
> +  VERSION_STRING                 = 1.0
> +
> +  ENTRY_POINT                    = EntryPoint
> +
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +
> +[Sources.common]
> +  Ax88772.h
> +  Ax88772.c
> +  ComponentName.c
> +  DriverBinding.c
> +  SimpleNetwork.c
> +
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +
> +[LibraryClasses]
> +  UefiLib
> +  UefiBootServicesTableLib
> +  BaseMemoryLib
> +  DebugLib
> +  UefiRuntimeLib
> +  UefiDriverEntryPoint
> +
> +[Protocols]
> +  gEfiDevicePathProtocolGuid           ## BY_START
> +  gEfiSimpleNetworkProtocolGuid        ## BY_START
> +  gEfiUsbIoProtocolGuid                ## TO_START
> +
> +[Depex]
> +  gEfiBdsArchProtocolGuid AND
> +  gEfiCpuArchProtocolGuid AND
> +  gEfiMetronomeArchProtocolGuid AND
> +  gEfiMonotonicCounterArchProtocolGuid AND
> +  gEfiRealTimeClockArchProtocolGuid AND
> +  gEfiResetArchProtocolGuid AND
> +  gEfiRuntimeArchProtocolGuid AND
> +  gEfiSecurityArchProtocolGuid AND
> +  gEfiTimerArchProtocolGuid AND
> +  gEfiVariableWriteArchProtocolGuid AND
> +  gEfiVariableArchProtocolGuid AND
> +  gEfiWatchdogTimerArchProtocolGuid
> diff --git
> a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/ComponentNa
> me.c
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/ComponentN
> ame.c
> new file mode 100644
> index 0000000000..76a732a7b0
> --- /dev/null
> +++
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/ComponentN
> ame.c
> @@ -0,0 +1,175 @@
> +/** @file
> +  UEFI Component Name(2) protocol implementation.
> +
> +  Copyright (c) 2011, Intel Corporation. All rights reserved.
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "Ax88772.h"
> +
> +/**
> +  EFI Component Name Protocol declaration
> +**/
> +GLOBAL_REMOVE_IF_UNREFERENCED
> EFI_COMPONENT_NAME_PROTOCOL  gComponentName = {
> +  GetDriverName,
> +  GetControllerName,
> +  "eng"
> +};
> +
> +/**
> +  EFI Component Name 2 Protocol declaration
> +**/
> +GLOBAL_REMOVE_IF_UNREFERENCED
> EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
> +  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) GetDriverName,
> +  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)
> GetControllerName,
> +  "en"
> +};
> +
> +
> +/**
> +  Driver name table declaration
> +**/
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
> +mDriverNameTable[] = {
> +  {"eng;en", L"ASIX AX88772B Ethernet Driver 1.0"},
> +  {NULL,  NULL}
> +};
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the driver.
> +
> +  This function retrieves the user readable name of a driver in the form of a
> +  Unicode string. If the driver specified by This has a user readable name in
> +  the language specified by Language, then a pointer to the driver name is
> +  returned in DriverName, and EFI_SUCCESS is returned. If the driver
> specified
> +  by This does not support the language specified by Language,
> +  then EFI_UNSUPPORTED is returned.
> +
> +  @param [in] pThis             A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
> +                                array indicating the language. This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified
> +                                in RFC 3066 or ISO 639-2 language code format.
> +  @param [out] ppDriverName     A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                driver specified by This in the language
> +                                specified by Language.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> +                                This and the language specified by Language was
> +                                returned in DriverName.
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetDriverName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
> +  IN  CHAR8 * pLanguage,
> +  OUT CHAR16 ** ppDriverName
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  Status = LookupUnicodeString2 (
> +             pLanguage,
> +             pThis->SupportedLanguages,
> +             mDriverNameTable,
> +             ppDriverName,
> +             (BOOLEAN)(pThis == &gComponentName)
> +             );
> +
> +  return Status;
> +}
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the controller
> +  that is being managed by a driver.
> +
> +  This function retrieves the user readable name of the controller specified
> by
> +  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> +  driver specified by This has a user readable name in the language specified
> by
> +  Language, then a pointer to the controller name is returned in
> ControllerName,
> +  and EFI_SUCCESS is returned.  If the driver specified by This is not
> currently
> +  managing the controller specified by ControllerHandle and ChildHandle,
> +  then EFI_UNSUPPORTED is returned.  If the driver specified by This does
> not
> +  support the language specified by Language, then EFI_UNSUPPORTED is
> returned.
> +
> +  @param [in] pThis             A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +  @param [in] ControllerHandle  The handle of a controller that the driver
> +                                specified by This is managing.  This handle
> +                                specifies the controller whose name is to be
> +                                returned.
> +  @param [in] ChildHandle       The handle of the child controller to retrieve
> +                                the name of.  This is an optional parameter that
> +                                may be NULL.  It will be NULL for device
> +                                drivers.  It will also be NULL for a bus drivers
> +                                that wish to retrieve the name of the bus
> +                                controller.  It will not be NULL for a bus
> +                                driver that wishes to retrieve the name of a
> +                                child controller.
> +  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
> +                                array indicating the language.  This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified in
> +                                RFC 3066 or ISO 639-2 language code format.
> +  @param [out] ppControllerName A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                controller specified by ControllerHandle and
> +                                ChildHandle in the language specified by
> +                                Language from the point of view of the driver
> +                                specified by This.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the user readable name
> in
> +                                the language specified by Language for the
> +                                driver specified by This was returned in
> +                                DriverName.
> +  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid
> EFI_HANDLE.
> +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a
> valid
> +                                EFI_HANDLE.
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> +  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> +                                managing the controller specified by
> +                                ControllerHandle and ChildHandle.
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetControllerName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
> +  IN  EFI_HANDLE ControllerHandle,
> +  IN OPTIONAL EFI_HANDLE ChildHandle,
> +  IN  CHAR8 * pLanguage,
> +  OUT CHAR16 ** ppControllerName
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  //
> +  // Set the controller name
> +  //
> +  *ppControllerName = L"ASIX AX88772B USB Fast Ethernet Controller";
> +  Status = EFI_SUCCESS;
> +
> +  //
> +  // Return the operation status
> +  //
> +
> +  return Status;
> +}
> diff --git
> a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/DriverBinding.
> c
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/DriverBinding.
> c
> new file mode 100644
> index 0000000000..2bec944140
> --- /dev/null
> +++
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/DriverBinding.
> c
> @@ -0,0 +1,696 @@
> +/** @file
> +  Implement the driver binding protocol for Asix AX88772 Ethernet driver.
> +
> +  Copyright (c) 2011-2013, Intel Corporation. All rights reserved.
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "Ax88772.h"
> +
> +ASIX_DONGLE ASIX_DONGLES[] = {
> +  { 0x05AC, 0x1402, FLAG_TYPE_AX88772 }, // Apple USB Ethernet Adapter
> +  // ASIX 88772B
> +  { 0x0B95, 0x772B, FLAG_TYPE_AX88772B | FLAG_EEPROM_MAC },
> +  { 0x0000, 0x0000, FLAG_NONE }   // END - Do not remove
> +};
> +
> +/**
> +  Verify the controller type
> +
> +  @param [in] pThis                Protocol instance pointer.
> +  @param [in] Controller           Handle of device to test.
> +  @param [in] pRemainingDevicePath Not used.
> +
> +  @retval EFI_SUCCESS          This driver supports this device.
> +  @retval other                This driver does not support this device.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DriverSupported (
> +  IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
> +  IN EFI_HANDLE Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
> +  )
> +{
> +  EFI_USB_DEVICE_DESCRIPTOR Device;
> +  EFI_USB_IO_PROTOCOL * pUsbIo;
> +  EFI_STATUS Status;
> +  UINT32 Index;
> +
> +  //
> +  //  Connect to the USB stack
> +  //
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiUsbIoProtocolGuid,
> +                  (VOID **) &pUsbIo,
> +                  pThis->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +  if (!EFI_ERROR ( Status )) {
> +
> +    //
> +    //  Get the interface descriptor to check the USB class and find a
> transport
> +    //  protocol handler.
> +    //
> +    Status = pUsbIo->UsbGetDeviceDescriptor ( pUsbIo, &Device );
> +    if (EFI_ERROR ( Status )) {
> +    	Status = EFI_UNSUPPORTED;
> +    }
> +    else {
> +      //
> +      //  Validate the adapter
> +      //
> +      for (Index = 0; ASIX_DONGLES[Index].VendorId != 0; Index++) {
> +        if (ASIX_DONGLES[Index].VendorId == Device.IdVendor &&
> +            ASIX_DONGLES[Index].ProductId == Device.IdProduct) {
> +              DEBUG ((EFI_D_INFO, "Found the AX88772B\r\n"));
> +              break;
> +        }
> +      }
> +
> +      if (ASIX_DONGLES[Index].VendorId == 0)
> +         Status = EFI_UNSUPPORTED;
> +    }
> +
> +    //
> +    //  Done with the USB stack
> +    //
> +    gBS->CloseProtocol (
> +           Controller,
> +           &gEfiUsbIoProtocolGuid,
> +           pThis->DriverBindingHandle,
> +           Controller
> +           );
> +  }
> +  return Status;
> +}
> +
> +
> +/**
> +  Start this driver on Controller by opening UsbIo and DevicePath protocols.
> +  Initialize PXE structures, create a copy of the Controller Device Path with
> the
> +  NIC's MAC address appended to it, install the NetworkInterfaceIdentifier
> protocol
> +  on the newly created Device Path.
> +
> +  @param [in] pThis                Protocol instance pointer.
> +  @param [in] Controller           Handle of device to work with.
> +  @param [in] pRemainingDevicePath Not used, always produce all possible
> children.
> +
> +  @retval EFI_SUCCESS          This driver is added to Controller.
> +  @retval other                This driver does not support this device.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DriverStart (
> +  IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
> +  IN EFI_HANDLE Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
> +  )
> +{
> +
> +	EFI_STATUS						Status;
> +	NIC_DEVICE						*pNicDevice;
> +	UINTN
> 	LengthInBytes;
> +	EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath = NULL;
> +	MAC_ADDR_DEVICE_PATH            MacDeviceNode;
> +        EFI_USB_DEVICE_DESCRIPTOR       Device;
> +        UINT32                          Index;
> +
> +  //
> +	//  Allocate the device structure
> +	//
> +	LengthInBytes = sizeof ( *pNicDevice );
> +	Status = gBS->AllocatePool (
> +                  EfiRuntimeServicesData,
> +                  LengthInBytes,
> +                  (VOID **) &pNicDevice
> +                  );
> +
> +	if (EFI_ERROR (Status)) {
> +		DEBUG ((EFI_D_ERROR, "gBS->AllocatePool:pNicDevice
> ERROR Status = %r\n", Status));
> +		goto EXIT;
> +	}
> +
> +	//
> +  //  Set the structure signature
> +  //
> +  ZeroMem ( pNicDevice, LengthInBytes );
> +  pNicDevice->Signature = DEV_SIGNATURE;
> +
> +	Status = gBS->OpenProtocol (
> +                    Controller,
> +                    &gEfiUsbIoProtocolGuid,
> +                    (VOID **) &pNicDevice->pUsbIo,
> +                    pThis->DriverBindingHandle,
> +                    Controller,
> +                    EFI_OPEN_PROTOCOL_BY_DRIVER
> +                    );
> +
> +	if (EFI_ERROR (Status)) {
> +		DEBUG ((EFI_D_ERROR, "gBS-
> >OpenProtocol:EFI_USB_IO_PROTOCOL ERROR Status = %r\n", Status));
> +		gBS->FreePool ( pNicDevice );
> +		goto EXIT;
> +	}
> +
> +	//
> +  //  Initialize the simple network protocol
> +  //
> +	Status = SN_Setup ( pNicDevice );
> +
> +	if (EFI_ERROR(Status)){
> +	   DEBUG ((EFI_D_ERROR, "SN_Setup ERROR Status = %r\n", Status));
> +	   gBS->CloseProtocol (
> +					Controller,
> +					&gEfiUsbIoProtocolGuid,
> +					pThis->DriverBindingHandle,
> +					Controller
> +					);
> +		  gBS->FreePool ( pNicDevice );
> +		  goto EXIT;
> +  }
> +
> +  Status = pNicDevice->pUsbIo->UsbGetDeviceDescriptor ( pNicDevice-
> >pUsbIo, &Device );
> +  if (EFI_ERROR ( Status )) {
> +     gBS->CloseProtocol (
> +               Controller,
> +               &gEfiUsbIoProtocolGuid,
> +               pThis->DriverBindingHandle,
> +               Controller
> +               );
> +     gBS->FreePool ( pNicDevice );
> +              goto EXIT;
> +  } else {
> +      //
> +      //  Validate the adapter
> +      //
> +      for (Index = 0; ASIX_DONGLES[Index].VendorId != 0; Index++) {
> +          if (ASIX_DONGLES[Index].VendorId == Device.IdVendor &&
> +              ASIX_DONGLES[Index].ProductId == Device.IdProduct) {
> +                break;
> +          }
> +      }
> +
> +      if (ASIX_DONGLES[Index].VendorId == 0) {
> +         gBS->CloseProtocol (
> +                   Controller,
> +                   &gEfiUsbIoProtocolGuid,
> +                   pThis->DriverBindingHandle,
> +                   Controller
> +                   );
> +          gBS->FreePool ( pNicDevice );
> +                   goto EXIT;
> +      }
> +
> +      pNicDevice->Flags = ASIX_DONGLES[Index].Flags;
> +  }
> +
> +	//
> +  // Set Device Path
> +  //
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiDevicePathProtocolGuid,
> +                  (VOID **) &ParentDevicePath,
> +				          pThis->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +	if (EFI_ERROR(Status)) {
> +        DEBUG ((EFI_D_ERROR, "gBS-
> >OpenProtocol:EFI_DEVICE_PATH_PROTOCOL error. Status = %r\n",
> +            Status));
> +		    gBS->CloseProtocol (
> +					Controller,
> +					&gEfiUsbIoProtocolGuid,
> +					pThis->DriverBindingHandle,
> +					Controller
> +					);
> +		  gBS->FreePool ( pNicDevice );
> +		  goto EXIT;
> +	}
> +
> +  ZeroMem (&MacDeviceNode, sizeof (MAC_ADDR_DEVICE_PATH));
> +  MacDeviceNode.Header.Type = MESSAGING_DEVICE_PATH;
> +  MacDeviceNode.Header.SubType = MSG_MAC_ADDR_DP;
> +
> +  SetDevicePathNodeLength (&MacDeviceNode.Header, sizeof
> (MAC_ADDR_DEVICE_PATH));
> +
> +  CopyMem (&MacDeviceNode.MacAddress,
> +      								&pNicDevice-
> >SimpleNetworkData.CurrentAddress,
> +
> 	PXE_HWADDR_LEN_ETHER);
> +
> +  MacDeviceNode.IfType = pNicDevice->SimpleNetworkData.IfType;
> +
> +  pNicDevice->MyDevPath = AppendDevicePathNode (
> +                                          ParentDevicePath,
> +                                          (EFI_DEVICE_PATH_PROTOCOL *) &MacDeviceNode
> +                                          );
> +
> +	pNicDevice->Controller = NULL;
> +
> +	//
> +  //  Install both the simple network and device path protocols.
> +  //
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                          &pNicDevice->Controller,
> +                          &gEfiCallerIdGuid,
> +                          pNicDevice,
> +                          &gEfiSimpleNetworkProtocolGuid,
> +                          &pNicDevice->SimpleNetwork,
> +
> &gEfiDevicePathProtocolGuid,
> +						              pNicDevice-
> >MyDevPath,
> +                          NULL
> +                          );
> +
> +	if (EFI_ERROR(Status)){
> +		DEBUG ((EFI_D_ERROR, "gBS-
> >InstallMultipleProtocolInterfaces error. Status = %r\n",
> +            Status));
> +		gBS->CloseProtocol (
> +					               Controller,
> +
> &gEfiDevicePathProtocolGuid,
> +					               pThis->DriverBindingHandle,
> +					               Controller);
> +	   gBS->CloseProtocol (
> +					Controller,
> +					&gEfiUsbIoProtocolGuid,
> +					pThis->DriverBindingHandle,
> +					Controller
> +					);
> +		  gBS->FreePool ( pNicDevice );
> +		  goto EXIT;
> +	}
> +
> +	//
> +	// Open For Child Device
> +	//
> +	Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiUsbIoProtocolGuid,
> +                  (VOID **) &pNicDevice->pUsbIo,
> +                  pThis->DriverBindingHandle,
> +                  pNicDevice->Controller,
> +                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
> +                  );
> +
> +	if (EFI_ERROR(Status)){
> +	   gBS->UninstallMultipleProtocolInterfaces (
> +              &pNicDevice->Controller,
> +                          &gEfiCallerIdGuid,
> +                          pNicDevice,
> +                          &gEfiSimpleNetworkProtocolGuid,
> +                          &pNicDevice->SimpleNetwork,
> +
> &gEfiDevicePathProtocolGuid,
> +						              pNicDevice-
> >MyDevPath,
> +                          NULL
> +                          );
> +		gBS->CloseProtocol (
> +					               Controller,
> +
> &gEfiDevicePathProtocolGuid,
> +					               pThis->DriverBindingHandle,
> +					               Controller);
> +	   gBS->CloseProtocol (
> +					Controller,
> +					&gEfiUsbIoProtocolGuid,
> +					pThis->DriverBindingHandle,
> +					Controller
> +					);
> +		  gBS->FreePool ( pNicDevice );
> +	}
> +
> +EXIT:
> +	return Status;
> +
> +}
> +
> +/**
> +  Stop this driver on Controller by removing NetworkInterfaceIdentifier
> protocol and
> +  closing the DevicePath and PciIo protocols on Controller.
> +
> +  @param [in] pThis                Protocol instance pointer.
> +  @param [in] Controller           Handle of device to stop driver on.
> +  @param [in] NumberOfChildren     How many children need to be stopped.
> +  @param [in] pChildHandleBuffer   Not used.
> +
> +  @retval EFI_SUCCESS          This driver is removed Controller.
> +  @retval EFI_DEVICE_ERROR     The device could not be stopped due to a
> device error.
> +  @retval other                This driver was not removed from this device.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DriverStop (
> +  IN  EFI_DRIVER_BINDING_PROTOCOL * pThis,
> +  IN  EFI_HANDLE Controller,
> +  IN  UINTN NumberOfChildren,
> +  IN  EFI_HANDLE * ChildHandleBuffer
> +  )
> +{
> +		BOOLEAN                                   AllChildrenStopped;
> +		UINTN                                     Index;
> +		EFI_SIMPLE_NETWORK_PROTOCOL
> 	  *SimpleNetwork;
> +		EFI_STATUS                                Status = EFI_SUCCESS;
> +		NIC_DEVICE
> 		  *pNicDevice;
> +
> +		//
> +		// Complete all outstanding transactions to Controller.
> +		// Don't allow any new transaction to Controller to be
> started.
> +		//
> +		if (NumberOfChildren == 0) {
> +
> +		  Status = gBS->OpenProtocol (
> +				                Controller,
> +				                &gEfiSimpleNetworkProtocolGuid,
> +				                (VOID **) &SimpleNetwork,
> +				                pThis->DriverBindingHandle,
> +				                Controller,
> +
> EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +				                );
> +
> +			if (EFI_ERROR(Status)) {
> +        //
> +        // This is a 2nd type handle(multi-lun root), it needs to close
> devicepath
> +        // and usbio protocol.
> +        //
> +        gBS->CloseProtocol (
> +            Controller,
> +            &gEfiDevicePathProtocolGuid,
> +            pThis->DriverBindingHandle,
> +            Controller
> +            );
> +        gBS->CloseProtocol (
> +            Controller,
> +            &gEfiUsbIoProtocolGuid,
> +            pThis->DriverBindingHandle,
> +            Controller
> +            );
> +        return EFI_SUCCESS;
> +      }
> +
> +      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( SimpleNetwork );
> +
> +      Status = gBS->UninstallMultipleProtocolInterfaces (
> +				                  Controller,
> 
> +				                  &gEfiCallerIdGuid,
> +                          pNicDevice,
> +                          &gEfiSimpleNetworkProtocolGuid,
> +                          &pNicDevice->SimpleNetwork,
> +
> &gEfiDevicePathProtocolGuid,
> +						              pNicDevice-
> >MyDevPath,
> +                          NULL
> +                          );
> +
> +      if (EFI_ERROR (Status)) {
> +        return Status;
> +      }
> +		  //
> +		  // Close the bus driver
> +		  //
> +		  Status = gBS->CloseProtocol (
> +		                  Controller,
> +		                  &gEfiDevicePathProtocolGuid,
> +		                  pThis->DriverBindingHandle,
> +		                  Controller
> +		                  );
> +
> +		  if (EFI_ERROR(Status)){
> +          DEBUG ((EFI_D_ERROR, "driver stop: gBS-
> >CloseProtocol:EfiDevicePathProtocol error. Status %r\n", Status));
> +		  }
> +
> +		  Status = gBS->CloseProtocol (
> +		                  Controller,
> +		                  &gEfiUsbIoProtocolGuid,
> +		                  pThis->DriverBindingHandle,
> +		                  Controller
> +		                  );
> +
> +		  if (EFI_ERROR(Status)){
> +          DEBUG ((EFI_D_ERROR, "driver stop: gBS-
> >CloseProtocol:EfiUsbIoProtocol error. Status %r\n", Status));
> +		  }
> +      return EFI_SUCCESS;
> +		}
> +		AllChildrenStopped = TRUE;
> +
> +		for (Index = 0; Index < NumberOfChildren; Index++) {
> +
> +				Status = gBS->OpenProtocol (
> +				                ChildHandleBuffer[Index],
> +				                &gEfiSimpleNetworkProtocolGuid,
> +				                (VOID **) &SimpleNetwork,
> +				                pThis->DriverBindingHandle,
> +				                Controller,
> +
> EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +				                );
> +
> +				if (EFI_ERROR (Status)) {
> +          AllChildrenStopped = FALSE;
> +          DEBUG ((EFI_D_ERROR, "Fail to stop No.%d multi-lun child handle
> when opening SimpleNetwork\n", (UINT32)Index));
> +          continue;
> +        }
> +
> +        pNicDevice = DEV_FROM_SIMPLE_NETWORK ( SimpleNetwork );
> +
> +        gBS->CloseProtocol (
> +				                    Controller,
> +				                    &gEfiUsbIoProtocolGuid,
> +				                    pThis->DriverBindingHandle,
> +				                    ChildHandleBuffer[Index]
> +				                    );
> +
> +				Status = gBS-
> >UninstallMultipleProtocolInterfaces (
> +				                  ChildHandleBuffer[Index],
> 
> +				                  &gEfiCallerIdGuid,
> +                          pNicDevice,
> +                          &gEfiSimpleNetworkProtocolGuid,
> +                          &pNicDevice->SimpleNetwork,
> +
> &gEfiDevicePathProtocolGuid,
> +						              pNicDevice-
> >MyDevPath,
> +                          NULL
> +                          );
> +
> +        if (EFI_ERROR (Status)) {
> +            Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiUsbIoProtocolGuid,
> +                  (VOID **) &pNicDevice->pUsbIo,
> +                  pThis->DriverBindingHandle,
> +                  ChildHandleBuffer[Index],
> +                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
> +                  );
> +        }
> +        else {
> +            int i;
> +            RX_PKT * pCurr = pNicDevice->QueueHead;
> +            RX_PKT * pFree;
> +
> +            for ( i = 0 ; i < MAX_QUEUE_SIZE ; i++) {
> +                 if ( NULL != pCurr ) {
> +                    pFree = pCurr;
> +                    pCurr = pCurr->pNext;
> +                    gBS->FreePool (pFree);
> +                 }
> +            }
> +
> +            if ( NULL != pNicDevice->pRxTest)
> +						    gBS->FreePool (pNicDevice-
> >pRxTest);
> +
> +					 if ( NULL != pNicDevice->pTxTest)
> +						    gBS->FreePool (pNicDevice-
> >pTxTest);
> +
> +           if ( NULL != pNicDevice->MyDevPath)
> +					       gBS->FreePool (pNicDevice-
> >MyDevPath);
> +
> +				    if ( NULL != pNicDevice)
> +                  gBS->FreePool (pNicDevice);
> +        }
> +    }
> +
> +        if (!AllChildrenStopped) {
> +                return EFI_DEVICE_ERROR;
> +        }
> +        return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Driver binding protocol declaration
> +**/
> +EFI_DRIVER_BINDING_PROTOCOL  gDriverBinding = {
> +  DriverSupported,
> +  DriverStart,
> +  DriverStop,
> +  0xa,
> +  NULL,
> +  NULL
> +};
> +
> +
> +/**
> +  Ax88772 driver unload routine.
> +
> +  @param [in] ImageHandle       Handle for the image.
> +
> +  @retval EFI_SUCCESS           Image may be unloaded
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DriverUnload (
> +  IN EFI_HANDLE ImageHandle
> +  )
> +{
> +  UINTN BufferSize;
> +  UINTN Index;
> +  UINTN Max;
> +  EFI_HANDLE * pHandle;
> +  EFI_STATUS Status;
> +
> +  //
> +  //  Determine which devices are using this driver
> +  //
> +  BufferSize = 0;
> +  pHandle = NULL;
> +  Status = gBS->LocateHandle (
> +                  ByProtocol,
> +                  &gEfiCallerIdGuid,
> +                  NULL,
> +                  &BufferSize,
> +                  NULL );
> +  if ( EFI_BUFFER_TOO_SMALL == Status ) {
> +    for ( ; ; ) {
> +      //
> +      //  One or more block IO devices are present
> +      //
> +      Status = gBS->AllocatePool (
> +                      EfiRuntimeServicesData,
> +                      BufferSize,
> +                      (VOID **) &pHandle
> +                      );
> +      if ( EFI_ERROR ( Status )) {
> +        DEBUG ((EFI_D_ERROR, "Insufficient memory, failed handle buffer
> allocation\r\n"));
> +        break;
> +      }
> +
> +      //
> +      //  Locate the block IO devices
> +      //
> +      Status = gBS->LocateHandle (
> +                      ByProtocol,
> +                      &gEfiCallerIdGuid,
> +                      NULL,
> +                      &BufferSize,
> +                      pHandle );
> +      if ( EFI_ERROR ( Status )) {
> +        //
> +        //  Error getting handles
> +        //
> +        break;
> +      }
> +
> +      //
> +      //  Remove any use of the driver
> +      //
> +      Max = BufferSize / sizeof ( pHandle[ 0 ]);
> +      for ( Index = 0; Max > Index; Index++ ) {
> +        Status = DriverStop ( &gDriverBinding,
> +                              pHandle[ Index ],
> +                              0,
> +                              NULL );
> +        if ( EFI_ERROR ( Status )) {
> +          DEBUG ((EFI_D_ERROR, "WARNING - Failed to shutdown the driver on
> handle %08x\r\n", pHandle[ Index ]));
> +          break;
> +        }
> +      }
> +      break;
> +    }
> +  }
> +  else {
> +    if ( EFI_NOT_FOUND == Status ) {
> +      //
> +      //  No devices were found
> +      //
> +      Status = EFI_SUCCESS;
> +    }
> +  }
> +
> +  //
> +  //  Free the handle array
> +  //
> +  if ( NULL != pHandle ) {
> +    gBS->FreePool ( pHandle );
> +  }
> +
> +  //
> +  //  Remove the protocols installed by the EntryPoint routine.
> +  //
> +  if ( !EFI_ERROR ( Status )) {
> +    gBS->UninstallMultipleProtocolInterfaces (
> +            ImageHandle,
> +            &gEfiDriverBindingProtocolGuid,
> +            &gDriverBinding,
> +            &gEfiComponentNameProtocolGuid,
> +            &gComponentName,
> +            &gEfiComponentName2ProtocolGuid,
> +            &gComponentName2,
> +            NULL
> +            );
> +
> +    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> +            "Removed:   gEfiComponentName2ProtocolGuid from 0x%08x\r\n",
> +            ImageHandle ));
> +    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> +              "Removed:   gEfiComponentNameProtocolGuid from 0x%08x\r\n",
> +              ImageHandle ));
> +    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> +              "Removed:   gEfiDriverBindingProtocolGuid from 0x%08x\r\n",
> +              ImageHandle ));
> +
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +Ax88772 driver entry point.
> +
> +@param [in] ImageHandle       Handle for the image.
> +@param [in] pSystemTable      Address of the system table.
> +
> +@retval EFI_SUCCESS           Image successfully loaded.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +EntryPoint (
> +  IN EFI_HANDLE ImageHandle,
> +  IN EFI_SYSTEM_TABLE * pSystemTable
> +  )
> +{
> +  EFI_STATUS    Status;
> +
> +  //
> +  //  Add the driver to the list of drivers
> +  //
> +  Status = EfiLibInstallDriverBindingComponentName2 (
> +             ImageHandle,
> +             pSystemTable,
> +             &gDriverBinding,
> +             ImageHandle,
> +             &gComponentName,
> +             &gComponentName2
> +             );
> +  if ( !EFI_ERROR ( Status )) {
> +    DEBUG ((EFI_D_INFO, "Installed: gEfiDriverBindingProtocolGuid on
> 0x%08x\r\n",
> +              ImageHandle));
> +    DEBUG ((EFI_D_INFO, "Installed: gEfiComponentNameProtocolGuid on
> 0x%08x\r\n",
> +              ImageHandle));
> +    DEBUG ((EFI_D_INFO,"Installed: gEfiComponentName2ProtocolGuid on
> 0x%08x\r\n",
> +              ImageHandle ));
> +
> +  }
> +  return Status;
> +}
> diff --git
> a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwor
> k.c
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwor
> k.c
> new file mode 100644
> index 0000000000..76babedb20
> --- /dev/null
> +++
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwor
> k.c
> @@ -0,0 +1,1657 @@
> +/** @file
> +  Provides the Simple Network functions.
> +
> +  Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "Ax88772.h"
> +
> +/**
> +  This function updates the filtering on the receiver.
> +
> +  This support routine calls ::Ax88772MacAddressSet to update
> +  the MAC address.  This routine then rebuilds the multicast
> +  hash by calling ::Ax88772MulticastClear and ::Ax88772MulticastSet.
> +  Finally this routine enables the receiver by calling
> +  ::Ax88772RxControl.
> +
> +  @param [in] pSimpleNetwork    Simple network mode pointer
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +ReceiveFilterUpdate (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> +  )
> +{
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  NIC_DEVICE * pNicDevice;
> +  EFI_STATUS Status;
> +  UINT32 Index;
> +
> +  //
> +  // Set the MAC address
> +  //
> +  pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> +  pMode = pSimpleNetwork->Mode;
> +
> +  //
> +  // Clear the multicast hash table
> +  //
> +  Ax88772MulticastClear ( pNicDevice );
> +
> +  //
> +  // Load the multicast hash table
> +  //
> +  if ( 0 != ( pMode->ReceiveFilterSetting &
> EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST )) {
> +      for ( Index = 0; Index < pMode->MCastFilterCount; Index++ ) {
> +        //
> +        // Enable the next multicast address
> +        //
> +        Ax88772MulticastSet ( pNicDevice,
> +                              &pMode->MCastFilter[ Index ].Addr[0]);
> +      }
> +  }
> +
> +  Status = Ax88772RxControl ( pNicDevice, pMode->ReceiveFilterSetting );
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  This function updates the SNP driver status.
> +
> +  This function gets the current interrupt and recycled transmit
> +  buffer status from the network interface.  The interrupt status
> +  and the media status are returned as a bit mask in InterruptStatus.
> +  If InterruptStatus is NULL, the interrupt status will not be read.
> +  Upon successful return of the media status, the MediaPresent field
> +  of EFI_SIMPLE_NETWORK_MODE will be updated to reflect any change
> +  of media status.  If TxBuf is not NULL, a recycled transmit buffer
> +  address will be retrived.  If a recycled transmit buffer address
> +  is returned in TxBuf, then the buffer has been successfully
> +  transmitted, and the status for that buffer is cleared.
> +
> +  This function calls ::Ax88772Rx to update the media status and
> +  queue any receive packets.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] pInterruptStatus  A pointer to the bit mask of the current
> active interrupts.
> +                                If this is NULL, the interrupt status will not be read from
> +                                the device.  If this is not NULL, the interrupt status will
> +                                be read from teh device.  When the interrupt status is
> read,
> +                                it will also be cleared.  Clearing the transmit interrupt
> +                                does not empty the recycled transmit buffer array.
> +  @param [out] ppTxBuf          Recycled transmit buffer address.  The
> network interface will
> +                                not transmit if its internal recycled transmit buffer array is
> +                                full.  Reading the transmit buffer does not clear the
> transmit
> +                                interrupt.  If this is NULL, then the transmit buffer status
> +                                will not be read.  If there are not transmit buffers to
> recycle
> +                                and TxBuf is not NULL, *TxBuf will be set to NULL.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_GetStatus (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  OUT UINT32 * pInterruptStatus,
> +  OUT VOID ** ppTxBuf
> +  )
> +{
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  NIC_DEVICE * pNicDevice;
> +  EFI_STATUS Status;
> +  BOOLEAN bFullDuplex;
> +  BOOLEAN bLinkUp;
> +  BOOLEAN bSpeed100;
> +  EFI_TPL TplPrevious;
> +
> +  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> +  //
> +  // Verify the parameters
> +  //
> +  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> +    //
> +    // Return the transmit buffer
> +    //
> +
> +    pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> +    if (( NULL != ppTxBuf ) && ( NULL != pNicDevice->pTxBuffer )) {
> +     		 *ppTxBuf = pNicDevice->pTxBuffer;
> +     		 pNicDevice->pTxBuffer = NULL;
> +   	}
> +
> +    //
> +    // Determine if interface is running
> +    //
> +    pMode = pSimpleNetwork->Mode;
> +    if ( EfiSimpleNetworkInitialized == pMode->State ) {
> +
> +      if ( pNicDevice->LinkIdleCnt > MAX_LINKIDLE_THRESHOLD) {
> +
> +          bLinkUp = pNicDevice->bLinkUp;
> +          bSpeed100 = pNicDevice->b100Mbps;
> +          bFullDuplex = pNicDevice->bFullDuplex;
> +          Status = Ax88772NegotiateLinkComplete ( pNicDevice,
> +                                            &pNicDevice->PollCount,
> +                                            &pNicDevice->bComplete,
> +                                            &pNicDevice->bLinkUp,
> +                                            &pNicDevice->b100Mbps,
> +                                            &pNicDevice->bFullDuplex );
> +
> +          //
> +          // Determine if the autonegotiation is complete
> +          //
> +          if ( pNicDevice->bComplete ) {
> +              if ( pNicDevice->bLinkUp ) {
> +                  if (( bSpeed100 && ( !pNicDevice->b100Mbps ))
> +                      || (( !bSpeed100 ) && pNicDevice->b100Mbps )
> +                      || ( bFullDuplex && ( !pNicDevice->bFullDuplex ))
> +                      || (( !bFullDuplex ) && pNicDevice->bFullDuplex )) {
> +                          pNicDevice->PollCount = 0;
> +                          DEBUG (( EFI_D_INFO , "Reset to establish proper link
> setup: %d Mbps, %a duplex\r\n",
> +                                    pNicDevice->b100Mbps ? 100 : 10, pNicDevice-
> >bFullDuplex ? "Full" : "Half"));
> +                          Status = SN_Reset ( &pNicDevice->SimpleNetwork, FALSE );
> +                  }
> +                  if (( !bLinkUp ) && pNicDevice->bLinkUp ) {
> +                      //
> +                      // Display the autonegotiation status
> +                      //
> +                      DEBUG (( EFI_D_INFO , "Link: Up, %d Mbps, %a duplex\r\n",
> +                                pNicDevice->b100Mbps ? 100 : 10, pNicDevice-
> >bFullDuplex ? "Full" : "Half"));
> +
> +                  }
> +                  pNicDevice->LinkIdleCnt = 0;
> +            }
> +        }
> +        //
> +        //  Update the link status
> +        //
> +        if ( bLinkUp && ( !pNicDevice->bLinkUp )) {
> +            DEBUG (( EFI_D_INFO , "Link: Down\r\n"));
> +        }
> +      }
> +
> +      pMode->MediaPresent = pNicDevice->bLinkUp;
> +      //
> +      // Return the interrupt status
> +      //
> +      if ( NULL != pInterruptStatus ) {
> +        *pInterruptStatus = 0;
> +      }
> +      Status = EFI_SUCCESS;
> +    }
> +    else {
> +      if ( EfiSimpleNetworkStarted == pMode->State ) {
> +        Status = EFI_DEVICE_ERROR;
> +      }
> +      else {
> +        Status = EFI_NOT_STARTED;
> +      }
> +    }
> +
> +  }
> +  else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +  gBS->RestoreTPL(TplPrevious) ;
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Resets the network adapter and allocates the transmit and receive buffers
> +  required by the network interface; optionally, also requests allocation of
> +  additional transmit and receive buffers.  This routine must be called
> before
> +  any other routine in the Simple Network protocol is called.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] ExtraRxBufferSize Size in bytes to add to the receive buffer
> allocation
> +  @param [in] ExtraTxBufferSize Size in bytes to add to the transmit buffer
> allocation
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_OUT_OF_RESOURCES  There was not enough memory for the
> transmit and receive buffers
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Initialize (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN UINTN ExtraRxBufferSize,
> +  IN UINTN ExtraTxBufferSize
> +  )
> +{
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  EFI_STATUS Status;
> +  UINT32  TmpState;
> +   EFI_TPL TplPrevious;
> +
> +   TplPrevious = gBS->RaiseTPL (TPL_CALLBACK);
> +  //
> +  // Verify the parameters
> +  //
> +  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> +    //
> +    // Determine if the interface is already started
> +    //
> +    pMode = pSimpleNetwork->Mode;
> +    if ( EfiSimpleNetworkStarted == pMode->State ) {
> +      if (( 0 == ExtraRxBufferSize ) && ( 0 == ExtraTxBufferSize )) {
> +        //
> +        // Start the adapter
> +        //
> +        TmpState = pMode->State;
> +        pMode->State = EfiSimpleNetworkInitialized;
> +        Status = SN_Reset ( pSimpleNetwork, FALSE );
> +        if ( EFI_ERROR ( Status )) {
> +          //
> +          // Update the network state
> +          //
> +          pMode->State = TmpState;
> +          DEBUG (( EFI_D_ERROR , "SN_reset failed\n"));
> +        }
> +      }
> +      else {
> +        DEBUG (( EFI_D_ERROR , "Increase ExtraRxBufferSize = %d
> ExtraTxBufferSize=%d\n",
> +              ExtraRxBufferSize, ExtraTxBufferSize));
> +        Status = EFI_UNSUPPORTED;
> +      }
> +    }
> +    else {
> +      Status = EFI_NOT_STARTED;
> +    }
> +  }
> +  else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +  gBS->RestoreTPL (TplPrevious);
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  This function converts a multicast IP address to a multicast HW MAC
> address
> +  for all packet transactions.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] bIPv6             Set to TRUE if the multicast IP address is IPv6
> [RFC2460].
> +                                Set to FALSE if the multicast IP address is IPv4 [RFC 791].
> +  @param [in] pIP               The multicast IP address that is to be converted
> to a
> +                                multicast HW MAC address.
> +  @param [in] pMAC              The multicast HW MAC address that is to be
> generated from IP.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_MCastIPtoMAC (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN BOOLEAN bIPv6,
> +  IN EFI_IP_ADDRESS * pIP,
> +  OUT EFI_MAC_ADDRESS * pMAC
> +  )
> +{
> +  EFI_STATUS Status;
> +  EFI_TPL TplPrevious;
> +
> +  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> +  //
> +  // Get pointer to SNP driver instance for *this.
> +  //
> +  if (pSimpleNetwork == NULL) {
> +    gBS->RestoreTPL(TplPrevious);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (pIP == NULL || pMAC == NULL) {
> +    gBS->RestoreTPL(TplPrevious);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (bIPv6){
> +    Status = EFI_UNSUPPORTED;
> +  }
> +  else {
> +      //
> +      // check if the ip given is a mcast IP
> +      //
> +      if ((pIP->v4.Addr[0] & 0xF0) != 0xE0) {
> +        gBS->RestoreTPL(TplPrevious);
> +        return EFI_INVALID_PARAMETER;
> +      }
> +      else {
> +        if (pSimpleNetwork->Mode->State == EfiSimpleNetworkInitialized)
> +        {
> +          pMAC->Addr[0] = 0x01;
> +          pMAC->Addr[1] = 0x00;
> +          pMAC->Addr[2] = 0x5e;
> +          pMAC->Addr[3] = (UINT8) (pIP->v4.Addr[1] & 0x7f);
> +          pMAC->Addr[4] = (UINT8) pIP->v4.Addr[2];
> +          pMAC->Addr[5] = (UINT8) pIP->v4.Addr[3];
> +          Status = EFI_SUCCESS;
> +        }
> +        else if (pSimpleNetwork->Mode->State == EfiSimpleNetworkStarted) {
> +          Status = EFI_DEVICE_ERROR;
> +        }
> +        else {
> +          Status = EFI_NOT_STARTED;
> +        }
> +        gBS->RestoreTPL(TplPrevious);
> +      }
> +  }
> +  return Status;
> +}
> +
> +
> +/**
> +  This function performs read and write operations on the NVRAM device
> +  attached to a network interface.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] ReadWrite         TRUE for read operations, FALSE for write
> operations.
> +  @param [in] Offset            Byte offset in the NVRAM device at which to
> start the
> +                                read or write operation.  This must be a multiple of
> +                                NvRamAccessSize and less than NvRamSize.
> +  @param [in] BufferSize        The number of bytes to read or write from the
> NVRAM device.
> +                                This must also be a multiple of NvramAccessSize.
> +  @param [in, out] pBuffer      A pointer to the data buffer.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_NvData (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN BOOLEAN ReadWrite,
> +  IN UINTN Offset,
> +  IN UINTN BufferSize,
> +  IN OUT VOID * pBuffer
> +  )
> +{
> +  EFI_STATUS Status;
> +  //
> +  // This is not currently supported
> +  //
> +  Status = EFI_UNSUPPORTED;
> +  return Status;
> +}
> +
> +VOID
> +FillPkt2Queue (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN UINTN BufLength)
> +{
> +
> +  UINT16 * pLength;
> +  UINT16 * pLengthBar;
> +  UINT8* pData;
> +  UINT32 offset;
> +  NIC_DEVICE * pNicDevice;
> +
> +  pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork);
> +  for ( offset = 0; offset < BufLength; ){
> +      pLength = (UINT16*) (pNicDevice->pBulkInBuff + offset);
> +      pLengthBar = (UINT16*) (pNicDevice->pBulkInBuff + offset +2);
> +
> +      *pLength &= 0x7ff;
> +      *pLengthBar &= 0x7ff;
> +      *pLengthBar |= 0xf800;
> +
> +      if ((*pLength ^ *pLengthBar ) != 0xFFFF) {
> +          DEBUG (( EFI_D_ERROR , "Pkt length error. BufLength = %d\n",
> BufLength));
> +          return;
> +      }
> +
> +      if (TRUE == pNicDevice->pNextFill->f_Used) {
> +        return;
> +      }
> +      else {
> +          pData = pNicDevice->pBulkInBuff + offset + 4;
> +          pNicDevice->pNextFill->f_Used = TRUE;
> +          pNicDevice->pNextFill->Length = *pLength;
> +          CopyMem (&pNicDevice->pNextFill->Data[0], pData, *pLength);
> +
> +          pNicDevice->pNextFill = pNicDevice->pNextFill->pNext;
> +          offset += ((*pLength + HW_HDR_LENGTH - 1) &~3) + 1;
> +          pNicDevice->PktCntInQueue++;
> +      }
> +
> +  }
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +SN_Receive (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  OUT UINTN                      * pHeaderSize,
> +  OUT UINTN                      * pBufferSize,
> +  OUT VOID                       * pBuffer,
> +  OUT EFI_MAC_ADDRESS            * pSrcAddr,
> +  OUT EFI_MAC_ADDRESS            * pDestAddr,
> +  OUT UINT16                     * pProtocol
> +  )
> +{
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  NIC_DEVICE * pNicDevice;
> +  EFI_STATUS Status;
> +  EFI_TPL TplPrevious;
> +  UINT16 Type;
> +  EFI_USB_IO_PROTOCOL *pUsbIo;
> +  UINTN LengthInBytes;
> +  UINT32 TransferStatus;
> +  RX_PKT * pFirstFill;
> +  TplPrevious = gBS->RaiseTPL (TPL_CALLBACK);
> +
> +  //
> +  // Verify the parameters
> +  //
> +  if (( NULL != pSimpleNetwork ) &&
> +    ( NULL != pSimpleNetwork->Mode ) &&
> +    (NULL != pBufferSize) &&
> +    (NULL != pBuffer)) {
> +    //
> +    // The interface must be running
> +    //
> +    pMode = pSimpleNetwork->Mode;
> +    if ( EfiSimpleNetworkInitialized == pMode->State ) {
> +      //
> +      // Update the link status
> +      //
> +      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> +      pNicDevice->LinkIdleCnt++;
> +      pMode->MediaPresent = pNicDevice->bLinkUp;
> +
> +      if ( pMode->MediaPresent && pNicDevice->bComplete) {
> +
> +
> +        if (pNicDevice->PktCntInQueue != 0 ) {
> +            DEBUG (( EFI_D_INFO, "pNicDevice->PktCntInQueue = %d\n",
> +                pNicDevice->PktCntInQueue));
> +        }
> +
> +        LengthInBytes = MAX_BULKIN_SIZE;
> +        if (pNicDevice->PktCntInQueue == 0 ){
> +            //
> +            // Attempt to do bulk in
> +            //
> +            SetMem (&pNicDevice->pBulkInBuff[0], 4, 0);
> +            pUsbIo = pNicDevice->pUsbIo;
> +            Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
> +                                       USB_ENDPOINT_DIR_IN | BULK_IN_ENDPOINT,
> +                                       &pNicDevice->pBulkInBuff[0],
> +                                       &LengthInBytes,
> +                                       BULKIN_TIMEOUT,
> +                                       &TransferStatus );
> +
> +            if (LengthInBytes != 0 && !EFI_ERROR(Status)
> && !EFI_ERROR(TransferStatus) ){
> +                FillPkt2Queue(pSimpleNetwork, LengthInBytes);
> +            }
> +        }
> +
> +        pFirstFill = pNicDevice->pFirstFill;
> +
> +        if (TRUE == pFirstFill->f_Used) {
> +            ETHERNET_HEADER * pHeader;
> +            pNicDevice->LinkIdleCnt = 0;
> +            CopyMem (pBuffer,  &pFirstFill->Data[0], pFirstFill->Length);
> +            pHeader = (ETHERNET_HEADER *) &pFirstFill->Data[0];
> +
> +            DEBUG (( EFI_D_INFO, "RX: %02x-%02x-%02x-%02x-%02x-%02x "
> +                      "%02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x  %d
> bytes\r\n",
> +                      pFirstFill->Data[0],
> +                      pFirstFill->Data[1],
> +                      pFirstFill->Data[2],
> +                      pFirstFill->Data[3],
> +                      pFirstFill->Data[4],
> +                      pFirstFill->Data[5],
> +                      pFirstFill->Data[6],
> +                      pFirstFill->Data[7],
> +                      pFirstFill->Data[8],
> +                      pFirstFill->Data[9],
> +                      pFirstFill->Data[10],
> +                      pFirstFill->Data[11],
> +                      pFirstFill->Data[12],
> +                      pFirstFill->Data[13],
> +                      pFirstFill->Length));
> +
> +            if ( NULL != pHeaderSize ) {
> +              *pHeaderSize = sizeof ( *pHeader );
> +            }
> +            if ( NULL != pDestAddr ) {
> +               CopyMem ( pDestAddr, &pHeader->dest_addr,
> PXE_HWADDR_LEN_ETHER );
> +            }
> +            if ( NULL != pSrcAddr ) {
> +             CopyMem ( pSrcAddr, &pHeader->src_addr,
> PXE_HWADDR_LEN_ETHER );
> +            }
> +            if ( NULL != pProtocol ) {
> +              Type = pHeader->type;
> +              Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
> +              *pProtocol = Type;
> +            }
> +            Status = EFI_SUCCESS;
> +            if (*pBufferSize < pFirstFill->Length) {
> +                  DEBUG (( EFI_D_ERROR, "RX: Buffer was too small"));
> +                  Status = EFI_BUFFER_TOO_SMALL;
> +            }
> +            *pBufferSize =  pFirstFill->Length;
> +            pFirstFill->f_Used = FALSE;
> +            pNicDevice->pFirstFill = pFirstFill->pNext;
> +            pNicDevice->PktCntInQueue--;
> +        }
> +        else {
> +            pNicDevice->LinkIdleCnt++;
> +            Status = EFI_NOT_READY;
> +        }
> +      }
> +      else {
> +        //
> +        //  Link no up
> +        //
> +        pNicDevice->LinkIdleCnt++;
> +        Status = EFI_NOT_READY;
> +      }
> +
> +    }
> +    else {
> +      if (EfiSimpleNetworkStarted == pMode->State) {
> +        Status = EFI_DEVICE_ERROR;
> +      }
> +      else {
> +        Status = EFI_NOT_STARTED;
> +      }
> +    }
> +  }
> +  else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +  gBS->RestoreTPL (TplPrevious);
> +  return Status;
> +}
> +
> +/**
> +  This function is used to enable and disable the hardware and software
> receive
> +  filters for the underlying network device.
> +
> +  The receive filter change is broken down into three steps:
> +
> +    1.  The filter mask bits that are set (ON) in the Enable parameter
> +        are added to the current receive filter settings.
> +
> +    2.  The filter mask bits that are set (ON) in the Disable parameter
> +        are subtracted from the updated receive filter settins.
> +
> +    3.  If the resulting filter settigns is not supported by the hardware
> +        a more liberal setting is selected.
> +
> +  If the same bits are set in the Enable and Disable parameters, then the bits
> +  in the Disable parameter takes precedence.
> +
> +  If the ResetMCastFilter parameter is TRUE, then the multicast address list
> +  filter is disabled (irregardless of what other multicast bits are set in
> +  the enable and Disable parameters).  The SNP->Mode->MCastFilterCount
> field
> +  is set to zero.  The SNP->Mode->MCastFilter contents are undefined.
> +
> +  After enableing or disabling receive filter settings, software should
> +  verify the new settings by checking the SNP->Mode-
> >ReceeiveFilterSettings,
> +  SNP->Mode->MCastFilterCount and SNP->Mode->MCastFilter fields.
> +
> +  Note: Some network drivers and/or devices will automatically promote
> +  receive filter settings if the requested setting can not be honored.
> +  For example, if a request for four multicast addresses is made and
> +  the underlying hardware only supports two multicast addresses the
> +  driver might set the promiscuous or promiscuous multicast receive filters
> +  instead.  The receiving software is responsible for discarding any extra
> +  packets that get through the hardware receive filters.
> +
> +  If ResetMCastFilter is TRUE, then the multicast receive filter list
> +  on the network interface will be reset to the default multicast receive
> +  filter list.  If ResetMCastFilter is FALSE, and this network interface
> +  allows the multicast receive filter list to be modified, then the
> +  MCastFilterCnt and MCastFilter are used to update the current multicast
> +  receive filter list.  The modified receive filter list settings can be
> +  found in the MCastFilter field of EFI_SIMPLE_NETWORK_MODE.
> +
> +  This routine calls ::ReceiveFilterUpdate to update the receive
> +  state in the network adapter.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] Enable            A bit mask of receive filters to enable on the
> network interface.
> +  @param [in] Disable           A bit mask of receive filters to disable on the
> network interface.
> +                                For backward compatibility with EFI 1.1 platforms, the
> +                                EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit must be
> set
> +                                when the ResetMCastFilter parameter is TRUE.
> +  @param [in] bResetMCastFilter Set to TRUE to reset the contents of the
> multicast receive
> +                                filters on the network interface to their default values.
> +  @param [in] MCastFilterCnt    Number of multicast HW MAC address in
> the new MCastFilter list.
> +                                This value must be less than or equal to the
> MaxMCastFilterCnt
> +                                field of EFI_SIMPLE_NETWORK_MODE.  This field is
> optional if
> +                                ResetMCastFilter is TRUE.
> +  @param [in] pMCastFilter      A pointer to a list of new multicast receive
> filter HW MAC
> +                                addresses.  This list will replace any existing multicast
> +                                HW MAC address list.  This field is optional if
> ResetMCastFilter
> +                                is TRUE.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_ReceiveFilters (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN UINT32 Enable,
> +  IN UINT32 Disable,
> +/*
> +#define EFI_SIMPLE_NETWORK_RECEIVE_UNICAST               0x01
> +#define EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST             0x02
> +#define EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST             0x04
> +#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS           0x08
> +#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST 0x10
> +*/
> +  IN BOOLEAN bResetMCastFilter,
> +  IN UINTN MCastFilterCnt,
> +  IN EFI_MAC_ADDRESS * pMCastFilter
> +  )
> +{
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  EFI_STATUS Status = EFI_SUCCESS;
> +  EFI_TPL TplPrevious;
> +
> +  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> +  pMode = pSimpleNetwork->Mode;
> +
> +  if (pSimpleNetwork == NULL) {
> +    gBS->RestoreTPL(TplPrevious);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  switch (pMode->State) {
> +    case EfiSimpleNetworkInitialized:
> +      break;
> +    case EfiSimpleNetworkStopped:
> +      Status = EFI_NOT_STARTED;
> +      gBS->RestoreTPL(TplPrevious);
> +      return Status;
> +    default:
> +      Status = EFI_DEVICE_ERROR;
> +      gBS->RestoreTPL(TplPrevious);
> +      return Status;
> +  }
> +
> +  //
> +  // check if we are asked to enable or disable something that the UNDI
> +  // does not even support!
> +  //
> +  if (((Enable &~pMode->ReceiveFilterMask) != 0) ||
> +    ((Disable &~pMode->ReceiveFilterMask) != 0)) {
> +    Status = EFI_INVALID_PARAMETER;
> +    gBS->RestoreTPL(TplPrevious);
> +    return Status;
> +  }
> +
> +  if (bResetMCastFilter) {
> +    Disable |= (EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST & pMode-
> >ReceiveFilterMask);
> +      pMode->MCastFilterCount = 0;
> +      if ( (0 == (pMode->ReceiveFilterSetting &
> EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST))
> +            && Enable == 0 && Disable == 2) {
> +            gBS->RestoreTPL(TplPrevious);
> +            return EFI_SUCCESS;
> +      }
> +  }
> +  else {
> +    if (MCastFilterCnt != 0) {
> +      UINTN i;
> +      EFI_MAC_ADDRESS * pMulticastAddress;
> +      pMulticastAddress =  pMCastFilter;
> +
> +      if ((MCastFilterCnt > pMode->MaxMCastFilterCount) ||
> +          (pMCastFilter == NULL)) {
> +        Status = EFI_INVALID_PARAMETER;
> +        gBS->RestoreTPL(TplPrevious);
> +        return Status;
> +      }
> +
> +      for ( i = 0 ; i < MCastFilterCnt ; i++ ) {
> +          UINT8  tmp;
> +          tmp = pMulticastAddress->Addr[0];
> +          if ( (tmp & 0x01) != 0x01 ) {
> +            gBS->RestoreTPL(TplPrevious);
> +            return EFI_INVALID_PARAMETER;
> +          }
> +          pMulticastAddress++;
> +      }
> +
> +      pMode->MCastFilterCount = (UINT32)MCastFilterCnt;
> +      CopyMem (&pMode->MCastFilter[0],
> +                     pMCastFilter,
> +                     MCastFilterCnt * sizeof ( EFI_MAC_ADDRESS));
> +    }
> +  }
> +
> +  if (Enable == 0 && Disable == 0 && !bResetMCastFilter && MCastFilterCnt
> == 0) {
> +    Status = EFI_SUCCESS;
> +    gBS->RestoreTPL(TplPrevious);
> +    return Status;
> +  }
> +
> +  if ((Enable & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0 &&
> MCastFilterCnt == 0) {
> +    Status = EFI_INVALID_PARAMETER;
> +    gBS->RestoreTPL(TplPrevious);
> +    return Status;
> +  }
> +
> +  pMode->ReceiveFilterSetting |= Enable;
> +  pMode->ReceiveFilterSetting &= ~Disable;
> +  Status = ReceiveFilterUpdate (pSimpleNetwork);
> +
> +  if (EFI_DEVICE_ERROR == Status || EFI_INVALID_PARAMETER == Status)
> +      Status = EFI_SUCCESS;
> +
> +  gBS->RestoreTPL(TplPrevious);
> +  return Status;
> +}
> +
> +/**
> +  Reset the network adapter.
> +
> +  Resets a network adapter and reinitializes it with the parameters that
> +  were provided in the previous call to Initialize ().  The transmit and
> +  receive queues are cleared.  Receive filters, the station address, the
> +  statistics, and the multicast-IP-to-HW MAC addresses are not reset by
> +  this call.
> +
> +  This routine calls ::Ax88772Reset to perform the adapter specific
> +  reset operation.  This routine also starts the link negotiation
> +  by calling ::Ax88772NegotiateLinkStart.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] bExtendedVerification  Indicates that the driver may perform
> a more
> +                                exhaustive verification operation of the device
> +                                during reset.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Reset (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN BOOLEAN bExtendedVerification
> +  )
> +{
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  NIC_DEVICE * pNicDevice;
> +  EFI_STATUS Status;
> +  EFI_TPL TplPrevious;
> +
> +  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> +  //
> +  //  Verify the parameters
> +  //
> +  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> +		pMode = pSimpleNetwork->Mode;
> +		if ( EfiSimpleNetworkInitialized == pMode->State ) {
> +    	//
> +    	//  Update the device state
> +    	//
> +    	pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> +    	pNicDevice->bComplete = FALSE;
> +    	pNicDevice->bLinkUp = FALSE;
> +    	pNicDevice->bHavePkt = FALSE;
> +    	pMode = pSimpleNetwork->Mode;
> +    	pMode->MediaPresent = FALSE;
> +
> +    	//
> +   		//  Reset the device
> +    	//
> +    	Status = Ax88772Reset ( pNicDevice );
> +    	if ( !EFI_ERROR ( Status )) {
> +     	 	//
> +     	 	//  Update the receive filters in the adapter
> +     	 	//
> +     	 	Status = ReceiveFilterUpdate ( pSimpleNetwork );
> +
> +     	 	//
> +     		 //  Try to get a connection to the network
> +     	 	//
> +     	 	if ( !EFI_ERROR ( Status )) {
> +        	//
> +        	//  Start the autonegotiation
> +       		//
> +        	Status = Ax88772NegotiateLinkStart ( pNicDevice );
> +     		}
> +   	 	}
> +   	}
> +   	else {
> +      if (EfiSimpleNetworkStarted == pMode->State) {
> +        Status = EFI_DEVICE_ERROR;
> +      }
> +      else {
> +        Status = EFI_NOT_STARTED;
> +      }
> +   	}
> +  }
> +  else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +  gBS->RestoreTPL ( TplPrevious );
> +  return Status;
> +}
> +
> +/**
> +  Initialize the simple network protocol.
> +
> +  This routine calls ::Ax88772MacAddressGet to obtain the
> +  MAC address.
> +
> +  @param [in] pNicDevice       NIC_DEVICE_INSTANCE pointer
> +
> +  @retval EFI_SUCCESS     Setup was successful
> +
> +**/
> +EFI_STATUS
> +SN_Setup (
> +  IN NIC_DEVICE * pNicDevice
> +  )
> +{
> +
> +
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork;
> +  EFI_STATUS Status;
> +  RX_PKT * pCurr = NULL;
> +  RX_PKT * pPrev = NULL;
> +
> +	pSimpleNetwork = &pNicDevice->SimpleNetwork;
> +  pSimpleNetwork->Revision =
> EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;
> +  pSimpleNetwork->Start = (EFI_SIMPLE_NETWORK_START)SN_Start;
> +  pSimpleNetwork->Stop = (EFI_SIMPLE_NETWORK_STOP)SN_Stop;
> +  pSimpleNetwork->Initialize =
> (EFI_SIMPLE_NETWORK_INITIALIZE)SN_Initialize;
> +  pSimpleNetwork->Reset = (EFI_SIMPLE_NETWORK_RESET)SN_Reset;
> +  pSimpleNetwork->Shutdown =
> (EFI_SIMPLE_NETWORK_SHUTDOWN)SN_Shutdown;
> +  pSimpleNetwork->ReceiveFilters =
> (EFI_SIMPLE_NETWORK_RECEIVE_FILTERS)SN_ReceiveFilters;
> +  pSimpleNetwork->StationAddress =
> (EFI_SIMPLE_NETWORK_STATION_ADDRESS)SN_StationAddress;
> +  pSimpleNetwork->Statistics =
> (EFI_SIMPLE_NETWORK_STATISTICS)SN_Statistics;
> +  pSimpleNetwork->MCastIpToMac =
> (EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC)SN_MCastIPtoMAC;
> +  pSimpleNetwork->NvData = (EFI_SIMPLE_NETWORK_NVDATA)SN_NvData;
> +  pSimpleNetwork->GetStatus =
> (EFI_SIMPLE_NETWORK_GET_STATUS)SN_GetStatus;
> +  pSimpleNetwork->Transmit =
> (EFI_SIMPLE_NETWORK_TRANSMIT)SN_Transmit;
> +  pSimpleNetwork->Receive = (EFI_SIMPLE_NETWORK_RECEIVE)SN_Receive;
> +  pSimpleNetwork->WaitForPacket = NULL;
> +  pMode = &pNicDevice->SimpleNetworkData;
> +  pSimpleNetwork->Mode = pMode;
> +  pMode->State = EfiSimpleNetworkStopped;
> +  pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
> +  pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
> +  pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
> +  pMode->NvRamSize = 0;
> +  pMode->NvRamAccessSize = 0;
> +  pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
> +                           | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
> +                           | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
> +                           | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
> +                           |
> EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
> +  pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
> +                              | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
> +  pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
> +  pMode->MCastFilterCount = 0;
> +  SetMem ( &pMode->BroadcastAddress,
> +           PXE_HWADDR_LEN_ETHER,
> +           0xff );
> +  pMode->IfType = EfiNetworkInterfaceUndi;
> +  pMode->MacAddressChangeable = TRUE;
> +  pMode->MultipleTxSupported = FALSE;
> +  pMode->MediaPresentSupported = TRUE;
> +  pMode->MediaPresent = FALSE;
> +  pNicDevice->LinkIdleCnt = 0;
> +  //
> +  //  Read the MAC address
> +  //
> +  pNicDevice->PhyId = PHY_ID_INTERNAL;
> +  pNicDevice->b100Mbps = TRUE;
> +  pNicDevice->bFullDuplex = TRUE;
> +
> +  Status = Ax88772MacAddressGet (
> +                pNicDevice,
> +                &pMode->PermanentAddress.Addr[0]);
> +
> +  if ( !EFI_ERROR ( Status )) {
> +    int i;
> +    //
> +    //  Use the hardware address as the current address
> +    //
> +
> +    CopyMem ( &pMode->CurrentAddress,
> +              &pMode->PermanentAddress,
> +              PXE_HWADDR_LEN_ETHER );
> +
> +    CopyMem ( &pNicDevice->MAC,
> +              &pMode->PermanentAddress,
> +              PXE_HWADDR_LEN_ETHER );
> +
> +    pNicDevice->PktCntInQueue = 0;
> +
> +    for ( i = 0 ; i < MAX_QUEUE_SIZE ; i++) {
> +        Status = gBS->AllocatePool ( EfiRuntimeServicesData,
> +                                      sizeof (RX_PKT),
> +                                      (VOID **) &pCurr);
> +        if ( EFI_ERROR(Status)) {
> +            DEBUG (( EFI_D_ERROR, "Memory are not enough\n"));
> +            return Status;
> +        }
> +        pCurr->f_Used = FALSE;
> +
> +        if ( i ) {
> +            pPrev->pNext = pCurr;
> +        }
> +        else {
> +            pNicDevice->QueueHead = pCurr;
> +        }
> +
> +        if (MAX_QUEUE_SIZE - 1 == i) {
> +            pCurr->pNext = pNicDevice->QueueHead;
> +        }
> +
> +        pPrev = pCurr;
> +    }
> +
> +    pNicDevice->pNextFill = pNicDevice->QueueHead;
> +    pNicDevice->pFirstFill = pNicDevice->QueueHead;
> +
> +    Status = gBS->AllocatePool (EfiRuntimeServicesData,
> +                                MAX_BULKIN_SIZE,
> +                                (VOID **) &pNicDevice->pBulkInBuff);
> +
> +    if (EFI_ERROR(Status)) {
> +        DEBUG (( EFI_D_ERROR, "gBS->AllocatePool for pBulkInBuff error.
> Status = %r\n",
> +              Status));
> +        return Status;
> +    }
> +  }
> +  else {
> +    DEBUG (( EFI_D_ERROR, "Ax88772MacAddressGet error. Status = %r\n",
> Status));
> +		return Status;
> +  }
> +
> +  Status = gBS->AllocatePool ( EfiRuntimeServicesData,
> +                                   sizeof ( RX_TX_PACKET ),
> +                                   (VOID **) &pNicDevice->pRxTest );
> +
> +  if (EFI_ERROR (Status)) {
> +    DEBUG (( EFI_D_ERROR, "gBS->AllocatePool:pNicDevice->pRxTest error.
> Status = %r\n",
> +              Status));
> +	  return Status;
> +  }
> +
> +  Status = gBS->AllocatePool ( EfiRuntimeServicesData,
> +                                   sizeof ( RX_TX_PACKET ),
> +                                   (VOID **) &pNicDevice->pTxTest );
> +
> +  if (EFI_ERROR (Status)) {
> +    DEBUG (( EFI_D_ERROR, "gBS->AllocatePool:pNicDevice->pTxTest error.
> Status = %r\n",
> +              Status));
> +	  gBS->FreePool (pNicDevice->pRxTest);
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  This routine starts the network interface.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_ALREADY_STARTED   The network interface was already
> started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Start (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> +  )
> +{
> +  NIC_DEVICE * pNicDevice;
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  EFI_STATUS Status;
> +  EFI_TPL TplPrevious;
> +  int i = 0;
> +  RX_PKT * pCurr = NULL;
> +
> +  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> +  //
> +  // Verify the parameters
> +  //
> +  Status = EFI_INVALID_PARAMETER;
> +  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> +    pMode = pSimpleNetwork->Mode;
> +    if ( EfiSimpleNetworkStopped == pMode->State ) {
> +      //
> +      // Initialize the mode structuref
> +      // NVRAM access is not supported
> +      //
> +      ZeroMem ( pMode, sizeof ( *pMode ));
> +
> +      pMode->State = EfiSimpleNetworkStarted;
> +      pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
> +      pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
> +      pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
> +      pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
> +                               | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
> +                               | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
> +                               | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
> +                               |
> EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
> +      pMode->ReceiveFilterSetting =
> EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
> +      pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
> +      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> +      Status = Ax88772MacAddressGet ( pNicDevice, &pMode-
> >PermanentAddress.Addr[0]);
> +      CopyMem ( &pMode->CurrentAddress,
> +                &pMode->PermanentAddress,
> +                sizeof ( pMode->CurrentAddress ));
> +      SetMem(&pMode->BroadcastAddress, PXE_HWADDR_LEN_ETHER, 0xff);
> +      pMode->IfType = EfiNetworkInterfaceUndi;
> +      pMode->MacAddressChangeable = TRUE;
> +      pMode->MultipleTxSupported = FALSE;
> +      pMode->MediaPresentSupported = TRUE;
> +      pMode->MediaPresent = FALSE;
> +      pNicDevice->PktCntInQueue = 0;
> +      pNicDevice->pNextFill = pNicDevice->QueueHead;
> +      pNicDevice->pFirstFill = pNicDevice->QueueHead;
> +      pCurr = pNicDevice->QueueHead;
> +
> +      for ( i = 0 ; i < MAX_QUEUE_SIZE ; i++) {
> +        pCurr->f_Used = FALSE;
> +        pCurr = pCurr->pNext;
> +      }
> +
> +    }
> +    else {
> +      Status = EFI_ALREADY_STARTED;
> +    }
> +  }
> +  gBS->RestoreTPL ( TplPrevious );
> +  return Status;
> +}
> +
> +
> +/**
> +  Set the MAC address.
> +
> +  This function modifies or resets the current station address of a
> +  network interface.  If Reset is TRUE, then the current station address
> +  is set ot the network interface's permanent address.  If Reset if FALSE
> +  then the current station address is changed to the address specified by
> +  pNew.
> +
> +  This routine calls ::Ax88772MacAddressSet to update the MAC address
> +  in the network adapter.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] bReset            Flag used to reset the station address to the
> +                                network interface's permanent address.
> +  @param [in] pNew              New station address to be used for the network
> +                                interface.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_StationAddress (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN BOOLEAN bReset,
> +  IN EFI_MAC_ADDRESS * pNew
> +  )
> +{
> +  NIC_DEVICE * pNicDevice;
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  EFI_STATUS Status;
> +  EFI_TPL TplPrevious;
> +
> +  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> +  //
> +  // Verify the parameters
> +  //
> +  if (( NULL != pSimpleNetwork )
> +    && ( NULL != pSimpleNetwork->Mode )
> +    && (( bReset ) || ( ( !bReset) && ( NULL != pNew )))) {
> +    //
> +    // Verify that the adapter is already started
> +    //
> +    pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> +    pMode = pSimpleNetwork->Mode;
> +    if ( EfiSimpleNetworkInitialized == pMode->State ) {
> +      //
> +      // Determine the adapter MAC address
> +      //
> +      if ( bReset ) {
> +        //
> +        // Use the permanent address
> +        //
> +        CopyMem ( &pMode->CurrentAddress,
> +                  &pMode->PermanentAddress,
> +                  sizeof ( pMode->CurrentAddress ));
> +      }
> +      else {
> +        //
> +        // Use the specified address
> +        //
> +        CopyMem ( &pMode->CurrentAddress,
> +                  pNew,
> +                  sizeof ( pMode->CurrentAddress ));
> +      }
> +
> +      //
> +      // Update the address on the adapter
> +      //
> +      Status = Ax88772MacAddressSet ( pNicDevice, &pMode-
> >CurrentAddress.Addr[0]);
> +    }
> +    else {
> +      if (EfiSimpleNetworkStarted == pMode->State) {
> +        Status = EFI_DEVICE_ERROR;
> +      }
> +      else {
> +        Status = EFI_NOT_STARTED;
> +      }
> +    }
> +  }
> +  else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +  gBS->RestoreTPL ( TplPrevious );
> +  return Status;
> +}
> +
> +
> +/**
> +  This function resets or collects the statistics on a network interface.
> +  If the size of the statistics table specified by StatisticsSize is not
> +  big enough for all of the statistics that are collected by the network
> +  interface, then a partial buffer of statistics is returned in
> +  StatisticsTable.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] bReset            Set to TRUE to reset the statistics for the
> network interface.
> +  @param [in, out] pStatisticsSize  On input the size, in bytes, of
> StatisticsTable.  On output
> +                                the size, in bytes, of the resulting table of statistics.
> +  @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS
> structure that
> +                                conains the statistics.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_BUFFER_TOO_SMALL  The pStatisticsTable is NULL or the
> buffer is too small.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +  typedef struct {
> +  UINT64 RxTotalFrames;
> +  UINT64 RxGoodFrames;
> +  UINT64 RxUndersizeFrames;
> +  UINT64 RxOversizeFrames;
> +  UINT64 RxDroppedFrames;
> +  UINT64 RxUnicastFrames;
> +  UINT64 RxBroadcastFrames;
> +  UINT64 RxMulticastFrames;
> +  UINT64 RxCrcErrorFrames;
> +  UINT64 RxTotalBytes;
> +  UINT64 TxTotalFrames;
> +  UINT64 TxGoodFrames;
> +  UINT64 TxUndersizeFrames;
> +  UINT64 TxOversizeFrames;
> +  UINT64 TxDroppedFrames;
> +  UINT64 TxUnicastFrames;
> +  UINT64 TxBroadcastFrames;
> +  UINT64 TxMulticastFrames;
> +  UINT64 TxCrcErrorFrames;
> +  UINT64 TxTotalBytes;
> +  UINT64 Collisions;
> +  UINT64 UnsupportedProtocol;
> +  } EFI_NETWORK_STATISTICS;
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Statistics (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN BOOLEAN bReset,
> +  IN OUT UINTN * pStatisticsSize,
> +  OUT EFI_NETWORK_STATISTICS * pStatisticsTable
> +  )
> +{
> +  EFI_STATUS Status;
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  //
> +  // Verify the prarameters
> +  //
> +  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> +    pMode = pSimpleNetwork->Mode;
> +    //
> +    // Determine if the interface is started
> +    //
> +    if (EfiSimpleNetworkInitialized == pMode->State){
> +      //
> +      // Determine if the StatisticsSize is big enough
> +      //
> +      if (sizeof (EFI_NETWORK_STATISTICS) <= *pStatisticsSize){
> +        if (bReset) {
> +          Status = EFI_SUCCESS;
> +        }
> +        else {
> +          Status = EFI_UNSUPPORTED;
> +        }
> +      }
> +      else {
> +        Status = EFI_BUFFER_TOO_SMALL;
> +      }
> +    }
> +    else{
> +      if (EfiSimpleNetworkStarted == pMode->State) {
> +        Status = EFI_DEVICE_ERROR;
> +      }
> +      else {
> +        Status = EFI_NOT_STARTED;
> +      }
> +    }
> +  }
> +  else {
> +  	Status = EFI_INVALID_PARAMETER;
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  This function stops a network interface.  This call is only valid
> +  if the network interface is in the started state.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Stop (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> +  )
> +{
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  EFI_STATUS Status;
> +  EFI_TPL TplPrevious;
> +
> +  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> +  //
> +  // Verify the parameters
> +  //
> +  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> +    //
> +    // Determine if the interface is started
> +    //
> +    pMode = pSimpleNetwork->Mode;
> +    if ( EfiSimpleNetworkStarted == pMode->State ) {
> +        pMode->State = EfiSimpleNetworkStopped;
> +        Status = EFI_SUCCESS;
> +    }
> +    else {
> +        Status = EFI_NOT_STARTED;
> +    }
> +  }
> +  else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +
> +  gBS->RestoreTPL ( TplPrevious );
> +  return Status;
> +}
> +
> +
> +/**
> +  This function releases the memory buffers assigned in the Initialize() call.
> +  Pending transmits and receives are lost, and interrupts are cleared and
> disabled.
> +  After this call, only Initialize() and Stop() calls may be used.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +  @retval EFI_UNSUPPORTED       The increased buffer size feature is not
> supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Shutdown (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> +  )
> +{
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  UINT32 RxFilter;
> +  EFI_STATUS Status;
> +  EFI_TPL TplPrevious;
> +
> +  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> +  //
> +  // Verify the parameters
> +  //
> +  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> +    //
> +    // Determine if the interface is already started
> +    //
> +    pMode = pSimpleNetwork->Mode;
> +    if ( EfiSimpleNetworkInitialized == pMode->State ) {
> +      //
> +      // Stop the adapter
> +      //
> +      RxFilter = pMode->ReceiveFilterSetting;
> +      pMode->ReceiveFilterSetting = 0;
> +      Status = SN_Reset ( pSimpleNetwork, FALSE );
> +      pMode->ReceiveFilterSetting = RxFilter;
> +      if ( !EFI_ERROR ( Status )) {
> +
> +        //
> +        // Update the network state
> +        //
> +        pMode->State = EfiSimpleNetworkStarted;
> +      }
> +      else if ( EFI_DEVICE_ERROR == Status ) {
> +      	pMode->State = EfiSimpleNetworkStopped;
> +      }
> +    }
> +    else {
> +      Status = EFI_NOT_STARTED;
> +    }
> +  }
> +  else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +  gBS->RestoreTPL ( TplPrevious );
> +  return Status;
> +}
> +
> +
> +/**
> +  Send a packet over the network.
> +
> +  This function places the packet specified by Header and Buffer on
> +  the transmit queue.  This function performs a non-blocking transmit
> +  operation.  When the transmit is complete, the buffer is returned
> +  via the GetStatus() call.
> +
> +  This routine calls ::Ax88772Rx to empty the network adapter of
> +  receive packets.  The routine then passes the transmit packet
> +  to the network adapter.
> +
> +  @param [in] pSimpleNetwork    Protocol instance pointer
> +  @param [in] HeaderSize        The size, in bytes, of the media header to be
> filled in by
> +                                the Transmit() function.  If HeaderSize is non-zero, then
> +                                it must be equal to SimpleNetwork->Mode-
> >MediaHeaderSize
> +                                and DestAddr and Protocol parameters must not be NULL.
> +  @param [in] BufferSize        The size, in bytes, of the entire packet (media
> header and
> +                                data) to be transmitted through the network interface.
> +  @param [in] pBuffer           A pointer to the packet (media header followed
> by data) to
> +                                to be transmitted.  This parameter can not be NULL.  If
> +                                HeaderSize is zero, then the media header is Buffer must
> +                                already be filled in by the caller.  If HeaderSize is nonzero,
> +                                then the media header will be filled in by the Transmit()
> +                                function.
> +  @param [in] pSrcAddr          The source HW MAC address.  If HeaderSize is
> zero, then
> +                                this parameter is ignored.  If HeaderSize is nonzero and
> +                                SrcAddr is NULL, then SimpleNetwork->Mode-
> >CurrentAddress
> +                                is used for the source HW MAC address.
> +  @param [in] pDestAddr         The destination HW MAC address.  If
> HeaderSize is zero, then
> +                                this parameter is ignored.
> +  @param [in] pProtocol         The type of header to build.  If HeaderSize is
> zero, then
> +                                this parameter is ignored.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_NOT_READY         The network interface is too busy to accept
> this transmit request.
> +  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
> +  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL
> or did not point to a valid
> +                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> +  @retval EFI_DEVICE_ERROR      The command could not be sent to the
> network interface.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SN_Transmit (
> +  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> +  IN UINTN HeaderSize,
> +  IN UINTN BufferSize,
> +  IN VOID * pBuffer,
> +  IN EFI_MAC_ADDRESS * pSrcAddr,
> +  IN EFI_MAC_ADDRESS * pDestAddr,
> +  IN UINT16 * pProtocol
> +  )
> +{
> +  ETHERNET_HEADER * pHeader;
> +  EFI_SIMPLE_NETWORK_MODE * pMode;
> +  NIC_DEVICE * pNicDevice;
> +  EFI_USB_IO_PROTOCOL * pUsbIo;
> +  EFI_STATUS Status;
> +  UINTN TransferLength;
> +  UINT32 TransferStatus;
> +  UINT16 Type;
> +  EFI_TPL TplPrevious;
> +
> +  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> +
> +  // Verify the parameters
> +  //
> +  if (( NULL != pSimpleNetwork ) &&
> +      ( NULL != pSimpleNetwork->Mode ) &&
> +      ( NULL != pBuffer) &&
> +      ( (HeaderSize == 0) || ( (NULL != pDestAddr) && (NULL != pProtocol) ))) {
> +    //
> +    // The interface must be running
> +    //
> +    pMode = pSimpleNetwork->Mode;
> +    //
> +    // Verify parameter of HeaderSize
> +    //
> +    if ((HeaderSize == 0) || (HeaderSize == pMode->MediaHeaderSize)){
> +      //
> +      // Determine if BufferSize is big enough
> +      //
> +      if (BufferSize >= pMode->MediaHeaderSize){
> +        if ( EfiSimpleNetworkInitialized == pMode->State ) {
> +          //
> +          // Update the link status
> +          //
> +          pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> +          pMode->MediaPresent = pNicDevice->bLinkUp;
> +
> +          //
> +          //  Release the synchronization with Ax88772Timer
> +          //
> +          if ( pMode->MediaPresent && pNicDevice->bComplete) {
> +            //
> +            //  Copy the packet into the USB buffer
> +            //
> +
> +            CopyMem ( &pNicDevice->pTxTest->Data[0], pBuffer, BufferSize );
> +            pNicDevice->pTxTest->Length = (UINT16) BufferSize;
> +
> +            //
> +            //  Transmit the packet
> +            //
> +            pHeader = (ETHERNET_HEADER *) &pNicDevice->pTxTest->Data[0];
> +            if ( 0 != HeaderSize ) {
> +              if ( NULL != pDestAddr ) {
> +                CopyMem ( &pHeader->dest_addr, pDestAddr,
> PXE_HWADDR_LEN_ETHER );
> +              }
> +              if ( NULL != pSrcAddr ) {
> +                CopyMem ( &pHeader->src_addr, pSrcAddr,
> PXE_HWADDR_LEN_ETHER );
> +              }
> +              else {
> +                CopyMem ( &pHeader->src_addr, &pMode-
> >CurrentAddress.Addr[0], PXE_HWADDR_LEN_ETHER );
> +              }
> +              if ( NULL != pProtocol ) {
> +                Type = *pProtocol;
> +              }
> +              else {
> +                Type = pNicDevice->pTxTest->Length;
> +              }
> +              Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
> +              pHeader->type = Type;
> +            }
> +            if ( pNicDevice->pTxTest->Length < MIN_ETHERNET_PKT_SIZE ) {
> +              pNicDevice->pTxTest->Length = MIN_ETHERNET_PKT_SIZE;
> +              ZeroMem ( &pNicDevice->pTxTest->Data[ BufferSize ],
> +                        pNicDevice->pTxTest->Length - BufferSize );
> +            }
> +
> +            DEBUG ((EFI_D_INFO, "TX: %02x-%02x-%02x-%02x-%02x-
> %02x  %02x-%02x-%02x-%02x-%02x-%02x"
> +                      "  %02x-%02x  %d bytes\r\n",
> +                      pNicDevice->pTxTest->Data[0],
> +                      pNicDevice->pTxTest->Data[1],
> +                      pNicDevice->pTxTest->Data[2],
> +                      pNicDevice->pTxTest->Data[3],
> +                      pNicDevice->pTxTest->Data[4],
> +                      pNicDevice->pTxTest->Data[5],
> +                      pNicDevice->pTxTest->Data[6],
> +                      pNicDevice->pTxTest->Data[7],
> +                      pNicDevice->pTxTest->Data[8],
> +                      pNicDevice->pTxTest->Data[9],
> +                      pNicDevice->pTxTest->Data[10],
> +                      pNicDevice->pTxTest->Data[11],
> +                      pNicDevice->pTxTest->Data[12],
> +                      pNicDevice->pTxTest->Data[13],
> +                      pNicDevice->pTxTest->Length ));
> +
> +            pNicDevice->pTxTest->LengthBar = ~(pNicDevice->pTxTest->Length);
> +            TransferLength = sizeof ( pNicDevice->pTxTest->Length )
> +                           + sizeof ( pNicDevice->pTxTest->LengthBar )
> +                           + pNicDevice->pTxTest->Length;
> +
> +            if (TransferLength % 512 == 0 || TransferLength % 1024 == 0)
> +                TransferLength +=4;
> +
> +            //
> +            //  Work around USB bus driver bug where a timeout set by receive
> +            //  succeeds but the timeout expires immediately after, causing the
> +            //  transmit operation to timeout.
> +            //
> +            pUsbIo = pNicDevice->pUsbIo;
> +            Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
> +                                               BULK_OUT_ENDPOINT,
> +                                               &pNicDevice->pTxTest->Length,
> +                                               &TransferLength,
> +                                               0xfffffffe,
> +                                               &TransferStatus );
> +            if ( !EFI_ERROR ( Status )) {
> +              Status = TransferStatus;
> +            }
> +
> +            if ( !EFI_ERROR ( Status )) {
> +              pNicDevice->pTxBuffer = pBuffer;
> +            }
> +            else {
> +              if ((TransferLength != (UINTN)( pNicDevice->pTxTest->Length + 4 ))
> &&
> +                   (TransferLength != (UINTN)(( pNicDevice->pTxTest->Length + 4 )
> + 4))) {
> +                DEBUG ((EFI_D_INFO, "TransferLength didn't match Packet
> Length\n"));
> +              }
> +              //
> +              //  Reset the controller to fix the error
> +              //
> +              if ( EFI_DEVICE_ERROR == Status ) {
> +                SN_Reset ( pSimpleNetwork, FALSE );
> +              }
> +              Status = EFI_NOT_READY;
> +            }
> +          }
> +          else {
> +            //
> +            // No packets available.
> +            //
> +            Status = EFI_NOT_READY;
> +          }
> +
> +        }
> +        else {
> +          if (EfiSimpleNetworkStarted == pMode->State) {
> +            Status = EFI_DEVICE_ERROR;
> +          }
> +          else {
> +            Status = EFI_NOT_STARTED ;
> +          }
> +        }
> +      }
> +      else {
> +        Status = EFI_BUFFER_TOO_SMALL;
> +      }
> +    }
> +    else {
> +      Status = EFI_INVALID_PARAMETER;
> +    }
> +  }
> +  else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +
> +  gBS->RestoreTPL (TplPrevious);
> +
> +  return Status;
> +}
> diff --git a/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.c
> b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.c
> new file mode 100644
> index 0000000000..4e7830ea94
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.c
> @@ -0,0 +1,917 @@
> +/** @file
> +  Cirrus Logic 5430 Controller Driver.
> +  This driver is a sample implementation of the UGA Draw and Graphics
> Output
> +  Protocols for the Cirrus Logic 5430 family of PCI video controllers.
> +  This driver is only usable in the EFI pre-boot environment.
> +  This sample is intended to show how the UGA Draw and Graphics output
> Protocol
> +  is able to function.
> +  The UGA I/O Protocol is not implemented in this sample.
> +  A fully compliant EFI UGA driver requires both
> +  the UGA Draw and the UGA I/O Protocol.  Please refer to Microsoft's
> +  documentation on UGA for details on how to write a UGA driver that is
> able
> +  to function both in the EFI pre-boot environment and from the OS
> runtime.
> +
> +  Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +//
> +// Cirrus Logic 5430 Controller Driver
> +//
> +#include "CirrusLogic5430.h"
> +
> +EFI_DRIVER_BINDING_PROTOCOL gCirrusLogic5430DriverBinding = {
> +  CirrusLogic5430ControllerDriverSupported,
> +  CirrusLogic5430ControllerDriverStart,
> +  CirrusLogic5430ControllerDriverStop,
> +  0x10,
> +  NULL,
> +  NULL
> +};
> +
> +///
> +/// Generic Attribute Controller Register Settings
> +///
> +UINT8  AttributeController[21] = {
> +  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
> +  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
> +  0x41, 0x00, 0x0F, 0x00, 0x00
> +};
> +
> +///
> +/// Generic Graphics Controller Register Settings
> +///
> +UINT8 GraphicsController[9] = {
> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF
> +};
> +
> +//
> +// 640 x 480 x 256 color @ 60 Hertz
> +//
> +UINT8 Crtc_640_480_256_60[28] = {
> +  0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e,
> +  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +  0xe1, 0x83, 0xdf, 0x50, 0x00, 0xe7, 0x04, 0xe3,
> +  0xff, 0x00, 0x00, 0x22
> +};
> +
> +UINT16 Seq_640_480_256_60[15] = {
> +  0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
> +  0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e
> +};
> +
> +//
> +// 800 x 600 x 256 color @ 60 Hertz
> +//
> +UINT8 Crtc_800_600_256_60[28] = {
> +  0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0,
> +  0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +  0x58, 0x8C, 0x57, 0x64, 0x00, 0x5F, 0x91, 0xE3,
> +  0xFF, 0x00, 0x00, 0x22
> +};
> +
> +UINT16 Seq_800_600_256_60[15] = {
> +  0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
> +  0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e
> +};
> +
> +//
> +// 1024 x 768 x 256 color @ 60 Hertz
> +//
> +UINT8 Crtc_1024_768_256_60[28] = {
> +  0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,
> +  0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +  0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3,
> +  0xFF, 0x4A, 0x00, 0x22
> +};
> +
> +UINT16 Seq_1024_768_256_60[15] = {
> +  0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
> +  0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e
> +};
> +
> +///
> +/// Table of supported video modes
> +///
> +CIRRUS_LOGIC_5430_VIDEO_MODES  CirrusLogic5430VideoModes[] = {
> +  {  640, 480, 8, 60, Crtc_640_480_256_60,  Seq_640_480_256_60,  0xe3 },
> +  {  800, 600, 8, 60, Crtc_800_600_256_60,  Seq_800_600_256_60,  0xef },
> +  { 1024, 768, 8, 60, Crtc_1024_768_256_60, Seq_1024_768_256_60, 0xef }
> +};
> +
> +
> +/**
> +  CirrusLogic5430ControllerDriverSupported
> +
> +  TODO:    This - add argument and description to function comment
> +  TODO:    Controller - add argument and description to function comment
> +  TODO:    RemainingDevicePath - add argument and description to function
> comment
> +**/
> +EFI_STATUS
> +EFIAPI
> +CirrusLogic5430ControllerDriverSupported (
> +  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
> +  IN EFI_HANDLE                     Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
> +  )
> +{
> +  EFI_STATUS          Status;
> +  EFI_PCI_IO_PROTOCOL *PciIo;
> +  PCI_TYPE00          Pci;
> +  EFI_DEV_PATH        *Node;
> +
> +  //
> +  // Open the PCI I/O Protocol
> +  //
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiPciIoProtocolGuid,
> +                  (VOID **) &PciIo,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Read the PCI Configuration Header from the PCI Device
> +  //
> +  Status = PciIo->Pci.Read (
> +                        PciIo,
> +                        EfiPciIoWidthUint32,
> +                        0,
> +                        sizeof (Pci) / sizeof (UINT32),
> +                        &Pci
> +                        );
> +  if (EFI_ERROR (Status)) {
> +    goto Done;
> +  }
> +
> +  Status = EFI_UNSUPPORTED;
> +  //
> +  // See if the I/O enable is on.  Most systems only allow one VGA device to
> be turned on
> +  // at a time, so see if this is one that is turned on.
> +  //
> +  //  if (((Pci.Hdr.Command & 0x01) == 0x01)) {
> +  //
> +  // See if this is a Cirrus Logic PCI controller
> +  //
> +  if (Pci.Hdr.VendorId == CIRRUS_LOGIC_VENDOR_ID) {
> +    //
> +    // See if this is a 5430 or a 5446 PCI controller
> +    //
> +    if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_DEVICE_ID ||
> +        Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID ||
> +        Pci.Hdr.DeviceId == CIRRUS_LOGIC_5446_DEVICE_ID) {
> +
> +      Status = EFI_SUCCESS;
> +      //
> +      // If this is an Intel 945 graphics controller,
> +      // go further check RemainingDevicePath validation
> +      //
> +      if (RemainingDevicePath != NULL) {
> +        Node = (EFI_DEV_PATH *) RemainingDevicePath;
> +        //
> +        // Check if RemainingDevicePath is the End of Device Path Node,
> +        // if yes, return EFI_SUCCESS
> +        //
> +        if (!IsDevicePathEnd (Node)) {
> +          //
> +          // If RemainingDevicePath isn't the End of Device Path Node,
> +          // check its validation
> +          //
> +          if (Node->DevPath.Type != ACPI_DEVICE_PATH ||
> +              Node->DevPath.SubType != ACPI_ADR_DP ||
> +              DevicePathNodeLength(&Node->DevPath) !=
> sizeof(ACPI_ADR_DEVICE_PATH)) {
> +            Status = EFI_UNSUPPORTED;
> +          }
> +        }
> +      }
> +    }
> +  }
> +
> +Done:
> +  //
> +  // Close the PCI I/O Protocol
> +  //
> +  gBS->CloseProtocol (
> +        Controller,
> +        &gEfiPciIoProtocolGuid,
> +        This->DriverBindingHandle,
> +        Controller
> +        );
> +
> +  return Status;
> +}
> +
> +/**
> +  CirrusLogic5430ControllerDriverStart
> +
> +  TODO:    This - add argument and description to function comment
> +  TODO:    Controller - add argument and description to function comment
> +  TODO:    RemainingDevicePath - add argument and description to function
> comment
> +**/
> +EFI_STATUS
> +EFIAPI
> +CirrusLogic5430ControllerDriverStart (
> +  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
> +  IN EFI_HANDLE                     Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;
> +  BOOLEAN                         PciAttributesSaved;
> +  EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath;
> +  ACPI_ADR_DEVICE_PATH            AcpiDeviceNode;
> +  UINT64                          Supports;
> +
> +  PciAttributesSaved = FALSE;
> +  //
> +  // Allocate Private context data for UGA Draw inteface.
> +  //
> +  Private = AllocateZeroPool (sizeof (CIRRUS_LOGIC_5430_PRIVATE_DATA));
> +  if (Private == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto Error;
> +  }
> +
> +  //
> +  // Set up context record
> +  //
> +  Private->Signature  = CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE;
> +  Private->Handle     = NULL;
> +
> +  //
> +  // Open PCI I/O Protocol
> +  //
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiPciIoProtocolGuid,
> +                  (VOID **) &Private->PciIo,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    goto Error;
> +  }
> +
> +  //
> +  // Get supported PCI attributes
> +  //
> +  Status = Private->PciIo->Attributes (
> +                             Private->PciIo,
> +                             EfiPciIoAttributeOperationSupported,
> +                             0,
> +                             &Supports
> +                             );
> +  if (EFI_ERROR (Status)) {
> +    goto Error;
> +  }
> +
> +  Supports &= (EFI_PCI_IO_ATTRIBUTE_VGA_IO |
> EFI_PCI_IO_ATTRIBUTE_VGA_IO_16);
> +  if (Supports == 0 || Supports == (EFI_PCI_IO_ATTRIBUTE_VGA_IO |
> EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) {
> +    Status = EFI_UNSUPPORTED;
> +    goto Error;
> +  }
> +
> +  //
> +  // Save original PCI attributes
> +  //
> +  Status = Private->PciIo->Attributes (
> +                    Private->PciIo,
> +                    EfiPciIoAttributeOperationGet,
> +                    0,
> +                    &Private->OriginalPciAttributes
> +                    );
> +
> +  if (EFI_ERROR (Status)) {
> +    goto Error;
> +  }
> +  PciAttributesSaved = TRUE;
> +
> +  Status = Private->PciIo->Attributes (
> +                             Private->PciIo,
> +                             EfiPciIoAttributeOperationEnable,
> +                             EFI_PCI_DEVICE_ENABLE |
> EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | Supports,
> +                             NULL
> +                             );
> +  if (EFI_ERROR (Status)) {
> +    goto Error;
> +  }
> +
> +  //
> +  // Get ParentDevicePath
> +  //
> +  Status = gBS->HandleProtocol (
> +                  Controller,
> +                  &gEfiDevicePathProtocolGuid,
> +                  (VOID **) &ParentDevicePath
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    goto Error;
> +  }
> +
> +  if (FeaturePcdGet (PcdSupportGop)) {
> +    //
> +    // Set Gop Device Path
> +    //
> +    if (RemainingDevicePath == NULL) {
> +      ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH));
> +      AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH;
> +      AcpiDeviceNode.Header.SubType = ACPI_ADR_DP;
> +      AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0,
> ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0);
> +      SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof
> (ACPI_ADR_DEVICE_PATH));
> +
> +      Private->GopDevicePath = AppendDevicePathNode (
> +                                          ParentDevicePath,
> +                                          (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode
> +                                          );
> +    } else if (!IsDevicePathEnd (RemainingDevicePath)) {
> +      //
> +      // If RemainingDevicePath isn't the End of Device Path Node,
> +      // only scan the specified device by RemainingDevicePath
> +      //
> +      Private->GopDevicePath = AppendDevicePathNode (ParentDevicePath,
> RemainingDevicePath);
> +    } else {
> +      //
> +      // If RemainingDevicePath is the End of Device Path Node,
> +      // don't create child device and return EFI_SUCCESS
> +      //
> +      Private->GopDevicePath = NULL;
> +    }
> +
> +    if (Private->GopDevicePath != NULL) {
> +      //
> +      // Creat child handle and device path protocol firstly
> +      //
> +      Private->Handle = NULL;
> +      Status = gBS->InstallMultipleProtocolInterfaces (
> +                      &Private->Handle,
> +                      &gEfiDevicePathProtocolGuid,
> +                      Private->GopDevicePath,
> +                      NULL
> +                      );
> +    }
> +  }
> +
> +  //
> +  // Construct video mode buffer
> +  //
> +  Status = CirrusLogic5430VideoModeSetup (Private);
> +  if (EFI_ERROR (Status)) {
> +    goto Error;
> +  }
> +
> +  if (FeaturePcdGet (PcdSupportUga)) {
> +    //
> +    // Start the UGA Draw software stack.
> +    //
> +    Status = CirrusLogic5430UgaDrawConstructor (Private);
> +    ASSERT_EFI_ERROR (Status);
> +
> +    Private->UgaDevicePath = ParentDevicePath;
> +    Status = gBS->InstallMultipleProtocolInterfaces (
> +                    &Controller,
> +                    &gEfiUgaDrawProtocolGuid,
> +                    &Private->UgaDraw,
> +                    &gEfiDevicePathProtocolGuid,
> +                    Private->UgaDevicePath,
> +                    NULL
> +                    );
> +
> +  } else if (FeaturePcdGet (PcdSupportGop)) {
> +    if (Private->GopDevicePath == NULL) {
> +      //
> +      // If RemainingDevicePath is the End of Device Path Node,
> +      // don't create child device and return EFI_SUCCESS
> +      //
> +      Status = EFI_SUCCESS;
> +    } else {
> +
> +      //
> +      // Start the GOP software stack.
> +      //
> +      Status = CirrusLogic5430GraphicsOutputConstructor (Private);
> +      ASSERT_EFI_ERROR (Status);
> +
> +      Status = gBS->InstallMultipleProtocolInterfaces (
> +                      &Private->Handle,
> +                      &gEfiGraphicsOutputProtocolGuid,
> +                      &Private->GraphicsOutput,
> +                      &gEfiEdidDiscoveredProtocolGuid,
> +                      &Private->EdidDiscovered,
> +                      &gEfiEdidActiveProtocolGuid,
> +                      &Private->EdidActive,
> +                      NULL
> +                      );
> +    }
> +  } else {
> +    //
> +    // This driver must support eithor GOP or UGA or both.
> +    //
> +    ASSERT (FALSE);
> +    Status = EFI_UNSUPPORTED;
> +  }
> +
> +
> +Error:
> +  if (EFI_ERROR (Status)) {
> +    if (Private) {
> +      if (Private->PciIo) {
> +        if (PciAttributesSaved == TRUE) {
> +          //
> +          // Restore original PCI attributes
> +          //
> +          Private->PciIo->Attributes (
> +                          Private->PciIo,
> +                          EfiPciIoAttributeOperationSet,
> +                          Private->OriginalPciAttributes,
> +                          NULL
> +                          );
> +        }
> +        //
> +        // Close the PCI I/O Protocol
> +        //
> +        gBS->CloseProtocol (
> +              Private->Handle,
> +              &gEfiPciIoProtocolGuid,
> +              This->DriverBindingHandle,
> +              Private->Handle
> +              );
> +      }
> +
> +      gBS->FreePool (Private);
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  CirrusLogic5430ControllerDriverStop
> +
> +  TODO:    This - add argument and description to function comment
> +  TODO:    Controller - add argument and description to function comment
> +  TODO:    NumberOfChildren - add argument and description to function
> comment
> +  TODO:    ChildHandleBuffer - add argument and description to function
> comment
> +  TODO:    EFI_SUCCESS - add return value to function comment
> +**/
> +EFI_STATUS
> +EFIAPI
> +CirrusLogic5430ControllerDriverStop (
> +  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
> +  IN EFI_HANDLE                     Controller,
> +  IN UINTN                          NumberOfChildren,
> +  IN EFI_HANDLE                     *ChildHandleBuffer
> +  )
> +{
> +  EFI_UGA_DRAW_PROTOCOL           *UgaDraw;
> +  EFI_GRAPHICS_OUTPUT_PROTOCOL    *GraphicsOutput;
> +
> +  EFI_STATUS                      Status;
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;
> +
> +  if (FeaturePcdGet (PcdSupportUga)) {
> +    Status = gBS->OpenProtocol (
> +                    Controller,
> +                    &gEfiUgaDrawProtocolGuid,
> +                    (VOID **) &UgaDraw,
> +                    This->DriverBindingHandle,
> +                    Controller,
> +                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +    //
> +    // Get our private context information
> +    //
> +    Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS
> (UgaDraw);
> +    CirrusLogic5430UgaDrawDestructor (Private);
> +
> +    if (FeaturePcdGet (PcdSupportGop)) {
> +      CirrusLogic5430GraphicsOutputDestructor (Private);
> +      //
> +      // Remove the UGA and GOP protocol interface from the system
> +      //
> +      Status = gBS->UninstallMultipleProtocolInterfaces (
> +                      Private->Handle,
> +                      &gEfiUgaDrawProtocolGuid,
> +                      &Private->UgaDraw,
> +                      &gEfiGraphicsOutputProtocolGuid,
> +                      &Private->GraphicsOutput,
> +                      NULL
> +                      );
> +    } else {
> +      //
> +      // Remove the UGA Draw interface from the system
> +      //
> +      Status = gBS->UninstallMultipleProtocolInterfaces (
> +                      Private->Handle,
> +                      &gEfiUgaDrawProtocolGuid,
> +                      &Private->UgaDraw,
> +                      NULL
> +                      );
> +    }
> +  } else {
> +    Status = gBS->OpenProtocol (
> +                    Controller,
> +                    &gEfiGraphicsOutputProtocolGuid,
> +                    (VOID **) &GraphicsOutput,
> +                    This->DriverBindingHandle,
> +                    Controller,
> +                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +
> +    //
> +    // Get our private context information
> +    //
> +    Private =
> CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS
> (GraphicsOutput);
> +
> +    CirrusLogic5430GraphicsOutputDestructor (Private);
> +    //
> +    // Remove the GOP protocol interface from the system
> +    //
> +    Status = gBS->UninstallMultipleProtocolInterfaces (
> +                    Private->Handle,
> +                    &gEfiUgaDrawProtocolGuid,
> +                    &Private->UgaDraw,
> +                    &gEfiGraphicsOutputProtocolGuid,
> +                    &Private->GraphicsOutput,
> +                    NULL
> +                    );
> +  }
> +
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Restore original PCI attributes
> +  //
> +  Private->PciIo->Attributes (
> +                  Private->PciIo,
> +                  EfiPciIoAttributeOperationSet,
> +                  Private->OriginalPciAttributes,
> +                  NULL
> +                  );
> +
> +  //
> +  // Close the PCI I/O Protocol
> +  //
> +  gBS->CloseProtocol (
> +        Controller,
> +        &gEfiPciIoProtocolGuid,
> +        This->DriverBindingHandle,
> +        Controller
> +        );
> +
> +  //
> +  // Free our instance data
> +  //
> +  gBS->FreePool (Private);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  CirrusLogic5430UgaDrawDestructor
> +
> +  TODO:    Private - add argument and description to function comment
> +  TODO:    EFI_SUCCESS - add return value to function comment
> +**/
> +EFI_STATUS
> +CirrusLogic5430UgaDrawDestructor (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  Private TODO: add argument description
> +  @param  Address TODO: add argument description
> +  @param  Data TODO: add argument description
> +
> +  TODO: add return values
> +
> +**/
> +VOID
> +outb (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
> +  UINTN                           Address,
> +  UINT8                           Data
> +  )
> +{
> +  Private->PciIo->Io.Write (
> +                      Private->PciIo,
> +                      EfiPciIoWidthUint8,
> +                      EFI_PCI_IO_PASS_THROUGH_BAR,
> +                      Address,
> +                      1,
> +                      &Data
> +                      );
> +}
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  Private TODO: add argument description
> +  @param  Address TODO: add argument description
> +  @param  Data TODO: add argument description
> +
> +  TODO: add return values
> +
> +**/
> +VOID
> +outw (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
> +  UINTN                           Address,
> +  UINT16                          Data
> +  )
> +{
> +  Private->PciIo->Io.Write (
> +                      Private->PciIo,
> +                      EfiPciIoWidthUint16,
> +                      EFI_PCI_IO_PASS_THROUGH_BAR,
> +                      Address,
> +                      1,
> +                      &Data
> +                      );
> +}
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  Private TODO: add argument description
> +  @param  Address TODO: add argument description
> +
> +  TODO: add return values
> +
> +**/
> +UINT8
> +inb (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
> +  UINTN                           Address
> +  )
> +{
> +  UINT8 Data;
> +
> +  Private->PciIo->Io.Read (
> +                      Private->PciIo,
> +                      EfiPciIoWidthUint8,
> +                      EFI_PCI_IO_PASS_THROUGH_BAR,
> +                      Address,
> +                      1,
> +                      &Data
> +                      );
> +  return Data;
> +}
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  Private TODO: add argument description
> +  @param  Address TODO: add argument description
> +
> +  TODO: add return values
> +
> +**/
> +UINT16
> +inw (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
> +  UINTN                           Address
> +  )
> +{
> +  UINT16  Data;
> +
> +  Private->PciIo->Io.Read (
> +                      Private->PciIo,
> +                      EfiPciIoWidthUint16,
> +                      EFI_PCI_IO_PASS_THROUGH_BAR,
> +                      Address,
> +                      1,
> +                      &Data
> +                      );
> +  return Data;
> +}
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  Private TODO: add argument description
> +  @param  Index TODO: add argument description
> +  @param  Red TODO: add argument description
> +  @param  Green TODO: add argument description
> +  @param  Blue TODO: add argument description
> +
> +  TODO: add return values
> +
> +**/
> +VOID
> +SetPaletteColor (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
> +  UINTN                           Index,
> +  UINT8                           Red,
> +  UINT8                           Green,
> +  UINT8                           Blue
> +  )
> +{
> +  outb (Private, PALETTE_INDEX_REGISTER, (UINT8) Index);
> +  outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Red >> 2));
> +  outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Green >> 2));
> +  outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Blue >> 2));
> +}
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  Private TODO: add argument description
> +
> +  TODO: add return values
> +
> +**/
> +VOID
> +SetDefaultPalette (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
> +  )
> +{
> +  UINTN Index;
> +  UINTN RedIndex;
> +  UINTN GreenIndex;
> +  UINTN BlueIndex;
> +
> +  Index = 0;
> +  for (RedIndex = 0; RedIndex < 8; RedIndex++) {
> +    for (GreenIndex = 0; GreenIndex < 8; GreenIndex++) {
> +      for (BlueIndex = 0; BlueIndex < 4; BlueIndex++) {
> +        SetPaletteColor (Private, Index, (UINT8) (RedIndex << 5), (UINT8)
> (GreenIndex << 5), (UINT8) (BlueIndex << 6));
> +        Index++;
> +      }
> +    }
> +  }
> +}
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  Private TODO: add argument description
> +
> +  TODO: add return values
> +
> +**/
> +VOID
> +ClearScreen (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
> +  )
> +{
> +  UINT32  Color;
> +
> +  Color = 0;
> +  Private->PciIo->Mem.Write (
> +                        Private->PciIo,
> +                        EfiPciIoWidthFillUint32,
> +                        0,
> +                        0,
> +                        0x100000 >> 2,
> +                        &Color
> +                        );
> +}
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  Private TODO: add argument description
> +
> +  TODO: add return values
> +
> +**/
> +VOID
> +DrawLogo (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
> +  UINTN                           ScreenWidth,
> +  UINTN                           ScreenHeight
> +  )
> +{
> +}
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  Private TODO: add argument description
> +  @param  ModeData TODO: add argument description
> +
> +  TODO: add return values
> +
> +**/
> +VOID
> +InitializeGraphicsMode (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
> +  CIRRUS_LOGIC_5430_VIDEO_MODES   *ModeData
> +  )
> +{
> +  UINT8 Byte;
> +  UINTN Index;
> +  UINT16 DeviceId;
> +  EFI_STATUS Status;
> +
> +  Status = Private->PciIo->Pci.Read (
> +             Private->PciIo,
> +             EfiPciIoWidthUint16,
> +             PCI_DEVICE_ID_OFFSET,
> +             1,
> +             &DeviceId
> +             );
> +  //
> +  // Read the PCI Configuration Header from the PCI Device
> +  //
> +  ASSERT_EFI_ERROR (Status);
> +
> +  outw (Private, SEQ_ADDRESS_REGISTER, 0x1206);
> +  outw (Private, SEQ_ADDRESS_REGISTER, 0x0012);
> +
> +  for (Index = 0; Index < 15; Index++) {
> +    outw (Private, SEQ_ADDRESS_REGISTER, ModeData->SeqSettings[Index]);
> +  }
> +
> +  if (DeviceId != CIRRUS_LOGIC_5446_DEVICE_ID) {
> +    outb (Private, SEQ_ADDRESS_REGISTER, 0x0f);
> +    Byte = (UINT8) ((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30);
> +    outb (Private, SEQ_DATA_REGISTER, Byte);
> +  }
> +
> +  outb (Private, MISC_OUTPUT_REGISTER, ModeData->MiscSetting);
> +  outw (Private, GRAPH_ADDRESS_REGISTER, 0x0506);
> +  outw (Private, SEQ_ADDRESS_REGISTER, 0x0300);
> +  outw (Private, CRTC_ADDRESS_REGISTER, 0x2011);
> +
> +  for (Index = 0; Index < 28; Index++) {
> +    outw (Private, CRTC_ADDRESS_REGISTER, (UINT16) ((ModeData-
> >CrtcSettings[Index] << 8) | Index));
> +  }
> +
> +  for (Index = 0; Index < 9; Index++) {
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16)
> ((GraphicsController[Index] << 8) | Index));
> +  }
> +
> +  inb (Private, INPUT_STATUS_1_REGISTER);
> +
> +  for (Index = 0; Index < 21; Index++) {
> +    outb (Private, ATT_ADDRESS_REGISTER, (UINT8) Index);
> +    outb (Private, ATT_ADDRESS_REGISTER, AttributeController[Index]);
> +  }
> +
> +  outb (Private, ATT_ADDRESS_REGISTER, 0x20);
> +
> +  outw (Private, GRAPH_ADDRESS_REGISTER, 0x0009);
> +  outw (Private, GRAPH_ADDRESS_REGISTER, 0x000a);
> +  outw (Private, GRAPH_ADDRESS_REGISTER, 0x000b);
> +  outb (Private, DAC_PIXEL_MASK_REGISTER, 0xff);
> +
> +  SetDefaultPalette (Private);
> +  ClearScreen (Private);
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +InitializeCirrusLogic5430 (
> +  IN EFI_HANDLE           ImageHandle,
> +  IN EFI_SYSTEM_TABLE     *SystemTable
> +  )
> +{
> +  EFI_STATUS              Status;
> +
> +  Status = EfiLibInstallDriverBindingComponentName2 (
> +             ImageHandle,
> +             SystemTable,
> +             &gCirrusLogic5430DriverBinding,
> +             ImageHandle,
> +             &gCirrusLogic5430ComponentName,
> +             &gCirrusLogic5430ComponentName2
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Install EFI Driver Supported EFI Version Protocol required for
> +  // EFI drivers that are on PCI and other plug in cards.
> +  //
> +  gCirrusLogic5430DriverSupportedEfiVersion.FirmwareVersion = PcdGet32
> (PcdDriverSupportedEfiVersion);
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &ImageHandle,
> +                  &gEfiDriverSupportedEfiVersionProtocolGuid,
> +                  &gCirrusLogic5430DriverSupportedEfiVersion,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> diff --git a/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.h
> b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.h
> new file mode 100644
> index 0000000000..355f0418b3
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.h
> @@ -0,0 +1,432 @@
> +/** @file
> +  Cirrus Logic 5430 Controller Driver
> +
> +  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +//
> +// Cirrus Logic 5430 Controller Driver
> +//
> +
> +#ifndef _CIRRUS_LOGIC_5430_H_
> +#define _CIRRUS_LOGIC_5430_H_
> +
> +
> +#include <Uefi.h>
> +#include <Protocol/UgaDraw.h>
> +#include <Protocol/GraphicsOutput.h>
> +#include <Protocol/PciIo.h>
> +#include <Protocol/DriverSupportedEfiVersion.h>
> +#include <Protocol/EdidOverride.h>
> +#include <Protocol/EdidDiscovered.h>
> +#include <Protocol/EdidActive.h>
> +#include <Protocol/DevicePath.h>
> +
> +#include <Library/DebugLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/UefiLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/TimerLib.h>
> +
> +#include <IndustryStandard/Pci.h>
> +//
> +// Cirrus Logic 5430 PCI Configuration Header values
> +//
> +#define CIRRUS_LOGIC_VENDOR_ID                0x1013
> +#define CIRRUS_LOGIC_5430_DEVICE_ID           0x00a8
> +#define CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID 0x00a0
> +#define CIRRUS_LOGIC_5446_DEVICE_ID           0x00b8
> +
> +//
> +// Cirrus Logic Graphical Mode Data
> +//
> +#define CIRRUS_LOGIC_5430_MODE_COUNT         3
> +
> +typedef struct {
> +  UINT32  ModeNumber;
> +  UINT32  HorizontalResolution;
> +  UINT32  VerticalResolution;
> +  UINT32  ColorDepth;
> +  UINT32  RefreshRate;
> +} CIRRUS_LOGIC_5430_MODE_DATA;
> +
> +#define PIXEL_RED_SHIFT   0
> +#define PIXEL_GREEN_SHIFT 3
> +#define PIXEL_BLUE_SHIFT  6
> +
> +#define PIXEL_RED_MASK    (BIT7 | BIT6 | BIT5)
> +#define PIXEL_GREEN_MASK  (BIT4 | BIT3 | BIT2)
> +#define PIXEL_BLUE_MASK   (BIT1 | BIT0)
> +
> +#define PIXEL_TO_COLOR_BYTE(pixel, mask, shift) ((UINT8) ((pixel & mask)
> << shift))
> +#define PIXEL_TO_RED_BYTE(pixel) PIXEL_TO_COLOR_BYTE(pixel,
> PIXEL_RED_MASK, PIXEL_RED_SHIFT)
> +#define PIXEL_TO_GREEN_BYTE(pixel) PIXEL_TO_COLOR_BYTE(pixel,
> PIXEL_GREEN_MASK, PIXEL_GREEN_SHIFT)
> +#define PIXEL_TO_BLUE_BYTE(pixel) PIXEL_TO_COLOR_BYTE(pixel,
> PIXEL_BLUE_MASK, PIXEL_BLUE_SHIFT)
> +
> +#define RGB_BYTES_TO_PIXEL(Red, Green, Blue) \
> +  (UINT8) ( (((Red) >> PIXEL_RED_SHIFT) & PIXEL_RED_MASK) | \
> +            (((Green) >> PIXEL_GREEN_SHIFT) & PIXEL_GREEN_MASK) | \
> +            (((Blue) >> PIXEL_BLUE_SHIFT) & PIXEL_BLUE_MASK) )
> +
> +#define GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER  0xffff
> +
> +//
> +// Cirrus Logic 5440 Private Data Structure
> +//
> +#define CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE  SIGNATURE_32
> ('C', 'L', '5', '4')
> +
> +typedef struct {
> +  UINT64                                Signature;
> +  EFI_HANDLE                            Handle;
> +  EFI_PCI_IO_PROTOCOL                   *PciIo;
> +  UINT64                                OriginalPciAttributes;
> +  EFI_UGA_DRAW_PROTOCOL                 UgaDraw;
> +  EFI_GRAPHICS_OUTPUT_PROTOCOL          GraphicsOutput;
> +  EFI_EDID_DISCOVERED_PROTOCOL          EdidDiscovered;
> +  EFI_EDID_ACTIVE_PROTOCOL              EdidActive;
> +  EFI_DEVICE_PATH_PROTOCOL              *GopDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL              *UgaDevicePath;
> +  UINTN                                 CurrentMode;
> +  UINTN                                 MaxMode;
> +  CIRRUS_LOGIC_5430_MODE_DATA
> ModeData[CIRRUS_LOGIC_5430_MODE_COUNT];
> +  UINT8                                 *LineBuffer;
> +  BOOLEAN                               HardwareNeedsStarting;
> +} CIRRUS_LOGIC_5430_PRIVATE_DATA;
> +
> +///
> +/// Video Mode structure
> +///
> +typedef struct {
> +  UINT32  Width;
> +  UINT32  Height;
> +  UINT32  ColorDepth;
> +  UINT32  RefreshRate;
> +  UINT8   *CrtcSettings;
> +  UINT16  *SeqSettings;
> +  UINT8   MiscSetting;
> +} CIRRUS_LOGIC_5430_VIDEO_MODES;
> +
> +#define CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS(a) \
> +  CR(a, CIRRUS_LOGIC_5430_PRIVATE_DATA, UgaDraw,
> CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE)
> +
> +#define
> CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS(a) \
> +  CR(a, CIRRUS_LOGIC_5430_PRIVATE_DATA, GraphicsOutput,
> CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE)
> +
> +
> +//
> +// Global Variables
> +//
> +extern UINT8                                      AttributeController[];
> +extern UINT8                                      GraphicsController[];
> +extern UINT8                                      Crtc_640_480_256_60[];
> +extern UINT16                                     Seq_640_480_256_60[];
> +extern UINT8                                      Crtc_800_600_256_60[];
> +extern UINT16                                     Seq_800_600_256_60[];
> +extern UINT8                                      Crtc_1024_768_256_60[];
> +extern UINT16                                     Seq_1024_768_256_60[];
> +extern CIRRUS_LOGIC_5430_VIDEO_MODES
> CirrusLogic5430VideoModes[];
> +extern EFI_DRIVER_BINDING_PROTOCOL
> gCirrusLogic5430DriverBinding;
> +extern EFI_COMPONENT_NAME_PROTOCOL
> gCirrusLogic5430ComponentName;
> +extern EFI_COMPONENT_NAME2_PROTOCOL
> gCirrusLogic5430ComponentName2;
> +extern EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL
> gCirrusLogic5430DriverSupportedEfiVersion;
> +
> +//
> +// Io Registers defined by VGA
> +//
> +#define CRTC_ADDRESS_REGISTER   0x3d4
> +#define CRTC_DATA_REGISTER      0x3d5
> +#define SEQ_ADDRESS_REGISTER    0x3c4
> +#define SEQ_DATA_REGISTER       0x3c5
> +#define GRAPH_ADDRESS_REGISTER  0x3ce
> +#define GRAPH_DATA_REGISTER     0x3cf
> +#define ATT_ADDRESS_REGISTER    0x3c0
> +#define MISC_OUTPUT_REGISTER    0x3c2
> +#define INPUT_STATUS_1_REGISTER 0x3da
> +#define DAC_PIXEL_MASK_REGISTER 0x3c6
> +#define PALETTE_INDEX_REGISTER  0x3c8
> +#define PALETTE_DATA_REGISTER   0x3c9
> +
> +//
> +// UGA Draw Hardware abstraction internal worker functions
> +//
> +EFI_STATUS
> +CirrusLogic5430UgaDrawConstructor (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
> +  );
> +
> +EFI_STATUS
> +CirrusLogic5430UgaDrawDestructor (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
> +  );
> +
> +//
> +// Graphics Output Hardware abstraction internal worker functions
> +//
> +EFI_STATUS
> +CirrusLogic5430GraphicsOutputConstructor (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
> +  );
> +
> +EFI_STATUS
> +CirrusLogic5430GraphicsOutputDestructor (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
> +  );
> +
> +
> +//
> +// EFI_DRIVER_BINDING_PROTOCOL Protocol Interface
> +//
> +/**
> +  TODO: Add function description
> +
> +  @param  This TODO: add argument description
> +  @param  Controller TODO: add argument description
> +  @param  RemainingDevicePath TODO: add argument description
> +
> +  TODO: add return values
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CirrusLogic5430ControllerDriverSupported (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> +  );
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  This TODO: add argument description
> +  @param  Controller TODO: add argument description
> +  @param  RemainingDevicePath TODO: add argument description
> +
> +  TODO: add return values
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CirrusLogic5430ControllerDriverStart (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> +  );
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  This TODO: add argument description
> +  @param  Controller TODO: add argument description
> +  @param  NumberOfChildren TODO: add argument description
> +  @param  ChildHandleBuffer TODO: add argument description
> +
> +  TODO: add return values
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CirrusLogic5430ControllerDriverStop (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN UINTN                        NumberOfChildren,
> +  IN EFI_HANDLE                   *ChildHandleBuffer
> +  );
> +
> +//
> +// EFI Component Name Functions
> +//
> +/**
> +  Retrieves a Unicode string that is the user readable name of the driver.
> +
> +  This function retrieves the user readable name of a driver in the form of a
> +  Unicode string. If the driver specified by This has a user readable name in
> +  the language specified by Language, then a pointer to the driver name is
> +  returned in DriverName, and EFI_SUCCESS is returned. If the driver
> specified
> +  by This does not support the language specified by Language,
> +  then EFI_UNSUPPORTED is returned.
> +
> +  @param  This[in]              A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> +                                array indicating the language. This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified
> +                                in RFC 4646 or ISO 639-2 language code format.
> +
> +  @param  DriverName[out]       A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                driver specified by This in the language
> +                                specified by Language.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> +                                This and the language specified by Language was
> +                                returned in DriverName.
> +
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CirrusLogic5430ComponentNameGetDriverName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
> +  IN  CHAR8                        *Language,
> +  OUT CHAR16                       **DriverName
> +  );
> +
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the controller
> +  that is being managed by a driver.
> +
> +  This function retrieves the user readable name of the controller specified
> by
> +  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> +  driver specified by This has a user readable name in the language specified
> by
> +  Language, then a pointer to the controller name is returned in
> ControllerName,
> +  and EFI_SUCCESS is returned.  If the driver specified by This is not
> currently
> +  managing the controller specified by ControllerHandle and ChildHandle,
> +  then EFI_UNSUPPORTED is returned.  If the driver specified by This does
> not
> +  support the language specified by Language, then EFI_UNSUPPORTED is
> returned.
> +
> +  @param  This[in]              A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> +  @param  ControllerHandle[in]  The handle of a controller that the driver
> +                                specified by This is managing.  This handle
> +                                specifies the controller whose name is to be
> +                                returned.
> +
> +  @param  ChildHandle[in]       The handle of the child controller to retrieve
> +                                the name of.  This is an optional parameter that
> +                                may be NULL.  It will be NULL for device
> +                                drivers.  It will also be NULL for a bus drivers
> +                                that wish to retrieve the name of the bus
> +                                controller.  It will not be NULL for a bus
> +                                driver that wishes to retrieve the name of a
> +                                child controller.
> +
> +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> +                                array indicating the language.  This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified in
> +                                RFC 4646 or ISO 639-2 language code format.
> +
> +  @param  ControllerName[out]   A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                controller specified by ControllerHandle and
> +                                ChildHandle in the language specified by
> +                                Language from the point of view of the driver
> +                                specified by This.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the user readable name
> in
> +                                the language specified by Language for the
> +                                driver specified by This was returned in
> +                                DriverName.
> +
> +  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a
> valid
> +                                EFI_HANDLE.
> +
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> +                                managing the controller specified by
> +                                ControllerHandle and ChildHandle.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CirrusLogic5430ComponentNameGetControllerName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
> +  IN  EFI_HANDLE                                      ControllerHandle,
> +  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
> +  IN  CHAR8                                           *Language,
> +  OUT CHAR16                                          **ControllerName
> +  );
> +
> +
> +//
> +// Local Function Prototypes
> +//
> +VOID
> +InitializeGraphicsMode (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
> +  CIRRUS_LOGIC_5430_VIDEO_MODES   *ModeData
> +  );
> +
> +VOID
> +SetPaletteColor (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
> +  UINTN                           Index,
> +  UINT8                           Red,
> +  UINT8                           Green,
> +  UINT8                           Blue
> +  );
> +
> +VOID
> +SetDefaultPalette (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
> +  );
> +
> +VOID
> +DrawLogo (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
> +  UINTN                           ScreenWidth,
> +  UINTN                           ScreenHeight
> +  );
> +
> +VOID
> +outb (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
> +  UINTN                           Address,
> +  UINT8                           Data
> +  );
> +
> +VOID
> +outw (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
> +  UINTN                           Address,
> +  UINT16                          Data
> +  );
> +
> +UINT8
> +inb (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
> +  UINTN                           Address
> +  );
> +
> +UINT16
> +inw (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
> +  UINTN                           Address
> +  );
> +
> +EFI_STATUS
> +CirrusLogic5430VideoModeSetup (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
> +  );
> +
> +#endif
> diff --git
> a/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf
> b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf
> new file mode 100644
> index 0000000000..3e8b7b087f
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf
> @@ -0,0 +1,84 @@
> +## @file
> +# Component description file for CirrusLogic5430 module
> +#
> +# Cirrus Logic 5430 Controller Driver.This driver is a sample implementation
> +#  of the UGA Draw Protocol for the Cirrus Logic 5430 family of PCI video
> controllers.
> +#  This driver is only usable in the EFI pre-boot environment. This sample is
> +#  intended to show how the UGA Draw Protocol is able to function. The
> UGA I/O
> +#  Protocol is not implemented in this sample. A fully compliant EFI UGA
> driver
> +#  requires both the UGA Draw and the UGA I/O Protocol. Please refer to
> Microsoft's
> +#  documentation on UGA for details on how to write a UGA driver that is
> able
> +#  to function both in the EFI pre-boot environment and from the OS
> runtime.
> +# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = CirrusLogic5430Dxe
> +  FILE_GUID                      = 555F76EA-785F-40d7-9174-153C43636C68
> +  MODULE_TYPE                    = UEFI_DRIVER
> +  VERSION_STRING                 = 1.0
> +
> +  ENTRY_POINT                    = InitializeCirrusLogic5430
> +
> +  PCI_VENDOR_ID  = 0x1013
> +  PCI_DEVICE_ID  = 0x00A8
> +  PCI_CLASS_CODE = 0x030000
> +  PCI_REVISION   = 0x00
> +  PCI_COMPRESS   = TRUE
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +#  DRIVER_BINDING                =  gCirrusLogic5430DriverBinding
> +#  COMPONENT_NAME                =  gCirrusLogic5430ComponentName
> +#
> +
> +[Sources]
> +  ComponentName.c
> +  DriverSupportedEfiVersion.c
> +  CirrusLogic5430UgaDraw.c
> +  CirrusLogic5430GraphicsOutput.c
> +  CirrusLogic5430.c
> +  CirrusLogic5430.h
> +  Edid.c
> +  CirrusLogic5430I2c.h
> +  CirrusLogic5430I2c.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  OptionRomPkg/OptionRomPkg.dec
> +
> +[LibraryClasses]
> +  UefiBootServicesTableLib
> +  MemoryAllocationLib
> +  UefiLib
> +  UefiDriverEntryPoint
> +  DebugLib
> +  BaseMemoryLib
> +  DevicePathLib
> +  TimerLib
> +
> +[Protocols]
> +  gEfiDriverSupportedEfiVersionProtocolGuid     # PROTOCOL
> ALWAYS_PRODUCED
> +  gEfiUgaDrawProtocolGuid                       # PROTOCOL BY_START
> +  gEfiGraphicsOutputProtocolGuid                # PROTOCOL BY_START
> +  gEfiEdidDiscoveredProtocolGuid                # PROTOCOL BY_START
> +  gEfiEdidActiveProtocolGuid                    # PROTOCOL BY_START
> +  gEfiDevicePathProtocolGuid                    # PROTOCOL BY_START
> +  gEfiPciIoProtocolGuid                         # PROTOCOL TO_START
> +  gEfiEdidOverrideProtocolGuid                  # PROTOCOL TO_START
> +
> +
> +[FeaturePcd]
> +  gOptionRomPkgTokenSpaceGuid.PcdSupportGop
> +  gOptionRomPkgTokenSpaceGuid.PcdSupportUga
> +
> +[Pcd]
> +  gOptionRomPkgTokenSpaceGuid.PcdDriverSupportedEfiVersion
> diff --git
> a/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430GraphicsOutpu
> t.c
> b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430GraphicsOutp
> ut.c
> new file mode 100644
> index 0000000000..b74d84b131
> --- /dev/null
> +++
> b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430GraphicsOutp
> ut.c
> @@ -0,0 +1,556 @@
> +/** @file
> +Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +Module Name:
> +
> +  UefiCirrusLogic5430GraphicsOutput.c
> +
> +Abstract:
> +
> +  This file produces the graphics abstration of Graphics Output Protocol. It is
> called by
> +  CirrusLogic5430.c file which deals with the EFI 1.1 driver model.
> +  This file just does graphics.
> +
> +**/
> +#include "CirrusLogic5430.h"
> +#include <IndustryStandard/Acpi.h>
> +
> +
> +STATIC
> +VOID
> +CirrusLogic5430CompleteModeInfo (
> +  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info
> +  )
> +{
> +  Info->Version = 0;
> +  Info->PixelFormat = PixelBitMask;
> +  Info->PixelInformation.RedMask = PIXEL_RED_MASK;
> +  Info->PixelInformation.GreenMask = PIXEL_GREEN_MASK;
> +  Info->PixelInformation.BlueMask = PIXEL_BLUE_MASK;
> +  Info->PixelInformation.ReservedMask = 0;
> +  Info->PixelsPerScanLine = Info->HorizontalResolution;
> +}
> +
> +
> +STATIC
> +EFI_STATUS
> +CirrusLogic5430CompleteModeData (
> +  IN  CIRRUS_LOGIC_5430_PRIVATE_DATA    *Private,
> +  OUT EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode
> +  )
> +{
> +  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info;
> +  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     *FrameBufDesc;
> +
> +  Info = Mode->Info;
> +  CirrusLogic5430CompleteModeInfo (Info);
> +
> +  Private->PciIo->GetBarAttributes (
> +                        Private->PciIo,
> +                        0,
> +                        NULL,
> +                        (VOID**) &FrameBufDesc
> +                        );
> +
> +  Mode->FrameBufferBase = FrameBufDesc->AddrRangeMin;
> +  Mode->FrameBufferSize = Info->HorizontalResolution * Info-
> >VerticalResolution;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +//
> +// Graphics Output Protocol Member Functions
> +//
> +EFI_STATUS
> +EFIAPI
> +CirrusLogic5430GraphicsOutputQueryMode (
> +  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,
> +  IN  UINT32                                ModeNumber,
> +  OUT UINTN                                 *SizeOfInfo,
> +  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  **Info
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Graphics Output protocol interface to query video mode
> +
> +  Arguments:
> +    This                  - Protocol instance pointer.
> +    ModeNumber            - The mode number to return information on.
> +    Info                  - Caller allocated buffer that returns information about
> ModeNumber.
> +    SizeOfInfo            - A pointer to the size, in bytes, of the Info buffer.
> +
> +  Returns:
> +    EFI_SUCCESS           - Mode information returned.
> +    EFI_BUFFER_TOO_SMALL  - The Info buffer was too small.
> +    EFI_DEVICE_ERROR      - A hardware error occurred trying to retrieve the
> video mode.
> +    EFI_NOT_STARTED       - Video display is not initialized. Call SetMode ()
> +    EFI_INVALID_PARAMETER - One of the input args was NULL.
> +
> +--*/
> +{
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;
> +
> +  Private =
> CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
> +
> +  if (Private->HardwareNeedsStarting) {
> +    return EFI_NOT_STARTED;
> +  }
> +
> +  if (Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode-
> >MaxMode) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *Info = AllocatePool (sizeof
> (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
> +  if (*Info == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
> +
> +  (*Info)->HorizontalResolution = Private-
> >ModeData[ModeNumber].HorizontalResolution;
> +  (*Info)->VerticalResolution   = Private-
> >ModeData[ModeNumber].VerticalResolution;
> +  CirrusLogic5430CompleteModeInfo (*Info);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +CirrusLogic5430GraphicsOutputSetMode (
> +  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
> +  IN  UINT32                       ModeNumber
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Graphics Output protocol interface to set video mode
> +
> +  Arguments:
> +    This             - Protocol instance pointer.
> +    ModeNumber       - The mode number to be set.
> +
> +  Returns:
> +    EFI_SUCCESS      - Graphics mode was changed.
> +    EFI_DEVICE_ERROR - The device had an error and could not complete the
> request.
> +    EFI_UNSUPPORTED  - ModeNumber is not supported by this device.
> +
> +--*/
> +{
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA    *Private;
> +  CIRRUS_LOGIC_5430_MODE_DATA       *ModeData;
> +
> +  Private =
> CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
> +
> +  if (ModeNumber >= This->Mode->MaxMode) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  ModeData = &Private->ModeData[ModeNumber];
> +
> +  if (Private->LineBuffer) {
> +    gBS->FreePool (Private->LineBuffer);
> +  }
> +
> +  Private->LineBuffer = NULL;
> +  Private->LineBuffer = AllocatePool (ModeData->HorizontalResolution);
> +  if (Private->LineBuffer == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  InitializeGraphicsMode (Private, &CirrusLogic5430VideoModes[ModeData-
> >ModeNumber]);
> +
> +  This->Mode->Mode = ModeNumber;
> +  This->Mode->Info->HorizontalResolution = ModeData-
> >HorizontalResolution;
> +  This->Mode->Info->VerticalResolution = ModeData->VerticalResolution;
> +  This->Mode->SizeOfInfo =
> sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
> +
> +  CirrusLogic5430CompleteModeData (Private, This->Mode);
> +
> +  Private->HardwareNeedsStarting  = FALSE;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +CirrusLogic5430GraphicsOutputBlt (
> +  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,
> +  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer, OPTIONAL
> +  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION     BltOperation,
> +  IN  UINTN                                 SourceX,
> +  IN  UINTN                                 SourceY,
> +  IN  UINTN                                 DestinationX,
> +  IN  UINTN                                 DestinationY,
> +  IN  UINTN                                 Width,
> +  IN  UINTN                                 Height,
> +  IN  UINTN                                 Delta
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Graphics Output protocol instance to block transfer for CirrusLogic device
> +
> +Arguments:
> +
> +  This          - Pointer to Graphics Output protocol instance
> +  BltBuffer     - The data to transfer to screen
> +  BltOperation  - The operation to perform
> +  SourceX       - The X coordinate of the source for BltOperation
> +  SourceY       - The Y coordinate of the source for BltOperation
> +  DestinationX  - The X coordinate of the destination for BltOperation
> +  DestinationY  - The Y coordinate of the destination for BltOperation
> +  Width         - The width of a rectangle in the blt rectangle in pixels
> +  Height        - The height of a rectangle in the blt rectangle in pixels
> +  Delta         - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
> +                  If a Delta of 0 is used, the entire BltBuffer will be operated on.
> +                  If a subrectangle of the BltBuffer is used, then Delta represents
> +                  the number of bytes in a row of the BltBuffer.
> +
> +Returns:
> +
> +  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  EFI_SUCCESS - Blt operation success
> +
> +--*/
> +{
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;
> +  EFI_TPL                         OriginalTPL;
> +  UINTN                           DstY;
> +  UINTN                           SrcY;
> +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *Blt;
> +  UINTN                           X;
> +  UINT8                           Pixel;
> +  UINT32                          WidePixel;
> +  UINTN                           ScreenWidth;
> +  UINTN                           Offset;
> +  UINTN                           SourceOffset;
> +  UINT32                          CurrentMode;
> +
> +  Private =
> CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
> +
> +  if ((UINT32)BltOperation >= EfiGraphicsOutputBltOperationMax) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (Width == 0 || Height == 0) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // If Delta is zero, then the entire BltBuffer is being used, so Delta
> +  // is the number of bytes in each row of BltBuffer.  Since BltBuffer is Width
> pixels size,
> +  // the number of bytes in each row can be computed.
> +  //
> +  if (Delta == 0) {
> +    Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
> +  }
> +
> +  //
> +  // We need to fill the Virtual Screen buffer with the blt data.
> +  // The virtual screen is upside down, as the first row is the bootom row of
> +  // the image.
> +  //
> +
> +  CurrentMode = This->Mode->Mode;
> +  //
> +  // Make sure the SourceX, SourceY, DestinationX, DestinationY, Width,
> and Height parameters
> +  // are valid for the operation and the current screen geometry.
> +  //
> +  if (BltOperation == EfiBltVideoToBltBuffer) {
> +    //
> +    // Video to BltBuffer: Source is Video, destination is BltBuffer
> +    //
> +    if (SourceY + Height > Private-
> >ModeData[CurrentMode].VerticalResolution) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +
> +    if (SourceX + Width > Private-
> >ModeData[CurrentMode].HorizontalResolution) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +  } else {
> +    //
> +    // BltBuffer to Video: Source is BltBuffer, destination is Video
> +    //
> +    if (DestinationY + Height > Private-
> >ModeData[CurrentMode].VerticalResolution) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +
> +    if (DestinationX + Width > Private-
> >ModeData[CurrentMode].HorizontalResolution) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +  }
> +  //
> +  // We have to raise to TPL Notify, so we make an atomic write the frame
> buffer.
> +  // We would not want a timer based event (Cursor, ...) to come in while
> we are
> +  // doing this operation.
> +  //
> +  OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);
> +
> +  switch (BltOperation) {
> +  case EfiBltVideoToBltBuffer:
> +    //
> +    // Video to BltBuffer: Source is Video, destination is BltBuffer
> +    //
> +    for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY);
> SrcY++, DstY++) {
> +
> +      Offset = (SrcY * Private->ModeData[CurrentMode].HorizontalResolution)
> + SourceX;
> +      if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {
> +        Private->PciIo->Mem.Read (
> +                              Private->PciIo,
> +                              EfiPciIoWidthUint32,
> +                              0,
> +                              Offset,
> +                              Width >> 2,
> +                              Private->LineBuffer
> +                              );
> +      } else {
> +        Private->PciIo->Mem.Read (
> +                              Private->PciIo,
> +                              EfiPciIoWidthUint8,
> +                              0,
> +                              Offset,
> +                              Width,
> +                              Private->LineBuffer
> +                              );
> +      }
> +
> +      for (X = 0; X < Width; X++) {
> +        Blt         = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer +
> (DstY * Delta) + (DestinationX + X) * sizeof
> (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
> +
> +        Blt->Red    = PIXEL_TO_RED_BYTE (Private->LineBuffer[X]);
> +        Blt->Green  = PIXEL_TO_GREEN_BYTE (Private->LineBuffer[X]);
> +        Blt->Blue   = PIXEL_TO_BLUE_BYTE (Private->LineBuffer[X]);
> +      }
> +    }
> +    break;
> +
> +  case EfiBltVideoToVideo:
> +    //
> +    // Perform hardware acceleration for Video to Video operations
> +    //
> +    ScreenWidth   = Private->ModeData[CurrentMode].HorizontalResolution;
> +    SourceOffset  = (SourceY * Private-
> >ModeData[CurrentMode].HorizontalResolution) + (SourceX);
> +    Offset        = (DestinationY * Private-
> >ModeData[CurrentMode].HorizontalResolution) + (DestinationX);
> +
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0000);
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0010);
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0012);
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0014);
> +
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0001);
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0011);
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0013);
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0015);
> +
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Width << 8) &
> 0xff00) | 0x20));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Width & 0xff00) |
> 0x21));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Height << 8) &
> 0xff00) | 0x22));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Height & 0xff00) |
> 0x23));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8)
> & 0xff00) | 0x24));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth &
> 0xff00) | 0x25));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8)
> & 0xff00) | 0x26));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth &
> 0xff00) | 0x27));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) << 8) &
> 0xff00) | 0x28));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 0) &
> 0xff00) | 0x29));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 8) &
> 0xff00) | 0x2a));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) <<
> 8) & 0xff00) | 0x2c));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >>
> 0) & 0xff00) | 0x2d));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >>
> 8) & 0xff00) | 0x2e));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x002f);
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0030);
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0d32);
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0033);
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0034);
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0035);
> +
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0231);
> +
> +    outb (Private, GRAPH_ADDRESS_REGISTER, 0x31);
> +    while ((inb (Private, GRAPH_DATA_REGISTER) & 0x01) == 0x01)
> +      ;
> +    break;
> +
> +  case EfiBltVideoFill:
> +    Blt       = BltBuffer;
> +    Pixel     = RGB_BYTES_TO_PIXEL (Blt->Red, Blt->Green, Blt->Blue);
> +    WidePixel = (Pixel << 8) | Pixel;
> +    WidePixel = (WidePixel << 16) | WidePixel;
> +
> +    if (DestinationX == 0 && Width == Private-
> >ModeData[CurrentMode].HorizontalResolution) {
> +      Offset = DestinationY * Private-
> >ModeData[CurrentMode].HorizontalResolution;
> +      if (((Offset & 0x03) == 0) && (((Width * Height) & 0x03) == 0)) {
> +        Private->PciIo->Mem.Write (
> +                              Private->PciIo,
> +                              EfiPciIoWidthFillUint32,
> +                              0,
> +                              Offset,
> +                              (Width * Height) >> 2,
> +                              &WidePixel
> +                              );
> +      } else {
> +        Private->PciIo->Mem.Write (
> +                              Private->PciIo,
> +                              EfiPciIoWidthFillUint8,
> +                              0,
> +                              Offset,
> +                              Width * Height,
> +                              &Pixel
> +                              );
> +      }
> +    } else {
> +      for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY);
> SrcY++, DstY++) {
> +        Offset = (DstY * Private-
> >ModeData[CurrentMode].HorizontalResolution) + DestinationX;
> +        if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {
> +          Private->PciIo->Mem.Write (
> +                                Private->PciIo,
> +                                EfiPciIoWidthFillUint32,
> +                                0,
> +                                Offset,
> +                                Width >> 2,
> +                                &WidePixel
> +                                );
> +        } else {
> +          Private->PciIo->Mem.Write (
> +                                Private->PciIo,
> +                                EfiPciIoWidthFillUint8,
> +                                0,
> +                                Offset,
> +                                Width,
> +                                &Pixel
> +                                );
> +        }
> +      }
> +    }
> +    break;
> +
> +  case EfiBltBufferToVideo:
> +    for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY);
> SrcY++, DstY++) {
> +
> +      for (X = 0; X < Width; X++) {
> +        Blt =
> +          (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) (
> +              (UINT8 *) BltBuffer +
> +              (SrcY * Delta) +
> +              ((SourceX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))
> +            );
> +        Private->LineBuffer[X]  =
> +          RGB_BYTES_TO_PIXEL (Blt->Red, Blt->Green, Blt->Blue);
> +      }
> +
> +      Offset = (DstY * Private->ModeData[CurrentMode].HorizontalResolution)
> + DestinationX;
> +
> +      if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {
> +        Private->PciIo->Mem.Write (
> +                              Private->PciIo,
> +                              EfiPciIoWidthUint32,
> +                              0,
> +                              Offset,
> +                              Width >> 2,
> +                              Private->LineBuffer
> +                              );
> +      } else {
> +        Private->PciIo->Mem.Write (
> +                              Private->PciIo,
> +                              EfiPciIoWidthUint8,
> +                              0,
> +                              Offset,
> +                              Width,
> +                              Private->LineBuffer
> +                              );
> +      }
> +    }
> +    break;
> +  default:
> +    ASSERT (FALSE);
> +  }
> +
> +  gBS->RestoreTPL (OriginalTPL);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +CirrusLogic5430GraphicsOutputConstructor (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
> +  )
> +{
> +  EFI_STATUS                   Status;
> +  EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
> +
> +
> +  GraphicsOutput            = &Private->GraphicsOutput;
> +  GraphicsOutput->QueryMode =
> CirrusLogic5430GraphicsOutputQueryMode;
> +  GraphicsOutput->SetMode   = CirrusLogic5430GraphicsOutputSetMode;
> +  GraphicsOutput->Blt       = CirrusLogic5430GraphicsOutputBlt;
> +
> +  //
> +  // Initialize the private data
> +  //
> +  Status = gBS->AllocatePool (
> +                  EfiBootServicesData,
> +                  sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE),
> +                  (VOID **) &Private->GraphicsOutput.Mode
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  Status = gBS->AllocatePool (
> +                  EfiBootServicesData,
> +                  sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),
> +                  (VOID **) &Private->GraphicsOutput.Mode->Info
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  Private->GraphicsOutput.Mode->MaxMode = (UINT32) Private->MaxMode;
> +  Private->GraphicsOutput.Mode->Mode    =
> GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;
> +  Private->HardwareNeedsStarting        = TRUE;
> +  Private->LineBuffer                   = NULL;
> +
> +  //
> +  // Initialize the hardware
> +  //
> +  GraphicsOutput->SetMode (GraphicsOutput, 0);
> +  ASSERT (Private->GraphicsOutput.Mode->Mode <
> CIRRUS_LOGIC_5430_MODE_COUNT);
> +  DrawLogo (
> +    Private,
> +    Private->ModeData[Private->GraphicsOutput.Mode-
> >Mode].HorizontalResolution,
> +    Private->ModeData[Private->GraphicsOutput.Mode-
> >Mode].VerticalResolution
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +CirrusLogic5430GraphicsOutputDestructor (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
> +  )
> +/*++
> +
> +Routine Description:
> +
> +Arguments:
> +
> +Returns:
> +
> +  None
> +
> +--*/
> +{
> +  if (Private->GraphicsOutput.Mode != NULL) {
> +    if (Private->GraphicsOutput.Mode->Info != NULL) {
> +      gBS->FreePool (Private->GraphicsOutput.Mode->Info);
> +    }
> +    gBS->FreePool (Private->GraphicsOutput.Mode);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> diff --git a/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.c
> b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.c
> new file mode 100644
> index 0000000000..0cec8670b7
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.c
> @@ -0,0 +1,427 @@
> +/** @file
> +  I2C Bus implementation upon CirrusLogic.
> +
> +  Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "CirrusLogic5430.h"
> +#include "CirrusLogic5430I2c.h"
> +
> +#define SEQ_ADDRESS_REGISTER    0x3c4
> +#define SEQ_DATA_REGISTER       0x3c5
> +
> +#define I2C_CONTROL             0x08
> +#define I2CDAT_IN               7
> +#define I2CCLK_IN               2
> +#define I2CDAT_OUT              1
> +#define I2CCLK_OUT              0
> +
> +#define I2C_BUS_SPEED           100  //100kbps
> +
> +/**
> +  PCI I/O byte write function.
> +
> +  @param  PciIo        The pointer to PCI_IO_PROTOCOL.
> +  @param  Address      The bit map of I2C Data or I2C Clock pins.
> +  @param  Data         The date to write.
> +
> +**/
> +VOID
> +I2cOutb (
> +  EFI_PCI_IO_PROTOCOL    *PciIo,
> +  UINTN                  Address,
> +  UINT8                  Data
> +  )
> +{
> +  PciIo->Io.Write (
> +             PciIo,
> +             EfiPciIoWidthUint8,
> +             EFI_PCI_IO_PASS_THROUGH_BAR,
> +             Address,
> +             1,
> +             &Data
> +             );
> +}
> +/**
> +  PCI I/O byte read function.
> +
> +  @param  PciIo        The pointer to PCI_IO_PROTOCOL.
> +  @param  Address      The bit map of I2C Data or I2C Clock pins.
> +
> +  return byte value read from PCI I/O space.
> +
> +**/
> +UINT8
> +I2cInb (
> +  EFI_PCI_IO_PROTOCOL    *PciIo,
> +  UINTN                  Address
> +  )
> +{
> +  UINT8 Data;
> +
> +  PciIo->Io.Read (
> +             PciIo,
> +             EfiPciIoWidthUint8,
> +             EFI_PCI_IO_PASS_THROUGH_BAR,
> +             Address,
> +             1,
> +             &Data
> +             );
> +  return Data;
> +}
> +
> +/**
> +  Read status of I2C Data and I2C Clock Pins.
> +
> +  @param  PciIo        The pointer to PCI_IO_PROTOCOL.
> +  @param  Blt          The bit map of I2C Data or I2C Clock pins.
> +
> +  @retval 0            Low on I2C Data or I2C Clock Pin.
> +  @retval 1            High on I2C Data or I2C Clock Pin.
> +
> +**/
> +UINT8
> +I2cPinRead (
> +  EFI_PCI_IO_PROTOCOL    *PciIo,
> +  UINT8                  Bit
> +  )
> +{
> +  I2cOutb (PciIo, SEQ_ADDRESS_REGISTER, I2C_CONTROL);
> +  return (UINT8) ((I2cInb (PciIo, SEQ_DATA_REGISTER) >> Bit ) & 0xfe);
> +}
> +
> +
> +/**
> +  Set/Clear I2C Data and I2C Clock Pins.
> +
> +  @param  PciIo              The pointer to PCI_IO_PROTOCOL.
> +  @param  Blt                The bit map to controller I2C Data or I2C Clock pins.
> +  @param  Value              1 or 0 stands for Set or Clear I2C Data and I2C Clock
> Pins.
> +
> +**/
> +VOID
> +I2cPinWrite (
> +  EFI_PCI_IO_PROTOCOL    *PciIo,
> +  UINT8                  Bit,
> +  UINT8                  Value
> +  )
> +{
> +  UINT8        Byte;
> +  I2cOutb (PciIo, SEQ_ADDRESS_REGISTER, I2C_CONTROL);
> +  Byte = (UINT8) (I2cInb (PciIo, SEQ_DATA_REGISTER) & (UINT8) ~(1 << Bit)) ;
> +  Byte = (UINT8) (Byte | ((Value & 0x01) << Bit));
> +  I2cOutb (PciIo, SEQ_DATA_REGISTER, (UINT8) (Byte | 0x40));
> +  return;
> +}
> +
> +/**
> +  Read/write delay acoording to I2C Bus Speed.
> +
> +**/
> +VOID
> +I2cDelay (
> +  VOID
> +  )
> +{
> +  MicroSecondDelay (1000 / I2C_BUS_SPEED);
> +}
> +
> +/**
> +  Write a 8-bit data onto I2C Data Pin.
> +
> +  @param  PciIo              The pointer to PCI_IO_PROTOCOL.
> +  @param  Data               The byte data to write.
> +
> +**/
> +VOID
> +I2cSendByte (
> +  EFI_PCI_IO_PROTOCOL    *PciIo,
> +  UINT8                  Data
> +  )
> +{
> +  UINTN                  Index;
> +  //
> +  // Send byte data onto I2C Bus
> +  //
> +  for (Index = 0; Index < 8; Index --) {
> +    I2cPinWrite (PciIo, I2CDAT_OUT, (UINT8) (Data >> (7 - Index)));
> +    I2cPinWrite (PciIo, I2CCLK_OUT, 1);
> +    I2cDelay ();
> +    I2cPinWrite (PciIo, I2CCLK_OUT, 0);
> +  }
> +}
> +
> +/**
> +  Read a 8-bit data from I2C Data Pin.
> +
> +  @param  PciIo              The pointer to PCI_IO_PROTOCOL.
> +
> +  Return the byte data read from I2C Data Pin.
> +**/
> +UINT8
> +I2cReceiveByte (
> +  EFI_PCI_IO_PROTOCOL    *PciIo
> +  )
> +{
> +  UINT8          Data;
> +  UINTN          Index;
> +
> +  Data = 0;
> +  //
> +  // Read byte data from I2C Bus
> +  //
> +  for (Index = 0; Index < 8; Index --) {
> +    I2cPinWrite (PciIo, I2CCLK_OUT, 1);
> +    I2cDelay ();
> +    Data = (UINT8) (Data << 1);
> +    Data = (UINT8) (Data | I2cPinRead (PciIo, I2CDAT_IN));
> +    I2cPinWrite (PciIo, I2CCLK_OUT, 0);
> +  }
> +
> +  return Data;
> +}
> +
> +/**
> +  Receive an ACK signal from I2C Bus.
> +
> +  @param  PciIo              The pointer to PCI_IO_PROTOCOL.
> +
> +**/
> +BOOLEAN
> +I2cWaitAck (
> +  EFI_PCI_IO_PROTOCOL    *PciIo
> +  )
> +{
> +  //
> +  // Wait for ACK signal
> +  //
> +  I2cPinWrite (PciIo, I2CDAT_OUT, 1);
> +  I2cPinWrite (PciIo, I2CCLK_OUT, 1);
> +  I2cDelay ();
> +  if (I2cPinRead (PciIo, I2CDAT_IN) == 0) {
> +    I2cPinWrite (PciIo, I2CDAT_OUT, 1);
> +    return TRUE;
> +  } else {
> +    return FALSE;
> +  }
> +}
> +
> +/**
> +  Send an ACK signal onto I2C Bus.
> +
> +  @param  PciIo              The pointer to PCI_IO_PROTOCOL.
> +
> +**/
> +VOID
> +I2cSendAck (
> +  EFI_PCI_IO_PROTOCOL    *PciIo
> +  )
> +{
> +  I2cPinWrite (PciIo, I2CCLK_OUT, 1);
> +  I2cPinWrite (PciIo, I2CDAT_OUT, 1);
> +  I2cPinWrite (PciIo, I2CDAT_OUT, 0);
> +  I2cPinWrite (PciIo, I2CCLK_OUT, 0);
> +}
> +
> +/**
> +  Start a I2C transfer on I2C Bus.
> +
> +  @param  PciIo              The pointer to PCI_IO_PROTOCOL.
> +
> +**/
> +VOID
> +I2cStart (
> +  EFI_PCI_IO_PROTOCOL    *PciIo
> +  )
> +{
> +  //
> +  // Init CLK and DAT pins
> +  //
> +  I2cPinWrite (PciIo, I2CCLK_OUT, 1);
> +  I2cPinWrite (PciIo, I2CDAT_OUT, 1);
> +  //
> +  // Start a I2C transfer, set SDA low from high, when SCL is high
> +  //
> +  I2cPinWrite (PciIo, I2CDAT_OUT, 0);
> +  I2cPinWrite (PciIo, I2CCLK_OUT, 0);
> +}
> +
> +/**
> +  Stop a I2C transfer on I2C Bus.
> +
> +  @param  PciIo              The pointer to PCI_IO_PROTOCOL.
> +
> +**/
> +VOID
> +I2cStop (
> +  EFI_PCI_IO_PROTOCOL    *PciIo
> +  )
> +{
> +  //
> +  // Stop a I2C transfer, set SDA high from low, when SCL is high
> +  //
> +  I2cPinWrite (PciIo, I2CDAT_OUT, 0);
> +  I2cPinWrite (PciIo, I2CCLK_OUT, 1);
> +  I2cPinWrite (PciIo, I2CDAT_OUT, 1);
> +}
> +
> +/**
> +  Read one byte data on I2C Bus.
> +
> +  Read one byte data from the slave device connectet to I2C Bus.
> +  If Data is NULL, then ASSERT().
> +
> +  @param  PciIo              The pointer to PCI_IO_PROTOCOL.
> +  @param  DeviceAddress      Slave device's address.
> +  @param  RegisterAddress    The register address on slave device.
> +  @param  Data               The pointer to returned data if EFI_SUCCESS
> returned.
> +
> +  @retval EFI_DEVICE_ERROR
> +  @retval EFI_SUCCESS
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +I2cReadByte (
> +  EFI_PCI_IO_PROTOCOL    *PciIo,
> +  UINT8                  DeviceAddress,
> +  UINT8                  RegisterAddress,
> +  UINT8                  *Data
> +  )
> +{
> +  ASSERT (Data != NULL);
> +
> +  //
> +  // Start I2C transfer
> +  //
> +  I2cStart (PciIo);
> +
> +  //
> +  // Send slave address with enabling write flag
> +  //
> +  I2cSendByte (PciIo, (UINT8) (DeviceAddress & 0xfe));
> +
> +  //
> +  // Wait for ACK signal
> +  //
> +  if (I2cWaitAck (PciIo) == FALSE) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Send register address
> +  //
> +  I2cSendByte (PciIo, RegisterAddress);
> +
> +  //
> +  // Wait for ACK signal
> +  //
> +  if (I2cWaitAck (PciIo) == FALSE) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Send slave address with enabling read flag
> +  //
> +  I2cSendByte (PciIo, (UINT8) (DeviceAddress | 0x01));
> +
> +  //
> +  // Wait for ACK signal
> +  //
> +  if (I2cWaitAck (PciIo) == FALSE) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Read byte data from I2C Bus
> +  //
> +  *Data = I2cReceiveByte (PciIo);
> +
> +  //
> +  // Send ACK signal onto I2C Bus
> +  //
> +  I2cSendAck (PciIo);
> +
> +  //
> +  // Stop a I2C transfer
> +  //
> +  I2cStop (PciIo);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Write one byte data onto I2C Bus.
> +
> +  Write one byte data to the slave device connectet to I2C Bus.
> +  If Data is NULL, then ASSERT().
> +
> +  @param  PciIo              The pointer to PCI_IO_PROTOCOL.
> +  @param  DeviceAddress      Slave device's address.
> +  @param  RegisterAddress    The register address on slave device.
> +  @param  Data               The pointer to write data.
> +
> +  @retval EFI_DEVICE_ERROR
> +  @retval EFI_SUCCESS
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +I2cWriteByte (
> +  EFI_PCI_IO_PROTOCOL    *PciIo,
> +  UINT8                  DeviceAddress,
> +  UINT8                  RegisterAddress,
> +  UINT8                  *Data
> +  )
> +{
> +  ASSERT (Data != NULL);
> +
> +  I2cStart (PciIo);
> +  //
> +  // Send slave address with enabling write flag
> +  //
> +  I2cSendByte (PciIo, (UINT8) (DeviceAddress & 0xfe));
> +
> +  //
> +  // Wait for ACK signal
> +  //
> +  if (I2cWaitAck (PciIo) == FALSE) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Send register address
> +  //
> +  I2cSendByte (PciIo, RegisterAddress);
> +
> +  //
> +  // Wait for ACK signal
> +  //
> +  if (I2cWaitAck (PciIo) == FALSE) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Send byte data onto I2C Bus
> +  //
> +  I2cSendByte (PciIo, *Data);
> +
> +  //
> +  // Wait for ACK signal
> +  //
> +  if (I2cWaitAck (PciIo) == FALSE) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Stop a I2C transfer
> +  //
> +  I2cStop (PciIo);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +
> diff --git a/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.h
> b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.h
> new file mode 100644
> index 0000000000..505575cc99
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.h
> @@ -0,0 +1,62 @@
> +/** @file
> +  I2c Bus byte read/write functions.
> +
> +  Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _CIRRUS_LOGIC_I2C_H_
> +#define _CIRRUS_LOGIC_I2C_H_
> +
> +#include <Protocol/PciIo.h>
> +
> +/**
> +  Read one byte data on I2C Bus.
> +
> +  Read one byte data from the slave device connectet to I2C Bus.
> +  If Data is NULL, then ASSERT().
> +
> +  @param  PciIo              The pointer to PCI_IO_PROTOCOL.
> +  @param  DeviceAddress      Slave device's address.
> +  @param  RegisterAddress    The register address on slave device.
> +  @param  Data               The pointer to returned data if EFI_SUCCESS
> returned.
> +
> +  @retval EFI_DEVICE_ERROR
> +  @retval EFI_SUCCESS
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +I2cReadByte (
> +  EFI_PCI_IO_PROTOCOL    *PciIo,
> +  UINT8                  DeviceAddress,
> +  UINT8                  RegisterAddress,
> +  UINT8                  *Data
> +  );
> +
> +/**
> +  Write one byte data onto I2C Bus.
> +
> +  Write one byte data to the slave device connectet to I2C Bus.
> +  If Data is NULL, then ASSERT().
> +
> +  @param  PciIo              The pointer to PCI_IO_PROTOCOL.
> +  @param  DeviceAddress      Slave device's address.
> +  @param  RegisterAddress    The register address on slave device.
> +  @param  Data               The pointer to write data.
> +
> +  @retval EFI_DEVICE_ERROR
> +  @retval EFI_SUCCESS
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +I2cWriteByte (
> +  EFI_PCI_IO_PROTOCOL    *PciIo,
> +  UINT8                  DeviceAddress,
> +  UINT8                  RegisterAddress,
> +  UINT8                  *Data
> +  );
> +
> +#endif
> diff --git
> a/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430UgaDraw.c
> b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430UgaDraw.c
> new file mode 100644
> index 0000000000..bdcbd3450c
> --- /dev/null
> +++
> b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430UgaDraw.c
> @@ -0,0 +1,412 @@
> +/** @file
> +  This file produces the graphics abstration of UGA Draw. It is called by
> +  CirrusLogic5430.c file which deals with the EFI 1.1 driver model.
> +  This file just does graphics.
> +
> +  Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "CirrusLogic5430.h"
> +
> +//
> +// UGA Draw Protocol Member Functions
> +//
> +EFI_STATUS
> +EFIAPI
> +CirrusLogic5430UgaDrawGetMode (
> +  IN  EFI_UGA_DRAW_PROTOCOL *This,
> +  OUT UINT32                *HorizontalResolution,
> +  OUT UINT32                *VerticalResolution,
> +  OUT UINT32                *ColorDepth,
> +  OUT UINT32                *RefreshRate
> +  )
> +{
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;
> +
> +  Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS
> (This);
> +
> +  if (Private->HardwareNeedsStarting) {
> +    return EFI_NOT_STARTED;
> +  }
> +
> +  if ((HorizontalResolution == NULL) ||
> +      (VerticalResolution == NULL)   ||
> +      (ColorDepth == NULL)           ||
> +      (RefreshRate == NULL)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *HorizontalResolution = Private->ModeData[Private-
> >CurrentMode].HorizontalResolution;
> +  *VerticalResolution   = Private->ModeData[Private-
> >CurrentMode].VerticalResolution;
> +  *ColorDepth           = Private->ModeData[Private-
> >CurrentMode].ColorDepth;
> +  *RefreshRate          = Private->ModeData[Private-
> >CurrentMode].RefreshRate;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +CirrusLogic5430UgaDrawSetMode (
> +  IN  EFI_UGA_DRAW_PROTOCOL *This,
> +  IN  UINT32                HorizontalResolution,
> +  IN  UINT32                VerticalResolution,
> +  IN  UINT32                ColorDepth,
> +  IN  UINT32                RefreshRate
> +  )
> +{
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;
> +  UINTN                           Index;
> +
> +  Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS
> (This);
> +
> +  for (Index = 0; Index < Private->MaxMode; Index++) {
> +
> +    if (HorizontalResolution != Private-
> >ModeData[Index].HorizontalResolution) {
> +      continue;
> +    }
> +
> +    if (VerticalResolution != Private->ModeData[Index].VerticalResolution) {
> +      continue;
> +    }
> +
> +    if (ColorDepth != Private->ModeData[Index].ColorDepth) {
> +      continue;
> +    }
> +
> +    if (RefreshRate != Private->ModeData[Index].RefreshRate) {
> +      continue;
> +    }
> +
> +    if (Private->LineBuffer) {
> +      gBS->FreePool (Private->LineBuffer);
> +    }
> +
> +    Private->LineBuffer = NULL;
> +    Private->LineBuffer = AllocatePool (HorizontalResolution);
> +    if (Private->LineBuffer == NULL) {
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +
> +    InitializeGraphicsMode (Private, &CirrusLogic5430VideoModes[Private-
> >ModeData[Index].ModeNumber]);
> +
> +    Private->CurrentMode            = Index;
> +
> +    Private->HardwareNeedsStarting  = FALSE;
> +
> +    return EFI_SUCCESS;
> +  }
> +
> +  return EFI_NOT_FOUND;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +CirrusLogic5430UgaDrawBlt (
> +  IN  EFI_UGA_DRAW_PROTOCOL     *This,
> +  IN  EFI_UGA_PIXEL             *BltBuffer, OPTIONAL
> +  IN  EFI_UGA_BLT_OPERATION     BltOperation,
> +  IN  UINTN                     SourceX,
> +  IN  UINTN                     SourceY,
> +  IN  UINTN                     DestinationX,
> +  IN  UINTN                     DestinationY,
> +  IN  UINTN                     Width,
> +  IN  UINTN                     Height,
> +  IN  UINTN                     Delta
> +  )
> +{
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;
> +  EFI_TPL                         OriginalTPL;
> +  UINTN                           DstY;
> +  UINTN                           SrcY;
> +  EFI_UGA_PIXEL                   *Blt;
> +  UINTN                           X;
> +  UINT8                           Pixel;
> +  UINT32                          WidePixel;
> +  UINTN                           ScreenWidth;
> +  UINTN                           Offset;
> +  UINTN                           SourceOffset;
> +
> +  Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS
> (This);
> +
> +  if ((UINT32)BltOperation >= EfiUgaBltMax) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (Width == 0 || Height == 0) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // If Delta is zero, then the entire BltBuffer is being used, so Delta
> +  // is the number of bytes in each row of BltBuffer.  Since BltBuffer is Width
> pixels size,
> +  // the number of bytes in each row can be computed.
> +  //
> +  if (Delta == 0) {
> +    Delta = Width * sizeof (EFI_UGA_PIXEL);
> +  }
> +
> +  //
> +  // We need to fill the Virtual Screen buffer with the blt data.
> +  // The virtual screen is upside down, as the first row is the bootom row of
> +  // the image.
> +  //
> +
> +  //
> +  // Make sure the SourceX, SourceY, DestinationX, DestinationY, Width,
> and Height parameters
> +  // are valid for the operation and the current screen geometry.
> +  //
> +  if (BltOperation == EfiUgaVideoToBltBuffer) {
> +    //
> +    // Video to BltBuffer: Source is Video, destination is BltBuffer
> +    //
> +    if (SourceY + Height > Private->ModeData[Private-
> >CurrentMode].VerticalResolution) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +
> +    if (SourceX + Width > Private->ModeData[Private-
> >CurrentMode].HorizontalResolution) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +  } else {
> +    //
> +    // BltBuffer to Video: Source is BltBuffer, destination is Video
> +    //
> +    if (DestinationY + Height > Private->ModeData[Private-
> >CurrentMode].VerticalResolution) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +
> +    if (DestinationX + Width > Private->ModeData[Private-
> >CurrentMode].HorizontalResolution) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +  }
> +  //
> +  // We have to raise to TPL Notify, so we make an atomic write the frame
> buffer.
> +  // We would not want a timer based event (Cursor, ...) to come in while
> we are
> +  // doing this operation.
> +  //
> +  OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);
> +
> +  switch (BltOperation) {
> +  case EfiUgaVideoToBltBuffer:
> +    //
> +    // Video to BltBuffer: Source is Video, destination is BltBuffer
> +    //
> +    for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY);
> SrcY++, DstY++) {
> +
> +      Offset = (SrcY * Private->ModeData[Private-
> >CurrentMode].HorizontalResolution) + SourceX;
> +      if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {
> +        Private->PciIo->Mem.Read (
> +                              Private->PciIo,
> +                              EfiPciIoWidthUint32,
> +                              0,
> +                              Offset,
> +                              Width >> 2,
> +                              Private->LineBuffer
> +                              );
> +      } else {
> +        Private->PciIo->Mem.Read (
> +                              Private->PciIo,
> +                              EfiPciIoWidthUint8,
> +                              0,
> +                              Offset,
> +                              Width,
> +                              Private->LineBuffer
> +                              );
> +      }
> +
> +      for (X = 0; X < Width; X++) {
> +        Blt         = (EFI_UGA_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Delta) +
> (DestinationX + X) * sizeof (EFI_UGA_PIXEL));
> +
> +        Blt->Red    = (UINT8) (Private->LineBuffer[X] & 0xe0);
> +        Blt->Green  = (UINT8) ((Private->LineBuffer[X] & 0x1c) << 3);
> +        Blt->Blue   = (UINT8) ((Private->LineBuffer[X] & 0x03) << 6);
> +      }
> +    }
> +    break;
> +
> +  case EfiUgaVideoToVideo:
> +    //
> +    // Perform hardware acceleration for Video to Video operations
> +    //
> +    ScreenWidth   = Private->ModeData[Private-
> >CurrentMode].HorizontalResolution;
> +    SourceOffset  = (SourceY * Private->ModeData[Private-
> >CurrentMode].HorizontalResolution) + (SourceX);
> +    Offset        = (DestinationY * Private->ModeData[Private-
> >CurrentMode].HorizontalResolution) + (DestinationX);
> +
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0000);
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0010);
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0012);
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0014);
> +
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0001);
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0011);
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0013);
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0015);
> +
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Width << 8) &
> 0xff00) | 0x20));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Width & 0xff00) |
> 0x21));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Height << 8) &
> 0xff00) | 0x22));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Height & 0xff00) |
> 0x23));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8)
> & 0xff00) | 0x24));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth &
> 0xff00) | 0x25));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8)
> & 0xff00) | 0x26));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth &
> 0xff00) | 0x27));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) << 8) &
> 0xff00) | 0x28));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 0) &
> 0xff00) | 0x29));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 8) &
> 0xff00) | 0x2a));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) <<
> 8) & 0xff00) | 0x2c));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >>
> 0) & 0xff00) | 0x2d));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >>
> 8) & 0xff00) | 0x2e));
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x002f);
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0030);
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0d32);
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0033);
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0034);
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0035);
> +
> +    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0231);
> +
> +    outb (Private, GRAPH_ADDRESS_REGISTER, 0x31);
> +    while ((inb (Private, GRAPH_DATA_REGISTER) & 0x01) == 0x01)
> +      ;
> +    break;
> +
> +  case EfiUgaVideoFill:
> +    Blt       = BltBuffer;
> +    Pixel     = (UINT8) ((Blt->Red & 0xe0) | ((Blt->Green >> 3) & 0x1c) | ((Blt-
> >Blue >> 6) & 0x03));
> +    WidePixel = (Pixel << 8) | Pixel;
> +    WidePixel = (WidePixel << 16) | WidePixel;
> +
> +    if (DestinationX == 0 && Width == Private->ModeData[Private-
> >CurrentMode].HorizontalResolution) {
> +      Offset = DestinationY * Private->ModeData[Private-
> >CurrentMode].HorizontalResolution;
> +      if (((Offset & 0x03) == 0) && (((Width * Height) & 0x03) == 0)) {
> +        Private->PciIo->Mem.Write (
> +                              Private->PciIo,
> +                              EfiPciIoWidthFillUint32,
> +                              0,
> +                              Offset,
> +                              (Width * Height) >> 2,
> +                              &WidePixel
> +                              );
> +      } else {
> +        Private->PciIo->Mem.Write (
> +                              Private->PciIo,
> +                              EfiPciIoWidthFillUint8,
> +                              0,
> +                              Offset,
> +                              Width * Height,
> +                              &Pixel
> +                              );
> +      }
> +    } else {
> +      for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY);
> SrcY++, DstY++) {
> +        Offset = (DstY * Private->ModeData[Private-
> >CurrentMode].HorizontalResolution) + DestinationX;
> +        if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {
> +          Private->PciIo->Mem.Write (
> +                                Private->PciIo,
> +                                EfiPciIoWidthFillUint32,
> +                                0,
> +                                Offset,
> +                                Width >> 2,
> +                                &WidePixel
> +                                );
> +        } else {
> +          Private->PciIo->Mem.Write (
> +                                Private->PciIo,
> +                                EfiPciIoWidthFillUint8,
> +                                0,
> +                                Offset,
> +                                Width,
> +                                &Pixel
> +                                );
> +        }
> +      }
> +    }
> +    break;
> +
> +  case EfiUgaBltBufferToVideo:
> +    for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY);
> SrcY++, DstY++) {
> +
> +      for (X = 0; X < Width; X++) {
> +        Blt                     = (EFI_UGA_PIXEL *) ((UINT8 *) BltBuffer + (SrcY * Delta)
> + (SourceX + X) * sizeof (EFI_UGA_PIXEL));
> +        Private->LineBuffer[X]  = (UINT8) ((Blt->Red & 0xe0) | ((Blt->Green >> 3)
> & 0x1c) | ((Blt->Blue >> 6) & 0x03));
> +      }
> +
> +      Offset = (DstY * Private->ModeData[Private-
> >CurrentMode].HorizontalResolution) + DestinationX;
> +
> +      if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {
> +        Private->PciIo->Mem.Write (
> +                              Private->PciIo,
> +                              EfiPciIoWidthUint32,
> +                              0,
> +                              Offset,
> +                              Width >> 2,
> +                              Private->LineBuffer
> +                              );
> +      } else {
> +        Private->PciIo->Mem.Write (
> +                              Private->PciIo,
> +                              EfiPciIoWidthUint8,
> +                              0,
> +                              Offset,
> +                              Width,
> +                              Private->LineBuffer
> +                              );
> +      }
> +    }
> +    break;
> +
> +  default:
> +    break;
> +  }
> +
> +  gBS->RestoreTPL (OriginalTPL);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +//
> +// Construction and Destruction functions
> +//
> +EFI_STATUS
> +CirrusLogic5430UgaDrawConstructor (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
> +  )
> +{
> +  EFI_UGA_DRAW_PROTOCOL *UgaDraw;
> +
> +  //
> +  // Fill in Private->UgaDraw protocol
> +  //
> +  UgaDraw           = &Private->UgaDraw;
> +
> +  UgaDraw->GetMode  = CirrusLogic5430UgaDrawGetMode;
> +  UgaDraw->SetMode  = CirrusLogic5430UgaDrawSetMode;
> +  UgaDraw->Blt      = CirrusLogic5430UgaDrawBlt;
> +
> +  //
> +  // Initialize the private data
> +  //
> +  Private->CurrentMode            = 0;
> +  Private->HardwareNeedsStarting  = TRUE;
> +  Private->LineBuffer             = NULL;
> +
> +  //
> +  // Initialize the hardware
> +  //
> +  UgaDraw->SetMode (
> +            UgaDraw,
> +            Private->ModeData[Private->CurrentMode].HorizontalResolution,
> +            Private->ModeData[Private->CurrentMode].VerticalResolution,
> +            Private->ModeData[Private->CurrentMode].ColorDepth,
> +            Private->ModeData[Private->CurrentMode].RefreshRate
> +            );
> +  DrawLogo (
> +    Private,
> +    Private->ModeData[Private->CurrentMode].HorizontalResolution,
> +    Private->ModeData[Private->CurrentMode].VerticalResolution
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git a/Drivers/OptionRomPkg/CirrusLogic5430Dxe/ComponentName.c
> b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/ComponentName.c
> new file mode 100644
> index 0000000000..3792937bed
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/ComponentName.c
> @@ -0,0 +1,203 @@
> +/** @file
> +  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "CirrusLogic5430.h"
> +
> +//
> +// EFI Component Name Protocol
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED
> EFI_COMPONENT_NAME_PROTOCOL  gCirrusLogic5430ComponentName = {
> +  CirrusLogic5430ComponentNameGetDriverName,
> +  CirrusLogic5430ComponentNameGetControllerName,
> +  "eng"
> +};
> +
> +//
> +// EFI Component Name 2 Protocol
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED
> EFI_COMPONENT_NAME2_PROTOCOL gCirrusLogic5430ComponentName2 =
> {
> +  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)
> CirrusLogic5430ComponentNameGetDriverName,
> +  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)
> CirrusLogic5430ComponentNameGetControllerName,
> +  "en"
> +};
> +
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
> mCirrusLogic5430DriverNameTable[] = {
> +  { "eng;en", L"Cirrus Logic 5430 Driver" },
> +  { NULL , NULL }
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
> mCirrusLogic5430ControllerNameTable[] = {
> +  { "eng;en", L"Cirrus Logic 5430 PCI Adapter" },
> +  { NULL , NULL }
> +};
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the driver.
> +
> +  This function retrieves the user readable name of a driver in the form of a
> +  Unicode string. If the driver specified by This has a user readable name in
> +  the language specified by Language, then a pointer to the driver name is
> +  returned in DriverName, and EFI_SUCCESS is returned. If the driver
> specified
> +  by This does not support the language specified by Language,
> +  then EFI_UNSUPPORTED is returned.
> +
> +  @param  This[in]              A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> +                                array indicating the language. This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified
> +                                in RFC 4646 or ISO 639-2 language code format.
> +
> +  @param  DriverName[out]       A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                driver specified by This in the language
> +                                specified by Language.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> +                                This and the language specified by Language was
> +                                returned in DriverName.
> +
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CirrusLogic5430ComponentNameGetDriverName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
> +  IN  CHAR8                        *Language,
> +  OUT CHAR16                       **DriverName
> +  )
> +{
> +  return LookupUnicodeString2 (
> +           Language,
> +           This->SupportedLanguages,
> +           mCirrusLogic5430DriverNameTable,
> +           DriverName,
> +           (BOOLEAN)(This == &gCirrusLogic5430ComponentName)
> +           );
> +}
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the controller
> +  that is being managed by a driver.
> +
> +  This function retrieves the user readable name of the controller specified
> by
> +  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> +  driver specified by This has a user readable name in the language specified
> by
> +  Language, then a pointer to the controller name is returned in
> ControllerName,
> +  and EFI_SUCCESS is returned.  If the driver specified by This is not
> currently
> +  managing the controller specified by ControllerHandle and ChildHandle,
> +  then EFI_UNSUPPORTED is returned.  If the driver specified by This does
> not
> +  support the language specified by Language, then EFI_UNSUPPORTED is
> returned.
> +
> +  @param  This[in]              A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> +  @param  ControllerHandle[in]  The handle of a controller that the driver
> +                                specified by This is managing.  This handle
> +                                specifies the controller whose name is to be
> +                                returned.
> +
> +  @param  ChildHandle[in]       The handle of the child controller to retrieve
> +                                the name of.  This is an optional parameter that
> +                                may be NULL.  It will be NULL for device
> +                                drivers.  It will also be NULL for a bus drivers
> +                                that wish to retrieve the name of the bus
> +                                controller.  It will not be NULL for a bus
> +                                driver that wishes to retrieve the name of a
> +                                child controller.
> +
> +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> +                                array indicating the language.  This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified in
> +                                RFC 4646 or ISO 639-2 language code format.
> +
> +  @param  ControllerName[out]   A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                controller specified by ControllerHandle and
> +                                ChildHandle in the language specified by
> +                                Language from the point of view of the driver
> +                                specified by This.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the user readable name
> in
> +                                the language specified by Language for the
> +                                driver specified by This was returned in
> +                                DriverName.
> +
> +  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a
> valid
> +                                EFI_HANDLE.
> +
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> +                                managing the controller specified by
> +                                ControllerHandle and ChildHandle.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CirrusLogic5430ComponentNameGetControllerName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
> +  IN  EFI_HANDLE                                      ControllerHandle,
> +  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
> +  IN  CHAR8                                           *Language,
> +  OUT CHAR16                                          **ControllerName
> +  )
> +{
> +  EFI_STATUS                      Status;
> +
> +  //
> +  // This is a device driver, so ChildHandle must be NULL.
> +  //
> +  if (ChildHandle != NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Make sure this driver is currently managing ControllHandle
> +  //
> +  Status = EfiTestManagedDevice (
> +             ControllerHandle,
> +             gCirrusLogic5430DriverBinding.DriverBindingHandle,
> +             &gEfiPciIoProtocolGuid
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Get the Cirrus Logic 5430's Device structure
> +  //
> +  return LookupUnicodeString2 (
> +           Language,
> +           This->SupportedLanguages,
> +           mCirrusLogic5430ControllerNameTable,
> +           ControllerName,
> +           (BOOLEAN)(This == &gCirrusLogic5430ComponentName)
> +           );
> +}
> diff --git
> a/Drivers/OptionRomPkg/CirrusLogic5430Dxe/DriverSupportedEfiVersion.c
> b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/DriverSupportedEfiVersion.c
> new file mode 100644
> index 0000000000..2d8412bf53
> --- /dev/null
> +++
> b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/DriverSupportedEfiVersion.c
> @@ -0,0 +1,14 @@
> +/** @file
> +  Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +  Module Name:  DriverSupportEfiVersion.c
> +
> +**/
> +#include "CirrusLogic5430.h"
> +
> +EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL
> gCirrusLogic5430DriverSupportedEfiVersion = {
> +  sizeof (EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL), // Size of
> Protocol structure.
> +  0                                                   // Version number to be filled at start up.
> +};
> +
> diff --git a/Drivers/OptionRomPkg/CirrusLogic5430Dxe/Edid.c
> b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/Edid.c
> new file mode 100644
> index 0000000000..5f288d219e
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/CirrusLogic5430Dxe/Edid.c
> @@ -0,0 +1,525 @@
> +/** @file
> +  Read EDID information and parse EDID information.
> +
> +  Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "CirrusLogic5430.h"
> +#include "CirrusLogic5430I2c.h"
> +
> +//
> +// EDID block
> +//
> +typedef struct {
> +  UINT8   Header[8];                        //EDID header "00 FF FF FF FF FF FF 00"
> +  UINT16  ManufactureName;                  //EISA 3-character ID
> +  UINT16  ProductCode;                      //Vendor assigned code
> +  UINT32  SerialNumber;                     //32-bit serial number
> +  UINT8   WeekOfManufacture;                //Week number
> +  UINT8   YearOfManufacture;                //Year
> +  UINT8   EdidVersion;                      //EDID Structure Version
> +  UINT8   EdidRevision;                     //EDID Structure Revision
> +  UINT8   VideoInputDefinition;
> +  UINT8   MaxHorizontalImageSize;           //cm
> +  UINT8   MaxVerticalImageSize;             //cm
> +  UINT8   DisplayTransferCharacteristic;
> +  UINT8   FeatureSupport;
> +  UINT8   RedGreenLowBits;                  //Rx1 Rx0 Ry1 Ry0 Gx1 Gx0 Gy1Gy0
> +  UINT8   BlueWhiteLowBits;                 //Bx1 Bx0 By1 By0 Wx1 Wx0 Wy1 Wy0
> +  UINT8   RedX;                             //Red-x Bits 9 - 2
> +  UINT8   RedY;                             //Red-y Bits 9 - 2
> +  UINT8   GreenX;                           //Green-x Bits 9 - 2
> +  UINT8   GreenY;                           //Green-y Bits 9 - 2
> +  UINT8   BlueX;                            //Blue-x Bits 9 - 2
> +  UINT8   BlueY;                            //Blue-y Bits 9 - 2
> +  UINT8   WhiteX;                           //White-x Bits 9 - 2
> +  UINT8   WhiteY;                           //White-x Bits 9 - 2
> +  UINT8   EstablishedTimings[3];
> +  UINT8   StandardTimingIdentification[16];
> +  UINT8   DetailedTimingDescriptions[72];
> +  UINT8   ExtensionFlag;                    //Number of (optional) 128-byte EDID
> extension blocks to follow
> +  UINT8   Checksum;
> +} EDID_BLOCK;
> +
> +#define EDID_BLOCK_SIZE                        128
> +#define VBE_EDID_ESTABLISHED_TIMING_MAX_NUMBER 17
> +
> +typedef struct {
> +  UINT16  HorizontalResolution;
> +  UINT16  VerticalResolution;
> +  UINT16  RefreshRate;
> +} EDID_TIMING;
> +
> +typedef struct {
> +  UINT32  ValidNumber;
> +  UINT32  Key[VBE_EDID_ESTABLISHED_TIMING_MAX_NUMBER];
> +} VALID_EDID_TIMING;
> +
> +//
> +// Standard timing defined by VESA EDID
> +//
> +EDID_TIMING mVbeEstablishedEdidTiming[] = {
> +  //
> +  // Established Timing I
> +  //
> +  {800, 600, 60},
> +  {800, 600, 56},
> +  {640, 480, 75},
> +  {640, 480, 72},
> +  {640, 480, 67},
> +  {640, 480, 60},
> +  {720, 400, 88},
> +  {720, 400, 70},
> +  //
> +  // Established Timing II
> +  //
> +  {1280, 1024, 75},
> +  {1024,  768, 75},
> +  {1024,  768, 70},
> +  {1024,  768, 60},
> +  {1024,  768, 87},
> +  {832,   624, 75},
> +  {800,   600, 75},
> +  {800,   600, 72},
> +  //
> +  // Established Timing III
> +  //
> +  {1152, 870, 75}
> +};
> +
> +/**
> +  Read EDID information from I2C Bus on CirrusLogic.
> +
> +  @param  Private             Pointer to CIRRUS_LOGIC_5430_PRIVATE_DATA.
> +  @param  EdidDataBlock       Pointer to EDID data block.
> +  @param  EdidSize            Returned EDID block size.
> +
> +  @retval EFI_UNSUPPORTED
> +  @retval EFI_SUCCESS
> +
> +**/
> +EFI_STATUS
> +ReadEdidData (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA     *Private,
> +  UINT8                              **EdidDataBlock,
> +  UINTN                              *EdidSize
> +  )
> +{
> +  UINTN             Index;
> +  UINT8             EdidData[EDID_BLOCK_SIZE * 2];
> +  UINT8             *ValidEdid;
> +  UINT64            Signature;
> +
> +  for (Index = 0; Index < EDID_BLOCK_SIZE * 2; Index ++) {
> +    I2cReadByte (Private->PciIo, 0xa0, (UINT8)Index, &EdidData[Index]);
> +  }
> +
> +  //
> +  // Search for the EDID signature
> +  //
> +  ValidEdid = &EdidData[0];
> +  Signature = 0x00ffffffffffff00ull;
> +  for (Index = 0; Index < EDID_BLOCK_SIZE * 2; Index ++, ValidEdid ++) {
> +    if (CompareMem (ValidEdid, &Signature, 8) == 0) {
> +      break;
> +    }
> +  }
> +
> +  if (Index == 256) {
> +    //
> +    // No EDID signature found
> +    //
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  *EdidDataBlock = AllocateCopyPool (
> +                     EDID_BLOCK_SIZE,
> +                     ValidEdid
> +                     );
> +  if (*EdidDataBlock == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  //
> +  // Currently only support EDID 1.x
> +  //
> +  *EdidSize = EDID_BLOCK_SIZE;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Generate a search key for a specified timing data.
> +
> +  @param  EdidTiming             Pointer to EDID timing
> +
> +  @return The 32 bit unique key for search.
> +
> +**/
> +UINT32
> +CalculateEdidKey (
> +  EDID_TIMING       *EdidTiming
> +  )
> +{
> +  UINT32 Key;
> +
> +  //
> +  // Be sure no conflicts for all standard timing defined by VESA.
> +  //
> +  Key = (EdidTiming->HorizontalResolution * 2) + EdidTiming-
> >VerticalResolution;
> +  return Key;
> +}
> +
> +/**
> +  Search a specified Timing in all the valid EDID timings.
> +
> +  @param  ValidEdidTiming        All valid EDID timing information.
> +  @param  EdidTiming             The Timing to search for.
> +
> +  @retval TRUE                   Found.
> +  @retval FALSE                  Not found.
> +
> +**/
> +BOOLEAN
> +SearchEdidTiming (
> +  VALID_EDID_TIMING *ValidEdidTiming,
> +  EDID_TIMING       *EdidTiming
> +  )
> +{
> +  UINT32 Index;
> +  UINT32 Key;
> +
> +  Key = CalculateEdidKey (EdidTiming);
> +
> +  for (Index = 0; Index < ValidEdidTiming->ValidNumber; Index ++) {
> +    if (Key == ValidEdidTiming->Key[Index]) {
> +      return TRUE;
> +    }
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +  Parse the Established Timing and Standard Timing in EDID data block.
> +
> +  @param  EdidBuffer             Pointer to EDID data block
> +  @param  ValidEdidTiming        Valid EDID timing information
> +
> +  @retval TRUE                   The EDID data is valid.
> +  @retval FALSE                  The EDID data is invalid.
> +
> +**/
> +BOOLEAN
> +ParseEdidData (
> +  UINT8                         *EdidBuffer,
> +  VALID_EDID_TIMING             *ValidEdidTiming
> +  )
> +{
> +  UINT8        CheckSum;
> +  UINT32       Index;
> +  UINT32       ValidNumber;
> +  UINT32       TimingBits;
> +  UINT8        *BufferIndex;
> +  UINT16       HorizontalResolution;
> +  UINT16       VerticalResolution;
> +  UINT8        AspectRatio;
> +  UINT8        RefreshRate;
> +  EDID_TIMING  TempTiming;
> +  EDID_BLOCK   *EdidDataBlock;
> +
> +  EdidDataBlock = (EDID_BLOCK *) EdidBuffer;
> +
> +  //
> +  // Check the checksum of EDID data
> +  //
> +  CheckSum = 0;
> +  for (Index = 0; Index < EDID_BLOCK_SIZE; Index ++) {
> +    CheckSum = (UINT8) (CheckSum + EdidBuffer[Index]);
> +  }
> +  if (CheckSum != 0) {
> +    return FALSE;
> +  }
> +
> +  ValidNumber = 0;
> +  SetMem (ValidEdidTiming, sizeof (VALID_EDID_TIMING), 0);
> +
> +  if ((EdidDataBlock->EstablishedTimings[0] != 0) ||
> +      (EdidDataBlock->EstablishedTimings[1] != 0) ||
> +      (EdidDataBlock->EstablishedTimings[2] != 0)
> +      ) {
> +    //
> +    // Established timing data
> +    //
> +    TimingBits = EdidDataBlock->EstablishedTimings[0] |
> +                 (EdidDataBlock->EstablishedTimings[1] << 8) |
> +                 ((EdidDataBlock->EstablishedTimings[2] & 0x80) << 9) ;
> +    for (Index = 0; Index < VBE_EDID_ESTABLISHED_TIMING_MAX_NUMBER;
> Index ++) {
> +      if (TimingBits & 0x1) {
> +        ValidEdidTiming->Key[ValidNumber] = CalculateEdidKey
> (&mVbeEstablishedEdidTiming[Index]);
> +        ValidNumber ++;
> +      }
> +      TimingBits = TimingBits >> 1;
> +    }
> +  } else {
> +    //
> +    // If no Established timing data, read the standard timing data
> +    //
> +    BufferIndex = &EdidDataBlock->StandardTimingIdentification[0];
> +    for (Index = 0; Index < 8; Index ++) {
> +      if ((BufferIndex[0] != 0x1) && (BufferIndex[1] != 0x1)){
> +        //
> +        // A valid Standard Timing
> +        //
> +        HorizontalResolution = (UINT16) (BufferIndex[0] * 8 + 248);
> +        AspectRatio = (UINT8) (BufferIndex[1] >> 6);
> +        switch (AspectRatio) {
> +          case 0:
> +            VerticalResolution = (UINT16) (HorizontalResolution / 16 * 10);
> +            break;
> +          case 1:
> +            VerticalResolution = (UINT16) (HorizontalResolution / 4 * 3);
> +            break;
> +          case 2:
> +            VerticalResolution = (UINT16) (HorizontalResolution / 5 * 4);
> +            break;
> +          case 3:
> +            VerticalResolution = (UINT16) (HorizontalResolution / 16 * 9);
> +            break;
> +          default:
> +            VerticalResolution = (UINT16) (HorizontalResolution / 4 * 3);
> +            break;
> +        }
> +        RefreshRate = (UINT8) ((BufferIndex[1] & 0x1f) + 60);
> +        TempTiming.HorizontalResolution = HorizontalResolution;
> +        TempTiming.VerticalResolution = VerticalResolution;
> +        TempTiming.RefreshRate = RefreshRate;
> +        ValidEdidTiming->Key[ValidNumber] = CalculateEdidKey
> (&TempTiming);
> +        ValidNumber ++;
> +      }
> +      BufferIndex += 2;
> +    }
> +  }
> +
> +  ValidEdidTiming->ValidNumber = ValidNumber;
> +  return TRUE;
> +}
> +
> +/**
> +  Construct the valid video modes for CirrusLogic5430.
> +
> +**/
> +EFI_STATUS
> +CirrusLogic5430VideoModeSetup (
> +  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
> +  )
> +{
> +  EFI_STATUS                             Status;
> +  UINT32                                 Index;
> +  BOOLEAN                                EdidFound;
> +  EFI_EDID_OVERRIDE_PROTOCOL             *EdidOverride;
> +  UINT32                                 EdidAttributes;
> +  BOOLEAN                                EdidOverrideFound;
> +  UINTN                                  EdidOverrideDataSize;
> +  UINT8                                  *EdidOverrideDataBlock;
> +  UINTN                                  EdidDiscoveredDataSize;
> +  UINT8                                  *EdidDiscoveredDataBlock;
> +  UINTN                                  EdidActiveDataSize;
> +  UINT8                                  *EdidActiveDataBlock;
> +  VALID_EDID_TIMING                      ValidEdidTiming;
> +  UINT32                                 ValidModeCount;
> +  CIRRUS_LOGIC_5430_MODE_DATA            *ModeData;
> +  BOOLEAN                                TimingMatch;
> +  CIRRUS_LOGIC_5430_VIDEO_MODES          *VideoMode;
> +  EDID_TIMING                            TempTiming;
> +
> +  //
> +  // setup EDID information
> +  //
> +  Private->EdidDiscovered.Edid       = NULL;
> +  Private->EdidDiscovered.SizeOfEdid = 0;
> +  Private->EdidActive.Edid           = NULL;
> +  Private->EdidActive.SizeOfEdid     = 0;
> +
> +  EdidFound               = FALSE;
> +  EdidOverrideFound       = FALSE;
> +  EdidAttributes          = 0xff;
> +  EdidOverrideDataSize    = 0;
> +  EdidOverrideDataBlock   = NULL;
> +  EdidActiveDataSize      = 0;
> +  EdidActiveDataBlock     = NULL;
> +  EdidDiscoveredDataBlock = NULL;
> +
> +  //
> +  // Find EDID Override protocol firstly, this protocol is installed by platform
> if needed.
> +  //
> +  Status = gBS->LocateProtocol (
> +                   &gEfiEdidOverrideProtocolGuid,
> +                   NULL,
> +                   (VOID **) &EdidOverride
> +                   );
> +  if (!EFI_ERROR (Status)) {
> +    //
> +    // Allocate double size of VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE to
> avoid overflow
> +    //
> +    EdidOverrideDataBlock = AllocatePool (EDID_BLOCK_SIZE * 2);
> +    if (NULL == EdidOverrideDataBlock) {
> +  		Status = EFI_OUT_OF_RESOURCES;
> +      goto Done;
> +    }
> +
> +    Status = EdidOverride->GetEdid (
> +                             EdidOverride,
> +                             Private->Handle,
> +                             &EdidAttributes,
> +                             &EdidOverrideDataSize,
> +                             (UINT8 **) &EdidOverrideDataBlock
> +                             );
> +    if (!EFI_ERROR (Status)  &&
> +         EdidAttributes == 0 &&
> +         EdidOverrideDataSize != 0) {
> +      //
> +      // Succeeded to get EDID Override Data
> +      //
> +      EdidOverrideFound = TRUE;
> +    }
> +  }
> +
> +  if (EdidOverrideFound != TRUE || EdidAttributes ==
> EFI_EDID_OVERRIDE_DONT_OVERRIDE) {
> +    //
> +    // If EDID Override data doesn't exist or
> EFI_EDID_OVERRIDE_DONT_OVERRIDE returned,
> +    // read EDID information through I2C Bus
> +    //
> +    if (ReadEdidData (Private, &EdidDiscoveredDataBlock,
> &EdidDiscoveredDataSize) == EFI_SUCCESS) {
> +      Private->EdidDiscovered.SizeOfEdid = (UINT32) EdidDiscoveredDataSize;
> +     	Private->EdidDiscovered.Edid = (UINT8 *) AllocateCopyPool (
> +                                                          EdidDiscoveredDataSize,
> +                                                          EdidDiscoveredDataBlock
> +
> 
> 								  );
> +
> +      if (NULL == Private->EdidDiscovered.Edid) {
> +     	  Status = EFI_OUT_OF_RESOURCES;
> +        goto Done;
> +      }
> +
> +      EdidActiveDataSize  = Private->EdidDiscovered.SizeOfEdid;
> +      EdidActiveDataBlock = Private->EdidDiscovered.Edid;
> +
> +      EdidFound = TRUE;
> +    }
> +  }
> +
> +  if (EdidFound != TRUE && EdidOverrideFound == TRUE) {
> +    EdidActiveDataSize  = EdidOverrideDataSize;
> +    EdidActiveDataBlock = EdidOverrideDataBlock;
> +    EdidFound = TRUE;
> + 	}
> +
> + 	if (EdidFound == TRUE) {
> +    //
> +    // Parse EDID data structure to retrieve modes supported by monitor
> +    //
> +    if (ParseEdidData ((UINT8 *) EdidActiveDataBlock, &ValidEdidTiming) ==
> TRUE) {
> +      //
> +      // Copy EDID Override Data to EDID Active Data
> +      //
> +      Private->EdidActive.SizeOfEdid = (UINT32) EdidActiveDataSize;
> +      Private->EdidActive.Edid = (UINT8 *) AllocateCopyPool (
> +                                             EdidActiveDataSize,
> +                                             EdidActiveDataBlock
> +                                             );
> +      if (NULL == Private->EdidActive.Edid) {
> +   		  Status = EFI_OUT_OF_RESOURCES;
> +        goto Done;
> +      }
> +    }
> +  } else {
> +    Private->EdidActive.SizeOfEdid = 0;
> +    Private->EdidActive.Edid = NULL;
> +    EdidFound = FALSE;
> +  }
> +
> +  if (EdidFound) {
> +    //
> +    // Initialize the private mode data with the supported modes.
> +    //
> +    ValidModeCount = 0;
> +    ModeData = &Private->ModeData[0];
> +    VideoMode = &CirrusLogic5430VideoModes[0];
> +    for (Index = 0; Index < CIRRUS_LOGIC_5430_MODE_COUNT; Index++) {
> +
> +      TimingMatch = TRUE;
> +
> +      //
> +      // Check whether match with CirrusLogic5430 video mode
> +      //
> +      TempTiming.HorizontalResolution = (UINT16) VideoMode->Width;
> +      TempTiming.VerticalResolution   = (UINT16) VideoMode->Height;
> +      TempTiming.RefreshRate          = (UINT16) VideoMode->RefreshRate;
> +      if (SearchEdidTiming (&ValidEdidTiming, &TempTiming) != TRUE) {
> +        TimingMatch = FALSE;
> +      }
> +
> +      //
> +      // Not export Mode 0x0 as GOP mode, this is not defined in spec.
> +      //
> +      if ((VideoMode->Width == 0) || (VideoMode->Height == 0)) {
> +        TimingMatch = FALSE;
> +      }
> +
> +      if (TimingMatch) {
> +        ModeData->ModeNumber = Index;
> +        ModeData->HorizontalResolution          = VideoMode->Width;
> +        ModeData->VerticalResolution            = VideoMode->Height;
> +        ModeData->ColorDepth                    = VideoMode->ColorDepth;
> +        ModeData->RefreshRate                   = VideoMode->RefreshRate;
> +
> +        ModeData ++;
> +        ValidModeCount ++;
> +      }
> +
> +      VideoMode ++;
> +    }
> +
> +    Private->MaxMode = ValidModeCount;
> +
> +  } else {
> +    //
> +    // If EDID information wasn't found
> +    //
> +    ModeData = &Private->ModeData[0];
> +    VideoMode = &CirrusLogic5430VideoModes[0];
> +    for (Index = 0; Index < CIRRUS_LOGIC_5430_MODE_COUNT; Index ++) {
> +      ModeData->ModeNumber = Index;
> +      ModeData->HorizontalResolution          = VideoMode->Width;
> +      ModeData->VerticalResolution            = VideoMode->Height;
> +      ModeData->ColorDepth                    = VideoMode->ColorDepth;
> +      ModeData->RefreshRate                   = VideoMode->RefreshRate;
> +
> +      ModeData ++ ;
> +      VideoMode ++;
> +    }
> +    Private->MaxMode = CIRRUS_LOGIC_5430_MODE_COUNT;
> +  }
> +
> +  if (EdidOverrideDataBlock != NULL) {
> +    FreePool (EdidOverrideDataBlock);
> +  }
> +
> +  return EFI_SUCCESS;
> +
> +Done:
> +  if (EdidOverrideDataBlock != NULL) {
> +    FreePool (EdidOverrideDataBlock);
> +  }
> +  if (Private->EdidDiscovered.Edid != NULL) {
> +    FreePool (Private->EdidDiscovered.Edid);
> +  }
> +  if (Private->EdidDiscovered.Edid != NULL) {
> +    FreePool (Private->EdidActive.Edid);
> +  }
> +
> +  return EFI_DEVICE_ERROR;
> +}
> diff --git a/Drivers/OptionRomPkg/Include/Library/BltLib.h
> b/Drivers/OptionRomPkg/Include/Library/BltLib.h
> new file mode 100644
> index 0000000000..48990a296d
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/Include/Library/BltLib.h
> @@ -0,0 +1,253 @@
> +/** @file
> +  Library for performing video blt operations
> +
> +  Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef __BLT_LIB__
> +#define __BLT_LIB__
> +
> +#include <Protocol/GraphicsOutput.h>
> +
> +
> +/**
> +  Configure the BltLib for a frame-buffer
> +
> +  @param[in] FrameBuffer      Pointer to the start of the frame buffer
> +  @param[in] FrameBufferInfo  Describes the frame buffer characteristics
> +
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - Blt operation success
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibConfigure (
> +  IN  VOID                                 *FrameBuffer,
> +  IN  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo
> +  );
> +
> +
> +/**
> +  Performs a UEFI Graphics Output Protocol Blt operation.
> +
> +  @param[in,out] BltBuffer     - The data to transfer to screen
> +  @param[in]     BltOperation  - The operation to perform
> +  @param[in]     SourceX       - The X coordinate of the source for
> BltOperation
> +  @param[in]     SourceY       - The Y coordinate of the source for
> BltOperation
> +  @param[in]     DestinationX  - The X coordinate of the destination for
> BltOperation
> +  @param[in]     DestinationY  - The Y coordinate of the destination for
> BltOperation
> +  @param[in]     Width         - The width of a rectangle in the blt rectangle in
> pixels
> +  @param[in]     Height        - The height of a rectangle in the blt rectangle in
> pixels
> +  @param[in]     Delta         - Not used for EfiBltVideoFill and
> EfiBltVideoToVideo operation.
> +                                 If a Delta of 0 is used, the entire BltBuffer will be
> operated on.
> +                                 If a subrectangle of the BltBuffer is used, then Delta
> represents
> +                                 the number of bytes in a row of the BltBuffer.
> +
> +  @retval  EFI_DEVICE_ERROR - A hardware error occured
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - Blt operation success
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibGopBlt (
> +  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL      *BltBuffer, OPTIONAL
> +  IN     EFI_GRAPHICS_OUTPUT_BLT_OPERATION  BltOperation,
> +  IN     UINTN                              SourceX,
> +  IN     UINTN                              SourceY,
> +  IN     UINTN                              DestinationX,
> +  IN     UINTN                              DestinationY,
> +  IN     UINTN                              Width,
> +  IN     UINTN                              Height,
> +  IN     UINTN                              Delta
> +  );
> +
> +
> +/**
> +  Performs a UEFI Graphics Output Protocol Blt Video Fill.
> +
> +  @param[in]  Color         Color to fill the region with
> +  @param[in]  DestinationX  X location to start fill operation
> +  @param[in]  DestinationY  Y location to start fill operation
> +  @param[in]  Width         Width (in pixels) to fill
> +  @param[in]  Height        Height to fill
> +
> +  @retval  EFI_DEVICE_ERROR - A hardware error occured
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - Blt operation success
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibVideoFill (
> +  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *Color,
> +  IN  UINTN                                 DestinationX,
> +  IN  UINTN                                 DestinationY,
> +  IN  UINTN                                 Width,
> +  IN  UINTN                                 Height
> +  );
> +
> +
> +/**
> +  Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation.
> +
> +  @param[out] BltBuffer     Output buffer for pixel color data
> +  @param[in]  SourceX       X location within video
> +  @param[in]  SourceY       Y location within video
> +  @param[in]  Width         Width (in pixels)
> +  @param[in]  Height        Height
> +
> +  @retval  EFI_DEVICE_ERROR - A hardware error occured
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - Blt operation success
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibVideoToBltBuffer (
> +  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
> +  IN  UINTN                                 SourceX,
> +  IN  UINTN                                 SourceY,
> +  IN  UINTN                                 Width,
> +  IN  UINTN                                 Height
> +  );
> +
> +
> +/**
> +  Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation
> +  with extended parameters.
> +
> +  @param[out] BltBuffer     Output buffer for pixel color data
> +  @param[in]  SourceX       X location within video
> +  @param[in]  SourceY       Y location within video
> +  @param[in]  DestinationX  X location within BltBuffer
> +  @param[in]  DestinationY  Y location within BltBuffer
> +  @param[in]  Width         Width (in pixels)
> +  @param[in]  Height        Height
> +  @param[in]  Delta         Number of bytes in a row of BltBuffer
> +
> +  @retval  EFI_DEVICE_ERROR - A hardware error occured
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - Blt operation success
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibVideoToBltBufferEx (
> +  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
> +  IN  UINTN                                 SourceX,
> +  IN  UINTN                                 SourceY,
> +  IN  UINTN                                 DestinationX,
> +  IN  UINTN                                 DestinationY,
> +  IN  UINTN                                 Width,
> +  IN  UINTN                                 Height,
> +  IN  UINTN                                 Delta
> +  );
> +
> +
> +/**
> +  Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation.
> +
> +  @param[in]  BltBuffer     Output buffer for pixel color data
> +  @param[in]  DestinationX  X location within video
> +  @param[in]  DestinationY  Y location within video
> +  @param[in]  Width         Width (in pixels)
> +  @param[in]  Height        Height
> +
> +  @retval  EFI_DEVICE_ERROR - A hardware error occured
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - Blt operation success
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibBufferToVideo (
> +  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
> +  IN  UINTN                                 DestinationX,
> +  IN  UINTN                                 DestinationY,
> +  IN  UINTN                                 Width,
> +  IN  UINTN                                 Height
> +  );
> +
> +
> +/**
> +  Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation
> +  with extended parameters.
> +
> +  @param[in]  BltBuffer     Output buffer for pixel color data
> +  @param[in]  SourceX       X location within BltBuffer
> +  @param[in]  SourceY       Y location within BltBuffer
> +  @param[in]  DestinationX  X location within video
> +  @param[in]  DestinationY  Y location within video
> +  @param[in]  Width         Width (in pixels)
> +  @param[in]  Height        Height
> +  @param[in]  Delta         Number of bytes in a row of BltBuffer
> +
> +  @retval  EFI_DEVICE_ERROR - A hardware error occured
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - Blt operation success
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibBufferToVideoEx (
> +  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
> +  IN  UINTN                                 SourceX,
> +  IN  UINTN                                 SourceY,
> +  IN  UINTN                                 DestinationX,
> +  IN  UINTN                                 DestinationY,
> +  IN  UINTN                                 Width,
> +  IN  UINTN                                 Height,
> +  IN  UINTN                                 Delta
> +  );
> +
> +
> +/**
> +  Performs a UEFI Graphics Output Protocol Blt Video to Video operation
> +
> +  @param[in]  SourceX       X location within video
> +  @param[in]  SourceY       Y location within video
> +  @param[in]  DestinationX  X location within video
> +  @param[in]  DestinationY  Y location within video
> +  @param[in]  Width         Width (in pixels)
> +  @param[in]  Height        Height
> +
> +  @retval  EFI_DEVICE_ERROR - A hardware error occured
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - Blt operation success
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibVideoToVideo (
> +  IN  UINTN                                 SourceX,
> +  IN  UINTN                                 SourceY,
> +  IN  UINTN                                 DestinationX,
> +  IN  UINTN                                 DestinationY,
> +  IN  UINTN                                 Width,
> +  IN  UINTN                                 Height
> +  );
> +
> +
> +/**
> +  Returns the sizes related to the video device
> +
> +  @param[out]  Width   Width (in pixels)
> +  @param[out]  Height  Height (in pixels)
> +
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - The sizes were returned
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibGetSizes (
> +  OUT UINTN                                 *Width,  OPTIONAL
> +  OUT UINTN                                 *Height  OPTIONAL
> +  );
> +
> +#endif
> +
> diff --git
> a/Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.c
> b/Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.c
> new file mode 100644
> index 0000000000..520fac4c63
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.c
> @@ -0,0 +1,744 @@
> +/** @file
> +  FrameBufferBltLib - Library to perform blt operations on a frame buffer.
> +
> +  Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "PiDxe.h"
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/BltLib.h>
> +#include <Library/DebugLib.h>
> +
> +#if 0
> +#define VDEBUG DEBUG
> +#else
> +#define VDEBUG(x)
> +#endif
> +
> +#define MAX_LINE_BUFFER_SIZE (SIZE_4KB * sizeof
> (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))
> +
> +UINTN                           mBltLibColorDepth;
> +UINTN                           mBltLibWidthInBytes;
> +UINTN                           mBltLibBytesPerPixel;
> +UINTN                           mBltLibWidthInPixels;
> +UINTN                           mBltLibHeight;
> +UINT8                           mBltLibLineBuffer[MAX_LINE_BUFFER_SIZE];
> +UINT8                           *mBltLibFrameBuffer;
> +EFI_GRAPHICS_PIXEL_FORMAT       mPixelFormat;
> +EFI_PIXEL_BITMASK               mPixelBitMasks;
> +INTN                            mPixelShl[4]; // R-G-B-Rsvd
> +INTN                            mPixelShr[4]; // R-G-B-Rsvd
> +
> +
> +VOID
> +ConfigurePixelBitMaskFormat (
> +  IN EFI_PIXEL_BITMASK          *BitMask
> +  )
> +{
> +  UINTN   Loop;
> +  UINT32  *Masks;
> +  UINT32  MergedMasks;
> +
> +  MergedMasks = 0;
> +  Masks = (UINT32*) BitMask;
> +  for (Loop = 0; Loop < 3; Loop++) {
> +    ASSERT ((Loop == 3) || (Masks[Loop] != 0));
> +    ASSERT ((MergedMasks & Masks[Loop]) == 0);
> +    mPixelShl[Loop] = HighBitSet32 (Masks[Loop]) - 23 + (Loop * 8);
> +    if (mPixelShl[Loop] < 0) {
> +      mPixelShr[Loop] = -mPixelShl[Loop];
> +      mPixelShl[Loop] = 0;
> +    } else {
> +      mPixelShr[Loop] = 0;
> +    }
> +    MergedMasks = (UINT32) (MergedMasks | Masks[Loop]);
> +    DEBUG ((EFI_D_INFO, "%d: shl:%d shr:%d mask:%x\n", Loop,
> mPixelShl[Loop], mPixelShr[Loop], Masks[Loop]));
> +  }
> +  MergedMasks = (UINT32) (MergedMasks | Masks[3]);
> +
> +  ASSERT (MergedMasks != 0);
> +  mBltLibBytesPerPixel = (UINTN) ((HighBitSet32 (MergedMasks) + 7) / 8);
> +
> +  DEBUG ((EFI_D_INFO, "Bytes per pixel: %d\n", mBltLibBytesPerPixel));
> +
> +  CopyMem (&mPixelBitMasks, BitMask, sizeof (*BitMask));
> +}
> +
> +
> +/**
> +  Configure the FrameBufferLib instance
> +
> +  @param[in] FrameBuffer      Pointer to the start of the frame buffer
> +  @param[in] FrameBufferInfo  Describes the frame buffer characteristics
> +
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter
> +  @retval  EFI_UNSUPPORTED - The BltLib does not support this
> configuration
> +  @retval  EFI_SUCCESS - Blt operation success
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibConfigure (
> +  IN  VOID                                 *FrameBuffer,
> +  IN  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo
> +  )
> +{
> +  STATIC EFI_PIXEL_BITMASK  RgbPixelMasks =
> +    { 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 };
> +  STATIC EFI_PIXEL_BITMASK  BgrPixelMasks =
> +    { 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 };
> +
> +  switch (FrameBufferInfo->PixelFormat) {
> +  case PixelRedGreenBlueReserved8BitPerColor:
> +    ConfigurePixelBitMaskFormat (&RgbPixelMasks);
> +    break;
> +  case PixelBlueGreenRedReserved8BitPerColor:
> +    ConfigurePixelBitMaskFormat (&BgrPixelMasks);
> +    break;
> +  case PixelBitMask:
> +    ConfigurePixelBitMaskFormat (&(FrameBufferInfo->PixelInformation));
> +    break;
> +  case PixelBltOnly:
> +    ASSERT (FrameBufferInfo->PixelFormat != PixelBltOnly);
> +    return EFI_UNSUPPORTED;
> +  default:
> +    ASSERT (FALSE);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  mPixelFormat = FrameBufferInfo->PixelFormat;
> +
> +  mBltLibFrameBuffer = (UINT8*) FrameBuffer;
> +  mBltLibWidthInPixels = (UINTN) FrameBufferInfo->HorizontalResolution;
> +  mBltLibHeight = (UINTN) FrameBufferInfo->VerticalResolution;
> +  mBltLibWidthInBytes = mBltLibWidthInPixels * mBltLibBytesPerPixel;
> +
> +  ASSERT (mBltLibWidthInBytes < sizeof (mBltLibLineBuffer));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Performs a UEFI Graphics Output Protocol Blt operation.
> +
> +  @param[in,out] BltBuffer     - The data to transfer to screen
> +  @param[in]     BltOperation  - The operation to perform
> +  @param[in]     SourceX       - The X coordinate of the source for
> BltOperation
> +  @param[in]     SourceY       - The Y coordinate of the source for
> BltOperation
> +  @param[in]     DestinationX  - The X coordinate of the destination for
> BltOperation
> +  @param[in]     DestinationY  - The Y coordinate of the destination for
> BltOperation
> +  @param[in]     Width         - The width of a rectangle in the blt rectangle in
> pixels
> +  @param[in]     Height        - The height of a rectangle in the blt rectangle in
> pixels
> +  @param[in]     Delta         - Not used for EfiBltVideoFill and
> EfiBltVideoToVideo operation.
> +                                 If a Delta of 0 is used, the entire BltBuffer will be
> operated on.
> +                                 If a subrectangle of the BltBuffer is used, then Delta
> represents
> +                                 the number of bytes in a row of the BltBuffer.
> +
> +  @retval  EFI_DEVICE_ERROR - A hardware error occured
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - Blt operation success
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibGopBlt (
> +  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer, OPTIONAL
> +  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION     BltOperation,
> +  IN  UINTN                                 SourceX,
> +  IN  UINTN                                 SourceY,
> +  IN  UINTN                                 DestinationX,
> +  IN  UINTN                                 DestinationY,
> +  IN  UINTN                                 Width,
> +  IN  UINTN                                 Height,
> +  IN  UINTN                                 Delta
> +  )
> +{
> +  switch (BltOperation) {
> +  case EfiBltVideoToBltBuffer:
> +    return BltLibVideoToBltBufferEx (
> +             BltBuffer,
> +             SourceX,
> +             SourceY,
> +             DestinationX,
> +             DestinationY,
> +             Width,
> +             Height,
> +             Delta
> +             );
> +
> +  case EfiBltVideoToVideo:
> +    return BltLibVideoToVideo (
> +             SourceX,
> +             SourceY,
> +             DestinationX,
> +             DestinationY,
> +             Width,
> +             Height
> +             );
> +
> +  case EfiBltVideoFill:
> +    return BltLibVideoFill (
> +             BltBuffer,
> +             DestinationX,
> +             DestinationY,
> +             Width,
> +             Height
> +             );
> +
> +  case EfiBltBufferToVideo:
> +    return BltLibBufferToVideoEx (
> +             BltBuffer,
> +             SourceX,
> +             SourceY,
> +             DestinationX,
> +             DestinationY,
> +             Width,
> +             Height,
> +             Delta
> +             );
> +  default:
> +    return EFI_INVALID_PARAMETER;
> +  }
> +}
> +
> +
> +/**
> +  Performs a UEFI Graphics Output Protocol Blt Video Fill.
> +
> +  @param[in]  Color         Color to fill the region with
> +  @param[in]  DestinationX  X location to start fill operation
> +  @param[in]  DestinationY  Y location to start fill operation
> +  @param[in]  Width         Width (in pixels) to fill
> +  @param[in]  Height        Height to fill
> +
> +  @retval  EFI_DEVICE_ERROR - A hardware error occured
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - The sizes were returned
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibVideoFill (
> +  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *Color,
> +  IN  UINTN                                 DestinationX,
> +  IN  UINTN                                 DestinationY,
> +  IN  UINTN                                 Width,
> +  IN  UINTN                                 Height
> +  )
> +{
> +  UINTN                           DstY;
> +  VOID                            *BltMemDst;
> +  UINTN                           X;
> +  UINT8                           Uint8;
> +  UINT32                          Uint32;
> +  UINT64                          WideFill;
> +  BOOLEAN                         UseWideFill;
> +  BOOLEAN                         LineBufferReady;
> +  UINTN                           Offset;
> +  UINTN                           WidthInBytes;
> +  UINTN                           SizeInBytes;
> +
> +  //
> +  // BltBuffer to Video: Source is BltBuffer, destination is Video
> +  //
> +  if (DestinationY + Height > mBltLibHeight) {
> +    DEBUG ((EFI_D_INFO, "VideoFill: Past screen (Y)\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (DestinationX + Width > mBltLibWidthInPixels) {
> +    DEBUG ((EFI_D_INFO, "VideoFill: Past screen (X)\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (Width == 0 || Height == 0) {
> +    DEBUG ((EFI_D_INFO, "VideoFill: Width or Height is 0\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  WidthInBytes = Width * mBltLibBytesPerPixel;
> +
> +  Uint32 = *(UINT32*) Color;
> +  WideFill =
> +    (UINT32) (
> +        (((Uint32 << mPixelShl[0]) >> mPixelShr[0]) & mPixelBitMasks.RedMask)
> |
> +        (((Uint32 << mPixelShl[1]) >> mPixelShr[1]) &
> mPixelBitMasks.GreenMask) |
> +        (((Uint32 << mPixelShl[2]) >> mPixelShr[2]) & mPixelBitMasks.BlueMask)
> +      );
> +  VDEBUG ((EFI_D_INFO, "VideoFill: color=0x%x, wide-fill=0x%x\n", Uint32,
> WideFill));
> +
> +  //
> +  // If the size of the pixel data evenly divides the sizeof
> +  // WideFill, then a wide fill operation can be used
> +  //
> +  UseWideFill = TRUE;
> +  if ((sizeof (WideFill) % mBltLibBytesPerPixel) == 0) {
> +    for (X = mBltLibBytesPerPixel; X < sizeof (WideFill); X++) {
> +      ((UINT8*)&WideFill)[X] = ((UINT8*)&WideFill)[X % mBltLibBytesPerPixel];
> +    }
> +  } else {
> +    //
> +    // If all the bytes in the pixel are the same value, then use
> +    // a wide fill operation.
> +    //
> +    for (
> +      X = 1, Uint8 = ((UINT8*)&WideFill)[0];
> +      X < mBltLibBytesPerPixel;
> +      X++) {
> +      if (Uint8 != ((UINT8*)&WideFill)[X]) {
> +        UseWideFill = FALSE;
> +        break;
> +      }
> +    }
> +    if (UseWideFill) {
> +      SetMem ((VOID*) &WideFill, sizeof (WideFill), Uint8);
> +    }
> +  }
> +
> +  if (UseWideFill && (DestinationX == 0) && (Width ==
> mBltLibWidthInPixels)) {
> +    VDEBUG ((EFI_D_INFO, "VideoFill (wide, one-shot)\n"));
> +    Offset = DestinationY * mBltLibWidthInPixels;
> +    Offset = mBltLibBytesPerPixel * Offset;
> +    BltMemDst = (VOID*) (mBltLibFrameBuffer + Offset);
> +    SizeInBytes = WidthInBytes * Height;
> +    if (SizeInBytes >= 8) {
> +      SetMem32 (BltMemDst, SizeInBytes & ~3, (UINT32) WideFill);
> +      SizeInBytes = SizeInBytes & 3;
> +    }
> +    if (SizeInBytes > 0) {
> +      SetMem (BltMemDst, SizeInBytes, (UINT8)(UINTN) WideFill);
> +    }
> +  } else {
> +    LineBufferReady = FALSE;
> +    for (DstY = DestinationY; DstY < (Height + DestinationY); DstY++) {
> +      Offset = (DstY * mBltLibWidthInPixels) + DestinationX;
> +      Offset = mBltLibBytesPerPixel * Offset;
> +      BltMemDst = (VOID*) (mBltLibFrameBuffer + Offset);
> +
> +      if (UseWideFill && (((UINTN) BltMemDst & 7) == 0)) {
> +        VDEBUG ((EFI_D_INFO, "VideoFill (wide)\n"));
> +        SizeInBytes = WidthInBytes;
> +        if (SizeInBytes >= 8) {
> +          SetMem64 (BltMemDst, SizeInBytes & ~7, WideFill);
> +          SizeInBytes = SizeInBytes & 7;
> +        }
> +        if (SizeInBytes > 0) {
> +          CopyMem (BltMemDst, (VOID*) &WideFill, SizeInBytes);
> +        }
> +      } else {
> +        VDEBUG ((EFI_D_INFO, "VideoFill (not wide)\n"));
> +        if (!LineBufferReady) {
> +          CopyMem (mBltLibLineBuffer, &WideFill, mBltLibBytesPerPixel);
> +          for (X = 1; X < Width; ) {
> +            CopyMem(
> +              (mBltLibLineBuffer + (X * mBltLibBytesPerPixel)),
> +              mBltLibLineBuffer,
> +              MIN (X, Width - X) * mBltLibBytesPerPixel
> +              );
> +            X = X + MIN (X, Width - X);
> +          }
> +          LineBufferReady = TRUE;
> +        }
> +        CopyMem (BltMemDst, mBltLibLineBuffer, WidthInBytes);
> +      }
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation.
> +
> +  @param[out] BltBuffer     Output buffer for pixel color data
> +  @param[in]  SourceX       X location within video
> +  @param[in]  SourceY       Y location within video
> +  @param[in]  Width         Width (in pixels)
> +  @param[in]  Height        Height
> +
> +  @retval  EFI_DEVICE_ERROR - A hardware error occured
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - The sizes were returned
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibVideoToBltBuffer (
> +  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
> +  IN  UINTN                                 SourceX,
> +  IN  UINTN                                 SourceY,
> +  IN  UINTN                                 Width,
> +  IN  UINTN                                 Height
> +  )
> +{
> +  return BltLibVideoToBltBufferEx (
> +           BltBuffer,
> +           SourceX,
> +           SourceY,
> +           0,
> +           0,
> +           Width,
> +           Height,
> +           0
> +           );
> +}
> +
> +
> +/**
> +  Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation
> +  with extended parameters.
> +
> +  @param[out] BltBuffer     Output buffer for pixel color data
> +  @param[in]  SourceX       X location within video
> +  @param[in]  SourceY       Y location within video
> +  @param[in]  DestinationX  X location within BltBuffer
> +  @param[in]  DestinationY  Y location within BltBuffer
> +  @param[in]  Width         Width (in pixels)
> +  @param[in]  Height        Height
> +  @param[in]  Delta         Number of bytes in a row of BltBuffer
> +
> +  @retval  EFI_DEVICE_ERROR - A hardware error occured
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - The sizes were returned
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibVideoToBltBufferEx (
> +  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
> +  IN  UINTN                                 SourceX,
> +  IN  UINTN                                 SourceY,
> +  IN  UINTN                                 DestinationX,
> +  IN  UINTN                                 DestinationY,
> +  IN  UINTN                                 Width,
> +  IN  UINTN                                 Height,
> +  IN  UINTN                                 Delta
> +  )
> +{
> +  UINTN                           DstY;
> +  UINTN                           SrcY;
> +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *Blt;
> +  VOID                            *BltMemSrc;
> +  VOID                            *BltMemDst;
> +  UINTN                           X;
> +  UINT32                          Uint32;
> +  UINTN                           Offset;
> +  UINTN                           WidthInBytes;
> +
> +  //
> +  // Video to BltBuffer: Source is Video, destination is BltBuffer
> +  //
> +  if (SourceY + Height > mBltLibHeight) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (SourceX + Width > mBltLibWidthInPixels) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (Width == 0 || Height == 0) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // If Delta is zero, then the entire BltBuffer is being used, so Delta
> +  // is the number of bytes in each row of BltBuffer.  Since BltBuffer is Width
> pixels size,
> +  // the number of bytes in each row can be computed.
> +  //
> +  if (Delta == 0) {
> +    Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
> +  }
> +
> +  WidthInBytes = Width * mBltLibBytesPerPixel;
> +
> +  //
> +  // Video to BltBuffer: Source is Video, destination is BltBuffer
> +  //
> +  for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY);
> SrcY++, DstY++) {
> +
> +    Offset = (SrcY * mBltLibWidthInPixels) + SourceX;
> +    Offset = mBltLibBytesPerPixel * Offset;
> +    BltMemSrc = (VOID *) (mBltLibFrameBuffer + Offset);
> +
> +    if (mPixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
> +      BltMemDst =
> +        (VOID *) (
> +            (UINT8 *) BltBuffer +
> +            (DstY * Delta) +
> +            (DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))
> +          );
> +    } else {
> +      BltMemDst = (VOID *) mBltLibLineBuffer;
> +    }
> +
> +    CopyMem (BltMemDst, BltMemSrc, WidthInBytes);
> +
> +    if (mPixelFormat != PixelBlueGreenRedReserved8BitPerColor) {
> +      for (X = 0; X < Width; X++) {
> +        Blt         = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer +
> (DstY * Delta) + (DestinationX + X) * sizeof
> (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
> +        Uint32 = *(UINT32*) (mBltLibLineBuffer + (X * mBltLibBytesPerPixel));
> +        *(UINT32*) Blt =
> +          (UINT32) (
> +              (((Uint32 & mPixelBitMasks.RedMask)   >> mPixelShl[0]) <<
> mPixelShr[0]) |
> +              (((Uint32 & mPixelBitMasks.GreenMask) >> mPixelShl[1]) <<
> mPixelShr[1]) |
> +              (((Uint32 & mPixelBitMasks.BlueMask)  >> mPixelShl[2]) <<
> mPixelShr[2])
> +            );
> +      }
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation.
> +
> +  @param[in]  BltBuffer     Output buffer for pixel color data
> +  @param[in]  DestinationX  X location within video
> +  @param[in]  DestinationY  Y location within video
> +  @param[in]  Width         Width (in pixels)
> +  @param[in]  Height        Height
> +
> +  @retval  EFI_DEVICE_ERROR - A hardware error occured
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - The sizes were returned
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibBufferToVideo (
> +  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
> +  IN  UINTN                                 DestinationX,
> +  IN  UINTN                                 DestinationY,
> +  IN  UINTN                                 Width,
> +  IN  UINTN                                 Height
> +  )
> +{
> +  return BltLibBufferToVideoEx (
> +           BltBuffer,
> +           0,
> +           0,
> +           DestinationX,
> +           DestinationY,
> +           Width,
> +           Height,
> +           0
> +           );
> +}
> +
> +
> +/**
> +  Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation
> +  with extended parameters.
> +
> +  @param[in]  BltBuffer     Output buffer for pixel color data
> +  @param[in]  SourceX       X location within BltBuffer
> +  @param[in]  SourceY       Y location within BltBuffer
> +  @param[in]  DestinationX  X location within video
> +  @param[in]  DestinationY  Y location within video
> +  @param[in]  Width         Width (in pixels)
> +  @param[in]  Height        Height
> +  @param[in]  Delta         Number of bytes in a row of BltBuffer
> +
> +  @retval  EFI_DEVICE_ERROR - A hardware error occured
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - The sizes were returned
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibBufferToVideoEx (
> +  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
> +  IN  UINTN                                 SourceX,
> +  IN  UINTN                                 SourceY,
> +  IN  UINTN                                 DestinationX,
> +  IN  UINTN                                 DestinationY,
> +  IN  UINTN                                 Width,
> +  IN  UINTN                                 Height,
> +  IN  UINTN                                 Delta
> +  )
> +{
> +  UINTN                           DstY;
> +  UINTN                           SrcY;
> +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *Blt;
> +  VOID                            *BltMemSrc;
> +  VOID                            *BltMemDst;
> +  UINTN                           X;
> +  UINT32                          Uint32;
> +  UINTN                           Offset;
> +  UINTN                           WidthInBytes;
> +
> +  //
> +  // BltBuffer to Video: Source is BltBuffer, destination is Video
> +  //
> +  if (DestinationY + Height > mBltLibHeight) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (DestinationX + Width > mBltLibWidthInPixels) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (Width == 0 || Height == 0) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // If Delta is zero, then the entire BltBuffer is being used, so Delta
> +  // is the number of bytes in each row of BltBuffer.  Since BltBuffer is Width
> pixels size,
> +  // the number of bytes in each row can be computed.
> +  //
> +  if (Delta == 0) {
> +    Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
> +  }
> +
> +  WidthInBytes = Width * mBltLibBytesPerPixel;
> +
> +  for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++,
> DstY++) {
> +
> +    Offset = (DstY * mBltLibWidthInPixels) + DestinationX;
> +    Offset = mBltLibBytesPerPixel * Offset;
> +    BltMemDst = (VOID*) (mBltLibFrameBuffer + Offset);
> +
> +    if (mPixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
> +      BltMemSrc = (VOID *) ((UINT8 *) BltBuffer + (SrcY * Delta));
> +    } else {
> +      for (X = 0; X < Width; X++) {
> +        Blt =
> +          (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) (
> +              (UINT8 *) BltBuffer +
> +              (SrcY * Delta) +
> +              ((SourceX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))
> +            );
> +        Uint32 = *(UINT32*) Blt;
> +        *(UINT32*) (mBltLibLineBuffer + (X * mBltLibBytesPerPixel)) =
> +          (UINT32) (
> +              (((Uint32 << mPixelShl[0]) >> mPixelShr[0]) &
> mPixelBitMasks.RedMask) |
> +              (((Uint32 << mPixelShl[1]) >> mPixelShr[1]) &
> mPixelBitMasks.GreenMask) |
> +              (((Uint32 << mPixelShl[2]) >> mPixelShr[2]) &
> mPixelBitMasks.BlueMask)
> +            );
> +      }
> +      BltMemSrc = (VOID *) mBltLibLineBuffer;
> +    }
> +
> +    CopyMem (BltMemDst, BltMemSrc, WidthInBytes);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Performs a UEFI Graphics Output Protocol Blt Video to Video operation
> +
> +  @param[in]  SourceX       X location within video
> +  @param[in]  SourceY       Y location within video
> +  @param[in]  DestinationX  X location within video
> +  @param[in]  DestinationY  Y location within video
> +  @param[in]  Width         Width (in pixels)
> +  @param[in]  Height        Height
> +
> +  @retval  EFI_DEVICE_ERROR - A hardware error occured
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - The sizes were returned
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibVideoToVideo (
> +  IN  UINTN                                 SourceX,
> +  IN  UINTN                                 SourceY,
> +  IN  UINTN                                 DestinationX,
> +  IN  UINTN                                 DestinationY,
> +  IN  UINTN                                 Width,
> +  IN  UINTN                                 Height
> +  )
> +{
> +  VOID                            *BltMemSrc;
> +  VOID                            *BltMemDst;
> +  UINTN                           Offset;
> +  UINTN                           WidthInBytes;
> +  INTN                            LineStride;
> +
> +  //
> +  // Video to Video: Source is Video, destination is Video
> +  //
> +  if (SourceY + Height > mBltLibHeight) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (SourceX + Width > mBltLibWidthInPixels) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (DestinationY + Height > mBltLibHeight) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (DestinationX + Width > mBltLibWidthInPixels) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (Width == 0 || Height == 0) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  WidthInBytes = Width * mBltLibBytesPerPixel;
> +
> +  Offset = (SourceY * mBltLibWidthInPixels) + SourceX;
> +  Offset = mBltLibBytesPerPixel * Offset;
> +  BltMemSrc = (VOID *) (mBltLibFrameBuffer + Offset);
> +
> +  Offset = (DestinationY * mBltLibWidthInPixels) + DestinationX;
> +  Offset = mBltLibBytesPerPixel * Offset;
> +  BltMemDst = (VOID *) (mBltLibFrameBuffer + Offset);
> +
> +  LineStride = mBltLibWidthInBytes;
> +  if ((UINTN) BltMemDst > (UINTN) BltMemSrc) {
> +    LineStride = -LineStride;
> +  }
> +
> +  while (Height > 0) {
> +    CopyMem (BltMemDst, BltMemSrc, WidthInBytes);
> +
> +    BltMemSrc = (VOID*) ((UINT8*) BltMemSrc + LineStride);
> +    BltMemDst = (VOID*) ((UINT8*) BltMemDst + LineStride);
> +    Height--;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Returns the sizes related to the video device
> +
> +  @param[out]  Width   Width (in pixels)
> +  @param[out]  Height  Height (in pixels)
> +
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - The sizes were returned
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibGetSizes (
> +  OUT UINTN                                 *Width,  OPTIONAL
> +  OUT UINTN                                 *Height  OPTIONAL
> +  )
> +{
> +  if (Width != NULL) {
> +    *Width = mBltLibWidthInPixels;
> +  }
> +  if (Height != NULL) {
> +    *Height = mBltLibHeight;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
> b/Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
> new file mode 100644
> index 0000000000..7af8a1baa0
> --- /dev/null
> +++
> b/Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
> @@ -0,0 +1,29 @@
> +## @file
> +#  FrameBufferBltLib - Library to perform blt operations on a frame buffer.
> +#
> +#  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = FrameBufferBltLib
> +  FILE_GUID                      = 2a40f516-c852-4baa-b7a8-0e9ea090d659
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = BltLib
> +
> +[Sources.common]
> +  FrameBufferBltLib.c
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  OptionRomPkg/OptionRomPkg.dec
> +
> diff --git a/Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.c
> b/Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.c
> new file mode 100644
> index 0000000000..f28affd26b
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.c
> @@ -0,0 +1,449 @@
> +/** @file
> +  GopBltLib - Library to perform blt using the UEFI Graphics Output Protocol.
> +
> +  Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "PiDxe.h"
> +
> +#include <Protocol/GraphicsOutput.h>
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/BltLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +
> +EFI_GRAPHICS_OUTPUT_PROTOCOL         *mGop = NULL;
> +
> +
> +/**
> +  Configure the FrameBufferLib instance
> +
> +  @param[in] FrameBuffer      Pointer to the start of the frame buffer
> +  @param[in] FrameBufferInfo  Describes the frame buffer characteristics
> +
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter
> +  @retval  EFI_UNSUPPORTED - The BltLib does not support this
> configuration
> +  @retval  EFI_SUCCESS - Blt operation success
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibConfigure (
> +  IN  VOID                                 *FrameBuffer,
> +  IN  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  EFI_HANDLE                      *HandleBuffer;
> +  UINTN                           HandleCount;
> +  UINTN                           Index;
> +  EFI_GRAPHICS_OUTPUT_PROTOCOL    *Gop;
> +
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gEfiGraphicsOutputProtocolGuid,
> +                  NULL,
> +                  &HandleCount,
> +                  &HandleBuffer
> +                  );
> +  if (!EFI_ERROR (Status)) {
> +    for (Index = 0; Index < HandleCount; Index++) {
> +      Status = gBS->HandleProtocol (
> +                      HandleBuffer[Index],
> +                      &gEfiGraphicsOutputProtocolGuid,
> +                      (VOID*) &Gop
> +                      );
> +      if (!EFI_ERROR (Status) &&
> +          (FrameBuffer == (VOID*)(UINTN) Gop->Mode->FrameBufferBase)) {
> +        mGop = Gop;
> +        FreePool (HandleBuffer);
> +        return EFI_SUCCESS;
> +      }
> +    }
> +
> +    FreePool (HandleBuffer);
> +  }
> +
> +  return EFI_UNSUPPORTED;
> +}
> +
> +
> +/**
> +  Performs a UEFI Graphics Output Protocol Blt operation.
> +
> +  @param[in,out] BltBuffer     - The data to transfer to screen
> +  @param[in]     BltOperation  - The operation to perform
> +  @param[in]     SourceX       - The X coordinate of the source for
> BltOperation
> +  @param[in]     SourceY       - The Y coordinate of the source for
> BltOperation
> +  @param[in]     DestinationX  - The X coordinate of the destination for
> BltOperation
> +  @param[in]     DestinationY  - The Y coordinate of the destination for
> BltOperation
> +  @param[in]     Width         - The width of a rectangle in the blt rectangle in
> pixels
> +  @param[in]     Height        - The height of a rectangle in the blt rectangle in
> pixels
> +  @param[in]     Delta         - Not used for EfiBltVideoFill and
> EfiBltVideoToVideo operation.
> +                                 If a Delta of 0 is used, the entire BltBuffer will be
> operated on.
> +                                 If a subrectangle of the BltBuffer is used, then Delta
> represents
> +                                 the number of bytes in a row of the BltBuffer.
> +
> +  @retval  EFI_DEVICE_ERROR - A hardware error occured
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - Blt operation success
> +
> +**/
> +EFI_STATUS
> +InternalGopBltCommon (
> +  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer, OPTIONAL
> +  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION     BltOperation,
> +  IN  UINTN                                 SourceX,
> +  IN  UINTN                                 SourceY,
> +  IN  UINTN                                 DestinationX,
> +  IN  UINTN                                 DestinationY,
> +  IN  UINTN                                 Width,
> +  IN  UINTN                                 Height,
> +  IN  UINTN                                 Delta
> +  )
> +{
> +  if (mGop == NULL) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return mGop->Blt (
> +                 mGop,
> +                 BltBuffer,
> +                 BltOperation,
> +                 SourceX,
> +                 SourceY,
> +                 DestinationX,
> +                 DestinationY,
> +                 Width,
> +                 Height,
> +                 Delta
> +                 );
> +}
> +
> +
> +/**
> +  Performs a UEFI Graphics Output Protocol Blt operation.
> +
> +  @param[in,out] BltBuffer     - The data to transfer to screen
> +  @param[in]     BltOperation  - The operation to perform
> +  @param[in]     SourceX       - The X coordinate of the source for
> BltOperation
> +  @param[in]     SourceY       - The Y coordinate of the source for
> BltOperation
> +  @param[in]     DestinationX  - The X coordinate of the destination for
> BltOperation
> +  @param[in]     DestinationY  - The Y coordinate of the destination for
> BltOperation
> +  @param[in]     Width         - The width of a rectangle in the blt rectangle in
> pixels
> +  @param[in]     Height        - The height of a rectangle in the blt rectangle in
> pixels
> +  @param[in]     Delta         - Not used for EfiBltVideoFill and
> EfiBltVideoToVideo operation.
> +                                 If a Delta of 0 is used, the entire BltBuffer will be
> operated on.
> +                                 If a subrectangle of the BltBuffer is used, then Delta
> represents
> +                                 the number of bytes in a row of the BltBuffer.
> +
> +  @retval  EFI_DEVICE_ERROR - A hardware error occured
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - Blt operation success
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibGopBlt (
> +  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer, OPTIONAL
> +  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION     BltOperation,
> +  IN  UINTN                                 SourceX,
> +  IN  UINTN                                 SourceY,
> +  IN  UINTN                                 DestinationX,
> +  IN  UINTN                                 DestinationY,
> +  IN  UINTN                                 Width,
> +  IN  UINTN                                 Height,
> +  IN  UINTN                                 Delta
> +  )
> +{
> +  return InternalGopBltCommon (
> +           BltBuffer,
> +           BltOperation,
> +           SourceX,
> +           SourceY,
> +           DestinationX,
> +           DestinationY,
> +           Width,
> +           Height,
> +           Delta
> +           );
> +}
> +
> +
> +/**
> +  Performs a UEFI Graphics Output Protocol Blt Video Fill.
> +
> +  @param[in]  Color         Color to fill the region with
> +  @param[in]  DestinationX  X location to start fill operation
> +  @param[in]  DestinationY  Y location to start fill operation
> +  @param[in]  Width         Width (in pixels) to fill
> +  @param[in]  Height        Height to fill
> +
> +  @retval  EFI_DEVICE_ERROR - A hardware error occured
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - The sizes were returned
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibVideoFill (
> +  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *Color,
> +  IN  UINTN                                 DestinationX,
> +  IN  UINTN                                 DestinationY,
> +  IN  UINTN                                 Width,
> +  IN  UINTN                                 Height
> +  )
> +{
> +  return InternalGopBltCommon (
> +           Color,
> +           EfiBltVideoFill,
> +           0,
> +           0,
> +           DestinationX,
> +           DestinationY,
> +           Width,
> +           Height,
> +           0
> +           );
> +}
> +
> +
> +/**
> +  Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation.
> +
> +  @param[out] BltBuffer     Output buffer for pixel color data
> +  @param[in]  SourceX       X location within video
> +  @param[in]  SourceY       Y location within video
> +  @param[in]  Width         Width (in pixels)
> +  @param[in]  Height        Height
> +
> +  @retval  EFI_DEVICE_ERROR - A hardware error occured
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - The sizes were returned
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibVideoToBltBuffer (
> +  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
> +  IN  UINTN                                 SourceX,
> +  IN  UINTN                                 SourceY,
> +  IN  UINTN                                 Width,
> +  IN  UINTN                                 Height
> +  )
> +{
> +  return InternalGopBltCommon (
> +           BltBuffer,
> +           EfiBltVideoToBltBuffer,
> +           SourceX,
> +           SourceY,
> +           0,
> +           0,
> +           Width,
> +           Height,
> +           0
> +           );
> +}
> +
> +
> +/**
> +  Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation
> +  with extended parameters.
> +
> +  @param[out] BltBuffer     Output buffer for pixel color data
> +  @param[in]  SourceX       X location within video
> +  @param[in]  SourceY       Y location within video
> +  @param[in]  DestinationX  X location within BltBuffer
> +  @param[in]  DestinationY  Y location within BltBuffer
> +  @param[in]  Width         Width (in pixels)
> +  @param[in]  Height        Height
> +  @param[in]  Delta         Number of bytes in a row of BltBuffer
> +
> +  @retval  EFI_DEVICE_ERROR - A hardware error occured
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - The sizes were returned
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibVideoToBltBufferEx (
> +  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
> +  IN  UINTN                                 SourceX,
> +  IN  UINTN                                 SourceY,
> +  IN  UINTN                                 DestinationX,
> +  IN  UINTN                                 DestinationY,
> +  IN  UINTN                                 Width,
> +  IN  UINTN                                 Height,
> +  IN  UINTN                                 Delta
> +  )
> +{
> +  return InternalGopBltCommon (
> +           BltBuffer,
> +           EfiBltVideoToBltBuffer,
> +           SourceX,
> +           SourceY,
> +           DestinationX,
> +           DestinationY,
> +           Width,
> +           Height,
> +           Delta
> +           );
> +}
> +
> +
> +/**
> +  Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation.
> +
> +  @param[in]  BltBuffer     Output buffer for pixel color data
> +  @param[in]  DestinationX  X location within video
> +  @param[in]  DestinationY  Y location within video
> +  @param[in]  Width         Width (in pixels)
> +  @param[in]  Height        Height
> +
> +  @retval  EFI_DEVICE_ERROR - A hardware error occured
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - The sizes were returned
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibBufferToVideo (
> +  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
> +  IN  UINTN                                 DestinationX,
> +  IN  UINTN                                 DestinationY,
> +  IN  UINTN                                 Width,
> +  IN  UINTN                                 Height
> +  )
> +{
> +  return InternalGopBltCommon (
> +           BltBuffer,
> +           EfiBltBufferToVideo,
> +           0,
> +           0,
> +           DestinationX,
> +           DestinationY,
> +           Width,
> +           Height,
> +           0
> +           );
> +}
> +
> +
> +/**
> +  Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation
> +  with extended parameters.
> +
> +  @param[in]  BltBuffer     Output buffer for pixel color data
> +  @param[in]  SourceX       X location within BltBuffer
> +  @param[in]  SourceY       Y location within BltBuffer
> +  @param[in]  DestinationX  X location within video
> +  @param[in]  DestinationY  Y location within video
> +  @param[in]  Width         Width (in pixels)
> +  @param[in]  Height        Height
> +  @param[in]  Delta         Number of bytes in a row of BltBuffer
> +
> +  @retval  EFI_DEVICE_ERROR - A hardware error occured
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - The sizes were returned
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibBufferToVideoEx (
> +  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
> +  IN  UINTN                                 SourceX,
> +  IN  UINTN                                 SourceY,
> +  IN  UINTN                                 DestinationX,
> +  IN  UINTN                                 DestinationY,
> +  IN  UINTN                                 Width,
> +  IN  UINTN                                 Height,
> +  IN  UINTN                                 Delta
> +  )
> +{
> +  return InternalGopBltCommon (
> +           BltBuffer,
> +           EfiBltBufferToVideo,
> +           SourceX,
> +           SourceY,
> +           DestinationX,
> +           DestinationY,
> +           Width,
> +           Height,
> +           Delta
> +           );
> +}
> +
> +
> +/**
> +  Performs a UEFI Graphics Output Protocol Blt Video to Video operation
> +
> +  @param[in]  SourceX       X location within video
> +  @param[in]  SourceY       Y location within video
> +  @param[in]  DestinationX  X location within video
> +  @param[in]  DestinationY  Y location within video
> +  @param[in]  Width         Width (in pixels)
> +  @param[in]  Height        Height
> +
> +  @retval  EFI_DEVICE_ERROR - A hardware error occured
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - The sizes were returned
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibVideoToVideo (
> +  IN  UINTN                                 SourceX,
> +  IN  UINTN                                 SourceY,
> +  IN  UINTN                                 DestinationX,
> +  IN  UINTN                                 DestinationY,
> +  IN  UINTN                                 Width,
> +  IN  UINTN                                 Height
> +  )
> +{
> +  return InternalGopBltCommon (
> +           NULL,
> +           EfiBltVideoToVideo,
> +           SourceX,
> +           SourceY,
> +           DestinationX,
> +           DestinationY,
> +           Width,
> +           Height,
> +           0
> +           );
> +}
> +
> +/**
> +  Returns the sizes related to the video device
> +
> +  @param[out]  Width   Width (in pixels)
> +  @param[out]  Height  Height (in pixels)
> +
> +  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in
> +  @retval  EFI_SUCCESS - The sizes were returned
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BltLibGetSizes (
> +  OUT UINTN                                 *Width,  OPTIONAL
> +  OUT UINTN                                 *Height  OPTIONAL
> +  )
> +{
> +  ASSERT (mGop != NULL);
> +
> +  if (Width != NULL) {
> +    *Width = mGop->Mode->Info->HorizontalResolution;
> +  }
> +  if (Height != NULL) {
> +    *Height = mGop->Mode->Info->VerticalResolution;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git a/Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.inf
> b/Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.inf
> new file mode 100644
> index 0000000000..c5559133f9
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.inf
> @@ -0,0 +1,31 @@
> +## @file
> +#  GopBltLib - Library to perform blt using the UEFI Graphics Output
> Protocol.
> +#
> +#  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = GopBltLib
> +  FILE_GUID                      = b75b91f0-a0b4-42fe-ba62-849027999b39
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = BltLib
> +
> +[Sources.common]
> +  GopBltLib.c
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  MemoryAllocationLib
> +  UefiBootServicesTableLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  OptionRomPkg/OptionRomPkg.dec
> +
> diff --git a/Drivers/OptionRomPkg/OptionRomPkg.dec
> b/Drivers/OptionRomPkg/OptionRomPkg.dec
> new file mode 100644
> index 0000000000..6881f3648e
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/OptionRomPkg.dec
> @@ -0,0 +1,41 @@
> +## @file
> +# Option Rom Package Reference Implementations.
> +#
> +# This package is designed to interoperate with the EDK II open source
> project
> +# at http://www.tianocore.org, and this package is required to build PCI
> compliant
> +# Option ROM image for all CPU architectures, including EBC target.
> +# A single driver can support mixes of EFI 1.1, UEFI 2.0 and UEFI 2.1.
> +#
> +# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  DEC_SPECIFICATION              = 0x00010005
> +  PACKAGE_NAME                   = OptionRomPkg
> +  PACKAGE_GUID                   = AA3865E8-7F30-4f59-8696-99F560101852
> +  PACKAGE_VERSION                = 0.1
> +
> +[Includes]
> +  Include
> +
> +[LibraryClasses]
> +  ##  @libraryclass  Provides an interface for performing UEFI Graphics
> +  ##                 Output Protocol Video blt operations
> +  ##
> +  BltLib|Include/Library/BltLib.h
> +
> +[Guids]
> +  gOptionRomPkgTokenSpaceGuid = { 0x1e43298f, 0x3478, 0x41a7, { 0xb5,
> 0x77, 0x86, 0x6, 0x46, 0x35, 0xc7, 0x28 } }
> +
> +[PcdsFeatureFlag]
> +
> gOptionRomPkgTokenSpaceGuid.PcdSupportScsiPassThru|TRUE|BOOLEAN|
> 0x00010001
> +
> gOptionRomPkgTokenSpaceGuid.PcdSupportExtScsiPassThru|TRUE|BOOLEA
> N|0x00010002
> +
> gOptionRomPkgTokenSpaceGuid.PcdSupportGop|TRUE|BOOLEAN|0x00010
> 004
> +
> gOptionRomPkgTokenSpaceGuid.PcdSupportUga|TRUE|BOOLEAN|0x000100
> 05
> +
> +[PcdsFixedAtBuild, PcdsPatchableInModule]
> +
> gOptionRomPkgTokenSpaceGuid.PcdDriverSupportedEfiVersion|0x0002000a
> |UINT32|0x00010003
> +
> diff --git a/Drivers/OptionRomPkg/OptionRomPkg.dsc
> b/Drivers/OptionRomPkg/OptionRomPkg.dsc
> new file mode 100644
> index 0000000000..bea64b585e
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/OptionRomPkg.dsc
> @@ -0,0 +1,113 @@
> +## @file
> +# Option Rom Package build validation file for All Architectures.
> +#
> +# This package is designed to interoperate with the EDK II open source
> project
> +# at http://www.tianocore.org, and this package is required to build PCI
> compliant
> +# Option ROM image for all CPU architectures, including EBC target.
> +# A single driver can support mixes of EFI 1.1, UEFI 2.0 and UEFI 2.1.
> +#
> +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +##############################################################
> ##################
> +#
> +# Defines Section - statements that will be processed to create a Makefile.
> +#
> +##############################################################
> ##################
> +[Defines]
> +  PLATFORM_NAME                  = OptionRomPkg
> +  PLATFORM_GUID                  = C7B25F37-B1F4-4c46-99CB-3EA7DCF5FCDC
> +  PLATFORM_VERSION               = 0.1
> +  DSC_SPECIFICATION              = 0x00010005
> +  OUTPUT_DIRECTORY               = Build/OptionRomPkg
> +  SUPPORTED_ARCHITECTURES        = IA32|X64|EBC|ARM|AARCH64
> +  BUILD_TARGETS                  = DEBUG|RELEASE
> +  SKUID_IDENTIFIER               = DEFAULT
> +
> +##############################################################
> ##################
> +#
> +# SKU Identification section - list of all SKU IDs supported by this
> +#                              Platform.
> +#
> +##############################################################
> ##################
> +[SkuIds]
> +  0|DEFAULT              # The entry: 0|DEFAULT is reserved and always
> required.
> +
> +[LibraryClasses]
> +  DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf
> +
> DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/Base
> DebugPrintErrorLevelLib.inf
> +  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
> +  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
> +  BltLib|OptionRomPkg/Library/GopBltLib/GopBltLib.inf
> +  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
> +
> TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTem
> plate.inf
> +
> UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBo
> otServicesTableLib.inf
> +
> UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/
> UefiRuntimeServicesTableLib.inf
> +
> UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntry
> Point.inf
> +  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
> +  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +
> MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemo
> ryAllocationLib.inf
> +  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
> +
> UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiA
> pplicationEntryPoint.inf
> +  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
> +
> +[LibraryClasses.AARCH64, LibraryClasses.ARM]
> +  NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
> +
> +[LibraryClasses.ARM]
> +  NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
> +
> +##############################################################
> ##################
> +#
> +# Pcd Section - list of all EDK II PCD Entries defined by this Platform
> +#
> +##############################################################
> ##################
> +[PcdsFeatureFlag]
> +  gOptionRomPkgTokenSpaceGuid.PcdSupportScsiPassThru|TRUE
> +  gOptionRomPkgTokenSpaceGuid.PcdSupportExtScsiPassThru|TRUE
> +
> +[PcdsFixedAtBuild]
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x27
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000042
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue|0x0
> +  gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|0x0
> +  gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|0x0
> +  gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|0x0
> +
> gOptionRomPkgTokenSpaceGuid.PcdDriverSupportedEfiVersion|0x0002000a
> # EFI_2_10_SYSTEM_TABLE_REVISION
> +
> +##############################################################
> #####################################
> +#
> +# Components Section - list of the modules and components that will be
> processed by compilation
> +#                      tools and the EDK II tools to generate PE32/PE32+/Coff image
> files.
> +#
> +# Note: The EDK II DSC file is not used to specify how compiled binary
> images get placed
> +#       into firmware volume images. This section is just a list of modules to
> compile from
> +#       source into UEFI-compliant binaries.
> +#       It is the FDF file that contains information on combining binary files
> into firmware
> +#       volume images, whose concept is beyond UEFI and is described in PI
> specification.
> +#       Binary modules do not need to be listed in this section, as they should
> be
> +#       specified in the FDF file. For example: Shell binary (Shell_Full.efi), FAT
> binary (Fat.efi),
> +#       Logo (Logo.bmp), and etc.
> +#       There may also be modules listed in this section that are not required
> in the FDF file,
> +#       When a module listed here is excluded from FDF file, then UEFI-
> compliant binary will be
> +#       generated for it, but the binary will not be put into any firmware
> volume.
> +#
> +##############################################################
> #####################################
> +
> +[Components]
> +  OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
> +  OptionRomPkg/Library/GopBltLib/GopBltLib.inf
> +
> +  OptionRomPkg/AtapiPassThruDxe/AtapiPassThruDxe.inf
> +  OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf
> +  OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf
> +  OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf
> +  OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf
> +  OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
> +
> +[Components.IA32, Components.X64]
> +  OptionRomPkg/Application/BltLibSample/BltLibSample.inf
> diff --git a/Drivers/OptionRomPkg/ReadMe.txt
> b/Drivers/OptionRomPkg/ReadMe.txt
> new file mode 100644
> index 0000000000..99f97896da
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/ReadMe.txt
> @@ -0,0 +1,17 @@
> +AtapiPassThru:
> +  For now, AtapiPassThru driver in this package is to test Scsi Bus support:
> +  ScsiBus driver should support both/either ScsiPassThru and
> ExtScsiPassThru
> +  installed on a controller handle.
> +
> +  AtapiPassThru driver in this package can selectively produce ScsiPassThru
> +  and/or ExtScsiPassThru protocol based on feature flags of
> PcdSupportScsiPassThru
> +  and PcdSupportExtScsiPassThru.
> +
> +CirrusLogic5430:
> +  Sample implementation of UGA Draw or Graphics Output Protocol for the
> Cirrus
> +  Logic 5430 family of PCI video card. It provides reference code for the
> GOP/UGA,
> +  Component Name (2), EFI driver supported Verison protocol.
> +
> +Build Validation:
> +ICC             IA32 X64 IPF
> +
> diff --git a/Drivers/OptionRomPkg/UndiRuntimeDxe/ComponentName.c
> b/Drivers/OptionRomPkg/UndiRuntimeDxe/ComponentName.c
> new file mode 100644
> index 0000000000..b310143271
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/UndiRuntimeDxe/ComponentName.c
> @@ -0,0 +1,359 @@
> +/** @file
> +    UEFI Component Name(2) protocol implementation for EFI UNDI32
> driver.
> +
> +Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +
> +#include "Undi32.h"
> +
> +//
> +// EFI Component Name Functions
> +//
> +/**
> +  Retrieves a Unicode string that is the user readable name of the driver.
> +
> +  This function retrieves the user readable name of a driver in the form of a
> +  Unicode string. If the driver specified by This has a user readable name in
> +  the language specified by Language, then a pointer to the driver name is
> +  returned in DriverName, and EFI_SUCCESS is returned. If the driver
> specified
> +  by This does not support the language specified by Language,
> +  then EFI_UNSUPPORTED is returned.
> +
> +  @param  This[in]              A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> +                                array indicating the language. This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified
> +                                in RFC 4646 or ISO 639-2 language code format.
> +
> +  @param  DriverName[out]       A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                driver specified by This in the language
> +                                specified by Language.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> +                                This and the language specified by Language was
> +                                returned in DriverName.
> +
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UndiComponentNameGetDriverName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
> +  IN  CHAR8                        *Language,
> +  OUT CHAR16                       **DriverName
> +  );
> +
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the controller
> +  that is being managed by a driver.
> +
> +  This function retrieves the user readable name of the controller specified
> by
> +  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> +  driver specified by This has a user readable name in the language specified
> by
> +  Language, then a pointer to the controller name is returned in
> ControllerName,
> +  and EFI_SUCCESS is returned.  If the driver specified by This is not
> currently
> +  managing the controller specified by ControllerHandle and ChildHandle,
> +  then EFI_UNSUPPORTED is returned.  If the driver specified by This does
> not
> +  support the language specified by Language, then EFI_UNSUPPORTED is
> returned.
> +
> +  @param  This[in]              A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> +  @param  ControllerHandle[in]  The handle of a controller that the driver
> +                                specified by This is managing.  This handle
> +                                specifies the controller whose name is to be
> +                                returned.
> +
> +  @param  ChildHandle[in]       The handle of the child controller to retrieve
> +                                the name of.  This is an optional parameter that
> +                                may be NULL.  It will be NULL for device
> +                                drivers.  It will also be NULL for a bus drivers
> +                                that wish to retrieve the name of the bus
> +                                controller.  It will not be NULL for a bus
> +                                driver that wishes to retrieve the name of a
> +                                child controller.
> +
> +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> +                                array indicating the language.  This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified in
> +                                RFC 4646 or ISO 639-2 language code format.
> +
> +  @param  ControllerName[out]   A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                controller specified by ControllerHandle and
> +                                ChildHandle in the language specified by
> +                                Language from the point of view of the driver
> +                                specified by This.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the user readable name
> in
> +                                the language specified by Language for the
> +                                driver specified by This was returned in
> +                                DriverName.
> +
> +  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a
> valid
> +                                EFI_HANDLE.
> +
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> +                                managing the controller specified by
> +                                ControllerHandle and ChildHandle.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UndiComponentNameGetControllerName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
> +  IN  EFI_HANDLE                                      ControllerHandle,
> +  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
> +  IN  CHAR8                                           *Language,
> +  OUT CHAR16                                          **ControllerName
> +  );
> +
> +
> +//
> +// EFI Component Name Protocol
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED
> EFI_COMPONENT_NAME_PROTOCOL  gUndiComponentName = {
> +  UndiComponentNameGetDriverName,
> +  UndiComponentNameGetControllerName,
> +  "eng"
> +};
> +
> +//
> +// EFI Component Name 2 Protocol
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED
> EFI_COMPONENT_NAME2_PROTOCOL gUndiComponentName2 = {
> +  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)
> UndiComponentNameGetDriverName,
> +  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)
> UndiComponentNameGetControllerName,
> +  "en"
> +};
> +
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
> mUndiDriverNameTable[] = {
> +  {
> +    "eng;en",
> +    L"UNDI32 Driver"
> +  },
> +  {
> +    NULL,
> +    NULL
> +  }
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
> mUndiControllerNameTable[] = {
> +  {
> +    "eng;en",
> +    L"UNDI32 Controller"
> +  },
> +  {
> +    NULL,
> +    NULL
> +  }
> +};
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the driver.
> +
> +  This function retrieves the user readable name of a driver in the form of a
> +  Unicode string. If the driver specified by This has a user readable name in
> +  the language specified by Language, then a pointer to the driver name is
> +  returned in DriverName, and EFI_SUCCESS is returned. If the driver
> specified
> +  by This does not support the language specified by Language,
> +  then EFI_UNSUPPORTED is returned.
> +
> +  @param  This[in]              A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> +                                array indicating the language. This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified
> +                                in RFC 4646 or ISO 639-2 language code format.
> +
> +  @param  DriverName[out]       A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                driver specified by This in the language
> +                                specified by Language.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> +                                This and the language specified by Language was
> +                                returned in DriverName.
> +
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UndiComponentNameGetDriverName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
> +  IN  CHAR8                        *Language,
> +  OUT CHAR16                       **DriverName
> +  )
> +{
> +  return LookupUnicodeString2 (
> +           Language,
> +           This->SupportedLanguages,
> +           mUndiDriverNameTable,
> +           DriverName,
> +           (BOOLEAN)(This == &gUndiComponentName)
> +           );
> +}
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the controller
> +  that is being managed by a driver.
> +
> +  This function retrieves the user readable name of the controller specified
> by
> +  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> +  driver specified by This has a user readable name in the language specified
> by
> +  Language, then a pointer to the controller name is returned in
> ControllerName,
> +  and EFI_SUCCESS is returned.  If the driver specified by This is not
> currently
> +  managing the controller specified by ControllerHandle and ChildHandle,
> +  then EFI_UNSUPPORTED is returned.  If the driver specified by This does
> not
> +  support the language specified by Language, then EFI_UNSUPPORTED is
> returned.
> +  Currently not implemented.
> +
> +  @param  This[in]              A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> +  @param  ControllerHandle[in]  The handle of a controller that the driver
> +                                specified by This is managing.  This handle
> +                                specifies the controller whose name is to be
> +                                returned.
> +
> +  @param  ChildHandle[in]       The handle of the child controller to retrieve
> +                                the name of.  This is an optional parameter that
> +                                may be NULL.  It will be NULL for device
> +                                drivers.  It will also be NULL for a bus drivers
> +                                that wish to retrieve the name of the bus
> +                                controller.  It will not be NULL for a bus
> +                                driver that wishes to retrieve the name of a
> +                                child controller.
> +
> +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> +                                array indicating the language.  This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified in
> +                                RFC 4646 or ISO 639-2 language code format.
> +
> +  @param  ControllerName[out]   A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                controller specified by ControllerHandle and
> +                                ChildHandle in the language specified by
> +                                Language from the point of view of the driver
> +                                specified by This.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the user readable name
> in
> +                                the language specified by Language for the
> +                                driver specified by This was returned in
> +                                DriverName.
> +
> +  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a
> valid
> +                                EFI_HANDLE.
> +
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> +                                managing the controller specified by
> +                                ControllerHandle and ChildHandle.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UndiComponentNameGetControllerName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
> +  IN  EFI_HANDLE                                      ControllerHandle,
> +  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
> +  IN  CHAR8                                           *Language,
> +  OUT CHAR16                                          **ControllerName
> +  )
> +{
> +  EFI_STATUS                                Status;
> +  EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *Nii;
> +
> +  if (ChildHandle != NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Make sure this driver is currently managing ControllHandle
> +  //
> +  Status = EfiTestManagedDevice (
> +             ControllerHandle,
> +             gUndiDriverBinding.DriverBindingHandle,
> +             &gEfiPciIoProtocolGuid
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Retrieve an instance of a produced protocol from ControllerHandle
> +  //
> +  Status = gBS->OpenProtocol (
> +                   ControllerHandle,
> +                   &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
> +                  (VOID **)&Nii,
> +                   NULL,
> +                   NULL,
> +                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                   );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  return LookupUnicodeString2 (
> +           Language,
> +           This->SupportedLanguages,
> +           mUndiControllerNameTable,
> +           ControllerName,
> +           (BOOLEAN)(This == &gUndiComponentName)
> +           );
> +}
> diff --git a/Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c
> b/Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c
> new file mode 100644
> index 0000000000..b7a2d16bc6
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c
> @@ -0,0 +1,1516 @@
> +/** @file
> +  Provides the basic UNID functions.
> +
> +Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "Undi32.h"
> +
> +//
> +// Global variables defined in this file
> +//
> +UNDI_CALL_TABLE api_table[PXE_OPCODE_LAST_VALID+1] = { \
> +  {PXE_CPBSIZE_NOT_USED,PXE_DBSIZE_NOT_USED,0,
> (UINT16)(ANY_STATE),UNDI_GetState },\
> +
> {(UINT16)(DONT_CHECK),PXE_DBSIZE_NOT_USED,0,(UINT16)(ANY_STATE),U
> NDI_Start },\
> +
> {PXE_CPBSIZE_NOT_USED,PXE_DBSIZE_NOT_USED,0,MUST_BE_STARTED,UN
> DI_Stop },\
> +
> {PXE_CPBSIZE_NOT_USED,sizeof(PXE_DB_GET_INIT_INFO),0,MUST_BE_STAR
> TED, UNDI_GetInitInfo },\
> +
> {PXE_CPBSIZE_NOT_USED,sizeof(PXE_DB_GET_CONFIG_INFO),0,MUST_BE_S
> TARTED, UNDI_GetConfigInfo },\
> +
> {sizeof(PXE_CPB_INITIALIZE),(UINT16)(DONT_CHECK),(UINT16)(DONT_CHEC
> K),MUST_BE_STARTED,UNDI_Initialize },\
> +
> {PXE_CPBSIZE_NOT_USED,PXE_DBSIZE_NOT_USED,(UINT16)(DONT_CHECK),
> MUST_BE_INITIALIZED,UNDI_Reset },\
> +  {PXE_CPBSIZE_NOT_USED,PXE_DBSIZE_NOT_USED,0,
> MUST_BE_INITIALIZED,UNDI_Shutdown },\
> +
> {PXE_CPBSIZE_NOT_USED,PXE_DBSIZE_NOT_USED,(UINT16)(DONT_CHECK),
> MUST_BE_INITIALIZED,UNDI_Interrupt },\
> +
> {(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK),
> MUST_BE_INITIALIZED, UNDI_RecFilter },\
> +
> {(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK),
> MUST_BE_INITIALIZED, UNDI_StnAddr },\
> +  {PXE_CPBSIZE_NOT_USED, (UINT16)(DONT_CHECK),
> (UINT16)(DONT_CHECK), MUST_BE_INITIALIZED, UNDI_Statistics },\
> +
> {sizeof(PXE_CPB_MCAST_IP_TO_MAC),sizeof(PXE_DB_MCAST_IP_TO_MAC),
> (UINT16)(DONT_CHECK),MUST_BE_INITIALIZED, UNDI_ip2mac },\
> +
> {(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK),
> MUST_BE_INITIALIZED, UNDI_NVData },\
> +
> {PXE_CPBSIZE_NOT_USED,(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK),
> MUST_BE_INITIALIZED, UNDI_Status },\
> +  {(UINT16)(DONT_CHECK),PXE_DBSIZE_NOT_USED,(UINT16)(DONT_CHECK),
> MUST_BE_INITIALIZED, UNDI_FillHeader },\
> +  {(UINT16)(DONT_CHECK),PXE_DBSIZE_NOT_USED,(UINT16)(DONT_CHECK),
> MUST_BE_INITIALIZED, UNDI_Transmit },\
> +
> {sizeof(PXE_CPB_RECEIVE),sizeof(PXE_DB_RECEIVE),0,MUST_BE_INITIALIZED,
> UNDI_Receive } \
> +};
> +
> +//
> +// end of global variables
> +//
> +
> +
> +/**
> +  This routine determines the operational state of the UNDI.  It updates the
> state flags in the
> +  Command Descriptor Block based on information derived from the
> AdapterInfo instance data.
> +  To ensure the command has completed successfully, CdbPtr->StatCode
> will contain the result of
> +  the command execution.
> +  The CdbPtr->StatFlags will contain a STOPPED, STARTED, or INITIALIZED
> state once the command
> +  has successfully completed.
> +  Keep in mind the AdapterInfo->State is the active state of the adapter
> (based on software
> +  interrogation), and the CdbPtr->StateFlags is the passed back information
> that is reflected
> +  to the caller of the UNDI API.
> +
> +  @param  CdbPtr               Pointer to the command descriptor block.
> +  @param  AdapterInfo          Pointer to the NIC data structure information
> which
> +                               the UNDI driver is layering on..
> +
> +  @return None
> +
> +**/
> +VOID
> +UNDI_GetState (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  CdbPtr->StatFlags = (PXE_STATFLAGS) (CdbPtr->StatFlags | AdapterInfo-
> >State);
> +  return ;
> +}
> +
> +
> +/**
> +  This routine is used to change the operational state of the UNDI from
> stopped to started.
> +  It will do this as long as the adapter's state is
> PXE_STATFLAGS_GET_STATE_STOPPED, otherwise
> +  the CdbPtr->StatFlags will reflect a command failure, and the CdbPtr-
> >StatCode will reflect the
> +  UNDI as having already been started.
> +  This routine is modified to reflect the undi 1.1 specification changes. The
> +  changes in the spec are mainly in the callback routines, the new spec adds
> +  3 more callbacks and a unique id.
> +  Since this UNDI supports both old and new undi specifications,
> +  The NIC's data structure is filled in with the callback routines (depending
> +  on the version) pointed to in the caller's CpbPtr.  This seeds the Delay,
> +  Virt2Phys, Block, and Mem_IO for old and new versions and Map_Mem,
> UnMap_Mem
> +  and Sync_Mem routines and a unique id variable for the new version.
> +  This is the function which an external entity (SNP, O/S, etc) would call
> +  to provide it's I/O abstraction to the UNDI.
> +  It's final action is to change the AdapterInfo->State to
> PXE_STATFLAGS_GET_STATE_STARTED.
> +
> +  @param  CdbPtr               Pointer to the command descriptor block.
> +  @param  AdapterInfo          Pointer to the NIC data structure information
> which
> +                               the UNDI driver is layering on..
> +
> +  @return None
> +
> +**/
> +VOID
> +UNDI_Start (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  PXE_CPB_START_30  *CpbPtr;
> +  PXE_CPB_START_31  *CpbPtr_31;
> +
> +  //
> +  // check if it is already started.
> +  //
> +  if (AdapterInfo->State != PXE_STATFLAGS_GET_STATE_STOPPED) {
> +    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +    CdbPtr->StatCode  = PXE_STATCODE_ALREADY_STARTED;
> +    return ;
> +  }
> +
> +  if (CdbPtr->CPBsize != sizeof(PXE_CPB_START_30) &&
> +      CdbPtr->CPBsize != sizeof(PXE_CPB_START_31)) {
> +
> +    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
> +    return ;
> +  }
> +
> +  CpbPtr    = (PXE_CPB_START_30 *) (UINTN) (CdbPtr->CPBaddr);
> +  CpbPtr_31 = (PXE_CPB_START_31 *) (UINTN) (CdbPtr->CPBaddr);
> +
> +  if (AdapterInfo->VersionFlag == 0x30) {
> +    AdapterInfo->Delay_30     = (bsptr_30) (UINTN) CpbPtr->Delay;
> +    AdapterInfo->Virt2Phys_30 = (virtphys_30) (UINTN) CpbPtr->Virt2Phys;
> +    AdapterInfo->Block_30     = (block_30) (UINTN) CpbPtr->Block;
> +    //
> +    // patch for old buggy 3.0 code:
> +    // In EFI1.0 undi used to provide the full (absolute) I/O address to the
> +    // i/o calls and SNP used to provide a callback that used GlobalIoFncs and
> +    // everything worked fine! In EFI 1.1, UNDI is not using the full
> +    // i/o or memory address to access the device, The base values for the i/o
> +    // and memory address is abstracted by the device specific PciIoFncs and
> +    // UNDI only uses the offset values. Since UNDI3.0 cannot provide any
> +    // identification to SNP, SNP cannot use nic specific PciIoFncs callback!
> +    //
> +    // To fix this and make undi3.0 work with SNP in EFI1.1 we
> +    // use a TmpMemIo function that is defined in init.c
> +    // This breaks the runtime driver feature of undi, but what to do
> +    // if we have to provide the 3.0 compatibility (including the 3.0 bugs)
> +    //
> +    // This TmpMemIo function also takes a UniqueId parameter
> +    // (as in undi3.1 design) and so initialize the UniqueId as well here
> +    // Note: AdapterInfo->Mem_Io_30 is just filled for consistency with other
> +    // parameters but never used, we only use Mem_Io field in the In/Out
> routines
> +    // inside e100b.c.
> +    //
> +    AdapterInfo->Mem_Io_30  = (mem_io_30) (UINTN) CpbPtr->Mem_IO;
> +    AdapterInfo->Mem_Io     = (mem_io) (UINTN) TmpMemIo;
> +    AdapterInfo->Unique_ID  = (UINT64) (UINTN) AdapterInfo;
> +
> +  } else {
> +    AdapterInfo->Delay      = (bsptr) (UINTN) CpbPtr_31->Delay;
> +    AdapterInfo->Virt2Phys  = (virtphys) (UINTN) CpbPtr_31->Virt2Phys;
> +    AdapterInfo->Block      = (block) (UINTN) CpbPtr_31->Block;
> +    AdapterInfo->Mem_Io     = (mem_io) (UINTN) CpbPtr_31->Mem_IO;
> +
> +    AdapterInfo->Map_Mem    = (map_mem) (UINTN) CpbPtr_31-
> >Map_Mem;
> +    AdapterInfo->UnMap_Mem  = (unmap_mem) (UINTN) CpbPtr_31-
> >UnMap_Mem;
> +    AdapterInfo->Sync_Mem   = (sync_mem) (UINTN) CpbPtr_31->Sync_Mem;
> +    AdapterInfo->Unique_ID  = CpbPtr_31->Unique_ID;
> +  }
> +
> +  AdapterInfo->State = PXE_STATFLAGS_GET_STATE_STARTED;
> +
> +  return ;
> +}
> +
> +
> +/**
> +  This routine is used to change the operational state of the UNDI from
> started to stopped.
> +  It will not do this if the adapter's state is
> PXE_STATFLAGS_GET_STATE_INITIALIZED, otherwise
> +  the CdbPtr->StatFlags will reflect a command failure, and the CdbPtr-
> >StatCode will reflect the
> +  UNDI as having already not been shut down.
> +  The NIC's data structure will have the Delay, Virt2Phys, and Block, pointers
> zero'd out..
> +  It's final action is to change the AdapterInfo->State to
> PXE_STATFLAGS_GET_STATE_STOPPED.
> +
> +  @param  CdbPtr               Pointer to the command descriptor block.
> +  @param  AdapterInfo          Pointer to the NIC data structure information
> which
> +                               the UNDI driver is layering on..
> +
> +  @return None
> +
> +**/
> +VOID
> +UNDI_Stop (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  if (AdapterInfo->State == PXE_STATFLAGS_GET_STATE_INITIALIZED) {
> +    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +    CdbPtr->StatCode  = PXE_STATCODE_NOT_SHUTDOWN;
> +    return ;
> +  }
> +
> +  AdapterInfo->Delay_30     = 0;
> +  AdapterInfo->Virt2Phys_30 = 0;
> +  AdapterInfo->Block_30     = 0;
> +
> +  AdapterInfo->Delay        = 0;
> +  AdapterInfo->Virt2Phys    = 0;
> +  AdapterInfo->Block        = 0;
> +
> +  AdapterInfo->Map_Mem      = 0;
> +  AdapterInfo->UnMap_Mem    = 0;
> +  AdapterInfo->Sync_Mem     = 0;
> +
> +  AdapterInfo->State        = PXE_STATFLAGS_GET_STATE_STOPPED;
> +
> +  return ;
> +}
> +
> +
> +/**
> +  This routine is used to retrieve the initialization information that is needed
> by drivers and
> +  applications to initialize the UNDI.  This will fill in data in the Data Block
> structure that is
> +  pointed to by the caller's CdbPtr->DBaddr.  The fields filled in are as
> follows:
> +  MemoryRequired, FrameDataLen, LinkSpeeds[0-3], NvCount, NvWidth,
> MediaHeaderLen, HWaddrLen,
> +  MCastFilterCnt, TxBufCnt, TxBufSize, RxBufCnt, RxBufSize, IFtype, Duplex,
> and LoopBack.
> +  In addition, the CdbPtr->StatFlags ORs in that this NIC supports cable
> detection.  (APRIORI knowledge)
> +
> +  @param  CdbPtr               Pointer to the command descriptor block.
> +  @param  AdapterInfo          Pointer to the NIC data structure information
> which
> +                               the UNDI driver is layering on..
> +
> +  @return None
> +
> +**/
> +VOID
> +UNDI_GetInitInfo (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  PXE_DB_GET_INIT_INFO  *DbPtr;
> +
> +  DbPtr = (PXE_DB_GET_INIT_INFO *) (UINTN) (CdbPtr->DBaddr);
> +
> +  DbPtr->MemoryRequired = MEMORY_NEEDED;
> +  DbPtr->FrameDataLen = PXE_MAX_TXRX_UNIT_ETHER;
> +  DbPtr->LinkSpeeds[0] = 10;
> +  DbPtr->LinkSpeeds[1] = 100;
> +  DbPtr->LinkSpeeds[2] = DbPtr->LinkSpeeds[3] = 0;
> +  DbPtr->NvCount = MAX_EEPROM_LEN;
> +  DbPtr->NvWidth = 4;
> +  DbPtr->MediaHeaderLen = PXE_MAC_HEADER_LEN_ETHER;
> +  DbPtr->HWaddrLen = PXE_HWADDR_LEN_ETHER;
> +  DbPtr->MCastFilterCnt = MAX_MCAST_ADDRESS_CNT;
> +
> +  DbPtr->TxBufCnt = TX_BUFFER_COUNT;
> +  DbPtr->TxBufSize = (UINT16) sizeof (TxCB);
> +  DbPtr->RxBufCnt = RX_BUFFER_COUNT;
> +  DbPtr->RxBufSize = (UINT16) sizeof (RxFD);
> +
> +  DbPtr->IFtype = PXE_IFTYPE_ETHERNET;
> +  DbPtr->SupportedDuplexModes =
> PXE_DUPLEX_ENABLE_FULL_SUPPORTED |
> +                  PXE_DUPLEX_FORCE_FULL_SUPPORTED;
> +  DbPtr->SupportedLoopBackModes =
> PXE_LOOPBACK_INTERNAL_SUPPORTED |
> +                    PXE_LOOPBACK_EXTERNAL_SUPPORTED;
> +
> +  CdbPtr->StatFlags |= (PXE_STATFLAGS_CABLE_DETECT_SUPPORTED |
> +                        PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED);
> +  return ;
> +}
> +
> +
> +/**
> +  This routine is used to retrieve the configuration information about the
> NIC being controlled by
> +  this driver.  This will fill in data in the Data Block structure that is pointed
> to by the caller's CdbPtr->DBaddr.
> +  The fields filled in are as follows:
> +  DbPtr->pci.BusType, DbPtr->pci.Bus, DbPtr->pci.Device, and DbPtr->pci.
> +  In addition, the DbPtr->pci.Config.Dword[0-63] grabs a copy of this NIC's
> PCI configuration space.
> +
> +  @param  CdbPtr               Pointer to the command descriptor block.
> +  @param  AdapterInfo          Pointer to the NIC data structure information
> which
> +                               the UNDI driver is layering on..
> +
> +  @return None
> +
> +**/
> +VOID
> +UNDI_GetConfigInfo (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  UINT16                  Index;
> +  PXE_DB_GET_CONFIG_INFO  *DbPtr;
> +
> +  DbPtr               = (PXE_DB_GET_CONFIG_INFO *) (UINTN) (CdbPtr->DBaddr);
> +
> +  DbPtr->pci.BusType  = PXE_BUSTYPE_PCI;
> +  DbPtr->pci.Bus      = AdapterInfo->Bus;
> +  DbPtr->pci.Device   = AdapterInfo->Device;
> +  DbPtr->pci.Function = AdapterInfo->Function;
> +
> +  for (Index = 0; Index < MAX_PCI_CONFIG_LEN; Index++) {
> +    DbPtr->pci.Config.Dword[Index] = AdapterInfo->Config[Index];
> +  }
> +
> +  return ;
> +}
> +
> +
> +/**
> +  This routine resets the network adapter and initializes the UNDI using the
> parameters supplied in
> +  the CPB.  This command must be issued before the network adapter can
> be setup to transmit and
> +  receive packets.
> +  Once the memory requirements of the UNDI are obtained by using the
> GetInitInfo command, a block
> +  of non-swappable memory may need to be allocated.  The address of this
> memory must be passed to
> +  UNDI during the Initialize in the CPB.  This memory is used primarily for
> transmit and receive buffers.
> +  The fields CableDetect, LinkSpeed, Duplex, LoopBack, MemoryPtr, and
> MemoryLength are set with information
> +  that was passed in the CPB and the NIC is initialized.
> +  If the NIC initialization fails, the CdbPtr->StatFlags are updated with
> PXE_STATFLAGS_COMMAND_FAILED
> +  Otherwise, AdapterInfo->State is updated with
> PXE_STATFLAGS_GET_STATE_INITIALIZED showing the state of
> +  the UNDI is now initialized.
> +
> +  @param  CdbPtr               Pointer to the command descriptor block.
> +  @param  AdapterInfo          Pointer to the NIC data structure information
> which
> +                               the UNDI driver is layering on..
> +
> +  @return None
> +
> +**/
> +VOID
> +UNDI_Initialize (
> +  IN  PXE_CDB       *CdbPtr,
> +  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  PXE_CPB_INITIALIZE  *CpbPtr;
> +
> +  if ((CdbPtr->OpFlags != PXE_OPFLAGS_INITIALIZE_DETECT_CABLE) &&
> +      (CdbPtr->OpFlags !=
> PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE)) {
> +    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
> +    return ;
> +  }
> +
> +  //
> +  // check if it is already initialized
> +  //
> +  if (AdapterInfo->State == PXE_STATFLAGS_GET_STATE_INITIALIZED) {
> +    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +    CdbPtr->StatCode  = PXE_STATCODE_ALREADY_INITIALIZED;
> +    return ;
> +  }
> +
> +  CpbPtr  = (PXE_CPB_INITIALIZE *) (UINTN) CdbPtr->CPBaddr;
> +
> +  if (CpbPtr->MemoryLength < (UINT32) MEMORY_NEEDED) {
> +    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CPB;
> +    return ;
> +  }
> +
> +  //
> +  // default behaviour is to detect the cable, if the 3rd param is 1,
> +  // do not do that
> +  //
> +  AdapterInfo->CableDetect = (UINT8) ((CdbPtr->OpFlags == (UINT16)
> PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE) ? (UINT8) 0 : (UINT8) 1);
> +  AdapterInfo->LinkSpeedReq = (UINT16) CpbPtr->LinkSpeed;
> +  AdapterInfo->DuplexReq    = CpbPtr->DuplexMode;
> +  AdapterInfo->LoopBack     = CpbPtr->LoopBackMode;
> +  AdapterInfo->MemoryPtr    = CpbPtr->MemoryAddr;
> +  AdapterInfo->MemoryLength = CpbPtr->MemoryLength;
> +
> +  CdbPtr->StatCode          = (PXE_STATCODE) E100bInit (AdapterInfo);
> +
> +  if (CdbPtr->StatCode != PXE_STATCODE_SUCCESS) {
> +    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +  } else {
> +    AdapterInfo->State = PXE_STATFLAGS_GET_STATE_INITIALIZED;
> +  }
> +
> +  return ;
> +}
> +
> +
> +/**
> +  This routine resets the network adapter and initializes the UNDI using the
> parameters supplied in
> +  the CPB.  The transmit and receive queues are emptied and any pending
> interrupts are cleared.
> +  If the NIC reset fails, the CdbPtr->StatFlags are updated with
> PXE_STATFLAGS_COMMAND_FAILED
> +
> +  @param  CdbPtr               Pointer to the command descriptor block.
> +  @param  AdapterInfo          Pointer to the NIC data structure information
> which
> +                               the UNDI driver is layering on..
> +
> +  @return None
> +
> +**/
> +VOID
> +UNDI_Reset (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  if (CdbPtr->OpFlags != PXE_OPFLAGS_NOT_USED &&
> +      CdbPtr->OpFlags != PXE_OPFLAGS_RESET_DISABLE_INTERRUPTS &&
> +      CdbPtr->OpFlags != PXE_OPFLAGS_RESET_DISABLE_FILTERS ) {
> +
> +    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
> +    return ;
> +  }
> +
> +  CdbPtr->StatCode = (UINT16) E100bReset (AdapterInfo, CdbPtr->OpFlags);
> +
> +  if (CdbPtr->StatCode != PXE_STATCODE_SUCCESS) {
> +    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +  }
> +}
> +
> +
> +/**
> +  This routine resets the network adapter and leaves it in a safe state for
> another driver to
> +  initialize.  Any pending transmits or receives are lost.  Receive filters and
> external
> +  interrupt enables are disabled.  Once the UNDI has been shutdown, it can
> then be stopped
> +  or initialized again.
> +  If the NIC reset fails, the CdbPtr->StatFlags are updated with
> PXE_STATFLAGS_COMMAND_FAILED
> +  Otherwise, AdapterInfo->State is updated with
> PXE_STATFLAGS_GET_STATE_STARTED showing the state of
> +  the NIC as being started.
> +
> +  @param  CdbPtr               Pointer to the command descriptor block.
> +  @param  AdapterInfo          Pointer to the NIC data structure information
> which
> +                               the UNDI driver is layering on..
> +
> +  @return None
> +
> +**/
> +VOID
> +UNDI_Shutdown (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  //
> +  // do the shutdown stuff here
> +  //
> +  CdbPtr->StatCode = (UINT16) E100bShutdown (AdapterInfo);
> +
> +  if (CdbPtr->StatCode != PXE_STATCODE_SUCCESS) {
> +    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +  } else {
> +    AdapterInfo->State = PXE_STATFLAGS_GET_STATE_STARTED;
> +  }
> +
> +  return ;
> +}
> +
> +
> +/**
> +  This routine can be used to read and/or change the current external
> interrupt enable
> +  settings.  Disabling an external interrupt enable prevents and external
> (hardware)
> +  interrupt from being signaled by the network device.  Internally the
> interrupt events
> +  can still be polled by using the UNDI_GetState command.
> +  The resulting information on the interrupt state will be passed back in the
> CdbPtr->StatFlags.
> +
> +  @param  CdbPtr               Pointer to the command descriptor block.
> +  @param  AdapterInfo          Pointer to the NIC data structure information
> which
> +                               the UNDI driver is layering on..
> +
> +  @return None
> +
> +**/
> +VOID
> +UNDI_Interrupt (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  UINT8 IntMask;
> +
> +  IntMask = (UINT8)(UINTN)(CdbPtr->OpFlags &
> (PXE_OPFLAGS_INTERRUPT_RECEIVE |
> +                                              PXE_OPFLAGS_INTERRUPT_TRANSMIT |
> +                                              PXE_OPFLAGS_INTERRUPT_COMMAND |
> +                                              PXE_OPFLAGS_INTERRUPT_SOFTWARE));
> +
> +  switch (CdbPtr->OpFlags & PXE_OPFLAGS_INTERRUPT_OPMASK) {
> +  case PXE_OPFLAGS_INTERRUPT_READ:
> +    break;
> +
> +  case PXE_OPFLAGS_INTERRUPT_ENABLE:
> +    if (IntMask == 0) {
> +      CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +      CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
> +      return ;
> +    }
> +
> +    AdapterInfo->int_mask = IntMask;
> +    E100bSetInterruptState (AdapterInfo);
> +    break;
> +
> +  case PXE_OPFLAGS_INTERRUPT_DISABLE:
> +    if (IntMask != 0) {
> +      AdapterInfo->int_mask = (UINT16) (AdapterInfo->int_mask &
> ~(IntMask));
> +      E100bSetInterruptState (AdapterInfo);
> +      break;
> +    }
> +
> +  //
> +  // else fall thru.
> +  //
> +  default:
> +    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
> +    return ;
> +  }
> +
> +  if ((AdapterInfo->int_mask & PXE_OPFLAGS_INTERRUPT_RECEIVE) != 0) {
> +    CdbPtr->StatFlags |= PXE_STATFLAGS_INTERRUPT_RECEIVE;
> +
> +  }
> +
> +  if ((AdapterInfo->int_mask & PXE_OPFLAGS_INTERRUPT_TRANSMIT) != 0)
> {
> +    CdbPtr->StatFlags |= PXE_STATFLAGS_INTERRUPT_TRANSMIT;
> +
> +  }
> +
> +  if ((AdapterInfo->int_mask & PXE_OPFLAGS_INTERRUPT_COMMAND) != 0)
> {
> +    CdbPtr->StatFlags |= PXE_STATFLAGS_INTERRUPT_COMMAND;
> +
> +  }
> +
> +  return ;
> +}
> +
> +
> +/**
> +  This routine is used to read and change receive filters and, if supported,
> read
> +  and change multicast MAC address filter list.
> +
> +  @param  CdbPtr               Pointer to the command descriptor block.
> +  @param  AdapterInfo          Pointer to the NIC data structure information
> which
> +                               the UNDI driver is layering on..
> +
> +  @return None
> +
> +**/
> +VOID
> +UNDI_RecFilter (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  UINT16                  NewFilter;
> +  UINT16                  OpFlags;
> +  PXE_DB_RECEIVE_FILTERS  *DbPtr;
> +  UINT8                   *MacAddr;
> +  UINTN                   MacCount;
> +  UINT16                  Index;
> +  UINT16                  copy_len;
> +  UINT8                   *ptr1;
> +  UINT8                   *ptr2;
> +  BOOLEAN                 InvalidMacAddr;
> +
> +  OpFlags   = CdbPtr->OpFlags;
> +  NewFilter = (UINT16) (OpFlags & 0x1F);
> +
> +  switch (OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_OPMASK) {
> +  case PXE_OPFLAGS_RECEIVE_FILTER_READ:
> +
> +    //
> +    // not expecting a cpb, not expecting any filter bits
> +    //
> +    if ((NewFilter != 0) || (CdbPtr->CPBsize != 0)) {
> +      goto BadCdb;
> +
> +    }
> +
> +    if ((NewFilter & PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST) == 0)
> {
> +      goto JustRead;
> +
> +    }
> +
> +    NewFilter = (UINT16) (NewFilter | AdapterInfo->Rx_Filter);
> +    //
> +    // all other flags are ignored except mcast_reset
> +    //
> +    break;
> +
> +  case PXE_OPFLAGS_RECEIVE_FILTER_ENABLE:
> +    //
> +    // there should be atleast one other filter bit set.
> +    //
> +    if (NewFilter == 0) {
> +      //
> +      // nothing to enable
> +      //
> +      goto BadCdb;
> +    }
> +
> +    if (CdbPtr->CPBsize != 0) {
> +      //
> +      // this must be a multicast address list!
> +      // don't accept the list unless selective_mcast is set
> +      // don't accept confusing mcast settings with this
> +      //
> +      if (((NewFilter & PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST)
> == 0) ||
> +          ((NewFilter & PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST) !=
> 0) ||
> +          ((NewFilter & PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST) != 0)
> ||
> +          ((CdbPtr->CPBsize % sizeof (PXE_MAC_ADDR)) != 0) ) {
> +        goto BadCdb;
> +      }
> +
> +      MacAddr   = (UINT8 *) ((UINTN) (CdbPtr->CPBaddr));
> +      MacCount  = CdbPtr->CPBsize / sizeof (PXE_MAC_ADDR);
> +
> +      //
> +      // The format of Ethernet multicast address for IPv6 is defined in
> RFC2464,
> +      // for IPv4 is defined in RFC1112. Check whether the address is valid.
> +      //
> +      InvalidMacAddr = FALSE;
> +
> +      for (; MacCount-- != 0; MacAddr += sizeof (PXE_MAC_ADDR)) {
> +        if (MacAddr[0] == 0x01) {
> +          //
> +          // This multicast MAC address is mapped from IPv4 address.
> +          //
> +          if (MacAddr[1] != 0x00 || MacAddr[2] != 0x5E || (MacAddr[3] &
> 0x80) != 0) {
> +            InvalidMacAddr = TRUE;
> +          }
> +        } else if (MacAddr[0] == 0x33) {
> +          //
> +          // This multicast MAC address is mapped from IPv6 address.
> +          //
> +          if (MacAddr[1] != 0x33) {
> +            InvalidMacAddr = TRUE;
> +          }
> +        } else {
> +          InvalidMacAddr = TRUE;
> +        }
> +
> +        if (InvalidMacAddr) {
> +          CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +          CdbPtr->StatCode  = PXE_STATCODE_INVALID_CPB;
> +          return ;
> +        }
> +      }
> +    }
> +
> +    //
> +    // check selective mcast case enable case
> +    //
> +    if ((OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) !=
> 0) {
> +      if (((OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST) != 0)
> ||
> +          ((OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST) != 0) ) {
> +        goto BadCdb;
> +
> +      }
> +      //
> +      // if no cpb, make sure we have an old list
> +      //
> +      if ((CdbPtr->CPBsize == 0) && (AdapterInfo->mcast_list.list_len == 0)) {
> +        goto BadCdb;
> +      }
> +    }
> +    //
> +    // if you want to enable anything, you got to have unicast
> +    // and you have what you already enabled!
> +    //
> +    NewFilter = (UINT16) (NewFilter |
> (PXE_OPFLAGS_RECEIVE_FILTER_UNICAST | AdapterInfo->Rx_Filter));
> +
> +    break;
> +
> +  case PXE_OPFLAGS_RECEIVE_FILTER_DISABLE:
> +
> +    //
> +    // mcast list not expected, i.e. no cpb here!
> +    //
> +    if (CdbPtr->CPBsize != PXE_CPBSIZE_NOT_USED) {
> +      goto BadCdb;
> +    }
> +
> +    NewFilter = (UINT16) ((~(CdbPtr->OpFlags & 0x1F)) & AdapterInfo-
> >Rx_Filter);
> +
> +    break;
> +
> +  default:
> +    goto BadCdb;
> +  }
> +
> +  if ((OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST) != 0) {
> +    AdapterInfo->mcast_list.list_len = 0;
> +    NewFilter &= (~PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST);
> +  }
> +
> +  E100bSetfilter (AdapterInfo, NewFilter, CdbPtr->CPBaddr, CdbPtr-
> >CPBsize);
> +
> +JustRead:
> +  //
> +  // give the current mcast list
> +  //
> +  if ((CdbPtr->DBsize != 0) && (AdapterInfo->mcast_list.list_len != 0)) {
> +    //
> +    // copy the mc list to db
> +    //
> +
> +    DbPtr = (PXE_DB_RECEIVE_FILTERS *) (UINTN) CdbPtr->DBaddr;
> +    ptr1  = (UINT8 *) (&DbPtr->MCastList[0]);
> +
> +    //
> +    // DbPtr->mc_count = AdapterInfo->mcast_list.list_len;
> +    //
> +    copy_len = (UINT16) (AdapterInfo->mcast_list.list_len *
> PXE_MAC_LENGTH);
> +
> +    if (copy_len > CdbPtr->DBsize) {
> +      copy_len = CdbPtr->DBsize;
> +
> +    }
> +
> +    ptr2 = (UINT8 *) (&AdapterInfo->mcast_list.mc_list[0]);
> +    for (Index = 0; Index < copy_len; Index++) {
> +      ptr1[Index] = ptr2[Index];
> +    }
> +  }
> +  //
> +  // give the stat flags here
> +  //
> +  if (AdapterInfo->Receive_Started) {
> +    CdbPtr->StatFlags = (PXE_STATFLAGS) (CdbPtr->StatFlags | AdapterInfo-
> >Rx_Filter);
> +
> +  }
> +
> +  return ;
> +
> +BadCdb:
> +  CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +  CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
> +}
> +
> +
> +/**
> +  This routine is used to get the current station and broadcast MAC
> addresses, and to change the
> +  current station MAC address.
> +
> +  @param  CdbPtr               Pointer to the command descriptor block.
> +  @param  AdapterInfo          Pointer to the NIC data structure information
> which
> +                               the UNDI driver is layering on..
> +
> +  @return None
> +
> +**/
> +VOID
> +UNDI_StnAddr (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  PXE_CPB_STATION_ADDRESS *CpbPtr;
> +  PXE_DB_STATION_ADDRESS  *DbPtr;
> +  UINT16                  Index;
> +
> +  if (CdbPtr->OpFlags == PXE_OPFLAGS_STATION_ADDRESS_RESET) {
> +    //
> +    // configure the permanent address.
> +    // change the AdapterInfo->CurrentNodeAddress field.
> +    //
> +    if (CompareMem (
> +          &AdapterInfo->CurrentNodeAddress[0],
> +          &AdapterInfo->PermNodeAddress[0],
> +          PXE_MAC_LENGTH
> +          ) != 0) {
> +      for (Index = 0; Index < PXE_MAC_LENGTH; Index++) {
> +        AdapterInfo->CurrentNodeAddress[Index] = AdapterInfo-
> >PermNodeAddress[Index];
> +      }
> +
> +      E100bSetupIAAddr (AdapterInfo);
> +    }
> +  }
> +
> +  if (CdbPtr->CPBaddr != (UINT64) 0) {
> +    CpbPtr = (PXE_CPB_STATION_ADDRESS *) (UINTN) (CdbPtr->CPBaddr);
> +    //
> +    // configure the new address
> +    //
> +    for (Index = 0; Index < PXE_MAC_LENGTH; Index++) {
> +      AdapterInfo->CurrentNodeAddress[Index] = CpbPtr->StationAddr[Index];
> +    }
> +
> +    E100bSetupIAAddr (AdapterInfo);
> +  }
> +
> +  if (CdbPtr->DBaddr != (UINT64) 0) {
> +    DbPtr = (PXE_DB_STATION_ADDRESS *) (UINTN) (CdbPtr->DBaddr);
> +    //
> +    // fill it with the new values
> +    //
> +    for (Index = 0; Index < PXE_MAC_LENGTH; Index++) {
> +      DbPtr->StationAddr[Index]   = AdapterInfo->CurrentNodeAddress[Index];
> +      DbPtr->BroadcastAddr[Index] = AdapterInfo-
> >BroadcastNodeAddress[Index];
> +      DbPtr->PermanentAddr[Index] = AdapterInfo-
> >PermNodeAddress[Index];
> +    }
> +  }
> +
> +  return ;
> +}
> +
> +
> +/**
> +  This routine is used to read and clear the NIC traffic statistics.  This
> command is supported only
> +  if the !PXE structure's Implementation flags say so.
> +  Results will be parsed out in the following manner:
> +  CdbPtr->DBaddr.Data[0]   R  Total Frames (Including frames with errors
> and dropped frames)
> +  CdbPtr->DBaddr.Data[1]   R  Good Frames (All frames copied into receive
> buffer)
> +  CdbPtr->DBaddr.Data[2]   R  Undersize Frames (Frames below minimum
> length for media <64 for ethernet)
> +  CdbPtr->DBaddr.Data[4]   R  Dropped Frames (Frames that were dropped
> because receive buffers were full)
> +  CdbPtr->DBaddr.Data[8]   R  CRC Error Frames (Frames with alignment or
> CRC errors)
> +  CdbPtr->DBaddr.Data[A]   T  Total Frames (Including frames with errors
> and dropped frames)
> +  CdbPtr->DBaddr.Data[B]   T  Good Frames (All frames copied into transmit
> buffer)
> +  CdbPtr->DBaddr.Data[C]   T  Undersize Frames (Frames below minimum
> length for media <64 for ethernet)
> +  CdbPtr->DBaddr.Data[E]   T  Dropped Frames (Frames that were dropped
> because of collisions)
> +  CdbPtr->DBaddr.Data[14]  T  Total Collision Frames (Total collisions on this
> subnet)
> +
> +  @param  CdbPtr               Pointer to the command descriptor block.
> +  @param  AdapterInfo          Pointer to the NIC data structure information
> which
> +                               the UNDI driver is layering on..
> +
> +  @return None
> +
> +**/
> +VOID
> +UNDI_Statistics (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  if ((CdbPtr->OpFlags &~(PXE_OPFLAGS_STATISTICS_RESET)) != 0) {
> +    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
> +    return ;
> +  }
> +
> +  if ((CdbPtr->OpFlags & PXE_OPFLAGS_STATISTICS_RESET) != 0) {
> +    //
> +    // Reset the statistics
> +    //
> +    CdbPtr->StatCode = (UINT16) E100bStatistics (AdapterInfo, 0, 0);
> +  } else {
> +    CdbPtr->StatCode = (UINT16) E100bStatistics (AdapterInfo, CdbPtr-
> >DBaddr, CdbPtr->DBsize);
> +  }
> +
> +  return ;
> +}
> +
> +
> +/**
> +  This routine is used to translate a multicast IP address to a multicast MAC
> address.
> +  This results in a MAC address composed of 25 bits of fixed data with the
> upper 23 bits of the IP
> +  address being appended to it.  Results passed back in the equivalent of
> CdbPtr->DBaddr->MAC[0-5].
> +
> +  @param  CdbPtr               Pointer to the command descriptor block.
> +  @param  AdapterInfo          Pointer to the NIC data structure information
> which
> +                               the UNDI driver is layering on..
> +
> +  @return None
> +
> +**/
> +VOID
> +UNDI_ip2mac (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  PXE_CPB_MCAST_IP_TO_MAC *CpbPtr;
> +  PXE_DB_MCAST_IP_TO_MAC  *DbPtr;
> +  UINT8                   *TmpPtr;
> +
> +  CpbPtr  = (PXE_CPB_MCAST_IP_TO_MAC *) (UINTN) CdbPtr->CPBaddr;
> +  DbPtr   = (PXE_DB_MCAST_IP_TO_MAC *) (UINTN) CdbPtr->DBaddr;
> +
> +  if ((CdbPtr->OpFlags & PXE_OPFLAGS_MCAST_IPV6_TO_MAC) != 0) {
> +    //
> +    // for now this is not supported
> +    //
> +    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +    CdbPtr->StatCode  = PXE_STATCODE_UNSUPPORTED;
> +    return ;
> +  }
> +
> +  TmpPtr = (UINT8 *) (&CpbPtr->IP.IPv4);
> +  //
> +  // check if the ip given is a mcast IP
> +  //
> +  if ((TmpPtr[0] & 0xF0) != 0xE0) {
> +    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CPB;
> +  }
> +  //
> +  // take the last 23 bits in IP.
> +  // be very careful. accessing word on a non-word boundary will hang
> motherboard codenamed Big Sur
> +  // casting the mac array (in the middle) to a UINT32 pointer and accessing
> +  // the UINT32 content hung the system...
> +  //
> +  DbPtr->MAC[0] = 0x01;
> +  DbPtr->MAC[1] = 0x00;
> +  DbPtr->MAC[2] = 0x5e;
> +  DbPtr->MAC[3] = (UINT8) (TmpPtr[1] & 0x7f);
> +  DbPtr->MAC[4] = (UINT8) TmpPtr[2];
> +  DbPtr->MAC[5] = (UINT8) TmpPtr[3];
> +
> +  return ;
> +}
> +
> +
> +/**
> +  This routine is used to read and write non-volatile storage on the NIC (if
> supported).  The NVRAM
> +  could be EEPROM, FLASH, or battery backed RAM.
> +  This is an optional function according to the UNDI specification  (or will
> be......)
> +
> +  @param  CdbPtr               Pointer to the command descriptor block.
> +  @param  AdapterInfo          Pointer to the NIC data structure information
> which
> +                               the UNDI driver is layering on..
> +
> +  @return None
> +
> +**/
> +VOID
> +UNDI_NVData (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  PXE_DB_NVDATA *DbPtr;
> +  UINT16        Index;
> +
> +  if ((CdbPtr->OpFlags == PXE_OPFLAGS_NVDATA_READ) != 0) {
> +
> +    if ((CdbPtr->DBsize == PXE_DBSIZE_NOT_USED) != 0) {
> +      CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +      CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
> +      return ;
> +    }
> +
> +    DbPtr = (PXE_DB_NVDATA *) (UINTN) CdbPtr->DBaddr;
> +
> +    for (Index = 0; Index < MAX_PCI_CONFIG_LEN; Index++) {
> +      DbPtr->Data.Dword[Index] = AdapterInfo->NVData[Index];
> +
> +    }
> +
> +  } else {
> +    //
> +    // no write for now
> +    //
> +    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +    CdbPtr->StatCode  = PXE_STATCODE_UNSUPPORTED;
> +  }
> +
> +  return ;
> +}
> +
> +
> +/**
> +  This routine returns the current interrupt status and/or the transmitted
> buffer addresses.
> +  If the current interrupt status is returned, pending interrupts will be
> acknowledged by this
> +  command.  Transmitted buffer addresses that are written to the DB are
> removed from the transmit
> +  buffer queue.
> +  Normally, this command would be polled with interrupts disabled.
> +  The transmit buffers are returned in CdbPtr->DBaddr->TxBufer[0 -
> NumEntries].
> +  The interrupt status is returned in CdbPtr->StatFlags.
> +
> +  @param  CdbPtr               Pointer to the command descriptor block.
> +  @param  AdapterInfo          Pointer to the NIC data structure information
> which
> +                               the UNDI driver is layering on..
> +
> +  @return None
> +
> +**/
> +VOID
> +UNDI_Status (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  PXE_DB_GET_STATUS *DbPtr;
> +  PXE_DB_GET_STATUS TmpGetStatus;
> +  UINT16            Index;
> +  UINT16            Status;
> +  UINT16            NumEntries;
> +  RxFD              *RxPtr;
> +
> +  //
> +  // Fill in temporary GetStatus storage.
> +  //
> +  RxPtr = &AdapterInfo->rx_ring[AdapterInfo->cur_rx_ind];
> +
> +  if ((RxPtr->cb_header.status & RX_COMPLETE) != 0) {
> +    TmpGetStatus.RxFrameLen = RxPtr->ActualCount & 0x3fff;
> +  } else {
> +    TmpGetStatus.RxFrameLen = 0;
> +  }
> +
> +  TmpGetStatus.reserved = 0;
> +
> +  //
> +  // Fill in size of next available receive packet and
> +  // reserved field in caller's DB storage.
> +  //
> +  DbPtr = (PXE_DB_GET_STATUS *) (UINTN) CdbPtr->DBaddr;
> +
> +  if (CdbPtr->DBsize > 0 && CdbPtr->DBsize < sizeof (UINT32) * 2) {
> +    CopyMem (DbPtr, &TmpGetStatus, CdbPtr->DBsize);
> +  } else {
> +    CopyMem (DbPtr, &TmpGetStatus, sizeof (UINT32) * 2);
> +  }
> +
> +  //
> +  //
> +  //
> +  if ((CdbPtr->OpFlags & PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS) != 0)
> {
> +    //
> +    // DBsize of zero is invalid if Tx buffers are requested.
> +    //
> +    if (CdbPtr->DBsize == 0) {
> +      CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +      CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
> +      return ;
> +    }
> +
> +    //
> +    // remember this b4 we overwrite
> +    //
> +    NumEntries = (UINT16) (CdbPtr->DBsize - sizeof (UINT64));
> +
> +    //
> +    // We already filled in 2 UINT32s.
> +    //
> +    CdbPtr->DBsize = (UINT16) (sizeof (UINT32) * 2);
> +
> +    //
> +    // will claim any hanging free CBs
> +    //
> +    CheckCBList (AdapterInfo);
> +
> +    if (AdapterInfo->xmit_done_head == AdapterInfo->xmit_done_tail) {
> +      CdbPtr->StatFlags |=
> PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY;
> +    } else {
> +      for (Index = 0; ((Index < MAX_XMIT_BUFFERS) && (NumEntries >= sizeof
> (UINT64))); Index++, NumEntries -= sizeof (UINT64)) {
> +        if (AdapterInfo->xmit_done_head != AdapterInfo->xmit_done_tail) {
> +          DbPtr->TxBuffer[Index]      = AdapterInfo->xmit_done[AdapterInfo-
> >xmit_done_head];
> +          AdapterInfo->xmit_done_head = next (AdapterInfo-
> >xmit_done_head);
> +          CdbPtr->DBsize += sizeof (UINT64);
> +        } else {
> +          break;
> +        }
> +      }
> +    }
> +
> +    if (AdapterInfo->xmit_done_head != AdapterInfo->xmit_done_tail) {
> +      CdbPtr->StatFlags |= PXE_STATFLAGS_DB_WRITE_TRUNCATED;
> +
> +    }
> +    //
> +    // check for a receive buffer and give it's size in db
> +    //
> +  }
> +  //
> +  //
> +  //
> +  if ((CdbPtr->OpFlags & PXE_OPFLAGS_GET_INTERRUPT_STATUS) != 0) {
> +
> +    Status = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBStatus);
> +    AdapterInfo->Int_Status = (UINT16) (AdapterInfo->Int_Status | Status);
> +
> +    //
> +    // acknoledge the interrupts
> +    //
> +    OutWord (AdapterInfo, (UINT16) (Status & 0xfc00), (UINT32)
> (AdapterInfo->ioaddr + SCBStatus));
> +
> +    //
> +    // report all the outstanding interrupts
> +    //
> +    Status = AdapterInfo->Int_Status;
> +    if ((Status & SCB_STATUS_FR) != 0) {
> +      CdbPtr->StatFlags |= PXE_STATFLAGS_GET_STATUS_RECEIVE;
> +    }
> +
> +    if ((Status & SCB_STATUS_SWI) != 0) {
> +      CdbPtr->StatFlags |= PXE_STATFLAGS_GET_STATUS_SOFTWARE;
> +    }
> +  }
> +
> +  //
> +  // Return current media status
> +  //
> +  if ((CdbPtr->OpFlags & PXE_OPFLAGS_GET_MEDIA_STATUS) != 0) {
> +    AdapterInfo->PhyAddress = 0xFF;
> +    AdapterInfo->CableDetect = 1;
> +
> +    if (!PhyDetect (AdapterInfo)) {
> +      CdbPtr->StatFlags |= PXE_STATFLAGS_GET_STATUS_NO_MEDIA;
> +    }
> +  }
> +
> +  return ;
> +}
> +
> +
> +/**
> +  This routine is used to fill media header(s) in transmit packet(s).
> +  Copies the MAC address into the media header whether it is dealing
> +  with fragmented or non-fragmented packets.
> +
> +  @param  CdbPtr               Pointer to the command descriptor block.
> +  @param  AdapterInfo          Pointer to the NIC data structure information
> which
> +                               the UNDI driver is layering on..
> +
> +  @return None
> +
> +**/
> +VOID
> +UNDI_FillHeader (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  PXE_CPB_FILL_HEADER             *Cpb;
> +  PXE_CPB_FILL_HEADER_FRAGMENTED  *Cpbf;
> +  EtherHeader                     *MacHeader;
> +  UINTN                           Index;
> +
> +  if (CdbPtr->CPBsize == PXE_CPBSIZE_NOT_USED) {
> +    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
> +    return ;
> +  }
> +
> +  if ((CdbPtr->OpFlags & PXE_OPFLAGS_FILL_HEADER_FRAGMENTED) != 0) {
> +    Cpbf = (PXE_CPB_FILL_HEADER_FRAGMENTED *) (UINTN) CdbPtr-
> >CPBaddr;
> +
> +    //
> +    // assume 1st fragment is big enough for the mac header
> +    //
> +    if ((Cpbf->FragCnt == 0) || (Cpbf->FragDesc[0].FragLen <
> PXE_MAC_HEADER_LEN_ETHER)) {
> +      //
> +      // no buffers given
> +      //
> +      CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +      CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
> +      return ;
> +    }
> +
> +    MacHeader = (EtherHeader *) (UINTN) Cpbf->FragDesc[0].FragAddr;
> +    //
> +    // we don't swap the protocol bytes
> +    //
> +    MacHeader->type = Cpbf->Protocol;
> +
> +    for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
> +      MacHeader->dest_addr[Index] = Cpbf->DestAddr[Index];
> +      MacHeader->src_addr[Index]  = Cpbf->SrcAddr[Index];
> +    }
> +  } else {
> +    Cpb       = (PXE_CPB_FILL_HEADER *) (UINTN) CdbPtr->CPBaddr;
> +
> +    MacHeader = (EtherHeader *) (UINTN) Cpb->MediaHeader;
> +    //
> +    // we don't swap the protocol bytes
> +    //
> +    MacHeader->type = Cpb->Protocol;
> +
> +    for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
> +      MacHeader->dest_addr[Index] = Cpb->DestAddr[Index];
> +      MacHeader->src_addr[Index]  = Cpb->SrcAddr[Index];
> +    }
> +  }
> +
> +  return ;
> +}
> +
> +
> +/**
> +  This routine is used to place a packet into the transmit queue.  The data
> buffers given to
> +  this command are to be considered locked and the application or network
> driver loses
> +  ownership of these buffers and must not free or relocate them until the
> ownership returns.
> +  When the packets are transmitted, a transmit complete interrupt is
> generated (if interrupts
> +  are disabled, the transmit interrupt status is still set and can be checked
> using the UNDI_Status
> +  command.
> +  Some implementations and adapters support transmitting multiple
> packets with one transmit
> +  command.  If this feature is supported, the transmit CPBs can be linked in
> one transmit
> +  command.
> +  All UNDIs support fragmented frames, now all network devices or
> protocols do.  If a fragmented
> +  frame CPB is given to UNDI and the network device does not support
> fragmented frames
> +  (see !PXE.Implementation flag), the UNDI will have to copy the fragments
> into a local buffer
> +  before transmitting.
> +
> +  @param  CdbPtr               Pointer to the command descriptor block.
> +  @param  AdapterInfo          Pointer to the NIC data structure information
> which
> +                               the UNDI driver is layering on..
> +
> +  @return None
> +
> +**/
> +VOID
> +UNDI_Transmit (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +
> +  if (CdbPtr->CPBsize == PXE_CPBSIZE_NOT_USED) {
> +    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
> +    return ;
> +  }
> +
> +  CdbPtr->StatCode = (PXE_STATCODE) E100bTransmit (AdapterInfo,
> CdbPtr->CPBaddr, CdbPtr->OpFlags);
> +
> +  if (CdbPtr->StatCode != PXE_STATCODE_SUCCESS) {
> +    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +  }
> +
> +  return ;
> +}
> +
> +
> +/**
> +  When the network adapter has received a frame, this command is used to
> copy the frame
> +  into the driver/application storage location.  Once a frame has been
> copied, it is
> +  removed from the receive queue.
> +
> +  @param  CdbPtr               Pointer to the command descriptor block.
> +  @param  AdapterInfo          Pointer to the NIC data structure information
> which
> +                               the UNDI driver is layering on..
> +
> +  @return None
> +
> +**/
> +VOID
> +UNDI_Receive (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +
> +  //
> +  // check if RU has started...
> +  //
> +  if (!AdapterInfo->Receive_Started) {
> +    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +    CdbPtr->StatCode  = PXE_STATCODE_NOT_INITIALIZED;
> +    return ;
> +  }
> +
> +
> +  CdbPtr->StatCode  = (UINT16) E100bReceive (AdapterInfo, CdbPtr-
> >CPBaddr, CdbPtr->DBaddr);
> +  if (CdbPtr->StatCode != PXE_STATCODE_SUCCESS) {
> +    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +
> +  }
> +
> +  return ;
> +}
> +
> +
> +
> +/**
> +  This is the main SW UNDI API entry using the newer nii protocol.
> +  The parameter passed in is a 64 bit flat model virtual
> +  address of the cdb.  We then jump into the common routine for both old
> and
> +  new nii protocol entries.
> +
> +  @param  CdbPtr               Pointer to the command descriptor block.
> +  @param  AdapterInfo          Pointer to the NIC data structure information
> which
> +                               the UNDI driver is layering on..
> +
> +  @return None
> +
> +**/
> +// TODO:    cdb - add argument and description to function comment
> +VOID
> +EFIAPI
> +UNDI_APIEntry_new (
> +  IN  UINT64 cdb
> +  )
> +{
> +  PXE_CDB           *CdbPtr;
> +  NIC_DATA_INSTANCE *AdapterInfo;
> +
> +  if (cdb == (UINT64) 0) {
> +    return ;
> +
> +  }
> +
> +  CdbPtr = (PXE_CDB *) (UINTN) cdb;
> +
> +  if (CdbPtr->IFnum >= (pxe_31->IFcnt | pxe_31->IFcntExt << 8) ) {
> +    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
> +    return ;
> +  }
> +
> +  AdapterInfo               = &(UNDI32DeviceList[CdbPtr->IFnum]->NicInfo);
> +  //
> +  // entering from older entry point
> +  //
> +  AdapterInfo->VersionFlag  = 0x31;
> +  UNDI_APIEntry_Common (cdb);
> +}
> +
> +
> +/**
> +  This is the common routine for both old and new entry point procedures.
> +  The parameter passed in is a 64 bit flat model virtual
> +  address of the cdb.  We then jump into the service routine pointed to by
> the
> +  Api_Table[OpCode].
> +
> +  @param  CdbPtr               Pointer to the command descriptor block.
> +  @param  AdapterInfo          Pointer to the NIC data structure information
> which
> +                               the UNDI driver is layering on..
> +
> +  @return None
> +
> +**/
> +// TODO:    cdb - add argument and description to function comment
> +VOID
> +UNDI_APIEntry_Common (
> +  IN  UINT64 cdb
> +  )
> +{
> +  PXE_CDB           *CdbPtr;
> +  NIC_DATA_INSTANCE *AdapterInfo;
> +  UNDI_CALL_TABLE   *tab_ptr;
> +
> +  CdbPtr = (PXE_CDB *) (UINTN) cdb;
> +
> +  //
> +  // check the OPCODE range
> +  //
> +  if ((CdbPtr->OpCode > PXE_OPCODE_LAST_VALID) ||
> +      (CdbPtr->StatCode != PXE_STATCODE_INITIALIZE) ||
> +      (CdbPtr->StatFlags != PXE_STATFLAGS_INITIALIZE) ||
> +      (CdbPtr->IFnum >= (pxe_31->IFcnt |  pxe_31->IFcntExt << 8))) {
> +    goto badcdb;
> +
> +  }
> +
> +  if (CdbPtr->CPBsize == PXE_CPBSIZE_NOT_USED) {
> +    if (CdbPtr->CPBaddr != PXE_CPBADDR_NOT_USED) {
> +      goto badcdb;
> +    }
> +  } else if (CdbPtr->CPBaddr == PXE_CPBADDR_NOT_USED) {
> +    goto badcdb;
> +  }
> +
> +  if (CdbPtr->DBsize == PXE_DBSIZE_NOT_USED) {
> +    if (CdbPtr->DBaddr != PXE_DBADDR_NOT_USED) {
> +      goto badcdb;
> +    }
> +  } else if (CdbPtr->DBaddr == PXE_DBADDR_NOT_USED) {
> +    goto badcdb;
> +  }
> +
> +  //
> +  // check if cpbsize and dbsize are as needed
> +  // check if opflags are as expected
> +  //
> +  tab_ptr = &api_table[CdbPtr->OpCode];
> +
> +  if (tab_ptr->cpbsize != (UINT16) (DONT_CHECK) && tab_ptr->cpbsize !=
> CdbPtr->CPBsize) {
> +    goto badcdb;
> +  }
> +
> +  if (tab_ptr->dbsize != (UINT16) (DONT_CHECK) && tab_ptr->dbsize !=
> CdbPtr->DBsize) {
> +    goto badcdb;
> +  }
> +
> +  if (tab_ptr->opflags != (UINT16) (DONT_CHECK) && tab_ptr->opflags !=
> CdbPtr->OpFlags) {
> +    goto badcdb;
> +
> +  }
> +
> +  AdapterInfo = &(UNDI32DeviceList[CdbPtr->IFnum]->NicInfo);
> +
> +  //
> +  // check if UNDI_State is valid for this call
> +  //
> +  if (tab_ptr->state != (UINT16) (-1)) {
> +    //
> +    // should atleast be started
> +    //
> +    if (AdapterInfo->State == PXE_STATFLAGS_GET_STATE_STOPPED) {
> +      CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +      CdbPtr->StatCode  = PXE_STATCODE_NOT_STARTED;
> +      return ;
> +    }
> +    //
> +    // check if it should be initialized
> +    //
> +    if (tab_ptr->state == 2) {
> +      if (AdapterInfo->State != PXE_STATFLAGS_GET_STATE_INITIALIZED) {
> +        CdbPtr->StatCode  = PXE_STATCODE_NOT_INITIALIZED;
> +        CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +        return ;
> +      }
> +    }
> +  }
> +  //
> +  // set the return variable for success case here
> +  //
> +  CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
> +  CdbPtr->StatCode  = PXE_STATCODE_SUCCESS;
> +
> +  tab_ptr->api_ptr (CdbPtr, AdapterInfo);
> +  return ;
> +  //
> +  // %% AVL - check for command linking
> +  //
> +badcdb:
> +  CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
> +  CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
> +  return ;
> +}
> +
> +
> +/**
> +  When called with a null NicPtr, this routine decrements the number of
> NICs
> +  this UNDI is supporting and removes the NIC_DATA_POINTER from the
> array.
> +  Otherwise, it increments the number of NICs this UNDI is supported and
> +  updates the pxe.Fudge to ensure a proper check sum results.
> +
> +  @param  NicPtr               Pointer to the NIC data structure.
> +
> +  @return None
> +
> +**/
> +VOID
> +PxeUpdate (
> +  IN  NIC_DATA_INSTANCE *NicPtr,
> +  IN PXE_SW_UNDI        *PxePtr
> +  )
> +{
> +  UINT16 NicNum;
> +  NicNum = (PxePtr->IFcnt | PxePtr->IFcntExt << 8);
> +
> +  if (NicPtr == NULL) {
> +    if (NicNum > 0) {
> +      //
> +      // number of NICs this undi supports
> +      //
> +      NicNum --;
> +    }
> +    goto done;
> +  }
> +
> +  //
> +  // number of NICs this undi supports
> +  //
> +  NicNum++;
> +
> +done:
> +  PxePtr->IFcnt = (UINT8)(NicNum & 0xFF);
> +  PxePtr->IFcntExt = (UINT8) ((NicNum & 0xFF00) >> 8);
> +  PxePtr->Fudge = (UINT8) (PxePtr->Fudge - CalculateSum8 ((VOID *) PxePtr,
> PxePtr->Len));
> +  return ;
> +}
> +
> +
> +/**
> +  Initialize the !PXE structure
> +
> +  @param  PxePtr               Pointer to SW_UNDI data structure.
> +
> +  @retval EFI_SUCCESS          This driver is added to Controller.
> +  @retval other                This driver does not support this device.
> +
> +**/
> +VOID
> +PxeStructInit (
> +  IN PXE_SW_UNDI *PxePtr
> +  )
> +{
> +  //
> +  // Initialize the !PXE structure
> +  //
> +  PxePtr->Signature = PXE_ROMID_SIGNATURE;
> +  PxePtr->Len       = (UINT8) sizeof (PXE_SW_UNDI);
> +  //
> +  // cksum
> +  //
> +  PxePtr->Fudge     = 0;
> +  //
> +  // number of NICs this undi supports
> +  //
> +  PxePtr->IFcnt = 0;
> +  PxePtr->IFcntExt = 0;
> +  PxePtr->Rev       = PXE_ROMID_REV;
> +  PxePtr->MajorVer  = PXE_ROMID_MAJORVER;
> +  PxePtr->MinorVer  = PXE_ROMID_MINORVER;
> +  PxePtr->reserved1 = 0;
> +
> +  PxePtr->Implementation = PXE_ROMID_IMP_SW_VIRT_ADDR |
> +    PXE_ROMID_IMP_FRAG_SUPPORTED |
> +    PXE_ROMID_IMP_CMD_LINK_SUPPORTED |
> +    PXE_ROMID_IMP_NVDATA_READ_ONLY |
> +    PXE_ROMID_IMP_STATION_ADDR_SETTABLE |
> +    PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED |
> +    PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED |
> +    PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED |
> +    PXE_ROMID_IMP_FILTERED_MULTICAST_RX_SUPPORTED |
> +    PXE_ROMID_IMP_SOFTWARE_INT_SUPPORTED |
> +    PXE_ROMID_IMP_PACKET_RX_INT_SUPPORTED;
> +
> +  PxePtr->EntryPoint  = (UINT64) (UINTN) UNDI_APIEntry_new;
> +  PxePtr->MinorVer    = PXE_ROMID_MINORVER_31;
> +
> +  PxePtr->reserved2[0]  = 0;
> +  PxePtr->reserved2[1]  = 0;
> +  PxePtr->reserved2[2]  = 0;
> +  PxePtr->BusCnt        = 1;
> +  PxePtr->BusType[0]    = PXE_BUSTYPE_PCI;
> +
> +  PxePtr->Fudge         = (UINT8) (PxePtr->Fudge - CalculateSum8 ((VOID *)
> PxePtr, PxePtr->Len));
> +}
> +
> diff --git a/Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c
> b/Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c
> new file mode 100644
> index 0000000000..199f5430ad
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c
> @@ -0,0 +1,3541 @@
> +/** @file
> +  Provides basic function upon network adapter card.
> +
> +Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "Undi32.h"
> +
> +UINT8 basic_config_cmd[22] = {
> +                    22,        0x08,
> +                    0,           0,
> +                    0, (UINT8)0x80,
> +                    0x32,        0x03,
> +                    1,            0,
> +                    0x2E,           0,
> +                    0x60,           0,
> +                    (UINT8)0xf2,        0x48,
> +                    0,        0x40,
> +                    (UINT8)0xf2, (UINT8)0x80, // 0x40=Force full-duplex
> +                    0x3f,       0x05,
> +};
> +
> +//
> +// How to wait for the command unit to accept a command.
> +// Typically this takes 0 ticks.
> +//
> +#define wait_for_cmd_done(cmd_ioaddr) \
> +{                      \
> +  INT16 wait_count = 2000;              \
> +  while ((InByte (AdapterInfo, cmd_ioaddr) != 0) && --wait_count >= 0)  \
> +    DelayIt (AdapterInfo, 10);  \
> +  if (wait_count == 0) \
> +    DelayIt (AdapterInfo, 50);    \
> +}
> +
> +
> +/**
> +  This function calls the MemIo callback to read a byte from the device's
> +  address space
> +  Since UNDI3.0 uses the TmpMemIo function (instead of the callback
> routine)
> +  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't
> have
> +  to make undi3.0 a special case
> +
> +  @param  Port                            Which port to read from.
> +
> +  @retval Results                         The data read from the port.
> +
> +**/
> +// TODO:    AdapterInfo - add argument and description to function
> comment
> +UINT8
> +InByte (
> +  IN NIC_DATA_INSTANCE *AdapterInfo,
> +  IN UINT32            Port
> +  )
> +{
> +  UINT8 Results;
> +
> +  (*AdapterInfo->Mem_Io) (
> +    AdapterInfo->Unique_ID,
> +    PXE_MEM_READ,
> +    1,
> +    (UINT64)Port,
> +    (UINT64) (UINTN) &Results
> +    );
> +  return Results;
> +}
> +
> +
> +/**
> +  This function calls the MemIo callback to read a word from the device's
> +  address space
> +  Since UNDI3.0 uses the TmpMemIo function (instead of the callback
> routine)
> +  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't
> have
> +  to make undi3.0 a special case
> +
> +  @param  Port                            Which port to read from.
> +
> +  @retval Results                         The data read from the port.
> +
> +**/
> +// TODO:    AdapterInfo - add argument and description to function
> comment
> +UINT16
> +InWord (
> +  IN NIC_DATA_INSTANCE *AdapterInfo,
> +  IN UINT32            Port
> +  )
> +{
> +  UINT16  Results;
> +
> +  (*AdapterInfo->Mem_Io) (
> +    AdapterInfo->Unique_ID,
> +    PXE_MEM_READ,
> +    2,
> +    (UINT64)Port,
> +    (UINT64)(UINTN)&Results
> +    );
> +  return Results;
> +}
> +
> +
> +/**
> +  This function calls the MemIo callback to read a dword from the device's
> +  address space
> +  Since UNDI3.0 uses the TmpMemIo function (instead of the callback
> routine)
> +  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't
> have
> +  to make undi3.0 a special case
> +
> +  @param  Port                            Which port to read from.
> +
> +  @retval Results                         The data read from the port.
> +
> +**/
> +// TODO:    AdapterInfo - add argument and description to function
> comment
> +UINT32
> +InLong (
> +  IN NIC_DATA_INSTANCE *AdapterInfo,
> +  IN UINT32            Port
> +  )
> +{
> +  UINT32  Results;
> +
> +  (*AdapterInfo->Mem_Io) (
> +    AdapterInfo->Unique_ID,
> +    PXE_MEM_READ,
> +    4,
> +    (UINT64)Port,
> +    (UINT64)(UINTN)&Results
> +    );
> +  return Results;
> +}
> +
> +
> +/**
> +  This function calls the MemIo callback to write a byte from the device's
> +  address space
> +  Since UNDI3.0 uses the TmpMemIo function (instead of the callback
> routine)
> +  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't
> have
> +  to make undi3.0 a special case
> +
> +  @param  Data                            Data to write to Port.
> +  @param  Port                            Which port to write to.
> +
> +  @return none
> +
> +**/
> +// TODO:    AdapterInfo - add argument and description to function
> comment
> +VOID
> +OutByte (
> +  IN NIC_DATA_INSTANCE *AdapterInfo,
> +  IN UINT8             Data,
> +  IN UINT32            Port
> +  )
> +{
> +  UINT8 Val;
> +
> +  Val = Data;
> +  (*AdapterInfo->Mem_Io) (
> +     AdapterInfo->Unique_ID,
> +     PXE_MEM_WRITE,
> +     1,
> +     (UINT64)Port,
> +     (UINT64)(UINTN)(UINTN)&Val
> +     );
> +  return ;
> +}
> +
> +
> +/**
> +  This function calls the MemIo callback to write a word from the device's
> +  address space
> +  Since UNDI3.0 uses the TmpMemIo function (instead of the callback
> routine)
> +  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't
> have
> +  to make undi3.0 a special case
> +
> +  @param  Data                            Data to write to Port.
> +  @param  Port                            Which port to write to.
> +
> +  @return none
> +
> +**/
> +// TODO:    AdapterInfo - add argument and description to function
> comment
> +VOID
> +OutWord (
> +  IN NIC_DATA_INSTANCE *AdapterInfo,
> +  IN UINT16            Data,
> +  IN UINT32            Port
> +  )
> +{
> +  UINT16  Val;
> +
> +  Val = Data;
> +  (*AdapterInfo->Mem_Io) (
> +     AdapterInfo->Unique_ID,
> +     PXE_MEM_WRITE,
> +     2,
> +     (UINT64)Port,
> +     (UINT64)(UINTN)&Val
> +     );
> +  return ;
> +}
> +
> +
> +/**
> +  This function calls the MemIo callback to write a dword from the device's
> +  address space
> +  Since UNDI3.0 uses the TmpMemIo function (instead of the callback
> routine)
> +  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't
> have
> +  to make undi3.0 a special case
> +
> +  @param  Data                            Data to write to Port.
> +  @param  Port                            Which port to write to.
> +
> +  @return none
> +
> +**/
> +// TODO:    AdapterInfo - add argument and description to function
> comment
> +VOID
> +OutLong (
> +  IN NIC_DATA_INSTANCE *AdapterInfo,
> +  IN UINT32            Data,
> +  IN UINT32            Port
> +  )
> +{
> +  UINT32  Val;
> +
> +  Val = Data;
> +  (*AdapterInfo->Mem_Io) (
> +     AdapterInfo->Unique_ID,
> +     PXE_MEM_WRITE,
> +     4,
> +     (UINT64)Port,
> +     (UINT64)(UINTN)&Val
> +     );
> +  return ;
> +}
> +
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  AdapterInfo                     TODO: add argument description
> +  @param  MemAddr                         TODO: add argument description
> +  @param  Size                            TODO: add argument description
> +  @param  Direction                       TODO: add argument description
> +  @param  MappedAddr                      TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +UINTN
> +MapIt (
> +  IN NIC_DATA_INSTANCE *AdapterInfo,
> +  IN UINT64            MemAddr,
> +  IN UINT32            Size,
> +  IN UINT32            Direction,
> +  OUT UINT64           MappedAddr
> +  )
> +{
> +  UINT64  *PhyAddr;
> +
> +  PhyAddr = (UINT64 *) (UINTN) MappedAddr;
> +  //
> +  // mapping is different for theold and new NII protocols
> +  //
> +  if (AdapterInfo->VersionFlag == 0x30) {
> +    if (AdapterInfo->Virt2Phys_30 == (VOID *) NULL) {
> +      *PhyAddr = (UINT64) AdapterInfo->MemoryPtr;
> +    } else {
> +      (*AdapterInfo->Virt2Phys_30) (MemAddr, (UINT64) (UINTN) PhyAddr);
> +    }
> +
> +    if (*PhyAddr > FOUR_GIGABYTE) {
> +      return PXE_STATCODE_INVALID_PARAMETER;
> +    }
> +  } else {
> +    if (AdapterInfo->Map_Mem == (VOID *) NULL) {
> +      //
> +      // this UNDI cannot handle addresses beyond 4 GB without a map
> routine
> +      //
> +      if (MemAddr > FOUR_GIGABYTE) {
> +        return PXE_STATCODE_INVALID_PARAMETER;
> +      } else {
> +        *PhyAddr = MemAddr;
> +      }
> +    } else {
> +      (*AdapterInfo->Map_Mem) (
> +        AdapterInfo->Unique_ID,
> +        MemAddr,
> +        Size,
> +        Direction,
> +        MappedAddr
> +        );
> +    }
> +  }
> +
> +  return PXE_STATCODE_SUCCESS;
> +}
> +
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  AdapterInfo                     TODO: add argument description
> +  @param  MemAddr                         TODO: add argument description
> +  @param  Size                            TODO: add argument description
> +  @param  Direction                       TODO: add argument description
> +  @param  MappedAddr                      TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +VOID
> +UnMapIt (
> +  IN NIC_DATA_INSTANCE *AdapterInfo,
> +  IN UINT64            MemAddr,
> +  IN UINT32            Size,
> +  IN UINT32            Direction,
> +  IN UINT64            MappedAddr
> +  )
> +{
> +  if (AdapterInfo->VersionFlag > 0x30) {
> +    //
> +    // no mapping service
> +    //
> +    if (AdapterInfo->UnMap_Mem != (VOID *) NULL) {
> +      (*AdapterInfo->UnMap_Mem) (
> +        AdapterInfo->Unique_ID,
> +        MemAddr,
> +        Size,
> +        Direction,
> +        MappedAddr
> +        );
> +
> +    }
> +  }
> +
> +  return ;
> +}
> +
> +
> +/**
> +
> +  @param  AdapterInfo                     Pointer to the NIC data structure
> +                                          information which the UNDI driver is
> +                                          layering on..
> +
> +
> +**/
> +// TODO:    MicroSeconds - add argument and description to function
> comment
> +VOID
> +DelayIt (
> +  IN NIC_DATA_INSTANCE *AdapterInfo,
> +  UINT16               MicroSeconds
> +  )
> +{
> +  if (AdapterInfo->VersionFlag == 0x30) {
> +    (*AdapterInfo->Delay_30) (MicroSeconds);
> +  } else {
> +    (*AdapterInfo->Delay) (AdapterInfo->Unique_ID, MicroSeconds);
> +  }
> +}
> +
> +
> +/**
> +
> +  @param  AdapterInfo                     Pointer to the NIC data structure
> +                                          information which the UNDI driver is
> +                                          layering on..
> +
> +
> +**/
> +// TODO:    flag - add argument and description to function comment
> +VOID
> +BlockIt (
> +  IN NIC_DATA_INSTANCE *AdapterInfo,
> +  UINT32               flag
> +  )
> +{
> +  if (AdapterInfo->VersionFlag == 0x30) {
> +    (*AdapterInfo->Block_30) (flag);
> +  } else {
> +    (*AdapterInfo->Block) (AdapterInfo->Unique_ID, flag);
> +  }
> +}
> +
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  AdapterInfo                     TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +UINT8
> +Load_Base_Regs (
> +  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  //
> +  // we will use the linear (flat) memory model and fill our base registers
> +  // with 0's so that the entire physical address is our offset
> +  //
> +  //
> +  // we reset the statistics totals here because this is where we are loading
> stats addr
> +  //
> +  AdapterInfo->RxTotals = 0;
> +  AdapterInfo->TxTotals = 0;
> +
> +  //
> +  // Load the statistics block address.
> +  //
> +  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
> +  OutLong (AdapterInfo, (UINT32) AdapterInfo->stat_phy_addr,
> AdapterInfo->ioaddr + SCBPointer);
> +  OutByte (AdapterInfo, CU_STATSADDR, AdapterInfo->ioaddr + SCBCmd);
> +  AdapterInfo->statistics->done_marker = 0;
> +
> +  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
> +  OutLong (AdapterInfo, 0, AdapterInfo->ioaddr + SCBPointer);
> +  OutByte (AdapterInfo, RX_ADDR_LOAD, AdapterInfo->ioaddr + SCBCmd);
> +
> +  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
> +  OutLong (AdapterInfo, 0, AdapterInfo->ioaddr + SCBPointer);
> +  OutByte (AdapterInfo, CU_CMD_BASE, AdapterInfo->ioaddr + SCBCmd);
> +
> +  return 0;
> +}
> +
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  AdapterInfo                     TODO: add argument description
> +  @param  cmd_ptr                         TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +UINT8
> +IssueCB (
> +  NIC_DATA_INSTANCE *AdapterInfo,
> +  TxCB              *cmd_ptr
> +  )
> +{
> +  UINT16  status;
> +
> +  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
> +
> +  //
> +  // read the CU status, if it is idle, write the address of cb_ptr
> +  // in the scbpointer and issue a cu_start,
> +  // if it is suspended, remove the suspend bit in the previous command
> +  // block and issue a resume
> +  //
> +  // Ensure that the CU Active Status bit is not on from previous CBs.
> +  //
> +  status = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBStatus);
> +
> +  //
> +  // Skip acknowledging the interrupt if it is not already set
> +  //
> +
> +  //
> +  // ack only the cna the integer
> +  //
> +  if ((status & SCB_STATUS_CNA) != 0) {
> +    OutWord (AdapterInfo, SCB_STATUS_CNA, AdapterInfo->ioaddr +
> SCBStatus);
> +
> +  }
> +
> +  if ((status & SCB_STATUS_CU_MASK) == SCB_STATUS_CU_IDLE) {
> +    //
> +    // give a cu_start
> +    //
> +    OutLong (AdapterInfo, cmd_ptr->PhysTCBAddress, AdapterInfo->ioaddr +
> SCBPointer);
> +    OutByte (AdapterInfo, CU_START, AdapterInfo->ioaddr + SCBCmd);
> +  } else {
> +    //
> +    // either active or suspended, give a resume
> +    //
> +
> +    cmd_ptr->PrevTCBVirtualLinkPtr->cb_header.command &=
> ~(CmdSuspend | CmdIntr);
> +    OutByte (AdapterInfo, CU_RESUME, AdapterInfo->ioaddr + SCBCmd);
> +  }
> +
> +  return 0;
> +}
> +
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  AdapterInfo                     TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +UINT8
> +Configure (
> +  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  //
> +  // all command blocks are of TxCB format
> +  //
> +  TxCB  *cmd_ptr;
> +  UINT8 *data_ptr;
> +  volatile INT16 Index;
> +  UINT8 my_filter;
> +
> +  cmd_ptr   = GetFreeCB (AdapterInfo);
> +  ASSERT (cmd_ptr != NULL);
> +  data_ptr  = (UINT8 *) cmd_ptr + sizeof (struct CB_Header);
> +
> +  //
> +  // start the config data right after the command header
> +  //
> +  for (Index = 0; Index < sizeof (basic_config_cmd); Index++) {
> +    data_ptr[Index] = basic_config_cmd[Index];
> +  }
> +
> +  my_filter = (UINT8) ((AdapterInfo->Rx_Filter &
> PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS) ? 1 : 0);
> +  my_filter = (UINT8) (my_filter | ((AdapterInfo->Rx_Filter &
> PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST) ? 0 : 2));
> +
> +  data_ptr[15]  = (UINT8) (data_ptr[15] | my_filter);
> +  data_ptr[19]  = (UINT8) (AdapterInfo->Duplex ? 0xC0 : 0x80);
> +  data_ptr[21]  = (UINT8) ((AdapterInfo->Rx_Filter &
> PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST) ? 0x0D : 0x05);
> +
> +  //
> +  // check if we have to use the AUI port instead
> +  //
> +  if ((AdapterInfo->PhyRecord[0] & 0x8000) != 0) {
> +    data_ptr[15] |= 0x80;
> +    data_ptr[8] = 0;
> +  }
> +
> +  BlockIt (AdapterInfo, TRUE);
> +  cmd_ptr->cb_header.command = CmdSuspend | CmdConfigure;
> +
> +  IssueCB (AdapterInfo, cmd_ptr);
> +  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
> +
> +  BlockIt (AdapterInfo, FALSE);
> +
> +  CommandWaitForCompletion (cmd_ptr, AdapterInfo);
> +
> +  //
> +  // restore the cb values for tx
> +  //
> +  cmd_ptr->PhysTBDArrayAddres = cmd_ptr->PhysArrayAddr;
> +  cmd_ptr->ByteCount = cmd_ptr->Threshold = cmd_ptr->TBDCount = 0;
> +  //
> +  // fields beyond the immediatedata are assumed to be safe
> +  // add the CB to the free list again
> +  //
> +  SetFreeCB (AdapterInfo, cmd_ptr);
> +  return 0;
> +}
> +
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  AdapterInfo                     TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +UINT8
> +E100bSetupIAAddr (
> +  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  //
> +  // all command blocks are of TxCB format
> +  //
> +  TxCB    *cmd_ptr;
> +  UINT16  *data_ptr;
> +  UINT16  *eaddrs;
> +
> +  eaddrs    = (UINT16 *) AdapterInfo->CurrentNodeAddress;
> +
> +  cmd_ptr   = GetFreeCB (AdapterInfo);
> +  ASSERT (cmd_ptr != NULL);
> +  data_ptr  = (UINT16 *) ((UINT8 *) cmd_ptr +sizeof (struct CB_Header));
> +
> +  //
> +  // AVOID a bug (?!) here by marking the command already completed.
> +  //
> +  cmd_ptr->cb_header.command  = (CmdSuspend | CmdIASetup);
> +  cmd_ptr->cb_header.status   = 0;
> +  data_ptr[0]                 = eaddrs[0];
> +  data_ptr[1]                 = eaddrs[1];
> +  data_ptr[2]                 = eaddrs[2];
> +
> +  BlockIt (AdapterInfo, TRUE);
> +  IssueCB (AdapterInfo, cmd_ptr);
> +  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
> +  BlockIt (AdapterInfo, FALSE);
> +
> +  CommandWaitForCompletion (cmd_ptr, AdapterInfo);
> +
> +  //
> +  // restore the cb values for tx
> +  //
> +  cmd_ptr->PhysTBDArrayAddres = cmd_ptr->PhysArrayAddr;
> +  cmd_ptr->ByteCount = cmd_ptr->Threshold = cmd_ptr->TBDCount = 0;
> +  //
> +  // fields beyond the immediatedata are assumed to be safe
> +  // add the CB to the free list again
> +  //
> +  SetFreeCB (AdapterInfo, cmd_ptr);
> +  return 0;
> +}
> +
> +
> +/**
> +  Instructs the NIC to stop receiving packets.
> +
> +  @param  AdapterInfo                     Pointer to the NIC data structure
> +                                          information which the UNDI driver is
> +                                          layering on..
> +
> +
> +**/
> +VOID
> +StopRU (
> +  IN NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  if (AdapterInfo->Receive_Started) {
> +
> +    //
> +    // Todo: verify that we must wait for previous command completion.
> +    //
> +    wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
> +
> +    //
> +    // Disable interrupts, and stop the chip's Rx process.
> +    //
> +    OutWord (AdapterInfo, INT_MASK, AdapterInfo->ioaddr + SCBCmd);
> +    OutWord (AdapterInfo, INT_MASK | RX_ABORT, AdapterInfo->ioaddr +
> SCBCmd);
> +
> +    AdapterInfo->Receive_Started = FALSE;
> +  }
> +
> +  return ;
> +}
> +
> +
> +/**
> +  Instructs the NIC to start receiving packets.
> +
> +  @param  AdapterInfo                     Pointer to the NIC data structure
> +                                          information which the UNDI driver is
> +                                          layering on..
> +
> +  @retval 0                               Successful
> +  @retval -1                              Already Started
> +
> +**/
> +INT8
> +StartRU (
> +  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +
> +  if (AdapterInfo->Receive_Started) {
> +    //
> +    // already started
> +    //
> +    return -1;
> +  }
> +
> +  AdapterInfo->cur_rx_ind = 0;
> +  AdapterInfo->Int_Status = 0;
> +
> +  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
> +
> +  OutLong (AdapterInfo, (UINT32) AdapterInfo->rx_phy_addr, AdapterInfo-
> >ioaddr + SCBPointer);
> +  OutByte (AdapterInfo, RX_START, AdapterInfo->ioaddr + SCBCmd);
> +
> +  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
> +
> +  AdapterInfo->Receive_Started = TRUE;
> +  return 0;
> +}
> +
> +
> +/**
> +  Configures the chip.  This routine expects the NIC_DATA_INSTANCE
> structure to be filled in.
> +
> +  @param  AdapterInfo                     Pointer to the NIC data structure
> +                                          information which the UNDI driver is
> +                                          layering on..
> +
> +  @retval 0                               Successful
> +  @retval PXE_STATCODE_NOT_ENOUGH_MEMORY  Insufficient length of
> locked memory
> +  @retval other                           Failure initializing chip
> +
> +**/
> +UINTN
> +E100bInit (
> +  IN NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  PCI_CONFIG_HEADER *CfgHdr;
> +  UINTN             stat;
> +  UINTN             rx_size;
> +  UINTN             tx_size;
> +
> +  if (AdapterInfo->MemoryLength < MEMORY_NEEDED) {
> +    return PXE_STATCODE_NOT_ENOUGH_MEMORY;
> +  }
> +
> +  stat = MapIt (
> +          AdapterInfo,
> +          AdapterInfo->MemoryPtr,
> +          AdapterInfo->MemoryLength,
> +          TO_AND_FROM_DEVICE,
> +          (UINT64)(UINTN) &AdapterInfo->Mapped_MemoryPtr
> +          );
> +
> +  if (stat != 0) {
> +    return stat;
> +  }
> +
> +  CfgHdr = (PCI_CONFIG_HEADER *) &(AdapterInfo->Config[0]);
> +
> +  //
> +  // fill in the ioaddr, int... from the config space
> +  //
> +  AdapterInfo->int_num = CfgHdr->int_line;
> +
> +  //
> +  // we don't need to validate integer number, what if they don't want to
> assign one?
> +  // if (AdapterInfo->int_num == 0 || AdapterInfo->int_num == 0xff)
> +  // return PXE_STATCODE_DEVICE_FAILURE;
> +  //
> +  AdapterInfo->ioaddr       = 0;
> +  AdapterInfo->VendorID     = CfgHdr->VendorID;
> +  AdapterInfo->DeviceID     = CfgHdr->DeviceID;
> +  AdapterInfo->RevID        = CfgHdr->RevID;
> +  AdapterInfo->SubVendorID  = CfgHdr->SubVendorID;
> +  AdapterInfo->SubSystemID  = CfgHdr->SubSystemID;
> +  AdapterInfo->flash_addr   = 0;
> +
> +  //
> +  // Read the station address EEPROM before doing the reset.
> +  // Perhaps this should even be done before accepting the device,
> +  // then we wouldn't have a device name with which to report the error.
> +  //
> +  if (E100bReadEepromAndStationAddress (AdapterInfo) != 0) {
> +    return PXE_STATCODE_DEVICE_FAILURE;
> +
> +  }
> +  //
> +  // ## calculate the buffer #s depending on memory given
> +  // ## calculate the rx and tx ring pointers
> +  //
> +
> +  AdapterInfo->TxBufCnt       = TX_BUFFER_COUNT;
> +  AdapterInfo->RxBufCnt       = RX_BUFFER_COUNT;
> +  rx_size                     = (AdapterInfo->RxBufCnt * sizeof (RxFD));
> +  tx_size                     = (AdapterInfo->TxBufCnt * sizeof (TxCB));
> +  AdapterInfo->rx_ring        = (RxFD *) (UINTN) (AdapterInfo->MemoryPtr);
> +  AdapterInfo->tx_ring        = (TxCB *) (UINTN) (AdapterInfo->MemoryPtr +
> rx_size);
> +  AdapterInfo->statistics     = (struct speedo_stats *) (UINTN) (AdapterInfo-
> >MemoryPtr + rx_size + tx_size);
> +
> +  AdapterInfo->rx_phy_addr    = AdapterInfo->Mapped_MemoryPtr;
> +  AdapterInfo->tx_phy_addr    = AdapterInfo->Mapped_MemoryPtr +
> rx_size;
> +  AdapterInfo->stat_phy_addr  = AdapterInfo->tx_phy_addr + tx_size;
> +
> +  //
> +  // auto detect.
> +  //
> +  AdapterInfo->PhyAddress     = 0xFF;
> +  AdapterInfo->Rx_Filter            =
> PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
> +  AdapterInfo->Receive_Started      = FALSE;
> +  AdapterInfo->mcast_list.list_len  = 0;
> +  return InitializeChip (AdapterInfo);
> +}
> +
> +
> +/**
> +  Sets the interrupt state for the NIC.
> +
> +  @param  AdapterInfo                     Pointer to the NIC data structure
> +                                          information which the UNDI driver is
> +                                          layering on..
> +
> +  @retval 0                               Successful
> +
> +**/
> +UINT8
> +E100bSetInterruptState (
> +  IN NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  //
> +  // don't set receive interrupt if receiver is disabled...
> +  //
> +  UINT16  cmd_word;
> +
> +  if ((AdapterInfo->int_mask & PXE_OPFLAGS_INTERRUPT_RECEIVE) != 0) {
> +    cmd_word = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBCmd);
> +    cmd_word &= ~INT_MASK;
> +    OutWord (AdapterInfo, cmd_word, AdapterInfo->ioaddr + SCBCmd);
> +  } else {
> +    //
> +    // disable ints, should not be given for SW Int.
> +    //
> +    OutWord (AdapterInfo, INT_MASK, AdapterInfo->ioaddr + SCBCmd);
> +  }
> +
> +  if ((AdapterInfo->int_mask & PXE_OPFLAGS_INTERRUPT_SOFTWARE) != 0)
> {
> +    //
> +    // reset the bit in our mask, it is only one time!!
> +    //
> +    AdapterInfo->int_mask &= ~(PXE_OPFLAGS_INTERRUPT_SOFTWARE);
> +    cmd_word = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBCmd);
> +    cmd_word |= DRVR_INT;
> +    OutWord (AdapterInfo, cmd_word, AdapterInfo->ioaddr + SCBCmd);
> +  }
> +
> +  return 0;
> +}
> +//
> +// we are not going to disable broadcast for the WOL's sake!
> +//
> +
> +/**
> +  Instructs the NIC to start receiving packets.
> +
> +  @param  AdapterInfo                     Pointer to the NIC data structure
> +                                          information which the UNDI driver is
> +                                          layering on.. new_filter
> +                                              - cpb                             -
> +                                          cpbsize                         -
> +
> +  @retval 0                               Successful
> +  @retval -1                              Already Started
> +
> +**/
> +UINTN
> +E100bSetfilter (
> +  NIC_DATA_INSTANCE *AdapterInfo,
> +  UINT16            new_filter,
> +  UINT64            cpb,
> +  UINT32            cpbsize
> +  )
> +{
> +  PXE_CPB_RECEIVE_FILTERS *mc_list = (PXE_CPB_RECEIVE_FILTERS *)
> (UINTN)cpb;
> +  UINT16                  cfg_flt;
> +  UINT16                  old_filter;
> +  UINT16                  Index;
> +  UINT16                  Index2;
> +  UINT16                  mc_count;
> +  TxCB                    *cmd_ptr;
> +  struct MC_CB_STRUCT     *data_ptr;
> +  UINT16                  mc_byte_cnt;
> +
> +  old_filter  = AdapterInfo->Rx_Filter;
> +
> +  //
> +  // only these bits need a change in the configuration
> +  // actually change in bcast requires configure but we ignore that change
> +  //
> +  cfg_flt = PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS |
> +            PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;
> +
> +  if ((old_filter & cfg_flt) != (new_filter & cfg_flt)) {
> +    XmitWaitForCompletion (AdapterInfo);
> +
> +    if (AdapterInfo->Receive_Started) {
> +      StopRU (AdapterInfo);
> +    }
> +
> +    AdapterInfo->Rx_Filter = (UINT8) (new_filter |
> PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST);
> +    Configure (AdapterInfo);
> +  }
> +
> +  //
> +  // check if mcast setting changed
> +  //
> +  if ( ((new_filter &
> PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) !=
> +       (old_filter & PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) )
> ||
> +       (mc_list != NULL) ) {
> +
> +
> +    if (mc_list != NULL) {
> +      mc_count = AdapterInfo->mcast_list.list_len = (UINT16) (cpbsize /
> PXE_MAC_LENGTH);
> +
> +      for (Index = 0; (Index < mc_count && Index <
> MAX_MCAST_ADDRESS_CNT); Index++) {
> +        for (Index2 = 0; Index2 < PXE_MAC_LENGTH; Index2++) {
> +          AdapterInfo->mcast_list.mc_list[Index][Index2] = mc_list-
> >MCastList[Index][Index2];
> +        }
> +      }
> +    }
> +
> +    //
> +    // are we setting the list or resetting??
> +    //
> +    if ((new_filter &
> PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) != 0) {
> +      //
> +      // we are setting a new list!
> +      //
> +      mc_count = AdapterInfo->mcast_list.list_len;
> +      //
> +      // count should be the actual # of bytes in the list
> +      // so multiply this with 6
> +      //
> +      mc_byte_cnt = (UINT16) ((mc_count << 2) + (mc_count << 1));
> +      AdapterInfo->Rx_Filter |=
> PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST;
> +    } else {
> +      //
> +      // disabling the list in the NIC.
> +      //
> +      mc_byte_cnt = mc_count = 0;
> +      AdapterInfo->Rx_Filter &=
> (~PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST);
> +    }
> +
> +    //
> +    // before issuing any new command!
> +    //
> +    XmitWaitForCompletion (AdapterInfo);
> +
> +    if (AdapterInfo->Receive_Started) {
> +      StopRU (AdapterInfo);
> +
> +    }
> +
> +    cmd_ptr = GetFreeCB (AdapterInfo);
> +    if (cmd_ptr == NULL) {
> +      return PXE_STATCODE_QUEUE_FULL;
> +    }
> +    //
> +    // fill the command structure and issue
> +    //
> +    data_ptr = (struct MC_CB_STRUCT *) (&cmd_ptr->PhysTBDArrayAddres);
> +    //
> +    // first 2 bytes are the count;
> +    //
> +    data_ptr->count = mc_byte_cnt;
> +    for (Index = 0; Index < mc_count; Index++) {
> +      for (Index2 = 0; Index2 < PXE_HWADDR_LEN_ETHER; Index2++) {
> +        data_ptr->m_list[Index][Index2] = AdapterInfo-
> >mcast_list.mc_list[Index][Index2];
> +      }
> +    }
> +
> +    cmd_ptr->cb_header.command  = CmdSuspend | CmdMulticastList;
> +    cmd_ptr->cb_header.status   = 0;
> +
> +    BlockIt (AdapterInfo, TRUE);
> +    IssueCB (AdapterInfo, cmd_ptr);
> +    wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
> +
> +    BlockIt (AdapterInfo, FALSE);
> +
> +    CommandWaitForCompletion (cmd_ptr, AdapterInfo);
> +
> +    cmd_ptr->PhysTBDArrayAddres = cmd_ptr->PhysArrayAddr;
> +    cmd_ptr->ByteCount = cmd_ptr->Threshold = cmd_ptr->TBDCount = 0;
> +    //
> +    // fields beyond the immediatedata are assumed to be safe
> +    // add the CB to the free list again
> +    //
> +    SetFreeCB (AdapterInfo, cmd_ptr);
> +  }
> +
> +  if (new_filter != 0) {
> +    //
> +    // enable unicast and start the RU
> +    //
> +    AdapterInfo->Rx_Filter = (UINT8) (AdapterInfo->Rx_Filter | (new_filter |
> PXE_OPFLAGS_RECEIVE_FILTER_UNICAST));
> +    StartRU (AdapterInfo);
> +  } else {
> +    //
> +    // may be disabling everything!
> +    //
> +    if (AdapterInfo->Receive_Started) {
> +      StopRU (AdapterInfo);
> +    }
> +
> +    AdapterInfo->Rx_Filter |= (~PXE_OPFLAGS_RECEIVE_FILTER_UNICAST);
> +  }
> +
> +  return 0;
> +}
> +
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  AdapterInfo                     TODO: add argument description
> +  @param  cpb                             TODO: add argument description
> +  @param  opflags                         TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +UINTN
> +E100bTransmit (
> +  NIC_DATA_INSTANCE *AdapterInfo,
> +  UINT64            cpb,
> +  UINT16            opflags
> +  )
> +{
> +  PXE_CPB_TRANSMIT_FRAGMENTS  *tx_ptr_f;
> +  PXE_CPB_TRANSMIT            *tx_ptr_1;
> +  TxCB                        *tcb_ptr;
> +  UINT64                      Tmp_ptr;
> +  UINTN                       stat;
> +  INT32                       Index;
> +  UINT16                      wait_sec;
> +
> +  tx_ptr_1  = (PXE_CPB_TRANSMIT *) (UINTN) cpb;
> +  tx_ptr_f  = (PXE_CPB_TRANSMIT_FRAGMENTS *) (UINTN) cpb;
> +  Tmp_ptr = 0;
> +
> +  //
> +  // stop reentrancy here
> +  //
> +  if (AdapterInfo->in_transmit) {
> +    return PXE_STATCODE_BUSY;
> +
> +  }
> +
> +  AdapterInfo->in_transmit = TRUE;
> +
> +  //
> +  // Prevent interrupts from changing the Tx ring from underneath us.
> +  //
> +  // Calculate the Tx descriptor entry.
> +  //
> +  if ((tcb_ptr = GetFreeCB (AdapterInfo)) == NULL) {
> +    AdapterInfo->in_transmit = FALSE;
> +    return PXE_STATCODE_QUEUE_FULL;
> +  }
> +
> +  AdapterInfo->TxTotals++;
> +
> +  tcb_ptr->cb_header.command  = (CmdSuspend | CmdTx | CmdTxFlex);
> +  tcb_ptr->cb_header.status   = 0;
> +
> +  //
> +  // no immediate data, set EOF in the ByteCount
> +  //
> +  tcb_ptr->ByteCount = 0x8000;
> +
> +  //
> +  // The data region is always in one buffer descriptor, Tx FIFO
> +  // threshold of 256.
> +  // 82557 multiplies the threashold value by 8, so give 256/8
> +  //
> +  tcb_ptr->Threshold = 32;
> +  if ((opflags & PXE_OPFLAGS_TRANSMIT_FRAGMENTED) != 0) {
> +
> +    if (tx_ptr_f->FragCnt > MAX_XMIT_FRAGMENTS) {
> +      SetFreeCB (AdapterInfo, tcb_ptr);
> +      AdapterInfo->in_transmit = FALSE;
> +      return PXE_STATCODE_INVALID_PARAMETER;
> +    }
> +
> +    tcb_ptr->TBDCount = (UINT8) tx_ptr_f->FragCnt;
> +
> +    for (Index = 0; Index < tx_ptr_f->FragCnt; Index++) {
> +      stat = MapIt (
> +              AdapterInfo,
> +              tx_ptr_f->FragDesc[Index].FragAddr,
> +              tx_ptr_f->FragDesc[Index].FragLen,
> +              TO_DEVICE,
> +              (UINT64)(UINTN) &Tmp_ptr
> +              );
> +      if (stat != 0) {
> +        SetFreeCB (AdapterInfo, tcb_ptr);
> +        AdapterInfo->in_transmit = FALSE;
> +        return PXE_STATCODE_INVALID_PARAMETER;
> +      }
> +
> +      tcb_ptr->TBDArray[Index].phys_buf_addr  = (UINT32) Tmp_ptr;
> +      tcb_ptr->TBDArray[Index].buf_len        = tx_ptr_f-
> >FragDesc[Index].FragLen;
> +    }
> +
> +    tcb_ptr->free_data_ptr = tx_ptr_f->FragDesc[0].FragAddr;
> +
> +  } else {
> +    //
> +    // non fragmented case
> +    //
> +    tcb_ptr->TBDCount = 1;
> +    stat = MapIt (
> +            AdapterInfo,
> +            tx_ptr_1->FrameAddr,
> +            tx_ptr_1->DataLen + tx_ptr_1->MediaheaderLen,
> +            TO_DEVICE,
> +            (UINT64)(UINTN) &Tmp_ptr
> +            );
> +    if (stat != 0) {
> +      SetFreeCB (AdapterInfo, tcb_ptr);
> +      AdapterInfo->in_transmit = FALSE;
> +      return PXE_STATCODE_INVALID_PARAMETER;
> +    }
> +
> +    tcb_ptr->TBDArray[0].phys_buf_addr  = (UINT32) (Tmp_ptr);
> +    tcb_ptr->TBDArray[0].buf_len        = tx_ptr_1->DataLen + tx_ptr_1-
> >MediaheaderLen;
> +    tcb_ptr->free_data_ptr              = tx_ptr_1->FrameAddr;
> +  }
> +
> +  //
> +  // must wait for previous command completion only if it was a non-
> transmit
> +  //
> +  BlockIt (AdapterInfo, TRUE);
> +  IssueCB (AdapterInfo, tcb_ptr);
> +  BlockIt (AdapterInfo, FALSE);
> +
> +  //
> +  // see if we need to wait for completion here
> +  //
> +  if ((opflags & PXE_OPFLAGS_TRANSMIT_BLOCK) != 0) {
> +    //
> +    // don't wait for more than 1 second!!!
> +    //
> +    wait_sec = 1000;
> +    while (tcb_ptr->cb_header.status == 0) {
> +      DelayIt (AdapterInfo, 10);
> +      wait_sec--;
> +      if (wait_sec == 0) {
> +        break;
> +      }
> +    }
> +    //
> +    // we need to un-map any mapped buffers here
> +    //
> +    if ((opflags & PXE_OPFLAGS_TRANSMIT_FRAGMENTED) != 0) {
> +
> +      for (Index = 0; Index < tx_ptr_f->FragCnt; Index++) {
> +        Tmp_ptr = tcb_ptr->TBDArray[Index].phys_buf_addr;
> +        UnMapIt (
> +          AdapterInfo,
> +          tx_ptr_f->FragDesc[Index].FragAddr,
> +          tx_ptr_f->FragDesc[Index].FragLen,
> +          TO_DEVICE,
> +          (UINT64) Tmp_ptr
> +          );
> +      }
> +    } else {
> +      Tmp_ptr = tcb_ptr->TBDArray[0].phys_buf_addr;
> +      UnMapIt (
> +        AdapterInfo,
> +        tx_ptr_1->FrameAddr,
> +        tx_ptr_1->DataLen + tx_ptr_1->MediaheaderLen,
> +        TO_DEVICE,
> +        (UINT64) Tmp_ptr
> +        );
> +    }
> +
> +    if (tcb_ptr->cb_header.status == 0) {
> +      SetFreeCB (AdapterInfo, tcb_ptr);
> +      AdapterInfo->in_transmit = FALSE;
> +      return PXE_STATCODE_DEVICE_FAILURE;
> +    }
> +
> +    SetFreeCB (AdapterInfo, tcb_ptr);
> +  }
> +  //
> +  // CB will be set free later in get_status (or when we run out of xmit
> buffers
> +  //
> +  AdapterInfo->in_transmit = FALSE;
> +
> +  return 0;
> +}
> +
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  AdapterInfo                     TODO: add argument description
> +  @param  cpb                             TODO: add argument description
> +  @param  db                              TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +UINTN
> +E100bReceive (
> +  NIC_DATA_INSTANCE *AdapterInfo,
> +  UINT64            cpb,
> +  UINT64            db
> +  )
> +{
> +  PXE_CPB_RECEIVE *rx_cpbptr;
> +  PXE_DB_RECEIVE  *rx_dbptr;
> +  RxFD            *rx_ptr;
> +  INT32           status;
> +  INT32           Index;
> +  UINT16          pkt_len;
> +  UINT16          ret_code;
> +  PXE_FRAME_TYPE  pkt_type;
> +  UINT16          Tmp_len;
> +  EtherHeader     *hdr_ptr;
> +  ret_code  = PXE_STATCODE_NO_DATA;
> +  pkt_type  = PXE_FRAME_TYPE_NONE;
> +  status    = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBStatus);
> +  AdapterInfo->Int_Status = (UINT16) (AdapterInfo->Int_Status | status);
> +  //
> +  // acknoledge the interrupts
> +  //
> +  OutWord (AdapterInfo, (UINT16) (status & 0xfc00), (UINT32) (AdapterInfo-
> >ioaddr + SCBStatus));
> +
> +  //
> +  // include the prev ints as well
> +  //
> +  status = AdapterInfo->Int_Status;
> +  rx_cpbptr = (PXE_CPB_RECEIVE *) (UINTN) cpb;
> +  rx_dbptr  = (PXE_DB_RECEIVE *) (UINTN) db;
> +
> +  rx_ptr    = &AdapterInfo->rx_ring[AdapterInfo->cur_rx_ind];
> +
> +  //
> +  // be in a loop just in case (we may drop a pkt)
> +  //
> +  while ((status = rx_ptr->cb_header.status) & RX_COMPLETE) {
> +
> +    AdapterInfo->RxTotals++;
> +    //
> +    // If we own the next entry, it's a new packet. Send it up.
> +    //
> +    if (rx_ptr->forwarded) {
> +      goto FreeRFD;
> +
> +    }
> +
> +    //
> +    // discard bad frames
> +    //
> +
> +    //
> +    // crc, align, dma overrun, too short, receive error (v22 no coll)
> +    //
> +    if ((status & 0x0D90) != 0) {
> +      goto FreeRFD;
> +
> +    }
> +
> +    //
> +    // make sure the status is OK
> +    //
> +    if ((status & 0x02000) == 0) {
> +      goto FreeRFD;
> +    }
> +
> +    pkt_len = (UINT16) (rx_ptr->ActualCount & 0x3fff);
> +
> +    if (pkt_len != 0) {
> +
> +      Tmp_len = pkt_len;
> +      if (pkt_len > rx_cpbptr->BufferLen) {
> +        Tmp_len = (UINT16) rx_cpbptr->BufferLen;
> +      }
> +
> +      CopyMem ((INT8 *) (UINTN) rx_cpbptr->BufferAddr, (INT8 *) &rx_ptr-
> >RFDBuffer, Tmp_len);
> +
> +      hdr_ptr = (EtherHeader *) &rx_ptr->RFDBuffer;
> +      //
> +      // fill the CDB and break the loop
> +      //
> +
> +      //
> +      // includes header
> +      //
> +      rx_dbptr->FrameLen = pkt_len;
> +      rx_dbptr->MediaHeaderLen = PXE_MAC_HEADER_LEN_ETHER;
> +
> +      for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
> +        if (hdr_ptr->dest_addr[Index] != AdapterInfo-
> >CurrentNodeAddress[Index]) {
> +          break;
> +        }
> +      }
> +
> +      if (Index >= PXE_HWADDR_LEN_ETHER) {
> +        pkt_type = PXE_FRAME_TYPE_UNICAST;
> +      } else {
> +        for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
> +          if (hdr_ptr->dest_addr[Index] != AdapterInfo-
> >BroadcastNodeAddress[Index]) {
> +            break;
> +          }
> +        }
> +
> +        if (Index >= PXE_HWADDR_LEN_ETHER) {
> +          pkt_type = PXE_FRAME_TYPE_BROADCAST;
> +        } else {
> +          if ((hdr_ptr->dest_addr[0] & 1) == 1) {
> +            //
> +            // mcast
> +            //
> +
> +            pkt_type = PXE_FRAME_TYPE_FILTERED_MULTICAST;
> +          } else {
> +            pkt_type = PXE_FRAME_TYPE_PROMISCUOUS;
> +          }
> +        }
> +      }
> +
> +      rx_dbptr->Type      = pkt_type;
> +      rx_dbptr->Protocol  = hdr_ptr->type;
> +
> +      for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
> +        rx_dbptr->SrcAddr[Index]  = hdr_ptr->src_addr[Index];
> +        rx_dbptr->DestAddr[Index] = hdr_ptr->dest_addr[Index];
> +      }
> +
> +      rx_ptr->forwarded = TRUE;
> +      //
> +      // success
> +      //
> +      ret_code          = 0;
> +      Recycle_RFD (AdapterInfo, AdapterInfo->cur_rx_ind);
> +      AdapterInfo->cur_rx_ind++;
> +      if (AdapterInfo->cur_rx_ind == AdapterInfo->RxBufCnt) {
> +        AdapterInfo->cur_rx_ind = 0;
> +      }
> +      break;
> +    }
> +
> +FreeRFD:
> +    Recycle_RFD (AdapterInfo, AdapterInfo->cur_rx_ind);
> +    AdapterInfo->cur_rx_ind++;
> +    if (AdapterInfo->cur_rx_ind == AdapterInfo->RxBufCnt) {
> +      AdapterInfo->cur_rx_ind = 0;
> +    }
> +
> +    rx_ptr = &AdapterInfo->rx_ring[AdapterInfo->cur_rx_ind];
> +  }
> +
> +  if (pkt_type == PXE_FRAME_TYPE_NONE) {
> +    AdapterInfo->Int_Status &= (~SCB_STATUS_FR);
> +  }
> +
> +  status = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBStatus);
> +  if ((status & SCB_RUS_NO_RESOURCES) != 0) {
> +    //
> +    // start the receive unit here!
> +    // leave all the filled frames,
> +    //
> +    SetupReceiveQueues (AdapterInfo);
> +    OutLong (AdapterInfo, (UINT32) AdapterInfo->rx_phy_addr, AdapterInfo-
> >ioaddr + SCBPointer);
> +    OutWord (AdapterInfo, RX_START, AdapterInfo->ioaddr + SCBCmd);
> +    AdapterInfo->cur_rx_ind = 0;
> +  }
> +
> +  return ret_code;
> +}
> +
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  AdapterInfo                     TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +INT16
> +E100bReadEepromAndStationAddress (
> +  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  INT32   Index;
> +  INT32   Index2;
> +  UINT16  sum;
> +  UINT16  eeprom_len;
> +  UINT8   addr_len;
> +  UINT16  *eedata;
> +
> +  eedata    = (UINT16 *) (&AdapterInfo->NVData[0]);
> +
> +  sum       = 0;
> +  addr_len  = E100bGetEepromAddrLen (AdapterInfo);
> +
> +  //
> +  // in words
> +  //
> +  AdapterInfo->NVData_Len = eeprom_len = (UINT16) (1 << addr_len);
> +  for (Index2 = 0, Index = 0; ((Index2 < PXE_MAC_LENGTH - 1) && (Index <
> eeprom_len)); Index++) {
> +    UINT16  value;
> +    value         = E100bReadEeprom (AdapterInfo, Index, addr_len);
> +    eedata[Index] = value;
> +    sum           = (UINT16) (sum + value);
> +    if (Index < 3) {
> +      AdapterInfo->PermNodeAddress[Index2++]  = (UINT8) value;
> +      AdapterInfo->PermNodeAddress[Index2++]  = (UINT8) (value >> 8);
> +    }
> +  }
> +
> +  if (sum != 0xBABA) {
> +    return -1;
> +  }
> +
> +  for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
> +    AdapterInfo->CurrentNodeAddress[Index] = AdapterInfo-
> >PermNodeAddress[Index];
> +  }
> +
> +  for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
> +    AdapterInfo->BroadcastNodeAddress[Index] = 0xff;
> +  }
> +
> +  for (Index = PXE_HWADDR_LEN_ETHER; Index < PXE_MAC_LENGTH;
> Index++) {
> +    AdapterInfo->CurrentNodeAddress[Index]    = 0;
> +    AdapterInfo->PermNodeAddress[Index]       = 0;
> +    AdapterInfo->BroadcastNodeAddress[Index]  = 0;
> +  }
> +
> +  return 0;
> +}
> +
> +//
> +//  CBList is a circular linked list
> +//  1) When all are free, Tail->next == Head and FreeCount == # allocated
> +//  2) When none are free, Tail == Head and FreeCount == 0
> +//  3) when one is free, Tail == Head and Freecount == 1
> +//  4) First non-Free frame is always at Tail->next
> +//
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  AdapterInfo                     TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +UINT8
> +SetupCBlink (
> +  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  TxCB  *head_ptr;
> +  TxCB  *tail_ptr;
> +  TxCB  *cur_ptr;
> +  INT32 Index;
> +  UINTN array_off;
> +
> +  cur_ptr   = &(AdapterInfo->tx_ring[0]);
> +  array_off = (UINTN) (&cur_ptr->TBDArray) - (UINTN) cur_ptr;
> +  for (Index = 0; Index < AdapterInfo->TxBufCnt; Index++) {
> +    cur_ptr[Index].cb_header.status   = 0;
> +    cur_ptr[Index].cb_header.command  = 0;
> +
> +    cur_ptr[Index].PhysTCBAddress     =
> +    (UINT32) AdapterInfo->tx_phy_addr + (Index * sizeof (TxCB));
> +
> +    cur_ptr[Index].PhysArrayAddr      =
> (UINT32)(cur_ptr[Index].PhysTCBAddress + array_off);
> +    cur_ptr[Index].PhysTBDArrayAddres =
> (UINT32)(cur_ptr[Index].PhysTCBAddress + array_off);
> +
> +    cur_ptr->free_data_ptr = (UINT64) 0;
> +
> +    if (Index < AdapterInfo->TxBufCnt - 1) {
> +      cur_ptr[Index].cb_header.link             = cur_ptr[Index].PhysTCBAddress +
> sizeof (TxCB);
> +      cur_ptr[Index].NextTCBVirtualLinkPtr      = &cur_ptr[Index + 1];
> +      cur_ptr[Index + 1].PrevTCBVirtualLinkPtr  = &cur_ptr[Index];
> +    }
> +  }
> +
> +  head_ptr                        = &cur_ptr[0];
> +  tail_ptr                        = &cur_ptr[AdapterInfo->TxBufCnt - 1];
> +  tail_ptr->cb_header.link        = head_ptr->PhysTCBAddress;
> +  tail_ptr->NextTCBVirtualLinkPtr = head_ptr;
> +  head_ptr->PrevTCBVirtualLinkPtr = tail_ptr;
> +
> +  AdapterInfo->FreeCBCount        = AdapterInfo->TxBufCnt;
> +  AdapterInfo->FreeTxHeadPtr      = head_ptr;
> +  //
> +  // set tail of the free list, next to this would be either in use
> +  // or the head itself
> +  //
> +  AdapterInfo->FreeTxTailPtr  = tail_ptr;
> +
> +  AdapterInfo->xmit_done_head = AdapterInfo->xmit_done_tail = 0;
> +
> +  return 0;
> +}
> +
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  AdapterInfo                     TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +TxCB *
> +GetFreeCB (
> +  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  TxCB  *free_cb_ptr;
> +
> +  //
> +  // claim any hanging free CBs
> +  //
> +  if (AdapterInfo->FreeCBCount <= 1) {
> +    CheckCBList (AdapterInfo);
> +  }
> +
> +  //
> +  // don't use up the last CB problem if the previous CB that the CU used
> +  // becomes the last CB we submit because of the SUSPEND bit we set.
> +  // the CU thinks it was never cleared.
> +  //
> +
> +  if (AdapterInfo->FreeCBCount <= 1) {
> +    return NULL;
> +  }
> +
> +  BlockIt (AdapterInfo, TRUE);
> +  free_cb_ptr                 = AdapterInfo->FreeTxHeadPtr;
> +  AdapterInfo->FreeTxHeadPtr  = free_cb_ptr->NextTCBVirtualLinkPtr;
> +  --AdapterInfo->FreeCBCount;
> +  BlockIt (AdapterInfo, FALSE);
> +  return free_cb_ptr;
> +}
> +
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  AdapterInfo                     TODO: add argument description
> +  @param  cb_ptr                          TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +VOID
> +SetFreeCB (
> +  IN NIC_DATA_INSTANCE *AdapterInfo,
> +  IN TxCB              *cb_ptr
> +  )
> +{
> +  //
> +  // here we assume cb are returned in the order they are taken out
> +  // and we link the newly freed cb at the tail of free cb list
> +  //
> +  cb_ptr->cb_header.status    = 0;
> +  cb_ptr->free_data_ptr       = (UINT64) 0;
> +
> +  AdapterInfo->FreeTxTailPtr  = cb_ptr;
> +  ++AdapterInfo->FreeCBCount;
> +  return ;
> +}
> +
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  ind                             TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +UINT16
> +next (
> +  IN UINT16 ind
> +  )
> +{
> +  UINT16  Tmp;
> +
> +  Tmp = (UINT16) (ind + 1);
> +  if (Tmp >= (TX_BUFFER_COUNT << 1)) {
> +    Tmp = 0;
> +  }
> +
> +  return Tmp;
> +}
> +
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  AdapterInfo                     TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +UINT16
> +CheckCBList (
> +  IN NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  TxCB    *Tmp_ptr;
> +  UINT16  cnt;
> +
> +  cnt = 0;
> +  while (1) {
> +    Tmp_ptr = AdapterInfo->FreeTxTailPtr->NextTCBVirtualLinkPtr;
> +    if ((Tmp_ptr->cb_header.status & CMD_STATUS_MASK) != 0) {
> +      //
> +      // check if Q is full
> +      //
> +      if (next (AdapterInfo->xmit_done_tail) != AdapterInfo->xmit_done_head)
> {
> +        ASSERT (AdapterInfo->xmit_done_tail < TX_BUFFER_COUNT << 1);
> +        AdapterInfo->xmit_done[AdapterInfo->xmit_done_tail] = Tmp_ptr-
> >free_data_ptr;
> +
> +        UnMapIt (
> +          AdapterInfo,
> +          Tmp_ptr->free_data_ptr,
> +          Tmp_ptr->TBDArray[0].buf_len,
> +          TO_DEVICE,
> +          (UINT64) Tmp_ptr->TBDArray[0].phys_buf_addr
> +          );
> +
> +        AdapterInfo->xmit_done_tail = next (AdapterInfo->xmit_done_tail);
> +      }
> +
> +      SetFreeCB (AdapterInfo, Tmp_ptr);
> +    } else {
> +      break;
> +    }
> +  }
> +
> +  return cnt;
> +}
> +//
> +// Description : Initialize the RFD list list by linking each element together
> +//               in a circular list.  The simplified memory model is used.
> +//               All data is in the RFD.  The RFDs are linked together and the
> +//               last one points back to the first one.  When the current RFD
> +//               is processed (frame received), its EL bit is set and the EL
> +//               bit in the previous RXFD is cleared.
> +//               Allocation done during INIT, this is making linked list.
> +//
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  AdapterInfo                     TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +UINT8
> +SetupReceiveQueues (
> +  IN NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  RxFD    *rx_ptr;
> +  RxFD    *tail_ptr;
> +  UINT16  Index;
> +
> +  AdapterInfo->cur_rx_ind = 0;
> +  rx_ptr                  = (&AdapterInfo->rx_ring[0]);
> +
> +  for (Index = 0; Index < AdapterInfo->RxBufCnt; Index++) {
> +    rx_ptr[Index].cb_header.status  = 0;
> +    rx_ptr[Index].cb_header.command = 0;
> +    rx_ptr[Index].RFDSize           = RX_BUFFER_SIZE;
> +    rx_ptr[Index].ActualCount       = 0;
> +    //
> +    // RBDs not used, simple memory model
> +    //
> +    rx_ptr[Index].rx_buf_addr       = (UINT32) (-1);
> +
> +    //
> +    // RBDs not used, simple memory model
> +    //
> +    rx_ptr[Index].forwarded = FALSE;
> +
> +    //
> +    // don't use Tmp_ptr if it is beyond the last one
> +    //
> +    if (Index < AdapterInfo->RxBufCnt - 1) {
> +      rx_ptr[Index].cb_header.link = (UINT32) AdapterInfo->rx_phy_addr +
> ((Index + 1) * sizeof (RxFD));
> +    }
> +  }
> +
> +  tail_ptr                    = (&AdapterInfo->rx_ring[AdapterInfo->RxBufCnt - 1]);
> +  tail_ptr->cb_header.link    = (UINT32) AdapterInfo->rx_phy_addr;
> +
> +  //
> +  // set the EL bit
> +  //
> +  tail_ptr->cb_header.command = 0xC000;
> +  AdapterInfo->RFDTailPtr = tail_ptr;
> +  return 0;
> +}
> +
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  AdapterInfo                     TODO: add argument description
> +  @param  rx_index                        TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +VOID
> +Recycle_RFD (
> +  IN NIC_DATA_INSTANCE *AdapterInfo,
> +  IN UINT16            rx_index
> +  )
> +{
> +  RxFD  *rx_ptr;
> +  RxFD  *tail_ptr;
> +  //
> +  // change the EL bit and change the AdapterInfo->RxTailPtr
> +  // rx_ptr is assumed to be the head of the Q
> +  // AdapterInfo->rx_forwarded[rx_index] = FALSE;
> +  //
> +  rx_ptr                    = &AdapterInfo->rx_ring[rx_index];
> +  tail_ptr                  = AdapterInfo->RFDTailPtr;
> +  //
> +  // set el_bit and suspend bit
> +  //
> +  rx_ptr->cb_header.command = 0xc000;
> +  rx_ptr->cb_header.status    = 0;
> +  rx_ptr->ActualCount         = 0;
> +  rx_ptr->forwarded           = FALSE;
> +  AdapterInfo->RFDTailPtr     = rx_ptr;
> +  //
> +  // resetting the el_bit.
> +  //
> +  tail_ptr->cb_header.command = 0;
> +  //
> +  // check the receive unit, fix if there is any problem
> +  //
> +  return ;
> +}
> +//
> +// Serial EEPROM section.
> +//
> +//  EEPROM_Ctrl bits.
> +//
> +#define EE_SHIFT_CLK  0x01  /* EEPROM shift clock. */
> +#define EE_CS         0x02  /* EEPROM chip select. */
> +#define EE_DI         0x04  /* EEPROM chip data in. */
> +#define EE_WRITE_0    0x01
> +#define EE_WRITE_1    0x05
> +#define EE_DO         0x08  /* EEPROM chip data out. */
> +#define EE_ENB        (0x4800 | EE_CS)
> +
> +//
> +// Delay between EEPROM clock transitions.
> +// This will actually work with no delay on 33Mhz PCI.
> +//
> +#define eeprom_delay(nanosec) DelayIt (AdapterInfo, nanosec);
> +
> +//
> +// The EEPROM commands include the alway-set leading bit.
> +//
> +#define EE_WRITE_CMD  5 // 101b
> +#define EE_READ_CMD   6 // 110b
> +#define EE_ERASE_CMD  (7 << 6)
> +
> +VOID
> +shift_bits_out (
> +  IN NIC_DATA_INSTANCE *AdapterInfo,
> +  IN UINT16            val,
> +  IN UINT8             num_bits
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  TODO: Add function description
> +
> +Arguments:
> +
> +  AdapterInfo - TODO: add argument description
> +  val         - TODO: add argument description
> +  num_bits    - TODO: add argument description
> +
> +Returns:
> +
> +  TODO: add return values
> +
> +--*/
> +{
> +  INT32   Index;
> +  UINT8   Tmp;
> +  UINT32  EEAddr;
> +
> +  EEAddr = AdapterInfo->ioaddr + SCBeeprom;
> +
> +  for (Index = num_bits; Index >= 0; Index--) {
> +    INT16 dataval;
> +
> +    //
> +    // will be 0 or 4
> +    //
> +    dataval = (INT16) ((val & (1 << Index)) ? EE_DI : 0);
> +
> +    //
> +    // mask off the data_in bit
> +    //
> +    Tmp = (UINT8) (InByte (AdapterInfo, EEAddr) &~EE_DI);
> +    Tmp = (UINT8) (Tmp | dataval);
> +    OutByte (AdapterInfo, Tmp, EEAddr);
> +    eeprom_delay (100);
> +    //
> +    // raise the eeprom clock
> +    //
> +    OutByte (AdapterInfo, (UINT8) (Tmp | EE_SHIFT_CLK), EEAddr);
> +    eeprom_delay (150);
> +    //
> +    // lower the eeprom clock
> +    //
> +    OutByte (AdapterInfo, (UINT8) (Tmp &~EE_SHIFT_CLK), EEAddr);
> +    eeprom_delay (150);
> +  }
> +}
> +
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  AdapterInfo                     TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +UINT16
> +shift_bits_in (
> +  IN NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  UINT8   Tmp;
> +  INT32   Index;
> +  UINT16  retval;
> +  UINT32  EEAddr;
> +
> +  EEAddr  = AdapterInfo->ioaddr + SCBeeprom;
> +
> +  retval  = 0;
> +  for (Index = 15; Index >= 0; Index--) {
> +    //
> +    // raise the clock
> +    //
> +
> +    //
> +    // mask off the data_in bit
> +    //
> +    Tmp = InByte (AdapterInfo, EEAddr);
> +    OutByte (AdapterInfo, (UINT8) (Tmp | EE_SHIFT_CLK), EEAddr);
> +    eeprom_delay (100);
> +    Tmp     = InByte (AdapterInfo, EEAddr);
> +    retval  = (UINT16) ((retval << 1) | ((Tmp & EE_DO) ? 1 : 0));
> +    //
> +    // lower the clock
> +    //
> +    OutByte (AdapterInfo, (UINT8) (Tmp &~EE_SHIFT_CLK), EEAddr);
> +    eeprom_delay (100);
> +  }
> +
> +  return retval;
> +}
> +
> +
> +/**
> +  This routine sets the EEPROM lockout bit to gain exclusive access to the
> +  eeprom. the access bit is the most significant bit in the General Control
> +  Register 2 in the SCB space.
> +
> +  @param  AdapterInfo                     Pointer to the NIC data structure
> +                                          information which the UNDI driver is
> +                                          layering on..
> +
> +  @retval TRUE                            if it got the access
> +  @retval FALSE                           if it fails to get the exclusive access
> +
> +**/
> +BOOLEAN
> +E100bSetEepromLockOut (
> +  IN NIC_DATA_INSTANCE  *AdapterInfo
> +  )
> +{
> +  UINTN wait;
> +  UINT8 tmp;
> +
> +  if ((AdapterInfo->DeviceID == D102_DEVICE_ID) ||
> +      (AdapterInfo->RevID >= D102_REVID)) {
> +
> +    wait = 500;
> +
> +    while (wait--) {
> +
> +      tmp = InByte (AdapterInfo, AdapterInfo->ioaddr + SCBGenCtrl2);
> +      tmp |= GCR2_EEPROM_ACCESS_SEMAPHORE;
> +      OutByte (AdapterInfo, tmp, AdapterInfo->ioaddr + SCBGenCtrl2);
> +
> +      DelayIt (AdapterInfo, 50);
> +      tmp = InByte (AdapterInfo, AdapterInfo->ioaddr + SCBGenCtrl2);
> +
> +      if (tmp & GCR2_EEPROM_ACCESS_SEMAPHORE) {
> +        return TRUE;
> +      }
> +    }
> +
> +    return FALSE;
> +  }
> +
> +  return TRUE;
> +}
> +
> +
> +/**
> +  This routine Resets the EEPROM lockout bit to giveup access to the
> +  eeprom. the access bit is the most significant bit in the General Control
> +  Register 2 in the SCB space.
> +
> +  @param  AdapterInfo                     Pointer to the NIC data structure
> +                                          information which the UNDI driver is
> +                                          layering on..
> +
> +  @return None
> +
> +**/
> +VOID
> +E100bReSetEepromLockOut (
> +  IN NIC_DATA_INSTANCE  *AdapterInfo
> +  )
> +{
> +  UINT8 tmp;
> +
> +  if ((AdapterInfo->DeviceID == D102_DEVICE_ID) ||
> +      (AdapterInfo->RevID >= D102_REVID)) {
> +
> +    tmp = InByte (AdapterInfo, AdapterInfo->ioaddr + SCBGenCtrl2);
> +    tmp &= ~(GCR2_EEPROM_ACCESS_SEMAPHORE);
> +    OutByte (AdapterInfo, tmp, AdapterInfo->ioaddr + SCBGenCtrl2);
> +
> +    DelayIt (AdapterInfo, 50);
> +  }
> +}
> +
> +
> +/**
> +  Using the NIC data structure information, read the EEPROM to get a Word
> of data for the MAC address.
> +
> +  @param  AdapterInfo                     Pointer to the NIC data structure
> +                                          information which the UNDI driver is
> +                                          layering on..
> +  @param  Location                        Word offset into the MAC address to read.
> +  @param  AddrLen                         Number of bits of address length.
> +
> +  @retval RetVal                          The word read from the EEPROM.
> +
> +**/
> +UINT16
> +E100bReadEeprom (
> +  IN NIC_DATA_INSTANCE  *AdapterInfo,
> +  IN INT32              Location,
> +  IN UINT8              AddrLen
> +  )
> +{
> +  UINT16  RetVal;
> +  UINT8   Tmp;
> +
> +  UINT32  EEAddr;
> +  UINT16  ReadCmd;
> +
> +  EEAddr  = AdapterInfo->ioaddr + SCBeeprom;
> +  ReadCmd = (UINT16) (Location | (EE_READ_CMD << AddrLen));
> +
> +  RetVal  = 0;
> +
> +  //
> +  // get exclusive access to the eeprom first!
> +  //
> +  E100bSetEepromLockOut (AdapterInfo);
> +
> +  //
> +  // eeprom control reg bits: x,x,x,x,DO,DI,CS,SK
> +  // to write the opcode+data value out one bit at a time in DI starting at
> msb
> +  // and then out a 1 to sk, wait, out 0 to SK and wait
> +  // repeat this for all the bits to be written
> +  //
> +
> +  //
> +  // 11110010b
> +  //
> +  Tmp = (UINT8) (InByte (AdapterInfo, EEAddr) & 0xF2);
> +  OutByte (AdapterInfo, (UINT8) (Tmp | EE_CS), EEAddr);
> +
> +  //
> +  // 3 for the read opcode 110b
> +  //
> +  shift_bits_out (AdapterInfo, ReadCmd, (UINT8) (3 + AddrLen));
> +
> +  //
> +  // read the eeprom word one bit at a time
> +  //
> +  RetVal = shift_bits_in (AdapterInfo);
> +
> +  //
> +  // Terminate the EEPROM access and leave eeprom in a clean state.
> +  //
> +  Tmp = InByte (AdapterInfo, EEAddr);
> +  Tmp &= ~(EE_CS | EE_DI);
> +  OutByte (AdapterInfo, Tmp, EEAddr);
> +
> +  //
> +  // raise the clock and lower the eeprom shift clock
> +  //
> +  OutByte (AdapterInfo, (UINT8) (Tmp | EE_SHIFT_CLK), EEAddr);
> +  eeprom_delay (100);
> +
> +  OutByte (AdapterInfo, (UINT8) (Tmp &~EE_SHIFT_CLK), EEAddr);
> +  eeprom_delay (100);
> +
> +  //
> +  // giveup access to the eeprom
> +  //
> +  E100bReSetEepromLockOut (AdapterInfo);
> +
> +  return RetVal;
> +}
> +
> +
> +/**
> +  Using the NIC data structure information, read the EEPROM to determine
> how many bits of address length
> +  this EEPROM is in Words.
> +
> +  @param  AdapterInfo                     Pointer to the NIC data structure
> +                                          information which the UNDI driver is
> +                                          layering on..
> +
> +  @retval RetVal                          The word read from the EEPROM.
> +
> +**/
> +UINT8
> +E100bGetEepromAddrLen (
> +  IN NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  UINT8   Tmp;
> +  UINT8   AddrLen;
> +  UINT32  EEAddr;
> +  //
> +  // assume 64word eeprom (so,6 bits of address_length)
> +  //
> +  UINT16  ReadCmd;
> +
> +  EEAddr  = AdapterInfo->ioaddr + SCBeeprom;
> +  ReadCmd = (EE_READ_CMD << 6);
> +
> +  //
> +  // get exclusive access to the eeprom first!
> +  //
> +  E100bSetEepromLockOut (AdapterInfo);
> +
> +  //
> +  // address we are trying to read is 0
> +  // eeprom control reg bits: x,x,x,x,DO,,DI,,CS,SK
> +  // to write the opcode+data value out one bit at a time in DI starting at
> msb
> +  // and then out a 1 to sk, wait, out 0 to SK and wait
> +  // repeat this for all the bits to be written
> +  //
> +  Tmp = (UINT8) (InByte (AdapterInfo, EEAddr) & 0xF2);
> +
> +  //
> +  // enable eeprom access
> +  //
> +  OutByte (AdapterInfo, (UINT8) (Tmp | EE_CS), EEAddr);
> +
> +  //
> +  // 3 for opcode, 6 for the default address len
> +  //
> +  shift_bits_out (AdapterInfo, ReadCmd, (UINT8) (3 + 6));
> +
> +  //
> +  // (in case of a 64 word eeprom).
> +  // read the "dummy zero" from EE_DO to say that the address we wrote
> +  // (six 0s) is accepted, write more zeros (until 8) to get a "dummy zero"
> +  //
> +
> +  //
> +  // assume the smallest
> +  //
> +  AddrLen = 6;
> +  Tmp     = InByte (AdapterInfo, EEAddr);
> +  while ((AddrLen < 8) && ((Tmp & EE_DO) != 0)) {
> +    OutByte (AdapterInfo, (UINT8) (Tmp &~EE_DI), EEAddr);
> +    eeprom_delay (100);
> +
> +    //
> +    // raise the eeprom clock
> +    //
> +    OutByte (AdapterInfo, (UINT8) (Tmp | EE_SHIFT_CLK), EEAddr);
> +    eeprom_delay (150);
> +
> +    //
> +    // lower the eeprom clock
> +    //
> +    OutByte (AdapterInfo, (UINT8) (Tmp &~EE_SHIFT_CLK), EEAddr);
> +    eeprom_delay (150);
> +    Tmp = InByte (AdapterInfo, EEAddr);
> +    AddrLen++;
> +  }
> +
> +  //
> +  // read the eeprom word, even though we don't need this
> +  //
> +  shift_bits_in (AdapterInfo);
> +
> +  //
> +  // Terminate the EEPROM access.
> +  //
> +  Tmp = InByte (AdapterInfo, EEAddr);
> +  Tmp &= ~(EE_CS | EE_DI);
> +  OutByte (AdapterInfo, Tmp, EEAddr);
> +
> +  //
> +  // raise the clock and lower the eeprom shift clock
> +  //
> +  OutByte (AdapterInfo, (UINT8) (Tmp | EE_SHIFT_CLK), EEAddr);
> +  eeprom_delay (100);
> +
> +  OutByte (AdapterInfo, (UINT8) (Tmp &~EE_SHIFT_CLK), EEAddr);
> +  eeprom_delay (100);
> +
> +  //
> +  // giveup access to the eeprom!
> +  //
> +  E100bReSetEepromLockOut (AdapterInfo);
> +
> +  return AddrLen;
> +}
> +
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  AdapterInfo                     TODO: add argument description
> +  @param  DBaddr                          TODO: add argument description
> +  @param  DBsize                          TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +UINTN
> +E100bStatistics (
> +  NIC_DATA_INSTANCE *AdapterInfo,
> +  UINT64            DBaddr,
> +  UINT16            DBsize
> +  )
> +{
> +  PXE_DB_STATISTICS db;
> +  //
> +  // wait upto one second (each wait is 100 micro s)
> +  //
> +  UINT32            Wait;
> +  Wait = 10000;
> +  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
> +
> +  //
> +  // Clear statistics done marker.
> +  //
> +  AdapterInfo->statistics->done_marker = 0;
> +
> +  //
> +  // Issue statistics dump (or dump w/ reset) command.
> +  //
> +  OutByte (
> +    AdapterInfo,
> +    (UINT8) (DBsize ? CU_SHOWSTATS : CU_DUMPSTATS),
> +    (UINT32) (AdapterInfo->ioaddr + SCBCmd)
> +    );
> +
> +  //
> +  // Wait for command to complete.
> +  //
> +  // zero the db here just to chew up a little more time.
> +  //
> +
> +  ZeroMem ((VOID *) &db, sizeof db);
> +
> +  while (Wait != 0) {
> +    //
> +    // Wait a bit before checking.
> +    //
> +
> +    DelayIt (AdapterInfo, 100);
> +
> +    //
> +    // Look for done marker at end of statistics.
> +    //
> +
> +    switch (AdapterInfo->statistics->done_marker) {
> +    case 0xA005:
> +    case 0xA007:
> +      break;
> +
> +    default:
> +      Wait--;
> +      continue;
> +    }
> +
> +    //
> +    // if we did not "continue" from the above switch, we are done,
> +    //
> +    break;
> +  }
> +
> +  //
> +  // If this is a reset, we are out of here!
> +  //
> +  if (DBsize == 0) {
> +    return PXE_STATCODE_SUCCESS;
> +  }
> +
> +  //
> +  // Convert NIC statistics counter format to EFI/UNDI
> +  // specification statistics counter format.
> +  //
> +
> +  //
> +  //                54 3210 fedc ba98 7654 3210
> +  // db.Supported = 01 0000 0100 1101 0001 0111;
> +  //
> +  db.Supported = 0x104D17;
> +
> +  //
> +  // Statistics from the NIC
> +  //
> +
> +  db.Data[0x01] = AdapterInfo->statistics->rx_good_frames;
> +
> +  db.Data[0x02] = AdapterInfo->statistics->rx_runt_errs;
> +
> +  db.Data[0x08] = AdapterInfo->statistics->rx_crc_errs +
> +                  AdapterInfo->statistics->rx_align_errs;
> +
> +  db.Data[0x04] = db.Data[0x02] +
> +                  db.Data[0x08] +
> +                  AdapterInfo->statistics->rx_resource_errs +
> +                  AdapterInfo->statistics->rx_overrun_errs;
> +
> +  db.Data[0x00] = db.Data[0x01] + db.Data[0x04];
> +
> +  db.Data[0x0B] = AdapterInfo->statistics->tx_good_frames;
> +
> +  db.Data[0x0E] = AdapterInfo->statistics->tx_coll16_errs +
> +    AdapterInfo->statistics->tx_late_colls +
> +    AdapterInfo->statistics->tx_underruns +
> +    AdapterInfo->statistics->tx_one_colls +
> +    AdapterInfo->statistics->tx_multi_colls;
> +
> +  db.Data[0x14] = AdapterInfo->statistics->tx_total_colls;
> +
> +  db.Data[0x0A] = db.Data[0x0B] +
> +                  db.Data[0x0E] +
> +                  AdapterInfo->statistics->tx_lost_carrier;
> +
> +  if (DBsize > sizeof db) {
> +    DBsize = (UINT16) sizeof (db);
> +  }
> +
> +  CopyMem ((VOID *) (UINTN) DBaddr, (VOID *) &db, (UINTN) DBsize);
> +
> +  return PXE_STATCODE_SUCCESS;
> +}
> +
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  AdapterInfo                     TODO: add argument description
> +  @param  OpFlags                         TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +UINTN
> +E100bReset (
> +  IN NIC_DATA_INSTANCE *AdapterInfo,
> +  IN INT32             OpFlags
> +  )
> +{
> +
> +  UINT16  save_filter;
> +  //
> +  // disable the interrupts
> +  //
> +  OutWord (AdapterInfo, INT_MASK, AdapterInfo->ioaddr + SCBCmd);
> +
> +  //
> +  // wait for the tx queue to complete
> +  //
> +  CheckCBList (AdapterInfo);
> +
> +  XmitWaitForCompletion (AdapterInfo);
> +
> +  if (AdapterInfo->Receive_Started) {
> +    StopRU (AdapterInfo);
> +  }
> +
> +  InitializeChip (AdapterInfo);
> +
> +  //
> +  // check the opflags and restart receive filters
> +  //
> +  if ((OpFlags & PXE_OPFLAGS_RESET_DISABLE_FILTERS) == 0) {
> +
> +    save_filter = AdapterInfo->Rx_Filter;
> +    //
> +    // if we give the filter same as Rx_Filter,
> +    // this routine will not set mcast list (it thinks there is no change)
> +    // to force it, we will reset that flag in the Rx_Filter
> +    //
> +    AdapterInfo->Rx_Filter &=
> (~PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST);
> +    E100bSetfilter (AdapterInfo, save_filter, (UINT64) 0, (UINT32) 0);
> +  }
> +
> +  if ((OpFlags & PXE_OPFLAGS_RESET_DISABLE_INTERRUPTS) != 0) {
> +    //
> +    // disable the interrupts
> +    //
> +    AdapterInfo->int_mask = 0;
> +  }
> +  //
> +  // else leave the interrupt in the pre-set state!!!
> +  //
> +  E100bSetInterruptState (AdapterInfo);
> +
> +  return 0;
> +}
> +
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  AdapterInfo                     TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +UINTN
> +E100bShutdown (
> +  IN NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  //
> +  // disable the interrupts
> +  //
> +  OutWord (AdapterInfo, INT_MASK, AdapterInfo->ioaddr + SCBCmd);
> +
> +  //
> +  // stop the receive unit
> +  //
> +  if (AdapterInfo->Receive_Started) {
> +    StopRU (AdapterInfo);
> +  }
> +
> +  //
> +  // wait for the tx queue to complete
> +  //
> +  CheckCBList (AdapterInfo);
> +  if (AdapterInfo->FreeCBCount != AdapterInfo->TxBufCnt) {
> +    wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
> +  }
> +
> +  //
> +  // we do not want to reset the phy, it takes a long time to renegotiate the
> +  // link after that (3-4 seconds)
> +  //
> +  InitializeChip (AdapterInfo);
> +  SelectiveReset (AdapterInfo);
> +  return 0;
> +}
> +
> +
> +/**
> +  This routine will write a value to the specified MII register
> +  of an external MDI compliant device (e.g. PHY 100).  The command will
> +  execute in polled mode.
> +
> +  @param  AdapterInfo                     pointer to the structure that contains
> +                                          the NIC's context.
> +  @param  RegAddress                      The MII register that we are writing to
> +  @param  PhyAddress                      The MDI address of the Phy component.
> +  @param  DataValue                       The value that we are writing to the MII
> +                                          register.
> +
> +  @return nothing
> +
> +**/
> +VOID
> +MdiWrite (
> +  IN NIC_DATA_INSTANCE *AdapterInfo,
> +  IN UINT8             RegAddress,
> +  IN UINT8             PhyAddress,
> +  IN UINT16            DataValue
> +  )
> +{
> +  UINT32  WriteCommand;
> +
> +  WriteCommand = ((UINT32) DataValue) |
> +                 ((UINT32)(RegAddress << 16)) |
> +                 ((UINT32)(PhyAddress << 21)) |
> +                 ((UINT32)(MDI_WRITE << 26));
> +
> +  //
> +  // Issue the write command to the MDI control register.
> +  //
> +  OutLong (AdapterInfo, WriteCommand, AdapterInfo->ioaddr +
> SCBCtrlMDI);
> +
> +  //
> +  // wait 20usec before checking status
> +  //
> +  DelayIt (AdapterInfo, 20);
> +
> +  //
> +  // poll for the mdi write to complete
> +  while ((InLong (AdapterInfo, AdapterInfo->ioaddr + SCBCtrlMDI) &
> +                    MDI_PHY_READY) == 0){
> +    DelayIt (AdapterInfo, 20);
> +  }
> +}
> +
> +
> +/**
> +  This routine will read a value from the specified MII register
> +  of an external MDI compliant device (e.g. PHY 100), and return
> +  it to the calling routine.  The command will execute in polled mode.
> +
> +  @param  AdapterInfo                     pointer to the structure that contains
> +                                          the NIC's context.
> +  @param  RegAddress                      The MII register that we are reading
> from
> +  @param  PhyAddress                      The MDI address of the Phy component.
> +  @param  DataValue                       pointer to the value that we read from
> +                                          the MII register.
> +
> +
> +**/
> +VOID
> +MdiRead (
> +  IN NIC_DATA_INSTANCE *AdapterInfo,
> +  IN UINT8             RegAddress,
> +  IN UINT8             PhyAddress,
> +  IN OUT UINT16        *DataValue
> +  )
> +{
> +  UINT32  ReadCommand;
> +
> +  ReadCommand = ((UINT32) (RegAddress << 16)) |
> +                ((UINT32) (PhyAddress << 21)) |
> +                ((UINT32) (MDI_READ << 26));
> +
> +  //
> +  // Issue the read command to the MDI control register.
> +  //
> +  OutLong (AdapterInfo, ReadCommand, AdapterInfo->ioaddr + SCBCtrlMDI);
> +
> +  //
> +  // wait 20usec before checking status
> +  //
> +  DelayIt (AdapterInfo, 20);
> +
> +  //
> +  // poll for the mdi read to complete
> +  //
> +  while ((InLong (AdapterInfo, AdapterInfo->ioaddr + SCBCtrlMDI) &
> +          MDI_PHY_READY) == 0) {
> +    DelayIt (AdapterInfo, 20);
> +
> +  }
> +
> +  *DataValue = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBCtrlMDI);
> +}
> +
> +
> +/**
> +  This routine will reset the PHY that the adapter is currently
> +  configured to use.
> +
> +  @param  AdapterInfo                     pointer to the structure that contains
> +                                          the NIC's context.
> +
> +
> +**/
> +VOID
> +PhyReset (
> +  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  UINT16  MdiControlReg;
> +
> +  MdiControlReg = (MDI_CR_AUTO_SELECT |
> +                  MDI_CR_RESTART_AUTO_NEG |
> +                  MDI_CR_RESET);
> +
> +  //
> +  // Write the MDI control register with our new Phy configuration
> +  //
> +  MdiWrite (
> +    AdapterInfo,
> +    MDI_CONTROL_REG,
> +    AdapterInfo->PhyAddress,
> +    MdiControlReg
> +    );
> +
> +  return ;
> +}
> +
> +
> +/**
> +  This routine will detect what phy we are using, set the line
> +  speed, FDX or HDX, and configure the phy if necessary.
> +  The following combinations are supported:
> +  - TX or T4 PHY alone at PHY address 1
> +  - T4 or TX PHY at address 1 and MII PHY at address 0
> +  - 82503 alone (10Base-T mode, no full duplex support)
> +  - 82503 and MII PHY (TX or T4) at address 0
> +  The sequence / priority of detection is as follows:
> +  - PHY 1 with cable termination
> +  - PHY 0 with cable termination
> +  - PHY 1 (if found) without cable termination
> +  - 503 interface
> +  Additionally auto-negotiation capable (NWAY) and parallel
> +  detection PHYs are supported. The flow-chart is described in
> +  the 82557 software writer's manual.
> +  NOTE:  1.  All PHY MDI registers are read in polled mode.
> +  2.  The routines assume that the 82557 has been RESET and we have
> +  obtained the virtual memory address of the CSR.
> +  3.  PhyDetect will not RESET the PHY.
> +  4.  If FORCEFDX is set, SPEED should also be set. The driver will
> +  check the values for inconsistency with the detected PHY
> +  technology.
> +  5.  PHY 1 (the PHY on the adapter) may have an address in the range
> +  1 through 31 inclusive. The driver will accept addresses in
> +  this range.
> +  6.  Driver ignores FORCEFDX and SPEED overrides if a 503 interface
> +  is detected.
> +
> +  @param  AdapterInfo                     pointer to the structure that contains
> +                                          the NIC's context.
> +
> +  @retval TRUE                            If a Phy was detected, and configured
> +                                          correctly.
> +  @retval FALSE                           If a valid phy could not be detected and
> +                                          configured.
> +
> +**/
> +BOOLEAN
> +PhyDetect (
> +  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  UINT16  *eedata;
> +  UINT16  MdiControlReg;
> +  UINT16  MdiStatusReg;
> +  BOOLEAN FoundPhy1;
> +  UINT8   ReNegotiateTime;
> +
> +  eedata          = (UINT16 *) (&AdapterInfo->NVData[0]);
> +
> +  FoundPhy1       = FALSE;
> +  ReNegotiateTime = 35;
> +  //
> +  // EEPROM word [6] contains the Primary PHY record in which the least 3
> bits
> +  // indicate the PHY address
> +  // and word [7] contains the secondary PHY record
> +  //
> +  AdapterInfo->PhyRecord[0] = eedata[6];
> +  AdapterInfo->PhyRecord[1] = eedata[7];
> +  AdapterInfo->PhyAddress   = (UINT8) (AdapterInfo->PhyRecord[0] & 7);
> +
> +  //
> +  // Check for a phy address over-ride of 32 which indicates force use of
> 82503
> +  // not detecting the link in this case
> +  //
> +  if (AdapterInfo->PhyAddress == 32) {
> +    //
> +    // 503 interface over-ride
> +    // Record the current speed and duplex.  We will be in half duplex
> +    // mode unless the user used the force full duplex over-ride.
> +    //
> +    AdapterInfo->LinkSpeed = 10;
> +    return (TRUE);
> +  }
> +
> +  //
> +  // If the Phy Address is between 1-31 then we must first look for phy 1,
> +  // at that address.
> +  //
> +  if ((AdapterInfo->PhyAddress > 0) && (AdapterInfo->PhyAddress < 32)) {
> +
> +    //
> +    // Read the MDI control and status registers at phy 1
> +    // and check if we found a valid phy
> +    //
> +    MdiRead (
> +      AdapterInfo,
> +      MDI_CONTROL_REG,
> +      AdapterInfo->PhyAddress,
> +      &MdiControlReg
> +      );
> +
> +    MdiRead (
> +      AdapterInfo,
> +      MDI_STATUS_REG,
> +      AdapterInfo->PhyAddress,
> +      &MdiStatusReg
> +      );
> +
> +    if (!((MdiControlReg == 0xffff) ||
> +          ((MdiStatusReg == 0) && (MdiControlReg == 0)))) {
> +
> +      //
> +      // we have a valid phy1
> +      // Read the status register again because of sticky bits
> +      //
> +      FoundPhy1 = TRUE;
> +      MdiRead (
> +        AdapterInfo,
> +        MDI_STATUS_REG,
> +        AdapterInfo->PhyAddress,
> +        &MdiStatusReg
> +        );
> +
> +      //
> +      // If there is a valid link then use this Phy.
> +      //
> +      if (MdiStatusReg & MDI_SR_LINK_STATUS) {
> +        return (SetupPhy(AdapterInfo));
> +      }
> +    }
> +  }
> +
> +  //
> +  // Next try to detect a PHY at address 0x00 because there was no Phy 1,
> +  // or Phy 1 didn't have link, or we had a phy 0 over-ride
> +  //
> +
> +  //
> +  // Read the MDI control and status registers at phy 0
> +  //
> +  MdiRead (AdapterInfo, MDI_CONTROL_REG, 0, &MdiControlReg);
> +  MdiRead (AdapterInfo, MDI_STATUS_REG, 0, &MdiStatusReg);
> +
> +  //
> +  // check if we found a valid phy 0
> +  //
> +  if (((MdiControlReg == 0xffff) ||
> +       ((MdiStatusReg == 0) && (MdiControlReg == 0)))) {
> +
> +    //
> +    // we don't have a valid phy at address 0
> +    // if phy address was forced to 0, then error out because we
> +    // didn't find a phy at that address
> +    //
> +    if (AdapterInfo->PhyAddress == 0x0000) {
> +      return (FALSE);
> +    } else {
> +      //
> +      // at this point phy1 does not have link and there is no phy 0 at all
> +      // if we are forced to detect the cable, error out here!
> +      //
> +      if (AdapterInfo->CableDetect != 0) {
> +        return FALSE;
> +
> +      }
> +
> +      if (FoundPhy1) {
> +        //
> +        // no phy 0, but there is a phy 1 (no link I guess), so use phy 1
> +        //
> +        return SetupPhy (AdapterInfo);
> +      } else {
> +        //
> +        // didn't find phy 0 or phy 1, so assume a 503 interface
> +        //
> +        AdapterInfo->PhyAddress = 32;
> +
> +        //
> +        // Record the current speed and duplex.  We'll be in half duplex
> +        // mode unless the user used the force full duplex over-ride.
> +        //
> +        AdapterInfo->LinkSpeed = 10;
> +        return (TRUE);
> +      }
> +    }
> +  } else {
> +    //
> +    // We have a valid phy at address 0.  If phy 0 has a link then we use
> +    // phy 0.  If Phy 0 doesn't have a link then we use Phy 1 (no link)
> +    // if phy 1 is present, or phy 0 if phy 1 is not present
> +    // If phy 1 was present, then we must isolate phy 1 before we enable
> +    // phy 0 to see if Phy 0 has a link.
> +    //
> +    if (FoundPhy1) {
> +      //
> +      // isolate phy 1
> +      //
> +      MdiWrite (
> +        AdapterInfo,
> +        MDI_CONTROL_REG,
> +        AdapterInfo->PhyAddress,
> +        MDI_CR_ISOLATE
> +        );
> +
> +      //
> +      // wait 100 microseconds for the phy to isolate.
> +      //
> +      DelayIt (AdapterInfo, 100);
> +    }
> +
> +    //
> +    // Since this Phy is at address 0, we must enable it.  So clear
> +    // the isolate bit, and set the auto-speed select bit
> +    //
> +    MdiWrite (
> +      AdapterInfo,
> +      MDI_CONTROL_REG,
> +      0,
> +      MDI_CR_AUTO_SELECT
> +      );
> +
> +    //
> +    // wait 100 microseconds for the phy to be enabled.
> +    //
> +    DelayIt (AdapterInfo, 100);
> +
> +    //
> +    // restart the auto-negotion process
> +    //
> +    MdiWrite (
> +      AdapterInfo,
> +      MDI_CONTROL_REG,
> +      0,
> +      MDI_CR_RESTART_AUTO_NEG | MDI_CR_AUTO_SELECT
> +      );
> +
> +    //
> +    // wait no more than 3.5 seconds for auto-negotiation to complete
> +    //
> +    while (ReNegotiateTime) {
> +      //
> +      // Read the status register twice because of sticky bits
> +      //
> +      MdiRead (AdapterInfo, MDI_STATUS_REG, 0, &MdiStatusReg);
> +      MdiRead (AdapterInfo, MDI_STATUS_REG, 0, &MdiStatusReg);
> +
> +      if (MdiStatusReg & MDI_SR_AUTO_NEG_COMPLETE) {
> +        break;
> +      }
> +
> +      DelayIt (AdapterInfo, 100);
> +      ReNegotiateTime--;
> +    }
> +
> +    //
> +    // Read the status register again because of sticky bits
> +    //
> +    MdiRead (AdapterInfo, MDI_STATUS_REG, 0, &MdiStatusReg);
> +
> +    //
> +    // If the link was not set
> +    //
> +    if ((MdiStatusReg & MDI_SR_LINK_STATUS) == 0) {
> +      //
> +      // PHY1 does not have a link and phy 0 does not have a link
> +      // do not proceed if we need to detect the link!
> +      //
> +      if (AdapterInfo->CableDetect != 0) {
> +        return FALSE;
> +      }
> +
> +      //
> +      // the link wasn't set, so use phy 1 if phy 1 was present
> +      //
> +      if (FoundPhy1) {
> +        //
> +        // isolate phy 0
> +        //
> +        MdiWrite (AdapterInfo, MDI_CONTROL_REG, 0, MDI_CR_ISOLATE);
> +
> +        //
> +        // wait 100 microseconds for the phy to isolate.
> +        //
> +        DelayIt (AdapterInfo, 100);
> +
> +        //
> +        // Now re-enable PHY 1
> +        //
> +        MdiWrite (
> +          AdapterInfo,
> +          MDI_CONTROL_REG,
> +          AdapterInfo->PhyAddress,
> +          MDI_CR_AUTO_SELECT
> +          );
> +
> +        //
> +        // wait 100 microseconds for the phy to be enabled
> +        //
> +        DelayIt (AdapterInfo, 100);
> +
> +        //
> +        // restart the auto-negotion process
> +        //
> +        MdiWrite (
> +          AdapterInfo,
> +          MDI_CONTROL_REG,
> +          AdapterInfo->PhyAddress,
> +          MDI_CR_RESTART_AUTO_NEG | MDI_CR_AUTO_SELECT
> +          );
> +
> +        //
> +        // Don't wait for it to complete (we didn't have link earlier)
> +        //
> +        return (SetupPhy (AdapterInfo));
> +      }
> +    }
> +
> +    //
> +    // Definitely using Phy 0
> +    //
> +    AdapterInfo->PhyAddress = 0;
> +    return (SetupPhy(AdapterInfo));
> +  }
> +}
> +
> +
> +/**
> +  This routine will setup phy 1 or phy 0 so that it is configured
> +  to match a speed and duplex over-ride option.  If speed or
> +  duplex mode is not explicitly specified in the registry, the
> +  driver will skip the speed and duplex over-ride code, and
> +  assume the adapter is automatically setting the line speed, and
> +  the duplex mode.  At the end of this routine, any truly Phy
> +  specific code will be executed (each Phy has its own quirks,
> +  and some require that certain special bits are set).
> +  NOTE:  The driver assumes that SPEED and FORCEFDX are specified at the
> +  same time. If FORCEDPX is set without speed being set, the driver
> +  will encouter a fatal error and log a message into the event viewer.
> +
> +  @param  AdapterInfo                     pointer to the structure that contains
> +                                          the NIC's context.
> +
> +  @retval TRUE                            If the phy could be configured correctly
> +  @retval FALSE                           If the phy couldn't be configured
> +                                          correctly, because an unsupported
> +                                          over-ride option was used
> +
> +**/
> +BOOLEAN
> +SetupPhy (
> +  IN NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  UINT16  MdiControlReg;
> +  UINT16  MdiStatusReg;
> +  UINT16  MdiIdLowReg;
> +  UINT16  MdiIdHighReg;
> +  UINT16  MdiMiscReg;
> +  UINT32  PhyId;
> +  BOOLEAN ForcePhySetting;
> +
> +  ForcePhySetting = FALSE;
> +
> +  //
> +  // If we are NOT forcing a setting for line speed or full duplex, then
> +  // we won't force a link setting, and we'll jump down to the phy
> +  // specific code.
> +  //
> +  if (((AdapterInfo->LinkSpeedReq) || (AdapterInfo->DuplexReq))) {
> +    //
> +    // Find out what kind of technology this Phy is capable of.
> +    //
> +    MdiRead (
> +      AdapterInfo,
> +      MDI_STATUS_REG,
> +      AdapterInfo->PhyAddress,
> +      &MdiStatusReg
> +      );
> +
> +    //
> +    // Read the MDI control register at our phy
> +    //
> +    MdiRead (
> +      AdapterInfo,
> +      MDI_CONTROL_REG,
> +      AdapterInfo->PhyAddress,
> +      &MdiControlReg
> +      );
> +
> +    //
> +    // Now check the validity of our forced option.  If the force option is
> +    // valid, then force the setting.  If the force option is not valid,
> +    // we'll set a flag indicating that we should error out.
> +    //
> +
> +    //
> +    // If speed is forced to 10mb
> +    //
> +    if (AdapterInfo->LinkSpeedReq == 10) {
> +      //
> +      // If half duplex is forced
> +      //
> +      if ((AdapterInfo->DuplexReq & PXE_FORCE_HALF_DUPLEX) != 0) {
> +        if (MdiStatusReg & MDI_SR_10T_HALF_DPX) {
> +
> +          MdiControlReg &= ~(MDI_CR_10_100 | MDI_CR_AUTO_SELECT |
> MDI_CR_FULL_HALF);
> +          ForcePhySetting = TRUE;
> +        }
> +      } else if ((AdapterInfo->DuplexReq & PXE_FORCE_FULL_DUPLEX) != 0) {
> +
> +        //
> +        // If full duplex is forced
> +        //
> +        if (MdiStatusReg & MDI_SR_10T_FULL_DPX) {
> +
> +          MdiControlReg &= ~(MDI_CR_10_100 | MDI_CR_AUTO_SELECT);
> +          MdiControlReg |= MDI_CR_FULL_HALF;
> +          ForcePhySetting = TRUE;
> +        }
> +      } else {
> +        //
> +        // If auto duplex (we actually set phy to 1/2)
> +        //
> +        if (MdiStatusReg & (MDI_SR_10T_FULL_DPX | MDI_SR_10T_HALF_DPX))
> {
> +
> +          MdiControlReg &= ~(MDI_CR_10_100 | MDI_CR_AUTO_SELECT |
> MDI_CR_FULL_HALF);
> +          ForcePhySetting = TRUE;
> +        }
> +      }
> +    }
> +
> +    //
> +    // If speed is forced to 100mb
> +    //
> +    else if (AdapterInfo->LinkSpeedReq == 100) {
> +      //
> +      // If half duplex is forced
> +      //
> +      if ((AdapterInfo->DuplexReq & PXE_FORCE_HALF_DUPLEX) != 0) {
> +        if (MdiStatusReg & (MDI_SR_TX_HALF_DPX | MDI_SR_T4_CAPABLE)) {
> +
> +          MdiControlReg &= ~(MDI_CR_AUTO_SELECT | MDI_CR_FULL_HALF);
> +          MdiControlReg |= MDI_CR_10_100;
> +          ForcePhySetting = TRUE;
> +        }
> +      } else if ((AdapterInfo->DuplexReq & PXE_FORCE_FULL_DUPLEX) != 0) {
> +        //
> +        // If full duplex is forced
> +        //
> +        if (MdiStatusReg & MDI_SR_TX_FULL_DPX) {
> +          MdiControlReg &= ~MDI_CR_AUTO_SELECT;
> +          MdiControlReg |= (MDI_CR_10_100 | MDI_CR_FULL_HALF);
> +          ForcePhySetting = TRUE;
> +        }
> +      } else {
> +        //
> +        // If auto duplex (we set phy to 1/2)
> +        //
> +        if (MdiStatusReg & (MDI_SR_TX_HALF_DPX | MDI_SR_T4_CAPABLE)) {
> +
> +          MdiControlReg &= ~(MDI_CR_AUTO_SELECT | MDI_CR_FULL_HALF);
> +          MdiControlReg |= MDI_CR_10_100;
> +          ForcePhySetting = TRUE;
> +        }
> +      }
> +    }
> +
> +    if (!ForcePhySetting) {
> +      return (FALSE);
> +    }
> +
> +    //
> +    // Write the MDI control register with our new Phy configuration
> +    //
> +    MdiWrite (
> +      AdapterInfo,
> +      MDI_CONTROL_REG,
> +      AdapterInfo->PhyAddress,
> +      MdiControlReg
> +      );
> +
> +    //
> +    // wait 100 milliseconds for auto-negotiation to complete
> +    //
> +    DelayIt (AdapterInfo, 100);
> +  }
> +
> +  //
> +  // Find out specifically what Phy this is.  We do this because for certain
> +  // phys there are specific bits that must be set so that the phy and the
> +  // 82557 work together properly.
> +  //
> +
> +  MdiRead (
> +    AdapterInfo,
> +    PHY_ID_REG_1,
> +    AdapterInfo->PhyAddress,
> +    &MdiIdLowReg
> +    );
> +  MdiRead (
> +    AdapterInfo,
> +    PHY_ID_REG_2,
> +    AdapterInfo->PhyAddress,
> +    &MdiIdHighReg
> +    );
> +
> +  PhyId = ((UINT32) MdiIdLowReg | ((UINT32) MdiIdHighReg << 16));
> +
> +  //
> +  // And out the revsion field of the Phy ID so that we'll be able to detect
> +  // future revs of the same Phy.
> +  //
> +  PhyId &= PHY_MODEL_REV_ID_MASK;
> +
> +  //
> +  // Handle the National TX
> +  //
> +  if (PhyId == PHY_NSC_TX) {
> +
> +    MdiRead (
> +      AdapterInfo,
> +      NSC_CONG_CONTROL_REG,
> +      AdapterInfo->PhyAddress,
> +      &MdiMiscReg
> +      );
> +
> +    MdiMiscReg |= (NSC_TX_CONG_TXREADY | NSC_TX_CONG_F_CONNECT);
> +
> +    MdiWrite (
> +      AdapterInfo,
> +      NSC_CONG_CONTROL_REG,
> +      AdapterInfo->PhyAddress,
> +      MdiMiscReg
> +      );
> +  }
> +
> +  FindPhySpeedAndDpx (AdapterInfo, PhyId);
> +
> +  //
> +  // We put a hardware fix on to our adapters to work-around the PHY_100
> errata
> +  // described below.  The following code is only compiled in, if we wanted
> +  // to attempt a software workaround to the PHY_100 A/B step problem.
> +  //
> +
> +  return (TRUE);
> +}
> +
> +
> +/**
> +  This routine will figure out what line speed and duplex mode
> +  the PHY is currently using.
> +
> +  @param  AdapterInfo                     pointer to the structure that contains
> +                                          the NIC's context.
> +  @param  PhyId                           The ID of the PHY in question.
> +
> +  @return NOTHING
> +
> +**/
> +VOID
> +FindPhySpeedAndDpx (
> +  IN NIC_DATA_INSTANCE *AdapterInfo,
> +  IN UINT32            PhyId
> +  )
> +{
> +  UINT16  MdiStatusReg;
> +  UINT16  MdiMiscReg;
> +  UINT16  MdiOwnAdReg;
> +  UINT16  MdiLinkPartnerAdReg;
> +
> +  //
> +  // If there was a speed and/or duplex override, then set our current
> +  // value accordingly
> +  //
> +  AdapterInfo->LinkSpeed  = AdapterInfo->LinkSpeedReq;
> +  AdapterInfo->Duplex = (UINT8) ((AdapterInfo->DuplexReq &
> PXE_FORCE_FULL_DUPLEX) ?
> +                        FULL_DUPLEX : HALF_DUPLEX);
> +
> +  //
> +  // If speed and duplex were forced, then we know our current settings, so
> +  // we'll just return.  Otherwise, we'll need to figure out what NWAY set
> +  // us to.
> +  //
> +  if (AdapterInfo->LinkSpeed && AdapterInfo->Duplex) {
> +    return ;
> +
> +  }
> +  //
> +  // If we didn't have a valid link, then we'll assume that our current
> +  // speed is 10mb half-duplex.
> +  //
> +
> +  //
> +  // Read the status register twice because of sticky bits
> +  //
> +  MdiRead (
> +    AdapterInfo,
> +    MDI_STATUS_REG,
> +    AdapterInfo->PhyAddress,
> +    &MdiStatusReg
> +    );
> +  MdiRead (
> +    AdapterInfo,
> +    MDI_STATUS_REG,
> +    AdapterInfo->PhyAddress,
> +    &MdiStatusReg
> +    );
> +
> +  //
> +  // If there wasn't a valid link then use default speed & duplex
> +  //
> +  if (!(MdiStatusReg & MDI_SR_LINK_STATUS)) {
> +
> +    AdapterInfo->LinkSpeed  = 10;
> +    AdapterInfo->Duplex     = HALF_DUPLEX;
> +    return ;
> +  }
> +
> +  //
> +  // If this is an Intel PHY (a T4 PHY_100 or a TX PHY_TX), then read bits
> +  // 1 and 0 of extended register 0, to get the current speed and duplex
> +  // settings.
> +  //
> +  if ((PhyId == PHY_100_A) || (PhyId == PHY_100_C) || (PhyId ==
> PHY_TX_ID)) {
> +    //
> +    // Read extended register 0
> +    //
> +    MdiRead (
> +      AdapterInfo,
> +      EXTENDED_REG_0,
> +      AdapterInfo->PhyAddress,
> +      &MdiMiscReg
> +      );
> +
> +    //
> +    // Get current speed setting
> +    //
> +    if (MdiMiscReg & PHY_100_ER0_SPEED_INDIC) {
> +      AdapterInfo->LinkSpeed = 100;
> +    } else {
> +      AdapterInfo->LinkSpeed = 10;
> +    }
> +
> +    //
> +    // Get current duplex setting -- if bit is set then FDX is enabled
> +    //
> +    if (MdiMiscReg & PHY_100_ER0_FDX_INDIC) {
> +      AdapterInfo->Duplex = FULL_DUPLEX;
> +    } else {
> +      AdapterInfo->Duplex = HALF_DUPLEX;
> +    }
> +
> +    return ;
> +  }
> +  //
> +  // Read our link partner's advertisement register
> +  //
> +  MdiRead (
> +    AdapterInfo,
> +    AUTO_NEG_LINK_PARTNER_REG,
> +    AdapterInfo->PhyAddress,
> +    &MdiLinkPartnerAdReg
> +    );
> +
> +  //
> +  // See if Auto-Negotiation was complete (bit 5, reg 1)
> +  //
> +  MdiRead (
> +    AdapterInfo,
> +    MDI_STATUS_REG,
> +    AdapterInfo->PhyAddress,
> +    &MdiStatusReg
> +    );
> +
> +  //
> +  // If a True NWAY connection was made, then we can detect speed/duplex
> by
> +  // ANDing our adapter's advertised abilities with our link partner's
> +  // advertised ablilities, and then assuming that the highest common
> +  // denominator was chosed by NWAY.
> +  //
> +  if ((MdiLinkPartnerAdReg & NWAY_LP_ABILITY) &&
> +      (MdiStatusReg & MDI_SR_AUTO_NEG_COMPLETE)) {
> +
> +    //
> +    // Read our advertisement register
> +    //
> +    MdiRead (
> +      AdapterInfo,
> +      AUTO_NEG_ADVERTISE_REG,
> +      AdapterInfo->PhyAddress,
> +      &MdiOwnAdReg
> +      );
> +
> +    //
> +    // AND the two advertisement registers together, and get rid of any
> +    // extraneous bits.
> +    //
> +    MdiOwnAdReg = (UINT16) (MdiOwnAdReg & (MdiLinkPartnerAdReg &
> NWAY_LP_ABILITY));
> +
> +    //
> +    // Get speed setting
> +    //
> +    if (MdiOwnAdReg & (NWAY_AD_TX_HALF_DPX |
> NWAY_AD_TX_FULL_DPX | NWAY_AD_T4_CAPABLE)) {
> +      AdapterInfo->LinkSpeed = 100;
> +    } else {
> +      AdapterInfo->LinkSpeed = 10;
> +    }
> +
> +    //
> +    // Get duplex setting -- use priority resolution algorithm
> +    //
> +    if (MdiOwnAdReg & (NWAY_AD_T4_CAPABLE)) {
> +      AdapterInfo->Duplex = HALF_DUPLEX;
> +      return ;
> +    } else if (MdiOwnAdReg & (NWAY_AD_TX_FULL_DPX)) {
> +      AdapterInfo->Duplex = FULL_DUPLEX;
> +      return ;
> +    } else if (MdiOwnAdReg & (NWAY_AD_TX_HALF_DPX)) {
> +      AdapterInfo->Duplex = HALF_DUPLEX;
> +      return ;
> +    } else if (MdiOwnAdReg & (NWAY_AD_10T_FULL_DPX)) {
> +      AdapterInfo->Duplex = FULL_DUPLEX;
> +      return ;
> +    } else {
> +      AdapterInfo->Duplex = HALF_DUPLEX;
> +      return ;
> +    }
> +  }
> +
> +  //
> +  // If we are connected to a dumb (non-NWAY) repeater or hub, and the
> line
> +  // speed was determined automatically by parallel detection, then we
> have
> +  // no way of knowing exactly what speed the PHY is set to unless that PHY
> +  // has a propietary register which indicates speed in this situation.  The
> +  // NSC TX PHY does have such a register.  Also, since NWAY didn't establish
> +  // the connection, the duplex setting should HALF duplex.
> +  //
> +  AdapterInfo->Duplex = HALF_DUPLEX;
> +
> +  if (PhyId == PHY_NSC_TX) {
> +    //
> +    // Read register 25 to get the SPEED_10 bit
> +    //
> +    MdiRead (
> +      AdapterInfo,
> +      NSC_SPEED_IND_REG,
> +      AdapterInfo->PhyAddress,
> +      &MdiMiscReg
> +      );
> +
> +    //
> +    // If bit 6 was set then we're at 10mb
> +    //
> +    if (MdiMiscReg & NSC_TX_SPD_INDC_SPEED) {
> +      AdapterInfo->LinkSpeed = 10;
> +    } else {
> +      AdapterInfo->LinkSpeed = 100;
> +    }
> +  }
> +
> +  //
> +  // If we don't know what line speed we are set at, then we'll default to
> +  // 10mbs
> +  //
> +  else {
> +    AdapterInfo->LinkSpeed = 10;
> +  }
> +}
> +
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  AdapterInfo                     TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +VOID
> +XmitWaitForCompletion (
> +  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  TxCB  *TxPtr;
> +
> +  if (AdapterInfo->FreeCBCount == AdapterInfo->TxBufCnt) {
> +    return ;
> +  }
> +
> +  //
> +  // used xmit cb list starts right after the free tail (ends before the
> +  // free head ptr)
> +  //
> +  TxPtr = AdapterInfo->FreeTxTailPtr->NextTCBVirtualLinkPtr;
> +  while (TxPtr != AdapterInfo->FreeTxHeadPtr) {
> +    CommandWaitForCompletion (TxPtr, AdapterInfo);
> +    SetFreeCB (AdapterInfo, TxPtr);
> +    TxPtr = TxPtr->NextTCBVirtualLinkPtr;
> +  }
> +}
> +
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  cmd_ptr                         TODO: add argument description
> +  @param  AdapterInfo                     TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +INT8
> +CommandWaitForCompletion (
> +  TxCB              *cmd_ptr,
> +  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  INT16 wait;
> +  wait = 5000;
> +  while ((cmd_ptr->cb_header.status == 0) && (--wait > 0)) {
> +    DelayIt (AdapterInfo, 10);
> +  }
> +
> +  if (cmd_ptr->cb_header.status == 0) {
> +    return -1;
> +  }
> +
> +  return 0;
> +}
> +
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  AdapterInfo                     TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +INT8
> +SoftwareReset (
> +  NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  UINT8   tco_stat;
> +  UINT16  wait;
> +
> +  tco_stat = 0;
> +
> +  //
> +  // Reset the chip: stop Tx and Rx processes and clear counters.
> +  // This takes less than 10usec and will easily finish before the next
> +  // action.
> +  //
> +
> +  OutLong (AdapterInfo, PORT_RESET, AdapterInfo->ioaddr + SCBPort);
> +  //
> +  // wait for 5 milli seconds here!
> +  //
> +  DelayIt (AdapterInfo, 5000);
> +  //
> +  // TCO Errata work around for 559s only
> +  // -----------------------------------------------------------------------------------
> +  // TCO Workaround Code
> +  //  haifa workaround
> +  // -----------------------------------------------------------------------------------
> +  //    1. Issue SW-RST ^^^ (already done above)
> +  //    2. Issue a redundant Set CU Base CMD immediately
> +  //       Do not set the General Pointer before the Set CU Base cycle
> +  //       Do not check the SCB CMD before the Set CU Base cycle
> +  //    3. Wait for the SCB-CMD to be cleared
> +  //       this indicates the transition to post-driver
> +  //    4. Poll the TCO-Req bit in the PMDR to be cleared
> +  //       this indicates the tco activity has stopped for real
> +  //    5. Proceed with the nominal Driver Init:
> +  //       Actual Set CU & RU Base ...
> +  //
> +  // Check for ICH2 device ID.  If this is an ICH2,
> +  // do the TCO workaround code.
> +  //
> +  if (AdapterInfo->VendorID == D102_DEVICE_ID ||
> +      AdapterInfo->VendorID == ICH3_DEVICE_ID_1 ||
> +      AdapterInfo->VendorID == ICH3_DEVICE_ID_2 ||
> +      AdapterInfo->VendorID == ICH3_DEVICE_ID_3 ||
> +      AdapterInfo->VendorID == ICH3_DEVICE_ID_4 ||
> +      AdapterInfo->VendorID == ICH3_DEVICE_ID_5 ||
> +      AdapterInfo->VendorID == ICH3_DEVICE_ID_6 ||
> +      AdapterInfo->VendorID == ICH3_DEVICE_ID_7 ||
> +      AdapterInfo->VendorID == ICH3_DEVICE_ID_8 ||
> +      AdapterInfo->RevID >= 8) {  // do the TCO fix
> +    //
> +    // donot load the scb pointer but just give load_cu cmd.
> +    //
> +    OutByte (AdapterInfo, CU_CMD_BASE, AdapterInfo->ioaddr + SCBCmd);
> +    //
> +    // wait for command to be accepted.
> +    //
> +    wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
> +    //
> +    // read PMDR register and check bit 1 in it to see if TCO is active
> +    //
> +
> +    //
> +    // wait for 5 milli seconds
> +    //
> +    wait = 5000;
> +    while (wait) {
> +      tco_stat = InByte (AdapterInfo, AdapterInfo->ioaddr + 0x1b);
> +      if ((tco_stat & 2) == 0) {
> +        //
> +        // is the activity bit clear??
> +        //
> +        break;
> +      }
> +
> +      wait--;
> +      DelayIt (AdapterInfo, 1);
> +    }
> +
> +    if ((tco_stat & 2) != 0) {
> +      //
> +      // not zero??
> +      //
> +      return -1;
> +    }
> +  }
> +
> +  return 0;
> +}
> +
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  AdapterInfo                     TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +UINT8
> +SelectiveReset (
> +  IN NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  UINT16  wait;
> +  UINT32  stat;
> +
> +  wait  = 10;
> +  stat  = 0;
> +  OutLong (AdapterInfo, POR_SELECTIVE_RESET, AdapterInfo->ioaddr +
> SCBPort);
> +  //
> +  // wait for this to complete
> +  //
> +
> +  //
> +  // wait for 2 milli seconds here!
> +  //
> +  DelayIt (AdapterInfo, 2000);
> +  while (wait > 0) {
> +    wait--;
> +    stat = InLong (AdapterInfo, AdapterInfo->ioaddr + SCBPort);
> +    if (stat == 0) {
> +      break;
> +    }
> +
> +    //
> +    // wait for 1 milli second
> +    //
> +    DelayIt (AdapterInfo, 1000);
> +  }
> +
> +  if (stat != 0) {
> +    return PXE_STATCODE_DEVICE_FAILURE;
> +  }
> +
> +  return 0;
> +}
> +
> +
> +/**
> +  TODO: Add function description
> +
> +  @param  AdapterInfo                     TODO: add argument description
> +
> +  @return TODO: add return values
> +
> +**/
> +UINT16
> +InitializeChip (
> +  IN NIC_DATA_INSTANCE *AdapterInfo
> +  )
> +{
> +  UINT16  ret_val;
> +  if (SoftwareReset (AdapterInfo) != 0) {
> +    return PXE_STATCODE_DEVICE_FAILURE;
> +  }
> +
> +  //
> +  // disable interrupts
> +  //
> +  OutWord (AdapterInfo, INT_MASK, AdapterInfo->ioaddr + SCBCmd);
> +
> +  //
> +  // Load the base registers with 0s (we will give the complete address as
> +  // offset later when we issue any command
> +  //
> +  if ((ret_val = Load_Base_Regs (AdapterInfo)) != 0) {
> +    return ret_val;
> +  }
> +
> +  if ((ret_val = SetupCBlink (AdapterInfo)) != 0) {
> +    return ret_val;
> +  }
> +
> +  if ((ret_val = SetupReceiveQueues (AdapterInfo)) != 0) {
> +    return ret_val;
> +  }
> +
> +  //
> +  // detect the PHY only if we need to detect the cable as requested by the
> +  // initialize parameters
> +  //
> +  AdapterInfo->PhyAddress = 0xFF;
> +
> +  if (AdapterInfo->CableDetect != 0) {
> +    if (!PhyDetect (AdapterInfo)) {
> +      return PXE_STATCODE_DEVICE_FAILURE;
> +    }
> +  }
> +
> +  if ((ret_val = E100bSetupIAAddr (AdapterInfo)) != 0) {
> +    return ret_val;
> +  }
> +
> +  if ((ret_val = Configure (AdapterInfo)) != 0) {
> +    return ret_val;
> +  }
> +
> +  return 0;
> +}
> diff --git a/Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h
> b/Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h
> new file mode 100644
> index 0000000000..18ff7aa94d
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h
> @@ -0,0 +1,665 @@
> +/** @file
> +  Definitions for network adapter card.
> +
> +Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _E100B_H_
> +#define _E100B_H_
> +
> +// pci config offsets:
> +
> +#define RX_BUFFER_COUNT 32
> +#define TX_BUFFER_COUNT 32
> +
> +#define PCI_VENDOR_ID_INTEL 0x8086
> +#define PCI_DEVICE_ID_INTEL_82557 0x1229
> +#define D100_VENDOR_ID   0x8086
> +#define D100_DEVICE_ID   0x1229
> +#define D102_DEVICE_ID   0x2449
> +
> +#define ICH3_DEVICE_ID_1   0x1031
> +#define ICH3_DEVICE_ID_2   0x1032
> +#define ICH3_DEVICE_ID_3   0x1033
> +#define ICH3_DEVICE_ID_4   0x1034
> +#define ICH3_DEVICE_ID_5   0x1035
> +#define ICH3_DEVICE_ID_6   0x1036
> +#define ICH3_DEVICE_ID_7   0x1037
> +#define ICH3_DEVICE_ID_8   0x1038
> +
> +#define SPEEDO_DEVICE_ID   0x1227
> +#define SPLASH1_DEVICE_ID   0x1226
> +
> +
> +// bit fields for the command
> +#define PCI_COMMAND_MASTER  0x04  // bit 2
> +#define PCI_COMMAND_IO    0x01  // bit 0
> +#define PCI_COMMAND  0x04
> +#define PCI_LATENCY_TIMER  0x0D
> +
> +#define ETHER_MAC_ADDR_LEN 6
> +#ifdef AVL_XXX
> +#define ETHER_HEADER_LEN 14
> +// media interface type
> +// #define INTERFACE_TYPE "
> +
> +// Hardware type values
> +#define HW_ETHER_TYPE    1
> +#define HW_EXPERIMENTAL_ETHER_TYPE 2
> +#define HW_IEEE_TYPE    6
> +#define HW_ARCNET_TYPE     7
> +
> +#endif  // AVL_XXX
> +
> +#define MAX_ETHERNET_PKT_SIZE 1514  // including eth header
> +#define RX_BUFFER_SIZE 1536  // including crc and padding
> +#define TX_BUFFER_SIZE 64
> +#define ETH_MTU 1500  // does not include ethernet header length
> +
> +#define SPEEDO3_TOTAL_SIZE 0x20
> +
> +#pragma pack(1)
> +
> +typedef struct eth {
> +  UINT8 dest_addr[PXE_HWADDR_LEN_ETHER];
> +  UINT8 src_addr[PXE_HWADDR_LEN_ETHER];
> +  UINT16 type;
> +} EtherHeader;
> +
> +#pragma pack(1)
> +typedef struct CONFIG_HEADER {
> +  UINT16 VendorID;
> +  UINT16 DeviceID;
> +  UINT16 Command;
> +  UINT16 Status;
> +  UINT16 RevID;
> +  UINT16 ClassID;
> +  UINT8  CacheLineSize;
> +  UINT8  LatencyTimer;
> +  UINT8  HeaderType;    // must be zero to impose this structure...
> +  UINT8  BIST;  // built-in self test
> +  UINT32 BaseAddressReg_0;  // memory mapped address
> +  UINT32 BaseAddressReg_1;  //io mapped address, Base IO address
> +  UINT32 BaseAddressReg_2;  // option rom address
> +  UINT32 BaseAddressReg_3;
> +  UINT32 BaseAddressReg_4;
> +  UINT32 BaseAddressReg_5;
> +  UINT32 CardBusCISPtr;
> +  UINT16 SubVendorID;
> +  UINT16 SubSystemID;
> +  UINT32 ExpansionROMBaseAddr;
> +  UINT8 CapabilitiesPtr;
> +  UINT8 reserved1;
> +  UINT16 Reserved2;
> +  UINT32 Reserved3;
> +  UINT8 int_line;
> +  UINT8 int_pin;
> +  UINT8 Min_gnt;
> +  UINT8 Max_lat;
> +} PCI_CONFIG_HEADER;
> +#pragma pack()
> +
> +//-------------------------------------------------------------------------
> +// Offsets to the various registers.
> +//   All accesses need not be longword aligned.
> +//-------------------------------------------------------------------------
> +enum speedo_offsets {
> +  SCBStatus = 0, SCBCmd = 2,     // Rx/Command Unit command and status.
> +  SCBPointer = 4,                // General purpose pointer.
> +  SCBPort = 8,                   // Misc. commands and operands.
> +  SCBflash = 12, SCBeeprom = 14, // EEPROM and flash memory control.
> +  SCBCtrlMDI = 16,               // MDI interface control.
> +  SCBEarlyRx = 20,               // Early receive byte count.
> +  SCBEarlyRxInt = 24, SCBFlowCtrlReg = 25, SCBPmdr = 27,
> +  // offsets for general control registers (GCRs)
> +  SCBGenCtrl = 28, SCBGenStatus = 29, SCBGenCtrl2 = 30, SCBRsvd = 31
> +};
> +
> +#define GCR2_EEPROM_ACCESS_SEMAPHORE 0x80 // bit offset into the
> gcr2
> +
> +//-------------------------------------------------------------------------
> +// Action commands - Commands that can be put in a command list entry.
> +//-------------------------------------------------------------------------
> +enum commands {
> +  CmdNOp = 0, CmdIASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
> +  CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7,
> +  CmdSuspend = 0x4000,    /* Suspend after completion. */
> +  CmdIntr = 0x2000,      /* Interrupt after completion. */
> +  CmdTxFlex = 0x0008      /* Use "Flexible mode" for CmdTx command. */
> +};
> +
> +//-------------------------------------------------------------------------
> +// port commands
> +//-------------------------------------------------------------------------
> +#define PORT_RESET 0
> +#define PORT_SELF_TEST 1
> +#define POR_SELECTIVE_RESET 2
> +#define PORT_DUMP_POINTER 2
> +
> +//-------------------------------------------------------------------------
> +// SCB Command Word bit definitions
> +//-------------------------------------------------------------------------
> +//- CUC fields
> +#define   CU_START    0x0010
> +#define   CU_RESUME    0x0020
> +#define   CU_STATSADDR  0x0040
> +#define   CU_SHOWSTATS  0x0050  /* Dump statistics counters. */
> +#define   CU_CMD_BASE  0x0060  /* Base address to add to add CU
> commands. */
> +#define   CU_DUMPSTATS  0x0070  /* Dump then reset stats counters. */
> +
> +//- RUC fields
> +#define   RX_START  0x0001
> +#define   RX_RESUME  0x0002
> +#define   RX_ABORT  0x0004
> +#define   RX_ADDR_LOAD  0x0006  /* load ru_base_reg */
> +#define   RX_RESUMENR  0x0007
> +
> +// Interrupt fields (assuming byte addressing)
> +#define INT_MASK  0x0100
> +#define DRVR_INT  0x0200    /* Driver generated interrupt. */
> +
> +//- CB Status Word
> +#define CMD_STATUS_COMPLETE 0x8000
> +#define RX_STATUS_COMPLETE 0x8000
> +#define CMD_STATUS_MASK 0xF000
> +
> +//-------------------------------------------------------------------------
> +//- SCB Status bits:
> +// Interrupts are ACKed by writing to the upper 6 interrupt bits
> +//-------------------------------------------------------------------------
> +#define SCB_STATUS_MASK        0xFC00 // bits 2-7 - STATUS/ACK Mask
> +#define SCB_STATUS_CX_TNO      0x8000 // BIT_15  - CX or TNO Interrupt
> +#define SCB_STATUS_FR          0x4000 // BIT_14 - FR Interrupt
> +#define SCB_STATUS_CNA         0x2000 // BIT_13 - CNA Interrupt
> +#define SCB_STATUS_RNR         0x1000 // BIT_12  - RNR Interrupt
> +#define SCB_STATUS_MDI         0x0800 // BIT_11  - MDI R/W Done Interrupt
> +#define SCB_STATUS_SWI         0x0400 // BIT_10  - SWI Interrupt
> +
> +// CU STATUS: bits 6 & 7
> +#define SCB_STATUS_CU_MASK     0x00C0 // bits 6 & 7
> +#define SCB_STATUS_CU_IDLE     0x0000 // 00
> +#define SCB_STATUS_CU_SUSPEND  0x0040 // 01
> +#define SCB_STATUS_CU_ACTIVE   0x0080 // 10
> +
> +// RU STATUS: bits 2-5
> +#define SCB_RUS_IDLE         0x0000
> +#define SCB_RUS_SUSPENDED    0x0004  // bit 2
> +#define SCB_RUS_NO_RESOURCES   0x0008 // bit 3
> +#define SCB_RUS_READY       0x0010 // bit 4
> +
> +//-------------------------------------------------------------------------
> +// Bit Mask definitions
> +//-------------------------------------------------------------------------
> +#define BIT_0       0x0001
> +#define BIT_1       0x0002
> +#define BIT_2       0x0004
> +#define BIT_3       0x0008
> +#define BIT_4       0x0010
> +#define BIT_5       0x0020
> +#define BIT_6       0x0040
> +#define BIT_7       0x0080
> +#define BIT_8       0x0100
> +#define BIT_9       0x0200
> +#define BIT_10      0x0400
> +#define BIT_11      0x0800
> +#define BIT_12      0x1000
> +#define BIT_13      0x2000
> +#define BIT_14      0x4000
> +#define BIT_15      0x8000
> +#define BIT_24      0x01000000
> +#define BIT_28      0x10000000
> +
> +
> +//-------------------------------------------------------------------------
> +// MDI Control register bit definitions
> +//-------------------------------------------------------------------------
> +#define MDI_DATA_MASK           BIT_0_15        // MDI Data port
> +#define MDI_REG_ADDR            BIT_16_20       // which MDI register to
> read/write
> +#define MDI_PHY_ADDR            BIT_21_25       // which PHY to read/write
> +#define MDI_PHY_OPCODE          BIT_26_27       // which PHY to read/write
> +#define MDI_PHY_READY           BIT_28          // PHY is ready for another MDI
> cycle
> +#define MDI_PHY_INT_ENABLE      BIT_29          // Assert INT at MDI cycle
> completion
> +
> +#define BIT_0_2     0x0007
> +#define BIT_0_3     0x000F
> +#define BIT_0_4     0x001F
> +#define BIT_0_5     0x003F
> +#define BIT_0_6     0x007F
> +#define BIT_0_7     0x00FF
> +#define BIT_0_8     0x01FF
> +#define BIT_0_13    0x3FFF
> +#define BIT_0_15    0xFFFF
> +#define BIT_1_2     0x0006
> +#define BIT_1_3     0x000E
> +#define BIT_2_5     0x003C
> +#define BIT_3_4     0x0018
> +#define BIT_4_5     0x0030
> +#define BIT_4_6     0x0070
> +#define BIT_4_7     0x00F0
> +#define BIT_5_7     0x00E0
> +#define BIT_5_9     0x03E0
> +#define BIT_5_12    0x1FE0
> +#define BIT_5_15    0xFFE0
> +#define BIT_6_7     0x00c0
> +#define BIT_7_11    0x0F80
> +#define BIT_8_10    0x0700
> +#define BIT_9_13    0x3E00
> +#define BIT_12_15   0xF000
> +
> +#define BIT_16_20   0x001F0000
> +#define BIT_21_25   0x03E00000
> +#define BIT_26_27   0x0C000000
> +
> +//-------------------------------------------------------------------------
> +// MDI Control register opcode definitions
> +//-------------------------------------------------------------------------
> +#define MDI_WRITE               1               // Phy Write
> +#define MDI_READ                2               // Phy read
> +
> +//-------------------------------------------------------------------------
> +// PHY 100 MDI Register/Bit Definitions
> +//-------------------------------------------------------------------------
> +// MDI register set
> +#define MDI_CONTROL_REG             0x00        // MDI control register
> +#define MDI_STATUS_REG              0x01        // MDI Status regiser
> +#define PHY_ID_REG_1                0x02        // Phy indentification reg (word 1)
> +#define PHY_ID_REG_2                0x03        // Phy indentification reg (word 2)
> +#define AUTO_NEG_ADVERTISE_REG      0x04        // Auto-negotiation
> advertisement
> +#define AUTO_NEG_LINK_PARTNER_REG   0x05        // Auto-negotiation link
> partner ability
> +#define AUTO_NEG_EXPANSION_REG      0x06        // Auto-negotiation
> expansion
> +#define AUTO_NEG_NEXT_PAGE_REG      0x07        // Auto-negotiation next
> page transmit
> +#define EXTENDED_REG_0              0x10        // Extended reg 0 (Phy 100
> modes)
> +#define EXTENDED_REG_1              0x14        // Extended reg 1 (Phy 100 error
> indications)
> +#define NSC_CONG_CONTROL_REG        0x17        // National (TX)
> congestion control
> +#define NSC_SPEED_IND_REG           0x19        // National (TX) speed
> indication
> +
> +// MDI Control register bit definitions
> +#define MDI_CR_COLL_TEST_ENABLE     BIT_7       // Collision test enable
> +#define MDI_CR_FULL_HALF            BIT_8       // FDX =1, half duplex =0
> +#define MDI_CR_RESTART_AUTO_NEG     BIT_9       // Restart auto
> negotiation
> +#define MDI_CR_ISOLATE              BIT_10      // Isolate PHY from MII
> +#define MDI_CR_POWER_DOWN           BIT_11      // Power down
> +#define MDI_CR_AUTO_SELECT          BIT_12      // Auto speed select enable
> +#define MDI_CR_10_100               BIT_13      // 0 = 10Mbs, 1 = 100Mbs
> +#define MDI_CR_LOOPBACK             BIT_14      // 0 = normal, 1 = loopback
> +#define MDI_CR_RESET                BIT_15      // 0 = normal, 1 = PHY reset
> +
> +// MDI Status register bit definitions
> +#define MDI_SR_EXT_REG_CAPABLE      BIT_0       // Extended register
> capabilities
> +#define MDI_SR_JABBER_DETECT        BIT_1       // Jabber detected
> +#define MDI_SR_LINK_STATUS          BIT_2       // Link Status -- 1 = link
> +#define MDI_SR_AUTO_SELECT_CAPABLE  BIT_3       // Auto speed select
> capable
> +#define MDI_SR_REMOTE_FAULT_DETECT  BIT_4       // Remote fault detect
> +#define MDI_SR_AUTO_NEG_COMPLETE    BIT_5       // Auto negotiation
> complete
> +#define MDI_SR_10T_HALF_DPX         BIT_11      // 10BaseT Half Duplex
> capable
> +#define MDI_SR_10T_FULL_DPX         BIT_12      // 10BaseT full duplex
> capable
> +#define MDI_SR_TX_HALF_DPX          BIT_13      // TX Half Duplex capable
> +#define MDI_SR_TX_FULL_DPX          BIT_14      // TX full duplex capable
> +#define MDI_SR_T4_CAPABLE           BIT_15      // T4 capable
> +
> +// Auto-Negotiation advertisement register bit definitions
> +#define NWAY_AD_SELCTOR_FIELD       BIT_0_4     // identifies supported
> protocol
> +#define NWAY_AD_ABILITY             BIT_5_12    // technologies that are
> supported
> +#define NWAY_AD_10T_HALF_DPX        BIT_5       // 10BaseT Half Duplex
> capable
> +#define NWAY_AD_10T_FULL_DPX        BIT_6       // 10BaseT full duplex
> capable
> +#define NWAY_AD_TX_HALF_DPX         BIT_7       // TX Half Duplex capable
> +#define NWAY_AD_TX_FULL_DPX         BIT_8       // TX full duplex capable
> +#define NWAY_AD_T4_CAPABLE          BIT_9       // T4 capable
> +#define NWAY_AD_REMOTE_FAULT        BIT_13      // indicates local remote
> fault
> +#define NWAY_AD_RESERVED            BIT_14      // reserved
> +#define NWAY_AD_NEXT_PAGE           BIT_15      // Next page (not
> supported)
> +
> +// Auto-Negotiation link partner ability register bit definitions
> +#define NWAY_LP_SELCTOR_FIELD       BIT_0_4     // identifies supported
> protocol
> +#define NWAY_LP_ABILITY             BIT_5_9     // technologies that are
> supported
> +#define NWAY_LP_REMOTE_FAULT        BIT_13      // indicates partner
> remote fault
> +#define NWAY_LP_ACKNOWLEDGE         BIT_14      // acknowledge
> +#define NWAY_LP_NEXT_PAGE           BIT_15      // Next page (not supported)
> +
> +// Auto-Negotiation expansion register bit definitions
> +#define NWAY_EX_LP_NWAY             BIT_0       // link partner is NWAY
> +#define NWAY_EX_PAGE_RECEIVED       BIT_1       // link code word received
> +#define NWAY_EX_NEXT_PAGE_ABLE      BIT_2       // local is next page able
> +#define NWAY_EX_LP_NEXT_PAGE_ABLE   BIT_3       // partner is next page
> able
> +#define NWAY_EX_PARALLEL_DET_FLT    BIT_4       // parallel detection fault
> +#define NWAY_EX_RESERVED            BIT_5_15    // reserved
> +
> +
> +// PHY 100 Extended Register 0 bit definitions
> +#define PHY_100_ER0_FDX_INDIC       BIT_0       // 1 = FDX, 0 = half duplex
> +#define PHY_100_ER0_SPEED_INDIC     BIT_1       // 1 = 100mbs, 0= 10mbs
> +#define PHY_100_ER0_WAKE_UP         BIT_2       // Wake up DAC
> +#define PHY_100_ER0_RESERVED        BIT_3_4     // Reserved
> +#define PHY_100_ER0_REV_CNTRL       BIT_5_7     // Revsion control (A step
> = 000)
> +#define PHY_100_ER0_FORCE_FAIL      BIT_8       // Force Fail is enabled
> +#define PHY_100_ER0_TEST            BIT_9_13    // Revsion control (A step =
> 000)
> +#define PHY_100_ER0_LINKDIS         BIT_14      // Link integrity test is
> disabled
> +#define PHY_100_ER0_JABDIS          BIT_15      // Jabber function is disabled
> +
> +
> +// PHY 100 Extended Register 1 bit definitions
> +#define PHY_100_ER1_RESERVED        BIT_0_8     // Reserved
> +#define PHY_100_ER1_CH2_DET_ERR     BIT_9       // Channel 2 EOF
> detection error
> +#define PHY_100_ER1_MANCH_CODE_ERR  BIT_10      // Manchester code
> error
> +#define PHY_100_ER1_EOP_ERR         BIT_11      // EOP error
> +#define PHY_100_ER1_BAD_CODE_ERR    BIT_12      // bad code error
> +#define PHY_100_ER1_INV_CODE_ERR    BIT_13      // invalid code error
> +#define PHY_100_ER1_DC_BAL_ERR      BIT_14      // DC balance error
> +#define PHY_100_ER1_PAIR_SKEW_ERR   BIT_15      // Pair skew error
> +
> +// National Semiconductor TX phy congestion control register bit
> definitions
> +#define NSC_TX_CONG_TXREADY         BIT_10      // Makes TxReady an input
> +#define NSC_TX_CONG_ENABLE          BIT_8       // Enables congestion
> control
> +#define NSC_TX_CONG_F_CONNECT       BIT_5       // Enables congestion
> control
> +
> +// National Semiconductor TX phy speed indication register bit definitions
> +#define NSC_TX_SPD_INDC_SPEED       BIT_6       // 0 = 100mb, 1=10mb
> +
> +//-------------------------------------------------------------------------
> +// Phy related constants
> +//-------------------------------------------------------------------------
> +#define PHY_503                 0
> +#define PHY_100_A               0x000003E0
> +#define PHY_100_C               0x035002A8
> +#define PHY_TX_ID               0x015002A8
> +#define PHY_NSC_TX              0x5c002000
> +#define PHY_OTHER               0xFFFF
> +
> +#define PHY_MODEL_REV_ID_MASK   0xFFF0FFFF
> +#define PARALLEL_DETECT         0
> +#define N_WAY                   1
> +
> +#define RENEGOTIATE_TIME        35 // (3.5 Seconds)
> +
> +#define CONNECTOR_AUTO          0
> +#define CONNECTOR_TPE           1
> +#define CONNECTOR_MII           2
> +
> +//-------------------------------------------------------------------------
> +
> +/* The Speedo3 Rx and Tx frame/buffer descriptors. */
> +#pragma pack(1)
> +struct CB_Header {      /* A generic descriptor. */
> +  UINT16 status;    /* Offset 0. */
> +  UINT16 command;    /* Offset 2. */
> +  UINT32 link;          /* struct descriptor *  */
> +};
> +
> +/* transmit command block structure */
> +#pragma pack(1)
> +typedef struct s_TxCB {
> +  struct CB_Header cb_header;
> +  UINT32 PhysTBDArrayAddres;  /* address of an array that contains
> +                physical TBD pointers */
> +  UINT16 ByteCount;  /* immediate data count = 0 always */
> +  UINT8 Threshold;
> +  UINT8 TBDCount;
> +  UINT8 ImmediateData[TX_BUFFER_SIZE];
> +  /* following fields are not seen by the 82557 */
> +  struct TBD {
> +    UINT32 phys_buf_addr;
> +    UINT32 buf_len;
> +    } TBDArray[MAX_XMIT_FRAGMENTS];
> +  UINT32 PhysArrayAddr;  /* in case the one in the header is lost */
> +  UINT32 PhysTCBAddress;    /* for this TCB */
> +  struct s_TxCB *NextTCBVirtualLinkPtr;
> +  struct s_TxCB *PrevTCBVirtualLinkPtr;
> +  UINT64 free_data_ptr;  // to be given to the upper layer when this xmit
> completes1
> +}TxCB;
> +
> +/* The Speedo3 Rx and Tx buffer descriptors. */
> +#pragma pack(1)
> +typedef struct s_RxFD {          /* Receive frame descriptor. */
> +  struct CB_Header cb_header;
> +  UINT32 rx_buf_addr;      /* VOID * */
> +  UINT16 ActualCount;
> +  UINT16 RFDSize;
> +  UINT8 RFDBuffer[RX_BUFFER_SIZE];
> +  UINT8 forwarded;
> +  UINT8 junk[3];
> +}RxFD;
> +
> +/* Elements of the RxFD.status word. */
> +#define RX_COMPLETE 0x8000
> +#define RX_FRAME_OK 0x2000
> +
> +/* Elements of the dump_statistics block. This block must be lword aligned.
> */
> +#pragma pack(1)
> +struct speedo_stats {
> +  UINT32 tx_good_frames;
> +  UINT32 tx_coll16_errs;
> +  UINT32 tx_late_colls;
> +  UINT32 tx_underruns;
> +  UINT32 tx_lost_carrier;
> +  UINT32 tx_deferred;
> +  UINT32 tx_one_colls;
> +  UINT32 tx_multi_colls;
> +  UINT32 tx_total_colls;
> +  UINT32 rx_good_frames;
> +  UINT32 rx_crc_errs;
> +  UINT32 rx_align_errs;
> +  UINT32 rx_resource_errs;
> +  UINT32 rx_overrun_errs;
> +  UINT32 rx_colls_errs;
> +  UINT32 rx_runt_errs;
> +  UINT32 done_marker;
> +};
> +#pragma pack()
> +
> +
> +struct Krn_Mem{
> +  RxFD rx_ring[RX_BUFFER_COUNT];
> +  TxCB tx_ring[TX_BUFFER_COUNT];
> +  struct speedo_stats statistics;
> +};
> +#define MEMORY_NEEDED  sizeof(struct Krn_Mem)
> +
> +/* The parameters for a CmdConfigure operation.
> +   There are so many options that it would be difficult to document each bit.
> +   We mostly use the default or recommended settings.
> +*/
> +
> +/*
> + *--------------------------------------------------------------------------
> + * Configuration CB Parameter Bit Definitions
> + *--------------------------------------------------------------------------
> + */
> +// - Byte 0  (Default Value = 16h)
> +#define CFIG_BYTE_COUNT    0x16       // 22 Configuration Bytes
> +
> +//- Byte 1  (Default Value = 88h)
> +#define CFIG_TXRX_FIFO_LIMIT  0x88
> +
> +//- Byte 2  (Default Value = 0)
> +#define CFIG_ADAPTIVE_IFS    0
> +
> +//- Byte 3  (Default Value = 0, ALWAYS. This byte is RESERVED)
> +#define CFIG_RESERVED        0
> +
> +//- Byte 4  (Default Value = 0. Default implies that Rx DMA cannot be
> +//-          preempted).
> +#define CFIG_RXDMA_BYTE_COUNT      0
> +
> +//- Byte 5  (Default Value = 80h. Default implies that Tx DMA cannot be
> +//-          preempted. However, setting these counters is enabled.)
> +#define CFIG_DMBC_ENABLE            0x80
> +
> +//- Byte 6  (Default Value = 33h. Late SCB enabled, No TNO interrupts,
> +//-          CNA interrupts and do not save bad frames.)
> +#define CFIG_LATE_SCB               1  // BIT 0
> +#define CFIG_TNO_INTERRUPT          0x4  // BIT 2
> +#define CFIG_CI_INTERRUPT           0x8  // BIT 3
> +#define CFIG_SAVE_BAD_FRAMES        0x80  // BIT_7
> +
> +//- Byte 7  (Default Value = 7h. Discard short frames automatically and
> +//-          attempt upto 3 retries on transmit.)
> +#define CFIG_DISCARD_SHORTRX         0x00001
> +#define CFIG_URUN_RETRY              BIT_1 OR BIT_2
> +
> +//- Byte 8  (Default Value = 1. Enable MII mode.)
> +#define CFIG_503_MII              BIT_0
> +
> +//- Byte 9  (Default Value = 0, ALWAYS)
> +
> +//- Byte 10 (Default Value = 2Eh)
> +#define CFIG_NSAI                   BIT_3
> +#define CFIG_PREAMBLE_LENGTH         BIT_5      ;- Bit 5-4  = 1-0
> +#define CFIG_NO_LOOPBACK             0
> +#define CFIG_INTERNAL_LOOPBACK       BIT_6
> +#define CFIG_EXT_LOOPBACK            BIT_7
> +#define CFIG_EXT_PIN_LOOPBACK        BIT_6 OR BIT_7
> +
> +//- Byte 11 (Default Value = 0)
> +#define CFIG_LINEAR_PRIORITY         0
> +
> +//- Byte 12 (Default Value = 60h)
> +#define CFIG_LPRIORITY_MODE          0
> +#define CFIG_IFS                     6          ;- 6 * 16 = 96
> +
> +//- Byte 13 (Default Value = 0, ALWAYS)
> +
> +//- Byte 14 (Default Value = 0F2h, ALWAYS)
> +
> +//- Byte 15 (Default Value = E8h)
> +#define CFIG_PROMISCUOUS_MODE        BIT_0
> +#define CFIG_BROADCAST_DISABLE       BIT_1
> +#define CFIG_CRS_CDT                 BIT_7
> +
> +//- Byte 16 (Default Value = 0, ALWAYS)
> +
> +//- Byte 17 (Default Value = 40h, ALWAYS)
> +
> +//- Byte 18 (Default Value = F2h)
> +#define CFIG_STRIPPING               BIT_0
> +#define CFIG_PADDING                 BIT_1
> +#define CFIG_RX_CRC_TRANSFER         BIT_2
> +
> +//- Byte 19 (Default Value = 80h)
> +#define CFIG_FORCE_FDX               BIT_6
> +#define CFIG_FDX_PIN_ENABLE          BIT_7
> +
> +//- Byte 20 (Default Value = 3Fh)
> +#define CFIG_MULTI_IA                BIT_6
> +
> +//- Byte 21 (Default Value = 05)
> +#define CFIG_MC_ALL                  BIT_3
> +
> +/*-----------------------------------------------------------------------*/
> +#define D102_REVID 0x0b
> +
> +#define HALF_DUPLEX 1
> +#define FULL_DUPLEX 2
> +
> +typedef struct s_data_instance {
> +
> +  UINT16 State;  // stopped, started or initialized
> +  UINT16 Bus;
> +  UINT8 Device;
> +  UINT8 Function;
> +  UINT16 VendorID;
> +  UINT16 DeviceID;
> +  UINT16 RevID;
> +  UINT16 SubVendorID;
> +  UINT16 SubSystemID;
> +
> +  UINT8 PermNodeAddress[PXE_MAC_LENGTH];
> +  UINT8 CurrentNodeAddress[PXE_MAC_LENGTH];
> +  UINT8 BroadcastNodeAddress[PXE_MAC_LENGTH];
> +  UINT32 Config[MAX_PCI_CONFIG_LEN];
> +  UINT32 NVData[MAX_EEPROM_LEN];
> +
> +  UINT32 ioaddr;
> +  UINT32 flash_addr;
> +
> +  UINT16 LinkSpeed;     // actual link speed setting
> +  UINT16 LinkSpeedReq;  // requested (forced) link speed
> +  UINT8  DuplexReq;     // requested duplex
> +  UINT8  Duplex;        // Duplex set
> +  UINT8  CableDetect;   // 1 to detect and 0 not to detect the cable
> +  UINT8  LoopBack;
> +
> +  UINT16 TxBufCnt;
> +  UINT16 TxBufSize;
> +  UINT16 RxBufCnt;
> +  UINT16 RxBufSize;
> +  UINT32 RxTotals;
> +  UINT32 TxTotals;
> +
> +  UINT16 int_mask;
> +  UINT16 Int_Status;
> +  UINT16 PhyRecord[2];  // primary and secondary PHY record registers from
> eeprom
> +  UINT8  PhyAddress;
> +  UINT8  int_num;
> +  UINT16 NVData_Len;
> +  UINT32 MemoryLength;
> +
> +  RxFD *rx_ring;  // array of rx buffers
> +  TxCB *tx_ring;  // array of tx buffers
> +  struct speedo_stats *statistics;
> +  TxCB *FreeTxHeadPtr;
> +  TxCB *FreeTxTailPtr;
> +  RxFD *RFDTailPtr;
> +
> +  UINT64 rx_phy_addr;  // physical addresses
> +  UINT64 tx_phy_addr;
> +  UINT64 stat_phy_addr;
> +  UINT64 MemoryPtr;
> +  UINT64 Mapped_MemoryPtr;
> +
> +  UINT64 xmit_done[TX_BUFFER_COUNT << 1]; // circular buffer
> +  UINT16 xmit_done_head;  // index into the xmit_done array
> +  UINT16 xmit_done_tail;  // where are we filling now (index into xmit_done)
> +  UINT16 cur_rx_ind;  // current RX Q head index
> +  UINT16 FreeCBCount;
> +
> +  BOOLEAN in_interrupt;
> +  BOOLEAN in_transmit;
> +  BOOLEAN Receive_Started;
> +  UINT8 Rx_Filter;
> +  UINT8 VersionFlag;  // UNDI30 or UNDI31??
> +  UINT8 rsvd[3];
> +
> +  struct mc{
> +    UINT16 reserved [3]; // padding for this structure to make it 8 byte
> aligned
> +    UINT16 list_len;
> +    UINT8 mc_list[MAX_MCAST_ADDRESS_CNT][PXE_MAC_LENGTH]; // 8*32
> is the size
> +  } mcast_list;
> +
> +  UINT64 Unique_ID;
> +
> +  EFI_PCI_IO_PROTOCOL   *Io_Function;
> +  //
> +  // Original PCI attributes
> +  //
> +  UINT64                OriginalPciAttributes;
> +
> +  VOID (*Delay_30)(UINTN);  // call back routine
> +  VOID (*Virt2Phys_30)(UINT64 virtual_addr, UINT64 physical_ptr);  // call
> back routine
> +  VOID (*Block_30)(UINT32 enable);  // call back routine
> +  VOID (*Mem_Io_30)(UINT8 read_write, UINT8 len, UINT64 port, UINT64
> buf_addr);
> +  VOID (*Delay)(UINT64, UINTN);  // call back routine
> +  VOID (*Virt2Phys)(UINT64 unq_id, UINT64 virtual_addr, UINT64
> physical_ptr);  // call back routine
> +  VOID (*Block)(UINT64 unq_id, UINT32 enable);  // call back routine
> +  VOID (*Mem_Io)(UINT64 unq_id, UINT8 read_write, UINT8 len, UINT64
> port,
> +          UINT64 buf_addr);
> +  VOID (*Map_Mem)(UINT64 unq_id, UINT64 virtual_addr, UINT32 size,
> +                   UINT32 Direction, UINT64 mapped_addr);
> +  VOID (*UnMap_Mem)(UINT64 unq_id, UINT64 virtual_addr, UINT32 size,
> +            UINT32 Direction, UINT64 mapped_addr);
> +  VOID (*Sync_Mem)(UINT64 unq_id, UINT64 virtual_addr,
> +            UINT32 size, UINT32 Direction, UINT64 mapped_addr);
> +} NIC_DATA_INSTANCE;
> +
> +#pragma pack(1)
> +struct MC_CB_STRUCT{
> +  UINT16 count;
> +  UINT8 m_list[MAX_MCAST_ADDRESS_CNT][ETHER_MAC_ADDR_LEN];
> +};
> +#pragma pack()
> +
> +#define FOUR_GIGABYTE (UINT64)0x100000000ULL
> +
> +#endif
> +
> diff --git a/Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c
> b/Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c
> new file mode 100644
> index 0000000000..2625a6cc5c
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c
> @@ -0,0 +1,1051 @@
> +/** @file
> +  Initialization functions for EFI UNDI32 driver.
> +
> +Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "Undi32.h"
> +//
> +// Global Variables
> +//
> +
> +PXE_SW_UNDI             *pxe_31 = NULL;  // 3.1 entry
> +UNDI32_DEV              *UNDI32DeviceList[MAX_NIC_INTERFACES];
> +UNDI_CONFIG_TABLE       *UndiDataPointer = NULL;
> +
> +//
> +// UNDI Class Driver Global Variables
> +//
> +EFI_DRIVER_BINDING_PROTOCOL  gUndiDriverBinding = {
> +  UndiDriverSupported,
> +  UndiDriverStart,
> +  UndiDriverStop,
> +  0xa,
> +  NULL,
> +  NULL
> +};
> +
> +
> +/**
> +  When address mapping changes to virtual this should make the
> appropriate
> +  address conversions.
> +
> +  (Standard Event handler)
> +
> +  @return None
> +
> +**/
> +VOID
> +EFIAPI
> +UndiNotifyVirtual (
> +  EFI_EVENT Event,
> +  VOID      *Context
> +  )
> +{
> +  UINT16  Index;
> +  VOID    *Pxe31Pointer;
> +
> +  if (pxe_31 != NULL) {
> +    Pxe31Pointer = (VOID *) pxe_31;
> +
> +    EfiConvertPointer (
> +      EFI_OPTIONAL_PTR,
> +      (VOID **) &Pxe31Pointer
> +      );
> +
> +    //
> +    // UNDI32DeviceList is an array of pointers
> +    //
> +    for (Index = 0; Index < (pxe_31->IFcnt | pxe_31->IFcntExt << 8); Index++) {
> +      UNDI32DeviceList[Index]->NIIProtocol_31.Id = (UINT64) (UINTN)
> Pxe31Pointer;
> +      EfiConvertPointer (
> +        EFI_OPTIONAL_PTR,
> +        (VOID **) &(UNDI32DeviceList[Index])
> +        );
> +    }
> +
> +    EfiConvertPointer (
> +      EFI_OPTIONAL_PTR,
> +      (VOID **) &(pxe_31->EntryPoint)
> +      );
> +    pxe_31 = Pxe31Pointer;
> +  }
> +
> +  for (Index = 0; Index <= PXE_OPCODE_LAST_VALID; Index++) {
> +    EfiConvertPointer (
> +      EFI_OPTIONAL_PTR,
> +      (VOID **) &api_table[Index].api_ptr
> +      );
> +  }
> +}
> +
> +
> +/**
> +  When EFI is shuting down the boot services, we need to install a
> +  configuration table for UNDI to work at runtime!
> +
> +  (Standard Event handler)
> +
> +  @return None
> +
> +**/
> +VOID
> +EFIAPI
> +UndiNotifyReadyToBoot (
> +  EFI_EVENT Event,
> +  VOID      *Context
> +  )
> +{
> +  InstallConfigTable ();
> +}
> +
> +
> +/**
> +  Test to see if this driver supports ControllerHandle. Any ControllerHandle
> +  than contains a  DevicePath, PciIo protocol, Class code of 2, Vendor ID of
> 0x8086,
> +  and DeviceId of (D100_DEVICE_ID || D102_DEVICE_ID ||
> ICH3_DEVICE_ID_1 ||
> +  ICH3_DEVICE_ID_2 || ICH3_DEVICE_ID_3 || ICH3_DEVICE_ID_4 ||
> ICH3_DEVICE_ID_5 ||
> +  ICH3_DEVICE_ID_6 || ICH3_DEVICE_ID_7 || ICH3_DEVICE_ID_8) can be
> supported.
> +
> +  @param  This                 Protocol instance pointer.
> +  @param  Controller           Handle of device to test.
> +  @param  RemainingDevicePath  Not used.
> +
> +  @retval EFI_SUCCESS          This driver supports this device.
> +  @retval other                This driver does not support this device.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UndiDriverSupported (
> +  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
> +  IN EFI_HANDLE                     Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
> +  )
> +{
> +  EFI_STATUS          Status;
> +  EFI_PCI_IO_PROTOCOL *PciIo;
> +  PCI_TYPE00          Pci;
> +
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiDevicePathProtocolGuid,
> +                  NULL,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiPciIoProtocolGuid,
> +                  (VOID **) &PciIo,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = PciIo->Pci.Read (
> +                        PciIo,
> +                        EfiPciIoWidthUint8,
> +                        0,
> +                        sizeof (PCI_CONFIG_HEADER),
> +                        &Pci
> +                        );
> +
> +  if (!EFI_ERROR (Status)) {
> +    Status = EFI_UNSUPPORTED;
> +
> +    if (Pci.Hdr.ClassCode[2] == 0x02 && Pci.Hdr.VendorId ==
> PCI_VENDOR_ID_INTEL) {
> +      switch (Pci.Hdr.DeviceId) {
> +      case D100_DEVICE_ID:
> +      case D102_DEVICE_ID:
> +      case ICH3_DEVICE_ID_1:
> +      case ICH3_DEVICE_ID_2:
> +      case ICH3_DEVICE_ID_3:
> +      case ICH3_DEVICE_ID_4:
> +      case ICH3_DEVICE_ID_5:
> +      case ICH3_DEVICE_ID_6:
> +      case ICH3_DEVICE_ID_7:
> +      case ICH3_DEVICE_ID_8:
> +      case 0x1039:
> +      case 0x103A:
> +      case 0x103B:
> +      case 0x103C:
> +      case 0x103D:
> +      case 0x103E:
> +      case 0x1050:
> +      case 0x1051:
> +      case 0x1052:
> +      case 0x1053:
> +      case 0x1054:
> +      case 0x1055:
> +      case 0x1056:
> +      case 0x1057:
> +      case 0x1059:
> +      case 0x1064:
> +        Status = EFI_SUCCESS;
> +      }
> +    }
> +  }
> +
> +  gBS->CloseProtocol (
> +        Controller,
> +        &gEfiPciIoProtocolGuid,
> +        This->DriverBindingHandle,
> +        Controller
> +        );
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Start this driver on Controller by opening PciIo and DevicePath protocol.
> +  Initialize PXE structures, create a copy of the Controller Device Path with
> the
> +  NIC's MAC address appended to it, install the NetworkInterfaceIdentifier
> protocol
> +  on the newly created Device Path.
> +
> +  @param  This                 Protocol instance pointer.
> +  @param  Controller           Handle of device to work with.
> +  @param  RemainingDevicePath  Not used, always produce all possible
> children.
> +
> +  @retval EFI_SUCCESS          This driver is added to Controller.
> +  @retval other                This driver does not support this device.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UndiDriverStart (
> +  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
> +  IN EFI_HANDLE                     Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
> +  )
> +{
> +  EFI_STATUS                Status;
> +  EFI_DEVICE_PATH_PROTOCOL  *UndiDevicePath;
> +  PCI_CONFIG_HEADER         *CfgHdr;
> +  UNDI32_DEV                *UNDI32Device;
> +  UINT16                    NewCommand;
> +  UINT8                     *TmpPxePointer;
> +  EFI_PCI_IO_PROTOCOL       *PciIoFncs;
> +  UINTN                     Len;
> +  UINT64                    Supports;
> +  BOOLEAN                   PciAttributesSaved;
> +
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiPciIoProtocolGuid,
> +                  (VOID **) &PciIoFncs,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiDevicePathProtocolGuid,
> +                  (VOID **) &UndiDevicePath,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +
> +  if (EFI_ERROR (Status)) {
> +    gBS->CloseProtocol (
> +          Controller,
> +          &gEfiPciIoProtocolGuid,
> +          This->DriverBindingHandle,
> +          Controller
> +          );
> +
> +    return Status;
> +  }
> +
> +  PciAttributesSaved = FALSE;
> +
> +  Status = gBS->AllocatePool (
> +                  EfiRuntimeServicesData,
> +                  sizeof (UNDI32_DEV),
> +                  (VOID **) &UNDI32Device
> +                  );
> +
> +  if (EFI_ERROR (Status)) {
> +    goto UndiError;
> +  }
> +
> +  ZeroMem ((CHAR8 *) UNDI32Device, sizeof (UNDI32_DEV));
> +
> +  //
> +  // Get original PCI attributes
> +  //
> +  Status = PciIoFncs->Attributes (
> +                    PciIoFncs,
> +                    EfiPciIoAttributeOperationGet,
> +                    0,
> +                    &UNDI32Device->NicInfo.OriginalPciAttributes
> +                    );
> +
> +  if (EFI_ERROR (Status)) {
> +    goto UndiErrorDeleteDevice;
> +  }
> +  PciAttributesSaved = TRUE;
> +
> +  //
> +  // allocate and initialize both (old and new) the !pxe structures here,
> +  // there should only be one copy of each of these structure for any
> number
> +  // of NICs this undi supports. Also, these structures need to be on a
> +  // paragraph boundary as per the spec. so, while allocating space for these,
> +  // make sure that there is space for 2 !pxe structures (old and new) and a
> +  // 32 bytes padding for alignment adjustment (in case)
> +  //
> +  TmpPxePointer = NULL;
> +  if (pxe_31 == NULL) {
> +    Status = gBS->AllocatePool (
> +                    EfiRuntimeServicesData,
> +                    (sizeof (PXE_SW_UNDI) + sizeof (PXE_SW_UNDI) + 32),
> +                    (VOID **) &TmpPxePointer
> +                    );
> +
> +    if (EFI_ERROR (Status)) {
> +      goto UndiErrorDeleteDevice;
> +    }
> +
> +    ZeroMem (
> +      TmpPxePointer,
> +      sizeof (PXE_SW_UNDI) + sizeof (PXE_SW_UNDI) + 32
> +      );
> +    //
> +    // check for paragraph alignment here, assuming that the pointer is
> +    // already 8 byte aligned.
> +    //
> +    if (((UINTN) TmpPxePointer & 0x0F) != 0) {
> +      pxe_31 = (PXE_SW_UNDI *) ((UINTN) (TmpPxePointer + 8));
> +    } else {
> +      pxe_31 = (PXE_SW_UNDI *) TmpPxePointer;
> +    }
> +
> +    PxeStructInit (pxe_31);
> +  }
> +
> +  UNDI32Device->NIIProtocol_31.Id = (UINT64) (UINTN) (pxe_31);
> +
> +  Status = PciIoFncs->Attributes (
> +                        PciIoFncs,
> +                        EfiPciIoAttributeOperationSupported,
> +                        0,
> +                        &Supports
> +                        );
> +  if (!EFI_ERROR (Status)) {
> +    Supports &= EFI_PCI_DEVICE_ENABLE;
> +    Status = PciIoFncs->Attributes (
> +                          PciIoFncs,
> +                          EfiPciIoAttributeOperationEnable,
> +                          Supports,
> +                          NULL
> +                          );
> +  }
> +  //
> +  // Read all the registers from device's PCI Configuration space
> +  //
> +  Status = PciIoFncs->Pci.Read (
> +                            PciIoFncs,
> +                            EfiPciIoWidthUint32,
> +                            0,
> +                            MAX_PCI_CONFIG_LEN,
> +                            &UNDI32Device->NicInfo.Config
> +                            );
> +
> +  CfgHdr = (PCI_CONFIG_HEADER *) &(UNDI32Device->NicInfo.Config[0]);
> +
> +  //
> +  // make sure that this device is a PCI bus master
> +  //
> +
> +  NewCommand = (UINT16) (CfgHdr->Command | PCI_COMMAND_MASTER
> | PCI_COMMAND_IO);
> +  if (CfgHdr->Command != NewCommand) {
> +    PciIoFncs->Pci.Write (
> +                    PciIoFncs,
> +                    EfiPciIoWidthUint16,
> +                    PCI_COMMAND,
> +                    1,
> +                    &NewCommand
> +                    );
> +    CfgHdr->Command = NewCommand;
> +  }
> +
> +  //
> +  // make sure that the latency timer is at least 32
> +  //
> +  if (CfgHdr->LatencyTimer < 32) {
> +    CfgHdr->LatencyTimer = 32;
> +    PciIoFncs->Pci.Write (
> +                    PciIoFncs,
> +                    EfiPciIoWidthUint8,
> +                    PCI_LATENCY_TIMER,
> +                    1,
> +                    &CfgHdr->LatencyTimer
> +                    );
> +  }
> +  //
> +  // the IfNum index for the current interface will be the total number
> +  // of interfaces initialized so far
> +  //
> +  UNDI32Device->NIIProtocol_31.IfNum  = pxe_31->IFcnt | pxe_31-
> >IFcntExt << 8;
> +
> +  PxeUpdate (&UNDI32Device->NicInfo, pxe_31);
> +
> +  UNDI32Device->NicInfo.Io_Function                    = PciIoFncs;
> +  UNDI32DeviceList[UNDI32Device->NIIProtocol_31.IfNum] = UNDI32Device;
> +  UNDI32Device->Undi32BaseDevPath                      = UndiDevicePath;
> +
> +  Status = AppendMac2DevPath (
> +            &UNDI32Device->Undi32DevPath,
> +            UNDI32Device->Undi32BaseDevPath,
> +            &UNDI32Device->NicInfo
> +            );
> +
> +  if (Status != 0) {
> +    goto UndiErrorDeletePxe;
> +  }
> +
> +  UNDI32Device->Signature                     = UNDI_DEV_SIGNATURE;
> +
> +  UNDI32Device->NIIProtocol_31.Revision       =
> EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION_31;
> +  UNDI32Device->NIIProtocol_31.Type           = EfiNetworkInterfaceUndi;
> +  UNDI32Device->NIIProtocol_31.MajorVer       = PXE_ROMID_MAJORVER;
> +  UNDI32Device->NIIProtocol_31.MinorVer       =
> PXE_ROMID_MINORVER_31;
> +  UNDI32Device->NIIProtocol_31.ImageSize      = 0;
> +  UNDI32Device->NIIProtocol_31.ImageAddr      = 0;
> +  UNDI32Device->NIIProtocol_31.Ipv6Supported  = TRUE;
> +
> +  UNDI32Device->NIIProtocol_31.StringId[0]    = 'U';
> +  UNDI32Device->NIIProtocol_31.StringId[1]    = 'N';
> +  UNDI32Device->NIIProtocol_31.StringId[2]    = 'D';
> +  UNDI32Device->NIIProtocol_31.StringId[3]    = 'I';
> +
> +  UNDI32Device->DeviceHandle                  = NULL;
> +
> +  UNDI32Device->Aip.GetInformation            = UndiAipGetInfo;
> +  UNDI32Device->Aip.SetInformation            = UndiAipSetInfo;
> +  UNDI32Device->Aip.GetSupportedTypes         =
> UndiAipGetSupportedTypes;
> +
> +  //
> +  // install both the 3.0 and 3.1 NII protocols.
> +  //
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &UNDI32Device->DeviceHandle,
> +                  &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
> +                  &UNDI32Device->NIIProtocol_31,
> +                  &gEfiDevicePathProtocolGuid,
> +                  UNDI32Device->Undi32DevPath,
> +                  &gEfiAdapterInformationProtocolGuid,
> +                  &UNDI32Device->Aip,
> +                  NULL
> +                  );
> +
> +  if (EFI_ERROR (Status)) {
> +    goto UndiErrorDeleteDevicePath;
> +  }
> +
> +  //
> +  // if the table exists, free it and alloc again, or alloc it directly
> +  //
> +  if (UndiDataPointer != NULL) {
> +    Status = gBS->FreePool(UndiDataPointer);
> +  }
> +  if (EFI_ERROR (Status)) {
> +    goto UndiErrorDeleteDevicePath;
> +  }
> +
> +  Len = ((pxe_31->IFcnt|pxe_31->IFcntExt << 8)* sizeof (UndiDataPointer-
> >NII_entry)) + sizeof (UndiDataPointer);
> +  Status = gBS->AllocatePool (EfiRuntimeServicesData, Len, (VOID **)
> &UndiDataPointer);
> +
> +  if (EFI_ERROR (Status)) {
> +    goto UndiErrorAllocDataPointer;
> +  }
> +
> +  //
> +  // Open For Child Device
> +  //
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiPciIoProtocolGuid,
> +                  (VOID **) &PciIoFncs,
> +                  This->DriverBindingHandle,
> +                  UNDI32Device->DeviceHandle,
> +                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
> +                  );
> +
> +  return EFI_SUCCESS;
> +UndiErrorAllocDataPointer:
> +  gBS->UninstallMultipleProtocolInterfaces (
> +                  &UNDI32Device->DeviceHandle,
> +                  &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
> +                  &UNDI32Device->NIIProtocol_31,
> +                  &gEfiDevicePathProtocolGuid,
> +                  UNDI32Device->Undi32DevPath,
> +                  &gEfiAdapterInformationProtocolGuid,
> +                  &UNDI32Device->Aip,
> +                  NULL
> +                  );
> +
> +UndiErrorDeleteDevicePath:
> +  UNDI32DeviceList[UNDI32Device->NIIProtocol_31.IfNum] = NULL;
> +  gBS->FreePool (UNDI32Device->Undi32DevPath);
> +
> +UndiErrorDeletePxe:
> +  PxeUpdate (NULL, pxe_31);
> +  if (TmpPxePointer != NULL) {
> +    gBS->FreePool (TmpPxePointer);
> +
> +  }
> +
> +UndiErrorDeleteDevice:
> +  if (PciAttributesSaved) {
> +    //
> +    // Restore original PCI attributes
> +    //
> +    PciIoFncs->Attributes (
> +                    PciIoFncs,
> +                    EfiPciIoAttributeOperationSet,
> +                    UNDI32Device->NicInfo.OriginalPciAttributes,
> +                    NULL
> +                    );
> +  }
> +
> +  gBS->FreePool (UNDI32Device);
> +
> +UndiError:
> +  gBS->CloseProtocol (
> +        Controller,
> +        &gEfiDevicePathProtocolGuid,
> +        This->DriverBindingHandle,
> +        Controller
> +        );
> +
> +  gBS->CloseProtocol (
> +        Controller,
> +        &gEfiPciIoProtocolGuid,
> +        This->DriverBindingHandle,
> +        Controller
> +        );
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Stop this driver on Controller by removing NetworkInterfaceIdentifier
> protocol and
> +  closing the DevicePath and PciIo protocols on Controller.
> +
> +  @param  This                 Protocol instance pointer.
> +  @param  Controller           Handle of device to stop driver on.
> +  @param  NumberOfChildren     How many children need to be stopped.
> +  @param  ChildHandleBuffer    Not used.
> +
> +  @retval EFI_SUCCESS          This driver is removed Controller.
> +  @retval other                This driver was not removed from this device.
> +
> +**/
> +// TODO:    EFI_DEVICE_ERROR - add return value to function comment
> +EFI_STATUS
> +EFIAPI
> +UndiDriverStop (
> +  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,
> +  IN  EFI_HANDLE                     Controller,
> +  IN  UINTN                          NumberOfChildren,
> +  IN  EFI_HANDLE                     *ChildHandleBuffer
> +  )
> +{
> +  EFI_STATUS                                Status;
> +  BOOLEAN                                   AllChildrenStopped;
> +  UINTN                                     Index;
> +  UNDI32_DEV                                *UNDI32Device;
> +  EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *NIIProtocol;
> +
> +  //
> +  // Complete all outstanding transactions to Controller.
> +  // Don't allow any new transaction to Controller to be started.
> +  //
> +  if (NumberOfChildren == 0) {
> +
> +    //
> +    // Close the bus driver
> +    //
> +    Status = gBS->CloseProtocol (
> +                    Controller,
> +                    &gEfiDevicePathProtocolGuid,
> +                    This->DriverBindingHandle,
> +                    Controller
> +                    );
> +
> +    Status = gBS->CloseProtocol (
> +                    Controller,
> +                    &gEfiPciIoProtocolGuid,
> +                    This->DriverBindingHandle,
> +                    Controller
> +                    );
> +
> +    return Status;
> +  }
> +
> +  AllChildrenStopped = TRUE;
> +
> +  for (Index = 0; Index < NumberOfChildren; Index++) {
> +
> +    Status = gBS->OpenProtocol (
> +                    ChildHandleBuffer[Index],
> +                    &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
> +                    (VOID **) &NIIProtocol,
> +                    This->DriverBindingHandle,
> +                    Controller,
> +                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                    );
> +    if (!EFI_ERROR (Status)) {
> +
> +      UNDI32Device = UNDI_DEV_FROM_THIS (NIIProtocol);
> +
> +      Status = gBS->CloseProtocol (
> +                      Controller,
> +                      &gEfiPciIoProtocolGuid,
> +                      This->DriverBindingHandle,
> +                      ChildHandleBuffer[Index]
> +                      );
> +      if (!EFI_ERROR (Status)) {
> +        Status = gBS->UninstallMultipleProtocolInterfaces (
> +                        ChildHandleBuffer[Index],
> +                        &gEfiDevicePathProtocolGuid,
> +                        UNDI32Device->Undi32DevPath,
> +                        &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
> +                        &UNDI32Device->NIIProtocol_31,
> +                        NULL
> +                        );
> +        if (!EFI_ERROR (Status)) {
> +          //
> +          // Restore original PCI attributes
> +          //
> +          Status = UNDI32Device->NicInfo.Io_Function->Attributes (
> +                                                        UNDI32Device->NicInfo.Io_Function,
> +                                                        EfiPciIoAttributeOperationSet,
> +                                                        UNDI32Device-
> >NicInfo.OriginalPciAttributes,
> +                                                        NULL
> +                                                        );
> +
> +          ASSERT_EFI_ERROR (Status);
> +
> +          gBS->FreePool (UNDI32Device->Undi32DevPath);
> +          gBS->FreePool (UNDI32Device);
> +
> +        }
> +      }
> +    }
> +
> +    if (EFI_ERROR (Status)) {
> +      AllChildrenStopped = FALSE;
> +    }
> +  }
> +
> +  if (!AllChildrenStopped) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +
> +}
> +
> +
> +/**
> +  Use the EFI boot services to produce a pause. This is also the routine
> which
> +  gets replaced during RunTime by the O/S in the NIC_DATA_INSTANCE so it
> can
> +  do it's own pause.
> +
> +  @param  UnqId                Runtime O/S routine might use this, this temp
> +                               routine does not use it
> +  @param  MicroSeconds         Determines the length of pause.
> +
> +  @return none
> +
> +**/
> +VOID
> +TmpDelay (
> +  IN UINT64 UnqId,
> +  IN UINTN  MicroSeconds
> +  )
> +{
> +  gBS->Stall ((UINT32) MicroSeconds);
> +}
> +
> +
> +/**
> +  Use the PCI IO abstraction to issue memory or I/O reads and writes.  This is
> also the routine which
> +  gets replaced during RunTime by the O/S in the NIC_DATA_INSTANCE so it
> can do it's own I/O abstractions.
> +
> +  @param  UnqId                Runtime O/S routine may use this field, this temp
> +                               routine does not.
> +  @param  ReadWrite            Determine if it is an I/O or Memory Read/Write
> +                               Operation.
> +  @param  Len                  Determines the width of the data operation.
> +  @param  Port                 What port to Read/Write from.
> +  @param  BuffAddr             Address to read to or write from.
> +
> +  @return none
> +
> +**/
> +VOID
> +TmpMemIo (
> +  IN UINT64 UnqId,
> +  IN UINT8  ReadWrite,
> +  IN UINT8  Len,
> +  IN UINT64 Port,
> +  IN UINT64 BuffAddr
> +  )
> +{
> +  EFI_PCI_IO_PROTOCOL_WIDTH Width;
> +  NIC_DATA_INSTANCE         *AdapterInfo;
> +
> +  Width       = (EFI_PCI_IO_PROTOCOL_WIDTH) 0;
> +  AdapterInfo = (NIC_DATA_INSTANCE *) (UINTN) UnqId;
> +  switch (Len) {
> +  case 2:
> +    Width = (EFI_PCI_IO_PROTOCOL_WIDTH) 1;
> +    break;
> +
> +  case 4:
> +    Width = (EFI_PCI_IO_PROTOCOL_WIDTH) 2;
> +    break;
> +
> +  case 8:
> +    Width = (EFI_PCI_IO_PROTOCOL_WIDTH) 3;
> +    break;
> +  }
> +
> +  switch (ReadWrite) {
> +  case PXE_IO_READ:
> +    AdapterInfo->Io_Function->Io.Read (
> +                                  AdapterInfo->Io_Function,
> +                                  Width,
> +                                  1,
> +                                  Port,
> +                                  1,
> +                                  (VOID *) (UINTN) (BuffAddr)
> +                                  );
> +    break;
> +
> +  case PXE_IO_WRITE:
> +    AdapterInfo->Io_Function->Io.Write (
> +                                  AdapterInfo->Io_Function,
> +                                  Width,
> +                                  1,
> +                                  Port,
> +                                  1,
> +                                  (VOID *) (UINTN) (BuffAddr)
> +                                  );
> +    break;
> +
> +  case PXE_MEM_READ:
> +    AdapterInfo->Io_Function->Mem.Read (
> +                                    AdapterInfo->Io_Function,
> +                                    Width,
> +                                    0,
> +                                    Port,
> +                                    1,
> +                                    (VOID *) (UINTN) (BuffAddr)
> +                                    );
> +    break;
> +
> +  case PXE_MEM_WRITE:
> +    AdapterInfo->Io_Function->Mem.Write (
> +                                    AdapterInfo->Io_Function,
> +                                    Width,
> +                                    0,
> +                                    Port,
> +                                    1,
> +                                    (VOID *) (UINTN) (BuffAddr)
> +                                    );
> +    break;
> +  }
> +
> +  return ;
> +}
> +
> +
> +/**
> +  Using the NIC data structure information, read the EEPROM to get the
> MAC address and then allocate space
> +  for a new devicepath (**DevPtr) which will contain the original device
> path the NIC was found on (*BaseDevPtr)
> +  and an added MAC node.
> +
> +  @param  DevPtr               Pointer which will point to the newly created
> device
> +                               path with the MAC node attached.
> +  @param  BaseDevPtr           Pointer to the device path which the UNDI
> device
> +                               driver is latching on to.
> +  @param  AdapterInfo          Pointer to the NIC data structure information
> which
> +                               the UNDI driver is layering on..
> +
> +  @retval EFI_SUCCESS          A MAC address was successfully appended to
> the Base
> +                               Device Path.
> +  @retval other                Not enough resources available to create new
> Device
> +                               Path node.
> +
> +**/
> +EFI_STATUS
> +AppendMac2DevPath (
> +  IN OUT  EFI_DEVICE_PATH_PROTOCOL **DevPtr,
> +  IN      EFI_DEVICE_PATH_PROTOCOL *BaseDevPtr,
> +  IN      NIC_DATA_INSTANCE        *AdapterInfo
> +  )
> +{
> +  EFI_MAC_ADDRESS           MACAddress;
> +  PCI_CONFIG_HEADER         *CfgHdr;
> +  INT32                     Val;
> +  INT32                     Index;
> +  INT32                     Index2;
> +  UINT8                     AddrLen;
> +  MAC_ADDR_DEVICE_PATH      MacAddrNode;
> +  EFI_DEVICE_PATH_PROTOCOL  *EndNode;
> +  UINT8                     *DevicePtr;
> +  UINT16                    TotalPathLen;
> +  UINT16                    BasePathLen;
> +  EFI_STATUS                Status;
> +
> +  //
> +  // set the environment ready (similar to UNDI_Start call) so that we can
> +  // execute the other UNDI_ calls to get the mac address
> +  // we are using undi 3.1 style
> +  //
> +  AdapterInfo->Delay      = TmpDelay;
> +  AdapterInfo->Virt2Phys  = (VOID *) 0;
> +  AdapterInfo->Block      = (VOID *) 0;
> +  AdapterInfo->Map_Mem    = (VOID *) 0;
> +  AdapterInfo->UnMap_Mem  = (VOID *) 0;
> +  AdapterInfo->Sync_Mem   = (VOID *) 0;
> +  AdapterInfo->Mem_Io     = TmpMemIo;
> +  //
> +  // these tmp call-backs follow 3.1 undi style
> +  // i.e. they have the unique_id parameter.
> +  //
> +  AdapterInfo->VersionFlag  = 0x31;
> +  AdapterInfo->Unique_ID    = (UINT64) (UINTN) AdapterInfo;
> +
> +  //
> +  // undi init portion
> +  //
> +  CfgHdr              = (PCI_CONFIG_HEADER *) &(AdapterInfo->Config[0]);
> +  AdapterInfo->ioaddr = 0;
> +  AdapterInfo->RevID  = CfgHdr->RevID;
> +
> +  AddrLen             = E100bGetEepromAddrLen (AdapterInfo);
> +
> +  for (Index = 0, Index2 = 0; Index < 3; Index++) {
> +    Val                       = E100bReadEeprom (AdapterInfo, Index, AddrLen);
> +    MACAddress.Addr[Index2++] = (UINT8) Val;
> +    MACAddress.Addr[Index2++] = (UINT8) (Val >> 8);
> +  }
> +
> +  SetMem (MACAddress.Addr + Index2, sizeof (EFI_MAC_ADDRESS) - Index2,
> 0);
> +  //for (; Index2 < sizeof (EFI_MAC_ADDRESS); Index2++) {
> +  //  MACAddress.Addr[Index2] = 0;
> +  //}
> +  //
> +  // stop undi
> +  //
> +  AdapterInfo->Delay  = (VOID *) 0;
> +  AdapterInfo->Mem_Io = (VOID *) 0;
> +
> +  //
> +  // fill the mac address node first
> +  //
> +  ZeroMem ((CHAR8 *) &MacAddrNode, sizeof MacAddrNode);
> +  CopyMem (
> +    (CHAR8 *) &MacAddrNode.MacAddress,
> +    (CHAR8 *) &MACAddress,
> +    sizeof (EFI_MAC_ADDRESS)
> +    );
> +
> +  MacAddrNode.Header.Type       = MESSAGING_DEVICE_PATH;
> +  MacAddrNode.Header.SubType    = MSG_MAC_ADDR_DP;
> +  MacAddrNode.Header.Length[0]  = (UINT8) sizeof (MacAddrNode);
> +  MacAddrNode.Header.Length[1]  = 0;
> +
> +  //
> +  // find the size of the base dev path.
> +  //
> +  EndNode = BaseDevPtr;
> +
> +  while (!IsDevicePathEnd (EndNode)) {
> +    EndNode = NextDevicePathNode (EndNode);
> +  }
> +
> +  BasePathLen = (UINT16) ((UINTN) (EndNode) - (UINTN) (BaseDevPtr));
> +
> +  //
> +  // create space for full dev path
> +  //
> +  TotalPathLen = (UINT16) (BasePathLen + sizeof (MacAddrNode) + sizeof
> (EFI_DEVICE_PATH_PROTOCOL));
> +
> +  Status = gBS->AllocatePool (
> +                  EfiRuntimeServicesData,
> +                  TotalPathLen,
> +                  (VOID **) &DevicePtr
> +                  );
> +
> +  if (Status != EFI_SUCCESS) {
> +    return Status;
> +  }
> +  //
> +  // copy the base path, mac addr and end_dev_path nodes
> +  //
> +  *DevPtr = (EFI_DEVICE_PATH_PROTOCOL *) DevicePtr;
> +  CopyMem (DevicePtr, (CHAR8 *) BaseDevPtr, BasePathLen);
> +  DevicePtr += BasePathLen;
> +  CopyMem (DevicePtr, (CHAR8 *) &MacAddrNode, sizeof (MacAddrNode));
> +  DevicePtr += sizeof (MacAddrNode);
> +  CopyMem (DevicePtr, (CHAR8 *) EndNode, sizeof
> (EFI_DEVICE_PATH_PROTOCOL));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Install a GUID/Pointer pair into the system's configuration table.
> +
> +  none
> +
> +  @retval EFI_SUCCESS          Install a GUID/Pointer pair into the system's
> +                               configuration table.
> +  @retval other                Did not successfully install the GUID/Pointer pair
> +                               into the configuration table.
> +
> +**/
> +// TODO:    VOID - add argument and description to function comment
> +EFI_STATUS
> +InstallConfigTable (
> +  IN VOID
> +  )
> +{
> +  EFI_STATUS              Status;
> +  EFI_CONFIGURATION_TABLE *CfgPtr;
> +  UNDI_CONFIG_TABLE       *TmpData;
> +  UINT16                  Index;
> +  UNDI_CONFIG_TABLE       *UndiData;
> +
> +  if (pxe_31 == NULL) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  if(UndiDataPointer == NULL) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  UndiData = (UNDI_CONFIG_TABLE *)UndiDataPointer;
> +
> +  UndiData->NumberOfInterfaces  = (pxe_31->IFcnt | pxe_31->IFcntExt << 8);
> +  UndiData->nextlink            = NULL;
> +
> +  for (Index = 0; Index < (pxe_31->IFcnt | pxe_31->IFcntExt << 8); Index++) {
> +    UndiData->NII_entry[Index].NII_InterfacePointer =
> &UNDI32DeviceList[Index]->NIIProtocol_31;
> +    UndiData->NII_entry[Index].DevicePathPointer    =
> UNDI32DeviceList[Index]->Undi32DevPath;
> +  }
> +
> +  //
> +  // see if there is an entry in the config table already
> +  //
> +  CfgPtr = gST->ConfigurationTable;
> +
> +  for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
> +    Status = CompareGuid (
> +              &CfgPtr->VendorGuid,
> +              &gEfiNetworkInterfaceIdentifierProtocolGuid_31
> +              );
> +    if (Status != EFI_SUCCESS) {
> +      break;
> +    }
> +
> +    CfgPtr++;
> +  }
> +
> +  if (Index < gST->NumberOfTableEntries) {
> +    TmpData = (UNDI_CONFIG_TABLE *) CfgPtr->VendorTable;
> +
> +    //
> +    // go to the last link
> +    //
> +    while (TmpData->nextlink != NULL) {
> +      TmpData = TmpData->nextlink;
> +    }
> +
> +    TmpData->nextlink = UndiData;
> +
> +    //
> +    // 1st one in chain
> +    //
> +    UndiData = (UNDI_CONFIG_TABLE *) CfgPtr->VendorTable;
> +  }
> +
> +  //
> +  // create an entry in the configuration table for our GUID
> +  //
> +  Status = gBS->InstallConfigurationTable (
> +                  &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
> +                  UndiData
> +                  );
> +  return Status;
> +}
> +
> +/**
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitializeUndi(
> +  IN EFI_HANDLE           ImageHandle,
> +  IN EFI_SYSTEM_TABLE     *SystemTable
> +  )
> +{
> +  EFI_EVENT     Event;
> +  EFI_STATUS    Status;
> +
> +  Status = EfiLibInstallDriverBindingComponentName2 (
> +             ImageHandle,
> +             SystemTable,
> +             &gUndiDriverBinding,
> +             ImageHandle,
> +             &gUndiComponentName,
> +             &gUndiComponentName2
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_NOTIFY,
> +                  UndiNotifyReadyToBoot,
> +                  NULL,
> +                  &gEfiEventReadyToBootGuid,
> +                  &Event
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_NOTIFY,
> +                  UndiNotifyVirtual,
> +                  NULL,
> +                  &gEfiEventVirtualAddressChangeGuid,
> +                  &Event
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> diff --git a/Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h
> b/Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h
> new file mode 100644
> index 0000000000..31c55a8e11
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h
> @@ -0,0 +1,439 @@
> +/** @file
> +  EFI internal structures for the EFI UNDI driver.
> +
> +Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _UNDI_32_H_
> +#define _UNDI_32_H_
> +
> +#include <Uefi.h>
> +
> +#include <Guid/EventGroup.h>
> +#include <Protocol/PciIo.h>
> +#include <Protocol/NetworkInterfaceIdentifier.h>
> +#include <Protocol/DevicePath.h>
> +#include <Protocol/AdapterInformation.h>
> +
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/UefiRuntimeLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +
> +#include <IndustryStandard/Pci.h>
> +
> +
> +#include "E100b.h"
> +
> +extern EFI_DRIVER_BINDING_PROTOCOL  gUndiDriverBinding;
> +extern EFI_COMPONENT_NAME_PROTOCOL  gUndiComponentName;
> +extern EFI_COMPONENT_NAME2_PROTOCOL gUndiComponentName2;
> +
> +#define MAX_NIC_INTERFACES 16
> +
> +#define EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION_31
> 0x00010001
> +#define PXE_ROMID_MINORVER_31 0x10
> +#define PXE_STATFLAGS_DB_WRITE_TRUNCATED  0x2000
> +
> +//
> +// UNDI_CALL_TABLE.state can have the following values
> +//
> +#define DONT_CHECK -1
> +#define ANY_STATE -1
> +#define MUST_BE_STARTED 1
> +#define MUST_BE_INITIALIZED 2
> +
> +#define UNDI_DEV_SIGNATURE   SIGNATURE_32('u','n','d','i')
> +#define UNDI_DEV_FROM_THIS(a) CR(a, UNDI32_DEV, NIIProtocol_31,
> UNDI_DEV_SIGNATURE)
> +#define UNDI_DEV_FROM_NIC(a) CR(a, UNDI32_DEV, NicInfo,
> UNDI_DEV_SIGNATURE)
> +#define UNDI_DEV_FROM_AIP(a) CR(a, UNDI32_DEV, Aip,
> UNDI_DEV_SIGNATURE)
> +
> +typedef struct {
> +  UINTN                                     Signature;
> +  EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL NIIProtocol_31;
> +  EFI_ADAPTER_INFORMATION_PROTOCOL          Aip;
> +  EFI_HANDLE                                DeviceHandle;
> +  EFI_DEVICE_PATH_PROTOCOL                  *Undi32BaseDevPath;
> +  EFI_DEVICE_PATH_PROTOCOL                  *Undi32DevPath;
> +  NIC_DATA_INSTANCE                         NicInfo;
> +} UNDI32_DEV;
> +
> +typedef struct {
> +  UINT16 cpbsize;
> +  UINT16 dbsize;
> +  UINT16 opflags;
> +  UINT16 state;
> +  VOID (*api_ptr)();
> +} UNDI_CALL_TABLE;
> +
> +typedef VOID (*ptr)(VOID);
> +typedef VOID (*bsptr_30)(UINTN);
> +typedef VOID (*virtphys_30)(UINT64, UINT64);
> +typedef VOID (*block_30)(UINT32);
> +typedef VOID (*mem_io_30)(UINT8, UINT8, UINT64, UINT64);
> +
> +typedef VOID (*bsptr)(UINT64, UINTN);
> +typedef VOID (*virtphys)(UINT64, UINT64, UINT64);
> +typedef VOID (*block)(UINT64, UINT32);
> +typedef VOID (*mem_io)(UINT64, UINT8, UINT8, UINT64, UINT64);
> +
> +typedef VOID (*map_mem)(UINT64, UINT64, UINT32, UINT32, UINT64);
> +typedef VOID (*unmap_mem)(UINT64, UINT64, UINT32, UINT32, UINT64);
> +typedef VOID (*sync_mem)(UINT64, UINT64, UINT32, UINT32, UINT64);
> +
> +extern UNDI_CALL_TABLE  api_table[];
> +extern PXE_SW_UNDI      *pxe_31;  // !pxe structure for 3.1 drivers
> +extern UNDI32_DEV       *UNDI32DeviceList[MAX_NIC_INTERFACES];
> +
> +//
> +// functions defined in e100b.c
> +//
> +UINT8 InByte (NIC_DATA_INSTANCE *AdapterInfo, UINT32 Port);
> +UINT16 InWord (NIC_DATA_INSTANCE *AdapterInfo, UINT32 Port);
> +UINT32 InLong (NIC_DATA_INSTANCE *AdapterInfo, UINT32 Port);
> +VOID  OutByte (NIC_DATA_INSTANCE *AdapterInfo, UINT8 Data, UINT32
> Port);
> +VOID  OutWord (NIC_DATA_INSTANCE *AdapterInfo, UINT16 Data, UINT32
> Port);
> +VOID  OutLong (NIC_DATA_INSTANCE *AdapterInfo, UINT32 Data, UINT32
> Port);
> +
> +UINTN E100bInit (NIC_DATA_INSTANCE *AdapterInfo);
> +UINTN E100bReset (NIC_DATA_INSTANCE *AdapterInfo, INT32 OpFlags);
> +UINTN E100bShutdown (NIC_DATA_INSTANCE *AdapterInfo);
> +UINTN E100bTransmit (NIC_DATA_INSTANCE *AdapterInfo, UINT64 cpb,
> UINT16 opflags);
> +UINTN E100bReceive (NIC_DATA_INSTANCE *AdapterInfo, UINT64 cpb,
> UINT64 db);
> +UINTN E100bSetfilter (NIC_DATA_INSTANCE *AdapterInfo, UINT16
> New_filter,
> +                      UINT64 cpb, UINT32 cpbsize);
> +UINTN E100bStatistics(NIC_DATA_INSTANCE *AdapterInfo, UINT64 db,
> UINT16 dbsize);
> +UINT8 E100bSetupIAAddr (NIC_DATA_INSTANCE *AdapterInfo);
> +UINT8 E100bSetInterruptState (NIC_DATA_INSTANCE *AdapterInfo);
> +
> +UINT8 E100bGetEepromAddrLen (NIC_DATA_INSTANCE *AdapterInfo);
> +UINT16 E100bReadEeprom (NIC_DATA_INSTANCE *AdapterInfo, INT32
> Location, UINT8 address_len);
> +INT16 E100bReadEepromAndStationAddress (NIC_DATA_INSTANCE
> *AdapterInfo);
> +
> +UINT16 next(UINT16);
> +UINT8 SetupCBlink (NIC_DATA_INSTANCE *AdapterInfo);
> +VOID SetFreeCB (NIC_DATA_INSTANCE *AdapterInfo,TxCB *);
> +TxCB *GetFreeCB (NIC_DATA_INSTANCE *AdapterInfo);
> +UINT16 CheckCBList (NIC_DATA_INSTANCE *AdapterInfo);
> +
> +UINT8 SelectiveReset (NIC_DATA_INSTANCE *AdapterInfo);
> +UINT16 InitializeChip (NIC_DATA_INSTANCE *AdapterInfo);
> +UINT8 SetupReceiveQueues (NIC_DATA_INSTANCE *AdapterInfo);
> +VOID  Recycle_RFD (NIC_DATA_INSTANCE *AdapterInfo, UINT16);
> +VOID XmitWaitForCompletion (NIC_DATA_INSTANCE *AdapterInfo);
> +INT8 CommandWaitForCompletion (TxCB *cmd_ptr, NIC_DATA_INSTANCE
> *AdapterInfo);
> +
> +BOOLEAN PhyDetect (NIC_DATA_INSTANCE *AdapterInfo);
> +VOID PhyReset (NIC_DATA_INSTANCE *AdapterInfo);
> +VOID
> +MdiWrite (
> +  IN NIC_DATA_INSTANCE *AdapterInfo,
> +  IN UINT8 RegAddress,
> +  IN UINT8 PhyAddress,
> +  IN UINT16 DataValue
> +  );
> +
> +VOID
> +MdiRead(
> +  IN NIC_DATA_INSTANCE *AdapterInfo,
> +  IN UINT8 RegAddress,
> +  IN UINT8 PhyAddress,
> +  IN OUT UINT16 *DataValue
> +  );
> +
> +BOOLEAN SetupPhy (NIC_DATA_INSTANCE *AdapterInfo);
> +VOID FindPhySpeedAndDpx (NIC_DATA_INSTANCE *AdapterInfo, UINT32
> PhyId);
> +
> +
> +
> +//
> +// functions defined in init.c
> +//
> +EFI_STATUS
> +InstallConfigTable (
> +  IN VOID
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +InitializeUNDIDriver (
> +  IN EFI_HANDLE           ImageHandle,
> +  IN EFI_SYSTEM_TABLE     *SystemTable
> +  );
> +
> +VOID
> +UNDI_notify_virtual (
> +  EFI_EVENT event,
> +  VOID      *context
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +UndiDriverSupported (
> +  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
> +  IN EFI_HANDLE                     Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +UndiDriverStart (
> +  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
> +  IN EFI_HANDLE                     Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +UndiDriverStop (
> +  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,
> +  IN  EFI_HANDLE                     Controller,
> +  IN  UINTN                          NumberOfChildren,
> +  IN  EFI_HANDLE                     *ChildHandleBuffer
> +  );
> +
> +EFI_STATUS
> +AppendMac2DevPath (
> +  IN OUT  EFI_DEVICE_PATH_PROTOCOL **DevPtr,
> +  IN      EFI_DEVICE_PATH_PROTOCOL *BaseDevPtr,
> +  IN      NIC_DATA_INSTANCE        *AdapterInfo
> +  );
> +
> +VOID
> +TmpDelay (
> +  IN UINT64 UnqId,
> +  IN UINTN MicroSeconds
> +  );
> +
> +VOID
> +TmpMemIo (
> +  IN UINT64 UnqId,
> +  IN UINT8 ReadWrite,
> +  IN UINT8 Len,
> +  IN UINT64 Port,
> +  IN UINT64 BufAddr
> +  );
> +
> +//
> +// functions defined in decode.c
> +//
> +VOID
> +UNDI_GetState (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  );
> +
> +VOID
> +UNDI_Start (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  );
> +
> +VOID
> +UNDI_Stop (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  );
> +
> +VOID
> +UNDI_GetInitInfo (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  );
> +
> +VOID
> +UNDI_GetConfigInfo (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  );
> +
> +VOID
> +UNDI_Initialize (
> +  IN  PXE_CDB       *CdbPtr,
> +  NIC_DATA_INSTANCE *AdapterInfo
> +  );
> +
> +VOID
> +UNDI_Reset (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  );
> +
> +VOID
> +UNDI_Shutdown (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  );
> +
> +VOID
> +UNDI_Interrupt (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  );
> +
> +VOID
> +UNDI_RecFilter (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  );
> +
> +VOID
> +UNDI_StnAddr (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  );
> +
> +VOID
> +UNDI_Statistics (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  );
> +
> +VOID
> +UNDI_ip2mac (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  );
> +
> +VOID
> +UNDI_NVData (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  );
> +
> +VOID
> +UNDI_Status (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  );
> +
> +VOID
> +UNDI_FillHeader (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  );
> +
> +VOID
> +UNDI_Transmit (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  );
> +
> +VOID
> +UNDI_Receive (
> +  IN  PXE_CDB           *CdbPtr,
> +  IN  NIC_DATA_INSTANCE *AdapterInfo
> +  );
> +
> +VOID EFIAPI UNDI_APIEntry_new(UINT64);
> +VOID UNDI_APIEntry_Common(UINT64);
> +
> +PXE_IPV4 convert_mcip(PXE_MAC_ADDR *);
> +INT32 validate_mcip (PXE_MAC_ADDR *MCastAddr);
> +
> +VOID PxeStructInit (PXE_SW_UNDI *PxePtr);
> +VOID PxeUpdate (NIC_DATA_INSTANCE *NicPtr, PXE_SW_UNDI *PxePtr);
> +
> +//
> +// functions defined in UndiAipImpl.c
> +//
> +
> +/**
> +  Returns the current state information for the adapter.
> +
> +  This function returns information of type InformationType from the
> adapter.
> +  If an adapter does not support the requested informational type, then
> +  EFI_UNSUPPORTED is returned.
> +
> +  @param[in]  This                   A pointer to the
> EFI_ADAPTER_INFORMATION_PROTOCOL instance.
> +  @param[in]  InformationType        A pointer to an EFI_GUID that defines
> the contents of InformationBlock.
> +  @param[out] InforamtionBlock       The service returns a pointer to the
> buffer with the InformationBlock
> +                                     structure which contains details about the data
> specific to InformationType.
> +  @param[out] InforamtionBlockSize   The driver returns the size of the
> InformationBlock in bytes.
> +
> +  @retval EFI_SUCCESS                The InformationType information was
> retrieved.
> +  @retval EFI_UNSUPPORTED            The InformationType is not known.
> +  @retval EFI_DEVICE_ERROR           The device reported an error.
> +  @retval EFI_OUT_OF_RESOURCES       The request could not be completed
> due to a lack of resources.
> +  @retval EFI_INVALID_PARAMETER      This is NULL.
> +  @retval EFI_INVALID_PARAMETER      InformationBlock is NULL.
> +  @retval EFI_INVALID_PARAMETER      InformationBlockSize is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UndiAipGetInfo (
> +  IN   EFI_ADAPTER_INFORMATION_PROTOCOL *This,
> +  IN   EFI_GUID                         *InformationType,
> +  OUT  VOID                             **InformationBlock,
> +  OUT  UINTN                            *InformationBlockSize
> +  );
> +
> +/**
> +  Sets state information for an adapter.
> +
> +  This function sends information of type InformationType for an adapter.
> +  If an adapter does not support the requested information type, then
> EFI_UNSUPPORTED
> +  is returned.
> +
> +  @param[in]  This                   A pointer to the
> EFI_ADAPTER_INFORMATION_PROTOCOL instance.
> +  @param[in]  InformationType        A pointer to an EFI_GUID that defines
> the contents of InformationBlock.
> +  @param[in]  InforamtionBlock       A pointer to the InformationBlock
> structure which contains details
> +                                     about the data specific to InformationType.
> +  @param[in]  InforamtionBlockSize   The size of the InformationBlock in
> bytes.
> +
> +  @retval EFI_SUCCESS                The information was received and
> interpreted successfully.
> +  @retval EFI_UNSUPPORTED            The InformationType is not known.
> +  @retval EFI_DEVICE_ERROR           The device reported an error.
> +  @retval EFI_INVALID_PARAMETER      This is NULL.
> +  @retval EFI_INVALID_PARAMETER      InformationBlock is NULL.
> +  @retval EFI_WRITE_PROTECTED        The InformationType cannot be
> modified using EFI_ADAPTER_INFO_SET_INFO().
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UndiAipSetInfo (
> +  IN   EFI_ADAPTER_INFORMATION_PROTOCOL *This,
> +  IN   EFI_GUID                         *InformationType,
> +  IN   VOID                             *InformationBlock,
> +  IN   UINTN                            InformationBlockSize
> +  );
> +
> +/**
> +  Get a list of supported information types for this instance of the protocol.
> +
> +  This function returns a list of InformationType GUIDs that are supported
> on an
> +  adapter with this instance of EFI_ADAPTER_INFORMATION_PROTOCOL.
> The list is returned
> +  in InfoTypesBuffer, and the number of GUID pointers in InfoTypesBuffer is
> returned in
> +  InfoTypesBufferCount.
> +
> +  @param[in]  This                  A pointer to the
> EFI_ADAPTER_INFORMATION_PROTOCOL instance.
> +  @param[out] InfoTypesBuffer       A pointer to the list of InformationType
> GUID pointers that are supported
> +                                    by This.
> +  @param[out] InfoTypesBufferCount  A pointer to the number of GUID
> pointers present in InfoTypesBuffer.
> +
> +  @retval EFI_SUCCESS               The list of information type GUIDs that are
> supported on this adapter was
> +                                    returned in InfoTypesBuffer. The number of
> information type GUIDs was
> +                                    returned in InfoTypesBufferCount.
> +  @retval EFI_INVALID_PARAMETER     This is NULL.
> +  @retval EFI_INVALID_PARAMETER     InfoTypesBuffer is NULL.
> +  @retval EFI_INVALID_PARAMETER     InfoTypesBufferCount is NULL.
> +  @retval EFI_OUT_OF_RESOURCES      There is not enough pool memory to
> store the results.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UndiAipGetSupportedTypes (
> +  IN    EFI_ADAPTER_INFORMATION_PROTOCOL *This,
> +  OUT   EFI_GUID                         **InfoTypesBuffer,
> +  OUT   UINTN                            *InfoTypesBufferCount
> +  );
> +
> +#endif
> diff --git a/Drivers/OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c
> b/Drivers/OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c
> new file mode 100644
> index 0000000000..21151a076f
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c
> @@ -0,0 +1,145 @@
> +/** @file
> +
> +Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +
> +#include "Undi32.h"
> +
> +
> +UINTN      mSupportedInfoTypesCount = 1;
> +EFI_GUID   mSupportedInfoTypes[] = {
> +  EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT_GUID
> +};
> +
> +/**
> +  Returns the current state information for the adapter.
> +
> +  This function returns information of type InformationType from the
> adapter.
> +  If an adapter does not support the requested informational type, then
> +  EFI_UNSUPPORTED is returned.
> +
> +  @param[in]  This                   A pointer to the
> EFI_ADAPTER_INFORMATION_PROTOCOL instance.
> +  @param[in]  InformationType        A pointer to an EFI_GUID that defines
> the contents of InformationBlock.
> +  @param[out] InforamtionBlock       The service returns a pointer to the
> buffer with the InformationBlock
> +                                     structure which contains details about the data
> specific to InformationType.
> +  @param[out] InforamtionBlockSize   The driver returns the size of the
> InformationBlock in bytes.
> +
> +  @retval EFI_SUCCESS                The InformationType information was
> retrieved.
> +  @retval EFI_UNSUPPORTED            The InformationType is not known.
> +  @retval EFI_DEVICE_ERROR           The device reported an error.
> +  @retval EFI_OUT_OF_RESOURCES       The request could not be completed
> due to a lack of resources.
> +  @retval EFI_INVALID_PARAMETER      This is NULL.
> +  @retval EFI_INVALID_PARAMETER      InformationBlock is NULL.
> +  @retval EFI_INVALID_PARAMETER      InformationBlockSize is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UndiAipGetInfo (
> +  IN   EFI_ADAPTER_INFORMATION_PROTOCOL *This,
> +  IN   EFI_GUID                         *InformationType,
> +  OUT  VOID                             **InformationBlock,
> +  OUT  UINTN                            *InformationBlockSize
> +  )
> +{
> +  UNDI32_DEV                            *UNDI32Device;
> +  EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT    *UndiIpv6Support;
> +
> +  if (This == NULL || InformationBlock == NULL || InformationBlockSize ==
> NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (!CompareGuid (InformationType,
> &gEfiAdapterInfoUndiIpv6SupportGuid)) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  UNDI32Device = UNDI_DEV_FROM_AIP (This);
> +  *InformationBlockSize = sizeof
> (EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT);
> +  *InformationBlock = AllocateZeroPool (*InformationBlockSize);
> +  if (*InformationBlock == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  UndiIpv6Support = (EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT *)
> (*InformationBlock);
> +  UndiIpv6Support->Ipv6Support = UNDI32Device-
> >NIIProtocol_31.Ipv6Supported;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Sets state information for an adapter.
> +
> +  This function sends information of type InformationType for an adapter.
> +  If an adapter does not support the requested information type, then
> EFI_UNSUPPORTED
> +  is returned.
> +
> +  @param[in]  This                   A pointer to the
> EFI_ADAPTER_INFORMATION_PROTOCOL instance.
> +  @param[in]  InformationType        A pointer to an EFI_GUID that defines
> the contents of InformationBlock.
> +  @param[in]  InforamtionBlock       A pointer to the InformationBlock
> structure which contains details
> +                                     about the data specific to InformationType.
> +  @param[in]  InforamtionBlockSize   The size of the InformationBlock in
> bytes.
> +
> +  @retval EFI_SUCCESS                The information was received and
> interpreted successfully.
> +  @retval EFI_UNSUPPORTED            The InformationType is not known.
> +  @retval EFI_DEVICE_ERROR           The device reported an error.
> +  @retval EFI_INVALID_PARAMETER      This is NULL.
> +  @retval EFI_INVALID_PARAMETER      InformationBlock is NULL.
> +  @retval EFI_WRITE_PROTECTED        The InformationType cannot be
> modified using EFI_ADAPTER_INFO_SET_INFO().
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UndiAipSetInfo (
> +  IN   EFI_ADAPTER_INFORMATION_PROTOCOL *This,
> +  IN   EFI_GUID                         *InformationType,
> +  IN   VOID                             *InformationBlock,
> +  IN   UINTN                            InformationBlockSize
> +  )
> +{
> +  return EFI_WRITE_PROTECTED;
> +}
> +
> +/**
> +  Get a list of supported information types for this instance of the protocol.
> +
> +  This function returns a list of InformationType GUIDs that are supported
> on an
> +  adapter with this instance of EFI_ADAPTER_INFORMATION_PROTOCOL.
> The list is returned
> +  in InfoTypesBuffer, and the number of GUID pointers in InfoTypesBuffer is
> returned in
> +  InfoTypesBufferCount.
> +
> +  @param[in]  This                  A pointer to the
> EFI_ADAPTER_INFORMATION_PROTOCOL instance.
> +  @param[out] InfoTypesBuffer       A pointer to the list of InformationType
> GUID pointers that are supported
> +                                    by This.
> +  @param[out] InfoTypesBufferCount  A pointer to the number of GUID
> pointers present in InfoTypesBuffer.
> +
> +  @retval EFI_SUCCESS               The list of information type GUIDs that are
> supported on this adapter was
> +                                    returned in InfoTypesBuffer. The number of
> information type GUIDs was
> +                                    returned in InfoTypesBufferCount.
> +  @retval EFI_INVALID_PARAMETER     This is NULL.
> +  @retval EFI_INVALID_PARAMETER     InfoTypesBuffer is NULL.
> +  @retval EFI_INVALID_PARAMETER     InfoTypesBufferCount is NULL.
> +  @retval EFI_OUT_OF_RESOURCES      There is not enough pool memory to
> store the results.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UndiAipGetSupportedTypes (
> +  IN    EFI_ADAPTER_INFORMATION_PROTOCOL *This,
> +  OUT   EFI_GUID                         **InfoTypesBuffer,
> +  OUT   UINTN                            *InfoTypesBufferCount
> +  )
> +{
> +  if (This == NULL || InfoTypesBuffer == NULL || InfoTypesBufferCount ==
> NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *InfoTypesBufferCount = 1;
> +  *InfoTypesBuffer = AllocateCopyPool (sizeof (EFI_GUID),
> &gEfiAdapterInfoUndiIpv6SupportGuid);
> +  if (InfoTypesBuffer == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Drivers/OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf
> b/Drivers/OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf
> new file mode 100644
> index 0000000000..96666dc88a
> --- /dev/null
> +++ b/Drivers/OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf
> @@ -0,0 +1,72 @@
> +## @file
> +# Component description file for Undi module.
> +#
> +# This module provides support for Universal Network Driver Interface.
> +# Notes: this module is no longer regular maintained/validated.
> +#
> +# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = UndiRuntimeDxe
> +  FILE_GUID                      = A1f436EA-A127-4EF8-957C-8048606FF670
> +  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
> +  VERSION_STRING                 = 1.0
> +
> +  ENTRY_POINT                    = InitializeUndi
> +
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +
> +[Sources]
> +  Undi32.h
> +  E100b.h
> +  E100b.c
> +  Decode.c
> +  Init.c
> +  ComponentName.c
> +  UndiAipImpl.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> +  UefiLib
> +  UefiBootServicesTableLib
> +  BaseMemoryLib
> +  DebugLib
> +  UefiRuntimeLib
> +  UefiDriverEntryPoint
> +  BaseLib
> +  MemoryAllocationLib
> +
> +[Protocols]
> +  gEfiNetworkInterfaceIdentifierProtocolGuid_31
> +  gEfiPciIoProtocolGuid
> +  gEfiDevicePathProtocolGuid
> +  gEfiAdapterInformationProtocolGuid
> +
> +[Guids]
> +  gEfiEventExitBootServicesGuid        ## PRODUCES ## Event
> +  gEfiEventVirtualAddressChangeGuid    ## PRODUCES ## Event
> +  gEfiAdapterInfoUndiIpv6SupportGuid   ## PRODUCES
> +
> +[Depex]
> +  gEfiBdsArchProtocolGuid AND
> +  gEfiCpuArchProtocolGuid AND
> +  gEfiMetronomeArchProtocolGuid AND
> +  gEfiMonotonicCounterArchProtocolGuid AND
> +  gEfiRealTimeClockArchProtocolGuid AND
> +  gEfiResetArchProtocolGuid AND
> +  gEfiRuntimeArchProtocolGuid AND
> +  gEfiSecurityArchProtocolGuid AND
> +  gEfiTimerArchProtocolGuid AND
> +  gEfiVariableWriteArchProtocolGuid AND
> +  gEfiVariableArchProtocolGuid AND
> +  gEfiWatchdogTimerArchProtocolGuid
> --
> 2.21.0.windows.1


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [edk2-platforms: Patch 0/8] Add packages from edk2
  2019-05-10  3:34 [edk2-platforms: Patch 0/8] Add packages from edk2 Michael D Kinney
                   ` (8 preceding siblings ...)
  2019-05-10  5:14 ` [edk2-devel] [edk2-platforms: Patch 0/8] Add packages from edk2 Liming Gao
@ 2019-05-11  2:12 ` Ni, Ray
  2019-05-13 21:03 ` Steele, Kelly
  10 siblings, 0 replies; 23+ messages in thread
From: Ni, Ray @ 2019-05-11  2:12 UTC (permalink / raw)
  To: Kinney, Michael D, devel@edk2.groups.io
  Cc: Sun, Zailiang, Qian, Yi, Steele, Kelly, Kubacki, Michael A,
	Leif Lindholm, Ard Biesheuvel

Reviewed-by: Ray Ni <ray.ni@intel.com>

> -----Original Message-----
> From: Kinney, Michael D
> Sent: Friday, May 10, 2019 11:34 AM
> To: devel@edk2.groups.io
> Cc: Sun, Zailiang <zailiang.sun@intel.com>; Qian, Yi <yi.qian@intel.com>;
> Steele, Kelly <kelly.steele@intel.com>; Ni, Ray <ray.ni@intel.com>; Kubacki,
> Michael A <michael.a.kubacki@intel.com>; Leif Lindholm
> <leif.lindholm@linaro.org>; Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Subject: [edk2-platforms: Patch 0/8] Add packages from edk2
> 
> https://bugzilla.tianocore.org/show_bug.cgi?id=1467
> https://bugzilla.tianocore.org/show_bug.cgi?id=1374
> https://bugzilla.tianocore.org/show_bug.cgi?id=1793
> 
> Add the following platform, silicon, and driver packages from the edk2 repo
> to the edk2-platforms repo
> * Drivers/OptionRomPkg
> * Platform/BeagleBoard/BeagleBoardPkg
> * Platform/Intel/QuarkPlatformPkg
> * Platform/Intel/Vlv2TbltDevicePkg
> * Silicon/Intel/QuarkSocPkg
> * Silicon/Intel/Vlv2DeviceRefCodePkg
> * Silicon/TexasInsturments/Omap35xxPkg
> 
> Cc: Zailiang Sun <zailiang.sun@intel.com>
> Cc: Yi Qian <yi.qian@intel.com>
> Cc: Kelly Steele <kelly.steele@intel.com>
> Cc: Ray Ni <ray.ni@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>
> 
> Michael D Kinney (8):
>   Silicon/TexasInsturments: Import Omap35xxPkg from edk2
>   Platform/BeagleBoard: Import BeagleBoardPkg from edk2
>   Silicon/Intel: Import QuarkSocPkg from edk2
>   Platform/QuarkPlatformPkg: Import QuarkPlatformPkg from edk2
>   Platform/Vlv2DeviceRefCodePkg: Import Vlv2DeviceRefCodePkg from edk2
>   Platform/Vlv2TbltDevicePkg: Import Vlv2TbltDevicePkg from edk2
>   Drivers/OptionRomPkg: Import OptionRomPkg from edk2
>   edk2-platforms: Update Maintainers.txt/Readme.md for imported packages
> 
>  .../Application/BltLibSample/BltLibSample.c   |  279 +
>  .../Application/BltLibSample/BltLibSample.inf |   30 +
>  .../AtapiPassThruDxe/AtapiPassThru.c          | 3410 +++++++++++++
>  .../AtapiPassThruDxe/AtapiPassThru.h          | 1618 ++++++
>  .../AtapiPassThruDxe/AtapiPassThruDxe.inf     |   70 +
>  .../AtapiPassThruDxe/ComponentName.c          |  169 +
>  .../DriverSupportedEfiVersion.c               |   14 +
>  .../FtdiUsbSerialDxe/CompatibleDevices.txt    |    5 +
>  .../Bus/Usb/FtdiUsbSerialDxe/ComponentName.c  |  218 +
>  .../FtdiUsbSerialDxe/FtdiUsbSerialDriver.c    | 2580 ++++++++++
>  .../FtdiUsbSerialDxe/FtdiUsbSerialDriver.h    |  589 +++
>  .../Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf |   55 +
>  .../Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt       |   32 +
>  .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.c   | 1318 +++++
>  .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.h   |  969 ++++
>  .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf |   61 +
>  .../Usb/UsbNetworking/Ax88772/ComponentName.c |  178 +
>  .../Usb/UsbNetworking/Ax88772/DriverBinding.c |  507 ++
>  .../Usb/UsbNetworking/Ax88772/SimpleNetwork.c | 1503 ++++++
>  .../Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c  |  875 ++++
>  .../Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h  | 1026 ++++
>  .../Usb/UsbNetworking/Ax88772b/Ax88772b.inf   |   61 +
>  .../UsbNetworking/Ax88772b/ComponentName.c    |  175 +
>  .../UsbNetworking/Ax88772b/DriverBinding.c    |  696 +++
>  .../UsbNetworking/Ax88772b/SimpleNetwork.c    | 1657 ++++++
>  .../CirrusLogic5430Dxe/CirrusLogic5430.c      |  917 ++++
>  .../CirrusLogic5430Dxe/CirrusLogic5430.h      |  432 ++
>  .../CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf |   84 +
>  .../CirrusLogic5430GraphicsOutput.c           |  556 ++
>  .../CirrusLogic5430Dxe/CirrusLogic5430I2c.c   |  427 ++
>  .../CirrusLogic5430Dxe/CirrusLogic5430I2c.h   |   62 +
>  .../CirrusLogic5430UgaDraw.c                  |  412 ++
>  .../CirrusLogic5430Dxe/ComponentName.c        |  203 +
>  .../DriverSupportedEfiVersion.c               |   14 +
>  .../OptionRomPkg/CirrusLogic5430Dxe/Edid.c    |  525 ++
>  Drivers/OptionRomPkg/Include/Library/BltLib.h |  253 +
>  .../FrameBufferBltLib/FrameBufferBltLib.c     |  744 +++
>  .../FrameBufferBltLib/FrameBufferBltLib.inf   |   29 +
>  .../Library/GopBltLib/GopBltLib.c             |  449 ++
>  .../Library/GopBltLib/GopBltLib.inf           |   31 +
>  Drivers/OptionRomPkg/OptionRomPkg.dec         |   41 +
>  Drivers/OptionRomPkg/OptionRomPkg.dsc         |  113 +
>  Drivers/OptionRomPkg/ReadMe.txt               |   17 +
>  .../UndiRuntimeDxe/ComponentName.c            |  359 ++
>  Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c  | 1516 ++++++
>  Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c   | 3541 +++++++++++++
>  Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h   |  665 +++
>  Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c    | 1051 ++++
>  Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h  |  439 ++
>  .../OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c |  145 +
>  .../UndiRuntimeDxe/UndiRuntimeDxe.inf         |   72 +
>  Maintainers.txt                               |   20 +
>  .../BeagleBoardPkg/BeagleBoardPkg.dec         |   30 +
>  .../BeagleBoardPkg/BeagleBoardPkg.dsc         |  496 ++
>  .../BeagleBoardPkg/BeagleBoardPkg.fdf         |  308 ++
>  .../BeagleBoardPkg/ConfigurationHeader.bin    |  Bin 0 -> 512 bytes
>  .../BeagleBoardPkg/ConfigurationHeader.dat    |   41 +
>  .../Debugger_scripts/rvi_boot_from_ram.inc    |   15 +
>  .../Debugger_scripts/rvi_convert_symbols.sh   |   17 +
>  .../Debugger_scripts/rvi_dummy.axf            |  Bin 0 -> 7984 bytes
>  .../Debugger_scripts/rvi_hw_setup.inc         |   61 +
>  .../Debugger_scripts/rvi_load_symbols.inc     |   17 +
>  .../Debugger_scripts/rvi_symbols_macros.inc   |  188 +
>  .../Debugger_scripts/rvi_unload_symbols.inc   |  112 +
>  .../Debugger_scripts/trace32_load_symbols.cmm |  205 +
>  .../trace32_load_symbols_cygwin.cmm           |  182 +
>  .../BeagleBoardPkg/Include/BeagleBoard.h      |  173 +
>  .../Library/BeagleBoardLib/BeagleBoard.c      |  115 +
>  .../BeagleBoardLib/BeagleBoardHelper.S        |   41 +
>  .../BeagleBoardLib/BeagleBoardHelper.asm      |   47 +
>  .../Library/BeagleBoardLib/BeagleBoardLib.inf |   48 +
>  .../Library/BeagleBoardLib/BeagleBoardMem.c   |   74 +
>  .../Library/BeagleBoardLib/Clock.c            |   63 +
>  .../Library/BeagleBoardLib/PadConfiguration.c |  316 ++
>  .../Library/DxeHobPeCoffLib/DxeHobPeCoff.c    |  282 ++
>  .../DxeHobPeCoffLib/DxeHobPeCoffLib.inf       |   39 +
>  .../LzmaHobCustomDecompressLib.c              |   44 +
>  .../LzmaHobCustomDecompressLib.inf            |   45 +
>  .../MemoryInitPeiLib/MemoryInitPeiLib.c       |  192 +
>  .../MemoryInitPeiLib/MemoryInitPeiLib.inf     |   58 +
>  .../Library/ResetSystemLib/ResetSystemLib.c   |  149 +
>  .../Library/ResetSystemLib/ResetSystemLib.inf |   37 +
>  .../BeagleBoardPkg/PrePi/Arm/ArchPrePi.c      |   23 +
>  .../PrePi/Arm/ModuleEntryPoint.S              |  124 +
>  .../PrePi/Arm/ModuleEntryPoint.asm            |  142 +
>  .../BeagleBoardPkg/PrePi/LzmaDecompress.h     |   97 +
>  .../BeagleBoardPkg/PrePi/MainUniCore.c        |   33 +
>  .../BeagleBoardPkg/PrePi/PeiUniCore.inf       |   97 +
>  .../BeagleBoard/BeagleBoardPkg/PrePi/PrePi.c  |  179 +
>  .../BeagleBoard/BeagleBoardPkg/PrePi/PrePi.h  |   90 +
>  .../BeagleBoardPkg/Tools/GNUmakefile          |   14 +
>  .../BeagleBoardPkg/Tools/generate_image.c     |  402 ++
>  .../BeagleBoard/BeagleBoardPkg/Tools/makefile |   16 +
>  .../BeagleBoardPkg/Tools/replace.c            |  140 +
>  .../Acpi/AcpiTables/AcpiTables.inf            |   42 +
>  .../Acpi/AcpiTables/Cpu0Cst/Cpu0Cst.asl       |  399 ++
>  .../Acpi/AcpiTables/Cpu0Ist/Cpu0Ist.asl       |  159 +
>  .../Acpi/AcpiTables/Cpu0Tst/Cpu0Tst.asl       |  133 +
>  .../Acpi/AcpiTables/CpuPm/CpuPm.asl           |   73 +
>  .../Acpi/AcpiTables/Dsdt/AD7298.asi           |   38 +
>  .../Acpi/AcpiTables/Dsdt/ADC108S102.asi       |   33 +
>  .../Acpi/AcpiTables/Dsdt/CAT24C08.asi         |   34 +
>  .../Acpi/AcpiTables/Dsdt/CY8C9540A.asi        |   47 +
>  .../Acpi/AcpiTables/Dsdt/GpioClient.asi       |   89 +
>  .../Acpi/AcpiTables/Dsdt/LpcDev.asi           |  248 +
>  .../Acpi/AcpiTables/Dsdt/PCA9685.asi          |   34 +
>  .../Acpi/AcpiTables/Dsdt/PCAL9555A.asi        |   90 +
>  .../Acpi/AcpiTables/Dsdt/PciHostBridge.asi    |  195 +
>  .../Acpi/AcpiTables/Dsdt/PciIrq.asi           |  552 ++
>  .../Acpi/AcpiTables/Dsdt/PcieExpansionPrt.asi |  127 +
>  .../Acpi/AcpiTables/Dsdt/Platform.asl         |  347 ++
>  .../Acpi/AcpiTables/Dsdt/QNC.asi              |   49 +
>  .../Acpi/AcpiTables/Dsdt/QNCApic.asi          |   32 +
>  .../Acpi/AcpiTables/Dsdt/QNCLpc.asi           |   23 +
>  .../AcpiTables/Dsdt/QuarkSouthCluster.asi     |  110 +
>  .../Acpi/AcpiTables/Dsdt/Tpm.asi              |   45 +
>  .../Acpi/AcpiTables/Facs/Facs.aslc            |   74 +
>  .../Acpi/AcpiTables/Facs/Facs.h               |   29 +
>  .../Acpi/AcpiTables/Fadt/Fadt.h               |  102 +
>  .../Acpi/AcpiTables/Fadt/Fadt1.0.aslc         |   76 +
>  .../Acpi/AcpiTables/Fadt/Fadt2.0.aslc         |  157 +
>  .../Acpi/AcpiTables/Hpet/Hpet.aslc            |   68 +
>  .../Acpi/AcpiTables/Hpet/Hpet.h               |   45 +
>  .../Acpi/AcpiTables/Mcfg/Mcfg.aslc            |   75 +
>  .../Acpi/AcpiTables/Mcfg/Mcfg.h               |   56 +
>  .../Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.c     | 1402 +++++
>  .../Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.h     |  316 ++
>  .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.c      |  805 +++
>  .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.h      |  120 +
>  .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.inf    |  196 +
>  .../Acpi/Dxe/AcpiPlatform/Madt.h              |  207 +
>  .../Acpi/Dxe/AcpiPlatform/MadtPlatform.c      |  300 ++
>  .../BootScriptExecutorDxe.inf                 |   77 +
>  .../Dxe/BootScriptExecutorDxe/IA32/S3Asm.S    |   44 +
>  .../Dxe/BootScriptExecutorDxe/IA32/S3Asm.asm  |   51 +
>  .../BootScriptExecutorDxe/IA32/SetIdtEntry.c  |   57 +
>  .../Dxe/BootScriptExecutorDxe/ScriptExecute.c |  379 ++
>  .../Dxe/BootScriptExecutorDxe/ScriptExecute.h |   70 +
>  .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.c     | 1011 ++++
>  .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.h     |  167 +
>  .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.inf   |   78 +
>  .../Acpi/DxeSmm/SmmPowerManagement/Ppm.c      |  372 ++
>  .../Acpi/DxeSmm/SmmPowerManagement/Ppm.h      |  150 +
>  .../SmmPowerManagement/SmmPowerManagement.c   |  113 +
>  .../SmmPowerManagement/SmmPowerManagement.h   |   52 +
>  .../SmmPowerManagement/SmmPowerManagement.inf |   74 +
>  .../Application/ForceRecovery/ForceRecovery.c |   47 +
>  .../ForceRecovery/ForceRecovery.inf           |   34 +
>  .../PlatformFlashAccessLibDxe.c               |  262 +
>  .../PlatformFlashAccessLibDxe.inf             |   47 +
>  .../PlatformFlashAccessLib/SpiFlashDevice.c   |  330 ++
>  .../PlatformFlashAccessLib/SpiFlashDevice.h   |  180 +
>  .../SystemFirmwareDescriptor.aslc             |   83 +
>  .../SystemFirmwareDescriptor.inf              |   40 +
>  .../SystemFirmwareDescriptorPei.c             |   60 +
>  .../SystemFirmwareUpdateConfig.ini            |   57 +
>  .../Include/Guid/CapsuleOnDataCD.h            |   23 +
>  .../Include/Guid/CapsuleOnFatFloppyDisk.h     |   23 +
>  .../Include/Guid/CapsuleOnFatIdeDisk.h        |   24 +
>  .../Include/Guid/CapsuleOnFatUsbDisk.h        |   24 +
>  .../Include/Guid/MemoryConfigData.h           |   23 +
>  .../Include/Guid/QuarkCapsuleGuid.h           |   46 +
>  .../Include/Guid/QuarkVariableLock.h          |   23 +
>  .../Include/Guid/SystemNvDataHobGuid.h        |   29 +
>  .../Include/Library/PlatformHelperLib.h       |  266 +
>  .../Include/Library/PlatformPcieHelperLib.h   |   56 +
>  .../Intel/QuarkPlatformPkg/Include/Pcal9555.h |   24 +
>  .../Intel/QuarkPlatformPkg/Include/Platform.h |  119 +
>  .../QuarkPlatformPkg/Include/PlatformBoards.h |  166 +
>  .../Include/Protocol/GlobalNvsArea.h          |   82 +
>  .../Include/Protocol/PlatformSmmSpiReady.h    |   23 +
>  .../PlatformBootManager.c                     |  472 ++
>  .../PlatformBootManager.h                     |   49 +
>  .../PlatformBootManagerLib.inf                |   83 +
>  .../PlatformBootManagerLib/PlatformData.c     |  275 +
>  .../Library/PlatformHelperLib/CommonHeader.h  |   51 +
>  .../DxePlatformHelperLib.inf                  |   70 +
>  .../PeiPlatformHelperLib.inf                  |   45 +
>  .../PlatformHelperLib/PlatformHelperDxe.c     |  337 ++
>  .../PlatformHelperLib/PlatformHelperLib.c     |  481 ++
>  .../PlatformHelperLib/PlatformHelperPei.c     |  159 +
>  .../Library/PlatformHelperLib/PlatformLeds.c  |  146 +
>  .../PlatformPcieHelperLib/CommonHeader.h      |   55 +
>  .../PlatformPcieHelperLib.c                   |  114 +
>  .../PlatformPcieHelperLib.inf                 |   41 +
>  .../Library/PlatformPcieHelperLib/SocUnit.c   |  125 +
>  .../Library/PlatformSecLib/Ia32/Flat32.S      |  796 +++
>  .../Library/PlatformSecLib/Ia32/Flat32.asm    |  685 +++
>  .../Library/PlatformSecLib/Ia32/Platform.inc  |  134 +
>  .../Library/PlatformSecLib/PlatformSecLib.c   |  207 +
>  .../Library/PlatformSecLib/PlatformSecLib.inf |   54 +
>  .../PlatformSecLib/PlatformSecLibModStrs.uni  |   18 +
>  .../PlatformSecureLib/PlatformSecureLib.c     |  164 +
>  .../PlatformSecureLib/PlatformSecureLib.inf   |   41 +
>  .../Library/Tpm12DeviceLibAtmelI2c/TisPc.c    |  408 ++
>  .../Tpm12DeviceLibAtmelI2c.inf                |   39 +
>  .../Tpm12DeviceLibAtmelI2c.uni                |   16 +
>  .../Library/Tpm12DeviceLibInfineonI2c/TisPc.c |  612 +++
>  .../Tpm12DeviceLibInfineonI2c.inf             |   39 +
>  .../Tpm12DeviceLibInfineonI2c.uni             |   16 +
>  .../Pci/Dxe/PciHostBridge/PciHostBridge.c     | 1397 +++++
>  .../Pci/Dxe/PciHostBridge/PciHostBridge.h     |  389 ++
>  .../Pci/Dxe/PciHostBridge/PciHostBridge.inf   |   61 +
>  .../Dxe/PciHostBridge/PciHostBridgeSupport.c  |  140 +
>  .../Pci/Dxe/PciHostBridge/PciHostResource.h   |   60 +
>  .../Pci/Dxe/PciHostBridge/PciRootBridge.h     |  693 +++
>  .../Pci/Dxe/PciHostBridge/PciRootBridgeIo.c   | 1610 ++++++
>  .../Pci/Dxe/PciPlatform/CommonHeader.h        |   31 +
>  .../Pci/Dxe/PciPlatform/PciPlatform.c         |  194 +
>  .../Pci/Dxe/PciPlatform/PciPlatform.h         |   82 +
>  .../Pci/Dxe/PciPlatform/PciPlatform.inf       |   54 +
>  .../Dxe/MemorySubClass/MemorySubClass.c       |  435 ++
>  .../Dxe/MemorySubClass/MemorySubClass.h       |   65 +
>  .../Dxe/MemorySubClass/MemorySubClass.inf     |   60 +
>  .../MemorySubClass/MemorySubClassStrings.uni  |   29 +
>  .../Dxe/PlatformInit/PlatformConfig.c         |  443 ++
>  .../Dxe/PlatformInit/PlatformInitDxe.c        |   87 +
>  .../Dxe/PlatformInit/PlatformInitDxe.h        |   58 +
>  .../Dxe/PlatformInit/PlatformInitDxe.inf      |   56 +
>  .../Dxe/SaveMemoryConfig/SaveMemoryConfig.c   |  118 +
>  .../Dxe/SaveMemoryConfig/SaveMemoryConfig.inf |   44 +
>  .../Platform/Dxe/Setup/CommonHeader.h         |   55 +
>  .../Platform/Dxe/Setup/DxePlatform.inf        |   76 +
>  .../Platform/Dxe/Setup/KeyboardLayout.c       |  262 +
>  .../Platform/Dxe/Setup/QNCRegTable.c          |   80 +
>  .../Platform/Dxe/Setup/SetupPlatform.c        |   97 +
>  .../Platform/Dxe/Setup/SetupPlatform.h        |   71 +
>  .../Platform/Dxe/Setup/Strings.uni            |   47 +
>  .../Platform/Dxe/Setup/processor.c            |   40 +
>  .../Platform/Dxe/SmbiosMiscDxe/CommonHeader.h |   34 +
>  .../MiscBaseBoardManufacturer.uni             |   19 +
>  .../MiscBaseBoardManufacturerData.c           |   45 +
>  .../MiscBaseBoardManufacturerFunction.c       |  181 +
>  .../Dxe/SmbiosMiscDxe/MiscBiosVendor.uni      |   18 +
>  .../Dxe/SmbiosMiscDxe/MiscBiosVendorData.c    |   92 +
>  .../SmbiosMiscDxe/MiscBiosVendorFunction.c    |  222 +
>  .../SmbiosMiscDxe/MiscBootInformationData.c   |   24 +
>  .../MiscBootInformationFunction.c             |   71 +
>  .../SmbiosMiscDxe/MiscChassisManufacturer.uni |   17 +
>  .../MiscChassisManufacturerData.c             |   36 +
>  .../MiscChassisManufacturerFunction.c         |  168 +
>  .../Dxe/SmbiosMiscDxe/MiscDevicePath.h        |   42 +
>  .../MiscNumberOfInstallableLanguagesData.c    |   28 +
>  ...MiscNumberOfInstallableLanguagesFunction.c |  240 +
>  .../Dxe/SmbiosMiscDxe/MiscOemString.uni       |   12 +
>  .../Dxe/SmbiosMiscDxe/MiscOemStringData.c     |   20 +
>  .../Dxe/SmbiosMiscDxe/MiscOemStringFunction.c |   78 +
>  .../Dxe/SmbiosMiscDxe/MiscOnboardDevice.uni   |   18 +
>  .../Dxe/SmbiosMiscDxe/MiscOnboardDeviceData.c |   49 +
>  .../SmbiosMiscDxe/MiscOnboardDeviceFunction.c |  105 +
>  .../MiscPortInternalConnectorDesignator.uni   |   53 +
>  .../MiscPortInternalConnectorDesignatorData.c |  184 +
>  ...cPortInternalConnectorDesignatorFunction.c |  292 ++
>  .../SmbiosMiscDxe/MiscSystemManufacturer.uni  |   20 +
>  .../MiscSystemManufacturerData.c              |   32 +
>  .../MiscSystemManufacturerFunction.c          |  198 +
>  .../SmbiosMiscDxe/MiscSystemOptionString.uni  |   14 +
>  .../MiscSystemOptionStringData.c              |   23 +
>  .../MiscSystemOptionStringFunction.c          |   81 +
>  .../MiscSystemSlotDesignation.uni             |   27 +
>  .../MiscSystemSlotDesignationData.c           |  357 ++
>  .../MiscSystemSlotDesignationFunction.c       |  285 ++
>  .../MiscSystemSlotOnboardDevices.uni          |   23 +
>  .../Platform/Dxe/SmbiosMiscDxe/SmbiosMisc.h   |  137 +
>  .../Dxe/SmbiosMiscDxe/SmbiosMiscDataTable.c   |  109 +
>  .../Dxe/SmbiosMiscDxe/SmbiosMiscDxe.inf       |  308 ++
>  .../Dxe/SmbiosMiscDxe/SmbiosMiscEntryPoint.c  |   82 +
>  .../Dxe/SmbiosMiscDxe/SmbiosMiscStrings.uni   |   26 +
>  .../Pei/PlatformConfig/PlatformConfigPei.c    |   81 +
>  .../Pei/PlatformConfig/PlatformConfigPei.inf  |   45 +
>  .../Platform/Pei/PlatformInit/BootMode.c      |  218 +
>  .../Platform/Pei/PlatformInit/CommonHeader.h  |   81 +
>  .../Pei/PlatformInit/Generic/Recovery.c       |  467 ++
>  .../Pei/PlatformInit/MemoryCallback.c         |  279 +
>  .../Platform/Pei/PlatformInit/MrcWrapper.c    | 1565 ++++++
>  .../Platform/Pei/PlatformInit/MrcWrapper.h    |  225 +
>  .../Platform/Pei/PlatformInit/PeiFvSecurity.c |  111 +
>  .../Platform/Pei/PlatformInit/PeiFvSecurity.h |   67 +
>  .../Pei/PlatformInit/PlatformEarlyInit.c      | 1227 +++++
>  .../Pei/PlatformInit/PlatformEarlyInit.h      |  301 ++
>  .../Pei/PlatformInit/PlatformEarlyInit.inf    |  193 +
>  .../Pei/PlatformInit/PlatformErratas.c        |  178 +
>  .../Platform/SpiFvbServices/FvbInfo.c         |  332 ++
>  .../Platform/SpiFvbServices/FwBlockService.c  | 2053 ++++++++
>  .../Platform/SpiFvbServices/FwBlockService.h  |  308 ++
>  .../Platform/SpiFvbServices/PlatformSmmSpi.c  |   31 +
>  .../SpiFvbServices/PlatformSmmSpi.inf         |   80 +
>  .../Platform/SpiFvbServices/PlatformSpi.inf   |   79 +
>  .../Platform/SpiFvbServices/SpiFlashDevice.c  |  331 ++
>  .../Platform/SpiFvbServices/SpiFlashDevice.h  |  181 +
>  Platform/Intel/QuarkPlatformPkg/Quark.dsc     |  948 ++++
>  Platform/Intel/QuarkPlatformPkg/Quark.fdf     |  907 ++++
>  Platform/Intel/QuarkPlatformPkg/QuarkMin.dsc  |  648 +++
>  Platform/Intel/QuarkPlatformPkg/QuarkMin.fdf  |  608 +++
>  .../QuarkPlatformPkg/QuarkPlatformPkg.dec     |  933 ++++
>  Platform/Intel/QuarkPlatformPkg/Readme.md     |  685 +++
>  Platform/Intel/Vlv2TbltDevicePkg/.gitignore   |    5 +
>  .../AcpiPlatform/AcpiPlatform.c               | 1338 +++++
>  .../AcpiPlatform/AcpiPlatform.h               |  219 +
>  .../AcpiPlatform/AcpiPlatform.inf             |   89 +
>  .../AcpiPlatform/AcpiPlatformHooks.c          |  493 ++
>  .../AcpiPlatform/AcpiPlatformHooks.h          |  127 +
>  .../AcpiPlatform/AcpiPlatformHooksLib.h       |   91 +
>  .../Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h     |   56 +
>  .../FirmwareUpdate/FirmwareUpdate.c           |  922 ++++
>  .../FirmwareUpdate/FirmwareUpdate.h           |  185 +
>  .../FirmwareUpdate/FirmwareUpdate.inf         |   83 +
>  .../FirmwareUpdate/FirmwareUpdateStrings.uni  |   45 +
>  Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe   |  Bin 0 -> 499712 bytes
>  Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env  |   25 +
>  Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env  |   25 +
>  .../Intel/Vlv2TbltDevicePkg/BiosIdx64D.env    |   25 +
>  .../Intel/Vlv2TbltDevicePkg/BiosIdx64R.env    |   25 +
>  .../BootScriptSaveDxe/BootScriptSaveDxe.inf   |   60 +
>  .../InternalBootScriptSave.h                  |  102 +
>  .../BootScriptSaveDxe/ScriptSave.c            |  626 +++
>  .../Intel/Vlv2TbltDevicePkg/Build_IFWI.bat    |  200 +
>  .../Intel/Vlv2TbltDevicePkg/Build_IFWI.sh     |  104 +
>  Platform/Intel/Vlv2TbltDevicePkg/FCE.exe      |  Bin 0 -> 632832 bytes
>  .../Capsule/GenerateCapsule/GenCapsuleAll.bat |   35 +
>  .../Capsule/GenerateCapsule/GenCapsuleAll.sh  |   28 +
>  .../GenerateCapsule/GenCapsuleMinnowMax.bat   |  131 +
>  .../GenerateCapsule/GenCapsuleMinnowMax.sh    |   65 +
>  .../GenCapsuleMinnowMaxRelease.bat            |  131 +
>  .../GenCapsuleMinnowMaxRelease.sh             |   65 +
>  .../GenerateCapsule/GenCapsuleSampleColor.bat |  137 +
>  .../GenerateCapsule/GenCapsuleSampleColor.sh  |   70 +
>  .../Feature/Capsule/GenerateCapsule/Lvfs.ddf  |   14 +
>  .../LvfsGenCapsuleMinnowMax.bat               |  139 +
>  .../LvfsGenCapsuleMinnowMaxRelease.bat        |  139 +
>  .../LvfsGenCapsuleSampleColor.bat             |  145 +
>  ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
>  ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
>  ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
>  .../GenerateCapsule/template.metainfo.xml     |   27 +
>  .../Library/FmpDeviceLib/FmpDeviceLib.c       |  589 +++
>  .../Library/FmpDeviceLib/FmpDeviceLib.inf     |   46 +
>  .../Library/FmpDeviceLibSample/FmpDeviceLib.c |  412 ++
>  .../FmpDeviceLibSample/FmpDeviceLib.inf       |   34 +
>  .../PlatformFlashAccessLib.c                  |  685 +++
>  .../PlatformFlashAccessLib.inf                |   54 +
>  .../SystemFirmwareDescriptor.aslc             |   83 +
>  .../SystemFirmwareDescriptor.inf              |   40 +
>  .../SystemFirmwareDescriptorPei.c             |   60 +
>  .../SystemFirmwareUpdateConfig.ini            |   66 +
>  .../SystemFirmwareUpdateConfigGcc.ini         |   66 +
>  .../Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc |   55 +
>  .../Vlv2TbltDevicePkg/FmpCertificate.dsc      |   22 +
>  .../FmpGreenSampleDevice.dsc                  |   55 +
>  .../Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc  |   59 +
>  .../Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc  |   55 +
>  .../FspAzaliaConfigData/AzaliaConfig.bin      |  Bin 0 -> 3708 bytes
>  .../FspSupport/BootModePei/BootModePei.c      |   42 +
>  .../FspSupport/BootModePei/BootModePei.inf    |   40 +
>  .../FspHobProcessLibVlv2.c                    |  421 ++
>  .../FspHobProcessLibVlv2.inf                  |   74 +
>  .../FspPlatformSecLibVlv2.c                   |  144 +
>  .../FspPlatformSecLibVlv2.inf                 |   82 +
>  .../Ia32/AsmSaveSecContext.asm                |   45 +
>  .../SecFspPlatformSecLibVlv2/Ia32/Fsp.inc     |   45 +
>  .../Ia32/PeiCoreEntry.asm                     |  135 +
>  .../Ia32/SecEntry.asm                         |  338 ++
>  .../SecFspPlatformSecLibVlv2/Ia32/Stack.S     |   71 +
>  .../SecFspPlatformSecLibVlv2/Ia32/Stack.asm   |   76 +
>  .../SecFspPlatformSecLibVlv2/PlatformInit.c   |   36 +
>  .../SecFspPlatformSecLibVlv2/SaveSecContext.c |  108 +
>  .../SecGetPerformance.c                       |   83 +
>  .../SecPlatformInformation.c                  |   77 +
>  .../SecFspPlatformSecLibVlv2/SecRamInitData.c |   16 +
>  .../SecTempRamSupport.c                       |  149 +
>  .../SecFspPlatformSecLibVlv2/UartInit.c       |  192 +
>  .../Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c   |   68 +
>  .../Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf |   49 +
>  .../Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c |  170 +
>  .../FvbRuntimeDxe/FvbRuntimeDxe.inf           |   80 +
>  .../FvbRuntimeDxe/FvbService.c                | 1098 ++++
>  .../FvbRuntimeDxe/FvbService.h                |  182 +
>  .../FvbRuntimeDxe/FvbServiceDxe.c             |  199 +
>  .../FvbRuntimeDxe/FvbServiceSmm.c             |  127 +
>  .../FvbRuntimeDxe/FvbSmm.inf                  |   82 +
>  .../FvbRuntimeDxe/FvbSmmCommon.h              |   73 +
>  .../FvbRuntimeDxe/FvbSmmDxe.c                 |  944 ++++
>  .../FvbRuntimeDxe/FvbSmmDxe.h                 |  232 +
>  .../FvbRuntimeDxe/FvbSmmDxe.inf               |   50 +
>  Platform/Intel/Vlv2TbltDevicePkg/GenBiosId    |  Bin 0 -> 12236 bytes
>  .../Intel/Vlv2TbltDevicePkg/GenBiosId.exe     |  Bin 0 -> 384000 bytes
>  .../Include/AlertStandardFormatTable.h        |  122 +
>  .../Vlv2TbltDevicePkg/Include/ChipsetAccess.h |   28 +
>  .../Include/CommonIncludes.h                  |  115 +
>  .../Intel/Vlv2TbltDevicePkg/Include/CpuType.h |   59 +
>  .../Vlv2TbltDevicePkg/Include/FileHandleLib.h |  499 ++
>  .../Include/Guid/AcpiTableStorage.h           |   30 +
>  .../Include/Guid/AlertStandardFormat.h        |   86 +
>  .../Vlv2TbltDevicePkg/Include/Guid/BiosId.h   |   30 +
>  .../Include/Guid/BoardFeatures.h              |  214 +
>  .../Include/Guid/EfiVpdData.h                 |  156 +
>  .../Include/Guid/FirmwareId.h                 |   61 +
>  .../Include/Guid/HwWatchdogTimerHob.h         |  134 +
>  .../Vlv2TbltDevicePkg/Include/Guid/IdccData.h |  104 +
>  .../Vlv2TbltDevicePkg/Include/Guid/ItkData.h  |   70 +
>  .../Include/Guid/MemoryConfigData.h           |   32 +
>  .../Include/Guid/OsSelection.h                |   85 +
>  .../Include/Guid/PciLanInfo.h                 |   39 +
>  .../Include/Guid/PlatformCpuInfo.h            |  180 +
>  .../Include/Guid/PlatformInfo.h               |  433 ++
>  .../Include/Guid/SensorInfoVariable.h         |  279 +
>  .../Include/Guid/SetupVariable.h              | 1344 +++++
>  .../Intel/Vlv2TbltDevicePkg/Include/Hpet.h    |   40 +
>  .../Include/Library/BiosIdLib.h               |  104 +
>  .../Include/Library/CpuIA32.h                 |  345 ++
>  .../Include/Library/EfiRegTableLib.h          |  196 +
>  .../Vlv2TbltDevicePkg/Include/Library/Esrt.h  |   74 +
>  .../Vlv2TbltDevicePkg/Include/Library/Fd.h    |  264 +
>  .../Include/Library/FlashDeviceLib.h          |  122 +
>  .../Include/Library/I2CLib.h                  |   58 +
>  .../Include/Library/I2cMmioConfigLib.h        |   23 +
>  .../Include/Library/I2cPort_platform.h        |   26 +
>  .../Include/Library/PlatformFsaLib.h          |   50 +
>  .../Include/Library/PlatformFspLib.h          |   23 +
>  .../Include/Library/SpiFlash.H                |  239 +
>  .../Include/Library/StallSmmLib.h             |   40 +
>  .../Include/Library/UsbDeviceModeLib.h        |  181 +
>  .../Intel/Vlv2TbltDevicePkg/Include/Mcfg.h    |   69 +
>  .../Vlv2TbltDevicePkg/Include/McfgTable.h     |   65 +
>  .../Vlv2TbltDevicePkg/Include/Platform.h      |  133 +
>  .../Include/PlatformBootMode.h                |   35 +
>  .../Include/PlatformDefinitions.h             |   43 +
>  .../Include/Ppi/MfgMemoryTest.h               |   42 +
>  .../Include/Ppi/Sha256Hash.h                  |  131 +
>  .../Vlv2TbltDevicePkg/Include/Ppi/Speaker.h   |   65 +
>  .../Include/Ppi/UsbController.h               |   85 +
>  .../Include/Protocol/CK505ClockPlatformInfo.h |  126 +
>  .../Include/Protocol/EnhancedSpeedstep.h      |   76 +
>  .../Include/Protocol/GlobalNvsArea.h          |  475 ++
>  .../Include/Protocol/HwWatchdogTimer.h        |  235 +
>  .../Include/Protocol/I2cAcpi.h                |  107 +
>  .../Include/Protocol/I2cBus.h                 |  164 +
>  .../Include/Protocol/I2cBusMcg.h              |  163 +
>  .../Include/Protocol/I2cHostMcg.h             |  138 +
>  .../Include/Protocol/I2cMasterMcg.h           |  519 ++
>  .../Include/Protocol/I2cSlave.h               |  194 +
>  .../Include/Protocol/LpcWpc83627Policy.h      |   92 +
>  .../Include/Protocol/LpcWpce791Policy.h       |   55 +
>  .../Include/Protocol/MmioDevice.h             |   84 +
>  .../Include/Protocol/Observable.h             |  186 +
>  .../Include/Protocol/PlatformGopPolicy.h      |   68 +
>  .../Include/Protocol/PlatformIdeInit.h        |   43 +
>  .../Include/Protocol/SetupMode.h              |   79 +
>  .../Include/Protocol/SmbiosSlotPopulation.h   |   47 +
>  .../Include/Protocol/Speaker.h                |   65 +
>  .../Include/Protocol/TcoReset.h               |   67 +
>  .../Include/Protocol/TpmMp.h                  |  136 +
>  .../Include/Protocol/UsbPolicy.h              |  126 +
>  .../Include/Protocol/VlvPlatformPolicy.h      |  102 +
>  .../Vlv2TbltDevicePkg/Include/SetupMode.h     |   85 +
>  .../IntelGopDepex/IntelGopDriver.depex        |    1 +
>  .../Library/BiosIdLib/BiosIdLib.c             |  337 ++
>  .../Library/BiosIdLib/BiosIdLib.inf           |   50 +
>  .../Library/CpuIA32Lib/CpuIA32Lib.inf         |   41 +
>  .../Library/CpuIA32Lib/EfiCpuVersion.c        |   70 +
>  .../Library/CpuIA32Lib/IA32/CpuIA32.S         |  223 +
>  .../Library/CpuIA32Lib/IA32/CpuIA32.asm       |  206 +
>  .../Library/CpuIA32Lib/IA32/CpuIA32.c         |  177 +
>  .../Library/CpuIA32Lib/X64/Cpu.S              |  207 +
>  .../Library/CpuIA32Lib/X64/Cpu.asm            |  222 +
>  .../Library/EfiRegTableLib/EfiRegTableLib.c   |  282 ++
>  .../Library/EfiRegTableLib/EfiRegTableLib.inf |   47 +
>  .../Library/FlashDeviceLib/FlashDeviceLib.c   |  461 ++
>  .../Library/FlashDeviceLib/FlashDeviceLib.inf |   44 +
>  .../FlashDeviceLib/FlashDeviceLibDxe.c        |   56 +
>  .../FlashDeviceLib/FlashDeviceLibDxe.inf      |   43 +
>  .../FlashDeviceLibDxeRuntimeSmm.c             |  173 +
>  .../FlashDeviceLib/SpiChipDefinitions.h       |  835 +++
>  .../Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c |   46 +
>  .../Library/I2CLib/I2CLibNull.inf             |   39 +
>  .../Library/I2CLibDxe/I2CLib.c                |  735 +++
>  .../Library/I2CLibDxe/I2CLibDxe.inf           |   39 +
>  .../Library/I2CLibDxe/I2CRegs.h               |  126 +
>  .../Library/I2CLibPei/I2CAccess.h             |   44 +
>  .../Library/I2CLibPei/I2CDelayPei.c           |   46 +
>  .../Library/I2CLibPei/I2CDelayPei.h           |   30 +
>  .../Library/I2CLibPei/I2CIoLibPei.c           |  178 +
>  .../Library/I2CLibPei/I2CIoLibPei.h           |  153 +
>  .../Library/I2CLibPei/I2CLibPei.c             |  638 +++
>  .../Library/I2CLibPei/I2CLibPei.h             |  280 +
>  .../Library/I2CLibPei/I2CLibPei.inf           |   40 +
>  .../IntelPchAcpiTimerLib/CommonHeader.h       |   27 +
>  .../IntelPchAcpiTimerLib.c                    |  255 +
>  .../IntelPchAcpiTimerLib.inf                  |   51 +
>  .../BoardClkGens/BoardClkGens.c               |  430 ++
>  .../BoardClkGens/BoardClkGens.h               |  255 +
>  .../MultiPlatformLib/BoardGpios/BoardGpios.c  |  531 ++
>  .../MultiPlatformLib/BoardGpios/BoardGpios.h  |  324 ++
>  .../BoardJumpers/BoardJumpers.c               |   30 +
>  .../BoardJumpers/BoardJumpers.h               |   30 +
>  .../BoardOemIds/BoardOemIds.c                 |   43 +
>  .../BoardOemIds/BoardOemIds.h                 |   29 +
>  .../BoardSsidSvid/BoardSsidSvid.c             |   38 +
>  .../BoardSsidSvid/BoardSsidSvid.h             |   35 +
>  .../MultiPlatformLib/MultiPlatformLib.c       |  120 +
>  .../MultiPlatformLib/MultiPlatformLib.h       |   89 +
>  .../MultiPlatformLib/MultiPlatformLib.inf     |   77 +
>  .../MultiPlatformLib/PlatformInfoHob.c        |   54 +
>  .../Library/PchPlatformLib/PchPlatformLib.inf |   50 +
>  .../PchPlatformLib/PchPlatformLibrary.c       |  131 +
>  .../PchPlatformLib/PchPlatformLibrary.h       |   35 +
>  .../Library/PchSmmLib/CommonHeader.h          |   32 +
>  .../Library/PchSmmLib/PchSmmLib.c             |  157 +
>  .../Library/PchSmmLib/PchSmmLib.inf           |   46 +
>  .../Library/PlatformBdsLib/BdsPlatform.c      | 3098 ++++++++++++
>  .../Library/PlatformBdsLib/BdsPlatform.h      |  516 ++
>  .../Library/PlatformBdsLib/PlatformBdsLib.inf |  127 +
>  .../PlatformBdsLib/PlatformBdsStrings.uni     |   30 +
>  .../Library/PlatformBdsLib/PlatformData.c     |  306 ++
>  .../Library/PlatformCmosLib/PlatformCmosLib.c |  106 +
>  .../PlatformCmosLib/PlatformCmosLib.inf       |   30 +
>  .../Library/PlatformFspLib/PlatformFspLib.c   |   44 +
>  .../Library/PlatformFspLib/PlatformFspLib.inf |   49 +
>  .../Library/ResetSystemLib/ResetSystemLib.c   |  235 +
>  .../Library/ResetSystemLib/ResetSystemLib.inf |   47 +
>  .../SerialPortLib/PlatformSerialPortLib.h     |   53 +
>  .../Library/SerialPortLib/SerialPortLib.c     |  246 +
>  .../Library/SerialPortLib/SerialPortLib.inf   |   52 +
>  .../Library/SerialPortLib/SioInit.c           |  127 +
>  .../Library/SerialPortLib/SioInit.h           |   62 +
>  .../Library/SmbusLib/CommonHeader.h           |   26 +
>  .../Library/SmbusLib/SmbusLib.c               |  873 ++++
>  .../Library/SmbusLib/SmbusLib.inf             |   46 +
>  .../Library/StallSmmLib/StallSmm.c            |   89 +
>  .../Library/StallSmmLib/StallSmmLib.inf       |   51 +
>  .../Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.c    |  117 +
>  .../Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.inf  |   61 +
>  .../Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.c    |  145 +
>  .../Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.inf  |   60 +
>  .../Intel/Vlv2TbltDevicePkg/Logo/Logo.bmp     |  Bin 0 -> 94434 bytes
>  .../Metronome/LegacyMetronome.c               |  185 +
>  .../Metronome/LegacyMetronome.h               |   64 +
>  .../Vlv2TbltDevicePkg/Metronome/Metronome.inf |   49 +
>  .../MonoStatusCode/EfiStatusCode.h            |  178 +
>  .../MonoStatusCode/MonoStatusCode.c           |  132 +
>  .../MonoStatusCode/MonoStatusCode.h           |  128 +
>  .../MonoStatusCode/MonoStatusCode.inf         |   72 +
>  .../MonoStatusCode/PeiPostCode.c              |  121 +
>  .../MonoStatusCode/PlatformStatusCode.c       |  381 ++
>  .../MonoStatusCode/PlatformStatusCode.h       |  138 +
>  .../Library/GenericBdsLib/BdsBoot.c           | 4490 +++++++++++++++++
>  .../Library/GenericBdsLib/BdsConnect.c        |  429 ++
>  .../Library/GenericBdsLib/BdsConsole.c        | 1061 ++++
>  .../Library/GenericBdsLib/BdsMisc.c           | 1575 ++++++
>  .../Library/GenericBdsLib/DevicePath.c        |   27 +
>  .../Library/GenericBdsLib/GenericBdsLib.inf   |  142 +
>  .../Library/GenericBdsLib/GenericBdsLib.uni   |   19 +
>  .../GenericBdsLib/GenericBdsStrings.uni       |   30 +
>  .../Library/GenericBdsLib/InternalBdsLib.h    |  173 +
>  .../Library/GenericBdsLib/String.c            |   26 +
>  .../Library/GenericBdsLib/String.h            |   42 +
>  .../PciPlatform/BoardPciPlatform.c            |   55 +
>  .../PciPlatform/PciPlatform.c                 |  367 ++
>  .../PciPlatform/PciPlatform.h                 |   83 +
>  .../PciPlatform/PciPlatform.inf               |   65 +
>  .../Vlv2TbltDevicePkg/PlatformCapsule.dsc     |   39 +
>  .../Vlv2TbltDevicePkg/PlatformCapsule.fdf     |   52 +
>  .../Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc  |   38 +
>  .../Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf  |   52 +
>  .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.c   |   60 +
>  .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.h   |   29 +
>  .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf |   55 +
>  .../PlatformDxe/AzaliaVerbTable.h             |  247 +
>  .../Vlv2TbltDevicePkg/PlatformDxe/BoardId.c   |  223 +
>  .../PlatformDxe/BoardIdDecode.c               |  129 +
>  .../PlatformDxe/BoardIdDecode.h               |   61 +
>  .../PlatformDxe/ClockControl.c                |  202 +
>  .../PlatformDxe/Configuration.h               |  692 +++
>  .../Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c |   89 +
>  .../PlatformDxe/IchPlatformPolicy.c           |  484 ++
>  .../PlatformDxe/IchRegTable.c                 |  134 +
>  .../PlatformDxe/IchTcoReset.c                 |  211 +
>  .../Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c  |   72 +
>  .../PlatformDxe/LegacySpeaker.c               |  161 +
>  .../PlatformDxe/LegacySpeaker.h               |   69 +
>  .../PlatformDxe/Observable/Observable.c       |  582 +++
>  .../PlatformDxe/Observable/Observable.h       |  137 +
>  .../Vlv2TbltDevicePkg/PlatformDxe/PciBus.h    |  379 ++
>  .../Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c |  506 ++
>  .../Vlv2TbltDevicePkg/PlatformDxe/Platform.c  | 1820 +++++++
>  .../PlatformDxe/PlatformDxe.h                 |  722 +++
>  .../PlatformDxe/PlatformDxe.inf               |  149 +
>  .../Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c |  154 +
>  .../Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c |  112 +
>  .../PlatformDxe/SioPlatformPolicy.c           |   82 +
>  .../PlatformDxe/SlotConfig.c                  |  148 +
>  .../PlatformDxe/SlotConfig.h                  |   80 +
>  .../PlatformGopPolicy/PlatformGopPolicy.c     |  201 +
>  .../PlatformGopPolicy/PlatformGopPolicy.inf   |   51 +
>  .../PlatformInfoDxe/PlatformInfoDxe.c         |  169 +
>  .../PlatformInfoDxe/PlatformInfoDxe.h         |   30 +
>  .../PlatformInfoDxe/PlatformInfoDxe.inf       |   52 +
>  .../PlatformInitPei/BootMode.c                |  434 ++
>  .../PlatformInitPei/CpuInitPeim.c             |   44 +
>  .../Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c  |  319 ++
>  .../PlatformInitPei/FlashMap.c                |  143 +
>  .../PlatformInitPei/LegacySpeaker.c           |  168 +
>  .../PlatformInitPei/LegacySpeaker.h           |   71 +
>  .../PlatformInitPei/MchInit.c                 |   72 +
>  .../PlatformInitPei/MemoryCallback.c          |  338 ++
>  .../PlatformInitPei/MemoryPeim.c              |  408 ++
>  .../PlatformInitPei/PchInitPeim.c             |  808 +++
>  .../PlatformInitPei/PlatformEarlyInit.c       | 1195 +++++
>  .../PlatformInitPei/PlatformEarlyInit.h       | 1499 ++++++
>  .../PlatformInitPei/PlatformInfoInit.c        |  181 +
>  .../PlatformInitPei/PlatformInitPei.inf       |  117 +
>  .../PlatformInitPei/PlatformSsaInitPeim.c     |   58 +
>  .../PlatformInitPei/Recovery.c                |  361 ++
>  .../Vlv2TbltDevicePkg/PlatformInitPei/Stall.c |   91 +
>  .../Vlv2TbltDevicePkg/PlatformPei/BootMode.c  |  346 ++
>  .../PlatformPei/CommonHeader.h                |   60 +
>  .../PlatformPei/MemoryCallback.c              |  154 +
>  .../Vlv2TbltDevicePkg/PlatformPei/Platform.c  | 1198 +++++
>  .../Vlv2TbltDevicePkg/PlatformPei/Platform.h  |  213 +
>  .../PlatformPei/PlatformPei.inf               |  129 +
>  .../Vlv2TbltDevicePkg/PlatformPei/Stall.c     |   90 +
>  .../Intel/Vlv2TbltDevicePkg/PlatformPkg.dec   |  211 +
>  .../Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf   | 1073 ++++
>  .../Vlv2TbltDevicePkg/PlatformPkgConfig.dsc   |  107 +
>  .../Vlv2TbltDevicePkg/PlatformPkgGcc.fdf      | 1033 ++++
>  .../Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc   | 1711 +++++++
>  .../Vlv2TbltDevicePkg/PlatformPkgIA32.dsc     | 1699 +++++++
>  .../Vlv2TbltDevicePkg/PlatformPkgX64.dsc      | 1714 +++++++
>  .../PlatformSetupDxe/Boot.vfi                 |   72 +
>  .../PlatformSetupDxe/Configuration.h          |   56 +
>  .../PlatformSetupDxe/DebugConfig.vfi          |  118 +
>  .../PlatformSetupDxe/FwVersionStrings.uni     |   40 +
>  .../PlatformSetupDxe/Main.vfi                 |  331 ++
>  .../PlatformSetupDxe/PlatformSetupDxe.c       |  929 ++++
>  .../PlatformSetupDxe/PlatformSetupDxe.h       |   97 +
>  .../PlatformSetupDxe/PlatformSetupDxe.inf     |  141 +
>  .../PlatformSetupDxe/Security.vfi             |  104 +
>  .../PlatformSetupDxe/SetupFunctions.c         |   85 +
>  .../PlatformSetupDxe/SetupInfoRecords.c       | 1855 +++++++
>  .../PlatformSetupDxe/SouthClusterConfig.vfi   |  933 ++++
>  .../PlatformSetupDxe/SystemComponent.vfi      |   81 +
>  .../PlatformSetupDxe/Thermal.vfi              |  106 +
>  .../PlatformSetupDxe/UnCore.vfi               |  235 +
>  .../PlatformSetupDxe/UqiList.uni              |  452 ++
>  .../PlatformSetupDxe/Vfr.vfr                  |  123 +
>  .../PlatformSetupDxe/VfrStrings.uni           | 1417 ++++++
>  .../Vlv2TbltDevicePkg/PlatformSmm/Platform.c  |  997 ++++
>  .../PlatformSmm/PlatformSmm.inf               |   93 +
>  .../Vlv2TbltDevicePkg/PlatformSmm/S3Save.c    |  377 ++
>  .../PlatformSmm/SmmPlatform.h                 |  240 +
>  .../PlatformSmm/SmmScriptSave.c               |  252 +
>  .../PlatformSmm/SmmScriptSave.h               |   50 +
>  .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c   |  148 +
>  .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h   |   36 +
>  .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf |   49 +
>  Platform/Intel/Vlv2TbltDevicePkg/Readme.md    |  233 +
>  .../SaveMemoryConfig/SaveMemoryConfig.c       |  181 +
>  .../SaveMemoryConfig/SaveMemoryConfig.h       |   66 +
>  .../SaveMemoryConfig/SaveMemoryConfig.inf     |   60 +
>  .../SmBiosMiscDxe/CommonHeader.h              |   39 +
>  .../MiscBaseBoardManufacturer.uni             |   33 +
>  .../MiscBaseBoardManufacturerData.c           |   58 +
>  .../MiscBaseBoardManufacturerFunction.c       |  238 +
>  .../SmBiosMiscDxe/MiscBiosVendor.uni          |   26 +
>  .../SmBiosMiscDxe/MiscBiosVendorData.c        |  101 +
>  .../SmBiosMiscDxe/MiscBiosVendorFunction.c    |  336 ++
>  .../SmBiosMiscDxe/MiscBootInformationData.c   |   34 +
>  .../MiscBootInformationFunction.c             |   82 +
>  .../SmBiosMiscDxe/MiscChassisManufacturer.uni |   28 +
>  .../MiscChassisManufacturerData.c             |   57 +
>  .../MiscChassisManufacturerFunction.c         |  158 +
>  .../SmBiosMiscDxe/MiscMemoryDevice.uni        |   35 +
>  .../SmBiosMiscDxe/MiscMemoryDeviceData.c      |   45 +
>  .../SmBiosMiscDxe/MiscMemoryDeviceFunction.c  |  319 ++
>  .../MiscNumberOfInstallableLanguagesData.c    |   38 +
>  ...MiscNumberOfInstallableLanguagesFunction.c |  251 +
>  .../SmBiosMiscDxe/MiscOemString.uni           |   25 +
>  .../SmBiosMiscDxe/MiscOemStringData.c         |   34 +
>  .../SmBiosMiscDxe/MiscOemStringFunction.c     |   89 +
>  .../SmBiosMiscDxe/MiscOemType0x90.uni         |   31 +
>  .../SmBiosMiscDxe/MiscOemType0x90Data.c       |   36 +
>  .../SmBiosMiscDxe/MiscOemType0x90Function.c   |  442 ++
>  .../SmBiosMiscDxe/MiscOemType0x94.uni         |   42 +
>  .../SmBiosMiscDxe/MiscOemType0x94Data.c       |   54 +
>  .../SmBiosMiscDxe/MiscOemType0x94Function.c   | 1218 +++++
>  .../SmBiosMiscDxe/MiscOnboardDevice.uni       |   26 +
>  .../SmBiosMiscDxe/MiscOnboardDeviceData.c     |   48 +
>  .../SmBiosMiscDxe/MiscOnboardDeviceFunction.c |  135 +
>  .../SmBiosMiscDxe/MiscPhysicalArray.uni       |   25 +
>  .../SmBiosMiscDxe/MiscPhysicalArrayData.c     |   38 +
>  .../SmBiosMiscDxe/MiscPhysicalArrayFunction.c |  101 +
>  .../MiscPortInternalConnectorDesignator.uni   |   31 +
>  .../MiscPortInternalConnectorDesignatorData.c |   56 +
>  ...cPortInternalConnectorDesignatorFunction.c |  152 +
>  .../SmBiosMiscDxe/MiscProcessorCache.uni      |   22 +
>  .../SmBiosMiscDxe/MiscProcessorCacheData.c    |   33 +
>  .../MiscProcessorCacheFunction.c              |  189 +
>  .../MiscProcessorInformation.uni              |   27 +
>  .../MiscProcessorInformationData.c            |   71 +
>  .../MiscProcessorInformationFunction.c        |  448 ++
>  .../SmBiosMiscDxe/MiscResetCapabilitiesData.c |   43 +
>  .../MiscResetCapabilitiesFunction.c           |   85 +
>  .../SmBiosMiscDxe/MiscSubclassDriver.h        |  188 +
>  .../SmBiosMiscDxe/MiscSubclassDriver.uni      |   35 +
>  .../MiscSubclassDriverDataTable.c             |   98 +
>  .../MiscSubclassDriverEntryPoint.c            |  182 +
>  .../MiscSystemLanguageString.uni              |   24 +
>  .../MiscSystemLanguageStringData.c            |   34 +
>  .../MiscSystemLanguageStringFunction.c        |   93 +
>  .../SmBiosMiscDxe/MiscSystemManufacturer.uni  |   30 +
>  .../MiscSystemManufacturerData.c              |   48 +
>  .../MiscSystemManufacturerFunction.c          |  364 ++
>  .../SmBiosMiscDxe/MiscSystemOptionString.uni  |   24 +
>  .../MiscSystemOptionStringData.c              |   31 +
>  .../MiscSystemOptionStringFunction.c          |   93 +
>  .../MiscSystemSlotDesignation.uni             |   34 +
>  .../MiscSystemSlotDesignationData.c           |  246 +
>  .../MiscSystemSlotDesignationFunction.c       |  127 +
>  .../SmBiosMiscDxe/SmBiosMiscDxe.inf           |  139 +
>  .../SmmSwDispatch2OnSmmSwDispatchThunk.c      |  459 ++
>  .../SmmSwDispatch2OnSmmSwDispatchThunk.inf    |   54 +
>  .../SmramSaveInfoHandlerSmm.c                 |  164 +
>  .../SmramSaveInfoHandlerSmm.inf               |   60 +
>  .../Stitch/Gcc/NvStorageFtwSpare.bin          |  Bin 0 -> 262144 bytes
>  .../Stitch/Gcc/NvStorageFtwWorking.bin        |  Bin 0 -> 8192 bytes
>  .../Stitch/Gcc/NvStorageVariable.bin          |  Bin 0 -> 253952 bytes
>  .../Stitch/IFWIHeader/IFWI_HEADER.bin         |  Bin 0 -> 4096 bytes
>  .../Stitch/IFWIHeader/IFWI_HEADER_SPILOCK.bin |  Bin 0 -> 4096 bytes
>  .../Stitch/IFWIHeader/Vacant.bin              |  Bin 0 -> 3928064 bytes
>  .../Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat   |  270 +
>  .../Stitch/MNW2_Stitch_Config.txt             |   10 +
>  .../Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c |   33 +
>  .../Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf   |   32 +
>  .../VlvPlatformInitDxe/IgdOpRegion.c          |  929 ++++
>  .../VlvPlatformInitDxe/IgdOpRegion.h          |  235 +
>  .../VlvPlatformInitDxe/VlvPlatformInit.c      |  287 ++
>  .../VlvPlatformInitDxe/VlvPlatformInit.h      |   65 +
>  .../VlvPlatformInitDxe/VlvPlatformInitDxe.inf |   74 +
>  .../Vlv2TbltDevicePkg/Wpce791/LpcDriver.c     |  340 ++
>  .../Vlv2TbltDevicePkg/Wpce791/LpcDriver.h     |  112 +
>  .../Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c    |  366 ++
>  .../Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h    |  103 +
>  .../Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c  |  126 +
>  .../Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h  |  101 +
>  .../Vlv2TbltDevicePkg/Wpce791/Wpce791.inf     |   63 +
>  Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat  |  332 ++
>  Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh   |  256 +
>  Platform/Intel/Vlv2TbltDevicePkg/cln.sh       |   62 +
>  Readme.md                                     |    9 +
>  .../Include/DdrMemoryController.h             |  251 +
>  .../QuarkNorthCluster/Include/IntelQNCBase.h  |   17 +
>  .../Include/IntelQNCConfig.h                  |  100 +
>  .../QuarkNorthCluster/Include/IntelQNCDxe.h   |   17 +
>  .../QuarkNorthCluster/Include/IntelQNCPeim.h  |   17 +
>  .../QuarkNorthCluster/Include/IntelQNCRegs.h  |   48 +
>  .../Include/Library/IntelQNCLib.h             |  284 ++
>  .../Include/Library/QNCAccessLib.h            |  161 +
>  .../Include/Library/QNCSmmLib.h               |   57 +
>  .../Include/Ppi/QNCMemoryInit.h               |   36 +
>  .../Include/Protocol/PchInfo.h                |   48 +
>  .../Include/Protocol/PlatformPolicy.h         |   31 +
>  .../Include/Protocol/QncS3Support.h           |   84 +
>  .../Include/Protocol/SmmIchnDispatch2.h       |  115 +
>  .../QuarkNorthCluster/Include/Protocol/Spi.h  |  345 ++
>  .../QuarkNorthCluster/Include/QNCAccess.h     |  177 +
>  .../Include/QNCCommonDefinitions.h            |  350 ++
>  .../QuarkNorthCluster/Include/QuarkNcSocId.h  |  751 +++
>  .../Library/IntelQNCLib/CommonHeader.h        |   32 +
>  .../Library/IntelQNCLib/IntelQNCLib.c         |  771 +++
>  .../Library/IntelQNCLib/IntelQNCLib.inf       |   57 +
>  .../Library/IntelQNCLib/PciExpress.c          |  932 ++++
>  .../Library/MtrrLib/MtrrLib.c                 | 2112 ++++++++
>  .../Library/MtrrLib/MtrrLib.inf               |   42 +
>  .../Library/MtrrLib/MtrrLib.uni               |   18 +
>  .../Library/QNCAccessLib/BaseAccess.c         |   28 +
>  .../Library/QNCAccessLib/QNCAccessLib.c       |  327 ++
>  .../Library/QNCAccessLib/QNCAccessLib.inf     |   37 +
>  .../Library/QNCAccessLib/RuntimeAccess.c      |  142 +
>  .../QNCAccessLib/RuntimeQNCAccessLib.inf      |   43 +
>  .../Library/QNCSmmLib/QNCSmmLib.c             |  313 ++
>  .../Library/QNCSmmLib/QNCSmmLib.inf           |   44 +
>  .../Library/ResetSystemLib/ResetSystemLib.c   |  379 ++
>  .../Library/ResetSystemLib/ResetSystemLib.inf |   46 +
>  .../Library/SmbusLib/CommonHeader.h           |   25 +
>  .../Library/SmbusLib/SmbusLib.c               |  797 +++
>  .../Library/SmbusLib/SmbusLib.inf             |   47 +
>  .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.c     |  446 ++
>  .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf   |   30 +
>  .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.uni   |   12 +
>  .../MemoryInit/Pei/MemoryInit.c               |   59 +
>  .../MemoryInit/Pei/MemoryInit.h               |   35 +
>  .../MemoryInit/Pei/MemoryInitPei.inf          |   70 +
>  .../MemoryInit/Pei/core_types.h               |   43 +
>  .../MemoryInit/Pei/gen5_iosf_sb_definitions.h |  738 +++
>  .../MemoryInit/Pei/general_definitions.h      |   84 +
>  .../QuarkNorthCluster/MemoryInit/Pei/hte.c    |  536 ++
>  .../QuarkNorthCluster/MemoryInit/Pei/hte.h    |   66 +
>  .../QuarkNorthCluster/MemoryInit/Pei/io.h     |  132 +
>  .../QuarkNorthCluster/MemoryInit/Pei/lprint.c |  382 ++
>  .../MemoryInit/Pei/meminit.c                  | 2638 ++++++++++
>  .../MemoryInit/Pei/meminit.h                  |   22 +
>  .../MemoryInit/Pei/meminit_utils.c            | 1574 ++++++
>  .../MemoryInit/Pei/meminit_utils.h            |   95 +
>  .../MemoryInit/Pei/memory_options.h           |   77 +
>  .../QuarkNorthCluster/MemoryInit/Pei/mrc.c    |   40 +
>  .../QuarkNorthCluster/MemoryInit/Pei/mrc.h    |  160 +
>  .../MemoryInit/Pei/platform.c                 |  186 +
>  .../MemoryInit/Pei/prememinit.c               |  187 +
>  .../MemoryInit/Pei/prememinit.h               |   15 +
>  .../QNCInit/Dxe/CommonHeader.h                |   49 +
>  .../QNCInit/Dxe/DxeQNCSmbus.c                 |  612 +++
>  .../QNCInit/Dxe/DxeQNCSmbus.h                 |  205 +
>  .../QNCInit/Dxe/LegacyRegion.c                |  237 +
>  .../QNCInit/Dxe/LegacyRegion.h                |  198 +
>  .../QuarkNorthCluster/QNCInit/Dxe/QNCInit.c   |  518 ++
>  .../QuarkNorthCluster/QNCInit/Dxe/QNCInit.h   |   49 +
>  .../QNCInit/Dxe/QNCInitDxe.inf                |   92 +
>  .../QNCInit/Dxe/QNCRootPorts.c                |   76 +
>  .../QuarkNorthCluster/QNCInit/Dxe/QNCSmbus.h  |   80 +
>  .../QNCInit/Dxe/QNCSmbusExec.c                |  246 +
>  .../S3Support/Dxe/QncS3Support.c              |  417 ++
>  .../S3Support/Dxe/QncS3Support.h              |  117 +
>  .../S3Support/Dxe/QncS3Support.inf            |   64 +
>  .../Smm/Dxe/SmmAccessDxe/SmmAccess.inf        |   49 +
>  .../Smm/Dxe/SmmAccessDxe/SmmAccessDriver.c    |  405 ++
>  .../Smm/Dxe/SmmAccessDxe/SmmAccessDriver.h    |  230 +
>  .../Smm/Dxe/SmmControlDxe/SmmControlDriver.c  |  358 ++
>  .../Smm/Dxe/SmmControlDxe/SmmControlDxe.inf   |   55 +
>  .../DxeSmm/QncSmmDispatcher/CommonHeader.h    |   45 +
>  .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmGpi.c   |   32 +
>  .../QncSmmDispatcher/QNC/QNCSmmHelpers.c      |  549 ++
>  .../QNC/QNCSmmPeriodicTimer.c                 |  424 ++
>  .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmQncn.c  |  211 +
>  .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmSw.c    |   90 +
>  .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmSx.c    |  147 +
>  .../Smm/DxeSmm/QncSmmDispatcher/QNCSmm.h      |  868 ++++
>  .../Smm/DxeSmm/QncSmmDispatcher/QNCSmmCore.c  |  825 +++
>  .../QncSmmDispatcher/QNCSmmDispatcher.inf     |   81 +
>  .../DxeSmm/QncSmmDispatcher/QNCSmmHelpers.c   |  367 ++
>  .../DxeSmm/QncSmmDispatcher/QNCSmmHelpers.h   |  219 +
>  .../DxeSmm/QncSmmDispatcher/QNCSmmRegisters.h |   13 +
>  .../DxeSmm/QncSmmDispatcher/QNCxSmmHelpers.h  |  178 +
>  .../Smm/Pei/SmmAccessPei/SmmAccessPei.c       |  376 ++
>  .../Smm/Pei/SmmAccessPei/SmmAccessPei.inf     |   45 +
>  .../Smm/Pei/SmmControlPei/SmmControlPei.c     |  274 +
>  .../Smm/Pei/SmmControlPei/SmmControlPei.inf   |   51 +
>  .../QuarkNorthCluster/Spi/Common/SpiCommon.c  |  927 ++++
>  .../QuarkNorthCluster/Spi/Common/SpiCommon.h  |  317 ++
>  .../QuarkNorthCluster/Spi/PchSpiRuntime.inf   |   84 +
>  .../QuarkNorthCluster/Spi/PchSpiSmm.inf       |   50 +
>  .../QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.c |  205 +
>  .../QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.h |   79 +
>  .../QuarkNorthCluster/Spi/Smm/PchSpi.c        |  123 +
>  .../QuarkNorthCluster/Spi/Smm/PchSpi.h        |   47 +
>  Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dec     |  234 +
>  Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dsc     |  254 +
>  .../QuarkSouthCluster/Include/CEATA.h         |  114 +
>  .../QuarkSouthCluster/Include/I2cRegs.h       |   95 +
>  .../QuarkSouthCluster/Include/Ioh.h           |  248 +
>  .../QuarkSouthCluster/Include/IohAccess.h     |   18 +
>  .../Include/IohCommonDefinitions.h            |  342 ++
>  .../Include/Library/I2cLib.h                  |  152 +
>  .../Include/Library/IohLib.h                  |   36 +
>  .../QuarkSouthCluster/Include/MMC.h           |  274 +
>  .../QuarkSouthCluster/Include/SDCard.h        |  146 +
>  .../QuarkSouthCluster/Include/SDHostIo.h      |  333 ++
>  .../IohInit/Dxe/CommonHeader.h                |   55 +
>  .../QuarkSouthCluster/IohInit/Dxe/IohBds.h    |   83 +
>  .../QuarkSouthCluster/IohInit/Dxe/IohData.c   |   42 +
>  .../QuarkSouthCluster/IohInit/Dxe/IohInit.c   |   37 +
>  .../IohInit/Dxe/IohInitDxe.inf                |   76 +
>  .../Library/I2cLib/CommonHeader.h             |  214 +
>  .../QuarkSouthCluster/Library/I2cLib/I2cLib.c |  998 ++++
>  .../Library/I2cLib/I2cLib.inf                 |   62 +
>  .../Library/IohLib/CommonHeader.h             |   29 +
>  .../QuarkSouthCluster/Library/IohLib/IohLib.c |   99 +
>  .../Library/IohLib/IohLib.inf                 |   49 +
>  .../Sdio/Dxe/SDControllerDxe/ComponentName.c  |  227 +
>  .../Sdio/Dxe/SDControllerDxe/ComponentName.h  |  141 +
>  .../Sdio/Dxe/SDControllerDxe/SDController.c   | 1784 +++++++
>  .../Sdio/Dxe/SDControllerDxe/SDController.h   |  316 ++
>  .../Dxe/SDControllerDxe/SDControllerDxe.inf   |   56 +
>  .../Sdio/Dxe/SDMediaDeviceDxe/CEATA.c         |  647 +++
>  .../Sdio/Dxe/SDMediaDeviceDxe/CEATABlockIo.c  |  389 ++
>  .../Sdio/Dxe/SDMediaDeviceDxe/ComponentName.c |  215 +
>  .../Sdio/Dxe/SDMediaDeviceDxe/ComponentName.h |  139 +
>  .../Sdio/Dxe/SDMediaDeviceDxe/MMCSDBlockIo.c  |  538 ++
>  .../Sdio/Dxe/SDMediaDeviceDxe/MMCSDTransfer.c | 1708 +++++++
>  .../Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.c |  317 ++
>  .../Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.h |  462 ++
>  .../Dxe/SDMediaDeviceDxe/SDMediaDeviceDxe.inf |   60 +
>  .../QuarkSouthCluster/Usb/Common/Pei/UsbPei.c |  320 ++
>  .../QuarkSouthCluster/Usb/Common/Pei/UsbPei.h |   38 +
>  .../Usb/Common/Pei/UsbPei.inf                 |   53 +
>  .../Usb/Ohci/Dxe/ComponentName.c              |  219 +
>  .../Usb/Ohci/Dxe/ComponentName.h              |  141 +
>  .../Usb/Ohci/Dxe/Descriptor.h                 |  132 +
>  .../QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.c     | 2473 +++++++++
>  .../QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.h     |  663 +++
>  .../Usb/Ohci/Dxe/OhciDebug.c                  |   78 +
>  .../Usb/Ohci/Dxe/OhciDebug.h                  |   42 +
>  .../Usb/Ohci/Dxe/OhciDxe.inf                  |   71 +
>  .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.c  | 1390 +++++
>  .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.h  |  920 ++++
>  .../Usb/Ohci/Dxe/OhciSched.c                  |  528 ++
>  .../Usb/Ohci/Dxe/OhciSched.h                  |  225 +
>  .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.c  |  889 ++++
>  .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.h  |  387 ++
>  .../QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.c |  560 ++
>  .../QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.h |  152 +
>  .../Usb/Ohci/Pei/Descriptor.h                 |  131 +
>  .../QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.c  | 1386 +++++
>  .../QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.h  |  252 +
>  .../Usb/Ohci/Pei/OhciPei.inf                  |   56 +
>  .../QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.c  | 1386 +++++
>  .../QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.h  |  875 ++++
>  .../Usb/Ohci/Pei/OhciSched.c                  |  223 +
>  .../Usb/Ohci/Pei/OhciSched.h                  |  108 +
>  .../QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.c  |  560 ++
>  .../QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.h  |  231 +
>  .../QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.c |  491 ++
>  .../QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.h |  134 +
>  .../AcpiTablesPCAT/98_LINK.ASL                |  617 +++
>  .../AcpiTablesPCAT/AcpiTablePlatform.h        |   70 +
>  .../AcpiTablesPCAT/AcpiTables.inf             |   40 +
>  .../AcpiTablesPCAT/CPU.asl                    |   49 +
>  .../AcpiTablesPCAT/DSDT.ASL                   |   75 +
>  .../AcpiTablesPCAT/Facp/Facp.aslc             |  188 +
>  .../AcpiTablesPCAT/Facs/Facs.aslc             |   84 +
>  .../AcpiTablesPCAT/GloblNvs.asl               |  348 ++
>  .../AcpiTablesPCAT/Gpe.asl                    |   99 +
>  .../AcpiTablesPCAT/HOST_BUS.ASL               |  347 ++
>  .../AcpiTablesPCAT/Hpet/Hpet.aslc             |   63 +
>  .../AcpiTablesPCAT/INTELGFX.ASL               |  879 ++++
>  .../AcpiTablesPCAT/INTELISPDev2.ASL           |   71 +
>  .../AcpiTablesPCAT/IgdOGBDA.ASL               |  155 +
>  .../AcpiTablesPCAT/IgdOMOBF.ASL               |  485 ++
>  .../AcpiTablesPCAT/IgdOSBCB.ASL               |  274 +
>  .../AcpiTablesPCAT/IgdOpRn.ASL                |  299 ++
>  .../AcpiTablesPCAT/IoTVirtualDevice.asl       |  171 +
>  .../AcpiTablesPCAT/LPC_DEV.ASL                |  151 +
>  .../AcpiTablesPCAT/LpcB.asl                   |   59 +
>  .../AcpiTablesPCAT/Lpit/Lpit.aslc             |  223 +
>  .../AcpiTablesPCAT/Madt/Madt.h                |  189 +
>  .../AcpiTablesPCAT/Madt/Madt30.aslc           |  178 +
>  .../AcpiTablesPCAT/Mcfg/Mcfg.aslc             |   86 +
>  .../AcpiTablesPCAT/PCI_DRC.ASL                |   90 +
>  .../AcpiTablesPCAT/Pch.asl                    |  686 +++
>  .../AcpiTablesPCAT/PchAudio.asl               |   36 +
>  .../AcpiTablesPCAT/PchEhci.asl                |  269 +
>  .../AcpiTablesPCAT/PchLpss.asl                | 1093 ++++
>  .../AcpiTablesPCAT/PchPcie.asl                |   50 +
>  .../AcpiTablesPCAT/PchScc.asl                 |  610 +++
>  .../AcpiTablesPCAT/PchSmb.asl                 |  833 +++
>  .../AcpiTablesPCAT/PchXhci.asl                |  379 ++
>  .../AcpiTablesPCAT/PciTree.asl                |  377 ++
>  .../AcpiTablesPCAT/Platform.asl               |  703 +++
>  .../AcpiTablesPCAT/RTD3.asl                   |  197 +
>  .../AcpiTablesPCAT/RhProxy.asl                |  160 +
>  .../AcpiTablesPCAT/THERMAL.ASL                |  137 +
>  .../AcpiTablesPCAT/UsbSbd.asl                 |   93 +
>  .../AcpiTablesPCAT/Video.asl                  |   34 +
>  .../AcpiTablesPCAT/Vlv.asl                    |   39 +
>  .../AcpiTablesPCAT/Wsmt/Wsmt.aslc             |   54 +
>  .../AcpiTablesPCAT/token.asl                  |   39 +
>  .../Guid/Vlv2DeviceRefCodePkgTokenSpace.h     |   24 +
>  .../Include/Ppi/PttPassThruPpi.h              |   92 +
>  .../Include/Ppi/fTPMPolicy.h                  |   26 +
>  .../Include/Protocol/PttPassThru.h            |   91 +
>  .../Guid/PowerManagementAcpiTableStorage.h    |   27 +
>  .../CPU/Include/Ppi/VlvPolicy.h               |  104 +
>  .../CPU/Include/Protocol/PpmPlatformPolicy.h  |  132 +
>  .../ValleyView2Soc/CPU/Include/Types.h        |   55 +
>  .../AcpiTables/PowerManagementAcpiTables.inf  |   39 +
>  .../PowerManagement/AcpiTables/Ssdt/ApCst.asl |  110 +
>  .../PowerManagement/AcpiTables/Ssdt/ApIst.asl |  166 +
>  .../PowerManagement/AcpiTables/Ssdt/ApTst.asl |  262 +
>  .../AcpiTables/Ssdt/Cpu0Cst.asl               |  274 +
>  .../AcpiTables/Ssdt/Cpu0Ist.asl               |  260 +
>  .../AcpiTables/Ssdt/Cpu0Tst.asl               |  235 +
>  .../PowerManagement/AcpiTables/Ssdt/CpuPm.asl |  793 +++
>  .../Include/PlatformBaseAddresses.h           |   92 +
>  .../NorthCluster/Include/Ppi/Capsule.h        |   60 +
>  .../Include/Ppi/PlatformMemoryRange.h         |  144 +
>  .../Include/Ppi/PlatformMemorySize.h          |   46 +
>  .../NorthCluster/Include/Ppi/SmmAccess.h      |  165 +
>  .../NorthCluster/Include/Ppi/VlvMmioPolicy.h  |   39 +
>  .../NorthCluster/Include/Ppi/VlvPeiInit.h     |   35 +
>  .../NorthCluster/Include/Ppi/VlvPolicy.h      |  106 +
>  .../Include/Protocol/IgdOpRegion.h            |  213 +
>  .../NorthCluster/Include/Protocol/MemInfo.h   |   83 +
>  .../Include/Protocol/PlatformGopPolicy.h      |   67 +
>  .../Include/Protocol/VlvPlatformPolicy.h      |  105 +
>  .../NorthCluster/Include/Valleyview.h         |   55 +
>  .../NorthCluster/Include/VlvAccess.h          |  254 +
>  .../Include/VlvCommonDefinitions.h            |  252 +
>  .../SouthCluster/Include/Guid/PchInitVar.h    |   48 +
>  .../Include/Guid/SataControllerGuid.h         |   34 +
>  .../SouthCluster/Include/Guid/SmbusArpMap.h   |   30 +
>  .../SouthCluster/Include/Guid/Vlv2Variable.h  |   28 +
>  .../Include/IndustryStandard/CeAta.h          |  126 +
>  .../Include/IndustryStandard/Mmc.h            |  349 ++
>  .../Include/IndustryStandard/SdCard.h         |  157 +
>  .../SouthCluster/Include/Library/I2CLib.h     |  169 +
>  .../Include/Library/PchPlatformLib.h          |  115 +
>  .../SouthCluster/Include/PchAccess.h          |  471 ++
>  .../Include/PchCommonDefinitions.h            |  210 +
>  .../SouthCluster/Include/PchRegs.h            |  205 +
>  .../SouthCluster/Include/PchRegs/PchRegsHda.h |   50 +
>  .../Include/PchRegs/PchRegsLpss.h             |  486 ++
>  .../Include/PchRegs/PchRegsPcie.h             |   83 +
>  .../SouthCluster/Include/PchRegs/PchRegsPcu.h | 1201 +++++
>  .../Include/PchRegs/PchRegsRcrb.h             |   48 +
>  .../Include/PchRegs/PchRegsSata.h             |  245 +
>  .../SouthCluster/Include/PchRegs/PchRegsScc.h |   53 +
>  .../Include/PchRegs/PchRegsSmbus.h            |  149 +
>  .../SouthCluster/Include/PchRegs/PchRegsSpi.h |  119 +
>  .../SouthCluster/Include/PchRegs/PchRegsUsb.h |   92 +
>  .../SouthCluster/Include/Ppi/PchInit.h        |   75 +
>  .../SouthCluster/Include/Ppi/PchPeiInit.h     |   34 +
>  .../Include/Ppi/PchPlatformPolicy.h           |  161 +
>  .../SouthCluster/Include/Ppi/PchUsbPolicy.h   |   69 +
>  .../SouthCluster/Include/Ppi/PeiBlockIo.h     |  230 +
>  .../SouthCluster/Include/Ppi/Sdhc.h           |  359 ++
>  .../SouthCluster/Include/Ppi/SmbusPolicy.h    |   40 +
>  .../SouthCluster/Include/Ppi/Spi.h            |   42 +
>  .../Include/Protocol/ActiveBios.h             |  123 +
>  .../Include/Protocol/ActiveBiosProtocol.h     |  125 +
>  .../Protocol/DxePchPolicyUpdateProtocol.h     |   51 +
>  .../Include/Protocol/EmmcCardInfoProtocol.h   |   42 +
>  .../SouthCluster/Include/Protocol/Gpio.h      |  161 +
>  .../Include/Protocol/HwWatchdogTimer.h        |  294 ++
>  .../SouthCluster/Include/Protocol/I2cBus.h    |  164 +
>  .../Include/Protocol/PchExtendedReset.h       |   84 +
>  .../SouthCluster/Include/Protocol/PchInfo.h   |   60 +
>  .../Include/Protocol/PchPlatformPolicy.h      |  550 ++
>  .../SouthCluster/Include/Protocol/PchReset.h  |  114 +
>  .../Include/Protocol/PchS3Support.h           |  132 +
>  .../SouthCluster/Include/Protocol/SdHostIo.h  |  409 ++
>  .../Include/Protocol/SmbiosSlotPopulation.h   |   47 +
>  .../Include/Protocol/SmmIchnDispatchEx.h      |  159 +
>  .../SouthCluster/Include/Protocol/SmmSmbus.h  |   39 +
>  .../SouthCluster/Include/Protocol/Spi.h       |  260 +
>  .../SouthCluster/Include/Protocol/TcoReset.h  |   88 +
>  .../SouthCluster/Include/Rsci.h               |   28 +
>  .../SouthCluster/Include/TianoApi.h           |   61 +
>  .../Vlv2DeviceRefCodePkg.dec                  |  231 +
>  .../Omap35xxPkg/Flash/Flash.c                 |  768 +++
>  .../Omap35xxPkg/Flash/Flash.h                 |  100 +
>  .../Omap35xxPkg/Flash/Flash.inf               |   42 +
>  .../TexasInsturments/Omap35xxPkg/Gpio/Gpio.c  |  129 +
>  .../Omap35xxPkg/Gpio/Gpio.inf                 |   39 +
>  .../Omap35xxPkg/Include/Library/OmapDmaLib.h  |   84 +
>  .../Omap35xxPkg/Include/Library/OmapLib.h     |   38 +
>  .../Omap35xxPkg/Include/Omap3530/Omap3530.h   |   34 +
>  .../Include/Omap3530/Omap3530Dma.h            |  124 +
>  .../Include/Omap3530/Omap3530Gpio.h           |  125 +
>  .../Include/Omap3530/Omap3530Gpmc.h           |  101 +
>  .../Include/Omap3530/Omap3530I2c.h            |   56 +
>  .../Include/Omap3530/Omap3530Interrupt.h      |   45 +
>  .../Include/Omap3530/Omap3530MMCHS.h          |  208 +
>  .../Omap3530/Omap3530PadConfiguration.h       |  297 ++
>  .../Include/Omap3530/Omap3530Prcm.h           |  159 +
>  .../Include/Omap3530/Omap3530Timer.h          |   76 +
>  .../Include/Omap3530/Omap3530Uart.h           |   48 +
>  .../Include/Omap3530/Omap3530Usb.h            |   42 +
>  .../Omap35xxPkg/Include/TPS65950.h            |   74 +
>  .../InterruptDxe/HardwareInterrupt.c          |  396 ++
>  .../Omap35xxPkg/InterruptDxe/InterruptDxe.inf |   48 +
>  .../LcdGraphicsOutputBlt.c                    |  439 ++
>  .../LcdGraphicsOutputDxe.c                    |  394 ++
>  .../LcdGraphicsOutputDxe.h                    |  151 +
>  .../LcdGraphicsOutputDxe.inf                  |   46 +
>  .../DebugAgentTimerLib/DebugAgentTimerLib.c   |  159 +
>  .../DebugAgentTimerLib/DebugAgentTimerLib.inf |   42 +
>  .../Library/GdbSerialLib/GdbSerialLib.c       |   96 +
>  .../Library/GdbSerialLib/GdbSerialLib.inf     |   35 +
>  .../Omap35xxTimerLib/Omap35xxTimerLib.inf     |   40 +
>  .../Library/Omap35xxTimerLib/TimerLib.c       |  151 +
>  .../Library/OmapDmaLib/OmapDmaLib.c           |  170 +
>  .../Library/OmapDmaLib/OmapDmaLib.inf         |   43 +
>  .../Omap35xxPkg/Library/OmapLib/OmapLib.c     |   77 +
>  .../Omap35xxPkg/Library/OmapLib/OmapLib.inf   |   31 +
>  .../RealTimeClockLib/RealTimeClockLib.c       |  291 ++
>  .../RealTimeClockLib/RealTimeClockLib.inf     |   32 +
>  .../Library/SerialPortLib/SerialPortLib.c     |  208 +
>  .../Library/SerialPortLib/SerialPortLib.inf   |   40 +
>  .../Omap35xxPkg/MMCHSDxe/MMCHS.c              | 1492 ++++++
>  .../Omap35xxPkg/MMCHSDxe/MMCHS.h              |  169 +
>  .../Omap35xxPkg/MMCHSDxe/MMCHS.inf            |   48 +
>  .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.c       |  671 +++
>  .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.h       |   38 +
>  .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf     |   47 +
>  .../Omap35xxPkg/Omap35xxPkg.dec               |   52 +
>  .../Omap35xxPkg/Omap35xxPkg.dsc               |  183 +
>  .../Omap35xxPkg/PciEmulation/PciEmulation.c   |  107 +
>  .../Omap35xxPkg/PciEmulation/PciEmulation.inf |   41 +
>  .../Omap35xxPkg/SmbusDxe/Smbus.c              |  319 ++
>  .../Omap35xxPkg/SmbusDxe/Smbus.inf            |   39 +
>  .../Omap35xxPkg/TPS65950Dxe/TPS65950.c        |  110 +
>  .../Omap35xxPkg/TPS65950Dxe/TPS65950.inf      |   42 +
>  .../Omap35xxPkg/TimerDxe/Timer.c              |  370 ++
>  .../Omap35xxPkg/TimerDxe/TimerDxe.inf         |   51 +
>  1103 files changed, 259532 insertions(+)
>  create mode 100644
> Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.c
>  create mode 100644
> Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.inf
>  create mode 100644
> Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.c
>  create mode 100644
> Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.h
>  create mode 100644
> Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThruDxe.inf
>  create mode 100644
> Drivers/OptionRomPkg/AtapiPassThruDxe/ComponentName.c
>  create mode 100644
> Drivers/OptionRomPkg/AtapiPassThruDxe/DriverSupportedEfiVersion.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/CompatibleDevices.txt
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ComponentName.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.h
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.h
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/ComponentName
> .c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/DriverBinding.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/SimpleNetwork.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/ComponentNam
> e.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/DriverBinding.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwork.
> c
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.c
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.h
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430GraphicsOutput.
> c
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.c
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.h
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430UgaDraw.c
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/ComponentName.c
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/DriverSupportedEfiVersion.c
>  create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/Edid.c
>  create mode 100644 Drivers/OptionRomPkg/Include/Library/BltLib.h
>  create mode 100644
> Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.c
>  create mode 100644
> Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
>  create mode 100644 Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.c
>  create mode 100644 Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.inf
>  create mode 100644 Drivers/OptionRomPkg/OptionRomPkg.dec
>  create mode 100644 Drivers/OptionRomPkg/OptionRomPkg.dsc
>  create mode 100644 Drivers/OptionRomPkg/ReadMe.txt
>  create mode 100644
> Drivers/OptionRomPkg/UndiRuntimeDxe/ComponentName.c
>  create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c
>  create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c
>  create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h
>  create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c
>  create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h
>  create mode 100644
> Drivers/OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c
>  create mode 100644
> Drivers/OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.dec
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.dsc
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.fdf
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/ConfigurationHeader.bin
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/ConfigurationHeader.dat
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_boot_from_ra
> m.inc
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_convert_symb
> ols.sh
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_dummy.axf
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_hw_setup.inc
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_load_symbols.i
> nc
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_symbols_macr
> os.inc
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_unload_symbo
> ls.inc
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/trace32_load_sym
> bols.cmm
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/trace32_load_sym
> bols_cygwin.cmm
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Include/BeagleBoard.h
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoard.
> c
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoard
> Helper.S
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoard
> Helper.asm
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoard
> Lib.inf
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoard
> Mem.c
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/Clock.c
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/PadConfigur
> ation.c
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/DxeHobPeCoffLib/DxeHobPe
> Coff.c
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/DxeHobPeCoffLib/DxeHobPe
> CoffLib.inf
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/LzmaHobCustomDecompress
> Lib/LzmaHobCustomDecompressLib.c
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/LzmaHobCustomDecompress
> Lib/LzmaHobCustomDecompressLib.inf
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/MemoryInitPeiLib/MemoryIn
> itPeiLib.c
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/MemoryInitPeiLib/MemoryIn
> itPeiLib.inf
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/ResetSystemLib/ResetSystem
> Lib.c
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/ResetSystemLib/ResetSystem
> Lib.inf
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ArchPrePi.c
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ModuleEntryPoint.S
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ModuleEntryPoint.asm
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/PrePi/LzmaDecompress.h
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/PrePi/MainUniCore.c
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/PrePi/PeiUniCore.inf
>  create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/PrePi/PrePi.c
>  create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/PrePi/PrePi.h
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Tools/GNUmakefile
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Tools/generate_image.c
>  create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Tools/makefile
>  create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Tools/replace.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/AcpiTables.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Cst/Cpu0Cst.asl
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Ist/Cpu0Ist.asl
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Tst/Cpu0Tst.asl
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/CpuPm/CpuPm.asl
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/AD7298.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/ADC108S102.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/CAT24C08.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/CY8C9540A.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/GpioClient.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/LpcDev.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PCA9685.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PCAL9555A.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PciHostBridge.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PciIrq.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PcieExpansionPrt.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Platform.asl
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNC.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNCApic.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNCLpc.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QuarkSouthCluster.
> asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Tpm.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Facs/Facs.aslc
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Facs/Facs.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt1.0.aslc
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt2.0.aslc
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.aslc
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Mcfg/Mcfg.aslc
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Mcfg/Mcfg.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Madt.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/MadtPlatform.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/BootScri
> ptExecutorDxe.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/S3
> Asm.S
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/S3
> Asm.asm
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/Set
> IdtEntry.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/ScriptEx
> ecute.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/ScriptEx
> ecute.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatfor
> m.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatfor
> m.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatfor
> m.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/P
> pm.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/P
> pm.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/S
> mmPowerManagement.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/S
> mmPowerManagement.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/S
> mmPowerManagement.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Application/ForceRecovery/ForceRecovery
> .c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Application/ForceRecovery/ForceRecovery
> .inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAcc
> essLib/PlatformFlashAccessLibDxe.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAcc
> essLib/PlatformFlashAccessLibDxe.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAcc
> essLib/SpiFlashDevice.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAcc
> essLib/SpiFlashDevice.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareDescript
> or/SystemFirmwareDescriptor.aslc
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareDescript
> or/SystemFirmwareDescriptor.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareDescript
> or/SystemFirmwareDescriptorPei.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareUpdateC
> onfig/SystemFirmwareUpdateConfig.ini
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnDataCD.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatFloppyDisk.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatIdeDisk.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatUsbDisk.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Guid/MemoryConfigData.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Guid/QuarkCapsuleGuid.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Guid/QuarkVariableLock.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Guid/SystemNvDataHobGuid.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Library/PlatformHelperLib.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Library/PlatformPcieHelperLib.h
>  create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Pcal9555.h
>  create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Platform.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/PlatformBoards.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Protocol/GlobalNvsArea.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Protocol/PlatformSmmSpiReady.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/Platform
> BootManager.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/Platform
> BootManager.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/Platform
> BootManagerLib.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/Platform
> Data.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/CommonHeade
> r.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/DxePlatformHel
> perLib.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PeiPlatformHel
> perLib.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelper
> Dxe.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelper
> Lib.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelper
> Pei.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformLeds.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/CommonHe
> ader.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPci
> eHelperLib.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPci
> eHelperLib.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/SocUnit.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Flat32.S
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Flat32.asm
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Platform.inc
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLibMo
> dStrs.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecure
> Lib.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecure
> Lib.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/TisPc.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12D
> eviceLibAtmelI2c.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12D
> eviceLibAtmelI2c.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/TisPc.
> c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/Tpm1
> 2DeviceLibInfineonI2c.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/Tpm1
> 2DeviceLibInfineonI2c.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridgeSupp
> ort.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostResource.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridge.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridgeIo.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/CommonHeader.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemoryS
> ubClass.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemoryS
> ubClass.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemoryS
> ubClass.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemoryS
> ubClassStrings.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformConfig.
> c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe
> .c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe
> .h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe
> .inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveMe
> moryConfig.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveMe
> moryConfig.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/CommonHeader.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/DxePlatform.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/KeyboardLayout.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/QNCRegTable.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/Strings.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/processor.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/CommonHe
> ader.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBo
> ardManufacturer.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBo
> ardManufacturerData.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBo
> ardManufacturerFunction.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVe
> ndor.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVe
> ndorData.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVe
> ndorFunction.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootInf
> ormationData.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootInf
> ormationFunction.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassis
> Manufacturer.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassis
> ManufacturerData.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassis
> ManufacturerFunction.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscDevice
> Path.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumbe
> rOfInstallableLanguagesData.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumbe
> rOfInstallableLanguagesFunction.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemStr
> ing.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemStr
> ingData.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemStr
> ingFunction.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboar
> dDevice.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboar
> dDeviceData.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboar
> dDeviceFunction.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInt
> ernalConnectorDesignator.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInt
> ernalConnectorDesignatorData.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInt
> ernalConnectorDesignatorFunction.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystem
> Manufacturer.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystem
> ManufacturerData.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystem
> ManufacturerFunction.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystem
> OptionString.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystem
> OptionStringData.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystem
> OptionStringFunction.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystem
> SlotDesignation.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystem
> SlotDesignationData.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystem
> SlotDesignationFunction.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystem
> SlotOnboardDevices.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMisc
> .h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMisc
> DataTable.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMisc
> Dxe.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMisc
> EntryPoint.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMisc
> Strings.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConf
> igPei.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConf
> igPei.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/BootMode.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/CommonHeader
> .h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/Generic/Recove
> ry.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MemoryCallbac
> k.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyIni
> t.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyIni
> t.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyIni
> t.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformErratas.
> c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FvbInfo.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.
> c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.
> inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSpi.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.h
>  create mode 100644 Platform/Intel/QuarkPlatformPkg/Quark.dsc
>  create mode 100644 Platform/Intel/QuarkPlatformPkg/Quark.fdf
>  create mode 100644 Platform/Intel/QuarkPlatformPkg/QuarkMin.dsc
>  create mode 100644 Platform/Intel/QuarkPlatformPkg/QuarkMin.fdf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/QuarkPlatformPkg.dec
>  create mode 100644 Platform/Intel/QuarkPlatformPkg/Readme.md
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/.gitignore
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooksLib.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUp
> date.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUp
> date.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUp
> date.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUp
> dateStrings.uni
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64D.env
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64R.env
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/BootScriptSaveDxe.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/InternalBootScriptSave
> .h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/ScriptSave.c
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.bat
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.sh
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FCE.exe
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCa
> psuleAll.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCa
> psuleAll.sh
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCa
> psuleMinnowMax.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCa
> psuleMinnowMax.sh
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCa
> psuleMinnowMaxRelease.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCa
> psuleMinnowMaxRelease.sh
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCa
> psuleSampleColor.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCa
> psuleSampleColor.sh
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Lvfs.dd
> f
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGe
> nCapsuleMinnowMax.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGe
> nCapsuleMinnowMaxRelease.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGe
> nCapsuleSampleColor.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/NewRo
> ot.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMPL
> E_DEVELOPMENT.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7C
> ertBufferXdr.inc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMPL
> E_DEVELOPMENT_SAMPLE_PRODUCTION.cer.gFmpDevicePkgTokenSpaceGu
> id.PcdFmpDevicePkcs7CertBufferXdr.inc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/templa
> te.metainfo.xml
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/F
> mpDeviceLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/F
> mpDeviceLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSa
> mple/FmpDeviceLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSa
> mple/FmpDeviceLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAcc
> essLib/PlatformFlashAccessLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAcc
> essLib/PlatformFlashAccessLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescript
> or/SystemFirmwareDescriptor.aslc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescript
> or/SystemFirmwareDescriptor.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescript
> or/SystemFirmwareDescriptorPei.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdateC
> onfig/SystemFirmwareUpdateConfig.ini
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdateC
> onfig/SystemFirmwareUpdateConfigGcc.ini
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FmpCertificate.dsc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FmpGreenSampleDevice.dsc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspAzaliaConfigData/AzaliaConfig.bin
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.i
> nf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLibV
> lv2/FspHobProcessLibVlv2.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLibV
> lv2/FspHobProcessLibVlv2.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/FspPlatformSecLibVlv2.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/FspPlatformSecLibVlv2.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/Ia32/AsmSaveSecContext.asm
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/Ia32/Fsp.inc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/Ia32/PeiCoreEntry.asm
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/Ia32/SecEntry.asm
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/Ia32/Stack.S
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/Ia32/Stack.asm
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/PlatformInit.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/SaveSecContext.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/SecGetPerformance.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/SecPlatformInformation.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/SecRamInitData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/SecTempRamSupport.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/UartInit.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbRuntimeDxe.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceDxe.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceSmm.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmm.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmCommon.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.inf
>  create mode 100755 Platform/Intel/Vlv2TbltDevicePkg/GenBiosId
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/GenBiosId.exe
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/AlertStandardFormatTable.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/ChipsetAccess.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/CommonIncludes.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/CpuType.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/FileHandleLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AcpiTableStorage.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AlertStandardFormat.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BiosId.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BoardFeatures.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/EfiVpdData.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/FirmwareId.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/HwWatchdogTimerHob.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/IdccData.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/ItkData.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/MemoryConfigData.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/OsSelection.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PciLanInfo.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformCpuInfo.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformInfo.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SensorInfoVariable.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SetupVariable.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Hpet.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/BiosIdLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/CpuIA32.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/EfiRegTableLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Esrt.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Fd.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/FlashDeviceLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2CLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cMmioConfigLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cPort_platform.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFsaLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFspLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/SpiFlash.H
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/StallSmmLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/UsbDeviceModeLib.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Mcfg.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/McfgTable.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Platform.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformBootMode.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformDefinitions.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/MfgMemoryTest.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Sha256Hash.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Speaker.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/UsbController.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/CK505ClockPlatformInfo.
> h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/EnhancedSpeedstep.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/GlobalNvsArea.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/HwWatchdogTimer.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cAcpi.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBus.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBusMcg.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cHostMcg.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cMasterMcg.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cSlave.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpc83627Policy.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpce791Policy.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/MmioDevice.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Observable.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformGopPolicy.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformIdeInit.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SetupMode.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SmbiosSlotPopulation.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Speaker.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TcoReset.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TpmMp.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/UsbPolicy.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/VlvPlatformPolicy.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/SetupMode.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/IntelGopDepex/IntelGopDriver.depex
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/CpuIA32Lib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/EfiCpuVersion.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.S
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.asm
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.S
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.asm
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxe.
> c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxe.
> inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxe
> RuntimeSmm.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/SpiChipDefinitions.
> h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLibNull.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLibDxe.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CRegs.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CAccess.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/CommonHe
> ader.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpi
> TimerLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpi
> TimerLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens/B
> oardClkGens.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens/B
> oardClkGens.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/Boar
> dGpios.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/Boar
> dGpios.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers/B
> oardJumpers.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers/B
> oardJumpers.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/Bo
> ardOemIds.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/Bo
> ardOemIds.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid/B
> oardSsidSvid.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid/B
> oardSsidSvid.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib
> .c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib
> .h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib
> .inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/PlatformInfoHob
> .c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibrar
> y.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibrar
> y.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/CommonHeader.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsStrings
> .uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmosLi
> b.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmosLi
> b.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLib.in
> f
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/PlatformSerialPortLib
> .h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/CommonHeader.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmm.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmmLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2Devic
> eLibSeC.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2Devic
> eLibSeC.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2Devic
> eLibSeC.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2Devic
> eLibSeC.inf
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Logo/Logo.bmp
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Metronome/Metronome.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/EfiStatusCode.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PeiPostCode.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libra
> ry/GenericBdsLib/BdsBoot.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libra
> ry/GenericBdsLib/BdsConnect.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libra
> ry/GenericBdsLib/BdsConsole.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libra
> ry/GenericBdsLib/BdsMisc.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libra
> ry/GenericBdsLib/DevicePath.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libra
> ry/GenericBdsLib/GenericBdsLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libra
> ry/GenericBdsLib/GenericBdsLib.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libra
> ry/GenericBdsLib/GenericBdsStrings.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libra
> ry/GenericBdsLib/InternalBdsLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libra
> ry/GenericBdsLib/String.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libra
> ry/GenericBdsLib/String.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/BoardPciPlatform.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.inf
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.dsc
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.fdf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe.
> c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe.
> h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe.
> inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/AzaliaVerbTable.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardId.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ClockControl.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Configuration.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchPlatformPolicy.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchRegTable.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchTcoReset.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciBus.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Platform.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.inf
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SioPlatformPolicy.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/BootMode.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/CpuInitPeim.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/FlashMap.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MchInit.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryCallback.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryPeim.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PchInitPeim.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInfoInit.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInitPei.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformSsaInitPeim.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Recovery.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Stall.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/BootMode.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/CommonHeader.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/MemoryCallback.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/PlatformPei.inf
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Stall.c
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.dec
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgConfig.dsc
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGcc.fdf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgIA32.dsc
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgX64.dsc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Boot.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Configuration.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/DebugConfig.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/FwVersionStrings.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Main.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Security.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupFunctions.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupInfoRecords.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SouthClusterConfig.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SystemComponent.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Thermal.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UnCore.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UqiList.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Vfr.vfr
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/VfrStrings.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/Platform.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/PlatformSmm.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/S3Save.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmPlatform.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Readme.md
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.in
> f
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/CommonHeader.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufactu
> rer.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufactu
> rerData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufactu
> rerFunction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendor.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorFunction.
> c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationData
> .c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationFunc
> tion.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturer.
> uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturer
> Data.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturer
> Function.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDevice.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceFuncti
> on.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstallable
> LanguagesData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstallable
> LanguagesFunction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemString.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringFunction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Data.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Functi
> on.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Data.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Functi
> on.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDevice.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceData.
> c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceFuncti
> on.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArray.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayFunctio
> n.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnect
> orDesignator.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnect
> orDesignatorData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnect
> orDesignatorFunction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCache.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheData.
> c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheFunct
> ion.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformation
> .uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformation
> Data.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformation
> Function.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesData
> .c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesFun
> ction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverDataTa
> ble.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverEntryP
> oint.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageStrin
> g.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageStrin
> gData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageStrin
> gFunction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacturer.
> uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacturer
> Data.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacturer
> Function.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionString.
> uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStringD
> ata.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStringF
> unction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignatio
> n.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignatio
> nData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignatio
> nFunction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/SmBiosMiscDxe.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchThun
> k/SmmSwDispatch2OnSmmSwDispatchThunk.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchThun
> k/SmmSwDispatch2OnSmmSwDispatchThunk.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSaveI
> nfoHandlerSmm.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSaveI
> nfoHandlerSmm.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwSpare.bin
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwWorking.bin
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageVariable.bin
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_HEADER.bin
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_HEADER_SPILOC
> K.bin
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/Vacant.bin
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Stitch/MNW2_Stitch_Config.txt
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInitDxe.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/Wpce791.inf
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/cln.sh
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/DdrMemoryControlle
> r.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCBase.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCConfig.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCDxe.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCPeim.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCRegs.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/IntelQNCLib.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/QNCAccessLib
> .h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/QNCSmmLib.
> h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Ppi/QNCMemoryInit.
> h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/PchInfo.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/PlatformPoli
> cy.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/QncS3Supp
> ort.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/SmmIchnDis
> patch2.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/Spi.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QNCAccess.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QNCCommonDefiniti
> ons.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QuarkNcSocId.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/Common
> Header.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNC
> Lib.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNC
> Lib.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/PciExpres
> s.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.uni
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/BaseAc
> cess.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/QNCAc
> cessLib.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/QNCAc
> cessLib.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/Runtim
> eAccess.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/Runtim
> eQNCAccessLib.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCSmmLib/QNCSm
> mLib.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCSmmLib/QNCSm
> mLib.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/Reset
> SystemLib.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/Reset
> SystemLib.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/CommonHe
> ader.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/SmbusLib.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/SmbusLib.i
> nf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/
> SmmCpuFeaturesLib.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/
> SmmCpuFeaturesLib.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/
> SmmCpuFeaturesLib.uni
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInit.
> c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInit.
> h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInitP
> ei.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/core_types.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/gen5_iosf_sb
> _definitions.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/general_defi
> nitions.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/hte.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/hte.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/io.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/lprint.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit_util
> s.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit_util
> s.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/memory_opt
> ions.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/mrc.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/mrc.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/platform.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/prememinit.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/prememinit.
> h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/CommonHeader
> .h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.
> h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInitDxe.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCRootPorts.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbus.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbusExec.
> c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Suppor
> t.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Suppor
> t.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Suppor
> t.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/Sm
> mAccess.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/Sm
> mAccessDriver.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/Sm
> mAccessDriver.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmControlDxe/S
> mmControlDriver.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmControlDxe/S
> mmControlDxe.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
> tcher/CommonHeader.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
> tcher/QNC/QNCSmmGpi.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
> tcher/QNC/QNCSmmHelpers.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
> tcher/QNC/QNCSmmPeriodicTimer.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
> tcher/QNC/QNCSmmQncn.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
> tcher/QNC/QNCSmmSw.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
> tcher/QNC/QNCSmmSx.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
> tcher/QNCSmm.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
> tcher/QNCSmmCore.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
> tcher/QNCSmmDispatcher.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
> tcher/QNCSmmHelpers.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
> tcher/QNCSmmHelpers.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
> tcher/QNCSmmRegisters.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispa
> tcher/QNCxSmmHelpers.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmAccessPei/Sm
> mAccessPei.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmAccessPei/Sm
> mAccessPei.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/Sm
> mControlPei.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/Sm
> mControlPei.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Common/SpiCommon.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Common/SpiCommon.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiRuntime.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiSmm.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchSpi.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchSpi.h
>  create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dec
>  create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dsc
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/CEATA.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/I2cRegs.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Ioh.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/IohAccess.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/IohCommonDefinitio
> ns.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Library/I2cLib.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Library/IohLib.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/MMC.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/SDCard.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/SDHostIo.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/CommonHeader.
> h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohBds.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohData.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohInit.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohInitDxe.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/CommonHeade
> r.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/I2cLib.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/I2cLib.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/CommonHead
> er.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/IohLib.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/IohLib.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/Co
> mponentName.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/Co
> mponentName.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SD
> Controller.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SD
> Controller.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SD
> ControllerDxe.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/
> CEATA.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/
> CEATABlockIo.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/
> ComponentName.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/
> ComponentName.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/
> MMCSDBlockIo.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/
> MMCSDTransfer.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/
> SDMediaDevice.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/
> SDMediaDevice.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/
> SDMediaDeviceDxe.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/ComponentNa
> me.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/ComponentNa
> me.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Descriptor.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDebug.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDebug.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDxe.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciSched.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciSched.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/Descriptor.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciPei.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciSched.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciSched.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/98_LINK.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTablePlatform.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTables.inf
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/CPU.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/DSDT.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facp/Facp.aslc
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facs/Facs.aslc
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/GloblNvs.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Gpe.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/HOST_BUS.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Hpet/Hpet.aslc
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELGFX.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELISPDev2.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOGBDA.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOMOBF.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOSBCB.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOpRn.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IoTVirtualDevice.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LPC_DEV.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LpcB.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Lpit/Lpit.aslc
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt30.aslc
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Mcfg/Mcfg.aslc
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PCI_DRC.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Pch.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchAudio.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchEhci.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchLpss.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchPcie.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchScc.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchSmb.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchXhci.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PciTree.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Platform.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RTD3.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RhProxy.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/THERMAL.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/UsbSbd.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Video.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Vlv.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Wsmt/Wsmt.aslc
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/token.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Guid/Vlv2DeviceRefCodePkgTo
> kenSpace.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/PttPassThruPpi.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/fTPMPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Protocol/PttPassThru.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Guid/Pow
> erManagementAcpiTableStorage.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Ppi/VlvPol
> icy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Protocol/
> PpmPlatformPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Types.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/PowerManagementAcpiTables.inf
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/Ssdt/ApCst.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/Ssdt/ApIst.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/Ssdt/ApTst.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/Ssdt/Cpu0Cst.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/Ssdt/Cpu0Ist.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/Ssdt/Cpu0Tst.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/Ssdt/CpuPm.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/P
> latformBaseAddresses.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/P
> pi/Capsule.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/P
> pi/PlatformMemoryRange.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/P
> pi/PlatformMemorySize.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/P
> pi/SmmAccess.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/P
> pi/VlvMmioPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/P
> pi/VlvPeiInit.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/P
> pi/VlvPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/P
> rotocol/IgdOpRegion.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/P
> rotocol/MemInfo.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/P
> rotocol/PlatformGopPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/P
> rotocol/VlvPlatformPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/V
> alleyview.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/V
> lvAccess.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/V
> lvCommonDefinitions.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/G
> uid/PchInitVar.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/G
> uid/SataControllerGuid.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/G
> uid/SmbusArpMap.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/G
> uid/Vlv2Variable.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/I
> ndustryStandard/CeAta.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/I
> ndustryStandard/Mmc.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/I
> ndustryStandard/SdCard.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Li
> brary/I2CLib.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/Li
> brary/PchPlatformLib.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> chAccess.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> chCommonDefinitions.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> chRegs.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> chRegs/PchRegsHda.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> chRegs/PchRegsLpss.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> chRegs/PchRegsPcie.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> chRegs/PchRegsPcu.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> chRegs/PchRegsRcrb.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> chRegs/PchRegsSata.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> chRegs/PchRegsScc.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> chRegs/PchRegsSmbus.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> chRegs/PchRegsSpi.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> chRegs/PchRegsUsb.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> pi/PchInit.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> pi/PchPeiInit.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> pi/PchPlatformPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> pi/PchUsbPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> pi/PeiBlockIo.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> pi/Sdhc.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> pi/SmbusPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> pi/Spi.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> rotocol/ActiveBios.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> rotocol/ActiveBiosProtocol.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> rotocol/DxePchPolicyUpdateProtocol.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> rotocol/EmmcCardInfoProtocol.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> rotocol/Gpio.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> rotocol/HwWatchdogTimer.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> rotocol/I2cBus.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> rotocol/PchExtendedReset.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> rotocol/PchInfo.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> rotocol/PchPlatformPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> rotocol/PchReset.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> rotocol/PchS3Support.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> rotocol/SdHostIo.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> rotocol/SmbiosSlotPopulation.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> rotocol/SmmIchnDispatchEx.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> rotocol/SmmSmbus.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> rotocol/Spi.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/P
> rotocol/TcoReset.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/R
> sci.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/T
> ianoApi.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
>  create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.c
>  create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.h
>  create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.inf
>  create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.c
>  create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapDmaLib.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapLib.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Dma
> .h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpio
> .h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpm
> c.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530I2c.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Inter
> rupt.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530MM
> CHS.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530PadC
> onfiguration.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Prcm
> .h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Time
> r.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Uart.
> h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Usb.
> h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/TPS65950.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/HardwareInterrupt.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/InterruptDxe.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphics
> OutputBlt.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphics
> OutputDxe.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphics
> OutputDxe.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphics
> OutputDxe.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/Debu
> gAgentTimerLib.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/Debu
> gAgentTimerLib.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.in
> f
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/Omap3
> 5xxTimerLib.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/TimerLi
> b.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib
> .c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib
> .inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTime
> ClockLib.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTime
> ClockLib.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.i
> nf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dec
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dsc
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/Timer.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/TimerDxe.inf
> 
> --
> 2.21.0.windows.1


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [edk2-platforms: Patch 5/8] Platform/Vlv2DeviceRefCodePkg: Import Vlv2DeviceRefCodePkg from edk2
  2019-05-10  3:34 ` [edk2-platforms: Patch 5/8] Platform/Vlv2DeviceRefCodePkg: Import Vlv2DeviceRefCodePkg " Michael D Kinney
@ 2019-05-13  2:52   ` Sun, Zailiang
  0 siblings, 0 replies; 23+ messages in thread
From: Sun, Zailiang @ 2019-05-13  2:52 UTC (permalink / raw)
  To: Kinney, Michael D, devel@edk2.groups.io
  Cc: Qian, Yi, Kubacki, Michael A, Leif Lindholm, Ard Biesheuvel

Reviewed-by: Zailiang Sun <zailiang.sun@intel.com>

> -----Original Message-----
> From: Kinney, Michael D
> Sent: Friday, May 10, 2019 11:35 AM
> To: devel@edk2.groups.io
> Cc: Sun, Zailiang <zailiang.sun@intel.com>; Qian, Yi <yi.qian@intel.com>;
> Kubacki, Michael A <michael.a.kubacki@intel.com>; Leif Lindholm
> <leif.lindholm@linaro.org>; Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Subject: [edk2-platforms: Patch 5/8] Platform/Vlv2DeviceRefCodePkg:
> Import Vlv2DeviceRefCodePkg from edk2
> 
> https://bugzilla.tianocore.org/show_bug.cgi?id=1374
> 
> Import Vlv2DeviceRefCodePkg 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>
> ---
>  .../AcpiTablesPCAT/98_LINK.ASL                |  617 +++++++++
>  .../AcpiTablesPCAT/AcpiTablePlatform.h        |   70 +
>  .../AcpiTablesPCAT/AcpiTables.inf             |   40 +
>  .../AcpiTablesPCAT/CPU.asl                    |   49 +
>  .../AcpiTablesPCAT/DSDT.ASL                   |   75 +
>  .../AcpiTablesPCAT/Facp/Facp.aslc             |  188 +++
>  .../AcpiTablesPCAT/Facs/Facs.aslc             |   84 ++
>  .../AcpiTablesPCAT/GloblNvs.asl               |  348 +++++
>  .../AcpiTablesPCAT/Gpe.asl                    |   99 ++
>  .../AcpiTablesPCAT/HOST_BUS.ASL               |  347 +++++
>  .../AcpiTablesPCAT/Hpet/Hpet.aslc             |   63 +
>  .../AcpiTablesPCAT/INTELGFX.ASL               |  879 ++++++++++++
>  .../AcpiTablesPCAT/INTELISPDev2.ASL           |   71 +
>  .../AcpiTablesPCAT/IgdOGBDA.ASL               |  155 +++
>  .../AcpiTablesPCAT/IgdOMOBF.ASL               |  485 +++++++
>  .../AcpiTablesPCAT/IgdOSBCB.ASL               |  274 ++++
>  .../AcpiTablesPCAT/IgdOpRn.ASL                |  299 ++++
>  .../AcpiTablesPCAT/IoTVirtualDevice.asl       |  171 +++
>  .../AcpiTablesPCAT/LPC_DEV.ASL                |  151 +++
>  .../AcpiTablesPCAT/LpcB.asl                   |   59 +
>  .../AcpiTablesPCAT/Lpit/Lpit.aslc             |  223 +++
>  .../AcpiTablesPCAT/Madt/Madt.h                |  189 +++
>  .../AcpiTablesPCAT/Madt/Madt30.aslc           |  178 +++
>  .../AcpiTablesPCAT/Mcfg/Mcfg.aslc             |   86 ++
>  .../AcpiTablesPCAT/PCI_DRC.ASL                |   90 ++
>  .../AcpiTablesPCAT/Pch.asl                    |  686 ++++++++++
>  .../AcpiTablesPCAT/PchAudio.asl               |   36 +
>  .../AcpiTablesPCAT/PchEhci.asl                |  269 ++++
>  .../AcpiTablesPCAT/PchLpss.asl                | 1093 +++++++++++++++
>  .../AcpiTablesPCAT/PchPcie.asl                |   50 +
>  .../AcpiTablesPCAT/PchScc.asl                 |  610 +++++++++
>  .../AcpiTablesPCAT/PchSmb.asl                 |  833 ++++++++++++
>  .../AcpiTablesPCAT/PchXhci.asl                |  379 ++++++
>  .../AcpiTablesPCAT/PciTree.asl                |  377 ++++++
>  .../AcpiTablesPCAT/Platform.asl               |  703 ++++++++++
>  .../AcpiTablesPCAT/RTD3.asl                   |  197 +++
>  .../AcpiTablesPCAT/RhProxy.asl                |  160 +++
>  .../AcpiTablesPCAT/THERMAL.ASL                |  137 ++
>  .../AcpiTablesPCAT/UsbSbd.asl                 |   93 ++
>  .../AcpiTablesPCAT/Video.asl                  |   34 +
>  .../AcpiTablesPCAT/Vlv.asl                    |   39 +
>  .../AcpiTablesPCAT/Wsmt/Wsmt.aslc             |   54 +
>  .../AcpiTablesPCAT/token.asl                  |   39 +
>  .../Guid/Vlv2DeviceRefCodePkgTokenSpace.h     |   24 +
>  .../Include/Ppi/PttPassThruPpi.h              |   92 ++
>  .../Include/Ppi/fTPMPolicy.h                  |   26 +
>  .../Include/Protocol/PttPassThru.h            |   91 ++
>  .../Guid/PowerManagementAcpiTableStorage.h    |   27 +
>  .../CPU/Include/Ppi/VlvPolicy.h               |  104 ++
>  .../CPU/Include/Protocol/PpmPlatformPolicy.h  |  132 ++
>  .../ValleyView2Soc/CPU/Include/Types.h        |   55 +
>  .../AcpiTables/PowerManagementAcpiTables.inf  |   39 +
>  .../PowerManagement/AcpiTables/Ssdt/ApCst.asl |  110 ++
>  .../PowerManagement/AcpiTables/Ssdt/ApIst.asl |  166 +++
>  .../PowerManagement/AcpiTables/Ssdt/ApTst.asl |  262 ++++
>  .../AcpiTables/Ssdt/Cpu0Cst.asl               |  274 ++++
>  .../AcpiTables/Ssdt/Cpu0Ist.asl               |  260 ++++
>  .../AcpiTables/Ssdt/Cpu0Tst.asl               |  235 ++++
>  .../PowerManagement/AcpiTables/Ssdt/CpuPm.asl |  793 +++++++++++
>  .../Include/PlatformBaseAddresses.h           |   92 ++
>  .../NorthCluster/Include/Ppi/Capsule.h        |   60 +
>  .../Include/Ppi/PlatformMemoryRange.h         |  144 ++
>  .../Include/Ppi/PlatformMemorySize.h          |   46 +
>  .../NorthCluster/Include/Ppi/SmmAccess.h      |  165 +++
>  .../NorthCluster/Include/Ppi/VlvMmioPolicy.h  |   39 +
>  .../NorthCluster/Include/Ppi/VlvPeiInit.h     |   35 +
>  .../NorthCluster/Include/Ppi/VlvPolicy.h      |  106 ++
>  .../Include/Protocol/IgdOpRegion.h            |  213 +++
>  .../NorthCluster/Include/Protocol/MemInfo.h   |   83 ++
>  .../Include/Protocol/PlatformGopPolicy.h      |   67 +
>  .../Include/Protocol/VlvPlatformPolicy.h      |  105 ++
>  .../NorthCluster/Include/Valleyview.h         |   55 +
>  .../NorthCluster/Include/VlvAccess.h          |  254 ++++
>  .../Include/VlvCommonDefinitions.h            |  252 ++++
>  .../SouthCluster/Include/Guid/PchInitVar.h    |   48 +
>  .../Include/Guid/SataControllerGuid.h         |   34 +
>  .../SouthCluster/Include/Guid/SmbusArpMap.h   |   30 +
>  .../SouthCluster/Include/Guid/Vlv2Variable.h  |   28 +
>  .../Include/IndustryStandard/CeAta.h          |  126 ++
>  .../Include/IndustryStandard/Mmc.h            |  349 +++++
>  .../Include/IndustryStandard/SdCard.h         |  157 +++
>  .../SouthCluster/Include/Library/I2CLib.h     |  169 +++
>  .../Include/Library/PchPlatformLib.h          |  115 ++
>  .../SouthCluster/Include/PchAccess.h          |  471 +++++++
>  .../Include/PchCommonDefinitions.h            |  210 +++
>  .../SouthCluster/Include/PchRegs.h            |  205 +++
>  .../SouthCluster/Include/PchRegs/PchRegsHda.h |   50 +
>  .../Include/PchRegs/PchRegsLpss.h             |  486 +++++++
>  .../Include/PchRegs/PchRegsPcie.h             |   83 ++
>  .../SouthCluster/Include/PchRegs/PchRegsPcu.h | 1201
> +++++++++++++++++
>  .../Include/PchRegs/PchRegsRcrb.h             |   48 +
>  .../Include/PchRegs/PchRegsSata.h             |  245 ++++
>  .../SouthCluster/Include/PchRegs/PchRegsScc.h |   53 +
>  .../Include/PchRegs/PchRegsSmbus.h            |  149 ++
>  .../SouthCluster/Include/PchRegs/PchRegsSpi.h |  119 ++
>  .../SouthCluster/Include/PchRegs/PchRegsUsb.h |   92 ++
>  .../SouthCluster/Include/Ppi/PchInit.h        |   75 +
>  .../SouthCluster/Include/Ppi/PchPeiInit.h     |   34 +
>  .../Include/Ppi/PchPlatformPolicy.h           |  161 +++
>  .../SouthCluster/Include/Ppi/PchUsbPolicy.h   |   69 +
>  .../SouthCluster/Include/Ppi/PeiBlockIo.h     |  230 ++++
>  .../SouthCluster/Include/Ppi/Sdhc.h           |  359 +++++
>  .../SouthCluster/Include/Ppi/SmbusPolicy.h    |   40 +
>  .../SouthCluster/Include/Ppi/Spi.h            |   42 +
>  .../Include/Protocol/ActiveBios.h             |  123 ++
>  .../Include/Protocol/ActiveBiosProtocol.h     |  125 ++
>  .../Protocol/DxePchPolicyUpdateProtocol.h     |   51 +
>  .../Include/Protocol/EmmcCardInfoProtocol.h   |   42 +
>  .../SouthCluster/Include/Protocol/Gpio.h      |  161 +++
>  .../Include/Protocol/HwWatchdogTimer.h        |  294 ++++
>  .../SouthCluster/Include/Protocol/I2cBus.h    |  164 +++
>  .../Include/Protocol/PchExtendedReset.h       |   84 ++
>  .../SouthCluster/Include/Protocol/PchInfo.h   |   60 +
>  .../Include/Protocol/PchPlatformPolicy.h      |  550 ++++++++
>  .../SouthCluster/Include/Protocol/PchReset.h  |  114 ++
>  .../Include/Protocol/PchS3Support.h           |  132 ++
>  .../SouthCluster/Include/Protocol/SdHostIo.h  |  409 ++++++
>  .../Include/Protocol/SmbiosSlotPopulation.h   |   47 +
>  .../Include/Protocol/SmmIchnDispatchEx.h      |  159 +++
>  .../SouthCluster/Include/Protocol/SmmSmbus.h  |   39 +
>  .../SouthCluster/Include/Protocol/Spi.h       |  260 ++++
>  .../SouthCluster/Include/Protocol/TcoReset.h  |   88 ++
>  .../SouthCluster/Include/Rsci.h               |   28 +
>  .../SouthCluster/Include/TianoApi.h           |   61 +
>  .../Vlv2DeviceRefCodePkg.dec                  |  231 ++++
>  125 files changed, 24185 insertions(+)
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/98_LINK.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTablePlatform.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTables.inf
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/CPU.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/DSDT.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facp/Facp.aslc
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facs/Facs.aslc
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/GloblNvs.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Gpe.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/HOST_BUS.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Hpet/Hpet.aslc
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELGFX.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELISPDev2.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOGBDA.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOMOBF.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOSBCB.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOpRn.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IoTVirtualDevice.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LPC_DEV.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LpcB.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Lpit/Lpit.aslc
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt30.aslc
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Mcfg/Mcfg.aslc
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PCI_DRC.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Pch.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchAudio.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchEhci.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchLpss.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchPcie.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchScc.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchSmb.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchXhci.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PciTree.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Platform.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RTD3.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RhProxy.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/THERMAL.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/UsbSbd.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Video.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Vlv.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Wsmt/Wsmt.aslc
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/token.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Guid/Vlv2DeviceRefCodePkgTo
> kenSpace.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/PttPassThruPpi.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/fTPMPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Protocol/PttPassThru.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Guid/Po
> werManagementAcpiTableStorage.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Ppi/VlvP
> olicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Protocol/
> PpmPlatformPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Types.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/PowerManagementAcpiTables.inf
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/Ssdt/ApCst.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/Ssdt/ApIst.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/Ssdt/ApTst.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/Ssdt/Cpu0Cst.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/Ssdt/Cpu0Ist.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/Ssdt/Cpu0Tst.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/Ssdt/CpuPm.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> PlatformBaseAddresses.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Ppi/Capsule.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Ppi/PlatformMemoryRange.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Ppi/PlatformMemorySize.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Ppi/SmmAccess.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Ppi/VlvMmioPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Ppi/VlvPeiInit.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Ppi/VlvPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Protocol/IgdOpRegion.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Protocol/MemInfo.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Protocol/PlatformGopPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Protocol/VlvPlatformPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Valleyview.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> VlvAccess.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> VlvCommonDefinitions.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Guid/PchInitVar.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Guid/SataControllerGuid.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Guid/SmbusArpMap.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Guid/Vlv2Variable.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/I
> ndustryStandard/CeAta.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/I
> ndustryStandard/Mmc.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/I
> ndustryStandard/SdCard.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/L
> ibrary/I2CLib.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/L
> ibrary/PchPlatformLib.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchAccess.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchCommonDefinitions.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchRegs.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchRegs/PchRegsHda.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchRegs/PchRegsLpss.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchRegs/PchRegsPcie.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchRegs/PchRegsPcu.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchRegs/PchRegsRcrb.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchRegs/PchRegsSata.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchRegs/PchRegsScc.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchRegs/PchRegsSmbus.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchRegs/PchRegsSpi.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchRegs/PchRegsUsb.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Ppi/PchInit.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Ppi/PchPeiInit.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Ppi/PchPlatformPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Ppi/PchUsbPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Ppi/PeiBlockIo.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Ppi/Sdhc.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Ppi/SmbusPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Ppi/Spi.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/ActiveBios.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/ActiveBiosProtocol.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/DxePchPolicyUpdateProtocol.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/EmmcCardInfoProtocol.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/Gpio.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/HwWatchdogTimer.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/I2cBus.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/PchExtendedReset.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/PchInfo.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/PchPlatformPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/PchReset.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/PchS3Support.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/SdHostIo.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/SmbiosSlotPopulation.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/SmmIchnDispatchEx.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/SmmSmbus.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/Spi.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/TcoReset.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Rsci.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> TianoApi.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> 
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/98_LINK.ASL
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/98_LINK.ASL
> new file mode 100644
> index 0000000000..50ebaffc34
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/98_LINK.ASL
> @@ -0,0 +1,617 @@
> +/*********************************************************
> *****************;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
> +;*    Family of Customer Reference Boards.                                *;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Copyright (c)  2012  - 2014, Intel Corporation. All rights reserved   *;
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*********************************************************
> *****************/
> +
> +
> +
> +// Use this information when determining the Possible IRQs that can be
> +// used in a given system.
> +//
> +// The following IRQs are always in use by legacy devices:
> +//              0  = System Timer
> +//              2  = 8259 PIC
> +//              8  = RTC
> +//              9  = SCI Interrupt (It may be used, we choose not to)
> +//              13 = Co-processor Error
> +//
> +// The following may be in use by legacy devices:
> +//              1  = If using PS/2 Keyboard
> +//              3  = If COMx Port Enabled and IRQ = 3
> +//              4  = If COMx Port Enabled and IRQ = 4
> +//              5  = If LPT Port Enabled and IRQ = 5
> +//              6  = If FDC Enabled
> +//              7  = If LPT Port Enabled and IRQ = 7
> +//              12 = If using PS/2 Mouse
> +//              14 = Primary IDE (If populated and in Compatibility Mode)
> +//              15 = Secondary IDE (If populated and in Compatibility Mode)
> +//
> +// The following will never be in use by legacy devices:
> +//              10 = Assign to PARC, PCRC, PERC, PGRC
> +//              11 = Assign to PBRC, PDRC, PFRC, PHRC
> +
> +Device(LNKA)                            // PARC Routing Resource
> +{
> +  Name(_HID,EISAID("PNP0C0F"))    // PCI Interrupt Link Device
> +
> +  Name(_UID,1)                    // Unique to other Link Devices
> +
> +  // Disable the PCI IRQ.
> +
> +  Method(_DIS,0,Serialized)
> +  {
> +    Or(PARC,0x80,PARC)
> +  }
> +
> +  // Possible IRQ Resource Setting.
> +
> +  Method (_PRS, 0, Serialized)
> +  {
> +    return (PRSA)
> +  }
> +
> +  // Current IRQ Resource Setting.
> +
> +  Method(_CRS,0,Serialized)
> +  {
> +    Name(RTLA,ResourceTemplate()
> +    {
> +      IRQ(Level,ActiveLow,Shared) {}
> +    })
> +
> +    // Point to specific byte.
> +
> +    CreateWordField(RTLA,1,IRQ0)
> +
> +    // Zero out IRQ mask bits 0-15
> +
> +    Store(Zero,IRQ0)
> +
> +    ShiftLeft(1,And(PARC,0x0F),IRQ0)
> +
> +    Return(RTLA)
> +  }
> +
> +  // Set IRQ Resource Setting.
> +
> +  Method(_SRS,1,Serialized)
> +  {
> +    // Point to the specific byte passed in
> +
> +    CreateWordField(Arg0,1,IRQ0)
> +
> +    // Determine the IRQ bit to set and store it
> +
> +    FindSetRightBit(IRQ0,Local0)
> +    Decrement(Local0)
> +    Store(Local0,PARC)
> +  }
> +
> +  // PCI IRQ Status.
> +
> +  Method(_STA,0,Serialized)
> +  {
> +    If(And(PARC,0x80))
> +    {
> +      Return(0x0009)
> +    }
> +    Else
> +    {
> +      Return(0x000B)
> +    }
> +  }
> +}
> +
> +Device(LNKB)                            // PBRC Routing Resource
> +{
> +  Name(_HID,EISAID("PNP0C0F"))
> +
> +  Name(_UID,2)
> +
> +  // Disable the PCI IRQ.
> +
> +  Method(_DIS,0,Serialized)
> +  {
> +    Or(PBRC,0x80,PBRC)
> +  }
> +
> +  // Possible IRQ Resource Setting.
> +
> +  Method (_PRS, 0, Serialized)
> +  {
> +    return (PRSB)
> +  }
> +
> +  // Current IRQ Resource Setting.
> +
> +  Method(_CRS,0,Serialized)
> +  {
> +    Name(RTLB,ResourceTemplate()
> +    {
> +      IRQ(Level,ActiveLow,Shared) {}
> +    })
> +
> +    // Point to specific byte.
> +
> +    CreateWordField(RTLB,1,IRQ0)
> +
> +    // Zero out IRQ mask bits 0-15
> +
> +    Store(Zero,IRQ0)
> +
> +    ShiftLeft(1,And(PBRC,0x0F),IRQ0)
> +
> +    Return(RTLB)
> +  }
> +
> +  // Set IRQ Resource Setting.
> +
> +  Method(_SRS,1,Serialized)
> +  {
> +    // Point to the specific byte passed in.
> +
> +    CreateWordField(Arg0,1,IRQ0)
> +
> +    // Determine the IRQ bit to set and store it,
> +
> +    FindSetRightBit(IRQ0,Local0)
> +    Decrement(Local0)
> +    Store(Local0,PBRC)
> +  }
> +
> +  // PCI IRQ Status.
> +
> +  Method(_STA,0,Serialized)
> +  {
> +    If(And(PBRC,0x80))
> +    {
> +      Return(0x0009)
> +    }
> +    Else
> +    {
> +      Return(0x000B)
> +    }
> +  }
> +}
> +
> +Device(LNKC)                            // PCRC Routing Resource
> +{
> +  Name(_HID,EISAID("PNP0C0F"))
> +
> +  Name(_UID,3)
> +
> +  // Disable the PCI IRQ.
> +
> +  Method(_DIS,0,Serialized)
> +  {
> +    Or(PCRC,0x80,PCRC)
> +  }
> +
> +  // Possible IRQ Resource Setting.
> +
> +  Method (_PRS, 0, Serialized)
> +  {
> +    return (PRSC)
> +  }
> +
> +  // Current IRQ Resource Setting.
> +
> +  Method(_CRS,0,Serialized)
> +  {
> +    Name(RTLC,ResourceTemplate()
> +    {
> +      IRQ(Level,ActiveLow,Shared) {}
> +    })
> +
> +    // Point to specific byte.
> +
> +    CreateWordField(RTLC,1,IRQ0)
> +
> +    // Zero out IRQ mask bits 0-15
> +
> +    Store(Zero,IRQ0)
> +
> +    ShiftLeft(1,And(PCRC,0x0F),IRQ0)
> +
> +    Return(RTLC)
> +  }
> +
> +  // Set IRQ Resource Setting.
> +
> +  Method(_SRS,1,Serialized)
> +  {
> +    // Point to the specific byte passed in.
> +
> +    CreateWordField(Arg0,1,IRQ0)
> +
> +    // Determine the IRQ bit to set and store it,
> +
> +    FindSetRightBit(IRQ0,Local0)
> +    Decrement(Local0)
> +    Store(Local0,PCRC)
> +  }
> +
> +  // PCI IRQ Status.
> +
> +  Method(_STA,0,Serialized)
> +  {
> +    If(And(PCRC,0x80))
> +    {
> +      Return(0x0009)
> +    }
> +    Else
> +    {
> +      Return(0x000B)
> +    }
> +  }
> +}
> +
> +Device(LNKD)                            // PDRC Routing Resource
> +{
> +  Name(_HID,EISAID("PNP0C0F"))
> +
> +  Name(_UID,4)
> +
> +  // Disable the PCI IRQ.
> +
> +  Method(_DIS,0,Serialized)
> +  {
> +    Or(PDRC,0x80,PDRC)
> +  }
> +
> +  // Possible IRQ Resource Setting.
> +
> +  Method (_PRS, 0, Serialized)
> +  {
> +    return (PRSD)
> +  }
> +
> +  // Current IRQ Resource Setting.
> +
> +  Method(_CRS,0,Serialized)
> +  {
> +    Name(RTLD,ResourceTemplate()
> +    {
> +      IRQ(Level,ActiveLow,Shared) {}
> +    })
> +
> +    // Point to specific byte.
> +
> +    CreateWordField(RTLD,1,IRQ0)
> +
> +    // Zero out IRQ mask bits 0-15
> +
> +    Store(Zero,IRQ0)
> +
> +    ShiftLeft(1,And(PDRC,0x0F),IRQ0)
> +
> +    Return(RTLD)
> +  }
> +
> +  // Set IRQ Resource Setting.
> +
> +  Method(_SRS,1,Serialized)
> +  {
> +    // Point to the specific byte passed in.
> +
> +    CreateWordField(Arg0,1,IRQ0)
> +
> +    // Determine the IRQ bit to set and store it,
> +
> +    FindSetRightBit(IRQ0,Local0)
> +    Decrement(Local0)
> +    Store(Local0,PDRC)
> +  }
> +
> +  // PCI IRQ Status.
> +
> +  Method(_STA,0,Serialized)
> +  {
> +    If(And(PDRC,0x80))
> +    {
> +      Return(0x0009)
> +    }
> +    Else
> +    {
> +      Return(0x000B)
> +    }
> +  }
> +}
> +
> +Device(LNKE)                            // PERC Routing Resource
> +{
> +  Name(_HID,EISAID("PNP0C0F"))
> +
> +  Name(_UID,5)
> +
> +  // Disable the PCI IRQ.
> +
> +  Method(_DIS,0,Serialized)
> +  {
> +    Or(PERC,0x80,PERC)
> +  }
> +
> +  // Possible IRQ Resource Setting.
> +
> +  Method (_PRS, 0, Serialized)
> +  {
> +    return (PRSE)
> +  }
> +
> +  // Current IRQ Resource Setting.
> +
> +  Method(_CRS,0,Serialized)
> +  {
> +    Name(RTLE,ResourceTemplate()
> +    {
> +      IRQ(Level,ActiveLow,Shared) {}
> +    })
> +
> +    // Point to specific byte.
> +
> +    CreateWordField(RTLE,1,IRQ0)
> +
> +    // Zero out IRQ mask bits 0-15
> +
> +    Store(Zero,IRQ0)
> +
> +    ShiftLeft(1,And(PERC,0x0F),IRQ0)
> +
> +    Return(RTLE)
> +  }
> +
> +  // Set IRQ Resource Setting.
> +
> +  Method(_SRS,1,Serialized)
> +  {
> +    // Point to the specific byte passed in
> +
> +    CreateWordField(Arg0,1,IRQ0)
> +
> +    // Determine the IRQ bit to set and store it
> +
> +    FindSetRightBit(IRQ0,Local0)
> +    Decrement(Local0)
> +    Store(Local0,PERC)
> +  }
> +
> +  // PCI IRQ Status.
> +
> +  Method(_STA,0,Serialized)
> +  {
> +    If(And(PERC,0x80))
> +    {
> +      Return(0x0009)
> +    }
> +    Else
> +    {
> +      Return(0x000B)
> +    }
> +  }
> +}
> +
> +Device(LNKF)                            // PFRC Routing Resource
> +{
> +  Name(_HID,EISAID("PNP0C0F"))
> +
> +  Name(_UID,6)
> +
> +  // Disable the PCI IRQ.
> +
> +  Method(_DIS,0,Serialized)
> +  {
> +    Or(PFRC,0x80,PFRC)
> +  }
> +
> +  // Possible IRQ Resource Setting.
> +
> +  Method (_PRS, 0, Serialized)
> +  {
> +    return (PRSF)
> +  }
> +
> +  // Current IRQ Resource Setting.
> +
> +  Method(_CRS,0,Serialized)
> +  {
> +    Name(RTLF,ResourceTemplate()
> +    {
> +      IRQ(Level,ActiveLow,Shared) {}
> +    })
> +
> +    // Point to specific byte.
> +
> +    CreateWordField(RTLF,1,IRQ0)
> +
> +    // Zero out IRQ mask bits 0-15
> +
> +    Store(Zero,IRQ0)
> +
> +    ShiftLeft(1,And(PFRC,0x0F),IRQ0)
> +
> +    Return(RTLF)
> +  }
> +
> +  // Set IRQ Resource Setting.
> +
> +  Method(_SRS,1,Serialized)
> +  {
> +    // Point to the specific byte passed in.
> +
> +    CreateWordField(Arg0,1,IRQ0)
> +
> +    // Determine the IRQ bit to set and store it,
> +
> +    FindSetRightBit(IRQ0,Local0)
> +    Decrement(Local0)
> +    Store(Local0,PFRC)
> +  }
> +
> +  // PCI IRQ Status.
> +
> +  Method(_STA,0,Serialized)
> +  {
> +    If(And(PFRC,0x80))
> +    {
> +      Return(0x0009)
> +    }
> +    Else
> +    {
> +      Return(0x000B)
> +    }
> +  }
> +}
> +
> +Device(LNKG)                            // PGRC Routing Resource
> +{
> +  Name(_HID,EISAID("PNP0C0F"))
> +
> +  Name(_UID,7)
> +
> +  // Disable the PCI IRQ.
> +
> +  Method(_DIS,0,Serialized)
> +  {
> +    Or(PGRC,0x80,PGRC)
> +  }
> +
> +  // Possible IRQ Resource Setting.
> +
> +  Method (_PRS, 0, Serialized)
> +  {
> +    return (PRSG)
> +  }
> +
> +  // Current IRQ Resource Setting.
> +
> +  Method(_CRS,0,Serialized)
> +  {
> +    Name(RTLG,ResourceTemplate()
> +    {
> +      IRQ(Level,ActiveLow,Shared) {}
> +    })
> +
> +    // Point to specific byte.
> +
> +    CreateWordField(RTLG,1,IRQ0)
> +
> +    // Zero out IRQ mask bits 0-15
> +
> +    Store(Zero,IRQ0)
> +
> +    ShiftLeft(1,And(PGRC,0x0F),IRQ0)
> +
> +    Return(RTLG)
> +  }
> +
> +  // Set IRQ Resource Setting.
> +
> +  Method(_SRS,1,Serialized)
> +  {
> +    // Point to the specific byte passed in.
> +
> +    CreateWordField(Arg0,1,IRQ0)
> +
> +    // Determine the IRQ bit to set and store it,
> +
> +    FindSetRightBit(IRQ0,Local0)
> +    Decrement(Local0)
> +    Store(Local0,PGRC)
> +  }
> +
> +  // PCI IRQ Status.
> +
> +  Method(_STA,0,Serialized)
> +  {
> +    If(And(PGRC,0x80))
> +    {
> +      Return(0x0009)
> +    }
> +    Else
> +    {
> +      Return(0x000B)
> +    }
> +  }
> +}
> +
> +Device(LNKH)                            // PHRC Routing Resource
> +{
> +  Name(_HID,EISAID("PNP0C0F"))
> +
> +  Name(_UID,8)
> +
> +  // Disable the PCI IRQ.
> +
> +  Method(_DIS,0,Serialized)
> +  {
> +    Or(PHRC,0x80,PHRC)
> +  }
> +
> +  // Possible IRQ Resource Setting.
> +
> +  Method (_PRS, 0, Serialized)
> +  {
> +    return (PRSH)
> +  }
> +
> +  // Current IRQ Resource Setting.
> +
> +  Method(_CRS,0,Serialized)
> +  {
> +    Name(RTLH,ResourceTemplate()
> +    {
> +      IRQ(Level,ActiveLow,Shared) {}
> +    })
> +
> +    // Point to specific byte.
> +
> +    CreateWordField(RTLH,1,IRQ0)
> +
> +    // Zero out IRQ mask bits 0-15
> +
> +    Store(Zero,IRQ0)
> +
> +    ShiftLeft(1,And(PHRC,0x0F),IRQ0)
> +
> +    Return(RTLH)
> +  }
> +
> +  // Set IRQ Resource Setting.
> +
> +  Method(_SRS,1,Serialized)
> +  {
> +    // Point to the specific byte passed in.
> +
> +    CreateWordField(Arg0,1,IRQ0)
> +
> +    // Determine the IRQ bit to set and store it,
> +
> +    FindSetRightBit(IRQ0,Local0)
> +    Decrement(Local0)
> +    Store(Local0,PHRC)
> +  }
> +
> +  // PCI IRQ Status.
> +
> +  Method(_STA,0,Serialized)
> +  {
> +    If(And(PHRC,0x80))
> +    {
> +      Return(0x0009)
> +    }
> +    Else
> +    {
> +      Return(0x000B)
> +    }
> +  }
> +}
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTablePlatform.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTablePlatform.h
> new file mode 100644
> index 0000000000..b3a7cba106
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTablePlatform.h
> @@ -0,0 +1,70 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  AcpiTablePlatform.h
> +
> +
> +Abstract: File contains platform specific ACPI defines for use in ACPI tables
> +
> +
> +--*/
> +#ifndef _Platform_h_INCLUDED_
> +#define _Platform_h_INCLUDED_
> +
> +#ifdef ECP_FLAG
> +#include "EdkIIGlueDxe.h"
> +#endif
> +#include <IndustryStandard/Acpi.h>
> +//
> +// ACPI table information used to initialize tables.
> +//
> +#define EFI_ACPI_OEM_ID           'O','E','M','I','D',' '   // OEMID 6 bytes long
> +#define EFI_ACPI_OEM_TABLE_ID
> SIGNATURE_64('O','E','M','T','A','B','L','E') // OEM table id 8 bytes long
> +#define EFI_ACPI_OEM_REVISION     0x00000005
> +#define EFI_ACPI_CREATOR_ID       SIGNATURE_32('C','R','E','A')
> +#define EFI_ACPI_CREATOR_REVISION 0x0100000D
> +#define INT_MODEL       0x01
> +#define PM_PROFILE      EFI_ACPI_4_0_PM_PROFILE_MOBILE
> +#define SCI_INT_VECTOR  0x0009
> +#define SMI_CMD_IO_PORT 0x000000B2
> +#define ACPI_ENABLE     0x0A0
> +#define ACPI_DISABLE    0x0A1
> +#define S4BIOS_REQ      0x00
> +#define PSTATE_CNT      0x00
> +#define PM1a_EVT_BLK    0x00000400
> +#define PM1b_EVT_BLK    0x00000000
> +#define PM1a_CNT_BLK    0x00000404
> +#define PM1b_CNT_BLK    0x00000000
> +#define PM2_CNT_BLK     0x00000450
> +#define PM_TMR_BLK      0x00000408
> +#define GPE0_BLK        0x00000420
> +#define GPE1_BLK        0x00000000
> +#define PM1_EVT_LEN     0x04
> +#define PM1_CNT_LEN     0x02
> +#define PM2_CNT_LEN     0x01
> +#define PM_TM_LEN       0x04
> +#define GPE0_BLK_LEN    0x10
> +#define GPE1_BLK_LEN    0x00
> +#define GPE1_BASE       0x00
> +#define CST_CNT         0x00
> +#define P_LVL2_LAT      0x0064
> +#define P_LVL3_LAT      0x01F4
> +#define FLUSH_SIZE      0x0400
> +#define FLUSH_STRIDE    0x0010
> +#define DUTY_OFFSET     0x01
> +#define DUTY_WIDTH      0x03
> +#define DAY_ALRM        0x0D
> +#define MON_ALRM        0x00
> +#define CENTURY         0x32
> +#define FLAG            ( EFI_ACPI_4_0_WBINVD | EFI_ACPI_4_0_SLP_BUTTON
> | EFI_ACPI_4_0_RESET_REG_SUP | EFI_ACPI_4_0_RTC_S4)
> +#define IAPC_BOOT_ARCH  ( EFI_ACPI_4_0_VGA_NOT_PRESENT |
> EFI_ACPI_4_0_8042 | EFI_ACPI_4_0_LEGACY_DEVICES)
> +#define RESERVED        0x00
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTables.inf
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTables.inf
> new file mode 100644
> index 0000000000..170598df7f
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTables.inf
> @@ -0,0 +1,40 @@
> +## @file
> +# Component description file for PlatformAcpiTable module.
> +#
> +# Build acpi table data required by system boot.
> +#  All .asi files tagged with "ToolCode="DUMMY"" in following file list are
> device description and are included
> +#  by top level ASL file which will be dealed with by asl.exe application.
> +#
> +# Copyright (c)  1999  - 2016, Intel Corporation. All rights reserved
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +#
> +##
> +
> +[defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = AcpiTables
> +  FILE_GUID                      = 7E374E25-8E01-4FEE-87F2-390C23C606CD
> +  MODULE_TYPE                    = USER_DEFINED
> +  VERSION_STRING                 = 1.0
> +  EDK_RELEASE_VERSION            = 0x00020000
> +  EFI_SPECIFICATION_VERSION      = 0x00020000
> +
> +[sources.common]
> +  DSDT.ASL
> +  RhProxy.asl
> +  Facs/Facs.aslc
> +  Facp/Facp.aslc
> +  Madt/Madt30.aslc
> +  Mcfg/Mcfg.aslc
> +  Hpet/Hpet.aslc
> +  Lpit/Lpit.aslc
> +  Wsmt/Wsmt.aslc
> +
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/CPU.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/CPU.asl
> new file mode 100644
> index 0000000000..8449ed0d55
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/CPU.asl
> @@ -0,0 +1,49 @@
> +/*********************************************************
> *****************;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
> +;*    Family of Customer Reference Boards.                                *;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved   *;
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*********************************************************
> *****************/
> +
> +
> +
> +// NOTE:  The _PDC Implementation is out of the scope of this
> +// reference code.  Please see the latest Hyper-Threading Technology
> +// Reference Code for complete implementation details.
> +
> +Scope(\_PR)
> +{
> +  Processor(CPU0,         // Unique name for Processor 0.
> +            1,                        // Unique ID for Processor 0.
> +            0x00,                 // CPU0 ACPI P_BLK address = ACPIBASE + 10h.
> +            0)                        // CPU0  P_BLK length = 6 bytes.
> +  {}
> +
> +  Processor(CPU1,         // Unique name for Processor 1.
> +            2,                        // Unique ID for Processor 1.
> +            0x00,
> +            0)                    // CPU1 P_BLK length = 6 bytes.
> +  {}
> +
> +  Processor(CPU2,         // Unique name for Processor 2.
> +            3,                        // Unique ID for Processor 2.
> +            0x00,
> +            0)                    // CPU2 P_BLK length = 6 bytes.
> +  {}
> +
> +  Processor(CPU3,         // Unique name for Processor 3.
> +            4,                        // Unique ID for Processor 3.
> +            0x00,
> +            0)                    // CPU3 P_BLK length = 6 bytes.
> +  {}
> +}     // End _PR
> +
> +
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/DSDT.ASL
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/DSDT.ASL
> new file mode 100644
> index 0000000000..cbf0d302b1
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/DSDT.ASL
> @@ -0,0 +1,75 @@
> +/*********************************************************
> *****************;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Intel Corporation - ACPI Reference Code for the Sandy Bridge        *;
> +;*    Family of Customer Reference Boards.                                *;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Copyright (c) 2012  - 2015, Intel Corporation. All rights reserved    *;
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*********************************************************
> *****************/
> +
> +DefinitionBlock (
> +  "DSDT.aml",
> +  "DSDT",
> +  0x02,  // DSDT revision.
> +  "OEMID", // OEM ID (6 byte string)
> +  "VLV-SOC", // OEM table ID  (8 byte string)
> +  0x0 // OEM version of DSDT table (4 byte Integer)
> +)
> +
> +// BEGIN OF ASL SCOPE
> +{
> +  External(MDBG, MethodObj)
> +
> +  Method(ADBG, 1, Serialized)
> +  {
> +
> +    If(CondRefOf(MDBG))   //check if SSDT is loaded
> +    {
> +      Return(MDBG(Arg0))
> +    }
> +
> +    Return(0)
> +  }
> +
> +
> +// Miscellaneous services enabled in Project
> +  include ("token.asl")
> +  include ("GloblNvs.asl")
> +  include ("PciTree.asl")
> +  include ("Pch.asl")
> +  include ("Vlv.asl")
> +  include ("CPU.asl")
> +  include ("Platform.asl")
> +  include ("THERMAL.ASL")
> +  include ("PCI_DRC.ASL")
> +  include ("Video.asl")
> +  include ("Gpe.asl")
> +  //include ("IoTVirtualDevice.asl")
> +
> +  // Sleep states supported by Chipset/Board.
> +  // SSx - BIOS setup controlled enabled _Sx Sleep state status
> +  // Values to be written to SLP_TYPE register are provided by SBACPI.SDL
> (South Bridge ACPI ModulePart)
> +
> +  Name(\_S0, Package(4) {0x0,0x0,0,0}) // mandatory System state
> +  Name(\_S1, Package(4) {0x1,0x0,0,0})
> +  Name(\_S3, Package(4) {0x5,0x0,0,0})
> +  Name(\_S4, Package(4) {0x6,0x0,0,0})
> +  Name(\_S5, Package(4) {0x7,0x0,0,0}) // mandatory System state
> +
> +  Method(PTS, 1)          // METHOD CALLED FROM _PTS PRIOR TO ENTER ANY
> SLEEP STATE
> +  {
> +    If(Arg0)            // entering any sleep state
> +    {
> +    }
> +  }
> +  Method(WAK, 1)          // METHOD CALLED FROM _WAK RIGHT AFTER WAKE
> UP
> +  {
> +  }
> +
> +}// End of ASL File
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facp/Facp.aslc
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facp/Facp.aslc
> new file mode 100644
> index 0000000000..df47144623
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facp/Facp.aslc
> @@ -0,0 +1,188 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  Facp.c
> +
> +
> +Abstract: The fixed ACPI description Table (FADT) Structure
> +
> +
> +--*/
> +#ifdef ECP_FLAG
> +#include "EDKIIGlueDxe.h"
> +#else
> +#include <PiDxe.h>
> +#endif
> +#include <IndustryStandard/Acpi50.h>
> +#include "AcpiTablePlatform.h"
> +
> +EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE FACP = {
> +  {
> +    EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
> +    sizeof (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE),
> +    EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION,
> +    0,                                                                                    // to make sum of entire table
> == 0
> +    EFI_ACPI_OEM_ID,         // OEMID is a 6 bytes long field
> +    EFI_ACPI_OEM_TABLE_ID,      // OEM table identification(8 bytes long)
> +    EFI_ACPI_OEM_REVISION,      // OEM revision number
> +    EFI_ACPI_CREATOR_ID,        // ASL compiler vendor ID
> +    EFI_ACPI_CREATOR_REVISION   // ASL compiler revision number
> +  },
> +  0,                                                                                    // Physical addesss of FACS
> +  0,                                                                                    // Physical address of DSDT
> +  INT_MODEL,                                                                                    // System Interrupt
> Model (ignored in 2k and later, must be 0 for 98)
> +  PM_PROFILE,                                                                                   // Preferred PM
> Profile
> +  SCI_INT_VECTOR,                                                                       // System vector of
> SCI interrupt
> +  SMI_CMD_IO_PORT,                                                                      // Port address of
> SMI command port
> +  ACPI_ENABLE,                                                                          // value to write to port
> smi_cmd to enable ACPI
> +  ACPI_DISABLE,                                                                         // value to write to port
> smi_cmd to disable ACPI
> +  S4BIOS_REQ,                                                                           // Value to write to SMI
> CMD port to enter the S4BIOS state
> +  PSTATE_CNT,       // PState control
> +  PM1a_EVT_BLK,                                                                         // Port address of
> Power Mgt 1a Event Reg Blk
> +  PM1b_EVT_BLK,                                                                         // Port address of
> Power Mgt 1b Event Reg Blk
> +  PM1a_CNT_BLK,                                                                         // Port address of
> Power Mgt 1a Ctrl Reg Blk
> +  PM1b_CNT_BLK,                                                                         // Port address of
> Power Mgt 1b Ctrl Reg Blk
> +  PM2_CNT_BLK,                                                                          // Port address of
> Power Mgt 2  Ctrl Reg Blk
> +  PM_TMR_BLK,                                                                           // Port address of
> Power Mgt Timer Ctrl Reg Blk
> +  GPE0_BLK,                                                                             // Port addr of General
> Purpose Event 0 Reg Blk
> +  GPE1_BLK,                                                                             // Port addr of General
> Purpose Event 1 Reg Blk
> +  PM1_EVT_LEN,                                                                          // Byte Length of ports
> at pm1X_evt_blk
> +  PM1_CNT_LEN,                                                                          // Byte Length of
> ports at pm1X_cnt_blk
> +  PM2_CNT_LEN,                                                                          // Byte Length of
> ports at pm2_cnt_blk
> +  PM_TM_LEN,                                                                            // Byte Length of ports
> at pm_tm_blk
> +  GPE0_BLK_LEN,                                                                         // Byte Length of ports
> at gpe0_blk
> +  GPE1_BLK_LEN,                                                                         // Byte Length of ports
> at gpe1_blk
> +  GPE1_BASE,                                                                            // offset in gpe model
> where gpe1 events start
> +  CST_CNT,          // _CST support
> +  P_LVL2_LAT,                                                                           // worst case HW latency
> to enter/exit C2 state
> +  P_LVL3_LAT,                                                                           // worst case HW latency
> to enter/exit C3 state
> +  FLUSH_SIZE,                                                                           // Size of area read to
> flush caches
> +  FLUSH_STRIDE,                                                                         // Stride used in
> flushing caches
> +  DUTY_OFFSET,                                                                          // bit location of duty
> cycle field in p_cnt reg
> +  DUTY_WIDTH,                                                                           // bit width of duty
> cycle field in p_cnt reg
> +  DAY_ALRM,                                                                             // index to day-of-
> month alarm in RTC CMOS RAM
> +  MON_ALRM,                                                                             // index to month-of-
> year alarm in RTC CMOS RAM
> +  CENTURY,                                                                              // index to century in RTC
> CMOS RAM
> +  IAPC_BOOT_ARCH,                                                                       // IA-PCI Boot
> Architecture Flag
> +  RESERVED,                                                                             // reserved
> +  FLAG,
> +  {
> +    EFI_ACPI_5_0_SYSTEM_IO,
> +    8,
> +    0,
> +    0,
> +    0xCF9
> +  },
> +  0x0E,             // Hardware reset value
> +  0, 0, 0,          // Reserved
> +  0,                // XFirmwareCtrl
> +  0,                // XDsdt
> +  //
> +  // X_PM1a Event Register Block
> +  //
> +  EFI_ACPI_5_0_SYSTEM_IO,
> +  0x20,
> +  0x00,
> +  EFI_ACPI_3_0_DWORD,
> +  PM1a_EVT_BLK,
> +
> +  //
> +  // X_PM1b Event Register Block
> +  //
> +  EFI_ACPI_5_0_SYSTEM_IO,
> +  0x00,
> +  0x00,
> +  EFI_ACPI_RESERVED_BYTE,
> +  PM1b_EVT_BLK,
> +
> +  //
> +  // X_PM1a Control Register Block
> +  //
> +  EFI_ACPI_5_0_SYSTEM_IO,
> +  0x10,
> +  0x00,
> +  EFI_ACPI_3_0_WORD,
> +  PM1a_CNT_BLK,
> +
> +  //
> +  // X_PM1b Control Register Block
> +  //
> +  EFI_ACPI_5_0_SYSTEM_IO,
> +  0x00,
> +  0x00,
> +  EFI_ACPI_RESERVED_BYTE,
> +  PM1b_CNT_BLK,
> +
> +  //
> +  // X_PM2 Control Register Block
> +  //
> +  EFI_ACPI_5_0_SYSTEM_IO,
> +  0x08,
> +  0x00,
> +  EFI_ACPI_3_0_BYTE,
> +  PM2_CNT_BLK,
> +
> +  //
> +  // X_PM Timer Control Register Block
> +  //
> +  EFI_ACPI_5_0_SYSTEM_IO,
> +  0x20,
> +  0x00,
> +  EFI_ACPI_3_0_DWORD,
> +  PM_TMR_BLK,
> +
> +  //
> +  // X_General Purpose Event 0 Register Block
> +  //
> +  EFI_ACPI_5_0_SYSTEM_IO,
> +  0x80,
> +  0x00,
> +  EFI_ACPI_RESERVED_BYTE,
> +  GPE0_BLK,
> +
> +  //
> +  // X_General Purpose Event 1 Register Block
> +  //
> +  EFI_ACPI_5_0_SYSTEM_IO,
> +  0x00,
> +  0x00,
> +  EFI_ACPI_RESERVED_BYTE,
> +  GPE1_BLK,
> +
> +  //
> +  // Sleep Control Register Block
> +  //
> +  EFI_ACPI_5_0_SYSTEM_IO,
> +  0x08,
> +  0x00,
> +  EFI_ACPI_RESERVED_BYTE,
> +  0,
> +
> +  //
> +  // Sleep Status Register Block
> +  //
> +  EFI_ACPI_5_0_SYSTEM_IO,
> +  0x08,
> +  0x00,
> +  EFI_ACPI_RESERVED_BYTE,
> +  0,
> +};
> +
> +VOID*
> +ReferenceAcpiTable (
> +  VOID
> +  )
> +{
> +  //
> +  // Reference the table being generated to prevent the optimizer from
> +  // removing the data structure from the executable
> +  //
> +  return (VOID*)&FACP;
> +}
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facs/Facs.aslc
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facs/Facs.aslc
> new file mode 100644
> index 0000000000..e216f61299
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facs/Facs.aslc
> @@ -0,0 +1,84 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  Ea815acpiFACS.c
> +
> +
> +Abstract:
> +
> +  This file contains the FACS structure definition.
> +
> +--*/
> +
> +//
> +// Statements that include other files
> +//
> +#ifdef ECP_FLAG
> +#include "EDKIIGlueDxe.h"
> +#else
> +#include <PiDxe.h>
> +#endif
> +#include <IndustryStandard/Acpi50.h>
> +#include "AcpiTablePlatform.h"
> +
> +EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE FACS = {
> +  EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE,
> +  sizeof (EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE),
> +
> +  //
> +  // Hardware Signature will be updated at runtime
> +  //
> +  0x00000000,                  //HardwareSignature
> +  0x00000000,                  //FirmwareWakingVector
> +  0x00000000,                  //GlobalLock
> +  0x00000000,                  //Flags
> +  0x0000000000000000,          //XFirmwareWakingVector
> +  EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION,
> +  EFI_ACPI_RESERVED_BYTE,      //Reserved0[3]
> +  EFI_ACPI_RESERVED_BYTE,
> +  EFI_ACPI_RESERVED_BYTE,
> +  0x00000000,                  //OspmFlags
> +  EFI_ACPI_RESERVED_BYTE,      //Reserved1[24]
> +  EFI_ACPI_RESERVED_BYTE,
> +  EFI_ACPI_RESERVED_BYTE,
> +  EFI_ACPI_RESERVED_BYTE,
> +  EFI_ACPI_RESERVED_BYTE,
> +  EFI_ACPI_RESERVED_BYTE,
> +  EFI_ACPI_RESERVED_BYTE,
> +  EFI_ACPI_RESERVED_BYTE,
> +  EFI_ACPI_RESERVED_BYTE,
> +  EFI_ACPI_RESERVED_BYTE,
> +  EFI_ACPI_RESERVED_BYTE,
> +  EFI_ACPI_RESERVED_BYTE,
> +  EFI_ACPI_RESERVED_BYTE,
> +  EFI_ACPI_RESERVED_BYTE,
> +  EFI_ACPI_RESERVED_BYTE,
> +  EFI_ACPI_RESERVED_BYTE,
> +  EFI_ACPI_RESERVED_BYTE,
> +  EFI_ACPI_RESERVED_BYTE,
> +  EFI_ACPI_RESERVED_BYTE,
> +  EFI_ACPI_RESERVED_BYTE,
> +  EFI_ACPI_RESERVED_BYTE,
> +  EFI_ACPI_RESERVED_BYTE,
> +  EFI_ACPI_RESERVED_BYTE,
> +  EFI_ACPI_RESERVED_BYTE
> +};
> +
> +VOID*
> +ReferenceAcpiTable (
> +  VOID
> +  )
> +{
> +  //
> +  // Reference the table being generated to prevent the optimizer from
> +  // removing the data structure from the executable
> +  //
> +  return (VOID*)&FACS;
> +}
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/GloblNvs.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/GloblNvs.asl
> new file mode 100644
> index 0000000000..513fa95e46
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/GloblNvs.asl
> @@ -0,0 +1,348 @@
> +/*********************************************************
> *****************;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
> +;*    Family of Customer Reference Boards.                                *;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Copyright (c)  1999  - 2016, Intel Corporation. All rights reserved   *;
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*********************************************************
> *****************/
> +
> +
> +
> +// Define a Global region of ACPI NVS Region that may be used for any
> +// type of implementation.  The starting offset and size will be fixed
> +// up by the System BIOS during POST.  Note that the Size must be a word
> +// in size to be fixed up correctly.
> +
> +OperationRegion(GNVS,SystemMemory,0xFFFF0000,0xAA55)
> +Field(GNVS,AnyAcc,Lock,Preserve)
> +{
> +  Offset(0),       // Miscellaneous Dynamic Registers:
> +  OSYS,   16,      //   (00) Operating System
> +      ,   8,       //   (02)
> +      ,   8,       //   (03)
> +      ,   8,       //   (04)
> +      ,   8,       //   (05)
> +      ,   8,       //   (06)
> +      ,   8,       //   (07)
> +      ,   8,       //   (08)
> +      ,   8,       //   (09)
> +      ,   8,       //   (10)
> +  P80D,   32,      //   (11) Port 80 Debug Port Value
> +  LIDS,   8,       //   (15) Lid State (Lid Open = 1)
> +      ,   8,       //   (16)
> +      ,   8,       //   (17)
> +  Offset(18),      // Thermal Policy Registers:
> +      ,   8,       //   (18)
> +      ,   8,       //   (19)
> +  ACTT,   8,       //   (20) Active Trip Point
> +  PSVT,   8,       //   (21) Passive Trip Point
> +  TC1V,   8,       //   (22) Passive Trip Point TC1 Value
> +  TC2V,   8,       //   (23) Passive Trip Point TC2 Value
> +  TSPV,   8,       //   (24) Passive Trip Point TSP Value
> +  CRTT,   8,       //   (25) Critical Trip Point
> +  DTSE,   8,       //   (26) Digital Thermal Sensor Enable
> +  DTS1,   8,       //   (27) Digital Thermal Sensor 1 Reading
> +  DTS2,   8,       //   (28) Digital Thermal Sensor 2 Reading
> +  DTSF,   8,       //   (29) DTS SMI Function Call
> +  Offset(30),      // Battery Support Registers:
> +      ,   8,       //   (30)
> +      ,   8,       //   (31)
> +      ,   8,       //   (32)
> +      ,   8,       //   (33)
> +      ,   8,       //   (34)
> +      ,   8,       //   (35)
> +      ,   8,       //   (36)
> +  Offset(40),      // CPU Identification Registers:
> +  APIC,   8,       //   (40) APIC Enabled by SBIOS (APIC Enabled = 1)
> +  MPEN,   8,       //   (41) Number of Logical Processors if MP Enabled != 0
> +      ,   8,       //   (42)
> +      ,   8,       //   (43)
> +      ,   8,       //   (44)
> +      ,   32,      //   (45)
> +  Offset(50),      // SIO CMOS Configuration Registers:
> +      ,   8,       //   (50)
> +      ,   8,       //   (51)
> +      ,   8,       //   (52)
> +      ,   8,       //   (53)
> +      ,   8,       //   (54)
> +      ,   8,       //   (55)
> +      ,   8,       //   (56)
> +      ,   8,       //   (57)
> +      ,   8,       //   (58)
> +  Offset(60),      // Internal Graphics Registers:
> +      ,   8,       //   (60)
> +      ,   8,       //   (61)
> +  CADL,   8,       //   (62) Current Attached Device List
> +      ,   8,       //   (63)
> +  CSTE,   16,      //   (64) Current Display State
> +  NSTE,   16,      //   (66) Next Display State
> +      ,   16,      //   (68)
> +  NDID,   8,       //   (70) Number of Valid Device IDs
> +  DID1,   32,      //   (71) Device ID 1
> +  DID2,   32,      //   (75) Device ID 2
> +  DID3,   32,      //   (79) Device ID 3
> +  DID4,   32,      //   (83) Device ID 4
> +  DID5,   32,      //   (87) Device ID 5
> +      ,   32,      //   (91)
> +      ,   8,       //   (95) Fifth byte of AKSV (mannufacturing mode)
> +  Offset(103),     // Backlight Control Registers:
> +      ,   8,       //   (103)
> +  BRTL,   8,       //   (104) Brightness Level Percentage
> +  Offset(105),     // Ambiant Light Sensor Registers:
> +      ,   8,       //   (105)
> +      ,   8,       //   (106)
> +  LLOW,   8,       //   (107) LUX Low Value
> +      ,   8,       //   (108)
> +  Offset(110),     // EMA Registers:
> +      ,   8,       //   (110)
> +      ,   16,      //   (111)
> +      ,   16,      //   (113)
> +  Offset(116),     // MEF Registers:
> +      ,   8,       //   (116) MEF Enable
> +  Offset(117),     // PCIe Dock:
> +      ,   8,       //   (117)
> +  Offset(120),     // TPM Registers:
> +      ,   8,       //   (120)
> +      ,   8,       //   (121)
> +      ,   8,       //   (122)
> +      ,   8,       //   (123)
> +      ,   32,      //   (124)
> +      ,   8,       //   (125)
> +      ,   8,       //   (129)
> +  Offset(130),     //
> +      ,   56,      //   (130)
> +      ,   56,      //   (137)
> +      ,   8,       //   (144)
> +      ,   56,      //   (145)
> +  Offset(170),     // IGD OpRegion/Software SCI base address
> +  ASLB,   32,      //   (170) IGD OpRegion base address
> +  Offset(174),     // IGD OpRegion/Software SCI shared data
> +  IBTT,   8,       //   (174) IGD Boot Display Device
> +  IPAT,   8,       //   (175) IGD Panel Type CMOs option
> +  ITVF,   8,       //   (176) IGD TV Format CMOS option
> +  ITVM,   8,       //   (177) IGD TV Minor Format CMOS option
> +  IPSC,   8,       //   (178) IGD Panel Scaling
> +  IBLC,   8,       //   (179) IGD BLC Configuration
> +  IBIA,   8,       //   (180) IGD BIA Configuration
> +  ISSC,   8,       //   (181) IGD SSC Configuration
> +  I409,   8,       //   (182) IGD 0409 Modified Settings Flag
> +  I509,   8,       //   (183) IGD 0509 Modified Settings Flag
> +  I609,   8,       //   (184) IGD 0609 Modified Settings Flag
> +  I709,   8,       //   (185) IGD 0709 Modified Settings Flag
> +  IDMM,   8,       //   (186) IGD DVMT Mode
> +  IDMS,   8,       //   (187) IGD DVMT Memory Size
> +  IF1E,   8,       //   (188) IGD Function 1 Enable
> +  HVCO,   8,       //   (189) HPLL VCO
> +  NXD1,   32,      //   (190) Next state DID1 for _DGS
> +  NXD2,   32,      //   (194) Next state DID2 for _DGS
> +  NXD3,   32,      //   (198) Next state DID3 for _DGS
> +  NXD4,   32,      //   (202) Next state DID4 for _DGS
> +  NXD5,   32,      //   (206) Next state DID5 for _DGS
> +  NXD6,   32,      //   (210) Next state DID6 for _DGS
> +  NXD7,   32,      //   (214) Next state DID7 for _DGS
> +  NXD8,   32,      //   (218) Next state DID8 for _DGS
> +  GSMI,   8,       //   (222) GMCH SMI/SCI mode (0=SCI)
> +  PAVP,   8,       //   (223) IGD PAVP data
> +  Offset(225),
> +  OSCC,   8,       //   (225) PCIE OSC Control
> +  NEXP,   8,       //   (226) Native PCIE Setup Value
> +  Offset(235), // Global Variables
> +  DSEN,   8,       //   (235) _DOS Display Support Flag.
> +  ECON,   8,       //   (236) Embedded Controller Availability Flag.
> +  GPIC,   8,       //   (237) Global IOAPIC/8259 Interrupt Mode Flag.
> +  CTYP,   8,       //   (238) Global Cooling Type Flag.
> +  L01C,   8,       //   (239) Global L01 Counter.
> +  VFN0,   8,       //   (240) Virtual Fan0 Status.
> +  VFN1,   8,       //   (241) Virtual Fan1 Status.
> +  Offset(256),
> +  NVGA,   32,  //   (256) NVIG opregion address
> +  NVHA,   32,  //   (260) NVHM opregion address
> +  AMDA,   32,  //   (264) AMDA opregion address
> +  DID6,   32,  //   (268) Device ID 6
> +  DID7,   32,  //   (272) Device ID 7
> +  DID8,   32,  //   (276) Device ID 8
> +  Offset(332),
> +  USEL,   8,    // (332) UART Selection
> +  PU1E,   8,    // (333) PCU UART 1 Enabled
> +  PU2E,   8,    // (334) PCU UART 2 Enabled
> +
> +  LPE0, 32,     // (335) LPE Bar0
> +  LPE1, 32,     // (339) LPE Bar1
> +  LPE2, 32,     // (343) LPE Bar2
> +
> +  Offset(347),
> +      ,   8,    // (347)
> +      ,   8,    // (348)
> +  PFLV,   8,    // (349) Platform Flavor
> +
> +  Offset(351),
> +  ICNF,   8,   //   (351) ISCT / AOAC Configuration
> +  XHCI,   8,   //   (352) xHCI controller mode
> +  PMEN,   8,   //   (353) PMIC enable/disable
> +
> +  LPEE,   8,   //   (354) LPE enable/disable
> +  ISPA,   32,  //   (355) ISP Base Addr
> +  ISPD,   8,    //  (359) ISP Device Selection 0: Disabled; 1: PCI Device 2; 2: PCI
> Device 3
> +
> +  offset(360),  // ((4+8+6)*4+2)*4=296
> +  //
> +  // Lpss controllers
> +  //
> +  PCIB,     32,
> +  PCIT,     32,
> +  D10A,     32,  //DMA1
> +  D10L,     32,
> +  D11A,     32,
> +  D11L,     32,
> +  P10A,     32,  //  PWM1
> +  P10L,     32,
> +  P11A,     32,
> +  P11L,     32,
> +  P20A,     32,  //  PWM2
> +  P20L,     32,
> +  P21A,     32,
> +  P21L,     32,
> +  U10A,     32,  // UART1
> +  U10L,     32,
> +  U11A,     32,
> +  U11L,     32,
> +  U20A,     32,  // UART2
> +  U20L,     32,
> +  U21A,     32,
> +  U21L,     32,
> +  SP0A,     32,  // SPI
> +  SP0L,     32,
> +  SP1A,     32,
> +  SP1L,     32,
> +
> +  D20A,     32,  //DMA2
> +  D20L,     32,
> +  D21A,     32,
> +  D21L,     32,
> +  I10A,     32,  //  I2C1
> +  I10L,     32,
> +  I11A,     32,
> +  I11L,     32,
> +  I20A,     32,  //  I2C2
> +  I20L,     32,
> +  I21A,     32,
> +  I21L,     32,
> +  I30A,     32,  //  I2C3
> +  I30L,     32,
> +  I31A,     32,
> +  I31L,     32,
> +  I40A,     32,  //  I2C4
> +  I40L,     32,
> +  I41A,     32,
> +  I41L,     32,
> +  I50A,     32,  //  I2C5
> +  I50L,     32,
> +  I51A,     32,
> +  I51L,     32,
> +  I60A,     32,  //  I2C6
> +  I60L,     32,
> +  I61A,     32,
> +  I61L,     32,
> +  I70A,     32,  //  I2C7
> +  I70L,     32,
> +  I71A,     32,
> +  I71L,     32,
> +  //
> +  // Scc controllers
> +  //
> +  eM0A,     32,  //  EMMC
> +  eM0L,     32,
> +  eM1A,     32,
> +  eM1L,     32,
> +  SI0A,     32,  //  SDIO
> +  SI0L,     32,
> +  SI1A,     32,
> +  SI1L,     32,
> +  SD0A,     32,  //  SDCard
> +  SD0L,     32,
> +  SD1A,     32,
> +  SD1L,     32,
> +  MH0A,     32,  //
> +  MH0L,     32,
> +  MH1A,     32,
> +  MH1L,     32,
> +
> +  offset(656),
> +  SDRM,     8,
> +  offset(657),
> +  HLPS,     8,   //(657) Hide Devices
> +  offset(658),
> +  OSEL,     8,      //(658) OS Seletion - Windows/Android
> +
> +  offset(659),  // VLV1 DPTF
> +  SDP1,     8,      //(659) An enumerated value corresponding to SKU
> +  DPTE,     8,      //(660) DPTF Enable
> +  THM0,     8,      //(661) System Thermal 0
> +  THM1,     8,      //(662) System Thermal 1
> +  THM2,     8,      //(663) System Thermal 2
> +  THM3,     8,      //(664) System Thermal 3
> +  THM4,     8,      //(665) System Thermal 3
> +  CHGR,     8,      //(666) DPTF Changer Device
> +  DDSP,     8,      //(667) DPTF Display Device
> +  DSOC,     8,      //(668) DPTF SoC device
> +  DPSR,     8,      //(669) DPTF Processor device
> +  DPCT,     32,     //(670) DPTF Processor participant critical temperature
> +  DPPT,     32,     //(674) DPTF Processor participant passive temperature
> +  DGC0,     32,     //(678) DPTF Generic sensor0 participant critical temperature
> +  DGP0,     32,     //(682) DPTF Generic sensor0 participant passive
> temperature
> +  DGC1,     32,     //(686) DPTF Generic sensor1 participant critical temperature
> +  DGP1,     32,     //(690) DPTF Generic sensor1 participant passive
> temperature
> +  DGC2,     32,     //(694) DPTF Generic sensor2 participant critical temperature
> +  DGP2,     32,     //(698) DPTF Generic sensor2 participant passive
> temperature
> +  DGC3,     32,     //(702) DPTF Generic sensor3 participant critical temperature
> +  DGP3,     32,     //(706) DPTF Generic sensor3 participant passive
> temperature
> +  DGC4,     32,     //(710)DPTF Generic sensor3 participant critical temperature
> +  DGP4,     32,     //(714)DPTF Generic sensor3 participant passive
> temperature
> +  DLPM,     8,      //(718) DPTF Current low power mode setting
> +  DSC0,     32,     //(719) DPTF Critical threshold0 for SCU
> +  DSC1,     32,     //(723) DPTF Critical threshold1 for SCU
> +  DSC2,     32,     //(727) DPTF Critical threshold2 for SCU
> +  DSC3,     32,     //(731) DPTF Critical threshold3 for SCU
> +  DSC4,     32,     //(735) DPTF Critical threshold3 for SCU
> +  DDBG,     8,      //(739) DPTF Super Debug option. 0 - Disabled, 1 - Enabled
> +  LPOE,     32,     //(740) DPTF LPO Enable
> +  LPPS,     32,     //(744) P-State start index
> +  LPST,     32,     //(748) Step size
> +  LPPC,     32,     //(752) Power control setting
> +  LPPF,     32,     //(756) Performance control setting
> +  DPME,     8,      //(760) DPTF DPPM enable/disable
> +  BCSL,     8,      //(761) Battery charging solution 0-CLV 1-ULPMC
> +  NFCS,     8,      //(762) NFCx Select 1: NFC1    2:NFC2
> +  PCIM,     8,      //(763) EMMC device 0-ACPI mode, 1-PCI mode
> +  TPMA,     32,     //(764)
> +  TPML,     32,     //(768)
> +  ITSA,      8,     //(772) I2C Touch Screen Address
> +  S0IX,     8,      //(773) S0ix status
> +  SDMD,     8,      //(774) SDIO Mode
> +  EMVR,     8,      //(775) eMMC controller version
> +  BMBD,     32,     //(776) BM Bound
> +  FSAS,     8,      //(780) FSA Status
> +  BDID,     8,      //(781) Board ID
> +  FBID,     8,      //(782) FAB ID
> +  OTGM,     8,      //(783) OTG mode
> +  STEP,     8,      //(784) Stepping ID
> +  WITT,     8,      //(785) Enable Test Device connected to I2C for WHCK test.
> +  SOCS,     8,      //(786) provide the SoC stepping infomation
> +  AMTE,     8,      //(787) Ambient Trip point change
> +  UTS,      8,      //(788) Enable Test Device connected to URT for WHCK test.
> +  SCPE,     8,      //(789) Allow higher performance on AC/USB - Enable/Disable
> +  Offset(792),
> +  EDPV,     8,      //(792) Check for eDP display device
> +  DIDX,     32,     //(793) Device ID for eDP device
> +  IOT,      8,      //(794) MinnowBoard Max JP1 is configured for MSFT IOT
> project.
> +  BATT,     8,      //(795) The Flag of RTC Battery Prensent.
> +  LPAD,     8,      //(796)
> +}
> +
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Gpe.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Gpe.asl
> new file mode 100644
> index 0000000000..c3c9cb6315
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Gpe.asl
> @@ -0,0 +1,99 @@
> +/*********************************************************
> *****************;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
> +;*    Family of Customer Reference Boards.                                *;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved    *;
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*********************************************************
> *****************/
> +
> +
> +// General Purpose Events.  This Scope handles the Run-time and
> +// Wake-time SCIs.  The specific method called will be determined by
> +// the _Lxx value, where xx equals the bit location in the General
> +// Purpose Event register(s).
> +
> +Scope(\_GPE)
> +{
> +  //
> +  // Software GPE caused the event.
> +  //
> +  Method(_L02)
> +  {
> +    // Clear GPE status bit.
> +    Store(0,GPEC)
> +    //
> +    // Handle DTS Thermal Events.
> +    //
> +    External(DTSE, IntObj)
> +    If(CondRefOf(DTSE))
> +    {
> +      If(LGreaterEqual(DTSE, 0x01))
> +      {
> +        Notify(\_TZ.TZ01,0x80)
> +      }
> +    }
> +  }
> +
> +  //
> +  // PUNIT SCI event.
> +  //
> +  Method(_L04)
> +  {
> +    // Clear the PUNIT Status Bit.
> +    Store(1, PSCI)
> +  }
> +
> +
> +  //
> +  // IGD OpRegion SCI event (see IGD OpRegion/Software SCI BIOS SPEC).
> +  //
> +  Method(_L05)
> +  {
> +    If(LAnd(\_SB.PCI0.GFX0.GSSE, LNot(GSMI)))   // Graphics software SCI
> event?
> +    {
> +      \_SB.PCI0.GFX0.GSCI()     // Handle the SWSCI
> +    }
> +  }
> +
> +  //
> +  // This PME event (PCH's GPE #13) is received when any PCH internal
> device with PCI Power Management capabilities
> +  // on bus 0 asserts the equivalent of the PME# signal.
> +  //
> +  Method(_L0D, 0)
> +  {
> +    If(LAnd(\_SB.PCI0.EHC1.PMEE, \_SB.PCI0.EHC1.PMES))
> +    {
> +      If(LNotEqual(OSEL, 1))
> +      {
> +        Store(1, \_SB.PCI0.EHC1.PMES) //Clear PME status
> +        Store(0, \_SB.PCI0.EHC1.PMEE) //Disable PME
> +      }
> +      Notify(\_SB.PCI0.EHC1, 0x02)
> +    }
> +    If(LAnd(\_SB.PCI0.XHC1.PMEE, \_SB.PCI0.XHC1.PMES))
> +    {
> +      If(LNotEqual(OSEL, 1))
> +      {
> +        Store(1, \_SB.PCI0.XHC1.PMES) //Clear PME status
> +        Store(0, \_SB.PCI0.XHC1.PMEE) //Disable PME
> +      }
> +      Notify(\_SB.PCI0.XHC1, 0x02)
> +    }
> +    If(LAnd(\_SB.PCI0.HDEF.PMEE, \_SB.PCI0.HDEF.PMES))
> +    {
> +      If(LNotEqual(OSEL, 1))
> +      {
> +        Store(1, \_SB.PCI0.HDEF.PMES) //Clear PME status
> +        Store(0, \_SB.PCI0.HDEF.PMEE) //Disable PME
> +      }
> +      Notify(\_SB.PCI0.HDEF, 0x02)
> +    }
> +  }
> +}
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/HOST_BUS.ASL
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/HOST_BUS.ASL
> new file mode 100644
> index 0000000000..6b0c2a349f
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/HOST_BUS.ASL
> @@ -0,0 +1,347 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  HOST_BUS.ASL
> +
> +Abstract:
> +
> +  Baytrail PCI configuration space definition.
> +
> +---*/
> +Device(VLVC)
> +{
> +  Name(_ADR, 0x00000000)           // Device 0, Function 0
> +
> +  // Define various MCH Controller PCI Configuration Space
> +  // registers which will be used to dynamically produce all
> +  // resources in the Host Bus _CRS.
> +  OperationRegion(HBUS, PCI_Config, 0x00, 0xFF)
> +  Field(HBUS, DWordAcc, NoLock, Preserve)
> +  {
> +    Offset(0xD0),
> +    SMCR,   32,             // VLV Message Control Register (0xD0)
> +    Offset(0xD4),
> +    SMDR,   32,             // VLV Message Data Register (0xD4)
> +    Offset(0xD8),
> +    MCRX,   32,             // VLV Message Control Register Extension (0xD8)
> +  }
> +
> +  // Define a method to read a 32-bit register on the VLV Message bus.
> +  //  Arg0 = Port
> +  //  Arg1 = Register
> +  //
> +  //  Returns 32-bit register value
> +
> +  Method(RMBR, 2, Serialized)
> +  {
> +
> +    // Initiate regsiter read message on VLV Message Bus MCR
> +
> +    Or(ShiftLeft(Arg0, 16), ShiftLeft(Arg1, 8), Local0)
> +    Or(0x100000F0, Local0, SMCR)
> +
> +    // Read register value from Message Data Register
> +
> +    Return(SMDR)
> +  }
> +
> +
> +  // Define a method to write a 32-bit register on the VLV Message bus MDR.
> +  //  Arg0 = Port
> +  //  Arg1 = Register
> +  //  Arg2 = 32-bit value
> +
> +  Method(WMBR, 3, Serialized)
> +  {
> +
> +    // Write register value to Message Data Register
> +
> +    Store(Arg2, SMDR)
> +
> +    // Initiate register write message on VLV Message Bus
> +
> +    Or(ShiftLeft(Arg0, 16), ShiftLeft(Arg1, 8), Local0)
> +    Or(0x110000F0, Local0, SMCR)
> +  }
> +}
> +
> +//
> +// BUS, I/O, and MMIO resources
> +//
> +Method(_CRS,0,Serialized)
> +{
> +  //Update ISP0 reserved memory
> +  CreateDwordField(RES0, ^ISP0._MIN,ISMN)
> +  CreateDwordField(RES0, ^ISP0._MAX,ISMX)
> +  CreateDwordField(RES0, ^ISP0._LEN,ISLN)
> +  If (LEqual(ISPD,1))
> +  {
> +    Store (ISPA, ISMN)
> +    Add (ISMN, ISLN, ISMX)
> +    Subtract(ISMX, 1, ISMX)
> +  } Else
> +  {
> +    Store (0, ISMN)
> +    Store (0, ISMX)
> +    Store (0, ISLN)
> +  }
> +
> +  //PCI MMIO SPACE
> +  CreateDwordField(RES0, ^PM01._MIN,M1MN)
> +  CreateDwordField(RES0, ^PM01._MAX,M1MX)
> +  CreateDwordField(RES0, ^PM01._LEN,M1LN)
> +
> +  //Get dBMBOUND Base
> +  And(BMBD, 0xFF000000, M1MN)
> +
> +  //Get ECBASE
> +  Store(PCIT, M1MX)
> +  Add(Subtract(M1MX, M1MN), 1, M1LN)
> +  Subtract(M1MX, 1, M1MX)
> +
> +  // Create pointers to Gfx Stolen Memory Sizing values.
> +  CreateDwordField(RES0, ^STOM._MIN,GSMN)
> +  CreateDwordField(RES0, ^STOM._MAX,GSMX)
> +  CreateDwordField(RES0, ^STOM._LEN,GSLN)
> +
> +  If (LNotEqual (\_SB.PCI0.GFX0.GSTM, 0xFFFFFFFF))
> +  {
> +    Store(0x00, GSMN) //Read the Stolen memory base from B0:D2:F0:R5C
> +  } else
> +  {
> +    Store(\_SB.PCI0.GFX0.GSTM, GSMN) //Read the Stolen memory base
> from B0:D2:F0:R5C
> +  }
> +  If (LNotEqual (\_SB.PCI0.GFX0.GUMA, 0xFFFFFFFF))
> +  {
> +    Store(0x00, GSLN) //Read the Stolen memory base from B0:D2:F0:R5C
> +  } else
> +  {
> +    ShiftLeft(\_SB.PCI0.GFX0.GUMA, 25, GSLN) //Read Stolen memory base
> form B0:D2:F0:R50
> +  }
> +  Add(GSMN, GSLN, GSMX) //Store the Stolen Memory Size
> +  Subtract(GSMX, 1, GSMX)
> +
> +  Return(RES0)
> +}
> +
> +Name( RES0,ResourceTemplate()
> +{
> +  WORDBusNumber (          // Bus number resource (0); the bridge produces
> bus numbers for its subsequent buses
> +    ResourceProducer,      // bit 0 of general flags is 1
> +    MinFixed,              // Range is fixed
> +    MaxFixed,              // Range is fixed
> +    PosDecode,             // PosDecode
> +    0x0000,                // Granularity
> +    0x0000,                // Min
> +    0x00FF,                // Max
> +    0x0000,                // Translation
> +    0x0100                 // Range Length = Max-Min+1
> +  )
> +
> +  IO (Decode16, 0x70, 0x77, 0x01, 0x08)         //Consumed resource (0xCF8-
> 0xCFF)
> +  IO (Decode16, 0xCF8, 0xCF8, 0x01, 0x08)       //Consumed resource (0xCF8-
> 0xCFF)
> +
> +  WORDIO (                 // Consumed-and-produced resource (all I/O below CF8)
> +    ResourceProducer,      // bit 0 of general flags is 0
> +    MinFixed,              // Range is fixed
> +    MaxFixed,              // Range is fixed
> +    PosDecode,
> +    EntireRange,
> +    0x0000,                // Granularity
> +    0x0000,                // Min
> +    0x006F,                // Max
> +    0x0000,                // Translation
> +    0x0070                 // Range Length
> +  )
> +
> +  WORDIO (                 // Consumed-and-produced resource
> +    ResourceProducer,      // bit 0 of general flags is 0
> +    MinFixed,              // Range is fixed
> +    MaxFixed,              // Range is fixed
> +    PosDecode,
> +    EntireRange,
> +    0x0000,                // Granularity
> +    0x0078,                // Min
> +    0x0CF7,                // Max
> +    0x0000,                // Translation
> +    0x0C80                 // Range Length
> +  )
> +
> +  WORDIO (                 // Consumed-and-produced resource (all I/O above CFF)
> +    ResourceProducer,      // bit 0 of general flags is 0
> +    MinFixed,              // Range is fixed
> +    MaxFixed,              // Range is fixed
> +    PosDecode,
> +    EntireRange,
> +    0x0000,                // Granularity
> +    0x0D00,                // Min
> +    0xFFFF,                // Max
> +    0x0000,                // Translation
> +    0xF300                 // Range Length
> +  )
> +
> +  DWORDMEMORY (            // Descriptor for legacy VGA video RAM
> +    ResourceProducer,      // bit 0 of general flags is 0
> +    PosDecode,
> +    MinFixed,              // Range is fixed
> +    MaxFixed,              // Range is fixed
> +    Cacheable,
> +    ReadWrite,
> +    0x00000000,            // Granularity
> +    0x000A0000,            // Min
> +    0x000BFFFF,            // Max
> +    0x00000000,            // Translation
> +    0x00020000             // Range Length
> +  )
> +
> +  DWORDMEMORY (            // Descriptor for legacy OptionRom
> +    ResourceProducer,      // bit 0 of general flags is 0
> +    PosDecode,
> +    MinFixed,              // Range is fixed
> +    MaxFixed,              // Range is fixed
> +    Cacheable,
> +    ReadWrite,
> +    0x00000000,            // Granularity
> +    0x000C0000,            // Min
> +    0x000DFFFF,            // Max
> +    0x00000000,            // Translation
> +    0x00020000             // Range Length
> +  )
> +
> +  DWORDMEMORY (            // Descriptor for BIOS Area
> +    ResourceProducer,      // bit 0 of general flags is 0
> +    PosDecode,
> +    MinFixed,              // Range is fixed
> +    MaxFixed,              // Range is fixed
> +    Cacheable,
> +    ReadWrite,
> +    0x00000000,            // Granularity
> +    0x000E0000,            // Min
> +    0x000FFFFF,            // Max
> +    0x00000000,            // Translation
> +    0x00020000             // Range Length
> +  )
> +
> +  DWORDMEMORY (            // Descriptor for ISP0 reserved Mem
> +    ResourceProducer,      // bit 0 of general flags is 0
> +    PosDecode,
> +    MinFixed,              // Range is fixed
> +    MaxFixed,              // Range is fixed
> +    Cacheable,
> +    ReadWrite,
> +    0x00000000,            // Granularity
> +    0x7A000000,            // Min
> +    0x7A3FFFFF,            // Max
> +    0x00000000,            // Translation
> +    0x00400000             // Range Length
> +    ,,,
> +    ISP0
> +  )
> +
> +  DWORDMEMORY (            // Descriptor for VGA Stolen Mem
> +    ResourceProducer,      // bit 0 of general flags is 0
> +    PosDecode,
> +    MinFixed,              // Range is fixed
> +    MaxFixed,              // Range is fixed
> +    Cacheable,
> +    ReadWrite,
> +    0x00000000,            // Granularity
> +    0x7C000000,            // Min
> +    0x7FFFFFFF,            // Max
> +    0x00000000,            // Translation
> +    0x04000000             // Range Length
> +    ,,,
> +    STOM
> +  )
> +
> +  DWORDMEMORY (            // Descriptor for PCI MMIO
> +    ResourceProducer,      // bit 0 of general flags is 0
> +    PosDecode,
> +    MinFixed,              // Range is fixed
> +    MaxFixed,              // Range is fixed
> +    Cacheable,
> +    ReadWrite,
> +    0x00000000,            // Granularity
> +    0x80000000,            // Min
> +    0xDFFFFFFF,            // Max
> +    0x00000000,            // Translation
> +    0x60000000             // Range Length
> +    ,,,
> +    PM01
> +  )
> +})
> +
> +//Name(GUID,UUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))
> +Name(GUID,Buffer()
> +{
> +  0x5b, 0x4d, 0xdb, 0x33,
> +  0xf7, 0x1f,
> +  0x1c, 0x40,
> +  0x96, 0x57,
> +  0x74, 0x41, 0xc0, 0x3d, 0xd7, 0x66
> +})
> +
> +
> +Name(SUPP,0)    // PCI _OSC Support Field value
> +Name(CTRL,0)    // PCI _OSC Control Field value
> +
> +Method(_OSC,4,Serialized)
> +{
> +  // Check for proper UUID
> +  // Save the capabilities buffer
> +  Store(Arg3,Local0)
> +
> +  // Create DWord-adressable fields from the Capabilties Buffer
> +  CreateDWordField(Local0,0,CDW1)
> +  CreateDWordField(Local0,4,CDW2)
> +  CreateDWordField(Local0,8,CDW3)
> +
> +  // Check for proper UUID
> +  If(LAnd(LEqual(Arg0,GUID),NEXP))
> +  {
> +    // Save Capabilities DWord2 & 3
> +    Store(CDW2,SUPP)
> +    Store(CDW3,CTRL)
> +
> +    If(Not(And(CDW1,1)))    // Query flag clear?
> +    {
> +      // Disable GPEs for features granted native control.
> +      If(And(CTRL,0x02))
> +      {
> +        NHPG()
> +      }
> +      If(And(CTRL,0x04))      // PME control granted?
> +      {
> +        NPME()
> +      }
> +    }
> +
> +    If(LNotEqual(Arg1,One))
> +    {
> +      // Unknown revision
> +      Or(CDW1,0x08,CDW1)
> +    }
> +
> +    If(LNotEqual(CDW3,CTRL))
> +    {
> +      // Capabilities bits were masked
> +      Or(CDW1,0x10,CDW1)
> +    }
> +    // Update DWORD3 in the buffer
> +	And(CTRL,0xfe,CTRL)
> +    Store(CTRL,CDW3)
> +    Store(CTRL,OSCC)
> +    Return(Local0)
> +  } Else
> +  {
> +    Or(CDW1,4,CDW1)         // Unrecognized UUID
> +    Return(Local0)
> +  }
> +}       // End _OSC
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Hpet/Hpet.aslc
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Hpet/Hpet.aslc
> new file mode 100644
> index 0000000000..ecbe51e6b0
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Hpet/Hpet.aslc
> @@ -0,0 +1,63 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  Hpet.c
> +
> +Abstract:
> +
> +  This file contains a structure definition for the ACPI HPET Table.
> +--*/
> +
> +//
> +// Statements that include other files
> +//
> +#ifdef ECP_FLAG
> +#include <Tiano.h>
> +#endif
> +#include <Hpet.h>
> +#include "AcpiTablePlatform.h"
> +
> +// Hpet Table
> +EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER HPET = {
> +  {
> +    EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE,
> +    sizeof (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER),
> +    EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_REVISION,
> +    0,                          // to make sum of entire table == 0
> +    EFI_ACPI_OEM_ID,            // OEMID is a 6 bytes long field
> +    EFI_ACPI_OEM_TABLE_ID,      // OEM table identification(8 bytes long)
> +    EFI_ACPI_OEM_REVISION,      // OEM revision
> +    EFI_ACPI_CREATOR_ID,        // ASL compiler vendor ID
> +    EFI_ACPI_CREATOR_REVISION   // ASL compiler revision number
> +  },
> +  0x0,                          // EventTimerBlockId
> +  {
> +    0x00,                     // Address_Space_ID = System Memory
> +    0x40,                     // Register_Bit_Width = 32 bits, mentioned about write
> failures when in 64bit in SCU HAS
> +    0x00,                     // Register_Bit_offset
> +    0x00,                     // Dword access
> +    HPET_BASE_ADDRESS,        // Base addresse of HPET
> +  },
> +  0x0,                          // Only HPET's _UID in Namespace
> +  MAIN_COUNTER_MIN_PERIODIC_CLOCK_TICKS,
> +  0x0
> +};
> +
> +VOID*
> +ReferenceAcpiTable (
> +  VOID
> +  )
> +{
> +  //
> +  // Reference the table being generated to prevent the optimizer from
> +  // removing the data structure from the executable
> +  //
> +  return (VOID*)&HPET;
> +}
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELGFX.ASL
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELGFX.ASL
> new file mode 100644
> index 0000000000..a2ba398568
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELGFX.ASL
> @@ -0,0 +1,879 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  INTELGFX.ASL
> +
> +Abstract:
> +
> +  IGD OpRegion/Software ACPI Reference Code for the Baytrail Family.
> +
> +--*/
> +
> +// Enable/Disable Output Switching.  In WIN2K/WINXP, _DOS = 0 will
> +// get called during initialization to prepare for an ACPI Display
> +// Switch Event.  During an ACPI Display Switch, the OS will call
> +// _DOS = 2 immediately after a Notify=0x80 to temporarily disable
> +// all Display Switching.  After ACPI Display Switching is complete,
> +// the OS will call _DOS = 0 to re-enable ACPI Display Switching.
> +
> +Method(_DOS,1)
> +{
> +  // Store Display Switching and LCD brightness BIOS control bit
> +  Store(And(Arg0,7),DSEN)
> +}
> +
> +// Enumerate the Display Environment.  This method will return
> +// valid addresses for all display device encoders present in the
> +// system.  The Miniport Driver will reject the addresses for every
> +// encoder that does not have an attached display device.  After
> +// enumeration is complete, the OS will call the _DGS methods
> +// during a display switch only for the addresses accepted by the
> +// Miniport Driver.  For hot-insertion and removal of display
> +// devices, a re-enumeration notification will be required so the
> +// address of the newly present display device will be accepted by
> +// the Miniport Driver.
> +
> +Method(_DOD, 0, Serialized)
> +{
> +  Store(0, NDID)
> +  If(LNotEqual(DIDL, Zero))
> +  {
> +    Store(SDDL(DIDL),DID1)
> +  }
> +  If(LNotEqual(DDL2, Zero))
> +  {
> +    Store(SDDL(DDL2),DID2)
> +  }
> +  If(LNotEqual(DDL3, Zero))
> +  {
> +    Store(SDDL(DDL3),DID3)
> +  }
> +  If(LNotEqual(DDL4, Zero))
> +  {
> +    Store(SDDL(DDL4),DID4)
> +  }
> +  If(LNotEqual(DDL5, Zero))
> +  {
> +    Store(SDDL(DDL5),DID5)
> +  }
> +
> +  // TODO - This level of flexibility is not needed for a true
> +  //      OEM design.  Simply determine the greatest number of
> +  //      encoders the platform will suppport then remove all
> +  //      return packages beyond that value.  Note that for
> +  //      current silicon, the maximum number of encoders
> +  //      possible is 5.
> +
> +  If(LEqual(NDID,1))
> +  {
> +    If (LNOTEqual (ISPD, 0))
> +    {
> +      Name(TMP0,Package() {0xFFFFFFFF,0xFFFFFFFF})
> +      Store(Or(0x10000,DID1),Index(TMP0,0))
> +      //Add ISP device to GFX0
> +      Store(0x00020F38, Index(TMP0,1))
> +      Return(TMP0)
> +    } Else
> +    {
> +      Name(TMP1,Package() {0xFFFFFFFF})
> +      Store(Or(0x10000,DID1),Index(TMP1,0))
> +      Return(TMP1)
> +    }
> +  }
> +
> +  If(LEqual(NDID,2))
> +  {
> +    If (LNOTEqual (ISPD, 0))
> +    {
> +      Name(TMP2,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
> +      Store(Or(0x10000,DID1),Index(TMP2,0))
> +      Store(Or(0x10000,DID2),Index(TMP2,1))
> +      //Add ISP device to GFX0
> +      Store(0x00020F38, Index(TMP2,2))
> +      Return(TMP2)
> +    } Else
> +    {
> +      Name(TMP3,Package() {0xFFFFFFFF, 0xFFFFFFFF})
> +      Store(Or(0x10000,DID1),Index(TMP3,0))
> +      Store(Or(0x10000,DID2),Index(TMP3,1))
> +      Return(TMP3)
> +    }
> +  }
> +
> +  If(LEqual(NDID,3))
> +  {
> +    If (LNOTEqual (ISPD, 0))
> +    {
> +      Name(TMP4,Package() {0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF,0xFFFFFFFF})
> +      Store(Or(0x10000,DID1),Index(TMP4,0))
> +      Store(Or(0x10000,DID2),Index(TMP4,1))
> +      Store(Or(0x10000,DID3),Index(TMP4,2))
> +      //Add ISP device to GFX0
> +      Store(0x00020F38, Index(TMP4,3))
> +      Return(TMP4)
> +    } Else
> +    {
> +      Name(TMP5,Package() {0xFFFFFFFF, 0xFFFFFFFF,0xFFFFFFFF})
> +      Store(Or(0x10000,DID1),Index(TMP5,0))
> +      Store(Or(0x10000,DID2),Index(TMP5,1))
> +      Store(Or(0x10000,DID3),Index(TMP5,2))
> +      Return(TMP5)
> +    }
> +  }
> +
> +  If(LEqual(NDID,4))
> +  {
> +    If (LNOTEqual (ISPD, 0))
> +    {
> +      Name(TMP6,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF})
> +      Store(Or(0x10000,DID1),Index(TMP6,0))
> +      Store(Or(0x10000,DID2),Index(TMP6,1))
> +      Store(Or(0x10000,DID3),Index(TMP6,2))
> +      Store(Or(0x10000,DID4),Index(TMP6,3))
> +      //Add ISP device to GFX0
> +      Store(0x00020F38, Index(TMP6,4))
> +      Return(TMP6)
> +    } Else
> +    {
> +      Name(TMP7,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF})
> +      Store(Or(0x10000,DID1),Index(TMP7,0))
> +      Store(Or(0x10000,DID2),Index(TMP7,1))
> +      Store(Or(0x10000,DID3),Index(TMP7,2))
> +      Store(Or(0x10000,DID4),Index(TMP7,3))
> +      Return(TMP7)
> +    }
> +  }
> +
> +  If(LGreater(NDID,4))
> +  {
> +    If (LNOTEqual (ISPD, 0))
> +    {
> +      Name(TMP8,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
> +      Store(Or(0x10000,DID1),Index(TMP8,0))
> +      Store(Or(0x10000,DID2),Index(TMP8,1))
> +      Store(Or(0x10000,DID3),Index(TMP8,2))
> +      Store(Or(0x10000,DID4),Index(TMP8,3))
> +      Store(Or(0x10000,DID5),Index(TMP8,4))
> +      //Add ISP device to GFX0
> +      Store(0x00020F38, Index(TMP8,5))
> +      Return(TMP8)
> +    } Else
> +    {
> +      Name(TMP9,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF})
> +      Store(Or(0x10000,DID1),Index(TMP9,0))
> +      Store(Or(0x10000,DID2),Index(TMP9,1))
> +      Store(Or(0x10000,DID3),Index(TMP9,2))
> +      Store(Or(0x10000,DID4),Index(TMP9,3))
> +      Store(Or(0x10000,DID5),Index(TMP9,4))
> +      Return(TMP9)
> +    }
> +  }
> +
> +  // If nothing else, return Unknown LFP.
> +  // (Prevents compiler warning.)
> +
> +  //Add ISP device to GFX0
> +  If (LNOTEqual (ISPD, 0))
> +  {
> +    Return(Package() {0x00000400, 0x00020F38})
> +  } Else
> +  {
> +    Return(Package() {0x00000400})
> +  }
> +}
> +
> +Device(DD01)
> +{
> +
> +  // Return Unique ID.
> +
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(And(0x0F00,DID1),0x400))
> +    {
> +      Store(0x1, EDPV)
> +      Store(DID1, DIDX)
> +      Return(1)
> +    }
> +    If(LEqual(DID1,0))
> +    {
> +      Return(1)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DID1))
> +    }
> +  }
> +
> +  // Return the Current Status.
> +
> +  Method(_DCS,0)
> +  {
> +    Return(CDDS(DID1))
> +  }
> +
> +  // Query Graphics State (active or inactive).
> +
> +  Method(_DGS,0)
> +  {
> +    Return(NDDS(DID1))
> +  }
> +
> +  // Device Set State.
> +
> +  // _DSS Table:
> +  //
> +  //      BIT31   BIT30   Execution
> +  //      0       0       Don't implement.
> +  //      0       1       Cache change.  Nothing to Implement.
> +  //      1       0       Don't Implement.
> +  //      1       1       Display Switch Complete.  Implement.
> +
> +  Method(_DSS,1)
> +  {
> +    If(LEqual(And(Arg0,0xC0000000),0xC0000000))
> +    {
> +
> +      // State change was performed by the
> +      // Video Drivers.  Simply update the
> +      // New State.
> +
> +      Store(NSTE,CSTE)
> +    }
> +  }
> +}
> +
> +Device(DD02)
> +{
> +
> +  // Return Unique ID.
> +
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(And(0x0F00,DID2),0x400))
> +    {
> +      Store(0x2, EDPV)
> +      Store(DID2, DIDX)
> +      Return(2)
> +    }
> +    If(LEqual(DID2,0))
> +    {
> +      Return(2)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DID2))
> +    }
> +  }
> +
> +  // Return the Current Status.
> +
> +  Method(_DCS,0)
> +  {
> +    Return(CDDS(DID2))
> +  }
> +
> +  // Query Graphics State (active or inactive).
> +
> +  Method(_DGS,0)
> +  {
> +    // Return the Next State.
> +    Return(NDDS(DID2))
> +  }
> +
> +  // Device Set State. (See table above.)
> +
> +  Method(_DSS,1)
> +  {
> +    If(LEqual(And(Arg0,0xC0000000),0xC0000000))
> +    {
> +
> +      // State change was performed by the
> +      // Video Drivers.  Simply update the
> +      // New State.
> +
> +      Store(NSTE,CSTE)
> +    }
> +  }
> +}
> +
> +Device(DD03)
> +{
> +
> +  // Return Unique ID.
> +
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(And(0x0F00,DID3),0x400))
> +    {
> +      Store(0x3, EDPV)
> +      Store(DID3, DIDX)
> +      Return(3)
> +    }
> +    If(LEqual(DID3,0))
> +    {
> +      Return(3)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DID3))
> +    }
> +  }
> +
> +  // Return the Current Status.
> +
> +  Method(_DCS,0)
> +  {
> +    If(LEqual(DID3,0))
> +    {
> +      Return(0x0B)
> +    }
> +    Else
> +    {
> +      Return(CDDS(DID3))
> +    }
> +  }
> +
> +  // Query Graphics State (active or inactive).
> +
> +  Method(_DGS,0)
> +  {
> +    Return(NDDS(DID3))
> +  }
> +
> +  // Device Set State. (See table above.)
> +
> +  Method(_DSS,1)
> +  {
> +    If(LEqual(And(Arg0,0xC0000000),0xC0000000))
> +    {
> +      // State change was performed by the
> +      // Video Drivers.  Simply update the
> +      // New State.
> +
> +      Store(NSTE,CSTE)
> +    }
> +  }
> +}
> +
> +Device(DD04)
> +{
> +
> +  // Return Unique ID.
> +
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(And(0x0F00,DID4),0x400))
> +    {
> +      Store(0x4, EDPV)
> +      Store(DID4, DIDX)
> +      Return(4)
> +    }
> +    If(LEqual(DID4,0))
> +    {
> +      Return(4)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DID4))
> +    }
> +  }
> +
> +  // Return the Current Status.
> +
> +  Method(_DCS,0)
> +  {
> +    If(LEqual(DID4,0))
> +    {
> +      Return(0x0B)
> +    }
> +    Else
> +    {
> +      Return(CDDS(DID4))
> +    }
> +  }
> +
> +  // Query Graphics State (active or inactive).
> +
> +  Method(_DGS,0)
> +  {
> +    Return(NDDS(DID4))
> +  }
> +
> +  // Device Set State. (See table above.)
> +
> +  Method(_DSS,1)
> +  {
> +    If(LEqual(And(Arg0,0xC0000000),0xC0000000))
> +    {
> +
> +      // State change was performed by the
> +      // Video Drivers.  Simply update the
> +      // New State.
> +
> +      Store(NSTE,CSTE)
> +    }
> +  }
> +}
> +
> +
> +Device(DD05)
> +{
> +
> +  // Return Unique ID.
> +
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(And(0x0F00,DID5),0x400))
> +    {
> +      Store(0x5, EDPV)
> +      Store(DID5, DIDX)
> +      Return(5)
> +    }
> +    If(LEqual(DID5,0))
> +    {
> +      Return(5)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DID5))
> +    }
> +  }
> +
> +  // Return the Current Status.
> +
> +  Method(_DCS,0)
> +  {
> +    If(LEqual(DID5,0))
> +    {
> +      Return(0x0B)
> +    }
> +    Else
> +    {
> +      Return(CDDS(DID5))
> +    }
> +  }
> +
> +  // Query Graphics State (active or inactive).
> +
> +  Method(_DGS,0)
> +  {
> +    Return(NDDS(DID5))
> +  }
> +
> +  // Device Set State. (See table above.)
> +
> +  Method(_DSS,1)
> +  {
> +    If(LEqual(And(Arg0,0xC0000000),0xC0000000))
> +    {
> +      // State change was performed by the
> +      // Video Drivers.  Simply update the
> +      // New State.
> +
> +      Store(NSTE,CSTE)
> +    }
> +  }
> +}
> +
> +
> +Device(DD06)
> +{
> +
> +  // Return Unique ID.
> +
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(And(0x0F00,DID6),0x400))
> +    {
> +      Store(0x6, EDPV)
> +      Store(DID6, DIDX)
> +      Return(6)
> +    }
> +    If(LEqual(DID6,0))
> +    {
> +      Return(6)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DID6))
> +    }
> +  }
> +
> +  // Return the Current Status.
> +
> +  Method(_DCS,0)
> +  {
> +    If(LEqual(DID6,0))
> +    {
> +      Return(0x0B)
> +    }
> +    Else
> +    {
> +      Return(CDDS(DID6))
> +    }
> +  }
> +
> +  // Query Graphics State (active or inactive).
> +
> +  Method(_DGS,0)
> +  {
> +    Return(NDDS(DID6))
> +  }
> +
> +  // Device Set State. (See table above.)
> +
> +  Method(_DSS,1)
> +  {
> +    If(LEqual(And(Arg0,0xC0000000),0xC0000000))
> +    {
> +      // State change was performed by the
> +      // Video Drivers.  Simply update the
> +      // New State.
> +
> +      Store(NSTE,CSTE)
> +    }
> +  }
> +}
> +
> +
> +Device(DD07)
> +{
> +
> +  // Return Unique ID.
> +
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(And(0x0F00,DID7),0x400))
> +    {
> +      Store(0x7, EDPV)
> +      Store(DID7, DIDX)
> +      Return(7)
> +    }
> +    If(LEqual(DID7,0))
> +    {
> +      Return(7)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DID7))
> +    }
> +  }
> +
> +  // Return the Current Status.
> +
> +  Method(_DCS,0)
> +  {
> +    If(LEqual(DID7,0))
> +    {
> +      Return(0x0B)
> +    }
> +    Else
> +    {
> +      Return(CDDS(DID7))
> +    }
> +  }
> +
> +  // Query Graphics State (active or inactive).
> +
> +  Method(_DGS,0)
> +  {
> +    Return(NDDS(DID7))
> +  }
> +
> +  // Device Set State. (See table above.)
> +
> +  Method(_DSS,1)
> +  {
> +    If(LEqual(And(Arg0,0xC0000000),0xC0000000))
> +    {
> +      // State change was performed by the
> +      // Video Drivers.  Simply update the
> +      // New State.
> +
> +      Store(NSTE,CSTE)
> +    }
> +  }
> +}
> +
> +
> +Device(DD08)
> +{
> +
> +  // Return Unique ID.
> +
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(And(0x0F00,DID8),0x400))
> +    {
> +      Store(0x8, EDPV)
> +      Store(DID8, DIDX)
> +      Return(8)
> +    }
> +    If(LEqual(DID8,0))
> +    {
> +      Return(8)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DID8))
> +    }
> +  }
> +
> +  // Return the Current Status.
> +
> +  Method(_DCS,0)
> +  {
> +    If(LEqual(DID8,0))
> +    {
> +      Return(0x0B)
> +    }
> +    Else
> +    {
> +      Return(CDDS(DID8))
> +    }
> +  }
> +
> +  // Query Graphics State (active or inactive).
> +
> +  Method(_DGS,0)
> +  {
> +    Return(NDDS(DID8))
> +  }
> +
> +  // Device Set State. (See table above.)
> +
> +  Method(_DSS,1)
> +  {
> +    If(LEqual(And(Arg0,0xC0000000),0xC0000000))
> +    {
> +      // State change was performed by the
> +      // Video Drivers.  Simply update the
> +      // New State.
> +
> +      Store(NSTE,CSTE)
> +    }
> +  }
> +}
> +
> +//device for eDP
> +Device(DD1F)
> +{
> +  // Return Unique ID.
> +
> +  Method(_ADR,0,Serialized)
> +  {
> +    If(LEqual(EDPV, 0x0))
> +    {
> +      Return(0x1F)
> +    }
> +    Else
> +    {
> +      Return(And(0xFFFF,DIDX))
> +    }
> +  }
> +
> +  // Return the Current Status.
> +
> +  Method(_DCS,0)
> +  {
> +    If(LEqual(EDPV, 0x0))
> +    {
> +      Return(0x00)
> +    }
> +    Else
> +    {
> +      Return(CDDS(DIDX))
> +    }
> +  }
> +
> +  // Query Graphics State (active or inactive).
> +
> +  Method(_DGS,0)
> +  {
> +    Return(NDDS(DIDX))
> +  }
> +
> +  // Device Set State. (See table above.)
> +
> +  Method(_DSS,1)
> +  {
> +    If(LEqual(And(Arg0,0xC0000000),0xC0000000))
> +    {
> +      // State change was performed by the
> +      // Video Drivers.  Simply update the
> +      // New State.
> +      Store(NSTE,CSTE)
> +    }
> +  }
> +  // Query List of Brightness Control Levels Supported.
> +
> +  Method(_BCL,0)
> +  {
> +    // List of supported brightness levels in the following sequence.
> +
> +    // Level when machine has full power.
> +    // Level when machine is on batteries.
> +    // Other supported levels.
> +    Return(Package() {80, 50, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
> 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
> 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
> 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
> 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100})
> +  }
> +
> +  // Set the Brightness Level.
> +
> +  Method (_BCM,1)
> +  {
> +    // Set the requested level if it is between 0 and 100%.
> +
> +    If(LAnd(LGreaterEqual(Arg0,0),LLessEqual(Arg0,100)))
> +    {
> +      \_SB.PCI0.GFX0.AINT(1, Arg0)
> +      Store(Arg0,BRTL)  // Store Brightness Level.
> +    }
> +  }
> +
> +  // Brightness Query Current level.
> +
> +  Method (_BQC,0)
> +  {
> +    Return(BRTL)
> +  }
> +}
> +
> +Method(SDDL,1)
> +{
> +  Increment(NDID)
> +  Store(And(Arg0,0xF0F),Local0)
> +  Or(0x80000000,Local0, Local1)
> +  If(LEqual(DIDL,Local0))
> +  {
> +    Return(Local1)
> +  }
> +  If(LEqual(DDL2,Local0))
> +  {
> +    Return(Local1)
> +  }
> +  If(LEqual(DDL3,Local0))
> +  {
> +    Return(Local1)
> +  }
> +  If(LEqual(DDL4,Local0))
> +  {
> +    Return(Local1)
> +  }
> +  If(LEqual(DDL5,Local0))
> +  {
> +    Return(Local1)
> +  }
> +  If(LEqual(DDL6,Local0))
> +  {
> +    Return(Local1)
> +  }
> +  If(LEqual(DDL7,Local0))
> +  {
> +    Return(Local1)
> +  }
> +  If(LEqual(DDL8,Local0))
> +  {
> +    Return(Local1)
> +  }
> +  Return(0)
> +}
> +
> +Method(CDDS,1)
> +{
> +  Store(And(Arg0,0xF0F),Local0)
> +
> +  If(LEqual(0, Local0))
> +  {
> +    Return(0x1D)
> +  }
> +  If(LEqual(CADL, Local0))
> +  {
> +    Return(0x1F)
> +  }
> +  If(LEqual(CAL2, Local0))
> +  {
> +    Return(0x1F)
> +  }
> +  If(LEqual(CAL3, Local0))
> +  {
> +    Return(0x1F)
> +  }
> +  If(LEqual(CAL4, Local0))
> +  {
> +    Return(0x1F)
> +  }
> +  If(LEqual(CAL5, Local0))
> +  {
> +    Return(0x1F)
> +  }
> +  If(LEqual(CAL6, Local0))
> +  {
> +    Return(0x1F)
> +  }
> +  If(LEqual(CAL7, Local0))
> +  {
> +    Return(0x1F)
> +  }
> +  If(LEqual(CAL8, Local0))
> +  {
> +    Return(0x1F)
> +  }
> +  Return(0x1D)
> +}
> +
> +Method(NDDS,1)
> +{
> +  Store(And(Arg0,0xF0F),Local0)
> +
> +  If(LEqual(0, Local0))
> +  {
> +    Return(0)
> +  }
> +  If(LEqual(NADL, Local0))
> +  {
> +    Return(1)
> +  }
> +  If(LEqual(NDL2, Local0))
> +  {
> +    Return(1)
> +  }
> +  If(LEqual(NDL3, Local0))
> +  {
> +    Return(1)
> +  }
> +  If(LEqual(NDL4, Local0))
> +  {
> +    Return(1)
> +  }
> +  If(LEqual(NDL5, Local0))
> +  {
> +    Return(1)
> +  }
> +  If(LEqual(NDL6, Local0))
> +  {
> +    Return(1)
> +  }
> +  If(LEqual(NDL7, Local0))
> +  {
> +    Return(1)
> +  }
> +  If(LEqual(NDL8, Local0))
> +  {
> +    Return(1)
> +  }
> +  Return(0)
> +}
> +
> +//
> +// Include IGD OpRegion/Software SCI interrupt handler which is use by
> +// the graphics drivers to request data from system BIOS.
> +//
> +include("IgdOpRn.ASL")
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELISPDev2.ASL
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELISPDev2.ASL
> new file mode 100644
> index 0000000000..97548a41f9
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELISPDev2.ASL
> @@ -0,0 +1,71 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  INTELISPDev2.ASL
> +
> +Abstract:
> +
> +  ISP Exist as B0D2F0 Software ACPI Reference Code for the Baytrail Family.
> +
> +--*/
> +////Device ISP0
> +Device(ISP0)
> +{
> +  Name(_ADR, 0x0F38)
> +  //Name (_HID, "80860F38")
> +  //Name (_CID, "80860F38")
> +  Name(_DDN, "VLV2 ISP - 80860F38")
> +  Name(_UID, 0x01)
> +
> +  Method (_STA, 0, NotSerialized)
> +  {
> +    If(LEqual(ISPD,1))   //Dev2 need report ISP0 as GFX0 child
> +    {
> +      Return (0xF)
> +    }
> +    Else
> +    {
> +      Return (0x0)
> +    }
> +  }
> +  Name(SBUF,ResourceTemplate ()
> +  {
> +    Memory32Fixed (ReadWrite, 0x00000000, 0x00400000, ISP0)
> +  })
> +  Method(_CRS, 0x0, NotSerialized)
> +  {
> +    Return (SBUF)
> +  }
> +  Method (_SRS, 0x1, NotSerialized)
> +  {
> +  }
> +  Method (_DIS, 0x0, NotSerialized)
> +  {
> +  }
> +  Method(_DSM, 0x4, NotSerialized)
> +  {
> +    If (LEqual (Arg0, 0x01))
> +    {
> +      ///Switch ISP to D3H
> +      Return (0x01)
> +    }
> +    Elseif (LEqual (Arg0, 0x02))
> +    {
> +      //Switch ISP to D0
> +      Return (0x02)
> +    }
> +    Else
> +    {
> +      //Do nothing
> +      Return (0x0F)
> +    }
> +  }
> +} ///End ISP0
> +
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOGBDA.ASL
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOGBDA.ASL
> new file mode 100644
> index 0000000000..4482db6906
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOGBDA.ASL
> @@ -0,0 +1,155 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  IgdOGBDA.ASL
> +
> +Abstract:
> +
> +  IGD OpRegion/Software SCI Reference Code for the Baytrail Family.
> +  This file contains Get BIOS Data Area funciton support for
> +  the Integrated Graphics Device (IGD) OpRegion/Software SCI mechanism.
> +
> +--*/
> +
> +
> +Method (GBDA, 0, Serialized)
> +{
> +
> +  // Supported calls: Sub-function 0
> +
> +  If (LEqual(GESF, 0))
> +  {
> +    //<TODO> Update implementation specific supported calls.  Reference
> +    // code is set to Intel's validated implementation.
> +
> +    Store(0x0000279, PARM)
> +
> +    Store(Zero, GESF)               // Clear the exit parameter
> +    Return(SUCC)                    // Success
> +  }
> +
> +  // Requested callbacks: Sub-function 1
> +
> +  If (LEqual(GESF, 1))
> +  {
> +
> +    //<TODO> Update implementation specific system BIOS requested call
> +    // back functions.  Call back functions are where the driver calls the
> +    // system BIOS at function indicated event.
> +
> +    Store(0x00000240, PARM)
> +
> +    Store(Zero, GESF)               // Clear the exit parameter
> +    Return(SUCC)                    // Success
> +  }
> +
> +  // Get Boot display Preferences: Sub-function 4
> +
> +  If (LEqual(GESF, 4))
> +  {
> +
> +    //<TODO> Update the implementation specific Get Boot Display
> +    // Preferences function.
> +
> +    And(PARM, 0xEFFF0000, PARM)     // PARM[30:16] = Boot device ports
> +    And(PARM, ShiftLeft(DeRefOf(Index(DBTB, IBTT)), 16), PARM)
> +    Or(IBTT, PARM, PARM)            // PARM[7:0] = Boot device type
> +
> +    Store(Zero, GESF)               // Clear the exit parameter
> +    Return(SUCC)                    // Success
> +  }
> +
> +  // Panel details: Sub-function 5
> +
> +  If (LEqual(GESF, 5))
> +  {
> +
> +    //<TODO> Update the implementation specific Get Panel Details
> +    // function.
> +
> +    Store(IPSC, PARM)               // Report the scaling setting
> +    Or(PARM, ShiftLeft(IPAT, 8), PARM)
> +    Add(PARM, 0x100, PARM)          // Adjust panel type, 0 = VBT default
> +    Or(PARM, ShiftLeft(LIDS, 16), PARM) // Report the lid state
> +    Add(PARM, 0x10000, PARM)        // Adjust the lid state, 0 = Unknown
> +    Or(PARM, ShiftLeft(IBLC, 18), PARM) // Report the BLC setting
> +    Or(PARM, ShiftLeft(IBIA, 20), PARM) // Report the BIA setting
> +    Store(Zero, GESF)
> +    Return(SUCC)
> +  }
> +
> +  // TV-standard/Video-connector: Sub-function 6
> +
> +  If (LEqual(GESF, 6))
> +  {
> +
> +    //<TODO> Update the implementation specific Get
> +    // TV-standard/Video-connectorPanel function.
> +
> +    Store(ITVF, PARM)
> +    Or(PARM, ShiftLeft(ITVM, 4), PARM)
> +    Store(Zero, GESF)
> +    Return(SUCC)
> +  }
> +
> +  // Internal graphics: Sub-function 7
> +
> +  If (LEqual(GESF, 7))
> +  {
> +    Store(GIVD, PARM)               // PARM[0]      - VGA mode(1=VGA)
> +    Xor(PARM, 1, PARM)              // Invert the VGA mode polarity
> +    Or(PARM, ShiftLeft(GMFN, 1), PARM) // PARM[1]   - # IGD PCI functions-1
> +    // PARM[3:2]    - Reserved
> +    // PARM[4]      - IGD D3 support(0=cold)
> +    // PARM[10:5]   - Reserved
> +    Or(PARM, ShiftLeft(3, 11), PARM) // PARM[12:11] - DVMT mode(11b = 5.0)
> +
> +    //
> +    // Report DVMT 5.0 Total Graphics memory size.
> +    //
> +    Or(PARM, ShiftLeft(IDMS, 17), PARM)   // Bits 20:17 are for Gfx total
> memory size
> +
> +    // If the "Set Internal Graphics" call is supported, the modified
> +    // settings flag must be programmed per the specification.  This means
> +    // that the flag must be set to indicate that system BIOS requests
> +    // these settings.  Once "Set Internal Graphics" is called, the
> +    //  modified settings flag must be cleared on all subsequent calls to
> +    // this function.
> +
> +    // Report the graphics frequency based on
> DISPLAY_CLOCK_FREQUENCY_ENCODING [MMADR+0x20C8]
> +
> +    Or(ShiftLeft(Derefof(Index(CDCT, \_SB.PCI0.GFX0.MCHK.DCFE)),
> 21),PARM, PARM)
> +
> +    Store(1, GESF)                  // Set the modified settings flag
> +    Return(SUCC)
> +  }
> +
> +  // Spread spectrum clocks: Sub-function 10
> +
> +  If (LEqual(GESF, 10))
> +  {
> +
> +    Store(0, PARM)                  // Assume SSC is disabled
> +
> +    If(ISSC)
> +    {
> +      Or(PARM, 3, PARM)       // If SSC enabled, return SSC1+Enabled
> +    }
> +
> +    Store(0, GESF)                  // Set the modified settings flag
> +    Return(SUCC)                    // Success
> +  }
> +
> +
> +  // A call to a reserved "Get BIOS data" function was received.
> +
> +  Store(Zero, GESF)                     // Clear the exit parameter
> +  Return(CRIT)                          // Reserved, "Critical failure"
> +}
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOMOBF.ASL
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOMOBF.ASL
> new file mode 100644
> index 0000000000..917e3268d7
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOMOBF.ASL
> @@ -0,0 +1,485 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  IgdOMOBF.ASL
> +
> +Abstract:
> +
> +  IGD OpRegion/Software SCI Reference Code for the Baytrail Family.
> +  This file contains ASL code with the purpose of handling events
> +  i.e. hotkeys and other system interrupts.
> +
> +--*/
> +
> +
> +// Notes:
> +// 1. The following routines are to be called from the appropriate event
> +//    handlers.
> +// 2. This code cannot comprehend the exact implementation in the OEM's
> BIOS.
> +//    Therefore, an OEM must call these methods from the existing event
> +//    handler infrastructure.  Details on when/why to call each method is
> +//    included in the method header under the "usage" section.
> +
> +
> +/*********************************************************
> ***************;
> +;* ACPI Notification Methods
> +;*********************************************************
> ***************/
> +
> +
> +/*********************************************************
> ***************;
> +;*
> +;* Name:        PDRD
> +;*
> +;* Description: Check if the graphics driver is ready to process
> +;*              notifications and video extensions.
> +;*
> +;* Usage:       This method is to be called prior to performing any
> +;*              notifications or handling video extensions.
> +;*              Ex: If (PDRD()) {Return (FAIL)}
> +;*
> +;* Input:       None
> +;*
> +;* Output:      None
> +;*
> +;* References:  DRDY (Driver ready status), ASLP (Driver recommended
> +;*              sleep timeout value).
> +;*
> +;*********************************************************
> ***************/
> +
> +Method(PDRD)
> +{
> +  If(LNot(DRDY))
> +  {
> +
> +    // Sleep for ASLP milliseconds if the driver is not ready.
> +
> +    Sleep(ASLP)
> +  }
> +
> +  // If DRDY is clear, the driver is not ready.  If the return value is
> +  // !=0, do not perform any notifications or video extension handling.
> +
> +  Return(LNot(DRDY))
> +}
> +
> +
> +/*********************************************************
> ***************;
> +;*
> +;* Name:        PSTS
> +;*
> +;* Description: Check if the graphics driver has completed the previous
> +;*              "notify" command.
> +;*
> +;* Usage:       This method is called before every "notify" command.  A
> +;*              "notify" should only be set if the driver has completed the
> +;*              previous command.  Else, ignore the event and exit the parent
> +;*              method.
> +;*              Ex: If (PSTS()) {Return (FAIL)}
> +;*
> +;* Input:       None
> +;*
> +;* Output:      None
> +;*
> +;* References:  CSTS (Notification status), ASLP (Driver recommended sleep
> +;*              timeout value).
> +;*
> +;*********************************************************
> ***************/
> +
> +Method(PSTS)
> +{
> +  If(LGreater(CSTS, 2))
> +  {
> +    // Sleep for ASLP milliseconds if the status is not "success,
> +    // failure, or pending"
> +    //
> +    Sleep(ASLP)
> +  }
> +
> +  Return(LEqual(CSTS, 3))         // Return True if still Dispatched
> +}
> +
> +
> +/*********************************************************
> ***************;
> +;*
> +;* Name:        GNOT
> +;*
> +;* Description: Call the appropriate methods to query the graphics driver
> +;*              status.  If all methods return success, do a notification of
> +;*              the graphics device.
> +;*
> +;* Usage:       This method is to be called when a graphics device
> +;*              notification is required (display switch hotkey, etc).
> +;*
> +;* Input:       Arg0 = Current event type:
> +;*                      1 = display switch
> +;*                      2 = lid
> +;*                      3 = dock
> +;*              Arg1 = Notification type:
> +;*                      0 = Re-enumeration
> +;*                      0x80 = Display switch
> +;*
> +;* Output:      Returns 0 = success, 1 = failure
> +;*
> +;* References:  PDRD and PSTS methods.  OSYS (OS version)
> +;*
> +;*********************************************************
> ***************/
> +
> +Method(GNOT, 2)
> +{
> +  // Check for 1. Driver loaded, 2. Driver ready.
> +  // If any of these cases is not met, skip this event and return failure.
> +  //
> +  If(PDRD())
> +  {
> +    Return(0x1)             // Return failure if driver not loaded.
> +  }
> +
> +  Store(Arg0, CEVT)               // Set up the current event value
> +  Store(3, CSTS)                  // CSTS=BIOS dispatched an event
> +
> +  If(LAnd(LEqual(CHPD, 0), LEqual(Arg1, 0)))      // Do not re-enum if driver
> supports hotplug
> +  {
> +    If(LOr(LGreater(OSYS, 2000), LLess(OSYS, 2006)))
> +    {
> +      //
> +      // WINXP requires that the entire PCI Bridge be re-enumerated.
> +      //
> +      Notify(\_SB.PCI0, Arg1)
> +    }
> +    Else
> +    {
> +      //
> +      // Re-enumerate the Graphics Device for non-XP operating systems.
> +      //
> +      Notify(\_SB.PCI0.GFX0, Arg1)
> +    }
> +  }
> +
> +  Notify(\_SB.PCI0.GFX0,0x80)
> +
> +
> +  Return(0x0)                     // Return success
> +}
> +
> +
> +/*********************************************************
> ***************;
> +;*
> +;* Name:        GHDS
> +;*
> +;* Description: Handle a hotkey display switching event (performs a
> +;*              Notify(GFX0, 0).
> +;*
> +;* Usage:       This method must be called when a hotkey event occurs and
> the
> +;*              purpose of that hotkey is to do a display switch.
> +;*
> +;* Input:       Arg0 = Toggle table number.
> +;*
> +;* Output:      Returns 0 = success, 1 = failure.
> +;*              CEVT and TIDX are indirect outputs.
> +;*
> +;* References:  TIDX, GNOT
> +;*
> +;*********************************************************
> ***************/
> +
> +Method(GHDS, 1)
> +{
> +  Store(Arg0, TIDX)               // Store the table number
> +
> +  // Call GNOT for CEVT = 1 = hotkey, notify value = 0
> +
> +  Return(GNOT(1, 0))              // Return stats from GNOT
> +}
> +
> +
> +/*********************************************************
> ***************;
> +;*
> +;* Name:        GLID
> +;*
> +;* Description: Handle a lid event (performs the Notify(GFX0, 0), but not the
> +;*              lid notify).
> +;*
> +;* Usage:       This method must be called when a lid event occurs.  A
> +;*              Notify(LID0, 0x80) must follow the call to this method.
> +;*
> +;* Input:       Arg0 = Lid state:
> +;*                      0 = All closed
> +;*                      1 = internal LFP lid open
> +;*                      2 = external lid open
> +;*                      3 = both external and internal open
> +;*
> +;* Output:      Returns 0=success, 1=failure.
> +;*              CLID and CEVT are indirect outputs.
> +;*
> +;* References:  CLID, GNOT
> +;*
> +;*********************************************************
> ***************/
> +
> +Method(GLID, 1)
> +{
> +  Store(Arg0, CLID)               // Store the current lid state
> +
> +  // Call GNOT for CEVT=2=Lid, notify value = 0
> +
> +  Return(GNOT(2, 0))              // Return stats from GNOT
> +}
> +
> +
> +/*********************************************************
> ***************;
> +;*
> +;* Name:        GDCK
> +;*
> +;* Description: Handle a docking event by updating the current docking
> status
> +;*              and doing a notification.
> +;*
> +;* Usage:       This method must be called when a docking event occurs.
> +;*
> +;* Input:       Arg0 = Docking state:
> +;*                      0 = Undocked
> +;*                      1 = Docked
> +;*
> +;* Output:      Returns 0=success, 1=failure.
> +;*              CDCK and CEVT are indirect outputs.
> +;*
> +;* References:  CDCK, GNOT
> +;*
> +;*********************************************************
> ***************/
> +
> +Method(GDCK, 1)
> +{
> +  Store(Arg0, CDCK)               // Store the current dock state
> +
> +  // Call GNOT for CEVT=4=Dock, notify value = 0
> +
> +  Return(GNOT(4, 0))              // Return stats from GNOT
> +}
> +
> +
> +/*********************************************************
> ***************;
> +;* ASLE Interrupt Methods
> +;*********************************************************
> ***************/
> +
> +
> +/*********************************************************
> ***************;
> +;*
> +;* Name:        PARD
> +;*
> +;* Description: Check if the driver is ready to handle ASLE interrupts
> +;*              generate by the system BIOS.
> +;*
> +;* Usage:       This method must be called before generating each ASLE
> +;*              interrupt.
> +;*
> +;* Input:       None
> +;*
> +;* Output:      Returns 0 = success, 1 = failure.
> +;*
> +;* References:  ARDY (Driver readiness), ASLP (Driver recommended sleep
> +;*              timeout value)
> +;*
> +;*********************************************************
> ***************/
> +
> +Method(PARD)
> +{
> +  If(LNot(ARDY))
> +  {
> +
> +    // Sleep for ASLP milliseconds if the driver is not ready.
> +
> +    Sleep(ASLP)
> +  }
> +
> +  // If ARDY is clear, the driver is not ready.  If the return value is
> +  // !=0, do not generate the ASLE interrupt.
> +
> +  Return(LNot(ARDY))
> +}
> +
> +
> +/*********************************************************
> ***************;
> +;*
> +;* Name:        AINT
> +;*
> +;* Description: Call the appropriate methods to generate an ASLE interrupt.
> +;*              This process includes ensuring the graphics driver is ready
> +;*              to process the interrupt, ensuring the driver supports the
> +;*              interrupt of interest, and passing information about the event
> +;*              to the graphics driver.
> +;*
> +;* Usage:       This method must called to generate an ASLE interrupt.
> +;*
> +;* Input:       Arg0 = ASLE command function code:
> +;*                      0 = Set ALS illuminance
> +;*                      1 = Set backlight brightness
> +;*                      2 = Do Panel Fitting
> +;*              Arg1 = If Arg0 = 0, current ALS reading:
> +;*                      0 = Reading below sensor range
> +;*                      1-0xFFFE = Current sensor reading
> +;*                      0xFFFF = Reading above sensor range
> +;*              Arg1 = If Arg0 = 1, requested backlight percentage
> +;*
> +;* Output:      Returns 0 = success, 1 = failure
> +;*
> +;* References:  PARD method.
> +;*
> +;*********************************************************
> ***************/
> +
> +Method(AINT, 2)
> +{
> +
> +  // Return failure if the requested feature is not supported by the
> +  // driver.
> +
> +  If(LNot(And(TCHE, ShiftLeft(1, Arg0))))
> +  {
> +    Return(0x1)
> +  }
> +
> +  // Return failure if the driver is not ready to handle an ASLE
> +  // interrupt.
> +
> +  If(PARD())
> +  {
> +    Return(0x1)
> +  }
> +
> +  // Evaluate the first argument (Panel fitting, backlight brightness, or ALS).
> +
> +  If(LEqual(Arg0, 2))             // Arg0 = 2, so request a panel fitting mode
> change.
> +  {
> +    If(CPFM)                                        // If current mode field is non-zero use it.
> +    {
> +      And(CPFM, 0x0F, Local0)                 // Create variables without reserved
> +      And(EPFM, 0x0F, Local1)                 // or valid bits.
> +
> +      If(LEqual(Local0, 1))                   // If current mode is centered,
> +      {
> +        If(And(Local1, 6))              // and if stretched is enabled,
> +        {
> +          Store(6, PFIT)          // request stretched.
> +        }
> +        Else                            // Otherwise,
> +        {
> +          If(And(Local1, 8))      // if aspect ratio is enabled,
> +          {
> +            Store(8, PFIT)  // request aspect ratio.
> +          }
> +          Else                    // Only centered mode is enabled
> +          {
> +            Store(1, PFIT)  // so request centered. (No change.)
> +          }
> +        }
> +      }
> +      If(LEqual(Local0, 6))                   // If current mode is stretched,
> +      {
> +        If(And(Local1, 8))              // and if aspect ratio is enabled,
> +        {
> +          Store(8, PFIT)          // request aspect ratio.
> +        }
> +        Else                            // Otherwise,
> +        {
> +          If(And(Local1, 1))      // if centered is enabled,
> +          {
> +            Store(1, PFIT)  // request centered.
> +          }
> +          Else                    // Only stretched mode is enabled
> +          {
> +            Store(6, PFIT)  // so request stretched. (No change.)
> +          }
> +        }
> +      }
> +      If(LEqual(Local0, 8))                   // If current mode is aspect ratio,
> +      {
> +        If(And(Local1, 1))              // and if centered is enabled,
> +        {
> +          Store(1, PFIT)          // request centered.
> +        }
> +        Else                            // Otherwise,
> +        {
> +          If(And(Local1, 6))      // if stretched is enabled,
> +          {
> +            Store(6, PFIT)  // request stretched.
> +          }
> +          Else                    // Only aspect ratio mode is enabled
> +          {
> +            Store(8, PFIT)  // so request aspect ratio. (No change.)
> +          }
> +        }
> +      }
> +    }
> +
> +    // The following code for panel fitting (within the Else condition) is
> retained for backward compatiblity.
> +
> +    Else                            // If CFPM field is zero use PFIT and toggle the
> +    {
> +      Xor(PFIT,7,PFIT)        // mode setting between stretched and centered
> only.
> +    }
> +
> +    Or(PFIT,0x80000000,PFIT)        // Set the valid bit for all cases.
> +
> +    Store(4, ASLC)                  // Store "Panel fitting event" to ASLC[31:1]
> +  }
> +  Else
> +  {
> +    If(LEqual(Arg0, 1))             // Arg0=1, so set the backlight brightness.
> +    {
> +      Store(Divide(Multiply(Arg1, 255), 100), BCLP) // Convert from percent to
> 0-255.
> +
> +      Or(BCLP, 0x80000000, BCLP)      // Set the valid bit.
> +
> +      Store(2, ASLC)                  // Store "Backlight control event" to ASLC[31:1]
> +    }
> +    Else
> +    {
> +      If(LEqual(Arg0, 0))             // Arg0=0, so set the ALS illuminace
> +      {
> +        Store(Arg1, ALSI)
> +
> +        Store(1, ASLC)          // Store "ALS event" to ASLC[31:1]
> +      }
> +      Else
> +      {
> +        Return(0x1) // Unsupported function
> +      }
> +    }
> +  }
> +
> +  Store(0x01, ASLE)               // Generate ASLE interrupt
> +  Return(0x0)                     // Return success
> +}
> +
> +
> +/*********************************************************
> ***************;
> +;*
> +;* Name:        SCIP
> +;*
> +;* Description: Checks the presence of the OpRegion and SCI
> +;*
> +;* Usage:       This method is called before other OpRegion methods. The
> +;*              former "GSMI True/False is not always valid.  This method
> +;*              checks if the OpRegion Version is non-zero and if non-zero,
> +;*              (present and readable) then checks the GSMI flag.
> +;*
> +;* Input:       None
> +;*
> +;* Output:      Boolean True = SCI present.
> +;*
> +;* References:  None
> +;*
> +;*********************************************************
> ***************/
> +
> +Method(SCIP)
> +{
> +  If(LNotEqual(OVER,0))           // If OpRegion Version not 0.
> +  {
> +    Return(LNot(GSMI))      // Return True if SCI.
> +  }
> +
> +  Return(0)                       // Else Return False.
> +}
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOSBCB.ASL
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOSBCB.ASL
> new file mode 100644
> index 0000000000..9e0482efb9
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOSBCB.ASL
> @@ -0,0 +1,274 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  IgdOSBCB.ASL
> +
> +Abstract:
> +
> +  IGD OpRegion/Software SCI Reference Code for the Baytrail Family.
> +  This file contains the system BIOS call back functionality for the
> +  OpRegion/Software SCI mechanism.
> +
> +--*/
> +
> +
> +Method (SBCB, 0, Serialized)
> +{
> +
> +  // Supported Callbacks: Sub-function 0
> +
> +  If (LEqual(GESF, 0x0))
> +  {
> +
> +    //<TODO> An OEM may support the driver->SBIOS status callbacks, but
> +    // the supported callbacks value must be modified.  The code that is
> +    // executed upon reception of the callbacks must be also be updated
> +    // to perform the desired functionality.
> +
> +    Store(0x00000000, PARM)         // No callbacks supported
> +
> +    If(LEqual(PFLV,FMBL))
> +    {
> +      Store(0x000F87FD, PARM)         // Mobile
> +    }
> +    If(LEqual(PFLV,FDTP))
> +    {
> +      Store(0x000F87BD, PARM)         // Desktop
> +    }
> +
> +    Store(Zero, GESF)               // Clear the exit parameter
> +    Return(SUCC)                    // "Success"
> +  }
> +
> +  // BIOS POST Completion: Sub-function 1
> +
> +  If (LEqual(GESF, 1))
> +  {
> +    Store(Zero, GESF)               // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)                    // Not supported, but no failure
> +  }
> +
> +  // Pre-Hires Set Mode: Sub-function 3
> +
> +  If (LEqual(GESF, 3))
> +  {
> +    Store(Zero, GESF)               // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)                    // Not supported, but no failure
> +  }
> +
> +  // Post-Hires Set Mode: Sub-function 4
> +
> +  If (LEqual(GESF, 4))
> +  {
> +    Store(Zero, GESF)               // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)                    // Not supported, but no failure
> +  }
> +
> +  // Display Switch: Sub-function 5
> +
> +  If (LEqual(GESF, 5))
> +  {
> +    Store(Zero, GESF)               // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)                    // Not supported, but no failure
> +  }
> +
> +  // Set TV format: Sub-function 6
> +
> +  If (LEqual(GESF, 6))
> +  {
> +
> +    //<TODO> If implemented, the input values must be saved into
> +    // non-volatile storage for parsing during the next boot.  The
> +    // following Sample code is Intel validated implementation.
> +
> +    Store(And(PARM, 0x0F), ITVF)
> +    Store(ShiftRight(And(PARM, 0xF0), 4), ITVM)
> +    Store(Zero, GESF)               // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)
> +  }
> +
> +  // Adapter Power State: Sub-function 7
> +
> +  If (LEqual(GESF, 7))
> +  {
> +
> +    // Upon notification from driver that the Adapter Power State = D0,
> +    // check if previous lid event failed.  If it did, retry the lid
> +    // event here.
> +    If(LEqual(PARM, 0))
> +    {
> +      Store(CLID, Local0)
> +      If(And(0x80000000,Local0))
> +      {
> +        And(CLID, 0x0000000F, CLID)
> +        GLID(CLID)
> +      }
> +    }
> +    Store(Zero, GESF)               // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)                    // Not supported, but no failure
> +  }
> +
> +  // Display Power State: Sub-function 8
> +
> +  If (LEqual(GESF, 8))
> +  {
> +    Store(Zero, GESF)               // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)                    // Not supported, but no failure
> +  }
> +
> +  // Set Boot Display: Sub-function 9
> +
> +  If (LEqual(GESF, 9))
> +  {
> +
> +    //<TODO> An OEM may elect to implement this method.  In that case,
> +    // the input values must be saved into non-volatile storage for
> +    // parsing during the next boot.  The following Sample code is Intel
> +    // validated implementation.
> +
> +    And(PARM, 0xFF, IBTT)           // Save the boot display to NVS
> +    Store(Zero, GESF)               // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)                    // Reserved, "Critical failure"
> +  }
> +
> +  // Set Panel Details: Sub-function 10 (0Ah)
> +
> +  If (LEqual(GESF, 10))
> +  {
> +
> +    //<TODO> An OEM may elect to implement this method.  In that case,
> +    // the input values must be saved into non-volatile storage for
> +    // parsing during the next boot.  The following Sample code is Intel
> +    // validated implementation.
> +
> +    // Set the panel-related NVRAM variables based the input from the driver.
> +
> +    And(PARM, 0xFF, IPSC)
> +
> +    // Change panel type if a change is requested by the driver (Change if
> +    // panel type input is non-zero).  Zero=No change requested.
> +
> +    If(And(ShiftRight(PARM, 8), 0xFF))
> +    {
> +      And(ShiftRight(PARM, 8), 0xFF, IPAT)
> +      Decrement(IPAT)         // 0 = no change, so fit to CMOS map
> +    }
> +    And(ShiftRight(PARM, 18), 0x3, IBLC)
> +    And(ShiftRight(PARM, 20), 0x7, IBIA)
> +    Store(Zero, GESF)               // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)                    // Success
> +  }
> +
> +  // Set Internal Graphics: Sub-function 11 (0Bh)
> +
> +  If (LEqual(GESF, 11))
> +  {
> +
> +    //<TODO> An OEM may elect to implement this method.  In that case,
> +    // the input values must be saved into non-volatile storage for
> +    // parsing during the next boot.  The following Sample code is Intel
> +    // validated implementation.
> +
> +    And(ShiftRight(PARM, 1), 1, IF1E) // Program the function 1 option
> +
> +    // Fixed memory/DVMT memory
> +
> +    And(ShiftRight(PARM, 17), 0xF, IDMS) // Program DVMT/fixed memory
> size
> +
> +    Store(Zero, GESF)               // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)                    // Success
> +  }
> +
> +  // Post-Hires to DOS FS: Sub-function 16 (10h)
> +
> +  If (LEqual(GESF, 16))
> +  {
> +    Store(Zero, GESF)               // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)                    // Not supported, but no failure
> +  }
> +
> +  // APM Complete:  Sub-function 17 (11h)
> +
> +  If (LEqual(GESF, 17))
> +  {
> +
> +    Store(ShiftLeft(LIDS, 8), PARM) // Report the lid state
> +    Add(PARM, 0x100, PARM)          // Adjust the lid state, 0 = Unknown
> +
> +    Store(Zero, GESF)               // Clear the exit parameter
> +    Return(SUCC)                    // Not supported, but no failure
> +  }
> +
> +  // Set Spread Spectrum Clocks: Sub-function 18 (12h)
> +
> +  If (LEqual(GESF, 18))
> +  {
> +
> +    //<TODO> An OEM may elect to implement this method.  In that case,
> +    // the input values must be saved into non-volatile storage for
> +    // parsing during the next boot.  The following Sample code is Intel
> +    // validated implementation.
> +
> +    If(And(PARM, 1))
> +    {
> +      If(LEqual(ShiftRight(PARM, 1), 1))
> +      {
> +        Store(1, ISSC)  // Enable HW SSC, only for clock 1
> +      }
> +      Else
> +      {
> +        Store(Zero, GESF)
> +        Return(CRIT)    // Failure, as the SSC clock must be 1
> +      }
> +    }
> +    Else
> +    {
> +      Store(0, ISSC)          // Disable SSC
> +    }
> +    Store(Zero, GESF)               // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)                    // Success
> +  }
> +
> +  // Post VBE/PM Callback: Sub-function 19 (13h)
> +
> +  If (LEqual(GESF, 19))
> +  {
> +    Store(Zero, GESF)               // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)                    // Not supported, but no failure
> +  }
> +
> +  // Set PAVP Data: Sub-function 20 (14h)
> +
> +  If (LEqual(GESF, 20))
> +  {
> +    And(PARM, 0xF, PAVP)    // Store PAVP info
> +    Store(Zero, GESF)               // Clear the exit parameter
> +    Store(Zero, PARM)
> +    Return(SUCC)                    // Success
> +  }
> +
> +  // A call to a reserved "System BIOS callbacks" function was received
> +
> +  Store(Zero, GESF)                     // Clear the exit parameter
> +  Return(SUCC)                          // Reserved, "Critical failure"
> +}
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOpRn.ASL
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOpRn.ASL
> new file mode 100644
> index 0000000000..8575fbfe6c
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOpRn.ASL
> @@ -0,0 +1,299 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  IgdOpRn.ASL
> +
> +Abstract:
> +
> +  IGD OpRegion/Software SCI Reference Code for the Baytrail Family.
> +  This file contains the interrupt handler code for the Integrated
> +  Graphics Device (IGD) OpRegion/Software SCI mechanism.
> +
> +--*/
> +
> +
> +//NOTES:
> +//
> +// (1)  The code contained in this file inherits the scope in which it
> +//      was included.  So BIOS developers must be sure to include this
> +//      file in the scope associated with the graphics device
> +//      (ex. \_SB.PCI0.GFX0).
> +// (2)  Create a _L06 method under the GPE scope to handle the event
> +//      generated by the graphics driver.  The _L06 method must call
> +//      the GSCI method in this file.
> +// (3)  The MCHP operation region assumes that _ADR and _BBN names
> +//      corresponding to bus 0, device0, function 0 have been declared
> +//      under the PCI0 scope.
> +// (4)  Before the first execution of the GSCI method, the base address
> +//      of the GMCH SCI OpRegion must be programmed where the driver can
> +//      access it. A 32bit scratch register at 0xFC in the IGD PCI
> +//      configuration space (B0/D2/F0/R0FCh) is used for this purpose.
> +
> +//  Define an OperationRegion to cover the GMCH PCI configuration space
> as
> +//  described in the IGD OpRegion specificiation.
> +
> +//  Define an OperationRegion to cover the IGD PCI configuration space as
> +//  described in the IGD OpRegion specificiation.
> +
> +OperationRegion(IGDP, PCI_Config,0x00,0x100)
> +Field(IGDP, AnyAcc, NoLock, Preserve)
> +{
> +  Offset(0x10),  // GTTMMADR
> +  MADR,   32,
> +  Offset(0x50),  // GMCH Graphics Control Register
> +  ,   1,
> +  GIVD,   1,     // IGD VGA disable bit
> +  ,   1,
> +  GUMA,   5,     // Stolen memory size
> +  ,   8,
> +  Offset(0x54),
> +  ,   4,
> +  GMFN,   1,     // Gfx function 1 enable
> +  ,   27,
> +  Offset(0x5C),  // Stolen Memory Base Address
> +  GSTM,   32,
> +  Offset(0xE0),  // Reg 0xE8, SWSCI control register
> +  GSSE,   1,     // Graphics SCI event (1=event pending)
> +  GSSB,   14,    // Graphics SCI scratchpad bits
> +  GSES,   1,     // Graphics event select (1=SCI)
> +  Offset(0xE4),
> +  ASLE,   8,     // Reg 0xE4, ASLE interrupt register
> +  ,   24,    // Only use first byte of ASLE reg
> +  Offset(0xFC),
> +  ASLS,   32,    // Reg 0xFC, Address of the IGD OpRegion
> +}
> +
> +Method (MCHK, 0, Serialized)
> +{
> +
> +  If (LNotEqual (MADR, 0xFFFFFFFF))
> +  {
> +    OperationRegion(IGMM,SystemMemory,MADR,0x3000)
> +    Field(IGMM,AnyAcc, NoLock, Preserve)
> +    {
> +      Offset(0X20C8),
> +      ,    4,
> +      DCFE,    4,                     // DISPLAY_CLOCK_FREQUENCY_ENCODING
> +    }
> +  }
> +}
> +
> +
> +//  Define an OperationRegion to cover the IGD OpRegion layout.
> +
> +OperationRegion(IGDM, SystemMemory, ASLB, 0x2000)
> +Field(IGDM, AnyAcc, NoLock, Preserve)
> +{
> +
> +  // OpRegion Header
> +
> +  SIGN,   128,                    // Signature-"IntelGraphicsMem"
> +  SIZE,   32,                     // OpRegion Size
> +  OVER,   32,                     // OpRegion Version
> +  SVER,   256,                    // System BIOS Version
> +  VVER,   128,                    // VBIOS Version
> +  GVER,   128,                    // Driver version
> +  MBOX,   32,                     // Mailboxes supported
> +  DMOD,   32,                     // Driver Model
> +  PCON,   32,                     // 96, Platform Configuration
> +
> +  // OpRegion Mailbox 1 (Public ACPI Methods)
> +  // Note: Mailbox 1 is normally reserved for desktop platforms.
> +
> +  Offset(0x100),
> +  DRDY,   32,                     // Driver readiness (ACPI notification)
> +  CSTS,   32,                     // Notification status
> +  CEVT,   32,                     // Current event
> +  Offset(0x120),
> +  DIDL,   32,                     // Supported display device ID list
> +  DDL2,   32,                     // Allows for 8 devices
> +  DDL3,   32,
> +  DDL4,   32,
> +  DDL5,   32,
> +  DDL6,   32,
> +  DDL7,   32,
> +  DDL8,   32,
> +  CPDL,   32,                     // Currently present display list
> +  CPL2,   32,                     // Allows for 8 devices
> +  CPL3,   32,
> +  CPL4,   32,
> +  CPL5,   32,
> +  CPL6,   32,
> +  CPL7,   32,
> +  CPL8,   32,
> +  CAD1,   32,                     // Currently active display list
> +  CAL2,   32,                     // Allows for 8 devices
> +  CAL3,   32,
> +  CAL4,   32,
> +  CAL5,   32,
> +  CAL6,   32,
> +  CAL7,   32,
> +  CAL8,   32,
> +  NADL,   32,                     // Next active display list
> +  NDL2,   32,                     // Allows for 8 devices
> +  NDL3,   32,
> +  NDL4,   32,
> +  NDL5,   32,
> +  NDL6,   32,
> +  NDL7,   32,
> +  NDL8,   32,
> +  ASLP,   32,                     // ASL sleep timeout
> +  TIDX,   32,                     // Toggle table index
> +  CHPD,   32,                     // Current hot plug enable indicator
> +  CLID,   32,                     // Current lid state indicator
> +  CDCK,   32,                     // Current docking state indicator
> +  SXSW,   32,                     // Display switch notify on resume
> +  EVTS,   32,                     // Events supported by ASL (diag only)
> +  CNOT,   32,                     // Current OS notifications (diag only)
> +  NRDY,   32,
> +
> +  // OpRegion Mailbox 2 (Software SCI Interface)
> +
> +  Offset(0x200),                  // SCIC
> +  SCIE,   1,                      // SCI entry bit (1=call unserviced)
> +  GEFC,   4,                      // Entry function code
> +  GXFC,   3,                      // Exit result
> +  GESF,   8,                      // Entry/exit sub-function/parameter
> +  ,   16,                     // SCIC[31:16] reserved
> +  Offset(0x204),                  // PARM
> +  PARM,   32,                     // PARM register (extra parameters)
> +  DSLP,   32,                     // Driver sleep time out
> +
> +  // OpRegion Mailbox 3 (BIOS to Driver Notification)
> +  // Note: Mailbox 3 is normally reserved for desktop platforms.
> +
> +  Offset(0x300),
> +  ARDY,   32,                     // Driver readiness (power conservation)
> +  ASLC,   32,                     // ASLE interrupt command/status
> +  TCHE,   32,                     // Technology enabled indicator
> +  ALSI,   32,                     // Current ALS illuminance reading
> +  BCLP,   32,                     // Backlight brightness
> +  PFIT,   32,                     // Panel fitting state or request
> +  CBLV,   32,                     // Current brightness level
> +  BCLM,   320,                    // Backlight brightness level duty cycle mapping table
> +  CPFM,   32,                     // Current panel fitting mode
> +  EPFM,   32,                     // Enabled panel fitting modes
> +  PLUT,   592,                    // Optional. 74-byte Panel LUT Table
> +  PFMB,   32,                     // Optional. PWM Frequency and Minimum
> Brightness
> +  CCDV,   32,                     // Optional. Gamma, Brightness, Contrast values.
> +  PCFT,   32,                     // Optional. Power Conservation Features
> +
> +  Offset(0x3B6),
> +  STAT,   32,                     // Status register
> +
> +  // OpRegion Mailbox 4 (VBT)
> +
> +  Offset(0x400),
> +  GVD1,   0xC000,                 // 6K bytes maximum VBT image
> +
> +  // OpRegion Mailbox 5 (BIOS to Driver Notification Extension)
> +
> +  Offset(0x1C00),
> +  PHED,   32,                     // Panel Header
> +  BDDC,   2048,                   // Panel EDID (Max 256 bytes)
> +
> +}
> +
> +
> +
> +// Convert boot display type into a port mask.
> +
> +Name (DBTB, Package()
> +{
> +  0x0000,                         // Automatic
> +  0x0007,                         // Port-0 : Integrated CRT
> +  0x0038,                         // Port-1 : DVO-A, or Integrated LVDS
> +  0x01C0,                         // Port-2 : SDVO-B, or SDVO-B/C
> +  0x0E00,                         // Port-3 : SDVO-C
> +  0x003F,                         // [CRT + DVO-A / Integrated LVDS]
> +  0x01C7,                         // [CRT + SDVO-B] or [CRT + SDVO-B/C]
> +  0x0E07,                         // [CRT + SDVO-C]
> +  0x01F8,                         // [DVO-A / Integrated LVDS + SDVO-B]
> +  0x0E38,                         // [DVO-A / Integrated LVDS + SDVO-C]
> +  0x0FC0,                         // [SDVO-B + SDVO-C]
> +  0x0000,                         // Reserved
> +  0x0000,                         // Reserved
> +  0x0000,                         // Reserved
> +  0x0000,                         // Reserved
> +  0x0000,                         // Reserved
> +  0x7000,                         // Port-4: Integrated TV
> +  0x7007,                         // [Integrated TV + CRT]
> +  0x7038,                         // [Integrated TV + LVDS]
> +  0x71C0,                         // [Integrated TV + DVOB]
> +  0x7E00                          // [Integrated TV + DVOC]
> +})
> +
> +// Core display clock value table.
> +
> +Name (CDCT, Package()
> +{
> +  Package() {160},
> +  Package() {200},
> +  Package() {267},
> +  Package() {320},
> +  Package() {356},
> +  Package() {400},
> +})
> +
> +// Defined exit result values:
> +
> +Name (SUCC, 1)                          // Exit result: Success
> +Name (NVLD, 2)                          // Exit result: Invalid parameter
> +Name (CRIT, 4)                          // Exit result: Critical failure
> +Name (NCRT, 6)                          // Exit result: Non-critical failure
> +
> +
> +/*********************************************************
> ***************;
> +;*
> +;* Name: GSCI
> +;*
> +;* Description: Handles an SCI generated by the graphics driver.  The
> +;*              PARM and SCIC input fields are parsed to determine the
> +;*              functionality requested by the driver.  GBDA or SBCB
> +;*              is called based on the input data in SCIC.
> +;*
> +;* Usage:       The method must be called in response to a GPE 06 event
> +;*              which will be generated by the graphics driver.
> +;*              Ex: Method(\_GPE._L06) {Return(\_SB.PCI0.GFX0.GSCI())}
> +;*
> +;* Input:       PARM and SCIC are indirect inputs
> +;*
> +;* Output:      PARM and SIC are indirect outputs
> +;*
> +;* References:  GBDA (Get BIOS Data method), SBCB (System BIOS Callback
> +;*              method)
> +;*
> +;*********************************************************
> ***************/
> +
> +Method (GSCI, 0, Serialized)
> +{
> +  Include("IgdOGBDA.ASL") // "Get BIOS Data" Functions
> +  Include("IgdOSBCB.ASL") // "System BIOS CallBacks"
> +
> +  If (LEqual(GEFC, 4))
> +  {
> +    Store(GBDA(), GXFC)     // Process Get BIOS Data functions
> +  }
> +
> +  If (LEqual(GEFC, 6))
> +  {
> +    Store(SBCB(), GXFC)     // Process BIOS Callback functions
> +  }
> +
> +  Store(0, GEFC)                  // Wipe out the entry function code
> +  Store(1, SCIS)                  // Clear the GUNIT SCI status bit in PCH ACPI I/O
> space.
> +  Store(0, GSSE)                  // Clear the SCI generation bit in PCI space.
> +  Store(0, SCIE)                  // Clr SCI serviced bit to signal completion
> +
> +  Return(Zero)
> +}
> +
> +// Include MOBLFEAT.ASL for mobile systems only.  Remove for desktop.
> +Include("IgdOMOBF.ASL")     // IGD SCI mobile features
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IoTVirtualDevice.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IoTVirtualDevice.asl
> new file mode 100644
> index 0000000000..320b36ffb2
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IoTVirtualDevice.asl
> @@ -0,0 +1,171 @@
> +/** @file
> +Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +Device(IOTD) {
> +  Name(_HID, "MSFT8000")
> +  Name(_CID, "MSFT8000")
> +
> +  Name(_CRS, ResourceTemplate() {
> +    // Index 0
> +    SPISerialBus(            // Pin 5, 7, 9 , 11 of JP1 for SIO_SPI
> +      1,                     // Device selection
> +      PolarityLow,           // Device selection polarity
> +      FourWireMode,          // wiremode
> +      8,                     // databit len
> +      ControllerInitiated,   // slave mode
> +      8000000,               // Connection speed
> +      ClockPolarityLow,      // Clock polarity
> +      ClockPhaseSecond,      // clock phase
> +      "\\_SB.SPI1",          // ResourceSource: SPI bus controller name
> +      0,                     // ResourceSourceIndex
> +      ResourceConsumer,      // Resource usage
> +      JSPI,                  // DescriptorName: creates name for offset of resource
> descriptor
> +      )                      // Vendor Data
> +
> +    // Index 1
> +    I2CSerialBus(            // Pin 13, 15 of JP1, for SIO_I2C5 (signal)
> +      0x00,                  // SlaveAddress: bus address (TBD)
> +      ,                      // SlaveMode: default to ControllerInitiated
> +      400000,                // ConnectionSpeed: in Hz
> +      ,                      // Addressing Mode: default to 7 bit
> +      "\\_SB.I2C6",          // ResourceSource: I2C bus controller name (For
> MinnowBoard Max, hardware I2C5(0-based) is reported as ACPI I2C6(1-
> based))
> +      ,
> +      ,
> +      JI2C,                  // Descriptor Name: creates name for offset of resource
> descriptor
> +      )                      // VendorData
> +
> +    // Index 2
> +    UARTSerialBus(           // Pin 17, 19 of JP1, for SIO_UART2
> +      115200,                // InitialBaudRate: in bits ber second
> +      ,                      // BitsPerByte: default to 8 bits
> +      ,                      // StopBits: Defaults to one bit
> +      0xfc,                  // LinesInUse: 8 1-bit flags to declare line enabled
> +      ,                      // IsBigEndian: default to LittleEndian
> +      ,                      // Parity: Defaults to no parity
> +      ,                      // FlowControl: Defaults to no flow control
> +      32,                    // ReceiveBufferSize
> +      32,                    // TransmitBufferSize
> +      "\\_SB.URT2",          // ResourceSource: UART bus controller name
> +      ,
> +      ,
> +      UAR2,                  // DescriptorName: creates name for offset of resource
> descriptor
> +      )
> +
> +    // Index 3
> +    GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO2",) {0}
> // Pin 21 of JP1 (GPIO_S5[00])
> +    // Index 4
> +    GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO2",)
> {0}
> +
> +    // Index 5
> +    GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO2",) {1}
> // Pin 23 of JP1 (GPIO_S5[01])
> +    // Index 6
> +    GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO2",)
> {1}
> +
> +    // Index 7
> +    GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO2",) {2}
> // Pin 25 of JP1 (GPIO_S5[02])
> +    // Index 8
> +    GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO2",)
> {2}
> +
> +    // Index 9
> +    UARTSerialBus(           // Pin 6, 8, 10, 12 of JP1, for SIO_UART1
> +      115200,                // InitialBaudRate: in bits ber second
> +      ,                      // BitsPerByte: default to 8 bits
> +      ,                      // StopBits: Defaults to one bit
> +      0xfc,                  // LinesInUse: 8 1-bit flags to declare line enabled
> +      ,                      // IsBigEndian: default to LittleEndian
> +      ,                      // Parity: Defaults to no parity
> +      FlowControlHardware,   // FlowControl: Defaults to no flow control
> +      32,                    // ReceiveBufferSize
> +      32,                    // TransmitBufferSize
> +      "\\_SB.URT1",          // ResourceSource: UART bus controller name
> +      ,
> +      ,
> +      UAR1,              // DescriptorName: creates name for offset of resource
> descriptor
> +      )
> +
> +    // Index 10
> +    GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {62}
> // Pin 14 of JP1 (GPIO_SC[62])
> +    // Index 11
> +    GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",)
> {62}
> +
> +    // Index 12
> +    GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {63}
> // Pin 16 of JP1 (GPIO_SC[63])
> +    // Index 13
> +    GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",)
> {63}
> +
> +    // Index 14
> +    GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {65}
> // Pin 18 of JP1 (GPIO_SC[65])
> +    // Index 15
> +    GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",)
> {65}
> +
> +    // Index 16
> +    GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {64}
> // Pin 20 of JP1 (GPIO_SC[64])
> +    // Index 17
> +    GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",)
> {64}
> +
> +    // Index 18
> +    GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {94}
> // Pin 22 of JP1 (GPIO_SC[94])
> +    // Index 19
> +    GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",)
> {94}
> +
> +    // Index 20
> +    GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {95}
> // Pin 24 of JP1 (GPIO_SC[95])
> +    // Index 21
> +    GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",)
> {95}
> +
> +    // Index 22
> +    GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",) {54}
> // Pin 26 of JP1 (GPIO_SC[54])
> +    // Index 23
> +    GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone, 0,"\\_SB.GPO0",)
> {54}
> +  })
> +
> +  Name(_DSD, Package() {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package(1) {	  // Just one Property for IOT (at this time)
> +      Package(2) {	//The �symbolic-identifiers� property
> +        "symbolic-identifiers",
> +        Package() {	//Contains all the <resource index, symbolic-
> identifier> pairs
> +          0, "SPI0",
> +          1, "I2C5",
> +          2, "UART2",
> +          3, 21,       // Pin 21 of JP1 (GPIO_S5[00])
> +          4, 21,       // Pin 21 for separate resource.
> +          5, 23,       // Pin 23 of JP1 (GPIO_S5[01])
> +          6, 23,
> +          7, 25,       // Pin 25 of JP1 (GPIO_S5[02])
> +          8, 25,
> +          9, "UART1",
> +          10, 14,      // Pin 14 of JP1 (GPIO_SC[62])
> +          11, 14,
> +          12, 16,      // Pin 16 of JP1 (GPIO_SC[63])
> +          13, 16,
> +          14, 18,      // Pin 18 of JP1 (GPIO_SC[65])
> +          15, 18,
> +          16, 20,      // Pin 20 of JP1 (GPIO_SC[64])
> +          17, 20,
> +          18, 22,      // Pin 22 of JP1 (GPIO_SC[94])
> +          19, 22,
> +          20, 24,      // Pin 24 of JP1 (GPIO_SC[95])
> +          21, 24,
> +          22, 26,      // Pin 26 of JP1 (GPIO_SC[54])
> +          23, 26
> +        }
> +      }
> +    }
> +  })
> +
> +  Method(_STA,0,Serialized) {
> +
> +    //
> +    // Only report IoT virtual device when all pins' configuration follows
> MSFT's datasheet.
> +    //
> +    If (LEqual(IOT, 1)) {
> +      Return (0xF)
> +    }
> +
> +    Return (0x0)
> +  }
> +}
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LPC_DEV.ASL
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LPC_DEV.ASL
> new file mode 100644
> index 0000000000..7367f4c77c
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LPC_DEV.ASL
> @@ -0,0 +1,151 @@
> +/*********************************************************
> *****************;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
> +;*    Family of Customer Reference Boards.                                *;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved    *;
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*********************************************************
> *****************/
> +
> +Device(FWHD) // Firmware Hub Device
> +{
> +  Name(_HID,EISAID("INT0800"))
> +
> +  Name(_CRS,ResourceTemplate()
> +  {
> +    Memory32Fixed(ReadOnly,0xFF000000,0x1000000)
> +  })
> +}
> +
> +Device(IPIC) // 8259 PIC
> +{
> +  Name(_HID,EISAID("PNP0000"))
> +
> +  Name(_CRS,ResourceTemplate()
> +  {
> +    IO(Decode16,0x20,0x20,0x01,0x02)
> +    IO(Decode16,0x24,0x24,0x01,0x02)
> +    IO(Decode16,0x28,0x28,0x01,0x02)
> +    IO(Decode16,0x2C,0x2C,0x01,0x02)
> +    IO(Decode16,0x30,0x30,0x01,0x02)
> +    IO(Decode16,0x34,0x34,0x01,0x02)
> +    IO(Decode16,0x38,0x38,0x01,0x02)
> +    IO(Decode16,0x3C,0x3C,0x01,0x02)
> +    IO(Decode16,0xA0,0xA0,0x01,0x02)
> +    IO(Decode16,0xA4,0xA4,0x01,0x02)
> +    IO(Decode16,0xA8,0xA8,0x01,0x02)
> +    IO(Decode16,0xAC,0xAC,0x01,0x02)
> +    IO(Decode16,0xB0,0xB0,0x01,0x02)
> +    IO(Decode16,0xB4,0xB4,0x01,0x02)
> +    IO(Decode16,0xB8,0xB8,0x01,0x02)
> +    IO(Decode16,0xBC,0xBC,0x01,0x02)
> +    IO(Decode16,0x4D0,0x4D0,0x01,0x02)
> +    IRQNoFlags() {2}
> +  })
> +}
> +
> +Device(LDRC) // LPC Device Resource Consumption
> +{
> +  Name(_HID,EISAID("PNP0C02"))
> +
> +  Name(_UID,2)
> +
> +  Name(_CRS,ResourceTemplate()
> +  {
> +    IO(Decode16,0x4E,0x4E,0x1,0x02)         // LPC Slot Access.
> +    IO(Decode16,0x61,0x61,0x1,0x1)          // NMI Status.
> +    IO(Decode16,0x63,0x63,0x1,0x1)          // Processor I/F.
> +    IO(Decode16,0x65,0x65,0x1,0x1)          // Processor I/F.
> +    IO(Decode16,0x67,0x67,0x1,0x1)          // Processor I/F.
> +    IO(Decode16,0x70,0x70,0x1,0x1)          // NMI Enable.
> +    IO(Decode16,0x80,0x80,0x1,0x10)         // Postcode.
> +    IO(Decode16,0x92,0x92,0x1,0x1)          // Processor I/F.
> +    IO(Decode16,0xB2,0xB2,0x01,0x02)        // Software SMI.
> +    IO(Decode16,0x680,0x680,0x1,0x20)       // 32 Byte I/O.
> +    IO(Decode16,0x400,0x400,0x1,0x80)       // ACPI Base.
> +    IO(Decode16,0x500,0x500,0x1,0xFF)       // GPIO Base.
> +  })
> +}
> +
> +Device(TIMR) // 8254 Timer
> +{
> +  Name(_HID,EISAID("PNP0100"))
> +
> +  Name(_CRS,ResourceTemplate()
> +  {
> +    IO(Decode16,0x40,0x40,0x01,0x04)
> +    IO(Decode16,0x50,0x50,0x10,0x04)
> +    IRQNoFlags() {0}
> +  })
> +}
> +
> +Device(IUR3) // Internal UART
> +{
> +  Name(_HID, EISAID("PNP0501"))
> +
> +  Name(_UID,1)
> +
> +  // Status Method for internal UART
> +
> +  Method(_STA,0,Serialized)
> +  {
> +    // Only report resources to the OS if internal UART is
> +    // not set to Disabled in BIOS Setup.
> +
> +    If(LEqual(USEL,0))
> +    {
> +      If(LEqual(PU1E,1))
> +      {
> +        Store(1,UI3E) // Enable IRQ3 for UART
> +        Store(1,UI4E) // Enable IRQ4 for UART
> +        Store(1,C1EN) // Enable UART
> +        Return(0x000F)
> +      }
> +    }
> +
> +    Return(0x0000)
> +  }
> +
> +  // Disable Method for internal UART
> +
> +  Method(_DIS,0,Serialized)
> +  {
> +    Store(0,UI3E)
> +    Store(0,UI4E)
> +    Store(0,C1EN)
> +  }
> +
> +  // Current Resource Setting Method for internal UART
> +
> +  Method(_CRS,0,Serialized)
> +  {
> +    // Create the Buffer that stores the Resources to
> +    // be returned.
> +
> +    Name(BUF0,ResourceTemplate()
> +    {
> +      IO(Decode16,0x03F8,0x03F8,0x01,0x08)
> +      IRQNoFlags() {3}
> +    })
> +
> +    Name(BUF1,ResourceTemplate()
> +    {
> +      IO(Decode16,0x03F8,0x03F8,0x01,0x08)
> +      IRQNoFlags() {4}
> +    })
> +
> +    If (LLessEqual(SRID, 0x04))
> +    {
> +      Return(BUF0)
> +    } Else
> +    {
> +      Return(BUF1)
> +    }
> +  }
> +}
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LpcB.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LpcB.asl
> new file mode 100644
> index 0000000000..157c149d0a
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LpcB.asl
> @@ -0,0 +1,59 @@
> +/*********************************************************
> *****************;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
> +;*    Family of Customer Reference Boards.                                *;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved    *;
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*********************************************************
> *****************/
> +
> +
> +// LPC Bridge - Device 31, Function 0
> +// Define the needed LPC registers used by ASL.
> +
> +scope(\_SB)
> +{
> +  OperationRegion(ILBR, SystemMemory, \IBAS, 0x8C)
> +  Field(ILBR, AnyAcc, NoLock, Preserve)
> +  {
> +    Offset(0x08), // 0x08
> +    PARC,   8,
> +    PBRC,   8,
> +    PCRC,   8,
> +    PDRC,   8,
> +    PERC,   8,
> +    PFRC,   8,
> +    PGRC,   8,
> +    PHRC,   8,
> +    Offset(0x88), // 0x88
> +    ,       3,
> +    UI3E,   1,
> +    UI4E,   1
> +  }
> +
> +  Include ("98_LINK.ASL")
> +}
> +
> +OperationRegion(LPC0, PCI_Config, 0x00, 0xC0)
> +Field(LPC0, AnyAcc, NoLock, Preserve)
> +{
> +  Offset(0x08), // 0x08
> +  SRID,   8,  // Revision ID
> +  Offset(0x080), // 0x80
> +  C1EN,   1, // COM1 Enable
> +  ,      31
> +}
> +
> +
> +Include ("LPC_DEV.ASL")
> +
> +
> +
> +
> +
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Lpit/Lpit.aslc
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Lpit/Lpit.aslc
> new file mode 100644
> index 0000000000..9847ec3a12
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Lpit/Lpit.aslc
> @@ -0,0 +1,223 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +--*/
> +
> +//
> +// Include files
> +//
> +
> +#include <PiDxe.h>
> +#include <IndustryStandard/Acpi50.h>
> +
> +
> +
> +//
> +// LPIT Definitions
> +//
> +
> +#define EFI_ACPI_LOW_POWER_IDLE_TABLE_REVISION 0x1
> +
> +//
> +// Ensure proper structure formats
> +//
> +#pragma pack(1)
> +
> +typedef union _EFI_ACPI_LPI_STATE_FLAGS {
> +  struct {
> +    UINT32 Disabled           :1;
> +    UINT32 CounterUnavailable :1;
> +    UINT32 Reserved           :30;
> +  };
> +  UINT32 AsUlong;
> +} EFI_ACPI_LPI_STATE_FLAGS, *PEFI_ACPI_LPI_STATE_FLAGS;
> +
> +// Only Mwait LPI here:
> +
> +typedef struct _EFI_ACPI_MWAIT_LPI_STATE_DESCRIPTOR {
> +  UINT32 Type;        // offset: 0
> +  UINT32 Length;      // offset: 4
> +  UINT16 UniqueId;    // offset: 8
> +  UINT8 Reserved[2];  // offset: 9
> +  EFI_ACPI_LPI_STATE_FLAGS Flags; // offset: 12
> +  EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE EntryTrigger; // offset: 16
> +  UINT32 Residency;   // offset: 28
> +  UINT32 Latency;     // offset: 32
> +  EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE ResidencyCounter; //
> offset: 36
> +  UINT64 ResidencyCounterFrequency; //offset: 48
> +} EFI_ACPI_MWAIT_LPI_STATE_DESCRIPTOR;
> +
> +
> +//
> +// Defines for LPIT table, some are VLV specific
> +//
> +
> +
> +// signature "LPIT"
> +#define EFI_ACPI_LOW_POWER_IDLE_TABLE_SIGNATURE  0x5449504c
> +
> +#define EFI_ACPI_OEM_LPIT_REVISION                      0x00000000
> +
> +#define EFI_ACPI_LOW_POWER_IDLE_MWAIT_TYPE    0x0
> +#define EFI_ACPI_LOW_POWER_IDLE_DEFAULT_FLAG  0x0
> +#define EFI_ACPI_LOW_POWER_IDLE_RES_FREQ_8K   0x8000    // 32768
> +
> +//
> +// LPI state count (4 on VLV: S0ir, S0i1, S0i2, S0i3)
> +//
> +
> +#define EFI_ACPI_VLV_LPI_STATE_COUNT          0x4
> +
> +//
> +// LPI TRIGGER (HW C7 on VLV),
> +// TOFIX!!!
> +//
> +#define EFI_ACPI_VLV_LPI_TRIGGER {0x7F,0x1,0x2,0x0,0x64}
> +
> +//
> +// LPI residency counter (MMIO)
> +//
> +#define  EFI_ACPI_VLV_LPI_RES_COUNTER0   {0x0,32,0x0,0x03,0xFED03080}
> +#define  EFI_ACPI_VLV_LPI_RES_COUNTER1   {0x0,32,0x0,0x03,0xFED03084}
> +#define  EFI_ACPI_VLV_LPI_RES_COUNTER2   {0x0,32,0x0,0x03,0xFED03088}
> +#define  EFI_ACPI_VLV_LPI_RES_COUNTER3   {0x0,32,0x0,0x03,0xFED0308C}
> +
> +//
> +// LPI break-even residency in us - all match S0i3 residency
> +// Residency estimate: Latency x 3
> +//
> +#define  EFI_ACPI_VLV_LPI_MIN_RES0   15000
> +#define  EFI_ACPI_VLV_LPI_MIN_RES1   15000
> +#define  EFI_ACPI_VLV_LPI_MIN_RES2   15000
> +#define  EFI_ACPI_VLV_LPI_MIN_RES3   15000
> +
> +//
> +// LPI latency in us - all match S0i3 latency
> +//
> +#define  EFI_ACPI_VLV_LPI_LATENCY0   5000
> +#define  EFI_ACPI_VLV_LPI_LATENCY1   5000
> +#define  EFI_ACPI_VLV_LPI_LATENCY2   5000
> +#define  EFI_ACPI_VLV_LPI_LATENCY3   5000
> +
> +
> +//
> +// LPI ID
> +//
> +#define  EFI_ACPI_VLV_LPI_UNIQUE_ID0   0
> +#define  EFI_ACPI_VLV_LPI_UNIQUE_ID1   1
> +#define  EFI_ACPI_VLV_LPI_UNIQUE_ID2   2
> +#define  EFI_ACPI_VLV_LPI_UNIQUE_ID3   3
> +
> +//
> +//  LPI ACPI table header
> +//
> +
> +
> +typedef struct _EFI_ACPI_LOW_POWER_IDLE_TABLE {
> +  EFI_ACPI_DESCRIPTION_HEADER             Header;
> +  EFI_ACPI_MWAIT_LPI_STATE_DESCRIPTOR
> LpiStates[EFI_ACPI_VLV_LPI_STATE_COUNT];
> +} EFI_ACPI_LOW_POWER_IDLE_TABLE;
> +
> +#pragma pack()
> +
> +EFI_ACPI_LOW_POWER_IDLE_TABLE Lpit = {
> +
> +  //
> +  // Header
> +  //
> +
> +
> +  EFI_ACPI_LOW_POWER_IDLE_TABLE_SIGNATURE,
> +  sizeof (EFI_ACPI_LOW_POWER_IDLE_TABLE),
> +  EFI_ACPI_LOW_POWER_IDLE_TABLE_REVISION ,
> +
> +  //
> +  // Checksum will be updated at runtime
> +  //
> +  0x00,
> +
> +  //
> +  // It is expected that these values will be updated at runtime
> +  //
> +  ' ', ' ', ' ', ' ', ' ', ' ',
> +
> +  0,
> +  EFI_ACPI_OEM_LPIT_REVISION,
> +  0,
> +  0,
> +
> +
> +
> +  //
> +  // Descriptor
> +  //
> +  {
> +    {
> +      EFI_ACPI_LOW_POWER_IDLE_MWAIT_TYPE,
> +      sizeof(EFI_ACPI_MWAIT_LPI_STATE_DESCRIPTOR),
> +      EFI_ACPI_VLV_LPI_UNIQUE_ID0,
> +      {0,0},
> +      {EFI_ACPI_LOW_POWER_IDLE_DEFAULT_FLAG},   // Flags
> +      EFI_ACPI_VLV_LPI_TRIGGER,  //EntryTrigger
> +      EFI_ACPI_VLV_LPI_MIN_RES0, //Residency
> +      EFI_ACPI_VLV_LPI_LATENCY0, //Latency
> +      EFI_ACPI_VLV_LPI_RES_COUNTER0, //ResidencyCounter
> +      EFI_ACPI_LOW_POWER_IDLE_RES_FREQ_8K //Residency counter
> frequency
> +    },
> +    {
> +      EFI_ACPI_LOW_POWER_IDLE_MWAIT_TYPE,
> +      sizeof(EFI_ACPI_MWAIT_LPI_STATE_DESCRIPTOR),
> +      EFI_ACPI_VLV_LPI_UNIQUE_ID1,
> +      {0,0},
> +      {EFI_ACPI_LOW_POWER_IDLE_DEFAULT_FLAG},   // Flags
> +      EFI_ACPI_VLV_LPI_TRIGGER,  //EntryTrigger
> +      EFI_ACPI_VLV_LPI_MIN_RES1, //Residency
> +      EFI_ACPI_VLV_LPI_LATENCY1, //Latency
> +      EFI_ACPI_VLV_LPI_RES_COUNTER1, //ResidencyCounter
> +      EFI_ACPI_LOW_POWER_IDLE_RES_FREQ_8K //Residency counter
> frequency
> +    },
> +    {
> +      EFI_ACPI_LOW_POWER_IDLE_MWAIT_TYPE,
> +      sizeof(EFI_ACPI_MWAIT_LPI_STATE_DESCRIPTOR),
> +      EFI_ACPI_VLV_LPI_UNIQUE_ID2,
> +      {0,0},
> +      {EFI_ACPI_LOW_POWER_IDLE_DEFAULT_FLAG},   // Flags
> +      EFI_ACPI_VLV_LPI_TRIGGER,  //EntryTrigger
> +      EFI_ACPI_VLV_LPI_MIN_RES2, //Residency
> +      EFI_ACPI_VLV_LPI_LATENCY2, //Latency
> +      EFI_ACPI_VLV_LPI_RES_COUNTER2, //ResidencyCounter
> +      EFI_ACPI_LOW_POWER_IDLE_RES_FREQ_8K //Residency counter
> frequency
> +    },
> +    {
> +      EFI_ACPI_LOW_POWER_IDLE_MWAIT_TYPE,
> +      sizeof(EFI_ACPI_MWAIT_LPI_STATE_DESCRIPTOR),
> +      EFI_ACPI_VLV_LPI_UNIQUE_ID3,
> +      {0,0},
> +      {EFI_ACPI_LOW_POWER_IDLE_DEFAULT_FLAG},   // Flags
> +      EFI_ACPI_VLV_LPI_TRIGGER,  //EntryTrigger
> +      EFI_ACPI_VLV_LPI_MIN_RES3, //Residency
> +      EFI_ACPI_VLV_LPI_LATENCY3, //Latency
> +      EFI_ACPI_VLV_LPI_RES_COUNTER3, //ResidencyCounter
> +      EFI_ACPI_LOW_POWER_IDLE_RES_FREQ_8K //Residency counter
> frequency
> +    }
> +  }
> +
> +};
> +
> +
> +VOID*
> +ReferenceAcpiTable (
> +  VOID
> +  )
> +{
> +  //
> +  // Reference the table being generated to prevent the optimizer from
> +  // removing the data structure from the executable
> +  //
> +  return (VOID*)&Lpit;
> +}
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt.h
> new file mode 100644
> index 0000000000..72eb44e900
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt.h
> @@ -0,0 +1,189 @@
> +/*++
> +
> +Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +Module Name:
> +
> +  Madt.h
> +
> +Abstract:
> +
> +  This file describes the contents of the ACPI Multiple APIC Description
> +  Table (MADT).  Some additional ACPI values are defined in Acpi1_0.h and
> +  Acpi2_0.h.
> +  To make changes to the MADT, it is necessary to update the count for the
> +  APIC structure being updated, and to modify table found in Madt.c.
> +
> +--*/
> +
> +#ifndef _MADT_H
> +#define _MADT_H
> +
> +//
> +// Statements that include other files
> +//
> +#include "AcpiTablePlatform.h"
> +#include <IndustryStandard/Acpi10.h>
> +#include <IndustryStandard/Acpi20.h>
> +#include <IndustryStandard/Acpi30.h>
> +#include "Platform.h"
> +
> +//
> +// MADT Definitions
> +//
> +#define EFI_ACPI_OEM_MADT_REVISION                      0x00000000
> +//
> +// Multiple APIC Flags are defined in AcpiX.0.h
> +//
> +#define EFI_ACPI_1_0_MULTIPLE_APIC_FLAGS
> (EFI_ACPI_1_0_PCAT_COMPAT)
> +#define EFI_ACPI_2_0_MULTIPLE_APIC_FLAGS
> (EFI_ACPI_2_0_PCAT_COMPAT)
> +#define EFI_ACPI_3_0_MULTIPLE_APIC_FLAGS
> (EFI_ACPI_3_0_PCAT_COMPAT)
> +#define EFI_ACPI_4_0_MULTIPLE_APIC_FLAGS
> (EFI_ACPI_4_0_PCAT_COMPAT)
> +
> +//
> +// Define the number of each table type.
> +// This is where the table layout is modified.
> +//
> +#define EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT
> MAX_CPU_NUM
> +#define EFI_ACPI_LOCAL_APIC_NMI_COUNT                   MAX_CPU_NUM
> +#define EFI_ACPI_IO_APIC_COUNT                          1
> +#define EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT        2
> +#define EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT    0
> +#define EFI_ACPI_LOCAL_APIC_ADDRESS_OVERRIDE_COUNT      0
> +#define EFI_ACPI_IO_SAPIC_COUNT                         0
> +#define EFI_ACPI_PROCESSOR_LOCAL_SAPIC_COUNT            0
> +#define EFI_ACPI_PLATFORM_INTERRUPT_SOURCES_COUNT       0
> +
> +//
> +// MADT structure
> +//
> +//
> +// Ensure proper structure formats
> +//
> +#pragma pack(1)
> +//
> +// ACPI 1.0 Table structure
> +//
> +typedef struct {
> +  EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER   Header;
> +
> +#if EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT > 0
> +  EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC_STRUCTURE
> LocalApic[EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT];
> +#endif
> +
> +#if EFI_ACPI_IO_APIC_COUNT > 0
> +  EFI_ACPI_1_0_IO_APIC_STRUCTURE
> IoApic[EFI_ACPI_IO_APIC_COUNT];
> +#endif
> +
> +#if EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT > 0
> +  EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE
> Iso[EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT];
> +#endif
> +
> +#if EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT > 0
> +  EFI_ACPI_1_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE
> NmiSource[EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT];
> +#endif
> +
> +#if EFI_ACPI_LOCAL_APIC_NMI_COUNT > 0
> +  EFI_ACPI_1_0_LOCAL_APIC_NMI_STRUCTURE
> LocalApicNmi[EFI_ACPI_LOCAL_APIC_NMI_COUNT];
> +#endif
> +
> +#if EFI_ACPI_LOCAL_APIC_ADDRESS_OVERRIDE_COUNT > 0
> +  EFI_ACPI_1_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE
> LocalApicOverride[EFI_ACPI_LOCAL_APIC_ADDRESS_OVERRIDE_COUNT];
> +#endif
> +
> +} EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE;
> +
> +//
> +// ACPI 2.0 Table structure
> +//
> +typedef struct {
> +  EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER   Header;
> +
> +#if EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT > 0
> +  EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE
> LocalApic[EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT];
> +#endif
> +
> +#if EFI_ACPI_IO_APIC_COUNT > 0
> +  EFI_ACPI_2_0_IO_APIC_STRUCTURE
> IoApic[EFI_ACPI_IO_APIC_COUNT];
> +#endif
> +
> +#if EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT > 0
> +  EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE
> Iso[EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT];
> +#endif
> +
> +#if EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT > 0
> +  EFI_ACPI_2_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE
> NmiSource[EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT];
> +#endif
> +
> +#if EFI_ACPI_LOCAL_APIC_NMI_COUNT > 0
> +  EFI_ACPI_2_0_LOCAL_APIC_NMI_STRUCTURE
> LocalApicNmi[EFI_ACPI_LOCAL_APIC_NMI_COUNT];
> +#endif
> +
> +#if EFI_ACPI_LOCAL_APIC_ADDRESS_OVERRIDE_COUNT > 0
> +  EFI_ACPI_2_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE
> LocalApicOverride[EFI_ACPI_LOCAL_APIC_ADDRESS_OVERRIDE_COUNT];
> +#endif
> +
> +#if EFI_ACPI_IO_SAPIC_COUNT > 0
> +  EFI_ACPI_2_0_IO_SAPIC_STRUCTURE
> IoSapic[EFI_ACPI_IO_SAPIC_COUNT];
> +#endif
> +
> +#if EFI_ACPI_PROCESSOR_LOCAL_SAPIC_COUNT > 0
> +  EFI_ACPI_2_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE
> LocalSapic[EFI_ACPI_PROCESSOR_LOCAL_SAPIC_COUNT];
> +#endif
> +
> +#if EFI_ACPI_PLATFORM_INTERRUPT_SOURCES_COUNT > 0
> +  EFI_ACPI_2_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE
> PlatformInterruptSources[EFI_ACPI_PLATFORM_INTERRUPT_SOURCES_CO
> UNT];
> +#endif
> +
> +} EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE;
> +
> +//
> +// ACPI 3.0 Table structure
> +//
> +typedef struct {
> +  EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER   Header;
> +
> +#if EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT > 0           // Type 0x00
> +  EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_STRUCTURE
> LocalApic[EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT];
> +#endif
> +
> +#if EFI_ACPI_IO_APIC_COUNT > 0                        // Type 0x01
> +  EFI_ACPI_3_0_IO_APIC_STRUCTURE
> IoApic[EFI_ACPI_IO_APIC_COUNT];
> +#endif
> +
> +#if EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT > 0      // Type 0x02
> +  EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE
> Iso[EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT];
> +#endif
> +
> +#if EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT > 0  // Type
> 0x03
> +  EFI_ACPI_3_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE
> NmiSource[EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT];
> +#endif
> +
> +#if EFI_ACPI_LOCAL_APIC_NMI_COUNT > 0                 // Type 0x04
> +  EFI_ACPI_3_0_LOCAL_APIC_NMI_STRUCTURE
> LocalApicNmi[EFI_ACPI_LOCAL_APIC_NMI_COUNT];
> +#endif
> +
> +#if EFI_ACPI_LOCAL_APIC_ADDRESS_OVERRIDE_COUNT > 0    // Type 0x05
> +  EFI_ACPI_3_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE
> LocalApicOverride[EFI_ACPI_LOCAL_APIC_ADDRESS_OVERRIDE_COUNT];
> +#endif
> +
> +#if EFI_ACPI_IO_SAPIC_COUNT > 0                       // Type 0x06
> +  EFI_ACPI_3_0_IO_SAPIC_STRUCTURE
> IoSapic[EFI_ACPI_IO_SAPIC_COUNT];
> +#endif
> +
> +#if EFI_ACPI_PROCESSOR_LOCAL_SAPIC_COUNT > 0          // Type 0x07 : This
> table changes in madt 2.0
> +  EFI_ACPI_3_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE
> LocalSapic[EFI_ACPI_PROCESSOR_LOCAL_SAPIC_COUNT];
> +#endif
> +
> +#if EFI_ACPI_PLATFORM_INTERRUPT_SOURCES_COUNT > 0     // Type 0x08
> +  EFI_ACPI_3_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE
> PlatformInterruptSources[EFI_ACPI_PLATFORM_INTERRUPT_SOURCES_CO
> UNT];
> +#endif
> +
> +} EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE;
> +
> +#pragma pack()
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt30.aslc
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt30.aslc
> new file mode 100644
> index 0000000000..926b32f512
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt30.aslc
> @@ -0,0 +1,178 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2015, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  Madt3.0.c
> +
> +Abstract:
> +
> +  This file contains a structure definition for the ACPI 2.0 Multiple APIC
> +  Description Table (MADT).  Any changes to the MADT table require
> updating the
> +  respective structure count in Madt.h and then adding the structure to the
> +  MADT defined in this file.  The table layout is defined in Madt.h and the
> +  table contents are defined in Acpi3_0.h and Madt.h.
> +
> +--*/
> +
> +//
> +// Statements that include other files
> +//
> +#include "Madt.h"
> +#include <IndustryStandard/Acpi50.h>
> +
> +//
> +// Multiple APIC Description Table
> +//
> +EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE  Madt = {
> +  EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, //
> **Signatures are the same 1.0-3.0 because it says "APIC".
> +  sizeof (EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE),  //
> **Length
> +  EFI_ACPI_5_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,
> +  //
> +  // EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,  //
> **Table Revision must be 2.0 for ACPI 3.0
> +  // Checksum will be updated at runtime
> +  //
> +  0x00, // **Check sum
> +  //
> +  // It is expected that these values will be programmed at runtime
> +  //
> +  ' ',                        // OEMID
> +  ' ',                        // Creative way to
> +  ' ',                        // make six bytes
> +  ' ',                        // of space in
> +  ' ',                        // a table for
> +  ' ',                        // **OEMID
> +  0,                          // **OEM Table ID
> +  EFI_ACPI_OEM_MADT_REVISION, // **OEM Revision
> +  0,                          // **Creator ID
> +  0,                          // **Creator Revision
> +  //
> +  // MADT specific fields
> +  //
> +  LOCAL_APIC_ADDRESS,               // **Local APIC Address
> +  EFI_ACPI_4_0_MULTIPLE_APIC_FLAGS, // **Flags
> +  //
> +  // Processor Local APIC Structure
> +  // Correct processor order, Primary threads first then Hyper threads
> +  // And correct APIC-ids
> +  // This text below is included as a reference until Thurley is 100%:
> +  // According to EDS the Local APIC ID is determined based of a bit structure
> +  // Bit 24: Core ID Bit 25: Core Pair ID Bit 26-27: Reserved Bit 28-30: Socket ID
> Bit 31: Reserved
> +  // 4 Sockets and 4 Cores per Socket.
> +  // So possible LAPIC IDs 00, 01, 02, 03, 10, 11, 12, 13, 20, 21, 22, 23, 30, 31, 32,
> 33
> +  // Static Entries 00, 10, 20, 30, 01, 11, 21, 31, 02, 12, 22, 32, 03, 13, 23, 33
> +  // BSP needs to be first entry in table. Check before boot. If BSP non zero
> need to rotate the entries.
> +  // Suppore BSP is LAPIC ID xy. Rotate the table by using formula [x + (y * 4)]
> +  // So if BSP LAPIC ID is 21 then table rotated 6 times.
> +  // End of Reference Text.
> +  // Thurley is supposed to be 2 sockets, 4 cores, and hyperthreading
> available per each core.
> +  // 2 (sockets) x 4 (cores) = 8 (processors non-HT), 8 (processors non-HT) x 2
> (HT/proc) = 16 (HT procs)
> +  // Rhyme & reason of the ordering below.  This is a best guess ordering for
> now,
> +  // Thurley EPS may give better info on LAPIC numbers.
> +  // Ordering was established to help dissipate heat across two sockets
> evenly.
> +  // Since logical processor number only has to be unique, I followed
> +  // a similar approach to high end servers and have the first digit of the
> LAPIC
> +  // id the socket number.
> +  //
> +  EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC,                    // Type 0x00
> +  sizeof (EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_STRUCTURE), // Length
> +  0x01,                                                 // Processor ID
> +  0x00,                                                 // Local APIC ID
> +  0x00000001,                                           // Flags - Disabled (until initialized by
> platform driver)
> +  EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC,                    // Type
> +  sizeof (EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_STRUCTURE), // Length
> +  0x02,                                                 // Processor ID
> +  0x04,                                                 // Local APIC ID
> +  0x00000001,                                           // Flags - Disabled (until initialized by
> platform driver)
> +  EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC,                    // Type
> +  sizeof (EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_STRUCTURE), // Length
> +  0x03,                                                 // Processor ID
> +  0x02,                                                 // Local APIC ID
> +  0x00000001,                                           // Flags - Disabled (until initialized by
> platform driver)
> +  EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC,                    // Type
> +  sizeof (EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_STRUCTURE), // Length
> +  0x04,                                                 // Processor ID
> +  0x06,                                                 // Local APIC ID
> +  0x00000001,                                           // Flags - Disabled (until initialized by
> platform driver)
> +  //
> +  // ***************   IO APIC Structure ******************
> +  //
> +  //
> +  //
> +  // **************************  I/O APIC  **************
> +  //
> +  EFI_ACPI_3_0_IO_APIC,                     // Type 0x01
> +  sizeof (EFI_ACPI_3_0_IO_APIC_STRUCTURE),  // Length
> +  ICH_IOAPIC_ID,                            // IO APIC ID
> +  EFI_ACPI_RESERVED_BYTE,                   // Reserved
> EFI_ACPI_RESERVED_BYTE
> +  IO_APIC_ADDRESS,                          // IO APIC Address (physical)   0xFEC00000
> +  0x18 * 0,                                 // Global System Interrupt Base
> +
> +  //
> +  // Interrupt Source Override Structure: Sample
> +  //
> +  // EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE,                   // Type  0x02
> +  // sizeof (EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE),//
> Length
> +  // 0x00,                                                     // Bus
> +  // 0x00,                                                     // Source
> +  // 0x00000000,                                               // Global System Interrupt
> +  // 0x0000,                                                   // Flags
> +  //
> +  // IRQ0=>IRQ2 Interrupt Source Override Structure
> +  //
> +  EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE, // Type  0x02
> +  sizeof (EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE),  //
> Length
> +  0x00,       // Bus - ISA
> +  0x00,       // Source - IRQ0
> +  0x00000002, // Global System Interrupt - IRQ2
> +  0x0000,     // Flags - Conforms to specifications of the bus
> +  //
> +  // ISO (SCI Active High) Interrupt Source Override Structure
> +  //
> +  EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE, // Type  0x02
> +  sizeof (EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE),  //
> Length
> +  0x00,       // Bus - ISA
> +  0x09,       // Source - IRQ0
> +  0x00000009, // Global System Interrupt - IRQ2
> +  0x000D,     // Flags - Level-tiggered, Active High
> +
> +
> +
> +  EFI_ACPI_3_0_LOCAL_APIC_NMI,                    // Type
> +  sizeof (EFI_ACPI_3_0_LOCAL_APIC_NMI_STRUCTURE), // Length
> +  0x01,                                           // ACPI Processor ID
> +  0x000D,                                         // Flags - Level-tiggered, Active High
> +  0x01,                                           // Local APIC LINT#
> +  EFI_ACPI_3_0_LOCAL_APIC_NMI,                    // Type
> +  sizeof (EFI_ACPI_3_0_LOCAL_APIC_NMI_STRUCTURE), // Length
> +  0x02,                                           // ACPI Processor ID
> +  0x000D,                                         // Flags - Level-tiggered, Active High
> +  0x01,                                           // Local APIC LINT#
> +  EFI_ACPI_3_0_LOCAL_APIC_NMI,                    // Type
> +  sizeof (EFI_ACPI_3_0_LOCAL_APIC_NMI_STRUCTURE), // Length
> +  0x03,                                           // ACPI Processor ID
> +  0x000D,                                         // Flags - Level-tiggered, Active High
> +  0x01,                                           // Local APIC LINT#
> +  EFI_ACPI_3_0_LOCAL_APIC_NMI,                    // Type
> +  sizeof (EFI_ACPI_3_0_LOCAL_APIC_NMI_STRUCTURE), // Length
> +  0x04,                                           // ACPI Processor ID
> +  0x000D,                                         // Flags - Level-tiggered, Active High
> +  0x01,                                           // Local APIC LINT#
> +};
> +
> +VOID*
> +ReferenceAcpiTable (
> +  VOID
> +  )
> +{
> +  //
> +  // Reference the table being generated to prevent the optimizer from
> +  // removing the data structure from the executable
> +  //
> +  return (VOID*)&Madt;
> +}
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Mcfg/Mcfg.aslc
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Mcfg/Mcfg.aslc
> new file mode 100644
> index 0000000000..9373c542f6
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Mcfg/Mcfg.aslc
> @@ -0,0 +1,86 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  Mcfg.c
> +
> +Abstract:
> +
> +  This file contains a structure definition for the ACPI Memory mapped
> +  configuration space base address Description Table (MCFG).  Any changes
> +  to the MCFG table require updating the respective structure count in
> +  Mcfg.h and then adding the structure to the MCFG defined in this file.
> +  The table layout is defined in Mcfg.h and the table contents are defined
> +  in McfgTable.h and Mcfg.h.
> +
> +--*/
> +
> +//
> +// Statements that include other files
> +//
> +#include <Mcfg.h>
> +
> +//
> +// MCFG Table definition
> +//
> +EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE
> MCFG = {
> +
> EFI_ACPI_3_0_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABL
> E_SIGNATURE,
> +  sizeof
> (EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE),
> +
> EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_RE
> VISION,
> +  //
> +  // Checksum will be updated at runtime
> +  //
> +  0x00,
> +  //
> +  // It is expected that these values will be programmed at runtime
> +  //
> +  ' ',
> +  ' ',
> +  ' ',
> +  ' ',
> +  ' ',
> +  ' ',
> +
> +  0,
> +  EFI_ACPI_OEM_MCFG_REVISION,
> +  0,
> +  0,
> +  //
> +  // Beginning of MCFG specific fields
> +  //
> +  EFI_ACPI_RESERVED_QWORD,
> +  //
> +  // Sample Memory Mapped Configuration Space Base Address Structure
> +  //
> +  // 0x0,                                                              // Base Address
> +  // 0x0,                                                              // PCI Segment Group Number
> +  // 0x0,                                                              // Start Bus Number
> +  // 0x0,                                                              // End Bus Number
> +  // EFI_ACPI_RESERVED_DWORD,                                          // Reserved
> +  //
> +  // Memory Mapped Configuration Space Base Address Structure
> +  //
> +  0x0,                      // Base Address, will be updated by AcpiPlatform
> +  0x0,                      // PCI Segment Group Number
> +  0x0,                      // Start Bus Number
> +  PLATFORM_MAX_BUS_NUM,     // End Bus Number
> +  EFI_ACPI_RESERVED_DWORD,  // Reserved
> +};
> +
> +VOID*
> +ReferenceAcpiTable (
> +  VOID
> +  )
> +{
> +  //
> +  // Reference the table being generated to prevent the optimizer from
> +  // removing the data structure from the executable
> +  //
> +  return (VOID*)&MCFG;
> +}
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PCI_DRC.ASL
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PCI_DRC.ASL
> new file mode 100644
> index 0000000000..a475040898
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PCI_DRC.ASL
> @@ -0,0 +1,90 @@
> +/*********************************************************
> *****************;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
> +;*    Family of Customer Reference Boards.                                *;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved    *;
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*********************************************************
> *****************/
> +
> +
> +
> +Scope (\_SB.PCI0)
> +{
> +
> +  Device(PDRC)   // PCI Device Resource Consumption
> +  {
> +    Name(_HID,EISAID("PNP0C02"))
> +
> +    Name(_UID,1)
> +
> +    Name(BUF0,ResourceTemplate()
> +    {
> +      //
> +      // PCI Express BAR _BAS and _LEN will be updated in _CRS below
> according to B0:D0:F0:Reg.60h
> +      // Forced hard code at the moment.
> +      //
> +      //Memory32Fixed(ReadWrite,0,0,PCIX)       // PCIEX BAR
> +      Memory32Fixed(ReadWrite,0x0E0000000,0x010000000,PCIX)
> +
> +      //
> +      // SPI BAR. Check if the hard code meets the real configuration.
> +      // If not, dynamically update it like the _CRS method below.
> +      //
> +      Memory32Fixed(ReadWrite,0x0FED01000,0x01000,SPIB) // SPI BAR
> +
> +      //
> +      // PMC BAR. Check if the hard code meets the real configuration.
> +      // If not, dynamically update it like the _CRS method below.
> +      //
> +      Memory32Fixed(ReadWrite,0x0FED03000,0x01000,PMCB) // PMC BAR
> +
> +      //
> +      // SMB BAR. Check if the hard code meets the real configuration.
> +      // If not, dynamically update it like the _CRS method below.
> +      //
> +      Memory32Fixed(ReadWrite,0x0FED04000,0x01000,SMBB) // SMB BAR
> +
> +      //
> +      // IO BAR. Check if the hard code meets the real configuration.
> +      // If not, dynamically update it like the _CRS method below.
> +      //
> +      Memory32Fixed(ReadWrite,0x0FED0C000,0x04000,IOBR) // IO BAR
> +
> +      //
> +      // ILB BAR. Check if the hard code meets the real configuration.
> +      // If not, dynamically update it like the _CRS method below.
> +      //
> +      Memory32Fixed(ReadWrite,0x0FED08000,0x01000,ILBB) // ILB BAR
> +
> +      //
> +      // RCRB BAR _BAS will be updated in _CRS below according to
> B0:D31:F0:Reg.F0h
> +      //
> +      Memory32Fixed(ReadWrite,0x0FED1C000,0x01000,RCRB) // RCRB BAR
> +
> +      //
> +      // Local APIC range(0xFEE0_0000 to 0xFEEF_FFFF)
> +      //
> +      Memory32Fixed (ReadOnly, 0x0FEE00000, 0x0100000, LIOH)
> +
> +      //
> +      // MPHY BAR. Check if the hard code meets the real configuration.
> +      // If not, dynamically update it like the _CRS method below.
> +      //
> +      Memory32Fixed(ReadWrite,0x0FEF00000,0x0100000,MPHB)       // MPHY
> BAR
> +    })
> +
> +    Method(_CRS,0,Serialized)
> +    {
> +
> +      Return(BUF0)
> +    }
> +
> +  }
> +}
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Pch.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Pch.asl
> new file mode 100644
> index 0000000000..af8aceb515
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Pch.asl
> @@ -0,0 +1,686 @@
> +/*********************************************************
> *****************;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
> +;*    Family of Customer Reference Boards.                                *;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Copyright (c) 2012  - 2016, Intel Corporation. All rights reserved    *;
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*********************************************************
> *****************/
> +
> +
> +Scope(\)
> +{
> +  //
> +  // Define VLV ABASE I/O as an ACPI operating region. The base address
> +  // can be found in Device 31, Registers 40-43h.
> +  //
> +  OperationRegion(PMIO, SystemIo, \PMBS, 0x46)
> +  Field(PMIO, ByteAcc, NoLock, Preserve)
> +  {
> +    ,      8,
> +    PWBS,  1,       // Power Button Status
> +    Offset(0x20),
> +    ,      13,
> +    PMEB,  1,     // PME_B0_STS
> +    Offset(0x42),     // General Purpose Control
> +    ,      1,
> +    GPEC,  1
> +  }
> +  Field(PMIO, ByteAcc, NoLock, WriteAsZeros)
> +  {
> +    Offset(0x20),     // GPE0 Status
> +    ,      4,
> +    PSCI,  1,       // PUNIT SCI Status
> +    SCIS,  1        // GUNIT SCI Status
> +  }
> +
> +
> +
> +  //
> +  // Define a Memory Region that will allow access to the PMC
> +  // Register Block.  Note that in the Intel Reference Solution, the PMC
> +  // will get fixed up dynamically during POST.
> +  //
> +  OperationRegion(PMCR, SystemMemory, \PFDR, 0x04)// PMC Function
> Disable Register
> +  Field(PMCR,DWordAcc,Lock,Preserve)
> +  {
> +    Offset(0x00),   //  Function Disable Register
> +    L10D,  1,         //  (0) LPIO1 DMA Disable
> +    L11D,  1,         //  (1) LPIO1 PWM #1 Disable
> +    L12D,  1,         //  (2) LPIO1 PWM #2 Disable
> +    L13D,  1,         //  (3) LPIO1 HS-UART #1 Disable
> +    L14D,  1,         //  (4) LPIO1 HS-UART #2 Disable
> +    L15D,  1,         //  (5) LPIO1 SPI Disable
> +    ,          2,     //  (6:7) Reserved
> +    SD1D,  1,         //  (8) SCC SDIO #1 Disable
> +    SD2D,  1,         //  (9) SCC SDIO #2 Disable
> +    SD3D,  1,         //  (10) SCC SDIO #3 Disable
> +    HSID,  1,         //  (11)
> +    HDAD,  1,         //  (12) Azalia Disable
> +    LPED,  1,         //  (13) LPE Disable
> +    OTGD,  1,         //  (14) USB OTG Disable
> +    ,          1,     //  (15) USH Disable
> +    ,          1,     //  (16)
> +    ,          1,     //  (17)
> +    ,          1,     //  (18) USB Disable
> +    ,          1,     //  (19) SEC Disable
> +    RP1D,  1,         //  (20) Root Port 0 Disable
> +    RP2D,  1,         //  (21) Root Port 1 Disable
> +    RP3D,  1,         //  (22) Root Port 2 Disable
> +    RP4D,  1,         //  (23) Root Port 3 Disable
> +    L20D,  1,         //  (24) LPIO2 DMA Disable
> +    L21D,  1,         //  (25) LPIO2 I2C #1 Disable
> +    L22D,  1,         //  (26) LPIO2 I2C #2 Disable
> +    L23D,  1,         //  (27) LPIO2 I2C #3 Disable
> +    L24D,  1,         //  (28) LPIO2 I2C #4 Disable
> +    L25D,  1,         //  (29) LPIO2 I2C #5 Disable
> +    L26D,  1,         //  (30) LPIO2 I2C #6 Disable
> +    L27D,  1          //  (31) LPIO2 I2C #7 Disable
> +  }
> +
> +
> +  OperationRegion(CLKC, SystemMemory, \PCLK, 0x18)// PMC CLK CTL
> Registers
> +  Field(CLKC,DWordAcc,Lock,Preserve)
> +  {
> +    Offset(0x00),   //  PLT_CLK_CTL_0
> +    CKC0, 2,
> +    CKF0, 1,
> +    ,     29,
> +    Offset(0x04),   //  PLT_CLK_CTL_1
> +    CKC1, 2,
> +    CKF1, 1,
> +    ,     29,
> +    Offset(0x08),   //  PLT_CLK_CTL_2
> +    CKC2,  2,
> +    CKF2, 1,
> +    ,     29,
> +    Offset(0x0C),   //  PLT_CLK_CTL_3
> +    CKC3,  2,
> +    CKF3, 1,
> +    ,     29,
> +    Offset(0x10),   //  PLT_CLK_CTL_4
> +    CKC4,  2,
> +    CKF4, 1,
> +    ,     29,
> +    Offset(0x14),   //  PLT_CLK_CTL_5
> +    CKC5,  2,
> +    CKF5, 1,
> +    ,     29,
> +  }
> +} //end Scope(\)
> +
> +scope (\_SB)
> +{
> +  Device(LPEA)
> +  {
> +    Name (_ADR, 0)
> +    Name (_HID, "80860F28")
> +    Name (_CID, "80860F28")
> +    //Name (_CLS, Package (3) {0x04, 0x01, 0x00})
> +    Name (_DDN, "Intel(R) Low Power Audio Controller - 80860F28")
> +    Name (_SUB, "80867270")
> +    Name (_UID, 1)
> +    Name (_DEP, Package() {\_SB.I2C2.RTEK})
> +    Name(_PR0,Package() {PLPE})
> +
> +    Method (_STA, 0x0, NotSerialized)
> +    {
> +      If (LAnd(LAnd(LEqual(LPEE, 2), LEqual(LPED, 0)), LEqual(OSEL, 0)))
> +      {
> +        If(LEqual(LPAD, 1))
> +        {
> +          Return (0xF)
> +        }
> +      }
> +      Return (0x0)
> +    }
> +
> +    Method (_DIS, 0x0, NotSerialized)
> +    {
> +      //Add a dummy disable function
> +    }
> +
> +    Name (RBUF, ResourceTemplate ()
> +      {
> +        Memory32Fixed (ReadWrite, 0xFE400000, 0x00200000, BAR0)  // MMIO
> 1 - LPE MMIO
> +        Memory32Fixed (ReadWrite, 0xFE830000, 0x00001000, BAR1)  // MMIO
> 2 - Shadowed PCI Config Space
> +        Memory32Fixed (ReadWrite, 0x55AA55AA, 0x00100000, BAR2)  // LPE
> Memory Bar Allocate during post
> +        Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {24}
> +        Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {25}
> +        Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {26}
> +        Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {27}
> +        Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {28}
> +        Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {29}
> +        GpioInt(Edge, ActiveBoth, ExclusiveAndWake, PullNone,
> 0,"\\_SB.GPO2") {28} //  Audio jack interrupt
> +      }
> +    )
> +
> +    Method (_CRS, 0x0, NotSerialized)
> +    {
> +      CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
> +      Store(LPE0, B0BA)
> +      CreateDwordField(^RBUF, ^BAR1._BAS, B1BA)
> +      Store(LPE1, B1BA)
> +      CreateDwordField(^RBUF, ^BAR2._BAS, B2BA)
> +      Store(LPE2, B2BA)
> +      Return (RBUF)
> +    }
> +
> +    OperationRegion (KEYS, SystemMemory, LPE1, 0x100)
> +    Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
> +    {
> +      Offset (0x84),
> +      PSAT,   32
> +    }
> +
> +    PowerResource(PLPE, 0, 0)   // Power Resource for LPEA
> +    {
> +      Method (_STA)
> +      {
> +        Return (1)      // Power Resource is always available.
> +      }
> +
> +      Method (_ON)
> +      {
> +        And(PSAT, 0xfffffffC, PSAT)
> +        OR(PSAT, 0X00000000, PSAT)
> +      }
> +
> +      Method (_OFF)
> +      {
> +        OR(PSAT, 0x00000003, PSAT)
> +        OR(PSAT, 0X00000000, PSAT)
> +      }
> +    } // End PLPE
> +  } // End "Low Power Engine Audio"
> +
> +  Device(LPA2)
> +  {
> +    Name (_ADR, 0)
> +    Name (_HID, "LPE0F28")  // _HID: Hardware ID
> +    Name (_CID, "LPE0F28")  // _CID: Compatible ID
> +    Name (_DDN, "Intel(R) SST Audio - LPE0F28")  // _DDN: DOS Device Name
> +    Name (_SUB, "80867270")
> +    Name (_UID, 1)
> +    Name (_DEP, Package() {\_SB.I2C2.RTEK})
> +    Name(_PR0,Package() {PLPE})
> +
> +    Method (_STA, 0x0, NotSerialized)
> +    {
> +      If (LAnd(LAnd(LEqual(LPEE, 2), LEqual(LPED, 0)), LEqual(OSEL, 1)))
> +      {
> +        If(LEqual(LPAD, 1))
> +        {
> +          Return (0xF)
> +        }
> +      }
> +      Return (0x0)
> +    }
> +
> +    Method (_DIS, 0x0, NotSerialized)
> +    {
> +      //Add a dummy disable function
> +    }
> +
> +    Name (RBUF, ResourceTemplate ()
> +      {
> +        Memory32Fixed (ReadWrite, 0x55AA55AA, 0x00100000, BAR2)  // LPE
> Memory Bar Allocate during post
> +        Memory32Fixed (ReadWrite, 0x55AA55AA, 0x00000100, SHIM)
> +        Memory32Fixed (ReadWrite, 0x55AA55AA, 0x00001000, MBOX)
> +        Memory32Fixed (ReadWrite, 0x55AA55AA, 0x00014000, IRAM)
> +        Memory32Fixed (ReadWrite, 0x55AA55AA, 0x00028000, DRAM)
> +        Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {29}
> +        Memory32Fixed (ReadWrite, 0xFE830000, 0x00001000, BAR1)  // MMIO
> 2 - Shadowed PCI Config Space
> +      }
> +    )
> +
> +    Method (_CRS, 0x0, NotSerialized)
> +    {
> +      CreateDwordField(^RBUF, ^SHIM._BAS, SHBA)
> +      Add(LPE0, 0x140000, SHBA)
> +      CreateDwordField(^RBUF, ^MBOX._BAS, MBBA)
> +      Add(LPE0, 0x144000, MBBA)
> +      CreateDwordField(^RBUF, ^IRAM._BAS, IRBA)
> +      Add(LPE0, 0xC0000, IRBA)
> +      CreateDwordField(^RBUF, ^DRAM._BAS, DRBA)
> +      Add(LPE0, 0x100000, DRBA)
> +      CreateDwordField(^RBUF, ^BAR1._BAS, B1BA)
> +      Store(LPE1, B1BA)
> +      CreateDwordField(^RBUF, ^BAR2._BAS, B2BA)
> +      Store(LPE2, B2BA)
> +      Return (RBUF)
> +    }
> +
> +    OperationRegion (KEYS, SystemMemory, LPE1, 0x100)
> +    Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
> +    {
> +      Offset (0x84),
> +      PSAT,   32
> +    }
> +
> +    PowerResource(PLPE, 0, 0)   // Power Resource for LPEA
> +    {
> +      Method (_STA)
> +      {
> +        Return (1)      // Power Resource is always available.
> +      }
> +
> +      Method (_ON)
> +      {
> +        And(PSAT, 0xfffffffC, PSAT)
> +        OR(PSAT, 0X00000000, PSAT)
> +      }
> +
> +      Method (_OFF)
> +      {
> +        OR(PSAT, 0x00000003, PSAT)
> +        OR(PSAT, 0X00000000, PSAT)
> +      }
> +    } // End PLPE
> +
> +    Device (ADMA)
> +    {
> +      Name (_ADR, Zero)  // _ADR: Address
> +      Name (_HID, "DMA0F28")  // _HID: Hardware ID
> +      Name (_CID, "DMA0F28")  // _CID: Compatible ID
> +      Name (_DDN, "Intel(R) Audio  DMA0 - DMA0F28")  // _DDN: DOS Device
> Name
> +      Name (_UID, One)  // _UID: Unique ID
> +      Name (RBUF, ResourceTemplate ()
> +      {
> +        Memory32Fixed (ReadWrite, 0x55AA55AA, 0x00001000, DMA0)  // LPE
> BASE + LPE DMA0 offset
> +        Memory32Fixed (ReadWrite, 0x55AA55AA, 0x00001000, SHIM)  // LPE
> BASE + LPE SHIM offset
> +        Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {24}
> +      })
> +
> +      Method (_CRS, 0, NotSerialized)   // _CRS: Current Resource Settings
> +      {
> +        CreateDwordField(^RBUF, ^DMA0._BAS, D0BA)
> +        Add(LPE0, 0x98000, D0BA)
> +        CreateDwordField(^RBUF, ^SHIM._BAS, SHBA)
> +        Add(LPE0, 0x140000, SHBA)
> +        Return (RBUF)
> +      }
> +    }
> +  } // End "Low Power Engine Audio" for Android
> +}
> +
> +scope (\_SB.PCI0)
> +{
> +
> +  //
> +  // Serial ATA Host Controller - Device 19, Function 0
> +  //
> +
> +  Device(SATA)
> +  {
> +    Name(_ADR,0x00130000)
> +    //
> +    // SATA Methods pulled in via SSDT.
> +    //
> +
> +    OperationRegion(SATR, PCI_Config, 0x74,0x4)
> +    Field(SATR,WordAcc,NoLock,Preserve)
> +    {
> +      Offset(0x00), // 0x74, PMCR
> +      ,   8,
> +      PMEE,   1,    //PME_EN
> +      ,   6,
> +      PMES,   1     //PME_STS
> +    }
> +
> +    Method (_STA, 0x0, NotSerialized)
> +    {
> +      Return(0xf)
> +    }
> +
> +    Method(_DSW, 3)
> +    {
> +    } // End _DSW
> +  }
> +
> +  //
> +  // For eMMC 4.41 PCI mode in order to present non-removable device
> under Windows environment
> +  //
> +  Device(EM41)
> +  {
> +    Name(_ADR,0x00100000)
> +    OperationRegion(SDIO, PCI_Config, 0x84,0x4)
> +    Field(SDIO,WordAcc,NoLock,Preserve)
> +    {
> +      Offset(0x00), // 0x84, PMCR
> +      ,   8,
> +      PMEE,   1,    //PME_EN
> +      ,   6,
> +      PMES,   1     //PME_STS
> +    }
> +
> +    Method (_STA, 0x0, NotSerialized)
> +    {
> +      If (LAnd(LEqual(PCIM, 1), LEqual(SD1D, 0)))
> +      {
> +        Return(0xF)
> +      }
> +      Else
> +      {
> +        Return(0x0)
> +      }
> +    }
> +
> +    Method(_DSW, 3)
> +    {
> +    } // End _DSW
> +
> +    Device (CARD)
> +    {
> +      Name (_ADR, 0x00000008)
> +      Method(_RMV, 0x0, NotSerialized)
> +      {
> +        Return (0)
> +      } // End _DSW
> +    }
> +  }
> +
> +  //
> +  // For eMMC 4.5 PCI mode in order to present non-removable device
> under Windows environment
> +  //
> +  Device(EM45)
> +  {
> +    Name(_ADR,0x00170000)
> +    OperationRegion(SDIO, PCI_Config, 0x84,0x4)
> +    Field(SDIO,WordAcc,NoLock,Preserve)
> +    {
> +      Offset(0x00), // 0x84, PMCR
> +      ,   8,
> +      PMEE,   1,    //PME_EN
> +      ,   6,
> +      PMES,   1     //PME_STS
> +    }
> +
> +    Method (_STA, 0x0, NotSerialized)
> +    {
> +      If (LAnd(LEqual(PCIM, 1), LEqual(HSID, 0)))
> +      {
> +        Return(0xF)
> +      }
> +      Else
> +      {
> +        Return(0x0)
> +      }
> +    }
> +
> +    Method(_DSW, 3)
> +    {
> +    } // End _DSW
> +
> +    Device (CARD)
> +    {
> +      Name (_ADR, 0x00000008)
> +      Method(_RMV, 0x0, NotSerialized)
> +      {
> +        Return (0)
> +      } // End _DSW
> +    }
> +  }
> +  //
> +  // For SD Host Controller (Bus 0x00 : Dev 0x12 : Func 0x00) PCI mode in
> order to present non-removable device under Windows environment
> +  //
> +  Device(SD12)
> +  {
> +    Name(_ADR,0x00120000)
> +
> +    Method (_STA, 0x0, NotSerialized)
> +    {
> +      //
> +      // PCIM>> 0:ACPI mode           1:PCI mode
> +      //
> +      If (LEqual(PCIM, 0)) {
> +        Return (0x0)
> +      }
> +
> +      //
> +      // If device is disabled.
> +      //
> +      If (LEqual(SD3D, 1))
> +      {
> +        Return (0x0)
> +      }
> +
> +      Return (0xF)
> +    }
> +
> +    Device (CARD)
> +    {
> +      Name (_ADR, 0x00000008)
> +      Method(_RMV, 0x0, NotSerialized)
> +      {
> +        // SDRM = 0 non-removable;
> +        If (LEqual(SDRM, 0))
> +        {
> +          Return (0)
> +        }
> +
> +        Return (1)
> +      }
> +    }
> +  }
> +
> +  // xHCI Controller - Device 20, Function 0
> +  include("PchXhci.asl")
> +
> +  //
> +  // High Definition Audio Controller - Device 27, Function 0
> +  //
> +  Device(HDEF)
> +  {
> +    Name(_ADR, 0x001B0000)
> +    include("PchAudio.asl")
> +
> +    Method (_STA, 0x0, NotSerialized)
> +    {
> +      If (LEqual(HDAD, 0))
> +      {
> +        Return(0xf)
> +      }
> +      Return(0x0)
> +    }
> +
> +    Method(_DSW, 3)
> +    {
> +    } // End _DSW
> +  } // end "High Definition Audio Controller"
> +
> +
> +
> +  //
> +  // PCIE Root Port #1
> +  //
> +  Device(RP01)
> +  {
> +    Name(_ADR, 0x001C0000)
> +    include("PchPcie.asl")
> +    Name(_PRW, Package() {9, 4})
> +
> +    Method(_PRT,0)
> +    {
> +      If(PICM) { Return(AR04) }// APIC mode
> +      Return (PR04) // PIC Mode
> +    } // end _PRT
> +  } // end "PCIE Root Port #1"
> +
> +  //
> +  // PCIE Root Port #2
> +  //
> +  Device(RP02)
> +  {
> +    Name(_ADR, 0x001C0001)
> +    include("PchPcie.asl")
> +    Name(_PRW, Package() {9, 4})
> +
> +    Method(_PRT,0)
> +    {
> +      If(PICM) { Return(AR05) }// APIC mode
> +      Return (PR05) // PIC Mode
> +    } // end _PRT
> +
> +  } // end "PCIE Root Port #2"
> +
> +  //
> +  // PCIE Root Port #3
> +  //
> +  Device(RP03)
> +  {
> +    Name(_ADR, 0x001C0002)
> +    include("PchPcie.asl")
> +    Name(_PRW, Package() {9, 4})
> +    Method(_PRT,0)
> +    {
> +      If(PICM) { Return(AR06) }// APIC mode
> +      Return (PR06) // PIC Mode
> +    } // end _PRT
> +
> +  } // end "PCIE Root Port #3"
> +
> +  //
> +  // PCIE Root Port #4
> +  //
> +  Device(RP04)
> +  {
> +    Name(_ADR, 0x001C0003)
> +    include("PchPcie.asl")
> +    Name(_PRW, Package() {9, 4})
> +    Method(_PRT,0)
> +    {
> +      If(PICM) { Return(AR07) }// APIC mode
> +      Return (PR07) // PIC Mode
> +    } // end _PRT
> +
> +  } // end "PCIE Root Port #4"
> +
> +
> +  Scope(\_SB)
> +  {
> +    //
> +    // Dummy power resource for USB D3 cold support
> +    //
> +    PowerResource(USBC, 0, 0)
> +    {
> +      Method(_STA) { Return (0xF) }
> +      Method(_ON) {}
> +      Method(_OFF) {}
> +    }
> +  }
> +  //
> +  // EHCI Controller - Device 29, Function 0
> +  //
> +  Device(EHC1)
> +  {
> +    Name(_ADR, 0x001D0000)
> +    Name(_DEP, Package(0x1)
> +    {
> +      PEPD
> +    })
> +    include("PchEhci.asl")
> +    Name(_PRW, Package() {0x0D, 4})
> +
> +    OperationRegion(USBR, PCI_Config, 0x54,0x4)
> +    Field(USBR,WordAcc,NoLock,Preserve)
> +    {
> +      Offset(0x00), // 0x54, PMCR
> +      ,   8,
> +      PMEE,   1,    //PME_EN
> +      ,   6,
> +      PMES,   1     //PME_STS
> +    }
> +
> +    Method (_STA, 0x0, NotSerialized)
> +    {
> +      If(LEqual(XHCI, 0))      //XHCI is not present. It means EHCI is there
> +      {
> +        Return (0xF)
> +      } Else
> +      {
> +        Return (0x0)
> +      }
> +    }
> +
> +    Method (_RMV, 0, NotSerialized)
> +    {
> +      Return (0x0)
> +    }
> +    //
> +    // Create a dummy PR3 method to indicate to the PCI driver
> +    // that the device is capable of D3 cold
> +    //
> +    Method(_PR3, 0x0, NotSerialized)
> +    {
> +      return (Package() {\_SB.USBC})
> +    }
> +
> +  } // end "EHCI Controller"
> +
> +  //
> +  // SMBus Controller - Device 31, Function 3
> +  //
> +  Device(SBUS)
> +  {
> +    Name(_ADR,0x001F0003)
> +    Include("PchSmb.asl")
> +  }
> +
> +  Device(SEC0)
> +  {
> +    Name (_ADR, 0x001a0000)                     // Device 0x1a, Function 0
> +    Name(_DEP, Package(0x1)
> +    {
> +      PEPD
> +    })
> +
> +
> +    OperationRegion (PMEB, PCI_Config, 0x84, 0x04)  //PMECTRLSTATUS
> +    Field (PMEB, WordAcc, NoLock, Preserve)
> +    {
> +      ,   8,
> +      PMEE,   1,    //bit8 PMEENABLE
> +      ,   6,
> +      PMES,   1     //bit15 PMESTATUS
> +    }
> +
> +    // Arg0 -- integer that contains the device wake capability control (0-
> disable 1- enable)
> +    // Arg1 -- integer that contains target system state (0-4)
> +    // Arg2 -- integer that contains the target device state
> +    Method (_DSW, 3, NotSerialized)   // _DSW: Device Sleep Wake
> +    {
> +    }
> +
> +    Method (_CRS, 0, NotSerialized)
> +    {
> +      Name (RBUF, ResourceTemplate ()
> +      {
> +        Memory32Fixed (ReadWrite, 0x1e000000, 0x2000000)
> +      })
> +
> +      If (LEqual(PAVP, 2))
> +      {
> +        Return (RBUF)
> +      }
> +      Return (ResourceTemplate() {})
> +    }
> +
> +    Method (_STA)
> +    {
> +      If (LNotEqual(PAVP, 0))
> +      {
> +        Return (0xF)
> +      }
> +      Return (0x0)
> +    }
> +  }   // Device(SEC0)
> +
> +} // End scope (\_SB.PCI0)
> +
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchAudio.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchAudio.asl
> new file mode 100644
> index 0000000000..4dd5e6f756
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchAudio.asl
> @@ -0,0 +1,36 @@
> +/*********************************************************
> *****************;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
> +;*    Family of Customer Reference Boards.                                *;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Copyright (c)  2011  - 2014, Intel Corporation. All rights reserved   *;
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*********************************************************
> *****************/
> +//
> +// High Definition Audio - Device 27, Function 0
> +//
> +OperationRegion(HDAR, PCI_Config, 0x4C,0x10)
> +Field(HDAR,WordAcc,NoLock,Preserve)
> +{
> +  Offset(0x00), // 0x4C, Dock Control Register
> +  DCKA,    1,   // Dock Attach
> +  ,    7,
> +  Offset(0x01), // 04Dh, Dock Status Register
> +  DCKM,    1,   // Dock Mated
> +  ,    6,
> +  DCKS,    1,   // Docking Supported
> +  Offset(0x08), // 0x54, Power Management Control and Status Register
> +  ,    8,
> +  PMEE,    1,   // PME_EN
> +  ,    6,
> +  PMES,    1    // PME Status
> +}
> +
> +
> +
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchEhci.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchEhci.asl
> new file mode 100644
> index 0000000000..c058cd0c3e
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchEhci.asl
> @@ -0,0 +1,269 @@
> +/*********************************************************
> ******************************;
> +;*                                                                                     *;
> +;*                                                                                     *;
> +;*    Intel Corporation - ACPI Reference Code for the Baytrail                         *;
> +;*    Family of Customer Reference Boards.                                             *;
> +;*                                                                                     *;
> +;*                                                                                     *;
> +;*    Copyright (c)  2011  - 2014, Intel Corporation. All rights reserved              *;
> +;*                                                                                     *;
> +;*   ThSPDX-License-Identifier: BSD-2-Clause-Patent
> +;*                                                                                     *;
> +;*                                                                                     *;
> +;*                                                                                     *;
> +;*********************************************************
> ******************************/
> +
> +OperationRegion(PWKE,PCI_Config,0x62,0x04)
> +
> +Field(PWKE,DWordAcc,NoLock,Preserve)
> +{
> +  , 1,
> +  PWUC, 8 // Port Wake Up Capability Mask
> +}
> +
> +Method(_PSW,1)
> +{
> +  If(Arg0)
> +  {
> +    Store(Ones,PWUC)
> +  }
> +  Else
> +  {
> +    Store(0,PWUC)
> +  }
> +}
> +
> +// Leaves the USB ports on in S3/S4 to allow
> +// the ability to Wake from USB.  Therefore, define
> +// the below control methods to state D2 entry during
> +// the given S-State.
> +
> +Method(_S3D,0)
> +{
> +  Return(2)
> +}
> +
> +Method(_S4D,0)
> +{
> +  Return(2)
> +}
> +
> +Device(HUBN)
> +{
> +  Name(_ADR, Zero)
> +  Device(PR01)
> +  {
> +    Name(_ADR, One)
> +
> +    //
> +    // There will have "Generic USB Hub" existed at Port 1 of each EHCI
> controller
> +    // in Windows "Device Manager" while RMH is enabled, so need to add
> _UPC
> +    // and _PLD to report OS that it's not user visible to pass WHQL: Single
> Computer
> +    // Display Object test in Win7
> +    //
> +    Name(_UPC, Package()
> +    {
> +      0xFF,                       // Port is connectable
> +      0x00,                       // Connector type - Type "A"
> +      0x00000000,                 // Reserved 0 - must be zero
> +      0x00000000
> +    })                // Reserved 1 - must be zero
> +
> +    Name(_PLD, Package()
> +    {
> +      Buffer (0x10)
> +      {
> +        0x81, 0x00, 0x00, 0x00,     // Revision 1, Ignore color
> +        0x00, 0x00, 0x00, 0x00,
> +        0x30, 0x1C, 0x00, 0x00,     // Panel Unknown, Shape Unknown
> +        0x00, 0x00, 0x00, 0x00
> +      }
> +    })
> +
> +    Device(PR11)
> +    {
> +      Name(_ADR, One)
> +      Name(_UPC, Package()
> +      {
> +        0xFF,                       // Port is connectable
> +        0xFF,                       // Proprietary connector
> +        0x00000000,                 // Reserved 0 - must be zero
> +        0x00000000
> +      })                // Reserved 1 - must be zero
> +      Name(_PLD, Package()
> +      {
> +        Buffer (0x10)
> +        {
> +          0x81, 0x00, 0x00, 0x00,     // Revision 1, Ignore color
> +          0x00, 0x00, 0x00, 0x00,
> +          0xE1, 0x1C, 0x00, 0x00,     // Front Panel, Vertical Upper, Horz. Left,
> Shape Unknown
> +          0x00, 0x00, 0x00, 0x00
> +        }
> +      })
> +    }
> +
> +    Device(PR12)
> +    {
> +      Name(_ADR, 0x02)
> +      Name(_UPC, Package()
> +      {
> +        0xFF,                       // Port is connectable
> +        0xFF,                       // Proprietary connector
> +        0x00000000,                 // Reserved 0 - must be zero
> +        0x00000000
> +      })                // Reserved 1 - must be zero
> +      Name(_PLD, Package()
> +      {
> +        Buffer (0x10)
> +        {
> +          0x81, 0x00, 0x00, 0x00,     // Revision 1, Ignore color
> +          0x00, 0x00, 0x00, 0x00,
> +          0xE1, 0x1D, 0x00, 0x00,     // Front Panel, Vertical Center, Horz. Left,
> Shape Unknown
> +          0x00, 0x00, 0x00, 0x00
> +        }
> +      })
> +    }
> +
> +    Device(PR13)
> +    {
> +      Name(_ADR, 0x03)
> +      Name(_UPC, Package()
> +      {
> +        0xFF,                       // Port is connectable
> +        0xFF,                       // Proprietary connector
> +        0x00000000,                 // Reserved 0 - must be zero
> +        0x00000000
> +      })                // Reserved 1 - must be zero
> +      Name(_PLD, Package()
> +      {
> +        Buffer (0x10)
> +        {
> +          0x81, 0x00, 0x00, 0x00,     // Revision 1, Ignore color
> +          0x00, 0x00, 0x00, 0x00,
> +          0xE1, 0x1D, 0x00, 0x00,     // Front Panel, Vertical Center, Horz. Left,
> Shape Unknown
> +          0x00, 0x00, 0x00, 0x00
> +        }
> +      })
> +    }
> +
> +    Device(PR14)
> +    {
> +      Name(_ADR, 0x04)
> +      Name(_UPC, Package()
> +      {
> +        0xFF,                       // Port is connectable
> +        0xFF,                       // Proprietary connector
> +        0x00000000,                 // Reserved 0 - must be zero
> +        0x00000000
> +      })                // Reserved 1 - must be zero
> +
> +      Name(_PLD, Package()
> +      {
> +        Buffer (0x10)
> +        {
> +          0x81, 0x00, 0x00, 0x00,     // Revision 1, Ignore color
> +          0x00, 0x00, 0x00, 0x00,
> +          0xE1, 0x1E, 0x00, 0x00,     // Front Panel, Vertical Lower, Horz. Left,
> Shape Unknown
> +          0x00, 0x00, 0x00, 0x00
> +        }
> +      })
> +
> +      // copy USB Sideband Deferring GPE Vector (HOST_ALERT#1) to DSM
> method
> +      Include("UsbSbd.asl")
> +    }
> +
> +    Device(PR15)
> +    {
> +      Name(_ADR, 0x05)
> +      Name(_UPC, Package()
> +      {
> +        0xFF,                       // Port is connectable
> +        0xFF,                       // Proprietary connector
> +        0x00000000,                 // Reserved 0 - must be zero
> +        0x00000000
> +      })                // Reserved 1 - must be zero
> +      Name(_PLD, Package()
> +      {
> +        Buffer (0x10)
> +        {
> +          0x81, 0x00, 0x00, 0x00,     // Revision 1, Ignore color
> +          0x00, 0x00, 0x00, 0x00,
> +          0xB1, 0x1E, 0x00, 0x00,     // Panel Unknown, Shape Unknown
> +          0x00, 0x00, 0x00, 0x00
> +        }
> +      })
> +      // copy USB Sideband Deferring GPE Vector (HOST_ALERT#2) to DSM
> method
> +      Include("UsbSbd.asl")
> +    }
> +
> +    Device(PR16)
> +    {
> +      Name(_ADR, 0x06)
> +      Name(_UPC, Package()
> +      {
> +        0xFF,                       // Port is connectable
> +        0xFF,                       // Proprietary connector
> +        0x00000000,                 // Reserved 0 - must be zero
> +        0x00000000
> +      })                // Reserved 1 - must be zero
> +      Name(_PLD, Package()
> +      {
> +        Buffer (0x10)
> +        {
> +          0x81, 0x00, 0x00, 0x00,     // Revision 1, Ignore color
> +          0x00, 0x00, 0x00, 0x00,
> +          0xB1, 0x1E, 0x00, 0x00,     // Panel Unknown, Shape Unknown
> +          0x00, 0x00, 0x00, 0x00
> +        }
> +      })
> +      // copy USB Sideband Deferring GPE Vector (HOST_ALERT#1) to DSM
> method
> +      Include("UsbSbd.asl")
> +    }
> +
> +    Device(PR17)
> +    {
> +      Name(_ADR, 0x07)
> +      Name(_UPC, Package()
> +      {
> +        0xFF,                       // Port is connectable
> +        0xFF,                       // Proprietary connector
> +        0x00000000,                 // Reserved 0 - must be zero
> +        0x00000000
> +      })                // Reserved 1 - must be zero
> +      Name(_PLD, Package()
> +      {
> +        Buffer (0x10)
> +        {
> +          0x81, 0x00, 0x00, 0x00,     // Revision 1, Ignore color
> +          0x00, 0x00, 0x00, 0x00,
> +          0xB1, 0x1E, 0x00, 0x00,     // Panel Unknown, Shape Unknown
> +          0x00, 0x00, 0x00, 0x00
> +        }
> +      })
> +      // copy USB Sideband Deferring GPE Vector (HOST_ALERT#2) to DSM
> method
> +      Include("UsbSbd.asl")
> +    }
> +
> +    Device(PR18)
> +    {
> +      Name(_ADR, 0x08)
> +      Name(_UPC, Package()
> +      {
> +        0xFF,                       // Port is connectable
> +        0xFF,                       // Proprietary connector
> +        0x00000000,                 // Reserved 0 - must be zero
> +        0x00000000
> +      })                // Reserved 1 - must be zero
> +      Name(_PLD, Package()
> +      {
> +        Buffer (0x10)
> +        {
> +          0x81, 0x00, 0x00, 0x00,     // Revision 1, Ignore color
> +          0x00, 0x00, 0x00, 0x00,
> +          0xB1, 0x1E, 0x00, 0x00,     // Panel Unknown, Shape Unknown
> +          0x00, 0x00, 0x00, 0x00
> +        }
> +      })
> +    }
> +  } // End of PR01
> +} // End of HUBN
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchLpss.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchLpss.asl
> new file mode 100644
> index 0000000000..9510efd698
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchLpss.asl
> @@ -0,0 +1,1093 @@
> +/*********************************************************
> *****************;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
> +;*    Family of Customer Reference Boards.                                *;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Copyright (c) 2012  - 2016, Intel Corporation. All rights reserved    *;
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*********************************************************
> *****************/
> +//
> +// LPIO1 DMA#1 (Synopsis GP DMA)
> +//
> +Device (GDM1)
> +{
> +  Name (_HID, "INTL9C60")
> +  Name (_DDN, "Intel(R) DMA Controller #1 - INTL9C60")
> +  Name (_UID, 1)
> +
> +  Name (RBUF, ResourceTemplate ()
> +  {
> +    Memory32Fixed (ReadWrite, 0x00000000, 0x00004000, BAR0)
> +    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {42}  //
> DMA #1 IRQ
> +  })
> +  Method (_CRS, 0x0, NotSerialized)
> +  {
> +    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
> +    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
> +    Store(D10A, B0BA)
> +    Store(D10L, B0LN)
> +    Return (RBUF)
> +  }
> +  Method (_STA, 0x0, NotSerialized)
> +  {
> +    //
> +    // PCIM>> 0:ACPI mode           1:PCI mode
> +    //
> +    If (LEqual(PCIM, 1)) {
> +      Return (0x0)
> +    }
> +
> +    If (LOr(LEqual(D10A, 0), LEqual(L10D, 1)))
> +    {
> +      Return (0x0)
> +    }
> +    Return (0xF)
> +  }
> +}
> +
> +//
> +// LPIO1 DMA#2 (Synopsis GP DMA)
> +//
> +Device (GDM2)
> +{
> +  Name (_HID, "INTL9C60")
> +  Name (_DDN, "Intel(R) DMA Controller #2 - INTL9C60")
> +  Name (_UID, 2)
> +
> +  Name (RBUF, ResourceTemplate ()
> +  {
> +    Memory32Fixed (ReadWrite, 0x00000000, 0x00004000, BAR0)
> +    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {43}  //
> DMA #2 IRQ
> +  })
> +  Method (_CRS, 0x0, NotSerialized)
> +  {
> +    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
> +    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
> +    Store(D20A, B0BA)
> +    Store(D20L, B0LN)
> +    Return (RBUF)
> +  }
> +  Method (_STA, 0x0, NotSerialized)
> +  {
> +    //
> +    // PCIM>> 0:ACPI mode           1:PCI mode
> +    //
> +    If (LEqual(PCIM, 1)) {
> +      Return (0x0)
> +    }
> +
> +    If (LOr(LEqual(D20A, 0), LEqual(L20D, 1)))
> +    {
> +      Return (0x0)
> +    }
> +    Return (0xF)
> +  }
> +}
> +
> +//
> +// LPIO1 PWM #1
> +//
> +Device(PWM1)
> +{
> +  Name (_ADR, 0)
> +  Name (_HID, "80860F09")
> +  Name (_CID, "80860F09")
> +  Name (_DDN, "Intel(R) PWM Controller #1 - 80860F08")
> +  Name (_UID, 1)
> +
> +  Name (RBUF, ResourceTemplate ()
> +  {
> +    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
> +  })
> +  Method (_CRS, 0x0, NotSerialized)
> +  {
> +    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
> +    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
> +    Store(P10A, B0BA)
> +    Store(P10L, B0LN)
> +    Return (RBUF)
> +  }
> +  Method (_STA, 0x0, NotSerialized)
> +  {
> +    //
> +    // PCIM>> 0:ACPI mode           1:PCI mode
> +    //
> +    If (LEqual(PCIM, 1)) {
> +      Return (0x0)
> +    }
> +
> +    If (LOr(LEqual(P10A, 0), LEqual(L11D, 1)))
> +    {
> +      Return (0x0)
> +    }
> +    Return (0xF)
> +  }
> +}
> +
> +//
> +// LPIO1 PWM #2
> +//
> +Device(PWM2)
> +{
> +  Name (_ADR, 0)
> +  Name (_HID, "80860F09")
> +  Name (_CID, "80860F09")
> +  Name (_DDN, "Intel(R) PWM Controller #2 - 80860F09")
> +  Name (_UID, 2)
> +
> +  Name (RBUF, ResourceTemplate ()
> +  {
> +    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
> +  })
> +  Method (_CRS, 0x0, NotSerialized)
> +  {
> +    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
> +    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
> +    Store(P20A, B0BA)
> +    Store(P20L, B0LN)
> +    Return (RBUF)
> +  }
> +  Method (_STA, 0x0, NotSerialized)
> +  {
> +    //
> +    // PCIM>> 0:ACPI mode           1:PCI mode
> +    //
> +    If (LEqual(PCIM, 1)) {
> +      Return (0x0)
> +    }
> +
> +    If (LOr(LEqual(P20A, 0), LEqual(L12D, 1)))
> +    {
> +      Return (0x0)
> +    }
> +    Return (0xF)
> +  }
> +}
> +
> +//
> +// LPIO1 HS-UART #1
> +//
> +Device(URT1)
> +{
> +  Name (_ADR, 0)
> +  Name (_HID, "80860F0A")
> +  Name (_CID, "80860F0A")
> +  Name (_DDN, "Intel(R) HS-UART Controller #1 - 80860F0A")
> +  Name (_UID, 1)
> +  Name(_DEP, Package(0x1)
> +  {
> +    PEPD
> +  })
> +  Name (RBUF, ResourceTemplate ()
> +  {
> +    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
> +    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {39}  // HS-
> UART #1 IRQ
> +
> +    FixedDMA(0x2, 0x2, Width32Bit, )
> +    FixedDMA(0x3, 0x3, Width32Bit, )
> +  })
> +  Method (_HRV, 0x0, NotSerialized)
> +  {
> +    Return (SOCS)
> +  }
> +  Method (_CRS, 0x0, NotSerialized)
> +  {
> +    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
> +    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
> +    Store(U10A, B0BA)
> +    Store(U10L, B0LN)
> +    Return (RBUF)
> +  }
> +
> +  Method (_STA, 0x0, NotSerialized)
> +  {
> +    //
> +    // PCIM>> 0:ACPI mode           1:PCI mode
> +    //
> +    If (LEqual(PCIM, 1)) {
> +      Return (0x0)
> +    }
> +
> +    If (LOr(LEqual(U10A, 0), LEqual(L13D, 1)))
> +    {
> +      Return (0x0)
> +    }
> +    Return (0xF)
> +  }
> +
> +  Method (_PS3, 0, NotSerialized)
> +  {
> +    OR(PSAT, 0x00000003, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +  }
> +
> +  Method (_PS0, 0, NotSerialized)
> +  {
> +    And(PSAT, 0xfffffffC, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +  }
> +
> +  OperationRegion (KEYS, SystemMemory, U11A, 0x100)
> +  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
> +  {
> +    Offset (0x84),
> +    PSAT,   32
> +  }
> +}//  Device (URT1)
> +
> +//
> +// LPIO1 HS-UART #2
> +//
> +Device(URT2)
> +{
> +  Name (_ADR, 0)
> +  Name (_HID, "80860F0A")
> +  Name (_CID, "80860F0A")
> +  Name (_DDN, "Intel(R) HS-UART Controller #2 - 80860F0C")
> +  Name (_UID, 2)
> +
> +  Name(_DEP, Package(0x1)
> +  {
> +    PEPD
> +  })
> +
> +  Name (RBUF, ResourceTemplate ()
> +  {
> +    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
> +    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {40}  // HS-
> UART #2 IRQ
> +
> +    FixedDMA(0x4, 0x4, Width32Bit, )
> +    FixedDMA(0x5, 0x5, Width32Bit, )
> +  })
> +
> +  Method (_HRV, 0x0, NotSerialized)
> +  {
> +    Return (SOCS)
> +  }
> +
> +  Method (_CRS, 0x0, NotSerialized)
> +  {
> +    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
> +    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
> +    Store(U20A, B0BA)
> +    Store(U20L, B0LN)
> +    Return (RBUF)
> +  }
> +
> +  Method (_STA, 0x0, NotSerialized)
> +  {
> +    //
> +    // PCIM>> 0:ACPI mode           1:PCI mode
> +    //
> +    If (LEqual(PCIM, 1)) {
> +      Return (0x0)
> +    }
> +
> +    If (LOr(LEqual(U20A, 0), LEqual(L14D, 1)))
> +    {
> +      Return (0x0)
> +    }
> +    Return (0xF)
> +  }
> +
> +  Method (_PS3, 0, NotSerialized)
> +  {
> +    OR(PSAT, 0x00000003, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +  }
> +
> +  Method (_PS0, 0, NotSerialized)
> +  {
> +    And(PSAT, 0xfffffffC, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +  }
> +
> +  OperationRegion (KEYS, SystemMemory, U21A, 0x100)
> +  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
> +  {
> +    Offset (0x84),
> +    PSAT,   32
> +  }
> +}//  Device (URT2)
> +
> +//
> +// LPIO1 SPI
> +//
> +Device(SPI1)
> +{
> +  Name (_ADR, 0)
> +  Name (_HID, "80860F0E")
> +  Name (_CID, "80860F0E")
> +  Name (_UID, "0")  // Static bus number assignment
> +  Name(_DEP, Package(0x1)
> +  {
> +    PEPD
> +  })
> +  Name (_DDN, "Intel(R) SPI Controller - 80860F0E")
> +
> +  Name (RBUF, ResourceTemplate ()
> +  {
> +    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
> +    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {41}  // SPI
> IRQ
> +
> +    FixedDMA(0x0, 0x0, Width32Bit, )
> +    FixedDMA(0x1, 0x1, Width32Bit, )
> +  })
> +
> +  Method (_HRV, 0x0, NotSerialized)
> +  {
> +    Return (SOCS)
> +  }
> +
> +  Method (_CRS, 0x0, NotSerialized)
> +  {
> +    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
> +    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
> +    Store(SP0A, B0BA)
> +    Store(SP0L, B0LN)
> +    Return (RBUF)
> +  }
> +
> +  Method (_STA, 0x0, NotSerialized)
> +  {
> +    //
> +    // PCIM>> 0:ACPI mode           1:PCI mode
> +    //
> +    If (LEqual(PCIM, 1)) {
> +      Return (0x0)
> +    }
> +
> +    If (LOr(LEqual(SP0A, 0), LEqual(L15D, 1)))
> +    {
> +      Return (0x0)
> +    }
> +    Return (0xF)
> +  }
> +
> +  Method (_PS3, 0, NotSerialized)
> +  {
> +    OR(PSAT, 0x00000003, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +  }
> +
> +  Method (_PS0, 0, NotSerialized)
> +  {
> +    And(PSAT, 0xfffffffC, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +  }
> +
> +  OperationRegion (KEYS, SystemMemory, SP1A, 0x100)
> +  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
> +  {
> +    Offset (0x84),
> +           PSAT,   32
> +  }
> +}//  Device (SPI1)
> +
> +//
> +// LPIO2 I2C #1
> +//
> +Device(I2C1)
> +{
> +  Name (_ADR, 0)
> +  Name (_HID, "80860F41")
> +  Name (_CID, "80860F41")
> +  Name(_DEP, Package(0x1)
> +  {
> +    PEPD
> +  })
> +  Name (_DDN, "Intel(R) I2C Controller #1 - 80860F41")
> +  Name (_UID, 1)
> +
> +  Name (RBUF, ResourceTemplate ()
> +  {
> +    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
> +    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {32}  // I2C
> #1 IRQ
> +
> +    FixedDMA(0x10, 0x0, Width32Bit, )
> +    FixedDMA(0x11, 0x1, Width32Bit, )
> +  })
> +
> +  Method (SSCN, 0x0, NotSerialized)
> +  {
> +    Name (PKG, Package(3) { 0x200, 0x200, 0x06 })
> +    Return (PKG)
> +  }
> +  Method (FMCN, 0x0, NotSerialized)
> +  {
> +    Name (PKG, Package(3) { 0x55, 0x99, 0x06 })
> +    Return (PKG)
> +  }
> +  Method (FPCN, 0x0, NotSerialized)
> +  {
> +    Name (PKG, Package(3) { 0x1b, 0x3a, 0x06 })
> +    Return (PKG)
> +  }
> +
> +  Method (_HRV, 0x0, NotSerialized)
> +  {
> +    Return (SOCS)
> +  }
> +  Method (_CRS, 0x0, NotSerialized)
> +  {
> +    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
> +    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
> +    Store(I10A, B0BA)
> +    Store(I10L, B0LN)
> +    Return (RBUF)
> +  }
> +  Method (_STA, 0x0, NotSerialized)
> +  {
> +    //
> +    // PCIM>> 0:ACPI mode           1:PCI mode
> +    //
> +    If (LEqual(PCIM, 1)) {
> +      Return (0x0)
> +    }
> +
> +    If (LOr(LEqual(I10A, 0), LEqual(L21D, 1)))
> +    {
> +      Return (0x0)
> +    }
> +    Return (0xF)
> +
> +  }
> +
> +  Method (_PS3, 0, NotSerialized)
> +  {
> +    OR(PSAT, 0x00000003, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +  }
> +  Method (_PS0, 0, NotSerialized)
> +  {
> +    And(PSAT, 0xfffffffC, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +  }
> +  OperationRegion (KEYS, SystemMemory, I11A, 0x100)
> +  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
> +  {
> +    Offset (0x84),
> +           PSAT,   32
> +  }
> +
> +}
> +
> +//
> +// LPIO2 I2C #2
> +//
> +Device(I2C2)
> +{
> +  Name (_ADR, 0)
> +  Name (_HID, "80860F41")
> +  Name (_CID, "80860F41")
> +  Name(_DEP, Package(0x1)
> +  {
> +    PEPD
> +  })
> +  Name (_DDN, "Intel(R) I2C Controller #2 - 80860F42")
> +  Name (_UID, 2)
> +
> +  Name (RBUF, ResourceTemplate ()
> +  {
> +    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
> +    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {33}  // I2C
> #2 IRQ
> +
> +    FixedDMA(0x12, 0x2, Width32Bit, )
> +    FixedDMA(0x13, 0x3, Width32Bit, )
> +  })
> +
> +  Method (SSCN, 0x0, NotSerialized)
> +  {
> +    Name (PKG, Package(3) { 0x200, 0x200, 0x06 })
> +    Return (PKG)
> +  }
> +  Method (FMCN, 0x0, NotSerialized)
> +  {
> +    Name (PKG, Package(3) { 0x55, 0x99, 0x06 })
> +    Return (PKG)
> +  }
> +  Method (FPCN, 0x0, NotSerialized)
> +  {
> +    Name (PKG, Package(3) { 0x1b, 0x3a, 0x06 })
> +    Return (PKG)
> +  }
> +
> +  Method (_HRV, 0x0, NotSerialized)
> +  {
> +    Return (SOCS)
> +  }
> +  Method (_CRS, 0x0, NotSerialized)
> +  {
> +    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
> +    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
> +    Store(I20A, B0BA)
> +    Store(I20L, B0LN)
> +    Return (RBUF)
> +  }
> +  Method (_STA, 0x0, NotSerialized)
> +  {
> +    //
> +    // PCIM>> 0:ACPI mode           1:PCI mode
> +    //
> +    If (LEqual(PCIM, 1)) {
> +      Return (0x0)
> +    }
> +
> +    If (LOr(LEqual(I20A, 0), LEqual(L22D, 1)))
> +    {
> +      Return (0x0)
> +    }
> +    Return (0xF)
> +  }
> +
> +  Method (_PS3, 0, NotSerialized)
> +  {
> +    OR(PSAT, 0x00000003, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +
> +  }
> +  Method (_PS0, 0, NotSerialized)
> +  {
> +    And(PSAT, 0xfffffffC, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +  }
> +  OperationRegion (KEYS, SystemMemory, I21A, 0x100)
> +  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
> +  {
> +    Offset (0x84),
> +           PSAT,   32
> +  }
> +
> +
> +  //
> +  // Realtek Audio Codec
> +  //
> +  Device (RTEK)   //Audio Codec driver I2C
> +  {
> +    Name (_ADR, 0)
> +    Name (_HID, "10EC5640")
> +    Name (_CID, "10EC5640")
> +    Name (_DDN, "RTEK Codec Controller " )
> +    Name (_UID, 1)
> +
> +
> +    Method(_CRS, 0x0, Serialized)
> +    {
> +      Name(SBUF,ResourceTemplate ()
> +      {
> +        I2CSerialBus(0x1C,          //SlaveAddress: bus address
> +                     ,                         //SlaveMode: default to ControllerInitiated
> +                     400000,                   //ConnectionSpeed: in Hz
> +                     ,                         //Addressing Mode: default to 7 bit
> +                     "\\_SB.I2C2",             //ResourceSource: I2C bus controller name
> +                     ,                         //ResourceSourceIndex: defaults to 0
> +                     ,                         //ResourceUsage: Defaults to ResourceConsumer
> +                     ,                         //Descriptor Name: creates name for offset of
> resource descriptor
> +                    )  //VendorData
> +        GpioInt(Edge, ActiveHigh, ExclusiveAndWake, PullNone,
> 0,"\\_SB.GPO2") {4} //  AUD_INT
> +      })
> +      Return (SBUF)
> +    }
> +
> +    Method (_STA, 0x0, NotSerialized)
> +    {
> +
> +      If (LEqual(LPEE, 2)) { // LPE enable/disable
> +        If (LEqual(LPAD, 1))
> +        {
> +          Return(0xF)
> +        }
> +      }
> +      Return(0)
> +    }
> +
> +    Method (_DIS, 0x0, NotSerialized)
> +    {
> +
> +    }
> +  } // Device (RTEK)
> +} //  Device (I2C2)
> +
> +//
> +// LPIO2 I2C #3
> +//
> +Device(I2C3)
> +{
> +  Name (_ADR, 0)
> +  Name (_HID, "80860F41")
> +  Name (_CID, "80860F41")
> +  Name (_DDN, "Intel(R) I2C Controller #3 - 80860F43")
> +  Name (_UID, 3)
> +  Name(_DEP, Package(0x1)
> +  {
> +    PEPD
> +  })
> +  Name (RBUF, ResourceTemplate ()
> +  {
> +    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
> +    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {34}  // I2C
> #3 IRQ
> +
> +    FixedDMA(0x14, 0x4, Width32Bit, )
> +    FixedDMA(0x15, 0x5, Width32Bit, )
> +  })
> +
> +  Method (SSCN, 0x0, NotSerialized)
> +  {
> +    Name (PKG, Package(3) { 0x200, 0x200, 0x06 })
> +    Return (PKG)
> +  }
> +  Method (FMCN, 0x0, NotSerialized)
> +  {
> +    Name (PKG, Package(3) { 0x55, 0x99, 0x06 })
> +    Return (PKG)
> +  }
> +  Method (FPCN, 0x0, NotSerialized)
> +  {
> +    Name (PKG, Package(3) { 0x1b, 0x3a, 0x06 })
> +    Return (PKG)
> +  }
> +
> +  Method (_HRV, 0x0, NotSerialized)
> +  {
> +    Return (SOCS)
> +  }
> +  Method (_CRS, 0x0, NotSerialized)
> +  {
> +    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
> +    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
> +    Store(I30A, B0BA)
> +    Store(I30L, B0LN)
> +    Return (RBUF)
> +  }
> +
> +  Method (_STA, 0x0, NotSerialized)
> +  {
> +    //
> +    // PCIM>> 0:ACPI mode           1:PCI mode
> +    //
> +    If (LEqual(PCIM, 1)) {
> +      Return (0x0)
> +    }
> +
> +    If (LOr(LEqual(I30A, 0), LEqual(L23D, 1)))
> +    {
> +      Return (0x0)
> +    }
> +    Return (0xF)
> +  }
> +
> +  Method (_PS3, 0, NotSerialized)
> +  {
> +    OR(PSAT, 0x00000003, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +
> +  }
> +  Method (_PS0, 0, NotSerialized)
> +  {
> +    And(PSAT, 0xfffffffC, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +  }
> +  OperationRegion (KEYS, SystemMemory, I31A, 0x100)
> +  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
> +  {
> +    Offset (0x84),
> +    PSAT,   32
> +  }
> +
> +
> +}
> +
> +//
> +// LPIO2 I2C #4
> +//
> +Device(I2C4)
> +{
> +  Name (_ADR, 0)
> +  Name (_HID, "80860F41")
> +  Name (_CID, "80860F41")
> +  Name (_DDN, "Intel(R) I2C Controller #4 - 80860F44")
> +  Name (_UID, 4)
> +  Name(_DEP, Package(0x1)
> +  {
> +    PEPD
> +  })
> +  Name (RBUF, ResourceTemplate ()
> +  {
> +    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
> +    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {35}  // I2C
> #4 IRQ
> +
> +    FixedDMA(0x16, 0x6, Width32Bit, )
> +    FixedDMA(0x17, 0x7, Width32Bit, )
> +  })
> +
> +  Method (SSCN, 0x0, NotSerialized)
> +  {
> +    Name (PKG, Package(3) { 0x200, 0x200, 0x06 })
> +    Return (PKG)
> +  }
> +  Method (FMCN, 0x0, NotSerialized)
> +  {
> +    Name (PKG, Package(3) { 0x55, 0x99, 0x06 })
> +    Return (PKG)
> +  }
> +  Method (FPCN, 0x0, NotSerialized)
> +  {
> +    Name (PKG, Package(3) { 0x1b, 0x3a, 0x06 })
> +    Return (PKG)
> +  }
> +
> +
> +  Method (_HRV, 0x0, NotSerialized)
> +  {
> +    Return (SOCS)
> +  }
> +  Method (_CRS, 0x0, NotSerialized)
> +  {
> +    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
> +    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
> +    Store(I40A, B0BA)
> +    Store(I40L, B0LN)
> +    Return (RBUF)
> +  }
> +
> +  Method (_STA, 0x0, NotSerialized)
> +  {
> +    //
> +    // PCIM>> 0:ACPI mode           1:PCI mode
> +    //
> +    If (LEqual(PCIM, 1)) {
> +      Return (0x0)
> +    }
> +
> +    If (LOr(LEqual(I40A, 0), LEqual(L24D, 1)))
> +    {
> +      Return (0x0)
> +    }
> +    Return (0xF)
> +  }
> +
> +  Method (_PS3, 0, NotSerialized)
> +  {
> +    OR(PSAT, 0x00000003, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +
> +  }
> +  Method (_PS0, 0, NotSerialized)
> +  {
> +    And(PSAT, 0xfffffffC, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +  }
> +  OperationRegion (KEYS, SystemMemory, I41A, 0x100)
> +  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
> +  {
> +    Offset (0x84),
> +    PSAT,   32
> +  }
> +
> +  PowerResource (CLK0, 0x00, 0x0000)
> +  {
> +    Method (_STA, 0, NotSerialized)   // _STA: Status
> +    {
> +      Return (CKC0)
> +    }
> +
> +    Method (_ON, 0, NotSerialized)   // _ON_: Power On
> +    {
> +      Store (One, CKC0)
> +      Store (One, CKF0)
> +      Sleep (0x20)
> +    }
> +
> +    Method (_OFF, 0, NotSerialized)   // _OFF: Power Off
> +    {
> +      Store (0x02, CKC0)
> +    }
> +  }
> +  PowerResource (CLK1, 0x00, 0x0000)
> +  {
> +    Method (_STA, 0, NotSerialized)   // _STA: Status
> +    {
> +      Return (CKC1)
> +    }
> +
> +    Method (_ON, 0, NotSerialized)   // _ON_: Power On
> +    {
> +      Store (One, CKC1)
> +      Store (One, CKF1)
> +      Sleep (0x20)
> +    }
> +
> +    Method (_OFF, 0, NotSerialized)   // _OFF: Power Off
> +    {
> +      Store (0x02, CKC1)
> +    }
> +  }
> +}
> +
> +//
> +// LPIO2 I2C #5
> +//
> +Device(I2C5)
> +{
> +  Name (_ADR, 0)
> +  Name (_HID, "80860F41")
> +  Name (_CID, "80860F41")
> +  Name (_DDN, "Intel(R) I2C Controller #5 - 80860F45")
> +  Name (_UID, 5)
> +  Name(_DEP, Package(0x1)
> +  {
> +    PEPD
> +  })
> +  Name (RBUF, ResourceTemplate ()
> +  {
> +    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
> +    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {36}  // I2C
> #5 IRQ
> +
> +    FixedDMA(0x18, 0x0, Width32Bit, )
> +    FixedDMA(0x19, 0x1, Width32Bit, )
> +  })
> +
> +  Method (SSCN, 0x0, NotSerialized)
> +  {
> +    Name (PKG, Package(3) { 0x200, 0x200, 0x06 })
> +    Return (PKG)
> +  }
> +  Method (FMCN, 0x0, NotSerialized)
> +  {
> +    Name (PKG, Package(3) { 0x55, 0x99, 0x06 })
> +    Return (PKG)
> +  }
> +  Method (FPCN, 0x0, NotSerialized)
> +  {
> +    Name (PKG, Package(3) { 0x1b, 0x3a, 0x06 })
> +    Return (PKG)
> +  }
> +
> +  Method (_HRV, 0x0, NotSerialized)
> +  {
> +    Return (SOCS)
> +  }
> +  Method (_CRS, 0x0, NotSerialized)
> +  {
> +    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
> +    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
> +    Store(I50A, B0BA)
> +    Store(I50L, B0LN)
> +    Return (RBUF)
> +  }
> +  Method (_STA, 0x0, NotSerialized)
> +  {
> +    //
> +    // PCIM>> 0:ACPI mode           1:PCI mode
> +    //
> +    If (LEqual(PCIM, 1)) {
> +      Return (0x0)
> +    }
> +
> +    If (LOr(LEqual(I50A, 0), LEqual(L25D, 1)))
> +    {
> +      Return (0x0)
> +    }
> +    Return (0xF)
> +  }
> +
> +  Method (_PS3, 0, NotSerialized)
> +  {
> +    OR(PSAT, 0x00000003, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +  }
> +  Method (_PS0, 0, NotSerialized)
> +  {
> +    And(PSAT, 0xfffffffC, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +  }
> +  OperationRegion (KEYS, SystemMemory, I51A, 0x100)
> +  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
> +  {
> +    Offset (0x84),
> +    PSAT,   32
> +  }
> +}
> +
> +//
> +// LPIO2 I2C #6
> +//
> +Device(I2C6)
> +{
> +  Name (_ADR, 0)
> +  Name (_HID, "80860F41")
> +  Name (_CID, "80860F41")
> +  Name (_DDN, "Intel(R) I2C Controller #6 - 80860F46")
> +  Name (_UID, 6)
> +  Name(_DEP, Package(0x1)
> +  {
> +    PEPD
> +  })
> +  Name (RBUF, ResourceTemplate ()
> +  {
> +    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
> +    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {37}  // I2C
> #6 IRQ
> +
> +    FixedDMA(0x1A, 0x02, Width32Bit, )
> +    FixedDMA(0x1B, 0x03, Width32Bit, )
> +  })
> +
> +  Method (SSCN, 0x0, NotSerialized)
> +  {
> +    Name (PKG, Package(3) { 0x200, 0x200, 0x06 })
> +    Return (PKG)
> +  }
> +  Method (FMCN, 0x0, NotSerialized)
> +  {
> +    Name (PKG, Package(3) { 0x55, 0x99, 0x06 })
> +    Return (PKG)
> +  }
> +  Method (FPCN, 0x0, NotSerialized)
> +  {
> +    Name (PKG, Package(3) { 0x1b, 0x3a, 0x06 })
> +    Return (PKG)
> +  }
> +
> +  Method (_HRV, 0x0, NotSerialized)
> +  {
> +    Return (SOCS)
> +  }
> +  Method (_CRS, 0x0, NotSerialized)
> +  {
> +    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
> +    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
> +    Store(I60A, B0BA)
> +    Store(I60L, B0LN)
> +    Return (RBUF)
> +  }
> +  Method (_STA, 0x0, NotSerialized)
> +  {
> +    //
> +    // PCIM>> 0:ACPI mode           1:PCI mode
> +    //
> +    If (LEqual(PCIM, 1)) {
> +      Return (0x0)
> +    }
> +
> +    If (LOr(LEqual(I60A, 0), LEqual(L26D, 1)))
> +    {
> +      Return (0x0)
> +    }
> +    Return (0xF)
> +  }
> +
> +  Method (_PS3, 0, NotSerialized)
> +  {
> +    OR(PSAT, 0x00000003, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +  }
> +  Method (_PS0, 0, NotSerialized)
> +  {
> +    And(PSAT, 0xfffffffC, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +  }
> +  OperationRegion (KEYS, SystemMemory, I61A, 0x100)
> +  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
> +  {
> +    Offset (0x84),
> +           PSAT,   32
> +  }
> +}
> +
> +//
> +// LPIO2 I2C #7
> +//
> +Device(I2C7)
> +{
> +  Name (_ADR, 0)
> +  Name (_HID, "80860F41")
> +  Name (_CID, "80860F41")
> +  //Name (_CLS, Package (3) {0x0C, 0x80, 0x00})
> +  Name (_DDN, "Intel(R) I2C Controller #7 - 80860F47")
> +  Name (_UID, 7)
> +  Name(_DEP, Package(0x1)
> +  {
> +    PEPD
> +  })
> +  Name (RBUF, ResourceTemplate ()
> +  {
> +    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
> +    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {38}  // I2C
> #7 IRQ
> +
> +    FixedDMA(0x1C, 0x4, Width32Bit, )
> +    FixedDMA(0x1D, 0x5, Width32Bit, )
> +  })
> +
> +  Method (SSCN, 0x0, NotSerialized)
> +  {
> +    Name (PKG, Package(3) { 0x200, 0x200, 0x06 })
> +    Return (PKG)
> +  }
> +  Method (FMCN, 0x0, NotSerialized)
> +  {
> +    Name (PKG, Package(3) { 0x55, 0x99, 0x06 })
> +    Return (PKG)
> +  }
> +  Method (FPCN, 0x0, NotSerialized)
> +  {
> +    Name (PKG, Package(3) { 0x1b, 0x3a, 0x06 })
> +    Return (PKG)
> +  }
> +
> +  Method (_HRV, 0x0, NotSerialized)
> +  {
> +    Return (SOCS)
> +  }
> +
> +  Method (_CRS, 0x0, NotSerialized)
> +  {
> +    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
> +    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
> +    Store(I70A, B0BA)
> +    Store(I70L, B0LN)
> +    Return (RBUF)
> +  }
> +
> +  Method (_STA, 0x0, NotSerialized)
> +  {
> +    //
> +    // PCIM>> 0:ACPI mode           1:PCI mode
> +    //
> +    If (LEqual(PCIM, 1)) {
> +      Return (0x0)
> +    }
> +
> +    If (LOr(LEqual(I70A, 0), LEqual(L27D, 1)))
> +    {
> +      Return (0x0)
> +    }
> +    Return (0xF)
> +  }
> +
> +  Method (_PS3, 0, NotSerialized)
> +  {
> +    OR(PSAT, 0x00000003, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +  }
> +
> +  Method (_PS0, 0, NotSerialized)
> +  {
> +    And(PSAT, 0xfffffffC, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +  }
> +
> +  OperationRegion (KEYS, SystemMemory, I71A, 0x100)
> +  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
> +  {
> +    Offset (0x84),
> +    PSAT,   32
> +  }
> +
> +}
> +
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchPcie.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchPcie.asl
> new file mode 100644
> index 0000000000..7b32ea2dae
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchPcie.asl
> @@ -0,0 +1,50 @@
> +/*********************************************************
> *****************;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
> +;*    Family of Customer Reference Boards.                                *;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Copyright (c)  2011  - 2014, Intel Corporation. All rights reserved   *;
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*********************************************************
> *****************/
> +
> +
> +OperationRegion(PXCS,PCI_Config,0x40,0xC0)
> +Field(PXCS,AnyAcc, NoLock, Preserve)
> +{
> +  Offset(0x10), // LCTL - Link Control Register
> +  L0SE, 1,      // 0, L0s Entry Enabled
> +  , 7,
> +  Offset(0x12), // LSTS - Link Status Register
> +  , 13,
> +  LASX, 1,      // 0, Link Active Status
> +  Offset(0x1A), // SLSTS[7:0] - Slot Status Register
> +  ABPX, 1,      // 0, Attention Button Pressed
> +  , 2,
> +  PDCX, 1,      // 3, Presence Detect Changed
> +  , 2,
> +  PDSX, 1,      // 6, Presence Detect State
> +  , 1,
> +  Offset(0x20), // RSTS - Root Status Register
> +  , 16,
> +  PSPX, 1,      // 16,        PME Status
> +}
> +
> +
> +Device(PXSX)
> +{
> +  Name(_ADR, 0x00000000)
> +
> +  // NOTE:  Any PCIE Hot-Plug dependency for this port is
> +  // specific to the CRB.  Please modify the code based on
> +  // your platform requirements.
> +
> +  Name(_PRW, Package() {9,4})
> +}
> +
> +
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchScc.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchScc.asl
> new file mode 100644
> index 0000000000..78a928a5da
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchScc.asl
> @@ -0,0 +1,610 @@
> +/*********************************************************
> *****************;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
> +;*    Family of Customer Reference Boards.                                *;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved    *;
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*********************************************************
> *****************/
> +Device (PEPD)
> +{
> +  Name (_HID, "INT3396")
> +  Name(_CID, 0x800dd041)
> +  Name (_UID, 0x1)
> +
> +  // Indicates if the platform PEP has loaded
> +  Name(PEPP, Zero)
> +
> +  // Devices score-boarded by the PEP, Rev0 format
> +  Name (DEVS, Package() {0})
> +
> +  // Devices score-boarded by the PEP, Rev1 format
> +  Name(DEVX, Package()
> +  {
> +    Package () {"\\_SB.PCI0.XHC1", 0x1},
> +    Package () {"\\_SB.PCI0.EHC1", 0x1},
> +    Package () {"\\_SB.PCI0.GFX0", 0x1},
> +    Package () {"\\_SB.PCI0.GFX0.ISP0", 0x1},
> +    Package () {"\\_SB.PCI0.SEC0", 0x1},
> +    Package () {"\\_SB.I2C1", 0x1},
> +    Package () {"\\_SB.I2C2", 0x1},
> +    Package () {"\\_SB.I2C3", 0x1},
> +    Package () {"\\_SB.I2C4", 0x1},
> +    Package () {"\\_SB.I2C5", 0x1},
> +    Package () {"\\_SB.I2C6", 0x1},
> +    Package () {"\\_SB.I2C7", 0x1},
> +    Package () {"\\_SB.SDHA", 0x1},
> +    Package () {"\\_SB.SDHB", 0x1},
> +    Package () {"\\_SB.SDHC", 0x1},
> +    Package () {"\\_SB.SPI1", 0x1},
> +    Package () {"\\_SB.URT1", 0x1},
> +    Package () {"\\_SB.URT2", 0x1},
> +  })
> +  // Crashdump device package
> +  Name(CDMP, Package(2) {})
> +  // Device dependency for uPEP
> +  Name(DEVY, Package()
> +  {
> +    Package() {"\\_PR.CPU0", 0x1, Package() {Package() {0xFF, 0}}},
> +    Package() {"\\_PR.CPU1", 0x1, Package() {Package() {0xFF, 0}}},
> +    Package() {"\\_PR.CPU2", 0x1, Package() {Package() {0xFF, 0}}},
> +    Package() {"\\_PR.CPU3", 0x1, Package() {Package() {0xFF, 0}}},
> +    Package() {"\\_SB.I2C1", 0x1, Package() {Package() {0xFF,3}}},
> +    Package() {"\\_SB.I2C2", 0x1, Package() {Package() {0xFF,3}}},
> +    Package() {"\\_SB.I2C3", 0x1, Package() {Package() {0xFF,3}}},
> +    Package() {"\\_SB.I2C4", 0x1, Package() {Package() {0xFF,3}}},
> +    Package() {"\\_SB.I2C5", 0x1, Package() {Package() {0xFF,3}}},
> +    Package() {"\\_SB.I2C6", 0x1, Package() {Package() {0xFF,3}}},
> +    Package() {"\\_SB.I2C7", 0x1, Package() {Package() {0xFF,3}}},
> +    Package() {"\\_SB.PCI0.GFX0", 0x1, Package() {Package() {0xFF,3}}},
> +    Package() {"\\_SB.PCI0.SEC0", 0x1, Package() {Package() {0xFF,3}}},
> +    Package() {"\\_SB.PCI0.XHC1", 0x1, Package() {Package() {0xFF,3}}},
> +    Package() {"\\_SB.PCI0.GFX0.ISP0", 0x1, Package() {Package() {0xFF,3}}},
> +    Package() {"\\_SB.LPEA", 0x1, Package() {Package() {0x0,3}, Package()
> {0x1,0}, Package() {0x2,3}, Package() {0x3,3}}},
> +    Package() {"\\_SB.SDHA", 0x1, Package() {Package() {0xFF,3}}},
> +    Package() {"\\_SB.SDHB", 0x1, Package() {Package() {0xFF,3}}},
> +    Package() {"\\_SB.SDHC", 0x1, Package() {Package() {0xFF,3}}},
> +    Package() {"\\_SB.SPI1", 0x1, Package() {Package() {0xFF,3}}},
> +    Package() {"\\_SB.URT1", 0x1, Package() {Package() {0xFF,3}}},
> +    Package() {"\\_SB.URT2", 0x1, Package() {Package() {0xFF,3}}}
> +  })
> +  // BCCD crashdump information
> +  Name(BCCD, Package()
> +  {
> +    Package()
> +    {
> +      "\\_SB.SDHA",
> +      Package()
> +      {
> +        Package() { Package() {0, 32, 0,  3, 0xFFFFFFFFFFFFFFFF}, Package()
> {0xFFFFFFFC, 0x0, 0x4}, 0}
> +      }
> +    }
> +  })
> +
> +  Method(_STA, 0x0, NotSerialized)
> +  {
> +    Return(0xf)
> +  }
> +
> +  Method(_DSM, 0x4, Serialized)
> +  {
> +    If(LEqual(Arg0,ToUUID("B8FEBFE0-BAF8-454b-AECD-49FB91137B21")))
> +    {
> +
> +      // Number of fn IDs supported
> +      If(LEqual(Arg2, Zero))
> +      {
> +        Return(Buffer(One)
> +        {
> +          0xf
> +        })
> +      }
> +
> +      // Pep presence
> +      If(LEqual(Arg2, One))
> +      {
> +        Store(0x1, PEPP)
> +        Return(0xf)
> +      }
> +
> +      // Mitigation devices
> +      If(LEqual(Arg2, 0x2))
> +      {
> +        If(LEqual(Arg1, 0x0))
> +        {
> +          // Rev0
> +          Return(DEVS)
> +        }
> +        If(LEqual(Arg1, 0x1))
> +        {
> +          // Rev1
> +          Return(DEVX)
> +        }
> +      }
> +
> +      // Crashdump device data
> +      If(LEqual(Arg2, 0x3))
> +      {
> +        Store("\\_SB.SDHA", Index(CDMP,0))
> +        Store(EM1A, Index(CDMP,1))
> +        Return(CDMP)
> +      }
> +    }
> +    // New UUID for built-in uPEP
> +    If(LEqual(Arg0,ToUUID("C4EB40A0-6CD2-11E2-BCFD-0800200C9A66")))
> +    {
> +
> +      // Number of fn IDs supported
> +      If(LEqual(Arg2, Zero))
> +      {
> +        Return(Buffer(One)
> +        {
> +          0x7
> +        })
> +      }
> +      // LPI device dependencies
> +      If(LEqual(Arg2, 0x1))
> +      {
> +        Return(DEVY)
> +      }
> +      // Crashdump device data
> +      If(LEqual(Arg2, 0x2))
> +      {
> +        Store(EM1A, Local0)
> +        Add(Local0, 0x84, Local0)
> +        Store(Local0,
> Index(DerefOf(Index(DerefOf(Index(DerefOf(Index(DerefOf(Index(BCCD,
> Zero, )), One, )), Zero, )), Zero, )), 0x4, ))
> +        Return(BCCD)
> +      }
> +    }
> +
> +    Return(One)
> +  }
> +}
> +
> +//
> +// eMMC 4.41
> +//
> +Device(SDHA)
> +{
> +  Name (_ADR, 0)
> +  Name (_HID, "80860F14")
> +  Name (_CID, "PNP0D40")
> +  Name (_DDN, "Intel(R) eMMC Controller - 80860F14")
> +  Name (_UID, 1)
> +  Name(_DEP, Package(0x1)
> +  {
> +    PEPD
> +  })
> +
> +  Name (RBF1, ResourceTemplate ()
> +  {
> +    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
> +    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {45}  //
> eMMC 4.41 IRQ
> +  })
> +
> +  Method (_CRS, 0x0, NotSerialized)
> +  {
> +    // Update the Base address for BAR0 of eMMC 4.41
> +    CreateDwordField(^RBF1, ^BAR0._BAS, B0B1)
> +    CreateDwordField(^RBF1, ^BAR0._LEN, B0L1)
> +    Store(eM0A, B0B1)
> +    Store(eM0L, B0L1)
> +    Return (RBF1)
> +  }
> +  Method (_STA, 0x0, NotSerialized)
> +  {
> +    //
> +    // PCIM>> 0:ACPI mode            1:PCI mode
> +    // SD1D>> 0:eMMC 4.41 enable     1:eMMC 4.41 disable
> +    //
> +    If (LAnd(LEqual(PCIM, 0), LEqual(SD1D, 0)))
> +    {
> +      Return (0xF)
> +    }
> +    Else
> +    {
> +      Return (0x0)
> +    }
> +  }
> +
> +
> +  Method (_PS3, 0, NotSerialized)
> +  {
> +    OR(PSAT, 0x00000003, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +    //
> +    // If not B1, still keep 2 ms w/a
> +    //
> +    If(LLess(SOCS, 0x03))
> +    {
> +      Sleep(2)
> +    }
> +  }
> +  Method (_PS0, 0, NotSerialized)
> +  {
> +    And(PSAT, 0xfffffffC, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +    //
> +    // If not B1, still keep 2 ms w/a
> +    //
> +    If(LLess(SOCS, 0x03))
> +    {
> +      Sleep(2)
> +    }
> +  }
> +
> +  OperationRegion (KEYS, SystemMemory, eM1A, 0x100)
> +  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
> +  {
> +    Offset (0x84),
> +           PSAT,  32
> +  }
> +
> +         Method (_DIS, 0x0, NotSerialized)
> +  {
> +    //Adding dummy disable methods for device EMM0
> +  }
> +
> +  Device (EMMD)
> +  {
> +    Name (_ADR, 0x00000008) // Slot 0, Function 8
> +    Method (_RMV, 0, NotSerialized)
> +    {
> +      Return (0x0)
> +    }
> +  }
> +}
> +
> +
> +//
> +// eMMC 4.5
> +//
> +Device(SDHD)
> +{
> +  Name (_ADR, 0)
> +  Name (_HID, "80860F14")
> +  Name (_CID, "PNP0D40")
> +  Name (_DDN, "Intel(R) eMMC Controller - 80860F14")
> +  Name (_UID, 1)
> +  Name(_DEP, Package(0x1)
> +  {
> +    PEPD
> +  })
> +
> +  Name (RBF1, ResourceTemplate ()
> +  {
> +    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
> +    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {44}  //
> eMMC 4.5 IRQ
> +  })
> +  Method (_CRS, 0x0, NotSerialized)
> +  {
> +    CreateDwordField(^RBF1, ^BAR0._BAS, B0B1)
> +    CreateDwordField(^RBF1, ^BAR0._LEN, B0L1)
> +    Store(eM0A, B0B1)
> +    Store(eM0L, B0L1)
> +    Return (RBF1)
> +  }
> +  Method (_STA, 0x0, NotSerialized)
> +  {
> +    //
> +    // PCIM>> 0:ACPI mode           1:PCI mode
> +    // HSID>> 0:eMMC 4.5 enable     1:eMMC 4.5 disable
> +    //
> +    If (LAnd(LEqual(PCIM, 0), LEqual(HSID, 0)))
> +    {
> +      Return (0xF)
> +    }
> +    Else
> +    {
> +      Return (0x0)
> +    }
> +  }
> +
> +
> +  Method (_PS3, 0, NotSerialized)
> +  {
> +    OR(PSAT, 0x00000003, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +    //
> +    // If not B1, still keep 2 ms w/a
> +    //
> +    If(LLess(SOCS, 0x03))
> +    {
> +      Sleep(2)
> +    }
> +  }
> +  Method (_PS0, 0, NotSerialized)
> +  {
> +    And(PSAT, 0xfffffffC, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +    //
> +    // If not B1, still keep 2 ms w/a
> +    //
> +    If(LLess(SOCS, 0x03))
> +    {
> +      Sleep(2)
> +    }
> +  }
> +
> +  OperationRegion (KEYS, SystemMemory, eM1A, 0x100)
> +  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
> +  {
> +    Offset (0x84),
> +           PSAT,  32
> +  }
> +
> +         Method (_DIS, 0x0, NotSerialized)
> +  {
> +    //Adding dummy disable methods for device EMM0
> +  }
> +
> +  Device (EM45)
> +  {
> +    Name (_ADR, 0x00000008) // Slot 0, Function 8
> +    Method (_RMV, 0, NotSerialized)
> +    {
> +      Return (0x0)
> +    }
> +  }
> +}
> +
> +
> +//
> +// SDIO
> +//
> +Device(SDHB)
> +{
> +  Name (_ADR, 0)
> +  Name (_HID, "INT33BB")
> +  Name (_CID, "PNP0D40")
> +  Name (_DDN, "Intel(R) SDIO Controller - 80860F15")
> +  Name (_UID, 2)
> +  Name (_HRV, 2)
> +  Name(_DEP, Package(0x01)
> +  {
> +    PEPD
> +  })
> +  Name (PSTS, 0x0)
> +
> +  Name (RBUF, ResourceTemplate ()
> +  {
> +    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
> +    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {46}  //
> SDIO IRQ
> +  })
> +
> +  Method (_CRS, 0x0, NotSerialized)
> +  {
> +
> +    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
> +    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
> +    Store(SI0A, B0BA)
> +    Store(SI0L, B0LN)
> +    Return (RBUF)
> +  }
> +  Method (_STA, 0x0, NotSerialized)
> +  {
> +    If (LLessEqual(STEP, 0x04))
> +    {
> +      //A stepping
> +      Store(SDMD, _HRV)
> +    }
> +
> +    //
> +    // PCIM>> 0:ACPI mode           1:PCI mode
> +    //
> +    If (LEqual(PCIM, 1)) {
> +      Return (0x0)
> +    }
> +
> +    If (LOr(LEqual(SI0A, 0), LEqual(SD2D, 1)))
> +    {
> +      Return (0x0)
> +    }
> +    Return (0xF)
> +  }
> +  Method (_DIS, 0x0, NotSerialized)
> +  {
> +    //Adding dummy disable methods for device EMM0
> +  }
> +
> +  Method (_PS3, 0, NotSerialized)
> +  {
> +    OR(PSAT, 0x00000003, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +  }
> +  Method (_PS0, 0, NotSerialized)
> +  {
> +    And(PSAT, 0xfffffffC, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +
> +    if(LEqual(\_SB.SDHB.PSTS,0x0))
> +    {
> +      if(LEqual (\_SB.GPO2.AVBL, 1))
> +      {
> +        Store( 0x01, \_SB.GPO2.WFD3 ) // WL_WIFI_REQ_ON = 1 put the device
> to normal state
> +        Store( 0x01, \_SB.SDHB.PSTS)  // indicates that the device powered ON
> +      }
> +    }
> +
> +
> +  }
> +  OperationRegion (KEYS, SystemMemory, SI1A, 0x100)
> +  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
> +  {
> +    Offset (0x84),
> +           PSAT,   32
> +  }
> +
> +
> +         Device (BRCM)
> +  {
> +    Name (_ADR, 0x01)                 //SlotNumber + Function
> +    Name (_DEP, Package() {\_SB.GPO2})
> +
> +    Method (_RMV, 0, NotSerialized)
> +    {
> +      Return (0x0)
> +    }
> +    Name (_PRW, Package() {0, 0})
> +    Name (_S4W, 2)
> +
> +    Method (_CRS, 0, Serialized)
> +    {
> +      Name (RBUF, ResourceTemplate ()
> +      {
> +        Interrupt (ResourceConsumer, Edge, ActiveHigh, ExclusiveAndWake, , , )
> {73}
> +      })
> +      Return (RBUF)
> +    }
> +
> +    Method (_PS3, 0, NotSerialized)
> +    {
> +      if(LEqual (\_SB.GPO2.AVBL, 1))
> +      {
> +        Store( 0x00, \_SB.GPO2.WFD3 ) // WL_WIFI_REQ_ON = 0 puts the
> device in reset state
> +        Store( 0x00, \_SB.SDHB.PSTS) //Indicates that the device is powered off
> +      }
> +
> +    }
> +    Method (_PS0, 0, NotSerialized)
> +    {
> +      if(LEqual(\_SB.SDHB.PSTS,0x0))
> +      {
> +        if(LEqual (\_SB.GPO2.AVBL, 1))
> +        {
> +          Store( 0x01, \_SB.GPO2.WFD3 ) // WL_WIFI_REQ_ON = 1 put the
> device to normal state
> +          Store( 0x01, \_SB.SDHB.PSTS)     // indicates that the device powered
> ON
> +        }
> +      }
> +    }
> +  } // Device (BRCM)
> +  //
> +  // Secondary Broadcom WIFI function
> +  //
> +  Device(BRC2)
> +  {
> +    Name(_ADR, 0x2) // function 2
> +    Name(_STA, 0xf)
> +    //
> +    // The device is not removable. This must be a method.
> +    //
> +    Method(_RMV, 0x0, NotSerialized)
> +    {
> +      Return(0x0)
> +    }
> +
> +    //
> +    // Describe a vendor-defined connection between this device and the
> +    // primary wifi device
> +    //
> +
> +    Method(_CRS)
> +    {
> +      Name(NAM, Buffer() {"\\_SB.SDHB.BRCM"})
> +      Name(SPB, Buffer()
> +      {
> +        0x8E,       // SPB Descriptor
> +        0x18, 0x00, // Length including NAM above
> +        0x01,       // +0x00 SPB Descriptor Revision
> +        0x00,       // +0x01 Resource Source Index
> +        0xc0,       // +0x02 Bus type - vendor defined
> +        0x02,       // +0x03 Consumer + controller initiated
> +        0x00, 0x00, // +0x04 Type specific flags
> +        0x01,       // +0x06 Type specific revision
> +        0x00, 0x00  // +0x07 type specific data length
> +        // +0x09 - 0xf bytes for NULL-terminated NAM
> +        // Length = 0x18
> +      })
> +
> +      Name(END, Buffer() {0x79, 0x00})
> +      Concatenate(SPB, NAM, Local0)
> +      Concatenate(Local0, END, Local1)
> +      Return(Local1)
> +    }
> +  }
> +
> +}
> +
> +//
> +// SD Card
> +//
> +Device(SDHC)
> +{
> +  Name (_ADR, 0)
> +  Name (_HID, "80860F16")
> +  Name (_CID, "PNP0D40")
> +  Name (_DDN, "Intel(R) SD Card Controller - 80860F16")
> +  Name (_UID, 3)
> +  Name(_DEP, Package(0x01)
> +  {
> +    PEPD
> +  })
> +  Name (RBUF, ResourceTemplate ()
> +  {
> +    Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
> +    Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {47}  // SD
> Card IRQ
> +  })
> +  Method (_CRS, 0x0, NotSerialized)
> +  {
> +    CreateDwordField(^RBUF, ^BAR0._BAS, B0BA)
> +    CreateDwordField(^RBUF, ^BAR0._LEN, B0LN)
> +    Store(SD0A, B0BA)
> +    Store(SD0L, B0LN)
> +    Return (RBUF)
> +  }
> +  Method (_STA, 0x0, NotSerialized)
> +  {
> +    //
> +    // PCIM>> 0:ACPI mode           1:PCI mode
> +    //
> +    If (LEqual(PCIM, 1)) {
> +      Return (0x0)
> +    }
> +
> +    If (LOr(LEqual(SD0A, 0), LEqual(SD3D, 1)))
> +    {
> +      Return (0x0)
> +    }
> +    Return (0xF)
> +  }
> +
> +  Method (_PS3, 0, NotSerialized)
> +  {
> +    OR(PSAT, 0x00000003, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +  }
> +  Method (_PS0, 0, NotSerialized)
> +  {
> +    And(PSAT, 0xfffffffC, PSAT)
> +    OR(PSAT, 0X00000000, PSAT)
> +  }
> +  OperationRegion (KEYS, SystemMemory, SD1A, 0x100)
> +  Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
> +  {
> +    Offset (0x84),
> +           PSAT,   32
> +  }
> +
> +  Device (CARD)
> +  {
> +    Name (_ADR, 0x00000008)
> +    Method(_RMV, 0x0, NotSerialized)
> +    {
> +      // SDRM = 0 non-removable;
> +      If (LEqual(SDRM, 0))
> +      {
> +        Return (0)
> +      }
> +
> +      Return (1)
> +    }
> +  }
> +
> +}
> +
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchSmb.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchSmb.asl
> new file mode 100644
> index 0000000000..4de0c32927
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchSmb.asl
> @@ -0,0 +1,833 @@
> +/*********************************************************
> *****************;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
> +;*    Family of Customer Reference Boards.                                *;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved   *;
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*********************************************************
> *****************/
> +
> +
> +// Define various SMBus PCI Configuration Space Registers.
> +
> +OperationRegion(SMBP,PCI_Config,0x40,0xC0)
> +Field(SMBP,DWordAcc,NoLock,Preserve)
> +{
> +  ,     2,
> +  I2CE, 1
> +}
> +
> +// SMBus Send Byte - This function will write a single byte of
> +// data to a specific Slave Device per SMBus Send Byte Protocol.
> +//      Arg0 = Address
> +//      Arg1 = Data
> +//      Return: Success = 1
> +//              Failure = 0
> +
> +      Method(SSXB,2,Serialized)
> +{
> +  OperationRegion(SMPB,PCI_Config,0x20,4)
> +  Field(SMPB,DWordAcc,NoLock,Preserve)
> +  {
> +    ,     5,
> +    SBAR, 11
> +  }
> +
> +  // Define various SMBus IO Mapped Registers.
> +
> +  OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10)
> +  Field(SMBI,ByteAcc,NoLock,Preserve)
> +  {
> +    HSTS, 8,        // 0 - Host Status Register
> +    Offset(0x02),
> +    HCON, 8,        // 2 - Host Control
> +    HCOM, 8,        // 3 - Host Command
> +    TXSA, 8,        // 4 - Transmit Slave Address
> +    DAT0, 8,        // 5 - Host Data 0
> +    DAT1, 8,        // 6 - Host Data 1
> +    HBDR, 8,        // 7 - Host Block Data
> +    PECR, 8,        // 8 - Packer Error Check
> +    RXSA, 8,        // 9 - Receive Slave Address
> +    SDAT, 16,       // A - Slave Data
> +  }
> +
> +  // Step 1:  Confirm the ICHx SMBus is ready to perform
> +  // communication.
> +
> +  If(STRT())
> +  {
> +    Return(0)
> +  }
> +
> +  // Step 2:  Initiate a Send Byte.
> +
> +  Store(0,I2CE)                           // Ensure SMbus Mode.
> +  Store(0xBF,HSTS)                        // Clear all but INUSE_STS.
> +  Store(Arg0,TXSA)                        // Write Address in TXSA.
> +  Store(Arg1,HCOM)                        // Data in HCOM.
> +
> +  // Set the SMBus Host control register to 0x48.
> +  //   Bit 7:    =  0  = reserved
> +  //   Bit 6:    =  1  = start
> +  //   Bit 5:    =  0  = disregard, I2C related bit
> +  //   Bits 4:2: = 001 = Byte Protocol
> +  //   Bit 1:    =  0  = Normal Function
> +  //   Bit 0:    =  0  = Disable interrupt generation
> +
> +  Store(0x48,HCON)
> +
> +  // Step 3:  Exit the Method correctly.
> +
> +  If(COMP)
> +  {
> +    Or(HSTS,0xFF,HSTS)              // Clear INUSE_STS and others..
> +    Return(1)                       // Return Success.
> +  }
> +
> +  Return(0)
> +}
> +
> +// SMBus Receive Byte - This function will write a single byte
> +// of data to a specific Slave Device per SMBus Receive Byte
> +// Protocol.
> +//      Arg0 = Address
> +//      Return: Success = Byte-Size Value
> +//              Failure = Word-Size Value = FFFFh.
> +
> +Method(SRXB,1,Serialized)
> +{
> +  OperationRegion(SMPB,PCI_Config,0x20,4)
> +  Field(SMPB,DWordAcc,NoLock,Preserve)
> +  {
> +    ,     5,
> +    SBAR, 11
> +  }
> +
> +  // Define various SMBus IO Mapped Registers.
> +
> +  OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10)
> +  Field(SMBI,ByteAcc,NoLock,Preserve)
> +  {
> +    HSTS, 8,        // 0 - Host Status Register
> +    Offset(0x02),
> +    HCON, 8,        // 2 - Host Control
> +    HCOM, 8,        // 3 - Host Command
> +    TXSA, 8,        // 4 - Transmit Slave Address
> +    DAT0, 8,        // 5 - Host Data 0
> +    DAT1, 8,        // 6 - Host Data 1
> +    HBDR, 8,        // 7 - Host Block Data
> +    PECR, 8,        // 8 - Packer Error Check
> +    RXSA, 8,        // 9 - Receive Slave Address
> +    SDAT, 16,       // A - Slave Data
> +  }
> +  // Step 1:  Confirm the ICHx SMBus is ready to perform
> +  // communication.
> +
> +  If(STRT())
> +  {
> +    Return(0xFFFF)
> +  }
> +
> +  // Step 2:  Initiate a Receive Byte.
> +
> +  Store(0,I2CE)                           // Ensure SMbus Mode.
> +  Store(0xBF,HSTS)                        // Clear all but INUSE_STS.
> +  Store(Or(Arg0,1),TXSA)                  // Read Address in TXSA.
> +
> +  // Set the SMBus Host control register to 0x48.
> +  //   Bit 7:    =  0  = reserved
> +  //   Bit 6:    =  1  = start
> +  //   Bit 5:    =  0  = disregard, I2C related bit
> +  //   Bits 4:2: = 001 = Byte Protocol
> +  //   Bit 1:    =  0  = Normal Function
> +  //   Bit 0:    =  0  = Disable interrupt generation
> +
> +  Store(0x44,HCON)
> +
> +  // Step 3:  Exit the Method correctly.
> +
> +  If(COMP)
> +  {
> +    Or(HSTS,0xFF,HSTS)              // Clear INUSE_STS and others..
> +    Return(DAT0)                    // Return Success.
> +  }
> +
> +  Return(0xFFFF)                          // Return Failure.
> +}
> +
> +// SMBus Write Byte - This function will write a single byte
> +// of data to a specific Slave Device per SMBus Write Byte
> +// Protocol.
> +//      Arg0 = Address
> +//      Arg1 = Command
> +//      Arg2 = Data
> +//      Return: Success = 1
> +//              Failure = 0
> +
> +Method(SWRB,3,Serialized)
> +{
> +  OperationRegion(SMPB,PCI_Config,0x20,4)
> +  Field(SMPB,DWordAcc,NoLock,Preserve)
> +  {
> +    ,     5,
> +    SBAR, 11
> +  }
> +
> +  // Define various SMBus IO Mapped Registers.
> +
> +  OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10)
> +  Field(SMBI,ByteAcc,NoLock,Preserve)
> +  {
> +    HSTS, 8,        // 0 - Host Status Register
> +    Offset(0x02),
> +    HCON, 8,        // 2 - Host Control
> +    HCOM, 8,        // 3 - Host Command
> +    TXSA, 8,        // 4 - Transmit Slave Address
> +    DAT0, 8,        // 5 - Host Data 0
> +    DAT1, 8,        // 6 - Host Data 1
> +    HBDR, 8,        // 7 - Host Block Data
> +    PECR, 8,        // 8 - Packer Error Check
> +    RXSA, 8,        // 9 - Receive Slave Address
> +    SDAT, 16,       // A - Slave Data
> +  }
> +  // Step 1:  Confirm the ICHx SMBus is ready to perform communication.
> +
> +  If(STRT())
> +  {
> +    Return(0)
> +  }
> +
> +  // Step 2:  Initiate a Write Byte.
> +
> +  Store(0,I2CE)                           // Ensure SMbus Mode.
> +  Store(0xBF,HSTS)                        // Clear all but INUSE_STS.
> +  Store(Arg0,TXSA)                        // Write Address in TXSA.
> +  Store(Arg1,HCOM)                        // Command in HCOM.
> +  Store(Arg2,DAT0)                        // Data in DAT0.
> +
> +  // Set the SMBus Host control register to 0x48.
> +  //   Bit 7:    =  0  = reserved
> +  //   Bit 6:    =  1  = start
> +  //   Bit 5:    =  0  = disregard, I2C related bit
> +  //   Bits 4:2: = 010 = Byte Data Protocol
> +  //   Bit 1:    =  0  = Normal Function
> +  //   Bit 0:    =  0  = Disable interrupt generation
> +
> +  Store(0x48,HCON)
> +
> +  // Step 3:  Exit the Method correctly.
> +
> +  If(COMP)
> +  {
> +    Or(HSTS,0xFF,HSTS)              // Clear INUSE_STS and others..
> +    Return(1)                       // Return Success.
> +  }
> +
> +  Return(0)                               // Return Failure.
> +}
> +
> +// SMBus Read Byte - This function will read a single byte of data
> +// from a specific slave device per SMBus Read Byte Protocol.
> +//      Arg0 = Address
> +//      Arg1 = Command
> +//      Return: Success = Byte-Size Value
> +//              Failure = Word-Size Value
> +
> +Method(SRDB,2,Serialized)
> +{
> +  OperationRegion(SMPB,PCI_Config,0x20,4)
> +  Field(SMPB,DWordAcc,NoLock,Preserve)
> +  {
> +    ,     5,
> +    SBAR, 11
> +  }
> +
> +  // Define various SMBus IO Mapped Registers.
> +
> +  OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10)
> +  Field(SMBI,ByteAcc,NoLock,Preserve)
> +  {
> +    HSTS, 8,        // 0 - Host Status Register
> +    Offset(0x02),
> +    HCON, 8,        // 2 - Host Control
> +    HCOM, 8,        // 3 - Host Command
> +    TXSA, 8,        // 4 - Transmit Slave Address
> +    DAT0, 8,        // 5 - Host Data 0
> +    DAT1, 8,        // 6 - Host Data 1
> +    HBDR, 8,        // 7 - Host Block Data
> +    PECR, 8,        // 8 - Packer Error Check
> +    RXSA, 8,        // 9 - Receive Slave Address
> +    SDAT, 16,       // A - Slave Data
> +  }
> +  // Step 1:  Confirm the ICHx SMBus is ready to perform communication.
> +
> +  If(STRT())
> +  {
> +    Return(0xFFFF)
> +  }
> +
> +  // Step 2:  Initiate a Read Byte.
> +
> +  Store(0,I2CE)                           // Ensure SMbus Mode.
> +  Store(0xBF,HSTS)                        // Clear all but INUSE_STS.
> +  Store(Or(Arg0,1),TXSA)                  // Read Address in TXSA.
> +  Store(Arg1,HCOM)                        // Command in HCOM.
> +
> +  // Set the SMBus Host control register to 0x48.
> +  //   Bit 7:    =  0  = reserved
> +  //   Bit 6:    =  1  = start
> +  //   Bit 5:    =  0  = disregard, I2C related bit
> +  //   Bits 4:2: = 010 = Byte Data Protocol
> +  //   Bit 1:    =  0  = Normal Function
> +  //   Bit 0:    =  0  = Disable interrupt generation
> +
> +  Store(0x48,HCON)
> +
> +  // Step 3:  Exit the Method correctly.
> +
> +  If(COMP)
> +  {
> +    Or(HSTS,0xFF,HSTS)              // Clear INUSE_STS and others..
> +    Return(DAT0)                    // Return Success.
> +  }
> +
> +  Return(0xFFFF)                          // Return Failure.
> +}
> +
> +// SMBus Write Word - This function will write a single word
> +// of data to a specific Slave Device per SMBus Write Word
> +// Protocol.
> +//      Arg0 = Address
> +//      Arg1 = Command
> +//      Arg2 = Data (16 bits in size)
> +//      Return: Success = 1
> +//              Failure = 0
> +
> +Method(SWRW,3,Serialized)
> +{
> +  OperationRegion(SMPB,PCI_Config,0x20,4)
> +  Field(SMPB,DWordAcc,NoLock,Preserve)
> +  {
> +    ,     5,
> +    SBAR, 11
> +  }
> +
> +  // Define various SMBus IO Mapped Registers.
> +
> +  OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10)
> +  Field(SMBI,ByteAcc,NoLock,Preserve)
> +  {
> +    HSTS, 8,        // 0 - Host Status Register
> +    Offset(0x02),
> +	HCON, 8,        // 2 - Host Control
> +	HCOM, 8,        // 3 - Host Command
> +	TXSA, 8,        // 4 - Transmit Slave Address
> +	DAT0, 8,        // 5 - Host Data 0
> +	DAT1, 8,        // 6 - Host Data 1
> +	HBDR, 8,        // 7 - Host Block Data
> +	PECR, 8,        // 8 - Packer Error Check
> +	RXSA, 8,        // 9 - Receive Slave Address
> +	SDAT, 16,       // A - Slave Data
> +  }
> +  // Step 1:  Confirm the ICHx SMBus is ready to perform communication.
> +
> +  If(STRT())
> +  {
> +    Return(0)
> +  }
> +
> +  // Step 2:  Initiate a Write Word.
> +
> +  Store(0,I2CE)                           // Ensure SMbus Mode.
> +  Store(0xBF,HSTS)                        // Clear all but INUSE_STS.
> +  Store(Arg0,TXSA)                        // Write Address in TXSA.
> +  Store(Arg1,HCOM)                        // Command in HCOM.
> +  And(Arg2,0xFF,DAT1)                     // Low byte Data in DAT1.
> +  And(ShiftRight(Arg2,8),0xFF,DAT0)       // High byte Data in DAT0.
> +
> +  // Set the SMBus Host control register to 0x4C.
> +  //   Bit 7:    =  0  = reserved
> +  //   Bit 6:    =  1  = start
> +  //   Bit 5:    =  0  = disregard, I2C related bit
> +  //   Bits 4:2: = 011 = Word Data Protocol
> +  //   Bit 1:    =  0  = Normal Function
> +  //   Bit 0:    =  0  = Disable interrupt generation
> +
> +  Store(0x4C,HCON)
> +
> +  // Step 3:  Exit the Method correctly.
> +
> +  If(COMP())
> +  {
> +    Or(HSTS,0xFF,HSTS)              // Clear INUSE_STS and others.
> +    Return(1)                       // Return Success.
> +  }
> +
> +  Return(0)                               // Return Failure.
> +}
> +
> +// SMBus Read Word - This function will read a single byte of data
> +// from a specific slave device per SMBus Read Word Protocol.
> +//      Arg0 = Address
> +//      Arg1 = Command
> +//      Return: Success = Word-Size Value
> +//              Failure = Dword-Size Value
> +
> +Method(SRDW,2,Serialized)
> +{
> +  OperationRegion(SMPB,PCI_Config,0x20,4)
> +  Field(SMPB,DWordAcc,NoLock,Preserve)
> +  {
> +    ,     5,
> +    SBAR, 11
> +  }
> +
> +  // Define various SMBus IO Mapped Registers.
> +
> +  OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10)
> +  Field(SMBI,ByteAcc,NoLock,Preserve)
> +  {
> +    HSTS, 8,        // 0 - Host Status Register
> +	Offset(0x02),
> +	HCON, 8,        // 2 - Host Control
> +	HCOM, 8,        // 3 - Host Command
> +	TXSA, 8,        // 4 - Transmit Slave Address
> +	DAT0, 8,        // 5 - Host Data 0
> +	DAT1, 8,        // 6 - Host Data 1
> +	HBDR, 8,        // 7 - Host Block Data
> +	PECR, 8,        // 8 - Packer Error Check
> +	RXSA, 8,        // 9 - Receive Slave Address
> +	SDAT, 16,       // A - Slave Data
> +  }
> +  // Step 1:  Confirm the ICHx SMBus is ready to perform communication.
> +
> +  If(STRT())
> +  {
> +    Return(0xFFFF)
> +  }
> +
> +  // Step 2:  Initiate a Read Word.
> +
> +  Store(0,I2CE)                           // Ensure SMbus Mode.
> +  Store(0xBF,HSTS)                        // Clear all but INUSE_STS.
> +  Store(Or(Arg0,1),TXSA)                  // Read Address in TXSA.
> +  Store(Arg1,HCOM)                        // Command in HCOM.
> +
> +  // Set the SMBus Host control register to 0x4C.
> +  //   Bit 7:    =  0  = reserved
> +  //   Bit 6:    =  1  = start
> +  //   Bit 5:    =  0  = disregard, I2C related bit
> +  //   Bits 4:2: = 011 = Word Data Protocol
> +  //   Bit 1:    =  0  = Normal Function
> +  //   Bit 0:    =  0  = Disable interrupt generation
> +
> +  Store(0x4C,HCON)
> +
> +  // Step 3:  Exit the Method correctly.
> +
> +  If(COMP())
> +  {
> +    Or(HSTS,0xFF,HSTS)                      // Clear INUSE_STS and others.
> +    Return(Or(ShiftLeft(DAT0,8),DAT1))      // Return Success.
> +  }
> +
> +  Return(0xFFFFFFFF)                      // Return Failure.
> +}
> +
> +// SMBus Block Write - This function will write an entire block of data
> +// to a specific slave device per SMBus Block Write Protocol.
> +//      Arg0 = Address
> +//      Arg1 = Command
> +//      Arg2 = Buffer of Data to Write
> +//      Arg3 = 1 = I2C Block Write, 0 = SMBus Block Write
> +//      Return: Success = 1
> +//              Failure = 0
> +
> +Method(SBLW,4,Serialized)
> +{
> +  OperationRegion(SMPB,PCI_Config,0x20,4)
> +  Field(SMPB,DWordAcc,NoLock,Preserve)
> +  {
> +    ,     5,
> +    SBAR, 11
> +  }
> +
> +  // Define various SMBus IO Mapped Registers.
> +
> +  OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10)
> +  Field(SMBI,ByteAcc,NoLock,Preserve)
> +  {
> +    HSTS, 8,        // 0 - Host Status Register
> +	Offset(0x02),
> +	HCON, 8,        // 2 - Host Control
> +	HCOM, 8,        // 3 - Host Command
> +	TXSA, 8,        // 4 - Transmit Slave Address
> +	DAT0, 8,        // 5 - Host Data 0
> +	DAT1, 8,        // 6 - Host Data 1
> +	HBDR, 8,        // 7 - Host Block Data
> +	PECR, 8,        // 8 - Packer Error Check
> +	RXSA, 8,        // 9 - Receive Slave Address
> +	SDAT, 16,       // A - Slave Data
> +  }
> +  // Step 1:  Confirm the ICHx SMBus is ready to perform communication.
> +
> +  If(STRT())
> +  {
> +    Return(0)
> +  }
> +
> +  // Step 2:  Initiate a Block Write.
> +
> +  Store(Arg3,I2CE)                        // Select the proper protocol.
> +  Store(0xBF,HSTS)                        // Clear all but INUSE_STS.
> +  Store(Arg0,TXSA)                        // Write Address in TXSA.
> +  Store(Arg1,HCOM)                        // Command in HCOM.
> +  Store(Sizeof(Arg2),DAT0)                // Count in DAT0.
> +  Store(0,Local1)                         // Init Pointer to Buffer.
> +  Store(DerefOf(Index(Arg2,0)),HBDR)      // First Byte in HBD Register.
> +
> +  // Set the SMBus Host control register to 0x48.
> +  //   Bit 7:    =  0  = reserved
> +  //   Bit 6:    =  1  = start
> +  //   Bit 5:    =  0  = disregard, I2C related bit
> +  //   Bits 4:2: = 101 = Block Protocol
> +  //   Bit 1:    =  0  = Normal Function
> +  //   Bit 0:    =  0  = Disable interrupt generation
> +
> +  Store(0x54,HCON)
> +
> +  // Step 3:  Send the entire Block of Data.
> +
> +  While(LGreater(Sizeof(Arg2),Local1))
> +  {
> +    // Wait up to 200ms for Host Status to get set.
> +
> +    Store(4000,Local0)              // 4000 * 50us = 200ms.
> +
> +    While(LAnd(LNot(And(HSTS,0x80)),Local0))
> +    {
> +      Decrement(Local0)       // Decrement Count.
> +      Stall(50)               // Delay = 50us.
> +    }
> +
> +    If(LNot(Local0))                // Timeout?
> +    {
> +      KILL()                  // Yes.  Kill Communication.
> +      Return(0)               // Return failure.
> +    }
> +
> +    Store(0x80,HSTS)                // Clear Host Status.
> +    Increment(Local1)               // Point to Next Byte.
> +
> +    // Place next byte in HBDR if last byte has not been sent.
> +
> +    If(LGreater(Sizeof(Arg2),Local1))
> +    {
> +      Store(DerefOf(Index(Arg2,Local1)),HBDR)
> +    }
> +  }
> +
> +  // Step 4:  Exit the Method correctly.
> +
> +  If(COMP())
> +  {
> +    Or(HSTS,0xFF,HSTS)              // Clear all status bits.
> +    Return(1)                       // Return Success.
> +  }
> +
> +  Return(0)                               // Return Failure.
> +}
> +
> +// SMBus Block Read - This function will read a block of data from
> +// a specific slave device per SMBus Block Read Protocol.
> +//      Arg0 = Address
> +//      Arg1 = Command
> +//      Arg2 = 1 = I2C Block Write, 0 = SMBus Block Write
> +//      Return: Success = Data Buffer (First Byte = length)
> +//              Failure = 0
> +
> +Method(SBLR,3,Serialized)
> +{
> +  OperationRegion(SMPB,PCI_Config,0x20,4)
> +  Field(SMPB,DWordAcc,NoLock,Preserve)
> +  {
> +    ,     5,
> +    SBAR, 11
> +  }
> +
> +  // Define various SMBus IO Mapped Registers.
> +
> +  OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10)
> +  Field(SMBI,ByteAcc,NoLock,Preserve)
> +  {
> +    HSTS, 8,        // 0 - Host Status Register
> +	Offset(0x02),
> +	HCON, 8,        // 2 - Host Control
> +	HCOM, 8,        // 3 - Host Command
> +	TXSA, 8,        // 4 - Transmit Slave Address
> +	DAT0, 8,        // 5 - Host Data 0
> +	DAT1, 8,        // 6 - Host Data 1
> +	HBDR, 8,        // 7 - Host Block Data
> +	PECR, 8,        // 8 - Packer Error Check
> +	RXSA, 8,        // 9 - Receive Slave Address
> +	SDAT, 16,       // A - Slave Data
> +  }
> +  Name(TBUF, Buffer(256) {})
> +
> +  // Step 1:  Confirm the ICHx SMBus is ready to perform communication.
> +
> +  If(STRT())
> +  {
> +    Return(0)
> +  }
> +
> +  // Step 2:  Initiate a Block Read.
> +
> +  Store(Arg2,I2CE)                        // Select the proper protocol.
> +  Store(0xBF,HSTS)                        // Clear all but INUSE_STS.
> +  Store(Or(Arg0,1),TXSA)                  // Read Address in TXSA.
> +  Store(Arg1,HCOM)                        // Command in HCOM.
> +
> +  // Set the SMBus Host control register to 0x48.
> +  //   Bit 7:    =  0  = reserved
> +  //   Bit 6:    =  1  = start
> +  //   Bit 5:    =  0  = disregard, I2C related bit
> +  //   Bits 4:2: = 101 = Block Protocol
> +  //   Bit 1:    =  0  = Normal Function
> +  //   Bit 0:    =  0  = Disable interrupt generation
> +
> +  Store(0x54,HCON)
> +
> +  // Step 3:  Wait up to 200ms to get the Data Count.
> +
> +  Store(4000,Local0)                      // 4000 * 50us = 200ms.
> +
> +  While(LAnd(LNot(And(HSTS,0x80)),Local0))
> +  {
> +    Decrement(Local0)               // Decrement Count.
> +    Stall(50)                       // Delay = 50us.
> +  }
> +
> +  If(LNot(Local0))                        // Timeout?
> +  {
> +    KILL()                          // Yes.  Kill Communication.
> +    Return(0)                       // Return failure.
> +  }
> +
> +  Store(DAT0,Index(TBUF,0))               // Get the Data Count.
> +  Store(0x80,HSTS)                        // Clear Host Status.
> +  Store(1,Local1)                         // Local1 = Buffer Pointer.
> +
> +  // Step 4:  Get the Block Data and store it.
> +
> +  While(LLess(Local1,DerefOf(Index(TBUF,0))))
> +  {
> +    // Wait up to 200ms for Host Status to get set.
> +
> +    Store(4000,Local0)              // 4000 * 50us = 200ms.
> +
> +    While(LAnd(LNot(And(HSTS,0x80)),Local0))
> +    {
> +      Decrement(Local0)       // Decrement Count.
> +      Stall(50)               // Delay = 50us.
> +    }
> +
> +    If(LNot(Local0))                // Timeout?
> +    {
> +      KILL()                  // Yes.  Kill Communication.
> +      Return(0)               // Return failure.
> +    }
> +
> +    Store(HBDR,Index(TBUF,Local1))  // Place into Buffer.
> +    Store(0x80,HSTS)                // Clear Host Status.
> +    Increment(Local1)
> +  }
> +
> +  // Step 5:  Exit the Method correctly.
> +
> +  If(COMP())
> +  {
> +    Or(HSTS,0xFF,HSTS)              // Clear INUSE_STS and others.
> +    Return(TBUF)                    // Return Success.
> +  }
> +
> +  Return(0)                               // Return Failure.
> +}
> +
> +
> +// SMBus Start Check
> +//      Return: Success = 0
> +//              Failure = 1
> +
> +Method(STRT,0,Serialized)
> +{
> +  OperationRegion(SMPB,PCI_Config,0x20,4)
> +  Field(SMPB,DWordAcc,NoLock,Preserve)
> +  {
> +    ,     5,
> +    SBAR, 11
> +  }
> +
> +  // Define various SMBus IO Mapped Registers.
> +
> +  OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10)
> +  Field(SMBI,ByteAcc,NoLock,Preserve)
> +  {
> +    HSTS, 8,        // 0 - Host Status Register
> +	Offset(0x02),
> +	HCON, 8,        // 2 - Host Control
> +	HCOM, 8,        // 3 - Host Command
> +	TXSA, 8,        // 4 - Transmit Slave Address
> +	DAT0, 8,        // 5 - Host Data 0
> +	DAT1, 8,        // 6 - Host Data 1
> +	HBDR, 8,        // 7 - Host Block Data
> +	PECR, 8,        // 8 - Packer Error Check
> +	RXSA, 8,        // 9 - Receive Slave Address
> +	SDAT, 16,       // A - Slave Data
> +  }
> +  // Wait up to 200ms to confirm the SMBus Semaphore has been
> +  // released (In Use Status = 0).  Note that the Sleep time may take
> +  // longer as the This function will yield the Processor such that it
> +  // may perform different tasks during the delay.
> +
> +  Store(200,Local0)                       // 200 * 1ms = 200ms.
> +
> +  While(Local0)
> +  {
> +    If(And(HSTS,0x40))              // In Use Set?
> +    {
> +      Decrement(Local0)       // Yes.  Decrement Count.
> +      Sleep(1)                // Delay = 1ms.
> +      If(LEqual(Local0,0))    // Count = 0?
> +      {
> +        Return(1)       // Return failure.
> +      }
> +    }
> +    Else
> +    {
> +      Store(0,Local0)         // In Use Clear.  Continue.
> +    }
> +  }
> +
> +  // In Use Status = 0 during last read, which will make subsequent
> +  // reads return In Use Status = 1 until software clears it.  All
> +  // software using ICHx SMBus should check this bit before initiating
> +  // any SMBus communication.
> +
> +  // Wait up to 200ms to confirm the Host Interface is
> +  // not processing a command.
> +
> +  Store(4000,Local0)                      // 4000 * 50us = 200ms.
> +
> +  While(Local0)
> +  {
> +    If(And(HSTS,0x01))              // Host Busy Set?
> +    {
> +      Decrement(Local0)       // Decrement Count.
> +      Stall(50)               // Delay = 50us.
> +      If(LEqual(Local0,0))    // Count = 0?
> +      {
> +        KILL()          // Yes.  Kill Communication.
> +      }
> +    }
> +    Else
> +    {
> +      Return(0)
> +    }
> +  }
> +
> +  Return(1)                               // Timeout.  Return failure.
> +}
> +
> +// SMBus Completion Check
> +//      Return: Success = 1
> +//              Failure = 0
> +
> +Method(COMP,0,Serialized)
> +{
> +  OperationRegion(SMPB,PCI_Config,0x20,4)
> +  Field(SMPB,DWordAcc,NoLock,Preserve)
> +  {
> +    ,     5,
> +    SBAR, 11
> +  }
> +
> +  // Define various SMBus IO Mapped Registers.
> +
> +  OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10)
> +  Field(SMBI,ByteAcc,NoLock,Preserve)
> +  {
> +    HSTS, 8,        // 0 - Host Status Register
> +	Offset(0x02),
> +	HCON, 8,        // 2 - Host Control
> +	HCOM, 8,        // 3 - Host Command
> +	TXSA, 8,        // 4 - Transmit Slave Address
> +	DAT0, 8,        // 5 - Host Data 0
> +	DAT1, 8,        // 6 - Host Data 1
> +	HBDR, 8,        // 7 - Host Block Data
> +	PECR, 8,        // 8 - Packer Error Check
> +	RXSA, 8,        // 9 - Receive Slave Address
> +	SDAT, 16,       // A - Slave Data
> +  }
> +  // Wait for up to 200ms for the Completion Command
> +  // Status to get set.
> +
> +  Store(4000,Local0)                      // 4000 * 50us = 200ms.
> +
> +  While(Local0)
> +  {
> +    If(And(HSTS,0x02))              // Completion Status Set?
> +    {
> +      Return(1)               // Yes.  We are done.
> +    }
> +    Else
> +    {
> +      Decrement(Local0)       // Decrement Count.
> +      Stall(50)               // Delay 50us.
> +      If(LEqual(Local0,0))    // Count = 0?
> +      {
> +        KILL()          // Yes.  Kill Communication.
> +      }
> +    }
> +  }
> +
> +  Return(0)                               // Timeout.  Return Failure.
> +}
> +
> +// SMBus Kill Command
> +
> +Method(KILL,0,Serialized)
> +{
> +  OperationRegion(SMPB,PCI_Config,0x20,4)
> +  Field(SMPB,DWordAcc,NoLock,Preserve)
> +  {
> +    ,     5,
> +    SBAR, 11
> +  }
> +
> +  // Define various SMBus IO Mapped Registers.
> +
> +  OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10)
> +  Field(SMBI,ByteAcc,NoLock,Preserve)
> +  {
> +    HSTS, 8,        // 0 - Host Status Register
> +	Offset(0x02),
> +	HCON, 8,        // 2 - Host Control
> +	HCOM, 8,        // 3 - Host Command
> +	TXSA, 8,        // 4 - Transmit Slave Address
> +	DAT0, 8,        // 5 - Host Data 0
> +	DAT1, 8,        // 6 - Host Data 1
> +	HBDR, 8,        // 7 - Host Block Data
> +	PECR, 8,        // 8 - Packer Error Check
> +	RXSA, 8,        // 9 - Receive Slave Address
> +	SDAT, 16,       // A - Slave Data
> +  }
> +  Or(HCON,0x02,HCON)                      // Yes.  Send Kill command.
> +  Or(HSTS,0xFF,HSTS)                      // Clear all status.
> +}
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchXhci.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchXhci.asl
> new file mode 100644
> index 0000000000..914209f668
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchXhci.asl
> @@ -0,0 +1,379 @@
> +/*********************************************************
> *****************;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Intel Corporation - ACPI Reference Code for the Haswell             *;
> +;*    Family of Customer Reference Boards.                                *;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Copyright (c)  2010  - 2015, Intel Corporation. All rights reserved   *;
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*********************************************************
> *****************/
> +
> +//scope is \_SB.PCI0.XHC
> +Device(XHC1)
> +{
> +  Name(_ADR, 0x00140000)                     //Device 20, Function 0
> +
> +  //When it is in Host mode, USH core is connected to USB3 microAB(USB3
> P1 and USB2 P0)
> +  Name (_DDN, "Baytrail XHCI controller (CCG core/Host only)" )
> +
> +  Method(XDEP, 0)
> +  {
> +    If(LEqual(OSYS,2013))
> +    {
> +      Name(_DEP, Package(0x1)
> +      {
> +        PEPD
> +      })
> +    }
> +  }
> +
> +  Name (_STR, Unicode ("Baytrail XHCI controller (CCG core/Host only)"))
> +  Name(_PRW, Package() {0xD,4})
> +
> +  Method(_PSW,1)
> +  {
> +    If (LAnd (PMES, PMEE)) {
> +       Store (0, PMEE)
> +       Store (1, PMES)
> +    }
> +  }
> +
> +  OperationRegion (PMEB, PCI_Config, 0x74, 0x04)  // Power Management
> Control/Status
> +  Field (PMEB, WordAcc, NoLock, Preserve)
> +  {
> +    ,   8,
> +    PMEE,   1,   //bit8 PME_En
> +    ,   6,
> +    PMES,   1    //bit15 PME_Status
> +  }
> +
> +  Method(_STA, 0)
> +  {
> +    If(LNotEqual(XHCI, 0))      //NVS variable controls present of XHCI
> controller
> +    {
> +      Return (0xF)
> +    } Else
> +    {
> +      Return (0x0)
> +    }
> +  }
> +
> +  OperationRegion(XPRT,PCI_Config,0xD0,0x10)
> +  Field(XPRT,DWordAcc,NoLock,Preserve)       //usbx_top.doc.xml
> +  {
> +    PR2,  32,                              //bit[8:0] USB2HCSEL
> +    PR2M, 32,                              //bit[8:0] USB2HCSELM
> +    PR3,  32,                              //bit[3:0] USB3SSEN
> +    PR3M, 32                               //bit[3:0] USB3SSENM
> +  }
> +
> +  Device(RHUB)
> +  {
> +    Name(_ADR, Zero)         //address 0 is reserved for root hub
> +
> +    //
> +    // Super Speed Ports - must match _UPC declarations of the
> coresponding Full Speed Ports.
> +    //   Paired with Port 1
> +    Device(SSP1)
> +    {
> +      Name(_ADR, 0x07)
> +
> +      Method(_UPC,0,Serialized)
> +      {
> +        Name(UPCP, Package()
> +        {
> +          0xFF,                                      // Port is connectable if non-zero
> +          0x06,                                      // USB3 uAB connector
> +          0x00,
> +          0x00
> +        })
> +        Return(UPCP)
> +      }
> +
> +      Method(_PLD,0,Serialized)
> +      {
> +        Name(PLDP, Package()       //pls check ACPI 5.0 section 6.1.8
> +        {
> +          Buffer(0x14)
> +          {
> +            //31:0   - Bit[6:0]=2 revision is 0x2, Bit[7]=1 Ignore Color Bit[31:8]=0
> RGB color is ignored
> +            0x82, 0x00, 0x00, 0x00,
> +            //63:32 - Bit[47:32]=0 width: 0x0000  Bit[63:48]=0 Height:0x0000
> +            0x00, 0x00, 0x00, 0x00,
> +            //95:64 - bit[66:64]=b'011 visiable/docking/no lid bit[69:67]=b'001
> bottom panel bit[71:70]=b'01 Center  bit[73:72]=b'01 Center
> +            //           bit[77:74]=6 Horizontal Trapezoid bit[78]=0 bit[86:79]=0
> bit[94:87]='0 no group info' bit[95]=0 not a bay
> +            0x4B, 0x19, 0x00, 0x00,
> +            //127:96 -bit[96]=1 Ejectable bit[97]=1 OSPM Ejection required
> Bit[105:98]=0 no Cabinet Number
> +            //            bit[113:106]=0 no Card cage Number bit[114]=0 no reference
> shape Bit[118:115]=0 no rotation Bit[123:119]=0 no order
> +            0x03, 0x00, 0x00, 0x00,
> +            //159:128  Vert. and Horiz. Offsets not supplied
> +            0xFF, 0xFF, 0xFF, 0xFF
> +          }
> +        })
> +        Return (PLDP)
> +      }
> +    }
> +    //
> +    // High Speed Ports
> +    // pair port with port 7 (SS)
> +    //    The UPC declarations for LS/FS/HS and SS ports that are paired to
> form a USB3.0 compatible connector.
> +    //    A "pair" is defined by two ports that declare _PLDs with identical
> Panel, Vertical Position, Horizontal Postion, Shape, Group Orientation
> +    //    and Group Token
> +    Device(HS01)
> +    {
> +      Name(_ADR, 0x01)
> +
> +      Method(_UPC,0,Serialized)
> +      {
> +        Name(UPCP, Package() { 0xFF,0x06,0x00,0x00 })
> +        Return(UPCP)
> +      }
> +
> +      Method(_PLD,0,Serialized)
> +      {
> +        Name(PLDP, Package()       //pls check ACPI 5.0 section 6.1.8
> +        {
> +          Buffer(0x14)
> +          {
> +            //31:0   - Bit[6:0]=2 revision is 0x2, Bit[7]=1 Ignore Color Bit[31:8]=0
> RGB color is ignored
> +            0x82, 0x00, 0x00, 0x00,
> +            //63:32 - Bit[47:32]=0 width: 0x0000  Bit[63:48]=0 Height:0x0000
> +            0x00, 0x00, 0x00, 0x00,
> +            //95:64 - bit[66:64]=b'011 visiable/docking/no lid bit[69:67]=b'001
> bottom panel bit[71:70]=b'01 Center  bit[73:72]=b'01 Center
> +            //           bit[77:74]=6 Horizontal Trapezoid bit[78]=0 bit[86:79]=0
> bit[94:87]='0 no group info' bit[95]=0 not a bay
> +            0x4B, 0x19, 0x00, 0x00,
> +            //127:96 -bit[96]=1 Ejectable bit[97]=1 OSPM Ejection required
> Bit[105:98]=0 no Cabinet Number
> +            //            bit[113:106]=0 no Card cage Number bit[114]=0 no reference
> shape Bit[118:115]=0 no rotation Bit[123:119]=0 no order
> +            0x03, 0x00, 0x00, 0x00,
> +            //159:128  Vert. and Horiz. Offsets not supplied
> +            0xFF, 0xFF, 0xFF, 0xFF
> +          }
> +        })
> +        Return (PLDP)
> +      }
> +    }//end of HS01
> +
> +    // USB2 Type-A/USB2 only
> +    // EHCI debug capable
> +    Device(HS02)
> +    {
> +      Name(_ADR, 0x02)                                   // 0 is for root hub so physical port
> index starts from 1 (it is port1 in schematic)
> +
> +      Method(_UPC,0,Serialized)
> +      {
> +        Name(UPCP, Package()
> +        {
> +          0xFF,                     // connectable
> +          0xFF,                     //
> +          0x00,
> +          0x00
> +        })
> +
> +        Return(UPCP)
> +      }
> +
> +      Method(_PLD,0,Serialized)
> +      {
> +        Name(PLDP, Package()
> +        {
> +          Buffer(0x14)
> +          {
> +            //31:0   - Bit[6:0]=2 revision is 0x2, Bit[7]=1 Ignore Color Bit[31:8]=0
> RGB color is ignored
> +            0x82, 0x00, 0x00, 0x00,
> +            //63:32 - Bit[47:32]=0 width: 0x0000  Bit[63:48]=0 Height:0x0000
> +            0x00, 0x00, 0x00, 0x00,
> +            //95:64 - bit[66:64]=b'011 visiable/docking/no lid bit[69:67]=b'001
> bottom panel bit[71:70]=b'01 Center  bit[73:72]=b'00 Left
> +            //           bit[77:74]=2 Square bit[78]=0 bit[86:79]=0 bit[94:87]='0 no
> group info' bit[95]=0 not a bay
> +            0x4B, 0x08, 0x00, 0x00,
> +            //127:96 -bit[96]=1 Ejectable bit[97]=1 OSPM Ejection required
> Bit[105:98]=0 no Cabinet Number
> +            //            bit[113:106]=0 no Card cage Number bit[114]=0 no reference
> shape Bit[118:115]=0 no rotation Bit[123:119]=0 no order
> +            0x03, 0x00, 0x00, 0x00,
> +            //159:128  Vert. and Horiz. Offsets not supplied
> +            0xFF, 0xFF, 0xFF, 0xFF
> +          }
> +        })
> +
> +        Return (PLDP)
> +      }
> +    }//end of HS02
> +    // high speed port 3
> +    Device(HS03)
> +    {
> +      Name(_ADR, 0x03)
> +
> +      Method(_UPC,0,Serialized)
> +      {
> +        Name(UPCP, Package()
> +        {
> +          0xFF,                     //  connectable
> +          0xFF,
> +          0x00,
> +          0x00
> +        })
> +
> +        Return(UPCP)
> +      }
> +
> +      Method(_RMV, 0)                                    // for XHCICV debug purpose
> +      {
> +        Return(0x0)
> +      }
> +
> +      Method(_PLD,0,Serialized)
> +      {
> +        Name(PLDP, Package()
> +        {
> +          Buffer(0x14)
> +          {
> +            //31:0   - Bit[6:0]=2 revision is 0x2, Bit[7]=1 Ignore Color Bit[31:8]=0
> RGB color is ignored
> +            0x82, 0x00, 0x00, 0x00,
> +            //63:32 - Bit[47:32]=0 width: 0x0000  Bit[63:48]=0 Height:0x0000
> +            0x00, 0x00, 0x00, 0x00,
> +            //95:64 - bit[66:64]=b'000 not Visible/no docking/no lid bit[69:67]=6
> (b'110) unknown(Vertical Position and  Horizontal Position will be ignored)
> +            //           bit[71:70]=b'00 Vertical Position ignore bit[73:72]=b'00
> Horizontal Position ignore
> +            //           bit[77:74]=2 Square bit[78]=0 bit[86:79]=0 bit[94:87]='0 no
> group info' bit[95]=0 not a bay
> +            0x30, 0x08, 0x00, 0x00,
> +            //127:96 -bit[96]=0 not Ejectable bit[97]=0 OSPM Ejection not
> required Bit[105:98]=0 no Cabinet Number
> +            //            bit[113:106]=0 no Card cage Number bit[114]=0 no reference
> shape Bit[118:115]=0 no rotation Bit[123:119]=0 no order
> +            0x00, 0x00, 0x00, 0x00,
> +            //159:128  Vert. and Horiz. Offsets not supplied
> +            0xFF, 0xFF, 0xFF, 0xFF
> +          }
> +        })
> +        Return (PLDP)
> +      }
> +    }
> +
> +    Device(HS04)
> +    {
> +      Name(_ADR, 0x04)
> +
> +      Method(_UPC,0,Serialized)
> +      {
> +        Name(UPCP, Package()
> +        {
> +          0xFF,                     //connectable
> +          0xFF,                     //Proprietary connector (FPC connector)
> +          0x00,
> +          0x00
> +        })
> +
> +        Return(UPCP)
> +      }
> +      Method(_PLD,0,Serialized)
> +      {
> +        Name(PLDP, Package()
> +        {
> +          Buffer(0x14)
> +          {
> +            //31:0   - Bit[6:0]=2 revision is 0x2, Bit[7]=1 Ignore Color Bit[31:8]=0
> RGB color is ignored
> +            0x82, 0x00, 0x00, 0x00,
> +            //63:32 - Bit[47:32]=0 width: 0x0000  Bit[63:48]=0 Height:0x0000
> +            0x00, 0x00, 0x00, 0x00,
> +            //95:64 - bit[66:64]=b'000 not Visible/no docking/no lid bit[69:67]=6
> (b'110) unknown(Vertical Position and  Horizontal Position will be ignored)
> +            //           bit[71:70]=b'00 Vertical Position ignore bit[73:72]=b'00
> Horizontal Position ignore
> +            //           bit[77:74]=2 Square bit[78]=0 bit[86:79]=0 bit[94:87]='0 no
> group info' bit[95]=0 not a bay
> +            0x30, 0x08, 0x00, 0x00,
> +            //127:96 -bit[96]=0 not Ejectable bit[97]=0 OSPM Ejection not
> required Bit[105:98]=0 no Cabinet Number
> +            //            bit[113:106]=0 no Card cage Number bit[114]=0 no reference
> shape Bit[118:115]=0 no rotation Bit[123:119]=0 no order
> +            0x00, 0x00, 0x00, 0x00,
> +            //159:128  Vert. and Horiz. Offsets not supplied
> +            0xFF, 0xFF, 0xFF, 0xFF
> +          }
> +        })
> +
> +        Return (PLDP)
> +      }
> +    }
> +
> +
> +    Device(HSC1)                                           // USB2 HSIC 01
> +    {
> +      Name(_ADR, 0x05)
> +
> +      Method(_UPC,0,Serialized)
> +      {
> +        Name(UPCP, Package()
> +        {
> +          0xFF,                     //connectable
> +          0xFF,                     //Proprietary connector (FPC connector)
> +          0x00,
> +          0x00
> +        })
> +
> +        Return(UPCP)
> +      }
> +      Method(_PLD,0,Serialized)
> +      {
> +        Name(PLDP, Package()
> +        {
> +          Buffer(0x14)
> +          {
> +            //31:0   - Bit[6:0]=2 revision is 0x2, Bit[7]=1 Ignore Color Bit[31:8]=0
> RGB color is ignored
> +            0x82, 0x00, 0x00, 0x00,
> +            //63:32 - Bit[47:32]=0 width: 0x0000  Bit[63:48]=0 Height:0x0000
> +            0x00, 0x00, 0x00, 0x00,
> +            //95:64 - bit[66:64]=b'000 not Visible/no docking/no lid bit[69:67]=6
> (b'110) unknown(Vertical Position and  Horizontal Position will be ignored)
> +            //           bit[71:70]=b'00 Vertical Position ignore bit[73:72]=b'00
> Horizontal Position ignore
> +            //           bit[77:74]=2 Square bit[78]=0 bit[86:79]=0 bit[94:87]='0 no
> group info' bit[95]=0 not a bay
> +            0x30, 0x08, 0x00, 0x00,
> +            //127:96 -bit[96]=0 not Ejectable bit[97]=0 OSPM Ejection not
> required Bit[105:98]=0 no Cabinet Number
> +            //            bit[113:106]=0 no Card cage Number bit[114]=0 no reference
> shape Bit[118:115]=0 no rotation Bit[123:119]=0 no order
> +            0x00, 0x00, 0x00, 0x00,
> +            //159:128  Vert. and Horiz. Offsets not supplied
> +            0xFF, 0xFF, 0xFF, 0xFF
> +          }
> +        })
> +        Return (PLDP)
> +      }
> +    }
> +
> +    Device(HSC2)                                           // USB2 HSIC 02
> +    {
> +      Name(_ADR, 0x06)
> +
> +      Method(_UPC,0,Serialized)
> +      {
> +        Name(UPCP, Package()
> +        {
> +          0xFF,                     //connectable
> +          0xFF,                     //Proprietary connector (FPC connector)
> +          0x00,
> +          0x00
> +        })
> +
> +        Return(UPCP)
> +      }
> +      Method(_PLD,0,Serialized)
> +      {
> +        Name(PLDP, Package()
> +        {
> +          Buffer(0x14)
> +          {
> +            //31:0   - Bit[6:0]=2 revision is 0x2, Bit[7]=1 Ignore Color Bit[31:8]=0
> RGB color is ignored
> +            0x82, 0x00, 0x00, 0x00,
> +            //63:32 - Bit[47:32]=0 width: 0x0000  Bit[63:48]=0 Height:0x0000
> +            0x00, 0x00, 0x00, 0x00,
> +            //95:64 - bit[66:64]=b'000 not Visible/no docking/no lid bit[69:67]=6
> (b'110) unknown(Vertical Position and  Horizontal Position will be ignored)
> +            //           bit[71:70]=b'00 Vertical Position ignore bit[73:72]=b'00
> Horizontal Position ignore
> +            //           bit[77:74]=2 Square bit[78]=0 bit[86:79]=0 bit[94:87]='0 no
> group info' bit[95]=0 not a bay
> +            0x30, 0x08, 0x00, 0x00,
> +            //127:96 -bit[96]=0 not Ejectable bit[97]=0 OSPM Ejection not
> required Bit[105:98]=0 no Cabinet Number
> +            //            bit[113:106]=0 no Card cage Number bit[114]=0 no reference
> shape Bit[118:115]=0 no rotation Bit[123:119]=0 no order
> +            0x00, 0x00, 0x00, 0x00,
> +            //159:128  Vert. and Horiz. Offsets not supplied
> +            0xFF, 0xFF, 0xFF, 0xFF
> +          }
> +        })
> +        Return (PLDP)
> +      }
> +    }
> +  }  //end of root hub
> +
> +} // end of XHC1
> +
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PciTree.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PciTree.asl
> new file mode 100644
> index 0000000000..a64dbafc86
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PciTree.asl
> @@ -0,0 +1,377 @@
> +/*********************************************************
> *****************;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Intel Corporation - ACPI Reference Code for the Sandy Bridge        *;
> +;*    Family of Customer Reference Boards.                                *;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Copyright (c) 2012  - 2015, Intel Corporation. All rights reserved    *;
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*********************************************************
> *****************/
> +
> +Scope(\_SB)
> +{
> +//RTC
> +  Device(RTC)    // RTC
> +  {
> +    Name(_HID,EISAID("PNP0B00"))
> +
> +    Name(_CRS,ResourceTemplate()
> +    {
> +      IO(Decode16,0x70,0x70,0x01,0x08)
> +    })
> +
> +    Method(_STA,0,Serialized) {
> +
> +      //
> +      // Report RTC Battery is Prensent or Not Present.
> +      //
> +      If (LEqual(BATT, 1)) {
> +        Return (0xF)
> +      }
> +      Return (0x0)
> +    }
> +  }
> +//RTC
> +
> +  Device(HPET)   // High Performance Event Timer
> +  {
> +    Name (_HID, EisaId ("PNP0103"))
> +    Name (_UID, 0x00)
> +    Method (_STA, 0, NotSerialized)
> +    {
> +      Return (0x0F)
> +    }
> +
> +    Method (_CRS, 0, Serialized)
> +    {
> +      Name (RBUF, ResourceTemplate ()
> +      {
> +        Memory32Fixed (ReadWrite,
> +                       0xFED00000,         // Address Base
> +                       0x00000400,         // Address Length
> +                      )
> +        Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, )
> +        {
> +          0x00000008,   //0xB HPET-2
> +        }
> +      })
> +      Return (RBUF)
> +    }
> +  }
> +//HPET
> +
> +  Name(PR00, Package()
> +  {
> +// SD Host #0 - eMMC
> +    Package() {0x0010FFFF, 0, LNKA, 0 },
> +// SD Host #1 - SDIO
> +    Package() {0x0011FFFF, 0, LNKB, 0 },
> +// SD Host #2 - SD Card
> +    Package() {0x0012FFFF, 0, LNKC, 0 },
> +// SATA Controller
> +    Package() {0x0013FFFF, 0, LNKD, 0 },
> +// xHCI Host
> +    Package() {0x0014FFFF, 0, LNKE, 0 },
> +// Low Power Audio Engine
> +    Package() {0x0015FFFF, 0, LNKF, 0 },
> +// USB OTG
> +    Package() {0x0016FFFF, 0, LNKG, 0 },
> +// MIPI-HSI/eMMC4.5
> +    Package() {0x0017FFFF, 0, LNKH, 0 },
> +// LPSS2 DMA
> +// LPSS2 I2C #4
> +    Package() {0x0018FFFF, 0, LNKB, 0 },
> +// LPSS2 I2C #1
> +// LPSS2 I2C #5
> +    Package() {0x0018FFFF, 2, LNKD, 0 },
> +// LPSS2 I2C #2
> +// LPSS2 I2C #6
> +    Package() {0x0018FFFF, 3, LNKC, 0 },
> +// LPSS2 I2C #3
> +// LPSS2 I2C #7
> +    Package() {0x0018FFFF, 1, LNKA, 0 },
> +// SeC
> +    Package() {0x001AFFFF, 0, LNKF, 0 },
> +//
> +// High Definition Audio Controller
> +    Package() {0x001BFFFF, 0, LNKG, 0 },
> +//
> +// EHCI Controller
> +    Package() {0x001DFFFF, 0, LNKH, 0 },
> +// LPSS DMA
> +    Package() {0x001EFFFF, 0, LNKD, 0 },
> +// LPSS I2C #0
> +    Package() {0x001EFFFF, 3, LNKA, 0 },
> +// LPSS I2C #1
> +    Package() {0x001EFFFF, 1, LNKB, 0 },
> +// LPSS PCM
> +    Package() {0x001EFFFF, 2, LNKC, 0 },
> +// LPSS I2S
> +// LPSS HS-UART #0
> +// LPSS HS-UART #1
> +// LPSS SPI
> +// LPC Bridge
> +//
> +// SMBus Controller
> +    Package() {0x001FFFFF, 1, LNKC, 0 },
> +//
> +// PCIE Root Port #1
> +    Package() {0x001CFFFF, 0, LNKA, 0 },
> +// PCIE Root Port #2
> +    Package() {0x001CFFFF, 1, LNKB, 0 },
> +// PCIE Root Port #3
> +    Package() {0x001CFFFF, 2, LNKC, 0 },
> +// PCIE Root Port #4
> +    Package() {0x001CFFFF, 3, LNKD, 0 },
> +
> +// Host Bridge
> +// Mobile IGFX
> +    Package() {0x0002FFFF, 0, LNKA, 0 },
> +  })
> +
> +  Name(AR00, Package()
> +  {
> +// SD Host #0 - eMMC
> +    Package() {0x0010FFFF, 0, 0, 16 },
> +// SD Host #1 - SDIO
> +    Package() {0x0011FFFF, 0, 0, 17 },
> +// SD Host #2 - SD Card
> +    Package() {0x0012FFFF, 0, 0, 18 },
> +// SATA Controller
> +    Package() {0x0013FFFF, 0, 0, 19 },
> +// xHCI Host
> +    Package() {0x0014FFFF, 0, 0, 20 },
> +// Low Power Audio Engine
> +    Package() {0x0015FFFF, 0, 0, 21 },
> +// USB OTG
> +    Package() {0x0016FFFF, 0, 0, 22 },
> +//
> +// MIPI-HSI
> +    Package() {0x0017FFFF, 0, 0, 23 },
> +//
> +// LPSS2 DMA
> +// LPSS2 I2C #4
> +    Package() {0x0018FFFF, 0, 0, 17 },
> +// LPSS2 I2C #1
> +// LPSS2 I2C #5
> +    Package() {0x0018FFFF, 2, 0, 19 },
> +// LPSS2 I2C #2
> +// LPSS2 I2C #6
> +    Package() {0x0018FFFF, 3, 0, 18 },
> +// LPSS2 I2C #3
> +// LPSS2 I2C #7
> +    Package() {0x0018FFFF, 1, 0, 16 },
> +
> +// SeC
> +    Package() {0x001AFFFF, 0, 0, 21 },
> +//
> +// High Definition Audio Controller
> +    Package() {0x001BFFFF, 0, 0, 22 },
> +//
> +// EHCI Controller
> +    Package() {0x001DFFFF, 0, 0, 23 },
> +// LPSS DMA
> +    Package() {0x001EFFFF, 0, 0, 19 },
> +// LPSS I2C #0
> +    Package() {0x001EFFFF, 3, 0, 16 },
> +// LPSS I2C #1
> +    Package() {0x001EFFFF, 1, 0, 17 },
> +// LPSS PCM
> +    Package() {0x001EFFFF, 2, 0, 18 },
> +// LPSS I2S
> +// LPSS HS-UART #0
> +// LPSS HS-UART #1
> +// LPSS SPI
> +// LPC Bridge
> +//
> +// SMBus Controller
> +    Package() {0x001FFFFF, 1, 0, 18 },
> +//
> +// PCIE Root Port #1
> +    Package() {0x001CFFFF, 0, 0, 16 },
> +// PCIE Root Port #2
> +    Package() {0x001CFFFF, 1, 0, 17 },
> +// PCIE Root Port #3
> +    Package() {0x001CFFFF, 2, 0, 18 },
> +// PCIE Root Port #4
> +    Package() {0x001CFFFF, 3, 0, 19 },
> +// Host Bridge
> +// Mobile IGFX
> +    Package() {0x0002FFFF, 0, 0, 16 },
> +  })
> +
> +  Name(PR04, Package()
> +  {
> +// PCIE Port #1 Slot
> +    Package() {0x0000FFFF, 0, LNKA, 0 },
> +    Package() {0x0000FFFF, 1, LNKB, 0 },
> +    Package() {0x0000FFFF, 2, LNKC, 0 },
> +    Package() {0x0000FFFF, 3, LNKD, 0 },
> +  })
> +
> +  Name(AR04, Package()
> +  {
> +// PCIE Port #1 Slot
> +    Package() {0x0000FFFF, 0, 0, 16 },
> +    Package() {0x0000FFFF, 1, 0, 17 },
> +    Package() {0x0000FFFF, 2, 0, 18 },
> +    Package() {0x0000FFFF, 3, 0, 19 },
> +  })
> +
> +  Name(PR05, Package()
> +  {
> +// PCIE Port #2 Slot
> +    Package() {0x0000FFFF, 0, LNKB, 0 },
> +    Package() {0x0000FFFF, 1, LNKC, 0 },
> +    Package() {0x0000FFFF, 2, LNKD, 0 },
> +    Package() {0x0000FFFF, 3, LNKA, 0 },
> +  })
> +
> +  Name(AR05, Package()
> +  {
> +// PCIE Port #2 Slot
> +    Package() {0x0000FFFF, 0, 0, 17 },
> +    Package() {0x0000FFFF, 1, 0, 18 },
> +    Package() {0x0000FFFF, 2, 0, 19 },
> +    Package() {0x0000FFFF, 3, 0, 16 },
> +  })
> +
> +  Name(PR06, Package()
> +  {
> +// PCIE Port #3 Slot
> +    Package() {0x0000FFFF, 0, LNKC, 0 },
> +    Package() {0x0000FFFF, 1, LNKD, 0 },
> +    Package() {0x0000FFFF, 2, LNKA, 0 },
> +    Package() {0x0000FFFF, 3, LNKB, 0 },
> +  })
> +
> +  Name(AR06, Package()
> +  {
> +// PCIE Port #3 Slot
> +    Package() {0x0000FFFF, 0, 0, 18 },
> +    Package() {0x0000FFFF, 1, 0, 19 },
> +    Package() {0x0000FFFF, 2, 0, 16 },
> +    Package() {0x0000FFFF, 3, 0, 17 },
> +  })
> +
> +  Name(PR07, Package()
> +  {
> +// PCIE Port #4 Slot
> +    Package() {0x0000FFFF, 0, LNKD, 0 },
> +    Package() {0x0000FFFF, 1, LNKA, 0 },
> +    Package() {0x0000FFFF, 2, LNKB, 0 },
> +    Package() {0x0000FFFF, 3, LNKC, 0 },
> +  })
> +
> +  Name(AR07, Package()
> +  {
> +// PCIE Port #4 Slot
> +    Package() {0x0000FFFF, 0, 0, 19 },
> +    Package() {0x0000FFFF, 1, 0, 16 },
> +    Package() {0x0000FFFF, 2, 0, 17 },
> +    Package() {0x0000FFFF, 3, 0, 18 },
> +  })
> +
> +  Name(PR01, Package()
> +  {
> +// PCI slot 1
> +    Package() {0x0000FFFF, 0, LNKF, 0 },
> +    Package() {0x0000FFFF, 1, LNKG, 0 },
> +    Package() {0x0000FFFF, 2, LNKH, 0 },
> +    Package() {0x0000FFFF, 3, LNKE, 0 },
> +// PCI slot 2
> +    Package() {0x0001FFFF, 0, LNKG, 0 },
> +    Package() {0x0001FFFF, 1, LNKF, 0 },
> +    Package() {0x0001FFFF, 2, LNKE, 0 },
> +    Package() {0x0001FFFF, 3, LNKH, 0 },
> +// PCI slot 3
> +    Package() {0x0002FFFF, 0, LNKC, 0 },
> +    Package() {0x0002FFFF, 1, LNKD, 0 },
> +    Package() {0x0002FFFF, 2, LNKB, 0 },
> +    Package() {0x0002FFFF, 3, LNKA, 0 },
> +// PCI slot 4
> +    Package() {0x0003FFFF, 0, LNKD, 0 },
> +    Package() {0x0003FFFF, 1, LNKC, 0 },
> +    Package() {0x0003FFFF, 2, LNKF, 0 },
> +    Package() {0x0003FFFF, 3, LNKG, 0 },
> +  })
> +
> +  Name(AR01, Package()
> +  {
> +// PCI slot 1
> +    Package() {0x0000FFFF, 0, 0, 21 },
> +    Package() {0x0000FFFF, 1, 0, 22 },
> +    Package() {0x0000FFFF, 2, 0, 23 },
> +    Package() {0x0000FFFF, 3, 0, 20 },
> +// PCI slot 2
> +    Package() {0x0001FFFF, 0, 0, 22 },
> +    Package() {0x0001FFFF, 1, 0, 21 },
> +    Package() {0x0001FFFF, 2, 0, 20 },
> +    Package() {0x0001FFFF, 3, 0, 23 },
> +// PCI slot 3
> +    Package() {0x0002FFFF, 0, 0, 18 },
> +    Package() {0x0002FFFF, 1, 0, 19 },
> +    Package() {0x0002FFFF, 2, 0, 17 },
> +    Package() {0x0002FFFF, 3, 0, 16 },
> +// PCI slot 4
> +    Package() {0x0003FFFF, 0, 0, 19 },
> +    Package() {0x0003FFFF, 1, 0, 18 },
> +    Package() {0x0003FFFF, 2, 0, 21 },
> +    Package() {0x0003FFFF, 3, 0, 22 },
> +  })
> +//---------------------------------------------------------------------------
> +// List of IRQ resource buffers compatible with _PRS return format.
> +//---------------------------------------------------------------------------
> +// Naming legend:
> +// RSxy, PRSy - name of the IRQ resource buffer to be returned by _PRS,
> "xy" - last two characters of IRQ Link name.
> +// Note. PRSy name is generated if IRQ Link name starts from "LNK".
> +// HLxy , LLxy - reference names, can be used to access bit mask of available
> IRQs. HL and LL stand for active High(Low) Level triggered Irq model.
> +//---------------------------------------------------------------------------
> +  Name(PRSA, ResourceTemplate()         // Link name: LNKA
> +  {
> +    IRQ(Level, ActiveLow, Shared, LLKA) {3,4,5,6,10,11,12,14,15}
> +  })
> +  Alias(PRSA,PRSB)      // Link name: LNKB
> +  Alias(PRSA,PRSC)      // Link name: LNKC
> +  Alias(PRSA,PRSD)      // Link name: LNKD
> +  Alias(PRSA,PRSE)      // Link name: LNKE
> +  Alias(PRSA,PRSF)      // Link name: LNKF
> +  Alias(PRSA,PRSG)      // Link name: LNKG
> +  Alias(PRSA,PRSH)      // Link name: LNKH
> +//---------------------------------------------------------------------------
> +// Begin PCI tree object scope
> +//---------------------------------------------------------------------------
> +
> +  Device(PCI0)   // PCI Bridge "Host Bridge"
> +  {
> +    Name(_HID, EISAID("PNP0A08"))       // Indicates PCI Express/PCI-X
> Mode2 host hierarchy
> +    Name(_CID, EISAID("PNP0A03"))       // To support legacy OS that doesn't
> understand the new HID
> +    Name(_ADR, 0x00000000)
> +    Method(^BN00, 0) { return(0x0000) } // Returns default Bus number for
> Peer PCI busses. Name can be overriden with control method placed directly
> under Device scope
> +    Method(_BBN, 0) { return(BN00()) }  // Bus number, optional for the Root
> PCI Bus
> +    Name(_UID, 0x0000)  // Unique Bus ID, optional
> +    Name(_DEP, Package(0x1)
> +    {
> +      PEPD
> +    })
> +
> +                            Method(_PRT,0)
> +    {
> +      If(PICM) {Return(AR00)} // APIC mode
> +      Return (PR00) // PIC Mode
> +    } // end _PRT
> +
> +    include("HOST_BUS.ASL")
> +    Device(LPCB)   // LPC Bridge
> +    {
> +      Name(_ADR, 0x001F0000)
> +      include("LpcB.asl")
> +    } // end "LPC Bridge"
> +
> +  } // end PCI0 Bridge "Host Bridge"
> +} // end _SB scope
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Platform.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Platform.asl
> new file mode 100644
> index 0000000000..784eb09f90
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Platform.asl
> @@ -0,0 +1,703 @@
> +/*********************************************************
> *****************;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
> +;*    Family of Customer Reference Boards.                                *;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved    *;
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*********************************************************
> *****************/
> +
> +
> +// Define the following External variables to prevent a WARNING when
> +// using ASL.EXE and an ERROR when using IASL.EXE.
> +
> +External(PDC0)
> +External(PDC1)
> +External(PDC2)
> +External(PDC3)
> +External(CFGD)
> +External(\_PR.CPU0._PPC, IntObj)
> +External(\_SB.PCI0.LPCB.TPM.PTS, MethodObj)
> +External(\_SB.STR3, DeviceObj)
> +External(\_SB.I2C1.BATC, DeviceObj)
> +External(\_SB.DPTF, DeviceObj)
> +External(\_SB.TCHG, DeviceObj)
> +External(\_SB.IAOE.PTSL)
> +External(\_SB.IAOE.WKRS)
> +
> +//
> +// Create a Global MUTEX.
> +//
> +Mutex(MUTX,0)
> +
> +
> +
> +// Port 80h Update:
> +//              Update 8 bits of the 32-bit Port 80h.
> +//
> +//      Arguments:
> +//              Arg0:   0 = Write Port 80h, Bits 7:0 Only.
> +//                      1 = Write Port 80h, Bits 15:8 Only.
> +//                      2 = Write Port 80h, Bits 23:16 Only.
> +//                      3 = Write Port 80h, Bits 31:24 Only.
> +//              Arg1:   8-bit Value to write
> +//
> +//      Return Value:
> +//              None
> +
> +Method(P8XH,2,Serialized)
> +{
> +  If(LEqual(Arg0,0))            // Write Port 80h, Bits 7:0.
> +  {
> +    Store(Or(And(P80D,0xFFFFFF00),Arg1),P80D)
> +  }
> +
> +  If(LEqual(Arg0,1))            // Write Port 80h, Bits 15:8.
> +  {
> +    Store(Or(And(P80D,0xFFFF00FF),ShiftLeft(Arg1,8)),P80D)
> +  }
> +
> +  If(LEqual(Arg0,2))            // Write Port 80h, Bits 23:16.
> +  {
> +    Store(Or(And(P80D,0xFF00FFFF),ShiftLeft(Arg1,16)),P80D)
> +  }
> +
> +  If(LEqual(Arg0,3))            // Write Port 80h, Bits 31:24.
> +  {
> +    Store(Or(And(P80D,0x00FFFFFF),ShiftLeft(Arg1,24)),P80D)
> +  }
> +
> +}
> +
> +//
> +// Define SW SMI port as an ACPI Operating Region to use for generate SW
> SMI.
> +//
> +OperationRegion (SPRT, SystemIO, 0xB2, 2)
> +Field (SPRT, ByteAcc, Lock, Preserve)
> +{
> +  SSMP, 8
> +}
> +
> +// The _PIC Control Method is optional for ACPI design.  It allows the
> +// OS to inform the ASL code which interrupt controller is being used,
> +// the 8259 or APIC.  The reference code in this document will address
> +// PCI IRQ Routing and resource allocation for both cases.
> +//
> +// The values passed into _PIC are:
> +//       0 = 8259
> +//       1 = IOAPIC
> +
> +Method(\_PIC,1)
> +{
> +  Store(Arg0,GPIC)
> +  Store(Arg0,PICM)
> +}
> +
> +OperationRegion(SWC0, SystemIO, 0x610, 0x0F)
> +Field(SWC0, ByteAcc, NoLock, Preserve)
> +{
> +  G1S, 8,      //SWC GPE1_STS
> +  Offset(0x4),
> +  G1E, 8,
> +  Offset(0xA),
> +  G1S2, 8,     //SWC GPE1_STS_2
> +  G1S3, 8      //SWC GPE1_STS_3
> +}
> +
> +OperationRegion (SWC1, SystemIO, \PMBS, 0x2C)
> +Field(SWC1, DWordAcc, NoLock, Preserve)
> +{
> +  Offset(0x20),
> +  G0S, 32,      //GPE0_STS
> +  Offset(0x28),
> +  G0EN, 32      //GPE0_EN
> +}
> +
> +// Prepare to Sleep.  The hook is called when the OS is about to
> +// enter a sleep state.  The argument passed is the numeric value of
> +// the Sx state.
> +
> +Method(_PTS,1)
> +{
> +  Store(0,P80D)         // Zero out the entire Port 80h DWord.
> +  P8XH(0,Arg0)          // Output Sleep State to Port 80h, Byte 0.
> +
> +  //clear the 3 SWC status bits
> +  Store(Ones, G1S3)
> +  Store(Ones, G1S2)
> +  Store(1, G1S)
> +
> +  //set SWC GPE1_EN
> +  Store(1,G1E)
> +
> +  //clear GPE0_STS
> +  Store(Ones, G0S)
> +
> +
> +  If(LEqual(Arg0,3))   // If S3 Suspend
> +  {
> +    //
> +    // Disable Digital Thermal Sensor function when doing S3 suspend
> +    //
> +    If(CondRefOf(DTSE))
> +    {
> +      If(LGreaterEqual(DTSE, 0x01))
> +      {
> +        Store(30, DTSF) // DISABLE_UPDATE_DTS_EVERY_SMI
> +        Store(0xD0, SSMP) // DTS SW SMI
> +      }
> +    }
> +  }
> +}
> +
> +// Wake.  This hook is called when the OS is about to wake from a
> +// sleep state.  The argument passed is the numeric value of the
> +// sleep state the system is waking from.
> +Method(_WAK,1,Serialized)
> +{
> +  P8XH(1,0xAB) // Beginning of _WAK.
> +
> +  Notify(\_SB.PWRB,0x02)
> +
> +  If(NEXP)
> +  {
> +    // Reinitialize the Native PCI Express after resume
> +    If(And(OSCC,0x02))
> +    {
> +      \_SB.PCI0.NHPG()
> +    }
> +
> +    If(And(OSCC,0x04))   // PME control granted?
> +    {
> +      \_SB.PCI0.NPME()
> +    }
> +  }
> +
> +  If(LOr(LEqual(Arg0,3), LEqual(Arg0,4)))   // If S3 or S4 Resume
> +  {
> +
> +
> +    // If CMP is enabled, we may need to restore the C-State and/or
> +    // P-State configuration, as it may have been saved before the
> +    // configuration was finalized based on OS/driver support.
> +    //
> +    //   CFGD[24]  = Two or more cores enabled
> +    //
> +    If(And(CFGD,0x01000000))
> +    {
> +      //
> +      // If CMP and the OSYS is WinXP SP1, we will enable C1-SMI if
> +      // C-States are enabled.
> +      //
> +      //   CFGD[7:4] = C4, C3, C2, C1 Capable/Enabled
> +      //
> +      //
> +    }
> +
> +    // Windows XP SP2 does not properly restore the P-State
> +    // upon resume from S4 or S3 with degrade modes enabled.
> +    // Use the existing _PPC methods to cycle the available
> +    // P-States such that the processor ends up running at
> +    // the proper P-State.
> +    //
> +    // Note:  For S4, another possible W/A is to always boot
> +    // the system in LFM.
> +    //
> +    If(LEqual(OSYS,2002))
> +    {
> +      If(And(CFGD,0x01))
> +      {
> +        If(LGreater(\_PR.CPU0._PPC,0))
> +        {
> +          Subtract(\_PR.CPU0._PPC,1,\_PR.CPU0._PPC)
> +          PNOT()
> +          Add(\_PR.CPU0._PPC,1,\_PR.CPU0._PPC)
> +          PNOT()
> +        }
> +        Else
> +        {
> +          Add(\_PR.CPU0._PPC,1,\_PR.CPU0._PPC)
> +          PNOT()
> +          Subtract(\_PR.CPU0._PPC,1,\_PR.CPU0._PPC)
> +          PNOT()
> +        }
> +      }
> +    }
> +  }
> +  Return(Package() {0,0})
> +}
> +
> +// Power Notification:
> +//              Perform all needed OS notifications during a
> +//              Power Switch.
> +//
> +//      Arguments:
> +//              None
> +//
> +//      Return Value:
> +//              None
> +
> +Method(PNOT,0,Serialized)
> +{
> +  // If MP enabled and driver support is present, notify all
> +  // processors.
> +
> +  If(MPEN)
> +  {
> +    If(And(PDC0,0x0008))
> +    {
> +      Notify(\_PR.CPU0,0x80)    // Eval CPU0 _PPC.
> +
> +      If(And(PDC0,0x0010))
> +      {
> +        Sleep(100)
> +        Notify(\_PR.CPU0,0x81)  // Eval _CST.
> +      }
> +    }
> +
> +    If(And(PDC1,0x0008))
> +    {
> +      Notify(\_PR.CPU1,0x80)    // Eval CPU1 _PPC.
> +
> +      If(And(PDC1,0x0010))
> +      {
> +        Sleep(100)
> +        Notify(\_PR.CPU1,0x81)  // Eval _CST.
> +      }
> +    }
> +
> +    If(And(PDC2,0x0008))
> +    {
> +      Notify(\_PR.CPU2,0x80)    // Eval CPU2 _PPC.
> +
> +      If(And(PDC2,0x0010))
> +      {
> +        Sleep(100)
> +        Notify(\_PR.CPU2,0x81)  // Eval _CST.
> +      }
> +    }
> +
> +    If(And(PDC3,0x0008))
> +    {
> +      Notify(\_PR.CPU3,0x80)    // Eval CPU3 _PPC.
> +
> +      If(And(PDC3,0x0010))
> +      {
> +        Sleep(100)
> +        Notify(\_PR.CPU3,0x81)  // Eval _CST.
> +      }
> +    }
> +  }
> +  Else
> +  {
> +    Notify(\_PR.CPU0,0x80)      // Eval _PPC.
> +    Sleep(100)
> +    Notify(\_PR.CPU0,0x81)      // Eval _CST
> +  }
> +}
> +
> +//
> +// System Bus
> +//
> +Scope(\_SB)
> +{
> +  Name(CRTT, 110) // Processor critical temperature
> +  Name(ACTT, 77)  // Active temperature limit for processor participant
> +  Name(GCR0, 70)  // Critical temperature for Generic participant 0 in degree
> celsius
> +  Name(GCR1, 70)  // Critical temperature for Generic participant 1 in degree
> celsius
> +  Name(GCR2, 70)  // Critical temperature for Generic participant 2 in degree
> celsius
> +  Name(GCR3, 70)  // Critical temperature for Generic participant 3 in degree
> celsius
> +  Name(GCR4, 70)  // Critical temperature for Generic participant 4 in degree
> celsius
> +  Name(GCR5, 70)  // Critical temperature for Generic participant 5 in degree
> celsius
> +  Name(GCR6, 70)  // Critical temperature for Generic participant 6 in degree
> celsius
> +  Name(PST0, 60)  // Passive temperature limit for Generic Participant 0 in
> degree celsius
> +  Name(PST1, 60)  // Passive temperature limit for Generic Participant 1 in
> degree celsius
> +  Name(PST2, 60)  // Passive temperature limit for Generic Participant 2 in
> degree celsius
> +  Name(PST3, 60)  // Passive temperature limit for Generic Participant 3 in
> degree celsius
> +  Name(PST4, 60)  // Passive temperature limit for Generic Participant 4 in
> degree celsius
> +  Name(PST5, 60)  // Passive temperature limit for Generic Participant 5 in
> degree celsius
> +  Name(PST6, 60)  // Passive temperature limit for Generic Participant 6 in
> degree celsius
> +  Name(LPMV, 3)
> +  Name(PDBG, 0)   // DPTF Super debug option
> +  Name(PDPM, 1)   // DPTF DPPM enable
> +  Name(PDBP, 1)   // DPTF DBPT enable (dynamic battery protection
> technology)
> +  Name(DLPO, Package()
> +  {
> +    0x1, // Revision
> +    0x1, // LPO Enable
> +    0x1, // LPO StartPState
> +    25,  // LPO StepSize
> +    0x1, //
> +    0x1, //
> +  })
> +  Name(BRQD, 0x00) // This is used to determine if DPTF display participant
> requested Brightness level change
> +  // or it is from Graphics driver. Value of 1 is for DPTF else it is 0
> +
> +  Method(_INI,0)
> +  {
> +    // NVS has stale DTS data.  Get and update the values
> +    // with current temperatures.   Note that this will also
> +    // re-arm any AP Thermal Interrupts.
> +    // Read temperature settings from global NVS
> +    Store(DPCT, CRTT)
> +    Store(Subtract(DPPT, 8), ACTT)                      // Active Trip point = Passive
> trip point - 8
> +    Store(DGC0, GCR0)
> +    Store(DGC0, GCR1)
> +    Store(DGC1, GCR2)
> +    Store(DGC1, GCR3)
> +    Store(DGC1, GCR4)
> +    Store(DGC2, GCR5)
> +    Store(DGC2, GCR6)
> +    Store(DGP0, PST0)
> +    Store(DGP0, PST1)
> +    Store(DGP1, PST2)
> +    Store(DGP1, PST3)
> +    Store(DGP1, PST4)
> +    Store(DGP2, PST5)
> +    Store(DGP2, PST6)
> +    // Read Current low power mode setting from global NVS
> +    Store(DLPM, LPMV)
> +
> +
> +    // Update DPTF Super Debug option
> +    Store(DDBG, PDBG)
> +
> +
> +    // Update DPTF LPO Options
> +    Store(LPOE, Index(DLPO,1))
> +    Store(LPPS, Index(DLPO,2))
> +    Store(LPST, Index(DLPO,3))
> +    Store(LPPC, Index(DLPO,4))
> +    Store(LPPF, Index(DLPO,5))
> +    Store(DPME, PDPM)
> +  }
> +
> +  // Define a (Control Method) Power Button.
> +  Device(PWRB)
> +  {
> +    Name(_HID,EISAID("PNP0C0C"))
> +
> +    // GPI_SUS0 = GPE16 = Waketime SCI.  The PRW isn't working when
> +    // placed in any of the logical locations ( PS2K, PS2M),
> +    // so a Power Button Device was created specifically
> +    // for the WAKETIME_SCI PRW.
> +
> +    Name(_PRW, Package() {16,4})
> +  }
> +
> +  Device(SLPB)
> +  {
> +    Name(_HID, EISAID("PNP0C0E"))
> +  } // END SLPB
> +
> +  Scope(PCI0)
> +  {
> +    Method(_INI,0)
> +    {
> +      // Determine the OS and store the value, where:
> +      //
> +      //   OSYS = 2009 = Windows 7 and Windows Server 2008 R2.
> +      //   OSYS = 2012 = Windows 8 and Windows Server 2012.
> +      //
> +      // Assume Windows 7 at a minimum.
> +
> +      Store(2009,OSYS)
> +
> +      // Check for a specific OS which supports _OSI.
> +
> +      If(CondRefOf(\_OSI,Local0))
> +      {
> +        // Linux returns _OSI = TRUE for numerous Windows
> +        // strings so that it is fully compatible with
> +        // BIOSes available in the market today.  There are
> +        // currently 2 known exceptions to this model:
> +        //      1) Video Repost - Linux supports S3 without
> +        //              requireing a Driver, meaning a Video
> +        //              Repost will be required.
> +        //      2) On-Screen Branding - a full CMT Logo
> +        //              is limited to the WIN2K and WINXP
> +        //              Operating Systems only.
> +
> +        // Use OSYS for Windows Compatibility.
> +        If(\_OSI("Windows 2009"))   // Windows 7 or Windows Server 2008 R2
> +        {
> +          Store(2009,OSYS)
> +        }
> +        If(\_OSI("Windows 2012"))   // Windows 8 or Windows Server 2012
> +        {
> +          Store(2012,OSYS)
> +        }
> +        If(\_OSI("Windows 2013"))   //Windows Blue
> +        {
> +          Store(2013,OSYS)
> +        }
> +
> +        //
> +        // If CMP is enabled, enable SMM C-State
> +        // coordination.  SMM C-State coordination
> +        // will be disabled in _PDC if driver support
> +        // for independent C-States deeper than C1
> +        // is indicated.
> +      }
> +    }
> +
> +    Method(NHPG,0,Serialized)
> +    {
> +
> +    }
> +
> +    Method(NPME,0,Serialized)
> +    {
> +
> +    }
> +  } // end Scope(PCI0)
> +
> +  Device (GPED)   //virtual GPIO device for ASL based AC/Battery/Expection
> notification
> +  {
> +    Name (_ADR, 0)
> +    Name (_HID, "INT0002")
> +    Name (_CID, "INT0002")
> +    Name (_DDN, "Virtual GPIO controller" )
> +    Name (_UID, 1)
> +
> +    Method (_CRS, 0x0, Serialized)
> +    {
> +      Name (RBUF, ResourceTemplate ()
> +      {
> +        Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, ) {0x9} //
> Was 9
> +      })
> +      Return (RBUF)
> +    }
> +
> +    Method (_STA, 0x0, NotSerialized)
> +    {
> +      Return(0x0)
> +    }
> +
> +    Method (_AEI, 0x0, Serialized)
> +    {
> +      Name(RBUF, ResourceTemplate()
> +      {
> +        GpioInt(Edge, ActiveHigh, ExclusiveAndWake, PullDown,,"\\_SB.GPED",)
> {2} //pin 2
> +      })
> +      Return(RBUF)
> +    }
> +
> +    Method(_E02)   // _Exx method will be called when interrupt is raised
> +    {
> +      If (LEqual (PWBS, 1))
> +      {
> +        Store (1, PWBS)      //Clear PowerButton Status
> +      }
> +      If (LEqual (PMEB, 1))
> +      {
> +        Store (1, PMEB)      //Clear PME_B0_STS
> +      }
> +      If (LEqual (\_SB.PCI0.SATA.PMES, 1))
> +      {
> +        Store (1, \_SB.PCI0.SATA.PMES)
> +        Notify (\_SB.PCI0.SATA, 0x02)
> +      }
> +      //
> +      // eMMC 4.41
> +      //
> +      If (LAnd(LEqual (\_SB.PCI0.EM41.PMES, 1), LEqual(PCIM, 1)))
> +      {
> +        Store (1, \_SB.PCI0.EM41.PMES)
> +        Notify (\_SB.PCI0.EM41, 0x02)
> +      }
> +
> +      //
> +      // eMMC 4.5
> +      //
> +      If (LAnd(LEqual (\_SB.PCI0.EM45.PMES, 1), LEqual(PCIM, 1)))
> +      {
> +        Store (1, \_SB.PCI0.EM45.PMES)
> +        Notify (\_SB.PCI0.EM45, 0x02)
> +      }
> +
> +      If (LEqual(HDAD, 0))
> +      {
> +        If (LEqual (\_SB.PCI0.HDEF.PMES, 1))
> +        {
> +          Store (1, \_SB.PCI0.HDEF.PMES)
> +          Notify (\_SB.PCI0.HDEF, 0x02)
> +        }
> +      }
> +
> +      If (LEqual (\_SB.PCI0.EHC1.PMES, 1))
> +      {
> +        Store (1, \_SB.PCI0.EHC1.PMES)
> +        Notify (\_SB.PCI0.EHC1, 0x02)
> +      }
> +      If (LEqual (\_SB.PCI0.XHC1.PMES, 1))
> +      {
> +        Store (1, \_SB.PCI0.XHC1.PMES)
> +        Notify (\_SB.PCI0.XHC1, 0x02)
> +      }
> +      If (LEqual (\_SB.PCI0.SEC0.PMES, 1))
> +      {
> +        Or (\_SB.PCI0.SEC0.PMES, Zero, \_SB.PCI0.SEC0.PMES)
> +        Notify (\_SB.PCI0.SEC0, 0x02)
> +      }
> +    }
> +  } //  Device (GPED)
> +
> +  //--------------------
> +  //  GPIO
> +  //--------------------
> +  Device (GPO0)
> +  {
> +    Name (_ADR, 0)
> +    Name (_HID, "INT33FC")
> +    Name (_CID, "INT33B2")
> +    Name (_DDN, "ValleyView2 General Purpose Input/Output (GPIO)
> controller" )
> +    Name (_UID, 1)
> +    Method (_CRS, 0x0, Serialized)
> +    {
> +      Name (RBUF, ResourceTemplate ()
> +      {
> +        Memory32Fixed (ReadWrite, 0x0FED0C000, 0x00001000)
> +        Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , , ) {49}
> +
> +      })
> +      Return (RBUF)
> +    }
> +
> +    Method (_STA, 0x0, NotSerialized)
> +    {
> +      //
> +      // GPO driver will report present if any of below New IO bus exist
> +      //
> +      If (LOr(LEqual(L11D, 0), LEqual(L12D, 0))) // LPIO1 PWM #1 or #2 exist
> +      { Return(0xF) }
> +      If (LOr(LEqual(L13D, 0), LEqual(L14D, 0))) // LPIO1 HS-UART #1 or #2 exist
> +      { Return(0xF) }
> +      If (LOr(LEqual(L15D, 0), LEqual(SD1D, 0))) // LPIO1 SPI or SCC SDIO #1
> exist
> +      { Return(0xF) }
> +      If (LOr(LEqual(SD2D, 0), LEqual(SD3D, 0))) // SCC SDIO #2 or #3 exist
> +      { Return(0xF) }
> +      If (LOr(LEqual(L21D, 0), LEqual(L22D, 0))) // LPIO2 I2C #1 or #2 exist
> +      { Return(0xF) }
> +      If (LOr(LEqual(L23D, 0), LEqual(L24D, 0))) // LPIO2 I2C #3 or #4 exist
> +      { Return(0xF) }
> +      If (LOr(LEqual(L25D, 0), LEqual(L26D, 0))) // LPIO2 I2C #5 or #6 exist
> +      { Return(0xF) }
> +      If (LEqual(L27D, 0))                       // LPIO2 I2C #7 exist
> +      { Return(0xF) }
> +
> +      Return(0x0)
> +    }
> +
> +    // Track status of GPIO OpRegion availability for this controller
> +    Name(AVBL, 0)
> +    Method(_REG,2)
> +    {
> +      If (Lequal(Arg0, 8))
> +      {
> +        Store(Arg1, ^AVBL)
> +      }
> +    }
> +
> +    OperationRegion(GPOP, SystemIo, \GPBS, 0x50)
> +      Field(GPOP, ByteAcc, NoLock, Preserve) {
> +      Offset(0x28), // cfio_ioreg_SC_GP_LVL_63_32_ - [GPIO_BASE_ADDRESS]
> + 28h
> +          ,  21,
> +      BTD3,  1,     //This field is not used. Pin not defined in schematics. Closest
> is GPIO_S5_35 - COMBO_BT_WAKEUP
> +      Offset(0x48), // cfio_ioreg_SC_GP_LVL_95_64_ - [GPIO_BASE_ADDRESS]
> + 48h
> +          ,  30,
> +      SHD3,  1      //GPIO_S0_SC_95 - SENS_HUB_RST_N
> +    }
> +
> +
> +
> +  }   //  Device (GPO0)
> +
> +  Device (GPO1)
> +  {
> +    Name (_ADR, 0)
> +    Name (_HID, "INT33FC")
> +    Name (_CID, "INT33B2")
> +    Name (_DDN, "ValleyView2 GPNCORE controller" )
> +    Name (_UID, 2)
> +    Method (_CRS, 0x0, Serialized)
> +    {
> +      Name (RBUF, ResourceTemplate ()
> +      {
> +        Memory32Fixed (ReadWrite, 0x0FED0D000, 0x00001000)
> +        Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , , ) {48}
> +      })
> +      Return (RBUF)
> +    }
> +
> +    Method (_STA, 0x0, NotSerialized)
> +    {
> +      Return(\_SB.GPO0._STA)
> +    }
> +  }   //  Device (GPO1)
> +
> +  Device (GPO2)
> +  {
> +    Name (_ADR, 0)
> +    Name (_HID, "INT33FC")
> +    Name (_CID, "INT33B2")
> +    Name (_DDN, "ValleyView2 GPSUS controller" )
> +    Name (_UID, 3)
> +    Method (_CRS, 0x0, Serialized)
> +    {
> +      Name (RBUF, ResourceTemplate ()
> +      {
> +        Memory32Fixed (ReadWrite, 0x0FED0E000, 0x00001000)
> +        Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , , ) {50}
> +      })
> +      Return (RBUF)
> +    }
> +
> +    Method (_STA, 0x0, NotSerialized)
> +    {
> +      Return(^^GPO0._STA)
> +    }
> +
> +    // Track status of GPIO OpRegion availability for this controller
> +    Name(AVBL, 0)
> +    Method(_REG,2)
> +    {
> +      If (Lequal(Arg0, 8))
> +      {
> +        Store(Arg1, ^AVBL)
> +      }
> +    }
> +    //Manipulate GPIO line using GPIO operation regions.
> +    Name (GMOD, ResourceTemplate ()     //One method of creating a
> Connection for OpRegion accesses in Field definitions
> +    {
> +      //is creating a named object that refers to the connection attributes
> +      GpioIo (Exclusive, PullDefault, 0, 0, IoRestrictionOutputOnly,
> "\\_SB.GPO2") {21}  //sus 21+128 BT+WLAN_ENABLE
> +    })
> +
> +  OperationRegion(GPOP, SystemIo, \GPBS, 0x100)
> +  Field(GPOP, ByteAcc, NoLock, Preserve) {
> +      Offset(0x88),  // cfio_ioreg_SUS_GP_LVL_31_0_ -
> [GPIO_BASE_ADDRESS] + 88h
> +          ,  20,
> +      WFD3,  1
> +    }
> +
> +
> +  }   //  Device (GPO2)
> +  include ("PchScc.asl")
> +  include ("PchLpss.asl")
> +
> +         Scope(I2C7)
> +  {
> +
> +  } //End Scope(I2C7)
> +
> +} // end Scope(\_SB)
> +
> +Name(PICM, 0)   // Global Name, returns current Interrupt controller mode;
> updated from _PIC control method
> +
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RTD3.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RTD3.asl
> new file mode 100644
> index 0000000000..2bf62e92a1
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RTD3.asl
> @@ -0,0 +1,197 @@
> +/*********************************************************
> *****************;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
> +;*    Family of Customer Reference Boards.                                *;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved    *;
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*********************************************************
> *****************/
> +DefinitionBlock (
> +  "Rtd3.aml",
> +  "SSDT",
> +  1,
> +  "AcpiRef",
> +  "Msg_Rtd3",
> +  0x1000
> +)
> +{
> +  External(RTD3)             //flag if RTD3 is enabled
> +
> +  If(LEqual(RTD3,1))
> +  {
> +    Scope (\_SB)
> +    {
> +      Name(OSCI, 0)  // \_SB._OSC DWORD2 input
> +      Name(OSCO, 0)  // \_SB._OSC DWORD2 output
> +
> +      //Arg0 -- A buffer containing UUID
> +      //Arg1 -- An Interger containing a Revision ID of the buffer format
> +      //Arg2 -- An interger containing a count of entries in Arg3
> +      //Arg3 -- A buffer containing a list of DWORD capacities
> +      Method(_OSC, 4, NotSerialized)
> +      {
> +        // Check for proper UUID
> +        If(LEqual(Arg0, ToUUID("0811B06E-4A27-44F9-8D60-3CBBC22E7B48")))
> +        {
> +          CreateDWordField(Arg3,0,CDW1)     //bit1,2 is always clear
> +          CreateDWordField(Arg3,4,CDW2)     //Table 6-147 from ACPI spec
> +
> +          Store(CDW2, OSCI)                 // Save DWord2
> +          Or(OSCI, 0x4, OSCO)               // Only allow _PR3 support
> +
> +          If(LNotEqual(Arg1,One))
> +          {
> +            Or(CDW1,0x08,CDW1)            // Unknown revision
> +          }
> +
> +          If(LNotEqual(OSCI, OSCO))
> +          {
> +            Or(CDW1,0x10,CDW1)            // Capabilities bits were masked
> +          }
> +
> +          Store(OSCO, CDW2)                 // Replace DWord2
> +          Return(Arg3)
> +        } Else
> +        {
> +          Or(CDW1,4,CDW1)                   // Unrecognized UUID
> +          Return(Arg3)
> +        }
> +      }// End _OSC
> +    }
> +  }//end of RTD3 condition
> +
> +
> +  //USB RTD3 code
> +  If(LEqual(RTD3,1))
> +  {
> +    Scope(\_SB.PCI0.EHC1.HUBN.PR01.PR13)
> +    {
> +      Name(_PR0, Package() {\PR34})
> +      Name(_PR3, Package() {\PR34})
> +
> +      Method(_S0W, 0)
> +      {
> +        If(And(\_SB.OSCO, 0x04))              // PMEs can be genrated from D3cold
> +        {
> +          Return(4)                         // OS comprehends D3cold, as described via
> \_SB._OSC
> +        } Else
> +        {
> +          Return(3)
> +        }
> +      } // End _S0W
> +    }
> +
> +    Scope(\_SB.PCI0.EHC1.HUBN.PR01.PR14)
> +    {
> +      Name(_PR0, Package() {\PR34})
> +      Name(_PR3, Package() {\PR34})
> +
> +      Method(_S0W, 0)
> +      {
> +        If(And(\_SB.OSCO, 0x04))
> +        {
> +          Return(4)
> +        } Else
> +        {
> +          Return(3)
> +        }
> +      } // End _S0W
> +    }
> +
> +
> +    Scope(\_SB.PCI0.EHC1.HUBN.PR01.PR15)
> +    {
> +      Name(_PR0, Package() {\PR56})
> +      Name(_PR3, Package() {\PR56})
> +
> +      Method(_S0W, 0)
> +      {
> +        If(And(\_SB.OSCO, 0x04))
> +        {
> +          Return(4)
> +        } Else
> +        {
> +          Return(3)
> +        }
> +      } // End _S0W
> +    }
> +
> +    Scope(\_SB.PCI0.EHC1.HUBN.PR01.PR16)
> +    {
> +      Name(_PR0, Package() {\PR56})
> +      Name(_PR3, Package() {\PR56})
> +
> +      Method(_S0W, 0)
> +      {
> +        If(And(\_SB.OSCO, 0x04))
> +        {
> +          Return(4)
> +        } Else
> +        {
> +          Return(3)
> +        }
> +      } // End _S0W
> +    }
> +
> +    Scope(\_SB.PCI0.XHC1)                              // XHCI host only controller
> +    {
> +
> +      Method(_PS0,0,Serialized)                      // set device into D0 state
> +      {
> +      }
> +
> +      Method(_PS3,0,Serialized)                      // place device into D3H state
> +      {
> +        //write to PMCSR
> +      }
> +
> +      Method(_DSW, 3,Serialized)                     // enable or disable the device’s
> ability to wake a sleeping system.
> +      {
> +      }
> +    }
> +
> +    Scope(\_SB.PCI0.XHC1.RHUB.HS01)
> +    {
> +
> +    }
> +
> +    Scope(\_SB.PCI0.XHC1.RHUB.SSP1)
> +    {
> +
> +    }
> +
> +    Scope(\_SB.PCI0.XHC2)                              // OTG
> +    {
> +
> +      Method(_PS0,0,Serialized)                      // set device into D0 state
> +      {
> +      }
> +
> +      Method(_PS3,0,Serialized)                      // place device into D3H state
> +      {
> +        //write to PMCSR
> +      }
> +
> +      Method(_DSW, 3,Serialized)                      // enable or disable the device’s
> ability to wake a sleeping system.
> +      {
> +      }
> +    }
> +
> +    Scope(\_SB.PCI0.XHC2.RHUB.HS01)
> +    {
> +
> +    }
> +
> +    Scope(\_SB.PCI0.XHC2.RHUB.SSP1)
> +    {
> +
> +    }
> +  } //If(LEqual(RTD3,1)) USB
> +
> +}//end of SSDT
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RhProxy.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RhProxy.asl
> new file mode 100644
> index 0000000000..d7e785f532
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RhProxy.asl
> @@ -0,0 +1,160 @@
> +/** @file
> +  SSDT for RhProxy Driver.
> +
> +Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +DefinitionBlock ("RHPX.aml", "SSDT", 1, "MSFT", "RHPROXY", 1)
> +{
> +    Scope (\_SB)
> +    {
> +        //
> +        // Test peripheral device node for MinnowBoardMax
> +        //
> +        Device(RHPX)
> +        {
> +            Name(_HID, "MSFT8000")
> +            Name(_CID, "MSFT8000")
> +            Name(_UID, 1)
> +
> +            Name(_CRS, ResourceTemplate()
> +            {
> +                // Index 0
> +                SPISerialBus(            // Pin 5, 7, 9 , 11 of JP1 for SIO_SPI
> +                    1,                     // Device selection
> +                    PolarityLow,           // Device selection polarity
> +                    FourWireMode,          // wiremode
> +                    8,                     // databit len
> +                    ControllerInitiated,   // slave mode
> +                    8000000,               // Connection speed
> +                    ClockPolarityLow,      // Clock polarity
> +                    ClockPhaseSecond,      // clock phase
> +                    "\\_SB.SPI1",          // ResourceSource: SPI bus controller name
> +                    0,                     // ResourceSourceIndex
> +                    ResourceConsumer,      // Resource usage
> +                    JSPI,                  // DescriptorName: creates name for offset of
> resource descriptor
> +                    )                      // Vendor Data
> +
> +                // Index 1
> +                I2CSerialBus(            // Pin 13, 15 of JP1, for SIO_I2C5 (signal)
> +                    0xFF,                  // SlaveAddress: bus address (TBD)
> +                    ,                      // SlaveMode: default to ControllerInitiated
> +                    400000,                // ConnectionSpeed: in Hz
> +                    ,                      // Addressing Mode: default to 7 bit
> +                    "\\_SB.I2C6",          // ResourceSource: I2C bus controller name
> (For MinnowBoard Max, hardware I2C5(0-based) is reported as ACPI I2C6(1-
> based))
> +                    ,
> +                    ,
> +                    JI2C,                  // Descriptor Name: creates name for offset of
> resource descriptor
> +                    )                      // VendorData
> +
> +                // Index 2
> +                UARTSerialBus(           // Pin 17, 19 of JP1, for SIO_UART2
> +                    115200,                // InitialBaudRate: in bits ber second
> +                    ,                      // BitsPerByte: default to 8 bits
> +                    ,                      // StopBits: Defaults to one bit
> +                    0xfc,                  // LinesInUse: 8 1-bit flags to declare line enabled
> +                    ,                      // IsBigEndian: default to LittleEndian
> +                    ,                      // Parity: Defaults to no parity
> +                    ,                      // FlowControl: Defaults to no flow control
> +                    32,                    // ReceiveBufferSize
> +                    32,                    // TransmitBufferSize
> +                    "\\_SB.URT2",          // ResourceSource: UART bus controller name
> +                    ,
> +                    ,
> +                    UAR2,                  // DescriptorName: creates name for offset of
> resource descriptor
> +                    )
> +
> +                // Index 3
> +                GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO2",)
> {0}  // Pin 21 of JP1 (GPIO_S5[00])
> +                // Index 4
> +                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone,
> 0,"\\_SB.GPO2",) {0}
> +
> +                // Index 5
> +                GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO2",)
> {1}  // Pin 23 of JP1 (GPIO_S5[01])
> +                // Index 6
> +                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone,
> 0,"\\_SB.GPO2",) {1}
> +
> +                // Index 7
> +                GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO2",)
> {2}  // Pin 25 of JP1 (GPIO_S5[02])
> +                // Index 8
> +                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone,
> 0,"\\_SB.GPO2",) {2}
> +
> +                // Index 9
> +                UARTSerialBus(           // Pin 6, 8, 10, 12 of JP1, for SIO_UART1
> +                    115200,                // InitialBaudRate: in bits ber second
> +                    ,                      // BitsPerByte: default to 8 bits
> +                    ,                      // StopBits: Defaults to one bit
> +                    0xfc,                  // LinesInUse: 8 1-bit flags to declare line enabled
> +                    ,                      // IsBigEndian: default to LittleEndian
> +                    ,                      // Parity: Defaults to no parity
> +                    FlowControlHardware,   // FlowControl: Defaults to no flow
> control
> +                    32,                    // ReceiveBufferSize
> +                    32,                    // TransmitBufferSize
> +                    "\\_SB.URT1",          // ResourceSource: UART bus controller name
> +                    ,
> +                    ,
> +                    UAR1,              // DescriptorName: creates name for offset of
> resource descriptor
> +                    )
> +
> +                // Index 10
> +                GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",)
> {62}  // Pin 14 of JP1 (GPIO_SC[62])
> +                // Index 11
> +                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone,
> 0,"\\_SB.GPO0",) {62}
> +
> +                // Index 12
> +                GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",)
> {63}  // Pin 16 of JP1 (GPIO_SC[63])
> +                // Index 13
> +                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone,
> 0,"\\_SB.GPO0",) {63}
> +
> +                // Index 14
> +                GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",)
> {65}  // Pin 18 of JP1 (GPIO_SC[65])
> +                // Index 15
> +                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone,
> 0,"\\_SB.GPO0",) {65}
> +
> +                // Index 16
> +                GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",)
> {64}  // Pin 20 of JP1 (GPIO_SC[64])
> +                // Index 17
> +                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone,
> 0,"\\_SB.GPO0",) {64}
> +
> +                // Index 18
> +                GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",)
> {94}  // Pin 22 of JP1 (GPIO_SC[94])
> +                // Index 19
> +                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone,
> 0,"\\_SB.GPO0",) {94}
> +
> +                // Index 20
> +                GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",)
> {95}  // Pin 24 of JP1 (GPIO_SC[95])
> +                // Index 21
> +                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone,
> 0,"\\_SB.GPO0",) {95}
> +
> +                // Index 22
> +                GpioIo (Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPO0",)
> {54}  // Pin 26 of JP1 (GPIO_SC[54])
> +                // Index 23
> +                GpioInt(Edge, ActiveBoth, SharedAndWake, PullNone,
> 0,"\\_SB.GPO0",) {54}
> +            })
> +
> +            Name(_DSD, Package()
> +            {
> +                ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +                Package()
> +                {
> +                    // SPI Mapping
> +                    Package(2) { "bus-SPI-SPI0", Package() { 0 }},
> +
> +                    // TODO: Intel will need to provide the right value for SPI0
> properties
> +                    Package(2) { "SPI0-MinClockInHz", 100000 },
> +                    Package(2) { "SPI0-MaxClockInHz", 15000000 },
> +                    // SupportedDataBitLengths takes a list of support data bit length
> +                    // Example : Package(2) { "SPI0-SupportedDataBitLengths",
> Package() { 8, 7, 16 }},
> +                    Package(2) { "SPI0-SupportedDataBitLengths", Package() { 4, 5, 6,
> 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
> 30, 31, 32 }},
> +                    // I2C Mapping
> +                    Package(2) { "bus-I2C-I2C5", Package() { 1 }},
> +                    // UART Mapping
> +                    Package(2) { "bus-UART-UART2", Package() { 2 }},
> +                    Package(2) { "bus-UART-UART1", Package() { 9 }},
> +                }
> +            })
> +        }
> +    }
> +}
> \ No newline at end of file
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/THERMAL.ASL
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/THERMAL.ASL
> new file mode 100644
> index 0000000000..6d9e9f3d69
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/THERMAL.ASL
> @@ -0,0 +1,137 @@
> +/*********************************************************
> *****************;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
> +;*    Family of Customer Reference Boards.                                *;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Copyright (c)  1999  - 2017, Intel Corporation. All rights reserved   *;
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*********************************************************
> *****************/
> +
> +
> +// THERMAL.ASL represents a Thermal Zone to be used for testing on the
> +// Customer Reference Boards.
> +
> +External(\_SB.DPTF.CTOK, MethodObj)
> +
> +Scope(\_TZ)
> +{
> +
> +  // Thermal Zone 1 = DTS Thermal Zone.
> +
> +  ThermalZone(TZ01)
> +  {
> +    // Return the temperature at which the OS must perform a Critcal
> +    // Shutdown.
> +
> +    Method(_CRT,0,Serialized)
> +    {
> +      Return(Add(2732,Multiply(CRTT,10)))
> +    }
> +
> +    // Notifies ASL Code the current cooling mode.
> +    //      0 - Active cooling
> +    //      1 - Passive cooling
> +
> +    Method(_SCP,1,Serialized)
> +    {
> +      Store(Arg0,CTYP)
> +    }
> +
> +    // _TMP (Temperature)
> +    //
> +    // Return the highest of the CPU temperatures to the OS.
> +    //
> +    // Arguments: (0)
> +    //   None
> +    // Return Value:
> +    //   An Integer containing the current temperature of the thermal zone (in
> tenths of degrees Kelvin)
> +    //
> +    Method(_TMP,0,Serialized)
> +    {
> +      If(DTSE)
> +      {
> +        If(LGreater(DTS2, DTS1))
> +        {
> +          Store(DTS2,Local0)
> +        } else
> +        {
> +          Store(DTS1,Local0)
> +        }
> +        If (LEqual(And(Local0, 0x80), 0)) {
> +          Return(Add(2732,Multiply(Local0,10)))
> +        } else {
> +          Add(Subtract(255, Local0), 1, Local0)
> +          Return(Subtract(2732,Multiply(Local0,10)))
> +        }
> +        //
> +        // Else return a static value if both EC and DTS are unavailable.
> +        //
> +      } Else
> +      {
> +        Return(3000) // (3000-2732)/10 = 26.8 degree C
> +      }
> +    }
> +
> +    // Return the Processor(s) used for Passive Cooling.
> +
> +    Method(_PSL,0,Serialized)
> +    {
> +      If(LEqual(MPEN, 4))
> +      {
> +        //  CMP - Throttling controls all four logical CPUs.
> +        Return(Package() {\_PR.CPU0,\_PR.CPU1,\_PR.CPU2,\_PR.CPU3})
> +      }
> +
> +      If(MPEN)
> +      {
> +        //  CMP - Throttling controls both CPUs.
> +
> +        Return(Package() {\_PR.CPU0,\_PR.CPU1})
> +      }
> +
> +      Return(Package() {\_PR.CPU0})
> +    }
> +
> +    // Returns the temperature at which the OS initiates CPU throttling.
> +
> +    Method(_PSV,0,Serialized)
> +    {
> +      Return(Add(2732,Multiply(PSVT,10)))
> +    }
> +
> +    // Returns TC1 value used in the passive cooling formula.
> +
> +    Method(_TC1,0,Serialized)
> +    {
> +      Return(TC1V)
> +    }
> +
> +    // Returns TC2 value used in the passive cooling formula.
> +
> +    Method(_TC2,0,Serialized)
> +    {
> +      Return(TC2V)
> +    }
> +
> +    // Returns the sampling period used in the passive cooling formula.
> +
> +    Method(_TSP,0,Serialized)
> +    {
> +      Return(TSPV)
> +    }
> +
> +    // Returns Hot Temperature
> +
> +    Method(_HOT,0,Serialized)
> +    {
> +      Subtract(CRTT, 5, Local0)
> +      Return(Add(2732,Multiply(Local0,10)))
> +    }
> +  }
> +}
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/UsbSbd.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/UsbSbd.asl
> new file mode 100644
> index 0000000000..a4fb173862
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/UsbSbd.asl
> @@ -0,0 +1,93 @@
> +/*********************************************************
> ***************************;
> +;*                                                                                  *;
> +;*                                                                                  *;
> +;*    Intel Corporation - ACPI Reference Code for the Baytrail                      *;
> +;*    Family of Customer Reference Boards.                                          *;
> +;*                                                                                  *;
> +;*    MPG-MSAE                                                                      *;
> +;*                                                                                  *;
> +;*    Copyright (c) 1999 - 2014, Intel Corporation.                                 *;
> +;*                                                                                  *;
> +;* ThSPDX-License-Identifier: BSD-2-Clause-Patent
> +;*                                                                                  *;
> +;*                                                                                  *;
> +;*    This program has been developed by Intel Corporation.                         *;
> +;*    Licensee has Intel's permission to incorporate this source code               *;
> +;*    into their product, royalty free.  This source code may NOT be                *;
> +;*    redistributed to anyone without Intel's written permission.                   *;
> +;*                                                                                  *;
> +;*    Intel specifically disclaims all warranties, express or                       *;
> +;*    implied, and all liability, including consequential and other                 *;
> +;*    indirect damages, for the use of this code, including liability               *;
> +;*    for infringement of any proprietary rights, and including the                 *;
> +;*    warranties of merchantability and fitness for a particular                    *;
> +;*    purpose.  Intel does not assume any responsibility for any                    *;
> +;*    errors which may appear in this code nor any responsibility to                *;
> +;*    update it.                                                                    *;
> +;*                                                                                  *;
> +;*    Version:  See README.TXT                                                      *;
> +;*                                                                                  *;
> +;*********************************************************
> ***************************/
> +
> +//
> +// _DSM : Device Specific Method supporting USB Sideband Deferring
> function
> +//
> +// Arg0: UUID Unique function identifier
> +// Arg1: Integer Revision Level
> +// Arg2: Integer Function Index
> +// Arg3: Package Parameters
> +//
> +Method (_DSM, 4, Serialized, 0, UnknownObj, {BuffObj, IntObj, IntObj,
> PkgObj})
> +{
> +
> +  If (LEqual(Arg0, ToUUID ("A5FC708F-8775-4BA6-BD0C-BA90A1EC72F8")))
> +  {
> +    //
> +    // Switch by function index
> +    //
> +    Switch (ToInteger(Arg2))
> +    {
> +      //
> +      // Standard query - A bitmask of functions supported
> +      // Supports function 0-2
> +      //
> +      Case (0)
> +      {
> +        if (LEqual(Arg1, 1))   // test Arg1 for the revision
> +        {
> +          Return (Buffer () {0x07})
> +        }
> +        else
> +        {
> +          Return (Buffer () {0})
> +        }
> +      }
> +      //
> +      // USB Sideband Deferring Support
> +      //   0: USB Sideband Deferring not supported on this device
> +      //   1: USB Sideband Deferring supported
> +      //
> +      Case (1)
> +      {
> +        if (LEqual(SDGV,0xFF))   // check for valid GPE vector
> +        {
> +          Return (0)
> +        }
> +        else
> +        {
> +          Return (1)
> +        }
> +      }
> +      //
> +      // GPE Vector
> +      //  Return the bit offset within the GPE block of the GPIO (HOST_ALERT)
> driven by this device
> +      //
> +      Case (2)
> +      {
> +        Return (SDGV)
> +      }
> +    }
> +  }
> +
> +  Return (0)
> +}
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Video.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Video.asl
> new file mode 100644
> index 0000000000..768b912aae
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Video.asl
> @@ -0,0 +1,34 @@
> +/*********************************************************
> *****************;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Intel Corporation - ACPI Reference Code for the Baytrail            *;
> +;*    Family of Customer Reference Boards.                                *;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved   *;
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*********************************************************
> *****************/
> +
> +
> +
> +
> +// Brightness Notification:
> +//              Generate a brightness related notification
> +//      to the LFP if its populated.
> +//
> +//      Arguments:
> +//              Arg0:   Notification value.
> +//
> +//      Return Value:
> +//              None
> +Method(BRTN,1,Serialized)
> +{
> +  If(LEqual(And(DIDX,0x0F00),0x400))
> +  {
> +    Notify(\_SB.PCI0.GFX0.DD1F,Arg0)
> +  }
> +}
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Vlv.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Vlv.asl
> new file mode 100644
> index 0000000000..32e1851303
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Vlv.asl
> @@ -0,0 +1,39 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  VLV.ASL
> +
> +Abstract:
> +
> +  Baytrail PCI configuration space definition.
> +
> +--*/
> +Scope (\_SB.PCI0)
> +{
> +
> +  Device(GFX0)   // Mobile I.G.D
> +  {
> +    Name(_ADR, 0x00020000)
> +
> +    Method(GDEP, 0)
> +    {
> +      If(LEqual(OSYS,2013))
> +      {
> +        Name(_DEP, Package(0x1)
> +        {
> +          PEPD
> +        })
> +      }
> +    }
> +
> +    include("INTELGFX.ASL")
> +    include("INTELISPDev2.ASL")
> +  } // end "Mobile I.G.D"
> +}//end scope
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Wsmt/Wsmt.aslc
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Wsmt/Wsmt.aslc
> new file mode 100644
> index 0000000000..35fa799123
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Wsmt/Wsmt.aslc
> @@ -0,0 +1,54 @@
> +/*++
> +  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  Wsmt.c
> +
> +Abstract:
> +
> +  This file contains a structure definition for the Windows SMM Security
> +  Mitigations Table (WSMT).
> +
> +++*/
> +
> +//
> +// Statements that include other files
> +//
> +#include "AcpiTablePlatform.h"
> +#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
> +
> +//
> +// WSMT Table definition
> +//
> +EFI_ACPI_WSMT_TABLE WSMT = {
> +  EFI_ACPI_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE,
> +  sizeof (EFI_ACPI_WSMT_TABLE),
> +  EFI_WSMT_TABLE_REVISION,
> +  //
> +  // Checksum will be updated at runtime
> +  //
> +  0,
> +  EFI_ACPI_OEM_ID,            // OEMID is a 6 bytes long field
> +  EFI_ACPI_OEM_TABLE_ID,      // OEM table identification(8 bytes long)
> +  EFI_ACPI_OEM_REVISION,      // OEM revision
> +  EFI_ACPI_CREATOR_ID,        // ASL compiler vendor ID
> +  EFI_ACPI_CREATOR_REVISION,  // ASL compiler revision number
> +  0x00000000,                 // Protection flag
> +};
> +
> +VOID*
> +ReferenceAcpiTable (
> +  VOID
> +  )
> +{
> +  //
> +  // Reference the table being generated to prevent the optimizer from
> +  // removing the data structure from the executable
> +  //
> +  return (VOID*)&WSMT;
> +}
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/token.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/token.asl
> new file mode 100644
> index 0000000000..f976cb84d3
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/token.asl
> @@ -0,0 +1,39 @@
> +/*********************************************************
> *****************;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Intel Corporation - ACPI Reference Code for the Sandy Bridge        *;
> +;*    Family of Customer Reference Boards.                                *;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*    Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved    *;
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;*                                                                        *;
> +;*                                                                        *;
> +;*********************************************************
> *****************/
> +
> +Name(PMBS, 0x400)       // ASL alias for ACPI I/O base address.
> +Name(SMIP, 0xb2)        // I/O port to trigger SMI
> +Name(GPBS, 0x500)       // GPIO Register Block address
> +Name(APCB, 0xfec00000)  // Default I/O APIC(s) memory start address,
> 0x0FEC00000 - default, 0 - I/O APIC's disabled
> +Name(APCL, 0x1000)      // I/O APIC(s) memory decoded range, 0x1000 -
> default, 0 - I/O APIC's not decoded
> +Name(PFDR, 0xfed03034)  // PMC Function Disable Register
> +Name(PMCB, 0xfed03000)  // PMC Base Address
> +Name(PCLK, 0xfed03060)  // PMC Clock Control Register
> +Name(PUNB, 0xfed05000)  // PUNIT Base Address
> +Name(IBAS, 0xfed08000)  // ILB Base Address
> +Name(SRCB, 0xfed1c000)  // RCBA (Root Complex Base Address)
> +Name(SRCL, 0x1000)      // RCBA length
> +Name(HPTB, 0xfed00000)  // Same as HPET_BASE_ADDRESS for ASL use
> +Name(PEBS, 0xe0000000)  // PCIe Base
> +Name(PELN, 0x10000000)  //
> +Name(FMBL, 0x1) // Platform Flavor - Mobile flavor for ASL code.
> +Name(FDTP, 0x2) // Platform Flavor - Desktop flavor for ASL code.
> +Name(SDGV, 0x1c)        // UHCI Controller HOST_ALERT's bit offset within
> the GPE block. GPIO[0:15] corresponding to GPE[16:31]
> +Name(PEHP, 0x1) // _OSC: Pci Express Native Hot Plug Control
> +Name(SHPC, 0x0) // _OSC: Standard Hot Plug Controller (SHPC) Native Hot
> Plug control
> +Name(PEPM, 0x1) // _OSC: Pci Express Native Power Management Events
> control
> +Name(PEER, 0x1) // _OSC: Pci Express Advanced Error Reporting control
> +Name(PECS, 0x1) // _OSC: Pci Express Capability Structure control
> +
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Guid/Vlv2DeviceRefCodePkg
> TokenSpace.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Guid/Vlv2DeviceRefCodePkg
> TokenSpace.h
> new file mode 100644
> index 0000000000..c7408b9308
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Guid/Vlv2DeviceRefCodePkg
> TokenSpace.h
> @@ -0,0 +1,24 @@
> +/*++
> +
> +Copyright (c)  2010  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +Module Name:
> +
> +  Vlv2DeviceRefCodeTokenSpace.h
> +
> +Abstract:
> +
> +  Interface definition details for GUID.
> +
> +--*/
> +#ifndef __VLV2_REF_CODE__PKG_TOKEN_SPACE_GUID_H__
> +#define __VLV2_REF_CODE__PKG_TOKEN_SPACE_GUID_H__
> +
> +#define EFI_VLV_TOKEN_SPACE_GUID \
> +  { 0xca452c68, 0xdf0c, 0x45c9, {0x82, 0xfb, 0xea, 0xe4, 0x2b, 0x31, 0x29,
> 0x46}}
> +extern EFI_GUID gEfiVLVTokenSpaceGuid;
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/PttPassThruPpi.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/PttPassThruPpi.h
> new file mode 100644
> index 0000000000..55646f4f3e
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/PttPassThruPpi.h
> @@ -0,0 +1,92 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2015, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +--*/
> +
> +#ifndef _EFI_PTT_PASS_THRU_PPI_H
> +#define _EFI_PTT_PASS_THRU_PPI_H
> +
> +#define PTT_PASS_THRU_PPI_GUID \
> +  { \
> +    0xc5068bac, 0xa7dc, 0x42f1, 0xae, 0x80, 0xca, 0xa2, 0x4b, 0xb4, 0x90, 0x4b
> \
> +  }
> +// {C5068BAC-A7DC-42f1-AE80-CAA24BB4904B}
> +//static const GUID <<name>> =
> +//{ 0xc5068bac, 0xa7dc, 0x42f1, { 0xae, 0x80, 0xca, 0xa2, 0x4b, 0xb4, 0x90,
> 0x4b } };
> +
> +
> +
> +//#define EFI_PTT_PROTOCOL_GUID  HECI_PROTOCOL_GUID
> +
> +typedef struct _PTT_PASS_THRU_PPI PTT_PASS_THRU_PPI;
> +
> +/**
> +  This service enables the sending of commands to the TPM2.
> +
> +  @param[in]      InputParameterBlockSize  Size of the TPM2 input parameter
> block.
> +  @param[in]      InputParameterBlock      Pointer to the TPM2 input
> parameter block.
> +  @param[in,out]  OutputParameterBlockSize Size of the TPM2 output
> parameter block.
> +  @param[in]      OutputParameterBlock     Pointer to the TPM2 output
> parameter block.
> +
> +  @retval EFI_SUCCESS            The command byte stream was successfully
> sent to the device and a response was successfully received.
> +  @retval EFI_DEVICE_ERROR       The command was not successfully sent to
> the device or a response was not successfully received from the device.
> +  @retval EFI_BUFFER_TOO_SMALL   The output parameter block is too
> small.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *TPM2_SUBMIT_COMMAND) (
> +  IN PTT_PASS_THRU_PPI *This,
> +  IN UINT32                  InputParameterBlockSize,
> +  IN UINT8                   *InputParameterBlock,
> +  IN OUT UINT32              *OutputParameterBlockSize,
> +  IN UINT8                   *OutputParameterBlock
> +  );
> +
> +/**
> +  This service requests use TPM2.
> +
> +  @retval EFI_SUCCESS      Get the control of TPM2 chip.
> +  @retval EFI_NOT_FOUND    TPM2 not found.
> +  @retval EFI_DEVICE_ERROR Unexpected device behavior.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *TPM2_REQUEST_USE_TPM) (
> +  IN PTT_PASS_THRU_PPI *This
> +  );
> +
> +typedef struct {
> +  EFI_GUID                           ProviderGuid;
> +  TPM2_SUBMIT_COMMAND                Tpm2SubmitCommand;
> +  TPM2_REQUEST_USE_TPM               Tpm2RequestUseTpm;
> +} PTT_TPM2_DEVICE_INTERFACE;
> +
> +
> +/**
> +  This service register TPM2 device.
> +
> +  @param Tpm2Device  TPM2 device
> +
> +  @retval EFI_SUCCESS          This TPM2 device is registered successfully.
> +  @retval EFI_UNSUPPORTED      System does not support register this TPM2
> device.
> +  @retval EFI_ALREADY_STARTED  System already register this TPM2 device.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *TPM2_REGISTER_TPM2_DEVICE_LIB) (
> +  IN PTT_PASS_THRU_PPI  *This,
> +  IN PTT_TPM2_DEVICE_INTERFACE   *Tpm2Device
> +  );
> +
> +typedef struct _PTT_PASS_THRU_PPI {
> +  TPM2_SUBMIT_COMMAND             Tpm2SubmitCommand;
> +  TPM2_REQUEST_USE_TPM            Tpm2RequestUseTpm;
> +  TPM2_REGISTER_TPM2_DEVICE_LIB   Tpm2RegisterTpm2DeviceLib;
> +} PTT_PASS_THRU_PPI;
> +
> +extern EFI_GUID gPttPassThruPpiGuid;
> +
> +#endif // _EFI_HECI_H
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/fTPMPolicy.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/fTPMPolicy.h
> new file mode 100644
> index 0000000000..8f3acfd005
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/fTPMPolicy.h
> @@ -0,0 +1,26 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2015, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +--*/
> +
> +#ifndef _SEC_FTPM_POLICY_PPI_H_
> +#define _SEC_FTPM_POLICY_PPI_H_
> +
> +#define SEC_FTPM_POLICY_PPI_GUID \
> +  { \
> +    0x4fd1ba49, 0x8f90, 0x471a, 0xa2, 0xc9, 0x17, 0x3c, 0x7a, 0x73, 0x2f, 0xd0
> \
> +  }
> +
> +extern EFI_GUID  gSeCfTPMPolicyPpiGuid;
> +
> +//
> +// PPI definition
> +//
> +typedef struct SEC_FTPM_POLICY_PPI {
> +  BOOLEAN                 fTPMEnable;
> +} SEC_FTPM_POLICY_PPI;
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Protocol/PttPassThru.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Protocol/PttPassThru.h
> new file mode 100644
> index 0000000000..2009a46816
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Protocol/PttPassThru.h
> @@ -0,0 +1,91 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2015, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +--*/
> +
> +#ifndef _EFI_PTT_PASS_THRU_H
> +#define _EFI_PTT_PASS_THRU_H
> +
> +#define PTT_PASS_THRU_PROTOCOL_GUID \
> +  { \
> +    0x73e2576, 0xf6c1, 0x4b91, 0x92, 0xa9, 0xd4, 0x67, 0x5d, 0xda, 0x34, 0xb1
> \
> +  }
> +// {073E2576-F6C1-4b91-92A9-D4675DDA34B1}
> +//static const GUID <<name>> =
> +//{ 0x73e2576, 0xf6c1, 0x4b91, { 0x92, 0xa9, 0xd4, 0x67, 0x5d, 0xda, 0x34,
> 0xb1 } };
> +
> +
> +//#define EFI_PTT_PROTOCOL_GUID  HECI_PROTOCOL_GUID
> +
> +typedef struct _PTT_PASS_THRU_PROTOCOL PTT_PASS_THRU_PROTOCOL;
> +
> +/**
> +  This service enables the sending of commands to the TPM2.
> +
> +  @param[in]      InputParameterBlockSize  Size of the TPM2 input parameter
> block.
> +  @param[in]      InputParameterBlock      Pointer to the TPM2 input
> parameter block.
> +  @param[in,out]  OutputParameterBlockSize Size of the TPM2 output
> parameter block.
> +  @param[in]      OutputParameterBlock     Pointer to the TPM2 output
> parameter block.
> +
> +  @retval EFI_SUCCESS            The command byte stream was successfully
> sent to the device and a response was successfully received.
> +  @retval EFI_DEVICE_ERROR       The command was not successfully sent to
> the device or a response was not successfully received from the device.
> +  @retval EFI_BUFFER_TOO_SMALL   The output parameter block is too
> small.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *TPM2_SUBMIT_COMMAND) (
> +  IN PTT_PASS_THRU_PROTOCOL *This,
> +  IN UINT32                  InputParameterBlockSize,
> +  IN UINT8                   *InputParameterBlock,
> +  IN OUT UINT32              *OutputParameterBlockSize,
> +  IN UINT8                   *OutputParameterBlock
> +  );
> +
> +/**
> +  This service requests use TPM2.
> +
> +  @retval EFI_SUCCESS      Get the control of TPM2 chip.
> +  @retval EFI_NOT_FOUND    TPM2 not found.
> +  @retval EFI_DEVICE_ERROR Unexpected device behavior.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *TPM2_REQUEST_USE_TPM) (
> +  IN PTT_PASS_THRU_PROTOCOL *This
> +  );
> +
> +typedef struct {
> +  EFI_GUID                           ProviderGuid;
> +  TPM2_SUBMIT_COMMAND                Tpm2SubmitCommand;
> +  TPM2_REQUEST_USE_TPM               Tpm2RequestUseTpm;
> +} PTT_TPM2_DEVICE_INTERFACE;
> +
> +
> +/**
> +  This service register TPM2 device.
> +
> +  @param Tpm2Device  TPM2 device
> +
> +  @retval EFI_SUCCESS          This TPM2 device is registered successfully.
> +  @retval EFI_UNSUPPORTED      System does not support register this TPM2
> device.
> +  @retval EFI_ALREADY_STARTED  System already register this TPM2 device.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *TPM2_REGISTER_TPM2_DEVICE_LIB) (
> +  IN PTT_PASS_THRU_PROTOCOL  *This,
> +  IN PTT_TPM2_DEVICE_INTERFACE   *Tpm2Device
> +  );
> +
> +typedef struct _PTT_PASS_THRU_PROTOCOL {
> +  TPM2_SUBMIT_COMMAND             Tpm2SubmitCommand;
> +  TPM2_REQUEST_USE_TPM            Tpm2RequestUseTpm;
> +  TPM2_REGISTER_TPM2_DEVICE_LIB   Tpm2RegisterTpm2DeviceLib;
> +} PTT_PASS_THRU_PROTOCOL;
> +
> +extern EFI_GUID gPttPassThruProtocolGuid;
> +
> +#endif // _EFI_HECI_H
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Guid/P
> owerManagementAcpiTableStorage.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Guid/P
> owerManagementAcpiTableStorage.h
> new file mode 100644
> index 0000000000..eab1db0897
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Guid/P
> owerManagementAcpiTableStorage.h
> @@ -0,0 +1,27 @@
> +
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +Module Name:
> +
> +  PowerManagementAcpiTableStorage.h
> +
> +Abstract:
> +
> +  GUID definition for the Power Management ACPI table storage file name
> +
> +--*/
> +
> +#ifndef _POWER_MANAGEMENT_ACPI_TABLE_STORAGE_H_
> +#define _POWER_MANAGEMENT_ACPI_TABLE_STORAGE_H_
> +
> +#define POWER_MANAGEMENT_ACPI_TABLE_STORAGE_GUID \
> +  { 0x161be597, 0xe9c5, 0x49db, 0xae, 0x50, 0xc4, 0x62, 0xab, 0x54, 0xee,
> 0xda }
> +
> +extern EFI_GUID gPowerManagementAcpiTableStorageGuid;
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Ppi/Vlv
> Policy.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Ppi/Vlv
> Policy.h
> new file mode 100644
> index 0000000000..0a8b267db1
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Ppi/Vlv
> Policy.h
> @@ -0,0 +1,104 @@
> +
> +/*++
> +
> +Copyright (c)  2010  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +Module Name:
> +
> +  VlvPolicy.h
> +
> +Abstract:
> +
> +  Interface definition details between ValleyView MRC and platform drivers
> during PEI phase.
> +
> +--*/
> +
> +#ifndef _VLV_POLICY_PPI_H_
> +#define _VLV_POLICY_PPI_H_
> +
> +//
> +// MRC Policy provided by platform for PEI phase {7D84B2C2-22A1-4372-
> B12C-EBB232D3A6A3}
> +//
> +#define VLV_POLICY_PPI_GUID \
> +  { \
> +    0x7D84B2C2, 0x22A1, 0x4372, 0xB1, 0x2C, 0xEB, 0xB2, 0x32, 0xD3, 0xA6,
> 0xA3 \
> +  }
> +
> +//
> +// Extern the GUID for protocol users.
> +//
> +extern EFI_GUID gVlvPolicyPpiGuid;
> +
> +//
> +// PPI revision number
> +// Any backwards compatible changes to this PPI will result in an update in
> the revision number
> +// Major changes will require publication of a new PPI
> +//
> +#define MRC_PLATFORM_POLICY_PPI_REVISION  1
> +
> +#ifndef MAX_SOCKETS
> +#define MAX_SOCKETS 4
> +#endif
> +
> +#define S3_TIMING_DATA_LEN          9
> +#define S3_READ_TRAINING_DATA_LEN   16
> +#define S3_WRITE_TRAINING_DATA_LEN  12
> +
> +#ifndef S3_RESTORE_DATA_LEN
> +#define S3_RESTORE_DATA_LEN (S3_TIMING_DATA_LEN +
> S3_READ_TRAINING_DATA_LEN + S3_WRITE_TRAINING_DATA_LEN)
> +#endif // S3_RESTORE_DATA_LEN
> +#pragma pack(1)
> +//
> +// MRC Platform Data Structure
> +//
> +typedef struct {
> +  UINT8   SpdAddressTable[MAX_SOCKETS];
> +  UINT8   TSonDimmSmbusAddress[MAX_SOCKETS];
> +
> +  UINT16  SmbusBar;
> +  UINT32  IchRcba;
> +  UINT32  WdbBaseAddress; // Write Data Buffer area (WC caching mode)
> +  UINT32  WdbRegionSize;
> +  UINT32  SmBusAddress;
> +  UINT8   UserBd;
> +  UINT8   PlatformType;
> +  UINT8   FastBoot;
> +  UINT8   DynSR;
> +} VLV_PLATFORM_DATA;
> +
> +
> +typedef struct {
> +  UINT16  MmioSize;
> +  UINT16  GttSize;
> +  UINT8   IgdDvmt50PreAlloc;
> +  UINT8   PrimaryDisplay;
> +  UINT8   PAVPMode;
> +  UINT8   ApertureSize;
> +} GT_CONFIGURATION;
> +
> +typedef struct {
> +  UINT8   EccSupport;
> +  UINT16  DdrFreqLimit;
> +  UINT8   MaxTolud;
> +} MEMORY_CONFIGURATION;
> +
> +
> +//
> +// MRC Platform Policiy PPI
> +//
> +typedef struct _VLV_POLICY_PPI {
> +  UINT8                 Revision;
> +  VLV_PLATFORM_DATA     PlatformData;
> +  GT_CONFIGURATION      GtConfig;
> +  MEMORY_CONFIGURATION  MemConfig;
> +  VOID                  *S3DataPtr; // was called MRC_PARAMS_SAVE_RESTORE
> +  UINT8                 ISPEn;            //ISP (IUNIT) Device Enabled
> +  UINT8                 ISPPciDevConfig;  //ISP (IUNIT) Device Config: 0->B0/D2/F0
> for Window OS, 1->B0D3/F0 for Linux OS
> +} VLV_POLICY_PPI;
> +
> +#pragma pack()
> +
> +#endif // _VLV_POLICY_PPI_H_
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Protoc
> ol/PpmPlatformPolicy.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Protoc
> ol/PpmPlatformPolicy.h
> new file mode 100644
> index 0000000000..ab6b9e80d3
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Protoc
> ol/PpmPlatformPolicy.h
> @@ -0,0 +1,132 @@
> +/**
> +  Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +/*++
> +
> +Module Name:
> +
> +  PpmPlatformPolicy.h
> +
> +Abstract:
> +
> +  Interface definition details between PPM and platform drivers during DXE
> phase.
> +
> +--*/
> +#ifndef _PPM_PLATFORM_POLICY_H_
> +#define _PPM_PLATFORM_POLICY_H_
> +
> +//
> +//  PPM policy provided by platform for DXE phase {DDABFEAC-EF63-452c-
> 8F39-ED7FAED8265E}
> +//
> +#define PPM_PLATFORM_POLICY_PROTOCOL_GUID \
> +  {0xddabfeac, 0xef63, 0x452c, 0x8f, 0x39, 0xed, 0x7f, 0xae, 0xd8, 0x26, 0x5e}
> +
> +//
> +// Extern the GUID for protocol users.
> +//
> +extern EFI_GUID gPpmPlatformPolicyProtocolGuid;
> +
> +//
> +// Forward reference for ANSI C compatibility
> +//
> +typedef struct _PPM_PLATFORM_POLICY_PROTOCOL
> PPM_PLATFORM_POLICY_PROTOCOL;
> +
> +//
> +// Protocol revision number
> +// Any backwards compatible changes to this protocol will result in an
> update in the revision number
> +// Major changes will require publication of a new protocol
> +//
> +// Revision 1: Original version
> +// Revision 2: Added T-states field to the PPM_FUNCTION_ENABLES
> structure, Renamed unused fields - CxPopUpEnable, CxPopDownEnable,
> FastC4ExitEnable
> +// Revision 3: Extended VidCpuid to 32 bits for extended CPUID support
> (Penryn)
> +// Revision 4: Added support for extended C6 residency enabling
> +//
> +#define PPM_PLATFORM_POLICY_PROTOCOL_REVISION     1
> +#define PPM_PLATFORM_POLICY_PROTOCOL_REVISION_2   2
> +#define PPM_PLATFORM_POLICY_PROTOCOL_REVISION_3   3
> +#define PPM_PLATFORM_POLICY_PROTOCOL_REVISION_4   4
> +
> +//
> +// Define maximum number of custom VID states supported
> +//
> +#ifndef MAX_CUSTOM_VID_TABLE_STATES
> +#define MAX_CUSTOM_VID_TABLE_STATES               6
> +#endif
> +//
> +// Custom VID table
> +//
> +typedef struct {
> +  UINT8   VidNumber;
> +  UINT32  VidCpuid;
> +  UINT16  VidMaxRatio;
> +  UINT16  VidMaxVid;
> +  UINT16  StateRatio[MAX_CUSTOM_VID_TABLE_STATES];
> +  UINT16  StateVid[MAX_CUSTOM_VID_TABLE_STATES];
> +} PPM_CUSTOM_VID_TABLE;
> +
> +//
> +// PPM functional enables
> +//
> +typedef struct {
> +  UINT8   EnableGv                   :1; // 0: Disabled; 1: Enabled
> +  UINT8   EnableCx                   :1;
> +  UINT8   EnableCxe                  :1;
> +  UINT8   EnableC4                   :1;
> +  UINT8   EnableC6                   :1;
> +  UINT8   EnableC7                   :1;
> +  UINT8   EnableTm                   :1;
> +  UINT8   Reserve00                  :1;
> +  UINT8   Reserve01                  :1;
> +  UINT8   EnableTurboMode            :1;
> +  UINT8   PowerLimit2                :1;
> +  UINT8   EnableProcHot              :1;
> +  UINT8   Reserve02                  :1;
> +  UINT8   EnableCMP                  :1;
> +  UINT8   TStatesEnable              :1;
> +  UINT8   Reserve03                  :1;
> +  UINT8   Reserve04                  ;
> +
> +} PPM_FUNCTION_ENABLES;
> +
> +
> +//
> +// PPM Turbo settings
> +//
> +typedef struct _PPM_TURBO_SETTINGS {
> +  UINT16  PowerLimit1;
> +  UINT32  PowerLimit1Time;
> +  UINT16  PowerLimit2;
> +  UINT8   TurboPowerLimitLock;
> +} PPM_TURBO_SETTINGS;
> +
> +//
> +// Platform Policy
> +//
> +struct _PPM_PLATFORM_POLICY_PROTOCOL {
> +  UINT8                                 Revision;
> +  PPM_FUNCTION_ENABLES                  FunctionEnables;
> +  PPM_CUSTOM_VID_TABLE                  CustomVidTable;
> +  PPM_TURBO_SETTINGS                    TurboSettings;
> +
> +  UINT8                                 Reserve00;
> +  UINT8                                 Reserve01;
> +  UINT8                                 Reserve02;
> +  UINT8                                 Reserve03;
> +  UINT8                                 Reserve04;
> +  UINT8                                 Reserve05;
> +  UINT8                                 Reserve06;
> +
> +  UINT8                                 S3RestoreMsrSwSmiNumber;
> +  UINT8                                 Reserve07;
> +  UINT32                                Reserve08;
> +  UINT8                                 Reserve09;
> +  //
> +  // Primary and Secondary Plane Current Limits
> +  //
> +  UINT16                                Reserve10;
> +  UINT8                                 Reserve11;
> +};
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Types.
> h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Types.
> h
> new file mode 100644
> index 0000000000..0df6a6d193
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Types.
> h
> @@ -0,0 +1,55 @@
> +/*++
> +
> +Copyright (c) 1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +    Types.h
> +
> +Abstract:
> +
> +    This file include all the external data types.
> +
> +--*/
> +
> +#ifndef _TYPES_H_
> +#define _TYPES_H_
> +
> +
> +
> +//
> +// Modifiers to abstract standard types to aid in debug of problems
> +//
> +#define CONST     const
> +#define STATIC    static
> +#define VOID      void
> +#define VOLATILE  volatile
> +
> +//
> +// Constants. They may exist in other build structures, so #ifndef them.
> +//
> +#ifndef TRUE
> +#define TRUE  ((BOOLEAN) 1 == 1)
> +#endif
> +
> +#ifndef FALSE
> +#define FALSE ((BOOLEAN) 0 == 1)
> +#endif
> +
> +#ifndef NULL
> +#define NULL  ((VOID *) 0)
> +#endif
> +
> +typedef UINT32 STATUS;
> +#define SUCCESS 0
> +#define FAILURE 0xFFFFFFFF
> +
> +#ifndef MRC_DEADLOOP
> +#define MRC_DEADLOOP()    while (TRUE)
> +#endif
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/PowerManagementAcpiTables.inf
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/PowerManagementAcpiTables.inf
> new file mode 100644
> index 0000000000..021b95fa61
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/PowerManagementAcpiTables.inf
> @@ -0,0 +1,39 @@
> +#
> +#/*++
> +#
> +#Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +#Module Name:
> +#
> +#  PowerManagementAcpiTables.inf
> +#
> +#Abstract:
> +#
> +#  Component description file for the ACPI tables
> +#
> +#--*/
> +
> +[defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = PowerManagementAcpiTables2
> +  FILE_GUID                      = 161BE597-E9C5-49DB-AE50-C462AB54EEDA
> +  MODULE_TYPE                    = USER_DEFINED
> +  VERSION_STRING                 = 1.0
> +  EDK_RELEASE_VERSION            = 0x00020000
> +  EFI_SPECIFICATION_VERSION      = 0x00020000
> +
> +
> +[sources.common]
> +  Ssdt/Cpu0Cst.asl
> +  Ssdt/Cpu0Ist.asl
> +  Ssdt/Cpu0Tst.asl
> +  Ssdt/ApCst.asl
> +  Ssdt/ApIst.asl
> +  Ssdt/ApTst.asl
> +  Ssdt/CpuPm.asl
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/Ssdt/ApCst.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/Ssdt/ApCst.asl
> new file mode 100644
> index 0000000000..6aa130b115
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/Ssdt/ApCst.asl
> @@ -0,0 +1,110 @@
> +/*-----------------------------------------------------------------------------
> +-------------------------------------------------------------------------------
> +
> +
> + Intel Silvermont Processor Power Management BIOS Reference Code
> +
> + Copyright (c) 2006 - 2014, Intel Corporation
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> + Filename:      CPU1CST.ASL
> +
> + Revision:      Refer to Readme
> +
> + Date:          Refer to Readme
> +
> +--------------------------------------------------------------------------------
> +-------------------------------------------------------------------------------
> +
> + This Processor Power Management BIOS Source Code is furnished under
> license
> + and may only be used or copied in accordance with the terms of the license.
> + The information in this document is furnished for informational use only, is
> + subject to change without notice, and should not be construed as a
> commitment
> + by Intel Corporation. Intel Corporation assumes no responsibility or liability
> + for any errors or inaccuracies that may appear in this document or any
> + software that may be provided in association with this document.
> +
> + Except as permitted by such license, no part of this document may be
> + reproduced, stored in a retrieval system, or transmitted in any form or by
> + any means without the express written consent of Intel Corporation.
> +
> + WARNING: You are authorized and licensed to install and use this BIOS
> code
> + ONLY on an IST PC. This utility may damage any system that does not
> + meet these requirements.
> +
> +        An IST PC is a computer which
> +        (1) Is capable of seamlessly and automatically transitioning among
> +        multiple performance states (potentially operating at different
> +        efficiency ratings) based upon power source changes, END user
> +        preference, processor performance demand, and thermal conditions;
> and
> +        (2) Includes an Intel Pentium II processors, Intel Pentium III
> +        processor, Mobile Intel Pentium III Processor-M, Mobile Intel Pentium 4
> +        Processor-M, Intel Pentium M Processor, or any other future Intel
> +        processors that incorporates the capability to transition between
> +        different performance states by altering some, or any combination of,
> +        the following processor attributes: core voltage, core frequency, bus
> +        frequency, number of processor cores available, or any other attribute
> +        that changes the efficiency (instructions/unit time-power) at which the
> +        processor operates.
> +
> +-------------------------------------------------------------------------------
> +-------------------------------------------------------------------------------
> +
> +NOTES:
> +        (1) <TODO> - IF the trap range and port definitions do not match those
> +        specified by this reference code, this file must be modified IAW the
> +        individual implmentation.
> +
> +--------------------------------------------------------------------------------
> +------------------------------------------------------------------------------*/
> +
> +
> +DefinitionBlock (
> +        "APCST.aml",
> +        "SSDT",
> +        1,
> +        "PmRef",
> +        "ApCst",
> +        0x3000
> +        )
> +{
> +External(\_PR.CPU1, DeviceObj)
> +External(\_PR.CPU2, DeviceObj)
> +External(\_PR.CPU3, DeviceObj)
> +External(\_PR.CPU0._CST)
> +
> +        Scope(\_PR.CPU1)
> +        {
> +                Method(_CST,0)
> +                {
> +                        //
> +                        // Return P0's _CST object.
> +                        //
> +                        Return(\_PR.CPU0._CST)
> +                }
> +        }
> +
> +        Scope(\_PR.CPU2)
> +        {
> +                Method(_CST,0)
> +                {
> +                        //
> +                        // Return P0's _CST object.
> +                        //
> +                        Return(\_PR.CPU0._CST)
> +                }
> +        }
> +
> +        Scope(\_PR.CPU3)
> +        {
> +                Method(_CST,0)
> +                {
> +                        //
> +                        // Return P0's _CST object.
> +                        //
> +                        Return(\_PR.CPU0._CST)
> +                }
> +        }
> +}  // End of Definition Block
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/Ssdt/ApIst.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/Ssdt/ApIst.asl
> new file mode 100644
> index 0000000000..ffffe9a8fc
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/Ssdt/ApIst.asl
> @@ -0,0 +1,166 @@
> +/*-----------------------------------------------------------------------------
> +-------------------------------------------------------------------------------
> +
> +
> + Intel Silvermont Processor Power Management BIOS Reference Code
> +
> + Copyright (c) 2006 - 2014, Intel Corporation
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> + Filename:      APIST.ASL
> +
> + Revision:      Refer to Readme
> +
> + Date:          Refer to Readme
> +
> +--------------------------------------------------------------------------------
> +-------------------------------------------------------------------------------
> +
> + This Processor Power Management BIOS Source Code is furnished under
> license
> + and may only be used or copied in accordance with the terms of the license.
> + The information in this document is furnished for informational use only, is
> + subject to change without notice, and should not be construed as a
> commitment
> + by Intel Corporation. Intel Corporation assumes no responsibility or liability
> + for any errors or inaccuracies that may appear in this document or any
> + software that may be provided in association with this document.
> +
> + Except as permitted by such license, no part of this document may be
> + reproduced, stored in a retrieval system, or transmitted in any form or by
> + any means without the express written consent of Intel Corporation.
> +
> + WARNING: You are authorized and licensed to install and use this BIOS
> code
> + ONLY on an IST PC. This utility may damage any system that does not
> + meet these requirements.
> +
> +        An IST PC is a computer which
> +        (1) Is capable of seamlessly and automatically transitioning among
> +        multiple performance states (potentially operating at different
> +        efficiency ratings) based upon power source changes, END user
> +        preference, processor performance demand, and thermal conditions;
> and
> +        (2) Includes an Intel Pentium II processors, Intel Pentium III
> +        processor, Mobile Intel Pentium III Processor-M, Mobile Intel Pentium 4
> +        Processor-M, Intel Pentium M Processor, or any other future Intel
> +        processors that incorporates the capability to transition between
> +        different performance states by altering some, or any combination of,
> +        the following processor attributes: core voltage, core frequency, bus
> +        frequency, number of processor cores available, or any other attribute
> +        that changes the efficiency (instructions/unit time-power) at which the
> +        processor operates.
> +
> +-------------------------------------------------------------------------------
> +-------------------------------------------------------------------------------
> +
> +NOTES:
> +        (1) <TODO> - IF the trap range and port definitions do not match those
> +        specified by this reference code, this file must be modified IAW the
> +        individual implmentation.
> +
> +--------------------------------------------------------------------------------
> +------------------------------------------------------------------------------*/
> +
> +
> +DefinitionBlock (
> +        "APIST.aml",
> +        "SSDT",
> +        1,
> +        "PmRef",
> +        "ApIst",
> +        0x3000
> +        )
> +{
> +        External(\_PR.CPU0._PSS, MethodObj)
> +        External(\_PR.CPU0._PCT, MethodObj)
> +        External(\_PR.CPU0._PPC, IntObj)
> +        External(\_PR.CPU0._PSD, MethodObj)
> +        External(\_PR.CPU1, DeviceObj)
> +        External(\_PR.CPU2, DeviceObj)
> +        External(\_PR.CPU3, DeviceObj)
> +        External (CFGD)
> +        External (PDC0)
> +
> +        Scope(\_PR.CPU1)
> +        {
> +                Method(_PPC,0)
> +                {
> +                        Return(\_PR.CPU0._PPC)  // Return P0 _PPC value.
> +                }
> +
> +                Method(_PCT,0)
> +                {
> +                        Return(\_PR.CPU0._PCT)  // Return P0 _PCT.
> +                }
> +
> +                Method(_PSS,0)
> +                {
> +                        //Return the same table as CPU0 for CMP cases.
> +                        Return(\_PR.CPU0._PSS)
> +                }
> +
> +                // The _PSD object provides information to the OSPM related
> +                // to P-State coordination between processors in a multi-processor
> +                // configurations.
> +                //
> +                Method(_PSD,0)
> +                {
> +                        Return(\_PR.CPU0._PSD)  // Return P0 _PSD.
> +                }
> +        }
> +
> +        Scope(\_PR.CPU2)
> +        {
> +                Method(_PPC,0)
> +                {
> +                        Return(\_PR.CPU0._PPC)  // Return P0 _PPC value.
> +                }
> +
> +                Method(_PCT,0)
> +                {
> +                        Return(\_PR.CPU0._PCT)  // Return P0 _PCT.
> +                }
> +
> +                Method(_PSS,0)
> +                {
> +                        //Return the same table as CPU0 for CMP cases.
> +                        Return(\_PR.CPU0._PSS)
> +                }
> +
> +                // The _PSD object provides information to the OSPM related
> +                // to P-State coordination between processors in a multi-processor
> +                // configurations.
> +                //
> +                Method(_PSD,0)
> +                {
> +                        Return(\_PR.CPU0._PSD)  // Return P0 _PSD.
> +                }
> +        }
> +
> +        Scope(\_PR.CPU3)
> +        {
> +                Method(_PPC,0)
> +                {
> +                        Return(\_PR.CPU0._PPC)  // Return P0 _PPC value.
> +                }
> +
> +                Method(_PCT,0)
> +                {
> +                        Return(\_PR.CPU0._PCT)  // Return P0 _PCT.
> +                }
> +
> +                Method(_PSS,0)
> +                {
> +                        //Return the same table as CPU0 for CMP cases.
> +                        Return(\_PR.CPU0._PSS)
> +                }
> +
> +                // The _PSD object provides information to the OSPM related
> +                // to P-State coordination between processors in a multi-processor
> +                // configurations.
> +                //
> +                Method(_PSD,0)
> +                {
> +                        Return(\_PR.CPU0._PSD)  // Return P0 _PSD.
> +                }
> +        }
> +} // End of Definition Block
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/Ssdt/ApTst.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/Ssdt/ApTst.asl
> new file mode 100644
> index 0000000000..760eb3c108
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/Ssdt/ApTst.asl
> @@ -0,0 +1,262 @@
> +/*-----------------------------------------------------------------------------
> +-------------------------------------------------------------------------------
> +
> +
> + Intel Platform Processor Power Management BIOS Reference Code
> +
> + Copyright (c) 2007  - 2014, Intel Corporation
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> + Filename:      APTST.ASL
> +
> + Revision:      Refer to Readme
> +
> + Date:          Refer to Readme
> +
> +--------------------------------------------------------------------------------
> +-------------------------------------------------------------------------------
> +
> + This Processor Power Management BIOS Source Code is furnished under
> license
> + and may only be used or copied in accordance with the terms of the license.
> + The information in this document is furnished for informational use only, is
> + subject to change without notice, and should not be construed as a
> commitment
> + by Intel Corporation. Intel Corporation assumes no responsibility or liability
> + for any errors or inaccuracies that may appear in this document or any
> + software that may be provided in association with this document.
> +
> + Except as permitted by such license, no part of this document may be
> + reproduced, stored in a retrieval system, or transmitted in any form or by
> + any means without the express written consent of Intel Corporation.
> +
> + WARNING: You are authorized and licensed to install and use this BIOS
> code
> + ONLY on an IST PC. This utility may damage any system that does not
> + meet these requirements.
> +
> +        An IST PC is a computer which
> +        (1) Is capable of seamlessly and automatically transitioning among
> +        multiple performance states (potentially operating at different
> +        efficiency ratings) based upon power source changes, END user
> +        preference, processor performance demand, and thermal conditions;
> and
> +        (2) Includes an Intel Pentium II processors, Intel Pentium III
> +        processor, Mobile Intel Pentium III Processor-M, Mobile Intel Pentium 4
> +        Processor-M, Intel Pentium M Processor, or any other future Intel
> +        processors that incorporates the capability to transition between
> +        different performance states by altering some, or any combination of,
> +        the following processor attributes: core voltage, core frequency, bus
> +        frequency, number of processor cores available, or any other attribute
> +        that changes the efficiency (instructions/unit time-power) at which the
> +        processor operates.
> +
> +-------------------------------------------------------------------------------
> +-------------------------------------------------------------------------------
> +
> +NOTES:
> +        (1) <TODO> - IF the trap range and port definitions do not match those
> +        specified by this reference code, this file must be modified IAW the
> +        individual implmentation.
> +
> +--------------------------------------------------------------------------------
> +------------------------------------------------------------------------------*/
> +
> +
> +DefinitionBlock(
> +        "APTST.aml",
> +        "SSDT",
> +        0x01,
> +        "PmRef",
> +        "ApTst",
> +        0x3000
> +        )
> +{
> +        External(\_PR.CPU1, DeviceObj)
> +        External(\_PR.CPU2, DeviceObj)
> +        External(\_PR.CPU3, DeviceObj)
> +        External(\_PR.CPU0._PTC)
> +        External(\_PR.CPU0._TSS)
> +        External(PDC0)
> +        External(CFGD)
> +        External(MPEN)
> +
> +        Scope(\_PR.CPU1)
> +        {
> +                Name(_TPC, 0)   // All T-States are available
> +
> +                //
> +                // T-State Control/Status interface
> +                //
> +                Method(_PTC, 0)
> +                {
> +                        Return(\_PR.CPU0._PTC)
> +                }
> +
> +                Method(_TSS, 0)
> +                {
> +                        Return(\_PR.CPU0._TSS)
> +                }
> +
> +                //
> +                // T-State Dependency
> +                //
> +                Method(_TSD, 0)
> +                {
> +                        //
> +                        // IF four cores are supported/enabled && !(direct access to
> MSR)
> +                        //    Report 4 processors and SW_ANY as the coordination
> +                        // IF two cores are supported/enabled && !(direct access to
> MSR)
> +                        //    Report 2 processors and SW_ANY as the coordination type
> +                        //  ELSE
> +                        //    Report 1 processor and SW_ALL as the coordination type
> (domain 1)
> +                        //
> +                        //  CFGD[23] = Four cores enabled
> +                        //  CFGD[24] = Two or more cores enabled
> +                        //  PDCx[2] = OSPM is capable of direct access to On
> +                        //              Demand throttling MSR
> +                        //
> +
> +                If(LNot(And(PDC0,4)))
> +                {
> +                                Return(Package(){       // SW_ANY
> +                                        Package(){
> +                                                5,                // # entries.
> +                                                0,                // Revision.
> +                                                0,                // Domain #.
> +                                                0xFD,           // Coord Type- SW_ANY
> +                                                MPEN          // # processors.
> +                                        }
> +                                })
> +                }
> +                Return(Package(){               // SW_ALL
> +                        Package(){
> +                                5,                        // # entries.
> +                                0,                        // Revision.
> +                                1,                        // Domain #.
> +                                0xFC,                   // Coord Type- SW_ALL
> +                                1               // # processors.
> +                        }
> +                })
> +                }
> +        }  // End of CPU1
> +
> +        Scope(\_PR.CPU2)
> +        {
> +                Name(_TPC, 0)   // All T-States are available
> +
> +                //
> +                // T-State Control/Status interface
> +                //
> +                Method(_PTC, 0)
> +                {
> +                        Return(\_PR.CPU0._PTC)
> +                }
> +
> +                Method(_TSS, 0)
> +                {
> +                        Return(\_PR.CPU0._TSS)
> +                }
> +
> +                //
> +                // T-State Dependency
> +                //
> +                Method(_TSD, 0)
> +                {
> +                        //
> +                        // IF four cores are supported/enabled && !(direct access to
> MSR)
> +                        //    Report 4 processors and SW_ANY as the coordination
> +                        // IF two cores are supported/enabled && !(direct access to
> MSR)
> +                        //    Report 2 processors and SW_ANY as the coordination type
> +                        //  ELSE
> +                        //    Report 1 processor and SW_ALL as the coordination type
> (domain 1)
> +                        //
> +                        //  CFGD[23] = Four cores enabled
> +                        //  CFGD[24] = Two or more cores enabled
> +                        //  PDCx[2] = OSPM is capable of direct access to On
> +                        //              Demand throttling MSR
> +                        //
> +
> +                If(LNot(And(PDC0,4)))
> +                {
> +                                Return(Package(){       // SW_ANY
> +                                        Package(){
> +                                                5,                // # entries.
> +                                                0,                // Revision.
> +                                                0,                // Domain #.
> +                                                0xFD,           // Coord Type- SW_ANY
> +                                                MPEN          // # processors.
> +                                        }
> +                                })
> +                }
> +                Return(Package(){               // SW_ALL
> +                        Package(){
> +                                5,                        // # entries.
> +                                0,                        // Revision.
> +                                1,                        // Domain #.
> +                                0xFC,                   // Coord Type- SW_ALL
> +                                1                // # processors.
> +                        }
> +                })
> +                }
> +        }  // End of CPU2
> +
> +        Scope(\_PR.CPU3)
> +        {
> +                Name(_TPC, 0)   // All T-States are available
> +
> +                //
> +                // T-State Control/Status interface
> +                //
> +                Method(_PTC, 0)
> +                {
> +                        Return(\_PR.CPU0._PTC)
> +                }
> +
> +                Method(_TSS, 0)
> +                {
> +                        Return(\_PR.CPU0._TSS)
> +                }
> +
> +                //
> +                // T-State Dependency
> +                //
> +                Method(_TSD, 0)
> +                {
> +                        //
> +                        // IF four cores are supported/enabled && !(direct access to
> MSR)
> +                        //    Report 4 processors and SW_ANY as the coordination
> +                        // IF two cores are supported/enabled && !(direct access to
> MSR)
> +                        //    Report 2 processors and SW_ANY as the coordination type
> +                        //  ELSE
> +                        //    Report 1 processor and SW_ALL as the coordination type
> (domain 1)
> +                        //
> +                        //  CFGD[23] = Four cores enabled
> +                        //  CFGD[24] = Two or more cores enabled
> +                        //  PDCx[2] = OSPM is capable of direct access to On
> +                        //              Demand throttling MSR
> +                        //
> +
> +                If(LNot(And(PDC0,4)))
> +                {
> +                                Return(Package(){       // SW_ANY
> +                                        Package(){
> +                                                5,                // # entries.
> +                                                0,                // Revision.
> +                                                0,                // Domain #.
> +                                                0xFD,           // Coord Type- SW_ANY
> +                                                MPEN          // # processors.
> +                                        }
> +                                })
> +                }
> +                Return(Package(){               // SW_ALL
> +                        Package(){
> +                                5,                        // # entries.
> +                                0,                        // Revision.
> +                                1,                        // Domain #.
> +                                0xFC,                   // Coord Type- SW_ALL
> +                                1                // # processors.
> +                        }
> +                })
> +                }
> +        }  // End of CPU3
> +} // End of Definition Block
> +
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/Ssdt/Cpu0Cst.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/Ssdt/Cpu0Cst.asl
> new file mode 100644
> index 0000000000..76c774a44d
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/Ssdt/Cpu0Cst.asl
> @@ -0,0 +1,274 @@
> +
> +/*-----------------------------------------------------------------------------
> +-------------------------------------------------------------------------------
> +
> +
> + Intel Silvermont Processor Power Management BIOS Reference Code
> +
> + Copyright (c) 2006 - 2014, Intel Corporation
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> + Filename:    CPU0CST.ASL
> +
> + Revision:    Refer to Readme
> +
> + Date:        Refer to Readme
> +
> +--------------------------------------------------------------------------------
> +-------------------------------------------------------------------------------
> +
> + This Processor Power Management BIOS Source Code is furnished under
> license
> + and may only be used or copied in accordance with the terms of the license.
> + The information in this document is furnished for informational use only, is
> + subject to change without notice, and should not be construed as a
> commitment
> + by Intel Corporation. Intel Corporation assumes no responsibility or liability
> + for any errors or inaccuracies that may appear in this document or any
> + software that may be provided in association with this document.
> +
> + Except as permitted by such license, no part of this document may be
> + reproduced, stored in a retrieval system, or transmitted in any form or by
> + any means without the express written consent of Intel Corporation.
> +
> + WARNING: You are authorized and licensed to install and use this BIOS
> code
> + ONLY on an IST PC. This utility may damage any system that does not
> + meet these requirements.
> +
> +    An IST PC is a computer which
> +    (1) Is capable of seamlessly and automatically transitioning among
> +    multiple performance states (potentially operating at different
> +    efficiency ratings) based upon power source changes, END user
> +    preference, processor performance demand, and thermal conditions; and
> +    (2) Includes an Intel Pentium II processors, Intel Pentium III
> +    processor, Mobile Intel Pentium III Processor-M, Mobile Intel Pentium 4
> +    Processor-M, Intel Pentium M Processor, or any other future Intel
> +    processors that incorporates the capability to transition between
> +    different performance states by altering some, or any combination of,
> +    the following processor attributes: core voltage, core frequency, bus
> +    frequency, number of processor cores available, or any other attribute
> +    that changes the efficiency (instructions/unit time-power) at which the
> +    processor operates.
> +
> +-------------------------------------------------------------------------------
> +-------------------------------------------------------------------------------
> +
> +NOTES:
> +    (1) <TODO> - IF the trap range and port definitions do not match those
> +    specified by this reference code, this file must be modified IAW the
> +    individual implmentation.
> +
> +--------------------------------------------------------------------------------
> +------------------------------------------------------------------------------*/
> +
> +
> +DefinitionBlock (
> +    "CPU0CST.aml",
> +    "SSDT",
> +    1,
> +    "PmRef",
> +    "Cpu0Cst",
> +    0x3001
> +    )
> +{
> +    External(\_PR.CPU0, DeviceObj)
> +    External(PWRS)
> +    External(CFGD)
> +    External(PDC0)
> +
> +    Scope(\_PR.CPU0)
> +    {
> +        OperationRegion (DEB0, SystemIO, 0x80, 1)    //DBG
> +        Field (DEB0, ByteAcc,NoLock,Preserve)        //DBG
> +        { DBG8, 8,}                    //DBG
> +
> +        Method (_CST, 0)
> +        {
> +            Store(0x60,DBG8) //DBG
> +
> +            // IF CMP is supported, but independent C-States beyond C1 are
> +            // not supported; return C1 Halt and rely on BIOS based software
> +            // coordination
> +            //
> +            //   CFGD[24] = CMP support
> +            //   PDCx[4]  = 0 - OS does not support ind. C2/C3 in MP systems
> +            //
> +            // Note:  SMI will be generated when both processor enter the
> +            // Halt state.
> +            //
> +            If(LAnd(And(CFGD,0x01000000), LNot(And(PDC0,0x10))))
> +            {
> +                Store(0x61,DBG8) //DBG
> +                Return(Package() {
> +                    1,
> +                    Package()
> +                    {   // C1 halt, but with BIOS coordination
> +                        ResourceTemplate(){Register(FFixedHW, 0, 0, 0)},
> +                        1,
> +                        157,
> +                        1000
> +                    }
> +                })
> +            }
> +
> +            // IF MWAIT extensions are supported, use them.
> +            //
> +            //  IF C6 capable/enabled AND Battery
> +            //        Report MWAIT C1, C2, C6 w/ BM_STS avoidance
> +            //  ELSE IF C4 capable/enabled AND Battery
> +            //        Report MWAIT C1, C2, C4 w/ BM_STS avoidance
> +            //  ELSE IF C3 capable/enabled
> +            //      Report MWAIT C1, C2, C3 w/ BM_STS avoidance
> +            //  ELSE IF C2 capable/enabled
> +            //        Report MWAIT C1, C2
> +            //  ELSE
> +            //        Report MWAIT C1
> +            //
> +            //   CFGD[21] = 1 - MWAIT extensions supported
> +            //   CFGD[13] = 1 - C7  Capable/Enabled
> +            //   CFGD[12] = 1 - C6S Capable/Enabled
> +            //   CFGD[11] = 1 - C6  Capable/Enabled
> +            //   CFGD[7]  = 1 - C4  Capable/Enabled
> +            //   CFGD[5]  = 1 - C3  Capable/Enabled
> +            //   PDCx[9]  = 1 - OS  supports MWAIT extensions
> +            //   PDCx[8]  = 1 - OS  supports MWAIT for C1
> +            //            (Inferred from PDCx[9] = 1.)
> +            //   PDCx[4]  = 1 - OS supports independent C2/C3 in MP systems
> +            //    or
> +            //   NOT CMP  (Inferred from previous check.)
> +            //
> +            If(LAnd(And(CFGD, 0x200000), And(PDC0,0x200)))
> +            {
> +                //
> +                // <TODO> The implementor may wish to only report C1-C2
> +                // when on AC power.  In this case, the IF clause below can
> +                // be modified to something like:
> +                //
> +                // "If(LAnd(And(CFGD,0x200), LNot(PWRS)))"
> +                //
> +                // Which uses the power state of the system (PWRS) to
> +                // determine whether to allow deepers states.
> +                //
> +                //   IF C7 supported AND on battery
> +                //    report MWAIT C1, C6, C7
> +                //
> +                //   CFGD[13] = C7  Capable/Enabled
> +                //   CFGD[11] = C6  Capable/Enabled
> +                //
> +              If(LAnd(And(CFGD,0x2000),And(CFGD,0x40000000)))
> +                {
> +                    Store(0x77,DBG8) //DBG
> +                    Return( Package()
> +                    {
> +                        3,
> +                        Package()
> +                        {   // C1, MWAIT
> +                            ResourceTemplate(){Register(FFixedHW, 1, 2, 0x00, 1)},
> +                            1,
> +                            1,
> +                            1000
> +                        },
> +                        Package()
> +                        {
> +                            // C6, MWAIT Extension with Incremental L2 Shrink
> +                            // ResourceTemplate(){Register(FFixedHW, 1, 2, 0x50, 1)},
> +                            // C6, MWAIT Extension with No L2 Shrink
> +                            ResourceTemplate(){Register(FFixedHW, 1, 2, 0x51, 1)},
> +                            2,
> +                            500,
> +                            10
> +                        },
> +                        Package()
> +                        {
> +                            // C7, MWAIT Extension with Full L2 Shrink
> +                            ResourceTemplate(){Register(FFixedHW, 1, 2, 0x64, 1)},
> +                            3,
> +                            1500,   //PnP setting, 1.5 ms for worst-case exit latency
> +                            10
> +                        }
> +                    })
> +                }
> +
> +
> +             If(LAnd(And(CFGD,0x2000),LNot(And(CFGD,0x40000000))))
> +                {
> +                    Store(0x67,DBG8) //DBG
> +                    Return( Package()
> +                    {
> +                        3,
> +                        Package()
> +                        {   // C1, MWAIT
> +                            ResourceTemplate(){Register(FFixedHW, 1, 2, 0x00, 1)},
> +                            1,
> +                            1,
> +                            1000
> +                        },
> +                        Package()
> +                        {
> +                            // C6, MWAIT Extension with Incremental L2 Shrink
> +                            // ResourceTemplate(){Register(FFixedHW, 1, 2, 0x50, 1)},
> +                            // C6 = C6NS, MWAIT Extension with No L2 Shrink
> +                            ResourceTemplate(){Register(FFixedHW, 1, 2, 0x51, 1)},
> +                            2,
> +                            500,
> +                            10
> +                        },
> +                        Package()
> +                        {
> +
> +                            ResourceTemplate(){Register(FFixedHW, 1, 2, 0x52, 1)},
> +                            3,
> +                            1500,   //PnP setting, 1.5 ms for worst-case exit latency
> +                            10
> +                        }
> +                    })
> +                }
> +
> +                If(And(CFGD,0x800)) // Setup Max C-State = C6
> +                {
> +                    Store(0x76,DBG8) //DBG
> +                    Return( Package()
> +                    {
> +                        2,
> +                        Package()
> +                        {   // C1, MWAIT
> +                            ResourceTemplate(){Register(FFixedHW, 1, 2, 0x00, 1)},
> +                            1,
> +                            1,
> +                            1000
> +                        },
> +                        Package()
> +                        {
> +                            // C6, MWAIT Extension with Incremental L2 Shrink
> +                            // ResourceTemplate(){Register(FFixedHW, 1, 2, 0x50, 1)},
> +                            // C6, MWAIT Extension with No L2 Shrink
> +                            ResourceTemplate(){Register(FFixedHW, 1, 2, 0x51, 1)},
> +                            2,
> +                            500,
> +                            10
> +                        }
> +                    })
> +                }
> +                //
> +                // IF no deeper C-States are supported; report MWAIT C1.
> +                //
> +                Store(0x71,DBG8) //DBG
> +                Return(Package()
> +                {
> +                    1,
> +                    Package()
> +                    {   // C1, MWAIT
> +                        ResourceTemplate () {Register(FFixedHW, 1, 2, 0x00, 1)},
> +                        1,
> +                        1,
> +                        1000
> +                    }
> +                })
> +            }
> +
> +
> +        }
> +    }
> +}
> +
> +
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/Ssdt/Cpu0Ist.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/Ssdt/Cpu0Ist.asl
> new file mode 100644
> index 0000000000..07bdb85602
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/Ssdt/Cpu0Ist.asl
> @@ -0,0 +1,260 @@
> +/*-----------------------------------------------------------------------------
> +-------------------------------------------------------------------------------
> +
> +
> + Intel Silvermont Processor Power Management BIOS Reference Code
> +
> + Copyright (c) 2006 - 2014, Intel Corporation
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> + Filename:    CPU0IST.ASL
> +
> + Revision:    Refer to Readme
> +
> + Date:        Refer to Readme
> +
> +--------------------------------------------------------------------------------
> +-------------------------------------------------------------------------------
> +
> + This Processor Power Management BIOS Source Code is furnished under
> license
> + and may only be used or copied in accordance with the terms of the license.
> + The information in this document is furnished for informational use only, is
> + subject to change without notice, and should not be construed as a
> commitment
> + by Intel Corporation. Intel Corporation assumes no responsibility or liability
> + for any errors or inaccuracies that may appear in this document or any
> + software that may be provided in association with this document.
> +
> + Except as permitted by such license, no part of this document may be
> + reproduced, stored in a retrieval system, or transmitted in any form or by
> + any means without the express written consent of Intel Corporation.
> +
> + WARNING: You are authorized and licensed to install and use this BIOS
> code
> + ONLY on an IST PC. This utility may damage any system that does not
> + meet these requirements.
> +
> +    An IST PC is a computer which
> +    (1) Is capable of seamlessly and automatically transitioning among
> +    multiple performance states (potentially operating at different
> +    efficiency ratings) based upon power source changes, END user
> +    preference, processor performance demand, and thermal conditions; and
> +    (2) Includes an Intel Pentium II processors, Intel Pentium III
> +    processor, Mobile Intel Pentium III Processor-M, Mobile Intel Pentium 4
> +    Processor-M, Intel Pentium M Processor, or any other future Intel
> +    processors that incorporates the capability to transition between
> +    different performance states by altering some, or any combination of,
> +    the following processor attributes: core voltage, core frequency, bus
> +    frequency, number of processor cores available, or any other attribute
> +    that changes the efficiency (instructions/unit time-power) at which the
> +    processor operates.
> +
> +-------------------------------------------------------------------------------
> +-------------------------------------------------------------------------------
> +
> +NOTES:
> +    (1) <TODO> - IF the trap range and port definitions do not match those
> +    specified by this reference code, this file must be modified IAW the
> +    individual implmentation.
> +
> +--------------------------------------------------------------------------------
> +------------------------------------------------------------------------------*/
> +
> +
> +DefinitionBlock (
> +    "CPU0IST.aml",
> +    "SSDT",
> +    0x01,
> +    "PmRef",
> +    "Cpu0Ist",
> +    0x3000
> +    )
> +{
> +    External (\_PR.CPU0, DeviceObj)
> +    External (PDC0)
> +    External (CFGD)
> +
> +    Scope(\_PR.CPU0)
> +    {
> +        //OperationRegion (DEB0, SystemIO, 0x80, 1)    //DBG
> +        //Field (DEB0, ByteAcc,NoLock,Preserve)        //DBG
> +        //{ DBG8, 8,}                                  //DBG
> +
> +        Name(_PPC, 0)        // Initialize as All States Available.
> +
> +        // NOTE:  For CMP systems; this table is not loaded unless
> +        //      the required driver support is present.
> +        //      So, we do not check for those cases here.
> +        //
> +        //   CFGD[0] = GV3 Capable/Enabled
> +        //   PDCx[0]  = OS Capable of Hardware P-State control
> +        //
> +        Method(_PCT,0)
> +        {
> +            If(LAnd(And(CFGD,0x0001), And(PDC0,0x0001)))
> +            {
> +                //Store(0xA0,DBG8) //DBG
> +                Return(Package()    // Native Mode
> +                {
> +                    ResourceTemplate(){Register(FfixedHW, 0, 0, 0)},
> +                    ResourceTemplate(){Register(FfixedHW, 0, 0, 0)}
> +                })
> +            }
> +            // @NOTE: IO Trap is not supported. Therefore should not expose any
> IO interface for _PCT
> +            // For all other cases, report control through the
> +            // SMI interface.  (The port used for SMM control is fixed up
> +            // by the initialization code.)
> +            //
> +            Return(Package()        // SMM Mode
> +            {
> +               ResourceTemplate(){Register(FfixedHW, 0, 0, 0)},
> +               ResourceTemplate(){Register(FfixedHW, 0, 0, 0)}
> +            })
> +        }
> +
> +
> +        // NOTE:  For CMP systems; this table is not loaded if MP
> +        //      driver support is not present or P-State are disabled.
> +        //
> +        Method(_PSS,0)
> +        {
> +            //
> +            // Report NSPP if:
> +            //   (1) GV3 capable (Not checked, see above.)
> +            //   (2) Driver support direct hardware control
> +            //   (3) MP driver support present (Not checked, see above.)
> +            // else;
> +            //   Report SPSS
> +            //
> +            //   PDCx[0]  = OS Capable of Hardware P-State control
> +            //
> +            If(And(PDC0,0x0001)){
> +                //Store(0xB0,DBG8) //DBG
> +                Return(NPSS)
> +            }
> +            //Store(0xBF,DBG8) //DBG
> +            // Otherwise, report SMM mode
> +            //
> +            Return(SPSS)
> +
> +        }
> +
> +        Name(SPSS,Package()
> +        {
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000}
> +        })
> +
> +        Name(NPSS,Package()
> +        {
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000},
> +            Package(){0x80000000, 0x80000000, 0x80000000, 0x80000000,
> 0x80000000, 0x80000000}
> +        })
> +
> +        // The _PSD object provides information to the OSPM related
> +        // to P-State coordination between processors in a multi-processor
> +        // configurations.
> +        //
> +        Method(_PSD,0)
> +        {
> +            //
> +            // IF CMP is supported/enabled
> +            //   IF quad core processor
> +            //     IF PDC[11]
> +            //         Report 4 processors and HW_ALL as the coordination type
> +            //     ELSE
> +            //         Report 4 processors and SW_ALL as the coordination type
> +            //   ELSE
> +            //     IF PDC[11]
> +            //         Report 2 processors and HW_ALL as the coordination type
> +            //     ELSE
> +            //         Report 2 processors and SW_ALL as the coordination type
> +            // ELSE
> +            //    Report 1 processor and SW_ALL as the coordination type
> +            //    (Domain 0)
> +            //
> +            //   CFGD[24] = Two or more cores enabled
> +            //   CFGD[23] = Four cores enabled
> +            //   PDCx[11] = Hardware coordination with hardware feedback
> +            //
> +
> +            If(And(CFGD,0x1000000))    // CMP Enabled.
> +            {
> +              If(And(CFGD,0x800000))    // 2 or 4 process.
> +                {
> +                  If(And(PDC0,0x0800))
> +                  {
> +                      Return(Package(){    // HW_ALL
> +                        Package(){
> +                            5,              // # entries.
> +                            0,              // Revision.
> +                            0,              // Domain #.
> +                            0xFE,           // Coord Type- HW_ALL.
> +                            4               // # processors.
> +                        }
> +                      })
> +                  } // If(And(PDC0,0x0800))
> +                   Return(Package(){        // SW_ALL
> +                     Package(){
> +                        5,                  // # entries.
> +                        0,                  // Revision.
> +                        0,                  // Domain #.
> +                        0xFC,               // Coord Type- SW_ALL.
> +                        4                   // # processors.
> +                     }
> +                    })
> +                } else {
> +                  Return(Package(){        // HW_ALL
> +                      Package(){
> +                          5,                  // # entries.
> +                          0,                  // Revision.
> +                          0,                  // Domain #.
> +                          0xFE,               // Coord Type- HW_ALL.
> +                          2                   // # processors.
> +                      }
> +                  })
> +                }
> +            }    // If(And(CFGD,0x1000000))    // CMP Enabled.
> +
> +            Return(Package(){              // SW_ALL
> +                Package(){
> +                    5,                        // # entries.
> +                    0,                        // Revision.
> +                    0,                        // Domain #.
> +                    0xFC,                     // Coord Type- SW_ALL.
> +                    1                         // # processors.
> +                }
> +            })
> +        } // Method(_PSD,0)
> +    } // Scope(\_PR.CPU0)
> +} // End of Definition Block
> +
> +
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/Ssdt/Cpu0Tst.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/Ssdt/Cpu0Tst.asl
> new file mode 100644
> index 0000000000..1d65b0dc0d
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/Ssdt/Cpu0Tst.asl
> @@ -0,0 +1,235 @@
> +/*-----------------------------------------------------------------------------
> +-------------------------------------------------------------------------------
> +
> +
> + Intel Silvermont Processor Power Management BIOS Reference Code
> +
> + Copyright (c) 2006 - 2014, Intel Corporation
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> + Filename:      CPU0TST.ASL
> +
> + Revision:      Refer to Readme
> +
> + Date:          Refer to Readme
> +
> +--------------------------------------------------------------------------------
> +-------------------------------------------------------------------------------
> +
> + This Processor Power Management BIOS Source Code is furnished under
> license
> + and may only be used or copied in accordance with the terms of the license.
> + The information in this document is furnished for informational use only, is
> + subject to change without notice, and should not be construed as a
> commitment
> + by Intel Corporation. Intel Corporation assumes no responsibility or liability
> + for any errors or inaccuracies that may appear in this document or any
> + software that may be provided in association with this document.
> +
> + Except as permitted by such license, no part of this document may be
> + reproduced, stored in a retrieval system, or transmitted in any form or by
> + any means without the express written consent of Intel Corporation.
> +
> + WARNING: You are authorized and licensed to install and use this BIOS
> code
> + ONLY on an IST PC. This utility may damage any system that does not
> + meet these requirements.
> +
> +        An IST PC is a computer which
> +        (1) Is capable of seamlessly and automatically transitioning among
> +        multiple performance states (potentially operating at different
> +        efficiency ratings) based upon power source changes, end user
> +        preference, processor performance demand, and thermal conditions;
> and
> +        (2) Includes an Intel Pentium II processors, Intel Pentium III
> +        processor, Mobile Intel Pentium III Processor-M, Mobile Intel Pentium 4
> +        Processor-M, Intel Pentium M Processor, or any other future Intel
> +        processors that incorporates the capability to transition between
> +        different performance states by altering some, or any combination of,
> +        the following processor attributes: core voltage, core frequency, bus
> +        frequency, number of processor cores available, or any other attribute
> +        that changes the efficiency (instructions/unit time-power) at which the
> +        processor operates.
> +
> +-------------------------------------------------------------------------------
> +-------------------------------------------------------------------------------
> +
> +NOTES:
> +        (1) <TODO> - IF the trap range and port definitions do not match those
> +        specified by this reference code, this file must be modified IAW the
> +        individual implmentation.
> +
> +--------------------------------------------------------------------------------
> +------------------------------------------------------------------------------*/
> +
> +DefinitionBlock(
> +        "CPU0TST.aml",
> +        "SSDT",
> +        0x01,
> +        "PmRef",
> +        "Cpu0Tst",
> +        0x3000
> +        )
> +{
> +        External(\_PR.CPU0, DeviceObj)
> +        External(PDC0)
> +        External(CFGD)
> +        External(_PSS)
> +
> +        Scope(\_PR.CPU0)
> +        {
> +                Name(_TPC, 0)   // All T-States are available
> +
> +                //
> +                // T-State Control/Status interface
> +                //
> +                Method(_PTC, 0)
> +                {
> +                        //
> +                        // IF OSPM is capable of direct access to MSR
> +                        //    Report MSR interface
> +                        // ELSE
> +                        //    Report I/O interface
> +                        //
> +                        //  PDCx[2] = OSPM is capable of direct access to On
> +                        //              Demand throttling MSR
> +                        //
> +                        If(And(PDC0, 0x0004)) {
> +                                Return(Package() {
> +                                        ResourceTemplate(){Register(FFixedHW, 0, 0, 0)},
> +                                        ResourceTemplate(){Register(FFixedHW, 0, 0, 0)}
> +                                })
> +                        }
> +
> +                }
> +
> +                // _TSS package for I/O port based T-State control
> +                // "Power" fields are replaced with real values by the first
> +                // call of _TSS method.
> +                //
> +                Name(TSSI, Package() {
> +                                Package(){100, 1000, 0, 0x00, 0},
> +                                Package(){ 88,  875, 0, 0x0F, 0},
> +                                Package(){ 75,  750, 0, 0x0E, 0},
> +                                Package(){ 63,  625, 0, 0x0D, 0},
> +                                Package(){ 50,  500, 0, 0x0C, 0},
> +                                Package(){ 38,  375, 0, 0x0B, 0},
> +                                Package(){ 25,  250, 0, 0x0A, 0},
> +                                Package(){ 13,  125, 0, 0x09, 0}
> +                })
> +
> +                // _TSS package for MSR based T-State control
> +                // "Power" fields are replaced with real values by the first
> +                // call of _TSS method.
> +                //
> +                Name(TSSM, Package() {
> +                                Package(){100, 1000, 0, 0x00, 0},
> +                                Package(){ 88,  875, 0, 0x1E, 0},
> +                                Package(){ 75,  750, 0, 0x1C, 0},
> +                                Package(){ 63,  625, 0, 0x1A, 0},
> +                                Package(){ 50,  500, 0, 0x18, 0},
> +                                Package(){ 38,  375, 0, 0x16, 0},
> +                                Package(){ 25,  250, 0, 0x14, 0},
> +                                Package(){ 13,  125, 0, 0x12, 0}
> +                })
> +
> +                Name(TSSF, 0)   // Flag for TSSI/TSSM initialization
> +
> +                Method(_TSS, 0)
> +                {
> +                        // Update "Power" fields of TSSI/TSSM with the LFM
> +                        // power data IF _PSS is available
> +                        //
> +                        IF (LAnd(LNot(TSSF),CondRefOf(_PSS)))
> +                        {
> +                                Store(_PSS, Local0)
> +                                Store(SizeOf(Local0), Local1)   // _PSS size
> +                                Decrement(Local1)               // Index of LFM
> +                                Store(DerefOf(Index(DerefOf(Index(Local0,Local1)),1)),
> Local2)  // LFM Power
> +
> +                                Store(0, Local3)
> +                                While(LLess(Local3, SizeOf(TSSI)))
> +                                {
> +                                        Store(Divide(Multiply(Local2, Subtract(8, Local3)), 8),
> +                                              Local4)           // Power for this TSSI/TSSM entry
> +                                        Store(Local4,Index(DerefOf(Index(TSSI,Local3)),1))
> +                                        Store(Local4,Index(DerefOf(Index(TSSM,Local3)),1))
> +                                        Increment(Local3)
> +                                }
> +                                Store(Ones, TSSF)               // TSSI/TSSM are updated
> +                        }
> +                        //
> +                        // IF OSPM is capable of direct access to MSR
> +                        //    Report TSSM
> +                        // ELSE
> +                        //    Report TSSI
> +                        //
> +                        If(And(PDC0, 0x0004))
> +                        {
> +                                Return(TSSM)
> +                        }
> +                        Return(TSSI)
> +                }
> +
> +              Method(_TDL, 0)
> +              {
> +                Store ("Cpu0: _TDL Called", Debug)
> +                Name ( LFMI, 0)
> +                Store (SizeOf(TSSM), LFMI)
> +                Decrement(LFMI)    // Index of LFM entry in TSSM
> +                Return(LFMI)
> +              }
> +
> +                //
> +                // T-State Dependency
> +                //
> +                Method(_TSD, 0)
> +                {
> +                        //
> +      // IF four cores are supported/enabled && !(direct access to MSR)
> +                        //    Report 4 processors and SW_ANY as the coordination type
> +      // ELSE IF two cores are supported/enabled && !(direct access to MSR)
> +                        //    Report 2 processors and SW_ANY as the coordination type
> +                        // ELSE
> +                        //   Report 1 processor and SW_ALL as the coordination type
> +                        //
> +                        //  CFGD[23] = Four cores enabled
> +                        //  CFGD[24] = Two or more cores enabled
> +                        //  PDCx[2] = OSPM is capable of direct access to On
> +                        //              Demand throttling MSR
> +                        //
> +                        If(LAnd(And(CFGD,0x0800000),LNot(And(PDC0,4))))
> +                        {
> +                                Return(Package(){       // SW_ANY
> +                                        Package(){
> +                                                5,                // # entries.
> +                                                0,                // Revision.
> +                                                0,                // Domain #.
> +                                                0xFD,           // Coord Type- SW_ANY
> +                                                4                   // # processors.
> +                                        }
> +                                })
> +                        }
> +                        If(LAnd(And(CFGD,0x1000000),LNot(And(PDC0,4))))
> +                        {
> +                                Return(Package(){       // SW_ANY
> +                                        Package(){
> +                                                5,                // # entries.
> +                                                0,                // Revision.
> +                                                0,                // Domain #.
> +                                                0xFD,           // Coord Type- SW_ANY
> +                                                2                   // # processors.
> +                                        }
> +                                })
> +                        }
> +                        Return(Package(){               // SW_ALL
> +                                Package(){
> +                                        5,                        // # entries.
> +                                        0,                        // Revision.
> +                                        0,                        // Domain #.
> +                                        0xFC,                   // Coord Type- SW_ALL
> +                                        1                           // # processors.
> +                                }
> +                        })
> +                }
> +        }
> +} // End of Definition Block
> +
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/Ssdt/CpuPm.asl
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/Ssdt/CpuPm.asl
> new file mode 100644
> index 0000000000..3d30965c9f
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManage
> ment/AcpiTables/Ssdt/CpuPm.asl
> @@ -0,0 +1,793 @@
> +/*-----------------------------------------------------------------------------
> +
> +
> + Intel Silvermont Processor Power Management BIOS Reference Code
> +
> + Copyright (c) 2006 - 2014, Intel Corporation
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> + Filename:    CPUPM.ASL
> +
> + Revision:    Refer to Readme
> +
> + Date:        Refer to Readme
> +-------------------------------------------------------------------------------
> +
> + This Processor Power Management BIOS Source Code is furnished under
> license
> + and may only be used or copied in accordance with the terms of the license.
> + The information in this document is furnished for informational use only, is
> + subject to change without notice, and should not be construed as a
> commitment
> + by Intel Corporation. Intel Corporation assumes no responsibility or liability
> + for any errors or inaccuracies that may appear in this document or any
> + software that may be provided in association with this document.
> +
> + Except as permitted by such license, no part of this document may be
> + reproduced, stored in a retrieval system, or transmitted in any form or by
> + any means without the express written consent of Intel Corporation.
> +
> + WARNING: You are authorized and licensed to install and use this BIOS
> code
> + ONLY on an IST PC. This utility may damage any system that does not
> + meet these requirements.
> +
> +    An IST PC is a computer which
> +    (1) Is capable of seamlessly and automatically transitioning among
> +    multiple performance states (potentially operating at different
> +    efficiency ratings) based upon power source changes, END user
> +    preference, processor performance demand, and thermal conditions; and
> +    (2) Includes an Intel Pentium II processors, Intel Pentium III
> +    processor, Mobile Intel Pentium III Processor-M, Mobile Intel Pentium 4
> +    Processor-M, Intel Pentium M Processor, or any other future Intel
> +    processors that incorporates the capability to transition between
> +    different performance states by altering some, or any combination of,
> +    the following processor attributes: core voltage, core frequency, bus
> +    frequency, number of processor cores available, or any other attribute
> +    that changes the efficiency (instructions/unit time-power) at which the
> +    processor operates.
> +-------------------------------------------------------------------------------
> +
> +NOTES:
> +    (1) <TODO> - Except for the SSDT package, the objects in this ASL code
> +    may be moved to the DSDT. It is kept separate in this reference package
> +    for ease of distribution only.
> +------------------------------------------------------------------------------*/
> +
> +DefinitionBlock (
> +    "CPUPM.aml",
> +    "SSDT",
> +    0x01,
> +    "PmRef",
> +    "CpuPm",
> +    0x3000
> +    )
> +{
> +    External(\_PR.CPU0, DeviceObj)
> +    External(\_PR.CPU1, DeviceObj)
> +    External(\_PR.CPU2, DeviceObj)
> +    External(\_PR.CPU3, DeviceObj)
> +    External(SMIF)
> +
> +  Scope(\)
> +  {
> +
> +      // Package of pointers to SSDT's
> +      //
> +      // First column is SSDT name, used for debug only.
> +      // (First column must be EXACTLY eight characters.)
> +      // Second column is physical address.
> +      // Third column is table length.
> +      //
> +      // IF modifying this file, see warnings listed in ppminit.asm.
> +      //
> +      Name(SSDT,Package()
> +      {
> +          "CPU0IST ", 0x80000000, 0x80000000,
> +          "APIST   ", 0x80000000, 0x80000000,
> +          "CPU0CST ", 0x80000000, 0x80000000,
> +          "APCST   ", 0x80000000, 0x80000000
> +      })
> +
> +      //
> +      // Note:  See PpmBiosInit in PPMINIT.ASM for a definition of
> +      // the PpmFlags mirrored in CFGD.
> +      //
> +      Name(CFGD, 0x80000000)
> +
> +      Name(\PDC0,0x80000000)    // CPU0 _PDC Flags.
> +      Name(\PDC1,0x80000000)    // CPU1 _PDC Flags.
> +      Name(\PDC2,0x80000000)    // CPU2 _PDC Flags.
> +      Name(\PDC3,0x80000000)    // CPU3 _PDC Flags.
> +      Name(\SDTL,0x00)          // Loaded SSDT Flags.
> +  }
> +
> +  Scope(\_PR.CPU0)
> +  {
> +      //
> +      // Define handles for opregions (used by load.)
> +      //
> +      Name(HI0,0)        // Handle to CPU0IST
> +      Name(HC0,0)        // Handle to CPU0CST
> +
> +      Method(_PDC,1)
> +      {
> +          //
> +          // Check and extract the _PDC information.
> +          //
> +          Store(CPDC(Arg0), Local0)
> +          //
> +          // Save the capability information and load tables as needed.
> +          //
> +          GCAP(Local0)
> +          //
> +          // Return status.
> +          //
> +          //Return (Local0)
> +      }
> +
> +      Method(_OSC, 4)
> +      {
> +          //
> +          // Check and extract the _OSC information.
> +          //
> +          Store(COSC(Arg0, Arg1, Arg2, Arg3), Local0)
> +          //
> +          // Save the capability information and load tables as needed.
> +          //
> +          GCAP(Local0)
> +          //
> +          // Return status.
> +          //
> +          Return (Local0)
> +      }
> +
> +      //
> +      // Implement a generic Method to check _PDC information which may
> be called
> +      // by any of the processor scopes.  (The use of _PDC is deprecated in
> ACPI 3.
> +      // in favor of _OSC. However, for backwards compatibility, _PDC may be
> +      // implemented using _OSC as follows:)
> +      //
> +      Method(CPDC,1)
> +      {
> +          CreateDwordField (Arg0, 0, REVS)
> +          CreateDwordField (Arg0, 4, SIZE)
> +
> +          //
> +          // Local0 = Number of bytes for Arg0
> +          //
> +          Store (SizeOf (Arg0), Local0)
> +
> +          //
> +          // Local1 = Number of Capabilities bytes in Arg0
> +          //
> +          Store (Subtract (Local0, 8), Local1)
> +
> +          //
> +          // TEMP = Temporary field holding Capability DWORDs
> +          //
> +          CreateField (Arg0, 64, Multiply (Local1, 8), TEMP)
> +
> +          //
> +          // Create the Status (STAT) buffer with the first DWORD = 0
> +          // This is required as per ACPI 3.0 Spec which says the
> +          // first DWORD is used to return errors defined by _OSC.
> +          //
> +          Name (STS0, Buffer () {0x00, 0x00, 0x00, 0x00})
> +
> +          //
> +          // Concatenate the _PDC capabilities bytes to the STS0 Buffer
> +          // and store them in a local variable for calling OSC
> +          //
> +          Concatenate (STS0, TEMP, Local2)
> +
> +          Return(COSC (ToUUID("4077A616-290C-47BE-9EBD-D87058713953"),
> REVS, SIZE, Local2))
> +      }
> +
> +      //
> +      // Implement a generic Method to check _OSC information which may
> be called
> +      // by any of the processor scopes.
> +      //
> +      Method(COSC, 4)
> +      {
> +          //
> +          // Point to Status DWORD in the Arg3 buffer (STATUS)
> +          //
> +          CreateDWordField(Arg3, 0, STS0)
> +          //
> +          // Point to Caps DWORDs of the Arg3 buffer (CAPABILITIES)
> +          //
> +          CreateDwordField(Arg3, 4, CAP0)
> +
> +          //
> +          // _OSC needs to validate the UUID and Revision.
> +          //
> +          // IF Unrecognized UUID
> +          //    Return Unrecognized UUID _OSC Failure
> +          // IF Unsupported Revision
> +          //    Return Unsupported Revision _OSC Failure
> +          //
> +          //    STS0[0] = Reserved
> +          //    STS0[1] = _OSC Failure
> +          //    STS0[2] = Unrecognized UUID
> +          //    STS0[3] = Unsupported Revision
> +          //    STS0[4] = Capabilities masked
> +          //
> +          // Note:  The comparison method used is necessary due to
> +          // limitations of certain OSes which cannot perform direct
> +          // buffer comparisons.
> +          //
> +          // Create a set of "Input" UUID fields.
> +          //
> +          CreateDwordField(Arg0, 0x0, IID0)
> +          CreateDwordField(Arg0, 0x4, IID1)
> +          CreateDwordField(Arg0, 0x8, IID2)
> +          CreateDwordField(Arg0, 0xC, IID3)
> +          //
> +          // Create a set of "Expected" UUID fields.
> +          //
> +          Name(UID0, ToUUID("4077A616-290C-47BE-9EBD-D87058713953"))
> +          CreateDwordField(UID0, 0x0, EID0)
> +          CreateDwordField(UID0, 0x4, EID1)
> +          CreateDwordField(UID0, 0x8, EID2)
> +          CreateDwordField(UID0, 0xC, EID3)
> +          //
> +          // Verify the input UUID matches the expected UUID.
> +          //
> +          If(LNot(LAnd(LAnd(LEqual(IID0, EID0),LEqual(IID1,
> EID1)),LAnd(LEqual(IID2, EID2),LEqual(IID3, EID3)))))
> +          {
> +              //
> +              // Return Unrecognized UUID _OSC Failure
> +              //
> +              Store (0x6, STS0)
> +              Return (Arg3)
> +          }
> +
> +          If(LNot(LEqual(Arg1,1)))
> +          {
> +              //
> +              // Return Unsupported Revision _OSC Failure
> +              //
> +              Store (0xA, STS0)
> +              Return (Arg3)
> +          }
> +
> +          Return (Arg3)
> +      }
> +
> +      //
> +      // Get the capability information and load appropriate tables as needed.
> +      //
> +      Method(GCAP, 1)
> +      {
> +
> +          // Point to Status DWORD in the Arg0 buffer (STATUS)
> +          CreateDWordField(Arg0, 0, STS0)
> +
> +          // Point to Caps DWORDs of the Arg0 buffer (CAPABILITIES)
> +          CreateDwordField(Arg0, 4, CAP0)
> +
> +          //
> +          // If the UUID was unrecognized or the _OSC revision was
> unsupported,
> +          // return without updating capabilities.
> +          //
> +          If(LOr(LEqual(STS0,0x6),LEqual(STS0,0xA)))
> +          {
> +              Return()
> +          }
> +
> +          //
> +          // Check if this is a query (BIT0 of Status = 1).
> +          // If so, mask off the bits we support and return.
> +          //
> +          if (And(STS0, 1))
> +          {
> +              And(CAP0, 0xBFF, CAP0)
> +              Return()
> +          }
> +
> +          //
> +          // Store result of PDC. (We clear out the MSB, which was just
> +          // used as a placeholder for the compiler; and then "OR" the
> +          // value in case we get multiple calls, each of which only
> +          // reports partial support.)
> +          //
> +          Or(And(PDC0, 0x7FFFFFFF), CAP0, PDC0)
> +
> +          //
> +          // Check IF the IST SSDTs should be loaded.
> +          //
> +          //   CFGD[0] = GV3 Capable/Enabled
> +          //
> +          If(And(CFGD,0x01))
> +          {
> +              //
> +              // Load the IST SSDTs if:
> +              //   (1) CMP capable and enabled.
> +              //   (2) Driver supports P-States in MP configurations
> +              //   (3) Driver supports direct HW P-State control
> +              //   (4) SSDT is not already loaded
> +              //
> +              //   CFGD[24] = Two or more cores enabled
> +              //   PDCx[3]  = OS supports C1 and P-states in MP systems
> +              //   PDCx[0]  = OS supports direct access of the perf MSR
> +              //   SDTL[0]  = CPU0 IST SSDT Loaded
> +              //
> +              If(LAnd(LAnd(And(CFGD,0x01000000),LEqual(And(PDC0, 0x0009),
> 0x0009)),LNot(And(SDTL,0x01))))
> +              {
> +                  //
> +                  // Flag the IST SSDT as loaded for CPU0
> +                  //
> +                  Or(SDTL, 0x01, SDTL)
> +
> +
> OperationRegion(IST0,SystemMemory,DeRefOf(Index(SSDT,1)),DeRefOf(In
> dex(SSDT,2)))
> +                  Load(IST0, HI0)    // Dynamically load the CPU0IST SSDT
> +              }
> +          }
> +
> +          //
> +          // Check IF the CST SSDTs should be loaded.
> +          //
> +          //   CFGD[11,7,2,1] = C6, C4, C1E, C1 Capable/Enabled
> +          //
> +          If(And(CFGD,0x82))
> +          {
> +              //
> +              // Load the CST SSDTs if:
> +              //   (1) CMP capable/enabled
> +              //   (2) Driver supports multi-processor configurations
> +              //   (3) CPU0 CST ISDT is not already loaded
> +              //
> +              //   CFGD[24] = Two or more cores enabled
> +              //   PDCx[3]  = OS supports C1 and P-states in MP systems
> +              //   PDCx[4]  = OS supports ind. C2/C3 in MP systems
> +              //   SDTL[1]  = CPU0 CST SSDT Loaded
> +              //
> +
> If(LAnd(LAnd(And(CFGD,0x01000000),And(PDC0,0x0018)),LNot(And(SDTL,0x
> 02))))
> +              {
> +                  //
> +                  // Flag the CST SSDT as loaded for CPU0
> +                  //
> +                  Or(SDTL, 0x02, SDTL)
> +
> +
> OperationRegion(CST0,SystemMemory,DeRefOf(Index(SSDT,7)),DeRefOf(In
> dex(SSDT,8)))
> +                  Load(CST0, HC0)    // Dynamically load the CPU0CST SSDT
> +              }
> +          }
> +
> +          Return ()
> +      }
> +  }
> +
> +
> +  Scope(\_PR.CPU1)
> +  {
> +      //
> +      // Define handles for opregions (used by load.)
> +      //
> +      Name(HI1,0)        // Handle to APIST
> +      Name(HC1,0)        // Handle to APCST
> +
> +      Method(_PDC,1)
> +      {
> +          //
> +          // Refer to \_PR.CPU0._PDC for description.
> +          //
> +          Store(\_PR.CPU0.CPDC(Arg0), Local0)
> +          GCAP(Local0)
> +          //Return (Local0)
> +      }
> +
> +      Method(_OSC, 4)
> +      {
> +          //
> +          // Refer to \_PR.CPU0._OSC for description.
> +          //
> +          Store(\_PR.CPU0.COSC(Arg0, Arg1, Arg2, Arg3), Local0)
> +          GCAP(Local0)
> +          Return (Local0)
> +      }
> +
> +      //
> +      // Get the capability information and load appropriate tables as needed.
> +      //
> +      Method(GCAP, 1)
> +      {
> +          //
> +          // Point to Status DWORD in the Arg0 buffer (STATUS)
> +          //
> +          CreateDWordField(Arg0, 0, STS1)
> +          //
> +          // Point to Caps DWORDs of the Arg0 buffer (CAPABILITIES)
> +          //
> +          CreateDwordField(Arg0, 4, CAP1)
> +          //
> +          // If the UUID was unrecognized or the _OSC revision was
> unsupported,
> +          // return without updating capabilities.
> +          //
> +          If(LOr(LEqual(STS1,0x6),LEqual(STS1,0xA)))
> +          {
> +              Return()
> +          }
> +
> +          //
> +          // Check if this is a query (BIT0 of Status = 1).
> +          // If so, mask off the bits we support and return.
> +          //
> +          if (And(STS1, 1))
> +          {
> +              And(CAP1, 0xBFF, CAP1)
> +              Return()
> +          }
> +
> +          //
> +          // Store result of PDC. (We clear out the MSB, which was just
> +          // used as a placeholder for the compiler; and then "OR" the
> +          // value in case we get multiple calls, each of which only
> +          // reports partial support.)
> +          //
> +          Or(And(PDC1, 0x7FFFFFFF), CAP1, PDC1)
> +
> +          //
> +          // Attempt to dynamically load the IST SSDTs if:
> +          //   (1) Driver supports P-States in MP configurations
> +          //   (2) Driver supports direct HW P-State control
> +          //
> +          //   PDCx[3]  = OS supports C1 and P-states in MP systems
> +          //   PDCx[0]  = OS supports direct access of the perf MSR
> +          //
> +          If(LEqual(And(PDC0, 0x0009), 0x0009))
> +          {
> +              APPT()
> +          }
> +
> +          //
> +          // Load the CST SSDTs if:
> +          //   (1) Driver supports multi-processor configurations
> +          //
> +          //   PDCx[3]  = OS supports C1 and P-states in MP systems
> +          //   PDCx[4]  = OS supports ind. C2/C3 in MP systems
> +          //
> +          If(And(PDC0,0x0018))
> +          {
> +              APCT()
> +          }
> +
> +          Return()
> +      }
> +
> +      //
> +      // Dynamically load the CST SSDTs if:
> +      //   (1) C-States are enabled
> +      //   (2) SSDT is not already loaded
> +      //
> +      //   CFGD[11,7,2,1] = C6, C4, C1E, C1 Capable/Enabled
> +      //   SDTL[5]   = AP CST SSDT Loaded
> +      //
> +      Method(APCT,0)
> +      {
> +          If(LAnd(And(CFGD,0x82),LNot(And(SDTL,0x20))))
> +          {
> +              //
> +              // Flag the CST SSDT as loaded for the AP's
> +              //
> +              Or(SDTL, 0x20, SDTL)
> +              //
> +              // Dynamically load the APCST SSDT
> +              //
> +
> OperationRegion(CST1,SystemMemory,DeRefOf(Index(SSDT,10)),DeRefOf(I
> ndex(SSDT,11)))
> +              Load(CST1, HC1)
> +          }
> +      }
> +
> +      //
> +      // Dynamically load the IST SSDTs if:
> +      //   (1) If GV3 capable and enabled
> +      //   (2) SSDT is not already loaded
> +      //
> +      //   CFGD[0] = GV3 Capable/Enabled
> +      //   SDTL[4] = AP IST SSDT Loaded
> +      //
> +      Method(APPT,0)
> +      {
> +          If(LAnd(And(CFGD,0x01),LNot(And(SDTL,0x10))))
> +          {
> +              //
> +              // Flag the IST SSDT as loaded for CPU0
> +              //
> +              Or(SDTL, 0x10, SDTL)
> +
> +
> OperationRegion(IST1,SystemMemory,DeRefOf(Index(SSDT,4)),DeRefOf(In
> dex(SSDT,5)))
> +              Load(IST1, HI1)    // Dynamically load the CPU1IST SSDT
> +          }
> +      }
> +  }    // End CPU1
> +
> +  Scope(\_PR.CPU2)
> +  {
> +      //
> +      // Define handles for opregions (used by load.)
> +      //
> +      Name(HI1,0)        // Handle to APIST
> +      Name(HC1,0)        // Handle to APCST
> +
> +      Method(_PDC,1)
> +      {
> +          //
> +          // Refer to \_PR.CPU0._PDC for description.
> +          //
> +          Store(\_PR.CPU0.CPDC(Arg0), Local0)
> +          GCAP(Local0)
> +          //Return (Local0)
> +      }
> +
> +      Method(_OSC, 4)
> +      {
> +          //
> +          // Refer to \_PR.CPU0._OSC for description.
> +          //
> +          Store(\_PR.CPU0.COSC(Arg0, Arg1, Arg2, Arg3), Local0)
> +          GCAP(Local0)
> +          Return (Local0)
> +      }
> +
> +      //
> +      // Get the capability information and load appropriate tables as needed.
> +      //
> +      Method(GCAP, 1)
> +      {
> +          //
> +          // Point to Status DWORD in the Arg0 buffer (STATUS)
> +          //
> +          CreateDWordField(Arg0, 0, STS1)
> +          //
> +          // Point to Caps DWORDs of the Arg0 buffer (CAPABILITIES)
> +          //
> +          CreateDwordField(Arg0, 4, CAP1)
> +          //
> +          // If the UUID was unrecognized or the _OSC revision was
> unsupported,
> +          // return without updating capabilities.
> +          //
> +          If(LOr(LEqual(STS1,0x6),LEqual(STS1,0xA)))
> +          {
> +              Return()
> +          }
> +
> +          //
> +          // Check if this is a query (BIT0 of Status = 1).
> +          // If so, mask off the bits we support and return.
> +          //
> +          if (And(STS1, 1))
> +          {
> +              And(CAP1, 0xBFF, CAP1)
> +              Return()
> +          }
> +
> +          //
> +          // Store result of PDC. (We clear out the MSB, which was just
> +          // used as a placeholder for the compiler; and then "OR" the
> +          // value in case we get multiple calls, each of which only
> +          // reports partial support.)
> +          //
> +          Or(And(PDC1, 0x7FFFFFFF), CAP1, PDC1)
> +
> +          //
> +          // Attempt to dynamically load the IST SSDTs if:
> +          //   (1) Driver supports P-States in MP configurations
> +          //   (2) Driver supports direct HW P-State control
> +          //
> +          //   PDCx[3]  = OS supports C1 and P-states in MP systems
> +          //   PDCx[0]  = OS supports direct access of the perf MSR
> +          //
> +          If(LEqual(And(PDC0, 0x0009), 0x0009))
> +          {
> +              APPT()
> +          }
> +
> +          //
> +          // Load the CST SSDTs if:
> +          //   (1) Driver supports multi-processor configurations
> +          //
> +          //   PDCx[3]  = OS supports C1 and P-states in MP systems
> +          //   PDCx[4]  = OS supports ind. C2/C3 in MP systems
> +          //
> +          If(And(PDC0,0x0018))
> +          {
> +              APCT()
> +          }
> +
> +          Return()
> +      }
> +
> +      //
> +      // Dynamically load the CST SSDTs if:
> +      //   (1) C-States are enabled
> +      //   (2) SSDT is not already loaded
> +      //
> +      //   CFGD[11,7,2,1] = C6, C4, C1E, C1 Capable/Enabled
> +      //   SDTL[5]   = AP CST SSDT Loaded
> +      //
> +      Method(APCT,0)
> +      {
> +          If(LAnd(And(CFGD,0x82),LNot(And(SDTL,0x20))))
> +          {
> +              //
> +              // Flag the CST SSDT as loaded for the AP's
> +              //
> +              Or(SDTL, 0x20, SDTL)
> +              //
> +              // Dynamically load the APCST SSDT
> +              //
> +
> OperationRegion(CST1,SystemMemory,DeRefOf(Index(SSDT,10)),DeRefOf(I
> ndex(SSDT,11)))
> +              Load(CST1, HC1)
> +          }
> +      }
> +
> +      //
> +      // Dynamically load the IST SSDTs if:
> +      //   (1) If GV3 capable and enabled
> +      //   (2) SSDT is not already loaded
> +      //
> +      //   CFGD[0] = GV3 Capable/Enabled
> +      //   SDTL[4] = AP IST SSDT Loaded
> +      //
> +      Method(APPT,0)
> +      {
> +          If(LAnd(And(CFGD,0x01),LNot(And(SDTL,0x10))))
> +          {
> +              //
> +              // Flag the IST SSDT as loaded for CPU0
> +              //
> +              Or(SDTL, 0x10, SDTL)
> +
> +
> OperationRegion(IST1,SystemMemory,DeRefOf(Index(SSDT,4)),DeRefOf(In
> dex(SSDT,5)))
> +              Load(IST1, HI1)    // Dynamically load the CPU1IST SSDT
> +          }
> +      }
> +  }    // End CPU1
> +
> +  Scope(\_PR.CPU3)
> +  {
> +      //
> +      // Define handles for opregions (used by load.)
> +      //
> +      Name(HI1,0)        // Handle to APIST
> +      Name(HC1,0)        // Handle to APCST
> +
> +      Method(_PDC,1)
> +      {
> +          //
> +          // Refer to \_PR.CPU0._PDC for description.
> +          //
> +          Store(\_PR.CPU0.CPDC(Arg0), Local0)
> +          GCAP(Local0)
> +          //Return (Local0)
> +      }
> +
> +      Method(_OSC, 4)
> +      {
> +          //
> +          // Refer to \_PR.CPU0._OSC for description.
> +          //
> +          Store(\_PR.CPU0.COSC(Arg0, Arg1, Arg2, Arg3), Local0)
> +          GCAP(Local0)
> +          Return (Local0)
> +      }
> +
> +      //
> +      // Get the capability information and load appropriate tables as needed.
> +      //
> +      Method(GCAP, 1)
> +      {
> +          //
> +          // Point to Status DWORD in the Arg0 buffer (STATUS)
> +          //
> +          CreateDWordField(Arg0, 0, STS1)
> +          //
> +          // Point to Caps DWORDs of the Arg0 buffer (CAPABILITIES)
> +          //
> +          CreateDwordField(Arg0, 4, CAP1)
> +          //
> +          // If the UUID was unrecognized or the _OSC revision was
> unsupported,
> +          // return without updating capabilities.
> +          //
> +          If(LOr(LEqual(STS1,0x6),LEqual(STS1,0xA)))
> +          {
> +              Return()
> +          }
> +
> +          //
> +          // Check if this is a query (BIT0 of Status = 1).
> +          // If so, mask off the bits we support and return.
> +          //
> +          if (And(STS1, 1))
> +          {
> +              And(CAP1, 0xBFF, CAP1)
> +              Return()
> +          }
> +
> +          //
> +          // Store result of PDC. (We clear out the MSB, which was just
> +          // used as a placeholder for the compiler; and then "OR" the
> +          // value in case we get multiple calls, each of which only
> +          // reports partial support.)
> +          //
> +          Or(And(PDC1, 0x7FFFFFFF), CAP1, PDC1)
> +
> +          //
> +          // Attempt to dynamically load the IST SSDTs if:
> +          //   (1) Driver supports P-States in MP configurations
> +          //   (2) Driver supports direct HW P-State control
> +          //
> +          //   PDCx[3]  = OS supports C1 and P-states in MP systems
> +          //   PDCx[0]  = OS supports direct access of the perf MSR
> +          //
> +          If(LEqual(And(PDC0, 0x0009), 0x0009))
> +          {
> +              APPT()
> +          }
> +
> +          //
> +          // Load the CST SSDTs if:
> +          //   (1) Driver supports multi-processor configurations
> +          //
> +          //   PDCx[3]  = OS supports C1 and P-states in MP systems
> +          //   PDCx[4]  = OS supports ind. C2/C3 in MP systems
> +          //
> +          If(And(PDC0,0x0018))
> +          {
> +              APCT()
> +          }
> +
> +          Return()
> +      }
> +
> +      //
> +      // Dynamically load the CST SSDTs if:
> +      //   (1) C-States are enabled
> +      //   (2) SSDT is not already loaded
> +      //
> +      //   CFGD[11,7,2,1] = C6, C4, C1E, C1 Capable/Enabled
> +      //   SDTL[5]   = AP CST SSDT Loaded
> +      //
> +      Method(APCT,0)
> +      {
> +          If(LAnd(And(CFGD,0x82),LNot(And(SDTL,0x20))))
> +          {
> +              //
> +              // Flag the CST SSDT as loaded for the AP's
> +              //
> +              Or(SDTL, 0x20, SDTL)
> +              //
> +              // Dynamically load the APCST SSDT
> +              //
> +
> OperationRegion(CST1,SystemMemory,DeRefOf(Index(SSDT,10)),DeRefOf(I
> ndex(SSDT,11)))
> +              Load(CST1, HC1)
> +          }
> +      }
> +
> +      //
> +      // Dynamically load the IST SSDTs if:
> +      //   (1) If GV3 capable and enabled
> +      //   (2) SSDT is not already loaded
> +      //
> +      //   CFGD[0] = GV3 Capable/Enabled
> +      //   SDTL[4] = AP IST SSDT Loaded
> +      //
> +      Method(APPT,0)
> +      {
> +          If(LAnd(And(CFGD,0x01),LNot(And(SDTL,0x10))))
> +          {
> +              //
> +              // Flag the IST SSDT as loaded for CPU0
> +              //
> +              Or(SDTL, 0x10, SDTL)
> +
> +
> OperationRegion(IST1,SystemMemory,DeRefOf(Index(SSDT,4)),DeRefOf(In
> dex(SSDT,5)))
> +              Load(IST1, HI1)    // Dynamically load the CPU1IST SSDT
> +          }
> +      }
> +  }    // End CPU3
> +} // End of Definition Block
> +
> +
> +
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/PlatformBaseAddresses.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/PlatformBaseAddresses.h
> new file mode 100644
> index 0000000000..1d230fdecd
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/PlatformBaseAddresses.h
> @@ -0,0 +1,92 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +
> +
> +Module Name:
> +
> +  PlatformBaseAddresses.h
> +
> +Abstract:
> +
> +
> +
> +Revision History
> +
> +++*/
> +
> +
> +#ifndef _PLATFORM_BASE_ADDRESSES_H
> +#define _PLATFORM_BASE_ADDRESSES_H
> +
> +//
> +// Define some fixed platform device location information
> +//
> +
> +//
> +// Define platform base
> +//
> +
> +//
> +// SIO
> +//
> +#define SIO_BASE_ADDRESS                  0x0680
> +#define SIO_MONITORING_BASE_ADDRESS       0x0290
> +#define SIO_BASE_MASK                     0xFFF0
> +#define WINDBOND_ECIR_BASE_ADDRESS        0x0810
> +#define SIO_MAILBOX_BASE_ADDRESS          0x0360    // Used by EC
> controller
> +#define SIO_EC_CHANNEL2                   0x62      // Used by EC controller for
> offset 0x62 and 0x66
> +
> +
> +//
> +// South Cluster
> +//
> +#define ACPI_BASE_ADDRESS                 0x0400
> +#define GPIO_BASE_ADDRESS                 0x0500
> +#define SMBUS_BUS_DEV_FUNC                0x1F0300
> +#define SMBUS_BASE_ADDRESS                0xEFA0     // SMBus IO Base
> Address
> +#define SPI_BASE_ADDRESS                  0xFED01000 // SPI Memory Base
> Address
> +#define PMC_BASE_ADDRESS                  0xFED03000 // PMC Memory Base
> Address
> +#define SMBM_BASE_ADDRESS                 0xFED04000 // SMBus Memory
> Base Address
> +#define IO_BASE_ADDRESS                   0xFED0C000 // IO Memory Base
> Address
> +#define ILB_BASE_ADDRESS                  0xFED08000 // ILB Memory Base
> Address
> +#define HPET_BASE_ADDRESS                 0xFED00000 // HPET Base Address
> +#define RCBA_BASE_ADDRESS                 0xFED1C000 // Root Complex Base
> Address
> +#define MPHY_BASE_ADDRESS                 0xFEF00000 // MPHY Memory Base
> Address
> +#define PUNIT_BASE_ADDRESS                0xFED05000 // PUnit Memory Base
> Address
> +
> +//
> +// GPIO GROUP OFFSET
> +//
> +#define GPIO_SCORE_OFFSET                 0x0000
> +#define GPIO_NCORE_OFFSET                 0x1000
> +#define GPIO_SSUS_OFFSET                  0x2000
> +
> +//
> +// MCH/CPU
> +//
> +#define DMI_BASE_ADDRESS                  0xFED18000 // 4K, similar to
> IIO_RCBA // modify from bearlake -- cchew10
> +#define EP_BASE_ADDRESS                   0xFED19000
> +#define MC_MMIO_BASE                      0xFED14000 // Base Address for MMIO
> registers
> +
> +//
> +// TPM
> +//
> +#define TPM_BASE_ADDRESS                  0xFED40000  // Base address for TPM
> +
> +//
> +// Local and I/O APIC addresses.
> +//
> +#define IO_APIC_ADDRESS                   0xFEC00000
> +#define IIO_IOAPIC_ADDRESS                0xFEC90000
> +#define LOCAL_APIC_ADDRESS                0xFEE00000
> +
> +
> +#endif
> +
> +
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Ppi/Capsule.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Ppi/Capsule.h
> new file mode 100644
> index 0000000000..98485701af
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Ppi/Capsule.h
> @@ -0,0 +1,60 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  Capsule.h
> +
> +Abstract:
> +
> +  Capsule PPI definitions.
> +
> +--*/
> +//
> +//
> +#ifndef _PEI_CAPSULE_PPI_H_
> +#define _PEI_CAPSULE_PPI_H_
> +
> +#define PEI_CAPSULE_PPI_GUID \
> +  { \
> +    0x3acf33ee, 0xd892, 0x40f4, 0xa2, 0xfc, 0x38, 0x54, 0xd2, 0xe1, 0x32, 0x3d
> \
> +  }
> +
> +EFI_FORWARD_DECLARATION (PEI_CAPSULE_PPI);
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_CAPSULE_COALESCE) (
> +  IN EFI_PEI_SERVICES                **PeiServices,
> +  IN OUT VOID                        **MemoryBase,
> +  IN OUT UINTN                       *MemSize
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_CAPSULE_CREATE_STATE) (
> +  IN EFI_PEI_SERVICES                                   **PeiServices,
> +  IN VOID                                               *CapsuleBase, // returned from coalesce
> +  IN UINTN                              CapsuleSize                   // returned from coalesce
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_CAPSULE_CHECK_CAPSULE_UPDATE) (
> +  IN EFI_PEI_SERVICES           **PeiServices
> +  );
> +
> +typedef struct _PEI_CAPSULE_PPI {
> +  PEI_CAPSULE_COALESCE              Coalesce;
> +  PEI_CAPSULE_CHECK_CAPSULE_UPDATE  CheckCapsuleUpdate;
> +  PEI_CAPSULE_CREATE_STATE          CreateState;
> +} PEI_CAPSULE_PPI;
> +
> +extern EFI_GUID gPeiCapsulePpiGuid;
> +
> +#endif // #ifndef _PEI_CAPSULE_PPI_H_
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Ppi/PlatformMemoryRange.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Ppi/PlatformMemoryRange.h
> new file mode 100644
> index 0000000000..7378e2c9ca
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Ppi/PlatformMemoryRange.h
> @@ -0,0 +1,144 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  PlatformMemoryRange.h
> +
> +Abstract:
> +
> +  Platform Memory Range PPI as defined in EFI 2.0
> +
> +  PPI for reserving special purpose memory ranges.
> +
> +--*/
> +//
> +//
> +#ifndef _PEI_PLATFORM_MEMORY_RANGE_H_
> +#define _PEI_PLATFORM_MEMORY_RANGE_H_
> +
> +#define PEI_PLATFORM_MEMORY_RANGE_PPI_GUID \
> +  { \
> +    0x30eb2979, 0xb0f7, 0x4d60, 0xb2, 0xdc, 0x1a, 0x2c, 0x96, 0xce, 0xb1, 0xf4
> \
> +  }
> +
> +typedef struct _PEI_PLATFORM_MEMORY_RANGE_PPI
> PEI_PLATFORM_MEMORY_RANGE_PPI ;
> +
> +#define PEI_MEMORY_RANGE_OPTION_ROM UINT32
> +
> +#define PEI_MR_OPTION_ROM_ALL       0xFFFFFFFF
> +#define PEI_MR_OPTION_ROM_NONE      0x00000000
> +#define PEI_MR_OPTION_ROM_C0000_16K 0x00000001
> +#define PEI_MR_OPTION_ROM_C4000_16K 0x00000002
> +#define PEI_MR_OPTION_ROM_C8000_16K 0x00000004
> +#define PEI_MR_OPTION_ROM_CC000_16K 0x00000008
> +#define PEI_MR_OPTION_ROM_D0000_16K 0x00000010
> +#define PEI_MR_OPTION_ROM_D4000_16K 0x00000020
> +#define PEI_MR_OPTION_ROM_D8000_16K 0x00000040
> +#define PEI_MR_OPTION_ROM_DC000_16K 0x00000080
> +#define PEI_MR_OPTION_ROM_E0000_16K 0x00000100
> +#define PEI_MR_OPTION_ROM_E4000_16K 0x00000200
> +#define PEI_MR_OPTION_ROM_E8000_16K 0x00000400
> +#define PEI_MR_OPTION_ROM_EC000_16K 0x00000800
> +#define PEI_MR_OPTION_ROM_F0000_16K 0x00001000
> +#define PEI_MR_OPTION_ROM_F4000_16K 0x00002000
> +#define PEI_MR_OPTION_ROM_F8000_16K 0x00004000
> +#define PEI_MR_OPTION_ROM_FC000_16K 0x00008000
> +
> +//
> +// SMRAM Memory Range
> +//
> +#define PEI_MEMORY_RANGE_SMRAM      UINT32
> +#define PEI_MR_SMRAM_ALL            0xFFFFFFFF
> +#define PEI_MR_SMRAM_NONE           0x00000000
> +#define PEI_MR_SMRAM_CACHEABLE_MASK 0x80000000
> +#define PEI_MR_SMRAM_SEGTYPE_MASK   0x00FF0000
> +#define PEI_MR_SMRAM_ABSEG_MASK     0x00010000
> +#define PEI_MR_SMRAM_HSEG_MASK      0x00020000
> +#define PEI_MR_SMRAM_TSEG_MASK      0x00040000
> +//
> +// If adding additional entries, SMRAM Size
> +// is a multiple of 128KB.
> +//
> +#define PEI_MR_SMRAM_SIZE_MASK          0x0000FFFF
> +#define PEI_MR_SMRAM_SIZE_128K_MASK     0x00000001
> +#define PEI_MR_SMRAM_SIZE_256K_MASK     0x00000002
> +#define PEI_MR_SMRAM_SIZE_512K_MASK     0x00000004
> +#define PEI_MR_SMRAM_SIZE_1024K_MASK    0x00000008
> +#define PEI_MR_SMRAM_SIZE_2048K_MASK    0x00000010
> +#define PEI_MR_SMRAM_SIZE_4096K_MASK    0x00000020
> +#define PEI_MR_SMRAM_SIZE_8192K_MASK    0x00000040
> +
> +#define PEI_MR_SMRAM_ABSEG_128K_NOCACHE 0x00010001
> +#define PEI_MR_SMRAM_HSEG_128K_CACHE    0x80020001
> +#define PEI_MR_SMRAM_HSEG_128K_NOCACHE  0x00020001
> +#define PEI_MR_SMRAM_TSEG_128K_CACHE    0x80040001
> +#define PEI_MR_SMRAM_TSEG_128K_NOCACHE  0x00040001
> +#define PEI_MR_SMRAM_TSEG_256K_CACHE    0x80040002
> +#define PEI_MR_SMRAM_TSEG_256K_NOCACHE  0x00040002
> +#define PEI_MR_SMRAM_TSEG_512K_CACHE    0x80040004
> +#define PEI_MR_SMRAM_TSEG_512K_NOCACHE  0x00040004
> +#define PEI_MR_SMRAM_TSEG_1024K_CACHE   0x80040008
> +#define PEI_MR_SMRAM_TSEG_1024K_NOCACHE 0x00040008
> +
> +//
> +// Graphics Memory Range
> +//
> +#define PEI_MEMORY_RANGE_GRAPHICS_MEMORY  UINT32
> +#define PEI_MR_GRAPHICS_MEMORY_ALL        0xFFFFFFFF
> +#define PEI_MR_GRAPHICS_MEMORY_NONE       0x00000000
> +#define PEI_MR_GRAPHICS_MEMORY_CACHEABLE  0x80000000
> +//
> +// If adding additional entries, Graphics Memory Size
> +// is a multiple of 512KB.
> +//
> +#define PEI_MR_GRAPHICS_MEMORY_SIZE_MASK    0x0000FFFF
> +#define PEI_MR_GRAPHICS_MEMORY_512K_NOCACHE 0x00000001
> +#define PEI_MR_GRAPHICS_MEMORY_512K_CACHE   0x80000001
> +#define PEI_MR_GRAPHICS_MEMORY_1M_NOCACHE   0x00000002
> +#define PEI_MR_GRAPHICS_MEMORY_1M_CACHE     0x80000002
> +#define PEI_MR_GRAPHICS_MEMORY_4M_NOCACHE   0x00000008
> +#define PEI_MR_GRAPHICS_MEMORY_4M_CACHE     0x80000008
> +#define PEI_MR_GRAPHICS_MEMORY_8M_NOCACHE   0x00000010
> +#define PEI_MR_GRAPHICS_MEMORY_8M_CACHE     0x80000010
> +#define PEI_MR_GRAPHICS_MEMORY_16M_NOCACHE  0x00000020
> +#define PEI_MR_GRAPHICS_MEMORY_16M_CACHE    0x80000020
> +#define PEI_MR_GRAPHICS_MEMORY_32M_NOCACHE  0x00000040
> +#define PEI_MR_GRAPHICS_MEMORY_32M_CACHE    0x80000040
> +#define PEI_MR_GRAPHICS_MEMORY_48M_NOCACHE  0x00000060
> +#define PEI_MR_GRAPHICS_MEMORY_48M_CACHE    0x80000060
> +#define PEI_MR_GRAPHICS_MEMORY_64M_NOCACHE  0x00000080
> +#define PEI_MR_GRAPHICS_MEMORY_64M_CACHE    0x80000080
> +#define PEI_MR_GRAPHICS_MEMORY_128M_NOCACHE 0x00000100
> +#define PEI_MR_GRAPHICS_MEMORY_128M_CACHE   0x80000100
> +#define PEI_MR_GRAPHICS_MEMORY_256M_NOCACHE 0x00000200
> +#define PEI_MR_GRAPHICS_MEMORY_256M_CACHE   0x80000200
> +//
> +// Pci Memory Hole
> +//
> +#define PEI_MEMORY_RANGE_PCI_MEMORY       UINT32
> +#define PEI_MR_PCI_MEMORY_SIZE_512M_MASK  0x00000001
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_CHOOSE_RANGES) (
> +  IN      EFI_PEI_SERVICES                      **PeiServices,
> +  IN PEI_PLATFORM_MEMORY_RANGE_PPI              * This,
> +  IN OUT  PEI_MEMORY_RANGE_OPTION_ROM           * OptionRomMask,
> +  IN OUT  PEI_MEMORY_RANGE_SMRAM                * SmramMask,
> +  IN OUT  PEI_MEMORY_RANGE_GRAPHICS_MEMORY      *
> GraphicsMemoryMask,
> +  IN OUT  PEI_MEMORY_RANGE_PCI_MEMORY           * PciMemoryMask
> +  );
> +
> +struct _PEI_PLATFORM_MEMORY_RANGE_PPI {
> +  PEI_CHOOSE_RANGES ChooseRanges;
> +};
> +
> +extern EFI_GUID gPeiPlatformMemoryRangePpiGuid;
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Ppi/PlatformMemorySize.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Ppi/PlatformMemorySize.h
> new file mode 100644
> index 0000000000..b19a178732
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Ppi/PlatformMemorySize.h
> @@ -0,0 +1,46 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +Module Name:
> +
> +  PlatformMemorySize.h
> +
> +Abstract:
> +
> +  Platform Memory Size PPI as defined in Tiano
> +
> +  PPI for describing the minimum platform memory size in order to
> successfully
> +  pass control into DXE
> +
> +--*/
> +//
> +//
> +#ifndef _PEI_PLATFORM_MEMORY_SIZE_H_
> +#define _PEI_PLATFORM_MEMORY_SIZE_H_
> +
> +#define PEI_PLATFORM_MEMORY_SIZE_PPI_GUID \
> +  { \
> +    0x9a7ef41e, 0xc140, 0x4bd1, 0xb8, 0x84, 0x1e, 0x11, 0x24, 0xb, 0x4c, 0xe6
> \
> +  }
> +
> +EFI_FORWARD_DECLARATION (PEI_PLATFORM_MEMORY_SIZE_PPI);
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_GET_MINIMUM_PLATFORM_MEMORY_SIZE) (
> +  IN      EFI_PEI_SERVICES                       **PeiServices,
> +  IN PEI_PLATFORM_MEMORY_SIZE_PPI                * This,
> +  IN OUT  UINT64                                 *MemorySize
> +  );
> +
> +typedef struct _PEI_PLATFORM_MEMORY_SIZE_PPI {
> +  PEI_GET_MINIMUM_PLATFORM_MEMORY_SIZE
> GetPlatformMemorySize;
> +} PEI_PLATFORM_MEMORY_SIZE_PPI;
> +
> +extern EFI_GUID gPeiPlatformMemorySizePpiGuid;
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Ppi/SmmAccess.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Ppi/SmmAccess.h
> new file mode 100644
> index 0000000000..dda3f8cabe
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Ppi/SmmAccess.h
> @@ -0,0 +1,165 @@
> +//
> +//
> +/*++
> +
> +Copyright (c)  2009  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  SmmAccess.h
> +
> +Abstract:
> +
> +  SmmAccess PPI
> +
> +  This code abstracts the PEI core to provide SmmAccess services.
> +
> +--*/
> +
> +#ifndef _PEI_SMM_ACCESS_PPI_H_
> +#define _PEI_SMM_ACCESS_PPI_H_
> +
> +#ifdef ECP_FLAG
> +#include "Guid/SmramMemoryReserve/SmramMemoryReserve.h"
> +#else
> +#include "Guid/SmramMemoryReserve.h"
> +#endif
> +
> +#define PEI_SMM_ACCESS_PPI_GUID \
> +  { \
> +    0x268f33a9, 0xcccd, 0x48be, 0x88, 0x17, 0x86, 0x5, 0x3a, 0xc3, 0x2e, 0xd6 \
> +  }
> +
> +typedef struct _PEI_SMM_ACCESS_PPI PEI_SMM_ACCESS_PPI;
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_SMM_OPEN) (
> +  IN EFI_PEI_SERVICES                **PeiServices,
> +  IN PEI_SMM_ACCESS_PPI              *This,
> +  IN UINTN                           DescriptorIndex
> +  )
> +/*++
> +
> +  Routine Description:
> +    This routine accepts a request to "open" a region of SMRAM.  The
> +    region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
> +    The use of "open" means that the memory is visible from all PEIM
> +    and SMM agents.
> +
> +  Arguments:
> +    PeiServices           - General purpose services available to every PEIM.
> +    This                  - Pointer to the SMM Access Interface.
> +    DescriptorIndex       - Region of SMRAM to Open.
> +
> +  Returns:
> +    EFI_SUCCESS           - The region was successfully opened.
> +    EFI_DEVICE_ERROR      - The region could not be opened because locked
> by
> +                            chipset.
> +    EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +--*/
> +;
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_SMM_CLOSE) (
> +  IN EFI_PEI_SERVICES                **PeiServices,
> +  IN PEI_SMM_ACCESS_PPI              *This,
> +  IN UINTN                           DescriptorIndex
> +  )
> +/*++
> +
> +  Routine Description:
> +    This routine accepts a request to "close" a region of SMRAM.  The
> +    region could be legacy AB or TSEG near top of physical memory.
> +    The use of "close" means that the memory is only visible from SMM
> agents,
> +    not from PEIM.
> +
> +  Arguments:
> +    PeiServices           - General purpose services available to every PEIM.
> +    This                  - Pointer to the SMM Access Interface.
> +    DescriptorIndex       - Region of SMRAM to Close.
> +
> +  Returns:
> +    EFI_SUCCESS           - The region was successfully closed.
> +    EFI_DEVICE_ERROR      - The region could not be closed because locked by
> +                              chipset.
> +    EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +
> +--*/
> +;
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_SMM_LOCK) (
> +  IN EFI_PEI_SERVICES                **PeiServices,
> +  IN PEI_SMM_ACCESS_PPI              *This,
> +  IN UINTN                           DescriptorIndex
> +  )
> +/*++
> +
> +  Routine Description:
> +    This routine accepts a request to "lock" SMRAM.  The
> +    region could be legacy AB or TSEG near top of physical memory.
> +    The use of "lock" means that the memory can no longer be opened
> +    to PEIM.
> +
> +  Arguments:
> +    PeiServices           - General purpose services available to every PEIM.
> +    This                  - Pointer to the SMM Access Interface.
> +    DescriptorIndex       - Region of SMRAM to Lock.
> +
> +  Returns:
> +    EFI_SUCCESS           - The region was successfully locked.
> +    EFI_DEVICE_ERROR      - The region could not be locked because at least
> +                            one range is still open.
> +    EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +
> +--*/
> +;
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_SMM_CAPABILITIES) (
> +  IN EFI_PEI_SERVICES                **PeiServices,
> +  IN PEI_SMM_ACCESS_PPI              *This,
> +  IN OUT UINTN                       *SmramMapSize,
> +  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
> +  )
> +/*++
> +
> +  Routine Description:
> +    This routine services a user request to discover the SMRAM
> +    capabilities of this platform.  This will report the possible
> +    ranges that are possible for SMRAM access, based upon the
> +    memory controller capabilities.
> +
> +  Arguments:
> +    PeiServices           - General purpose services available to every PEIM.
> +    This                  - Pointer to the SMRAM Access Interface.
> +    SmramMapSize          - Pointer to the variable containing size of the
> +                              buffer to contain the description information.
> +    SmramMap              - Buffer containing the data describing the Smram
> +                              region descriptors.
> +  Returns:
> +    EFI_BUFFER_TOO_SMALL  - The user did not provide a sufficient buffer.
> +    EFI_SUCCESS           - The user provided a sufficiently-sized buffer.
> +--*/
> +;
> +
> +struct _PEI_SMM_ACCESS_PPI {
> +  PEI_SMM_OPEN          Open;
> +  PEI_SMM_CLOSE         Close;
> +  PEI_SMM_LOCK          Lock;
> +  PEI_SMM_CAPABILITIES  GetCapabilities;
> +  BOOLEAN               LockState;
> +  BOOLEAN               OpenState;
> +};
> +
> +extern EFI_GUID gPeiSmmAccessPpiGuid;
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Ppi/VlvMmioPolicy.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Ppi/VlvMmioPolicy.h
> new file mode 100644
> index 0000000000..0d359e6062
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Ppi/VlvMmioPolicy.h
> @@ -0,0 +1,39 @@
> +
> +/*++
> +
> +Copyright (c)  2010  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +Module Name:
> +
> +  VlvMmioPolicy.h
> +
> +Abstract:
> +
> +  Interface definition details between ValleyView platform drivers during PEI
> phase.
> +
> +--*/
> +
> +#ifndef _VLV_MMIO_POLICY_PPI_H_
> +#define _VLV_MMIO_POLICY_PPI_H_
> +
> +#define VLV_MMIO_POLICY_PPI_GUID \
> +  { \
> +    0xE767BF7F, 0x4DB6, 0x5B34, 0x10, 0x11, 0x4F, 0xBE, 0x4C, 0xA7, 0xAF,
> 0xD2 \
> +  }
> +
> +extern EFI_GUID gVlvMmioPolicyPpiGuid;
> +
> +
> +//
> +// MRC Platform Policiy PPI
> +//
> +typedef struct _VLV_MMIO_POLICY_PPI {
> +  UINT16                 MmioSize;
> +} VLV_MMIO_POLICY_PPI;
> +
> +#pragma pack()
> +
> +#endif // _VLV_MMIO_POLICY_PPI_H_
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Ppi/VlvPeiInit.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Ppi/VlvPeiInit.h
> new file mode 100644
> index 0000000000..f9f8e816f5
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Ppi/VlvPeiInit.h
> @@ -0,0 +1,35 @@
> +
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +Module Name:
> +
> +  VlvPeiInit.h
> +
> +Abstract:
> +
> +  Interface definition between ValleyView MRC and VlvInitPeim driver..
> +
> +--*/
> +
> +#ifndef _VLV_PEI_INIT_H_
> +#define _VLV_PEI_INIT_H_
> +
> +//
> +// Define the VLV PEI Init PPI GUID
> +//
> +#define VLV_PEI_INIT_PPI_GUID \
> +  { \
> +    0x9ea8911, 0xbe0d, 0x4230, 0xa0, 0x3, 0xed, 0xc6, 0x93, 0xb4, 0x8e, 0x11 \
> +  }
> +
> +//
> +// Extern the GUID for PPI users.
> +//
> +extern EFI_GUID     gVlvPeiInitPpiGuid;
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Ppi/VlvPolicy.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Ppi/VlvPolicy.h
> new file mode 100644
> index 0000000000..07ebfe3fb1
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Ppi/VlvPolicy.h
> @@ -0,0 +1,106 @@
> +
> +/*++
> +
> +Copyright (c)  2010  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +Module Name:
> +
> +  VlvPolicy.h
> +
> +Abstract:
> +
> +  Interface definition details between ValleyView MRC and platform drivers
> during PEI phase.
> +
> +--*/
> +
> +#ifndef _VLV_POLICY_PPI_H_
> +#define _VLV_POLICY_PPI_H_
> +
> +//
> +// MRC Policy provided by platform for PEI phase {7D84B2C2-22A1-4372-
> B12C-EBB232D3A6A3}
> +//
> +#define VLV_POLICY_PPI_GUID \
> +  { \
> +    0x7D84B2C2, 0x22A1, 0x4372, 0xB1, 0x2C, 0xEB, 0xB2, 0x32, 0xD3, 0xA6,
> 0xA3 \
> +  }
> +
> +//
> +// Extern the GUID for protocol users.
> +//
> +extern EFI_GUID gVlvPolicyPpiGuid;
> +
> +//
> +// PPI revision number
> +// Any backwards compatible changes to this PPI will result in an update in
> the revision number
> +// Major changes will require publication of a new PPI
> +//
> +#define MRC_PLATFORM_POLICY_PPI_REVISION  1
> +
> +#ifndef MAX_SOCKETS
> +#define MAX_SOCKETS 4
> +#endif
> +
> +#define S3_TIMING_DATA_LEN          9
> +#define S3_READ_TRAINING_DATA_LEN   16
> +#define S3_WRITE_TRAINING_DATA_LEN  12
> +
> +#ifndef S3_RESTORE_DATA_LEN
> +#define S3_RESTORE_DATA_LEN (S3_TIMING_DATA_LEN +
> S3_READ_TRAINING_DATA_LEN + S3_WRITE_TRAINING_DATA_LEN)
> +#endif // S3_RESTORE_DATA_LEN
> +#pragma pack(1)
> +//
> +// MRC Platform Data Structure
> +//
> +typedef struct {
> +  UINT8   SpdAddressTable[MAX_SOCKETS];
> +  UINT8   TSonDimmSmbusAddress[MAX_SOCKETS];
> +
> +  UINT16  SmbusBar;
> +  UINT32  IchRcba;
> +  UINT32  WdbBaseAddress; // Write Data Buffer area (WC caching mode)
> +  UINT32  WdbRegionSize;
> +  UINT32  SmBusAddress;
> +  UINT8   UserBd;
> +  UINT8   PlatformType;
> +  UINT8   FastBoot;
> +  UINT8   DynSR;
> +} VLV_PLATFORM_DATA;
> +
> +
> +typedef struct {
> +  UINT16  MmioSize;
> +  UINT16  GttSize;
> +  UINT8   IgdDvmt50PreAlloc;
> +  UINT8   PrimaryDisplay;
> +  UINT8   PAVPMode;
> +  UINT8   ApertureSize;
> +  UINT8   InternalGraphics;
> +  UINT8   IgdTurboEn;
> +} GT_CONFIGURATION;
> +
> +typedef struct {
> +  UINT8   EccSupport;
> +  UINT16  DdrFreqLimit;
> +  UINT8   MaxTolud;
> +} MEMORY_CONFIGURATION;
> +
> +
> +//
> +// MRC Platform Policiy PPI
> +//
> +typedef struct _VLV_POLICY_PPI {
> +  UINT8                 Revision;
> +  VLV_PLATFORM_DATA      PlatformData;
> +  GT_CONFIGURATION      GtConfig;
> +  MEMORY_CONFIGURATION  MemConfig;
> +  VOID                  *S3DataPtr; // was called MRC_PARAMS_SAVE_RESTORE
> +  UINT8                 ISPEn;            //ISP (IUNIT) Device Enabled
> +  UINT8                 ISPPciDevConfig;  //ISP (IUNIT) Device Config: 0->B0/D2/F0
> for Window OS, 1->B0D3/F0 for Linux OS
> +} VLV_POLICY_PPI;
> +
> +#pragma pack()
> +
> +#endif // _VLV_POLICY_PPI_H_
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Protocol/IgdOpRegion.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Protocol/IgdOpRegion.h
> new file mode 100644
> index 0000000000..5cf15be3c7
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Protocol/IgdOpRegion.h
> @@ -0,0 +1,213 @@
> +
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +Module Name:
> +
> +  IgdOpRegion.h
> +
> +Abstract:
> +
> +  This file is part of the IGD OpRegion Implementation.  The IGD OpRegion is
> +  an interface between system BIOS, ASL code, and Graphics drivers.
> +
> +  Supporting Specifiction: IGD OpRegion/Software SCI SPEC
> +
> +  Note:  Data structures defined in this protocol are packed not naturally
> +    aligned.
> +
> +  GUID forms:
> +    {CDC5DDDF-E79D-41ec-A9B0-6565490DB9D3}
> +    (0xcdc5dddf, 0xe79d, 0x41ec, 0xa9, 0xb0, 0x65, 0x65, 0x49, 0xd, 0xb9,
> 0xd3);
> +
> +  Acronyms:
> +    NVS:        ACPI Non Volatile Storage
> +    OpRegion:   ACPI Operational Region
> +    VBT:        Video BIOS Table (OEM customizable data)
> +
> +--*/
> +
> +#ifndef _IGD_OPREGION_PROTOCOL_H_
> +#define _IGD_OPREGION_PROTOCOL_H_
> +
> +//
> +// OpRegion / Software SCI protocol GUID
> +//
> +#define IGD_OPREGION_PROTOCOL_GUID \
> +  { \
> +    0xcdc5dddf, 0xe79d, 0x41ec, 0xa9, 0xb0, 0x65, 0x65, 0x49, 0xd, 0xb9, 0xd3
> \
> +  }
> +
> +//
> +// Extern the GUID for protocol users.
> +//
> +extern EFI_GUID gIgdOpRegionProtocolGuid;
> +
> +//
> +// Forward reference for pure ANSI compatability
> +//
> +typedef struct _IGD_OPREGION_PROTOCOL IGD_OPREGION_PROTOCOL;
> +
> +//
> +// Protocol data definitions
> +//
> +
> +//
> +// OpRegion structures:
> +// Sub-structures define the different parts of the OpRegion followed by
> the
> +// main structure representing the entire OpRegion.
> +//
> +// Note: These structures are packed to 1 byte offsets because the exact
> +// data location is requred by the supporting design specification due to
> +// the fact that the data is used by ASL and Graphics driver code compiled
> +// separatly.
> +//
> +
> +//
> +// OpRegion header (mailbox 0) structure and #defines.
> +//
> +#pragma pack (1)
> +typedef struct {
> +  CHAR8   SIGN[0x10]; // 0      OpRegion signature
> +  UINT32  SIZE;       // 0x10   OpRegion size
> +  UINT32  OVER;       // 0x14   OpRegion structure version
> +  UINT8   SVER[0x20]; // 0x18   System BIOS build version
> +  UINT8   VVER[0x10]; // 0x38   Video BIOS build version
> +  UINT8   GVER[0x10]; // 0x48   Graphic driver build version
> +  UINT32  MBOX;       // 0x58   Mailboxes supported
> +  UINT32  DMOD;       // 0x5C   Driver Model
> +  UINT32  PCON;       // 0x60   Platform Configuration Info
> +  CHAR8   GOPV[0x20]; // 0X64   GOP build version
> +  UINT8   RSV[0x7C];  //        Reserved
> +} OPREGION_HEADER;
> +#pragma pack ()
> +
> +//
> +// OpRegion mailbox 1 (public ACPI Methods).
> +//
> +#pragma pack (1)
> +typedef struct {
> +  UINT32  DRDY;     // 0    Driver readiness
> +  UINT32  CSTS;     // 4    Status
> +  UINT32  CEVT;     // 8    Current event
> +  UINT8   RM11[0x14]; // 12   Reserved
> +  UINT32  DIDL;       // 32   Supported display devices list
> +  UINT32  DDL2;       //  8 Devices.
> +  UINT32  DDL3;
> +  UINT32  DDL4;
> +  UINT32  DDL5;
> +  UINT32  DDL6;
> +  UINT32  DDL7;
> +  UINT32  DDL8;
> +  UINT32  CPDL;       // 64   Currently present display devices list
> +  UINT32  CPL2;       //  8 Devices.
> +  UINT32  CPL3;
> +  UINT32  CPL4;
> +  UINT32  CPL5;
> +  UINT32  CPL6;
> +  UINT32  CPL7;
> +  UINT32  CPL8;
> +  UINT32  CADL;       // 96   Currently active display devices list
> +  UINT32  CAL2;       //  8 Devices.
> +  UINT32  CAL3;
> +  UINT32  CAL4;
> +  UINT32  CAL5;
> +  UINT32  CAL6;
> +  UINT32  CAL7;
> +  UINT32  CAL8;
> +  UINT32  NADL;       // 128  Next active device list
> +  UINT32  NDL2;       //   8 Devices.
> +  UINT32  NDL3;
> +  UINT32  NDL4;
> +  UINT32  NDL5;
> +  UINT32  NDL6;
> +  UINT32  NDL7;
> +  UINT32  NDL8;
> +  UINT32  ASLP;     // 160  ASL sleep timeout
> +  UINT32  TIDX;     // 164  Toggle table index
> +  UINT32  CHPD;     // 168  Current hot plug enable indicator
> +  UINT32  CLID;     // 172  Current lid state indicator
> +  UINT32  CDCK;     // 176  Current docking state indicator
> +  UINT32  SXSW;     // 180  Display Switch notification on Sx State resume
> +  UINT32  EVTS;     // 184  Events supported by ASL
> +  UINT32  CNOT;     // 188  Current OS Notification
> +  UINT32  NRDY;     // 192  Reasons for DRDY = 0
> +  UINT8   RM12[0x3C]; // 196  Reserved
> +} OPREGION_MBOX1;
> +#pragma pack ()
> +
> +//
> +// OpRegion mailbox 2 (Software SCI Interface).
> +//
> +#pragma pack (1)
> +typedef struct {
> +  UINT32  SCIC;       // 0    Software SCI function number parameters
> +  UINT32  PARM;       // 4    Software SCI additional parameters
> +  UINT32  DSLP;       // 8    Driver sleep timeout
> +  UINT8   RM21[0xF4]; // 12   Reserved
> +} OPREGION_MBOX2;
> +#pragma pack ()
> +
> +//
> +// OpRegion mailbox 3 (Power Conservation).
> +//
> +#pragma pack (1)
> +typedef struct {
> +  UINT32  ARDY;       // 0    Driver readiness
> +  UINT32  ASLC;       // 4    ASLE interrupt command / status
> +  UINT32  TCHE;       // 8    Technology enabled indicator
> +  UINT32  ALSI;       // 12   Current ALS illuminance reading
> +  UINT32  BCLP;       // 16   Backlight britness to set
> +  UINT32  PFIT;       // 20   Panel fitting Current State or Request
> +  UINT32  CBLV;       // 24   Brightness Current State
> +  UINT16  BCLM[0x14]; // 28   Backlight Brightness Level Duty Cycle Mapping
> Table
> +  UINT32  CPFM;       // 68   Panel Fitting Current Mode
> +  UINT32  EPFM;       // 72   Enabled Panel Fitting Mode
> +  UINT8   PLUT[0x4A]; // 76   Panel Look Up Table
> +  UINT32  PFMB;       // 150  PWM Frequency and Minimum Brightness
> +  UINT32  CCDV;       // 154  Color Correction Default Values
> +  UINT32  PCFT;       // 158  Power Conservation Features
> +  UINT8   RM31[0x5E]; // 162  Reserved
> +} OPREGION_MBOX3;
> +#pragma pack ()
> +
> +//
> +// OpRegion mailbox 4 (VBT).
> +//
> +#pragma pack (1)
> +typedef struct {
> +  UINT8 GVD1[0x1800]; // 6K Reserved
> +} OPREGION_VBT;
> +#pragma pack ()
> +
> +#pragma pack (1)
> +typedef struct {
> +  UINT8 EDIDOVRD[0x400]; // 6K Edid overriding data
> +} OPREGION_MBOX5;
> +#pragma pack ()
> +//
> +// Entire OpRegion
> +//
> +#pragma pack (1)
> +typedef struct {
> +  OPREGION_HEADER  Header; // OpRegion header
> +  OPREGION_MBOX1   MBox1;  // Mailbox 1: Public ACPI Methods
> +  OPREGION_MBOX2   MBox2;  // Mailbox 2: Software SCI Inteface
> +  OPREGION_MBOX3   MBox3;  // Mailbox 3: Power Conservation
> +  OPREGION_VBT        VBT;    // VBT: Video BIOS Table (OEM customizable
> data)
> +  OPREGION_MBOX5   MBox5;
> +} IGD_OPREGION_STRUC;
> +#pragma pack ()
> +
> +//
> +// Protocol data structure definition
> +//
> +struct _IGD_OPREGION_PROTOCOL {
> +  IGD_OPREGION_STRUC    *OpRegion;
> +};
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Protocol/MemInfo.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Protocol/MemInfo.h
> new file mode 100644
> index 0000000000..f5a51e03b0
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Protocol/MemInfo.h
> @@ -0,0 +1,83 @@
> +
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +Module Name:
> +
> +  MemInfo.h
> +
> +Abstract:
> +
> +  This protocol provides the memory information data, such as
> +  total physical memory size, memory frequency, memory size
> +  of each dimm and rank.
> +
> +  This protocol is EFI compatible.
> +
> +--*/
> +
> +#ifndef _MEM_INFO_PROTOCOL_H_
> +#define _MEM_INFO_PROTOCOL_H_
> +
> +//
> +// Define the  protocol GUID
> +//
> +#define MEM_INFO_PROTOCOL_GUID \
> +  { \
> +    0x6f20f7c8, 0xe5ef, 0x4f21, 0x8d, 0x19, 0xed, 0xc5, 0xf0, 0xc4, 0x96, 0xae \
> +  }
> +
> +//
> +// Extern the GUID for protocol users.
> +//
> +extern EFI_GUID                   gMemInfoProtocolGuid;
> +
> +//
> +// Forward reference for ANSI C compatibility
> +//
> +typedef struct _MEM_INFO_PROTOCOL MEM_INFO_PROTOCOL;
> +
> +//
> +// Protocol definitions
> +//
> +
> +#define CH_NUM    2
> +#define DIMM_NUM  1
> +#define RANK_NUM  2
> +
> +#pragma pack(1)
> +typedef struct {
> +  UINT32  memSize;
> +  UINT8   ddrFreq;
> +  UINT8   ddrType;
> +  BOOLEAN EccSupport;
> +  UINT16  dimmSize[CH_NUM * DIMM_NUM];
> +  UINT8   reserved;
> +  UINT16   reserved2;
> +} MEMORY_INFO_DATA;
> +#pragma pack()
> +
> +/*++
> +Data definition:
> +
> +  memSize         Total physical memory size
> +  ddrFreq         DDR Frequency
> +  EccSupport      ECC Support
> +  dimmSize        Dimm Size
> +  DimmExist       Dimm Present or not
> +  RankInDimm      No. of ranks in a dimm
> +
> +--*/
> +
> +//
> +// Protocol definition
> +//
> +struct _MEM_INFO_PROTOCOL {
> +  MEMORY_INFO_DATA  MemInfoData;
> +};
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Protocol/PlatformGopPolicy.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Protocol/PlatformGopPolicy.h
> new file mode 100644
> index 0000000000..a862e505bc
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Protocol/PlatformGopPolicy.h
> @@ -0,0 +1,67 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +--*/
> +
> +/** @file
> +**/
> +
> +#ifndef _PLATFORM_GOP_POLICY_PROTOCOL_H_
> +#define _PLATFORM_GOP_POLICY_PROTOCOL_H_
> +
> +#define EFI_PLATFORM_GOP_POLICY_PROTOCOL_GUID \
> +  { 0xec2e931b, 0x3281, 0x48a5, 0x81, 0x7, 0xdf, 0x8a, 0x8b, 0xed, 0x3c, 0x5d }
> +
> +#define EFI_BMP_IMAGE_GUID \
> +  { 0x878AC2CC, 0x5343, 0x46F2, 0xB5, 0x63, 0x51, 0xF8, 0x9D, 0xAF, 0x56,
> 0xBA }
> +
> +#define PLATFORM_GOP_POLICY_PROTOCOL_REVISION_01 0x01
> +#define PLATFORM_GOP_POLICY_PROTOCOL_REVISION_02 x0222
> +
> +#pragma pack(1)
> +
> +typedef enum {
> +  LidClosed,
> +  LidOpen,
> +  LidStatusMax
> +} LID_STATUS;
> +
> +typedef enum {
> +  Docked,
> +  UnDocked,
> +  DockStatusMax
> +} DOCK_STATUS;
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *GET_PLATFORM_LID_STATUS) (
> +  OUT LID_STATUS *CurrentLidStatus
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *GET_VBT_DATA) (
> +  OUT EFI_PHYSICAL_ADDRESS *VbtAddress,
> +  OUT UINT32 *VbtSize
> +  );
> +
> +#pragma pack()
> +
> +typedef struct _PLATFORM_GOP_POLICY_PROTOCOL {
> +  UINT32                             Revision;
> +  GET_PLATFORM_LID_STATUS            GetPlatformLidStatus;
> +  GET_VBT_DATA                       GetVbtData;
> +} PLATFORM_GOP_POLICY_PROTOCOL;
> +
> +//
> +// Extern the GUID for protocol users.
> +//
> +extern EFI_GUID  gPlatformGOPPolicyGuid;
> +
> +extern EFI_GUID  gBmpImageGuid;
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Protocol/VlvPlatformPolicy.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Protocol/VlvPlatformPolicy.h
> new file mode 100644
> index 0000000000..93756c5dea
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Protocol/VlvPlatformPolicy.h
> @@ -0,0 +1,105 @@
> +
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +Module Name:
> +
> +  VlvPlatformPolicy.h
> +
> +Abstract:
> +
> +  Interface definition details between MCH and platform drivers during DXE
> phase.
> +
> +--*/
> +
> +#ifndef _VLV_PLATFORM_POLICY_H_
> +#define _VLV_PLATFORM_POLICY_H_
> +
> +//
> +// VLV Policy provided by platform for DXE phase {5BAB88BA-E0E2-4674-
> B6AD-B812F6881CD6}
> +//
> +#define DXE_VLV_PLATFORM_POLICY_GUID \
> +  {0x5bab88ba, 0xe0e2, 0x4674, 0xb6, 0xad, 0xb8, 0x12, 0xf6, 0x88, 0x1c,
> 0xd6}
> +
> +//
> +// Extern the GUID for protocol users.
> +//
> +extern EFI_GUID gDxeVlvPlatformPolicyGuid;
> +
> +//
> +// Protocol revision number
> +// Any backwards compatible changes to this protocol will result in an
> update in the revision number
> +// Major changes will require publication of a new protocol
> +//
> +#define DXE_VLV_PLATFORM_POLICY_PROTOCOL_REVISION 0
> +
> +
> +typedef struct {
> +  UINT8  PFITStatus;
> +  UINT8  IgdTheramlSupport;
> +  UINT8  ALSEnabled;
> +  UINT8  LidStatus;
> +} IGD_PANEL_FEATURES;
> +
> +typedef struct {
> +  UINT8   Reserved00;
> +  UINT8   Reserved01;
> +  UINT16  Reserved02;
> +  UINT16  Reserved03;
> +  UINT16  Reserved04;
> +  UINT16  Reserved05;
> +  UINT16  Reserved06;
> +  UINT16  Reserved07;
> +  UINT16  Reserved08;
> +  UINT16  Reserved09;
> +  UINT16  Reserved0A;
> +  UINT16  Reserved0B;
> +  UINT16  Reserved0C;
> +  UINT16  Reserved0D;
> +  UINT8   Reserved0E;
> +  UINT8   Reserved0F;
> +  UINT32  Reserved10;
> +  UINT32  Reserved11;
> +  UINT32  Reserved12;
> +  UINT32  Reserved13;
> +  UINT32  Reserved14;
> +  UINT8   Reserved15;
> +  UINT8   Reserved16;
> +} DPTF_SETTINGS;
> +
> +//
> +// MCH DXE Platform Policiy
> ==================================================
> +//
> +
> +#define NO_AUDIO   0
> +#define HD_AUDIO   1
> +#define LPE_AUDIO  2
> +
> +typedef struct _DXE_VLV_PLATFORM_POLICY_PROTOCOL {
> +  UINT8                   Revision;
> +  IGD_PANEL_FEATURES      IgdPanelFeatures;
> +  DPTF_SETTINGS           Reserved;
> +  UINT8                   GraphicReserve00;
> +  UINT8                   GraphicsPerfAnalyzers;
> +  UINT8                   PwmReserved00;
> +  UINT8                   PwmReserved01;
> +  UINT8                   PmSupport;
> +  UINT8                   GraphicReserve01;
> +  UINT8                   GfxPause;
> +  UINT8                   GraphicsFreqReq;
> +  UINT8                   GraphicReserve03;
> +  UINT8                   GraphicReserve02;
> +  UINT8                   GraphicReserve04;
> +  UINT8                   PavpMode;
> +  UINT8                   GraphicReserve05;
> +  UINT8                   UlClockGating;
> +  UINT8                   IdleReserve;
> +  UINT8                   AudioTypeSupport;
> +  UINT8                   GraphicReserve06;
> +} DXE_VLV_PLATFORM_POLICY_PROTOCOL;
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Valleyview.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Valleyview.h
> new file mode 100644
> index 0000000000..589e30b1a8
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/Valleyview.h
> @@ -0,0 +1,55 @@
> +
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  Valleyview.h
> +
> +Abstract:
> +
> +  This header file provides common definitions just for Valleyview-SOC using
> to avoid including extra module's file.
> +--*/
> +
> +#ifndef _MC_H_INCLUDED_
> +#define _MC_H_INCLUDED_
> +/*
> +< Extended Configuration Base Address.*/
> +#define EC_BASE             0xE0000000
> +
> +//
> +// DEVICE 0 (Memroy Controller Hub)
> +//
> +#define MC_BUS          0x00
> +#define MC_DEV          0x00
> +#define MC_DEV2         0x02
> +#define MC_FUN          0x00
> +// NC DEV 0 Vendor and Device IDs
> +#define MC_VID          0x8086
> +#define MC_DID_OFFSET   0x2         //Device Identification
> +#define MC_GGC_OFFSET   0x50        //GMCH Graphics Control Register
> +
> +//
> +// Device 2 Register Equates
> +//
> +#define IGD_BUS             0x00
> +#define IGD_DEV             0x02
> +#define IGD_FUN_0           0x00
> +#define IGD_FUN_1           0x01
> +#define IGD_DEV_FUN         (IGD_DEV << 3)
> +#define IGD_BUS_DEV_FUN     (MC_BUS << 8) + IGD_DEV_FUN
> +#define IGD_VID             0x8086
> +#define IGD_DID             0xA001
> +#define IGD_MGGC_OFFSET     0x0050      //GMCH Graphics Control Register
> 0x50
> +#define IGD_BSM_OFFSET      0x005C      //Base of Stolen Memory
> +#define IGD_SWSCI_OFFSET    0x00E0      //Software SCI 0xE0 2
> +#define IGD_ASLE_OFFSET     0x00E4      //System Display Event Register
> 0xE4 4
> +#define IGD_ASLS_OFFSET     0x00FC      // ASL Storage
> +#define IGD_DID_QS          0x0BE2      //RCOverride -a: Fix the DID error
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/VlvAccess.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/VlvAccess.h
> new file mode 100644
> index 0000000000..d471921edc
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/VlvAccess.h
> @@ -0,0 +1,254 @@
> +
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  vlvAccess.h
> +
> +Abstract:
> +
> +  Macros to simplify and abstract the interface to PCI configuration.
> +
> +--*/
> +
> +#ifndef _VLVACCESS_H_INCLUDED_
> +#define _VLVACCESS_H_INCLUDED_
> +
> +#include "Valleyview.h"
> +#include "VlvCommonDefinitions.h"
> +#include <Library/IoLib.h>
> +
> +//
> +// Memory Mapped IO access macros used by MSG BUS LIBRARY
> +//
> +#define MmioAddress( BaseAddr, Register ) \
> +  ( (UINTN)BaseAddr + \
> +    (UINTN)(Register) \
> +  )
> +
> +
> +//
> +// UINT32
> +//
> +
> +#define Mmio32Ptr( BaseAddr, Register ) \
> +  ( (volatile UINT32 *)MmioAddress( BaseAddr, Register ) )
> +
> +#define Mmio32( BaseAddr, Register ) \
> +  *Mmio32Ptr( BaseAddr, Register )
> +
> +#define Mmio32Or( BaseAddr, Register, OrData ) \
> +  Mmio32( BaseAddr, Register ) = \
> +    (UINT32) ( \
> +      Mmio32( BaseAddr, Register ) | \
> +      (UINT32)(OrData) \
> +    )
> +
> +#define Mmio32And( BaseAddr, Register, AndData ) \
> +  Mmio32( BaseAddr, Register ) = \
> +    (UINT32) ( \
> +      Mmio32( BaseAddr, Register ) & \
> +      (UINT32)(AndData) \
> +    )
> +
> +#define Mmio32AndThenOr( BaseAddr, Register, AndData, OrData ) \
> +  Mmio32( BaseAddr, Register ) = \
> +    (UINT32) ( \
> +      ( Mmio32( BaseAddr, Register ) & \
> +          (UINT32)(AndData) \
> +      ) | \
> +      (UINT32)(OrData) \
> +    )
> +
> +//
> +// UINT16
> +//
> +
> +#define Mmio16Ptr( BaseAddr, Register ) \
> +  ( (volatile UINT16 *)MmioAddress( BaseAddr, Register ) )
> +
> +#define Mmio16( BaseAddr, Register ) \
> +  *Mmio16Ptr( BaseAddr, Register )
> +
> +#define Mmio16Or( BaseAddr, Register, OrData ) \
> +  Mmio16( BaseAddr, Register ) = \
> +    (UINT16) ( \
> +      Mmio16( BaseAddr, Register ) | \
> +      (UINT16)(OrData) \
> +    )
> +
> +#define Mmio16And( BaseAddr, Register, AndData ) \
> +  Mmio16( BaseAddr, Register ) = \
> +    (UINT16) ( \
> +      Mmio16( BaseAddr, Register ) & \
> +      (UINT16)(AndData) \
> +    )
> +
> +#define Mmio16AndThenOr( BaseAddr, Register, AndData, OrData ) \
> +  Mmio16( BaseAddr, Register ) = \
> +    (UINT16) ( \
> +      ( Mmio16( BaseAddr, Register ) & \
> +          (UINT16)(AndData) \
> +      ) | \
> +      (UINT16)(OrData) \
> +    )
> +
> +//
> +// UINT8
> +//
> +
> +#define Mmio8Ptr( BaseAddr, Register ) \
> +  ( (volatile UINT8 *)MmioAddress( BaseAddr, Register ) )
> +
> +#define Mmio8( BaseAddr, Register ) \
> +  *Mmio8Ptr( BaseAddr, Register )
> +
> +#define Mmio8Or( BaseAddr, Register, OrData ) \
> +  Mmio8( BaseAddr, Register ) = \
> +    (UINT8) ( \
> +      Mmio8( BaseAddr, Register ) | \
> +      (UINT8)(OrData) \
> +    )
> +
> +#define Mmio8And( BaseAddr, Register, AndData ) \
> +  Mmio8( BaseAddr, Register ) = \
> +    (UINT8) ( \
> +      Mmio8( BaseAddr, Register ) & \
> +      (UINT8)(AndData) \
> +    )
> +
> +#define Mmio8AndThenOr( BaseAddr, Register, AndData, OrData ) \
> +  Mmio8( BaseAddr, Register ) = \
> +    (UINT8) ( \
> +      ( Mmio8( BaseAddr, Register ) & \
> +          (UINT8)(AndData) \
> +        ) | \
> +      (UINT8)(OrData) \
> +    )
> +
> +//
> +// MSG BUS API
> +//
> +
> +#define MSG_BUS_ENABLED     0x000000F0
> +#define MSGBUS_MASKHI       0xFFFFFF00
> +#define MSGBUS_MASKLO       0x000000FF
> +
> +#define MESSAGE_BYTE_EN          BIT4
> +#define MESSAGE_WORD_EN          BIT4 | BIT5
> +#define MESSAGE_DWORD_EN         BIT4 | BIT5 | BIT6 | BIT7
> +
> +#define SIDEBAND_OPCODE          0x78
> +#define MEMREAD_OPCODE           0x00000000
> +#define MEMWRITE_OPCODE          0x01000000
> +
> +
> +
> +/***************************/
> +//
> +// Memory mapped PCI IO
> +//
> +
> +#define PciCfgPtr(Bus, Device, Function, Register )\
> +    (UINTN)(Bus << 20) + \
> +    (UINTN)(Device << 15) + \
> +    (UINTN)(Function << 12) + \
> +    (UINTN)(Register)
> +
> +#define PciCfg32Read_CF8CFC(B,D,F,R) \
> +
> (UINT32)(IoOut32(0xCF8,(0x80000000|(B<<16)|(D<<11)|(F<<8)|(R))),IoIn32(
> 0xCFC))
> +
> +#define PciCfg32Write_CF8CFC(B,D,F,R,Data) \
> +
> (IoOut32(0xCF8,(0x80000000|(B<<16)|(D<<11)|(F<<8)|(R))),IoOut32(0xCFC,
> Data))
> +
> +#define PciCfg32Or_CF8CFC(B,D,F,R,O) \
> +  PciCfg32Write_CF8CFC(B,D,F,R, \
> +    (PciCfg32Read_CF8CFC(B,D,F,R) | (O)))
> +
> +#define PciCfg32And_CF8CFC(B,D,F,R,A) \
> +  PciCfg32Write_CF8CFC(B,D,F,R, \
> +    (PciCfg32Read_CF8CFC(B,D,F,R) & (A)))
> +
> +#define PciCfg32AndThenOr_CF8CFC(B,D,F,R,A,O) \
> +  PciCfg32Write_CF8CFC(B,D,F,R, \
> +    (PciCfg32Read_CF8CFC(B,D,F,R) & (A)) | (O))
> +
> +//
> +// Device 0, Function 0
> +//
> +#define McD0PciCfg64(Register)                              MmPci64           (0, MC_BUS,
> 0, 0, Register)
> +#define McD0PciCfg64Or(Register, OrData)                    MmPci64Or         (0,
> MC_BUS, 0, 0, Register, OrData)
> +#define McD0PciCfg64And(Register, AndData)                  MmPci64And        (0,
> MC_BUS, 0, 0, Register, AndData)
> +#define McD0PciCfg64AndThenOr(Register, AndData, OrData)
> MmPci64AndThenOr  (0, MC_BUS, 0, 0, Register, AndData, OrData)
> +
> +#define McD0PciCfg32(Register)                              MmPci32           (0, MC_BUS,
> 0, 0, Register)
> +#define McD0PciCfg32Or(Register, OrData)                    MmPci32Or         (0,
> MC_BUS, 0, 0, Register, OrData)
> +#define McD0PciCfg32And(Register, AndData)                  MmPci32And        (0,
> MC_BUS, 0, 0, Register, AndData)
> +#define McD0PciCfg32AndThenOr(Register, AndData, OrData)
> MmPci32AndThenOr  (0, MC_BUS, 0, 0, Register, AndData, OrData)
> +
> +#define McD0PciCfg16(Register)                              MmPci16           (0, MC_BUS,
> 0, 0, Register)
> +#define McD0PciCfg16Or(Register, OrData)                    MmPci16Or         (0,
> MC_BUS, 0, 0, Register, OrData)
> +#define McD0PciCfg16And(Register, AndData)                  MmPci16And        (0,
> MC_BUS, 0, 0, Register, AndData)
> +#define McD0PciCfg16AndThenOr(Register, AndData, OrData)
> MmPci16AndThenOr  (0, MC_BUS, 0, 0, Register, AndData, OrData)
> +
> +#define McD0PciCfg8(Register)                               MmPci8            (0, MC_BUS, 0,
> 0, Register)
> +#define McD0PciCfg8Or(Register, OrData)                     MmPci8Or          (0,
> MC_BUS, 0, 0, Register, OrData)
> +#define McD0PciCfg8And(Register, AndData)                   MmPci8And         (0,
> MC_BUS, 0, 0, Register, AndData)
> +#define McD0PciCfg8AndThenOr( Register, AndData, OrData )
> MmPci8AndThenOr   (0, MC_BUS, 0, 0, Register, AndData, OrData)
> +
> +
> +//
> +// Device 2, Function 0
> +//
> +#define McD2PciCfg64(Register)                              MmPci64           (0, MC_BUS,
> 2, 0, Register)
> +#define McD2PciCfg64Or(Register, OrData)                    MmPci64Or         (0,
> MC_BUS, 2, 0, Register, OrData)
> +#define McD2PciCfg64And(Register, AndData)                  MmPci64And        (0,
> MC_BUS, 2, 0, Register, AndData)
> +#define McD2PciCfg64AndThenOr(Register, AndData, OrData)
> MmPci64AndThenOr  (0, MC_BUS, 2, 0, Register, AndData, OrData)
> +
> +#define McD2PciCfg32(Register)                              MmPci32           (0, MC_BUS,
> 2, 0, Register)
> +#define McD2PciCfg32Or(Register, OrData)                    MmPci32Or         (0,
> MC_BUS, 2, 0, Register, OrData)
> +#define McD2PciCfg32And(Register, AndData)                  MmPci32And        (0,
> MC_BUS, 2, 0, Register, AndData)
> +#define McD2PciCfg32AndThenOr(Register, AndData, OrData)
> MmPci32AndThenOr  (0, MC_BUS, 2, 0, Register, AndData, OrData)
> +
> +#define McD2PciCfg16(Register)                              MmPci16           (0, MC_BUS,
> 2, 0, Register)
> +#define McD2PciCfg16Or(Register, OrData)                    MmPci16Or         (0,
> MC_BUS, 2, 0, Register, OrData)
> +#define McD2PciCfg16And(Register, AndData)                  MmPci16And        (0,
> MC_BUS, 2, 0, Register, AndData)
> +#define McD2PciCfg16AndThenOr(Register, AndData, OrData)
> MmPci16AndThenOr  (0, MC_BUS, 2, 0, Register, AndData, OrData)
> +
> +#define McD2PciCfg8(Register)                               MmPci8            (0, MC_BUS, 2,
> 0, Register)
> +#define McD2PciCfg8Or(Register, OrData)                     MmPci8Or          (0,
> MC_BUS, 2, 0, Register, OrData)
> +#define McD2PciCfg8And(Register, AndData)                   MmPci8And         (0,
> MC_BUS, 2, 0, Register, AndData)
> +
> +//
> +// IO
> +//
> +
> +#ifndef IoIn8
> +
> +#define IoIn8(Port) \
> +  IoRead8(Port)
> +
> +#define IoIn16(Port) \
> +  IoRead16(Port)
> +
> +#define IoIn32(Port) \
> +  IoRead32(Port)
> +
> +#define IoOut8(Port, Data) \
> +  IoWrite8(Port, Data)
> +
> +#define IoOut16(Port, Data) \
> +  IoWrite16(Port, Data)
> +
> +#define IoOut32(Port, Data) \
> +  IoWrite32(Port, Data)
> +
> +#endif
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/VlvCommonDefinitions.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/VlvCommonDefinitions.h
> new file mode 100644
> index 0000000000..4a521154d9
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Includ
> e/VlvCommonDefinitions.h
> @@ -0,0 +1,252 @@
> +
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  VlvCommonDefinitions.h
> +
> +Abstract:
> +
> +  Macros to simplify and abstract the interface to PCI configuration.
> +
> +--*/
> +
> +///
> +/// PCI CONFIGURATION MAP REGISTER OFFSETS
> +///
> +#ifndef PCI_VID
> +#define PCI_VID             0x0000  ///< Vendor ID Register
> +#define PCI_DID             0x0002  ///< Device ID Register
> +#define PCI_CMD             0x0004  ///< PCI Command Register
> +#define PCI_STS             0x0006  ///< PCI Status Register
> +#define PCI_RID             0x0008  ///< Revision ID Register
> +#define PCI_IFT             0x0009  ///< Interface Type
> +#define PCI_SCC             0x000A  ///< Sub Class Code Register
> +#define PCI_BCC             0x000B  ///< Base Class Code Register
> +#define PCI_CLS             0x000C  ///< Cache Line Size
> +#define PCI_PMLT            0x000D  ///< Primary Master Latency Timer
> +#define PCI_HDR             0x000E  ///< Header Type Register
> +#define PCI_BIST            0x000F  ///< Built in Self Test Register
> +#define PCI_BAR0            0x0010  ///< Base Address Register 0
> +#define PCI_BAR1            0x0014  ///< Base Address Register 1
> +#define PCI_BAR2            0x0018  ///< Base Address Register 2
> +#define PCI_PBUS            0x0018  ///< Primary Bus Number Register
> +#define PCI_SBUS            0x0019  ///< Secondary Bus Number Register
> +#define PCI_SUBUS           0x001A  ///< Subordinate Bus Number Register
> +#define PCI_SMLT            0x001B  ///< Secondary Master Latency Timer
> +#define PCI_BAR3            0x001C  ///< Base Address Register 3
> +#define PCI_IOBASE          0x001C  ///< I/O base Register
> +#define PCI_IOLIMIT         0x001D  ///< I/O Limit Register
> +#define PCI_SECSTATUS       0x001E  ///< Secondary Status Register
> +#define PCI_BAR4            0x0020  ///< Base Address Register 4
> +#define PCI_MEMBASE         0x0020  ///< Memory Base Register
> +#define PCI_MEMLIMIT        0x0022  ///< Memory Limit Register
> +#define PCI_BAR5            0x0024  ///< Base Address Register 5
> +#define PCI_PRE_MEMBASE     0x0024  ///< Prefetchable memory Base
> register
> +#define PCI_PRE_MEMLIMIT    0x0026  ///< Prefetchable memory Limit
> register
> +#define PCI_PRE_MEMBASE_U   0x0028  ///< Prefetchable memory base
> upper 32 bits
> +#define PCI_PRE_MEMLIMIT_U  0x002C  ///< Prefetchable memory limit
> upper 32 bits
> +#define PCI_SVID            0x002C  ///< Subsystem Vendor ID
> +#define PCI_SID             0x002E  ///< Subsystem ID
> +#define PCI_IOBASE_U        0x0030  ///< I/O base Upper Register
> +#define PCI_IOLIMIT_U       0x0032  ///< I/O Limit Upper Register
> +#define PCI_CAPP            0x0034  ///< Capabilities Pointer
> +#define PCI_EROM            0x0038  ///< Expansion ROM Base Address
> +#define PCI_INTLINE         0x003C  ///< Interrupt Line Register
> +#define PCI_INTPIN          0x003D  ///< Interrupt Pin Register
> +#define PCI_MAXGNT          0x003E  ///< Max Grant Register
> +#define PCI_BRIDGE_CNTL     0x003E  ///< Bridge Control Register
> +#define PCI_MAXLAT          0x003F  ///< Max Latency Register
> +#endif
> +//
> +// Bit Difinitions
> +//
> +#ifndef BIT0
> +#define BIT0                     0x0001
> +#define BIT1                     0x0002
> +#define BIT2                     0x0004
> +#define BIT3                     0x0008
> +#define BIT4                     0x0010
> +#define BIT5                     0x0020
> +#define BIT6                     0x0040
> +#define BIT7                     0x0080
> +#define BIT8                     0x0100
> +#define BIT9                     0x0200
> +#define BIT10                    0x0400
> +#define BIT11                    0x0800
> +#define BIT12                    0x1000
> +#define BIT13                    0x2000
> +#define BIT14                    0x4000
> +#define BIT15                    0x8000
> +#define BIT16                    0x00010000
> +#define BIT17                    0x00020000
> +#define BIT18                    0x00040000
> +#define BIT19                    0x00080000
> +#define BIT20                    0x00100000
> +#define BIT21                    0x00200000
> +#define BIT22                    0x00400000
> +#define BIT23                    0x00800000
> +#define BIT24                    0x01000000
> +#define BIT25                    0x02000000
> +#define BIT26                    0x04000000
> +#define BIT27                    0x08000000
> +#define BIT28                    0x10000000
> +#define BIT29                    0x20000000
> +#define BIT30                    0x40000000
> +#define BIT31                    0x80000000
> +#endif
> +
> +#ifndef _PCIACCESS_H_INCLUDED_
> +#define _PCIACCESS_H_INCLUDED_
> +#ifndef PCI_EXPRESS_BASE_ADDRESS
> + #define PCI_EXPRESS_BASE_ADDRESS 0xE0000000
> +#endif
> +
> +#ifndef MmPciAddress
> +#define MmPciAddress( Segment, Bus, Device, Function, Register ) \
> +  ( (UINTN)PCI_EXPRESS_BASE_ADDRESS + \
> +    (UINTN)(Bus << 20) + \
> +    (UINTN)(Device << 15) + \
> +    (UINTN)(Function << 12) + \
> +    (UINTN)(Register) \
> +  )
> +#endif
> +
> +//
> +// UINT64
> +//
> +#define MmPci64Ptr( Segment, Bus, Device, Function, Register ) \
> +  ( (volatile UINT64 *)MmPciAddress( Segment, Bus, Device, Function,
> Register ) )
> +
> +#define MmPci64( Segment, Bus, Device, Function, Register ) \
> +  *MmPci64Ptr( Segment, Bus, Device, Function, Register )
> +
> +#define MmPci64Or( Segment, Bus, Device, Function, Register, OrData ) \
> +  MmPci64( Segment, Bus, Device, Function, Register ) = \
> +    (UINT64) ( \
> +      MmPci64( Segment, Bus, Device, Function, Register ) | \
> +      (UINT64)(OrData) \
> +    )
> +
> +#define MmPci64And( Segment, Bus, Device, Function, Register, AndData )
> \
> +  MmPci64( Segment, Bus, Device, Function, Register ) = \
> +    (UINT64) ( \
> +      MmPci64( Segment, Bus, Device, Function, Register ) & \
> +      (UINT64)(AndData) \
> +    )
> +
> +#define MmPci64AndThenOr( Segment, Bus, Device, Function, Register,
> AndData, OrData ) \
> +  MmPci64( Segment, Bus, Device, Function, Register ) = \
> +    (UINT64) ( \
> +      ( MmPci64( Segment, Bus, Device, Function, Register ) & \
> +          (UINT64)(AndData) \
> +      ) | \
> +      (UINT64)(OrData) \
> +    )
> +
> +//
> +// UINT32
> +//
> +
> +#define MmPci32Ptr( Segment, Bus, Device, Function, Register ) \
> +  ( (volatile UINT32 *) MmPciAddress( Segment, Bus, Device, Function,
> Register ) )
> +
> +#define MmPci32( Segment, Bus, Device, Function, Register ) \
> +  *MmPci32Ptr( Segment, Bus, Device, Function, Register )
> +
> +#define MmPci32Or( Segment, Bus, Device, Function, Register, OrData ) \
> +  MmPci32( Segment, Bus, Device, Function, Register ) = \
> +    (UINT32) ( \
> +      MmPci32( Segment, Bus, Device, Function, Register ) | \
> +      (UINT32)(OrData) \
> +    )
> +
> +#define MmPci32And( Segment, Bus, Device, Function, Register, AndData )
> \
> +  MmPci32( Segment, Bus, Device, Function, Register ) = \
> +    (UINT32) ( \
> +      MmPci32( Segment, Bus, Device, Function, Register ) & \
> +      (UINT32)(AndData) \
> +    )
> +
> +#define MmPci32AndThenOr( Segment, Bus, Device, Function, Register,
> AndData, OrData ) \
> +  MmPci32( Segment, Bus, Device, Function, Register ) = \
> +    (UINT32) ( \
> +      ( MmPci32( Segment, Bus, Device, Function, Register ) & \
> +          (UINT32)(AndData) \
> +      ) | \
> +      (UINT32)(OrData) \
> +    )
> +
> +//
> +// UINT16
> +//
> +
> +#define MmPci16Ptr( Segment, Bus, Device, Function, Register ) \
> +  ( (volatile UINT16 *)MmPciAddress( Segment, Bus, Device, Function,
> Register ) )
> +
> +#define MmPci16( Segment, Bus, Device, Function, Register ) \
> +  *MmPci16Ptr( Segment, Bus, Device, Function, Register )
> +
> +#define MmPci16Or( Segment, Bus, Device, Function, Register, OrData ) \
> +  MmPci16( Segment, Bus, Device, Function, Register ) = \
> +    (UINT16) ( \
> +      MmPci16( Segment, Bus, Device, Function, Register ) | \
> +      (UINT16)(OrData) \
> +    )
> +
> +#define MmPci16And( Segment, Bus, Device, Function, Register, AndData )
> \
> +  MmPci16( Segment, Bus, Device, Function, Register ) = \
> +    (UINT16) ( \
> +      MmPci16( Segment, Bus, Device, Function, Register ) & \
> +      (UINT16)(AndData) \
> +    )
> +
> +#define MmPci16AndThenOr( Segment, Bus, Device, Function, Register,
> AndData, OrData ) \
> +  MmPci16( Segment, Bus, Device, Function, Register ) = \
> +    (UINT16) ( \
> +      ( MmPci16( Segment, Bus, Device, Function, Register ) & \
> +          (UINT16)(AndData) \
> +      ) | \
> +      (UINT16)(OrData) \
> +    )
> +
> +//
> +// UINT8
> +//
> +
> +#define MmPci8Ptr( Segment, Bus, Device, Function, Register ) \
> +  ( (volatile UINT8 *)MmPciAddress( Segment, Bus, Device, Function,
> Register ) )
> +
> +#define MmPci8( Segment, Bus, Device, Function, Register ) \
> +  *MmPci8Ptr( Segment, Bus, Device, Function, Register )
> +
> +#define MmPci8Or( Segment, Bus, Device, Function, Register, OrData ) \
> +  MmPci8( Segment, Bus, Device, Function, Register ) = \
> +    (UINT8) ( \
> +      MmPci8( Segment, Bus, Device, Function, Register ) | \
> +      (UINT8)(OrData) \
> +    )
> +
> +#define MmPci8And( Segment, Bus, Device, Function, Register, AndData ) \
> +  MmPci8( Segment, Bus, Device, Function, Register ) = \
> +    (UINT8) ( \
> +      MmPci8( Segment, Bus, Device, Function, Register ) & \
> +      (UINT8)(AndData) \
> +    )
> +
> +#define MmPci8AndThenOr( Segment, Bus, Device, Function, Register,
> AndData, OrData ) \
> +  MmPci8( Segment, Bus, Device, Function, Register ) = \
> +    (UINT8) ( \
> +      ( MmPci8( Segment, Bus, Device, Function, Register ) & \
> +          (UINT8)(AndData) \
> +        ) | \
> +      (UINT8)(OrData) \
> +    )
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Guid/PchInitVar.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Guid/PchInitVar.h
> new file mode 100644
> index 0000000000..aa5de5f4fd
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Guid/PchInitVar.h
> @@ -0,0 +1,48 @@
> +/*++
> +
> +Copyright (c) 2011  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  PchInitVar.h
> +
> +Abstract:
> +
> +  This file defines variable shared between PCH Init DXE driver and PCH
> +  Init S3 Resume PEIM.
> +
> +--*/
> +#ifndef _PCH_INIT_VAR_H_
> +#define _PCH_INIT_VAR_H_
> +
> +#include <Protocol/PchPlatformPolicy.h>
> +//
> +// Define the PCH Init Var GUID
> +//
> +#define PCH_INIT_VARIABLE_GUID {0xe6c2f70a, 0xb604, 0x4877,{0x85,
> 0xba, 0xde, 0xec, 0x89, 0xe1, 0x17, 0xeb}}
> +//
> +// Extern the GUID for PPI users.
> +//
> +extern EFI_GUID gPchInitVariableGuid;
> +
> +#define PCH_INIT_VARIABLE_NAME  L"PchInit"
> +
> +//
> +// Define the Pch Init Variable structure
> +//
> +typedef struct {
> +  UINT32  StorePosition;
> +  UINT32  ExecutePosition;
> +} PCH_S3_PARAMETER_HEADER;
> +
> +#pragma pack(1)
> +typedef struct _PCH_INIT_VARIABLE {
> +  PCH_S3_PARAMETER_HEADER *PchS3Parameter;
> +} PCH_INIT_VARIABLE;
> +#pragma pack()
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Guid/SataControllerGuid.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Guid/SataControllerGuid.h
> new file mode 100644
> index 0000000000..42643ec770
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Guid/SataControllerGuid.h
> @@ -0,0 +1,34 @@
> +/*++
> +
> +Copyright (c)  2009  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  SataControllerGuid.h
> +
> +Abstract:
> +
> +  GUID for use in describing SataController
> +
> +--*/
> +#ifndef _SERIAL_ATA_CONTROLLER_GUID_H_
> +#define _SERIAL_ATA_CONTROLLER_GUID_H_
> +
> +#ifdef ECP_FLAG
> +#define PCH_SATA_CONTROLLER_DRIVER_GUID \
> +  { \
> +    0xbb929da9, 0x68f7, 0x4035, 0xb2, 0x2c, 0xa3, 0xbb, 0x3f, 0x23, 0xda, 0x55
> \
> +  }
> +#else
> +#define PCH_SATA_CONTROLLER_DRIVER_GUID \
> +  {\
> +    0xbb929da9, 0x68f7, 0x4035, 0xb2, 0x2c, 0xa3, 0xbb, 0x3f, 0x23, 0xda, 0x55
> \}
> +
> +#endif
> +
> +extern EFI_GUID gSataControllerDriverGuid;
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Guid/SmbusArpMap.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Guid/SmbusArpMap.h
> new file mode 100644
> index 0000000000..98c2f38443
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Guid/SmbusArpMap.h
> @@ -0,0 +1,30 @@
> +//
> +//
> +/*++
> +
> +Copyright (c)  2009  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  SmbusArpMap.h
> +
> +Abstract:
> +
> +  GUID for use in describing SMBus devices that were ARPed during PEI.
> +
> +--*/
> +#ifndef _EFI_SMBUS_ARP_MAP_GUID_H_
> +#define _EFI_SMBUS_ARP_MAP_GUID_H_
> +
> +#define EFI_SMBUS_ARP_MAP_GUID \
> +  { \
> +    0x707be83e, 0x0bf6, 0x40a5, 0xbe, 0x64, 0x34, 0xc0, 0x3a, 0xa0, 0xb8,
> 0xe2 \
> +  }
> +
> +extern EFI_GUID gEfiSmbusArpMapGuid;
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Guid/Vlv2Variable.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Guid/Vlv2Variable.h
> new file mode 100644
> index 0000000000..c67ae129a1
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Guid/Vlv2Variable.h
> @@ -0,0 +1,28 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  Vlv2Variable.h
> +
> +Abstract:
> +
> +  GUID used to define ValleyView2 variable.
> +
> +--*/
> +
> +#ifndef _VLV2_VARIABLE_GUID_H_
> +#define _VLV2_VARIABLE_GUID_H_
> +
> +#define EFI_VLV2_VARIABLE \
> +  { \
> +    0x10ba6bbe, 0xa97e, 0x41c3, {0x9a, 0x07, 0x60, 0x7a, 0xd9, 0xbd, 0x60,
> 0xe5 } \
> +  }
> +extern EFI_GUID gEfiVlv2VariableGuid;
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/IndustryStandard/CeAta.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/IndustryStandard/CeAta.h
> new file mode 100644
> index 0000000000..8cfbd74f7b
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/IndustryStandard/CeAta.h
> @@ -0,0 +1,126 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +--*/
> +
> +
> +/*++
> +
> +Module Name:
> +
> +  CEATA.h
> +
> +Abstract:
> +
> +  Header file for chipset CE-AT spec.
> +
> +--*/
> +
> +#ifndef _CE_ATA_H
> +#define _CE_ATA_H
> +
> +#pragma pack(1)
> +
> +
> +#define  DATA_UNIT_SIZE       512
> +
> +
> +#define  CMD60                60
> +#define  CMD61                61
> +
> +
> +#define RW_MULTIPLE_REGISTER  CMD60
> +#define RW_MULTIPLE_BLOCK     CMD61
> +
> +
> +#define CE_ATA_SIG_CE         0xCE
> +#define CE_ATA_SIG_AA         0xAA
> +
> +
> +#define Reg_Features_Exp      01
> +#define Reg_SectorCount_Exp   02
> +#define Reg_LBALow_Exp        03
> +#define Reg_LBAMid_Exp        04
> +#define Reg_LBAHigh_Exp       05
> +#define Reg_Control           06
> +#define Reg_Features_Error    09
> +#define Reg_SectorCount       10
> +#define Reg_LBALow            11
> +#define Reg_LBAMid            12
> +#define Reg_LBAHigh           13
> +#define Reg_Device_Head       14
> +#define Reg_Command_Status    15
> +
> +#define Reg_scrTempC          0x80
> +#define Reg_scrTempMaxP       0x84
> +#define Reg_scrTempMinP       0x88
> +#define Reg_scrStatus         0x8C
> +#define Reg_scrReallocsA      0x90
> +#define Reg_scrERetractsA     0x94
> +#define Reg_scrCapabilities   0x98
> +#define Reg_scrControl        0xC0
> +
> +
> +
> +typedef struct {
> +  UINT8  Reserved0;
> +  UINT8  Features_Exp;
> +  UINT8  SectorCount_Exp;
> +  UINT8  LBALow_Exp;
> +  UINT8  LBAMid_Exp;
> +  UINT8  LBAHigh_Exp;
> +  UINT8  Control;
> +  UINT8  Reserved1[2];
> +  UINT8  Features_Error;
> +  UINT8  SectorCount;
> +  UINT8  LBALow;
> +  UINT8  LBAMid;
> +  UINT8  LBAHigh;
> +  UINT8  Device_Head;
> +  UINT8  Command_Status;
> +} TASK_FILE;
> +
> +
> +//
> +//Reduced ATA command set
> +//
> +#define IDENTIFY_DEVICE       0xEC
> +#define READ_DMA_EXT          0x25
> +#define WRITE_DMA_EXT         0x35
> +#define STANDBY_IMMEDIATE     0xE0
> +#define FLUSH_CACHE_EXT       0xEA
> +
> +
> +
> +typedef struct {
> +  UINT16  Reserved0[10];
> +  UINT16  SerialNumber[10];
> +  UINT16  Reserved1[3];
> +  UINT16  FirmwareRevision[4];
> +  UINT16  ModelNumber[20];
> +  UINT16  Reserved2[33];
> +  UINT16  MajorVersion;
> +  UINT16  Reserved3[19];
> +  UINT16  MaximumLBA[4];
> +  UINT16  Reserved4[2];
> +  UINT16  Sectorsize;
> +  UINT16  Reserved5;
> +  UINT16  DeviceGUID[4];
> +  UINT16  Reserved6[94];
> +  UINT16  Features;
> +  UINT16  MaxWritesPerAddress;
> +  UINT16  Reserved7[47];
> +  UINT16  IntegrityWord;
> +} IDENTIFY_DEVICE_DATA;
> +
> +
> +
> +
> +
> +#pragma pack()
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/IndustryStandard/Mmc.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/IndustryStandard/Mmc.h
> new file mode 100644
> index 0000000000..fd2706eb89
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/IndustryStandard/Mmc.h
> @@ -0,0 +1,349 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +--*/
> +
> +
> +/*++
> +
> +Module Name:
> +
> +  MMC.h
> +
> +Abstract:
> +
> +  Header file for Industry MMC 4.2 spec.
> +
> +--*/
> +
> +#ifndef _MMC_H
> +#define _MMC_H
> +
> +#pragma pack(1)
> +//
> +//Command definition
> +//
> +
> +#define  CMD0              0
> +#define  CMD1              1
> +#define  CMD2              2
> +#define  CMD3              3
> +#define  CMD4              4
> +#define  CMD6              6
> +#define  CMD7              7
> +#define  CMD8              8
> +#define  CMD9              9
> +#define  CMD10             10
> +#define  CMD11             11
> +#define  CMD12             12
> +#define  CMD13             13
> +#define  CMD14             14
> +#define  CMD15             15
> +#define  CMD16             16
> +#define  CMD17             17
> +#define  CMD18             18
> +#define  CMD19             19
> +#define  CMD20             20
> +#define  CMD23             23
> +#define  CMD24             24
> +#define  CMD25             25
> +#define  CMD26             26
> +#define  CMD27             27
> +#define  CMD28             28
> +#define  CMD29             29
> +#define  CMD30             30
> +#define  CMD35             35
> +#define  CMD36             36
> +#define  CMD38             38
> +#define  CMD39             39
> +#define  CMD40             40
> +#define  CMD42             42
> +#define  CMD55             55
> +#define  CMD56             56
> +
> +
> +
> +#define  GO_IDLE_STATE           CMD0
> +#define  SEND_OP_COND            CMD1
> +#define  ALL_SEND_CID            CMD2
> +#define  SET_RELATIVE_ADDR       CMD3
> +#define  SET_DSR                 CMD4
> +#define  SWITCH                  CMD6
> +#define  SELECT_DESELECT_CARD    CMD7
> +#define  SEND_EXT_CSD            CMD8
> +#define  SEND_CSD                CMD9
> +#define  SEND_CID                CMD10
> +#define  READ_DAT_UNTIL_STOP     CMD11
> +#define  STOP_TRANSMISSION       CMD12
> +#define  SEND_STATUS             CMD13
> +#define  BUSTEST_R               CMD14
> +#define  GO_INACTIVE_STATE       CMD15
> +#define  SET_BLOCKLEN            CMD16
> +#define  READ_SINGLE_BLOCK       CMD17
> +#define  READ_MULTIPLE_BLOCK     CMD18
> +#define  BUSTEST_W               CMD19
> +#define  WRITE_DAT_UNTIL_STOP    CMD20
> +#define  SET_BLOCK_COUNT         CMD23
> +#define  WRITE_BLOCK             CMD24
> +#define  WRITE_MULTIPLE_BLOCK    CMD25
> +#define  PROGRAM_CID             CMD26
> +#define  PROGRAM_CSD             CMD27
> +#define  SET_WRITE_PROT          CMD28
> +#define  CLR_WRITE_PROT          CMD29
> +#define  SEND_WRITE_PROT         CMD30
> +#define  ERASE_GROUP_START       CMD35
> +#define  ERASE_GROUP_END         CMD36
> +#define  ERASE                   CMD38
> +#define  FAST_IO                 CMD39
> +#define  GO_IRQ_STATE            CMD40
> +#define  LOCK_UNLOCK             CMD42
> +#define  APP_CMD                 CMD55
> +#define  GEN_CMD                 CMD56
> +
> +#define B_PERM_WP_DIS            0x10
> +#define B_PWR_WP_EN              0x01
> +#define US_PERM_WP_DIS           0x10
> +#define US_PWR_WP_EN             0x01
> +
> +#define FREQUENCY_OD            (400 * 1000)
> +#define FREQUENCY_MMC_PP        (26 * 1000 * 1000)
> +#define FREQUENCY_MMC_PP_HIGH   (52 * 1000 * 1000)
> +
> +#define DEFAULT_DSR_VALUE        0x404
> +
> +//
> +//Registers definition
> +//
> +
> +typedef struct {
> +  UINT32  Reserved0:   7;  // 0
> +  UINT32  V170_V195:   1;  // 1.70V - 1.95V
> +  UINT32  V200_V260:   7;  // 2.00V - 2.60V
> +  UINT32  V270_V360:   9;  // 2.70V - 3.60V
> +  UINT32  Reserved1:   5;  // 0
> +  UINT32  AccessMode:  2;  // 00b (byte mode), 10b (sector mode)
> +  UINT32  Busy:        1;  // This bit is set to LOW if the card has not finished the
> power up routine
> +} OCR;
> +
> +
> +typedef struct {
> +  UINT8   NotUsed:     1; //  1
> +  UINT8   CRC:         7; //  CRC7 checksum
> +  UINT8   MDT;            //  Manufacturing date
> +  UINT32  PSN;            //  Product serial number
> +  UINT8   PRV;            //  Product revision
> +  UINT8   PNM[6];         //  Product name
> +  UINT16  OID;            //  OEM/Application ID
> +  UINT8   MID;            //  Manufacturer ID
> +} CID;
> +
> +
> +typedef struct {
> +  UINT8   NotUsed:            1; //  1 [0:0]
> +  UINT8   CRC:                7; //  CRC [7:1]
> +  UINT8   ECC:                2; //  ECC code [9:8]
> +  UINT8   FILE_FORMAT:        2; //  File format [11:10]
> +  UINT8   TMP_WRITE_PROTECT:  1; //  Temporary write protection [12:12]
> +  UINT8   PERM_WRITE_PROTECT: 1; //  Permanent write protection [13:13]
> +  UINT8   COPY:               1; //  Copy flag (OTP) [14:14]
> +  UINT8   FILE_FORMAT_GRP:    1; //  File format group [15:15]
> +  UINT16  CONTENT_PROT_APP:   1; //  Content protection application [16:16]
> +  UINT16  Reserved0:          4; //  0 [20:17]
> +  UINT16  WRITE_BL_PARTIAL:   1; //  Partial blocks for write allowed [21:21]
> +  UINT16  WRITE_BL_LEN:       4; //  Max. write data block length [25:22]
> +  UINT16  R2W_FACTOR:         3; //  Write speed factor [28:26]
> +  UINT16  DEFAULT_ECC:        2; //  Manufacturer default ECC [30:29]
> +  UINT16  WP_GRP_ENABLE:      1; //  Write protect group enable [31:31]
> +  UINT32  WP_GRP_SIZE:        5; //  Write protect group size [36:32]
> +  UINT32  ERASE_GRP_MULT:     5; //  Erase group size multiplier [41:37]
> +  UINT32  ERASE_GRP_SIZE:     5; //  Erase group size [46:42]
> +  UINT32  C_SIZE_MULT:        3; //  Device size multiplier [49:47]
> +  UINT32  VDD_W_CURR_MAX:     3; //  Max. write current @ VDD max
> [52:50]
> +  UINT32  VDD_W_CURR_MIN:     3; //  Max. write current @ VDD min [55:53]
> +  UINT32  VDD_R_CURR_MAX:     3; //  Max. read current @ VDD max [58:56]
> +  UINT32  VDD_R_CURR_MIN:     3; //  Max. read current @ VDD min [61:59]
> +  UINT32  C_SIZELow2:         2;//  Device size [73:62]
> +  UINT32  C_SIZEHigh10:       10;//  Device size [73:62]
> +  UINT32  Reserved1:          2; //  0 [75:74]
> +  UINT32  DSR_IMP:            1; //  DSR implemented [76:76]
> +  UINT32  READ_BLK_MISALIGN:  1; //  Read block misalignment [77:77]
> +  UINT32  WRITE_BLK_MISALIGN: 1; //  Write block misalignment [78:78]
> +  UINT32  READ_BL_PARTIAL:    1; //  Partial blocks for read allowed [79:79]
> +  UINT32  READ_BL_LEN:        4; //  Max. read data block length [83:80]
> +  UINT32  CCC:                12;//  Card command classes [95:84]
> +  UINT8   TRAN_SPEED          ; //  Max. bus clock frequency [103:96]
> +  UINT8   NSAC                ; //  Data read access-time 2 in CLK cycles (NSAC*100)
> [111:104]
> +  UINT8   TAAC                ; //  Data read access-time 1 [119:112]
> +  UINT8   Reserved2:          2; //  0 [121:120]
> +  UINT8   SPEC_VERS:          4; //  System specification version [125:122]
> +  UINT8   CSD_STRUCTURE:      2; //  CSD structure [127:126]
> +} CSD;
> +
> +typedef struct {
> +  UINT8  Reserved133_0[134];     // [133:0] 0
> +  UINT8  SEC_BAD_BLOCK_MGMNT;    // [134] Bad Block Management
> mode
> +  UINT8  Reserved135;            // [135] 0
> +  UINT8  ENH_START_ADDR[4];      // [139:136] Enhanced User Data Start
> Address
> +  UINT8  ENH_SIZE_MULT[3];       // [142:140] Enhanced User Data Start Size
> +  UINT8  GP_SIZE_MULT_1[3];      // [145:143] GPP1 Size
> +  UINT8  GP_SIZE_MULT_2[3];      // [148:146] GPP2 Size
> +  UINT8  GP_SIZE_MULT_3[3];      // [151:149] GPP3 Size
> +  UINT8  GP_SIZE_MULT_4[3];      // [154:152] GPP4 Size
> +  UINT8  PARTITION_SETTING_COMPLETED; // [155] Partitioning Setting
> +  UINT8  PARTITIONS_ATTRIBUTES;  // [156] Partitions attributes
> +  UINT8  MAX_ENH_SIZE_MULT[3];   // [159:157] GPP4 Start Size
> +  UINT8  PARTITIONING_SUPPORT;   // [160] Partitioning Support
> +  UINT8  HPI_MGMT;               // [161] HPI management
> +  UINT8  RST_n_FUNCTION;         // [162] H/W reset function
> +  UINT8  BKOPS_EN;               // [163] Enable background operations
> handshake
> +  UINT8  BKOPS_START;            // [164] Manually start background operations
> +  UINT8  Reserved165;            // [165] 0
> +  UINT8  WR_REL_PARAM;           // [166] Write reliability parameter register
> +  UINT8  WR_REL_SET;             // [167] Write reliability setting register
> +  UINT8  RPMB_SIZE_MULT;         // [168] RPMB Size
> +  UINT8  FW_CONFIG;              // [169] FW configuration
> +  UINT8  Reserved170;            // [170] 0
> +  UINT8  USER_WP;                // [171] User area write protection
> +  UINT8  Reserved172;            // [172] 0
> +  UINT8  BOOT_WP;                // [173] Boot area write protection
> +  UINT8  Reserved174;            // [174] 0
> +  UINT8  ERASE_GROUP_DEF;        // [175] High density erase group
> definition
> +  UINT8  Reserved176;            // [176] 0
> +  UINT8  BOOT_BUS_WIDTH;         // [177] Boot bus width
> +  UINT8  BOOT_CONFIG_PROT;       // [178] Boot config protection
> +  UINT8  PARTITION_CONFIG;       // [179] Partition config
> +  UINT8  Reserved180;            // [180] 0
> +  UINT8  ERASED_MEM_CONT;        // [181] Erased Memory Content
> +  UINT8  Reserved182;            // [182] 0
> +  UINT8  BUS_WIDTH;              // [183] Bus Width Mode
> +  UINT8  Reserved184;            // [184] 0
> +  UINT8  HS_TIMING;              // [185] High Speed Interface Timing
> +  UINT8  Reserved186;            // [186] 0
> +  UINT8  POWER_CLASS;            // [187] Power Class
> +  UINT8  Reserved188;            // [188] 0
> +  UINT8  CMD_SET_REV;            // [189] Command Set Revision
> +  UINT8  Reserved190;            // [190] 0
> +  UINT8  CMD_SET;                // [191] Command Set
> +  UINT8  EXT_CSD_REV;            // [192] Extended CSD Revision
> +  UINT8  Reserved193;            // [193] 0
> +  UINT8  CSD_STRUCTURE;          // [194] CSD Structure Version
> +  UINT8  Reserved195;            // [195] 0
> +  UINT8  CARD_TYPE;              // [196] Card Type
> +  UINT8  Reserved197;            // [197] 0
> +  UINT8  OUT_OF_INTERRUPT_TIME;  // [198] Out-of-interrupt busy timing
> +  UINT8  PARTITION_SWITCH_TIME;  // [199] Partition switching timing
> +  UINT8  PWR_CL_52_195;          // [200] Power Class for 52MHz @ 1.95V
> +  UINT8  PWR_CL_26_195;          // [201] Power Class for 26MHz @ 1.95V
> +  UINT8  PWR_CL_52_360;          // [202] Power Class for 52MHz @ 3.6V
> +  UINT8  PWR_CL_26_360;          // [203] Power Class for 26MHz @ 3.6V
> +  UINT8  Reserved204;            // [204] 0
> +  UINT8  MIN_PERF_R_4_26;        // [205] Minimum Read Performance for
> 4bit @26MHz
> +  UINT8  MIN_PERF_W_4_26;        // [206] Minimum Write Performance for
> 4bit @26MHz
> +  UINT8  MIN_PERF_R_8_26_4_52;   // [207] Minimum Read Performance
> for 8bit @26MHz/4bit @52MHz
> +  UINT8  MIN_PERF_W_8_26_4_52;   // [208] Minimum Write Performance
> for 8bit @26MHz/4bit @52MHz
> +  UINT8  MIN_PERF_R_8_52;        // [209] Minimum Read Performance for
> 8bit @52MHz
> +  UINT8  MIN_PERF_W_8_52;        // [210] Minimum Write Performance for
> 8bit @52MHz
> +  UINT8  Reserved211;            // [211] 0
> +  UINT8  SEC_COUNT[4];           // [215:212] Sector Count
> +  UINT8  Reserved216;            // [216] 0
> +  UINT8  S_A_TIMEOUT;            // [217] Sleep/awake timeout
> +  UINT8  Reserved218;            // [218] 0
> +  UINT8  S_C_VCCQ;               // [219] Sleep current (VCCQ)
> +  UINT8  S_C_VCC;                // [220] Sleep current (VCC)
> +  UINT8  HC_WP_GRP_SIZE;         // [221] High-capacity write protect group
> size
> +  UINT8  REL_WR_SEC_C;           // [222] Reliable write sector count
> +  UINT8  ERASE_TIMEOUT_MULT;     // [223] High-capacity erase timeout
> +  UINT8  HC_ERASE_GRP_SIZE;      // [224] High-capacity erase unit size
> +  UINT8  ACC_SIZE;               // [225] Access size
> +  UINT8  BOOT_SIZE_MULTI;        // [226] Boot partition size
> +  UINT8  Reserved227;            // [227] 0
> +  UINT8  BOOT_INFO;              // [228] Boot information
> +  UINT8  SEC_TRIM_MULT;          // [229] Secure TRIM Multiplier
> +  UINT8  SEC_ERASE_MULT;         // [230] Secure Erase Multiplier
> +  UINT8  SEC_FEATURE_SUPPORT;    // [231] Secure Feature support
> +  UINT8  TRIM_MULT;              // [232] TRIM Multiplier
> +  UINT8  Reserved233;            // [233] 0
> +  UINT8  MIN_PERF_DDR_R_8_52;    // [234] Min Read Performance for 8-bit
> @ 52MHz
> +  UINT8  MIN_PERF_DDR_W_8_52;    // [235] Min Write Performance for 8-
> bit @ 52MHz
> +  UINT8  Reserved237_236[2];     // [237:236] 0
> +  UINT8  PWR_CL_DDR_52_195;      // [238] Power class for 52MHz, DDR at
> 1.95V
> +  UINT8  PWR_CL_DDR_52_360;      // [239] Power class for 52MHz, DDR at
> 3.6V
> +  UINT8  Reserved240;            // [240] 0
> +  UINT8  INI_TIMEOUT_AP;         // [241] 1st initialization time after
> partitioning
> +  UINT8  CORRECTLY_PRG_SECTORS_NUM[4]; // [245:242] Number of
> correctly programmed sectors
> +  UINT8  BKOPS_STATUS;           // [246] Background operations status
> +  UINT8  Reserved501_247[255];   // [501:247] 0
> +  UINT8  BKOPS_SUPPORT;          // [502] Background operations support
> +  UINT8  HPI_FEATURES;           // [503] HPI features
> +  UINT8  S_CMD_SET;              // [504] Sector Count
> +  UINT8  Reserved511_505[7];     // [511:505] Sector Count
> +} EXT_CSD;
> +
> +
> +//
> +//Card Status definition
> +//
> +typedef struct {
> +  UINT32  Reserved0:           2; //Reserved for Manufacturer Test Mode
> +  UINT32  Reserved1:           2; //Reserved for Application Specific commands
> +  UINT32  Reserved2:           1; //
> +  UINT32  SAPP_CMD:            1; //
> +  UINT32  Reserved3:           1; //Reserved
> +  UINT32  SWITCH_ERROR:        1; //
> +  UINT32  READY_FOR_DATA:      1; //
> +  UINT32  CURRENT_STATE:       4; //
> +  UINT32  ERASE_RESET:         1; //
> +  UINT32  Reserved4:           1; //Reserved
> +  UINT32  WP_ERASE_SKIP:       1; //
> +  UINT32  CID_CSD_OVERWRITE:   1; //
> +  UINT32  OVERRUN:             1; //
> +  UINT32  UNDERRUN:            1; //
> +  UINT32  ERROR:               1; //
> +  UINT32  CC_ERROR:            1; //
> +  UINT32  CARD_ECC_FAILED:     1; //
> +  UINT32  ILLEGAL_COMMAND:     1; //
> +  UINT32  COM_CRC_ERROR:       1; //
> +  UINT32  LOCK_UNLOCK_FAILED:  1; //
> +  UINT32  CARD_IS_LOCKED:      1; //
> +  UINT32  WP_VIOLATION:        1; //
> +  UINT32  ERASE_PARAM:         1; //
> +  UINT32  ERASE_SEQ_ERROR:     1; //
> +  UINT32  BLOCK_LEN_ERROR:     1; //
> +  UINT32  ADDRESS_MISALIGN:    1; //
> +  UINT32  ADDRESS_OUT_OF_RANGE:1; //
> +} CARD_STATUS;
> +
> +typedef struct {
> +  UINT32  CmdSet:              3;
> +  UINT32  Reserved0:           5;
> +  UINT32  Value:               8;
> +  UINT32  Index:               8;
> +  UINT32  Access:              2;
> +  UINT32  Reserved1:           6;
> +} SWITCH_ARGUMENT;
> +
> +#define CommandSet_Mode          0
> +#define SetBits_Mode             1
> +#define ClearBits_Mode           2
> +#define WriteByte_Mode           3
> +
> +
> +#define  Idle_STATE              0
> +#define  Ready_STATE             1
> +#define  Ident_STATE             2
> +#define  Stby_STATE              3
> +#define  Tran_STATE              4
> +#define  Data_STATE              5
> +#define  Rcv_STATE               6
> +#define  Prg_STATE               7
> +#define  Dis_STATE               8
> +#define  Btst_STATE              9
> +
> +
> +
> +#pragma pack()
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/IndustryStandard/SdCard.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/IndustryStandard/SdCard.h
> new file mode 100644
> index 0000000000..62bd6e0823
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/IndustryStandard/SdCard.h
> @@ -0,0 +1,157 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +--*/
> +
> +
> +/*++
> +Module Name:
> +
> +  SDCard.h
> +
> +Abstract:
> +
> +  Header file for Industry SD Card 2.0 spec.
> +
> +--*/
> +
> +#ifndef _SD_CARD_H
> +#define _SD_CARD_H
> +
> +#include "Mmc.h"
> +
> +#pragma pack(1)
> +
> +#define CHECK_PATTERN     0xAA
> +
> +#define ACMD6             6
> +#define ACMD13            13
> +#define ACMD23            23
> +#define ACMD41            41
> +#define ACMD42            42
> +#define ACMD51            51
> +
> +
> +#define SWITCH_FUNC              CMD6
> +#define SEND_IF_COND             CMD8
> +
> +
> +#define SET_BUS_WIDTH            ACMD6
> +#define SD_STATUS                ACMD13
> +#define SET_WR_BLK_ERASE_COUNT   ACMD23
> +#define SD_SEND_OP_COND          ACMD41
> +#define SET_CLR_CARD_DETECT      ACMD42
> +#define SEND_SCR                 ACMD51
> +
> +
> +
> +#define SD_BUS_WIDTH_1              0
> +#define SD_BUS_WIDTH_4              2
> +
> +
> +
> +#define FREQUENCY_SD_PP        (25 * 1000 * 1000)
> +#define FREQUENCY_SD_PP_HIGH   (50 * 1000 * 1000)
> +
> +
> +#define SD_SPEC_10                  0
> +#define SD_SPEC_11                  1
> +#define SD_SPEC_20                  2
> +
> +
> +#define VOLTAGE_27_36               0x1
> +
> +typedef struct {
> +  UINT8   NotUsed:            1; //  1 [0:0]
> +  UINT8   CRC:                7; //  CRC [7:1]
> +  UINT8   ECC:                2; //  ECC code [9:8]
> +  UINT8   FILE_FORMAT:        2; //  File format [11:10]
> +  UINT8   TMP_WRITE_PROTECT:  1; //  Temporary write protection [12:12]
> +  UINT8   PERM_WRITE_PROTECT: 1; //  Permanent write protection [13:13]
> +  UINT8   COPY:               1; //  Copy flag (OTP) [14:14]
> +  UINT8   FILE_FORMAT_GRP:    1; //  File format group [15:15]
> +  UINT16  Reserved0:          5; //  0 [20:16]
> +  UINT16  WRITE_BL_PARTIAL:   1; //  Partial blocks for write allowed [21:21]
> +  UINT16  WRITE_BL_LEN:       4; //  Max. write data block length [25:22]
> +  UINT16  R2W_FACTOR:         3; //  Write speed factor [28:26]
> +  UINT16  DEFAULT_ECC:        2; //  Manufacturer default ECC [30:29]
> +  UINT16  WP_GRP_ENABLE:      1; //  Write protect group enable [31:31]
> +  UINT16  WP_GRP_SIZE:        7; //  Write protect group size [38:32]
> +  UINT16  SECTOR_SIZE:        7; //  Erase sector size [45:39]
> +  UINT16  ERASE_BLK_EN:       1; //  Erase single block enable [46:46]
> +  UINT16  Reserved1:          1; //  0 [47:47]
> +
> +  UINT32  C_SIZE:             22; //  Device size [69:48]
> +  UINT32  Reserved2:          6;  //  0 [75:70]
> +  UINT32  DSR_IMP:            1;  //  DSR implemented [76:76]
> +  UINT32  READ_BLK_MISALIGN:  1;  //  Read block misalignment [77:77]
> +  UINT32  WRITE_BLK_MISALIGN: 1;  //  Write block misalignment [78:78]
> +  UINT32  READ_BL_PARTIAL:    1;  //  Partial blocks for read allowed [79:79]
> +
> +  UINT16  READ_BL_LEN:        4;  //  Max. read data block length [83:80]
> +  UINT16  CCC:                12; //  Card command classes [95:84]
> +  UINT8   TRAN_SPEED          ;   //  Max. bus clock frequency [103:96]
> +  UINT8   NSAC                ;   //  Data read access-time 2 in CLK cycles (NSAC*100)
> [111:104]
> +  UINT8   TAAC                ;   //  Data read access-time 1 [119:112]
> +  UINT8   Reserved3:          6;  //  0 [125:120]
> +  UINT8   CSD_STRUCTURE:      2;  //  CSD structure [127:126]
> +} CSD_SDV2;
> +
> +typedef struct {
> +  UINT32  Reserved0;
> +  UINT32  Reserved1:               16;
> +  UINT32  SD_BUS_WIDTH:            4;
> +  UINT32  SD_SECURITY:             3;
> +  UINT32  DATA_STAT_AFTER_ERASE:   1;
> +  UINT32  SD_SPEC:                 4;
> +  UINT32  SCR_STRUCT:              4;
> +} SCR;
> +
> +
> +typedef struct {
> +  UINT8   Reserved0[50];
> +  UINT8   ERASE_OFFSET:               2;
> +  UINT8   ERASE_TIMEOUT:              6;
> +  UINT16  ERASE_SIZE;
> +  UINT8   Reserved1:                  4;
> +  UINT8   AU_SIZE:                    4;
> +  UINT8   PERFORMANCE_MOVE;
> +  UINT8   SPEED_CLASS;
> +  UINT32  SIZE_OF_PROTECTED_AREA;
> +  UINT32  SD_CARD_TYPE:              16;
> +  UINT32  Reserved2:                 13;
> +  UINT32  SECURED_MODE:               1;
> +  UINT32  DAT_BUS_WIDTH:              2;
> +} SD_STATUS_REG;
> +
> +
> +
> +typedef struct {
> +  UINT8   Reserved0[34];
> +  UINT16  Group1BusyStatus;
> +  UINT16  Group2BusyStatus;
> +  UINT16  Group3BusyStatus;
> +  UINT16  Group4BusyStatus;
> +  UINT16  Group5BusyStatus;
> +  UINT16  Group6BusyStatus;
> +  UINT8   DataStructureVersion;
> +  UINT8   Group21Status;
> +  UINT8   Group43Status;
> +  UINT8   Group65Status;
> +  UINT16  Group1Function;
> +  UINT16  Group2Function;
> +  UINT16  Group3Function;
> +  UINT16  Group4Function;
> +  UINT16  Group5Function;
> +  UINT16  Group6Function;
> +  UINT16  MaxCurrent;
> +} SWITCH_STATUS;
> +
> +
> +#pragma pack()
> +#endif
> +
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Library/I2CLib.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Library/I2CLib.h
> new file mode 100644
> index 0000000000..7df5ff2fef
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Library/I2CLib.h
> @@ -0,0 +1,169 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  I2CRegs.h
> +
> +Abstract:
> +
> +  Register Definitions for I2C Driver/PEIM.
> +
> +--*/
> +#include <Uefi.h>
> +#include <Library/IoLib.h>
> +
> +#ifndef I2C_REGS_A0_H
> +#define I2C_REGS_A0_H
> +
> +//
> +// FIFO write workaround value.
> +//
> +#define FIFO_WRITE_DELAY    2
> +
> +//
> +// MMIO Register Definitions
> +//
> +#define    R_IC_CON                          ( 0x00) // I2C Control
> +#define     B_IC_RESTART_EN                  BIT5
> +#define     B_IC_SLAVE_DISABLE               BIT6
> +#define     V_SPEED_STANDARD                 0x02
> +#define     V_SPEED_FAST                     0x04
> +#define     V_SPEED_HIGH                     0x06
> +#define     B_MASTER_MODE                    BIT0
> +
> +#define    R_IC_TAR                          ( 0x04) // I2C Target Address
> +#define     IC_TAR_10BITADDR_MASTER           BIT12
> +
> +#define    R_IC_SAR                          ( 0x08) // I2C Slave Address
> +#define    R_IC_HS_MADDR                     ( 0x0C) // I2C HS MasterMode Code
> Address
> +#define    R_IC_DATA_CMD                     ( 0x10) // I2C Rx/Tx Data Buffer and
> Command
> +
> +#define    B_READ_CMD                         BIT8    // 1 = read, 0 = write
> +#define    B_CMD_STOP                         BIT9    // 1 = STOP
> +#define    B_CMD_RESTART                      BIT10   // 1 = IC_RESTART_EN
> +
> +#define    V_WRITE_CMD_MASK                  ( 0xFF)
> +
> +#define    R_IC_SS_SCL_HCNT                  ( 0x14) // Standard Speed I2C Clock
> SCL High Count
> +#define    R_IC_SS_SCL_LCNT                  ( 0x18) // Standard Speed I2C Clock
> SCL Low Count
> +#define    R_IC_FS_SCL_HCNT                  ( 0x1C) // Full Speed I2C Clock SCL
> High Count
> +#define    R_IC_FS_SCL_LCNT                  ( 0x20) // Full Speed I2C Clock SCL
> Low Count
> +#define    R_IC_HS_SCL_HCNT                  ( 0x24) // High Speed I2C Clock SCL
> High Count
> +#define    R_IC_HS_SCL_LCNT                  ( 0x28) // High Speed I2C Clock SCL
> Low Count
> +#define    R_IC_INTR_STAT                    ( 0x2C) // I2C Inetrrupt Status
> +#define    R_IC_INTR_MASK                    ( 0x30) // I2C Interrupt Mask
> +#define     I2C_INTR_GEN_CALL                 BIT11  // General call received
> +#define     I2C_INTR_START_DET                BIT10
> +#define     I2C_INTR_STOP_DET                 BIT9
> +#define     I2C_INTR_ACTIVITY                 BIT8
> +#define     I2C_INTR_TX_ABRT                  BIT6   // Set on NACK
> +#define     I2C_INTR_TX_EMPTY                 BIT4
> +#define     I2C_INTR_TX_OVER                  BIT3
> +#define     I2C_INTR_RX_FULL                  BIT2   // Data bytes in RX FIFO over
> threshold
> +#define     I2C_INTR_RX_OVER                  BIT1
> +#define     I2C_INTR_RX_UNDER                 BIT0
> +#define    R_IC_RAW_INTR_STAT                ( 0x34) // I2C Raw Interrupt Status
> +#define    R_IC_RX_TL                        ( 0x38) // I2C Receive FIFO Threshold
> +#define    R_IC_TX_TL                        ( 0x3C) // I2C Transmit FIFO Threshold
> +#define    R_IC_CLR_INTR                     ( 0x40) // Clear Combined and Individual
> Interrupts
> +#define    R_IC_CLR_RX_UNDER                 ( 0x44) // Clear RX_UNDER
> Interrupt
> +#define    R_IC_CLR_RX_OVER                  ( 0x48) // Clear RX_OVERinterrupt
> +#define    R_IC_CLR_TX_OVER                  ( 0x4C) // Clear TX_OVER interrupt
> +#define    R_IC_CLR_RD_REQ                   ( 0x50) // Clear RD_REQ interrupt
> +#define    R_IC_CLR_TX_ABRT                  ( 0x54) // Clear TX_ABRT interrupt
> +#define    R_IC_CLR_RX_DONE                  ( 0x58) // Clear RX_DONE interrupt
> +#define    R_IC_CLR_ACTIVITY                 ( 0x5C) // Clear ACTIVITY interrupt
> +#define    R_IC_CLR_STOP_DET                 ( 0x60) // Clear STOP_DET interrupt
> +#define    R_IC_CLR_START_DET                ( 0x64) // Clear START_DET
> interrupt
> +#define    R_IC_CLR_GEN_CALL                 ( 0x68) // Clear GEN_CALL interrupt
> +#define    R_IC_ENABLE                       ( 0x6C) // I2C Enable
> +#define    R_IC_STATUS                       ( 0x70) // I2C Status
> +
> +#define    R_IC_SDA_HOLD                     ( 0x7C) // I2C
> IC_DEFAULT_SDA_HOLD//16bits
> +
> +#define     STAT_MST_ACTIVITY                 BIT5   // Master FSM Activity Status.
> +#define     STAT_RFF                          BIT4   // RX FIFO is completely full
> +#define     STAT_RFNE                         BIT3   // RX FIFO is not empty
> +#define     STAT_TFE                          BIT2   // TX FIFO is completely empty
> +#define     STAT_TFNF                         BIT1   // TX FIFO is not full
> +
> +#define    R_IC_TXFLR                        ( 0x74) // Transmit FIFO Level Register
> +#define    R_IC_RXFLR                        ( 0x78) // Receive FIFO Level Register
> +#define    R_IC_TX_ABRT_SOURCE               ( 0x80) // I2C Transmit Abort
> Status Register
> +#define    R_IC_SLV_DATA_NACK_ONLY           ( 0x84) // Generate
> SLV_DATA_NACK Register
> +#define    R_IC_DMA_CR                       ( 0x88) // DMA Control Register
> +#define    R_IC_DMA_TDLR                     ( 0x8C) // DMA Transmit Data Level
> +#define    R_IC_DMA_RDLR                     ( 0x90) // DMA Receive Data Level
> +#define    R_IC_SDA_SETUP                    ( 0x94) // I2C SDA Setup Register
> +#define    R_IC_ACK_GENERAL_CALL             ( 0x98) // I2C ACK General Call
> Register
> +#define    R_IC_ENABLE_STATUS                ( 0x9C) // I2C Enable Status
> Register
> +#define    R_IC_COMP_PARAM                   ( 0xF4) // Component Parameter
> Register
> +#define    R_IC_COMP_VERSION                 ( 0xF8) // Component Version ID
> +#define    R_IC_COMP_TYPE                    ( 0xFC) // Component Type
> +
> +#define    R_IC_CLK_GATE                     ( 0xC0) // Clock Gate
> +
> +#define    I2C_SS_SCL_HCNT_VALUE_100M        0x1DD
> +#define    I2C_SS_SCL_LCNT_VALUE_100M        0x1E4
> +#define    I2C_FS_SCL_HCNT_VALUE_100M        0x54
> +#define    I2C_FS_SCL_LCNT_VALUE_100M        0x9a
> +#define    I2C_HS_SCL_HCNT_VALUE_100M        0x7
> +#define    I2C_HS_SCL_LCNT_VALUE_100M        0xE
> +
> +#define     IC_TAR_10BITADDR_MASTER           BIT12
> +#define     FIFO_SIZE                         32
> +#define     R_IC_INTR_STAT                    ( 0x2C) // I2c Inetrrupt Status
> +#define     R_IC_INTR_MASK                    ( 0x30) // I2c Interrupt Mask
> +#define     I2C_INTR_GEN_CALL                 BIT11  // General call received
> +#define     I2C_INTR_START_DET                BIT10
> +#define     I2C_INTR_STOP_DET                 BIT9
> +#define     I2C_INTR_ACTIVITY                 BIT8
> +#define     I2C_INTR_TX_ABRT                  BIT6   // Set on NACK
> +#define     I2C_INTR_TX_EMPTY                 BIT4
> +#define     I2C_INTR_TX_OVER                  BIT3
> +#define     I2C_INTR_RX_FULL                  BIT2   // Data bytes in RX FIFO over
> threshold
> +#define     I2C_INTR_RX_OVER                  BIT1
> +#define     I2C_INTR_RX_UNDER                 BIT0
> +
> +EFI_STATUS ProgramPciLpssI2C (
> +  IN  UINT8 BusNo
> +  );
> +EFI_STATUS ByteReadI2C_Basic(
> +  IN  UINT8 BusNo,
> +  IN  UINT8 SlaveAddress,
> +  IN  UINTN ReadBytes,
> +  OUT UINT8 *ReadBuffer,
> +  IN  UINT8 Start,
> +  IN  UINT8 End
> +  );
> +EFI_STATUS ByteWriteI2C_Basic(
> +  IN  UINT8 BusNo,
> +  IN  UINT8 SlaveAddress,
> +  IN  UINTN WriteBytes,
> +  IN  UINT8 *WriteBuffer,
> +  IN  UINT8 Start,
> +  IN  UINT8 End
> +  );
> +
> +EFI_STATUS ByteReadI2C(
> +  IN  UINT8 BusNo,
> +  IN  UINT8 SlaveAddress,
> +  IN  UINT8 Offset,
> +  IN  UINTN ReadBytes,
> +  OUT UINT8 *ReadBuffer
> +  );
> +EFI_STATUS ByteWriteI2C(
> +  IN  UINT8 BusNo,
> +  IN  UINT8 SlaveAddress,
> +  IN  UINT8 Offset,
> +  IN  UINTN WriteBytes,
> +  IN  UINT8 *WriteBuffer
> +  );
> +
> +#endif  // I2C_REGS_A0_H
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Library/PchPlatformLib.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Library/PchPlatformLib.h
> new file mode 100644
> index 0000000000..f6593324a9
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Library/PchPlatformLib.h
> @@ -0,0 +1,115 @@
> +/**
> +**/
> +/**
> +
> +Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +  @file
> +  PchPlatformLib.h
> +
> +  @brief
> +  Header file for PchPlatform Lib.
> +
> +**/
> +#ifndef _PCH_PLATFORM_LIB_H_
> +#define _PCH_PLATFORM_LIB_H_
> +
> +///
> +/// Timeout value used when Sending / Receiving messages.
> +/// NOTE: this must cover the longest possible wait time
> +/// between message being sent and response being available.
> +/// e.g. Virtual function readiness might take some time.
> +///
> +VOID
> +EFIAPI
> +PchPmTimerStall (
> +  IN  UINTN   Microseconds
> +  )
> +/**
> +
> +  @brief
> +  Delay for at least the request number of microseconds.
> +  This function would be called by runtime driver, please do not use any
> MMIO marco here.
> +
> +  @param[in] Microseconds         Number of microseconds to delay.
> +
> +  @retval NONE
> +
> +**/
> +;
> +
> +BOOLEAN
> +EFIAPI
> +PchIsSpiDescriptorMode (
> +  IN  UINTN   SpiBase
> +  )
> +/**
> +
> +  @brief
> +  Check whether SPI is in descriptor mode
> +
> +  @param[in] SpiBase              The PCH Spi Base Address
> +
> +  @retval TRUE                    SPI is in descriptor mode
> +  @retval FALSE                   SPI is not in descriptor mode
> +
> +**/
> +;
> +
> +PCH_STEPPING
> +EFIAPI
> +PchStepping (
> +  VOID
> +  )
> +/**
> +
> +  @brief
> +  Return Pch stepping type
> +
> +  @param[in] None
> +
> +  @retval PCH_STEPPING            Pch stepping type
> +
> +**/
> +;
> +
> +BOOLEAN
> +IsPchSupported (
> +  VOID
> +  )
> +/**
> +
> +  @brief
> +  Determine if PCH is supported
> +
> +  @param[in] None
> +
> +  @retval TRUE                    PCH is supported
> +  @retval FALSE                   PCH is not supported
> +
> +**/
> +;
> +
> +VOID
> +EFIAPI
> +PchAlternateAccessMode (
> +  IN  UINTN         IlbBase,
> +  IN  BOOLEAN       AmeCtrl
> +  )
> +/**
> +
> +  This function can be called to enable/disable Alternate Access Mode
> +
> +  @param[in] IlbBase              The PCH ILB Base Address
> +  @param[in] AmeCtrl              If TRUE, enable Alternate Access Mode.
> +                                  If FALSE, disable Alternate Access Mode.
> +
> +  @retval NONE
> +
> +**/
> +;
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchAccess.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchAccess.h
> new file mode 100644
> index 0000000000..d7988c55be
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchAccess.h
> @@ -0,0 +1,471 @@
> +/**
> +
> +Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +  @file
> +  PchAccess.h
> +
> +  @brief
> +  Macros that simplify accessing PCH devices's PCI registers.
> +
> +  ** NOTE ** these macros assume the PCH device is on BUS 0
> +
> +**/
> +#ifndef _PCH_ACCESS_H_
> +#define _PCH_ACCESS_H_
> +
> +#include "PchRegs.h"
> +#include "PchCommonDefinitions.h"
> +
> +#ifndef STALL_ONE_MICRO_SECOND
> +#define STALL_ONE_MICRO_SECOND 1
> +#endif
> +#ifndef STALL_ONE_SECOND
> +#define STALL_ONE_SECOND 1000000
> +#endif
> +
> +///
> +/// Memory Mapped PCI Access macros
> +///
> +///
> +/// PCI Device MM Base
> +///
> +#ifndef MmPciAddress
> +#define MmPciAddress(Segment, Bus, Device, Function, Register) \
> +  ((UINTN) PatchPcdGet64 (PcdPciExpressBaseAddress) + \
> +   (UINTN) (Bus << 20) + \
> +   (UINTN) (Device << 15) + \
> +   (UINTN) (Function << 12) + \
> +   (UINTN) (Register) \
> +  )
> +#endif
> +///
> +/// Pch Controller PCI access macros
> +///
> +#define PCH_RCRB_BASE ( \
> +  MmioRead32 (MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_LPC, \
> +  PCI_FUNCTION_NUMBER_PCH_LPC), \
> +  R_PCH_LPC_RCBA)) & B_PCH_LPC_RCBA_BAR \
> +  )
> +
> +///
> +/// Device 0x1b, Function 0
> +///
> +#define PchAzaliaPciCfg32(Register) \
> +  MmioRead32 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_AZALIA, \
> +  0, \
> +  Register) \
> +  )
> +
> +#define PchAzaliaPciCfg32Or(Register, OrData) \
> +  MmioOr32 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_AZALIA, \
> +  0, \
> +  Register), \
> +  OrData \
> +  )
> +
> +#define PchAzaliaPciCfg32And(Register, AndData) \
> +  MmioAnd32 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_AZALIA, \
> +  0, \
> +  Register), \
> +  AndData \
> +  )
> +
> +#define PchAzaliaPciCfg32AndThenOr(Register, AndData, OrData) \
> +  MmioAndThenOr32 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_AZALIA, \
> +  0, \
> +  Register), \
> +  OrData \
> +  )
> +
> +#define PchAzaliaPciCfg16(Register) \
> +  MmioRead16 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_AZALIA, \
> +  0, \
> +  Register) \
> +  )
> +
> +#define PchAzaliaPciCfg16Or(Register, OrData) \
> +  MmioOr16 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_AZALIA, \
> +  0, \
> +  Register), \
> +  OrData \
> +  )
> +
> +#define PchAzaliaPciCfg16And(Register, AndData) \
> +  MmioAnd16 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_AZALIA, \
> +  0, \
> +  Register), \
> +  AndData \
> +  )
> +
> +#define PchAzaliaPciCfg16AndThenOr(Register, AndData, OrData) \
> +  MmioAndThenOr16 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_AZALIA, \
> +  0, \
> +  Register), \
> +  AndData, \
> +  OrData \
> +  )
> +
> +#define PchAzaliaPciCfg8(Register)  MmioRead8 (MmPciAddress (0,
> DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_AZALIA, 0,
> Register))
> +
> +#define PchAzaliaPciCfg8Or(Register, OrData) \
> +  MmioOr8 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_AZALIA, \
> +  0, \
> +  Register), \
> +  OrData \
> +  )
> +
> +#define PchAzaliaPciCfg8And(Register, AndData) \
> +  MmioAnd8 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_AZALIA, \
> +  0, \
> +  Register), \
> +  AndData \
> +  )
> +
> +#define PchAzaliaPciCfg8AndThenOr(Register, AndData, OrData) \
> +  MmioAndThenOr8 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_AZALIA, \
> +  0, \
> +  Register), \
> +  AndData, \
> +  OrData \
> +  )
> +
> +///
> +/// Device 0x1f, Function 0
> +///
> +#define PchLpcPciCfg32(Register)  MmioRead32 (MmPciAddress (0,
> DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0,
> Register))
> +
> +#define PchLpcMmioOr32 (Register, OrData) \
> +  MmioOr32 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_LPC, \
> +  0, \
> +  Register), \
> +  OrData \
> +  )
> +
> +#define PchLpcPciCfg32And(Register, AndData) \
> +  MmioAnd32 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_LPC, \
> +  0, \
> +  Register), \
> +  AndData \
> +  )
> +
> +#define PchLpcPciCfg32AndThenOr(Register, AndData, OrData) \
> +  MmioAndThenOr32 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_LPC, \
> +  0, \
> +  Register), \
> +  AndData, \
> +  OrData \
> +  )
> +
> +#define PchLpcPciCfg16(Register)  MmioRead16 (MmPciAddress (0,
> DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0,
> Register))
> +
> +#define PchLpcPciCfg16Or(Register, OrData) \
> +  MmioOr16 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_LPC, \
> +  0, \
> +  Register), \
> +  OrData \
> +  )
> +
> +#define PchLpcPciCfg16And(Register, AndData) \
> +  MmioAndThenOr16 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_LPC, \
> +  0, \
> +  Register), \
> +  AndData \
> +  )
> +
> +#define PchLpcPciCfg16AndThenOr(Register, AndData, OrData) \
> +  MmioAndThenOr16 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_LPC, \
> +  0, \
> +  Register), \
> +  AndData, \
> +  OrData \
> +  )
> +
> +#define PchLpcPciCfg8(Register) MmioRead8 (MmPciAddress (0,
> DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0,
> Register))
> +
> +#define PchLpcPciCfg8Or(Register, OrData) \
> +  MmioOr8 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_LPC, \
> +  0, \
> +  Register), \
> +  OrData \
> +  )
> +
> +#define PchLpcPciCfg8And(Register, AndData) \
> +  MmioAnd8 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_LPC, \
> +  0, \
> +  Register), \
> +  AndData \
> +  )
> +
> +#define PchLpcPciCfg8AndThenOr(Register, AndData, OrData) \
> +  MmioAndThenOr8 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_LPC, \
> +  0, \
> +  Register), \
> +  AndData, \
> +  OrData \
> +  )
> +
> +
> +///
> +/// SATA device 0x13, Function 0
> +///
> +#define PchSataPciCfg32(Register) MmioRead32 (MmPciAddress (0,
> DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SATA,
> PCI_FUNCTION_NUMBER_PCH_SATA, Register))
> +
> +#define PchSataPciCfg32Or(Register, OrData) \
> +  MmioOr32 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_SATA, \
> +  PCI_FUNCTION_NUMBER_PCH_SATA, \
> +  Register), \
> +  OrData \
> +  )
> +
> +#define PchSataPciCfg32And(Register, AndData) \
> +  MmioAnd32 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_SATA, \
> +  PCI_FUNCTION_NUMBER_PCH_SATA, \
> +  Register), \
> +  AndData \
> +  )
> +
> +#define PchSataPciCfg32AndThenOr(Register, AndData, OrData) \
> +  MmioAndThenOr32 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_SATA, \
> +  PCI_FUNCTION_NUMBER_PCH_SATA, \
> +  Register), \
> +  AndData, \
> +  OrData \
> +  )
> +
> +#define PchSataPciCfg16(Register) MmioRead16 (MmPciAddress (0,
> DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SATA,
> PCI_FUNCTION_NUMBER_PCH_SATA, Register))
> +
> +#define PchSataPciCfg16Or(Register, OrData) \
> +  MmioOr16 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_SATA, \
> +  PCI_FUNCTION_NUMBER_PCH_SATA, \
> +  Register), \
> +  OrData \
> +  )
> +
> +#define PchSataPciCfg16And(Register, AndData) \
> +  MmioAndThenOr16 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_SATA, \
> +  PCI_FUNCTION_NUMBER_PCH_SATA, \
> +  Register), \
> +  AndData \
> +  )
> +
> +#define PchSataPciCfg16AndThenOr(Register, AndData, OrData) \
> +  MmioAndThenOr16 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_SATA, \
> +  PCI_FUNCTION_NUMBER_PCH_SATA, \
> +  Register), \
> +  AndData, \
> +  OrData \
> +  )
> +
> +#define PchSataPciCfg8(Register)  MmioRead8 (MmPciAddress (0,
> DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SATA,
> PCI_FUNCTION_NUMBER_PCH_SATA, Register))
> +
> +#define PchSataPciCfg8Or(Register, OrData) \
> +  MmioOr8 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_SATA, \
> +  PCI_FUNCTION_NUMBER_PCH_SATA, \
> +  Register), \
> +  OrData \
> +  )
> +
> +#define PchSataPciCfg8And(Register, AndData) \
> +  MmioAnd8 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_SATA, \
> +  PCI_FUNCTION_NUMBER_PCH_SATA, \
> +  Register), \
> +  AndData \
> +  )
> +
> +#define PchSataPciCfg8AndThenOr(Register, AndData, OrData) \
> +  MmioAndThenOr8 ( \
> +  MmPciAddress (0, \
> +  DEFAULT_PCI_BUS_NUMBER_PCH, \
> +  PCI_DEVICE_NUMBER_PCH_SATA, \
> +  PCI_FUNCTION_NUMBER_PCH_SATA, \
> +  Register), \
> +  AndData, \
> +  OrData \
> +  )
> +
> +
> +///
> +/// Root Complex Register Block
> +///
> +#define PchMmRcrb32(Register)                           MmioRead32
> (PCH_RCRB_BASE + Register)
> +
> +#define PchMmRcrb32Or(Register, OrData)                 MmioOr32
> (PCH_RCRB_BASE + Register, OrData)
> +
> +#define PchMmRcrb32And(Register, AndData)               MmioAnd32
> (PCH_RCRB_BASE + Register, AndData)
> +
> +#define PchMmRcrb32AndThenOr(Register, AndData, OrData)
> MmioAndThenOr32 (PCH_RCRB_BASE + Register, AndData, OrData)
> +
> +#define PchMmRcrb16(Register)                           MmioRead16
> (PCH_RCRB_BASE + Register)
> +
> +#define PchMmRcrb16Or(Register, OrData)                 MmioOr16
> (PCH_RCRB_BASE + Register, OrData)
> +
> +#define PchMmRcrb16And(Register, AndData)               MmioAnd16
> (PCH_RCRB_BASE + Register, AndData)
> +
> +#define PchMmRcrb16AndThenOr(Register, AndData, OrData)
> MmioAndThenOr16 (PCH_RCRB_BASE + Register, AndData, OrData)
> +
> +#define PchMmRcrb8(Register)                            MmioRead8 (PCH_RCRB_BASE
> + Register)
> +
> +#define PchMmRcrb8Or(Register, OrData)                  MmioOr8
> (PCH_RCRB_BASE + Register, OrData)
> +
> +#define PchMmRcrb8And(Register, AndData)                MmioAnd8
> (PCH_RCRB_BASE + Register, AndData)
> +
> +#define PchMmRcrb8AndThenOr(Register, AndData, OrData)
> MmioAndThenOr8 (PCH_RCRB_BASE + Register, AndData, OrData)
> +
> +
> +///
> +/// Message Bus
> +///
> +
> +///
> +/// Message Bus Registers
> +///
> +#define MC_MCR            0x000000D0 // Cunit Message Control Register
> +#define MC_MDR            0x000000D4 // Cunit Message Data Register
> +#define MC_MCRX           0x000000D8 // Cunit Message Control Register
> Extension
> +
> +///
> +/// Message Bus API
> +///
> +#define MSG_BUS_ENABLED   0x000000F0
> +#define MSGBUS_MASKHI     0xFFFFFF00
> +#define MSGBUS_MASKLO     0x000000FF
> +#define MESSAGE_DWORD_EN  BIT4 | BIT5 | BIT6 | BIT7
> +
> +#define PchMsgBusRead32(PortId, Register, Dbuff, ReadOpCode,
> WriteOpCode) \
> +{ \
> +  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) +
> MC_MCRX), (UINT32) (Register & MSGBUS_MASKHI)); \
> +  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) +
> MC_MCR ), (UINT32) ((ReadOpCode << 24) | (PortId << 16) | ((Register &
> MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN)); \
> +  (Dbuff) = MmioRead32 ((UINTN) (PatchPcdGet64
> (PcdPciExpressBaseAddress) + MC_MDR)); \
> +}
> +
> +#define PchMsgBusAnd32(PortId, Register, Dbuff, AndData, ReadOpCode,
> WriteOpCode) \
> +{ \
> +  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) +
> MC_MCRX), (UINT32) (Register & MSGBUS_MASKHI)); \
> +  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) +
> MC_MCR ), (UINT32) ((ReadOpCode << 24) | (PortId << 16) | ((Register &
> MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN)); \
> +  (Dbuff) = MmioRead32 ((UINTN) (PatchPcdGet64
> (PcdPciExpressBaseAddress) + MC_MDR)); \
> +  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) +
> MC_MCRX), (UINT32) (Register & MSGBUS_MASKHI)); \
> +  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) +
> MC_MDR ), (UINT32) (Dbuff & AndData)); \
> +  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) +
> MC_MCR ), (UINT32) ((WriteOpCode << 24) | (PortId << 16) | ((Register &
> MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN)); \
> +}
> +
> +#define PchMsgBusOr32(PortId, Register, Dbuff, OrData, ReadOpCode,
> WriteOpCode) \
> +{ \
> +  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) +
> MC_MCRX), (UINT32) (Register & MSGBUS_MASKHI)); \
> +  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) +
> MC_MCR ), (UINT32) ((ReadOpCode << 24) | (PortId << 16) | ((Register &
> MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN)); \
> +  (Dbuff) = MmioRead32 ((UINTN) (PatchPcdGet64
> (PcdPciExpressBaseAddress) + MC_MDR)); \
> +  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) +
> MC_MCRX), (UINT32) (Register & MSGBUS_MASKHI)); \
> +  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) +
> MC_MDR ), (UINT32) (Dbuff | OrData)); \
> +  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) +
> MC_MCR ), (UINT32) ((WriteOpCode << 24) | (PortId << 16) | ((Register &
> MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN)); \
> +}
> +
> +#define PchMsgBusAndThenOr32(PortId, Register, Dbuff, AndData, OrData,
> ReadOpCode, WriteOpCode) \
> +{ \
> +  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) +
> MC_MCRX), (UINT32) (Register & MSGBUS_MASKHI)); \
> +  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) +
> MC_MCR ), (UINT32) ((ReadOpCode << 24) | (PortId << 16) | ((Register &
> MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN)); \
> +  (Dbuff) = MmioRead32 ((UINTN) (PatchPcdGet64
> (PcdPciExpressBaseAddress) + MC_MDR)); \
> +  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) +
> MC_MCRX), (UINT32) (Register & MSGBUS_MASKHI)); \
> +  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) +
> MC_MDR ), (UINT32) ((Dbuff & AndData) | OrData)); \
> +  MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) +
> MC_MCR ), (UINT32) ((WriteOpCode << 24) | (PortId << 16) | ((Register &
> MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN)); \
> +}
> +
> +typedef struct _PCH_MSG_BUS_TABLE_STRUCT {
> +  UINT32      PortId;
> +  UINT32      Address;
> +  UINT32      AndMask;
> +  UINT32      OrMask;
> +  UINT32      ReadOpCode;
> +  UINT32      WriteOpCode;
> +} PCH_MSG_BUS_TABLE_STRUCT_TABLE_STRUCT;
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchCommonDefinitions.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchCommonDefinitions.h
> new file mode 100644
> index 0000000000..c12f0d2195
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchCommonDefinitions.h
> @@ -0,0 +1,210 @@
> +/*++
> +
> +Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  PchCommonDefinitions.h
> +
> +Abstract:
> +
> +  This header file provides common definitions for PCH
> +
> +--*/
> +#ifndef _PCH_COMMON_DEFINITIONS_H_
> +#define _PCH_COMMON_DEFINITIONS_H_
> +
> +//
> +//  MMIO access macros
> +//
> +#define PchMmioAddress(BaseAddr, Register)  ((UINTN) BaseAddr +
> (UINTN) (Register))
> +
> +//
> +// 32 bit MMIO access
> +//
> +#define PchMmio32Ptr(BaseAddr, Register)  ((volatile UINT32 *)
> PchMmioAddress (BaseAddr, Register))
> +
> +#define PchMmio32(BaseAddr, Register)     *PchMmio32Ptr (BaseAddr,
> Register)
> +
> +#define PchMmio32Or(BaseAddr, Register, OrData) \
> +  PchMmio32 (BaseAddr, Register) = (UINT32) \
> +    (PchMmio32 (BaseAddr, Register) | (UINT32) (OrData))
> +
> +#define PchMmio32And(BaseAddr, Register, AndData) \
> +  PchMmio32 (BaseAddr, Register) = (UINT32) \
> +    (PchMmio32 (BaseAddr, Register) & (UINT32) (AndData))
> +
> +#define PchMmio32AndThenOr(BaseAddr, Register, AndData, OrData) \
> +  PchMmio32 (BaseAddr, Register) = (UINT32) \
> +    ((PchMmio32 (BaseAddr, Register) & (UINT32) (AndData)) | (UINT32)
> (OrData))
> +
> +//
> +// 16 bit MMIO access
> +//
> +#define PchMmio16Ptr(BaseAddr, Register)  ((volatile UINT16 *)
> PchMmioAddress (BaseAddr, Register))
> +
> +#define PchMmio16(BaseAddr, Register)     *PchMmio16Ptr (BaseAddr,
> Register)
> +
> +#define PchMmio16Or(BaseAddr, Register, OrData) \
> +  PchMmio16 (BaseAddr, Register) = (UINT16) \
> +    (PchMmio16 (BaseAddr, Register) | (UINT16) (OrData))
> +
> +#define PchMmio16And(BaseAddr, Register, AndData) \
> +  PchMmio16 (BaseAddr, Register) = (UINT16) \
> +    (PchMmio16 (BaseAddr, Register) & (UINT16) (AndData))
> +
> +#define PchMmio16AndThenOr(BaseAddr, Register, AndData, OrData) \
> +  PchMmio16 (BaseAddr, Register) = (UINT16) \
> +    ((PchMmio16 (BaseAddr, Register) & (UINT16) (AndData)) | (UINT16)
> (OrData))
> +
> +//
> +// 8 bit MMIO access
> +//
> +#define PchMmio8Ptr(BaseAddr, Register) ((volatile UINT8 *)
> PchMmioAddress (BaseAddr, Register))
> +
> +#define PchMmio8(BaseAddr, Register)    *PchMmio8Ptr (BaseAddr,
> Register)
> +
> +#define PchMmio8Or(BaseAddr, Register, OrData) \
> +  PchMmio8 (BaseAddr, Register) = (UINT8) \
> +    (PchMmio8 (BaseAddr, Register) | (UINT8) (OrData))
> +
> +#define PchMmio8And(BaseAddr, Register, AndData) \
> +  PchMmio8 (BaseAddr, Register) = (UINT8) \
> +    (PchMmio8 (BaseAddr, Register) & (UINT8) (AndData))
> +
> +#define PchMmio8AndThenOr(BaseAddr, Register, AndData, OrData) \
> +  PchMmio8 (BaseAddr, Register) = (UINT8) \
> +    ((PchMmio8 (BaseAddr, Register) & (UINT8) (AndData)) | (UINT8)
> (OrData))
> +
> +//
> +// Memory Mapped PCI Access macros
> +//
> +#define PCH_PCI_EXPRESS_BASE_ADDRESS  0xE0000000
> +//
> +// PCI Device MM Base
> +//
> +#define PchPciDeviceMmBase(Bus, Device, Function) \
> +    ( \
> +      (UINTN) PCH_PCI_EXPRESS_BASE_ADDRESS + (UINTN) (Bus << 20) +
> (UINTN) (Device << 15) + (UINTN) \
> +        (Function << 12) \
> +    )
> +
> +//
> +// PCI Device MM Address
> +//
> +#define PchPciDeviceMmAddress(Segment, Bus, Device, Function, Register)
> \
> +    ( \
> +      (UINTN) PCH_PCI_EXPRESS_BASE_ADDRESS + (UINTN) (Bus << 20) +
> (UINTN) (Device << 15) + (UINTN) \
> +        (Function << 12) + (UINTN) (Register) \
> +    )
> +
> +//
> +// 32 bit PCI access
> +//
> +#define PchMmPci32Ptr(Segment, Bus, Device, Function, Register) \
> +    ((volatile UINT32 *) PchPciDeviceMmAddress (Segment, Bus, Device,
> Function, Register))
> +
> +#define PchMmPci32(Segment, Bus, Device, Function, Register)
> *PchMmPci32Ptr (Segment, Bus, Device, Function, Register)
> +
> +#define PchMmPci32Or(Segment, Bus, Device, Function, Register, OrData) \
> +  PchMmPci32 ( \
> +  Segment, \
> +  Bus, \
> +  Device, \
> +  Function, \
> +  Register \
> +  ) = (UINT32) (PchMmPci32 (Segment, Bus, Device, Function, Register) |
> (UINT32) (OrData))
> +
> +#define PchMmPci32And(Segment, Bus, Device, Function, Register,
> AndData) \
> +  PchMmPci32 ( \
> +  Segment, \
> +  Bus, \
> +  Device, \
> +  Function, \
> +  Register \
> +  ) = (UINT32) (PchMmPci32 (Segment, Bus, Device, Function, Register) &
> (UINT32) (AndData))
> +
> +#define PchMmPci32AndThenOr(Segment, Bus, Device, Function, Register,
> AndData, OrData) \
> +  PchMmPci32 ( \
> +  Segment, \
> +  Bus, \
> +  Device, \
> +  Function, \
> +  Register \
> +  ) = (UINT32) ((PchMmPci32 (Segment, Bus, Device, Function, Register) &
> (UINT32) (AndData)) | (UINT32) (OrData))
> +
> +//
> +// 16 bit PCI access
> +//
> +#define PchMmPci16Ptr(Segment, Bus, Device, Function, Register) \
> +    ((volatile UINT16 *) PchPciDeviceMmAddress (Segment, Bus, Device,
> Function, Register))
> +
> +#define PchMmPci16(Segment, Bus, Device, Function, Register)
> *PchMmPci16Ptr (Segment, Bus, Device, Function, Register)
> +
> +#define PchMmPci16Or(Segment, Bus, Device, Function, Register, OrData) \
> +  PchMmPci16 ( \
> +  Segment, \
> +  Bus, \
> +  Device, \
> +  Function, \
> +  Register \
> +  ) = (UINT16) (PchMmPci16 (Segment, Bus, Device, Function, Register) |
> (UINT16) (OrData))
> +
> +#define PchMmPci16And(Segment, Bus, Device, Function, Register,
> AndData) \
> +  PchMmPci16 ( \
> +  Segment, \
> +  Bus, \
> +  Device, \
> +  Function, \
> +  Register \
> +  ) = (UINT16) (PchMmPci16 (Segment, Bus, Device, Function, Register) &
> (UINT16) (AndData))
> +
> +#define PchMmPci16AndThenOr(Segment, Bus, Device, Function, Register,
> AndData, OrData) \
> +  PchMmPci16 ( \
> +  Segment, \
> +  Bus, \
> +  Device, \
> +  Function, \
> +  Register \
> +  ) = (UINT16) ((PchMmPci16 (Segment, Bus, Device, Function, Register) &
> (UINT16) (AndData)) | (UINT16) (OrData))
> +
> +//
> +// 8 bit PCI access
> +//
> +#define PchMmPci8Ptr(Segment, Bus, Device, Function, Register) \
> +    ((volatile UINT8 *) PchPciDeviceMmAddress (Segment, Bus, Device,
> Function, Register))
> +
> +#define PchMmPci8(Segment, Bus, Device, Function, Register)
> *PchMmPci8Ptr (Segment, Bus, Device, Function, Register)
> +
> +#define PchMmPci8Or(Segment, Bus, Device, Function, Register, OrData) \
> +  PchMmPci8 ( \
> +  Segment, \
> +  Bus, \
> +  Device, \
> +  Function, \
> +  Register \
> +  ) = (UINT8) (PchMmPci8 (Segment, Bus, Device, Function, Register) |
> (UINT8) (OrData))
> +
> +#define PchMmPci8And(Segment, Bus, Device, Function, Register, AndData)
> \
> +  PchMmPci8 ( \
> +  Segment, \
> +  Bus, \
> +  Device, \
> +  Function, \
> +  Register \
> +  ) = (UINT8) (PchMmPci8 (Segment, Bus, Device, Function, Register) &
> (UINT8) (AndData))
> +
> +#define PchMmPci8AndThenOr(Segment, Bus, Device, Function, Register,
> AndData, OrData) \
> +  PchMmPci8 ( \
> +  Segment, \
> +  Bus, \
> +  Device, \
> +  Function, \
> +  Register \
> +  ) = (UINT8) ((PchMmPci8 (Segment, Bus, Device, Function, Register) &
> (UINT8) (AndData)) | (UINT8) (OrData))
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs.h
> new file mode 100644
> index 0000000000..3314b9dcf7
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs.h
> @@ -0,0 +1,205 @@
> +/**
> +
> +Copyright (c) 2011  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +  @file
> +  PchRegs.h
> +
> +  @brief
> +  Register names for VLV SC.
> +
> +  Conventions:
> +
> +  - Prefixes:
> +    Definitions beginning with "R_" are registers
> +    Definitions beginning with "B_" are bits within registers
> +    Definitions beginning with "V_" are meaningful values of bits within the
> registers
> +    Definitions beginning with "S_" are register sizes
> +    Definitions beginning with "N_" are the bit position
> +  - In general, PCH registers are denoted by "_PCH_" in register names
> +  - Registers / bits that are different between PCH generations are denoted
> by
> +    "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_VLV_"
> +  - Registers / bits that are different between SKUs are denoted by
> "_<SKU_name>"
> +    at the end of the register/bit names
> +  - Registers / bits of new devices introduced in a PCH generation will be just
> named
> +    as "_PCH_" without <generation_name> inserted.
> +
> +**/
> +#ifndef _PCH_REGS_H_
> +#define _PCH_REGS_H_
> +
> +///
> +/// Bit Definitions. BUGBUG: drive these definitions to code base. Should
> not need
> +/// to be part of chipset modules
> +///
> +#ifndef BIT0
> +#define BIT0  0x0001
> +#define BIT1  0x0002
> +#define BIT2  0x0004
> +#define BIT3  0x0008
> +#define BIT4  0x0010
> +#define BIT5  0x0020
> +#define BIT6  0x0040
> +#define BIT7  0x0080
> +#define BIT8  0x0100
> +#define BIT9  0x0200
> +#define BIT10 0x0400
> +#define BIT11 0x0800
> +#define BIT12 0x1000
> +#define BIT13 0x2000
> +#define BIT14 0x4000
> +#define BIT15 0x8000
> +#define BIT16 0x00010000
> +#define BIT17 0x00020000
> +#define BIT18 0x00040000
> +#define BIT19 0x00080000
> +#define BIT20 0x00100000
> +#define BIT21 0x00200000
> +#define BIT22 0x00400000
> +#define BIT23 0x00800000
> +#define BIT24 0x01000000
> +#define BIT25 0x02000000
> +#define BIT26 0x04000000
> +#define BIT27 0x08000000
> +#define BIT28 0x10000000
> +#define BIT29 0x20000000
> +#define BIT30 0x40000000
> +#define BIT31 0x80000000
> +#define BIT32 0x100000000
> +#define BIT33 0x200000000
> +#define BIT34 0x400000000
> +#define BIT35 0x800000000
> +#define BIT36 0x1000000000
> +#define BIT37 0x2000000000
> +#define BIT38 0x4000000000
> +#define BIT39 0x8000000000
> +#define BIT40 0x10000000000
> +#define BIT41 0x20000000000
> +#define BIT42 0x40000000000
> +#define BIT43 0x80000000000
> +#define BIT44 0x100000000000
> +#define BIT45 0x200000000000
> +#define BIT46 0x400000000000
> +#define BIT47 0x800000000000
> +#define BIT48 0x1000000000000
> +#define BIT49 0x2000000000000
> +#define BIT50 0x4000000000000
> +#define BIT51 0x8000000000000
> +#define BIT52 0x10000000000000
> +#define BIT53 0x20000000000000
> +#define BIT54 0x40000000000000
> +#define BIT55 0x80000000000000
> +#define BIT56 0x100000000000000
> +#define BIT57 0x200000000000000
> +#define BIT58 0x400000000000000
> +#define BIT59 0x800000000000000
> +#define BIT60 0x1000000000000000
> +#define BIT61 0x2000000000000000
> +#define BIT62 0x4000000000000000
> +#define BIT63 0x8000000000000000
> +#endif
> +///
> +/// The default PCH PCI bus number
> +///
> +#define DEFAULT_PCI_BUS_NUMBER_PCH  0
> +
> +///
> +/// Default Vendor ID and Subsystem ID
> +///
> +#define V_PCH_INTEL_VENDOR_ID   0x8086
> +#define V_PCH_DEFAULT_SID       0x7270
> +#define V_PCH_DEFAULT_SVID_SID  (V_PCH_INTEL_VENDOR_ID +
> (V_PCH_DEFAULT_SID << 16))
> +
> +///
> +/// Include device register definitions
> +///
> +#include "PchRegs/PchRegsHda.h"
> +#include "PchRegs/PchRegsLpss.h"
> +#include "PchRegs/PchRegsPcie.h"
> +#include "PchRegs/PchRegsPcu.h"
> +#include "PchRegs/PchRegsRcrb.h"
> +#include "PchRegs/PchRegsSata.h"
> +#include "PchRegs/PchRegsScc.h"
> +#include "PchRegs/PchRegsSmbus.h"
> +#include "PchRegs/PchRegsSpi.h"
> +#include "PchRegs/PchRegsUsb.h"
> +//#include "PchRegs/PchRegsLpe.h"
> +
> +///
> +/// Device IDS that are PCH Server specific
> +///
> +#define IS_PCH_DEVICE_ID(DeviceId) \
> +    ( \
> +      (DeviceId == V_PCH_LPC_DEVICE_ID_0) || \
> +      (DeviceId == V_PCH_LPC_DEVICE_ID_1) || \
> +      (DeviceId == V_PCH_LPC_DEVICE_ID_2) || \
> +      (DeviceId == V_PCH_LPC_DEVICE_ID_3) \
> +    )
> +
> +#define IS_PCH_VLV_LPC_DEVICE_ID(DeviceId) \
> +    ( \
> +      IS_PCH_DEVICE_ID (DeviceId) \
> +    )
> +
> +#define IS_PCH_VLV_SATA_DEVICE_ID(DeviceId) \
> +    ( \
> +      IS_PCH_VLV_SATA_AHCI_DEVICE_ID (DeviceId) || \
> +      IS_PCH_VLV_SATA_MODE_DEVICE_ID (DeviceId) || \
> +      IS_PCH_VLV_SATA_RAID_DEVICE_ID (DeviceId) \
> +    )
> +
> +#define IS_PCH_VLV_SATA_AHCI_DEVICE_ID(DeviceId) \
> +    ( \
> +      (DeviceId == V_PCH_SATA_DEVICE_ID_D_AHCI) || \
> +      (DeviceId == V_PCH_SATA_DEVICE_ID_M_AHCI) \
> +    )
> +
> +#define IS_PCH_VLV_SATA_RAID_DEVICE_ID(DeviceId) \
> +    ( \
> +      (DeviceId == V_PCH_SATA_DEVICE_ID_D_RAID) || \
> +      (DeviceId == V_PCH_SATA_DEVICE_ID_M_RAID) \
> +    )
> +
> +#define IS_PCH_VLV_SATA_MODE_DEVICE_ID(DeviceId) \
> +    ( \
> +      (DeviceId == V_PCH_SATA_DEVICE_ID_D_IDE) || \
> +      (DeviceId == V_PCH_SATA_DEVICE_ID_M_IDE) \
> +    )
> +#define IS_PCH_VLV_USB_DEVICE_ID(DeviceId) \
> +    ( \
> +      (DeviceId == V_PCH_USB_DEVICE_ID_0) || \
> +      (DeviceId == V_PCH_USB_DEVICE_ID_1) \
> +    )
> +#define IS_PCH_VLV_PCIE_DEVICE_ID(DeviceId) \
> +    ( \
> +      (DeviceId == V_PCH_PCIE_DEVICE_ID_0) || \
> +      (DeviceId == V_PCH_PCIE_DEVICE_ID_1) || \
> +      (DeviceId == V_PCH_PCIE_DEVICE_ID_2) || \
> +      (DeviceId == V_PCH_PCIE_DEVICE_ID_3) || \
> +      (DeviceId == V_PCH_PCIE_DEVICE_ID_4) || \
> +      (DeviceId == V_PCH_PCIE_DEVICE_ID_5) || \
> +      (DeviceId == V_PCH_PCIE_DEVICE_ID_6) || \
> +      (DeviceId == V_PCH_PCIE_DEVICE_ID_7) \
> +    )
> +
> +///
> +/// Any device ID that is Valleyview SC
> +///
> +#define IS_PCH_VLV_DEVICE_ID(DeviceId) \
> +    ( \
> +      IS_PCH_VLV_LPC_DEVICE_ID (DeviceId) || \
> +      IS_PCH_VLV_SATA_DEVICE_ID (DeviceId) || \
> +      IS_PCH_VLV_USB_DEVICE_ID (DeviceId) || \
> +      IS_PCH_VLV_PCIE_DEVICE_ID (DeviceId) || \
> +      (DeviceId) == V_PCH_SMBUS_DEVICE_ID || \
> +      (DeviceId) == V_PCH_HDA_DEVICE_ID_0 || \
> +      (DeviceId) == V_PCH_HDA_DEVICE_ID_1 \
> +    )
> +
> +#define IS_SUPPORTED_DEVICE_ID(DeviceId)  IS_PCH_VLV_DEVICE_ID
> (DeviceId)
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsHda.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsHda.h
> new file mode 100644
> index 0000000000..b25a79a4d1
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsHda.h
> @@ -0,0 +1,50 @@
> +/**
> +
> +Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +  @file
> +  PchRegsHda.h
> +
> +  @brief
> +  Register names for PCH High Definition Audio device.
> +
> +  Conventions:
> +
> +  - Prefixes:
> +    Definitions beginning with "R_" are registers
> +    Definitions beginning with "B_" are bits within registers
> +    Definitions beginning with "V_" are meaningful values of bits within the
> registers
> +    Definitions beginning with "S_" are register sizes
> +    Definitions beginning with "N_" are the bit position
> +  - In general, PCH registers are denoted by "_PCH_" in register names
> +  - Registers / bits that are different between PCH generations are denoted
> by
> +    "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_VLV_"
> +  - Registers / bits that are different between SKUs are denoted by
> "_<SKU_name>"
> +    at the end of the register/bit names
> +  - Registers / bits of new devices introduced in a PCH generation will be just
> named
> +    as "_PCH_" without <generation_name> inserted.
> +
> +**/
> +#ifndef _PCH_REGS_HDA_H_
> +#define _PCH_REGS_HDA_H_
> +
> +///
> +/// Azalia Controller Registers (D27:F0)
> +///
> +#define PCI_DEVICE_NUMBER_PCH_AZALIA       27
> +#define PCI_FUNCTION_NUMBER_PCH_AZALIA     0
> +
> +#define R_PCH_HDA_PCS                      0x54  // Power Management Control
> and Status
> +#define B_PCH_HDA_PCS_DATA                 0xFF000000 // Data, does not
> apply
> +#define B_PCH_HDA_PCS_CCE                  BIT23 // Bus Power Control Enable,
> does not apply
> +#define B_PCH_HDA_PCS_PMES                 BIT15 // PME Status
> +#define B_PCH_HDA_PCS_PMEE                 BIT8  // PME Enable
> +#define B_PCH_HDA_PCS_PS                   (BIT1 | BIT0) // Power State - D0/D3
> Hot
> +#define V_PCH_HDA_PCS_PS0                  0x00
> +#define V_PCH_HDA_PCS_PS3                  0x03
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsLpss.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsLpss.h
> new file mode 100644
> index 0000000000..a5d0d49cdb
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsLpss.h
> @@ -0,0 +1,486 @@
> +/*++
> +
> +Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  PchRegsLpss.h
> +
> +Abstract:
> +
> +  Register names for VLV Low Input Output (LPSS) module.
> +
> +  Conventions:
> +
> +  - Prefixes:
> +    Definitions beginning with "R_" are registers
> +    Definitions beginning with "B_" are bits within registers
> +    Definitions beginning with "V_" are meaningful values of bits within the
> registers
> +    Definitions beginning with "S_" are register sizes
> +    Definitions beginning with "N_" are the bit position
> +  - In general, PCH registers are denoted by "_PCH_" in register names
> +  - Registers / bits that are different between PCH generations are denoted
> by
> +    "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_VLV_"
> +  - Registers / bits that are different between SKUs are denoted by
> "_<SKU_name>"
> +    at the end of the register/bit names
> +  - Registers / bits of new devices introduced in a PCH generation will be just
> named
> +    as "_PCH_" without <generation_name> inserted.
> +
> +--*/
> +#ifndef _PCH_REGS_LPSS_H_
> +#define _PCH_REGS_LPSS_H_
> +
> +
> +//
> +// Low Power Input Output (LPSS) Module Registers
> +//
> +
> +//
> +// LPSS DMAC Modules
> +// PCI Config Space Registers
> +//
> +#define PCI_DEVICE_NUMBER_PCH_LPSS_DMAC0          30
> +#define PCI_DEVICE_NUMBER_PCH_LPSS_DMAC1          24
> +#define PCI_FUNCTION_NUMBER_PCH_LPSS_DMAC         0
> +
> +#define R_PCH_LPSS_DMAC_DEVVENDID                 0x00  // Device ID &
> Vendor ID
> +#define B_PCH_LPSS_DMAC_DEVVENDID_DID             0xFFFF0000 // Device
> ID
> +#define B_PCH_LPSS_DMAC_DEVVENDID_VID             0x0000FFFF // Vendor
> ID
> +
> +#define R_PCH_LPSS_DMAC_STSCMD                    0x04  // Status & Command
> +#define B_PCH_LPSS_DMAC_STSCMD_RMA                BIT29 // RMA
> +#define B_PCH_LPSS_DMAC_STSCMD_RCA                BIT28 // RCA
> +#define B_PCH_LPSS_DMAC_STSCMD_CAPLIST            BIT20 // Capability List
> +#define B_PCH_LPSS_DMAC_STSCMD_INTRSTS            BIT19 // Interrupt
> Status
> +#define B_PCH_LPSS_DMAC_STSCMD_INTRDIS            BIT10 // Interrupt
> Disable
> +#define B_PCH_LPSS_DMAC_STSCMD_SERREN             BIT8  // SERR# Enable
> +#define B_PCH_LPSS_DMAC_STSCMD_BME                BIT2  // Bus Master
> Enable
> +#define B_PCH_LPSS_DMAC_STSCMD_MSE                BIT1  // Memory Space
> Enable
> +
> +#define R_PCH_LPSS_DMAC_REVCC                     0x08  // Revision ID & Class
> Code
> +#define B_PCH_LPSS_DMAC_REVCC_CC                  0xFFFFFF00 // Class Code
> +#define B_PCH_LPSS_DMAC_REVCC_RID                 0x000000FF // Revision ID
> +
> +#define R_PCH_LPSS_DMAC_CLHB                      0x0C
> +#define B_PCH_LPSS_DMAC_CLHB_MULFNDEV             BIT23
> +#define B_PCH_LPSS_DMAC_CLHB_HT                   0x007F0000 // Header Type
> +#define B_PCH_LPSS_DMAC_CLHB_LT                   0x0000FF00 // Latency
> Timer
> +#define B_PCH_LPSS_DMAC_CLHB_CLS                  0x000000FF // Cache Line
> Size
> +
> +#define R_PCH_LPSS_DMAC_BAR                       0x10  // BAR
> +#define B_PCH_LPSS_DMAC_BAR_BA                    0xFFFFC000 // Base
> Address
> +#define V_PCH_LPSS_DMAC_BAR_SIZE                  0x4000
> +#define N_PCH_LPSS_DMAC_BAR_ALIGNMENT             14
> +#define B_PCH_LPSS_DMAC_BAR_SI                    0x00000FF0 // Size Indicator
> +#define B_PCH_LPSS_DMAC_BAR_PF                    BIT3  // Prefetchable
> +#define B_PCH_LPSS_DMAC_BAR_TYPE                  (BIT2 | BIT1) // Type
> +#define B_PCH_LPSS_DMAC_BAR_MS                    BIT0  // Message Space
> +
> +#define R_PCH_LPSS_DMAC_BAR1                      0x14  // BAR 1
> +#define B_PCH_LPSS_DMAC_BAR1_BA                   0xFFFFF000 // Base
> Address
> +#define B_PCH_LPSS_DMAC_BAR1_SI                   0x00000FF0 // Size Indicator
> +#define B_PCH_LPSS_DMAC_BAR1_PF                   BIT3  // Prefetchable
> +#define B_PCH_LPSS_DMAC_BAR1_TYPE                 (BIT2 | BIT1) // Type
> +#define B_PCH_LPSS_DMAC_BAR1_MS                   BIT0  // Message Space
> +
> +#define R_PCH_LPSS_DMAC_SSID                      0x2C  // Sub System ID
> +#define B_PCH_LPSS_DMAC_SSID_SID                  0xFFFF0000 // Sub System
> ID
> +#define B_PCH_LPSS_DMAC_SSID_SVID                 0x0000FFFF // Sub System
> Vendor ID
> +
> +#define R_PCH_LPSS_DMAC_ERBAR                     0x30  // Expansion ROM BAR
> +#define B_PCH_LPSS_DMAC_ERBAR_BA                  0xFFFFFFFF // Expansion
> ROM Base Address
> +
> +#define R_PCH_LPSS_DMAC_CAPPTR                    0x34  // Capability Pointer
> +#define B_PCH_LPSS_DMAC_CAPPTR_CPPWR              0xFF  // Capability
> Pointer Power
> +
> +#define R_PCH_LPSS_DMAC_INTR                      0x3C  // Interrupt
> +#define B_PCH_LPSS_DMAC_INTR_ML                   0xFF000000 // Max Latency
> +#define B_PCH_LPSS_DMAC_INTR_MG                   0x00FF0000
> +#define B_PCH_LPSS_DMAC_INTR_IP                   0x00000F00 // Interrupt Pin
> +#define B_PCH_LPSS_DMAC_INTR_IL                   0x000000FF // Interrupt Line
> +
> +#define R_PCH_LPSS_DMAC_PCAPID                    0x80  // Power Capability ID
> +#define B_PCH_LPSS_DMAC_PCAPID_PS                 0xF8000000 // PME
> Support
> +#define B_PCH_LPSS_DMAC_PCAPID_VS                 0x00070000 // Version
> +#define B_PCH_LPSS_DMAC_PCAPID_NC                 0x0000FF00 // Next
> Capability
> +#define B_PCH_LPSS_DMAC_PCAPID_PC                 0x000000FF // Power
> Capability
> +
> +#define R_PCH_LPSS_DMAC_PCS                       0x84  // PME Control Status
> +#define B_PCH_LPSS_DMAC_PCS_PMESTS                BIT15 // PME Status
> +#define B_PCH_LPSS_DMAC_PCS_PMEEN                 BIT8  // PME Enable
> +#define B_PCH_LPSS_DMAC_PCS_NSS                   BIT3  // No Soft Reset
> +#define B_PCH_LPSS_DMAC_PCS_PS                    (BIT1 | BIT0) // Power State
> +
> +#define R_PCH_LPSS_DMAC_MANID                     0xF8  // Manufacturer ID
> +#define B_PCH_LPSS_DMAC_MANID_MANID               0xFFFFFFFF //
> Manufacturer ID
> +
> +
> +//
> +// LPSS I2C Module
> +// PCI Config Space Registers
> +//
> +#define PCI_DEVICE_NUMBER_PCH_LPSS_I2C            24
> +#define PCI_FUNCTION_NUMBER_PCH_LPSS_I2C0         1
> +#define PCI_FUNCTION_NUMBER_PCH_LPSS_I2C1         2
> +#define PCI_FUNCTION_NUMBER_PCH_LPSS_I2C2         3
> +#define PCI_FUNCTION_NUMBER_PCH_LPSS_I2C3         4
> +#define PCI_FUNCTION_NUMBER_PCH_LPSS_I2C4         5
> +#define PCI_FUNCTION_NUMBER_PCH_LPSS_I2C5         6
> +#define PCI_FUNCTION_NUMBER_PCH_LPSS_I2C6         7
> +
> +#define R_PCH_LPSS_I2C_DEVVENDID                  0x00  // Device ID & Vendor
> ID
> +#define B_PCH_LPSS_I2C_DEVVENDID_DID              0xFFFF0000 // Device ID
> +#define B_PCH_LPSS_I2C_DEVVENDID_VID              0x0000FFFF // Vendor ID
> +
> +#define R_PCH_LPSS_I2C_STSCMD                     0x04  // Status & Command
> +#define B_PCH_LPSS_I2C_STSCMD_RMA                 BIT29 // RMA
> +#define B_PCH_LPSS_I2C_STSCMD_RCA                 BIT28 // RCA
> +#define B_PCH_LPSS_I2C_STSCMD_CAPLIST             BIT20 // Capability List
> +#define B_PCH_LPSS_I2C_STSCMD_INTRSTS             BIT19 // Interrupt Status
> +#define B_PCH_LPSS_I2C_STSCMD_INTRDIS             BIT10 // Interrupt
> Disable
> +#define B_PCH_LPSS_I2C_STSCMD_SERREN              BIT8  // SERR# Enable
> +#define B_PCH_LPSS_I2C_STSCMD_BME                 BIT2  // Bus Master Enable
> +#define B_PCH_LPSS_I2C_STSCMD_MSE                 BIT1  // Memory Space
> Enable
> +
> +#define R_PCH_LPSS_I2C_REVCC                      0x08  // Revision ID & Class
> Code
> +#define B_PCH_LPSS_I2C_REVCC_CC                   0xFFFFFF00 // Class Code
> +#define B_PCH_LPSS_I2C_REVCC_RID                  0x000000FF // Revision ID
> +
> +#define R_PCH_LPSS_I2C_CLHB                       0x0C
> +#define B_PCH_LPSS_I2C_CLHB_MULFNDEV              BIT23
> +#define B_PCH_LPSS_I2C_CLHB_HT                    0x007F0000 // Header Type
> +#define B_PCH_LPSS_I2C_CLHB_LT                    0x0000FF00 // Latency Timer
> +#define B_PCH_LPSS_I2C_CLHB_CLS                   0x000000FF // Cache Line Size
> +
> +#define R_PCH_LPSS_I2C_BAR                        0x10  // BAR
> +#define B_PCH_LPSS_I2C_BAR_BA                     0xFFFFF000 // Base Address
> +#define V_PCH_LPSS_I2C_BAR_SIZE                   0x1000
> +#define N_PCH_LPSS_I2C_BAR_ALIGNMENT              12
> +#define B_PCH_LPSS_I2C_BAR_SI                     0x00000FF0 // Size Indicator
> +#define B_PCH_LPSS_I2C_BAR_PF                     BIT3  // Prefetchable
> +#define B_PCH_LPSS_I2C_BAR_TYPE                   (BIT2 | BIT1) // Type
> +#define B_PCH_LPSS_I2C_BAR_MS                     BIT0  // Message Space
> +
> +#define R_PCH_LPSS_I2C_BAR1                       0x14  // BAR 1
> +#define B_PCH_LPSS_I2C_BAR1_BA                    0xFFFFF000 // Base Address
> +#define B_PCH_LPSS_I2C_BAR1_SI                    0x00000FF0 // Size Indicator
> +#define B_PCH_LPSS_I2C_BAR1_PF                    BIT3  // Prefetchable
> +#define B_PCH_LPSS_I2C_BAR1_TYPE                  (BIT2 | BIT1) // Type
> +#define B_PCH_LPSS_I2C_BAR1_MS                    BIT0  // Message Space
> +
> +#define R_PCH_LPSS_I2C_SSID                       0x2C  // Sub System ID
> +#define B_PCH_LPSS_I2C_SSID_SID                   0xFFFF0000 // Sub System ID
> +#define B_PCH_LPSS_I2C_SSID_SVID                  0x0000FFFF // Sub System
> Vendor ID
> +
> +#define R_PCH_LPSS_I2C_ERBAR                      0x30  // Expansion ROM BAR
> +#define B_PCH_LPSS_I2C_ERBAR_BA                   0xFFFFFFFF // Expansion
> ROM Base Address
> +
> +#define R_PCH_LPSS_I2C_CAPPTR                     0x34  // Capability Pointer
> +#define B_PCH_LPSS_I2C_CAPPTR_CPPWR               0xFF  // Capability
> Pointer Power
> +
> +#define R_PCH_LPSS_I2C_INTR                       0x3C  // Interrupt
> +#define B_PCH_LPSS_I2C_INTR_ML                    0xFF000000 // Max Latency
> +#define B_PCH_LPSS_I2C_INTR_MG                    0x00FF0000
> +#define B_PCH_LPSS_I2C_INTR_IP                    0x00000F00 // Interrupt Pin
> +#define B_PCH_LPSS_I2C_INTR_IL                    0x000000FF // Interrupt Line
> +
> +#define R_PCH_LPSS_I2C_PCAPID                     0x80  // Power Capability ID
> +#define B_PCH_LPSS_I2C_PCAPID_PS                  0xF8000000 // PME Support
> +#define B_PCH_LPSS_I2C_PCAPID_VS                  0x00070000 // Version
> +#define B_PCH_LPSS_I2C_PCAPID_NC                  0x0000FF00 // Next
> Capability
> +#define B_PCH_LPSS_I2C_PCAPID_PC                  0x000000FF // Power
> Capability
> +
> +#define R_PCH_LPSS_I2C_PCS                        0x84  // PME Control Status
> +#define B_PCH_LPSS_I2C_PCS_PMESTS                 BIT15 // PME Status
> +#define B_PCH_LPSS_I2C_PCS_PMEEN                  BIT8  // PME Enable
> +#define B_PCH_LPSS_I2C_PCS_NSS                    BIT3  // No Soft Reset
> +#define B_PCH_LPSS_I2C_PCS_PS                     (BIT1 | BIT0) // Power State
> +
> +#define R_PCH_LPSS_I2C_MANID                      0xF8  // Manufacturer ID
> +#define B_PCH_LPSS_I2C_MANID_MANID                0xFFFFFFFF //
> Manufacturer ID
> +
> +//
> +// LPSS I2C Module
> +// Memory Space Registers
> +//
> +#define R_PCH_LPSS_I2C_MEM_RESETS                 0x804 // Software Reset
> +#define B_PCH_LPSS_I2C_MEM_RESETS_FUNC            BIT1  // Function Clock
> Domain Reset
> +#define B_PCH_LPSS_I2C_MEM_RESETS_APB             BIT0  // APB Domain
> Reset
> +
> +//
> +// LPSS PWM Modules
> +// PCI Config Space Registers
> +//
> +#define PCI_DEVICE_NUMBER_PCH_LPSS_PWM            30
> +#define PCI_FUNCTION_NUMBER_PCH_LPSS_PWM0         1
> +#define PCI_FUNCTION_NUMBER_PCH_LPSS_PWM1         2
> +
> +#define R_PCH_LPSS_PWM_DEVVENDID                  0x00  // Device ID &
> Vendor ID
> +#define B_PCH_LPSS_PWM_DEVVENDID_DID              0xFFFF0000 // Device
> ID
> +#define B_PCH_LPSS_PWM_DEVVENDID_VID              0x0000FFFF // Vendor
> ID
> +
> +#define R_PCH_LPSS_PWM_STSCMD                     0x04  // Status & Command
> +#define B_PCH_LPSS_PWM_STSCMD_RMA                 BIT29 // RMA
> +#define B_PCH_LPSS_PWM_STSCMD_RCA                 BIT28 // RCA
> +#define B_PCH_LPSS_PWM_STSCMD_CAPLIST             BIT20 // Capability List
> +#define B_PCH_LPSS_PWM_STSCMD_INTRSTS             BIT19 // Interrupt
> Status
> +#define B_PCH_LPSS_PWM_STSCMD_INTRDIS             BIT10 // Interrupt
> Disable
> +#define B_PCH_LPSS_PWM_STSCMD_SERREN              BIT8  // SERR# Enable
> +#define B_PCH_LPSS_PWM_STSCMD_BME                 BIT2  // Bus Master
> Enable
> +#define B_PCH_LPSS_PWM_STSCMD_MSE                 BIT1  // Memory Space
> Enable
> +
> +#define R_PCH_LPSS_PWM_REVCC                      0x08  // Revision ID & Class
> Code
> +#define B_PCH_LPSS_PWM_REVCC_CC                   0xFFFFFF00 // Class Code
> +#define B_PCH_LPSS_PWM_REVCC_RID                  0x000000FF // Revision ID
> +
> +#define R_PCH_LPSS_PWM_CLHB                       0x0C
> +#define B_PCH_LPSS_PWM_CLHB_MULFNDEV              BIT23
> +#define B_PCH_LPSS_PWM_CLHB_HT                    0x007F0000 // Header Type
> +#define B_PCH_LPSS_PWM_CLHB_LT                    0x0000FF00 // Latency
> Timer
> +#define B_PCH_LPSS_PWM_CLHB_CLS                   0x000000FF // Cache Line
> Size
> +
> +#define R_PCH_LPSS_PWM_BAR                        0x10  // BAR
> +#define B_PCH_LPSS_PWM_BAR_BA                     0xFFFFF000 // Base Address
> +#define V_PCH_LPSS_PWM_BAR_SIZE                   0x1000
> +#define N_PCH_LPSS_PWM_BAR_ALIGNMENT              12
> +#define B_PCH_LPSS_PWM_BAR_SI                     0x00000FF0 // Size Indicator
> +#define B_PCH_LPSS_PWM_BAR_PF                     BIT3  // Prefetchable
> +#define B_PCH_LPSS_PWM_BAR_TYPE                   (BIT2 | BIT1) // Type
> +#define B_PCH_LPSS_PWM_BAR_MS                     BIT0  // Message Space
> +
> +#define R_PCH_LPSS_PWM_BAR1                       0x14  // BAR 1
> +#define B_PCH_LPSS_PWM_BAR1_BA                    0xFFFFF000 // Base
> Address
> +#define B_PCH_LPSS_PWM_BAR1_SI                    0x00000FF0 // Size Indicator
> +#define B_PCH_LPSS_PWM_BAR1_PF                    BIT3  // Prefetchable
> +#define B_PCH_LPSS_PWM_BAR1_TYPE                  (BIT2 | BIT1) // Type
> +#define B_PCH_LPSS_PWM_BAR1_MS                    BIT0  // Message Space
> +
> +#define R_PCH_LPSS_PWM_SSID                       0x2C  // Sub System ID
> +#define B_PCH_LPSS_PWM_SSID_SID                   0xFFFF0000 // Sub System
> ID
> +#define B_PCH_LPSS_PWM_SSID_SVID                  0x0000FFFF // Sub System
> Vendor ID
> +
> +#define R_PCH_LPSS_PWM_ERBAR                      0x30  // Expansion ROM BAR
> +#define B_PCH_LPSS_PWM_ERBAR_BA                   0xFFFFFFFF // Expansion
> ROM Base Address
> +
> +#define R_PCH_LPSS_PWM_CAPPTR                     0x34  // Capability Pointer
> +#define B_PCH_LPSS_PWM_CAPPTR_CPPWR               0xFF  // Capability
> Pointer Power
> +
> +#define R_PCH_LPSS_PWM_INTR                       0x3C  // Interrupt
> +#define B_PCH_LPSS_PWM_INTR_ML                    0xFF000000 // Max Latency
> +#define B_PCH_LPSS_PWM_INTR_MG                    0x00FF0000
> +#define B_PCH_LPSS_PWM_INTR_IP                    0x00000F00 // Interrupt Pin
> +#define B_PCH_LPSS_PWM_INTR_IL                    0x000000FF // Interrupt Line
> +
> +#define R_PCH_LPSS_PWM_PCAPID                     0x80  // Power Capability ID
> +#define B_PCH_LPSS_PWM_PCAPID_PS                  0xF8000000 // PME
> Support
> +#define B_PCH_LPSS_PWM_PCAPID_VS                  0x00070000 // Version
> +#define B_PCH_LPSS_PWM_PCAPID_NC                  0x0000FF00 // Next
> Capability
> +#define B_PCH_LPSS_PWM_PCAPID_PC                  0x000000FF // Power
> Capability
> +
> +#define R_PCH_LPSS_PWM_PCS                        0x84  // PME Control Status
> +#define B_PCH_LPSS_PWM_PCS_PMESTS                 BIT15 // PME Status
> +#define B_PCH_LPSS_PWM_PCS_PMEEN                  BIT8  // PME Enable
> +#define B_PCH_LPSS_PWM_PCS_NSS                    BIT3  // No Soft Reset
> +#define B_PCH_LPSS_PWM_PCS_PS                     (BIT1 | BIT0) // Power State
> +
> +#define R_PCH_LPSS_PWM_MANID                      0xF8  // Manufacturer ID
> +#define B_PCH_LPSS_PWM_MANID_MANID                0xFFFFFFFF //
> Manufacturer ID
> +
> +//
> +// LPSS PWM Module
> +// Memory Space Registers
> +//
> +#define R_PCH_LPSS_PWM_MEM_RESETS                 0x804 // Software Reset
> +#define B_PCH_LPSS_PWM_MEM_RESETS_FUNC            BIT1  // Function
> Clock Domain Reset
> +#define B_PCH_LPSS_PWM_MEM_RESETS_APB             BIT0  // APB Domain
> Reset
> +
> +//
> +// LPSS HSUART Modules
> +// PCI Config Space Registers
> +//
> +#define PCI_DEVICE_NUMBER_PCH_LPSS_HSUART         30
> +#define PCI_FUNCTION_NUMBER_PCH_LPSS_HSUART0      3
> +#define PCI_FUNCTION_NUMBER_PCH_LPSS_HSUART1      4
> +
> +#define R_PCH_LPSS_HSUART_DEVVENDID               0x00  // Device ID &
> Vendor ID
> +#define B_PCH_LPSS_HSUART_DEVVENDID_DID           0xFFFF0000 // Device
> ID
> +#define B_PCH_LPSS_HSUART_DEVVENDID_VID           0x0000FFFF //
> Vendor ID
> +
> +#define R_PCH_LPSS_HSUART_STSCMD                  0x04  // Status &
> Command
> +#define B_PCH_LPSS_HSUART_STSCMD_RMA              BIT29 // RMA
> +#define B_PCH_LPSS_HSUART_STSCMD_RCA              BIT28 // RCA
> +#define B_PCH_LPSS_HSUART_STSCMD_CAPLIST          BIT20 // Capability
> List
> +#define B_PCH_LPSS_HSUART_STSCMD_INTRSTS          BIT19 // Interrupt
> Status
> +#define B_PCH_LPSS_HSUART_STSCMD_INTRDIS          BIT10 // Interrupt
> Disable
> +#define B_PCH_LPSS_HSUART_STSCMD_SERREN           BIT8  // SERR# Enable
> +#define B_PCH_LPSS_HSUART_STSCMD_BME              BIT2  // Bus Master
> Enable
> +#define B_PCH_LPSS_HSUART_STSCMD_MSE              BIT1  // Memory Space
> Enable
> +
> +#define R_PCH_LPSS_HSUART_REVCC                   0x08  // Revision ID & Class
> Code
> +#define B_PCH_LPSS_HSUART_REVCC_CC                0xFFFFFF00 // Class Code
> +#define B_PCH_LPSS_HSUART_REVCC_RID               0x000000FF // Revision
> ID
> +
> +#define R_PCH_LPSS_HSUART_CLHB                    0x0C
> +#define B_PCH_LPSS_HSUART_CLHB_MULFNDEV           BIT23
> +#define B_PCH_LPSS_HSUART_CLHB_HT                 0x007F0000 // Header
> Type
> +#define B_PCH_LPSS_HSUART_CLHB_LT                 0x0000FF00 // Latency
> Timer
> +#define B_PCH_LPSS_HSUART_CLHB_CLS                0x000000FF // Cache Line
> Size
> +
> +#define R_PCH_LPSS_HSUART_BAR                     0x10  // BAR
> +#define B_PCH_LPSS_HSUART_BAR_BA                  0xFFFFF000 // Base
> Address
> +#define V_PCH_LPSS_HSUART_BAR_SIZE                0x1000
> +#define N_PCH_LPSS_HSUART_BAR_ALIGNMENT           12
> +#define B_PCH_LPSS_HSUART_BAR_SI                  0x00000FF0 // Size Indicator
> +#define B_PCH_LPSS_HSUART_BAR_PF                  BIT3  // Prefetchable
> +#define B_PCH_LPSS_HSUART_BAR_TYPE                (BIT2 | BIT1) // Type
> +#define B_PCH_LPSS_HSUART_BAR_MS                  BIT0  // Message Space
> +
> +#define R_PCH_LPSS_HSUART_BAR1                    0x14  // BAR 1
> +#define B_PCH_LPSS_HSUART_BAR1_BA                 0xFFFFF000 // Base
> Address
> +#define B_PCH_LPSS_HSUART_BAR1_SI                 0x00000FF0 // Size
> Indicator
> +#define B_PCH_LPSS_HSUART_BAR1_PF                 BIT3  // Prefetchable
> +#define B_PCH_LPSS_HSUART_BAR1_TYPE               (BIT2 | BIT1) // Type
> +#define B_PCH_LPSS_HSUART_BAR1_MS                 BIT0  // Message Space
> +
> +#define R_PCH_LPSS_HSUART_SSID                    0x2C  // Sub System ID
> +#define B_PCH_LPSS_HSUART_SSID_SID                0xFFFF0000 // Sub System
> ID
> +#define B_PCH_LPSS_HSUART_SSID_SVID               0x0000FFFF // Sub System
> Vendor ID
> +
> +#define R_PCH_LPSS_HSUART_ERBAR                   0x30  // Expansion ROM
> BAR
> +#define B_PCH_LPSS_HSUART_ERBAR_BA                0xFFFFFFFF // Expansion
> ROM Base Address
> +
> +#define R_PCH_LPSS_HSUART_CAPPTR                  0x34  // Capability Pointer
> +#define B_PCH_LPSS_HSUART_CAPPTR_CPPWR            0xFF  // Capability
> Pointer Power
> +
> +#define R_PCH_LPSS_HSUART_INTR                    0x3C  // Interrupt
> +#define B_PCH_LPSS_HSUART_INTR_ML                 0xFF000000 // Max
> Latency
> +#define B_PCH_LPSS_HSUART_INTR_MG                 0x00FF0000
> +#define B_PCH_LPSS_HSUART_INTR_IP                 0x00000F00 // Interrupt Pin
> +#define B_PCH_LPSS_HSUART_INTR_IL                 0x000000FF // Interrupt
> Line
> +
> +#define R_PCH_LPSS_HSUART_PCAPID                  0x80  // Power Capability ID
> +#define B_PCH_LPSS_HSUART_PCAPID_PS               0xF8000000 // PME
> Support
> +#define B_PCH_LPSS_HSUART_PCAPID_VS               0x00070000 // Version
> +#define B_PCH_LPSS_HSUART_PCAPID_NC               0x0000FF00 // Next
> Capability
> +#define B_PCH_LPSS_HSUART_PCAPID_PC               0x000000FF // Power
> Capability
> +
> +#define R_PCH_LPSS_HSUART_PCS                     0x84  // PME Control Status
> +#define B_PCH_LPSS_HSUART_PCS_PMESTS              BIT15 // PME Status
> +#define B_PCH_LPSS_HSUART_PCS_PMEEN               BIT8  // PME Enable
> +#define B_PCH_LPSS_HSUART_PCS_NSS                 BIT3  // No Soft Reset
> +#define B_PCH_LPSS_HSUART_PCS_PS                  (BIT1 | BIT0) // Power State
> +
> +#define R_PCH_LPSS_HSUART_MANID                   0xF8  // Manufacturer ID
> +#define B_PCH_LPSS_HSUART_MANID_MANID             0xFFFFFFFF //
> Manufacturer ID
> +
> +//
> +// LPSS HSUART Module
> +// Memory Space Registers
> +//
> +#define R_PCH_LPSS_HSUART_MEM_PCP                 0x800 // Private Clock
> Parameters
> +#define B_PCH_LPSS_HSUART_MEM_PCP_CLKUPDATE       BIT31 // Clock
> Divider Update
> +#define B_PCH_LPSS_HSUART_MEM_PCP_NVAL            0x7FFF0000 // N
> value for the M over N divider
> +#define B_PCH_LPSS_HSUART_MEM_PCP_MVAL            0x0000FFFE // M
> value for the M over N divider
> +#define B_PCH_LPSS_HSUART_MEM_PCP_CLKEN           BIT0  // Clock Enable
> +
> +#define R_PCH_LPSS_HSUART_MEM_RESETS              0x804 // Software
> Reset
> +#define B_PCH_LPSS_HSUART_MEM_RESETS_FUNC         BIT1  // Function
> Clock Domain Reset
> +#define B_PCH_LPSS_HSUART_MEM_RESETS_APB          BIT0  // APB
> Domain Reset
> +
> +//
> +// LPSS SPI Module
> +// PCI Config Space Registers
> +//
> +#define PCI_DEVICE_NUMBER_PCH_LPSS_SPI            30
> +#define PCI_FUNCTION_NUMBER_PCH_LPSS_SPI          5
> +
> +#define R_PCH_LPSS_SPI_DEVVENDID                  0x00  // Device ID & Vendor
> ID
> +#define B_PCH_LPSS_SPI_DEVVENDID_DID              0xFFFF0000 // Device ID
> +#define B_PCH_LPSS_SPI_DEVVENDID_VID              0x0000FFFF // Vendor ID
> +
> +#define R_PCH_LPSS_SPI_STSCMD                     0x04  // Status & Command
> +#define B_PCH_LPSS_SPI_STSCMD_RMA                 BIT29 // RMA
> +#define B_PCH_LPSS_SPI_STSCMD_RCA                 BIT28 // RCA
> +#define B_PCH_LPSS_SPI_STSCMD_CAPLIST             BIT20 // Capability List
> +#define B_PCH_LPSS_SPI_STSCMD_INTRSTS             BIT19 // Interrupt Status
> +#define B_PCH_LPSS_SPI_STSCMD_INTRDIS             BIT10 // Interrupt
> Disable
> +#define B_PCH_LPSS_SPI_STSCMD_SERREN              BIT8  // SERR# Enable
> +#define B_PCH_LPSS_SPI_STSCMD_BME                 BIT2  // Bus Master Enable
> +#define B_PCH_LPSS_SPI_STSCMD_MSE                 BIT1  // Memory Space
> Enable
> +
> +#define R_PCH_LPSS_SPI_REVCC                      0x08  // Revision ID & Class
> Code
> +#define B_PCH_LPSS_SPI_REVCC_CC                   0xFFFFFF00 // Class Code
> +#define B_PCH_LPSS_SPI_REVCC_RID                  0x000000FF // Revision ID
> +
> +#define R_PCH_LPSS_SPI_CLHB                       0x0C
> +#define B_PCH_LPSS_SPI_CLHB_MULFNDEV              BIT23
> +#define B_PCH_LPSS_SPI_CLHB_HT                    0x007F0000 // Header Type
> +#define B_PCH_LPSS_SPI_CLHB_LT                    0x0000FF00 // Latency Timer
> +#define B_PCH_LPSS_SPI_CLHB_CLS                   0x000000FF // Cache Line Size
> +
> +#define R_PCH_LPSS_SPI_BAR                        0x10  // BAR
> +#define B_PCH_LPSS_SPI_BAR_BA                     0xFFFFF000 // Base Address
> +#define V_PCH_LPSS_SPI_BAR_SIZE                   0x1000
> +#define N_PCH_LPSS_SPI_BAR_ALIGNMENT              12
> +#define B_PCH_LPSS_SPI_BAR_SI                     0x00000FF0 // Size Indicator
> +#define B_PCH_LPSS_SPI_BAR_PF                     BIT3  // Prefetchable
> +#define B_PCH_LPSS_SPI_BAR_TYPE                   (BIT2 | BIT1) // Type
> +#define B_PCH_LPSS_SPI_BAR_MS                     BIT0  // Message Space
> +
> +#define R_PCH_LPSS_SPI_BAR1                       0x14  // BAR 1
> +#define B_PCH_LPSS_SPI_BAR1_BA                    0xFFFFF000 // Base Address
> +#define B_PCH_LPSS_SPI_BAR1_SI                    0x00000FF0 // Size Indicator
> +#define B_PCH_LPSS_SPI_BAR1_PF                    BIT3  // Prefetchable
> +#define B_PCH_LPSS_SPI_BAR1_TYPE                  (BIT2 | BIT1) // Type
> +#define B_PCH_LPSS_SPI_BAR1_MS                    BIT0  // Message Space
> +
> +#define R_PCH_LPSS_SPI_SSID                       0x2C  // Sub System ID
> +#define B_PCH_LPSS_SPI_SSID_SID                   0xFFFF0000 // Sub System ID
> +#define B_PCH_LPSS_SPI_SSID_SVID                  0x0000FFFF // Sub System
> Vendor ID
> +
> +#define R_PCH_LPSS_SPI_ERBAR                      0x30  // Expansion ROM BAR
> +#define B_PCH_LPSS_SPI_ERBAR_BA                   0xFFFFFFFF // Expansion
> ROM Base Address
> +
> +#define R_PCH_LPSS_SPI_CAPPTR                     0x34  // Capability Pointer
> +#define B_PCH_LPSS_SPI_CAPPTR_CPPWR               0xFF  // Capability
> Pointer Power
> +
> +#define R_PCH_LPSS_SPI_INTR                       0x3C  // Interrupt
> +#define B_PCH_LPSS_SPI_INTR_ML                    0xFF000000 // Max Latency
> +#define B_PCH_LPSS_SPI_INTR_MG                    0x00FF0000
> +#define B_PCH_LPSS_SPI_INTR_IP                    0x00000F00 // Interrupt Pin
> +#define B_PCH_LPSS_SPI_INTR_IL                    0x000000FF // Interrupt Line
> +
> +#define R_PCH_LPSS_SPI_PCAPID                     0x80  // Power Capability ID
> +#define B_PCH_LPSS_SPI_PCAPID_PS                  0xF8000000 // PME Support
> +#define B_PCH_LPSS_SPI_PCAPID_VS                  0x00070000 // Version
> +#define B_PCH_LPSS_SPI_PCAPID_NC                  0x0000FF00 // Next
> Capability
> +#define B_PCH_LPSS_SPI_PCAPID_PC                  0x000000FF // Power
> Capability
> +
> +#define R_PCH_LPSS_SPI_PCS                        0x84  // PME Control Status
> +#define B_PCH_LPSS_SPI_PCS_PMESTS                 BIT15 // PME Status
> +#define B_PCH_LPSS_SPI_PCS_PMEEN                  BIT8  // PME Enable
> +#define B_PCH_LPSS_SPI_PCS_NSS                    BIT3  // No Soft Reset
> +#define B_PCH_LPSS_SPI_PCS_PS                     (BIT1 | BIT0) // Power State
> +
> +#define R_PCH_LPSS_SPI_MANID                      0xF8  // Manufacturer ID
> +#define B_PCH_LPSS_SPI_MANID_MANID                0xFFFFFFFF //
> Manufacturer ID
> +
> +//
> +// LPSS SPI Module
> +// Memory Space Registers
> +//
> +#define R_PCH_LPSS_SPI_MEM_PCP                    0x400 // Private Clock
> Parameters
> +#define B_PCH_LPSS_SPI_MEM_PCP_CLKUPDATE          BIT31 // Clock
> Divider Update
> +#define B_PCH_LPSS_SPI_MEM_PCP_NVAL               0x7FFF0000 // N value
> for the M over N divider
> +#define B_PCH_LPSS_SPI_MEM_PCP_MVAL               0x0000FFFE // M value
> for the M over N divider
> +#define B_PCH_LPSS_SPI_MEM_PCP_CLKEN              BIT0  // Clock Enable
> +
> +#define R_PCH_LPSS_SPI_MEM_RESETS                 0x404 // Software Reset
> +#define B_PCH_LPSS_SPI_MEM_RESETS_FUNC            BIT1  // Function Clock
> Domain Reset
> +#define B_PCH_LPSS_SPI_MEM_RESETS_APB             BIT0  // APB Domain
> Reset
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsPcie.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsPcie.h
> new file mode 100644
> index 0000000000..8b1ae403c9
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsPcie.h
> @@ -0,0 +1,83 @@
> +/**
> +
> +Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +  @file
> +  PchRegsPcie.h
> +
> +  @brief
> +  Register names for VLV PCI-E root port devices
> +
> +  Conventions:
> +
> +  - Prefixes:
> +    Definitions beginning with "R_" are registers
> +    Definitions beginning with "B_" are bits within registers
> +    Definitions beginning with "V_" are meaningful values of bits within the
> registers
> +    Definitions beginning with "S_" are register sizes
> +    Definitions beginning with "N_" are the bit position
> +  - In general, PCH registers are denoted by "_PCH_" in register names
> +  - Registers / bits that are different between PCH generations are denoted
> by
> +    "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_VLV_"
> +  - Registers / bits that are different between SKUs are denoted by
> "_<SKU_name>"
> +    at the end of the register/bit names
> +  - Registers / bits of new devices introduced in a PCH generation will be just
> named
> +    as "_PCH_" without <generation_name> inserted.
> +
> +--*/
> +#ifndef _PCH_REGS_PCIE_H_
> +#define _PCH_REGS_PCIE_H_
> +
> +#define PCH_PCIE_MAX_ROOT_PORTS                            4
> +
> +///
> +/// VLV PCI Express Root Ports (D28:F0~F3)
> +///
> +#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS              28
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1           0
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2           1
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3           2
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4           3
> +
> +#define R_PCH_PCIE_ID                                      0x00  // Identifiers
> +#define B_PCH_PCIE_ID_DID                                  0xFFFF0000 // Device ID
> +#define V_PCH_PCIE_DEVICE_ID_0                             0x0F48  // PCIE Root Port
> #1
> +#define V_PCH_PCIE_DEVICE_ID_1                             0x0F4A  // PCIE Root Port
> #2
> +#define V_PCH_PCIE_DEVICE_ID_2                             0x0F4C  // PCIE Root Port
> #3
> +#define V_PCH_PCIE_DEVICE_ID_3                             0x0F4E  // PCIE Root Port
> #4
> +#define B_PCH_PCIE_ID_VID                                  0x0000FFFF // Vendor ID
> +#define V_PCH_PCIE_VENDOR_ID
> V_PCH_INTEL_VENDOR_ID
> +
> +
> +#define R_PCH_PCIE_BNUM_SLT                                0x18  // Bus Numbers;
> Secondary Latency Timer
> +#define B_PCH_PCIE_BNUM_SLT_SLT                            0xFF000000 //
> Secondary Latency Timer
> +#define B_PCH_PCIE_BNUM_SLT_SBBN                           0x00FF0000 //
> Subordinate Bus Number
> +#define B_PCH_PCIE_BNUM_SLT_SCBN                           0x0000FF00 //
> Secondary Bus Number
> +#define B_PCH_PCIE_BNUM_SLT_PBN                            0x000000FF // Primary
> Bus Number
> +#define R_PCH_PCIE_CAPP                                    0x34  // Capabilities List
> Pointer
> +#define B_PCH_PCIE_CAPP                                    0xFF  // Capabilities Pointer
> +
> +#define R_PCH_PCIE_SLCTL_SLSTS                             0x58  // Slot Control; Slot
> Status
> +#define S_PCH_PCIE_SLCTL_SLSTS                             4
> +#define B_PCH_PCIE_SLCTL_SLSTS_DLLSC                       BIT24 // Data Link
> Layer State Changed
> +#define B_PCH_PCIE_SLCTL_SLSTS_PDS                         BIT22 // Presence
> Detect State
> +#define B_PCH_PCIE_SLCTL_SLSTS_MS                          BIT21 // MRL Sensor
> State
> +#define B_PCH_PCIE_SLCTL_SLSTS_PDC                         BIT19 // Presence
> Detect Changed
> +#define B_PCH_PCIE_SLCTL_SLSTS_MSC                         BIT18 // MRL Sensor
> Changed
> +#define B_PCH_PCIE_SLCTL_SLSTS_PFD                         BIT17 // Power Fault
> Detected
> +#define B_PCH_PCIE_SLCTL_SLSTS_DLLSCE                      BIT12 // Data Link
> Layer State Changed Enable
> +#define B_PCH_PCIE_SLCTL_SLSTS_PCC                         BIT10 // Power
> Controller Control
> +#define B_PCH_PCIE_SLCTL_SLSTS_HPE                         BIT5  // Hot Plug
> Interrupt Enable
> +#define B_PCH_PCIE_SLCTL_SLSTS_CCE                         BIT4  // Command
> Completed Interrupt Enable
> +#define B_PCH_PCIE_SLCTL_SLSTS_PDE                         BIT3  // Presence
> Detect Changed Enable
> +
> +#define R_PCH_PCIE_SVID                                    0x94  // Subsystem Vendor IDs
> +#define S_PCH_PCIE_SVID                                    4
> +#define B_PCH_PCIE_SVID_SID                                0xFFFF0000 // Subsystem
> Identifier
> +#define B_PCH_PCIE_SVID_SVID                               0x0000FFFF // Subsystem
> Vendor Identifier
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsPcu.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsPcu.h
> new file mode 100644
> index 0000000000..456c033bc6
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsPcu.h
> @@ -0,0 +1,1201 @@
> +/*++
> +
> +Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  PchRegsPcu.h
> +
> +Abstract:
> +
> +  Register names for VLV PCU device.
> +
> +  Conventions:
> +
> +  - Prefixes:
> +    Definitions beginning with "R_" are registers
> +    Definitions beginning with "B_" are bits within registers
> +    Definitions beginning with "V_" are meaningful values of bits within the
> registers
> +    Definitions beginning with "S_" are register sizes
> +    Definitions beginning with "N_" are the bit position
> +  - In general, PCH registers are denoted by "_PCH_" in register names
> +  - Registers / bits that are different between PCH generations are denoted
> by
> +    "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_VLV_"
> +  - Registers / bits that are different between SKUs are denoted by
> "_<SKU_name>"
> +    at the end of the register/bit names
> +  - Registers / bits of new devices introduced in a PCH generation will be just
> named
> +    as "_PCH_" without <generation_name> inserted.
> +
> +--*/
> +#ifndef _PCH_REGS_LPC_H_
> +#define _PCH_REGS_LPC_H_
> +
> +//
> +// VLV PCU Registers (D31:F0)
> +//
> +#define PCI_DEVICE_NUMBER_PCH_LPC                 31
> +#define PCI_FUNCTION_NUMBER_PCH_LPC               0
> +
> +// Silicon Steppings
> +typedef enum {
> +  PchA0         = 0,
> +  PchA1         = 1,
> +  PchB0         = 2,
> +  PchB1         = 3,
> +  PchB2         = 4,
> +  PchB3         = 5,
> +  PchC0         = 6,
> +  PchD0         = 7,
> +  PchSteppingMax
> +} PCH_STEPPING;
> +
> +#define R_PCH_LPC_REG_ID                          0x00  // Identifiers Register
> +#define B_PCH_LPC_DEVICE_ID                       0xFFFF0000 // Device
> Identification
> +#define B_PCH_LPC_VENDOR_ID                       0x0000FFFF // Vendor
> Identification
> +#define V_PCH_LPC_VENDOR_ID                       V_PCH_INTEL_VENDOR_ID //
> Vendor ID for Intel
> +//
> +// General VLV PCU Device ID
> +//
> +#define V_PCH_LPC_DEVICE_ID_0                     0x0F1C
> +#define V_PCH_LPC_DEVICE_ID_1                     0x0F1D
> +#define V_PCH_LPC_DEVICE_ID_2                     0x0F1E
> +#define V_PCH_LPC_DEVICE_ID_3                     0x0F1F
> +
> +#define R_PCH_LPC_COMMAND                         0x04  // Command
> +#define B_PCH_LPC_COMMAND_ID                      BIT10 // Interrupt Disable
> +#define B_PCH_LPC_COMMAND_FBE                     BIT9  // Fast Back to Back
> Enable
> +#define B_PCH_LPC_COMMAND_SERR_EN                 BIT8  // SERR# Enable
> +#define B_PCH_LPC_COMMAND_WCC                     BIT7  // Wait Cycle Control
> +#define B_PCH_LPC_COMMAND_PER                     BIT6  // Parity Error
> Response Enable
> +#define B_PCH_LPC_COMMAND_VPS                     BIT5  // VGA Palette Snoop
> +#define B_PCH_LPC_COMMAND_MWIE                    BIT4  // Memory Write
> and Invalidate Enable
> +#define B_PCH_LPC_COMMAND_SCE                     BIT3  // Special Cycle
> Enable
> +#define B_PCH_LPC_COMMAND_BME                     BIT2  // Bus Master Enable
> +#define B_PCH_LPC_COMMAND_MSE                     BIT1  // Memory Space
> Enable
> +#define B_PCH_LPC_COMMAND_IOSE                    BIT0  // I/O Space Enable
> +
> +#define R_PCH_LPC_DEV_STS                         0x06  // Status
> +#define B_PCH_LPC_DEV_STS_DPE                     BIT15 // Detected Parity Error
> +#define B_PCH_LPC_DEV_STS_SSE                     BIT14 // Signaled System Error
> +#define B_PCH_LPC_DEV_STS_RMA                     BIT13 // Received Master
> Abort
> +#define B_PCH_LPC_DEV_STS_RTA                     BIT12 // Received Target
> Abort
> +#define B_PCH_LPC_DEV_STS_STA                     BIT11 // Signaled Target Abort
> +#define B_PCH_LPC_DEV_STS_DEVT_STS                (BIT10 | BIT9) // DEVSEL#
> Timing Status
> +#define B_PCH_LPC_DEV_STS_MDPED                   BIT8  // Data Parity Error
> +#define B_PCH_LPC_DEV_STS_FB2B                    BIT7  // Fast Back to Back
> Capable
> +#define B_PCH_LPC_DEV_STS_66MHZ_CAP               BIT5  // 66 MHz capable
> +#define B_PCH_LPC_DEV_STS_CAP_LIST                BIT4  // Capabilities List
> +#define B_PCH_LPC_DEV_STS_INT_STS                 BIT3  // Interrupt Status
> +
> +#define R_PCH_LPC_RID_CC                          0x08  // Revision ID & Class Code
> +#define B_PCH_LPC_RID_CC_BCC                      0xFF000000 // Base Class Code
> +#define B_PCH_LPC_RID_CC_SCC                      0x00FF0000 // Sub-Class Code
> +#define B_PCH_LPC_RID_CC_PI                       0x0000FF00 // Programming
> Interface
> +#define B_PCH_LPC_RID_CC_RID                      0x000000FF // Revision ID
> +
> +// Silicon Steppings
> +
> +#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)
> +#define V_PCH_LPC_RID_E                           0x10  // D0 Stepping (17 x 17)
> +#define V_PCH_LPC_RID_F                           0x11  // D0 Stepping (25 x 27)
> +
> +#define R_PCH_LPC_MLT                             0x0D  // Master Latency Timer
> +#define B_PCH_LPC_MLT_MLC                         0xF8  // Master Latency Count
> +
> +#define R_PCH_LPC_HEADTYP                         0x0E  // Header Type
> +#define B_PCH_LPC_HEADTYP_MFD                     BIT7  // Multi-function
> Device
> +#define B_PCH_LPC_HEADTYP_HT                      0x7F  // Header Type
> +
> +#define R_PCH_LPC_SS                              0x2C  // Subsystem ID & Vendor ID
> +#define B_PCH_LPC_SS_SSID                         0xFFFF0000 // Subsystem ID
> +#define B_PCH_LPC_SS_SSVID                        0x0000FFFF // Subsystem
> Vendor ID
> +
> +#define R_PCH_LPC_CAP_LIST                        0x34  // Capability List
> +#define B_PCH_LPC_CAP_LIST_CP                     0xFF  // Capability Pointer
> +
> +#define R_PCH_LPC_ACPI_BASE                       0x40 // ABASE, 16bit
> +#define B_PCH_LPC_ACPI_BASE_BAR                   0x0000FF80 // Base Address,
> 128 Bytes
> +#define B_PCH_LPC_ACPI_BASE_EN                    BIT1 // Enable Bit
> +#define B_PCH_LPC_ACPI_BASE_MEMI                  BIT0 // Memory Space
> Indication
> +
> +#define R_PCH_LPC_PMC_BASE                        0x44  // PBASE, 32bit, 512 Bytes
> +#define B_PCH_LPC_PMC_BASE_BAR                    0xFFFFFE00 // Base Address
> +#define B_PCH_LPC_PMC_BASE_PREF                   BIT3  // Prefetchable
> +#define B_PCH_LPC_PMC_BASE_ADDRNG                 BIT2  // Address Range
> +#define B_PCH_LPC_PMC_BASE_EN                     BIT1  // Enable Bit
> +#define B_PCH_LPC_PMC_BASE_MEMI                   BIT0  // Memory Space
> Indication
> +
> +#define R_PCH_LPC_GPIO_BASE                       0x48  // GBASE, 16bit
> +#define B_PCH_LPC_GPIO_BASE_BAR                   0xFF00 // Base Address, 256
> Bytes
> +#define B_PCH_LPC_GPIO_BASE_EN                    BIT1  // Enable Bit
> +#define B_PCH_LPC_GPIO_BASE_MEMI                  BIT0  // Memory Space
> Indication
> +
> +#define R_PCH_LPC_IO_BASE                         0x4C  // IOBASE, 32bit
> +#define B_PCH_LPC_IO_BASE_BAR                     0xFFFFC000 // Base Address,
> 16 KiloBytes
> +#define B_PCH_LPC_IO_BASE_PREF                    BIT3  // Prefetchable
> +#define B_PCH_LPC_IO_BASE_ADDRNG                  BIT2  // Address Range
> +#define B_PCH_LPC_IO_BASE_EN                      BIT1  // Enable Bit
> +#define B_PCH_LPC_IO_BASE_MEMI                    BIT0  // Memory Space
> Indication
> +
> +#define R_PCH_LPC_ILB_BASE                        0x50  // IBASE, 32bit
> +#define B_PCH_LPC_ILB_BASE_BAR                    0xFFFFFE00 // Base Address,
> 512 bytes
> +#define B_PCH_LPC_ILB_BASE_PREF                   BIT3  // Prefetchable
> +#define B_PCH_LPC_ILB_BASE_ADDRNG                 BIT2  // Address Range
> +#define B_PCH_LPC_ILB_BASE_EN                     BIT1  // Enable Bit
> +#define B_PCH_LPC_ILB_BASE_MEMI                   BIT0  // Memory Space
> Indication
> +
> +#define R_PCH_LPC_SPI_BASE                        0x54  // SBASE, 32bit
> +#define B_PCH_LPC_SPI_BASE_BAR                    0xFFFFFE00 // Base Address,
> 512 bytes
> +#define B_PCH_LPC_SPI_BASE_PREF                   BIT3  // Prefetchable
> +#define B_PCH_LPC_SPI_BASE_ADDRNG                 BIT2  // Address Range
> +#define B_PCH_LPC_SPI_BASE_EN                     BIT1  // Enable Bit
> +#define B_PCH_LPC_SPI_BASE_MEMI                   BIT0  // Memory Space
> Indicator
> +
> +#define R_PCH_LPC_MPHY_BASE                       0x58 // MPBASE, 32bit
> +#define B_PCH_LPC_MPHY_BASE_BAR                   0xFFF00000 // Base
> Address, 1 MegaByte
> +#define B_PCH_LPC_MPHY_BASE_PREF                  BIT3  // Prefetchable
> +#define B_PCH_LPC_MPHY_BASE_ADDRNG                BIT2  // Address Range
> +#define B_PCH_LPC_MPHY_BASE_EN                    BIT1  // Enable Bit
> +#define B_PCH_LPC_MPHY_BASE_MEMI                  BIT0  // Memory Space
> Indicator
> +
> +#define R_PCH_LPC_PUNIT_BASE                      0x5C  // PUBASE, 32bit
> +#define B_PCH_LPC_PUNIT_BASE_BAR                  0xFFFFF800 // Base
> Address, 2K bytes
> +#define B_PCH_LPC_PUNIT_BASE_PREF                 BIT3  // Prefetchable
> +#define B_PCH_LPC_PUNIT_BASE_ADDRNG               BIT2  // Address Range
> +#define B_PCH_LPC_PUNIT_BASE_EN                   BIT1  // Enable Bit
> +#define B_PCH_LPC_PUNIT_BASE_MEMI                 BIT0  // Memory Space
> Indicator
> +
> +#define R_PCH_LPC_UART_CTRL                       0x80  // UART Control
> +#define B_PCH_LPC_UART_CTRL_COM1_EN               BIT0  // COM1 Enable
> +
> +#define R_PCH_LPC_FWH_BIOS_DEC                    0xD8  // BIOS Decode Enable
> +#define B_PCH_LPC_FWH_BIOS_DEC_EF8                BIT15 // F8-FF Enable
> +#define B_PCH_LPC_FWH_BIOS_DEC_EF0                BIT14 // F0-F8 Enable
> +#define B_PCH_LPC_FWH_BIOS_DEC_EE8                BIT13 // E8-EF Enable
> +#define B_PCH_LPC_FWH_BIOS_DEC_EE0                BIT12 // E0-E8 Enable
> +#define B_PCH_LPC_FWH_BIOS_DEC_ED8                BIT11 // D8-DF Enable
> +#define B_PCH_LPC_FWH_BIOS_DEC_ED0                BIT10 // D0-D8 Enable
> +#define B_PCH_LPC_FWH_BIOS_DEC_EC8                BIT9  // C8-CF Enable
> +#define B_PCH_LPC_FWH_BIOS_DEC_EC0                BIT8  // C0-C8 Enable
> +#define B_PCH_LPC_FWH_BIOS_DEC_LFE                BIT7  // Legacy F Segment
> Enable
> +#define B_PCH_LPC_FWH_BIOS_DEC_LEE                BIT6  // Legacy E Segment
> Enable
> +#define B_PCH_LPC_FWH_BIOS_DEC_E70                BIT3  // 70-7F Enable
> +#define B_PCH_LPC_FWH_BIOS_DEC_E60                BIT2  // 60-6F Enable
> +#define B_PCH_LPC_FWH_BIOS_DEC_E50                BIT1  // 50-5F Enable
> +#define B_PCH_LPC_FWH_BIOS_DEC_E40                BIT0  // 40-4F Enable
> +
> +#define R_PCH_LPC_FDCAP                           0xE0  // Feature Detection
> Capability ID
> +#define B_PCH_LPC_FDCAP_NEXT                      0xFF00 // Next Capability
> +#define B_PCH_LPC_FDCAP_CAPID                     0x00FF // Capability ID
> +
> +#define R_PCH_LPC_FDLEN                           0xE2  // Feature Detection
> Capability Length
> +#define B_PCH_LPC_FDLEN_CAPLEN                    0xFF  // Capability Length
> +
> +#define R_PCH_LPC_FDVER                           0xE3  // Feature Detection
> Capability Version
> +#define B_PCH_LPC_FDVER_VSCID                     0xF0  // Vendor Specific
> Capability ID
> +#define B_PCH_LPC_FDVER_CAPVER                    0x0F  // Capability Version
> +
> +#define R_PCH_LPC_FVECTIDX                        0xE4  // Feature Vector Index
> +
> +#define R_PCH_LPC_FVECTD                          0xE8  // Feature Vector Data
> +
> +#define R_PCH_LPC_RCBA                            0xF0  // RCBA, 32bit
> +#define B_PCH_LPC_RCBA_BAR                        0xFFFFFC00 // Base Address, 1
> KiloByte
> +#define B_PCH_LPC_RCBA_EN                         BIT0  // Enable Bit
> +
> +#define R_PCH_LPC_ULT_OBS                         0xF4  // ULT Observability
> +#define B_PCH_LPC_ULT_OBS_WNUM                    0x3FF000 // Reserved
> Wafer Number
> +#define B_PCH_LPC_ULT_OBS_XLOC                    0xFC0 // Reserved X Loc
> +#define B_PCH_LPC_ULT_OBS_YLOC                    0x3F  // Reserved Y Loc
> +
> +#define R_PCH_LPC_MAN_ID                          0xF8  // Manufacturer ID
> +#define B_PCH_LPC_MAN_ID_DPID                     0xF000000 // Dot Portion of
> Process ID
> +#define B_PCH_LPC_MAN_ID_MSID                     0xFF0000 // Manufacturing
> Stepping Identifier
> +#define B_PCH_LPC_MAN_ID_MID                      0xFF00 // Manufacturing
> Identifier
> +#define B_PCH_LPC_MAN_ID_PPID                     0xFF  // Process Portion of
> Process ID
> +
> +#define R_PCH_LPC_CGC                             0xFC  // Clock Gating Control
> +#define B_PCH_LPC_CGC_SBLCG                       BIT9  // IOSF-SB Local Clock
> Gating Disable
> +#define B_PCH_LPC_CGC_SBTCG                       BIT8  // IOSF-SB Trunk Clock
> Gating (Request) Disable
> +#define B_PCH_LPC_CGC_PRILCG                      BIT1  // IOSF-PRI Local Clock
> Gating Disable
> +#define B_PCH_LPC_CGC_PRITCG                      BIT0  // IOSF-PRI Trunk Clock
> Gating (Request) Disable
> +
> +//
> +// iLB Memory Space Registers (IBASE)
> +//
> +#define R_PCH_ILB_ACPI_CNT                        0x00  // ACPI Control
> +#define B_PCH_ILB_ACPI_CNT_SCI_IRQ_SEL            (BIT2 | BIT1 | BIT0) // SCI
> IRQ Select
> +#define V_PCH_ILB_ACPI_CNT_SCI_IRQ_9              0     // IRQ9
> +#define V_PCH_ILB_ACPI_CNT_SCI_IRQ_10             BIT0  // IRQ10
> +#define V_PCH_ILB_ACPI_CNT_SCI_IRQ_11             BIT1  // IRQ11
> +#define V_PCH_ILB_ACPI_CNT_SCI_IRQ_20             BIT2  // IRQ20 (Only if
> APIC enabled)
> +#define V_PCH_ILB_ACPI_CNT_SCI_IRQ_21             (BIT2 | BIT0) // IRQ21
> (Only if APIC enabled)
> +#define V_PCH_ILB_ACPI_CNT_SCI_IRQ_22             (BIT2 | BIT1) // IRQ22
> (Only if APIC enabled)
> +#define V_PCH_ILB_ACPI_CNT_SCI_IRQ_23             (BIT2 | BIT1 | BIT0) //
> IRQ23 (Only if APIC enabled)
> +
> +#define R_PCH_ILB_MC                              0x04  // Miscellaneous Control
> +#define B_PCH_ILB_MC_DRTC                         BIT3  // Disable RTC
> +#define B_PCH_ILB_MC_D8259                        BIT2  // Disable 8259
> +#define B_PCH_ILB_MC_D8254                        BIT1  // Disable 8254
> +#define B_PCH_ILB_MC_AME                          BIT0  // Alternate Access Mode
> Enable
> +
> +#define R_PCH_ILB_PIRQA_ROUT                      0x08  // PIRQA Routing Control
> +#define R_PCH_ILB_PIRQB_ROUT                      0x09  // PIRQB Routing Control
> +#define R_PCH_ILB_PIRQC_ROUT                      0x0A  // PIRQC Routing Control
> +#define R_PCH_ILB_PIRQD_ROUT                      0x0B  // PIRQD Routing Control
> +#define R_PCH_ILB_PIRQE_ROUT                      0x0C  // PIRQE Routing Control
> +#define R_PCH_ILB_PIRQF_ROUT                      0x0D  // PIRQF Routing Control
> +#define R_PCH_ILB_PIRQG_ROUT                      0x0E  // PIRQG Routing Control
> +#define R_PCH_ILB_PIRQH_ROUT                      0x0F  // PIRQH Routing Control
> +//
> +// Bit values are the same for R_PCH_ILB_PIRQA_ROUT to
> R_PCH_ILB_PIRQH_ROUT
> +//
> +#define B_PCH_ILB_PIRQX_ROUT_IRQEN                BIT7  // Interrupt Routing
> Enable
> +#define B_PCH_ILB_PIRQX_ROUT                      0x0F  // IRQ Routing
> +#define V_PCH_ILB_PIRQX_ROUT_IRQ_3                0x03  // Route to IRQ3
> +#define V_PCH_ILB_PIRQX_ROUT_IRQ_4                0x04  // Route to IRQ4
> +#define V_PCH_ILB_PIRQX_ROUT_IRQ_5                0x05  // Route to IRQ5
> +#define V_PCH_ILB_PIRQX_ROUT_IRQ_6                0x06  // Route to IRQ6
> +#define V_PCH_ILB_PIRQX_ROUT_IRQ_7                0x07  // Route to IRQ7
> +#define V_PCH_ILB_PIRQX_ROUT_IRQ_9                0x09  // Route to IRQ9
> +#define V_PCH_ILB_PIRQX_ROUT_IRQ_10               0x0A  // Route to IRQ10
> +#define V_PCH_ILB_PIRQX_ROUT_IRQ_11               0x0B  // Route to IRQ11
> +#define V_PCH_ILB_PIRQX_ROUT_IRQ_12               0x0C  // Route to IRQ12
> +#define V_PCH_ILB_PIRQX_ROUT_IRQ_14               0x0E  // Route to IRQ14
> +#define V_PCH_ILB_PIRQX_ROUT_IRQ_15               0x0F  // Route to IRQ15
> +
> +#define R_PCH_ILB_SERIRQ_CNT                      0x10  // Serial IRQ Control
> +#define B_PCH_ILB_SERIRQ_CNT_SIRQMD               BIT7  // Mode
> +
> +#define R_PCH_ILB_ULKMC                           0x14  // USB Legacy Keyboard /
> Mouse Control
> +#define B_PCH_ILB_ULKMC_TRAPBY64W                 BIT11 // SMI Caused by
> Port 64 Write
> +#define B_PCH_ILB_ULKMC_TRAPBY64R                 BIT10 // SMI Caused by
> Port 64 Read
> +#define B_PCH_ILB_ULKMC_TRAPBY60W                 BIT9  // SMI Caused by
> Port 60 Write
> +#define B_PCH_ILB_ULKMC_TRAPBY60R                 BIT8  // SMI Caused by
> Port 60 Read
> +#define B_PCH_ILB_ULKMC_64WEN                     BIT3  // SMI on Port 64
> Writes Enable
> +#define B_PCH_ILB_ULKMC_64REN                     BIT2  // SMI on Port 64 Reads
> Enable
> +#define B_PCH_ILB_ULKMC_60WEN                     BIT1  // SMI on Port 60
> Writes Enable
> +#define B_PCH_ILB_ULKMC_60REN                     BIT0  // SMI on Port 60 Reads
> Enable
> +
> +#define R_PCH_ILB_FWH_BIOS_SEL                    0x18  // FWH ID Select
> +#define B_PCH_ILB_FWH_BIOS_SEL_F8                 0xF0000000 // F8-FF ID
> Select
> +#define B_PCH_ILB_FWH_BIOS_SEL_F0                 0x0F000000 // F0-F7 ID
> Select
> +#define B_PCH_ILB_FWH_BIOS_SEL_E8                 0x00F00000 // E8-EF ID
> Select
> +#define B_PCH_ILB_FWH_BIOS_SEL_E0                 0x000F0000 // E0-E7 ID
> Select
> +#define B_PCH_ILB_FWH_BIOS_SEL_D8                 0x0000F000 // D8-DF ID
> Select
> +#define B_PCH_ILB_FWH_BIOS_SEL_D0                 0x00000F00 // D0-D7 ID
> Select
> +#define B_PCH_ILB_FWH_BIOS_SEL_C8                 0x000000F0 // C8-CF ID
> Select
> +#define B_PCH_ILB_FWH_BIOS_SEL_C0                 0x0000000F // C0-C7 ID
> Select
> +
> +#define R_PCH_ILB_BIOS_CNTL                       0x1C  // BIOS Control
> +#define S_PCH_ILB_BIOS_CNTL                       4
> +#define B_PCH_ILB_BIOS_CNTL_PFE                   BIT8  // Prefetch Enable
> +#define B_PCH_ILB_BIOS_CNTL_LE                    BIT1  // Lock Enable
> +#define N_PCH_ILB_BIOS_CNTL_LE                    1
> +#define B_PCH_ILB_BIOS_CNTL_WP                    BIT0  // Write Protect
> +
> +#define R_PCH_ILB_D0IR                            0x20  // Device 0 Interrupt Route
> +#define R_PCH_ILB_D1IR                            0x22  // Device 1 Interrupt Route
> +#define R_PCH_ILB_D2IR                            0x24  // Device 2 Interrupt Route
> +#define R_PCH_ILB_D3IR                            0x26  // Device 3 Interrupt Route
> +#define R_PCH_ILB_D4IR                            0x28  // Device 4 Interrupt Route
> +#define R_PCH_ILB_D5IR                            0x2A  // Device 5 Interrupt Route
> +#define R_PCH_ILB_D6IR                            0x2C  // Device 6 Interrupt Route
> +#define R_PCH_ILB_D7IR                            0x2E  // Device 7 Interrupt Route
> +#define R_PCH_ILB_D8IR                            0x30  // Device 8 Interrupt Route
> +#define R_PCH_ILB_D9IR                            0x32  // Device 9 Interrupt Route
> +#define R_PCH_ILB_D10IR                           0x34  // Device 10 Interrupt Route
> +#define R_PCH_ILB_D11IR                           0x36  // Device 11 Interrupt Route
> +#define R_PCH_ILB_D12IR                           0x38  // Device 12 Interrupt Route
> +#define R_PCH_ILB_D13IR                           0x3A  // Device 13 Interrupt Route
> +#define R_PCH_ILB_D14IR                           0x3C  // Device 14 Interrupt Route
> +#define R_PCH_ILB_D15IR                           0x3E  // Device 15 Interrupt Route
> +#define R_PCH_ILB_D16IR                           0x40  // Device 16 Interrupt Route
> +#define R_PCH_ILB_D17IR                           0x42  // Device 17 Interrupt Route
> +#define R_PCH_ILB_D18IR                           0x44  // Device 18 Interrupt Route
> +#define R_PCH_ILB_D19IR                           0x46  // Device 19 Interrupt Route
> +#define R_PCH_ILB_D20IR                           0x48  // Device 20 Interrupt Route
> +#define R_PCH_ILB_D21IR                           0x4A  // Device 21 Interrupt Route
> +#define R_PCH_ILB_D22IR                           0x4C  // Device 22 Interrupt Route
> +#define R_PCH_ILB_D23IR                           0x4E  // Device 23 Interrupt Route
> +#define R_PCH_ILB_D24IR                           0x50  // Device 24 Interrupt Route
> +#define R_PCH_ILB_D25IR                           0x52  // Device 25 Interrupt Route
> +#define R_PCH_ILB_D26IR                           0x54  // Device 26 Interrupt Route
> +#define R_PCH_ILB_D27IR                           0x56  // Device 27 Interrupt Route
> +#define R_PCH_ILB_D28IR                           0x58  // Device 28 Interrupt Route
> +#define R_PCH_ILB_D29IR                           0x5A  // Device 29 Interrupt Route
> +#define R_PCH_ILB_D30IR                           0x5C  // Device 30 Interrupt Route
> +#define R_PCH_ILB_D31IR                           0x5E  // Device 31 Interrupt Route
> +
> +#define B_PCH_ILB_DXXIR_IDR_MASK                  (BIT14 | BIT13 | BIT12) //
> INTD Mask
> +#define V_PCH_ILB_DXXIR_IDR_PIRQA                 0                       // INTD
> Mapping to IRQ A
> +#define V_PCH_ILB_DXXIR_IDR_PIRQB                 BIT12                   // INTD
> Mapping to IRQ B
> +#define V_PCH_ILB_DXXIR_IDR_PIRQC                 BIT13                   // INTD
> Mapping to IRQ C
> +#define V_PCH_ILB_DXXIR_IDR_PIRQD                 (BIT13 | BIT12)         // INTD
> Mapping to IRQ D
> +#define V_PCH_ILB_DXXIR_IDR_PIRQE                 BIT14                   // INTD
> Mapping to IRQ E
> +#define V_PCH_ILB_DXXIR_IDR_PIRQF                 (BIT14 | BIT12)         // INTD
> Mapping to IRQ F
> +#define V_PCH_ILB_DXXIR_IDR_PIRQG                 (BIT14 | BIT13)         // INTD
> Mapping to IRQ G
> +#define V_PCH_ILB_DXXIR_IDR_PIRQH                 (BIT14 | BIT13 | BIT12) //
> INTD Mapping to IRQ H
> +
> +#define B_PCH_ILB_DXXIR_ICR_MASK                  (BIT10 | BIT9 | BIT8) // INTC
> Mask
> +#define V_PCH_ILB_DXXIR_ICR_PIRQA                 0                     // INTC Mapping
> to IRQ A
> +#define V_PCH_ILB_DXXIR_ICR_PIRQB                 BIT8                  // INTC
> Mapping to IRQ B
> +#define V_PCH_ILB_DXXIR_ICR_PIRQC                 BIT9                  // INTC
> Mapping to IRQ C
> +#define V_PCH_ILB_DXXIR_ICR_PIRQD                 (BIT9 | BIT8)         // INTC
> Mapping to IRQ D
> +#define V_PCH_ILB_DXXIR_ICR_PIRQE                 BIT10                 // INTC
> Mapping to IRQ E
> +#define V_PCH_ILB_DXXIR_ICR_PIRQF                 (BIT10 | BIT8)        // INTC
> Mapping to IRQ F
> +#define V_PCH_ILB_DXXIR_ICR_PIRQG                 (BIT10 | BIT9)        // INTC
> Mapping to IRQ G
> +#define V_PCH_ILB_DXXIR_ICR_PIRQH                 (BIT10 | BIT9 | BIT8) // INTC
> Mapping to IRQ H
> +
> +#define B_PCH_ILB_DXXIR_IBR_MASK                  (BIT6 | BIT5 | BIT4) // INTB
> Mask
> +#define V_PCH_ILB_DXXIR_IBR_PIRQA                 0                    // INTB Mapping
> to IRQ A
> +#define V_PCH_ILB_DXXIR_IBR_PIRQB                 BIT4                 // INTB
> Mapping to IRQ B
> +#define V_PCH_ILB_DXXIR_IBR_PIRQC                 BIT5                 // INTB
> Mapping to IRQ C
> +#define V_PCH_ILB_DXXIR_IBR_PIRQD                 (BIT5 | BIT4)        // INTB
> Mapping to IRQ D
> +#define V_PCH_ILB_DXXIR_IBR_PIRQE                 BIT6                 // INTB
> Mapping to IRQ E
> +#define V_PCH_ILB_DXXIR_IBR_PIRQF                 (BIT6 | BIT4)        // INTB
> Mapping to IRQ F
> +#define V_PCH_ILB_DXXIR_IBR_PIRQG                 (BIT6 | BIT5)        // INTB
> Mapping to IRQ G
> +#define V_PCH_ILB_DXXIR_IBR_PIRQH                 (BIT6 | BIT5 | BIT4) // INTB
> Mapping to IRQ H
> +
> +#define B_PCH_ILB_DXXIR_IAR_MASK                  (BIT2 | BIT1 | BIT0) // INTA
> Mask
> +#define V_PCH_ILB_DXXIR_IAR_PIRQA                 0                    // INTA Mapping
> to IRQ A
> +#define V_PCH_ILB_DXXIR_IAR_PIRQB                 BIT0                 // INTA
> Mapping to IRQ B
> +#define V_PCH_ILB_DXXIR_IAR_PIRQC                 BIT1                 // INTA
> Mapping to IRQ C
> +#define V_PCH_ILB_DXXIR_IAR_PIRQD                 (BIT1 | BIT0)        // INTA
> Mapping to IRQ D
> +#define V_PCH_ILB_DXXIR_IAR_PIRQE                 BIT2                 // INTA
> Mapping to IRQ E
> +#define V_PCH_ILB_DXXIR_IAR_PIRQF                 (BIT2 | BIT0)        // INTA
> Mapping to IRQ F
> +#define V_PCH_ILB_DXXIR_IAR_PIRQG                 (BIT2 | BIT1)        // INTA
> Mapping to IRQ G
> +#define V_PCH_ILB_DXXIR_IAR_PIRQH                 (BIT2 | BIT1 | BIT0) // INTA
> Mapping to IRQ H
> +
> +#define R_PCH_ILB_OIC                             0x60  // Other Interrupt Controller
> +#define B_PCH_ILB_OIC_SIRQEN                      BIT12 // Serial IRQ Enable
> +#define B_PCH_ILB_OIC_AEN                         BIT8  // APIC Enable
> +
> +#define R_PCH_ILB_RTC_CONF                        0x64  // RTC Control
> +#define B_PCH_ILB_RTC_CONF_UCMOS_LOCK             BIT1  // Upper 128
> Byte Lock
> +#define B_PCH_ILB_RTC_CONF_LCMOS_LOCK             BIT0  // Lower 128
> Byte Lock
> +
> +#define R_PCH_ILB_RTM                             0x68  // RTC Test Mode
> +#define B_PCH_ILB_RTM_RTM1                        (BIT2 | BIT1 | BIT0)
> +
> +#define R_PCH_ILB_BCS                             0x6C  // BIOS Control Status
> +#define B_PCH_ILB_BCS_SMIWPEN                     BIT1  // SMI WPD Enable
> +#define B_PCH_ILB_BCS_SMIWPST                     BIT0  // SMI WPD Status
> +
> +#define R_PCH_ILB_LE                              0x70  // LE
> +#define B_PCH_ILB_LE_IRQ12C                       BIT1  // IRQ12 Cause
> +#define B_PCH_ILB_LE_IRQ1C                        BIT0  // IRQ1 Cause
> +
> +#define R_PCH_ILB_RTCC                            0x74  // RTC HIP Configuration
> +#define B_PCH_ILB_RTCC_RTCB4                      BIT6  // RTC Bias Resistor 4,
> Adds 480 Kohm
> +#define B_PCH_ILB_RTCC_RTCB3                      BIT5  // RTC Bias Resistor 3,
> Adds 240 Kohm
> +#define B_PCH_ILB_RTCC_RTCB2                      BIT4  // RTC Bias Resistor 2,
> Adds 120 Kohm
> +#define B_PCH_ILB_RTCC_RTCB1                      BIT3  // RTC Bias Resistor 1,
> Adds 60 Kohm
> +#define B_PCH_ILB_RTCC_RTCB0                      BIT2  // RTC Bias Resistor 0,
> Adds 30 Kohm
> +#define B_PCH_ILB_RTCC_DSWEN                      BIT1  // Deep Sleep Well
> Enable
> +#define B_PCH_ILB_RTCC_FEN                        BIT0  // Enable the Fast Oscillator
> Bypass Mode
> +
> +#define R_PCH_ILB_DEF0                            0x78  // Defeature Register 0
> +#define B_PCH_ILB_DEF0_SHRTSYNC                   BIT22 // Short Sync Abort
> Defeature
> +#define B_PCH_ILB_DEF0_SDD                        BIT21 // Sub Decode Disable
> +
> +#define R_PCH_ILB_DEF1                            0x7C  // Defeature Register 1
> +#define B_PCH_ILB_DEF1_TPMPF                      BIT10 //
> usb2leg_chknbit_TPM_PF
> +#define B_PCH_ILB_DEF1_HPETDEF                    BIT8  // usb2leg_chknbit_hpet
> +#define B_PCH_ILB_DEF1_ECWS                       BIT6  // 8254 Early CW Select
> +#define B_PCH_ILB_DEF1_FOF                        BIT5  // 8254 Freeze on first on
> 1st rd wr11
> +#define B_PCH_ILB_DEF1_FOAR                       BIT4  // 8254
> Freeze_On_AnyRead
> +#define B_PCH_ILB_DEF1_LMOO                       BIT3  // 8259
> L2L0_Match_On_OCW2
> +#define B_PCH_ILB_DEF1_DFP                        BIT2  // 8259
> Disable_Freeze_Priority
> +#define B_PCH_ILB_DEF1_EETI                       BIT1  // 8259
> Extend_EdgeTrig_IRQ
> +#define B_PCH_ILB_DEF1_DSAEOI                     BIT0  // 8259
> Disable_Slave_AEOI
> +
> +#define R_PCH_ILB_GNMI                            0x80  // NMI Register
> +#define S_PCH_ILB_GNMI                            4
> +#define B_PCH_ILB_GNMI_NMI2SMIEN                  BIT6  // NMI to SMI Enable
> +#define N_PCH_ILB_GNMI_NMI2SMIEN                  6
> +#define B_PCH_ILB_GNMI_NMI2SMIST                  BIT5  // NMI to SMI Status
> +#define N_PCH_ILB_GNMI_NMI2SMIST                  5
> +#define B_PCH_ILB_GNMI_NMIN                       BIT4  // NMI NOW
> +#define B_PCH_ILB_GNMI_NMINS                      BIT3  // NMI NOW Status
> +#define B_PCH_ILB_GNMI_GNMIED                     BIT2  // GPIO NMI Edge
> Detection
> +#define B_PCH_ILB_GNMI_GNMIE                      BIT1  // GPIO NMI Enable
> +#define B_PCH_ILB_GNMI_GNMIS                      BIT0  // GPIO NMI Status
> +
> +#define R_PCH_ILB_LPCC                            0x84  // LPC Control
> +#define B_PCH_ILB_LPCC_LPCCLK_SLC                 BIT8  // iLPCCLK Mux Select
> +#define B_PCH_ILB_LPCC_LPCCLK_FORCE_OFF           BIT3
> +#define B_PCH_ILB_LPCC_CLKRUN_EN                  BIT2  // LPC CLKRUN
> Protocol Enable
> +#define B_PCH_ILB_LPCC_LPCCLK1EN                  BIT1  // Clock 1 Enable
> +#define B_PCH_ILB_LPCC_LPCCLK0EN                  BIT0  // Clock 0 Enable
> +
> +#define R_PCH_ILB_IRQE                            0x88  // IRQ Enable Control
> +#define B_PCH_ILB_IRQE_IRQ4TO7EN                  (BIT7 | BIT6 | BIT5 | BIT4) //
> IRQ4 - IRQ7 Enable
> +#define B_PCH_ILB_IRQE_UARTIRQEN_IRQ3             BIT3  // UART IRQ3
> Enable
> +
> +//
> +// ACPI and Legacy I/O Registers (ABASE)
> +//
> +#define R_PCH_ACPI_PM1_STS                        0x00  // Power Management 1
> Status
> +#define S_PCH_ACPI_PM1_STS                        2
> +#define B_PCH_ACPI_PM1_STS_WAK                    BIT15 // Wake Status
> +#define B_PCH_ACPI_PM1_STS_WAK_PCIE0              BIT14 // PCI Express 0
> Wake Status
> +#define B_PCH_ACPI_PM1_STS_USB_CLKLESS            BIT13 // USB Clockless
> Status
> +#define B_PCH_ACPI_PM1_STS_PRBTNOR                BIT11 // Power Button
> Override Status
> +#define B_PCH_ACPI_PM1_STS_RTC                    BIT10 // RTC Status
> +#define B_PCH_ACPI_PM1_STS_PWRBTN                 BIT8  // Power Button
> Status
> +#define B_PCH_ACPI_PM1_STS_GBL                    BIT5  // Global Status
> +#define B_PCH_ACPI_PM1_STS_WAK_PCIE3              BIT4  // PCI Express 3
> Wake Status
> +#define B_PCH_ACPI_PM1_STS_WAK_PCIE2              BIT3  // PCI Express 2
> Wake Status
> +#define B_PCH_ACPI_PM1_STS_WAK_PCIE1              BIT2  // PCI Express 1
> Wake Status
> +#define B_PCH_ACPI_PM1_STS_TMROF                  BIT0  // Timer Overflow
> Status
> +#define N_PCH_ACPI_PM1_STS_WAK                    15
> +#define N_PCH_ACPI_PM1_STS_PRBTNOR                11
> +#define N_PCH_ACPI_PM1_STS_RTC                    10
> +#define N_PCH_ACPI_PM1_STS_PWRBTN                 8
> +#define N_PCH_ACPI_PM1_STS_GBL                    5
> +#define N_PCH_ACPI_PM1_STS_TMROF                  0
> +
> +#define R_PCH_ACPI_PM1_EN                         0x02  // Power Management 1
> Enables
> +#define S_PCH_ACPI_PM1_EN                         2
> +#define B_PCH_ACPI_PM1_WAK_DIS_PCIE0              BIT14 // PCI Express 0
> Disable
> +#define B_PCH_ACPI_PM1_EN_USB_CLKLESS             BIT13 // USB Clockless
> Enable Bit
> +#define B_PCH_ACPI_PM1_EN_RTC                     BIT10 // RTC Alarm Enable Bit
> +#define B_PCH_ACPI_PM1_EN_PWRBTN                  BIT8  // Power Button
> Enable Bit
> +#define B_PCH_ACPI_PM1_EN_GBL                     BIT5  // Global Enable Bit
> +#define B_PCH_ACPI_PM1_WAK_DIS_PCIE3              BIT4  // PCI Express 3
> Disable
> +#define B_PCH_ACPI_PM1_WAK_DIS_PCIE2              BIT3  // PCI Express 2
> Disable
> +#define B_PCH_ACPI_PM1_WAK_DIS_PCIE1              BIT2  // PCI Express 1
> Disable
> +#define B_PCH_ACPI_PM1_EN_TMROF                   BIT0  // Timer Overflow
> Interrupt Enable Bit
> +#define N_PCH_ACPI_PM1_EN_RTC                     10
> +#define N_PCH_ACPI_PM1_EN_PWRBTN                  8
> +#define N_PCH_ACPI_PM1_EN_GBL                     5
> +#define N_PCH_ACPI_PM1_EN_TMROF                   0
> +
> +#define R_PCH_ACPI_PM1_CNT                        0x04  // Power Management 1
> Control
> +#define S_PCH_ACPI_PM1_CNT                        4
> +#define B_PCH_ACPI_PM1_CNT_SLP_EN                 BIT13 // Sleep enable
> +#define B_PCH_ACPI_PM1_CNT_SLP_TYP                (BIT12 | BIT11 | BIT10) //
> Sleep Type
> +#define V_PCH_ACPI_PM1_CNT_S0                     0x00000000 // ON (S0)
> +#define V_PCH_ACPI_PM1_CNT_S1                     0x00000400 // Puts CPU in S1
> state (S1)
> +#define V_PCH_ACPI_PM1_CNT_S3                     0x00001400 // Suspend-to-
> RAM (S3)
> +#define V_PCH_ACPI_PM1_CNT_S4                     0x00001800 // Suspend-to-
> Disk (S4)
> +#define V_PCH_ACPI_PM1_CNT_S5                     0x00001C00 // Soft Off (S5)
> +#define B_PCH_ACPI_PM1_CNT_GBL_RLS                BIT2
> +#define B_PCH_ACPI_PM1_CNT_BM_RLD                 BIT1  // Treated as
> Scratchpad Bit
> +#define B_PCH_ACPI_PM1_CNT_SCI_EN                 BIT0  // SCI Enable
> +
> +#define R_PCH_ACPI_PM1_TMR                        0x08  // Power Management 1
> Timer
> +#define B_PCH_ACPI_PM1_TMR_VAL                    0xFFFFFF // The timer value
> mask
> +#define V_PCH_ACPI_PM1_TMR_MAX_VAL                0x1000000 // The timer
> is 24 bit overflow
> +#define V_PCH_ACPI_PM1_TMR_FREQUENCY              3579545 // Timer
> Frequency
> +#define V_PCH_ACPI_PM1_TMR_NUM_BITS               24    // Programmed to
> 24 not 32
> +#define V_PCH_ACPI_PM1_TMR_MAX_BITS               32
> +
> +#define R_PCH_ACPI_GPE0a_STS                      0x20  // General Purpose Event
> 0a Status
> +#define S_PCH_ACPI_GPE0a_STS                      4
> +#define B_PCH_ACPI_GPE0a_STS_CORE_GPIO            0xFF000000 // CORE
> GPIO Status
> +#define B_PCH_ACPI_GPE0a_STS_SUS_GPIO             0x00FF0000 // SUS
> GPIO Status
> +#define B_PCH_ACPI_GPE0a_STS_PME_B0               BIT13 // Power
> Management Event Bus 0 Status
> +#define B_PCH_ACPI_GPE0a_STS_BATLOW               BIT10 // Battery Low
> Status
> +#define B_PCH_ACPI_GPE0a_STS_PCI_EXP              BIT9  // PCI Express
> Status
> +#define B_PCH_ACPI_GPE0a_STS_GUNIT_SCI            BIT5  // GUNIT SCI
> Status
> +#define B_PCH_ACPI_GPE0a_STS_PUNIT_SCI            BIT4  // PUNIT SCI
> Status
> +#define B_PCH_ACPI_GPE0a_STS_SWGPE                BIT2  // Software GPE
> Status
> +#define B_PCH_ACPI_GPE0a_STS_HOT_PLUG             BIT1  // Hot Plug Status
> +#define N_PCH_ACPI_GPE0a_STS_PME_B0               13
> +#define N_PCH_ACPI_GPE0a_STS_BATLOW               10
> +#define N_PCH_ACPI_GPE0a_STS_PCI_EXP              9
> +#define N_PCH_ACPI_GPE0a_STS_GUNIT_SCI            5
> +#define N_PCH_ACPI_GPE0a_STS_PUNIT_SCI            4
> +#define N_PCH_ACPI_GPE0a_STS_SWGPE                2
> +#define N_PCH_ACPI_GPE0a_STS_HOT_PLUG             1
> +
> +#define R_PCH_ACPI_GPE0a_EN                       0x28  // General Purpose Event
> 0a Enables
> +#define S_PCH_ACPI_GPE0a_EN                       4
> +#define B_PCH_ACPI_GPE0a_EN_CORE_GPIO             0xFF000000 // CORE
> GPIO Enable
> +#define B_PCH_ACPI_GPE0a_EN_SUS_GPIO              0x00FF0000 // SUS GPIO
> Enable
> +#define B_PCH_ACPI_GPE0a_EN_PME_B0                BIT13 // Power
> Management Event Bus 0 Enable
> +#define B_PCH_ACPI_GPE0a_EN_BATLOW                BIT10 // Battery Low
> Enable
> +#define B_PCH_ACPI_GPE0a_EN_PCI_EXP               BIT9  // PCI Express
> Enable
> +#define B_PCH_ACPI_GPE0a_EN_SWGPE                 BIT2  // Software GPE
> Enable
> +#define B_PCH_ACPI_GPE0a_EN_HOT_PLUG              BIT1  // Hot Plug Enable
> +#define N_PCH_ACPI_GPE0a_EN_PME_B0                13
> +#define N_PCH_ACPI_GPE0a_EN_BATLOW                10
> +#define N_PCH_ACPI_GPE0a_EN_PCI_EXP               9
> +#define N_PCH_ACPI_GPE0a_EN_SWGPE                 2
> +#define N_PCH_ACPI_GPE0a_EN_HOT_PLUG              1
> +
> +#define R_PCH_SMI_EN                              0x30  // SMI Control and Enable
> +#define S_PCH_SMI_EN                              4
> +#define B_PCH_SMI_EN_LEGACY_USB3                  BIT31 // Legacy USB 3
> Enable
> +#define B_PCH_SMI_EN_INTEL_USB2                   BIT18 // Intel USB 2 Enable
> +#define B_PCH_SMI_EN_LEGACY_USB2                  BIT17 // Legacy USB 2
> Enable
> +#define B_PCH_SMI_EN_PERIODIC                     BIT14 // Periodic Enable
> +#define B_PCH_SMI_EN_TCO                          BIT13 // TCO Enable
> +#define B_PCH_SMI_EN_BIOS_RLS                     BIT7  // BIOS RLS
> +#define B_PCH_SMI_EN_SWSMI_TMR                    BIT6  // Software SMI
> Timer Enable
> +#define B_PCH_SMI_EN_APMC                         BIT5  // APMC Enable
> +#define B_PCH_SMI_EN_ON_SLP_EN                    BIT4  // SMI On Sleep
> Enable
> +#define B_PCH_SMI_EN_BIOS                         BIT2  // BIOS Enable
> +#define B_PCH_SMI_EN_EOS                          BIT1  // End of SMI
> +#define B_PCH_SMI_EN_GBL_SMI                      BIT0  // Global SMI Enable
> +#define N_PCH_SMI_EN_LEGACY_USB3                  31
> +#define N_PCH_SMI_EN_GPIO_UNLOCK                  27
> +#define N_PCH_SMI_EN_INTEL_USB2                   18
> +#define N_PCH_SMI_EN_LEGACY_USB2                  17
> +#define N_PCH_SMI_EN_PERIODIC                     14
> +#define N_PCH_SMI_EN_TCO                          13
> +#define N_PCH_SMI_EN_BIOS_RLS                     7
> +#define N_PCH_SMI_EN_SWSMI_TMR                    6
> +#define N_PCH_SMI_EN_APMC                         5
> +#define N_PCH_SMI_EN_ON_SLP_EN                    4
> +#define N_PCH_SMI_EN_BIOS                         2
> +#define N_PCH_SMI_EN_EOS                          1
> +#define N_PCH_SMI_EN_GBL_SMI                      0
> +
> +#define R_PCH_SMI_STS                             0x34  // SMI Status Register
> +#define S_PCH_SMI_STS                             4
> +#define B_PCH_SMI_STS_LEGACY_USB3                 BIT31 // Legacy USB 3
> Status
> +#define B_PCH_SMI_STS_GUNIT_SMI                   BIT29 // GUNIT SMI Status
> +#define B_PCH_SMI_STS_PUNIT_SMI                   BIT28 // PUNIT SMI Status
> +#define B_PCH_SMI_STS_SPI                         BIT26 // SPI SMI Status
> +#define B_PCH_SMI_STS_PCI_EXP                     BIT20 // PCI Express SMI
> Status
> +#define B_PCH_SMI_STS_INTEL_USB2                  BIT18 // Intel USB 2 Status
> +#define B_PCH_SMI_STS_LEGACY_USB2                 BIT17 // Legacy USB 2
> Status
> +#define N_PCH_SMI_STS_TCO                         13
> +#define B_PCH_SMI_STS_SMBUS                       BIT16 // SMBUS SMI Status
> +#define B_PCH_SMI_STS_ILB                         BIT15 // ILB SMI Status
> +#define B_PCH_SMI_STS_PERIODIC                    BIT14 // Periodic Status
> +#define B_PCH_SMI_STS_TCO                         BIT13 // TCO Status
> +#define B_PCH_SMI_STS_GPE0                        BIT9  // GPE0 Status
> +#define B_PCH_SMI_STS_PM1_STS_REG                 BIT8  // PM1 Status
> Register
> +#define B_PCH_SMI_STS_SWSMI_TMR                   BIT6  // Software SMI
> Timer Status
> +#define B_PCH_SMI_STS_APM                         BIT5  // APM Status
> +#define B_PCH_SMI_STS_ON_SLP_EN                   BIT4  // SMI On Sleep
> Enable Status
> +#define B_PCH_SMI_STS_BIOS                        BIT2  // BIOS Status
> +#define N_PCH_SMI_STS_LEGACY_USB3                 31
> +#define N_PCH_SMI_STS_SPI                         26
> +#define N_PCH_SMI_STS_PCI_EXP                     20
> +#define N_PCH_SMI_STS_INTEL_USB2                  18
> +#define N_PCH_SMI_STS_LEGACY_USB2                 17
> +#define N_PCH_SMI_STS_SMBUS                       16
> +#define N_PCH_SMI_STS_ILB                         15
> +#define N_PCH_SMI_STS_PERIODIC                    14
> +#define N_PCH_SMI_STS_TCO                         13
> +#define N_PCH_SMI_STS_GPE0                        9
> +#define N_PCH_SMI_STS_PM1_STS_REG                 8
> +#define N_PCH_SMI_STS_SWSMI_TMR                   6
> +#define N_PCH_SMI_STS_APM                         5
> +#define N_PCH_SMI_STS_ON_SLP_EN                   4
> +#define N_PCH_SMI_STS_BIOS                        2
> +
> +#define R_PCH_ALT_GP_SMI_EN                       0x38  // Alternate GPI SMI
> Enable
> +#define S_PCH_ALT_GP_SMI_EN                       2
> +#define B_PCH_ALT_GP_SMI_EN_CORE_GPIO             0xFF00 // SUS GPIO
> SMI Enable
> +#define B_PCH_ALT_GP_SMI_EN_SUS_GPIO              0x00FF // CORE GPIO
> SMI Enable
> +
> +#define R_PCH_ALT_GP_SMI_STS                      0x3A  // Alternate GPI SMI
> Status
> +#define S_PCH_ALT_GP_SMI_STS                      2
> +#define B_PCH_ALT_GP_SMI_STS_CORE_GPIO            0xFF00 // SUS GPIO
> SMI Status
> +#define B_PCH_ALT_GP_SMI_STS_SUS_GPIO             0x00FF // CORE GPIO
> SMI Status
> +
> +#define R_PCH_UPRWC                               0x3C  // USB Per-Port Registers
> Write Control
> +#define S_PCH_UPRWC                               2
> +#define B_PCH_UPRWC_WR_EN_SMI_STS                 BIT8 // Write Enable
> Status
> +#define B_PCH_UPRWC_WR_EN                         BIT1 // USB Per-Port Registers
> Write Enable
> +#define B_PCH_UPRWC_WR_EN_SMI_EN                  BIT0 // Write Enable SMI
> Enable
> +
> +#define R_PCH_ACPI_GPE_CNTL                       0x40  // General Purpose Event
> Control
> +#define B_PCH_ACPI_GPE_CNTL_SWGPE_CTRL            BIT17 // Software GPE
> Control
> +#define B_PCH_ACPI_GPE_CNTL_PCIE3_SCI_EN          BIT3
> +#define B_PCH_ACPI_GPE_CNTL_PCIE2_SCI_EN          BIT2
> +#define B_PCH_ACPI_GPE_CNTL_PCIE1_SCI_EN          BIT1
> +#define B_PCH_ACPI_GPE_CNTL_PCIE0_SCI_EN          BIT0
> +
> +#define R_PCH_ACPI_PM2_CNT                        0x50  // PM2a Control Block
> +#define B_PCH_ACPI_PM2_CNT_ARB_DIS                BIT0  // Scratchpad Bit
> +
> +#define R_PCH_TCO_RLD                             0x60  // TCO Reload
> +#define B_PCH_TCO_RLD_VAL                         0x3FF // TCO Timer Count Value
> +
> +#define R_PCH_TCO_STS                             0x64  // TCO Timer Status
> +#define S_PCH_TCO_STS                             4
> +#define B_PCH_TCO_STS_SECOND_TO                   BIT17 // Second Timeout
> Status
> +#define B_PCH_TCO_STS_TIMEOUT                     BIT3  // Timeout
> +#define N_PCH_TCO_STS_TIMEOUT                     3
> +
> +#define R_PCH_TCO_CNT                             0x68  // TCO Control
> +#define S_PCH_TCO_CNT                             2
> +#define B_PCH_TCO_CNT_OS_POLICY                   (BIT21 | BIT20) // OS Policy
> +#define B_PCH_TCO_CNT_LOCK                        BIT12 // TCO Enable Lock
> +#define B_PCH_TCO_CNT_TMR_HLT                     BIT11 // TCO Timer Halt
> +
> +#define R_PCH_TCO_TMR                             0x70  // TCO Timer
> +#define B_PCH_TCO_TMR_TCO_TRLD                    0x3FF0000
> +
> +//
> +// PMC Memory Space Registers (PBASE)
> +//
> +#define R_PCH_PMC_PRSTS                           0x00  // Power and Reset Status
> +#define B_PCH_PMC_PRSTS_PRODID                    0xFF000000 // Power
> Management Controller Product ID
> +#define B_PCH_PMC_PRSTS_REVID                     0x00FF0000 // Power
> Management Controller Revision ID
> +#define B_PCH_PMC_PRSTS_PM_WD_TMR                 BIT15 // PMC
> Watchdog Timer Status
> +#define B_PCH_PMC_PRSTS_CODE_COPIED_STS           BIT11 // Patch
> Copied Over Status
> +#define B_PCH_PMC_PRSTS_CODE_LOAD_TO              BIT9  // Patch Load
> Timeout Status
> +#define B_PCH_PMC_PRSTS_OP_STS                    BIT8  // PMC Operational
> Status
> +#define B_PCH_PMC_PRSTS_SEC_GBLRST_STS            BIT7  // SEC Global
> Reset Status
> +#define B_PCH_PMC_PRSTS_SEC_WD_TMR_STS            BIT6  // SEC
> Watchdog Timer Status
> +#define B_PCH_PMC_PRSTS_WOL_OVR_WK_STS            BIT5  // Wake On
> LAN Override Wake Status
> +#define B_PCH_PMC_PRSTS_HOST_WAKE_STS             BIT4  // PMC Host
> Wake Status
> +
> +#define R_PCH_PMC_PM_CFG                          0x08  // Power Management
> Configuration
> +#define B_PCH_PMC_PM_CFG_SPS                      BIT5  // Shutdown Policy
> Select
> +#define B_PCH_PMC_PM_CFG_NO_REBOOT                BIT4  // No Reboot
> Strap
> +#define B_PCH_PMC_PM_CFG_SX_ENT_TO_EN             BIT3  // S1 / 3 / 4 / 5
> Entry Timeout Enable
> +#define B_PCH_PMC_PM_CFG_TIMING_T581              (BIT1 | BIT0) // Timing
> t581
> +
> +#define R_PCH_PMC_PM_STS                          0x0C  // Power Management
> Status
> +#define B_PCH_PMC_PM_STS_PMC_MSG_FULL             BIT24 // PMC
> Message Full Status
> +#define B_PCH_PMC_PM_STS_PMC_MSG_4_FULL           BIT23 // PMC 4
> Message Full Status
> +#define B_PCH_PMC_PM_STS_PMC_MSG_3_FULL           BIT22 // PMC 3
> Message Full Status
> +#define B_PCH_PMC_PM_STS_PMC_MSG_2_FULL           BIT21 // PMC 2
> Message Full Status
> +#define B_PCH_PMC_PM_STS_PMC_MSG_1_FULL           BIT20 // PMC 1
> Message Full Status
> +#define B_PCH_PMC_PM_STS_CODE_REQ                 BIT8  // Patch Request
> Status
> +#define B_PCH_PMC_PM_STS_HPR_ENT_TO               BIT2  // Host partition
> Reset Entry Timeout Status
> +#define B_PCH_PMC_PM_STS_SX_ENT_TO                BIT1  // S3 / 4 / 5 Entry
> Timeout Status
> +
> +#define R_PCH_PMC_MTPMC                           0x10  // Message to PMC
> +
> +#define R_PCH_PMC_GEN_PMCON_1                     0x20  // General PM
> Configuration 1
> +#define B_PCH_PMC_GEN_PMCON_UART_EN               BIT24 // UART Debug
> Port Enable
> +#define B_PCH_PMC_GEN_PMCON_DRAM_INIT             BIT23 // DRAM
> Initialization Scratchpad Bit
> +#define B_PCH_PMC_GEN_PMCON_MEM_SR                BIT21 // Memory
> Placed in Self-Refresh
> +#define B_PCH_PMC_GEN_PMCON_SRS                   BIT20 // System Reset
> Status
> +#define B_PCH_PMC_GEN_PMCON_CTS                   BIT19 // CPU Thermal
> Trip Status
> +#define B_PCH_PMC_GEN_PMCON_MIN_SLP_S4            BIT18 // Minimum
> SLP_S4# Assertion Width Violation Status
> +#define B_PCH_PMC_GEN_PMCON_PWROK_FLR             BIT16 // PWROK
> Failure
> +#define B_PCH_PMC_GEN_PMCON_PME_B0_S5_DIS         BIT15 // PME B0
> S5 Disable
> +#define B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR           BIT14 // SUS Well
> Power Failure
> +#define B_PCH_PMC_GEN_PMCON_WOL_ENABLE_OVERRIDE   BIT13 //
> WOL Enable Override
> +#define B_PCH_PMC_GEN_PMCON_DISABLE_SX_STRETCH    BIT12 //
> Disable SLP_X Scretching After SUS Well Power Up
> +#define B_PCH_PMC_GEN_PMCON_SLP_S3_MAW            (BIT11 | BIT10) //
> SLP_S3# Minimum Assertion Width
> +#define V_PCH_PMC_GEN_PMCON_SLP_S3_MAW_60US       0x000 // 60
> micro seconds
> +#define V_PCH_PMC_GEN_PMCON_SLP_S3_MAW_1MS        0x400 // 1 milli
> second
> +#define V_PCH_PMC_GEN_PMCON_SLP_S3_MAW_50MS       0x800 // 50
> milli seconds
> +#define V_PCH_PMC_GEN_PMCON_SLP_S3_MAW_2S         0xC00 // 2
> seconds
> +#define B_PCH_PMC_GEN_PMCON_GEN_RST_STS           BIT9  // General
> Reset Status
> +#define B_PCH_PMC_GEN_PMCON_RTC_RESERVED          BIT8  // RTC
> Reserved
> +#define B_PCH_PMC_GEN_PMCON_SWSMI_RTSL            (BIT7 | BIT6)  //
> SWSMI Rate Select
> +#define V_PCH_PMC_GEN_PMCON_SWSMI_RTSL_64MS       0xC0  // 64ms
> +/- 4ms
> +#define V_PCH_PMC_GEN_PMCON_SWSMI_RTSL_32MS       0x80  // 32ms
> +/- 4ms
> +#define V_PCH_PMC_GEN_PMCON_SWSMI_RTSL_16MS       0x40  // 16ms
> +/- 4ms
> +#define V_PCH_PMC_GEN_PMCON_SWSMI_RTSL_1_5MS      0x00  //
> 1.5ms +/- 0.6ms
> +#define B_PCH_PMC_GEN_PMCON_SLP_S4_MAW            (BIT5 | BIT4) //
> SLP_S4# Minimum Assertion Width
> +#define V_PCH_PMC_GEN_PMCON_SLP_S4_MAW_1S         0x30  // 1
> second
> +#define V_PCH_PMC_GEN_PMCON_SLP_S4_MAW_2S         0x20  // 2
> seconds
> +#define V_PCH_PMC_GEN_PMCON_SLP_S4_MAW_3S         0x10  // 3
> seconds
> +#define V_PCH_PMC_GEN_PMCON_SLP_S4_MAW_4S         0x00  // 4
> seconds
> +#define B_PCH_PMC_GEN_PMCON_SLP_S4_ASE            BIT3  // SLP_S4#
> Assertion Scretch Enable
> +#define B_PCH_PMC_GEN_PMCON_RTC_PWR_STS           BIT2  // RTC
> Power Status
> +#define B_PCH_PMC_GEN_PMCON_AFTERG3_EN            BIT0  // After G3
> State Enable
> +
> +#define R_PCH_PMC_GEN_PMCON_2                     0x24  // General PM
> Configuration 2
> +#define B_PCH_PMC_GEN_PMCON_LOCK_S4_STRET_LD      BIT18 // SLP_S3
> / SLP_S4 Stretching Policy Lock-Down
> +#define B_PCH_PMC_GEN_PMCON_BIOS_PCI_EXP_EN       BIT10 // BIOS
> PCI Express Enable
> +#define B_PCH_PMC_GEN_PMCON_PWRBTN_LVL            BIT9  // Power
> Button Level
> +#define B_PCH_PMC_GEN_PMCON_SMI_LOCK              BIT4  // SMI Lock
> +#define B_PCH_PMC_GEN_PMCON_PER_SMI_SEL           (BIT1 | BIT0) //
> Period SMI Select
> +#define V_PCH_PMC_GEN_PMCON_PER_SMI_64S           0x0000 // 64
> seconds
> +#define V_PCH_PMC_GEN_PMCON_PER_SMI_32S           0x0001 // 32
> seconds
> +#define V_PCH_PMC_GEN_PMCON_PER_SMI_16S           0x0002 // 16
> seconds
> +#define V_PCH_PMC_GEN_PMCON_PER_SMI_8S            0x0003 //  8
> seconds
> +
> +#define R_PCH_PMC_MFPMC                           0x28  // Message from PMC
> +
> +#define R_PCH_PMC_SEC_STS                         0x2C  // SEC Status
> +#define B_PCH_PMC_SEC_STS_SEC                     (BIT3 | BIT2 | BIT1 | BIT0) //
> SEC Exclusion Cause
> +
> +#define R_PCH_PMC_CRID                            0x30  // Configured Revision ID
> +#define B_PCH_PMC_CRID_RID_SEL                    (BIT1 | BIT0) // Revision ID
> Select
> +
> +#define R_PCH_PMC_FUNC_DIS                        0x34  // Function Disable
> Register
> +#define B_PCH_PMC_FUNC_DIS_LPSS2_FUNC7            BIT31 // LPSS2 I2C #7
> +#define B_PCH_PMC_FUNC_DIS_LPSS2_FUNC6            BIT30 // LPSS2 I2C #6
> +#define B_PCH_PMC_FUNC_DIS_LPSS2_FUNC5            BIT29 // LPSS2 I2C #5
> +#define B_PCH_PMC_FUNC_DIS_LPSS2_FUNC4            BIT28 // LPSS2 I2C #4
> +#define B_PCH_PMC_FUNC_DIS_LPSS2_FUNC3            BIT27 // LPSS2 I2C #3
> +#define B_PCH_PMC_FUNC_DIS_LPSS2_FUNC2            BIT26 // LPSS2 I2C #2
> +#define B_PCH_PMC_FUNC_DIS_LPSS2_FUNC1            BIT25 // LPSS2 I2C #1
> +#define B_PCH_PMC_FUNC_DIS_LPSS2_FUNC0            BIT24 // LPSS2 DMA
> Disable
> +#define B_PCH_PMC_FUNC_DIS_PCI_EX_FUNC3           BIT23 // PCI Express
> Function 3 Disable
> +#define B_PCH_PMC_FUNC_DIS_PCI_EX_FUNC2           BIT22 // PCI Express
> Function 2 Disable
> +#define B_PCH_PMC_FUNC_DIS_PCI_EX_FUNC1           BIT21 // PCI Express
> Function 1 Disable
> +#define B_PCH_PMC_FUNC_DIS_PCI_EX_FUNC0           BIT20 // PCI Express
> Function 0 Disable
> +#define N_PCH_PMC_FUNC_DIS_PCI_EX_FUNC0           20
> +#define B_PCH_PMC_FUNC_DIS_SEC                    BIT19 // SEC Disable
> +#define B_PCH_PMC_FUNC_DIS_USB                    BIT18 // USB Disable
> +#define B_PCH_PMC_FUNC_DIS_SATA                   BIT17 // SATA Disable
> +#define B_PCH_PMC_FUNC_DIS_USH                    BIT15 // USH (USB3)
> Disable
> +#define B_PCH_PMC_FUNC_DIS_OTG                    BIT14 // USB OTG Disable
> +#define B_PCH_PMC_FUNC_DIS_LPE                    BIT13 // LPE Disable
> +#define B_PCH_PMC_FUNC_DIS_AZALIA                 BIT12 // Azalia Disable
> +#define B_PCH_PMC_FUNC_DIS_MIPI                   BIT11 // MIPI-HSI Disable
> +#define B_PCH_PMC_FUNC_DIS_SDIO4                  BIT11 // SCC SDIO #4
> (Device 23, eMMC4.5) Disable
> +#define B_PCH_PMC_FUNC_DIS_SDIO3                  BIT10 // SCC SDIO #3
> (Device 18, SD Card) Disable
> +#define B_PCH_PMC_FUNC_DIS_SDIO2                  BIT9  // SCC SDIO #2
> (Device 17, SDIO) Disable
> +#define B_PCH_PMC_FUNC_DIS_SDIO1                  BIT8  // SCC SDIO #1
> (Device 16, eMMC) Disable
> +#define B_PCH_PMC_FUNC_DIS_LPSS1_FUNC7            BIT7  // LPSS1 Spare
> #2 Disable
> +#define B_PCH_PMC_FUNC_DIS_LPSS1_FUNC6            BIT6  // LPSS1 Spare
> #1 Disable
> +#define B_PCH_PMC_FUNC_DIS_LPSS1_FUNC5            BIT5  // LPSS1 SPI
> Disable
> +#define B_PCH_PMC_FUNC_DIS_LPSS1_FUNC4            BIT4  // LPSS1 HS-
> UART #2 Disable
> +#define B_PCH_PMC_FUNC_DIS_LPSS1_FUNC3            BIT3  // LPSS1 HS-
> UART #1 Disable
> +#define B_PCH_PMC_FUNC_DIS_LPSS1_FUNC2            BIT2  // LPSS1 PWM
> #2 Disable
> +#define B_PCH_PMC_FUNC_DIS_LPSS1_FUNC1            BIT1  // LPSS1 PWM
> #1 Disable
> +#define B_PCH_PMC_FUNC_DIS_LPSS1_FUNC0            BIT0  // LPSS1 DMA
> Disable
> +
> +#define R_PCH_PMC_FUNC_DIS2                       0x38  // Function Disable 2
> Register
> +#define B_PCH_PMC_FUNC_DIS2_USH_SS_PHY            BIT2  // USH Super
> Speed PHY Disable
> +#define B_PCH_PMC_FUNC_DIS2_OTG_SS_PHY            BIT1  // OTG Super
> Speed PHY Disable
> +#define B_PCH_PMC_FUNC_DIS2_SMBUS                 BIT0  // SMBus Disable
> +
> +#define R_PCH_PMC_PMIR                            0x48  // Extended Test Mode
> Register (ETR)
> +#define B_PCH_PMC_PMIR_CF9LOCK                    BIT31 // CF9h Lockdown
> +#define B_PCH_PMC_PMIR_LTR_DEF                    BIT22 // LTR Default
> +#define B_PCH_PMC_PMIR_IGNORE_HPET                BIT21 // Ignore HPET
> Disable Check Before Going to S0i2
> +#define B_PCH_PMC_PMIR_CF9GR                      BIT20 // CF9h Global Reset
> +
> +#define R_PCH_PMC_VLT                             0x50  // Voltage Detect Register
> +#define B_PCH_PMC_VLT_FUSES                       0xFF  // Voltage Detect Fuses
> +
> +#define R_PCH_PMC_GPI_ROUT                        0x58  // GPI Rout
> +#define B_PCH_PMC_GPI_ROUT_0                      (BIT1 | BIT0)
> +#define B_PCH_PMC_GPI_ROUT_1                      (BIT3 | BIT2)
> +#define B_PCH_PMC_GPI_ROUT_2                      (BIT5 | BIT4)
> +#define B_PCH_PMC_GPI_ROUT_3                      (BIT7 | BIT6)
> +#define B_PCH_PMC_GPI_ROUT_4                      (BIT9 | BIT8)
> +#define B_PCH_PMC_GPI_ROUT_5                      (BIT11 | BIT10)
> +#define B_PCH_PMC_GPI_ROUT_6                      (BIT13 | BIT12)
> +#define B_PCH_PMC_GPI_ROUT_7                      (BIT15 | BIT14)
> +#define B_PCH_PMC_GPI_ROUT_8                      (BIT17 | BIT16)
> +#define B_PCH_PMC_GPI_ROUT_9                      (BIT19 | BIT18)
> +#define B_PCH_PMC_GPI_ROUT_10                     (BIT21 | BIT20)
> +#define B_PCH_PMC_GPI_ROUT_11                     (BIT23 | BIT22)
> +#define B_PCH_PMC_GPI_ROUT_12                     (BIT25 | BIT24)
> +#define B_PCH_PMC_GPI_ROUT_13                     (BIT27 | BIT26)
> +#define B_PCH_PMC_GPI_ROUT_14                     (BIT29 | BIT28)
> +#define B_PCH_PMC_GPI_ROUT_15                     (BIT31 | BIT30)
> +
> +#define R_PCH_PMC_PCC0                            0x60  // Platform Clock Control 0
> +#define B_PCH_PMC_PCC0_CLK_FREQ                   BIT2  // Clock Frequency
> +#define B_PCH_PMC_PCC0_CLK_CTL                    (BIT1 | BIT0) // Clock Gating
> +
> +#define R_PCH_PMC_PCC1                            0x64  // Platform Clock Control 1
> +#define B_PCH_PMC_PCC1_CLK_FREQ                   BIT2  // Clock Frequency
> +#define B_PCH_PMC_PCC1_CLK_CTL                    (BIT1 | BIT0) // Clock Gating
> +
> +#define R_PCH_PMC_PCC2                            0x68  // Platform Clock Control 2
> +#define B_PCH_PMC_PCC2_CLK_FREQ                   BIT2  // Clock Frequency
> +#define B_PCH_PMC_PCC2_CLK_CTL                    (BIT1 | BIT0) // Clock Gating
> +
> +#define R_PCH_PMC_PCC3                            0x6C  // Platform Clock Control 3
> +#define B_PCH_PMC_PCC3_CLK_FREQ                   BIT2  // Clock Frequency
> +#define B_PCH_PMC_PCC3_CLK_CTL                    (BIT1 | BIT0) // Clock Gating
> +
> +#define R_PCH_PMC_PCC4                            0x70  // Platform Clock Control 4
> +#define B_PCH_PMC_PCC4_CLK_FREQ                   BIT2  // Clock Frequency
> +#define B_PCH_PMC_PCC4_CLK_CTL                    (BIT1 | BIT0) // Clock Gating
> +
> +#define R_PCH_PMC_PCC5                            0x74  // Platform Clock Control 5
> +#define B_PCH_PMC_PCC5_CLK_FREQ                   BIT2  // Clock Frequency
> +#define B_PCH_PMC_PCC5_CLK_CTL                    (BIT1 | BIT0) // Clock Gating
> +
> +#define R_PCH_PMC_S0IR_TMR                        0x80  // S0I Ready Residency
> Timer
> +#define B_PCH_PMC_S0IR_TMR_RTIME                  0xFFFFFFFF // Time Spent
> in S0I Ready State
> +
> +#define R_PCH_PMC_S0I1_TMR                        0x84  // S0I1 Ready Residency
> Timer
> +#define B_PCH_PMC_S0I1_TMR_RTIME                  0xFFFFFFFF // Time Spent
> in S0I1 Ready State
> +
> +#define R_PCH_PMC_S0I2_TMR                        0x88  // S0I2 Ready Residency
> Timer
> +#define B_PCH_PMC_S0I2_TMR_RTIME                  0xFFFFFFFF // Time Spent
> in S0I2 Ready State
> +
> +#define R_PCH_PMC_S0I3_TMR                        0x8C  // S0I3 Ready Residency
> Timer
> +#define B_PCH_PMC_S0I3_TMR_RTIME                  0xFFFFFFFF // Time Spent
> in S0I3 Ready State
> +
> +#define R_PCH_PMC_S0_TMR                          0x90  // S0 Residency Timer
> +#define B_PCH_PMC_S0_TMR_RTIME                    0xFFFFFFFF // Time Spent
> in S0 State
> +
> +#define R_PCH_PMC_PSS                             0x98  // Power Island Power Status
> +#define B_PCH_PMC_PSS_PG_STS                      0x3FFFF // Power Gate Status
> of All Power Islands
> +#define B_PCH_PMC_PSS_PG_STS_USB_SUS              BIT17 // USB SUS
> +#define B_PCH_PMC_PSS_PG_STS_USB                  BIT16 // USB
> +#define B_PCH_PMC_PSS_PG_STS_OTG_VCCACLK          BIT15 // OTG
> VCCACLK
> +#define B_PCH_PMC_PSS_PG_STS_OTG VCCA             BIT14 // OTG VCCA
> +#define B_PCH_PMC_PSS_PG_STS_OTG_VCCS             BIT13 // OTG VCCS
> +#define B_PCH_PMC_PSS_PG_STS_OTG_CTL              BIT12 // OTG Control
> +#define B_PCH_PMC_PSS_PG_STS_USH_VCCA             BIT11 // USH VCCA
> +#define B_PCH_PMC_PSS_PG_STS_USH_VCCS             BIT10 // USH VCCS
> +#define B_PCH_PMC_PSS_PG_STS_USH_SUS              BIT9  // USH SUS
> +#define B_PCH_PMC_PSS_PG_STS_USH_CTL              BIT8  // USH Control
> +#define B_PCH_PMC_PSS_PG_STS_DFX                  BIT7  // DFX
> +#define B_PCH_PMC_PSS_PG_STS_LPE                  BIT6  // LPE Audio
> +#define B_PCH_PMC_PSS_PG_STS_LPSS                 BIT5  // LPSS
> +#define B_PCH_PMC_PSS_PG_STS_PCIE                 BIT4  // PCIe
> +#define B_PCH_PMC_PSS_PG_STS_HDA                  BIT2  // HDA
> +#define B_PCH_PMC_PSS_PG_STS_SATA                 BIT1  // SATA
> +
> +#define R_PCH_PMC_D3_STS_0                        0xA0  // D3 Status 0
> +#define B_PCH_PMC_D3_STS_0_LPSS1F7                BIT31 // LPSS 1 Function 7
> +#define B_PCH_PMC_D3_STS_0_LPSS1F6                BIT30 // LPSS 1 Function 6
> +#define B_PCH_PMC_D3_STS_0_LPSS1F5                BIT29 // LPSS 1 Function 5
> +#define B_PCH_PMC_D3_STS_0_LPSS1F4                BIT28 // LPSS 1 Function 4
> +#define B_PCH_PMC_D3_STS_0_LPSS1F3                BIT27 // LPSS 1 Function 3
> +#define B_PCH_PMC_D3_STS_0_LPSS1F2                BIT26 // LPSS 1 Function 2
> +#define B_PCH_PMC_D3_STS_0_LPSS1F1                BIT25 // LPSS 1 Function 1
> +#define B_PCH_PMC_D3_STS_0_LPSS1F0                BIT24 // LPSS 1 Function 0
> +#define B_PCH_PMC_D3_STS_0_PCIEF3                 BIT23 // PCIe Function 3
> +#define B_PCH_PMC_D3_STS_0_PCIEF2                 BIT22 // PCIe Function 2
> +#define B_PCH_PMC_D3_STS_0_PCIEF1                 BIT21 // PCIe Function 1
> +#define B_PCH_PMC_D3_STS_0_PCIEF0                 BIT20 // PCIe Function 0
> +#define B_PCH_PMC_D3_STS_0_USB                    BIT18 // USB
> +#define B_PCH_PMC_D3_STS_0_SATA                   BIT17 // SATA
> +#define B_PCH_PMC_D3_STS_0_USH                    BIT15 // USH
> +#define B_PCH_PMC_D3_STS_0_OTG                    BIT14 // OTG
> +#define B_PCH_PMC_D3_STS_0_LPE                    BIT13 // LPE
> +#define B_PCH_PMC_D3_STS_0_HDA                    BIT12 // HDA
> +#define B_PCH_PMC_D3_STS_0_MIPI                   BIT11 // MIPI-HSI
> +#define B_PCH_PMC_D3_STS_0_SCCF2                  BIT10 // SCC Function 2
> +#define B_PCH_PMC_D3_STS_0_SCCF1                  BIT9  // SCC Function 1
> +#define B_PCH_PMC_D3_STS_0_SCCF0                  BIT8  // SCC Function 0
> +#define B_PCH_PMC_D3_STS_0_LPSS0F7                BIT7  // LPSS 0 Function 7
> +#define B_PCH_PMC_D3_STS_0_LPSS0F6                BIT6  // LPSS 0 Function 6
> +#define B_PCH_PMC_D3_STS_0_LPSS0F5                BIT5  // LPSS 0 Function 5
> +#define B_PCH_PMC_D3_STS_0_LPSS0F4                BIT4  // LPSS 0 Function 4
> +#define B_PCH_PMC_D3_STS_0_LPSS0F3                BIT3  // LPSS 0 Function 3
> +#define B_PCH_PMC_D3_STS_0_LPSS0F2                BIT2  // LPSS 0 Function 2
> +#define B_PCH_PMC_D3_STS_0_LPSS0F1                BIT1  // LPSS 0 Function 1
> +#define B_PCH_PMC_D3_STS_0_LPSS0F0                BIT0  // LPSS 0 Function 0
> +
> +#define R_PCH_PMC_D3_STS_1                        0xA4  // D3 Status 1
> +#define B_PCH_PMC_D3_STS_1_DFX                    BIT3  // DFX
> +#define B_PCH_PMC_D3_STS_1_OTG_SS                 BIT2  // OTG SS
> +#define B_PCH_PMC_D3_STS_1_USH_SS                 BIT1  // USH SS
> +#define B_PCH_PMC_D3_STS_1_SMB                    BIT0  // SMBus
> +#define R_PCH_PMC_D3_STDBY_STS_0                  0xA8  // D3 Standby Status
> 0
> +#define B_PCH_PMC_D3_STDBY_STS_0_LPSS1F7          BIT31 // LPSS 1
> Function 7
> +#define B_PCH_PMC_D3_STDBY_STS_0_LPSS1F6          BIT30 // LPSS 1
> Function 6
> +#define B_PCH_PMC_D3_STDBY_STS_0_LPSS1F5          BIT29 // LPSS 1
> Function 5
> +#define B_PCH_PMC_D3_STDBY_STS_0_LPSS1F4          BIT28 // LPSS 1
> Function 4
> +#define B_PCH_PMC_D3_STDBY_STS_0_LPSS1F3          BIT27 // LPSS 1
> Function 3
> +#define B_PCH_PMC_D3_STDBY_STS_0_LPSS1F2          BIT26 // LPSS 1
> Function 2
> +#define B_PCH_PMC_D3_STDBY_STS_0_LPSS1F1          BIT25 // LPSS 1
> Function 1
> +#define B_PCH_PMC_D3_STDBY_STS_0_LPSS1F0          BIT24 // LPSS 1
> Function 0
> +#define B_PCH_PMC_D3_STDBY_STS_0_PCIEF3           BIT23 // PCIe Function
> 3
> +#define B_PCH_PMC_D3_STDBY_STS_0_PCIEF2           BIT22 // PCIe Function
> 2
> +#define B_PCH_PMC_D3_STDBY_STS_0_PCIEF1           BIT21 // PCIe Function
> 1
> +#define B_PCH_PMC_D3_STDBY_STS_0_PCIEF0           BIT20 // PCIe Function
> 0
> +#define B_PCH_PMC_D3_STDBY_STS_0_USB              BIT18 // USB
> +#define B_PCH_PMC_D3_STDBY_STS_0_SATA             BIT17 // SATA
> +#define B_PCH_PMC_D3_STDBY_STS_0_USH              BIT15 // USH
> +#define B_PCH_PMC_D3_STDBY_STS_0_OTG              BIT14 // OTG
> +#define B_PCH_PMC_D3_STDBY_STS_0_LPE              BIT13 // LPE
> +#define B_PCH_PMC_D3_STDBY_STS_0_HDA              BIT12 // HDA
> +#define B_PCH_PMC_D3_STDBY_STS_0_MIPI             BIT11 // MIPI-HSI
> +#define B_PCH_PMC_D3_STDBY_STS_0_SCCF2            BIT10 // SCC Function
> 2
> +#define B_PCH_PMC_D3_STDBY_STS_0_SCCF1            BIT9  // SCC Function 1
> +#define B_PCH_PMC_D3_STDBY_STS_0_SCCF0            BIT8  // SCC Function 0
> +#define B_PCH_PMC_D3_STDBY_STS_0_LPSS0F7          BIT7  // LPSS 0
> Function 7
> +#define B_PCH_PMC_D3_STDBY_STS_0_LPSS0F6          BIT6  // LPSS 0
> Function 6
> +#define B_PCH_PMC_D3_STDBY_STS_0_LPSS0F5          BIT5  // LPSS 0
> Function 5
> +#define B_PCH_PMC_D3_STDBY_STS_0_LPSS0F4          BIT4  // LPSS 0
> Function 4
> +#define B_PCH_PMC_D3_STDBY_STS_0_LPSS0F3          BIT3  // LPSS 0
> Function 3
> +#define B_PCH_PMC_D3_STDBY_STS_0_LPSS0F2          BIT2  // LPSS 0
> Function 2
> +#define B_PCH_PMC_D3_STDBY_STS_0_LPSS0F1          BIT1  // LPSS 0
> Function 1
> +#define B_PCH_PMC_D3_STDBY_STS_0_LPSS0F0          BIT0  // LPSS 0
> Function 0
> +
> +#define R_PCH_PMC_D3_STDBY_STS_1                  0xAC  // D3 Standby Status
> 1
> +#define B_PCH_PMC_D3_STDBY_STS_1_DFX              BIT3  // DFX
> +#define B_PCH_PMC_D3_STDBY_STS_1_OTG_SS           BIT2  // OTG SS
> +#define B_PCH_PMC_D3_STDBY_STS_1_USH_SS           BIT1  // USH SS
> +#define B_PCH_PMC_D3_STDBY_STS_1_SMB              BIT0  // SMBus
> +
> +#define R_PCH_PMC_MTPMC1                          0xB0  // Message to PMC 1
> +
> +#define R_PCH_PMC_MTPMC2                          0xB4  // Message to PMC 2
> +
> +#define R_PCH_PMC_MTPMC3                          0xB8  // Message to PMC 3
> +
> +#define R_PCH_PMC_MTPMC4                          0xBC  // Message to PMC 4
> +
> +//
> +// IO Memory Space Registers (IOBASE)
> +//
> +#define R_PCH_CFIO_PAD_CONF0                      0x00  // CFIO PAD_CONF0
> +#define R_PCH_CFIO_PAD_CONF1                      0x04  // CFIO PAD_CONF1
> +#define R_PCH_CFIO_PAD_VAL                        0x08  // CFIO PAD_VAL
> +#define R_PCH_CFIO_PAD_DFT                        0x0C  // CFIO PAD_CFT
> +
> +//
> +// GPIO Register Offsets from GBASE
> +//
> +#define R_PCH_GPIO_SC_USE_SEL                     0x00  // GPIO South Usage
> Select [31:0]
> +#define R_PCH_GPIO_SC_IO_SEL                      0x04  // GPIO South Input /
> Output Select [31:0]
> +#define R_PCH_GPIO_SC_LVL                         0x08  // GPIO South Level for
> Input or Output [31:0]
> +
> +#define R_PCH_GPIO_SC_TPE                         0x0C  // GPIO South Trigger
> Positive Edge Enable [31:0]
> +#define R_PCH_GPIO_SC_TNE                         0x10  // GPIO South Trigger
> Negative Edge Enable [31:0]
> +#define R_PCH_GPIO_SC_TS                          0x14  // GPIO South Trigger Status
> [31:0]
> +
> +#define R_PCH_GPIO_SC_USE_SEL2                    0x20  // GPIO South Usage
> Select 2 [63:32]
> +#define R_PCH_GPIO_SC_IO_SEL2                     0x24  // GPIO South Input /
> Output Select 2 [63:32]
> +#define R_PCH_GPIO_SC_LVL2                        0x28  // GPIO South Level for
> Input or Output 2 [63:32]
> +
> +#define R_PCH_GPIO_SC_TPE2                        0x2C  // GPIO South Trigger
> Positive Edge Enable 2 [63:32]
> +#define R_PCH_GPIO_SC_TNE2                        0x30  // GPIO South Trigger
> Negative Edge Enable 2 [63:32]
> +#define R_PCH_GPIO_SC_TS2                         0x34  // GPIO South Trigger
> Status 2 [63:32]
> +
> +#define R_PCH_GPIO_SC_USE_SEL3                    0x40  // GPIO South Usage
> Select 3 [95:64]
> +#define R_PCH_GPIO_SC_IO_SEL3                     0x44  // GPIO South Input /
> Output Select 3 [95:64]
> +#define R_PCH_GPIO_SC_LVL3                        0x48  // GPIO South Level for
> Input or Output 3 [95:64]
> +
> +#define R_PCH_GPIO_SC_TPE3                        0x4C  // GPIO South Trigger
> Positive Edge Enable 3 [95:64]
> +#define R_PCH_GPIO_SC_TNE3                        0x50  // GPIO South Trigger
> Negative Edge Enable 3 [95:64]
> +#define R_PCH_GPIO_SC_TS3                         0x54  // GPIO South Trigger
> Status 3 [95:64]
> +
> +#define R_PCH_GPIO_SC_USE_SEL4                    0x60  // GPIO South Usage
> Select 4 [127:96]
> +#define R_PCH_GPIO_SC_IO_SEL4                     0x64  // GPIO South Input /
> Output Select 4 [127:96]
> +#define R_PCH_GPIO_SC_LVL4                        0x68  // GPIO South Level for
> Input or Output 4 [127:96]
> +
> +#define R_PCH_GPIO_SC_TPE4                        0x6C  // GPIO South Trigger
> Positive Edge Enable 4 [127:96]
> +#define R_PCH_GPIO_SC_TNE4                        0x70  // GPIO South Trigger
> Negative Edge Enable 4 [127:96]
> +#define R_PCH_GPIO_SC_TS4                         0x74  // GPIO South Trigger
> Status 4 [127:96]
> +
> +#define R_PCH_GPIO_SUS_USE_SEL                    0x80  // GPIO Suspend Use
> Select [31:0]
> +#define R_PCH_GPIO_SUS_IO_SEL                     0x84  // GPIO Suspend Input /
> Output Select [31:0]
> +#define R_PCH_GPIO_SUS_LVL                        0x88  // GPIO Suspend Level for
> Input or Output [31:0]
> +
> +#define R_PCH_GPIO_SUS_TPE                        0x8C  // GPIO Suspend Trigger
> Positive Edge Enable [31:0]
> +#define R_PCH_GPIO_SUS_TNE                        0x90  // GPIO Suspend Trigger
> Negative Edge Enable [31:0]
> +#define R_PCH_GPIO_SUS_TS                         0x94  // GPIO Suspend Trigger
> Status [31:0]
> +
> +#define R_PCH_GPIO_SUS_WAKE_EN                    0x98  // GPIO Suspend
> Wake Enable [31:0]
> +
> +#define R_PCH_GPIO_SUS_USE_SEL2                   0x100 // GPIO Suspend Use
> Select 2 [42:32]
> +#define R_PCH_GPIO_SUS_IO_SEL2                    0x104 // GPIO Suspend Input
> / Output Select 2 [42:32]
> +#define R_PCH_GPIO_SUS_LVL2                       0x108 // GPIO Suspend Level
> for Input or Output 2 [42:32]
> +
> +#define R_PCH_GPIO_SUS_TPE2                       0x10C // GPIO Suspend Trigger
> Positive Edge Enable [42:32]
> +#define R_PCH_GPIO_SUS_TNE2                       0x110 // GPIO Suspend Trigger
> Negative Edge Enable [42:32]
> +#define R_PCH_GPIO_SUS_TS2                        0x114 // GPIO Suspend Trigger
> Status [42:32]
> +
> +#define R_PCH_GPIO_SUS_WAKE_EN2                   0x118 // GPIO Suspend
> Wake Enable 2 [42:32]
> +
> +//
> +// Fixed IO Space
> +//
> +
> +//
> +// Processor Interface Registers
> +//
> +#define R_PCH_NMI_SC                              0x61  // NMI Status and Control
> +#define B_PCH_NMI_SC_SERR_NMI_STS                 BIT7  // SERR# NMI Status
> +#define B_PCH_NMI_SC_IOCHK_NMI_STS                BIT6  // IOCHK NMI
> Status
> +#define B_PCH_NMI_SC_TMR2_OUT_STS                 BIT5  // Timer Counter 2
> Status
> +#define B_PCH_NMI_SC_REF_TOGGLE                   BIT4  // Refresh Cycle
> toggle Status
> +#define B_PCH_NMI_SC_IOCHK_NMI_EN                 BIT3  // IOCHK NMI
> Enable
> +#define B_PCH_NMI_SC_PCI_SERR_EN                  BIT2  // SERR# NMI Enable
> +#define B_PCH_NMI_SC_SPKR_DAT_EN                  BIT1  // Speaker Data
> Enable
> +#define B_PCH_NMI_SC_TIM_CNT2_EN                  BIT0  // Timer Counter 2
> Enable
> +
> +#define R_PCH_NMI_EN                              0x70  // NMI Enable and Real Time
> Clock Index, Co-function with R_PCH_RTC_INDEX
> +#define B_PCH_NMI_EN_NMI_EN                       BIT7  // NMI Enable, must
> preserve this bit first before writing to IO port 0x70
> +
> +//
> +// RTC Registers
> +//
> +#define R_PCH_RTC_INDEX                           0x70  // NMI Enable and Real Time
> Clock Index, Co-function with R_PCH_NMI_EN
> +#define R_PCH_RTC_TARGET                          0x71  // Real-Time Clock Target
> Register
> +#define R_PCH_RTC_EXT_INDEX                       0x72  // Extended RAM Index
> Register
> +#define R_PCH_RTC_EXT_TARGET                      0x73  // Extended RAM Target
> Register
> +#define R_PCH_RTC_INDEX2                          0x74  // Real-Time Clock Index
> Register
> +#define R_PCH_RTC_TARGET2                         0x75  // Real-Time Clock Target
> Register
> +#define R_PCH_RTC_EXT_INDEX2                      0x76  // Extended RAM Index
> Register
> +#define R_PCH_RTC_EXT_TARGET2                     0x77  // Extended RAM Target
> Register
> +
> +#define R_PCH_RTC_SECONDS                         0x00  // Seconds, Range 0..59
> +#define R_PCH_RTC_SECONDSALARM                    0x01  // Seconds Alarm,
> Range 0..59
> +#define R_PCH_RTC_MINUTES                         0x02  // Minutes, Range 0..59
> +#define R_PCH_RTC_MINUTESALARM                    0x03  // Minutes Alarm,
> Range 0..59
> +#define R_PCH_RTC_HOURS                           0x04  // Hours, Range 1..12 or
> 0..23 Bit 7 is AM/PM
> +#define R_PCH_RTC_HOURSALARM                      0x05  // Hours Alarm, Range
> 1..12 or 0..23 Bit 7 is AM/PM
> +#define R_PCH_RTC_DAYOFWEEK                       0x06  // Day of Week, Range
> 1..7
> +#define R_PCH_RTC_DAYOFMONTH                      0x07  // Day of Month,
> Range 1..31
> +#define R_PCH_RTC_MONTH                           0x08  // Month, Range 1..12
> +#define R_PCH_RTC_YEAR                            0x09  // Year, Range 0..99
> +
> +#define R_PCH_RTC_REGISTERA                       0x0A  // RTC Register A
> +#define B_PCH_RTC_REGISTERA_UIP                   BIT7  // Update In Progress
> +#define B_PCH_RTC_REGISTERA_DV                    (BIT6 | BIT5 | BIT4) //
> Division Chain Select
> +#define V_PCH_RTC_REGISTERA_DV_NORM_OP            0x20  // Normal
> Operation
> +#define V_PCH_RTC_REGISTERA_DV_BYP_5              0x30  // Bypass 5 Stages
> (Test mode only)
> +#define V_PCH_RTC_REGISTERA_DV_BYP_10             0x40  // Bypass 10
> Stages (Test mode only)
> +#define V_PCH_RTC_REGISTERA_DV_BYP_15             0x50  // Bypass 15
> Stages (Test mode only)
> +#define V_PCH_RTC_REGISTERA_DV_DIV_RST1           0x60  // Divider Reset
> +#define V_PCH_RTC_REGISTERA_DV_DIV_RST2           0x70  // Divider Reset
> +#define B_PCH_RTC_REGISTERA_RS                    (BIT3 | BIT2 | BIT1 | BIT0) //
> Rate Select
> +#define V_PCH_RTC_REGISTERA_RS_INT_NV_TGL         0x00  // Interrupt
> Never Toggles
> +#define V_PCH_RTC_REGISTERA_RS_3P906MS1           0x01  // 3.90625 ms
> +#define V_PCH_RTC_REGISTERA_RS_7P812MS1           0x02  // 7.8125 ms
> +#define V_PCH_RTC_REGISTERA_RS_122P0US            0x03  // 122.070 us
> +#define V_PCH_RTC_REGISTERA_RS_244P1US            0x04  // 244.141 us
> +#define V_PCH_RTC_REGISTERA_RS_488P2US            0x05  // 488.281 us
> +#define V_PCH_RTC_REGISTERA_RS_976P5US            0x06  // 976.5625 us
> +#define V_PCH_RTC_REGISTERA_RS_1P953MS            0x07  // 1.953125 ms
> +#define V_PCH_RTC_REGISTERA_RS_3P906MS            0x08  // 3.90625 ms
> +#define V_PCH_RTC_REGISTERA_RS_7P812MS            0x09  // 7.8125 ms
> +#define V_PCH_RTC_REGISTERA_RS_15P62MS            0x0A  // 15.625 ms
> +#define V_PCH_RTC_REGISTERA_RS_31P25MS            0x0B  // 31.25 ms
> +#define V_PCH_RTC_REGISTERA_RS_62P5MS             0x0C  // 62.5 ms
> +#define V_PCH_RTC_REGISTERA_RS_125MS              0x0D  // 125 ms
> +#define V_PCH_RTC_REGISTERA_RS_250MS              0x0E  // 250 ms
> +#define V_PCH_RTC_REGISTERA_RS_500MS              0x0F  // 500 ms
> +
> +#define R_PCH_RTC_REGISTERB                       0x0B  // RTC Register B
> +#define B_PCH_RTC_REGISTERB_SET                   BIT7  // Update Cycle Inhibit
> 1: Stop auto update, begin set value; 0: Update cycle occurs
> +#define B_PCH_RTC_REGISTERB_PIE                   BIT6  // Periodic Interrupt
> Enable
> +#define B_PCH_RTC_REGISTERB_AIE                   BIT5  // Alarm Interrupt
> Enable
> +#define B_PCH_RTC_REGISTERB_UIE                   BIT4  // Update-ended
> Interrupt Enable
> +#define B_PCH_RTC_REGISTERB_SQWE                  BIT3  // Square Wave
> Enable (Not implemented)
> +#define B_PCH_RTC_REGISTERB_DM                    BIT2  // Data Mode 1: Binary;
> 0:BCD
> +#define B_PCH_RTC_REGISTERB_HF                    BIT1  // Hour Format 1: 24
> mode; 0: 12 mode.
> +#define B_PCH_RTC_REGISTERB_DSE                   BIT0  // Daylight Savings
> Enable (Not Implemented)
> +
> +#define R_PCH_RTC_REGISTERC                       0x0C  // RTC Register C
> +#define B_PCH_RTC_REGISTERC_IRQF                  BIT7  // Interrupt Request
> Flag
> +#define B_PCH_RTC_REGISTERC_PF                    BIT6  // Periodic Interrupt Flag
> +#define B_PCH_RTC_REGISTERC_AF                    BIT5  // Alarm Flag
> +#define B_PCH_RTC_REGISTERC_UF                    BIT4  // Update-ended Flag
> +#define B_PCH_RTC_REGISTERC_RESERVED              (BIT3 | BIT2 | BIT1 | BIT0)
> +
> +#define R_PCH_RTC_REGISTERD                       0x0D  // RTC Register D
> +#define B_PCH_RTC_REGISTERD_VRT                   BIT7  // Valid RAM and Time
> Bit
> +#define B_PCH_RTC_REGISTERD_RESERVED              BIT6
> +#define B_PCH_RTC_REGISTERD_DA                    0x3F  // Date Alarm
> +
> +#define B_PCH_RTC_CENTURY                         0x32  // Century Data
> +
> +//
> +// APM Registers
> +//
> +#define R_PCH_APM_CNT                             0xB2  // Advanced Power
> Management Control Port
> +#define R_PCH_APM_STS                             0xB3  // Advanced Power
> Management Status Port
> +
> +//
> +// INIT Register
> +//
> +#define R_PCH_PORT92                              0x92
> +#define B_PCH_PORT92_ALT_A20_GATE                 BIT1  // Alternate A20
> Gate
> +#define B_PCH_PORT92_INIT_NOW                     BIT0  // Init Now
> +
> +//
> +// PCU UART
> +//
> +#define R_PCH_COM1_BASE                           0x3F8 // COM1 IO BASE
> +
> +//
> +// Reset Control Register
> +//
> +#define R_PCH_RST_CNT                             0xCF9 // Reset Control
> +#define B_PCH_RST_CNT_FULL_RST                    BIT3
> +#define B_PCH_RST_CNT_RST_CPU                     BIT2
> +#define B_PCH_RST_CNT_SYS_RST                     BIT1
> +#define V_PCH_RST_CNT_FULLRESET                   0x0E
> +#define V_PCH_RST_CNT_HARDRESET                   0x06
> +#define V_PCH_RST_CNT_SOFTRESET                   0x04  // Not supported by
> VLV
> +#define V_PCH_RST_CNT_HARDSTARTSTATE              0x02
> +#define V_PCH_RST_CNT_SOFTSTARTSTATE              0x00
> +
> +//
> +// Fixed Memory Region
> +//
> +
> +//
> +// IO APIC Registers
> +//
> +#define R_PCH_IO_APIC_INDEX                       0xFEC00000 // IOAPIC Index
> Register, 8bit
> +#define R_PCH_IO_APIC_WINDOW                      0xFEC00010 // IOAPIC
> Window Register, 32bit
> +#define R_PCH_IO_APIC_EOI                         0xFEC00040 // IOAPIC EOI
> Register, 8bit
> +
> +#define R_PCH_IO_APIC_ID                          0x00  // Identification
> +#define B_PCH_IO_APIC_ID_AID                      (BIT27 | BIT26 | BIT25 | BIT24)
> // APIC Identification
> +
> +#define R_PCH_IO_APIC_VS                          0x01  // Version
> +#define B_PCH_IO_APIC_VS_MRE                      0xFF0000 // Maximum
> Redirection Entries
> +#define B_PCH_IO_APIC_VS_PRQ                      BIT15 // Pin Assertion Register
> Supported
> +#define B_PCH_IO_APIC_VS_VS                       0xFF  // Version
> +
> +//
> +// HPET Registers
> +//
> +#define R_PCH_PCH_HPET                            0xFED00000 // HPET Base Address
> +
> +#define R_PCH_PCH_HPET_GCID                       0x00  // HPET General
> Capabilities and ID, 64bit
> +#define B_PCH_PCH_HPET_GCID_CTP                   0xFFFFFFFF00000000 //
> Counter Tick Period
> +#define B_PCH_PCH_HPET_GCID_VID                   0xFFFF0000 // Vendor ID
> +#define B_PCH_PCH_HPET_GCID_LRC                   BIT15 // Legacy Rout
> Capable
> +#define B_PCH_PCH_HPET_GCID_CS                    BIT13 // Counter Size
> +#define B_PCH_PCH_HPET_GCID_NT                    0x1F00 // Number of Timers
> +#define B_PCH_PCH_HPET_GCID_RID                   0xFF  // Revision ID
> +#define N_PCH_HPET_ADDR_ASEL                      12
> +
> +#define R_PCH_PCH_HPET_GCFG                       0x10  // HPET General
> Configuration
> +#define B_PCH_PCH_HPET_GCFG_LRE                   BIT1  // Legacy Rout Enable
> +#define B_PCH_PCH_HPET_GCFG_EN                    BIT0  // Overall Enable
> +
> +#define R_PCH_PCH_HPET_GIS                        0x20  // HPET General Interrupt
> Status
> +#define B_PCH_PCH_HPET_GIS_T2                     BIT2  // Timer 2 Status
> +#define B_PCH_PCH_HPET_GIS_T1                     BIT1  // Timer 1 Status
> +#define B_PCH_PCH_HPET_GIS_T0                     BIT0  // Timer 0 Status
> +
> +#define R_PCH_PCH_HPET_MCV                        0xF0  // HPET Main Counter
> Value, 64bit
> +
> +#define R_PCH_PCH_HPET_T0C                        0x100 // HPET Timer 0 Config
> and Capabilities
> +#define R_PCH_PCH_HPET_T0CV_L                     0x108 // HPET Timer 0 Lower
> Comparator Value
> +#define R_PCH_PCH_HPET_T0CV_H                     0x10C // HPET Timer 0 Upper
> Comparator Value
> +
> +#define R_PCH_PCH_HPET_T1C                        0x120 // HPET Timer 1 Config
> and Capabilities
> +#define R_PCH_PCH_HPET_T1CV                       0x128 // HPET Timer 1
> Comparator Value
> +
> +#define R_PCH_PCH_HPET_T2C                        0x140 // HPET Timer 2 Config
> and Capabilities
> +#define R_PCH_PCH_HPET_T2CV                       0x148 // HPET Timer 2
> Comparator Value
> +
> +#define B_PCH_PCH_HPET_TXC_IRC                    0xFFFFFFFF00000000 //
> Interrupt Rout Capability
> +#define B_PCH_PCH_HPET_TXC_FID                    BIT15 // FSB Interrupt
> Delivery
> +#define B_PCH_PCH_HPET_TXC_FE                     BIT14 // FSB Enable
> +#define B_PCH_PCH_HPET_TXC_IR                     0x3E00 // Interrupt Rout
> +#define B_PCH_PCH_HPET_TXC_T32M                   BIT8  // Timer 32-bit Mode
> +#define B_PCH_PCH_HPET_TXC_TVS                    BIT6  // Timer Value Set
> +#define B_PCH_PCH_HPET_TXC_TS                     BIT5  // Timer Size
> +#define B_PCH_PCH_HPET_TXC_PIC                    BIT4  // Periodic Interrupt
> Capable
> +#define B_PCH_PCH_HPET_TXC_TYP                    BIT3  // Timer Type
> +#define B_PCH_PCH_HPET_TXC_IE                     BIT2  // Interrupt Enable
> +#define B_PCH_PCH_HPET_TXC_IT                     BIT1  // Timer Interrupt Type
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsRcrb.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsRcrb.h
> new file mode 100644
> index 0000000000..7cc599cd6a
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsRcrb.h
> @@ -0,0 +1,48 @@
> +/**
> +
> +Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +  @file
> +  PchRegsRcrb.h
> +
> +  @brief
> +  Register names for VLV Chipset Configuration Registers
> +
> +  Conventions:
> +
> +  - Prefixes:
> +    Definitions beginning with "R_" are registers
> +    Definitions beginning with "B_" are bits within registers
> +    Definitions beginning with "V_" are meaningful values of bits within the
> registers
> +    Definitions beginning with "S_" are register sizes
> +    Definitions beginning with "N_" are the bit position
> +  - In general, PCH registers are denoted by "_PCH_" in register names
> +  - Registers / bits that are different between PCH generations are denoted
> by
> +    "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_VLV_"
> +  - Registers / bits that are different between SKUs are denoted by
> "_<SKU_name>"
> +    at the end of the register/bit names
> +  - Registers / bits of new devices introduced in a PCH generation will be just
> named
> +    as "_PCH_" without <generation_name> inserted.
> +
> +**/
> +#ifndef _PCH_REGS_RCRB_H_
> +#define _PCH_REGS_RCRB_H_
> +
> +///
> +/// Chipset Configuration Registers (Memory space)
> +/// RCBA
> +///
> +#define R_PCH_RCRB_GCS                    0x00  // General Control and Status
> +#define B_PCH_RCRB_GCS_BBSIZE             (BIT30 | BIT29) // Boot Block Size
> +#define B_PCH_RCRB_GCS_BBS                (BIT11 | BIT10) // Boot BIOS Straps
> +#define V_PCH_RCRB_GCS_BBS_SPI            (3 << 10) // Boot BIOS strapped
> to SPI
> +#define V_PCH_RCRB_GCS_BBS_LPC            (0 << 10) // Boot BIOS strapped
> to LPC
> +#define B_PCH_RCRB_GCS_TS                 BIT1 // Top Swap
> +#define B_PCH_RCRB_GCS_BILD               BIT0 // BIOS Interface Lock-Down
> +
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsSata.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsSata.h
> new file mode 100644
> index 0000000000..a326e178fe
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsSata.h
> @@ -0,0 +1,245 @@
> +/**
> +
> +Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +  @file
> +  PchRegsSata.h
> +
> +  @brief
> +  Register names for VLV SATA controllers
> +
> +  Conventions:
> +
> +  - Prefixes:
> +    Definitions beginning with "R_" are registers
> +    Definitions beginning with "B_" are bits within registers
> +    Definitions beginning with "V_" are meaningful values of bits within the
> registers
> +    Definitions beginning with "S_" are register sizes
> +    Definitions beginning with "N_" are the bit position
> +  - In general, PCH registers are denoted by "_PCH_" in register names
> +  - Registers / bits that are different between PCH generations are denoted
> by
> +    "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_VLV_"
> +  - Registers / bits that are different between SKUs are denoted by
> "_<SKU_name>"
> +    at the end of the register/bit names
> +  - Registers / bits of new devices introduced in a PCH generation will be just
> named
> +    as "_PCH_" without <generation_name> inserted.
> +
> +**/
> +#ifndef _PCH_REGS_SATA_H_
> +#define _PCH_REGS_SATA_H_
> +
> +///
> +/// VLV SATA Message Bus
> +///
> +#define PCH_SATA_PHY_PORT_ID                0xA3  // SATA PHY Port ID
> +#define PCH_SATA_PHY_MMIO_READ_OPCODE       0x00  // CUnit to SATA
> PHY MMIO Read Opcode
> +#define PCH_SATA_PHY_MMIO_WRITE_OPCODE      0x01  // CUnit to SATA
> PHY MMIO Write Opcode
> +
> +///
> +///  SATA Controller Registers (D19:F0)
> +///
> +#define PCI_DEVICE_NUMBER_PCH_SATA          19
> +#define PCI_FUNCTION_NUMBER_PCH_SATA        0
> +
> +#define R_PCH_SATA_ID                       0x00  // Identifiers
> +#define B_PCH_SATA_ID_DID                   0xFFFF0000 // Device ID
> +#define B_PCH_SATA_ID_VID                   0x0000FFFF // Vendor ID
> +#define V_PCH_SATA_VENDOR_ID                V_PCH_INTEL_VENDOR_ID
> +#define V_PCH_SATA_DEVICE_ID_D_IDE          0x0F20  // Desktop IDE Mode
> (Ports 0 and 1)
> +#define V_PCH_SATA_DEVICE_ID_D_AHCI         0x0F22  // Desktop AHCI
> Mode (Ports 0 and 1)
> +#define V_PCH_SATA_DEVICE_ID_D_RAID         0x2822  // Desktop RAID
> 0/1/5/10 Mode, based on D19:F0:9Ch[7]
> +
> +#define V_PCH_SATA_DEVICE_ID_M_IDE          0x0F21  // Mobile IDE Mode
> (Ports 0 and 1)
> +#define V_PCH_SATA_DEVICE_ID_M_AHCI         0x0F23  // Mobile AHCI
> Mode (Ports 0 and 1)
> +#define V_PCH_SATA_DEVICE_ID_M_RAID         0x282A  // Mobile RAID
> 0/1/5/10 Mode, based on D19:F0:9Ch[7]
> +
> +#define R_PCH_SATA_COMMAND                  0x04  // Command
> +#define B_PCH_SATA_COMMAND_INT_DIS          BIT10 // Interrupt Disable
> +#define B_PCH_SATA_COMMAND_FBE              BIT9  // Fast Back-to-back
> Enable
> +#define B_PCH_SATA_COMMAND_SERR_EN          BIT8  // SERR# Enable
> +#define B_PCH_SATA_COMMAND_WCC              BIT7  // Wait Cycle Enable
> +#define B_PCH_SATA_COMMAND_PER              BIT6  // Parity Error
> Response Enable
> +#define B_PCH_SATA_COMMAND_VPS              BIT5  // VGA Palette
> Snooping Enable
> +#define B_PCH_SATA_COMMAND_PMWE             BIT4  // Memory Write
> and Invalidate Enable
> +#define B_PCH_SATA_COMMAND_SCE              BIT3  // Special Cycle Enable
> +#define B_PCH_SATA_COMMAND_BME              BIT2  // Bus Master Enable
> +#define B_PCH_SATA_COMMAND_MSE              BIT1  // Memory Space
> Enable
> +#define B_PCH_SATA_COMMAND_IOSE             BIT0  // I/O Space Enable
> +
> +#define R_PCH_SATA_PCISTS                   0x06  // Device Status
> +#define B_PCH_SATA_PCISTS_DPE               BIT15 // Detected Parity Error
> +#define B_PCH_SATA_PCISTS_SSE               BIT14 // Signaled System Error
> +#define B_PCH_SATA_PCISTS_RMA               BIT13 // Received Master-Abort
> Status
> +#define B_PCH_SATA_PCISTS_RTA               BIT12 // Received Target-Abort
> Status
> +#define B_PCH_SATA_PCISTS_STA               BIT11 // Signaled Target-Abort
> Status
> +#define B_PCH_SATA_PCISTS_DEV_STS_MASK      (BIT10 | BIT9) // DEVSEL#
> Timing Status
> +#define B_PCH_SATA_PCISTS_DPED              BIT8  // Master Data Parity Error
> Detected
> +#define B_PCH_SATA_PCISTS_CAP_LIST          BIT4  // Capabilities List
> +#define B_PCH_SATA_PCISTS_ITNS              BIT3  // Interrupt Status
> +
> +#define R_PCH_SATA_RID                      0x08  // Revision ID (8 bits)
> +
> +#define R_PCH_SATA_PI_REGISTER              0x09  // Programming Interface
> (8 bits)
> +#define B_PCH_SATA_PI_REGISTER_SNC          BIT3  // Secondary Mode
> Native Capable
> +#define B_PCH_SATA_PI_REGISTER_SNE          BIT2  // Secondary Mode
> Native Enable
> +#define B_PCH_SATA_PI_REGISTER_PNC          BIT1  // Primary Mode Native
> Capable
> +#define B_PCH_SATA_PI_REGISTER_PNE          BIT0  // Primary Mode Native
> Enable
> +
> +#define R_PCH_SATA_CC                       0x0A  // Class Code
> +#define B_PCH_SATA_CC_BCC                   0xFF00 // Base Class Code
> +#define B_PCH_SATA_CC_SCC                   0x00FF // Sub Class Code
> +#define V_PCH_SATA_CC_SCC_IDE               0x01
> +#define V_PCH_SATA_CC_SCC_AHCI              0x06
> +#define V_PCH_SATA_CC_SCC_RAID              0x04
> +
> +#define R_PCH_SATA_CLS                      0x0C  // Cache Line Size (8 bits)
> +#define B_PCH_SATA_CLS                      0xFF
> +
> +#define R_PCH_SATA_MLT                      0x0D  // Master Latency Timer (8 bits)
> +#define B_PCH_SATA_MLT                      0xFF
> +
> +#define R_PCH_SATA_HTYPE                    0x0E  // Header Type
> +#define B_PCH_SATA_HTYPE_MFD                BIT7  // Multi-function Device
> +#define B_PCH_SATA_HTYPE_HL                 0x7F  // Header Layout
> +
> +#define R_PCH_SATA_PCMD_BAR                 0x10  // Primary Command Block
> Base Address
> +#define B_PCH_SATA_PCMD_BAR_BA              0x0000FFF8 // Base Address
> +#define B_PCH_SATA_PCMD_BAR_RTE             BIT0  // Resource Type
> Indicator
> +
> +#define R_PCH_SATA_PCTL_BAR                 0x14  // Primary Control Block
> Base Address
> +#define B_PCH_SATA_PCTL_BAR_BA              0x0000FFFC // Base Address
> +#define B_PCH_SATA_PCTL_BAR_RTE             BIT0  // Resource Type
> Indicator
> +
> +#define R_PCH_SATA_SCMD_BAR                 0x18  // Secondary Command
> Block Base Address
> +#define B_PCH_SATA_SCMD_BAR_BA              0x0000FFF8 // Base Address
> +#define B_PCH_SATA_SCMD_BAR_RTE             BIT0  // Resource Type
> Indicator
> +
> +#define R_PCH_SATA_SCTL_BAR                 0x1C  // Secondary Control Block
> Base Address
> +#define B_PCH_SATA_SCTL_BAR_BA              0x0000FFFC // Base Address
> +#define B_PCH_SATA_SCTL_BAR_RTE             BIT0  // Resource Type
> Indicator
> +
> +#define R_PCH_SATA_LBAR                     0x20  // Legacy IDE Base Address /
> AHCI Index Data Pair Base Address
> +#define B_PCH_SATA_LBAR_BA                  0x0000FFE0 // Base Address
> +#define B_PCH_SATA_LBAR_BA4                 BIT4  // Base Address 4
> +#define B_PCH_SATA_LBAR_RTE                 BIT0  // Resource Type Indicator
> +
> +#define R_PCH_SATA_SIDPBA                   0x24  // Serial ATA Index Data Pair
> Base Address
> +#define R_PCH_SATA_ABAR                     0x24  // AHCI Base Address
> +#define B_PCH_SATA_ABAR_BA                  0xFFFFF800 // AHCI Memory Base
> Address (When CC.SCC not equal 0x01)
> +#define V_PCH_SATA_ABAR_LENGTH              0x800 // AHCI Memory Length
> (When CC.SCC not equal 0x01)
> +#define N_PCH_SATA_ABAR_ALIGNMENT           11    // AHCI Base Address
> Alignment (When CC.SCC not equal 0x01)
> +#define B_PCH_SATA_SIDPBA_BA                0x0000FFF0 // Serial ATA Index
> Data Pair IO Base Address (When CC.SCC equal 0x01)
> +#define V_PCH_SATA_SIDPBA_LENGTH            0x10  // Serial ATA Index Data
> Pair IO Length (When CC.SCC equal 0x01)
> +#define N_PCH_SATA_SIDPBA_ALIGNMENT         4     // Serial ATA Index
> Data Pair Base Address Alignment (When CC.SCC not equal 0x01)
> +#define B_PCH_SATA_ABAR_PF                  BIT3  // Prefetchable
> +#define B_PCH_SATA_ABAR_TP                  (BIT2 | BIT1) // Type
> +#define B_PCH_SATA_ABAR_RTE                 BIT0  // Resource Type Indicator
> +
> +#define R_PCH_SATA_SS                       0x2C  // Sub System Identifiers
> +#define B_PCH_SATA_SS_SSID                  0xFFFF0000 // Subsystem ID
> +#define B_PCH_SATA_SS_SSVID                 0x0000FFFF // Subsystem Vendor
> ID
> +
> +#define R_PCH_SATA_AHCI_CAP_PTR             0x34  // Capabilities Pointer (8
> bits)
> +#define B_PCH_SATA_AHCI_CAP_PTR             0xFF
> +
> +#define R_PCH_SATA_INTR                     0x3C  // Interrupt Information
> +#define B_PCH_SATA_INTR_IPIN                0xFFFF0000 // Interrupt Pin
> +#define B_PCH_SATA_INTR_ILINE               0x0000FFFF // Interrupt Line
> +
> +#define R_PCH_SATA_PMCS                     0x74  // PCI Power Management
> Control and Status
> +#define B_PCH_SATA_PMCS_PMES                BIT15 // PME Status
> +#define B_PCH_SATA_PMCS_PMEE                BIT8  // PME Enable
> +#define B_PCH_SATA_PMCS_NSFRST              BIT3  // No Soft Reset
> +#define V_PCH_SATA_PMCS_NSFRST_1            0x01
> +#define V_PCH_SATA_PMCS_NSFRST_0            0x00
> +#define B_PCH_SATA_PMCS_PS                  (BIT1 | BIT0) // Power State
> +#define V_PCH_SATA_PMCS_PS_3                0x03
> +#define V_PCH_SATA_PMCS_PS_0                0x00
> +
> +#define R_PCH_SATA_MAP                      0x90  // Port Mapping Register
> +#define B_PCH_SATA_MAP_SPD                  (BIT14 | BIT13 | BIT12 | BIT11 |
> BIT10 | BIT9 | BIT8) // SATA Port Disable
> +#define B_PCH_SATA_PORT6_DISABLED           BIT14
> +#define B_PCH_SATA_PORT5_DISABLED           BIT13
> +#define B_PCH_SATA_PORT4_DISABLED           BIT12
> +#define B_PCH_SATA_PORT3_DISABLED           BIT11
> +#define B_PCH_SATA_PORT2_DISABLED           BIT10
> +#define B_PCH_SATA_PORT1_DISABLED           BIT9
> +#define B_PCH_SATA_PORT0_DISABLED           BIT8
> +#define B_PCH_SATA_MAP_SMS_MASK             (BIT7 | BIT6) // SATA Mode
> Select
> +#define V_PCH_SATA_MAP_SMS_IDE              0x00
> +#define V_PCH_SATA_MAP_SMS_AHCI             0x40
> +#define V_PCH_SATA_MAP_SMS_RAID             0x80
> +#define B_PCH_SATA_PORT_TO_CONTROLLER_CFG   BIT5  // SATA Port-to-
> Controller Configuration
> +
> +#define R_PCH_SATA_PCS                      0x92  // Port Control and Status
> +#define S_PCH_SATA_PCS                      0x2
> +#define B_PCH_SATA_PCS_OOB_RETRY            BIT15 // OOB Retry Mode
> +#define B_PCH_SATA_PCS_PORT6_DET            BIT14 // Port 6 Present
> +#define B_PCH_SATA_PCS_PORT5_DET            BIT13 // Port 5 Present
> +#define B_PCH_SATA_PCS_PORT4_DET            BIT12 // Port 4 Present
> +#define B_PCH_SATA_PCS_PORT3_DET            BIT11 // Port 3 Present
> +#define B_PCH_SATA_PCS_PORT2_DET            BIT10 // Port 2 Present
> +#define B_PCH_SATA_PCS_PORT1_DET            BIT9  // Port 1 Present
> +#define B_PCH_SATA_PCS_PORT0_DET            BIT8  // Port 0 Present
> +#define B_PCH_SATA_PCS_PORT5_EN             BIT5  // Port 5 Enabled
> +#define B_PCH_SATA_PCS_PORT4_EN             BIT4  // Port 4 Enabled
> +#define B_PCH_SATA_PCS_PORT3_EN             BIT3  // Port 3 Enabled
> +#define B_PCH_SATA_PCS_PORT2_EN             BIT2  // Port 2 Enabled
> +#define B_PCH_SATA_PCS_PORT1_EN             BIT1  // Port 1 Enabled
> +#define B_PCH_SATA_PCS_PORT0_EN             BIT0  // Port 0 Enabled
> +
> +#define R_PCH_SATA_AHCI_PI                  0x0C  // Ports Implemented
> +#define B_PCH_SATA_PORT_MASK                0x3F
> +#define B_PCH_SATA_PORT5_IMPLEMENTED        BIT5  // Port 5
> Implemented
> +#define B_PCH_SATA_PORT4_IMPLEMENTED        BIT4  // Port 4
> Implemented
> +#define B_PCH_SATA_PORT3_IMPLEMENTED        BIT3  // Port 3
> Implemented
> +#define B_PCH_SATA_PORT2_IMPLEMENTED        BIT2  // Port 2
> Implemented
> +#define B_PCH_SATA_PORT1_IMPLEMENTED        BIT1  // Port 1
> Implemented
> +#define B_PCH_SATA_PORT0_IMPLEMENTED        BIT0  // Port 0
> Implemented
> +
> +#define R_PCH_SATA_AHCI_P0SSTS              0x128 // Port 0 Serial ATA Status
> +#define R_PCH_SATA_AHCI_P1SSTS              0x1A8 // Port 1 Serial ATA Status
> +#define B_PCH_SATA_AHCI_PXSSTS_IPM          0x00000F00 // Interface
> Power Management
> +#define B_PCH_SATA_AHCI_PXSSTS_IPM_0        0x00000000
> +#define B_PCH_SATA_AHCI_PXSSTS_IPM_1        0x00000100
> +#define B_PCH_SATA_AHCI_PXSSTS_IPM_2        0x00000200
> +#define B_PCH_SATA_AHCI_PXSSTS_IPM_6        0x00000600
> +#define B_PCH_SATA_AHCI_PXSSTS_SPD          0x000000F0 // Current
> Interface Speed
> +#define B_PCH_SATA_AHCI_PXSSTS_SPD_0        0x00000000
> +#define B_PCH_SATA_AHCI_PXSSTS_SPD_1        0x00000010
> +#define B_PCH_SATA_AHCI_PXSSTS_SPD_2        0x00000020
> +#define B_PCH_SATA_AHCI_PXSSTS_SPD_3        0x00000030
> +#define B_PCH_SATA_AHCI_PXSSTS_DET          0x0000000F // Device
> Detection
> +#define B_PCH_SATA_AHCI_PXSSTS_DET_0        0x00000000
> +#define B_PCH_SATA_AHCI_PXSSTS_DET_1        0x00000001
> +#define B_PCH_SATA_AHCI_PXSSTS_DET_3        0x00000003
> +#define B_PCH_SATA_AHCI_PXSSTS_DET_4        0x00000004
> +
> +//
> +// Macros of VLV capabilities for SATA controller which are used by SATA
> controller driver
> +//
> +//
> +//
> +// Define the individual capabilities of each SATA controller
> +//
> +#define PCH_SATA_MAX_CONTROLLERS            1     // Max SATA controllers
> number supported
> +#define PCH_SATA_MAX_DEVICES                2     // Max SATA devices number
> of single SATA channel
> +#define PCH_IDE_MAX_CHANNELS                2     // Max IDE channels number
> of single SATA controller
> +#define PCH_IDE_MAX_DEVICES                 2     // Max IDE devices number of
> single SATA channel
> +#define PCH_AHCI_MAX_PORTS                  2     // Max number of SATA ports
> in VLV
> +#define PCH_IDE_MAX_PORTS                   2     // Max number of IDE ports in
> VLV
> +
> +//
> +// GPIOS_14 SATA0GP is the SATA port 0 reset pin.
> +//
> +#define PCH_GPIO_SATA_PORT0_RESET           14
> +//
> +// GPIOS_15 SATA1GP is the SATA port 1 reset pin.
> +//
> +#define PCH_GPIO_SATA_PORT1_RESET           15
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsScc.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsScc.h
> new file mode 100644
> index 0000000000..a45c2358f6
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsScc.h
> @@ -0,0 +1,53 @@
> +/*++
> +
> +Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  PchRegsScc.h
> +
> +Abstract:
> +
> +  Register names for VLV SCC module.
> +
> +  Conventions:
> +
> +  - Prefixes:
> +    Definitions beginning with "R_" are registers
> +    Definitions beginning with "B_" are bits within registers
> +    Definitions beginning with "V_" are meaningful values of bits within the
> registers
> +    Definitions beginning with "S_" are register sizes
> +    Definitions beginning with "N_" are the bit position
> +  - In general, PCH registers are denoted by "_PCH_" in register names
> +  - Registers / bits that are different between PCH generations are denoted
> by
> +    "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_VLV_"
> +  - Registers / bits that are different between SKUs are denoted by
> "_<SKU_name>"
> +    at the end of the register/bit names
> +  - Registers / bits of new devices introduced in a PCH generation will be just
> named
> +    as "_PCH_" without <generation_name> inserted.
> +
> +--*/
> +#ifndef _PCH_REGS_SCC_H_
> +#define _PCH_REGS_SCC_H_
> +
> +
> +//
> +// SCC Modules Registers
> +//
> +
> +//
> +// SCC SDIO Modules
> +// PCI Config Space Registers
> +//
> +#define PCI_DEVICE_NUMBER_PCH_SCC_SDIO_0         16
> +#define PCI_DEVICE_NUMBER_PCH_SCC_SDIO_1         17
> +#define PCI_DEVICE_NUMBER_PCH_SCC_SDIO_2         18
> +#define PCI_DEVICE_NUMBER_PCH_SCC_SDIO_3         23
> +
> +#define PCI_FUNCTION_NUMBER_PCH_SCC_SDIO         0
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsSmbus.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsSmbus.h
> new file mode 100644
> index 0000000000..dc858c244c
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsSmbus.h
> @@ -0,0 +1,149 @@
> +/**
> +
> +Copyright (c) 2011  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +  @file
> +  PchRegsSmbus.h
> +
> +  @brief
> +  Register names for VLV Smbus Device.
> +
> +  Conventions:
> +
> +  - Prefixes:
> +    Definitions beginning with "R_" are registers
> +    Definitions beginning with "B_" are bits within registers
> +    Definitions beginning with "V_" are meaningful values of bits within the
> registers
> +    Definitions beginning with "S_" are register sizes
> +    Definitions beginning with "N_" are the bit position
> +  - In general, PCH registers are denoted by "_PCH_" in register names
> +  - Registers / bits that are different between PCH generations are denoted
> by
> +    "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_VLV_"
> +  - Registers / bits that are different between SKUs are denoted by
> "_<SKU_name>"
> +    at the end of the register/bit names
> +  - Registers / bits of new devices introduced in a PCH generation will be just
> named
> +    as "_PCH_" without <generation_name> inserted.
> +
> +**/
> +#ifndef _PCH_REGS_SMBUS_H_
> +#define _PCH_REGS_SMBUS_H_
> +
> +///
> +/// SMBus Controller Registers (D31:F3)
> +///
> +#define PCI_DEVICE_NUMBER_PCH_SMBUS        31
> +#define PCI_FUNCTION_NUMBER_PCH_SMBUS      3
> +
> +#define R_PCH_SMBUS_VENDOR_ID              0x00  // Vendor ID
> +#define V_PCH_SMBUS_VENDOR_ID              V_PCH_INTEL_VENDOR_ID //
> Intel Vendor ID
> +
> +#define R_PCH_SMBUS_DEVICE_ID              0x02  // Device ID
> +#define V_PCH_SMBUS_DEVICE_ID              0x0F12
> +
> +#define R_PCH_SMBUS_PCICMD                 0x04  // CMD register
> enables/disables, Memory/IO space access and interrupt
> +#define B_PCH_SMBUS_PCICMD_INTR_DIS        BIT10 // Interrupt Disable
> +#define B_PCH_SMBUS_PCICMD_FBE             BIT9  // FBE - reserved as '0'
> +#define B_PCH_SMBUS_PCICMD_SERR_EN         BIT8  // SERR Enable -
> reserved as '0'
> +#define B_PCH_SMBUS_PCICMD_WCC             BIT7  // Wait Cycle Control -
> reserved as '0'
> +#define B_PCH_SMBUS_PCICMD_PER             BIT6  // Parity Error - reserved
> as '0'
> +#define B_PCH_SMBUS_PCICMD_VPS             BIT5  // VGA Palette Snoop -
> reserved as '0'
> +#define B_PCH_SMBUS_PCICMD_PMWE            BIT4  // Postable Memory
> Write Enable - reserved as '0'
> +#define B_PCH_SMBUS_PCICMD_SCE             BIT3  // Special Cycle Enable -
> reserved as '0'
> +#define B_PCH_SMBUS_PCICMD_BME             BIT2  // Bus Master Enable -
> reserved as '0'
> +#define B_PCH_SMBUS_PCICMD_MSE             BIT1  // Memory Space Enable
> +#define B_PCH_SMBUS_PCICMD_IOSE            BIT0  // I/O Space Enable
> +
> +#define R_PCH_SMBUS_BASE                   0x20  // The I/O memory bar
> +#define B_PCH_SMBUS_BASE_BAR               0x0000FFE0 // Base Address
> +#define B_PCH_SMBUS_BASE_IOSI              BIT0  // IO Space Indicator
> +
> +#define R_PCH_SMBUS_SVID                   0x2C  // Subsystem Vendor ID
> +#define B_PCH_SMBUS_SVID                   0xFFFF // Subsystem Vendor ID
> +
> +//
> +// SMBus I/O Registers
> +//
> +#define R_PCH_SMBUS_HSTS                   0x00  // Host Status Register R/W
> +#define B_PCH_SMBUS_HSTS_ALL               0xFF
> +#define B_PCH_SMBUS_BYTE_DONE_STS          BIT7  // Byte Done Status
> +#define B_PCH_SMBUS_IUS                    BIT6  // In Use Status
> +#define B_PCH_SMBUS_SMBALERT_STS           BIT5  // SMBUS Alert
> +#define B_PCH_SMBUS_FAIL                   BIT4  // Failed
> +#define B_PCH_SMBUS_BERR                   BIT3  // Bus Error
> +#define B_PCH_SMBUS_DERR                   BIT2  // Device Error
> +#define B_PCH_SMBUS_ERRORS                 (B_PCH_SMBUS_FAIL |
> B_PCH_SMBUS_BERR | B_PCH_SMBUS_DERR)
> +#define B_PCH_SMBUS_INTR                   BIT1  // Interrupt
> +#define B_PCH_SMBUS_HBSY                   BIT0  // Host Busy
> +
> +#define R_PCH_SMBUS_HCTL                   0x02  // Host Control Register R/W
> +#define B_PCH_SMBUS_PEC_EN                 BIT7  // Packet Error Checking
> Enable
> +#define B_PCH_SMBUS_START                  BIT6  // Start
> +#define B_PCH_SMBUS_LAST_BYTE              BIT5  // Last Byte
> +#define B_PCH_SMBUS_SMB_CMD                0x1C  // SMB Command
> +#define V_PCH_SMBUS_SMB_CMD_BLOCK_PROCESS  0x1C  // Block
> Process
> +#define V_PCH_SMBUS_SMB_CMD_IIC_READ       0x18  // I2C Read
> +#define V_PCH_SMBUS_SMB_CMD_BLOCK          0x14  // Block
> +#define V_PCH_SMBUS_SMB_CMD_PROCESS_CALL   0x10  // Process Call
> +#define V_PCH_SMBUS_SMB_CMD_WORD_DATA      0x0C  // Word Data
> +#define V_PCH_SMBUS_SMB_CMD_BYTE_DATA      0x08  // Byte Data
> +#define V_PCH_SMBUS_SMB_CMD_BYTE           0x04  // Byte
> +#define V_PCH_SMBUS_SMB_CMD_QUICK          0x00  // Quick
> +#define B_PCH_SMBUS_KILL                   BIT1  // Kill
> +#define B_PCH_SMBUS_INTREN                 BIT0  // Interrupt Enable
> +
> +#define R_PCH_SMBUS_HCMD                   0x03  // Host Command Register
> R/W
> +#define B_PCH_SMBUS_HCMD                   0xFF  // Command to be
> transmitted
> +
> +#define R_PCH_SMBUS_TSA                    0x04  // Transmit Slave Address
> Register R/W
> +#define B_PCH_SMBUS_ADDRESS                0xFE  // 7-bit address of the
> targeted slave
> +#define B_PCH_SMBUS_RW_SEL                 BIT0  // Direction of the host
> transfer, 1 = read, 0 = write
> +#define B_PCH_SMBUS_RW_SEL_READ            0x01  // Read
> +#define B_PCH_SMBUS_RW_SEL_WRITE           0x00  // Write
> +//
> +#define R_PCH_SMBUS_HD0                    0x05  // Data 0 Register R/W
> +#define R_PCH_SMBUS_HD1                    0x06  // Data 1 Register R/W
> +#define R_PCH_SMBUS_HBD                    0x07  // Host Block Data Register
> R/W
> +#define R_PCH_SMBUS_PEC                    0x08  // Packet Error Check Data
> Register R/W
> +
> +#define R_PCH_SMBUS_RSA                    0x09  // Receive Slave Address
> Register R/W
> +#define B_PCH_SMBUS_SLAVE_ADDR             0x7F  // TCO slave address
> (Not used, reserved)
> +
> +#define R_PCH_SMBUS_SD                     0x0A  // Receive Slave Data Register
> R/W
> +
> +#define R_PCH_SMBUS_AUXS                   0x0C  // Auxiliary Status Register
> R/WC
> +#define B_PCH_SMBUS_CRCE                   BIT0  // CRC Error
> +//
> +#define R_PCH_SMBUS_AUXC                   0x0D  // Auxiliary Control Register
> R/W
> +#define B_PCH_SMBUS_E32B                   BIT1  // Enable 32-byte Buffer
> +#define B_PCH_SMBUS_AAC                    BIT0  // Automatically Append CRC
> +
> +#define R_PCH_SMBUS_SMLC                   0x0E  // SMLINK Pin Control
> Register R/W
> +#define B_PCH_SMBUS_SMLINK_CLK_CTL         BIT2  // Not supported
> +#define B_PCH_SMBUS_SMLINK1_CUR_STS        BIT1  // Not supported
> +#define B_PCH_SMBUS_SMLINK0_CUR_STS        BIT0  // Not supported
> +
> +
> +#define R_PCH_SMBUS_SMBC                   0x0F  // SMBus Pin Control Register
> R/W
> +#define B_PCH_SMBUS_SMBCLK_CTL             BIT2  // SMBCLK Control
> +#define B_PCH_SMBUS_SMBDATA_CUR_STS        BIT1  // SMBDATA Current
> Status
> +#define B_PCH_SMBUS_SMBCLK_CUR_STS         BIT0  // SMBCLK Current
> Status
> +
> +#define R_PCH_SMBUS_SSTS                   0x10  // Slave Status Register R/WC
> +#define B_PCH_SMBUS_HOST_NOTIFY_STS        BIT0  // Host Notify Status
> +
> +#define R_PCH_SMBUS_SCMD                   0x11  // Slave Command Register
> R/W
> +#define B_PCH_SMBUS_SMBALERT_DIS           BIT2  // Not supported
> +#define B_PCH_SMBUS_HOST_NOTIFY_WKEN       BIT1  // Host Notify Wake
> Enable
> +#define B_PCH_SMBUS_HOST_NOTIFY_INTREN     BIT0  // Host Notify
> Interrupt Enable
> +
> +#define R_PCH_SMBUS_NDA                    0x14  // Notify Device Address
> Register RO
> +#define B_PCH_SMBUS_DEVICE_ADDRESS         0xFE  // Device Address
> +
> +#define R_PCH_SMBUS_NDLB                   0x16  // Notify Data Low Byte
> Register RO
> +#define R_PCH_SMBUS_NDHB                   0x17  // Notify Data High Byte
> Register RO
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsSpi.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsSpi.h
> new file mode 100644
> index 0000000000..bca7e4567e
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsSpi.h
> @@ -0,0 +1,119 @@
> +/**
> +
> +Copyright (c) 2011  - 2015, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +  @file
> +  PchRegsSpi.h
> +
> +  @brief
> +  Register names for PCH SPI device.
> +
> +  Conventions:
> +
> +  - Prefixes:
> +    Definitions beginning with "R_" are registers
> +    Definitions beginning with "B_" are bits within registers
> +    Definitions beginning with "V_" are meaningful values of bits within the
> registers
> +    Definitions beginning with "S_" are register sizes
> +    Definitions beginning with "N_" are the bit position
> +  - In general, PCH registers are denoted by "_PCH_" in register names
> +  - Registers / bits that are different between PCH generations are denoted
> by
> +    "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_VLV_"
> +  - Registers / bits that are different between SKUs are denoted by
> "_<SKU_name>"
> +    at the end of the register/bit names
> +  - Registers / bits of new devices introduced in a PCH generation will be just
> named
> +    as "_PCH_" without <generation_name> inserted.
> +
> +**/
> +#ifndef _PCH_REGS_SPI_H_
> +#define _PCH_REGS_SPI_H_
> +
> +///
> +/// SPI Host Interface Registers
> +///
> +
> +#define R_PCH_SPI_HSFS                       0x04  // Hardware Sequencing Flash
> Status Register (16bits)
> +#define B_PCH_SPI_HSFS_FLOCKDN               BIT15 // Flash Configuration
> Lock-Down
> +#define B_PCH_SPI_HSFS_FDV                   BIT14 // Flash Descriptor Valid
> +#define B_PCH_SPI_HSFS_FDOPSS                BIT13 // Flash Descriptor
> Override Pin-Strap Status
> +#define B_PCH_SPI_HSFS_SCIP                  BIT5  // SPI Cycle in Progress
> +#define B_PCH_SPI_HSFS_BERASE_MASK           (BIT4 | BIT3) // Block /
> Sector Erase Size
> +#define V_PCH_SPI_HSFS_BERASE_256B           0x00  // Block/Sector = 256
> Bytes
> +#define V_PCH_SPI_HSFS_BERASE_4K             0x01  // Block/Sector = 4K
> Bytes
> +#define V_PCH_SPI_HSFS_BERASE_8K             0x10  // Block/Sector = 8K
> Bytes
> +#define V_PCH_SPI_HSFS_BERASE_64K            0x11  // Block/Sector = 64K
> Bytes
> +#define B_PCH_SPI_HSFS_AEL                   BIT2  // Access Error Log
> +#define B_PCH_SPI_HSFS_FCERR                 BIT1  // Flash Cycle Error
> +#define B_PCH_SPI_HSFS_FDONE                 BIT0  // Flash Cycle Done
> +
> +#define R_PCH_SPI_PR0                        0x74  // Protected Region 0 Register
> +#define B_PCH_SPI_PR0_WPE                    BIT31 // Write Protection Enable
> +#define B_PCH_SPI_PR0_PRL_MASK               0x1FFF0000 // Protected Range
> Limit Mask, [28:16] here represents upper limit of address [24:12]
> +#define B_PCH_SPI_PR0_RPE                    BIT15 // Read Protection Enable
> +#define B_PCH_SPI_PR0_PRB_MASK               0x00001FFF // Protected Range
> Base Mask, [12:0] here represents base limit of address [24:12]
> +
> +#define R_PCH_SPI_PR1                        0x78  // Protected Region 1 Register
> +#define B_PCH_SPI_PR1_WPE                    BIT31 // Write Protection Enable
> +#define B_PCH_SPI_PR1_PRL_MASK               0x1FFF0000 // Protected Range
> Limit Mask, [28:16] here represents upper limit of address [24:12]
> +#define B_PCH_SPI_PR1_RPE                    BIT15 // Read Protection Enable
> +#define B_PCH_SPI_PR1_PRB_MASK               0x00001FFF // Protected Range
> Base Mask, [12:0] here represents base limit of address [24:12]
> +
> +#define R_PCH_SPI_PREOP                      0x94  // Prefix Opcode Configuration
> Register (16 bits)
> +#define B_PCH_SPI_PREOP1_MASK                0xFF00 // Prefix Opcode 1 Mask
> +#define B_PCH_SPI_PREOP0_MASK                0x00FF // Prefix Opcode 0 Mask
> +
> +#define R_PCH_SPI_OPTYPE                     0x96  // Opcode Type Configuration
> +#define B_PCH_SPI_OPTYPE7_MASK               (BIT15 | BIT14) // Opcode Type
> 7 Mask
> +#define B_PCH_SPI_OPTYPE6_MASK               (BIT13 | BIT12) // Opcode Type
> 6 Mask
> +#define B_PCH_SPI_OPTYPE5_MASK               (BIT11 | BIT10) // Opcode Type
> 5 Mask
> +#define B_PCH_SPI_OPTYPE4_MASK               (BIT9 | BIT8) // Opcode Type 4
> Mask
> +#define B_PCH_SPI_OPTYPE3_MASK               (BIT7 | BIT6) // Opcode Type 3
> Mask
> +#define B_PCH_SPI_OPTYPE2_MASK               (BIT5 | BIT4) // Opcode Type 2
> Mask
> +#define B_PCH_SPI_OPTYPE1_MASK               (BIT3 | BIT2) // Opcode Type 1
> Mask
> +#define B_PCH_SPI_OPTYPE0_MASK               (BIT1 | BIT0) // Opcode Type 0
> Mask
> +#define V_PCH_SPI_OPTYPE_RDNOADDR            0x00  // Read cycle type
> without address
> +#define V_PCH_SPI_OPTYPE_WRNOADDR            0x01  // Write cycle type
> without address
> +#define V_PCH_SPI_OPTYPE_RDADDR              0x02  // Address required;
> Read cycle type
> +#define V_PCH_SPI_OPTYPE_WRADDR              0x03  // Address required;
> Write cycle type
> +
> +#define R_PCH_SPI_OPMENU0                    0x98  // Opcode Menu
> Configuration 0 (32bits)
> +#define R_PCH_SPI_OPMENU1                    0x9C  // Opcode Menu
> Configuration 1 (32bits)
> +
> +#define R_PCH_SPI_IND_LOCK                   0xA4  // Indvidual Lock
> +#define B_PCH_SPI_IND_LOCK_PR0               BIT2  // PR0 LockDown
> +
> +
> +#define R_PCH_SPI_FDOC                       0xB0  // Flash Descriptor Observability
> Control Register (32 bits)
> +#define B_PCH_SPI_FDOC_FDSS_MASK             (BIT14 | BIT13 | BIT12) //
> Flash Descriptor Section Select
> +#define V_PCH_SPI_FDOC_FDSS_FSDM             0x0000 // Flash Signature and
> Descriptor Map
> +#define V_PCH_SPI_FDOC_FDSS_COMP             0x1000 // Component
> +#define V_PCH_SPI_FDOC_FDSS_REGN             0x2000 // Region
> +#define V_PCH_SPI_FDOC_FDSS_MSTR             0x3000 // Master
> +#define V_PCH_SPI_FDOC_FDSS_VLVS             0x4000 // Soft Straps
> +#define B_PCH_SPI_FDOC_FDSI_MASK             0x0FFC // Flash Descriptor
> Section Index
> +
> +#define R_PCH_SPI_FDOD                       0xB4  // Flash Descriptor Observability
> Data Register (32 bits)
> +
> +#define R_PCH_SPI_BCR                        0xFC  // BIOS Control Register
> +#define S_PCH_SPI_BCR                        1
> +#define B_PCH_SPI_BCR_SMM_BWP                BIT5  // SMM BIOS Write
> Protect Disable
> +#define B_PCH_SPI_BCR_SRC                    (BIT3 | BIT2) // SPI Read
> Configuration (SRC)
> +#define V_PCH_SPI_BCR_SRC_PREF_EN_CACHE_EN   0x08  // Prefetch
> Enable, Cache Enable
> +#define V_PCH_SPI_BCR_SRC_PREF_DIS_CACHE_DIS 0x04  // Prefetch
> Disable, Cache Disable
> +#define V_PCH_SPI_BCR_SRC_PREF_DIS_CACHE_EN  0x00  // Prefetch
> Disable, Cache Enable
> +#define B_PCH_SPI_BCR_BLE                    BIT1  // Lock Enable (LE)
> +#define B_PCH_SPI_BCR_BIOSWE                 BIT0  // Write Protect Disable
> (WPD)
> +#define N_PCH_SPI_BCR_BLE                    1
> +#define N_PCH_SPI_BCR_BIOSWE                 0
> +
> +//
> +// Flash Descriptor Base Address Region (FDBAR) from Flash Region 0
> +//
> +#define R_PCH_SPI_FDBAR_FLVALSIG             0x00  // Flash Valid Signature
> +#define V_PCH_SPI_FDBAR_FLVALSIG             0x0FF0A55A
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsUsb.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsUsb.h
> new file mode 100644
> index 0000000000..93b6419eb7
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/PchRegs/PchRegsUsb.h
> @@ -0,0 +1,92 @@
> +/**
> +
> +Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +  @file
> +  PchRegsUsb.h
> +
> +  @brief
> +  Register names for PCH USB devices.
> +
> +  Conventions:
> +
> +  - Prefixes:
> +    Definitions beginning with "R_" are registers
> +    Definitions beginning with "B_" are bits within registers
> +    Definitions beginning with "V_" are meaningful values of bits within the
> registers
> +    Definitions beginning with "S_" are register sizes
> +    Definitions beginning with "N_" are the bit position
> +  - In general, PCH registers are denoted by "_PCH_" in register names
> +  - Registers / bits that are different between PCH generations are denoted
> by
> +    "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_VLV_"
> +  - Registers / bits that are different between SKUs are denoted by
> "_<SKU_name>"
> +    at the end of the register/bit names
> +  - Registers / bits of new devices introduced in a PCH generation will be just
> named
> +    as "_PCH_" without <generation_name> inserted.
> +
> +**/
> +#ifndef _PCH_REGS_USB_H_
> +#define _PCH_REGS_USB_H_
> +
> +///
> +/// USB Definitions
> +///
> +
> +typedef enum {
> +  PchEhci1 = 0,
> +  PchEhciControllerMax
> +} PCH_USB20_CONTROLLER_TYPE;
> +
> +#define PCH_USB_MAX_PHYSICAL_PORTS          4      /// Max Physical
> Connector EHCI + XHCI, not counting virtual ports like USB-R.
> +#define PCH_EHCI_MAX_PORTS                  4      /// Counting ports behind
> RMHs 8 from EHCI-1 and 6 from EHCI-2, not counting EHCI USB-R virtual ports.
> +#define PCH_HSIC_MAX_PORTS                  2
> +#define PCH_XHCI_MAX_USB3_PORTS             1
> +
> +#define PCI_DEVICE_NUMBER_PCH_USB           29
> +#define PCI_FUNCTION_NUMBER_PCH_EHCI        0
> +
> +#define R_PCH_USB_VENDOR_ID                 0x00  // Vendor ID
> +#define V_PCH_USB_VENDOR_ID                 V_PCH_INTEL_VENDOR_ID
> +
> +#define R_PCH_USB_DEVICE_ID                 0x02  // Device ID
> +#define V_PCH_USB_DEVICE_ID_0               0x0F34  // EHCI#1
> +
> +#define R_PCH_EHCI_SVID                     0x2C  // USB2 Subsystem Vendor ID
> +#define B_PCH_EHCI_SVID                     0xFFFF // USB2 Subsystem Vendor ID
> Mask
> +
> +#define R_PCH_EHCI_PWR_CNTL_STS             0x54  // Power Management
> Control / Status
> +#define B_PCH_EHCI_PWR_CNTL_STS_PME_STS     BIT15 // PME Status
> +#define B_PCH_EHCI_PWR_CNTL_STS_DATASCL     (BIT14 | BIT13) // Data
> Scale
> +#define B_PCH_EHCI_PWR_CNTL_STS_DATASEL     (BIT12 | BIT11 | BIT10 |
> BIT9) // Data Select
> +#define B_PCH_EHCI_PWR_CNTL_STS_PME_EN      BIT8  // Power Enable
> +#define B_PCH_EHCI_PWR_CNTL_STS_PWR_STS     (BIT1 | BIT0) // Power
> State
> +#define V_PCH_EHCI_PWR_CNTL_STS_PWR_STS_D0  0     // D0 State
> +#define V_PCH_EHCI_PWR_CNTL_STS_PWR_STS_D3  (BIT1 | BIT0) // D3
> Hot State
> +
> +///
> +/// USB3 (XHCI) related definitions
> +///
> +#define PCI_DEVICE_NUMBER_PCH_XHCI          20
> +#define PCI_FUNCTION_NUMBER_PCH_XHCI        0
> +//
> +/////
> +///// XHCI PCI Config Space registers
> +/////
> +
> +#define R_PCH_XHCI_SVID                     0x2C
> +#define B_PCH_XHCI_SVID                     0xFFFF
> +
> +
> +#define R_PCH_XHCI_PWR_CNTL_STS             0x74
> +#define B_PCH_XHCI_PWR_CNTL_STS_PME_STS     BIT15
> +#define B_PCH_XHCI_PWR_CNTL_STS_DATASCL     (BIT14 | BIT13)
> +#define B_PCH_XHCI_PWR_CNTL_STS_DATASEL     (BIT12 | BIT11 | BIT10 |
> BIT9)
> +#define B_PCH_XHCI_PWR_CNTL_STS_PME_EN      BIT8
> +#define B_PCH_XHCI_PWR_CNTL_STS_PWR_STS     (BIT1 | BIT0)
> +#define V_PCH_XHCI_PWR_CNTL_STS_PWR_STS_D3  (BIT1 | BIT0)
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/PchInit.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/PchInit.h
> new file mode 100644
> index 0000000000..c8aba9c5e6
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/PchInit.h
> @@ -0,0 +1,75 @@
> +/**
> +**/
> +/**
> +
> +Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +  @file
> +  PchInit.h
> +
> +  @brief
> +  This file defines the PCH Init PPI
> +
> +**/
> +#ifndef _PCH_INIT_H_
> +#define _PCH_INIT_H_
> +
> +//
> +// Define the PCH Init PPI GUID
> +//
> +
> +
> +#include <Protocol/PchPlatformPolicy.h>
> +#define PCH_INIT_PPI_GUID \
> +  { \
> +    0x9ea894a, 0xbe0d, 0x4230, 0xa0, 0x3, 0xed, 0xc6, 0x93, 0xb4, 0x8e, 0x95 \
> +  }
> +extern EFI_GUID               gPchInitPpiGuid;
> +
> +///
> +/// Forward reference for ANSI C compatibility
> +///
> +typedef struct _PCH_INIT_PPI  PCH_INIT_PPI;
> +
> +///
> +/// Data structure definitions
> +///
> +typedef enum _CPU_STRAP_OPERATION {
> +  GetCpuStrapSetData,
> +  SetCpuStrapSetData,
> +  LockCpuStrapSetData
> +} CPU_STRAP_OPERATION;
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *PCH_USB_INIT) (
> +  IN  EFI_PEI_SERVICES            **PeiServices
> +  )
> +/**
> +
> +  @brief
> +  The function performing USB init in PEI phase. This could be used by USB
> recovery
> +  or debug features that need USB initialization during PEI phase.
> +  Note: Before executing this function, please be sure that
> PCH_INIT_PPI.Initialize
> +  has been done and PchUsbPolicyPpi has been installed.
> +
> +  @param[in] PeiServices    General purpose services available to every
> PEIM
> +
> +  @retval EFI_SUCCESS       The function completed successfully
> +  @retval Others            All other error conditions encountered result in an
> ASSERT.
> +
> +**/
> +;
> +
> +///
> +/// PCH_INIT_PPI Structure Definition
> +///
> +struct _PCH_INIT_PPI {
> +  PCH_USB_INIT          UsbInit;
> +};
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/PchPeiInit.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/PchPeiInit.h
> new file mode 100644
> index 0000000000..a9bbb3766c
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/PchPeiInit.h
> @@ -0,0 +1,34 @@
> +
> +/*++
> +
> +Copyright (c)  2013  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +Module Name:
> +
> +  PchPeiInit.h
> +
> +Abstract:
> +
> +
> +--*/
> +
> +#ifndef _PCH_PEI_INIT_H_
> +#define _PCH_PEI_INIT_H_
> +
> +//
> +// Define the PCH PEI Init PPI GUID
> +//
> +#define PCH_PEI_INIT_PPI_GUID \
> +  { \
> +    0xACB93B08, 0x5CDC, 0x4A8F, 0x93, 0xD4, 0x6, 0xE3, 0x42, 0xDF, 0x18,
> 0x2E \
> +  }
> +
> +//
> +// Extern the GUID for PPI users.
> +//
> +extern EFI_GUID     gPchPeiInitPpiGuid;
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/PchPlatformPolicy.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/PchPlatformPolicy.h
> new file mode 100644
> index 0000000000..b3b2f549cd
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/PchPlatformPolicy.h
> @@ -0,0 +1,161 @@
> +/**
> +**/
> +/**
> +
> +Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +  @file
> +  PchPlatformPolicy.h
> +
> +  @brief
> +  PCH policy PPI produced by a platform driver specifying various
> +  expected PCH settings. This PPI is consumed by the PCH PEI modules.
> +
> +**/
> +#ifndef PCH_PLATFORM_POLICY_H_
> +#define PCH_PLATFORM_POLICY_H_
> +//
> +// External include files do NOT need to be explicitly specified in real EDKII
> +// environment
> +//
> +
> +
> +#include "PchRegs.h"
> +
> +//
> +#define PCH_PLATFORM_POLICY_PPI_GUID \
> +  { \
> +    0x15344673, 0xd365, 0x4be2, 0x85, 0x13, 0x14, 0x97, 0xcc, 0x7, 0x61, 0x1d
> \
> +  }
> +
> +extern EFI_GUID                         gPchPlatformPolicyPpiGuid;
> +
> +///
> +/// Forward reference for ANSI C compatibility
> +///
> +typedef struct _PCH_PLATFORM_POLICY_PPI PCH_PLATFORM_POLICY_PPI;
> +
> +///
> +/// PPI revision number
> +/// Any backwards compatible changes to this PPI will result in an update in
> the revision number
> +/// Major changes will require publication of a new PPI
> +///
> +/// Revision 1:    Original version
> +///
> +#define PCH_PLATFORM_POLICY_PPI_REVISION_1  1
> +#define PCH_PLATFORM_POLICY_PPI_REVISION_2  2
> +#define PCH_PLATFORM_POLICY_PPI_REVISION_3  3
> +#define PCH_PLATFORM_POLICY_PPI_REVISION_4  4
> +#define PCH_PLATFORM_POLICY_PPI_REVISION_5  5
> +//
> +// Generic definitions for device enabling/disabling used by PCH code.
> +//
> +#define PCH_DEVICE_ENABLE   1
> +#define PCH_DEVICE_DISABLE  0
> +
> +typedef struct {
> +  UINT8  ThermalDataReportEnable  : 1;   // OBSOLETE from Revision 5 !!! DO
> NOT USE !!!
> +  UINT8  MchTempReadEnable        : 1;
> +  UINT8  PchTempReadEnable        : 1;
> +  UINT8  CpuEnergyReadEnable      : 1;
> +  UINT8  CpuTempReadEnable        : 1;
> +  UINT8  Cpu2TempReadEnable       : 1;
> +  UINT8  TsOnDimmEnable           : 1;
> +  UINT8  Dimm1TempReadEnable      : 1;
> +
> +  UINT8  Dimm2TempReadEnable      : 1;
> +  UINT8  Dimm3TempReadEnable      : 1;
> +  UINT8  Dimm4TempReadEnable      : 1;
> +  UINT8  Rsvdbits                 : 5;
> +} PCH_THERMAL_REPORT_CONTROL;
> +//
> +// ---------------------------- HPET Config -----------------------------
> +//
> +typedef struct {
> +  BOOLEAN Enable; /// Determines if enable HPET function
> +  UINT32  Base;   /// The HPET base address
> +} PCH_HPET_CONFIG;
> +
> +
> +///
> +/// ---------------------------- SATA Config -----------------------------
> +///
> +typedef enum {
> +  PchSataModeIde,
> +  PchSataModeAhci,
> +  PchSataModeRaid,
> +  PchSataModeMax
> +} PCH_SATA_MODE;
> +
> +///
> +/// ---------------------------- PCI Express Config -----------------------------
> +///
> +typedef enum {
> +  PchPcieAuto,
> +  PchPcieGen1,
> +  PchPcieGen2
> +} PCH_PCIE_SPEED;
> +
> +typedef struct {
> +  PCH_PCIE_SPEED  PcieSpeed[PCH_PCIE_MAX_ROOT_PORTS];
> +} PCH_PCIE_CONFIG;
> +
> +///
> +/// ---------------------------- IO APIC Config -----------------------------
> +///
> +typedef struct {
> +  UINT8 IoApicId;
> +} PCH_IOAPIC_CONFIG;
> +
> +///
> +/// --------------------- Low Power Input Output Config ------------------------
> +///
> +typedef struct {
> +  UINT8                   LpssPciModeEnabled    : 1;    /// Determines if LPSS PCI
> Mode enabled
> +  UINT8                   Dma0Enabled           : 1;     /// Determines if LPSS DMA1
> enabled
> +  UINT8                   Dma1Enabled           : 1;     /// Determines if LPSS DMA2
> enabled
> +  UINT8                   I2C0Enabled           : 1;     /// Determines if LPSS I2C #1
> enabled
> +  UINT8                   I2C1Enabled           : 1;     /// Determines if LPSS I2C #2
> enabled
> +  UINT8                   I2C2Enabled           : 1;     /// Determines if LPSS I2C #3
> enabled
> +  UINT8                   I2C3Enabled           : 1;     /// Determines if LPSS I2C #4
> enabled
> +  UINT8                   I2C4Enabled           : 1;     /// Determines if LPSS I2C #5
> enabled
> +  UINT8                   I2C5Enabled           : 1;     /// Determines if LPSS I2C #6
> enabled
> +  UINT8                   I2C6Enabled           : 1;     /// Determines if LPSS I2C #7
> enabled
> +  UINT8                   Pwm0Enabled           : 1;     /// Determines if LPSS PWM #1
> enabled
> +  UINT8                   Pwm1Enabled           : 1;     /// Determines if LPSS PWM #2
> enabled
> +  UINT8                   Hsuart0Enabled        : 1;     /// Determines if LPSS HSUART #1
> enabled
> +  UINT8                   Hsuart1Enabled        : 1;     /// Determines if LPSS HSUART #2
> enabled
> +  UINT8                   SpiEnabled            : 1;     /// Determines if LPSS SPI enabled
> +  UINT8                   Rsvdbits              : 2;
> +} PEI_PCH_LPSS_CONFIG;
> +
> +///
> +/// ------------ General PCH Platform Policy PPI definition ------------
> +///
> +struct _PCH_PLATFORM_POLICY_PPI {
> +  UINT8                         Revision;
> +  UINT8                         BusNumber;  // Bus Number of the PCH device
> +  UINT32                        SpiBase;    // SPI Base Address.
> +  UINT32                        PmcBase;    // PMC Base Address.
> +  UINT32                        SmbmBase;   // SMB Memory Base Address.
> +  UINT32                        IoBase;     // IO Base Address.
> +  UINT32                        IlbBase;    // Intel Legacy Block Base Address.
> +  UINT32                        PUnitBase;  // PUnit Base Address.
> +  UINT32                        Rcba;       // Root Complex Base Address.
> +  UINT32                        MphyBase;   // MPHY Base Address.
> +  UINT16                        AcpiBase;   // ACPI I/O Base address.
> +  UINT16                        GpioBase;   // GPIO Base address
> +  PCH_HPET_CONFIG               *HpetConfig;
> +  PCH_SATA_MODE                 SataMode;
> +  PCH_PCIE_CONFIG               *PcieConfig;
> +  PCH_IOAPIC_CONFIG             *IoApicConfig;
> +  PEI_PCH_LPSS_CONFIG           *LpssConfig;
> +  BOOLEAN                       EnableRmh;      // Determines if enable USB RMH
> function
> +  BOOLEAN                       EhciPllCfgEnable;
> +};
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/PchUsbPolicy.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/PchUsbPolicy.h
> new file mode 100644
> index 0000000000..d03aa4a8b4
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/PchUsbPolicy.h
> @@ -0,0 +1,69 @@
> +/**
> +**/
> +/**
> +
> +Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +  @file
> +  PchUsbPolicy.h
> +
> +  @brief
> +  PCH Usb policy PPI produced by a platform driver specifying
> +  various expected PCH Usb settings. This PPI is consumed by the
> +  PCH PEI drivers.
> +
> +**/
> +#ifndef _PCH_USB_POLICY_H_
> +#define _PCH_USB_POLICY_H_
> +
> +//
> +// PCH Usb policy provided by platform for PEI phase
> +//
> +
> +#ifndef ECP_FLAG
> +#include <PiPei.h>
> +#endif
> +
> +#include "PchRegs.h"
> +#include <Protocol/PchPlatformPolicy.h>
> +
> +#define PCH_USB_POLICY_PPI_GUID \
> +  { \
> +    0xc02b0573, 0x2b4e, 0x4a31, 0xa3, 0x1a, 0x94, 0x56, 0x7b, 0x50, 0x44, 0x2c
> \
> +  }
> +
> +extern EFI_GUID                     gPchUsbPolicyPpiGuid;
> +
> +typedef struct _PCH_USB_POLICY_PPI  PCH_USB_POLICY_PPI;
> +
> +///
> +/// PPI revision number
> +/// Any backwards compatible changes to this PPI will result in an update in
> the revision number
> +/// Major changes will require publication of a new PPI
> +///
> +/// Revision 1: Original version
> +///
> +#define PCH_USB_POLICY_PPI_REVISION_1 1
> +
> +///
> +/// Generic definitions for device enabling/disabling used by PCH code.
> +///
> +#define PCH_DEVICE_ENABLE   1
> +#define PCH_DEVICE_DISABLE  0
> +
> +#define EHCI_MODE           1
> +
> +struct _PCH_USB_POLICY_PPI {
> +  UINT8           Revision;
> +  PCH_USB_CONFIG  *UsbConfig;
> +  UINT8           Mode;
> +  UINTN           EhciMemBaseAddr;
> +  UINT32          EhciMemLength;
> +  UINTN           XhciMemBaseAddr;
> +};
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/PeiBlockIo.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/PeiBlockIo.h
> new file mode 100644
> index 0000000000..d6c8366e26
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/PeiBlockIo.h
> @@ -0,0 +1,230 @@
> +/** @file
> +  Block IO protocol as defined in the UEFI 2.0 specification.
> +
> +  The Block IO protocol is used to abstract block devices like hard drives,
> +  DVD-ROMs and floppy drives.
> +
> +  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef __PEI_BLOCK_IO_H__
> +#define __PEI_BLOCK_IO_H__
> +// {BC5FA650-EDBB-4d0d-B3A3-D98907F847DF}
> +#ifndef ECP_FLAG
> +#define PEI_BLOCK_IO_PPI_GUID \
> +  {  \
> +    0xbc5fa650, 0xedbb, 0x4d0d, { 0xb3, 0xa3, 0xd9, 0x89, 0x7, 0xf8, 0x47,
> 0xdf }  \
> +  }
> +#endif
> +typedef struct _PEI_BLOCK_IO_PPI  PEI_BLOCK_IO_PPI;
> +
> +
> +/**
> +  Reset the Block Device.
> +
> +  @param  This                 Indicates a pointer to the calling context.
> +  @param  ExtendedVerification Driver may perform diagnostics on reset.
> +
> +  @retval EFI_SUCCESS          The device was reset.
> +  @retval EFI_DEVICE_ERROR     The device is not functioning properly and
> could
> +                               not be reset.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_BLOCK_RESET)(
> +  IN PEI_BLOCK_IO_PPI               *This,
> +  IN BOOLEAN                        ExtendedVerification
> +  );
> +
> +/**
> +  Read BufferSize bytes from Lba into Buffer.
> +
> +  @param  This       Indicates a pointer to the calling context.
> +  @param  MediaId    Id of the media, changes every time the media is
> replaced.
> +  @param  Lba        The starting Logical Block Address to read from
> +  @param  BufferSize Size of Buffer, must be a multiple of device block size.
> +  @param  Buffer     A pointer to the destination buffer for the data. The
> caller is
> +                     responsible for either having implicit or explicit ownership of the
> buffer.
> +
> +  @retval EFI_SUCCESS           The data was read correctly from the device.
> +  @retval EFI_DEVICE_ERROR      The device reported an error while
> performing the read.
> +  @retval EFI_NO_MEDIA          There is no media in the device.
> +  @retval EFI_MEDIA_CHANGED     The MediaId does not matched the
> current device.
> +  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block
> size of the device.
> +  @retval EFI_INVALID_PARAMETER The read request contains LBAs that
> are not valid,
> +                                or the buffer is not on proper alignment.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_BLOCK_READ)(
> +  IN  EFI_PEI_SERVICES              **PeiServices,
> +  IN PEI_BLOCK_IO_PPI               *This,
> +  IN UINT32                         MediaId,
> +  IN EFI_LBA                        Lba,
> +  IN UINTN                          BufferSize,
> +  OUT VOID                          *Buffer
> +  );
> +
> +/**
> +  Write BufferSize bytes from Lba into Buffer.
> +
> +  @param  This       Indicates a pointer to the calling context.
> +  @param  MediaId    The media ID that the write request is for.
> +  @param  Lba        The starting logical block address to be written. The caller
> is
> +                     responsible for writing to only legitimate locations.
> +  @param  BufferSize Size of Buffer, must be a multiple of device block size.
> +  @param  Buffer     A pointer to the source buffer for the data.
> +
> +  @retval EFI_SUCCESS           The data was written correctly to the device.
> +  @retval EFI_WRITE_PROTECTED   The device can not be written to.
> +  @retval EFI_DEVICE_ERROR      The device reported an error while
> performing the write.
> +  @retval EFI_NO_MEDIA          There is no media in the device.
> +  @retval EFI_MEDIA_CHNAGED     The MediaId does not matched the
> current device.
> +  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block
> size of the device.
> +  @retval EFI_INVALID_PARAMETER The write request contains LBAs that
> are not valid,
> +                                or the buffer is not on proper alignment.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_BLOCK_WRITE)(
> +  IN  EFI_PEI_SERVICES              **PeiServices,
> +  IN PEI_BLOCK_IO_PPI               *This,
> +  IN UINT32                         MediaId,
> +  IN EFI_LBA                        Lba,
> +  IN UINTN                          BufferSize,
> +  IN VOID                           *Buffer
> +  );
> +
> +/**
> +  Flush the Block Device.
> +
> +  @param  This              Indicates a pointer to the calling context.
> +
> +  @retval EFI_SUCCESS       All outstanding data was written to the device
> +  @retval EFI_DEVICE_ERROR  The device reported an error while writting
> back the data
> +  @retval EFI_NO_MEDIA      There is no media in the device.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_BLOCK_FLUSH)(
> +  IN  PEI_BLOCK_IO_PPI           *This
> +  );
> +
> +/**
> +  Block IO read only mode data and updated only via members of BlockIO
> +**/
> +typedef struct {
> +  ///
> +  /// The curent media Id. If the media changes, this value is changed.
> +  ///
> +  UINT32  MediaId;
> +
> +  ///
> +  /// TRUE if the media is removable; otherwise, FALSE.
> +  ///
> +  BOOLEAN RemovableMedia;
> +
> +  ///
> +  /// TRUE if there is a media currently present in the device;
> +  /// othersise, FALSE. THis field shows the media present status
> +  /// as of the most recent ReadBlocks() or WriteBlocks() call.
> +  ///
> +  BOOLEAN MediaPresent;
> +
> +  ///
> +  /// TRUE if LBA 0 is the first block of a partition; otherwise
> +  /// FALSE. For media with only one partition this would be TRUE.
> +  ///
> +  BOOLEAN LogicalPartition;
> +
> +  ///
> +  /// TRUE if the media is marked read-only otherwise, FALSE.
> +  /// This field shows the read-only status as of the most recent WriteBlocks
> () call.
> +  ///
> +  BOOLEAN ReadOnly;
> +
> +  ///
> +  /// TRUE if the WriteBlock () function caches write data.
> +  ///
> +  BOOLEAN WriteCaching;
> +
> +  ///
> +  /// The intrinsic block size of the device. If the media changes, then
> +  /// this field is updated.
> +  ///
> +  UINT32  BlockSize;
> +
> +  ///
> +  /// Supplies the alignment requirement for any buffer to read or write
> block(s).
> +  ///
> +  UINT32  IoAlign;
> +
> +  ///
> +  /// The last logical block address on the device.
> +  /// If the media changes, then this field is updated.
> +  ///
> +  EFI_LBA LastBlock;
> +
> +  ///
> +  /// Only present if EFI_BLOCK_IO_PROTOCOL.Revision is greater than or
> equal to
> +  /// EFI_BLOCK_IO_PROTOCOL_REVISION2. Returns the first LBA is aligned
> to
> +  /// a physical block boundary.
> +  ///
> +  EFI_LBA LowestAlignedLba;
> +
> +  ///
> +  /// Only present if EFI_BLOCK_IO_PROTOCOL.Revision is greater than or
> equal to
> +  /// EFI_BLOCK_IO_PROTOCOL_REVISION2. Returns the number of logical
> blocks
> +  /// per physical block.
> +  ///
> +  UINT32 LogicalBlocksPerPhysicalBlock;
> +
> +  ///
> +  /// Only present if EFI_BLOCK_IO_PROTOCOL.Revision is greater than or
> equal to
> +  /// EFI_BLOCK_IO_PROTOCOL_REVISION3. Returns the optimal transfer
> length
> +  /// granularity as a number of logical blocks.
> +  ///
> +  UINT32 OptimalTransferLengthGranularity;
> +#ifdef ECP_FLAG
> +} PEI_BLOCK_IO_MEDIA2;
> +#else
> +} PEI_BLOCK_IO_MEDIA;
> +#endif
> +#define EFI_BLOCK_IO_PROTOCOL_REVISION  0x00010000
> +#define EFI_BLOCK_IO_PROTOCOL_REVISION2 0x00020001
> +#define EFI_BLOCK_IO_PROTOCOL_REVISION3 0x00020031
> +
> +///
> +/// Revision defined in EFI1.1.
> +///
> +#define EFI_BLOCK_IO_INTERFACE_REVISION
> EFI_BLOCK_IO_PROTOCOL_REVISION
> +
> +///
> +///  This protocol provides control over block devices.
> +///
> +struct _PEI_BLOCK_IO_PPI {
> +  ///
> +  /// The revision to which the block IO interface adheres. All future
> +  /// revisions must be backwards compatible. If a future version is not
> +  /// back wards compatible, it is not the same GUID.
> +  ///
> +  UINT64              Revision;
> +  ///
> +  /// Pointer to the EFI_BLOCK_IO_MEDIA data for this device.
> +  ///
> +  PEI_BLOCK_IO_MEDIA  *Media;
> +  PEI_BLOCK_RESET     Reset;
> +  PEI_BLOCK_READ      ReadBlocks;
> +  PEI_BLOCK_WRITE     WriteBlocks;
> +  PEI_BLOCK_FLUSH     FlushBlocks;
> +};
> +
> +//extern EFI_GUID gEfiBlockIoProtocolGuid;
> +extern EFI_GUID gPeiBlockIoPpiGuid;
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/Sdhc.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/Sdhc.h
> new file mode 100644
> index 0000000000..4909d81573
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/Sdhc.h
> @@ -0,0 +1,359 @@
> +/**
> +**/
> +/**
> +
> +Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +  @file
> +  Spi.h
> +
> +  @brief
> +  This file defines the EFI SPI PPI which implements the
> +  Intel(R) PCH SPI Host Controller Compatibility Interface.
> +
> +**/
> +#ifndef _PEI_SDHC_H_
> +#define _PEI_SDHC_H_
> +
> +
> +
> +//
> +#define PEI_SDHC_PPI_GUID \
> +  {  \
> +    0xf4ef9d7a, 0x98c5, 0x4c1a, 0xb4, 0xd9, 0xd8, 0xd8, 0x72, 0x65, 0xbe, 0xc
> \
> +  }
> +typedef struct _PEI_SD_CONTROLLER_PPI PEI_SD_CONTROLLER_PPI;
> +
> +#define EFI_SD_HOST_IO_PROTOCOL_REVISION_01          0x01
> +
> +typedef enum {
> +  ResponseNo = 0,
> +  ResponseR1,
> +  ResponseR1b,
> +  ResponseR2,
> +  ResponseR3,
> +  ResponseR4,
> +  ResponseR5,
> +  ResponseR5b,
> +  ResponseR6,
> +  ResponseR7
> +} RESPONSE_TYPE;
> +
> +typedef enum {
> +  NoData = 0,
> +  InData,
> +  OutData
> +} TRANSFER_TYPE;
> +
> +typedef enum {
> +  Reset_Auto = 0,
> +  Reset_DAT,
> +  Reset_CMD,
> +  Reset_DAT_CMD,
> +  Reset_All
> +} RESET_TYPE;
> +
> +
> +
> +typedef enum {
> +  SDMA = 0,
> +  ADMA2,
> +  PIO
> +} DMA_MOD;
> +
> +typedef struct {
> +  UINT32  HighSpeedSupport:    1;  //High speed supported
> +  UINT32  V18Support:          1;  //1.8V supported
> +  UINT32  V30Support:          1;  //3.0V supported
> +  UINT32  V33Support:          1;  //3.3V supported
> +  UINT32  Reserved0:           4;
> +  UINT32  BusWidth4:           1;  // 4 bit width
> +  UINT32  BusWidth8:           1;  // 8 bit width
> +  UINT32  Reserved1:           6;
> +  UINT32  SDMASupport:         1;
> +  UINT32  ADMA2Support:        1;
> +  UINT32  DmaMode:             2;
> +  UINT32  Reserved2:           12;
> +  UINT32  BoundarySize;
> +}HOST_CAPABILITY;
> +
> +
> +#define PCI_SUBCLASS_SD_HOST_CONTROLLER   0x05
> +#define PCI_IF_STANDARD_HOST_NO_DMA       0x00
> +#define PCI_IF_STANDARD_HOST_SUPPORT_DMA  0x01
> +
> +//
> +//MMIO Registers definition for MMC/SDIO controller
> +//
> +#define  MMIO_DMAADR                     0x00
> +#define  MMIO_BLKSZ                      0x04
> +#define  MMIO_BLKCNT                     0x06
> +#define  MMIO_CMDARG                     0x08
> +#define  MMIO_XFRMODE                    0x0C
> +#define  MMIO_SDCMD                      0x0E
> +#define  MMIO_RESP                       0x10
> +#define  MMIO_BUFDATA                    0x20
> +#define  MMIO_PSTATE                     0x24
> +#define  MMIO_HOSTCTL                    0x28
> +#define  MMIO_PWRCTL                     0x29
> +#define  MMIO_BLKGAPCTL                  0x2A
> +#define  MMIO_WAKECTL                    0x2B
> +#define  MMIO_CLKCTL                     0x2C
> +#define  MMIO_TOCTL                      0x2E
> +#define  MMIO_SWRST                      0x2F
> +#define  MMIO_NINTSTS                    0x30
> +#define  MMIO_ERINTSTS                   0x32
> +#define  MMIO_NINTEN                     0x34
> +#define  MMIO_ERINTEN                    0x36
> +#define  MMIO_NINTSIGEN                  0x38
> +#define  MMIO_ERINTSIGEN                 0x3A
> +#define  MMIO_AC12ERRSTS                 0x3C
> +#define  MMIO_HOST_CTL2                  0x3E //hphang <- New in VLV2
> +#define  MMIO_CAP                        0x40
> +#define  MMIO_CAP2                       0x44 //hphang <- New in VLV2
> +#define  MMIO_MCCAP                      0x48
> +#define  MMIO_FORCEEVENTCMD12ERRSTAT     0x50 //hphang <- New in
> VLV2
> +#define  MMIO_FORCEEVENTERRINTSTAT       0x52 //hphang <- New in VLV2
> +#define  MMIO_ADMAERRSTAT                0x54 //hphang <- New in VLV2
> +#define  MMIO_ADMASYSADDR                0x58 //hphang <- New in VLV2
> +#define  MMIO_PRESETVALUE0               0x60 //hphang <- New in VLV2
> +#define  MMIO_PRESETVALUE1               0x64 //hphang <- New in VLV2
> +#define  MMIO_PRESETVALUE2               0x68 //hphang <- New in VLV2
> +#define  MMIO_PRESETVALUE3               0x6C //hphang <- New in VLV2
> +#define  MMIO_BOOTTIMEOUTCTRL            0x70 //hphang <- New in VLV2
> +#define  MMIO_DEBUGSEL                   0x74 //hphang <- New in VLV2
> +#define  MMIO_SHAREDBUS                  0xE0 //hphang <- New in VLV2
> +#define  MMIO_SPIINTSUP                  0xF0 //hphang <- New in VLV2
> +#define  MMIO_SLTINTSTS                  0xFC
> +#define  MMIO_CTRLRVER                   0xFE
> +#define  MMIO_SRST                       0x1FC
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SD_CONTROLLER_PPI_SEND_COMMAND) (
> +  IN  PEI_SD_CONTROLLER_PPI       *This,
> +  IN   UINT16                     CommandIndex,
> +  IN   UINT32                     Argument,
> +  IN   TRANSFER_TYPE              DataType,
> +  IN   UINT8                      *Buffer, OPTIONAL
> +  IN   UINT32                     BufferSize,
> +  IN   RESPONSE_TYPE              ResponseType,
> +  IN   UINT32                     TimeOut,
> +  OUT  UINT32                     *ResponseData OPTIONAL
> +  );
> +
> +/*++
> +
> +  Routine Description:
> +    Set max clock frequency of the host, the actual frequency
> +    may not be the same as MaxFrequency. It depends on
> +    the max frequency the host can support, divider, and host
> +    speed mode.
> +
> +  Arguments:
> +    This           - Pointer to EFI_SD_HOST_IO_PROTOCOL
> +    MaxFrequency   - Max frequency in HZ
> +
> +  Returns:
> +    EFI_SUCCESS
> +    EFI_TIMEOUT
> +--*/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SD_CONTROLLER_PPI_SET_CLOCK_FREQUENCY) (
> +  IN  PEI_SD_CONTROLLER_PPI      *This,
> +  IN  UINT32                     MaxFrequency
> +  );
> +
> +/*++
> +
> +  Routine Description:
> +    Set bus width of the host
> +
> +  Arguments:
> +    This       - Pointer to EFI_SD_HOST_IO_PROTOCOL
> +    BusWidth   - Bus width in 1, 4, 8 bits
> +
> +  Returns:
> +    EFI_SUCCESS
> +    EFI_INVALID_PARAMETER
> +
> +--*/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SD_CONTROLLER_PPI_SET_BUS_WIDTH) (
> +  IN  PEI_SD_CONTROLLER_PPI      *This,
> +  IN  UINT32                     BusWidth
> +  );
> +
> +/*++
> +
> +  Routine Description:
> +    Set Host mode in DDR
> +  Arguments:
> +    This      - Pointer to EFI_SD_HOST_IO_PROTOCOL
> +    SetHostDdrMode   - True for DDR Mode set, false for normal mode
> +
> +  Returns:
> +    EFI_SUCCESS
> +    EFI_INVALID_PARAMETER
> +
> +--*/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SET_HOST_DDR_MODE) (
> +  IN  PEI_SD_CONTROLLER_PPI    *This,
> +  IN  UINT32                     DdrMode
> +  );
> +
> +/*++
> +
> +  Routine Description:
> +    Set voltage which could supported by the host.
> +    Support 0(Power off the host), 1.8V, 3.0V, 3.3V
> +  Arguments:
> +    This      - Pointer to EFI_SD_HOST_IO_PROTOCOL
> +    Voltage   - Units in 0.1 V
> +
> +  Returns:
> +    EFI_SUCCESS
> +    EFI_INVALID_PARAMETER
> +
> +--*/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SD_CONTROLLER_PPI_SET_HOST_VOLTAGE) (
> +  IN  PEI_SD_CONTROLLER_PPI      *This,
> +  IN  UINT32                     Voltage
> +  );
> +
> +/*++
> +
> +  Routine Description:
> +   Reset the host
> +
> +  Arguments:
> +    This      - Pointer to EFI_SD_HOST_IO_PROTOCOL
> +    ResetAll  - TRUE to reset all
> +
> +  Returns:
> +    EFI_SUCCESS
> +    EFI_TIMEOUT
> +
> +--*/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SD_CONTROLLER_PPI_RESET_SD_HOST) (
> +  IN  PEI_SD_CONTROLLER_PPI      *This,
> +  IN  RESET_TYPE                 ResetType
> +  );
> +
> +/*++
> +
> +  Routine Description:
> +   Reset the host
> +
> +  Arguments:
> +    This    - Pointer to EFI_SD_HOST_IO_PROTOCOL
> +    Enable  - TRUE to enable, FALSE to disable
> +
> +  Returns:
> +    EFI_SUCCESS
> +    EFI_TIMEOUT
> +
> +--*/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SD_CONTROLLER_PPI_ENABLE_AUTO_STOP_CMD) (
> +  IN  PEI_SD_CONTROLLER_PPI      *This,
> +  IN  BOOLEAN                    Enable
> +  );
> +
> +/*++
> +
> +  Routine Description:
> +    Find whether these is a card inserted into the slot. If so
> +    init the host. If not, return EFI_NOT_FOUND.
> +
> +  Arguments:
> +    This      - Pointer to EFI_SD_HOST_IO_PROTOCOL
> +
> +  Returns:
> +    EFI_SUCCESS
> +    EFI_NOT_FOUND
> +
> +--*/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SD_CONTROLLER_PPI_DETECT_CARD_AND_INIT_HOST) (
> +  IN  PEI_SD_CONTROLLER_PPI      *This
> +  );
> +
> +/*++
> +
> +  Routine Description:
> +   Set the Block length
> +
> +  Arguments:
> +    This        - Pointer to EFI_SD_HOST_IO_PROTOCOL
> +    BlockLength - card supportes block length
> +
> +  Returns:
> +    EFI_SUCCESS
> +    EFI_TIMEOUT
> +
> +--*/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SD_CONTROLLER_PPI_SET_BLOCK_LENGTH) (
> +  IN  PEI_SD_CONTROLLER_PPI      *This,
> +  IN  UINT32                     BlockLength
> +  );
> +
> +/*++
> +
> +  Routine Description:
> +   Set the Block length
> +
> +  Arguments:
> +    This        - Pointer to EFI_SD_HOST_IO_PROTOCOL
> +    BlockLength - card supportes block length
> +
> +  Returns:
> +    EFI_SUCCESS
> +    EFI_TIMEOUT
> +
> +--*/
> +
> +typedef EFI_STATUS
> +(EFIAPI *EFI_SD_CONTROLLER_PPI_SETUP_DEVICE)(
> +  IN  PEI_SD_CONTROLLER_PPI    *This
> +  );
> +
> +//
> +// Interface structure for the EFI SD Host I/O Protocol
> +//
> +struct _PEI_SD_CONTROLLER_PPI {
> +  UINT32                                           Revision;
> +  HOST_CAPABILITY                                  HostCapability;
> +  EFI_SD_CONTROLLER_PPI_SEND_COMMAND               SendCommand;
> +  EFI_SD_CONTROLLER_PPI_SET_CLOCK_FREQUENCY
> SetClockFrequency;
> +  EFI_SD_CONTROLLER_PPI_SET_BUS_WIDTH              SetBusWidth;
> +  EFI_SD_CONTROLLER_PPI_SET_HOST_VOLTAGE           SetHostVoltage;
> +  EFI_SD_HOST_IO_PROTOCOL_SET_HOST_DDR_MODE
> SetHostDdrMode;
> +  EFI_SD_CONTROLLER_PPI_RESET_SD_HOST              ResetSdHost;
> +  EFI_SD_CONTROLLER_PPI_ENABLE_AUTO_STOP_CMD
> EnableAutoStopCmd;
> +  EFI_SD_CONTROLLER_PPI_DETECT_CARD_AND_INIT_HOST
> DetectCardAndInitHost;
> +  EFI_SD_CONTROLLER_PPI_SET_BLOCK_LENGTH           SetBlockLength;
> +  EFI_SD_CONTROLLER_PPI_SETUP_DEVICE               SetupDevice;
> +};
> +// Extern the GUID for PPI users.
> +//
> +extern EFI_GUID           gPeiSdhcPpiGuid;
> +
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/SmbusPolicy.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/SmbusPolicy.h
> new file mode 100644
> index 0000000000..3f48142138
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/SmbusPolicy.h
> @@ -0,0 +1,40 @@
> +//
> +//
> +
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  SmbusPolicy.h
> +
> +Abstract:
> +
> +  Smbus Policy PPI as defined in EFI 2.0
> +
> +--*/
> +#ifndef _PEI_SMBUS_POLICY_PPI_H
> +#define _PEI_SMBUS_POLICY_PPI_H
> +
> +#define PEI_SMBUS_POLICY_PPI_GUID \
> +  { \
> +    0x63b6e435, 0x32bc, 0x49c6, 0x81, 0xbd, 0xb7, 0xa1, 0xa0, 0xfe, 0x1a, 0x6c
> \
> +  }
> +
> +typedef struct _PEI_SMBUS_POLICY_PPI PEI_SMBUS_POLICY_PPI;
> +
> +struct _PEI_SMBUS_POLICY_PPI {
> +  UINTN   BaseAddress;
> +  UINT32  PciAddress;
> +  UINT8   NumRsvdAddress;
> +  UINT8   *RsvdAddress;
> +};
> +
> +extern EFI_GUID gPeiSmbusPolicyPpiGuid;
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/Spi.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/Spi.h
> new file mode 100644
> index 0000000000..3496f59d1d
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Ppi/Spi.h
> @@ -0,0 +1,42 @@
> +/**
> +**/
> +/**
> +
> +Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +  @file
> +  Spi.h
> +
> +  @brief
> +  This file defines the EFI SPI PPI which implements the
> +  Intel(R) PCH SPI Host Controller Compatibility Interface.
> +
> +**/
> +#ifndef _PEI_SPI_H_
> +#define _PEI_SPI_H_
> +
> +
> +#include <Protocol/Spi.h>
> +
> +
> +//
> +#define PEI_SPI_PPI_GUID \
> +  { \
> +    0xa38c6898, 0x2b5c, 0x4ff6, 0x93, 0x26, 0x2e, 0x63, 0x21, 0x2e, 0x56, 0xc2
> \
> +  }
> +// Extern the GUID for PPI users.
> +//
> +extern EFI_GUID           gPeiSpiPpiGuid;
> +
> +///
> +/// Reuse the EFI_SPI_PROTOCOL definitions
> +/// This is possible becaues the PPI implementation does not rely on a
> PeiService pointer,
> +/// as it uses EDKII Glue Lib to do IO accesses
> +///
> +typedef EFI_SPI_PROTOCOL  PEI_SPI_PPI;
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/ActiveBios.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/ActiveBios.h
> new file mode 100644
> index 0000000000..4bd0523445
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/ActiveBios.h
> @@ -0,0 +1,123 @@
> +/**
> +**/
> +/**
> +
> +Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +  @file
> +  ActiveBios.h
> +
> +  @brief
> +  This protocol is used to report and control what BIOS is mapped to the
> +  BIOS address space anchored at 4GB boundary.
> +
> +  This protocol is EFI compatible.
> +
> +  E.G. For current generation ICH, the 4GB-16MB to 4GB range can be
> mapped
> +  to PCI, SPI, or FWH.
> +
> +**/
> +#ifndef _EFI_ACTIVE_BIOS_PROTOCOL_H_
> +#define _EFI_ACTIVE_BIOS_PROTOCOL_H_
> +
> +
> +
> +
> +//
> +#define EFI_ACTIVE_BIOS_PROTOCOL_GUID \
> +  { \
> +    0xebbe2d1b, 0x1647, 0x4bda, 0xab, 0x9a, 0x78, 0x63, 0xe3, 0x96, 0xd4,
> 0x1a \
> +  }
> +extern EFI_GUID                           gEfiActiveBiosProtocolGuid;
> +
> +///
> +/// Forward reference for ANSI C compatibility
> +///
> +typedef struct _EFI_ACTIVE_BIOS_PROTOCOL
> EFI_ACTIVE_BIOS_PROTOCOL;
> +
> +///
> +/// Protocol definitions
> +///
> +typedef enum {
> +  ActiveBiosStateSpi,
> +  ActiveBiosStatePci,   /// Obsolete since VLV
> +  ActiveBiosStateLpc,
> +  ActiveBiosStateMax
> +} EFI_ACTIVE_BIOS_STATE;
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ACTIVE_BIOS_SET_ACTIVE_BIOS_STATE) (
> +  IN EFI_ACTIVE_BIOS_PROTOCOL     * This,
> +  IN EFI_ACTIVE_BIOS_STATE        DesiredState,
> +  IN UINTN                        Key
> +  )
> +/**
> +
> +  @brief
> +  Change the current active BIOS settings to the requested state.
> +  The caller is responsible for requesting a supported state from
> +  the EFI_ACTIVE_BIOS_STATE selections.
> +  This will fail if someone has locked the interface and the correct key is
> +  not provided.
> +
> +  @param[in] This                 Pointer to the EFI_ACTIVE_BIOS_PROTOCOL
> instance.
> +  @param[in] DesiredState         The requested state to configure the system
> for.
> +  @param[in] Key                  If the interface is locked, Key must be the Key
> +                                  returned from the LockState function call.
> +
> +  @retval EFI_SUCCESS             The function completed successfully
> +  @retval EFI_ACCESS_DENIED       The interface is currently locked.
> +
> +**/
> +;
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ACTIVE_BIOS_LOCK_ACTIVE_BIOS_STATE) (
> +  IN     EFI_ACTIVE_BIOS_PROTOCOL   * This,
> +  IN     BOOLEAN                    Lock,
> +  IN OUT UINTN                      *Key
> +  );
> +
> +/**
> +
> +  @brief
> +  Lock the current active BIOS state from further changes.  This allows a
> +  caller to implement a critical section.  This is optionally supported
> +  functionality.  Size conscious implementations may choose to require
> +  callers cooperate without support from this protocol.
> +
> +  @param[in] This                 Pointer to the EFI_ACTIVE_BIOS_PROTOCOL
> instance.
> +  @param[in] Lock                 TRUE to lock the current state, FALSE to unlock.
> +  @param[in] Key                  If Lock is TRUE, then a key will be returned.  If
> +                                  Lock is FALSE, the key returned from the prior call
> +                                  to lock the protocol must be provided to unlock the
> +                                  protocol.  The value of Key is undefined except that
> +                                  it cannot be 0.
> +
> +  @retval EFI_SUCCESS             Command succeed.
> +  @exception EFI_UNSUPPORTED      The function is not supported.
> +  @retval EFI_ACCESS_DENIED       The interface is currently locked.
> +  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
> +
> +**/
> +
> +///
> +/// Protocol definition
> +///
> +/// Note that some functions are optional.  This means that they may be
> NULL.
> +/// Caller is required to verify that an optional function is defined by
> checking
> +/// that the value is not NULL.
> +///
> +struct _EFI_ACTIVE_BIOS_PROTOCOL {
> +  EFI_ACTIVE_BIOS_STATE                   State;
> +  EFI_ACTIVE_BIOS_SET_ACTIVE_BIOS_STATE   SetState;
> +  EFI_ACTIVE_BIOS_LOCK_ACTIVE_BIOS_STATE  LockState;
> +};
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/ActiveBiosProtocol.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/ActiveBiosProtocol.h
> new file mode 100644
> index 0000000000..a41e5831f1
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/ActiveBiosProtocol.h
> @@ -0,0 +1,125 @@
> +/**
> +  This protocol is used to report and control what BIOS is mapped to the
> +  BIOS address space anchored at 4GB boundary.
> +
> +  This protocol is EFI compatible.
> +
> +  E.G. For current generation ICH, the 4GB-16MB to 4GB range can be
> mapped
> +  to PCI, SPI, or FWH.
> +
> +Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +**/
> +
> +
> +#ifndef _EFI_ACTIVE_BIOS_PROTOCOL_H_
> +#define _EFI_ACTIVE_BIOS_PROTOCOL_H_
> +
> +//
> +// Define the  protocol GUID
> +//
> +#define EFI_ACTIVE_BIOS_PROTOCOL_GUID  \
> +  { 0xebbe2d1b, 0x1647, 0x4bda, {0xab, 0x9a, 0x78, 0x63, 0xe3, 0x96, 0xd4,
> 0x1a} }
> +
> +typedef struct _EFI_ACTIVE_BIOS_PROTOCOL
> EFI_ACTIVE_BIOS_PROTOCOL;
> +
> +//
> +// Protocol definitions
> +//
> +typedef enum {
> +  ActiveBiosStateSpi,
> +  ActiveBiosStatePci,
> +  ActiveBiosStateLpc,
> +  ActiveBiosStateMax
> +} EFI_ACTIVE_BIOS_STATE;
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ACTIVE_BIOS_SET_ACTIVE_BIOS_STATE) (
> +  IN EFI_ACTIVE_BIOS_PROTOCOL     *This,
> +  IN EFI_ACTIVE_BIOS_STATE        DesiredState,
> +  IN UINTN                        Key
> +  );
> +/*++
> +
> +Routine Description:
> +
> +  Change the current active BIOS settings to the requested state.
> +  The caller is responsible for requesting a supported state from
> +  the EFI_ACTIVE_BIOS_STATE selections.
> +
> +  This will fail if someone has locked the interface and the correct key is
> +  not provided.
> +
> +Arguments:
> +
> +  This                    Pointer to the EFI_ACTIVE_BIOS_PROTOCOL instance.
> +  DesiredState            The requested state to configure the system for.
> +  Key                     If the interface is locked, Key must be the Key
> +                          returned from the LockState function call.
> +
> +Returns:
> +
> +  EFI_SUCCESS             Command succeed.
> +  EFI_ACCESS_DENIED       The interface is currently locked.
> +  EFI_DEVICE_ERROR        Device error, command aborts abnormally.
> +
> +--*/
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ACTIVE_BIOS_LOCK_ACTIVE_BIOS_STATE) (
> +  IN     EFI_ACTIVE_BIOS_PROTOCOL   *This,
> +  IN     BOOLEAN                    Lock,
> +  IN OUT UINTN                      *Key
> +  );
> +/*++
> +
> +Routine Description:
> +
> +  Lock the current active BIOS state from further changes.  This allows a
> +  caller to implement a critical section.  This is optionally supported
> +  functionality.  Size conscious implementations may choose to require
> +  callers cooperate without support from this protocol.
> +
> +Arguments:
> +
> +  This                    Pointer to the EFI_ACTIVE_BIOS_PROTOCOL instance.
> +  Lock                    TRUE to lock the current state, FALSE to unlock.
> +  Key                     If Lock is TRUE, then a key will be returned.  If
> +                          Lock is FALSE, the key returned from the prior call
> +                          to lock the protocol must be provided to unlock the
> +                          protocol.  The value of Key is undefined except that it
> +                          will never be 0.
> +
> +Returns:
> +
> +  EFI_SUCCESS             Command succeed.
> +  EFI_UNSUPPORTED         The function is not supported.
> +  EFI_ACCESS_DENIED       The interface is currently locked.
> +  EFI_DEVICE_ERROR        Device error, command aborts abnormally.
> +
> +--*/
> +
> +//
> +// Protocol definition
> +//
> +// Note that some functions are optional.  This means that they may be
> NULL.
> +// Caller is required to verify that an optional function is defined by checking
> +// that the value is not NULL.
> +//
> +struct _EFI_ACTIVE_BIOS_PROTOCOL {
> +  EFI_ACTIVE_BIOS_STATE                       State;
> +  EFI_ACTIVE_BIOS_SET_ACTIVE_BIOS_STATE       SetState;
> +  EFI_ACTIVE_BIOS_LOCK_ACTIVE_BIOS_STATE      LockState;
> +};
> +
> +//
> +// Extern the GUID for protocol users.
> +//
> +extern EFI_GUID gEfiActiveBiosProtocolGuid;
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/DxePchPolicyUpdateProtocol.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/DxePchPolicyUpdateProtocol.h
> new file mode 100644
> index 0000000000..4e7140e868
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/DxePchPolicyUpdateProtocol.h
> @@ -0,0 +1,51 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  DxePchPolicyUpdateProtocol.h
> +
> +Abstract:
> +
> +  PCH policy update protocol. This protocol is consumed by the
> PchDxePolicyInit driver
> +
> +--*/
> +#ifndef _DXE_PCH_POLICY_UPDATE_PROTOCOL_H_
> +#define _DXE_PCH_POLICY_UPDATE_PROTOCOL_H_
> +
> +#include "PchRegs.h"
> +
> +
> +#ifdef ECP_FLAG
> +#define DXE_PCH_POLICY_UPDATE_PROTOCOL_GUID \
> +  { \
> +    0x1a819e49, 0xd8ee, 0x48cb, 0x9a, 0x9c, 0xa, 0xa0, 0xd2, 0x81, 0xa, 0x38 \
> +  }
> +#else
> +#define DXE_PCH_POLICY_UPDATE_PROTOCOL_GUID \
> +  { \
> +    0x1a819e49, 0xd8ee, 0x48cb, \
> +    { \
> +        0x9a, 0x9c, 0xa, 0xa0, 0xd2, 0x81, 0xa, 0x38 \
> +    } \
> +  }
> +#endif
> +
> +extern EFI_GUID                                   gDxePchPolicyUpdateProtocolGuid;
> +#define DXE_PCH_POLICY_UPDATE_PROTOCOL_REVISION_1 1
> +
> +//
> +// ------------ General PCH policy Update protocol definition ------------
> +//
> +struct _DXE_PCH_POLICY_UPDATE_PROTOCOL {
> +  UINT8                   Revision;
> +};
> +
> +typedef struct _DXE_PCH_POLICY_UPDATE_PROTOCOL
> DXE_PCH_POLICY_UPDATE_PROTOCOL;
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/EmmcCardInfoProtocol.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/EmmcCardInfoProtocol.h
> new file mode 100644
> index 0000000000..d92f227d5b
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/EmmcCardInfoProtocol.h
> @@ -0,0 +1,42 @@
> +/*++
> +
> +Copyright (c)  2013  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +--*/
> +
> +
> +/*++
> +Module Name:
> +
> +  EmmcCardInfoProtocol.h
> +
> +Abstract:
> +
> +  Interface definition for EFI_EMMC_CARD_INFO_PROTOCOL
> +
> +--*/
> +
> +
> +#ifndef _EMMC_CARD_INFO_H_
> +#define _EMMC_CARD_INFO_H_
> +
> +#define EFI_EMMC_CARD_INFO_PROTOCOL_GUID \
> +  { \
> +    0x1ebe5ab9, 0x2129, 0x49e7, {0x84, 0xd7, 0xee, 0xb9, 0xfc, 0xe5, 0xde,
> 0xdd } \
> +  }
> +
> +typedef struct _EFI_EMMC_CARD_INFO_PROTOCOL
> EFI_EMMC_CARD_INFO_PROTOCOL;
> +
> +
> +//
> +// EMMC Card info Structures
> +//
> +struct _EFI_EMMC_CARD_INFO_PROTOCOL {
> +  CARD_DATA *CardData;
> +};
> +
> +extern EFI_GUID gEfiEmmcCardInfoProtocolGuid;
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/Gpio.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/Gpio.h
> new file mode 100644
> index 0000000000..3f7260e0bf
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/Gpio.h
> @@ -0,0 +1,161 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  Gpio.h
> +
> +Abstract:
> +
> +EFI 2.0 PEIM to provide platform specific information to other
> +modules and to do some platform specific initialization.
> +
> +--*/
> +
> +#ifndef _PEI_GPIO_H
> +#define _PEI_GPIO_H
> +
> +//#include "Efi.h"
> +//#include "EfiCommonLib.h"
> +//#include "Pei.h"
> +//#include "Numbers.h"
> +
> +////
> +//// GPIO Register Settings for BeaverBridge (FFVS) (Cedarview/Tigerpoint)
> +////
> +//// Field Descriptions:
> +////    USE: Defines the pin's usage model:  GPIO (G) or Native (N) mode.
> +////    I/O: Defines whether GPIOs are inputs (I) or outputs (O).
> +////         (Note:  Only meaningful for pins used as GPIOs.)
> +////    LVL: This field gives you the initial value for "output" GPIO's.
> +////         (Note: The output level is dependent upon whether the pin is
> inverted.)
> +////    INV: Defines whether Input GPIOs activation level is inverted.
> +////         (Note:  Only affects the level sent to the GPE logic and does not
> +////         affect the level read through the GPIO registers.)
> +////
> +//// Notes:
> +////    1. BoardID is GPIO [8:38:34]
> +////
> +////Signal         UsedAs               USE     I/O      LVL     INV
> +////--------------------------------------------------------------------------
> +////GPIO0           Nonfunction       G     O            H       -
> +////GPIO1           SMC_RUNTIME_SCI#    G        I           -       I
> +////PIRQE#/GPIO2    Nonfunction G   O   H   -
> +////PIRQF#/GPIO3    Nonfunction G   O   H   -
> +////PIRQG#/GPIO4    Nonfunction G   O   H   -
> +////PIRQH#/GPIO5    Nonfunction G   O   H   -
> +////GPIO6   unused  G   O   L   -
> +////GPIO7   unused  G   O   L   -
> +////GPIO8          BOARD ID2    G   I   -   -
> +////GPIO9   unused  G   O   L   -
> +////GPIO10  SMC_EXTSMI# G   I   -   I
> +////GPIO11  Nonfunction G   O   H   -
> +////GPIO12  unused  G   O   L   -
> +////GPIO13  SMC_WAKE_SCI#   G   I   -   I
> +////GPIO14  unused  G   O   L   -
> +////GPIO15  unused  G   O   L   -
> +////GPIO16  PM_DPRSLPVR N   -   -   -
> +////GNT5#/GPIO17    GNT5#   N   -   -   -
> +////STPPCI#/GPIO18  PM_STPPCI#  N   -   -   -
> +////STPCPU#/GPIO20  PM_STPCPU#  N   -   -   -
> +////GPIO22  CRT_RefClk  G   I   -   -
> +////GPIO23  unused  G   O   L   -
> +////GPIO24  unused  G   O   L   -
> +////GPIO25  DMI strap   G   O   L   -
> +////GPIO26  unused  G   O   L   -
> +////GPIO27  unused  G   O   L   -
> +////GPIO28  RF_KILL#    G   O   H   -
> +////OC5#/GPIO29 OC  N   -   -   -
> +////OC6#/GPIO30 OC  N   -   -   -
> +////OC7#/GPIO31 OC  N   -   -   -
> +////CLKRUN#/GPIO32  PM_CLKRUN#  N   -   -   -
> +////GPIO33  NC  G   O   L   -
> +////GPIO34  BOARD ID0   G   I   -   -
> +////GPIO36  unused  G   O   L   -
> +////GPIO38  BOARD ID1   G   I   -   -
> +////GPIO39  unused  G   O   L   -
> +////GPIO48  unused  G   O   L   -
> +////CPUPWRGD/GPIO49 H_PWRGD N   -   -   -
> +//
> +//#define   GPIO_USE_SEL_VAL              0x1FC0FFFF       //GPIO1, 10, 13 is EC
> signal
> +//#define   GPIO_USE_SEL2_VAL             0x000100D6
> +//#define   GPIO_IO_SEL_VAL               0x00402502
> +//#define   GPIO_IO_SEL2_VAL              0x00000044
> +//#define   GPIO_LVL_VAL                  0x1800083D
> +//#define   GPIO_LVL2_VAL                 0x00000000
> +//#define   GPIO_INV_VAL                  0x00002402
> +//#define   GPIO_BLNK_VAL                 0x00000000
> +//#define   ICH_GPI_ROUTE (ICH_GPI_ROUTE_SCI(13) |
> ICH_GPI_ROUTE_SCI(1))
> +
> +//
> +// GPIO Register Settings for CedarRock and CedarFalls platforms
> +//
> +//      GPIO Register Settings for NB10_CRB
> +//---------------------------------------------------------------------------------
> +//Signal        Used As         USE         I/O     LVL
> +//---------------------------------------------------------------------------------
> +//
> +// GPIO0    FP_AUDIO_DETECT     G       I
> +// GPIO1    SMC_RUNTIME_SCI#    G       I
> +// GPIO2        INT_PIRQE_N     N       I
> +// GPIO3    INT_PIRQF_N     N       I
> +// GPIO4        INT_PIRQG_N     N       I
> +// GPIO5        INT_PIRQH_N     N       I
> +// GPIO6
> +// GPIO7
> +// GPIO8
> +// GPIO9    LPC_SIO_PME     G       I
> +// GPIO10   SMC_EXTSMI_N        G       I
> +// GPIO11   SMBALERT- pullup    N
> +// GPIO12   ICH_GP12        G       I
> +// GPIO13   SMC_WAKE_SCI_N      G       I
> +// GPIO14   LCD_PID0        G       O       H
> +// GPIO15   CONFIG_MODE_N       G       I
> +// GPIO16       PM_DPRSLPVR     N
> +// GPIO17   SPI_SELECT_STRAP1
> +//          /L_BKLTSEL0_N   G       I
> +// GPIO18   PM_STPPCI_N     N
> +// GPIO19
> +// GPIO20   PM_STPCPU_N     N
> +// GPIO21
> +// GPIO22   REQ4B           G       I
> +// GPIO23   L_DRQ1_N        N
> +// GPIO24   CRB_SV_DET_N        G       O       H
> +// GPIO25   DMI strap
> +//          / L_BKLTSEL1_N  G       O       H
> +// GPIO26   LCD_PID1        G       O       H
> +// GPIO27   TPEV_DDR3L_DETECT   G       O       H
> +// GPIO28   RF_KILL         G       O       H:enable
> +// GPIO29   OC          N
> +// GPIO30   OC          N
> +// GPIO31   OC          N
> +// GPIO32   PM_CLKRUN_N     Native
> +// GPIO33   MFG_MODE_N      G       I
> +// GPIO34   BOARD ID0       G       I
> +// GPIO35
> +// GPIO36   SV_SET_UP       G       O       H
> +// GPIO37
> +// GPIO38   BOARD ID1       G       I
> +// GPIO39   BOARD ID2       G       I
> +// GPIO48   FLASH_SEL0      N
> +// GPIO49   H_PWRGD         N
> +
> +#define ICH_GPI_ROUTE_SMI(Gpio)          ((( 0 << ((Gpio * 2) + 1)) | (1 <<
> (Gpio * 2))))
> +#define ICH_GPI_ROUTE_SCI(Gpio)          ((( 1 << ((Gpio * 2) + 1)) | (0 <<
> (Gpio * 2))))
> +
> +#define   GPIO_USE_SEL_VAL              0X1F42F7C3
> +#define   GPIO_USE_SEL2_VAL             0X000000D6
> +#define   GPIO_IO_SEL_VAL               0X1042B73F
> +#define   GPIO_IO_SEL2_VAL              0X000100C6
> +#define   GPIO_LVL_VAL                  0X1F15F601
> +#define   GPIO_LVL2_VAL                 0X000200D7
> +#define   GPIO_INV_VAL                  0x00002602
> +#define   GPIO_BLNK_VAL                 0x00040000
> +#define   ICH_GPI_ROUTE (ICH_GPI_ROUTE_SCI(13) |
> ICH_GPI_ROUTE_SCI(1))
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/HwWatchdogTimer.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/HwWatchdogTimer.h
> new file mode 100644
> index 0000000000..592ac285ea
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/HwWatchdogTimer.h
> @@ -0,0 +1,294 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  HwWatchdogTimer.h
> +
> +Abstract:
> +
> +
> +--*/
> +
> +#ifndef __EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL_H__
> +#define __EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL_H__
> +
> +#define EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL_GUID \
> +  { 0xd5b06d16, 0x2ea1, 0x4def, 0x98, 0xd0, 0xa0, 0x5d, 0x40, 0x72, 0x84,
> 0x17 }
> +
> +#define EFI_WATCHDOG_TIMER_NOT_SUPPORTED_PROTOCOL_GUID \
> +  { 0xe9e156ac, 0x3203, 0x4572, 0xac, 0xdf, 0x84, 0x4f, 0xdc, 0xdb, 0x6, 0xbf }
> +
> +
> +#include <Guid/HwWatchdogTimerHob.h>
> +
> +//
> +// General Purpose Constants
> +//
> +#define ICH_INSTAFLUSH_GPIO      BIT16 // BIT 16 in GPIO Level 2 is GPIO 48.
> +#define B_INSTAFLUSH             BIT4
> +//
> +// Other Watchdog timer values
> +//
> +#define WDT_COUNTDOWN_VALUE                 0x14
> +#define BDS_WDT_COUNTDOWN_VALUE             0x35
> +
> +
> +//
> +// Prototypes for the Watchdog Timer Driver Protocol
> +//
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_WATCHDOG_START_TIMER) (
> +  VOID
> +  );
> +/*++
> +
> +  Routine Description:
> +    This service begins the Watchdog Timer countdown.  If the countdown
> completes prior to
> +    Stop Timer or Restart Timer the system will reset.
> +
> +  Arguments:
> +    None
> +
> +  Returns:
> +    EFI_SUCCESS       - Operation completed successfully
> +    EFI_DEVICE_ERROR  - The command was unsuccessful
> +
> +--*/
> +
> +
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_WATCHDOG_RESET_TIMER) (
> +  VOID
> +  );
> +/*++
> +
> +  Routine Description:
> +    This service resets the Watchdog Timer countdown and should only be
> called after the
> +    Start Timer function.
> +
> +  Arguments:
> +    None
> +
> +  Returns:
> +    EFI_SUCCESS       - Operation completed successfully
> +    EFI_DEVICE_ERROR  - The command was unsuccessful
> +
> +--*/
> +
> +
> +
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_WATCHDOG_RESTART_TIMER) (
> +  VOID
> +  );
> +/*++
> +
> +  Routine Description:
> +    This service restarts the Watchdog Timer countdown and should only be
> called after the
> +    Start Timer function.
> +
> +  Arguments:
> +    None
> +
> +  Returns:
> +    EFI_SUCCESS       - Operation completed successfully
> +    EFI_DEVICE_ERROR  - The command was unsuccessful
> +
> +--*/
> +
> +
> +
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_WATCHDOG_STOP_TIMER) (
> +  VOID
> +  );
> +/*++
> +
> +  Routine Description:
> +    This service disables the Watchdog Timer countdown.
> +
> +  Arguments:
> +    None
> +
> +  Returns:
> +    EFI_SUCCESS       - Operation completed successfully
> +    EFI_DEVICE_ERROR  - The command was unsuccessful
> +
> +--*/
> +
> +
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_WATCHDOG_CHECK_TIMEOUT) (
> +  OUT HW_WATCHDOG_TIMEOUT       *WatchdogTimeout
> +  );
> +/*++
> +
> +  Routine Description:
> +    This service disables the Watchdog Timer countdown.
> +
> +  Arguments:
> +    None
> +
> +  Returns:
> +    EFI_SUCCESS       - Operation completed successfully
> +    EFI_DEVICE_ERROR  - The command was unsuccessful
> +
> +--*/
> +
> +
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_WATCHDOG_FORCE_REBOOT) (
> +  IN BOOLEAN                    ForceTimeout,
> +  IN UINT8                      ResetType
> +  );
> +/*++
> +
> +  Routine Description:
> +    This service forces a reboot of the system due to a reset of the
> POWERGOOD_PS,
> +    POWERGOOD_CLK, and the BSEL Override
> +
> +  Arguments:
> +    None
> +
> +  Returns:
> +    This function should not return!
> +
> +    EFI_DEVICE_ERROR  - The command was unsuccessful and a reboot did
> not occur
> +
> +--*/
> +
> +
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_WATCHDOG_KNOWN_RESET) (
> +  IN BOOLEAN                    AllowReset
> +  );
> +/*++
> +
> +  Routine Description:
> +    This service notifies the Watchdog Timer of the fact that a known reset is
> occuring.
> +
> +  Arguments:
> +    AllowReset -  TRUE if a Reset is currently expected
> +                  FALSE if a Reset is not currently expected
> +
> +  Returns:
> +    This function should not return!
> +
> +    EFI_DEVICE_ERROR  - The command was unsuccessful and a reboot did
> not occur
> +
> +--*/
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_GET_TIMER_COUNT_DOWN_PERIOD)(
> +  OUT UINT32      *CountdownValue
> +  );
> +/*++
> +
> +  Routine Description:
> +    This service reads the current Watchdog Timer countdown reload value.
> +
> +  Arguments:
> +    CountdownValue - pointer to UINT32 to return the value of the reload
> register.
> +
> +  Returns:
> +    EFI_SUCCESS       - Operation completed successfully
> +    EFI_DEVICE_ERROR  - The command was unsuccessful
> +
> +--*/
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SET_TIMER_COUNT_DOWN_PERIOD)(
> +  OUT UINT32      CountdownValue
> +  );
> +/*++
> +
> +  Routine Description:
> +    This service reads the current Watchdog Timer countdown reload value.
> +
> +  Arguments:
> +    CountdownValue - Value to set the reload register.
> +
> +  Returns:
> +    EFI_SUCCESS       - Operation completed successfully
> +    EFI_DEVICE_ERROR  - The command was unsuccessful
> +
> +--*/
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_WATCHDOG_CLEAR_TIMER_STATE) (
> +  );
> +/*++
> +
> +  Routine Description:
> +    This service clears the state that indicates the Watchdog Timer fired.
> +
> +  Arguments:
> +
> +  Returns:
> +    EFI_SUCCESS       - Operation completed successfully
> +    EFI_DEVICE_ERROR  - The command was unsuccessful
> +
> +--*/
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_STALL_WATCHDOG_COUNTDOWN) (
> +  IN BOOLEAN Stall
> +  );
> +/*++
> +
> +  Routine Description:
> +    This service disables the Watchdog Timer countdown.  It also closes the
> recurring restart event
> +    if the event exists.
> +
> +  Arguments:
> +    Stall - TRUE = Stop the timer countdown
> +            FALSE = Start the timer countdown
> +
> +  Returns:
> +    EFI_SUCCESS       - Operation completed successfully
> +    EFI_DEVICE_ERROR  - The command was unsuccessful
> +
> +--*/
> +
> +typedef struct _EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL {
> +  EFI_WATCHDOG_START_TIMER                      StartWatchdogTimer;
> +  PEI_WATCHDOG_RESET_TIMER                      ResetWatchdogTimeout;
> +  EFI_WATCHDOG_RESTART_TIMER                    RestartWatchdogTimer;
> +  EFI_WATCHDOG_STOP_TIMER                       StopWatchdogTimer;
> +  EFI_WATCHDOG_CHECK_TIMEOUT                    CheckWatchdogTimeout;
> +  EFI_WATCHDOG_FORCE_REBOOT                     ForceReboot;
> +  EFI_WATCHDOG_KNOWN_RESET                      AllowKnownReset;
> +  EFI_GET_TIMER_COUNT_DOWN_PERIOD               GetCountdownPeriod;
> +  EFI_SET_TIMER_COUNT_DOWN_PERIOD               SetCountdownPeriod;
> +  PEI_WATCHDOG_CLEAR_TIMER_STATE                ClearTimerState;
> +  EFI_STALL_WATCHDOG_COUNTDOWN                  StallWatchdogCountdown;
> +} EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL;
> +
> +extern EFI_GUID gEfiWatchdogTimerDriverProtocolGuid;
> +extern EFI_GUID gEfiWatchdogTimerNotSupportedProtocolGuid;
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/I2cBus.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/I2cBus.h
> new file mode 100644
> index 0000000000..0fccaa0786
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/I2cBus.h
> @@ -0,0 +1,164 @@
> +/** @file
> +  I2C bus interface
> +
> +  This layer provides I/O access to an I2C device.
> +
> +  Copyright (c) 2012, Intel Corporation. All rights reserved.
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef __I2C_BUS_H__
> +#define __I2C_BUS_H__
> +
> +#include <Protocol/I2cHostMcg.h>
> +
> +///
> +/// I2C bus protocol
> +///
> +typedef struct _EFI_I2C_BUS_PROTOCOL  EFI_I2C_BUS_PROTOCOL;
> +
> +
> +/**
> +  Perform an I2C operation on the device
> +
> +  This routine must be called at or below TPL_NOTIFY.  For synchronous
> +  requests this routine must be called at or below TPL_CALLBACK.
> +
> +  N.B. The typical consumers of this API are the third party I2C
> +  drivers.  Extreme care must be taken by other consumers of this
> +  API to prevent confusing the third party I2C drivers due to a
> +  state change at the I2C device which the third party I2C drivers
> +  did not initiate.  I2C platform drivers may use this API within
> +  these guidelines.
> +
> +  This routine queues an operation to the I2C controller for execution
> +  on the I2C bus.
> +
> +  As an upper layer driver writer, the following need to be provided
> +  to the platform vendor:
> +
> +  1.  ACPI CID value or string - this is used to connect the upper layer
> +      driver to the device.
> +  2.  Slave address array guidance when the I2C device uses more than one
> +      slave address.  This is used to access the blocks of hardware within
> +      the I2C device.
> +
> +  @param[in] This               Address of an EFI_I2C_BUS_PROTOCOL
> +                                structure
> +  @param[in] SlaveAddressIndex  Index into an array of slave addresses for
> +                                the I2C device.  The values in the array are
> +                                specified by the board designer, with the
> +                                I2C device driver writer providing the slave
> +                                address order.
> +
> +                                For devices that have a single slave address,
> +                                this value must be zero.  If the I2C device
> +                                uses more than one slave address then the third
> +                                party (upper level) I2C driver writer needs to
> +                                specify the order of entries in the slave address
> +                                array.
> +
> +                                \ref ThirdPartyI2cDrivers "Third Party I2C Drivers"
> +                                section in I2cMaster.h.
> +  @param[in] Event              Event to set for asynchronous operations,
> +                                NULL for synchronous operations
> +  @param[in] RequestPacket      Address of an EFI_I2C_REQUEST_PACKET
> +                                structure describing the I2C operation
> +  @param[out] I2cStatus         Optional buffer to receive the I2C operation
> +                                completion status
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval EFI_ABORTED           The request did not complete because the
> driver
> +                                was shutdown.
> +  @retval EFI_ACCESS_DENIED     Invalid SlaveAddressIndex value
> +  @retval EFI_BAD_BUFFER_SIZE   The WriteBytes or ReadBytes buffer size
> is too large.
> +  @retval EFI_DEVICE_ERROR      There was an I2C error (NACK) during the
> operation.
> +                                This could indicate the slave device is not present.
> +  @retval EFI_INVALID_PARAMETER RequestPacket is NULL
> +  @retval EFI_INVALID_PARAMETER TPL is too high
> +  @retval EFI_NO_RESPONSE       The I2C device is not responding to the
> +                                slave address.  EFI_DEVICE_ERROR may also be
> +                                returned if the controller can not distinguish
> +                                when the NACK occurred.
> +  @retval EFI_NOT_FOUND         I2C slave address exceeds maximum
> address
> +  @retval EFI_NOT_READY         I2C bus is busy or operation pending, wait for
> +                                the event and then read status pointed to by
> +                                the request packet.
> +  @retval EFI_OUT_OF_RESOURCES  Insufficient memory for I2C operation
> +  @retval EFI_TIMEOUT           The transaction did not complete within an
> internally
> +                                specified timeout period.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_I2C_BUS_START_REQUEST) (
> +  IN CONST EFI_I2C_BUS_PROTOCOL *This,
> +  IN UINTN SlaveAddressIndex,
> +  IN EFI_EVENT Event OPTIONAL,
> +  IN CONST EFI_I2C_REQUEST_PACKET *RequestPacket,
> +  OUT EFI_STATUS *I2cStatus OPTIONAL
> +  );
> +
> +///
> +/// The I2C bus protocol enables access to a specific device on the I2C bus.
> +///
> +/// Each I2C device is described as an ACPI node (HID, UID and CID) within
> the
> +/// platform layer.  The I2C bus protocol enumerates the I2C devices in the
> +/// platform and creates a unique handle and device path for each I2C
> device.
> +///
> +/// I2C slave addressing is abstracted to validate addresses and limit
> operation
> +/// to the specified I2C device.  The third party providing the I2C device
> support
> +/// provides an ordered list of slave addresses for the I2C device to the
> team
> +/// building the platform layer.  The platform team must preserve the order
> of the
> +/// supplied list.  SlaveAddressCount is the number of entries in this list or
> +/// array within the platform layer.  The third party device support
> references
> +/// a slave address using an index into the list or array in the range of zero
> +/// to SlaveAddressCount - 1.
> +///
> +struct _EFI_I2C_BUS_PROTOCOL {
> +  ///
> +  /// Start an I2C operation on the bus
> +  ///
> +  EFI_I2C_BUS_START_REQUEST StartRequest;
> +
> +  ///
> +  /// The maximum number of slave addresses for the I2C device.  The caller
> may
> +  /// validate this value as a check on the platform layer's configuration.
> Slave
> +  /// address selection uses an index value in the range of zero to
> SlaveAddressCount - 1.
> +  ///
> +  UINTN SlaveAddressCount;
> +
> +  ///
> +  /// Hardware revision - Matches the ACPI _HRV value
> +  ///
> +  /// The HardwareRevision value allows a single driver to support multiple
> hardware
> +  /// revisions and implement the necessary workarounds for limitations
> within the
> +  /// hardware.
> +  ///
> +  UINT32 HardwareRevision;
> +
> +  ///
> +  /// The maximum number of bytes the I2C host controller
> +  /// is able to receive from the I2C bus.
> +  ///
> +  UINT32 MaximumReceiveBytes;
> +
> +  ///
> +  /// The maximum number of bytes the I2C host controller
> +  /// is able to send on the I2C bus.
> +  ///
> +  UINT32 MaximumTransmitBytes;
> +
> +  ///
> +  /// The maximum number of bytes in the I2C bus transaction.
> +  ///
> +  UINT32 MaximumTotalBytes;
> +};
> +
> +///
> +/// GUID for the I2C bus protocol
> +///
> +extern EFI_GUID gEfiI2cBusProtocolGuid;
> +
> +#endif  //  __I2C_BUS_H__
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/PchExtendedReset.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/PchExtendedReset.h
> new file mode 100644
> index 0000000000..ef7975b033
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/PchExtendedReset.h
> @@ -0,0 +1,84 @@
> +/*++
> +
> +Copyright (c) 2008  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  PchExtendedReset.h
> +
> +Abstract:
> +
> +  PCH Extended Reset Protocol
> +
> +--*/
> +#ifndef _EFI_PCH_EXTENDED_RESET_H_
> +#define _EFI_PCH_EXTENDED_RESET_H_
> +
> +
> +
> +//
> +#define EFI_PCH_EXTENDED_RESET_PROTOCOL_GUID \
> +  { \
> +    0xf0bbfca0, 0x684e, 0x48b3, 0xba, 0xe2, 0x6c, 0x84, 0xb8, 0x9e, 0x53, 0x39
> \
> +  }
> +extern EFI_GUID                                 gEfiPchExtendedResetProtocolGuid;
> +
> +//
> +// Forward reference for ANSI C compatibility
> +//
> +typedef struct _EFI_PCH_EXTENDED_RESET_PROTOCOL
> EFI_PCH_EXTENDED_RESET_PROTOCOL;
> +
> +//
> +// Related Definitions
> +//
> +//
> +// PCH Extended Reset Types
> +//
> +typedef struct {
> +  UINT8 PowerCycle  : 1;  // 0: Disabled*; 1: Enabled
> +  UINT8 GlobalReset : 1;  // 0: Disabled*; 1: Enabled
> +  UINT8 SusPwrDnAck : 1;  // 0: Do Nothing;
> +  // 1: GPIO[30](SUS_PWR_DN_ACK) level is set low prior to Global
> Reset(for systems with an embedded controller)
> +  UINT8 RsvdBits : 5;     // Reserved fields for future expansion w/o protocol
> change
> +} PCH_EXTENDED_RESET_TYPES;
> +
> +//
> +// Member functions
> +//
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_PCH_EXTENDED_RESET) (
> +  IN     EFI_PCH_EXTENDED_RESET_PROTOCOL   * This,
> +  IN     PCH_EXTENDED_RESET_TYPES          PchExtendedResetTypes
> +  );
> +
> +/*++
> +
> +Routine Description:
> +
> +  Execute Pch Extended Reset from the host controller.
> +
> +Arguments:
> +
> +  This                    - Pointer to the EFI_PCH_EXTENDED_RESET_PROTOCOL
> instance.
> +  PchExtendedResetTypes   - Pch Extended Reset Types which includes
> PowerCycle, Globalreset.
> +
> +Returns:
> +
> +  Does not return if the reset takes place.
> +  EFI_INVALID_PARAMETER   - If ResetType is invalid.
> +
> +--*/
> +
> +//
> +// Interface structure for the Pch Extended Reset Protocol
> +//
> +struct _EFI_PCH_EXTENDED_RESET_PROTOCOL {
> +  EFI_PCH_EXTENDED_RESET  Reset;
> +};
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/PchInfo.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/PchInfo.h
> new file mode 100644
> index 0000000000..22e25c27fa
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/PchInfo.h
> @@ -0,0 +1,60 @@
> +/**
> +**/
> +/**
> +
> +Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +  @file
> +  PchInfo.h
> +
> +  @brief
> +  This file defines the PCH Info Protocol.
> +
> +**/
> +#ifndef _PCH_INFO_H_
> +#define _PCH_INFO_H_
> +
> +
> +#define EFI_PCH_INFO_PROTOCOL_GUID \
> +  { \
> +    0xd31f0400, 0x7d16, 0x4316, 0xbf, 0x88, 0x60, 0x65, 0x88, 0x3b, 0x40, 0x2b
> \
> +  }
> +extern EFI_GUID                       gEfiPchInfoProtocolGuid;
> +
> +///
> +/// Forward reference for ANSI C compatibility
> +///
> +typedef struct _EFI_PCH_INFO_PROTOCOL EFI_PCH_INFO_PROTOCOL;
> +
> +///
> +/// Protocol revision number
> +/// Any backwards compatible changes to this protocol will result in an
> update in the revision number
> +/// Major changes will require publication of a new protocol
> +///
> +/// Revision 1:  Original version
> +///
> +#define PCH_INFO_PROTOCOL_REVISION_1  1
> +#define PCH_INFO_PROTOCOL_REVISION_2  2
> +
> +///
> +/// RCVersion[7:0] is the release number.
> +/// For example:
> +/// VlvFramework 0.6.0-01 should be 00 06 00 01 (0x00060001)
> +/// VlvFramework 0.6.2    should be 00 06 02 00 (0x00060200)
> +///
> +#define PCH_RC_VERSION                0x01000000
> +
> +///
> +/// Protocol definition
> +///
> +struct _EFI_PCH_INFO_PROTOCOL {
> +  UINT8   Revision;
> +  UINT8   BusNumber;
> +  UINT32  RCVersion;
> +};
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/PchPlatformPolicy.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/PchPlatformPolicy.h
> new file mode 100644
> index 0000000000..79845d646d
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/PchPlatformPolicy.h
> @@ -0,0 +1,550 @@
> +/**
> +**/
> +/**
> +
> +Copyright (c) 2013  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +  @file
> +  PchPlatformPolicy.h
> +
> +  @brief
> +  PCH policy protocol produced by a platform driver specifying various
> +  expected PCH settings. This protocol is consumed by the PCH drivers.
> +
> +**/
> +#ifndef _PCH_PLATFORM_POLICY_H_
> +#define _PCH_PLATFORM_POLICY_H_
> +
> +
> +//
> +#include "PchRegs.h"
> +#ifndef ECP_FLAG
> +#include "Uefi.h"
> +#endif
> +
> +#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_GUID \
> +  { \
> +    0x4b0165a9, 0x61d6, 0x4e23, 0xa0, 0xb5, 0x3e, 0xc7, 0x9c, 0x2e, 0x30,
> 0xd5 \
> +  }
> +extern EFI_GUID                                   gDxePchPlatformPolicyProtocolGuid;
> +
> +///
> +/// Forward reference for ANSI C compatibility
> +///
> +typedef struct _DXE_PCH_PLATFORM_POLICY_PROTOCOL
> DXE_PCH_PLATFORM_POLICY_PROTOCOL;
> +
> +///
> +/// Protocol revision number
> +/// Any backwards compatible changes to this protocol will result in an
> update in the revision number
> +/// Major changes will require publication of a new protocol
> +///
> +/// Revision 1: Original version
> +///
> +#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_1 1
> +#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_2 2
> +#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_3 3
> +#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_4 4
> +#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_5 5
> +#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_6 6
> +#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_7 7
> +#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_8 8
> +#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_9 9
> +#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_10 10
> +#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_11 11
> +#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_12 12
> +
> +///
> +/// Generic definitions for device enabling/disabling used by PCH code.
> +///
> +#define PCH_DEVICE_ENABLE   1
> +#define PCH_DEVICE_DISABLE  0
> +
> +///
> +/// ---------------------------- Device Enabling ------------------------------
> +///
> +/// PCH Device enablings
> +///
> +typedef struct {
> +  UINT8 Lan               : 1;    /// 0: Disable; 1: Enable
> +  UINT8 Azalia            : 2;    /// 0: Disable; 1: Enable; 2: Auto
> +  UINT8 Sata              : 1;    /// 0: Disable; 1: Enable
> +  UINT8 Smbus             : 1;    /// 0: Disable; 1: Enable
> +  UINT8 LpeEnabled        : 2;    /// 0: Disabled; 1: PCI Mode 2: ACPI Mode
> +  UINT8 Reserved[1];              /// Reserved fields for future expansion w/o
> protocol change
> +} PCH_DEVICE_ENABLING;
> +
> +///
> +/// ---------------------------- USB Config -----------------------------
> +///
> +///
> +/// Overcurrent pins
> +///
> +typedef enum {
> +  PchUsbOverCurrentPin0 = 0,
> +  PchUsbOverCurrentPin1,
> +  PchUsbOverCurrentPin2,
> +  PchUsbOverCurrentPin3,
> +  PchUsbOverCurrentPin4,
> +  PchUsbOverCurrentPin5,
> +  PchUsbOverCurrentPin6,
> +  PchUsbOverCurrentPin7,
> +  PchUsbOverCurrentPinSkip,
> +  PchUsbOverCurrentPinMax
> +} PCH_USB_OVERCURRENT_PIN;
> +
> +typedef struct {
> +  UINT8   Enable            : 1;    /// 0: Disable; 1: Enable. This would take effect
> while UsbPerPortCtl is enabled
> +  UINT8   Panel             : 1;    /// 0: Back Panel Port; 1: Front Panel Port.
> +  UINT8   Dock              : 1;    /// 0: Not docking port; 1: Docking Port.
> +  UINT8   Rsvdbits          : 5;
> +} PCH_USB_PORT_SETTINGS;
> +
> +typedef struct {
> +  UINT8 Enable              : 1;    /// 0: Disable; 1: Enable
> +  UINT8 Rsvdbits            : 7;
> +} PCH_USB20_CONTROLLER_SETTINGS;
> +
> +typedef struct {
> +  UINT8 Enable              : 2;    /// 0: 0: Disabled; 1: PCI Mode 2: ACPI Mode
> +  UINT8 Rsvdbits            : 6;
> +} PCH_USBOTG_CONTROLLER_SETTINGS;
> +
> +#define PCH_XHCI_MODE_OFF         0
> +#define PCH_XHCI_MODE_ON          1
> +#define PCH_XHCI_MODE_AUTO        2
> +#define PCH_XHCI_MODE_SMARTAUTO   3
> +
> +#define PCH_EHCI_DEBUG_OFF        0
> +#define PCH_EHCI_DEBUG_ON         1
> +
> +#define PCH_USB_FRONT_PANEL       1
> +#define PCH_USB_BACK_PANEL        0
> +
> +typedef struct {
> +  UINT8 Mode               : 2;    /// 0: Disable; 1: Enable, 2: Auto, 3: Smart Auto
> +  UINT8 PreBootSupport     : 1;    /// 0: No xHCI driver available; 1: xHCI driver
> available
> +  UINT8 XhciStreams        : 1;    /// 0: Disable; 1: Enable
> +  UINT8 Rsvdbits           : 4;
> +} PCH_USB30_CONTROLLER_SETTINGS;
> +
> +typedef struct {
> +  UINT8 UsbPerPortCtl       : 1;    /// 0: Disable; 1: Enable Per-port enable
> control
> +  UINT8 Ehci1Usbr           : 1;    /// 0: Disable; 1: Enable EHCI 1 USBR
> +  UINT8 RsvdBits            : 6;
> +  PCH_USB_PORT_SETTINGS
> PortSettings[PCH_USB_MAX_PHYSICAL_PORTS];
> +  PCH_USB20_CONTROLLER_SETTINGS
> Usb20Settings[PchEhciControllerMax];
> +  PCH_USB30_CONTROLLER_SETTINGS  Usb30Settings;
> +  PCH_USBOTG_CONTROLLER_SETTINGS UsbOtgSettings;
> +  PCH_USB_OVERCURRENT_PIN
> Usb20OverCurrentPins[PCH_USB_MAX_PHYSICAL_PORTS];
> +  PCH_USB_OVERCURRENT_PIN
> Usb30OverCurrentPins[PCH_XHCI_MAX_USB3_PORTS];
> +  ///
> +  /// The length of Usb Port to configure the USB transmitter,
> +  /// Bits [16:4] represents length of Usb Port in inches using octal format
> and [3:0] is for the decimal Point.
> +  ///
> +  UINT16                        Usb20PortLength[PCH_EHCI_MAX_PORTS];
> +  UINT16                        EhciDebug;
> +  UINT16                        UsbXhciLpmSupport;
> +
> +} PCH_USB_CONFIG;
> +
> +///
> +/// ---------------------------- PCI Express Config ----------------------
> +///
> +/// The values before AutoConfig match the setting of PCI Express Base
> Specification 1.1, please be careful for adding new feature
> +///
> +typedef enum {
> +  PchPcieAspmDisabled,
> +  PchPcieAspmL0s,
> +  PchPcieAspmL1,
> +  PchPcieAspmL0sL1,
> +  PchPcieAspmAutoConfig,
> +  PchPcieAspmMax
> +} PCH_PCI_EXPRESS_ASPM_CONTROL;
> +
> +///
> +/// Refer to PCH EDS for the PCH implementation values corresponding
> +/// to below PCI-E spec defined ranges
> +///
> +typedef enum {
> +  PchPciECompletionTO_Default,
> +  PchPciECompletionTO_50_100us,
> +  PchPciECompletionTO_1_10ms,
> +  PchPciECompletionTO_16_55ms,
> +  PchPciECompletionTO_65_210ms,
> +  PchPciECompletionTO_260_900ms,
> +  PchPciECompletionTO_1_3P5s,
> +  PchPciECompletionTO_4_13s,
> +  PchPciECompletionTO_17_64s,
> +  PchPciECompletionTO_Disabled
> +} PCH_PCIE_COMPLETION_TIMEOUT;
> +
> +typedef struct {
> +  UINT8 Enable                          : 1;    /// Root Port enabling, 0: Disable; 1: Enable.
> +  UINT8 Hide                            : 1;    /// Whether or not to hide the configuration
> space of this port
> +  UINT8 SlotImplemented                 : 1;
> +  UINT8 HotPlug                         : 1;
> +  UINT8 PmSci                           : 1;
> +  UINT8 ExtSync                         : 1;    /// Extended Synch
> +  UINT8 Rsvdbits                        : 2;
> +  ///
> +  /// Error handlings
> +  ///
> +  UINT8 UnsupportedRequestReport        : 1;
> +  UINT8 FatalErrorReport                : 1;
> +  UINT8 NoFatalErrorReport              : 1;
> +  UINT8 CorrectableErrorReport          : 1;
> +  UINT8 PmeInterrupt                    : 1;
> +  UINT8 SystemErrorOnFatalError         : 1;
> +  UINT8 SystemErrorOnNonFatalError      : 1;
> +  UINT8 SystemErrorOnCorrectableError   : 1;
> +
> +  UINT8 AdvancedErrorReporting          : 1;
> +  UINT8 TransmitterHalfSwing            : 1;
> +  UINT8 Reserved                        : 6;    /// Reserved fields for future expansion
> w/o protocol change
> +
> +  UINT8 FunctionNumber;                         /// The function number this root
> port is mapped to.
> +  UINT8 PhysicalSlotNumber;
> +  PCH_PCIE_COMPLETION_TIMEOUT   CompletionTimeout;
> +  PCH_PCI_EXPRESS_ASPM_CONTROL  Aspm;
> +} PCH_PCI_EXPRESS_ROOT_PORT_CONFIG;
> +
> +typedef struct {
> +  /**
> +    VendorId
> +
> +      The vendor Id of Pci Express card ASPM setting override, 0xFFFF means
> any Vendor ID
> +
> +    DeviceId
> +
> +      The Device Id of Pci Express card ASPM setting override, 0xFFFF means
> any Device ID
> +
> +    RevId
> +
> +      The Rev Id of Pci Express card ASPM setting override, 0xFF means all
> steppings
> +
> +    BaseClassCode
> +
> +      The Base Class Code of Pci Express card ASPM setting override, 0xFF
> means all base class
> +
> +    SubClassCode
> +
> +      The Sub Class Code of Pci Express card ASPM setting override, 0xFF
> means all sub class
> +
> +
> +    EndPointAspm
> +
> +      The override ASPM setting from End point
> +  **/
> +  UINT16                        VendorId;
> +  UINT16                        DeviceId;
> +  UINT8                         RevId;
> +  UINT8                         BaseClassCode;
> +  UINT8                         SubClassCode;
> +  PCH_PCI_EXPRESS_ASPM_CONTROL  EndPointAspm;
> +} PCH_PCIE_DEVICE_ASPM_OVERRIDE;
> +
> +typedef struct {
> +  UINT16  VendorId; ///< PCI configuration space offset 0
> +  UINT16  DeviceId; ///< PCI configuration space offset 2
> +  UINT8   RevId;    ///< PCI configuration space offset 8; 0xFF means all
> steppings
> +  /**
> +    SnoopLatency bit definition
> +    Note: All Reserved bits must be set to 0
> +
> +    BIT[15]     - When set to 1b, indicates that the values in bits 9:0 are valid
> +                  When clear values in bits 9:0 will be ignored
> +    BITS[14:13] - Reserved
> +    BITS[12:10] - Value in bits 9:0 will be multiplied with the scale in these bits
> +                  000b - 1 ns
> +                  001b - 32 ns
> +                  010b - 1024 ns
> +                  011b - 32,768 ns
> +                  100b - 1,048,576 ns
> +                  101b - 33,554,432 ns
> +                  110b - Reserved
> +                  111b - Reserved
> +    BITS[9:0]   - Snoop Latency Value. The value in these bits will be multiplied
> with
> +                  the scale in bits 12:10
> +  **/
> +  UINT16  SnoopLatency;
> +  /**
> +    NonSnoopLatency bit definition
> +    Note: All Reserved bits must be set to 0
> +
> +    BIT[15]     - When set to 1b, indicates that the values in bits 9:0 are valid
> +                  When clear values in bits 9:0 will be ignored
> +    BITS[14:13] - Reserved
> +    BITS[12:10] - Value in bits 9:0 will be multiplied with the scale in these bits
> +                  000b - 1 ns
> +                  001b - 32 ns
> +                  010b - 1024 ns
> +                  011b - 32,768 ns
> +                  100b - 1,048,576 ns
> +                  101b - 33,554,432 ns
> +                  110b - Reserved
> +                  111b - Reserved
> +    BITS[9:0]   - Non Snoop Latency Value. The value in these bits will be
> multiplied with
> +                  the scale in bits 12:10
> +  **/
> +  UINT16  NonSnoopLatency;
> +} PCH_PCIE_DEVICE_LTR_OVERRIDE;
> +
> +typedef struct {
> +  ///
> +  /// Temp Bus Number range available to be assigned to
> +  /// each root port and its downstream devices for initialization
> +  /// of these devices before PCI Bus enumeration
> +  ///
> +  UINT8                             TempRootPortBusNumMin;
> +  UINT8                             TempRootPortBusNumMax;
> +  PCH_PCI_EXPRESS_ROOT_PORT_CONFIG
> RootPort[PCH_PCIE_MAX_ROOT_PORTS];
> +  BOOLEAN                           RootPortClockGating;
> +  UINT8                             NumOfDevAspmOverride;     /// Number of PCI
> Express card Aspm setting override
> +  PCH_PCIE_DEVICE_ASPM_OVERRIDE     *DevAspmOverride;         /// The
> Pointer which is point to Pci Express card Aspm setting override
> +  UINT8                             PcieDynamicGating;        /// Need PMC enable it first
> from PMC 0x3_12 MCU 318.
> +} PCH_PCI_EXPRESS_CONFIG;
> +
> +
> +///
> +/// ---------------------------- SATA Config -----------------------------
> +///
> +typedef enum {
> +  PchSataSpeedSupportGen1 = 1,
> +  PchSataSpeedSupportGen2
> +} PCH_SATA_SPEED_SUPPORT;
> +
> +typedef struct {
> +  UINT8 Enable          : 1;    /// 0: Disable; 1: Enable
> +  UINT8 HotPlug         : 1;    /// 0: Disable; 1: Enable
> +  UINT8 MechSw          : 1;    /// 0: Disable; 1: Enable
> +  UINT8 External        : 1;    /// 0: Disable; 1: Enable
> +  UINT8 SpinUp          : 1;    /// 0: Disable; 1: Enable the COMRESET initialization
> Sequence to the device
> +  UINT8 Rsvdbits        : 3;    /// Reserved fields for future expansion w/o
> protocol change
> +} PCH_SATA_PORT_SETTINGS;
> +
> +typedef struct {
> +  PCH_SATA_PORT_SETTINGS  PortSettings[PCH_AHCI_MAX_PORTS];
> +  UINT8 RaidAlternateId : 1;    /// 0: Disable; 1: Enable
> +  UINT8 Raid0           : 1;    /// 0: Disable; 1: Enable RAID0
> +  UINT8 Raid1           : 1;    /// 0: Disable; 1: Enable RAID1
> +  UINT8 Raid10          : 1;    /// 0: Disable; 1: Enable RAID10
> +  UINT8 Raid5           : 1;    /// 0: Disable; 1: Enable RAID5
> +  UINT8 Irrt            : 1;    /// 0: Disable; 1: Enable Intel Rapid Recovery
> Technology
> +  UINT8 OromUiBanner    : 1;    /// 0: Disable; 1: Enable OROM UI and
> BANNER
> +  UINT8 HddUnlock       : 1;    /// 0: Disable; 1: Indicates that the HDD
> password unlock in the OS is enabled
> +
> +  UINT8 LedLocate       : 1;    /// 0: Disable; 1: Indicates that the LED/SGPIO
> hardware is attached and ping to locate feature is enabled on the OS
> +  UINT8 IrrtOnly        : 1;    /// 0: Disable; 1: Allow only IRRT drives to span
> internal and external ports
> +  UINT8 TestMode        : 1;    /// 0: Disable; 1: Allow entrance to the PCH SATA
> test modes
> +  UINT8 SalpSupport     : 1;    /// 0: Disable; 1: Enable Aggressive Link Power
> Management
> +  UINT8 LegacyMode      : 1;    /// 0: Native PCI mode; 1: Legacy mode, when
> SATA controller is operating in IDE mode
> +  UINT8 SpeedSupport    : 4;    /// Indicates the maximum speed the SATA
> controller can support
> +  /// 1h: 1.5 Gb/s (Gen 1); 2h: 3 Gb/s(Gen 2)
> +
> +  UINT8 Rsvdbits        : 7;    // Reserved fields for future expansion w/o
> protocol change
> +} PCH_SATA_CONFIG;
> +///
> +/// --------------------------- AZALIA Config ------------------------------
> +///
> +typedef struct {
> +  UINT32  VendorDeviceId;
> +  UINT16  SubSystemId;
> +  UINT8   RevisionId;                       /// 0xFF applies to all steppings
> +  UINT8   FrontPanelSupport;
> +  UINT16  NumberOfRearJacks;
> +  UINT16  NumberOfFrontJacks;
> +} PCH_AZALIA_VERB_TABLE_HEADER;
> +
> +typedef struct {
> +  PCH_AZALIA_VERB_TABLE_HEADER  VerbTableHeader;
> +  UINT32                        *VerbTableData;
> +} PCH_AZALIA_VERB_TABLE;
> +
> +typedef struct {
> +  UINT8                 Pme       : 1;      /// 0: Disable; 1: Enable
> +  UINT8                 DS        : 1;      /// 0: Docking is not supported; 1:Docking is
> supported
> +  UINT8                 DA        : 1;      /// 0: Docking is not attached; 1:Docking is
> attached
> +  UINT8                 HdmiCodec : 1;      /// 0: Disable; 1: Enable
> +  UINT8                 AzaliaVCi : 1;      /// 0: Disable; 1: Enable
> +  UINT8                 Rsvdbits  : 3;
> +  UINT8                 AzaliaVerbTableNum; /// Number of verb tables provided
> by platform
> +  PCH_AZALIA_VERB_TABLE *AzaliaVerbTable;   /// Pointer to the actual
> verb table(s)
> +  UINT16                ResetWaitTimer;     /// The delay timer after Azalia reset,
> the value is number of microseconds
> +} PCH_AZALIA_CONFIG;
> +
> +///
> +/// --------------------------- Smbus Config ------------------------------
> +///
> +typedef struct {
> +  UINT8 NumRsvdSmbusAddresses;
> +  UINT8 *RsvdSmbusAddressTable;
> +} PCH_SMBUS_CONFIG;
> +
> +///
> +/// --------------------------- Miscellaneous PM Config -----------------------------
> -
> +///
> +typedef struct {
> +  UINT8 MeWakeSts           : 1;
> +  UINT8 MeHrstColdSts       : 1;
> +  UINT8 MeHrstWarmSts       : 1;
> +  UINT8 MeHostPowerDn       : 1;
> +  UINT8 WolOvrWkSts         : 1;
> +  UINT8 Rsvdbits            : 3;
> +} PCH_POWER_RESET_STATUS;
> +
> +typedef struct {
> +  UINT8  PmeB0S5Dis         : 1;
> +  UINT8  WolEnableOverride  : 1;
> +  UINT8  Rsvdbits           : 6;
> +} PCH_WAKE_CONFIG;
> +
> +typedef enum {
> +  PchSlpS360us,
> +  PchSlpS31ms,
> +  PchSlpS350ms,
> +  PchSlpS32s
> +} PCH_SLP_S3_MIN_ASSERT;
> +
> +typedef enum {
> +  PchSlpS4PchTime,   /// The time defined in EDS Power Sequencing and
> Reset Signal Timings table
> +  PchSlpS41s,
> +  PchSlpS42s,
> +  PchSlpS43s,
> +  PchSlpS44s
> +} PCH_SLP_S4_MIN_ASSERT;
> +
> +typedef struct {
> +  ///
> +  /// Specify which Power/Reset bits need to be cleared by
> +  /// the PCH Init Driver.
> +  /// Usually platform drivers take care of these bits, but if
> +  /// not, let PCH Init driver clear the bits.
> +  ///
> +  PCH_POWER_RESET_STATUS  PowerResetStatusClear;
> +  ///
> +  /// Specify Wake Policy
> +  ///
> +  PCH_WAKE_CONFIG         WakeConfig;
> +  ///
> +  /// SLP_XX Minimum Assertion Width Policy
> +  ///
> +  PCH_SLP_S3_MIN_ASSERT   PchSlpS3MinAssert;
> +  PCH_SLP_S4_MIN_ASSERT   PchSlpS4MinAssert;
> +  UINT8                   SlpStrchSusUp : 1;  /// Enable/Disable SLP_X Stretching
> After SUS Well Power Up
> +  UINT8                   SlpLanLowDc   : 1;
> +  UINT8                   Rsvdbits      : 6;
> +} PCH_MISC_PM_CONFIG;
> +
> +///
> +/// --------------------------- Subsystem Vendor ID / Subsystem ID Config -----
> +///
> +typedef struct {
> +  UINT16  SubSystemVendorId;
> +  UINT16  SubSystemId;
> +} PCH_DEFAULT_SVID_SID;
> +
> +///
> +/// --------------------------- Lock Down Config ------------------------------
> +///
> +typedef struct {
> +  UINT8  GlobalSmi      : 1;
> +  UINT8  BiosInterface  : 1;
> +  UINT8  RtcLock        : 1;
> +  UINT8  BiosLock       : 1;
> +  UINT8  Rsvdbits       : 4;
> +  UINT8  PchBiosLockSwSmiNumber;
> +} PCH_LOCK_DOWN_CONFIG;
> +//
> +// --------------------------- Serial IRQ Config ------------------------------
> +//
> +typedef enum {
> +  PchQuietMode,
> +  PchContinuousMode
> +} PCH_SIRQ_MODE;
> +///
> +/// Refer to SoC EDS for the details of Start Frame Pulse Width in
> Continuous and Quiet mode
> +///
> +
> +typedef struct {
> +  BOOLEAN                 SirqEnable;       /// Determines if enable Serial IRQ
> +  PCH_SIRQ_MODE           SirqMode;         /// Serial IRQ Mode Select
> +} PCH_LPC_SIRQ_CONFIG;
> +
> +///
> +/// --------------------------- Power Optimizer Config ------------------------------
> +///
> +typedef struct {
> +  UINT8  NumOfDevLtrOverride;                            /// Number of Pci Express
> card listed in LTR override table
> +  PCH_PCIE_DEVICE_LTR_OVERRIDE *DevLtrOverride;          /// Pointer to Pci
> Express devices LTR override table
> +} PCH_PWR_OPT_CONFIG;
> +
> +///
> +/// --------------------- Low Power Input Output Config ------------------------
> +///
> +typedef struct {
> +  UINT8                   LpssPciModeEnabled    : 1;    /// Determines if LPSS PCI
> Mode enabled
> +  UINT8                   Dma0Enabled           : 1;     /// Determines if LPSS DMA1
> enabled
> +  UINT8                   Dma1Enabled           : 1;     /// Determines if LPSS DMA2
> enabled
> +  UINT8                   I2C0Enabled           : 1;     /// Determines if LPSS I2C #1
> enabled
> +  UINT8                   I2C1Enabled           : 1;     /// Determines if LPSS I2C #2
> enabled
> +  UINT8                   I2C2Enabled           : 1;     /// Determines if LPSS I2C #3
> enabled
> +  UINT8                   I2C3Enabled           : 1;     /// Determines if LPSS I2C #4
> enabled
> +  UINT8                   I2C4Enabled           : 1;     /// Determines if LPSS I2C #5
> enabled
> +  UINT8                   I2C5Enabled           : 1;     /// Determines if LPSS I2C #6
> enabled
> +  UINT8                   I2C6Enabled           : 1;     /// Determines if LPSS I2C #7
> enabled
> +  UINT8                   Pwm0Enabled           : 1;     /// Determines if LPSS PWM #1
> enabled
> +  UINT8                   Pwm1Enabled           : 1;     /// Determines if LPSS PWM #2
> enabled
> +  UINT8                   Hsuart0Enabled        : 1;     /// Determines if LPSS HSUART #1
> enabled
> +  UINT8                   Hsuart1Enabled        : 1;     /// Determines if LPSS HSUART #2
> enabled
> +  UINT8                   SpiEnabled            : 1;     /// Determines if LPSS SPI enabled
> +  UINT8                   Rsvdbits              : 2;
> +} PCH_LPSS_CONFIG;
> +
> +///
> +/// ----------------------------- SCC Config --------------------------------
> +///
> +typedef struct {
> +  UINT8                   eMMCEnabled           : 1;      /// Determines if SCC eMMC
> enabled
> +  UINT8                   SdioEnabled           : 1;      /// Determines if SCC SDIO enabled
> +  UINT8                   SdcardEnabled         : 1;      /// Determines if SCC SD Card
> enabled
> +  UINT8                   HsiEnabled            : 1;      /// Determines if SCC HSI enabled
> +  UINT8                   eMMC45Enabled         : 1;      /// Determines if SCC eMMC
> 4.5 enabled
> +  UINT8                   eMMC45DDR50Enabled    : 1;  /// Determines if DDR50
> enabled for eMMC 4.5
> +  UINT8                   eMMC45HS200Enabled    : 1;  /// Determines if
> HS200nabled for eMMC 4.5
> +  UINT8                   Rsvdbits              : 1;
> +  UINT8                   SdCardSDR25Enabled    : 1;    /// Determines if SDR25 for SD
> Card
> +  UINT8                   SdCardDDR50Enabled    : 1;    /// Determines if DDR50 for SD
> Card
> +  UINT8                   Rsvdbits1             : 6;
> +  UINT8                   eMMC45RetuneTimerValue;  /// Determines retune timer
> value.
> +} PCH_SCC_CONFIG;
> +
> +///
> +/// ------------ General PCH Platform Policy protocol definition ------------
> +///
> +struct _DXE_PCH_PLATFORM_POLICY_PROTOCOL {
> +  UINT8                   Revision;
> +  UINT8                   BusNumber;  /// PCI Bus Number of the PCH device
> +  PCH_DEVICE_ENABLING     *DeviceEnabling;
> +  PCH_USB_CONFIG          *UsbConfig;
> +  PCH_PCI_EXPRESS_CONFIG  *PciExpressConfig;
> +
> +  PCH_SATA_CONFIG         *SataConfig;
> +  PCH_AZALIA_CONFIG       *AzaliaConfig;
> +  PCH_SMBUS_CONFIG        *SmbusConfig;
> +  PCH_MISC_PM_CONFIG      *MiscPmConfig;
> +  PCH_DEFAULT_SVID_SID    *DefaultSvidSid;
> +  PCH_LOCK_DOWN_CONFIG    *LockDownConfig;
> +  PCH_LPC_SIRQ_CONFIG     *SerialIrqConfig;
> +  PCH_PWR_OPT_CONFIG      *PwrOptConfig;
> +  PCH_LPSS_CONFIG         *LpssConfig;
> +  PCH_SCC_CONFIG          *SccConfig;
> +  UINT8                   IdleReserve;
> +  UINT8                   EhciPllCfgEnable;
> +  UINT8                   AcpiHWRed; //Hardware Reduced Mode
> +};
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/PchReset.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/PchReset.h
> new file mode 100644
> index 0000000000..7e63f58346
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/PchReset.h
> @@ -0,0 +1,114 @@
> +/**
> +**/
> +/**
> +
> +Copyright (c) 2011  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +  @file
> +  PchReset.h
> +
> +  @brief
> +  PCH Reset Protocol
> +
> +**/
> +#ifndef _PCH_RESET_H_
> +#define _PCH_RESET_H_
> +
> +
> +//
> +#define PCH_RESET_PROTOCOL_GUID \
> +  { \
> +    0xdb63592c, 0xb8cc, 0x44c8, 0x91, 0x8c, 0x51, 0xf5, 0x34, 0x59, 0x8a, 0x5a
> \
> +  }
> +#define PCH_RESET_CALLBACK_PROTOCOL_GUID \
> +  { \
> +    0x3a3300ab, 0xc929, 0x487d, 0xab, 0x34, 0x15, 0x9b, 0xc1, 0x35, 0x62, 0xc0
> \
> +  }
> +extern EFI_GUID                             gPchResetProtocolGuid;
> +extern EFI_GUID                             gPchResetCallbackProtocolGuid;
> +
> +///
> +/// Forward reference for ANSI C compatibility
> +///
> +typedef struct _PCH_RESET_PROTOCOL          PCH_RESET_PROTOCOL;
> +
> +typedef struct _PCH_RESET_CALLBACK_PROTOCOL
> PCH_RESET_CALLBACK_PROTOCOL;
> +
> +///
> +/// Related Definitions
> +///
> +///
> +/// PCH Reset Types
> +///
> +typedef enum {
> +  ColdReset,
> +  WarmReset,
> +  ShutdownReset,
> +  PowerCycleReset,
> +  GlobalReset,
> +  GlobalResetWithEc
> +} PCH_RESET_TYPE;
> +
> +///
> +/// Member functions
> +///
> +typedef
> +EFI_STATUS
> +(EFIAPI *PCH_RESET) (
> +  IN     PCH_RESET_PROTOCOL       * This,
> +  IN     PCH_RESET_TYPE           PchResetType
> +  )
> +/**
> +
> +  @brief
> +  Execute Pch Reset from the host controller.
> +
> +  @param[in] This                 Pointer to the PCH_RESET_PROTOCOL instance.
> +  @param[in] PchResetType         Pch Reset Types which includes ColdReset,
> WarmReset, ShutdownReset,
> +                                  PowerCycleReset, GlobalReset, GlobalResetWithEc
> +
> +  @retval EFI_SUCCESS             Successfully completed.
> +  @retval EFI_INVALID_PARAMETER   If ResetType is invalid.
> +
> +**/
> +;
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *PCH_RESET_CALLBACK) (
> +  IN     PCH_RESET_TYPE           PchResetType
> +  )
> +/**
> +
> +  @brief
> +  Execute call back function for Pch Reset.
> +
> +  @param[in] PchResetType         Pch Reset Types which includes PowerCycle,
> Globalreset.
> +
> +  @retval EFI_SUCCESS             The callback function has been done
> successfully
> +  @retval EFI_NOT_FOUND           Failed to find Pch Reset Callback protocol.
> Or, none of
> +                                  callback protocol is installed.
> +  @retval Others                  Do not do any reset from PCH
> +
> +**/
> +;
> +
> +///
> +/// Interface structure for the Pch Reset Protocol
> +///
> +struct _PCH_RESET_PROTOCOL {
> +  PCH_RESET Reset;
> +};
> +
> +///
> +/// PCH_RESET_CALLBACK_PROTOCOL Structure Definition
> +///
> +struct _PCH_RESET_CALLBACK_PROTOCOL {
> +  PCH_RESET_CALLBACK  ResetCallback;
> +};
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/PchS3Support.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/PchS3Support.h
> new file mode 100644
> index 0000000000..ae1543c9ea
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/PchS3Support.h
> @@ -0,0 +1,132 @@
> +/**
> +**/
> +/**
> +
> +Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +  @file
> +  PchS3Support.h
> +
> +  @brief
> +  This file defines the PCH S3 support Protocol.
> +
> +**/
> +#ifndef _PCH_S3_SUPPORT_PROTOCOL_H_
> +#define _PCH_S3_SUPPORT_PROTOCOL_H_
> +
> +#ifndef ECP_FLAG
> +#include <Pi/PiS3BootScript.h>
> +#endif
> +
> +#define EFI_PCH_S3_SUPPORT_PROTOCOL_GUID \
> +  { \
> +    0xe287d20b, 0xd897, 0x4e1e, 0xa5, 0xd9, 0x97, 0x77, 0x63, 0x93, 0x6a, 0x4
> \
> +  }
> +
> +#include <Protocol/PchPlatformPolicy.h>
> +
> +///
> +/// Extern the GUID for protocol users.
> +///
> +extern EFI_GUID                             gEfiPchS3SupportProtocolGuid;
> +
> +///
> +/// Forward reference for ANSI C compatibility
> +///
> +typedef struct _EFI_PCH_S3_SUPPORT_PROTOCOL
> EFI_PCH_S3_SUPPORT_PROTOCOL;
> +
> +typedef enum {
> +  PchS3ItemTypeSendCodecCommand,
> +  PchS3ItemTypePollStatus,
> +  PchS3ItemTypeInitPcieRootPortDownstream,
> +  PchS3ItemTypePcieSetPm,
> +  PchS3ItemTypePmTimerStall,
> +  PchS3ItemTypeMax
> +} EFI_PCH_S3_DISPATCH_ITEM_TYPE;
> +
> +///
> +/// It's better not to use pointer here because the size of pointer in DXE is 8,
> but it's 4 in PEI
> +/// plug 4 to ParameterSize in PEIM if you really need it
> +///
> +typedef struct {
> +  UINT32                        HdaBar;
> +  UINT32                        CodecCmdData;
> +} EFI_PCH_S3_PARAMETER_SEND_CODEC_COMMAND;
> +
> +typedef struct {
> +  UINT64                        MmioAddress;
> +  EFI_BOOT_SCRIPT_WIDTH         Width;
> +  UINT64                        Mask;
> +  UINT64                        Value;
> +  UINT32                        Timeout;  // us
> +} EFI_PCH_S3_PARAMETER_POLL_STATUS;
> +
> +typedef struct {
> +  UINT8                         RootPortBus;
> +  UINT8                         RootPortDevice;
> +  UINT8                         RootPortFunc;
> +  UINT8                         TempBusNumberMin;
> +  UINT8                         TempBusNumberMax;
> +} EFI_PCH_S3_PARAMETER_INIT_PCIE_ROOT_PORT_DOWNSTREAM;
> +
> +typedef struct {
> +  UINT8                         RootPortBus;
> +  UINT8                         RootPortDevice;
> +  UINT8                         RootPortFunc;
> +  PCH_PCI_EXPRESS_ASPM_CONTROL  RootPortAspm;
> +  UINT8                         NumOfDevAspmOverride;
> +  UINT32                        DevAspmOverrideAddr;
> +  UINT8                         TempBusNumberMin;
> +  UINT8                         TempBusNumberMax;
> +  UINT8                         NumOfDevLtrOverride;
> +  UINT32                        DevLtrOverrideAddr;
> +} EFI_PCH_S3_PARAMETER_PCIE_SET_PM;
> +
> +typedef struct {
> +  UINT32                        DelayTime;  // us
> +} EFI_PCH_S3_PARAMETER_PM_TIMER_STALL;
> +
> +typedef struct {
> +  EFI_PCH_S3_DISPATCH_ITEM_TYPE Type;
> +  VOID                          *Parameter;
> +} EFI_PCH_S3_DISPATCH_ITEM;
> +
> +///
> +/// Member functions
> +///
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_PCH_S3_SUPPORT_SET_S3_DISPATCH_ITEM) (
> +  IN     EFI_PCH_S3_SUPPORT_PROTOCOL   * This,
> +  IN     EFI_PCH_S3_DISPATCH_ITEM      * DispatchItem,
> +  OUT    EFI_PHYSICAL_ADDRESS          * S3DispatchEntryPoint
> +  );
> +
> +/**
> +
> +  @brief
> +  Set an item to be dispatched at S3 resume time. At the same time, the
> entry point
> +  of the PCH S3 support image is returned to be used in subsequent boot
> script save
> +  call
> +
> +  @param[in] This                 Pointer to the protocol instance.
> +  @param[in] DispatchItem         The item to be dispatched.
> +  @param[in] S3DispatchEntryPoint The entry point of the PCH S3 support
> image.
> +
> +  @retval EFI_STATUS              Successfully completed.
> +  @retval EFI_OUT_OF_RESOURCES    Out of resources.
> +
> +**/
> +
> +///
> +/// Protocol definition
> +///
> +struct _EFI_PCH_S3_SUPPORT_PROTOCOL {
> +  EFI_PCH_S3_SUPPORT_SET_S3_DISPATCH_ITEM SetDispatchItem;
> +};
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/SdHostIo.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/SdHostIo.h
> new file mode 100644
> index 0000000000..c0c94b9384
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/SdHostIo.h
> @@ -0,0 +1,409 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +--*/
> +
> +
> +/*++
> +Module Name:
> +
> +  SdHostIo.h
> +
> +Abstract:
> +
> +  Interface definition for EFI_SD_HOST_IO_PROTOCOL
> +
> +--*/
> +
> +#ifndef _SD_HOST_IO_H
> +#define _SD_HOST_IO_H
> +
> +
> +// Global ID for the EFI_SD_HOST_IO_PROTOCOL
> +// {B63F8EC7-A9C9-4472-A4C0-4D8BF365CC51}
> +//
> +#define EFI_SD_HOST_IO_PROTOCOL_GUID \
> +  { 0xb63f8ec7, 0xa9c9, 0x4472, { 0xa4, 0xc0, 0x4d, 0x8b, 0xf3, 0x65, 0xcc,
> 0x51 } }
> +
> +typedef struct _EFI_SD_HOST_IO_PROTOCOL EFI_SD_HOST_IO_PROTOCOL;
> +
> +//
> +// TODO: Move to Pci22.h
> +//
> +#define PCI_SUBCLASS_SD_HOST_CONTROLLER   0x05
> +#define PCI_IF_STANDARD_HOST_NO_DMA       0x00
> +#define PCI_IF_STANDARD_HOST_SUPPORT_DMA  0x01
> +
> +//
> +// TODO: Retire
> +//
> +#define EFI_SD_HOST_IO_PROTOCOL_REVISION_01          0x01
> +
> +//
> +// TODO: Do these belong in an Industry Standard include file?
> +//
> +// MMIO Registers definition for MMC/SDIO controller
> +//
> +#define  MMIO_DMAADR                     0x00
> +#define  MMIO_BLKSZ                      0x04
> +#define  MMIO_BLKCNT                     0x06
> +#define  MMIO_CMDARG                     0x08
> +#define  MMIO_XFRMODE                    0x0C
> +#define  MMIO_SDCMD                      0x0E
> +#define  MMIO_RESP                       0x10
> +#define  MMIO_BUFDATA                    0x20
> +#define  MMIO_PSTATE                     0x24
> +#define  MMIO_HOSTCTL                    0x28
> +#define  MMIO_PWRCTL                     0x29
> +#define  MMIO_BLKGAPCTL                  0x2A
> +#define  MMIO_WAKECTL                    0x2B
> +#define  MMIO_CLKCTL                     0x2C
> +#define  MMIO_TOCTL                      0x2E
> +#define  MMIO_SWRST                      0x2F
> +#define  MMIO_NINTSTS                    0x30
> +#define  MMIO_ERINTSTS                   0x32
> +#define  MMIO_NINTEN                     0x34
> +#define  MMIO_ERINTEN                    0x36
> +#define  MMIO_NINTSIGEN                  0x38
> +#define  MMIO_ERINTSIGEN                 0x3A
> +#define  MMIO_AC12ERRSTS                 0x3C
> +#define  MMIO_HOST_CTL2                  0x3E //hphang <- New in VLV2
> +#define  MMIO_CAP                        0x40
> +#define  MMIO_CAP2                       0x44 //hphang <- New in VLV2
> +#define  MMIO_MCCAP                      0x48
> +#define  MMIO_FORCEEVENTCMD12ERRSTAT     0x50 //hphang <- New in
> VLV2
> +#define  MMIO_FORCEEVENTERRINTSTAT       0x52 //hphang <- New in VLV2
> +#define  MMIO_ADMAERRSTAT                0x54 //hphang <- New in VLV2
> +#define  MMIO_ADMASYSADDR                0x58 //hphang <- New in VLV2
> +#define  MMIO_PRESETVALUE0               0x60 //hphang <- New in VLV2
> +#define  MMIO_PRESETVALUE1               0x64 //hphang <- New in VLV2
> +#define  MMIO_PRESETVALUE2               0x68 //hphang <- New in VLV2
> +#define  MMIO_PRESETVALUE3               0x6C //hphang <- New in VLV2
> +#define  MMIO_BOOTTIMEOUTCTRL            0x70 //hphang <- New in VLV2
> +#define  MMIO_DEBUGSEL                   0x74 //hphang <- New in VLV2
> +#define  MMIO_SHAREDBUS                  0xE0 //hphang <- New in VLV2
> +#define  MMIO_SPIINTSUP                  0xF0 //hphang <- New in VLV2
> +#define  MMIO_SLTINTSTS                  0xFC
> +#define  MMIO_CTRLRVER                   0xFE
> +
> +typedef enum {
> +  ResponseNo = 0,
> +  ResponseR1,
> +  ResponseR1b,
> +  ResponseR2,
> +  ResponseR3,
> +  ResponseR4,
> +  ResponseR5,
> +  ResponseR5b,
> +  ResponseR6,
> +  ResponseR7
> +} RESPONSE_TYPE;
> +
> +typedef enum {
> +  NoData = 0,
> +  InData,
> +  OutData
> +} TRANSFER_TYPE;
> +
> +typedef enum {
> +  Reset_Auto = 0,
> +  Reset_DAT,
> +  Reset_CMD,
> +  Reset_DAT_CMD,
> +  Reset_All,
> +  Reset_HW
> +} RESET_TYPE;
> +
> +
> +typedef enum {
> +  SDMA = 0,
> +  ADMA2,
> +  PIO
> +} DMA_MOD;
> +
> +typedef struct {
> +  UINT32  HighSpeedSupport:    1;  //High speed supported
> +  UINT32  V18Support:          1;  //1.8V supported
> +  UINT32  V30Support:          1;  //3.0V supported
> +  UINT32  V33Support:          1;  //3.3V supported
> +  UINT32  SDR50Support:        1;
> +  UINT32  SDR104Support:       1;
> +  UINT32  DDR50Support:        1;
> +  UINT32  Reserved0:           1;
> +  UINT32  BusWidth4:           1;  // 4 bit width
> +  UINT32  BusWidth8:           1;  // 8 bit width
> +  UINT32  Reserved1:           6;
> +  UINT32  SDMASupport:         1;
> +  UINT32  ADMA2Support:        1;
> +  UINT32  DmaMode:             2;
> +  UINT32  ReTuneTimer:         4;
> +  UINT32  ReTuneMode:          2;
> +  UINT32  Reserved2:           6;
> +  UINT32  BoundarySize;
> +} HOST_CAPABILITY;
> +
> +/*++
> +
> +  Routine Description:
> +    The main function used to send the command to the card inserted into
> the SD host
> +    slot.
> +    It will assemble the arguments to set the command register and wait for
> the command
> +    and transfer completed until timeout. Then it will read the response
> register to fill
> +    the ResponseData
> +
> +  Arguments:
> +    This           - Pointer to EFI_SD_HOST_IO_PROTOCOL
> +    CommandIndex   - The command index to set the command index field of
> command register
> +    Argument       - Command argument to set the argument field of
> command register
> +    DataType       - TRANSFER_TYPE, indicates no data, data in or data out
> +    Buffer         - Contains the data read from / write to the device
> +    BufferSize     - The size of the buffer
> +    ResponseType   - RESPONSE_TYPE
> +    TimeOut        - Time out value in 1 ms unit
> +    ResponseData   - Depending on the ResponseType, such as CSD or card
> status
> +
> +  Returns:
> +    EFI_SUCCESS
> +    EFI_INVALID_PARAMETER
> +    EFI_OUT_OF_RESOURCES
> +    EFI_TIMEOUT
> +    EFI_DEVICE_ERROR
> +
> +--*/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SEND_COMMAND) (
> +  IN   EFI_SD_HOST_IO_PROTOCOL    *This,
> +  IN   UINT16                     CommandIndex,
> +  IN   UINT32                     Argument,
> +  IN   TRANSFER_TYPE              DataType,
> +  IN   UINT8                      *Buffer, OPTIONAL
> +  IN   UINT32                     BufferSize,
> +  IN   RESPONSE_TYPE              ResponseType,
> +  IN   UINT32                     TimeOut,
> +  OUT  UINT32                     *ResponseData OPTIONAL
> +  );
> +
> +/*++
> +
> +  Routine Description:
> +    Set max clock frequency of the host, the actual frequency
> +    may not be the same as MaxFrequency. It depends on
> +    the max frequency the host can support, divider, and host
> +    speed mode.
> +
> +  Arguments:
> +    This           - Pointer to EFI_SD_HOST_IO_PROTOCOL
> +    MaxFrequency   - Max frequency in HZ
> +
> +  Returns:
> +    EFI_SUCCESS
> +    EFI_TIMEOUT
> +--*/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SET_CLOCK_FREQUENCY) (
> +  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
> +  IN  UINT32                     MaxFrequency
> +  );
> +
> +/*++
> +
> +  Routine Description:
> +    Set bus width of the host
> +
> +  Arguments:
> +    This       - Pointer to EFI_SD_HOST_IO_PROTOCOL
> +    BusWidth   - Bus width in 1, 4, 8 bits
> +
> +  Returns:
> +    EFI_SUCCESS
> +    EFI_INVALID_PARAMETER
> +
> +--*/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SET_BUS_WIDTH) (
> +  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
> +  IN  UINT32                     BusWidth
> +  );
> +
> +/*++
> +
> +  Routine Description:
> +    Set voltage which could supported by the host.
> +    Support 0(Power off the host), 1.8V, 3.0V, 3.3V
> +  Arguments:
> +    This      - Pointer to EFI_SD_HOST_IO_PROTOCOL
> +    Voltage   - Units in 0.1 V
> +
> +  Returns:
> +    EFI_SUCCESS
> +    EFI_INVALID_PARAMETER
> +
> +--*/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SET_HOST_VOLTAGE) (
> +  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
> +  IN  UINT32                     Voltage
> +  );
> +
> +/*++
> +
> +  Routine Description:
> +    Set Host High Speed
> +  Arguments:
> +    This      - Pointer to EFI_SD_HOST_IO_PROTOCOL
> +    HighSpeed   - True for High Speed Mode set, false for normal mode
> +
> +  Returns:
> +    EFI_SUCCESS
> +    EFI_INVALID_PARAMETER
> +
> +--*/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SET_HOST_SPEED_MODE) (
> +  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
> +  IN  UINT32                     HighSpeed
> +  );
> +
> +/*++
> +
> +  Routine Description:
> +    Set High Speed Mode
> +  Arguments:
> +    This      - Pointer to EFI_SD_HOST_IO_PROTOCOL
> +    SetHostDdrMode   - True for DDR Mode set, false for normal mode
> +
> +  Returns:
> +    EFI_SUCCESS
> +    EFI_INVALID_PARAMETER
> +
> +--*/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SET_HOST_DDR_MODE) (
> +  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
> +  IN  UINT32                     DdrMode
> +  );
> +
> +
> +/*++
> +
> +  Routine Description:
> +   Reset the host
> +
> +  Arguments:
> +    This      - Pointer to EFI_SD_HOST_IO_PROTOCOL
> +    ResetAll  - TRUE to reset all
> +
> +  Returns:
> +    EFI_SUCCESS
> +    EFI_TIMEOUT
> +
> +--*/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_RESET_SD_HOST) (
> +  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
> +  IN  RESET_TYPE                 ResetType
> +  );
> +
> +/*++
> +
> +  Routine Description:
> +   Reset the host
> +
> +  Arguments:
> +    This    - Pointer to EFI_SD_HOST_IO_PROTOCOL
> +    Enable  - TRUE to enable, FALSE to disable
> +
> +  Returns:
> +    EFI_SUCCESS
> +    EFI_TIMEOUT
> +
> +--*/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_ENABLE_AUTO_STOP_CMD) (
> +  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
> +  IN  BOOLEAN                    Enable
> +  );
> +
> +/*++
> +
> +  Routine Description:
> +    Find whether these is a card inserted into the slot. If so
> +    init the host. If not, return EFI_NOT_FOUND.
> +
> +  Arguments:
> +    This      - Pointer to EFI_SD_HOST_IO_PROTOCOL
> +
> +  Returns:
> +    EFI_SUCCESS
> +    EFI_NOT_FOUND
> +
> +--*/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_DETECT_CARD_AND_INIT_HOST) (
> +  IN  EFI_SD_HOST_IO_PROTOCOL    *This
> +  );
> +
> +/*++
> +
> +  Routine Description:
> +   Set the Block length
> +
> +  Arguments:
> +    This        - Pointer to EFI_SD_HOST_IO_PROTOCOL
> +    BlockLength - card supportes block length
> +
> +  Returns:
> +    EFI_SUCCESS
> +    EFI_TIMEOUT
> +
> +--*/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SET_BLOCK_LENGTH) (
> +  IN  EFI_SD_HOST_IO_PROTOCOL    *This,
> +  IN  UINT32                     BlockLength
> +  );
> +
> +typedef EFI_STATUS
> +(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SETUP_DEVICE)(
> +  IN  EFI_SD_HOST_IO_PROTOCOL    *This
> +  );
> +
> +
> +
> +//
> +// Interface structure for the EFI SD Host I/O Protocol
> +//
> +struct _EFI_SD_HOST_IO_PROTOCOL {
> +  UINT32                                             Revision;
> +  HOST_CAPABILITY                                    HostCapability;
> +  EFI_SD_HOST_IO_PROTOCOL_SEND_COMMAND               SendCommand;
> +  EFI_SD_HOST_IO_PROTOCOL_SET_CLOCK_FREQUENCY
> SetClockFrequency;
> +  EFI_SD_HOST_IO_PROTOCOL_SET_BUS_WIDTH              SetBusWidth;
> +  EFI_SD_HOST_IO_PROTOCOL_SET_HOST_VOLTAGE           SetHostVoltage;
> +  EFI_SD_HOST_IO_PROTOCOL_SET_HOST_DDR_MODE
> SetHostDdrMode;
> +  EFI_SD_HOST_IO_PROTOCOL_RESET_SD_HOST              ResetSdHost;
> +  EFI_SD_HOST_IO_PROTOCOL_ENABLE_AUTO_STOP_CMD
> EnableAutoStopCmd;
> +  EFI_SD_HOST_IO_PROTOCOL_DETECT_CARD_AND_INIT_HOST
> DetectCardAndInitHost;
> +  EFI_SD_HOST_IO_PROTOCOL_SET_BLOCK_LENGTH           SetBlockLength;
> +  EFI_SD_HOST_IO_PROTOCOL_SETUP_DEVICE               SetupDevice;
> +  EFI_SD_HOST_IO_PROTOCOL_SET_HOST_SPEED_MODE
> SetHostSpeedMode;
> +};
> +
> +extern EFI_GUID gEfiSdHostIoProtocolGuid;
> +
> +#endif
> +
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/SmbiosSlotPopulation.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/SmbiosSlotPopulation.h
> new file mode 100644
> index 0000000000..8b7c42805f
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/SmbiosSlotPopulation.h
> @@ -0,0 +1,47 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +    SmbiosSlotPopulation.h
> +
> +Abstract:
> +
> +    EFI SMBIOS slot structure control code.
> +
> +GUID:
> +    {EF7BF7D6-F8FF-4a76-8247-C0D0D1CC49C0}
> +    0xef7bf7d6, 0xf8ff, 0x4a76, 0x82, 0x47, 0xc0, 0xd0, 0xd1, 0xcc, 0x49, 0xc0
> +
> +Revision History
> +
> +--*/
> +
> +#ifndef _EFI_SMBIOS_SLOT_POPULATION_H_
> +#define _EFI_SMBIOS_SLOT_POPULATION_H_
> +
> +//
> +// Slot Population Protocol GUID
> +//
> +#define EFI_SMBIOS_SLOT_POPULATION_GUID \
> +  { 0xef7bf7d6, 0xf8ff, 0x4a76, 0x82, 0x47, 0xc0, 0xd0, 0xd1, 0xcc, 0x49, 0xc0 }
> +
> +typedef struct {
> +  UINT16      SmbiosSlotId;   // SMBIOS Slot ID
> +  BOOLEAN     InUse;          // Does the slot have a card in it
> +  BOOLEAN     Disabled;       // Should the slot information be in SMBIOS
> +} EFI_SMBIOS_SLOT_ENTRY;
> +
> +typedef struct {
> +  UINT32                NumberOfEntries;
> +  EFI_SMBIOS_SLOT_ENTRY *SlotEntries;
> +} EFI_SMBIOS_SLOT_POPULATION_INFO;
> +
> +extern EFI_GUID gEfiSmbiosSlotPopulationGuid;
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/SmmIchnDispatchEx.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/SmmIchnDispatchEx.h
> new file mode 100644
> index 0000000000..73e12c5d6a
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/SmmIchnDispatchEx.h
> @@ -0,0 +1,159 @@
> +/**
> +**/
> +/**
> +
> +Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +  @file
> +  SmmIchnDispatchEx.h
> +
> +  @brief
> +  SmmIchnDispatch Extended Protocol
> +
> +**/
> +#ifndef _EFI_SMM_ICHN_DISPATCH_EX_H_
> +#define _EFI_SMM_ICHN_DISPATCH_EX_H_
> +
> +#ifdef ECP_FLAG
> +#include <Protocol/SmmIchnDispatch/SmmIchnDispatch.h>
> +#else
> +#include <Protocol/SmmIchnDispatch.h>
> +#endif
> +
> +#define EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL_GUID \
> +  { \
> +    0x3920405b, 0xc897, 0x44da, 0x88, 0xf3, 0x4c, 0x49, 0x8a, 0x6f, 0xf7, 0x36
> \
> +  }
> +extern EFI_GUID                                   gEfiSmmIchnDispatchExProtocolGuid;
> +
> +///
> +/// Forward reference for ANSI C compatibility
> +///
> +typedef struct _EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL
> EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL;
> +
> +///
> +/// Related Definitions
> +///
> +///
> +/// Ichn Dispatch Extended Types
> +///
> +typedef enum {
> +  IchnExPciExpress = NUM_ICHN_TYPES + 1,
> +  IchnExMonitor,
> +  IchnExSpi,
> +  IchnExQRT,
> +  IchnExGpioUnlock,
> +  IchnExTmrOverflow,
> +  IchnExPcie0Hotplug,
> +  IchnExPcie1Hotplug,
> +  IchnExPcie2Hotplug,
> +  IchnExPcie3Hotplug,
> +  IchnExPcie0LinkActive,
> +  IchnExPcie1LinkActive,
> +  IchnExPcie2LinkActive,
> +  IchnExPcie3LinkActive,
> +  ///
> +  /// INSERT NEW ITEMS JUST BEFORE THIS LINE
> +  ///
> +  IchnExTypeMAX /// the maximum number of items in this enumeration
> +} EFI_SMM_ICHN_EX_SMI_TYPE;
> +
> +typedef struct {
> +  EFI_SMM_ICHN_EX_SMI_TYPE  Type;
> +} EFI_SMM_ICHN_DISPATCH_EX_CONTEXT;
> +
> +///
> +/// Member functions
> +///
> +typedef
> +VOID
> +(EFIAPI *EFI_SMM_ICHN_DISPATCH_EX) (
> +  IN  EFI_HANDLE                                DispatchHandle,
> +  IN  EFI_SMM_ICHN_DISPATCH_EX_CONTEXT          * DispatchContext
> +  );
> +
> +/**
> +
> +  @brief
> +  Dispatch function for a ICH n Extended specific SMI handler.
> +
> +  @param[in] DispatchHandle       Handle of this dispatch function.
> +  @param[in] DispatchContext      Pointer to the dispatch function's context.
> +                                  The DispatchContext fields are filled in
> +                                  by the dispatching driver prior to
> +                                  invoking this dispatch function.
> +
> +    @retval None
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SMM_ICHN_EX_REGISTER) (
> +  IN  EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL   * This,
> +  IN  EFI_SMM_ICHN_DISPATCH_EX            DispatchFunction,
> +  IN  EFI_SMM_ICHN_DISPATCH_EX_CONTEXT    * DispatchContext,
> +  OUT EFI_HANDLE                          * DispatchHandle
> +  );
> +
> +/**
> +
> +  @brief
> +  Register a child SMI source dispatch function with a parent SMM driver
> +
> +  @param[in] This                 Protocol instance pointer.
> +  @param[in] DispatchFunction     Pointer to dispatch function to be invoked
> for
> +                                  this SMI source
> +  @param[in] DispatchContext      Pointer to the dispatch function's context.
> +                                  The caller fills this context in before calling
> +                                  the register function to indicate to the register
> +                                  function the ICHN SMI source for which the dispatch
> +                                  function should be invoked.
> +  @param[in] DispatchHandle       Handle of dispatch function, for when
> interfacing
> +                                  with the parent SMM driver.
> +
> +  @retval EFI_SUCCESS             The dispatch function has been successfully
> +                                  registered and the SMI source has been enabled.
> +  @retval EFI_DEVICE_ERROR        The driver was unable to enable the SMI
> source.
> +  @retval EFI_OUT_OF_RESOURCES    Not enough memory (system or SMM)
> to manage this
> +                                  child.
> +  @retval EFI_INVALID_PARAMETER   DispatchContext is invalid. The ICHN
> input value
> +                                  is not within valid range.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SMM_ICHN_EX_UNREGISTER) (
> +  IN  EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL         * This,
> +  IN  EFI_HANDLE                                DispatchHandle
> +  );
> +
> +/**
> +
> +  @brief
> +  Unregister a child SMI source dispatch function with a parent SMM driver
> +
> +  @param[in] This                 Protocol instance pointer.
> +  @param[in] DispatchHandle       Handle of dispatch function to deregister.
> +
> +  @retval EFI_SUCCESS             The dispatch function has been successfully
> +                                  unregistered and the SMI source has been disabled
> +                                  if there are no other registered child dispatch
> +                                  functions for this SMI source.
> +  @retval EFI_INVALID_PARAMETER   Handle is invalid.
> +  @retval Others                  TBD
> +
> +**/
> +
> +///
> +/// Interface structure for the SMM Ich n specific SMI Dispatch Protocol
> +///
> +typedef struct _EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL {
> +  EFI_SMM_ICHN_EX_REGISTER    Register;
> +  EFI_SMM_ICHN_EX_UNREGISTER  UnRegister;
> +};
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/SmmSmbus.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/SmmSmbus.h
> new file mode 100644
> index 0000000000..bb2b4d7c13
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/SmmSmbus.h
> @@ -0,0 +1,39 @@
> +/*++
> +
> +Copyright (c)  2009  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  SmmSmbus.h
> +
> +Abstract:
> +
> +  SmmSmbus Protocol
> +
> +--*/
> +#ifndef __EFI_SMM_SMBUS_PROTOCOL_H__
> +#define __EFI_SMM_SMBUS_PROTOCOL_H__
> +
> +//
> +// GUID for the SmmSmbus Protocol
> +//
> +// EDK and EDKII have different GUID formats
> +//
> +
> +#define EFI_SMM_SMBUS_PROTOCOL_GUID  \
> +  { \
> +    0x72e40094, 0x2ee1, 0x497a, 0x8f, 0x33, 0x4c, 0x93, 0x4a, 0x9e, 0x9c, 0xc \
> +  }
> +
> +//
> +// Resuse the DXE definition, and use another GUID.
> +//
> +typedef EFI_SMBUS_HC_PROTOCOL  SMM_SMBUS_HC_PROTOCOL;
> +
> +extern EFI_GUID  gEfiSmmSmbusProtocolGuid;
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/Spi.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/Spi.h
> new file mode 100644
> index 0000000000..a8d50cbbf2
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/Spi.h
> @@ -0,0 +1,260 @@
> +/**
> +**/
> +/**
> +
> +Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +  @file
> +  Spi.h
> +
> +  @brief
> +  This file defines the EFI SPI Protocol which implements the
> +  Intel(R) ICH SPI Host Controller Compatibility Interface.
> +
> +**/
> +#ifndef _EFI_SPI_H_
> +#define _EFI_SPI_H_
> +
> +
> +//
> +#define EFI_SPI_PROTOCOL_GUID \
> +  { \
> +    0x1156efc6, 0xea32, 0x4396, 0xb5, 0xd5, 0x26, 0x93, 0x2e, 0x83, 0xc3, 0x13
> \
> +  }
> +#define EFI_SMM_SPI_PROTOCOL_GUID \
> +  { \
> +    0xD9072C35, 0xEB8F, 0x43ad, 0xA2, 0x20, 0x34, 0xD4, 0x0E, 0x2A, 0x82,
> 0x85 \
> +  }
> +extern EFI_GUID                   gEfiSpiProtocolGuid;
> +extern EFI_GUID                   gEfiSmmSpiProtocolGuid;
> +
> +///
> +/// Forward reference for ANSI C compatibility
> +///
> +typedef struct _EFI_SPI_PROTOCOL  EFI_SPI_PROTOCOL;
> +
> +///
> +/// SPI protocol data structures and definitions
> +///
> +///
> +/// Number of Prefix Opcodes allowed on the SPI interface
> +///
> +#define SPI_NUM_PREFIX_OPCODE 2
> +
> +///
> +/// Number of Opcodes in the Opcode Menu
> +///
> +#define SPI_NUM_OPCODE  8
> +
> +///
> +/// Opcode Type
> +///    EnumSpiOpcodeCommand: Command without address
> +///    EnumSpiOpcodeRead: Read with address
> +///    EnumSpiOpcodeWrite: Write with address
> +///
> +typedef enum {
> +  EnumSpiOpcodeReadNoAddr,
> +  EnumSpiOpcodeWriteNoAddr,
> +  EnumSpiOpcodeRead,
> +  EnumSpiOpcodeWrite,
> +  EnumSpiOpcodeMax
> +} SPI_OPCODE_TYPE;
> +
> +typedef enum {
> +  EnumSpiCycle20MHz,
> +  EnumSpiCycle33MHz,
> +  EnumSpiCycle66MHz,  /// Not supported by VLV
> +  EnumSpiCycle50MHz,
> +  EnumSpiCycleMax
> +} SPI_CYCLE_FREQUENCY;
> +
> +typedef enum {
> +  EnumSpiRegionAll,
> +  EnumSpiRegionBios,
> +  EnumSpiRegionSeC,
> +  EnumSpiRegionDescriptor,
> +  EnumSpiRegionPlatformData,
> +  EnumSpiRegionMax
> +} SPI_REGION_TYPE;
> +
> +///
> +/// Hardware Sequencing required operations (as listed in Valleyview EDS
> "Hardware
> +/// Sequencing Commands and Opcode Requirements"
> +///
> +typedef enum {
> +  EnumSpiOperationWriteStatus,
> +  EnumSpiOperationProgramData_1_Byte,
> +  EnumSpiOperationProgramData_64_Byte,
> +  EnumSpiOperationReadData,
> +  EnumSpiOperationWriteDisable,
> +  EnumSpiOperationReadStatus,
> +  EnumSpiOperationWriteEnable,
> +  EnumSpiOperationFastRead,
> +  EnumSpiOperationEnableWriteStatus,
> +  EnumSpiOperationErase_256_Byte,
> +  EnumSpiOperationErase_4K_Byte,
> +  EnumSpiOperationErase_8K_Byte,
> +  EnumSpiOperationErase_64K_Byte,
> +  EnumSpiOperationFullChipErase,
> +  EnumSpiOperationJedecId,
> +  EnumSpiOperationDualOutputFastRead,
> +  EnumSpiOperationDiscoveryParameters,
> +  EnumSpiOperationOther,
> +  EnumSpiOperationMax
> +} SPI_OPERATION;
> +
> +///
> +/// SPI Command Configuration
> +///   Frequency       The expected frequency to be used (value to be
> programmed to the SSFC
> +///                   Register)
> +///   Operation       Which Hardware Sequencing required operation this
> opcode respoinds to.
> +///                   The required operations are listed in EDS Table 5-55: "Hardware
> +///                   Sequencing Commands and Opcode Requirements"
> +///                   If the opcode does not corresponds to any operation listed, use
> +///                   EnumSpiOperationOther, and provides TYPE and Code for it in
> +///                   SpecialOpcodeEntry.
> +///
> +typedef struct _SPI_OPCODE_MENU_ENTRY {
> +  SPI_OPCODE_TYPE     Type;
> +  UINT8               Code;
> +  SPI_CYCLE_FREQUENCY Frequency;
> +  SPI_OPERATION       Operation;
> +} SPI_OPCODE_MENU_ENTRY;
> +
> +//
> +// Initialization data table loaded to the SPI host controller
> +//    VendorId        Vendor ID of the SPI device
> +//    DeviceId0       Device ID0 of the SPI device
> +//    DeviceId1       Device ID1 of the SPI device
> +//    PrefixOpcode    Prefix opcodes which are loaded into the SPI host
> controller
> +//    OpcodeMenu      Opcodes which are loaded into the SPI host controller
> Opcode Menu
> +//    BiosStartOffset The offset of the start of the BIOS image relative to the
> flash device.
> +//                    Please note this is a Flash Linear Address, NOT a memory space
> address.
> +//                    This value is platform specific and depends on the system flash
> map.
> +//                    This value is only used on non Descriptor mode.
> +//    BiosSize        The the BIOS Image size in flash. This value is platform
> specific
> +//                    and depends on the system flash map. Please note BIOS Image
> size may
> +//                    be smaller than BIOS Region size (in Descriptor Mode) or the
> flash size
> +//                    (in Non Descriptor Mode), and in this case, BIOS Image is
> supposed to be
> +//                    placed at the top end of the BIOS Region (in Descriptor Mode)
> or the flash
> +//                    (in Non Descriptor Mode)
> +//
> +typedef struct _SPI_INIT_TABLE {
> +  UINT8                 VendorId;
> +  UINT8                 DeviceId0;
> +  UINT8                 DeviceId1;
> +  UINT8                 PrefixOpcode[SPI_NUM_PREFIX_OPCODE];
> +  SPI_OPCODE_MENU_ENTRY OpcodeMenu[SPI_NUM_OPCODE];
> +  UINTN                 BiosStartOffset;
> +  UINTN                 BiosSize;
> +} SPI_INIT_TABLE;
> +
> +//
> +// Protocol member functions
> +//
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_INIT) (
> +  IN EFI_SPI_PROTOCOL     * This,
> +  IN SPI_INIT_TABLE       * InitTable
> +  );
> +
> +/**
> +
> +  @brief
> +  Initializes the host controller to execute SPI commands.
> +
> +  @param[in] This                 Pointer to the EFI_SPI_PROTOCOL instance.
> +  @param[in] InitData             Pointer to caller-allocated buffer containing the
> SPI
> +                                  interface initialization table.
> +
> +  @retval EFI_SUCCESS             Opcode initialization on the SPI host controller
> completed.
> +  @retval EFI_ACCESS_DENIED       The SPI configuration interface is locked.
> +  @retval EFI_OUT_OF_RESOURCES    Not enough resource available to
> initialize the device.
> +  @retval EFI_DEVICE_ERROR        Device error, operation failed.
> +
> +**/
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_LOCK) (
> +  IN EFI_SPI_PROTOCOL     * This
> +  );
> +/**
> +
> +  @brief
> +  Initializes the host controller to execute SPI commands.
> +
> +  @param[in] This                 Pointer to the EFI_SPI_PROTOCOL instance.
> +  @param[in] InitData             Pointer to caller-allocated buffer containing the
> SPI
> +                                  interface initialization table.
> +
> +  @retval EFI_SUCCESS             Opcode initialization on the SPI host controller
> completed.
> +  @retval EFI_ACCESS_DENIED       The SPI configuration interface is locked.
> +  @retval EFI_OUT_OF_RESOURCES    Not enough resource available to
> initialize the device.
> +  @retval EFI_DEVICE_ERROR        Device error, operation failed.
> +
> +**/
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_EXECUTE) (
> +  IN     EFI_SPI_PROTOCOL   * This,
> +  IN     UINT8              OpcodeIndex,
> +  IN     UINT8              PrefixOpcodeIndex,
> +  IN     BOOLEAN            DataCycle,
> +  IN     BOOLEAN            Atomic,
> +  IN     BOOLEAN            ShiftOut,
> +  IN     UINTN              Address,
> +  IN     UINT32             DataByteCount,
> +  IN OUT UINT8              *Buffer,
> +  IN     SPI_REGION_TYPE    SpiRegionType
> +  );
> +/**
> +
> +  @brief
> +  Execute SPI commands from the host controller.
> +
> +  @param[in] This                 Pointer to the EFI_SPI_PROTOCOL instance.
> +  @param[in] OpcodeIndex          Index of the command in the OpCode
> Menu.
> +  @param[in] PrefixOpcodeIndex    Index of the first command to run when
> in an atomic cycle sequence.
> +  @param[in] DataCycle            TRUE if the SPI cycle contains data
> +  @param[in] Atomic               TRUE if the SPI cycle is atomic and interleave
> cycles are not allowed.
> +  @param[in] ShiftOut             If DataByteCount is not zero, TRUE to shift data
> out and FALSE to shift data in.
> +  @param[in] Address              In Descriptor Mode, for Descriptor Region, GbE
> Region, ME Region and Platform
> +                                  Region, this value specifies the offset from the Region
> Base; for BIOS Region,
> +                                  this value specifies the offset from the start of the BIOS
> Image. In Non
> +                                  Descriptor Mode, this value specifies the offset from the
> start of the BIOS Image.
> +                                  Please note BIOS Image size may be smaller than BIOS
> Region size (in Descriptor
> +                                  Mode) or the flash size (in Non Descriptor Mode), and in
> this case, BIOS Image is
> +                                  supposed to be placed at the top end of the BIOS Region
> (in Descriptor Mode) or
> +                                  the flash (in Non Descriptor Mode)
> +  @param[in] DataByteCount        Number of bytes in the data portion of the
> SPI cycle.
> +  @param[in] Buffer               Pointer to caller-allocated buffer containing the
> dada received or sent during the SPI cycle.
> +  @param[in] SpiRegionType        SPI Region type. Values EnumSpiRegionBios,
> EnumSpiRegionGbE, EnumSpiRegionMe,
> +                                  EnumSpiRegionDescriptor, and
> EnumSpiRegionPlatformData are only applicable in
> +                                  Descriptor mode. Value EnumSpiRegionAll is applicable to
> both Descriptor Mode
> +                                  and Non Descriptor Mode, which indicates
> "SpiRegionOffset" is actually relative
> +                                  to base of the 1st flash device (i.e., it is a Flash Linear
> Address).
> +
> +  @retval EFI_SUCCESS             Command succeed.
> +  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
> +  @exception EFI_UNSUPPORTED      Command not supported.
> +  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
> +
> +**/
> +
> +///
> +/// Protocol definition
> +///
> +struct _EFI_SPI_PROTOCOL {
> +  EFI_SPI_INIT    Init;
> +  EFI_SPI_LOCK    Lock;
> +  EFI_SPI_EXECUTE Execute;
> +};
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/TcoReset.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/TcoReset.h
> new file mode 100644
> index 0000000000..09be81ecbe
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Protocol/TcoReset.h
> @@ -0,0 +1,88 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  TcoReset.h
> +
> +Abstract:
> +
> +  Protocol to communicate with ICH TCO.
> +
> +GUID Info:
> + {A6A79162-E325-4c30-BCC3-59373064EFB3}
> + 0xa6a79162, 0xe325, 0x4c30, 0xbc, 0xc3, 0x59, 0x37, 0x30, 0x64, 0xef, 0xb3);
> +
> +
> +--*/
> +
> +#ifndef _TCO_RESET_H_
> +#define _TCO_RESET_H_
> +
> +
> +#define EFI_TCO_RESET_PROTOCOL_GUID  \
> +  {0xa6a79162, 0xe325, 0x4c30, 0xbc, 0xc3, 0x59, 0x37, 0x30, 0x64, 0xef, 0xb3}
> +
> +typedef struct _EFI_TCO_RESET_PROTOCOL EFI_TCO_RESET_PROTOCOL;
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_TCO_RESET_PROTOCOL_ENABLE_TCO_RESET) (
> +  IN      UINT32            *RcrbGcsSaveValue
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Enables the TCO timer to reset the system in case of a system hang.  This is
> +  used when writing the clock registers.
> +
> +Arguments:
> +
> +  RcrbGcsSaveValue  - This is the value of the RCRB GCS register before it is
> +                      changed by this procedure.  This will be used to restore
> +                      the settings of this register in PpiDisableTcoReset.
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +;
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_TCO_RESET_PROTOCOL_DISABLE_TCO_RESET) (
> +  OUT     UINT32    RcrbGcsRestoreValue
> +  )
> +/*++
> +
> +Routine Description:
> +
> +  Disables the TCO timer.  This is used after writing the clock registers.
> +
> +Arguments:
> +
> +  RcrbGcsRestoreValue - Value saved in PpiEnableTcoReset so that it can
> +                        restored.
> +
> +Returns:
> +
> +  EFI_STATUS
> +
> +--*/
> +;
> +
> +typedef struct _EFI_TCO_RESET_PROTOCOL {
> +  EFI_TCO_RESET_PROTOCOL_ENABLE_TCO_RESET       EnableTcoReset;
> +  EFI_TCO_RESET_PROTOCOL_DISABLE_TCO_RESET      DisableTcoReset;
> +} EFI_TCO_RESET_PROTOCOL;
> +
> +extern EFI_GUID gEfiTcoResetProtocolGuid;
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Rsci.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Rsci.h
> new file mode 100644
> index 0000000000..f5aa2eaf86
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/Rsci.h
> @@ -0,0 +1,28 @@
> +/*++
> +Copyright (c) 1996  - 2014, Intel Corporation.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +
> +
> +Abstract:
> +
> +
> +
> +--*/
> +
> +#ifndef _RSCI_H
> +#define _RSCI_H
> +
> +typedef enum {
> +  NOT_APPLICABLE_RESET = 0,
> +  WARM_RESET = 1,
> +  COLD_RESET = 2,
> +  GLOBAL_RESET = 7,
> +}ANDROID_RESET_TYPE;
> +
> +#endif
> diff --git
> a/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/TianoApi.h
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/TianoApi.h
> new file mode 100644
> index 0000000000..784ea187c6
> --- /dev/null
> +++
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Includ
> e/TianoApi.h
> @@ -0,0 +1,61 @@
> +/*++
> +
> +Copyright (c) 2004, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +Module Name:
> +
> +  TianoApi.h
> +
> +Abstract:
> +
> +  Tiano intrinsic definitions.
> +
> +
> +--*/
> +
> +#ifndef _TIANO_API_H_
> +#define _TIANO_API_H_
> +
> +//
> +// Pointer to internal runtime function
> +//
> +#define EFI_INTERNAL_FUNCTION 0x00000002
> +
> +//
> +// Pointer to internal runtime pointer
> +//
> +#define EFI_INTERNAL_POINTER  0x00000004
> +
> +//
> +// Pointer to internal runtime pointer
> +//
> +#define EFI_IPF_GP_POINTER  0x00000008
> +
> +#define EFI_TPL_DRIVER      6
> +
> +//
> +// EFI Event Types
> +//
> +#define EFI_EVENT_TIMER                         0x80000000
> +#define EFI_EVENT_RUNTIME                       0x40000000
> +#define EFI_EVENT_RUNTIME_CONTEXT               0x20000000
> +
> +#define EFI_EVENT_NOTIFY_WAIT                   0x00000100
> +#define EFI_EVENT_NOTIFY_SIGNAL                 0x00000200
> +
> +#define EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES     0x00000201
> +#define EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202
> +
> +#define EFI_EVENT_EFI_SIGNAL_MASK               0x000000FF
> +#define EFI_EVENT_EFI_SIGNAL_MAX                4
> +
> +//
> +// Task priority level
> +//
> +#define EFI_TPL_APPLICATION 4
> +#define EFI_TPL_CALLBACK    8
> +#define EFI_TPL_NOTIFY      16
> +#define EFI_TPL_HIGH_LEVEL  31
> +
> +#endif
> diff --git a/Silicon/Intel/Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> b/Silicon/Intel/Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> new file mode 100644
> index 0000000000..6117f179ba
> --- /dev/null
> +++ b/Silicon/Intel/Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> @@ -0,0 +1,231 @@
> +##  @file  Vlv2DeviceRefCodePkg.dec
> +#
> +# Copyright (c) 2012  - 2015, Intel Corporation. All rights reserved
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  DEC_SPECIFICATION              = 0x00010005
> +  PACKAGE_NAME                   = Vlv2DeviceRefCodePkg
> +  PACKAGE_GUID                   = E4FA0DCA-91A3-4957-9344-C10BAA0BFE5F
> +  PACKAGE_VERSION                = 0.1
> +
> +[Ppis]
> +  gVlvPolicyPpiGuid                                           = { 0x7D84B2C2, 0x22A1, 0x4372,
> {0xB1, 0x2C, 0xEB, 0xB2, 0x32, 0xD3, 0xA6, 0xA3}}
> +  gVlvMmioPolicyPpiGuid                                       = { 0xE767BF7F, 0x4DB6, 0x5B34,
> {0x10, 0x11, 0x4F, 0xBE, 0x4C, 0xA7, 0xAF, 0xD2}}
> +  gPeiSmbusPolicyPpiGuid                            = { 0x63b6e435, 0x32bc, 0x49c6,
> {0x81, 0xbd, 0xb7, 0xa1, 0xa0, 0xfe, 0x1a, 0x6c}}
> +  gSeCfTPMPpiGuid                       = { 0x10e26df1, 0x8775, 0x4ee1, {0xb5, 0x0a,
> 0x3a, 0xe8, 0x28, 0x93, 0x70, 0x3a}}
> +  gPchUsbPolicyPpiGuid                  = { 0xc02b0573, 0x2b4e, 0x4a31, {0xa3, 0x1a,
> 0x94, 0x56, 0x7b, 0x50, 0x44, 0x2c}}
> +  gPchInitPpiGuid                       = { 0x09ea894a, 0xbe0d, 0x4230, {0xa0, 0x03,
> 0xed, 0xc6, 0x93, 0xb4, 0x8e, 0x95}}
> +  gPchPlatformPolicyPpiGuid             = { 0x15344673, 0xD365, 0x4BE2, {0x85,
> 0x13, 0x14, 0x97, 0xCC, 0x07, 0x61, 0x1D}}
> +  gPeiSpiPpiGuid                        = { 0xA38C6898, 0x2B5C, 0x4FF6, {0x93, 0x26,
> 0x2E, 0x63, 0x21, 0x2E, 0x56, 0xC2}}
> +  gVlvPeiInitPpiGuid                    = { 0x09ea8911, 0xbe0d, 0x4230, {0xa0, 0x03,
> 0xed, 0xc6, 0x93, 0xb4, 0x8e, 0x11}}
> +  gSeCUmaPpiGuid                        = { 0xcbd86677, 0x362f, 0x4c04, {0x94, 0x59,
> 0xa7, 0x41, 0x32, 0x6e, 0x05, 0xcf}}
> +  gPeiSeCPlatformPolicyPpiGuid          = { 0x7ae3ceb7, 0x2ee2, 0x48fa, {0xaa,
> 0x49, 0x35, 0x10, 0xbc, 0x83, 0xca, 0xbf}}
> +  gPeiHeciPpiGuid                       = { 0xEE0EA811, 0xFBD9, 0x4777, {0xB9, 0x5A,
> 0xBA, 0x4F, 0x71, 0x10, 0x1F, 0x74}}
> +  gPeiSdhcPpiGuid                       = { 0xf4ef9d7a, 0x98c5, 0x4c1a, {0xb4, 0xd9,
> 0xd8, 0xd8, 0x72, 0x65, 0xbe, 0x0c}}
> +  gPeiBlockIoPpiGuid                    = { 0xbc5fa650, 0xedbb, 0x4d0d, {0xb3, 0xa3,
> 0xd9, 0x89, 0x07, 0xf8, 0x47, 0xdf}}
> +  gSeCfTPMPolicyPpiGuid                 = { 0x4fd1ba49, 0x8f90, 0x471a, {0xa2, 0xc9,
> 0x17, 0x3c, 0x7a, 0x73, 0x2f, 0xd0}}
> +  gEfiPeiReadOnlyVariable2PpiGuid       = { 0x2ab86ef5, 0xecb5, 0x4134, {0xb5,
> 0x56, 0x38, 0x54, 0xca, 0x1f, 0xe1, 0xb4}}
> +  gPchPeiInitPpiGuid                    = { 0xACB93B08, 0x5CDC, 0x4A8F, {0x93, 0xD4,
> 0x6, 0xE3, 0x42, 0xDF, 0x18, 0x2E}}
> +  gPttPassThruPpiGuid                   = { 0xc5068bac, 0xa7dc, 0x42f1, {0xae, 0x80,
> 0xca, 0xa2, 0x4b, 0xb4, 0x90, 0x4b}}
> +
> +[Protocols]
> +  gEfiGlobalNvsAreaProtocolGuid         = { 0x074e1e48, 0x8132, 0x47a1, {0x8c,
> 0x2c, 0x3f, 0x14, 0xad, 0x9a, 0x66, 0xdc}}
> +  gPpmPlatformPolicyProtocolGuid        = { 0xddabfeac, 0xef63, 0x452c, {0x8f,
> 0x39, 0xed, 0x7f, 0xae, 0xd8, 0x26, 0x5e}}
> +  gEfiSpiProtocolGuid                   = { 0x1156efc6, 0xea32, 0x4396, {0xb5, 0xd5,
> 0x26, 0x93, 0x2e, 0x83, 0xc3, 0x13}}
> +  gMemInfoProtocolGuid                  = { 0x6f20f7c8, 0xe5ef, 0x4f21, {0x8d, 0x19,
> 0xed, 0xc5, 0xf0, 0xc4, 0x96, 0xae}}
> +  gEfiSdHostIoProtocolGuid              = { 0xb63f8ec7, 0xa9c9, 0x4472, {0xa4,
> 0xc0, 0x4d, 0x8b, 0xf3, 0x65, 0xcc, 0x51}}
> +  gEfiSpiProtocolGuid                   = { 0x1156efc6, 0xea32, 0x4396, {0xb5, 0xd5,
> 0x26, 0x93, 0x2e, 0x83, 0xc3, 0x13}}
> +  gEfiSmmSpiProtocolGuid                = { 0xD9072C35, 0xEB8F, 0x43AD, {0xA2,
> 0x20, 0x34, 0xD4, 0x0E, 0x2A, 0x82, 0x85}}
> +  gEfiSmmIchnDispatchExProtocolGuid     = { 0x3920405B, 0xC897, 0x44DA,
> {0x88, 0xF3, 0x4C, 0x49, 0x8A, 0x6F, 0xF7, 0x36}}
> +  gEfiPchS3SupportProtocolGuid          = { 0xE287D20B, 0xD897, 0x4E1E, {0xA5,
> 0xD9, 0x97, 0x77, 0x63, 0x93, 0x6A, 0x04}}
> +  gPchResetProtocolGuid                 = { 0xDB63592C, 0xB8CC, 0x44C8, {0x91,
> 0x8C, 0x51, 0xF5, 0x34, 0x59, 0x8A, 0x5A}}
> +  gPchResetCallbackProtocolGuid         = { 0x3A3300AB, 0xC929, 0x487D,
> {0xAB, 0x34, 0x15, 0x9B, 0xC1, 0x35, 0x62, 0xC0}}
> +  gDxePchPlatformPolicyProtocolGuid     = { 0x4b0165a9, 0x61d6, 0x4e23,
> {0xa0, 0xb5, 0x3e, 0xc7, 0x9c, 0x2e, 0x30, 0xd5}}
> +  gEfiPchInfoProtocolGuid               = { 0xD31F0400, 0x7D16, 0x4316, {0xBF,
> 0x88, 0x60, 0x65, 0x88, 0x3B, 0x40, 0x2B}}
> +  gEfiPchExtendedResetProtocolGuid      = { 0xF0BBFCA0, 0x684E, 0x48B3,
> {0xBA, 0xE2, 0x6C, 0x84, 0xB8, 0x9E, 0x53, 0x39}}
> +  gEfiActiveBiosProtocolGuid            = { 0xEBBE2D1B, 0x1647, 0x4BDA, {0xAB,
> 0x9A, 0x78, 0x63, 0xE3, 0x96, 0xD4, 0x1A}}
> +  gDxeIchPlatformPolicyProtocolGuid     = { 0xf617b358, 0x12cf, 0x414a, {0xa0,
> 0x69, 0x60, 0x67, 0x7b, 0xda, 0x13, 0xb3}}
> +  gEfiIchInfoProtocolGuid               = { 0xd31f0400, 0x7d16, 0x4316, {0xbf, 0x88,
> 0x60, 0x65, 0x88, 0x3b, 0x40, 0x2b}}
> +  gEfiSmmIoTrapDispatchProtocolGuid     = { 0x58dc368d, 0x7bfa, 0x4e77,
> {0xab, 0xbc, 0x0e, 0x29, 0x41, 0x8d, 0xf9, 0x30}}
> +  gEfiSmmSmbusProtocolGuid              = { 0x72e40094, 0x2ee1, 0x497a, {0x8f,
> 0x33, 0x4c, 0x93, 0x4a, 0x9e, 0x9c, 0x0c}}
> +  gDxeVlvPlatformPolicyGuid             = { 0x5bab88ba, 0xe0e2, 0x4674, {0xb6,
> 0xad, 0xb8, 0x12, 0xf6, 0x88, 0x1c, 0xd6}}
> +  gIgdOpRegionProtocolGuid              = { 0xcdc5dddf, 0xe79d, 0x41ec, {0xa9,
> 0xb0, 0x65, 0x65, 0x49, 0x0d, 0xb9, 0xd3}}
> +  gEfiHeciProtocolGuid                  = { 0xcfb33810, 0x6e87, 0x4284, {0xb2, 0x03,
> 0xa6, 0x6a, 0xbe, 0x07, 0xf6, 0xe8}}
> +  gPlatformSeCHookProtocolGuid          = { 0xbc52476e, 0xf67e, 0x4301, {0xb2,
> 0x62, 0x36, 0x9c, 0x48, 0x78, 0xaa, 0xc2}}
> +  gEfiSeCRcInfoProtocolGuid             = { 0x11fbfdfb, 0x10d2, 0x43e6, {0xb5,
> 0xb1, 0xb4, 0x38, 0x6e, 0xdc, 0xcb, 0x9a}}
> +  gEfiTdtProtocolGuid                   = { 0x0bf70067, 0xd53b, 0x42df, {0xb7, 0x70,
> 0xe9, 0x2c, 0x91, 0xc6, 0x14, 0x11}}
> +  gDxePlatformSeCPolicyGuid             = { 0xf8bff014, 0x18fb, 0x4ef9, {0xb1,
> 0x0c, 0xae, 0x22, 0x73, 0x8d, 0xbe, 0xed}}
> +  gLpssDummyProtocolGuid                = { 0xaf4cc162, 0xd41c, 0x455a, {0xab,
> 0x45, 0x6d, 0xbc, 0xc1, 0xcd, 0x32, 0xf3}}
> +  gEfiEmmcCardInfoProtocolGuid          = { 0x1ebe5ab9, 0x2129, 0x49e7, {0x84,
> 0xd7, 0xee, 0xb9, 0xfc, 0xe5, 0xde, 0xdd}}
> +  gEfiTdtOperationProtocolGuid          = {0xfd301ba4, 0x5e62, 0x4679,{ 0xa0,
> 0x6f, 0xe0, 0x9a, 0xab, 0xdd, 0x2a, 0x91}}
> +  gEfiConfigFileNameGuid            = { 0x98B8D59B, 0xE8BA, 0x48EE, { 0x98,
> 0xDD, 0xC2, 0x95, 0x39, 0x2F, 0x1E, 0xDB }}
> +  gEfiDFUResultGuid                 = { 0x14a7c46f, 0xbc02, 0x4047, { 0x9f, 0x18,
> 0xa5, 0xd7, 0x25, 0xd8, 0xbd, 0x19 }}
> +  gPttPassThruProtocolGuid          = { 0x73e2576, 0xf6c1, 0x4b91, { 0x92, 0xa9,
> 0xd4, 0x67, 0x5d, 0xda, 0x34, 0xb1 } }
> +
> +[Guids]
> +  gEfiCPTokenSpaceGuid                  = { 0x918211ce, 0xa1d2, 0x43a0, {0xa0,
> 0x4e, 0x75, 0xb5, 0xbf, 0x44, 0x50, 0x0E}}
> +  gEfiSmbusArpMapGuid                   = { 0x707BE83E, 0x0BF6, 0x40A5, {0xBE,
> 0x64, 0x34, 0xC0, 0x3A, 0xA0, 0xB8, 0xE2}}
> +  gEfiMemoryConfigDataGuid              = { 0x80dbd530, 0xb74c, 0x4f11, {0x8c,
> 0x03, 0x41, 0x86, 0x65, 0x53, 0x28, 0x31}}
> +  gEfiVLVTokenSpaceGuid                 = { 0xca452c68, 0xdf0c, 0x45c9, {0x82, 0xfb,
> 0xea, 0xe4, 0x2b, 0x31, 0x29, 0x46}}
> +  gSataControllerDriverGuid             = { 0xbb929da9, 0x68f7, 0x4035, {0xb2,
> 0x2c, 0xa3, 0xbb, 0x3f, 0x23, 0xda, 0x55}}
> +  gDxePchPolicyUpdateProtocolGuid       = { 0x1a819e49, 0xd8ee, 0x48cb,
> {0x9a, 0x9c, 0x0a, 0xa0, 0xd2, 0x81, 0x0a, 0x38}}
> +  gPowerManagementAcpiTableStorageGuid  = { 0x161be597, 0xe9c5,
> 0x49db, {0xae, 0x50, 0xc4, 0x62, 0xab, 0x54, 0xee, 0xda}}
> +  gEfiSetupVariableGuid                 = { 0xec87d643, 0xeba4, 0x4bb5, {0xa1, 0xe5,
> 0x3f, 0x3e, 0x36, 0xb2, 0x0d, 0xa9}}
> +  gBmpImageGuid                         = { 0x878AC2CC, 0x5343, 0x46F2, {0xB5, 0x63,
> 0x51, 0xF8, 0x9D, 0xAF, 0x56, 0xBA}}
> +  gPchInitVariableGuid                  = { 0xe6c2f70a, 0xb604, 0x4877, {0x85, 0xba,
> 0xde, 0xec, 0x89, 0xe1, 0x17, 0xeb}}
> +  gEfiMemoryConfigDataGuid              = { 0x80dbd530, 0xb74c, 0x4f11, {0x8c,
> 0x03, 0x41, 0x86, 0x65, 0x53, 0x28, 0x31}}
> +  gVlvRefCodePkgTokenSpaceGuid          = { 0x85768E4A, 0x6CDC, 0x444E,
> {0x93, 0xDF, 0x93, 0x66, 0x85, 0xB5, 0xDF, 0xCC}}
> +  gSeCPlatformReadyToBootGuid           = { 0x03fdf171, 0x1d67, 0x4ace, {0xa9,
> 0x04, 0x3e, 0x36, 0xd3, 0x38, 0xfa, 0x74}}
> +  gAmtReadyToBootGuid                   = { 0x40b09b5a, 0xf0ef, 0x4627, {0x93,
> 0xd5, 0x27, 0xf0, 0x4b, 0x75, 0x4d, 0x05}}
> +  #
> +  # According to UEFI 2.3.1 Errata C, 3.2 Globally Defined Variables.
> +  # To prevent name collisions with possible future globally defined variables,
> +  # other internal firmware data variables that are not defined in Table.10
> must be saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE.
> +  #
> +  gEfiVlv2VariableGuid                  = { 0x10ba6bbe, 0xa97e, 0x41c3, {0x9a, 0x07,
> 0x60, 0x7a, 0xd9, 0xbd, 0x60, 0xe5}}
> +
> +[Includes.common]
> +  .
> +  ValleyView2Soc/NorthCluster/Include
> +  ValleyView2Soc/SouthCluster/Include
> +  ValleyView2Soc/CPU/Include
> +  Include
> +
> +[PcdsFixedAtBuild]
> +
> gEfiVLVTokenSpaceGuid.PcdTCSmbaIoBaseAddress|0x1040|UINT16|0x1000
> 0207
> +
> +[PcdsDynamic, PcdsDynamicEx]
> +
> gEfiVLVTokenSpaceGuid.PcdTCSmbaIoBaseAddress|0x1040|UINT16|0x1000
> 0207
> +  gEfiVLVTokenSpaceGuid.PcdEmmcManufacturerId|0|UINT8|0x10000208
> +  gEfiVLVTokenSpaceGuid.PcdProductSerialNumber|0|UINT32|0x10000209
> +
> gEfiVLVTokenSpaceGuid.PcdMeasuredBootEnable|TRUE|BOOLEAN|0x10000
> 20A
> +
> gEfiVLVTokenSpaceGuid.PcdFTPMErrorOccur|FALSE|BOOLEAN|0x1000020B
> +  gEfiVLVTokenSpaceGuid.PcdFTPMErrorSkip|FALSE|BOOLEAN|0x1000020C
> +  gEfiVLVTokenSpaceGuid.PcdFTPMCommand|0|UINT32|0x1000020D
> +  gEfiVLVTokenSpaceGuid.PcdFTPMResponse|0|UINT32|0x1000020E
> +
> gEfiVLVTokenSpaceGuid.PcdFTPMNotRespond|FALSE|BOOLEAN|0x1000020
> F
> +  gEfiVLVTokenSpaceGuid.PcdFTPMStatus|0|UINT32|0x10000210
> +
> gEfiVLVTokenSpaceGuid.PcdCpuLockBoxDataAddress|0x0|UINT64|0x100002
> 11
> +
> gEfiVLVTokenSpaceGuid.PcdCpuSmramCpuDataAddress|0x0|UINT64|0x100
> 00212
> +  gEfiVLVTokenSpaceGuid.PcdCpuLockBoxSize|0x0|UINT64|0x10000213
> +
> +[PcdsFeatureFlag]
> +
> gVlvRefCodePkgTokenSpaceGuid.PcdCeAtaSupport|FALSE|BOOLEAN|0x12
> +
> gVlvRefCodePkgTokenSpaceGuid.PcdMmcSdMultiBlockSupport|TRUE|BOOL
> EAN|0x13
> +
> +[PcdsPatchableInModule]
> +
> +  ## Memory Down or DIMM slot.<BR><BR>
> +  #  0 - DIMM<BR>
> +  #  1 - Memory Down<BR>
> +  # @Prompt Enable Memory Down
> +  # @ValidList 0x80000001 | 0, 1
> +
> gVlvRefCodePkgTokenSpaceGuid.PcdEnableMemoryDown|1|UINT8|0x2000
> 0000
> +
> +  ## Memory Parameter Patchable.<BR><BR>
> +  #  0 - Fixed Parameter for MinnowBoard Max<BR>
> +  #  1 - Patchable Parameter for Customization<BR>
> +  # @Prompt Memory Parameter Patchable.
> +  # @ValidList 0x80000001 | 0, 1
> +
> gVlvRefCodePkgTokenSpaceGuid.PcdMemoryParameterPatchable|FALSE|B
> OOLEAN|0x20000010
> +
> +  ## The speed of DRAM.<BR><BR>
> +  #  0 - 800 MHz<BR>
> +  #  1 - 1066 MHz<BR>
> +  #  2 - 1333 MHz<BR>
> +  #  3 - 1600 MHz<BR>
> +  # @Prompt DRAM Speed
> +  # @ValidList 0x80000001 | 0, 1, 2, 3
> +  gVlvRefCodePkgTokenSpaceGuid.PcdDramSpeed|1|UINT8|0x20000001
> +
> +  ## DRAM Type.<BR><BR>
> +  #  0 - DDR3<BR>
> +  #  1 - DDR3L<BR>
> +  #  2 - DDR3U<BR>
> +  #  3 - DDR3All<BR>
> +  #  4 - LPDDR2<BR>
> +  #  5 - LPDDR3<BR>
> +  #  6 - DDR4<BR>
> +  # @Prompt DRAM Type
> +  # @ValidList 0x80000001 | 0, 1, 2, 3, 4, 5, 6
> +  gVlvRefCodePkgTokenSpaceGuid.PcdDramType|1|UINT8|0x20000002
> +
> +  ## Please populate DIMM slot 0 if only one DIMM is supported.<BR><BR>
> +  #  0 - Disable<BR>
> +  #  1 - Enable<BR>
> +  # @Prompt DIMM 0 Enable
> +  # @ValidList 0x80000001 | 0, 1
> +  gVlvRefCodePkgTokenSpaceGuid.PcdEnableDimm0|1|UINT8|0x20000003
> +
> +  ## DIMM 1 has to be identical to DIMM 0.<BR><BR>
> +  #  0 - Disable<BR>
> +  #  1 - Enable<BR>
> +  # @Prompt DIMM 1 Enable Type
> +  # @ValidList 0x80000001 | 0, 1
> +  gVlvRefCodePkgTokenSpaceGuid.PcdEnableDimm1|0|UINT8|0x20000004
> +
> +  ## DRAM device data width.<BR><BR>
> +  #  0 - x8<BR>
> +  #  1 - x16<BR>
> +  #  2 - x32<BR>
> +  # @Prompt DIMM_DWIDTH
> +  # @ValidList 0x80000001 | 0, 1, 2
> +
> gVlvRefCodePkgTokenSpaceGuid.PcdDimmDataWidth|1|UINT8|0x20000005
> +
> +  ## DRAM device data density.<BR><BR>
> +  #  0 - 1 Gbit<BR>
> +  #  1 - 2 Gbit<BR>
> +  #  2 - 4 Gbit<BR>
> +  #  3 - 8 Gbit<BR>
> +  # @Prompt DIMM_Density
> +  # @ValidList 0x80000001 | 0, 1, 2, 3
> +  gVlvRefCodePkgTokenSpaceGuid.PcdDimmDensity|2|UINT8|0x20000006
> +
> +  ## DRAM device data bus width.<BR><BR>
> +  #  0 - 8 bits<BR>
> +  #  1 - 16 bits<BR>
> +  #  2 - 32 bits<BR>
> +  #  3 - 64 bits<BR>
> +  # @Prompt DIMM_BusWidth
> +  # @ValidList 0x80000001 | 0, 1, 2, 3
> +
> gVlvRefCodePkgTokenSpaceGuid.PcdDimmBusWidth|3|UINT8|0x20000007
> +
> +  ## Ranks Per DIMM or Sides Per DIMM.<BR><BR>
> +  #  0 - 1 Rank<BR>
> +  #  1 - 2 Ranks<BR>
> +  # @Prompt DIMM_Sides
> +  # @ValidList 0x80000001 | 0, 1
> +  gVlvRefCodePkgTokenSpaceGuid.PcdRankPerDimm|0|UINT8|0x20000008
> +
> +  ## tCL.<BR><BR>
> +  # @Prompt tCL
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTcl|11|UINT8|0x20000009
> +
> +  ## tRP and tRCD in DRAM clk - 5:12.5ns, 6:15ns, etc.<BR><BR>
> +  # @Prompt tRP_tRCD
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTrpTrcd|11|UINT8|0x2000000A
> +
> +  ## tWR in DRAM clk.<BR><BR>
> +  # @Prompt tWR
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTwr|12|UINT8|0x2000000B
> +
> +  ## tWTR in DRAM clk.<BR><BR>
> +  # @Prompt tWTR
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTwtr|6|UINT8|0x2000000C
> +
> +  ## tRRD in DRAM clk.<BR><BR>
> +  # @Prompt tRRD
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTrrd|6|UINT8|0x2000000D
> +
> +  ## tRTP in DRAM clk.<BR><BR>
> +  # @Prompt tRTP
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTrtp|6|UINT8|0x2000000E
> +
> +  ## tFAW in DRAM clk.<BR><BR>
> +  # @Prompt tFAW
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTfaw|32|UINT8|0x2000000F
> --
> 2.21.0.windows.1


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [edk2-platforms: Patch 6/8] Platform/Vlv2TbltDevicePkg: Import Vlv2TbltDevicePkg from edk2
  2019-05-10  3:34 ` [edk2-platforms: Patch 6/8] Platform/Vlv2TbltDevicePkg: Import Vlv2TbltDevicePkg " Michael D Kinney
@ 2019-05-13  2:52   ` Sun, Zailiang
  0 siblings, 0 replies; 23+ messages in thread
From: Sun, Zailiang @ 2019-05-13  2:52 UTC (permalink / raw)
  To: Kinney, Michael D, devel@edk2.groups.io
  Cc: Qian, Yi, Kubacki, Michael A, Leif Lindholm, Ard Biesheuvel

Reviewed-by: Zailiang Sun <zailiang.sun@intel.com>

> -----Original Message-----
> From: Kinney, Michael D
> Sent: Friday, May 10, 2019 11:35 AM
> To: devel@edk2.groups.io
> Cc: Sun, Zailiang <zailiang.sun@intel.com>; Qian, Yi <yi.qian@intel.com>;
> Kubacki, Michael A <michael.a.kubacki@intel.com>; Leif Lindholm
> <leif.lindholm@linaro.org>; Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Subject: [edk2-platforms: Patch 6/8] 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>
> ---
>  Platform/Intel/Vlv2TbltDevicePkg/.gitignore   |    5 +
>  .../AcpiPlatform/AcpiPlatform.c               | 1338 +++++
>  .../AcpiPlatform/AcpiPlatform.h               |  219 +
>  .../AcpiPlatform/AcpiPlatform.inf             |   89 +
>  .../AcpiPlatform/AcpiPlatformHooks.c          |  493 ++
>  .../AcpiPlatform/AcpiPlatformHooks.h          |  127 +
>  .../AcpiPlatform/AcpiPlatformHooksLib.h       |   91 +
>  .../Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h     |   56 +
>  .../FirmwareUpdate/FirmwareUpdate.c           |  922 ++++
>  .../FirmwareUpdate/FirmwareUpdate.h           |  185 +
>  .../FirmwareUpdate/FirmwareUpdate.inf         |   83 +
>  .../FirmwareUpdate/FirmwareUpdateStrings.uni  |   45 +
>  Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe   |  Bin 0 -> 499712 bytes
>  Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env  |   25 +
>  Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env  |   25 +
>  .../Intel/Vlv2TbltDevicePkg/BiosIdx64D.env    |   25 +
>  .../Intel/Vlv2TbltDevicePkg/BiosIdx64R.env    |   25 +
>  .../BootScriptSaveDxe/BootScriptSaveDxe.inf   |   60 +
>  .../InternalBootScriptSave.h                  |  102 +
>  .../BootScriptSaveDxe/ScriptSave.c            |  626 +++
>  .../Intel/Vlv2TbltDevicePkg/Build_IFWI.bat    |  200 +
>  .../Intel/Vlv2TbltDevicePkg/Build_IFWI.sh     |  104 +
>  Platform/Intel/Vlv2TbltDevicePkg/FCE.exe      |  Bin 0 -> 632832 bytes
>  .../Capsule/GenerateCapsule/GenCapsuleAll.bat |   35 +
>  .../Capsule/GenerateCapsule/GenCapsuleAll.sh  |   28 +
>  .../GenerateCapsule/GenCapsuleMinnowMax.bat   |  131 +
>  .../GenerateCapsule/GenCapsuleMinnowMax.sh    |   65 +
>  .../GenCapsuleMinnowMaxRelease.bat            |  131 +
>  .../GenCapsuleMinnowMaxRelease.sh             |   65 +
>  .../GenerateCapsule/GenCapsuleSampleColor.bat |  137 +
>  .../GenerateCapsule/GenCapsuleSampleColor.sh  |   70 +
>  .../Feature/Capsule/GenerateCapsule/Lvfs.ddf  |   14 +
>  .../LvfsGenCapsuleMinnowMax.bat               |  139 +
>  .../LvfsGenCapsuleMinnowMaxRelease.bat        |  139 +
>  .../LvfsGenCapsuleSampleColor.bat             |  145 +
>  ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
>  ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
>  ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
>  .../GenerateCapsule/template.metainfo.xml     |   27 +
>  .../Library/FmpDeviceLib/FmpDeviceLib.c       |  589 +++
>  .../Library/FmpDeviceLib/FmpDeviceLib.inf     |   46 +
>  .../Library/FmpDeviceLibSample/FmpDeviceLib.c |  412 ++
>  .../FmpDeviceLibSample/FmpDeviceLib.inf       |   34 +
>  .../PlatformFlashAccessLib.c                  |  685 +++
>  .../PlatformFlashAccessLib.inf                |   54 +
>  .../SystemFirmwareDescriptor.aslc             |   83 +
>  .../SystemFirmwareDescriptor.inf              |   40 +
>  .../SystemFirmwareDescriptorPei.c             |   60 +
>  .../SystemFirmwareUpdateConfig.ini            |   66 +
>  .../SystemFirmwareUpdateConfigGcc.ini         |   66 +
>  .../Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc |   55 +
>  .../Vlv2TbltDevicePkg/FmpCertificate.dsc      |   22 +
>  .../FmpGreenSampleDevice.dsc                  |   55 +
>  .../Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc  |   59 +
>  .../Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc  |   55 +
>  .../FspAzaliaConfigData/AzaliaConfig.bin      |  Bin 0 -> 3708 bytes
>  .../FspSupport/BootModePei/BootModePei.c      |   42 +
>  .../FspSupport/BootModePei/BootModePei.inf    |   40 +
>  .../FspHobProcessLibVlv2.c                    |  421 ++
>  .../FspHobProcessLibVlv2.inf                  |   74 +
>  .../FspPlatformSecLibVlv2.c                   |  144 +
>  .../FspPlatformSecLibVlv2.inf                 |   82 +
>  .../Ia32/AsmSaveSecContext.asm                |   45 +
>  .../SecFspPlatformSecLibVlv2/Ia32/Fsp.inc     |   45 +
>  .../Ia32/PeiCoreEntry.asm                     |  135 +
>  .../Ia32/SecEntry.asm                         |  338 ++
>  .../SecFspPlatformSecLibVlv2/Ia32/Stack.S     |   71 +
>  .../SecFspPlatformSecLibVlv2/Ia32/Stack.asm   |   76 +
>  .../SecFspPlatformSecLibVlv2/PlatformInit.c   |   36 +
>  .../SecFspPlatformSecLibVlv2/SaveSecContext.c |  108 +
>  .../SecGetPerformance.c                       |   83 +
>  .../SecPlatformInformation.c                  |   77 +
>  .../SecFspPlatformSecLibVlv2/SecRamInitData.c |   16 +
>  .../SecTempRamSupport.c                       |  149 +
>  .../SecFspPlatformSecLibVlv2/UartInit.c       |  192 +
>  .../Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c   |   68 +
>  .../Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf |   49 +
>  .../Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c |  170 +
>  .../FvbRuntimeDxe/FvbRuntimeDxe.inf           |   80 +
>  .../FvbRuntimeDxe/FvbService.c                | 1098 ++++
>  .../FvbRuntimeDxe/FvbService.h                |  182 +
>  .../FvbRuntimeDxe/FvbServiceDxe.c             |  199 +
>  .../FvbRuntimeDxe/FvbServiceSmm.c             |  127 +
>  .../FvbRuntimeDxe/FvbSmm.inf                  |   82 +
>  .../FvbRuntimeDxe/FvbSmmCommon.h              |   73 +
>  .../FvbRuntimeDxe/FvbSmmDxe.c                 |  944 ++++
>  .../FvbRuntimeDxe/FvbSmmDxe.h                 |  232 +
>  .../FvbRuntimeDxe/FvbSmmDxe.inf               |   50 +
>  Platform/Intel/Vlv2TbltDevicePkg/GenBiosId    |  Bin 0 -> 12236 bytes
>  .../Intel/Vlv2TbltDevicePkg/GenBiosId.exe     |  Bin 0 -> 384000 bytes
>  .../Include/AlertStandardFormatTable.h        |  122 +
>  .../Vlv2TbltDevicePkg/Include/ChipsetAccess.h |   28 +
>  .../Include/CommonIncludes.h                  |  115 +
>  .../Intel/Vlv2TbltDevicePkg/Include/CpuType.h |   59 +
>  .../Vlv2TbltDevicePkg/Include/FileHandleLib.h |  499 ++
>  .../Include/Guid/AcpiTableStorage.h           |   30 +
>  .../Include/Guid/AlertStandardFormat.h        |   86 +
>  .../Vlv2TbltDevicePkg/Include/Guid/BiosId.h   |   30 +
>  .../Include/Guid/BoardFeatures.h              |  214 +
>  .../Include/Guid/EfiVpdData.h                 |  156 +
>  .../Include/Guid/FirmwareId.h                 |   61 +
>  .../Include/Guid/HwWatchdogTimerHob.h         |  134 +
>  .../Vlv2TbltDevicePkg/Include/Guid/IdccData.h |  104 +
>  .../Vlv2TbltDevicePkg/Include/Guid/ItkData.h  |   70 +
>  .../Include/Guid/MemoryConfigData.h           |   32 +
>  .../Include/Guid/OsSelection.h                |   85 +
>  .../Include/Guid/PciLanInfo.h                 |   39 +
>  .../Include/Guid/PlatformCpuInfo.h            |  180 +
>  .../Include/Guid/PlatformInfo.h               |  433 ++
>  .../Include/Guid/SensorInfoVariable.h         |  279 +
>  .../Include/Guid/SetupVariable.h              | 1344 +++++
>  .../Intel/Vlv2TbltDevicePkg/Include/Hpet.h    |   40 +
>  .../Include/Library/BiosIdLib.h               |  104 +
>  .../Include/Library/CpuIA32.h                 |  345 ++
>  .../Include/Library/EfiRegTableLib.h          |  196 +
>  .../Vlv2TbltDevicePkg/Include/Library/Esrt.h  |   74 +
>  .../Vlv2TbltDevicePkg/Include/Library/Fd.h    |  264 +
>  .../Include/Library/FlashDeviceLib.h          |  122 +
>  .../Include/Library/I2CLib.h                  |   58 +
>  .../Include/Library/I2cMmioConfigLib.h        |   23 +
>  .../Include/Library/I2cPort_platform.h        |   26 +
>  .../Include/Library/PlatformFsaLib.h          |   50 +
>  .../Include/Library/PlatformFspLib.h          |   23 +
>  .../Include/Library/SpiFlash.H                |  239 +
>  .../Include/Library/StallSmmLib.h             |   40 +
>  .../Include/Library/UsbDeviceModeLib.h        |  181 +
>  .../Intel/Vlv2TbltDevicePkg/Include/Mcfg.h    |   69 +
>  .../Vlv2TbltDevicePkg/Include/McfgTable.h     |   65 +
>  .../Vlv2TbltDevicePkg/Include/Platform.h      |  133 +
>  .../Include/PlatformBootMode.h                |   35 +
>  .../Include/PlatformDefinitions.h             |   43 +
>  .../Include/Ppi/MfgMemoryTest.h               |   42 +
>  .../Include/Ppi/Sha256Hash.h                  |  131 +
>  .../Vlv2TbltDevicePkg/Include/Ppi/Speaker.h   |   65 +
>  .../Include/Ppi/UsbController.h               |   85 +
>  .../Include/Protocol/CK505ClockPlatformInfo.h |  126 +
>  .../Include/Protocol/EnhancedSpeedstep.h      |   76 +
>  .../Include/Protocol/GlobalNvsArea.h          |  475 ++
>  .../Include/Protocol/HwWatchdogTimer.h        |  235 +
>  .../Include/Protocol/I2cAcpi.h                |  107 +
>  .../Include/Protocol/I2cBus.h                 |  164 +
>  .../Include/Protocol/I2cBusMcg.h              |  163 +
>  .../Include/Protocol/I2cHostMcg.h             |  138 +
>  .../Include/Protocol/I2cMasterMcg.h           |  519 ++
>  .../Include/Protocol/I2cSlave.h               |  194 +
>  .../Include/Protocol/LpcWpc83627Policy.h      |   92 +
>  .../Include/Protocol/LpcWpce791Policy.h       |   55 +
>  .../Include/Protocol/MmioDevice.h             |   84 +
>  .../Include/Protocol/Observable.h             |  186 +
>  .../Include/Protocol/PlatformGopPolicy.h      |   68 +
>  .../Include/Protocol/PlatformIdeInit.h        |   43 +
>  .../Include/Protocol/SetupMode.h              |   79 +
>  .../Include/Protocol/SmbiosSlotPopulation.h   |   47 +
>  .../Include/Protocol/Speaker.h                |   65 +
>  .../Include/Protocol/TcoReset.h               |   67 +
>  .../Include/Protocol/TpmMp.h                  |  136 +
>  .../Include/Protocol/UsbPolicy.h              |  126 +
>  .../Include/Protocol/VlvPlatformPolicy.h      |  102 +
>  .../Vlv2TbltDevicePkg/Include/SetupMode.h     |   85 +
>  .../IntelGopDepex/IntelGopDriver.depex        |    1 +
>  .../Library/BiosIdLib/BiosIdLib.c             |  337 ++
>  .../Library/BiosIdLib/BiosIdLib.inf           |   50 +
>  .../Library/CpuIA32Lib/CpuIA32Lib.inf         |   41 +
>  .../Library/CpuIA32Lib/EfiCpuVersion.c        |   70 +
>  .../Library/CpuIA32Lib/IA32/CpuIA32.S         |  223 +
>  .../Library/CpuIA32Lib/IA32/CpuIA32.asm       |  206 +
>  .../Library/CpuIA32Lib/IA32/CpuIA32.c         |  177 +
>  .../Library/CpuIA32Lib/X64/Cpu.S              |  207 +
>  .../Library/CpuIA32Lib/X64/Cpu.asm            |  222 +
>  .../Library/EfiRegTableLib/EfiRegTableLib.c   |  282 ++
>  .../Library/EfiRegTableLib/EfiRegTableLib.inf |   47 +
>  .../Library/FlashDeviceLib/FlashDeviceLib.c   |  461 ++
>  .../Library/FlashDeviceLib/FlashDeviceLib.inf |   44 +
>  .../FlashDeviceLib/FlashDeviceLibDxe.c        |   56 +
>  .../FlashDeviceLib/FlashDeviceLibDxe.inf      |   43 +
>  .../FlashDeviceLibDxeRuntimeSmm.c             |  173 +
>  .../FlashDeviceLib/SpiChipDefinitions.h       |  835 +++
>  .../Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c |   46 +
>  .../Library/I2CLib/I2CLibNull.inf             |   39 +
>  .../Library/I2CLibDxe/I2CLib.c                |  735 +++
>  .../Library/I2CLibDxe/I2CLibDxe.inf           |   39 +
>  .../Library/I2CLibDxe/I2CRegs.h               |  126 +
>  .../Library/I2CLibPei/I2CAccess.h             |   44 +
>  .../Library/I2CLibPei/I2CDelayPei.c           |   46 +
>  .../Library/I2CLibPei/I2CDelayPei.h           |   30 +
>  .../Library/I2CLibPei/I2CIoLibPei.c           |  178 +
>  .../Library/I2CLibPei/I2CIoLibPei.h           |  153 +
>  .../Library/I2CLibPei/I2CLibPei.c             |  638 +++
>  .../Library/I2CLibPei/I2CLibPei.h             |  280 +
>  .../Library/I2CLibPei/I2CLibPei.inf           |   40 +
>  .../IntelPchAcpiTimerLib/CommonHeader.h       |   27 +
>  .../IntelPchAcpiTimerLib.c                    |  255 +
>  .../IntelPchAcpiTimerLib.inf                  |   51 +
>  .../BoardClkGens/BoardClkGens.c               |  430 ++
>  .../BoardClkGens/BoardClkGens.h               |  255 +
>  .../MultiPlatformLib/BoardGpios/BoardGpios.c  |  531 ++
>  .../MultiPlatformLib/BoardGpios/BoardGpios.h  |  324 ++
>  .../BoardJumpers/BoardJumpers.c               |   30 +
>  .../BoardJumpers/BoardJumpers.h               |   30 +
>  .../BoardOemIds/BoardOemIds.c                 |   43 +
>  .../BoardOemIds/BoardOemIds.h                 |   29 +
>  .../BoardSsidSvid/BoardSsidSvid.c             |   38 +
>  .../BoardSsidSvid/BoardSsidSvid.h             |   35 +
>  .../MultiPlatformLib/MultiPlatformLib.c       |  120 +
>  .../MultiPlatformLib/MultiPlatformLib.h       |   89 +
>  .../MultiPlatformLib/MultiPlatformLib.inf     |   77 +
>  .../MultiPlatformLib/PlatformInfoHob.c        |   54 +
>  .../Library/PchPlatformLib/PchPlatformLib.inf |   50 +
>  .../PchPlatformLib/PchPlatformLibrary.c       |  131 +
>  .../PchPlatformLib/PchPlatformLibrary.h       |   35 +
>  .../Library/PchSmmLib/CommonHeader.h          |   32 +
>  .../Library/PchSmmLib/PchSmmLib.c             |  157 +
>  .../Library/PchSmmLib/PchSmmLib.inf           |   46 +
>  .../Library/PlatformBdsLib/BdsPlatform.c      | 3098 ++++++++++++
>  .../Library/PlatformBdsLib/BdsPlatform.h      |  516 ++
>  .../Library/PlatformBdsLib/PlatformBdsLib.inf |  127 +
>  .../PlatformBdsLib/PlatformBdsStrings.uni     |   30 +
>  .../Library/PlatformBdsLib/PlatformData.c     |  306 ++
>  .../Library/PlatformCmosLib/PlatformCmosLib.c |  106 +
>  .../PlatformCmosLib/PlatformCmosLib.inf       |   30 +
>  .../Library/PlatformFspLib/PlatformFspLib.c   |   44 +
>  .../Library/PlatformFspLib/PlatformFspLib.inf |   49 +
>  .../Library/ResetSystemLib/ResetSystemLib.c   |  235 +
>  .../Library/ResetSystemLib/ResetSystemLib.inf |   47 +
>  .../SerialPortLib/PlatformSerialPortLib.h     |   53 +
>  .../Library/SerialPortLib/SerialPortLib.c     |  246 +
>  .../Library/SerialPortLib/SerialPortLib.inf   |   52 +
>  .../Library/SerialPortLib/SioInit.c           |  127 +
>  .../Library/SerialPortLib/SioInit.h           |   62 +
>  .../Library/SmbusLib/CommonHeader.h           |   26 +
>  .../Library/SmbusLib/SmbusLib.c               |  873 ++++
>  .../Library/SmbusLib/SmbusLib.inf             |   46 +
>  .../Library/StallSmmLib/StallSmm.c            |   89 +
>  .../Library/StallSmmLib/StallSmmLib.inf       |   51 +
>  .../Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.c    |  117 +
>  .../Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.inf  |   61 +
>  .../Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.c    |  145 +
>  .../Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.inf  |   60 +
>  .../Intel/Vlv2TbltDevicePkg/Logo/Logo.bmp     |  Bin 0 -> 94434 bytes
>  .../Metronome/LegacyMetronome.c               |  185 +
>  .../Metronome/LegacyMetronome.h               |   64 +
>  .../Vlv2TbltDevicePkg/Metronome/Metronome.inf |   49 +
>  .../MonoStatusCode/EfiStatusCode.h            |  178 +
>  .../MonoStatusCode/MonoStatusCode.c           |  132 +
>  .../MonoStatusCode/MonoStatusCode.h           |  128 +
>  .../MonoStatusCode/MonoStatusCode.inf         |   72 +
>  .../MonoStatusCode/PeiPostCode.c              |  121 +
>  .../MonoStatusCode/PlatformStatusCode.c       |  381 ++
>  .../MonoStatusCode/PlatformStatusCode.h       |  138 +
>  .../Library/GenericBdsLib/BdsBoot.c           | 4490 +++++++++++++++++
>  .../Library/GenericBdsLib/BdsConnect.c        |  429 ++
>  .../Library/GenericBdsLib/BdsConsole.c        | 1061 ++++
>  .../Library/GenericBdsLib/BdsMisc.c           | 1575 ++++++
>  .../Library/GenericBdsLib/DevicePath.c        |   27 +
>  .../Library/GenericBdsLib/GenericBdsLib.inf   |  142 +
>  .../Library/GenericBdsLib/GenericBdsLib.uni   |   19 +
>  .../GenericBdsLib/GenericBdsStrings.uni       |   30 +
>  .../Library/GenericBdsLib/InternalBdsLib.h    |  173 +
>  .../Library/GenericBdsLib/String.c            |   26 +
>  .../Library/GenericBdsLib/String.h            |   42 +
>  .../PciPlatform/BoardPciPlatform.c            |   55 +
>  .../PciPlatform/PciPlatform.c                 |  367 ++
>  .../PciPlatform/PciPlatform.h                 |   83 +
>  .../PciPlatform/PciPlatform.inf               |   65 +
>  .../Vlv2TbltDevicePkg/PlatformCapsule.dsc     |   39 +
>  .../Vlv2TbltDevicePkg/PlatformCapsule.fdf     |   52 +
>  .../Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc  |   38 +
>  .../Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf  |   52 +
>  .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.c   |   60 +
>  .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.h   |   29 +
>  .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf |   55 +
>  .../PlatformDxe/AzaliaVerbTable.h             |  247 +
>  .../Vlv2TbltDevicePkg/PlatformDxe/BoardId.c   |  223 +
>  .../PlatformDxe/BoardIdDecode.c               |  129 +
>  .../PlatformDxe/BoardIdDecode.h               |   61 +
>  .../PlatformDxe/ClockControl.c                |  202 +
>  .../PlatformDxe/Configuration.h               |  692 +++
>  .../Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c |   89 +
>  .../PlatformDxe/IchPlatformPolicy.c           |  484 ++
>  .../PlatformDxe/IchRegTable.c                 |  134 +
>  .../PlatformDxe/IchTcoReset.c                 |  211 +
>  .../Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c  |   72 +
>  .../PlatformDxe/LegacySpeaker.c               |  161 +
>  .../PlatformDxe/LegacySpeaker.h               |   69 +
>  .../PlatformDxe/Observable/Observable.c       |  582 +++
>  .../PlatformDxe/Observable/Observable.h       |  137 +
>  .../Vlv2TbltDevicePkg/PlatformDxe/PciBus.h    |  379 ++
>  .../Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c |  506 ++
>  .../Vlv2TbltDevicePkg/PlatformDxe/Platform.c  | 1820 +++++++
>  .../PlatformDxe/PlatformDxe.h                 |  722 +++
>  .../PlatformDxe/PlatformDxe.inf               |  149 +
>  .../Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c |  154 +
>  .../Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c |  112 +
>  .../PlatformDxe/SioPlatformPolicy.c           |   82 +
>  .../PlatformDxe/SlotConfig.c                  |  148 +
>  .../PlatformDxe/SlotConfig.h                  |   80 +
>  .../PlatformGopPolicy/PlatformGopPolicy.c     |  201 +
>  .../PlatformGopPolicy/PlatformGopPolicy.inf   |   51 +
>  .../PlatformInfoDxe/PlatformInfoDxe.c         |  169 +
>  .../PlatformInfoDxe/PlatformInfoDxe.h         |   30 +
>  .../PlatformInfoDxe/PlatformInfoDxe.inf       |   52 +
>  .../PlatformInitPei/BootMode.c                |  434 ++
>  .../PlatformInitPei/CpuInitPeim.c             |   44 +
>  .../Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c  |  319 ++
>  .../PlatformInitPei/FlashMap.c                |  143 +
>  .../PlatformInitPei/LegacySpeaker.c           |  168 +
>  .../PlatformInitPei/LegacySpeaker.h           |   71 +
>  .../PlatformInitPei/MchInit.c                 |   72 +
>  .../PlatformInitPei/MemoryCallback.c          |  338 ++
>  .../PlatformInitPei/MemoryPeim.c              |  408 ++
>  .../PlatformInitPei/PchInitPeim.c             |  808 +++
>  .../PlatformInitPei/PlatformEarlyInit.c       | 1195 +++++
>  .../PlatformInitPei/PlatformEarlyInit.h       | 1499 ++++++
>  .../PlatformInitPei/PlatformInfoInit.c        |  181 +
>  .../PlatformInitPei/PlatformInitPei.inf       |  117 +
>  .../PlatformInitPei/PlatformSsaInitPeim.c     |   58 +
>  .../PlatformInitPei/Recovery.c                |  361 ++
>  .../Vlv2TbltDevicePkg/PlatformInitPei/Stall.c |   91 +
>  .../Vlv2TbltDevicePkg/PlatformPei/BootMode.c  |  346 ++
>  .../PlatformPei/CommonHeader.h                |   60 +
>  .../PlatformPei/MemoryCallback.c              |  154 +
>  .../Vlv2TbltDevicePkg/PlatformPei/Platform.c  | 1198 +++++
>  .../Vlv2TbltDevicePkg/PlatformPei/Platform.h  |  213 +
>  .../PlatformPei/PlatformPei.inf               |  129 +
>  .../Vlv2TbltDevicePkg/PlatformPei/Stall.c     |   90 +
>  .../Intel/Vlv2TbltDevicePkg/PlatformPkg.dec   |  211 +
>  .../Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf   | 1073 ++++
>  .../Vlv2TbltDevicePkg/PlatformPkgConfig.dsc   |  107 +
>  .../Vlv2TbltDevicePkg/PlatformPkgGcc.fdf      | 1033 ++++
>  .../Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc   | 1711 +++++++
>  .../Vlv2TbltDevicePkg/PlatformPkgIA32.dsc     | 1699 +++++++
>  .../Vlv2TbltDevicePkg/PlatformPkgX64.dsc      | 1714 +++++++
>  .../PlatformSetupDxe/Boot.vfi                 |   72 +
>  .../PlatformSetupDxe/Configuration.h          |   56 +
>  .../PlatformSetupDxe/DebugConfig.vfi          |  118 +
>  .../PlatformSetupDxe/FwVersionStrings.uni     |   40 +
>  .../PlatformSetupDxe/Main.vfi                 |  331 ++
>  .../PlatformSetupDxe/PlatformSetupDxe.c       |  929 ++++
>  .../PlatformSetupDxe/PlatformSetupDxe.h       |   97 +
>  .../PlatformSetupDxe/PlatformSetupDxe.inf     |  141 +
>  .../PlatformSetupDxe/Security.vfi             |  104 +
>  .../PlatformSetupDxe/SetupFunctions.c         |   85 +
>  .../PlatformSetupDxe/SetupInfoRecords.c       | 1855 +++++++
>  .../PlatformSetupDxe/SouthClusterConfig.vfi   |  933 ++++
>  .../PlatformSetupDxe/SystemComponent.vfi      |   81 +
>  .../PlatformSetupDxe/Thermal.vfi              |  106 +
>  .../PlatformSetupDxe/UnCore.vfi               |  235 +
>  .../PlatformSetupDxe/UqiList.uni              |  452 ++
>  .../PlatformSetupDxe/Vfr.vfr                  |  123 +
>  .../PlatformSetupDxe/VfrStrings.uni           | 1417 ++++++
>  .../Vlv2TbltDevicePkg/PlatformSmm/Platform.c  |  997 ++++
>  .../PlatformSmm/PlatformSmm.inf               |   93 +
>  .../Vlv2TbltDevicePkg/PlatformSmm/S3Save.c    |  377 ++
>  .../PlatformSmm/SmmPlatform.h                 |  240 +
>  .../PlatformSmm/SmmScriptSave.c               |  252 +
>  .../PlatformSmm/SmmScriptSave.h               |   50 +
>  .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c   |  148 +
>  .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h   |   36 +
>  .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf |   49 +
>  Platform/Intel/Vlv2TbltDevicePkg/Readme.md    |  233 +
>  .../SaveMemoryConfig/SaveMemoryConfig.c       |  181 +
>  .../SaveMemoryConfig/SaveMemoryConfig.h       |   66 +
>  .../SaveMemoryConfig/SaveMemoryConfig.inf     |   60 +
>  .../SmBiosMiscDxe/CommonHeader.h              |   39 +
>  .../MiscBaseBoardManufacturer.uni             |   33 +
>  .../MiscBaseBoardManufacturerData.c           |   58 +
>  .../MiscBaseBoardManufacturerFunction.c       |  238 +
>  .../SmBiosMiscDxe/MiscBiosVendor.uni          |   26 +
>  .../SmBiosMiscDxe/MiscBiosVendorData.c        |  101 +
>  .../SmBiosMiscDxe/MiscBiosVendorFunction.c    |  336 ++
>  .../SmBiosMiscDxe/MiscBootInformationData.c   |   34 +
>  .../MiscBootInformationFunction.c             |   82 +
>  .../SmBiosMiscDxe/MiscChassisManufacturer.uni |   28 +
>  .../MiscChassisManufacturerData.c             |   57 +
>  .../MiscChassisManufacturerFunction.c         |  158 +
>  .../SmBiosMiscDxe/MiscMemoryDevice.uni        |   35 +
>  .../SmBiosMiscDxe/MiscMemoryDeviceData.c      |   45 +
>  .../SmBiosMiscDxe/MiscMemoryDeviceFunction.c  |  319 ++
>  .../MiscNumberOfInstallableLanguagesData.c    |   38 +
>  ...MiscNumberOfInstallableLanguagesFunction.c |  251 +
>  .../SmBiosMiscDxe/MiscOemString.uni           |   25 +
>  .../SmBiosMiscDxe/MiscOemStringData.c         |   34 +
>  .../SmBiosMiscDxe/MiscOemStringFunction.c     |   89 +
>  .../SmBiosMiscDxe/MiscOemType0x90.uni         |   31 +
>  .../SmBiosMiscDxe/MiscOemType0x90Data.c       |   36 +
>  .../SmBiosMiscDxe/MiscOemType0x90Function.c   |  442 ++
>  .../SmBiosMiscDxe/MiscOemType0x94.uni         |   42 +
>  .../SmBiosMiscDxe/MiscOemType0x94Data.c       |   54 +
>  .../SmBiosMiscDxe/MiscOemType0x94Function.c   | 1218 +++++
>  .../SmBiosMiscDxe/MiscOnboardDevice.uni       |   26 +
>  .../SmBiosMiscDxe/MiscOnboardDeviceData.c     |   48 +
>  .../SmBiosMiscDxe/MiscOnboardDeviceFunction.c |  135 +
>  .../SmBiosMiscDxe/MiscPhysicalArray.uni       |   25 +
>  .../SmBiosMiscDxe/MiscPhysicalArrayData.c     |   38 +
>  .../SmBiosMiscDxe/MiscPhysicalArrayFunction.c |  101 +
>  .../MiscPortInternalConnectorDesignator.uni   |   31 +
>  .../MiscPortInternalConnectorDesignatorData.c |   56 +
>  ...cPortInternalConnectorDesignatorFunction.c |  152 +
>  .../SmBiosMiscDxe/MiscProcessorCache.uni      |   22 +
>  .../SmBiosMiscDxe/MiscProcessorCacheData.c    |   33 +
>  .../MiscProcessorCacheFunction.c              |  189 +
>  .../MiscProcessorInformation.uni              |   27 +
>  .../MiscProcessorInformationData.c            |   71 +
>  .../MiscProcessorInformationFunction.c        |  448 ++
>  .../SmBiosMiscDxe/MiscResetCapabilitiesData.c |   43 +
>  .../MiscResetCapabilitiesFunction.c           |   85 +
>  .../SmBiosMiscDxe/MiscSubclassDriver.h        |  188 +
>  .../SmBiosMiscDxe/MiscSubclassDriver.uni      |   35 +
>  .../MiscSubclassDriverDataTable.c             |   98 +
>  .../MiscSubclassDriverEntryPoint.c            |  182 +
>  .../MiscSystemLanguageString.uni              |   24 +
>  .../MiscSystemLanguageStringData.c            |   34 +
>  .../MiscSystemLanguageStringFunction.c        |   93 +
>  .../SmBiosMiscDxe/MiscSystemManufacturer.uni  |   30 +
>  .../MiscSystemManufacturerData.c              |   48 +
>  .../MiscSystemManufacturerFunction.c          |  364 ++
>  .../SmBiosMiscDxe/MiscSystemOptionString.uni  |   24 +
>  .../MiscSystemOptionStringData.c              |   31 +
>  .../MiscSystemOptionStringFunction.c          |   93 +
>  .../MiscSystemSlotDesignation.uni             |   34 +
>  .../MiscSystemSlotDesignationData.c           |  246 +
>  .../MiscSystemSlotDesignationFunction.c       |  127 +
>  .../SmBiosMiscDxe/SmBiosMiscDxe.inf           |  139 +
>  .../SmmSwDispatch2OnSmmSwDispatchThunk.c      |  459 ++
>  .../SmmSwDispatch2OnSmmSwDispatchThunk.inf    |   54 +
>  .../SmramSaveInfoHandlerSmm.c                 |  164 +
>  .../SmramSaveInfoHandlerSmm.inf               |   60 +
>  .../Stitch/Gcc/NvStorageFtwSpare.bin          |  Bin 0 -> 262144 bytes
>  .../Stitch/Gcc/NvStorageFtwWorking.bin        |  Bin 0 -> 8192 bytes
>  .../Stitch/Gcc/NvStorageVariable.bin          |  Bin 0 -> 253952 bytes
>  .../Stitch/IFWIHeader/IFWI_HEADER.bin         |  Bin 0 -> 4096 bytes
>  .../Stitch/IFWIHeader/IFWI_HEADER_SPILOCK.bin |  Bin 0 -> 4096 bytes
>  .../Stitch/IFWIHeader/Vacant.bin              |  Bin 0 -> 3928064 bytes
>  .../Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat   |  270 +
>  .../Stitch/MNW2_Stitch_Config.txt             |   10 +
>  .../Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c |   33 +
>  .../Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf   |   32 +
>  .../VlvPlatformInitDxe/IgdOpRegion.c          |  929 ++++
>  .../VlvPlatformInitDxe/IgdOpRegion.h          |  235 +
>  .../VlvPlatformInitDxe/VlvPlatformInit.c      |  287 ++
>  .../VlvPlatformInitDxe/VlvPlatformInit.h      |   65 +
>  .../VlvPlatformInitDxe/VlvPlatformInitDxe.inf |   74 +
>  .../Vlv2TbltDevicePkg/Wpce791/LpcDriver.c     |  340 ++
>  .../Vlv2TbltDevicePkg/Wpce791/LpcDriver.h     |  112 +
>  .../Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c    |  366 ++
>  .../Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h    |  103 +
>  .../Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c  |  126 +
>  .../Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h  |  101 +
>  .../Vlv2TbltDevicePkg/Wpce791/Wpce791.inf     |   63 +
>  Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat  |  332 ++
>  Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh   |  256 +
>  Platform/Intel/Vlv2TbltDevicePkg/cln.sh       |   62 +
>  452 files changed, 95411 insertions(+)
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/.gitignore
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooksLib.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareU
> pdate.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareU
> pdate.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareU
> pdate.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareU
> pdateStrings.uni
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64D.env
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64R.env
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/BootScriptSaveDxe.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/InternalBootScriptSav
> e.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/ScriptSave.c
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.bat
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.sh
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FCE.exe
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenC
> apsuleAll.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenC
> apsuleAll.sh
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenC
> apsuleMinnowMax.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenC
> apsuleMinnowMax.sh
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenC
> apsuleMinnowMaxRelease.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenC
> apsuleMinnowMaxRelease.sh
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenC
> apsuleSampleColor.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenC
> apsuleSampleColor.sh
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Lvfs.d
> df
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsG
> enCapsuleMinnowMax.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsG
> enCapsuleMinnowMaxRelease.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsG
> enCapsuleSampleColor.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/NewR
> oot.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.i
> nc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMP
> LE_DEVELOPMENT.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7
> CertBufferXdr.inc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMP
> LE_DEVELOPMENT_SAMPLE_PRODUCTION.cer.gFmpDevicePkgTokenSpace
> Guid.PcdFmpDevicePkcs7CertBufferXdr.inc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/templ
> ate.metainfo.xml
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/F
> mpDeviceLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/F
> mpDeviceLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSa
> mple/FmpDeviceLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSa
> mple/FmpDeviceLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAc
> cessLib/PlatformFlashAccessLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAc
> cessLib/PlatformFlashAccessLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescrip
> tor/SystemFirmwareDescriptor.aslc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescrip
> tor/SystemFirmwareDescriptor.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescrip
> tor/SystemFirmwareDescriptorPei.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdate
> Config/SystemFirmwareUpdateConfig.ini
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdate
> Config/SystemFirmwareUpdateConfigGcc.ini
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FmpCertificate.dsc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FmpGreenSampleDevice.dsc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspAzaliaConfigData/AzaliaConfig.bin
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.
> c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.i
> nf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLib
> Vlv2/FspHobProcessLibVlv2.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLib
> Vlv2/FspHobProcessLibVlv2.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/FspPlatformSecLibVlv2.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/FspPlatformSecLibVlv2.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/Ia32/AsmSaveSecContext.asm
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/Ia32/Fsp.inc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/Ia32/PeiCoreEntry.asm
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/Ia32/SecEntry.asm
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/Ia32/Stack.S
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/Ia32/Stack.asm
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/PlatformInit.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/SaveSecContext.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/SecGetPerformance.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/SecPlatformInformation.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/SecRamInitData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/SecTempRamSupport.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/UartInit.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbRuntimeDxe.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceDxe.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceSmm.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmm.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmCommon.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.inf
>  create mode 100755 Platform/Intel/Vlv2TbltDevicePkg/GenBiosId
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/GenBiosId.exe
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/AlertStandardFormatTable.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/ChipsetAccess.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/CommonIncludes.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/CpuType.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/FileHandleLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AcpiTableStorage.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AlertStandardFormat.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BiosId.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BoardFeatures.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/EfiVpdData.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/FirmwareId.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/HwWatchdogTimerHob.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/IdccData.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/ItkData.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/MemoryConfigData.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/OsSelection.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PciLanInfo.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformCpuInfo.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformInfo.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SensorInfoVariable.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SetupVariable.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Hpet.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/BiosIdLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/CpuIA32.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/EfiRegTableLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Esrt.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Fd.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/FlashDeviceLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2CLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cMmioConfigLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cPort_platform.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFsaLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFspLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/SpiFlash.H
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/StallSmmLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/UsbDeviceModeLib.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Mcfg.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/McfgTable.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Platform.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformBootMode.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformDefinitions.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/MfgMemoryTest.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Sha256Hash.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Speaker.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/UsbController.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/CK505ClockPlatformInfo.
> h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/EnhancedSpeedstep.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/GlobalNvsArea.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/HwWatchdogTimer.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cAcpi.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBus.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBusMcg.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cHostMcg.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cMasterMcg.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cSlave.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpc83627Policy.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpce791Policy.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/MmioDevice.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Observable.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformGopPolicy.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformIdeInit.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SetupMode.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SmbiosSlotPopulation.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Speaker.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TcoReset.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TpmMp.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/UsbPolicy.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/VlvPlatformPolicy.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/SetupMode.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/IntelGopDepex/IntelGopDriver.depex
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/CpuIA32Lib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/EfiCpuVersion.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.S
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.asm
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.S
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.asm
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxe.
> c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxe.
> inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxe
> RuntimeSmm.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/SpiChipDefinitions.
> h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLibNull.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLibDxe.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CRegs.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CAccess.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/CommonHe
> ader.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpi
> TimerLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpi
> TimerLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens/B
> oardClkGens.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens/B
> oardClkGens.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/Boa
> rdGpios.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/Boa
> rdGpios.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers/B
> oardJumpers.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers/B
> oardJumpers.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/B
> oardOemIds.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/B
> oardOemIds.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid/B
> oardSsidSvid.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid/B
> oardSsidSvid.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib
> .c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib
> .h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib
> .inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/PlatformInfoHob
> .c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibrar
> y.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibrar
> y.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/CommonHeader.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsString
> s.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmosLi
> b.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmosLi
> b.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLib.i
> nf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/PlatformSerialPortLib
> .h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/CommonHeader.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmm.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmmLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2Devic
> eLibSeC.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2Devic
> eLibSeC.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2Devic
> eLibSeC.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2Devic
> eLibSeC.inf
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Logo/Logo.bmp
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Metronome/Metronome.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/EfiStatusCode.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PeiPostCode.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libr
> ary/GenericBdsLib/BdsBoot.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libr
> ary/GenericBdsLib/BdsConnect.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libr
> ary/GenericBdsLib/BdsConsole.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libr
> ary/GenericBdsLib/BdsMisc.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libr
> ary/GenericBdsLib/DevicePath.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libr
> ary/GenericBdsLib/GenericBdsLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libr
> ary/GenericBdsLib/GenericBdsLib.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libr
> ary/GenericBdsLib/GenericBdsStrings.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libr
> ary/GenericBdsLib/InternalBdsLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libr
> ary/GenericBdsLib/String.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libr
> ary/GenericBdsLib/String.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/BoardPciPlatform.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.inf
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.dsc
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.fdf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe
> .c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe
> .h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe
> .inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/AzaliaVerbTable.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardId.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ClockControl.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Configuration.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchPlatformPolicy.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchRegTable.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchTcoReset.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciBus.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Platform.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.inf
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SioPlatformPolicy.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/BootMode.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/CpuInitPeim.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/FlashMap.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MchInit.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryCallback.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryPeim.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PchInitPeim.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInfoInit.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInitPei.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformSsaInitPeim.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Recovery.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Stall.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/BootMode.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/CommonHeader.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/MemoryCallback.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/PlatformPei.inf
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Stall.c
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.dec
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgConfig.dsc
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGcc.fdf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgIA32.dsc
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgX64.dsc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Boot.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Configuration.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/DebugConfig.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/FwVersionStrings.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Main.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Security.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupFunctions.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupInfoRecords.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SouthClusterConfig.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SystemComponent.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Thermal.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UnCore.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UqiList.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Vfr.vfr
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/VfrStrings.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/Platform.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/PlatformSmm.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/S3Save.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmPlatform.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Readme.md
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.
> h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.i
> nf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/CommonHeader.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufact
> urer.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufact
> urerData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufact
> urerFunction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendor.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorFunction.
> c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationDat
> a.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationFun
> ction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturer
> .uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturer
> Data.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturer
> Function.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDevice.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceData.
> c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceFunct
> ion.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstallable
> LanguagesData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstallable
> LanguagesFunction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemString.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringFunction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Data.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Functi
> on.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Data.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Functi
> on.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDevice.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceData.
> c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceFunct
> ion.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArray.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayFunctio
> n.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnect
> orDesignator.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnect
> orDesignatorData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnect
> orDesignatorFunction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCache.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheData.
> c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheFunc
> tion.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformatio
> n.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformatio
> nData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformatio
> nFunction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesDat
> a.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesFun
> ction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverDataT
> able.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverEntryP
> oint.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageStri
> ng.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageStri
> ngData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageStri
> ngFunction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacture
> r.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacture
> rData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacture
> rFunction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionString.
> uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionString
> Data.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStringF
> unction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignati
> on.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignati
> onData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignati
> onFunction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/SmBiosMiscDxe.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchThun
> k/SmmSwDispatch2OnSmmSwDispatchThunk.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchThun
> k/SmmSwDispatch2OnSmmSwDispatchThunk.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSaveI
> nfoHandlerSmm.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSaveI
> nfoHandlerSmm.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwSpare.bin
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwWorking.bin
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageVariable.bin
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_HEADER.bin
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_HEADER_SPILOC
> K.bin
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/Vacant.bin
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Stitch/MNW2_Stitch_Config.txt
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInitDxe.inf
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/Wpce791.inf
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/cln.sh
> 
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/.gitignore
> b/Platform/Intel/Vlv2TbltDevicePkg/.gitignore
> new file mode 100644
> index 0000000000..c7698262ad
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/.gitignore
> @@ -0,0 +1,5 @@
> +AutoPlatformCFG.txt
> +Stitch/Stitching.log
> +Stitch/MNW*.bin
> +Stitch/MNW*.rom
> +Stitch/MNW*.rom.orig
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.c
> b/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.c
> new file mode 100644
> index 0000000000..5c03f66edb
> --- /dev/null
> +++ b/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_PROTECTIO
> N ));
> +      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));
> +}
> +
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.h
> b/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.h
> new file mode 100644
> index 0000000000..598756846a
> --- /dev/null
> +++ b/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
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.inf
> new file mode 100644
> index 0000000000..c59920db03
> --- /dev/null
> +++ b/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
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.c
> b/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.c
> new file mode 100644
> index 0000000000..ebe783e29e
> --- /dev/null
> +++ b/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;
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.h
> b/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.h
> new file mode 100644
> index 0000000000..4718949610
> --- /dev/null
> +++ b/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
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooksLib.h
> b/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooksLib.h
> new file mode 100644
> index 0000000000..a253d64ec0
> --- /dev/null
> +++
> b/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
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h
> b/Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h
> new file mode 100644
> index 0000000000..4d98db7592
> --- /dev/null
> +++ b/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
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/Firmware
> Update.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/Firmware
> Update.c
> new file mode 100644
> index 0000000000..a2fc54e20e
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/Firmware
> Update.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;
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/Firmware
> Update.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/Firmware
> Update.h
> new file mode 100644
> index 0000000000..745fb3aca4
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/Firmware
> Update.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
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/Firmware
> Update.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/Firmware
> Update.inf
> new file mode 100644
> index 0000000000..25104a86ed
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/Firmware
> Update.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
> \ No newline at end of file
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/Firmware
> UpdateStrings.uni
> b/Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/Firmware
> UpdateStrings.uni
> new file mode 100644
> index 0000000000..9418edfbf9
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/Firmware
> UpdateStrings.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"
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe
> b/Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..4402a78456ae1018915ac4a1fc
> e5d5d5de656652
> GIT binary patch
> literal 499712
> zcmeFaeSB2awKqOVCNRK+86Zg1C{aVD1r>$1*hmd2qfr^1iHy?v1{LBE5im^fr9
> _EC
> zY9@!V*h00fwotLsmR4FVFBTzSN}@&$La)?vuK}?=!=xp>rX^yO-
> }k%rK4)e^&_4IM
> z&*$^|Lt8TY?7h$0Yp=cD_S!GU|BaQ79EZc<#J>|K9F8sc<$tB}_mlsaC>}ccg`tk;
> z2fcRAmaOTooiigmZ*kG0>V<by&%UeZ_Sp*-
> EQ}O=b8b;}&4QwN3yP*)cYV=a3+K$e
> zFfVU#u?9VU&m{%njW=Io{rlyPtZVL+=UcAH!taU5x!26Y?{!Pgx#n*9z2us)@_
> X?$
> zP4ZhT<rVX84-
> >|zFb?<}j_FxBj_NBvy4I@G;mFAvlI22Y2RIxnvm|@XLi~D>3?PqG
> zU>g5OAO2_kIywfbGUSnd^1!;REWh>-
> GaZrZ2Rg<|>XZL;1qV0^KcULl%LitT4e(sA
> zQ1ADx3nO#yjiBWAFQY%ii+$DjSuYeh9J4O0o-
> ;c#+u=Ck1~B&BtADLZd=>w{P*rmj
> zFGj{J&;Xh8iy!O1Qir3-N`LnI83jJ0z-JWri~^rg;4=z*MuE>L@EHX@qrhhr_>2Po
> z|DZs~=!|yeZ)wASF<)oQ*A?@1$9z38UvG=An<z$WU0DyhqOB(qU%-
> se@VTO9R?O!z
> z{O;&ZXUy+5Mi$Jv(oqpE#9#Brhw(zQD?9-
> YYu)%0FkgLFvH(0<+v$j$Yxp~Z=J(%W
> zrqdY7Iu+)PH_78uMJum#BnO+1U+r*6Iy?!*hR<!dg68+m&n4*krkd$MDLW!4
> Jq85h
> zq3((*N0rnocLvQ@h;*|TJ&4x!I%;!)da^oN+wG{4<Q)d;n_s*_T1?IePfj&4!ERz
> Q
> zns7#>{+ErA+bDAf&|xF!svtIOWfCU+(Pno>EAFJck-G(ia#R?v1>z&`9aicvC;!Fa
> znE8!pbACyu+4~-d_}(oqvC1+OcAq$Lf-
> !{^NMA8$8t32~3;RDApYj{ywOh6hM>QF!
> z_kXF!rp4EZJV%SKP5nslrp3p&3^EU>pLX@r%%9!99r(8$|K8%jI%)=Q$p#*Y4}e
> bi
> zGNFVkU=|!=-
> &`@@;b`q)yUrg`C+_bK8ll4#<{vQgmnw?LgSU(%nBSs`;p+y0V*bvs
> z6HgeHP-
> k?Px59i0>;r;%Hu<(=4A1mz@^24@OWCBZaLM^nA$dBh1j6Mk@^?medV}UD
> zRV2WSG8e|;aM1j1vDB|`ikv1WmHnp-
> slsF|k@X!=HD?aVKvq>BkzV}+(1sk;X_UKE
> z2WKeg24Kkefm>s~wrFjeqvkYeelN(2Ox4_0yiX)py(-
> J_w*}3;=Mg=yVY?A(F9{t0
> zmcF)tc{7B{e(fP?w$bkm#zW0uVlWpl?gR#H73M>Nbs>;yY}oeqJV%3nhi6l0JE*
> fG
> zr@bMxy~QU(iu%T*&!apBIzqxc_0f+{oIouv$UNBa=Y!v4!;)@{OThf<*Q9mnz;
> M-p
> ziA{=Ai}S&$k3d*we&e=ib2(TwhzGLjO0c?PJc=z|orUxP&9`4ix>=_KNMBL8_-
> hMm
> z7DOCZEV+K({c|1D7v4U5ei~y7KhL@W483M+0pQvUtyx&Ob+_*&u;?!Q+lhb
> AWZCSl
> zIlBWdg2DHzpMC15Rs9H2Z06Szv4LfAP(T!gAL?XX?}-
> y>TEb=cdJ_+#qo9^ihM_hM
> zzv<cZXfp^~|E6d8=TH>)nSr=}14ai5B)@``wB=vkznt&m&4w);4u40qw!`6B{!=u
> K
> zf!hf%_1{O@@O4D*b!OF6dp6a)WcW8kcV-
> 98_bw&3I6a$sjF1`KHN3*yYvnYJ>nS-_
> zQ)2i#V*Ufs+5?WrMMmgA^nPb{%~0@LqpQKc3xvu_7D%?&5gCGPquh(?$!z
> @Z)yB|E
> z%XVcogkF-Sy^b1Z(wiIvfJV?83w0!BVEl-
> 8IaGQU+K*lB7U5OwXc|HHyf^PveT%Q~
> zPJ+4$n#;c^(udkmj`NzN*l#w5b~UWZng->drQf`40_#DSG#kF=KsX>$-
> 5fNhiFmjT
> z@V(i3k#s)p+XC)y27S#6^Z6@JrtdotYB2UQ5cx3%gvJQDD$F65u_78!nn(s>6Do
> pl
> z9O0Rw(!2rFC(@2u`=hn{snSGWJ%W1Sn+2sULGv7|&c0~vKD$m8>Im0__Enf)
> Es|bW
> zWm8u71<VW8v*F(tG|R?GFMa?u5ev23uME*uDEvnciulERt<l<6y9F0oAOuQ1
> l!vc1
> zV19ozVR=h@Z4r&?yWku&>c?o%2<;D;zm+=f%*-
> cMChHB0h1M9pHHN>vq`df^tEz_>
> zd~Pc#E4t@0!@obhxo5`M&5dS}`LDMGQG<OxqS8XK<Za1;DshA0@Vc(Y{_nE
> hF^z{r
> zANkB^tqFbfTZkIR)%40xLAbPKhRh|0iZuP~tJ0pOi#8TO7iGgofG)Z<+B^%&sQJ
> G@
> zBq$>=pJNM(EnSpzI;v{@(~JBqI{i1KH|Vs9^c734n&Y^xCbFm|a>cy)bFZC!*Iec;
> zxMEJG*@b=zw)lE!f5ku!oY<7ug*K6gzYd5Euy29~)LU2EYeFa%FR=`rzjxltA_pN?
> zeEDFCNx*zfv3dVhCg-xsFSI12y}o<-
> U>{@%ywGcjmaAoXRw?rMU*cX0Y{=E}P!kjl
> z|ASlBvW!|s9{jG|b+i~zX0F{2QH8Mr)C=gi6iiM!S`LQN$9>iD+M?Pk9TWe6Uasx
> E
> z{YnR<w=vH#=StY1))wD3HqzqLs&&13TF0N=zRg*cqO4nd8<~LzsNNRe8a}l6di
> bOL
> z4iUgb*_LoYk`ET92^ZXuJ?hz@x_(bQ0I<$RC0MBbTV35{J`UbM@8GtEThUpw
> K|LG(
> zp4e2U5$b_L518k{Dx#9%-
> xxISuwGantzAz!97ONsUCJR;is9QRMtptH94c)<4mVnI
> zxLqo(kA>FhUXdf#2uDEFHbxW9OZ{s+(fd%X3T>~ih*MA8AX?CE_}7cmyuQjw
> gD*vQ
> zPLf{NH+ky6B#K~tG*KAyudni|w>#jEskaqnlkQ5x-
> (3k!T^aLtdp3u<qsP6qg`Um6
> zZqN4VxgE^$Y=3ALv|34Pg!=ytX_hc`ZBIRYWN6aO(4<$Qbew-
> (G%;RLDpn5PzQ+hU
> zW1($^Z(GYU$}<1+Y=-
> R%JHZ7;Xq&in%gz$iG3t)wJVp9E<yFOeTMTG(^Vec!L3F!`
> zEwQUzz;#0)>?S1t7IE;tq#zlgEiIxu*d7{3ajb#uqeV-pY(w`q=<aXOBpC!!MUUjf
> zLhBO?G0cXq2SX8a(R0UCCfo3@3!3j9$xtzcXF+fL<ZV$ghQD{>Yi5NE1a-
> |!WK%{U
> z-Hu|^>wvg%$!s>#`?OA}K$?CJMA%V|^!4-
> ZSTH+MQ$078`dWDI?RU~4y5!25d2_T|
> zFY;Eb=UWG2z7BZV@HS4GdudPSFu+4_I{2gXkvQzh%OKE@PGD{X$Hqck+C!
> q-w+9?^
> z!<V&0bie@=2V?og94lvo?;T6Y=AR7;JozUzH7Q27XCp2C9@x-
> Ph|(_f&xQ0@q*MK~
> zG>7_?{uJo`oZO9GBAzDrkpa<Kx1(mD>ctIJSyhwKlYseNfv^%~9eJ*JsI$U+RPw
> x{
> zaM@XzKjy*T^*rnE%7JkEdze-
> 8O0>4iQPXUVw$;CG_U}dbh@5&Apnr8p+x_cBX{YX=
> zYjmljZ2rRA@AS`JlsWrqYm@#>f_`k<N-
> ?nARZ(RvKJ9yI=e2{q#Tev6A2j&#F=d1c
> zNlhHx1zqlLSjlu;9DFFSx)29Rh7t4W^6_;C9iaBHKb`sVu|GBVkD))5GQ6k!|6pUN
> z5Kkc1mX9)gSM4D@4TFPORZ;!Rp8BVOM^&l$AV!orFXV<0_}tOSw$E`dDp!?~
> +$39e
> zz<gf37icJV%T$zsQq1>kE}vBYa^&k(`R2qFtTHEo0YuHYRgQ2z<T$+6qZGN>HkV
> E2
> zEB|UZTOk>YVV=!plX8H(OrxC@<}}?N0BsS&<*6?R-
> &q~FjQTU*+>RmB9e9Yf(5~{X
> zTc)}-
> lF=9Bb<3suiTJ6yR%0l?VOZKboRN|)ci3Q!M!p@JD!M|Nh~6vHVlht@0G6VX
> z!T=LQ^I<iYC5fy|&*tEy`ZpuhKzfjdj&46H(958PG)B?;!2P7!<P55Pe@+_J4$vrK
> z+Lj4CM=X;D1DCwQ%+gp`uv?~5NjVZ{3mrp6oVN@|+HO4NZ-
> b8+y<bfc+GL8*mh1$|
> zH(0(~TdWKM*A~4OvjojoexQRHt;`kLP}b<rZveU4TFNYP7Fb?jn-
> CHuYH$cAMa*1w
> zOS4=XXYpp~=e5uSIE+HsB$%Ub0GrnTP^0b#Jj@V)u_oHh8AO|Xdm7Q65rzSJ
> MmazQ
> zCn<8_$sIKJBN~9Yn&2!Xiu*b+lcUECF&um&!DP<lz7A+=_U0D?_K1OpRVgrr-
> T7t#
> zDeCWNylO<l3h%&2X`VVN4G_*M_PZ-%%ZE8tiQy|STz9_Am*Oj2-
> 78T&JC?;sCY+Np
> z7fDv(js?LZx*i7J*U?y-->`hJiy$nhy3vtnbdZ29FtYD#DxgG#IvOiZ!^~?i^ZURV
> z1vo?cfioO%1|VOlm4X1q6$BB5gY+?^JCwTF3Z{xS7l{UDK#gvDN!;Iopv68_qeV
> 0s
> zNeHKSD151!LE2^|ho~SN-x-+rIgGQVo>vt^J)gZ-3~;o067=)IH?@AI-
> F*VZ)X&sK
> z?MTxGGu@1|WrLfLzGm)yj<3~JSI=D_e!UfTu#J@H@5#{Lty_VZrN2}DZHuoR
> *)UO}
> z!gu>#&7utjBMz@Bs5%knWN47GO-
> V0u5N+IFVICVL3{}N31tX!(nDLT>kP9aa^c*0+
> z6^%YjJ%6!;<a0InjzPH{i+<qr)RUrk88ytCzokq6g?9givGi;T4jZ?t!I$<t%6<l3
> zS}JF;3C3XagXZHkghBroAU&JPMnpSGBU9kTMH2<o@6lZa73TZ*_tQ|0)ldrXK
> mbmj
> zt`Vs_{tKXLwb=;?PU`kMkOszuV(AK1_2JYwf1tX6?bAUJTjPv|Y<f1i5D6(Pd8K9
> m
> zDD6lhP+@7I{U~^q@4rCW<eSZ425Nrl0C>WpwM20)%g_P0+{S9!+)S6IHAKA
> A=qqf1
> z^VbH8h7yd3rJ1S<%sFZBsm-
> GILsL;Pugie{(XDClJE>!2%taqUcRXN43ENsqMYCu^
> zM2~0J_zYi>;j*TL`9x;<V1`D(2F3L+*Az91uoXer3NcCr5T$&Y$DlbmpN$qI?xOCI
> z5gi`w$pS!skul5)#pL5PNU#DJDz1MM0KsmkqaB3;q$$y0vcHZ{05O}PHSlaIA0G
> W6
> zr{+2%RAgjZGt7J_0v)^oCcBq$-
> Uwm%6kJzm&^v{|<i6okx{$6}#I6{j{0cKx%GNRR
> zO%RV8rH6mHoLLBWwZmpk`xHVI6AC3wW`e&5a8cLo(b{%Ltqw=bNPevfn#>
> E4D^8;U
> z-
> =PS|`_ZQSfH}WfT8^3|55%V+Xnq|WA8j6sNNqaAY)es<e;$ge=Jm9h!dS5<lcB
> OM
> zL^fSY;{+({2%zSE=&1svZ$`Ro{_F*Jmd~9%XKuCaRw{jTJp-T_8p#fEl6X)@>5j7<
> z(Lc<x-M*vNjKB_a!s9?6YGK&j^snh<rws305ev6;|8Lhx_p#2C3TXIyF`0~ECK2kL
> z*kt&-
> CjQH)bs4u6jr)^vUGbT(BbXKQ?Tg*gD(=I+l2F?{H&r9d)?VUkU5r>s58Gxq
> zu}8o_2lbSMx)z@em7l|jn9H+0pWZJXJlkC*dt^?!N7brvqc;q5U<#DXP23IQsZl}
> n
> z6bj)e6~dDsEs!Nq)1oh!`IPv(7M~0L&I$E;wr7tyfeKUj2k}q8nd9$``440E`x<Oo
> z^aTl&c<O(L;wrCs2Zl|Qi#Jxsl2jGT>A`FXlHxTQRPo^$+{mtRzTSX2&VJW;l!Y;R
> z!z@BX(#ipK^sBa?>NO--
> BVMysp|1fMkb9iJmr{yefXS^EgK&}0QIW&M4_VJDK~Pu1
> zyclE^=5;g7+lfwn7x2UiNRSv)EV{7CJ5k%f6cc(-S~Blc)sUTr`2lg<4%m*{0l`y)
> z7~2;~1ecvb^C1;#v;u;Vm)mZ=DcVf281<?W3s_<BdtK*7^Z*?HVgTd2bvz#IX_
> RL3
> zX5?Xzx2PXh$I~kHvw}aneTJi@o^db9te<bC6#HdLi1t0~1%d+#P`mosrhYc4A05
> 70
> zqn@5nKaZ=QmGV<R$7-woW;-?0PBD1SdW?cJ`o=f-
> p4nZ0JMyp!1P*n3qIY242uBm+
> z8$&3{*Ap<!yYxtPLueX<ISrxr>uMR$#M%;U>ifdQHQ-_hCRWmVlg~pI-
> jA&&`HXu0
> z<r=I?2u;uQJbcKFR^lwflyhTAspCZP>Ii-`GO#{QOi5v=H;R;Q%uxN_-OIBWaHJrp
> z8BNT$#_+F+-
> Up2W5nJQglnqNzShBNbkOD~Cjc{@q*0<Iq|LEBiXP4_=jx6mDLRwW$
> zHWG+FiS(@z)4qli5=-u`VK>k=S1;C}1#QCDz=Si>f}EBzh9p?2r4*Hs@}tztR8>}E
> zs2D<InN(_hT0|%&@arXAoHZBfh3MMBTjnt6_x2FXn4ZQTSU*`L!GhaH@%A
> ^`;|RHy
> zd7Q-4IW^)cHfS=84p2#ZI!%By*HnZi!Ul-zEq_X|JQ)f`*s4yt?0NarbeRYYPeB)Y
> z#Z_76_w?JLHL)`2pEY{wHHe-
> 3=U^cdW?A6B#&TD~U?HR;9|<Ys%WyBi5?*167N1B1
> zVvf<opqPJ!juQG-3GccZLI$W{z_KHf-
> xJ+6C>DA=F%sI7x$s&%^&bPj7T>asTTAh?
> z-1|Z)MhqhYSSyY0_-
> aaWMO;K1L$v~`aAn1b&@!%mbepg5b|CmH>zdYpeV%=h>LtEa
> z@JwYC^O+eZsG!-{s-#Qg)(EYtFz?klzQ?04iZIhYK5oZ--vW({ZbNiRz=*R3uvi7=
> zc{~lH<qRTqo0ln!41pdn<7%qPI8-gxg&z-^-
> %>dWucZJDk6CbBgmh!*8F(mT;qn!u
> zi6W#6(S+rpkXKhB|8cCZA1AZIC+XC5tig;E(9cS1Ps1$$+{C*OivNck{HuSDgFP*$
> z=HR=5q2cRSvf+QxD(?YlsTcZiFwIzEBHl(sT!}JjNc_NYx{e<}0VrOkdQiNa?t6om
> zWjzJ$V<PVi7<t@ig7v5pHi!V6TBut7Wgrr6h5s)rkiY#3p<}~|XZhJIV6>ykVct1H
> zvSVTl4EY-f@8e5xnunlSH9%ptnvWG`5+NA$3UBU_05g^%#x7DE>N||w-
> &?uEt=x|A
> z0f00ATcZ9>qf0kp9#k1QU26Y<dWz2&kX2!R{|^dcJ?&EXFkgSJ@9RHJz1|TtSEa
> vx
> zqxCwC8N3BZf%GNZ$$qUS&<gXrx$Fp{LmhT;w-
> ocG3Uje4hD+MZT<)8gV58tSgXXz*
> z`x@XdJENW;0;WUbG<`r;(0r*`6KTIjz)-c|+d)JQKsvDo`Y{Ft(?8~!*@z{8&@h#o
> zF{$`6#v0K}hSA3Di5?k?`uf=wpEh_by1-rq&9*AOh0sN(EMt5DN(_-
> G#w^FRq8)jV
> zxTUWDgk4``Ud!Mr7$<{~f%pY7+JfBOdWxyv%+^KRK68UElJN?dSE|Pr-
> (g4s{2a@>
> zh-
> 1|>9%`@9T{lOEEo6;2NftDJC2<GHOb6nD7Enda|K20?u$&>G9>J&MeZUE|;eQ
> 4*
> z#<6{7PS)&^@t|htrS_nC@xLscln&wt0Fk^WyojslGyrg1dn(y7w`zqNea}GIjYR|
> L
> zhS{3yatXhGa+}Tn?60x$Y;5orh~u(E5z>hylBe)#Qqx(e&|)An9xlu?n0Obnw<mi
> E
> zm<jFxNT_*kIY~T9$f1ph+{Z#2GiIpXlcw^39C`*b@M7xr)C`={d3F)em$_+>sb*{
> ^
> zBh%=fG^Yn-
> ?souW5HV#jtVmr!z#NhW`9C?+>)*rsA5h~rz|*2el#u_|sBvQ&<j>3O
> zRJ&aN*VOn3&@7za;2iGLsFC=&%=A8`eJ*S#9%Ri=qk+^6{W~p7O{{`^IxkR2Hf
> 2Xm
> zMEJJIiYYb>t=qwlB4-;GO{2TAW%t-N>@Ulq0zwpEn<IiK-
> WEz2g%Yc&0rQPvQfS5S
> zunG<WdG#9Ao<kMp*=K5~Pbis*oNf5G0mKs(VeecRl}ETyq^T%iK79@$;Z@
> m<Gfp+M
> zjZ$T}qKPak>gB~o2(`;$hHm<E8C6fNH(u4FGG^1}cr{(sb3=qEa<H8()Qh!sPR41
> N
> z#e(-
> H;{VOq0jFGx2a3a$v?Dl9%!AD5Fz@4blDg)N=r$&))yPn>8%U7DjXLd6sZ7sC
> znrpjE2avv3r^}J1kIDSYkiP!*>e-Ro!?Mq9+Tw`(&RDo`zS?FoeeQxgB4I}=qpYT~
> z5|JR|#Gs2x9j{(o>NxAmrH*^>Zx8-
> mbZM#Moynz+D1OJ`x8s6RM?HRD`ckPQ7kOXD
> zzh8f)6q`bZrvI0n<IEi}&^2iAkfH882E8S|bc+4Fy}%njc#rz&RzF?pr;|UHkMr<g
> zjxHRdPV7Dmgo`lr+?Hs5=OdCE%MDna9U*m`@``!di<)nGteq~L=e9e9-
> 4FtjF!kM2
> zbfsRXOU}&@5-
> j(CyYO2!6uJ_>!91PM*dg<W=={Mte~`}SN+K6}21x#91SC)&3z@Q7
> zf;^x-R?zOj`VTrDZ7zi*RG3ewjU)lM1FEhSPsQSl-
> rDx_p@KG$EQBNBQFx9zwg(L~
> zTs<m0pJ3U&e{3RHP^n86pmnt50YpoHORsF@!Xno-
> LIi9f>5YtFk@>^l3K>**CSZiR
> zD$IvfmOw3eMT+$>!4HA`z=9DL!nh733&{mB2%f(X(`}C;(x_wYphm;gQ4^cgF5
> ~ZS
> zRlF_yVC`o@M`X)@8v=TszZdbNP_LM`-
> sBNT6J<g3kM{<>px>3Y8@wOxVU$s?=<AKd
> zS<q())-4hmK|n9~9BD}>mb-XHt0(2N9(qAK%2f+l7iJU;12pbKW@8Bq6uw--
> >sSQ9
> zAfETKRJU04@IcL?U8G?6UTLr^V0Io?uanY?q>dB#EN3ys#C(zpOz=TG+5C=rqD
> Kwv
> z>eQ3MZdxDg$d3%r0jroa;T5c&l+9c4zkqpNt6(^>30u~@P%y)`Sc71%MhSh%P
> }^M?
> zy>l>nl?Yv8kSnnw$c38h7+3#X5`b_e|HzUSkhIT!E%yxw7ZWJBME%HyH67B;ly
> Dg%
> zJ1Q)Z7TCyTi74b9FRZdgDynI%Xi=k{KpCzd++ja)LF?=4DK2h$AvjI!5aPb{6)Bf#
> zw7TU37Q>y!2;P0JqCII9QZq%Nl^e8r53(c-
> 2>lgA@6!7d=6QAVIZ#s?lFfsN7h&4F
> zEMW|Q)?zs~WP;yr5m85X`!eP?QL)MsUdQet;A+khZydtqiXO^}jHntNe%_+Q
> Rk{dj
> z>tHsD&JORh*yloBgc0g+qUiK+w*_!S8bB9{io)JXDheRgqZS9jWYL3OX=?(D$dC
> W2
> ziwLj?MQ4NqEFy-xbP+KuMbT;D`4+%uY=CtKmth=HdU|-d1v6&D9OJ-
> H3)D3h)cH2l
> zx<d{aGL)Vf-ev*5HVrU0qX^*r7T^hKfI)J3wc7$bA{}s%l%5^--l0kGPiuRL3%guO
> zrL-_Sfu*FvTh?X}*BA%-1Hhxh(^*J5yr2t1uDU}gWa-)A`4-?OY{1cjjz|HDR#;H$
> zR8is_bQ6p@2DVex*kFOaP1iU9Hv*ghihy7Oq|JhVnXYnxRs6)>k)x_~TJ4;!t88T
> z
> zX~)SLqr>j7?!qy(QzP+Ms-0X_Wjw2pNA~F|kyJYaRF&zhLMr`6R|(qf3}lU>@O-
> PC
> z@8}vArP_fUu*wRno%y<oJJrr0Rb_+K&Q-
> cf0?ecOGgx8LX0>y^uF=98if%(xl}@W2
> zr>?S&RTSN@WFb_Ur~7kIZU0Er+3n=18sk}mL%&1UxGmMrP*y1lPiGa<?Fn7
> wvQ#@B
> zRb{@_&V9Pd>2^Da;0jT!c5c))j?o)e{Taq8=Y%&{?M%{D_OXiU&u~?x-
> D+o;uJRjJ
> z5k459YIIxe990`p65mO+lg}!n!v$5kKW)0o{8T$5Rh7xCLO%Gpu5y*#&S|Q~Ox7
> UX
> z9@aJB>sb96rK;R(wKGRoai-
> cSV3nfq<5oLUb(Mn<I@O=kRgEoHJEL_C%tfqr&QMkM
> zTkZ4$2blB36Re`>cBUgT5~S_1+WC{Jl3c19DOAOUck0f(po?$OBXgE2FJ(D7;D@
> >#
> z8y-YF&u01P@En$tT=(npvlRHzO1&(%z~7{bY3Bsow`41-
> Q+5D@lq>#4v*U#WLs++}
> z!ji6t_V#cB11LP)B(_Pc88=yv+KA4oP1fR%{~z0HwM$a_R0f79OkHh0`y0y!hL?e!
> z=1;8W9`*bk>$#h|ZnzfQBmNoAzG-
> `Txdltx%M1QVh;DhECkbGt&&bT;VV8j_tI8c-
> zXHmUaTsb(UE^HO92yc{pI7jpUApix^1lc`}cq=Tv(CMgnSZ+A4UbsJ#Fre_*!)-
> DY
> z-9dALewR&lpDE4){Pb>k6c~u-
> )VuaL?bQ`{+zQ2qF`Y?`(<W7jaT+HL|7E)nPOy4g
> zr`gKuDy@9+&q>war&WD6t?E-MZF?*ee{GL(ntR9jS6~0-
> WM`zE!oZ!JLlvF~@NnA@
> zTq!jLGj~5L`06cJ*5LiXD(6U{&x_s{T4SQ(#YANkA%;zhuirf?g~^eiaz)rRUrS4y
> z%C?*|bHy2o&OCSmPJU8AlHJ+BLRAPdju7_$iJImqaw*ndp|Wh&FT_%TW_=
> ;czt8`O
> zC1Br`+CW4O!R~gP4T&B>{0;2fUEq1RQ51N$XH!F$p9`Gv1NecjSj5gzJa@=~0A
> ?G6
> zWw`72&t{na=PH-JY;lG8Bm0R15VxPOSH^r$J*gQ$83tH;wz4sYTV;zY(jl`=nGxLc
> zcUHwtJcy4Wd&AU>VBt0ak?4Zd0nbuv5JstXh$l7;<j098;<q*~Siv;kmtAL0JvU
> MN
> zqxr-
> gHE*f1__P68(0`z~##8qD@Bl+mARRJCR&aacZwgO(;P0NMym8KGT7IwaELV6
> &
> zh^LIdYKM4YVc5Bvc*6hB!0a0PiI`1E$INjOX8ls{Qo%~i5&Rk}VtBE}3X@|}Z-qs@
> zKWPeQQtu^|3kq>ue`h~&T%S=-YFw)}*!0rln%+D1TV``lb+TH%jPGVFXoAE-
> !yl=M
> zVRAJ0iUFmn93&1PVeXkMZ%A}Hxj4BHICl_da^@HdXTfe%26ltev1|KfU+ioy8
> zvZe
> z1&c8nBhqP*!pPQ4Klr&4!Ie9&E_KYirqnTPda2_X{QC;T#gXOg=f7-cj#gryEU(?p
> zyRPI|U_|gEfh5^=WbHSCfG$gX7hFW0=UI-
> aJW~0Nnh4$*k5@&<oUX?hItH`uA?k^o
> zjZ?xOseUQWZu*5y3w_$p=H%QYi@Y*Yr{||Q`6D$;Ow<X2y`^lEocy$=7h1u#y
> ~orO
> zc?I*?nEgav`Ig2&*44h6!a#UMojJ6zc<>0Zz#0=q;d`<!h_EE&=^ljzw_<sgYgFb~
> zsGN~P1ygIc-8j$Zeyq9z#L!{0OFe;Y=Tw-_VN@-
> 3#D(H+u&Hucgdw^UDO6l(sB~_Y
> z*KFok`b<Cixxk9|m<ai0-
> T{z4)OwFv9HcNOVLmPBKpkUV`vDgEX}&PdOW9HK{Ka})
> zAg4Ir;I41RNwT1MrrkwG7V_*TcK?JzTzCH;>PboM^XvQTemZ1ZP7)@oiZ%{E0
> c1?q
> zI%Z&(Cx)q0;>&87+9iPJOxy>CMK7=^)3aQ6VvW^_`I?rQow&h9l$|KIpV*17*i
> Rh8
> z@#;x+;wXrJ@)-
> 8piQ=?QG_w<5dn(n5^V2#pM0etOMg3MHPL6+0tvieEc0qTO`mpaR
> zmlVcE)9=_%bcX8eCrZU)^`xRaUrHe^Q6Bna?jZE04cXS4cm7pTA94^jiFo5r72-
> 6G
> z3%p8HIT97W6Jl7~EZ0>aNI&#x2I&z$<9VGu7&f{RD=|Ed4Jhu^vG*-V-
> &Q=ex_b6~
> zf!Wr<s&xJ3LImm5fw7bQv4<4xI!QZvLHB6-f=bX(^VAb)#=*WxJt+-
> !_RpjbjA2UD
> zi?&zW+S~uaBGFLcUee*AwTcc@5S5;kLAe?u2c{4Sb)nmDW1v$W)G7Q)@fR^
> DP_Jsc
> zCjxue+~Z1o4|!r^p3|gOBmJ~`VjrMoA5%}N58nXIg(<Ov5xxDE{T_RJm;D}j;x_#
> r
> zBY*HgDde5Pr-)fnC(%W6SA-
> o4G#zhykDy^gdoiS(7<~+0NcD|FCidpj$ICh~wg?Kw
> zWr1(kR8+&XOFbz`s~3@%E%9&%Z03CZFcFgAa<~v+%)kAF89ebAH237CnDcik
> B5x0h
> z&q7?`o5^0geIHszk+O{7ZNPL|2w<^;>mN43elPNYeXk!nlCDPIhuoI;A?n~CB7H
> })
> zN?v&|4^Tb?&bysiMM>=5>;;A(-
> cB%3Ch`7f^eeLHw^9~5tl<1Z>PgYhC)(yD`tg1U
> zi+<xtzhC`0MZZVgDf-
> o@nW#;_Tnl&dGsciZj~_6rxC+9~kK&<fjQNV_3pCwZHAc@;
> z9~N1{bha0F7fftQR)N*9R^)-
> S;kSG!*p6#Od1OK4(=0N7h|V9Z^9SjCvMJ9S4UqiJ
> zn7^Vv?wAQrAZ5taKRd*3O%l?RZ?9NmkzU5%`|mA}wD`L04(2A_M4IjJaun{h
> mffJe
> zhMaGeoF1OTyKEy{rmGpf4`D<s@TlX<#df~68IhABM`Q*j$gtS(2V~=6H})cP=O
> 145
> zck!wKGx@9n$b6^@l@H0@Yv;rNS80uJ@@Lx6i&Xs5D%0LxuftRSRVZR>^kk{y
> a}XoN
> znnIuP*xkNwE4D12w9!|9^xf-
> zfK;+~>%z<B6C_pfM&<(3glySb=#{O7|A1u(&*7j^
> zbItw{d&)H~VHCZ~nmhBYMWbhBrhyv!xmhP17D3n_FgJJbO?P;afZ7k;W)>@L
> 5-`7Y
> zwa_nMR?C(=>=Zf>zE}9<K!y4DAL=G?61B(P#JU1a$}x4?k|F;ku;t1K+T{=bQ=W
> y*
> zJmR#0)jRF#2Xrx)Tbo2Vp;(66iUM2+=&}O4)+$!(k2=Bwyv2xd!4{Kx8uoI5i6zKR
> z9!i0OcQ}p<bhvKDbyB*L=G<=*E9~ao$Gb1E*K#C1`Ij&RxYnj5)VW0GK&<T}K(
> HHV
> ziOZ;mr6nw6-
> YWV5Egg>FybpT+tJQ?7W=?BWT15}AFCB9Bh%Tm0d`P9kOF>+cgFy~A
> zPXhx5kovi!+z?choB-v>t8LB+FYl)!7`{<g)Mt!Sy8v#2gYl~;^ntVSkm^NvAlHIo
> z4mU~<YyYAE>8~xkYf<&w#f#_8k!5}AEBO!nUDtV8j@r-O+>8C}Z{Tgw2k-
> wfb*xMd
> zn{96ehVd6$QS1Gu*M)bZA`Xz%XW{s6z<lnY@PV8v-
> hSCaR%}7R`%hP*YOAUm{}?$z
> zvmw3eda1e_C+XgQI{d1txB569E6iD{p0(r4x&UfFDnX$3@n^Shub7>^G&_4?c
> J|^R
> zkSC7#1w7!;-g$4HKq|g`Byq-
> mk#ZS5oKjbZAu)5tpmanp&GFQ)VMW~3g8hJU9N?t}
> z)`e`f@sgyaOR5S@$CLVXVXDX#RbKVNKHSH0RC+IW&|u6?yHaZ678KbM-
> eKUvEi)@E
> z6LYM6EoB906ZYbO_&WO_i9B`!S>6{5;#d|k_5)zhY*iwgJS}_x#4`Vs4ZFlmD_t
> M6
> z6<6XTPzxIr)xAgKZvk6;A9BpiAuzhQ37{OY#JXk<GMMBV6p=~dS8*}TF^Sc|Ctj
> py
> zBTYha)6sOK1J!e<&8?ibVD20q_@6t6TR$9WXaC7SY4&fo?*zu<WBmI_j9{js`za
> dW
> zsSgRT#=JN{6K#Th*d{SjoZ~+s6Ym8)b%I?1-
> pDsu8IHzqoCmb(e2g*0Ki`Rx_6M<L
> z9W_0h9^x5v4E)FO87^KEg|ekMjrUPjQq_pQAQwK=WG9CUL^zB_o!sY=om_
> $UKEe(<
> z9sGu9DYx$YA1E5B{zW^dLH}>tIt)F~f?*$&7yZB6cMSa4g<|ymDE|E!kJ<>dGq
> =S@
> z0l-f)e|G!c$lC3D9lx*PCa5N6(T-
> ZTEb;Jbc7yMz@DgsVfHv%KM5co;J#yUeXvr%N
> zAhgR%m$GZzjsBx@w!TZuZwGHrItmCpj!P@rAx9ptGXgo#h8=Q&(yw6%V}5
> M3+9uJ+
> zZP;Ap^gJ9NNIbTkD6YTkj#5YXFj!3#mcuk%;s{~?!Zcy)fcd3vDlga$Gi<URZ#eqx
> zD&a<GV|~loNUGe&1Zqa_<iPfsc7KlH_+&PZPD1VwB<+BQNNnNI@T|UPImJ
> DE0)Nb9
> z7#0jr%-0mHZF1C%2^VAAbGQ=-
> RAE1IxNs4KqwsUAqYqG?fyU)k>fELZ)1!?Mn?lrH
> z94?(4ssx|8+_Ix{>3QkokW`X;cXTdYFrDOFNs?+4k51ATW6~H_5iSOThOa4Lj`|a
> k
> zoRl1>haYT+gS1&SXVJhNR&RjyCkM^=Uo@e6lV`FM8HJ1NLOGO-
> `BHD<`~et6yP6Rk
> zUt!+&4q;e+1dhU?ngi7opNbmgL9~6cNn;-
> cG_<cI==MCk7KQ{8^#%^pLZV*JO5#Mo
> zK5L7ct5I!2Z}7dIp6l6U9|}E&SwhK9&kAZ;2=41V{I*8YzSjWK&y^0E?S0mkC6~Q
> r
> z>Dzy`x}EBoKbJjARmOpiX&7IMkt2B}t?Ma(UD^*Y$0>pR8Caz{X>|t&lw^>kNA
> *!O
> z3zyqETGV05+1cP+b+ib5&&KH@^0h5`f0Am>oEjo4L$uF2tLloc%Hjn}73PY5#`J
> oW
> zV0`S#INc;YPh1Jb4{aiv1Qh-=w(OqAg%50a=lxWr{lFSXSZLgQcZCR3c&0F=8#l?B
> zj$AG0H<n6Sz`Rz@7(vdP4Sy4cN?qz_V!z}O4iGeo_@;`dHo(Aud!k$AaAE|GP3
> Tzk
> zcvj8%qTQG&5X=ui`@a0R2=69_<4?4<88OD6k-
> )y@n6EW_Gx4M2<S=JpaToFr|Mqf?
> z->=0t68!oZjx+7yINEnC4k&*NH^#Z5onE8a7>w(6u6D-
> CoyOHJUKxZd3<8)}bE|l3
> zuxg08F3AoTXLR`Yu#<^f@CSs6g<8Y2Ql$KyY+D7YZVT0%6snLgeE_Qi%0Uiboe
> ADh
> z2e6Le02bNCuWz&Cgc%A1bG(r}<xydNVUQ+YyS0<u2(`kWeEVdPIfJ+<GR{wt
> @pKEf
> zMPJoqyyNfs-
> DYwol`rm>`Umr{ZY+*#b5I<9Hgp_rW!m)#qE3DTO_8`Bf7I~7b+X!x
> zq}p9ezlFosGex(1^lw(X{Yg`5_>P@4d_o>qBlkx(gR6kn_1G^fCMk_0vE1iKY)c`t
> zG=)sQh0L86GT*e3QQkU90e&BaUtVFC(@(cwAZUMc%-
> <SbM$iZrflaq!)1dUzYk?kk
> zGH7s?qHJr>T>owcMdd<@Z(8S2zb;~Q1lJuN>*FPe9W4fTD8GPqR9R6>$a~Ti5
> B=g}
> zyhg{_14j}54_Jc7Tcgd>;1GUgB{~6z&^S?kTdAYz_EJa9oKnYwb4wkkRhBwr{_8
> q9
> zKD66+9BStS_%yvBg7Wte(6EDdY4a=X$RTv-jtx$Eb-
> Vs5T!3hipd^8W!P*G~j@i*B
> zI)Ta^#Ql-
> qv#KA5Ny0z>hb24V1hOU;P?ZxHIv$@k3{D`+=mdU1Cs1H*NjZUpNGuw~
> z33Sm341EC2neGHKJaz7O6kTMRWd9L*xIcNjBHV5AKLTf1ShxmmBe(&I1I{=u
> u)x^V
> zI4@~RP6o?IcNNHDaF1gNlw`M@C@()zcaYvr-
> 3R;|ac;~?<{@Yzo?1_G?<GxOa$vXo
> z5rv)L^9k`A!9_c#;&TI~EpYZvLJ95oF+vKZG)_Z=wJVAXYa;O2x_JGJOu^rqNDw
> >{
> zLj(~KMG>4gRT;6{SBNJ!jUI?+Qc>_N)bXana3D`wq0#XYai`O{%i2RCZsj|W?C^5
> R
> z99Kub+$h-eiIn^vb(D-
> DOflm%R&gsWhMD>_^(>S6nQ$>d58QN#t@w<58^b0x#X`gm
> zo^pxbyr&2k1cbUvLWdXQ)?0)DepWAUsHg(<9+U)MgX@M;vrXD!4kK1CW2l7
> ODz2d*
> z%t?oU5Io+OWAoI#bd0dwcea3`*p!sHa734&FHo;Z`9Vzg0aqdMI+z7s9Pb{+27
> ^uv
> zH3B9j<*vopmC}_H>V#XOE)&442;_KgxxCAmiTQ(cINv6mEf~*$S*P+dx|U~kE
> dyEf
> z6UU@3MnsS+1b%nPR2SkU42aa~b_nm{w04r`2pYFqXz)tv7^Z|=VXUWH!>L#
> y_~!|u
> zAO7k0JOHo5mAKi@A0!^OzsmqC95cj?W}$B~5Fig0w(ef0XyEHqGv^ueF%`ZU
> ?OAtQ
> z7wNV!I*yxBh)Iu}l?Ws4pL^HB>ic;0rhOHL=m_EOlkQhb1ybypqf8995HvT5V1
> @+_
> zK+tcxLduGf<tF})8iM`sFKg^2HdmXQpy!T`$lhzX49`iePOFwMn`ikiq*7OOGC~}
> P
> zZR57K1CZb@%nt)*$32=*0#QO7XRXkUNYq0@9P&b2h51bt_!ChFq7%QQs25
> UKY>8?x
> z&rZvPQot=TI>dqdXR#>J7W3~TlfrYsTUgOVM!WFfdzT8dL{dT-`_zDR-
> Gu>pH7219
> zunQs?54_82yj*EHvaMKG59%GzF%0K|(u@!V#>0xwLseKBf;{mR23v65AXKop
> 3=ybc
> z-
> me1b7<dtzp>`VvE;h=bGpBt~5KKCguUJunERBL~8<>#s{{;S&b08Jw$e{!WmRH`
> 2
> zx`PUXDJG*}h_uDyDvXwl$39*cF4BAZ%s1-
> }(I`O6=rHGxmkAha&9Pu12=+sGUls@7
> zinOxrWV9j_TRc1-
> X>#w3g%x+Db8!FsOCN}|!MNX)mw~yse>gma*cr}sQW@Xhk9&`u
> z%J39S-
> ~a|R!GKVU)o@PJ#8d!ru5aL4YO}_vNs#8vVfze#93YUb><)tiP={!_8&{9=
> zZgimM9&Dj!UESqO-kuyK(?|@a3IAEt1J7F}=Ti?rUtvFm(i!RkA7}C>$uFoPGiZJ#
> zvp)*Rdk+YH1af|20eBDh#{iP<+Fzv<(+BkA_o}8fMB5f&h>k(aB0Q%!`2{?vF+!g
> m
> z%_z6V$bC2JYMqmdG<lqLK0+PqY*#nZS1i$IvpAr<Ky1d`yB1xs#BnV?mDg88$
> @uo~
> zzbN^D0Lba4?}6n+Sz^~(?{1tzM_+fB4x^oF4326DeJIbPc!3l}rZ}I~VI_MT%HUv
> P
> zm9Tt7^k69t+;Ptv56JdLn+gJE?+8`T-`g;CSaP7i9`*~AHu^toD3=32bZ?%<z>+BG
> z@kJZI%9g2@pcvQWY%ZIy#{}Jhzz7XE)LR)VyTp>wTP!%1kV^kg_LpdQtTox|Y)
> kTN
> zCX0%cUQ8$HD-
> LJ|+K?BQDn9VLdElj6BtUrr<{>F^TLb@mH3suz*gMK5J)>Pnr(|;*
> zimh>PMS3wWo454Ir{1rsF@^(TehAU%D^_rwF??7OM0gGJyXdaTG2WuXdv
> DMioFB(Y
> z!vhoFJa#wSR8ub4F+I<gIdixa2OWf^n?HU_`k4yuVG_D50S{ShlfZ^lBdpLV6~X
> #k
> zfHb$O*HD6c*`c*2zKrH$Wks>8Id6$JO-
> 9TcO&h~<aPPYB0K&ou;+QTN0kEFTM8}U2
> z-M9bDCb<v^W8FDU_6i-w!AYEdN;T&{9CKO3E{cHIk46=-
> i$UxV(j@juDvq%zwP-yF
> z>FegF7DZ02zZLswS2`|-;-
> JM~FBQ49RmK8R@=~yK#{H+tqX&V6W8u7wYqcJ7=+(V-
> zKY`e+(n0L^K9o}9k0DL$5wj=$Cdv_*5na%Yw8bm7{pmAbQ<#fjPsa2EL(YQ^W
> QiWR
> z7m3>iqL(@%6S+8xtshrAJ<mdt-
> 8q=8xe*ufyX#<{9i`O+w?MltOBQlIvdaZuIk^or
> zqPT`tmta;YQfo<@wuciCKX2da1`HiPw`kczG<e~lScFpaNm#doA#VniIubXd!-|};
> ze-
> `tTeB4*aKoRFuU>cCLe1fLz3(#4PaqZDV19M)%WF$Fki)3J_xMN@rKLyhT+UN
> Mq
> z690bB!*8Q5-pdK8(0R8o8qXNxaB^_eu{WcKxE^pk+q0?(SE*s&u`0;S#$2-
> <Tfa+$
> zBEakx3$sq%DZneOx^jG-
> CBFSwa3t*#<QGAr69^`5MvwK<Fl3}8WG=o41CZl8?Ab(B
> zYLxY1f7mBA%Rel^+QZ40AuyPrRA=+z`7ZJOyAlHcRT?(g@IX0P#@H>b6C>JKo
> b=tB
> z!Eu3mz;UyeX{$5=0#l3!4kh_*CQA2few%}IrTP?x46?|}N&E)K2J@&M4l6eS9K
> *7o
> z(n&DN)EqUJljV5V<9JcA+*1!>@_cC36MHTC77Jlql66tHJ!`|kxC0>YTnfXT&T@i
> J
> zDfq2vs~4!J^IK0Gw?0TaZ()(Eua3lK845%{aw{t;it!#mC1Jd-OwPL0*M+Nl(3NG0
> zKcH2;&|@!L(yalT^M=u8<s{7&K=l70T|$WSEYSO<?|Uc$HJtg=$RRR-
> #T(pOF;3qU
> z4WrzV6WV`is2iulNzr6L`&V!}N_<_53$Y9iPFFF-qlhUYqG-xhStb`)OkQbca|UK-
> z^nzppF>Xl)XUxA3oN*<581Yw1LGi(OAjJ)yGIK;wZrx@26w;Po@&wY>ne)eyr
> dy)<
> zX8P>KDYpdU1!d6ack>Qj_s$~_dRIdL6JYnw1g5??p`4vMEUN4wYIru4X7B9qf-
> NAc
> zSvwE8a&}32SkA7D+FJjdG#|^*Kiofu%?L7jm*cP6OaOM=C_5xDX%JziKI%-
> IjS5=l
> zVTKLm6P!RL2~;qZ7>{TUp0<kC!Qn`_H<l7jjzX7|ei{b-gjzXx$BldVa6lHZt^({a
> z@I)E1KrYo1K6gQ7EE9r(q8Op?x-hCZvIqE3RJ=u@3`eD-9oZ9Kj`l!N?d08gI3OVf
> znb`<(9l)WAQg|&VE4m^ox*}0@`_mL%dNvf@eki(88eI-
> hEGsb<h$R?e0_&(*3h=_k
> zG@HtCzC3!+HSx{p2QJU5U9r$Uz*PmA*$C$C!#rzh{~hzPV_xYPHL%sO^lWsD
> mu_OV
> ziO*`~Fam`rW8yn-A(FTD+gZ&0qQ{-
> m*|xOKre~wGZRjj~S2!}gIoXIp%6VoZ8&*Vm
> zj`?FBQk;brw_sMcOwC=_Err~8zNO`cGuAg@<dxiDkR2OPZtc(5g0!VmMSp!_d
> `u#G
> zI&cv2b2`Nd5I8zudPF~F&MGHZdf(hxP05DD;NH^6aEY|SwnNCw7~);YfyrN_;X
> kJq
> z_+JN<>8>&mGeV=U_YKTPx#dH}Sy$VK<w)D}4hntB6-
> e2Of4_gejQ(9DdONd!V=-6|
> z7!$HEyri|JzkdBTtzVZt09^06FV(LSq&Y0QU(---^=mHc>VDmfbbtMl@#=TJFFJ-
> +
> z5Grao*TJx84{^qHN#+Xhpx`fDAQsPw>sy7#Fbq@Uh{;t^iZGtyO=R{LfwL~$|0i
> rN
> zVY(xtr2qoElE9{x3taplkbeYb-iifOAf4jB@hG-@$jL}wKlk>?yoC!?y#M6+5d!A8
> zX-
> qj#xMWtmNbGsuzEImknWkGiy4Hig88M*U#?0&ksYIn_1(#`Vuu03I^ec47?y?;
> 8
> z*o$njLUQZUPt|Kxm`%DApp_ONIesUa@x>3slB1p7Q-
> ^1xiQQ!*<W6IF)sN;1zoV>y
> zS1zMSCYrlTM`2X30jHO2ujXQ3LL`i|(e~mbf5y9&^X_p_={Z<WpkM5zUo2ZyoF
> ySQ
> zoGgld5@P6uA<Dr-s}~Jan0~<zgyZzU35zS$aEK3kTky#T-
> 0ot%3UvY<*2{}c0XB!q
> z-y8E1LAp7sVU-0z;kQqn4}xUiG!;M+@8S<w`GMmCK7-
> S&_bY;h)I7jaCexIQLS@29
> zHKu)kmzfxsd97&50I=ve>9?SRkYd1;MMyrECTr{Kz=A`7Ia!dius3QlWNjnLEm_-
> #
> zwB<*%B28Jdcrsm${7?IT?BxExKs^l8ah1A0p9fI5{j1aRSMAkp@k6zq!D3rkP9Ht
> f
> zq4npl)B3*dA@tpY{#t$C8_DSV29#TUZ%5kddo$9f>N^#v^#7#$-
> {Jc$bHH<va2Dp>
> z|B}U9E8MA;=bu9b)k9bcoYJ8!u;Pz!ZF&>mWd%Q2w^ci?SXVX5igJ9d*aXMV3
> &gD(
> z^q-
> NN)7<q<OX1b*69$_jSqK?m*IHY04{jhI7s3n?&YcNPiqFV8ArGC1GSrx4OkXSV
> zW93)|!}m`@CU0tPjRlKhQ;Wq#cgm79jIuJP-
> BFOUX)(!po4S)XiU+N?bAWg+Dp>R!
> zw>(A9^O4@Cb$AidjE7wn5qC6w+HYGaq3@^0$2g6)rKktru9F>nJ(vk&63rQQk
> 1-XK
> zXt)cApmfVz2XsZg1OPDSztq<Q!I#<eHJn6ulP+#Bqu%BDC9b+45C`(~jN1dQM
> D%Pj
> zzCTpOVWZ<o{U5x{dJ!41sgtQJ7(5HZ&?{{w`~uGi(hROB0-fjpY;NDeyCcT!Lfy+y
> zH{E5H{`b*;_$pBkCpEoz|D-#s-
> HT7dXPBU^Fp~jj=hU3`N=63$R0#uMVPTV({Cg5U
> zn}84aQSjMt_ow5Nc0Pd{mp~eRzYH|sWm)-
> f2oalffykId=j=hGGWlnmOVFsGeQQ0y
> zvpx6Ll~-
> c<B~lihaxYR`<ID>qk&`zce@pV1xn!U@6BDfDEzv29q|QiVB<qxn<RePI
> z!qUsvG7pG6#oxFeU#AiSfR9&z_SW@wY8=8V7h$8?bC^iLv$9q=<v7W+i&6up
> N%lX%
> zcRl6@$#0$t-
> $s^B>w|B;jjv^dT@`ERpewjsbQXSs;m3*e$D%eekv<NqoEqo<3BEl8
> z6}}NPgv$<$kwX2Ed<1>pX6dxG%p-mI8~1-YzH1f%-
> )sB9_v%yO8=bNO?>MTx_Y8_o
> zX+YAmBv;}!|2CssL{z~j{dZ&-OE2%!kxyil_3T5VNNpy~zrDbsc^bX(m4lL8cHtfm
> zK91=3mgKP$i?fpx;-MleazRqSi-
> j<A1@^aDaY$q%8yVA2Bj?zSq{Nr<Ti3~JD{=k#
> zJ~*#ihk(R7%92{;++E*;sR%CX?m`u84#D;Tgu>jhdK1sd!7cJjZ4%ys)<rpuI4sHu
> zi=p*zqaeO|KdRz9DU>@Lmv}uN114{TWB{iAFdmJ#{KcxfdgP^Pt0fDI=(>=HXL
> PBT
> zr<SY=`ML8k9D#5Xd;jns0hK$df4qm_i=r<QPe<fBBhExH+<{v0)$CJ+`Hg2;2TRqs
> zb>%`hX*d?h(m1;sG%r)7@zs2+hzlLCUm(eMT!}W4Sp&bvvpsM8O6Z@LBWH
> %02zLRF
> z`QbiPAuhuO7q_vRC{%=d*oX%A*00l1z_HA5FH2RM=2lf27vcxvaiWd;#uN(4V
> $b%G
> z((Id&(^a$1yHk*B)w^LA@?=<+9umwkMIRBJG8R~7*A8yUl?3~O!_b^2=fgtbv
> IZ|9
> zX+rQm2{_mMiYxAGD3mrxlYn`;#!pqW$QnH&4e2h1i}8YabT9HqivjH{1kG`$%
> Ne|2
> zIy{!;Z&>Ajc|*#>6PUZz%59fiSF{#auuS4*qXw?0w(xt(lvgy-!jt&sgVvkhSMZeY
> zv2+D|k7;*`?*Su&W$0tg+)z&`fCW7cn@s(u;$h2CS$H3e`U27-
> 07yTNG+7wR*RdXH
> z{f(a)^YGoy>DXd_iTrga`v?c^@KK`2vsym{{FH@;{E^hAv&$;Kzn}7_sIxiI%%cuZ
> zy{-
> I5UM6<4K)LlTffDVxq<V6=6eI{o@JDT$fy3~I%o_5mE|xJQ*O;AxmwR{aEqHPy
> zFGyk?3?naP8-=8<WI?!rptfjG*b?_`1qi)qo0r}j!DlVG$-+_f?<s07!JqofDx(@o
> z(|4A>&P(a*?BrQ-s2Onvpyv?7D<qdT!=Vx9MNzaII9L`-
> ^qCt21bx;GLD?F`3n%F_
> zIbu7>a$GEyo%I*Oc3Uia8TxBpMyVysUjLdDDi&&b1T2(=W@momHpN2E?;;D
> aVGw0=
> zSRtg>cUn=~;-P&=lRvCD$|v<de@Q?6hwpn*|8;YpM$fVRz-
> yBkVJ1C$?#Q4g7~(1V
> zMlyahg_ttOM$(tsEe=;!pYeowy$yv>G50s-F|}-
> GR)ZuA@v*q7A&IpFMjt?cig(6{
> zwj{9szb(aYr^#$2U%!tlSJK`$Gu}_=_c00=qZ{d{iPZzWB|fbE@)7LZQlKH7TZY8M
> zri^!3e+nx&BJd(ufs11!85}512gKWLj67D9?|QCfO>WA}0H*ofx<BwFz<QJABlL2
> (
> zfUSerT%}k`(AY0FkX(rPgW5--U${kHK-
> BwN3I#^7b4Cg>Sg@gbsn2|GIJ(<{mmKJB
> zVl)!TsgN#-
> U?t)Hq6OS3u3+Wlu`4AzmmuV#;|q8P#)n~Zm=rG3CJyjX8kE(ITsD2F
> z&sB}hX*l<QWuet6s8TIwq(I$;Wi*J)vc!)FpvE=si+mFpOE74bdI?AT2SyL}<Op>+
> zPvSBrj}jHACN->A79$`h`Dky9dKI-1?Ufhpeqas8?nhF+g7bv~GU%F72cxKuhrcr?
> zB^bg@O8<7w$NJQ&t!JVSCu^F%%%g|wpQtQa$l3-
> eWOxU;I8hjg%cmWnv2XDZFR$uo
> zg?XWbz%cx31w+I7Io@KZ0E+oZs640#tHOD4e3T*FMeSWst?q(BrB>NmU7)yl
> p&Zk_
> zmC6;f&w%-7p&a*0VRRAX>y}^$Vk+EOgCJi?-
> xlyWi0}je56?`sP?_FBUh)YHObd`C
> zyD0_Q`#sM8Z%<R8i(h0<=R<DqLpIg<N|40iT$L6FK>Bg$zX0+Jk>=c=$JefpRL@
> &*
> zhh>5@cgRqFJNu32o=W<T13H~SOZwo)Skm{ba$XTO<&C=5Db$xyp~csUznIA
> M@L<Cz
> zYduocJ0DY6_)LpPq$g5DnkqpZH4KU6cw4SRTZ|PHP@e~(CDP1Ce!~UP6<O}<
> M1Tbm
> zN{kLelRXr_<kfLpSYa^2{3Kiw8GqGsF@ous5<JhAJ5nvTAX1DwEEEIeB_D=DSC
> K<&
> zcvh~)@SO8a4i64rVNBket;d8)<8hS20g(L)>yS?WzM;^&NW|b&9}k9jtL0?*{Lq
> ^K
> zh@c3=a6s0JlK~LEd@i9O0-4Wc8a$Nv3Ti-
> *LR2I>CVq;SKp32|&W<cmgv#MJ?W#Zo
> z>>oHSdN8X7EUmwefVI|6sRZAKYgt)44<eAD(%Cx?dUN)~u$x7`UaMyJ>dSXn
> x9<SY
> zBW!xU7+r)~<tW@zM6r_R0XpL4a2cU20UQyroaiAQnopdI+G&x)1K$TN|2Rw
> 0vIw;N
> z0n#>qA4aJ~%R!H&?hxrk{#6SW%&oS9rkcpsqgFrkpQ4?gu>NA{m=r(9NpRYP
> yD^qx
> zOBAmZ!sPalM+VSeG@p`yojQ1zyxCferaD)v1)L&y16<B&luZaqW&cV^i29N)?
> yUHm
> zXbVtI+E~hHvzJ>N@^z$osJ+1Ed>mx@^=*nwT%f8(TKVDB18x*sbh?;THUAY
> Ot!eVL
> zg*6Kz7BgCO0)4FbP`bGeg93H;j=k-Q8_FZ>xO=hP@n6W{j(io&D}@20HQjRr-
> 385F
> zgTD{?s)PZ?_r`lM*W=q`Q*Y1LZ;OY(4JYFB|Lj)P7qJ(0osXkK@K3|&!`9Cs{cl^1
> zT^KU$37jW9+1C{Ch+o`)4Ey6jG#T6sOYsnjp^T0pFsZ&Did~N8%TKYYTYo>4U((
> pD
> za<CN;dMnO4?`@VkunL2PwG)#8Ni3E6s*(8S8-+Mr-)Sr#)!^TS%-
> v<9$ZU<}!y5cA
> z$@4H-&H*X2#U;UaM_&bv8$-Jqg7l#p{Vz3?;}|eMwi)?+Tz&K?JPia6-
> <+cI09>_W
> zDX_$^$k4KLU_|s#Y2;2o5%+<+ScL>Q?AEM4HOdnj6=s7Nd$tT6!q%~(hn)uc8
> M^m#
> zan-
> BvGPe78s@+HA)R<PBlarW);@z@gQ+@#yQg1!ax7t!~%}jp_JfTdW^GD#~7jI5
> 8
> zfr~bA4ngJs`!7Zb*&lNV$dtp4+F0}8Z4r)ZkmkOO0;DfTns@%wCQd-
> Qk4;Sf#G|iz
> z_TssLh4W`u&x_dWxP9e=x=nmp#J3so#13UdPE@ps=%m;0>)L3)c)I4$I<bPbu
> c}Kg
> zOc%p*ly7G5iH^`)-
> R;Oq4#24F&Vsw3<frncH2JaQ8BT@p84d`AT;P^L7|j#M+Hv$8
> zr`DIjn0yTJ#0Trt5%crfYX&#^KW<Mn_&-h_YV>`~-
> e~`=PkbCW$dnVGE<}jmEk|__
> ztH52QFd)6V$!+?Rl*zXh6iXXxc%Qu9puplQY}i}k<(KmCmsh3WTNa>r4-
> SjN^63Wf
> zEStc3@SR8tU-
> TPh3C^M3Uk7Hn;v3df2jfG%4A)J~m&qFtZqzwf>YzN@`S0L|@M4cK
> zcpTWE8*IRbtDWP@okRTHX*sTO<*v*e_qcMm&cQ;7pqwHOQqq1OdW((1F
> &Zd^CqZ2d
> zIb<-
> yFXoD7xEm5B{VuqHl{iM+T2*rnl~1^b@`lSeV7g2>Ags@f*HTesbNL!e$Y=jR
> ztFg!hgcL4_;3b?j$4k$tmt>Xqv7lg~PU7%W@A7iiI>}XQzb9%Ggvo?}D;5Fa?lcIY
> zbO^^Gn;;<W^T!aNcbsd&uaRxX>h#d(banXN%M!1mIst+Sg64dv1B@RC!Wmj
> ccxDRY
> zEZrVE_8#P4LFT@?#}E+UljU_QM-
> Pq?Px<u7mme@uLOkd(*2Bcki)CsqVVC%ObUXK^
> z+WCPTJLY0`z^u(^=c0bw87hchuWDKg-s^5u68vf7-z=E-
> 9sfr`lJMg|Nsa#uR<g$*
> z@k$Wp2_me=|2^`&c3r+syb(Q@D`0T1&`nQDpXq`6dP;oW$QOhYw()ha3C8i~
> >UH6S
> z_;rGhBA~ia_I{ORb?j9zV;Y}}{PkI%OJ5Ir0@c%F0{zkB|8hOd)(=IX8t9a<K3Mo~
> zwEw@nJ}3(R-0%TVIP9*$pLSS&q4ec)1~*?q0Li&f0C3L#w?DWNE<%&$(-
> kDego#a1
> zgr|qnhJf_ve!(%}8ANS)27W)0gS-
> mAL@x9I=7nPxj|o4{T5TCsBf2Uk==f+S2oGbF
> z4>q0$?t**qzkU^12U>>;!F|EsXU`@j@A!X2zWgPWIvlCFL^UKN{EzD`5`umydk
> h7B
> zpo!=>F?$P`Yd~nEwVsZ6DQF^9H)7HU#)M>|7$fp9z-
> bvugD2yn<3oEuQDv6pl$Xqe
> z>7L;0Bmr~gyV4G*ot-=c<x}E!MT(@MYg5=LH2|g8_-
> EF3hs)V9XbzLZl~N~>0jLQp
> zRCS){8h779>^sUPD)_$64rvy19rRG4h3KPrO}r;B<f^7}_iQi6YR&HsrBM72pavM
> 0
> zZ_^0YOeql22cIyXla?Qrpe+cCwGi+w@8<pk2}GyhrZlX&&A%a=vtRDr=+!&Zxy
> G*d
> zn+vhJ7caFaIn+iI3yzkLa|or}0f5)A-
> wp1HY=YZ93@(@K0o{&P|9DXM4+j_b!^V_^
> zdXd7RkRIhOVXsMNh4~X;Bjc{%^d=U=I}xlIUl5C>&u)5u2IqJUtRe#toDI%FnpA
> =i
> zItox|-
> L+YawECWvim0dY4^;VADYGdK<mLhuheATJo?FAUoD`w|Dg7g!xFOp~cp_lF
> zBmKcR$YBx0g=xQ&_ldZ?Yk9xwax`2}j(EYxvjiViF9;+I*Up346bf#U6Z+yDXX`rF
> zLinv$e^9AM?MG(#0x`JQ^p)5y2<hqJ<}&yQ>lIWo6dk=wVR>zaLVv(A>PQEsg
> v$`P
> z;NE-
> W8Sa%q^Dgx&!QlgL@H<`HaR?yYuyWczM%}o(9&<a~j{6$Or3klIRj}bNf!PNm
> ztPp?Gi7z%$w1z71fVVCM?^OOLcBKHre)pyD@I=Y5#h5$vI+iFt%oaYxV7QEFj
> Ud|X
> z+XOQeios`!dXhVYp3p-D3Tf*ME-2TXfFlTb>Bbx*JY5t44j;9@MiACo2>IRKilPyy
> z5Cn#W1AK+i(kIm`;TfVO5guKkGRPw!F-8i53(z&X-
> c0MoIVvOhqwvkvt3mxLPL0Yq
> z-
> hFM_IHvJuhQ8fksRHqZBWIBz!m|L<{OvW;8(>mlejD)z44WFc)6?Om$qV)yv^X
> YB
> zB3;PlSb=b1gQGCbC4hp7E<9KK1atKUeWnNOJmlqOeWnNQJXFB6>{?Cf^G}R
> V*;g4r
> ziDG9N?i@H=S6fId7HidyTj!ytajF-
> F8W`!^9On8=56{)$Z&}vP4p&aAO7kdzmCo7O
> zQIONhi5w441mP3or#x3j0GS>j5kQqcaOc4SMguYB;fbhALvE|R?~z}yA;Z^g9So
> @x
> z4#F7>5X;o-k>DBYn`PKwDZRixiB9ZYf*MS|i(n!!#2Ep`BM<X(8g8iT!2voc>5c`9
> ztBPdD;uis&nv&5+5&$E|jdh#L#=^?snyD@h3$_a@<#^?EAgAV97*7PI5FB<Hf
> &9IP
> z@EZ%{OO9MA>Md#YJn~%tPs<wDS{cKK;Q1DWsjOgc2N+<;)O<X}@TFO3k9
> &(8OUjXH
> z1dCwV1ST+cwM=CMf=1MUB0?!{+j7#%$EGrJWR&4bI8iD1I2^tt)>7tmIg(s)Yf;
> C@
> zQ4>c$k(s!Oc0eIWJjU&0{a6`8NeJg+f+Bc<KT>#UCmQ{QKI#8^WAJ04gk`fE2M;
> Fu
> zT96H-
> MEDMy_!!t53nP}B_%9)duX_r&t<_$NB3yug7jR8aqp!QcIaqQKJW_qfuz>4a
> z##C2HS#fo4f@UqTT43NfN8%%-K+*0>NItgCQ4s{pRmkKZ60{3P+W6Us9&D-
> Wt;Bb^
> zB%HW|;l!m-
> 7wD_1Cx5SU88tnP&I$ctfg@LNI1r;?*u=QnRZ?DzlVc;$aBn4AVB^VW
> z64@Xw7O-
> d<&c51a6s=G`iGD(X{GAC7W~H(G>PeTdV=D3){a|!;xsZ05FhE)UdA^>=
> zNQ@p;GHVyXVz747YiCZo`U}i~j^2|1-
> q>f@8$CXH@ea>sX5w3On^tAz50?Y+Alb!g
> zrHOBYnyPZv1LyM@UkKcep>pi~3txrd!VC|_XS5L6mD3fgL2RX4clz^JrFA+@-
> {DpF
> z)*`$z4tfJb&);hTxk@{9@*A~^W4j6m%hTYb>Emc;pLho72Cl{T4?Xn{0X%lR(-
> uA?
> zmXW+u8Jk*&m_cq8oB|Xm`KH{UU@Wq<n7b<B*Bt@?=^MW=4hBNZ7-
> Tg@&Vh=rs2VN2
> zwI6jjjqex0S_Poe2o{nj@IqxQP>8xlFn{L}ig%^4A}|S52hSp?jga4QZVOy`wT!Nd
> zf@75DpNGf*Mpw9*FR0P=%joLN=>d!`hregf5imDLW(pzIzGyK3Z(lpji)~ucqo7
> )=
> zq7XpUfjgI7c`|{8Kl@$3!+VT#Vc5s2Jq(I9L%q0{PUxPhFwm~h1D((fRqPhwgg`?
> ^
> zz*?5*lYgQ6K@wk2WlV8=a$o8l2sK2G!VOaJJ$Ffa?J)fkzT!^ibtK>7!1>X0^&-KO
> z0=PRb{#TBMFxyV^EFcUj;o#&418dG#hEP<Uuj{<BeE8P>E{aJPnqm+TnD!()0I
> Vn4
> zGq83LRvZ}@P7W3biJX|f6McgFOl|Wob&NtI*68bLP`H7)`}QCoi;LG)QGW-
> `cNE7H
> zFTm>2I;6+5!`Fko;h)#wtbT$>-IbUXqdIh*AJr2iO;7TT#31l`8imgKgg29Kq3ODv
> z)Gfg(s@1w(q5=S2hfz*PHxbTJ3z0YbGI<32QP;TvHEzIy$_zBSbsQc}T2QHMk(G
> oj
> zM{;<jAxVX~Bt4rY+#mhG`yh1HYKBZJTc(Bffx2(%7m+;mi|DDl<dxd-
> p3MRdUW{i`
> zepaOc5Nt(*N0iO8$vwC-
> HVv1iJO{WBpdIo^8fL0(8Ei>vh&VI%V5tV<*}TfXRLHAw
> zpXS@Ai?&0w9OM3ByuP<1r(M5V8C&IJL&=|F41SD&_@K%>obg)<-
> T~VAygCXSwJT%w
> zv!vH)xCl)YyGv421`G(6dGKo8W~HIfsWjpOVegT&h83RveEsUUSL9^MUNEr&4
> pOX7
> zuGXc|<K73qs9%<|zT;ZuM91DkHpCge^=L=NN5oK)NtllinphrUKLMI}?1lJh`bZ
> ^o
> zyc`6`*AOdXs~1USs}7$^c1DUdF4*Q>+2X`Js-NawfoR}+sH<-l0KWXK9+J?)6$Ru%
> zjOrZxXtrTe^Ba@EQT>o@Jn_FlQ=p5?0_(sCf_Gx8xj2Yi{$SNDJGljKsXTl9)#G&E
> z`kXy@VWzyG-;*(#sb8_jC?-txiJUB8z|5mG(XlzR(pW7Wh~-
> aB{vlDUuw~n@13nIM
> zWh}0!sfnsa;5djFcL!qeNG4+AaGpRjw;meL@*N<dv07EkMt83S=A<uGaSOZ#
> A&_Li
> z#<eV;O6z020eNOgWh@(mB`L)lOkz0oICD_WYsY~AjSgqPab?C7hB#1fApnIGp
> E30d
> zF?j}ff~efn0gjTC#evjz(u2e$sG#0PZAGhWoAyFch@nVr;_q;3U>?*GV9zE*IbJ
> B0
> zB|v?*^ZXww{YKsH*sRXFoQveeNUujTOn(9CrAQYeU5xbgk=fM|$BlF6-
> 4Vw6x2%F&
> z?ulA&Ir;ow6(+Z^6MvU|b?^wR<?NbTl+Y>JXP2az%#^;TLa+NktUJsfSF&8Vzm
> >L~
> z=FhgVnbxN6IKPBj3nMG;x0smNs;Trnl6w=s?AKskfn3XA7GPk&%TtvfDjo)G;fS
> U1
> zL%T2?qMw9I6V405cG67h+R9Ub?SyXEnHXGJQ_P?Cz~zI1r41fYy8}HzCjHPAU
> K$}f
> z<M^JXY-WO2M$4P+`A!_2<SV#n8qDbHfl>J?-
> {hIlQT*^b2)p{9T!O$lbPkPa@@&;a
> zcFjml-
> WsbsUm05%Ts04Xu_a_0+YG9vTkdq*oO~mBj$mej<HUD?spmMPTj#_t-~h2$
> z4;k$7DS^Wt(*|=;Dyle-
> %oUF<%&`VV5kJK?3^B*N^yalGie1zB4bx=!W&9KsFQ))8
> z9+#_9S^dYTp1%4a>wzcL58L$@^jE*KC70f>6P{@y8Y)0TYBP%Mxj!rb_>G<m`
> T~Hz
> zpx@6u_4`-a@Bi(xJ_w6HTA=qgfq6Q?Kk$Dr$dDnu3k-@6!Hj6FiNi1Wn-
> !UkzuBJU
> ztzevlFf`-
> o4}De52=(F{&zgb3)v~QD#^L+2D_O<Od!;*NX%OGHk?XM($@CI$41){z
> zU+?*=nI(a#Vg+4hTlriQ9HE<IbcRu^$i;9-aPd*(^Q_OXk?geM$f3IJe60}R=uc+~
> zi$?TAol)mNYb+-
> AhXuzQla>?~ag~8a{*SP@;$$oYootDM=$P@eZP2FkOH|C5gFgXj
> zD`q?$h27AZPT)Qh>FaN=o*lV8ocZwta52W$im&OIPD^gv?=UgJe=WJIR#~Zac
> HZ-L
> zYULAF>CES>)U=;lsX2CDyM6=0@zhGBjXeI%;r9MkK5~2Y3fTvnZ{#t7^T&DXQ
> G$r}
> z0pJ0OBK4+9nMdFs12Yu!KVu|Qv5}={w<Whp=bANO9E<`79@`d$mzJaUT0$?
> $CG5oo
> zsx3rB4QU--
> sD+02DM2TXpkZ8tCKeHig(1yUm~0x4Yo)viTNU$5vX+ces6=<c)a1v!
> zTevco9G>(V8Vu}Aer&L{3bOoCHCCX1I#Q##fl*zzq_AojEX4>cX`G}7LY>89pt*4
> 4
> zh-cF-xm!y02b(D}yOR!n3^W?<CGl+9qi*7pvId|?sOV`-
> 5(+@cNFfu}G+aB)0?($_
> zPe3cB<3wNdzn);uN*k0sxjzq6;RL^*Vtx_!-
> <&lHtKN=tFihmOTt^XR&gL&M+^{T9
> zZ9`T|ZZrP!Kj^fZ$zMh0hj`P-
> V}3~<>pb8#M)Ef{l6lc7OglV}AX@HN%N&{O<!wNU
> z(^|Q2&ycDm^4bG~*Yb_0SXG1d_dJNr89h0*XID8qJ4UiyLC~{lx))1bZ|4bu$(g
> zg
> zv&U`*ys|;!(Twf*d+K(6gyw_hv#KhCtr8F89-
> 9XSnhoI3<PpKHBv<!A`Vy0VCB6(f
> zHus(e3Vju{vX(u{zN|RNHbs(1ljpEwDqa}^Mgy-
> twGJIhMQtG(a_AIMTh>}U)W~Cn
> z9Na?y^WGt&V75<IuRf0wm9t&vQ1Zi$GJxNpbEpBr@JVogqt2lwP&o}chZ-
> T=aS(Nu
> z=p1SWt#3*x%hWs-
> =1g5m?Gv3MI;dvcT9!?GbL(JG^4LG_Y#Q_wGwP=BFWoHbHlRG*
> z{yLKHq%Ap)`jSm5^5+zG)e#vgqloXPULoC#PGLX!MW#F^g632!U-
> TUEM>0`ie%{I#
> ztp_mt#d$X?TT~#yFcCD5V+M}_h)xlONH9!Pn1`%<QI7z_-
> +=k5l`Z`y7$)%jK$Q<Q
> zf7KV$Y;@Xq!#C@76fx9;sGf>b^uoL9#ZAmb4#z#CJv&0ZYuUBkPHz?qjFH3~6
> F)>r
> zlP{n8bqB^~@i2LvT~aeey1luN0~!J%Xc%0BhW&`cO1uaSGq6ShSUd_6L3UG3v
> X_-H
> z=hewQ(&5UMWglOTAr&Bw(*A%PT?Fih6Nr%~Z?`zXvdRCD6#&sUpRj%$okB
> @=dRCZd
> zLqrVGQ;}}Z4$%U@x9(*}5fEU6c1NgZt@P1w2aqA%z}?#U3<>Ghjr^$+n%b){B
> 0)KY
> zEfFQMv{0xIC8K()U^%bmj3fEF5Qq`39icAa8qW@Qp#J6B^X-
> gEBaix}GUg6QUK%c4
> z$yR1zQUPQapW)dd8ZeJChqk)(V3M-
> 6x=hJ5k*nLKdWcmm^_nVboRNil*^f5*js}Pt
> zz6S{h1Im^@I@;<%&(E)1ON0XWPD>DeIM&u)kUDOqi?cx0L?Lq2BN9NyhYR
> w7WAz9y
> zMz;fjA;ijJLhR&tf)ysjq{Ho{3YHu)B8dST^C0K8QX2|&1F5S}#&>Zr3{p^+P~EX=
> z5yKpzf6hqCb_`2oJ97DMj#!MGT*<`^RXhCMmx@xY^~u^9;()lTZdl2#2*O?5vi
> 5}Z
> z&Y9q+mzDk(vq&bw3-
> l3q)1%%_kbJgI*o(_3OS6*;0KP|$gHVlpu6oZfv5D*c@dPpt
> zMEy)MkJe<ys$Ju-3i43E3`#9`;zba(4=Rbr;2;X&s7oppvx2RZaZ-8yE}M%)YBD&h
> zM+sk_7gfEq7Zs#5mQ)QWu7t2FHq{~{0VG8N0c4XvE!ur|f~|zpOjery0^`7!!Nq
> 9@
> zojE&=kqVjRWn^%QkJ6{$L9i#3k(J@ukw2Ahmb6E}9#m@TMJ;pxL0amyLN+V
> <qR;w8
> zTEp>GE=MWbqomjhM~i%VP6)g!4a0d-4I+N5a-b*_-
> O}sm9FWX<OA(R1Q5}F+4D-^M
> zpS5fkR3#Q6<hda~D-C-
> K|32SStz1h*Od|E6z*Educ?7=OIhf)J&<Y);$yB#Af@z)5
> z-Lg=|TPi30ty6a0eoM8^&Kh4-
> U3OkUxlsAko@*#vSng9fVv=mufxNhaS`R1*7o*+i
> z_G)c3US>*eEk4i>q6<XC4bcUS&cRyhvQ$;9l5z1R=feKjF?~KHjv%cCT{25Ci+Ph
> q
> zw6sAVgJEj$mDO`H99N}b@jdNLly!I5QH1scBPe53tuXft6)k{Kla{b(u3EBPTfE^g
> z&r~-
> s0ps8W{a`HooNs+EI%9Tjt9p{1VghxZn;6DOxMc(~*+2|R#wbHMr|ceAcZF5E
> zE&j1sUcab@*J6+KOtIM1SK4}Aq~KZ%e}oJVvEefqUKAVCG!gi&)C0MRo1m8a
> H5AI2
> zrcA_8a8Z|KAE3z)AcHXLexxC&#ap;diFYS(=o~|B6S)gOIxSP=M*+4X*hYvgblN
> TG
> zLSJ`D`vVBpVNpt%wC=iBIO2c_#U-
> r>?cjkaB$RuRSOV7`;NdE<_F_MA&`eyib19k%
> zb=DnW5juea7W%tOcCx7unv#xn=dpt22v}a7h!|phVv>}T;vSqMUOsdTO$@B
> v1L_7d
> zXbw;a(KK;QD-F?|d=)uL!X<}|!_QDTJ~S^<+-
> be#1EnPgHc&B^4JY*$cu4BlZKc1J
> z))rgGTM7>1u=ZQJb-
> OK)s9R`isTcRPpJJAjt^{t%FX1C}0#E%N{rpK12KidM1vU1V
> zPw}Uwq9vEV%N(eg$GHa%+FY793s$(=V_uX+M~Dyn&lt&6Y-
> 9uG)@zyMB%Z&@rO(M@
> zfrKCE;pa&0M%*5X1H4k3({ZT|8(}y@<#fH_)-%i-
> bNcyMhux59((}+yq&WqKQ1P{l
> zA%bUmQ-}=64W(<Po}kI8e`Z@Ub+T}ApM*<`PgWx2Mii{(ySehspsCCzUCF-
> ^IV0b{
> z3c_0nX9*?H89qLOyer41O<c4OAo}Z*&reEpo%`X@vG7XJFU-
> D6fY!VV(?N*^b|JX!
> z+3fbQ2>X-ZZB<lx&1-=z)O}rT7sI*LGtCR2N5Wykn8rUnYY=1_VV-Y8!8z9v)n2t(
> z!JGwE$#CQu*u0%<W-
> C}|CxEB!fdbj&B^t>~q{2a!CFwuf=|SepDvjmsVAUY=_v$GP
> z2~wwOsQFVw0aRCj#84n{0w*<wntuky77|XgR>R^Qi%xT)deULolV|sEHgUPK
> C(6(n
> z+#t-
> JIeN$b0Yh+xnk1_)tH|~secU#QHHGdyhqxyUSFJ8X{m25%MbLzshQWG)l=!*~
> z_HD_ib8A=7JPbNumYWV0JJc|bfJ&qXjh$eMwV=i};a)L>kJE~{SM*H<A$gwSP
> hTg$
> z1^F)2oH*Th%l9tMW2j1r)1fz0{k694BAUT*UW~6a_hObRB7@<1Csosmdmu1
> 46xHCu
> zwm5}bQSA_J&H<Mm8I!IAgg;MSPwE%qh*}FG`HB$1x<rV_ogTo2x83;M=Xbz
> &Sn<Pt
> z<8JI9fU!vaf3&>~e4ItK_`gXuWhp6}mZS|(AV85~3KYsqODMLbfq;!Bp`i%Ki$Z+}
> zhzPs9+0d44Fq<WUSL%fyD6N1mSLN0#mVy=27n^`p0#qzmF~z8}-
> 6&BaO))h8?>X~4
> z&pw+MMDP8#pX@&S%$YeeXU?2+=FFLy-ELu2x)PAK-
> ;tHx;#MeOc8zx;T$YIk?#zKu
> zw0RBbtN>B2fDxhBbPNrNuK%)t%Vd?e+B3u$anvR_`ZBM=Q~Apei9TH_RpZR
> ?rAd9t
> zEGA*n@<~hAzRP>{8ayUXnX_di#6N`DBN^<h-
> ae*E6_grLhQbyvT|4OKmZuD7+z?Sw
> zQlqa`4v1Y@B|p=pbY0e@Rr(II$0f)ca>;C<<y>jg^N@?<8pLN7$?PUU-
> SFlnWd<@2
> zLJFp5kS`K#yVuf%yfVaxk#F2`V(bQL8w<=Vn>kZXRTJp~ccC1&orWcwf?6}tLg*
> kW
> zj?aQ+#x>E2Q2K5u*><8AG`^dJ#2&Up7t}ZAn^#qGMAEWqY|YIFj<sAhCO-
> uk1#P^(
> zMHxj~&IJ^-
> 97d6q3q;86wsf!EGRR?@#V~}eowAJ#FSl}*ZDcLQV;ki(*v98FNKE{r
> z%VrX1Dc(VkZRWTkg+zNoD`6-?@CbSDYdS3YbfHMo+UWWTLX$ePOT|?r^Q-
> jN=?7)5
> z3b?M3#QNy^!YTnaPg@{i&vZc@g6x}auFophvAS3)rAh`VwbtBY)1yyMkb>%>
> >r17e
> zde2|c7^RF)xn;1DSa^fvqE6=tw5fK{alrhZl6nYurVC0q839Q}RRYd(5PRkCmK?Q
> a
> zvIR)5(J6zh<n1`x?>}KoGKo4O6HI!y5WLpxhQPM7zXfnGUUL|KdmSemDKwHk
> b_j&k
> z5JA5WP^Gd)T~sB60FB3W+)rcCz>ayh9;27~R@4kWE3p@^>^YY8TN(WX2%35
> qPG>u%
> z)X4Lf4O{OC#C^N+(-
> &i+OmpR@$08y>0mISQ5mxoC(oRhda$w<zkz~ym^BpCo?0dPd
> z+^t2{0l;`L18np~YaZb3mjLowAeDkTUPfO}aLJfkf5;HJtq#^lvS!&<1IkzdXCy>!
> zf$jSf-FdP<r~jq&%D?8VL7yRqRq<iZ^k-
> g_hDqpHvZ!j_50GbH^92_5@#qI1R2I&o
> zdzvaz6Xd&sNML=yFtTr6dGnysg=?XNex`p-
> <;Yc`x!BDja5a%v_E?~nhN0kEjk`Y8
> z+A!2Iao8Hr17dfId8iLfkw{ayJ(`^e=2EE%%b9Kkx*rq#nXAB)NDIPO_WYZ8p2f)?
> zsu&A{N1y<GM)r?g_^Z@aKW>T;DOA+NwN>Klph>M0u}3{y(!SDGN?PVwz^$
> !WAtz*!
> zMV9<@5m6pw;E0qQy!~{Fh^~*!njnjTcFijKbV-f$<63#O$wX##B}?T|h$7-
> Fl4%!;
> zNklpI@6hfMOR1w!h$sL21uo^sk@f&MA6ug(vZ(opJjkNvIv&=_Yh)=)mIw^_h
> u{2V
> zOg@pus<=d~`rDreD@!Fq(?`}yW*bOPa;j7c<#^HyiHAQLdyKLy2k?Mp#iuyBm
> >4v4
> zQFiA0tefyIziBG7Nx{bABSRHOKNDH`oxTR~uvTCms@VLJEauyBB-^uP*)(sN-
> PS6B
> zbJ%sn^0RtbdOz@P0f14j$_ZNAsjQ9oRbc)iKe$0SsSjTDY}J-Nrq!`6kkhNA4vl%{
> z5Q_+}ill3_%0OkImVTHmkSQ-
> ##Kg5)czgb1@{I~%=rYMy1Bpohvu#VMlKBXC?}wb~
> z%6MKYNf;v4c5o|UK>eT<P!hiG(y*Ftm+`L{OKKjp3sK<9i{3YgPGE)CMb8!(CXH
> (P
> z`cWAKjU1<~VP?eM7EvFo56{ZqvG)Uc?BLmN^h5D-
> &!+6ccoHd#%BeS}t8fpyQzIBj
> z24`*$hVGKhF~a(i(?%H948HOv_YR4S+p!X(6jMI7Z0XuQ05l%wF?pgi3GuURsX
> P3r
> zN9eBeL<v1jCjtT!o=)Ln;>k}NXe}<kD*5T6eVNC^W;R-
> Dg8bt4_U}SgYxkzVU~PD}
> z=HB>KT=U2z%1=tO)`nd$z5O`t{piz?ln$=eszKQ&kjrnGuFMaZF+ugC4jWD1<j8
> Mj
> zurm{Lcfc9NO$VhW$O8*M5^kYHrPVU~)@JJLTLzi7I&)sCRG@|R^g#p<l@{iyG
> hb2D
> zPd2Uz(S(C)&2smhA`vRs2i+5T3+vpT5Y4K`QT^3|=cf=y#)<BRkm(xRE(R-
> A#zgN+
> z(tSEOWo$K_AszQqJNmo<A)|wrMO8A`bXZXH>dKey%5LZh3?Cm_PzIov=W`
> FHY{q~@
> zwmxV~6+ocGR!>W4Dz&wq77H<~jVez^+;5USiIpWJX0IA`W*OYwl8GiSUVb!Y
> Q}pS@
> z+`(w=IO(K<mtJBQ5Q1WH)ytW#tO<}~xkj4KLg34NwX&az7`Wo4sYNwi;y6M@
> a(F#+
> zRNho|$;2o7Cdr%3k8CXC*5AzwnZFRRaLJ|ak%((QZ+q~5#%5?c$z8O58qYg<w
> lRyY
> z|9*6PMvuTNX<XnqM0+_a_%L50(i>J5JvAp3FKIm2c~H{UN!rbBn(SBN{O*#*
> h0ZQX
> z?3cs_H<4M>o$Qz`X{>TeZX<C9A7-
> {+s&t<0>IvU0dun%5*G6~mPrb><fXAG5O;our
> zPWJ)ThAZmWT-%?St}g~EtHU=>R3?xM$T=TFOsOJ$F;KC9?Cd-
> $hS%rR^s|$Z5G<X`
> z$V`S-$^Ei)M6LN*qubD;0_HN$)eR-
> yoghbk(MSE;<_)PZk|c4L$#w#&($9=1k2)l4
> zBaTC}Br?lP@G31jEX3Yscl&aY6$l3tM3KvY@ZZYb5_*hq`d%daGc2=@45tT;Y$=
> `M
> zJV~l^gHUpnQ1UPTWveY@rVpk#|1Ih3B)wD8f9a;ve|OLgQ=D~@ZX`W)JLyl_
> bnW>m
> z&JQH<Y~DMICGpFCW@&PMa=y~v>#<wrIb0_nYHRDK)-
> n&NH*0hQkx;GHeQn-*#CBq{
> zv@M}6w0AOxGyij{8<qRWn{e{9(f}v_`bIgJN2r1jeZ9oeETw1hJPxp66x{20zTn2
> 2
> z;;{wsrAx29SvMprJ*QfF_6R*iX^q&PVCflKD2#naI3)LvDWk?tRnOuK<%yLmrS5
> Vz
> z%2Yk9m>a-
> ~>&*53TY_@R{8Q`X*pqF|a{Ve_d*rL5S@44$j&TDsqr8BniDi<zH;*QZ
> zrQvF65sXOe=H-I|!uccdB3n*gdLKnN*U%##QFrQ+P9zy5YJ6gwmXcg8l-
> A?zQku^7
> zwuyb0vGDRgT9aaqa~6nN^CnW7%7E!o2_S2e+Q#QO4v2_$i;afkK-
> <DRPApP1RJp9y
> z?EA77#6d=1$V53dnsUT6)Q9N$)j|`zLT5zRD_y`>AtTS{qa#vnQlaQ`6BF-
> VM!boV
> zt+J{lde86V_4+oUCi@8vkj)G$GE@8_c>~j|$P@++e=|Ms(#}Z%UP|2{yd)d}F
> MWv=
> z8Gn|S`T+KLX^`jPyd-K+^+PS^O|E+eKJ++AJVd!C=E&)uS$o<uplB!|O*D-
> ?Qmej7
> zex$;2)<wiqL~aopoDk!zqrpj1+~Ab>B)CA1-j`lGk@FR<$$S!06`(<%%TEl<6sy=R
> zGV$)5yJiQVuO=-Ex%4jCb7qkz-
> kraUlLP#6&s%;#`V;5|%%Q?`t=I%jgVUCYi!1uv
> zf@$#k31qEvZW2kbQ9d$QlT45~zy49-
> PWK4K9kfSot!=B?&bf4*967L+=XRbq^1OlP
> zr+D7Qv*EeF*4aT>QnLBXkA!1RvzGoru@8Z{-
> ih2Hf=51lboT|&WgG@2Qdf_A#ZETt
> zS7pPdY%JTgG+8%})Yh7(TB>D^*;=)sWdXCAqSl6uEp>8yX=_b;OEoPdX=}>@$
> |0$<
> zrEY>IZEvZDbR>1PEQor01*ZK8PWlqYA^J73wHD^7<A*TM{rKfVGf4L0TW=Il$S
> Cg}
> zo_D#=pW^u`p38ZEInN8Pj$M74e$LX*Q}y!{?`UGRx|H9Fz4g>!s592G8Y1$wtx
> 8UX
> zw>+3VY4C6Gpq$ACjib+%<Z&e#M{rdkDmkJn^G8A(bkFZ|;qfq1e5U_<;rP77!
> 0j;(
> zfpY=$#U=5Bw^bG8$xCKZEj4oL7Z+?qSM3LXhJCuWTt8EIyxhb6OA_5zEPS_Ay
> &Zk7
> z=IzA3a^%ksCF!|_w~4P)C5d3=a61{n={Zy!{!-T{U0i3*gFz(98$*a3iFao%J39JY
> z)!T`IIm^rR!OVOJ&5ZeV$O{6;Cb)VFd9??*)Pr0y9CEsaoWJZSTjqJoC)+a590r-5
> zLg!&JU@XYV4+F^y!+M`V=0KbxL`mSth^~)|fmv%7e?eF}T-
> kTam7}&lKXblq{KKjd
> zrSY!#`UowDMdh+5TE6J1Y|Clz$ab#Et&pCTD>J+w65E+;T6p~A%{TPyk|~ZXWj
> i;>
> zI9tVs`R+HQ;)o#5Kc3=TE{P9H;yOwEl1<d{DH@mIQfs6qt%{Pv>&|sLfmGwCc(
> o*8
> za^)C5&UQ(cjC~IbOV?;ml7w)*=C4JgwBUo;M{d(rOYOU)_C{*owKmwauS(*e
> B$nJs
> z;ty@2h&5@Rxn+^ts#y5c_Dqd->WiubrLQVo-
> K(JAMj_EoX_Ncfl)6m|s^nOBT^{$H
> z|H!j*R%H+qXVXaEVt?z}fSvQVgKYDyZn_s>Pd7ct^Ju!s*H7=ie%Z!tRBiB<*1h)!
> zQg=Dx9ibm;(yN(1-dJR=(a>Oa4s`3qneNdl__DfTOOd(VG78l0<yuU+h4?~t-
> XKW3
> zRUpePrPlupPuK~{HN7;qhDOPeGP1BW(QTlfGkgQ7p8WihK)Nz>70(Oqh+TV2
> {k2zL
> zV_PjpEMD;0t3Tu2=j`#bcF_%RCG3O9)2+~)6jN&=I6HXPSmbO+<}eYhGYz%cy
> O`r_
> z_QyTV%jA3}$HWu9&LkaZFEIZ4@i|<m@_5w!(2D-
> gAn?%R29h;PJr}@EXxat6`_fKL
> z`fwH1%W&`KtOMd5RS|l<!5k+CctGYc6gjB#7}irb;B_NJ1fjS2L`EP6f}BRICCZLu
> zGw?~<SUCs-
> 0a`tj*e8>jhF&I?+ZO0#Mw7M)ar&79A${5w6*JN7PhQ9m#2I2)+r=8I
> zMkX{I=u!oGc=UG%-
> 2kA@bcU3(P{!3|D%@qtXgfsi`kvy5XUT~P(ES2*h6gn0&P(2t
> z^zD*vBz>}*4wuT@a*DHG(r15x^u>IbcfMv@s9p!AeU*`0rZ{42JF5g{jljI@!l<7
> x
> zRU6?vn<<X09XtI3Q@jkACtVl`j~ui!(OaiDc>=V8bZ3nKB`pwChlv;Amko+p=%E
> Cg
> z2HRMO4+G)5YsG%l^jMjfK7M3+;QYwT@7I=r>CFSA9L-
> NKE=M)n0i3Gw05&OrO8M-E
> z!UxKG<Z2K6KZ50{8Ftn8RgUfDa&Xq$Kq>3_*{XZ`qjA6U?Q<c<O+TC;x@Ijz4%
> H^M
> z_FZ)G67`atQZ+E^XB?p3cg<sx#F<x&<RL~A=1FvQyC+bNbY|9{CrbWgXR18pn
> *~3X
> znw2C5^5S{hRp?ZhC!eN-&}7Q-
> A)O+?HM0q+;wedV4rP`g%;db2?s+j`wT}6SRm_sP
> zD&tyil9F*wsy|c7Uqz}8n;zaGzK0CjAe5P)bTAfv3vsphbFWDv3PYh!TzSQ1!H#x
> G
> z41LvqDrX}HTWL?7I?{>RR$l70^73bMTG=0ppJX~wD}F02q_bFBDVfb-
> Ow@!fokQun
> zsRu2x&b3r^(aPNk-
> o&m}xwW~|Z4&MyqIHk$(4Q*pzQxF<wYBECE&9;hF6S3$l{q5}
> zPv@Q7=yEuR5HL2Xr`DM%P+SxmN0u#^Dvc+hW1f-
> }(U3z0+7CZ;j^KyxvH3v?bZ^89
> zu*I%K)2>kbNN2zj><q`qL%ykaM(X0T1u!R?|3pms1hbINP9d0NHtBVm0|(N@
> 3|y|v
> z#gvJz=FZ%miKd-`VuM9-
> riY?)Lk<dHPBf<lQCLWeLNc3sd=zgBbvV7}xruvUKm6sr
> zuX8gm81A<iW_uWx=3>|(7+%J*^BZ9yEe6SKrui6{P2)f75;IVbKaWSve`;1F2%B
> #*
> zF^{js%4cF3|FF5uFS?_OjEtWB49Hriyb1BO^kr!+UYV{8C++kgMeqS&x+v@aS(
> %8v
> zjNQY=MMDqgbA48Fh8Y(a0b`5{;fHyCac@`;P(X%|UKi+fwL0QQJJT-
> `Vc;O<k@!Nq
> zd~+&eKhW_UG&|FLoe}TREDP+Ekz0!}e|}OkZ4i-
> >Ini0cm)Aa1XDdTH<@DEx?7b9q
> zd4Q>=)RZg5EkBzP{A|YH=RjLL_PRma(s+h*i9F<+>logFhQMAYnO`xey@t4uPP
> Mc`
> zGMnRVD`d#uOAFe#bEBchoYF`+T!q65(YPC=NH5aFOmS1p8!yRwtbtv~F7Bhy
> KHYbn
> z&1crVBB|23<`3>WCd>6EqVJ`&tRyTkn_Upl9dFUSZ^vilVO<+Ht*VxVw_H!xac
> Mzq
> zmo&4=i6`NQQQ%A8A6_gZk!-
> H5{wL#?K1O+e$U@|xckvG^@98Ww<#E1{YPLjY-mK^6
> z6z*h+MQ_lCcbRb?oGO)Jm3V>0-
> T_&q8KB1ym;;Xqph#4EFj$s8qZF3f<PDK{o~Zal
> zZ>Y8&j!RXs)3nx{uhfX3fiAryw>YgofU|~Df17ho>a}Fk;9Uz-=Y>;6vkN*_E<1Ek
> z(8do=)rJdRT6y+i@{6mzNnbP@@gA<LH;4BM?XdDBMk~=#R5=dXF5Bp7J1TQ
> =>aWf3
> z#E#~qt|Kl=eKOMgn^?(`b=y<>Q!l*zU#WuRdEw;6MafxLUUtPNH;3iE<2tGM-
> )0R}
> z?oGWG`}mx5q)yddot~8{%vpTsV0?UP9{Vchl$3GB`NzVk#Zl@IuCFz%8Lf~44y
> )C(
> znL_(I9+@@N{7z~c*KW-VCpz+&k-
> bA5Kb9JrGdUieb8$(0{G5x+;)QcAo+_~{;UyQ>
> znR;z#kuBi7qB)Ca4*F?l1k-K}C*I0yekcBvr2&nSI=lZ?%-uz|hT=zIkmza0joiW{
> zuky@GZ^{19N<MLkakRPq1IPt4KhTsCFU6({y=2bWn78(t^{mP1i2V#4gv1agAB
> BJF
> zf*bY&xlS1^7v<aHeVL45DuufYC-
> }u{o4r&MYyUO{kwGkz!kA79&s2{<u{j*s)DbEI
> zg1WKXCjPr`Y0G3@95w&=zL$<{&CfhGl3%_0faqY0$YXv;BK6(xL>3OWFMGz2z
> wVi;
> zu0286)j$3!&GU@C#M}^64c*$XR=%0&%_%f=R{RVz3l%|yk9NMdSXIw;V&p$
> 4&-vzQ
> zt9-
> 2~+Mzk9Xb5k1spQrLR(V)k#K=!p?M%!q=3z)o&z+SM<XKGExse2@V{sxCP_SZ
> y
> z@AL(tbofxI0I(T}YSikA0^6bO)uzr>S}CPe$b9=9Y0^|%olLoNHi^#cAjCZiQD!01
> zM`Oz(dFAQ=GQOK1o47VCBC0ztj(qB&q2esuc<ag1c}{V*pgc1-
> SdcmSdtP6re?cx-
> z=r}EMARIdjcF2pJhUr5{i=f$;ANvsR3S#BXE>UEG`sJBF{#{z&)(-<b(LOC%wS&8k
> z>rBS>7b;5)z+&_4cYUOn2+~p^vXWdMntDR93sP0PI;2NXaJxF@i=UMS@9J0((
> I*n;
> z6>WTW*M3sPT&}}o$Ey;&);5D!PNDP~`B~acKNd(7kvyy&kYB{k$aiXjd{$2A<?~
> i{
> zam%k{sr*XJ?c*~Po3K{C!IG>F6Q0npD_PnjFHpY|Bt={y)XLV6mz=sF{%DkQN
> m887
> z+1f$JWHk|wB<)NtD3c<!gvKzjg(VOG4%(GypIU1k{)mvWND?MUg3JO*W4>
> NqXYR6z
> zypmYODI~*nyAqp7`m~p{E3vtp`*w1){Xq<zd^?E$iIUICD_@`xC_s%yl~(S0i5`=
> D
> z>-
> 8JDWsbzf%#q5fBAsKhn9B$>%7M;@#Uba8z|)Z;0h?(+4Cb}p@fZV3(Fb<AWH
> d+-
> zrtfjhgxr}2`*RC6GbQZYpm4+M_^j?R@r9dQ#in)yuAh&bqqGeQ-
> BH?m!9QuQE6?qa
> zcTeZ28Yd-
> ljK^?^Zspzd5%R8o40%UK9r|Y}%ad@8tT|^}$Zd^Qg`B391Yzz3S326w
> zKl=2R`XqYGd@F`)3UJ$~XXgmH=QgW)AlFU06|6XYaUm6wOF@qibrI+K68B)h
> 7Y~q{
> z$^~_^1jLoa7pF>981KoOqv8}{{LSKAVSIOh6+VnS@L3^87*9}PEOCeOU<C!+V
> YAY>
> z%2XB(lg1nl?HyQSpp-
> aK25D8KwlO~_k2z?Vn^=*@7TDRjM3jUpkIPhKW##cxBnIUj
> z{-
> {2wvn%gt{%ME+XtVLwtF+t`vZUm+;G42#=b4R~v)q;S1OyLq4Qx<CKO8LDw0+
> YX
> z6JYrz0uDWr7ju~Nc+x){yOjQL<#v9oW>~|@gUCOkWoH{UQji}J#Ga{b47Zk+TI
> m!?
> zbQ9-
> `kD(Q%j(}p>@D$ZAT^IYL%QL^V){$+VdGQIUJ&KrlY`U1*t8eByoQ?3eD(4o>
> z>^vXfhr<v9K0nAjZV%#29Ic7lOA186aUhh?f$L&s<IY@phpGZDaBJvK+{t~nM>
> _)z
> zs_|b56#BDo2MW#5@3=urJQC*176y-
> mszZy(3JO>rP+}#g!A6`ieWj{77CiK}Ej<_h
> zEFd}aTdeD8@Ea>Sjc*I89H3HwM(8<Y-ep9-
> rzVJEs;Dkb>Vv1S2Cc$U08vZ|pju1y
> z6br;jeNc^7S?KC8)o4l8Xd0sk<#0##(T2+E;#+YA^-<G`1;rApF4}`;@us(cH|Cf*
> zQtuqag98~caG*^PipLMv(n?g#k+V$I98PYNtShsKlGWU{Gc^=HSwGQ+eQYwJ
> Q|`B&
> z@*%juQvx%;73dT^4s0usRdG5Njn|w09ep6JU>=Wx?@LKpc=Pe&XJ)4+h$5B
> @M?06>
> zlFtm3{3^pH%R}U?4ktB-lt<(YVF&tBO3Y8@WzMwv+?F@pmbV~K-
> aW(1Bk)=b0MAfh
> zlBkvfXH_i_OMxg+51pD2vYgoG8!~-
> K7rJ+t@oeqmL~pU{@^Qtq8+9oLdO*n*ak+}C
> zWcyIEGcHl4ABQCJ=-b8c^Qpj22T`(Tf5Q_fC|MuaDJHiTVN&Y-
> E<wqD1}TG*#W!JR
> z!q5zpzEWjAE(q2q?A_>AXUO?hEUOi%&cIku2PxM?$R#j?9DY<YSfQ6UGLTr7s
> 5d`6
> zL)lH%F@h85QS|XYvp<+mRFBZFWBIEC{+w=gLLcp{vXr|%K)J74OT&sW1v}B?u
> l0l(
> zl=Fd|8-
> #LFgsIb&UZLEl>8g#lM$L<BJYw_mW2okH{veI^RXgmRRk?V9R8g5v=mBt}
> zs&+U3=&D^OoMLZClv=GhRYcg<NMP<I0NM2a7&Cpp;|!-
> ~Z)9wH<+`3=qkOZ`#XrIh
> zz0-nkVML7LdYAt942hAGx+|Cf1SfUB4fNTYaJJ9wId(+uq)v^U!t_$I${Z(N(->YO
> zIu7X_N$lq6>u{a<rZTzcICc#XtMcIG0Uftby+^L{HyM1IR>!3eks{q$;X-Rmc*bX>
> zzOf)^e;nuBPLa7r#oA!G>20DeW%7NN>f0Q3DUm1MAkV;-
> ezWQLgeey*lohV5f(sM*
> zCQEB2c|^YDq~vowlcp3PNT+KnokDCmuk^N@(o1!k`DQrUEVF6oCKD9shK6K
> S;qz((
> zL$qkK@RqJS;6P((omB_1lUa+EopeB#+h1bWX6u;>ukK`KS?jF0EI{qlpQL@$U4!
> Xt
> zDRpx>1BEihcB9M^HGWb>&61njcrOj)uF>4CxfQ5zO6H7%c2e~W?Nx*3e_QY
> BAm&&8
> z_%GJGopYgF6Ex4P*4%Er-5!cx3$+5~4$C@f?#$DS&N+c@d-
> c&EQwWWV6Pu^WoN=<-
> zW861{KZ#~T!g@2=PSVqI1dPR&AD^J31A9v@U56E=qu4(KpM)&JMFE7@4o9
> fQNkv_;
> zYo%EKM1Hin!<I#OF-
> o1@LorftI9VIcoUvAQdetB(c37EwSpY?T4hre`@MAg~hoK~<
> zQ#Rr9PRg5@EY6&+iWl8OY2UV`T^lIvDTZx!*hoblvvd7XX*F(UmR5W0JX+$BS
> u`u5
> zJ(f7dLGmVKO5Sy{%{5HFx$=1u8Aq4T`<<5I@^@?R81gru&#Z&R*Js}kw04_S>
> YhGh
> zk?j<7DktH3OB9X|?DU9SQhl~^wIva&6tm$APb!Zxz3YHOf@1lH0n{H2qRtV^xz
> jte
> zWBD6`(9@1;PRu<}Uj^q1n*xRZ#j0G}E|K5q@?=dn(JG!)NZ`skm!Orz9mu}3au
> P)J
> zX+l8sbp*=(kDRiJlexWQ<e=zgWU+QLLdmWEt=9W}6t!w=yFRj3=CCTXF)QU6
> &hm^R
> z(bufUkKl**@gKalD~F6?3%sNH3>^|fhFB`~q}WpL%1)O`Jsy<;2}&hN2vDg6LG
> LMu
> z8y*&9?(!{*Qr6Kmf*#GbPGcy2mlm#lQnyz8rXD@yIhP)q?3p!UFMtjH1ge+`zi
> ##^
> zrlsW)z=%SOvgJZNl58}KRK6gWy9~;h&2$Ay%~rtDyK@A+$6D|9J+I>>Tsf3Zqq
> bq?
> zhTjDHz`V-
> (gN=+BimvJb4x4g+bk*xTNkkPJN*cNno5v;jZ0ahAevy$!bGnA6HP@ET
> z$4t0#xUCTHmhwG^@I8P#B_n`pgFu;UoW3iD7jse$!~$pg2#BH_h;nDm2#7t*)
> BLJ*
> zRMF9pfx{4q0oWxZu@j)G9`?J|^dOoWbd@{0>M;e`X?w1RD=<7qb2xS^yqU
> O@5qp?$
> zR5m3)#w=e_3gXN*vni>PHqrg8&C3Gajt8k@R@e8aak9fM4kJkJ)FLoU=4ugQ
> n85F1
> zm;fn;3BSZJ*-
> ;lXL_#KC+vyo1Cz4qfYo$$fV#M#L4O$){^NI>HSA%y{?G&<zJH>VO
> zQhD@WPus%r<+bL_K;@_fTQ{hj)I*$olrNiBMqmqA8zFP8V#`(zDyfwO8nKdg)
> H?z5
> zf_SV^Dktr~qa+k<Zl<P+y|}h@g4hc}6DiKz=WkZHMk;hW^*mK8C^HvO$@PN
> @=?r|*
> zH)cYnQ-z`D^EyTlL1^cuAk5<m<1(~ME)D0n)5A1(1f~>j3%4+B;`CsF7ioc6iU=Jg
> z5W=M+y*rpS>WRk)*3skQkJ2wAMA@^y)}f7P$KgMG3UmL2N%KRQiSt9x^Y
> =J^R-Tv<
> z@?<Q1uJS}9K_Wx3DF|zKRP64I5z?cBOL$yImMlm#c(d3Q41Xr3^+<Y8Hg~xSJ
> R5N}
> z)0~ZI?rVJ?*tuMUhZJE_ZPL6Ftw-h-L|N;r+Fn;|rY49fm!u1usNk96pL;VL<8(%G
> z`N~-40AddC9kA}S$K-
> 8R>C>E~<{v@SYb}xwq%URtuxj}F;lD87KkaIz)E5Jk`sM@L
> zXwN?C4#g|Xq%Q|3<pVn*aywFlx%ytsl({A4&WrN6Mq()xyX03vij6M+V$*cQ
> WQCpt
> zgX%C6sWJpvw?;C*96_hKw&=0-DE#J|grXz)t@kIX&eN%{?7Z75!YCwnp~-
> x))@)<p
> zMyEjP)BL8UI<I*Ia$?fvMSQeLZ0($b^WYFX!S@3vl7DV^3#)2z;!?#~OFSyt4ghy
> 2
> zA6#s)XgurLy0{U^RApvhudjSFw1RcE166lsPRStEwL-*wOxXD}l4qziRC``1GbK~%
> z7Ty?ID+#qW!LyQb^tZM$KQnc-<Lk}Tly;hDKDg`A(?2jjxeL+mvb3)1a{hL42c)22
> zSyaILS0cNE<R|kpG*+3|$D+`&#BR`7a+%FbKZpSU!yK;xI=<mMh8>IGw010q!
> UPOl
> zQHs`%jbG2y!t)}%?dg<Q1Ifrf=5Fx|CA6!$ta5@ZwJtwftIsYOhOE3!j@Jh80)IF!
> zBJzSJ@PdxvMNx9RyS^+kNbDGtd?2VuR-
> YbzSv!BMkqkc)j{qS)t@RT^6iR?6yUwj$
> zI;hjQ60c_ker-RlR?i-
> k=YZu#x+Z%a%5U)pj_A*^<gGtgyaj4Jsh?8$@Cv>rPm<mP
> ztNT{2u4A8M{>Je4C8-
> bWM98g0nE5T5Dg9ZP0m3YJNeSc0(T0fY8FmRNUSsqkr$dN+
> zRM^C=+dUAfW8wX}nk~w&fnTj*p?c;OSE_W2Rn;w4mFj`$sxDHsuUyHpjQvs
> pW+`mC
> zSh>Mn`v5_TJ2Z9Eu@42F<f6O7!BTj|Euc7Yy9?%Hwsfa1bc+{Q5{S>02@>`IF$X
> Z4
> z2r^+H?1AojrxVHHdNxAl$11@*W8f&j>zv1f0RK+`Jk$0_B$L!q*EEvV2#v^ESuj
> a1
> zm^p&=%4s}uXKdk!n1DYLy(OGyssb_4`!=B0@BOJvJiXp;`BF~r6Vp4>^tT3j-
> v@T?
> z_j~_bjB;3pLH-c^ABa-
> 5Yez>rH&`}1B7o?qTtqnRXPQ(Hkq>MUNfG9C>@|yMrXYG=
> z26c4xCQd+0H1&p98K}01jtn4LZ<V~K?*N-
> =jtL_2fh{5_!hGIGB+|}Zn}BUOQ%G+u
> zX62@^X*p6}1<F8*EeMNR%PJP#!~KQ>^da}^!a+HyVN%0>D!v<1BZ+0LWuZ
> 7*^;lux
> z$4Y!V({xqnNIvu96ZLbFr*w;TMkn$%eY5gPF;mb~?Tm`L8G^HR26IA$Vru@(iUl
> *p
> z0GU4%9G*lTyuuSSt_rdI;SEw&XWMFe&GD2j-
> *Vm}7AH<wdmctaUha_*=eu~wUnd(O
> zxRI2AYEebeX3?i6u|SSeWETp{SmFp3KUM7wa#tyyOno=sVev@aSCysZ$@7
> WWcGK!^
> zI=1xe7J`n(n?E0EOF_<yv#YXj-WLI!D!JI!vEZg-3l;Dnb6Sy$4)Q9x>YEa~^W#&q
> zzn;&x&&leW$i8iUQ68on<2*lgq2x*CC;3)KL@+`w+di&#En=H4irFv!y=;jdL9+0c
> zM*K!TJ0s-
> tSoT{s@GF12j&8SWoE4u&&IW>zu*X!ux`IO}&oUw#k3}|)Zi7WvO-C_f
> zhgDW}M_0+I;v!|UZu0`UyCplzq(5X%X5G!)R1`0^#&BYHG20zwA}g~Wjz5Uqh
> O}c5
> zMrTB(QEz&ZwS+@NJ?mU^s5FdO!>ehEv8dj;f#&!!@;_COxh=_@;KH~CI#&fj
> Z%|No
> zNnat#>YPi05Elju3$`b*FC1-72=_{*bSg#TH@)kI7I<?dXIikd!55_$T=AWlE7~{|
> zo1qPpDWcb~ILGPHd<nnM3E@zwK#EO^t<l36;_L+3cEcMzxJ@Znk{7Sc&E^c
> M?6QP0
> zD-^faRt;@0;(T~oAO#Z!k?kwO)#4ZYlXh(nmOU-
> lE;7=3Vu`M>Wv91|HWB>6^U9E0
> zoTn%#mla?Ar6jo>IC7SlHCL@Ziuvb{h@3>^tT9h<d8f<jVi~Yzf@OehRFt^0Sk8
> @M
> zD;^;OH4lg(_CT?ABBxtD5N#VLd|1Uf7K5$T<t;UjN@2G#Z-?1t$@BF*r-
> ~ELevdqP
> zca_VlOL$f5EFmMii67-Ysrh2y6El5(=1BK-
> &7*Y!d6Gby&Us#XqUnAtTpVqWCL8XR
> zs@z*HRRMR+y)BCh*O_0yUnxAK51K7JSu0tQI6ZI`?YjQ?f@e=5PsK}6eDM1A
> g0@A4
> zTe<I^pb<jZ*~s$Y#*nknQ(ewRaygF+LmtyO*?dk*uQy950H!oo%I}&7lacfbnA
> r%U
> zZ3|1+h1#mNLeh10&I3V4p7jgK<1&-9?HDMI0-
> E&;Q$2%XTmgo>Qc)taTB6!wvV*9y
> zrdVQTBblR84b!N$c!9D@;pUmUq-
> 0EJS$mcIy{E~Rd2_YiNfy@S<SB_JHi=C11xSqW
> z+nwAQ<@8DebHrM!$~~8t*pq*$uCRyglqr8!yH``oREm#?EY&=+9ZL`VllTDTcI
> WRN
> zDG7sJXBE0<1rXkGl9_sUz^?Iu9p@UVB}JI)o3wRlRu9DZ=Ti<#kySZ44UHhE!lrX
> X
> zZMe&Eq7kf-
> i70R%kx<o?=Zm{<|6IGz)+6&nfv=uX=S&O2tWp?nL<z*qIwu^2_*4!=
> zK>t`g{<`$L$}EBSXfNiCNvAh?!W$u7X#3C0FA~xX_gjyyV0`DM54)A^Q-uOE)ti`P
> z?F%oSPw)k{=GgNjrOe<z`qP`o3cMF-
> ?ABvHvw>V3z)O9Zl4fhmM8<86YyXx*3}U5^
> zttxW&0<ygn7KvOdo#GsJP}cNqV?;p+k44l_+_yZyB0jLwB`hLEnCdTRCQRRHBI
> 2<}
> zV>maMfJSb{ho#d-oj;ODMSI-
> 4+^E0<+MmwhfeIAmR=|j*dV8<}KCrET6k$5<^eXU}
> zG`*=Pd@B|ffh^sEw_B!AGGCFi=Za=MU%{fmZtnN(^P(}(W;J~Ua%M?U+ro*
> =RX@YY
> zO1iPeP7-8SQ4O(P90ph*xrzk}-
> q`!nv70JnZwyxKKn0OTdt@u0MDiB80S1V1q6;=0
> zBGr?X*OZ<#0KCVp>W|R=8^%owwGW4LhxVuK?`({y&*|ODrMVoa@?nNZh
> xpMRV+GmD
> z{6^>HC284P59LB}dx`ee0;w}CPcI{ZA*$hkM7bH9+J2yNVo$i<T=z%UnM8mf+
> RRy_
> zY^9@!_(ybruNlpg2opPprr={KI1q4X67Beyrh0|NnJN;^eoe5j&jkyE<&~$4eV*
> >g
> z^7OL-mU?D|RKe%z9$~5D{E9FDd|+n=*ep-SZr4oGe&uN#J@B+Fhzm~-
> ^UGH4^0vYH
> zJpJQ91!m_~0B_?=^Y}845>&tkwiQsGew$4j)S3$XL)e#FVc7ZpB(eGQ3b(jmxm
> QfA
> z*sO6^#lr5whdYJccPhKr?6eDGvtF)fDB;v#4Ggr`JBsl}q#tW##chl7ncUp|3zyxq
> zVUAx^oP7li#hl=cz!X3jfA7o3zEDw9BB#Pt4OFms+{kGV8oMqWFCss&8J5_Fg(
> 4h}
> zULZ7%oc$0^Dv6P?BQuV%l&skyK73&qlyIGyc9iCjx@k+V`Hj?x9D%VSa#H#Ee-
> STN
> zSd<lZYpmk-
> gq_CA6(P&)b{P7_2X>4whJ@Ui%Wif11wU|Zyc~W{Z%`5#mk_oQqY6^x
> z8Vp!L5DJj1u&x*z|2%f?wx~<a+}Jsn9zsJSaS3q7Fm0mrs?*V5n8xQF9LRLruz|d
> W
> z4JK3>%Mnq*K%TzTSK4{z?Ja`9o1=U*FmMTlW#E3=%RJh^T_4O$AHx^$-
> HO+2AN#`4
> z_Al$fvg9DV6G={xXMxY!XLV}_#UaGI>}w%~{)0a>*&_tM;q$C+r2C~?ykyHy<s
> DVT
> zV$tzcz4mLse)ZX}e)$TRSmLk~N6UjsA7@8^rD_<~xw7UY^9-
> WIcO3e_&Q0XjB1|M^
> zGvOA!&GSUy7I~8sXT81QQ0sqwE7TG%yEUvT@)5>aZHB6PKeZ=Ll7@bkA0ri2
> 2KCRN
> ztEe#*HNBz-tNJ|hsy-qf<zJYutA1CdPb_aqNd4T*%uyzIb-
> qBYhVU6MxpLm)rO0&i
> zZ3spmh>xty?&R)PBiTPgV5zfRNSkl=TgC2;P$cJvO(TNQBWI(9bT$et<p2V+@n)
> qZ
> z8k;^Zt239+l;6IqJrIBC8-Ij5OP>wjT7l(H{_olRW4X62|14s-kR2LB&0(Z?60=ZR
> zDyJo|XWa|hneM3V^%Zb?jh&d=Sb}zDnkJ-
> ;*I35~b|U0<qzJS9^KN_7RbqdN`+g$+
> zb=j3uJVy>$6CQRu0c+NFf(V~uQBcwe?Y0w`IoSQqN4p0(I1dM^cIzFA#p{QiQn
> feZ
> zfvWkywrbiHr}$O-
> FI19ODNcSn{AHay>|h9Wen!dgNC4OPTwF|>W|~`rxO`xXONuZ*
> zyGbjEwmb)1xB#R7Eow@RY|+yd%Jg&vd}QwG#sZ|SySulToNRN6uFBJ#Wq7
> k!zA2E=
> zRdGHM>T*U&bd@7NYRV+`tO-
> {`nZ%Vh9qkm`7W^pCf@*6!SZa}l5)&_!OZ0p#DzU#p
> zZpxs0(qF;Gl4Q=Qt_$CSt{Y5NZI#(SIl{??t*NT53~`iwCASdW!$PjtkxW}`M~dXX
> zlo_6M<nyv%+)gD!Vg<DGjn&X@Lrg?k?XuEpGw(f)d(_$(Ubl7$sSiRJb%c%q3I
> *r`
> zTT)9A=F-o3q?QdA)DC4<hH-
> +X=ZRwlo;gq41x%m^Rn#EHr9BmLuN@S?cqvOwEU>?d
> zadmOr5NjYr<^z#z=u5|?RJnIzAbR(5nxn4ZQ#d*vZ}0M3CvT81q2ItW@>KBxx3
> P$m
> zNok6%9TcO;WRCPQK$MLFC{_oDwr@-
> |Y}70EOeGh(1c{n6ItrOX>F5xm+Nn20-JnFR
> z*^sQ^K$GnOqKby_h<c$l5Imv+Hq)#}D)~h9fdfP>ywM}-UCMI?a>`K-
> W%#@9mLxRn
> zmuI<d7}wDcIpONW^LTN~k{9N1mK?a2Iga&!A+)gzRz4DJlH#J9dR5!f6{rK-
> 6}{3G
> z>gvX*G22*bP~FpwpdP{z8sK95D)dnwe((GAN#%VGF*l405c4T;Du+JBH|+CN
> vZgc9
> z)EOXV84w;Z--8<i`V_De&2`8XpO`*yfS4O@&`jun)0l3y)^xXEf#R0LVbKGF=sZvi
> zQ?-
> y~7MN0Tkp8=PgsS|dNY9?|`~{*g8f9^+*1W1A`>wxWl=MH^T@hFr*dG$lH$tC
> &
> zfb%DW)^faw2vcTL*EqeRGxAOPmK>S@bCPL5{&{-
> Bg><?_NvI_L*7Y_Ak)1!&K4ON>
> zP3r6{i}J~WvKxS-(+BCFRKreBRUPTn3ffTPwI2TKa`B_5D$K7C3O;@dY4J;DbG(l~
> zQ>_-jw&_x#tX2-VMJlC&VmIdoSx!)k`N$JA-
> <aCi+PkWa>0s7K5akI9j2~iV`8AYd
> zIG&V7Vm>l{cE5!HX8Z^}#Es2aJ4?nZngW@waF#L}LO7LBh?7=of*4>6ijG^sYi5
> Ot
> z2WyS22>8s2-
> iy2#H$hkw5rQIYo)AigqY`QcJLZ>#MAG>#A&P%dCnOB@ap&q#PnaQ@
> z-
> 0s~8%eoet&VOdNRqbHbAZvee6b@^D5=SV!;+|D<oip<~<&~dU9qb7sU`{e8A
> Zz@-
> zvXD+W;P$MNFI*>0)Z>XHz9(SzTA6pGGidqYMi0j)a&aK=PBK6HYygLav^XTQn
> UcjJ
> z%Dj!c4AeK$F)u8ln&}}2J}nTU%SOORQjevB0d)0Dk3kWC7#sAS{E}2wJTP{S!*o
> %O
> z_T#9uFoRo^zpQDolQ0}w#?c1-sfh$C&T7}|%#&4}`UbfG2odD;WIua-
> O>&_SAA_!Q
> z#O%}ZR~y^C=~$h{1vocvwpPYBr9Jt<c_<$IFc;v*FAz*Q0*C$u9_z#{f0zUCh~Y
> VM
> z;YV>9UjI?SQRdak!cX<f&+bRc+QY#d7JiKSpZxKEwf^sYY*-
> FkKI6=7FP5p@e;Bbf
> z9wq$*40dr1=#0>&%kFR6AMT#2KWJZk@bhW@J{Ejx@idmTr-
> eB!<+@qztqZ3`R<*|`
> zbDbh%<K~08{dx2G2!X<MjD{^q?Mu8HzWJ2Bui;;e6;-^{asX$Uz=-
> j8Qk~pZ#;vn_
> z74!819+^$){Mfj+ze~a6E!-
> Y~1HqMB_zb&lVcLiO=p3Ox##%oWi6EOQi|s`0dki8O
> z!o+!wa#mZ7v)GD>uQFT%Y8I99VUyn&7{V6PStw#cRm$RPH3vF&k+>60|1t90
> m*`c)
> z+?iF>LkH?`sm=izrutaT`#w_L&h6zBdL()YWXfsf;~3I`R@yn1uQ)&NwQ`-c3p`<n
> z;yTexMHKnM&_X(o_^rJ08n>0{`GO)ljq}civeUT6n>`dYxhR+@ooJqM0w^q`M
> WGY8
> zgM1Wkpbp$wlJ50<Ue^HS_%TO%Db#q2hviSMK6L{<nIfHNE(&6?kQR$%Hcx!
> oYsl@Q
> zbiC;*vm_Q3d+`UV04~XyC6%aI)F(zkU&x;&oi6!nN>sH*7zEK(FNmP7DzUSqp
> U97z
> z5^t7Nk~>RUMXJ|`V}gyaCF(4xL}y9871p9JN=s~=BnM|nT{26e4$P9eh?}>wB%
> OVT
> z{f3L-SE|9q<*u^|bTe%W<MDu5RVM(Y=bV-
> #Ijpm%Kzt%S>BWkQ>(2V3ckhvg5EzG^
> zmu9lFRao^zot(<X3T)tP9ghV<Y~a`=G`>tu`uLWK$aZ(yu|3tW-
> A+4P!=53tTPF%=
> zdq)K>GEmm;)MA&8NIYMzmBp~nB6?P7%@$jOH&rH1ogio!NH(CWIxz_lf)(Oi
> W#za>
> zFJi&q73f>0j!of=levP~M)Wy}oUq1hcO9oLh@_4rs1Tt!eho4lr9aY?roYQVcWE
> G@
> zn9^H?XSPBUI&Ld2k@O}O8F0gSN+>&=UHjO4VEGoXM~2zQr#PK5O!Ce1jD%
> caR$)#@
> zT=~P?LOL7$VgALdYz`c7^VH7#(2?>YE6p(Z&!siI8flk`N9!I7{{bYJ%CGWKTHzin
> zd4<=Cf)TAa$$So3;kUv<Iy<Emda&fCE4@~vFO@+m$EAp$p7Wn{7De5~?Wa
> R?JWSKE
> zAWWO|*eg1i`Q>csak0F`zu6QKJ9(mx_5pvi%hZoBt)7bNaB5TfZ5c0$BQ?H4Z|
> 0C+
> za%^Wo>=RtfxoKY^q9yU>QJdZzmkPJFZ{no2=N1)*SMFW`Von<pXbdg68!8*}
> Ad~pY
> z{9Cw=K~C0BygQz=9<bpg=Bz*S>kM|Bt&fy}VSg#2%@Rc_e3gzw+_Sh-
> `qOepom5!N
> z{JiKYSX$~UGAS;1q)<R8J>7+&)Zz*~E4QE)xzhJf>u-
> 1VG@>VIWWA|BQ^{9Z)e|Q=
> z5}XK_KD{b-
> v_=xVVQ8Xz6M!_4^+TDV_GMnPHD0+pR1T2>3Af8SuLRTdav$m$ij9B?
> z4X3?fCDMn!y6qUR2V~0O5=!SB%<&WgQcLB^bp5k;)4K#V^d`EG+SENRRkYg
> n(BizX
> z1o;E#-
> qR=@E^R@WAS!bfA;kWYYDI|9F47pM_(5!Z=1IC0F)%1Z76+Tol<LgG%B5lY
> zDl;OO!RmMHoyd8^<Ne3n|8{_R?TOsMYER6;kQaiCGL<}tn*je{^ZfGxYwfS;|4
> Mx>
> z7*-!|Q7AiApl+++I$it8HHf5cZvN5hX6sY^uhi$6$8+fuSPgkY`ex*0TWYbz<{G^g
> zSpjbA<NPc2Ibm3R?5d<#kvS_hpVGRaO-
> 54a_zzY$sio9UY$xV;fp+7N66#z3Orn=?
> zQ{3~b9^|cXvN>NF2Q43MzMFUEczCuW6y?!+S-
> a^x^<j1M&FJrzQ;M31RXEyN*eIr&
> zljglMQ=aq999k04M}W;VPh24-P5>$h>=ctji!lA4&`dbAzX!5R#QeS?k0Hg$TUfrg
> zxlzB5GV}Kqqxwbpg`9T+h}*BuL97ekGZgV;i`WOYh@}Yg1s^f)M##a`3ag@si;-
> kB
> ztH=~;i9;ij*gUU=psT9)&e~SB|0KDzA`{tGHOSL@L}B$Isq8$x4X4UbX|W0g>%5
> $7
> zWkjvH_cE!Y#2IX*PTIQZ2sln=X+nY*siVf+_DP}EF#s@0)fs&HtMa3&moriB!Vto
> 3
> zxl0To{0O_)r<IhQq1gy6I$v(~ng2ssKw~N^W>zSEm?_s{izvxd>0^XPW;Ao#IK&
> +(
> zN&Snt-
> DHp`$3Wfnup00#JH%^4=cR5NG6f=AgUgwAzM|))aUX=T&6%)RqJ3Tq5yO^n
> zmkZ%!r_E4liIPa`rzhj&#U=KnP&4}T-6a=Gs5Mc}P-
> s)?rGjmh`)`d@;w^ui@>lND
> zndwp9%yjaSixYo}CjJ<$+<(QD@yHcdelmS1$0+aZU_KLymof=uDw^0Ax%tCy
> KQT0I
> z^=UQpL-(gTo|RNi#<*Ejc|j-pQmYru4-HLgTPW##ck=W8OZZsD-
> ?#ZY_NCTwEeEuo
> zm)CNBUh8@Jl-qKCeqvieqC-
> pH?w8(nK^9h_@)Fzf6CL?dhj02&_uKLk+w!D_Orl9`
> z@lz?If{K*!SIl38zYu=|)T56-!(VFQmwJ*5@9W_kht7S5?_R!p`R?PpkMDlI`}rQ=
> zdw}mjz6aaFZ8SYp&{r_vk|Q-
> Fjb6mxCH&pMA02qbmCtXvUs@b|wyk&HP{$mKKn@SK
> zEq2Oa+p;->ZYNC3cEW`B-hN^byj>py%h2A}p!5nJDa-
> 4VeYQ_3q)&EG7a#=q{vMtq
> zJj~>;^}K>(UurqOAn_Na-
> djq&{|OW=b#q~|ef5|8#9P`6Edj{;18}r}7P@`*mx9Dw
> z(zDUKFUDmT$U)hwsKdSdJ;2{1{5{U!_xO8?zYhMO^;Bp*mG3gX%lIzgyM*szz
> Ki)T
> z;=71%cAMPCR+KM=`3~pyjipgH<r)44_$&H&pl{AAfC7QO(BHH+&=0f?82c`#@
> 3QJm
> z^~ZQ?;FznJAEGV&*a26+$l`XRz{pJChEE7gu@8g(p%S%5?g>K9`R_dxn(m(Qw
> @zVl
> zPw)}_<>6nWWxqfE-
> YZ7nm;Lg>)4o&aBIE==!qK}$0f<2;Asp&LV>^9#4t9597bz;?
> zF@;4CD*#f5Gs)`)@mVp^<*`~Kl(|%Du(FdyeiGNu*Ej1g9IV)s&e$?Ye~$?>2Q
> y0M
> z_b7~v?^V7eTM5Xq;62ntbbZ}>6`Rw~NDeJ{KU)nZN&0gOIQEkqb^9wfOCSL`=
> INXD
> zb^FPofl8V~?htcx5Z5a?hRC7yTt83WtgjoY*qpf}T?C!oRx_s%#~~5Ex16Kc@^xy
> j
> zN3Ux|Bh-
> @xHn4JX3DqR#DudaM1efy#c%@F7qRbE6z}(6Sa(Z+;|Lra5zkV_=Waa;K
> zibCx`0G*kmr6kfS9R1>F=n1TB#&XF;@GgN+cr5D87o~&518oo0lBo=HHv*3Il1Y
> JK
> zszChEXkdnGLj^3~g5}p6SqvOeT2JOs1uL*%1@%T20~JiHeCtsW*ANG@u|W%
> 77(gYm
> zHX@yxQ<}INx<RUUU<(YSsWqz2gG~^yT_6>(d<#ZE+t<9(cF7T`HQj`1X0G#bE
> %#DA
> zI!GZq-
> 9qwwT$gxYJ2`DN!zmvw8RyyenKE=J;n`yUxhc15in@o9SAVacANoCikMlR1
> zzenok`$t4G{@72O+kf1Z4l{6vC(KZ5@H9b?u&ee3Ud*FncZ&aLd)va$kg$q|hg
> *Iq
> zX7rUu@3ym3ckthGfJ;}2sn!$m2GbwMPGx{eNS(4AzM@5=fK3-
> L;Y8Vghf#(P{kT!U
> z@&rsqvSLhZVoSz;UTJ3rkiK5%B9-
> |He9lpUza9ll&U{g%a>6l4acHd@1?*k{6QnW=
> z;x=qTYLcUX$x%Jp(y10H2jhNf6fimSNQ>dv7uIy43@0AqAR`jA9HTG&xNHNEY
> w_@E
> zN;>h2Hr*P1M@7H*Zdgh{x3`5aWyDd$9*fd|@-
> 2!VPL7{zhN47T&Q)N)Gb{3)qkugw
> zU=n35j&F9h;wxM`3RshX2~ta3199&h1?*xEsm6UL_OR{cqEWz3_K-
> >tB}mafGe!Z6
> zct|Z9$)TQwqk!$k=)(?woiFLw^bxkfN7S2NQ^0V#{7}H8!G~Jhht`>Oqk!EjVA9}
> H
> z?O0P<Ym%dYUF#v8Xpv5=H=h~>>>Lm21dDV+ov9oJY>J2UK#TN1;v+`^>tmX
> yEiJT2
> z3+v6F$vM2G&kLBeG|wW<t22KjQUI{@laeH@JJKRLvetZeloGz^Av(+=I;`HT8
> U^es
> z57A_cXmXwT<S1ZsJfxE>(n+=Ej8VWQc}NeoNDr<z(NVxMh<$C{c#Cv=osqk9
> h7&=&
> zx!Tfk7U{TJvuPBtuL+nikEkC;3+m@E3zojyLv)lybX1*LK1vCfd58|Thz_qcmy7~-
> znulnLMKq<}oH7d71P|#U7U>~%X8b5%e?*3B>!KEEwATEdoWqImQvs9K9b}
> OnRBtwp
> z0%rXPFw6lK=>c_SbuO5mz#mhL1r}og{#Oke5qGGo0VH0jUo<NWCMuJo5>T
> 0qqk;8_
> zQUpwtB48-
> sb3L#=3BhLR8|SI(a69Va`JpqH%nyC~672L(U^_Q3kK*^){C4>L62H^H
> zl=6E%zyFKhoB910U=HJVg5MAGyMy0v19LgQWBgvj@9q3Po!>S5zJuRS@cUq
> Xe~91p
> z{Jx9dp6%<}&zw&U0|x9Pu4Y&L`t(E$xQ}WYjlgyyoKGg^{k7&=4Zwj`>Q0c2pSS
> >w
> z5J9}C0;5*QIUblv5fe6szcJBUt~f9R!6AD&Fk({UD<jcWPguSXZ?G(x;Rul!Hv$j-
> zuvY~@7Qcj08L`m%FbD-
> kEwtxG1M3kB4KNuZfH6e=b2PASS|ea$p#g@4c9RFzjhTdB
> z47aTKmvdSs^9AB}NBHBmk8z%yyO$xbAhAQYs`)ovo$0K)UfozXe_RHHzm0-
> L$CJz(
> zAN73ixY#VD69e2XNX$In=D;m4tA>F+@x#JZW_vge&c&hODt88PSV)UQuh!X
> qo{!@t
> z##ozZej?ad`Vb;<-?GYme<eo_-;%XBU8I;7ZT_u}=<Ri8vGqf-
> +!dQgdc8T<d$FH0
> z4rDvusrE&xZ`1z5R1H~<b|KVxUJ(9~IM2Pcui33ctv76KT`;YyyNf&exDYyiy_TD?
> z&LWFQ%6;8?A&8{h=j{uNNUE~Ig~&zJF8;W7MO4+^T0O0Occ^{e0nz7PVs<7$
> kF-o(
> zb|RsW@EeI|(Kx#!otxB0$wlyP&pud_)3X|67rrpivlh})T{4@Ct2779!&Hjvg;`3U
> zEk{3?6E(7jxg@5zy|73u7!tzQOAefg_~*J2i#zMg)s6Bh_nIQYya1M?oiVBLJu@v
> B
> ze&kY6dc1Eu&ee-
> `Dm=m;7l_BnMqgn%y$`$>U&18c+cG$7w9?<VKBtV9gYimzMk&8w
> zG-
> xe<!*phto+Cl>C+3#F!cb#Lt56>pYnemr%aW$?_GJl7;55s}gF2iW!)pb$)>M35
> zBw5L0#hmHGN&9?;;vWg*X$j^@O^{4=+|M{N)A$XC0h;~+AEWLQEoqYAx=r
> 1Mg;IYe
> z-KkQ+mJGLMc4jl^^wFxof~KWF=^El-&KhFk?EInF>@m~!>-
> h+y=L@lbNtwF~J66u7
> z7EBk0GO6I6TIgvajJN1>g;O`2FI)BtO$3Jtm+4KA>eiVTzNw<$?Ev6cHbtaGH=o8
> s
> z%kuL>w^g7lPLx-
> h1`2ilbY@EV8T}#)sV{_9$bjUmiXy$BFu~zyL#1W7ekqgkm_L>@
> z9V>cV=3f73b@LVl@)o&ynezqmy83j~`e<aw&~m0n$VLek&aL6EES5lhrjDo&J
> J5?b
> zolMIpvSnxuAIj!+>*MBi>r)3Z-2dei$mu`tzdG1-uC{ip)j{QdDb74Da%XgZTB3Kl
> zyX(~7)}#I}RMafz-W$+P%j9D~#=&I%&vJToNH{(6#ll5Tt%-
> kHWCxMYy_*D2xvE;7
> z*~>xqy#!aKCFUb@j7S6)e~-i0qt;@#Xwq&j6l;fx(?bjfdYxr#?(yTILPgMcq1J+x
> zp`)s$wXRBKefBBRt)b(dwj!uvSD4!tQjDx^n9uUmL7}p4)W)K{tOc{0xD=PZN>?!
> *
> zxwptvNe+&SE6yx8b9he7&gbpP`ZR%S=dUxz3Islv2xPf7Ko&jriyPg|g3a0$wdN
> sw
> zml8o(WsVE2kQHg7g}+TrMgQzvqgCFCr-
> %wc3H(I_XqrM!7Pb{);1J1f9(YVgjaXJW
> z>mw3dw|5iro<m<+^RS&(wZ}eYU&LiPj!J)gTHq^{_w3OA{dW~~CHjVDZDxDz
> cS3o2
> zD`O@#e~_G~uIh<R`%Wk{6p9_f7gsptXMWK(e@L)YY}(Q`f4~3qp8quHKB;11{
> 7Jm_
> z2>WU5`>J+G?OZd;<vX)&0mQ`^=%$nRAa&tXSRW5*nM5<O-
> t>e5q~GHgAXC1mAVEJZ
> zTO4;p<S@OeT?dmPb1=VW*x!@*&ECoAbNDK`3Qm@`z6qtkkvYPyqV9q(cG
> Q_Z^`OXp
> zzQVNle1%tc)SEjlRbC}CdjrH>u?rQ=`%MAxX~Ntu>au9FIAvEhX>B-
> L`Kr(AI^*NK
> zbQZ~TzPY4Iu)Az*UU*l|KD7aI1X=XR`dV6ugwjvkF(VW|&RH*+=V|7~gU!DG5
> Z1uS
> z%1uc#@ZcqGpAm|k4Roq*2F_;|HKhiM%qb_6)5Y+W12`LLJbL@kPf2@<xPM
> &lzAnqa
> zpo%qfb>>QOddEJb?fbIsbPjW>!_B2Y97CZtju3&ejpoh*(~G&7)(9p@>1+M(U
> +v;r
> zWpUAEqC@O$vj;(odu?xXCKda72w0X-
> 8b;oa=1Kc|l99}K^Bs9+&6rRcO!)UVZ>+y?
> zwDTPvvHkF8ufpK&QsL=a=&W&a{v*h|kRithc3OmvQiMrWYUkM-
> HV>E8PKO39m&;>a
> z&tzJ+sk%|hj1O-;K~{C0A$+t*5b?UznV-
> 6lfkAG^Q|E~BG}igLxdSOMEwNLEqn&GR
> zRQ@{*2KD%FCxgl7KMjPRWfp!U&~6{tSx9az!hGedY`fFr@}*1MQ=*{c8Fx#fj
> M*ad
> z?m47|(&7&w<%Wc&xI+~yp^QN(a9pcdPANJHEd?hzl4cqaZm_40Lh;y}Phehn
> `^6a`
> zyUOUoG<&8P>pgsiOp9P-
> D!Rkm#gi5H&I*!*4V?vWn3mjDwUhPpTZJL%^NI1PIcVS3
> z$_UzguI+0#vnVPtTh5d^L5i>0kz`eR=MX0u{ajdxG2{=)JX`Ur^<u5CPNWMTkT
> FUS
> zW_NPIR4n+!?NjAA6EWk@`lz-
> #y^3NOK{rT2A{Z>KH^`IF!In88TP9_t7T|QfR9CDR
> zzNb8C^-N8-
> e{)K=cWzgA$2?h_=a|UHe|&yu<?}1#naYSI(@izFg@*p)Ihmg`B)P##
> z#$Sq4=ge+Bm?=yr{%NIFd5cV3V&hHOTqz7?`2pt}Zs#}7lM!GJQ?UYW)ojA=l!J
> wm
> zZ{K@{x;t$lUGIAt(AJ1kL6(9-v4i={i<R-2A3G*<5-6<nA5iIkB)^4-m<1yJMH>uS
> zZJ@s)d%sWit3C(CXUfM6KKvz*w=Z`k*9+gXWOglWd>Z|-R+f18ayfvEXSq-
> QWI0~H
> ze_Q_L){~+uQIS09@&0XjIIhIK!7WW3<5<<dEri>nU)RC<smXybo@D^7$p#s(<
> >aW4
> zEgl1`m;lUvfB3o9yzvF86jtu(wo+sl_go-*iwxLReE5q(FWllbB+qR~jy<9DEy<p*
> z)OeD1#&Ihpllay!|Fx=vjpd>bS#5i*QVY}-y<Qtra<c~2-9&Xx@~gA>CTg-
> 1l9G{w
> z;KUJx;WyQ5!7blavXbTG+$<}|VuN7_&6Pz7d-
> M_K16}4eWVX%9G(?Xhdgk|7>0YB~
> z&)OE83DoW}`5wkj+u5JM<*(BsdpC;>6+b(be^y@nr19;s51n;&Ui`T6J+UJ;nc}n
> N
> z=f@A_<;1hDE{GRnH6=EO$M?ivPI1NgmirHHf2o`Dx9r^v6NO@Bt@-
> pW#rz3Ek!jc7
> z&9o>Kdwgk%1S$WQyxk_{|BUi~f+s7};<ER4>Qc0%`T6Lor^%99HZ5|ojdHjsHn
> CN9
> zLtv!MapNA|N*$16%XRp+-
> 1%b59gQtlW^K75wdLY3a*u0f0#OQ?2*C##A`rr<*tC+p
> z+qCHird}g9A%1!0nAXX}jjVb(Hn(Mp-G31~!G-yQg_)iDx$Mw5L;)2D=mTV<#-
> CfF
> zmtA2uVYE!)yZEvzuH2HO7}-
> x0>(u(D#<|vK3OsI|cTvDESG^Pa@ZQa8eNK|^&`^A9
> z(l2Fca>}firO1{g`BEysJp>-{_@=*23uD7bo9uiLd(@23pIu}4^ODyZcQYRm*c2g3
> z#eQ|!ukH4$Q@)%B_-
> G6bm7d1jj49eozBr&m9e^c`lU)CNc!Nx1(lRiyx;jFVNsOYQ
> z(iy;``>;B9)CY>0&TE_JRTzpqdUV-Npi*4tB}UH<PA}BZeUfxeiAEH^+=yaOQTd!l
> zTeW>cXoYCa?HEy;cC*0Om8{u{#aM4rpg`%eSGv|b>ORYa<1zQSp{w3}%Y(t)c
> D;Qz
> zukejG3bp-^ZXy$9KfZCQSDyKFuikMnzOmTcZnFS-*H2`Shs`~$c@S1-
> m1g`2c@Uv#
> zeB<Hf(f`)E43$oU0*@8pE-+`e<b@uaCw9O$5-wcC+-Bj-
> TSz6%dZ4++z5>TtPii5q
> zh2ZM0Dx1t9m^dYpr4c^Y%42P6!l0a+%x$K8)te)}zMl%>Ovl%UQ;yJ%&RWw#i
> DnBQ
> zR9QV9A7R><n#fIPRfwEk1X+8%nZ;gfB;=OVwRn`<vjx<2)|t;p0pG|LK&fLHuJA
> 7c
> z_pu&oqoT_FZHE2s9rn9#*zf+p@5J0{=$DTp=5xtBah%ke^*qoIjxeUV4wn-
> @tYieA
> zcmDM}%zIYS4@NUbpN_2DSA*T9H^j4hA5}D1u;6T6bQoAUr<NIvCY^+ui9Wr
> cZ0<qy
> zxxSf-P)^(tJNPz<#6u|#V3R&;z$-
> hdd@=2hV8ze*Z#yYEus_pts=NC$Z*o@Lq*JFO
> zW=q|DlU<$a$<xH>n+ygFYYXW(fZP3<zd70Fz^N|$H^M^p_h-
> gE9M7DYgF~I_#|3d%
> zNQ*=FXWo{@p=(*XS3qV3C~&UgT>xIFBJ&%Kmlu}>iY*ww%Y|=~8U(F)Hf0(
> a*Cj9Z
> zW)gcYvJ^t<KAZt>Z{|Sm-
> b@BMZ_q>JuzNEH#L@BR@yewl2z+}>B0Es!8f!}E!=11=
> zcwI%Q{V`*V{@_qvu8}}x-$!qI<Z3-5hg{kv@0^<Lk}R<Epx-N1CwaY+Iai6~Ze$(s
> zH?p$b!dkG95c&xP?cLCJo;6UXXTYl?*tX2Fl#U<b%K+yztQF4_?RJ8?zT5_CdN#
> 7z
> zLL88V$j#rLcW%g}g9I9$Um-
> fO5KBadXKr+zFe&w<EO8w+hj<Q~xt_y@^!N489E(nu
> z`#$l{9IQHB{WEtAWhS)Uu|E@OyW_n~LE9bTkSTI;9ML*aoI)?hma3k15$(wos
> #3Q4
> zIM36^fV%p4H#ts2A0MBqk3rX=YL`uxR{ut}5$x^%xN?hXeNw#v4Sf>5voBuatI
> >Yx
> zJ6HC*Ub?^-
> >~{C;o6iehHC8!Y@{n&%XS@Z*dACf>*Uro`l?&;t1Kg3!=Isj2q4V<e
> z?l8h&nu<F{UA<ZQGvRSPyhS#EBd&L;yg$;p*CMX=5O187gBYDK(@YN{wvZO
> FWHxsO
> z5j!BpWaXw6)VK`Q<wq@Jv2_RcdEHWKeutc}lFC-
> |EDySiO?f~cuzd2egHknJE9VS-
> zZr)dJ!!NU)fu@c_HA8e$ob?nP=`6N2|Cm?v{M?$em2#%J(MJezEu^ivWH#*|
> 4v_3g
> z3@Gy#!WMw6*D@_+Igo8K1GyRF1hr9Xo_W-
> @+#4?n!1Xb<#T#N?@Zi4e!z~WLZ4@}!
> zWOdB1-SV!pa0n!}=cO7tWxG-I-
> fz(G<xH14SI%D1Ul5Ak^JQKjDjotZbxK8FYJT|e
> z&B?f7Nx4nWRH2(c!jh)WS~SRC0?&KWuVRKJn)*YrkE<qJ_JU$%n*R|bB88cX
> PUbKa
> z#qPjBQT<&bi%O|Q7wMQ+F1?bzQ+|3<bn7VamwBiqguT|}`KXUaIHmF)N_D
> 3GMvFL#
> z_MwW-!~Z5Vi1)&;9SanJ-
> u93Rd0+t;y69|~P2pl@KK&X>9*u&Eh;SEd6HdxVipVh_
> zxS#-#guyx3n|KZL&ER+DHD={QslL>^T8?_fO`SPrXC7hPhrBB^ZIVqOSrku`Bq-
> *G
> z1qa>JbhIErF<C5fXuzmwA|uiKm~PKOgWu0>Nv($l<p`RHhepESq%jxLp`a-
> XwuX9U
> z3%HW9rIGBRV<BMK!sTr2HlbT-
> zR^~f6>NIwnFHv%z5A$tvX+u0p+MJnlGV69>`y#4
> zk!1DMv?y~aDSF?Rcv{A74<-
> ~%+|9Fepxo$d+7{*?@K4H&B<?5*EuW_~Ah7Q!rDTzu
> z+b1-f+V;RixdA~dgz*&Vm|uL5V32Mqk%KIR@FikONrr-
> 2fl1a)oz;Hj@Uz)P2CMvy
> znE2~L2@Q<VEfM8p#gV|78JDR?iJ86KH6d0SVc-5LgXS-
> m0XkGVyH@=nE7PGB=llvA
> zaOLZ7{NQVOsQ(pTeK1sCXWA7>AASuD;lyx6)b;7{g>r5Yr=)Qlg*P#G6@)+E{S
> VrB
> z@kOcEvNKXNXL0->=A`zDrOffI<CvFvX9C13nB$(DJ1@OD@q3w-
> `d~nunaD6J^(KmT
> z<{X>s6=L@+x%25gc5)lDiDY}no67nV*hk-
> Y0y_hRd8Df_i?S2gOqsnnJ2@qDFi*6T
> zr|_(owN!K;6Js<{lG(i&cJX&;M6~%fOc1Zuo-UQ|wgp3%ZSj_Lu9=4YDrYKOl-
> kMp
> z2>3EwKSr#yb-ef>eja;q)$_4B*SV27Xy=mDmQBAezWAV>sqsIRbs#pt?49-
> Vg1&-%
> ziN6lXlF*B@w&B}g?<A{2@u|n@;?OJdl^2h!{3CT=5#M^nm6zf6NG%vVYfJ15X
> #Cb$
> zzmFY{W%4KSlx&HW@@f~a#_?)L=Brm+Y3saz4K!4J!F%>=P`<W{zaz5bqKjK6
> N^fIy
> ze6IELd62OowU?9<Tpru<&e|NCLXi`+U-
> >bf6C~cg;<78LgMGCvo^HEqsP*c65Kfm@
> z`Dbm7Ki4|HfLvv*ONVf<oV7LfyUcfIwUe!NbNUz9XKm*X@ncJ>Lq4+<hTs3U`
> -Ao!
> zJ@)>f#Vg0yALOjiy(rg6I>EJupZDL+$K(8U^7n!E2TAF~WBah~UXx+_gR~A~?hk
> Uy
> z_$Woq=5Ho{)A=jsuZ+K9{v!Obr{w=&e~=(c4N0SK;O}<+?v*$HzwZy~yIb(;{-
> 8BH
> zLbK8K2lZ1I`a*#35A!jdzgqshJw2oD4-
> #m~^I+a*e~^|NfcxkBgWR$o2gUdJdy2n}
> z{B7lLJAXU)`xAfk&HusvAVHQI3MJ@o{>u29!JpqZ=l!4U53=!#968@-{_-
> #blkayP
> z(F6ETmFGP?W4}D}J%mr*T}R2QU-
> PQgDG)6w)_mEUVz=V7F_|OmTa=r?{kOoG3wC?S
> z=yMDnNx4=EWjp^cZDjT3+-
> f{SZ0_^RGV8mg2rgsD9BgNjW+C#KH|{JsM}7p_bEMmz
> z4}lI7^JGDNn4tFCGgV$4AoXOIr8MTFer+>{$*x=5l0Q&Tty!+skcMVk@-
> QiZmWaM~
> z>p#h6H~W4!yz)!3l~?_a;ZmdoyYc^7`rk^SUVR${L2iAQNNrf*l=?pG*NOVd7Ck
> NK
> zbb&B0D(2k!W<W7keKote;Dguqxrc0hw^689-
> )99uZhgPStJ+2}R_jg1uM_pfD6#cz
> z76@~cpO&R>r4*OtlpOkMcJt61ADF%eyY-
> z+q10FTd%Pg<>#O{|7cj2%4!Qh2+piY<
> zt#930zbJ6#I>nz$<z`X>wa(>FpTE7b%&Ww4{yY4A&V!cz=Yh_n|5<|CZ;$f#@l
> wx5
> zvEu8^^?q%kKL)&|f1yB_N3|NcE%`Ah0xij*zh*awj;Q>Y{Qaf>wDtWeg?jaE6$
> H8U
> zy^UA3EJI3tf9%(Z`s&K0jMxT&FmLS=vgOwIASrGPez6Oi*J-
> YxFd4JHZ+z9(_m9-u
> z<CoWY&em7?rGr<s&H<i0jAW~PgnjE$`B8y0b4ICkgA|&r^%(r37%0np^Edw<z
> Z~qg
> zXENx#_KX+QKK(8K17<H+(Jq+nR~Y_ZBCYiJU*ODjTAAElXeQ;Kx5q2Xy!!gT*P
> e4$
> zyZjG2uRUi8>fH7mFZFb$c>Uw}6{bD<)@{!a#St&2mC0?-
> k4X9F?eWSo<NnR|+(?*$
> zu=lN?^TtP`p!VCN<9UhHQx>H~{`<9MeCV`N3OHRL%!{v$93L4_1X_|ao;AC<K
> y!^f
> zK8Vj0!6oN9esT-
> >;f6%_@~pp_cu6<%=Fz>Xq*<BboX*IV5_vaBPIaIS(i<?6Khbqr
> zp7J!_(!8yCWmW3~=anLCei#4AgZ~zOF8pDP-
> L09W0+XWa*`2oUgVuj#Z{NY8P<9Dl
> zoUht!4Y&9)P7K_3EbZh)oA*Nm4N_axEz}^=@@XP1qpM!#7xVgi_;Sit;ZhCD
> M@s@<
> zEcXc6LtGuX0IaQT!#{?GWM$!4;ui4G)|z)2&qRDCo8?NT#82e2Ha>q_a~JU(Qf
> Ml-
> z(0LT<oGl+(-fAh2cu?Z)kgV)KNJ(jBnfbP)P;53ui0dy<uXT5mdzE}>5zSIWtyy5h
> z5^Bw%ZV?A;(-
> azv&vz9vk_H#K4Stbd6#P(b!2>I^4dwuL+u)tFLmGT)#BK0_UW3<Z
> zgXOa}e$F<I3!=oY<(BwuN({DE3L{>hovhm08(aO>N-
> ?&zYjcYzmm>OC3~TM;v)m#o
> z+#+bL6iypCgJZSgX>%!a3BfL)OJ9Xwsj<LZ_qO~DbF5$ND1KgQf6C!4?}0fncO5a
> =
> z@Jb&)8vBPztMLLQn{_YEPvmnbc4tB#Lb1;aGB4K8X(yjcv)h5IGa>NNm(A_Vs#
> B{a
> zD+hxtq%^r3?hL|Tn`6AIZELg8-
> }swWtF~>m{H{+aO1x0>$boDsG!y^IGXD&&nn_hJ
> zTDiLjR*p}>{THThCd&mh?el8Q5r2_F(B!gT)Q(E6m+61eg-
> B%tqQv~(d(nD=4v_TR
> z@yZf=a;e`UgulwC{_5FpO9w7BQV8t&{TA&&IzE$|FG7~JWh+>5c1a=`>&#pt)-
> +?x
> z&nR>bF!#5YgYbU&u;arbEcEi7ZSyVdXr4}i<P1ZHw&wD`LP-fJI9sU|mr)}tFM)!~
> zrOe*D_$ZVtZIY$VJn|>ELcjl_wxn&fyicw^jnds>O$5RV!?Yii7&!aZ8@;T5?bFvO
> z3%hW^*OSeX3(O*Y0+??CX=4HV0U$@63$8V;=z8hhXQVb2FSzgP&Edb3QVD
> UYw-ur|
> zni(vvoZ?c7Dwnpq-*lT&=I0DicAz4iP2?;sp&Ip;y3In}TJtS0=NtEU-6^#S<h+TT
> z&Q<bZg@WzP&w2U2Y4gcYFt5MmQj4<y&yL=6zO3=ET~90A(Oe95S=$m(RA>
> I%f+m|w
> zc-
> zrj#wTb)_<C2%v&4+)LrMWE6d=_mM2<dPGG8LlD#l7WnNt`PzEbnvlArl*N|D
> cc
> z`56h7+56YjYN<;_SFnW2u4v+~QoCHxN-ZgR&#NTS9~vH-
> RTBftpsE&@*i%rU6=w8G
> zEpz+l%eeQoXK!!zsC;-XmDfl~rNSn;{d2%>w`b4sb5708IZtx72^n4f3SXFN6B@p>
> zyJC}D4R`E5+wB(i*Hv1L^ke9?VGSOGHuv-
> hZEU&eq<%w=X}MMTpyasw*Dg7(v-O~)
> z<8n(HiyQ+wM36ow`#C?9oAX~F$9KKL-
> b`3>JU~&@<;2_)yS@N{bGgDJ61_fZf3MYr
> zKt^(lEtx`3$}M!P22Szn^f5o@$+<Z%308+VeE3=So3B<DQ08kx{3|oQ^d{mZXS
> ^Ta
> z)$A{Kdz?5kw|uRc6<9fPxakd-d7kofo|2oh>rNq*RzpW>ThV-
> vZqMn!dxw=bmykcz
> zn(wXXYg>HA;P6UL@=#r1QDx4AfM@0+yIqhWNpkA=+Hc)D7W;LSBTWL*Oy
> uBN5req{
> zbd8ts*DF1;oRgce9DGi(d<2z~<K=tQ&-
> anse9j$cfbngvxZSWvDj0r7%BbkXTCqBA
> zt$p3Ls!FA@Zq)em&)q??&@XykZqcG>Q>CJ5b7jUWyId-
> a_j6X|<_u9Or{{LBF>O|+
> zKkVgud4&?et6hPu9i1n}`rp&qgtmLft%Lbi?vtiO@43&)$A(-
> y&aJF?yKVf5%~$wC
> zAieg>v?_-
> ^9b)ZNP=4H2fquU@x5%;B^NruQjV`r0m1j5wDcJdCR7cuiQM#>u!ppd8
> zx!3iV<z^d;&ewZ6zv1V+Iya|@LE?yf1a;>uFJGgd?^C(?*4;9C&+cQ{QEjN1e$LP
> 2
> z=Ipx}WH-r25aT8<-@skkMrTraUdSm2%<G-sacUnWC!42=_Wg-
> `7Q`oVk?Q0vk`TsP
> zzLz<YO$o;fwr7g%b74F`Q)q7bV_t|wSq(~__B5&pZ?nvIdn0XQooL_2j0|g()mV
> 4V
> zMm#`{lUnni=1=b6J{$%8rh%BKY^K0*u*~zyn>ejju6FGTW&T9Gd31g8rgvH6<
> sp*T
> zZBNyEr8~NQQEAsfoh;FEI?two0<NR&lF;_`6M-bU87%C<YuA-
> smUY=)u^lvW04+yM
> z5^c5}NQ#ZF2ao<bkg}hpA40FZd90p11w@21ra0wzyI3*}+cVD-
> n99*UQr+zuR89yh
> zP;!RU>HoAu>a~5F7*1|hc4=&o`cUKo7V^1uc6)rBoc<^4*|HGLO|@VDk?n;X|
> JJDc
> zhn?CrgnBWLmhK4jfTh2^KSFJ`FLVm?5SGii)jG43TdKVM`R-
> K@r#kmCe<qCS#;BI(
> zouICvgs(Fz^1~G^q;tDWw>6Y-
> 2H^?RK#t~>U0;Fg>bL6^I{uXvY|XSd#^>VTI*AH%
> zYY>Npv^ew(fKJqo#gS>Cvx!i=0916oL@r5$q8wnEjCeN!5vtJNu^>DomjV$WO
> X6UX
> z<BW5z2J5f)!tv;kAO}OgG4_vJia(;Eb6JX8_>ud&o%UzwpBslkTmMUTbmh+bB
> *)pq
> za<Il8VWqhk&L?P&fZv7er`)}{ICRn8-Km|Dy7!uCB?b0rcfl){k(A{g#V6<Oo<ID&
> z-S#o!%V9;?!!P5fTgH-
> jmx^>xXgf4l&s4h%8oheTi+T+;!##39M6d1Q<0s^>k)B`w
> zl>-
> B8WFehyVI#?G{=lq*F6MZmLW~YKu=Z<#i%;66<WS>m55?A^929WsiDqUHg
> @v>z
> zB(u5ONAV4mpTzVP+t50XQP)@$b37DR=c0g7Pc*+E#?v1R7Sf`S%;qQ`#YaFPg
> wxyd
> zPUVN5UD`u{SFQQZCLNKU0F^^N5Nn+&Iahn0cVq=o*=x(BiTFMA$coN-
> bHDdOkF4lq
> zz0JOGkE|fejV?s)NfH}nC+|jkWW~neM^;eoY_D8FBmw2edoT3J3d)@vMASf
> *!ch@z
> z5JVg7krf+89$E2}$3agi2UR`AX&Q;9t#Yr8dt}8&J=*^P=Y|Y<_XY%DPBe9h8lUzS
> z($Zd!tdLm|IXbGk1&i*{UiC0f$Ow+j;gqoGDpVns1eeO&0OcMHQ0~zHWrCb~
> QWM#7
> z>s}qRPJe57au4CjQGV8$H9yl1Nmi{(HLOcENMPd-
> *XdU6s;r8{@!fV)ekgN7=4iIu
> zwl?f+p*+sXsM)2eV^?BeylCC@^#~?*qjAhF9KdLIH<xk<KfG~7yYj{scDjuofiLn
> V
> z5RYmjru?fgW;mC~P|P<^Fcbpx8<Yz_CL%_C`dLV45#aX1k5AJlIs!#&63PWLj&Y
> v<
> z``|y{!++c;_`h5jz;7X)8+`n~hjzp8mk0EkC)1F4MHiue>m`_I)^A!bCz4pVM#Uy;
> zNYSZ3kKN47Dt4+HQ?w^x!Z%M^lKRJ{-$x35Ctt+{zsnqcCFfnn4)$`)BS-vimu(T)
> zKcvRb`nkp)Y0S~A7yWRfSa<5eLCQb&)J*KqP3dADi+Ie>bovoQHh@S!2Q_?1{
> OyR;
> z#}=`}L015z|JKScyH%~uq&B!rrCrI<7CCy#UUxIZfsk8EG9RL2x7RB;+mCT%1|#x
> W
> z>L|7(%%K|iR`$+Dre;kt_mt<3=BeU;<zG^L-
> ^sS^{7$a!l+UkimCqlw%jZuv^11Zh
> z)keSCcInsGHt1LLQ~LG9I{o_o_xO6`zUFSeI-1M*%nRi)<ibhy^|sZ7lWje`ZEFY<
> zot13f!E+;Sz_zwd78B~s=UAJ>p6zIspXiYGR6{tqdIvw+^c5B)&O9=4%;r$(<>Kh
> A
> zVoTys=_Ne2af0Pg>0)`QEyL3N|Hym)__(Vo|9_fJ=+LH2z*H(fgDqHT!D>MYX_
> vM%
> zSh3M0G=L}zu83nntu*0>w9qga$#fVkN)&fdsYPWKwJTjHNNZXuNwK;SsvD(h
> =tg~q
> ziEGqq1IFg_e4YD#zvn$kE9^e@kMHC0EoA0B_kHiV=bn4+x#ymH?z!Y7Ac(waI
> r>xP
> zZD=ssr386&T0J>2*DmMFDPN~?-
> mrvr;yLw~FR4qqZ7<r6Q>$#3=>yykX+O2)YrS1O
> zzi`;{_ZG{S?C}`CjE^YqsXyR>!})V?0bqUUVS_}27k7HZ;qqVRou>(jDc<dPzs}eu
> zo*VKo@5Qon|1nx9(tasZ3jXQ*G|yUnGKv+Auc`WBHLF=dR@0F9_h<54IIn<e
> ka*3F
> z+M1eq^U+(OII%Pe)ohJD$>WX3@$d`}ywahG!X#o~zm|t_<Tv_zmp`G^gOhb
> fZ)IBM
> zglwV0)5_YK5ee`je8<Vh(^3yfEXGpXD4M$0iAY}`2&NcB<mu5IsWlQ!D(5Y;ovtc
> (
> zg#H+Bw-
> 7}{#<GVAIHvl&uRVTPd^=T8WPjE8{yBp0vkYQ5U<|%tj#PJu?|s_m*%jjZ
> z_E*IBATp>(-
> }Y8|FhRI=^|pTvS0H{}e{_}PzdM?L?3G;51O0Q>IQ{cT@iuJzCbpTN
> z-O#<DZaU{)r!nj;9)!5&E>j4vPQ~<4<~`!(|A0IkggDzfmDx3%@m$VS?<eS174|;%
> zvXMzkmw%#gWO)=ES=dZol+J5{I^I=U2S*mp_P)zN3+r$>T^%ayx%2S0JYwY>
> TbcBx
> zTx60W(Eg@Atf*pj{hD?A@pI?+q#bFO#z8<Ju2n~AC@bt2MUt7XK@NMJGCh
> Wnpg3ir
> z#~^i3Yn;x`*^_0u!w0wbW+@e@I|5yX!#$S?oF7xTV}2U^IDXFs2Cgz?4HbD!a
> mVZT
> zuM%w%g>&Y0qMcpg=&&}R!`o;|$cpGaka^Vm4id@{V&Gta=8dXq34xAOcXl!
> IMn5_F
> z$j=(9uepx2!{f>cMu*rXYCsSvpg-qGMysZYcI3&bF%JF09jVVzd1|IGE?ZgYt$C*!
> z!urg}+9LhXu#FqGCQ6nc7J7Q2pvN!=lvLBTShq!?y7d`H(jE*POYp?^5h&5=rqJK
> -
> zS#14%B#n;oVfL1je0|_>)4zAT=&6h3$6H+}zqMj6M`1qm4`szUKFEha)Aoq<Tk
> 7E)
> zoWF_>+h@P@R>P~_`{x@(q3LeJeJdQ^mC@!S#cTz0gq`TWmV!+HHrRS+CtB
> Bu<@3Y8
> zXHsXk^C2@Lvh{w)EvkyGciY|Ercc|6J|NkQrVvH6dp+3NzPkbI5U@t?oAZ2IT0d
> &E
> zzwd6?+P?cyr63jwgzdW<h>Sqgd(WKcgV^YUU?*B{Xf3zs`TOowrTgy3lmhO_7
> F$~t
> zw)R)9wNKbyE3Lif=D*WgMdOZi%i&x5y|?(N{$=H1TKn2k5Q{*nq_yBv@9ksr
> %Z!hY
> z_#o6;-q2d^W^el}-H0yfx3-
> ;M^u#HpfP31Dt(_jWmcCQp?y>z?TD$3{ajkXk0jHHh
> zn+~*8FY?zhNyjjN8ohG^G%F%#@`mAkQazlc+VUMjoPF|2rTm^0Q@t)YQ+^
> K93)RYc
> zSiN`|3vhBcLubvGOSC+VpDSL^__?$uGJb}9@f===G93+aD-
> DSaXg8AGY)>={cC-6_
> z0jbCAX5Sn(yYEvp_7;8EZnkZJ=T)S^`%$;wJJUX79h~n_dT_1RqG$CM1Hhu2t_J
> xA
> z?@cZND`I}>l68m!I_vh*dU`)eXR&vEKa(=_8O~<}(KfDCu{N&Jlf4gg3N(9N_ou9
> 4
> z@qY6g6fVkp#tx-
> ftz6MXoa@J30?Q3*{RDE#>%!rI05<tvKzmQ{qYKJNTqMc}QkdCG
> z@=%@tVw2so$1`$`sIM&CI4?Loo9`iuUhBK$^>G1^J-
> pFohjQuJa`~LvtR(_z32fnd
> zuV=ltU{FL8sLW<|k)&7p4qs8Mli$5QZhCg_uyBD_MK=GWUrgWOD~fI9ceh_
> m&+Z+k
> z&#@MdWIMK~*c*(9R9}_NY*qr*>sxtqc|B$G%4nz7f%!1cRelTf>|oLlynBe>T
> m1U;
> zY%n@RShg-
> jwEA3LRKX2FjVDnJB~fi6QTUT6R7q5=B&re;1&@KEQ2B{myki5LQlCmt
> zS!xv1tS`HV;O_?Six+6*EVb}32V!f_gx@}2%5M+8-
> w6lrkw3!|mH6A;XmY^Yq~FFN
> z3PeO<xp>@PT6opnR61QBPR6TJ?w9|*KPY0?8E?9Mj~-
> 228Re+=e)~<!k<IL*Dd}zc
> zbo(BseBDM2`yTgx7=E-
> j@!(<}Y3pWXpZ~?82zXWV@8^aMkt58%>A|^A*ZvBX0JkNi
> zsUnFx6{nALfE<#vKuDGI%5`xB(Km42hVsN?Yb856mW=;cq+Yl#nK_vhI>pAnG
> b#76
> zs?9dw$K97(R;9ZUxCDv2Jf)x>O18;|hk$C=ccOpn&99h12tk<`rOeg!NY^3)1V;;d
> z5cJ<wR!-#A^>~wBBW-
> ^OoF^zW(b{8uDK~IGc?NXOP07hmYBpfG(t7^;SAV##<&Eiu
> zcb_GNs5+%@?@z`Wxc@aL@#AMpaCDl|)gUa#I}%>caY9ab*VOekAD>e5!Jy
> H-Cboyy
> z?dKr2^D;tD@rs~t-bx_=6d~K6dwatB2-
> yb8M;TDWdFxAmyy{T%$qpLFNgcE&%#L;o
> z8PzJ>5r4%-
> 4tlN+(&<l7dff3ot!M21heUe*q2|+RuC&gITm@l<hc!NGD<&?9&m%?w
> zy99N^-rxQO*3nr?y|G+c0$Z+%dE5`q61Z-
> }`%mR^M>l}a`e)g=_0N&+he!M!YB|O0
> z_+ubcy({ezdzvnf9r&u42D|(kF1$$8ly5;tUClxXR~5HV>gAhWBVc1+a8!K*BQ&
> =1
> zO{rczlzHnJn4$7+dCvFFC{|Zs6R|6%>cT>)Zc3&+KD>p$bA`b~9xdQN3{(h`e&N
> &|
> zFC3Mt%D5W_mrjnS`zE-
> %%~`Usgt*^fF*m>>UWx_Fwe!6PtZFsD`#=;6SIA)@INoD}
> zAr_{<$j^86Vu`9S5cJ<gOji|RBUwdFX0+)qoa6mzC}=mK0ARM!d5Y+naA;o;pj~
> $$
> zLc9`Pf2x7}ox=icpC~wo3;hQ_G+YMRh&R2^5SDrWDtdH6%W=7>j(YdB39<bXT
> B>X^
> zoVC#<FI&nbm(3iy@eVGqqPZcuv*4a<hU~_+M(=s|8_U);_2!5eIu#!s-
> rH#P??mCD
> z^`LE`bQ2{Zc%NQc8Hdl9;2;&JaKCT;9^C2}ImoN_jI+0d_UJdJuDHjTZW`WI5vIe~
> zGTUoKg$q~CE@x^P*_}Q5xfg>zmdwK-
> ?X1xnuiBP6CDkU#v6XXEH@GUk0}qE)&?>vr
> zGz}#cVjdC86`_gdMRqEPHE6xJ-&Tf5E0^;iMicT8c$bte4JV1>FsKKo=-J${kWHa2
> z#J3MJzEk7I_mS?iG~_E#oIj(1Oi0f~))^gN6Y?SViaVE3o8!(gd?s%Hv&(;EJ`0cx
> z=%p&FORDtYBfu>f+U$T3u|<%KNO6$pR5KzHLg8Zev%p0IT2b~R213CfB+8*V
> aEpH0
> zZ#@9*b?w~CWi4wYbQJ?i%jV{f=!7*1?l#$B-
> P3pbl~PD8m#()V_Wr;A&1g~Y&3#rB
> z;I8apMKX0@)<G4EU1vKKTrG7VySRcIn}ExfMR&DJ03Quuzcvgbco=9;n8L`cs82
> ok
> zGoaWRQTu3@eiL7RTz?K8VZRh%A)tO(OF+$jvw`v{5^M@#I#mcZvwZY%hZIq
> ^lX*G3
> zGNWy@(A*0)gp1EU7dbl@UvHEX4=3ApMl$CrHb5!@sekJ$B9%g{i(xg}S`h18R
> V&mu
> z-I)IaCR>=<icssl-#8LW_TbylZyQwog$s;1&k0bX7VF2dW}+t)Avbytg{52A@7pIz
> z`^|N6Qcoz!&X0Pp!y)?AzyX=dqWfM`pxJpCFd#qi8WDq&ke$vcf^Fz=BGmY8`
> 9?*F
> zM7Ig4@6miZVMt%r3gpA5O+GA5HS3|w`}BWD<b&<aV%TzdYJ)r<Da}(QIkU*
> +xj4vk
> zNi+|O27*7QU#@OJ?<ZISJzP<Ek<|6awl{UJTigA<=J|Zy*qq?==H}xI3w&iOhh
> o-E
> z?m-LMAl;F5r2<9lF5?L3fVz&vqv=)@zVtI?#E2+-Y+k2~qPx`B+G*XT*4ho+`~2uI
> zafj<a1-
> O3EpRWCFRA$+;yvYdGQ0%&#sUeA7753iyYoihy@gt0uz|0ji%{5miFtml>
> zHd)W&iMA)VV}9(!Eg=13b(YVyohy=ebqN33&g7%*ZBN-
> *<$Asb{$i~<kltUW=Jcr*
> z1=gMi(%tB*5+CUo4%uZOgRRf3<0Wkux%yDA1_vHj;kpB@FT^^L1YvnOeYn
> W$gm)N_
> zPbdISADf4AyJL%hSa)Dx6?x2-8p3!D>_nm{4k%@78XS20xNOG-
> *=h$*AN?MyI<T5y
> zxx5HM1bD^}WVmwEyDF4PO%XYYNQZfdNbwBH`+)&YUOB`upcV5mB?)oT1
> m`j3p~U`0
> z#T@c;Np~-
> Te8x|fe;xUh|1Q268bT(Z_RaI$9TG}2=K#K`_sJlx^J&HmEZDTy5inCj
> zp=1DAz@BZtEizLvbA+EN2zJS=3_m>#pA5)IY^#g5Z%{XT^K7}Nhc$Y*c4x<gY#
> pO#
> zCFWk@;64aXdcQDzN>OfacFb=^7;`f)l<T$<M%UsQhA8XcOn~wieI>%@e;iTfd
> Xu9l
> zhnXWNzk7dx@=L-
> |ypLJFBK0r`fo6lZ3{xvomy=I+DbLPwyMycin_O{((t&{<VX!60
> zeZrXBEbp+mD|eaY{<3m+2Dt}KD-
> >+zH10o}6y{cdlmi8>23D_|2ZhLBJ{7s9ErCy0
> zNQVE8kl}L!B|V3;%v^8cZz4SxW{!}d@r8g4e*}~p`G*m7h`)nBKk-@TF~<eT-
> LwS8
> z8IDvxy|j9Bq-jIW1X8G&*;OwP-
> gDULjd2P$x!A~dbmst?f==Y3lHSN_nGCRoV!{w1
> zG0v{K(69$tVQk5!^>PCQC$Jp?O$`|iw7Y1?wnZoTFJ;eZ;2^9yh2=&!ZRh@5{*L
> b?
> zcER@+$ByFrOMKtP-&6ekns;aO-
> NfHy{@%d*SVj16LRt7&`Y<v48Rx0|s7c{(JtU4U
> z{+w)&Q+$Qa=_i}V=_f-
> +)KB`<Feceg&qDl!DyBbkYEQS{rY+VhY{@vqWQ~o@{)l4o
> zJz!`#ZdZDgC?=UN=~a`<>{N!<{jqhZESU^%kg#R9pTcL=T2Ap(6*kAMXBZ~%c=
> ^Dw
> zswx7Q1wEcNKfPa_uk9kkApmO%%_&-
> 21!@lLfY;1<U$E>0bEWe|fT3;;YzB#eukx|-
> z-
> KmE(J(jJU?_GC}3RH%9xuhh7nqJTvYrZM<0JgA5{b?@Z@a_l)=NoLFEI^L?zm}9
> B
> z+!fzIjj_U8!y2Gjy0e;9neG9JraG07FoIT~eBcJ@+-v({%}db3q{WGrXm6;wBy<Hj
> zY#1<`Xxflaxbo65aV;+^eXYz4BS_v@L5kLo9OaL&83haBRm1hXGplemoZi$}-
> _VfS
> z^Yr4_wWH^%3g<$yE4y@N;@a%#N+Ijq+!b<AoHOrrxm6YELx-
> AcfN@Ux<wMQ!nm^uj
> zcK)23^6!15GB<^ARq5N}v6ell3F`8T65h8EjGE2uM<+iDo3H&;xxiwqzxp5F^Aup?
> z2N%bWBE`gh^E~QfC6}1j?KQ6-
> 9c{{`rjM?w7+qC4x~j_i2U^T(;VR2RGqPn{QK@2h
> zG!w!n_r}qWoizHf>7yT;<xTT5?u^HpF1!5F+>7%%=RH5~*?E7N$MKu@T#frf?
> #0|6
> zayy{c6tJ?lyLmr4`Wr?cL}Jw$ORer&%w;i?xbP8F<u`r9%tT|uDDjHDE$Tur*_rU~
> zhs6MDOIBZ%yfD>ijOdNJ$<gguv;MN%V+l$3HEa<K)q3w+&PKpUnZyiQ2C=;7
> KgYYy
> z>ho(y<Z>o48!Mdbecw_S1*xKHK}G(9hm9r}J11<?w|q9Zqh`O3BQ`6?H_3stO
> E1XO
> z^E%dY<;wS@witS5l=W)fEL<2W!`XOVSy-
> ;67j(GHXPJ*c6+mrsS5a5B4K07}t|imO
> zcBCM9jRCp+3S-
> $YCTA5^0sS7)hA`X1BVCK9OT)3EaeET5iq_p_$66|};EfAPeMIPy
> z22r;e>pMOJr=|7^_gE@V-
> 2s{Ja}#<%X2SO2N<xvhS?!E4s%^di6dJs<uscC{|HUY(
> zKFK!p)F5D5gY+#*vKeeokti+T(>gdE#tZ$ewqDkic>uLXIsFw%cyCRQOYC=FX1f
> d5
> z2kdgyb$V->m?vxdltEsx30zipWb^k+joPNq7*p=tMr-
> mU=C@SEy%KTWSKQ?7dqem+
> zFZPc4Wn|V3^QVSC6IflY`kC5a#c54o>z{Dw1&5ra3`|mAu*%Qe$NOB~KDE|gl
> +0+4
> zG-
> v6oFMV?n>&xXXSA+L#kamc>ojO#q(cA9QoCB+0_UnGW5+Bw~CHb|XqHl9B
> &Fg7>
> z!_1!jJufG>@6>VNbr312?b@I=Vc^$RAEXHbzqSQY46Hp3-
> mJr7P~l^sZ^NKNPq@=|
> z_Qg7fxtNVR;Iws<AXVKZZ1t?MnCs9}w&Pwt)7$i^esfN*siPzP_Pbvh{eymUIW
> P7u
> zW04(dOJRQ3Z|42_mH+hnZ6>hwPyJTCLj9(cfp;;R6~h(hHy9rJ6drz%+=>VuAN
> W-X
> z9xms_-jAM-;1T9`c$lmH$pIen($hcTao?rFLn#AYoLJ~Gr$Lb@xC|uopfIt7KKJ#c
> zzEHi_C))Gh=4EnwhrYr!ww9pp0~V+5RWy0`3VtNFTi*0b)oV`o3#4DZ<&M`Sw`
> UxT
> z_85$wej%C7%l$(gq;IRLLr>X`&3xuE_L&z_$?f;<sHV`4mvKZ?Le6l_W@0?2x9M
> |I
> z@~&r5=5u-
> dARO14=eaqvR<@m(8vlbvcC3<*8v5KnYt~uR`(&GrROO8n=sbyr^?r`;
> zs#UvCSi`p4I>0=bT|0cUdggBGqxbfL9s(~H>AkQ0qNMkfG1hXiSNZcu?}hnY?+J
> =`
> z^-p{*lINuUsR2K4P^*<Pa5U}AcZlMqhOakrH+Tt$^1u(!VSJx0Hn`ZOVs9#l1=Syl
> zz8(Sg2{dpYMf|SHc8p-
> O%VqSb>z>`iHvO!;`5n2u9+HpVvjy^w&g{6KFCsRkyIGnI
> z73N?mO7CX*IE3>xSA@!5GNgOlho-
> KB%*ukDi!4mBLjyC4m8M@lvt<_NG3vcXtPw!-
> zv_@Zx*_-U_qYbf(bnxfdCQnz4d)IeP_PH#-
> BGE(Yz)y8_rPc)bz%xAi%$6QLv*nb$
> zw$HB&0NbIPwXE5U0)T7kx&B$e8FS{Bml5*5XW%XaVZ4y-
> 7&e0FGwr=So3V#&`aC;%
> zm)(4u*AIxY&k?2Dh$2%=`lTEE1*8~9bkHPMqyyVqLj&@_43^+;Z8^i1cnuTMF
> Q3zb
> z1&>uP))*`gLs%Xlq6)M|3e0Pn5f*q$%kd=z>=HQ&6fO<GU)y|Mu!8(h^Bgi8jv
> vLc
> z=$imqnsGKD6<gXZY^wViuE6;%*%gY1fd^@>jJ@<QMy8<x8EF}lFfAKc&Y1zfb
> F%pZ
> z<ji&GGyUS?tb5p|pXVj-
> I++5wjDBF4TDH#&Qx$vxw{`zqUdosk!W9Kxs3f(ysVmd2
> zp~SyDzSmwSe1x)aT{iO&$=9*7&KC|cXgkCm;khB-
> w6D=SdcMpB_#~)sdYgf0h7Ec(
> zGZfA+?mIUG)kdcEd40AU3}mG8<vRp0+cYw8^(20YV<)&W*~~hFt502pleeF
> @qH3Rz
> zoAv;k`xHV8tM@+kX{y&ruzdw24viAwxI3#u1#)sd9C3w{-
> <$CH**kyCp65QssbP6)
> zpq3ma^RZl9H?SKm9ip9X<ny@(@Gt@U&!h4R8G_#Y)0wQMo@|GH<}5Lrxdj
> Alteg$^
> z8;U4~^o3C!12)@5iH#4cDQJ`aHalurzFCNOsC3R?;KuKOaYgDWIeTrMO>AOilvg
> Zm
> z51j0?x3lX;e*99lZeQU&R>{#(f@L#n1UPTttrDFhu?HslQ*!niHs;5%xen!(@xdM
> d
> zZ*OO7M|j`BH(AtJ^WFuAs(G1J<n}hsP!OYJ=0Um_dmJPhgeFFAW+pxJ0!GzS
> Hgkh2
> z*rrcS+3il~|1(q%RKD-HsW(s^T+WNV6Zb}hewg10eL?Y7;#*}Z-*jN>pM?Ie-
> yxbR
> zWuOXv8+eh~MZ<1?b@OpVIwAc!+)DJtm1oBgErrLNO=h~F$vAu9QOYnKs6o
> NZyrbGp
> z=Qe^DF@g#CLP_h^CpB*5tgx1KO^+6Rh1vSqGA$_m(g(HV=`jjbw(^Psw@aS
> tf!~`b
> zbNiCiuSAqJA`rf;J*_*hq5%8DGu2GID*9}7jWF-C-TI!^9m<fcvr|$A15c;)PRw-V
> zsmd)I&eg+e*9gsyYxxv;{&I<2Xz*6RpQ6E^znBuA<o8HJzC)QCH&*0vtnt3_3G
> 4IG
> zp7bsvAv5aMfo1a<*0O5B`ntg)68XmIR^a2s0$eQVYcwBhnPVeDg<DQjvDFTR5
> pD>n
> zq8$5$k#ekG%&>Zv?j)1|w-
> z#$jhLOz$%FTOQWTLq7?{F>g^cOlix{x1D&f;u;iJLB
> zb&!~`jN<kH4TBv_x7G6-lv+E?)Z&EaIv$#jf4X*XZqD+iI~&?-e}}D!4vH1H<!V@P
> zie$i~F@&j|w{`{hkQqCgPqx9bgo<pi)KgKmV+Egf`K-~wmTV`R7(C%H`LeE-
> ^b6I^
> zOT}yZ7d4+^nSTgx05ti%&d+BvMZg8ZhA~xt+kgAmn70dk7$+Kxtjkpj-
> ~<Ek5%-GN
> z$r0d)MGp2gFG_Dy8)A2yx8~^dHq{+lJtvpf!@-~BtbOTcW2hSWWh7-gmh)-
> Tkopb<
> zX1dGkUc3BZCZn5Xa7lG~qvgb0hoIy#f|BlwW$kCy{S3w!fMf0w@)r)$?_)=l12
> M%A
> z(MDfC*_nABbHj$AW#{U8GQ00MCYModQw)6bZI}~2--
> z3p>c;I%uefjft;~X*bF-QE
> z^3%^@`N^mp+_!xPCT;`d+Lhj>tmof;T&_b86FbClS$k$aTc1~AJ2t`*!((LNgOXjf
> zk2#^sK(ze?H<5_Ln%`*G!7;TnHc*h}HWP^5FH73fvAM;gdTV=Q$;=DT$M5(HH
> MMCF
> zHBW`P&w>_4yIC4D_+%(?c98fQE5ofuBv$*0XpXaM_szytJ+l<7tyo3NNfBK-
> m)DDi
> zmDS#rj70=h^c^Nq-M#AF;a(X-C7Nd%nD}AA%=KR5^2+rt+4duPPOVRVau-
> isnK{&@
> z-
> h=?zjzz+#c3(ELKo5EQ?9ivpcY4r$UpAyN%6nZdaa}h5BD2zUxek3bt~@HAnai8{
> ze11M(oEPPeG*fw0QO;`MW-(V)dYjeW!XQv)4i32mp{5?Rq2h`t*P-
> `~K4|Yw`Vg1{
> zS1R9$d7FLM1y3M%bss9mn`>MSe@(b%rgcQT`J@t<B6A~TCW@HA*<>({nL
> @kN|1n1r
> zk?r(85ocfx#vnJ#W%E@Oli1y}l(dX~5jbHhNA?RXBwzp{rt&9#xHz`%M~h>R@
> Hgu}
> z7ROrnYvpejf1^E%V`Y3#<?kTx2l+dJ=NbIP%F8E|yMJZn6U)ovz?w_`e*Px#_j~
> ?c
> z<}ViiyZ<Kewyc<A;)YM{T^w8R<HfNx&n}L=_os_vzv20-q&4z=0l)8iZgK1jd^hp;
> zY4R-RJH=n^&#3E|3CG0vulTP_j}woHyOi={j+z9@$4t`C#L<(FIcCZ+6~`PiRrWZv
> zcXPK{q!Ct;{<uz&<CIH~#vOPHR%Ry`R#}#~9be(9Y5W^2>=>@rAh~1L*CyJ_lG
> |}T
> zd_i1lR?!OXrqd~sitGffoGKbQTZ@OvwlAv}@jB7ruu*LzR(4G=PU5EdO214c_Q
> k+N
> z2Y#xX-Npg!HfB0+uMW;pu9w%%0t##SjS6tVs2#oOiFmsN@e?bH?W+vhSC!-
> 1G8LqK
> zSC6UVUGVApvi4d=zPl7?eJyURJ<d+d>fb~aqRc9-
> _CELwNX$R8MG6S4UD>emLT{7H
> z%vqqa!p5*U@>jtgC(>fHwEHvo!DYz-
> (#7|HFTNknHMlIr_mT3~6#?)bf0&+e`%Opk
> zU-
> W8P!M(GZ12=LD^KY*S4pccy)5>#Fi=3JA&>m4cJk!RO@@#MA?xMo#=S)?T-
> Cd9M
> z<StjDd$jN&wr3i>_uQ$3&~r-
> LLG7L;q1XiEraPcxe|QH|pNdLucu(5iq&#S#Z+H}2
> zdr+TtfRC_O67jFnfdm-
> JWRbg{DRRG((Kqt`n&i@$_ciNFyWwf<d%K_Mt}*XR?}z$O
> z@vZTr8t301WzgS#<o5>sjnVh1IO;;+|HM55uD^%I_V?h-BkV77AK|>t_S)a-
> >K`E4
> zCPq)b>9^b{#GuUA?P*wfRDG)bH6LCyIxWT4S78!fth$8Gr#P`hf6F{}Z5Go~EcR
> ~p
> zQi{Co``6LF^l<#<nYoJ0L#zSQFOA}7`Xo=yNwkdGL_@uI24xZE?A%Q2;YH(CZ6o
> R3
> z<4E}!8T8vS(7x8e1(;+)`~1kIm*rZjF3+t^T%P^+U5I?n8}LbinD<U}%Umz)m3h7;
> zdAawdK-
> E+R?E<YFy)1WbGtI&PH$XJX(Vs4qsv*5jkm~c9z4}_IqcVO5_N$M{cPKgA
> z(Zi>#kor#C2aA`fGj64SavWRM{lvH=+uK~lzYl+w^U9YuT;|<Mn`n!cj*UFN1(&?
> d
> z6VlrZ>6S$1`DEL<By+dKG471CGRi;2g<k9!#L<ySwOfd}r2GM<vxaonUoZE5w?
> q^7
> z^vv_kXXOmNTwWO)FH3cQPX6~Q3|%W&<fu?%{pfQ8--A-
> Qb5|J^j3|&L?_fq-JxlNE
> zY5Jcv0gvW00s!NNbjfeitCsTbZKf(8kbzRAB?JsW^}pnUGPI(gGJ4fgzV&`UxxQd
> J
> zXke5!rq+;DpL6ZMykWFMbYpF%b@Nf9({8Zs*^#UNao!K#<0U`h=JsH)^X<k*
> <+3sH
> zR9?;aQ0Kbw!ThBgx9YIM_1ajGpu%HYBc^E&>eT;!#29}k;!*x4LMmed6_0J3V
> Ms~$
> zCEI>Yr>&bGyYw>uXh3)VV-
> xb%&W!ojv9%nW{iF1bvsz!mr6rcU>ppVlzc51KdAkc0
> z{`D?g<;Fb{_f$g9_Is!5CDT~jvs?+)vtCC&+jh4cyga{6FJ|vdca6II@0y@nVt2Rv
> zCD+aMAGtsN=_|QzE^FO72QYtnFxS1lQbnI_Ip~+%k^2K>*OwOa3;pTAs|)4d
> ZD!<b
> zR1<S~HSf}uW%UhS6?!Ry1aVR~f|gc$gWr=zpQVh3$oS8lyp_`FzcQFxDkKO9d
> B7M<
> zw*8)Fr=I-$#Y7lb2Vcl){{tm$CW)>5HA?%-
> rYqRZOtyW87s~K;zUkTAWfiFh$<~m%
> zh0pYhGaFN@c*x&geR=8{9#YfwE8j^ysThw9qdgQ+zRUBqTiE*Z8oUjFO7EJV8
> li#t
> zrY()BVLfo@AvLH6E6gpew}3|e-
> g1HB5QebH<%NGfqa^MXxU|75SMThaCGl$XIG3}J
> z611rYfJBbVz5lY)(3QM)y#E?MM}+r%d2Ht;DkL?fcQN~2K5umP(|Fs6e_-
> VFOO-d4
> zKMu3UYF=7>=K7Q7vdTz4`h$j4KWBw}4AWfCsa@w?744_!4&SFI6u!^sgh%sL
> w>}-8
> z6ni>;yf)TLCj&SBS_k7}_<M`b-^n)l&t-^hlx!m)Lo6q*F5&140*=<Xfsmso2NxEJ
> zpBMe#@N@nDnxDI2hmC5|r7I^QYjFd38^SEY%(r}~D3)xdE4?2GB5J-
> oIv3A8^v@R)
> zb|mVs4gX8ud?|i2>(q)|Jg+G=TV-
> EYJ;mG{D2{%=yZjs9s~!8P`s^ydhEM&ooc?>I
> zWvA-1t6aIl_f|53-
> $vz${BD`xLe9nN8__UQJs_NVhL4p?Qcvn@f_LT78U?<N2uoaf
> zMU*M1f9u>oE_TQ`{@A+t8zsM?$EFmu2KY9tjC&bd9mh8+z22L&T2){P8-X?r-
> hCgl
> zpH_&xpLcn&5kxC4(#L!WPD$<h7n`*%Pd%)MGVk>})oDK7c;BN=^4q`0)-
> P@IiI2pc
> zH(IUZ>EGaIc%RDvmUb}X7~yJ>VHAU1K5*rS_m5z_qHL*0u)pa`PG7@FS%xe
> g_%qkO
> z7w3-
> jf*<aK6DG899)INeXQ#LBTm@;!m#zAKFE5Y_&Yt2sM&ZWs6Qy%r3qKE*VBm
> 0^
> zeCy&rRI>ho(WFAh7@X*@;&}lfQj91vbM3oS%K`_0P*hlF7W~Ap!t)2}R~ROCF
> iW9c
> z+K_u%xN|q-Yflz!<xmo-
> zwl+h+1hdN4WCeM=2`(uFEC&+Sy5D{Yy9zK^c&_pkrA(|
> zrm#KedhlmGG<WR$zw7V#-
> !a(`rM#CLk7F&|KV8X{m8W=n`GOnV4aaxQx31T~4bbvW
> z8%wvcD;QF}##Jk)dtaYw!XSufaGZDklUgvb83e@#KFQb0$=+8~XK_`;i1*3ba&
> h3<
> z*63}1ZP0VC7adtS{pduaqxYNd1|S2EVI6N`(Uh&S-r<@dSKte-
> K*{oH3iW@$)&B~M
> zCpTUr&1TC=1MqXqTVM}MO<sAd_r`M^b#z+Q@tpIb3&u0$eb%72PNKJ>LrC
> %oLxB!w
> zxAV%;`}p$=qVl=^tRL5(M>@abn?ZqDQ+{CQ+hRALkAyhS4Q-#@tO-
> j`u`1}LF|>($
> zZ+E$&4L+A+S3ckq#0x^M^xb@su=j3q<P3&>S>ep|!fP3yv6iXc1y2Nhg<(Y0+ii
> 2b
> zs3%*&_X;P<Naj7_QoSi*cE%?M%-CC-
> ;{E0E0LEA;2R_J;BKz){YV11=Z=aBTyYUX>
> zM|xqL8__4U%rSw;p-
> 9w&VfiQzYXl%0(BX5_G!7WNx{AI~Uzp(vP1KGv?R4=HC5TPL
> z*`3mC0%1S`j7|^%22)2e{lZXI{FvZc`i+8!HYSL{C=JD{-@mKI_3!^({F(Xpo4B9H
> zC=A8D9mhD^`_fjC^|heQa^~uka;7TvVex1F@Q5q%D&o)hb^HgzGE#@dpQ(
> w~aZRKS
> zi$9Yu)^P~(5sxHiig9Q!nYwugGxz^D;?D>b<ch31wa2Ta<KoZwbm)SILpmU#7*
> M0$
> zTOJFD{c7XSsJ{PA{23#e;?L-TQS8T`(XSx>Ox&1aWu-
> SVNvMvGKhySTFyac!X>laF
> zjSrnw8}Jlhpro3=7k@?t#z>o__q^%#@gqrMH@@?=Cz<jyf)Q&vhB0S#l$q6r<
> =>A#
> zbHunC5Bx?#VtP~@YdmhP$BEGUuY(hcYp}l)Z{y$5zMjqua#l2mw&CHGX#)Lj
> Mm$nZ
> zfdwquhK;W)zQp(%`XV2_`iR5z`MioWcs)OnoFWeW*G^ZbOwV^HJ&3l^_%S6
> ~+>5Iu
> zth~i80hd)S&Fw^%QIAF2DAqHdDim!ao(`gI2;%IX$5m|*Yh$<b|KL2Mt2PpA<C
> m+#
> zI$f-
> dAG!oA!PNN_ed4`m3(7vRHu?bUy^|kZh!fi3$J*FOa_1LZ7z{m2cUG*8?ZsFd
> zy(G)Zr0<f~VXTe4yxHsn(X-
> _u*2Z=&+mT;F4`~nk@Aa(rkysmhNKys*4qs8Mo8J%m
> z#q{jng|Rkv`Ni}dzM@zszwh^p>Dj#tV{JUCV$oO|Ta`fd`c~dtUQfjG;M1lNZ7}h
> y
> zU_#2LX9v^8+SttR4Ss!kHW(cuCc!d9G<GOO6}B?fcoNl664fRWg+GZxl|<D_qA
> DR#
> z@GuSsu{MV9WU5Ndr?Qe*8;WJ)9e1&KVJUj2h08b-
> Zu>l3<RrRrbr@^oZQp?>h_&&i
> zH>pUqcb<M5heTp+e6h6f1DbbM=|daD`HmqfZS=N1>ko;0UoTM8U964eWX
> oriqu#rI
> zo|HsljQ7)&^frCESR3ED&Qt(mZOl3oAogZ_tc^Wa7T2npl{NlBEY#8X-
> Bq4IZ_qy^
> z1;5d+H;kLFk97Vva`wDWdwCq#+>8WZzFnNUUk_#8=NUBNY+-
> rM^2+}$m@LAasdbVZ
> zD(qeUu$4fao&~P#V)Wf~ocHYJKw^`Q_Kr?3eTTb{yFnc-
> @Xc5+5g>sUD5YyVR&A2l
> ziLkxrxuN!0;cJhl1RDpo8Sy60Z$N9zzDJ?wFe{Id=5cSTtAmrWoaMyvT@i-
> 6YAZxh
> zq;+~{GQEGu9RA#0LR<(KC|ny5mcg1~x{Cx*@1623Lz&Qz2fodanOm5z%>-
> $YuT--C
> zn?cDZtmI*pS=Zn6=jL(!*>{Bf1nM^z9aKJCFga{jIA9eGD2A!E7rO<NJqHsIl%*?9
> z)r+7juEP566ItDc<r31+HywW}=^N>qulL>OYHf2W*+v8^w9AT`sZ#5ccdd6Mw
> F!`T
> z8tez15Oj|1q&4*yR*G2OmB$$-K5e-
> fS^))|U%@_lwWhXWH4D>yoKsXF12g=Z<B(3f
> zqv=e+KbStZdG=F*`x{Y%^}4swTVPmnfTTaxa$9MC%SAJp?i(^M&5E(gb%4*s
> K+Y{2
> zvF*-
> %#2qH0Ao#G|U)uvd?58SHOpo78w!Lm^aQHxE+;{7}?;1{}8)Q?UX!?&vQ8*Db
> zbY3ZDI?L&FboN7?4uR@FRf;-GG@la-
> r|6w`B2tEq^j5=A;VSkW8eVGh(ZM>WMn8$Q
> z%W8o7P6!zIs&80n7<eA#Vc;p=nIRx}a=;E7shb{=__8(STS`Hk5P}$D*c*u7@(|*
> p
> zCHTNY>{SfNq!?kYn`ez}HC+~6kpvAr(HQwH4gqg{1b6}G#%L=~_gfhb(6wI=+I
> OiT
> zN0SO~HoE=S?}GN66cD36%zTDrmPu&f9q7j6mzm)L33;0y<Q%g3tNWtMHxsF
> KH(kF~
> z+V#9=54I48q4LB|GaC)zfjH+1N!irz8E~l~Curv)2_k}aNT<#3hq{iG(afnH$y$N%
> z3SYHC;QAi6Xp-
> O72x0Zd@f>^x7^eSHY3)S)!cb!b_8zjOtU^s_rfjap1XNQyvYG&I
> zBeUHqv+2M@ML9clk;*c*igAD3{L(W{9v#_!(@(F%j0mLi0a^b;S(D=j1K|S4z=7
> Bo
> z&Rvsyk<e%EB^cE;nu*u&5!~Nc){GPDZ*?#jOw3^CsNIqAGV5@X``U+$EHM5
> B^g3KS
> zuax%=Tj)(;p>iv97`|}y85&2Qzhe)<STh<d<1c_9Z*+|A6U4icNiEYUzxRHYo@0Y
> Q
> zKtGrLDed?LYx$Vd?9X(ZogTiWWx99gzlxJ?f#}}b>~R*4GA|g|zcc@Mv#2&$gc!
> dQ
> zufz<YrECv_ehQGO6%W9h^Y!6^WgcLEnGI%yN4@vq*NN=Y$*RqnNY*&{?O
> 5^;K+Cc&
> zaam!}vX-gnq2)Kat4uJ{GGhg%3enrCWWFYIZzr~l`)L0riOaz7BJ=K2??M`~NlHgR
> z?m4MpV0piFlOb!N6GJI`FCe<g1w;QN3QF{@KmZs$u<w{E)AG@cLri{*HNW$)
> oCbDZ
> zETc8k26?;o+*E8GoG;@rZZHV+`>9F?`<7IWWm{6yJF8e>6&^Fl<K73_Nh!7wG
> mh}{
> zZKoVmg2+&7F|&h_9_8*ylX<?C-
> PkASY1hI?d9EU{@+&V)t<yu9cSp2vP>o1^TtJXX
> z8>J0IV%`|NDuTQr$PWe}=Nt~C&RH(kl;)H9rpMK7HFXL9-
> 24by>#~h%+sah|p#Or$
> zBf=Cj-C5qdkd>i5$>mI)L^&($ZQN)jsH=}2N9JTrm9cIg_#sIq#C*fDB4Imp2rIma
> zA4KF9Qa2OQ0QIT^v2L@af(;x1bsK3mNgz#O5QXkx7P!y#2=T6C0pe$tB2Komy
> w856
> zh<GZ@>~I$d@7E9bxDyBjH>GK!dRMtIC7`Vdg{j`VLNH+jZNEPd&o?P*^ytlp$J
> gwM
> z;QNqKIn^7%_v0oMLmwmvJ=goqgAshg%&EIYYk~02b@;lF;6&5#86v66bpqP>
> -1@Uf
> zUB{Hx1#RYfACJ}*W_EQ6gtz-
> kMjKZb9&Yq&1@;C<0&713#nrdT4y+VGOJiTQvGV6g
> z?Hj%}mZj!;Bby>E4Kt_u)lz}*-Vv?+*1y}*zeMVqSz4F1bVIbRFte-
> 6TKcOmMp|k+
> z4%5`q?6F~YYkinn1V0w%3fX-
> (No=JT>N93rVe>=w&rLItHf`8AYM(C;yUHcX^slRY
> zgeUD*A6Y(DY*g;+JF6y^JNY=0n`#e=5jb4aG_v}13B$U?>}BZF2U^iefVdj-
> ^>6_{
> z#6Si<S8PTge$^iK!=$6vRaj|3-0@-
> (C1@)+twa7k=K*=f;snASQ2Ud*a%A{)#p*ol
> z;EV`QYBBf=Yz=_7$zBE*i<a3-w8$c;z>a|=(S`_-
> @u6pRMw=52`MWFS9f4yCT4wsi
> zI7i%YUdF#r?vlH5O}mIo*IYjE?sDb!Cf4pU#cVjoA)r0VxNL-Ft8UQRk6f7!B<{P~
> zF&x*)9Ngg74qbQ?GxpGhG!3f=?a3{U*DOgSGf$Jk>+024KH-
> `@^xTUFpUrXQd)?j{
> zD_WPjr>vfu_D*aXTE8Sd2Y1lD6YGZB7vs99wB+_B+VyyCDTKrf>0jAn3)i9Uqz9
> _)
> zZ3Otet-FMc)s*#ryiyft^kYCJX4J=34Y4{k6VjcySSq}_&60kioq69iv2KqeC5KAQ
> zb-
> g>iw%h2^ZFC_@Mjynh6Y=W2*+drCO;`OvZXF}E+&wP$u8CNnYj+U`YR60RsO
> 2`H
> zQg}^0HBH^gwu9D6g;&be$7>p(d6&_=r+W2!d{*mu&O6vc5Gu$yW9j;(?kTIM
> +PxEN
> zd)6<DuT#KzXx-
> B;r(Go`w=aulc85goag>b`z2|>G^qykB_5}S(71pm1eGI55(TV>C
> z(TP0gh)%RPh^|B<`T>i>+OMFB47Q${S_q>3q@1o^>dnWWF=tVa^>L1aa4?j
> @w(hgb
> z#qiDY?EWy1SN5FXNT_)Il6cKB$k=IQ?5<vYxsj$@=o)8suWyL2+v&KpyS+iYS>^
> L)
> z_j4~YCZ{;gjHZd-r<Cw};r*`+_I0$QNM%6|xv}(xfj=zA)1qD4$nYlGFwZvN+0$#|
> z9s&{30W-<`STb`BL`yF;F`8^!A_`88p^)x)A(@+|)QOiUyh19r2!%juBKwKxv(gY<
> zD=qhPFK$%cDfNlmR6U5!RvH!3!Ru;k*QnIL@Xh*V7m59XjP1)Va;0+(m5}@*
> Q8!44
> zr}rPSDl`DCiuA3C(PZWx;04;N52wOMFDP0W*;3RZDmT?+|L&@ZCh}eND79Gk
> t%h_b
> zn<Z97gLiea=C6vJ>B$<}_CR;kl&hIHp-m%5@${p)#aW5>oAjFDh8HZvj7o5m-
> }5gU
> zI{`6_*#|w|_Cev`?m#%`F0<;jx^IGe2cPpe&CJ;?Rt=+tX@1ZN-
> A6c3oqlHYxfh8U
> zwNcX|rXrl9Yw8ZHem!yq&YoenLp1fwXoyeQiP42KGeqtopi+O~r!HqQW0A^S
> D=g@6
> zO}Rh;LE_(=VRtvw^~_inpYmgaz%3723G^491DMO4%zRe;>#F8dFZV#O>@TT
> qzkAzq
> ziBGU-
> RqUAb)2*&V2>w?g_?BtjFVSdyLzqQS(M?g5YVdv%H~m)4y+p?Y_+C<(o<C~2
> z?svJeQ`I8(ioj?X0X54Jespk@bIY19m?OP#a_Y^s^vu{|lgX5yw#@6Q9W?G$>^j
> PN
> zGnQ{y%0#Ol%C|x6J>^F_u`p<kHG>5v=WrhG4d-Ew;O-
> d*h#}T;0xzn0;{%1(cN<WP
> zZZZ;EgPnBb$NTN@?;f+-?BRCJx;+wcOP|3cjlROPJ-
> ew}uBf$pOD1WZs`Mx6A?~R}
> zR!TcyVxyEV_1uIFvjr3Oo^Vd>Ez-
> nI*u4{*_V|Lmm)Xw*yVAx?*gk}QP1yZz!WOTV
> zPT0LOBI2tzoUmV^3g(V6p!#jX?tjGzTfyamxnc<7*<8_Q$_wF{++2Yo(`R#q(rvC
> l
> z1z--
> ~nYkiLwN5%rYR+2b3Q#tc1wKNH3FZntm(CSvLh!Wa3W(y*6_zFr4Cjhoky>-b
> zD}iOMi0CeYthvGnQToEbABNbXNOP67Yp-
> UE;fc~K_u7mxJh2wPe^{#<rY4Ifj&8Wm
> za&>1Ha~yA<?w;9~JC>8EGK(LJ+^%Mj)tEfyylU-
> WO}V6C%j7PTnox`}%TOE4B2@5O
> zi$}r_OTTR};aFpOJc44X^!fCT%IkM?)W!r<M4~&BtXm^#RW2?@#m@S&-
> HPt4%udt8
> zSeZML+O?R42XmHh$kxh(L6&9GV%c>|rCWO3v@)KGRcoGM4Isax2b3*{B9#
> 6(TQ)em
> z5ZZ`iJw<;QO*I%E&gYHPGQ+BCF;Yt7j@Uy9330;+YHre$1W0DSt}?w4Ja@v$=8
> HK@
> zDZt00T>8E)+}X>aY{63BAsOoS{`du34fNW1;9lLk+xwwTTLaYf<?o$fYXIC5oDh?r
> z-k`}4Nxuu%R-0znZ$rVvh=SC!u+TH?U-&UxxMRQUw-
> f6z=N=G6SYbJZpzZ)BBhiG8
> zPbj3hu1ZH$Yuy=Jg|t?%0t^g8Tua1})Ez3v*;J15vCO*ps$A_**CL|@Z@XGYSOi
> )7
> zIpe#Nnl#k9Vnd{Yi7PB7l&(5_mOu$XT|+e7x^s|RS-6oP2Ueo+DMmr-
> j$yDdW$^$I
> znG2;spbVl`x`8ZZ5CHfSy0<8uyydjG4Rc>r?BzIN*U}A3t^35geO+zqCGi1{O4Nta
> zd=ZK3ms}KQl=QWuz3kQ*IeINl921#9E{Xd}d9PE-
> wE|Q+S}s#aaGcGp@8;r!o$fr|
> z_JWwo*?%IKC@ljwx2V(-
> &lZ&jAa2ml`@(+iV@=52hfp1=GBR~vW)GxBy?1UQn)ql_
> ze+~NnC-
> 2u>P}j@BS7xuKo{3Gp=Qs7=uF>>nTNU;OQ;7^Awo(~(>pcelNa=cSxVYXM
> zcGCxn%|17M=*dkV`!MGF)5pGvb;CA&C~eI2;X{ZnJ%&rC4+9=ZG=uN|XnKVz
> m_EjU
> ziY`4A!pugaTY50GS$bGpGsQUTnON658~F;wbgcN3|6uGsG!bV?@%j;|rAfs`m
> ?zk*
> zIQ+>*&o<hWZj%jF!J|BjFC_{}7ADY`$tIu|M1_RGWMkwkS(rdX_@;DWVre3
> mn{0xP
> z(PZ;VV3}+pgcIcA!ldMdfj?~5h(?-
> bMxdjXB3hUzWF@R>iks#Uv1)&|eq`Y5#+&G}
> zJ<0qRO=m&v)cdTaPn(mB@|OU_%82EAtb4Q#8mQ3<DQld&*R8R8ZAJcO^;}
> (Vu*@FA
> z-X)}W+R^`C*xT(PABlK-
> F*N0?c9<mzYMU&D3q*M*OIdmjWyQinh*^7P*hu6D!lDzY
> zNsow;#lCx!+m&x0x`s>=C>r+Mjv?aNaD~11FpO+zM`UEc3JFyZ86SI{G6o~>Ee
> exT
> zMlN}AWJVss@E}GWnph`ZgOSbRSd`^53QC^|*Vo6xa2suT-
> IsK0%!!M!+(nny#0_!F
> zYd2fC<+bNBPeJ^cR>h=YYgKfD+%&=KYP(0Xk^TiQ);C<V?!^hgul9zET+!ST7T3!
> (
> zJxvP|;_1Fat^yfKtO6Epqb>iGUMRg}!tL)4po~>;N;N76BfX<)_KtcV%+9JtD_ieX
> zeZVcHZS^gymOVr?LVpH?Uaf;SK&Qa^YbwQV6eoWxtGg?6FFTZKD%UvY^{n-
> lJ>)v{
> z(`{=d^Pi>=+Nvo|ThnW|>dG%(j}8#F6a}R_C#xw;yR~(PGm$=NiJYo?kZk@kt*
> dsk
> zs`A|gw0|b4gH4p3{pw_1CzsezaasH`8MaRB%G?JKrGsUMo~4<&hi&?~Xzgo=
> S*VKI
> zG7kk=f0Ev&x`}^x1#4Co7Q$J(tOH%Ph8<$o@z?!21mT&s=cU(riDdo^Ni(cEow
> N!Y
> z*S^*r(wl53?@NE2!}KT`JuHcvCvRoHeRQD3AfmWun|8@olzD)fb9sF#1_t{!yG
> (J|
> z)ykFLH1qb!TX8)d9ayMxf%;guuxO{uTPv+`7v7Fvo_?CRwN~faI@C-
> Fddrw?%iHg@
> zyDHZlYj)^l%h6ONq^XJ%QlkUUO5#fv?7|LRW2k{Wmp6?LJZ6&t)77r5>3q^;?m
> UY(
> zw4B)@$hN_<^`eVP?`-NF&{1vz`{WWeb%SI&C|K89rYDJV-
> <7$a_kOS0v$SOQuuZQP
> zCG*>%b64%d%9N|?%(C<W0p@bkmTT%bGWdJF>QMGv?ZY*$-
> N`m>1u=Wp)D7Ku46+cE
> z*2QAyHx1u7dFx+<#jmaZhEI<TvHxGYC0Dm4y#w2umSU|ttt*KiT)VfXwy&8}6
> ?<#y
> zhB*&V$y=f#^c}Kw+TOx1?M)wCgJap~z&(PACR^sKaMma3!*r2#NljijLls=KM
> hBYw
> zvP%**wfjiK<7#w3TQ$<T)#`_h`yL(`p-_75!!fSCF&b5`o#lj=fqTxIBK`k>Tj;u^
> z7pFAsVSj-zfA$+WYz35+09!;Y6COqBJVm#&Z-
> x<2#2_%|lEx4h?C@S19r&{A6V&&b
> zCZYTXCFYe_i=zw6rp|#g)GIP+ZAEjg!4$4jPVVPOjnnCyCvBw*Mhi?%TCmVdw
> qSX(
> zb*I)-*`_Cn83~jh_c=i^Fu-s!yYrr!V-;zxJ6E^4W?39Cc!7+ni@MEJ);&;1&M|vN
> zZhq)P&c>QgN$K1B(0`aCCSHSF_nN?*sZ=&^y?XqwQ+pcN$=l3_cN*F`&L{pBV
> Y3~s
> zcv~tqvLxoc_82*N##0X~^FzwKixEub^um6t>g1HZy+c0=s;XeGx=gEErAKfCKRI
> #;
> z5l=_qF^86H$h-
> H<*u3w9IS%)Jf*^Q15A)WY*O{=A9Nw3Y^uED+1I9_K;UhfIF2aSU
> z6(Z}@8vCgkRD;$Xo*O^^ZmifUqv(k5{SfypY78TmeHX-
> <kJI6&ksL>DzWAF%7<?0j
> z|0HFaN;P^pm(*3RpZd2k{%WDsN1>@yqqi`Crl0z^vTS3F$9ivudqc%jM=&1aK
> O81Z
> z>!nW`y*FQAt*!Tle{EQHm8+!wvFAw<{qsi7kKt)T{*8<7vSTz4xs~}FS{Eu|I&^D
> 3
> zQI+UdgZIq<RPZu4O;6|`56a3BE=!~PoA`fLzJ1Jj`6Hf}^Ztcy^}SEh3ul7xgk;-p
> z!?{{Ncv@du`Q?*%Ht)ODSYyDx!Mlit(ABbKPuuI-
> AEfk|SKWE6yKRx%hdx?U*MFnk
> zCP#Ok<Q<$ZDb;uW1l<|emn*CH{!9wcMtcgoQ~eqgJsK3>HkM1I29@F|<qIw
> )y>OOD
> z+cIP2sQ2?fh}tMg)y-91<w_UQ-
> X=T<z3s%NDRKU)FgN;gPp*Y{e^ttuePUO+wOggW
> zzy}NZ2Jc!P#L43hjD?hT4~#F)Yo+F}bw4`oVfrK(?x&_sA`QMpK<MB)^N)Nunk
> NbT
> zC^A2^AKA#kXIibWm(w<r-
> yg*qzX|W+ZhK3b`+ZaNH}{`&zK(iTnRlB7Yyl7fn%?wF
> z6CVttM(@9FcNHkl+bT``Sf1;rxM$_LW1h>eJoB)E8$!VO?a@wLJy4D8dhuL)u}
> MRG
> zJOhFs?U56%juz_r>q)YSm2uo&J1C6pMB$ea2}S<k{GDHJhMke)vU@8{XmcyA
> =7j)$
> zB5@GX5BeX*AH%<aeiPbI>K6HClzFjFhy<mcCpU0RIB@Yvg_%=VP{LhC|J}7#
> $a#a9
> zKSsaCa*5~3e8G>Uz8b0P-
> b_hd=8qAJ))i)UbqR#`u4rA(A48Rm@yGbP?d^=<P+5wD
> zdD^TYTu|8FFmvkeu)RN6^QznXRHUv4+s3!IGFn%d+0|w3y*gT#Yp?e|Z0|23I
> 8>M7
> zVC}toU8KEX=G22>d!N7URkyb<QrDLB`1V#u>k2cwx~#n)jn?JbJNQ3r@5>P!=
> 9c1M
> z?Y;kwNPEM~sVBqs7C!!}+xxdjUAy4j$k;J{o*S(z%<Ss2_TCY#%e8mtf7ssR(Tjrd
> zyQmZgYwyE|wUD2~%&Fe6y??#+Rk!zqNL_p3-
> LdUm6s;@F?CP@iekxj*Ywv;oVS9DX
> zB4}@YDGt`&ClL{0d&A7B>6-$1H6@CJ$*bv_Dof<m0jPt#njfjFAKo3?-
> uh@=VP;pC
> zKzLueB|=-
> *URCx#kynio9Ih$F!P>hA5fQdG%$!;gw)ey+4%XhPaqT^a+_d+yNL>fu
> z-LdVxCR$gR+0`Ww-nVZa*IrdNroD<+@apxiZ!n$8IgJ08t(q})K|2Z{K5X2(dqXUl
> zQ549PQ@x8jRdIOKNqJM|_r*4z^ugx0o63b(TtDiDuTmc0y0+i+Nd*tkCj2$en_
> dcV
> zQ$DjxQclfukbIr8L|vLf-IHD2Pia%iuUC~3Dxlgs<c|4J?U58E=_`j)_2cMqq<D7h
> zo1qDfdiS0qvh4F7W+i7UOWLd5wMLJ7ke%X*y#&=V!BWocm!}$dle$5DU6!i
> m+57zu
> z)Zicnak5PdAXx)$Og-
> K%MQ?2%fsNQX;@K2ZcidsXDq!8_HV`s*s+1PDDK^r4+MW!U
> z){m!*yvIUb_u4!3GoQly04w^k4sS>W+PX5WO21H+%$y~V)701Iw|5FZq4YJ|$
> MteN
> zJ9PmZCM|hMV$&i$LWYKl?6jpk7p-
> 1qp?97a<y`!v6>~o*T$fu>UwK`&s%|d13qKp5
> z9~RMxowZefooJ=jFFvXL&iNU#|GbzzFshMV+VxuEcJ#5KLcgzHe=-
> T}?TbD^iT?~&
> zCq9`@imYlXSxSjl>%HDyM<oJq*)j)UM`FJGHY3SX1<wBTj<&qMb!}hB(uyFOcc
> 8ql
> zAO)P5&<TZJ>rc6Xj1Bi-`txWib@9cqYd0!aeR^=FADXH@Uwh!%O-
> l6dPQWxyV5mMX
> z_4`9wMcAA2IZ#snZ~#8k^2RRv4F%Btx0;rZ|Hz0qSOt?qhs3;vwT1VS{cok&w^(
> +}
> zg<<wS>cK)-cxT}pvX8W!U4$-
> Zf6#088sj*SL`r?#O6@I7M}Ov!S>(+IdxPSA;95W2
> z-(mIj^x&K@IM<-
> NEBU94I^<2304X|%!v;1d12>`$kjTE{Ul}3A*f#RFWdl>ooAPA3
> z7Gkjbdwu8JT>CP*8?XChW;TgFQDqlp^OynzKpqnFt!87lVj>r$b0=J3KlqEhzAX
> St
> zuAB$rt8c?hcKx$#ypH7W-gyOZanckhc8$4vLffp#M-
> >|Wog^h6T`~dd%tbUj`6%X7
> zT}FX3tOD?0PA08k!ud@@H=hQu<o5QZ0K@lI&LNL3IeE$s+G<X&Cl{V6d}-
> h&x{|k|
> ztu`wv{CEILTEh91sU|D*f=i2vs7J!z9JQJY)QlY3RjkOhj9iy%TeX}@ugfmIq!RZm
> z(f0I^wqJrG1J3e_tJP^76YvOh*gTyFMLcXyCLcozj!x@@eS#hR>nW4x@F3C<5
> %r|K
> zNw%H;>WK~x+UwRXPes?F3UvVEZ9?)BTX@RX{ZfZ1A@*J)w!D`dv1>{4iOqF
> RJdPta
> zX^z-
> %r}{Yg=(3Z!=EKpu{gRUl&lMhmF~HQKB>9~LW5`~l6K3iQV4R$O25~P4?e!<i
> zDXxNX(C8`pjxAC}et_b)VW9AWp&bd{!ghz@r=wOUZR@t;x~`@5Se^^}trtXl<
> M6^s
> z>4i4XWuV~D<X2riIE+lhgMvuJgT%Od-
> ^sAXSPP8Svo;V}u8y=0JV?Jf7C!Fgv#2up
> z=$*~yEa5_x%r$&%Jr<3maQxOdm=-
> Fx9;aVNZ`GcKPQVEEhJ|EX%HKQqYvk|U{3$N6
> zf)9uP$|i<ZiO70dT<=GFYF#^GVjdq4g657qy;viS9`6dSx8u5PqZaS|tMQ6-i!$?C
> zoF=pohi;3FZsW5BbyY!ziOM{({+@HN6|~o%q$wrnjR<P~lwznsqxE;5+eY?QO)
> N|)
> zr4*)pt%I|$tcD_MB%kSJ<3r3Zo+$FaF3ROz2i}Pf*ygck+b~dK>o$8uC99|9@_Jt
> 1
> zp-*Bf4)Im!c{-!->U`#xd}T8SFb-
> =+OW)}oWn6i}16Q8#nS4~yAC|gz8U+SuT#dnd
> zMucU!xzeHZbX&RARQQj=1DJBv4m-
> q)IlUp@G5j|I2c$%!ydhL?*4U+!Ws<4(v&VxB
> zx}Sy{QIt6^m<{$U8_E&|t@VC5QN?DCD@G&66oYuhVxM)zN~mchv#q^SY9`
> a)hTJ)8
> zVe+xICgIO^elrpxG0_US@mwkXur6Uphwogu^=;GC5}yaIa@~`B?A|&9#y!Rt
> goT|%
> zsRq}HuKO-IIeh1L>%CJIr?P#6F;ubIr`IVVHt-fiyxk%DDx3Ee3Z;#C7T<WGd${uE
> zw}uF47D;zkhAnDee6nj)dS`WrnUBmBuK4=`I3EX2DU~8cppv8cK%}*%ezAuU
> &@yP$
> z0?k_%dh&_sQ8C5%Ne`an4@1T>3eKQ+7p81|f9khr7<fd<$+ubww<`hP0d1d
> oN?53b
> zTCZ?Qp~}||mHGxt?Jp$s;{^Q(2d(N`xDWeqtfgw@-
> @M=XaRJJeB<e?FB}#~qe`7cA
> z0uv#>x9%zZE%}<>`Xq&M6#WICkgWA_{T||Cj%3?2N@_}^pRk?bWSe%jD3
> WW}Z!D6@
> z%tJvAZEMAv&#||9=55OvsPl}MJN3KXoAV=IS54&ZQ5B8e*H3Z=Qz4=0QRNx
> 3_vo43
> z3M;SL^t-
> _u{Gq=h0HVs*doRD%%4<zVDdE)UJ?(O7AwfyyYw*4kmP|j<NlL8wqxM$M
> z!t;GTp1b&c)*(LXy*olM0*wJT*81W)J{!Fcgl|+qkKPREO@sH2@QoVXNgDUN`
> c;dr
> zdr6rKUAe+f8T8X{x9-
> 278l^OPyOKexRDseOyrDhT_M*&>%p~Q>Pod4wFC#npP@fX5
> zYbGpPq_yt_%m6#~qlhHZYbxtw&1b^JJ6=FzNaU7IuIEfd%XE=0l2-
> 5C<thqO(`zO#
> zk1=%zz|(6ctcbNNjzV4@Yhj4`P{_XmT`P6pgJvfX1EtpKxy;-
> 1QE9@y%{W?s3J^j*
> z_ErI?2B_zjSFTVW3Dsy?gSXF?q=^Am2BX%2joxmT<i-
> sAF8*c}ZyP+AydO6<mLdZA
> z^&EZY7}&ithK-
> clLS9ip<@6ja*BN=IXa8NXtAb<5I!JxThr>p+uBmk0G&4#Ix{2A|
> zr$uhXg!*vBTci*4ni+zjYauv`&SE#N@KGqVg<RFTQ)maUoJbLUv?fWmO+$P*
> N@=l4
> zp~F%te0La1h3^hSsqmes6Hrmlps9ENhm^9a0_wp@uZB`8b2v&lScww(i~Z%k
> arT!Z
> z#b5AFoH5=Wh3aqisFtNGE4(L&_koh^6JTR?mL)ybgY=FY8oYmmK(^(LC$roR`~
> d$`
> zDE5>q_7o9Aw!WU8tG|K6DWM_h-
> (N7Gf5(vIYq+leD`L$@*~(Oh$KNZlm_W;hy@<Bb
> z{C53jL56oGs{1$4BS2T1N?g{aovp{EkoYMm9wQp4)6iO%N&K*iU?c3axVMmn
> RYZ}J
> z4gu;<4_0}9K21~_W@YD0ItPDt;%+I0LIU69p>Vy4kI=-
> MS&0sDQ>C|P2@?}X6;`FY
> z5n*^nuNwGgDCVd2{moDN1Ze}Ud~}t|L<AW}3oYDO#!>4*&6zTB4Dt>85Bfnl
> IBK2x
> zstK=das<LFdA*tuZg?GtwVdtU#<e}6K{d>rT0m(7;XU(Dt`IjqOoUz{0CC5!0{1K
> U
> zo6Fx){`~GRd&;5I*0KCGm^ebbq1J_B7$fy!xZ=Yu7>v(MDW#{B!K*S0L}HVEjN
> _%7
> zU8$#zVBa~E>V4JtI9c+P5i_AXQJT+|{IP|E1`|tc>65Lu#6w%3d+i<fw42$PsOHC
> -
> z-%n#6uvi4a$Pk!g8@+d+dKxQPHtujFRcgZP1a-
> a<LXm})wHj|HvW{zRyMs$e!9-VV
> z>d-fzAU|gn^yE(=pZLD7r5w)QMX`FX-
> &u45wJPX7^<S|6DpIUrgFI1w2ZKwIt}yj%
> z7CT+bVj$Hm{wibfk?`L3T~){VG<UG$IPVO+2g3k9YgOb!(IR&K-
> #gZoV#LXhSe_j%
> z)!?ro`SdQs-}~jY5jeV4A@$J`IA+z|{e;ynI68?ulKyy{bNvQMJ|Z7?utXU~@(n)Z
> zwkTwsr88a=e^cZ?`Hk3;yb!T~tnP6BJ46R-
> v1rKTyTca?xE|xP@G%z~jEc0^KG9X=
> zb8_JpYL|t`V411t(}U_=;x;!gwIXJ~_~BEo;~XBRmcT!@1pX$MGk`zc!S6C9T9q`!
> zyUHM#G^(h~qJJ;DT)o*mSN)5QV!QLruP5~W<8M{|wF!*iFq8^QZ*KH%aeSz
> o*~K47
> zL7GAHdrWX9N_dF(%rC=Z$J-J8P5f1Zx8)?8W>Swt`xn+4-0HKIn;Vke4-
> iKIYZX4^
> z&4EPT=YGSIMtcsJ!f(LS+<#1Qc7$R0Itzsm4ntmo`-
> AxK9d2yRahad8V~6oTMH0Yq
> zL&?Sr?e%mXCLn@q|MW}7`r8~S-
> mM?s*(ZYyImOW^zXRdES6v|CzSp`!C%bG50^#mC
> z;eImaq(Hd8#XNRH;oi#_@V@xIh;R=xr}j#?3xxN(_lgWv4D1J~%scx;^};^yr}Vh
> F
> zNis84vT4E0<TF}omZ}WKz8lEP9*g!-vTZ(~p!>$J1SD2F4BQPc4jWH5JI3)rdUScL
> zAf4dbt^|%a{U~(ifEf-
> !iah`v{MFbUQ=Fz`n^ZVs<x^8yD%kYC{ET2!aeQqVwt3YJ
> z=&BGI)dq)v$v)Fjo-
> poauoDdKTW*Ni_KkLCS{8=8GA(bh)EgSyeAMPjt(=~lrYR}C
> zlbcPJQ=RwSi9(>lBcy$x6c!u!qX&&7Psun>xbF-7>O_-
> yI6sbMNOW~vRad3^e((C=
> zNI_&n>Fw6bLWpI1cIvet<nYsOQA)q2+RJ;i;>}K*Nyd$qU@NrjRF8$7U%*zUo
> 2oxq
> zEYt1Eki{?auo9-uBul{kR)6cD^yknX$36hk<|1>hIw^WrlP7l*^=D><G#a96RJgSt
> zD~4rUI7wp8UNNr>tRZh#2BB>iw031uJW&h%UkN9?i?>|*LBQ1X%gd9QH_*
> q_gyZ~#
> z^h*~dGso*U!OgZWDN7Guoy<(qZ*G6dUjvks_cfLa9eQl^rY_d96_;|x1<^M38
> ACSO
> z&)FH}$!4zLv-y}@UN5c28k-q^0no0@4J3-
> ?WbD(knHTM0n?B3$cxNsz0E8&D8eOjI
> zJ1cVSTiK~>@V-$lKF}=l`do*KT>oqZ#s}Wjdv7|yc;tLT!J>=*vqQtoZo((kZ;jDo
> zqc?P+-xyVx-lk79Th|!7g0ZGqQ~FF0=Vn{pmfx|4ZSl`)gloB*>I7J7kwH{p;;9O7
> zeJV`@^Z8XgH+cV2qe?34y=ToxFg@3ytWUR1)9YA1qc6g;3cTA+ea4Mq<~>NH
> ZZs0<
> z!L?<g(Z}_TBa#cIi>Xx<v!?1H@-
> CS<PwLDzV+t)J5%8ZmO3cMwzxCu**jasxV{#pO
> z;_TOej(2D>le=rQO|T00W!kkD(|w&L+4dquUH1ye5xaMdqhzf4Bd*P%sbX1u
> K(T*4
> z4P0&FugQ0aJkV9-K_Y?oH-
> K*auUn0cJUWM<2Q@+iAgJG7%H3TL1A>s=X74E}NcWUG
> z3gAdPw@4dJ=r{XsGRu9i`W9I3E9Hqc(>{TCX9z-SMBOmE9Jj?GeQ3^;KF~U-
> 8?wXk
> zKGJ3EDR5mjeD&n*twL60mI6IzpXEK2;Z|i5x-
> !f7q$b9sF1A|4ug1J#Qo?H1Ee}sp
> zqoy-F#JcygHBurrC?|^6drPZ*BFkUAqSy-
> q@1sbN=~u5+rg*xu+{vKSkXYYMZn?Y!
> zP=oi~Z)kGk_VDN+Qr**4cT<J4O<~|!md($n1WBk=x#b%wviSx4Ua6p?*FSp{i
> TUM~
> zGil#kc(u{{%-;mp@*=8Dn81a94aeR!4>9(J7<(a)2p=418BB)Cj(CH2`^Sx0>b<6C
> z1kE3O>781sI$4@UmL?zTP`8psr*fpTg8M=(1?{%t`cB2V&99g+v(X!6jSfx-Y<v>f
> zP=L0HTweX5bB-PACdaC|<vqi>6+PU`Jd4I;JLd4&W#Untt-
> +xYY6DvjZsgYF1t6K1
> zIa5X`%i~5#t}$LywWH;d^fqOWH7_iAS+yg#bVuCf%pNNx-(;tcibJ8ICzlr%+2uX)
> z!c~RKO0w{BMGr*Q=x}4H1b&A#f?BK{*%j1f11+1;i(FpgD{IgPX7K1h*BCjHnIF
> @d
> zmGY<0Ez{MKY^=l?>GLVru=0*nOjbjA%Rk7TCi^qGp{k7%U74BW;6cRd(6hF{-
> NQEh
> zykqsuoaIS=@9tVb<1S8#E6Z|S_U<O76?Ua$=-
> oIU?I)<zdod=a)&v4%8(&M}l#CGx
> z%MG_hFs}VHp&T4?x2)ETI6(u{Jt`|TV!f0FctW9jl)gyh(1}|G)r7T~o;sPHbi;NW
> zss6U&c*|%&WS34}#sbI9dfwopVlgePjJGsGvWyi2tjUF4b;g!hq;;E0n+^E3B1m
> k$
> zzQv6OzJK2CmQzf6ub@qVBK*cHMF3wBrsiNMm?6@;-XTz$zM|2))JH7H-L-
> VWa?#13
> zH!%d+#1<^70#(Hl8D#avYL-q|#sUmcSw9-x`EW`a@-
> jU*oikzTk}wSBkZKCgrI{@U
> zlTMR_!H3l{UnJEI)_b$RCIaHaWWiTW3a&SG=74!q4|CGo!iHgT8s-
> !%{taE)>Xj~P
> zT!8JacnNt?-
> )c<tA#jlLMOB2r`b|TK2=4d!3rHYdWc*!wJz|O#wyz>=m6&SRhiM*l
> zL+}KVUo)KIfeE?a(<~9FyV`k<R7XPOm)BvMjTXZ!cRW#Jz?}WpdTh`9ke_f%`W
> EcU
> zOJTcQgAB^PHD=ztPM-
> (T0aBRhPe(*Xc|hZ`p8HL<IPSwZd@Ba$r8Zt=X%2w}4AmY1
> z)_Zv=Fpc#U+?VYG)3*5vp$v{)i;QW6WYd9c16;v4Atu8z$T+ZH&FbX?=4(38==D
> 9~
> zuzBUCeI|m<C1bGhoAwzW*ef^fz6h|tU3S=}UF-upeABuX*IRS-
> c9}iV%0(%H9qWeh
> zh;jhSn|{zqrcgiF=XF<b<?{Wc>9B}A)n=h_urN&TsJ3W$92uX34-
> bqWMUx!m+Cj!y
> zhw-
> 8mf6c7Lvhlw*_HB`YnTjAFnw(FtA(1fk{Gyhd=msqYI7KV&eJUV8D)Ds~xAR~5
> z*vf|#42E&N_XfL<jE6%z)kE-oRZNHYs;-
> k&gv%kW>sq1;YI%?}O|P9!EWljdbl+%F
> zTQQ)k1K_Sk@3vz^VfIV=TG#do`_*&723>Ec!TZwjdI#4h+a~(?aa>~ms+e9-
> drjo>
> zz>_p6JxTiJZ3=4idMWD^N;Umde&tQ2qLRTd)9Q1ir)yeJrk4exb};#vg-Xay4h!g}
> zgdxT+qKDi@H@Q)r93W5JnFRNUgM~aA4ISyFO3=LxQ1?%z)SWNF=7lzzJF6b$
> gvuVs
> z9cb{bau=1?d-
> v`rQu;XQOoL>qs`qX<pmbCcD16+?xJ+xhBE?(b(y4Exv_8+o*bv~k
> zZ&U{VD?esUsrTOOs=yS_Y8vtUZ!e7(&*ImTEohV1iF~b$n?)Blf-
> 2}xF~XMUla*^1
> zn|Py-N5H2NP1Y@+?)?UgH47Fqd)$cemio>6V7rgf7r7x4{wjRSH-
> (gr9nBb4e}zRm
> z#z{k#+h_WXB20;JHwW(3owD1*xwfb~yX6Yn&01GJZ*?FvBSgsi76?`Hu@d#3
> 81WNy
> z%|KJ4b>}+Rq0#GMAlXuGl0%E?o?iDUUa>1b@BymuvBZ%m*bYop0L{ppezR
> L_`k`s<
> z7`O#&sKrZbczvS1?x6NuTJTIBUbOn6<o2e6>6g!Lz5oOjw!~4)5M1<4Kr-
> uqV#CTs
> zHi+IDVD{nf8Nmj=1yX>UPy|<dkfptWJEs)fEf1>$#Mc##fJ4}JF2epj$8YP24r1YI
> zz?HSE0K3Z7@8t6HgK+)P4$C<$3&HZdQm_xvxgnNODy|P8@7V4-w;UI-
> !W+3S9SrBN
> zYCp+A=jk}@^wd_cE`XUT2EK|)7dgsl3IqL5-F0EzYrahvCip0^q}=oopP}kpozD2N
> zh$ax^zcRgZQDZ7j8B=<oD=awEOmK{5tRi==gPJhQX^ffH9s1FbYWs*~_swtKp
> GRz-
> zxXN7?8F)5sJO=|3v*#|`7-
> ^oBUO1P8(dJWgQ}xi0o2CrR)ygnREE{Y=oD_L;>LHK`
> zj>nlE(|n@0#36B9>OO1T0pPlGaw7^wG@QG~A_JkkXy*=xKK8_k{lv_}|0U~D
> )33~h
> z(C62@wiF)OV{(|%<+pS6cBpWpPS3g%dWxGwS4?bJVAGE2U-
> BS*Y#9VPkY73(Gk`~L
> z1)<{XB>yZ6sG&?ponJS&x|+ns)K+l!x{vk6dJ9HeQ|-71Zl~l<5l`z}H@;aNsOOm^
> zoPE7`KjZ%?efLuboqSxX^9b~neu!D*73n)Vt()$=YG+)Ve(<NdA~#h%jkBriY5%
> 2r
> zzfrspSP04A5N#GRQx#(Dnz{=6WP|rtM+#{K?AHWY_fR83c02*CezzZyo7N13
> M(=S4
> zVYKI}orxIlbsjUyaIV4%?+>&W!6xHHYQ$&~oXy;H1AtOPN@Kope7H&IrTUcyU
> VfS?
> zOzkTzdkbmlg@VAz-
> Sk2gW9mvTR9>`%^g?Bbwan=%SDwE2vIjg>RLdFxa?{k*tTkoh
> zULH3oyCeA~(Kx+OpQFvweS(E!Oy&I9{b-
> ux{qg$*EK?Pn@3heyw`K)&p690tzkqV5
> z`e{OSqw1~qD*Pn<^4^pa3$;{uk1|#v-
> A2Ar)&HaxsG<h%A55xnY<H9T+!qHeM|+>J
> z{DtP!H$?0n2*#0&DpV-
> $m!142iAm;H6As7@)(^%qFqIH#@H~gZXb*KC?OottaR<3_
> zdb$My<!5wS5ABz(&0gYg*OEAD#^~YWy983|w4fHXt--
> r9sHLmiq?j}opVr5RL{^V<
> zm0J(+-
> uu@2;?9p7(eRtjw~X8WInw<NC7g*i%nIVY8`je$+S09pT1<0XymG!bgMDL$
> z?_4Jy*{pCZNWN^VB%>SFrRf^c%%5FLRtXTmpI+C^1MUZjr(1Q$3qjC$YsXe3
> M(sq)
> zgEWy1lmDWx5lMk!!YYHCftK7r(e$l1aAzeYH)`v^rLphU=+!?T6k!BLTs?XnsKaf~
> zJN<^<OHeCg-
> gSxhQyN>GFV?26fmOz^&2z+@h_KDOZHk|!o@?AFwyF324S!c!Ahu~f
> zT^_F7DR-
> 60hJafLO^1147#*JK2+_*?s7%Wc$FP*I?z!RKEAGO(W2^+1JhS^p13@-<
> zWu<p;yVZO+f#vvP)j0k*(*0U=3mbB}ZYtUKX>}*NR=3WKHS3U(Hiu@`d!PS`p
> =)pE
> z6yMCj|1a|9oZ_2v>b(y{-Yh7-Sy1o2Bl2cx@y$~7=g6C7#W&09z2n0-
> t+yKYhUmQ)
> z|HcOmJ<c<2$OilY6RIVgh05Yd#AaSIN7ed@>u`>$70>n5^)-
> 0^?ts9JQP!I3t#u%u
> zf??khLN{g?ac*!Ypv)taEw-
> MYxo%OgOR=t2HT~vsfwx+}TnSM$$oJ4s0z9LYRd|&_
> zWg<QP01l^dJHu{bbmGAH+t-TBPp##R!IUPM4`;saNV-
> yj5c^{1Pz=6s(9q)Kyw;VE
> zNYwiB=@_y~CP6^W0>NA>6yP@}8vR83y|0*w-
> >?|AnT6UZz3G(HNt+q|v6b^v2|bi~
> z&tI%s1BXXnA4Fw&4PD5>ELxXeANm&{aU>q{{sGqvx6<I=_Y(L^1NgT^;j@Y#
> U2|?L
> zpFqE3jzCPoOC%S|wM%emUGrGHVMZ<HuR*=sF8H;Bg*O-
> 8pr60ePh3!yH~H9-LzWRg
> z<sq-
> bGJ5hz9`f4t!ym}BKRq~0%5=WY^FE30fLUR5&09HMV>q0p<hvqpX<G8JiX}62
> zb61~UUSOd62DVeFeqYJ&db()G%Zb+gg28?Zo9k|Y&KaY`j^V`VN^j@1TpjD8
> Uq4;@
> z8<tkX$hcVH*!4|`_NM-)Yk#dIaq`Luf*MyX?CMrE=+|GsGgoP*W?K*sH|E(-
> b~%5}
> zyL#`OpZoUa796wp0mg7s`*Z+pTJo{F5o<!Pz};-g7S&SpSg3t-{IkK8$Sv>{L|;6k
> zwxUo~I8L*!^NR6UPQw{vIKb#xd6_?LMB*?w)&G>#qE8!teJFK}<FDH=4TSt<
> %Y(DM
> z-(n;Pe9~6BoT+-UTVe0~1+E04OXVQ}sV$HrVIM16Uyy}`J6q*!Q<3gl)NJd}Zz`L7
> zVk**{6*yjUd09nzcQx6vmsBVQYEC))WH}>|?0&YsP{FGfB0%9h^d(#4#ublS=
> U5bW
> zw9>LoXLU)9GV9>_lVXFBiHH4tipq+j7`1H45Th1<GFv>~8Xs*r+secb_HwINAM
> ryg
> zDLh5TmdLHz&9npn(9?><HK29>ojkYP!TWk|^j%g_dU%xE+Ew#^2MLFo-
> vpdS?-wp1
> zH?-
> priyn&X@pJT@x})!?iSd8$<jz`b$?`HeFyHi!1B&kFs%d@MDm#vnBJS>3waD!g
> zr}dWUF<7<*7dA)P1Ujk9_(BYuObfdR1kRmqVPBOVCybnx7AbPF&AIVm?vW
> &5kI-wD
> zc0<Jo!|;>*RmaVjNAjm(^d4$C#rw%Wh=cUc`)7M(H`gdR3zTIzTqEwTDc?f#SC
> 4nK
> zsoTrow#&dyNqHNLVVhD9I);5_aS6lr#ahnyt}9kIJFE^V>I$Xq6YmO+xAy#ycfV
> *X
> zhcqacPW8g6J6<>{SCvtJB)2b}9OsCPIOAY1(?8b}-S4otEWl!EDHi*LMc=}((O<Dg
> zH5x2jA%}(F5N{{MVmeqnf%0<)b}avPxn8Pk24hNI9#r=eMr34^;#_pT_pxGiZ?
> (tQ
> zy6RjZSDoN^?ZxW;l`J-WEzMhKnLxdiR6HUbm?M2-9(`8t-
> KwsX8&H4YLhnh0L03!-
> z^<J<?o{*gVQs}fhlu9_l{Zr7ADbbdc=o1#b%ln2y3|E`O`h1yuYev3df0PZBnTYkI
> z@!b2u`n@wktTcKL9ux8$$J3_<Ja-
> ?YH}|glgmbRxK0=kH*FLFhogB}l+DH%ZzVyP9
> z9w6HS@Aoxfhi|b**Wtx-
> sl>kpoHy~ju+KjTKJeU*m&)mi^!`(K>^~|O&pXarUKuBv
> zpxl=a{w!O!6<i$Wr7{s*y5R8$H*6Iy?=RvqD~d~4&f#MGck^3AT%MoG#XnH;4
> &82u
> z%QS|tEmZ3GFQs*3K!C>5O1G%e|Gpq3z$5nPSg=^mRcc&VR;=_oD)r+<np;w
> }&B{mO
> zzcTZZc?)Ic?bbF!vSUZKZgYC=X7yB`4HS19oi8B%mBA394%rrXwM9fHM-
> kl+G|(X`
> zXx_We4XLw@osz@jwtng4nLT|y!|k<&^>u~zx_j5Hy>~)$lFzbaTN2J1XqSA!__
> u$;
> z!Jqs0oIMP}PdbDj4k|{)8-`mW2tO=@??q7g0`%SX=u<W<=MWY&@1b)-
> ge!z_UFDAl
> z(l5m&S2r*b#0qSNRsNXkE;i(9H)LxoQ=3)!79qldtFpnne7%+k45ht_kB<2M4HC
> mS
> zd3sZ<_5>v~lpdb)|Csw4_$Z5O@68vikg!1$jffZ!6b)h&Kfs7aU@NqwCMmJD^
> @Fw)
> z*N9gNyL?zal5V!m@~|zvWm{}%3m1CJ?Q2_lFI8-
> b222Se)<9FmmRkeTI_t)o)>s2Z
> z^8Wv4=6UwnkkIz_zQ5m#=Gl4XIWu$S%$YMYXU?4Agb0#JOOY{JFKn1O<PH
> Dvvb}#C
> zV&w`mM`v9(F*@(MNeOnNew5geq6GJvZ65m*IM+pq9i+rM!399@$0R{R2`8
> P465pNT
> zP$CnUqH^KmXQCBQ55qZnJI+Z*>22^FJ#V(J;TzI!m_A~__J(DgwsPaTch1Ym3
> 7;P3
> zYghspZTS`;^nlV6jt$q%9hTDw;=`XI&etEnRZuj^@E;;xyr_t3>jBEyKPw|=7*yZM
> z$Pr(|&_N5}Ff}3E19V;oaWpz&vpHY|;c;=@y!;7`xI=&!5(ps<Nq;}YwxP>&%%u
> hz
> z2KJ*EpyN-
> 5don^W1sIHcSA<Uu3w}yEbj`pO10~kY%DAEtT*vzna8na+$|7wJL6XZI
> zS(t<kl>h!&`Bx09#T*)^v1FI<0M+ONNKh*`9}2^cN?F^DfVY0nDl|YRM%QKc+g
> c7T
> z=W{}rD-
> R@+8M`JRhy`&JN{4Pp!@k5OaC~wS03QjBFopq%2F4Z1+Vf|^Xwc4R=vsV1
> z>t^x%2U>R^#C*>{wAUZ6LsR)0ZUH<SID8t?q7!|Thz9*U$p4HNWDMcd-9Vh-
> duCon
> zcK9GBaOn*NyARA;8s~YllT*)8eE9hL{qrpl&TgEWi9BiF4FBG;uZBCW4#C-
> ~FFXws
> zHYi>MuTj1T@$a8Us(0Ytp>p8f4?Fj)iU)1d$)klu<E)X{$<gp{j<T>>g}JM_ngQ>^
> zu03LqkoZ2kLj}-
> *rD+~^Oo(yMx{;0GUAXcETk~Cbt0%FNuw<=v?C|tWtLRyJCv=nC
> znM1D$VLuswI3k3thok#5G3_-
> O01bLt?^&1G2q)`DB{RMYqxK{&mkw!=GHW}{nOOhT
> zyn|iF^tREpx3Y&pJD~Y8be@|NJt1tHcXGK`addwMTn(9uCw@*+515&mpw14
> ?##Yul
> z<d>2C>oBQbZUbku&i_v1tYJCHYCxA&w1-
> B4Dc^yFLw^3F`#r;)>L*Jf_4{gJT?f_2
> zMA-
> MraM27`$Pf(gfSfQU?T7yE4>&(NT0*wMO*a+E@G0Etb{f>f9Zl#1+#zCRDS6Q9
> zN5NsbdvLL5)8H-uwfbor4^kZUJ&9Gz*QR1cjD6Q};nmx-
> *TSOtXqmr#38^PC6)m-0
> zT55ap#k3^Rnl0hgTRfqQlouz=TRm4JPrLvA5M9vnZvg|9`M0Bd-
> bk|@zM~T_{VjIK
> zfWaNwfys;V*Lg@_hmOEGbJfIwI}mEU?)=7i8BoO;P6TvTXkz~kqo<0<a@~22
> bMxWF
> z)9EQ7_IC7u<Y*eiZGZ3R<JFXsu=k(fYB0c;;I<m}i{8Tu0J#vUhrqV&FvJber%7L7
> z5b_hP#)b-AqM5Z)?VZfQ)scD2V4?sdN-
> El?9GQkYlH%B5OXqwom7?>!rMP{F7p@#i
> z+(EkrE$iT_<SCegQ`Ys92=2KseUqe1!j!~<tm{{zThesA-#_1!q=BClC_ZUH;ctVZ
> z6x_))4L2r)zeQPB(<XR9)_su;dk)-
> =Q`Ysv&MgZMLb*K<MMO@I;c1zgwuM&aLTs7v
> zye32uW5lORTLK=5JqbEch8J?*Qy3KTf|t|nlpjgF3uz+QA&`s-H)o<EiI>@<c*9jY
> zwoK1V^S3Si2rhT<Jyn&-
> E{&c7Kp07&#vL%E8HTEwEN~S)U3VepkqfC&>5vQ=BUrU1
> zR!LtqsHJ2c?BQxNV^G-+Oa-
> eT1G^;Wl6e=Rtc5s32eb_V5+kLk^d@%`^#pp{H_<S@
> zr=T(h_rMoY|JtmCGA`=htUn-
> cyPEx5!$@ZTX1kMa7FoY}klNI2w!3F~qv~uhOS)nh
> z>|XsH5J#cWQ1G3kV8$(EKra)-
> wyB!DUPS2`>6!mM*3~oNN$4b63g+WyQRU+lrZpXQ
> z$Awq(Tv$X_v{$L$t>@ew=V`mogfP>ApYZib7&~`I{p&6N`jjHar4R3fIZuJM(|Q
> =x
> zb}0$5l*V50n7~FXTQSMMIk1X>Om%l@+PoYvrE1?KN>QV8(2#)um%B`?3MN
> VlanqW}
> zK`AmXgmNvntfs&h7B>-
> M`Y&WyCZ<8TxLudWNm7>xj|o(2Os3nI9J)3Q6Ie4`qo%qs
> z(U2MwCRXdNOkt8-194YYQDD|%-
> Kgq#UBGR20S~7afHS(+s8>o@)p6iD5Jf}k0+?7`
> zWeVW;<fYm%E$-
> %{H8SnlpfS1fCALv+f7=qHuZMnZ_gVV2!Tj+VT}MbTLV+H2iv+28
> z-
> ~#PwA@y1MwWEj@T?fq{(c3V|>qytH%?RuvB{Eg5h<WE6o9Neuq>6jtYJ1WQ
> TIfW9
> zCy-L>*DjUgU%Y=&Uu)G*{-
> w$1f%I!LZ7fdWZUWaz@E8?dby74dp!{wubRvy~=r_JO
> zK_><l|H0~V((<v#{>KWh70AO;c)f6yU4PXjLE<xj!t0}UO-
> 8wEGJwMC=Nhp=6kek5
> z$`vlkSSB^l8})sm8&$c3ifGynX--~b7rYhSB1J;bqMo$CPD?EqfP;Pyr1MD`>Dll5
> zLc{H8sa8j`Vh}6XX%wT#ebThqXxe1iIY-
> 40`peJMh)u<F`VOwtZ#309=!<4=VnLws
> zKZO-
> v1KT+@0M6RtuUdT>dH~2gSfp}GnA;9t1g@d+YBHpbUeTd;+<`byj9ET>k&z+q
> z#9*3)(=Yjet%-4}4?S1+Yd~>#;$Sf{j8+PG5x`9}u6&-24`xHaj?52YNbQj~*@qw|
> zP&c3e>|P|X%OMfm<zNIc_$7Lw9gRIqMw{2;Z#%E16k9WkQ`Nlwm`G2Mt&p
> 44(ceRy
> zG#5|v_XP9Q3-
> VHq7dlXZQR`z3!X~s6L9%L9i;93)x}f^wUf|$sI7L>V@mr5ItYo%#
> z<=B9iB=-ci;Db&6`RHUR^6RSRm+-
> E)Udc`G7|0!msA`dHFQ881+hGl8(_5*D10mQ|
> zsXhaRjP#=J<mcgq0e6Vvc_w%Xkd}3Pm)3-
> 46=>yAO{ch3kUbF?%Ho#g@bTi{&AfC0
> z{7W0zDybN>Rwu<0?BwOJSMKTKI;wwLChyXStn+&tGm~RLT8cyN*u)?j1iO}D
> Hg>R!
> zEvx9&7d)nO5cFt%y>*ykV&UJZaQ268N%drbR!<s5T42$~NY&cK0q=haN9Uo-
> IwTck
> z+hny8(#jb~HDur<T0;`67m9TXuumnhmSGepl+j<H-aCY9h*&=)74jd#><-
> ssvoCFt
> z_N-lMm;7}-
> AXA5vfr&j}Cab>ju97vRE}4l{RjTBdQB3{neCmmpk*l<Q&suu4LkGy$
> zSAMq6$els5GAh@;`7@U{K8=R3DFU5wQ!wm1`k?ftvJpZDwcxf`awX>-
> tL_#y=UwRl
> z6JG*7^d+!r9JBQ9&+tq+V((Z%mxd@z*N`MSEC~tKLw9OFexJmG#Rjhc@6%
> U&z@-SB
> z7Uu82qmLZV3|9}up?27t(05>}CG`YJ+7s<uAW~ABFjM*l>Yl&DqedVd?1hc3$!f
> Gf
> z54A;@aIu?8cS;v;#=ge#7oqC*j6j>q=^Xc9VmEM(*oxB~G%ZKLuNWN6ayfJ3e
> 5u*C
> z>>L~L?2>MrKttFq|F{{GP0M4-
> be+n<K`NW)0uFHCB)C+vQ1iw(Y<E)F4!#P6?Utd^
> zo#eKZ*Av`K3csHiDWKHdLO%Bdcv{mg|KjxW0d}2=jB}Om0PFIZg=)XlDSrV<gK
> a-}
> zr~o{a4?=SA@>U1t`(}C67eEOY0c+4$``Jx$`+{?5$N-iNmg6;J8P=J(kWtg}ysNS4
> zINU1aFGL5q7}q~SccgG5TU9{(V1Y;XWnlkSP9<T!+<PVzn$k>{FC>Rl{v>{Z*h$=
> W
> z14+ipFVdCoc2$0~nTi<V18lNt!~s-$IvH?)b>*3bdS$d-`DCs1j898_K4sSjWZ-cg
> z-s*tUUcJ%{a!U?RlNv1@wpA+T??^(C;e6EV-
> AY|M>=@U0u}I9QRPX;x=BD<@4E{Qs
> z`PG+%OABCZBK$YW@E_QpG$0#N?tu+$HZW{RpHMa%oDX5+5`Dr3Yan7AH
> gtdk#b9F1
> zhA&=XQzB6)s)KxZzvcdMC{LsZjqiIgP%|pUpUQ3`Mf6}8j4f`{M20^vaUr%6eZh
> qo
> zn&>+9hs#`uIlvk*;m;dVh^>-|0+to|zArt6^3)C_wr~R}<iTigtHZfyGQ4`LG~@0&
> z#bS*tITKnVO?<E2#2=$leqRRsCoRR)1J((UiMb^Q`ZMoIv~lXIaU8DO*q@KGaI
> O?w
> ze9<mxW90*4;i=<7!&DAYgpd{Uj9-8l$@%Kf=<)-gZKRcSwh<1_;Ge9T-
> 2F59Kzj5I
> zDC6?`LZj7>C^n>oZOqLs;S(r<jO>g3MjFJsA9IocyQuWUX*s5gN>{~F1zofzS2Tq
> k
> zSR30+O!;4>ZjrN6b{7?|Of)H$E-
> HpMFt~xalIU2SE;_^A{&F7NS@3kSi~a%P$LXRD
> zux@|pqBmTunFh1rwHQW{kDb+gJmqJakDYbE<~z#fbG}012<2S0X+BuEnC83
> ZKc)Fd
> zKn^+WefY;UKCJJ#r<FE@N&hX9!7F{ZQ8Tol>}N10{du7At~q0-
> M~xAaxBsQ_PI5f-
> zR~Oeyb?g!J9OGSnbTww2-
> p8$;DW^+Lhu`q=C(;+X6>|^kaQMVpj6Y=ugXfnVtg2L>
> zMB8Hy0C=1oh#U#}v;6rb`#3#owpL?m(*4d4@hv&|z1PC6$heEqI3(D`=q}J49
> WU!Z
> zNgFQB#`$hg8go|W1q?V43%#<54-
> @6?O$=S=d%GESZQIAAT+fDuzO{&1duKi$#e9_V
> zQO-vtAM^QG9DBA7&~rj<cD_bE!~9!wn&DuR|J09hG0--
> ?IcK7zeZ90yxjd%@ALQ#+
> zg6M|Dcjyz2{-
> gSY2@q#yyZOyg4F1#lgqeX#PDL`+D2fEzfKhY~)6|nvhE(wjPH~tg
> z>qLQa%73xfd9l#$X8$vN!Ymt$jb=V!#$nMXl%}wF7u{J`8d&H=8Vk`U+?m3{(I;f
> p
> z{_p4$zTlLswn&gv89<+KmtB*CW^y1k!9aWlJgPn1XakyBjo9G&g!;}cuo7_2gYG
> d0
> zeo>|_x|cs9T_7|u-
> g1mpSRT2oFFK6wXqU`3Yag|7o9xETwDrLvhqb;cL8CI%i2|G0
> z*33s8zrbnhl_(CKZUCF4l-
> <Sq*i(8xd@55;iM<~_oe_dR)_h~O1%a#WwzRoL?Q$E#
> z^=905^TEUvhHv5Ir#&Gti8O{{XmNWA!&lHj`s+E;)YQeiCQsI?)BwIKw|a3zu2Qc
> C
> z%>q5R;2b&BpQuAK1n*Fz4&zk57WA_hK|{I{Q>~5r;H=Sjm>+Z#yh~I&yzLYV{
> wA3{
> z;Uoi2Cf2-9!-D^Vn7+bJ0cvUWA7HDS6(x@vaGL-ZL(8-
> #{1{+Oy2w@xo!pan#tURl
> z4HH~;4%}Gq<2n^({|Gq`48V;{Si@h5om!|Upt2Ynm@h09;DvB@n;kV{t+d&|B
> wIHx
> z<A%nXUBHVc9e*}35L^mOWi7F1QL_scyUmqq^++m5a;Z1SNo>SKF2NZbcTJv
> w$GNYr
> zFnDRF5y-uSK0NYE4qz{H*_Av3(5Cab(Vfp+nGj;{1Qrf$$&U<-
> 43f%r!VLpcrghe^
> zshq{==>Zm;iNE4icJ?aTptfkPR(s{vID<PCyt2UqzHdw3p!-IK-8V9EzRPSJ;lkCY
> zYML=+haJmC%-DB2yF7LS)1?I&w>Br{-z7%P&AiCCrUmN4#lkLJT|+J;K1-
> B7h0SmO
> zp-
> Px^0IgkEnhex!_4c<yYM9(Z<wMTOs^}E|oQKM44y?{eT*%BuI4a1*5WLgKE4T
> >E
> ziLhtCe^=f=T-
> I1@h?P|^|0hXJIA@@_3D!8Ab%Ctz5;p=Ou?~;3sJCJvZbYqAZ;O-n
> zY~ND{NW-#&yuH-
> U$E7^IOVFNW&|cW;Z_e{9#ND@5>c@5l*p>4)m$gw@#TA;+!Jw9O
> z<&=|Hj#*pc<!m<YKy(#LfC+WPxnUuojHwDM5P9AgDF@wJBirBCXVzOITTF=
> dP;o}%
> zYF0eK)iD3_g{fbR#daVj8Y8F`=Q9>zOi5e)X_^%;eawnU8W9ak7g>@IY$YP!V+#
> 4k
> z8cD$SOq{XYeuSw;r;xl8cP1l_rVf%l8$<$@ptml@6tJ2~|Cpd#A+|nFmP`6rT(C
> M=
> zrO^ZbrJI$QU2-u8GJIDI^JZKtLiME-rK?)9cbdOzH4X!(6Q0L46C;h>qn%EK*5s6o
> z5&E8MjjYELboW>>zT1+Li`ZCv17f0aLRbP9i!r8T@AN)q7-
> oA}aY@Ggu>7S<EXh=M
> zc4Li9CSSS1D*@kA5yo=A6XxEXvMbwZNdeeg#1^NN!d+VlSTPp8(26tB!sy6;p
> A!#i
> zTGCmF<PnPqdXQy;C$%dBn5F6MT!)taUflkH9;6G?buKwLtzrOLzDinZ<u}MT8c
> P89
> z-
> @#MJ2VG%|QC6JK5+R5${7vE91@CB}SY#r;MJ16HW71fhF(n7<PgMhQ>2gc5)r
> `FK
> zAxm<U?d*6l;Ph9a4-4@<6=N*-XGg)K4}yk@3<?wjx*$-
> IutLSO&xxf%MJT)e59EC;
> z767hQ@EHVPgWSHyOZFY^snp10NoI^IM21FKHTVl-
> 1w$94q~7;HlSCX3xO3t+{G)LZ
> zTZ*tHamH4|eG-
> 0R>vMFWf4jNB0!+aclYpDo;YyELm&FLN_G`MJGAU?HCRD37WjP3a
> z94(pru))Z<>-al*p3lf7=<U(_l8*fo)J0GVL>f>_*=Z`pGY1wr3*ofGSms#>V$l}$
> z;uJcawv<7o$Ng@sx$jQSJ%?1}=@U3&!+Zy(VxvMs;F)?t@)9*%vL1~RRjC9?V
> &>+R
> zC3T6v)2i45?-
> Uonsb<>B+R+bVebsZ;`l?|N|H{$NDa_GXM$Eqj7GOOX0?nj7IcYao
> z*YlhOkjN@96aSfSmP8~j6p=1d{6HgM18tlgW!9GCuD9yXQY%mp^*4l9H+W!si
> yeYL
> zLcCZN4beQB1GdWPiee<A`lKPeuRL1Qu$5nOJg`5U=5JVvn{yiW-
> ;s@Rv7t4S#asS{
> z{pC5Z`)a_&N=V5s>t>7}Ux%2+JI0&0wa(lA853YQhcs8{G%~*e)czSac#`Wd$Q_
> |`
> zl^)cSn;pJ}KOqFO1q&AwZGh@R>`~TR73;GqHbg7x>Q`?dW~*_2XhSr<0{GCk3
> 4a-F
> zNhs>y(CXhz!l70bw#7yvjrz-KHfZl=fo6Pm)9Q-Pq|qvGE5VUd;w!9T1uQ-
> qqI%y+
> zzF>208zERiLwIj_w4%YP*=%Ktt)xRd3_1TO@y<!EuP3l!3kKjc#FM<l@^6&!aw
> Eti
> zQ-
> t+aO<j0jcC@ArpUV8G>lVSjE<CNzSfK&nmNUMFFysB}X|s7eBe=q<K@gYTd$
> ~hc
> z2Up5{g|qZb>^|fqi>!_M08AGA(~vT(Z-eEpgBy1k8X>eE)9Mdr2e$Z-
> F<A+IU6y=~
> zlVdo~(X2;H5^#bwTkpy=L_h3JOmo!-
> N_JD9@am0OzStz;gpD|LlO^1$%M9PrN3ZY=
> z;i+eQk-tdwNaK2>!RgS}NDw(fz|vc3%|<8$wQ2pk(KtU?@)@0Mw#-
> r+!>b!Xn6Duh
> zgur}Xmi!uFAI$1U{hPw8H+h0VsbC}bsW!pM8=+5S!fRno11v=$XUc`yvtc7uvq^
> 71
> zg->UJl74*0rsVTb7&SPw0p`u{TXZ+}EHrJz`3TG_8*o?+GaaOgR(g{-
> P=nM}Fy$>r
> zOe1b|L5IuWN}fJRq~N?d!4|zPJHeBFmasUQt{b>RXEnG#WcXV!A_x3y&rcy}
> %U7@D
> zZ1YyxU-
> bkZ#B9j0G?Zgxb(q6~)q7I$hShs`@mG)BLId+u*umxkjRv5Rd;v=!%m6gk
> zRH?59*v&wY-d5dLPz6td{nwGC&`;HOjz-%%`iCA{K1O&4M>KL0&(?^-
> lc{kBkO^5a
> zeyIxNAaP$|FI!N);od03XCrpa(%KsW$FzjZz#Tt`2FYQsdcW@dl6AO=+0YC$!^=
> Si
> zst{Kpls7CIx$#aRLIy9jBq8RVk|T7^?&1yhHt<zeocZ$>ws6lap(2en?x3Roa@mLv
> zt8%V8hO7FacKP8Zsji&b)@7+#4{B0^y5jb;VW%FBw0^JXBmMnbpTk}#V-
> @daxNOa1
> z>UJp+eHaYHtt>7YMNfVdzmS8l3OdH4?$|!|{*3#0wT}dPgq~{NFb=zpk{mE4s(
> A=2
> zfO9!1$iPW}OJa3C1{9{i(7LF0sJh@IGHx4k!D^U(fExWB`~Amn+3!DrIZg-Y>Zy_y
> zBDdLyQu0FE_;gmbNiHYLkPC?HxHuT9-
> u<wA9z^M7D_8Lg`r*E%=<4ohs3&?~uXSIp
> z_1xpu0n8(&94t8)KJMdBx}w=SJp7f=hb?sZUxkmajaI0#KL;-;`SaZ$t5n|wjz&LR
> zq2TRjxpg1Unq>XD<S-
> VQSw~A=jo#N~g*vU(UD#TDXFG~Xeyr@J(2eiC8s3}F?HU+q
> zP?3BR-
> *C|sZ~Vl~hbN)PD#3x`>MAuC)zl><N7=y8dGAeR!b?2x&5}$l)Fjknt?qXE
> znO$Y6uNV4i)YnN5t#xup?AxU9Lf@l9@b^*Zs~^1^`szpTr@oph?7I-
> P_Tz|J`v9UI
> zU09CCzf|I}Y(5@q7URQ%h+F$8;?^!l+}gE^V^7v0Pg}XYO>j!L_#r;#eDh^cD!8|
> E
> zC&I2<O+tEbO>$JSDE%{b_w)6)v>goghrYn354r9Sooz%*>i$rW9mmVt)wN%6
> E)Eqt
> z3J_k7294wnCJ&ZDA96^Hp2q}s>ke>#U^@eu>SO3Tt`2a>6Pl%-
> g|Bf(Tc{xe8v!nf
> z)kwIXM2c2_3-
> IQo4^7!eG#Y`1<!?z0!|YC6+ZE!O$zED8ehpZE7vZ_RzKi|Ss@a9J
> zL!xnkg_OqX0UN6(bU_zZ(8|nGSGlp$kQyr{R$n+{uxe&0F0B6Y7_n+j1Z55hTP
> wKx
> zYa<LM?O5LX-@uR~^N=pqp&QV2hr+O8%KY%pp8#;inoAk=8$?ysdVNp&-
> >6hY&BDXb
> zH6<@$T*VtWMBlD{N*MK#XYG%oHNm*vue9U_D5l;BpT33`%tg4VCF;j;)P*x
> 2HE&?Y
> zM&?LeNt|4$cq4qOgeM{TWk3@19*u$wUQz=RPd1HTgFzhjDXsoJtfq?;Z>%IK
> _9Py{
> z!Y+9m(}$+&{7We|3!t6$Bw={p#c5T~3Y>SxrI=i1+(V<B0`e)FuYfaXJGK9fa8Ful
> zlZ2^p4=0cP44gVYG))trG*oIsGLb3$9v);d4RdzY5A;nr@?Hpw1XY{ud$Q(@Y7%
> }b
> zst14JO+t7yB9=(NPL*PpG+7m(Cq$=>@&xn;4rr-
> H<<qMQB~8y`Ympd)PZUQho=6Vm
> z*J#ZXmj8*cx|!K!CZYK1gvITWOxz1pQ-
> o_nqcug)MV9&1l0xVK%PLf8G{y))b6QR3
> za$E%3=KD!aK^Cn_+GyE>HixNSk?cieCSh6Iuk91qzr_-<OOAhZv5*tq5V}-
> 8E+t|E
> z({H6PGI1#iAI}b5EkGF|SZf!BJFtUL4|^z&r*1jcivYm21BgJTYnR=ieurLcYy_Dz
> zRI11g-}-omfKIKmuVa%-
> Dwk~Og7QT}LDsbKNN*eJ7p>Xt;<lB`$!)u_$X#&uwZN2b
> zX=0Mr8EOcXYAv=sh9gfgy>yw!h&(-
> ZS|CN9rhSGyZPwq;lBa2KQr<Tl$p1I;`+!@1
> zFS`5VgGlf;^+@P%OK`~YW=>%o34T&b@ULYEDQpWkz<gAF059M!2~NmBJ0
> DD}?mA^;
> zrAXvf|86izN=~$?XMv67-
> (}V8PTV?(EZ@Q;<cuv^mT$2SnY(1U!SBzWH2n4uzx&+y
> zJrGFYC$jt}JqABYULdwp|CoWMO<gAVJz>@COl)>Zbu%6vAhZz~uRAg%R?(&
> |LOLzn
> z+thI8;TG;~swZd*_tz^`+0ThJdf8?p++T-
> qZ&U4rQUCI^{V}|HvnOZ^_f%;j++QD1
> zxWAq*++TMK_f!V9c&$MuY2ww$)HF#skZ>09T7ldtUI&usqZ~Yp<VhihzJViFJ
> Qt@H
> z{2w^)6H8PI+6qmCmzI(U5A7BrXh91+-
> z>%4Fgec%TL0^qnzX6y0(zSR3PDSxM9{Ks
> zB53`uhgC7wtrWBsuSY93VM!W(^JZq3li-dSbnIpRf+abL9ejZ-
> dmi_&72()zS&dpU
> zcR7qATFU$<m&~v#TFNR;hVIv2AO}O8Q^3hiZNBm83{Nz)A-
> Z~F)Zd5`C8BUxzkKo%
> zNU;rN6^+ZsYha|uhEEIp-
> (&3tK|kfMS$i*dIqGkT)*OK7ro4x~A|<;0UEH2~9dwp$
> zn63m4Mxfj-vA)9;8N$~ay3B}fp4o=zc5`dOl1f7CX7kt>z<DB>ayc_NvL2gK6yjr-
> zV3=?5EXR#rl+U40;sb^GlB(tW(6?-
> k8gkkZ>XJz?ALUS}W6y>^9NZ;S#v@boEy+8H
> zv%oI6wMNp@)T)d3+esQ+q|)-<Q66zV?197wF?h}yB*FCmK-
> 9m(5&dmy&F3jVwp%qj
> zT+;sm_o1DE<^TSH<#C$e4v75UtRV-K|8-6-_G&@aM?5^38b(C^-
> |avGAKdp0VY039
> zX()>F8u%=%<MYy0eBQW%&*?!t7p^bdB0qT><>%7H@{_YjekKIu=b8oh+5F
> X<P580=
> zo^9*pH+$O#{Kov=ZJYTX>3~dY%{dCcNE!HVD?e^qkGIyGIy}$I_B6NVG{{%*e
> O@sQ
> zJ7Y(Y#wr}oaQql$V&T0|8f<F=7~CF)Kg3>{O(&%HAUe<kf!|j+55e$sg1~<cpzh
> O9
> z0hZ8LSc$JtFU`e|z0hL&oC$0=YdzjJh(5U0-$8zIEjW(iW_J!(!D?A?PYo15DGQDh
> z;8EAq9x#*DN8fV|R~j<l0k|YqTmGU`KoJbL&ajpyd&+65e&*=Y>@wD*m(k8L
> -u$bp
> z3=OHvpe?()HC4t77}20#H%5o*$WK^0j)xli5gfs5!<<K)K9&0-`ovco{3pwjCEGYn
> zYO7LD+Y#b4sjXV=&=JOI5|Vt=K%_fOI>2G|fOeX6U|rStwi9iqeb4NJLh@mhT
> ctj2
> z=S%NQ*r-
> >Pb_5IZBj4NI1u@Cw0SjtjK`l~HO$)T)%^jZR9*E!rbWx1mT{b8|n)MKm
> zQ_=P!a&fJ+=^Zw`N9YNKJq5uc@*4HnyDoZbNKJ1hR)-
> *1Wf9pyxg;hvQ^iT%wgTZ_
> zSh+y#KnT;ep62RsOj)Dt>pS2=2a(5cpPtw+Q7f3znn06>3%7psV`((#O*$aL?D^
> *d
> z_kYU8-
> >JN{<1uZxp7jCC=M*&UANs>t@M1dpYxKas6J87jx19q%b%Y64;9{5`vZ1B?
> zwC_@S&EVgqv>RRD(Vuso)t?8upVcU;AS$k(Dh*=zAN?Fck~;`~oTi1P0qEONm
> RJ01
> zxR;836<=_gb8G%{aMF6~22XGmK3au*wX)aAfu=A(aPgG^vT`?6sq4z5t=Ms}p
> L0@1
> z(39YZf>qPme0h?*pgz2>*r;czoK3~!KB{VFfJuOfY|XAmDW1e9z*%X$F&x#|cC
> %FH
> zZ)wy(?{McN_+wJc%53wwq#F=CN$J+`uhJ7L11Fyn>6Q&C<C1QGnXDE=wm6
> e<4H;+y
> zxFlBl-qI-`-6}BIhN29sZ`(yz2a4FvoISNwb`e|Av0O!Tu!uZ&5gJk#!Nlr;R1t5Y
> z^;`nfR*N?3GOFz|rl*$ywdiE^AAfdLLqqB^m{`3JB{H!>HNJ#0&}mT&E<xv^S9>
> T}
> zq)YjjUCJxnX*H3dV5Yki4XI0EVnyY*DWzDKVvTf>s~zN;r3;y77qTS15E%=859#B
> y
> zh=$aKFtI9474i#=H)<y*f%%xUsehMr<cR*lKz$pKa{Q+U&IbE@5i+`3MkzNnG
> qkey
> zT8t=F>I(RV*83+9qD4O^DC&ZnIXGU3|2`MkDdS{d2Y);<c>h-
> 4qoc2uqDpn)BdmTg
> zhJq_;{uUeyFNPYtHY32T0#)!KA&`AyAt&*3j%I!Z)x1p1F&~34g$KW1yhT*7zQJ
> )N
> z>{V+gu<%X(46bE>Sr}7sTe{#0=7)WpZkXKniG@+8D0S`)mDED>0g(C|iJf<vzcY
> AY
> zVA7-
> DYhog2D__2npK_Dsm_v&q>Du6puos{$lB@1Pj`ZmXzoQdYs`dw1J``iP)S*$X
> z%*wW)3&B3!WBM(ttNskjTY3{R<`$zX<Eh9PnvzP55VP>x`L5FWVtw&A8|uYB
> ks<gm
> zbsC3+!U5ZTh)gwXXrbB)STt(ze$=10YE-=~jXKTW9lU_;jACwcqCz)Wq3-
> bh455|m
> z+KkiR%DS)tqd#HL?uIO_R70IlnLunV1~qkq6oyHgx*8#wj*CUX2pZ{u_}vwxk5{
> ;X
> zakv0Ob?7*p9ZSu)MV?Ky)kY^-)3fYe;l%4{@?78;z6N$MoQeA*S%9-
> a0%>!d`X1zo
> z-F;HPfsIHZS*Sl@-^X;*`zX`o3JKf!+c8)}F4hHc@?;lukbNap5Jb*(>LzzV4zMnW
> zStxF5nS#10*`Oma2gkI`85_`&E%19+N%PZ7g4nrE9YUXXs^kFcl0?2;k}7E(B~ML
> 0
> z3cCgJ4Z3wb4aFf05j}y|TxE5?omMMIpX=0ocUcawE=#1`Pu_59HAa_ZWunvB1
> Z)EV
> zwUi5VxQdFV7uCk1-
> c7oy<pArVMApqp6~!xZ$<kew>c`hfmxgd4Lw8lF@7NJAo$iEX
> zOFPQdHZEL0*1}x~4zA9|`8n{SEm9)dJ{H-%BzH??hnuso4-
> t5WI4=<H!ji1wP?dV%
> z4yi9RnsS;+Og<(M8&BY`1STtLobws-;-
> Ou;An#x6<F}RSho535*j)*{m!4+#Zh*_#
> zI(maalJd(%DpjiGItgkhmS?@m0@f*r1uq<H^)7>!wG)*whaqcmVK-
> c%e!bL?MoFK$
> z9$HM+{g{Y<S`EO!!Jf17mMa)Z&xd%@5+rdGB_j#CM|^>UBsn<L8JK|R6iJ|bP;
> <)-
> zNklwrQ-t#Yh3ZWtaEc^#tRBq=VW=vSeJ|Ab5W1CW(<g-
> @Qs=q4yeuBBQR?>z$P%bf
> zPGVvM1`|V?ZaIep%cX9QZ+#siQPef*MHNd?-
> Pjjju@0{7aR9A^N2U*y>_h3QO5JIf
> zJVuvH+F+>R`azF+SE>ap8D|SYWBb%2Z{C5NrT=|RCCI)<Fm;nX_)2yD9M%E~n
> y#{n
> z+@Q!k(7SiGj>U0VIY%n;4fhQ@`(2uq#u$-
> ?lgdV(eHNY1C1!9cZnAm_ecSH*1~PDz
> zoJM)5#$w~!$e6vr(KUOL&VVV0nLT~pE~5{<&Q%6ZUX`ea-
> DPM<U4}@Prq}H<lJm){
> zF`RIZVQ{ez*Q!Y}Ttf`QpqpFIa7M<PY&b^g)r)!)rvrt4y&xP1p;zx@o?Z?VI4=K!
> zexq4~Iqy@&p;0XNFB8(U<Ki=?p7ts!wFDCS!qW#2B)SgfLfiXu4jHwTfk_Nxs;u
> <7
> z_jp2O>U$6}dURC_BxsIG=tO}cq?CNrldw(&;k0)ZZr-
> DI;S;AEN0W4H(up>a>98sA
> zU*Ak4b~pC4)Z|ow@BGo#wpD_qE|B>szpKDxEs4=rn2o)9EyMakMfN`ZW?_
> PCwH?`6
> zp5*Od?C^>FATAY5^44}7&j?<HhQlUHaIE@?l$itkRZxPoB~TCPq}j>L0UV})zF42
> N
> zowYt2%zwYDB|6NZm3G|{9}P6?mRO0d=Hfz(+}Ef-{J}*H4H?);@-
> wlz`M9LOxfmV?
> z3iPdI1E6bOrl+mb8If`wJYSc0mtEd@>E&SnzgmUd<!MM=9uuq94pUz8R#;LzF
> Fphu
> zMGFhQ320#U2?cb&b=*+(I}JV9I!^f2yEPjcFCHSF-iDK8`pD0_%#+szjSElDr9v!t
> zvHJaAGHAfh6G1QIvy~_5U>gKDUjuu+@O^_Eq99@)Y$4`A3_Yd?9{zm|o0$$q
> Mlgu!
> z&>zeEz01CU&lY4|ukV@ck>Q@{A@G=%ck-
> c1%|gi#))+S`4ZV9Tbl=|CJTEMK{#{Q9
> zh44$p26}|zf$yOxo9G+C=}sd{`QXObtjvsLK5d)!X2b9)aSx<vKc3V4)^!%Y4R)Uh
> z+UKf?Zbd+9lr!?jk>6*x)wMe1U~NSyBkjd0Rl0l`8wl)Sch?gg!`NHUk(@e9Q%+I
> 2
> z5TLdQPXPyJA+=<oK1F{bwrDBFhy>1V#h}fm#XaKCpyzv*V|O)I{1#%56&kQEe
> x?RY
> zZhgWyYA>tC26p^H&^iGCyD82~M+<^ziV8u#IA}S*8ZBm_TK?OGR@A`;at}v|
> Nn>@r
> zD5S`0oScLxaTdr-
> WaW366jKN|i||G>SpoU_Axt_fFOF?58@hWOE5Ice55EYay6pKV
> zn`5)B5m)O$3Yj!~R+K44{n&-
> =1EC8Avz<Z&!w@3eQUqn0=BNC*{q48T!B4M>3jwFU
> zr=Kauz@)t)$o*X?V;~vuiq7F&d}WVdXYrRzbTE-
> FXp)A!2OMEHWVspe%~?8W$R{AG
> zoQ8CO16|}VW})8yovR_QKa0QUi$M>8Ty}AdvNz>lp-
> uDn{Vp8#m<fTw0n?NzYN8tl
> z2Uz34EYxy04nIcQu(8yiWs?I8B;rhtJ^m}d@k*K-H`_c!QC2e=452-GprJW+`{j*N
> zD-4Xh|Hz94PpCj`d5yH7fuV{ch~dx=4qIYluMye^g!CLm<eimSsU`}yU}D;L7jrF=
> zj)#dI4B&gCuvK!;I;6cOQW^~E{(wpi-HMonJR_5W^8-
> iOoSAC19@lM!G@7tfB_ILp
> zCal$vfo6b9VpaBASNrj#o3v8o7o=3pKX|VHB-
> EqkTt7_SPNtvh{|t6S(bHVhNPDWf
> zNm#M=0=p8s^>A!g0z6Qv#=9$_A$28~SS@?iRf#W?3DIzLih(Uhcx`~qW&S$x
> DU0!l
> zqmt-aF@(_%0~}~W@1Ms}gFc*lf|<z|W&Df0^gp3NM~Vg=(9EXO;Ql2-
> gP$)3(m2YV
> zr_DC|xi^5@VjKyg3)wM&8#HOg*rfRmx`Jy60L(S&Jcv@;w?VCj)TCiz^{JzpG$Ii
> n
> z1?%+%AGDoP+>g##g6^SRk5KfKaO?!fpY46*DE5ETzH2Y9cKw(V{Gxr3EXOt|n
> >vlN
> zwM5eLvh*x@*)iz;n&@m`+lsLqT5YOmMBQPg<88)0Qn{X#1p-
> ^xBQjMG9n?jrHZFHM
> zASRrSpdkYr0j}rZ*T14uK#|*wGGaB*e9|3*oM~w1A%`k>@WCKY9RRIH_(N
> MBTohAo
> zOKqOvjd6?Sq>L-0u}_dTgTtLg$2`FgbLJYH3g-}VEbHi5UdiEi`3$_qiYfn5bC(5<
> z)54UWzD8l#Tcth*gL{mE&q-E3m5sV#cOjb3MN$^hV%<2v_Kz8_D$k<-
> VE2Ex_BV_4
> z0!XXQ#|FkfD+37Ue>Tzk^q_8cT+D>0sD~k6Y@!Do;D8sYB@6ZQ-
> )IKq+9>gL89<8k
> z;T6}c$kuA<W)9F!*DiEjdZEy2O;LY^Ja7tifOVnFLiyc=jzOW})uTPZN3l4sKd~12
> zM`z{Lj-hg=2-
> (0^SD}UJg|@TMdUv4?ur8EYsJ3=jO}WxAOr#xZ*=hkj{Bt~_3ALhC
> zZ@2}Fls>(LUv{w2Jh{xS96N?qrZ7v9HPXI-
> !d!hK7f`^7oq@pb`DqYvIShtEx@zUQ
> z+GZ)7E62cH)CvnG+H;&7gqigGwZ3zY)TISaR7v{le*fDD$~+QAbR05GzroaQLLF
> X%
> zdFayk#VO#v{N!+ByN(xhDeb_D9XXJ@7mt(8AA&h~OO?7-
> 77e%v=t<FnQ0Mg~vJg(t
> zpo=YlawBwBjZE4rm8C&huBQ%5A?WoA>W_QMhhl(*d1GJwLBx6*Yj9m%J*-
> UdBKDJg
> za$cj+52Z~3tg@pO8-nmYzab-
> 7fM;g##^mkVSyEkMFOq|AV5A6pD3;<u)|f>1AikNC
> zXa>p?-
> @?;G$|)uFMaUaHGlKAFg)JM_D&p;CeFi|8a6Nt@U)D$cd(1s1Pk<7rG=1vY
> z>~HDu+wOCF$cgX0>|%chSW}2us1F@+apEDY(!n3mnnugt7{;w^c&=_-y!-
> *HqS5!{
> z*D7C|;prP6pNb#*D)~04i+E*9u+<R{apy_w)?sSa5;S3}$1)NYJT#&eU{*@@6*
> UFw
> z1WiDol9(h41!M=FyD&n52Kk7?Ts6DHt9Oe_E=_?OToj1v!QZ9;z^15o(Z3x5-
> ~ek1
> zEFuMF9d=RRAQ)7$#ZXv%@!VP+k4CS(*#v?gVE|QJJIVxt_k|G?oWfV261*w7
> fI-we
> zcvtch3_=SMoWuau3c+g`K;FSo$y?!*K?uaQM;PUJ5}a)z%xWioqQlgpB(~|W5ci
> u1
> zs|u+XLTIsETS^9TkZKjECsf0M7ls8S#t<%m39sHo+8OS-
> +eNzyJv*>z2e2vXX^1I@
> zb`G$Md%SHf+I<CjXbci{M2Xx_YK*e-I-
> a`I^WNdhD@Ge1@M!rC;wL?&Ja`4BMpO=A
> zcHV)R7p}rWLQK9O&oV=pL@F^fQ<7soa)g(L4getsajK2pR*Wf|&I9_pjwBA=q
> o3vj
> zu%@H_Aacg&-
> JvGqWD<H8=kU2WiUxILu2c@+Q#_{*{F)UmLY!(s(DEdnhC&xp$kq&^
> zOl@ul76^xE*hl3r!qh?XVhXS5%s3=s>$3pR&^gwhK%!=xuE*0C*@_=j1Bx<V1
> J41o
> zw#U&dIC#?YcjipHzFZ^Va|adh1_F?03wT?b_bX|+Z1pnwKlR{Ui9_e1r~R+x|1
> T#0
> zWlsK!kUwwOu+Qkp!o?T)5-
> 4HpThaF|ebgT{uxCPYrcK|D!I_YOz^^9_0^aqrb=~Or
> zqGo5c>U@d3nGGLdFzlL7>o49bG+doTf7fT5)T;>U%D?30z~7x2g6Tm`9}e$v7|
> 2IV
> zR)`m*^o0+2Wdt}zZ8KMLUjaWswG3;`zVP!IjTM-34c0L0D*9w-
> 9UNe8{`k7%bxsZg
> zHQab9>G*74<P-
> =d!<D#^@iioDw!(!Y+#tjuVhmN_j%xMz4><H;hr1bu(|w_9RS_y&
> zKQ#;}Y`v0}*bkO<M7DYn4JKRsiRU1m5?=?*e*X)+Bhmi?*8|M&6B{KzsOoM9
> QC<l5
> zjKb!wzgaFL5P*p%M3+Y$y`BFbWcr=09&z&jEb^x&#URlA?`cS0Y6$!zlkP^Q69z
> 3o
> zI(Nlyg<ur1fDt@&B@AEnV9rY>3efS(At7oC=!UIj0tflwejJvda4=wF16_LFN{c#s
> z480S*-
> dQZznMdV#a(&YZk*1lRwb!S@!G}y3#Rbdl_zX|*7CRo{$;k@)Ez=Xc*@nWE
> zh1c2f2v0~}$;na@j!l4L28M?EQ+$T95uKSFCQpVT!!SAJ?84V@Ge(V8|8}$%es<
> `e
> zE&LI#?I`y}v@st<4I-PPF&?L_Z{id0<-u#5a9yy_2{-#1Uc~3bS0Tq*wSjvgEHdp-
> zG){jVR)kL)_v%0sU$cE*7PU%@FMZ=<Etn|SUVWw0Jim|Zkspl&@I4w|gr^l_c
> zBHA
> zAUr7uW9TmSZ5w*NKrawzhA)pX96m)R)1Y-S3C~vEU)juZ26W*hV+XMIBsjv-
> gMR#8
> zW)k63aF;+6pTPa!2o&QBa6j4~_dFY$dH5cUQ=x3d7#<#DIQa22++W*kYRXf7(
> Rigm
> zGkkfBVK?qA$3#x4xi8wd&yY6VLd=~iI04>t;%kWFV{KNfW;;e8>Bi4&K(6fSPlQ)
> L
> z;aPKic=e8q(4;9xFxWS1Hs9`I^Z6p3jY)&y8>`}pXlyo-YvQvnc##fd2B+&lR&ZS6
> zRUxD_X0E||;~^VwS_Rav-
> v0J4o`nlz@@WE03c7E{;c9SO{pmA!;=HBC_>idTvIWI*
> zjpA+>icKQE4T|bo6ryJ$SWC$I@KO|JRcz-
> 7%8t?p^={}kv;p?|1ikP4n<0pnee@Mf
> z5q7sORsH@2V2zEDu0%Tum98~acu#{p&_A`txyYp6!ql{fN_+#UL2ES0k5JcE|0
> X=~
> z!{sf0q+hP{zug#_1&Y=+@tG04L<cgVUxLT#?L-|ZkP*Bj;hpruJL-
> oDZZ50Xw5G<m
> z4uGqIlA29u@=dY1Ios`_==GnNnr_5ddiDujg+;O)$X4A4?V7&H9$c|0t70P#7$
> mnj
> z;|<}{R)Xs)-mW{o7MF^RuRBpU?65Q#osoeEXN|h!jWEjaaHag-
> ZwCjiJCV_RV(7YA
> z8RN&V9kx%fq|yVWpJ!jvsjsZU1$<h1%?{0$$()yFzJm>~a{ZQEIcp#QdG@?VC
> R?Cr
> zGp<XP*_c=@bFqfm*kO{|nJ2jCWoC;0_fF3qwx?H*w(7~p-
> @uwa<<E_^Fzuf)pTtx~
> zUG=<a%H+6Yu|q(zW*PzM7Bw5E)4Hfm-
> Vi%H!}B=)zK_43;;#vRzr&v=C;eYW`fE;R
> zzxS+u@Bip)c5II4hTqPRzb9Xv;o%?OJ-^d`OAzKC-
> >D%K{Ws3o_M&mnA9^U0VjRP}
> zpo5TYJy^kYSu<eH0Rt6LFwlEV54uHaS4Z|}&VP#?1p6m4<>ZRIlbO*gOb?DS!p
> 4P!
> zqCOIPJG^Pw@$1WpPn9|XaJ|Q)HJAD+_}!4MpFe5K?2|+q>XHHU^KDRMKr
> Q*-=$6h*
> zgC-|XZO;MM*y}Cm=Ls3u!v~f7>f8Gyg*FZN2*krbp`SmeZhGIRSkO83^QIC-
> >6H-u
> ze8YZMB`$DPLiF=5!{Y_2tt;`RObVowexAzqWw^13x_M~g3tam79yv(Vlf(iG8`2T!
> zu@&?jFM90RwjTR-
> yk;z$hF%3*o_=1lkI@qb{e;680v9628!xYDuT;PKq}2K8I*^;2
> z09pal&y51_0<iV*rEEq|ZLw4k?U{$Z>1t2t<4e`bU%E)4A$5B)v3jA|MT##_Hq(?
> S
> zU*C}j5^xh-j%8!_f*zxBjU#sGvDP)TNNrF2ip=&8QlmXZjdt8Cl}?T3PiSh$?u0{)
> zHk-St^#OOc!H|k3V5!}St8HrZiTrbHCINGedbowu7>A^wn}*cXkll%<XEinWJ-
> Jv~
> zHDI^u18C0@xu%b9mua=5_bSkwXFJY5#FNEt0NhSSTRGF*`~q5O_t{79k$Mia
> Jwf?X
> zWuy;|A`YV?Y_DgvT)<{qx0!wa>wz+aP;wN8iGEiBD9%;5v55c0N-
> HHnM1GV~vu*qn
> z*tA^roN(5{KrsWE>c7yTT$}}3ma5C1b8(i24CDelz{KkF&uCi8MCniHWK)jFCDgp
> ~
> z`XpLQ?UNE7v`eT;F99a|rK$<i#*sxDQkTHQ%I7YDJLhO2Y}Z2~iF5vZh*xpWpHJ
> uf
> z*j!T?{XKt^|IF>A+*@&WkHGO&s{G@+U2x8cdky=*{Z0jVAYhZOz(aNgHlU-
> qNYud!
> z^g_}&?4}`g1(;ZUv`LeQ?3UmX32mIY1ot2mj9-
> ocq93dCV7K1w7!z2a%dWM{E=VsM
> zTOFmUPRb_v!Ri`Pm(9fL$R1bo+=a5WHW<u<BUinwa<CY(V1MQ{U>n(&q^lS
> a1>9MC
> z@3+w!9QDAshoK9uTImI#rrQa^{mSa@^OoT>eRp{8$B_@N+_bZyatyJh>9J1c
> <nU$K
> z73~4Bmu!Qef$zvAi+~p7td7;TPe-
> w;m?~rld<Av1DKQKk+|>%$e<@YVAmr>;NC9hN
> zFbnm|U!)o$>6dClwDgL&N40ygTU+xEB49tSH*P!ERlLKicYDQJ6FtjzK1pu`y-
> N;B
> zXWm!fVgHqmi$+DqMWgoG@=K-
> ^$P>eRKUeAx_F`G5J1WvsN71jZe+U5jWR%XoXjteX
> z_TaT6#TSoUc|TA&oKk3Uf%!5thKf4RG?5_kU@AN#L~-
> vTqyn6((Xv`gg|X7Hq42*A
> zb+GCEEj=NyRkjceQ`8WMQM=owfCC#H*--
> Oy7xPWREP}G3O}Fbww5yg40lLJr%eg+i
> z9EgW0>bnpCPB{*+E=MH9TTi>nX%Pw0E)t?mBt)AnA=*Sjv<)C34pBn1Nh=?s
> &Q%NW
> zigu9@V?M_0WsU-`$woq$YIL9)T0#Wwa8=`BJ@v531tBp-
> y#g`du%`p8t08jY3R4Y{
> z6CWTqh&YiG`64F{AVwDH2k?tNa=?}oV~v~$%y40l&?CN$f$WOb2nJeIq<}RB
> A}zM>
> zb`g@(1V>u5i?k^41WTmb3??lw8iw0Eko~Zc!dij%*>sBWekHt@855(mxce4!Rf
> y^-
> z&sSC2tf~TwIC{acNA5o%Q*u2#o$W}Lwk2N_$<jv2(r!x@({wJ$vd~4ioqBR$6H
> X+{
> zXh>0~=^S89IFT$5KcxxBru$!%EcvoJ(dVflA80IOHfnXpzQITc^yj|9T<i*%gOt+0
> zC)$k%v!qysQp>MD1IIy1t(}6E9emEM^m^b2);4H<{x@9raaV&dC4}*JB!+=7G
> @+v1
> z15Bvwb9m;8wX#67o;Iw~L$pmZ^xEl4q4V3lwpK$1c2G1hvAX3+A(%0(V3E6l9#
> )eH
> z?l@t9@jc18IzPO`50&tTfVujUb2Bf6@0B1dg6RlP1}B1I8a)P#x%UJHE4~juJgp{|
> zTRL9p(>+NrRS#?p@s)1saHS1glK0{rd`ep#rg5^Q&*R4+Gr&5y2bU;}7Tk_HG8F
> Ws
> zyfy~iU%}Qr<b&%FE5Dx!EI!NL;qN&Ad4_b!c9x<Ypau^N3~>JQ84}8M{?pg+1I
> APg
> za0b-
> Zz+GJ%nCC#bxukx!goW`$FPa(k>2QvJTDT`JjJRN_JHPM>m@CMYvxVlADeT=c
> z1Yw*qkVymW1(438?-IE9tRj!-BA-
> j(R=Bf|iv~ZC%$_^v=D%LAqs=UD{j|?6eWW9F
> z7n%;cI4knALbEX6wno-
> JR#2St^^1d7Yp9h4WBE2(!0J~NjN==4Ktp=UAI}KosvZn?
> zyGaLHjNi8}+jKpdM58?eTi(Www4CyHuF-
> HN*wWvMOn);JsGm*;0w4Wj`7eT(i6@!~
> z@Hp6q-Fk5>@ZRBQ9-Rs#zJU^X{-CdLDjfol<+?F(nj$y$=}tX`_po;N6}ADu4i})a
> z>oCtO_7&#i9S7T{h?$<Ghg<aS`qkY;fLr0+cOiiL1Z%pf&hP6B<pO+fNB(fh94VrL
> z7rwuDBr5(69Bvo+<Kk|4uV3vI+7~$8;3Cun+>{iP`!sN^Unx?*c@zq2mto}hL2lI8
> zntd<$5q92u7a4?!X|G&O*NHrZ{d?gO)HYC~;W)0R!0_0a1K;QH6FCE0Y98Hs=6
> <`*
> z41J1+L!uNh-
> &}wQS57nLbG5rN+v|&PZx>g1S+HBL>0&oCp1`a;#%1N@;z?)J7ef8>
> z@DY%V$hOWJDdi>GFj2K;EWpGG8P-
> q3{Iod)&r`VAZUH+_q7e^F{pzP~;1>*sJ*{^v
> zs7GY-^T4|Pmapk(-
> U+#&fzh9oe6Sy;uU$kw5k}9HOk%D~zR2iFlF3(HnQ((M35Qrf
> z2D>B8A-G*7GV2g6s4u9h_4dJgJ-
> ur}>Z$0A1z?GaUdK&uuQemPQXpWSg9Si$v}!(V
> zyIibb_Xn<wx!8og<H)iaFK@BL`az=d3P81opNDJy+-ViPOEZ(dwF)Kb2)q*JPOIr%
> z%2fi5roD2cBa3foD^}@G`Qhou_T33pdyZP~r?8+|hi7Z~lRRXgIYiE`eU5Ed0VT#r
> z7&lHrUUFh~I*+%*%P7VO+G19!-
> HVN&g0+7JVtbPZYeRw37Os11v2{y>#7Z?|7@?r~
> zV<(Kt$%OE9o=-
> 5ok%@y<C^*msHF7ro%MAiX2(!RDb%C;|>e2{?PfzzXkO6Af*d;>^
> zh(mHOoF~PyOzgOI)AIMS+Dti6QK{Bkz>nV69Ki#rX>GRz6Ld01U^HqF@bb})(
> G}&O
> zFYzc`H+NhwZ<nE|Qk}k>c@!~kI{)oX%z*qw39Lz_8f}-rSN;PctspBVfH^$N!Ju1l
> zA?;)9OH<AChneumpR;QZ@{mKoft|mAmlR0N^^jchq9A*yUdCY%xGC@iFW
> Smqt%Ac{
> zdVHZDB5bC0GOZj5?55*#ib&Zr;Td3Vf1r_I=z~h!z7#XQuD&I5P;0qxZC5ONU75
> dY
> zsYERZaO?}*Dh=&?u2eg+ND<f_X;u>0sdiE9Etq{2)Ps;*y5WG=R9z^U>dlO3VG
> m4A
> z@NHW!e%++8`v*pzZ3W;P5rmpvV%vsXK-
> ~gu<N>J%M&z1~*W*G!<nyRrt~61uGkwzx
> zJuY+^t(c*a<h?EAX?j6=2QomIyf?WV`J3A;i=xA*u%&5OKI)+tv&QULzsovTulM
> 0-
> z>YXZe@vlVh53S#|Vz!5GP)<iPOg{8-
> $O0izjD8UBsq~nC6>Dv21)2mt0^bRrhOG?d
> zZ1047&htg!1_H4a??j%*Z5Q@(I*Hr&faFjhxxc(Gwbn3Qc`Qnhu3St%g$Tk+;(1
> 7J
> zYbukk=~$Qu<Ro4KiyAs&lLuC`q-U5H)q|=9*mI)S<bo(XF?Exf!C$%|SXTJ-
> y%<L9
> z>R|CNGnvlhal6!U*c<Y9PC4>)CKA2(=g5&zDJvVqXo~do(L2tK*9Eo%i?rtIJglfi
> z;d-c3CZ(Mq+IXRWj}-9Si{_V-^V1q2dC0D2aI{Qfaq)@9nshNFIu9iHK9Hkw-`9YV
> z0wItVqJVURe>GTnq1&N#ac&Oz_pZxqMEg4BIkxF84jO=Wl1R<6tJRy(W9bYp
> bWx6m
> zpd@rr6l|CFVzkSNRh%mmHH?$_Sfis5;i7c-#Ctr3!)|dtX6jlJIsF3dXxO{}e#K?n
> z=r{jTY}@ek-4sNj(!Rp+VlM?VFSJ>1YYyYd1j$0Zg$C!Fp<z0j4XhJp_#!+yEfk0U
> zU{@A$rh_+2KuG9u!uJ%19&9GSu>c&4a_EpKEI{n2But~bODcK}pVG`lStjzVrV
> }ED
> z*UnN-
> >WgtiAO*+NemXGQ2rZn1K6T~;Ev~eZW+dbgrhUbn1~w<o12&SI2rGqV@1H9
> =
> zNg+?FD%i8;>ET2hMW*t>d_Zi_b^SAgd4__%$POU{bUq-
> &XrZM>f)g<+<v5d&tunBN
> zCWJkW68EI&FR7Uo3DH$jp@a;*S~i<%@(9fNb~U@?a5^k%6ilj$q?*YI;6Buirf
> ?WD
> zFRElc(7hE*;s}A*0Z)4#I&}9lr86O}_fKDdpQQyGtRd(LnSE{H{n_<r7`NoD``s>x
> z?tW&GhTk#(JmdPoga2x?)DTR+IJWg<1TVttdl;Uji-
> ax@Pv5x~JQo@j;NnPKN_w_r
> z2WS>!{1IoTO_*(dmZg-;GPJ10wD_W>7k~;FILZoMEW$i1lnM8!zvl;ExC-
> oxc{x)B
> zOA%oHLHI85jtNqjTDiX*jTE?sN&d@F{&z`1vvUHB{TgGt0yjAom}ghuBehtEXv
> g?^
> zgY!m6oW9_-
> be+<}vC=L>&3TY{XG6aO|M0(IxiXCQ74qtr#1Fu*22)?dx9|di{3^O7
> z7`Oh-
> W(0N@KwZcS7csTQN~R05oetC{u>M8NB!YY#IE2RzJ_s6MB6Y(HX1X){5|)nX
> zPUrqF(qD<~C8ZM`O;1PAA#OmX+&pz<TFU&6ewXto-
> HX)mgC@(}qjZ*Jy+sS9a%hxr
> z&#lYm0mUkHkB-CS3kO1fiT;4x#ZEkh^6nQf*~|*u8fO0J1Q-
> fb$zjdS7dKL%;s9Bt
> zE(fXKO2=&~QU{*+PFjUuhe-
> <hK&2Yxr212OstpHaQfL*t$Tp~U5$gwb+TUL+H4Eey
> zXW;lI;59Ly62tslN?7oty+75T8({+C=0+@$(B8slSO`M7ECO2id9<U{kcm8%F3;ee
> zhf|B?ezE-
> U>BS*jcQ27Jy~F9$vV*u=EO8~6+JRjfEClOg%=LzQKE~bkZq!zkqB5*Q
> z#zJYt)Zx=hgXhDtBj3Quo;~N4`fw>6Ez;~4i%d)&F)DB~psc1RG#Mp{=d66J@U#
> aI
> zu{n`fu{ptgT`0DbJSEdqmXFCnq7E?*nhS!<95f#a@}xWNY4C<mKN`H>fe8hx9h
> eot
> z4>>UR1aHxJF9==-L(Kf}sfU6Sb(J0sUZy{Vf*0yfD=^2B+TP=f{8=y&`h`y|V3iD^
> z9tuu#a(^@k)vbXEK`PiVD?nHq%X>&z8ADk^v7xsyy2-
> }q8XF^;&w$9G;3YOjAUo+V
> zxrl87a}jF=2y-|Nl{Fvwj2BM*sEbHh^Y9o0-ry49y`#9+>@p1lt83fb2L{c>_Gifk
> z2k4;00jt1|*T&SrFYsG^XEAKV?fW4j_nhkMySp`VE3UF)i{UymMCi~aC$!iJZE!*>
> zoX`#v!jz>l7MqVZHU3iQI3pV!kUA$c+bQS?C$0e@{%ehFaY8$t&?+ai%L%PVh)
> AYX
> zu(7GgINZc1jq6Lr-D6;AHl*0j-
> ^dnj*ADh(dpq1f&QYKEeo7sif)8v&BFRPV*dpm#
> zBVJyOf`6ut#i*ktk%{h`g~y|j8&JFzlV=rNMwI&^Bgp;|U#TYlOiM?&n47Dis?;bu
> z?hH<##hJ2N4bgGhL!(Limt8t-
> nv=%Jf_Gs;gEI#F6%UFrhTPs7eUUoQ$u8{)lZ#+r
> zO50?|5d%|NgO1Y}NPVi*;sG(3Z!qAmU=U}hpBqP<h`1NAY%yZXFy(|5XDAvk
> m8Rp9
> zO{cv&(kH0XbT|GWt?4x69QEC8uBLO~b<>G^$G5&~nl3xN={|>1(26iJG3_SJM
> cn`2
> z8;wm8RQMz+^vQ|wCf9|^5C1(46%9E@UEoH=f!C;rXV1^rsCd#*`7OpLE5gXck
> Kw_r
> zH8PK7lQ>W#Ne^m`*nKAHvtkT$il_rke9iR5?xyoIdC3Tk2sg2#Ks}VWU2<$Rou
> xHW
> zZt}+UdQRNEPAJt4&+hqFoShkaP=9Y91^QSO$L>OjxTcUlvhKwB-
> dtXf`pk7iSnBFq
> z|5Lp9o)Osasp3@=OoH&~6>Bf{Jrj{Uo^0IRhvNgsebLxGU>dR!e}z(UhG5{!LLz)
> V
> z+<cxDV`Y6$ZuA~Sy1l2fqj5%roA|^U<|i^N;iLfu+6lgfEqK**>kHjmJ1iEb#KHsw
> zGl(6VWhxPAUNg;#F&dNk@agfP5>0SS{sZMhxXg$}n(-C>({3V*fKqG*@;Q-
> }CP7#i
> z0tBwY7ZfBpV(t!Ca<}V(xa%&0(2B4$nc(J{vh=M@;ifJ4;8}Hf8a{<OdckUxJP!o1
> zOJ-
> QeB(c%RL?Hv8WN{CLqbE?~V)0h+vP)2E$T_MMa?swlO2KOuXD({(w@q*BMT
> ss!
> z`QAljaYiOyfSC@io&@$~akAT*5tdXn8mYu*+(8#(Y&6C<E6yiwXhe)0!_sXB<@
> CRy
> zIykG1dd>xeT~CIko-
> u}^vGGz*K3UJ*?NZNAyXyJczopevL(WmNzvrr_1F!4JT+}ze
> zW$M|3a$NQFNj({vcpV&VNq37zW+MX4hv!h=m-kM_hZtXA-
> #)%<rs=iN=^Mrfp5Lz@
> z^Xgm+sahlUIBUkAwhQ6@-
> 1nsPt!nibOc0<8<$Z8Zf(kK_BUo8@tJWEa4WK=jg{h7y
> zngeKj(F>%L8F!zNV$cjEYyY~C%yN<JiLGfQBcLZVM-
> @W2IjrHpYmzY+wcv3>vToKK
> z|4bc@6_Pa=nb=thtmBjj=yu-
> 9bs`R`)Nd&$T5=PO*N_B3@Pf2)oFQCdhbJzsV>m*g
> zWySc6#yCxJPh~iP;lC6S6E`D6BWR-WS-`-G@JSc&I?%+|{N=dqk^vmOycf-
> dqnESr
> zgNt2}BX7=-
> KynstW@W_lyqOgNcw>r7#6es!DiPy!lDs;gZxTV8>qK6iD6xH#gHrhP
> z)xOC0F~hfo`9(0h#ro<9>4;KU&BT59o-RUqzX>F8;W9-
> CXHWx*koVDJ!cF{qE)i0W
> zO50tFVIg~jA>1*FRth)q$*xtbyH>M{Pa4pNTp~n6&QWhcLO6Wlz-
> vBXF6!2A8b0Yl
> zIs9k%WEb@CR)mp>M)sgMu}_H*zC|Oq;&V!b@Xd<zsYQq-
> 1lik>9o~~eIqeDgtr!#T
> zJ)Yg#kjE%iS7*KVMD{xA5{(Uo2k^y#)Xf^*n0E-
> Vi61h7aDdIPuwEA2kU^}WkeNas
> z^A|QszTLZuKsHcq)32p>{nACXkLo#su@-
> 0|AbZzSkT(w19C%GN=Awpt!%(dgwRKT#
> z&H1DnBNNr&_Qb5KF&33L2wDw=EkH0DDL_H77@t*Yn4C&692RaOpLteaYI8
> G2QL?Nh
> z{0D0m`Nh>)((N989>?@V*u-
> XyY%@ICb`|^WVrGMXiM@DrhI+90zoxM`objosJ~D_i
> zO-N(2xQv95W-tW5IG$p0E)6UhszueG8YMN0^D|joQp-
> p`9yiy>;3=czR8YodafXSZ
> z6=x_K&j&TaO?=8IsT=EES7UA6oW|lBa*i4XN#`_{1Fsv)!^Zl=M$=dd<+vK_a6T
> K0
> zk%{k@0FM~4FO%^Qqhy?K(fAGc3>J?x@GZhO%<S=u3Y>-
> l>xK6S>ygDHObD)TZ4j;(
> z7MHBS_IhM!+?XdUZbNFR6kVT_VsUBoYTYAnWx2);8N@b9zo}L?yq(74xgZ-
> @eDM)s
> z@zXA<J*?*lHj5LGEZ&ZO?@-
> Nw*HmLJ>hiA}s+~k_T~zzFk5pr1;!$vS;?q|Oi`zA{
> zHs%S7$Gs>h7U8o}U5P_pB1Fky;U?kD)tI6&z<=athWqm~;}RYeU>G<WD`f-
> 3`3%1~
> z2kRIHn)saT`?74XNBH7<vavyij@V)j9pYI#+_Ojy35m8hS9dR*m(0iDpvMcJJ;dO
> o
> z9=lxPFJw-0-|kJJ5)9+e5@m!>-2im}cg8X?j+-&YQ)iDciA}ClQ$iD+RM+FWuk=(C
> z`qq-
> CSXT0Lc0mh*H%k&sk{`krvO)b(=tm4DP`KCtau*Dc!fw<(*fx@}&736HW1=s$
> z07*<nOC-nHVx`zr8n+>{{5;-AYpT5gst<?WlR!-
> ?&S&_|JEA(!#MhgBU;fKD%3{8N
> z-d&pByGU=LXZ?v%<caIc`WImEJWfTHui<`(qt-|^xf1{Ev9~Bj!BmR#W?-
> 9zm>%GJ
> z0?sc0z^SZfm0PGx1O~QHVVD_N5r(1>4-$r(_>^%|caI<Cq!zk!Hwl~D-
> 9tmpQ9pys
> zaJq*BZ^lh_kL(Smdvu^2{xjp|s$6ytMkXr3xXvnq`yzTC-
> cMSvJ}GGdYCsT4+*#7X
> zK>kf>k?CaMNQ)s!kRdf7_G0l1X|dt3NQ<Ak$T3|{2W)Z>kkaDcAq*UHIPjVr%t
> gHm
> z%QH+rS|i8O$??c=l7o?nJFbAVc%~TAVv>WPBQ1JRP%Oe{rJ5#ZO6+D|h}j^Tu
> PQ+Q
> z6S4R`2v^4<TwzzLwa~e8<6QVB+$3BSgj`vHujGitRY;TKDVRO0%?E6r>PBIM^3-
> @>
> zZ1WVu$PCTLP&D3!gyAMWT|D)oi-<k(G@jCsbJVB*)kQ=H-
> o;ZpV}^)FQI3nJCc+ZL
> ziZC+KJH9_p*~}8&BO?PxAX)B#&06(*i1pBmKJb~I<u|U+krBv-
> )SWciP?#ElM1t5$
> z8H_-(YD5OOq`evBty2G~(s-&9^Z-
> wJHBTLOkt3nUUz?{0NS><xnu{C`ye0>8QCrs=
> za<r$D<6>B-SP@1h-
> ntx(Tsua1%0|#ypCcnsOrfAyoKM(u$ypEb6q|jWJR2iqrdHu4
> z(kK?=do;EO)k_p2Q=4-
> x5^3}qodquRMGgsgMjcQX6$34saTpfHi7*t6bRc24iBA{f
> z^tdSXtR8c1N@>VBY9eHf)B7BF7vn6q45ivoj*D^L9!g3vGV$EF{)}U{y?g4CE{w3
> 5
> z^-l|<ET^wK!f53m(-
> `L%=mEy5YZGDA>mtWabQsr~hJa+8i@)k3hXb$4!CX{eogv4e
> zbaHeIAvqYC*fkc6bKPh?bur@B5k^N*P%OeH)_-
> !k1G96sI__E~4sfy(lh>8mv|BFR
> zQV(09IN8RE@L8!|{xC5>D#|Gg?s{lG&QTUdEpaA>d0SMVbzZ(_GafJ5ceqC<(
> W_?R
> zqlu{%^dJdGM&m3d@tI55&pDh=kfHZ{XGXxmT~N?-FIZf*Mn-
> Geti|Lu&Usce&KOJL
> zqmeeLt*FpK7sV(zKl_}il5~&3*uMyQ*zC`+uz#GPX#9ZW$)}6`Z-FAu-
> Y;m@W2(*m
> z8gh=h3S!Y=e+S;h{wo?ydmlhKF81%rW_vR-
> (Q;XT_W#>*Q`p~@D*r>dnRT|@eC+i!
> z_HO|_QtW@5iyS`%pS#$ffMows5Q`2u9C#P|KlEioj+S(C9M2*-
> 7@7DPq+8<pi-rB|
> z8ai^b83o1Sd{(PR<n)NmshYVsaSN^pH<1x=iM^G#o%}CiGsU--
> ^oMBt5VC;?;xi^p
> zg@dRPfZ4+sOFsLa%EZe^D@Is4<d;D5dHuCSGCF)(GkNkMyWHVhrQ4Y<L|m
> e=b`}$t
> z!ZZg{E5lbY1(DC%E(Ehu!cx;K0Td=*OQaUjnDnRfi~0`%56DRtQUi$x9RdnKVY?4
> 7
> ztcL)GqLJM!wTVwxABegdeUF|4*nL1l&QTK}(ws(j;9Y$n7%`3BjB;Fkpc6*%R)m
> p>
> zW{A6gbUyn3Xb4!=k=6%xfgY(o5Oa~^M|uumlY@Zl0~bbJ<Z$3!ec*Eqh8%m+
> $?@MF
> zl7o?npF&(FCgTVa6g0LlaE5@LC@2=;6Zc&{!@NwZt6#kG0qzp@MSg&0o$@?Y
> ;`zwU
> zZf}OQ%ws4Te*!s#oA_jVH-
> 25lxNo^Cct{W3b_F%$9Caf^n$zA6ysjW~Q4L{J!QCjw
> z)!w~*AE1JaOtg(c1uF_UhI3E|A1{UtTb!)B&=O_!!e}PWpTrnri5@sQ(lvL!04cTp
> zmz6UL>u_^%qp0ajp3j%t0}ICrY_hZf*kQ7#<b}g)`id<V=-
> CuwSW}FlXncoIj89h&
> zX?9WUTY7Z2DW)Oks4Pf5hhh%AtA|v7(NJs`%5hQbAnd%X2qP2Ug+z3CVekn
> x<ljF%
> zq4u6VFns#I(>ld=kN`Z>^^)++3oZ(50{6QH1_H8EWPHg*0S8`FfVrs3dP9Mo=@
> dBd
> z0V%-
> 9#Ae96#KjkIJ3}VJB3`k7%qEnz6sHOvZg?>OoIJ^!jY20><fs`R<OG8N(#RLq
> zYmE=muQ5s==A~n|A&WJi47|qb?O|0j^>n0u-
> +f42t=7M+jSXf0G~6V+sKH`OUhVl4
> zORC>X_-Krna`%sM%-f#B<9Jy?cpq$>VP0Ec&F--
> (d!w;Upj<S*8PCK;NIj5p!3(NL
> zEs!U}$P#VOP&Bdu3Byf%x>$A8(A0$HZ9Nj(tg0dBsCyus99DJUU99?pwWgt-
> Kshc}
> zy{wlF#mK}v5L{;8DmXUKpqXT}tL&xjvK?k~2KkM^8e7b)0jMGYD<Y9+(Z*;tj=c
> Xt
> zU!^4*LX}!wS7nsX)$lC^awC?*a8)c$x>j$^jnSb03pbOivti-bGTNR8*MW$^Yi+){
> z!W8g%DL{t%>a9hR__kDHSPGf_>IXwN+A1by6uQ!+zfL1a94f860%TC7KDfy#-
> K(c0
> zqAt58G}f6M3)@gY>hIKRr_JSu-
> Ok2<_?Jn+2R=uh+On@TvKy&~0TuBd=Xz~GoMuIe
> z3~lp+CX(%G+W%ZBu}lp$q@y>hLpWHxKe8F|rIr{9g`2AyBj3S$Yh(kS=slj~)w&
> =N
> zMrM5>DIw!o8|XFxX73)zs(@NbU&A;=+r8pancDAo%G9t9?S{P@JQME?(jT(H
> e0G0e
> z7?=QYhNAHx5{8@jboGZ#E}nc%kIHs`(2&^wg<Nv_g9GpC58s5XwrH1jpd43!
> @SS3R
> zU}WNT$Sh~v5oMb_rVlR1vx&Ps{rw+K@Uxu^9L31vuaM`Q-
> KWK%2jqCquSAY-c9Ek^
> zkKr~s2uL|Tt<FUb2VRqdxv0i37;<b+Cx@qp<X~i?{d{m^RUX*nItM|g?=M0@u
> {fXA
> z>IrT66pgsr{uFrGEF`HPABbf_10)-aWjsL0W*LSx%P<s;2Y^JliBA{H>~hiQ2|a4t
> zG}4gR|AvHgSjK^OvCM+U42`y+92d(R`zvY0$i&W(|2WG)JMmAmOpenc4$Cb
> 3O&ZHA
> z06oAm^EJ!tc9G*ddI-14K|r$1kTouHIPjVr%th6#H00QvPL3DfB{>+G*ovl3jDe-%
> zKrAyK1;yfgR;!i&#k?R8T`aR7Vo0+L>>_;)pGDWQXPxD~hO1p7XRIjG3Uwa7XP
> X~S
> z%SUe`o;_pi?N0F!!@@%mhN6*sfmOJPPZtlp?IKzL9m+Ld(vWl1VMrB+ha7kp
> 4;8O4
> zMB9{3v`yV48Y2^neEoUoZ>!bV7o1sUza2rNfYY=)_l}^^S~+U9alcOEp?g3N@Q
> ~5R
> zzT+atC-m&X<{<)-
> hxS3LIOK5PH915dJ94=p$HsJWMBgDf7@4?l1bFDT;DzLkP7R$k
> z)jSjgD;Yd1RpC#Cht6vM32B@{y;E|hhJ5Pp<dhy4r!cIg4MVV3L)qabK3$yR1-iBd
> z>NfNv7pG{*IqC-
> xCJt#Fco(PqHDpM$A)Pe;@)weZk%<`)#{cL5C7kk44p0MV?t9>d
> z#5F+81wB%nlItSJwX4&}K|pfKCI}OU91gsTQ{D&~a;#4$#{+*RIT)Fkk_%4RiCI5
> 5
> z#jc?<K+Q%$u{fXAD*0pPmF?@_{_`keL?IQ1zt@KGF2)%nvzq_Z3Df0E4@f%D
> G{4)$
> zH4JO6VF;#5z$4tmr;BSQxX9$y(-
> XTxX~;S1^AH~nnH+c**EBCRWNJ(&)6_1KiIIt1
> z$m9P{xMtt4(zvD^^hj~dRW5Rz(nGIJ4g!*EJ_GULki&s@am`Pc7;-eEljEwlNe)IP
> zJ~$6t^B7t_dHva3b1Mpp#rcFki6?|>(i?xQi$^XK>#nb8uqn@*K`7RM)QMArFi
> Dq-
> zNf_2l!ca6m6$xPskEe@CZgWxPbv**xRMC)g)ZAq*syOg2Ci(W~4OQyWsdB-
> eNEJpV
> z-as+`pD@XH4y7^44WLJgN$4BFmbC49Y_-
> WjKr+d62vUbh9C#O#tY2)%u_~P$*>8~?
> zj7%KGSeK|lTf-
> *sEYVVmf?{z#tJQ`d3X`O_zOj%vQ69WA+(dTpti5d&Y(+WQ@hnA-
> z47_&~cC+{mAI8xfILbya8e4^@v-
> ScD854^lokT<FWNEM`Jat&aPIOJUag}V0S;D%A
> zWt@OoLrT!E#(c)DVVPhH!uPZd$G{2~o#}AF6Q@jNB}o>J#XpYqqP^&);zTd+=
> `&Ky
> zaw5%Zv8W^p!vzIj!#X5`mJy)zf*v87Sp5^CN?rY1aAR|6G_oGADIiG+O#y)_Rn
> Fz0
> zkEWZc6``lC!JZWZSurk;qY~E3@^zA3BWxSEz8BOONPGlydtHGNv*W;Jy55Hq^
> **6&
> zy#rUo!P~-
> 31o6P_ilh*QKxy#GemU!p`!lfuC%EJ#0kQQLqyO2!kw*WtVF@?U=)mKP
> zT!R;9>Kpu&t*L;qFb=`%Mg29J_K5M|K36k_W!PU!TwjgGgtv>1)M<-
> TU#<8i6j>sh
> ze<gA11z?~fG#7PmM{a0zEJpKQ7`uBxd48*`Emn_X)Wz_h_Km4=l!z*aDz#e!*
> ge4u
> z+889W2h6fmeMqMWH|;<MSTMeVsu?o-
> zH$&Rt&swhjsR%G7Kz3t5>vrF8XqrM%QMEO
> zG%o`*u8uNMoZt(sOl;u)3Gx<3A^fST9TJNd;R`H6it$sa9yua)gM}qtEh$8Hl$bo+
> zBskFUo50w*(q})oI!s>SvV^u`{0=>qWUc-Ki$2gR@kzpsb=i4q^g&tHs8ZEyICIEi
> z6&Om|0Y0Ker)AD|s6so8wBfZ<^Af5)8LU<pwNdHmO&uCZT*kpyPEvS+uze~
> =s}AMf
> zgEGSqRh|r!r(n~FP&AS+b>@>pl1DElhhPM?WpJgQf7miuL(Wl8KkAaf4!oAZ%
> td)0
> zHZpicx(u#+gEE+riFwi`%$|Ur)Jt#iMT+pHRm3v60S9bk!6aHYu4uHxE)#o8-
> &d2U
> zk9#4}OxB5?MD<{Th^LrcOQ4BQnEMw>3ckSHf8wpQMw5lo3HVhhfPqU3a**l
> a*SCxC
> z*AD&%f%%Dnd4QP?0`n0AQ+5uRI}Hq#%!B1~xq;zP|G{8h+oo}T=^QXt7P%F
> x^TlWf
> z=;YWM-vc~c`+{FOKo}q)8c2o_1ivs8jpPcy@JW8zf|JcSrgEE$UyAiq#O4<b`5_g3
> z#KkWTyyh3?qK*a(zbs1Um&!koUl^IZGJ!R9U*an`;%v5};sL}P&F+-
> ~$cX!`*ga^$
> zDKDy-IE=v)z3{JHecnv$EX?%0gul-WpXs@2#7vJLe?vyj^ej7nrsrzJmErGV{CV;B
> zQT*M9KllRAF#fzVbKvNkzPi^U&0R<{6TkEE`+59%vd{T1179;!5Lp}66wmbh7t&
> oj
> zYNqFf2{S#bE}H4tgt#M!+lcqIm(KKDa>Y!~UW7jinE%A@EBO1`jVNnG#t0AoO
> a04a
> zFl$7%j>#D@WGHYRF_f>~^M;KWF?>Ysh!J^rOq=QX9R8yC`w{*Q<L_Pk&AA2
> j#-HsV
> zjOV9eKZ=vZ;p62&981p)KL+o6^!s64S>#8DB^L`wHsmk>q8~=z$qlc__N=-
> BR;bp<
> zb$)MSCeGM;aSZ|Z2j`pt1+QoH(}KH(;BFO%t8f_CTdCfHb00`D?b@b~u1WIsRb
> R<G
> zc-=5*^5JR7cDe-
> oShn$4jr)<;6l3QG2UPMa*WqZ5x)mLpXKJvUgZqr=aiFcgzXH@R
> zKUKecyMA!h0XI-
> ci26OyuME0vgC7#P?F^%3e)T#(1bUnHriUXvVl)hYI8tb_`erQ{
> zdg|45)uJ7x*50nrHHjDy%1mx`szZNcI9x;0(yJf5gz&|>qX(BM+WvUppKnut|9q
> X^
> zLGFVLPha1BC+3U(+97I#Ug4U<?Dm)Q)owJ(R)V2Lw(%Dbz^+ew!W)j1-
> _R+aJNsTc
> z;0t_q|K0c?v-8r>P`9A;vkIIrXn{6knqOW1(f;MPv=2fLTvdSbP~ZXm)24sS9hE2b
> z+cEy&ChG@&B=XY`Ol`rQLDYW?Qtm7G9>{(L2awgvc<fn>TlD;GmFf(1q7bH)%
> Ks`y
> zWL~)U)pXF}&+~4+_A2#jp8*}^fNn?!?P9LHn{T3>>)S^qSM|!J^h4Uwn$y6x#l
> O~^
> zV{nmxChObEz_vC#0w;l*8XYE^!I@A?7`OG&bzqB_wD=;EA=ksx8<|6J6#Qv1R
> H+WN
> z>ZwGId>}$cpGD4v6RU8xv!~D3kd)$BFvkTekDniY{?=$koA0T@F^Gok%!sX%5
> O}!x
> z)+~BI$A`Qn{6MEc)9VoO1TVq$hLXOJ?<Iu-
> f8<u&7s|^$+^xYILgDn|b_?$4M^@MN
> z1&*OWy0GkkcNKb_p)F8&HJqJ7SO8@IjN3g)_|iOP(eHh%<|v(S-
> Ol&f*;Pnhit>;g
> zP9&Y==Sy;&yCcm0JCGg@*p9*AZoe=J@l5Q)!=~2dRvxK?j^9$PJ~fFv;)PQVxV
> ;ib
> zx8fMlhRt^<yJWvmHozH2;27G5PHk{W<8Q|alcDdyzy4E%$=}B8O%C+gp#A60
> 05@I2
> z#3{zxfNY2bZf~koUrS|V5LCbak_eef^)uNPhxl%*Ru^-
> w#VfzsA#af%!xbm1;15&6
> z{rcii^|)U4;^x!?Sg+9k2@ts^9g#}bCyS`yZdcO2N@dP6Zb7EmWw(U)WkqXRfU
> F$#
> zxh8ZzJkHCxphJk`ipk$1BzZ7bNb*o~KJ>$2Aml5nt`eMO5dICHE?tFV4LYA`YvE)I
> zdE=a9OS0XLy+vP|=6w0T#JvrCl*P3_zIl@c7B*<mSW%)zt0D@b77b{4Sw&^rO
> >}*!
> z_)h5>dn-
> y7(Sm}Tt=TMFsghf4t(9tTZEIU@rHCzHf)oNx+dyeeEv*5m&bq0_nwCf-
> z`F+1<W}baE2~_Xx{r~fUXP=juIWuR@oH=vOnKO7FQX_T24rTtU(q4B;i%!WcX
> $u_H
> zfjCXz|FW3al2%VGh_a2b<=b>}oR-
> V*)wMWKCvs~pHj6bjQDdHzyC+#ySgl^bb`_9D
> zNWHyVm;j@h2)#1sIC>SLfYYlwo+Wy9;E}fAm+CoS6_ZrLiy7r3JcGaY4B)SaJ+J*
> J
> zb>?$|8pAcYRa9XMKP%V&P*zSY6*~3d0;i&Wu}&MG6qq^(#H$BD3E8i(Qv{(>
> b+ADK
> z0^$+=R?s8SuNdWNNP#pqSyfUonrsn7$3Q716(h(g{dI4U>Zb}L_19gF2e7gE7=
> 8%-
> z^cnw)MGxXO1O~R410J6qz;89)FXH<eBpy*~zAQ9f$m*~W4lzPXs%!FU@>D{`
> +u51R
> z|5b4)jD<*)BY<K-7}=~WU*)MvT@XHv!6#F}vj`43&tOh`I-
> R)yshsbnf@S8*Ddr2A
> zw5x(1#W*RkExLk7EDm5;h^-(Ca#hfyzNHIFbIwD&8ekqj-
> KaHw6g1QLk?=E+Y+?_T
> z+_eO8b-
> JLOWg_HcBJ?5?(QGP_o*3a$xP3Qj+(pGia(W3ixB(mIX<#|Y5Y0#j+0sbM
> ztMRDeI$3h`Zgh9W=nh<$TqRf?Q!#??7ULv5lscxOh~FM0&HNVNr3c4UNVW$
> {Z3f9c
> zOoHvEe~46>%iNh!6#L!gGU?(hjok=<0s?GL10?t*g_D}NoeTL2@7gtm3B3h7B!
> yQq
> zz=D=Lw=3Y1a<i-W=qC`csG_KyO&F@f|DKd#VWk;x$=-
> ?)`&qjAB9Uz=W$N*C?R92!
> zB2pck@Pfb*gy7QvWa<4yvtlj1m6*>c<3I7zT-
> 5%+2Ozdn@mTbQAs){YFReg&zGEo7
> zl4N1y{I4*uX%}R41S~8`P2nRB9Wo(l5s$JsmcH!H?f-#n1&GZmCtW-
> d+gDJqnej{V
> z&5M@>RNpvcEG`;{v`@S&fcgp$mulksPrL-!0LxPx!rc|&F%KP|42&7an02LCc-
> *yp
> z2+A&KL3AW8D8`KAVGpHuH4P~U^b{Z(7h)!r7DeZxF3a}nc3u(N-
> a8Fp9Y1<IYo(o?
> zww;yIPRQ#x0iyFk9GlY<OAjIZ+p#2AwogO3GPa|4I?(sgp=fL>3q@m7Nu)ZUv
> Zo+e
> zCJ~^#dC~I`0xuyHnhcc7q;`f}&%U#X1XB>0@C?ZVZBC3J?@MnWDKZb~@UV
> GEIAFDZ
> zK^JINdp=pMh@*&Nr=Ac!6j<%8zZO=D091GG5_qGTGa=Xe%U1KD$TR2kqG
> x!ABW`h}
> zrcQ1$<Cab3YkprmHYs_Qz0D_`f3>7;%6mp?$_9{K-
> *R(yrKA@CLeFPh>qH#I(otn&
> z4mn}p6~u0Eicdv0peZ;lCVngDC>v^MiJax~-khvn!laBmD>6PZs~Oiz4t*rkuYlc}
> za*2Y60gLmsVW`Anj(~NTnqUXd8^;+eO9{_|DDnodFBdS<Oi+v5fOSd@n3>g%
> >s)}Z
> z0bs605mCAek>xQK7&r5w6M3vgmuJCfb+%KMuIZ`BfFwg6Dp@>q8G_B;UHL
> dqZfQr~
> zN))hm{GvpNC3|ovFKawg*Z5Lf<ImobgDRw%ptj!VLX}RbYs}25)Lr9mgZ+b;m
> QLCW
> z-9R^{3k0G2Jk`HVm+4c*V(PLdOoHl=@>M}ig9vjih(CG4X0(z)DRFp-
> $}<e3rTGIe
> z40*9h7{(!{?bHlolQ4`!shN52N|{x89+bI0G_XuT+Y*DeC?GCtHdT!60;lbgvtkHE
> zM?M{dXLP!FBNq0Z{di*(QT@A?ZC;8hFqCE+IidvEG)L5ADj6|wAd~o4#kyldON
> 7B$
> zCBz=VSoC@^KoJEnF>MScL(FV0RQ&KWgP{Up<UkX><Y$a{)=NHTBgKKOnW(
> a;FGJ)7
> zRkCD7Mb(%k`I-H?BLqbXpA%JxwaZE|bYkV0afJ<14Jc83wvGtWog7xBK8I-
> ^F>WnS
> zCvyvNwM>DZF^d@pT2&&E6aZBS+Tmq8m;hb+mroCD2Zq@cCvTz6TPS%8!5
> 5#%(iPrO
> zwW79FmXZD^H934m_=#8j1#^v!ugp2MjKiEUJXP|aTvCC}=%B3p=#B!8{8c=ch
> R04c
> z*%C0Q+Jz02M<(zlUln1Py7&*G`HffifWuf@CYTFTMoM^LX7$R|SvG(@SYhw#
> PB6p-
> zBL3&F#KXX^Cs<F-cnd#{0o)({dl<G3e4R4#1;S@$HDdt$u8#p<Y4{gf_(g-jzsC(<
> zr;M}`J~OLVs{6NJ9R_}^vqS>$f+ZGv?i<Z}#!5uwUJ!W~`<q0rqbUY3CM9Ss7~hI
> N
> z2#zkbb-
> eAf{c$uw{pwm5j&#aME%HfbHP%(f^c1jIT@R2y;sv{?LP!S?XK9EtEyQ<k
> z$bpDsKPIRf-4Jz34Uw7E55X?ckDAxhaE7y-
> 5TO{?JhoOsMYFX=?CvxZ24EL!*Z~WB
> zK`v~Zv^ZY99(J`>r_`{SSxt1o&Qxj9Z_#or3Dl6IS*t=(@Ol}D8$G~*ayG@<d>ogx
> zaLD>o*bfK@O@UEzLF&T@L;R347mCtClQrmhJqg_^ZTU>Xb3c<1+|Mk|K3{k
> 3)sy;?
> zGs{bcH!Uf-
> Jb6ty{A>@r7Hjt;@GgNzd>doGm1e(<!MD=kP0`Zi?DA6P#|dKZCEIaV
> zjNjj8rs1Ant|>3!yPcVxf7to<&i3JdjCSLD*MYg^W0EcSQhMOcf}Qt{tU$W^y!Q
> ^N
> zK-
> z_QpPsZUx%D&AAqQSN&>nlubK}joY_{j+Tz#EXx7b$6m#tDUs^nvl_;w5dXFr
> wV
> z6IuvIfZ4h}Qrns3KGbFNq+Or6|I?YPrNSk|0Lt+7t8fb{T>4d9N=$8wQQMKIt#6
> @s
> z99n+@uz_D6ev3bIzpeN!H#+sUYFYG8tP|_H9*#3GP0S50aZCqa#?g9K9Gmr;u
> )}|V
> z$YWV?4Dp&LsN2DC9Cq}n2vbHT@WRY$EhYfu(1d?3Wek@%_DR)W9J9y&7;)
> @kDGq#i
> zNiJZK1JfAA4q%;90~T?t!VP#G#<&s3L=amtTK&Mut?Tx<B<X(QrKMxPJOry3M
> 4JwG
> z-
> MNcTkP8?m7z>!LR7vVGAPh1B4nCnEviL^3eCooSwk*we`dAeCIu(V8#tVz3?(y
> <5
> zz%x@k@qKxVaV`dqenoPC>V{B_cNq6n81bYC%v>@<cO|MIwy<K59S(fJ>3c
> ek!sx_0
> z_0H`^o*1`N7{=i8fpAcknhlxFc^@VC8Y*UK`2e-Vkpo-
> {B7S^VVpg#T5ol6xvU<$8
> zl4W?G2+@3#%(E5A5ex7YYj0GN^S-Gh^k}H0_s;DiEQGtIl9Ff&P-
> qfCy@^DH&`bjd
> z<8~5GF`B(?S{c%S7u!iw=+&$KJ`@&BGZXmLTM!txdEjw~gqh1B^u!j;^h8gKti_
> wi
> z93k17a&_{zNo6RtH!*D{S{{2~rbpu1Cuhy%DsZ^^mQxN;@9?u&r&q<Hs<-
> fR<%^%=
> zV5}p^7gt}aIe;)GVLc9G;$SCZYDvxk6R_hvz4MR4n6`s4y)TTZR2Wl<!<abK$(Ve
> G
> zG2QGQ)xZx%@iQx+>VfhhF=8ceV3-
> =ciZ}T3Bz`Tk1rtDe=nG4Ous_UyVVY;|YN9(7
> zJAysNDEr0cf|;VQ7IU?)0B$n3VN^qq%IDz$-qE$k;(BatF|J3|;*1Ed-ygpgV+$&t
> z^^ePR<ES){1!Z_gN2kW7K8@;m5HC9~GGPva!;L<>igpZ~nzXHmpHP4&gV^w
> 17!s0Q
> z>LiHAi3vE`i|>VdwI+kDv2;F8M}-cz#Q(_8_#xctU-
> xkDjSMyySNKVeAbzUU%lYg(
> zsyWdFxZu#PsjkeEmx98~gR6<akZSCok`rH<Ny#LcYm$QEYE{!eDMMcV9mXC
> &dWOA#
> zqYXx|7pl~y{gV>@4wIBgfFieH&!aXzCa8mMe~+iODE$svm)?sD(C4LD#amcA9
> M|Fa
> z22UA}`qfdS+jcRS6s2D#G6L<(7R_1F0L|(Zk<S8ekyaTXIFJj|a+Uh$Q+kwy+Y{60
> zAaQKb98c|u=4*uclHvB`^f@7wrx($%ha&8Bd$MW{b&DbOSy4A&BI%GNb$(
> _x5B93U
> z);x{n3wZk1tU?^g6Fm!N9kAoXbT5*`nsH8OhjV@pKo^AOTomrOmloGw;+(GZ
> Gps%j
> zR&K$Ogu<s<VB;vh50-
> @%geV$Af+<gx;D^W7EYgP^bHl0#kX!JJ)^CAAKenWeE)dJv
> za8KkJB4LprL7fN=;F{Qw>>QPtot<B@i6ar@kRnw3<vJ697Vrq80cw2s9Yk-
> K;n{)z
> zf5-
> o)@&BaH&Je!?Iv2>F_An^OL)vRWqBr6{s6EgA;m$)NzaFoX2aMOw!`M$T+^$&
> B
> zZ@8iD7&5{lwCU%?K1m_!{tk>{Pi8C<Xx6bOi9<d9)13hOhCy%pJsjKn^J<5w2)
> @GX
> zk;ofBt|K*QkSk_t@=Zwh%p&GI(8HEOQG^b_SoTab-QMd5w72ar?S-
> m@{k$#E!5?7>
> zv{4C5ph*=h;T3*>g=*cyCASJo=)GkIGPG%)*_IpyN+scQ>TOSt0N(LYkP+<vk*
> gDY
> z6y7@EBel}_$Z?z;@R1=!)wu;6oqC+e0aL#RFc~doER7^f-
> GZ~cF`U|LA!&NdfxMfz
> zVrW7RA@3&qB5xB$2MvE&@}{cZlJ_OS9P&o8iR$}TxX9Z{9BFsR`-
> 7R5ywex5eu4cV
> z71zh-
> 3Fq9OC+C!W0^g*chv0mNUo;~RjJ&nOK!7b0^T3`oD69&HB!Wqi>la4PmKNWN
> zGe*G~wpHHBhA>eS$4`K9%uR%0Zp4SV%k76L`p`5SDND=mZV{|@ua<MvisT
> %%z;2wQ
> z7Tk@K!N_5z;~X{a>Hwm4W`?Pkz*B+Ce&i}PX{qiFy1F1*)B$q>3YZ(>X=b2TZ)
> O-c
> zP?g*lGC{4oC9v0mpY2IZzg6-=71M#aCs8#Q^2-3GknF3!X@;j4|2O0R>-
> hg2{J;2S
> zjC;5(<<oTu|LC`bzruVYuwy*XzX!4iWwNTme{~?*9~_2i4n#YeIw8$|A<*{fGxV
> %<
> zCH!SI$vLFH{ZC;EE?I$90DLu>^Ip?j`NHQj<oQ<n9P6BE4%<|pMj4P_&1lSZ6oB=
> J
> zU1Ftxsm}r`?A5(^7uo&C%P{v(z}#=SHO)L1U^GNp@Ck-lI1?;}3}Dru{Cq4vgAG-
> w
> z`VXY$&#=VEdZvfLRi_WByUfSu`0?4C!b0lP=Hv7D2=&YLkxC?pl=3n^Nk<SIYO~
> `N
> zDLte{iSfS_XT|4ZD(%I1$-+UsKnNlAVUMoLS`-
> +Y$}1+*$bO~`w&5@twjrcmHL2F%
> zdvY|dI3c3;3#*yFBG6NNdvXL{R;iH(rMN_(H949et5vVAaUy_G51aL5j{Vy6`apF
> Q
> zYQUt&ibIAk1ydWMe8D}XFWdqb3<%}ju?~z}<Jcjl?b(<O>xuttvkRYQv!O?OM
> h*mr
> z72y->C?KHOy@mI}6jzLm$euE+go-
> mbBdQp?pbF6|#hDwEBZ%UPU=QNJjOJ~%`i!kC
> zIkBhqsJ<{}V_|=_XRjvC+1OK(BY0b-
> PPVC=VoRF9N%W)vC0)mA_H0ObY=RB3B^!7~
> zR<Ia~NOK-
> _umhuXLx1un{o3<I<QVN!Fj75B#sD?_&%{0th`=z*e4++@)$c%UY|iI5
> z4khc@mK~q5&I!~V(XfEZ+9foPum?%$Q|+;meZdF~kZtoItI863EI6&RlGQ0Aog
> _YH
> zR`*=W&NoYFPXS#%o#W&8Lqnv`xUSKs+5<vWE(BRCZ=B(Rpi^oHa=NwO4dE
> #cr?79{
> zHqJpyiu-D>T83+1-
> $S+2@tC)8iZ%mYROH3sq6>zDCF9qy<YJM|cEe?5XNNuE+6PB%
> z`1grRl$>x~3IuHi?{*r|fkx;Pu50wk_GrZN%cRl9CzUpu394s08*vKy00`A7btB|#
> z>nktOXyW(uA7oN0k+ZE!<ZSCUypajB4Zj?*_H65u%-
> PoFWP89a&V?<Ol*Iy@{SVkR
> za+bJ;EvH)ldaA377_h=BR^T^@!{nBfdO+UcUf^^*m>5pA!x>&+<i^B+b=rZ~<
> e=eR
> zF|~NHRE(C0Wy9PCys(1|T?k6YdH2_`B&x+tIXsRNuP5|-?G#T+UkKHF4-
> kIuYO#VA
> z-}^<Z<>&F(GyPtlnC?2S`YULuJu%%A$mt6?ulftqvVEc5?8-
> o^8YOaG_0OkdyCW0S
> zjR!PTTIt63&P$G(Cn^VEqEjAVmB3A~YaY)i?2WyRNURuZor11TB*KBp_ih!Pz~
> &Oi
> z^HmQ(j&B**(5Yfz(@bJJoHGjnhXxGi%dv(x0~z@--
> uv@{(~&?=gu49FVbS9_!XFw%
> zi<H;1;4pAXv-}8#_h7LCd-UY643rn^oSXm|262QDxv-
> 0CoGb$$Oc@6TJH7A#hOldi
> z0>&{(y@`Qq8Amp8q}Smc7gV?i^Af{5%<1I&AuDR$5xLX_=jdEGU>}pzgKjuZV
> hu+)
> z$geJT!TG&#klluZv<U~n)>O?w+Ju9&!D82+gS1kpYZDFv!LK#TL3RrVIVcW8!a+(
> L
> z4q}?pfu?8<5^;{b$3VUugVu#IFp){>1+WRrM6!u>Q-
> qJ?o2CdK8IGoa>j@tz7CxeV
> z{4jlrV=5M;mXDll_(=BHd(_|;7$&Y7fR#*A6Qu^4m1Gm^8VEO8dXWp633QFa
> O?C@6
> zf#qPl9#DtnCJ+^2%7hmiR6umQ?#0Q*n6oD}g{rB$2gj*aH$2P93|8CXN!zPJb^
> =w?
> z|H{P)mhF&m{}(*R=ebXYh~YeK_bwIA(?-
> q%(m<<(^Oz2Fah`cDTKsZl4*G=i{0)r7
> z=|Cs3MxSt=X_Gbj*n$5CoJU&#48JG^Q_<+8hYbdLx#1WxzR#zXCwdGyMHD
> BI!n#6v
> zmB%{p70o|B&qA<}{b;hxP5bc+F0>!rLc=%b#XTZElt#|rO}?ttQ?;EJk!FJGz#z9=
> zphl;R6eGE0R_A@nMNNKzjqy{r9gt{j^T$Oy6!x0o>XYH>v%}RV!<FYC^dGJr9Ii
> eY
> zt{qsXWrr(#;xXZ0C3~G@xB^Hc4wTjBEuu*qrAa5)Cau;Jw{21vn>51RB%RVU37
> OR`
> z7rL4>1zb(EL%paDj;*Cf;X<60+3SDN3s+|N7~$wqJ(Ki^pFmG$57YSLzaz4PXgJW
> 1
> zuIQ`1av84VQ`7L6x3EID@1oHn=?q&ff=*x$+HJNm?1B67&VAL952e?zT!+f!>fe
> Y>
> z<E5p|aCzQdJ3?!t2Jz$Q#Np!X;R#3xnc_@~j>ohtVbOs!6VxGa1gD2}N{tR?R-
> p@A
> z=-
> @s@kX>K&Vl*6MdtTB@VF9PKz6d{N9FhthDKLd2c7c;(tO!QX+(7?{o?7VJ(#y~
> m
> zbx9M0;niYWNC^b_drykY*L`-
> rt>j<z>~1Sr;#qhJFpdFW=W$}+g?SvoidnxH2*LUs
> z?pH8+^zh8x5}}`x3?zAs6f904BMD)$f2d`Vra<nYC4JtunO7ddA?zW%PY2LxQ1h
> 7N
> zgHf$?(nTVkLQIuTgfB0854@4>-3>;xb8nUIJ$O29&aYODzmnct&-
> M~Ghy;l7If(3N
> z#ryL$VrE&y?A8;mMGR)?@v0IG$#Se3ol^H6GpolYx!BdcLWeb$4sS!l$BCF&5%
> ev%
> z8uU0$P8>%Q#%=CDAX_s~TDTK%xfpECHj&?evefJl#^(=OrKQ%wBK+#?LHX4
> l46s~&
> zMMqTOSF)0)Q^-
> Jm<@uBFt1WsqwfGQzH31ySq2|&EQ${)+e)aHqE^5A2V1qPnmHrpn
> z9;~mWOZy{af0jc*vA4fJhx*<x4F=K&^(_B?#tSbskZ@Y_;Jk3GAOY;XQBVCAU
> BV0V
> z!0jA#>68XtB%iA%y3jQd4awz&U<5dL;3JJpc!k=L2}Y1vq9$)JTp(P6(+{&;V4SV(
> zTY9F|wWVGvjPZ}Xyx1>>@jnW1?Mes7K!fiT!xa^}GCAHHiVkp|5*djl;5<!+0|d
> bV
> zgddXwyqo0!*onr`J~QNS0PI`%_p|Sn+co<Z2JlhXw_yO6Se*P;Pq(%Q!M?|<O
> V4*P
> z0G(3zpfG^1o_iz)U`I5101N=*UW~)!3oQeA8&K{}fVBnGq}dsY-
> #{LzYo>wKeZR%c
> z0Ia<7@x+p&BW;|$^3|X8jBHyi!~6;`HivF?%E%Wu)+y7dZ=B<z+Z$z=|KABCn`F
> 1t
> z5rmOrY(q+N8zKX6DL9hT5S`LAgadHbcvnMs3Qz6;{Qp%L*(!UPd>>mFDYNJ((x
> Qd!
> zR}n_;0mpIBp;Kyfh%oYs?6Wf3su+jp|3nPY0vb)3A74P@6mJByT=Lff+E0El*a+`
> 8
> z#dAMgzbXDKi<9^Cgl%ymQ~XU6Tq9hk)Hsn5{^N1~rV-
> 95zTXIMg{9#zBfMpcdxRTB
> zrCVQl#>bu3kB+p1<T2j=swZiS0~zl(fR8zJp;JbdI^+EZXSs&S_5a%m_g_ryzkWrx
> z{IC=5F}5M)xebx=z5=YtX^2i~8p83u?@U)i9@TS@h}2ws{EwzuP3*Fn<=?&x+p
> <|O
> z@iUpvc0r&O>!J8f(BDwJIcUR$^RQlynEC7^i=YB6U)Y|O`Rs16JV&6_DK&zG+M
> CaC
> zQTsh2(B5eU+FKp+tqAxQP#2-aTMDi_`z^HELF_r-
> 6L3HXv}eUQ=7m_8nt3JGU4LxO
> zA$G3M4@DLYupf6E#(wPb`rJ)z92RD^)v_>~9C;2z44VHy&(jtYNOO+*9JrlBDm
> rCk
> zC25|S)r+4LOu#oF{d=&oNgzjB2e1~_t_UZYb8%}fvM?HRVYGRo<5Zp-
> hEAzr$Z@z=
> zJ1{cQ6!u>P_X8yf+9Nwc>dpN`inYMPELo+Fxr%ivgo&F*A?iGR&|%=iSy#%&M
> Ov`1
> z=@y6%smtL30o!Mec^^_D5}%034JZY>0rw2FaFWFU|5XUZC2H<o=$ndBA^~
> B;=_n}3
> z>5r9TLHVDhFE-_)8OHvj-k38;=|`;3-
> obL{`V3P33xlPW@<DH_2GHA{!_b>Cjk?GV
> zN(rb39kRPH^5ma|>>k$gg(W+rIY+$%9^{anP8nH_<eKa%PjkplLZdAyE<|t{I#x
> sD
> zR9q=5T9Bi*hJb+qd9a4Gi?h&4ky3(%i@t@Qp9>#4xO3DO-
> SBlv4WF4+Q@I0wHHsI=
> z&;=G(MwdXy&%gKRWzbJR&B6^Xt%OfbB-
> {P5T!qYP#$OwUou{VKR^)yySy)8K`1=cZ
> zje`iCQdfkT)u*x*DJ7%Ea--
> u=0&&9WOoVZQJ^Nes=8O>fIP8=qD|Y2#uk{789>d;*
> z{mJRR)85|<dqHr2Vj8p&#j$;bIK3^fpCKu>GezP`EK&Bynn3i}VqStN&Xc*FBR+
> a%
> z&7w$?FcF#{)QbBF6SM^lE54Q{M;ESxnHU?R<p!hy?DS=>)P*nG?uF7$m!E+Zp
> 8#<h
> z9QTe`m?$+d3kxf(a<x+x+U83@RM@|bdo#q?p7kfg2u90p)D6c7?ig$YgZ`IwPJ
> mc$
> z&$kbB8H@eurEuGZ2^l^U!_-
> f|B>rt`<Li!}B;FsZrtXpV$q|xxZ@#~dY8@QffoL!|
> z2ZYx~tUvk^--L|Pm-s34O?`=tSa0^tTiyt-VEm-^$j>*|%TIi*{CsDP{QU5F{5<(+
> zyaPYm;$^tPWeWJfshY4e_N4-
> dlLOX=h(Lu1$dPEoR_wkS?6OV8+n}EfsUQ8EJ%G45
> ze1u<9WinWpNbSKxs*$f?dqd<YWP(<#1|A95!(5-
> jc9*`<*WeC*E`NGT_O&2h&EwGb
> z<+3u7u*g3IQ^KKq2X>yy<+1nFuy6Q|gkXiDLY4(GJr=l{pSjo0STg5lGDtiw;N3|
> @
> zoz8^xvCd-
> CC6ZAz#*3lC>CS(U=E8#7V>2fuN6Z3giFo2ojOKmj{?+md7Vf*Xc1!yQ
> zV+c~;1|(unl_*ici}q_?Fg4P~n|$>TJ+<2*h>Z{9)a~Fl&JffoBWsXcGOM*^mKW
> q~
> zzv29VT0gVqA>);b=he=Go<Ej#&T`XV@3q$f@r4)}n0Qcw+T-
> x}cZtqYh+VLsk4<I%
> zyy(s9R!~l|a`tIHjQQwsU?GKYM!E_wV@;JIReg{p6uX@UB6T2Xb*4>GDYohoR
> cc?n
> zEUTcx^vT%v46EGRKvU$&PBd{jFJ-)Vc^QK-pGuJetJLrS!N3J{-
> %8RNH%&1lhb!Nj
> z47@=`ujNh*oiomyA$89jlk+(zCws<~GlZOxN?zO$FS7aO>wH_|9B0@X3N)k|T
> R_&B
> z?)yeB2L%IPlTo4W++y3_Mv3iD;Znpbab^jr=`&4rj@QMeQhbj?c~H11R&9EnZ
> Nx^B
> z;jx}63-
> 7X7zpG#43?8PvChs?9Bzhv^?UO}e2#{+ERzDA1Al_iM<Z(OJvnu17&D$zf
> z{#{Hc46l%U+@h7Sid@L?psb{f_*}Gp;zrYsDkmp+hCAnTY2+NS29>DNh!tj1tvV
> 1P
> zPP+0qCnsy=f*C^2$V^_OLrh0LXY;-OnA8>0Y?XTa&jwXqpvwQ{bA-41G-
> 43>AE-Sa
> z?V+%wB04FK!@%2Z@g`gWma)}Ryyw;dxj{%nJdSJROB{d%T>Cfqien$lsl^e+g
> MT`=
> zwm2#2D<r{!{LBv!(h>P5?Rp7=&I1?qMm~;fLlivz3iOILe~iT6FKLB*^ndv`_ynq=
> zL!b*c?TY=u!eVb1=t?5A9%~uOA>X&J7Qro~{`;%8XC;bCmP(egq|qdj+@7tx!S
> v64
> zPR=p8btq#_p{s(FG)M53+sg;9H>FI}rKG<~UCu{B%9sB{q)3@N)4ET9hw|Jyd{j
> K_
> zt2TJ}-U^F{({f8X93Cdy7ToRRJUut(N5RA2t}}QzQ<sva1scs6pIg*(Zvmx)V+Z{_
> zXb*dB%YO5yZ5e|bxoG8ZExXy)snN-
> KZf?#q+||LhWl%8Y%8+IR1+Gz$OFB{PsS$QE
> z#VL3~ZoyKe5hS`?a{1-
> 822J@+&WX7>pMEo!=q$E2$pHIDvdg}BS?YUWTvzO!{Bgg|
> z1vA%z`NmfSXPHl-D?XJAXchs1VdM;_aW>=aIwP`Ol$%Z1-
> DtAAT%5cYHZ42D$tiv)
> z*@4*g7jQboi+lcg$>!@y+3pork!-
> $7WT_dJGHf*=0ksNWVj1IFs_g4~_3Kn!kxYl2
> zr`07g!ol?$ouVsq8*{kHwA@zeMki+=H)qFwv}4UT`!%NX8iRyWbv|3W-
> 69(lqVu@t
> zVXJ;hEk9}vNN(8&Y>NNO466ckhjZcFx(_m>Y5G@mzM>b9(zYMcVQxSC;nRjT
> pI&b9
> z$&EDqhsz+ed9JPeJe^aB=7!w7#i$P3kkf_#xZ1ROyaV#a+-
> !%#^9Gyq{iLnzZMiu+
> zI)LK&yts*`&gT2MlkfK2e5J@Tn3!~>&AH6U`T5+O*S`*6rM$Qy9&Phoq4PzKF3
> a;o
> zB0I9ZQ}!ff3|}I?g_G7sUJIh5u&Vj|Z-|~k%Kwi+td%c?(Sp`YvA!=t;KCx+{I|Y7
> z1i%RPVs#LOB2ol)k=N%ti>W<EayLS^=waa@Qmj2ho`+E2awWCOBHv#zeCSH
> r4Pg_~
> zc;rMaTN_tWD2vWfyN`EC<2q%em9i-
> _tJ6nYX*@j(Fn$JM`XO<{luZw<koecIXb+r8
> z4UEEE7_Edc-wi{j)G(M?Z7y+O><6cVjlVh-
> >`*syHi6fRzwR8o<(nHY&n7*wMes(6
> zKaPO_j8z1S7tF`n6}}2nDb_uBiYgFbXW;=ZSEw)6bRFs)6o$<|=@<b75&scuD<1
> +q
> zGEk)~o_u0>^dX)LW9%e?TbOIT<l2%BO10n>f*p^&nR=|P5`iWr_?jeWN}r7c>
> 4z!I
> z<K<8I(i?l}c~k*0c%H)#J8I!ER;i_mksN9=_&1~w`-r+IYP%SRK>H<Q-HCE)SdIrS
> z_*g|U9v+r@@TK<DPGUrmC>*-
> H1#r^XG#!o?Q5Z0K#YqC~>P>_<F#kc!Gs(b)^rNVk
> z`s;D*W{s8g7Ax(NVtx8QkRtsG#zG1~JWw5}h8HpUI7#Tr{E0~!%E(05vy~Yul|jH
> B
> zxM{*gVl4qLlVaD3pS^q@uJ_@^dLF1fMcv`5$r@XePfM0HX$I}m-
> Rh4~BugP&gs#9G
> zrtl=|iPfr9csD|DWoviofZEC8mitD!;7P0AJvQ6==Pk_FFk2-9&!_JO96C?YL$kYR
> z;VG)wmHIiG`guwHT$=8JXl+5Do7>$ru{_IGCndqNX)p)te+TW0cwcBezYG}|)_
> W>~
> z-
> AfSRhusHPnugg$yX)a^qk9u4pc)E%nuT5{g+87BC0d>N320WlaD3@@EMtWXp
> Jb|H
> zN%ds<J4lsYg$rMf<4bSs{u1a2krDd^-
> xX$*2(04gJ(#AFfmNB>OpWe!3}O#@97_(3
> z@C*|aClS{pm;5wN$Et6DHCT#TX|eQWDRm|E2!<Y45Y~KoyCUP|!ySAG?g6h
> $Y{H$@
> zXb8W9KMw{XU5iBH24c3R|Iuiz_RoS7knzvTbkGn2cYgCJ3jYA3^=QhY_Q2<qF8
> bC1
> z-ny&w%HHlrp>A7;D&W+r9&mk?{ISk*!-c7aBXJE3L(vKBi+WNAX29-
> b<LPp8WWI3Y
> z$oZfT%Pe2TSa5lJcGKH)2H2rhk7N@^u0d`oLOte}OnMjkF&Mg1n=twq!6;CtzS
> =9S
> z1AZkQ^A=t_xC6eTw~KbbS8&O3x!>nisg2KZR))S2_I)Jt(z&06UrMUSE=<}DGDj
> uD
> zrLqTZ3|QBGDD4@a7wgbUL}nI!CDlTG(RotAYd~5E+$j~DWh;28RPZ8QkACJH`
> U^6^
> z7+k+PXkjp3b0m<EI#Jh8jXnl?HBXwF8+xN~b3A~;Xi`U4BhU|KEB}{i7lu<kqMZI
> *
> zTH)Ku=fN-
> ~0Q>t%(1TB6o6**RjYGx*41+PRT0Q<<!4wi)6zDl&JC1<}cEP*&4Bguz
> z)0wF;Z6;GQ{ep>4P~oH5+ozybRsdvT-
> P<feJv&18Hj`w|02J9K)k~K)AQX|&wodCq
> zThL8#pTqd+Ng#@nTTv+5MQv|j|DmV)?NK=eD{JVRwA;E#ZRmXp_5=YQ13l1
> %y4mX5
> zPd0X_$it{cr0gA$E{5ec59;=bYT+msF*}JPy(DI_M*YI)O#UyR578;c&6VL%Ma3_
> =
> zetbgZu~$ipHi%086N(*?xC?%Rkt4Fw%|!K&Vi$ZTv4+ngR3Hm~5@{&hvu(O>x
> <CUD
> z@+D>gt1!~~68V~BFI@=d=$>uUs8)Ok8=1nzJNFUkA*lbyU<8z61TYkI4>lEfWe
> i}_
> zhRz;6)0^Ijayf<jmqRH<Sm3Ty&<1-F(_j$ji9LYO+NYp632{4V*Rp+-
> X%gWUc?IG|
> z8U(F|p1uduvU=hz;tpa&3pR80)n1EoFhRpX(pIP^hJ)!*AOPiq;wNplak{t2D-0xp
> z&Z8S(52jf)%NEFOSADfbsB@+aBnL#mk!l(osgRJBTry-
> m%>#NDv*zHIe<O&a5g_#b
> zsz}q;nI82cO=CuC;BJc^P8r}J6t;k16Gg!xKk9oCPhl{E)g{h3Y>5<r29_x0m4SZ~
> zE@fpp)?wR~)?DLQgtbCY+{J4N`XY=?7k7s8dZPNyNEbmli6gBT0#bzP9_kSE+d|
> N8
> z2Pv5pBy11*70B$AC>&t>I1-
> wJ$P*dqg8vc*j|)DMO;o43;X8>nd={Z<v+!$3&_Ql3
> z(Q(t!jkw36vFwlNk`uUA*-~n|<OT?!AJ;dQGl)1+!uJL7yt0m?+Bf!oiKBrzr1wxX
> zs{IK1Ij+MrhKME<XTeck5CqWfW;<X#Mz0G2NOq1Y2S0QerjuABfJLYUUfThgF
> L1Ce
> zz5@fWul6SEQE&~Y8kA3Wf-5Mca8wQSCFsC`*x8TTJf3wVpk+pT5j3tg+`m7|1-
> +3I
> z<PHY4P^h*9yjJM(Y(tM`zXr*Yd=_LW@++`n$Wk;hhR=Rm&;Qn@B4ok%$Bxk
> 8B#v}C
> zWO>sNi<R^zx%vS457=igQa-rpwV&TEf~y&)e1~53-X79!z8acaF?82N6-
> 78@r(#ZG
> zT`{58Ek`*O`$|6P)rU2m|H~UOKGbAnP8Q2(ri9^8G9>_d253UA7HPu}@*#hG
> DY8nJ
> z-
> )y@avJu?Zv47CF05(#%mUG!R&>a#X%3WWz!8hwE1ukeDAy<D(`dmFR3{{_e
> N_3cd
> z6nA8$vNxaJsF^#|m-udA<+V?PuK6l3K|KUPf-
> ?TZTU7=O_L~;>MaQV~9Uy19fl%im
> zQ%Q;*IUvV>^KOid65T_OT@xT<4?v1&t9^j5eH}aP=mX@8UA?(R6GN|=Sj}v
> VWD`{c
> zyvZ56PGU_AGIn1qbckUYdl7*$77yr3uER}Nav%@dmF?_G=W7B{N5bvduEZk
> Dbmi~A
> zDP2iSa#GrDCM7QLxhb{(`k_?Db3gg%Jk3Z4lb<ku^=AQ*HC<r7PyNI8yaoNgm
> =C4I
> z*@rFhu=648r5JIJimB<^R2=47n6Q@{Ez`C*I<fC&^t<ssNd=#VYGhkrB|6755Bn
> VO
> zCEg95#^<cJQe!9C+(ur7I<6MZz7gd_%H9=L@n=%C6Bo>+oTx4bmvXp;lRn}@
> CM_=h
> zXTC!qzkwM(8-
> XlEAAs0KUI}u7xMD?`Tp;ht1*ua`RJ*}{9FR_W4U(m(Q?nrF03?Q~
> zb`?mb=rEA1^2PR5`s196aTF2WghYQJCg;A|**aB~`XO`*^6pUW<YXh$RjViTJB
> CWe
> zQNTKH+@$Lm+uU(fLE%rEnqiF>yDU$3YDK=ujI1Lb5e-
> %4ZTs2|`ZsOH@mTSt=mHDv
> zQVWeWFwn-?cdUVdcAUEg(w-_+FlY^00GT!5uhc-
> iF&d_qH+6WLdWQHnwP33b{3EvD
> zJBfj5c@MO}n8&+BBb_f|8+m0H&94!v*zD?}7Bh8go?%i>R1=F_UF4+KUBpt<
> QjbFw
> zFC7DT&|jrey?~>RUHoC+*7zqu#U7kd&tKUk-
> 7OjhpMTw`_%46l!K0BUfG7BxjYc=1
> zpRkqZO2ikF%|_VpNY$JdTBq)6)eRbe(2aQX`i24!H5OPF_!>slhri`t7x-34{pt-<
> zPV~>2MtlOO*um5M@kemh^tN~xae%+AfyePQhSejU<Sr412Lz5R<24anwK
> edery=}d
> zefUsA;81<word5$^}#nA!f)1xU*8(XN%wsy<t;?ik#IIRZ0Ai91Gk|9s;r0Mdj#;<
> zP1WjO7i_IkKhcgnXyPZ6jf6tIrrbaulnky)F?w4oHvM3$@v8I&5;melG&TWLGR|
> vE
> zot4lx8~GUYKk^kOO7X$J?yDs)GFVPy_qrLL^n>`&5P0kCy!yaf4Jp=kX*#c7Zql5>
> zq-xXiVm%k)90p>kDnEAc{OAP1Dyj^uwo4=0x5Xh03Yu_)oViPnMG@%+qK-
> {uIg_Ge
> zoN~^KVt=?%?563ufcV`4BQJJvZY^Q>*Uid{eQ;-
> Oxs(5H>^HG#7S&=>HfgSpo{o)q
> zCpzJN2CdEtz<`U)iI{AN)9|2`&ddcu3W<=+9S*23AjDOckdDyg%(<DN4dJ(zZqB
> O@
> zzttf9kFw-9Qv%vp+MHJ(e1~b?lr(Rq)9jT^fp?%-`~>~J5at)V=r$K7u>TaEZL_fc
> zTFE7e@bs;LH#tz)QBZ|nD9!iAKDe4&?|_N?SkH{;DASREBpsRYH%Nx1Z|Bv^j
> mfpW
> zOb1u{VlA{ht#{O(gzJ~MoyS|93Ur6m_c83ae3c1=5knD^0P34=CQu{fBfPRWyC
> CBi
> zYe&X5^1crN<gV}|=SGq)qJ6}ctb(=&M`ekEAie=<aI_$ErSC}S8}Sn>^*^#0yXx
> WK
> zfNzNDv|PwEJ{LcxEI8K5sADzcCK+BO{kY1%Nid8<sD?HKUl$y|p8h(B&%xD$-
> iE;I
> z?A6!P56gQ&O?*2tgkP7Qc-
> _^(2=c(427=I=ac~7(7}@mQ80f@e_`{kqEF5^S$pwu@
> zKxzF_bS%;dAGs-
> 70?u(01QcOC*q69v>$Krzw#1uo_yxxV$^%1s%t?mf|5)sU@zG=a
> z>%x!2O$=dJP#(JXrs$-
> G@MHDi$HBWEZ|*6OgnNhl3=Q%8cAuPTQkXY<GhRR5`~eSx
> zsV^Lsc@Vi9y!FAyoWM%V&8!v8OT1FvyBS|Y;PLvvyA8p|>VuCrgdazBGQiYh#
> MEO<
> zi>ka^vE!lf$otq4AwQOd{4&{QdL(E;Hvpmji_#aMZ%JTLC?$7eFM2Yt5{eNL6%~
> j=
> zR7oKw#N#Oz!m|_v@6J{1X~wf$72oc!`vTg{s5fNm-
> DLdgArc&XpfxpWI`r3_jC4ZT
> zH{iM;dV(g<p*$p(lse);b5j<b%$n)_smVruYd#3|G)}oGDaO$Ja8g?`C3L=b$a=w
> f
> z$Ej`py3N2o4p(~zRf_*W?!&Khx?)tX2B}GXe2>twWUf*#-
> 72*NV?Tj&7dep3U8)I#
> z1J$pO{|U({wq5Em^W#xikcQ0t!6?-6-sD$lVX00@(V-
> NA52;ZHm>m&5SI$E~rFl>=
> z23N}Vyp=qVVWp{yehXZ$q+Yp2z_-8<07TL<B#6|FuU3yrg}j-
> f^nDn_Fw9j1R@P3`
> zjg5YiN+wnwsu{42QefzHv<dOFR?1F4s-0It)s5VhIC~`BjgtwXE1ZjJYs8O_g6s~F
> z#13VKXJ+V^<FLOuxJrm&RkXzR{cwj*f&t}p`Et@zZkJE+$9bM<E^g<#)A={)e*6
> Ga
> z2Uvsj>A~xxGjofc=+0tma-5JLwpgzML(9Ve3cSe{yor`A0?^E@$rR-
> T;Z1V0q;*m4
> zX*M@(i-
> v%s?wofsCpKjdG6;N92^=lTN={(9Ig}$T21hgm4+)<m3a48XLQ!wQ9AiNb
> zvo-C{!msqXF^Cv%{yK{ERz!*G(X)tll-Bvt>-
> _5s8Sm2m9O&{3lQQWi8#&?sccJQe
> z0LP=rtAxC25DZtVr$GizUy;9P)TNVXmQ(D{wF?D`y&C}Uj$WV}HF?R&IZz7JWB
> s7G
> zCR3g^PBFyPC|}J(+5&lXjILy!y1IXMr#_(XH^HmEm~4~|q}0V5&6Z+n!V|irWQx
> r_
> zW`}91JXvIq&UV0I@xE)A8yjN=9e^VRW8U=LfP@Y?1gwlrrr5Ltf6$G?X$goiB(F
> 5G
> z)7XXKbRG{m1r}}R1sp7ocCdVUvXNqL^FH`k^G36Yka{1(HQQO3Pu~<edoy#Jf1
> T;i
> z;#aK@K2y31WKJrbykt~TMCay?f`r_lYn<%IX?QwC%C}<Y-
> b9LUUEQZi4_m`?hmz(>
> zCgbelHl6R|p!}AcHVuyQZ%7(%`lT$&M<%6)Fd4}&+Ikt!<0esna>32yuC~g*Df|
> w^
> zF$63&ah@e&B5cnqla1^%c<zf#3@bwB6j0e)j3WUishgC@=ZQ1m-
> O>&75~IL4hroj@
> z{d0J9fI2iP4fD;<Jd=I~@2#JSAbvbd(&6O=;jXRu<DIC`;0xm|UnqB2Yc6xV-0SLV
> zgHT42TSYyKLo+A;&UClGZW)>l630SBCXH2)Qts*BTT+wkq+=ptr(hw}`U^~2%d
> 1k2
> zR9#fdsU-
> KHu~0TZ04_?8ECPTWN%NT@t~#bakBX(@y`Y<rI#Yj1dMQS6nBc$gsETHP
> zd<aHBZcY7l@3Zzfg<s|_JQ-
> MC5a?<M_SM6vWTJehu<I(7qS^(^%jIYRtBuuWSC#r1
> zs%oo!9lFFB9`8wDBdk#kzGT&=XEu!Ed-
> }5%4OJ@s(Ev|#0sb>|!nu9AK(J|KA;FiS
> zQ-
> 9sF<O)JDpQ|0AZvy_fEDrmLSm2Q$J)&c)2WMpc>puJ;5MYsUCF_)f=GUdhIr7=
> ~
> z=rjvp{6_&W+XWzv)icQZQcK<!=1Pb-
> kP`Gs>2Ov5IqzC`Mf~fGz*)H~m%ww7few=q
> z&jRHp8C+fv?9y{vJ#2j@3Ojr!K-HuaET5KxXh<or=ioe*6;#|C0+(awb0itW$i-K8
> zhp|H`?P|@2nRfpv$-
> I{7%r;DCy2EsIy<oyO^5TxWAUlFDV34g0k?Vj2tCFLOQ;gu4
> z`mX4^`r05kg5P`%{hj%=UKmygz}iy>twmJVB2Dcu7nW4n$ik907=m2J!f2=x!4m
> Tk
> zD`82MIeE~TuG|zT=YiWLcDiH0NPSXpXt1O!YUTx-
> sbUAVZw)3&HA_}+`X?yVVQOcG
> z1?w1)_vMbCNfr=hO1j%%MVA!+f85I|&{xq`i&#84UBt9i>Us^R-
> #1Q;h?l6pWhOXZ
> zHTCvI;hY5^SmvD;)v6%sNxq0pLPhDGPA;wy-
> E$<*EL~ou{;P_V3L;>kebLM5U=uyg
> zsLn72LBqG6U+_oUUr$0FlPSJ5J3O@FZONTjOo-
> Ed=FH3(Nc4%uHl#76bBlcCi_CEI
> zYBpZM2eJu%LHB%J`vt8i|F0RIpFTUo^LzaN<#%Ryeum%Q;kN|u&&7Ywki-
> Aw4H=R@
> zWJtjf{2u175buk!-;PT5&H3&O&*z_?;kkPa;%@(7hUYr`-
> ht=;#QW3m{3HBsSqr#%
> z`T6-
> n3x?vaFt2Fn(4&Ut4IMgU=umIgd@cJ~fp{z*E4&L&j!dTB+Y?y_60th)*WM?t
> z%~54GsXzWbk|vMDt_YMw=S1kR5}6=cbM_HV-
> L6&>E|Z+}!h!L!ICim)nSCFu<=Z?M
> zIN**<r#%shnd3p(h(dK%(z|mnbUAP%m=XC!PTBkhegeoLbyAQJtZ`T(avu+H
> bS?x(
> z$`&HaRqL;cwyK|g9)0IYF5Q5lb1WjTcUEDM55?(uzhc=`u?_{-
> z{bkn%m^?WZ*1S|
> zvA2gv1jqiyRN$5Qp@@Y$B-
> jj8L<t^7?v=yHp%?KcN8upZ(<nB<pe@f>LLxz;7`tD%
> zgx~N(VMzQsn0t)aW0!dQu+0S?Op@d4a16v)Fs-
> ogc?3AYBb+8Yo#tU6khh9!CXXQ>
> z1*Hap;QrdSG5Sjb4*8dL*1GL2YhZ6F1y@VN7o!x%<U-j)n_NVrn+mQ-
> 1lMj0)S+oK
> zxon~S7)olb3bmn;#ZzWmpoxjhCViJVhFXHyMqc}yV_LL1<}>fPNYSR8sMi1W!
> >nyY
> z%rQ(KS;LEX?+k%*ktB@$>bD)AV~!!iif!bzzd6Q$+ymL%p?;fkq6)Y{ia90=Qp_<
> c
> zVYo3M-
> zlXK0R`f2fYG~ka?LS(4|@BMIj{pz%rSgdrB1T%#2mwS)oPf2XUs7=??2ER
> z%$sYDS&Q^EaPU`~V|X{1IfkWFsWqk)se#^Urk=F##2mwPAyu#6=^DuHqbg
> N9XbsjN
> zJ!`;UZI0pHKy%FVcuSgKTHXtDXyl#d$FYrVOwrFAW4h>~cXPT(r<|z1opDixm}9
> bC
> zB<7g+-gLU?Dx6rX%`u&TqaL}P<`_6ViaCbAgP3EKSlKvbRjDuU5d4Ez9L5~;Igp*0
> zW2WdEj7pKrtU2aU@SI0O>JnQ{KXXj9gu|(WIKbc5KnzcmtN4_ZJG~0mYvV+)-
> UK7(
> zIdkDwGvLHT6ZjD7CMZpyeQyZAQy<>f5ZG5Acy((W*rJK%4VY+PF69zBxQ{A5
> A5AoL
> z=!GDr?F?Xr8=w!}P_6thvuPIjNv&`Y;ZQUW!TMylKE(t0HXtk$w&B;OIWpnsorp
> gN
> zP{|apvGiF9eM3i1nrK!qQ6nFq`#yiSoM%vipY%ic&=7oscA4NC4UMd>2wc3;HX
> 3UK
> zp^ZlDEHDGmMnic8LAoGRv`H)4w#7XLciZBy<O>#EHX2(FZ8WwV+GuP!)<z@
> WAfwPm
> zV{I|C(b)X7(bzP!(bzP!(KNyO5^NJWYVhiajYcdvZ9*u6rpkPd7@;ZU4W9W5TB
> OWG
> zBaM~Oj@ahRIaETuLH*qu4JpAWjU~Lv90TeQd%!zPvyW-
> ^r4_qHRK2j#gb~RZ8}mzW
> zUXp|!DB+Iua2;(lG6`%A>;n-AT|pSWK$;KZB5gEA(4&n;cO-
> >l0XwomGQbcgzb4a;
> zGVB#VOms2PY!DO82AXIvO>_6U8iJs+Vxr-
> MgSAeMR=GwDppcmPQ3`>HhW9kloJ#x6
> zMpCSpXzHQ-
> dkt!L)5!ag{0^Rouwen!e;d9O{XAn6h()Sjvw;XisE6Sy)?5goAJ|Dw
> zhj#}3&BVN<@)nGPe9A_~cRh$%xlX*;=vi2YwTkKnGtx&sr5}auH5uNJXnYollW
> |^S
> z>W+lI*~mxOh<*)Ke=@}fm@=Q2ane|aAJZ7vh(z7z9*{z9_1Q|GUteXvzM6g
> #V+%S1
> zshpUCUX`wYHO)9zP9M^!^r}$XtDrT9A&B_`=hdKZX(NJ{CzqTp4Z#m(tZExkcx|
> ;B
> z^(Ar(Vv{x^9&sZ!9oUFsH#wU4WMJ*qO4x{kx<uHB_LIk<JlJp^c9MZzJ{;>28&
> NO@
> zH4^N8$bbP)8&UA#`d|zkDhBff<eZ0Nj=droTnl5ysNrqMAA=nS&-
> EpFnTL=YyKDjv
> z1FT>PWra~f;NglksJK}kZA9T%efZsmz{B-
> {SVJ&|>QHC*u%PN;CI+l`E1GE}3O{^A
> z&<|%pZz3~Kj{r657KrvIMLQ1B1nOuJ&Q+HPukW{R+>gGmR-
> M{9iPU$%0UoivXv9#K
> zq+v56AC^^gJ#9w9UUQb+S6K@t%QFMRU&p<KQYLIh8^mVB&tfy;jo6HMBQ
> ~QAuo;yg
> zgLdH%n-
> S6M*o>rPrw?c|dQ(p@Vl(;;?&Z7y1Q($s<w<AcYxq@KksiZ+gACnzaVx>X
> zmBm%51(zY4i0A#r`vVw0_)s5*Y)dQB7Fv;HT5q~htVnXd7Wc`l6{!_z!ArJOsb9iv
> zOsq(Cup(^{D^i`zA9a{a1(7NP`+8l2)PtI;IvEOe4)U?$46YY4S`WKY?gClY{Zmp!
> z+Lf*b=izA(U^{52dS{>I0$6FF{k3zGf%V4SwY9JInq^B`K`9T_UIiU&-
> ok*K4VGuN
> z0gN=EU>l!CTW~^app~=`=TkDpYu4{|y~KoFcAt#L%*}wYm3;sR)fU1P0%6AB5
> T49|
> zz^7!2SG(f?<zvUe$-
> 4aX%P_D2L`9&^Uw45p6m2a0BuOS~L)&nNzm8M{?a8au8PX~O
> z=4hg3qHbTZb-Nch9~WM~^B}-
> fgj*Nfj_w#2SdS<obhB%9JSH8CtYUp}s#b2QM2hc|
> zjl5=^?sOXTppGUv2bM=Lt;`bSwn)0iRwRP@jg!8v2(~WxtgaR+1>8GfY)6`dBvL
> C`
> z2}}&Ex=oXa^KDYTS>*9M(3P59jQuTtg0Yj}i_-
> VQ6p|hfo5{AohPgnE9;)M`BO1bo
> zgasKRA}NeU#6Z2Uf_fSe_53!xA-
> GT2_rCs9<mKA%YNkk;9AQNKgLHt~+hMFb9p(iY
> z*gaxIl+h6T;QDAFclPbHMnp+#Y69PtdO5+WKDMMjZwa{QK54=}v`wstw`rkP
> W-rRQ
> zU_y&(Pqz&rR}(#QeKaSlF(c+$atXIu{lc0N`Do3EZ@`Sm=K+RTz7#{O1>?e@ttxP
> s
> z!$%8p8j1ti{B<u2HHY_skHsIsy|jXI#Qf;>P`VNd;(csn4^zzmGa}{EWFuu#m=XU
> Q
> z%j<-
> ^O2{kCajMh})?mp3I0YHxrI(|_oN^azu;s#zxIyfQOfPms7nlNdWj`=9R#`fM
> z9nqCGU!8=s1@h_`UCTT*d|-
> B4A&lgGn9shL6df=*qTFb&K5a;p(o<|O4T*e8$dm1A
> z7!u9w6@?*Di=q9M*$FWc8UYVVyg~b4(s<MV0SKs;F(eWm4T*$r42e<&d0`E
> SXo5ek
> z4T&H^-F-
> A95}Q@3_2(ANFeGw;CWb`b=vfQ?L)Ok|y30W>4T*eLt+xHl76L;e`U-|b
> z-
> B(b#N|`hy^2XgaFeLJoPGJm*CQZK%fFV%^k<$SJ)?^ezBJ+J5lpmYZromBOEou
> 52
> z5($ZhM1i<ugBTL+N;bAp?glj^ws{y~y)M}(9R$3v&#WQw4Q)uQ(@jc<AraHJ;7
> 1!0
> zD~<y9e7BGj5e$h0ZbW<<5?{r8$B;<GkB2h4k=m|7ZHY`VE(%+s;SRYB@1NF|$
> Ychm
> zv?bP~INB2Vx=Q_Sz3Fj(-
> 6LeP;d+N*W7fZKK!=&i7)b~UR>u_84r3hEbD>m<iC}x_
> z1q3KnyF%(xG3#lI;zcm|<XWSu+%-+#hRmrrWh0#5^){-
> $r7+i`$codVc#KTj?)v)c
> zxP;CvyxUq7nJp=*!$FLS?Wi>?k6N?xXbLMI61(EV=rU-
> ~L?B*_9&$#@6LL<O*cAnL
> zfqJJa#Ec;(Rm`vnxyizI1UAQ}c_i=!F7O}1Xp!5?qutFD+!^Ba*R3O`m+>psMYccS
> zk3UVU^%KUI^PNRau7UALy?Un@?=)iWV9j!Dj9-#^+vTpA-
> !6B7ahn;B1Sa1Frq{7F
> zvN_}6ahcN;S{mzR*;n76Id@7araI2#^!uOYl7CKVAb(M5IkSIKC|it;1fOGUYzOI(
> zf<QW?AkY&j2=)Qk8yO?eQqaXzW93ZP)$W=}7Y-
> _`CnXt7O`11V8++rdti93JPE3xn
> zxVY{!G&yRLhTKT2;~Q?P<8jFxtK(CkgG^X!MJj|!YtI_AE`8D<#4VLQE{^e$3QEz
> 1
> z@g{40#HKYEALS$UE4&$Cd?Y@r)pvEd>3?N>94qNeXX^UuH6QM!`+b8L9|<C
> )W*QJb
> z5gEmB!5>d%2T}IvXM9`-
> vc`vm`0;BcP}1JZ%4#s<V+%W8{ZX=FS(am%WF>Guvi_E1
> zeB_rS8Xt#|87^thL!^{^O^H?N^b1J8APSv3=-
> 3~LWNm+3!E*6u?2mj*rg%jhEnLl#
> z^uyV-Kk`L-8!(f84j05rMLdqDa0gdzSTdL6D=0*i<GjZ$*aq(q$pu%$XyIEZ#~0B|
> z;)z5-vJs;kAJfj78ta`+8BnxEINM2_^x9;?Qq=C>NItQMLXx!g4N86aBJ&Byu4>vc
> zQNCefqk(h{45XnY+CaMf<r$vqH_h-
> ofd6;n{wChzcRl{^#{Yk}eROFvY@jVDzjcP^
> z_H8(y7{A}g^GkStC!TlV_u`#^`@ge~8VvvJ_bv=$AiyYB;T_yQdPWy_6*>0N;xjd
> l
> zKe~PNX1y9El>YWnr);-
> <^w7D4@G<S9*8aJMdH+ARf3Eo0_D_kv_CK_L+BUlFpM9gh
> z5W37-g<%hkb(S!2!D0j%_7-saUBAGhfiAl}`;^H1_c#J;Y9rV4CSQFM<ID`dBK0)b
> zfpCg*RMF1t_%o>^=Oc?0pss7xxnQq+9)n%B7LKCMbzcvI9CwlfP|q&=v~iH2-
> G_Th
> z<a$z=r{;bO|3o+ZGJ%hcxZ@N9*4puJQfv4uK)w1)3qNx%fzu(wn=EYHfS77jet
> DC=
> zIPZ1*RZwF>e;dSPE%<}Z*Ns0O$}IKgW*3pj&Gz=w4E`cyezpmp6*n^BU`6UC
> @K-_M
> z1hp9)$~GaJA=2bvag=VwdSvO#aCh}V+m05tL(KHPIPcL8eC~~w)cn0~^el8fE$
> 4-e
> zlI)ZC@=tu}HecWgP?(Z0a9za4Nw%GjS^Ig_>gTu{PVD=M5xjTd1^AH9*69Gxh
> _AiA
> ze|+su@A^;(3c;z+6w1!Wi3o4;3s@Ksb~}^`bj^K+sM{9b^SYi7w#9cNh8N#$jkm
> pw
> zyGS2&$cT^=--
> ##0m%D>K>f0J`XEOUS^#?pvsYUwZJXjc|xX7WglDBam9&w(Y&D-{4
> zSKjzeJcZO0{ZTp?Yh!Q0V%c1L7UW|m2#q)29~Y03^}ti#=x2dotf{}kCSbNY9@H
> Rx
> z9q}H(09gMIQ1Gyb2UeI=icNtmS6r=1hN0sbAN8(F*pkx73Z&~BeSXzt93CDqDk
> b7i
> zqE56S^LHr{KrM+o1g2uT$RZ~Tq9LPX#E6pjy{l|d>cf9BA}O)Tzw}fJ(>UeSU$;Zh
> z-HOtPWEFsNISK7d3tp(nc;M_!QCtVth-83$-
> G(@^7E=3vOuklvJ(75gZIptRoQ38~
> z_(^gL-TY_oK=V&QOtv?`1K{YQet8AkTc&=?=SIRyAS#>A&set-)-
> jvE<L_i5PvRmN
> zG|;d8E1|;?Wc*aY9y%&Ndaaz_3ISsk3T;I`VvhHW`HPaNt95lu8B!!u{9dKY);LrL
> zJ5AX;r%2hzDRCULb!zHH3_4vCcfYDz5uHS8^);PSY6V-
> 2Wi<@O%_dICt;ix27n#qC
> zi%8Tlwy-OmYD~?|cLuYtuXC#ZN1RzNl{nf~f>C+s(}JC$Xe_%`T?<yi?ry>hbp;-D
> zce@A_j35*#B?JyUQ!@@W?031Dco_p>4Y?tLu~6yynYs0Ix?aHxAPJgpyIgmDJ
> D*d8
> zoq))x^Aj(Z=jMN!y`Js*MnbPvH)c%toL3>;leri<ugcBY^uBb^%OKR8nvb=4|8cS
> 8
> z-
> 4@@#$_sARo4XnWOBP5vr?3#L!kDm1edQYZCV}di8gN6oa3=sRi5+2d@x5BTE
> )HX5
> zv5iu=^gSkbHxWkuhBhjW7ERt{SRpm!>!uGst?P-
> 9+2Fc7n{w*&yz$qaielh~V(JW+
> z7;{(SR|gTP19A?y71DSRCz;GU#iVe_YUD4%-
> y|e&Y@?J=I}2Varhrt6cUXi94rq~1
> zN?v&Q^z8y&VQo{YnX{BG`4YllGWnUOV;hBSLq$4*6-}gAFM{Q-
> faOhWqg0n*pTi^Z
> zpGxr#V2J=Idk9wY90n{?XTciItgt4A12J%Lp~k^0rat~SNi#N;bC;*~(rxi)9k9G}
> zx3+II6X}K?>uP9<2@!f8)pH7cm-x*Y-
> IqXEj!lv2w6As|rmM!Mkqv8kViWqSI+9%>
> z$cfLG2*?>Y*&^1P;xrA1x{?$nk=VZc+7Tw3=IZWmg|+vYX;A_<T?9(}HX7(+Zth
> t}
> zCeRSwfz(sN95Czr{ZldkFmJGa#$)loA5Pe=XOdHQK$@`rcsd-8#x^ib@k3+!Xkl=}
> zBYGNq4h?uEDWm{>*W3i`2OiH2x7>UqVw7R=bj*AVdK+~v>#(Wig^oewg*i*
> Xs77G-
> z#u4R(ckTGK@&aakwh7oUvwnOR9z*I57)a5r_)OeqKc`;9W0jhzKW~k9yo;|^pl
> IBS
> zr)u>{CvV%M?!56`cnm48{tRqLFheUdoCAI2N0b>Tf$QFD>Lt^|B`Y)hSV#r@vtu
> dQ
> z0($RL7fSC%%8;&a^yFNbVdX<wX5eq{KRL(o4l)DNMLO|D-
> <rNR?~CuX@74DAMP@+D
> z`InwH#L5g!=umY6j^z?b0ZmsU@vseV4<jiEb}rt)T2oTMBW8MB^>lF*hO4X5&
> UEq8
> z7C?ZcuzDI>S*E_n=f)P~6G=hxbGjIsn?Hn>MM{@Dtdw09QX3E>QKrKJQE`;!N
> (w6;
> z>gziL`6wyy{??@;DU8f5dC@^)k>4Fj;m0J4TW#6jJzx3*bt=xyS&E#H6j&285s@
> ~l
> z)P*Zdt^PyjJe;I3I=8r%574?TyckJA3QMDSX=0gEjpK6jEn*h-u+FCkz4~vPPfe2Q
> zQ|@#m1$<+-s<U6w-
> Q9#2YAhafcSBP6u^~&56mGSZGBp$arhZJ)5lMldHf~{|A}Nf`
> zt)J8Nn>GU)DE+@K)m{H1KBov<Bn8ROuIF(%F4CFLUe9*DkrbLAGkEdp_KBo$
> T5e7+
> z>YXdf>6*uF-q!O3H;@zv9Djg5F1L*NJ$lw3AUV8?Zbx{x4}Q#gl!R29i27wXCje!|
> zHcE*i6mav1t2t}9ZfJkRc2|llsY>0x&j>yj=_(ygC|HZaSy5~mFn5>`|AJT^E}>ww
> z2nCHyirG2NUwC+9y2cG=XXfMVyoNXUOEvNi(-
> >=lnFRjok{4&~aHoj~1rQUE1~Vj*
> zWarIXp<uKK1&yp1!SYwY@&-Z@t^)RX-
> UwLU+1XQrl{`6MnPxDs1B8N;H4d^u!RLW?
> zmr(GW1D1F0*5(KW@a81M#@vQFLc!4}G^<gF?alMoF*G;k`q&hi>k$nTCwQ4
> OoczI>
> zXJYP5#FvA^#5VGpk8L7XQhaz;*MvkFQcIt}_rr(}m9hw}ElR%w#M!vNN8$O;c*
> X(}
> zg%YKp-UoAu?F<kbWmZtHmP!ndcp5o?17-
> }V3x7z+AmI_Rr~nDC!u!}pUOly!=$laO
> z1*me0Rkjk9`W3buqRI&2W`r3n#<1B~ty1R6RK_++?G}O}cq3juym1OkHu4dbV
> Vy{R
> z5RzOaxUo&CNe_QLuerY!*52<32aeqIWG*(`Gq076FyYR-
> pUuF{#&d)nfc>$RCc@u=
> z_7j>kLp-
> $^JF|2EM)fyLTQctnq5NyP>0JzlLFA@C&I1d~%1u?N+2w`fT25#>&~|D|
> za?5F+E?6;J?j4qFzF{S%<-+n;#&d3ndopPevP55nc%r+ZQ)AdBo@>{ffU7P%I-
> p_a
> zb^_4EQjkWZn^H%<`WdwMsJD%Chh!7g>2T_BbW={^NC$-
> #*^v+x`>*Usz!FJ<q9cSj
> zBkHxn@rsaoBLXSzf)vVygk%%dh7B%APGSv-
> MX2FfNN=O8R2Z?|u(zapTcwU4DlsP#
> zRnTNH^g)7#lWo(nmhO89S}Tbo#%PR)D6|hAYUoqZb$TUIXpaPOW=6ByrCW
> BpbjxlR
> z?m<hALi~eCO=iCfqg*6MiR)80_PgK^#O^Av`v)E;t7UjlfU%KAyCu?Sw~aK~-
> 7nJU
> z76R2<T)K6n(QeKh=h~w1-
> 9+j{e^wptyuMjnoF4JKK14ThpYV4Jf^ws)UF0SEeNq8x
> z*pt{$!}Pg9EY;6{#5|=oPi}qsmH+Zj{zdr%O8?al`sL8&k1_Sh271*I+qqCwXS!>o
> z)7$zFD1Uta8tL>tr+mb~`5yET=s?}VLB4Mv_#IRv_;Ln+T++A$VVfn7E^k2k#v`P
> U
> zb;9`(^n}2;JqVh=>|pS-
> Sj84jYRXiQEP_1+v!+O>mF{I1hXUqP87L~&Wbh!lhGSex
> zuA=PjF%xf?<zui&IlU$*Cia~9Uz`rtv|bztg>ci|Jk!qXgBJ_^83L1ujzR?H1*dW}
> zgnboNzI)-Bh#>?Wdw0Q=-iw011&C<dohi(`Y!9)|F8@ex&=-
> 3@eK}S=FHG~yU5zpA
> z3B|UwALcy9#OKtuz<!(rXO~t<9tHS&s?llNi5`n+f-
> J%;R1v8r{WUzIb>kTIbWbw8
> zr&_XLC9H>O2X<m2D5u#b;^b>%)T)kTRr#`g$iMW!YbWfY4+eLi$PySnk(o+!pT
> W`X
> zo$$ULrB6Pcw0&xk$J69r*_>>CCCLi6<W#AJwhmoLF2e_#*Z4SN06x@V@B!O
> 78iH+X
> z9RyJ`T>ao6**8%kit7O8H@yAJKjkgJ>Y4z9P?f;J8s{Lw!Fqpe$^J@ziW(!V)}g^*
> z{5vcLc%TuFD=ci3fOvs+`T`?NR;7e?wC{^NSm|CAX!pndf>M#dzX|b>_rd7f#^*
> qL
> zY!Mjj9XN*YW~Uk`m?>lT<I9A|)6g+W^e)89uhGuLXaGz@9ZUyV5vQQe()_VK
> aU~oE
> zq#0J<GfZ8k%Y8+<avUKx`JhuNg?y2%PAv%7d>Dfd>GMbd?0a~Sv~QhOi2a4_
> +wzG`
> zpryH^2$;Z|aV3I`=7UESY(^Y%c&;84o6Q~sYL@c>(#@!1WCbt24>^O@RMwQ
> KLZ6=f
> z0Z~G*e4Xv(hKlwC#ARR?N2O5Fw7D!HH|z^ku9D}y0<H$SY_niC+>X%|Xx|F|
> 59HsL
> zCsho$Z=GI*eHZQ9DuI0<>1E_=-dm(;y!jx;+#bDuF6oor+d4CkP25whR)IP-
> iGU7;
> ze9$UvMFbVOv^&E=Ht&2OWP`&e_w<uZtVBY7M#YDJ`6_9lx1xyc^2ZW<40@
> YCD5B`Q
> zZ*23vqmqS!%Gi|rzUY70V*safmZrT5M{JD5HLvzqT=Q#BLezDLQZ@hR8$AVz3
> !3L~
> zC<g3V^2FUoRkUI82>_(M-kkO#ccR1#E_p)cc=frp6f2-
> i@~8&6#hnNHC+#%maHMQ|
> zUStCTPJ5o?<Dl*FZ<<|PD1v?+(+paf*c9w>jo3D0KNpVvb+;K7S+w~RnNwiwv
> @Jds
> z_qM&maBo{1@HY2=IK8pGW1IILm4xFI5WcN&6v@Igci{_8bH5?CsMw&*mH
> oG!v}YcQ
> zo}}(}(yH^F61dCsJPbqj@?ylUGZ<Nb(b>=N8SFM432{%Y5OMEfWQ<IfVWDnY
> Cqu#t
> zmc5?n6!qaxSW*6|&2q~wf<Wrzi<Ba>l%_@@nmGki)aTnsg_;b42mhv-
> !?15Ok23jz
> zc1)V6%agh;^m(;)`JFgyIYKUW+h3&a$=2mUcU_!(x-
> KkD#eZn)k~x0x9#0mE1fltP
> zXaGN_;WMk)beTZ)QQwFOg$DX!9p2hu@V0s@w!N%A_!dYSvr#4HafG=Fyft
> De(13u3
> z7z@kx@}6nKZ^d>LBS<080}dz)%YdHZj?>G+kec;l8P!DOJ<_oq`B4-
> |D3ySMQ<9c+
> z6huu~UX-QgA=WcE6IfXv$fWeY*=eN!sHVy-
> ?nqr}u}Wy(Oz>b<@Lz%j64I2e7^5eG
> zWl6ua=g=>LGuET$kVQB~dk)8Fm|a}HbnjAdV;Se|W}KG@U#p*;Uw)V}XAUb
> bf2e<v
> zK4C)jGe_Z65%D|A;d<DKf|Hvk_Xnj}sDINnd6?J^^#_O97DKT98ZYZ#r6v=pICP
> su
> z@py>#M0hu+{N2L15#D&ftnaWNBM;3VKrdZ~p_hK6pg>P9IJyH;5~=}q)De3C
> bL?%H
> zeLLQlemAox4iuJo`5Zm_20LQSIQFs=0}$PX*%uWSDFG!Ur+XnLKpaX;<J_CI01
> QW|
> zJ9MdN?S2m;bqvb>AVT`E-
> k159lVFZ{z)mHC1dNw{O)?BFHFFrJbk5w?*MJ%H_*yXl
> zUx$;Igwq|P!r&!(J|NxxOh&-
> ~_SQ}Wvg2qy<<twbiokGE<T<i5PtDnpm72H3F%Ddd
> zW(XDMsQ17lGz=$Yq>kK-nbnN%Sq_pWgBiTh{khp5ocuLggC1`|56cBD=Z-
> IQgVrfE
> zXl7O|*p6%%X%id9z@K%P{z0=2Z5)ZW)>dHlsZz}n0G{U*Rbmnb#hCM^AWjl
> #LOdi2
> zglD)!m7qr4Yg(*cd)}f2Y4n_hR(XX-
> *92^<&KFN6!=Q6$j&3T|YPYU0B$FeOlb+vZ
> zBfdO#!*!?!PyMhj8@xKWM+W;zky{T*Z(bCc&6|AnqA*Bjb^uDJs#B%f*qF<H
> *C`|C
> zBe`T&Q8|sKM33=@2<m-
> +;_BnG1zH_K#S7FSA`YUxV>HN%Ey$U<AlnIY%@2qv15&5d
> zAemX^Taax)qJUf~AluS!LFQ)_p5}9?P{#k+eDNq=gdD@(G#pp}<t<b+{5C@}x
> 2C_3
> z%)szG>^_|*Yfg&Y2?TCOn$PG0u{X5GzixK^iLt$f{<^iAgpi&jfDMX0@caBG@s!
> 6r
> zCos<}9PeFNU6T(_pAg*zz4RWAcuYNePLX;-
> n=GA_#$!koOeG^K$HJOIAqvKB)UJ6r
> zv?NnOSxKU)b~W$wqB8FlAUbBaCv%E=@cR~H`Vcxn%bhG9htRcgm;tmjCo_
> |kdr(96
> zzvwimxONObe9rx0dH#vWnh37X4Dr8+kUHV@*h;xxW5<VjjRJJUbTTf(%ziqv
> &nm>m
> z*>3;3nWIjOby!46;30U_5>ap$b0O+)CnHZ~A+l8gQ9OVxpJn23R0mPNVG`ofCr
> 9-)
> z;W4CMs~CW&01$;0w}Yr)SMy#VD*Rr-
> 4q&hwhzf)IXwt%lQcFLTEIzO${ayB`ZH`7%
> zSVKnhZG#M=rno=UjS@r!))G;a2G`C@hSw51f?>R>Xs$h#IK(s5kvOOLTg|E2LlJ
> Ph
> ziD-Mdj1_3goXI3W62=n)+6XZ}Bi}Y;Mx^0>(#O<a<(r(z!^{V)yjUsJArU@&t_cJ4
> zMXVFMl5h^kkV#GHS4izREFcwB>b9{TqFkl!WVz4)a%qa7s5~Rk6!-
> dP$T%@#_AuQj
> zsnMSFLnwn$U#Rfhj2HsK^BksfNo0j)Dz{@ayQT>6#i{Do7{ks8*C`{59HvtCjO4)l
> zqkBlHr%*)*A87`$aA|YxtYnzVr55D77!EFwn3blg8{HsvN)1w&$`8M7KvGu0=uv
> 8%
> zfZUyaLMEwVxDm)!#bR!0UBGt^uVDNi%PW*RmH9##0yrhk@QT{Sg7-
> ?0KGyFn{Lo2~
> z2nfdJdH=d=hMgGOS4fx8E$nu#iTMF%AApXqcRAdXUW50TEAbW~J&~|U5}p
> 8p=>;>;
> zUxx2Ygqu(=(bsq}R+}&!P&+$Tdr+))?`ItzU>#(vf~o1TS_=nw5C{(UAT!Hc>NFYx
> zxaM<!ER>l6<X{g*m;N#wyW2MakoM_Er8ltBAa<z9Z~&nue%$kHFBkE*u^yX
> GWZ$-B
> zCb2D=_*>aHe)})^)|xpkeLsXRqfg?8lzeE(4g<<VK#=P^y<sv_7H8ur0ZGrSZ@O
> HI
> zQCfalGeCYi-
> 1<cHZyl`HYL*dFC)^;GMXf{f_~TpyV}@K58PkW!v4g}sKM5l%!sw}U
> zPm#1CwQw}a490lGKm#iGPbi$}$xMl~A$8yA=ON;miL&<O$a8oH5gO9tVtKEJ
> 7v&4d
> zWN#n`gw(m$N%_(`E6JF{m---k1bCV&h1bj!M_;!ab2RjIh?kSq*DYJJo6k{ijkj-f
> zJD_5rz!sa_hgXJZ{sa7S<pr5Y6s<RH_IgB4g#;f4W*{-
> 3wS7^q`b1^E=O#MHfQcnx
> z);Tb(5dN7uSM7PpndJ-
> <KdD8v&;GD4oQxDFLuXVcL*;NDMJfpCHzA2Pc};n7B7Z%k
> z49_cofLF!g5LBuW0GZo&0bYA#ojGYsC^fUZP&?Wp)fvg_y~+8$*rC4Ki(`w+&+
> e-|
> zs-
> m|1?1ke~=Pyk9UP#O?_a$ceVvAoWL?pUM9!L7j7rg2UlqWa0;3o4Tt36k{`k+72
> zmRBY<%}t8y&$9aqSqB7~sq!VOeHT@EqgwO)%GFgr?|=a?Gu+&u5MSadZ(>
> Ga;x1pf
> zDs=q~H{Ea}!YB5%ne&>wBDEi_z6I{2C2Fv4j=w>45<RG?2<;fTs47ke(#j>sTv{hl
> zGd?mCqzN&v?K?T_5ekX3)D#B<x=N>voKH$-
> X7!bCN)BjQrp2aqp$&aFg=pw&AND=N
> z2mQ)ZtD}iC2KN!9=t@0iG5)Fysgm9C>>Mrf3|lZ3x_2l7yJ;&`*IXl{jaP8j=Bvyu
> zDM044O4{|JW5~1?LVG4>M+UrFuL4Z%#B5>S2EAH+*zZK)PGIL*BE?g4Wn_i
> M&QG4r
> z!46ImnxIZv?V7K2%E%&Ohndy<CnbkIA#)CAR-
> DU+qjuGhQqHVh%6~jqoH<GO0D1>Z
> zv1Hi?G)zA@L%g2B5zqu2-
> &%}w@i^_O=f!Qur=ES9kk3L=^#pE{m=xMs<Z=|v8S$^^
> zb}8b%NxS5vWGa6YnsvQy)=joqf7Fwz)j}!GiI+>^r=V~kK&RBrVrKQkH>6pR?U
> {l=
> zj}xG~(~D&OL)7z<`g|9HNrA?kz|`sEgt4b-^-t4>*Q||F;r-G|&8s0T!_)?wH*&ni
> z963i2cW~XwLl^c#EB`9W=d+GaZ;kyA_~TE?2Y8PU#N%A?4f5fb3{IM?A=hY4_(
> d-@
> zCBk+oq>qEE`I1G~^I9OV=)zLyVpaMr_Ju*0PN~r)he_3Z-Jq-
> 0qDvi11hi&mt3N;G
> z^x|)E%U*0@gSSeGmdsg#MNFoc$vYDHMh;+#XC=iJo@LvmzQzYF`N@2TDV
> ~Qvx@>}f
> z>E&`32foSpD8mQ?+ean14D3|*Vfx|kLntRSkE&!o-
> NRCglMi!?iinS?aBsExhAxRg
> zXqJFjP%(r-
> >LBtuq(~@5g8P|0UuwAD)Qh?a{t0|Uf)V&N9@G>>{Z_Rb!bKKBkL(1|
> z5V{GWTUWZ<Ri=~&Ei9KxUFt_AdSI<XgOZf+y~$;?HThrkg_iC0Eaj@DlL<e^1h
> 7%{
> z7nenULV+rzz71fUR9?{)H&?(Tut)(&2AIOK|H^Y@*_f3l%r}<tXZhwX!{o2Y)0s!)
> zWY+lMH)dWvAhZ5X_%-=D|F5vU01|k%k|>|wnE$pT<uBCvQ-
> kHlH|9V22>HcB!n8l9
> z2*5Yrr2X=3u=Ya?CGtk(WH#-
> mh|2a4$n0u=v1$L=gR~#tr2R+89~t8GUqen2tiS%o
> zB2F4mgz3M?bx!^(2jth^r2X=3koHH8bMg-xkY9ge{-
> +L?zoyKzf7~GL$2V#JfXo_y
> z5VyTkF%&$s2xKV-AN6-
> }b#@`>P7MRvjH4lndt(Q0A<yhZ0m3u2TRqkjGM0d!Di;F(
> zBzdVmMP4k2J~&d|9QfG*mOe|`_%Yz?yu`sx9~b`B6f=i6A-
> >w|@?zZkCha=#9)7*J
> zZl1I&6H2xu=itjV<vzaMncn%wop0}KAHF@>ec=6M%YnJ&C11s*xM1hKBP)>T
> J}-We
> zaG`e`B+(PDDKEjV7r(v(uN`QQz2>=bb1}qW=MVT>)_FFhS1qJsOW68rw@HvE;
> @d`N
> zweePIPqx#iQOk-
> N1(TSt_9peDA2Up#gXyx0J_+UoH#4k+=!#@csT)!Vd(fKSi75CB
> zJ;$4A&ZN9dowJJbmDa#Tob-
> |NJ#bf$u&7HO*OOhm9A)z_6>L&Hs6$fTq;EZ%RYR;)
> z6x4^^M!e=6UB@>eb(CmiZLCzjt5Sax{T|*)tW>_MR)5y-
> OsrI$cZW%r8!NRC>FL$X
> zUmYuzcZ0=B)zIoJG&#CXLz{2kNvu>2ZH~JJ(w-
> _cYtR~aObz&}W2N$LV64<$On>Yy
> z)|U5R6o|aWyF}wk<cMwLmHlRpt{dv=w-
> H*{u>Gb}UZxiQr>ozb^t#_9R_ZUlYWl4V
> zW!rwM9Lav;oAh(VZUu|%bB}FYVd`O==6tSt#GjDzY&~?!%hWrKu6j7>bv?vyZ
> mO-v
> z7*{>kk6=CcCS8Vl=zzCGkzI$zpJh$tMTh?3Vu%7Wq6(&<Nk-
> I!M*iT9R&+4*Trr$1
> z;M~is{^bRDK!`*pihWSF_%xFtc5u-{$0HJ!l(DXUJ>=imUVkFhgYIAl@mD}K@-
> EQ`
> zEj_Br>s?JlZT!ZS-ge|`K8O=YSkaioc=Y<?-$G7A3dIh+Ze(UZvq;`cktyCKQp+U^
> zuk7>nySXZfe9ndI<3Wj#?JTZ!%FEQl=zM3aI_Wj8S&G{EsOj@klx_QbwvV{xoA
> g>l
> z1JmItaWn_265Gh@5dR~)u%1n(_|R9LT6@Y&^aE74TnaR)Daao}C>J8ETHP$Cf
> r9<}
> z>t0|22~{kzWP?fZ1$M#~I9xeh1<jEts$hW?v>VHHydEV20lOa;1SDMuDE(Rv0+
> `Sf
> zy-
> Y0wFLDszq}K>wDXQ%&1_33=VG(fEa3X+j(l4N$sYVhARG!{YgHQ+d`$?2EU;39
> m
> zQs8dsE1vb$j&+xf2)f_l)U-x`0}F!EtB}P|R-&;J2u#L#jVX8#%gsh!i|@NCnc@vX
> ze|7@BIK^-`es}~!OJO3=l{p(0!`OCMA-
> WLo14nr5z<Etw41m`qCU7Q!UlNjFJ<*ju
> zH48L$@T}+=aF-
> 0J@)ouorHL571kRdBUWnv~f`|im!V0160_v_NSiPm$scXCl@~hIn
> zN1!dUmP_xzz3HS_&souvQo$1JXWeEB7MI#3klF<UjEvWI*De$%otm1Rk7FI
> %(vL_H
> zLJNsTB?#d)rmjfD<z^$V=lCBPf#H!%@qtG>o+?Q3;0J``-
> vqhh3p^Xf30m4Uf=<6#
> zJQNcT+~P~M<R*j>y)b$@mO1dt!WoR`BiJqZf<EW5YuR?sQmzxa(#u>KCPm
> @UXEK}@
> zJuWB1-oA%0P|+Dz+v4Zeeo9g!X6l`_XWKg7O>?k@A7!*F+#<mu9Wa-
> TxE`iKKX&7h
> zfbo}p7R^PsvWF2Nw=07%JZKr*o6xfK>|qYaN~HE9B|^2}8hd+MLf>rU<EQ+O
> oQMpF
> z$%Y62y85Mpy3|afF5I<j-voSQcps-+5W=#(#dupA-
> WIPjHQ`cR{XgQ~2R_Q;+8^E|
> z8(3gr7fmFU2tlBtK^uiC7}0=PMN8^tCHVhu5%;corLe201QIvVEbF$|npS&lFVsI
> 5
> zD{ZN@f);3?ls}f*Xt@?OwSk+qvu<up+q6cF<oErandjMOlW6Vx{@%}<e0KMF
> X3or<
> znK^Uj%$YN1&fF_KyG%QHUX~O;&t@}5ZeGCEF|ek(_b)&KcEpl6zC*Hzf(-
> QT@n?nl
> zp2j&TP#>~tKnd$o{BDsvj15AnbsK_U6O_JTBnBZVc7;v@H}!~#@8CD=KH#y1u
> lGPJ
> zcVe=5Ln97Z()_tUsE&TY5Ml>}Hdcxa7lju$CP?DQCq!0B?E6{XW97SF?Gt^dHsP
> 6U
> zNm0W9!>F+%eE^C{G}?4&J{Vt-
> YLGpM0EXo7r+}mOXm9+j#Yn7c$ECA)h5IsmCz_)`
> zK*q{{?lCC#OJ7K<--
> 6vdEUPy@$*KfkeJU7H&y`wE#9Ns<DS61r0KUSd*rcRH!?G1G
> zaGyq4lC(Tz4(QnOn*LYche2HC8YyIyv%wP0tC(?0vX?^W3{@WBeQi=wqA}F)G
> CtW#
> zSaNB3K=u+_PE|lh`ui}alj^noTvxC8c0jA+e%C)hS9?!_vbE!z4zz|f>+zX1j{}p^
> zMqw7PgWsI>S~S!D7FyksP^W51!J73n<VEVCl!NKp@S5o}7xh*Pkt)K)smPmu
> oVAt|
> zlIb%fy%Y47eh0G)huzUK7)c8H%W(b{(aRDZT<P7)3gMU#zNwTE%1*z4G?)%p
> Axn_h
> zRi>p68NpQ;!6~_?M7ni5cYAs2fF4KMsprm=%OQkfEA{)gaxZ|pw62W55s*l*h
> WwNd
> zcz*&BYZiom&qmq)Yl`ilw8q`nAwfuWp|v>*wXIVW%)FBXU(?>WivZY`p+ZISfK
> hmS
> zH|*~K0|k3uG6+(;kyUG5if=a0t!_-
> }*ciY#YR4^Ldg_L&cf9xGXbXWu8@(xRf0R~<
> zUY5t8N@dhF086;`<nf9!<~33Bf+lHWi6qEeU?+f4lo7ygjm?x1!NjpCOx9H(DD(
> %D
> zV~dckR{hwKj<(t4>Ziww^-
> z==Vk+Yu?G`_H?P7}`q{m==1wfd0VZdTf3!K!Ixzl>U
> zE>}CoGUUt+s2IpW#4<jg!q7k;rWVaS8}JaFus6_Mkrdc?TWw3=f1%Dq2e~qn0
> Lpx_
> z%>Wbdp2nBieV_%h56(2vlVq^`xXlcfAPP#fF2;BIM@&sF&DjiaWP{0J;1ar&_>r
> <`
> zHEHc=RdkX7pRa*^KWlp|(VWdVgFSsr)nz7j>!8?qCXb1d#|J+X#Bwt@Q8M_
> wj+*tF
> zGjr4{-dPpJF(%f*we}odM9Q*VD`zHCe4tBC#u=BK3-
> Op}U4(C$hS+xyU~mbpAe>^f
> zhPQ#F-
> 8h4jtD|XR6O*k1*34YuovwtuCiJT{#*ncK)`{r%Bk!T#2ahP7#TY@vHug#d
> zw(4Pnp(W0t+nW!p9hYooX=5b&=zTZ_@K`9AOtEYn1Y}f5J&)r{@wSRY^R;+25
> CRWC
> zLe#3S%|W##BVDif4uZ~Ib6m2O4+Y}qIU&!O&(@_FNO#ozf=9o;A}+91GhGZs
> *<;lc
> z2`Maks+ikhYRA}sY*E463QSsr?R8ZoVedoR52(6vDQ5E#w2$fd3xqcD9vutfJ{<%
> t
> zZ8t;OE>8l>tw3D)34+Uyjsawu354WW9_T0!bS0Xrfwd&_#!4NsbTY+=+DMri<K
> _au
> z?~JSIf+W$6`-OCr5R?ZOFR<s_!)8;V_FzaOn|OUMHUwTlPqX&Euk69ozUG-
> I3lFGX
> zf1<UD7zH{K&FAqUCEu<5midkkbfhjrs+q9MlAdLW)SH-<;Bk~cp~#3-
> a|L38sni_&
> z)T##+Qd8t%K}jhA9=LT;@f}in41<8cF3JX+IQW<OtYbx#Y-
> N1NWUci5T>kXcgqxU>
> z*#`%;JXnf!2;WuXO_lW$b~P>!M@P6}uajM6C0p6dAvE)oAPH%oPFJ*;mNcC~
> RrN>C
> z5wKwFWaFfNg`;zNZ3+<mFp`VYLuP8`;*`&%1zdB3r$lN7vXAfJH>YXWE3!5lF)B
> Mv
> zuTIExYfaM{@<R28X2&#b!|Q39xv1HVk`C9PAaDM068Paq{g`$c0`qr0{Wg2>#<
> ;Ib
> z9N*xbZW|mdJa-1>bnYY%6c<&ye8ttS1^8^m$9+Pz%a70H_<UtTwd-MoJ&w-
> <_}quj
> zGx$7*kE^gSuTcNx7Zwy2x>J|9eugwFk!C%9*WfpSkIVgue|d<_&q5TepER-
> B^-H81
> z^BL^&mtsq}q}ug)gdIWH0lc4bVzq1LN!6|{JWm14TljqspF@*T*0{WJxMX}>_A
> j50
> z1>@X0q;TAbkwAIeNWOYTjUG2{%sB73abqn7BlWXbkKi~`{798tU?S#lI8ov^2k
> !hh
> zaJO7Q+^}rHf<+GfdF9X_7fs3W>jIvZeAq{O8jo;TVM7^E$$T-
> 1^(OMT)bqlRCiSoN
> z*Kl^nVXb~hoC8>B)cEy=EA9g26<?Bu*N0gfF<QTlV#KNj*1K!UtV3(-
> xM6S}NP+qS
> z$SmjbqO1H&dyWcQ*Uz7=pWmuqQPNYuOJa&pzZ+OTM;Vu4VDW+ou&N>
> qGJj}Y09wd)
> z9&ABbmKl#Jv`n262XW3hEk=n6W6@t5xj;Rkfq_tdW}{sl?k7>KLRsC_OOi05C{5
> vJ
> zo%o;g_HoR)mWca%xE|9MqcFj`UT8J|;R*b@Em#XfkMm%1(cBjOAG|MXJh$
> fR*c-_O
> z=b>d@E7;vQhbP=(`+Zv%j=1~^-_}({sp^p><$s+uFzc=619z3;+)vV9`PUVrlE=zF
> zs9fH^Vs!lHdGWRxm2a&0Q{@}c>+sevuMLJPkj~=sw#&mpMRy6!ZBOtudhXs
> r#^+@U
> zH}XAvtxMdq(D-E5KPvY|Aqn)<0@)=?Qm{%{vSdjuWxq0L>qp&ija40}6~-
> s?6S1y=
> z_IW>f>P(!3`Wj~&2@aK}0xB5368SC}c#W!}yChB}^O99%$S{S|saIS+(9Wn@iR
> w+n
> z`jKHMoWeqH;I$@1V6O`K^;f>4eE}hD(4%wv5Y3Dj=H|tAa$R3Y?q~%k<s=h<R
> Rz=k
> z0Z`nbsQe`iGy>g~`|ifNt+QZvW#5Y9b!weo?D_Qfm|>ug==>0m^FWc4eeoypS
> kT6Q
> zoK%I28nh3rUMldD>}mdouc?WtfCkX^E=dLY0LA|lxH)SOy`sFnyYl=MAg8`<sEe
> y|
> z|6M-
> to67U{t{90?Qn_nIZ?bwXB>19;YdVT_VbJirZ8Ef6=Ywr?Yz%UCko+Ls%dEY`
> zfz1qJBTeBSc#WyiN>zMfTL<UxsfSN9@D%8};ToYui*x8-
> &~syV2@tgRC;H>__JA;4
> zQ9q6|*7Sq(&N)?c-i>9D)R!bb-
> @vxmS4b$<Y~Xb+18>A*SfSGgUS|Wvd|=y5{2`_Y
> z4uQ*)Cy~a&hlMVF)7%CP8HQNQ53B_6H3N7>c#j52_BG>7QFxnqJKX$M^y*
> Zq2Z?GU
> zdC-}*AR-
> LPZWw4~PN2})&|=~#)!K{iP%zc3@QaQKF9&Gt0IsQsVXe!^`0lZdAGm??
> ziW8R%6feSP)x<5BEHs#;nh6@jb;tNgrTXxV)e-
> XqnMt0(f#2#PYm<EgzcD#A55%5J
> zrkHfgwR4)r{sRxuQ7uhl-
> @`*@6#1Y;CO^;SoYj_kXe@J1Jvj|+=~`Db0yo@%K;nI4
> z*8DZq%qY+uoBRfN8bXU+uQr{co0L6>{sSj6igR`SS;ugWrO!wJMwto1Vb11?F|
> *Sb
> zpSQmao$PDozF+vtJUaSgA&G$K`NVki^Jv`gB1FM#4>)N1G;K&h+tL#d4Vkl6Jz
> 614
> zz9*Ptc-
> vdFXKOe1Y(aIOi9E>2CmCsH7F5@p$aX}6>aPsXL22P4ercmRRjc0A2R^ZX
> z{b!0dF#S;Zu}i{zF5qRC13d*tiW+M&Jd6zE^Z1Q*R=Dd;j+1scqF^0hpYS=2@FBz}
> zi}_ty*B8BgBjGCpebJkfV;PA1{LU0Wn2;xn85vSuD`Y><{YU4->-
> W2&XARUHGzNmv
> z$*I8MV8jcH2~a6c1cV0a_Ji5O>Y*3Mwzv=xl|sD!kSn@Ks2Gi$t+smuZ3%JJ<B$
> 7g
> znHE&1{jaHZzk9_v%w<?`y2`NN^izH4hf3RxPV;B3NseU`SJw1Fxl_!?kh(#)Mk25
> $
> zUcbi`9WhY1$5J57+{iX(Wlv6y<zuZn(}Hf}4L8xz;FmzY4JkIVXM@Ub0c^*u2UsX
> O
> zEmClJrgoriJ5E98=bVBDebUltkon3*<G2M3^A)krI2LXnVxQUjG3SBQv+qID%$
> ~tg
> zuntF7ZZtnaF<6Z6t`X{M0Q{%NC-
> nF!*?4$2EBHB07d#d)_7Fm9)k#(eln*^167)cz
> zr<~`+v2p2M$zhNWE<&6CzFKtw^noHB;iPy^Ij_ob&xLJxoa_EZtYn})SV=;FmY
> &)g
> z#Q?DF0^T{+oviDwtm|DdJ>19<xfEl7VtqF!kXrSVSD7=eETh~78zr1QkMD+O2n
> ZwH
> zl>w$|aijw6!4Y&wt<6ovBlTBk{CD*M<Nj1pqbM$*=Hoeg+%Gy)4-
> 7U3*CuL*4!}Hu
> z=?UwR-
> EOVv2&yLxDBB6UDVBsJ@(~2ZY3K@ci{9*kV$%}p5MLW^&*B<!V==S!*H-PY
> zlEwKwCl+IgOG3Issy=dC2~vah>-
> zVB0ddF8D%<eGaL*alE>&PM=>X|kg=>BZ<I$c^
> zO>eLVR{OzKlU1v%5kA$BA53ly$z}X9#p|>1nh2|FWu0tnN5xH?ZBL=@mJC;$-
> i#Iu
> z)b*<`fpnb}VP){g@pCNfzl<Ew=|AA(#s~1-
> $SMcb&AI{pC9K~@uc5DpV6Aa6_@K9+
> z=(JiD_{F=YE!oI`p!##U;g|hc<AfS*_BAQ&%@-zL9qtp_R%hPlTuSmr=nD1iyR+-
> a
> zh=vR+P6te^-
> d!Onv;pQfG46oMKGFcR1O1rGZbFcjLCjp%9j}L7XH;7Sb|O|RTsoNo
> z+ztC*V)HgB+(L|8k)VazH}1_r4R&!AD&L8khSaDrv0CgzP3F|)2u@-
> oS`(*?TwgQC
> zDb(fA1k2$}@_`P)2PzElQ{aM8r@?25h0lmwe7an*YU{9TGAi>#vPa!?*GB`13R
> FWU
> zb0D|%%TgUH$(1@u=1PpAka`n$zY7EHRg+Jn_|O9m6%4aO2a1D`j4A^?m<*&
> Q6qF)v
> zat4qrq^Tm+9b<=KN7AK^;4$eU|98llppVAx&4{+;%U+nVV!`mVbYBTLPb#$>
> w2xKi
> zzUHMAgz>kpIgF<UJYn)^<ulYI&=s529CvS3$j>>XB+-
> 03qT@UG4H9??X>5y8crciV
> zVkl1|A7|oXD>3uNz62BFdddG~iPwfZNvZjmzEg~-
> RTF+`@h4$Hh3Q`aPGd`&`gk0F
> z;2Vk~ig|#EZgmtx<Z++x%Tf$|_=EHJ#pm#7;dQ`065bDt!khRt2VcpQ)EQ^Y*n`;
> 6
> zKyuC#ypsE;u)Tz0D5(C59YTsrJET#gyo#O7bs`i!n4>Upy$dXyv6MPK`i;c$&?uR7
> zdOu<4RH=C<p7u2_MoDfw!SWfZOuV4(5*Q43fnajl_=s034>A!?9SuyDVw$~q
> $mvEr
> zAcW2@TKO!yPx7#X-
> |qTFNr74C4KU}H)HMi&Ap(CwDo`s_55a0mvYB~8Cwkif>_$s`
> zs(O68E~+Ij!v*}~nE47&DNMFll7vfh<Y)4;ZWJN21m~yAvGBq|8|-
> ;$@+9JzEHK9k
> zFwb4*P2SO;{8IlwC(kv=*@rB5Jb3WRs~&Vu8|buy{@J_mPY;BhrAax<fR!+|8
> NUDd
> zYEl)~f0&kKCjJ$iHd4!hgIh;F(psFQNt_`BcGvYMDwie%Q+?XPft8&<=Xf&^uvpD
> @
> zlsWp<B@$T~>dY)G>p!!;Ab$TO{geMM(=Yw_^yr`DLi*|UBp1xUY7Y9FWNk@
> EeHnI@
> zp!Dl-lEQ9oEzgzOYn|?@bE-
> A#!D*sdyU5(20OM&!?QjU!zd~c)uif%MEQ9L8bTv%-
> z$z~|ys&B$#5zHBCaElIXGicHa_NUP=o>?_sHTJ}hI3(myjyJi0Vy~CS8QGa)2cN9
> v
> zc{{MLm9T(-
> UIh*AXl>Kpb1rYJ_t4outZ3V!IoR2+ff`Ok3~|O{TLyMCAW|4>s^&0j
> z*U53oTYf>j3eL?%tSp1bX7;~9TBH~wz$9+zP2ACE)%`FQF1mU+e?_(?ZFCR~0K
> *Qo
> z=Tyi*>l+Y^!~UtjK~xO>fG`al5{)zYgiONG3HF#tUUxWAVCa%(KTPg8swyXfbf3
> w1
> zb2Q+=5{ylDF#HfKiyn`f?5mnaY^3^`yE0L*Wwt512dz%^9vT`J)MzC!kWVgPLqo
> MV
> zUieQL;^X&DgL7%!o$vwB(oeo+{nH9Q%*Iv?BD0pVKQPL_RGPf4Y@k!h%_2;E
> $q<oQ
> za-sk7B{*Vq1r?^pl5ek`2mKDt8^sFMMX-
> }%HaJZ9=e$(W3v(B(cc<Lz>kBIvde#&Y
> z#uLB8o0t4B`8G4FKfvsG3vo$&Z(ice#JQELymz}R-
> @B_&efW2ZWc@d!+%H_8ayMo%
> zvD**rKuu&~gqn=0JlXOnJL!vVH6Cw?EqqJvz1|XmfxqfI1z-
> (~0RJ3^wwmj~PZfPC
> z{avbi9Zor!1b|<n_Ax=sQz@Cn#;dJ-
> |Drn~MImeTw4Ec>%26M<ROMgrvx~2>zg&M^
> zdN!-
> E#GMGbZB(QJ$RGE0uxp@qR68+eC2MA&Pp6@K%g~S7KfiMUNw}wR{voK!P
> y;za
> zEk^)uMi^E@gJfvQ|2&*r0)xj<80qx9a5raCDzB(ayAnbT8p6A;kU*rhOtB?Gtcs1
> +
> z!CY$4|Na_S|C9hPY`30S$l|FB$1Ge~S5nWtIcRPYff8O5-
> Jhr_(dEKvqd~yeOzUcU
> z6m}z1yoq{-bO3!im|Q-
> n8kY#i>p`?u04%w%9|Z4F*M6341It|)rt}Pmnr0j(WUT5c
> z1Jis>)lw&(vME6$(zRU=keybmnj{^?Ejfh2h3o6wHRo|}Xdua-
> bhW502Sq{Ovl#7S
> z-
> BdE(aMbj#fw5R#%{mY}gS&HUX5hQ??vum6`yI2xvJ}h45j!YGxUpX#ds=9tgA{Z
> R
> zvc5PelL%<Re2mF8vpRDxre<-
> +hke3FU7Xy#6hkR?@|2a60CF*dAg!2fW{yQL)GzCW
> z^E9OG38@yi`J$v~#A`dn2)z{N8iCinch{;vqnm*@t?<f_M=8p;+EKVSgn8X6SUB
> {-
> zpA%#%uCw=v;N}qzA+XvjtqgQY95z1HvpNoQNBS1#E|duQcL`pM=x_7$PF7?{
> zf13!
> zHsG>q2F_vcN_l@pN|li^P#hJ_-
> 61NKgd{#h9ADO)J*zEt*0xRvNU(d49g6qmub8TP
> zs^(B?@hEiFH9s|7^%~QNUq^P8Fm$kL%cBDc<|#lVYYw5z!)P2$F4S>NgR+kpf
> Paim
> zUj?A_Vti?$I)o-Xj1(48aj-#ICypsbr*Wdel|DtX^*0`YCd(DQBwk+zm#c8(RasZI
> zW^{TKL8z&<x;I&O2&ErJzWO|rHGokzDA1KY%&*_z3kpG_%|tUCa5O`^qZ#Vj
> Q`N^|
> zI$r#eX@*}Sr8L7HHp3pgq0W0O&nRvoRj3`g;hJp=i#RkZiMcaNGK*P{Sh+A94lk
> 32
> z)6_JO(Q@fA-45=|DVgb+sk)ynx@$+Hb&A|D4P(&;?-
> Ww)tW_5Zo>+?=4ykj@Gu*cg
> zqkoe#XX9mt@zP%?&W*!52zn@<V*!5@|7Ou8c#kWLRC-FJr@#Kj`hJe-
> 7*t+ppeOc8
> z17*%Y@IegZ=ybH{lyI<sE9dYCbWpelTouPouewcEn|h0Q5IffL8Onx$0+kc&S;0
> JU
> zUcHaDZ`gx*EeeYt7&y@C&1R?lnYWODS~r#5STrJE?)<UlZO$JY_Et0I4qwh4k>
> 7Lf
> zm?ljI@k{28&mwH-
> +`%Fw|7r1gy)u8y;RaPi&mWPzf#MtOse|!ogTYe=gJtTF3}hmZ
> zoP5pO0Bj}#p%iSTqS+xbCIV&g`ckrf9ROaB&BL-<byJyP{a8WwYStg;xTx!`tSgP4
> zMe?D6j~*9ffu%u}k~BGN|1zfGv0?vU#>x>kP<*Y7P)sj|!BH>x$6v7X(QQ3xES
> $l_
> zq`JQ5JiM6utqjh3{=#%ss>zvCkUvPaH7%EIl^UjDab+@?=g}r)SY)JYW;WJ$!GdA!
> z-4?^@(hTc+FPM=E&m2Sw+$2|t(kVWSsO-
> EIE(39kI!9k;NX`F%2{Em7p^Z90BN{i#
> zlcgAunum%;C<>ovoO6@`q;Ds7HK;`lEie?2lN%H>+<4nK1N%A-
> c`M%SQO%QNV+Mqt
> zTzI<>eSc+fSpxg9m@g2veCpWqS}um2s2T%Tk6NTi-cKexXaI4%a-
> ^;Tle{xh74~{L
> z=CDZyhMTAUUAUO7CLXQV49_teNW`M<c@{5dHCZ`RAMi_<8=@}MU~~Qd
> bLnU;Y}X^f
> zzWdoJ=w^L3tO8X-
> @r~OKA%ri{OG%~=^R;m|LD5vaDFbss1pt#RjETR<7}wfK;r(OC
> zE}&@J!iRiy`mIi0LEh7!kR+B?SC4N)W8ebV7+(NmFUUf0%vz0xB6rgYhIb*4aivt
> #
> zYsQtZI=JOIlTr}9_4L-
> N+y9qcS2Tu~utDWcUKom;<pB7?5CE*+W;p;(8v=mC+_N13
> zqlN(B-1Fxh0IGX14ke+;*$#kxg8)JiIAFD_@XVlC_}C0ZPICaX3;~!Hij+G5ZXE(J
> zBNTyPYZr0R5P+GX$mtG%=|cc2LXk5Z0PZ0GvqO>3IRO4AGq@2-
> LlKaSjl=FC0CPf-
> zY6rl^ApqxvA^`_L!w`U~P~;*9zzstHszZ^B9RTMK0azG{EOY>zGz4H#C~}DdpkJ
> <L
> zcG6og6uHy^@YWE3#i7U-8~`s30k|?0S>ynCYzV-$p-
> 7DbVAT+S8$*#VIsmR10<bg`
> zxy%7@_7H$@C<1}o?yTY=0Jn!Ca~%M^>A~H-
> JQO+C0q~n40MSqc4xsHKo*M$NDik@-
> z0r2n;fYqVMJO{w?K>&@r8^D!9k@Foei-
> y273Csl!m>EN0S_G!b0plJ5^N_&IcffS2
> z+%{?4y<T7zIAFF9fq6t=E_A>=Is}Gm`%q+t1135I=5c{J)d3S60<%G2CSzS|@z0q
> <
> zV4f71G6#%j2+StJgbQHW>i|3Qr@__VB4DE|Fsx$1v0oYlh8z;&!(do}jq?R(gu?
> WP
> zkh`e!hMvY<tES0{)WZcE)QFI0kGBIbe?dd1^6da7f!6OY+hr~^NnonoX$LR~G?2
> fx
> z1CRt7r=QvHETk-
> `eqaYM1w7k)+YVqMGiudCb^w#iguR3vz$6v$7i|YH$?RHnl^wt&
> z5b_q<0ZcLn>j67}NzTLl$94ddR0UPB9l#{jA?3CMm}FtC`kSl^tp;0!^EY+?lLSNR
> zRXc!57T2maJAkEJ8B{;C1DNF6kot}tz$7=;s+1kTBuj&8wH?4D;gGt`4q%eoYt_|u
> z0Fx{as!QwuCW(gB96NwXR@JIg>;NWN9aJaS0Z8(21IbS1+hIu6!ch-
> >fXGv(5$@+G
> zhd(+yjA><5tG#v@({dEos^{!56nZ~LEzbYjVN5HdRIRhan3kimR^4TXG3^FPd$S
> $J
> zv@+_{7ws^n<tVFF=jyPm{x05Ky5tI@C9xzUs=qCzFa)^xJy>wi@nrm7UY^+oc`
> tHH
> zI4rVdqymCv@fMB+2$tGCl@TmyeZ>K`WjjiK(TlHSeb?WfihS8h>Q*zKWkQ@=
> (Hfr;
> z%9+rLw7!^?Gt<272-
> XjJJ0JPQSCs;ZK4cfE&*pUWdnPBX!TPMp=?gk1j#8+O<~j2{
> zfNDUx);q+grEhEP`Eq)sD;R;=6W2e$Ck^yNSN@M-M2cE-
> RI$w+jQAV?=L`Yx1S5V2
> zzzI%(D5MxT>(crZ5v)<+C$~w34VvH3Z`@|1avSj2Kd4oc@l5s8sa7}Db#3f{kd5u
> Y
> znyzGVFCS~M?C464?c?)8tme^dNCj;VmTRM=wtUSLn=Fjv3?(BoVpnTfJUX9@
> P=tG|
> z`HaL4NAXtt-
> BZFd+5I?*gzUm4LJDflHM!z?d>dJ|D|#LhCLb2|ZD%$EbtP3Y6!qU~
> z*B`|)&!Aeb!<ZIo$cMQ`V2YaVgd`$@IC3Dsv)XRZo62VWqYtj#1`s(YQ~_&w^e
> >NJ
> z&RzQ%WWpm7=?X-*z=b@W`$DggIoE=z#90%L04V6GyIr>+uLX-
> h`@{tgA7TA+l!tCD
> zcbZAF4zuQ$d>C8-S5M_wwrkYSj)m$rsD3KTQ&FPSx+|s6qP&S7z?_F3H_-
> rI08iuW
> zMu|on)Iu9qucNKiqtQRe`0YaTuzjGCwa9}5x5OH_95Z)7-
> 5R+(yeB(wuieac$H0|^
> zZOjbZVmIKfvf$k6f&VgNi&|yauM=MtRPX*oI!&)4k5FBV<5eUt3|GS{zQbAe
> mTXSv
> zSvhG&!BNVbp3*tt4c5i#o6dX_%(t$~9{pJ1&A|%UTJph0V>eb{#SXz?)9-
> Tx2LNCN
> zhCKvZNO^Dw09IgFXxjkGh5%p%hC{$MKwt;}RwpG6fN4Vj%0iK#1E63C02X0b
> y4yt@
> zeS2^%un5D+WdLZwXV(ybQ$rCDw+*mi2*7Ef$YKY;+93etp-
> 7zr;QAo|Sm!|#XcsYW
> z2*Bx~2yDn~fYKoVXM`e9o!9^${%&wJKNpH%husEv(+Lo*!g+P<AAqW~Qi8-
> 2{;|b7
> zNIX~DZ!oS@i}af&(epu@AUEz7s|)c=Uh0#1X{T_%diA%bI8245&`R2$5WQ#%`
> 4I|E
> z&UYskxXF(mmJnohsYkeMkHux-
> 0~}noYoAt$fXm9Tw7ml;o6Axo<1$>9&x5(F#DmMW
> zXfC@4AmOOyvL#FYbuLSMYt{MBSuMp{lJmlTREM!v@Dcei%Ox{{MPHW7szF
> @VC|9-q
> zllrFr-}!A}`VE8lLT}~Rev56Ajl$vBML&{yvyQd?%3{}73|A%7g(QE9i6(SWWue=O
> zCO8hldrUN;ODe~DtZ0Il1XWsOAI;HAD~r8WG{He=FPmsWmsJ+}t!QRm7E;fe
> XhKh`
> z99v{X6MR}wJ*1;;hA;ZAD%)5JGFm(84J9j7?)=%Wf7<j<FMniCIAk`FIAh&YgsI>
> e
> zuz2Cp*noxZ2Xml17<T&+D1s2wHP99x3aV?~l<^6DU}3t9)57)Pva!_7McnGnjci
> s3
> zZ|#wrt<d~%14fo|Kg}r2D+eP>t*AU5m43=Z?T;)Q6!nS~)fNe7qo_qzKenQv-
> EJ2T
> ze=x7c4ZOYB@DL+w+*aSlb=`e354BtKP%k7pGau5(0G7GjNN9vOgk0-+)?-
> ~=Ukir0
> zaXp!ND+QZ%a)AYO?Y>>>Dht!okS%tl3hydRe+G{@JJJEays(?jTXT7;?kGxO_Q(
> Wo
> zB`7!eUf>=DbRc+In1@sJr$dr}^IQ~8xuH)COZp^iK^`uUS_^$XEPea-
> =9OhSGe6PV
> zaX}(kbFgt2v4zKQd_$if;`s(OMHaqgkVIfH#%Wf@Erf_L4X2WI`x|#R;vuA8c^wv
> A
> zX)^~+*T~{K*!jZ_xnyzSFj=$>n*{)~SzP1Df?FBbzFoGj;TQ=IQ2Y1JUkg;)_AbCr
> zVE^8R1|8nEw^5#?{jUD__Jdl*YQNe4r2USgfm<C4Z@QF~bTwq&$owEoM1
> WEuQG>Sr
> zV6A$mhvesttd$lbD5j(RkjL%tnl{tkKs=;g(%~E;+uD#D#?F5*Q#9hke76<azUDY
> y
> zu|F}1ofrNEUcw$3Dry;yHe)pCEiVW;psxGL(N8COLG@oEgmD?kOgWMp-
> )X>iNTuu;
> z@P`%-
> ^~N+~YSl_RhMBb?EU0eKVK~aLk7I`88>cA}5^GZt0u$@VCfF>}JlJMyBsS6@
> z4HDx?tS1^tHid*R5sODNaJ#c*GoD!yTqKy5B^)gV|E>dZfI}V9fvghRe6Rghw?C
> w|
> z*>8cip!%NuMs3dH`c2Q*Pa(hb27CeM_)Beg;Ec(Z;4}7Q>~)D9j~TOF&zOGzh}
> Hgo
> z{Gy}%(a8H6nF0Th^FHYczHHm%mNig9oJhV@F-
> kTwbW^;zWi;L#&9JY5ZNO&cIjA1k
> z4OaAGm(V)cXr@Tv*B<qh`_u04lpo3N@34SD8FGCi3ars;;{dE;1O4z%fffPX5L%
> Y6
> z#x<W{V9KBVsmp)1(=H#P&Y;>@_I~QW3qEaqu5sjNp908{A7uaQQ|C9v<VRL
> J{QZKq
> zZ4yh7`p;Nm1TeG|?1(zmU2Xk1M2!0ncA>}6bcdwrtaX!Pp1`ts<jPsXS$dQ1b<j
> V-
> za|p!7WRD4}UIzu+tvawE(34tJk&o@C%+AO?;h>Mxq@0S#3#kjgW#&q4=iS5s
> 3g(90
> z$?WW8%?d2l7nk8y*ReMrYVZ!3wmQI88h~ne4zdoH@oU>SQY;vspa(j{yaL;Z
> ^1A+V
> z-
> eKPX`R?CnzYQTMPjnw8awO{~@XCQ|6wm~s1Mq_iAtQ4Xa%Hv<)_1s4_JmC-
> {~@Xi
> zUCL$7Qqm`ZUZp71+tdg1r1&xJRC|8L9rnWx%WzF2=s(O;XCLD{<%SeAe1AT@
> Q}^c&
> zn9D!uPw&dvcHhkjs%PP7B)3DuLG=wC=;+WL;SFq)+&;bY(cC_zrsWg*)a#4Cic
> E$!
> z_kY>VJ;RSaZ9~U8P#mtg>uxp8JyUcfy16^^Ke1DJj#YQ6lyal9l<=^f`tCAQ%3e`B
> z=u+-
> =mXa?0q)vSoD)T{|I&6Q=96UZ>hqjsH^KEAEPx>==e0Jmw?oN!)eLB$5ojbFG
> zj>oXzG=^G3k_OFAdXtMAp(bB%=Vb+kL+ZY4Uey@u@LaNk35>G#x@?kOOI
> dqKHpOD3
> zsOy1QS+ZpVdZSjIZs6f6s5&2lDcB0~dJ=IVHQvP4^x*m^V5rk+CGOwF1P<0c*>
> pXP
> zySR1(_X*P<MwV1zf7Y5yr-vZG3Y{Lt0JM^Ih>-
> wibVLQ!&;KN1QnsCPnbWUOgjnVv
> zi;jeMJvbBHa%=ipd_1VQ?>Nqvu-
> )lRde=jsCQrg<Qu%I>T1Tz=`cgw%k>^=Z2>?QB
> zlBrfrhpuvmbjM-
> DB^EcrVkG=#ZW)_chSfQxKpaj;Abj_f?`MG_b%s?)p(%t6@x=ia
> zh-
> JK0NV*I}oUN#}Mj%1>;xuTK!FU+CC#u)Y0T#c{#bP0`&^#FNtX?_whCSu45~HB
> n
> z^d(c(wW5sB!)TVlqOL>te224;FbX-
> ETS(7%M<E=pg9^FOD&#~*A+H?MRkaIAPvUs3
> zkrow_ML~beEocJ^B85JR@S*+o*3G6e&xzhZ_uDd4j@_gf^}sM8+Z8Axom)h
> ZMPSCd
> z|8ay5t;#B^h|5e7q?dxhRk3QZ0ePT^?%X2!z(}*>YzXxgTSaus+FsXU!$*S%!>R
> ?x
> zBZ}aG7zcrGU=geZqlebwxtmNwB}@^l#XM7l-
> 62*jIIK~`UvrCCXw^bS{g7H*W)<;S
> zs}}vVz6axsVHSo1uOZVZ=TFS14}9R5Pid-2vqS9(gSNepkZaWnpn`E}YaSf)F;|+F
> zA(^@Dy?R(^k-rF?Ydb9YA2)0YncuIp-0_)H7^Uz}-
> >G(C5^~%#beL|8U}3ntNVXwv
> z$J{HO1FNC;7H|@<Jfsq=N`2{q?8(8f4II7_sU-{b+_{p-zFekLRbXz#(lGrUuuEE~
> znY-h)8SRwtY+djjj)K?Z77T0KD)r9!j)HAqT`;pybFG5+phckC?NnP)Q(i<hUHG(T
> zuP)wC1G((g^<G{4a!2t4^K<GA7i?APHfQlRur8iisF&uNdbe4{&ynKW(obW}Oq
> =#t
> zF_8)})TIr!5;dD)!p^fKo0Eaf6d`F>C7T1j2fj`zsLoISDw`VWH@Tu?@I5^`I?ZV*
> z9YbuqzQ`4WAuqnCgnKbrfbt)9)Z-jyJ=8PvtOj&khxG`y2;h+}olliRonNMKzd5%8
> zi$d=2ygxO@5agSM;M4}j1b<UKp%fMahU(Yl%d+53WQzHL815;BQUvOy9@k
> wk^A(?r
> z>6e%jj%@HqkUveKjqP$S69ENm3c>&Qe{x{adTtrg=G}E8;OTV~_Zd|{GcYCGp
> li$Z
> ztwpVuR5^Ohl$EK?OvhpqHGxNCoV14>8YBR|%R<0UnGlX5YGCO0DS*<L8*tT
> gFD`hI
> z8sVsbXRjO=D-
> ZO*<2b8vA!bP2>Lxzu(&T8EkM_c#l&Owqs=LRk$?%q?FTTip*=QW;
> z<$!}wSL+XsYOTP4a|}X&%~NkzT3v}Aw}H(dL>B7wa||(Zvrn4$Sxje1+^B{#TU)
> HK
> zZ%Wt}UWU=B*73z&r-FYpc5~)h0*6E}BHo;=*&I*9-gI-
> ke)C<v2iK1yHEj01aDU%@
> zbSm5YD1O+f*eF}gi&x_JmW)`7BLJI7H#8h2>jekfWF2*w5?)mz6nhp(&+5Zwj5
> 0@M
> z(PkCuFBsRhKVlm=d@WK-
> 7OLuONd(2o48h7i#sK3HSm#n~Qr(Eb>Mac~P(sDne+QZ%
> zgH;;MCoMGDWvIxLW*DMR44Rb=G~dQha-
> fN=yb5)x6HOb~f#zeMx6o`H%a*Wtd2#_n
> znNrBgr6E;q@VrVufS#XtvR(aS*qj?IJU0lQbsONDKn`Eys^kgMoYX&B&3Se%o;
> agj
> zp}q?~WjCh{tnp+P>Mye`Jm2uLDQwej==hU$rAf+W>T%%5_WY565Iw8gHJ*=
> Kcv3V$
> zWgoY8Mr}O5;K1`M7!Z#3lyl%8z^$8&rw#1D^Aa1+Gl@j@^a}PS*zJqfhig?YqK
> M}x
> z{??a4>DWSi>L}#e9RNKrH5%$}Y5Wp!ELusw1s}_(eSEGy>v52;aQ2zM*Hy+dW
> aGg~
> zFnuS$LrU=S4qi(5l6#VhiVIIjos^SvBeF_UH$dBQM+1xa0FmKcX<Q4B%cbCw__
> -R7
> zYQDlXmIoSc!3UfS_|R`e2^@pLbibyAFN12xo$;V*&B^(FIPgrri!UKCZ=M;r-
> pQo2
> zN39+t7eI-
> RT1F}0Qkv4%IePG*o_vkJI@pzi(&m5(**$0j>mFnl>cO)tO1qOt$YBEA
> zDQq^sY&peIU64k4p@k-
> {*VX*RGl6J6VxjqnM)MJz&J@G+DdD~oWI%k~f#&pFG&_mr
> z!(bmanl`XTlUb<FGc7dt!$aRNXrf^|fF9A@NC*zsL1?bG&|I(4T#w0K4(Hft{)Yq2
> zHCmRiTC;;_z617QqiF*>(41?dIYrP!`*|LdUD@~E*Xwc+5SC{c2}3H;7g8sh8vNd
> a
> zXfno9*J>OR@i*R6N@<I2{g73Oholm955al6kscd#TT|4rn9qwCz>Yx;>9ImhcU
> Hm%
> z)|FruDhdaYNQB{cE%Cs43~OLV3V=+qwiLrIr0zfs+1zJY$PQwYEf%I6?Wk=F<as
> %@
> zWwW0jIxzL+VtR;}-UsetH@6L}F%>rX^5-
> l}pBp&{Qz+|!DTS$!`Z+KprY!_wv$`#Y
> z?yh8;Hd&Z9X-u0E@R&-kzf-~<-KN_dnBJo2b&D_nR-s;<<-
> pVi)|fI2Rc2%A86H!2
> zNR=8ikBl&A3jGQp%P?!O&}`6XHYDl}8kxlmvo;5sJN1lgp$VC#LY?MB(*}0X?>%
> rl
> zsk{CrA|YjuSzBuLKc`5e9h!`4fT_corOm@j%_3M8=(u!=$z!f-HO~9`<L6ecg-_1a
> zShh<|;FFWjQW<$l1om_L6V1N9SlGrd9rgLMp1Q620IWh?4d!JNhz+dk!z|P@r
> (5-T
> zxDfRj!rdU|J`E&E9JdjG6^2w&Yza?5ca;NOK5KOOWPD9!#go?@=w6VE?jEB1E
> VzS>
> zt_`fwrG%qCfWKAU{72nH7wiM)nflW=p}o@A;%hhrqYec5tP$i>BG4uq$+rCTh
> 6BOx
> z=&9RkPwY2WsL@UYZD0q2SJ?>87X*3q%*+;;?uc$s)uAETpeGVym<FW>6s!O
> Ftnn4U
> zD1q(twv}zrP6xh!2JIqS3txbt|G}y32DO15_&!r^HR!`!e~L)#qHFSg^tvnK1vh{l
> zge*Ux<$}Nrh6{Ps-?&OMT=f6#4s`h}=!#Pk+#(&X-$rx|=l!Dt-
> 3xNj1sM7tOu$Ch
> z2G-
> ~b=l$R`3*Dp0N{}n9tm&tl^*)xH!Nxlpx%9CYF~VG!QlKx)38<{=Uk&GvMh&cw
> zk!slyvw5H|sCc<3JEtD`%jwhdA<_~$64KJU=sl=Rj2w13z%!?QjHt9H2XqEN)02q)
> z@Z!%ma-
> csTW%p>xhC+nq9N)&p%g@K_pJ&5ftNFl0U~Nrlf7DZ~MF#+@P$94_yJ2l$
> z-LT9;ZG>A#J+KnGtmOQn$6j2j8xe}#L5u-
> Y@mJYEXeb`<6@n;wq;FsV#KGCP=!wag
> zjX@k?2XXM3our-kB<i-
> r>$k8Dom#m;qYJAJC+F4yU=`{sU{!V<Y+zjnW}$uuSB<(3
> zzhEht-m-N_?vL*}{<Z^4g&K+;+bK0WR`4?JSkEB>7}SCYevCRHr_6ooz;1XqFslpI
> z@ms$5*$oiVTX!ej>x1eXf%RrC6M1`Y{&bOhWoHiFXfgWXdN)nE7p`f`GpCAT;
> 89)U
> z`HmV_XqiIy8jdUK>tjWyxBg}<ThGVmp*yNw9sgeK3VgZR)s0VKwAvMmRl82
> U3x135
> zu6EsdPql0Az16Pc0Q-
> mAt6j4J+jM8O>pRP<T|Zb+?Yd@VwQDod{2cIpz<wK_rGRx!
> zFn{)g6<~hz2E999^9$t7U5K9%@;GvWXTqq_W4sz_>^Prap2km@aNL9m$Lr9
> d;uE~o
> zPl9sb+9+BHEulW>dnR;}*aZ@oy;vo{Be5)Dyj-;y`&;&*UPHjSaArqVX^H%-
> `(>%h
> z;&Dn#bBO`_6%Yj{<a%~cjknUXGD3GCxCo=p%UxhzKc7J1@V2lk4_6WgAechj
> 1Q&_#
> zt{|&{^2G~(oQ?<{khbn2z}6693b-
> 2pH_Ji=vNb@T#K^vAAMyfO+S&`VUkw(E3d=E2
> z2mpC^;m}%c!Tl|$x^0i_sJa6Xh|o}A4bWjGcmLF63g3gszn?ba{T37Nr?T!t1VEp
> S
> zM=^G$dP&{`AGQFtSJYlejMK#ZD-
> K#XYke)UHgZT5h3?Ob`ZJ{>_iRA*;7*4UPieB{
> zNxs$eVhX`>{QgaR!$w0*Y5Ya1cJh2p7jWRzd*NL^Ssdnp+Pe0PXX8>iTHDUiTU
> *q)
> z`*!egTq}NvZM%@#xMhi&*HOu3Sa;!~^EUyv493y`!S)dz7vkQTnzscYAMu^I@
> 8Kww
> z?bLbqLKApMPSFFs%|HT9D%;J1(bq(*jNghb9t2fiyjOMzg6bD-qUVEo8-
> +<<(*uBn
> z*(Vmo2O;?PLbrHG7R3<#m@E9?FjrXIh;dk#w7Xb9ubB%rfF<%>AabmYK{~qq
> bJpp0
> zPdgUMnQbt3g1-+z#I5aRIw+0>dc_#i*K~kylDV&G2cGu^-
> i3jn0y_ASsS&U=AaR<b
> zAu$O91J5R~%67OJ>mX5cTwo861;F+VSJKDdIVFMb`aL1vgEzZb_#WIj)YeSRTI
> vz}
> z&~P7j(L<)<K%!(-aQ75g6(PFl0bV4g(Bs7Hj?8F$-<)yddqMgH=EbDjq2raL6mlf#
> zb|jsalXR&hy-
> AYJPrn5QDoH74<dYn?xuYHdxko^*N^?F3Pfr9mW9AX$`TXdp484sQ
> zY%WPZLKvQc=ZqvUTL!@_OfR>JqHa-
> OHV=ZSNiVX>+7z$fBrux>!Cao60hn;lXRw<@
> z3#hAKAWwn{na*9{E~SvBg_FYFjEBb)b*>$ce#59Nz%WIlEl(d2`GNk=$Kc8ejy
> GyR
> zpbs?TjT$ZS3)2VpB6>QclF0YKi-
> @57g56p4Ed2GhSW4`F7y8M&YnepRj4?KI)@zub
> z!@veATpE#D^Yi^$T(D-V^kve5pkt)fN^Iz$vN|953e|hsj>*srfu3Q80PR{t-R&3x
> z+KWdWkj8NgU(+X5=@$=v+A6*1sL~I$^k7$MHCvb}wEyp_bUFkg3^nk~^jZC
> Q#Ab9S
> z7~^~FBC!tz{{&f>D!(nk(u+;6NiQ-c-ggR|a#$QYo$X!@T-;~(z%XrrC`b49Xbt!4
> zj<$FLPNgCL*loeBB-
> 0kX!*nkQ7v0;NBkP#%H8V^OhqGrFXZIGNEx?@WdJD)3dec)r
> zq#wV)yVza9Q5^+Fo2x5a7kC#87&UxPEMvKYLw)F8X&7lzxnM`OeNbOGL;OLr
> )fBe@
> z)A*dcyS{{WGaEKqE;CI*uZ9+-
> Kl<66rpSavor#3&#$#S48war>j59v1Ze^0o(X|Q*
> zecEPApNidDVep)E;X`a~yxJ9RtakM`RJ$&~=U#jc<5PyPYJ7f(&rk5azNy;f8vSv9
> zc{(DWKLx`8A>NJPLPm{{_>ms|j9Py^^1cP1+wl1^K9AwE0iUPw*^H0gDYo~EY
> 2WwM
> zTeK>KT>Ve|Ta<4T`@@Z8Uje^!2u3DTkvC?_)**JKaFBPbIL4BG2E$=c)W@K^
> u>KQv
> z&OIEN^l<XS+QXR?uG-
> 0~OClv<*Y9|fmfADT(WkQMRiP@TWLFmkGTaBoCyCYl@Dhmu
> zp`FcMDrFbBV%LI^?#-tVGZ4L`5#R7og1eF6()2Ev@ll?fTj;63*tK#@ax8ywc{)j4
> z%bXApx`N@4WKffaYSs6#xd;IjRIIqRs>dF1^G}7I|HV=|v!!&>M@dd87n@RElL
> A_?
> zmXxhrIGTNQhcwe<tC_w%HK&<+xCk3n=4d7jshf$3)io0x%`{aQsFrNuX0Z?bI1
> q#D
> z3)t-V_2A*<MYjA5@l9`c!hC)#W@8bX`l9)nUuEu53vj{!oZzz<Xq9!|6_ditHLm3r
> zu75e%fvd>2+>@qkOX<e4_eaSxwfJGJ4>OQH5pw!aT%bq<k0KPeTj-
> 5G+hj+y51o)k
> zCkXaX(s>H%yn7c6xV8lmn5GO1F&tcHcp{K%NajlCg9wU+2<ke}J!Z9mz4VS+-
> 957H
> z8&aFZqQ|?96-154YIntlDXWmU591f}_hD;CZBlr)Zi(})miQA0+2-A{>vp=jd=h)@
> zWF*Bf(2%;<m{>ja8Qp7)&n%aUge_{m0n4Fsu?DNG@va0H_LhtC1QjUXJ(#)=
> Wya?M
> zBm#%%7t2(TNzquTMSc)_o0$86*d5~@<9*4jwxIb#R^Wf@@<+EtM`42TJ?oy
> 9`3pP`
> z#t#h8x8kn6bt5EdZ=UZ7_q3INhJ(R9W!E40d6px6y8My@l93nQ7A2#<q%J}OG
> AH3b
> zFe{LgHR_euKN=|1ausM9+z509T>)=7g@swVMCM3nN<4CoEZ$Z{k#auF_WI)
> Y!Vlt9
> z;fHR$%Eii*ZsUWI6T)Rvpt@MV0ngiL`u5F-lAB%JhlPT#>1%ujBh{;8U(@~iT|6sJ
> z1UP(Sig-ZRjquIH4J;r-ArLB>)uLvmN+Z4s_+Cs9xCttmj1t>{E=mN6;bg4FaH11K
> z2$iVZxpscceWuPY^GPXY$fgG|V2X(B*XT9?2ISmdWWnUz^ubx!fcns`5~SUO
> M@Sic
> zATpf8zEM*0TrS-#N2kEkm;$qmmf#`H2OqAw#|1IPZTip-
> v;G@0pa&<kN(oMCEXPvP
> zhy^?^2EyhQp<LnjVa-
> ^w3@QcdrF2;$2>qXT8HW9`1l;P9`8Iur2+_Gv{=6deN^CZy
> z;In{!xO6HehVGN`<>FU2x-
> f$7#_6(WDvcpnLz2wABvXb6IJ^tz`E^GwEWuHR+cjo%
> zOSM4a<GZUu;d~2(9;h53lOv-
> e*wpqL7bW0kLA7fM%h9gp?GYsO>NQp+_Oh?9GT>c%
> zvmBnf7M)rU@R}P@!HBWu_axmfLz42-
> Uv%a7NEAF(EVCjRCuFSD;$5I2f5M+Rk->0n
> zX_N_6n;7*+U*;RL+8FD5Bs-#kPc1r`-
> Z0L5T^7?&o%I#?9@&l1M9`1CLBAnYWFikp
> z<Sq`OON#)quc`z+0GhxtHb2f<LMsh=bdk%*@#<?eb;&ZD6G@`h3x90>uVO`
> 797Pke
> z?1i|<iU&8y?{UJ)Gu?$OpmJc*p7_y`F`fzESEUEtAQ1%kH+Hw6MEeL{zuNzr#R
> X(X
> z28rP>P}4kaS%m};S(U13sKrgR6z&%k@zR6oh45Wg$nFg$Q-sO(?*t9FZ-
> F47SN7kB
> ze31$?09Nu~3w?K!bPVs-
> S%J!+3`e~Gy*DSm)_61@g*5Iaoxuw@OTpkUR5U?nWq6A&
> z<zkjn*8o^41${KnDg;+b81y}3-
> 2l_66Z1VLSaMG+C^ZPSvam#LNt#B%CcA~6_>p|G
> z@|3*d_hR%#tynKqG0vh_yw3W88^!FFgP-
> vHe^M|g_Kn{NU1`9|`Q8{jh)aD8jwP9Z
> z!IHh57dyu^joO0!4RA{EziC;3m-94&iJ-
> >>n!1%*h?APoB8~6!+t>82?u=|*7W&_N
> zW8#6vBhneW*cqr0+Xwu}?hI*hLvy+_UP3+&vcay~mZ$9=AB{*GM}5WUAT(
> uooRjS|
> z61+}fcN$EcTxcBK*+PVgg(dpBt8D+=ZsI`<4X^2jmB`8k-
> WaYvV#C7skD*~jJ(He7
> z&idDj&ip?}lWrh^8Fc-
> )%R!?QUj@<%=QiJ$pEAuCyG%C(9slW$P=z+$vrK)#Bo0WM
> zN#2P|JyyojW_lP}RBn<~dE%XNqlsuac)8UioJ#>K-
> ktS8?&N>34$uFFXKZo7&^?H;
> zwSPUAvGKx8nhP4{VNV0L05lx`^1L#Xe?5ZrF2=%e{L3%=i_~05V*XV8%S&R;
> @+XYa
> z|9QgdjT^0&MfVy0!K;x>&)kMVr76nl8AGY1gGRMI9O5s#b&eRanmnYp*sLHA
> Ln=ZZ
> zIS7Spgf7#`sle5&S#jUdLP9doEMq9YGn4>UcfhTSvMDDylspFDQYe=^^!^8?D7
> XR{
> zFSp*fbLPh)OlEDZcAuLWi+yg-
> SlPV~cKUGrU2<?}f9v}~hwblwHeVI#iaO`3%t}XR
> zbF%vTMyt0kvbgO6kc8&8vrN~S;bbvZizAtSUI6az9>l>gc@G|P&%(WtqfJqNGv
> yy}
> zlLJzY@C+2Mq9}lKuk%YO0#GI>O<Y=HoiFodCwCD`Cj$cOQmjIY!?PjhAx%g<Cl
> U(v
> zv@;@}6t6_lr|02&p1w;R!rCIl(!b1{a0L@nLlv_VPeo#$=pIAC6aE5nQXYpW?TR<
> 3
> zzAGoaaBPK)<rg^1CxaXHgMJ12S?qW4Vz+*<Ll<N)Yj+5e^5~VH@onWYtKYZP
> 8#oNX
> zwDQ#$<;;<p!!p%4xrES56Y|J5!4gQ-
> p6LUe+_vrqQv_%5ZGAN%<3LLt<o}!qa*<!a
> z`CNSgd7+!<20T%yZM3+JJu&#d(h)dG$-
> TRvI{Bcm!^$4P&D!gf+WwZO8MGj#>uc(X
> zT0`|%^Pz8N-
> G_J<U4aMd_!?YR`eFS2n^xm)^|}w^A1qtzh2HSPxH<*9T$xfGJAd`@
> zI`*QqxEF-6BlRBGt|M4K)qTiILcnb^-
> =f58OM%0d4|))FCx`_3^vz#AN*8hUn&Wg4
> zH?5woqwa-WkkvIv1$_j!-
> OMItrY)x^;n^rppZA5z>T9BlIU`&RDuT*t{Be#|eR8b(
> z1zc$dCAmBxZ)_Vx&JE8I*f4L+R&6)1g&|`1Qv`sNelM0>SmE{a_S6F+Enmv5LC
> V;G
> zhXpzo1GQfAQ|uQ8u}H#36!aba<Y@v%(VIZn6<Xkd@h05z(8dLUR)Yb5+)q_;8
> J0vj
> z_fvI!%>8Y+nh=D9(^y^n!RR{{o1%U@mbwc5!G4#I5UyQtjun3y*U*rSVC@KN
> sQ?@%
> zJ--
> XOHLMB_Ay~8{JlYE!56QjPFi4yfR_mo5zZkw<x8ni7qaDSz@jP`)w#3uy5}_#3
> ziNaSRrR1Yldvs!r44ujVja_|(?9?NZcO4m#ENX58PQIPhquo&D>kH4|H64gNt`W
> J+
> zLZm7ek;AUod8z}qADgOglt)$_i0DKb5$2=*HqwcR991Bf+I%fF-0tjv`2^geWl-p2
> zsjYpn3!h4%H1Y7!iEBeL7paqM9Ml3Ev)n$z{?MebM_27?t7^CS9Bm9_a2~;2#0
> R||
> zm_gxnf+p_c>x35?oNic}fW@!NmAx3vNH8+~xJaiqnOBc+xf)WRzf#icRq8;jQb
> osD
> zbRyOj8lP|iSz0K)HqL>PA*KezL!XH4TOJdk+MyS$yeml8&QS354aBDEn;&E!t;Z
> Dw
> z(e(t?dqM<mok`|=)M(fHg=7jxC+|8sBI!<P3RvWK%iTPlT^|&ZU3E_0)d~7&Wo
> *l$
> zd@5x)lB}U)jsJLe$>pa1jNZwt<1c^w%H)3B3RLC_e*5vO%U_L7uKo6`Hs5#A3
> W@6!
> z)PdMA69$hU4B9~7H5j$iQAKyuua3trRyrdEfR}RVn?v+?4GtNv-
> 5)bvai5&+<4ES7
> zWxg4^5W?YS`Z+V7o;by4d}m{QC*;_+=y7;Bi4Pd69RQV~+QCFPF{$s#>te9U0(
> $X}
> zp$Xut4uhJW*t46LrREAhTK)n5Sw5sbA9p`qq(Hq`L&C6z45!wh3IG>`VUD%#^rJ
> o=
> z*9-#wfQJ7$AU_UEL%bRv+-G7>uD$Vj71-!-
> MZXN6>3BGX%VFjoKw0vJ3$&Mw9T-Ue
> zfJI$Khdl6#1wYkr)m=<z&}J2AlOl-
> DCqFhJdou|xERnpKcm(sw{2Q)xmoPT8DLDo)
> z7ypGRTqUXV=A9=EkdL4%(ANs|8Em4HfdVfSgBp<cm)c0I*19WQh?^~j%`iwQ
> lYeB-
> z+g1x``dUAvKh($2mmw}Hl02}lYRj6RM?+-eVftbTKcYGLz-
> Z@?t_Qb2PyGk@qG6yn
> z%Hs)0;7k{8A~R=h>W6Z)y$ItteLtXtvy3@Hts2%{o#^WCe8EW?WL7nuvMJGtp
> >#Ij
> zmnCUp@+NeKZ`LY5PhIVC`?j`ow9_$=rx9Cu&>Dj3Wq!leV=v`!L(<bdx{%@TC
> KdiS
> zO#~@8Ji>~GN={zq0hTBtYOGj9R?Oy}W%QYcXpSpvXQ0n|)arVktnX1xYtS`t=1
> A+5
> zyy%$>`Z9z3@s}8sADt9#W23qv7l$|L*4;SD(Yj1frSpLOA<vbG`nJxy3_gy)0GB25
> z;GvInM#w*+R4{>b2myQ_fs{e2QD1=IcPfkk#oz%ZD^7R|yEP#u`3<uG<M&sJ
> bKlkT
> z>>DJ(rE#}6K(-JBCltkw2f2qLqZs^{4#twozJ_E0!=W{H=C}e1Ks2G8)jL_uhD(oq
> zuG4@Ib`L3vFvVo1z(p-
> dgXRT}0<n=tkp9&K>B`)exd{t5q1oLSFz^Qo>Bw8FF&e2$
> z76()2VwA~hH=JcyC5jBh?7lDAb@KF^a7TtcCSe^s{nn!%;)`R(;P^sk>kCJOfM5Q
> I
> z&FeRu5%DBORhE5^ch3g#fI7O=_4oA;;A%1IJ$&(ROD((9RVV`F{W${EusFM8N
> *Q!6
> zf`aC_(3)K&5zNg8Gbhq`mflvnR0$!}b8S|f+>AVvF~?9IW`>8`Q52wkFL>cSrIRtw
> zGbYfP#?5N3%n7InthpHexP*74j}uDjQrr3Nif<D-
> UQ<nwXAp$h8*?x;bF?mn|Djt9
> ziQzWmI!wQw#-ogAsq0%8@U#Tp-y8S<{oE@oy;RMC_Yd6@>uRvP=-
> V53pRp(rTL~=T
> zVipRUVr<qF@G@qK3B2MxOhqyQK1%>-
> lOajqt%L}vvs#J6G)s|=tIMENKg{_3uqwk*
> z^UQoG%kyF<_+Fq_6ddF3Qa_NGLzz=DC;48e`^fh~pnq4VXG}Zn;u!r^iH3<BU
> +(9N
> zgAz2yMSs`E=PlfZIVJ|S;kjw`czoXrZ(~9QT;O0|Q+8zW=+BG;^-!Sd5~>;Mu!s4v
> zr+B`$Qm&uUE1%3eQXlLM_=O?*V}8|>$96m!%_etAB41;+@=FAvQ0#lfKdAII
> ZRe}W
> z^W^9S7`b@UHYHxko$q>am(5<&L_cn_w+mT^d@^@9U|9l|gYej|5k47?Xg^i
> v#|y#r
> zt26A(GZmR1>TI9|z!ryD@TE@yYp}8(+#X)+0Yl;{4|pi`PsOY_q<g5JiFa3Uz+y&K
> zZ{Lk0?l@`Ascu)IMw#npw@(vJd~SFXAM(`%@vCE-
> ^(!8&jl0+mdUC_MkC5R<_{GHP
> zzdz*CugJ`%Eb8)AB)YCNg*Lvg<a?D{b_J)BRS6lSw4MU9A7Lg-noha(lN;7{r+C2i
> z$HU+f8iqhWc*SZ$Pa*U|HwYIl+^WZ)1Wir!a&)_Fw{w01_lM{Lq(lN_lAWkO1i
> (xL
> z?)Cb29Wg*-_Rp>H#!g^T8l_^)bgM@M@^GdqGX~0y{<(Et7%3K}X-
> `fZ<_5em`1S)`
> zV;ps>WdeODbDVLP$gq%vwGZkO^auH;@quu?%-~*!REhY;?#Iz)Mh4#-
> 7;vo%473D}
> zt*bfKQu9?3PAiW*=o@F<cb~4WU&Tq|((hNp(($W#X{hmC>5cf>8#tDirjZ_U$
> xD9~
> z532iEKe~~B*yaCZWBFDd|A_D4H<z{k=|Ut+!u^^^{tDX7Zu%RrGt@OwfT0r&
> 99E<g
> zrdQv8U+9Dq&;%%aWQFwzR)l&(`Aod)AqDnfOfxbW3FNei3;hCqIb~{0Dl)%_R
> 8wT!
> z0)Fx}W{i!<E!C*oMlRD6fhH=dnxs>k;`L3g=qbs%CKzDI`lt!!7iNj%l_ipI=i)p!
> z4$|jmUMBGBQH}LYXU%fCRvfP$_=v6MMb5<hI&k4+py{@@LhPqQ96Jg(;T_
> T_kvtIA
> z(OR|aa;c_uGW2*A$jP9T8St9SCh@Et--
> Ywz4L}X!1(pi#M2ZK6_60cSxH404oLson
> z=47BjxKu+@0GLc308m-
> iRDUyECCKV~v(^k0U~h}fAbL)%?)L3m040GxhJ|>84q3Or
> z4U-j}jp#>{`7m(D$?67}q9j`dk$hk?kdEOCN+wLz+8o*72hZTc<NqlTM>7{-Yqzc`
> z(aKALv3igjm_Zn5-
> _4csQV+xV!MJ3e!V)3AAM;zEn%Hj<bgJg@TG9f?7j5uicmOw+
> zoNpe1gv1*KAHq5!AzMn;DtkSo2>OF>zJ?v<iSMAAk!BWk>qDwRh?UFk%pKs
> F`LR(E
> zm&&aCXdt6iW-
> }vTCXXZE7UY|%X#q=n980Dqyd?uIiNK>tV1%2Su!PD?Mh0%M41r(>
> z4iZcEj*v6p0Nr3faiW+!1NJ7DJyY$v4xcN{XBmElpD(u8cb0Rvjmu9V!M7*JM)^>
> 4
> zXj!s&6`sH|4{x{^4=sT=_XXNmqP^5td=nnFAEGo!(v`vZ*bf2-Y){r~uT?!Suu))1
> z(XCwwb;IAL^!0v#!Bhm6OTUKH4T%FDxR;_3xwD%07%mG6{bOK*z~#6_>=fv
> Jw9iyE
> z=L2grsq5sC8_^tCE3kG)kKGXtBD3&${Mz<eWP1Ys?=U5#aFHEXs_^W1V+of|
> B|-Ju
> zyI5QqCI&EoKJ?%~`empIQ#I|is$5q>`%UG^yC_ac!|mqrI=ldyN7{Qpaa;u=!6}1
> m
> zTh#35J#^dPwIZmx#DvWa=kVHd6r|k!82x}}qs*1IfSw8!fws`gOY7>2v`g_cuPuz
> v
> ztAhH}6`QPndg-x&C-
> `Co*(gr{%I3zu%*2fZDG2Nds)$wc9$oStD@yMe9G@%}(7HWh
> znL7`i@^iT`@SqiOP)Ed;B*zM54FZIn224(PUzi_%|J>MYN0J2v@xFPnlX2ic2d1E
> 3
> z465IWpDQ%OK_COm@q?MiaOj{su%|#@Xa(Q-
> ^ce!%yZxNNbDQW4_MQ5c&LWtC8&9+y
> zZ9uNrffkajcr0ACQDuH+mk1}wq+9x^J4{bmxnwp_W5}$CWLAVzJ+Vp-
> XfZ5#?g~cI
> zdx=?|?|RQByFbb!$<Cse?PSSJDAyN*vzUIR2#T{Aur=<=EQ=UtR$21A66A?$V!
> wgA
> z41un4l-^suA8%bD<rn&dXT(3<N>oY&Fj4b-
> vhMki`nnk1p(Syx9KEk$Hpp$Ql_)L4
> zDi11+BNPn>>zuA~Sj+T^!!xk3?@lmgK=+u^^ibZCtl3hlrt8uQaGwE`NEp4l-RL49
> zEYm4CIOLwLOf&MNp`nDMIbcQ%#7NJ+CN8aYR|hRR+M}!a{$s2iWN1wXQUc
> xeSX_e6
> z#tM<zQIS5#0#>s@#VO6EovNYP-
> Z;TjWXm#Vvu(yShw~_6!#7;BW!95me9h0G%~0al
> z+!D8;MDhbDKrtEMdW@A;DVOR}kOWtNJCR(4B;n3Y+{oh+44D1?bc5LmI*qW
> CSx7lP
> zH{~3uUK@JJBz)RR_`6$7mAZte(YA2tKAA0D*Ht+l#uDri6li*c{gLm=oXoYZY-;^(
> zG1EhC^;`E9m@{66o5)=bGR$k$k2LJQLXLX=3A%D;EcoBoO-@vEcR-
> i+n{Puj9(Mg;
> zoo|CwkTq(xrEJ_h>|MzPlx9cynKuEI%}C~}^R#xTTU~z}(5F^uf<q`j^>z`;(<3ni
> zhgqE5cucla=7k@X8AjcUv741U(dAg2{PAxb+D7Qqkm1#wKA2d|c~?@vk`*(<T
> FT}x
> z01vE)({z$S)gL`?LG>ry0a3S97kR!_<jCA2;lyK}TInoOL+T=#SpDM9rpQB9krzsl
> zhtg9}<Vy^!tn*K76M3!^MQ-VqT3%ok`N%(VYT3ymUCtskq%M+)Rmdu`-
> 72y@!dkYA
> zdY85C;d{`{ZMoPCEhFhGY|(qrp9mB7L$^ZMM<ngROpGsE`LfVW!#U6)$eOD+
> ?&5fY
> zVq{2|uUjx)=p?#T6JBxO&{i_`GMQofahp7xpIOMwk^=T;F#P-
> D3NptYCOb(&_vFwI
> z<vFWRXb!$NSl<-y<`hZ--
> {^%N0)=7R@!(NY8^S07%0G|2fOGQMQao#uL+twxq`yhf
> zdEqTWW7MVLq|}Csr4RJh3|zlc5M06Z)W=Xs4fzlIL*pTjSb1W-c{~Rz>{!pLWol-
> g
> z!L{Ehnx_7KCz}IX`t=jB+2e{91C&OyBQ>b0g^V&t7X9hjXsjG-
> W$o|oSa{12{dVWa
> z=(izu9*Y&Lzr)G6o(8v#LQT{3!$dW}Ki}2t6sIwh!ka!40-Y09dKmr<#ON4?Aka$n
> zRl5|mSRPpx8b>DzAL58)KI-X=B-Xh65F-Ml^a&e>)~03$2FfCh$6O1K+j8-
> MPQFr&
> z%;IqnV_)y*0uP-
> ?<H3B?BqtuH01q;!)#KMf_3d@7fH1<{U)ejN1`+)Z&Dde_>@q35
> zo$cU)D#SF%(ZA+22zFO1)fy?CN!5k&XzNdyNF&00RO>ssK^UJF8({8QUUmUh
> de%-6
> zmi{>#dyZ8r%nWg7taFq^k&$RhyE3!sGTz!TU0|U*%ZaXf3d}<{6I3|twVYi8-
> pmzJ
> zyEHb#?;AMwU*g>h;cr(4q`lTSh%BMp<UkQ-(|VLO1GB-
> Yf)4nooLbWne}5o46)OmW
> zu(%Z#2-^G**x1y-p*S{3z3Tn{1vhe~Wf9Gj0`1^M6YH=6&n-
> !wKJY!nGZJe@i#+ha
> zEIf;SLIid>v$68Rf~^8S=0I_5y4r*c_39o@=eWo>LLson031knBPi@@5GsW{4lx~
> r
> zSZ0fE44}2p6DZm<kY4tPVFNUtN*`dwu`*&b2&&CM@xV|UPOE~O?iX&V#vU
> ?CY_g_-
> z*bH?ZaEs3=j2)-)1xxN)155ru_InJxiN`lj<1-
> 2^he+2waW|VnUwG#G>J_NLYTXnM
> zegV&1?n?W97t3sl5`q2TiFV7(K+B|?kUP;{yJj^;f^x0A3w>g)JD2Wz9UBPJeJmX
> -
> z?Wth6=)TJ&<56>kYSGN=u@cr}7rGXMD|q8naD4RS6!p1oHoT)sdRd<AQ31px
> DzZ7B
> zLZawE8y&{%gOO2ZA+U{Sc<Z)Jt=k^|U?4V1bznp%UEFVW-
> q+=QEEE*PcZg$BEc0;8
> zxSyzHXBu0djs4vAPt9L(XvI~9{ngX?(13?&e82`rbfP@q6bAO95t1*)<YFztlLuly
> z0uQRtd>RHjV}|gPbHaW;<g2gg`CK1}6qqyAF|Y|+&e4$JesU5fR>41N4ut9K`@
> +k>
> z`j1yHOB#-
> 8&U2J_4CAl!R2Ez2EQ9!50G3G|Vya@Bv&^;d`hXN^9n=(<Gt@G>4B@h@
> zfyRrrFlyT$Y`lt5Jc#5I_!te#-+L2m7Cg%su$*fZy*9UKu-G$HCT(#pVaC~_#cE|<
> zw&-u61%!6q*Ys(4(<ftt>)<V2?FzP_jQh-
> N6|+lqnxh0PL|+H_+HGX^Vh3?lQt_SV
> z%1HSnjw<pq#p{oo9;buoz{?=T4`&pzZjpal`;qqdeLG*}NTq_Kw-HAsK%i?usq)}!
> zqAMf5RDpi)-~;lEPD}sH1cP>cP4lc5H(q!|FuegG!<XvY2`y&hk+ozugE~8Fjgr2R
> z=|8?=V}Znw{Jmo8(o#JhTB+fvXx-
> wxX$?mk24@SKd)mM(_DoB^Gfb`y1DeJIQtY72
> zvse$#SzBMNs~$aVT7ws2V{Rwd=uXSThDTVG&W$fip@Z7OMjET#+-
> x<z?AwMT4GjnA
> zN-
> <|d+2~HAm>C<njUAdP;;E+CsBP?K*k%@PBNYt8|6uRQJz7AKhk1k;z{8*|0aw
> Eu
> zCo?;FSRXnNJqSk!a$pL__RCHs4+}qnaBC?15+lVP3W7m}ItPr(Vq;n0um`Cn3-
> !Pe
> zNhD`q<>*Z)>_G<(6bCV*<VeIAAGHqS4GWR&8j%eSL>3H#$Pd6CY(#9}@RL
> M@S*VXX
> z9f;tBn`a~ONML#~4TtitNY>+W8XOV)>kptudGC$*yLsyZ-
> jDFMFK^DsC@o?0ll%H_
> zkYj>?rx*k>l4X?Q>7wlJxt8xuJe19E4~o_C1&;L8TMbTc;*p-WBRXSsddOII`Kt#(
> z5I+--^w$rHHTZ=`>Y=NvFxLqr^|RxV#YAVUmA=54{(ZdINb2-fJkr1Aj5YNSPjIH!
> z{*;XY0@D}R@ksw4!==B%nf@Lpgide8BmFhbSgZY@>NEX!UT!q^ThV?JkHnJ(
> #p?8K
> zNBeVo)UG^45T-
> ZrNKgL@&R8Aqairfq2!iQNJkoO|F(f_g{Wz)7y5p6rw6)IbSA)#q
> zfiXIVq5JWM<$mKm?k6E5#-
> >F`P!P$P%Gg^&a_=VS9Rv+@bK_IC6Bu@tgeg5hh>uX4
> zx*xLv=1<37CnYY%4}|+Jy2!P3Ban3kaa*w2-
> GGL;cj*%hWNXs|VKUG)(>9D4pknkg
> z^fN3k2<t|e`z*>oX=+VTtdi@v=w!xzh%~UJxPL$MfdS6eqJ>kjErAo!;9#;bEHV
> uE
> z+F=&O(8K68lzAAknOOobqx+c=EwXx-8rxCU5coHCce$Z^D8p&{S-
> *g{>wV1|;7Ed*
> znFFS#ZS1S`x^$eBXDlwcc1zW?sd-njhMfe+s=`u_Bft0#e$#hZg*HqZi9*9${u`_E
> ze6_60$z%=WMe5h!UN(EP;lmwdZ_Gta>X3B%nyZmF|A@n5z#%Ci>Hma#-
> mHGC`BA}x
> z-
> ^Ang%c&6vdmVVZ{XaQ)XvmAy#ZEkIc#Q{hQQvsW;8EqkW4z$Okn{xLv9I}g7K
> }gB
> zZ~K~`v;#VII7b6W6=!N;CfB?f(Y~!I{va&A8+W64n-
> BP!eux!Ee23)bd+57(@og2@
> zcwZUp=yihl`>WRCSVODivGab{*DrF#JAH}f*~pChl>C*#QhZ9Jwy=;^`4+T%J0E
> H<
> zL!w>pW0RJ6CR_QPXsy6^d<VZr`W`Gp;mKycVE;b&Ivo~?8Bi)k>|~v`EGf7_pM
> *BR
> ziay<q#RS$5QaH`d56jVf1-
> mgUNo|Uw5)hOG0S}TIo!y#xB~mkybF!7+@psA+`e6rO
> z{dX@)HuC{4mRf)d93d^o4=<Q{8M_5NaC8{xiSLKIk)90pg?i!#<SMEO0MG&qV
> X$8V
> z7_5$a(idh+jlX|dY(@%(&#M1;E^wjU65Eq{Y+wK!uRU13zV`+eu22ZpsoP!~ZTc
> j&
> zD8C({>3@u2twjryeh1H{YvLcA7Mqm9cCUKE%DA0gV(T%Cr3sK-
> P5W&Jkezg;K6KHZ
> z{x8WwNF$M&AuYo1_&b**TIFE}zt8YJ$ZdpVGhfguTXd^DF0H~d+VQ^IV-
> vtt;=9lk
> z5D(B0T-s+F0(`P3eE@wRtOw>uXUE{I4@tS<Haqqip-
> VI_B>bMSt_C@np2m+2KMPxM
> z7W`STQ6U{0_~`>{=}xpK1EUw@h|HHp&k<nQPW@YSCSV1{JEK!9fEfMLArt_s
> a3I+L
> zTnUp0Uv@O5?}mmogKD9N%Zz&`Rty3lDwe)|v^`)F&C}2@$rQii>G=u$u!FDX
> _#O-*
> zL9&%E@P=RdTM|@rC!4OOr}0PyB4e;~0&SHcSBvi1lW&X{62So8#N2_#k+SF&
> =s><2
> z!@AZ-
> @VvLV72i;;wy9$5W(WiI;=#7jObJ*h)w~UGK~?tOKy!~D>Q{@&XT~i{rkL%r
> zM2aw}R(@lp1Qx?dApOutY$Fq?YK>H)c|8E)JNS)@L6a$Yy~pi}otP}%&<N3xt1
> KLr
> zfBu`~Xdvv445TDfn9T=Q0If`rT!4svo!IxYJaaZ4d-*c>Gn37@9S#^9avkY^j6ll<
> zdZwF3v^ole5B=D_<}wt4zqJ^QP*}F|H7S9K<`z7sa0o+1<t&Jxfj&4|rrkV<eD2v
> O
> z6%jRhBJ~hb7>3LII%F@j14dMpl3D$tq=0C%oeS6(i4g50o0-
> t}0#>=toX2K|)*JRa
> ztqf%r@}PmZ2O`j!4Vk5SjglPuB-@g=a7&Xwb)RT$LeiuZnoO}CwCj-
> v<UA=U(V%y{
> zj8CQr%Rwm*nFBhuysrP%57>S$z|KH=_21>#2u>w70A97tpdqTS`APJ=wvH-
> AFzJ9C
> zpU-
> #%N%INE)9?*@5r$$iYyq#wWcV%gj5R60swY>Yz%h^)sdL|OOv*OAo(!3bN*p
> qi
> z;d#iLe{57Ywg{5V3`vg$O{V{bS=S7W<C3jJ9}@*9jb({^+}N06NV1gyiSb6FN&gIK
> zjONLj@!HDFJjuKcRAIC`hQM~3n+i9jCLA?$Wy-
> |`cd?bc?^c?cYvqx@5quX3){yn`
> z0q>OF*31w8o~^R|*A!L2jT?7ehc>NM51-
> 0<f<uZ1EDGD0P8mJzg^Y(03S}|L0{f%!
> zU9h#o)KHXM(3iZlKheCLRZB(jE#p5(nuDuFD2ju=ox<2LeQw8le=wCIaBZ^Ki)))
> h
> z>OfNX%RoCWVc{rh0Fu#Dq+(N;*MZBJ7q@PUOC-
> Ug*#sU(&C6w6Gj*(t=^mDJ*k9gQ
> zgk(W=lOq|j!w89gaC!{;UEuUmLCkr!=f(bzYW%vzGSbD6y8##9Uj_b-
> g*I5Oi&vuP
> zhcKE2+yoNQ2Gk4GAoR)SQy3cP!xW^sYy%#mC&D3RcLnH{5b@o$unGDzbW
> -RcSLP%@
> zGb_6ta0sslXD|^dh8#VOM_tGydXfy68*n6xOs)Aw<OG{7e9L_<(h!{Z0LMxGo
> MGS+
> zx|DclS+ttOcBCpgNr2xOBboYs*7le)<4ma(dC<ge9TYpy<S|k5cv?f{W^kfpkknD
> L
> z4w%eS#G3QY(W>bD_zu3g*3MZyD!zl2a;=0tB_G~9oD@jhs0gv7`AP&OQrF^J
> Px9<P
> zNINAOSjX!GStw~aPWL_2**39>$rQ6mwlbUeQ5fb)uKJZSi#?REmD3aNd=Gs;
> cueUm
> z#t0_7w4e*E>Poe4#f+`T4#t<*JGM8s!AWB)OBf?1MDK&9hHCI;79Z3Z)v9YNfl
> FIO
> zqWN}&8VG@hlMW_^Kb|IB#i|=Xqq>8jbJrY~O!1*0MY2lBGuZSx$%qbJjq}&^
> t>j>W
> zA^0zMd$L9ZoEAZ8(NnnuqdbB^0-34;j#I4U2-}-qf$2te%Au1!?D93gg622<e-
> ZoR
> zD92OOM>;<p^e>0QGBc$S^K@{z9gM3RKz#Ypv4k$Of+2I3^9I4LMC)QyN0NG
> Dr4Bhf
> z+02Mwq)d&%-~``t#=)QjyVteq3>_up<$;$EcB6aPY%0`l)EwD}1DodO(T!{b-
> &elJ
> zaRLMVRFHV!V#3x%d}x;M6u)KO<3n@XntC#xk}nwH$A<^5bvGjq^e}U%O^
> MhPQd18i
> zCAe+#LT0gp-
> {LKsQw0AqXQgER0O#}6E=!tJJJ7JS?P+FS1(G%)&*=!$Ow4J74&j>W
> zR8uj%!dg8|TEiVJb>yFvRt}*tw@U$Ng-
> *R44%cz2?@Tg6k68z&XZ{uSmjzKGH3w+0
> z%74Fv(;?rIHQQjlQj8-
> IT#m2z9jJDljnBW~^Lu<|zFh5^gU@~Vyzt9v*EWRx9G~yw
> z^Id#i#pg|YT!n>sh59eQu%NKe4f{)lG~Z$x{62-
> >AK~M2f8t*rV)L^Q1?!jpy4v+O
> zq?`MzYS($MR=b`!SnX;-
> *hu`Ii1&M5sdhEs_w)EH0?bVOF2v_^hfvly+{%Ri>|Z_~
> z3&y#1Na45<BZ2a`k$m-x8a-
> ~@m~q~5<HqWpEd34r1SEbQzy`yGKO(PKf6$N`$86|D
> z5`LpIvjGysnKB4#+n-
> {GW14F>N6Bc3z0V~Sf}^xBkc0GwphQ;R#{9+U9F{;JN!TkF
> zVcPYZ4DUlyQczt{{M-R7G+;C8Q~?1$ocDmEWeY+2m!;Pjy16Xinu@-
> xZyr=e2<j+(
> z6z&*g15EV(5KaXi3o4vKl+t(#0826$N=dP0YR|7hQ*%z^^sD`IM=nsE+WH<S<!
> 8Q=
> z)#qaWuOtW!$)`F`p4E;7EW-eOa1e$8C8x<o-
> htOh&h}{v*|qvS(6KZ#1~S}BwTzq-
> zeDGzR0{eCC7|J~8#mo8NH}Q~M)-
> uWHULuuN8Mow?amW=bSFgU}C__W)GDPJv)h;7*
> zC%O;je`4ac{XrIOn;g(mE-kxmSSnzn-
> oEn+L%j>WtUX$QV^Z+wpgQSYCdbgtJ%J7L
> z#J}l`<plP}AHSwP(CQ%&D>8+NQQO{Xmy#>y_7pj3$LJ4-
> z?Z!R_*v4qp9+3U58w+v
> z0p3qnE#}CI#^%4p2no3hzB%zy`cFPSUP^0q#8W?N`HVNWU7r0kM<J0%{*B#
> z?*Ci*
> z#ot{Bnh11)sQxAW;)r%93ETR`I}c_lES%LZR)FrcesSkMNw=@L3Y?mM<lS?t$-
> 5bn
> z?(_X?`o%RI#r9Cz@hI|e#V%5R`lSPptbS4O5Mn>u!h;Ja3y&Y6EzFW?Iq>+ur(e
> 9D
> znmS9rSc?~X(eN?)#TV}1HemFNGk_phoBU-
> jB}F^s)Gyxl+Nh*fF~0Cn{$ZrERgCc+
> zPa>7a*ZiOC-q(1%XBq-9!^#4I&yuBtCYm3?dwd7Kxq#hvNEWcSfYhu7tRD=-
> (b^jF
> zBK3dRdmHd5i>q&Z69O&}*q}k9MhF6m1`!1nj9@@kK}k(gqFAkBMO;%qDDE
> m+KHaQk
> zS=M4}TH0ERRa><7DfY35Ezp2S(1+HD^pRGq0aH7-
> n?6l#S{IDu|NEVpx%b{A;K$ql
> z_4az-
> S1&gAJ@=WJGiT16IdkUBnR_8Qtn3Q8@FAf#OHn&tGQH0E*;4zGsdmP8azPS
> n
> z4lNNR`0JWO`2tgszxAl*(AWP(=Fno)rkC_$4&`ffGk?V#$_E(!%7F{ap`-AJ+RVSs
> z9QqfWmiqt29Qv>=_|uz1i-
> aQl6?3ROZ04_P4&@7|64F$eB~;P2#{bLBp@k$}lD}dO
> zm50szb<LrCfjM-KkS?}{r280i=qotj1Qt2EIdnCO-
> 4S~TzhVyUbFo<wd^8!O&K_A$
> zit(}9nnMRQ0L{;64n0pJrR{dn&8t{3&7pjV_FxWu@_xhTUCp7)V9lX?KB_siJMb
> ql
> zhZdk%{AbOfd`-mo8;{lDSInU|%lXw$U=Ce@97iyRvM`!M3F0w_-
> ZzQnB(YnHIrO_Y
> z((9T-2`lDMK4>5@hw}Af%%RI92P-
> w^PMSmcs?DMN?3zRQBIZy&&>YIYSdMowhu&~V
> z_fl*TKC5Ss>uL_oN3xww_$;$YJ)h$B3-KG>%-
> <uJL$~QU*qTE%<fW=~yJt4Zm_ubY
> z5p(E$za~<JddrO+DeJ#7&L-ngoAX?Eb12czHit6h-`pH}e<9oXuQ7-
> A0eL>DIrNuz
> zAKe`K%L`eS#~d2ZWH_2R^nS^gF^5)rvZ1(-
> HHR)(VnxQkt2wk%j)i=@IdoJHa7Q$U
> zz9|Pk@{V8*-E6)d-5mOD4b_u5bdmn_|IDF1n?oy3gA_ZeIkfc7|7Q-
> RFOX{vefr4e
> z&{sc&IrJtC`!6tu_C4PyKR!Gh$sAhvJUaSQn?tof+@~{#zVd0zp$shmw6e^hPB8
> _c
> zYYtufH%_!qaH0(l)(^*Uspn^kS?ckb6LliVr+9K2exsZD%gNdITUqM$>6=;Vjckxf
> z)=thE@)GsnCeP&T!t13TOHpq<FZmj^4~v<cXOHLPJQlU#UN$i*$HlLN6Zb{(Z8
> W}V
> z!|io90~UtcA%DajgZQ@)|NaO6%HE#lyA1zU;@?ZnSP3F+H~wwHzi08U8UGy
> o>&b5W
> z0rEV>Jox(@{x;y>r?uNIZJFlF-49#rfoZ-g-ks+AIiA0bwBzyj47{&+XPWQp_&W{%
> zt_4gP{$7oLlO5FczhJi&d(x+{*XFPOKhs`Y_)9R>C$rbWW6(GSVlz`zQXEEo9wCw
> s
> z&JXuR@Row;q51IA(TRK?*HHEf?hJ6`wipY07hL@jGUj<i{7rwJZqDL5#Vu&<fl$
> #7
> zcLZJ9UEyO91E#>hwaK6ZT$_xziZ<NuDP9aXI)gKQQ?P?oR+En4hz_Cv!^&O4Xz
> gNp
> zFNEI(k2_!iQ1%Kp(j}f5t8CTHXmysMOoMs!;N0-
> tE{eB?YhkYsJdY6bhwcnt@4`gF
> zw2kX#EDT@j!psg|sBxYfJ_j*M3g{s;N;l`u@KF5;-a-1)!ten7X?7s?H;NHUq`Bds
> zTl%fxiEin4hT$8AT1oT>+>J6AV7tv=Ih#aPmRNGi-(qyW#po=H(Flvt$rdA!oINR}
> zwAfN)rw^WQWx*Elvz~?85K$Hzg4hw%CrMyi9Vu@(?DN51+%-5<!x-
> 9sfaA)A*p$}C
> zl**c<7{&}u3<8_LLCSNtgt0d-Z`}jWHtX*hn|%-~!q`Rs(9#!fRCp(Tjj=WE(|q@7
> zwfnTteOhOpxM`A1&cT~HZwv%)>|qyVnfo-
> |t>_sytqxE8uQ9gPeOm86EpnfpbDvh>
> ziAZ{!Oedh==w|+Mj_AS3G>1bnV|>++GgR#c&m5640?%}fz%M*&=7{m_8co
> y2bI?Yt
> z;gIM&j4(Tyos`&kL506Wr3XLLyI;scMMKU|ZzEKOYnja0fdv(@1COz&jLk;nM`y{
> 5
> zMO69%mB!dC){XzL2NADlH#Ej9;ZwNLfX}i{mxs;#%?%`<J(qT0zT`v(!T?MfM|w
> No
> zMRH?og`qfX;il}ynC*qe*mdsLOkZ|qpG1<VV4Lleb~Mn}uCOyvCp<v;hkJmoD{
> R@>
> zL|IxJSTzPOFjW)Cy28q{afOvKJf`YL{;o~c{42Cd@(CN)tfZd5Vyb3y171@#6QY~>
> zi+dvF@UQVh92uxv3wft0*BQC4wqG(y#>f6%eznT2=S;^P#)*j-
> lf{j3M5I)c+!r}M
> zR1QBQ9JQ`*z}IT^+H^7rXvL18Y^GgZIt9<V5+HB}zMvv05zE~CD)pU*r6S(WCF2
> R!
> z5)`0mX6g#W-
> j_1g;)8F|@GN|wlQDVjV${3_1hF;qS;$n+CpZEN8TczY86CNOp_;sm
> zPWBK6mS?<a$QkO;&pk};!iR*(eJDlE_zyGQMrSkm)-
> %cEOms$!rEW+x%aUZcC2$qt
> z8+aYK;Uc9NQ?W&WH!vOX6*%W-
> (roq}wi$ki7ro7}8W6Ufe3o{`_yo;Q+R0zG(`+-`
> z=xOIu65z(}k8akGGt{x(cDnGoowChv<4;XHM`gG3_wXx&%P!k_5jZ+gPjumM
> 2y9@f
> z#4mOlCXdF47+<i{uzqCFj9a**8pa48+hrtoVkG;Kt1(7#&Bi8^95-
> N2KQ^Cb)KsdE
> zIG*67{l`*5h5;$0Nb(7RxbTaxTYRqP=uXHK0iRMldnXP~7yM7x#S)w(3N!;4PLIGl
> zQO{r5vyg|){4Kbr7Dhxoz&fwcD(qP_;SV-
> jP$IW2<N^27$Sg%)Zh3$MKvE#!(Jc?D
> z;W~@)>(;p-_XG&u-SXfZJk!Mq4&H&-
> Ixb#}*gHY|vIfeDR9HyZT4xTvXAiY84`qfL
> zC#)Wa+F=kox|yGkHq`3SYRiIr7P{B-
> 2_D_Tg8U^5mgt?X1`i9K_McfpO+(I5U;mkB
> zsJZZ(1zC#v<I{!(M`W|$Ri~2$ndrPgPD>K|%uwT7ynY#Q%M3NX!EKZH%22~$0
> zhp&
> zkQd!FxPfiQU1~8&YR+q{>&+xKR~L;d1>mwn0X;AN@PM88=ECZpjj!sx3#rae
> m_@qN
> z<yi!~5cE(+^5Fq2w_5!Om}41g;x5ESpkNSg&FdngUh)v`FM2|?>qY|lA~V!g5JB!
> l
> z?80lpu@v>>Q-*LQ*@QdgG!l-
> 9&N6Vk^Q}=3+odjoiH8Sl2ZHcvMn%aOe=F5fa_Gb`
> zS#&d5&A0dz%h5c3fs}*{I2<gNzg(9R?#m507$CD^a+V*i(!!>vqRz(Hd=`WMoa
> 6B7
> z&Whmj`YbM|FZC#k0P|Qbmq`Qu3pg@0{lN^EQyD`y<5!;<a3>Va<@`)8m)zpL
> KLP=l
> zGZV@p@Q3AcJ`+RSjUil93~FHOQn~<(eBD|9@N`!B`YbNjkTcX%&v-
> h^g*OulJ1hNT
> z(^<vYoi%?1JBx|V>t_Iu7_l#tsRI*Al5dcCzztkpU&pt4zTtuv;wx|(3al61B&<g+
> zuV+Rueq)_5zHqq|y|o!!F1<Am{488<VYO(A*A32axpX@{**Gk!!R5A$<SH3G
> xDS$+
> zlnj>_0S;U~f46Y?ArIk>fgJG6!~`Ul&;N;sa4x(i97|EZ{*fVEQ8wW&7*4`5(fKa8
> z%UO>V3b@=Nm{`?YxI9^iijwvGtyV9}NmOt-
> nG8`m@#|X*g@zCOk1WmSt}M+o=Soyy
> zcsL#lvk#K|jXE>nLd}QG{Kfw6G*BB+AMt`s%7W84gTy*GgP0R0w?$3?OG_|4?
> DlbB
> z!CANf&aisgfP+8NqOTO_na1HF8W}`YJ3pe2q)dg2=Xi#o#IYF!z65VbIj{JZp&WU
> Z
> zn58z`xX2mM|FEJ(wsTQ^muv?*my)qqL~5?h!-
> FtJspLTzgFFwy7+iP|#sKgji~*R9
> z0F5%W;aFA<B1KA}I2l6)f+Nl8`~bBKx1y!Qv>FchrUibt1#b=aP<%e<nMm?iwu
> R+k
> zGk>uyJYyIs&KFR8k*0V#{ut`&gEB5%abSy8Wt0#*-
> xi6p^P_(x!*Q>88c=rrf!@@@
> z!?(yQMQ%fF99C3_`OLP#n-
> @><WC1cpH}hBKN<A3v>zz?c4}t4FgF!>iP&cjf3<ek8
> z%#|DrKY!c|hQjQ@aApYy0~4Jj*wht>ywWQn3OL4nbd!u(iU(0!Au$^3L}IWVT
> 6u-Y
> zFnZWL2m%og7FKr<rpAnTkj{mVqR11u4{R+6i!zd0>{P19{sKy5#6vzv0`cH~O~k
> _z
> z4@H#L0_-
> G6K#GSdh)s7Abm28cSc+QvLqm~*Y>E^OB}JI%e02o4?zExks?lyE6Lo{P
> z1J!uUkBX8>{#L0c_IZ2W48sE@;TtgQ$qOUd$tz-cc-
> #@|jbEs*b5M$Ua|o^F`uSBn
> zBdqvC&j1!~0tCjV+4xhX-uZ!01Ba);Gz*ba7zpR5>RJ4}cs;?AG5*G5oA6yPc?sp*
> zJcRu!ORvZYvfuuXHwE2z%m;Xf7Pg-FH00q^KBFx3HJ{@39UxD1Gk-
> mNn)dWcwN^1~
> zuV}~_>Q_&Cdc}qJ@M*utOt0i;_sadJuveJq{OQ!Ld}<lZJB=BBGSe8eh73D*o5l
> ?6
> z$4_Iq?vQY&v4ihr@o5?uf=`z<37>X&C{m6g>KVBNB%eO@goh$7yru|CQRyET
> iukiB
> zG9Mcgi5L@|*N35-
> mlW%1Od8Xi=T2kofJoN!7w125`iTxt((%#F?0!0q=vSOTj|@)?
> zkmF}b@=&6lztw8q9FuDWULodX@Q#!tb!R7%ECjLX;sUIT3jErqPt}RtB_l3Vqc
> Ur%
> zBV_breT7<_^(T|rM6e%_gLdxvr$o;TdJ>iscXPp#_-`o`og^pRc#<iJdj7`iTha0i
> z`|~v6KlhsUuz5#h|2fDlqYNXC&%*vmKE;zQQYL>r?0+H8S(zi@pVzvFWq%DhL
> v4c0
> zafOl#?_vM`kDAWTL)rY#$cE@i>})1F??N7ZS}`r`FE)n%B{7}rN<mjlANq3^`!@r_
> z4Es;^P-F^5zK8t@NcMjk<K3l*3-
> 4k7gO3=B__8VTl@m!3COUf{;GCr=3j5nex?*}C
> zAd*S`R;iEv+tcx`ln&G}I8k&nxxp9dug_nK5KYK1h$q{SJ7YtH39_C%sy&DBfJHxk
> z%VOlT#khTx;MxUgs_DM=B6@Me<O2_77WN|5%%M!CN?Cl+Kw{nGYwF?D
> -4?Tab1qYm
> z$_y$!O5^oPaubI{Qh1&oNqo>AN&M`3B=JQ&lK4Q6B>pXx5e%m!X`M5sh(xi|
> 2FJ~o
> z-x>1l1@sZe&2^q}!)HBi_!Lj>VZEFA>lrt350{**)f78!G~^6b2N~#ci3{%;H?M!!
> za7hR1@r;`*P9T>s(fJR^$A6!3vkf-
> {dDNRGkR&s1k{*im)oO~R2mv{67C=zA6mj7_
> z<7Vr33`Nq}6q$HDDZ)hO5y)8QG6X%u>ZjYd*@cRdN&Z%;mtOaDygK18AId@
> 9AERfr
> z0dh7<v!asE(&aHe#bY~BLUc2K+2uVP)E%W~eA_?`IYT}4eNO{3o@rue70<Nh
> HKu{>
> zsK?Xgvj?+*Omu#A5*j#fu$@V;>4fm(F>)_d0Gbcy#r-
> (0ThA1@R3IUqn^CWv(a5RI
> zh-
> {oORYbSq(5^P+%k&g|rChHH^jLvSn{n1%M&mutJt<eSfS)B9pEb$&6pw8elJVC
> w
> zN*X*o@ei#MSdwYT8R~k7N|z^Gc+V*L>9-
> BZ+E9;&WFz7H2El_wX9dKl%M4!Qmr*N>
> z@r%b^-L*hB<Cj%IWLbJN<JU268Lsi`sr^|4qXAR^-
> ?Y6d`qY1Uh|s2|N=pO+a$sEZ
> zJr5CFcufSBqSk%O5TP}j2qkd1OvISzL?QZ|F}OodtKV@Waj)Y9A@(O~89r_?@B
> uja
> zQWqGbK%@wv5@_>?9=e6m00<!ceEf24H9-
> C)#&E#0bn4?MV#zgGC$%M~oW-tGe@cBw
> zVF7<%lm;t0YsYntNj_-gu!hC+@@;Z<yPk-0b;&dqZN>O-
> ?zT1{JP5*a6eg<Di77bP
> zzY&DPngPEK13UG^td$^&WmZ0;Nc29Ra5MrLVILOi!@8?itS5m#tSU4e1KBh2
> YseYu
> zS;!}sSzUM!v-;{yKPlAXVb+C%*iTG!-
> h}MZBP}O9EL5j?q}WsUF0DLh9&vfiwPQX9
> ztl=WV7Jw@9fTNB~>_!_ik(Z)!obBX>0<L){eX9do^zK6<NwOoAdIa6PQ4WH&
> ^VEBl
> zdVQwH&C{s0%Rt5OSj#u3n;Kp&5LJPNAUBV|SE>3;Zfxhf>^0tK;w&g)^T#E>a
> 4e3{
> z^DKO|s`2Dch-
> M=<Je?I8W>oA~U~n<kAN^ev5aOU!pepsHS?mq097H=m7DgwdKUwkD
> z7~2SN9+h{ng9o|kzQ*L0w1R;KAGldh`9Til^XV=)O2sOTO8>}ZcnlAp*BE;QZ#X`
> m
> zBxH0ej?X6_MM|UW+EA@couR8@*>=GonFr~T25^+=C4)8U(9{*E8;Nu~F!aI
> s!#GeS
> zZCs14gHXq>bLa>|VkY>{4hcS^cA(BD?AswDj`rZ!Bfr;p*z!EBtys~eA!n#ZA(`AE
> z;lg`{#9tmVL!t%sc!tEy134s^=<I~lawi`#;@Fw}$iloAakp#e&o0b+xn;P*eBYa(
> zM8=4-8YF=*PiqgjM?4f6uC*0Q5du<}uYwG4DdNIwim(**=4wNc=4^_5egG-
> LL}$aX
> zV96U{Q%s%XBIrthRj4Q#<8P(v#L23z-
> QTxANh8b9{j{|9#5RpR<U11EOb14mZTPI&
> zhEEt-z#_VtzaF-sf4!BYhxPPriKHQCs9PTP5Xpu2u+4_A8zSvPJs!3hlTRWs(Rpal
> zr)L|O=>HXLgInK4U+`>zJ^A}Awy6V2z&3L<+idhuq*c%5mLdcs+ths1LlGBVQ-
> r0c
> zCmu8u*_%y~;{K!v6P=~#ZRbpMe@|?)3>Cp?0l$@M=g#hIvm4UL*s1p;xX-
> O1m0fO@
> z2kOr9NS<M0Ii9P_&~E1*>7%!$NS<sH@-$#**@(}=MoB)!lZ${ABI5`t+zI)w9-
> =+3
> zCss=|4LL)Ve8WRD7v950cP0(d_MjdQ8~wR2iN-
> |d@<3NM`rm0nzW$9YHd+XhfQ^g^
> z`R^WzJc$wHQBep;HW~<V>q;LNUQ<L&$X{G#DAJTok>B}A5hgkla8S~D2kekK
> &sD2k
> z+e8=@C6oNEQaA1pHtNO#qq3Mq;=33~Ifd{En57(eSZ3j~mN|UFb{6V}1|ki1n
> Z*xu
> zt;|`8q2wWrhMb}P4w2%L#)bDV%hZG+%`VjAVU}MWL((wOIR!HL(@s@vhbu
> 2W`&5NZ
> z_pUPMoZn?J%WWV@hFS7G6j_LI;-Lru$t?RJQe29-
> @E&FvyV6i(XEsIF^&v%===9GA
> zvuwb60?c9&bf>BiDoV!qTdBt5*cPU$Kvx#{0tJmsSJC|tG^cxbM~D0Q@I}dpvn
> d|N
> z;RVAzsr?rLC(Af|){Miacx*24K>QwQyvsNvJ!GoVx{8%D8ghpEC4`7eCKukrIDO-
> W
> zOxsb9hjEtoCYhM%v_Q-
> J_hFp$?kvWc1CnGI=L`=;F4nq=r3eAZIO`xpT#C5x9>)3L
> zYlb2X*%Y}mj}&2|vm1vAoW<z;)VbXm=Q>oBjPbWpeYmxU{vY9ClcBOfv`2%D
> +nvQH
> z9Y^4k2|&T}37<8e@ClKNP;GQGe?3agWDix&(8`IWiiVt_z5)5+QpJV$@X7uM3
> {^Iv
> z9uJ>f(~DGLqO%Fr{QK}p6Cz@Ibm3VbNrq3RdMI*&R!%HM2uMCz2KnJq#D(|
> p$*VC#
> zk&W3Dxh$6yVWRUiCOxMH-JKfOolh!JQ8LEgO7;4$g-
> >`;O$0^q2_(BJO!zXKd?8v(
> zCo^;xA$)g@!`>Jk7`lt!Oz5sPc#J0>!LM1Id6t?C;3cKU2&J=S!5;7}!^(D)-Ee|N
> z#xPz2T+bpUjF;4)UyWae*X%M<XJ$MvSy=XLh0%rf7d#_amaeA8h5wTESHtJP
> Zf$W1
> zt9O_r2ozrt=L`M^M4`W+5U5*;Y@jy2Nw_bf34;M4s?_a&#SLaW-
> }Ve%GeD9PXSxUk
> zf29dL;^u7?p(WxMA9~43IG&Uu#MZD<ibK#ZS@a8PT)8{EZ$vjhTlTeGzuWrW
> EN;LQ
> z;mKHjAg3=3n<$Gg@xV^+QnLQYz+hqx&_|{LZY-
> emzMhWNI=!!FiD==5H3Empi4QwF
> zg>SU0b=n@ngUwPO5yXW0B2OmU&dYJXBa~R?`w%<V<%W+l`Aa<Cwbxmx
> Y-g0#vriGu
> zODNAaN1G+Y7_GkIMT*rs>5r&b$72S@NcDJ_CZta6#?u;6rOwj;c0BlTv#l_f2{+
> cQ
> z$g%20Yy_jo=;n2r6pi2#L+rqVza+~@=f#uLiJxE`ub(Ek%5Rdt(zSd*n9K*GWKZo
> l
> z@U6oix=sWu@$5Nu$KtAz;v`V59$ktuXhtk&VVn6YLCA<N|6>p`K3C!Z23@!4T
> 2QUl
> zVOn7bsTj-
> ZC3z9X4A0IS<{6enCbAFMoy=3E2HHlmP~W1{ExjZfnOhND#84Qckv%Fk
> zfk@iGc{1Wvip8^1&HWP%p#F@{zO$CnRNUC*93Fjy<Q(33h&fP3j7xkbA0?7}i
> YG5Z
> zJ<-
> kl<y_RmIlS+$5D97}uZEnV`arO{k~eb>Py2jxIa#yJNZ#jA5C1bA^P3KIMvRHh
> zSa*)a4ndB*$QTL4=zh^C%Ot@Y``lDbWl-@!%W3Vs8u&W*7QE|-
> 20+APV^KpQ$zNd+
> zdDzU~K7p^v38H$wbdIQhj;>91Nd_A*Z1dYuf_MuzzaS#txq($20cMkdDLV?x
> Mgt?a
> z1RSB9hYif%**iyosWdRJ9tEaD?)ZdNavj<iuYU%=&JO@Tj(5?<M&lKT3NP>(kK
> hG9
> zA(Wl)0)NR1Ykwo#3zI!(G9S|Vh2;eed8s;dzlRrGcs&cV6g6Xs;e{tq5C1c~u=Nm
> m
> zfr+Wp9iZLmjQb5I0geMqvPd_8YXp!9h!Tm;L43Vmlwt;Fe7zO_oaTEI|3-
> g+bCvk_
> z?L*UiKf=G-kEZ$d9iHa<8q(I_-
> `)6kGyXk;f4{=Np3Z5$gFMe6&yVr<CH#E@|32+G
> z%~SgaeJ6HK^F5ju^xahu^f@^}-
> z21+kF<;MUg8h>Uc%p7@$XlF`2zkf#lO#$1V8gR
> z&Gz9zU(tx5?;`x0gMW4Sw-
> ^7`;oqk{zd7?N$~M^4{|}3|H;V%46P({%cCh@e!OISo
> z+|?)W<hIwFUraQOYgo2_=<5ew9M>>zx5Pg~JiZCt;_<Z|;l9JnDKhtBEq#=&c5
> G;&
> zj>k7KD&xb9D+HcIth^_eW(Jjk429eiY#-
> dGbKok+X>u0nTN9X&iISHu6PCId!yBC`
> zarm<W;PL#@`#R6jE_=cOL+}so=eP=fs&c1O8mAef2g(Dnw<tMytz?<3R`PIx8Z
> NBn
> zrIKgbgu~&p<u=I^bwZ+T>*3y##cv>*hi+}|(<|>6aw|OI#`DbTgq667x1w!j)rh7
> 8
> zO@{(ow&4cLFH5<*Wf5R1;w_b1Z2~JID(iKEu864oz(8bI)G8-
> hrJ|bFl~YGFH2WIT
> z#{{<QjJ@3bNGJla%AI-bKHUE`zm`I=_O#G?-
> E&KqXZ0LlaR1k0PtR${&?@#EGpkAW
> z+MaW$<iXJwr+9JySto+CB2xR*{AhCy_MmW!Cr^zo1CikkjL7FasGA#>n?ZMy
> @--b2
> zmJ(t55!-#|9hl~DFFJCejGVHm{>Tu#Fz%7gf|F{@lE}pziVtyw+0=EFhtFZILDBaR
> zL$f1ZATQ8y16wNmWm|bOxhE5E4*eYB@JpJ?6qLKN!oLEMEm35isbET;t>Le
> %ZwkU@
> zN`*Tm7hZ#YaRAkK;_1ks`d9d^(wv{>#c<&PazXDg;~Jb**p`u`flRs^R|Wd#QElX
> *
> zQQnxl6&Ew`dO-Bl+)}x`E*P50hg|hLjHir=iZEl;ltrGN(vYDM0GG__oA<aqRfu{w
> zV%}O>7A%mX(g;q8I?NThm)SbLl3fRG<sGBm`l_c64XNvpD{{}y)Uh545W_C=(
> %GHw
> zL$^cI19f>wWy+4fW2*E=?=AF2YC%d|)qB@v7?QZNc^+ao;l$Uxct8Cvw;uCe2
> 81@=
> z!>rdbYjBTqrBu*CEsBx!O+3=nvjW*f$a4g;$>BDj6C-
> !Z1)lyYTq_HKQQMb57ZJ#Z
> z+jy!v2ZwPtqq%Dfw|#;o-^0D(y9o6zT7dhvoj;%yeTQN+eP8%Y^;-
> z8Mjwu8p={lE
> z`Uc)kW_ngK?R0oQJtDitEB2w<cuh0!@Mspin{hQXL;ka#eHg7@#s{<?PdBoFwI
> ~2l
> zhLDt7sb1X2yRqp|R-ULp5^tD~j8-
> #yz+k&5B`Dx*!C<>H92lV1ie|ZoyxCa<0F+xw
> zboN@R;F=RTPE(u1x<@c8&U)unXVE2cruqYheAhN3(iyZHWZV2V5~{&OE$@g
> |Y+~w<
> zC3TbYJrK&lVIARtZA?ToTJXRS^mV1$e;zp$F~T-7&s~ydW2!bahgX*JD&YJo-
> DfK#
> zCq^f(!1VMPF1(!V;?@{^&f;{2l=NJxBy~InFZJh&^{io#q_0o;`I5&Mecuq-HtRM{
> zOe{c52jt~=o-`fTAp0Vxghs`A&AR9A<SnQZkg1~7@r*j^`SOJR(lxxQo{!31`H=66
> zAglrIRvJtZ5SHhA7`Gfm^HI*rT>uEeZ!gmx7TPJIAw)&nj@;)lN<Gp6BX^t{zA!U
> #
> zGr*yB6c8*zEx1cE$(?Y{br>^(!8PF7dAti9SapW4SdL!^j__2x=G=V|nuue(6MOq
> {
> zH`87H69f1+Ua^Z8Srq8egHiKZb7klwV22KbM<UMuVp9^!O_6*6^xK=(i$z#`?|;
> w{
> z6-8wg1rUh5NNQ)QPa;@^+ho~I$-i<)RP4lho<WeoHQ$pPM-
> kSGqOvoxP_Ukjy5@<O
> z7O}qEVm(E$F4M?O94uJ(drXiHZs!0g5boHXsM-
> G7fohGkoW`kCE!Z~%(rVw`P}Ff%
> z!aid2Dsc_&bH;Fl*C@Jp;+L|!u7eF`;Dmy}1MlEDy11w_P`68y;Zvg4kU^~>QPa>
> B
> zwHX>UT<|loqClcuK*(Upvrsd}i9pUW#-
> nDsPUl2&cFCQmlT<&nsL^*SFvIz17g#d}
> zi%{2mMHmCOTo8!uegpo2xW6lf02L5x3fx=ChSlJbB#?bt<zX|g`5ET{3I}c>>WB
> wL
> zd_N*t_n2tV`hGGHstBE`<4m(tX`N69WYiUP88I@SPDt|du(W5M)Nz~LSO)h4o
> ltnR
> zOqEZA@jZiKk1ukLIzHkV3@&hJHgZTf1a<R#oe2@5D?vYMy_mmvhrPu61a&(
> ?vY`B$
> zr>64knwnVCGht6nF0ihNMW_$&bZdH7h?s7inm?6Ka_4A#Iw+XN>=H-
> F|8(P&JPtq2
> z{8qX^b^Pydh}@CM3(>uyNpzSqUTI8iU}}^RzZ_S%rFje8A}D0(#GoCyXqTuhxR
> YK|
> zz`y{B7vM@rsGGRo?v5+y)C7fl7m<KEL^UZLr#h65-iMNKc~Uyz-
> ;o11QGIg|#;YVr
> z0G2dDi=*#xk-
> JX~w?*N5hui%+9<?{VvpPuvMVs*F`g<37oR;9u8F}0~`s4WFKRE^r
> zKYSPbp3M(qR3FGb*Z$)IhgP}#P;-avrPL*8P-
> D672lj~WtQvG1Ed0`K)Zy@u#n5Rt
> zn0H6__UB9dYk!rFeSL;^ssO)x=MfEYOa?-
> }yZI&dwc{mV*Zcy}n1RsaiB%*klp5lE
> z*qI4gQqdA!jJab-
> =;3E&oiIMMOAo25F?>8E1k5D$BBX>RVXcM?JxBU6vl@K6<UnLk
> z@-M6UCaR+BJlPB{D!dq8%_5bCgerBF=h-S-
> FpfM`Vo^CsReGz`kh)4{RzJMWRJqqy
> zSt3>Lb=IMGh(bBvwFbgVz_i$*jv_1%ai!E>6tUcsT8I$&2)eT&7ej&Ry^$60yQ)-
> 5
> z8yKjBB3e6V0E|A|l!!S3GnP_sq68>$JF&jAkQmN5;t9PKb6^LSG|)=QD$?Ocp>
> mdD
> zoYp{lRq8IOxhXSJJnIS609;UmERceJDGY&%rYs7e#4jwxOooeZO5{6G0n)g>IE|
> TH
> z@XL=L6u>kAArTr%@I4EYwP4Xw<k9*N?yEH_k6tEwgrU9;)@6_{+1@%|>k`%
> kfNOEb
> zsvknoxeTHqL(MLOwAV^+$+E<WqYoIApFDw}{6G%3?7BR0ldYv`K^9K{<}7uQ
> w-ybl
> zYZ0D!&{Iq5G-{OSv}*NZ84vzcVd_|_ZH5!}%LJ64-
> 2)geSbqKJ&#XC5$B&P;79yIG
> ze-
> h1)5v&4&nEO+U5Ld~+{2&*_i*e5(F18&7N6o<V`IUIdAO6ZbbWZAOJ?>i7k6``g
> z#QGoag598X7gqCaE#G8ql0=wK=;a93ueI|B@TF3%6^1H?MWK(bm6^)$3Fsh{
> Rz?2s
> zt=Y(H`$ts<Ti%^}hX+$!Jmq4V2TWN+s=_L~V-
> tg~TLEv=$7bRe@}dLBI+LJZZH{Qd
> zs-P=AwLaV$k#8=l*eyivLQcwe56tx<*t~a`;`{Q}I`D&uZ53UN^}=zSjU!k{LtW-V
> z`cm%JaBU6t&-
> dL8eR(zLF8cCn{6&|p&fK?NzD0!D@KC{7q93d@Q@zoN_K{cr3EAQD
> zs)h`;lUJEpO%G{aJsw3nuW$>5NL>e3!juXOI>R$?B|W81xE!xJcVEZ>-
> (62$MLjuR
> z^yF2E;3}&n^WKmubyp56$w%u#QUflii2aIf`LwmH$kehT5nPd7%K%eL<_3(ty
> aEV=
> zZOvvO)0vh`HyJ&}kO?qj)vI6jkV!*oGBL9nc8iBhkLPhlEUF@lZakp5z2P13cV(Vf
> zeoDKox^~YnI?Xf8GncTzXPj%L94-
> 2=dc_P?*cq9?DYc?t<)9U~7`OwHk&AbVV$8J#
> zA{+~_rbg7U7SZop!nvv6I8^&&y^1CEY0#(;jBEi+V!GMWY_o4O6TdVYVijwLm
> ANZu
> z_6cmDS}Ucqa#>mz#CG!%m=@{N7SsrDe1tg)7NW*&!X*LZgu3J+$Qd>eW86
> !i3e16L
> zKLBD2X$9~zS4p7HF)Oe(7PcqBYe}Jz?JBEjT5vk4b2lhjiKP|_s8R<XAmL~!z>QD4
> z^fD~<8fLN5;4YZsOwf^FbNCG6GNsd}j)7RzOZvv(I$ASW=KK3e@pX;^+(_j>>~
> (yh
> zJu2K^{q9zqgA5*c;M-l0-
> 42e27N4Azb67OOo$+8pqN1U!V!KB8B@~WXu|Z55(>(}R
> zG)NaU0O6XQr8N!F135a*9M&{p+@s^~70lmJe%KeC#ATcB?tZ8R*Vv#LA2kM
> _;4*}`
> zpD(yS;m{8g#Oqa)zhi1AsJYex3>JX3PQDP{zk?0yY20GT>f}t6buHGnvSN(a)L}%)
> zfQ|?25*2k-dZ8$@f3^D6N8HHF-
> $+J67Yx8fhmc3htUOu<41v<Jc+IBh;!WI{8ZR6d
> z+JJP+bRS?`d6XT1m8+W|blhc{3#^A5i%>tmNisDCA2}68kqTp**@KTbr=xOobt
> #Nw
> z2XhzQDctm&a1%6xjffKpgGi!geOb+Ox^qS$AGm3~aMMrfJlwQixM@APX=7
> <{eHJ(2
> zLQ`<lVKlBq#vbm<l^}#d*!fl<-
> U7;%23s&}%7XcKU4tpO6r++CCFPgCW|rgw^pZTb
> z2qKjC%X&d@FC<bC$^*Yvl<_+nm7LZu2ljjH$cl9Vd^%K}1sP;HdyVDnqPIzxH
> M~@t
> z2N{G`d6M>UPxB?_ckmtNyEb+BE##~yhSpF7>qBN)!f)^Yk#jPRAVPhFxuTV6|
> A91I
> z-|Z<?^zDM^q>ct~Z)BX9ws0SP=irB{gkSO-d-
> Id9%V2A2TnLX9Nd~uq^92BYGF?{9
> zx(w$y<kc{^gw0eGh<%8hu9c}6hhQ;o5`(a$iwBE|1SA+*l@Dv*Z9qg6Lg-
> VRTwi3J
> zP{5X)H?ARa&c<dCe%$U4B55dh3r-Eag^d&FmbgB$O0{hu>GLYpEgy-
> kl6U8F4+I5(
> zE86V71C@@ia8-z_zENj^*l~2dP-XH`<*CWAmcS9n+Wp!YKBA^LV~I>5NQ$-
> ?(3IQG
> z;4{JEj4_bqs$PNvmb@LQyj1SE2Ga*Zf44u!>^pLQo{GNi+Mj<Ue2@L<+j_+Q<
> fk6`
> zlgYY2<tf}ZI!PDOL&vgDOvg%Tfmj|&{AB$}#`5+jZBWvm=c7N*_4a4(g5kD5le79
> l
> zFCO{})1lw`uzQCF+v34?hLeu4L+_=<fPF!gmWs9IXmsfG)TPp)L#0EtF_*oDDUZ
> E2
> zUz^=i!!#f2E3nY9!FE{|7o#Wx!t&Lbf=joKHJdKdzkc<PVi+zqQo8#huu}S$Pq^u>
> z+nc#N<X=AVG@ox7r~INs?nrR+&`GEE{^p4b5J|NtQB{HoC){r%`^(WbJVcevi|
> (I?
> z$)~1>Hji*|bTJ0d@x;)Yt+4(0B3Az}{py_Cn0+ID01{mYEp-G79|RK#s#|_&80rh$
> zzs7zqhP^Ps7a~VIBeNmSqW2Z_T5u(CUsy;4@4kdXwyHQW74{fecp=j4hKdoO
> dI_jr
> z461u?57SGVPAEd#xxT}AOP!q>l?avquDEJt%?RYN=<6Yf;;R(=lhKS4X$FUk&~w
> _3
> z;D^2)!9#4$@`ZWJ0JD^GIZ@@;Rv+wZ@;=$VIt_DMBDhH-*|`X67gVB-
> vZ}nrxvAc&
> zKg<(uhXi8Rg3_osdT&9mK<smTsqrtrudoCS4j1djlUm^d66anaL?CvWhKt?@%
> Ef51
> zRJ~7Te^X_mPud&U;8O3O^igMG8I$5cziQ#zidB58C_r;^C{n=U*Ue;msVot>JC
> p~x
> zNSQ$_a;^udA`enjaST$CfzoAQjNWP#N>O*A!stesU&8mQn*|xZVbG|n@z%I
> Zz9B`6
> zLEy6b1i>Y+p+V3=e?yM_7fz}|s0KDPLANZWr1Mv*;{yU2T8$+PqkjJrj2@bWO
> ?<pm
> zDRl+bKE2i7-bG_T%?rs=f!OVULFVW}QhE+w1bIVgp}L{8%W{F(1c57x-
> ixL9180KL
> z$(q*cWUviPg!_Ai@ro){V;jXoA#CueV|o4OR&24fi9x&&265cdSr%*!L{rjMl^9f
> 3
> z)3Fr0zzSuQP0w4BoBA)Bj;F$g-wY!*c8a0bqabJrRCils-wJl-X3>=&r1uY+m6%%0
> zU1UbM+Uve1cwY^(?vt$h5*2$j1n>S_auc?=5>R=dKyx5r0PI0Knyb{G!7tDmF#
> F`D
> zUId@#tgQJEUq|3;30kRK$gcCgbjA#>KDUof^-
> Ud<ia9|Hapwc9bul)Jq0J98jCRui
> z>9W9v;33|DE&c}GWdamYEi)(+UJ!yoC=pfk`h1*L2d@S;U}rxNqoGO-
> C<0rr7ACLR
> zr8-X_%L|hSo7CU<R^gAY;Aiy?-
> >{#unxCVKN5~zJezXt~S+7nV?o15;6{XQ?I$pWo
> zX2l71S^gvxD&SBCHtI)$NuGKztBPgbDpKV}_T7DfrUW8%i_oC}BJX5tP}0D+iQ4
> uO
> z@a}mn7(!!Fo*6>unBJ-hi5^u-BtGO*6-
> +5Kji6XH39OI5jX6(XWMJ+G__jQsnH%`W
> zz~fV+PhgPAUx7@Jb>8ntehodz0n?m=06IWfRbEN-
> IP+wRb<5NBFa8AeM_cpZe}X9q
> zG+hR1HJbu#+VO1bG7!KQo~h2qTcS<fiA&@sKETBA1di5;6<1!;j8Nb%9c>TUtp
> Es-
> z@1gT>@irt#ZwLD@nwzkdNCJNSox?CQwO1wKZlY%lvUgFn>hl*ffIB#NU=qZ
> *gUJv^
> z#6mG5rps#D1JR#JaaimYm-
> !dL+=10~aoN<orB#5WAI*C?h&@B<OfQHo8ibj02w~s@
> zqH+*oOn?d!({l3yTc%^38#$?muX(xA=5k<u4``2p<IZj!q6%cy(yJ2Fmdm3a3cL
> WB
> zh4JW&LmAy1GT2}2RBVI52byvK=uCzDkC;h+IU9-
> en*79+JhTpuES%`_qT4t+L>Zv2
> z8%9($J#SF^xsu>OJvYqtDEv<j_@Qga9kBbMPEbDKYfc!^^?1YU0m7jyKb>H(I^
> ?kn
> zu~t#zFl;N_X#ADvU&2jCG56A%yL@q4SYaq0M6t<Dm8+aW&MIQ?LMiHfT)(R
> Rava%8
> z(w3a0-o{&RzF-o<<YN3}+T)1WZ&hT_2mWB|y7_~(9Kjzfelz5Ifk!C-
> MZHSFJ}L!F
> zlbfmcL7b~=GFa?|fCd)acG?>+F#0UaG-VZqfjT-
> 0K;(BWfn<VRrv;rM8pO+J80lE$
> zM`9v>8)gPWLc&djIlU#iXeau2B<UV(j!*T6dV#{g1Ke&P60>&Z!Cx9DhfS?;1PZo
> R
> zs#Rj8%zH6$Gq*K?0kSp2KgO8{ZbAw^cPcO#PNl2W$9jo-
> Ki&*+_atiepu@RYwkMwR
> zB38s@HH9L=1`v02W<?7(_IkLd74(O_9gAd9pGthZs+)t9Q$Pnq99XZf%s05hW
> He>C
> z2yIB{Z~jSSxU_L}wW`A_X0QaCY$Yv3*eTMy0!R=n{V>eI+wm#>5Z5P(no$%A
> m{d&`
> z4k-$12o-3|7*fS%89}=iZRGGs`)OB^tof&@8~-
> #MjeoFQZZem?$zX%8PqU0Q*b8g+
> zRI3l5P+_o<d5Q;diql%%PBoBkMyuPUe0+ncOy)!NK7=ROBrcy#U&1SdLk(~I(_
> L|<
> zKLH3Qx(qOq{&)UNP~JYi9+@Ej$s6inl-{^Z78p`ep{V5>vFW$`-n?Z<T6!F1!c^@S
> z24_6jSi}%3aO)El>){&%tD~qr4UNI=$Ra*E+eLeV3j!9Y+smfr!!fF2`<GuXgs}`t
> zb=kCjc}vE1N%1comPrACi0@4amcKEP_X;)h+|-
> kJM`sqwvJ34zPIfmi=9*ZuOCMoy
> zkco*3hG(Di9sICYYMSF!kodT;c;}x<qCB-
> aKnm|P3da3>tJ$R$4D_B}a=|RFwfo5D
> z(KS}HKavuCHuba!uB&fCXb8Y3rb4?sLsy3xtsqhHoMy<uFav`l;OyDd(<sVJ_(tAa
> z>8X|B$mcMas0c@bU~y>hq6Bl50t7_~hQ#eK>#hih3*SR%_C@N^fwtGlKe9;
> 5vMy+U
> zhQpzBH~v48KP}{EW3UB<LF^aEtTbF?o0*kxX$nls_hPpL>{NjDDgc*>S>~_6fRI
> >J
> zG7Y<klo`z_&`68M{N&66cw;u3u9fW3W`B4#=T%5#O#3&$p;k{~6S=U!)$q5wD
> W^m3
> z=^lW4Wkn$kJYazYJke%|E(qz>9M6GLap9YXJDqZ31D2IpZegZ|k0#q1t}!+AcW
> VG+
> zBSa0|crdF{lWDG2XO(hV1@#M~3k&lir=pVRL|+)HLZP03n<3GZ_#<t{9NiqJTC
> ?#F
> zz+j7z5ZPck`a%YQMJ@u94FW6Ol+i8%jG0qusdB664|pd*9ywDGLM_#(C3S74
> <Wt>p
> zrkIk)x+!N%$)NBgNy-
> E7Vlj&w*Q5LMIN`U*3<BGjT(E+||MC07c6Lb(7QPZGGbWSF
> zxvuB=g7>LcVQ(tyKJ}yUo9HFW_ZzOE4`2(phIhnM>wy&&d<5gInf$tV<-
> o3j4&qV`
> z8}&JG$6XAir!<92aZCqEU#gMd2XGcl{E%=oGvJ2u*Zv3so&j2AgB}7RT|qYh6c})
> _
> z^^#-
> gUN^ZXS{VJE{_I`p(ds|){3APuSdSWs1x>j|WL7aWaTx){GA_$ql3?(_3X|tD
> zjC#vOD|HeUc=>vZMSAeIH{5SMqO9c;4GF!>rWS2XI7x;5lj(4?@h9@2Qqs}_D
> by<;
> z%U~#hluo^9x`jOU_|lm6t90Lw=*6McKDZID+?sKs68&P7?4Q!O`&*7%tz2T49
> m@nL
> z6!}^q4#biiQWa^l>;Q8VL=Til?!yAX$o4B}`Gw^sG8O(n9@(CT=rm#!*|pUMPM
> -7`
> zf*2jFt_FhET0<<R0}C}3iAI0ghXp*w3U>we#f@G*LNGNo2V%5xo7w}hK77ew
> fT8AM
> z0C8wB2*m!#1{o}dtJnP5SZu>rwF!w<zrYFz0u);d@Ir(>(u@_nZ<!b=aBKh^04E
> Og
> z0W@jzDw7NrP{wl@ozt!%=v=X6u4vrxnl@mUm|hHd*9J=pM9i%?2qe~r@W
> pBpsy9T)
> z){VJ&NL{cE8c{PuCifnoe_^wU!_m$}b*`P;&VbV2h1Li!Y9*($tzfoxm{X(M^2EP
> _
> z&e>0qI#?P_!1MR{%$1Db+h+QE8tRw+h6`nzr@z}g{oQ8!8;<pD(%%EsEyrYt+J
> -VX
> z`G9jP)sVN1V%MQAAq;TR#*9H~oV=$KVy}n~Qp4rFO)DEDa(iPg!~>Mvbfb?C
> DhCjT
> zcCFCY%<85!UZDQm$5qr92h{KJmRTnW>Fny?thXT5FynGzcbgd;TzMJY0ZtoQcl
> g{V
> z&>haSy2CK_B~)wBOM?k9RZ{&<$8&V&nJo(GFGyqBc)NELIcfs@NG}uahdw_
> Ef)c72
> zhi)K-%Rb;w*c)^dA{u;`z+1_ZUv!?^)f-
> F@vyjz&M&bObo6qP#h3aQ+Mym^*qrT_n
> z6%}F?WFHW~1b2LGj#}bos8kEYG1sqZ-3-
> RKeY?7vNrEGd+>z_lrEWe{B+A$*b#5l#
> zy;_<Ssv&Mha3780krI(wC#gJqG1SEXYlHNl(_>q_pL#D3m2t6a)&+l%clbXVP1P
> 8F
> z%zy#?Hx_`7R$}5E^U3T_GoQHgM1E%tZk5!tm|k6uY2$FUt4mIAJx&UC@Zzto
> f8l4T
> zA8Rxqfa)?ha250PUq1~Fy8bnvz5eXV&-zrAyY1ijnd;Bp-pJ|<65_G{`2>VO`?3Ek
> zOh#3+q6zFyx1-+b8?PSj+!6dcmQJnU7p~oct+Mih@WE=SwQSJh+bKP!7t=N-
> a@KvN
> z6`H0tNMasGfOJV)NsO6dJZA_kplRlYq~|_qs~FevdsV`2alVAkhrv4B2PouVdG}
> mu
> z*~;MGGjhzb5c{t)RC3v+zPXPP&B`jP2#tHGG8t^2`#4kMH@B&6ITVtzDIuncFQ
> I*g
> zmDOo@PK{7M00?G<_zFUCw@xh{Cu>K_-;MXo3Hn|{4!)@HZ)v1ypBv|-
> >AU8J>#x<g
> z0iP;UDk<jr&p^BA0L4xZJ@=p(ZpB~-
> MJq2cGdEA2HXec5WLqR}eGXP!JI>A8&xI|-
> zSU7*mYN0xjdfb~7v*#Kn*0dXWh_iL=A_w9B*KXw>)_(1twO_lHckJ_PbW=Q
> 2J`{s?
> z{n~xXhw&6jf%sD{8B5i`OrhLG<Ql5NuM~(@sm_&S5VSlVW2f(p-
> KKAj|7dI8=V7yi
> zwn3v1c&Mf`QovQ-
> ?H%eXk00*5>gvv>8?H~h^+lxBBvRVxFw&c5P(+rz5)fa!=GvFH
> z<%=0y$}6y!D+bd$g8%f@_Ti3BC=YTE=wZ8++s(j>mPvMIDv*S(qV~7SZm`ihE7
> CZ&
> ze3%CyvIMA<Kh`ZDi`z6AKo&n>baU+|^jhBiSoaa;F*AOWvKhnLH(@^*oINtSc
> u!7b
> zC=EbpJobrAI^6z{j<u8A8!DZQNuZ-
> s{AjW7MBSjET76SI+q5mDO}42=$^Nof(F(+)
> z!0&n#0H95KJKO<`xG&CxC8L)wZiB>LdXL=~Z`1qY$9&7|i!a${^p_?%o1<IW1m}
> <F
> z;#OVW5SgjlUfU0MdW>P%=YP+<(BRuJu3?LYXD8NP@axp1=XoaV57oVfvbbp
> ;K3lLB
> z`yb_58zq6U;plyF3IW)`aVx6xh-
> AW!{77cf8QV~Nt60yuC$BfsrMcm+gy^*udPdwJ
> zsf}U+AMjmbhn+m}xeb3#$`Dl3qOcyJtjGz7<iInm-
> +!F>G3!aMr*N=QI)>qB+u~5G
> zT6q}($uJjI158bnbQKDm^c<LroFx2H&LdEPx?$j8YPxiXuKVTDJk!fU?b?}h^QGb
> h
> zWgU;jGyRN9=mSJ&O|(WshV}tmd!~PNvgE+&7I3<FrXNIAutz&j2rE#u^yHa-
> k*)Ib
> z>?)h-
> nZ9AFr%DZ}s}wI}zpZkQt?~h>a*uNks{ADraU$~M2ANIv!54EQ8|SN?WUG7w
> z<I>|F29wz&b&0o14XLYSW>r7Qv=TuzbSsaODx1V^LIRKDyLN^@gA9pD3_T9p
> @8#!l
> zeGbthj_><kAaQm%UjsQ)oZkZUL*LF4{)SIj@NchHZ=5bmdM&M_6<EE(5gnqi
> fsl;?
> z8EmLjKedox18nAEE(Ck%qhkeOau40(gB@kTboiT?ElZ&<Yq$DYg2zs~ZDFT7Eid
> z3
> zfAwojADY8E+FyN`InWTgpZsq)Cps;QrX4&p_t)}FH)eoC`C}~eOuk4mX|HweF?
> 91<
> zA7)N6grc6hPROncj#lGT)LWMetm_i4*<I$TizD|1VHEesS37(OHKT;;Jazp9-
> 0$HP
> z2#2xi1aDm~u&ztkWuB+5)ELYwV1;}L5^O@3Ve$eym?MtfFH^Kdx!Zg|8B*Je|
> 3bj4
> zAyfkL!Lto>%;RmC?5(D)yAb0)8@@a=Dg)o%6MS?MlRI%_QXUS6^B-
> dZW{f!yrqM~P
> zq%(ZHemIQHivdi5Fy!a#+Rgf}{3;3{F|!urWn_>K{%vGm|MM6Fn9gaIJ)M&c=
> O>D9
> zwM49A7%Mm)sMLDE^N7nX7);3+WI`Ngu%~L~92O7ji$l}Lh$DIqMzE)+M0VW
> {QQ^ui
> z4H+5>@DMYrUr&@A9@#ZXs@&^b!zwe!$eYcnnqpmLxvla+^qHqhkzI!%D%
> >hHq^^>g
> z)l6HZE4yBSlNb+Vzbn$Z0L&sfZ2@Po2BzUOH{5*ZQ5x`=HpVzk+$yz=`6}VqLXYj
> 4
> zxu?K18mM~_9D)phhyKxDpK5TPK_bo~bZp%ZEs@{)@8t0bx3s|Xkq(wP-
> <0_L)Pl0M
> zMd#Y&YnVJ8p%kl*Eqj0I$%MR=N##hIj-
> wkj9lc(g2Ve2jWj4p@?&ssn{<dhWO)hZD
> zFDh$WdLj$@=s8>VNj!AXYa5%Hn#NBD?57&EZ`z<!qRj>2Vt#np`=M^oDG(cR
> 96vpV
> zO@t_&2N6niz*Ia8kCwt*U{3BZ`$}d9?i(u7feo|#r$i4}y2-I4Y^;-Rn12o3YSLQ|
> zaB~1<^=CUXrJ-
> GEmN>zb`26$&G?#Rf<Y7!k2R%RaSTtAYHqfG8#Un3iX>MBRCOQ84
> zpOzZOm%T4^ljOZj7HSuj{Y}&DB_>JPpj$<{7dteq>Grh!6h!-
> kFAUut@_tyAD|D-9
> zAl-OqssYDH8bJLt$;hO#SHi>1L74Qo-
> DO(?KiHO>b!?|OURB7#f=#J$1OczXM79fT
> z1_vso(m&_7U8xhC(HPG-
> (QiMzEgyDzoeD%=WzCnEM=_>6=NCQx!&{z3$*xmFcb7f-
> z3_p!ZD%A+oDV}@cM?6m|_WBXq2~YH;>8`%LCpsxlJW(g%P)=(u<cj$N8QeM
> e5z*@r
> zIH@;*z<0h>wvREBF=R#aTr$`?2&x}L2tuoi2a8hBzKc2+(`b7)6Bn2G0B0N!)lv&r
> zLbwtQ_c<mCR^pE==mlbfP`l9*jd4<z)z&Q;8Ym9OjmYv-
> 9zm5vm5H^Kwr}c|BBNU&
> z?6`ca84+H<$s_4HHd4190e@u4gI#9PY9-G`<Pq4c-
> SrW+e8B28!C<4<ZeJscE!w?=
> zwc(Vk)@dt>ZR@-GqI3>kBc8Wdho<2)YRXxp%fTD8YITQx!-
> ~{79mQ%g;p|5dUa&bt
> zzUxK>Sry=nNC_-
> {wV)#EEvqPj`wBbGX~r+U<t#B~^Co#O;ycRpIh4rBng*eZT~Y}_
> zeyjl{{y<4i_$*YD!&n4xLBO4zoS}T7_fSG;j-
> IVPuT=!AX&3pH+#X%rkb9S@XSUR{
> z1Mwxe%-
> <_FTJD9n2b4hgG2*}uo~Gx(KMvkZg%IibQ`xpf@P5WS1U&$z=9KMRY8rM7
> z3QYY%H$uYMlJ#trWM$`1_)S*qfIlEN+V{$Z;(Mhco~oH(O2l&MEO;;h5B;g^HB
> ?!H
> zca1_-PT4kF<-
> ;ftRZ8J2@JoKNW1<#SjBwYFipOGvjB^0TmnGTW)he3KcvmaEiro4&
> zvJ~9qC&0iU!)p^)k(<yKR0IFnW|_4)*7~7TtdpRH(e|(HTHHvp7(jsabGVW3{1<
> *S
> zp4!nj8_#{RzuwPzlAvqxBYu(DsP6Nkx=*8eyhSzn8-wabqPh_!0M(6l!JC)5GF5??
> zCcv{5cp40{@C*-
> wMg(PvD_{CmHsjfzJfL`@zbE~0rb$J4*#E6k6U=k4#cZ}$?7@oh
> zex9w!vOQ2HiagYN;aE~&X+ql?hO794ronpHQ11wAAroTD&zPT5Z(@Ed6`-
> yqN_iLQ
> zRcNa^{1bE;Rl^gEy9$rly!;HOi+xTZIMj1^TJyw^(6qB<@pf@&G#_%+NeCz6(Ye
> 4k
> zlhgy_Jvx_$3>5%eGON93XRCRw>ME&nuk#rA!V{6pYL=}sTx-
> j1l|Q~9t4h%<kMmZk
> zA$66^tZued8a1y~y@RGx&10;KE=$zr%o25qt#W*Jm7-
> a$9p`DKhSXKcn&bU3rj=%i
> z+KT&sS!I*MV~-
> ^CYQAHM3i_YL_hopm%$j?*h<O>i(^#wG{FCJ0m0H4=&+`R`Y3asb
> zHFh$dzdDoy!<P#WkODcScq&U*7o|Cym+0xn7a6MFJl8fthx&oZ0P&2TCZ;=a
> Sc!Xo
> zx$zn-
> h+EZqN!^~sQsgHSKL$=Po@MqWa#^xnS9!nOtGC?sN=5i_#8qa_G`2I(iEKT>
> zhlF;G6|TD`w2=?F>In(1Q)tCCOa^0Af!h>F3=J7t3vkJ-zI2vm8ic@@g()1AqSaa~
> zTj8O#lf)zH!E;F+C<Y>`uvCZH8?i@@Q@=RJQVCJEoI>UgHkSrlCv`6M`4$Zc-
> KNp|
> zvPG}A7rhXHAnM>3Sgqc?NUD&GIG<UhGu~!1?gAUTqY2U?u%${44C*6jkL4j!
> Pg!q2
> zej|m60eq`cCsHBVp7%K4FyrDEGwF*W3}Hn+Gdd}sN#SA2cd=Zpcbxk3SZ`}C#
> YF0S
> zQ{Y=*&VqOz&y?j%(Zxk3gnojzkY8wDo2UBRPf=gstui9P&kjLmBnA@)9R<f!9=
> Ra&
> z^Q;11TCNKqY8FNcpq2MArZxf|Wl0;MOUse@v&QX)QJ_HtP>2AQYTv?0bg9N
> 3T0lH1
> znoC74!#o$kyL7Br(F3dW-f-I88;1VE{o`~ZZ)K%g_jMu%>mJB)E9PF9-nq)-{xT)+
> zMXM3c$be(FJd#dKdmt~Kw=(tL%NMu9hH>#-=Z4-
> Ta+X|xt<prPR=ZZQY^%D_7?c(&
> zrrZ)+Q4}OSqy3;4p2d%x6NoX00PVhu!IkZ}n4ZXBKR&lC*uLmO!7+C^f^VYw(V
> <Sj
> zn(6@z&7rzBPk5(NU6F-=?zL&C%Qi??Pg*oiTM5p>m!RKt2CP-
> mAE_bK{y^3x4+^DR
> z2=ERKrD9{O`z?_eilQwcU=qeQ)hq8Y4-
> DCGy}F~0&pc>B9V1Z3GXT)bhA|Tdx*onE
> zbhw^@F_9)R*{MOOH$R7Mp6ze|{Q09oS&XyNn$}(n3y39W2M!>}wzJ-
> qYLT<IyN8RB
> zTEU{SR#p(SzQZn#fw{P?Gtyr*LR9EemgEam@~xz_Q#e9Q!)W{cI?Zi66kzW{$}
> DIg
> z-
> >QW2Tt|bI;HrQV9^8J9Ug!&7p)D<l@CVfa#;D0<6b?MN0go%Ba+$j&KR0@C5
> _|>G
> z9$<rnLO(*K4MgKgdvm01P3NWxQcrl_5z^df5+Yx*80-
> LL*^_d{4R#)CVf0jDx1$>4
> z*dba3aU{7??}UEk={-2_@DO^ndO-
> $1I*l9Cb`8?6wy&D=Bu6219KF}qjur;$$hIh-
> zZf;Eo0U|vQZ~WHKc2C(*sX);=x?q~txz|ksT>x%)$>oNb=YS>Jz!$ne%@f!guTs
> C0
> z`@+Bl&pcwdK)ZrqjI_xHR-
> 5x>^e>9m;|jx0Qwa3Ie)!mG6rAO6)@rvE&p})!?ku+H
> zokfp!VyC8XwTULP5a?lQ>Z^4P&(t(pMc@bM8llFA2pJ0ThnZF5X(GPn4Zz-
> 11&kxG
> zsflCi4J|@2+k0?2gE0jrY>0D8Ggt?j@h#)R4L@eMv%a8ny$AzBGaB4&%hE2j<*
> )F^
> z1b4mN#z>+P&9XcYtHLxuJE{8MLg`o?Llm|_^{!1|Xiu(Uf2R|4XisL@ZXmKld$v
> %^
> zZjsQQ!IqWNM>OqkIvCjUTJ%tE<YuWjFX}+D<V$R)e2MLJF3L{~LR-+>T-
> ZYV%W>VJ
> z&j<U;0RYnLgo7fU1Be682N3g!iU$N>2Elmx?I}Vi=WV1r_sg6BWJg)-84{Jqo?sIs
> zQYqTk$J-pX?;m0&%!_6>XCIrhPe&@<he)MO%}r^zMn?}~$=i-
> TLNF0+_@Z@{{u|zg
> zjh2RC)UNcez=;Yp1+gK~IOLNfVA3{-
> Oteim37~+eQcw9P@i3D2BD6(kq%YaV;m)HT
> zpr5hEJ%WPx@N}#30$bxA>{Z$t6R43?#*tGHcQM|a5<vn4-
> 63lN6AP9M^9!3`8RiL{
> zkYSi_8i;HP>wQSgFikjTlec{TG7u<G_Y3^WV5se#3@U7?;b`HqI2Us;)P^-p9KhI}
> zJ1lSEl7J8zTs&dQTznhJk7F?J!BIFrUJ0p{&w#9p#t0p-(Y<ok0LAzl*nG$O%0>g*
> zB?%Ca?96_+4?;}k=ygC>tAU*yDCnA9(Z#zu5ypli`sP&BrBiA)^OGC8usMfO&us
> pR
> z=@^&IUr8O88iYi{<L{j$JbpcfI#!VvH9>RttRgYKiQ+s6<th~rQ=T^*4cC{;TOScZ
> zDg0vUM(CHW@o1hsh93}*=2*_`cOy{wA_!A-wgf8YGqdU-
> 2HgVFl!Vr4x%js;M9O*O
> z;#l=XNIq9CYRJ$k%0&rG^Rr=+Lx*r2El3oi@2ObGj%sW>tIY(EskTuWW&qC|95
> 9xs
> z7ABnIKoia}xe)l`;&mOVrk-z!7=LZ}1s$*EMc6$t6?2~hd$-)@;BfOqk{NE>bz*kA
> z05ev_Mta(%A$7YXlFS=&*s4&sYZi{b(ALHk)*YC=`1kJbqZf}DNoMcK>~X9LA0g
> ~X
> zghf=0d?`m;2y`Tw7T?{7L<(y??L~zi>0l0`rZ9ssT1y+LSiz`wAX{g+%2IK<P;siJ
> zRF_y5VNFDdClXKcEm6;38)cF)yeica>}rCDFD%;%FMyZB1^V*k`GB*`!)H_v=HV
> 00
> zvO>a;$YYTMtGIGY<mXP$VjjRuQY9liMAnd+$jq!343!*>!8P0}C#BlHM@p@64
> siL#
> zGfeq+EwK@4s2S~|dPe`HrbJDX4)anL+@)iPv>-
> 1`J3C=#t5&y^%Nh=X1~!+SVv5;`
> z7$Ox-
> r4>7)`*S|{{mCzX@OvCp2oELE84cG}MHw3eKDcfy5sCK0&jorKKyP878x4$G
> z$COzVX`I`oCLQhP0klcI`V{ZA#?k+Z!m^5%OthabTB<G4iiI6=g+7Kj#YWS|g%(0!
> z*%qNh3uEpSN)rlGTSPbnP=Z&h);x48C)XN8{J}<-jrg;i{Yqu9!IEJ+&H&-~4vy}W
> zRWxYACcaC;)@(w~N;UA}3}Gua2?m=OIcIw*!pnFg=U_{}V@Ekc{S=={9$+LC1
> V6C>
> zQI0{GiQvP|K_JyF)X#emDmn+*J3G`5k$sNxHt5G`lf&_fjW}`?uUU`aF=as$P38
> ~Z
> z5l%of8F0cECua~w{1~3^W;B_KjinXqvp8Wq#FT{X@rL>d>gYcV^|QLtFzFR29`U
> `L
> zNusToSU_mpDhqI?0IYI~h2n0Au1_ZWZo?qU$UeR$V*JgPeT~={#IXIP#QfQfV
> JnwY
> zgaBuUEuVp~FOlR^yyBVY;%7X;e`xcyJa}k$*2o1|xta$7=m!6Bf%V{(;6J}O*$mzl
> zry9D9!`1@AeK|adfuX=?J9i3mJt52m8`U~QcZvtsCMwpJRXm}YYYZ}hxz-
> AEJ*zD*
> zGHNT<3UjR`bFC|_S)0XN@NETiA@Ywz^6`#VNXM^O=@<f^luB$M3X(5it|^r`
> K$yr&
> zcbX7O15Jpf`njMItZ7*=@g!3d^394(mVs6w&J-
> 3}<=CA>H*jf;&_Cxwo>@+>vz&g)
> zw@H;chW=RwLW!8`D{0Hz^^LX9AzX>qLZ@TgjYcM{z*8rsin2e$84_khe#>$x;
> CiVu
> zG(F>g8Eq{$tA~vHCD*daiaqKF^&eW7OU|P7Xu~o#KR(E_ilU}Ofxqz=BJghvjW
> }0U
> zQ7`Jb--
> <54OjBnMAqkA<lZFfx0$ehy<tG}Rp;mwq(*f#YHr=DrKm&ruxen_YId_0y
> z)P=c=uo+Z1VhNlA#q2Nkf3mlX_?^+kJBd}f#_CHJtFyAP0?ah^ol`tmX-
> JI~GpkgQ
> z!K$GPR$mgV8XUyf1E=9&Mw>aih^6nm1pN!Z35Y$Bi!W>i;VWzXP<mT%KlXn
> ZLjf#N
> zL4ad%#Dg7evPsmIdKC(1OEi5J?-
> ?kHzKkM@dMGtjjD6*n=%G>^#_L`PDHSQlvI<Me
> zK1JjNdc}iWh5gVHMw@I4JU=LUXdx#-
> JR%s^Y`Rz$l5I%MLO&i*N<rijjdX*=13@VW
> zKw@$*a}6@*M$@w+#cq3hKo(X#hH0X$NSC%im!?g)op6l3N;i7SqP|!rwnPtp
> Vac(&
> zeK#(es6XAe6uuAqbmJmMhD6ivTbeJQ6fEM;iOWKZ%mB|t-
> @71Q(+WrA5Vmj1f`tom
> zQ_!$MOUw|UWm8#=LWG@QQ&~_&iY;yvYg+FKKn)1|tfH`2MJp5uD(XeiS8y
> n$NcLHB
> zxnk(nU(T5n1h7;nSftxn&3=CbOo}1XhvTKjvPKHsQN%mDa1H}NIgzVaJdWS@
> U5+EB
> zIL&hpY&ihPjZ8uU3SD~lcy;h3D{OTp_94G@0vD58bKWxcn&dL06=&$^=4hZ`t8
> DsU
> zFOD{&g*fc%8DQW31_v0Xb=N=IU4l?vWQiSaJt=tgK(bM?;Cn_sVJVi`LD2FE)=E
> N(
> ze9HO^`83}xC1cWHeOYi)-
> =!`jzC$`i8%m5+WBsk;xkO4<w5b1C{bA>FEOa0T0#TkB
> zVxseqXjy0T`7J!-
> EXE6T;mKJ7_m>v+3X<sVO2f>+H#peoTbMeDXiyBcsC9%;Q~%q3
> zqr?l3=9dShxWq$r)c|y0Lq3LTGrvsZmteEQ7&Tn}Gu{BxM@#xX=UAlkeJ0<1(T
> y4*
> zIO?>hiAaK~>fd_Mm=mhhRbQ2DPK@7EQPkE$CZfTLn)J$`e?{;hV<Eu-
> 8Is7CDporo
> zvh+;Dn?ow#Q+<$MDI6KDwMD%FG9?grAg{8v7sIB)#*Cw1=}I|wPk;>sfVVs2
> zM}nj
> zt5n;bCJrOS0NKv-zf`&R^80K;Bm6qT*|+CJjt^|0-w?tTx2VbTWl!q#)G2`tH6PKp
> zYHPE<Ka}$(ejX~Hn|R|vi#nDso|UiW3G{E3Wv~%g!%kT=2)|!oydH7^t+Mbo
> mQ@oT
> z3sM8Yt?bDb*`)G!D^U0a6FGafO>KewI}^_!`+SDP%fn7WrGoH;^hC4)@qMX9
> 8f1zo
> zS;`v)DXE=H>d^(*4-
> uCaM1@C~5bO2=_deI#h2Pm5UA$eG%r4Xg<RGG6mvADw41Kek
> zR3aWMQX70Ukk#zJxw~=3Bv3-
> X74DZMrXzkziNp)D39x31%ZOS4$$>e72M7^HCD<N@
> z;?mwpU+#8*a1WpVV>JO&w+@h=iG-
> %NcW9HQj{<gi#z;gr&?Vh`j|s|$ofjNxR@dG_
> zr3hXIyMJo7?zI&T?Zz~^55vdxGT<>xn0>^%9On}MhV4rXPQgNgyV-
> Mx@SX=8<MGj*
> zTzn6>i{bnoKk%JL*et{Ygm1@^bF>j@`JpyQR_jC`Oebgh`c<iI^9*7WEn<5qPxlI
> 9
> zHG8d}WIyq0cj)j+XA}^Y$5k;@;x#3ZRnR%-
> HReshbijZKc*gAmc!BAcErCS9$fhH6
> z39!9R{0kt@m@Dx7tSN_=<BS@%`i`|pg;PulM1Cs~fhY+U;sOg@AP#h|Y89f$E
> Wh>{
> zQWTaj_$WMVo`bE~0RcFkAo<CCv<PwMq=N-
> >S;@ioFZdp9ExGFI7pOdJnE>T3xw!f7
> zPl~XhPc`->ux#^%2XU2#)A{}|FlhIce+Pnzr;2zypasoqhCgfwy@`V)2$|$}LnaYF
> z?!RCFW0_s0t~(A5!O?pgSIPa}(dfGlwF}Vc2&+QEpn>*#Pw|v|u)q*ZNMXV>S
> $JFD
> zzQIST5Am=H-D=zk&CL(jj=n${#;LwlYR6vonxE&gX|c7)BUjJx-^#$t){sH&i170?
> z{J7n4di}w+#I{Tg-txOkM{oUxeqLf^)u+qMl-KB+tLcqPA%vr9IvVX21ertO79RB1
> z$0<DVtd=2P5A;X;8Ty>^T&=Fb&kziki$H___its`idR1@BVdVxUy>AzxA;_ard%
> <B
> z`;&Nj7|g|>H8>xQLu)slD?5)Vgg)X03W75)Q1EkbAT2{Qw>PutW7;c-
> @D2(bCz?XG
> zH-kyI7VYhZf0{WEHE{~oQ#h{<yX=ifiQb10K{F{$aQTy(`x|ewu-
> ~apHO=zgcY#0@
> z8XjwCw2hZ*RH^tmwq3jgLfQqB0S~tD{2EQ=p0;`MD}x48cR%r`i|@yxxOG=o6
> qnwp
> zDgUu3zB~4lqG<Vr@zD&ug<^;cfKXnTM!tHduG44^8F&ejfLH|`h?|8-
> c)d5?M)vHg
> zU>JBCuPq6+f&G|MN8m2JPd2dSgMX`}r#<}J0LJNoe?9U_{pFLE&-
> Mxqs3^@DB)feU
> z-?y+x7JOHK27C)X9^Xk8-;XPw_zDd0o!%W^Bd^sYE|f^$M?M3-
> b3pKqq3<UypZE$6
> zz;^<X%Fq}4$qTDtl*rmoZa>0)vP`1A<#L<aJoVcut`T^^8K{DP{827UVFze|g1~62
> zXuzSo@D$8(h$oZ7D0<#6xwzI@zVr$Y35~kWY)d}@Qej(qL4g<|v_S<%gv3<FT
> )?i-
> z3%79u*puBl7+8NGvs@$dBG!O&yB>RWB^vno>Z?8vyH5X?!xf2$Ke0If`6>VTg
> $*Ui
> z8NQXL^=nyqO!)ME4dLO@9XZj)oD2WFpwETx+>@L8?uCtbdJ#`ME^LnUhcPb
> l+PIf5
> zY!3J3DWJ{;xgY#KvGv;PZ+O{+jq}zA{eUU}tux<{Ce95t=q7$W;B6w61;`<s;=7<&
> z$SNKSka79T_ftwmPE&vE&y`MJ(i$6s2!OG(1hNbFA#Nn8otvN%r_MH?5XWz
> X`l)0%
> zl^Hk-<VRmAfi#R)nhfV6gZY54yO-
> lrW?~@p0l5B)Bt>37u5+Zs#m$k2IoDjCpE}Vb
> zyj-
> FaG!}1RnAs25H6*0X_*eJU)MGh^E2wsSM4LwDBY)(4b^kVWb3@5Q96cMLBJ
> xs>
> z7aqNBt5PFEqWeMl#m*Q=RtUEO87rDzoYMkzxx_?vP!s)1r~B_67V`g`JrG(8g4j
> ;z
> zH_+P&oHo*lf>H*|gVu%8putEhIBg<MlI(=?GAAC6TLS8s36{|b;ZdIdSC)nqb$jY
> A
> zdgp|P;rDPDOPjW>2YW-`iyj!d^+2Cqg~<l2eh{6NI=9jr#)=!p(fuXiiM6?U?SWIj
> zAAZP&Ve_n6yeyiB(@@rl8yS1(&(zHrAllzRXbCHuKUE4Eqnpvs8CQf>&Ywy6`3
> fy(
> z|BuBP3u6R_4MXXcj?U`W6znN_^W4e~Ge5u{A-1=!yRh@A-
> f$Pzy%nSd{UN5d7W@T|
> zwAjTphQ<~d8bzT|`|yyf!g4y>^_Ro~e5`8rdkmKvGBjeG-
> F!VaPx?`BQnnk@X`t>U
> z)I{^pXS}_mnZE4$j*w=qX3R}`de8MrY-
> OUeJ$tVD(1Lq=$H}%iPhuRxEM%?2IP5%D
> z4e~ZeL+a+pp6gA$Jk1$N&lbJvr+H15pL(x!OV_<p<7v&k(li>)bIizT_e!VR-GGZ_
> zuXLhrTbHZ&BxWQpUXUv@_gP!N-
> XgtL9G2WI(gD~a#bRx*?ODBi<n?f^at7Po89l?2
> z;=BE_NYP4C^f|`Uvl>#9LUu-
> H=XywS5_p;Bhsb%<h%(!dTaLI5X($4V>u*wv)fI4q
> zgI!7QL8dc%kmD_Whx%sW*L@Fi3k-}sTyMe=DKtxW--GM}F@Zfu-
> 6eGMkQQJWZ1>AH
> za<|NxEb_|TBKu^w*zC!0=pIH?&f?IYVrLN?YInv4U}uchRNGs$!Gb+t9#wLJVu
> -m7
> zqjtKbMk|=q!?=ofJk9RS-
> r}SJDWxHGZ^>5J(>~o>{GPfKY}OgR#d6*CvZKWKw%iYc
> z^vN$3TLswAy?w%72)PTk=&bL!3l^usZ2OoKO1r*vVh8pZIS_4B3U~UY{tAP+K
> bju9
> zSp0SSVI<KjD|+z4#WbZuV;SrG13U%$x_|kh0!*WU<bTOKu9TXC6|&B^Taq9`
> 57shm
> zAhVvu&koQ1=*(>{^b@v#Lm6OxbrNnd^Dv9+qVI7Fn9np_G(S6Ew8gyZ0$=V
> H(3Sz_
> zXR(rLJmz7;Ll@0GS7JJ8K9fwzcyxNX#k}hRGoqnsNCujpo!`k96f>{CEqR+HkskAz
> zW{Sq6v(7DMUcQB<l}zKoBm;~`=c{fp@4CRZxCOLjp!wOUu*J+nR1@983*7?d
> GtCr@
> zM{(}b&8Zw{p{ZI39$#RR2If~Wor$yF!6p~@Z7{Gd;13ySes(ygNHHad1F!L*ySO
> gk
> zOs46g`B_wDT}(N4nlyBsE#Pt{^=DaU@vFTItQmVni+f|6CiO*~^*ttNIDSiAD%B
> Uj
> zQmetv*L9!71P#V-si7<aCp^j8CxNx?H$0|#;hWfpp#QJwrvD!)eqrrE^?U48W-
> I*&
> z<{YR?qD_ebh16>3FVb9qC)lbHBT}EZ4#QOwD+7O`09O$p_%xk8u^7+`bnMyv
> a1O_C
> z9`siP=dEal#!m|YwB|}o@enk#LlgLrtFF-
> #y`D=`kFrRbH@>9vLrKZ#mROjXXu<t~
> z_#BP+Q5Oi17of++ZuB^ke=XNMY<_G8SS#ckg`bj-ra-y;%M@CVwfzfwKP^;-
> =tr;5
> z2+?%R1GKU^8rmc+hl(deX_i@}Io5DDF2Qc;h5M(sV7sw|SH`sTs%XYko_YhVs
> g@uH
> z?%GQmR06R_&<(Y?Z=uqZDPF&Ux)^&0$3*DGzEgh#a&nWXw!~ZuwfIp036(
> >I<Dph9
> z1ijH`5YxE0Iv2)Dm`GrOII%>G8I`I{Oc6zLi8epM3tH~j<|EBR(9HM6tMX`!*@yj<
> z>jfh;qDu9dWmzb@hqg$t1jOf(s(M<;>HgW<t$&WfuZ%y^1HZ2RIDWkbZ9fXX
> PW`+T
> zn}WlymtPTZLijaA@nKo^M>&Kw>R;-
> 6mSsDurHG@j>`x^o0SI!WHLafC3b7929fXCx
> zQS;zjRh8kv%wa36oNs{C2NQZ7Bs4wK-
> RSwT{C=_JcQ2RUf$=7bl^(eK{ue$Am)|xe
> ztMj^W`SqGS#)mVT%ctsZ-MM@mF{dmEl^=!6$DLxhyx;A_`;&6{Xl;ZLE-
> !JdBiUTO
> z7vVp^kVoP2Ed2%YsOa-
> u?K4N=_ldfAyR;UAsTRrL$ZU~3k}N(QTVfQqj4gb7rRGQu
> z(i`=2>Q$7K-2lcfkp^_<O3hCby5PHfI~`V!Xi|dX1_k2RfL?8Hb%uoJq1y!`Kt_;q
> z%f(qtU=HBEP=pyqeHocB!4=D{S!OprDUM!hGy2**R)hH=es!)0a&>7|Z&j|VK
> ~QUq
> z`y<$p&^~S7gzeo=R|Bj;@@aRcF&r~EMY?Anps^f!3)0*@olJhQ*Is~pEQ8kZd_
> 41_
> z7w&l@g|CT%IHT<2MhEVp(E!}p#5wY1cL}cPJ^M4!dj&89bzhJmI+osdBjtlhN2
> WK-
> z5!mZ1fwhC-
> 6EcBm43%f1O!K%Ok1oM^UvoEtzpCpw8o@2SV7AOz1wzu*^dj}o1ZT7S
> z$1eg0BnI#|K41cV#oPez1BqZXcpAS3{g0R9Z>q4dH~;d##@_tG|8#Nj0b>bS(-
> 9v$
> znh(LE$EWjeMPYovOg!x9U5Q_$%e^Co?%teh|CkQP%Vb4bb>2xQhc@*A{zf
> MeE$BtN
> zQO{$1#$kx)!HXl8B?jxasX5VfIquHXn8R;M9vEI${S$19ey$9yDZ_?haBrmwvq&
> 5p
> zV>JsOz%X8-+YML$=%I@v*P0rp=R^;Vh*Tg3Lrqh)`t^y-
> #I66dx&)c{xAdz>!)=<U
> zOOD4$H71Woa<XD)m7+$@s+kyIMS~fxK+W|er=d*nbMt*Hs#l~h#_mvjPhH
> H^S0ptj
> zJXlrU=Hu@4DUY!dv>qPSgLLEJX3?h3K{2U(`eE?xalAz*Nf$-
> VWy1T5kkF9xIQyzL
> zC&a;?7{He*^*jm&G3c3Fvnf89nM~F|-
> 9scd!7392_yK<EZR&x==stmilN6j8;FN{4
> zeV`o<kYSp~6S}4(G8QMa#DN(wYKN}`XX(WKSs^{6gtbaqYwEpJG4D+ZwrWpk
> B{}&n
> zdvmR+?;|@h^19N;h>46@!_T#qq1j9VTfc{PZj=|A<ncY)8d4)6)?lTW{umi?War
> zR
> zox+mnS4JKF;1agqpBT)q%U|)8V4%q}i3z!+{&@%4)$eS8%yXW_k7hE>EP+@
> UDbgvV
> zFFVKkIdX;RFY?mGkx9akH_ODHm)(=h$wm+6L+Tv{Q)cD&n#w1l7KC#_`~W<
> Fr5M`f
> zta~XF+WEK}d;$wMA5T~)j8d3nNCK2_fhpkwFjc0?KwT4utkfpGQ68w<f|O*%
> -YT^n
> z>oTchuj(tM1!6zMx4?$M9J}b|JIpBNXi8Qzfi08@fGzN%)M?S|g2R(#EZnIJ1;}32
> z3n0WV8QfSITFYUHtG@W*KJ;H=r+N{8q^v*O54Ju-
> gRZln>jm^m4Z6mH{tTczA{&-~
> zOjW=e#$xmKIw(cd%I*=`<n#G$X<7J0OQ*o?s2bh;Dq8B${VPK(T(09GR3z;7Fi
> 0^#
> zz--^Er$WMO7ZQ`mc-
> C_P>c+qwm8@8+O2LU}*Ba;pLr7x3t^6Apgs41K0||i>P3X5O
> zHCcl&d2%WMk1}-TNtkPya8|0+MG34uNPq1J>#u>-0G?g-
> tCUW#6CB2aZ4|lja$5w2
> z=ZMH)DWppMw|FAZK%JVH8lhoa&J<HR{2A10;X|xO{5+9lvi1krIF^F?n30UXIg
> gd#
> za@%n)VfJz>cgDgEV<Cvt(Rb<iE;V3gfVANxqDDhx$|$%CbVH$HX>ksNk>T&5{
> &*`A
> zMa&zyeFLNA?5tFSbpt@?cJ-ZQ9-
> yqQiXJKtkJ9<MMwEgqL2|WoMXnTa6&TBzg-UCW
> z3vB|g>O58IdQ71Zoaoyk_)N(c;gaaK<IE_YP&**>401@lmFldl4E$iK-
> #S27&+Usg
> zkWe@`P`49LWDr#tU`=`Iwt2!__tX|Jz$lsP5EvT%!BuJyoZUIobPnbuizm2h%FQ
> FV
> z%C8ACM7s(s#ZbC1v`$7_yYk^R^aNip22qr_&m<Yf@G7t{+J#}*iXkE-
> _)kn|p1j+a
> z*t`|%5W*dD2D>%MiuG0MBscGRoA(~(Ey7_Q3N{Xce}dPg)Q?aMJp1x7iiVgTz
> Z`-A
> z1PvgVuVsR7Q&!Nu2mJhHb~$wLiWZ!9`y9_gWNpcV-
> <G#>w~ABeuW#YsHuXII8V4xL
> zfAM57L~vKWi!m`CE24DX%-
> <UVUpw^}RG8#TV8cU&4MAV$i2C%egGS&hE%5bNTly8j
> z&AA*|=#qFb>V-
> FBKCZW`TP{7hu3CLTJdWTxc~LUB7U$W~p;{4XQCC8QGvALf#N{06
> z<Ve5T5~jQaQr1F<wy0m>$$ADC?8wcr4MLnW$om$N_m`myI99gx>2Y4d@`
> MV_nrd}D
> zw*Rd{vw(AYu-VmMj$I)AaHbt!Rh`j8=R{8Clvs-hB&%_r`(}$e^d00Tdiy{E^j<zu
> zVHYf-
> *fq20dXR%?l>#m2554hXhHh17BCme+MCcgIax28S^DBHtm!TuGp~4pG5<=B`
> z3K<lyFGMG04e&&gN%3R>exsZDiw-
> Skrh2{vHr&5XIy4r>A2SlIAkba<4D>|ed=E33
> z8DMH>B0pAgq3A+s^-D0f^C8Sp-9M9G%QU|_=c52;Pmf@n^$G#TzoYNM-
> <rMBjmy9q
> zteb^9-@y;mwsjLYT$?J@a1arEgQ-
> _dKu>WBW_2@7p2n^<<q=;(JZ+fc$sQrt0SatL
> zA)l;SQLTO=EJ8)OO<gHUt=7lU$wQcSvUGU(SUvqLHk!tC6t1t;^kb$@tAFTO$Q
> g@t
> z=eND^^D=(2C?*I>|D$^QB^Q*gLzknFHdX2U5Rc`f2d(t9!n>Y{@p?Z$#rTWuh`
> 4^(
> z%-
> 6iY*UG?Ci6meCKla`Qu&V0HA3lKqmlzBxRja611Pp?JfCxU2KrTW{API^1YzRpp
> z!H~q{ULF<{dXq{Fw=z>{v9%pLwXOe-
> |7vF($Es1Vj0VSAbZkpIOvT4ccf7PxO>1gn
> z`F_8(&c5f|M+iPTo$vb^IQyQn&)#dVz4lsbuf6u;932}A><LLlyGqU5vq{iE0&C2I
> z$8=vPMQ{r+=rUhG>vVLP^I4lN6Lc$eJ?q2MQhBU2^(SjF7%$gM(xF>PY-
> baSD>X}o
> zvy5!yEd(T_+ik92C+XU*L4x8~Yz2Nw%=kpQ(Kg+5O}BF)0ma&incVy-
> VBz(E2L#>;
> zOgAAGn?*oq!=2cxh?2_$VgMySXH&ikEwcs-MmV0?ZT<<-
> WVSD$Q;*LEx#^!25uVLT
> z;|;Cc_&F+HNosGKS}xtokf8gwB(Gnt*{(v7zk%lJe#!S563bz1io`OiJ;qO9L^~Ne
> z;S=;`YWTc(u`&iXB#JPqkPdSZAn-L#?aOYLW{v_Ok&#EuD9CZF=uwe?{3@-
> `H<?^)
> zs%Ko|;%^YsJ%uP*W3Ro9zM3>PV`TeISy<J^Flq|g^`?`L!}D(6N6i)E1G<f|U^8?
> Z
> zqw(YF>xD-
> <M#XAD8j<u<YZN1%BAAu{y{h?Lb>f8#dS}LVP6cgB&1gM75Cne6j0DTM
> zxshltKBngyBX&q}daNxUxr)v2e+QIhQ2LPh1)8^ZznBCMnGtwkFHS{~wNj9Z-
> )1e(
> zd)H`0gN?Y;jkwW9-0DUwmXon_C<p(Bwu$3-
> t6sAQM26NlmtX6wr5=y91qB;ZA<ZOA
> zav1E3#Dc(<N-
> 2*W{Ej;w4LSb@*N=V>a^Asp7}v><g`8dJiJhSz>@O>8ko)K68=O73
> zpFbuTay`n~gzKxgp2oGeGvrKqJmkEO`z848!u2Cu-
> $MNACqvHd#3}cK{blLjph1Hr
> zUv}=0Aw!4w{)PpH4;hk^gJ^kw!m=kq&ew3QW|{7_2W7v8i+@?*BnO@qvA?
> nBNIf0j
> zW0P8YIZ5td3S+-OKd&mRdjGoHciaQmDKf$C0?TU-
> L%~Cf;t69I^Gkh7z@?ez<50RU
> zk_Wv%v2S6{oSjkD&r}rRqm$6LEK>wlg0AvxLa_(;0$p<8gEu<PGog3ozNL=bhz}
> P-
> zM|g$iwf+dt3F(JJDX;Z$#N<6PLdL!O!slQJTp~kY*juh)^Rv%Lsoi7H5wM(}0Y`9p
> zh*;^^mV5THP`X-ry=DkR6}ws9#lY<xrdo4-to$I(Q@X)R@)|^u$XetuT+3_Yz$b-
> f
> z_I-Pdn!ZEyee}(-?RwM6$Z>hM-
> _49|e8_ub+rfXOI*N7S$5xf&zlunuZK;w$^n#V9
> z(KuHAJRHMp-
> Ip=`>!B9mDB)BLoJD*uWM5&qh&+`%Hjd9_Wn<+Jl&(2H7J3+2_Li7y
> z^}8j-
> YgWX{pC~oATrV^L)F9P*7uF}b!1tqzl0%CWEw>L+i1*;M|5)fg*wb?E96P$L
> zHs3Dhdm22D7=au%;T5W9w6iF`3-
> g^?u2f?cJ3}3SJ`RP1w#0A*tGhHRfDu<blEVMg
> zYO%IWRA_5%j1{%wiwv>y?O1PighV1fCG2Fn%$xX;Lb6Z@8aOL{0r@Bv<34O
> y3UZ2q
> zX)PrcXem5q)4vEyD?Uln-oUgdK{pSZFC_}uZc~2~sk`xITJ2upQj1-VJX<;$qD$4A
> zx#8vU<shIL2eT2pn7d{WpH`z4<CkfT3X$IRy2KVsse@v%GTfNIL7xQto}<q1GN
> ;&r
> zFCdz^@f>ay>ov4r<nzo$0rL<j><Z_OA$vp46}XCj7;^5w?@w?!S=s&l4a&Cf277
> Zk
> z34d|G$^f*+Noo@GXdfRh!>9agUmoqfGBQ1-*{HU#-
> 0@;?2M0oHE(C(;AFoj!bUhpJ
> zE5aFblBP*gFVwGF4{yO69AVgpAD_6EL{3HAVf3v1NG!1BVPc@n0@orD3u;NS
> 2AZ0;
> z{T~6>Csnia?z|T<@->00+^RcKGv)5~&|U52yHaY{fq@<lLjcQRKivxO9-
> O2QL1>#M
> ztz~;?M|?&ym~HLl+ta{o2bgUD^RjstS{AuFigvW)yJS2Y6?J&&T4~+xJE3X1??8~)
> zMb-
> mkeRP3Jy#o=6W`T5#QZih*Qb8<6?)Y+FjSDtiVw*VnhvM5VfU^NhE5Dy@eq8
> ~T
> z*VXZM0vHUjy9alj@-
> {Y2w?}&7?y%&)D;4lN77^>L>!u?%QIM2jU(q?_X8(?x{b6L+
> z@qG9iq5gR8d{oazmpN%gg1B(-pR!z7s2!X0vDFc-
> 3|Q1KKuug|*V<9uicO5zQHvJ=
> z^Ch$d_$q#Nyv&8`Zf1%VJz(0=yA;zU7Av~1#5{hr3wI0PCQ84@R3TM+XiG=Y7
> Tv%s
> zZ8AsU`p%^jd%!O*Jn!*8P_OQvBJjxAJ9U#glOmqA*|%MgXn^i1Tvwgkabtm
> N_fA6L
> zDu6Uen2SjPD}-q6p_qoeDSk<U?9ulMHjPbyNBiPadwuvil#Pm&<vfMe!*N-
> _GcBo+
> z;$KNXNs4FVN%Fxu%am9~F7ir-
> w7}^Fbq!^FCz4)J+v?v}TcZ10;6^QloAIS{>yU}9
> z_MKGO-
> =Lq8Qzs*4@TRCQ7Mn!%`1eiFd~(>3`7&=Y#=4WgJNZ^;#&mr7O#;B{b^#EJ
> zH8FQ~IkP-$`pVErwDIgZf8$(<)tZ6`r%vQ1wv%bt3AT;JO|g0BuyoGFF1)*-p5tfX
> zwfMcTKj=;Amh9^YUb`vJSRq}(F!k?e<vk*hapK_3u{L^Bip?&NkD~{8uwuE0!G
> 5%5
> z!ju-;?QrzC&<;YR^Pb!veQ!==1jf-?xp!;O7te7Y-oyhxGK%geFQrl)LSQ?K_=FG&
> z+RG)Bj;Sd=%RwwxEen5#6aMA{;6*eaNZDh)4<w%%Lfegd1x+)Wmj)o$^jT)0
> qmJLe
> zPH?LjfbRi<h$WVKijGI;hV9!uW(rVG@L%-
> Jso1E$VJfB^hP%>YRS9KZ*~8p`aVP}2
> z$5f%m?fxoROC$sHXjIT6fTKl*=P8_<B4@S1%gHO)9}e@idn~ehsmEgO)0Hyi;|
> VF`
> z6!YqORz`+?Z<yN%<dtM$$ZLCu^kV;TZ!dWy+w?9Kj<{(Je9m1!{-
> F7MB}t0e&9BKh
> zu1P-
> Uz0u8k9ZZ+t!#PCstFVRRlU+CS1I%4go6Aa+KU`{lQzCrR(Pdh}CwTdWiTl&v
> z<4=EIsd+MyzRae7oay0-
> y34$XmpFrDd$GA>0>K6Z9?Mrc;4oO6%y%pN%oJ4f8q7m6
> z?C3Prs3|aGV_2ZY_W2>Ko9>rkKPk(QgJe(|hhauuD>?xG^9!HL=zr$Ms00fdX(
> 1S3
> zMXB!QyeC6&HjDc}yauItx8H*iM2Gbn?0!kS2KV3xB^H~J?@D{%zI!Xv`R#1gpO
> )cj
> z^Fd)sMkmw<)AK0D`1Dwe)?A7C6?PJl2k7Ccy@n%kG40HqOx<M`qIH>RGz($
> D|Dx#`
> z7eE|IVWPhm7%?8)x!%18+3taj$1kPaE<$(MY?tToXV+B6LR*EfpAxx?xLxbw>$
> I$g
> zAa!>XZQWM1CGW}dEz$QbjO5-C`rNkA)@MSWn;g%6CbV@jj_?wn)S8-
> D+YBlq@ydx=
> zYkmT`0p`D<%I-3^uTY@Z11L-
> YF|l5E&6BGT7n4)pFrTk(5OZ3QF!(Yscw4PNR=xdq
> z=u=$}p82O+Q)gG&s*yC>$<PU(=APq2qAw&epw&UJ0oyp*TNt@mBmi$=;cq
> ~WQWb(W
> zb_O_4bBUFMO{@X(-iy5P>1mm0O<E2A{Y0j#+)OtiQ}-
> $auxev6L@=A)U^4|`J4drn
> z^P?VZwKl#L)8ouyEs$QXHJ^1&`<amVJBp5Oi}k>NwWX8c!cEil=2N#0is#3~*N
> *R_
> z9TIp@{4yl?LM4E}=_wDihm^&SAb&@UVYGWeyWVv2F?;=nj-9-
> Lb8OVVhfp>4C&gyG
> zqG`ci;s^T}DjSPsBVCF4ll6XSiFy8Xf6H_`>8L9;KTS^eD`2)}GstWUcmzXpJj$G^
> z_N&RW0N;i&$M+-
> DUHD~v#Cinifaky%^fz=It%RVy`$EV$;m0AT6<26~$Z5jwjW33r
> z@wjfodnfS0{;~!QPRo!zMEq77pFM2HP{92q;7`V{y|<$zv3K~<4C=H87vs>lH$N
> fk
> z1hAacyan?RCtz&FzN(|xBQ{EF_XAj%WWnztVSFB5{)sQKGb^`PM5)9K0~`+gk
> *J-C
> z&O)O11p+o6h~fFKkSM-
> hgV(T+$2nWT3$0U6z*EtYt*`PCJK^xr<=33kdC0=n_nZJy
> z+_k&CEgLO{V+tf0+KGqh(aMQ2KHAApcK<VLHqhVcFg;E~Mj<2d+{R}(j3wQiw
> 9?LW
> zOG8pAtq&SLp7U%Qe;xcqJLN8~tu^O3aP4L847f5r+Q~2(*B++#;mYS|CqpN^s
> b5@A
> za&ZNX1y}wmu5y>xc3^l0Ty0HHc5@$gbMseo%UxdER}#7BqE(8_z6GKUr<mY
> Xax*?w
> zj;?q9S!{C{eZg4ho?`RzB4Gj1=(8YpShP@dSBW{xO+{{dwE|d46K?@rEKo-
> av9b4E
> zp>4gVJ!Xg#)|as{SD>wbapp^0X0Vg-
> (N2aA4!&kaHgy{hWr^c}C2|nkIwq&IbTR~Y
> zU6|Exc_=pTE|hnO0MOd}RT{`$Uh8l16f18nHGKtIP3y|}Y^-
> QI`u$w<MfM+EW)k`<
> zsq{DDs*{=d3+71<gPoAHCoZa;bp>^FJrx-
> z)u9hvpU%Atg=T>AB>)pBHv&rS3}yhq
> zcA&46FR1^EQqf!qeF3w$)I6d$i%gLgGM8O&Y$w%hDH=qzc?^eM;K6kXO-
> ~f|b4WSL
> zY_?^#qg}f19Y&RKz}$mm9Aw@lzx&O0`Q2?=<+sah!mkxzNUV^ajrbBi%Nih6p
> KjlI
> zkW}S4WaFd}^-zlTHbzG~8Bz!&CtERgfXT7{o{i2{+{uV&CquO27`7rok!kuVkY-ti
> z0vR3cWaxyi*8)*XAUYKK>r=6vi%Bl?-
> j!|(qxQG5gKsNjQ<>Ki@ei0)((%((hV$wZ
> z@%zmZ#K&(MfT{Nry9`Xt_-
> H3Xhx@cqMPPS@GX%(;9*fP8!fx~x_9{9h9W9ocP$GV}
> z*@yUnDD*sWNN*BGM>`pU(mw#tE0vVg8MSd20cFr|jE{CQboePEwk4scl%r
> mha`ZYP
> zb$bZ|QpaDkE_5vKoXBP7Pmmoj_!+UCW2J3gxWcwgmw64M5yy-
> b4VPl`u<y+_$cZ^m
> zvo1AX(HjoPAQH46;D;S0nHtX!aA5uj`ZN)^?F!YkAC_nWc{2@AQJ!lt%<#QA9d
> D=t
> z91JiZ;RTe{o?^M5U>=v^BSGmNgE6s~O3XhOvSd!W^q7s1KRI(#*5I4~1fC5&3
> ^G9O
> z9yOyO*)q1or)gtthtX@{yr?soIZ#|Xm5L$u1|mz$4}B2N2ShVZ>y1Spa6uIXOes
> _Y
> zyWDq2ptzN599iMHCSZPnbU>xO?T~bg44v>P9WmaRuK{X%+itgk_)Ek(BnBtq
> brd}e
> znjSz(eD6Rg!a>!eW&tTOfRH{xpy@2g=x8UyWUcThll!#-
> Bch!Q!K=~Z&<YO|LVAIW
> zj&?ExoDSAbRFS6{ZlQ+0pLOKIidgI++=|wIRO2vcjqSE^T^e_wxHc$_v!5@_`1w
> L(
> zFj~D1M26@{>NEQEuKpC`M>t|NxKX~ik}5dVtiJB?A=W5^CSiQElc5uym#j&q)
> BN5=
> zq_|?ac9ir*_u{$OY*j`8lFwocD~SBE9K153HsE$Zd3e<BE4D*Gz-PtruB81(yu`wS
> zog45561GiXt{u&a!z##+#kMeud0aYBP6}1poEwmHfSNwgPfZyg?PQ3?6R+_AT
> z5YK
> zr85Deqn!+$Fg})&VuDg%(F7gjno9Q(2ox57RblbY!Kx<sJSfuNM)R7jbFA`eB1z0
> |
> z&r(`2K^qcKdErzAQ2uAWH~)sVH{XUfgWfwky7^%zd^$3~#CX^o!LTA${-
> ~&lH*nwm
> z)ohBHYLV&WD2sRmr_@vBZbJ9=9=6Fjk+WpE9H%MXn@u#h0JHlrEW7TDFk(
> +oKQc+!
> z1^KRUnj{;`=7D$fy=?!?Z1N=^m)H?}ik&25aerVRA6YC$i>wf7yGH8x`YgBhv10N
> 8
> zhLSs1kSwIeawtnM#1Z|un?Jygi($II2%1|>f?D~CL1Czsc(~z$m~mO6R;Mx_hx
> Q3_
> z^f#2am+hFL^J09olVP%Xeh<_8%yT|RI~nq1B};r;8nm=<%}AGPb}=`&hQHLJ(N
> 4Jw
> zpIrNfIPEb0LI)z>I7@>?!S@e>?jo!Vm@_`w$uJr79Zc`ToX^othR4F(4lK4aH!$a~
> zVlH>U{2>?f-
> =WRAe}#7gV!n;AGGNa5XeYyD%v+h>hdH04oeZ7uqO{U1&F!FO3v&Z=
> z{wn5j7tX8Q;$nUoFpp170E&$BOU?%H7-
> sP~I}<P`U8#Ke2+YMqdfV8k4YY{`XQ(FQ
> zqn!+stGR*cebwZ1w38te+m|yD)>hRvQkW1>RsL#K<t~!0&TLLgq$W2fe>JDv
> h0mkn
> zQ6ppLLdvT7%;l6aRX8irTg69{II-AVinIxeh|>b-F@@~XQp`Tm$k%(-v)By17vrOy
> z3{iFL^>xg0=pH%^xuwi1gZ^y)T0%`%@QjXjGECV1TVwzsIHoH2Y61Z*`Kt<^clb
> t{
> zP-FvHXXh-
> T$l}X9iWH+mOQ47Ebx|d%837o1tt|)#Ajt}rn}H;Zk9IOl8t>k~<o@w4
> zBch!QQ69bj1C)0S0c0qT@zG9(GzI-bk-XLiGBIN+`<E$TA;AitlZNrpPKF8gCxzbQ
> z5G-7tAYMP?x?)02Z(Bx3I~h9RX@0VUcetFar?j@7P1ZIQO;&8~mYz(R_-
> l}U^XN=v
> zFPYg%)#9l&TTC1>2sY!RoeZ6Dy+?K|tvWJpH%NvrWn!@qoeT>J;S5cZ3Z3two
> eZ7u
> zcwx2`!fg4%Y_H7nnC*4AV7sql6AxhV6tcK<qA@z!$<PTmrK&SQ82!x_ATDmO
> xdd{C
> zCL_)q-
> b=rR;XU6)I~fvZ=!4oa;v5T#Qkdw&c?xm<Heh=6$>{dEoTX)8OU6e#89L#W
> ziF#wJFeHsACwzgkd;oxM!f(X*XeUF;GErS9sGcsUZn?xGZ!4VV17JDBSI7!qA&if
> 9
> zGE5TIsZ8z{Rz^fS8R9F9=8H4Pgf6>YF6=r|*!4|tr`5T?q1#kA6zBV*24wB2k~Sb|
> zpY)}D8fnQv?7FT-
> BfzBcmc3c`ude^wkTxS<5y4pqec0+Y7vsP3KAEDjlSjUJrGmWe
> zXF(@>bBx#J-I+W;igm9z+bVf3S|M){$XFN<J(Pv%z@omb`<x)+@L{=Jrg-
> h>E0_nz
> z$v>NWPtS{eUpT!_-9BK%J{-
> ICtD{Ge2VN%RK@J}7h2zcp#vT1TWW?rC9&&~qfxXe!
> zPRE%TVI1uIMj$*F;mGjKa!d#lJHUhPCjh(>PJ!sYx!C>?KUpzg3C~Fh<%h8Mfu}
> (?
> zOH#?jPv&fWjk&fy2Ph!a!8p8;Kmhqhi0>+NP|h6gi(e*bB^$of(l?H|aJ)6DYO5k
> 2
> z^};d0eepar2bcma*4I58>QQJkRKI;QH1Bq`242Pjy*GY~nLi;FW@3RT^d0hdw*
> ePH
> z1F<8(DD>gSTT<~ps(H|SSZD(LEG_yYF3$&I-Tuxa?(-ex&+94`mT*!M;>FPD-
> 3w_d
> zdDD<%^V&ifZ6sDLrg2nzIX|p`dCosdPmizZY|DRJ)*?Fi(W+KURd;ArUz2peYBj6
> 6
> zORCx}OEiV7OuNtd8$=iN$>vNyh`&`3e`i5N2?C=E)TR3lM!JZXWJTXAPFbj!%F%
> Z9
> zN_%K;N6}u+Vj<kT_k_ILzstrb-;1pz+odLLn^==%fiUaP-rZ-z)0Z-
> x?+Mn_O@(&y
> z9*2|6zHO$(?j%WruhG1y3q8yQfQ2fsrq5x?965rFv>VL9&11q@@zatd+Wa2p-
> *<l<
> zDZ07B9f>%l)7?gyOU9Jz5j{MxcLEEoK<RyCY?VUS(T9G|$^iw`mB!sxu*gJ$S9@
> r8
> z-
> Xlftx*wo|&?{GhZzu^WO~S??jzBqr&l+&`0BaZ2R5&6VWxe9^B@zt9=Lab6PYj
> ~C
> zKam}7?!H@^0pdzbIcK0E810(d9(oj5St+y%<x%;}2gL>{B@a#yb9KbleSm@LK5
> T2F
> zY6AUXd-=m1p@)Gd<cX;zqaZ740$&P>E3(LeF9CHFJw$cqm-
> kOXK9V9hp`OAO-M<BQ
> z`dA}x``5^>mItG~v-0lb!B+_u!Qzpm_SV|o1{|n354V>;&=GooJ7ExRejt!{`<2XH
> z^Z-=ME-QCZm6L_i(jG|B9=bn{?;_iJ!la?rR${Qx-3GqTl9!F{YU=wsLiZtiN74OB
> zT$9``_u7mE=_>kr@wFZR?*2dI&E%#L*4alVO?%NjeubNv7kAm#^YP-Yj-p-
> 2+);jy
> zBHv%j-(~aqTK+C9qD0Gg=Ml36QM8Zn>)IX1p=-
> CN>)P!d<=flKci_`cDoh!eYnz|B
> zwsjP318uv>s@gE9CuC-
> >G)%l+T2fTr3btfl{5s_drb=|g3p6K^At&5Ol*wsc&L+(n
> z)SOJU&)I-
> DcHv$h7GD^j?_<u{k<(L@3X*bmIDS?l6?|V@OT|u5bQaYSilzM$TjXqt
> zhn!n+o#Fll+~4268FC7L9dbT>IOJ5}_aNfm!8H@l0bJ+cDn|S>zkySI_`rWzz9hO
> K
> z#1}Cbv+Tos&%*;dz76<K;mSuDSK@L8JA<<zzFAp=2bH~rJt??8e<b950^Rmyx
> F+CQ
> zimM7&1Xp6cGCs9r-
> noEgpPmbG+C`qcLsQl#=!8=rQ)nsT%)<qzhEGH|Eqofni^KWx
> zi`}JRy=KvspehV?oSq6JH&MvjjCS{s{}gs4?8SIKR<g;8@0tR5elHg{aIXm<CDv|>
> zW!ZP3q)b?rvc7IES9Y(Q1b;Br+@qM&o`zxNo{KSYzGOD1z$AseyCk8cu=k_DQ)
> +X=
> zGh}@^P7iQ*{~wZV#OBj45Ed7{-
> wbC2ejdXQTn@eF#d#i;xV<TD^T<jI9yH9=<>#E=
> zh<}Q?=fn61+qo;;+ZaDhG1zS}=qe#G_M1m9mV$qap+CyM)Rtd@^6gUg|3c+
> 68r(vk
> zkscy>t=x%|Xi)AG1D_{%x|sjT&AYt|ZAH&Y&O{7ZL+9&|^<G3mMx(F&32O_n
> vJmNF
> zjKb%W9@+NB?{pgne%54}zt6XA-
> DAe1IpeEwwp+{>c@iV>A#k(77uh!#kyor4Y^r>b
> zzhY!Q4z5|^i+qWZr>q%jX8R&L5osr&UIgM~s-
> WevCJcEPkvNN>LL<mbrvd3nxC(Gx
> zjq4^{TX205moqeL=%As4hh}s0RbnKgH=wU2E_q;#QZ{im0lnoM5PeJAC;ka6l9
> umf
> zz{3qk8iXNnGC=}f^suaLA(J#Pn>5ZHCv7W#W6NfI0sbU}SB7s!cun}6?mYm)Eg0
> @f
> znD>PivJ&Poyh*`^ApcFqec{tYJc-
> %`DpB2>&4`~tShaH@cz9J}ewhFlZ%BcK>A|8S
> z=GRD2j9cX5+5$7;RMu&f$jA37w%E)7lEYt~sBC;J&=6Uk3YEk5I3<zl#6&79;KIK+
> zsG`?=4n<i~<KWup=7aO{ZvSU8bNNA7yVZXn^R*S@hZF`qIE(OW@GS<jD5d*
> rNLstl
> zRVh0$SHdaO&gr5RWLJByc?+Hzo!>ZOzBmE*$#TI8=b|FT34G5ECcw+tu980Q
> Nm}q@
> z!<V_(F2tu=uv`f%k$@CwagB!*PX@4?0$zmHC89kbf-
> O0*zMI?9a43p?WO;tx?f;jF
> ziVk2e=Mz%#o%iEM3QP=gET1hJVfjp~(xgOOVa21TK&p9g(<-
> Urk>oUJX=4ThX|yzx
> z%ZV}Pjbd^f+0Gix%(g|uXZxt%I6eV#jIQPS^;D@Nw;+gMl$bxF!%`_=lkd3e-
> H<b)
> zH{`sC-
> |yj?g=#td?ZWZJ+wC~MDDQUA;2kFeP7HAW5!X*~O*l@t9*_)oSPUop85DYP
> zN$ue+n-
> 5<TE<|`8&LdutA~UApJW=|vHO%GF1!8NMS_+#UuwuSWrb}S~cR_tZUT<;J
> z><0&s5zWtWgC2@9G8rtyHRRtyR01be8z(|x%nh$VcwP9^_&Q-
> >NdE(9B9{0$o5Qk?
> zd3ub+_0S5SNW17znJ5PKjM!L?@;-
> x}N%UKdf{D*b;v6gJSGjM4$^>SzG64qg7L9S5
> z!b-iTWQD$CVVglvq&xcTSpA(3PGVIlEmEkQ@iaHD^>suj-
> Q^IW>+)J(L`=r@@<-XR
> zx-
> yHSqVih5<OjwRVUBE=BJ1ZTq_iYDJnX*XX=3J#xzq^gD9=TY9xqpT*oVY*=`Wz
> Y
> zp)Ii4a)x~IO*gts#1T@xvhZ5~bj!RgcJ%S1N(ytPs7{_((PN&2Z4?(Xp~ozN5fdNM
> z%|)bkmM9K-
> paCuAR9{+x!0=e@r$yv^t61zd4K(5eBFUcMUIi8ZOnmB^2{M;TW9kgL
> z4PhA8hDCQm$#;P>s42S4iBO*?JU%IYf#!h0LJLZh9x^YmS-
> Z?tP@4ETG%X2LX=K57
> zgNJWk>m2A3#Th4Sh2Bj;7@N3`;*ZRCGtj_UE$?!RS!h?(%x_1ydDrN?+j*`OM
> pjUc
> z2eTG%qx(bnsU1BBUSj0C8$|3rbr5=kQEtrbjLBxqNH-
> ?Jn77$u1l*V^#vEdd<HnRQ
> z<^{&|3T1lDm58Z5;y#q3(%lc@HTTs<4-JOvLRL|0h1j3Jg*R_uk6cO>JIb+Zjsvf#
> z8H-(Q(ak$9&bxgm0AYU{s+2!Ss?>)nff(R~qusv;+twPl+{eI%-ET1FkQ;M9V_ss+
> z0XODLjM>eY{ccPvW4_0jE;pu`G50X$2{&d1V`wJSKJ3OUK}`I!D)Wi$ug{m5FA
> Wxz
> zBxb;Ok%nY1g)IYv7wdyy5`f#Lq4}tJsz7&azLI4H*nJxpb_*2OK7cZ$W4bn|?1r?L
> zu#N6>3xAP<fum6Aj|Tjw`8Y2HmnTXLPXxCEo3mY9o`GrT$K~7SDlR_*l_Bp(^
> W+=k
> zY`FH&_Ku?M(eC-
> }2sdvBbA1T}z}OfjN0YQf+Y0;ufs)!?M2y==zH^RXEY<%9qE#bi
> z)eb@Yff94O?|lc~hrq{gwU=+hhQ_D~wIkfTEwCOZC2vE6@6ra}!D48gNip1dH`
> fQI
> z5MXG~9EMGWVa}OiZUkj%><`ZNu-
> Oa|B(7|L?}M&vfY(r=?q?8iyUS?6WL|2o9Y_Fb
> z{3)`4PlM2YF&y+uH5Ds=8T-di6S&-fIaJy<GNN`1H*X-
> K932t&WV4(_T26d3@mnnT
> z;fpc&lq?);V{5kwQQk0vsf+pf415Eyc9R=<BEZO85<Ve{=!I_d&mdYr320!e4DFA
> r
> zPZd<CicUj%pZzB*U1<MNL1HZb-
> S<Pz6S!W$bqLqnxK8?0$jQca9<HrNL(Vk(?!Yhp
> zcr?S{!8sgz<1Yt)0R}la!vSj{(tH(Z|1YkmaJ`7@bzJSZHsksou56@fCM?a?Z>R-j
> zXXBU!DFz7x!-sbqJ>OY?Io$=$Rk*g};s{^=rJoQn2sky^bXjo4@}Jk0dir*j`ByBS
> zg8-atw#yB_lbiC<fY5#n4EdG%9FR~o6n0+XjDD4{-
> R{AHMbEe68}pmHuFbpsLC~wC
> z96t2V1+%H5+8q42y3KB1s9g!=Nv3#MnWFnqWU9SJH0oh<6x<oVskYdCJi^Bt
> Y8SeX
> zukx{|_Hy^}B|grno#a0LkdIT$;ZKT>NcvpVUL?PEEYt9e>Jvu`pMZxCo0HLZv46d
> Q
> zaro9t7^|rc%WA4#fD#V>J0Pd3qsPpjLXOsz8S6<BWvSrc1x_KZWw=)2x)ayUx
> VGSW
> z5|=~1`I!G;c7h?bVbOnz1oY^k1-SR0{_LK&f$zfhihb|zXJ2P?SsyMPJJ^m!lZW5+
> z7`A>P96RVZA0C2^bBmC;*Q}s4&Z*ttK9=xtO8mmwCO2X(BhF6rh8OYCb@2S
> oH7#zn
> z7;vUc3il0_4bJ1kIcm}Fi*TGVrp<;z1D3x5emV#&z)vsZ$ERp<y2l(@1Inp&)DOi`
> zKa#tCim?nx;f?eoT0WIP$I;ipm%QF~uPneFjO%3gYQpaqaAlGp(0l7)n%=e|7~8
> =S
> zofz9~0{^)K&cQTftaTZEZ{{XFdqV8g*|!E0w8udgc8f3VMd01tg+9y6`sPgdL6gJ|
> z{5m0WeIf;1S-
> K6Gu)D9Ii#wUNNT1E`i}ww?Ri|WRb{$==>o$1i^aR#LC_0W${q#AK
> zVQ?Y?qK?{Ka^qb*gGfvn`fuddUgHgO9ohuGQ)ukG)?tu9_80D<BM0z(Pc4bPh
> }i*=
> z^2ivzSk7pZ<Er+Tn16pv%}(qfDDNsYJ=)oH!2gBuk7O@F_BhUedjqxLQA&opIY
> 4`P
> zIRh^f6o#g|C_yZq0+N?RO*;TDb}bTqg9Dxr;O%-5zT*~-
> mYIxq=4Ycsd!7~xJydMI
> zo98KsCo!_&&XfB~%olyptLb8)*DO1{%)EDsWWHE8cJ4qYc5kVP$o6O5&9V#M
> H&4`d
> zF&!)<R+S5STZvidCT4UlK%4I<NE}LvA%mU~7Q+c)=4jmdE{9k!qX`D9%DJh#)cj
> Ht
> zNC8jN*MuJWyPyIrh{;%6+qMF!__74+X?JobVyU^w?P_tp06hZ4p$j;yNv!XF5
> 5z$$
> zw96(CEDl00S>MeY(}~>eZBuc}<xc#CC^;Q+$L}Lx%ZTjY{MKP&9v}{dNK~v__)1
> I+
> z);~2e@zL!Q|M3ZBU7W8n-
> o<AZIK)g>n&6|gWJM}>EXN13pXJM|^(EH%Uk>P{=9#w@
> zEE8OZ1Y9c14G_iV0pFW@VKwq&zTp!|65wiH0L`G{22<yp97IK^b65dJl%Nq2V
> Mk^O
> zeH}e~y2tf-tv?|FtR9Z`&fIjOk5y;i>QfpOk%l|)xne52aiAj`>wOf8#u|&0y3KF(
> z9y9zSO&bha#KZ7W<=BSyXZ(-
> 6G@wSWS&Miv$Z16db&N^{^bbHPe!04PSSCM_%rn@`
> zB=A4nKG+mHYWnWzdlz7}j=T^{{b)ej0#sNVzll<5%pYNW-
> hpqd^Zrh>5V5{0fd!mN
> zi2oHhiP%li_%Td#p5BXR&X{uMEFX!w8}kFCc2A@=zeejP(OAZlQ(3iA@L`geD_
> J@4
> z+P`J<{(>+(BKzlsXCa&)zB=9@-
> #Ek6U9Kq6@$dfpjD1^PoxNob7HH;f%SnRNeJb=C
> z5Pl{ri-
> %zLnxBGaQdDmD+aMvJJ>!hif)ht0bRXcGM2nlLdk$sWCNIf~6^?}E)noIx
> z4nTg1eBBhRrAJ|PEUdg|`tD+o<FI)T`WDoMQI2<Kp`XJ8&cB464cxG8o=>Zwu
> O<2{
> zL|f+LN#bd97N@QGj2`6LYc8^x3=2$kg<}2#Eo29CH6S*bAKx$um;)!vgD}4Ims}
> Z0
> zG@inX#9|DPna3NPFcgUs#K4)qv-
> p+pSoyoy{Xm|>L9$$ohObU=TrmRN1ir=~@@0{+
> zUqg_|ub%}JTdxE(e7CK)An%^1aXMf0wTaQEPo4N2%noczGc$n*X*U_a&xW
> `!8c>XX
> zOG<Y5%xLE!6g(unUT^R%*&iZZ_i0FNE<TZXgqNGedb5O3n_w0KxhZRgnQtYu
> |HIq^
> zhjXNu;FWVxPM67thDFT|nL8nUn8Fxl)+Lf3GVg)CyMKU^%zij-Q3zlkHlr-;;bxId
> zjN_#MyXXP5{9zMS*w5n!un(K*3VXOY!zM@M*8w}e!mLjKK4cz;`71~V%n{T
> @%v~Hm
> z1;E%=NhB{&z%2^+kog5+oU$fh_Sob|#Q7n52oC~p=*WZIKAOxiiB{pc&M9pS
> j{!b*
> zqiy`WnV=Y<jh~k`9<J=v{bkrw$JxfjAg^r#nlDLiF*SKk-tC`*(Q*gAY=FbQ%zus~
> z594GA9MeD!{m-
> C~Z?EZr!eQ<2fh7s@Ou#*M9&KW8LDIA$^<I;Q)M(H9ZKkIr(_yn(
> zGeKJSB2&GasV&SNg>CaQ4zjyUlg)QK^6@PCS4ZZx4#^?`Psc~o)mi#D3`%nN-
> M|`J
> zcO-
> 1RTVkQT_6RJjIKoQknbO8o^?S{w1ZD*a?BillMl9T&nP%PhrN09Xhk=S@8;oo`
> zw_-
> 0R9o@e5L1|$H`}#P%Pn?Pa$0CdfcFm<`f&vpLo1uSf8^JObx8+{*WoQz7_sJra
> z!WmenYAgE!?MPJi0rWEF#T;S(>v0Hw^tD`U>!cd!WS9%z`aD08zU1cPk)R}wy
> M57i
> z@29<LtNT9mhaftN)j1DBA3c;C?ak$m$4NrUxIIAtq<j!~OX-8SdJ{C?!I4gEtR#FI
> zLZsH_Uh@p9EeW&Sgxe(HXi0dtFX7jakcj8Cz2G1V`nk){zVu_?<v#zLJfr6>8fDIr
> zdu|ZQHQ$7qM{8nn51li6%`!lWpUwUq{3yo?mzW>tdMJGn%oU$2spZH}NtR8
> 7I?$gZ
> zk9)MiS2Yh<p@5^>F7pfg2#HDv;R53EWsny_a5nB`M=#G`!1u;|rHw;cV)bjJq}v
> Rb
> z;>`QKW-YKLPqAAl05`F5e~g-
> 1llwnu#~|);#C1P{fW(PxV1>tMq4m6fMDK+tIdYE=
> zpnHR^VQwAJ0Y!8IislIG$i0df5dv*6HFq<XnqQnCL_$rAp=j{a%^zgFG(Jm8AIB=
> +
> z2jdM@#uso$*+J4b+>A(?m_a^E@%L;zu|JaRJFd@>1F~;S2tc&=n#j@=DPT3H
> NTI&D
> z*)Kq@NuEO_*;%Zy&dt(Vo0mXGCV>^49FBEuWL%Qk18AM%Q-
> 6kR#rgsul6j!?O3Zpg
> z`M?=6x#pl!7hM((MSXx=%sGIcLKKzPd(AJ<5s)o%O_QdD(tz{x9;W5V@Za^N{
> T|ZV
> zG5I_+63LwGpj)h|@j_`R_QE|t&eI}!tz33)Uiv3laL1A9W)5PJ26XLnB6D!QA<O}
> ^
> zFkC!1xDqz}P|yY~`(wHRx=bxCByeDf`2yBY>11Q~-
> veehfpGjf9$2tObF=}hAG62A
> z$Q!b*ENZgg5QFx;n8ztT!J~}PKbh?h2}G6)1!0PYTjqKPvJ2{B{RHGG{y3o*!&n7R
> zeTMfhgK;1vXUebyK4ZqMP)n}ItPdi~CG<AMitZ`FAP5H@h@@j89PVS|n%Ox
> 28HJ#N
> z=i7{PkdezDcsQilBbp3ic-
> SmJY4{Z}e2jGkPkjS*7ymws{%6>4Ky4Z7=5}(RW@~Zn
> zqij{4I6z^`kKx!pvnEmc3N5`3r2~mUtguiy|GzDj<5yxW2SBoyVgu<Z1fW%neW9
> rU
> zwU9Gk0qg-
> gDS%)7mj&Pnmg~n9`5LLmL~{uOxOe!2ZWFAK6JMVjW}ATgnP9Bs{BjoL
> zRMdov7mALUalA#^V)JP^g9pP#Wk{5_2FLq(AD%Lo%7}0z642Ae_b9~o{*1Ku
> <CEUM
> zCkKN1^JhuH^S);*?f2lh@PXKv0p1Vl?>#w3+NB9CuH5gH0Qe;$YMj09+d@C+
> 1cU|X
> zVW+CTN;v3hp8zvZk@qSG#Yc<x$b9l7A+tS<CPyFLmIM6g;kmA+F>^p>nps0((
> xKC9
> zT?rvfC@xOGmLP%(gXR|Ww|tKU`ez-
> YVVQzg?xDi%G8aQosk_W#NEd$}MyZ5&q8}n$
> zJ$bFKpw_ir!pFU)6D+~xZEo@};iX^Gd>+p}H9a@H0SCi!lP!+GH*@c23&HuYLQ
> cG|
> z9AX)57?2Wd&Zb0oF2B^{W?AwHQZham?n{QLjlC{{qk&-
> ebr24weFfGjltj?O5Z_;r
> z^>HDH%$m(ia~UY%#~6nPCL7*yRG`<~rJ&BFUZ<wSM>Sr|7W@VAA<%P3CJ
> N&2p@8Vq
> z$HJY^57Gh|{mUao63rn1bmi$Myp@c96n6K^Q}i&HUwR%h8AT=9=3LZ7d<+
> M^t#l^d
> z&m&SRTFREUCM0aew2IoX=+DtEe*B|{Cwbnf8(<;QI~C&UH77g*^H3%q$YQ
> qx$1g9V
> zn#lYzN8ofAaeYPIFI>SS&Ig1o4?)A4V)F_N3T4Y7pbyyc>-d4J^_YJ~`&fD|O2J3I
> z`2?Soe$XY$lSQg1$cugx%E7|o3@PmU=%MTkZ@v7{LxBO_j~w9r3hp3Vk+*Y
> C#~vSw
> zw)}BhK&T8567M<ra?JN=h-
> 1D7!=hXdUNGf(Zpt$dIwm~qR>}O{<fAHLT7&7c+fK(J
> z_%!gK={mAwe8NXn6BMxcU=vXWXhMJ0_JI=p5+N)R*2DfGKls1Bs0SPx-
> 90RNsJ9(A
> zoAFh^)2XB3*XbA}-
> vI0;D~hemkKU~ZZw8<|p?`ZiN=9B*9>|N{g~zRU2STmm=M}$+
> zXZJ&Dwb_U?O;97k>+(H$@_Mh?jznO7^7;|ng4d70tf3vnIoTfhJ|T9(^>oPh3H
> bp;
> zVA|I{FPCfMdteH+m%ynA;pl5$7<i0jPsF!eLp|-
> qBjfy><GI{&Midj#@+f&0j>Olz
> zv(Yg;9Y{<|f*vKDuL$)$OLTybth%=3(*0s6fE{e0<PI79^qTS1@?B<1Qdc8+guaR
> N
> zGW<cU*RjXyGDm@KLNjO)nbV&Njezt&&X_(KU*KMn9ewQxsZ`9*M9Sk^$
> &arjKR)Gu
> z-1^#WXs6_uqfjg<F<2In5(95-N(|0pbYl`!^yrK4fJR@%F~xoDpUOrmd3-
> DR@s;Gq
> zr~HpwUllZMcDJ>py4ZyA5%JA?vWQ;~JQ0heF>nJBO{>^$@<GPz1hb&Y67>n
> 70()K^
> zz2^_3qp#wa7JfT3dg#ard&rsiII(<Sc#lC`7XH)2YFp-n{g!I{uJoQaheTh4doXLy
> zYeOtmUOC}8TXQL;dnlGF;QyXi@wsa)=&96#Ajw+LFfB-
> 1)hi48UIHD1_yuJxHDF5x
> zud*$$y%01^EqJ&sc(@ik?kLzGwdfpMbdD|hC|JWQS_?eE7RU`jS|HfPE6^pi$
> U`m;
> zRF+R|;`3#CY!CeLGC6>bQ<Vkw<^>><edc-
> ?VCXHWP<ljwaTarVPdncCb_8UD?5pob
> z_Y9Us>h&6_7mXA@9h)UJ3aUw3t@l}U3l!2`%b&f%uKEc6^gn_>y+_NR{up7)
> q%@>o
> zaxT&;C5B>@$OUcXXTSvisQ`KM<QItOYky(+m&W@fHKutS?L(s#{3n7nQD#g
> Mf~D<!
> zwRA{5LUUB9M`*5(P!ayeSCSu}@;}-paMN3gpf||2DgylkB+-
> o#m6jAEDlI8SRGP*F
> zqO+a6RyylNmfZP+NAdh@s8_f~L=0Ptr0+fn0~au9`$&r1NmvWY;lW_$cAueia
> xdGH
> z*ZLM2j#)YJ^M{JO)_+Ng7@ODn?WBmy^ICT%Ma;=-
> ZB2@}FudLaSh;D0_i)RtH+l~R
> z{x{d%I^TOU)&FMptz3)=^d1Rp{lgX%v}vUG{3kr$I^6sheqh3!0KVmTt-
> LpW8hdF`
> z`O$q@+DhI3h*aI2)PQ_Zcwz4Mm@_zq;#MCz_|tGQqqh!p1oEB~Z8aPdR~?Z
> +`-zu5
> z9fk`EmH`!Qv<s7-JtDI`DzoVLZHZbOypsUWGlSq+I63h$x(`e9$s({QY=+EnF4{=N
> z1LM_b0KZ!MILoyUqld?S!+y^ZJFpL8{3uh&2W`iEP?+xEvuJx(^`O+?EpC)%N1>
> 0e
> zBtJgoe;g-0pD+11Q7lOj<mIFYvT{-cIoXXk^vocrxI^MnI)u-cKykYsy4Zi?tK_?<
> zMqdJ#9@>^A?_l##*_xZDypK(sfp#=cQQ(B4+{hCh<%h6}VB-
> ECVA$bId=A#*A;|ba
> zbCuXd*b3f<^I#v#m-Ap<n@i+9-%qatvCtpzfpu&qu=F}0^g3Yab-
> >c=fY3`HUqO1`
> z<5T`emtNj`mtOt|p_e~G=;e<PdTGQ#(CeAd>u~qwI=7v}btwU-
> <ut@lz~4Op>P26~
> zVGJZr5%%&Q#DpLA#tZSR?_<V)B?w!7aND4ycc)KI5VkyULOBQv7xwEACz!Ga
> `614t
> zg8=%>AbgACAiRqc_dEt2>P*~^W;qBkI$(Y#Zd%|$dVlKtG<w6{XMdU%&O<n
> uTMebF
> zj1Q%LqA}f*se812?@03<IWE}O_qw|LEewg1jrm@TXKA!+w+bHbl}6G>w3+`A
> ZRS0?
> zZRU$m9`{E`oB1Q8&HNG4W^P3EQioEnJ@=95zQGy$RN+T78&6L#jUX$?j?+&
> 1Ocm~<
> zy@N<BQSLM_dMUvKiDg{w2*Jw_!(^5d#^TRD^Bow}fHOc=J6>?@`Hs2Sdk&
> 4>(>vM+
> z-
> Dhtm_xA||P`=F%WxEfW+1l5d#P=TX#U4$CA3bdAKSl74Ky|aUJ>5gNM3%K+y
> @dey
> zO(uYak6Qm0iXEC3YFKdH7j$t+;K~Yn^g@oOG)JO5+PTMBp4yQ6wh$k!a>n}7E
> KaSj
> zr5EWDIL3Pz#rx<*I2Qcj1LcP~d93`jo%_R2%I84v81*}0p!^uKr{<3yhJD@R&S0>
> M
> z<oPgYxGC%o!3w=xMS=B<m@dOvCOD4731e4xZwHQz@9h|Q^rgWVX~M|)
> 54Lks+a}tV
> z{skZW1DIO}{OQT?U&FMdg)fG<g%8PrVnQF<7yp?!1~BsP>o|$QyzHa<w}sx}`
> S<T&
> zRnI&9ls~$?=nX97G!;^CUfVu!33YY^(?)NYKY;77%cwn+>uNZ91I-
> U*0V{Nz!Ay92
> z5qu&6SbH(yuiSQeA>I(;z*NC%NTJGFe$o2Y)l>*D@<5=YSUGdV{jjdM_i)~J&
> %~l5
> z8!>L{!G=}YwL`PVQnNU4^d&5Pm9GQR8ktCM2%Q^)p+>2bdd=gQwgQ>rF*G
> B(p?EG4
> zBY^_XplQWT>T_qPe6f82O+2fghX0d}%w<rPpzMiva04BlzX`8kJl8rjBH(j7QT9p
> X
> zNB|aj^~2-$yO@8l3y-D)pMNOuti$6cK6v|(qknk+;KKW-_Y^-
> 1?;XOMh$nNmzTw7I
> z^CR3#we}7s`nI_75HpMZb^hYg>2aA`-
> u#sEz6e*a2e8HmaJU~}8a?7~DLvl#Lo)u;
> zhxy@s0_a)<e}Eim^ytNx0RkK$w2|Z3J}$gF=#|6sJFGB{TJG)0G0)0$VJ}AWFt;z
> o
> znWwg^&NY3qqSEWC?{J67V}*_U!(^UwNnqcFhmfZ503D_DR<8cG<8yZ)5`w8
> NYpHH`
> zasL%g%pk8pR$veIn(q+zwJaiFPDsJM(BeMQ%uUAq6i#gEApiHkF?o=0u|EuO$
> B(_&
> zpB7;~fMN;03YZA)IU+IjU|ejX!`&EL2^WWztOSoa=@@PnaN-
> bZ8T)Ca*N29}7!USX
> zA8L55qJ)Ivn2SEgZ!XcK6@8gBns@0*eX089Cqls<^DS61prGsJ=rO-
> T;j&kO$adM6
> zxPJooFjMl{?m$jU%3Sli?j+YMl&5mhg~A3t_iOnP(PnVJ;s|c2e{&Oi42-
> Ne_#toM
> zj7EHX9{Oas*@9Zf;R$jFTu2X#2R4?Br{RK>nsTg+(>#FMxj>CM4P0qx$sQ={l*(I
> s
> zfc0m>2l3q$bQDx^Sz%h)gRwwR$lqgLCk3|oDml`O?5C2~3|Ps}LpV`jrb>Pl^*^
> pk
> zX0B0^eRB@K1JgS=jB{KA=5H~vi^^efX}}D{3!W3k!@ywVyPT46nfVw6@T|SU!
> SsiB
> zn8Kigj}J|v<^WHsP}%wl2<x%tpQ}7Jqj?ZwEWRM&#y)dSQqiJeZ21ttS9@F;!2
> M5f
> zFKo`)R4UK^S2<sg*8@r=0)LUO`4jyY23Ec1#~6o+R>1uaIVPjvbLo;QkM9U=J|5
> 4d
> zFbaK{o=*9Otcviu7OR|p4q-
> }G&Iu2!s~>uOny{DpA%{!Wdku!IXiN^L5{g0O$L(LN
> z4w!~C&mt*hw%0tz^$ifJ(;!HhhOOPZ-
> GtvjLQAckk_puMCSRi8qZ8?)4NplS8NgZ!
> zjWoBt0n|9TYkk!2IQiLB3Zc%>J{%_xG)fhEobKw!A9F6dH!H7oB8MeVm`_T?;Jn
> r|
> z7$N#NEZYHk%s;`(m5;D1Z~O}Nru!nV^*@C?AhFIs!_YmF75-
> $r5qe#y;<?tkA3{=F
> zyIk{)*OO|8uPp}d7$lwMvyfw$u^b^DMi!#Rb9tb<`|TmFv2aJ4MHa4(HDvpw
> wH)3T
> z$cB)OK&EwUWLnUrT*AqS@qL<C&wB8z_s;A8Lw%TDo;4f?ly>a#k0M<CL;mc
> G?wMqs
> zz_5S|Vev4-JctKK=d%vR$-MDr^xH?aKf6=M)2pcR{~cBz)c<w1-
> q@cZUl9YhXuaK@
> z4*SC)XGvZa84Jir2&Z^peinll+j((NCbObtTVY>h=wjXakO{<ZHT>2bARgU431=N)
> zT@b97qhXo1DGywBlKXB(9G|PDl10Z<2)I7+q&{-
> {qi3C$Wj#*cvjrHWlKuLjhwZ=S
> z5|Z_sxa3m(HVXW0>5^+^%WBz#6wSA90_Gh1CP6XohwL?%p!gJu!Dj9=SElk
> Mb{VFi
> z;ME6>M84u66aHmn7tfVGLR0u3;mGno!ja`Yx{fSgggUbP5#q@5M~EZKA0f&`
> BK)0!
> zwU;<ZXN!g}rv-
> r{qr({3QpxhXvf*rqh1ncFVw`#lUJi;MW*q9bFq@_g?2bVDJn&1B
> z=G7Ll^Z@lvf(AjpXPq~+o$n|QY%7uJLLWo8={XDHkhV5|sPB%sDO-
> =E0QbFMk6nIP
> zcYxzT$!T|#1h$Q&oWuSiGchv;wn#7jDe3=iBjMN=^Z+Afj(kD@!Gyw06Tj&P>j
> L9?
> zfm<xEKIL)`M~dc^Us?^ux}(t+imNh|i}eK{V00r$if^r|zgs98C^eS~*xdLimONLn
> zE9!l=07fS96dGn)PtY+pH<j6Z?Z*`d(G93R9floT(||?`+)<WubX)l!>EHMx{2PBv
> z2Vm(T{z~eX*`eH9;jig4pTh&{E^twge5w8zA;oA8s)e;_@_|&VFuc{387W>pzbn
> DE
> zm**dpxk_?G_LZbRN;wbU%q))Edb7B|BVZ=V!(i^{R=?>`#DZU0Je)f7QW(gq5
> 9tAj
> zBT0`%0kiDaVj`#DNB(m0Nl70?`fZ^!(xs&zD|q8e6T0L@=RK7A=BbQjCeZ}&M4
> y4+
> zzl8?@8J~4Vff~dbo*|JB^eh_!gRpW5zWeB_nBsv;RvOqRH!5xZ{-
> |GmarLLd+&w94
> z%#ia~pei!2e!%EKKR^7vpC1NA#!J0}Qg0l2n~Q@h2n803xdx2fA2+bRt}Bn41#5
> =j
> zID@=m$d40iFyV)0U{qiHH4-
> sJyK4QYZjj(i(1@GRNU2<zB?M7M$|TfCS)fk8J6_?~
> z6?V8<z@Yd()dg<H!TN3<=|s5J=c+_@8DVLLu}BVg1mIxG^|G$WDBvokGD=I0
> Kg%?a
> zpv`jg9yw{^)BaA0_5H@--B&rq=GD{txVp|-
> bAykT_pSM)IpGHqy9RS(reY2zb@m3#
> zX;-{2pFC9gw)Aqrd?f(}n3R}_r%C>AvWyHAL-
> }sLm6{L89UbQsV*~oQYzYGr=1MqH
> z!ch{QF5zeigA$IFFkiw+5>AzHhJ>>uyj;S$5*A9hP{PF$7E4$r;WZN8AmIuLt0k<J
> zuwKF@3BwX@kZ_ZPTO@3iaGQkNCEOw5T@vn+@E!^8mGC|Z@0aia2_KU1
> VF@3V@CgZb
> zOSo6UE(xEPaKD5vOL#!SgAyK+@C^x#goh<OB4Lk&y%P3G=#&WkB@9TIE8$
> 29M@e|P
> zgrg-
> 4N;p=+d<iE>I90+K63&wFatY^3SSaB_2^ULPEMb|1*GPDSgexShmataBdI_5(
> z3`@8{!c7uxk+4<5Z4z#maEF9<Nw`bGdnCLUp=u~BgzoP8`Flq@%Eks_=p{dOV
> 0xGN
> zRn8xeJ{n$hmDByTx86T$Rhj%^lVtZUfBJ`!{$H5>@=qiE+Vu4MyKDXFw;}!QOk
> d0N
> zSEQ$ZqkEP={UM}Z&h$M?k$yyK`UKvGk!}jp1xk_bzkcK5O?=G(U;Umyx?xOL#
> &n%X
> z$A12=e}ARGUn%fc3jCD<f2F`*DezYc{I8)vVfiqp3|BR-Fs^O5?!ol{uD!Sp;(8NT
> zAFjaF!<^G`jm0$+S23<txYprn#dR01`*A&i>j19b<H}i%Jh;Z<nu)6r*LAp>aBaf%
> z1zcap^$4zKa2>?;CazvwL$4X;jKVb**X6j%aMj{khieP2?YMT~`Yx_VaqY$R5-x-5
> zZCrz{9p;>hYYeU#xaQ(2#<dbx7}w`<eI3^$xSq%L3tUHV<y<$+IRn=WT#Iq7!nF
> n0
> zS8)9!uBUMw!1Wtkf5LV0^~0RWxaQzmjB6#XW?Y}cbr-
> I0<9Za=bGQ!TI*e=34WJ9I
> zd|Y#ImEl^0YZI>RxW10-AzV-
> 6O8whkQQ!n;&vSNfpXW49E_CkwdZ9D&$UHAu!8~W~
> zZ{|6NYC}%2vcQXX@0zcAe+h5l#Nj7+ou(_%9=KLHRZhLr=(IRBe4X?>8SnU)kG
> El`
> z87V5AwNB7E7azV1I!l~#XEFXwkTexZIV*6cU!%aSa&Ah3ktuh+a{=HsI@Kt_zO
> Qh~
> zQ11E84bD`A6Qq><v{dOhv;a;M;54ArRf&78Nj_rgfR$HDa(*v;1!~NCHytxa6KG
> P0
> zlEO&EKmW5wJ3?&+=9NfiYnNQ^{QA0@hOpx-
> THVmtjAoc$TIMWiY+hSg?>GyZYqVhi
> zKMNPz56(r0?(+whEpYC`buX@6xOU(QH8(dlUm9Fnv$nB$W3aNmzOkw@T-
> VreX>es_
> zwT)hh*qegkjZHO^vF^ZG)Ud9yzOLGrI@nToOU<Rhaf>3sl^eq~Et1R`2cjsh!P>
> ^g
> zoBZilRo2x<nibptX@ZsE;HtX%n&7zFmSBBd18%AnezmjGS&g%5$!ATDQn13A
> 59);x
> zGM?O2gkN$?v$GK`MDD9Vd?nhId|ZVmg~Rr%a27ftr@$%3T@ik-
> aZ2%Af_9jKs{uS5
> z0jvqQpCdfo;4DLn-
> hvYNR{<;*;JI1&e_n#0gGfsWXmXY!uG;b5Xr9Huh7#k&A1ep>
> zv{dSBYY@a2mNo%?J|r#u-
> FRobl)VIb)*n|HDxu`hRD3T)y&E9I<YG#N)@u<??p%Vj
> zq*VppF2WPE3d+@zGeN1BI@}C;)=1qm!&2%CafQCxwu_MCYH7hbP;;Tsq6u
> x*=t@@&
> zT7a@xj&!^)MA|SeTd%U(n&3QPX|UGR4da@E>nmF<ch*#ch4E0gx&gP%jgc
> @|u4Pg%
> z(oz$waHA`lYeZ7=72*e$p`4;5aYH#k1niwZu6hDk`*`GQ01!zs)m(F-C)hzx^!&1!
> zF-
> <?BR{@$*wmysuRiTw4q60lCYDtoz8hq}i39uW`ww`RJw`QttJRbQ|Ua59v^;mM}
> zrKB9#C*^-nPL;zf?>6|POW!Exrsn^k^5ZZ4!^q9TP(g8U{?gLY^5U{ZOP2%-LuH})
> zWud}LgO#hoHO-<}RmJC@2M%PbQz|CspkoPE*Mw`T!eG&GE#kuvoyw-
> B`a10;g6o?b
> z!!^NhqwOgaU`<1HuyIwewx+TvxH7V8RZX)f?Ee*b3?w*cvi|X0S+fc~?#D?m7
> h+4e
> zvN@cIX5^s%HTVoby9)6CV)O&^oliq@%baVWli4FILN8eXja?vpL!szqKToI2jp|j
> u
> zep&^)#;3YOus*sTCsbA973kNk9`dw~<A~8gn@E+k^cHn3o~0A4Z){kt=E(7;9e
> |3*
> zYVXDd$XXNmgmzv~h4#aUYo%W}RkYa$k{+&cbxgkdAHrh*N);9q6<if6bSkK5
> s%mc%
> z{%8rVuM5`(BMmn-
> G_G$5HrIqB%?&{qtdW{?VZ3HaTR{PvS5R17Rw^xdtTdq|g#)Hp
> zva~S7M8|?NFLc$SB}ioL)n({W!?09n(Jp|MSczZz$8m_Y-s+I5MeHu-
> EQOR6Lh7yp
> z9NJ37Vuh9AX#r%d0P*Z)t#z0Vhc;ReBc=_wR=NK)?pCpelS`ods(jNr4&kam=?
> kQU
> zpwz^VPa#qehie5JVn<ytaK8CsgR2f<iOU5BHAw$u`SU2w$4b2zm=uVP^5-
> LTQj3?`
> zwNqV-(Y8?`Y?lSNnvt8f_k3J+Xg7}NmZIg>h*iY)q0O)g@tJIt)zZ=xfYaiv!#!=)
> z@xCY3eYVWwv31EO^D0wDYpWU~=!Fxy;ds&vAa2sa99!v#${S%d0ec<SI;ayZ
> ?J(+<
> zUU!Ze)}t@zKZOHG93dS$jirs^QHZk1yQC!Bq6(qoEM2(<W=pU-
> vbHH$)ws5)9%c+>
> zvI^a7lG>aUY>BMo&^9=3!=!Y*juAG-
> )u~w$1KouBuaYr&YPw^Bc0N0<zIt;|`WRaN
> z!Ao&}-
> U1GFWkhkFjVweZ>KaxD8>LPy!3*c)IKjfoaOI`J%g43M365*Y0S{e(_8|?L
> zL4!s-s}F=@QtNe4dU@8X9T$-|#!a4f4T^UPt-
> 0rV1nO%lZ)$<!ENcvd4BjxJg`<5A
> zmE6((;>zaLH7(&_LuBnrn3NbTRi~st88$<(u0e9MbCrRZIt)_Vm1FIu1TWMHZ`G
> lF
> zDPN7!<{aPAOJe2K>bm5&mm`Jk+mRJ?;>e{A8kQW%QHDP~ErCoU8~8oMj+
> ut^)U(U+
> zy99LhU{P`hf~{ULJ976djl#;cm8;RCtAVM5(%QPJ+5v~A;Az@HNjxo?8XCj4y<o
> dw
> zOlwE4DT7*XEPFh-XCC#Dsvi{(zb)p`RNE)BZMGJzw-
> $O={Wv#e&^Yv!D8<>z<QwnV
> z`uN5GLPWTU(h~$fHR2yR#`3`!XA+)mZ$LlM81Mo$O(Q~b7PX%C13}?eEt9^_`
> ADPV
> z-N|@j&mKYQTHLP`-d&H7IfDsk99c&IuTFZ0U;_UjIE`cCAap1tnk6b`EZvsK5i0##
> z?31jQ%3|ICxWwsl$P2wi%TSB!++LZ!F7<NN07ueQ>$40c(Z8j<?NKk;V{84N$&}
> 3G
> z_a&d?<KKGm&#AVy^1BSU;7hZ>pLb=_6I<Km*y-
> mx<*<MJw$8EBhakCyu7)H}P><Az
> z=h?fr{Grrk|F#+w%2cNopN^$xH~CrNtn#%QY2bg>6b?!_p7ybt%-
> RWlNXf0D<&aOP
> zZ&;?i*AnT2w=t<X={v84T}WOach13O`KSVvpx&(ppRE`DSr6KIx=i2dJ6ks^GwW
> P^
> zNj@$VKBf&sKDN-
> wALLGQK`LLb0zR~i)kfvWaw$@kq3x3`UCqzBZ2$~AS3oYUM4f8{
> zy7ldAZ<$;g`%cT16~Kh$(5txszZ}`p@-4tKC5S22(|ImpSy~0!u>o>J{lGbj4_2=B
> z+pAJ|D*4%MKf1*yS2<N{t0&iNfZk|aySB2SdNO{UDVU16KrmP<EvcGAxi@vL
> gnTl8
> zY0<Lc(0r$5V@tSZEr8;WEgAtH<bZWj3){xDST$B9p8Aney$&^|Pd13MCrFF(%
> @}CG
> zrJ&g|@dwOzwbnGzs$<Y58*#C%)`|~bb=t+wMSwtA^4=0B|Fh*SmC!0+x>2y
> ?{1eM<
> zf#%|`+TxsxQkm&5J@cuyqdh>5y#fEmNDEH{oQs@kxKD?ut=<GGv5X4QZ1q
> C7W}@tb
> z*EYE=g?ps%W{I>09)6bRG?j&?G`4wdEPFG`N((T{q?Jf3%8#Eeq)DnwS&S5JjY~
> PE
> zQrV|8+B7;FR^j%TI#yE3kShJBA}^)BtwoD_RHDD0b0_`HwoOJ|ZGAYtpiD83wz
> IYx
> z@5g|L*kb&n9M&UkBicpN=Zj>rm96a;L<;uetC7d*wI<<VTF``eb5a>W=R(BgB
> UbO4
> z+*H$rHyrSbho{Gnneeo{<)Acb3)acDfo*ZAMxx%S@HoOG$JIcxlmZsJCKo#|h
> 2>k-
> zi2cz=-)cX^x>NS4L3y7l9rhjdA7{ssWyij~9$Mf=&`8U-
> RC1&TX@Hd38fbg10~Bw(
> zvI-Pozm*zm<-
> S7RkiYE+hdGk@%C;%_uTE%ni?lcUfbnT@mM(UTUM;j=iJY9FV~*sQ
> z^z@a`K{~dm1$51k9H)6WUTaE}Z*4L=>&QN*41Ei|B{Q8F@?`U|Rcu{SC7%*W
> zE_Kw
> zR<up2P*i8=TYbZLOHWEVVW-
> d8E8H9hgAM#KoGkz35m>UXYX)68n@*b|2yZW~;t1$g
> zkEi+0MEnb)pH^E~TOtVWP91bfGg5JO*8b(ApP)V4f`80ITZ8YZVQ87NPo;#=4h
> Tzo
> z(>89xKT@6}6xNMWt@7|GP_hj7YmtXKL~ZXNppg4Ge&8rW=}R2e14fGrNA(6
> <U*{6T
> zuI^Kbm<jG?Ul(*{yBxk4+UGBYztwvm1^;THhk9yAP2OqiV{HLw$`KM{SIIqXM
> 32@=
> z@mjoDk5n7+8<F&s&qlNs+nKz@7Sa(<rL+i3&=^0RwFPrfQYA{{xQRSLx~sMB
> wS8t@
> zt45g|N!gK1I;Q^8C>bAxZfy6z1buD*CC7j!EdPIsQvLH8+wpiMg*^*7!*Z9Ue?y
> Yw
> zeHe(DWYhMH+Q!zhNynDG88y{(_jekkdzyQn+5`Uot<9&PZT<Ff8T9%>jDtAx
> o&dY(
> zqGQnMFR2rcjkk`sLM}IIucNx>Qq+fk>3ZRVa3#5<Kj@TPuivQvb=kwMM-
> NVGgSM$^
> zV2)AA)#?1I+&VB<_b(I2m-
> iy+=@eJ?+UyrTKKl3}dNlcHboa*hY9o7;{%CNUpr2~d
> z7Ss}|N33q)EJOorVd@T!672I#_nD(d4-
> 3mzA70<}hl!3hQcI_FYWr#ZKWe$;C@mwo
> zwzl^C^_Qo1ndR(sPR_)kjO)La9}j%m3G`)oVKUs0n@*NK9HS|H?6~*ilP5pKk4
> v61
> z+k_uoKic+HT6pkCcW=aN`9Qg38b(F5yw&$WsnSuog~capb=nc8jzInGtoMZI@
> #^J?
> zeAZgE`Gc?}8{p@pE?$pt4pEgqt51@#Rh!r5W+};7GlqS`2Psi4FOH5pd)ji1)h8cT
> z&WKAoWRH73D*XOO76m?=(T>}!Ez6PFxyPXM@#_)RZ{U(_eK`%=P`S1ySXJ4
> ;nY5KP
> z!Roq}ruxc_m`ua+m*sU0vp2YSS-
> +Im{*~w*)w)%FO&=$6w4mND%OQ4LME>%|sMSbC
> zp9uZl8v&KRRUKz7mtJ@_%CYvi#l!QD(c7I|O8@xih~C0t)s(Mkk#Lr+#kETM_w
> ycq
> zX_>L|>}z^!)S^`D%yB{+nwo1`TCg&G;1;oT_+agk$wvF=Z8CZCWKd51u>N)#m
> _I&_
> z_86#?<oCy-
> e+9U~FKgtFRj>eW07q6MTnBAUPT~5E7Ch4*M2{xDD}2u}dp&YgfL~`p
> zd)pLzLm%}GNzf-FM*V*3E8t8OcWBVJs-
> 78oAT$+y;PeTQ#+m(LeDAG0_GU$G|GP@O
> zk-BcjySLE&@M-s^&jJ#TU3rjNmbWrN`!~)$(MQHVd#|fDv^>Uf4F^3f{PX;m-
> r5ev
> zv+vRwYP<8nftJu!@my1%N{M7xn%fUClV)6iHc{=t71NMGA7;z(jw?-
> +BB;xyH&j>O
> zu&yfH*jV3k16J8otgNrTp{1sNRmFx`GZ}G1OLNr?)hkywH-
> &Y23GFrpemVMUg9ynx
> zH{ouT^t0q9+ZRv+a`%PmMV9FKemFv6+n)<qb`DYJQ<ebkdW=sk+~heDrHAe
> (Sca5g
> z@iTHI6ZzKWT8=*Z<K}brgY<>b)2eN5=O^v#57)tPB^}rF72|gyX3v(&yg26|Ip3)
> (
> z@hs0Be}1mQD*~*m@eAIX-
> yAMnxw^Ebsj)eHX>eJ%nX8P@g0iY9*w`GjI}xgCE1N5^
> z3cR_6OLsIOWl{B-r)N3iR_Xe|)HlffW(I7v*^qhOk3p@J>V-
> lFdUq|=X~`@Tm{!hI
> zqj+;P?E5I?i@*c^nPiU0$d8qfbIv4k2aftFlObyFmbqV>>iQN3ssZb$o<6UJ>=Uh
> T
> zB)#wIk4{CX4QE(6icF`|pQk?}-
> w#~>V`0Ynr@sGi^|uz#|5V*=J9z!D<yX~m>3Agf
> z!2{E+zZxmec%>YhUY^dUj#t}{dj`q-
> Yr$#bahD#i{Y(GSwH#8ff5$&xQwYwqGcEMd
> zB+u3KU)Bea<fV{Qf6rq1(?9wn{gy&fbnPi^0ImW_mm1pme-
> 5lvZ}_P(4mg~PnXsG;
> zV<x`)AQz#0eEw18gPbH8)iGjDV$5Nm{eCx>Iq*Y#{t|N;|8sLaTuos4tO0#Sau2
> pl
> ztP$D)c09ZU{Kk1CY6v@uSC0cZv;Xw!mtY!d^BVNt3g_6q2<r(^eUpk^G9(Wp-
> hDWK
> z0%x1mUM~WUo^<I5leXe|tahaxtm_{AJ+B?f>8vbmbI!%nwxPC~44kY^q(_E
> &i~S@=
> z1)R_I_L6g4yHesRamP_FeT(eLIZMm&FlT!CREf8qt;cm@glh5N9*0`7$GNkC>$S
> KC
> zX^D8+SWC`*b1cF??@8@2&Fdc@=(?`-
> RU;Fm6wcanT?G9?td(6;!j&WqVv%sw6?=E9
> zn=O{KWocL1v3X-+EW?owYpHtI8{=r-
> #oDh$nd!D{RaMIstW$Z}f(vK4zZcD1Of%0Z
> zU$SUEwxj@4|Gs%0nWU}-
> Bc`ONuKKbV4%GHGJ?GeU&70Rk)=o^v+NMo^<Hx~{i!80I
> zH$R;QEn%!>wrkf~R)w+kP(~W`IdfHluBx%{>`Fp!gr;jvy)}mV<|2|1wBxE6uA|h
> p
> z%x{R)*Sms>uR09nX8V!O;GxdYK_jz6q0kWiT|5=s$IQW5#n%iAIG0SFy1W=?H
> 3Wll
> z#Ajed?F#%k&W5H9_zNI~gA+9P4b%Ys@zKHl<EDr^V50n;4?NBX2Uu%>whT
> wVY_BSj
> z8tzD;jjWy{Z+(NVtFx;t^O2gf7)r%VT%c{hKDSAFUR{gBIei<Wl;k*_zE;}ov{F)6
> z;H19ST;=ZmtkOtBxDIZ%`L#7wH|f5I9DKCJSr)Fuvptpo+pw{j1q;}DJb|okuWD>
> =
> zjx=Fc9#R)zyi!$Jk4;|9b(JfzeS%xrxC6m1r>_f3R9!<|xDH#mZ;@OnWiXE)C~zo%
> zs|i~gu)DP~*n(Xk_1M@@jcpfl5<;++87ifiN+8hE!fkncJvkU$v<iFbuuYIa>l(s1
> ztpSd!%KAycjg66DOKoGM9=mlaTX3cVmhQJSMw+W?n43>hq-
> <g16ZYCRH#VVK*k!x2
> zF3datzW_tCnhllQ)pBVtm@{HH$7jK+;1$9Ay5M+h-
> d(U@!eu!l=GRs>td=1i;Wk#+
> zaPa2hwGrFo>g$8DNnq6~Zk1tiH%CC8@J5RZJZ_PC?0;V!Y-
> ~a+k#GWMvNVzGJCKca
> zOdncSEY&4M;#|{QzcJWSxei$>tC~rk%HXO<Llr53O4iq-
> 9%ZBv{zqC+E|OPbyB<p<
> zJSJhuzFgHcRrQt404U^X#7Ph~QB`BZIwi8c^JQvkWCNh#k}_Aqn~Q2UBU1(-
> ZvC>r
> z1N`H!|5DzpRHh`^5{!4gbG{HE!AN3glqDxY8q|4Z4QnUt!|FiJ-6$WIA~)pY!ZJ@l
> z7U;PdLG05GUWko9j+LXL#_9+-e+gXHi8$-
> SmP#Pd)mIn7e_+>Nd3(6nSNhl41fBC>
> z!?IVVokMHZ=BHnVwh&i!(Raf$HvAU+WLS?Q5K|6)V6_i>??%KWd$YN=i)#pi
> uvPtb
> z2Z^RMPS7#fPy-IPn>sDM-
> HO@vsHqIPjbb&0t3SY1HO=Hi?1B;gPcR}HB2k7cZX4I4
> z{|I_cP}jOiOcTQTY6Q4G-
> g2Fsg6e9Zh%Hr9WlAAunVhDA_{4E6c3%})#R{>l1h<Vj
> zIqrTiqPD&T8lxe+ssQ(3u;%I0CRf*EA!UKbsK?EKmbOU>I6*SUS)8nSleDf?w{oB
> i
> za8X!po47Eb4V?L|mbE%ocH>dCQbPQiH37p4wGRm1ZU4#wX9cc>xJKjZyL*9C
> H=W+c
> z+M8-xnq04=?o;~zrrx3-
> Rd)%|>ZJY6(L)nx!`12R@2$0iC}%CtKmk<>TEHZtm#JQA
> z#Mvu55RqniWpe|X!SOq8?FhSnzbU<@4x~NR)9E-
> xb?gipSA~OD*HP;S=TDp%EUZ}>
> zSsh$lx3ami8OuPA!!Nm1O$8|ix+#+%@_76Oe@<@!_foQ2<FI`)r?|Osb#vufY
> >9OB
> zOX_b<PJS_UK(MqXjDwh9b5u)i*9fo&ZivO1qsm_8o=P5fIg4>j4S%7<yty(-
> f;bus
> zbqzSXVy(y`CopRp*V7tlW@k;*&<(O*h5!d~Q)yWu$2~3v+hlRz0I~74TXkbqW
> G%YT
> z1W?V^qQh%gf;w;506s_^#r8jD_C~aJR{zg6#=hKET_$?n&IQx@nfd8h<L(bLi%
> <J{
> z;Bhx~IQRAX&%{{?8Mk9t{~K$MH~G$?u@=5PL5vcU>HHo)OdVz0J*o=T^GU8
> 3OP{{)
> zHR#iI_j+oa4vbhoS_oX5%`uqnETo6tNyKy1z*TP+cS{kQkNCELf9$hO$M}5YQ=
> b5L
> zRO-
> %gyOLf{@8T{k@63WiJaO)Xd%bk$Bj@dOj89y(96!z$yG$k7I<j7z>9o1iaU!n#
> zOMmmhuq6zoBg^ABn0}O-
> P%>9#I<g|hzt`E;P2baE)19B?sQnU9!tORuxOUG&I$Z9-
> zw);y`N8R%qn?oDw!q9J3&|c_MTF@ug)QG{Mo|#ntH6cu8ktpAmnaQ6`{|tR_
> Q_+ub
> zl$*+j%%kTgB*Ri(v~RpJQhC&0zJ15`CQtL-
> dT{M((3rlg^qJ+<GW}`woj)dB3O&61
> z=|I1gRdUW=6@V<BUs1NG2&ZVwuUJxE6e?XbU*d|EE(w(tlwQmD`DND@i;s
> u*OBXLL
> zD8m!(3l=YSoQJ--fT%dTm(O$V!~NWCS2+)TrqJ2t-
> tSmm=xlfI?=2~Gwz&6)iVB?#
> zHvRlUCu`8)>>)#k1%~IGkUQeUypboJe9EX#oO;^npFHEt(Py1~PVn3@=ZzgV{`
> ~w2
> z7fhUV;p8b(FPb)e#>F!)nKk>;%PzlS&Xscu=FKk*Ex2moqECH#anX{c#U-
> W7%F3@^
> ze$BPlU4O%kpQ%_;xw5LdX4UH2x-~b|uWe{-
> y1BU}99g%1!^T@ayJ_>Sx1pUWVcwn=
> zs{=TT!q(9@br`A4!97p((=|{vXg{{*M(6spm>a=Q>wPfOXUsj_@KH;lKIOTY^qr
> _L
> zGg*qb#>LL%e%y6Zd(UeBKWCj%OS1Zr_2y~~`bVt>qz~6?PxZ!T_A&A#I9-
> WH9#GGg
> z`o4nF&I7~tJdrImVR003Adt#a#9=YUqST4hj#gKu^ODu7nck>=wQ#tno_}gjG=
> KxV
> zc?R;S?s?VKy59V;?mhLtXRA%YW%YP^isW5(y8BhvCbJc6pW&x?>VEIbknRcw
> _)E8c
> z?7B*>w@k)Dy?#2Mft|?chwYq)f2V*yRdUT(US|AkzpAqA$IF|)RlI01YT3LS<6
> MTT
> z|9aa#hda}_yAbu3FjKw#-cG`{bzcOIruT!qsnjNxtUXuv&_l}dGqt;yjx<rsZBEA6
> zo>ogEEUu2ynJ2<eUFASbmPwhK&RY|UJ>4Hey|{PVt_e)GL;c*O1zEoF+DB=j
> @u~Ei
> z2fa)QQ2KG*)CJJzwvM{1j=RWpt~>%;N8zxBdVWO^?`(^xO!#wCYWn9_<x=i3
> r#uH8
> zo_CcDi><+S^ruu!tuudrsnT^tBxOcNy`;8!q%<a3&(H@)Z(WP@jvPtN2e)tsWij5
> ^
> zIrP-J51cErP8v90vZnI$5c$K?S>&kWuaEYt?CA;R_-f<j`5<-iavgt7j;|hz(H>k~
> z$UU>i-!7@Sj<+tU`Hr_X6_Y1@fOh%c!e`@?tc~ljQ|(6Kl#8$`jr-QDt-?7j+K<{|
> z^jY(ne-
> #OSOzy?G$CN#ZYG|uLsFhRoTe5CSmz2~NNySO~O^$jf_xuYra8jpOCphr@
> z=}_sC&|-Ld3u*mhkM`QS4On;yKU8wMa9wqn^JKJx7Sy-!C`tY<s|jDtV-
> k6PmG54>
> z(1gd8mb6+n!j7qN$77jhzp2H&e#lx<)0~SzZT@kNo3pw0l!N4FweAT+ZDqBol1
> HqT
> zHg-LL1B&R%06R9oOfU{Yp-
> t&QqMlccZ@r)jCm+}}pib<!6{pnkT55Tz))RG=+B?ZD
> zZ`Trdwm<8yE1px!z}OFUSc`gFE0Jka<81x(9D;Nh<X~D(dYX~rd$M%>pldih`<e6
> 4
> zq?B6ptTB1fuFv2ZIrBhawk<t9#E^M|l1kfWt@J`XlTOFf>`9fMb!CH|US)kzmU?
> #1
> znta0A`RDOTBepOt4doZFZM`v-
> mO<RpS8v<4<tY>7g8pZ+Ki>83nNPJKjpv~*cJ+(S
> zoN?}~|MSR>RXaOc>7PG&t`lW46(4Fro%2s#Ymhv4CH*yTD(!4;zV}WnV|wpN
> d6IlY
> z4a!j=*8q{HxUPp!Jc+?i54*mHt>%ZDDv|lekmNdO%sO{XMRjxCIx0er=4w$QT
> c5ro
> z{&`RR%Z_)3m99!=kH;N3b}c&LaJ`dyY`ysxk2j~GZB@tl)2Ua|AERleLx-~N+UD$`
> zct)51xjx}bWsCIZyYlD1IVu0miTqn0y~;U&YaO`pSaOm2Ua4hq((xO)$+ih~g07<
> D
> zo%RKK76-MR%A?{pP+sqZCRD*GE+|{b-
> <GDz^$qLru?p?Fg_Ay>bF7NRgS^nyYu*V~
> z^ipt7AXma@&#0P@yQbB;xB#OYj@?!xjn&$zt8R#UdMfL?anka8Z<sHYj{TRy
> wn)a9
> zZIv8j+fWV@1732#7=Kq*(tYnt#-
> U^U<)3XU+i&HI4CtvrR`1xk97+dQEK&2@vy(K=
> zT3xE8Ti~;+laqro!B0O=iP+P-
> WbG<XM*KXKnu`3F8b>^|FXvl7yvaP=DPw(8VGInH
> z=TvzoKv|wumc1ZR>hZRr>MMU6TKml6Zz1`4hP@^wjw@5EaK{Fvy~GitjuCZi
> oR85l
> zwGPJ?Uhhi%OV0(p6I|6vx{*h{7|TQSpK9x*Vxh85T^~k1_P;s;%t!guUAhB^)U
> <OI
> z6|$Q1YQcqb9qI9Uwv^f>>)2c}nzGLxPW}=y<CTup1;CO06n!o9bkV<{7^`p7TD
> >0x
> z<4pXm7LKleB`nL4v@W?~#_xGj=_4hre${-
> bb;@K3_+io7(lZ{tzR8b=ZF|c>1H((^
> z74^GO&)c&E=`Hh4fa4m4QpAK|{cva5vG=m2>l~h^<+l|4bklqGg`^YLFS7*ojHJ
> ?u
> ze4T#oVLGn<veIGX%UbN@G_-
> Rv+jEwdYUv(dE|pb1CzJe0`J{xV+h?h?qD=5_!3WsC
> z$rD)@BS!^%+L`xnsswwZm&uS`%Cq9h^Vo?;CLC?;se3p#n`tDa`IJM6ySGM}XF
> =;~
> zWly%Lanf~|Lg#6o+y_?xjL7NKA<J+r!W#Edgk^YVY3b)+mg#*hEOnJDOXSM)
> RQi+O
> zcv6Adb7L?@B2BpVy&NSi5bp!e2jM=(F#b`S=*eVUE2pPoaolQC&%(X(5l>g++
> 8)ku
> zQM+-
> io}C%7qhXG~lFO$CVQS_7dgKY=UiX_aE&r%}y;aaGos`p)PeW+`GQ=p|7`I#~
> zmKs|QyJu!UZ)PRp$*&&IavVZGaQX<9^ZS%pwGCL$dOWX2%AkxeNnzWUW
> Xf+jr2m}W
> zeC(<O=WwT$_oVRIC-
> }L5^Tq1L)bG|Q{kRWf8B%%}Yn$0UtadFqwE^2=t<;QtB-@d-
> zQhrf=@ZlkOeG6f05B=wods~7h_sKn@e`P{yKjvUOU`Iim?IZ7RNKnBa<Bft?H
> &0Wf
> z_hg<ISa)R7%R?)L=a|q7a3wC5%Dqr(qaPcdu34b<YR?m8Tl4SZ^$XY%RGY07U
> qGr>
> z!Il9?*NhZg?0PG;PMT3yo!`<`ST<JSruGTk8=`$P`%0Znqr~a#3@vrle>w}RBOTV
> A
> za5(1G7#DW9x(4Gf8Gf~dtMO%kb#h-
> >foR+{yKDYy`0c@<<BY(XwX(%amn{oQ3?H3k
> zi<VsFdvpqy78NX7;*Y_4<e5{a&lr(YfaPkwPf~GR{@O|`cCSQy7>5}*$rAqh#>#
> 40
> zzcxQ;%dgi3hq7dx>#udeX(e(u)UCqD3?}E;1?m75X=sTwaicWXpI6EXJpt)k4hO
> eu
> z%jDp-SmNJ+&**Rs-
> `YkjGvBD|?EE<5)yha6HUY>=c7KUnsfSN7a;bh|xt_Q7Zj7%q
> zT`pNygN5}i!DZM0fFhUGRo7g&a^r>k4RTrM+Lib&MavlA(o|Qa%l~V*;;%Zwk
> 7M|k
> z?@bo6vq^=n(?{f77%cF}$8~{4%N8xxeFUqT8`tVeYOeT0Asg|f4cR^3fVF_@61
> xrD
> z{T8x5&?RO=HNPE3tU-
> d+L`ha5`lvHGxG2mO@@pHh`J%q=rW!!!!b2>NOx+vMAUIvf
> z4}5UpYA}CFRekdWZ=ZqSSs6?q)qpKRs5xki|MIf1zP_lku0d)~ewxO5a}PsJLt|u
> h
> zZ4kZ$?9D(^=pK`#cCi#=zKc@m<*njZro)%iq*?J5wFWG|tis1gl(~+B9xR7tOl2A
> T
> zCL8hd3aED9Pn*T}k%mfcfdPkkDdb~MiY?$wyW|*kTwmwQDDCFuo7rzZNcl1
> HUCew<
> z_}pi3U0rjSi+=6Wb=i9%1rRUDazC`Mz-
> AAuGMfU%!B0?TFA{iNG@JRndSmYiR<brW
> zv^0Va)ivwt{-5@~22QT3y!+%siM-
> fGo7a~jwwFjGN;b*ni%l9Jv$HdsmHilYXA=m)
> z-PxJD*@4-aaXvN)4R%5BMH`V8UX4mE2vusa(i#;lZBwN-
> `qGxS^1en&YuaK<eW{I>
> zDz>2g|Ic&J+;i{T+1-
> 3WKQjA!_S}1(bDnd~b3X3*c+T@=T|cbHBX>_(tlDWCb^fqJ
> zKDTTB)RCeWW|Eg+Y7;zCU@N%Z9)%dbHDA0)ycL8jyjrT<YU=tDQN?|G9it6L4
> 774{
> zAqo|UYb%p^v|Thh);9;VdQsn%;Rv+y>=cZ%pj)D-
> xGV*(Aht#OqAD!g=n)HqGLyOu
> zhesCa^eDq>&BMrck1;!6DHSQ_i!v~*=3!)54E0(dxT+b>u)05uW2DsAh_u{(BU
> >cF
> zG1S#9xP@%E;YUL{ym?N;`6|zDXeDHqo)7xpevu2X@tkiqOVijPf@h&JyXG93d
> r~|h
> z;#{3KJNICJY9;(-4o8>YZkZ=?95vrqGc!89`Q%<`QG=1!ko1fAn)^F*zQhc7bg4zm
> ztb_f1FSA!?q<&<tE*M%Qez=RpKiTbE>y_P<+fFqYn{$lT=@WY*64j=u=(`KH&
> ^;>y
> zzvg_|wa!#eWxH95)ufzBnfp@yO6!6~U8THQ;2d{S&qa;wQa>cohO}ije_iU!#7
> bM2
> z`4-QNsMA62R?8We+_mPK($}J6>&*$C=?G_JbtQEvD-
> YqDNZ|NZyJS^NJv6j{M7zI~
> zwx(rof9Hr4Wj$l|jU>FW3dt3=`Eh>k-zk?^JR{`%lUxybb?WXGt?g1ao;va5o!XAr
> zFXdF4@pwiq=lit1!POagVn30xj1=6*W6hftW%VV?7r9;2vv}^K&Xyl?gY|2;$(!x
> M
> zch<sy-
> XBQm|FljOL(3V`?46@tCi|K(=$+2`pgsXgb8&Szmy&bcaXRxOXJm89$?469
> zw1<~JA99z1U$eR7g^i5kL%9FZK03z`vy;&rVl(JdcXYQNJ+4AnGa{S{KJ)7$H{!YG
> z5043R=d~$c6g^u$!7rz*qiJtUQZ+r6Hsg5jgmxVUFmCb|ozb4{#}4z6yCU47jN;U
> (
> z;1h2?<WPGPjr{r}=UlnO`fsN5a&w36(znyb`5W5<&mP0yzOe3u@E0(ueZSnL<
> Ni12
> zyhb+zZ&=B0&#B&zveU8mj)L>b8YD~2OwyOH;~o{iu4&krqboB+nQhDzpEhF{
> ex~^L
> ztd_gMq-
> xTU6lDK#x%TBq#M8R=Mt)?psoj8E0oapD?~w1z4WPq4uCP1_%O@D&0d=)=
> zzmV$yrWOvL#q5MTV=|kOeQl8xl>75$x6?nrY_|Af?`cac>WmJa@0c*$zn(;jGS
> ?*E
> zWVbi$E4j!1TD{m;DyHl1b~l%vs3$A=p$rf9-<l~V-
> Lbw*C04HVW%j<cUVLl45UcMR
> za?1nRT7PK@!h{?X{rz&5(YATRdv1~on_oOZ=n91lmxVQA(<NVx?H#5WMT4cx
> fY+>v
> zU3jL(QL)w&Mct-
> va%t=V3H`K}cjFsHg=a;qcb=S^(VZs{qCX}ID>`JT&yj6wF6Wy*
> zAMBn*E=WFuXN2K4VeT|WpQS~e^wM^_Ep;Yy{P0<CtJ6833#JbJwn&>#&27
> =N!(Ee9
> z|Dv~tb$^oesElNCE04Ww7uJ{}%wxuMf4$%Y;u#H*JXJBLS{zBtdS-
> XNSk3Q}^tifU
> zFQ)Va1YW&6jL__yEA57^0^W$H|1fUHi#g#Qe@~YBuv*>U?Znu;M{CStZJp}z
> SZ+mf
> zPoJq6z965yP@@ooew8VR1efb&T_$;#BB?&y(1elM&eERkSSj#CcMv1;8qny%
> >aADj
> zRZbto0tG$%a|Yi}^pX`(BW7nqM?Ed)$#yFK$&#eU@A8SAD{lwyDthD&pDX)i
> GrJe3
> z=e&&NGAY>QGCJRE&Kf@xo~5VNPtHkYj%M@;2mMUjz!z@H=)z)L^36YQG
> pAnmT;2GY
> zuT)t2TE3nBoZj?*j(wclcA_oVy8&ia8w{76W4K-~9P=*Ulqs}+j#lA!DKSSI`G)(W
> z0MEumrbz+EvBA7coTzanDz-g0oRh`|r_Fh54>tenILv?&c_@{~_Iyq=P-
> ZE9FQViX
> z*Z54=NTPG>T8?=Tzc03(v6tV<n7^N9+UoJ-
> pR&CLd_}3FS@u&Y_aN<xXJFRx*Xh<)
> z0gm&e{zU5`smBu0Hf*mf%)T3UpG3d)sk4e^tbV=pHov3~hWQm`nW$CE<*b
> P#m#J-j
> zM{PYJerq}rs!^$${cNdcvnpurYi5nG7J1`ZVJ6#OFR!(?m$u$lp@)d1g`B2P*23&u
> z%w+fL<sGAD&b7bW6g7?=Ps^L#x|gx*WvtMOv=_%d$^)^*Hn&A-
> fwQ;R*6n?6aRYX}
> zM1@eqco>z#sFdlq6f;TAO2j_cQuxTIezJUSmTx~bbj>N3FUxDj3$boBcY9u^Vj
> OFg
> zo7rr7aa=xi>9ZcC^umiUCpbbH?w@SEwl1+rqxt)MJnfO^4bk?!P9ML>A2~HO
> W$@H=
> zv6@c0e<jhs_!Xn%+NtYb(Q~nr&#$Rpzr6(cZdNsv{FJaVvKT$vvTMh0GdW5*T
> amqQ
> zeJb5t<D}@fS<{|^DL0=`2Xi1}+woiL!o4J;{7u*X$=81hv!|f_FS`|-EdACqa|)D+
> zo<J&vb8{Dj%474h`HLpC8nu#%p+}fikC`<G?SJ{@<C&BnS_R(BdYAL<s9VF#F7
> FKT
> zrU|7uW!A}k^RP6x(GBm1GPKKH{P4aYX`5LRcL)93-
> ?H1r(+5fp%RDMNAKbm<&ew8p
> zPdS{1IVCbwqSBEwH`$5w=|u15wW4E7z02Ls;J!kbTc=k3mG@BX^bF@syXM
> @Y`4(>!
> zZ~R>zv*Ss=hv`#ewc)(M7Xvx4LvSu<?uwfe7vD$nnlFmV?jm+UD1E>c%@Cl1T
> {pJ#
> zoNk?B0lqoR5KbCotc==|V4cgEj|1x5#S$wt+?OzWoWVT$WjnR?6fQOPq~>M
> =%CHAB
> zj6Rfr`{@3@kXSzILjUPTz3`p}&rQV|5-
> k^X!N=^h^DeMY!Dw;exhlgO8Yb2V_|=2C
> zsl<0cy;V4-
> (TTe1)+x;tay$0Ay0FtLyNIUWa4cx8Bh}<Ms2|nnw`1HQ@=vLRv?tTz
> zpEa6R-W)<siKRrmBR7b@IC7VsF)wB&!BqV`cVTa47vjH^mYJA-
> c%PHfSkZQ0<mRny
> zSL)PRexW2g<%)PNPDyyVdBS^*BIj3yFWbK3^=UryCW=45k@oC(-
> xq#Eq+}dtc&9|Z
> z1^gb)y?m`g%2(BwTcb=s&~l;~H~szQ)_f&3o2yLKtmgXA9{A-I?KCXyvg-
> 0>xi>ph
> zYRl>aF1#<)I(|4MkzN!oQvW}HCrhv5)ym1xVF_f^u3)SQb0C;cfBrM~ax<hoj?2
> B2
> z*)5ftxxct`nL$bW4A0@HA=vOInE&WfH`kjP=}vCc7(mNQpl6sfJLYx;R6;|^zuG*
> G
> z*(OAvuP>H%7oneb2>NVb4ua+lAe--
> (NVHdPa=6w)u`mXUJ$1A1Qf#zkmSXO8#61$`
> zX9Rar<H#X2>NJgzG2okLmQnpZgRdARH-
> fDx%va{FRXCpCn7P}@_4np+^i*lYKABN8
> znvX2?6vk2+m#G<!wPI>AidW60I~lH;`aKQfC~9-Lwzj}kE_?Jc`1tAhJK}S1v-}>)
> zDS`BRj;ZGRdgAoVhzepSNslFo9$_TEHvQnZ6#YGl>OalnD!DS-SZR-
> }a|ut&qmt*j
> zP;OnWXl{hdb?W9hQ6nzKT(myJVF#Jrj5)UKHnp~YK7{Y0=!D{oNwgCb;lp`Q6i<
> w$
> z5w3*DZ8HmHdi<GjTO<x>dCBC+^mg+;^B6jpaa-g#f-
> 6orSGL!nz8$Vob(}|&T7blt
> z(V@gSZ-
> 4u?7g!GQ<@}K6g0eQG#DekX9v;^)!e6d~D1FX3K6zqWE+bDwTL*6nQ%=i%
> zGb`jUt>$$@l(x2D`rJ9;E*ozy@EbFmO|z<&BnZkMvFv7#FOQs3hqhTO%bttzm
> 7G^0
> zl^5RYuxW_>0H2C|T1a10{vKm+#En;Q^Dvt!V5UGRo>(zARL&RUFk(X9UGG+k
> ZoybZ
> zVP45ye%E_YYVwy~dAicFWAM%4xePz*eWgSsW%v1`4?{9OU6U8KVa}C#ryn
> LQ0&gaa
> z`Gzyq@P3i#<l=~J_MrS-
> 3fp%!TCMiMnD<vsPrqyWrfC>1Tkx*wcilX_<Q1=g<+59E
> zz4aB)8L)afHGLbbkS)KcBei`RcFAD8ES0(q(VXSew@o9Kg88zEiHSvv&e~Hh?=F`
> E
> zcFV%@sb&|VZz$E(*|A!yD5Mrcyba*K9uyDeaZAo!4=?C7Y}`2O%2!Z@C0Yf+y
> l)_x
> z-X0rF>}(hj*(vv7hiY})Kit`|a`jFqF|3z&Zqt_^2Hjn8n2&L<aQ7-aUs-o6d$oqc
> z#GV-G!H;PJEgrG1ZLw63uRpPs>=z^ZZ6-
> JdiR_mq@3kqmR$o%fm%)mu;i1H!Nlh*|
> zid@>zUfc$pOnSz$R<9MUiQE@lidH6L3|j-
> &q5N;O3Q!JGY&iLLmqhx2^4$_Ptc~B6
> zXR&FMKlZz6XWWyK9B}`18=mC`PE`Mubwv?;@W0^Hpu<%n@Ay-
> {nyjceuCrJ9JEZjC
> zPQS?c_?mEnq2x@!*54^wW^BE(?4cZg{l02+xtKEXqU?lQXc!1OwR%ywKj+)h
> m_R;Q
> zj~qp~+Mx~)(fYvha&~L<bMQR_Zpn_J=#6pE?u>oN45*MxX4j83_FwzwfE&R-
> t{LPn
> z=pX&I6&4(4`nyFn{{_R}r2M~mYHoivg`1WCH($-|&%}5BYgfK5eRI7|ywojV-
> c60a
> zd2{@k8l-
> #kJpXV0yt)0E_|2t1UZ2@|08?6mKa(Qg{O84Ljs^CDg~QLSw0@|?%72!p
> zdGpu|rf<6WowwZjuK#)4yWjJR``>%}`|kLqU%vCM|MmV49QfdeK79ADeB@
> W}x%Z>@
> z-T!MJ`}hOD{)yjs@RPs!sfT{+w?BRGGoSt3!=L}c?>zFmzxVrx{@{yWdh`#!{6~ks
> z^40(S*dPDNpFaM7{_JZ{{NMlg^&{VS^3R|8i@*Hl(ZBlZzj^vwfBSdO{QbB8|Fi
> $_
> zoqs&`-
> S7R=bN~GPA3XoVfBDxJUi{II)yW!6X>AZ?P6kt6?()Cf>7O+JXERvS8m|r3
> zyxiqCYZ7zA#msX!_oKdY+ft4R!xa$krBongaT)%HE!G&#Yn&^Y8yhAaYO|X3Rz
> A&X
> za0W_^e-
> cXWatE#9*tCmvG2m=yQ%buyD{Toi8|}$bQBSagdE^R9?vA%3m#s_g&mT<;
> z!&mZzR+~tC>()(^lbdJ>3+H?It#JDAbNH|qKh@W_DwkV@2mDffu*nI)l`81aa
> kWx+
> z+^}jq<HA*m-
> ne^(^?(GxRV+x7<DOQ%plRTOmRA0W>soor4&dfimUB#8;;PiOHAQ`=
> zOF#1J7U(O`B~1ldqys1--
> d+V7jL*2d2c~c%tX|0hL3$Oe&+vr1VwI}rhpS^n*L%TD
> zGW~>0Wg3h7W#VRPjLUcm;T6IugyH=&ZzW)_4vZ}jk<m3b_I%kNu69K3M|O
> TWcV>It
> zjkN@Cp<RQva;>);7k#e58S`@V1Ik_=KYdD{jNz{mNNEHo#gy)lJeZZPNuQR-
> <vyHg
> zFHk}>Zu$^;8+HD2V)>MQz}243iPJ$piW7zpelC1o%v4TO8zSG;x{kRYXn0Azd`8z
> w
> ztMVNWUFxgnZVkshL-|zDt)6na)QCatmU7FMJI^PVPoExd-
> JU!>zxM4mc=Gk{(~W9-
> zCr`h53^_Tz8hX*WHGQRqafmg*eGs!pn#8VoFZLS~EEIlGazK69F^nTjl!Sr<TCR
> FK
> zzRDcsWFJ0iFG0%Zk59G?k?Cim9fSM3qW_Rmn%qq>a!28PA0zL|aNPOWgS?2
> $n+fUb
> z>f~)w?gjZdF!FCK0Wq8fM9F%|c}uje&|vPUNs`}mezQfhKV=DJ-
> ^9*qu)O@HP@mKY
> zzA2*b+3cm$TFgf9LP}xeahQ|YDac-
> I2jXtTpQJvwn4(R?&hJd|So>Mf_hZc^pC*>%
> za=n*Blcuyoemh&2RJ52LZ@MPdiKn~Q`|=)d%6>dao3<6!>w59)W~TB^pdWC
> ~e7x!U
> z@g&_fo@}z=HPf6aU21CQY)8`N*@>JQiKgC}>c_-0<u!5r{xoyCvYUK-
> ?MlXNBaz##
> z&w7|&Ni%3u&h#NY>}ej%lpiy~9xwm>c)|zjU-
> ol!I>uX$V?4((<C;I>*<<dh80R_q
> z@pOtOu}qbBjeHwbJdf>zL}gziCo;nNxyY=-
> mtt~Nc@kA1V=%uUX8&HPI@UUFuC0pe
> z@h%rR-uv~i5uYm|QVm)_u~Nu6Z-
> NTSvCJ;+yH}xIYNG9WXf?%twtmixS8zPXTGsE5
> zg>x)ip){3&TIDhhZfd1AM1daXN?UdUN)Z{iTyYxDMHoOXy1UzMa5IHWF{dU<
> #a&1e
> zmg`|_x>V49yO04~!o}GjG=9S0E$-6(*&AHFW-
> `P~h|Hv`vstfZR2_w_BQMq6dA+!+
> z?sjwe>O>n(gEbB42`%z{$}PG#)ZGFzX#DCGEZVSmGVf9zN0+DJ=T_>7;)lspGC
> ESg
> z4~EJ?*u*J<hdPuM1{!B^y6K0Rgu+Z%c5lQ1U!bWqqt~Z~4${H;5`44hxCN)0DN
> JQ@
> zCFni$%I0S4fp=6mDw}rWD{i?CO|w}4ny^_YZ_TiXR(`XkLTPd=&t&{?6A;$2-
> p5LX
> z{1k#1I?yNy#gkIu)V>Q&x>e}7tz>S<7xE|=e#KH{x4R23ZN<HKu2K`X?>APu9%
> T!J
> z!wcE~qqmv*%vV@@Y!PsQ-v!;97TUZQ>U*#fFV!n-S6&#Dd!pt-
> wXBO)<@sf>NUtz^
> z;}y4<ooFOu-
> UD>JFkoaRXT=$F3oMkhQ|6BC(90p7Eq@f)_&53=H57aO&)}r5`TfiI
> zv+tPa>(IhjY33d0uZ?H4w*1(btC?=_Y+L3T8P4B;$~5m_g8wXiN!M4dUIR-
> S#Z&Be
> ztkhZs<>z@ls>}FQF|cG%@oXc$-(<OvAJ1buq2b5=?sa$LM;9=m8jJ-Eld7&D-
> 2`xl
> z#LJsi{S80ID-5DG{P@h@qMz+niT+{r+|P)6)N`NEZcIG}x4*Yj9n$Y{^$6S@Teqr*
> zwcDc}f*apDr0(|oZ}Z-39)486r&S6r>1>9}^j2#(rX20|swLWuE2Z5|_1qg6u17ts
> z-M6YE+TEcJX?IB7uidmdpxth@U%SI<+H=crlY^aVRJ(E2tKD9;S-
> V4O1>CMgOr5LU
> zxLT;)UiIAh^dC}B!)5wU!0ky7sl#yl2L{za&%H;x{pvQjsdT5R!A%SeshoB@Ra(2f
> zYKwLU)C%p!)ne^-DW%<{diM2<mrzHv+pQke?pAeByM5|@?e?oXwA-
> VmwHs3f?e0)J
> zwL7S`YIj(5X!mM$p?0^aC2)tfCDl1_S*}I&@9$O%wL7eo=RSX4H_q~7>KNSa&
> O!AI
> z-
> 1ydhb(HQ7<j?az?74^F_V;$FgK)QA(XAff`;K09zvmu+%lP{}cN%VLut)8IJGAWz
> zH34@=EU9+Fy#jpg_1?F5?<?S@(*ruc%+L9Fr+W@u=9BrSd(JuMopaXW4GYg
> %)V6TJ
> z!gCfcUi5}V{f)7-
> zcH4|Jiwm?aR03ANvFyRj_W0nO{8qV%r;Et8kaM&RRFVol)LA1
> zjUCkCyHxdK7F5ALA$9+YU5z&Q?L}_sUscz8Qhb!_5E+6Iy@HmT0F;rUv>Ml^{
> %ne4
> zfP{U!=Px^a1952J1dQx*Yew&ip(^qW5{}fk>Y}a2yw-
> K5ntUWA<xR+cN=WQR9L#;Z
> zXWmaRVJK;0ZW|as=F#MO1aZoG?ZADmmENvpuT`Qn=G?qJaG6&g&JH=Fqz
> |c^QvynN
> zacytz?Qk7ov|kB_PG4GUSR~{`q`+8yW9h*5G3B3WAAxjoCCoH-
> %eesU{!liLdnL5y
> zrttwEp~`tWIb+`w;VOp`e6~!6={LT-E$fi`8r**nn+c|M`##b_?0vYo#$SqE8Y7F!
> zyqomR?45QpXHTDYZ1(8Y*<9kYZOLA`?B1FbWS`#Hl%TGc>p_#Hd<*zio&$Z+i
> 8~v8
> z2^CF0%8nCnx9&nKf0M_5;WqO{Igx1ja;Yid3qy)r`BHFGFp>wh4XJ&~oo>`6lzw
> Z6
> zV!brSgCEqaW3H>ur$qj1uvEf1k7?(Wfuz(Vt<CVhDkrqk-hGT|^Sf)9W{ar}l*zO(
> zStT2JA@<~n29DBX%$M(DXc5D+4b#4v|DcZv$#wJcMmRGv1nmZKOgDE^4a
> H!{PRL;P
> zW0g9nt_BBZ3+>w;nmsJO@3;*o_KW5c+O}UL+CmI3D1&8kPky|-
> <u>~$=BpLXTN$f;
> zbIUR)r^}eU4=plvMw6&sDxoKYHH?LC{nCzFFpOyl%{2YJ?Pi=W8_azRDTV0zv)
> _H%
> zwr^PLCTjy{m5?gmiP1QR|5Iqy{3f#BRPioyzSI)Q6Q7-
> WmwjftX06k+^|qOQYQDcx
> z;%1&npY=nTa`DtFSUY0V+LwqlJ7}gq_kdge4QG}+Di1#A*-ri2>$Beo_i39RN=ZY%
> zNBXpa`8Ipa(fQ;k<c~p7cd<?T3(DjhKFR&<ELyFt{jQnM?5lEu5R^X;`U=%>Seut3
> zdv3m<GVY$*_GLzKemVD|4y%}%adshm7{gXtrU0uWqK;A>+m=xDbN6H+6+
> jJ@N<Dgc
> zw_1HgLX93sDBO&js?@St7J*+2wqEKymYvR^9zQ9kaD-
> CqHmAbAKL5iQrQ!qqJ^dGI
> zcVIYuVWS;}X_}InlnhPY&y%#pN32iza`x@o>L^cKM6YQWzeeNzIcOL!@rj=)zM
> OCQ
> zZGmGEwIl{xcQeoIFS40)Ny&*ZWen0~UYh9&XZ?1-
> n=f)U$XSPAWwu32BAm&IwhZ=4
> z(O1TBK@9UN^2WRq&$~U;9Kssl4Ak7WbTAh3B!lga=WX(ZmwAi7Hw-<J-
> mHRDIo^b=
> zw#um^*GxvXf;sYa94GK?Z*9AkG;Io;QQD=EyD4F6%m>>K?{C=oHuDrIg{cS1S
> o@rd
> zss&Src0JG{FEtekt?(RL-iN@w8xVpeehX6J_r(q`-)Z(q>F0vu=_F58_@k9=S>eg|
> z&we-gH)FhvOJ-
> $oddDS`iajp*cQnQRxc~0A`D}Ia=saCA`L_U$^NKrv+IV$s=~mNs
> zCDeYn>isf)4a+Ux!1#6#@P{zAaeR9g&*cxwb4Lss8a^b?GOs7cC4E}PG`~};_ky!
> O
> z&L!-
> XylFE<v_r!!oP}UKFE{!yYfy4k*1HkRE7#R*S=74Q+!n**fum=doTYQc!B+NW
> z?PKKEMDGXJ>w=?3ak=*)YkIaFu8Ek#jBckgnq2IyXt+MKX_pb7vL?gGV-
> 9(iu}Io+
> zbDEnl>!Ljv3B?%}Z!d7)cJ5)N1fpkwW1oBjojB~f6)^ZXqK4V&<>#<exd^nKcmX
> Ep
> zoUM7cLdmziPM2HFR`O*Jt(;Dp$dW*@N+q)wk!(LdIE)24IBiVtExREiqx}5hJcK
> Ht
> zvoN!z4T0g%q>{TxjpCF5I+b(Il)k3~V_fCE+W43;G>7A|ikI0@FU-
> ^!^E6XP+^w1m
> zz1&_L2q8;2zM)yP9IS|W=Iv;(j_gsRCJcoX^Vsmd!G+~J!H&8UCfl=S$qGAT#>4!
> u
> z@?>!W`D)^uZ=25!I9e{i03VHyp?GWq*Ieslaj6T|<fMFIyoDVtO&0Uo#2i$9v)&
> B_
> zwi_H4UUMz-
> A$2=7u5HQ%YOaw?FbwK^FrDrpZxdV9XgycM@fQRoi#VwOu8BJhGRoqi
> z;df-At#Fa-
> v+y)?XX@N$8`_U&Y7eKBK8q$ZW$?kYt(h`m!bE0(WpA|4=nRZj(Pc6f
> zVL3QsHBPTxy5kv|bF@p~v#LQ~S6Nhi$-
> JLEmWyX@tOVvS&}Y5QN`J`dx}|XmGle`B
> zP-jzPy7uWg>a_$uzwJ_`_5t1m*u42tb=hT?s%3ay1!x0Y40sD*-
> #&zS6I{jtyaTWt
> z!{iFMh=MU5@!@WUy9}@j(018dFdGF8J`?coV!XUX<8XJlEW-
> v~72D|rh<_>I0=#bq
> zq02zjYtOnZGu+4sj35^ByNWm%8ySJQOt1r@zIZOzDjQ%CVg%MPS!5k{9O~lb
> Wn`o_
> zk!O7YF){*Mj*T$o484VRHs@xs^EAT2E4Q3}=WN1R2;ljR-
> RfDuQNR;`!+=A8gMbGB
> zU;PlyYSwkD#{rK3?gmT)?g8!q;OGNMbr;+_0Q&*A0d4_I18RUWpa7Tv<N%|9
> oq($V
> zX+R3l3)l+i0&D?n26O<{0agQ60G0zT1UP{60p|ji02Twz0W1P61Sr4@9Vi#zS-
> ?@i
> z5x`@BgMbGBcL8dEG+-TI3E;U)P)5K(z#V`xU@Kq+;C#TjfW-
> g>cxnT91vm_N7;raW
> zA0Q1_0ayq)vL5^b901e+TLI?-6o5R9Z=?1Wr8aF+itTk2fYWjcEwr(jvt7~tZ2{kh
> zwlYKoCNX|i+SEk|Jenz%ihCzZ^(w5RPP*6x&*}kn6y6fKIVQ-
> V|1=R)Q>8pkVwLJ2
> z?(L=P?m;p|XK8$?qpqn<Kyk~p$RXu8C?g<wh7H;pzL;(fuMl0ILKZc`3|kEEeQ^C
> W
> z%_leqdz#Lq7KyjU6<9efpx2;3n><E^x5pb30ci!t3x8N?5M`K5?mC?7mnuJx=P9
> @x
> zTkU6e58lu(0XKrjH(ms}BD|14^qVT7CPdspt=Q}q3i)z1U%gDNSh;c~(8}^soMx1
> E
> zV?JU<(pg71e9h3sp^t&4EcBC7!~IwE4{V23sgd0q);ZAik%dLz5!j^}$ro$wYdT0@
> zKkIP-ersWsL*q7xix6X_lJ4ud5-JK4w*t=8K}u=!opAXMM<KSVPCys~&rF7XE-
> r33
> zd@lj(R>o;H7q58F>Is^D_MYU6#r$Lc0-;7d)jp1!t=7ReP=GJW$u#i9H0Ytrj|amN
> z?N`We+Jw9P9O5{>X8E4sL~pZt^EFES{5W`iBWNM;&vV{`Ft=gdkcuZ8@HpP5F
> H5RB
> z01pAq??nH-9M6DbfC;=G+Ja|*6HBUte204!pgQ4q`Q;=Fo!BS-
> b8hU$21>X3Zy+%^
> z)HRg8EA{=S*MB(n-
> nIP?Jo14J^?C4*Z`wJyG48^kcDe!uoPDJ+G^UYKW!Fwla?_~2
> z>dwx5aVN}utX;FSb9@puQ&*OAW8qvKyd7f;_KeJLJ|3RI`*VQBT#MnyFiexb
> ALB=N
> z3xM&S0M7hu+zKx)ag4he?}nZUPxl4HzbX`V0`Fzdk9hO5>DzILXFlvS>38n?F#c
> M!
> zS++;<{y4zog<+z~X2&C~bqJ@>Hq4K-
> 7UTVVfT6`OQMBxMjGsohUW*pj!aMO^2+?CW
> zro*3Ib~`R{w;<fz7Cq+SLA)RI{D?O{n~oia_`4DAX^Rfieva>G<AxT)M3vEwM_LC
> F
> zZZ+bWA8BpDd#^={VWMc+@fiOxgxeRQwIA;XELsc`MazyyTF)Td;SjAOcz@c
> W#V}E{
> z7_a>4dFrt*&r=f%7pg6nEL77S3)MvOmFfWCFyMKB)BQ@d6~N!(A8t8r&=K)(
> 3*sIx
> zn7BVeMf3S_&o%G=cx;OfV%`sh@Mk?2#2*gffB4Tq{G%cK-
> @O>bKM}$|{^KA%oWI{V
> zE2j7}`8yJdUs@EzKNiBLe=>*<r=MFK#D~kj>c0o^VfwecE{G53|H1z;Grs@4AU;
> h0
> zE9VFCVfr0!oEd*{dk`P4zt49B@nQP!yKH9smGK}x%-
> @CGGvn`>1^=e4Gspj82>)QH
> z{_lBPFn+jwUb`!Z57+;(>w@@)Ec&mk#MA`<yM5kc;pzW{dxQ9J`nUf^5Ff6e8
> $K7r
> zhxz;0pAX{0?dP{25j^v9E1pe13fJ@NzZ|3!&PU>#LHr|DIX`+dralJX&(OE=Py9_x
> z9Rb+*aQe4A8^njpdCxxt@nJsx#P@>uFdv@!K@cCV=kb3D;=}p-
> ^ov1!IDen|Q4k-F
> z|IiydXDt6WR|N54{_kAXslf6dk0z69DfY?dfm)%*|DI~%-aq0@J%sb|rptrrgvZlL
> zY-W6>Gl&n<|J_6oAFikVt%7G(H+B2ZulM{-
> zQg=|O(sY;T)%~EXQRyDu%5%|KXQGL
> zPMFW1e8<fA7jF;Zb5=k2<cB)drvdz#a)jwWcdyjr9acTAgPdp7kM+npKV*d+og
> pk~
> zm~<bq@<so*d^(t~aJ?lz6U2x4`x9RZ;=}dxg-
> 2(`zxI!U_;CMw{IMWDTyH=9r$Kx;
> z|Mh<qJj>dHXTyhZ`yRS1&LA!EkB0CELwrni2IGhM@S9yhd^rA!9YK7U&wsu%
> h!5A}
> zdq#rzFdx6LFNn9tVU~N}wBVoi%5~ePWL{|a^@hI^Ji~tan{j2r?fZpbxZ!X6;ST>
> @
> zyur_hEq+~eEUsbz{tW$afB4t$`E>64u1_ai|KI&VkWRS%fA)t#d^nvu|22rW>3
> @Ae
> zm-;Ti&S$t@zp<h<zI#=d>I1Zj{~~Y;RtNER`iwVrcMxy4i^NB|R2|TYKK-3v4dTP)
> zFW(!)huh7^K0h=5`QPi(W6?2dEP8gJ^|)o~J6z7EzY$C)T#w&cp3vo744D=Faw
> %E!
> zmf`LP@W=fJ{?OF)n&uolk9y(F{)3G>hV$cA`MG95(zzIJ2f&28$7;t+D>*3Py01*
> A
> zG{A(j^M7zSp}qj%FAD!9$me_oVB_ua>FwJSY9F8#{@vFm)cXOg@UMPbLY)U
> _g?|rl
> zAD99Ex{-u>BVdcBApd$t6AeBao*Fd2PlP9~?ACLV`FMUB&-
> 8l^uKlAQe}*r1`=<ZT
> z+$ia6>GtP0y@Np-496d789L#9I`QFP`R)2)+;@LGh!5xE;$IKq!|^wNB8U&if6aqI
> zd^rA}h45E}+S#vvG8jLMKkrisb@$L&EQ<a;wG+=N*;_Dv#_bwDOQiuhKn-
> vk;BLT!
> zfJXsO0lp1*0kCM>S?XNCg@6r!6kr@M1-J!p7vKTFBY-1-
> ?*q=>jyQk|0UH2afE|D`
> zU?1Riz()X|1$-Is6yV!{=K-(0>MXSca3NqbAPtxROaZ0=`vC_4p8z}zcogtwfM)>T
> z1I)krEcH6TQouUE7C;Ix2B-nv1^5Wyvw+6{PXdks&famBIuEc8&<hv`Oandy_-()!
> z0Y?De0sIK?+H1~ID*=}QdI4jA3gBkIU4V}P9tM0B@D$)#z<kunxq#(>%K&M>b
> %1?<
> z{eX`E9s+z3z@IaJtD7ksHK$6go!?XK%;W~$OfFT!4*J{Yc@~@#l?tw0sw-
> 5Sw^iMS
> z0@N7x#Th19FBDRl+C)E2ZQwUVzb+i0xD;H7sRPiSiv9PH0$io8oZstaroxJGm3k
> +%
> z5Aj%?I`d;{F{we?0*CWC>fVp3*XevGE3T{5-xIsdtyHmXPmQUIH7-
> W!M0Fo=o&{}|
> zRH?7hM?~4vF!3F$G6_DZcM#K8%GC=xS(XH9nD1M#9XE5`I8L-
> n1$c}zl#YXfsn2U_
> zwcJ+ZjAs*XTad;LP23Buxn8Q+vSgTey@D&3CM&AAV7Lf70f>`J7?DX31&g2;X
> #upw
> zwnT444RyI=^<B8qnZjWzh{85ToC;;VOniO*V68A*gh}z7`uP08Oup(i(xByR9lI0N
> zi2Ip$E!dvVxiDE!NtgO??w#-
> 4TXR)?e&ab^G6B?M3ko<QDY!+{?>#INOBl=LkO_$C
> z56<r`Wl%e~0$bUO5I1=>7_Ra|Dv4vVLaba)KsY3(ZX~53*Ae?XU5A6N)Z!BT*2
> R<K
> z(q8pi{U+@YEoH$r5h>7(;U@DY5!H(MJ#2Sq3fH^2o?^D5Wj1gQZu>(4mGS=tK
> R3cn
> z<mK~<IW^V!B5kkp8kM?}VFwa@d|t@sc#4+T)#a!m-
> J{~T^qhhej&c{I3snTrT7FfQ
> zZ(jb!`HbooOj1*kmXg-
> ;JUuzgLl{PvZaG^9?WudcG0_xWsn5)3=Vb%MML>q<V@i&{
> zl)7J9vqmq~v87$J3~Q}-R0!f<$oRqsPf7LX7-
> p!J!HwrK3ma2gtUTDG!r6@LwR+qC
> zZ4A%!V>QSDjMZ^pA3PrN#ubfFaf_zMcQE3<`C3(S3deXQ-
> h$4eQ$lk#y398jKAq2A
> z@8$CQ(Cy{AmcHg8ErEfAh8eOMp?=UJ#&)$mItE6Dzm`-d-
> 5t=9OlBZcBKrKD`7FD~
> zS#%j;A?$3~eFPNVJAa^FgHbNsBPEaE#qG_$2zv?nIpmKt-%-
> gzy*fdLb=JqnG5jg@
> zMzm@pP8IHVx0#-
> ynW)tBy2M_8Rd2TY14fI9OcCw2YkqIMFH>&hEMdPRPhTJh1S`Y5
> z`rV)p!W=bRN^1U~eBJcv!U);$snMsG(rlWK2op1XNPN|&@cpPy%CIe7Y&Czw
> c*C&%
> z*CkRrz40DQ@jn<Cv14jILwU6!{AO$4L0@)k-
> Agf&=~3*C1=}<E8ZtHniJgKgf_;#z
> zl+ng(i%5AfYa>z24UFrqr0T&Epxm1j#RD@Hx52%i3;H0;PYIQVTJdeT$)3R(cT8Q
> 8
> z80=5<`nurFyy}d5h686fARK@s0ebcLN{EnR5sow7m1|cMvl!1JW#D+TLYe|Q8?
> woe
> zXTw*m4Z$m8SXXabhOevdF01ZLLy8Evi#6=|*8csMzUTab53YZA=GHH@eeIz?
> e*FvW
> zH-
> 4h$&g<?Uef6(A{?0_QXJjZ5PxlP;kHiQ1QiD(yfM;d<cMtb;jda1MKcP1tY+Nb<
> zVHf-
> Yem(KPdpZ%scU_eLxm4n+P`qu4!KSpS$A6@!Kb;s%#^ND5%x^5+)7jJ8lfJrr
> zLm<s$&tTtn*fSW}HqblVml)~ki*+M<Fw9^gksKK88yOnzOkbT!jIf}gFoUt}fjFr|
> zPh{SQ`uZCFAfbQLsKWz*6ZsuPyu*MafM-Y}135UrYCtcb47dxx-
> ~DhO0k95|+eVT-
> zy$M|$lXu$>`!Kr9j28}%b}&2$R-z&3-I_3-W%p1`aapIWaER9zm0s6i530O5AE?((
> zwzUyP95JDq!^Kjm-kvyGfY)B_a-u$(@;FnQu;Vt;*Oht|n@tlfqD*;-?;V5eBw!!l
> zZotEUCjid^7G@z!1K0}K3AhFD005Px#hSu>c+iD5nMxKydwuRC>~lcOx_A+kE
> 4k*j
> z8e~xay@ly^i}6ZU#sV`2Evt(0!q%?SmUG%l&eCPorTQQ39&#>%m!YL+ldnFlo
> &EL6
> zWx2Lxt2?g3zjcj&Ypz<hdJW&?A?&vGx>IgJ50bkvCPL;}n^g4Z?qnKTtX${8<kx9)
> z5sF!(&o!CGEdN>uxnjQ<OvErI_6)^3d(lwiv6OSElO7yS1n`OeD6}7cC>=`=4_PsV
> z_I7kajF6GUnYQ4giTn6w;>7h1#IFctSLa9jH%HO9p>$9DimN4AJF}$Mm*^W9y
> n3V$
> zeKFBxA&E;2#)c9jse#@YM-?F3$sLP-
> 5t(5;&D$0kB3{bh965w*D$QJIC%1L38Hx4w
> zbociq`qLxrR*^I>Lijba;MdK9@0bPOzQGE>{D;zCYiA$=4|&yKy9~vL^r{~qBL157
> zRt6&Q>)WjiMBv-
> 6@X1H=Zx;NzS@0dR;M+G?0V49ZcFoNA4R!`1;)8z{0k3U`cnluS
> z8U}ovHB5WoEWDfrzit+M$1M2v4OV~%UaVa+Gk$}efr$9vrA446FJ}z{Ud|e(y
> ?Yj3
> z+W2cq`Zjo#gFo}#DPvR5j)Vg$tM@G1<Bx0o!+nAu3gWIA$7hWcbipx08|jbrB
> @i8-
> z84ijqys=MLgrPO3t*XCAS^n2g@@2w4L;zoLQiB6=PT~8zF^pb0+%t$#xosDt_}{
> ZY
> z9N#-g%kobZTwbcHmfdWA9J=o&@QnKf6foyi2xm9-4C=dJjz_u%dFho9-
> |lPBZ1ZC1
> zJ2Vc4HH&^nwj=AVzoetBBeOQwwr;#V+qQAz+VyQ68#lCftjDAxms<-
> KkydibY0KMj
> zoBW)%w&WDIy}RqU8K6JtUYKzmPxC@P?DQYUSH7kZLe@enuD4o;*<+>$vx
> JkHA}xQO
> z!N~^aHfIBtRaYXHmC0Pb;;b5SR$VF6A(WSR&R6u*#Cyl|XAh@8jel$QV8+8Yc?
> i4Y
> z8`p_u9+ky@4*fV6N@3}j#)1cK|3H62W!9n#uFjweI@;Z~b?svt+BU9tJKEaUTr
> $2c
> zyRl>4C6{b;(mk>M0VfURi6!n0$-X(3Cnpitb=SG;J2rN-t=-tZu5I0#^&8tZ<~F!(
> zx$Grlxl1;#TfH_r?)2{Hi#feFOlJI4Pc+_mwtXy{8(ZCWNp5X>+q#XJOxwn_8!~N
> ~
> zbsJW%&TY))R(Gs*;)8K~Tv7cptv!)A-Uc`BTtJsg?P7&}JEt^`8;vr(U%_iOoZe>|
> zIw+iR+&yq}7sz;$?CVRju8w!g%kd<+4R=e%t7vmlM_4kbUFZ>X;fLOcdmH#i;9
> kKJ
> zCWK#Na1dJWd>3nID4^(8#_dXU4s+FMTr@?_$=Ap~hfkXt{}9d?Fkil`j$3<dhq
> #b~
> z46<YTetvok4=U^GR$PWPbXYcyfOPr4j!QrJ+FpIp%E7VDuG)mY-
> |ptBj=n8}TYC-^
> z#bIyRscH?HXsczYxD=%yjw?rk3Ok|0LW*O@@;B?@3>SfR!+f2?%U6z_QZx-
> sYt`<I
> zzOL%v<`wSR6!Md}Jxq-
> vuI7C*IppwDAcVa!%3t7(<1hd<ggZaXmxHZWD(Q5R+noGl
> z2AkRH)W+vpi<{o^5o;_ny<E&K4<|+=50zXnOX-
> ;Mu*?m=ZMYehfv#QD*e;wx;y!W&
> zE<537udmi8!4nMPO+2;f8J>Go{g}rQ*NQY-dgJ*$XgQ{2rYt@Ij>idIzqpCYtIhh8
> znlIuIMVEuT5IoK|b2H&h``{<}MB=xmzdJIIP%v#}Qu4T)_F%m-1o0{M05<V-
> Nlte{
> z-
> 6|s;3k?B=Yw+vw+C<|zCH#)}d&hC%RHQo_4bxWbp`}Isxi>NA?F#bYc+1Q<t8n
> od
> zSMt;fM=4A#G+YapW9LG+DQJA4E>2h5;q`4UQ`41bM(KoplyUq~bIn}B8_Uwv
> vtgcl
> zpwl9wsAr77+0!)fNFxE=8sjGrFRr!g&<+K)F&T;}P@~2j(RU&IIllZDO8<V#)T%r~
> z;6)ZC7Y#=EUcTyVbt(Vh2l0UtggCM_hnwAcYI(K;B_QG_hnddOJ>IX4Zs?!EEp7
> By
> zSspo!etaVB_oc{JD}MQXz|{F%+HSDFu>ZaBxY~T{G{W`AdZQ&|>P4(T?~Tc&(
> Ocx_
> zKPptS?whDkhE^0Vx`&?{x^wBh%_+^yk5*-
> n5vG}1RQTEWVQA4_hZ9*l(OjFYE~D~7
> zN^|4W@#iKgJyZ5pd7XQHL^EDg8l+)H{CP--
> va!Z}@gM%;kC`@q{eQdVcYf=qf4|H5
> zlALwXoyUOYx7a-R?tDDjL41rn5l=YtJHvtF<v_Sy#W1Jhtcn`)<a<jSUScVpTFo~p
> z2YPA5_To4~P%D`4Q_yo1@yRKEpqEsVYB69DfIp`9I)G`j3%qB}>COeb0`O`8C75
> 3Y
> zI14~|{zaZkKfaSTanyleaHPw)bbk`SG}xW!_Zq-!J)r*u0Q#>7@IB_e^HvDoQvk-
> {
> z-
> T}i6c`gKmH2tgLGVOxrKMB_Xa5L(B0Oy>{E6c(BOaqwbn>_bsxWvB`K>RHLrt?d
> H
> zHv>N6z26I$`MDp!^ga$?xX%HYzdr#G|8)TI=YlEZkKx&pcY*hSr*BQ_x>#~&QY
> {3`
> zLzpm}`~IYQ{;s4t0=NfI1Ec}w$MF0aSKj>h+5B7KThTG$XLC*bm(zXW!%6iV;3#1
> 8
> zJHfy2L*^M7y2t5!39_}g<xdiKTK-
> ;w%)JCjv^Ih*iMKYw{1RmDB}$@Y6JRsMuVoW(
> zH2OcwzyIJ(;oNs(J~)5jqWke-
> 9KCt(%@=s}^09Bq!@a*I?oGdX^aVa`dB?PNA3*p&
> zxbMmP96>kzzv)NfwZ(HkGso~TFZ^c_{!c&p^heKA-
> }>k?ALY(W@YkUKj(c^CEAb(}
> z^2xV7>8Oz>uX}P$FfiV3`r47dJo-
> bW+TS5DAADuEzQYywLYgtZDdI_bY`LvFK;dNH
> zna^-ukG<DV<AH^caeGy_dgyGp@ZXB`8J;fdn(GAq0-5>`_%d&n-~7;Tf%h{-
> B@d?c
> zj*js;K6lB(u)PFW2zcRh{`>~b@DS%k{JjCsoM-a)e(U+Yc;+0EzuT?n_gT+(SkIWF
> zHNyY0^?axGjP9c6r+eVCSe&DEd=+ysxaYv--0$dDk{Y)aE(huJ;c`y*?BS%Is~(2?
> zQ+U4{F6YKMxKxO|8SZ&-7s7o#+{gY1ddT435BF!_-
> U9b$;W}^~xX*k!sV;zf><@95
> z67GRVlelq&aB%m+t-
> *y^H<g3S!DJLJ8)S;E)i&+t>9Vx@W8amwn;Ozbdx&*nzf{-B
> z#ee=6p~G>%^sQJGw-
> 5Ajz8pXDtZjvysPLhH%WBTD+}V1b_QHXrdhl1IoU9|Z4+6_-
> zes+m$oz(PanAFAu^h(YS4Bx9DD~U1T6BzIKOaBD)%K>@;TLE2wEr88{b$}Is3jy
> Z>
> z&H*e0JpXFwUjrNiJPUXR@HF5k;3>cnz!QMS0gnL=0}cTW0v-
> h14`BGa0e1oR1Ev9c
> z00qD(U?<=zKrf&JumbQZFvg5^tKZuVef4OoaGyUkJN$z8JBIM2!MJqEbAtJipK
> QZF
> z2iO5%JN*FQGk_-
> m{{(mqBCZDX1113`4i!goUA7y5{;duIz6SUnU@^k20`vh20Q1||
> zhO(}ax>$L6Y};5SH^S3REg`c7`c1cN3E;yx-a96Q=}?daDig;`h#$r=jVvyVdE^81
> ziDTS+&S0VY&C1`%2$XJ)RBE;SNNMak?0fscbdkbob@BMO9~Z|$<)EHK&pSZB
> Y$5D)
> z%QhjTWaBgn_s?qesv&9Ed&WJ(fioO9!+|p#IKzQ695};)GaNX>fioO9!+|p#IKz
> Q6
> K9QaSjfqw%w5I}YS
> 
> literal 0
> HcmV?d00001
> 
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env
> b/Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env
> new file mode 100644
> index 0000000000..85313dfbd7
> --- /dev/null
> +++ b/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
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env
> b/Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env
> new file mode 100644
> index 0000000000..4af249dc19
> --- /dev/null
> +++ b/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
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64D.env
> b/Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64D.env
> new file mode 100644
> index 0000000000..a2173b7e44
> --- /dev/null
> +++ b/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
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64R.env
> b/Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64R.env
> new file mode 100644
> index 0000000000..c235177e1b
> --- /dev/null
> +++ b/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
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/BootScriptSaveDxe.i
> nf
> b/Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/BootScriptSaveDxe.i
> nf
> new file mode 100644
> index 0000000000..d2fa621096
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/BootScriptSaveDxe.i
> nf
> @@ -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
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/InternalBootScriptS
> ave.h
> b/Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/InternalBootScriptS
> ave.h
> new file mode 100644
> index 0000000000..f232281e2b
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/InternalBootScriptS
> ave.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_
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/ScriptSave.c
> b/Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/ScriptSave.c
> new file mode 100644
> index 0000000000..837a8c95cd
> --- /dev/null
> +++ b/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
> +                  );
> +
> +}
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.bat
> b/Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.bat
> new file mode 100644
> index 0000000000..887206703a
> --- /dev/null
> +++ b/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_Fla
> gs%  %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
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.sh
> b/Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.sh
> new file mode 100644
> index 0000000000..4a11a1cba9
> --- /dev/null
> +++ b/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
> ==========================================================
> ============
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FCE.exe
> b/Platform/Intel/Vlv2TbltDevicePkg/FCE.exe
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..18300115d08320c40843a8c6ff
> 69e37db83d6a5e
> GIT binary patch
> literal 632832
> zcmeFa3w%`7wLd;dCNSXO1PvNB+Eh_dsYS8Af;B`&17+;Y$oQzXf<inXB83@5O
> B9$y
> zGdWC!7J7ZqiWOViV&zs0!6FS530iEUVvW6N8*Q{_oZK2U%1BfBf4^(*b7lqtKJ
> NY8
> z`}_YsKU*^Ato>Sh?X}lyKThBq%Uwk-
> m&=WR`}Vn9E%@bsRr2@He>#wS_!pi&+_hoI
> z3twz0nEb*Qrx-KmSInJv>rL~f-
> BNMmv^jHbjaJ++qhelcPQ}bQ6%)RGMa3<*PM>k+
> zuwg?->Z&h$>G5>YlfP}T|BZ~bw7BGbTgx2$Zt0K6`|+<|)-
> oRN$G?7M%SrNE)zT`z
> z;g&-
> DhG*VrunrsJpx@=1Tu|hy`@=UPHmu84RB%|q5SMG)V3+Ing$g_iza@C=0*t-
> p
> zGeE`o;eYn8YyD6~B)~wg#gdVESwMcB9|B#yUm4;WB~PF5=Z(Rx@<U`<c;XO
> ZmHiKR
> zwiIMv_kTJwI%8oJz)h{_5AkAOIk-
> 9hRk&PJ&zv`XT6CJrwc&bH#=cL*?+(%+`(G6Z
> za;D1Ws=o#4RiNEcq@RM{od2p^uGXB_|M&R+BML;!o=}^=e;5AqZ7iM}nB;0`j
> h*b<
> z81OVa7d^h#jCg7jBi8sQxoRI~Vr{&&p!N|yrLROWb~HW24D`ph79;}wzKtW8b
> U~zl
> z{?Vo%uU<ck`Zh*9mCwft(<h~O16*qcP^n6)HKjytd|Lt9VPW&lZ~m6p=>LFUy
> vK{S
> z`Uq(AXVi}%Z2CREjh=X_uoi722eBFZQf(rVK}x)}FyZ%%eGX}vbU85VTuDs)ndIa
> W
> z7RZ>9KD3&M^bv>-_g8MMs|Knl+-C;7X3SG-
> mL64`m@?iA%CK}0xlqiLoG`R7Xa@Ss
> zh&NgPJSR`kI;Xe572obn{{ZlKssKrerixQtF2T|DEhJU;Sa-c&FmV3{?B3Yc+JwI!
> z#7eL!AX^AzK><y4e+FZb@Mnl?BvZM9t=;xDK^{nYYt6}%ytN6BQ_}8)$v!xU1K
> p5y
> z+dG21CQ?zP4-KV%gsRT)W26KJa6*4=VmN5kuln-
> jdk6G|LnGrg`l@8z?oEdQ(H6qq
> z|Ap#`9wOa^Hh&L$(&q0~Kb`8Qi$AkmMi&T<zQ?zggshu3x=37Kb9=)}v7s#^A
> b(R&
> zLLM0|`~ii7M#uLjxvcg7kZzD-
> !#Y?T%xhNPQ2Pi64^Uro$Q$1~*w;WUkwe`MGty!D
> zJItmvfFIVl7Jp+UZT?PF4)nV4*OeZD%FLx}@R;y-noZ1;2y_W>xd8jjrj-KBq>lj2
> ziz1z-KXatN3#61m!YJ-GBjEo`<<iy2c-y)24mSzvt6Xs(-shh}+G02o-e(tb9z-&U
> z(q|Xpsg`qw^A01CUhDLu*w?_8ZPMlv6M2?w-
> HF7Ib=@VTi96x9%!m~Rt%?Z;zfK?=
> zB-z>UT<mK|i@)toM7k9Y-
> Dao+jSCtROM#F=0~{dpG}3SSEldEXkyE7+4;o3|j~Udz
> zWUmDsxoEJAR2r;^4m{E_dlHbnKE8c4W<m_pMP|D2izk0xYX;%KTC1xy{vb_%
> 2=oqH
> zx2x8C&8-ksw^I0|+?dbN$sn0;<I)M32f<kw?~J*k2G3!u<z2-
> W{tQG9=0puAjOi~)
> zEalua1Eq<kZazdZZA&?e_#aSa4@1`11OfD|KXu2xefvN&px=xMqXd<bPXo^1
> +-|%w
> z{(x@$N>wb~@HLPnoUTYmsv&j)-
> pZ}9*?0vPab`CX;mSZs>}v3hxs+H}`b%Szq_adF
> z;{y&$EEmy33dn<WysS1cIVe4sPKp>PPpsT3G>BB-
> Nr+(g`wGEW`aMzlO#!wAGb~>~
> zOaITueBZh0aCAY>cdZ(nnJ%K)ndzEUEz-Ho->rVS_#@2R+2-
> G^U>)kGUH$Ch55`1f
> zw>NApsd8v4NP9!pw-
> nM!P>jbI#x1hGuX&hz6*Sv((K2wluX*X|Bvs~=7*togsIGR1
> zH_Q%i(7IM?Wxvyp2?HFPZAS8dDfg&6GI@Lr?G!?hewjcPW=5@9111Y}qA622
> EaBg6
> z3Wp^E9c_NqjYuYJwO*_{z_A6lWkS{u?V2I!d<_?hc<Yl+bejRp&JdWw-
> &xu2YZ%0|
> zKzAar(~Rs??Ns`A`x^csMA~Vt5ax(<_!=l!(Y1uX*9`QAtVwpOJ!Yf_eeMlfr`oMT
> z82B32F@K~-`qO3lyW%ZXAeSq87n+N2QqS|vNSC>k&%nFeT*0TX^-
> u*n<iWJO0_BRw
> z=;S3^`4qC2-
> )kqIV^Y+pscJ%us)=g)yUj*U*^t$sL^*02Vn%j}p5A5pd(aqq(DGHO
> zC*ki&T>#d^R6sW}L2Hc-
> ?@RsSW55HuDg*7Yax+o_3DjAeD8y8U2u=)#uuqJ4uP;a+
> z>j;(UcG>>a2$VgWg6e#5{H}C9#~*UO_k&EdhroAK&D7ms46T|c0t|p}qZkx^Z
> )JPz
> z95fG+27`qvo@PhJR1>l?QW87LfvBM@jk(WmO}o=;))!>wpx`r7rX3Vh0{X_^4
> UPwG
> zFy0A2bq^46G_OoH2v(#+6ea?q6|D0v(u@efPO)c&tWre}nMuBe=iOu>HJgBC
> pRaj^
> zOrgD}M2`fPzUD@G{b;1G;T~l5HII<__L8suB*ntn95HB8PBklN^^Viy*q^>9uTl_
> 3
> zDjfx0z@$AzgxwUp#JdV&Wopc<u(jSPpPB$Z@HP9(8(O0$qbgV{CAEo=S14GT
> 5V2`S
> z$`Z>-$<)0VrFdOMaqL3VUxx0MhM=@cfKy-
> 4D#zf*x0lG&jvniv>d!Xy8git+&hpWT
> z#9GbC5)9{wc$InIY0t;f7<7E6Jr~O$er)>oRoZ<|HIi3h-#sl;%eHT>fd<tQb5?<I
> zH9BuC&ge3|@w#4D>}aF>s);V^`4439lvQ*RN=asRMkdRHZ!*~{{jD$~y_gChO
> |=(^
> zW~4N+Ld3tnEU`qSf1r2AlGD%@1VC?_%x|*vtU?m9k@!J=luLWy@SydNJ%S
> N3CnPhZ
> ziIx_??tEf5Iv2YJIM$$%78l5D*LnAGc0FxNDFCEVXfjZ@k@`Gj)#tRt9MY0xMN3
> oI
> z(zZUqOVQyt)sk=H3Kr+kYRLjrO=%)%E$L<f5@N~L$<oM|FOVuQ7)!Ph61I+q2
> p01R
> z_Cf{(?X$D?NdoLA5!81HmuHlq)+Xbuf>~wO3m>vPrdwCMu8Tu9m#7|{i|SmI
> odu@u
> zhIP{ww$gu7Soyo!s=TBF<YU|T5_yVrwN;l2Z7?9+P%|NG^Ra@UjK);e7^=bea
> ?Fqg
> z*7N;2SuV=SQlhhzhO7lSS&q%gQcCf^(CdmG0W9LTm$;%3$6fI|O4*fV?8;=gG
> $4?o
> z`lCcwAx8aB4RyNi7$E?aM2J(YOHlfOhDN&0>Qa!k%M6u<t;HIOHe21~UYpqGo
> v$i^
> z(!@v>b7+FruM`jhE;W@iD9{_<>IMya!q#A&-
> =1vu*jf8i$Nh8PzOk+G?IR)EdoeY#
> zl9Zl`_FoRLNB0-
> (zKz4$;c;9L=%0TPy<1FcI=fH9#I1ZWHVR@xoKX5^mELEUM<=;r
> zM=G1M(*4RxzA91v%Un^OZNCckRO=>=dA>d6Yc3YK+Ul!+01Ph9Z9DDjNV~
> So+hHEy
> z-
> !OX8m0NwuIm||vc$b*ryR;txUq66<BWROXKJQCbBO6QBn%XUgjfH;gGTpDx3
> 83lV
> zeT7Z{^pvkT;%Rs(dICm5Bn<Mwmf0?H6D}Hz@@QfD`<N;ii{3D5%><46s^Oju?
> -S7q
> zuFFlE1!vFtBb?g!_A+RycwN7%PP=&511m|sY!8!ZlS%Rj<1w<{i{f&-
> LHpEKh<~%h
> zEWWJFfnIUeL*|HetrIbiW5@upZr7k2_!v_!>F)?8q45MqqwE17I_d+h12DIvqx
> 1R+
> zI|7~Vpu(`iD)-
> *^nY%po5r%74;Veq6EM0PH4QC|ZekgngC_r(+X7bg;%XOK<h;SmX
> zJzlrn6|E$3P5*YY#_ii!02NbV2DY0aSPZSEzZEQB>4^<9`O;Te?M8%UDAR{0BHP
> oy
> zY4h(y-
> C~aH6mw)J(;_=7L*Ds8RVUtRO?L>6rKRdM{X0$XHkhgAlx=Va;lk#0H@{;-
> zsgK{2KBZTu9{Sh5eX05U^HW6!895ofk3Jk|aF-&RP-
> j+wwGp8LHNH#g`Y}?AV_tX=
> zbn`K|>1!2zq9?O9ICeszko99!kTay(**ud&pfcvr{*NE#(O%~*9NQW;UkD~gRG
> d`h
> zvW|G8z;*REVD?o(G`#Y<5)I3NjcXK>VPNq2ay)n7*@NdQJYN!<7o0sUT6^ofT
> P9BD
> z+k_dl(_*uuc(Ld6lAguLd?n`e;!PEJa^^IcUb{S9ZGP<yX_tpKJJi4Se6%~XQvt<+
> zX!EzKw-
> )uYLH(>(KQ!S{e2w~9%b#SRHDo+C0qi}*rglrbuEpi6_o6S3#TGr=^tbq$
> zYii;joq~D%oEgDebq$>*=qNmgCSp<yLngCka{ToI@Z6(2{O`kF08?&=*KKe`=VF
> Zf
> z8<Yrdk@(F|p&0D=P4qH|1Ss7NW(Yhz6#nhGW@Lj|joE#l8MqIITjlWBNhV)P
> D{I_n
> zHL?L1jDjmL3=I{a<c{&93c%?og%IC{bQ5O&`-ox`r^+xeL`L;<+S#I-68?2&WL;Rn
> zE*dMEM8yuSFazr(cCbDP5tfvg#(Fa}7fPnZx3Okw2px&EgsrkCGz0I7*X?pG8b
> mbG
> zu+G;7Ri&e(A#`9}dX>h7eTv^P(iQU=%c~%(PVNz0(om=y%$kuQ!!;gIpFllIdEPS!
> zvmeynSbamnztRk>L>MuFzjZ4I-
> {v<XEBB3DwRUtBNDBwnb$<dbOr$eC8pb*#gZ+9u
> zea^zM&oMR7nLb=z@nTLwgai&L=v;2Xfo?a0nBKdA%#NzlKvIq?LSut`4X=Pz;&
> r=S
> zw+)KdwY%oQZq&~O3+77p)71!^<}#KSz$Pt67!dj&RVS)P3rI%atQj4$s=Anlki%
> |J
> zv^{9dMW1EhM~AJbICv$B(l<a=FgOL$RD`V5pQKnifUsO;q&)`h+6mV-
> dJ*y57`g!&
> z8GQl+RfMh0Ds#3Tb`hy?VII~=kqtYlPXpb^*53F>i2n@%<{)(<vfT79M-
> Z;EaV5Gv
> z@BG_9Fo4=CmoDe~C^VP|EHfj^O#f~bweu}qj1=S}xLrl=1}03A1f2#Z%&C9PC
> (L6x
> zgt_)VnKmF{+F$z&gn2||9*8iFI%z+`AfQO;V-
> FWPAF^J6H|NaUxdSo4aas!x!~hrn
> zCBL6tIsKe3ygy(+t&Y#o&tI#|1NC!_PTH@ZC;1vm;U>v!fIe+$TG51VHv$##UpZ
> J2
> zQ~piqH_UsOGrs!2lPr`wV18AZV*W2k+}w?%#CV7KImt!`txNu_`c6I_orvr-
> N~^*B
> z{+&VVc7zn5?Tm2%Se<Y4#a-mzneguvgRV;qx-
> M<dbwOHoX~wVIRySI`qRw((^Mt~J
> zpfR1*26l$56Qx?rww>{9MQAX+$(U_7IY>3B>&clwh^&OIg|7;#DVjqPffE!0Kw
> &F_
> z&H<nh=+csjKh3`)z3$)hapg{5l8^a{Mn<CQ2Da6lP&q$>F@|1HxJ|mj_rzAIrAe
> n1
> zVKyftYr@vMe-t#bJxoLz6aIP={|_{pku{Z5wt8Yd`*kf|y>LfFgt^kisYww27zs$S
> z(-=EDi*sD$c&>Cok3v?XYDny2>8c-HmH4{T)#jzdjvf4sj6E<Pe?uPH3IAd<vN--
> W
> zR*)9Q>lP2bZIS6;yl-T~cFJfDI@X;0s=k=jG-aEovGnjXXApP{R-GEx7=ne9U*u}o
> zrRgb3Jd@Z=H)EDLVW%hI{z3Y}1L`vuZSy3?{T^1DH!<b+?lj^G`_<coY8$<SQePl
> d
> zz><=ln1o=MXc&=@szGrbW3MO{_~RbBN6IQ1hn`sdm_x9NzO`igViKgs;(Vjil$
> <Eb
> z$`g<YhV4Gg7uN$Upr1`Vx9aCQJg>ns><m{F&#;oNoHjc)!xf6nm>-
> >a>zuF8n?7Tn
> zOJL)tPoMYo+AF8=b>8He^P?_v-
> @l)Xy6~?D|NfwV`OJTR!N15ERjym{uMPi9{mW<m
> zdldh~5YvAoURI{#W!3><GI8{ruyqd*26y-
> JC%beq<aC*`FywXgaLG1WW?`#K5|q%0
> zO+}(wn8;t~f}unej{(TgHcHZ8-Se_g9|6uvzc<E+1Y`Vk5iwp2mf5Q|TTWv}SQ`E5
> z`1%4hOr2i>)gzd~SAPR86h`P6JadGopIzNZ?a{RF#j_%OmLi~sz5a`4ni|RWje(D`
> zLfBN;=toQ~0QNzb^n8diYFc=9tK&8cJxeq_a|4bUn(q%=KcM$WLP2wnDWYH
> 8M+<F-
> z|2<F?@wR2qypVs5{`ct>S})Y=*Z1INz7I<iW|lVyEU*&uqRBLLK9fEhsqf{dzW*I
> 3
> z6+vEam`+2``r&LFiueuGD#)`JtnQ$%)+;|n{4}32`amU{F`VJG6tG+Ubnyoy4O*|
> A
> zs`-
> VHQ>Yg#VKtAEanx%+=TcO0*_g{%2ouD&EeczY*rj?@+#B4oC}h>y1tskCrZmw
> b
> zVW(aRfRu-
> <S$4s01lhqmz46xapf$lRC?Wn8EEwr_mMoNIR2&@%I}FCQH=Y@cSS3tL
> zWfn#eNX0X)r;}nAfx0Gqc*yfE3CwrFh99DrOVfk#z@EqJIvF*BrH>_CSq>kHI?_
> Re
> zhrs#>)d17pQ#3bsr$S&+wH$#}?L|TB6+5XX^)CtTXu>^X!~0TC0B%QePT6gbsq
> iDb
> z$APyC1nC_nxzMs!*`M^Um+am5F;;wsv~a$p%hE?daAz+17@MI0qtAz!yW=
> WOJ`1z$
> z@0hQgZCn!j1)jA$Wcevbr#xi2sd&D0=DhjQDYxBPeS37qd`Kd}?-
> Th=v~Whufu8&o
> zvK{`v7R2j3uGrwQt*H;t2!g|uKGuzJUuAZ5$LqQop1W`;9PGtcPjnf}@W(n*t*F
> @R
> z*-
> )H_vSE>;Ye`)fEAYi1<lpANUlDOf5XBRQA6=N_y2?Ujl0q|O;vZE+|E7rMs(>_q
> z75KR5)p&xEour*;X9p+mt%x2b<YaF6iWkP~yalntYJFP*8JHG5X&)=wy4M59H
> pC%%
> zI6OU=B;7>}hW_RE?36e4b+U)QyU5?QgOdtuO}D+{Y>dUVFR8I$K<^89)?-
> 2XcOl&#
> zi^8!=4icULe9DYl=3Zh<n|HqRbk@046f!;o$N#iiKo3BD@!8T<vaUw)#-
> K|kUYBvj
> zz~@}&NqEu~e8(g}!iBCV;2HW}nKTw%5Y+J`z*Jd5l+{nRJl2b-
> 9Bp4cTu@3AR=_2r
> z_#Nf0C~P4QEmrHi49Nsv1MmtP4o~U}Iq)(YUKX+j=fK@I+#Rysks!OO$791Gd
> 0)+e
> zkGA1(@P6aK!`74f+24<CH>t}oV4R$8j7p;2o}4y)2htZ>z=~weY6xuO!2)gu%F?
> %S
> zco74Q*M650T@(hl?RbjFazD6J18uc2f@(vSZ-2L3Yk>ar7_Bw3i6<;^5)q&EQqu;l
> ziQl$?7)hlwcKpHag7C*E#Bw?|VSd@M99z#hmV<OdR@ku00^L_Vrig^;-
> r@fnbl)2g
> z_uW_zO=_(FMoDeGSf^j#z!FW+`tcWKP$f2JVMdgMt-
> DT?Ij+@4iYyVZL~Zmyc%l`U
> z4zMml-
> pXyhhF=NC^pF*?Fo=*I!+F@`B3lS#Ma<U#T0##fxGXX@@^9=8*4Dg~3qc6G
> z%r*l(YE`HJ1pFJ+?lE>KP@?T0EhFAoU(Te@ht_=q0pMfo5HEF?HA*@r8II0Nxa
> $_X
> zB-
> J0ckoBoR0J{IOT1!UvQ~i+i5KMoAVB%z=P77KmeV=7L>C=(&MqbM8ag|cS6?
> Mj-
> zt)I>p2qqxHd!xXTAHI+`p5@wp8DQlU904X1#Js+Zh&NHs${bYt1<U|eSk8N1#F
> W~5
> zCV}>hb|}E1ROzK>M0zWqpMN!KE8?OS*txkBaSd;gzgNAvJ(cazbFn{#Vi5wuT
> NFWx
> zKhxwbYz(|Tt0*Y}k`i!H(AxQ&G)Dt-YY}ise;16ZM51*bL}CqkNA*;Wo_cjpshfJ4
> zh=~d3*VT{b2{UF#r%m8C&^&t(`|SqQpIROn#xy#z7@{%zgdKH6J63AUMv8Tz
> L>Jsp
> zPw$}}iP&Q2j`hf1g|yyhfjBvBy2oXC5OH}BsXuIe_kCtUNIwHZI9h6~W`(H^0iwc
> (
> z$*v%{Oos6J(z>zBM(1JpugW;)DnV?x(azGpuuG?F9bAsi!-
> bJbjm~%9VigJ<Z+x5k
> zf=DJh+;H81dTw;;!O8~);cq(d#a`SK7Ywo7j)|enf|b8h947MOYRHSnHXQ}*o!IY
> g
> zyugC|%x0w+S8aYBCf=@UX)lw?TKTra{~Oe+qrz0|E@KSvH{9R=th9_%V}|&IO
> |8eU
> zs#MI~F|GE}^S7WR&0$_Fg(Lzka2Vs;usHX~Qr$;H4O=ke*i$n|_SE?55nO;7Vvg
> vB
> zu^+bnB;!vrUDV;xMh(d~@>MCWLY@CY0fyQ9yJ2<kInZAeXb)Kz+imPZa1B((
> R!x}1
> zJ%~h>#jX?yS6IZ24Op#!v>T2AGX1;G*v1`sfnAV;U<~ePfywgd4mJmI_!wcBxJ
> 9y(
> z0abAv)+j_;?M%^9w^LCocG$31?A%LmKVYT^>n;j{7P=tGAPDRhkQTJ6>_$2P
> X8f`%
> zXpL5|Hot`6xi@y52)1>qA>et&PGD+o9sANI&ci+LUf^Fh{}M!~Z+@u=mJL?mu
> so0W
> zfemQFcGbqflQ5Iu#CQ3cz1W)&d9w2P=rD+f4KTx-
> B2PA!7GUG4|1oI14xo}Lifj*C
> zXZPD3<zi1Dlblk3m@mBv(V9IXX0WxUDE>x&QKUUViesUuDBjhN-
> X;9oQ`d;)y<Ijg
> zVh0*_k+hSa)X2?0l@l1V7G=ZM$*{9z?(M>e*p;*={O#!%#R$SkfcE#Qc$w@1y
> c)vk
> zR;*C%X8~cpw0MWZo-
> J}0a?RwKzJKi7x9JkMGj$%W`q@O+*k{3k`|l^yQ%X;b3{iy~
> zQ$M**nf6ee)s<b6rC~FA%cmU;Px7g)!TpW`*i)yVpFHJBG`Ns}eO$9St=9NBt&
> $C1
> zz=GE0N-
> `UZa%SA~|CC}u>qU_|D8B*qW4;XId<j`UmuQqTUyd=BalZ6PNWcwTN5GFx
> z{RITbPO;nUB7O0?K3D7*V?B#(%`fr`6v5P%N!l7a3iDNF`E#*SEcOiM)O{&BM0K
> _x
> zeWoJ>q9-
> AzBxAQ6a!UD^V#AExY~!1%4H5qZ$H<iC@`A7(43xhJ$fFIE3d)f{hZrck
> z5mt6g3SR?U1lO#g$z%qj8!}gs)M2aSyMsAt(NF)bptVgxQf{-
> ?Op@Rs>)#cis5iNa
> z#lqGa1xQX9gsmty%8SQLvaUpZk^`bDj&EMY7t+afBl>VZyaXs2o3wFE!(;<%4C
> <D!
> z<1B2-@SDqIU_;ikQhSM(aa`hnkeS-
> Xion{`NHj}!2dz$7JBF<TH>}4M{hF^iNp^yP
> zQl;GSK1eXkQ(7k2((MjgcOc{@I;Tsvh#X^#B$9nE<{|kPk}?k^RU5FFBvTJ9s$D_
> H
> z7*kk&Lw@-mp}Zh;c^08d6nV^gArElsB2GmNNPQ?cp-
> wAaXOVFAtaEC9os)<YH<|T7
> zOlk@sqI3FIMHLwc%079(S`G*Vqv4-
> NF&XUMk$M)QSfc|T;H(JS6Dfl5ElBGyZS)vS
> z*9|}-e$fW3kGrCXGqmr<d-
> `ZRWcEuan?BLy+cIL!C1i4JIK$#oGRYkZA#0qtDV}tt
> z!PMj`Lc`W63Tli)!DItrLF+^X!w%7qoz15}DhGs{MkaO}Gg-
> s++~_qbFuSZm^;*<x
> zxG>MH_Z8O__3EBlZzzD`-
> dAKsyAvXXq=1<uK|)d&v>_Oh0xD=#O0}h_1VoiI`+%y)
> z)Xkc9JF3}5_N(3O%{Jg+5)%7e)q8UCAVkJ5&qc!=!5m?QjR>uv!Uml+R}q`A^|+
> KS
> zvyuC*h)8s!1*v9|d9eQ|C9G^Cuvg@vJN^vw?29pAL=l&jw`rf^bcQDs%PUseE
> OXk0
> zz?8@fn{TZPRQ>7aC=3y*VjS^g1=G5Re&dlE3xB7wlt*3yWB7z^w3M&^77UQF
> FIbCV
> zmn_*%?E~HPGT2zh5~!y~BRlzmX4DKkQ=(AzUxR1L4hUOU5YH3mOrNpvis(G
> o6*F#R
> zX#4VMx6E)|8k;@)ve?Y&Q*OO=HueY1oHLV2Vs(FVyusP@6Fu7K1%Fzv!K8=
> $Ql``h
> z;FFytBaOK;kYl6DVeI6~&vUcC1vIsj3flyM37&vKFd`El*RbfmNtjqwkWKM%$sX
> {m
> zD>@cgO!q3jP-dB>NoGR)64hi)ZF|2CSu*`|?B_V|KPb}RxU2m-
> I#_bc!`#{uv{G2;
> zMylFksnbHTmj?Ffx|B8~`mq&c2>1eS#W;53Z@aR+PM>J+6Vb(wu=n}=C&mh
> Oi{s9X
> z`omiHvoM6-<6w_(--
> OY#?eQJ{e}XJM0N|%f{b)NvSqJ{@1RASBZR<2Ou@nAX@=j#{
> zb#;Xjd&$5qh(Z-f044r>B(a7=(Gjof0CU1}7k&OdYJ)8(TXmBDe_{s`B`Aw+2ch9o
> zxQ}DO(gO-
> Uje<#p##DS`I|?D3{BM%^z*Z1nfIsl6EA46Wzv?b%^uG#c8UG^xtbD$1
> zKF~Hj&~-&kD}{;tufj&H^e&wTfti~Ev$N7O|0rV@H(gx^zXk->{h-
> |tcoj%=nLH8I
> z6S795DlxC6!*z%YONX&OcROags30s+LdC>oU#gorkKtvQ&fiuLL3l`0;MK)j3mO
> I6
> zSAh>U5Z{NYD_^V|3H%9(FItY+6^xkx@ZM!kXmSUwGgTGot%!7}Y2JS+rulhW
> WSYmf
> zj{{5WeMYf_DRb6+S(OW00^t>5c=61&63*o-
> @!X}KC*XOPem)1!{@R(<vD(@h^J->H
> z<HA*B&dlnWbE>D!pTX6u8T046uB@H6ALR1bEjP@VcWZ56+KtA{IX9^cc0BkH
> @rO_E
> zA|mus0@g80mzagJA^;aHPy+ri-
> AxijV<eefL+q&%>oM`4@j22{6zNW2*9Zgrp7=+H
> z$L>T#c^Q(d;WFc(sg+@&r`keQgo-
> ~{idYD^HW4brggb){RBvKDnncKD<!YITaEU3E
> z>vZ8t6hrexH6;mb2#xg808)EsrW{Vb^5E>0-
> )gEUSp523zUCJNweHl{Kzjxg8P6EE
> zIe$XSd@j}T8#r+=N1Q$H`7S^&`h?jn9yj7JFk6h^wczL`I3eI@vZk+oC~X=zea)f
> M
> zxrmIIIc7IrYewN@L_M}`h{M=ieHyj}sDmH&*~eUA%Bf(6Muv^iY~VC$06gBqy
> |2b<
> z!bS)Tac1#PD2nxAMCJ<gRo0Zu$6lTuvl^=~h!>UCfJ`j+XE8ZF=|3P}d|_!3_7|-u
> z{8@p!(-
> E{BzrC~&@K(Yf*KjP_^vJedpRtSZRT_S>s;2<?cN1Qx;lqqBzRppvMh{=6
> zsTb8kQS9P@k*}%nH4nca(s$eO(%}m9%-
> 8H59yHw7p^oFF4o`X)k6wUA6=pSd`VI{l
> zUZ(C-&a+X<m-pla!Du3$*Bp3?D;HQ!Lk-
> vmQFwu$&B+@AFz}HJLq<94_@&gLnj<yK
> zv5_)lmV}LwOkJ*<8_k!vZVvQExUVPG!#F`*f58F-
> hWo?D80NWNSBC>6{Xt_PL6a2-
> zq8iNk(58ImwBy|e;m-
> krKf;*3JN)m!TJHrvexDo{=+*pKf1B_lUKKwYctu_;uQ}Y~
> zoIK%Sxn8q+WYE}5Jl8%;E{Ac{%YE2J4`Is%#>Ea!4KQK$NGYaurZPk(#DuLW!<%
> oT
> zI}|iBEO)gk2PVWq-
> tEGKu5SWfC2%q!X7(Mzge8QJ((sE=8JL!v;>rmx(QusDU_E5Q
> zk%VWq%ZyA9Gsf^WrCwE~!UzN5s~I6fMnE6S(HX@E<5<U|Qio;)ki}ty2~535
> QZYk;
> z9@aNRtc6C0jmb=$rHYaeV2s|>jj#ftg5H7qd^%(s83YU2#uVoLs%~aDjZkAHL1!
> pX
> zlm8vXBj4GW$0N%A!};b6W3UiU`bP;X>8LTGmH}6+Ogtgy1|Yh`uJYBdK`wa946
> m-#
> z?AvS9Ah*?^Ug2%PsIYERZ_3rUP;smspF^NF{Y|V?fL*}mlcgzmmAfTZ35**CZh
> rEf
> zNauKFU$hv6O^-
> IFAS2AR;~k8^B4O*7vgrxdfgql`QUo^+KhqRj+ML&M_7nf1|4VwV
> z1|Kul^B73G=}L4;he>l|JyN3+&r!m>cn$WI^FPOS%UgplE<p%Wl8YPR?D0RWz
> ZA4J
> z>_R&N7e7TkwQ86h?Kx65W`Wk-h{^?xt4SCx+WcCW)@vAFXW+-
> +`F86nj439UF_ol$
> zzFxQ&#Ho;2D<l}!%O6<_+ZXCtHg&@4VstqX@jgs&Fq!N?>mlnQOURsD#aEm
> U6xM+^
> zMNcsP4F9^KHKuyC;2aU6{6ycDmBUylzW2J=NR?wpeK8>}UAg$X)<vp?bYc1lV
> >+-+
> zu42E#Ng+wl`h7+^Lgls<WPv3xn_W6jAp#e3E?-BfS9rGcp{-
> +_*C<nm>er`Ob8_++
> zxRq_cm3}F=P&t0C*q1@Qg(zS=EFm<|YxyE(D>YYfe8SeW|KO`TzH?t{5L^aR;V
> 5ky
> zt66Xj{+P)YWDZ#)rB$cw$*Szb<y9cBooBg3L=k{nk0RzO77Sbe{F7?s83J9=3rtB3
> z8td4XIdC7qy=Ib$A?xe6OWsG;b1YX87Pfw^%BPPux>#bIlyF-U&U3jWpE3F-
> pxVj<
> z5Up>i+U%vt5)W-8u$V;3;YDE@xKhU!!xDWOEzCL|6gr=!Yw*W<<2Ni_YCV8-
> 6fwp*
> z^;+*ry;yfMjFk@bdv6NVHs6jm?qe;hr53kp>Is;G5UcR#zM!o&g$W!0tgscRo^i
> =C
> z^*H=0$kmY5^BQY~^QKSu#m<Od#93Gr9ikrGh!(Z7rL$E_kOk7Mn^^;9lJ)%Yx(
> 4h-
> zf#uJY&zr_d^VUB6+SEASa2cqj2c|pPBNBE^U!;$Bk$9_UtAe?9s9bgq?!K_Thd`
> 5E
> z*)c|x*&fQz)`4uw`aHKtT9Fe2)@l01Vic!bzsPY1pL%(i9Zoc?!}yy?{^g`r56|$m
> z*mn>2Qkbjwf^FO9Tvdg3h`<R70jn0=VdI7Xh)^g!%V=dD`X}hIwXJf1JeL}s%=1
> T`
> z=SLUk=Rt>D=@X3%^ZZKZd4Tay&0=<25*H~>y^4`>!VA9o=TTY>Vqx?P_OKq
> Mhc!A(
> zJz$UckCBf9B0jr>hg8I?3X6;4`zbCePSIS^^~C1JFY1z*g3lbrhmf@d&7-3R!{91d
> zb-j4Yo=2FjvvX%rhAwluL>;%ewp@6{?$I$u*-UiyS-
> 1tL%Vq%V=RwD87Cl1YP#8T~
> zcOeR+(K$&4N5w|c*KjXhjLE1`A$0j0tQIrW4zvf^*wy)stw0&Iw1~jd=0CFp*t#$
> L
> zFgwPTMcv=69ZZ6k-osSu$12taE4i|mIip7zi&^{LU*~oueXfoCahj4*-5s|*;|9f!
> zP=oLoi~m}RBLpw&<!XKn9wRifN8s>>N#LO6QW(T9%B+NT#CDQld<a>VimS&
> j>eKKM
> zd<a|Z3Jwp=i58uX4G20alvqXe%|sgKmYL*h$a+u}N<XJ&+Ag@39CSGm_Rc-
> (MP}L?
> z`bB2iE9%7#>%7%T&f>bT^6I;;gjYZ9m$|{a-
> y*)ZWc$_NIM^CTA&J2|Q`WjI<fbZg
> zBe5KFaTlL4Xh-
> 6iN{Y{3Jp1P?m^@>SD>y9*7QoKagM{st8&_1hmgW3gkLTU^=h!ox
> z&$MSesC*N)rhE!}rUHs;)^w~S`Rjw$;3tHM<ULsi84|Mk&?E2_7<>$J<^{Jiuphi
> =
> zDP&#W#Z1}YHlbl_qJkO|P!RETz=D=v!D!qiSE+1gE0D^8=_Q8WMT*t22tzgTW
> %Z`)
> z$P-
> (IPsI=Gh4sh<5QP69lsqa5dzUCYw^4(ZrGk(DA_!s%(A`F8Z!%IW58Nh<t^_pG
> zbCM10F(P91A!D%=M6@XOF|(9lvIMP}D*h(w=y6eU?&K<#!4aPNpwY-
> ~qOdhwFex!w
> zS^<dE!=6$m9TvK2^cJ^3k1SUFH0B!c)9`h<{51dX<R^|K_-
> V&4a{1|e<gQ11(=oDl
> z;hAmoc|M*=OY+%ucs>aKgl8<6IiI27*ex#mnGs{#9**}MxW6c8(NhfJ9sWHK!
> 5`vZ
> zAO3xSe`-
> (d4*$EZ9mQO}g9C|Og2S!jj*y5iG{fT5u?VOFToAj%m~aJ#gu63C*38yH
> z<QkX{eq%Dhv{!>x*a4quOd%Ne3=I!kl@9o5<GO4mBW-Z(1Y<hD)>yHL-
> PVJ{v+X}X
> zgNNJM?!Iy`<m{SkV{iUO<KS!fEhyP0mOaQgfXR#s3g@3-
> JjO<T51#^@W1XAR$XC#a
> z(Urxl$*wwf7Q7ks4G{<HP1u|{rdM%l9}p7ryfDE_8(^N}JR43wc?uVtVNm=TJ@
> }L4
> z4I!tA*@nfj%nnf^*pHcU)fJ~Uql#1=EY;L4G%UJ_f}+`A2Zc$hXVla1=;AQqv4t<-
> z#mVIa{?>U0p=Z79S>IEtXV;Zv$#*Rq;F?Ox%Lb~ZIAisbEt-5W-2iOFfl22^12rgU
> zeP1{5Pf!9<MfhVck-wG=fZwrilnp2z@!JjH(jg>qry);1a0`>f7QJA|Lg<`52$OyH
> zIOITI3Ve4DXEiIccz*nhjpqb<mR_6z3|rS6zTa5Pr?pS&V7rx~4jgZ9Q)JKLw+k90
> zdz$<oGM4>e`d;HcR;_6Kh*Nb97m&S-
> ^jIGc+pp>}R!!t_mzF{v%H7)(*t0l=VDp})
> zNZ;aZXrnJR26LKym^ay2oh8Fp?M9+sG1g?eb*cjfUjl5MyFrcKkI*%nxIe_0q<D
> FR
> zB2)APqa=c?hv}^IbF$7u)+8MFB%S^{^1X!O)D)yDHbQ4ysl%YYj3}zogm_@HP2
> -EX
> zG@%Ibfp<Sb_)y6}g!oXR?jNQi@Rf{(tW`;a2|2YQ;-
> E(Eq5W&!1Y8ChIh(5c5NbCT
> zu~x-a|M<0y>sMzL*>iK^{<Yr7TIo9H&CMqN2V{c}Qa@*<i?al{-
> >LM<r0n`p$cFFa
> zm^j|n(MCOrSj&E;Myd~uruK@DLW(7ZaqaU!0;MiuW3Ac7Mmvq2df<d^io7f
> A^sW-g
> z1*v^|QF?n$|DU$|fBJz_swwck495Fvuz{N^wS^V5vjR0Nk2@8dc3^O!$^RZH^
> qwjY
> zBDzv{vV3P2{aftvSX}JR;&r7Bh64E$jtkp7{2IiBGDBUE^A-wNU;B4Oz$bIE{fgNr
> z0G7_A0I0aq!S`RAbccQQmosT3lhg!$BbzjqNu!yh*rY9+RK}!pvK6k&CjAQ?G{$8
> s
> zT#-
> $BgGm#z6)wmowJ~XOw!&+(N$Z#t%vM;HO<KXEDcK57wv(cF7*}U2JKO=^Xk
> 3@A
> zXitl#LUgh*HCsuS1OAFJJ6p+f4)_FPA;4CLn1^nwYG`(3E(TpvYce8TK8$}<aMza*
> zqwI_CEw~HoW&RK1nS#5HgW!3WNk<^*eI^Y-
> (tAj{^8{lZE51ut{CC(1_K?4Yo~j`)
> zh@FEP`cQ)}$*T%b%Lk~%m;AZB_}@oOzT^+(CGehPTkaGtj-
> h!$sP0a*%Di<kRL6XE
> zvsD9wBoFJX`-Yt-Wap_-
> c?x4T_KR%n>%OFuq8F)$qUbs5!5uwA_qh(y3C?I&^cbU?
> zU0o^mwA<>3bk$vTyo>X1gf&?7W3dL+&VX9+>bP@w^TWy#1i4*R$Op${A5
> ^q!GM+D8
> zz}0>(^ebCV`vae_pB7>R%doJls4VH^;9e#kn8BHW1&3h*EIGe@u*<dJXk$?|
> @a}wE
> zrW?<tEKdC%4a@9FPB;P<+j6B!upfyPl%N6}1GybJjg=^BtYLYtZJxuJlTy^fC2anC
> z=&*PgvMj;X0B0=$USxme@cB~}s<{5oy&`Dcz_H~bKW>W@hyS)AOX~U<S6x
> twco*6l
> zlY?s-L4NcSm70^6LNkw4rGci2ll-_^(j7`CxyZ*eHCL^1Ld6mvA9<x-;5+CAS3CUJ
> zvFFc?5kvmCVuvAk7=M0W>LifX*Bpa)3WYjTad~C0FFr`%>WJGG_t1D|%pz=
> m%Xz=x
> zt|N2btug3sdU`G>Gi|>jwfhyhibc-
> KD>8o37xUgPy=!>xyLFy8RWQxBC@#g!*>}b^
> zu@<q2+Y8dU{(1}UMfLo-
> d?f!CSG;kV3(wZ!5~nYDt?q4X4t;x=3rY<E?ALDT{%c+5
> zYqz|OgY>>9{MdnpJHawdfqkN0_NCr{Q3B>4`w}AcJVw*;BZvIzJWR!vSLp%hL
> UnNN
> z;lSlDwdO8mQ4gN)o`1B_K_)l@rX-
> y^Vb~@pF@w86td)2Y?h)1jpROgJj=O}>PW-W^
> zi%*DKjIfEKQTPZ}c_vZqp5*~#frbP!iSdNTx0S*B#L=-5EWP4Zq`M{33lm+fKEu-
> M
> zOC3(-
> j_oYfB?wRmGoFDRubxB+H@1Y}TEZDhPFaB<gO@PO4|qX_L1gafWFL61oe!D
> Y
> z#+PygQg`Ezs9`u!#$4vR-pPj<lWD6i1$(*D)1+!lF=HV!U6_-}pJ}TqMaNy~aZZc%
> z%rqh=le9?fj~MfPOziks4oS~Lao7%A^JlL_bl|1cmLupec9F;uzHiw}6ft$Zg?Ao?
> zzeUlTQ`ofPn&q*sTrV}EbBXcgps*qojt$m<6)-
> 1}Wo%BC3MWfN(E5hTV&iX3656Br
> zj5)D9QIH6^Q`e#un^M;4Dm_{HEJQE&i>v9V+Sa+SZ7^gNsEk{?ig=wTM-
> B+}{7?{b
> zTI+;820lu9rM8f@OxH$UsjvxeHLF}0`1ngMT_GYIylvt^T_No$dc&s5%JwFeHx^
> (;
> zP6iPx^!>6~s^5(DkHvHWw@_+cr?MwvR-
> z7b0@uA_y$Hv6yKfsa559|48R)tV_t(jZ
> z$$qo6F>IZ#8xZ=SvV{BH#FTg4xNp}+!DFM~F^8V96N8(;*)iQ-4-
> 7c;SNflHFU2oM
> z{NTgyp&BVQTob@IYkr#L8=h#q9`n5d^WAzNZ@%w${%qD5>pUff^tz)QJ-
> i2FH){+X
> z44j3yYPBAeek||fKhUbJdbB)Yn|4*1JmHGw@rd2()CzfGD(zC}Af%EXSawJCD
> AtRs
> zNeIWS3#vj0GbBTT0~oTd*hxZQX5)w!Pnn&R(+P>Bs6Wsj`}If8?^RMgM2|J5g
> D#>J
> zrrVocWN9^a9HvspFi5poKVj$eB`r?^1v$cayy%ysjg`!DnPkyB^2Fw;^A^R9l`N%
> 3
> z3$u*O$&#KcI1I<Qg;nJIC#rR+89EXd8oLmoweEGmg)uBC1EW@6;Iq&H7Xi#lW
> O-?t
> z4epm6RT!6xRfx_$i08ULJI*$VKp$fh1hOnPbplhPi|EE4Wv5Gx^Zj^vj9R4?Q{DH
> D
> zkiu9@==W^sNB>aJc0w1~(7$QuXhLgk=nEQZ5gN3i8#Q#yrGQ>&Lm$@A#e|
> Nup{9mD
> zMyTjJViwcT4ni|r4<qz?4IOnEpl{gFi5gl%=q?*NRzoKf+H6CQ*U+m8U1LKBYv>
> w6
> zn{4R2|EcKEMQGH9{)dK+ssZ#{HuPByT|{V&4ShmGTL?YdhTd=2FcHvl8yeTp#
> e@#B
> zp|@yg2cf;anhsZK=$J`>{>g@p*U%P1x7*M&G}QeyK!0gNM`&mjq4(L)eLbqj
> %L!d-
> zLsJ^sMd)lB`m%<OnGEQaHuM<{T})_|4gINxwi9}~4PBw3WdT4-
> ZRmG2bSj}AlR-K1
> zGc>e^l(cN<*EMuK^S)$5FVN6lLO0vclQeV@sq+&XI!r?=E(dhE4c(Jgbhw((J8bC
> d
> z8rn|ibQ}6R4ITA$KrgqUPig2vLeICM4{7L5LQk}z2@Nd^0_wG)^EK2U^g}Wz>F`
> Yr
> zT|;P>4ZTc5dkKBshMuLNYl-g$8+x3EMv23ZY-q8DR)qj<w4v{)0J~8`=sX+xnue|>
> z^g0{*TMgYw=%qIFaSg2q13Jcr{+ou*CG=Pux<o@;33c1hn>DnQQPh8sZApiSh
> E@^U
> zVM8xgP-u@gvC&GtJ0SkXK<ATX5z;>A3k`IT`z$tx#ICjPv-sC|{c0af7U^y+2nrZh
> zczP5p|M##GE`r>8yvj-7>F%KAJ<A5rzLg6sE&#61sVU&w(zC?pvR?jufvh=|-
> r2iv
> z(|5Xx23m7kMh)8LU#WhmsN}w%h7vfjylf!p<pZvZT;<^dzCY05wv+I6n0-
> 4M_Q6%a
> z38|0O53go$Jx!I5A_lH|X;IG&)A8KaPzF@khEav>1z6fjw)~Z=RHv=vZ1LLARdbO
> U
> z`|~xlotG8tfR_!m4tp(VSO6p&3^b4ZDc@B^UDqJf!#SDC07xdQkSS#SOlKOyOp
> 9_d
> z)i9G<DYEKSCQ;Etm2>heBH=>wmS@DqO8A$@>z3nF0BUg;w&7o8O9O0s?76
> ;?0%*IN
> zTV<M1kP9+$YlGz+FWb$&xB0ogjGwjqnN<NY1lEVFlQD*%fz*E#>%;8{1xf#&
> pmo?f
> zrj(>dQ{T&-
> 3OHJ5eeer`B7Z>)o4Kt<|DN<voE)~ce&j*i+P5XLC%$(WuR~fX%dabO
> z!NQ(IlFVSP;@|k&Llf%Z8NOcTyJrpp&SnE&e9eue^;NEYBa?3Y2u?>QBb{MmD
> hMVN
> z`B2uuz3K60U^$lh(EW3SMu?^^V~o|9&YXc|A#1WI3Uq9l3s*x&mW8bc)Iw03
> U$~F=
> zg2ZZdzro<r@4%jrb)@Pc`mLyet0%0W^{=1j_B&vquk3fk!j%zN3h-
> _5?}=xIM&Ykv
> zc-
> sHL%ovjBL#cNW`NvJ8kxsec>e7dp0&I8lKD*elaD<bSUDzdRkVhKDeD$QBK^Zy
> 2
> z{g|BLeoUX?ehhSetTNC!|J#E0326Q?ob^h2gCS!b`%QZ6ew{6N(>1tJ4hAZ)Iby
> RI
> zsGv}8f%Q@VWKsIXCX{~}_P?veEKMl++5lS~`w|+fO_bK?fdTs%8|-
> Gkshb_|H2dJM
> z?Pima^<iT(bF%g)MPl3Sai|LN+B3EzCyQ9uthHmb4cuU={Pk|R<rLALwWfb9oK
> |wP
> z8CVMfC+It`#VvY?nlf?DUlWfCZu#0oHJ!-<t4%`!YZK!ud>dC$JfKV>2>;%<G09il
> z=b2LsUcPUmNRgn`lvCIv!pVhco<5@1Y~X_$BzZ(tgy;rv#Nk9#B6-
> YZ&r<dvg|9@n
> z%8g66g6XGq^IKmp3MG{!VrmV>?}jEBQK3360$)q_)7V9Fa&)`@s>XW)ZVW`|
> 0h0Q}
> zr)|QME}`<UvD>Eod7@`>Y2Tnib@o^%u^MA^+5^z>;{gWXM!9M=I{=It9Ap5l
> R{WeZ
> z0GDdWAqU`#ImL1ZU`S5k|H%P(y>Wm6u<QZ2@h|%iz{4&34?vGS0L`-
> PF?RsmPqH{R
> z42e`qdEtc`z4icH_3!`#@J27I&kg`p-9ZN6RrsRxO|vuLSq(Yl0IbO=mOB8AIfefx
> z2Vm+w0}MdM9)LGG_aA_Yjr$LP>l<47d<DBHMBj;8p!A9VJ0Z>hm<<1UkX=O
> 3A0KiC
> zU;+~)WH=2Q*>VSfA+ZAo;9%nA5;(v1nB)@o3=QYV{7(|M=x$9BSQyZ@t8tsO
> 5DSu|
> z@joOfN89dr%BF16zdC4?Gbf4omp64Kj<y}Wo)DX?vk)IyO)JWpa3A4_NTHh$
> %4TG>
> zD8?`4fGd=cYYMDxB<q^h74rDBvgslND#g{ldmhFxC=Ca>iH&uo!{d9ujDT(hkhH
> $E
> zO3+aT*7QNJWoc1;5z*<#ICP=%q<b6o&P#tFRloZu=}#ITB+^oK*9N=i)P)Meq
> <3e?
> zxSC~XU;L?C%4my&s&3R1(x^SRFNMfYp9uvOvJSUX#5TjFx?$rwqItI%pE}0#44
> 1~K
> z(N-
> pEMhd?97TQc%DB0gayFx*c{}2`$EfwmDQ{EB`#ZtKp&84dGM>nO+zJg?APuTic
> ztXDRrOr=8JRBl-cs+)>fFob9n`K_%P4-
> 7*bsiv9EPq`#GHn0t$2WjK`wk#{AA&oog
> zOKZ(l1gUFA<uN@(EPlzj@hSc!lgy3#ZGIr=R`$lu6$Q*R$xAoEsH*mfbzcEf65mT
> w
> zQd_wS1$u`}s-B26uM)goir%j6wpc)W6wtz~3R^rHR}N!6$p-
> 4{U^1yHZ6<lP<DSe0
> zdKo}nY4c)U!Vl9(F5XX{bU-aI5m>D@5%>t&(03timS$-~w}-
> T;!mp+cL7Fyv)U=U|
> z8=vBj?QI;VI2^S3ve1TU2cylGl|WVgQ$gw_MHE2@pGx_yAS4E@ui^W6(SFte-
> AXpl
> zWpapfKXjKO4h<>X>QAbek|*JQg&!X<lToB3yz=P*d~#37hWTHckVkL_$*N7E
> %B|Q7
> zZ~}s@#&S#zV>Rc;AH{z5lEgw$Y?x_WR?M-
> %SSS*+HhJ_lH_$JnW28t7_hjQL`jNgZ
> z^&_}fu5u^YFG-
> NPVpbkOVtSsEapP0`(K`XH7IBu`LSlNUOq0B9*=D~6ViUA>HHb9W
> zAvhGIW<hvi%mpDF;NwC>{37n;axExM1^7mJR3@9dj1CbgFy;sUQ7TDSJ65%S
> y)A}R
> z)=tR^>2saznzStoN}r#L%i>7jLUS0~lNF8Me2?{d9^rm6y}LGcyg5R4mT?8w=pw
> N{
> zx>s_geg_tiD*#3EM&OQ+#u2z9{>LhdS!n)kf<DA4M5AodO}ZxqjgdI5Cr0YUuc
> &@x
> z#cACWc0cwjGfK)prI^aF&2ivfQ_D@ZIQ=$=P87yIr<#NvU9HFsQKQ^39H4?QA
> 1}TM
> zJ>>c?Vnri8O$)eOZ})gH?)R6agB4T@xPy4Rwk-
> XVjDYg`Zs_IYQ+qnyajfEBv@~~5
> z=R?nMPbb4A2>HCXM1@hzeb~9;@*+1bz1RnqaAjB$&#*jP|B2^LJY$Zz-
> o!KbU|$8E
> zyYReP!(YO)f#(wde-_VG`gtRs$?t^!0?!m$423+5XU<?g{{YYATnf?Ucpg7*-n83Y
> zIiD2Beow##M!r2WCj)nmI(hgKn6~heTjxZl&73o1-
> h9`T+vm=3p~Mw4@0gK$)uDa=
> zp({Djb$4Br%f!DUqE)WhORMmK+amn`6aFjsg!H1KLTCTO7@W6n-
> vp6zU{Fe8ChDfk
> zKF;X~4nMvMdxHCqJ-
> #ia1@XN@ef3<}mz=mf_Epy`L}ZeIPQ+s{gmk+31r*%4Ces54
> z6?4i~;Lgc6#GBvmMmE&V_5O<J6iftMKBnJ?Mknwc_6)A_@-
> %rpjgv=oqV_&rJKHZn
> z3w`lS$(=_VcVY*Qu?7JuV;#d*Pl%!JO)tlS{i`@1c(H@almZ;h8X7$lfL^TGB}=#B
> zz9oE$saNSH0^38zPKLS=c(Dd4+d9<;LCRc;quU$6mp9*)voGcMFwWxJ$AFth0
> ?eRb
> z0VvgheB{{@Ja^;y65MmC_{zTD@{s2ZB_=jlOt$p(SpRIjo<=;Dlg3EQj5qRddY`D?
> zl2ZoZ3h@yl+29=EE(x_jhY`VjZYs)#&}Gn?hu|PAQ>^o1eg08-9^0zV2G-
> tbhcpq-
> zT+%ZVz2N@&PIP}0Htih9Hf;@ENJEOV>!ZQ40S(>G6DwdQV+@=HoTlQr2kU1
> b6}Sf5
> zMRucSzAeRaPfRQBiILs#y(km5O2s{Kw$e8c8niwZ>)K;jD40wV7P9s#82g*l+5W
> CT
> zDu=q$H*CGPO!dE4E&2UTy{f(Re_SqU3F(BsWCb?_tzw_TR!ve6HYFANk5xb|(
> ZJrt
> zg-8XsE3XGQS<fV-
> BDIzNI{Pf+WvVj?p^TX%eL{w3Du#6xpTpK$f{b^ETm<Jbc;}PB
> z+oDV<0ekgtG%>shp}Hx56-
> #2bJ>uz$a)s=L80RJ1IfP)#B$CLM=%33q7nw;jH(nOu
> z`5^n_?WIZi6@D0p(IY=>?*~8p0W}?PK2$zFxn(lClze6<a=riPT4M(?LQpgm;3PN
> V
> zUv)ynO^ETiwzNvdHYB|NXf3ktR9TZB1A_bEbF+@dC4$Lkb^z`7A2q0wQRS+=L
> ba(X
> zpL1hKCsM(W9qLD1j2-
> @$<@Sx2xe@bag!*5Oe^lg4{sUPcBVL~Q64^6ZKY}<1t%qQr
> zh=<$7YcYKF>yU_Rnc^1|`5M+Rqq=3z<ksf+70io}<}Udt$%0ws)^ar?b(AxD>8u
> h}
> zV0X}3b({2_w>F1h;JkH>G{m4C?`u$>>UuE;h%2;rw^hr+y+mx`NAAWod)O7mi
> $r(J
> zjSm3e=C7`hb>BCow)9cPRNlCF`)<5)(WR@MaF4pd*}ivYbrU$|CwJs>j0b_pCE
> Gd3
> z;FxQXM2>-8qW)dW>{^z+h-VV&Ur5-
> D=is~<a+}VK>D+TSL$23x<!`_Hl=m&`Yaw`<
> zv9pVeIw${7JnzM^FUi54qj7RC4ll`p)blp*k{rawd0!4Q1+5jEw5_FX!O`EGdI!v(
> z{<%5~^<{KK#yc;^3&?>hee@Sgk2U0U)P~1d83e3kU4#RXf8}kgf5rV)I3{X6`~B
> Qx
> z`$C?$)a0CW`#N65pzITk>F6}-vz%{+ox*IQibZicDhi4bSCTs44BJbF<blqQo|9gH
> zxp{STB_jHa2lV3GVf<oP5MK`CH^lhKEVSZ|@WeD$bs$}mJWpMjB<AJlSo(rbS
> Cj|D
> zq^Qd&DxU>AD#^2?52^(?k$|bCHjc%ZxgejqbEr6VGB}F4)iBhoWg@1M8ipgK
> S6AfJ
> zlfFpWt5TrU-
> !c1Bzs4UNwInjCmcsm6^o=LD(@|f|TAu_bKaP3Gt690t?%Q~FWaBcV
> zb^|L9Fuo7Zm(RHEis-HLrrk7yN6~oE%%RQ)Y5sM-
> BGrvrz{w(zoTHBNQ7tB<Dlo#L
> z!@sJAj@u38BdQ2Z9QV8sLnsxy6JWU{Uap90jbc60E`e)G<kGkJwkYI@K-
> Il}v9pjO
> zcmDCv7%wFbT0dAK?3r8S{hgZVJ?W=-a7^&|iw*2c-
> 7G_d%eojZxpEE5V}#^Bx@ZM9
> zR)wq;@m!u?gdJMlFafavE8QknpdV$pXq5dNE&zreB$8vKry{Lj0ak!;sK1KoO_
> GjV
> zFjP8@$o7*+&bW=c7vuIpOazv?J-7ugwyiY*shvQT{y`AW`Jc4V_7-
> f70q&#M4RPi0
> zzfb6t+mXUNky3>Lw}sBr&~aHwVvC9skmCTMbMen|vr_2nfzZ*%YNID&kM<
> sfu#UBU
> zio*8n(PEBUlhemz?dObpbL+61dx8|!A98z57EUlX`MEt^{9dFxj2j)Rj{eHdDti(i
> zueNv>;t*lgbPVHf7t1g!%jb&p#Zm;4@!B7<eNOJ|g<>06;Cs0R4tk;3YKduMQ>
> gyz
> z{pR^<>}@0EAo~RlxlsVOjp2k+U(mW&E$-
> W!1=_zTLJB7~Aldox3$<Bb2o8&5z#9Gk
> z+;6kM)Ki@VwOQcaqisNw|DS5JfOjB#5BB{Naj|+S^#hRl^6?)`U{2y<`JiOGFL@
> M(
> zT78#5bV!f(i*Tnb@0A@UAC$y*C*S7yp(H*pC<33~u802UF-
> u>N4@$zla=#!Sl%%sJ
> zmtpc#k#I7;vy9_~n;&^SKw<hpbyE1*uSw6a9T-
> 7hb<z~o^@l`{s4VZ@&4N%QA|vb@
> zr*6*6Zl5QvUCz8Xik+ADV(vDkufp3~fIaR*;W1^!eBU3idT(kEmBH`uhr8_f`IQI0
> zoy#G@AD{YuFXiJ3eS1X(W4pJO<rXMv%Za?JdOo97@=rUGl_wykz!I?q#Qh(U
> IJT)_
> z&)Bn(BP$@jq=<6Dqj_16HcD$Tv(6X0SZ{~iD}u%O9`uFeA8ahao_MkuY!G2HS
> O&BX
> z95y@LW;5YN@R4%v!HK*u-
> C?sg6r16D&kmb`3vvIC&1T&Wn_1KuylsM<8njBAi243(
> zcIH;aX2oPP-ss#NB-
> g6j2^E`}^(;txMT`zDuS$WhN`G*hRH39<aq42|2AqipOLdc_
> zdcyh=#BQ-
> &z=3(yynz0wYIfI1H7Q2SQ!n$+Lr5e4+yAp3jx)>tA5CqttAOmi{yyTW
> zWgo^b|GSzus+w#u9L~o`+b>_8RZOdl|I3*ScZ=$Eh@kU2w=hBsQDTYE<fU!*
> %yFiK
> z%!g0>{)twNj#}(Rg<yV}12711{6KAaJrimd4Ha|$E6%?tzQYj(<zkoUR9?r5_=BC=
> zB^TgzEx;ldZocbG55nz(a)mg)l3*F_ytHWnoDkHj?t~i;#{{>K;k!6;>)XkEl`G;#
> z;flEWqxg#b^}O@|fe~EEkIxw36CJSnc;Op9^;rHb)HqUV^eVJ(Lm3BcV*=CNl0
> M*t
> zaMl_AZrpG--)Br_&OhBQxTXJW1o`?q^$LvSVy`KLZ4}sm7kl+U9_ov|fL-
> =tuc<6|
> zmnz4Ly?BcpZ<jL&zezWVi@kUm8*i6eNVvWaCyk4}cpDur_NpiRJe?nBepnAL
> _F6{x
> z7c_jBaUWkx)N9TSZwLBZ=#{$RO)mE08w9kv*lR88*tL+<7~qDtbxi%Gq<R%Q6
> krCB
> z>cS4j2Bv>kmDblvQLH*w%UNdxx-
> JNi>YJH!y5w|&>aBc@s8^tFR+j{g?SzfDE3<pS
> zFMNR+5MAs6(v{V`PL0Ea+Y%9B^j3$Ac9t8W%7N<osym<2LHN7kv-
> 3JNp)RRz5&oKn
> zU!<r@s`nATRl`qK^^ofQg#S##hZ!D*h#pX{s?xmc)N=8yuJAQ`E(nn7>?160`D8`
> d
> zC}ka2N*#*o<njt0<TkNcubippODe8_=;8gQJ*lVQv*Wx;!Ga6aKrB?^K@WuN
> U7w*r
> zGLbQzg2pJ;^p6D`-
> IDZqs^G;3795>d5H}PV3t8|fRZuxv*n%YXx)YB+m_057r<p;-
> z41_aIk@2>OiQMwJWjKs7T$zX`T$OoUY!D_BK4?Zc$LWvH{^$`;zlex(5j5JC!g%I
> 7
> zeiDd$rM@FY&%w4HwSRCxd|V&$Qt^l`bkP=m&ZYGo1P)|n;`0n}xMuuXc%A
> WBv97#f
> zt9mm*%184x^k6a&U4C<n&R_iL8d#GqUY1S!#~ZT3QUzpfCjD#4P{j=VAX}f=$
> Y*@7
> zVYRe^b5W-
> m?pYxFSK%39iXr=wZDWunY>h4vh}r;f2OAY%4{Pyft2JE&kznoOi{ife
> zM$|9Y<kpd1EefIWyx<O|!HNk|-
> y+3%040_%Lk{Xk8~;Wvd=3yXCKH<q#6O_p5wZ$d
> zG;n|!Kjc6|V<~GxKjq4Eb17>IT63pM{!|O9K?CLr_7eNy9+aZV2`=16&@KpKA7
> o#A
> zlOP!V3a>V|`cOvK&tOU;>xa3~r|XtDS&6RyYUagtz`lmd*^)ziU;S74&KoQnN1;3
> n
> z;8UcEDR_x@74QqpG?g)!Pi<mz9Gui~Fb>qWi)|{!w^cy-
> AnM1}EQW3E<6jJ4!VJR4
> zfS&$&ge`T{@~B(Kj`4*TqZd1>i}G6^4xkJ-
> 5lBpO^P|fhZPjk5FBZm{MWO~;)TSqD
> zN{si;LO{_Teq`dAJnN_%^+;Iptrha&30!FI@DWWd>-`&47Qa>GZ--
> %?Gw70&#75td
> z^Es6>U1}`jC_g`s1>G$}VBe&VbJ+L$Ee?e~g8YF@Q4wqJLvZI$snza0mrhbMlz5
> OB
> zbt#jzKVN}o#9_uSm^O3vv>Rs2?Y`NQy=o4_p0UptNu**Cd032R321yty~@X*
> XcXWp
> z8e$dk#L~BQyIEm?C)9^}aKUHcl8+c0jvfa|62HT{j~~<X#20$@VUsWJLb%<%Pv
> jCr
> zkjJd{I3h)rNBC7k#NHZcKf9Pz2OgWn9sO-+7M-Bv19OzLfr$`t$NX8Gj-
> s`&CG(Vh
> zl*Jw^!Q6bsg{+y%KwtDE5sSSX3Tv62sLpxf+u8f@0m<|$@Gy%4UgTadxCMe>
> arziY
> zfqjT(>Q{(NG~S!=(5>QU8!y4+$rqhMH@m-Iz-
> LR?W%Z7Wc7bVf!cczA#GwrfAU$uq
> zCM*0@xQl{*jCAp2Oe#H$j6Yqfa_M0V^wYwl&}a3?2K3f~!-
> *d0&7)<9a}+mvmVCsC
> z7Uicr3)dF_6NTSr9bd202iD(n;CLQ5kXnTZGDq;d8E@J4##=;+%MrdGp;N-7ya-
> V`
> z%XQGOwaI>kV#9Zs`l2)Cy0{yuE;xG;*7Iudjtnxtn~OOIc|aE1)_EC}*IdemF#bP
> ~
> zX^4~~P#*W#7RL8p98+w7@CG<!mfc(?eJ^6j*qbAajliis?=TVb-
> 5Gi5|3U846_y@I
> zCvr*!t<VO|r&=eXt7kqX*y-<;{9FifP@RZ1&#y`qht!E@tddsH;ZuwaluxI_`2lsa
> zLeVN4q9m3~sS6?9pon@x))$2ks9X-
> ~Mh7E$x}&=AUnG(Y(^ecl)H1&k5{eUpmkysk
> zEr&dszk)^|?}GaRR@&6C48mty@fFLnTT$Snsrsyoo)7V!Pw$WQfJCrG`qWRC`s
> q|Z
> z;+^Su1!a|DH5d#y_^(yz;VW(8oNRQHIKysH#K9MCX)gq={=ovk$G+xLdDWG;
> Vlch<
> zp&@9!Kg`ztY$sS5Uvz?}H>*UtDp#|vzm8>bJfnL@b?G<Yyzi(Q@i9`=S6gJCx)*
> a2
> zatF7MCsn{(t7<Sdn!xhGE;(Ndm5B-
> NvF)6zup0|Qn4AI&0E=a~@xX6w5)B%$YI!)<
> z+EE1!8nAZ2SHv8`hi*iFw<3bakGXlwrJ_N{Q-cPqw(&}X^49gPL^U>LLR5%-
> gPOQ0
> z9+J<qWGe|mjThfmg7XEkG>9n-
> L$X3dZ5Pr|u}m{4OMD+kXW=(oa1NOp7_x>4a#DkW
> zlaTWsr?N9}u9zPrZlb+Xv{k9dF+YJ0EV@3sQqlG;#bQ{KqcS)j>3v#9PQde_bfnD
> J
> z(b)g7d(&Yksuyk@|2~(WcKH8}<JMhdCZH~hi}-
> dd?9<)+b`U?|g%w9xcCe08r=X#M
> zoYOWk`QfXCt&|<V>cgcI46}Od+)z+`SpNjjtnntN46P7CVL(x97w%m5#YbXJ>N
> o=~
> zzr7knv4#qZ0w0MLVq<IR&0yRq@F~C&YMF^El~7-
> Qhj%bt1$$uMR?l>p6=T6sM%&)x
> zgpvw;#uRoay6ZA{wFfvNzSSEtTwSQQ=NjQ*IUI$tU$U(WIdH(Y6>04%E&UZK
> Ci&4?
> zycPETQ#r*XGb&xOm1Xh$6_tkCq~q>H6PZ!H)`AeV2^oFZ*@9=#Dw|ClfUuQ
> VLiQpL
> zKCSe|(Z&bpt1$*7FltDL&C1skBOTofTmNx$wlFzP3iE-
> Nk?djNdKO;I!guMy;CFof
> zv4qTS`wiVNk~x<-RGj^|;G9OSWlu@o^eA)P${O=}Z1L4NPG-
> wC>+jcDF+G=@4n$y6
> zTRUWeBG_vcPX;Jxo%6U%aTyDKM-
> DyNDj;%;M0WZr0~zclDo#Cy1r)LQmmf(S#Ha9g
> zT_4{*8p3rork10ul)Vw}`F#57VTBUSEHV3`ukQRMv9x_SIA~y=1N2q&M4+4_e
> H}+;
> z`FEv{P)*v)gGQUJI*CTo_mj$Mob$ZAYn);X7hw>fOTXe2OI;61K&c{g@0;@BC`
> X6!
> zYvEXG(+bR$Ep$2xo!zPw*vxO_kPPx7$37EjjmzKo$y-
> PO_@%rLp+7OH#HO*xm;ZkM
> z`Q&v%Du?!9heCzDwiUiAQNROeZ&Mcj^AS=7NO5rgdEYX7Ku$AyI3YfUOOS6
> X^g!ZL
> z&S2s!PVK^9j4gyX<jYc+&0-
> FGCjWVy!TKnS2JoNngLF5_XJdL!z#pp%Ye$@8^q+Y>
> zi{^F5-
> vb_0Lbi`<jfqJ9l=_H<!*<80UgrAGGdSV3|9lOd%xZVMt0Z=|G<CtiO`$%D
> z5%6DE(0X=?G=&>c>WS$N@vJqKeu7@4?iTBTJ~nnBVV2m<`RXCuAe7)^+dB
> Fbq?#+l
> z$9{u8wy-
> M(Fa&#02%Jgn!IW2fX>8v<zI7bBzB_E4A=qYp?2kl!Sx{fvLV%AA3!y_<
> z2ynG&A;5|DAfKzP+RGnqXtZ7B!?d&xbhM4HU}7GwuqQf%;yLyNGHQDQ&U
> $;IdL;Ve
> z*b^Oz;3(P?eU3fR5#KgCY}H?(#+LeHoVeTVYACfmVTG(|I!nZo&qGpsWbFxi&
> >=8!
> zK0xJ!N4}Y(alUx_jz=ys13IeUXAV7on(L9T`6bMal~?9?<X7Q^6I|OHk1>O`H#Xq;
> z6YPx~`4O}}gFpT{*w+>-
> G>zpy$QRmC`}^agY=3;@fd2T%Tz?JaL1PUOd3B)w<^=rq
> zzsBnSSbzLU%)kSvW&7Xp*8gpPyi}t{dVdao{1e7^RPOlxulnQT4)n)IW54EyGSv
> p~
> z$NTTLQ$DvpzA2nD^1{!b&%W8ZmZ(S=$+mBP^r&F>sr~U^N)?CHu@5##E8>
> rLQ#w5W
> zXC`0AHbQ3GIyU|3{qeJ$##6ce_yeIF@;Lr@C)NAC@SCAgfJ?4FJ`)A<`RRYmAH
> TES
> zCeF!5=`FypPHp9c$kP7!Y^;fZHt@%PBpNl(AHVpUj*FAykF%@dk5>egj`>{vIM
> wUH
> z{PDK9AoXeeacdxL3%!TH^bbLMF>&COYi;`(y?1C^n5J3pU9@eU_YQ4))MTw~
> ;k`rK
> z!Vf*bdw>6HnpmIcy+5aO`uhg--
> g};cw)A7Kr@hZ`2%agaCBEH<RNHrVH6L1+QUS{R
> z{%`l+-
> ?Clwf&BMPcB1XScQ^oAYN3%ZM9i8|@ZZOM8vlKgury?Z?Y~bTqpyV1!8t#I
> zcJ+Y%`_gM1=B8gvtI7<Gg8x45ApU#%-
> %;=ANivN4`|oSsL0XAQv;BAGxBd4ICT5En
> z%$(!DzoydY(X!+F`|qRj{r8bU>uQOE9mIbh1jogg3KAHNq(lEr(y;d5M}@89ata^
> d
> zzk67CI}7))@NaZs<-
> d={jCK6?ks4`YJd&1WeA~EO|K06$D$jrC*usD3<ahk{*J=bs
> zP~;H)dldK1QmQkSqW$**1i0zy9MperFJi^{{(C1TSFTy}U(j!_E0i1`68`%Zg_729
> zpVfbFzf<~{=fAI$MnnT1%zwY%DVFu$V@|Pr|NTpc^53hng>wD(pMk9%l7U`
> 1_V@pq
> z|2{*lOgprP|6Z-
> I*R((V6aDwFRB=e#;^I1cKu$Bp&B28DDjXMbp|b#Ljeb|MDF2;*
> z!H&v*=OyprUVbM3eUSvS4&uN604my;4MdDJ#HK>6H;Yrfa$u)A&wrommx-
> 48P<hOD
> z(Eb|uQ0UaB_TNt%xT!q<y;wEHuVxX`K@vI8{yUD6xl&lv)obJkSmgQdAV9uPd
> @%og
> z#RHna1N-
> k3SMcAD+s}W0lP))Jxcv<NJAC)HsuC0=qQ2%8qY$T1+jp@>u44;{AcOzR
> zsGN2B@$HFFDfmHq)d&kDCY8Zi_xCB|3j-
> J5S{|}GE>QxIO97+hTdnP2A=FD>okA7y
> zU!5gj6=6}HYYwQ@-
> sF&_JaU>UCw%p?TS56{;<`J&y1l<3a=$~nU+4PjlefUQurAH<
> z)qjB(&i<rY8<@fj+E<^7=R^7G+P=t<7oW*rKTEePe!Be!@@F7_z0CI4O9%AV
> OLOgS
> z@z+QH-
> {!9uVa7R9+NRe3IsW?e2?{;x+t1;zf5P~d<&N+Fs=q$^K!3eFXf1e4rrQAi
> z`sCZ}l+W$255bIgM*hEG&kR>9+m23!J@XF%+3OLXyng<%tp6TTr>0}<Fpl$M{
> k)12
> z>TPV2%GaqKDaoR?q<ngReTma}p1=O~_#E;${`zRDrN4ID#LxBDH=#g2KmCvS
> >%WiM
> z#5viROX9pBE;e>r+y44ytipp@@YkC}gXa0`_XZr7CdXfASH)kSdy&>NpJ)A?>hx
> g#
> z`q2vQ&*`s2!8zI$td^r)E%@Fla<8>3GHUG#4cH~x70$VA#)CtlwW}tTxC+p&cZ}
> 1$
> zhKmC2ie>XIXjgm70?jq+DxD?JR}|=y{gSBF)~?8@*CmkiOFF0W&7H_V(KfZR-
> uNuE
> z<IgV6`sTObnR8Qo^W{jjee>0L9!Ph}{QYnD#|POf<OBKRuQ~3wUQf?B0P%@
> w!eA>o
> z{PEGB#vgxLSQawC_Q%(dk=+v1IFvvB-
> b9Ca>5t=%5%}X}@W)3V#2>FX6Nmj*Unrxy
> zzdzn}IMNoYG}|9%e%l|PkyFfI<{W=~qDniMKVFvakCz6mof7>yh(At#H8z6;Ml
> b0w
> zTP;>=f4nSgnK^|I@W;iOA3Ya^r{a(GWnEbL<K=Xs?e+AP7bq_0P?aKq%%1Cy
> M|FC{
> z%5pa7%dv$&F0Q@3o<31$J)}S0ofJ8g>yLk1){zh4k5~0c8Sc?_*3&0rLOIF{X3Kv;
> ze}&XKcCP+96Xy)!gMChayy{lLH_sn0SDi#72VGAe;uOpJ<8KPNs2KD8@xY<{@
> %7n4
> zx&HVul{q8>y>jg9Pvwu>`Ek6n1jjp1pfJRSzJkia*x~wlyt}g6ExQ_Tw;|rjYOg?U
> z(wlpDSAcUG2BY4O4D)N4om|zQ^j2ekGq!2sgM66F{mIfA?Ed6N$y1=sz@%8`
> =QroE
> z=FbAWaJh6+<u+-
> ;onE`XKyiie!#UVrv`cPwIN)Lky|CtdARH{l%X(kME}wRB*tj@{
> z5D-
> GL=%uF!2NrmPj2DB7Syb9q(EF81IIxy_g7Jb#Ng^WGEkqB;r3(eo<M6jIIx2mE
> zv2s3ciNHm;RwtI1!BIG|a34XurRF&e8fmN{i1)iRYtV3GtzGaD1tMycY{R#{UAE*
> 6
> z?f{POb^97lWb^*MN`Gd4^#RGTFRSmIVGqrjA?r_ShderfU6!vFq>sR4Hw$^<-
> BrX;
> zSYNss+bmz@6=+x*L8m<ODRSsNsXlsO_0x=Xz!K^4)-&-vI=lYp7-
> K!*+`EHzZ*bsc
> zMhoGTF=vLYNj6;Lb0jJ<Jxg8}gs=@E(3h?^Bc)-m+p9cn=cROlX!78EtoY`ovg^Lx
> zwP-NL;Z%SWjnv*So?WPnWadwhTDPXkP%(-2kvn#lu{j5g-
> !71WamX?N8XFFRhUY*u
> z*1)*>)M&KkpfT?Aqk+qgz*>3KIOemUu`>sar{ti9tV9Wud<JUp-
> iQ6r_#Qx?ni{)u
> z&^Yt+qcJ}p4Q}0rbi#xM+|_b8!urbO^85iN*SY6P!~#-e><iZYIG`KfehxNkz4H|%
> zDRu0k1X(-5mP1iPIi4p^n{$)%VOH%ji@Z6+d0slNF?<}v%k6Ie31kd6`fF6+kF`7~
> zI@sC#m?5stX4)PiuJ;~d8kArkw7!^ps9UxdmLjACIm*4Ml&y;Yd8h!=w5S>~jC
> &(}
> z%{ZgvtA9!41>UfEsvCxR{B4M?Zd`pZ#&^#TC9NBWOkBI=*6-
> Grt1w%85LwdFk_X|O
> z6OD){^<v+40a`Ci{~Za?>B%Vt*a_Q{s#VRvmdln5^vbC>>=MVm5tOVhgc4y%
> hUSYB
> zfu0mEV^ZzG-
> 12R#!5O(eyF8_pd|DLpNTU$1>vKhqXP5V{xk%NV{vDFg9QXT!3aNI?
> zSCB%&V5q+u$98h+hq%J$+96^iy>eXyc3Y$V!t`5C*WB!y$x8T{E7TAu!AZE-
> G&F${
> zxR2>3&HxFB;=YW_IH*{7DC38CREAS?GGJ#<pp0J%IvdO;I~uX_SO5=0fXP}`g+
> mUh
> zlhK|{gk18oW4?_OCKX6u-?Do;i9MAa`8;8m`ZHMR;6rHFp++KG2YDv-
> V;0S!77ns~
> zBDGG);}E-gH5_lHpU*=w1$Q~Gflo6W12@1+{xDEE4M-
> 2VFmaq7#J3f3_;wK{!w0^@
> zw;BqHcvKGuRzQ7Wl3(N&0+$vP$yd>YOYxo2o>UVv$gCijVgpbSPfqouV_D!v2
> RPLM
> zqJp9tR*;_j$pdoOeuFv;1CoZZ!)Y8g7Ex%V#VPlsDiDShv4+Fv5MAe-
> r9_vfy~<UM
> ze+%)i1OJYHvC8#3{2TOAmFp(_+lhaj`1ddTI|1{2EdJHt-*x!668~HUg+=b-L4$qz
> zKhKb%_M`kB<{g&zet0%?C{H2}4|bliA0&ig*n^QMZ{stDsWfEmTq^U2hPdnvg
> NyWN
> zT;_os!|^q|DBPTpn`bE9>~J_l-
> uWSG;>(hk7mPm7Dq$x!FXhJGc;*ye!$xTZARQ<0
> zH9SfP%)EsLuGG3uCC4|(er9#%kRsIHM-
> S`N2wQ)=Q8y90IeQDqximtXSFj~i2ac%0
> zU9n#@BiJ$6Z#L35!$!YIIo=Y5yeTC$6x~Rl?p&G>`@$je{zc*C?9zi#c7E9U)=N%T
> zRWJJWzFuEFB5$B34uY{)Jdt%^FG@a3FF*ozp@_$>M3iMalAf?%FAkNrOl?*!
> #rG_i
> z2=er4N^!JB-4=uMUDVC|{1}8G82RQibG#Mp-
> yL*+oaj}m`csqGr8x^XG1^B%`sDir
> zxKBY2&(tvwPY@{^!1XF@fV0sMw?yzT*@s_JjhZ|m>GB{sqt`4-
> @qFd9dHP08e$O-i
> z#GmjxPu7$Bp~?9pr&MU1!dJzuC&l&uA8Y3WCv{cz|Ji@Az``uJ2r4NiDhd_;DK
> X60
> zm9foOompAaGXDaNh)TFCrl5<%<__Z~n)FclBqbRZB_#<M*g~|RQlVK7B`O*{
> eaG2y
> zGkjcii{JZm?)}crE@=Ip*RwD)-|zi<?z!ild+s^s-pgqOTlTWvuPCWbGFx-vu7cbd
> z7WOEbZl~sWu*n%`A+5z*b`X*XzUM<4dKPbej*$9bg%2Uq9?NuRK_*m`WN
> ON1+FpF_
> zg)_Jgg3ZX~ONY0{aiM301JCW|It(-KaF1QQK1iKp(-
> DE%!&S_L#A2;J5nSuSIp*h1
> zU}n<iXqleO&}F=&Tf3-
> ?m@gH^G+T_M7h=9#7}IJoT5&;}D;M(CdIw_{vZX2+=_^xP
> z$FRTFVAl$fnUK!8WMTnD7`_kbUxsHSKx?&tB6^nXoswvzQ#ovV+ch?U7q;D1
> O7kzm
> z|8;y}^9Q)*UyMI|K3um-
> ma`6Fo8J}jV1^3^ba>X%n!&BrGxa>O^&Ie$IGtqC^|cox
> zv#A|f34XS+ofi-
> O;Ecq!#FUpj>s><ExkkHvhxI1(Aa<~4lH*NUCyK>r`CD@_XC;rZ
> z>9i-acpSk~YEEw&Vo-
> FY6PM=TJu)Y=M4ne4thAa?BJ9uIC%A9ER6^+aNRP=~5<&yb
> zCquBBNeqGK)m(}UXpEC9eOnNb9n7PJ45rL0>VxZ<bm$b`)743`q;5&7$a)nyv5
> _Kc
> z`3g2TV=m`}j1KmgatIhO<8&(Rr<Hbv(ymq7yIfkP#_h%DUv%LN;LOw}K?~p{<H
> 5%+
> z6VE7RKgO-
> bJT$FW11!f*m_+><mDZ`!%9|+d?0n6Y!Bwti%TZ}L(0z|eUaA~%5+{?&
> zQBja%Qb7*X4LaIFIWAL<waT$WIsSlU%3Q=cJ^g?;ziH$F52PqpTk#%X>=Y`i;0
> @4k
> zs80bulY&i?RT}tlggPp@K(&p&iP|Rd70eB5<0{2-
> V;9GT^sVFTgZpkV#Hd?szv=0|
> zsy^kr4NI5wui|c1F;i76R272?tGIB+C#YiaR_%geKV)w$?WK?bvmtb~!9v{t)n3;P
> zjD@h7Ha-
> vL*T!_l$AdP*kUMuT+VYsO0;V<^^mA7gh)|mX1UYSU5sHJ_g|4lPz*{Co
> z#DKV}b5bIR<H#maTjB9AJe~+97lhA<G@fr9ZALt(EU3I`va)TRfj%Ovm=(r;tGJ5
> +
> zW)=V1Wng8%{X9$vRF?a3b`nptCm!r_mMAxcJbGd;5;O_;Kf}jC^8;(bvh3f~dY
> G}_
> z7l}PDG%^G?c^j8vH48`B?X6fn*9RBpV?EuS;hNy3B|Lf=xaDCV&iSHY?@)++&E
> +!$
> zvLV<ZmYoi7no8awwlWN_<b36V@TxEz0d9LfygvA;d(K`KV(EJ>V0+AVI5?L6r4
> vGA
> z9ST1}%H&9+bc2cDvkrVaKdI@%hW8aW=Uc?gp%W`4IHI+x58mfngftK=wmG
> 0Qx1mqf
> zL-JKy54|hBR`?0|c~_ZZ%u`_3i?_Ce;QC-
> hFBJU=_CFlV097A+f4UKA?gy;Y%QT~N
> zpU1&PDxyC4nHhH>{rng}4T(05F)%GGazFiFSfoS(_Fo-
> bq>~lq9#mwWy8q_#7<I>t
> zv6nh1olx<L%URfPMbrmJynB(~EGY7I&Un{=v4-
> z6DDOVFNJZ2K9XI8B)Z;P_<);dY
> ze4wC6iSJOXrn+Q(5Od}taGct(gd%OgRAlbabA524i**Ba@VJonL;%+RhhDF!uy
> )oW
> zzjwenM8GyGQd^N`4?76tJil7unrYqd@8`|^*h<5+pD8TuEGrF}=NC==5s>fs^T
> N`+
> z67)Rw9x;k?Ka{W&OgA6WQYSlq=(xhBy*GWc{%I6%l-
> {T@5$tyWxM4O~BT%P%ey|s;
> z{v+*C*A94VJlOt8N8>-
> Hw8dM5^F;7qVSyOs%gYoV51wz#x6~IYm8}ilE5ai8BM&*7
> zBGjWb&B90{G7%HSLilx9a67tNuE_@eg^6HEZ?VjfuX@=DRen4e<cqD-
> K?LRX!64%c
> zLLja5ROFU<2Ws7fqVTy!U4+lA5B{7F2Y&bLXz7V#`y>2c^0SNsw2+_exUoM<^
> 8BpM
> zHP*0vO32R~53M<<ZcooFtjbf}BNh%qt<SMUqi*|*4%A7#eX>FnHSxAu7xf{9
> DC&~i
> zKH{P-
> Yy5zV8rwL|MIGCCl#6<Q;|LcuzR~BpqIcUuU;l?g%I990WrzLs*pY^`5+R~X
> z2Vq@AKVsHFL1-
> 5D{Yz_$nqR&>`q(q*Zb(vM_shczr3VRghXS0%taOdTW+Nu}Qv<v0
> z49XsVIABli0R|n>J+sr;aw<7Ezk7DN*okJPV_nbDUyD1%*Emjm9OZ62gJ*9w>L
> }A1
> z1%<`ke7?-
> *&PYd@RzW<r@u+1FKU(A18HOzjDWId}R=&Bb<reqzMg90w5VptGQ95sH
> z-
> A}9gX||u1c}mG&N6QVC$L_dvQ8Rti_LfWilMvVz=cS|N6MS<$(0%o7v6Yh162S
> ta
> zlnR{~Y0FD3jAJWVg2sdCta_mzl9>e0Q8GyIgYB@KY}>KcjtB3eLAI8@@7gCXO$
> 0~y
> zEZjR@GuOt<+<cbLkcG0gSI^VQm^MTk>w`C)Mbo&*!gvt)*IwrEI~NkXxGW
> M0j<~l#
> z>#Y?f_rHEcLA&*AG_o5SiKcR6tumvN-Q1VJ?#2Q-
> c@AevI}!jN%Uw%{w>G@w;@h(W
> zn_n(!t$PuAev$R-P{{eEc<^^>H6m(Le_?vOjrf;RZy&9@XsjpwH9_js94n)`mr`$?
> z)O2B6!_)P_MZia9FSReSHQoh4N6}BGx{q%90C(poAM3wLPavKybWh=OMa@
> R5&Gj~V
> z%!;5LR3Gc{q|Irk(IsyVkp5t#`s3PXF9n??@wp6$*_ojVazt;BELOG`$1c7gj*4?>
> z-Ak>twnW-mnO@%Li%z$k#Z#tD->K|~w0qdB*Yl%y{=F2;F4qgHv%Tfj-
> 2K_o%#TzA
> zyHZ<<VVs>NrGE|!lNLWMDz_t2<P)%Xx0*~Hex^&4{U(J<ov_QP6Id>dPXuFJ
> B;gIa
> z#Pk6;)qZk3DD|1Hahdwo`sdMBt1nCo5el1_2!8Ftt*8MiD!RUQ;xjKNf&tg5e;D+
> g
> z>6%H|k!qc^<GYq7id*ADv!x2~O&I8#KpT6TaFZ)I`+P~CoYCx4eFKJNHxj^Ec3L
> OC
> zPH!dGXj!#G%c>u<fOhLdB&^w)nu}(qtH)>4q}Tr2UaX?l8|bT>tH=;zZ8p3U!K<
> UJ
> z9PUigaF;RXyBZd<iO)-
> &iL%dIZB31^$QoYCy;!8pxa+z!f}~<dTyIEma?FL9<w~NN
> za=ExmrbXX*UBfP!NzgT5LhH;}f^?!bcXY<xyKBsvh2X~>nq6(VW$MeDYsDK-
> wKQkX
> zeji|xy<ykVngOlVh#IJ|6X&OwPgcd7^<A-
> GdZtAW(A%Uz)k@w`eL+!fDm~Xxb3t+L
> z49e`7dO@k~Yg1G?E=LwMEQdZ)QNwbFxu|H)*V{41uvkD})8oOa!$T4h>ZNRg
> pr_Xd
> zce!v6dLtXrIgpX*(JPRP8jtH2azYb_z4<ibS&kuuOfr0o_5?UR5qu)2QS8W1Lo#)9
> zJdc&}K$lISTj`}cKemb-
> DB0OWaxHD?{Ey^mff`d=PUn8Vk=6=gtLDoyyr7Mf<3YQN
> z%^ptyT=4}~JBmsjRd>`B6=jDi+>?E&Pk=Ed`-
> bSrh`*yaOfZ%7FDTrX6DFu3{Vx>m
> z%PDaQwpSOa7q?fJ=_mW(!6k;HuPAHl(|!!3&*<x}vR3A<2rDU`gFVfSnBFn^t
> WWjP
> zFjWcH7#@^rjZak-
> rW%B)%D1V=j)lLRd+0Rbwmf?q+9yQMOa7|fgSqcZZN8KUjqMc!
> z8QbLx7~5m{3VwI0K`2A2c$m$~@nGdOet^}z2;(2<L;zRGsN^?Q!c3LWtP<|?C5
> Zir
> zq3tv7cv)D2W}^2ueZ~X8I>%S>kEN;tY(Nh)(rp4Svs~Zx!5v8#r7IY|nzm;zb}VgE
> z`<k~Dwc11W8}ts1mVhF5au=^&T*0_u8r$~98)XG;x-
> OJ1+9YH!X!b$mQZOQ9jQF<d
> z$e&njbKs|rfHE2|CD&A@x=T5{-59}#3FXo?6#-
> s`CU*z{$FWvXOB(hqtr^~GLX!tK
> zJE&XpP~A)Ew$sUyS*~x{fZfApy<Qc)bN6Ubp<d8h?t^)7U-
> e9W7&ICdBY>1e44a=H
> z9$}s3$D5qpSV-
> WAa*q$M%ui7)C2#=!q6=q`9e&d(ltpU}Pwg$C(XG{!$jtksEqm2z
> zkmM*=-
> 0AEma@oEm4KNnn2lXq);8nsE*%JX6o!|Ii2P;t61A19Q@~GrrMH{1UhBhYg
> z72G_@Q5RP5qI1u!ue0?LOU{+EeGlV!!%FfV_qvf$4bu0|PM=p<z%Wo7usr<1
> @UZP6
> zt03<%?tgLNVEIl&AFfJ3`PIx(5d=WHjhyU%w~qgDGc;&KirZ?{m1nOQMRg*8d
> yLC5
> zPTDgK?H$H2$9VuofSmTlTco$<es>RpV^_uWOS|7p9L+-
> ~RH|p%7jM<cQ=Fe!=>X?Q
> zo_6oCn+WbUnt`vjr_DHJ9d~#-
> wp#9ys}sQkj;7>STpwKJ6W6terxvyMo?7(2axk70
> z#+!xl0Uxs3+^WPD5&f<YTdk|d5FU>~kY=5~dbZx(b9*K&+acFZR_8hZ%?KcUh
> m`Xm
> zLF8ex?_o!(^XT+VsYRP2jq`}hZxi0+TR7zzu3BstKxHgX7#(gq>Kh}~!JELu?2Oq0
> z@F;aA0fl8+RaJVaRoKw3E(;F-yr-0Q{Igs)Wml^d_1o{Wp1<|>o8-
> 7qPRsY(7ox5U
> zdZ(GN-#+bPXo9EidsKP$T-
> 6}O=z`uF>e~G#O==Jcy6zYB=wtI0sQWc1)BWz4*f)l`
> zy76R3e5`Whq%%(NXLC`HGn%N4qvMxNBiyE!qUKj_k3P0F)je91G&O62=I)xp
> WbNDS
> zoLIuaY5R7w^Xlcac5=*4FIHjM-
> ?~_TDwIc#>>waV2{=F21IQ?$AD!=a@S61+vk)XF
> zRjsx7NUmsvK4Ysnf7SJ>T{RzU^@&ByA|QbDs$k}uD@30YzX*L!<13hr2@F}%t
> ^lw_
> zE-
> P7h49Di<oG9%l^jSI>=K<)`UZKxYu7K5Zd*)t8pQYzPpU}%tvr!q<5GyvBshyVy
> z<}<E)2{gLoe;f{c<1%#+sqJc?vNgKoYl>rFKGyniVM920?2fZ}6pFBke~d?sa}u1@
> zn_x<Bf{*qlII}mw<S@bddp;5-
> Sl@cOPmsC8js&Czztb(*EZqEIjBs<h8!AtY5MY}~
> zGdpvSs0{M3p<-
> bfqto;<QLE4`?NIJ&H&hs^!3FG8W7K6AQ3{;8GC2AemCc~tkXp1s
> zazIA?GWHhwWinsEuTHjp$;38nkDNR0+zX+Ukd!y1wzA3e0~MB_V0djvZ5fsb
> M!N7!
> z1Ie@qa_Y9rue2`6{$n`s*%4YYIPPLT$2*e#_ttFSxL<J06CACA<6IAi42G<U2ed9l
> z0EqYn??9)=D9S#hV*T_DX(GS(FZR1Cc87}Ht72cns6@5CRRiefu9QqBpB`f2*@
> pfF
> z{&jCZIDcsPx>fk%EBNNY1uovY8c^$l5?^Lf|1t-^(yz?*D)VNQxlCoA=gP!p(@{Nl
> zaCS>2jr0zqbVee0s(&Nfm4BD=2g*O#=a+lg+_cH1p@3L{3=o}v8|@eC8j7ITC{
> d)n
> z1pDt`Ljehf&;Oi9P_%Ffd0IZfvGdQ;CQkU+@VF~EwWSRCDWBlD`A7LGj?Gsw
> G9LVG
> zkX5nqa2tqS%<ora{}}Dpg`NE|zFVyuzmV2V<tvzoZO&GqU9@3o&Cu4xq6{-
> |%}tve
> zOs6t<6^f9PZjp5>wOQXK(L2o-
> tW7TnSG9v#pqV%{>}wQ|UX1c4lD_9Y15Z*?)CI4w
> z;QRBzl`eRt1+U`!ag$iM>oOg`DnxZ8%W^rC-
> G)K+U1chs@mX#S@F>=qfL)8Xs*3tx
> zS3XL}mCVt#c*{zn62VVg)Z@sXkbIw-
> ip&>`6@~h=u%^YnIJedqQCQRLe3WWBys)NE
> z`I=BE^slKnH%m9G_p9beUzS^}99~$>fq|~A$kJ4EbYV67T-
> 4+AZvSdZoZ_misRA9+
> zi%bGYZ(rt)4$wj2-
> fGZztXNB>1X4`6poGGa1%3dhGsa@(=S6rVF~Sibe(UV+`E<YC
> zr$Jbry?Q9s7mlvEFZLUqqXt2L&7!{*qQ5mPMn!*e6Gi<ptaX{upMM?Nx{L*l8q
> _g$
> zE^Z86+ZQk4U4Nc=g>5l_<t~8&fAv_`7B_JLvKVMQcp1*or!C%!JIJ>sOgG54<v
> %K@
> zxsc1Qe4$@kKCHIvR$IE%mc1soqgr!ZcBtdBeW=-
> (P${^#%KS>H`xpnWlLTG2(2P_1
> z!z&KNjC9H8lpHGb_KHjX=y3mM4ovOCzPtAHgZF&FJ82Q{*76lh^6=I%IID*qd
> d&Kv
> zTsUUCGI!|pnY}=O&g!bLy;0X*UOQ^$4wOiPZ%XY|QV#}in34)&?@HgH9?X8U
> Kd|TY
> z2ljFS+bUpJ3fPp1>)~88)C~)<fchXP4OxJOMbr%oftUz>>7oSUK|mi2<puqryl-
> $n
> zl>X=Q{ZM*?pxi4cy9MP7?|0-
> Z|KdLEl(~na*LykXq^4mTjU}M_gK?vzigj(DdMQA2
> zT^0$An~&^Y{n7oaU##jU-$wOuzJkl%qx!P`)uT)l9lm?@U!`!woQc61rg=ilS(jS0
> zPGZhCRP8cVyIR%$8B>!@BI~vnC8nJ_Bh#?X<c!kR^M?7EOLF}>J9_q`C6<_(vF
> xUa
> zoJ^U@meH9o!7`U58V^RfB$>K(CJdE-
> *%5rhIwuTum9+zUJcwVcaMs(lCPkkjTS`&(
> zC3v8L-E8_Uz+RhLv{qnm5ZL<!c8|cG<iU=u-
> 5yC?5TB8$TWh^m+FFfX(><59R!9BZ
> zA}#k?liC&(yY|MOO9gTTV|60ohsetM;4@+5TG3+gsWt;1AluwZdTl1wnywj71#
> V5l
> zbhU%#)CY?{ZO!r8;$K?N-maeID_CNyfeMBkI?{^N+s8#)GU`8gf-`70-
> QE#<gk|np
> z;-l&16G264v%X6f9G7X)13J`;2Ula8dZZ{<$#-
> #XFyEy)Sm+~6HWYl1m@SjUBhg28
> z+2BrG#W2==ZZ%iMgHudZrj%*p!bD_ZYnRqC?pw*1{ro`D)BgHkvQeoNWME
> E1Qr?0n
> zu#js%R%DoSGg4*K`|Z%}3cw~>3p|jq$B@x@ks%{D)}??E_ojHxQq;Q?RDe|n
> JCC#D
> zU=q}&0A9D2{mlS3fP+<k(7^RDsl(KpXy=C22M<SlZ|<`xsI)bHqN|i01ih8+vr1oR
> zFtFac(#yh1Ka{VOk~*p@N=%<~q*ZKEy|;Pa=}OIU^trDP%?b*g8(cU&@@1y
> &3apC4
> zRJyJ;cN`eJ8-2rYXK;kq?t4%!m+I0xU7}`axuoH_r8PzE!N76c!-&bK7cq~Q`OeDx
> zK17UbG%J)oFyv-
> fi=8#o>X8E{m@27zZfT;Z{ndfZuTc0_^xS!@e~!W#fs=xNngWLr
> zsI4R#ffvEilFLNZt3}m6e4j&o!#><l<-Mje*ejUY0AW1#n+sJp*J`oh;_y7y&`{xZ
> zaiN1t_!uh3QD;Ug@@BO6Z2J>1UL(}IclT|3S--
> ZwX7$5hjI+=Mh#>2LBb^wZJIRmJ
> z7PY8TEh=xOMSE<usd1`w_iTb{-kVrX5in9K7xw~V#KLs3kE}~;i(Ahd+OP2!Il$h#
> z7yb(dFZm@{{a^WJ>S(=+fuPxGl~DrXo>lHj^9@>~2G!D*<P~br5Z@q4Wc$*s-
> D=Q#
> z5!RKeRb1fI-de3!VH|x3>)v`JEMMzZ)w)u(Zcweuk8*_J(b)4Z(fBHod|T{k{4bh}
> zX5hC^Cqn-
> e2Fugw<>O(2nHGJgf}*s0*sRw}7o3r4(*qpvW;o=5am$nZ<j(f$*B1p_
> zw_vMW3~X;5X|Uyv$+2(CEPJmS%7{x|p#-
> ~Kg6u`WluhVsy1qW4uNuD0M0}cqGc*wo
> z4dyqB5PEFKA|w9kbjvsa+@^2sKynY}gn)MYR8~Wo<%(l*RzAcmvbzCV0zBse
> B`UMK
> zN#Qq($wMK#!`|0|$w+n+&)$0>yO!td_xbW{hFzd-
> k=#fSc(*1j@6n)H;!bCn@{SEz
> z_GyOR4Sv*RXDSF+h%Bd?V>2+{hU^7Aw|OJPKjvHS&}wd1Wv$xWG`QDi!R}
> H1#uvgA
> zc3&dywMdG|l|t?YA@^2i2+kX2ZXcDrTq$-
> dMVC@s;!=34MmDr+Xp$8n)Cb)rYC8Xr
> z=n`RsJr`!zz^49nUe)i>773T0ZC#@ps_vkMNqhxwI(uwr{4fs-
> O>s;qemONVtybiX
> zA7ylGj;+a9J`$B|&}|&(4kI}m)?#LlcFZ0(tLTZg>K6xGni$@?T)qd4)_Ab(IUB><
> z-SwW?0Wax754T%k?Z9f}gMUQWt#J9`ZJIvuxt+$ld~TVOBO6G-
> n#S%NzP7wN@-)x%
> zN#t^#xhVMnBpIpW`9A;rQJ!Tpl6*RzXW5mN<_Mkzt@2jze9jHm-
> `IHN^^NDwz4G&s
> z8MCgN$3}=7xrBPwCuc_LuACRUdEWe4H{N*74cF^R>d5&`*IhMh{spspgY!W
> bHeT5{
> z>$+LjH%2bJ`i6P4E|_=D4Krs&&S{!IpRj`T?7JKmOpRQ?X9=Huol_%=vr{7@_{_;
> o
> zjhx5(=lQhpd6dr%!uImnP1-
> D<J9(}oyqn+g{QjQL>Eu0*&rCjl;hp_WqYnNn88xc3
> z^x)vK0iy=80cuFasG+0yKWx;fXyxz`hm9IlHPR(MeA#WUQZJune7?p<@89S1Z
> 9WR$
> z-
> 0!oF_sd_K8cDwa?0oJot&TkS=G4e*Z?nI&XKLiT{{;4;>PXA~OpTnvXX{_5Mt;HX
> zF_G#>LrHaHCvmTn?hF5z8hPNIsgaY4t0Tve_k^ygkr)3qH8S<}sgY@A)saU?dp
> u?D
> zAij&VgQ)9K%J>qr;`Vrz4j5Q|j2bs|=rQ&;OpQC{Fg;g|JbctK$BgFbh$AiT-}^dh
> z%=;pi^5|v9bb|{%0iO%rq8$h5FFwEG^BkYQ09yrc=J*}PZ=}Ti73rtgzx*HlM4+o
> 5
> zQpZz#-
> anu^@&v!n^I6H~cYI0+i}E>x&jiKui4+YPQaohHkdjiq%7zRWz>oe0>Z_d3
> zAjSS~{ss?;ShfMZ{+aLQe~Mtm)=N!}ZlZtSQ=WIqKakZFQpLjQ3POaD!%)jkrNk
> 8)
> zuMXP=9B!1W@cYPu_uX&FwO6jy()M_pSmQ$Tot34)j8i@N)8s0`D>j~)=<_xq
> $5l*-
> z^?YrkE<}0rEd(bRU3d-nvG78_j|A^l?@56x37c4Za+7isbGQ)>E#(SUiK_}5!>*OE
> zIe$6N>d+psBj7~grm%|;OA5|+c#r+o>;mdVns+($o2X4zy3{IQozRQIGYzXD3S
> WW~
> z7N8KRrY94xm|~WLXv@Qjjd5#G?Zs@9z&0Y|!jv6MCW^orxuIvNSwdT@Yr|I
> =p<1gy
> z>0ZN|f2M0sjoUn!dYf&E^I^Ku66g0eR@mOgzx-
> YJP_ZD=xtl~=mKr_u_zM%7ju4t{
> z1^2*UNiIw-
> J)!+6?B1r2>PkSFNlD619y9ukMt`zN(@uVyoZK<9uK)@avdh&QrnLLV
> zOh2r=xTA}mWO!93t_m%0cx?Ax?G(~YaN5a&T<3OuBDrurGvBGU=*OT}k*O
> V%NN!Nr
> z(H4e8!zQS4@!%0^CQq_mam6mZv+JBMnCdFDyRiumpm2X?@XM1dhqI`yG
> =({e-HLQg
> zQgFI!DXsJ*>sw2!z11uTBiR=n7W17jF52=mL5Jvs<m<i@D$H9_7k-
> 9gqR!WE7U!|P
> ze(sa9-BFov6RGo2|Iv6ABR`2l;j6@z1iq#vw^{p5&ydGgx5EBv%j-P8ZU<iBE252D
> z&sv-_8Rw2=zay8+x{K6<|M-N}tWh-
> p@A1OZ5Gs)^#=jxi!tEpO+z+CWE5J~sQjuOx
> z7{haH_BBWV*XZiQ{6<LpXT$wW&a>C9@x}$$uJML&L`db_ZW~9~EYAJWOqe
> }N#6C!8
> z!X%Nu(53V|SjkZZukqw6on!Q-
> t>DXZPtjOppIQ&2_jgWp_S;_riTRxt*Pm+$(uN8y
> zhldbCT};ej#9WA*&LJ|~Mk0e-C9)nnkD`g-
> {DsP|!(Wi_x^X$PYn;Q<r&{SS>7Lw5
> zaVl+AT*H73_d<F2Lj2fK5TlY?h9GP1kgT~^0%67(k`c$bg-lxbk_EL?!y0AJ@ao9Y
> z7`wl@p{%mCD0j+i&LaUj0?gTft;YT}U9}hmV*~61c2$+G*rhGI(|55eK<GNcgS6
> ~!
> z3cR1s8a|Kn$>VPZ=jE)~IFc^!e;=2$B1rt(Q4CbV^e%#D4>t12e$o^Sm6&}hQr!a
> @
> z@z3K~nyWJ1H^g&oMe42Nw5<1O2I3Ax70uZwIdu?D8zxBOL-
> XhvO0T&hE~5qejMi@v
> zSIXaHt|62Cy)Ei1Q(NT$J7*Lrb!~gdAL}X?Z)peA1ear5mz#fmv;~Gp!b-1DynLD`
> z2W{0*rQu$lk60$A0QM9_TYgJHqJZ!&TtI_s)>Tc}5^edC;&6<)WqhRZ+_u<uNJ
> Ynh
> z(~t@tv8cRbB$Hnm80_x@_Bo@-
> mZ=$^;+T2dx3K^H)o3d>(qfz`iWa@|7Yi0T*C(!`
> zTpYx7JOq}^y)Fs{w$m-bdjYc@u8&!$1cR`_-
> #kZ!L80B*!3^ZyK8m)eXO(aVzwzJ=
> zOURPR#0Z5ka;s8r7e(*>X`h5+TtdyCAqth6`&wO99)*S`k3!Uo4V+cdBqI=HF)a0
> R
> zWz$GsJYz2m9NTz?FwvFT8da;Ye|EkrCVuClz{FNJU0a)7Q@&S|Z}TOEZ644x2Z
> x=i
> zRCm$sSE@H5<){&-
> w|#QekAhQg>CPV!tq(8O1*`a;78T{Vf)Te=HV)WexC#owiL{8i
> zG0~rs2kAqAgw!?+S_k1v6BVruo0=DGDvK^z2c~!$*cj#exag8oH4pvMNVJorx
> EZ9S
> zf7*a5J#${!l-
> B!5KmVKs!^5DWDXm(x&YwiZz>scOn~tq9P4=2hb=j0V5bh%L>qsx<
> zHbF&G%qVixM`-{}%G{yc>FT1)y(&4KfT?Lz_ie~6IYT?Roh|S#7kJPs`DrL-
> wxw@t
> zaEd2>0hq&G>WJ~0it=(*NLYI;+zD4rQ$xY3i=LLXOST+_!a!H0ur4`<Fs2V`#6_X=
> z)exH9fSi4XuZ~!*fO0ca^A-0c$g9GdZA`BqV>qT!-F0PZa4I^lGJ(b*C*nb3Z6%4C
> znK27iJgByY!hgHiaZsPBu8hN^S>+pTD6t!rN4jK78*<HCi&`6Us9AD0&`jGtW$VI
> X
> z{HE;=sXVd<8q78<wcZXF`YT2;-+qHZ&O$%6Z3e9SGF~*BWDb;2-
> %8?9ZP>c~d7gLq
> z=Vy4{&NDp~*~W99bvrY5P1Eezv*zm<16!!ux+DCu{Yqnv?Q_l^id+u3VY4=#C
> Wz7W
> zCX<_Afp{spja5e*mpmo4;e*WylkYn(Qa=a%%vU%;@t;3Em~npvs5k^+59!FLy
> ZeIr
> zU}V<1wNLoS-
> 6TnEy^j4OL1C=U|Et?;hxF`CE!sP9!DP<zWPUvBi0a6<ln2{!B=>>L
> zP<yVPTa-ICV`X6gEY6J#laz4Wc9^6jM0q)71mhXHl7Gg6@lHrl7-
> tMeDv8|haeS&0
> z`seXHAB@(_fk#F&ukv|;Plx~2vp&!A$<Mck+#i)%G^S+X;0<(ibJhgmMPnk-
> mMy@+
> z++q%&D?jE*U3&w;BO4LfI(W<33JvG3yOdr>8nG*uF)wwM%ls9~49&5J$}hi|
> v>W8L
> zj<)>`#6p`WoFBl*WJL<u<n}kMLQTIY@+o&TwQ@4sdJ~bv6Dk}}c+8F^%um>5
> +0TNi
> z>_z%|1%PN;QPcHIk11`{`~6wI8GZ@o+)E#I@HsO^o>5e2o|ofYRe~8q9LP_z>
> uie?
> zj9Sy3E8$00u0~bvq1^S<S=^Ll1-
> N>e%o$zWU)HbQu6S^EVWn*Dbt~s`*|rNR6$~)G
> zYG0+XnXdYvy0^X`hL`XD0J<&||J?r4fB!t-F0jSq!E)EOVlf!O8poQ}2M?l6g~7JQ
> zIC2YaRg1K^mvNAKRaek5ERK!d`Nu(`mA$aC$O+~S9UPBh<1tOX(Ipv5Y{QE}Ye
> 0z>
> zap8?)S~-
> vKhwA&h#4;+GVCqUPT!MspA74S%7Gn59b+IQqxu5e7;obNHj}buSNbIL2
> zHz{3$Wdsl=cj{%Ddojd!1D7IpDPn?)$bN)CVB?O|=#slb*yyOfuzjFEY%>Mha}<
> >9
> zRB3e%HUp^IVF;(l07lLH-
> uPi?Ccv+MEEF5WlT|I`_&$pVz&5}>ZimE_=7uK6Dr%WU
> zmD)*9Z8&g<3^YH+A#|L0N5_M2{-
> 7VKZW1_?$egTI2~XIXjpaJz@nfQBwF4(s1)cz>
> zE@*jD;J^cu^OR$Z2S*rP`?^XOI13e3<iJrT=A86-V}J&*)3xJx-Ci>mq=7+|99^P`
> zJ$aXMJ#88TbO4otn)_GFt-Z<n6!}9Jd1yM=vZi0-
> {zHwspM1%6%KWk|FeSysgX68#
> z(&QdRT-
> >k9a%*{c_QHV%;GYGcbupumv1GG+oH6YP`@H_ueoxizRkhtJeU7hIL-?|x
> z1vnL53#YN5rCm7Hq%`(R<k(^Bbymsr!li!;aXL{^Kd>m@#fKaXKmC3`ENl`uXOT
> HM
> zLnS<KYf*=VUsn`>b0~^is2pc{aMXZbc7@=yD(Ywlj_85TO~=R3ZGfHDoko@0r;
> gPu
> z<Y?I$E|M#hEBKpL3nCr&?H=H|c$Ffbc9CtuHMV_8RK2)<@q7Imw?~azL%!rT
> W&Y;@
> zl_cvX_Z3^IrO8f3G`UifU3y9Sm(n|V`K)`%&Sq8jugCM}`UCJ60Z>Ij$%!g$kq1CD
> z_Jtw;0=qMm<9S$SIG%5KEyV5>ifXs0_ZrW?dbl4x4hWoi0;g3a{Pmv>AEKmJ1{
> Z*H
> zsPVj3Ii`DX)PTKiBN5|ylcG*>;JoX2miQKq=acFA<WA*!=QXP~Kc0txXWE<Gt;iQ
> $
> z<e|s&-&Xf)+|e+|<X-
> Y6yOnvkZ=67FV1+6cJ+_sI)_j#(f~FhxWMX?{QssNmo`KOj
> zn@twjgG=Z*<{4-#bH{za9?vXY#!n(SPKBIfg}@4lz2C)322Ug>EB5$;*i|lerNvHH
> z>_8Wr9jA&8D*g&3+4olge2C&3728n|+o$+e#jbX-
> ZXer0#ow<aEd>Sifqt!GKVJ~r
> zr}%A({iKV{U2`z#yA^*@LGC_fcPVyAL2RG0%hSaE#i;-
> ^W9jupdo9goLDat<e0v}2
> zM-
> bDa5Ja4Ul1Y^o>2Wv}LF|Wj=Vz}&v9@K(q4h~P_+EGWOaSeEMV;e8ld}5IlWC
> $q
> zIF}2YH3DawO8CM%zKa=rvkJjE)Zpt>j$hjv9F+?VxH=C`x1!crRO!18KCQ39!6#8k
> zf{62%s!x_LrGOj5vZcO3&+~I~XdI4F<VCLZL$~vq@AN}^v)Vb1e95zvIsJBTJAX;l
> z8iz9#5pkt56}T$bIzI2L!rPGTg6m&$E0=MsTu$ZLtrf*cb`s58V{66TJhNUYJi~6;
> zGe=cNt{a2x_vq@#$Hua5ISxA{=^|xioB&z&?ti731E;>fI&u%6)#T~&zk1eZI-
> hWD
> z>DN1b^q<AKkNfqcjtu22HQ0)jv&br(?k)ZAF}-
> icGaE$W$(7Op|J@V;c^&XH)c0zw
> ztzZA8eBBXy4XJt`r6B`r{VG$w?aK-cB9iedIB(1Zy!=9DRC0~#USM_m-
> B=A`O3sXe
> z1unmH>o(M}EUo;$;c-
> nPlFupYSuU$zKbi5RPp%IY<~pHiENeID&MZC8HjYS^e}OW(
> zSyVt2+1~>`P)cK?TyEFVlpVKy$YrvV+ul|gTI01^8BYSoSt?_lFJrmNaP}hjd8TfU
> zt*ec(FSsGo08?MSYdlOnhAV>(<tBL|IZq|bw-U;87vZbK-Rm46uD-
> chQJ?lvQ*dkG
> zXxn770&9HW36#Yxg^5gMeX>;%Cs{-VjAEHykF-|~XmoUaKeY#6-
> P23gpW)fjwWOg{
> zM2Bng4xU55hfO>mYE3?n@Z<Q*<#V?G)w4bq^7%iepMRKqQ$RoMYT_BD&
> +zo)6l$Il
> zu#dKiLzX<#hbj)Dr9j1W{n^pMQJw-
> Fe|q<fC(!w0WHwswGioiap^zK2wC*+S2d;aK
> zS>rX)lmlbRGtsuqB=Qs@GJh;B_`de$TOyZ+J=%xMH*&y&FCrG;b2@s07MXRg
> i7Xx~
> z9UM=_Rpm6RvOITP7{%a@CofjiNj{1b-
> Yr+AbZI<!g<_&UW^x!a?J2g|Ry>tRCKcWF
> z-
> ^M6&M>wFVuA(xLY*f^5Evh^#hpCW~_MHqRP5(nLB~|h)N)jD)5*gCbFj^4O
> Q7O-d
> zqN9(HKEdZZeCGOJJ?rx&J|WLDdU}`h@6e8-Oxs^-
> z3_LKNO?xr3%~|5<$X@7zm(yv
> zL+oc9995m1jAjM{k!@lAr*mjW7mHWd--
> ~j`S%$*1^kpjz5Bu+trE1mE*xy<0Ghr0L
> zPlS#Tbo&MVKKxn-
> r=Ik0S@vYnJE%CP|9B63eQ28(3CdzrCW{fzvML=HT8ySTf)91g
> zD^9j?poyc8J#O9vg*#nyw542`{8>=oxSR5$9Da_+7b2|WRR|VtH|B%lc8Z0T_D
> JiM
> zW}cv!+>PjiSUpw7lYxTg``}AaBWDsYv;7La)Q6r+8FrIOoS2AI6Ezl7k(-z=z0&j_
> zKEud-
> >0=aJ<$}Xyn<_R<m+5{^{7)}Iuu4R<S<U`<2?^ts@%cX*GWyv!zjKnc0Tg9-
> zqqf49@3?FC2N)BR|I3XDog3ZrJ4XZ{D-r<}q0CUhGvlC-%<#rUe0C_{I6i0cxscE8
> z{xgSPKi?nfKDE3K*)&_;ZPB}DAa-%DNOZ|k>t&}S{K<H0RlbXzhVO3IDsQE-
> iP(2A
> z>v5;%To`8Tqa(d2%xJcNBCE*hNTq{x)K=Cwo}P6!%z=$4TSOC3<N#et;?v-j|1fy!
> z)u7IFQMDX3-
> FQ@?R(71hA$4o^MtG7dtv2=62~DTCET2TwIl)M2dg_&;rlVlvNO^dD
> za00=fPxQUFKl>47w(6~p6CH@Pskg^bUqP02y;(}gvbHFDt<it40{GtE6fcV;%pm
> TL
> zR9g^6^<>+K%6?E;Jwhi~9IUGkLd#t9ytR*oB;4$OiO`4sJ%s+|ggj3E{}KAt-pv0l
> zLa*-4;t+~IMS(hfT5t3|P<Cp&<EcORjT=sRo@(<!9Q*p(ja4+XzkU4>!y$h)O+flk
> zYTX_~3ewvy_p`(OY;!;D`ss-
> MjL&*}^~=n=iV>yxKAF@~;wLN)U>OitBDmyuKel#c
> z8g`hg*q-
> e%D?%bUyP^@v+mQ^})jj2&v2_0eC`|#;^)sp~knU9AOe?TF_p4;9UK?Eb
> z|Dqf`XRP4+w(J{-
> %{a4U%U*sF@KwYJE21K|ExB5+B_86TomhAh$!!XI4WVDl&5`>F
> zs}GuAFg|F?`6c6gqdb|S`MlEF85%}@z^q?LqtJJ{W*)m32<_&4&39B56VEP`io+
> PL
> z*q_M(&T=E&xTeGltP%}sE_2c`*&K^8B&@hgS~G^K9a8uwm(q`qBdqQ&XOxi
> !v=fV2
> z@QgF0S{j}2DtihChCc2VmO9G03yy#z3O1A99%n7bESFnhR%Z-
> 9_gEMslWhe1NQu!D
> z-
> f?YMGYyHhEU}Ti&yKallz?K~xoDj3?l6G84TSA+ql9<kKmqB~90%L8dk#ob9Bm
> m(
> zL87o;Kffux(TyL{Ek<pa!9`#yZoPNr2spp$0bw>T660t7vm!^Q4L`#x0AIo&wE<N(
> zeuvZA>eefJ<_^89Ne(67{j6FaS|}F2k1Uy1C80T7Z_-
> G&#n!`53(Bth8TS1+Wu+cR
> z?Pg`i)>C4Txkv9PPCI#{<3H8EY*nu$aR1@h5GcE0J#|>w)blfht;1zR34pDWa-ft^
> z|E(rgIuCJN0_dD^@An<HFMF9yz`cDrD2(dLK8e}QaTV-
> Ke>>J^*`J+EcqqoM`7l#<
> z%da(MU!K|)XU?wWMUobT5?M!VXcK;o=g=nnC!W_c5zuXs-
> 8{dGP546Gxv%_u!I}2&
> zBENc*RPrpzJjv$;XsJ7LA1M|sq3(`z)}&kUGPk~R2k(zcJ~R|2G@X3Onacc)tTHo
> S
> zgSVHQzBYN6V((Y%P%9ei48t}tL50!{CxdBzYfhra6fSQYg`eodPw?T#`|xoVzP{%
> D
> z7QQ|))&Ymp;VRYfFw20{wn@p|db!_T*sS%-c-
> zR)XMpM>f90ejiO4Uaj}fNby#Qm0
> zM)WeB%0!;~$w#65d}#T{IDK-
> WM7Hs+&JcfE3Thv^!{3yz^uyoL!@%EU@+ITS{8^@j
> z5PuIi1#|LdMLdf*Pp`O^>{UzRKp)<4P~}@9dI$>IvHxA#5l&zQ>j5vr*>${fH9PI
> u
> zjqtU|n}5^jV3~mZwA|c|X;3*MXRK5#I)D>*H7>$H)WB4!5W9Y$BKJFOgtfSWg
> +oDo
> z<}as$Pxdu)b(u`P++6^H^j;;0GJ>&RoO|U^3lPd96X(CtZ=%_0kz)FFz|M%jvem
> ^q
> zfU&DV%WRON0mG+kZNj@QUmb!Om$+2qo-
> Ir>VQatDlbt6_3q^Q|V3Mno9BrjF@!&`B
> z0nJ{Dn&qP4C8LrrgT!PhKI+NQd<D1sx9?!N6MpXL5K!MCz<UUPM;droL5Vu(E
> g4sd
> zGgabvUn17}pwobmTkfbNo`-
> DKQ?gY`R^*de^Wn^R2bJfp=gVOSol}LaR+<0M*b#~^
> zFzb|ZZaq2LVTEp}BF0dK`HiWN9`6QcmJWtYkv+Mi!o*GL+@aQ$;I=$>U+6^n`K
> R(y
> zQ~^EY>5rqz56@E}=X*KAr%5XBEV>UzO4ad%=;Bxa;xrs!t(cvzB+_*x@pju&d
> G5D5
> z`G+`+z5Xoy;K_XT?|nXWd51h1<w=NtkiUK+IQdBRACnc>V&&kg0gX&IOYa%~
> $|oYN
> zjGl@ivC5{O6Y9q6vMG$$mDH>8s%ubYdKffbR}dNUomD*7&${l)Yp$P(OOHFh
> T33vX
> zO17yt_oz3!)SIX6b7Vy8xvH@<IE(_JR?&}3{~e_t^JUUc;wvc0r?=$$kT6Bu2jjo5
> z-
> gZh|<)RPJ$|(&MHzMAZFRiO;El({PUDSwerfSQpjQ8@^IMXFgtfSS*TZM^Utpn
> vR
> z?rf)#oWDC265cq8XD=mxYwE+FjGXohkz1_t_{dmh@u=PSGSHvso;%sS$|Djk
> =^J(e
> zTq${}8a7W2JNb_e5!^2F%GAa|h^XRPIm&1ka<{ikr&=Ct#Um>h=1*=(V_{eke
> Wani
> zL`-eJ0YLJ`GwjBqhfG>@qo`Wd-LLA_s=A-
> PV%2SrZBjMcV;fX>?jz=9bAZJ*Ob7{^
> z{`#cy?N`3?yUCZz=QF6tCy*Mdpkh;lQ*ZQ%MA4R4%7<({4o5+^={>sSaHdyKIt
> 86?
> zYOtR1$$NR~vAFluRc?>1R>QW(R;kR6mTT40j+SfO&m8@1k2PBoJN{EoY;#X9u
> O%wA
> zS>J=BOFmr=)b=tox}-
> S&a(rW1_Ez3HTC^TRT(V#J&vsB7;Fi>FO4n7rXA{_8o^F|D
> zmFatK^v>Iqw@ojo!6#3*&6*Yb&;dgu)RvA_X0NpJD^pK$)mdfsLcP(sPr+*{vo
> XEJ
> zDpNa<iz~BdgemFJ%IryDN<1ekv!+EAT~TTi9+H)dpN!BYB*b+n0`qSe&2a>2UF
> S49
> zQ`?iSTdk`z$5<HJfiXU8;=80?b%@lfvJV-CD;K|FwX)m-
> (y>75yMc2ICe3GC>e@4L
> za;s~;_DSZ=wQbXe?@Gs-
> |2>T6HbH3<Vw=)(9ETFD9@<j5_$g~0EQy2uVykllC_i1d
> zDu>H$)r5vk>4qxEL<HdavnV^k#8&!8!!pyR?^Jeh+CA7<y*_&99<0%s<%+}fvB
> $cr
> zWwp8sEWZ3CxIFDy+-KEF7$V%4P8&<8!P87-
> Vv)q|t!(;;;c+xRW}Fm|<~BSKU(@ro
> zbnO0g!%B9}$HuUwIStzD#$>AV;gc;FJMQT##;NP8?sVP#nRt)#5kNj>EX$YR%
> D4N;
> zosO+E0NJPM1_h!D+@UyponSDP>s4b#9#e~77Pw6pZ*RGRkik5&LsgLoKduQ
> cSvT59
> zOD$R%xqZUI0jWjzM{eW*Sz65mSLy14Ti*ZXA2P9(sa=sbImY^apvj%;%B`eaK
> Ryk>
> z%BCZ%tiya+L&$qtyUUYl6C}(%E17%l$ELM|{R(eM#Heg**fC+NNG5jwkl4zmp
> {Yfy
> zxC6=482#QhW9W`_!wM(?8BVK+H~;2N0Zwh6Ntuzx;aY@7Cb)xt?VI6ktz~~kY
> Eg5f
> zaU_}X3CQO!5mhxupI9y)15OatnoW}c-
> LA3=AXhmeq=|HTM~k?R{Hs!X$2J;@UX~IJ
> zI(<cSYB+U66GB}Lp=MKn<ccV@BK)|EjW)Uv;bao@`3gyi1+-#esYNRyO@vn-
> e*n&H
> z9kt>txUO}q4H2+o)Sn$gH3dY~%K)TR7kgNy?P`74Kt86eVVR*7RwWo=K)<3b9
> ?-so
> zosP8vXx$hi_A$C9t_HGfO)YATG_f6U#dM&{uB8()b*+iuT&M9(w_FU?G7YUT
> q57c6
> z1<p>l%upzq+Xrx7mbqf$cGePCXk9A{COOpeTRRMD;kRZe@~Oh*y{YgaK76n
> bALPT!
> zak{iqr*ZkTO5&L|L6AsZ40v-
> Qb54NLIFEl2jofxtTWm)<wj%pHT=rd>yyOr~UXoh0
> zB+|sRyy7m(%++M-mH?T~is4sg!-
> gfu<N&7N5+7WQ`*9%zU)8L%ZJdYTk`RJX{kTcm
> zPSKS@r!U?um;scoTj5XKUGyP$tS(nBA2@J(dih*_ZaN~hS-
> +zfRAyTAkf~@{dDkZ)
> zi4~kmZ5!ZSLYJ(xAlWjPEYq+85U1?o3NJglH<4Ud*os{!!?>Lw`!#iYtg6IwapwKu
> z?&@a(qfgWpZF#wT$TP<^Y{37Ysba7pZ<CP6G_s<dhdfKqVar*uO(FkwaYJ<)Y
> ?Yf4
> zawFQ9pkpgEOrA87W)@u`=o+}HL34&d<n6=+MxUrD;+laWJC3VkD?=}IJ3{Do3
> YNO6
> z2__ok;y|~{!TWC(C+PCohqocCh>hjPn;XxJy~e}0+Zp~EvfEp3rn4A`kzADz<=KT
> o
> zDaKS@iNKd&I+hf!Y`?jyJ<CMot!p+W)|_c*p3<;t{$TMEV;mnRD*8y9s-
> Syy?4}pj
> z`h-p&Y`wPSID^WaGT2m{E6zQXX;?L-
> q4~xEHZ8BR1{4A7;<v;Go6hBE&j}5yOb}fz
> zK{ajPR{L1uPq1~+SkAjl%o*#_GDQ5jV^cA3+Re=6%vIvI^0ig>MV~NHkkwIjrcI
> @m
> zaAK)FI0meePqdPcMPnO}KG7zwZvKR_C$QT5)8E6QVeb=!fx7k*E1`cmA%v7O
> XOc_I
> znD)hdGha;hUiHNPM_II475A1^pD)Y9iwa_D#?V#58LNHq7Pbz&`8mtHeLdm^
> =8M{H
> z10B%7Sva+E7`H~hW;e$M+VnaFB&5nr!h{M!nVrW_W-
> sXZjIB9JV(n>ra8xU#hse^g
> ztajF<xoi7l@4jH}!QA)FnrcOfQK-hI)h^<+hhC{<fjiRQz|^en=Jt}N%eVK+`hD|e
> zjLnG}r@SkK#~N8MQMcF6nJ5QokFw{?&sM-?rD8BTGCF=+-
> %X$3{M!jJ=s4D1Vr_np
> zmP5#v7@qH2z93)tzsbk4d%;znmNl+L<)=OSW>b6i+jOR1DeAI`<a02fWWZMt`
> K|ab
> z%RdGa=Nmz#5RRkwH?WH`l<29{%TpUqG)4Wl{-
> Q9q2%N8ys+LjGc)o(ip7SLsc@qkD
> z^!mjt!1IegyXCK4>31vrmwftI`Gi=vf$7u&8$N|vAidFazvxL$`(>d0xr?{8(+1Y`
> zA16j@Y1aFa*V;+FgLa<4^FMiB%QJ9A{>t+*|GbaqbCOrizw+uv^atnOF#ozM8
> ++d`
> zx^iyQEWceSbKv!lS4Xy;T^;!=pU3z-
> %V#y86@0EHZULXYJQq)`jzk8(_g_&y+U^$~
> zJg_|c%SYrN2IZd){V<63?uu1MTKRmlraJOD>i-
> _UW#?2!=JR|Zzn|cD$Fyor<*km)
> z<~e#UFjiC)Rs3K46|0bvu%yz8vH=wp1H;$yib2JLc^MMwgF}CcwwR0{vNvffa<
> 9e+
> z?Fr|dn<{rS1VX=le!c5gN<cpX!%gii;$-lrMPxJYfoN{#D@Z)+h)hctMekJf4n^-(
> z^r<dd^;J<HZV6MxonjTw1dJ?nkc(ZF)c59Nc`ajszNan5a7NQ7XbX1UXd+>a;UL
> {i
> z&H`;tAAJ#3k>4~lqmsw5P)ts`7vQGx6)b<oVE5y2oFeBcvRRQgyU2XIk5}|cMXy
> uz
> zB|h4ewaj5`-
> <C3R@!JvFw{TQ)qLOzhdFfY3ezH$)I>DvIt*qvHb;nL8oqH7BAG$ms
> zcFp?lpM=fw_~$x8jts<Kr#|=tmRM4e7Bpf`{d(5e0O#=!Py~9<@^rCapDeB1xd
> LV!
> za3m)SnE%{m?FQ#5s&M+akUrSSz~x+%7DjPW<=(C{Z^x(SK#>k+I>0{g0}jo=<I
> -KZ
> zaD+>D%k6_KBp913#RsRnuS(jdj|X3|ZYwq42`=zbUBRT>VQf8s`tZaRD~qmgPX
> %WH
> z+<&hN38H`=l!x;U3(9FaS=m!>S96b;0e|jo+CvNQS1LqNvu{%?IOaudp%o6lU!
> wec
> zd$5;W<ToI8VOn*Y4rxd{_;}FEVP6y?X9|%w3z0Lhfr(ce5v01u>gYC6LF(;6+=ol!
> z%uJAbDGZ%d82YL=XL*gXOH&`rbGmV7v|W;hbIuuTaYdl&YpEv>OxUr3)*m=
> (YdjHX
> zISK&UD2aNou4hW!{`to)kk)%jL)T5Cl5Ys!Rf2be;9Z4PiR3C!<B9p;{jPw_j?C-6
> z6;x8P<FMD!J*JybdHObFKSz~l(D7xujB!Wr)IJ(w&*^_V59x0f4<di=Mc)S@&g7
> )~
> z0B0Is!AJ+r{}O#6!fwD!>B*-
> 1Vja0p4<!DXdV3Pw=;Nwzo+@0T3Rhu&vbi;%WYB5t
> zr#+ix;$ztPrXIRmzUXVQ&G}3IQ{93igF2i0K3&{tPo|zaFkzSLoh@<v#SuE*t9Rm
> p
> zZmpo(A?OA;=v1!noqg~UD*%;|`T{#gB6y_7+I!lwCEEVpbJ$a&RpTp;k7PfY?<&
> _*
> z-
> ~3T;PdNil!T7BT$M2AE{0=yH1n1LNFZAg@bGu95J~nsg^w@_k0+Xr_0@sgcv#
> o0M
> z70YRKBVWOAj9@g;Gw8G;?^EPzMefJ&r2cBaepjq}2J)5@#&tK=AvAJA3PSdP
> Q`>W~
> zT<O}P+{euZ=rY);9*Lj=j2MY@DPMii<Hy+g_9<PBrR3DObq1r{z0kLeUP<&G;iN
> +Q
> zS?rwlWCB~h-
> )#C;v`E5F4XK>}_o7O1+TW=GJJf(ZYQSl}0a8KMCmgq?3wvDVGRq8V
> zD4*-vr_LXh>{9-2<*)cE`Tvd$N(eyO=5(66%HULPB%#`;9|>8bFk6s+2&?zxII<=u
> zEB~YY^N(=(Gl$AA_$MfTT={1z|BWtxY7rOh9zp$mTJhhs0ue&<Okdo*&o%Fa
> d?mCm
> zoL>s<XQ(DI8ksrn6iM+g+f$!VgJs;)!F-
> MAPPA8BIPZxEv%YWGkUS7t$+rHmx0ehR
> zz4$PD)D3D+v)Xf?+Vh}^zp|}pg2WsrLuk5|c~o8AL}4~@S$~vA8UfHQ`2LDY*`Q
> K(
> zsg%!!rHJ!qiZR;h%%$>lLi2G(U1g7yUBR7?R`ii!(S`8k%ipN-$NUH7PvR^1#}3!)
> zu2dNf1#qG?9k&Vqml_=K6?xz{{GgX4JpA<M9+kXMB`;IS4~8X|n|*DG&(puX
> |4^<q
> z%GIu1*M+$%EZ6x3H94I3&wq3|`Ab)je>7jg2YT~YOR^l=zkptN&r;4ym2;kQ{(Z
> a0
> z1VYagX4(7N$^NS~y)8X-
> {a2}!`&7zmmGXnIl!_^EY%61FpE9UFq)(A#zF%5YPN&L=
> ze2sEu<;#I45m;J`t)SPyp_4PItdB53$_=_eWOBmB5mXqm6E9D5-
> =OD9I`D+q>N~1#
> z8Z{*^R(1c=;TjK-id-`_rRi$TIZ%QKx7_?0GV&zY#K0(&xM<Jf&SvJQi}3kt-Z+-0
> zyw4v?HyPu)+)t<b3Ea;<_p?_&9kG{4w$p`db3g6wXM_8Jd#NNErk~aBXO;U|s
> UIAb
> zv@;tGGxl!mt_+gO)T^V>yn8O7(?0X}kly8TN;Sk}T%|Twa<PLg7kZ|!2Rc=QG(%
> Y>
> zoGiw9H>hud64)j9MgBntu(Y<MweFq8i&!P=x-?v--dX&%449I-
> dQ3szlY11e{&&)K
> zQlZ%{f@TZ}M@8@4!LlWT>EN-
> }$}4QwdiUknkL>O#gC#v2^X_&M*@cpJO6hXFE#pgv
> zA!qN@+Z}xQ9X@QJO}#oOtu3|tGqu=~_EOr?n)24zOF-}vZU`U7FKkM~-
> o|4%w_*qV
> z&1#>2!Pxm~Qk6TUNIN1aAk{ty2fJ(%TqrZA!$ez7=Vg2BxyrXWb|bcX9zO;yRd
> #0f
> zx5aj1i`f8~;&P3X*@1@VBn#{h?tNG$f%ep*_Q)btJnrjMTw)b}_X`CT??Eoi)NP
> nj
> z=is}vH(7IGvY#kf!_NBPdz*YmY-8_#JorZVx{pIMY`gV7?$`dF(lFI;vk}Ho&HgN=
> z8&nF`?VYS;wgK~AV3seTb8b7(up7@kVE-
> K?Ca2KYws`Odle{^!xjoW2fp*;03*bxh
> ztR3=$3m$dJ95TzPCU+ua@lt(qCFzrEdNX~`GL3c#?eskkq!8@*=gUp<dnR;YJ~Y
> %d
> zo=lZHdvnkARq71Ysjf;-
> 2DyRI&E1j%IhwlhR93+m7&pWneQfaxkv7L2Prn0(UX>|^
> z_!NW|&0bsWE&D+-
> CpSPJ@*CA9>@S_C_A#)UE_DldHeuDuxH{n(@MbS1EC~Vn4Ra6(
> zfnIbhK=11Xdi@QCC)eaoDmGaE$V2vVLFO)A`_|g_PjWQVk(QWwS?csibjjyPK
> @Gp@
> zQW>T3;N&ma11A9yx;YH33PV?8*sA!3+OR4S+{SX9Oqnjs%B*+XTL~k0O+2_N
> |E8<d
> zX1KSu83T&ygHJr}t5~U&x@t}NGqF`XuS^6REG>AT%uT;^H8^ZA6bn%!b>5o#
> VElBY
> zVd>Nko4OM=#p3Wzx`~1Deh@VlXy<T;MsgYtLFRfT_Jgur3`$jgc(1EQ#ch1aS4
> ks2
> z=BoFsv90bdP8nMPq^sk>w?7%yYInt@e6EJo+`k&;GENGS(5}0Hb%p5fWOLKa
> cjXuW
> zs}+Q9=yqP$3tny<%&tTy=k&OhL~t~H<z%Ytk157F+-de&VRFGE-
> !aYJWsA2p(=cX}
> z>j}_Ql`*~DGScjXqr!<Iukx(rjh<iOd4+#|hUdHdb34y7Zn$CY1x=0fni{9iy8iQx
> z$$|i{*PC`@<AvAUGK-
> ^l=U>@)b<&<Q2R41CI#T($>d2k^{*cc~K4(*2q^QqU(Bd*S
> zhn8AUNr@zYg84fyUn2g=6N@9BG*xPS)MIuu48IZ|^K)^({3Mrr$&8gPI<BsV6
> }@&j
> zvE8gE_i8?y<dx1tpO@<E&o3fvx($VjDh%L;{@k4KY!_*@lC2uv5`X1QYsQl9)S~
> VP
> z2RM(6M4EFS!-5!nZ1|ZCJvUDBGh<Jt^d5-
> <RX_&ktSHgW2=Nx?#?qy|F#jSvy!2}i
> zx=uBL$>2Za`9B@8cbHBXznWY+^>Z-
> n*S5vpfi}H9Z$$|Ez!3H>JEX<K&Y7%r@8~$Q
> zV~nXeNv3o#r#sn9-f5xf@?2GNo(9^zj|c(&{K(?a`*`A2(CI*0Ajh;SNc8D%yVjtC
> zg}5W96A!O5KjW!9a|-
> kYv+J(BI(g0YpTA)C>>Fn_=C{W6w!hzbjd_veoqUs7(N!f^
> z2&{Jy-}7Ky?Z&2#Hen;e>ahKv7P7WUTWL!d-
> +r#NuX~3^MjzuQ<3%U9x5^Bcd6kz`
> zVfK!_!?G$fh{F??HoRkJcfFI_8M+|u`<83wyZ4v%4pVAgX!TPn${A4<z_?w<o(x
> Ab
> z^FmDcMzxvstCD_{uROx+4g;S(P>t7+g$rXzdyy^t;?QdJF&5cPCnlGH?qKse!v?
> KN
> z7h4GGUCn8U;E(i+E!fF`3#$?2{&dA1xW+6kE@hoGnj<7NEDz7#N`EmIzs4%wq
> blFs
> zqi53HqiK8C-FsF#JgBe75*hB9oXGR}vu<we-^T^~zyQNP@J4Poz))N{p*YoDxj-
> O%
> z%HY$$F5ClNnaWn4S=V#p1a*+x*cT7xo}*@I%0-q%Z;R_tReJCSfs-
> rEZBch=UGrfN
> zrme?2ry+Z9+BlpvUiP+L8WHvw{-Z1}Au-
> =$U#GON#|p;aF7iW=y&cEct`Ba7*r>B4
> zhP%c-*it;W#)Uvk6YwC|p&2|PORG-
> z)5#odoZZMy8<VVpiI*!ov&kkKs=%=+vZyRO
> zKp@!NFD0qBkBGMXjWXE(k&$T~k$N$HJqXtLpK)*<GWRx|7t2W^SB9>PyaR
> |%Hz-&W
> z1ajJxSo=+=R<=#3YfrsZd1F~t9>-*tDYPN*+lks@d!Rz4u>r-lig+-^6f`2nd2l30
> zjGr@N{IuhRP>m<XNk2AJ(3$C?kQgOR#e<7hDu%UlFhP!=dmutlC6OaUlCjZC
> %h`TR
> zXzO63$)mDg0KDuL>ejfVxBC<3y4eus?ccQdGPP|QU0%bBn=9ddkxj&F^`Yj!#
> &ftQ
> zVjs`DeE43TKQ-%%g>-
> x2tg9P2z`mD9*?1oh{p{X2n4&!W^m?KejCT*BJftzx&Kcc?
> z%o<$E3XT3<+VFa7!}GM|`BeA7rb+}z*O5{m49=bDA_g54G1f&C9~99a9Xme{I
> _9AZ
> zz4$YiGcGU;{${r-9uHzpB3OtK!-
> zab!o9SAG|zi^K6mzwwX?2tzQcb0J@kHs9x^Zy
> zb-SO!rE78>eA(vAkDI_9s*LOm(w~yvF*e4^&v-
> HM$IVOJfyHon{O1aU4P@_jX=POT
> zlbd{`XOtet)-7lYhtbEjZt0GI66IbP=FZK~(uuYwf{UH1OvBUXhP24N%j8nV8q+jc
> zt6f&0L%^OgTrOtpK^c-
> Su!MJ~w*B)r90oxU^gx+tANZS7tP0_^fA(4^G4JO=6wRU3
> zG<(TNpui5F0DBTvpx(}-cQTY+pfE6cI}3W-wlPW-d0l}=zsI|Y1Abl85qq9~G3L|}
> z`*qRwn5GXq)*?BUQ`Li$Z2;#x#q+o~l&0=^#NmA)Nk)4RcSE<7vmmGwH%*^
> #CkcCt
> zXVDvb{><2}XzE_VIfa%*8T<89!Ps<cN2YGa;xCTB{M?Ibn>g!c2b;bomBe<$gB=
> %}
> z&bKwTofKFECY8ubtQh4uh-!^>WMYKYPAZYd;-
> zQ$&|fekZHKpT>`JTy2Ea0{?ic80
> zqG}|ir$+`~<^ChK=5gT^UfR2|S3=e#`Zcqo$1rCg_oPSeB^^zCa38;+7_)y4<7Mj
> C
> zJ^MI|ekkEZqr}_Jdq@z@ZBwr8Jr7_K&(Bkl#?n}x3*{U3|M)Ypt7p!{m_E~FX%l
> nu
> zU-a+dPF)X!K4|kgtQ8x-LP-a)mF+ES=r&^TOIn?OT9toVnSZ)J|I|)tE{Do>PaE=2
> zJN%Ok)Gx8H0rz&;Z@NW=X$KpWe4UHPbR{=P*t*QUx>et?_EMfUfK*JTO`v
> g~5H!ND
> zPPU5=ELT{4Q0l@c){2h@fBdc`N?XHFi?r#)#)MCPU}X8;Pef2G;FpPFK_d5o=#n
> *{
> z$!BLAwFx7MU<myL3rOyuvbN=Wt+IjtWo0u*jZW@Vc#Fd0!E3+s;Z0@P@f6n
> 9rf?Io
> zlDjP3F0c|023pH1le-nxrm%$9x6@i7u5G!Hiw}-o;=!NIt(G`-NNTfn%c7$*ZHi3<
> zSyP;sZns!<Lw1d3b5}$##5Cun=@xZOYO{3^`(=E|KPb$Lj;%TSBk~#_@ulDT3u}
> L7
> zxhex90Vc1YHkFhJI)9|-%5;lpz$Xem?Mls9;1tW!2)HiCk%d)ik&`{!z*TI0at|m8
> z-
> aIqJBU>#iIwH_YWd|0A<w}ztS@HGrxNeAsW~@>1WT!H1&1b^bx}u|qL0j2T3
> _U2*
> zgO=w$^0>CC6$!WavO?>FbN)w+psFv9kMcDHvpAIm0`A2zGNf<M$v{t(+qwJ
> UOp6AH
> zi%VCuEL;IESZ+avhIHxjPO*nJ1)0;7#qDofF7kvkcE=BlEOoT`@^a+3_GrsBz>1EH
> zeLe?9MqE?}Q8{il5+w+Q;V5{*Dc>?i^xS6<zABwx_ul{`T2J<iKXdtIZstDX8M*X`
> zN5Gcm5+$}&0;-mgR$xt~g-
> `J;LKWIK^DG2P)>+5%x!25{WvoXJI+?$E{`@Zzdi_iV
> zOuMr2%0BW<sBibnF6PG6S%#=c<HR|LDl+@9$XzbnF+cu?(5vH~Wvz3&wb*
> yjliR+w
> z2($z8M!HoX8_zR-
> Hv@ph?=*rpHUQ;8{H~+rQQ}ZNwzX{Ff$69m?0Tk<q(H|vQdYzP
> z^w`UlEcHsIeDamGh#qlR&UeZwWLs*H4%PeTf$Hf5_M-
> ZSzZR+m9&i_VxJ^##A+f3u
> zuFJnr9r^U^nT9l*pDVDZ?pO2rnpN}1SaeUiUlI}0#QPpJVuYW@2?~a}S2S#5wv
> qgs
> zcH+JMZA;oVZ9ozJln>d9owDFog~=;?neu`Q8Z0X+HZ<>NI&GD7B~0YOc}_WJ
> D_@rK
> zs&@MWR+>{`u(rdlsy$_uOg;II@-vjRZ(QhqvFF{-
> fZk6xA{co6MBv``x}VOws5Ml(
> zvZUkoIc8`S(EE^vQfDniYxz7W?Ns-7zU49GVs-
> dW@Mjm+HhlowB=)2h1rcmI>?jX@
> zg+2@-<3v~O0NGn&>y;o8obaZ?k#Pbglfz(8BIWmsw2-!H<9KkdD-
> ^qNC*#`1fAh;e
> zUVvHEbHh{ytAa93K}pkIE8+qdS<-b;Fw^I3*jv)DhZA>Qi5*k_`Tnd-+^lp;>h^Y2
> zYadiYrS?BKruY|{Z4KzkRXW}(M7R)$=|11b!Jk%ID0H(<9r!!<D!QSyJMwQjhw}0
> K
> zn+_~n<K94BQ6hL?l`nh0^ds*4fFP0FrCJb(ja-IUo7gS^RlR0{Gw4M{2Vq4vI3TnP
> z+`rzQJymrIs4uXt0P;er8V6N9zO0a{pr?NPMJpy-8r&0s`yU^??M4BW&N-
> fGUXuBV
> z2$yu5Dl^UD9EOYEw!p7#Tj1BWEhyal0Q|NEg=^b_!nJLI-
> &!#+d=qL0Sor#cUB$_w
> zBH6<{WsCR$hPBhh`izDB&)s1gY&`VSPocYT3jnHFyk+`{9ElcG*{$>rby{|mmnl3
> R
> zbXqu2U{`Far!qTWgH;Wu18HD0@Y6rnOed8F8d7&?5Sqx~-
> rrj=>JiAfN1%sw?M4S+
> z)ZUZ3*Dl}S1;kh9f%aorKZk-
> }jJ`<2Ppgqex*jD8R_F=EU)wl}K6&#kQ)Wm_d+oEM
> z>Vr!hV{&4dRxg8?;W!P+W&g;**{^LM#VErZ573;baAwAO(}e`z|A|qJt-AVDN-
> nw4
> zuppMV962%A8w4df600&@8LHwgVd&-
> ARsnqhkYK5tGJO8~$w1{^pVqCZLiPny2QD%%
> zhvRhPfb{wmT5f)IsRL1K&D0jQz_BV1RY|Y56;$Wff0=U3*I*(lOdLn@OmQl}Lqc
> ml
> z<+i3*CW5nFxu?li{%y)J|CDc4edN5zgJbw&j<o*ym**As>Ki)XdZ6dDC)2T)({+D
> p
> z!$OxFO;JgemsH6?)|!ilrj9V!w}46S(^P%&XPk8LQzQnq#sJW8-!Pl+I!PzJfC!+Q
> z=TJ&8_})YRA(fHUof)di6T$N#vgyhffRsJfF<6aYnRhd=Jbjl<zz&!X8Zc5)EFoB(
> z3SCBSCY|&(f@KNMAuOJrzcrSM9vsit{}KMiQB+dpB~^0pFrpM9w1auv7lC<{!R
> $c3
> zm7(wO_Y8C`kPUwmNf+X8GS4B*{}%pKcV?(6PXynv+9B41@wZm6WT+JZ#sT
> x!4gn+l
> zP4mDAe;Y^_;%{34EFu27IkNr12(|t1@Q3p$w)2;z-
> b(gRR8mDHRcLU%v&}lxU2zNG
> z?qLLkq&L-|73pcb33cuqjU)*}+%@tX;x5m>{uTWRfXq-
> qkO)3&AUOP$FO9v>3ODie
> z*Cl{HWdM2n{m>Ru!e6O}Ncig}U5LNZTMvQ<qK+ra)#eI)mGTudIr}aJ{WRTQp
> JVBj
> zG&8i4?`xkNRWekW@E^2X62)4=Tm}5>TS^Vn`j+xeC{vb@K|iP{W`#T(6sqix{
> M2Xh
> zCV?CM9W;O8U%4<IT!A9PL=W%O&Cvu4>w}NdbS4z%O7mgpEW8TK&Y;6bv
> 0};=cl{OH
> zY;CHu!p^b6q-M(fDCE?Sv=*|?5Wa)XtH9mS))P#1S2NAou|?bdkcTa-
> WDMu+yGq<_
> ziq}T(Y>EQuB0LH!raTqG=H^T*?7LQ2U)T;i7&ZZTD0~5*n@xhV;Yv31I-
> ?*nNjE2A
> z=u8I?H@p|*ux?Ij%DK92Im(4M%s~NC0w;>tf&5JWuNuPyxPmf|^fP`+XFX+|
> ARx>>
> z6k@jFPLJ6`!3zP{mD$af(PR>HV+G7A?yC<0lB-
> m8pZ;}+J~dS_`650IMe|m{=0t1d
> zktCEDWkr0t7ozWk5d9nngM-
> P@&6fyYatu9<{OsLKbzjMmP3Ewhdi$2!M*uGIi(h^T
> zofRo`I85jOocp;Eu~CluqP>edS*YoJh`IE}#^c5C6!-V<_s)`<m4d~_3243{b`kD>
> z-Pu2p8Xe)DbX%jka<jfU{_$r7XO`=Q6Cg)7<Huv$sis?Mwk@>Gv()-
> 7Suj4+rU#BY
> zpRAOzUFHADUdtnRsMG@<Rl7#(VW8dJl55H|yo^Bj0<s2npXE1`v%W3X91p(r
> D-lyw
> zoA%v5mpgaPC>@$5!6g`YhlwMMhsgl@0;sES8_&k7T=WcT`9z-
> G4y|;<b75sPva%zB
> zr;B63!R>IoOIiwMj7{xY@d|-
> (ohUKtGjyJ48zNn#4*6b`rZrQGP*Bcu{>~sa1nK_N
> zH*c%%^JymU!~Qde-(&sfWPVTM6Lz7|>m>BsyEax(^r3rh``do-
> 7xWx+hxJ_Qt@7|z
> zoJR@r7712ads1%?<bX56ARk?10y}u2K6tvp583BZi=LD8I!rR#t(n+!@!)csYfF=p
> zh040;62T8Q_{6(Xi+0K9wc)w?;9=}Vut`aG)kR#Ag^^9c^}p^LY=OW0o_ek{H-
> g@@
> z#VH#?&TO{cL@ewmmQBHRP4i;9=8056*BlEKat;;!vVdUUFPe{9NgDRceLUN)
> ERRvc
> z=Rx+(-
> jR^^8#Ds}_CU%Dk+wayO>Z)~ZnG8oHXOo=Z@gTW@df9+Wz7pmPgxe@o))
> u0
> zGvpZSE&-2OmVkZHed!FtAXdcmw6>j@hHa^Z%Xiv-
> ?ruZ;4Y_;eT^2Mx=8NBCSJ};S
> zuWWIS2U%2JHZ8Tw1qjdC%cv?jl|D*d%2#lWtvm6=-
> o=n=PXyQe#8rv&n|7xLX)8-E
> zza2#bQ;T*+bo9*5`rwp@tz7F_%N-
> mOhTyu!+JUl$x{!P?jZ4u>qZy8Qk?YpYDrFkI
> z^vq({OS<YcGLeK~AAO4Fos6Aw!l&_kVdH$fANq7#I2_!3bCA8~-TTkm-
> wxSvmsrOw
> zbsPS}jw{Yx7WNvO>aEvu)BB8&hwI<F%Z}!VL1}#%0Ww^J$?qEJ3&X9|ScLN!{`
> GhJ
> zV|cR*$>Xze3HaR6T!7CBrW2I~W--
> B{dc)^J5{CHv2G1cr@8kJj;&VFuW!=WZK>tDf
> zMROWg{@vy;*1DPTWmubG>gK+a#b=3hxGM?M*AfITH;emD$`|{0KQzOJQr
> #xo7>+rA
> zQ}K<riKPeKZ+KdF?5r#+oezNQ!4}**l*Hhe6?MQb0>=ySV0gm!%O*FJHo2jsv
> 8SP=
> zVWLvh9NC9AWoER|HyN|xmHJa=nG8y7fUWzn!Ek15+kD*&y1k|d0zI(3rc6J%
> I`8qx
> z6?<)*%N;!Qs8#KKESs3p)>(3$UPSUJ<7`4~*E8K5$FeTX{e;pWtV<`@IItmIUFIp
> G
> zZf7Fc{GCFI&;@?qcOiL-
> X#Elt@z`wz6mf(pFsDNiHxOJfKP@9^NE46n9MZ&Up5Kio
> zj6Y76^YxC6VC`UnFj3*6{e61KM1=v?`=}q^%J=@?)kO_2q#JfxuCa&6C2Ej>QIH
> FU
> z;d1S=T(8<@^1hUYP0Q!ft*FLX5%44pWokypkriJ^1jQHlKIt=&U2Vu7Zj;ZhwZ4
> yc
> z&1b0Zn8+F-_d(bsQ(IeAb-
> H0krfFA6(@vZER=KoOx^Aq{v3msWn4PvAj4(|rt=K6K
> z^Bpy*m5v&^$U4efDsC_Z;beO17Ykia*;;rqDZ_r6#`8h*)q9LjL(z8I+1?jLbq9CH
> zM>QDL9r(HQ9gOQhp3Q6PY+hTJTC}eC#;a_gU)#6rvg|Jn_x<KI8rFASTT*A(&(
> y7R
> zgK=HI!Km)a-OVs!%rM~6umPN_Z~B-
> v#%DCEU1$hL%ok^{?KDg`M?YdcmTB0;iGW0L
> z0EC=$><)%)xy?$c(>yj!Qdb_EFKb{})`rxg4UtB)LEH#xax-i?obojM&i;1);WyER
> z<a@PrDZP5etp&sH>*gh);n#JG>r~Be6{HLMbOO)e*c-
> ?5yNx|fayI_{Re%3im!Tn?
> zvTXQ$_u&4v4G8M*_Wu1HGGCA@OM_#+uD@^XTXtFYL@T&oe~%C;6^f1b
> v9Fbt9&Gi{
> z%=cyA-
> @D?$C3Z(h>6x+i`FXi$E72Tk3qx;rJe9j#Gj%)Db=&AEJD@VUgawlZ{dyF`
> zx6#MELCu?x#r*Bq7rLb4><tP#Z_1X1+;y((Vc7KZil=P39T$m)3S1@F?6STnHzpS
> i
> zX9X7kMKLE~N!gTpfRr3w+l0io!FI%M$j*hK!@oO<5KT8Yrp~LAbPJ~T{SOpUk}
> kM?
> z#f9W4DSj7}^p~3pC@Ib`Ol=b-
> Jw&h=dB%=ixtNq8EiK?Vq@{U0_opSJAJBS8b6dA?
> zmN#3XvcS7|e`?YG0So3~z+fpiwT-
> <PvH?sjVye>C&D_Pd@~qCk*BX;8l0sE`H*=G<
> zNPVm(A3xs6qR6>xo%XCY<5J297n*-
> B)|_Zc>ssvGJ?VIvpSQNsrf2!Q!e>0tyv}bi
> zzoYr&$HyW4e+_Q7PM0sj@tISHSvPCt!(eRAo-
> 1;djf4Ho+#Za0M%y{NIoh(<sE8Ol
> zw)8QMEoDNnJf6f+loYX`v@+M%6rls~@vkeVR^^(;(NEMCage9>O#I%8tkg{8
> <LiSa
> z&H^+=h<S2_MLeRE9P7s7OCVD``@_SO?5pgIG#zGl$vtEue5nDJTj(ruTx4+j_k
> 5`+
> zq_}ae*`-o+(CD90f|&G*-
> acM50Z^xw9aUY1=QZ7T^YGj8pWGk036|Ldh9bG6<-2|R
> zaGjR6KXRjjO@85UuO6a-6?>1Im<Qa%3-oFHiqXTq`w@-
> Y1+1;>hc(tRYS_A7)%bB2
> zHMLQ$#6(p$e!xW~8ppY)i@C1eqONEh;i4w6x!ww#*rbiIrMcp@MFmO?qwld
> MroOwa
> z)dR~xxpPU>hN-U2b`!D8o#!#_?n-C1nc=L&g5$N#*uinE>J8nbtc^T-
> @uIH}zWoJ_
> z&I)kg7Nn)i7{4EA()e{(-
> ~O%9A;skJ3Stp=%*Wt^O6i}+@r>V7UOmwNN@3c!xKra4
> zeN8!eHlEG%K~i~8mcx;xWd;e%5qDJb*a58hmTAqmMr*z%Y+Gi?t?a0-
> #4g0W@8j!(
> z2RhVN<OCf0<ib{&+A=;7e3844O@V1Ao*z-
> Ae%^0dw=P*Z!_4<uW+vqQx;>tAxbV-Q
> z_0(eT+Vt{3!Fxk%eQ>vXZ;Q32TNVOqrcK`+MWtQ~fkP_;4>u&a;hJGGSmRU-
> _{4J1
> zL<4~}Xp<&cUVW#sBhqd5uvy>Jqj%P@Y{@Lw3nwTxKBOIRE#2RNjZxzI!i(kW
> L77>#
> z+`!5&3z90pY~1DX;6JT;7?W(ET&1paJ31kwc#v|sXLqvI;>}V^iB0IRxo+bZV=0Gy
> z^cE9|-nS*QT#ao#uPFP#2%!{kYR8NED3Y3f{_3H@`MnYw>?e~@5@vZK_-
> dFqFynq6
> z_BBcz!u~RY)uv$4Y<Yd~jDMHsSzVCYGM8WuSD#xStT%lTh*c{N)s`8Qi=r}YOS
> |hh
> z7O&ag3|Eb`rDi;(dV}Gcc7z8ugnp<UY7OsnZK(0!7+Q1-
> yxoekFUJP?x_z@*1kUDm
> z8FWxMg$q>^r#!QWbAmdl={f{@91glN^^@GR-
> c;d`ODRQ&fKOyUCa8?W@Q-z;HiW`a
> zS@upv8s*`ymygU2I#f$O@GdPmM~UsodwSz$BLzm4u$i{@WPe(T-
> `Zn*IWRgRgFLZU
> z<M#z6-
> BODa$2Aa&ywYoHm)@h>##)z8qyw5a>$@nr<Tng;_cE?=n0q*(@!af*%H_sS
> zUDwjY`8xiXfl+&bNHkMZ>!@XV$+B9C#KTQwhgcU6y5`#O%)V~3AGff>nD4M
> _&DtB!
> zcHmLM(wg&iri;ek1yG!zBNVhxFIlV-
> aa*(!xlum&rYkW=$7pC?K+me!%pLs`Hu<U-
> zsA@}lK8yG05*;nrX6j%EeB75%AN>3!KOSt+AHC~Cq)cs|M_Z)Q`jOb%Ua_|xv
> A59v
> z>`G#Pjq>6n7$><0Ez_nK$m*Hwlr7Oa_JUhSG&FH(?fI>P-
> J3Q@EkB)<a|XlITBh<8
> z5B_VOA?~y%MUo=W1_*R31ge|cV*938J<-
> %%lxd`CXFN`LCSz*v*_r9_f6jL2ytdiV
> zuGq_eY5=yjOrd-
> g!GT0gN9y5g6Sh9nooN#UOP4FQwW=t0O7yWdJ#Trrv^R}G$qiw}
> zCI64McY%+py7u@dFBl;(L4!m^iHemPR1~ZrU?C-nmehm-
> K8jVZieqZ6#R)zxC^$qD
> z#<aAR*4tXE)!u5KwpzhfEkO!FX$#72(V~sW)iX|N)0#@8Dg3{`wa=M3lLXt||Nj
> r4
> z%$zxU?bq6CueJ8tYp>nj=VfzgVfrG#GvW)j7`}(4dwLunqLj6>CpB$}HQkrR0PW
> f1
> z5ayfuOVU>g)+i??#i;1^6CHY5){LXzRFgiFH<v_iiltihyy6z@A(6<EEGIfn1=v)8
> zatd;+Vb}kvrv9wqufx<hu~sJ<GKWcu1k-
> fE=N#o;Ehr<Om=)<wx0@mmLdz9J)tE08
> zFHb*YfQkvVJXiN)J*pe`?7)t+%qk_WD*m3L>2!%+_(ExLmOK`vW{+6Z0^@$O
> )T&1e
> z__O?f^un^%d2`?BgTpb|!hAh5D;lgCw^|C}$h(~FF)4+i-
> 4fR&lPB9$m*2Lc)EdnM
> z;<Y?rm9l^}T(?vgw47h!=&sIN{uN=ZIDKk1XTA4>z|SVY!7WO310@x?*bHh`;bq
> xu
> zuz~_k;M}v`)i1vPhoM2Xx!y&6%RE6j2c({{v^v$K&wzUL+>d(pWJ}Mdp8E~Q{i){
> (
> z!H1|PJxwos9{-fN`(&*lCFwhJrK`&#ZUb#;tyJ^Y=reh%5qFcGSKQo(xNEYdo3Y1?
> zOs)uN|8u>sO&ee!3o}&?Cy<lLHivaWOzm03xVcTSdhdlVxk0;iNDje!J8YD5gu7
> 9R
> zIRp>7z1AQ9HKWyoCi`r)&$@!4^(BczHZ>hZN<jv9Pd)g#SGDR#GixrRfK7$P>Fr
> _*
> zxuRJTv8}?S>(|Mj!jTS6t;bmlMWl7!WH&S7<L+mh$Y;?zzG=BxK80oXN8^(OV-
> tY;
> z+e0vp@DZMwqkIJ`m;zs4?GX0ZA!@j*@lN;7jS2c?dOV5g69r)%bt>0m#`Uywo
> Gw+8
> zPcJQh?1SwE*?hK&4B4EgDaF~GeVnoEtM|Tk)<IBXylJo%=jQLLrk59|?`E&Vl~C
> s$
> z(zpKKDbX5djAYPlSw`}7Hk<6!29l~T*!yB?X35@d?l)FtOv>phLAt(skG$5WgN-
> C^
> zs%hug_!dcs<jqn}wCHf+e3f0o+T2vmXfA(7pC~8mNp?R>Inmn>C8ni+=yEyb!
> N^Fe
> zhp!fx@R?JzO4>oacg0o4)Ty)}eTTA{_Cn}@aU`?Ep5#mJkiy|Wq@1j+4-
> _2lh+H{L
> zu|O5FzG|Vy8>ui~Ql;G2ab>pBOj%}lPDFlwFq#Mvm#xj|Ui6DrEn$|v+6PzX0m
> sVp
> zk>tM6I81Vx>%7{&;71yGZ9Dhg<%X?<m%)s~Y$WBaw57ES6sFebGx_!zE$-
> nN{X8Ug
> z*JSBUP5QxdW+SVbRPC0c+DB9Ke|^~eA3DNmnO%U{Bt2Y^wOgtz@u)tDf3e
> Yd6kY4r
> z;AKml_b1!?EA>gmwrA5@Z7d!I;MWY?mU_<{0O-2_wOS-
> |;2s6;*A%*CuD8@S4+#)@
> z6-~_-
> OPM89d3?>Iz#d=wL)U*Nurdot8EPp*`=nIom41K!mSieZ^FwWYx<5qv)DqgN
> zxCB4`L!ZH1N($D6NAl#}H3HXJs^xvbYYm)B-u8vW<YZp@W0-
> t@WFxxT{4F>vkD%N~
> zS<1qBW1zw~uO9rFylRbpG}jkoP6coae2@&ak7COt!*IcgRqMg$&8zH3b9F)b
> @?xJh
> zJIoU$B-
> nmPilfcq+eW&6Ic8<@{EL>4em&ARUn416BDNCO!FvARokG+HEC@elIi&Lg
> z6s47^R(&SZr?$8UGgg$u?ph;aTB9_~iJcJcfXm3t=O?}xtS;AVaP-VACz(rf3+Qj=
> z7SNfG<qG-
> MdPlqHB$@HKLhcV0GBQ`leYrx?N1z$|EZ5f5KQ%SMq``jh6&4h~|D(`h
> zNpFzUsu1#52F^i&A~k{XjLOdIn{v2PWFI-
> TZ%QwvG3;=M5JA0VFO7(XW=$oTLtsZO
> z#^KYKg_|elF^sv#0)K|-
> VQ5D^>1hHnR>stf65k^y>W&TP#_;ex)5xuJgOuc?pyR#6
> zUGAG~m23sSp#__cA6~h$&s>_I%n}~+LQ3mVdRg0*Y@1i_o%V#wVbS4Te0
> MSD<obDa
> zUWrXx%&xe3$C^GN9%cdH<?X#jYZ-
> GkcER$qCX)`M(vUv?L*spzYAlPaHHP+`ZV|7u
> zM_&**x>)h_Fu7sgT<>{*uhuooKIye<^7Ynanx$I|vr^Zr#|9{?n7czjF(j;3y5t*a
> zX7+8KvF4y@ZUvE9l*+GhT3%}m2U#R_xHK1XG~1eWHp3Qzqb%TF+pK0Gp|
> |NT;UL$i
> z&tDBn!iOz!m>cp<1&8=D30sWpzRL<Tm-#g0)%-
> 4Rv<ove=`GmL6yx7%9lmN&+ZXQW
> zpoEDoWqJ&?A%OwejAW_Sd9<+JyVE7A)}<AAfCoxi8A~(t$Au=dvpXeAG3R;
> DT^8CY
> z`Or7yl_iY@WArVg$QZpE86H^)Y&&(x7y2(eKjJ@Ucy9Ke|Ci?*c!sA%UgKG!OV
> 2xa
> zp20J!Y-
> B6X^RE8v4eYPjx7(BDR~;|pa68dHPq)w0BCA`z#2&?$Irqw6^SAiBcV^`K
> z-
> <TQM@$H$B?O!9#@`E!Y1@{nZ=046wJuox!i*L@1RPj8Qv>$zi{T<*}13&%iGb8
> ^=
> zo{RYVDt|vE{XhSUa>)P1ud*+~?^}WY329I9ZtcS}i7``HR8)M7|F5KEkUb4PCVI$
> _
> zV~!bW|4K`T`SF#9$I1rVzY)hAdRY0$!$(ydp`S+{6&tN=N8_tDjP{?%Uy{F>{9Vc4
> zMfcB)H1hXl{?_uhi@y=nKaRfz{C$+amHd5{zpS%Pu%FrApBCp#`G?spQ5MXM
> !z(@9
> zn}T(HlQ@VUVL0=O+hxd=_yPM{m{mi?mbqJ}xMPKTM6{j32~LI5>FE=~m`m0
> OMAMV`
> zb#^}^JE27jhyh6K@Jj<HW$Mp6D{-
> B{$R+u&P_2und64)z`R(KISx;(6m3H9R0Mn22
> zi>qcA53TJEy@^)Mj^@89t(slxzrl)cTQE7~90cDMb3yS&>%3<^V~Z!a09!l+i1hce
> z+F+#d8Cr@-cszoJgB_vH`xfle<Y2EIEn-
> 7GIyXKGFkSoF5b;hOt8_oM)H2Gj6aG4p
> zRI*Abcqu1NR*~_ml!=&BWZHMUWs)zn_s$)9c1NPp)5Oh{x&3K-
> >z2O<8eIu1Rf3Bd
> zwJub`55gtvW8#9zI`4PaTL~gDb`eUGXGIimm7<sV;4I0Or(Xcvj??Na|0i3NMJ=9
> b
> z-F!IL;@N(EDqxx`fRc3%X1M<=h;ZP}b}ezfzdd#(f}$~aciKh>PCsQ9a#Y7*di;7e
> z=IZG<PE9DchVEDq^g#9exBn}@9wKVf@b9^_z_0i-mpE?dQ-
> #f!KJza`4?n!ts_9D)
> z@~?^Sp=Cx7_oB}jJ$&(QJ!qC0J?PfLxp7Y&aP%<7b--caV)cVPCcE~cbgp-
> 3Qkf;a
> z86turCQdTSh<=Og1crbzI*t_thcuy#9m}mwR}?`DKz*Bg6?F8Di}N~~>u+}cR?-
> Wa
> zi!@&sDd0M$4b0Lx<O*#k4(Pw`B1!d<+k9er%|`-$MU3jw8`-g%|99pRXTD-
> jMvJyL
> z&;NVo537iU<mRIB2VWrw>R(I!G{EZLdeJ|x-
> !?{i{5@CQo#Jyt5Tk1X56Ar5!%MKQ
> z?U152g%{4ejA5y#KSR*?>j2?#@o^wJevv+OPmUq{bF@(Nw~*P8xtdO)TgIeY
> qUW0`
> z$g+MIT87@+RuAuoN=4-T5dZxlKD;)Wv>86g-
> mkTrhjgSZejQbMjaR9r33jk+%Y`8n
> z1noN^{(v<tuYJEAlWSjEcZ0CmdBTk+#P<lQ;(>5i9`-
> ?DUCYz2Fmf!1$|37(U2AoN
> zlX{^WoYXtr;G|yspN~S0r*<i(-
> rpCgjgvCh{Qrc$%T*B@ZQhq%MTWvV7X&D@`8{C#
> za$}!S3_B+=yqiiY2|7SzSs_i2UefrT?R0wIy;^-J#xZiqnZnPrSV<Q)ju(o!ekHkY
> zVPj?dzHH9({G2*;fN+iaacE$3mj&e%Egoy-R2L+B&T6c11r<_ILJ{`4gQ+n2{;7#e
> zoIG&F`Aj8Iqv`LO*ww6N;oU?IHYFA&xIx}E?o`ePKb&n)yALOBxOAy?1wg-
> $@4G}4
> zP<5L*Vr8A$I0#i>Qz3>3z2MoY0hpoidgy}GSda6-
> H$>MJY1|ZlBwOFjCZDu|GNpyv
> z-Fr68C}fnlYrLr5wSAJSHvWTbuIl_;qpf~52*;v2m+8P=*5S;S_+!~@L-Vs;>}oL`
> zp~p0*o)yciYfF%Du5)L}TZKm(#hp5w@+^KY3mcD6Lt&b1>bv^B=+~!<l<v-
> 92rdn$
> zJZ|1W_-
> nFrK>wRob1Cq5gugRfJz)iDlENJ!oowf)r(#Qo)+~x1&b#B?RgQaKIqF4s
> zM;8-S8^)Zje*NQCMsPMG@e@`7&wSGPTgVAz1<zu5t2J6nN$vLa_-
> 39JxnbVt=6*I$
> z84dKKNw~LeeTwaxz_Ws#r(hMA;dQ9xP+xEQSZZj+85c^d^S%y?$q7Lnlj%)M
> ylk%V
> zL@ll6GQ#To%S^kza619u<a?c`2)u>`haW5C7bN<D#hy}^SQ)QuQi+@`mzyWEs
> NTDe
> z#ffX)ie<eZd3j@T=E}?{$>U`s6f@UrV4hPn&B|Qo+&o|&|7$Pdcv{#NXTFs=$t
> 8L9
> z-X;0{afO_aE9AuV_2AW=9`HR2PP9~9Vd%-
> <&$H@+Q5yX?qcm!+t<_+Q4AU$1ZkSw5
> z&atEi<8+;1{V}_m=Ux8ur95x*pXc#>&JsTsrv_C4$h0s!XNkoj)2r|p8$V>NJb?cj
> zqi5>_xWtoDAN|t3H&vH0D7~9zj9_Z?uBsn}NVngk^t;~M;($4#jb1YPaOH$;_B
> PK%
> zpF;<zJ}lWWL-BC|z2AZ2OjjjpL1~eppV2^DsPj5T=JJln;5AIuBfbaNs@lId&mJYk
> zMhl5Y>p~Nc{si#=T>Is_+RN_b>Ew$M1!{X5kw(Mb#c#(oY*EY1(^Xb6WnCIBO
> DfVq
> z<b^E;20KOI0ymQ(wjbw{u=z%v=Ihfe)d-&P>bcfEU(t5AlKHxE;cO+9281!`XAJiK
> z3*7V-f7!sZrms8GI*sIjE@tz5qe83(?fs|cz5NzTRsK6ur|-0T%ch+LQ|&N!uE{O)
> zccp4}5#5^Jw9XoWN9QiCjru%n$s-
> ~LgdO{FHG_tiT&G2{_}e+wPl9qN8ZyhKL!@W0
> znS&Bwy++Gdyk)P{5W>`;wtDY1myHw)dC{rC>u9O2Y&oA$w;jp#lUry6;r&JwD
> cbff
> z-LFmP=ct`<q-h<g>hX3<-
> rk)@tv}%awZQ~Bt6+|lSfr2>&sYUk9pRXx0kR)>5@dhr
> z6Asy9LH2x}v%K;VQUhE+!Se;z<sxqxeGJIo9r^h(u@!$q$ykpSfkU@%7DdElra+
> ph
> z+2dE(<+*!bK57fjpn#D9imjf2v8}2-_+b-cZ%rPlT)vjpzf_y!^k3syt;aSY#uz8P
> z%jXXXo&#FR(s!TrPIlra+a^1c!)6GZB9Xl}7e^YI%{|E}5uLZx+JuF8?8m4Cr9~X9
> z)HMjTr7NZYK4bCVbwi{nOLW_Hxjniq*bh->Da49VJJk^XpW(CL`Mm&_vS1-
> Gb~;@8
> z_6A%Qlgm0Hk}MtR1$5Y<(?mWB=RUU@6Qw#1;G^~DaGFTfw&d=?MbEd?c
> 4bDavlkd#
> zI|f@&<t`9kRO?Nx-
> 5I;<_rQ{`Xg;^^(C2QWGToD*gRG<WzQ|?1u#kO)_y7<pPGK@F
> zA^$a&>}@DacmNYD@XDZB<^zTXQqxsb(>b+f=aM0YwX`V3TF^=B(w8xQ*?9
> ANrq1_n
> zJQdUz)$EBq3F>?M5k8WOqso-
> ($HvKQVX926^%fTr(oU9Lj5uBCLnzfM_EfPSdE;=r
> z-
> $1ZbeM|$N`B)yUZG8$_y9Q0;qDwAwhY3&OM~*M;ARWuM*#|p#UbG}XNS
> %#uKYEkt
> z9F%ET70z?-Kg^JX^g(Egb2NTbB-d7sJU13wjBsHx#r__^nLIasTcK7X`o-IRoGpi;
> zhsiOqmm-
> S8BxmiJfqt|8sWK4mdyX2t^|(N))bsn^yn0Og7;J<_IF)|$wz>At!k)Ln
> zI4dl&E1$Ba)N}<t(;KMLKP9=jrh^~+lFkE-ci@A&(P>aStsp6fwy^ndQ0`9aHOF;2
> zB8|kn)%ke>BK9yJI3ZFc;>F_}iA@Nhom1v_-
> {_Aox1f5e1Fk)_rt8MhD36diTjwkR
> z|IB%8{Q2>IB<7Zv*<}|ObOkxln7hEObXIt2{meYd*z*f0qZaMPC}Re=F5`!A4W
> &mq
> zNySUU=;ElSbNWg-
> &l~;sWjsq=@o8qx6*ngOsw<Mm49+S}28!dfz0Fue*$JajZE5t2
> zX!H4n{rHL2^9loeJg}^34@<sYkRZ1_Hq5Qw4zok%FlOlh7bA$XWr#k4{E${Q|K
> N3_
> z$&e{oSHV{n+Vlm3no-
> !+QKoequ0d_PqeUC+c|_5M5Ug09(O*CPnj#o&Ru~k{dW!b@
> zhDYsNwIcJ3{AZY3Dv-uP#Q!?ewxQ&BY$+-
> h28Ib@$~2{y#e<6={**DgX!3Pbs(@(|
> zJ-xQnvBVLuMDi4oM|aOy@R{`$Q(-m9b&wu!#R*3kBZNVG-
> AP|v%%P~Wx}+Ay2sJ)g
> zJ!<c^WJe*}i#;&LHbQObXtO2czs5wg3q5<rfQ+?LjJ47j>&_5k4Znu5?u4<r$T%#
> r
> z)o?D9hpf`wAP{PGt0vmTlJCjcqxNo3z8+;a^nLD#*`VX?TrX}3`LCG}J6sThfjY)b
> zNCcR+j)~(39SgsvV_HC9qQtCOgzu*U|D?YR#xkECu(OaUo9EWqt)b3_U(?yGb
> XGq1
> zaJ3@NVU(HCHdTn!vYtcgeNa(Jjdn2Ix#F+>B~$g=C=oVQwdlB-
> ADXJRHoTW)_Csy1
> zKFo8Nha0_)_RkaSL8wA~x|1%rM~{_+XjX(mFvCQxmUk`yIZMHq@#Fke?u0<
> vc%PrH
> z8OV&$rW?Vt%Q$&P=U_p)k|i@Z^Sw|P=B=j-
> f1KrXp3(H+A)eI(bROnNWFhH+&bCaj
> zet!}?D~`A^7BQPZ@d)c5|9byw^7?nG$%*{_jbpr+Fdoz4(5dZ>1NG~tp?-
> ~TqpgEO
> z{dxh$6zbO`(u01@7p&i}IXn;4FB`A&Al_cyP#Kev*o8+On%q~=h#ty(9%4cjWu7
> G4
> z4nSFX(m0Lo@eqXPepNwjWi6*MG#9oKD6T=13w^;>>iIZ06FsKh`#i&9OFNqe
> gw5eZ
> z4ySJPj)Dcj3P-;v7{fnnGDod5Hqg!PY7I4k1!c)t%MTwXqO;im1p4hfp2I=5!~A;;
> zJ+AXEajl;Y;uNkyybv}{tF<?JDJAD|Xz~Z^$*de;EkZemx^kS7VufLO){RY^-!gSW
> zvSgUw(kzwPcvSfFr|;xpr_Amy>Ow-
> RK`XGNVF_Pc2BMQ~Y<(#~4K@vq+m$eScS-<Z
> z(((c2FEAQyiUbKLDOFw^Z5*`HQrm{`7h}bs4m*y;>0`0|kO4_%6xE_}b_aEjj;n7
> b
> z@Ryr^Fk*(_q+Q%bmSJvop`x&^z1mNz?cOxA2=1?QAhPO9v#9q@bY(XHA0>
> g>MrLc<
> zH1n`*^T(?_+`&;k*DDX|Lg(penO(tqGaa<U+%Y8_mf@7SA`G(GP+sS~X)y_8
> W!N<H
> zP~yIKx>~;FOf{B+x&!mUrWvE4ZS9+gvFOI3PVcH2j-+gS`st@-
> PiZ)+5Sc~vP3xR8
> zt#is!Ba$16*<(O;mTf6RwTxA?h@oP;0V~5Z#_>SCmV3qMQ3i$=UYX=U4;v&w
> RyekH
> zve@rZv3+CG{pzExc}`#W=kYU*LT9*04MkEWSeCQCe&;<YvUVR2YHg)Uuj*=P
> ^nAX}
> zsBNaFk%(_mOUzOPIA<=<qM(!eXieU;FD2z%-Dw;I3ph42G^c|*d4~>Z@-
> Fjuh`*I?
> zVltmdZ)`Gasr@!5wltaD+0Am&1O7Id=Rjv1&$IYjFt-
> ENZR7PX;$wpAeFz_~{Vj}-
> zGM664M<B<}a|*dk7anBYS?|4MBP%rI`VFs_Q0_p*DB^Hq!0YF80Hvda1tK!+
> M<HBP
> zYz7xc(fuqgUPA=ta8XHmfQwl?2e_Eb^FX)|lQDcu?i-E(wy~T+%^Io(!7lq6eI5fq
> z22mrO5|~3@0JGk3hhlBJzg8hidaAmT5bP~ATU!ZlBT}*4CmLGW8(vDNC&J#`L
> @yw_
> zqM98*W_Az`po%*bxxI`vd2MIwyn+MvgQ)O(8^se-
> iuK;vGMklhXY9xGJ*)&c($rVB
> z%+xl?TyK<l4xtn|0daXdczkJ^@W`4};R3$O4~IvsJ>sMXc>EgA0Up1?^A2Br-
> p#Xg
> zg7Xr#1j(9s44?nRKI+UQ!3@IIajO|gnDd0coCyDdRi$QPBtb*NLZ;Bp#?5(e1|Do
> W
> zQ)+r(1ZETYxQry-
> LIr28xfiHVjO8P6Mr~_?ksiC@3cfeF&U<H~hDl6YGp&AFkdYTH
> zGbf9;$w1mX)nUV@5679|29@AO3Rif)bs?}}0XPsp{Qr2rwO@O}`_Eg?`seNWf
> 4Tqs
> zf%`L{=@3IQJk-
> r}tt3&tSpZ*d_=CAau*kse2FFGM(nsMayPt<Fr_ui4Zkq_tqDtv3
> zy(9)S8GT`9r1t91es1wC{g%52Ss#Yu_w1lF%m&-
> ^<+H2U$|!Xh$NzzA6jUdl9^%x$
> z1DLh`rzj4l75J7&|7zrJw)gO|E#!`J_3`c_d?-7J9b5T5Wk<=FToh}%pJ&CqKnviO
> zm^$x<5k^l=*hQ8uX&CJ-
> o8xESYG?h=X()3Uw$AnLI73OWOWe=F@=JK2Ni@yh+ET3p
> zdkSCcJsWz7P}#b9hO`}4#6;Rc{u1wC2mAf=w<#`0b%njyCY{7<I?75*XAoAzBk`
> 9#
> zTN#k=Pc}Zm4B--!;R%6h0dy6wgR!|6IPI;-
> AoMWL=QdvJf^$3m8t8+tx<I88O`K((
> z2ZYx_|C2~aoahLfZH`gqD6I&*ET^&6p|R|-
> eUW0$Yd^1PDqZpQGhGujO|$=)e?fh*
> zXG<E0)4}4XIyrqMPm#n?sbL8oiiX|H=hR_(xn!_+5hk<DrOD|_4Q6C&q+q6w)
> K5~+
> zQtC$^)H{~S59zzLcC@dsgzqW~=4E_6o2%aA@S)_!(Y}|3Yw@Z5Tl{}%?<1(Rng
> 2Lg
> zdsiuSR-
> g8kXWLtbICh(;58gmm>Qck5<EuX2u14=SF_z!xTR##;^Z%v2J%e3)ms3%M
> zv)CgI`y=%e{Jx^pSr6)+@T>1uZY**NA&TEY+Ph8d{loz6eV%zD%5)?VYHxD-
> )8vUP
> zF1zWF<n(ns#+H<r)%af~lvCAI2xZ`oj8N)F`*h?331z4Huu2oO51|ao_94`MT$ZP
> n
> zs0%m67GrZPn>tLLxUn!Zp>=+xTSS4Y(Xf{a?nTT}V}~j^VSq{=oD@csKZB@mM
> dx_5
> zcj5!=U}gK%P*B`2KES4?9@M$Wrlu}HU@zR*h3OpEeUIM?h^TL>jKn=^H^%z
> zVs(=_
> z9cy}pgw{1X0bxH2g@eh_+N7WC_t~t$33?AdQ?2$nVs6U)l+Vu^dsU4$kV}+@
> ji1Vr
> zuOJIhUUD77Q5Wx0@4wbcCF?8ey!|bztupzHwJ&i&s#Op5@v;YXd5QWo*IR`
> F0X}Q?
> z6rwei)x|56+N!SB`}dudwyx37xvho=;&Uxho~Rvl2@1a{_Uy395Hq%?qvCpqS5l
> 5Q
> zG-
> %6WYYV5<)P%Y5ajL{GZg5@`aB+)|SE{SiOS49%fvtx8y4F@TyWTtAH6b%L_UuT
> j
> z_Qk{zuG&eVl7Hy(#wYX6hGijE1{;>f!;;e{(aOSQLpGP#gGffVn<Ko-O;3%_P)R-
> _
> zuC$WMG8NJ=<8!PI;iS$x&u^at4A7dq+A8w97@tQ5??8%o8ka@QN(AQ>kpz)
> VE9&DH
> zDgBQ@`Z+E=e!1Rm3Eobyx6$OX(GeZ)s-
> %&l!G{~DkA1_6^pO_7N;$t6<b3ZgOLSsx
> z=}U;Yji-gg+=-u+`?qERV&+y-a=P(KfQ|MGBaxr;tjc6SdxB??Fw8gd2+tpDT)g<|
> z>l5>?{p{6|IoDo)_38E*k$z$-
> |JVoB0*SFBDL>#=fjzv=o0U!9H=%#}L*m&oHw_aH
> z&*gUO8SLMQg;vWcGpv?m&*_UN$8P`y@rU_vKB?#szcr&ldBbTohN2p8j@4
> VbspMLI
> zMKUL6beVdc5t8@Vl`1Wosfe#rQJ!BEo|SjHg6Pehyw+NK9uzeNZFK#ANSw>s
> FMbxJ
> zi3NrDUBIu0<@j}B=IB<~j5c;G`YrwvqSB2RAbNT5G1`7=j<Fd(D`kM-
> XWdMcr;>p6
> z<7YBeK|;QdPC&Ae|5AxeGz~b8hV<8)qggAGeZ0vM9SN=fA4q5g)n0UoAIW-
> 8gGfjf
> zgOoG<2KoET?LY@Kw1a2SM_^a|p#GOH8KD2@UH$rhN?!j1eW)Kk#|=>4R<l
> ;*<MZbH
> z@*s$Zq#N1zNfgTZI8wUQCR4b=;dC^fh}X}Mh&FfYs$qKKYQbiENSThMy;Xa7P
> =!ec
> zutH5c)4rNLG!U5~M{kFl<)Pfq|8`z}FE4-E&(A3Q<mB)~%E`Nf-B)WqE9DK-
> ;+0%Y
> z9G}dGciU_mbT}vb`Hkfb)8lnYi!1Fv{50Gawdr5paCZD2CH_E(HGU#-
> i*99is=VQ&
> z@vTbSqr`F9QkjRTnbE1$#fuf_X(y!GFoeod^(^B5%JPAc_E!sN#)@whP1O}w)n
> gmz
> z&Wy7cJyT~FFGg$DKA(B~>i|FogE}vIs;bG(a+;ew3#Qa|FJURbt@G}lT*d3LiZlz
> n
> zkstOu%9Zl0aOw{v_YLD@HM?9j-
> J51`m=N2ok~S&&2pfYmr5n2hk*cCCb<ud`L%vh#
> z55M9!+Nt<BMfPsOlaUQKTWKFNK1Zo;Ky1DiyZPFy`MP4D`ARjqxNlVa5mMu0
> sVzQ@
> z58od~y)~P{sQ9Bwk1Kt-(x3I+Ss1@t7=}^t?<xHOrLR-
> ^{Vv@`epLMXO6*o*>BA(h
> z$YxfT3tMIy{&}<!yKzRmy8ykWwU`-
> %4#tQ*K>O*Z5bD47zWHT`k0$jk`HVgziQ>n&
> z`8D&?(|z+y=_@dkNmU_c@-
> <}pijBewWc>C?fjpwRNIAf&QFT}HeBSk3E$v5t^7-kC
> z&N7G3F5z<}nfmcRhtI?;5%w*`k;GKPAUyGO)9uC^O}uV4=wjAWqfI%&?|~~d
> UdX=X
> z#79MT<8?Y!ZfcTa0$=axYjcz8r*<etz7pEsa?Hk^(p&jDU2r&DqaHbsg>H)o=27a
> (
> zDM-uI+Aux9=pRhZb2d#JHTjJ3)dVNc^Z=>FM>BM-
> O)9X?8*|M7*gwS2)HuQw+0v>}
> zNgqlrsWo~uN7qkb3Yei+3KMUyu?NSkIH|OI)GhRL>tn2GlYW|FCI)5&X3KJ25o
> QX~
> z_Zgh41Q*)M#PF0+hWQX5!W_4n#31b<^O8$us#er{$1b$$rS5w*EXPqNn$|C
> wttF{<
> zhWo7>VV}iZsG`|!B4KpjghO<4g@mGP!lqdTOz=loqW>q`{cAL8)&f1mp0qKg4}
> @H6
> z)wp8&(1pN^XX^YY%;(0Vvpr4re2Q3jt;#pGwmf#{7zQEs<QmH*OC9K3o*9)b
> GPu*b
> zBy941mANo(Txc$&P(oI06h$)^UON#yn=PEOB9#CKb74HsedmHdACjGQ*n1y
> )s+=tT
> zOfdPMcVcNX1?EmjXxju=bkq)ZA$oCl*8Ra>B|nCX6Jo7*yQipjVS9%q&|`ZK)d
> 8s9
> zQCtb^j&jJs{NzMo=Bmu4V2kUMjjARr<&2GAWOCn>+a`yguOKZ4x#%|hPO^
> |Qm$CtG
> zM?_TaIkyi^UyL4rmvu?HP71-Y-my#Z(Z-p*dMxwx!(_!Jo0$;5P9K>f|A5AC-
> T`=H
> zg`I*idzQSATZsp*Q`_>VX(fPnYwgoKujBa%o_F!=@!VY(UrAXi*&B>fg;~g1cZM
> cD
> zM9p*K>r_+mcf!?O7OE~2hp8YnbgK{%kZL@FmMEq>!H{+>YN;PY>Z;l&nrAC{
> Rn5BQ
> zYDt_`^Pg_6m)G2?+V#z|6*F;F&Bo?x$|0$}xqg@>ZEc<n>PXtwTpbIH-
> t+zlCB4Qv
> z_@YZNde=cb5As9Avl=}=vXJD!zIeYtL8IQ^%d>1-dj2xcPw-
> sH^W8k_nC7Gb4r}_V
> zg?%B<xW6~pPwuzx@4KvQs?jRi-
> BfP(UPIo?Ev^<W6*!MFkma0{sB9dvs^&m(L37Q4
> z%$w|!6N`$J;vvbN35^r7zh@2MRK(2+7~ligi;EhEZ>lLR&`W}kHrFx}6{Iw_azDM
> v
> za5IZ5H=C(=2z+hjZ%FiCttuYUT=Q=1+1huL?^nVNA6L?|^WUB8Jz^{v=7ZM_F3
> 8K%
> zQ<yv~GB8WZwG3DLHz5$YJmB*|j^w@xOOK5`Tk~$RXUgp`C?32C|Al6Oq5rV
> w1y|dX
> znd>002p|^)kQera9OocsE*;~_Jm>bqU72V0flQBL@KAZMK5N^sr{#PCrKtCZte
> Sto
> zE|>=?jo3dCP2Hy(LnR*bWdruVFmtZ!e8v_D>b!r+?MLZ3B<lCP^Nw842khs{{0
> 7-&
> zfO20hI^I!dn3#ADuMgzsG%9`#v=Se!c{Yg;?+@k`0t@2w<*0aEiL;e>xe}jsi8eo_
> zF)&@~yqCYFuCn`NPG293-wY%Zs^04|3q@eGP58=Ne5ulvaa-
> SXwv*8ZrQB&@JM*{!
> zdhoC5cjh`UD*m8azg(@qSFMlab?w_q{DBfTD)EhJ)(czPO8I)@0>4)Y-
> HS;;bq4ja
> z<u<7FbZS^n(+#<3*6LHBRs5}4kZ2W>&G~xT&jLN|i8o*qcOM&)O@BrrXZ5sd
> QgX8C
> zX@CRS)XwujvPnZ78eePjb*!gBC*p_ufiT$d>>JU!9~<6lyXK?jS!=Ui6q_rvm=B
> d_
> zNcH{VwnO%mPf_{j|By;`-
> o5u)JqV7%%x+fN+^v?Vw2EG1A?vqBZVATxPkK=AO5-~i
> z1re6_lo?k-
> WMgNp8;&>V@xB7=HirV5vaV|VOyRcO>^F<mo7sU`q)eS3U92;<9PYx}
> z^|!C(n)o}ns0g+No*$F#yu)X*^8@^otmeCn06;9ZB<7UXUcVB8B-
> =79euGwZdw=4!
> z_OG-Zi@%}NK0Cv?$Ml0ehOF)zm(n7`<R`Mt#9$koIp0kxoDjsb<0-
> Yme2Sz~U>mn1
> zR`uS<AR`+~JK4jWI=`1E9BJGEt6qdKt_4h7+6Ljea(dk*18VjE)L5&tduw%XLaQC
> e
> zh*q&RGdUmTS=0#=h+IS>JH#gAuHyNE#srH9XORfe4|blj0S{3iJ?Pym6hKS<O
> ^tK>
> zaz)GfNB)DYuR(pvcl_YGJ`wmIDanerEjAeHA<__UF=q6JEd&@Nw=rk#EZ#e_E
> Q5oq
> zrxB@W+v|mz6!@92fB-M-v&}wIP`2xf{|Rf<9_Qc55*pNZx6E11Hkz;~slfKry{^<?
> zJNTBPLj*;CXtx%h{!X*VI%SLT($)3er7o+A;|4-}Z=x*)cA|0;g~-n3^0$^YMd@q3
> z*XpJ>19F%H$d<oEnqj?nH{$|IGH=_|+W#@@FW`GdXUjVne$g#pkppY7U})-
> y8&5$|
> zBs#O<snF<<eeq~&)+&(pE(=g9MohA<FBHB0(%=}Too=EALjmTx(?~()i|hgMo
> yG{*
> z3teq2IIty&-g9cSYrtG<z=-%RWznASr7lanLocK`%yBOO7r8J}3@$~V;lu3-GLCgG
> zGT(@MLDms|Rw%}d4L><5G>(os`}12}i5#ME?#1e@k9Sg}cPOh6O*XkHEvYu-
> 0LV~W
> z94?pf3+!#I2RBD1X_G}xAQ(VOqc}7%B+E0WQwr``V3)7@65ruj&x6`_m&y5A&
> x6}`
> zSLhjk)$F+s%Kt!q=AWMdSvtT$*4jNQmW@^`ZuD9I5zJxMjChb(i~P4mddsmS
> osN+2
> zWkFj<w5Z)Z%QZWAE^6zjC~DU!7rDUKvwP3i?2@+EIjZiS2erLk7CaAbd%dD)y
> S%9F
> zM9UOTm;3c$7oxuMsWsh!Z~qFTAUx?omX}+4X)0r(lJk`Hf_<h=96(rMXWqc+g
> %;v-
> z4M*m9l1^JOJ9{_)Whvb)^<#DSa3||w3fJJt6UjdhAYU1x3?t=q5Ld&ZeR^Y#cO
> 60F
> z+!iAECIl-s94u|+FYOjy>&op7s`uLJvZ?K{FCZ=zr&VSry{h8oj#}b-+ly3n#Y-I!
> zz|fia&qZ6R*_FpWSQ%OJabBkCE0JtgCM}L`o>@Uj5~3*>5vfFxFP4;VnW<ftR5
> by|
> zjit<Vp66s-)KXW*)yvtu=8^8dPtTXS%i3XWeHlmkORKi=gQb<c3S(=}M-
> 8S=6)(Nb
> z_s}{VkD@L0<zZ8Nh<^`!zxFzra|jL)INno4z4vi2$-Lk-gD!js!zF34c2Ls2;{6De
> zwrq;^2l|)EaaC=1bE#UDs@9QjwFKK5KWU(B3S$?Sq$TRy4LfV`PJjC!{3Kj%Hw(
> vZ
> zwZN)g%}cQ?a-
> JWpYPVZEdRR~PE&|Iy_r`u%(~FZ;y;Te860hApXGBwtJ*&!3CpNCV
> z<jO-
> _@uDr~XGJUIZY`3jZ!Bkm4kM^E#ikW_vp4hIGyy#i__uhUKPpQ+S@}0G{;aO
> @
> zwzLL!QEKJ+lUQ@8GvKK=`Tm&2vu$;_+z6t&{P>!l#7HIi(3MCKL1!3T|K+UnPjbl
> U
> z*`8*K670G+xo^ykzhv}<p+&JL?<puhR0FZW>2AkJyOl?iG?H$C=`N-
> dtpVwRXBnx;
> zOK<wWV7w@Ih#gI&B77jb!M)$-
> 1$bw;2@~RfqPeFkfv<v(Ft+6{d9HK*8SV#7qJv^z
> zbr_K?Bw)?~{tzKOdIwj~7kG=UojqESy_Qov>rA!m4wIC!$#Ot-G@)Ed8c-
> 5Q5X0lh
> zxl0(wt6<ur=1GAgq28MXHlZDycZHsjU2y!l4bB1jWnd1L|6!MZQL28lh>VsoBW0
> ;c
> z)t9%ut;xP9b$8t)a4td-
> o>%OXlf}~WZEU0PK!~vXc*3<XwkG71!Hq4H#n}2U=hQK_
> z8t0zvZ)+XRSWQ<+%bp2_KlbFxA%~Z#`8xeb$7iq~$yhN*{KH&7E)RxDXtaMO
> PX;`X
> zNe%M705{{@`pA*y{9cR(O?S}m9Khf#K+nV%H7ym>nu*C|CKGg(o%iY_bVHk
> Jdlt2T
> z8Av|!(!nwT%mt#$Mo<&Bf#{}{M!k{D?-
> @DWKjiW$RX89Fck5dk4<oiV?`Y}<PdE?0
> zKe+KkCm4;()N~zRU2b;*XqpiFQ^H9Mq9@ZqVLe0=Uq+OM&LRrS46zc@MJ=
> @mf*=(B
> zoA3McM#sglo%A%X9HNOux9GKnnx{!NqsloUc0q&qdA;{XNAYSGY^ld*OFgi
> q9@x@{
> zg(r&J<jSJ3910Czj@|TRerx9t{qngHblK4#kTdgps$S71MAtWnhppJ4mg-
> J3Ka32*
> z4*D*4M+NRC%@=(EeXQvG0T5i-^~^k`*i-
> 0*f!Q?YRwr97B;Ir#5Sc?4rCRmiFkz3e
> zwQKYyxvz}dan>4`qMy&H*^zlsqiCthXi1K6>@l|1&u^44-p`9-
> 6MM3}U{Pw;{2c=J
> zp)jSyo-
> 7@*sAU#@ZjW2Jw^8fA(YP6Y1+lgF)GQ@y_UEjc9eyRxGQ}cQe@Xr3rH-O)
> ze)^)8dumiu=G%<K{djx~G1-
> `24hb<%<?AfZ1`u>PP};x%S=KT2**fn6z}sWC(%N!v
> z6FT3=9TH-
> `ngnuH$fB1#zd?&yR@S<<Vq|xCu6o}3{1W8sMgojHl35cPg){t0>=b8J
> z`_I*+mv(2nGq2{6{)3o7kZ_~M+LiOwSBh3UUSb}HM~cqR1_|YUi45%x1{}cX*
> VH!d
> zXK^i+t8&Gnmg4&UXvjRz3@D}ag;oGX#)SFp*0t30FLjV4iWDKWD#o7SQV%{Z
> ^+=E0
> zm##^Uwf>2IQnOy++JitWEhDpzZ17fJT*g$GSw}AS?rxt7EG@Qn*8E3`+R1Q{
> W$^RO
> zFQ5AS?HBo3;NF(yUm0F2W@_8AQ9dr%hXLu<0j_?_{3<=xwN_2Zj=qcLP7a4
> wHwOF2
> z+FDxYZqfC7!UQj`+U8F!pAHoA<Ch@O-K}f)UNxRenlL=^MU!6hW}lS*;-1-
> (Mk%|X
> zmq8NfqLvYUoJoJCx)HKa+|;f?IsSQ^Et?WN#ny`Jw5~i~#kANfG*&AvwpI)0Rz
> #a?
> zImN42i?;9f$tKGWJlL~QQ2KNLvW;=LLO$4VfjkWia>a%q{SMkq*8IO01IQnTnX
> %5l
> zEpO&|j@7LepI=D&4l*Cdb1Tn}_|JFpyp-
> p$ykE}qClgmJPDC!e`r2#aiO9!3*Lb~e
> zC-KFpvv>55m(;-G7X##L=C^>3;FLV}&X$oPS-mlv(qr!8CPMRtiPIdy(ooV~((vFi
> z7l38`WG*Z|^HTaJ5LbTzI)}G32yLy+t3YxrO5HQl>7}M~AR7-`ieB0UHl#S=JbZjT
> zvQ%QzhjzLPvJ^(|znnJ{-
> 9>Q#y0)VNB5);>4_o$2*a<JCm)>3G^wRBa*Y{4l6c9yC
> zfQ7LyuBM*?W_AwsxjAtl&UWbqjiVZ*^w0Hfw{sM%A&MkoGsma_oTY6X36
> dp$FALJk
> z|G5Y@+#Xy6XO2~Sl5ZDMhjf$XdkT~Tv5o>@%0zeiVbmfeJ3TEVr2CbPjn9NM
> BU9g?
> zb>xZ-
> f|(nahG&$M=#j>Okk;P7TSFY>LUibFEThrW*p?2q)o=c@U<LRrfcZ<hf#7Fn
> z;lD5tyq)!1^pI5Iz`e9zl~-F4IvDox{357tT?wQ2Px7CT%|EnX{$%ID&i|pKQ8Wmu
> zz}TUiixMOGEJ)1ZvoN-@oizVyHg+?P!@y>%Ll+}aXH6h*w-
> &MUW%b^eK>{gNWUfw`
> z9@Ax@-
> <`%4iv4v<3&RR}F$3ETYL}y?)p;9P7*RSCTPNj+rSQ0WVb&X2xe}+z+2*VW
> zo3X&ltfT{Mg&H})wfA5odbbr$e>!umSVcejwPNBxtvI`HD^C8uwc?!qt+3`eD~
> W$z
> z<KbTIf56mbQ`XSeNly4S<sXpP4c{!L?dy2{<duuBNL(4u4{j0AFPw2DMl|q8DMK
> hF
> zN3%w+q!*tWq`y75UwY0*+`F&YhLCbL7@XxVtz!>Q69gXdDF)Wr10T#Q$Y<a
> NA1dz$
> zS@6Z-
> @@%YbaM$B0cn&%!RbJ4)M9NEcR+^guaVCiG1En&!;UnO!9Ffx<a@M^2tjzr5
> zz!x->dRLhZ8~W<7@D;vk{0t7t$$||Z?trXX%nyqrq>2J`KBf(9-
> W|5Vt|%e$uK~q@
> zM7(N0!}n__KDb}*OFV1%Rx`?x>qrg8?+b$T$8sgl)wd+BzH#o=+_zx6SauBTvs
> YXb
> z#8b-
> IKN+{{T&3X47O%Z($YdPxXh=h8d@D6+DtNyFb28EEv`4WS&N+|;Q^(di#6bt!
> zI~ll1Xn|t*9dP|>Y*YI+RAtq(wvx%hxv7|g-
> Fj8;za%&=P3%IT&DHj8w;i&1w#Ayo
> ztkx9PX%tt21MZPu9WQ#T<X4CM<LvO$nDD4DU=BLyg2RVS-
> dc%vB2*Ggos}Vz4e{9r
> zlJCp8Zhj}HST|LhbDbq&<799#kYUqool}NMs@qIbpp|WQ>lZx8PI&(h^USaUJ
> _7vv
> zo2Y*QG~NUAj+g&8X6#>#ag_%HqS&>g;(rs+EYjnb3+Sr>P_OSN_ny-
> 4Q~ElkFY(jC
> zi+mkN#rG;b`d!k;^5HG;(`CEp#SL+4^u|%~9>L5L%ngD$JzEA8kgAKaA2BNazF;;
> A
> zrb95pv+WRNn4jH}QSp5Os(VBQ@!_S}asr)Tohi5#WiCV>TbEC7#;G*YIEIa33nJ
> Tq
> zm#SVBcn>nTb>2`L;tKz`$X0-SFmHvWlm{t}L4e;27o-
> ?1*ftSF+EUw#Hcj2XBs#Sx
> zcE`hvtFvz|9+RA&_$Kux4!>|g@~v3%&DhlapT4Xy`svFqO;4fRy_=<UHjZpd7bb
> TX
> z5m#gJN$-
> A#8x6V(t0SvZn}4p<WV(29X|kiJsGU1Hq9hy`+ge;iI^WHLtKef6e{uef
> z-
> @a;4^WatI6f~b(u<D#b%56TkFuAEHx!FqJnk^k4<SeW~6(lzmCN~o>GrIV{vrw
> xY
> zOmb6!TDZADsm<9`%E(aXPX4y>*UsO1{?_sL7=MrOmzwp3JuS1oxQB0#Z?3`o
> LMPvy
> ze0TBP#dkN~-F)}(-NSb;-
> @UEHt#mz7)K%2uql379bh?zk3jW6P$ISlpWm}$GtsaM;
> zUGM!jv@s7Opd)~7O`O)-
> x^zmfKL}%UgD~tL?|!G3dRG@y%YnTwgXtMOQdTe~@4GRn
> z(wN*sTYwPo>W6u5=dX*uRp%5PzrFd~qU1Y<y+0fFei|xTZS!GrWA#p9^3OI3
> %^}Fu
> zAvk(K5B)KFrzrVnjcn|W1#sq24$7WIgXZuzkH3ZdUB%yZ{3ZCii$8EZ8eEU&yMp
> fu
> zzRUS8=evyWGQLasF6BGQHyeUqDCWC3e{39%9-
> zEO_*=){R+Sx$%{fJ2AT$>Co8E@T
> zfxZFb-
> sO#*FN^inSn!;&_(<K{PcFDHRa4x+oW09tX7sX8f9jHp!jm2N)B$loKqnqZ
> z{dLOOsh3-p_1;#UI;S{QI=N``ils-G1-WrJe$z$US4=xnbr5fc^f{A}qQ&)dy(#zv
> zX|JfJcSdq^>C{1R|E14Tm(^tDFG&5R>Al3UY}g<D$<(FMravUgFMMokYJckacf
> Xe^
> zYB{I4WkG4n#LGVQ=}R{h2af%!h=1AkrT$6_U!J-
> *@yRJ?tBrG7zahd8TKaPVPnmZ_
> zZ{v{EjN+oUDdiP-
> aDJjVH7`cXis#mOUrt#w4KS~*PiIQp%f={G;5D0AKoRHS_0q%h
> z`BM&Wj7?ck-Z*5+f{MnHDGNq(VMA^4g$wGv8P@Sqm-
> (F1Df1@uX4A%o)0Pxp(DYv8
> zlMW~OT};gzTbi0Pwiw)8J8}K0S!1Is*Eb%%VxM+>77q`&Vo5sj1&(B--
> Y0m^;?wrN
> zOq_^BY1Q`T!D2P(g2wk!?b?5A(^nZ^&%-
> 1k{KTMlzfZwK9NgQ2qk_wx<FnXj(}v$<
> z=Qwm96Uk2PAXvZ7;}*y6x`uYJ4%MwkQK;2osG(#unMg*8n|A?mbWo;H!EXc
> rb1tfx
> zb|L3_pB@Oz%ba6izTZLNT<^?*!1iPm{!S5mt+b-
> Ko>mtS8cHEy=g<q;QpL)QT9E!9
> zQ9=-
> DB+U;43)+UlSKC3QX0}GN(5`x&w_zZ#T~sQtLI;NOB`UMhb`cnoa?l_%*JkTl
> z7Nmyj+UXafyRTeb3j(m6shXV`0<9|)9cVn;z0Xvj_LRG`n|?~dQc5+4R(}`Fui<Y2
> ze{T=2j(mbYk-Pr+<HrDm$B*4`Ea(K@8Bw*N&LX-
> <snZUvgO}@M85$zrv2U$!ofSEN
> zFAvN|Q8J8ua6>~`W$cc*U_86j(hXgP33oOD_}=sd(t!!+Z{8yq5^#h#e*my?0;?
> @$
> zubO^GlN(r996tb9fxvKwTW^cIWE-
> ncT?E#*(pRL?s!~OPp;E3W`JVy69v7G@<!TsJ
> zT0YnN(Ewm~3rv;T_29`iJjL%C0PO0Z($TKc(fF4Q0Cu)j%7$oVi>y5~lB1@mu4PH
> D
> zl8Z0Q#({QSBu@jS7jYKI(wTjPa2XT3YoAopTBLdFx)?K#BHngYdQ|x*itme#7c4_
> *
> zGF@T)d>i-
> nO#^^EEHL`%X=xr!rpvh>dH}Fx0#l_9xgN;9c>u5lL8Z3HPrgk&!ukQg
> zP7NxJx=JxBoiqSgG^kWgNKtO}!M}b0u-
> 8%Z*vfiEIx7R4KH7Eo=((Qs`M!90Twv<(
> z5w7kd>b)Ng0Cu;))Zvk??vcpL0l=;fDjne}#bj~$0AObam0CpmWO`V=H)Q~@Q
> 9-4L
> zxJnNp-qQeJa<j0Wmbgkw=6do)@7vQY0#i>5Tu-
> ?IQOAA(OaDko>fJG}qGRg3M+Ye3
> zuArhLT}4N-
> KRf`~<v~S<yNV94_dYcM*p#5sLtUkZ)_Ic#06R3O)NTPtzCC=dH*5f~
> zjAKGcZ-
> }dO2>#LJ?2Ckr0#i@z#)G6csLuQ40ASw~n21N>CyGIGu2<o}(su+Ejd2x?
> zsrQx*P{OBzijH!<JF3oGFaX%3prTQ(qEU0bQwIPW7F2qetMoA94G#eJCi1{~XE
> !G#
> zy;xwMKpckn@h=6Y-
> VJq?4xQ_1W2rB$?iH8_X0WStaJ~1Hd@zf3ny?y+TsMpAyf3<K
> z++2-
> >f#I|qk`=T|WHNOTnel<Zx+D|<lTZW<0X#DR>r%Kc7Vb6O89!ie>cIA))sb{*
> zb!6o5>d4vf!SC^V1Ha!P;@Oe>PV)O3{NBv(cY#^R?*zXe;P+O3pTX~1e&53H@
> 9=v#
> zzdyw9x%|G3-
> ){|JEyBAheqYG%_59w+?_z#W;J1^mS@~K4wnF+5o(U#j*N&LFA@Olb
> zqZ8;(*i8J0WmlR3n$a<<ry>m!^~@6z6dV^Mbek43EdcZI1`E0$RGyRXl~#wGQs
> hde
> zU4Y)ykg3tw%I`S3Kwkr`@*%Q7(0Kg4VZpaT^~;FnNkijmHEC$wrlCDO5ZE4RXn
> <*o
> z0LBzqGZ0t@y%Cr+G{Df%t`EREQf9o9ml@WzP|r-iXxJZr-~`MO4?M+U>p^-
> DsY`D3
> zScKRH`Dryh6Mt3LTGMsaLrU`1lr`&HYIY`<?Tj=Y6Mtm)xjHZLk@##q6ms9VNW
> 2_h
> zoW_E!26Kvc<F|0-jNl@ZgN#oG+%kLL`MS%|e!xyNv=ZHD{vPjJb9l>P<%R-
> p<tJ>`
> z_<nU>lb_=4O6ooKs$J-
> ybq!25MA|h$>W`X~imAK9`=tMl<2iG^LG~WEoL&sY2R!C?
> zBvbB9$W`|<SKV`<4U}HhGE6<cI9NpWrHA@f;={>uE~B`AHt^j?RkbOMA#i{FG
> ywb?
> z9}Ew*Tlw@*R^Xov3>~b`1}OibfpggS)BZl?Hx3M)oqtiIjAVPk#4S@w?#3KtVN
> qdx
> zD6+#-BWFB%UL^Uv-5bVUgbZh}x1NUtsF@<g*Z*hr4^UXD&B3_#=~P4m-
> bwx@!%aUH
> zZp(#|{L*M2Yqz~^NUca>?5YB0*2?vXPq-
> J2e@2C2C*t9;p|4cI&kyY1e_PSEWY>X-
> z8<K6sk46d#RwTUC%wBSyzH(1uEU4g+>tTFF4sfF2*R3-
> TsFtd>=UQj(&p!Pl`_$_{
> zSr4uK$<E2GiiOrq1X<3t#MTfScUyAVw$R+UHeT_D&7BvRC!x6m%qiZP_l4$;g
> Nzpg
> z?&i+5=4)S`WbSB{8k(QXy{)RF!_Cj@gF3FsuLGD<yq8#5W#^}Zbag1RSCXrPwy
> >Ln
> zmJIT{H_s?$0^N?8ck@iRxnv@813yvtt9*gv+uCc>QhF(DaP%Gij6}QUr~+cGM
> ~7Q5
> zE*G<K2E^?C-
> 7?EAJyvCm*i=ZDEVzG*!o=|gMoEsAGGaTh?SNbVg|DhmcxyYwg{dny
> zAB<RReg>f`wV%p55cUwx5zL1GUh^%K<LKQsI=LJHJUd?g{8y}z&<0HA^}HN?;
> Z=U0
> z92f6VjtW;t08flhzx)cy@3UcgVlGDjf3Ws@d9BIe=iu#sD=$Y-e!wq`8{KrFV4`aA
> zfazcBpWcsOe$rt6b$)r}2f;gj@!;q)6(C9yp%J+}Ajh!wBLCL+lYd<Yk$?WF89PGG
> z8QF4o-
> bM$K?ELtDGQ$t(AWUgpe7`1ys{ijlN&7D)0yRg>V`~UO?Y6;=iFaw%M;aEz
> zSG(!Im1!87{zQ5|$(xLNn4OvqGQL#PUzxoI3sF#x#e%M~Sl)MzN+|XvrA}A(qn
> 9()
> zSn<z2c@l7#<-
> g=y%a7>WGl1wbd?h>Qn05m|DSJ+RQ1K(!ta^$qLp|M<T(&FHcx?Rg
> z|5Z=pa-
> 0u3`$u2u`+5Rk6TFXqE!Wu`aC`>2tqAYdFI(eTch*pmh1?kd?^6K9vMDtj
> z)5f=h*ER@jdAmW7%sjT!4Z?ai2wDB*Sbq@WGA#v7o0Z=*)SL<4V_yw5Eeq_
> LW<&AE
> zF9l8eo)(XOqo&rBAN3+Ui@4*UA>z;=E*jLe^S>-
> xpe_;XZh|)}Tvry@)ukf58?$wt
> zO<io~#D1)(W7;G%)?7hAy%n#QA`l2|HNPTN%?$6+CU{Q-
> &kSt`##R<s&I%m$SL_yK
> zY-J;#xFd-D##YAlqqag36_%Yx8H!1<?AZA1JvNX(3-#dea1Y2riOJ_H<=0S$t);uF
> zrq_li{S^eWk~zIoUwor1RxLFfb%Ku^#8KXus@dr5h*NQEy_10s1`@5x4Wzt~E
> _&My
> zq}@ffo<`bTWb65cnXYe{??mgd@p9MD4ZIIf{aL0`XnG-
> CCwMR4qhUP`D9AGl>`<*D
> zyy$An1jW5nsP-!`ZiTr%bn(QcHk<bffCCA=RoWegQL8^yy0ZohuzOqK-
> (XXrgIjyp
> z;O1Bh3lAW4D@UVBt?8Z0X6hZc(;d4t?KBRINVG0Fe4W08zn-V`RK@Kj9-
> ){WPPOu=
> z+Mt!hF+m1gf1eg$W)KQ#OYPIC`A@f~DZ2e352<;xqsUzfJ&_yQH`kbtl89xUA+
> >g0
> zORdu-
> vPkU?A+>@j8$v4T!~}08^E`{xEN}>^k7Gb56G*+yXwHLs>7E0uWj*ZX!oi5I
> zVR8*oV{5j?V?ifWo!o*KbVbYgd6cCi+nEz^XgSb`*SiC&><?y9F*Hn_HcSi!t3Wp
> t
> zof?X_=@!|EU-
> i1R!TBp3XawCkD*iP<y7VsA^hJB>&uX4@7lb=xK0(urLZ9Fp@_B-Y
> zy2)kj;)y<mRsa!D=nHEMF99<E>}2muW<nO3S>O;d7qRJR$jnTFZLg~B&}|uejO
> SpR
> z?`3&!-R(lfG9Lk-
> 9i;z;RSM~lQ)k@zBrGr*0ASATaQ<64#XYRQ4+L+<g#PDoOn$8B
> zd}K%@lJmY^aA8A{x1ow_w(XL|#29`)?tUsbNw2Uxz3cnjZWL?!Gd~)-
> 4~(qnI2Uis
> zbuz0xqt640Tirt>@%gX<7VpqT`)H<EYtwq*>bxmKg{%rZ)@P?$m9_rB$Z|@Pr
> yX&3
> zTh~0zySV}M-%qk;)wQ-NcYSJ&a?Cw2vWy%$8RRu^9?SdNbVhc@oD;-
> Fap$wUe7z1{
> zCfCoX^KSZ(%3$i}oZPHg?mW97{`Yu6lzTr6vdpTqYSU+fDA>|d^g6!08yR?=J|g<
> q
> z`7R&UvDW3R^Xt6{M=K8p+fO7DJtW`H^YbkyOKRj~R%dg4lqhGNH;6MPmh(
> @C1UY57
> z3e{Mt%A$R1{0+ot`F`f|nalbO6d5lD5v@&e92U|34~#4|Y&A}%NzdgMeD7Z=_
> $qyr
> zC`+rd)O%Nt_6uI<3T|Da_uLUr*?zI!6(C*&vwmo@XWEkMgRJMf*W8&d*jd&
> 0w>0UA
> znqSDT+4~D}tSB{X0_b2|b46Ee+rIB9wWjKM|2_BZ9;V7LzQ2Hbm&5IE@{7Bd;
> <((M
> zs_ODa<$I(2u6!w*^SAjqXDH{$N&QCUh9KvK*_=D_b9!CiZKpoMbTB!{H^$|Y
> O~RWv
> z&c{|1Y{l+8SE8R)zcqMs(?wu+5@n;%VefRHIIi<{bJOK~f{ciQ>F8N(#U4@yP-
> OtA
> zR`oo#wtS{;F|9gS(y5&KH~6WRm*Ah@Pg&&?Uwlf7_Pu{etx;Pz>lZ3~>b6)?Za
> {rN
> zr&>v|JAX$K!<*(SM6ox37FSsE?V>7c@Z5pM=X@-_HnM-
> Q?IX<^Nr6yF6)I_@$RvN(
> zY#Zs1?AmP3On%OFe<o+E(CE`w@%fy7;OF+&tJ-
> `rS)(a9*GmS4HMqjk4@oQdmvD0@
> zVv=gC+;oe5(}{QUoAR%sV=64n(6L+EwJ{MB-#O-UFm$w)`{;1@qYIG;@-
> QO*4Rj=e
> z!an7ik-i5Kq(sSr(9p~lf(J$tqdwqxUozD1U_rKn|Hv=&U>)o*9sqyc%;a&X(F!lr
> zoNe!fn!`9k&$bD)#z?^C8pj;mG}^u!_L9ei*AMYqc1^bY1Nr4!%N)aUIep?eCur
> Hp
> z*_<*3g<3Y-T4v3#nc7-9Gr-%kHu2u$P8J`LzqFR`t?Fu>_mSSdjr;>Dl(GB`WCIDA
> zGZ~dZ`IUA32{cH%G_K^g@!LVh7MGE1idr6Oqxj&1VuSe%^x7a}T{fdOX+jzAr
> M`Hx
> zKEf5A7UZkQ<{O@$ucH$QFr>A~3BeI2gNvV18CC7|t$w@r9j6W#x2~))FbQ$*
> t6<kA
> z$uqz@N{HnbeK1LT-v}Rl$!tz2J=~d_X;gfnKEgcxsvzITUA~}o3tj6NJZWj4@Y{O#
> zpvNGb74NHr*qzc+!M0B0gpk&eJ{MibF`vU-
> zLLj*4Eit2j%$LCpJN#=>vTH>xlW&u
> zU*y5a^SgM87|nda<usZ>$b_4-
> n&zkvdA+_q$T&Y+CF)o>+rjWWDad(LHs^%=oR@o`
> zc==m>@Z8HdT2tQu6|R$~<>wnmmVtDr4MEOFvpGMKpELd@m3cB`ghzH&k
> ni&@U;I#1
> zzxcg?1)~#%>CvW^rmG}<pV4Pg<A{dCy^ms9hcwZa|AydkDaDONTQg<uxrDP
> |CEk`}
> z3L=;JXNHE2L{fyz?>YYyKu0V7FpE`IVL6keck2pO5@_<i{U_R5a}W#Tr<^8>u_3T
> P
> z<(Xuiy-f#=>%18cs$`s8g3SQFUHblb$G>BbL;L5Tl(RTt*6A=8^Q>*{)OZ)_GTTx&
> zG+R%Cr4_cdDsR`yoK2^}LB>0zU7JB?_;Qz{{XphI=0mC)f7TfZoM(x3P|9#cGSkf
> f
> zdgnyJWo>Ti+{bJ**_i5QW5XW!o`XM#jV*)@e|$Q*k%R?UUN2o7nPcKN{7vS
> VhD(B8
> zuDUC)ms|pIiuYbJ)Jq2$uOpvj_Qu^F^fG-1t)@q2LE?^DEJ);xB(5;;sK-nu(<K=l
> z>by3$LNovOnl}vrb>3E{HJE5xuM^1D<jh$4i``0$>!UbEjB#Z4=z6clb|6@!_HM2
> o
> zO$|)_-pw-
> %rTHfOfF2?r>bpOAF#D`_SQNaFICKhx^aBbPZIok;>`xoD@dt#yLT}!k
> zc~~>M>w2(}wYxgV_}#*q(Z*kwSq|*3b2MMPJ5DncWU0Q7jo#4%X77IVfaA}
> bF7Lli
> z57YYe^5LSqUOJm=b_RSt=;ifIdA-
> Eodb0Nl^E=y12N|FAUeL?ZpqJ^Hsv>9B4fcMW
> zS+`+vP{q*vDlnX$?A;Wu!a=$!l-
> YZ9sgKC?Ym#lwYFawArtGLK?B8+a2Rm318U&Hw
> z7}W9|rY%e<n97(;PxeNHYjKdS7G?H6maXMxYJvaAZILi1KbGfLCx;h|=F9V}rsZ
> Ze
> z?UEs^D`z!5L-{!*C95eS5ku+oM!@CHYWj?R)RqTU)AD?)DeY#T-
> O*eJb1T~kSE5->
> z%gt)qS>-
> HzrD?_TRC3sAx=mJ7+JMz`8+Xq;tEpKdWzT`d9JbAjq+~KHBb#;ft++~O
> zYszhp4JbQlQ{KXHkv&B+T<%HFv#N-g))l)$s~~`3dMBuxgix!6RKIV6l?l#Dt|r$;
> zxW3uM5{ELAWvoOYF~j6m-we4`H@%n{(l_)mWn#O901SPDjB8-
> %lh2)5@H7y~EtS?-
> z41KwZWYK^{Os(;ju*ZlYwVev)_q1>~l`f{j;i9)n4yHt!&=ugg5jbewd#f=U2*a5;
> z*K^kHi9O3Dryb6i)lu&iw5fG0mk)5;ZmtCxf(!RItufvek=wAeJDS-jnvn+-1Gf>A
> zTe^+2yqKl(WUu&qz~3tS@wb1$|DuneyDHwJX;SFjwIW1VCJayU-
> en?Zr@4cSd)aAz
> z!YwWbd&s|{(YB+*S;Vq}M2ycu*@SoU-
> prUgty}YV23tGF#4mEQ^Xj1f!TI&WW~#g!
> z!}U8zSHCiQ-?=%cKQr5Q%qET3i>yQq@4-${15t<iaZ+va+~@Kgl#?31>uvgLKh-
> 8N
> z(=gI_n717c;V`7F^dIpO5*8W0&i&54*qeoqM#2yy`_4GsnpY&h31l-
> nDjI1Hg57P_
> z1fBfSyjjlc1iRF#C%IeR3QX<H$-#?)#Bo6tQQc;1c_J*~aGI~}RX8QFnrz=G{?*s4
> zUhLDSo1U8V4(Rya-
> kmHnjkW@Mn$eG*IzD(mb8}4xjSYJb1VW^&$9V5Y;*ae$>iV#+
> zF64IYPWIOPXMj7nw1bR40C-
> %Pz0FJ1YT5dAUAu&coFLd641~yXl^kg}GpJ(IZI&Tm
> z?<Pb}4_DzJT@}jgU6rjub`LT3XGiRP<)|0;zM^e6NYvFZIjG^P{2EMvY`Zno2?yzF
> zP-d?%Tf>*A!TZY8f(Rs-T(&3D81vRx)(S&lCK2cWihD~~M7D4nvqk$icQx$Cp{gz}
> zM;Y&t={A<I@yryr2@>)+_{>BlqBnF<YR+4U`@h+E`q77t9H91&0rqNh{AEVgb!
> L}E
> zOe)Rl+-
> ^REl;>VMDR^vrhK+jse!3LkY=YATf>G(!KF@tHj)1M?fa4R$ZAEx5By1?x
> z9Zo@+ljF<z3MksUz%_;muN#e{I$f*-hl9OyC^cmZl?zi#$3`>P`%XJ4^SrsxcknqZ
> zaPXNPIQWqMf&M(l<Ii&>>ofd$hHIJT{CRFUkQvr`%l=HX^_G8Ridt`x15c@6$I+
> `s
> z$cgC1#G>X=9PaQddOK6n!p~y!9ZD7W-a~k%1pY&>lVj4#_Yx=W-
> C(sHs&A`qbIT}q
> z=wp$4*mQ1T<g(}dAD2DX?5756fM7mf-
> fup4A7nl^4E8Sks43wA8TxKhILZu%pA5h{
> zhmz+?m*=32({E7Fp5^~edp4h)-yV7P>kvSW%xT-
> VVGS&}`?7Vl&CmbO+Loht{2Bk9
> z_MO<LeIfUqT@2enFm{^D^}($Q@U{NmY0uY;A!LQ$0IPCab>3iY8xUh_TnQiC
> wj931
> zd|8u+`d#kI&hm*odQ5hXwZ-<zdx5g0e2oznTA>TA<^8NtY#~PSMBAnBU~o-
> &=-?X$
> z(19wbfCqAjcwfBVS??bZ(<$^e``UmnVE~)pO|%l_hZzQrFBPLv5#E1*4ku)OKxL
> Vz
> zw|!ax9GZ~0tOswB=Uo|xYw)~tJR64;$Kl?i$hcqeC-
> N(XwNLPV4g<?_xGb=%SVeg0
> z&jl63szC?58ZESxP@+--Wjsfp!Y>j5&#9Lg&0HZ;^N+JO)$Bh-
> Vbe3wO*Oqd{UaiQ
> zAgihT<XTZO4vehS9;d(gefWWqqxo6q9l2Q5!6(xjtz>#P4rk`6wcVWOttmCd#Vf
> H!
> z9|r)NKjuM~{;Gb|bh56x4aJ#l?_E-y@#EW-
> s@cU+m~d<ih(Tt~m|GM(wLH>zr1zs6
> zg^N;3@?Nq>HkeQuGShV-
> IC?hiFRO3mBvoG9bsSCgE<G&h!vbtw)`v_Hxxz}Z&6i{+
> zqZU<&S|gh?Au;w*n~9p~5Vuf>Yen5UFmkM+NXrIW^g}U{ASISj<yv{t_dw@
> 3w+T7a
> zwSpaSjZZH<V0;L0Aw8|$`-PEFF)H8y-
> rv5yZY2M0%rW$#&kXU~U&#%;D%dZd>2-R%
> zc^{;Dvp((>$sf-D)8lbH7RE2PNuWpy-
> rI)=H@F~R@#Ue?ovJf@oN56(2B&vZa^^U>
> z4iZH9dj_WEtfcrJJaI8|^roK$2EpnSkYnPLtb&H~tQAbLtC&vNwI|El38YI7<H+g!
> zbyZd3)85mJR0<;L@P5kEX7z~)*h)-
> N#Uh1mzc9nsPoy{;NR)c3l!FOgmO0zIP2)Vd
> zkhckY8ixPuI4>>;1$H1z$vD?>3ryF^R<ZYe^eWSLdKGletM`sH-
> v&s?{DvKVHJw;~
> zMyJ-
> 4Ch%H|POU9V;7S_Jj7iNO3n5n0y3tG|=lkZZz0NudK%ddtx^?O>sbGzT?>?74
> z_MC#q*7{bt_O_!^Z#%v{webX9G(WX{@sL#8#rLElEyZJ>J6V>1rbs4jEHR)j-
> !u7W
> z&|{vc()Fd8hiN;@Z;5yu(zuLxQBj-!E=Jf;7aymGLa&V(mK`Dyc;i&>QmE4nf_I!f
> zO0CLfikFkq%JJrX#xk4QWfw8&u*dHAr4pN4NH-
> OF&?0&3g9_{NE5vd*+3SS4`4#@e
> z9{mbkCRd@#@!n|2RhVgDOqiVGZE_l6G*$$2|B}xNu-
> N+#ic4|fB+H)U?lM#SCW5qN
> zM}hA9VAWNaIM(~D)mcI(z0>Vc0>C@bWi1|HhWhhwQr5WyI|OUAZg1ioNrS
> *BE$fLN
> z&m6L?TsDMOY??K4TO{)qo<6ZB%i8wAnRws|c*li^Mfc>Kk=us0!=5?K+169kJf
> ~zE
> z4#*tp1d_ue)Pk<h9E3RGu*{{cRKwX2x!!H%vRWW1Hufa-
> *snt<+Yd8${06y<0>NFp
> z^4HsHgS0iXMK|3-*EDyl8N*~op?b_OXZ+I=Y1h_GnrePl?pIl7XI0$gxy+iac9(mJ
> zxG*j5;)dK#oX)~D%Xw&ymXD3@)plQ`aayYItb)c<hOAF~=&UOW8c!IqCvkL}S
> 9aFS
> z!p0+bIpVA<iW<4cvX}#?L-sVjn8Gao-
> 0Gv&Z|?v<&+XkHcAltMRY>nB<}G?erd@kC
> zpglwq4=*C-
> _y(2#8{TeG`M;w4XE^tgY0lF>@Yn6=r%!brL>~^#v<`n`Al_?)|A}~1
> z4~5=^#`Ck*M2x>Dd(Xi$0<quVAmcrnUdrtK?HZ$Ygs_$o@dGT0O(pvwRL1<D
> t`}OC
> zb1sF6_K2I=7X<aa1^tF*HujN|yibPfbC9k+W%ina`ZCkdhi|eqVOBqs-
> D48XU{(#J
> zJ-
> 0aMfptNDzC<6KfUmR!{q)Nf_rpx*e^Z&_JI5ubPbN8%IKsP*D{CP>S=N6?GTt-
> F
> z$GLFeVk_G$2adlh*D6sB`^;}lOv?X^(kGL2pOQE=#fi;NxWuV7y-
> WU6ihwo*xDaMU
> zvS)fDJVeK7qS7m5(0s90sMR$ebw0j(6lS`&bzYQ{?UO#9L;T`n<Ew3i<Lol9%j^b
> u
> z@%163Tm5jG)>(xG_)_XzdojI8Uu1hMp$TC4f!-
> n~_T7K@fc4k!*)n7>vg@xtTLF`W
> zB`xXq0FhhLYo+t5%Q^5^h2%$YSX^5gPJW<B?-y0aJ3@WF&3J8=uo=pU-
> rLva2s;NH
> z-}Mh@TSa(BTy2PQqJzCijpJs`P>7+_-&(l|<6vo|(Y9G+9PCoE*~vA<2~Yqtv<t{F
> zBv3HTlFkwg#am7u2ZjU$%|!2$;bvulU9(h#cgIzsX0=e7YmL)yWwiAsm^pzt;A|
> LD
> z1g|ok?yVP$2H`<;rKM0S0aFvt5!;jUuw?MM<J5sOXz2c+p|0*8s0XTq3f=0+yTq
> nA
> zULb9|RVtwZLgeDxb0t>)jrA1tRr&AG*G;G9(^vmpTbp__grtF2)Qzr$gVR|azvT
> v~
> z5El&w_6LsME@H%kfgSF&j=X`r71k9n(s&j)-c0Veitrx&kI=wk*6c%XhakY62I8;b
> zbb5+22VGh`#$6je9csfWr-%e?0BoZ7-l9+&vcRqlD#AM<+y-
> a*#n<nT`+VNzrkI$X
> ze9~bToX_17(3Du)e1!yXW(@{jp(I{%OG)VgzHO_q+`Hb|QA!!!l{}*U)If2IgVwt
> S
> zji*8IJXBcYe~LKv=6S~Z>b%+xqd6meBz7rPwTuW;V8E|t^rNRe2a%7PYj)5cRw
> ^=e
> z@U=%@-
> bR=J`fg1J;&ENzirY96?*Q#a0q~Fkr2oM$K>l}pm?CY0l~M3&4*XH@a57|u
> z^ZN<+`%r$T=I`K&8Mrz3gs{|n0v!*QnK_yr6i~T~-
> tVaQ_7Boqcs>#MKdG9OZLYVL
> z$ZkkkGLLb)HM<ZLy#H+oT;493-
> %1&aH9bXrE0$Sn6350%BeTVj9_D5IkprdxEQlKk
> zI-2oj&y=dT(+;j;+~1?|vfJfSwL6oyjE^*)5PwpcZ?Mb_!@bR>Kj4+Vv!!}G5k-<W
> zkB=m#0iCKJ-
> !eZ+Wom&{7Ox{yJi<q+W=CCvyCh}sY=3yKf6azB14p%5Ggo9T6Ebxr
> z9sL`#*=UYc&*G6lh-LXquqL{R?oOnp-
> {#k}Rm21;<pT=0BYw)ceqDvGu0A5D(7VKq
> z_H#P5paXnbQ?h`2{7Mo2o|b54i1%GRYl%1T8KHo8gydB;#6JRgHQSBDpMnN
> MM!#WF
> zgcKv>)dcS>D$DYZEO2}hx#KFryY|zT$yu0>lJ!9Whi{j&fxjwy3#FD~#iwn4D8d}I
> zvW)F@x&-W6H%-)g&-jpTu}KGl`E+@|`E>C8l<-
> 6f^*cD0Qd(g2cO(QF(BJQz$PIYb
> zHu0=#SW>p%S>Sl5`mG|o&tIDBcY08vhQycCV6xbDR58dkmU=x`kQPb5p$Syz
> o#p(a
> zeH3uH@dHds!Ews^6iTsK=rDL_Txs6TsQ$q$yqrS3ui-
> 8hxY;m4c2$5&3seeGlFohF
> zs*wfI4sR(>j(f+KlO!^XS2xjfmE2mhllU|XMUdzyBN|8NRa=m)wvd&}dhaxfLV;`?
> z;+?4CYj?C@CE9s_tNdP|&iH>&d@v;oT*LqToXr>HKK?jvaVxT|9?gD9^5)SBh*
> -O`
> z-
> mAcUkzS`)QVcWbIu#_w;BbAp5U$p`GQW{4ld@9P1c8}7%b!v|e#NFQwvEj*iz
> !T#
> z#A!}cxOs+*WoXQ!r=1^Jv1PeSwqq<EG^1s<i|yahQkXX-
> k9PBqGV8rx#%y>P#GjpL
> zO@2;i>k>n}!!K7|yEGwp9b_ZOpOks@-
> !MZnz^gF5DX_4FXKz6NvbEHCT{b!LZ75bA
> z`hjmX0*=t263&U?d=?}s_$*8umpO$_Icd;i(%=|=3#sIjG>~-
> Yb<)9pGYs9?VTcwo
> z0y`o3_zpfKeNDn{ulCVC`DKT8^gdgKYf)}jJ})GOH;Z_SP<bj>xz6w2RJbs^SVuM
> #
> zhyu9uDM6Ami{RwW4bc(8GIZN|yPK9A!mMxvVJ*2_^S6>5RXPIQLqsQl>%HA
> q7hs*e
> z?+P^v-
> Ql5~)+n+M$<IDP9T~5V1Oc*czS!@`=UkqC`Xo0dW$hU~4X4;(JO`QjmZrdx
> z0akR&9D%Di;1r!wQ@TWQ1T>mvZgO25yf(1BmlYW!stVc%UDaM83d=4Su)Ke
> W9%Lcn
> zy&4MT^WMG4L9$i;6>4axL^g|<KHgxRv61LByL8#&5?NDkprF%&s$4<KDUFO
> #XFcYc
> zqff(L40~7qKEU4T`B}!1rPX3;;MXF1x1k@q?Q=7HB%b85DlmT!292XQ^%+8_(d
> &cW
> zkBLvPzThE!=bHore!sjQzu$3C{mC#ZMz39M7Gxdy{)dy|Hy6{-
> La*zxJmg|#IK^AI
> zFvsN^9ArEWxbrdl!i8BR|B7+c&N-VHxl^^-&>Lq2b=;j_2d0Hnyq-
> ^m>Tr;*4#n;8
> zPRi8*?J~VM0rKP!)tg<wDjLU5^cr)9m=SBbmjOrFVf~Jk8Mv039m!=o4kV7{bH
> C=?
> zj<%i>7<BUWF>S98Dk^Qd{5}~8wrYX6wF{hM#9CE7c3a0b!pF7~MSf;p_W3*7
> _F>K4
> zk?a`L)-kB4c#UPRX;=1k%U;{Qs($SH-I4YC2FIS=fO-
> g_Z=_L1=o>}x=62&G?lJMW
> z5qiUv07=(4jUgm%PxfBAB!naf>5!z%UdaL*2&NON1@{xPGlU~Z{yydbws-
> ok>M>7)
> z&=QBxe{sDPiYFqC*J*C?ZJRz8@fI4d&YjqE{5<E48{SlPIZn#U5x`@8kpBx7{A~G
> k
> z9hBdjQ<Y2*1n_~kZ(jM9<N3TC$?0{BHCCRx7zFllVn14l0ddyY;uDsSiA1LBqcQg
> K
> zw6Tj)#bXyGJ8oZ;?76-
> 5s<F|=OVVHePC;a~pFeT>zmvBlT|?evXZg!pUL8I5)p=tH
> z`8l@K8>S{~EPt+*n2uibXI$;tUiS^vy<*zf+Y33mxABRB$con^k*?bTi4yvjr`XDG
> zlFfUWq}a+Y@Q8s=Z{Oo_)ts@h<*zS~HEAvK@?X5q0kr)6g2uv^JCf7ek!Gwl-
> sfHG
> zu#4DK__;O%(vzq+o46}K(fiHg1(8eCzNi-
> `>AhKF505q$&CE=Et<7zH{fbw^qm5ns
> z9!zPOpH1A7Ieg-
> l6F6!W89HlhS)<EbMP_w5we1A8b_JG+m~NZxy1jAGP)cuH$0Ykj
> zvNMs|T92?6k`|7Qe&f~8N4=?P-
> ^Q|wU%evwYC&>iLboQLL2*`px*BR%!9j)5SkqoC
> zR<G{lWjQYo+^$w6rh6#vkyY1?jjjLF;JvfPj#|#o#NmH9dBS7oMOOYg0fN@S$0
> O;#
> zlKJI#R{lD+aywmrxg-5NU$5?b*-
> N+Scbj(%P%n3^<Z7(@te#hQ{^8`+6ylomxU#Q*
> zxp(KwKZ$(fj~(|nj@mV>4pi@N)7#fxws(d5+n#%MXE>gw_Yq3<j$K<2d1x!6
> WET1o
> zZ^e@Zkw5ItXa7#$54|(`-
> (0euCOr1xS&_{p8+qDxsGiz+T3xQEtvq#&(9<@aBKB?v
> zPcFw!rH)hTE}kY>YKPugDSLP-
> <H@hn&9?_dOg2NKEyMJTXmvu&(y<pk&`&<KA5=cs
> zdL*<E5wliU7~gaJ%y^HJPjwgDd<obhFsFD=&kwOh2N~ZZ`J~L=J9RDxN<bG=
> BIMZ>
> zuwFkj)a0O!PG4>CxAs}-oZ?*+uERmPI!r#T%GGf<b+p=@kXo6_RkNec8-
> k`Cl2x@G
> z2pZ%I?sxd=`?9KbYrXevOwuN++Btk}vZ`IOYJR&3oAy4!X1#>XdM9kwBW$+q-
> nP#~
> zjbv3Qdu@B$`y~{T+&!jk_n@NkR+ClppH}v#Eql$=t7eZ~|9WKo`^c*8gnva=t%
> Dv-
> zRvB5RYSs}3A-
> Qa$2E~_E)d9kO;frS<VZfa1oj5NvC=Svg%w*NY7ucY%E_1R99bhsG
> zk-6SulYI;z%U!H2IUA60*I7zHB<vDKZB4XiieBYM$in9g;InL5R*WbcXsPi*^1?gt
> z8{;)0b<E8-<lR8><%8h+%P((x|I+>S%fZV3ZT}oW`v)lh!T!*G`Rn5FAUA<s{^a!K
> zKSUZdmToSw2Y6rRF!!>2*%0@#91@7L66Ua1iPXb};s*s==l$1JHhvE+Wg{jzU7
> wN0
> zkB0Izhx4R{DO0_7)c~1>tUD6W^iTL;b;YNydbUWw_`0+0S-
> woptZf}7C2Bv~Kx(9F
> zYbjop*_q4Wud0-
> xXc_mo^%}vmXDfnF6&t}PrxhMZOg?DZ{>12mrbURYK$)+XY+iA*
> zI5{+%N#!h>hEMOk-
> H6s_OJ=jzBwL{OyI&W8vD7d%x8Ccq?F6?jHTV_FqUzD&Nj$U@
> zHsGczmP{w>6?&<~r#+)Wlt^R_E;=k-
> @qA=C8Y4?roO9()kZh}D_j&@m*C9#Z*2Pvn
> z0;GJ|@no>F(staMvPwf`mHK57?l!NigSXF49vrwGc?)klAD{R97C+}|3AJz1KW$
> %W
> zsLWDVrnUH{Tv>kmvSnHOK0yDJEfk$9JB1xSIw!gKW~S@j@>8wdSQKy$z^#e
> !^bO>J
> zABybs_yb1t-mbY;ULbQ!9?XV;1(q*dWd0x4-
> Ul$Qs!IHyB$IY%lg<<pC{Q5K0)@0#
> zC<rBVEun#;jU*{4DF5nO%QN80(wS1+hPF;4oeraQm$0x4N-
> ZcVYIPARQcP)WQ>dCk
> z)u2_<8sQETwMw-qM)LcdbKiUOCV$Y~@2`-
> VH}C#C_uO;OIrrRi&y}3cee$89$Uen<
> zkR>WIN35`cO#v_5nJaT<d2OsHY=ihD)u#7@fi`ST+lI=V<NY>r&DaAtnS@wph7
> et+
> zEG73@h=W%u;zeA+41ai6twus)hUpmuz05Zldg*YJw?5$XRNm#u!}m!1&+700
> #gxcn
> z+{-_lKRK$6-(HaW-
> T9v_acMybTYo@VuzP9#QKIQiY>X~ur!*D}+<@$1f37}&RGZTY
> zk=-t4x6RiQ?8?D~>{+@|&O<bg-
> u_iy`<q;~z?F;Iel*y=&FRGb_Aejaew9zhp4AJz
> zmTS7F#_;pN2{>^Kzr#lkybud5JaQl{T5sgYlBpFX_US;$D>snjm6h*>i^wx+d`Ds
> u
> z<++hyYK+4$f7Fs?e7};rJl&bTk(6tva!<k3vc1{8zuf!g-tO_c6Nityl|Dr6lgKe|
> zYQ>S)OZMJ5p@w{SMeZD1L*C^@ALNp|oi_*DTzz!zvdYy*tCo$4KK{ZhJ=@b
> =vpQBE
> zIPH~#+h=vmdU^YvK>9bjUU_qS`h{69OS*B>7fMquxC)ShE8YB~WX&}wxG@
> cj&)Xs3
> zb_y~+&j&YVE39R}IssTC%OlnF{p4$>R`4C+yX?p>IHmB5P!M?VrSyhA+c8X^9q
> oKy
> zfHsC0TF!SiSlYao$(_twu`sk$o41(KK2xzdowYt~oOz|kRC046&L;De#;@@$AY%
> T!
> zTv;D{t#I331V*EoYPSmi?gC%?%Z*AS^ukrgZ}xhz4Qejz#d&5%uopI`b4Yrj>i8{n
> zUN5pAM&(c?S-4GudHhL90d`Ds{dzPFkEeck7Jbr-W$@5!Fn<`7T)0cAi)?E|c<e-}
> z2yYGVw3~!N;;NwDYObE%mVFD2TwRL#)8q64A~+-
> tPpIA{@eg7BQ(d92Kv#%9zaSP~
> zb6_<M$1l{}n2ZO+!^w5X()tE!ikEROINl%=lW&h>9(pcTxu54w_u!E_IJh$j=4^*
> n
> z0G1sJHP8r~&Nc~v04&FNilS?Aixzm3p9+g|W}S1hY?WvpdKs(M+lopWI9GS*
> @4_El
> z+Y1D!Zq$h<=H_=4eKmEx32yqJO%B)*NSPCNpk!DlvDF&7$W4mRN0LXSiyDcT
> c5|;<
> zh%rr6fuumf3R*&S7uQQuYg^-
> _t(sSFUxU$|vAXLFZH^I;BSr4O>6s$d9hyT#6u?c=
> zNKk#c`suT)pLCg;+M>^2TNF+n4AU~Ud@-
> qmir#AJi`?{3f`IdnkXw1d{#h_S>#f+*
> zpj=tNdh1q?M{0iaGpw0rBDfn_zk(n14C4o*org<(%(#2kW)%a8`IU{V_Pwg#v8
> ^?(
> zWwLvpMc91tG;v<yRm@B!D-(jO&tj?K$sFt|^3-
> JWI_H!??6{Vb&0p=z8LYenb!*cK
> z6i)LX3xQ4hSe2W1cDwl^<`tXIe4x{Pb&Tn-
> uV~|euWK9b#Nq%sgJ?F|WY>kN{6dsl
> zqRjBwv~e1r4e9c!d^MV@fAcpK0A}TWwJSpoL@@59Mspf9ps1_P{61zd{!^S_
> WOXOr
> zxom8G4m2lsM7F0t1`XQtdhkL<b$^4|E)~4Phg-
> qO%Q?%RlXLddTd|lu0$$Nf8%(c7
> zumi^knXi0HyC;L`@;6yHhC*|hh&WbH5F&pD`&vD8p^lzcvkc*7N$q90FF~YhW
> ;ejP
> zH0eCZmkZ7(%^A-
> K=^NG#u&nrmyTqY~O&l&5O+IUASFG)MO0*P))Qw!XaMAjSoEwU9
> z2<MaQ|Fwv7IL+xJB9GUP<wmGWUx=STY~S+rW9*M{-
> 0<?&%{SbFtD=3iGm*{QGr0aE
> z#hezJCa;Pw-H~{H{pBT;nzVlDAP$L_?ufsZ`}(X7imiVkd&)TM5?2lKV|#j+e0tRG
> z;{*K|U%>uA{9n%q<0`9nIMc?eUiH#df=hn~MvX8R&+`}@)6C{{%E<1<|9zh=0
> q>JV
> zUO=)8QMwae8@Cp=p-
> T5FR|MLyIc*y@{%^hwYy214A?80=3EFWj?Fz49<)Zu(kto;p
> z<)cV2YE7o<Tme)xSFylJ?B4;2{R=O$v48vZTynn``xg(vVC-K!XnDgf9VKk+-+u8w
> zzoAVkg}d$<#%p90lpe)*3(l!$E0FDuYP>P!JubaYA7y+_cVnA7pMx4b^i6Y>1y}X
> d
> zA-W$Fc<MzyvvZ$6O4~8V%DA!<c7-
> C%4V>KX2Tlg15us{Hm2UtJ9+K*B^cE07uIl!$
> zO#2sUbgCY##Xp*n0nz?^^nBMuv#~i!y&OZ!$F7(cGH>J&<m1o7o})Q_=;d(nH
> *?W-
> z?2QP}u26OD2ky3TfF?bi?QjHg54F@e8|0zbyaJ5}=pH^b)4cEUJW}19&h2D(q_F
> wd
> z%d~{`Q~XRAK|EF2k?L<3J|HMiH+y$i4(^F1>{MsIZFs)d@P`W<CeKW>b8etvo
> 6|Nd
> zg-
> w4=py6^FmQ|r{kO}FoI&CGMS>4Imp=Fh()vw5c`5MME&Am_dw^oG5t~_Jac
> y`Lx
> z%pUyY-2Yf!X%-
> AA@J$MsXUdBOS4|4C1*8H%<W5ynb6PQY;|%=;&q|Mpy4A8Ukgpd4
> z)J^{X@bZoG^IaRrw^{OuUt7-
> 0caUhK)ThvPaW++>8{GFLhImypUEj54_UgkW1Q+@|
> zFQC|mppW$V)rZoThfjVXl`v?U84Z-me7pW60g)-
> HYNeb8>dpSF7#y}94#lrgang32
> z_5$M$a%_OgOm!z>jH)=|AE>H)gsRe1MJ2oDRxw9I*-
> yz&Z>s<5#Nkcf;59Ahim)I1
> zO`i?hN*6uEisw)Cs027T2=XU^Akha=?W)xVa+4^Q4td!Ec|iSTq6iXdwZZ)6^kTs
> 9
> zo&Q?#RKwRaxs4nViMU{r<}&oS<f~{bL@|&C(zW4-
> 2;}s()}u1qFdkLK+$MP3+k(^9
> zzJexJyG_VNqY+VQTThop;HI{f_lHMmCNjL4wL_a>;N6~_=rsdJr<sV?44okpwki
> gc
> z-b@Pi1~~H-Orvh;WV42GT{&+RZo?+DobIER(CbMh+aCJfSjO(iQQ%KCP?IE-
> ykCr9
> zsrhBz&&m38a#kde98ZdVPWI<kj+5G=$xrhv1K7y;82q}&{+&7_$-
> B!!tL7>M+%|QZ
> z4A$jXa*X0|a_0VtpMaheAT$sH{=~*h3j%P3oVJ(j6{3$wfszKvlWLqitAkKWzIN
> =(
> z|A<*QMUY^vDWb?!Q3@>$&xP;l(vj(*j&Z8;l=!mD<*%^}tGL0+%g{kZUCM@
> 5|I<&=
> zq1OE3*WZ4G`#zo34?GxZYBcw74Ygd&i#JQ_;jt@ETy+eq0_80D*Km@FaE^6y
> D=s_O
> zdQk(^f>zJC9+oi0sQE<i4*)On6D!DdZM&mu|DDb+T9|${9mh1W6Rs2z4J$F8Y
> we<K
> z$ly@!Y}KB;JMiMwXiM+0ITOE4ze>KuN0PrOi658GMvjY<xuV4HFhay`xcQdt_D
> 0M2
> z@m?iSJz?tJbNQyNByJNa_Lm!OrXcs{=~--I+s40W4`h$=4rCvn-
> 05EEupeD;I*Q<_
> zauA#2-(~V08cgg+osgR(`=zWLPRLE*iPt=ZXT7YoBDts+Ig;XTKT%T>f1wl6w!1*0
> z2X$WC+p{NAJ9xu(?}~{fQ_;rc4#9=#Zterbh~l23iC3;4Cud+@ivMKo?s%hnxF$E
> g
> z`?~b@ZNG^v8sD8B_XD|?f(u%Y%zCNhP|4Bc9|z@%il5BdnS6oev)odVn0%&
> QR`H5_
> z6(u5TUI+Hoi5)lJas#?-
> x_02w?eX`5<3C*boA}x2vTw*qo$c{TUhU`A7+&qmJ#h0a
> z7Uo(mcm?#@zuB(=`SR(PIaS6b&xg!Pnvn0c%ni8p1@gQ?=1C;^Jys*3qI*u0S0
> Ce5
> zgHs|2Vof>z3}M48VNC86`xfGte6k*IFjv80Y%)_FUMMMVQJE}h3dzyxbBz+-
> h0~w}
> zj1oeQwtbn*rtx^zCPcix9C{{_2BgikytnHO6fDK%-Q`ZI7CZewdSXrGiY-?YkxJ$n
> zX^nSGsl5Lg&H;`yw-Me)Y7sAP7;;VNgHMx@*-
> Z=&rv4pMN;Ttn^CkKu8TFcHX>R@<
> zoLNgub{pr{?qd6#ntulwcV1p5M@`@##c4P*j@!km@5;vR3;s2mI^W&?MW3
> Eu#&NL9
> ze2oYGmaowwCYWDvW%<RNsh49YN>uu|HutMokK|&x38D#Ou{uLlxI%Bf;o
> ~j$xyx|e
> z54|(q?~&(qLi_%BPnK5+UU5y24)!^)dv~x;;*~qn3nhoSNx=|8$dB|fQk^%_1@
> Iqh
> zi<_UHs!}`vd^2TGDZKvn`SdCAEd-
> !m;P&9{=6MLbqQ5q<gCxXxw+~b9Byk$Hl(|WA
> zm~Uvyh46kzsv8AfEpE>K$Kjps!h0c=dhkw@1`6?8DbTctoNpqYUjV;wZ42*PR
> McSp
> zc8Zsl$M08384X@7Ztl`jLE;z{zbo<f5&W*DQh)wS13tWV{tGnDYMH}2|MMW9
> V&8i6
> zU-Fr&Mu7S)8uFpebJzm<sPyYHPZ3fPf(Vd^xUMLP<O_>Dv-fHG^ztOpyrn-
> +(VU0>
> zC!}e=KT6;2ylQBHiGcsBeQ2Q<bRUcVWs<|RDj0?Ia*k9t3cYA?bL8Zqz>kXm0h9
> %S
> zH%z4-y#4fH2)w`LRYQw#n<n#+4-@dJC$ChnU2>QoY0HK1-
> YwOQ0<U!hzUm)`cYzD<
> zwN&cS%Y13T$FI`MMFNd8){_^n`(Pn2^sS5Ka>-{-
> @RRdYzMY1AsPjWUgkHS5%v!sU
> z_+Qh@O7;bm{%OwZ&kAX}us<K;RfBV#*Pr8kfa#CE_2^&nnX43-
> !clmOhW>tkyt>R&
> zcA@jX?$49NXjJ;AIj=uYNYjP=Y3Egg!?v-V&sX{Y(;t27_U99l&)lWJ6!vF|RO(UH
> zsN>_+WqKzKof7}peBMtmZRt-
> h{qp8VH_!S0=zRVmuNuUOTll{ZE%QUwa;adG<S^e*
> zFbaF}A*s&mNdbKwYm1w+hXG$WpK(hN)+h&rhZ?}OK6nbQk$L+R@hjYuET
> 8y`GBu3Y
> z#AS=zBECdo^HX1<0Y(Rv$#oQSQLOc8{0nmc)L<$2$ID6;UU@IR0c;1R`j6LP%S
> WGv
> zKFl3jSO7RS`ZQh^NB>dy*$)U!8+!isxl#PxK%O`<u^Ow#)`XoAOmS=#Og-
> me>N&-f
> zT#MpaVLOgdYt+TgVtFVwbr-0K$8$@-
> #5coy`@Dcr$mVpeCA%Yq&2P@p5*!iiz`o!b
> zdLQAaqGyD?&^B?2*Tli|3!1<PJHvc1*o4h#n~=h0wco@|(nN=K2JgW1>E82JV
> Vjuk
> zHL<F&2^=40nB0s&FKkZRgcLTX_)WYGjs$Uf68v{M@d*Rct2-
> C}xnC*Cr9C}U(1{OR
> zy1?bGv(da~gLIKyM{#abm%AP6a<@Y_opuayx!WQ>b6c#--
> Ik#)cY)&dJ9JlZ#}Jph
> zr=<8(*5&T0;VyTZy}{pXr^)729SH0QxZHifL)-kB1tUYA8Rn_!0kqki7H#Ts_xjmd
> z!i}LP+ceR&|1GmoZ&>9*>FC<e=;ZA6Y~8)8`}eA?8`DE?dLpMG-
> CORS)Zc39?#0rL
> zwXL_&{LiOcTt1m@e$qzH8%!L>u1!r{Bmr^vX#dX1u{pYbeRKCZ>ce5be!re#*`
> Mqm
> zC$XTjw~4OZydS$dgNIJ(-hD}YOE#ny|5AsQJ?x%Q4-
> s)2`E`rZ32ZX4H1USErT3QX
> zta)d7q=vhT9s{#DQS*7{X~{Wpaa@ZZf8C<w8`0$J(HfSQiO9{j+>||v#nfHWS7H
> @N
> z9xO>7jof+eTaOP;ZNKo|+R%pdu4l!*kj#efl#S$)PHwxO{~7Lwotl{^>3nzcbHnv
> ~
> ztmW?s{-
> *3*KW5$7^;Z_HyQ*mYmBrM%?yBPC&XVLVt$mMQd*<qVUd>g+{!VgNvB2<
> U
> zKi39Z9~(ph;jSV{UFWA#M>T*<;xEQuguf7f{lIaEKf_;o-e-GL^FG(hx8d9H-N$zy
> z--
> q}<#P?yo5A)s6cR$|)d=F&885u}c{M<OM=tvJrrx);dJ%6|J2Zy`)mfhPoNRNZh
> zw)gHEU@X80=<xDp;^z-
> !R?Z%92VrV{5X%4d*5d=T+qI5X29LZ7rdRVwUEY`+wPR8(
> zW3mre$RU|G^zt0xVJ3g;uPm9ecimMb$=@sX{-
> D_VPM~Um&CQb^tKSzV|DdC=E|7CW
> zARj%ThwhmDz9jhv8QJKk7eU2=64bpG81Ccme*PZj?=k+K<nJl|cJT+UCxh$Bd
> {5$g
> z65kbk<E``A7~i<Te7215GQJ~xbC}?>VZOtKV`FjDLw$z7e*Vf*fw8%=1PlbmLV
> wfS
> zz&Ox1^4NC;W0zNt_F!WwTZkglB*vpzzg&MKjx-
> vIC4Rh`kS=&Bekaz*_yw*F=}j(c
> zzw_AZ(tq9dn@GuP@)aw2EqC%Q$&PS*f>&ZLB@%zSVY}r0ZF=0Sm(<pzHl|r
> W@y$!|
> zp7i?%sDH`@x%i3OvN0aZcr4C!`W7Q=Fw)NfH5cvKQVR7B-
> Twp)$^P(N$E3q;TgJ_2
> z(|=Znr}tQWN0fo^UB|&LaVQNvd37jNp<g#`XTQwLs#x*zZ|q@5I#n*8yGnccl
> z-&(
> z)8$>NTt0V|N-j5D%LU-uC^-
> VZ6Ghu$aml_=LlgRi6C00wAJ0cit+NNv*~`E53eim6
> z4O(sl{_yod8<n=dCG=y@q2K;K^i-
> |u>Y$ZRPPHCRCHhl04Ww@>OK+F0gu2MA7pq@P
> z9*D}<L+SomZ&$w!<CL%T-
> tj+Ayg!ZO&5x4@R<RvX^T+sc)qh;Hu)%zRUSVpXGz%e2
> zMR%odV$D}p@=EnytnDS;)vu;*I+SMjq7@Gg^VVZz%q^_>N#dd-
> uO_z<_qta&Ic&VX
> zm$Z7^ReGhgNcmVb5&?_y0$oK*3%QfL%(3)dX5m|pr-
> 8RbD^1grM1Q(<sP%Zy9_?==
> z)jB|b{qozgV{>CNA|OLcqn{kZ-
> v?uSEUMz;=9x>QtH$zo4X;*R$E#Jh@amIG=koC{
> z4SXzL%*Q=<kZ>#SR(+CptM206s#SMno?cCznIFjK)rn0C(+K)-
> vTxEte}nQcd69<w
> z^0n~c>(iYVg+f)KhDRR$aP{8!X^oG}>WF@cXeOzfWCH`A8Fks`6$ZSz{u|J@&!
> k{D
> z9y6!&%}jNJ)^T(C4MD<i=d{uT`fSxOeRj0?Me5(uE6}+hFO5#y#%3#G))V456|x
> >t
> z=Z~H>tvyV^j`*=WZ~#e<#_gBVq8{y+Lg)<Q5#sOHsvdv>Frv&?c+E~!g-
> s&R^Ap$Y
> z&tT<T_9W=`2~IeM5q2^S=prLNMiIqS56muiJwgBH4()&6)KT<#`ai2<UELcT9W
> 0^+
> zRqVSm&2ON*v!9aTXh+MK24~%IpO`yXIS*KJ$JmCoi`q9<A8(A<Ir^aeV|gX~X
> ==Kx
> zO_)!*qHV*3`Jv>|!FaT(0n%@5aN{enrT%Om+@ML>oFsiuFiN_3^SfK_E@teP
> *1x9j
> zvI)Wa?iQwRiY&S=-
> CD6QwROiI<&LdRKB*yOZpXkODsx*GZ)BOZ&|K}kl1%A~8t5b2
> zYeX!#j*Xw}-`K_Y*_;pyf@NnlWZL$Try-
> cc&`ii=<aH{uhtJ%&U2XEcB?@ONmLdDN
> zm>XMTcGS*Hw@Yd|y!8oC(6q4OIz#Lc>6*m$6tAfZI&#IEi;`Ov<n(t1&P1f`FW
> e?d
> zB3la+Jd&_?_1T-?GJSNSG1D%&o9wH$!(#hOZvX2-
> b6u^l)JbiBiO)zYkZJ9H<8{so
> zpv<&O;U+j!Lnb4I8k+`xmQ91L^qd7QGMsT}jP(A`+Iu&fi=OW<rjo&*gNQMiM
> <j<}
> z&lYI!VJ+X(GMH(TCh(z9d_KP*U*NlvBb|{^;^?Cb7u(BC&U7*@YFOAf*e;kz?w
> Bl#
> z#W91G^8pES|1CGq`q2&Mk#A8hxP{@(|Hc0o`j_Fd^bazif0Xc4eYeg97QEd4+
> 9NZf
> zc~8^-eMY$S8bL?*kDL!A=R}wm7(F7XHZ?ZZv7qT-09IcTTDT~>_5m4-
> &dk3Sr3cqf
> zynOA;iKEp&PHvmQT7YWq`nSv@17LU7Zq9jz)_=YOx>|RCxxA9BzfX6qkIY@W
> J8|^7
> z%vO0>{lYctuPM5UH~r~O<V^ZcNSaP0&6fR?MBH?)kIj`f-
> 0a)Ze=IEEW`FCkTXLn}
> zpBkGV+9=ScGXnX-
> mg0s+bE_I6VmIHwIB`V0{~P&1a{E6ITF&=>VfvI9Rmi%BSsO`h
> zeU2%U{Oe$J?H}m5bNfW-
> tMW$1T@FvaB(E0piv8N_dAG@+VaWXW4hfRsYl1D7Pm9W&
> zYsp3=MLv^nPQ^8chs-
> @ys2w~woq*1*lQiXQ=CN_Giz1Tmx=h_u?4IEqAp76R9hW#y
> zO4jD5nw%%(0rvyvVZSgZS*`_)%>AWO6_Hs5o^(dKz#W%-
> vahhP(JTZz$sN;BXe?5G
> z^Q1+J(?Ct+xXzrfIbuF-Z*y}D=Xadlg{9&OpTHEuPF?J}S%cL(#nq1}D;3G3L<IOA
> zq#UX_y6mj=lV`H06@B`pMrQ@RcHv9n9EcAFy3M*%uey>jh<KOOMKTq4?+l
> L(?F^s5
> zg+^Aoy5kidLa${my++r{8IgsH1n(OJ??R;k8okt|(YrhvUH|z*|7ZFP!4dwq^tqZo
> zZxm=3wv-@G@Z)(ALn-
> Xm8;2Xdo+nN)t@>09eF}6Gs)=obL}!Go_9hRm!U3S>#rUz@
> z-PU06xr9b!qk-Lhjvv;Qpxkj|Fm9CTR-7*nzx6fJa_1d+ExC(|56NpZ!b9>Jt&vi(
> zlFsU`rWRaL@A0+4G!O`1Q+UDxj}$6Hvs)VdLkFSMADc?Mp$({IqRd?tlaDI-
> m?<Bk
> zxLqZR+f|~tU3G`2vUPd&dPJq;>%{{;)md;X#29LMpJTuqcDhG6FYGJh${GitrY7^
> <
> zR(TILAD%0sMQn}|y{njMZLaPF!5vkz>juPbqIzHM6f;ZT&h_4s5sir=KjC3x7gI*!
> zMaVbwug>sgWYIW?-
> ynz3>Sb+xB!?0oZn?pEO2Km^RIK^xSpp05rau+VNEVzSlb5yI
> z%rj6RlN}XQ>h4?XhBOXBax)TUWT~2)k;3wndylk@GkI7GO9A;Ud);hT+Y2K^LP
> *iD
> zG%dzp?r_>&jH@+oIRU1sQBWW$ejC*t<ZM2Rh>x{IaqNg4!b9_W(If+C=F)d{;
> f!CU
> zt(ToCjm0koghrEwy@7ByVet1*uk;Pa8tD*qYKP=oFuCh;>+<M}NOwNVm3=<
> {-Lk9g
> zQN+F!aU%`-
> (UrUG%U=7{ZNF5b7oW#WeTRAJHF0|BkrXk?;w?b@xXi=Um)t6!5=Bn#
> zb3*nP!$h3U<CL)Gp~(6@_HtgyegH6pj;FF<erGd<>>;Q9$7#7;ZPTb*{s|0c6SX
> a^
> zZ?ZddSdgO+lAg}!r`!!PH`*qGBdzZn%%5FrU)%i(sC*8_XC$}E!#nY*>5M#x8MI
> w9
> z6dXQokC7&7o_wo4RG%=3b{*(Cs%MZBi)>W|b!uA@xI-
> &1jNOqbbL*6Et+QR82;$Mv
> z6YA*aWHVtr;$^$qBD@t`OZ)OH^C;aePpS3|d?vTbr-
> ts+pd5~HZV%}{IjI2YHs_V*
> zk`n?*_w!q%tNHcTV_l?ArEd8rNdL~S1?lo8drj20$jjj0r*O!pz+oM*ov{Hpt}2AX
> z=DgBuX59V3_w!pg^w{8Q%rl5)S6fv8j&l_bd6V76DqvUJQ_?X1+*1p?+8*;?^w
> {^h
> zQGo<qA6b|A7Kzd4+vQ7^DRLU4tnKCK+K*6Ia;w%Az3*CnM4#8Z$)i;(&vXkU-
> (Iom
> z#OU*FwvKfhnAlhtQkgK7$pFc>w3u#}r&Rl9X{1d*GXhlf`TMtRrqH&x!>M+8ky
> cn!
> zZ6ThMTjg_X^xl`tsUagjFa~yi6&ss9S0jUP)34AkqE9RMP38~p(@i}Q#!t~~Mp4l
> K
> z+ivu;JSW`}i-zBMR9y|t#EmZ65qsZFs%;$&GJN;Rd<{9`|Lc*_Iwomg?n=f`;!5*J
> z)@c6l`T6beNiC*|xv9f9S^C01>A`L6b)?(mO*TSDGwp(M4W$=-
> S`p5D$rk49?lKwF
> zeTq>Qr|J>xdAe|B?2sgI{fpG>9X)!0BJN<N+9mc%x=kann5vY0*eX9`cYPq8k%
> #Eh
> zpO1Y_jIQnd;8{-Rbh5j0C^sE>o!re`X@{`?bByT4VmU^{;i5z3t7%lSaK4HxY>FMq
> zo}O<s`S!VqX`H@qF#n^Spf-
> &T)k<6}vJ(^c5Dt!ViH^w;SIXShG0vqk!tQqQHoFh6
> zNcT>gY$wm|C?)&PO`MvM3&TF_RjeCftym!x160@Cb=%8Sr=yx#P~62{S+-
> 59P<lzV
> z_bWo=Gik17=^+nW<@3Dgz2$Hgbb5Y(luIm9rt$^l=z*%+6UY0MBX|%ImB$0
> ?rbF2m
> zK@EA>cuDrZH*pr~3t_{Gl5by_I7z2kF;fjRtl1p`iBe!qpunue6u-a)i4zJ692i{1
> zbYd_Tdetw9U#z(~%=Yp4bPvW)#u+W!ej?6kHy+8bf&k!dC$4AHCYomu*)P#
> uhE+zm
> zN=BHB^b8S7&$90y=QDv+<}f+a?edv?^YWB^*eX9Sj^2AR1=4NuBl`5Z#}suLM
> ^M*%
> zXwAWyBqoCO3I-
> 0ucpGot)wWjV68|!C<6#GMgs5MdYI}m$(P#9l!4X?TCbNZCTm`{V
> zrK6Y1tdFI%aB{0w5r+)AMK<KlQtG?NuWB{r)@S5%oz~$RtupOWAx5|CO?V1x
> nIc<;
> zE6hnrZk12`I=P5ke%{Rizmw9H6=>Fau^*Ai4lLun>_+bARI7AK5JzOqb}5jqC1Jo
> 8
> zj{czNq3Rd*_LGx&s!*QhPS}w$bL47&cGnniT6gG7MW0JGR1Xm(Te}81YuF~y^
> Z2()
> zPCs|0+T~|jU#8mP0HAZ_Jg8qmM6F{i6zd<8GgOJl#!1o@bU_P|C{>v|1n_n#o
> z^-q
> z>)Xmu^G{7{a`YK4pyFzaHp!dpC{F1E3o1>mt{>QYRBi&fK^r+Hh_F=K3aL1w)o
> UZk
> zH@Wy-ej@5mO=~h!jUN-
> !?UGm6v_4S1rdD&`S>68Z*D*+H_pX6LrF(6+liL*CDHg71
> z+hdTytd~W3kl^!*Ze)`@3#Fy?Db?mk16$=&g!Wv^_1nR^$Myf+Dgo}6y_@q
> &^H<o9
> z&-MNMmg`F`=3E5|p*@MZ<)3i<#Lon$@+NyM^p-
> V<7nybktGM7$!C#urJVo+S0-{bx
> zw@Zi8D$XQ)qf&PEDas%Yq(h!;-d1G=y3XLa%-
> ~Gh7E0={J}2`AVhPF3sa<p|l&hAX
> ziAt~Z(OYG~!ZAgXVrxjEz&*lG<$>RuNVuog`Gp{*Ob~>BW7nD&ZlXYwnW8!k
> hp&2M
> zdpZs??-7FMAjdYzkgC^^HChJ;w~{XqUxz$g!`Pp0fYcTXnC(mW6!d)Nr-
> =150c<JX
> z=*ll-
> ;&c2Sz{)3?n>I?^qXzR*ua5a(7Zx&|b*q6gewOyEO6s~)>tfNiQ9>a#nE%Qb
> z;Pw(%r@1vTU1x+8PMj{qN-
> PKi4e4?TrqpQuIZ%$phH~{860ukqxb_fHHlV76I1e|N
> zy`S{>LG~Dy8)QuGp38(~O$bSZa-Z}bmV#pDGOF97bPRG(?N*-
> 8mbZ2Nh!)E{SMv}*
> zVP{?6%(UiBb~LW5`yG~c1}Kyx=4HRslSc!qqC-
> R<Ar)E>_7S3n_$fMBYH3I(O9Kt1
> z+OOp^`z<LgoIw{{rzjgdX@q?D+E$VWs^YamYX|4XCu`;(K^s*1;6tgle6=}Tq7c;I
> zwrSC4Ito+gxHX)tHKc8>!Yn6g1$WpaJm&+I)2n39-
> 1yw&R_Q@#)x|51Np6+4L(8V8
> zGxBic)wK35`Em$FBQu{@srChYQnXx04)tY{&1;iwem|39P2{)mbjBiaa=Kk=Nw-
> NY
> z$(~S3f2QnDZ-(hKI#EXbz!64$=zOwOj8{MsOtM~3irjg|P8uebaKq-
> Vw%w~Hq}!ym
> z@mhWS-
> !KI{#I8X`+HSP9G@1720i<JQs_jOB%jVGhWR$|huiQ$vwIbWE<W|W#`<`Rd
> z?eb94F7%etXQ+35MqaMNI5VJd3}kN=&Q<q}Ww}g4_4}}5MCdDij)sawu-
> o(IGvl1k
> zam(^<XJ}^LSERK&6m2^Ie%yh7pHe2j<K>X{3~-
> ^io2Ixc(wEiVOZIRfx8nGCa#p!7
> z(HpDl_OqdwYMTetTC6NFIiO0XGm_BQQe|#rCZa3^)9`-
> D$np9$Hc1I8!WvjcE<9p2
> zGfkz<D<{mNYk$nhN$;bd-
> NDnYw&}DbqX`01?Q;bpF2HKLOdc}&*)E?d?c_mDzoaC4
> zo8(=Zjx0@O-
> b6Y@pJ|sbjP04WnWQviGMDhhdVrXvs_;ldX>EafO>9%it=f8mNg$ae
> z3W16Z5j^NZ`4v&RUDBJ}s?A!)kUFy;mV75?RQ3?OOK!)ISm_vE{@Lbm*Muvl
> >Oh2<
> z_rW>^%}t>B&x|0|sVJxvr}v%)^X)0}j+5Ixf}HG1+49hKQke>h3Ddp#C%kKuU+
> MZS
> zSk9m4l%-
> gc(u2MKT^s6oxHfd$BekJ*{QZ=_1N=?>LT%`lFV=?sndeXNcO8EV`1=%p
> zN&Z5mrA4LoUvX(kX=xb$jSZBUN12cCeGT6q<}Va}*MCK%7Uy%6Z1}^M@cp
> 3N{zq#=
> z&plQfx{~iPn`%Sf;oX1nyMJSC=x=;~m%l%e_9Wk({B8OQZA~be5aPf5zhZeTn
> Gm*b
> zN+*mN3&<13%FoC#<0ecPKcQ^GgmST2T6-
> G$yGERtE3>Rj&deo<D;&cKbsJ|SVySVt
> zJ2Xp}14U#|U$8Ru1(Q`sdgA)J$hzX_^YxK62ZU1fHsdmG$Ke7C;tmzb+NrDw2
> QQo|
> zZ<w#623taf8$@%jkL@Z_Y9d@)%q<hcK4?vB3ZJyi4NF-
> TjKtQzhee1zsV!cajb=8b
> zWeJWJaOofmkmB4=@-
> 7%&|6=+6#k~IMjnYz%{w*HTMgz3EzIa`oYyd#Fu_iWU@vr^S
> zJGL!}xdk-vGi|iW%tL2PUUF_ibP(t}*4Xks^Qg@XK*hO73;Ux-E9H2E9IfO>`tkt_
> zv)f-yr}lh05ltjZFg;LysaJuQzUeTATQ7g(M){?ZfQgs=rHp_qA2iy*WbfKBfm+51
> zfEotjwL2<uXJN8_|19AS97CE!YVd?SuE^-Bq~)V)x%9NA?-
> KZ#Zx21hezB_^w=Cc?
> zwzfU|B0kNB6qlKdByyQeroD=Z%Ie2myX;achRkhtmn9{$M?Tv-<@1pp^7-
> 8k`P}*(
> zpG)s+H~N*?uV0UdqPp}xWhP7SdwjG0`o@!dJ^Z=09=@#As|bP3Hb$zgn^&3
> oa4OR)
> z56xkYqovyRX+DAPgm9>XjcA@kmZT-
> )K7QD}W85uT*ipM(wyg*pFj(pElv41MTPITo
> zLF0tA6Un34ynVjn(~%knE0>Uyjkm>oAs{6F^S@gb<!&fg`gJ`i3Wo8FUwFePY}
> HJ8
> z)%__uCp!9w$)M%jRycZnFMAb;w&@pi>8UVsuvoy%m*^K`pPy>l!07o8j-
> G#!v3JyK
> z5C-
> ~!{ZvWrkP%1T)XbanjTFEykzs5Mbs^;$%T7VCfQ*`oA62pV#8rrngnu}d=iJ3P
> zT&E+)-
> 6?M9Q|~%v3#KuyB+OOe+Ah}1J8?gWyvPGdqVnd(awnsh&3!}^jEDK@uYk)=
> zpu{m-SlAO0K38VAVU=N|8-
> 74Q3vVEvfKEDAgpXFJ9dIi}ow@Q{Y*vSLHhE6mtfJ4v
> zQt0P!rjbp{nX@20aBr`W;64ull!JPq6ka@q5Zm_6nIpsdycGOj!TaX`yj`la_@O^s
> zc>NqshY#;^-HP?$z3T76o7f-
> 3@49a=f)TF&l+lh9bkOaeTn3XLkNbl8%ZBI2pJ(+@
> ze})~S-8Un9FmkIrdrhon)mkd9NxDvENr}P04b-
> sscp1@_k2oQDC^p|NE*MS%HJoQo
> zfn|8BdpD=kUCFRYVRH?qYZz9E3MJZ6ARJ-
> 0UhZ<LvzffK@y}ix^@VM8OB>%q?D%ci
> zoVE=qY;w9?t8KgkwYEgft3TA)=JJ?y`6U|syjSc#y=rE%VGzWvn~lVp<}#JB2L&V
> 1
> zwy!Xh61^(!h)34^h$;v;i^GNFr=Dr(2_@!Jmz?<L_Dgw><mycq%O+qiaVNMM
> Q+{gw
> zVGefZn7EQDrJ#safUCo|pD0j9au?3(ASlN577wdDJk-
> $@!JLLTK_e7}!U)f|h{zuC
> zz`RqMswEJnw5?m1@)IiqKWntTcs*H0hBeI%g$mgFr31UbJ=2Fb7G?CRQgFwc
> lyt^|
> zpIhZTL^fxdKwR7sGw(k}K*g}3XiZdj&=xDS%1RcDSUZ>6NvLwHtp&}nB}wO5*
> 7wMl
> zbdL)pYf+e702o&Y!gZV<&v>81sse#NvfI4QC-
> $#1b(39vVI=jyRMHe4Q0&TkWP`JW
> zXlz<OJ=zV>KZeg!EYHqu{w>#^!M^kP>A}H(&R`D;xw=5IbrRB3cZ0LyY(J|5E3SD
> B
> zSCcTk&SZLiCCf2na2bM>&GSoOoR^WJ^x@1snHko75+6(c#5E~eq+N<MnJ3p
> tN4Onr
> zQ$pt6q)eN<7uOF7F7nNGMOCtY?()SN66g{8g2c?Vm#<DW_tTEhUZ9=+6B+0
> +8#lm%
> zPz2Fxq{8YK_a5CM?N)Ew+as@uhjz2n&CMI<*p`#66`}aqqGFkg^Ubm+!e+-
> =Ub7W6
> z`x#Uuvkz7Qzi;cNa<hvcA_J(fHBu}~w0*pe0f_9H$#aBfG&pNrWl=o|m5SGrEZ
> +sm
> z$9k3QA?3zCJQT?#&zh@_O2mdrBb~fk`&*kX&yudUKXD;wEY-
> e)S5j2I{UnNY@VkGK
> zg-
> xDq8b_Xht1Q*_oLfx3{UnNQ;kR*%$+Jx(To+3S41P~ZF<b&bBF$H@IVdk^Uc
> MzS
> z8-+Zj+9abYzSQ|7&l}tx$g{1JDoA^R-}~J5<XP*;2r{vf2-2F;iWMv((s^D=M|mlI
> z;-$dPO97Ra(kd^d5nf7t=-
> K^HLL^<0nGA1ea;DLkLmYgF38PS^?GWVMVE#Hsrp!F|
> ze!|vsA-Khb1Q(-R%NZ@ln+|dPLo-`<uaI(;*(|@?g+fxQezwZ2_-
> J9_6(`VWm3#yn
> zeW1;q6&Y;a%nIk&sv>3(GAff1u!tY|FPbCOwx8;gTjjGPF%ckcXpw|)ONp5%1g
> <Gz
> z?`CXKPgKjj2oUr9;_vgD$5nwCjo&2uX6~$e4Hl@IA5c-!SeD*H$QK;Yi36Uljm;{R
> ztCP9=1J`nvGTcwL3S79ZMg*Zbur%6s3U6f9h0}`Mi;lgy2aP_}7?v|e^YK{hmP^R
> {
> z?0KelqHA-
> ^IW8Kxtpk3$FLP~?d*n=nSACc8V)o>SBGZLc=lhbC;4AfA=0iNQ0|v}R
> za`jN_M3>8DA104p*(a}~pM^IuYa?rBe{|U=dJ^X(=R6U;8Uaw{$hT?yCtXP3Cm
> JR0
> z0BeB3N_j6G;w0g=h&h91EZjBq-8ei;_kp0vCKF-LoaE-
> <diD9N(MiHaZXBAGS_IhM
> z^wkm5@ho6T2(BFWy7eSKRq;;z6k8jvd$zV`RmQwXM(Gs`^Vi@J$aS~MO1H{j
> D8~GH
> zLH+L{$xGgepD7apDO;8<W6QH&l-
> jzolG^YrVyG!kHh*0U<&a6@w%J^w@@uZLS+ak_
> zm<^bpN-
> kd>q3=C9Oy3(VKBIZ{OHg!26#`n+b~hTAr+~TP?=E!KAyZKD_AtkM#Y2^}
> zYIDh-J-q`}&E|9*5kcy7(L!7stK{WA4u!DaxJh2*L$`9W?dezb6}qKoexQS3y4R1X
> z)+0s5mS*1kh2)h0hIuhhj8~4}&3#O38ClQ=*E8aKgn@-
> g;l*1kjF(oB9($XJYmd_w
> z!pn_kQJ5|f+1iGr7sh+L)l1F$vwQL2wDzmsC0%Midq_Ixh4WX|Zk(*aC}oNI9;L
> d1
> zxSpz?Ff76FpR(X%L{uyB^dDEPkx*nKT0Sn+GQyDb#^DoHq8w-
> Dyd`^t@p0xt9z-rd
> znfc(^;9Tnm-
> pNC%1=@f0q1DPX+~6!d(mH|rI(HR|YRC$RJLAQUw!P7v{Rswp@-Eq2
> zMk~V7v}uI(j@w^~J*R6n4Yik_f6R}LVe@0O^^m)@fWAqKc-
> oqWz9;DO=r=iM68H}-
> zZ{8^1?C{Pm4e^k8uPI_#k7{<hGw&3pPRO}iBvH>~oknd;8Gjn>(h^cTXGtriwCs
> ZE
> z!^VeEtK_cBIgj!%$o6@CcTKrGCyMqY=iE<_oKQTGw^Mcd7A+a^!Ai-
> %#vWiasHOtH
> zvF1JJ2?50Y&y1NM$W;&dqCL4PXDx}&>R^suLfj!3?SdnF2}=P?XErWV^6ldI#Et
> g@
> z6L-
> VwRty~#&Fs15GvHi}&h`0<ip+lpD?%~b6_Sz6zAl2Oz6^UR22~E5#V>^tiX;GW
> zpcQr{%SsRjQ-^?8Wa<iP6>H^GZZ}k+_jZF4j<;?l*s0g1-0PYy7YvJW(>}=3?rKip
> zdW)U?_;$+3u>0cqLXucp_T01k-
> +>*`KfM@`R~1ki^hyEsqRb*1Ldo5O)#d%zB5Ud+
> z%O|EQ<*@{Ds}Cq^rSbwfGq^FvsFz^KlJ9i6eAbkQ`CML>u9RP?O8JGOKcB2B
> H_A6K
> z5yoEDt@~4z1Jon{l}n0*3<D$!xj-39Nra{S@C{um?T7QF8e`glG8Kg+aXBiH-
> S(%n
> zhL&*j>B`4IjWFG0$K(d{>3Kr3Ws*=X3Bo-
> |%PfdhHJXpvL}94Wr%S&=GV`6Y%_P0w
> zOWL1&p^8gk3K;iz=2Hq6@V~o0E8tI-
> gsq5xkxaAJp`pBKBfhQ5n;sM=SN4+VZvk%-
> zhT!o($ThV5wk@)dCc=6m!X2(Bcc?dCzc{hk89X1d_h#^RJyhZwgSZNHhItPSS$
> bx=
> z`<Wew(prVNIjhqizV!hJJNhlryjc7XVUFd((RCu5t!g2G?ONOQvC`)j1|GBap9r|2
> zo_KlVWuQL=_!_~I9j2qq=b<?J#P3|3E#YBwe(njBycjkAqnpbDsaPTHW`+k3{I+
> Kp
> zza8~{_OQA5DWwRv4=8(qo7^&9sEt~gUnAX~?UzRp=tccrk`m)*=tJI-
> 1Q~Y!pF94O
> z*!q`D;8*TN1>0;1ol<BDz-|2=)qY~x@5}B-
> >ttL3M0AOFnP37^EJwDYoZy%Kpk#4n
> z!=iMh3Wqm~W-
> C`mIP|jQ2?~c71El2;C2(ZnP_Dv3n3X)FD^)r)o4j<WGc~0{q{H2L
> zc`nMU?0Lv-
> =@G(f1?5ANE+vr<mROw4RRQ_%`q)DGa36_<@?nSOaODHte@JY*tpm?3
> zU##_>lSk!1qccBWcad4IC9AAt5n<1rzXcNG<H4%UOK*B}j8<l8E3qQ1am_JL8i
> nH@
> zW<0q33<&y*<Ml&2)_<Dcu_9AGq+`P+OKwa+@Z}nnFFtPhB0*pVIHKKP#BZ
> 3X2(vj~
> z1>O_ECcYM|z?3QYVrd8bI3h!po2OYXzyg&Z7HeT=B55A4xsJ)`69haq`6i6?FyZr)
> zD=JDv;`UpK+aHokeh#m>Tg8(^tUsLm)T9t+2D(m_PCF+DDlHCHnp;A-
> bYq2w!(!Rk
> z^Khs_JqCfocn(`3R?`?;cD{h_JghZahG3pA4Is-@!R@R)lD@8^yiS=jp}*t{Qz5~_
> z4d!<XqyUT8L$U(YGa$E+F^BIa9uiZbRYK_YUp*`nE{h;AF)&Pg!-
> rQU=crg+Hk&Q>
> zjq+Gs8`~t`0dYK#7sms`#c`UGH7bOw=f_g|V5M*gQbfhE%Ilg^S3+x!l*((_)fX|>
> zCsouB)Xa}9pUOL^8X)krE*IHIw|LW6!W&aPN7;B#toG4NlR4HVsJcxYL~5&0Ax
> _Cj
> zD#Q=5+Du6_RcQz<M6jE9kA5QS57jguX5cTe1D^~G{4u#8HPs)gsXrVi;w!|1Jnz
> fC
> zCgV&mE)_d9bxU1oye}^g=PpT?i<%(?PIp4K=KBLRe+%Ny(<x=ermczz^@%l{
> O?G)H
> zHDV3VU2L@#Ti+flW4{=v@0OwUMXYk-sX-
> Icm8u63QMFd|p!!38bE+VTS^AKF)$^g0
> zn>!e^(&hi$k32xXF{!8+@U5_AL8YLqrY`0x1&2@y!l&z;x*Q(lP1J8%`R?s#LD4hJ
> zNw0ehiwWpwc8su4slr^1&I{I13T}mqp%id*R0WWrizUp7W0g4|s#*9zI^L~C13
> a^N
> z_+NHK?i$SERVX<%bpy*#<p!#;yP_>LA1;yb?%OU^N@L#T#k0FU^W?c3Mau
> 3+7OW#Z
> zfvNaHo`=pE8t>^Jz7OVf=SGXUF9$FeHv!VodlY7vo?efCfH^<2Gmp|*g^8lBS<
> HQu
> zmBDk%qvji0#9bSHuqABzzOKmgR0)vbp)b~$aX0_X5skcs?oxPjj3}pW`B7B~iw}
> *W
> zX*NJWFtdQQ-
> _<X{SJhB_^+iTGPfw#47Xa<+xifA3^aXo>zrhhU^KJI+Bk4K{U!$jp
> z3}2+)h{6)oLrPFvJZkQNa{cN2E{jxEmP)g?t1vDrN?aq%tW<<#1L81wV1P(L?4K(
> c
> zi;#Se(5-
> XFnE^T6hMR%Eyfkkd^aehQ*8pmiUFXiT>s7Jb2vtX#T1tW%%$ZIDRTiox
> zGlKPIUxc@)ns%iM>;idvW}xG5{5H^W=3vrb9UEXm1terRJ`bjj04|Ex6s8o%&$T
> Hf
> z!X>qrPIaL6R6*^Px^O-ij<$UQA+DH{)fJdS08VZ+x2awY+M;d$&iIS){1h9s^)!Kt
> z4=g~A7uwua_LulB<RRrSVvOZ7I@QzwzAM=a<utLYbX}$*xeAd?oudCyr`#S(b
> 7gH(
> zy3y&J5-9!ize#CVWh($VEsM$lyC(d$XuzTs{l7w96>R$kZTo)#`GaQ!AU`DtxjRaU
> zkAbg%&IE#0XPTr1oh5;x`|)prgdtdti7ErNf7u-
> ~&eL2Zd2q8rhJW)a(OkmWMzJ&~
> zwG=1H#jqhtTbb3UWT@C=hE}>QTf8&S;7vmtRPCd>G3Kfv*6KopZ`lqLlCitX1G
> 2kJ
> z#k#xv-
> i<1>>jr4zN!!GlKof5>+5B0qLm%FxGMm~srGXF<atKR(6Nz?qkxEu147IJc
> zwWR~KJvp?t;!W06F(R(cyD*QdPhY9H%1r}NyXIEVAL$Sn4x%?H7KQ#<wp8BU
> ZTT-t
> zDzH5=|D8LO|Lzzqo=d=Y#d<pU^6Hg9KX+K6?MZr^9nLp1f9<g?<dvV<c}}>Jh
> &*$P
> znz_{%;Swmq<H{o}4}S=41ljVdfu>!3!8TpMmJ64M2$J7FCK&Ndm8vd$K)2%ySl
> =6g
> z%KNNHwUrC^&Q{^mpc_h-BM^useueCT+zscuv>-tkpC$wt-|qr-
> Zz!m{t_S8hd^+?n
> z;>0l=CgeV9yE3XEb`=yW?>5RBSXnk2qdY@XR_XEdm&L>A;a%(zU)fZEMp4Sb
> y3hxW
> zakz)YQm^cPxqQ>bQm==lK!RdP5&~Gd6ejOU-
> Imva^HD4qVxb#`kA)Vd5rw{|tnuyQ
> zLj<UY4|y)c$3}T&)fStd)?`J=5)gxd`k}_?X;t)Tu~tQ*PqR=Emy%RngfIrMGS!`P
> zU4E^306cuJ9)|CpQS=|*lI*%a{0^ZFDNp%Qa16{^qI}u2GDP|4m5JZl!~P^bf^d
> x<
> z-
> Hhx?zA(mKY+4e%7l#76(?wLg2Y*o;a$?hlY6>Ms0vbs6Gh}!A&K{cS*MA9Q$}M
> p^
> zhvj&#AV;n9*svV`Rgj~~SurffieL`+6mnJ!MDAHTySAz8&9U)GU`l3-
> cqB#FenqqB
> z;U=+s&9BH?)2Be2>|++iIXM|jDVE#oB&CE4F#{=V(u>?DhK>4u-
> 2se2Ip3?Qi8!gM
> zfKPl%D?u%pqm_tSB5p<~BIFdcgkPeT>|-+^uZD!oXYq5-
> t0BZ%=w%~PN^wgF+Q`0!
> zpxy!h)a<U_!7(ldNx||A)%1)l*xt;%aaG*66Mzmd?pEjo5Zzd0Ka~cCH5X7dLgo
> <L
> z>p|#1)C-
> ~{(Tpfb`<k49ZV@uuG<zX*f`Gd#LeVxMC`E%B0YqC6tVn$(rRHn&q{I?|
> zXa#^?pePX6WZH^&Ii0Svd{ri7nu5*c&Tvuf%n#-
> {PxH7|ITvBNY5OU!r8&b|N@JC9
> zE7LxPf))OX3nhank&%k!5y|-
> O%d7Pv^G(g}qXef#wtB8&V1}`?wO`Qb4SQ#|VyMYB
> zb9LyNpVx+F@Hd{n*MC;)-|6b{mq&;3m(k?A@)z|+iww#QjN-
> #DroscA;_s*+=0mZu
> zvw{OaD;|BPJJ-
> WA5bP^h$9TN@c~_vjH;s{Pra70RiJm)RKC^S7a2%<^d}yySc!eXk
> z4AwUPksxbJmy1$I>_3)OgB(l7+{aaq+*B?mWZ}wOQc)M#)^DwIo8)a?37|VEE
> k6vw
> zQ*0yuko=VW(P8-
> fU##!T&Q(l(BY>&<y8}{95n63RKMi2Y&+K%c1E!=3^Bzv3qnhTH
> zrQKCh5w4g^!PxN+2QfA>KjZ{bfT6Lan3!n2{dLmoU2T!vkB8yuum9~5;xH;yp{D
> fa
> ztB9^YfW~K0<7JZZVU=1X^3lMAex%zhGPmVUAtyO!0WOUtiL0&7&}e>lxhlPg
> X59ln
> zK}P#cU5GW9^J^t7lDmMzb*f^>s<-
> mOIb1+FSa}D2f4NB#LO>fLrCd@7CM79(1CKX9
> zdj8?@bT_))ZExK*#_c>N3k)zL{$?23Ds~Aa@{^Sk5@gaYM2`qqG^01wSwR#`3
> C|+}
> znF0IQe+383c4xR=2@|t=<%vV|N?MeJlEiJ|`D2f4n19uVz%92&qM|m&#8vnG
> >HsvU
> zMt5^pUFN&z+1DxVqH-PP^aaOFv<rC9A^z}qDoc%X55)-
> &5WNDSJH*`bD*ml@zY^VS
> zD63L@<L>|>4yXVUMCb*u_!C<_alo#x1Nvy=#xiEHr=Q8QuSscrnjFy2#Qt{fQ2
> X0x
> z{LUv<ZwH)Jpq-z8LWlJ@+2MT!^HZI-
> 7sIH0PUdHJ)=^rkFrV9_g|gOiVOBp_Fv!gj
> z*9hw(QVg`H0~{j~eWkSZRFQ|=3pa1WB*C)?A}(>8w>~Vta<90vx<|B}9?^1?4
> @cK_
> zNnZ6%vy6M?(gI>BZC#|);BIBmKzhN3u%7F}DbBTOu<yFy)8Sw(G@YKeo{82|
> aydE#
> zp><vDiG&mhIc^MQ!Gdfi$P>gSGzh(jZ0>1t<|{(2dCGjRPh_Mk^w`j<?`d?V1~
> WXU
> z89ZN#Q(+MTrEVXj=1-?V-
> Ly#6&KyR1H~*(gdc)|>)3}vhl6@76C@XjjjK17CCUVRj
> z{Tdd6-su13<$}>C+f4J%oF()}-
> _PvCs=d+w{EJ$MN&XPbAmF@j_i|2m`Yf4U7HB9_
> z*boNtndaz^0}c6^Z9`IpndUb%QyL;lR7|5paXTNk%+aGx+t8dqLsJVIBHK)}A=r?
> g
> z*)}9qm>=x+dL-P=-3x$hae9))j<`ORwywgP89TlB5^&;X!TL$n3qCVRqJ9y5alr;C
> zs30{=D*GL7DpnNn@k_2;k9#*q1Nwz0tXzYYWvXt#oXTf$VxoQ?>j}M>uCRpP
> X7Nsi
> zR$?p((+$(B8>dT~4bxep!4%V%&#bPUNrkD)XVQkpkp~K{yYu`VWIZY50iS8e)c
> 2V>
> z?vIl1`gU>Km7Q$jWQp{Vml0li62+4zRm1qtX!=3kacc4XLH^)`rb9^uPDZP;GIQLC
> zAy#E}q{Kgxxj(XukFK4D;6cvU)b&Kya*vL3k^DAhN&K9k62N_8vH<W58O4NbR
> %I!9
> zAeJc2%EC!>axt&o#azayq}sQM=njhrn&U+L=*niWGOnKYa?V+fi8MKVObp8b
> xb^nC
> zCeV}IIc^@eLZ>H~b-iYFeXlgfq(-MZn8OKH7VHm7O|(r^4h2fpc8rPJ-gdXbJ-ys{
> zELht~TARzBl5<4bgyPe+W3n9aI+i$5TM~BxU8Zo<fSjU_K>BjUd0C@DZI(A#ba
> #un
> zilRhKVKHZAu<b9rA!zaXiqED9bF;-(lVjT+g!`-3V$>u-_UQdu5Ujga>vsD^L3+<I
> zhZ|iGcaF5^h+<I}N$y-oMTMkz7>6{U6o-
> p>kKKCnDefQSkeSYuder=B18mK;j3D{^
> z1OFU1j>THV_n*~js{VdaH0~GEC2B!U^Zn7x7@@<uGVV8BKfh{S{THRO?|xq
> Wa%Rc%
> zS9wmylFvR#nWB4$(ebExfLHc9BaZEUvB6yV9f6)}aW>>m)%%QaQ2t`0<h)&S
> n&sd2
> z(vz(l(BLrad@<F0pMY{-
> m4HIq_4ln?P`cUN08dO~k$ccI@?^C@ZA8O?(y!Zgmpsco
> zCZX!RV0_@Vj*`rR(jCMrJx_QkW+Qds|ER~BovAYGeHZ?}5!EprYcfB)PI6b7-
> ^uU#
> z2UC&ki)eRXWaqrf&4hK>0ZKPFIu#W5=UC%!1H>eKTMWiwupBDgNp%7JD%
> r>V-g_F%
> z5B?&pgmw9GLb8=xV<!3xfSWFfs}MimSul((8R9AUw7}%vqE1=iEy9v>;^OanJL
> Ub!
> z0&>@S%=&V-Vq9MC-
> t&?Q9M6i3^TK)N&0PU;=x2611uPNW=EUt<D2qxh$|;}3)CN^H
> zbPDT;($;?x{n6dJ5pB~dLCiMy5f1Z25S3%Jhn~vvKazj`^hRfGFweo?1hAkvW;Qx
> Y
> zf;l=0a#*BTd7*<Q^HD|1BoN24F7JQrxihyg2VCX;Fun5f_>+x?g8GCrSTAm~1K!
> UV
> z73{rAxq|$8r)im_W-
> +#DxKTkF&F}e}2|QxmaN%A&LK|*=>%k}ahnyH6K${J=;lqO%
> z&qI&-*X^yQC;O^s6kp;gb!8GxPqmLe6dh-
> VF05yd&y!G%)mc0eQbp%0KMatNpV^s7
> zX|2NitV2l%)orSb1^N^*qMBJiMef7~qRSp#{|JS{l-
> ;0n0B~5x+qpCVz_SvV)jNuq
> zY&D{3ofQPY&ujsZDonEv0A_3eC<`yg&jiPZ9%;8nmH?t}6ECZ-Y}W2-jL-
> *42m<5n
> z-
> XpE*50#)AG?!)OO=Kv4tCj*zuvjHm7TfhWE0xrjl}M?W<bqa??47c$S`NCPh4ok
> C
> zl=3DHm;=G>YS=V;)eoE~eUd%AG&c(ne#7@04UFFqYO2*S97=(K{3Dzx|Fu$7
> kOJND
> zpRRlArw?-t6{-8Gt}83D|0#v#1}I{>;0GeNj=<a)(|bsOz|}hq*D53Z^Idk6Z-%+=
> zRlO}lqp?n0q4RvcT4avC7MSSf2Dpt~1_-rKv(#4Udcc`v2kvj3Zz#4{=(5<s-+PBr
> zsq*O}^YvhD5WP}$%%|$!JXOCMAgYh;EFh|0A*#JEc#vR)^D{g5`BWWxUJC)|
> N~LO6
> z`cSoOt_oG}XM8y4?%L3?GrFO+@>Knc006yEaDb}Sveys<z|U*}P^w<F)dS$KL
> cp9S
> zDki?OZsDT&8-}TRqJ(yaNMl0qLW$i1QnwO3m(okfkJzl2s|mAlutdGcT+V{tiCY-
> E
> zFEJu9qMjedvZSYK^Nw@(YMX~jnqwv6epVqFA^jsSPkFIgg3qIw^jC8_OU{ZZ
> &6mq4
> zicm<t08M=9c&U*VaCA7NcTR&i0TMN0AE&_T54#@q!aEVOjizCumJroZdm8(
> d{HBCI
> zTYP!=|KMLW6>lDIo%+EY(t_`Ft^QTd!b*InYd^CyACk8IRoU-
> rAy~pP&=K^n!f)4`
> zluV#CDwgOih>}f+5qzy~R#QEWLds^|#n-
> C2Qc(l<2r37jJW}aHI6RrJ1=7dGm$fIB
> zW*?9d%}-
> =IXrAxAPUL$0opcK(4zIu)b6s#E&*VB0UvJ4R2u@t$3NUe_Ug?o0?w@`c
> zD9so{7tr1GUrK}dm;}nN8aF;DCTpP_%+K;Hxm5vh(<@y2miJmjv;Nccjgo8;p}(
> Q>
> zylg~Wq8DW@o-`f#=tr3DBiUQ3`!QTadkC67#NZ@`f__Dh^HzYQ{<=-
> 6!;_z6JI~w-
> zBk@fierBgjNJ^?O4}8xS>Kx47<*lT}PEWut5hyOM7VA!KSf!09Uez3qG<j(T4ZW
> M#
> zlSO{>VfL~j)pdqbl}x$ndQ;8OMI>6?A(yUPd`wnB;KyHI;yn5uIC`-;CD=P^)H8<o
> z0$x<5#E0Ll%vNHMANVvFOH4Jl!@_oj(AHsJ{p^(`JF94z_}~(x0dJO2Zibsc(6}?q
> z9L;`)WQV^HDEq}KDoizKb_tK}zCKtKpHG5+m`3v+jB#%_%}dFMJ)JSXEP3D^8X
> y#U
> zj@c=oC3jcZ7XrZ#nWNro;v`5u_ve8>_&?oNyn(?v7Pn>X&6yGu9`F0tKhF3`i243
> _
> zxp`H85Lvz-dqDjm;)5L&$``{eBLK1{ag>AKwxKl#BGeIGd(=e{FpjI9AG!N<r%F&x
> zz!DNX^nc+80pgPKbTw8@XN5-
> SoQ*ftFF}#`HA#a>&?i<X1EG7s&44gkyH$Cp!K_}Q
> zGXd_C`&Znh^}@zOa$#frA-!>tz;35)J2<AKBD0uX2Be3GmOgvqVqf%mIr3W-
> znGv5
> zfQbuklNr>jvJgVOL<&aFn?i8m{y|*7hmB?K8ViU9zLG$R);~a^Nuql|jt%DEM?L
> 5e
> z6*ct(gs>b&LD+KZB6^FW#}-
> }sy(Gi&Bd$Eaw#RNMLBQ+x>H6$cH~e?Y9nQ3|O3@#%
> zLf)INtl`cx&pex-uWn9f!AvHr9ze~0*PE=_24V4{?GoPv#R;uo52K}8!5)$ztv#u_
> zE{%P8suQ6GP_@i!d9Ri3Udvt5@|<AHHm7Y_3Y$;nTmBifuW5~8zgxwTuIBz-
> wPATy
> z<0AGu&T;9>vRZ`#Lc!?+>5V8V6EEhVEb8|U#j<HcFZAH#-
> 9j=e7b(ia=vWLF9^3pB
> zzw4D}2z^C%7Gb5u!=ENn+y*MI)GiMF<tFlzlSSr9J$R0W(3x!Q9E@w-
> gc(AOj_tgB
> zP?&;L*gAF#%k#lp33JjL$pAms^UW1{P$?f`%c**htN6+&hfH!eyd;z=#x-
> g}zhIh*
> ziZWV#o}|t%$ZU<z{%y1xan=_E7Sx!RABb|!dUaT1atFjG7Fc9N=zN{VS+L}d{Lif
> h
> z;f*}m&No+V$<v(UXLfpp?4$~F=l}R*$Lbog!>p)ex13J117OKc#h0G2SCxYHA62
> q*
> z-
> VC&VU19r}=g&9Wp9!?@XSVH273NRh@!MZQYu>@0plo&Y^zq%EQlop2t<6l)
> odR#!
> zVEpPed_ty#2gPY|IX6g1RJz$J;+GMZMa4d$$1#!1aux9=u?C!XfL+YoFBCPI4^R
> Q(
> z8}fW7k(kvXd+dS^opZf>16VH-
> O^<(^?%ZKJFY?<%{)d@jg*xAPX6Mt=c@aA>TtBnz
> zyi{TS{B5uExfY!nAJP8Y;PppLRjjHx<+toAYnx*!S-p3*_GsBSSD)!2bg&xkG?B$A
> zYtjbWJ3JGcBM9fB2J`Xp+CyLEaW$L3d=UEvEH@Bu&cu~!hei|g_2ubsSfNjM4?
> @UP
> z_#$NLk%>#DmEh9D)J#_^alH|gOdf^>`KpYc*{Om;Et$Tw*~3&;gL1+h6UXW5
> Qyf+8
> zk(>bpc_IB`L$*U`_-
> 3pP@p0WDbm{lx0AT;gTqzvF^G!(*Fh8>eOzHQ6JYXwTktnOF
> zk3~Q84DFenPhsD~D9P+DI6KLZA~9KlDq%l*RGM{p%{z&Elmu?{NPyVyIPVs*
> $XSMJ
> z5~C>8UEMj9xO<_2d@6gFVp_H|AR93ef?z=9A3H{Az{~)!<Rxb$#+fMsB1||U
> YRmUQ
> zMsBf*jtsUnFIkxTbgw~RhQ3(v?W`RH^~{|!U{r&N$>t?tE84;~p8OU*L<>Ub(ac
> YE
> zKq5QQSw@_~I#Xwt%G6~F>r`eZUMz@QUPZ{<Ad!oFAihdOJLgW}m(@+i8-
> HC@>tfp5
> zjB}@OZE*aVu7UCI6UkWu^!^m~Gu!dkDSW{<Z6S2*Rp2o9sbRw>7EgEhWHO
> I9eBCm9
> zek$=y2m|5`pDb7G@O^o#*F%l&y-
> %i|hF_EDDg2)|@T&ZfWuwgJA?J|iT1Hy1qI2a9
> zde2Z6;KU@f!+@Hk|9_H)TI1J7t?^ytVQhr`Vk;2+HO0rB29b=#X1CCIei5!l>x<y
> G
> z9-
> C>gIi0z}W8^|8b1OHINeO1cKF9*fb{9#q@R0p031NhjIk!pAjq8N@hGY}(Z?4`c
> z#!HLo;I0G)Q2C{zwB&GKV}Ov?_UD=ds^k+x0tft?E>qQAE@EJ`sZZA#`BM&J$
> >1#Y
> zS$ZoFE8;oSDn=0Mt3~1Gd<T28x_fhXcrbCELK#-
> $RSz74`9CmTuTGK!d3p~Noe2qe
> zBG+vP)*Spa&xuu}H<+y&1V4<H9iOW$Kk2=AM~=k+@qgPF=|kJz5#_7Ftao$t
> oVKlJ
> zOiB2=s@t;!K({}vx_$j&uEhx3X4br|jU7u#S=H?hRSCLX<g8gSNkUD_#TXW|5yI
> cv
> zj0Zwkpc3w_RuUOW--
> mTULTN!onrQD6J?)WYBQI2Y9FWz^A#ayi=^g)+xx@B{M~kn4
> zV0kBTs+saFp&<EZ3^U)ZK?Ret!z;pPB_~oNHKo_Gv{{A{A%vt##6Bs5Ybi`jH+E
> 3m
> zXQ|@e>^yOS66_>b6Uuw(%{EVI8&cHV?Kg+EZwomOQ&Q_OU;nC4yI)X}!}Y
> Ed#$oSY
> z;wn-
> ZkLdIB#)XM~;of~yx1W%GcSz%*mPH;E|L&?JE);m!%r@ucp?K>XUZ?#+77D4y
> zoSBD0c27`=23OTId#4e*X>NgS?mDlzDTU2-OLITaHnh`g^-
> <0t)0{12o0EFX(@*%F
> z{wi6RuubNmbyf3L)#8FUDjwp*ZO?1|<}T`BR<X{^z0ZvEJ8ItJ!-G;NJa^V^da^~>
> zjKq9&hwnqKBA|$)d0BZFh$583g96+C)#@iF@%={g$4d6a;cthfAhKN79!hiHf-
> ku=
> z7uQFzdkD=PLsT-
> C=ISFg<sQvF=+PXGPJ)#OQ_asMTc49vgQYoVE$=<JH$u??K1sIA
> z%$$6S#eR$EuzoqG7vi;)cm7xWLAaaqYS5gn@-
> Z{XDxZtEE#)nUv92#V^6JUEkGz_y
> z-
> vTU_@|?B+ER}_@Y!O(#{dK?h%k@!u4=jE;3yad<<6rh+`5n;|(C45(PQ&ho1*G
> bq
> zqESnKjyle}1NSJ@9YDZS(&%ORMvL^(l3>1^ZB(gnX1>uCH0mzab^Tt&$d68c#d
> `1G
> zJj#ecK_XgVP}rPo-
> 7F*ZoN@<eLjXHRpu+&5WV_7#$Jc!9T(6HVpnf?EsMKceecZ>+
> zPcSWx4BPs7<ED1?boH;R%dM}^t*gI(b?f~_@hG3g(X~-
> 1E4xnk3rgw1q9eaJ`DNYC
> zeG-5lv;aRD0Qky6fS(kA55gi`V*ZLgx&Zs-
> EWlEm`PpMWz^4kp^|8HKoJoYQZa@$a
> zd=@zNzL{#?kgnU1s*5?BrEy09!59&1GzqnAFqK?0jk!>pq%QoM^%37fol4KMs
> nSx!
> ze70O<zed*<#aW0s5lOy&+P2rnq|2<yYTo(NQrDh8JuA~;2qvD$W8ygh#-
> *{#m_>o1
> zdqObL4fk>}@rXXUnDEO5FtKNokBJH(rE?e{*@HnFmJ56(-
> fic*&b;|tudCx0+4eR9
> zn_V}N)9JEyJ3Fr}DowsUF1l7?4XLSNts}Wdq~3I0=lTWXO6AswP91%0G<#5NQ
> +0a;
> zF5Me~6_3!)&Ur<p+|<>albh$pj@p2TsWX%Pfb$y}9dV;u`>LRNMAnk7?_7Uv
> ?96qT
> zhB_4r5V1$+`yLq^Su4aw?#ND>0i3#=SWNzH<l3XpFNmF$JUTAU)kYZPnn&&!
> m{>or
> z=&W^6U8gqPnQq>rxY;ACGBG)Lv?TWT0At)aFLu^Ag0I*2vBM=cqfS)4kvJ%k_
> wbrt
> zVZFH~h)3Z{2A~h=y8PzB%E`R9j<cnSDdvN4B&(U2Wjso>Bm&VLh8qrMzXrwU
> *tgyP
> ziNpjqen9pCc{ho`OHHOkryNJ|Z0?n$FuEmmeLA`$0VWs<uQ{-
> q0gA3&Kz<ouf^9|D
> z_Ay5V(0CmLs<)|)OK=o#B+7_Be{E4X`63EjA-@c(-
> m>o6h(vW55ii<&^1xq*)?1;J
> zy>3A<buv4;iAbiq3j0c$_snkYk0xg$o3XknTqi}_1pc9Q<Yz}Xd2lYU4}mVIRdq7<
> zh3K)&V%@xn;oM}FbF{@pjOec2N*MB6$+bWGEoMUYahVSFfWy^o<+4o%
> #Qp0hu7h^F
> zHJ|)e+Un0rh&Bj}j&X!}aCUt^)*-s|d~Ff4hWpASW3l$OduK6fuUi3N$ilLp3lvy|
> zc57wwTjA-?PLWzYpxljUOPMW2ndY~k&BC#<y-
> $b75h&l%W#X71C594&>tGR$oxXc#
> z5!Xn#9oLX!BUk1ssPp6VxwYagrkxyyDC`4nqy@E&T+#Zvx7N)YSDGWJW_L~fz
> Qjoo
> z<y&w#>Z|MC85-wzKQ|MuKiGl~7rNu?Gh`WtxadeV?|?D91v)ucT-
> ab%ZZM#hY9XsV
> zz?n-PCF1tmU@zIahdFRaN2gmk52M@-
> h1uzmV6o@n;2JXRs(Xx2aNf;P#pv^&e*#-a
> z+sk4?c`Uq&ZI$ktx_x&F_LQeGQjh6KJ(l}XL6KDRqsi7s3GZYUeM#p1xzy>+-
> {+Wu
> z>AFWDpqjeJXurO@r2a9?3wj^%yOKKs<8un!h=X3&y*?xe_VEbJ#Ve<cTqC_
> +f9$$z
> zi_QdWOUmRfNlY6$VXUf1mFtgL2iNtHMX~C-
> $HWI=vTX1^cBETwMiTGei>3z#jQrJd
> zUncWnV6P#A_+0IQZ1-UWak7645r?`#`Q#oMsKm*ZSlM6xq6k-?=dHs-
> 1t6;H_sx2F
> zcKx1c`wK&9%yOmFwUL>Kn!N{7^?R}lDdh6H=6%s;xC&Bu-
> 4Kot)P;Am>ru!F^BfCa
> zH{x7#r^jE1)|=-
> v9EG!{G4_X8Y?jpTnO)x%O+G2SuDMI$g4cao2KHTGJ0QGn2y{VS
> z_#&=Gg=7)n)2GV8gXXTK>EfjlNuH3mup)UQmlrj6WvhTCd%QAV0E#4!md82
> v*~6(<
> zy%Pxr*`qn-
> jodU?*Oe7BE|{isn6lrQUDvhjgT(8NKGRq%Q~ET`$o_TL_hb{E@=Il{
> z-
> =l?la(@pVYoT$QDr9@b8THRC?CL+t_D=jBiv3V%vZrWQ3I#=wEDkX5I06@nK7
> &6q
> zojZPu_NkseVLoy(lUtb)Z?}g>YGLGYP1irHld3e`{ID{Shlh@!+pW5Xbz+}6ay6>0
> z<ZfhCg{hwQ?m%9ooR#pCEPn69Jd)?E&v3K`m8#-d#ZVo6i}{3-
> trPaz+~ZB<eQbV6
> zJkfoPX6z)Lr<@OYCxPy>M_hrqeByAb?!I*0eV%D2@2}Aq@NU&jBUbJ9j_#Io
> oY;kG
> zblLQ1fnq)oN>rQZBf>_lHtyzhLS(mBb6@_Tr;5`!$8l<70lTZWsp8sG*-xsldlR=Y
> z?jwLR{US9YT<mmOa4Lp@Gt;boH~@~#={zOiNMZAx|5R}F&XH^>t*D-gX^<-
> +Dx%3>
> z2@T>IDt2HP=8`|Y1FI{OQ!sKk<puU8bU*P_=V1XL)H26|WW6#)--ikF=?wFi{|-
> Q6
> zb6QBGu$dNsBzF(&x2C?rT^}A6Lz8XbpS%XnDQtjkpc$rJ8#n`)0mbID4M<_L>j
> B$U
> zNza{PZ&~5GThF`=nSCs0yI0`rEMwx?x7nyNaB9~&Bs&p_ndm%dFsqRaf}+97l`
> 13H
> z*yvyLf@B6qYg+pkvw68(u8ew7Y>IhHyB%?@pZG=H;rW<}Pj%$mT;(}v$n_dr-
> c%`X
> z5j5t5#}T%D{{iki=-|WrL>+v^-
> Aw?po7q=6n`^MUSLhvZVdpu?yhSog*cCjRl5_5O
> z<oz^tiX-
> 1<KlkjZFG#!$%;7r00ZZQdPT$tvDXUwVjdH^XR1nw!@X`^lr2l%9bX^~t
> zj$x@Tewpv&FprLw-e?{_Q?7NQg+3m{SEc-
> kZ{pi$es_le1PdQ<WZPe_xe5o7Z1KDC
> z66>GEE|BbZhBX2v7&{5uu>^uUmSw*feDVL%g?}XXbKX=+sU~xxeYLApe#*a
> %Gyl=r
> zeyv*xZf#Pk$-
> HD=?JAX@@~@?M<8&Um|IVh+aQQS|G@3{K7nKfUf<MbAwYLrCGhQW9
> zQvU5Kl_K)bJWHlcl7HiaPhTx}QLTe4@%1@-%^Z1g$9Jv{#ZQ(-
> <X5Aq@v8C?+4UxY
> zb24j%ut%g<?B9!r*}wOX67RyCgUI&g&720nEQ+qZg`wV6x<Gya^ZL5jm*(@V
> wyZYc
> zMd@<s0r5s{kM%gagn;-
> txzm+P6dQlkD+?I=ZddrKCpWhNuwLtVR_YaN!Q*_(6}9@c
> zN4`XvG*XP5HTAuBPB8aU6H4IhVvb)QAi1WlcUf`nUr0|+Bz}R{&VF;VWTgJ0L1
> GQN
> zgVN$9cWo578q9~h7g#m+)zo*1$mywR-
> Xoh4U3y&swtTi(5koy_8vv61APa2guuRn+
> znW}R5n5pUv$eVt7^IiKUIp<m#=ERhiL38j2!ql+JSH&xKmCAeRvKfyQG_U^%e
> jBtT
> zBTq0wl$xz%*{;vUxs!L5>S#zQ!IJX%8+nlVHQE78olp3`IM*UWe3qx|=QL*?@0
> dr>
> z-
> 1W)|RYb(cDtBZrTWCqk>r7_TLg2To^FHz`SF!vgVk&M@I0Bp|z%N@O=E8SNZ#
> 3V%
> zU2bH+35^Y=uWFD68e$`Ct9$vK>_lzcU;&Uk?cSw$<oVutqH>^RlP3f1%CqEIQ(
> ;+;
> z)N_$8_`*)Z30H*7irX~PCSgfKCydu$@x)+#9gzT5V@3KG529zY!vrsi<bLh<Q}Z{
> v
> z(*-
> <9xhX1c@KVy!=($>2y60E$Q(<2|ei@%(DuaJR*(*pUXS1je#pc&m@_LRxBGk<
> L
> z@6XF>$It9+poG1w?C#H5X)1b7?rt=KIrD@l14_Z^&h1iv$oYAotvd_bLNAzUe*
> GVT
> zw*1VtEvdqk2iqbrek5Hfjin}f0!s1quKoRE0EXXNMWCR+9}dFcXLc@puh-
> wyXNUH8
> z?y&w=kemMgIndUp3)|BE{{G(s{q-
> ~3wxkMkO0X^4UukSef1!&_*Yg^Dq{?rU2X>q*
> z7s~@FOZYCNC;0X1Vf=dEDE!*J6V2tRu;j2rPc19q1nEa)HgF?Rd@`Sv@#FbCJ|5
> $9
> zOq@6ak!ZAS5j+S<zUV_bBRsAzMW`cEnV6HD;{aYLabZi5^XM5@z(O`K^<_Ya
> 03u1k
> z#B#^m6?XcN>H9pl-EdGGS8w6m=sIxKJ;^LfLs^VhMDKl85}Nl!pZ@giQs30J>-
> kET
> z3w|2Sj~oR=<wqG|{LyZkOy{k3zDkzdJsSmq+!r-8ryNE3f}2ya<gQICikr-ep;_f1
> z<}x>{i~<K@%ViWAP5scU(*Armt7IwQ(&Ith4c9AhFzNj;?CkI9UG@MUpf3{V<
> a8t)
> zAJ6A_(q87ZIr$U9>AE%QO=<QAf{eQEH7jnMxnX`NakcYd@aBXrmf4;zKcp9xK
> g6<t
> zB^3fMRePfd!xcB84!Wt1lp`r!dt-
> ySrbo46bk`P<g^f3gDX+m?@2Q<Vx*=VhTOccU
> z@%qIN9V}mjR3i#5cLF5NMf8b_XKh5+Y4~UNq$>{t#%(W`(R4|}jkBA3?iB6#C8
> T$D
> zlYkFV*LTVmfmq<hO*3{EVL&>gPp`XA2RO5qFLp6=D`u&$&JHCR+y!<}n%?hV
> L9Z^Z
> zr#l^XT5b{~ESBeDlVb`7HdNHh^*XqWw{CO%%+3NzXcgu&>un(#RhQ6V(s9EZ
> r(F@c
> ztm=x;t^6I!-v<8V&S1G1SpV7EflG=qSBE-JzasP_{-
> E_D?;lSg3HoE@ANSh~o3EqA
> zzkp`mXjYoZPdD}fnKH^Eh&O~<`@@fE4(0);&zQxb+-
> YR6tYg2N;(08XfoR>(TW?6_
> zc5e~4pDZO+HUo-
> =k?WJTX~>n61#&E{(iUOdn+BnW9rhUMFn!{MunlqK^|xbKf4fHI
> zPu()k?y-
> Ai2|LpDJCr5tNVe{PC2S`>jUo2wPp>^oS;Fmnp#)l<*`*=Hgz#nSsXJQ^
> z=1Ej!aLJRz8_Opi(x$qUw+>5u#U{!;#;i1?<kKXY){o2VwDUwAe||<|I$PYiBtbG
> |
> zRn`G#Lm{x0WK)!dyw#hugA(cp(!n=nJD43z3fby)$(tZpK6#g^Qsb|_$#%Y3abJ
> ME
> z{mjlxxPm3`uiWdAclNykALrlAe|*%V7#UEFb#oGFI?iLc4Xor(l#vs~;~>DL3pI0|
> z03&fUPMDN%{cvKs_IPnhF6ijlHFvRegoFqu`-
> E{UQPV34OYZX$E=!jixCCzU;<&d@
> zEl>M4%BzynK0asH?Q3NPzwfr)7%Yf;a^tRfk%&~A+nXC_p801%RM!x4g?YN*
> 9%)i=
> zAzENSCQ!kWhL(uZYb1w_pVhq5u4E|a342}ev;C>s#afo-
> WREEFjZ4r+hB1Y=r(6;G
> zm#J5TF66I~zZ3X-
> lD`mFju*?d<NPmoj`J^EY}H#k{~Lv6ih73|Q<y`ma*PBYKYdrO
> z+;cY$>t(a+2Uw=O>N8Z_DQ7niEIU?oLCb!}@|X(;&v5H}+bHDRU^ah5(ctR}0)n
> QS
> z&xnNTSVD^Zy<C4U_I@Y(F2kWk&}|k_2cY`LmDFDn|8Gf5&bgg-LeaJ#^TT-
> *awD9v
> zE)1-=lK4rT(3EpONlZC^-C&P1N%B`o#(}!gR4i6lH%X1oTFH-}qg`h-
> m?O8?#5*MM
> zj)KY>%rD%;xFlXHiS^wWYwQX|y<N>SZkCl~NzRc^v5#Cfq@vHexmJ*#E|*U^
> 1#)}3
> zQVP^G55zyRQC=b+Ev&NCE0?rJbEWqN!L*M{3`9J|FBrt;F1N|C(Ro@1e%Vr%
> ;h>3}
> z{q2MPx;VYc%CR4J35lkw3Xm!V*o0!(KdZodEO$e?TzV~#oSLqb$0pNl0Yz1k?T
> YxA
> zK`4}yFC1NtPv0nLkm$B&q|4>8(R|Iztz0F}^1{HmJ1MbIklkQXUIyW=Aqgp$cYP
> 9f
> z_`&8Kc^XrC@zyUGF~`ZSR3y}@8!$so6wib#pq<=FEsTk0jC0STSJ*UfS>w(Q-
> ySzp
> z);I1|ZrU^Kgaem|4&JiVc~l;XIU`aa>5VKnJ^`omB)yx{xsU8x*nIKRTEdz{OG+@j
> zzN}7YN4gQ5wBXnlZuMIDqN^6TE^m5@cYLq~o71)+h0UB`3mf76vtDMdW5#
> ApJ{bRi
> zdx9oj%g>_amszifp&r}95?$W_j2-*-
> 9`Ft%l(GHMWS;${Ys!?!U%1rk79O5V;yu+v
> zCnniWeBA5AFH!|)>Jc<u`58ge8H@o4wK;7kq_A1B#-
> d5mvqG1QbMgPj+`GU>SzP_&
> zn_CGG+<-
> w)5kbKlph2(&0S%W`ylk69R<Tv<h2l1)im;1V4J2%~X0vRiO5PXW+7@1I
> zYk$?2T2!=v0g(j6HXyCoqJ~Iy)=f24S|cL)f4^sDo_#h6cxivX&mTV7oqe8}IWuR
> @
> zIWu$4nKQhJy9hUNV<yEDnXp9ZB07(K=1S!QU@6pCVPW5p340%5?})mFNax
> hBSy&ye
> zat+aqfMiY(h(8O|porHta{U-I0K!u&A8?|E^$41P4w>#dAl!)wa28I_v|;(c>yV1%
> zx)GCvk4xpj-izRrdoa>)O_zF71LbjXm&Z=^Bz7Ds_IJRUf595CF9>MCZJZr2$}q(6
> z_sI<;sJ)oL*9$&^KR|meO0KBQ7>>O}$<sCI;YerJSYZ|Ft)=M^N%=`r=sZj#h)j=-
> z5;W3>#j1wWko?hRO>9U6+ULe#+QvOEFqmP+X%nkkn>dIZUa(EJ*;|U7aFk|
> #62``W
> zgRwE-a#oK1x`)vZ2y&k4>%z`F?UB|`fZtsg{9z1A)d*zZM5N^h#<5Qr5ljj^OZ(r$
> zHH5gt_5_E4N_9vLoP-CzC^$K}l`v9Yq-
> _EWh*(TeYV09X7<q^x&{89K5lG1nK@+Io
> zwMBs77^lWZ(o~tw94wk>WydW`T!cB*$c|<`)Di?h*e-
> an3(k$1a3DU$shtoIRzRgQ
> zYd9i7KCX1ZdDTdeJt9GxMS?U#ueOvDq*)|La}Niac2a^gi+2%s(`gBUg%%{p;#V
> 9A
> zB8PHBf;3wRGTcaz;8a&v>cO-
> wltGA$Q(4j#Ekx3pbyq}=6q~My9Kj8JkRyd6M+!xb
> zaA_cNq)C$%rX(##h6lAA3CghwBkhmRYym{cIJFdl%0Z@+S+_u>$*=EmA#*w
> 4Ino5y
> za7YtGSSbE<X#xt2?Dl;47f2Pk?hKcfwt*DK?Jnm+4$OcJSkVQ%g&N0n3&%B-
> !nwqR
> zb@7kqV;1|jWKMzSPT>+Gd72kgiKJ=Pk_XhGC66ITm*ko28pB;6an~4%<e36-
> YbS!B
> zlUZX>B+tCNH3m6`{}&`rVOsL&C4lfV<p+;TY9t!QA0QIM@cVd<UAJ>yaX7V5n5
> 54s
> zb~&m?<G4P6HZ<6Dq0Ci-gR_~)R!``u+v*Nsb}UvyA$Ki-Rp^|-
> 8OSb$Rq6L!)a4b}
> z;HR4HKowQ+-sp2kQCQ~-`{Fzz761j7eQ_QU3xJ-
> ^Bl0klIgi+a4M>`OaUv1y`^?J@
> z`_fbkS=TN{*M<g%=q{aXyYz;h$ZeO}*`+HW$DA(doVrUatSawvb!jrB95s)eU9
> mS2
> zZT}*8O&r$OlH)uBHZ6Ku=@3t(juaTU10DbK7wh=GbjSBW9nrPp4ZEe|>sug{v
> 3Tw`
> zZaa^1?X_Y=)CSag1!T>QrO*mw#B$_pi;q9*#f8NOT+oWuBnT-
> 7A3CST2Meq3E_UGq
> zK1CSVqE7nnV45wo(=74f!bPD>v4zpyu<l}cPc2tR2nw)dHL#*y+$fRI&cF;g$=9)
> 9
> zXmE~h<apc2b21xQ<XLnP=69?JtrrZy!KDypPCfPG5Fi#njBgJuT89Yz4&Jd|Btue
> ^
> z+90fgwGWyobjSgs+C#cBXxw&)HzCn0OOLEC#q;D0V3dzRwov=_M7BMi!IQ1
> LK7&Wc
> z<6X{CQ&>T=%T)F*8NFxOU*bk<Ke{X?v8ngl_5N8JF*7Y<`s+oI9X(9jV^k%?la*
> f;
> zI;S2z7FNGm<Pu&8Ie@Nw+j8KIpy^SvXru{-
> 5_^=mQ34y?&e86~@$!uKqR`lx?jg$p
> zUx^u)L)CU-v*AxJh>W}%-
> J`tP2L{WOS9EBSIZ@#oQc(3EuZky$yvo)K5{nLzSGPeT
> zImA3T$eh6;{GhN?tHUm0zENO9h~D@GB-
> DX4qaMKay(^;*`lG=>@{peOL2;YVA1;$Y
> zRJcSPBXPMMiK+ORwP+G&Sza(H2RqXzn4yB9j1*6?mR+s(>?1U4K=rTxpaG>r
> s&)~D
> zrwR@r-S_B~fW?-G!V(BO2U|L)#+Hb}1tAx<;BA4?fDR8!Xa*q>-
> a%~h&%~G5&|AKQ
> z7)VvBMjUhozn%dmo#Zb_%Yad~wP(0n3%<o_V{W`Zm;63(Kle6v*Mn1hkidn
> wynQge
> zdx<E-1i_Rka;FG#r@`<)aL*l+7SJyK=LS`VW!6-
> ~|332n=byGdMS5qyBxAK+`2Vv=
> zZ^Qo=S)}yWOA$MSklx_`J6-
> &*bLt_~{J+4({|kibDlFCA<Zv{GU?C1u7mN~zXNrX_
> zU5^*<fdI(Jpw0Ygx@Td~N8-v-NV>s0T>`+-
> Y`E4pi07Ee_Mg5?834B*Vf(&%(P6P5
> zY=0-
> @oI}VuXYe71?SFZPi;%Aqw*SAkI2rPy>AS3edRUwsZ#yzgFEwmOgd=|q3FUM
> |
> z=hPh$j%=Cl>c|7+$p0TLPEJR_Pq<Ef?#0P4i;wg5Qp4gy7AHS}407<Hb839Z;-
> vX@
> z7d|3j+Ap*$(E@?C#?LRFIprJi%*)EVif8Y3!O1hi^4l@xi#@N)luw_TE>r$F7AHf&
> z-mWc+O!;*ST`aG2YMcnmZ@5k4<TUgr)s5vX5A)RhRn7u{lAv4M1kU+(g&-
> MVkcKHB
> z-
> 9@e*AU6}UreaM#vgs%+Z|48AGWq?}r}+WF;>p7AC+jtgB@5yAdm+~xvd}q$
> gOOcN
> z^Ur+OMHaK23HS?cMm}Y#AKmz={BAl@u2&znBf{^SAex+x94}qg9T9$SpXchx
> eWY&}
> zzyCj{b?(ZJu@pIdTTiquT79a{#BSn>Gch!1rnjMXpwHLq4T~R{-
> hKj!=PYk^PK_U-
> z_2%#VhiH9ocUs4xlD$Wv^@%UIXkG8uaX)%D`|i>1BO@n-
> ;f$)*U_@a*PL*Kdgn!0R
> zb_QoHw33lJl@jnU9*I#q<J2^d<Q#vh<nQ^^bb8X&{AWR)n*q|)kCm8Qa4`zp
> jDQW*
> ztscBUR5G^erCkCA`b+4q&=ww$r@76ssTuw*u<hm=@gM?-
> N#utdoOTP}1BJ3gsLKcN
> z&~1o`#|MnLChN!!&yufWn^-
> QncpU>SjK0P~{puiM0QdHG@Gyg}rV3c$rG^J3-oz)2
> zYdN(57pdq640p!|Xb%((@Rt{8fCanHK?LnWVJu|Re#(0MvJ~wx=%3Rsi$OcSo
> >7-U
> zfBMWc&zv=^qBL^U`v;BX(2#sZmOA?asoG%3*!8)Az(EWc=v$!TnAET8aYP|VF
> ccCj
> zuxsvtqh)0B3Mf;=P2CTt5<ZIO)(Ivf$mXrt;>sK^SOL_vl&cLxIAA!`D9U6ys`QhR
> zMb$vpNEQrz3lx|Y#zBU3t)*(uCo<3sYymbm*L<Wd6k;83n*=B(q6d!QrE4x%|
> K*ex
> zQywvIx~mWR<JK})cKj$+ztatUKFMSK$c#_tO57}U!Fa(LE!eOQ!eF1uOXWa(bT
> >lV
> zfimBAyw2)2UPrsH&gDsH4nqg$|MODnO(q1_>N)7Y^+Lmnracn>2Ey49-
> 8yG*73Uxp
> zRu|k#bV|e&tqa298@ehSD}aTx*#q4SL)!tyL<?hFCJf{mrG5$l=fKc8H4KT1w`;D
> 2
> zkqRdef{s47P*$}FdS{&^<7q|#V_l~Dm&zkpW*7pAI!5Yl@gfK(4LO6dk0eAxwe
> poQ
> zFUcr9E^yaF<{#;bA$NKl48ea{!dE0)MP6~8j`ya%cB%k!`;dOo{5Xq<UEyK5NZ5o
> N
> zAKtxoYi~J9drs|M!nUV}`u{PsTkB2z@IRc{joyytFKz^Yi|n-49|u7+*?l=U_##>Q
> z4ATo4OLkECpR1OC+eH#OXD}DpHQ8;NV@V=8TrYfbLvUEq0TT;Ls4f(vC1+$=h
> T`;D
> z3`Z~FI6`&d6oB<qOt$b>>-C3)k38q90ylh}Q^RLrbx|6=%x;7X#eHE(xDvbY>;(g=
> zp+1E9hGtX=*vN)xr*;3%bj-+^x*;XDA%ij-BK#K#x)7mr>V~kedh!+r5sbG2Wn-
> k}
> zNX!Qd8fG2s6mk9_VF$}0^a(oeBY7ka8Pf|z0)bU1I6v5exdegk7%T_@9&&jO8
> FyVE
> zxGDUo4@m4HTuTO`$HY?v%zIKdljFmeS1b+|u{Y3I7L}<ZSi1|S!5o6OgX066zYI
> yg
> zB`YQgkOoC(>T+Fq_4a(sSGxYx0Q=07XP@y20z=P)(+)hkv=buwRzQR2fpien3=
> W2?
> z$*U(wFTuf>dV0M7s=BQh+hpfTjCO;gHIKmo98q%M64ggd|3L7g;`?affh`HgP5
> M-v
> zp!&Y5aoA5X@5gEPMxY}W<z<tx#7=(JH}UhwTlx8913x!zz~|iM^-
> 8`H`{e7#JWo7#
> zd32q8{cNp#J^mQJ9=b2ug0IHtFnq$v5ID+>)$hfRgfBN1J-
> ~!NH(qu)R?m5@0*Aa3
> z(Pk_NO4U8Tm&IG7{DdE1N!*_sOYFnDL_KrBP@a%#q3`Emp?UD<N%#-
> Kp(cnF{K8T%
> zk`mf+NyYGg9_bQ16LXN3AA%{ZEJMh8D$Dav4;1v>5fiL*TYr>U)mnxo9ZKTtR0
> ^3#
> z`SN#Bf#%Yu+IZYjP%Jw4K*f46dkJm(IiVA9xU=6rkd_$7^J4><PTjRe9>F8!c5OO
> n
> z2WyD7mFh4cu|0k2E%#!P1rvj-
> wJcf*c604SJ2*XgzU5*;oilh3Wf2Rj^KaB8=u?{R
> zvET=-ez^Tta%HXjUSob({K5a~DDh;6n|U+13=Iz6$VO(X4l~&rHx-D7v1$$^k)1lz
> znS&EhLPwQ-
> ;G4F2$=?ADR!D*?DVvB7kxj&qE2=C41?dQvQ5XEhneZ`nk5vaCfE@Tv
> zW({9r%O0PGKaLWLA!U1x9;=;ZE=Jf{e@ElgTnLDzh=+#wF0Ih3#!7MU<5<yU5
> xMSg
> zau-@l4)reo1^WYC-
> L!uv$n2#*Bkr)$Z;~LhxUdaDj&q@LwGHav&Etq#3qaY3MLKRf
> zu6hIDn18E0!nzklVp-HGc3>r<{`H8dkS<szYV9zpV;IL}ZfwToI4s-2SZ>_{*9!gg
> z9ItkDxexJh!T(MSN%7|B00O^YyjrR8>qo7T9yic}ezAD9^wPBieI^(yli9|q2X1l^
> zl#@AFPy&LMc(q%u(}fWJ>K!3yw;lKx@oJld(}Tyk;Qzu*<A$N2a~Z3Scf)rwYxt}}
> zO-sYCAVK@-x{`UDO0e)&49STQv#ueT{rS~y3|MPa5en{n>3zDkimZB4WIPC-
> A#24*
> z+C{;PDcgy6YT{jTnPBn%3$uDK{fDaNTy;FenN>vuoy@xb67O=_H!S{B-
> zBfzGe;Ee
> zH&}%`F1h3#Qq;CzE(Q#6OAo4c#;m1zL%-
> GA!?d0q_7<aL|J^$2WLmQ74UmzqU4vEr
> z$KusabfKy0<_t0wGHJWPMW#;X;An?TPyV_^Q}PU>i|^*g&`(~t>9>o*&>gSV
> (62Zi
> znF---
> (5j1nFn(jzRqlp4nRUa2ewSVAG>oU>KwuKDmM03;2`GH*c(o+#5?MZ)SfEFA
> z<eaWF;KZ!O8V|NB$iW_TuRX=AO%r*cqjmkw6G8*(&g;>1i7ESCq$pa&7a#G$
> J*ivN
> zwS3k+*shIQ%a(s1LQ%6M?Ou*KOgISstrEC)fCD6-
> 6(V+jAw%um1RyfCB>oCaeSTj4
> z6t&{c-==wavF7D2Iz?XbtQ{Vl@YCYRV`$;8W}Y>?47K7|bty!Z!^=))O$)-yi>`5K
> zp&Gs7VVrxqj^t<JW`?hIb2HE6_QcJ9TWh<S5x|x+3VjLEJ7&Y*J;tvs)`B%dhjon
> k
> zaqT@A`Q`tzBhNwnH{-cWjTauZ#-q-
> U*gprm?Vr_A&c{F{#CW5>gB;<`0^GS+lD+jn
> zC4Vji*)85^7dII>M4cIL^t|AWkWyGrK1xbY2grr9-
> $XSd4X(EX4x43ND0n618)HbS
> zNdbp+hM*;o*GG?Y*i*dGV%v(-
> GFyS&|3tM3GRky1B1v`{t<Z&ZD<t0Ile3&w{1>ud
> z|52{?|6R`aIvd_&H4G;Sse#5xZ)!!MfliHA{T+xl+UIU44NSDp3vIK%W0nEJZ(a3A
> zsPY@{N-MDY#OAf@?$hp{t_Ipl)e5;zRD$hZFN(kc@qRig-
> w$ipFdQ5x!t?C#S!?v;
> znKKYcGjtMkt^r*%-j3nCOs6Nc!?mAyn5ci_G{!1y>7f0_f?t&GDJM!7r`b|946_b;
> z4@~qBxDydyaz*eFRX8#Iri^<oMFsTZPRtd}f0a=A4-
> Jl(DtoHpV1uT!60>3uQ~`=8
> z-
> $g}x1>jS=us=Uk0@VQyL{CF|=8N_K&euBUhaW=>L*HIXdCepBGR}?D<eU&*
> 7!5#%
> zIMDl3@LTQY<+te&iH7v@C29HXnJ>z3GlH{;kZd&p4Aqt2_FV0Ndr*>w(siNW4
> 3yOT
> z_M&JiMbmoT7vVRbZN(EHZ&xdX-
> @ck|#qsV|=t8;`!f#q%Dy{gX9*1&u2bSR=pU=i`
> znE`hhg%x%W^4-
> PiK~R<nTDVD)9BIpfu7JCxwkK+~t0!GpkaWFQH|%IEXf)}r_2l{$
> zlOblO9yrqJ=!7;nC!!AM=4i8(kG{d&OUr?}fArzrkE$+-;M!v3ZNW6*gZZ|-
> 6Wr~U
> zJQLL(2rxr#4@&X`fPtjbg@WxIf7YX3{F)=_mH`~-
> z6W`mj@|k(;?jK_`6wHArfv#+
> z966K~zMTs(9r{`9F^v7JL$*S9XDIZ)%zD5qB7`>1Pq*;HtJql6LS0C=P=d9doo-<Z
> zs2JSbLj+JA=dpDdL$#or>_@4(9r0#(l9{4-
> 9AX=Snjo&`9HWNn)+*pBG*vxP%(F+b
> zc9=O2F%0g4XYNXv9}YmV0<C{f5={rvd;~JlI3##$8e}1kgR%w07Q>DF8c#Y0u9i$
> &
> z8-3!sZdJH+l5NJh#8G<b9H~TJQ!Yw%Fnsb6@(+#qsE@Q|ZO?-
> hxu?$rn71BBM|#e{
> zXm8_7RavFM2oIW2l6Znopo|@}Rx=T6>DnXG>t<z*uMMn2yAXiV|76d2ZJd!c
> 0o6iK
> zB?9Zp6TXI0^^0q12`J!QOL=mQWAbS>7LnIBA)d-
> J_n3BhYdB4z_EB6?7mjK|Jj6w3
> zQl2;KdcNtd=WDX*XqMoU&8aJTZVZanF=F8Oo-
> xxnqt66R1lSb{Egw#Pgr5=}(BF)!
> zo*K$k3LX(o+i^u4+b4OOQ{y#nWLe(G4xfgX;&$tAKuEI&*ennWcO^Wo*P^rH
> fQv2*
> zVMKXn3<<X)FX3B<Lw*T=gBWMF;uPbRLM~JmK`tb@;7)x5Dp_3Vi?Fb0);buS
> dSY80
> zLh~U#OXHd>QdSNxP=i8s=cGVWWnS_`R(70?u6Z!o8^0MSIy4W&iL_^%Z(YC
> 74Qn_~
> zjZE^h{%43y>@T3A=V>Z~RyV}|Mvi0xAKkEbxA$pMOYf_Q@m%lIO~m1(9bs
> N(pdH6k
> zeVvx4%B9(tnr2G`ySXuqcigXBZtB1|_!}l|M(j}8R)}wUn~YzZyRy7w2%CZAKH3j
> @
> zWcG~UwBJEC6Y|y$CwIt=(Z^Dq)Y~ETs7cYzAdlk-
> zO<~~7ugf_Yw;vj&#ZANkVx>!
> zsLfM4aX-Vt@5Sq-2m`PcE}R#aYQT7jU$B6@Bbp`Q-
> 4x|h28+a4;LsNQI@{t>^|tJO
> zx_0(jz{C>-Sy#^zh;}T`oR`TvpzdR|*7h=8J`t5hfd!>?P*U|IkK;vIAY4Ow!!Teu
> zzIH0~1(fdTs2vmi?UmW70hx$@^9T?>NJO9S<48xgH#!~2!9G8hSosR(iReT4Bv
> Rw`
> z{5?w0;f;`x6VcUp5|bS91oI{8`DE0N>W_{9h2BVn<)Tu~2e*jAh2gl=D&Dd6tB_Z}
> zC3#6U@6!oBWyDy-
> 4Fw&;SH5jMj@NoL03MyGCnUa+L|nknjZ3+?xJWefbrQNU;u9x%
> zGn-hZTYt>S#ldIba1N~vhc&Q7LVCG*qOS*h{)zbH@|KpZ`aL-
> Q)fnA}PeCE6k&ogD
> zep+gL5V;$pq33m`M12e1#p+ooE=3awJ^@`m`Xx=5QrMwO{t~H|*vldUQ_#Z
> ~-lwB{
> zO3FM%hnbX$8Cg^67R(E%1V87->zSR05HnvJy2PXvz-
> S~Ai_zLL(>!VLs4WkU+On&o
> zG!bQE(~(+5m`dj&8>Nfk;~gQA{3)=Ktj9-
> VbiV1nrG4fdRnMp8ae0|oo~MC+Is>5b
> zEJz-Zgqz}zizit1qy%#;{b9UbehHu@+0gLI_+SPE_ap-
> t%hctjMQP7~9=2C{F=FV&
> zYlM?ns1B#MX)t`jrV-^V3$qu_vf(oi;eKzuoa-
> ^HwV>ZXk{&_%DOhgdS~Phk#tu=%
> zuuZ!fab0?xc1$$c67KA<@Il<^lfqv@=#P=9lU0FKJ%m+{l_XN4AIfLMO_=K1;{F
> XV
> z4(7h9jf1lP!+z`0&%57x`7-u_|I{i;vO83`Jp<y#uD9!bDxa?3m=>JCg?F}Ux{^3>
> zVrYndV@?{}*$z0&=DJYuER@vyt#8cGh0&5PwBMR;TQM!O6|$y&9iwA9{jen
> 2X|zHY
> z(yfsF)}N+3t@tIfK!%sAtk-1S^>6RD&UPTHuR87NVZZfN+mpptxbWG-ek-
> UO_SyGa
> zkv5)4DpmJkP(iHv=vim@0`-
> GSEn&+|E35QIYMyP#d!Welz+!}|i5pzTi~WQgChWkR
> z_NXkzXt3`LyOtkt#Gv<?W+XTe94u9ZK2|5ZGU*trh{*m=y3V2Lh|S=MwDK}--
> <`E)
> z$YfZjeQl1noE-Qu7XXvIu?thvWuG`BSj$AVD$M8}9Vmtd=jl8?o2L!Ln??Z-Njeu`
> zU1IYzx${^SAI4=_fvltoQt#ktUH{s^)~d>_H-#qPb3rH{pLd1^r4SlK5EaKpw+a4x
> zZOK(Y8y;q1&gWWXJI<xGB{@^$A=jgvcXx2!P2F+SkT=!`s95*sX4}>w?zT#lfibE
> U
> z<Kk>Lb<W@rlnb)3dbUI`fZ!s}z*7V+C1?SNz;sP_mpi$yV86l5wzmec{+I!KvzUK
> F
> z99QDJGfZEMGs}B#J=^cwfZ$ZQ3m9rB(R{~rPx4>VtAo7T3(B(=0Pv*F1kFU6a2
> SW~
> zpK=KYP6M}9@2J8{Sv$AkLVKc%0t{KI_j?+!Rdvc!K3DJXAUk|8k}C!7!I53_pxky(
> z2~Eidlk<^>@p{sA91n8BLt-
> 3NF<YQ5d0Dq?18g>5+sMx6ur@%ePM2H=A>uR$J{Dqj
> zVt2L=BS5Y>B+N+nJb{Ce9k8(+OwtMhOpN3uT<N;7|6{}PjP=NF5hYqn(mCJ{3i
> Oo#
> zeL_!?zY29R|GoGIYp`b)+jr`-1nc>XjtcAX4Y=!VsI=ii3|L)k$8$?ef4n4vIphTN
> zBuG+AOzF%ndaAg{($lv=;K?UG!OzNekWG+e69CyDraQR@7FjOS!95i@cwQd
> dL;cJo
> z*|`)zZ*iw4{&lv=>!iv4b=L38X)=9YZIg#&HW|Jh#j19itI1AgSCgNfVw?OF+eq5a
> zfos-LSzYG%DYk)YZ3EZp2Cj`^uS=&*r-
> ARd8hEz|NoO)ewqo`6R96F?%&rEW;52Zc
> zZ6GAcQ5sm07u*X>qV<Re?3dj;!rh(-
> 6i2q?$$|WXSV87OnjTE<LCY%ggDp1y#xD8w
> z0e<Gsmi&(}f3IMh&7W}c!=W1W_j2mbV*b>f+64EQMbTq|qQGM~5Gq#(I4H
> _O4m*ak
> z&62@r&vp_;TOp+!vU4)KQ1rnhJBIHA#<7OZxooKkBXkfw0o8LqYQev1)(QqZb
> P!{d
> z&kf$mtiiJi6|&${i-J|C4Eh`F6c18SQJSE>|APx53$_-4t{D}stcxcf91byS(=R5_
> z7AwPS?z%eNs_NnJV^sBc$rUAlAphZ58IC!M6A5DJeQVxyPX+#7{qA(nFY(uez
> nkzk
> z1%FZe{Q~dW@iz$Ro%l}T+f(5D%gT0=nTZ_dXD(8CU+U%jW+K0L`ez?W_BC2z
> yPj?8
> zww`T2ioMQAEEr{mVYh|#gjt}OnV*jEaGeDC!ya_NI>JMR2HA4J<p}?r;O9UOj
> _^@#
> zdTeIxqK-2RRoE^^>3D@1B74bDd=^zAKruiSma0o~r6pjaykvhF-
> E_s+z`{u~^miI$
> zane+`!B)#z9f7FOR_j&|ih$?n-*on5F*e62@3b=JYe`a!B!7;Nife-fGq{qen4k{I
> zyk6+!jls3w)*6{y?FlUkuJ&ehE3$bQ_#YZOG>hS`sYi4gSEjBK^M%vk#@rQv=t+I
> q
> zfq=sUk%nQgdKF^<=zfYe!n3<^YJn8UOU}b4jSGX&G`NG)`IWdt4sm{MX|!i35
> YJAN
> zFUkUiY%5-BI%X8SLZG6%WB+v;^H>W5Xm|79P7qOi)`-
> IRj1figD@P0tl$Vy31xv%z
> zJ##v7jKVslZjH?tkv}IkQozm_Q5>J0kKCijofw~A5IJ%rGzoQ#j~qG@%ANH7qH`
> 1D
> z7bULyU17X$3?{X^b3NgmK}wwX^nA7Z%4`qUBl6<_ex%mUxev=GlE>h0-
> tdj*QEl#r
> zQ*%MN9+_)H<IptN=JLlisbM(l8Hfi5cg`>9oL|^Ezer)K1l1H=FL}_7SoV6%nV#nZ
> zs3t#tcIO>KI`0_VdB<65pvkx;*Auw<nycdPjB6P8*KxbY{cBuj=dN#j^9CH8e<%
> Kr
> z_-1g;d1#fq-H!L2oo@x=jFd@LYw$zh1%Ca3To0OhJ)q1RkzZcc85&Wf;2k6_*^-
> |b
> zVZ{0aI84~V&XNgD{3slU98q~4BvEAYOY7k8n-
> %s$CVgl3;OZ?^2$zO@v7#5&G7_{n
> zKtLC32(=@g`zJmxRWo0;L^=TVH0Hj<$NUFD*(+5qc(j`W(;lAJVGcIL=vc8q8BzH)
> zLYb^9z>TZWc~1V5v<l;ZokfAP1m}q8N7y-
> VEhrmofoluY44CW4zy8B6_^JO*gR$yU
> z0mI57lch3GXoQBTI}elbVbd|avV|uw!K60n9$0y(K94*k!9}KwpK`g!gBziL`2s}4
> zQ1w2(ARQ&nzk2dvHXm`h^POh(5xhwR+~6S85S*-
> K$zb)UEJ1K$LB|ywpl+SW$(8(!
> zT>yh`!C(7f!gPc$wsRJ(;Y+NfDOW#u#g5!*#3KaTVR0ltymF^Xy8@Ny&2XeElF>
> ;W
> zX9~Qi3jooeK<7kHA9ag{e^kbI&o8cS^U^L@zv_jYVf_mCspzj7f1<GiySSk_E!A
> M^
> zmhnJ&LmC*Z@ffYN4cxxRmbi1^I=s^O_WiHaXyR2=x6yUOv2}JBs!2rK(G2*P<
> FhfU
> z@QFS_)7EBE@dV$L1sUMKbKrVZ9+P*~8<`^)PnRsL7$2Oc#|?T{K8DJ>TzyIJY<
> 1O<
> zjjV>(R{iuVb{x|{QhhXN)aHpu#SCsNZGu8pYQ&x2Zt$k{HuKr>de-
> lKikG5Yh%*S%
> zYVT99T)lCbSQ#P;+mOSlzUov5eq^I`H`E`atYN9va-xjx#b9!1yawO^sO4%in0CJp
> z{a60zuIJ~D;op-bG0{$1@;&v^mx%#PgrH>ZmG-jR-
> 0$qgH$)JwLa;mMLZ4_0z8hRC
> z_*Jc-SeGUM`lV6ot5O}c-
> ;kd=XYe6p53;bT8mmh{H#o1Nm%4*H9fxCZ>lwUDOKN>B
> z+kE>k+~#YANudRJ-hg4oA`opmz$V$y-
> ldAdT8bY4A9S4vd#S5*?VqL;GV*aW?!Pq}
> z5>Y<z^pFV;shQr<mXrqPUn<&?)(IK?NA$IG)mJYdI*p-
> P=L}wl?4oK>Ram_cV^AFV
> zF-_~eoxKvd1&Wkn*6gV$vmlmcf`B6NT$LK{0-
> <wi5G<@tNrQL?Go$Oe9XpIg8b-N=
> zadIXM4CA@#UN;P#Q^R0k^~`xrH@*)TSh)ktM7SWp{B4gqbzCAnxynL$5|r*D
> 7CGuP
> z+zmzN)KFMhU6qD1OhbwH$5z;)YY))Xtbxq3KuR-#U@v>F+5jqXMnvb-Kv-
> D4d#=-!
> z-(#bwet_I`<!o0qQjQeYE!5zH$SH@67_h3-
> 8;u~7nnh}ykR86O;yl?%ju2MoLh@FO
> z=(nVa8gM)L=mh-#R&WE8*}-
> +fSqa2VRgX)Qhru{6x|!?aVO)rcMr1g`XzJ_;d{0rQ
> z&et1b%$n5AW1-
> C}OC+Mt;b0DvI8}qm74~wU>}er#M4exAzvRQE==ss@Fro7oHTTOf
> z2XIRCA56^3!Z{sSW807?^3iqSQ5Dxo7VlK{Jb$9EEp$R~PZsE!EfHO2XbfK!;IOqH
> zrJ&M3FLVJ`P<6nKtM66lX_tbNbiq<}{$qrXC^HAk)W25hwzN~vp_KlW(_Vdq@
> D_d<
> z6|c;!cm^tl9->q?h*i8fS{j7-y}y!rQ+de;IZ(fX5Yj5}wD&v_1qF8l-lqpPJXbBH
> zz?zU9x&i&C!uD&I5|ilv!O-
> y>XMmaPJPLm~9zGb^mL<57S!bAj2gkTm%&YULglfnt
> zRe8><Y&7gj%ol2a0K+BoDjz8<-
> r;0SqYEc~j?Zq<=i?c4XtEekrD~IYh83B0h%@qR
> z0+4~YZANHz^AQ>zEV!Hu8r(-
> TK6)9+Q1u5tx_A`QW~{1&JhAMP&Kz8c5>kbFY?Q-6
> z*Hfm6n$upky$=e5`K;U%6g83o^eA~HZ6ATi8LNuifSk-
> 45UWtr(|`_AvOz$b=yY1<
> z3=e9_7JS{+rHe8lLF|lG{|AD_>5`LKLlXJ+>N!rA>L_^_auJt2NhG{IjQ@#VY55j>
> z!v$;i`5C=Jwz29WH!LT!h9y$&yJ=WMHLQ3xn9d@w8KAV33%0mG-
> I@ssI<c|pWr#AT
> zTTW&TN@QJj8r1I~!AR2WrE2mNVQB~l5_Ef+8f71d&$l;9jhD!cXcJNuxSp}STw
> O9l
> z7{Q8^=;L@L)lK=KFs|qWcLs5U5zA<yE=Hx^S*9wr^4x|L6gT>jY>g-
> QFJ>l%=r*gF
> zNVVVtt|-
> s}ps8#68;;I@R5%)CKFln$g4x9oV~V_fmMQY5Uq})3P=~ck!LbzwDzTl%
> zMaG90!L-<h&LDax*Af-
> yVuw<uhEF!AQNnZQ!^p$FAKJjGDA^Ih!A7KR7sZvj0pdwZ
> z5FH4g2t8+oK}jCYa|K5tM;ax8rgBwrvCxgdC2su2@?ZdRp?haBa~dVH***FNz^
> O+h
> z`+d-NL+F;OfBjr{k7#=KK7p4*S3#vVjD{@XnOxXPKw#VeLNU&mfii7)msjB-
> K#j=+
> z)q#l~vMOE>ZT<~z`NAQfQH({_G-
> ?Z=t1>mvLcT{sCT=j*ye_9dMSY^C5i*YS0>}20
> z5|67x&Q1VGjU~uFoWbto)&>_OwZr<x6|cV?hj_Hy1HS)ao@$kyk#9w=1)2@
> XrbQY&
> z7>$^jYE}?NFWJuJz~hi2mP<^|;8_rbTA00YhQs-
> r(MH$mNgse1YGh2s9TvuGW&vSf
> z;Pk^Nb(tH6&Z%LDbh+Dsk-
> Cwzn!wIFfyssEmwA|9og>pV6y9)tqZu8SKX>3Q=O}X!
> zUzL#ic!C~?<0SO7DDm?-
> QFN56U+Q1nICQ;z&G>&;x19xAc({EcOoaW~_&HGV^OOVp
> zyr6}jQ}*F=?(%{87xJs$Vfl5+Uir$~BVQw%<!j7Nd_4rM4synQo`(<OXWW<ja0k
> 8<
> zIEk9e=g}7UOEu<|;294Tui?vw4^F@ZHhBu4y>mScjd^WIfet<KekH%e<qe6w
> D1!@|
> zn6Bp$;?993*bO{90cD}M**sgUxAqiqa5BbGA0v)TVHQlK$n_(gD@X{P1LvSTRC
> G7u
> z%cWm{J=kpG)*Jx2BSVAUb(|HM(t-
> z_p;P1in1C9Z8K4SbhR$Xav^0E9a29~8uL)tp
> zo-Di-
> 8W5a;r(8MM>jDnLO9IN2A9kRZ5+Im|x~cNU#e)dr%YAj1ArpG%`DN5`4`3QG
> zq3>!$W!Sqvm>|`fTMH#WPJE64w(u~$F?a9(|5N?_rUsJk@BE|m_weWIZ|A_
> R=<4-Q
> z-Z}b)(s(~&9vec9d3kB~ziT))x~m#r?qRfo^|W}uLfFL1)JN0`$eoXrSvG4EAojpA
> zQXf~AM0I>%5o#z`PwN^wo3HPx{?qN1`|U^&7dfCf-
> GmDij)+iav=3jwJ%TKI+ug$j
> zs5;ohXPA66!92_c2RHB;T56uL3Bh%lWe4L~WD09QV4=tq7Q>~KktxgzD`{j3Gk
> C(I
> z8}pdw#uzWSA|7LclK4P&J|>-
> 8(~RW9%&rIFVPZWpg`b@W0jW{wZ~@C<BIHdQG{mb-
> zD>^&Z5Cq~afnR}T>6XR(edZb4XK{JAdB&!$A>2|GG>`a8{puaYvIOerdki>h@D
> *(N
> z0ee6|m|yiqzq9#aQh{OEaBsCt@~1+<IwHFY2*Xy3u_GW9{-
> t+{hJC@^kefn8ATu_k
> zOzqKa=)^4=sO!tRuCppI5RkC67h|I89Jmwx2SZDEY$)!*4xQ@(%@sgi=*LQt;T8
> sa
> zR;K1#7>#)%Wynni(}Nrob37XJ1pj!iMgtvgrq=v^BzRUg{m;?jV`)+K2oARh6Ckn
> $
> zPO`{#Um)?usYPtRSpAE&_(CijO?h}7tES`%3Y%v>Cx>HlZ=6P_0Webjwkoa{r=!
> re
> z>MQVUy1WhY`p}AgDx4DVM(R@T%?yI*d1WY`fomMiW<M3vd7rN+P!~DH1
> Pb(%*yc=|
> z2OyEV=6PTv59F^|ydKkqJd2mjD_4Do$}G{P)&e!o)QZ){oESA$o@=4x?<#&Be
> zq=v
> zhxHJumB3$G{x8J}3TA|^WcHlwsBmDFngUPgT96842*<j74auxjefN;yfn*jM3F
> <-y
> zb+!l%OI<hzN{u@X8v$TvY9Ob4WZHTW3nGA!*cY^T*h6Z}JRYyxkNYN3)(XNt6
> @}_=
> zwF0-hz_avJ+Krx$c7GTK&ji-@*3fQ^z}k_!MtDS(i3^*ijVM)vbYtbs==7V>rRozg
> z)MLqqGUL;4aQfg)*PF@dH<L@%cGsJd^qZ1W^&8il8R<7Oa6hN(&CK+hnWg
> G(=S}rp
> z!Uaylae>_p`XvZ<tI8l)|Gs!x5V4@djyDp<HcZd8KtH6#pz6vNxg?jHbbm{kI#E~
> B
> zg#!Dj-|8w!*K?iPHC+R3^NhJ6G#-m++@B4NIrtSO$w>oA;h|HiD-
> W!G8i^v<5h4>X
> zxk$drgL@|T85S7Ui2KS_bh407H{$1%oAED0ewB&i*x7c<G>fDYkG3|-ukcubr-
> ka$
> z4+V+1xs=<0AAW*gM&2EVtdwy;Bj=Q~gcJB$(8@#ed#}wTzwLcN4B}&~TNDZ
> Omcj1h
> zFr#tO;ZHPPi23pt7uoCnwN2($F5z!e*S&?^6VF!-
> G6ClJ@XWWNdiU*1_5zDjmy!=<
> zz~*!y@s(Fl#eo~li<yA`=V|Pw<FcYW;VEkTsjiKO&KWF1_8<$ZxhF{psNKP*O9
> ^rv
> z+JQ)6;-
> }@>>sV#<VNPefsoa1JWP*e;dWzaS)CE%K)F4?{eQ=@yxyOQ>Dj@eHhl2*6
> z<wLn@MqCG|oNmz|FSa0ChiCK>>Y^#?t8S1wrv}Nws>*_FwjlrTH}<kQ`D=(@
> _WE7^
> zF3pX65B`Z~rFYk6-
> _s&m2kd)xGVlFTb|+)AwW%lhV<tip<zgdVh{YPOc3@<*{L)|+
> z_NvVDLz}0doIjW0XQ>)}5%*HVtZXd8@etd%u>zne1qRdC+iYdAljZ4FJ5dPzKy
> W)i
> zLD-Lyu(uYb=~dR-BB<>};xvImWnR;Oj$<74e;oQhjJp*1%bw|xjfB<-
> @Ei<i>@lG+
> zs#CD>J6CUU?KVXAiwjtu8bj_IE3gGWj7zA~bwWZN55YtmZk4G1sc=Y5q0cy`m
> 426q
> zVkg>Ad9qAdoNl<{3FxeLx*?Zgn{zmc39b_{3DTPu!%t_CNz&J3h@T(LN(!9-
> vXs?Y
> z4-Iy(Kb{IF9&P;846=e|yI6gAvWt>UJlYmA4-2ca2T2Ki>lSBW(F{g^Pe_6MZRilg
> z!Cz+Mgp}ZC)*|ex3lQ?DYanh$qm?-
> EILSx*Y>>yUv@F4W>hq~tDR8L;tm=W`WYGy7
> zVHOf#8~DH_0ib#)R_D7rVPerrCnOf_oD*D~xL2l8Xl)LoF%t6zHo(HV{<RXHeG
> _Gx
> z9GHSehA}R5e0JE2ZG86Z)Jq&aZ}g8}1P6>5VQ|pGnJohc58W;}=yJ;f_cLNPq&}
> G|
> z0C?!~UOI@4u3>0@bxH<mkY|h<1o3C%MO2tDw1OH5LwgyVIe^UdrxC{OG
> MKm8!Mp*(
> zI7(bAc*_F$eiX2<8Q0Zxzh!|@Xfxi!T*Y9FrhhC6dP&Ua1O5Dyx9OpFleWx@n
> %|EE
> z7k6799WDN)(ZOrk4m+iwh$5Y{NQ1p=c4)BnV+mLp49>n%W|3t>G7tqN@44#
> T!7fJ7
> zIfGXsyA)Q#igXDm5F3E2L;#koJ&0~0yt)Thy)j~20GdGRbh*yv7iHIh(uxu-GV`H}
> z+KY*BUzutpCv6=9@1=~D3)TSpJfX{F;WGh2eC4d|-bl--
> n_IpVFR0gn0%m39Mp_Y5
> zYOkCX-
> W%C}>gN4liswf8wsuxNj7)pW)Ndb`r3zw@wm?*<0q7fCoFwWABbp(UM-
> MA=
> zi~m*K@PFXg{&B?kV2yEY3LPFC?I+g;9|9IE())o)U5pFU#5i>q<crlArZWc%QCg}
> {
> zj}FiTO1p3J0rGBOaAP(kBSfP!%+^YwhdKBY7tmFD_IJgB9H(;KK%LAQD63H8+(5
> C%
> z@kA<zctW>B*;?JY^hjr?<F&a5HiY#gDNk^X3+U;YKw+*Jr|yFga(e1y)<9W>+S
> K3G
> zQyvU4M5IHcSv9Y@RtZ-u(S)yPb`wGZ<+-+Y-
> ;i;iC0orBU@V?3#4<SEKhk>Y=2lBC
> za*z`4?oJNm9FUQt_R2yK6v~yW8-8U;ieBru<f+laVE~2qNK96LRNb~-
> `obM64z#|9
> zZnZNBPN9>J^@i{jjjY1YP(Q=O+kBmcslNCD?4wvGQOpTWh$&d~HPA=fS7%~
> kZ7NeU
> zN;$FSmZ~d6JwI5+$%E>`un888^px}h58#ArXZ3bG^wj!0Qzum8JTHEP`r*)Mr*`
> zO
> z4WKiKwF!6Ym7(Jzl`FGCMfl7PeK}R4C+Di<7L<oJnZYe^iWTJG@t|@zP;dnT4>6
> r6
> zN&XLhnup@Vq#7VUjA;~cHU)Fq9eD*i$bu{I4eDMI3xKd2Xb4+}4x-
> y$<gh%nUC+ms
> zoRMvux<IPdjuGk18b_=`&GEV@>q+d#F`_a5@_1l*<Q<5y<&nze^Y8p-
> +_xMjB_{t$
> zPD+fxmswFHo24(Z%t&t4X^1aRQje>m<s<nRKB_S-
> dOTH(L72HF(HPityn}&2fn{N$
> zuGV6p7RAxFTAbvFRBj*!LK*|-yD-qGCv%GdWE-c(N!11ePG*e(R-
> tY_&V_;Bf$oGZ
> zdO=a_tEsN6fdjf{=~qmG7k$;h#oV*>B$Egsf=i7jG>$*f641jOCeiWG*HYIq39rl
> 0
> zXeQum89I*%)EzpB=WUt=Kbz1qqyYz~5OkWo7S~!lr`M*TnP$N)9pBV)h#^B
> W{({CV
> z5qfe9LzTr?6|$i(RWaZCNacDL&CGIPtX|LY7GubU`~ReBgE1$wi)M=ZxiD6ZiyJZ
> 3
> z5}GD@Vqx%_VeqN^u=#Y~kdb`D=-
> CI@FyW7q&@k+$agYVx{j%Qc0Nv3KACBb;k!P{P
> z(^X*ufg7)U2l^4U;z$kd8Wuw6DP0;~{|C5D0Am)0xDUrs6px1yqt%8VGkR(Pbv
> Ol)
> z37s$xeH}8i3&zw5@@y~)slG_YF#vtokNn1LwpP#4IG+z|(H^Yp6&5<sBw>ToI
> dC6#
> z!kD8WOyP<`yCIhLBT=RSc3e+`H@XI2(%UR=4G*qjIbYq1VOolH<!7un%vDxgh
> qNe&
> zXWO|xkvZ3!9LR|nwt6)nIS@@DS8LBo)li}FTy;hvI!Qm9WMgkgmj77&n}i~A)iy
> {I
> zUH`49U#n+|1W~e~@<zW8Of>q|;S<Oyi1(LO40>QzD*Ak#Ij4HW$$^}`Gji0<=
> wtd8
> z^R0^`E`yq^TR_E+j(-%XTnELZ8jlt=dZ=eqXFHACk<V%SV0IXXe0-faorIHTsX{!-
> z3HRY#5ZR8f8C(=$%+a_qHS{N(-
> =N3{bVhb$$z*V}fvF3067xqNIRxhzQPo=IWaw$&
> zMhK+VncgVHCL1}jiiw&eK830ffA}?|;d766f;dXm|7;^y!uw<^V~vK-
> Q{Tp*S5Jr_
> z7yMv|>~gi}N#@BFdWeI3+mp{h7$qM-
> o^8HALPMYM|B?1i*7tP@Hi!dG;fsNjKSn+}
> z37$5-
> tq+!$nhbY|IaH#B*!oW}^^+cS{oh3WvN6^T_~#25jXcHR_w{wUUEgOpq0ci>
> z&eiWpkb>wp&embV4xbqhG+}yW5_fPF_4AZaJQSt8u+Zx)eGxy}Z)Ra;gXf4|b
> dH7y
> zwG-wlaD%hxbZU<!?g5)tZ{#PB6D>VIoyIkD`Z)lGO6>D2Pv}DX9O-jYe)}ui6Z(qH
> zmFo$Owa<|rnL3jzp44y=bv$EPeTbjoTs+QB^^s4e5ik?$6igc4nhP*TH2NOJXyJ
> >~
> zD!v}!mk{m#5^wZH3L;7xJZy;7FP5J06TeGBW2!frbX91elWy?VyoA?D-
> o%3X@aaj)
> ztwX-%STuyPI0%nV-a)1l8~HQWd++_oiDU8j(K(`iEmj3K#E<Yy-G7m13S-
> fEcps~u
> zkI#5L(|si!5`7CLq2#{K=AI+DgOZ!+)9aaz9O?{PV)^Y8npm#wYl-
> C$@WN%19N$V(
> z$V0gmi{8je68x05OJXBG(f0q9w(|$tzO`%H|A6D6()QVSAFIC(pYeL8`${?_#}u5l
> zueP~MCHE}J&GhN@OuO6u&)@2{|G1BB`$aOQf_0}0P9jqI2!@?%iHe+r?@{i
> v$;QuJ
> z&sxChYZ+T*$@!7W$Fjns$2EY=n>3m8igHWlzZKDF)S`xN;(@iX`YYMEjr{Bk4bq
> A1
> z&=j4>37wXFMGz^&GsU#~Z@q21>4I8a`RIGUe-
> 4qQNv6pb$^Pg_65Es`_y}Ka+S|ES
> zdMyo{sT=sDtAT~?2C8KMp*KU=4anB+WPpkX9_92&F6o4BD0~rw3g>o8=hd4
> HI<(|F
> z#mJ|ahN{N0%~0yJCwBv=@YMtnNm|a`+_kjE@fD`@2l*&1qH-
> ll1Jf9g$I;V9ANQ~L
> zTCKl?E9?C4)h1>FpH&<AnH4%&C$gda9tzH7(@_EyA-E5I6MOiL{-
> J}bCj}l_5@__T
> zVuf+v>QTOjFyId*X7zj2&O;~2Fks+UMJiX3BXk#j`WwNox|D5|o^p{L4?L6;SQ
> QIA
> zlzP~iY?wb|l~5OWuc~!v-
> HfaeBdYprIp&NzLJOiSkM;#VdfpLP4K2OuuIw|SYX8zc
> zP0~hgF#)^V1`-
> n;rrZ59!!scUBdrJvc=V>~P+~iVIXQZoIbo?W(y#gu(1?W?r%72N
> zVj;$O;pruUdr4*%<DYe9_8q&j+6wa^?L(wQ3HQ+z!6pD2lrkpAQCcl??)OCs=B
> g!M
> zG6R`9Ej7$RAPF;L2hPK51>k~qDuUyk_x*Uf=STSa1^#}AzvuAx8vZ<ang6mff97
> R(
> z`JL0{_vihYi}RhQ|9raq{p@GcJ^bVE_sri-_~svfTcelJU&9U{+A-{pDVF4ZlXmD3
> zBAc-
> *fLC&Rd>R~f;4mn90<Ao!5jMjPQ2KX{3CzE;=;SuCjg>KwNe7O^!{^YYI5!Q@
> z`Yp`0`QW+C2;a)1>q{HQtp4Kj-1q3{+s%ECCxcg=#fNy37pr?gOjZvB%{+4k$5Wjl
> z`u1l!sT(cQ`t~azGyV;I`!RLR#n*nSzTI@<>RuV05PkcW99JjIU60ZU(YGHw;_Afr
> zAqb)5cl7O4p5r2F+=WUXd1_G{eY?46)m}uc899F&rfC`(W?H@U#bRWb2$q4b
> WtTf=
> zd5@`yuD*}PSgn8N=@%%TC(o8XKO=WgJ69U+<zk4l@m_pGitGjX82!4rgW9>
> ~@d~i4
> zYdoP}FIG=O8R?9tx#m$&A=f-6KXIYrZV}itEFf|i?(_l*V8v!&b-@lUgNEy9A-okb
> zE}b>zhChf{`+V5wa>ZjNHqO09W8({7@Hize0~;{Kj#0mamcp?%oa3Tyu{Qh_D
> oRrK
> zX~g(^8P%X2)o)@vN69U&G%3R?&)6O?oS*rEN83Rb1<m2C1<t2ka<%j`!;+>2
> g2)4F
> z-
> ^Lw3eZq(rp6{s~0t=wyeQfNb#b`2wQtBkk9>$v#O@ti5+N4Oob6LJ!^+(!@T{d
> QM
> zcZTKW@C2&%D&_`PGm)+S0fur>7I0atuJ^boOXm#Eq@-
> YBb>GJ>%6b<}Hg31rls^Rh
> z9sq=(hH$Hea9<__Sh0)M$B;G-
> ?dqHw0t>4#ZV1cC#({!uwD=W@#jg<Jc4?>tKgHr#
> z*n`DSZWS*Sk7(LT9BU9LzD)gkmL8Yg+IFx7)bDhFHu1r_1K+kC_yZWtg`yUA;6
> mvD
> z$qC5RIdunESj{_>CbuMaO>&Qu7oQ_|iBq#>d@4B6x#n2F9^^Xk6&aoi3%fiM
> HcS`A
> zY7?ZKgFKy6!)9UC4o^sux-4$L21r^P4C28R)Hp0O*h2-
> `;ceMtXaT34kw+0l6wp%k
> z;a_5Oz`{I;sSII9KMWVatK3OKpj961z32oOsw11PK|K&Bwi+nQ__R3lsZ%*Ad=a
> di
> z9YFR1EE+oyiEjbCyb2&^_0y9ZNJD$E(O55N2vQkoF)<Si?ivN0`Y2ZGAml95r!#A
> 0
> zunP5NM|vPqKIt|DEe!v<+lOI&4SawHINziVv2At!4{FiK!$Lcdm~DchHe{IOKfGY
> 4
> zF!PooXJz5yH`vg?$QWcWG6tExb0Xbk$pIK(S?vt&uy5cn7Gkur>-
> 7N_lE}o68HV@A
> zBLf!(T3%r6`h*8TczKrgm$ROpg-3zIC5Em73t!Zzphk7MFIxY%3Ak7fabzeZ_GlxT
> zmJ-
> 8_ln7pgK3M!W=>>vS=0Z@6Q{y34EhVNi2WLC7;+79x#5fwO3d)LRJ<bO(&RSLk
> z<z@*ZkZ#O`1934<?Sw#Z;5eBz9FZ6w|H}nut4NGJA~BjpVl-Qc(JT_9xd(}{llJju
> z8TFmGy2wh5Jt8sgDP{HIBY=p&^;%+>ZnU5qT4DsJy3qBYUW!<BL1>IqdD0Cn
> G}4)M
> zH$-
> lXH{D>C<R_>NGA?@oNUBieMw2C}CcFpFG+DVZJgDVHaGI+HgECtnR!>BCNF
> &n8
> ztXm+`<B5N|5XohOBR%$r^eFO#MhP1oO?rU1BhA>vL5fIhp2G}5%EMNr<zRK
> tC0uDv
> z`SlU_EkdXij@w>VYDraH{Wu>p*v`KpV+uTX;_f_0(ljqvCX%L^l4g&UG-l{rl4h<8
> zaj)yef*m@MG?zoFI+Di8tPv-
> Y=B|SpaU8n;prk1jN#n?e!H^He5UUyce320HzH?wp
> zhW}h-%804-
> 4?mULPU}6DUmmQ2qoFzn&4e^fos=4!`5LDTj??d4I}#1QGg$k_OP#A+
> z+h&@h{-
> rqRGUs8G0T_n)*`xlx3CPl0Es!n`WXY9OvHq_0$WDoTG&DG&R3^L|f_ot}
> zupYTd&;1tpJ3ZkU>Lo}K%l;KQXK*WJ3=6By_XYEfzO8Hn;Bq_0W?b?d{m`~13!
> nsp
> zZ1(U{$D(XX&Y}@ZAUVZQ!1cET*NO+$#R5$dZ5fwJvN4{DZ`xM9s3&yWswTG
> TEACe5
> zoVryktiEkq)zGC?Yk{1&uOYbz(op7PoaZ#_fcCoVTHo8UA;rSHoqc!$xv?%UX8P
> wW
> zSr~biy4kEHr|{7OcvM=E?|sVmHsbTV!7-)cE_E`W`QI*Mp4*v6-
> SxVCDG`&8$8I+h
> zT51K%0&hnSjR_BdiCtpS;n;3FXUMmq1dwU4J#`XPDsM+V8Wrx}tpcL>9<Xjv7
> H_Wv
> ziqAEJAAo}sY-
> NqU4P8+2vyDW>hU9l3uu~VYe0YMcznJ^#B3R2jDFoncmuP8=VXgBc
> ziDSsKY3eO1<ZBFH5ezOez%1>1JJOL++7w}FA4=osbI+v<!xJ?Eio?Y=Ckq+qvl&
> wZ
> zngR|?x2~@z$?3I{PgUf4p9;JUZ^S+7;0B`p$UZ?mhLIMbw<D?;i>p+boac5%X}e
> ^7
> z*~wb08*|e=19hLiw-
> kke`sA>f|FKjrzKsPQi~AmnsIRcP?9^OYqZBR3PT^el;K&XL
> zQiN`5p5#*t2ExiX$*;mg;1wv%oET`k6SqM(dw&xs%0aNLKr`H^IO@4Ee9}`k8<
> #_O
> z9sT5Rbdy+svYuEN44qn7-
> ;@gN2MEuSGTSmZvOhO`j%3OT<7$$@kru=~tVT#UnCkC@
> z(-tyhho|5HDqXs0yn6csD`Isak^tXzrqB&tT60Pj2VF|Jq)R*R@047SHq9Ttitux?
> zuwL&H2p9aG^tK+WRC_qUsA?Sfnii8>i>X|k2Y{4xNkZ3pFD+lOX-
> gN>@^!}{DJk+b
> z<2B^#uk|}utr~ttK7n7;EvFlP+gWyU2Ka<usqiyLI$fU3)~)!;0V2#M2Io`OW~(E5
> zj<>>0+=?q8t{f4oa|UN2dys|ILlUS9>a!LM9$a6PdIz9jfla<>e)oA6ze{o>i}O9<
> z)9oCka>vm>h9?PF<|!$&FG-(QOcmazsGH%7m-wO-
> Yy;iQQ&(o60?G+pjFp0@C3t=g
> zS)s8RiiOAKR`a{>u8DzyFxG7OvS#Z@LGpBX!k|Nd>%aw4yiVaTeq$ZN`vqBtQz
> b$q
> zM88K`rpj(Fn{bk}ZEsh4F#GJ~aJ_<Lbw*5&7w)g`=C5}2cy0%XI-
> F7}g|L85*UXOw
> zrC5Bz+Rx2c3)HSQo*R8PU?+CPbNdCK_*<MvX}IpDdVd5Dy*0~SnVpNx-
> ~1`(#$#S=
> zUhJ+fvKa1WL)}kGm3JQNfHRi4-`uoZ-
> %*Z$in@Ic$imeE^7$lArgshClBMo{T6+Kd
> zF`TzR;ugR8W4gw_sX2;2VC-
> AUv@79Tjq?TyOCdbKxOJvR%jvD><H!=d2M_qqyo<|&
> z<OyOXlia~t;4!#IIHjVbVwhU3_nq+9p)Zd1+I~ys?wXiftkjq{3l5OOP>frMn#h)t
> zSfEDkR?72WW}4`$S$IR-
> U$bp$E(Wtk`ya)9HQP$^`rvWnRL)*}Q#TD(5<ID$I>P)~
> z>ipU^Z6x;DD07A`Gr^SEHf_8oRfiiBc1K}o<uNYV%GKbyDA38Cc>h>nh4mF(9``
> TL
> z@vn&atEwwkuw|8)+*W8aF5@FD23q(yE~%Jr1&mOrhQ0DXBop65@qz5>q`(
> Sqf^&JW
> zfgdhhg`hZsytKILw}#nKllWnw7W6AtB>p4v29fn1W)4EAiEJ*3`D<WSisy>Ise?Q
> $
> zc|R}mj)|@ZlB0zHR-
> *Bq6ps6^6vkT#^hht^o>mpv0^gx3yqe@gUsoez++P)$*y*jg
> zk7;DM@QAmDj7R4+EGlq=)?&D|aiP+ZA1*|0m{L0j(me(9{`IIy{2*6qN0Xcaahj
> F>
> z*1(GjW;JMKky;M@?B%&8v=~SUaZ-xo;vE7{2?-
> +b9geK82C?+eSmN{Y{3K#FfuMDN
> zAV^Gq;6a$<O^g;wSP4(v9HCYXGjd@kT$(`A6L90A4i!oqSECHh9N`uK)c7y_rLaz
> 1
> z2?4A9PX8Gbdwg78gUJSq^G$7}vKEN>A&`L-
> Ey{wfTDZz+?;M&FJ)w|vuoga3{#E*7
> zTU;m<9)PFbP16uAyF`dR7k4lRR>2s{+79IalRmtknG2^G<aBU@mNy_mLJ>}ZLc
> 9St
> za!3L@%$j%^rwx>fmFA~#KNL#ilHDC8cv8z-e`^}EL?~Fm{i>w3;JVx-
> qVwQnIw=xE
> zcL1G(wx=g|Wvf4-
> Tt#WpuhoI!L~u#vUDT~l7CQHYZpEx+NSYH9NFB;HkUErY_PHVT
> zj)hoo;}T$;vFHbd7)RfP&3lp7Xaw#Pswq=H7Ha^tRE?Tf*oY+g*FAq#xAEA76OX
> MS
> z5j_k2i}{vYKiFsie%}E4aOU;ZxNF!D(zxAou_|ng9>lR1R-fLwMca51W+Ol8`toQi
> zJ=}x54mvovOcoeF*2@L6z%V(-sxQ5hUSp*52Xj$K-
> !6RtPT^3+2UquPxMiG2GU!gf
> zB_>y#Bbu54+5V=0e98s#oJ^29C+`1Ex<ESlHAvQ?wjipT0eKZb(q5F{P3Q>s#?N
> U5
> zkrq0>00D^jh9_mJ{R)}EVse>!WFxOs?+lI6i6aPuSkEW)JkuG(X)Z?(Q!Ltqca*jK
> zZpX>Ec!H_AvJuU#&4;|3wt$ka?xD_v)cH}Ku3TGbbF?6h)o(R*@>}YRGF3NoL<
> 3@l
> ze}tXFF5HO@o^HTXjwInT4eUYIGZl;S?)b<?esV~IIb1LXIc?e@-I3CG(jhTS&arA7
> z0^HeUV>-XaFKbaZ<6;+s-w$vX3%wf?iNk=SnxF*Q7CjRr2nQqirb-
> BxPLMMSyia9w
> zMjOvExK4s`_OAIItICBqy_^A;sKP~loZp8^iLo}+m!a~8G$>X5bOHrMpd&_l0r$
> E;
> z#b)cLWy)*o3BR7I*PtRDBjHntNHhYgEGu$oBm^3MH%8lu6a3redjP+Nu(^Uar
> ee`y
> z_>3p`8S}5&=KI7`7x<($aHP(6q}KOto&Vih|66r|w`v1#Y>R%(injUQ&NB8sZ0p`a
> z7o&Z_r0$lY=Qs<8rXsM;fwi{FXU6LZg)3r7#C@wEM-
> xTW&{Za`EQK0(RdNHy3vqQ~
> z^&0>x9_435ofFfEjr{5N-unY)O7MsGsUI$XjXu})^YE2if){nZw?}6|1yPq^Ypar3
> zwUS8QEHz^o82#|e;mI0J*^xuzxmQM@a5T99$3Fz!dmE#LXe!av7%eiX<f*74
> Sx3}y
> za9PhdC>l7lWvJ(T3VKsd@*r}hZgz%ZPKYqPPtDAVeDrNFm@R)hA{R(`4A)}LW
> +u<<
> z@EHj64u7t_GOzdCoE3lpH+cBC?3G<ckGWEFfRJ1wBz21eY92PVY%0j_*j-
> MYm+D;?
> zc)Mx~Tsq&blkrDg@|`LIZB%W}s`bCiJa0*!w~|SY$|m2tkOELP6lqUoS&9^4I~b
> n{
> zUFu5iePyQK=6ef_Q_q2l?xyo3x)0^XRa99ZiSY8%!~M-
> b0+I}5%3CJ|s@}<}m4qq9
> zK>bw6-
> 4=q0d*>}71b*ImH_&T2Yu^CjteDIOSTfPf0~NqQW>6Q)%Uu0ZDmgB)k<$k6
> zd0Xg3$&Dmk#6;mbz+2M?`bAJ}EV>?f;t766lDEWkVk3VJ_TKw_IMv4M`NR9vv
> fS56
> zrqO*MQ&SfMa0)-
> 58Ir)FLB??vWQm}pVM*^g{~LniH<JGY;&X7dB)`u021oUc<T80K
> zsEKYzfxsIw5^uN$7)G-_@xUHI=nYt|_-
> PTqGcY=_82F@O7!{~nOVu?K$gJ3g?z}sE
> zD)K>SMGjpbE`sF1`VZ%|Krwsb{;k`l_8n$xyxv>$CV2w&LC<!-
> lMU>Df8?Vv;p3r7
> zdH~`Zx+~O&;k`aQt}bwYZQucHmLJ&Mks}%R_hOVl&&#c--
> Mc9_tM3*(eqi%QxKLng
> zZEl~`5|qZm(tkg|3YJip4>kDjpR~C$U+Q}=RZ!=9pw{<Zo&Ww?{{wY_2hf}pFm
> *pM
> zbwBf>Deq0%v2+Z|-
> hWKU_opF0N3ofNt1!0O>_BuoXyTg~Tfq`G=X)en{z?SVB2iJV
> zBt#V#N-I^<q2q%{w-
> i(ana7c4q^nhob9g)Yt)uUm$w2*<1cx{<Qh}jEZ_Nng1ISxK
> z*Wz<w_+<T}_dUIJqTdpe7#5zumU*KLau%;A6>mP2gW>gVDk=nPelo5(p5W
> 8S{$8@H
> ze7WWHW^c_4$PMk>yVNWETGD|xcv}ef<aN@L+UQ=PWhq>yUhK<-
> E9bJ48M%w@7qqdK
> zs`tShcu^aD71^J;80B%DU9*`oe})igr6&C#((%IhGAe`djJ4w&L36np_7<y#I9&-P
> zTr;mC!wQ}kn62bthLv^F0-
> 8AS6ku0!@!BNB*@U%sPlK>Y+LVv5ULo)?yr3ufSBAzy
> z1Nkll4=ylqVqgQmgMo%OpsVS_E74cZjTOQ#%D)nJ7nHsgR><VXaNWn%mvhi
> ;jr%d-
> zeszH(!gohfeN)r*(@|lZ<y|F{{3_g6Y$QnEI{#b3(r-ZsW#H{u(p2WK7ki_x0!pT^
> zy5F4-vO>nP1Jj3hlO9)ShhZmn4~dX#x@s-UF!ij8ByndAH#b?8X(5ijEe6!oO>tQ)
> z5V1N@xpQ&o4BHVBvQYb~a7NMFS@ev|<&97w;;Tu^^Yx0nnE9^bYQiEB?29
> ;>wZ1Mm
> zbilZ9Xy+U5eGkgW%Q{LeDsbblaxY|cg9ymLTOj5rPfLM07E`;wbAI?*?^A|JkA
> M_4
> zF@Gg4Q-
> 8dk)BbOB)j<RfjLD;zJn}x}(7y|mdkQ4SI2Hd*;`@<Ha6owH?cob_XD3t+
> z&w!JomUn@J8XZD8KO=9px)FJEq)o@`W@agW_u>{udX*NwEuP?lkD^}^T0T
> LO|Ddia
> zo?wrU-(fl{zwB5KbR<@|Po3{A4id>XV-
> EcorVfXEQ!v1|*SCfMz5@1vER>rD(5xds
> z%c=1Mms%gbsxcnf?ScD-
> Jkt11a(Ab@;Ehhs9KTDP!MMmlGgg^g?{03*jY+~8iIX$h
> z=fdty-lr^m{@hZ*3>mDEcCc`nomASA6O)8{a0Y3BI!B^l#jgFa1T(ux!i>O;T}ME`
> znu1prHtTYq2j}-f5`7xZpO-
> xO$@Rdp!8va3V+&znkZ<($k}!5uc4rXTD5+4Hk&l<U
> z<l|mX2u78a@p=v#?=~dS#HQw^PNQiDQWM+$mAXr@>=cgvLxjsX;37oG&o
> gnxFZp|@
> zDnT9^m3q#Bt>)q6!=l1$2m3g36_?R0$AyvN>0|A8eN)(~Qs|8ek8osAro6iyIzR
> _6
> z2BAD+w+gd3R%3>PFMGrcx3{JmFhS#vyvBOvj;^C6EiqFeG(g6XmcSt>t(JiOVt
> HAj
> zo*D_b+alm)44uWsk*b~Kxp`g1_=`Be<Fqk(D;k!F9!9Tlzp;K3&*y@QV}?Iz@}$
> k)
> zXfLopW=p*_GSg=;<8AKBp_9V}j&=S{PMPg8Wws{}KOvDg3vI=eyBs}WvrEyd
> GPN5`
> zwava0L*lT<i4SMuOZIPi3IHSD5w92d!tEUs2C6jtvjM)=1^5Wn(;0Kvj|7`$RV4T_
> zbn30);Sfy{-wO5937<DA+r%!5t?v<gf{tyTZ+(_Ad;tis$fyvNxqIKx%iSgocuaVz
> z1u*8b0GQ(f&>H}-ez@3@H|}t8uN8Sw-
> 71;vR&^D=O9XWWIgZE+uE`v*jM^|@nbW)I
> z*4yhuDB(6;YcJ<f`9wV_1uBZ=AR1B%G!}?}`Y76Kk%RlAx-4Vgk)F8+i~}kWUb#-
> x
> zi_kK4x-
> =c@V=Z*9G(u;ZBXo4Tu>La3#+!eFB_!kmm~3S!r4C3C(aZL&Mf5WD<l~s)
> zaOR*H>qp3&r!n5Cuj(!0Bq7Dn={>gM$I{sR<o8(sTTCi-
> WQ)lJSdbf9ECUq|&6$_j
> z6H6`}Q0r-`yV6v6fl!>;Y$th6SGM8USB(r0l!j3$Fp_3KT)TzUEVKab70n}pV}nJ#
> zE!LQG@=w|v>bVKqrD(pKnRaNR2u%Qjz_52_&fk+Ppgj;m8e_NtSEq&O3MT
> CcUD#!H
> z&G)71Mh&RTJBn!B$D-e*ik-
> Kbx;y0}Gue}l3_}Zn{XUgex8WdAUUC!8BjDh0R#@VR
> zFE3TMwUd%TB&@VEe5n{p2SF@yc(5abZg3sn;2$;v2u)YdpK*B@i#8)|i07X_!k
> $AO
> zq|U}71tAg>JJWApk+*!1>T3#Y<s*Ls?zuSU7Nq1H$%38JJvlE<_l&^biAd+;`*eK
> Y
> zjK50!d3qiFUskVP*}Zz@^uqU1{^jC%Ui#ga;+_BJrRkpE??zC8KTr4EzH7SYH~4-
> U
> zzYpN~BK$s#?;(E$+^p>E?A|%O@h>+kuXpb+_0H<uyI1et`PLpu&v57)C*?1K(
> wmBI
> zPw+RG`K*TY(LWQ*<{+HS>W%(VCda~f_9S0X_`2XamRKxma_IE+VX%v|+8a(
> %3^`dC
> zxe&)Rap}*U@MmZw&6DV1O)}o0JfgSrG{U0FE1th=KZrTjCpA4tb8)(EzJsIz<W
> g18
> z#{7ff>MIdTSvyQ4g)kt{Ya(5VY-x=RL3<jw{0-1|b^8Bc7(MYSTK^ntxb;tkVgNhX
> z;)e)}JklHTg(m(KLtW%YTHlDggPZZ-
> Q`;?svDkZoUj&TIg+PK@DRwzdJ>^Fh=X&me
> zE+t=Xi5N+pqPQ#LH`pB+u)oBy+<e3f9VViSZ@X7-
> >@}77ogu0jF;k;N?eXH9AiYS#
> z*H$%}<B(7Bh$xpCg11hrv-
> (33f*|5MZ6Cug_5@DDt8QEDw!f@RL<fW4Vq$T2OfX!u
> zXcLSa0!h$5yROk!gPy|v0TayD#whI${Ow$3vQz(R&|h#F$}rFDL-
> w>TzX$Wok(XVR
> zYIBZNw>G<U`Hnd!IIP^7XZ{N}cag$jo+&>u!#qRnLu4aAX+G$|JQL3ZsdJ812mj
> ~-
> znKsV|NHNcxo(B2GU@`*CGkXBW2-
> ghr44;>&vh($jiI|FPr1TQ=3=?9WVM5F^Oz6{!
> zj(KJ+9??9)Z*87os;ha11vBbQ@Cnc7)icq>Jo6YHu}*$#^9)nn%`=bUDMyldnHI*
> E
> zR4huN8rjItqnKw#?amldopY>O`3Dz%9dnKzQZdgwzug(qrGtQ9G0(ICjyf9`hir=
> u
> z0>xqjDc?PqXNJJgqG#lCwf;d?MZQ0ZdFB_O88Oc+(Fqh3RjM`5+y~ye5AkztJzd
> N*
> zu_6P@m}l<7??$n)5o_Cg5&YuniofEL(wlL;MUMGvZJfG*!o8b~z6NF#la22as7>
> np
> zN1%<b3%pw!Xsz?L*7{!A7EKZ1+k9`rWYf&tkY}w_@fC2nmR@mC@s7wb(2s5
> ?S7ZO%
> zqTx)fcn}Q`H++aM6A#oTaAl!?Lt@rc9QvqDZj=SihFJ6wfQl#h8A+ZK(}|7z36l*2
> z^~CG>1G@0_heQ{?3SY^kcv0tnlXe>an|1YUt}MHl&^8-
> u6QRvU>?SY^&}Ku_LwN<%
> zH_N&ShF*`sU1K!Yq+B)|TMunEwjSDSY(3UyV{J3E+1OPHZ8o+%Z8kO!Z8kO!Z
> 8i-I
> zB+)D+(Q|WFU<kBjr&-oiJ?2V%ix{D4<xSX-
> EG!yr(&ToGKBvy5()&#+Y2K_$2u5i<
> zVIp-rs6+IW?=nv-^Ry-vhecGsu-OD~R^|ZaX^G7S9bb{eW~-
> siMkG2fzyde1HY|xR
> zknUqKOPh@`-_T~G2a-
> !<0ef7X6o6q)zD=PW!}M*_VzSvFCYud3*@z1^f=Eu(Hc(uS
> z#-?}CmOcbiH|I5ZiHJwHA?nmdW~9mHQrdGil48YVLywNv3x)Wh-wxk}?6-
> tq<=C*0
> ziogwbhvDFGAO>&rZr#Qc6IO@kYm0akh39LP>;zzLQdtW}!73xz*uA6=oh@qS
> #<HL>
> z4%FcAhWayvlfIBI`8(QXec+STXk<LWPq7(EVk19cGujQ+f4rVQz$e8Y3!miU%XE
> e|
> zBlb#^c*2l@S|R>gXGmx>dPRum6>Bpxt;2x7!U2E9+KlA6*o<Bgns@~xs8{+Jp
> qRf2
> zr!&$vqb8y1rY<%k1eQ5{D5V9lDK;Y%u{NU!Y(_>cANQ}*HX~i5V>4=^iUY?ROg
> 4zm
> zW!7dC(KaI#ur{M*wSfp0Xc29>SqA%sV>4Rk*o-1#xmjmyMoqLCEkj2HOQ_3-
> 8vM(&
> z%?S00%_t%^qh+=JNL?U;=8!d(5mU>U*JU$Wc1+02(vV>@iddTwJ0LcrCur6o
> mOva$
> zvd^nQ=qYDgL_;L5*u&75s#D=J!0is{6y7#Ulq||pG{~?v?yD8cLM?4H6520A|Fgs
> z
> zG+CeF3vbO#2wSNWCZr8wLgH&NAu%B)Bqqd!v;ih0UN@=Rgq~vzVM5BnW
> >`!}Qgen0
> zDXHfdF(K_nnzz$nXXa}_EuQ4N@;2}a8_al5b<)>b@gspsj@6Z^MgL&OIRkfL_s
> 79K
> zcu^bOj(pEtjPfulZA~O(qA&e{7?mVF18J90iM}b&aBVGDFX9lR7?o;ZRN5*=C3v
> U7
> zs05!iCAd^6Nbj0Dahst61P)rTch)%g=gxAy5Yl>>nKC#1Y<{`ARa!|iQz^L=k?6cN
> ze?eQ-A6~F>0O)%K-J3IRJ1UzSgF$&`XJ}S6K6xVa3jEAk<b!P)Eiy4+kBj$P^*C=G
> zc?d9YPX}(?h7zTozv5AT?s7t*uE&&Erha&ma3rEv1=h<6GC(M|5H1r4(|d-
> nDgy$4
> z#iRVRN6An>4xf(I^(Xhk*a8rf;Qm%aHHTJ{c%x^MYV3JT(wn!2!TYg;lEIGyAy!aI
> z@9(y4TL7s!DzJXnAs~5DVCTY{F$SZ2>vz#Qhg+JQqs+&}2MR{&SF*h)bj=k@@
> OfO`
> z?rOE?nsrTa|9UK3vdh)H6E%`5QF<F`6-c_nHY5l-80BYgC;4|S{JL%y8U?J4+R}Ac
> zR<IG^NjBZ)iADJ|p5SMhK1VO_;kuu=vJg1@J2p~~nxK>)(WH1Dj1xFqG6$&9+
> }how
> zND32^qG5cR6!i=TlVYn#{MN3M<el0SYbHsV9(yz?e$AZ^Q;G1lF)2#AyGe0~yN
> GQG
> zOp3K)Qlvwrm=s%OW@$y=tVxjzTr!rdZ$TYmQq&#6as$O-
> K(D1qF<rDrlcMIhe_E3w
> ze-
> ;CMG%3CblOlhQ33o9m@*#2PfN|l_!UGO76ma9Lxs`<@IQ!w46kF3KMf8Fz32j
> nj
> z#!~gG<s4y(GME&(GL6@BRSJ{hnlMd@d=!&Mj`XXw)=Snv`;kFG(wG!=#rMZ;
> #V{#u
> z5R)Qbh)K}}Cr3@}0*6*BODHfYy7FeLe#o06kB-
> ;P%u<J7Dt9;2)gW+sD^`CnDavTl
> zq{xJxDzr&aYEQ7oG$~4F<(DNDm=tS88C*+~qF#x1)oQO7bD>$|bu%fl)8*=5k
> 0wRJ
> zqe+qQjY(0OAP=lb5nZq*MQ8kIQe?$tDphCE43lCD9*Iej3FuPwNbI#HMgDYS
> mnKEs
> zyuZb4Eifr!uwYW;iwTu5ok^uMDKg<M4wE7u=^VzSX!2N+Fe3nyV&({FpHHa~
> f(9l<
> zmis(7pOMk0u4Y`_sVd3S)uc#BG${(i$_-
> *tWaGe;5NeX@(WKZcCdHa~y^Ij>!a=hp
> z#W%G{u}0%Un-npD3x2do@f)zgB;SL!9c-
> &nY4$QSDZYZ|Mp0!&!in*Eo}lQ_s>tq%
> zRndr{ObgW6*4oN!2B)+t)}lIE75TVKeQ>WCapOgvu~vi9z3YIP#+c=h+pxG7W;
> yEH
> zN)r-s4_27NfB+>bY>U^6flu2OX*c6Cl1^RXdZd<G`zM=}ya~-
> qh|6=S`X{dGfmF)0
> zEixBvi^p@~&S<Z<hQpUx`DyOT_34uy%!>%tonYh9YW5IaVdG21!nj(@X1ehY
> VT2rR
> zdHVaAxbxLIq8f7a&bSy?xdM|!8n&Q5!^n6n@WWl;Pa)xC*cqo=)2V|yL%iM^
> s`oS*
> ziJg%dU}sz{%N;64v^=9z*K$4+H7QV&X=*&ysNU<cfJR_A$wd4wrQLSRYi77hU
> 0~b>
> z$76vR<^nSWV6@GV-
> 5CWhOwsY!uF&RKE9>CeuG0A=cXJ$>c(5jO2s3KK5b9~)&i`?t
> z>>QlZbXMKQ%%4Cc_C!4?2&6*_0zHv}U=M)h@dgZ=wLE^ko8_@e`ezU&<ln
> {S$F7#C
> zXCxbpN?JCR8_VO&wB^yZPK=MTz4%)-jgOk7v2vvS@lCh=@q!-
> ;e_8wECeT4Dpfw|t
> zgi1p=Pnux`)omH0+hSsNJ7!2KFGU~5gkE3M40%Azkn)l`7ACrxAz5#^`ja3kKl$&
> P
> zA;(BP2Bo5t%GRd|kS0S03VJX@>L!$%COiR2;*d$=O%5PeM_tU2TS1R_5t9=D
> 8gX$s
> zAK)k_dN4z7MPEx*Qi|sHxTAhazsoQ~vU$feL;g95!K~by748p1mnK4WK+FIj8e
> Q7&
> zSRy$H+7h{(_2QqgMDk}m%1`abZZ@soS&EISIJQeb&g7$<CM)-
> 4d80o;3Xa{dY1X0;
> zC`c6QOd|>P5L2=G27E>~@{<a6rLB3lfQ+m)?=Lvd>R9t^PM@0ov`eAx<kt#y)}
> j_X
> zA?3t2x*pY=_Wphe+sg+jXbFvl)x7(uyjzENasOJFN;`eX3sWiL+@1N>bk9=<rhE
> 3{
> z@1?)Nj>$B>Pr&o@@%Nv$mA?M=bkA|`P4}Gi!F11-zfbpM<GT-
> j4_4DX+wr>?-w%BV
> zxW}-
> S(qd@sX~(jcF2;#l2g9IG*mfr6e<pkBaZLutpV?meP##Nsc6;eQ*iHUzduf@r
> zhYka&YG(a^X%9U~f^N}r*^_}%#s`P1-
> 1gAL|DuW~{|nheH`qQN%O2X8SBjH${HF?V
> zUBbisHLf8I52|a%{yaS|^kdv2%eQOz!3=?TTcoWpa-
> jXy?XL|P@!EAG^5yjL_UGq%
> z2h13ei_a;|bu&Hq9@rw^vpU}Q7PidwE^Hn>*ZV>P-
> dueMiJduOL&lUm@(4u3``&9O
> zM@wMeM8VOL$Z44CJ!^cl^y-<OXWv`u@r>FPNf!3qQT-
> 8GUFD7Z6|?0t?7_23;bS$|
> zd)tn=-j6pEO#TPnw@`LKzq8^qQE%ZJc=*a00NIFavqrLYT|p0t-
> gpD^UOQS61U-9v
> zbpFk3&ebE?kN3T^+fjNa>U$aWy?iR_dme8G<Y_3^?MHe_F(8hlq?2wzR7;gr6
> ;gLm
> zlnK`S!ioh<%zEK{?{x|_A408rk##fvUc%o#Ja5ML-|&1J(z}r7L)3rehysA!oP$R%
> z<8K=tokH+<_-8)cgZytHZzIyE^SbxvdW$+owgY)n_~DHVf>^C?WqM5e#U4-
> 2mS<O&
> z0JF_w=1=x``Zh}>Rp9mjR>mlfs;=7u7$Y@|S+AnWe70q-_nO_$-
> iVTOy<2w!aAC?c
> z`XJu21AoEayBNNKtCvaF_rLEQ^E{sY1JC-
> cm1nct=6dJ9^)6cb?z2mQvQf=>o%^%U
> zh%x+%9P)U7uph0>X^ONgjqI<g-du%D$lU^PsA~2p4H%WV-
> fLe0NSp3N`uUs&{U4xK
> zH2@U8FYpMGuKgpBzYAb@0PMA|pckFbRsjvD4NtcoLQiH(e}_r-
> +qNUutPutHY{ZcN
> zV+=}epMmP86yiPdz60>D;`;@lxdG{R<ZQt=(zB1?8-#x?*kb;N1cxf-r<nKve{ZrB
> z*a%-3-`QL7hm6OAe_q2Mw7cXc8SMe5v`asiG@;*U<*XOclwHH-
> dY5b`C$um1MyQzW
> zyE%gEsA`6Ai2~Fm@<4+h{-
> t^g83zSE7!Nvr`I!$uk>C`J<HB7<bG?U9*L#1R>wOpB
> zAE53<pzK$+#CPDxFN#$k(lqlhsuF&g(g{G`D1!hxtpj?VIq1|ntDkP{!d-yJ+6SCc
> zDyU4?E;T)q)tQ5lt=^A&A<*8!1vh|+`?A(k+_EEi#^KIRJiJH5${c<!f#_KH$}l84
> z;!OxZ-MJLEFaQb5{s*n{-
> upUP5B<OQPe>%ck7ptxFwza{+oub?Hsqkj3=xI#*oq2U
> zQS%<w+=3cH<v_I&T(j~_uUrDGs{lEM>{^Pz-
> ^uF`y(HeO?}b41;WhDDBMPfqfzT>K
> z8@qXbztcBA%dYfo#t4DK7Pg};1NvzhI$+j_-
> 1ogV?0EKMlt?~^en|n2dGrxHdi7lr
> zj6vQt+tK!Y7)}hpE8F$??&^>9;B7=^NQ<30z<m{P^%00BfoJIf4u1<ZY0~?Y!6oT
> *
> z8CW5a(CM}Yh^mnS26waedM%H%@ce6eGx^m+7H`d^7&YA$E9q=;Z_OzE4x
> DlToUrxT
> zcR_U$$sRQUI~X@0ZsBeY;BJlQzFTDQg)yqIs71zp6NDTG<ju!7#(n#<L(uso?MZ
> km
> z6o$$mWHWI27lX^qX)Jl8|0|dTu^`e3fNIidr37uiSYO{D>F2^Zud1$t(?f;f0ET5t
> zj&6nYx*8^=_UHQU0)2RE9t1Q%3V~~1*qUQR`o$j4f<c0>jAsjT@a(m`5~3OC+
> 6{DV
> z5p<<)A$6zQiZJV)OXE#_L2U!_NNCTVWWZd=jL)8eUuhn@bL4_N(94}eA-
> B58syt5J
> zg3L(U5P4e|10v&lB3qb19Du?2%8k5}A1fN6I^N6jK+qN9(yHgtt0iZFiE}YMO$K3
> K
> z9dCxjuior|h^T(2iVbS5y5>1fSE)0mc(M<7dVlZ_jF-)4a#U}r!ZP5R=a8SGxy3z8
> z#NV%em$L^%@)w^iP${S3J;2pSGe7J=`%vwNfBFBIdmH$;s%r0l(j+vrNhd%e0
> SZJY
> zT5Z8fL4ndsTN7xp!6Y_V<sEAs3TiJ+0J$w~oQ}8CVYFzYpeR&OQBk<cg`yPF7n_
> !g
> z4+X2X&`OHcdxnV`rP|ON$p8CW`<ydp(iXh;KL5|>X+Jr$&p!KQ?X}lld+oLNUTg
> h<
> zk?g=_HY9uNOQFJ#46W6)!jv+=l)@BJ!}I_86at%gjlSH^wDjrcp-
> @Kst4{+VLd9Gp
> zgE{}fFMRDIf9Km?zP-
> %k$ZS=uR&3$>Gr+gM^eSQ%vw^>j$v0w4FS$~{^7kw;5=fZU
> zRNl|K9ohYqvtPbAv0S?yKRu3j8)GAQJBT(Y%}P;;Z&K1`mRyCBv^YDcBoS%ChO
> bS`
> z-Lzd(@}=u7Uv9Zd5NyzBd#w`Bbz{8zYJPK{;Ikt20w~?NITo>SPXko(hr*~jq(Jn!
> zKVyIc8jUTxu^#tfMoOQStl5A1p};gg^7HMbPSWapMYKx|>q{qZ2>Ds+bOv7z`
> vpVU
> z`^Qmo%>P-
> nIkk|;H%9%j<AXc5?)*!>%8xknk2_!a?N)D!*r4~@^?y%E8;WzXonCV4
> zGw-`NR?=Sf+rQ+?y<Y&`-
> #1L_7_sy9QGaY7v9mY#V@8#CA^Apkx7VEc$K(J`3jY2p
> z3g45zC-(p!bN>V{-
> MwS?ju%g##Nl&S;fRep|45p>U*Bz>G`{XCoZj*L&cAH*Qz*lE
> zWY{=rYsZH-
> ?!@q!vheaF(&R2twa?Nrl}zNAoqv)QiX$9UK^d+}efT3EayxtTzu&zh
> zS4Cca1l-
> )=Ae3~(14xUCD$D(bHV$t_sepSZ$gpu|_s%^po_+~H|90o_mUZ!Quu$8|
> zE@61*)*XAoxSe};_N$1&9Xr4NQtvlAj^Ek6tLj<`Qyc{n*Is1@cQ>w8pXLYF(t=q
> 2
> zFPA3!+B5rjR<LGr&#&*ksls~+#Ix|;J-=f25y?&MSE5EL&uyd`EVTT8%WfT0-f`6Y
> z%r`Cvnq|+9SoWW9{N#ds+5DefaLoMlH?9<jKh*PQ4+@Uor_J+<-
> !#`xv9GVpswvy{
> zY<q3n`jzX)#eWljvb%FnSs6;07fN>|H&zdw`hTICom*W!JAdz2Ps9(c;@@w3ec
> R7h
> z{+x<e_C}!Cws+g!QC#O84vV)Qq_Mo*vC(@>==-
> }mRdbqtyp1oeyO!3x_(MJap1O|b
> zwDt<u)R8_}mFz0NUxc}H>!A`K=_k&Qbb*rJu0Ld<_5XNwM|P{IbJ;qL-
> `LWi>`_~x
> zK#fDcOSOL9)GOm+jT{2+&otrybYK3+FnaeD1GqKAik++u;K#SAFWXqb-
> IeB+R&P~_
> z&PiA9ZXB53xujz0i1yN*pQ_kepcRpfNO9L5MsDxUeld!jukYTu5oxmwX;akp^
> wRmv
> z#7FGBVcZcLIS`M5n<Lh;QxMy@t9%)}(NS+^M%if+M&Wt=OWR9#kJv~|vTqb
> y$oMsD
> z7<UA(nNjikw~SuDXEg6+>B@00P8^rqG)iaeV|?A1X&6@#DWk+9HqP%nf1JT
> Raooo?
> z&d-
> #Mn?IG;ljbvXw%0O#EKs?Y^=Hh(Ud+(PHttkP4Vjv86v^7im71?PIIexFgZHYi
> z;CHLMj<*K|*IB{I11GkR^w@l+bnjDzN_Lk&2m-(y7z2xYcAa=P?;6x=87Z+vJ-
> e!&
> zAR_<N?(+MGC0rdO1jDhLzPYRF5heVJ`ormW`X>7JiFW>J*A*2n_5OX+^o~)x
> 8!LA9
> z?!IDg{s=<+?rz+>`-
> =WfY;S_~j%jB5@w}bht}FVLq5M`n0@Up;pY+pNvE6m~vEhg5
> z+_`D0+xe&6$K^+2u5qWg`}o{x@DNwfPzPsmFe2F)rZ2yhYvxK{m!A+uPRGGk
> Q&9SG
> z_<3*R<s4OYJdjgbEcYA_4D|=VVO{V%wWj)zzy%);1>B0TprMYXvMa<%Mmo
> 5$8s_LN
> z<|Cbq9nDDL@4y#BNk^4yyl{q#2Okqx>=ITQchQ>3VUFn?^_F8aiw?EnitYJw8
> hpie
> zwXtz~1XBm8<oy1sFo?viy{GX?FS65_*LL04xV-
> S~j1l&YK}#3zx?(`MXt?!Uy_~%R
> z8c<4#80jYqqF>0lgh#shVRYVEFvySKJduo$NB$W+*uOnFvG8_I|2OE-
> OUVgzBYKo@
> z`Ni9BAaYCM5<AjV7b(JT&)D7Ny<`=j<vT3Uzq_%2SI5Avrh#3b>fe2ZCsOcSUt;Z
> Z
> zuew}^W%u$M%i!PDhbzEOqAWWTFY0|}cWgkr2kmI@DVbd-
> ?2*m2c)R1$ekAVJ+XnL^
> zkxo7hZwyLujr7~6!?GSnTZQQe^x^p7Olu_<Q~SKJ^HIq+;h~SaH`|UB_REq3pJ-
> =;
> zzrwcn*fyy!8%2|^^Oe0Fa8uHA&*a`9{VmQ~rB2PshNTWy4yo{GRXCO$o=}^)
> WLmMZ
> zWCc6fx`~qJ<_quGF2Y?QhB}5;9A&13d|<-
> rvBU5i6*Wgi*)1zryUdcjMf)(z>KZuZ
> z6F~zxIEsB6K%b-nC#%4U%pC^X2--
> 8{FS0Kq6Kk|0|BR&+j4ndExA$7tsqLITcsrlW
> zc<(24^O+#WTN`!S*~eS{SHyBfNG0fUqZ#*<jowM@od$9FR|)`qOMn&w<j@
> -A4*P@4
> zO(2e=Z>p6MXCDS>-iSOFKl{A#lys#}7Df-cf5c#}6FE-
> 56>>BVByt?2Ng%UuZONxc
> z&h0Xljq@*NaZ+-i)hns6>C!ed24s9=Fx_0H<2TN<f3|I3t2cF2A<aJ03>$qu{i**7
> zW@SAclt4*mbn4gN5E^$w%kQkLK9g?h?P=U1fET<i+qRc$r_XS1U{|K4tTlrtnr
> |WH
> zBK*lpY$c}E)^iRNhmP6=bB;k0Qeq`$GR!a(`zx~^>R)NIWRtz=Tzv{Heuaq>lgQ!R
> zgDm{2hJf#XqJ+{WcjM^cgsn2k+f6;yDm#|=b)=q871z@(TlqV=IvCayCU*6x2(K
> bq
> zkEtqf57GevRi_)DkR_8|?8lvZdVKW;q9$xmi?Q8*&-
> w}L`R=@La!$Vl<UGN)crW(t
> z&LeSmX=7!Wv~+#5x88;?WtwSl5x-
> oKaOgTe9x)0xgH%NRI!=}poHuw<nVEO&Eu_pe
> z4YI8_{@reDiUaxmH_bP^muakr&FuC5{hA{Cz0M~{*fX;u7@NX1-
> f;6wzS}#ddEfn7
> z1Y=?1MBf*Jp7}LbddS3O7VZYbRN=U5fvIs@?ysyE)J>JHn`9T?@1~|mrJKJ|R4I
> 1x
> zr+H^aD-
> 9F7O0Ao&2`YUisPrLP$yw0c601~lLj0TEoY+0Ju{zm(WC(;joZkZM&`Mhb
> zi0Q>Z;Ng6l_d~7>g~s{A#104*;q6-Ow|vVfe#_r&Ky1kkP&7va#<B={C-
> ZbbGNrN_
> zJSdxoKzC0!M8d7VN8JHs_>$dXtV^DAdIz@;2RE0T&M-F)$lOyMyG_0kh+o-
> KvV!}D
> zKIaj>_g)?4UP@A}v(kg5jTjed8oPhz30vX%rBEmZRf?Lq+S%5PHRHy?3EYm9M
> <PZM
> zD8cZh8>X(6-
> 5P#td1TtUp~S&vZx+Ws5Zjx*hmTg<Ib4dnC$9Y9wG2!6oTA4A3`eCy
> z4={C^7Hr^fJ!n#V`FB7P$be@UQy%y%^$*B3%fLac9hkTHU3|Rj@p<Ig|62UXZ
> IlV`
> zFMXOC<QpdZBrD7XEDenE^KlyPaQWP)Xg+#MAi&T|RS(#$T0Z^an5?hXb27xi
> -%-1O
> z<Muky#khpqzI441z)|{5RApp;`c<O9O$EMd<5B!p{uPEfX<219xTDgIKYly=?xs9
> r
> zy!#kas17+Tw_SCF7d89z_P9>ga^QZK?{UDNPwaN*Ku@DB+I>dgOFq7(eDRlT
> Q@8ic
> zD`)_{wuGq&F<s{yLhfxoIt$$U9gL}fdmqctjPQtuHBypaiSURpabnIF10L~XOyL-h
> zxZe%eZZCGFkad6VIZiA^Sownm9`VjdrQfpKd*PJvpeh{`tu##RDm5N4HK_F7p
> wbLY
> z&NSYeyPQgyN;iuhYm)0nPid+?;d!|zdVuO<K+RBiPo(-
> &i>rS?)qfEV6mo|!v8!H1
> zcu%hK+kCg<4&7d*ReyJGH=BWwQl^BV@NZ{%jkDeuI&DZt++OA$@(LW-
> cVhaM_ju~>
> zbPL|>38~NF0ycPYHoTmJEHE|?3yI4$S%|upGel+V5Mo0>Tq?z*j3z(9A=el}r9Z
> <w
> zfg?_J|I*8ai#v181`LB#1{1}3gcnY&6>d>(9x=%Z=Hdm%DeCs`Jbvr4J-y4;-$IcZ
> zi~a?r1sLzBZ1F}?o-
> KOdHG>G!Ok(?AIR5!%FZV9nu+WVz@r+Uv&)^nx1R$*zNPU+H
> zq}91~tWiV!T;QEH6GZlw2s?J*M<$f*wAbjiW$piSc%x0Z26Lv#SI$eftqtov%lqL)
> zk$y4b#LlX<b00j~92Iw5X84*E!Pmabh|I-h>{SiL0r&>wt8`X+l&B-&j%tRs#+*O2
> zS)?|~eUR(`?t}<1yt$n#=<2ffh6tt(ZgCUo4tJSj3j~u#AmjXT!r!isfxl3S<!+Fh
> z2lf%yjLyUW%IflY+WZsWj9nJJ#p0h|2;Yaja2tvrV=wWiknXrt*VgByE|dcuFWu
> G`
> zf2wg82efZb8Zp+yZd($d%awj=qj#!OHSO{il4(AyJ^q+X4o~9BIYDf?4V-)1==ftz
> z1Eo#ev@x5kD;o#2FbU|*>f}WJdm^>s$Ly6diU6V-
> yB1WF`)2@GMXU{O*C{r5GI($G
> zn;8M*KN|x;RC`7I3(J+-
> yq0O=kbsYvtH~w#+I$IO@?w}AxDZz)nu8~WiSj#1Hl^{A
> z_V>8CB6;B44wiDt$&H(A!%_6!;EEDvRab=W$LRgoumryv8Q5kL(+KukqprM-
> `tVss
> zeSZJud+A$S@91_KUSv3ERJVV}@!jKk%NCNBMM#h|=mnU`Ktq9OCp2z50aJ
> *Ly<8u?
> z<+!EXhUksmc$87qgpjK8r&ztn8lkO|-u*jdmjAgJ!Zn#u;YnV2#7J#Ya>?G<;-;mz
> z-
> 01a~n{J!|uT+2>@SxsS?;VRI`*bI}H7FuL2I(62!k~Kbmq$7W8^up)d!%EG72RNP
> z&b#q^6b18Gth>a|-
> KavjVJlX|1RaozC1O32!FG~&d7(tPX(%pnl$D4*bU*P@E0HUd
> z!g!R8#TH-;-*3yPuta18JShxol8t>vjMOQJ0NviZKOzpcD!Tq74NZU{UxI(WVvWF?
> z$p`)W#l8<AA0+$!2kWyD_=IONh|KWA)@NyYFqq-b{!-
> Bl&oXYZw}vZx;kqeIoJfQ-
> z{5HE(;jhnL0UeP^J+eMq8L8(NZhj6NhS>V-+-
> N;vVpoq%>WOGQpQ9dsQgrLHV}`HK
> zv?#Nc6oaXzbVeCnF??OtjK4X%hFDmPIp={a#xM(9*D49Fmy87o&eM!;C;18sv
> 3thS
> z^~FnWe?4{<RXYnL#_-1C!^iXL=ddVaAs|cS-P~su?H2^DBO++}j*}w-
> G?8qYcXT$=
> z9bw|c;;=iWukeMB9ZvS~yf0EA#*5ATlHBE0I(K=!1%Yd1q|)~mSK6yezj1q{(lD{
> B
> z)cWQbyJo>kaC=bc@mA^foP5G@l)DZ+$@{?uba)P{;`ODzmPWoCJLE&RRGw
> 3Ip;$0R
> zxXUIwnEo!4)SO1Ah6S~xltGhHLT9rz$y>`}OHY=kQ<f>$B0(_L3LIRDr9m!g(i2UC
> zr8BuWZfmOe7rsJIk_mUro;y#?28HK+>BAr^mRVs6DlMf}j?z_z(6euiOvo&`g4I
> =>
> zy9~n}^fE1Fsxh;v`}t-2UpTj|dI{4rYy4;OxR`R0*oa_}N;>T1z%HrvF|aOBQOYcs
> z1aK|hC%CO+D+`kl1kNv8)py&5k(XQVi#iJ`0@e-9-
> u5^3FVxo@>UUTtbklxHK+Ush
> zbK_GmF;;>*q~pPaUgH+1eiMx`9nX{hrBM>)A#0OM)<%f-
> cM<ye3j|8yfM`iJ*}H<<
> zTOkh#6DL-
> MM0<P6GC3ck*FiE79`Z<mPWMLYNf+1ii0b(pEF!EYOzi40Ivp3SN4g}&
> zMKC~jVY)k_w6P_#N!^%HYI<0XE5groq1Me06UF?aK6u!5>E8W5KVf`#$J$xu+
> EN4W
> zY^#OrrX8RZ!Q<SvUGclSS2R8q#yH1|gNvbtT^M#+3@wdq5p}A9;zgtv|C1(&v
> H6Dl
> z49M^)$Pf`<vI{h1I^IE)4<qt<A~(-?gC?R?LL%7#h&7bvRDj+`ja2G5SdK1f*RjPc
> z?9Jw<hi!Rri1{hvfA|yTv8}P=G-
> ;yL6sORNXdhSRZI%Pe`F}wOn&0tumsFlctAWy=
> zI!j;k*D{0oIV8Kr%AHQRZS^D?OWDIR{J1|X7u#}&N%TjK<QWr}{HL)Mwl^rTfG
> D&x
> zt=?E<PEa1|^c{ak<B0(~jk_CO(ZDTp>Ob=!P>R1)@84P0FrNML1N=z*^VK9Qlt
> wK&
> znSRUEWV_jSZS}r%g=)gD$Y8q6qVmrVAN+y7Z^0Xh@u$zipX%c?LMMuwo;i#
> ^BVQq)
> ziAQ=`CY~K!rikI4c;VmV{9?g5i7gCAl(duVs%1EUNppsG_vZ@(%TJlOU!zx<z5l~C
> z91VHwIK85=i<=F!T)5f5IyjDCslyqKT5xVq$1`p&510gL&hXBO*5OjRI+WR4P^jb
> c
> z8n+VTkxuuvdi`gq_Q3xYawCf<?7pCWO1?ZTp1RYx+_q+Kg=gtt%67f{?L6PWut
> C!^
> zGPJ}s{+CZ)|MC%m6O6V^($jA;`$~<QFs`H>fAf6NF})~z<1^-
> m=b2%Cc)FFn+p@QH
> z<A|xdH`YCX>x?aoR(1k3yV%Cm6SRdD%oFL*Q>62iv0!?Dsx@vt4^Xv5zR9a#V
> *#J@
> zQ#w?c4W<h?CrEeD<4`S%9;WbfB-eUhxz5J`tS+iw-
> rG9F*2pI2t6nE|?`rX$UZAvc
> zNW<Rpke!alfUNLc@9>SstzPaA&P%hM9*ceSsw*#x(5a1&;j>es{>~XOZ@SY?
> ghR<T
> z&<>rx`ana>JL<oY{sW}nV`F=mi#@-
> 5CR$MrEC#ow2F*_nmD<<G*~DB(Z_p(F8|ekj
> zhu<VU<9Fsk<M*xoy<L5=aR^`QM=vuen#UkkDJW{_l+fSX7mc`jLw|4Wi}`r4u
> ebJ7
> zSiV^zIbHLvdfhRzfg#MDwCy!f3@Np@X7N<@dDUXBQ)Fs7lN;)NcS3R|RETf&
> F0su7
> zrZPXWr>s*nlKUu>R76mtabNe`ENc$rwD+*&<m4SVZKk60+>bB%RBy+J=)%m
> 1<So^u
> z9Sy9pGDmgZT2o*C<>PFxkyM|pdAr`27)jQ7OU)^I!-
> t<s8Jl)jNk^sk_v1?3Q4wuf
> zU$LRA;Dp=gCDHtz1~!LpFuzTQpx0zyo$oKv?~Bf<)4n$=cF7;6{jB|Dle9QGf?>B
> ~
> zGF6J-|6IDNf!~}2Pi^fD)t*n$XtbRnw8^mirhU%o?qqIHHxhnEb^GCcVL037k-
> 6V8
> z@0*N%#{Aq&Zt5d{=aPK_K>kekeTaaR5c@h`79be*Y}~iLw|cY{h~^+|aPfWr^
> XXcF
> z7LH(Rf27Iw&S@RPJ*p3XcE;+HB-
> nhJAuzJzZ|T90_q)r{IiY@$E5(tMyK~<b??&f7
> z^Ku)6p3db{f(cuLF+puQD4Qa2Nyfn;jzGAq3zT$8UpcB5{8Y`T5J}lVpIo#1Qqo}#
> z&9vgMDy{|{+>Ha;^o*+|8-2En`(T_kh-
> GR$Cfjsdzv}U?xMr#pS6bD_^W3KXB^bNz
> zzy5hpCSZFSj<Wjl+f?9;c__swu=Ct6#A4knN!kW_X3R?hPi_SdX7|o>Pz-d-lIlRu
> z^m&~`=KmR}JI}krMK=!gOq(ZlRQ_XD&X--
> Zm6K95CSfRqL+xQ9TJh#5S|JQ;MOz`C
> zS2XTe0p?4JM$I8$RuXNX&udvwG1SIsEfz7L!b{JX2T3#yhHe4}S-
> &(}3WN@JRQ9D?
> zu4X0=Nuj`>+0Vu$t2UxCM@?y~&}jw47>laf2iC6NT3Omud2Z9-
> q7nHQGPM@<d?kX=
> zxov}s&=wD7DyB45*x{2>y+xMHKD|^Yr``Z_iFK5F7k5Y@IY2XFYqoPTG@uac;!
> mg#
> zZQF)r<wVLd9o|&2D^!jw_-
> H9>!C%{Qie?RF=akqo@aY8|i8*&j%vn$ddL*xT)o#J-
> z22r|d()-
> !}nX0Gnn^7=iY7GV!l9JuHMegvxz7bYOmVeifO@(g#CNWTl;tas#fvL`*
> z`GVVmnpvn~GvF?+tT9V#7$WBHlabbw7mQe=im|V1+YS{y<pu}E(<AvC(W8k
> t68)=?
> zymsmF01xV6EcGJ}qwa0-
> )?6)q%06Aiez9@P<KcUv40j;88L(e!P)nM<@89X>_j0}J
> zAAt0LR<K@vHGQC9;T(_OKgbkzbfM5q_n{`+Tt0CsWhBbTlNf*g#YmGwwF7V`
> d+~ZH
> zNwV?OThz7f$F9+@X*bci*6IcQvc#o6<;^tq(GyurpNmBzmlA_3t{+$-
> HJwWaXv77J
> zP-
> ylKagrabaAO&&?Z*t_l*ax=7Bw%yxQr!MSVxDSo4q4UltRq04GQPt@0_42jTQ)
> {
> zrV~UCvaZ17-TPdnA}W-{wd3d-zTG#T-vVk1<AeF>zG-
> }eZwB~c?bbsf!fs8E)|<$B
> z+U%7O-i~$w22rgu9VlSwBDNHb;Hkt2`jn27B};QZW;L?3Xj*4{UWEr3kq??h-
> ;B=n
> zAkWEo6|T{bL298LSaPc-
> WR&Q?x4lXM7J*aTrdM0Mo_;M>%UCSFhy2W@(p%T1OZ;-M
> z^lKHuQL3#zy%+K$$krQdsV2GvyKJu}57f6;aYyyl<iL^f)cY;A=~ZrFOSSIQ?fEJz
> zd?cW4o;DN=a5qvI%B%rh%j*m3_#??4tZVZxQ4$MXGvfa&==AX@yOY&sdDs
> jkg4G(|
> zpl?l@{g!<~yg#$Jx{?PjHx0gPPKH@VXQTS^dtCX+fm1qWLWz@~e|!X4_y2|SP
> ^iB-
> z9VV4N?j=i<A_CVjR6;^q`V_jW?>VOCK1ydV#oFHo(#9DEP-
> 9hZj$KaoTg}x)9l$Xt
> zznSf0ZRTW^LaiKi5?*{19f@VdZ&PJ*$v*%3lNAgr5QeyakIPoqyYHeFV%_1Tu)
> a{E
> zRac;(L(op1+^W0PyE7~h8(%&lKrcR`>(Y=}(TlH($Sr08;kUW1+IIayvW%q9!L3Nf
> zu)rl&rQ<~5xRCPBk$DY<l!NtpRQ~dWeb}}bQOBgA+KN3FF=e<DeU-
> 3L;zb1c+M(L9
> zaHizIE%?~5Xmzm5$YuXm^&(m2ZAC?x=<-zxfJwM{BK{bhAIHWrPQ^~_KKO-
> 2ads?-
> z%CnWSZ$i_+bFVq#5-
> &4;*477$8DJ?QJ~<m`e1_D1(t>LePxwp=ZQw_eV$rZG&usS{
> z1s_7}E2CuyQbz)fm1fM!quYm<${?wgNpP>lTW5NG7ITKCLOI9-
> x$dz2BXHN?Fc?og
> zV2JPx5i!H1141&Kn5!fSO>zB@hC@UkM)^@fgdZhD^iRNUqQ=-
> @;&!qJ&6FB+;phBj
> z_QTX;9q7zFj$RIe7fz|32KCW44~#Kqp2iIu<~Fs-r6BfD$4%kCmp)l`8UpR+sk8Z6
> zbWG+5>BKMuvbn7D4MpAf$198E)k~k8<I>-
> KaC$`zPtSSCK%ZkmXjGc<*N;rsv1-kt
> zrt4qbO{=Ow<$Y&CjLE5bI=k!*9&Qqb?wifs^yE}MOFJee23Xa3-
> $rh?G2C%Nrb-!T
> zb|pphlv{2P35v?C{)n(1=!ZDA8<h8%HT9Isfbb`9#F&7m!WpL2j^*o;vlFppA}Y;<
> zGb^d8j;bJ*%nVyM2LRN#*yILm(+=bxvy!#0F8W?80HM}mXhS5q`O(M0+Y@u
> XWCt(C
> zL(_?V8vx$-Z#MDBsXf-Hv}g-0|AJDl9ZztQEe1;3kLC3f?iI>EH958a2eV=&9mgjm
> zvH0ib$`V6*8N-8Ikplhsn)RH?Hzwt|xd9E`v5=3QD4kOCi`c)-iea{WME<w>5Kp$i
> zK3EqiSNkLaD!=`mbofa&nPn<}UPg`<H}YBS{tnqa)Q$u3PpXO<aKC${0ds-
> |d~gBl
> zK<5~lqgMN3?Pv2GYJblHTSLN$gF3wb{FSZSo9WR^*{@V@v&5L8+PfJ`x$lBpA
> JX`8
> z`7dNbYyqt>j?P!kA+WXvlAEx>mNu*;`yt<6T9erFbp*`^^@!=w`!ya)nouV1%u
> Ce(
> z#Lc^~$YbJW-
> )79UDx;oEqR@sD2Wiz=6uP&#(1gls=Alt7F6O<|<`;RPU!;cqDAzbT
> zB{^{ZO>>x3TfDz-
> w+2i4YZ&o!_z|VQQe66uyP&Mn#5R762{9FW6P|P2<hyxO);D{<
> z#r7_sllzawxtqzBn5{>l!T-j&4r}lOVXi+F=X&5y6Us9+zfd2vM)Gz9d2eue6V>%4
> zvBWacJ7oUN6GWBaFfrLu52Me3-wdZt?4%ANRtD6`!jS$qx?^F!eVC-
> `iuCDytWWQu
> z+{w{q{D8l<P_7n``VK7YI2Nf^k$PuS=4no}=5*xBk50a}s2$^he4bH}9Qd$wn<fZ
> J
> zo;R@z3WVvq(iXKJ&1QPFpROOQnGO^&l=7PT*(24#p$>$5BrTlg4Nhqr=r}`apP
> 7}N
> zd#Wpt#5mB1CBe3u&X?`=1s&d+^0es<REjMlR4#OvTW0j<H)&q`O(B@qwJ$&
> u#JQ)6
> z<blt$Ul}%~qrEjub4&Y$VVb$^=Q+6N$x9(38*XFAyC!|6{bcv4qy25}(=EurhP%1
> (
> z6qlb1h?=J+`G~r%{oJth&$M&A(}%J{r>6Wgw}99H%DF<UP2OrDRH98)VRByk`
> vQng
> z4<H&BKy*R?5olL$S}7WSh9|om!DKt7aj&h(8B-
> M~&7~{Sbzor@xeFB*Z<tZpzhlZa
> zxgk}W<jeJ8f@E)f@Y#yt1`bL#NCi{rtAmRmMsJ;c^_YhYwjfh;+1lwzozH0pLDZA
> F
> zpLZ9!GYl;ZL#x8jEn(;ZKZMxYoXuX%o3|0=bWdt^m}FTPni*E~U>LWYkpA_g?h
> Qi^
> zhoQw`=#emVJ0St7^Ay^^U!TsNqw^Z;^wf^1@2g@&nK<V$wxROU!pKw>q
> @3l=<knW8
> z#7~6j6Z`Ii8<?+(n-i9=Cso14UH$Xh_!Mo-SY&S9`;EZTsk5j)leMS6@9`f%nX&k0
> zFN<3YCcJcNlEJE{`I}HcJ}j~dn7;{2P_z@$HScd2nZk#Jex1Jwg^IRBa4~*RnO2wf
> zMy&AS?UC%&ewq5UGP@KSwoih|t;>lOx>diz#wofKN_S1Pw&*FmyKR$%u
> 7d`6|Kw+i
> z@a|I1^0sk&H^h6G-r?Q$Plo3EcrPo)`$dz5cSYtJQ4JK1)MUpSD0&JM-
> $TmC2q?Qg
> zT?C3tIm>H|f)b{8pxCZgdjLwT7?dZ@6ex<!{q$@No;j*pJ&uab$iF8Q5Im;|vkF
> W6
> zc7b(z9TCr7OV*^l;M*y=PE?NSE%!kyafMImJ*jDa**&R%`ss}DYher>JZ!Q0Ogb
> qx
> z{=oqT_^3FtAEHJK`Rj)m6T~W|XnXp-
> 0@&IbzkMAq_?%Lr<ZJbdPxCY2yL;(zSWUJv
> z9$hhWEBDv-
> #M9Zi5RJ%4zlNzUh0<NkswAc7_1#BivTAJn(bW|R@~uCB+e$?w*Xhan
> z@FAO0I5Nv5iAVQ)d3AUj>bQKtsBD+m4Z;QD(9<0JWGYW}-
> *#>$t7sNV$phm$COCw%
> zuu4ojLeh3N)y>yt@46=?gvfOkucC7SYh6OvRRRF-
> ;tLg7iAYQAF<;{<(&0!$awetP
> z9M1f@;;Fw{8Taxbw)oT{cxsdD6g_VVHO~PdLCp#qnk+V*8fR$GQzU*hObT(S
> IYQ#E
> z*{S$o+jyNzIm^2iCKisiFufyjmEzrjBQNb%rUt1||9mdD^F1PQMdp5UCWPH3F
> sF2h
> z+-
> @6_v8JX|&3xu;Pgb$%tllzRdZsO1?jdWo`VPhaw|K!P2<@CrilCheTRXD~;rrX#
> zsi)dm=h}IBq@70<x6`GZ<=y(pNIS#yuAM5y`yN+gtepeY6KUsP&QLoQnfo&oo
> w4DT
> zPR%5O?&CQ!{;$6{gAZA~42{d4zqr94wd|MpgwcNVuyHKE8($?Cu75y{8t9|-
> $5hvh
> ziB}DeR<Gd>XlqjiCwrIcl6uzo2&;w)Y|Z&e?g06cNed&>)H0~k83s1W-
> 1LuEVu}Q3
> zw`<mmB|aa)*>2l-4rxOPV;!@+3*l}dZG`C^&Qyxm!KE6***-
> O$e|{s@oi3ayGWWAd
> zfZZjQz__cRWyTO%ycfhOHdW@nbh?nx?jwN%+@h2&$q<>8p6Qg>Rwk=wI
> x8t7Dv3z`
> z(7ys2bJHo%XEo`r20+N9^h|p7X%|?h*Xo<E%VZUZKYB+y9X2$s>vDcFCgmizF
> csfV
> z(fI~k^zfV93Tw8A$@t|_#M2|v7T}DorL0;;_xPFM=Pnbzs}#unXkrLb^1!>}sqY}
> 4
> z2kiXVEa#KFC%B+u0)U#CyOQt4Ok}KEm>3h00CY$uqU(#vb^82fOk^634hEOP
> z%8OC
> zlup&rP04k7YH%(4mJx~^&<0cXBaEVOc^ssi<()V$LMUN+M<^=An{DlbiS$#C{`
> rKm
> zdV&Z=k-
> 0Bv40Q?m0u#|&I(0su3rs|BnJzsY6Un5MYJG26@`>_pwH<ffS&Q0J*0a1y
> zQEIL$8mr_hZA`3KUb}@aVM^Dn>D5)w5S!C(hU?dmU^$^>z)?bWd96xq_Ad
> P^=-N~r
> zjISE-2HFPJ7}~lcXj|gM1pkc4IwjQj`U5N{9A9C2hc=bs)p8Zb##bNBjiBucT`f#0
> zGItr|o@;tH)6s+wz|8X6O#p~HEGo)o^=$Dzs!K(ZF-
> 2m@b$Z5@oEVTZ6RAiQ2Npaz
> zE@{7*F12xY{nk<bh~g~$Huo*J^IaOa3snsNa!>Ob&i2swmy2kegKgdpuC*8d$`
> jDI
> zO@=TuuBV)XkqtP4(YQqWjLp`zvr!pNl#a&rSu}3BZL%NN5uGT{0W$%OD=Y{zT
> ?%0f
> z8*E_2*t&p;(sfpUq_eg`%n=%QDQ9`-!t27$3e&sJQYl`-+6Rq$)D!8fhsUe46q)<c
> z1mMUD`YARgGEsKvE!}k%pP}*8a=oSW#%h6Q+S0jHkY4f$BR$c0N*N*hp5;d
> NM&nlW
> z`aNYUZEjexy2@xgNa@&8`u6eyja#R;VrN*>jZPs3C1h9I$Z7R%{BseFSC9@G-
> *&Ij
> z_}?OEyUWQ50gWr6XnX`WAVai;=^ffsiuYbSg9qC7(%cBzKKo9gO_8~qA@AIE?
> =%_@
> z0L-
> keG8*qHqoQm|&t|WKYc?T?CD$2oE<sFFK>tM03J)h}qsR&>@F_T*ounS<(lhz
> W
> zth5WP)9V@Wf3*V)DZRuWU2(Tf9@!O|JT&8SLFI-
> HG(N$l8N+br(^541Ge$g^WUAeK
> zk(2O81`|Nv*P;6#D0Fahdlt)i?L1;X0LswttcooQW|^FwoAYx`?ie5DI@3J1MRT1t
> zv{Xc;0`j^EW);oTac_bM%Ga?)?}Pps^c#Kx6edA}TeRCpTG}?3Z8@9NI=4#k;Ln
> Qj
> z!XhO1ZhC@Q(b}EFX_*D`I4W=rKuP2``%Y9BA-*RXzV%GLGM%-
> f0_*gAfBat$oFZ<l
> z7w}!NM3Z&)8R6UE_T@>G$(^9#75H$PUMjx)D)>=PDkiGrUoiXDWyP6pn`>k
> <9|3{y
> zxmOuWPU?;=j&hapKoD>hg;h`{rBFIG$Wkx4PEVUT-
> SBvzyfAa#$~cH{6_;`r=Wimz
> zBTVnloEjcS8*B`ZUh2_5f9CwyI1LX)=H^1UA%h$RgiaP8#x5kD7uW^ZfD>8VLF
> ~d$
> z`PS?Lqvn1IA-nj19UBg(!~qZjyXe2i*u{epd@OJhLBKAQQ0(HDaD$Ltgy|hVREjr(
> zdptHJ?kdK|#it4%ip<S?2kheK^{|VHA%G#f*hfX#l%CDr=P!-
> +d;GDiy1ymCjT}VQ
> zxrAG@DJ`>+&z6H?w)%{KlIx6&+F>lW@Kq#{dpCIsM8$;^FV_|n-
> cMzRC8}{i91xYl
> z6h{9kl<w*yV{)CI5u(}>LE>pnJ_wNLQqJ<e02>UE7^aU9)jER>qS`?{5uz$TMMz
> X+
> z4x5_8h$`so<P$bEXb!S9A9U8^BqFuLt^6Rgl_uz~xV_xwpdh6irRn9hg*nLBNw}
> V2
> z4zjf)C1h{6nXSe9lLsCOa+U`|AgY8Ts%Ikjs5KcUT*oM(i0ZbFM(`1)clb~#-Vf*a
> zM76ybAAhSCJ`|aI^;CL!;YmhR0f3p?%WV$I?xmt^m!7TOU$~&c90W5_zpu3Ci
> j=4c
> z3-
> vy^WV3otXP@9bcLIe5q;stCqaV2<@XtaCxxa$eL$RZJzzQfwVWXUsLg~~lGUDi
> $
> zXM}QIjbJM8X5D~tT*_JA9JozLIbr$;<s=O>C}$h>L@4J!P8OyVncI5GaLNffKPtT
> x
> zvm>^v{`c&tG#u?AJ9^{~MU=Axgg`mH-
> !yi#KZ1`JO>zh+M+rqa4RD(fA7Ofj50&CA
> z;{K1Zqi2fo@w1bJ4@Kr4e>;@(zOhbv@%d%Qj<!=#Hl=5?_gITjj_da1I(2>wm#
> J9=
> zI2#%3I5ksS^C0IUyF@p5L*Uu$-
> SN0>vZal<nBU#(ya$_WG0qKjDKjSsai*X=R#yC}
> zlDj5scy7RDaZ6_-r16Di^kFg{mF^M^=RS$O6E~Dkv)T9PP$<y+ZXh`Ei$kqFsj&_>
> zOA&CpBx<F*6qB)dd>yNKzH;-
> }tXSudntepr_&6N>*HK15{|X!ZcPW(a+GJ(w8KM8P
> z(dPvV*}R)p1NwI<p??@-
> *xzCLDE%8~(Ek?diPHaA^|vB(TTdQN|8LDXjs63+@;~LA
> zr3Z7)M}AjC|J@*@K>z1P@bRLXRs(z}q0v8#F~mohK1%-
> |^67t5F+P5Fg7Bfp+~e@K
> z-1{)#$_h1TV#qn4prUM-
> p4_*)B+~6Zb!iu|{g&i9Q3CEUGgWmO0LC~AgqyJek?z_;
> zF$_9Avqn{T$Fl%uOHRtz=lEkBPUB=>R%vA)#RB=Q?&}0A=(z)q%JbI+^^RU+<I
> W#L
> zf+d~ZrfRyZGDpHv@aol$+t_CWZC;Q}l~x*G3s9MTonWm<XKg^et#0@v@Vz
> D<8*9mY
> z*h!!U3<rZiVK)gVlukXOTG#0r83fBCo&E<W1_Yh%QqJ-
> |1WyY)Jxm`N1h*Mz41#Xz
> zi420x$Enj5ncD=v`|rx6|9?#a4{^^XB0f9}LJEUmMFbzec49z)4<*zfxB$K!;v-BS
> z83do6?GJ({it+Jio$#T^+#@i|+<V`4=t<x~D$1txZ1#Tq!AQ4z^M3L=j-%tL@6xZ%
> z$xSt-
> 1s$%i<9Z6EyB?r~<T^do;nSR+w=2@Xzq#2vXrN0u%exY$7B(<U?;5C5ysQC5
> zhp(lcNQeLGST#_QxnE+{JJ(#RX<Q4v<eqvC3U-
> Nh=Vwf7Js)>;V=`IAWK18NJ}M$V
> zzm1$u4XnobitA)|{R-
> 1e_+@UL7ECR+2NO^IoWvoO>6q1_<fKZ#3oxdz!<a&>O$}pu
> zMuy1GA{g7~=Jx<&F6At5B5W_jSeQOCL@vA7Cy7U>CxWs2-
> X@GGGPeen7)mUM7ph@^
> z|9hdjBILZGP<_|#qET@#IDlxHooKW<f`V=nOG42|2{kI-1-
> A}S5T<u1P$}NrSw0FL
> zE=Iw<wL*a+bKivP<xV(88yhAN8-
> w*XFKt03X(6VqF9m=pmVdvm*6FAVwT+*YjG+Y9
> z%Wvy+dLQ!N=Bs|RpmVYJQN(Q@OT3`wRcd^Ua1u%9hAYV2>MdubVCy{Xq
> $bzt8N<?)
> zZL9_&lxpf+uk`8c<%G2ls5q4!$T3`Ptx0a+Bsq6+urM%?X&y{x?*wyrBIcQstLQ_
> ~
> zY6V!aR#2wG6iMeRgpXV@CfDg1q1D=v1)1hpCz}Mc>Qc_~mcgCEjtbL9X!W6s
> {Em8%
> zdLp#C{}^?YB6EL(bGd<5f&tDNM<mBa>i)Wu16<u9v4zw8YM^GbSuFr77RaP5
> @*v#!
> z`i<{Xd2_}#hMJwyuEp0u<M&%=Csq@2OSVgRZC$g28!pY>?@kd_m&v2t*gzC
> s1`^xf
> z6VS~&{0e4S1vcTguGwpuzf;J}86SV=`jZ`J2Z|;Y)bUO~|B((r!O)zk>ZJhe14IgN
> zLWwEOPUrHp6U(=vGxOzR_g(7kB5{7h4<q7y4nsu&Lk*Z8OqeQ10ZNWrNifau
> 6&;1I
> zkr&T!M|bEV+o;wto_B`HQAUQ^vt@+a>o=$FrqoFpJMWY1ZdsA~2JbzoRXiCz
> vHZJT
> zMaGT%C5GjM$&25k;UrnGiJ%xWLLXm#D$&8HIMJm0e(d0wl6D#W#vTq&v&
> wg<@lXcw
> z1>-
> ?sAOUcN(p~MMrgeHo#>4FqnjGoGlwdr#l(W2r@TG7(gy|#W;T{8!+3o@AiHw
> K;
> ztk!r?WbXIytZ?EnmD^j(_+^4U5P<)uGJaWDLdeLs{YE4os@xWW5E%K2Z`c}lRR
> kaV
> z-7Fs9LkY#mubvsfN0{E>L#23M{D99N?k~p2Z{os-
> B6Ghw8ggu{f==EW0vHbd8>lGT
> zrDv=6>WqUs{{Y17i~CZOABtw4I7GIA!|>1;00lIou%j7;Fs=m<$#r^0Xy)4y9R1S
> G
> z+X0ST%30p|u*i^R!t@cEx!wSTX6~h)2+jOtjBupL+`k?5-=`Tg6#sjgDG$3Oq?x;a
> zRYWuMKnOI`f49-
> h_agY%=qB+1A4({inRsCYA7Ofj50&CwHr=P0yNmI0UzPBo$lMzG
> zI(HH$4i7~$S5r~8OV3vCsc8q(%w`yoqZ!UO#+P5i;0grKY4PPc02?r!lTD>|nJeSY
> zyV9u$+c|I;5*plBAR&c~gi;EnQ<no%a-
> E(L66%ehY!%}vqUm=jXL+x|RYDR9(?>{X
> zynzS_-
> C2yXg_S~?B6FXP4=16wR;_6$gkt8fjlq9d)6d4>a83V5e_2FAb3q6s<SS+O
> zM)0xBi5CG0DWOOx2UiL45vF(eFr{qW1wIL_F2={zqlFJe=B^wA3B3p@<R^y!h
> N`tW
> zRK$T9p4cDzCnKR@-
> T#gVnY`WRrn6kS_+#D0gyOcHg@WQOp@9gYDC~HRLL6M9=Hxm(
> zBZTr=1Tmjv5Jd>ZrR4l0tRzHCm_9-
> %LsNaktSUy#MWcimMdlh|#sA&;$q40tJ3k#l
> zdq3&9B0`xBLJEZPdITRI!5&})A4(`f>4uer_z2TS2<6Y``}nxM7$5IHQut70?(9kk
> z<;O_<`Ljc27|u^KsVLi}XR9~a$|^gE04^1Su^q-_FAV0i2<4n)lyhK;fG8^_o7WD*
> zU-m`FMqx)b3UOo!IFjr1jF8RSpz%O;ImwA9!FX~hXL)zQK0-
> 8w=_6#b#UO;gtSClP
> zb%oHR$lMsX@&7Ai^V<I@BAaO-q(C;uNAOYa#FGFYN+_~P!#+ZMgy|z>v-
> UinY?c?}
> zBQ{d_P-
> O0nBO#lAq3iQ!9!xgpQ&F}{&sJ~n+(Y#KDG?$$*^YVr$|ak;)t`m3%gLQP
> z+$_`|p%R51l_-
> ?%I){uLRp%L@lJ`WgGRg@g0ajefS>7TTT!@u0eS}KBWgtQ&%Zjn`
> zO1ZG2$ec$t|F2NVFP|x*lCwZafl4Mv@NvM+t^q!jP*n19cxi}_FnxqdzI2XHC5
> wyk
> z@j{vKp~&10cv!BD&Sn-0_-
> DvmCQ(tgOV3vC*Y7tfDeiv%q{Pe9+Am736FtP1{?lU4
> zjY>?3EuusPF#Bn=;w*orZXqh2UCc9FeZgt`qZV~8OWIPoY(;5bjxA#uJ3b<Db9*
> tX
> zA~|NnQ`UU#HSJ#gV>D46%V_~C-
> 0#kE99re#3LR~5a+}xIlA_^k*GHI0gJrK&CvJg{
> zXL#)K@|x;i%Cb@rjW!VC%U6;OMI+ztYDFs`Fj@aAMT^({XI9MJlhUc%c`YQeo
> ahRa
> zsM*W^>2+i`g@aZp^|`mPaiu_MRtw~`h26q@r4@(yThlTaXj<w!XKK~}w^`t}3f
> yL#
> zsrZ#D&^%~O-2P9=byD%m+MKQQO(if1>+{7WyN|NyY&&^Ymhw3{)-
> C|(T7WJ9=zM5$
> zoz5P_;;GYl2}R%b%K}}66b<dixMlt64)>bi^XCO!R}y@k5c%rsOp<#>v>)a2))&5J
> zy6&XP3AO_`p-
> Y+p4(fospv20KvDvIn`f~8S0?g}M^MZQsi_E($P>a4PH+O=hbYQ>F
> zB?v}B1-
> S92+Ok6yImtWU<v`g@0jwB*L(_aT$G`A2FFmOmY9|10)FbKactL8gr@O`(
> z)b`BkY2B-
> U4qB&`sY}V{XGXA%|0ftOXG8SUvfzkpR~=tC7*fwqvv=RM*0!`&m$6E0
> zS4r8E>kI}R0#{<TuiQNlEf4eWh#ZQ}Wc3|QmKE*Y!>SK_<vyl#Z;zb$cHo0qwW
> !&<
> z*`@O@Tr7s5oaVi(eQZ(T>W3Ek!P)<=4%C__NckxZC;mxn<D;T*fh2c~W?#Eifu
> BPc
> z7^$QAo<9#s>8Y@2io=bBIBjZe)>CuRDz}*YTZ9MS<Rp-
> Q2fLKByq92$ArB7IJ07f3
> zyfKq~9(+qN559Ehb%;-qxj8l@{A~dzo!MxKr|S5^vRrh+KQ7zYlF9ULigX-
> %iXFU+
> ze~}xfg~bvpiEdJ)yY|vNjw153!>JZnrzc1MYb}RfIF&Yy!)f867&O0}bJ;`*CLr#7
> zuQC5zQW=6}+psi$^V3}QCTZ^Q)5u5T;mXPSX{2U8T$=0rG%~4hxHPBvX`X$P
> G@YfQ
> zRt^{}q#w}AsW<K+{p9CGFTEfJAWR3TFhS@=p>(R!=tWP_%OpoHrz3I&lJ1307
> 76IZ
> zrM%F4=<Eo+gy|i<s1)zFlYDx)p_pFYf#I}FN|E_@=JsLFBKNtc#T3M|&<zpq>v
> mrs
> zR6<2$vUBM`EO35o6H#W_;_8bVVqf@RL+mB~Zk*i^yXZp=u}k@@Yi)?F_;5q)
> JmNmc
> z-@Ev$<L^rTKE+?Gyu75`{ToqUT3%k3ofW%-
> JlBw?jo%yjP4X8jd((d<d>v6pQM#(@
> znugfV$=7gML+p3+8)B>GHpCtxZZB~U^4@i2Lu~RV8)7>Nf1ET=^ZRH1esB|Yj
> VT!u
> z<A34b2n9>Wl)0GlF-
> MF9<S`@lT5;s4F=IxLsT?z=>atrKVoUkEkG~%N^8CgBh4T5E
> z%%8gt&G}Jo1}FDSYsbn_W%5>hu*t59Zz`lZJu1J@l9a)JNszu6n@^Rp-z)Q~l^I-
> L
> zRjj}VRa1p?FU>t=Qu%gpD$^x-42@N`a+wwbpD%W(%Y8d#Lo)qR-
> BV(W7NdyOex7P9
> zIXR<N2A}HYoGwyFlkS0Wv)5S_#rh6*n$9J+?$xl7bKa1d6nM5^kRWJZb)kLLLHj
> U;
> zf|)Jy(Y~vP)xq6=^X@f-1srC{YK~qv!pVOj6D+cuAtNg01I#L|_cn2lFnP|qWedky
> z5?*kDcdtu~je`;SdyCtH{k`OR%oSB&g+<2rGSde#ErWn<@M6y}G2EVEU&Ue
> UktU~>
> zO}`j9v2no>-WOgo))g9;a$k=2HZz#l=mlZrKK+uSV2yG#Iaj-
> !8@W9`?~sNl{TuWF
> zd@KH8_$Yk;Kol(R9H2P}fMfnK0D}4-
> 7+(LT?T5inPvbM<WxngJVxJMASC?H%vS6gw
> zR1E1C*ge3QHkYuz!1u(YZ*!x#T91cE&WvRnv4z@)ZWN}<e%AN39VF8SUo1{q
> Q$f<E
> z?JeH=xSw=wm~>Tf(!DBGmO<YZl$v!(z0>}kBixO>J>`Sb=xhG<lyAZ$g2v4n1@
> 2qR
> zBT)%x#{b0T8_hhuOf}+DmE$e()EV&i<kXm`rTuv9mnqcjy<(dUSV*%E0;rifu<n
> C(
> zlH|Zpe0kogQ^lGeGFAF~{nqo-
> P21v+)qaH+j?Ro(bH8G{&o9OAMk61pUeN~`X_`7f
> zDAs-gCe1B>t==cpTKebD$E`wsOz50vFBO2-9ay?paDjZI9o4#EC^3f&GN#gt-
> 4|K;
> z(YYWqxeN0k$>tds#PTxtoT=Dc0{(W$*x3bopIO#I_6J;ctZ|3gkGAYw#Z#Ki)5(v)
> zyIq{VW1v7Nf-
> |>)M}VzUGgZP4j9^o%ciejQG*|r)6aBPbiKML#F}upPC@K<?JQBO^
> zw@vJ(O)cJvJ8b8WvB-
> I4(`{7Wr{ewEWP`y#$jdLp3Cdg`yj2t<C~%V0>|IbO$Oq8t
> zJIWYTv-jZ#j2<&>+giQ%OXk89a^rT^SCpr)%-CweCp>H{j`aTZZ#G^xCYNks-
> 6DG@
> z0CIXUAkAt|sX$pU&2W!DMN%RTH+#SNu3z`2<c898+a`du`wORc;7IftNpv#dz
> DX-5
> zd_4&zZ9gy@Ti110qbQcy;Wlz`i(!JC6N-M52PQ4%nu9Cn+@)M|plr(7l;0l2o)=Gj
> zo_+|w5Z~+#e%}fXDf6vLdnqif<NV^1e(Xwe1pb!AVA?p=4pDBCMf+_oxo^d}
> {T#4)
> zbul)p9X5d&Y&xHSUdwlUbguZ0p;OjMj9yD<BfWZ!h|cd-
> 4&}IB9nQUtUwU5wtIS#H
> zVqcn}JrwWrZ}I)6H~-
> FjwdEjwyzemlnEBv8{~DbSblcQB%QXNm4#TMN2=6tQ`p|Z5
> zt$hXiWnlIUh}{jCRpQjfelZf}%@}1UYWB|kwxQFklgSE~+%U-
> 0MoZ0<TCq`xREAP&
> zrc{Zu#+Uz&u1Zcd#v5OL5ihVk51xW4yAQ=5EB`yeW*FW+ep~qTSAJWG?^pZ
> +5?A&4
> zU;gBO5o_coooZ}dP=YO^uiE&Wn7`<)ilZ<UVpfo-
> N(I3Q1gxS;JULlUZkoua)qL^+
> z{FbUC=e^3wr*A43HQlXv1Mp7&%h&ubV(Jk9W8U9|f=v#<H!Y58R7e1z3W@;
> 8`F&SV
> zPIF{WV?UVZXCF}W<Dt{$r;j8Mct!Hon(LQfS4TJalt|Geq8F7&`>ixt|3~O4+m^^
> K
> zQfOpm)Nnx#Y)o^N6(z&kku!qkkXC}XTx=JsahcjD=<X@CTX-
> ({pka0Flq$t7#vKu*
> zj-
> 67jZ?}nNeo6J#gJY*yw%h8043>SASrW_rkW~2#qnRm6{T}4<)1_3Jx{(U43fQEp
> zP}MJylVPrdk+1Cf=g(I{bK*ye3db-
> @w_LYX{(~fUM~d$_9s@>G%DdHsBMqYbNqH4k
> zmxrqkPN{lErTbsZ^6+8oB{9A({Rra{Fl8tb>j_QZj0M7JRJ!c5<uj982B$F}YRwS%
> z8-
> (~y<+c0<bgp+jzKZnwUqev9#BWWetZM~sm@zYjA#@B()@0}CwXGi`bT%hoK
> eRfT
> zyYRZLpCVf+R!K3?<CWZ%e7UrAL#BWI8(7J<h^OWO(EgzbWUMZqK-
> #;WvWkXEv19e#
> zSMPe9x~UeEt=Mjz(l&PKad<kIARB{qEGDksI+C(WaX&Gj1<Ke7Bx|g@zI!AdR
> 7$bl
> zg$<>;@{W1H(z(aAb5?Te;B?Gz{^RYu-
> P+j~v~#Ytvk$v)QyTkj!*tw0GB;B7U&|7s
> z^JQ1d#mT1!XMnzcycUN|FQ~;~(=*G0pb|e}^=1*OqNL+2tk9*6Vl$27Y*HL=&
> xzM{
> zi-
> 1ZSC*3D<q0Q+k@xt5_V9@f2E)SbWgaqsTJzd~f@55rfCeAitfAJ#Ie<374d5<p`
> z3|{xV)mN*WX?uRQevMwrW0$|9{62*;HWsw%vp{}A=Tt@O`{I)`mZ$R-
> y}A5r1fkY9
> z2B{h#_I*|0NI1HFN%qxWTCmiGowkAzB7Anqi_l4leTeOFj`t^G-
> ;v<veVog|g*{KD
> zndCh?uAtxWQzrJR<;v`p)LRbcilqbWE*NK4^BBO*-loqA6Xwv?_x9Us{sm4-
> bW;Eo
> zPYEi1<()+p_p0JcqZPZ9u3}~OR&d1!P+i4?FjuW@u>jtW3p>VwtlllHUyS#${%Ic>
> z8d_BAjSP!(dA4X8S+Z~B;(GZg>woqg)4zOEt+$7Zdrtf3Qhke5bo#Q%d$7aoxU
> csq
> zse8LGl(E*vzNB~IU4DYrX7Bl5qnE*a<rWg3umNaf>{E$?fxTt@YYc3Qc+v*;8%o
> >f
> z2KJLSu;0iwl>FJsY$=IR=52>46To9jmn@cH<Jh7OYV2HZAky&X;gJ2}23Cu+D0_
> &p
> z-523uHG-g+hv8+Zt-o`_GC-gy$!+3XX1H{~bOHnUX|e=(@L+zcVxu;<F^b-
> oo>?R8
> zsT!Q6!W)~tF$^TE`=zIkWfEgXilAZ<X8nev*UZ1Mniv${k-
> f7)@gskVMVt(*^#ZR<
> z-8FfcnpIO;#x5C=-y1=Z$LDklHj4$6Od?JjJE3f)fr0X*GJsKz!A7-s*E3yXJ2>FI
> zVnWSY6-%&}5k(o;_AVrm6@Utac2uYxN<f$X08@m++re-
> +Kg>HS$XjN4%iv#k6*3Sf
> zm5SFhtsc&WnVLh7{|fI_=7zw2wdTZn4NGRl7H_Bd^Fc%9jNa;F!OFVHn=QU2
> QaOKd
> z7O+oBjQg$)+i{6*$1f%`rXu_TYka4B_rMVX{W;7)DHHeWq0HWM+{6inEf=ubD
> %Na=
> zfu-@N5Sf+_TYtjUe|k{=PZ+Jk>pwYKze|~zO}>OOdo2gmzvI7A{}xyO`-
> 1u>AEN$y
> zU`%2AUCP9Rs$ZGC=Z+uV{%wb;KiOAf296oy)v=pv6_%|-
> jCMop{pxoSyR(L97Us<w
> zA`W^Uus*sVfbol`49C$V@4vVY7{cgMCgzaOGJB^-
> V9cG*bm!n;7+{Y%LKQ|j%p&7m
> zjSWGKCl=R;edI}AI$EPk>1tGF?`Ovqu#$V4rpeJ|dz@#9TH6=2))$-
> m9D~;k*6(_x
> zF{pdZ+lyMe&-~v+>vkz!-
> OB7;5UD%g;zYHpe=O%pKVPQlOZNE@IA!RZ9?(FUD8Y3E
> zUgd8Zx%L$G0|vJx;8`xDG)5Q(L@q+%D=lhZe|oJ5-
> RW$NzSoNIqVFPv=(~z@?;pAJ
> z!;^<H4dZG?cQ2{AC^Kgq$7}b$klYbV6PM<dZ)1aRxc&^jjpbY2=<bfX%<OS>%0
> Kz}
> z{eQ{qAXLroFZ0t0>&u*RHHv#K|J=^!UU_cE=odTo@x6clym4bQTliA9{|}|l-
> 8g0n
> z>29vLapV-z-
> c)kQ<mWS+Kh!aD{|ozfBwvVKcI8zYs(qIzAO47eTOEK@SpcaTkSbLq
> z-;Pnmg-
> >;SqJ?b#&vx(_v<>4bfn~$w=Rfq>OY$E!fNO*S%BUO$@D>2ByMsrK4{bHj
> zjse=rn<^&I`V+tgzm@z}f9SIT;8$H1!tIMsfjxfKWdou-m?qO`M0|3_ts~;o`0ttc
> zG|tH+{tnR+>|syxR>5$>q4xfSQYNbPF!5;v7jTk+6mzCzjfnV^S~y&M3gk9ld^*
> pH
> zLvH&46izWg#U{5M8?D%-
> bQPQUG%H&1<BV}%e3C~P2~10By<fuy9OO<E`m&|kch}>~
> zPX7Ez791G#ZtK79dA%Vb$P_SZj{a;-_Cj!mxIjsgNfzVzIJEY?uQR7O=Xu7yPNfi2
> za<RVIce;IS6cDl0%O#6(J<@OT2374t4knJFFCCGbaWHw=WZj=`L4pxrh!Oi=(@
> Z`C
> zZzFvyHLu(1ixv}}GoFE^*h7d4#za+W2q*R7?5!_TxpK-
> (Cn^A?TmS<lCi?r+GpkLW
> z=$A3w*0B?6I*Cs=YX>J&5&%*pA@G&uGeAlN@PR~i29OokZ8f=}ZJz;YiOvU
> wej+rQ
> zBq~E04Gtzer+TVscF**B(!h=*^X4%6#e%!huXj7D&R`Ocdv9<LuqVb5L^9{m0S
> qQ@
> zX^3^4mUx7i#0sP21>?Mm(?n9#G?<>=05+2BshK;0%*+NY=Hj026Ncp=JPd@
> 8`1+~}
> zZxO2dpyFcr<1X`b^=9%1qmDkFDt-J-Cnd&y-
> )6OQ5^LR1d)&?Aj^efPMsoB#9;e#T
> zbKpZSz=eK&c%;6-
> qkX^k%x@)r$tF(cYsKX^1m%A;T0WeAXz|&dJSlzYL=|z@OB8|Q
> z&n?7Ief+VqmQ&@zvrivq>tkbI{=NBk>h)84#oe~j#vhyUh9&g$<y1@P<?$uj
> @4Zbg
> zwjt=lJ6>~%+<J}$UJS?%Eq<SGGkodkimr{6OVi?yRn9n7j_!K(af{m6*qeKjO7-
> sX
> z-ps_c{y+sjxQT4_I;IO(==f!Pykh-8#c7IP(YSYI6OKcEzq#=bh|vQurC9!`m2DL(
> z+V*a4{Jo;+5)^SN^-HQHCe@tYmg}ur9)hySm~tGDZQP5RO5YNy-
> #hbese9{Dqu?CI
> z_M`Mo?L+OGuf^f_pfzEKqRTCMM@Uv-
> mpc4R9XFjl7i~sXWU3Nt(PBPUHvQDb%6v`!
> zXmn*hO?VHv4az7*Sbp@m-a-1@!}(M5j(k-^s8>$PW-
> dInYV~8YV(skZ_9kz=f!zZg
> z(pgaD?c1d>Q}8WF+Jy5vIHmT^N69fu>+W{kT<&F;XNB$ZbR65cWbZ<z`t~uLfY
> FA<
> zKiM${77e{?lqo$Uk*TtP^I$ksyPS+HbE12jRo+@x_eQZXzg}D9kK(A!?0+%1s20{
> W
> z@8F%!03Q`+4EGP|9Y(+1)3`(1a^7G6BDC!Cz7H^_xTn3nP+6-
> t6S@HxX*vgZnkuHu
> zEQ>F%ATl8%_=#qX=Mjl|!rnJbhrr-
> 5?Ld5auO=FHs%}g?z5>K%mh`^*Z3^ij%v)2h
> z^q;NXeyacuvP1h^@zm#(OM3?iY}os_J&|HMZ%r6_j{?2!v$yL#!Uq`MMX|!K
> HX{=3
> zoC&j*Xd!3LILxLZYt`4um(d5F#4Ei#=EZ}0xh!2(2QkuRtn=<0s~~7-sZ7__6ZSV?
> z)iZl-
> +R`*$zNC)c#$g^H%+JheuAZN+X{sc3e&@mIArZL)T2e!?rIu^u^sy^Gx9SmA
> zye|}zqu0@f{a%ubtu4X*OmC@b*t>G&iA1beap%92<2M<jM%wG6X>8|I5ty
> M#J9~O*
> z_8!Idr?Ax2n>PBRFdsz+5#N*-
> 3?&=$<LQf`j#KdY9+I>iu3ztp@{&gfB8Ap2JFGu(
> zse4GG3`e`qzuDwm`|L%b>(ah)zG?90Y~#Lp_o*m<StKPwwyD?q!;aVGKhVCE
> SAbdl
> zgN?q?@va_w2P13&k7ElM5+<c6S{buD9Xnc*|2WBCFHT-
> >$#+DOUunsA<S)seMe@Op
> zGYX}vw9n|X)Y|NfMRJX|T-)=Sl-
> N9rd>Lb3wxJ6MhU#z*==fjX#K1UuW8bBef<I?t
> zbsBR366?SZ1?!M|P|7h7(dYjcBgPjApvA!V8Tym*c(M^>Foj=_=lT`*(*3wzi>IV
> *
> z4%V7v@Z~g=Wg^B!m57Y^HrqUHY%KpW@C&_^8+Zy~Ia;>pU#RB#=O-
> a#WN+W_u((;1
> z#5Xw^!;Ty}s(tZCE7(E5gsAwVGfJ3?K0w3cj~<1nr2!L4WW=@L3Az7f<|-
> Tnthk%P
> z;PItx{p34w^m^J_+SI>d`ic3c^Y`R#qAU3-+|DTD6aMSe+lpd#@<to)(1-
> MN_O}Dj
> z15a6ie#9cY^%y$bF`tgX`I+Sl@2ArF>4uA|^S?CQo*Lrz9*WOBApC>*_O~-
> nd#`gK
> zppHOJfq48enATA3M97EP&-
> ~I|Pad5EfIGsn#@m<p@^gv(2ayg8u)=f;B4TCFG)Z*O
> z_l}bI=OxNzn|_;a+Ad^oH)L;TXWSth#{z^5+2>`N2p)uN;vBM}PW5s8(U~VEx1x
> &@
> zzE@m)V*Z!;2YlT_q>~^F2@s25Z0ZZjI5GJ&>|Z6UXg)FjYr%_?aPM{js_l89pF(?
> P
> zSnuS~Y0-
> `fzJh_EQzG<q#G*KhPATy!=cngPug<?r=2q_;V9Y2yKQ=kl26{V+JgjQp
> z@9L3m3*T>7A~kb#?&NPU9^JXCfW_E&!e1c+k+KInbNAD)>@z_JN8fxp!f*W
> 1&w2OB
> z(qC#jKWmRdJC{FpZ5fc}tJfZ_w<Fh<>BrY&WoN}6BH^R_t>bSKfB(Us&eG|?T
> =;K9
> zse$0?FElyum({ss(Ad6?VwE-
> xZl11@MvwQ*pe~Kq3Ljg1@0o7>UnnF>%uC{|6GX@r
> zj(Q`*b$DG&F{+D3ul(HYh$SngkJS`2yf*+Xm|`kQwN@Hjxgz@$lG{YX6cfd;wXd
> ^p
> zJc`|rWesLiI}UJenCe6m1^U+s@}5*5-
> _%A<$XZzQrUg3J*(bVuQEeux@X9VdF)!NB
> zPk!6xlz!{8so(OGPVGa{DVz5CwX@I)WV-
> Z>KPu}x7*%#JSd&sg2h|vSXGB<no2wm2
> zo0pecP5Ec@_by<<ryaHo(TSXF*8m4PTNA=j)&SCOE&gxrF!|R{UKS)6VD4#liL)
> vb
> ztAAvqyD~E>wW`Um_D*gZcThGOF)SO%D`cDFvK3*|P$n_K0tIZwlMjictcCH%
> mbVH1
> zWN%439HOGs(z@}?$f_u{o?u9a-(0?x%WKt=6`c|`@>jU-
> i9fcw$qIXU1ce2e9Y?7L
> z)>7Af7oQk@^SgC*)d1~VvC0Z7RJ(bZB4W8SVez?bg#N+ieVe41F9f^OZ@j<-
> K6dl_
> zLI5<2B)72M^;^qK;u@9QP#;3(12flUza}W>R>}$TIV?r8fF+0XT%@&blpNfs^EG
> cZ
> z4Z@~wxwF8g{P{lczr$cd!0GeKx4n+M(&tq@N79*P$<H$L)GK0;4{U=m)v@iTh
> @UB<
> z(PL+vW!GL1!R*lIecNL9YW3OY-
> KiIU(7O73=c+XeUiV&nRl3Zwo^ttH74~s}99dyo
> z`ZW!B1#_|XzIJBuyZCEz?GvgzzI-=NP}cdl-dFrgCs3sJr8km4eV736Kh-;{hZTBH
> zo{NP4fMS$lErD43S@u<7zIMC=@t*PWIlVV~2TU=K?8>rRRkV6@zo#L@ObH
> O09+h8T
> z6_z(u<yUQbZ}EQW=U0i!-|Rhr?_u(5jYclP)atEvsr;Nu*WxV;b0&Y<O-!u)Gghv`
> zg7X?5&P}|Z{sxa`uPH1>ML$Da=PS#2a{n{@BG5$a=+Ahzc*lib1Y$RF&0e`*we
> Y%~
> zm@VvswVz{H(W~F?4o)*ujbd88Yi&KQR;dETwRlgO`X1%cAg^|4(0BgGbXXq$
> BGL@~
> zGKfV?%IREOGV@NYh0kNc!1SijySTbJhGXrfK}<iZ@`h2($#Y^IbwXVvuGwpI6
> @{_M
> z#iM4&G<ExhCl{B@iFHhmmOMMw!4UOJA^jX=t;E0&q#H_zfD)?|9^rkB%eJ9
> HG@5}5
> zU_#Lf05t$TGrM|@`beNg<66A$+qObQt{(}{I<VFIs*BQ?F?tt$v#PfxBqygIH!`L
> *
> z>K}!p-y8wEZ$_|@e2<V;SWrHNqxrfc-
> xT)06}l=SER`?)RM?2l#nrBx#zk>KH=#W7
> zagmu*((Etq!Z<nre2oi>p=&`n5<;OH=lCGxmxol<xj|qDWr?LY{75p6FSi>ihAAy
> R
> z$#h6eh2IW=sqot&Fcp3ib^<Ia44C@%e-TqwRe-&J5L3!?C``GsDvJ0o`l;rF^f8Ck
> zPhHo0uzm{B-}F-
> *4GSv0xlc#67He)nUxw_}n_PcGi+4E)Vx@oZxx`BE8kcQjezbQ4
> zRb-lP;4pKjSb8;Kg`!}1(=~k1|CO<Jb}(6)N*8>&SWboAqQG-
> oW&13>vm!t(gG~QD
> z<OtX;EJsF1<(~U72_$}ueAsEA)*^=9EB3=G0^gvkxg29Wewa@@tDpT;?*lIhO9
> RqX
> z&y<Qs4&o#fnrLjweSf{lxr)-8S&8;@jcV@0GNz7S%Z14;u&{yj^o6;vfiXX>_jNx`
> z=W=tMJbKEdGGZnl%6D+@NE?`%Go|wA;}`BJr`0;b!9}AjKQ!j0v(N$a+Fcf5UY6
> _(
> zZ&pd5If2uKi4%8|+lugR;gXOz9zL#vjr>*5KE(YR{=UWEqx==Ecc8C@!|Cg=_b)o
> 9
> zieL=Y(;=qOTcX62P<%oOJoGz2QE{JM7;C%@d5EO3{AhC3x?FF0{UW>{vg#j(&
> +(Q&
> zQWFZgPxVBh)0D&|p7t}uplqd~(Z(8F0%zwfWubD=efFL*&A+C<DD+j{M_j2JR
> o*$V
> z_K(w`vallcugb^qaU7x5h|rRqYOxY9IF?t@d5)pb&PS4TudbXObTqxv>)UJ%P*
> pv#
> zs{SATltOx@mnq~=KF2#C4>RhF-
> pP#pM(dBL?^4l#8;?FO6zUdN@+@D<;AD$iM?W7H
> zIo?3eCC2|q6Do_B3a|Dkqsw4J=V<SdH_)*8J4v}E%JR?AEQuXp#d`@mRS+g4
> mitaD
> zN<l?Et<aF3V+Rc?yc?qBoUL+hE-
> J^g#9u9xGab2t4XHBrSFI#DvafJu2|sXx1GcGO
> z0X;?_d=YSrR;gTBe#N_~f!*#A5UT&KVwK7c5(F~YPdC+PD=c&Il>Hv=;n8VSq;o
> WP
> zxQc>#<rZp}hRMn@Ra0}HjR-
> 9?EsH5YE_1p3@^|B<UKHcXf0o;bh4SB9Ts}9~RDO>M
> z;i{yitY?G~A599E+}6LBe#DM#;E0@M!MmY`DUFrwr(`-
> RAIBRVO7#kq>X4N(OR8@5
> z-p9Q|D!%H<sAyl%Pe`Le2INCy#L-jsRv-Li?eOus>2ULvzY6hwywj$w#LuGr4XJ$}
> zLsbwBGm_0UM|-niZy~9D8IZl-fHm(-ENa{AgSPz!_C+-
> j5lp0;%NU>YHrhDyJ4YV@
> z|3ilvbT_-i8(|<5!+eHXH0X5cVfJ07`Pr=MLv5}E<IVduV==Nm0$;rc;cM?<_gi|^
> zPd?gg$Z|S{A<N`qH;y#9Y*!MreEyaQlgmO4UT(FZ&I%@%WsHbWGPWB+lf1q
> ILM}!X
> zixMX;C$|;ho$z<d1Y@`#jCg~;al1acscKh>m>ChvcQG^ixK5m-Dg)l(7{RZx998Jk
> z`0{foicWfJeb7k`+1yaN0YYOV>}*G9evyTF<QFanH+S|TQ0`Qt{mnkh_D#xR0Eg
> R2
> z5+Q9UoSe{7#l(yAZdZe}^@(41?IWsgfH^Y+27&~adx2z^$w=qe=s-
> B(=GsKZ0>Yi5
> zj;Y};QOB7Udqazx4@bCM3+ghpni7*6Dq9odsm@E!5&)InKU2*?4eaYSlx)=Iz}{
> wW
> zo#P1BxPR-
> nK}wdw?8I6Dq%BPL{@L{b^G5GsW(FJ1j{lnoh}s}sH4T6qeA>Ng&|8(D
> z&D^0Cce-
> {lVVBxgi0P_jEZF@FwmQCVts?w9TP#mEYfnGVgNmqnf+PWBF@Dk6C;2_p
> z2XdGU@$dt7z-?@Bh|2iVlcr?HQRN&-
> RL8)F+}e{B%gl6_A~EU9lX)q(n6&sF<xL&h
> zlS&XGK>t@mDj(u2r@rI5X*D~Za*m04m3x~H#8b!8=NwVTIWd>Au8OBd>YX
> #z*{dlf
> zvG5@-rFALT>YcDj%76;YuknicHPr%dwbuzLrAepe^5kM-
> Rv)d#DK@k2rqG@g4%FO5
> zbkv&)n|jj%>+~#NdI?v(3AFe%x>VP9S90Qjom1BT8w7!7DV*CV%k|G!W<IBH
> &0f{V
> zL|bL&8VGh*_-hUfQ~L>?#0}OM1@Skt-fxU5Os>-
> t$=Wr>ZnRBlmq;)Uz>_|7i(x9?
> z(FoUaJ28{O5?f#vnJ#6<B7_QVP9#BmHjBeajA~rBP?d0P?%st0uFfUhyu4PQW
> 7(8`
> znlo9o#BJ|N#<d1=o5H%$P^A8JZ7DVUxV~{n;w~NI8C9?FZ%tJo@-
> 3div;!?PqR=vy
> z+29VH<(9pGX41-
> xgnmUac!ngDZW}b~xSISppc{*}Nf)NQ=@<y0IlfF3U;YYNUH7UG
> z>5{EirM<R5fIx@ISo^14n?qH}%;o@NU;WpBMNP?e2|eIdMZl4O`+Jn`&~sF#
> OAXQ)
> zDhsF)8UR84_EGgKkaIxTcTB;nq%WGhgQjpWKdFEl2?QPfm(*-
> >s#yK1*o=jgBW^{^
> z4vUaP(=>qk^6_Lro#^;YXWuTmG#u}P_*V6c!w!ib^1k&PGfS$0SNtUMEZ;^Rh
> dNx;
> zDniw>t(onb##?LFASog>>z40x@R@F5c!+dYvt3feHpnN8avtULK9ac)*Hl^Ph1
> @k{
> z2@<Wl)W%b?yWH`hM2wIA<d(?_cFt1|DGe@pqJv0v*QxHdN~aq`!88*W(Bv
> Qrkt{QN
> zRb@JRKJN>TAm;k#k03HTyLue$!)gSB^O_H+TuTe9Hf919jurqm_B@TfTX=*tB
> 6yM>
> zBB%|J<odD}?+HW?3TgIE{gg`c2VZi7_6;2`O~Xs$k9DboiKA1~b2=+!UPdvkL|xx
> ~
> z1hLsUCF5GXU(7I=VA!0I7$qi2OS0;Z^vtqMm%7Q3YG(Gffy|t37@HnXV=&Ldv
> &YzD
> zK%6#IMVvNNZRAeLs(^S_>QpJg{7*Ni)Yh^oHS0SrPOek(So_qXk2UKv4eQI?c
> uF6Y
> zW|3gr+6TpfP`NFW6%^^&+sg7+<S#8s!pAw=K(a=M8%ssycUdE-
> #oCdcLtQq|(kXq&
> zWHr9hR(kGK0c*8SF?7UJ&(Rv334tiiN~u{$l-
> cY#WNcZmG*K<BrS^x8zFBON^HK5T
> z%gND`;(&cHlDibPVQztSdM;fwE@NrpPu<?A(y&dzh{0tO;rZ#?+Z31Il#rr%%_^
> jy
> zpi=LF3#}6wA=sc1a(iZ!ku%2qDq}M})1WbXHKxq+Q?D+mHKU9x2<jf|7-
> (~)gav4#
> zq(ht1`0x}uW=I83dm(M6r)^A6vV~m+pT4Lt-
> clM6>4s4=Ss=Mt&pXd#MX7>}wlqT0
> zj1?<blMB20j4hE!=Q`y!9rV8xibUt^Yy4>7$0u*?ILWy8ykOj*BEI=mA;3Q~OU=
> Ph
> zFh!{MIA%SW;fv$vw0dh?e3-
> hY0Trnl?&eJtQ8ot#i?Tpeu}B74bC@yHP%@JR9IWyS
> zw?$ZGVZCMdeLZ!Fe`do!6u>P}Rp{%I_-
> WHbyhJT?@;2(FW^dMisdb#Ga(X6lqLn7j
> z?1Lk4ev{Ly$yYd%(vL1|GyU4MuSZ+Wl0}UQ&>i|(e^`1!-
> fB%G9%i0z94v?;x*y*U
> zi{SS0K7fF|XrExo^{}ax0lE{@$d#zp;|56{c87JK)%$YJXG|*-0vB<2kZC?rU2)}J
> z(oW<{Y-hRS2@Sc205{1|>v-
> xHyh1I>ThMDaKz5lHDYSiM&*aJ7J`H?1016sd^p|29
> z(70^IUV-f%h;);mMd96G<5imOu&{uj?u-
> =nj$wsqtj}rjKI0drZTmR_85nz}8PN#H
> zwteXqsDjD{(lcj*#@x$lmQ*JYA9td>GyDSHx@q@Cpt-
> aEkWJfDVRZcuH0^;%VILe;
> znBTP3eqo1hTF>-mYp%Y|v=G^*CGzFDds)~Ov=zQSs<W?~M4^1J%lpdKH-
> ^gZCJrqC
> z>!4)!cq9%MLCN*?>83swV#y5?IYR^?NYErjxpuHQmd<!lOiyDkPlyABv*=$33v
> 7{L
> zw`eTtcpDN}*JnZSfsUK#1}z4-{3`1GWq^Rhs(*uUXX-
> JHhXf3UakKY{XMO5@<`YJ}
> zc4_7K$y>SoJ3l>2CocG%K0-
> %U2sES2uH*PQ_i}xuOJim3E~ppkYV|&PiHbl9>*eg6
> zpkFizXpr^#TfFQNeS_-b%S-
> +A9Gt?xXd&Lrml(@clY2~dQiy&=l+c8Vy+@4{Tk{GV
> zC-asyk%~(C!bF{q1?vhWI-nvN`{Iu=ueS}RM}-
> *%;OSg(OTv1bbizV`V_YW&z;o3Y
> z#|oMPbi&fWkpQWP(W6Z#QHmtzL>R+vx7bQnA|H}Fs~)8U%O1e(Yw;$`^H&
> eo&MRR0
> zXvs`{B*J6$dFLq}EhZQ~dO?{~bD6ffR__!SPj6Nh*SFBvSU<&AladXGJF$9XGSb
> k;
> ztqP8wv6_ZG|M`~T?Agh)ku7jr&nEjSu&N4)`s|v6QQUmic}$q?z?8P?CDV<)Nz
> w+M
> z`VgM6KY_3w7GX)BH)yn_e)Br^`XJrlK+6Bf*Azs@jwTGh{>sEE`iny%()`Z+C&LI+
> zBGk=AYjvmAR8X!h>dxqxOS@U?mcUJ$0BCXu(85On=+1wqn-
> K4HO1@=*wj;R>O7X4U
> zH?Q?O<5$=En5x*kOtua<6_EP`RrpW}0fUBs!Nh7xGc+Id6J=(r$z2|^b8zo<U~
> waT
> zCFjofYtN^HlhOmz7JVT8WZVAafiv3A1HkFU0B(7NBAImnv1P$D8$@LRWK$eu
> xgP-(
> z#g!C_Yuuk4xXOxaC@wCh;+jO)m1gXP%LmiYpI_s*HFu4*HGdVwjp&#Ibk&P
> 4!5G+n
> zsQyR?<;0GuK&flsj;;-jljz(K$|x4+1|@&dFS%S>H}ArJ7!Xcm)jrmhP6$H@Y*|&Z
> zE`XRSbKgOvE57z&{ZHLjgmsraMi;K4AB!|8kJx4&oa+QvCm-
> Q=(`W*>eXEljrnM$+
> zCyxm|;1v=)#Z+*NW)gmG8Q6qa@X1@vbz@#y5)(@-
> xvzfnUL9ooZmJ3NJWku>(<l1Q
> zy7vq}Uw$}!rzx$a;k5gIrr0zMCzL{y&~WZbF4?8~e^<Xv++@KuiI@T-
> yfr!XQ+N}K
> zG-r5Ke<-Lo{gjDjAxN3M3--7iTZVGiG965QUUNjeYeTxt4wh5L!?jk&wLu+Ii|g2-
> zI==V&NF6Svt3#Q+7kk4x-k=E!;@;K=HMYa60#)a8Sca3^I<6^gv#<C@o55-
> CmP+<V
> zO^@@kFyj1gN%`5HVAkUTkr}Mpo4%N{mU`s~zFo7QsX3Be5-
> utz9u~egGlESRrqFY3
> zZ=6>vzl_O=%ea;(ZJ<c>K+*Y=n4ql4pC#!jG1uW?X@G~by$G(EZDH9%-
> o1MRMCA6<
> zSqA2f)+k-)p}O>RDN)fhGS~4s#p-
> KsBJR+zW{&a!yI2kAp^HQUdovDYw5nFPBPOlJ
> zIPmjJ6L*m;F<ualSWxYqX95i3u-i}I6qJMZufG$tm88wjK4j_1sVZGJpNgvS&l6LO
> zQ6%kYtW3{f;p_uYq@Nv4e;@Y)>+eIWW()JjSQByF<P{j%6Gt+Z?(83-
> YZ?gV0sqdG
> z<;Us=W3~<k=IjQFFB(_;LX9Try2zlk^lO{BE9JfY#@B~JnG4BjQ0VoS7@AExeCs
> X$
> z&P=~K)rb4_SVHT>Y|8r+3X}yLpdWDCsWSL<K3|MF5?dbE_|l{KYdkDVR#{rSGi
> -Mg
> zF4T3o=%+5*rTDaX9BYW?Mn#q-2d3S0h4`^|fs23#W*bIu7kz+wbXq-
> 9&%kkXb7`h(
> z1&V6gJm7$vu<dbGJK<?XVIR!w`J;h6$yIC8+B;2p*wql$iOm>Xe*TAx0F~6akv{
> RZ
> z!X-GZknIIj?+ISqZ4}1i2pQ7drRcRY&9JD#5^@kgoJtZ4ZguJG4x%Lk>9^=JcG_Ga
> z+xfEHFGOKW)kGok+ejtbh?{+vt3+XaH+}hN7&+b^iBbjn4L^}>3-
> 8bP#VYK+{eSGe
> z4SZcymG^&}7YJ?In?ef}Dg;`f(iRIvpoB^(z1RZLBsRRri&YV>g?a424ODHR<>qQH
> zw^!@P9dU+H5L9MlM#f=i)dtd1n-
> ;5vQZ;I4CarZim((#M6#_=`|NhoK=iGDCw1AKQ
> z&woDu=Se?3cb|RMep`F(z1CiP?X^+1Q!lhnTl{4D4L^~rllLutGKJkY%rS6FHi)}y
> zB|F`aNbwW0nGK4dc>M~N%k>CxIVMlBbhY3K!rgug6n1%X)SGXQ^S;3^Phrc
> WAY`KW
> z6w=UW2`dPPYCMr@D3NLtk*YtDsw$Bxl}Hsrr1E2Mh`ZO|m}dc#e^YV^g(Y>R
> RZ{o-
> z<n#RyceA(5$ZdhYa9()^)V8FY+Uh1jZKo_f*85kTze5MS@_&hZ>b<Y&-
> 6$l>0gMB&
> zl^PNfh$5uAO?>A8J*?1z3S~dRHW3*T_grH`B6)QEDAam@VLS{(lXuir5=7Vp*+
> )~-
> z9eP%_ji(Y#%{H+tt@Mr%f!mj=wj-
> S<B$=Z(_9MieK^03<qd#B3)@#%I7hIWZ!^}W`
> zODE?O8=GctfA5v7Uxp^0@6IY9IhucoTq6!SSfY0}x3CnhwNan?Rj#%3JB=TR#c
> rB2
> zy6vaA`4{54^v9K(SD)XM;B4OaSvef>{;T5amot!#oHYG+vxjE?GPC`T<J0V9)HVF>
> zwxe>dPk*gp+2Cz8m$1HT`1x(chM%Xdy=2wgD=uc%ZL3euU1))Yo{o+^tQRDZ
> 3$|A4
> z`>4L^hZK{HeV6_mns_x;n*DOa*3|KNX(U=FU3q1`v8VaUE3a&k)(Ndz+fg69Hf
> &9Q
> zZd9%=+qQ3L=iGn&+F7twY_kyo6+LfqzSV0<4l;jTIn=F%SDStFU`8$VWXPGLrm
> NmR
> zv{Rp&?9+j4+n`b=^VlB@b+_}uj*sDj>PPYRQv@>}rss0Ab(PEwaxJw>IRi4lA*N
> pb
> zb37I04U_6lrQb)F#MiTN{|rWtiTw>-cOp^uR&Ht-
> xQ(MdO6~G%d!nfA0H#k>M>6kR
> zIPppG^uq-6wcqC{XJtbZ&!I!X(=2{+{h62J?f3A-<<wG3n+9x;LlxTHq$;FZr?1@K
> z@b25*%g`}`YS?ziSk5*yT)6eN>Uj;DZhJYmU@J><T)3P{i809*2h^x#h-
> BnahhhVx
> zfgm?@Hv7Os?8-=8Ca5m7g{~Odsnnx#P4g7;6gpoabx6}RLWzAJyw*|TP-
> |}g>iv_*
> zEaY8-
> >A6kN0&<NVb%5s2y~WY|Lu+9RSLWVz9pur}RV^shV(6z}E3=$naxL^T^i!dv
> zEzT(sDdk>W>Jq;{_jZw0as?n)4n5Bq1f*{Wsg9Z$V7Cu=RWj*7aswIsiB49&*ZD
> C$
> znP0}+buSx}49T0N>P^nzV-liXHB@kU#xuR@4g<*-
> 4glEF1SjK{Zb?o6ym{zns`GaQ
> zmJz^r!TR0PyVI|Yjo+irPIr!-E1nlm7kJAXOj9nSLi70np3N{@esCUY88!|5%$3)i
> z8yI^2%AtuDYRC_@eTXv;fIWWQ`R!w0CXhO6P5ana2=pDfC~Kc`?-
> EvLcjniQRlfI5
> zIAYC&QS;IRW9~YT&nN~u6T;PFhNnkA<`C)^^1<1i*V>00ywCbyg4IH}p4BO~*
> V~Tv
> z8h;^n%SM|Pn9}(YA6tRxYE47+Vx+U%F@hMN)n;Kgz%LXv;EwNTiBL1!#P^xW
> $3Y=W
> zguDJtb8NUoV6l0I_abNRToF*NgG@f44pL%oGH!=Rfzjf{>ACA@_fXqt@3<%b
> IP|by
> zTvROO&$*l%<1BTxG;DiL+O+40+=R>$Dj9!j!RRV(>(MOi%X{;*(rBA37JkREY7@
> #K
> zS$ye_mOck@__4Cnp{regqe?iTQ@f#w{j_e)_pEi7C8sG+;XSy!tababk@9M-
> b<VzH
> zse??`0d9%CcjJtR);T8+*HNf6CpwV+wXf)WLBIEp=<9N^^zsR@ct$ckr?e-
> mepTBN
> zcd=iOAc4l0Ca_GcgRnH@y=P}C&sy)VdW6?A0QEjYQ1+f2?e6!^P?m|F;&13S%
> i_-2
> zJFQ*vB<j(uy1X^(`k-0ce_7TnTx-nr-esAeLgsXugLKVOV(;eXEd^#Vf>5FVN_$v5
> z7B%K!efK6Ntf`0~SQO-
> YP8RfM47$5`8S%xrJbdFD`7Tx~ncSp#7^Mr{nCwWAQ3?*j
> zS8<w8E_{6pl+<V~g8W+{R`!C#Z&DJzhXF|sd@`Pqj`I+Byk~~tk;|5$@lMrH%iv
> Ca
> zX+dYUHCP5On`P+wRDiC(VaP;ioMrF@-Vr}jU-
> ;;9kPcl+?47^UN7s%3U7!B4(6yuQ
> z3U3D<$oyX1L{PoBO%1-
> $Ahz|LVOV5Y#{#rBThW!+q6!LPzCmnp4i4U>m(U(uPC0!y
> z;^7MCSBKFb;LncbiAI5NuOlnfoaEE*Sn|d9r*?&T8zL4b1oz17#FQ9f$X?dv3~_0
> *
> zppA+S(mg_^Ed=4KtiF|eoszS>42|g``Zd3Nt2spe`)fu;N;o|z!PjhA2?tcd0axh*
> zVV?f@X9laKA^qNk54eH0KxNm&p9GJqWk!QXho;qgVyn<<H=1LKmjFZ(2s84
> hOv}&L
> z`#nfuEZHNgJ%2t`VM*za!4#UE^D*&cgc_Ws_rFPZxWm4c^04npzjTyK{0DYjg2
> VxS
> z^i7FBH!N}R-
> O^XM^xqpPJ>Qi6eTPfWRcNaGr$$Q8H>HmsCVdiA2JMez;o9%MS^MqV
> zNbSeThRXlLKaJ3SzFGT+B`#}!o!|bE((}#Qf0*>iBg6h%9?8Ph-+faSwZpOq`!C5V
> zB540X>D@PLzkM5_{mJ9P^aKA`LV+vaeN+0ihf2S+-fw>-aeyCvv-
> S^59DLW;x$2`6
> zI$!B2BX6hw=KKu=UP91St_)<gqjmN={n`gLhnjvvgVMG+8KW9YR{v%{t?KXtO
> UsUn
> z(!$7JJ#<>C7cIXuz<&0aA?PiX@6xLL%m0M(H_$cF^LJg<^Q5^7BUMrV&)PdQa
> Ul$-
> zH2%%s9CDSku9Yi6RlhP6s``})`yqkS{*+{Whq0Sfa>GUwI;J}jLf&|)y)SD9T8Y=U
> zGrcc#i*fjZhl5VuM-
> t1x`~D9clS1>V$r=_ogiR7_(!B$AXhOxReCPG8bZFv~<OV17
> zd?G0Sn~vAJ@=vt#Ib1Q_J0@DbgLdUB11}Ml-
> }g=x?hF^I3J)OE_33m#t~R5vJ01dg
> zW!*QQY65JA@~VvJBlt6C&Nlz6A?(-%_&e3dU-HYu2TkxC|8-
> 5c76IB&ILmALaS4T`
> z1j%LefWzY5&l(mtkYq>>D{5a0+VQB`p<`*ZLtzt%YX{pVEdBk^#7T5M44Wny7
> @C~g
> zKk(&%{{;)6s=R%{%MIL8ZP)8TZ5I~Y_<86Y=*{$(HQBKWhp_hDKD%*i@9YPhK
> YTx6
> zf6ay_HjTa9^}bf}ti-_V@1wQFESjZpzwhTGv-
> >}sRZLfA*N<IjYo_~Y=_aMmK^n_E
> z$6J$k$rRzHc59|bV8O@y&v|S1PIDh;@4P8n=q1DC>nFLidwFT{jttUve=C~yIo_
> JR
> z7ugsgW9x7oX{uadJ6UI7cIMA9L}DHFq<Z*%@aC+?S-pK$>ok^MZ)0>>-
> zU2_)0L}u
> zEFJADh13*OzUV4jc1XKJ;A8Jmfs>L~12;5r9?LX3EKuP+K%Jy|)9*q6as`Djeh^%
> 8
> zUYI0rNMdDX@sHI7S$Tb&SwV?OyY*L`E2Bu1zwS^j8bxxW)-
> msy9THHo`E5jaPx9gx
> zEBKYBx|5oceI;$0u-5F&w^JEt2bD#-
> !!k0R+RXCihdQ+nsRVRt@3>a&t@oPsZsnm<
> z^V3VMHmf}Sqnp5CM6IUMTf8m!exjF}yy<4_#4-
> g%>y@@ijKcALVAhdNm{WKKVRE+f
> zCz{t>$8>jsPy62F>j~96&0aFd`^Tm*oJ7j=%Ima@l=*_y#HDoD_r4tJzg<eJ)!nQ
> Y
> zaUrSc246#Vdx9y`OBI<$cFB4@OmpaG)*NKEFsz2wDiO-
> +d732Z>$2*<El5`vRDw;f
> zc3GWtWww9}>+W4lEvU!}okVzDytwZ6$tc)5Pi|8QB}J+YwkGfNS?a;bS<5cnV
> VPRj
> zFDS2H*!4H5G=!@&O$S=<U8#2~JIgI`F1@<`J>}_#X;l5vxBsKx^|MTsKdDbU$d
> {L=
> zTt>a~dFxJxn}Vi^7B3&9J#dK)x~|MdA0ueD{m{}O{8s=S5QQcXlq&*k@m3i7m
> QI{k
> z%55qyxA!Rs4Fxi{L-M`Jn|rm<db-
> 0hx4v&FPcexU$@?|sJ5{xn=CxkwxA6*BPk*nf
> zZESk(`C|QCT~9V>)+t5(iT>RWu_3i^of2yU5*V!cZ3D6(P#G=jS7!tA3Zy$Mht$H
> Z
> z%wv8A`GP_%J`S{1oU^pK`L$BDVwawp<R)j!Jum2NUK30o*F>c|Y}#)7U%82@
> Xttnw
> zsaXA5u?le2B+r<NeN+Md@&$z`RtT`g9V&ie4ppq6OU3##b8wI(?zMl;aPW*@
> pLj;3
> znVu`&6-!;zm3bsAR-
> tHX(WL_98hUJ`p#=eE3u<VX>2HPKP?$*X8I^iBEH!<h@zbHy
> zSz=cYlB_A87ezIDjc14+un%?gSYqJl6&`SGn@tRxDtaqYWBp`qRu{7lzE!2}^x2~A
> z63u}Uze)omb3>HtxPc%Yj<@^!!V6sIrFk|081Sl}w#NAW$}djX>85}w-
> 7VoR<D<W#
> z$(-
> 0SE&`?{jyO!a{jD)R8<Yv%GdY7owR>a48C~N(^scL08T8S$cPL*VFDw~BUbt=*
> zeCb+JnI`y9^1^R}5fI1=vpcy<Q>_ZPetst}&EEJE)Z$tb3e+3H=gcp7Y4Uz|ynWu9
> z>HRG^h62SN-
> Z)R_K3dxD&qdPi<OP3f?laSUOpe<Fnc>WuH!U+rB6q#FZ5wmJavp)q
> zkXKvOJ1yQgyO5pUd)GzQd&z0Q4NY87k{OWZGWXr>WCs0K0g%fp1ceDMd7
> vvu;&U)R
> ze(kT{<7efq$0rCf11;BI@nS?DCo^<H@7|ZT(2rQ|Z=>nnT3&ofp>Z;moYWGL6f
> #0p
> zlh>0J%}G+=6;97HX6)jKin2zB?BYC?0J|7!Q7h}c)Ae3Zd14nXz1YQ3<>{}cWy$*E
> zf~nLmeYEYOAt{V{x8bZ@QdoEQ(9kT>Nm5X_=cV^ZQW#gB^Qx`FqP{o#>_m
> Oi;{8*T
> zT1MVqn`?QKvaUR3Jt-
> McR6SrP)|+1Y6@JQFTuNV3hzxNjDNHQSuKWA6ZigO@Te!^5
> z3o<(~tcDIeMd)djlBkEvsy}qOUy1*`&__)~Qcy3cyZ>Rc>+Vh>yuahcmlR55X{+;
> O
> zP$|D=ZoXS7(lJSa)Np!bYF&R)dHuq!zfh$?=~d0H>u2aaud*d1y7cP$lgraDSFe}4
> z-skr5_xbHR!nMyNg;UE@)=_VN5-
> h9v^Y8W3KHFfpK~hlV`J?pd<#{aM;<!GNgDctP
> zWHSjHJl@Zo(9q<a*<`KCT3+c6%h7}a8L&pWYr``%C#8ok6#Q0`Q1>H#mCkcjI+
> RfG
> zgkMoanxM*YZ}u7`9xfCJ)VMRhjyn^8J1d>I^WzHemoF$J?)+OQ*$D*#igM>%
> UNG=v
> zKuUabM4>?SQnC8AViiD0;%UV`rhpZzP?S683YI1!i{$cx8L8NVgo2NM#&A#)3T
> _7N
> z5uxDGuvmqntt}G@as_=x6!>klp`lQ4G?|tO1@ZQ4ncX9TLA+f%4`s}M0=$!p#h
> GEa
> zHJN8cs-o{Q#D~Hot|lgsdN*8S4G6>uClP4v&cd&b9FWbbi~j}Uf-
> Q(6c>j0aSwNDh
> zPzv?lRZeXETAw1bLcLB(aYR>mkQCrR37fnL-
> ;~M=bKF}ReG<N(_;iP!G2J|_KvU{n
> zR5`CIBQUGVE#5b;wkkiz9=MaL-D*gcW)&-
> $r*B@m!)kX26rq6KeXKy38LM7isf_9*
> z@?$*}$svkuNlmV3$Je6Ys#2eD9Q<1pqU#nUH$6~}jVR|0WTU!f?>?>qHo570
> =h<`s
> z?^MV5hFo$s;<)J)Op;JmYJ_-
> 8HVIU6({CY^H<p`#8cA+ibOlpjAUBzQCB6T`yeuUT
> z$Z@?a8aHv7WqM_|oQ^!Y*BIC;x;h!#PR~|&$xf?>bEs`#XL-
> 9eY9jZ~g@?dNPr`??
> z@G3XBL}>69L#&azA$I6)KuYR$C1oNdz5aArNr0W@Esd5G0=trwh4&@gzknu
> eWQ#A7
> zSH885qnYT`aC<qQcUca|6DFFf1E5t-
> WDankX^8D{v`|d1PEO@C#jNYaY_J4mn}&k{
> zBp4{(uN+8-549pbDh^~ZHRRw7UPD%3?21K$-
> Fso)v9pP77Q;C#K(cjx9HKmcafRpo
> zQ5D3faT^)r=2t<Ve9<X1oSkBXx#AR+pvyaF?{p5h?aoM|Fp*Z7qsa=Z60-
> WcAge7@
> zuB4xK*5z!Po0u08(9`DFtS;>QP#;%<r}_Sw1tYn)+XOM8l)~xn@(CSdRsMn>W<
> ;1p
> zC8+~CMq&ZHtla~6cP7H}&wo&`hspn-
> +;cYm!xTaOhqZ=$<pW`j0{Ec*2j%~V8_H@F
> zz~dvp>JRC(cvl%7%?Hzn-
> |sy5J5=PS_boJM8_Y28LxFx2dzj(ymmCH@y<cbFpi_()
> z;_Jt+eoa<ZDS1w65Lq-1R4(LtTFCyu>I-CSWuNLrx1By7EY%psrG2Wl4Fc;xYoE)X
> z4zqlMQw!Mk;i6vNS~%-
> DNtZ1gO=)IrK$#pKn`UJS=!iLqf!pzKLltTpnrm<4=2C_b
> zXY>wKURE=wvG(?ABKoTOo-
> Q|559pKi+?wI*xh*}1@PCp0sAt>n^8)oMTeP9SW42h1
> z4R6=Ag{OA;zi87!&2&t1aqr!_n`xLNqnHwGnD&~9^fBR8$$q+SZmDa;gUHm?d
> r7}a
> zYh4|=Y~A5c&Ds#3=ZE{w(_So2e=rrtm|^zzxz({)XZ*fRxlPaHRAKGms=`_e=Mv
> kr
> z7vRF>3*TVc)>7C0tbbPTKc_Nc-?X7CgUy6-
> =kOq)=ko7%KQb4iH0kj8u|tAxr@Yhq
> z<w_><M6bS-t})3!Kz?vl<;qOm|10AO6;<$rZO0f-Sp41SOzlHn>UCiG60(I5KDh-(
> zV!3$x|Jl-YWhRri{_>5T-g$Syp)98O_M=U($!6~7doFL!X10Ci#WO#kil|$O$Dg73
> zzTs^CeY~bS^c+gfbb;4#OP5#7rdO+T1q0Z7(x$yfRB{cEsgwrUj@Nokzy050<HA
> Ds
> zE}YuEr~B3TQ_pcE=E@QBw6bKrW0^Y(p2}LY;K}CY+*En$*YYeVbnpDBoxQQnf
> g|Hj
> zZR02fn&kt;3fF>Fm?4NxUZHGZowY?zAw5|MqA`z-
> ApJjlp2}X@s2%AJ2YIQt@LwZH
> z58)lsm5X=h<37?S2~Ye9>6=#w>53^nijiwc6v(f&dgvJu2#$=@<Erv{ILJ%A&L<-
> E
> z2;p5lOeXm4xBPlch}7c(tA}EW_0$7RqzdNGzXbwaTNu&n;$`RsSFYtuP@XLDp;6
> Ee
> zF*Y03a@lu#9s3O|M3gkXwvw0lQwE!UwSL8^euDIC%kO?${HcuP@#LC?P-
> %KkJe%*Q
> zJJdn?wW10NWecDYl<9d(=TW)5>J@+TzM3TIHoaDrEhr-0p(h^Fze38{o$B-
> bBvwBw
> zONA}Vyh7Rh8cU+5a6Rc^>+>ZMT=y}eB;ELZ?jSGq7XM2G*CD*awQ}*&|K#J
> kj=Y0D
> z|IsJa=ZYylF;1gNb<Jixs*>)|^T_yTc8=vkUN1Pfs~?*PCJfQcQ>1T-
> KWW%*@tXdP
> zWbW|c6SOIBJ!hh82=W)|1^Fll`%0U*nl(9JW_W+4N1OK9Ogl9J18X(C#FC$mV
> 4w(j
> zM=&73Slgvu%eNyK2;m(Dl#93eAAJnek|Mysj!y^!iYb1ZhUN>R5a$0Hnq~CS?
> 0pB!
> zQ0L-y&VB@*lUjGVi5w##-
> P_l=FPvz*m9sym7XO+gK5b<S`#@nXqi5Qy$2wbq4n6Dc
> zygZjzApYd%uLi+GQw#I>VH-
> WYt%^gceKQc_)7v@G)!%nAhbhy~;t;=|J8KjDV^@J_
> zfne?n2-a5p#gj{gre8awZ5qNI>#fJscycqNrj>}IfOERLKiBHL@{4S%$Ca-
> M@0QNd
> z{;<d|uIVPWxQk1Oea2VZM%eGA^uQTyC+2nj;d|foGqwf8O8AyxKsU&C-
> ?EeJtXK0_
> zRCKeZC}u1RqZf8kX>u;3XWCnob%74Oo*DnlSOy3N@(wAh98zvIq_{JQx3(P{Q
> jYK-
> zy+#QSb;855pavMbH~n0>vL)C&D*f6yZQKLQ%utb)`-
> =Y6+hZV6306lE%;vV<Ai>#f
> z$CV}6GjunjgwA+>ko}FR^9-
> 7^!5>S_0NBn=ew_1fe)(;>x1Cr3mg{OH2XHkfwc@4u
> ztoT)$OSh_r>(#>m(lV63w5)j9=y1+LIRRv@plABUi_sh?(4psf@z0z<0<`A5#GhQ
> V
> z-%yu-T&Uxot-Z7O*cQ!K7}!%sY^t>@vr1!$KN%`|C;x-
> >EXwakiH@(gAGD6FZ}WL(
> zeAeWMO5O*0C|mAKlsMgCS?J7tk4<r>8TI}3-
> v?PSxewi&*K>{K!K5y@d_ft?h0gV8
> z_$<wbU7BoWx#g>;oOkB!^%FSsJ3cpY!ef{!XmN*!!1?2SLfqZQoI|68xYTL6f)cR
> G
> zl0a>V<4=$J()7*G4cJW{&hp}<KnNNE7?Evvv5RePI^$GBpHDSp4-
> v5b#TtaOI^dhX
> zyLBwDJ6q5zXHj@&bvGLvma+0V5NU%DpZWBKVf~|ahPCFQNotBt1Y3;|s<Zi
> 9Rq=vS
> z=PVD?W9XGLJ}2V5gb;E&FXM5o!HY=R0)5-v*XfOe&%KIB+jp%Ma#R#y*-
> T0q=Pi3H
> zM3<IXzz%uZXLnS4e6Ao^P16=2d;2<FhLO9A-
> $azP<~{xm*St&;Xz#=EKVtnJ&pbl+
> z;@T7x?E)J{6!1NTMQJ$;WivObfDS#y_vX1-
> zW~+)0rMr8a%9$bke7PbF|UOJW(e<Q
> zedXfitWp!YGBxC_Kk==f-
> mY0+F~yD0ThW8PXxQzoPaTa5DdKO+<;4kZ%GUIa!)p>j
> zwj6oNWYs9U_ylQS2Wn6tN^Gik@`sJ!d5qwEW`okGTQ_RlNLeC#scsq;>zi)6lZi
> p<
> zS8s09C&N(PY9L8)m*!Iic$YQEUGtN_5K?M|AP!!3uikt;30k~%Q+lv!w8e^?HTT
> *I
> zvU~L=0c0CDYDr;vu;fi|uE}!mcw$0s;XtklQoCB!)FC@V&kMKd0<gp`#!+{(&%fY
> _
> z8+ji@5hvi5hk71ggafe|_h`9XrJdZ#HtJSU%hYMsvU;KVZ!ItEY9HEX3I4D;On?Uk
> zUj)0kZHA2qC2l)e$!>I27;MUo?Im5a_e><6R-
> RAccx@)W$7}+(7Q)I(en{}wG&YzI
> zibt_J0x-RO9s`yG0L-MZzK;iio4^ZW8A(&CCdk1AGlfrAY+?Y`;wH~k1X9OsP3)hQ
> zGuU)z^P0qOSZ&flvAz=lRX!y&u)ytK{j9nVTF~?%PLq1O4VH%=@dwL73d$C);9
> 2~Z
> zQfp=qHv>+L`%@#pea4lN-
> cz5NFIw9>FU4^zfX{Tm_kSsyDP`L?*$O<`eT%Q}EdOe^
> zDw4wqmc#ysty<+E$6E%^xlglqMl+{XoK#4ma#agrcb~W7sC0+Qj@>>ZmsjAG
> pXaP~
> z+%}D%k)KCYwy=OFNyqAVjo9`i2kSmN_z=jjCjPBC9mH_!XF<8(_KRn_7oz~n)
> V&5H
> zjErM_Z&R=Dd4*mdKAv0_W2_==jEsGN!*|xZLBqhZD;&Es+wUHSe<I2mW7(
> %Zg^J@#
> zEu0!u*;q2@Q;YYqOprQf;q!}EAHv`P6hyN(6^N{5<l2?)5a^t{j?NVns4P6l6BmU%
> z;b!;d6<C96a?t8ASiD&?S7N=Jav6rsS%M=L=qvRO9degs!N|Y}byjLpn3lM$v03J
> v
> z5)qPP0J;Kg5BTv(=OUv_-cw^C?U~@ha5v3xH_9TX2a(5Enu^pIAnW}|<i_cV-
> P1W$
> zow-oe7s_kfCPzf+TwWiVm)3h@t0YU;MZe*`Gmmc$?`-
> $U2&#r9yRxYoF`HT5Rt7ZL
> z=;UO){YUhiS|9)H7DD*JqAc|$2*?)BSB(<8vzc=g$lJ4^r*S(4GTY<rS%GH+dsB{k
> zZ}L0gPWU*}PYbTiGSm3dl+VxN2mgdWCba|}6_m3QbZe3ebXe(a3<3eiBpEzG
> K!1Iw
> zMOH+)g1)!-S$pqt4Jv*>a3|!A_n^D2Vb<Mkv#xiH-
> (<IhT`|=<qKa`}T4m)5LURjf
> z{yHRK`00(MCdx-
> cZ<BYl?H=H)x>v|4{;*#R_YqYxHPHo*6qDZJGiEJL6&5Yz@(N}1
> z^+2aP^c0g`_kb<Ue$Sj2FzNR`s@Wr4oI1!$y!8|lGU*WBF=^%E{U^s^NY|CAB
> 5(bP
> z1)POUle3t<<9+6viSb?ECfYZ><r+6&3(__lSd?Sy(yuRw-95A*_HF*39!tbh{9ncY
> zXZZj6s08y(f;0Sy*vowH<Nw<TpThrGb@ixf_g7I}SzTSl*~NDP|118-`2S!0e^ue|
> zLZ%S|y0WRF^rdp$XR8yjhKfY&Q<aI>wMQmmzb5=O;+pxL!}}Mj60ryPUCjT_
> 19LgQ
> zH}ik~Xv!KlYFvzerN0UVE5}v2nCfvy97&bO9jVuvqehP#H)dSzxN&0x-
> JpJ*ewqab
> z>elq0d72h#)1PEFBaXt)-%zMyLt&YLRN1CRt!--
> 5+NOq<O}X*+CTiAH;AEr*pK;KG
> zSvl9{D$uU*IXg;=z1kN1kzkKL=GW><l+lC8oI@-
> %8tdGFG`z*N*7<4bIR5EWnN~lQ
> zjrW+Me3o!1m{pV8QiwmPZLc}dgLDRnEf)-#Z;Kz7Z2E)t)s@;;7qo9ej_awEj`l4X
> zRz?$p>)whr3FyZxm0IFYCeS0|*~iMlkYDb2n1HR&dhftPH0%5`bcN^y24r3H(u=
> $Y
> z9WXo67^;=Gr{>|s7uyv#u6|3ayvmQ6-1Cs)IS;hl-i+JO#Fy{1S4#x!aSoP=+t0Ps
> zqn4kxqf#d(7e1>2xb&)IuiKaFW|)PekIkV~hPZN%?v~!K#4=Zj5;8-
> 2@d4f!*3wSp
> z%NKp~5G+Yv`Rrnb$VP!*Mav(3{i6rz>kk}4U+?o?R4xtGQ_;uXIR^~<<Yq$%N^
> nh9
> zwpFy(d{eNDL)T)e@xVB*%6q{<<1u3&Y$IwYHnP6F+0Pd|_HuQD$TmeWZfRy
> st>B>A
> z+{x!%hO{x(8(?<wJ%2b)u=unF(L#c{{%J0C*RBx$pcU(F55d`hnP4lgG2RnlWO=
> W;
> z{@h=K)xcbpHre~+bT+C_^q%2|+>#n^-lxs4TUC1Q6(DF-
> +YBQB_9M0DBe{OSW@(%j
> zupKv18L<_vquYH=eN$YbN+~^P=XI`<Zg|F0?7IwV9m0e_HZ?9AXg{9b({JQo!-
> 2(z
> zlw)uhd>BT9{@!*_e;?{T*vQVW+gLd<+2aU#NpiUY72c6wjS#YJzRdJ)=j2|%LzX
> (o
> z<aK~sV()8TvJ@PJy^}VuiQRk0(cU~uf;LP?WIw2Q!(XM_I)KVP{?RfjQzs6hpfW
> nJ
> z<C3XaA$8XJ)OjK^RmhpWzc^mtvSF3aQ_}+uqs_}*8PAv#qGoNc3)8iRX{kQr>
> An4E
> zKbfAGR%+xvE9k&0=)k}W%_L`l!Fj2_RYR+C{oaTF4vBJBv7P3zBo)&v&z#<d8pf
> *c
> zFx6XVne}L%79CJb@FiNz1*;Jb=fz@oz74>J)}A}Zdky4I^Bl45>kBJV8CK-y52zxC
> z7<)c_>*h?W;@qp5|6*+o$+{oNY;c9lRGfpa)Z3E-
> ^e56Yq^5)PP2PXp=BCB#NYhoV
> zltP<#|Lw02&8b#o>Kx|3D%~I*68=MqZ}RQ~20Y1!LW*NbIO1Y$?UX&B-
> {0{n9kUE4
> z*npnBgXp>U5c3y3XRB_85L#7kQT>v;)uSlC_SPi`%}~~S6X4{F^dyA>QoJ5f%_l
> OE
> zZTvI$(?)3X`45-TrpE4)qkP)zF&V!7cpxdUVXUUj_-
> F0~H$ngAaAx6k9~TfOe2fME
> zzP_a*Gw*&=!fPfqmrJeC9nR!zp|Klzlgl4&uaSFrt^}2<VJ@R}x&V1+#naQPFAj
> oQ
> z?Ks0P5&mqr^oV$KtvxN?C#{wo$ln)h`_wR!MC%$)_x79Ol>^b`lT}ckOUXI6aL~
> j7
> z?Z)EKiuxeKC%UN*@<wAf>oX%`oG2lW`}Hwtxu?l{)#^0-
> R+cJn(}xVBj6~dU%`UH*
> zeAl@-4|%~KBBjCO50O4xpW*)R=L2q@-@}{}-ZP=|0@mcC0>05;$gR-
> qN_ocz1NaAD
> z3<mH+q|eUcwxs*Rj2J{k`Bt@V`b$?1T;}ZZEY^fs+z@2Z8fF1~Jq;lgk;I3J|4JxA
> zTz5_z-fEl4N;7=W&=ZW1``s-c-
> oX8(hW4Saq+`QYp6a(UoEQ53I%wY}lG(h_cb4Jp
> zA(tKPnH(VFsSx-+1BPK%7cXa`I3ybn#%Il};r`*?;QkQfan;2ifRS+Q<#=JJCCvy$
> zri{FUd+7T2)jnMti{gqkqwd}o?*X)Lh_?rcAUC=^Ag<n6+c`GHmgq;GOAeaJHx~
> j#
> z-
> A{i)2(vX!l=@=CMENk$M=a4H@f1vG0luakgs;QMW5@_Yf!J^X2zrm%!~_WPm
> c#Ti
> zo!aWrrWKoA!&u(c4*VJB=1_K6#)MAKpAi@mE^nLUb<_J@vE|_0D_C$EL5VY
> #?Z^zp
> z+T)!@v61tEf$(%<a`9i8NPJOp7VHH{qJwb}io^k!3}cQC+IQqbnmu(JuVrZYWA7
> 5c
> zhFRVmWVv*tEafuu3QYlST5r4KI|EGe+>Gtpgbd=RV%`p`+p-{|lgl!aC(D_h`Zttv
> z9At6==`6AL^g3$|W%Y_s5jbq>-$21E=y@2C`)=4e^zH=4c;;bVxL;b85^skcJ!~oh
> zxz`?vG5S1Nt9&6cmXsrzpyEl!Y6+=2zB|*~bziCCC16)~W#Lr@b?-Y}%xI#p-
> c>Dm
> zmO90(34LQdnNqm+`<6gqe;}gXq4UN=caB_NEjOi=c+jwH*T@9*-C*-
> &pp_8VEN^O9
> z5RH=^i~%Rxg==Nuz5jF8NON`4hszP4Ak5pNbK7vTPi@Jc2gxD0E6U3PH?zDAU
> kDmS
> zSs}11O9bn^@YzUNteEN70hHbc8AAo@GyKO!r0AgK1Fq%2kJQG^ujMU2BU+
> mfIJsLb
> zR~Fti(b{0(dYG2K94V{C=JK#CYxz@u6=``0?8>s1|0W-4`B++>o2Zs&#|Le<{!h+>
> z!b@|BRyGgULpkZWdb&FT&ku(~ZlYqd6Q}X)s$Oz25d3vjPZq3&W)PB6-
> >9x^`Rnv0
> zjQ@uOeM{$r%4*AumH1c-
> _#S!(Z$A}5l_IAvL>@V?8bu^I%8YG5dX9ng<_UNy?0Y_F
> zMlc<R`Af!WthLkwz;Ajn&OYV_>a+^w?(-
> fwPr0}TO*dKXjkj@=&A_QTHaX&8jVcNJ
> z@p7TbP;7(mVz41iOrI|y6?3&s#khII-v6<kRm=bgcKNk+I?IN)9k{ePdiT)iq8gGq
> zW=pPhiw>Dq7q5XM5?`6v;_M7%%C<v*3kO;D<XU$C7SBu~C+yxf4ale!#XgrK
> UUUaD
> zdjCZ<4MRlQle@U8VLtXSTZ!Rw{p}z4u4{Jx^Dn-
> #Q)Y6FyQVB&y}*UITw(!t&~umk
> zz4NPPpl;g5b@6LtDyukr5^EKHY<UhfQ^c>c<NI!s61iA!Un7~{w_1u~KY#z_jfy}
> b
> z8kSYf6s}FCm}ct2jgNHa09UNx9#w=P52}ik2h+wam5n<bDzOSOF?(Bj<u=31Hp
> 2^o
> zcrVCn6!IE9Geg8ua$f)~%L;?;cF<cY(X}VGknyHhrLn`sPI-Q<-3_hV;_Y(4BtuKg
> zE}N<vn!$OO;k>*4_G^7o>weyQr5mT-pmWNCdl$G+R-
> weM%0&0Q3#(Si%o$vFuaTv*
> zBJl%Uh2Qf4>D>;qQKWaj1*CVE`n5agSBkKH1?j`GiXt7;X^?v$K)P(QF(?g?ejtlq
> zI2^_9)g=>&?uG;ik$xlBxQ%5>zUo=FuH`yT_hD7Z_S(W`7Or?*Ptxk~$-
> *@XL+h7S
> zH7o>;orcD3^|xPTsM)6K8f9*~x4CK+=H8;xZEKoEn-hH6-
> 1hv7jL9*MGNW;#_c3Mk
> z-
> uIC=&X%36Z6z!#=a3r9KUnr7Qaml%B1gDhr493JGj<d`Hts<XH+Cd?xV$o+Spw
> 41
> zb8Q-px6c;_$IfDI+_Wd2o2b~z%a{QNlTsTbQME&HgDl`DF-
> N;r8uaroJ|x&NO*Of(
> z3JA}ZIyWCpg!1cZU!zf}zwpbw3ojA*1%PW7UgA>cn(;9`{}N$0h^R{Mecg)C0JI{
> w
> z<9rB5jpS$5(qdC3=jPY?)eDl!6Ir0*G9QCuZSLPbq0**&my8J=@32-vx)Tks718X?
> zTq6Eeo13U48rl}1I~t7f+<{pZ6X^u0(jr`m?+;sD8uw?d@ueBupTEz)aySFhS%vh
> b
> z<4i9H1#b%`2c4d%U#Zg$xyBvOdl-
> 1JosD=r)Hl(;_kwsRCH?Hs^DkywyB`u;WHG|h
> zxuNmE?WZtCpzJB;-
> MO`UN^{ki%^VeCBXJ+?1g`I=4l<t6otS<rlxAN;wXz}yP5<5$
> zjwFz2_mqWIW1h1dbn60Ka9`i^A#gnN*UH2djiD2MoY7>L6}Q)YZM$rQqOhU
> bXIIxN
> zMVS46gxR-E^mZdn21_jo<(qjYRkNon8l*U*>X&Kzf#3Oc>GOxo+x-I$Dmzv!a-
> X;v
> z5haSa-
> 2U{+{X>{?i8H|?y^uNe<l4HYJYmda%um~9``4^+(SXKLqc`P>bqo9#!L1W{
> zkNJ^yME2X}!u~#(bI6B#LO#5^E3pGm>JiC^A=Y+0AL=6?x~HtQOwC!#U~C0?r
> ord-
> znmyDGGko3A_X3@-
> DQ>~DsC$rC26E%4w{CM9oiZjZLld7#_ct`|V6K#OV2+k^{;cO1
> zHpCV%>>VLb?J42JG3=ho)*b%D-
> UIiuiCuBS7`C6oJ~8Zlj$w;d%Ncghl*shelMNX5
> z8x#TW7?#yOW7zxNkYT4+?qXNj@d|88b{ntgHQ}W<=kp2#nO@@+iZ@;Xw}
> %H1hF8cv
> zb%3=_I!t2DN_YiTHjxE7LW&7^g~H{$0!av(7Owy)KCiGiQDDd`dW356iZ{yEtRO
> <H
> zDrfNuLqt@laRfeQ1Y`>%m=vj9yTmaDDkWF$GLA7&sgq-
> n);2qwG$6*Y%{B&s+LpZ-
> zQ@7pn9ltv_UI(F2D~@O0u4j-
> n*nEr$5B_Sa#RA&6U{lkg{%ol2&oZfSqNK`Pxta`Z
> z^JBA3jt$k4<C!SN>NmZq?w0Lr<=HeFnbDm}%dL?#A&80*v9tc%Zb>)SWhW{
> ye9j$A
> zZn>C+2RzHyqMJKh%nD#y>~Aiwb4!mqmR2QW_2M(E0pzf@3FfCVE=HNi<-
> @4_*?bwy
> zEo9fQr1BK2K@l;BFA~eFR>9R-
> t%F_o>*ddC1U4TQe<4daUsr`bC_in*`21o9EQS1W
> z=P!9*4)b^U$2-(_%nXgYp4(%qfgZEA?qOy~^n9$-
> )&PyY`TIuM8UUyH?%r{%7!&(#
> z4$<s)(aL(04ENbkuxX@qz{p==$iMG7sBqI>_LOTXn@|`Z5Jp&GIe~yvZw@DPy
> !k$Q
> zr=$oDBW;c?W45-
> #c`^d3MaEveN$D`y!M>rPb@0yXu?OjzXSm>N*XltQLDqiEo;FjG
> zhFVvwpIB<*5<{o9fjux&S*e1$Mqps|=KVln%!w-
> 5rRe({qhR%>0cvBy;sJ7m7fOOa
> z7(|wL16jf#8DLxHz9Mw;wI=cvuEMFF-mV4f7PyXtP4srP-
> >Vs)%n^xt5t=U{^4|HE
> zRKa_C*C4%Y*B(5*R)uM|R3evE`9gV*6Uwy$R6J5H{KVgP^ZT3amb!H3ai&X$>
> !QEs
> zkRvUlZf;SDM8Dq_l?PY>1pT}_?B`zAgxvfG*1;+x6Un8u8&o6S+nzKYqs_p5Ujy
> >~
> zXLY2N0f|2nxL0d;Woyrz)_r$rG@WIu!k&PYNHJn7l>xWjWAG1_ulEK@>%9TTJ
> `ikn
> zJNBWFV;{RKTL*mhvAeQyz}Sc4hOrMnhv?E{pqzbJ=E00+`3LOd4T^w$49hCI^x
> $G`
> zFs&=KZN10Ph6EI8>%H#E#-8cSuV75JR-b*hk$Zn->pr9PLt;xz#YUK?ylwSi3loKH
> zv?<=04MjntghiK{3d$BH;235T;0vUJ!hqQrI?EO&AQ8GLUzk{&(B+s-
> &@o~*Z<H;}
> zCW1KSTw0iveX#6D>>8~@#AXJ;BO}Y$4ALmfqu&HK@ez^gzHHNA@gIyfk!8E
> %`7fKy
> zg4n6=T=9*xr~|Wx`OC=F(um}{t$VbM6o}Egm?w>LceyookFCh<x}nCNV3|FPy
> vtDU
> zq@({+$lL9~9SV87P&DNyY~uU~IQQpLsKCNTvx?7(g!>sn7G^kU$`2-
> sPG(JdM1(Bz
> z-
> Nnfb;C3TxNF_n1T6hhLh@IgId)EkrY;lJqWU^HyR6t~W>~g{wguJUXnUoW9*@
> r_D
> zazBa(5psWJqi796HjQI2mrI~=@=UnCmSfb1Y<b-
> qcWcbbi_zRgm)E*8z?RpJTe#)5
> z=YYq+F-
> )q0Y1mp7nIJdOEw4W>Zlu59!@bRyta@=&@V2J;l3;<%;(DRj)5IX6D&70K
> zD?sy+6~Mx6sO`h-
> bt0FHy6c)Cm*E0VxkTmiNN<`jeN&U4&E^R$mbS^;+vJwgw)&P<
> z%K{OJ&^VysYxVwH!Be39HIZU_6%BK$+HGB#``E!!Q}GFsS6J&U3vm9E*9Kdq
> $Mb(h
> zBBWIloHnFaZqOAr+WRVgN*`Lc<)k%*fH$n(<W!^^Et1Q;@tnfGmo3w}5|67
> Wf16bY
> zu{7(T6J=+#KAzY4OW)wY-(d7bEIbL4iC@ct!jjBfphK_oRvyFgRu$Bqc{Bk138tC~
> z$JbuXnw5ox>a1P3VwbI9`{6qNx?d+zJd^gk^h&QLo<B`|2(3;htwP7Od-
> W#CO*WKw
> zr$33Y9)d<UOXAe%4VW+t727OF1b1^kuqB(3!CNkGW^cGAV;^UW2@YFUui
> O%&nRkue
> z@S4)iRk}cY?7OI>r_5U`t#KFKg?*`BZMwBq=h_QurY3p=%(mz4edU(A72{109d
> A2|
> zqEu;$dR0a3)QqpWU<-
> Qa2CEviXXAXRxZaon>}rdX`6S8QGm|g09BvVStuwG5WKqeT
> ztv$sqH8Qa=SJTkAA0RfZhl;lt(8g?QCyr0}?)RF7B_+E+hd#}V=br-4U5Up8lxysC
> zN6KN?ZUNrV*cosCtv(e5o=ZH|;MyH;*VYi+v!Sv7wsFjbRB2T#Hm7yqw$U42R
> xN&Q
> z{WoxG4Ab3g;)z`26X{Lp-n0~3z1h05wU-rIL!vizJd;;L;{f()b$rF@viEgcr|s(d
> zcl*){)%;$0+C?VFxfQ+$XMKYA6{=R=Mb;$^dDR)L$WM8(RrMk5{F;WuZX)sWH
> B{7A
> zjbv^eq<_q)@3G<_iP9?{i>0pT3_0QYmDAkhW!XLNjgiCK18$+~qFx-
> +x`X`%PCnW@
> z^ROilC})m1$faybv-6nN$Fr@ELkI|BAebAvhas2R{Z6&}s_PTP_l8zg`M(vJS7d^F
> z5?D5M7EdE*#&E861CnzCs&L)+?Oq2PoJ`OC4Rpa!AIwP$7JA7REE`vE)_N-2x{-
> sl
> z<nkQXS?ae~WH_1Lc}K%|9lqO^Yka(6VHMfnqGd>3w9Qmy+lq}qmhBnYe1|>
> d!h`nj
> z4|N|N2Hs@K?6glm?3ljZcCz=;JGBv~Kkp0+Vx$v8XNXp?s1rxpI39LQhMjEEZu~
> AK
> zgKF&T0M`SA*JQjmIqiqG%YGHdfFm2iz+C9PbVpd?1`Dc0ECO7j<OEW>8#7+~
> OPAPH
> z<`Sdv!`zB7%0D2S=%FIZ&bBS}_XQRC(I?6((xZwjEmh>5(Tcc4t|H3E`%qa$M2)P
> z
> zTD*HlgPzj$dxyKRV^pd>FejD;59_jKPc|kxEx>s!RH2u8-)s|Jgbc6Sf`phYqJ1`d
> zCr#UMmNo4ILDODZ9%)*c$%VE}o4sGTYTB)F=r#{!2J5dM>!_d2N2m-
> ~UeL_SBdnS3
> zGOMAs2CpKlC^!0@?AIrmrM5wpmPD)M6VocbV>I28XBU8J0Q;f?h%1kVW`0
> 9$Q=AD1
> zj8)uAC)N6!ybQ;^K(foE@7=UW&KhuiX`UK#RpzN7{?rw9Rp~u{B!1ItY_-
> ;;dr#Wb
> z%dIJeB}gG_uBbpnWDQkjH0{e*GH^XHdBxF&(=(Huj&8rgPzdQZH@5p+sgV#
> o6rd1R
> zYfCRkt~FRwXLu*BQi3`yy|gw*w}bln1TDa@uHUYh>}4nk2D|1>5<BTT6-
> e%6Og~G_
> z2D42lI5@b2A`LKjt-zQs7+Z9KtsYt83<f$Nx8M)PfAXO5e<=G}PSm>b-
> %Hl9rDMD~
> zbIk57P`)H6lGxiXh}svHq!;P^*}0YU0xOfpR|zy1S_hyOJyj9VSC!!$CAkEip7f@9
> zwtpPNSL^KUoJ3DN{cCGqkK}jTAnw*XGRSf|<ReQ*d;4AGAZRkCs2=I}+h!#ng
> vqn^
> zL+8@s^?*wAD<B)rUcn*Pp%URXOD*quK&CHR1t#I6y<IL}XOA`ANj)-
> Qh7c*luMUSj
> zO&sFGIeaLdZ4)L2Tr+{$da*P$J%PGy-
> =<zJ>VXgROm}`mHobO4<z@saEY@BVGg`TO
> zh;4G&mlZehunTsRQ-7oha_KzI<W#g9v4Jwv3bg-
> ?+M8gc_GF#Ykle(@ka2o*ebxd}
> z!6B>7vyF&-I4Bd5BNGU-tvz_tN%U-;SEbgt^A*%=>-
> =hM+o3Nb?^xf{)OXXKYA1l$
> zh}rFrm|E+-tqVq}iJam7I%*t-
> A0)zjZ{$O({u>LzvWaF4WV7OYXGAGpJJK9e8gKEn
> z_gf47o0sBgO&uc-?DT~dLv4SNp4<P;MOe4b2gu*jNR7j)XH<$Cj|MAJC-
> zN~9pTcK
> zhbAsYcgmq4=2-
> csw>QQX7Nz*4*W2(J!nK#w*$G(A^qtW6HgC$Za2{T0L7_~$XuhJ&
> zx7dibXMK5l9zA4x{E2E*yuDp8!=@`&ne>G<L#brY<_q0)BO4~a%{n+xkvhKb6
> nJLP
> z;$sO1?Hx@xXzhqRsjF(d<^jLC=X^YD?ll&qVk0y+&?ncL+;E~dGlcbi$Gw1#ae<}
> c
> z*$l%Ggoa@j)_65z#&d>Q?ryE*1td%^w_)L(WV3!~GK68)h2Hn97}d^O6_$wIR
> G2P#
> zHHn?*@GY(b)BH_+Ot2df5B_ahq1-
> S4Gjno7vLRBJFZkTw`Bjlo+Z^wmrMevWi=g$?
> zB~0h)V$#Euur8cB9kIuARpv3wC#)!aA>XY#XnsGme79TJ*_wEP>7zE?Ta&`cM
> &k?V
> z?e%LKUx36pJv<LXAv{bZUKqOy$TbOe0c%(9QCP68FQlKXThq!0Kn)Y0If`_r#@
> mhy
> z>~ddTD#VH%7yr^ax|gd<T`BV@rH_-
> By_Ic#UNz+9EoM39rnaHB6TPh*&+Cd!qCl_D
> zf`mkEMe{OVva@CKYWB99y*!7(Rk2Z4F;t{XwkVt<x1!yfcwr6qq7iMPK~I@zaP
> Jj$
> zQ&;U-#T;n!9NN2b$zUqe;z)Te7(I3B-NUo2wW)T^g7H&*?-
> XUT;N^Cb<NV=8xltW|
> zYVjzUA`CCC%G^S&SzM#~H+$y_savY-
> PzXmWU}3GhOw`thWeGRp)M^wH$ODfbL@$T3
> zf2NzGcgzJIsv3LY`Ba1HsaIl5+lS!BH=G?63fQ(VK7FR+#*Mu!H=Di7kX;=&hF9!U
> z$C3kUKvU56A{UimYYe$Abh*-
> 6?x8+;<iUXpxmq1s5`Pv`Jk%*JYyYq&`Pb&<7mSu^
> zhd6o3rZ2!(_d)nNl>M_eXBWg<qET;-
> XjiUt*c{VJ*7sF@gf|PoH#&1><)`;gdMNpK
> zI+pUsd4^z#-
> eYehrrGNYVx<0TV6i_Afq1&@dZq`eZr3JD1>M9UUZiR7hxck=vQ9k!
> z^mN%7R?TTW5KsRzb(9ezj9+IZSWbJQCr=UBNL9*5k+y^yS`XZIYH~Hu$=x;wq
> o*-B
> z-FxX%zIfv1>kAOv)9j1N24R0gLaEk7QZ?>JvgfAcj`CEptiH<Cf75_8`1uK|&Gi9`
> zc5M|ld$kuC0v;ARpoA9h5AU`JdR)4FHuczcLvPBOV2}Iqu<%5WJH{OJf0K8Lgsv
> @B
> zZaIjxq3d(|-
> kg+}>9=rc6~b4>tx%;pkgu3e`&nBp#_E~1?l4w$<OWS#vM?F!l6YQb
> zhimyKA6%4(c^3!uW6L@uIQ!0g-
> v6fQ4S$8+PZzvCl$*EQH(W_g@yTyU`>{rHeRZZe
> zcD@1~5uP0*%|YYDwcpEFhAU{Vi4>Kb+Vno8xusmX@%7Ktx9+Ur=P3>~KB(
> _QH`3%L
> zZ<a&ATdMVLdhOs^mw2MppWc2r>9A_=>HSl$d`J;Z-
> bV9S&tM#!jj!68nE9&JzKqs)
> z{Xe$#-Gbyg1uDF!eV$z6>9f4)H;FYlN3}~GWO5bYme{-
> gLpBQB1(#oB+))*$HxVA=
> znGX@=?trx`OSxB*?eSP!%H6u?)+UU*UXcycB0C_cURAYvSGA^~YE#Rr2FxsP
> -A5x;
> zbC9lTO6+YmQ#1eWO`TLp))LLWJe%t}F6Z}kJfm@n!yVR2=2}VffJqF9?0#33>T_
> jK
> zpZk*5@W7`pM|>6p!ob@;qE9+<_}d$GPzAx$C5u$<R9Cqm$$x&>lJs587;5n*
> HTaX>
> z0q@@kN~MnX+N3&^sw1v9B>GdMT}yPU>{2#UYg!;#)*}<VPg1BmX61dHV9
> w5Jga#o-
> zAFKCE*&5#Odw^3;nA3jUx(^4Z1Nr<iXdh9uD{~_OU~v<XB(#dqQZ%s&bD&H
> r3wIiv
> zZs)w+V)>|^gij?tr#tk71inTZ*G_KaWW{#^#efp!6HPoNNUXfm9eT#vs*Ar-
> iPt43
> zJZI}dG~N2p?EM;L3zDqghroRwI9FS;KTI7rzW?AllKj(3baSK_RleD~%N4`a&9)Rg
> z=KL5M;_IpV(&XdajDdA})bqf9l&W1E#WX+2t>}6apU91G@wP)vC_$RM*uUu
> @;3V8O
> z@s)Lp98EB}{ypA1;ZZOyskx(HIj8C6+*b*Mnxu={1S6-
> @nWqSKWfqfH6(O#Ez#$PY
> z;MF3VlDA$ABZ%VoecXLR1p>{+DkaM+&DK%mv_!Sy4`o3?VcTA@K!=`HE3e2I
> %)PY<
> z<-
> 8_;EwOki)K80d%nT!8&c~db%P3F$s@$?2k=MTG7mV+AMXecS=l>so^HtI)m
> @V!o
> z{uBR@<^1a56h#E~I-
> 1{>N8Xu#XB{;E9!j1w|F#<c694HFj^t0gj!{#RPw@H++pf^v
> ztG!G@vpZM6#z|1T&31}^tX|oxx3-
> $4HA543F>&}(oX=?vD}9ytMbkm`J(NDmR+7hf
> z|H2GWT0VXksvcqa*dt=sgw<p1Lp6fXxe|p8bGt@NZ0U^TIvYCPuWVKd*N(u
> P>Af#3
> zBZN$@0^AaNtFN^&Cd$(Sj!uZm#pQP|hpWZi6ur<DJu@geSza{i?lZkz9}JpD(G
> JoT
> zt;F6DrJ_64aT0vaW)FpF)o1mGuT82!{p@{^T?djN<SwDZA^S0IBBJYsG!w=pW
> HYGW
> z?cGL=(9~t?yz|4l0RttY6QEVTf;kbi>aT3h_7Un6gVU$!TE7<W9#`Kt5P1FhcppPJ
> zoR8&?m^GfdG<1{cxi?J#B?7cw_cu!ef5exc3Su2YEphz(16nh7=&3VbBlsiU;uv}
> 0
> zCe=Y+>dm}C-
> Q>7`vVuyQ=bGe=J4GaTHTJH%#)zaVvw*zyCvP*~pbmJOBBuBaoPp}>
> zmAvG4;+5Fyp{MHM`^pbp-6DcqSY8hYd8zlc>m&6D;axq<HSVsf{d&xc)Z-
> +phhmB+
> zQ4d@TsbIsPad=!wh7r9kexrWS3fz>dz>(u)e2%Zr>xVdbEo!Zm|D*L|HBnn`@
> wNZJ
> z3*H_Dlpc_CT$dpIs+{AlFIXN=-
> Lno|db&4`V<q6^EJ(jrSY9En1LMg}UwT@#;!myZ
> zew;)Y(`56iXRe@UwlIq)?vi-oZFU-
> k=Q4U3nwq)r!{%*PlL9W0h=Uu|wD@&H{sadY
> z-
> xm+miiS$tRAw|}2R3X@>{qRPqj;aViknE{w=0{ULC(2?p6M6svo6q~*Sb4l5enc)
> zGeuo+fO{Q3TBba!WlG;n7Aom&I_T7Q3Q}!)dj%VTea8W?`q@>KDj3wbz_4W
> NFJ4|M
> zHT|kQv&zlpC$BU{!-
> `F!BA!_Vj)2>b;mj*P$1t&v4FgZER9&AqSE^p|^)c2eHLmzO
> z!hYAt<?D&&%I)MJW1Sz0MLn}Nc8im_t`sNZWPR~lmW7c<Hb2cUqG$TWMcI
> M{I`j-Y
> zvu5-HRvvIzSz}nKjjzWk->rB{)p2@If%&Wa-
> _=DC!A@9zaXXa;2=A5Y*UoL@C>_Ct
> z73o*cX_Mm#TLZF<f_u1CBn6(I5Po(W*CY7wXZv1Y=?uZ2I&`<RP;$)bXD-
> LA0>&kp
> z9JAt$RaKN@Rv$o)S$zOGX7vFA$E-
> Axl4C{oiH7J_^>Dp<*l$>kHLRFo>&@>RoPv=i
> zm)A30yg2Iu9eTwxYZD1_1--<dyr<?PBB;y`p-
> !&tX7RBNlMUbbE0k(<FSmYIEjAL7
> zCsyT7HTKk}uA&3=>TZZwQ@D@t)=YtCOmo(hlkwrG!0`mQYJQDG<mSAAwc
> wW$xF+w*
> zH)sUaxx?I!`HsW$rLx5fnqY9u%9EWie>G8Dd!+B5b@Tfj-
> DcJSfb(&l=AYGGNAS=3
> z)$d7Kgs_MEXH^0-k6>G0;lui8Js244l-
> <Rb*}W72_(%*o3c@$%to3BeU*Mcouepq#
> z*~}WA=HBpkE&e!UGftjB<L&o=G1CatJY<e$Q68}ImtRW?e@P`1o84yQu$$FY
> gJp(T
> zX&^ZJ#Wm|i>VhwxB!8M2C5%4_A3yybFeXRYDMVAnnrNzk12U5mz4krWcc
> azdsN7g{
> z5X%zAcMvP*cI}ozEy(5dl+~04$oa&aeTLq78K27wR)f+4cyP6^(>XBmn(+4|8$iz
> g
> zW3%6@tAO{u{GGv)4_EV7KbdF~(wOlT*6_#`6v`G>@Jx5;DP}l=57&2oK$!<Jn-
> 6)Z
> zcRv$V$dpSyT#YH457#cM6z<_JByar*sYjnErmUFa(a>b^CAhgiG%){A^>4y!oP
> M$u
> z_;AfDhASX>X2%CUT%RUQ;KSADc%Ah=pS01=wq}212pq<VYrrtyj1$+3%bd72
> `aW8l
> zy{AoBkgb4(-
> W2C~&>*0(>aI2)u8D{b*TxCyP007Kh6%a(95xxm&9Iu5Pw}+z|8~(_
> z>n@hH-
> Ay=JeT;b6=SExRvLLqCiE`rF;@v#M7U<52E2C%?otomBXI%iKynZ%Wd9ixS
> zO_USY7Vq3r0<N<6MTMK&rrSiO)NS=j_Z3Sg-
> >>rF+T;yQ56i*c6Hk>)|1;%MEp!A*
> ztQpT~L%hZN`1)YVC{8q+GB_jqp`i=cw!nq!ttA((v<qr*E?fzpPB?Jks##W*OTG
> QO
> zv-r75%1x6@@#A_^Ht}Cb$I|z`MMti`c&|TVmQY-
> _a3jwV9l3sc1h~&ooKLgmj$A+L
> zfaS=wl&$Z`b&>n#9JxlmmOFBt;-
> JbiaE@GS+$TA5EhVQD($0~qTHrf!)n{|$s(>81
> z>YMM#^=g8w(0NAsuMbDAmS<j{9efBhk|S3G%P5z0FOFO-
> Q}_C&9l0va7^_Ihk!xl>
> z92;#4rrsFdy5kMbm#aZr2_;{yDjr|1`qbi`aRmJ-U#_?EijqX$UJV{!u7YUxuC7K6
> zmQmO>4b>1~^W~}lzFh5-
> OOG#C1rGA%YBij09<(DwFW<k=VCt>9bNwlEvazjssrS+y
> zr|Q^A>geyxG%|184`th=eYU}jN*%pnx_wE6UnUtDR;22_TW?=lgD<&~ch|+V
> !@!((
> zSKgRRYCwxV$h+$hRY#n_yKDF@@a{U5@hi(2QCYcn*AUdt27ehY8}sg(d4lRV
> @2>wq
> zh-o2PXd;P}nVBmT$lJ4^r~26fneBJ2)C6?mBwq-
> cNFWq~a+U)^kmQ^u?@O&#HM|-t
> ziw-?wcgt@p0sZxzUB38mss06o>f~=;wW-
> W2Ro24ArAl)`84`Az8qL!sl_0@iY2m|F
> z*pLs`(&7eP7dbV7%x_x(+G%w@TpN3vz4zXtxrQCKUT_gBPQ|9tXK97=Nv0<
> M;aIUn
> zy*baQ*Z#XxMd8o%zZWNBlUngH%KuILA9rOUc0B*D=l}gzC1QU=+}HU3IsUiv
> |6lmO
> zk^dw4MtznvE0l)c&+z*N{=Ze<s4dqfVm~3>3D+cICtjb3Wv))dmJ(MaZtyz%rG
> 6k0
> z`zZ0p@&8O<#_@Xw|Hm((tUu8=s=vSRM($AY;8fcbUoWN01s6-
> n2%GC(jde4u4Fk@)
> zu9#5<rgwGjTq75D)oBwb%zs3Grk3F+NGi(t-
> |}brVJfI)mb^d6XKD*8V_V}VUJq2H
> z@%4$<@yF_yrqkmr$=Gc6J(`}<2rUisX!`HAr&enk%`ck*)7pc6a@j%pzC+n3l(Z
> wx
> z(g{`5vft~zC~WB-+-dtVr<<vNAP34l+L_)Lt|$qCK4fwQ;Fj3?{(D6DX6Yf75l(5i
> zZqa=4=-
> `g@gHHFdv>_<tnfJLA{@xET)4g{_%W#mc3{$y$C@iDz<Dk~On&9s4#n(&-
> z3H5Z`4EBv#%3DjBT;n8$c5ngSKD?vWFu>(%1y6a*QBB@2&k}6;rZ{B7iS)DnU>
> Tdm
> z=0W>-
> !H$?uPtNBo%Tt?ilMlAA|A;#~;UwI8EZGMHK59ewx|@MN>&?SIz5@7Bhk>sP
> z?@6p_akY6KhI>$L!tqcBZ?(ah{F{Zh+T4B^_|^Ld5aj<n`o>?@L5FUBeJlFL#Tree
> zrOgA(zq*vDV^N8!Bl^aw=L3D?{soq<D>IK2`qLbK-
> gwR7iYZEYQW{ZjtZ&=_iAU;j
> zzh94cMe9-0H(EW6_-_pAabct$-
> vSr@5^Fj3n14Qf<4w}s1^UKocnKE~htM}Zd5>Mj
> zC4J*GDky!Ue#HfIrmc$V8*kZpl&^Apa&3iO#uca>IXpwE8vimbyOd-
> q5hfdvrNWk_
> zg}6+PcP@TYEDPEZF5|l4@-l2Y$V<I0W|DA0y9Cm7T4uwxUB>nDe81Plr-
> NR<I395B
> z;%HD3s7LFq5_*Q}QN5r#s#<<n_2?cU`OlypolI$NiErvry{0?#H1((gC;~5}E~rPR
> z@?$EjKbv~=+KYuM=Gs5EdbA?Q_^qo)CmBZcH1((jI`j<Hqj~`=H#)2|8CIO`@&
> 9o3
> z=meoIucxU;EzqH7s2<e|>d|gPUFJTa?hVwV=U-$ba(MOVI<noG`8-
> ckk5<+CD}z6b
> zVbqn>qXJ`Puz{Z@@9sq=um4Hv(TCsd=+?A;+`+Aab$yir=@HbU>8}U6j$zkVD
> M6qf
> zRrs*#(Sw2CjC!<=Z21e+qk835K%QK~$J5lK&(HP8;Tx$(*O1~6>QQAT^{7B1>e
> 1z+
> zrCu`Ssi{Y6{sI&Q>QTX(dQ<@iWa?49zJYplm8DRjzWP(@QN23#s6L14QN5UYQ
> ~{|+
> z^?R^-
> ^oQKAq1h<2g3sRFj|^9j))F0X6NQbN6cox9mh((^=y?eBXk9{?2V$`gd8zja
> zCaRE|l+>ffO-w!ds8tH}=sD!AKgkd;)rgxY#$9n$t{zqO%hjWb`5&$xeb8i^KaYB}
> z3iP~L_2|OmLbc^&DOXm}t5Nmnh9i|%L_K<3DZ$~?qpK`kNj=(oY*@~lQja!qU
> !Yrt
> z{0~--es7LHVwON)hf$AyVFb8Csz)z%z$2<h&v4(~Ks{RJphi-U7SFdD|6lc}ul&qk
> zN6&@o(J}uG(H&MjItSyY|EnH-0;Jhuy`&y}-048eG=u)-
> S3h|R>d}um*gu1Mbg04?
> zf?g&N3PHovqo15-
> LeN`OkKSmi&bOu>?S3oj(U17RQT6CM&Eg?ckG65T+pYNA6<73#
> zU2#=IK#W<dNQK3)a|MOCn~i6>Lr*d35w5tp#pIxnNju0(IBytX(xoe|j7i%SSC#
> KF
> z=HBIOTYM({-
> ce%GvnY+zY^DTu)+l1&XWO?Kd~=H2zuM*$xw)abrHR;i{9nrdUjEO#
> zg}bEqzk>hkZ%xF$L);er{}cZo=KoIq|C0YB>2Zss`CFyo_v`$AoBwZBkNcO)60rlM
> zyWoE%Vsmdx#2)#JL@Y~O4ZkPw{>hIgV(t8%%l}4TX7am;|FhcubUp4c{n%U3
> =PsT8
> z|4)5x%Xtvko73l}_fPiKnQV<}B(RNx0S-no%Th<h*SFTCUt6X-
> k1bN~vpXA}#eB3l
> zg+Uj>-kzF>(mB4Kqdx=hH^<b<N`{DLxq>Au7S}Gf+fzrQjjr?I`UALr8+n}kz-5#U
> z2_7Lk{?x^6@^BEQ?F>q?TfORE`S}Uk?Wper>@r^Yh56KPcvh!@_nWXyk^7Y=
> M^%ce
> zhzYBBW9p8uiXTfY#fUP#zPTp-
> +Q(BjgfML>>CRm<mZvTaVXjVH;Ocy1>MV8w>SRGQ
> z%{Axasgv9%tcTpE<*Bjm)7A0Je_Kt+Q3$;;l?ZeHSZYp~`^Qt*j`=Wcm?M>Hz?
> G)N
> ztCm*_sb(lCq<U&<P@{8$8qEx9G&QKv2|<lOxq8xa*(davji{kK;WZ@orF2?nF{
> N=r
> zooz?9429ZPeu4J*RC}|V*c-
> arPI53l?hPQ_Tkj6uG;~`w@<EWpX*+kdKqrw?CZ@k$
> zy?+;$Z-IU`b2VoLvE{)3h-!t=BJVDAe;8U8hSr6l<zeViKV(Lt`6ax0Q_!a4_$LHe
> z6^0gu1w9tVwG+}`SLVSm^mrIr5r&=!Lu(1Ck`blw`DC2#&{Mo(1S8aoG$cz4ItRJ
> P
> zdvtb$SCouU>qDjR&(8FD#X0h`!e8FC@g&;FnvTfg1GCHY!sl33^i);cUPv<3^J0h
> k
> z#JOcvagd9=w@0fI!Y8dNrWd{<sLHJJs@%t}2%Jk*8BbNP+gI8AvFDI2s2jR60pc
> ;h
> zx3I0-70D(m&x&~dJ7-G|td~)3<4_0-
> $DCgHD$!k;H9p4Cjr)0bWrAMl%3K$IE%oKW
> z<b(Ss;MgL2vmH(KovG{<l!=9?euyiX%3ktLRoPk_UwbYusICPRn95q%H<h(KBC
> 6{L
> z@Q@>+L%)Wryh3antB``8rn**h<5AVMBGMgta;)WBn&5mp#Z%+$5Ay0TH`I
> 3B($V?6
> z2%kME{3fhBU7Sw4gL85jMVlSu)VApk<*~M7lk>2fTN=w3I{Dh-UG!-
> !D7E#?t0oFn
> z);fi-D})NXgD(_hIkN2KNa*RVAi4av@r3q-3>?n<vf`QFSsoAaA+};lS$(*ERM9uC
> zq~!ZSNKmrEhNgl-
> 7z!I2^c0aVc~}Pml1+hn9U}iR)EpUa4swxqKHGJn0wsiZM6O)C
> zo2UEZZALkff9n+yxgv`*uo%kaRn3OH2<|R!1=kz2PTepF%_x>F1KuDy)z{$66v*
> `*
> z+YVo)Iqoj>bwC8|RM^^?Q7D_4VeQmY?ew=Du8Xwug|o}r=^z(*P4A4fGlX~
> Tv~7pG
> z&+ywht-
> PIGFRPu3EG~eexz(7mvxT+P2F)c;b{;OB!H0}q*m>Ca&k29r>MAH3w-}WS
> z8_7eA<T_GyWi(x@vH85l4a8|i+!`J1PlH(PQv4?tDP5TqkcNu9LfO2g{9Hj#JfkU`
> z(KDM7Q;0GSu?zjVvXn!yK!*MR#we0{=L&k-9)<-
> v^sKvcDN02GXzLHqD)umT^TXx~
> zIm*i00(}WKloWxjw*~sn$>l8qi*F0`O>s$lyKk3@dC#Si$2gJ~N0sV?0eC#~s1`B)
> zw0E3YgWoz$U4(*B?JO?gd-+h?$O(GTWkXF2Ys8`UI>=6U==0%*T05-
> {NKj$JdqE*A
> zzUiBEhn^zARbREC_Pq!R-e_Ck;WEfUF7kdjBSL~9ydy#7;tiheli<{H5?pXVB&f*Z
> zCQ({mwJ!}dy=4ols9R~M=?$|^)z^j^hYf(*w6`j~abl<1-u9kc#-e(wy4tH1rRKV<
> zH|?pqiF?Lr;7!^4#%|+V2<v(_yS91<vBhsHiFKzA9vICo<=CF(yQeCD-
> &p0_;ypsm
> z+4=XKQ)Q--
> F^C&@$Pm{VLELl(X=IKPV61JCcOO$wI7fx>4spuGd*(DBarNbh8}pJ7
> zr^w<OsH^zpX-wPG!wTl^8@q)HW()Ncl+Wnd<Q-{w`9y}ZHvnQQ-
> yTr3j%N^)vjNAI
> z?e?oHm<4xBCkF?NE9Mv1bh~fGGbpnwvrO6WS3H5&kSjvvg)%DV0H6114zd`
> PD@{P<
> z#xziwa6{ow>q}HFVT^9(>CO~{48>8oK8wmNwORL1ZHqFL70^dO<qE5Yxx7Nz
> {A94f
> zR;G0U48?U;f26bSnpxIa4swzA!aE|J6~g-
> rMV)o5wGWN_<nqqC0p(fFB8$I#2ldFP
> z_6^25U?_RLG3QY?sJzgww}Res89mvIA;v*LzUhrddZO}z5<>W0?MC=U<(BoP
> UZ~u9
> z>n7;gs62pmQ&YBmVu{MF+nYI7AS!Qx%7Z-
> eYi;y2drwKDQlj!nz(M8R4;q#KK7zOe
> z^FV~k1t=>2CuX;h%0qaEIOXE~+Z3P5CzT`aR2`_yD6;rfsH?bv6$(@yR4});+NeA
> ~
> zfr9b{JzKn!Eib5CM3(L_@?42Pqk#TI(h3hJX~h+<q5z+Uvze6oAg^b-
> xCj$#1v>O(
> zzgLbya|OMyX*v1ZcBZ3-9|R*i-
> g0Z(+ac+6XN4}kGz_oaZYN?K+u#6z1{)q(9H%LA
> zkreA!cVy+<Hg{xYK4(_W!DqgX)l}(Njiupa%_<I{Sh#q9B-
> !k?cbI^vWM@<Suw;9O
> z?iOLG*uEQsqI6Kk7b<m7#;?2%%J_BBK^Y%F2W5PKtGSxWSR2Q-
> M#X&I7%xfe#UcD>
> z!W*rzIy~cAje)+3rv)`(3w}K%g7IbGGnd!Xwuvp!p(oqK3r`lt^#aD%IE-H*j63YQ
> zgES#tInbq|N<v7$ZztJ#hrxQAiP$?{0MQhGPj5PDG`1o-
> i`+_S8degB6(&e|3T5+k
> zBusbcX}r=6hPG<o>I1R#e5Q-
> YU~rI&yoZ=1!od*2`@B+vq1)=lEHa^dFiiT527@At
> z1;{j<5Nkz>CV(^U(;IEfYI-oSl^LU}-DV86!wIiU8EgVNCfGjFriTF5br7tvG(A{9
> zV-#ugNi)-f3Bcr$chgRj_m$s(iPH2?3rd(Cl3%gu;S&*zoMuu^C_M;J)5GVcMlce>
> zJB%n7?<o$_fXS{*T{%XM*e{GIvY4LA^l<7)bk&Tog1PpITcCk#riOy@c|DuG3d
> ^g?
> z?|FY1?yXOKkYO)cI8~jzCR0UlYo?kf;_DJ}@wWF3a<a;WI|%1$a-
> V+;Sj+|l%%`jQ
> zY4$E=h6fv14?r}_NofSc`Kp4lzX@Y^e)1VTvzd)XqicMq;*BS&Uv25tcAV|Mzn|k
> S
> z#xi5T7o}kviB6LdI#rlz(bo!P3xl91-JxfMPG5@j$~q@v1ZQR)<Rb6YQzE?*!bj+I
> znpKTnsV(o7Wn9dgv&iCaP8m+80ii|N*n>2`#Kw>sO5}VH8}nh`n2lA0Ln35jue?
> }B
> zrvp?QI_>?k(djD@jNIk;cz_WBicViRIf9W8-eE+!c*k=1#^|)B93wXrg%L#-e|a)=
> zx^l8(W7e47s*sHx03u(|v&H)WhiJl%Pj{&MWk`}yAicaQ);1+K){dv;MMJrQo-
> N)v
> z?QU<_v?xsTHh53fbeno-F0Zt@yug56R`I7}Uz)!8xdBeZkwIy??3-3vQyn5<4eKk?
> z6u)(Xh|MPUy><{UT>sQN&fu7^oyfZplH~7h1f9GXZZ@wN4vZM7?x*D?^4Af
> _#V7b!
> zQ1cE+{!2)0ql^)!u#taWp=^Gi<*8?c{NIKC!;JHora$jwkD#+1<Rb4i=815c4&fu@
> z{|>7f<X=VJ`t#?8zkETRt;phkF(19vY1+s?m}39*X}Thu1;c52;Ds{s@1=$%@}CpI
> z$lZ+m2;&l<$lqhUhZqUrBjkVF@jm&-
> $}#f6{}e_PS=`M8SG?<OM*cw~!)baq5c#~G
> z&EB<di*$TAOUK*)hQ3XAh#IiScjq&063y8#$maV=UD6@S2Z(6YSrQRo(a*CXB
> T8HO
> zzMO$Olcf26_wD^P(|j(Ye9S88wuQo)e`r&&mX`t!$h4b!?Ypn<j-
> Y0>{<%%7RB2GT
> zQJO7ymRfbl<&EZLp`?JbP}1knLP;-Xp`?H;l=M5@MlfeMt#!qjlZ2FjZD`y~=HQFX
> z9z8%Ga@<@O88-^MaidT+zf0wI=ouL|?GY-
> u#)&DxxN(q+yv@v8A(e#ik#Y0i$N5w;
> zNI8*lGiRTuM3KcOnIHe>jGIoJXGFxCZctJhH)|pod5;rQ0*nYy<K}TDiV!0qd}Q4
> G
> z2WNMTZ48uS<n&(&BZ@3O!W>(?6bBZpehwNpJ18ih*R$E1VtKLpQOA2fS?M
> g*zCq7A
> z1?1J_7EF~2TbE}P%4W8aB;BE>x_pF#yf-
> <HA2iTGF7kfNxDOjxvQ)F(1hZ6oeWKsM
> z1C$f#@=N!sfr>0Xb36_F=){1Nu<3-
> CUTXv*fYgUKWotOjTTrt&EJZ}Nq9k4wr<2mD
> z5!E<fSWR!@P_I+v8+%GWJI}2O+*m=U-
> 34?=Xy%;8RMO>(fW_1=K$*f0WeR08TMT7-
> zMn=i^A~Z4Ei39=49ONSJ0j9SQWg&cIl>A_VkFtKsiJ<J5Jwllxi|d$1Lt=<3zkIR6
> zSAHEyeZ#fDLCUW{1hGZb;gnxThIxd_uW#%r8yKBn0lH~&^3>J{63#SPCY1XHs
> DbfC
> zCaDk!A-
> qF^a`Cnv<0D~zITFV83JHoV=9v15Gmnvy*(7Rz#=TAq!t_s)GGf|dP=Gqc
> z`p)x}0&SCgok#k$o7;Q<>*r%vJFNlfbzOz!K-k4TOcr-tQ+ATuAndGmllPKI6LneJ
> zvO<fl(s2);S0L+)YRYi+W;@$mP(`)6RGhL7rg8i{Pe|)#f(e}K$~AL+GAAH6fH>9+
> zJd3(9W~7xs6G#b&RbjHE_Z8x(1PRd(8}`xex)tk0=pzt?KJ6HIK&%dOk@s8Xl(3&
> d
> z_z1C{c(mV79_2)c^(Gxc%qX(>E9NdY(nh6DPEK$%a$KbB(b2L)S_}1<Pf%;l^{W
> M7
> z#R6E)DDoiO_>BB*6wV=4Z75*HCj7R<pK_X9TzI)y$q_R9CZDF<Se=S*_L_gA#
> #Fge
> z@xEBQ3M{5(1$1+|U&4AEp&=?L6H@Dle6x2<DK*>qrcx7mo#RX5%BU?!f2XB
> 4qTq<V
> z&dRrV&+iXQuW?!9fGqv$%(jz#5&KybF2451eK!F_b#Nk3vo~vbWDQUp&q*R
> *ehQ|)
> zuFM9&@m>-
> uevwDyb&b6WSF9NLpv`*CAEHo&PY=P#l~tOA{!>>GOr7=}Hgq^!pMO9#
> zDF`^dnd9|^FZ14I8#j_{``+P7Q})s1M~6BxpaMm-TT)2dg#&uxgR${;Q{i00xfv62
> z9;Ek}*LfCSJH)8C0ul^Hg~F81s8ERefk?<{AD)pZT<%VSQL)SkEWxO7kc+&ZGdY
> E$
> zB7~2OiW;jR3xs`?6B!jvztpHuWbubgTp|B?lX{#=)jf~_{`3VxWtc~}K=|1&!9+=q
> zvksInpRf5lTOY5BVB`iTuml(ppyu-~rhyP6A-uzga`9ds>(3Lt<rsPQFN6_A7Qc5i
> zRCzsW#lEw`3Wf`WwG@=k>)Gsm!16-
> SiFAMU7@@`|8z^)nvN>ghbcZ6Fh14h@8-*R&
> zD8$m2TBJMljF8ROB1oF!gq{FN4swzARSx-
> uNDAR2Wb<6DkEGp{6Cs<o{ai>=Wbv=Z
> zzjd-fOaJE}o2sx^Lb7@A=VfHm4oV=K{s)X~{yu_{)16EcU_^i-
> n{_&R88~MP;T=Yl
> zi}y5Vbxc0)DaXi>J;I10i|zDw@ie-
> BB(hmWK^REzL_W5>%E{(O%tnzV=0`!5o15^A
> z5pRD-Wac@^baGE~aD|yiX6O;((@hp5apVQmFCZd?jfe^g;W~#p;X20<5pv|-
> 2+9sP
> z&KjW1K`!#HXKD#i7Q#n}XsuO|xn~#UM2KkDPlYl?7MtV4iRg`Wb81JZSNqd-
> b8IpB
> za%ZTUyY^>gM6?`~Kt#R{d0zx0dl^3w<%9r5M3;|?U?hZh7%?64Cy(-
> psJk2^n|~sV
> zD6)7FCnt-
> 0Acnr#VFg3oT#AD71wC85r)owbfN2pzIoVj$UpqK=CLuy9ZVOW=C|_yJ
> zqZR?FDD37Ng|hi&l#Bpk%?(NA)d*s?GmIjLagd9=vzhNgQVHQBr1BxFB&4!~a
> w4Si
> z_q&7`MHWwEK7Olg%1GsZpG}Rh-7xDXWu$T|C@GQ3A0rr9?-
> +0}cmya?sb_)>F%rT@
> zNacMT(6RYuTRBF)_`EQp$l`=rNaabE6MgRrC&Z9VB`GMM*R$FCg51h%sXB-
> RKA=g)
> ztxESY$($ac9p}dH11@3t9P<aTI?^0-
> A$1A}M`1@e3ZY=79(d!m#)pJ+EL0xIH|rQW
> z5yEkh=>M5QLNtZ&5yF{fHH2`sP)>w!mhBXp6j}U@Zl^LszgRr;Cgq#|_Xy{eon?
> fx
> z1eBBr=lBRl?s9TUKsW*v;k>{U5@IBTj}XqW)jr{LmSg0G=Y$bO7JqpZgtL;)?>qZo
> z!nuxu@_9XxZ>o%N%KLw6giKB{!=c#@Z1#4a7v&!zb@5QV=zOXW(22s17b(Q
> H6baKE
> zdPW4AcSf+1bb?8M6$iP<dye@d#7YPsp_7<Z5jxpOIT1Qp*e$FmviN<9DW{YF
> FL}|A
> zyUXZgF(@g~$?OP5u5^M)fDr+TPM&7|2r&}EN9g3gICo<c%!YD|ocm*8M3Kd
> RVIC{C
> z(%mERq9zK;7xcuRu;o=%P5|M|l6ns(VN|WV-
> @O8hJ@KH}?c#0(Ug=@c#c%q#7!F4>
> z_Y-
> 9K#?u#}BP&h(dpS|Zpj@&t*uAk;ENrLwOF9`kw4K0po|c)iOz&k?XC)Nu)i=wC
> zYF$nZWUg1-uF=R!7?<f7t7jXl(sg2@{N)Q*VR8`cY-t7SHkiyeqFytdcVm8_DvYrz
> z#M|#B8QA8V`TA15&=&}z*_-
> @b|G3*@yq170C4SKb)a1PfH;F#p{8kBC4#DyYROYn`
> z&RW=M{_o8weocj2saw^wa4%lYsBjH%ihZZnKWKSx3!6RWDD2%VJxGc7b(e
> GeDU3d5
> zaW|`J6T+O`$E_8!+`fl9K}|Ye0V?C`h15~T*Vo(BqWx;7>KVMa6?uBkJPuF<Ybxf
> B
> z)T9kFK^*(%TIstEuqkChkYH45(swaQ1Eeqv1efY+L%O#jb?kTQ4aD>XrCgl#*>v
> 01
> zm|jrl;@JzF1qtPXtYl4!5d+`kHES}gn5ApkH>GA*UUg{p8XQ0{Fls=RUze&8vz+B
> ^
> zXG54Q(;bhJ0XXTRzCPCDpZzW`!IslP)z50oIWnuOJ@a~6PbiS-
> jDI#wB42g1;s+&T
> zf@Oqrb-8<FOaK8YyXL$Z3$%C#G%?~?C^Ju)b?9kM%A^3-
> A5O|l8Q#P}44H7r#Gu9d
> zC-
> @82qL|+UUukJM$49s*5BPm2m!U~?M6n{oW^Y2!XcZ7!ae9C+c`GXwgasv;wS
> f0W
> ztR#@+6rCq<7l3I#o4miVy@HyO?SAooO{-
> ?kZs+pmQG%VzJBRs>rkj#UVG{uI3T5*b
> zQck)<Pcfwt&gDJtSZ*){JIF=eh0KcK6kIx&XIm0>F7K8<N=XJ&dV+HF=XcD%Y}X
> X5
> z$l|P!*|JkG%3f@+#4|F(=&~h@)tmip$?`V36mZ&0XT=)-oc0)^tiBV7Y-
> ScE<nnqN
> ziCCaR&m-
> cWv6Dmvy$nq)bjrjjST3OpMn}Je9E|y&J7}7|;s;g4Az+U7Va)gaAz;S&
> zFj6WXDxVjf+p6MAH2F|4U-
> w~td>ELDAK7Vld>YffY~eAU#jgNAyE6qhn87QR_<zWI
> z1NbP5Yj1dyY+!|jT{KA4h(TgS0UJdt7*L2TqO!VKS;SkgTB%)EZK-S!ErG-h%Ce?K
> zFW#%Iw}mU-
> +LpH1S`11t!4v{U8@*@~2{vHb&bp~a8+Fx4zW@Ks^E~@(0+rtP{l4%0
> zeINXu&GXEhnK^T2=FFKhGv`QO;5%M1&iEFun<{;Qzw8U8TE8$E@{}pa?#as%
> WHsa*
> zRqC+y1q)tJ$IL~2P0&VP*o<=c&*%$3*~7lTz|`5vLYT!$PJEfHNOqsrY(%&LxJm#
> S
> z09%o09Jqow@I9o3*B#j3TX&z&aS+dWF`r`>p2zO@IiA9EN8IOlYaQ-
> PBJ2lvR^a(2
> zo?qhm9iF4z+x#=qY(tu#;_n{(ZO8M^-rFqscihiR_#7M8`y7>z`y8n{pW`xwO-
> 0zH
> z_&#%k&#@1GZ^!dHz%0Vw8a&r-L0SJp`+G-
> zg?zXA9CPqQ@O%%?VLZRa!#kap{X95S
> z#f(#kGl$}x3=TiN3GMIG8y|+__m+LWA7GUHf6+eQePm3>cb^mX`PL7z&vz{
> UO_4lx
> zcatnBj60yXI0$Dqmt%loeF{6crq3zUnQESTK*PUy>lZi&G21WJU0`1J^YzANJX3!
> q
> z#D!(C8T+5V(s86RUtOO@S@MOmK=mBl$*mmgFe*pC!I7LgOk#=A1cy&JFM
> O21*Tp$H
> zqg>NVVJy7@n|1k;ITH_+j8YM7QAi-
> Uhf#KA1*{J`BKdW2cBV6rz=cov&=n52(wHZ{
> zlhOu0(KCPpUEcW8fjW9QGqG3#XkcNKf^(C&oGQLvK3%5=xW18W+DqIzs6C
> G59|g8q
> zfvFgIqdThxSQQixgYZ%*W)s6dL~J;K%Yitf^tU52TN$%lm3Z2YgKJSHfwRSH<kfI
> *
> zVWkUC=gmUqrmAq$hf93;K&e3j-o#NiJR-
> dTMhnq37VWZk4R`=dzyk}7Om?nmh+YJE
> zZDjIIh#5SL!mFyGH-
> jo)Yz0!gF@w#?tGVK71ePS9M>j*P;WckK%9yIl_ySKNHhRMU
> z7d>u7aX;AWsH96g>OXigd8cd5UL5y_Be1Az%4=woTjRK_oTTF`n!&8|_o!iwef
> |7<
> z;x4q4H})K*tDNZh4C+Tz!V#-y5d6!Az5A)Ej$9Gms;RwN%Lba-
> Oz;X5cw_e#I4aMT
> zLPr3JTX8&ygozI`?jsX2N=RHshKC{tzc=7JK#axydkJQH9wqYB?nTiSyoueaAcJle
> z>|kNEOl<eBoI$IX>>|6+J6-6VJ?c_|n8#1a5+f%t_-q|q;l$_(=+RToa8GuQcZt7)
> zo#i>`*Jr8|KVdgI7x>_=u}pqQ@rwplLnRXinlJO)C=mY4ndv$K=}O(6x|xOwr4N
> e~
> ziW9<g*DDx3LLf(Ct`p9R42;fD8`GH*JIxZyB)iTOZm5g<GO3S*b);PUIF%ok8#_JT
> z&=<TY(=AuaRI`|h6mzVmKijzrXcM!}uheHdF#_0)#u!Gb7`XcdR<k3y1X3)&|HA
> LN
> zPVq&3b|T~j!3}rri#{Togzxk=!hKKDwIwGZoz*&^i#XvK8{TlW^ry?hj@M=Mep
> $;G
> z=IDi^o*C+gxMOGvs1Xer?m|D5#Omb_WW2&gJ?OKVMV=-_?oV#V_8;#e(-
> BQ$#!XV+
> zRZ`?kv&bD{z0^E$0b>~`a)P}`4XKM{V)ZX(k&x1LkxzkSup*zFgCaQ%<1Rco0!}u
> 2
> zYKs|$&hOa<|1z|<%{dxufv9d|x`5NO&DZDIHZS+|*deE<_5=(Fq5sS&ufYO)9|
> 7+s
> z;7qti#qb#A**4pII?W=3hcuwuIp|@W5%Ew1xNZZANhfdMx)jW38+<HO4xhr
> nz9fe+
> zF2DCR9^!ZeM#GzLg$V)+C(pB$Qk=`c>)CQ|S<lJ~%;5KbCykD~_a~Npu=+G2_
> 7;O?
> zg00Oh0H5p2dzBcct}s))U`3x?_WsIJGx#Y6qu$S!7nb#`K7|=QV&#1*rrW-
> }T|_uF
> zn^E_gQ6W%i_9#@{i!~M^Znj6%jyfHLi_--
> Fs~Gq1xE03yiH^a6P}4MprCmAjg~H@#
> zGC6SH=1+UJ&3Bz1I}GX{1c`+Dnr7*wS2(57puFI*4gMlP(Y?&iplB%Fco<Ga$-
> 9P=
> z0-179<21|Kw!@^87la^1CHTh-
> 7DAi|LI_14WYApDrUDf8rG*e_p{S&|(~3U1>;s{w
> z1TV1iFD!dsQ}l8xZ&1{q&SO)jHAN?wQ9jgM`kg^hk3HhST%oAHo)m>cyih%QS
> 3P?d
> z3Cy6febMo3E#^PvwX#Ofk9XD0KM~GQT3F|YpGQr6EvYF40nG~b_?p>W8Mj
> >Gnp0zv
> zEq&09_?pa!#S+nExi8fG2`=vJ{A(_3zF@5{hJA&<#kyx(GvABs`35ihGL%y+?qcS
> 8
> zRCaYboaza?>LA>o08ciz8hIR>U0oWk*6ga<5Ecv*%EGR?!5u7ir6I#h0Iu29*mn(
> f
> z)n@XJJEX|Aq?<(^lU-
> eA7C9ojNMTp^*o)MVx=3MHKgVSluHQ2p@)Ky|;6pk27`yfW
> zcD0OQ$6#0QGhH^jimn{Us#*wiG*%@|oMBZ>=uAz*swml7tjgkPu+rh{YwU
> y!NhUUY
> zSKQZtNu8Pl$S?^%7#bKCY!PU_3g5Z7`USo!BYUoesM)`rQNJJx8HnREbs6f-
> E5fWj
> zStpnzN)}&WDVCg;k{QF2cVKKw$uNBYzJhT?W=Aks_rM6yqd{!I{J5cRwgZk8T
> G^e}
> z*OSn#90C45$YE%N7PF&AC9VY{;2sEnwxRJ=iD))w@T1M&*hjGXe<;y?-
> Gb{wl;6Xy
> zM%=EebScNMT*u<C-
> S}1Jk(gKF{CJj==lR4#ZuEl0?2>}S+`cKz>Za9w{h>tIn+Qw@
> zCITfvRRAc+U5f$YO3W|u#&hd2eK}r42?+9r0(69nLYDMj#Cqs8OjDq4c8PPz6A
> S^=
> zgv3HuVyQcJq(6E|Y-P!${^*dhXvw7Ilj|;Ao^byrKCi?b$J%w}Z*VhXOgM-
> AZT4?m
> z3M(M}@-
> @7qo+a8#;@C|kLWQWyi&GkwB;>p19w%|A^ujDlBIur0;i}Bn&VR3~c)lJ>
> zsnl@e1(~?xSG(euJL9*zLluFAH!Qy4tGk?z{#F>GH~tBI*|Su!ouA11xz69Ex_{f(
> zUjv~HczR<00dyGn*KIs49Q`ui58xdO@9iQsufoLCrJ4~GfP#;Uhn0V%76<ZBOX
> ^hm
> z|D;^nrT&W$YU>+jT&$|a5uL=C2PM12L#-
> $Z(4K8>EFwA?Q_dJ)XYyR2lEPg>7yJ@2
> z{9Fm|NS=sreqY6JLuk)gg(<X4U5p@#oQ<EjY7S9VRH2#*4G}wfCbDY$)MdEI3
> Z>Wi
> zTx)%w?Dl;MIky*F$&o5jCxdTk*>|1awbq~B?fZnWDAB?7VwZXyWP)n8+!=`E)
> zQ*p
> zs5e-LC1RLLcmg~_09eu~fas3;;|u;#m$P+C;H;ar+Hh0Shhv;=j9)-#Ut4MxB62EE
> z#vF|qeLrKSOU(Y%*{Rb#+d`jHcEVU4-
> Wm^K$aSgHCAyW8aF_D(!;*w;>!pg=jFMSb
> zVHt*Hlk4V{qwst0YPc<6FQD8p1hgW5!K*hl60;9m^016L!_BtYef0cP!It9b!!kHO
> zfQ5U?7_QViQXhy{hV)SBRj=S4-X6!9Ae;Dp1uXU>C?>vyAhJ4o{3-
> L)k`tMEo*BIi
> zj1FJxTx*9}5)8gIGt6YK`$V6*EmH`0Zc=yJU|9mZZe5YdeERWa4qr>?aDB>cWu7
> Wc
> z{Yq!EW^WXJzKm)o&&JedW<QV~?%k|c-$b8_h5*K!PRlK78v3nRcPS@)=oi!-
> zwYbL
> zm=yAx?xGjIA!7U`;k2HLKhzVexpIKJ=o#u}+&#3WVhtJY;#ADU>R)l!M&`vX&<I
> _$
> zTOC4CP~ar{jPIP^;CrSsw!+0bWai>2v6bo2Q86gH)h{GXXOfZ)JsDb!LWzGA#ZN
> 8$
> zL{}2}SA>Rex6Kk|ol&^rGnNGG4I*7)p6D=<nkNNxq#~R{Y=ZkVzZ<^&kd!M8j
> G1nA
> zra-o(W~PR7dYTq;!_8@alKzv4!!(~8BaHnT<EUHpKF!MRPn`(QP-
> a=364shEWUTqe
> zT;GWz!)-ZLkocPJ$B~C&D{Z&0-
> ?7fuzt(qTo&U&M|M%H(9uaTJ;vw33_hjuZ8D>&e
> zzT|W4_I*Dm`Cmw$+=QRqz9TtuR~xzHB)^XkwGVd!wfY85#G(0Sg~)h#)Rymf
> #kK+8
> z;*TuFFV6lj6fQ4H{wSSfLAZgvC0Dhg?^3y=<uwEBJT*-U&`KeA?j~?}3xAki-HzKf
> zOazV47_Q~~-nf4Qmb@}>qvzvW4=H**krC-lr6jN-2Lp|2+1-v}4pNFI-
> qi0Sv#CJa
> z8dM+5V8-q}zOA!SgH7`vzY5EjT1rT@(x|nus#=)QO@wOUwx{va{DiL-
> B1^3EjK<C(
> z3HKv60p7E7evT8eOKxf(fmfbTQ&oEbtWDi@l3JojH8*l5=G?PH`r8}wV+~Yc9*$
> In
> zR|rueIp|o2D^#ss2Sd9lYx9%T_^b?ym_euudB8EYze}#!R|7SSm%4dgSj32e=6i
> gc
> z1RW_@Yuh3`a7)5hEi|dd@p3i|Zs*Gj0LntORdCX>MSKizi5)tl@z9Vw_Zn6UCL
> RC`
> zvo`qk>@0U;#mCG2)jDKdxpOTHj4(ePkjRbaq)tRUyjsK30K)g=;-
> ^1Zi675SAGZ{1
> z?+0QAe#gZBI1mS!^Qyq(YhkGuxw8-
> QFQp{ZrA$7ma1&u5E~zK!PMls&)9Mp&9^Ikq
> z{Et_#FK~TB4<>2c8mA<e2yGCJO8@96w5l+sjUr4>#_J(P&^yX4*ti29!l6jSIVwj
> b
> zLhFO-M(M0hG<oVyOlrB6Cqx`-
> +Pu&EQx()aRZfav&_52P?o#Ai=U<C?`f=#M?!Z^V
> zw>Iv3Gy#nIM?VUkSn3R<aDrtB1Vi@t9+l=Df-
> D4dqXC*gI!v?cpWfqhynyF9<7viU
> z;SaIy`If%B!(bDeZhCVrI(%zl#1g*v_urZr9mX4YX4}RHUe@~FG!z_$9^SC^Cp-
> *U
> zccV)>QWzi2=m3z>{W~hujdMAsoN(`5H#-
> ;NeRsm&EPb^ZV6jUa(cIJ@pml`A5&1@V
> z5(<grLJJ2qwyK5B2g4i#o1Wjj^!$D{G^E^<1P?kHcOCU;Qf2ar-
> DVkBcVQbCEp}(P
> zxg88+D}P$sknPF%f2UDGU8of;T<2>DsBf)gDTM*`$TGeZLx=<eNV9p9`<$GHS
> }W9J
> zS4btqBt~DXssWD55}}5ms?p(j^ofRW=zC{kVG{S*XyI>8Kn+xnb$UPrH8^TlH$
> Mjg
> zNq556jL{Ex5@nju!f@om%qmC1PtP9G)RBA=wT8a`D-
> @B=P$%4Rr2h$im_ZiGV}P=;
> zcu$?Si6D8trhsajBNa&an{>%dW|XL-;kI$KfQFjnFvbit%8P)F`&-P279CN!ATdH9
> z{Rj|t>N9e}H{Ic0g6kqiUI;1Ai=}74`K_5x-Rxn`fV$d5rUl64LpPCn3|fhazNS3(
> z19XsXxUhr_6c06X0?#JVd2Bo7(pd!R;3*QcON<Jti~dT{6{h33ZWPOt(BwDLK`~s
> ^
> z`nsi!y2ISw&F*HWe@N2MD<!*G0lQfl2Q<87!5-
> ZaMnaPW_gVa>evE5>Mz?E{S9UwI
> zzw97OW<uywA$VBrN)fb6*l$<r)`%ng7o@Ru&!y;|sAd8iNFlhJ>zattdnY#I3%;
> D*
> z`aPKn3=H`e5tTv#jQgKSgq{hi9G}swUAkFOYBsf&p|sRdO5+Fx;k+nfBHTCkPTY
> kr
> zu&||OX@C5xE=>>RtqK2DoClpPrRDj$Feh>J?t;sdW*{unDP|x{r(LNv$a8mjKW
> c<<
> zkfT7zAzI&BZY}7h#-
> $_OkD7EfuRou8L#EdKKuVxPE0arvQIUM4wvo+iBO4rY3fX#0
> zvi(H%|3J2pMny>9xPJ?#xuDv2`LW2BTF(ySS@ToS3?+`pF0mET2l)Z4y<#%x3a
> D9T
> zDNp^2kPAshW+z#XB;oK@G_Wke(4bWZj0TPBG{R1%Amym+lmVoK?ilUDw
> Hp%7HWQZV
> zgup;LwTK7NGf3%BSJ|ja2soPZMvJgLaviBNxz@#obcK5UGa?IxvsW`0^m^U94
> Q>)0
> z1yE_83iW*ryC<Km#eahCNC1%keaFbj2W?LWP7ZAP7DU(q%R6&F15KoNfF}J
> Hfczz>
> zR57SngbLanlDTCEtnepXjh@N!ny~)s<}S*9rUQF8M*efH`D}k|#!6XB&WPlM=
> N$m=
> zH~yeW`$w;oT~RRkd;)>yj?`#9lXH6(JFyHV(~VUXI#!KN_zHm`41oDCugEH+Ff{
> ^E
> z{Z-u5TMl*`t12d(Q5$u-30F+GVhwi<;RLJP=m-Nn&l<M4G57BA^`J=P1-
> 1`UMX*ep
> zC@+BhrC3!-CIB-
> <30FPpw!_2)pO|#|`el2uo02fC5SK*nqQFvT;H~>=3FbFRQwVW~
> zCW|EvRY?NtFGgz=p*8wY*Ag>-!1lzddK{Ib+1%-
> %y6+R|IH>n3mgY;#70;fyzsRip
> zz_#oky@KKr)d?_@Tx8^PiOvUKzMg=Zq`$z0l4m1ZO&uItD#VAe(>#a@Y@6s
> XQr@#B
> z0xF{1GJkR9F#6$iBs=koxSUnPL<^M^EA3T<{6?ORWCP;s(0>!Y5(r)sq(cZnej*7
> A
> z#jJC2PINMg$)SnoVh1jMwo*88gx^69;iV#|s8O9Hh`D@We}RnGkh{z%XQ7m{
> 8{!k^
> zu{IGO+7kXYQEx_ZW(99^bFfyQjM)bZO&wLXYbB1j;2R?p0OdJl&8v-y4Mm2j-
> |9-p
> zd3ts|vq*O3<e%|d=iiM5D2fcVi9ypgDG1xnC{pJLA!l;JUj#gKRN1R2GK6o9LPbv
> 5
> zF0;rD$Ph(J=4<gQ!m!b|A}FH7*swLcT?rX)0v!41s;^9GsJx(_8>LfT`?ylY(z$ny
> z4<E#iPQtJ1=AQr+&SmAKAcTTBOv6RIc#PhGx}byYF#JkOuEPL<bm*y_XgNJ9x
> nXN!
> zfSG?-
> k}KyVRW};XV)W;tiflYP<gCK5<dX#5h#!6rK()h;YKKO3!z=?;o>CB0u@AGy
> zSC22CS`RK2tLk=CI#buC{9uQ`vm1CC7-Zo|6J;I13}-b$3NW2`_u}0RT9Q3+dd0a9
> z^>rx-
> n~a?mYJu_Y>q<FOxl<Yv{{3LMrMC@cxLUr)+5$e*dE&zzM@NDx2+AS|GA>I`
> zV5)coUKS%!Y&k>WhDM;0pYwKKO;sP;3!*4b+?+pONRT=Y!7VK~A#>K0y*SU
> dl|0rF
> z=00gS!1rABaffYWWV38z{lV=yFe6zzVBa9k)fn~vX{^y<P@Jx|@rE^gpR8B=QU
> {P=
> zq5vH=zv*1CQIFE{V-
> %geUEZz!eIqB2j${Ew&{33EEgh@@HnYQgf&DW(`XWQlP@CH*
> z`WZ?I4H=#X@GujrH*moQtN?D>(c7`@-
> K|Qb$hPDrkR{^}(OAuo4NuTT&NPes{Q(=r
> zWW_&2oo_EvL+T=#Slwb4x!)}EX;hv2Navx*=NMQP@}AZp^y`H7#i@&&Wfm
> FCE>gCx
> zcK*>;OAV=uWMb9xno&z*r@dQUDn+&?pGW^>t#9Nv&YR%4!eoA5gKwN7
> v7L2z@V_~H
> z;1daZlHKaakBD+hY85}mF)_|uh$M`GK@ArN20V7=cy;~)4-
> hZpgl^S?)Htt;<MSdX
> za607r=#w|hN?;quB+dpYsW}BPsW0|UZamb)99BtaldVhX{%NSAA#dAIAN4v>
> cc%(d
> zClA;Fy*sl3Wc2Tn1;(6iSo*h4nwY1h#)cc-
> l3sU1_$I#Os$K0_T>wX=&Qs@ERYCvM
> zkm0!im&EEO+|J<y1clOkh!~(0SKh*ia4c+wtfN~}vaevU(kPfgcUh>j@+9@&ub
> Wh2
> z`U0l+bx!nk&*)$6aI72~F3{-
> RZlX8dj$W8RV8vM01l3P}E1C~Uco*t*Q0jGuneZKS
> zV{4iOH{;UL@QHwx(x%djuX2>-
> Ux?qzg2V`ZRVc1wF)uv9uh<O!Vy1tQJdmsGb7M26
> zGAKGuz4Gkm-1s?3<!9A~2S1YkD)3#fJqD5GLWa~ZL}ynyHT-
> jYh1V0=+=x^4%4F`f
> z7g^~dWj+PZNQ@>9T3$8^ue><?>#PiZV`M<oOc=>vJ2KeBP%UQbI%3aK1hL6
> eUIPoA
> zD<lgOz@*wU7>O3uh{s*T!{0ek=8f*4T83|#hh($H^B@;3<f2m@o?7mULB8_$
> lCwJ3
> z1=Q~Mn461?C3+iGn!U1KLwqmOOka<K?FP87H&K~R%)Z|lcdkplQB&265p>zI
> 3-q$p
> zBo|;SG*N<Tm~3d9q9uBmFD+C|SvhtiD{y+PyGcF`<cNr8O<dl39aZR+y)fKMW
> O^Yd
> zmHB#CULrW=*5FVwik}pwTG?nV07J3~Mx4@j0xB+QWD^11YGUP7*B@#H7
> EfC2nY|7@
> zi*#}sjp0wnrO&0tQaS}$AD4{_PL&!0eFuj>rQ>;OUm+4_aH2B^p><U&E+TcEz
> &xN@
> zw0hbQh&;6v7ce`HV<HZ8J$!q>PPK%9iGErpIVBvGl<|bsYhWJp#gXF9iJ|Vikdn
> hQ
> zeX_3ZllH^R*(E+OUK=lqQU!sw+7M{Le?U6Sg+2Y1!_}X`D)fdS`vnSlMp{kxh%r
> Xp
> zH|j8}?hw#32R{sfLCXt5dG5@iD*+YQcm*nbROnr;`F0=lCn7YspOFPG#Ir906bl<
> 3
> zf^<VyG$RWALtg^eAfUhntvRHOzKQu9X^rVzZ1iomf8)-
> VEd31rimA2_lx0iG`U1LC
> zuE;)R5Sp4=4biRjiWET{p`PeVy&Znu)_TxO_6Y|Y1AA2%Y*_K2%H|qrSmXrt?p
> KIC
> zWH4wCI9O0aPc6GG^5<fD)fA)UsoM-
> U+46?Shu*XkS|Vf&hoEr;^pHRoqc{BC>J8KX
> zgf7vEexWneeWHh1zx^9SQ*hN)MlV3Ghsp(Gq(`dOle``6i>&py!muNSgg!VH&
> ^qWm
> zZzoO-$SV1KUwX>#p*-u+X9S>DK2kYa{T)~MbeFF`0ToP^k-tEWT*;+-
> Sw6QzmO;0+
> zAE=9Cmi_n(TJO&s<?DG>82{ApT2u-
> X+WT5uF!ul<V3esks}vQKSC)mjO(zO3B{`Un
> zs@*4))3}HW37<>0CR}=JB2ge)6P}$=D#ki<3_Iq&4hTAPH6GJUJZ{Uz0~2eR%F
> p1j
> z?-f?uz(Xg}crYK;hif%xL5;`Rs62(sm7`W;UFde)1%kAi1d(mKL<l?IZ85rt9~)js
> zI?#>0L6A;kzBbM$0j5l?l+sB{HA`L%5mP79h%g_u%s_<k$sgedow7px$JaT%JI&
> F+
> zlLOe8at+><iXG00o{}Zb+=V<K&S1Hbx)3Y1vElmj1>JHJ-Sh3}swZAH$%JJ&sg-
> q1
> zdIZHZ<+(+$`9}w(jqy7d@)7webJ2gWpg>R1+bvve<Sk@g5ER>Rt^#Z0@&1n3
> C;id!
> zn5{unDX#N+0|YeRkApqqefwi+oX}Svw@{Ky7Rr?Ap6G9dw(GPIx++*`w`c8TX
> tLGN
> zA3)c4{}jB3dF?ae>K}a}cqdqBsjR}9V^z(L%CpqZkeOEc;<%7oP?ik>U`_^`>_$-7
> zQB9rzwC@nn1xyKwxo!-
> e)z|}6%%6Rwi7!0OpyK|fM5qa)`6y5g29!_nkd?myB5<>2
> zrv1x>C+Gtj{go5crNAvVHNWyi<rFM=AO~3T4;ad0U}cyyQgBSw`xpwH*o=kcX
> }d@U
> zEhT!s4+{3L)TDTTmpQ2i7TRuxzyyf_DrH=9uqaai$|P%%JJDXfY9&U2ax7bp_Ar
> *P
> zLW8*rjCNt^*hL!;{)?u&Rx-YNk@OLexfYq}af_v&fh)M!c&z!*isRJzxL&x&VXKl>
> z)Fpb<6^MzKW^z889ijs?YQvHNqhe3UK%hPz+K~v=j}PsLecE4nf_e*FCE?%-
> +ML+*
> ze1=(xS83UR&wt9a7#2KkLiB8l1I&RYf9*ML{#pY@F%#12WWH46rGzigJw{KH7
> bo_U
> z<R#a^BgDd2sag<Di}jqT1sNL-cgg_0IPBm{u3C>FnUN8BR{A{QSJpaJLxvT(Dif>o
> zey>wNp8SRIGO+%WR5MtM=71D5sq--
> yf5=rf+GP9#_?)jbvyyR55xl0Ec%|7ZGm0@;
> z$t<zT!0^?O8ZRbR|JG#TH5$dEqx=ItroDcF&4Onwy+De-
> #4NfhyJ)c3^HdU!2rUM$
> zA$8GAtWL`m{R0jg_Ma;jOCLQxt_mfwaTa4K2L`oR;HYYuRVqY$i@EwtME9c$T
> QmYk
> zB`X=gQHja#G$zO9s0Kgfd8A`ak7uFNL90Y%OXDZ`pl$5%8I6aBB%F2J++R1(The
> -{
> z^%Kv|S4F-
> =&+moQ&knj8Jyl*jwKt<x_%Rdx_fEbb&uB^V1tS<Lb5HFI^TUY`Y6OxS
> z5pwiWJv(tqq2|zPvYY{pT_8s(*3QdyCaFsN2NfFuBnIX0mRhZyJqps@(R$Ik`8g
> %k
> zhpPu>>lATf?R-~Bk~-dhg!Nu2c0lGCtOw?-
> 1(kKPhn196yRl%%ZUhV6l2ql<5tc(G
> z+D*^EtSzJ|p&p}cs}EII@5S0Cn-&(jC3-)go(-
> BR5Dm%+^=#(U&{RIOn>fOewdG>;
> zHy6)f0*XA$C7l6047;J=YT#iqvy+FV(ST?{Y!ztb44jr6;(!frK)5*+_F|-1LqRYo
> zRTqI#nQSZr9G;8Rl7(8*Ac^WJ4y8t+dcp9PSyy4ET8LQ%3Q`kk&EIY67ZZ^_jmSn
> D
> zA~TPI$QG~%3lR%A+(kr~g*xzp4G}jG*+e|zRMHX$UH*085wQkNDoYZlqeMp
> {&p4n9
> zW$R*h;?BOrEq(o+JR!WxCHG2A{p`XU9&ncQcbcCqU-
> WIZ4}|?C2{{!Uuk1rZ{P=IU
> zzlx?Ht4ixB{<ec?TsZl_LHt9XbI1KE=aR$>!ESM1ylhEaFxBUlEv#_9Io9n$?l|<2
> zrX<Ep)5x>{ncD6hMfZ^xV)w3(8DKIs8svD>U--
> Y6zIX4@%NP1!93|!!kqU|O36O6v
> zdJ+|dL3M^!PA<loWRu_qJ#o8Bkup%{mA>cGC#`X$d`ctNj6AG>Wf>Shcx-
> `QYA)GC
> zaHs+5e9CC*P@zb16qVFBa0);a{bnST{z4($Um$y+U0hTAZgq7<Uq3PAT`_l}oX
> 3*f
> zIB6|sltek1s36%Px#U<?w$a<bf9iD@o^ZtlC0qTaJ>u;po}>458l_roL>K2Amm*S
> D
> ziFN)q)~+)VDwG2a=)4NsDRF-
> {w)^6t9vnB;N$g^L{2RUTJJV*}+v<F6y6#ZKYEA$e
> zwSWL|f2(@<NAM-
> Qz8aZ8dav`fP;`UVpg*)9bEt6upWGli#u_t;#clCCqhHFVnmLG?
> z<!n9MOw;c=8v%y}AoH<-ow38W;;@U)y=P_#v61ShmZzdTas-
> ;Pc|dh`WDpv66G3&^
> zm`RkA(3p*Xj0G|}HR5CUVrLeYDP3$1_=mz$Ko17~@;+{u#8#{1bY>CT1Ec(wq
> QvdR
> z{hd;-iLl0(i%IE}-s=|Nu>SSbryNPVwQ}luoZH6*<RLd;p5$#c?=^J=+osK1@2qpK
> zugWi*>spmhh@t(cz-NiKm`_y;bK-
> e`!a4Et<Cm1JaNq4L`*?Z2YQT~TN|>+JIk(+d
> z=d9895pd%GCz0F>5|ys_5cT=vXq2^&vQe&as`u~}-
> ^#DV?i=;ik>IP|AXqgcpnV+)
> z+Dvod&rB!OJReH+7UO<^BoO!o>PaT3bd^bFm7~-
> n{JzE+m!gohs<m>Yj|iO8oa-!m
> zAAcIfWyJe8E>7kW`vuN;z-
> gc&LloFwpQv(y!SC(=;FlPCAGgQe%US1he~zy`Ia7y<
> zyVu;rp1!Z`<t+ojhu0=9xY7~cxV_w=J8K};)N>5|h;8?#Ge#kMtl>H}QW`EjEQ0v
> Z
> zU0E|2U?!?%J2Ml90U0g=xFl9jZr3SrFmN`y6Z~J?$pC91Z;F&;$6BNuARIEyMxEx
> ^
> z!l7AT_)kU?3wug~cf=0Q^sJFq1?N`xYL7z3qB1%TNBoaOPlFas1d3iQEanx6ScT;?
> zr}gfhUtNj*+P!YBDLO)Z$GZXjR&rmjh@-
> vP2TA>k$(1AzsdeQg4V{jL^ia>vX6#Qx
> zaOgsHMZ44`>>|_!Mk9w1u=vRnN&idXt(xZlss#X3yM%)Z=c)c3Hkxb5@Osjmi
> PibI
> z$wN5<YaGZaWT_ZtSn2dfOQ?w~cSDZ^YsDCP^e<cuOk@L6Tsr4QMVH@<Kq
> ?LIg}xCY
> zcV9rwn=4BNra~S$W#z8QvG|DHgH9|-
> 9??k>x!8z91oeQrteHHl42>vG6C<a%S3Ypi
> z&a>0+Dr@8!Lug0ML_j)qO=^q|Q<;o%dH)0Ib7TqqvxLur;Hyh`kLAsROd_AnI+i
> O1
> zaTR2nZ@Ao}ZG!4q*jB;66pkQZLh(K<+RrBnuuRaAY?bUSWEoGf?whRhH+{Qt
> Sbn$f
> zAfC7I{0UDdo<n#J_w4q)y?QqmJG*^<#`70Ef5oHlB=NlS-
> fmxN^=@A`VE=~aT|DpM
> z>A~|po)7T+9nVvEev0R3cz%v&3!Y!#`6crI74qrD^C6y(@O+FXjpq|QpCbRy@V
> 6DP
> zui|+P&wu0DkLPtfZ{Yc3b!>)^A$rm#);pj+eMqPf_ibk1-
> Q4>69CV${IAg&>gQ1Nz
> zRT~v_C95wqUSOWfiB96%7*p7cWAtVa&GW#YARQ<C8$H_|n(mkbx1Epl^<x
> _LZJeA$
> zY5>NnHV*eZuw6sJt7jLWa27omiTC)P>3W+R2Cjp-2N&04C?9kjT-
> <=!;9$<d#mzji
> z+z+K=6WQ-@^(k13zS9DA-
> $7sV!NTM%$Q609^~}8dE~c#q?_r(|1Vx_BbvWv0%j=ht
> z*EpnuaL2q(O^(rd8F+ONFQ1EP>oK61X9GczXLFrzYrvM**E4tlapZMM@};46y
> d<yV
> ztK-QTyv#bT)_H-
> LtYaJTI=(vY16wfYW!7<u&I|2m<@JSiWNS#JJ{n@L)P89=Z@U8N
> zI&_SIqQrb*w$h|$XHYatS+DalP}HS-QTMR=!*x2b(T0-v_-OT`X9v-0=-
> }!eU!{VQ
> zm-H>OQqSY`T&ABMrBdi)=(imsniCuj-h-zeXW#n^F5K;LWR-
> PoR#`2_KfZpD$;<3}
> zd0BZi9e>}uCX<)h_nt+Qf(Aw>*}=SykDj@b*O?rvCOvQ0dD+K3$Cp7rU|)EgV}
> $nu
> z4f>gQdb0Ai_<)f&FgWEn`PEgKyiI!k2DQ)h18Xe*^X>lbGZx+^O|H+%`x&#{|9P
> 4`
> zoXOjy$!8c*8N9ccZTHX9<SUuHO`7~TEAP!_AN%KN^5$;_(d6>1ypJ;Ojy2bOFO
> !#v
> z=f~)685%tPKgaWeOx|YO{V*$U8E3~gU;G7k@r?d!;(2XWUNZiVj|cuBlb6}<d0
> BZq
> zYPCDo%KyYbn3c)cMDk}c1DO-
> |28)<ngdacmQ%_s9Hz=8!pJ}4?%vIO|az(+%%M%{X
> z<Z93X;wDZd{$M87+t6hs`e%F$8*zAE$1^VNbKHq%J09;RKF1<FAL0Em{QWbY
> ^FQ@D
> zl6d|D&qbg49NmzP9628R%gy7jGoQcwH)N>mgki(=`_X^h9?yuQ$NcXP9SJ*m
> 2Z8Uj
> zKA+<eJn!T2e-1l$cs|5aaRhb3lf+YwIz5U<7Ouw6fjdgPc$~cApV#1t-
> H#Th+HT}e
> z`4i21>ysB7RZ(?)D{Ych@)MBmvv~e0`b{}<6}_o_Wl0f2i$+`q-gZ|1-yu)VE-7xm
> zqof$2g#wFZQglq)h)(3vzSsN<h$3XzHloW2)_;v)q;(DlR@sGCesCP6MMr7O#I`|
> R
> z!?JTzF635_*Kk*H``&|X?G0@s6pB2svc$>yx9|NS%S@)BEinp@bx(?QUWO~F
> =WV~z
> z(bf}dn)D)`mxr{aGp`c*mIUbFw<H9)y4xELOfSJpv3eYNq70O4CDc)FRimTawy5
> ^K
> z*{N?dQZucY>?(xGH_Abny2QxF9`+?0O#9vpHX{*^GKkMUJ3hKx^&ZX<O0?S
> +-M&w7
> zvgJa1Q92g`FC+O@2{-XTAh3g4#mF){yfzzlUk1krWA+J-
> FJ<8<c&Mw*Xm@)iy8R`=
> z(Uwbz307?4sFTAKH*&Xd*+(4H(4I+&?(A@!sI$Yql)-
> T~V_p&*Te5HzJQVJa=xBF)
> zCc3>vaJ1!8ZGu@i>f~Vww{UrhIO6QHk!5!H^laFc431|qrbTdkISWU@L*<##?)
> FS{
> z`^$o(Etd}1*3r30xzkH@HB^&?Te!3k$E_x8hK>^cXg2K285~zJ=4HY0l`I?u57-wq
> zqTTJ8==N6xM_VpaO)!g&I(e~#TR6T<9Ni{t21g0+#kRX9gyjB82FEuU^NQg3hb
> $Zg
> z581DmXm@)iy8RCWbJ<|!BKUxgI{8Wow{U!gIEGEw42}{WuwcQS0LU^_83F|
> @1Q{G*
> zf)Nw|({r8Wa8$2`8n1eFbjqJP&vHx!;~vqD2=y#BKNn)F0sN<%oCJXd>OT>9U{
> VQr
> zlADoj(GnN`GA}ps>S10z_Ph=<FCGP3h)o(ZF9a4S9K*2X<#KdLUM@$#!sAa&`{
> e<6
> zAh1B4nw1viTWJn3&1Ya_cH9wIp#DNmXv6&r>c4M59#a3`4#=Zz<#E-
> YiuOVEzbz{-
> z)L-
> %%RR8h;cu4&xXQdrfe=_nx_5TFCEvx>vZc>0VL+B<8UkotN=qPkHuLG~EK>M
> D2
> zkpqf{pYq4ECI*?ZQ4NoEdaCQYIr)2Pmm-
> K@=m!1l2K}o&wTpDvc@pNS_2bisDc3QR
> zAXTjSihjoo>{&y5HOR$~3mPs<EGj9jd7A>o#J0O{w8adw$9UF$0D%OfZ~`GRF
> ^QKZ
> zw#D8a8hgn(@ufst&D)M@hhz9luqsptSTE#|Ld<_@RCvO{w$y)qybCK0N2QB
> #2rFt|
> zS#lxryHF$-08hpAKh;7ZQwqztEcQ}y?8ThKOW6pVB_+1S7wHn)4-
> v=qLv63J!=kE{
> zxowBq_jZgZf*^s>k<6*=V!j$9z!n{tT*9dI!8S>GN6Ce{7SWOIovC4hDRWGJyo
> +n{
> z=z@bQOQwIk3pqQYXIS_<5NG1wF~ZFZkr6PRPJxHTwC_F3aXFOv-
> 9_yemeedMarWby
> z(+QBV+Dl4eO+`0+b>WLa*jWKyh2RCS4LZAI2xP$i)zM+<AUam8sq|l7MDIdgg
> $ZZL
> zaHNdhqbGjd=l10Sn-
> U}|F{wELIIy{jMFgC&6HR<~VQe4tCr%*9l8m?MC8=U7u~8LC
> ze6Y=eKwg*yO+?xub^)Kj|6lqot=Rpa*>6Amf`0qq|D*l(Igp9m#p=3mnmy+K?
> XFv4
> zB4Tu1^*sn+FRGcC=U#08`-|-
> #Xd7gS{_7GQIN=cM!eYW1O5E;@b9L5T)4dTj%j|L_
> zF86w##i{Ug9ZfOzCN6jLhB?jx^k6?n?^+GLdnV3mV+}LYOI3b16z7iAg?NDzJh(
> %~
> z3tR@`YBpY=OLL@7!3)lZI#S-m)$Tnx<S+=qubj3t&Yhzu+}*z#*7bOA8b{1ixRd}{
> z0ea#)5|?9pofetA(UJH)85>Yl>U5ZMD8>!`*j}7~-<k+*jU7G|+lLEKTY>Yzncjno
> zH}Vw!*4UvVjK2;RIk6FbIgYDfZ~JQA#o|TA-
> auU)&G=NP)1<sY*!Mw03pQ$@9Gig0
> z1X>j$zQhkZ!l%V%6z|}&^+aSFRE@tUrtn~wF+Rkrg``}C+W)FVY8ArurJ_Pey#3
> V|
> zU7k6P@pwkzITa7TFU4~ao=JF&{U_+&T?ZHA_`Wy)2wAZh!5mq0$Wu)$`x*~
> Bhwp=-
> zz>f~%xQ1~OMK8c5JseQ@MxNCJ{@9qNIi5bx3;w>EBy*x&L(dDD^D6>x2lu?t
> 3|&lJ
> z?WkPzCrs`xVp3G1a1<ImJ7bv1SnnJ73e;lQEkwD3qu<+j$T_?bg&#SnPx9OFljE
> U1
> zt1EG(oEIJR!G(o7wBHIPi%OMCmT6RF27dsIN}#vFsu0M*pqfuu(Ms$kx*HFVz{
> V{O
> z@#4DZ(0b{FIJcCw!DrxG*#2(EV%MKKKWdtN@2K{7L2Bc0WHN>9EqZv?{1Tto
> 2x>g!
> zhJi&KEQWdITAr%}xU6{0Y-VK)b#O-*5NIbko(+=Fz!0vBxL-X43zE=H)f`52HH@0!
> z6jd{>TDYOMW*j#@Ww`aFngxgV`q^U00LPP~Bc;xJDIcH}VKy$)IJ<=zxKWMN
> dG_#M
> zTH!F+HL~Wgbcs)$o)>maHo6rQdMGqL%IrwC_H6GvxHz5FcxXa1o;1TPSA9mv
> 4Xb~+
> zpNS1bU9;i)(8~s<w6#AFKYDui$FF@s4pKgbg{^1a^O|rB+j$NOC2Ug})Zxoc!p
> W6d
> z*h-1<ENi#bxHCu%&zc9&78yz|5{emo$Fb^iaGcy#<U4uM(^3~{E<t-
> f7wY^lIFi4W
> zw(f?sV~mx^S?afqEY6#JjB&XA47iSb?(z_*sKf>uajAv72war<wyjg1!`qGr^GlzD
> z<kdMikyDK~5?#X6IaYqE2>2hw-
> YIwU<py%s0biF%3b{dfuP{8IDxAY;&(eYPny;aR
> z@ff^B=oLK~z3}9kL!_M^d7d>5sHE;+G9Evb@#sb8ZtNTZK0ZN4`I$PMZNy%V{
> $h<-
> zuOm8z2M|aom`BP`$(u#4FM(X=NX<)<^K)5jh7B<5=!rn&<eI}85&l-
> 5#cYK@1F}*}
> zfq1N`FgY9<vE0R8%@9s8nz^q+`Cldo+f|Ga*czw=7t%PTWfJD!ixVGmh>RQSe
> 5tnJ
> z^Y0yz0h|>*#fq3!IXM%Ne{V6kgPw5ZfD5iufI(t9>lKr2y{UOt!mJ$gziZF&>`acc
> zDo<sOG#H7=glD03ZoEF$3sQZgc|zrKOo@%1oOQuHdmPbQahte8h}J{qzgsi_;
> 4ht+
> zK5KS4ut%!<Tqk4a;!-
> 1e9D12WYNk3G%_AqOh)}&G$%7<v9vc&ZF4Utx`zvpgGcvc-
> z!R|l?hjJ5#R@{xKc_)KID{*L&_2}{8FbekN*{mh0f=o-_@{-
> Zg*%PXak8GAv>73Gl
> zv&3wC<9?dNv$M$%f#q0E7$Y!Y6iWNCPlEZ{`lK=C4V;{8{B=N)vxN>a5kDt2CF8
> |W
> z=Nw8#>D;IXzj;w_YIHrVy`;XYC%>pz5J}ysC)iu{VB!2hA;6jta7Ktj)o6TeX+ds^
> z#5&jK1K5$8Wc9k)_rf5L5!o4Qn2Dpx`tvLoW`KM-
> hcs9o0rFtkXTj4QOc#?n<Ne;6
> zL!Es+eV*F2D1cOgogN%DR7D~;VIp+#$gv#0CZRc^()f$HI4!4~a5H{vxVlTuP@N
> xk
> z@g-MX`@^hrYk--op8t1l78$qDG-
> Oy|i%1fyzdbA|^s(zN3m#)Qy8y=uwZ2ulgx~@p
> z)(pN!2kQgT#(d<8H56yg2gbTD1WCmbulvTM*!La!wTyk=&j2vMzOO<M{G^~
> <+}~Yo
> z+VF*aUmUE`_I-B~LbXCmgmH%>s2TgdTO_;0LoK9LmVMu^Gv+AveXo-
> 6jD6n-zq9T8
> zUXLJ<#BSfWtAS<1g~oB&_x;Mhu@TM%PRFqC`{7~~dQ|(qXnoq+-
> A@3^zVB{)1yu1^
> z8O8dfUzUB}<%B+}ecweAb4>fbGbGxu?_0``tln(MKUwyDXNi5^f6?}R8;UVw{
> ?qn-
> zW8E{Yl^6t3>F9<$%3fFJ-
> >;g!N>lUuRm&pw4U822XD_W2OUN+aRsI&Kf%4O6DFnmF
> z)*s%G4h)oVrajh~S2-02kYVo_w>&9DGrxJrk2b_3sZ$Y`D>lR_I5VzP;#zP}54YFT
> zu|qjgq--
> {0Pn6hZnCUITRrJ{5+$b(FH<|hN0$*5Qr~TIkWGDG`N>~G~_+nf2^6`U-
> zYw|zT%sepK0mY<!*<r{lUr4VFFe}D7JdQF=df~vJjb0}n97L~cJHC)!MN)^O)5{
> @o
> z$D-F^V1(<3$Dmh}#AefLtArW!ItlwP13TmYMtUu|LDTCFlxfl{yMG-
> %Fo<6LZ+;=Y
> zx{>d(`d6#O9gAMSme^y_YlFmQ)2mv-40^p?{J%mkoG-
> =<iv#KfI6MoB{<aG@VxIz&
> zPv2CTd@c?z{Ig6xuWiVhd|+_AR9*UzZSv8O;n@I}#A@k-
> naL+fkHT<r5pti_@NpY%
> zVW0$Wos=-
> uEMaMO2{<BLsyf!&O3;wH1SVD^?Ilphi#Y}6^H>|N!}FsCtPsYFS>ZCD
> z`?S4qKI`vBxovt{one-n{@1LU!7Nm%S|a71iIELPq#<>=OsxJbp=-
> wY<W(q_B^Efu
> zyA~BXoV@FGDVLh1Je*w$U`o}I@7rppA$2KCtV)eiIJqag@Pm~sU94i|Lq85U3
> +;8R
> zng!OStuNu?Ki;6#>LS0QNSvlv(N)TnzP@$-E;)HDF<_X61BcXh=x|{9SMJGQij-nI
> z^rDqh5G+DD4@yheG#JSxXek1WRXi+TA&&O95eDn(h8g$sX-
> >DmJmOpspXE$_2`wYG
> z8$NsgGcY_JehvU!{_v{CY}}^;AGF;B%UVxQvgVJzI*}3fSEz?jFHF&OurP);8ih@{
> zL=z1hK)7ndtpoU)=(sgL*QJusR$v(ftxvoh_S=1jp%aMbcwPu~f(QUa;`73#e?h
> M;
> z;!gwmFJ@#Y(s;q7AfQgT%dqUQ)I}U|-Ucd#f;hY<P}buSn(I%u#-
> hQ$asP<3T(x)(
> z>H%MdLz*F$egZan(EtdWJEZ0i<yGiAa6$;TSey_dJy3`BA_+};DagsVxuvZ}o?KJ
> a
> z)sM|4Xb1z_xdDV^J*k_;`2RW5>&Ao1d&)V3Q8?PezhH7Mxbo?~HD2LL{sQ0B
> j^*b}
> z7sZP?8K;UMJ41s;L(E!(24iBo`Y+=b7gkt14Ij>lS2ZR_4{t;%@p32pb|Dzq^Nc)h
> zW;wB^<*2SKLkKSKym}ZIB;YTBfgiVX^bLO%K_EB*MoE0!i&pBn75z-
> AQV*e>`iq|7
> zt;8A_51J7S`nopN&Z50<a4;B{IKuqp9#<LzZ{}Zxt(+TfMRP)GJ_SQLmbu=X=53E
> P
> zU>ugztRcgj+4@YZo_#=4pmV3_)!+%1g%2Vl<xAl<eGCeTe!wKoEL|LXu)xzy0`
> h@~
> z38|X~il90%AhY7JKIq7bHPh$W(m$64q0<}jNdI_NteGA*7_9Q|&4SSBjd-
> MAloe~H
> z&j}ADb2Y1QaR$i1--
> <^Tr(|L?>3QVNO3yQg1_{jcW<1ijXJXCtd13JwYnK0P2EwSn
> z6_51v%VQDPjK3a%R{3{lAO^-G{SBE|v;5o$mPbbWU1E<m+SiCj;-
> airGd*~WmHtx<
> z2n#(Uy%CS}kkD+gW_p(`J-2KIrZ?h|{_(6>BYmtJmeIIg>rsmWl!JQI5?oW1n_E-)
> zwE$nZ!3Ebav?Ebj5@CnJ@{Fm(wG0Y`YLTFyAp>aqDENvNm|=gFFlCJojjgH{m
> 3p=f
> zLrw4gu=>Ll)>W?VB7?ib$W5<#MNlsUe{n6wsWv$RCnmT6<mO`OCoB(qgf7G
> 2e`~zI
> zpt6kfSM&_V#u*DY*Ucb>aNdHs<H7qw9h?nGU(9u|aR6mj8$TG@hE_uhK`!Y
> ;X+Rq^
> zg8vh#RwuMmOSCJU8wRl>Q(rvYxC^BgeGOOee7M0Y#4*Y<w}ob`1tWn<7P?
> 1A_!)4T
> z{?UtI7#=oL!~zX1BJtj3_$fruI0kM<OSG_mF_`pIM2qd`k{k71ALbaYy_iQr+hCB
> A
> z@BuZ{h<uQdOBrcp7Etdj)+yIB@<Ep5Z-XIvqa-
> n2yvG1}6d<t~{B=Z64^JPE(Ix|G
> z1L6}S_*>@hi{6nK%>-qkzUa-
> H7#L7tjZWORKQV%Fu#ahmw8pCTJEB;&wK}2~;3}zM
> z=mZVPS=|kzM^qF*SJxkE#abLwJ62*jm25~h85=T+Yn@(L9VrGKy{WGzMzGe
> zWNczI
> zUxP|%L`^-ykp57M-gkq~piLx0nXeDa{1JSuP|umr%`_+zh07R)>pIOyv5CYEsK-
> oz
> zrdU-IuDe1WfUw}kU?GQ4K()!R`f1J=JRJ$~u<|5Pmtj{3c7xg2yD`{ACj<4C+p!!y
> zQkz0Y^`!e?hBX)eW5a3f?6ELhS|-z4c|2=c6M6iXYi!e+h732Li6yb>!~r@?grW>e
> zUL|D%sYMv*kePu&fAmW1QK9p%j?Tnq&hkqz!XQFV%YXD2S2~srN9*A)&4
> $C2tXo7t
> z2!LII@DYw4al=xfzWOHRJKFH0e_xTq*U-4cKV3>^rj$-
> vUCk=x!**Q?JeESxe`HtY
> z-
> eJ)tGW(xllIgUyS!9w$#RIiAGHFOnCMH(fSKG)m9+g1Vpp!$DAyK0p`ztS^FyQy
> D
> z8?_eG0tH}7#1yzitfp-4#r?<;R4UNDOd0~)%c*;m7e*4$i6IIXU>yY0i%X^nt`kjM
> zzpdpCeMb_aB}CSBxp3AY_Ek}m7W+}M$U0uwN`q9JmWD`k7!=5kNCAr5CH)
> PSi?nE;
> z2GdE(cmejfY3#}ixoP&jK7ha^?JJ@4?q+ixtrNgETry{xG(I}PXz2vtrn0?9Bd{Gb
> zpsSn55b_taN%PdRf~fHbc%C7<<&YJ2i@#)8xSq<LKgetoG$k%IDe(>5(6-
> 5JfSIgb
> zy^pPSCXzy8*O0o^m{{el(yhk$)KaNP*zC<;!!$4vjnSA>=65gSV4Wx{By{hIy9V~
> |
> z{WMQu2O!__?>8&R7!V6yTXHJYxBh5!c57nL^V=|E23!@FrGrf>lz2|75yEigv+j
> F@
> z$&v@jNz|`p_8cftTInV2F9pUv!)BL%&0(}@)~2?V-YWkGe<e&-
> `2+NI&<Arvm?~HN
> z;k1fB4f>Dl2LWFY$(T>c2=2jJxc28*hoGy)?sY=q1_-R+1;S3Rj3+FIO2w(ie(=*G
> zs=x}+Px6yzB2DDRa8!}SMVx9x9a|N$M{DHkW@v7>8XZZUsMpir>X9X8RF01N
> SZlrE
> z(jju|fT#{Lsv#22MDg&3YBZyu0l{=sC`#uOxw?wFWh%ffPJ^Q|KUoFVneeynV
> RuFi
> zdok_}r6$KjT1IKQ1~$|IPz9e+ed|K$wcJS1<2QAH8$X~7mQ0x94U6Xa$u9{<?#
> N%B
> zpF9n(Sdn$W>=@>loK@G=g$|<>W{*s8PZjJ3-dt&Oc`7-
> OWtbeVh)n}fx;uCeSMM-O
> zKFybg2G`%42j_D+#i`EJZ!w72JVXL6KWZ9@ZAF;Bs8Wzi7Ujuj*C@uWS$=XY7
> @_oP
> z$cYtV-V<idYIfCt1VQ~t6OK6nodcJE1!!Qk2<uhsL`fFDqh!%=)GPpqZe(O}iY<#=
> z#6U;jZ@D#IBePDZd3X70aIc2lGx5jYyt}4aw@SnA`{YgNx46!C7(^pkU|JF$0Y#}
> n
> zXJOHDp`>_6xmZZaLqY%)1_6d|kawCty?XR>T&tsnrTh)ENUPKvsh=CHuLT>2K
> o4?2
> zOF&)tig1R=YT#thmS*8pkrnQ1$Y%y1enW-I*TEbv&o!_D+7c;7O=2y-
> A)u{=Xa`SB
> zYhw7Mi7K{V7)Nv*VXur9b$*SFXVPpa{Af2JzUCcL3jQA+W4sG7%$1|LCRvT&3
> U$2|
> zgZ^+Ihx=qk1k|Ng1T$+uSWum-
> !=UusL;R(oU`0`4QFW;l%8u8F{2c;Sq@lnf))O0{
> zM>SudL|CV{aT@X^fQeW*d!?@_e%}_nvmU(_>bH*y?vN@z)PeLXvrz}KLZJ
> A=)|bB-
> z{)ntEy1rO$ec@!33hOV~HB3H<{E{2-L%y}W0WXf|EMjmU-!VQl-78^&-
> ;BR|TzEf(
> zDv<xr05Qq`Yb`bylQ*<4)y#nZkaABA>&}1AJ(Z+94r-7-+e_c2=x$J=e(QS_$1`Nu
> zBQzkD+3C5h&^-)`8{3|Z@N?`xs=qJf!UNqkotS%v?%-
> vkSKuIW^kfNJI)224XRpMW
> zNOjJNBV3|@F(f2=dv<y~qn%w1Q$NP^!eK*u^4Oeuhz%k_j%6OmT>rS#vg0
> oQr*~WB
> zLy2Uoi={7Nea0VmemB_i8>BF@==0y#A1{4QF!Cd-
> bsqyi=vuiz?NM&{8TcaqC~3e9
> z^pElk(;eGCN=a<S<Fl~rs+?Mf(;cQul$`$255im)xE72*FrGbQfI}1pg9~BZCU10L
> zA~|{1)FafGr|2ZZ?zyBmR#lV<aK?Q_33wS%zp5hh#wYg#wC55YbI1Hp7AlHfK
> n_$V
> zj@P&V>ILH~3aA5;#<K3rWe%@yVm^ZVK2xWfSuz!KgrQF2y#!uI=&S|?uT+!l
> 1%MCq
> zhzoID3HTY|Ol>ZwHO?5SxtNpS*F?`~1;E1_pxb~FtPC3K+%J<#K(NSievw&EKZ
> 7W`
> zy`X{XRg<7!g%Re}cbjf6;HZgiFXsM<yc}*XuKf`u705anRRY`;KxrU$W_WDkn^>H
> `
> zdZ>akYiCeh`?5>|TqD60I8e~IaYb7MjvkQ3z3dmj)~l$Sl>tcS5^QR$hq?Aq`BE}8
> z9^ILxr6|aa{%!Tgm6x(VPC!{DphGdTqung6$u_CZe!Ju{_Q|pADD)sJs-
> 0ql4eXOf
> z{?lVKHcEe-K_VOdQKouY8{J@aN&=DG13D#xrBl-
> D$|Tbti2AXU#e<$?MrENwcm_0t
> zq(bg7!)I-wE?4~U2m+opebNJrJ>+hbh5pdRKaly^hjo7_fU3xFL}PUjn2o`));I4p
> zIyEiT=uSNnc%Y}1`AR&sv_vi)+j4Z&10urBPVRS^E~{g|K|zq`i3_CbSx$VkUA6w
> v
> z>!k(thT14&O`oJwv*bSfz#GSTlrC4{09kM6-
> DhfFD>RmlKDQqi$)wL6_@U9~TDWp*
> zVMQ_B8G4e+;YO~hm8p9<QL^LVkntP)jE>g}-
> 08R^y8~onMzsU8O+l2@9fo`E=m=78
> zoRAKxAwo0MU5^|q1zZ{SiYf)iH*v@l=LQ!Ey3W+NV>=nrR6(~lhC7`Vy}n-
> NcQJU6
> z`KqYQ*QHqj+?;LKaZrXNzkyDqdjwd)0(@8sHc{p6@pZBygW6qM$Djcj!-
> Q<cVEUxN
> z8iwj9QO#(FJ^Kf`nt{RMj8~lfnmwFzz-
> X${9~e#5%%+lc5;nx`+Px>yxww|3vd$a@
> z;0D=Vaj1Vz&NsRt49cPz+K|HRR2*!kE!SbmNd!Jyvc-`j2Rd@}N^yaNt-
> Ox1Q1Pl^
> zNqTxoItgO&gZ(I-ws*DS${fJ($b&NjjwETB#2IlU0CR(iu9aliYjY0NY9j+2N6$VH
> z>(w(w@dGY-
> &SM4{nn;Ew<byiHJ)yxRrK>`GBVWtVLLW)8Fma|9q~^;kHIa>{8&Ib~
> z7sqhyA3aaFXNTx=o$zOUR%*NkGaZ$+f@s_t)Q+Pp@J{KfofYcoM~Nq_FSP~
> Llg2wZ
> zyLQ-PiY2D}fF-*=c_N|}#Vpaa{LlQ~Y-+->SKIy(<((<l9<O|I+qW$FN$a>xTrK&j
> z0@6urMX@9L?a0jVqW8I$4s-U8<fx9AEE2$S#d4?NbL-
> dAM!Y=G2mc`W09S^TfrE1}
> znYDKaznz?zabk3$tjJyZ$Xyi@?75GVD7u%ZcKVu8H56Y{zaJs|h+YMWHt`TYYjz
> P7
> zQ=1`Emr|}=%b3`9#yD1w4Hpt!M<fv5+C#k6SEGWkC027<kR-
> PAX|Zk`&5@}9&E$D@
> zZn<_z>3Oz%wp0{nOvSd>d-
> ?2&*hT0y<RDBIv0ct!<a}^{NLh7UY7B!06zYiK+Px(K
> zT*1f%Hh|>tfdH`Xh{L^B4$XrAyuk=g%vk_G83cf}GL(uI!2N>&3WJfa*Z{sU03a
> B_
> z;?+ui#emq@uHs+>R>duVFAV}H2}Yo!u>kT10Za%+FmYP|UBd<vVNx(M*#_|
> 9AOI+Q
> z&a(mh=OBO!gOM-
> W0BQyS6a^#bG8PUu4FZ@NjLfzHTs8<`dNAU%0gN34Ff$mLV*~j7
> zgn`wZ9gM*HyM;r?Ab`2S$Xpx1^Me591tVA50DdqCAP|gPWdpcp5WxIk<Z2th
> !a)EF
> zgOPbQfQttKEDA>aHh_}{0o)XfTw??H5XWD$2gQ<L<XRiR{y_lYU<3k%MX28l0
> =Od>
> znPvlcco4wSU<5l5Ru1181P~2I%4`6EK>#a)k?A&oFAoA(8HC@ZOc5go0MzWN
> 23HD3
> zF15kDGc=nNHM?pB<}w@1?m;kX1!krV=069)JSZ@;Y%r?^!K@dUavRLQ41(D
> pFqhk4
> zzA^~rQGuCYgE?^!4EK_Qk#lS??+zJQ_l*K`1}6%Gf9@Luvsqw@Z7}~e2<9omg
> !8B!
> z&SbTE5ZG1$JHZ6QK^<`Hg#*BlgH|35T+Eo~F=QJqKS}dXR35>&u(Lu1Wy^u;F)
> SF$
> zA<)dS0;r0_%AwQ>U=mmbKEn!N5*!s8X$3F|EEIo^4LM8a24(-
> >tZ$|$4yX<*fGJ9X
> z>Ln|Hg-
> pPHq!qv<lLG3eRsfTf2Gyfh0Fzu;p&qaTm;{UR<yHWbObx1USOH8jy+X~m
> z0+?iGKwWMHFv;woy1)uxlDQRXoE5+%^I(6{3Sg2zQ1xS<&8q#}`4#G2D}YHB2
> Gl_-
> zfJqhwRf`qCQf`9(TPuJ`mITz#tN<nn2i0R%0F&HNq1IXfOtLhf?zRG$BpOt=S^-
> S5
> zqC$nN047-(P_wN7BzdTs-
> A<KSVMw)>qrO5FSz$<cA4hpWxvVgzl~JvFMeZ_{uN=h{
> zs?!Q%T8>)yqq4%7Rz|6+x58L1M`eZDY=trHMoGKg3S(Lsb!w#*#<Uz|6)LR5L;
> yA9
> z+oA>68>>K5GUAqwX*8Ou&wHRCqSu(%y@gOtH$dKl3;5CxD5FJ6Ay~%lF$7
> D!L^K4;
> zFoqZh*w!5=dAl1wiK?!@KN<OsnbfJyUB-
> kwULt#eg_JX~>U$Bpeds${Njr|&gu1my
> zH{=&vQ3NE?$SzWq$*J=$BPZ<A;*{5yjGXS#IdNcPX?(jq-
> @URbO7B5ND8TQ+w$!Df
> z;Oq)SU?#b*0z8fD-;Z((zNfI-
> g*t~@SrLy7;PpWOt^m#qWpa4N4iJSDgA?tYDBTdO
> zQQ_A_eJ}h6Xg29D8o#CSYrxadqMEFeq|Py$2_E^@K95a#5)J1a_*wxqQ5Q}#
> @O>_}
> zra?BO!m1eSZSGHLwS8)|k%b{SLy5wS*wk7UH?-
> iC%Li(~MOKFvyjNuPFxxh~UX~eZ
> z3ykqt8@Ft!da`Usbh<18gne7${{%D%dnH3re>t6C@ZbBGXF%=LVN44(%R?-
> eDd2Nn
> z5|LBGzqtTUY51DyBSsWs#*g%Gu7|Kok3IR@kwgx&maZ&ed+!_-
> `*hlBI9g(SEQzD7
> zE;+_3J9RGJ3(zoSm0to36;-
> lzw5~iyw&i6XUiOl9VlS!kFgKWZ8WvYwQwdQW>+!`~
> zZn-
> #{0^D6?BS`0{m;Di{%YbT^jRSGwTH!2{HWa7c0Oq{(oDmJ+aya&4vr05*QUOKL
> z4|TM;#cUtXT_6|f1^unrT{w^n&4J7@bSG3;k?X>)zgq+Oxk_n4<Ae;nG_&(0M
> >_#`
> zg9+zU(Qg}LjaoEEB}c7K1=I+QjZSlj>M_gTnaMhS#98+nnVilwbJC21qn0_nDEs;
> B
> z4*nkO|L8BBZ(P)FT^2XMif<~G<>nGFq++|UB7>h7OD6fs5#Hvp)^q^CiVQka3
> t;ph
> z0IbNMh_V2BKOdL_R%EzJWdZ#6AONgZ3T*(t9t2Pvj09`|4-
> Epqq6}TvDq`s%04&O2
> zQWXGN5W02{z&XJPI=2OI-
> XMT;gOT|*fDwZLCI%xR8$fs8KssREx4;JQ(jb7z!N~PC
> zfS(NlI4>B1HpoIUJ_z8;!3aEZSO8%=Ky)S#XelRpmFA`FJom3;?=(Bl3hRrPh9de)
> zccn{(w<>y<P_qo)>XCVBr*Ok6_4g+^OoheZa96?`AH`9;mi!3?CuTW$5}Na^gk
> W~K
> z$|YR4$K<+Q!gaecTvvvr<!)A4T$dUebMKMw1G%omgX^|%(shKJ01^(%1gySt
> %RkR`
> zi7)iE-
> !&=4T9Ok7)Lb3LTEU|GLoAndhEv20*Hy>hy8q|!+x%p^f%sf^*@z7$+aw!x
> z2h@^#rQWP#g|}?<qh>UjE+l)O5l!fVvi!%*Xo436)t8KDLKl{e*l0!*yb$LvZJ8I9
> zjoxfV6C52)iKqnP0=l>?|0y$?nHLAuUL%^&C1oSFn9&3;f&8nZ4TdlDw%LF%`2P
> gc
> zpD`K^`;?t(NeR#WcB(th!X6KL>weG%c2JCY0rQr5ZUth(&}F#%frBHx;*0jG22pP
> (
> zdW^8y>#(4>NC)Qmdg|tt;ygu9YG>r$@Rkobi_oSD{R~&!MiN7?6IG+9mRoli#
> n4@6
> zN;OZZuvAa1l?@i^*qw`Ie}_!L9q8ya2o29g*5OkAH1~3k+(Zw(67ww*O$_x-
> +y`#i
> z5l{<f%Bib>df^SCjtd(d6)N_ER3ncn?T*2P)MghF&J@D>9<7uQE;CBG!B)!Y_EM
> 6k
> zWB*)=LcNXpKz@KJdbY%`$8)!>ZGg}s?T2$S7s|cBfv3N$^W1~lxAsikz7I0jFKA!)
> zvJ0)YoElKK?Ht&^;eeX218oibyYME`D7%gC{AP9=Q_}ngZS3~MaR2!zZOny<ZsV
> su
> zLL1M-
> j}676k$>5x2KnFIpK0VD{q7$&^3StN=|p$3N(mpekw=)NL~W%^wU?5_>9u1w
> z^2_4}H1ct_@1%j_cQda0vDa*2hF{RW+2eQJj)BdK@mr|_ZOywgGbqiYPZ*T!
> Dm?Gh
> zo0wk%wZWxUUS=TH-{)lVnhjpy>q-5N35><-
> @Jy0kbMgA|^F}lE)Xhf<xnY!8yAiEZ
> zp$_OcFp;|1xj0-
> 3wu8JjBQB_3Fyj13m!nNSAWyxhePVFBo|;C^UEoe(Zn|c=ZczPp
> zNp`>8Pmz+msSN|vOx7WrCi-MUUqIdb6tQ+^=#<U8UPcjErC>;d-
> ^AVP!MWO4s&KCT
> zpP*N-
> z>h%mCfw_>*Fv5J<=Vtu=z8E#o63wH?Rt#`;b?CM^dZmb*7JAhDtAb8v>`4&
> zzXm5B!nn0+FJl7BFdL@`VpYdPE?RmfHnYH>nr;^I#H+dxGR$udEF@WsPMxW
> !ZEnB_
> zCM{*yv?2HS>~&LtMQ1h^&1u`nn#$@;<hrS6;;Y0cptfCNRP}TN3)cV8c3ss_hi>
> @}
> zdm&*I@^*G1OYMbl_zozf!Yrh|RacdTtQ=TKaxBL$y@PbbrOTqAzh)Oy%z|(w
> Pn;hO
> zZnxw#qcQ=b9MZYKD96@r(l11PgCgF^E~52gc8%V|eUBr2a8>R%i}>3gGF5rHe
> h|HM
> zEjA(#6!Ew0B37^n)`HQ4Ycbv|Vx3V0YjKTH#GqPmJfeu6>>`TIS}=NWEgGg8gg
> V<+
> zi`28ns0D{Lihy-&d;f0c%)na6s7Iq^kD<k85lwQS5@V>3-par@FE1h|-alZv)#ukR
> z-`0xtm1E4e+^Xlc^8lZDOMx23sk!tPjf278x$8{VZ+e5BLYOK)3bc8@3($pt9+1EH
> zC@Bp2ZjoV$2RX~ObWsKCxcbz-
> {wcT;0V7_#6455NipGW0pUQ&aPRz~1jj*ele?9qM
> zf!<XWu$k&R*JW-
> +ge~B3CsIomYU4GM$k@|of$yR~9Mw$j1^eW|3O5f{#Qpjh#klYe
> zUGTST1wXhTt6-eAn5oi1Tfr8vE|^)Uv(17VKoKl;J5{9=+>i_i-{#c?7SF37C|*u1
> zRE`U8(8YhpR{V(U;#*n#J@(=)U|l@3P*3@ddUMGn#eZ}P>%AlSDp#F2(^NT{
> NO_5r
> zLvLuu{ZHWt6MgYLmGC`9k(2w*qAc;;zmrmu-
> 0kpfuCChbhz`f^S<zw1PmsTOVP$Q2
> zpB%Mm;W>2FCaP=mu&p+ig|dhVu$k)TxXNeVYz<q$x;D&0y*baQjjSh$_XM
> d;eKHTV
> z!Pz+xyuGG<4!>8FWaBFtg0eFZm?>pW;U%p)++;A0w|Ta~ItOyiMXmw014&
> @}3(7H^
> zr0;Po$BB?$=91(!M$ka6&3KbP!50&~T!=)#0ou3<b<=lE8!WdXZO-
> zW0PopZo`cLv
> zaU5k_*r7?n>!4=Go;2S^5~HkCMG8i;uz)pg?C{okT)stBhf|4$5y;~LN=~I{j&oa;
> z=Sq!AkP7`zu9)=1{m-
> x(Z;WC8cqaKYYf5H_X<zPGAr&rx^*HVxp>lD%P+w<BeaAR0
> zBp%Gig?liEgY(g+npv$7#-?q&HajY3s7Bt6G%WvQfOShV3)OR#(b8Lifspr7!E0-(
> zXb+rl8DZy2*p`%wh@Z}nLFY+ox*rAb0^FU)A($-
> *|CU%1=PkFys<tfmJg|NwtGC6o
> z?Y>3dp`)xdeM{+a%S%P$N_a){#_lZ~vKmLmo?^T6NDx^!x)DZ&J{pIH?3Ws!j}
> B<o
> z_!f*xTa7`uQuPP$0jtIqaJcITI25x`N3N7aICDBdu(FQ5VKWY=$|!cJPZ0w#E}0_`
> z#Exj9+po}QZZ^?myP+bRjbY3FrqR5_hUO05qs=f<xn4HGj-~}{L-
> TqI&6*LUgvI+4
> z<%Kw~30b=+sDcKbHwXyO^Ab<e)jOQz+-
> TytQSc0HG;dRl3oivh(1FTrcot;ii3?Sw
> zsv3OFBBuqc@njb2S948rwqxriVV#KdLPvu0v<b+5&_@72((`EnA$n%BYdjw}@
> uX;j
> z%06ytmMuK5vf+6LMum-
> @VkM&u9LvJf0=D5f)WY+8B9S@m2;B~wect*o&Tkrco&XS@
> zEYqgBcr4h~0J!&p;T%wFg!qNvG(5n3V7SyiHcg)mY~d&DTjcI`6w`vrC@?Wh_jC
> zZ
> zX!r*#<VW_&TPjANub-
> Hea}Bae#)K}^GSEh>aYh*A1`GULkT&tSP6{rJU83=r%}-xJ
> z!nHf6SnvT~13omzPzYCqbURqcj{!C0rb|FQk(Ki&!+^(o_>m6g&M^kA`waH9N
> 6i)_
> z7eI-
> Rn&&_vT6``&EpBVUpXtfk6fL^g(@wtH)`AwWZb4?Dd~?j6_H7~&;u$_YDo8dM
> z&VtJBAygM#BRSVZ(`9xv*BGL?!9;U|MstICFne6MTBG@}4b8l4G&_mrx4|&2j
> %ERC
> zG?|6^k<Uc4`GljQ3BtYu^oZsrLU6baKy$r`=6a3hdh;-+h2{@zXfD#She=J`TQ613
> zU>_Em7O)M?k7t``juSLNKi6ZT)&BSsxx<RxQSjk3M#3Okr-N#OQG-
> 9Z5KYEd<XAZx
> zRjIkBh+-jW{h(Qi2c;6B2Q$*9OVj#ETP6NoiyUSp+E|G^dnGJjT?uBPF0d-
> Gh<M;W
> zf;q4wc|aynQ6yT%@1lkz_XQ@h1K8wR6VtUC)3sO+$SGfo{ru8~>EF;%ZR`i)X{
> ova
> z+{Gfd1*|a@Ho5k4lia@^IsjAbUI9}|IYIR*FeIjH2}H6wO@{6)BTZ{fOlvi!wegTC
> z$*%8{VfL&I)626lg(O?5eszTnQwvyQ$}H4d<tC=CqhspC{VoH|LqiNSrT<DtmSI
> +H
> zqFJrctd56F5!D!GFWAt0T+1M4(?dipRW3W47O<`VUTmRxGm((8hp#R&+n-
> aUp<SAc
> zYGCq7VHeDtM2n0?v>K)3l7&Vd(;O>t_1PP{q-
> ?c&&zhB3_DfBM>36A&gyPz$A&3=f
> zvhTCir$tZQW_=)tm8z*=URDROfOUPCh5F_!lk5-
> i1nMB}hE3pSfFwJ|?Q%p_3s0j>
> z;R)!ju%XL$jV|Bfz9!ls$cQIgl$cV~>DlN4tW-fEpF!6G*64~9RX@{2_pp=bf_>oV
> ze_!%u&?~tJKhh!)o9qZiZ3yyRBgnV7uR$)(TJlqy4Z)Rq>Ne?#`?aM?VdPu%w19
> 00
> zj<FD&B?#JP3ru%JH=u3-
> AxY3v3BevT0AE^1H`|}@8ehJ}eLG@RJ8T5~lMUY%^j#Z+
> z02tcej;{r5!}pt)nFM`^>s1kn#Q;ekTHTRygBxHU$+WfwkrWIU@~XFHg=V;Df7)
> O-
> z(dE0KTgSJ!zdlw~Pjn5=`)3=vr)Q%JFtk6|l|^0)SfeYPw;p$hP)7(phmn;aR|JC^
> zRp3!+mYbR^L@s)4J4ToTQwsErq`DOV;~y*SH)xA3(FU_QeOQa(3p7p@@|W8
> R69-94
> zXh=v)pQH7lVlm{f>j0j@dBmfNO0Q*sP5@|fEYUx@__H|+`cw97nma~MfdYls
> *Z%_w
> zlxJd9&ycWPp9%Xt6^&;OtR^i9nEe)DrK%Kc%Ob1=tO?63)YoR1gpKR660-
> ^(+rC5-
> z5vt<>i~&>ee~>^R6t9CwhbY*P?(awE;A~v*#2J{4(K*7l&cSy!QsNQ5!EHdSYAf
> py
> z)^!+ftAiuE4gf1vcYsw{b+CYS9hims;dHYOzh^0!-
> ZFJaG{+iGx_$2w=?w*s?Ub4w
> z$%D0YsKsra00)%N2^vu+)GhU0bvNAen8L4GH=ZBT3=q;E*_Cjv4=A6&x>MJR
> yuCXY
> z>v_n%vh!CEhuyhCd?YFN#)qXQrq02YzH#AVUE`Uy8jsX6g>E&=%CYDK;TNz83
> )hW!
> z-
> u*g!7A%?L_{ptv9M^nvj^mrR&2juOGRIMS`y9vXcg%6T`mH&RAAWm|BMR6n
> 0Q+yZ
> z%yIk$@D9Lx!*d+J!!r`_X94yu!1m+W4Oqt*<Dd0n1{i;H27KE;bMxfOnU6n1<a
> Ov6
> z*BE$KbZe*)BRyVu8#QLkiDSl`q(civpX|0Dhtm2^^rYBSN0gS@pxl8Gf%9>10=r
> 5f
> zmo_&7({r+<adQ=8oM&R2>NN$7=cRsUDm_IXSz#!Ps0!nCV^i~q0ZjRj6Lb|D
> %<nF9
> zEsNk5o|r6gbJv;nWyC=MJY?iVFTm2|vF#8)!Bt|rO38X~!ppt3fU7byf~p(S-
> U_yw
> z2$LtaQrHpDD`cwyy@J^n>_J}Wrj|;>(4T_kiUSaAN<bjUS&mBqR{m0O-
> &#~1wgPaJ
> zi!hn0+W>(Gb*-
> y_4l}v?c_Y(a)R3D=5dJbI6hT?vX9$3nUlZAi>RspiY%O4Wr8FeQ
> z?b^P(S~SiEz6+7HA(zlgNOKNsVHb%Uv=P<AMm{B=qQu(G{POo=O2P8{zNh#
> FWx2m7
> zww*el98WE6y+BW!8-*d4$9a=11Y^LP9+f*~tsKo21vR_w0AGjUzx|}`TpF8!b-
> p)H
> z$y>1wgS&<|0e347p8*8hQFxsTCmjB_1Rxjjom2MW`>?)^)f=qC6*g+mA+&7)
> 5-_IJ
> zYAhf<wZux_d*q=?te!faknMngdi(1<atZCW2$!DP`vJ*=p@~on)`swJf@^fhm
> DOaf
> z@LbMZVVOZ1tV>%bl54%VWKf9izWjXQ9cY+!JmbgpduF|CneVYPl6tW#uuc$
> h>hnSe
> zMLg@3QRAuI$1lm;Q@a!IyM6EBMxp{b_#;y#S{3-
> 9Cz^YzKwaAl!YM?n7ne2SbRbBn
> zJsM!Ujs?U+O;D}J)Y)3V3wj>-I_50gq=QTP((j5(dMEyXl|sOR5eX3=C~4*0JuVSy
> zfXDh;L<1ePI5E33H4MLBPdV{ho;;a(G3kzke}^Qc&?8BAAnAszq)Q~}&60Fh@&
> IKR
> zCZ*hw%kEh3jJgEm9s#)_Nhc=Qy@NIsGiVM$p2>}#km7As1Dh+88wkV8vz(y
> >X6pc$
> zxyhwwQPedG%$5N#{^UHftfyjCPYKLZ17NO8P5?}Jg#*W1akEvqo*+-
> c1vlIlrqPmo
> z2)C)R;V9#IpFsVm8IN|ub=*802?o)YCJ#}b;L6Q4d^L^-8><lPUsHs`=%a>9w1sJ0
> zPnGF0L}iWV{_ThW<A4~{gO&}d`<IxS?Qco{$yrW2n4X<9LsB_OX0INtYkUgrW
> Xc=?
> zEk2mDm)`tfKStVhVv8zkPV5mich3N&6x3DNb3V!t;GrGaink2`;}$3|!{J#^?LVs0
> zZ*Do>D$#boS*0p1O;}Z;Kqy1=|Gp|shFC=I?CVWl(8sM`TK@Lbe#|Bc_2y~!P
> %=tc
> z<+mhQTCo;>SkQ_bzp+owh9@NU4UnuinQ2}Q+@Si&*N;LAMA@2mg>K&0
> ZM67KnMhU^
> zEw~kB(4zM!%}Z-
> L!rZfTj?%onM`>OI*DO&fSpZsan(WQvc<xP(gSSu5PXBv2DP6{6
> zl><d>&o=*i;J}#IyZ%b{%zYg(WG9pnnsUp7s!LD@EH0pac(X~1+tCwa({h&IB2l
> u9
> zbB=7|7_>NIqs2Ea$)ZInEHgV2>bWyZ=W5NHSxQeC7RO7sBwc_Chv%&O{)#z{
> H<!<G
> zd<)Ohm2({3c&@_x!+5sg8F%*_$JzLsdoN_VVaNKHqa$+pC+{dgh<745pHV|3
> eyEFo
> zPFUZH^8SeDAfC7J3`bcf;wi*47LQ$^Gvou<e>w4Z?+>4If!rV7RF8v&8NtZNG?
> eIG
> zFr^`2{DU9^xp-afFnFp!U-
> $gnS(17`QR#~9?MFBSgLOkBYIlz331`W&cN2{;7j@%a
> z?V3$;93UThwdVRdkwUyq&wU@EyRZks)(Y&5VCwT?Z)qBgTg5uqk$C;q8OO;-
> 2#N%t
> zCn=1hKFF*mf}whL&V@kb#-
> ?CjS#uORN|$HbED70mRo}!$adw3~5dS%@Gh_FJi9bhX
> zNcef#t4M*!ZRMXsGWBe$_<Z6nb0{PJ2nGSRubB7<<9AjZDcgk<D0SOR3E5V0
> 1SuYn
> zzE4#8GbzAUn4%vk1kY_VC1hJg|HNIXg-
> Kj7mT`w#V+^C#ePw>{GF;h5HZ)2F*%NPI
> z)X2mIJh9t?Qo-ke<|yO<8Qa>#q~Hu=7pbT9g=l-
> {!29vFXQE#k(j7Az^8LCw7~O11
> zQ(jj8>ixVwUnV%527=TJ6W?6KJt#_fXR?sYil;JNazHxPFq8BDEZnY7(*Rs_JfI;b
> zqEcu&pbsl)xI%Msc>T~T9qI~M<)UrVduBoV$aYV2-
> mHCCXq!%u7;9eh)ZVAR#c=Iu
> zEUp4Ml3<vPVKnCZl8=+pFV@aAkYahiA7!lozE=<=GBdn3A0@ud4oEM2QC#`Z
> 7@lUw
> z5EhS6xy!8lnEUxUztlfUF<G?H#DFQdmq83z0x%$_yheIH+`+(Hqbt7}^#R}Irf4r-
> zNkKBspsJLVkbdRtY;;^rRiFACr^5^JlH`krhQV<{d=eygg9-Db3{A^`DuuXXzxn^7
> z?QP)es;d0&n>V<$DK~`_1C%z<R*|++EGVT^(!zyO2quvr$csgxW`ZIEH@w-
> Ggxg@#
> zOPo5whyyq{;ygHiM$uuQI0e#D+k%}jg^m_zF)b1I<z^&mv;ji%e1B`7bM8&kB
> Km)x
> zd_GCe*=N73z4qE`uf6u#YvsSl5L(6=xSrGu8bo-nTEgBge3`hUqYlMPIYP(~F4IfR
> zl49kz1rU?#iQ;*cj7rO?94Vdx_)TjLJ3rQRh5p<S*Asu58E(v`U#$!*e3Jji?38lV
> ze86)>Q&9zVi2|zd-0+}>O#X5f*!T2?nuez0FpFH{6l9r<r$XqzBDjkSt3ZErvf8PL
> zICh@sLwXI4{zEZ5IY<P66`#|wed-DTDM^-pYx;(5EP9%JP;I94d8D(746FCwd`qJS
> z?)~XBbWWal=f&$GrHYOU1riyE;i@Ls+-
> VydY)1!k|DZqs1F^*2T>)qH{Ex9#(8S@t
> zx6KV2roocL-5W^lsMA!3j2qmZ;Nx@lalK~JBCe>!H`i1#5Re8}cW`lx5^e~xjLA!-
> zT_0NQiOhPUjWLet@y}Cn2Rnob4})p7y-
> <GG89Mn3#fqFD*Hpn4P)*0vdk$@3=S)L>
> z?nQfLVb$Po>sv*Oc^CZdPQt=_W?&j~3fH+iJn46ss=E2s&f3=c%stYwXBJfM-
> EnN!
> zv@(1vm1&ggGM!Rf=ZE<NKI7&E27upb{Tm{CXR?*NR);Xu{Y@JfIl;S;&d^4|_l
> mtQ
> zA4_n(Vj5}NAaZNS7$nS*fS5kus|r|*Z{<9-(%4E~YlShoE^MUbj1c_zxKgtD(jD{T
> zL9*4}v0!2V;60{`udmAfQiJ8ITZnJ^;$SCWs7T+=Bus^06|AMO>BTeDKgFqvFo)Z
> U
> z;y=@{<jpnShR#qmcYb+GVkC@JxnuyPM!Trx;{j^itB0t?QrO_se1_+XJb)c_@s
> WL-
> z7y>S80wZm2>2G4?n|?6zeOXu`hx~23Z7|krFzAr*16zs)!%!5^oF9yzP)`BbAUw
> WG
> z5H;JWCECaEF@mw}c@gk_VA}Nfcz)1C@V-
> PeXfpNyIev7E2s;*5W&c$pmLH!l2Hzou
> zi~i0d);`W%P~KAKzj4<+pkbF|-|ttFkN)LN=l+T^+13JZk*5N3O5X};HH}2yKXDT7
> zH@ctnh>*s_4}_Z?!96?ZFHGV&!<qHAV^Q3vV;3Ww`DqwZc~GP#p6)5t<Tg!;L
> SbBp
> zDKV^XLunwTj^uxx2j+hVW^6w)2)$I8XKdYfj$~}<-
> KB6Zg}pcc_c|E=+H~k>{sqXI
> z3kTv~6~@0r&1E9y_r<@;Ma+5r#4H{Ejc_y;hnQvf0{+2G<8WlY#ia5S6^=|msT2
> 2`
> z)zNfFKVRx=WXgK-
> u+b7)A&)#|H;n|S74a%051SHF(|OkHDhq(H3Ovgg&F=zAfYm)$
> z>YIuvCo`HnW@1oWNFJd+nk9;>uD{BRrjJS%v#wRqm<KDC#yncFLS6L1*Q;NY
> jUMk8
> zyl{7*@&0q`Ri*D};d+(3sQ|ZHtfmm2#v}LKklWq>NqBBMd*pNq8EeRqf^l8|_b
> >H1
> zBM!#mz5kSZ>G1-
> b+I$O^{O3x=0VPMohbKHDQ2^JX^CwCKkW4VKW6?<4<p_U-(#bFO
> z682M*DPc;W)P$xXBtPnCaII$JE<IYZIZo(?(7SUvwi$U&FEQ_Lng%JPEbfA+5I|J}
> zRPI8Yc<93P=}iM+%^!?1P4P81Bdd(A_6TY;Lrz$A`XMPKxQZz*wCO(#CG0~DA
> Nbc=
> zLI+Sy4+bX{$ZVl@A3s=QZaSLCGn`QoHL^Up5P5d)Hj9FJXl}=TGG-
> tTt%L{XQFIBy
> zczl|I=Omuk0uzOkB%avTVe`gIDOxWiVdP~VlYX`S2k|vZ=Op8)8KIQUnMS>Plt
> $F0
> zexzSr6z^JP(_?ObL4?k$e24$%v7p0Ye}jI~Yji=i?<AgXe1~V-ZpPVx)uQEjC;isd
> zODE_{`t2nv*l8x;LEFqJ1<`=)>-?oh`mg7%7~{Vl>d!C;eXS3j=Zr_^K9u`MNyvfJ
> zc#!s?7t@tNM6@zEf9YYqiO(!Q!Z&gC(rNzF?bvyQLqn<H*d)AE-
> &N3*$Tb|_N{zrg
> zoqV>$?et+Nw~Qf;x4o?uZP_vUoEay#Yl$Z+=kr!RrCU*$a-
> Y_|g<!Dm?A$wCu<COc
> z^npnZvnx4a=yUV*X7aiB!zw#x`MK$HQ}|NnYQLr-
> k{axg*)OO<ecC})GyyRY33Ppk
> z83WhDtN7&sv?7D+$rwkN5~LFZwfTojJW*QbYsl56=S`izh`!CrOn3|@z75}bh`#
> {n
> z9aO}zT5M{?)vtTHGY?J|<UZ6aH{#{Ar}^4#cM3<kw6*aPKGYU8cLhWW+lp9fFr
> F7i
> zCw$tvYJX_ES?Se{KM<w0B6f3JUW%D!MY@Eby8xV_yC59eU1QiK#+s8&C+e
> Ztr9W7p
> z;j=s+ac^>oF+6+@ayG@t-lW3r_({G5E-
> @aJ^v87xVS9C!SpknqtkfNFrL1~GLzuq3
> zGS<=zz06Hk+{EU;oI}DTs85U$u<O#hsTEpKN9g94iXNw;$sO5GS_9GfAH>Tww
> RrAF
> zmXrG=eeMr5%YBmUG;(I!#c1ua2V+4p?)?u_rhUp}<P&;(_4|3<$+v^gZsmH|s
> _M?Z
> zOfAC`CgRsHJ$QTSB-
> eAi&~Xx6VD@uNg(V$hZ~)5q7@gi^g|=qRr6l{(WDi{mVsrG`
> zT<gWdB5r5xaHj_mAKw?fD3N%&TCIML3fS_JglzK13qmbz4IVYTKlzp!?y5WlFL
> =CR
> zsUAY`J0}cm$xZ=m@zY*YMD=EEC)L<HUGXw>K1d@{2k%6i3|?&Vyso07@zQ
> dV>*Jnd
> z(C02sOI$YzTU=o+ZZxxc?Q|Qv)RDij)UND(AS%mzG#Xf`#8~=PXkZeEVSPv&^
> W?xw
> zWlpm)>j(?FSjUu%8Lnadm@TrBl1E02S<CURE`n`ya%~7x?l;21+FUhCxgahcR{;9
> l
> zi<bVF%<B8xCcPMkwE2WG8>AH64I+H3^cl=LKi`7sew@u}kHT_L$Q)iryX4GO<
> &HvF
> z3qtnVmw)zOqM2L3Z_<7F`CA@SG-
> ?zH6Kt)q=UY%JYy@#;oxhRcq~?uz>)EQYnz~KD
> zBR!nGKV_yCm_hZ#T4uXbCg*2wK6BHMCa|h-i@6^|As>In0-
> Z@Gb=ho4i(};qpc+nH
> z(8k|kBG4@0wdm$EK@$YLfAEnmsf>L9L#U(+kIR7%{&FU2gZt%88tZc7Ok|7#;
> pvu?
> zbC>;^!Dy_S+gNckf)F!jotzC<b=0oQG_J!uRztgDZgMaPDYp|-
> l5X*=Sd(tBhZuO4
> zsZoFd40CJT$#AHUf8{fK45$is6?bANv^lw5F&zcWBLW6C@?TV~_pQ8h0cH^T
> &}}fh
> zj@@oI(*RTcQHEP?wPCwdoED@N8PXPoNSkj+<LIV>^Y1wpspY0I-
> ?4x#kSKFh$i!eQ
> z)3|oqo(7LIY1R=gzI&tL%w4BghQvUCGdXv-
> LD!u<8R+01o~;;bUx^YDD(Qu}ChqLz
> z8QYKH#LEBTNz4k+#vFJ&ZP@mYx$+pW8O+#Rac^c@6zvD)c5%Hs)WZe@a~
> dmbvkALq
> zSRVAla%{n{%wUcd49gB(l)0Cye_`O5rYN%?7FFRkbL+*1W$OvSuuSOHux!oE0j
> !S3
> zURJ+4^$eu<TIbGLw9lx^B<b2-#hip4Z4u61eoaNU1k1k7XU){mJk`7L6-
> #uBZPt&J
> z!Grboi;-}NvxFg<<{-ac|E$&g0=y7WQz}O-wq1d*Uc%{|T5gN&lBRA=-
> C}nXQ?mdo
> z-
> LaOBxI2!`6Kk{2+4L~kt+0FSC|`obwwFbobI1m}AG9Z2Y(GM(QjS%3jnO9B+2F<
> y
> z-gK66189=wShi@(PjC~gF)d}$64v7$r81D5O{;-
> gZ^TpX5BMm{LM_VV%!f1aqo}r{
> z7X0?O+pW}=Y^{M67;fZN*~+|887{L78?!UWkiElXf*zMrBCf4uE5hOY!~BCjV>c
> hk
> z0NcXkjvzad53!r@k8Y+V`k*s=&#2{Nr^n4uJu$yJc$dO{MW3x(T?C0xXeGpo1q
> 6C(
> zu|0<78wzH>SoOGdyVd8etd1(&FzmoDcAJx8>~_QdA1%ka?3W~1JS(;!|CAs|
> U_|1D
> z0rOAF8Z4uQz)Ut^A|Yd~06*KRU7J0MYVGsbyr^-4Ybk)_u@I69EAm+OHO+n-
> )<k-u
> z0Kz4j$HpY(;Krk{iZXM%U7ul*H|UB+L1zl}6iZHjEOmk_Droc3u+95>gr7&VU#1;t
> z(wCBZpzP)o+>6`{3~}{HnEQIm{YZAcAWROGBnRL}H+y1vSiP>b3=e0k$q-
> tva;O)C
> z$CVTo9Ka3EtsPi)svkbs@9GQ7w#!J!k0vrxK!Fdb(!pN|#)q;$qu03~L+B<QmS=
> Y$
> zUmF=ds9Y~tt_OX95#5|o;{PfUMZSq8;_heuSn~`e*ZunZZ7XwsE|qKcqaFw+2r
> wR}
> z|E3J=P82w(aKt@MC%b=xlZ9BiH^h?S7jSDQhalvQ&hA!QAGOrG{k^|wda2#X
> );aSp
> zJmrr70)7OaV={79Imkpcf)2xu$<0>c3HesT^**x^Ie948gX;)I#tS~-I50UhJsIDo
> z*hsk&>WW&h`bWt_fAVWyC=cx?>FkKUM*F`R(f$O9!pk%!-
> vqJ_@{QIglW%$<1+82b
> zae_H}eAB(gEt_WZA!L}p_6xPQ#jxoz+ttGoqt!ji+_aR^R)uRFZ#>h>H|;jhfTj@
> w
> zvAds0H^kTT(oKym)VR5k5VQYkXp!%<f_ErHap77>$gy{t3uPPhp0uO>REhF+$
> F-w&
> zXK?cv;d>_|_9S$$Vs7o=u`k&A-
> IteVWDFSg_z%plf+d0rg0tOcClvHJ%Ite=^32yN
> z3VQqvYQrcBE;R__l!S}eJ>xBtSN&nyaLX4=dil#yvLi1b?2zkvFS-!oVLd2uf8#}$
> zM=N#zIy+Wygtj?eSow{iNX#K|=Qf_buwqw`Ys)uT@ay5!!f<fTvcb{PKU#{~o|
> mGw
> zXJB}F8LFtxebxiQAk3*9IQE6TFSGpx+jXA46oNLycDt82Li%ztz5d;i!uAP(ho~84
> z_SjYxt~%kdtt`0{ZK!eJWReLqR?;}2kbVVX$pB(WUNcj$A2^6S^60_k5yH^yfRq
> k!
> z$N%9y=Lz0BfT?NmS=h-JyN3hWVX&yB2<y%5v6fR@rFBkHZ(-
> )9spFVDs=}RpxTik^
> zjyez}p+;^DBBAE^rXJst>@C8UJ~6T-<eF35zaCLQv{7c?lB#eojf+}(ow^{`%?rvG
> z=*e?8`OHKY7?=Gn1_`B_K9Ya(yDf|hQva?EGg3LrKS%pQbXH7Wb#Q<#TlB$>
> Mc(*;
> zdtS%uSbn^Prk^H}2(wm8VMbDdLuEp%W1SFl{{FhmUIoO0QoF@jU`Vm_1hv
> 48Phx<z
> z?XjvFw^$NWL2ZtqDz*<)wcGBDQx)Gw>gUuGNfg1JvdZ*AJ_6uD`0=|V_osa`{
> v190
> zyNErYhkKcq1*`>n_=qcoS4PY<%G^{F(ZlTWaFlX*vL4)A<HtcG;s;B^=8t^j(o{cw
> z%M=ROg9KuY`ym?Lf5|A4!J8gzNaA0DA@<vEzyHpUbiBdmC<}80_=(Ctx|H(2$
> s;iM
> z?!#F~UTd-(KMix(cj6UDvQ!+NtvC<!Of$NxZreV6>ms^jojZn}aRnxb(X*7aLbujI
> zdn0!j!xJ7wv2L1x{oA|ZJ=&`~Kzro}YA@Yak)HSPd}$<Sn}kBJK;I_HB|=l_6XU;s
> z6d)xRt2b5_Bi*nPOmFt@fR2f?M^cH;gUGJKjA)ggI5Jw5fbasc0w<~SFe}L*rls7f
> zHhCe4389|W_Ar*SU)b9+SP;adcF@Oixw1t|2|-
> M*IaMUV<ms1jj%~d#n+<J3q_w?G
> zGgihrA+>}UXerGt%$;j)K_(k^08R>~0gFX4F)z90j`wi;Ti?<f4j5U=045Ob%or$c
> zu)s@(_6trD>c5-!HC_5q80mvgE{K9^Z|wWjC7-rk<SFp&pAuTT--
> p&N*e>q0;3<=u
> zZup~kc=M@Ew=(@;;J@+9dbm2F+nDJ-
> 1=kEGY>>05NwZajU3=VSE2<Mly_VI8O*1l9
> zoh$e5zk-320l(KppJP<5Bbgq)F*}A8E;yD$Ql!+)zSOgv+Vo%vd`%F3`?FVF9tn<q
> zIScjwGot<Sz$Fqd7nY}Y*Cg66r%r%ra7lAATbdpm#$PCENOx+OurGD82`W>3L
> Z*NH
> zzA`IvM3AFr^7@`bN=pA@@%@XSDkpMq{XgUgEa_G+oZ7v+`>n*&+tP0rr_e
> Q1@hjI0
> z6G2OofSwN%)RJI%(kJ+qROI0x$H<m?)l#puRNK3{erorg?za<9Z_uDz3&hwAr
> QeXz
> zRtJI55rl4ImH8<3XNs}n0<ZY8=J;ce2845oJwghHDBL+H?-&DG_hi4xe3BtysQE9x
> zS$rm*T|s*G1pXMX<stMT;@<gE(7zCIZ}@~f;$8}JjO>mNndT9<6JyEJw%x4^c
> w*%f
> z`m6Ja=CV#=PIby~ZVB!WVaRZkF-B6^H^>ywkR-
> wAx(3Sq!DU|x(ZO0;h>njKI@t8A
> zzIa?8_j!Z@H2&eTi6Ch>Vc7&HxhkQ8%!#MT-
> Qd1!ch+G5J8+Lgm@rS;*XHif+08Vg
> z^Gj8M7JI|07W;C$)GdO_jQ1yw#dfx{+Yf^-(J(-
> 0HOSFXM2=tNj+7x+d4p=LbIVgU
> z1{~@Quoa7aYs6N}C_do#;h?>X!FJ(s%}D(*>?dSSwiMYJk(4m3#<^p1RU<zmG
> T@s+
> z-
> wJfd)?V{)Q&snQ5o_tI31%BiWxz8PznpD%@8a1jV$vv?wILCD#}{xNL_)5CPii{7
> zPPZzXuWoXl>-
> =r7;s;_QdCqaW;42Z=@j07zi0i1ZOOzVd36$5g3mZX)vfW*RCpP(|
> zx=K1794SfJU0Ez$Lgm!uYzEiTPumRo)7{3k=<e*!H@xtZ2G!?6s9qUsZG^mVi=a
> BM
> z5GtS3L#4v*wvqs<F11nsRTs#S?q`d*lDUK0oa|N}91tyG-
> rD^o+?mRss(PXPb<LW{
> zy$$Zj*EG_ySY^jecBZ&=k=)u~$K9X%IRw<39-OJuj;i!?RDr4As9HJMrLy$f(_4-_
> zKqbOdON}b3bK8v)Wf=y#D#rk1?t^e*)N<*!Z)K~W<dJI-
> m$vA0g+9ZrWF{(nSG1h%
> zf&N-pOUp;Y5-
> QwC;o|h*r5L}+eXII=0AQJMexa^}?fUvY;p_9U0)~lmu9J7Vt@Gq3
> zIDmRf=gHQ?tC!C4pKf0<%YV{Yw|%;uvu>4g)g8&la);_G7nL&H_I=~y_|VA}>$
> XAP
> z++^jA#W`jo*hJ$2HoNCGx*I`$_uQmwnTTh82@#cZ8vAY`5<qw2hqaX@IHs@
> d)`YIY
> zB&UPFIw&m`YZ*0S*^}rU>1ijInQCTtyah64(%?6Y^^@QWMjScVL=`q4Ehkx~q
> Lxck
> z{T{@pHUhK7Vy(9z@ROmqWgZDsy5i<j-
> S^5gZ%*K|FQie_w_#ujO8e?tHEveQnr0tU
> z!I(&&ZEf)0y_cO|H$CKlq=1<JuvNso4o(%W&bBmrelddWNEhI+Pk?+2IZMHQ
> G(6s(
> zjG08ik(NKxzTKBJel_AV{OYPvwfgo)<g@lq9hI}7eTiYsCHidwV_i)P4?iDyb|(k1
> z-|gm-
> L;*YW{B>mhnx?vZ{_O|KpPr}WVYrYz>`Rq@M+r!R_v)~Bo*EfW9pxYPVH!S8
> zDM*3(T-bV~@2b&gC01Ho4A84{hdYS*sQtNi&FkR}y88&1opGA+v$;(-
> 03@>A*h5F~
> zGxE%Hx4^L?F6(nPT}pN<?7qKGGBJl%J49S+YA;Rcl>8y2gaXFiV_{GyHQj%zHF;
> *(
> z<h_TCXp+Oid9JjuNuSd<slx7KVUyd#CRbXM+p{u2|A`Vgz6(x*cGAnzoz~>Mu
> *qp7
> zn?!=0=e}NC&`Y1wH>twzS(Z}krA-
> F)a=bO!oqZab(EBNR_htnjE+kX8<3_ET+|S*r
> zY%f12<ZQKjA-ONHFeV;{e{eG4+?#x=%QSAp|7>%xy%-
> {cx5{Bf;3(eCw4M8@<xF<f
> zxlEW7&1-
> PgBRndrNMUv{q(xRn4uh$0AiYf2txG$HYA`sq<cde!3$giueOEB$677mM
> zS)gpO(+qT0o@~5YC!m~dezgr(!Xar0=N08~n$O&{JtCej4jEd-
> %U5Je)K=a!#P86K
> z59p;S4W7gCyLMz-
> Y~*IUZLxy3qRhT6qncP@TbOaj0?lVdp!po2U!G8!Ru;7NmS3;K
> zeho+$cWq%?QD)zkk;~oh<olKTNVxZu804P2!N?&vqAxt=#|;QHR#CWz3C5%5
> 5?d;C
> zL!_b<rX9@bA8e9Ql5>x5hNh4-Z$s7eq42~?`U^M16bsPaPUX8w`I0-
> cTakN&=)e(Z
> z$P4biz-
> Gx=O|gXWf?;L^G#~cdc)@kUNN|By!DgSc$!R!M*gf#}{=6Uuh~fp8smZ(x
> z(2y4lEwUzS!Y1z;*`)D;L1uf@q|fP_RAF~g*kr^DZnY-2XJ3~brS;06YO`HPtn9KK
> zUmQap$x}n%$gEQ0!p;pUS67;NoMVZ{FDyO|)8WL*XQ2dyV>66t8S8DwvO3
> Q~SQuKr
> zhq<K*Ja(ImyU1rMbVRZiEWMnYq#A2V6HhFxnESh>9}SZa4H|l4!4Y%&R~)OH
> 13x7v
> z_n)4qm#NxN$p%4}J1;EpKhfu-
> =Kg*u5{s|@X(e0zRdav0;%HU$f0RTgo>+iUTkTNE
> z7UaO8+&TKRCj1ojuOc;3A8sl9a98nhOhY)5L?4|?ZbZP?=#f<}11WkssI82Sd&*
> V(
> zbQK5o#~TL|kDoLCIE0Y^Z^p7Xo*g?|)@FkN-f9Qe??!-
> tofVH2czMo6zXny~>l?#P
> zRLt!+yjk+km25~lV(#xf-qtC}FaX{f2TL>#gN8RN@j&$XC<Z`yv*bIY`l}cK!`n?!
> z-7*Fov;i3Oc)K+G6!kB_+gXJlR*pBkCA&;ygv)j<;hMd`(SR}*gLBuXrU<2~fA({8
> zyA%JkzVpJvaM07OK5uxIo+P_-
> vy}y$v7kyZWlPJy*te~@4`gScX$`!As!*qW*pl~J
> zd;s~%VN)%(QmF5%i1Z<Yo05NuH6Nnm#HLaNb#aa876wwG?U`~33v+eWZK{
> aFNLD4L
> z&LDfxrK^EDe;gR<TV_S|yXcA)m(L-
> ^@FrVhd@dBQ@?B^x2+Sit5We*jQP8oon8w*a
> zQOjhV8*A@9JRwNOyn%G&Qu7q6Q{YrJ3*E4GlUM=t=QzQwXmCHeQoN|t=
> (JzCT27Q;
> z2Iw?XA%l993ZV@b893_`f0ct_AM(B5LcaI+vou8^-
> |;N3knfFGTitc;3Ou2k9<bX4
> zWepgE7zQg-
> eUqpUkvWL^j^^O9PpT{)0s4VM!MBG@MF>2GdPRK~rwY!YVyTl2>c~w|
> zKPCE1RVb854+yHffzn`B7ci}>(@X|ccR7q_yAtU0L&c$WH}$toS_PY~F>bGn%|
> $NQ
> z&j$L@)I}a;0#(|~gVxpZ0Xbsi;A1*xf*>S3OqT?rfsuC?whap5MkH_rT5FhW#H6
> !{
> zS_dV4bk#^oDv-
> Y|{_!uUcWpWBJJxb0Ot<ay&)@W=9z4@v8awBMY;(B0D7TiVUWO;n
> zJE80wN3$1WTUKAqjV9DYj6zH|BN-lDCP?pIlHxeO$}XQyOfN%We3Ue-
> p`IB%+-`QO
> zOdDTP%Rq4Xw@O!OTBfRU>56Es?d{`fFL4JK1F4?xikx+qUId)rY`Iix!|fF%Hxd*
> z
> z-
> gaxH0KEBZzGDlI&Ay!zA*!9i4f?6zSsu$qda**fBOQW8xwVm<DJ*y}H%s2Gsu`P!
> z^>E**6bj)FPdN|)js_5l>}RO%(HqX!b2cU4!3oIQ0>ACn(pHMBkUt)-
> |9N#7nnfAH
> zVX~sMj>dKD?L5%KOUDTnjYD(mOP3Yr%G`(7;GiiSAatxo|GJ!5l4#fUR(jEPdu2
> 5U
> zNKN#}5ccd&Gd`<?m_+*reZDlF&JyiM^WtW2*Z8jjuvkl3b_ddgt0pPasw9m3-
> 4S|Q
> zC9HSUR?wXyKf&GeUr_hCg@8Js%-!{O1;Dk)!;t_({g4NW-MB``fZ{f6JOD}#9T-
> 9g
> zrOcg6E$%xn3ZlCOQR+7L4c;=XdgBnlwez;w-
> t<{sLo{~o=?@qziO0JP9L67aB5zeG
> zk>#@+!~5yl;vytYO<2yRN0^(PwOwui!f$#IB|b0p?oRqdXA)ndGXQ>uNG#EQ
> y~#TS
> zKNO~~){6ljVA?tuU^*hfMEe}eSCzgE6R|s|gXvBtr&a@aX+Vfob#B^enygZ^z+
> 5e)
> zj_G7vdP5~=*s!v>$-YFo&-&^z<8e^50v(W}j=2j<mlx-
> LrdU`DI1cSmkgR&C|EWky
> z7KDgiSs|~-
> Fae>kH<tL?gQ`aNP$x=HzaCf8JEGSNJD{B^y3>m8Br=1~p`(iB*AT2d
> zgT7?DpIFQXEh#<q?$^+ZX~)pEJPVx{F<su_^He^|aj0Bb_^j{*o@Jd-V1Ijw-
> GiKw
> zJ1lo-Ze{iy=6v=~2-Zy2i5RvV9#Gm1<ATvmzO6f`y9^tnn8YR}hfLzhAP*N}Y}g-|
> z5LB@R=OXR0SaxS@gRs^Zl{ap6GxXMKRG#d1lk|qc%_@C%6?(%Sag9Ewmrd
> 2RJZMRr
> z!##E~x*f&mv`)M4@d~?(913&F@Owj1h4D<>OTTE4l)C@yE^Ol8^cFUetFeBR
> $8P?(
> z#{?=UV?yFcBAx?aQeGQiMi6g9hB<U4^#yZ?ktuWkOJboo;rUZNazm%}WXQd
> <M07p0
> zxu}boAu*)jG9f(8<R9hd)8?4vsU32^XrfTwzS_Q%{Bs5p45fRDSd)O*O}b9d=_D
> <z
> zwxB*?a>&hP>ixO)**|m2#1aKcTj5rhih<qub9J?q{>M@mx@&mL^t;;UhKA?d
> sl?Rj
> znyqtcKY4af3Nu0Ra-q?m{f$s3yv5krosv{pb{{2!K`{3AZ>#sQAsoQgPBu1LLA+aB
> zcg-om1Rm1lk)4&65M89H6tWrz=i-kg{X?q`(Qe}0_|hxj>C`cILFtNmax!Z%cUiy3
> zu!GmHrQ>niFiCk9$VuD!9*&vFRFOHSnA<-
> KvG{5^<^W$yi_<+dKz<9jm&g;Yc8cD&
> zUn?bbtYQbkfNYx58)sx^Q%7F(wH3{emj)I0xpMm;^GED0;s0T%$~JY9bdFl)m(
> n}#
> zHv8kU4VoM#9IR*A+;E4)G_4yt&HbdZ1A1|4jLMEr?}^JR9`~^D4n!L4imyef<KP
> ?m
> zs(jR?3*L4m9||xPxY_D@`Z6yl1~2qtnQbJ7#J~pImJJ#yOy<D^o#Gt!<Nu{qWer
> v7
> z$5pIi1|3UUdab1`KgNyYtxPX0LM$$UxAB3F3c4^-
> (Nnnob3Qyc>U_BOAm_s!*TU~{
> zJzCmIGZGTOaG{W}Q$m8$>~;qRX1(r~tr1i^6iUZ?58Tm_4<gY!x3)5|QkOGi#J(I
> x
> z#c^COgJTlKFTV;`kncI<$lgr(2386-CPJz5EkNw=O)uTTcu&(fBzrm*#G9l`0uH!P
> zkRx;P7Oq{cJ0gEji2Y$-ox9yMB&E-
> 0u4Sv@ho`m&{b+Ux)J01E?D@m)2R|!B_Jh0y
> z$d;`a1R$5{+dGP$#S(pPW2JGlV+A{uz##&LL!-{BgYgGybTlZ}s^x>hCaqQk?NlJe
> zLv8ut0>lilbmQSL?A;$WmTrBV(coU-
> l?9E9fqBLYOFP!O$06I)%mVF&pmi>bHp%`X
> z(|Dqo1dD7?L{=%{+ej)?H53~shT8y+-
> F5iM(d#=W(oBBCXYfNm)w59njj%81dN2CH
> zT%~(+awm;2NJx~Z8G3B)RhgNvI}I;fwyo-
> QXFLz545Yj*Zie0hDQ~Nrq&F_G+Vbcs
> z^oD_>eGbNQbMi6KNklID3)bK<3*t<+0U{g!>~9RLzIyiq%Ca7aHr$V4)tg&w1E
> SCP
> zRg>7h7NerJ+e%wWT7j*2If-
> V#m3VqfNA06Ji&j!c^3hD~qjrOYVu(Rq;e{IJ%0|;b
> zZB&iPjW`j|WwedgJy(hL03mzsIb%wf6K`=uN_@rf`4lo3J70&VJ}z$HsYH@`aqf
> G(
> zGnfRbWr?7l<Gpq<I5vv#V+0PG=t0bJr9PImZ49H**wazZ3czXKAv1)cQul)`!tj<r
> z-
> gr=Nja$9E!RYxdS<4mBtO?bhVrW81|6oG($!22m;WS58sVU^oEI``)!gOm6)?1O
> O
> zeasW&k*GbPh-
> cYdkDf&VGmF;$0&ePs<Ccq<OcIP+l8`tOy$QwIwE$os=_iMReOU|0
> z9kPJtRc_tpaMVRcwuc&FWE0Z=!cp|!e{lK_tc_u#wn|Mg-
> WIG<@=|3%0XTxywccqo
> z+iHr5H#KFoy0q<4nl{z&jGi1g@~pAE^TG<Q_=z`?!FVHUQap93)>$}mRfBu#Gl
> oSl
> zJ4YLh9_&$~ln)^(`w<{0L~Ui7MGz9u#bS9u0rz~zwQHGMc*nlsY>l9ib3v_ox8_
> ^8
> zJgV=qpoQC_6bQRg@lk`BPVEiuIt!M_`d7(iywa8vv=^8YOCdT`rfos)(N*W4+KSJ
> b
> z-P0j4aZ?)*=-
> kDM;eX;Yc>rF%EbQVZ0ssc1lo=5KmGUMUV&x0IcJ5VykeAK2sGL?7
> z(@O60e9f&<J@bQ_za6Du(?Qq3@PAs84#wHs%HQJdQV9UPG+_dOnU_;}36
> (QYT3vDz
> zjINB!oY@*BYppx*dI7&}`b+4|<P?0ec&gFiaW7OO=dF^0I?ovc9qA4e8K5xTD=
> SbR
> z9OG>}p)`)~%zq|A(DYnGG(bp9RrPKP^Z<=;d<BP-
> 7J`uVlc&(R4}+_4EPd8Nn%O^V
> zDOnGIj+ra+=op0y&H8Zut=b<Seer|OKOKC?Mj_x>NY0JMvnC>$+YFd!^RgyF
> 36lpc
> zO=(0hA3Grr?J=Ael*<9g-W@iAw=aJ$kPY5?W-
> bkuNFT}oNC&m_LrPm%s^&`(F{NdJ
> z3zd|!Emj`bSIL4<^O|3NegEB2&l1?}xj+o$cz5;s@Ko5^OZS~<R>)FE{<r3>BvbV
> 6
> zW^9i@!QFld$cc8YheH5^!8Qcqs7UXrX}O&ZL%`cF;H&ZW1#B4#c>7?1!elU1n6
> Np(
> zu^9@J39e;>1SjoMy^?hyP`Je;2J+KRHuSPTgH(2Q1j@Rp25Hc8qFu(GLF<Y3L-
> dk|
> zfT<Qi06PpJNVLDI4h2w5ac{043B?A!x|c}|<qLL1x+6`${nZLK^s!b`THrJd3gFO#
> zF+j2oUQMITh6<gWZey@m;&oFw(0WQ6Aqm`kregFxk!jVBW(5}W=|5<FldaB
> K?sA$B
> zkT6m<mbHy!!G0v79$2PS5|Y2XGCy32R*pEmjn4l$Jm?2@E&S5fYoEt}57@N_
> 3{Mz&
> zj{a7D-
> *Uupew<kOfS$FpF?jof@ji$4ZM?ZN+Fvl<{RQLQACC72$YbMuxNGmqBekD8
> z#2O{ex+|FH%zc1zS1S)NdELf%S8wlw8B<?$jCb?xouJ|(8zFgMb1~c!As2gYJ-
> Er_
> z2yoYjDm~ck^mSCYGQI@UVOhfMeWq~VWT*>8*kFF3nC9qI8@(@%mK_w
> G-eiZ1-iPdf
> z6^@r3j(4pz8-
> O<m5wcWD{2uHm@`HEq{TTMsKyko<6NR15McVUhHXz?$2P;A}vwJM<
> z_>_sc!)VqcHIRLlyFWc04u|#QOYYZ7FvNzk(1~uF(rhq7nW)k|6%`C+qf^}Xqq4T
> (
> z{p9#iSUZa2gS(;vb#AfU!-~6GqXL04{7ddyC0Sciinm-rJn0ZZ8ZzPRL|2n9cbgZ|
> zD&35zAV5l2+)`~^>=<_hUjl6RqmYD~=#oW$#~3&G6m{EF^!o&7@7%WtB-
> a9V>iOx~
> z3h?MTXt=&S{FkgR(YjI26@ze9^SjM*PLqNiMet$t8lRVD^XuD|zova1n(2;1X&
> wd+
> zoZPB6-#-jt|J`5T{>aA1{soN}tncwt_uF5-*ZNM23?R&J<Y~x=!4M)={Pz7LA{dl_
> zUsM{=Nfe!X3#Q22ujW*s_2zxUo05NEvnfTmxvlN9of*tYXI^v1V~Q*V(?sdg<
> hPbX
> zoZwYTAF1YG9>I-
> Z?x1>3%}R1AJWp#43|wk)RstO;^qDfQyrd4jM(O{mD_T+x0fZv9
> ze~;x_S111v^0|<v{CEyG)#UAU>q9}wZUF=ayB*hZzvL%kqISSxs*F1N7ogTv@
> |>IM
> z9v};=M#n1U(ovzyT@=~0uAQ^}+}N{}FlPO^7AbKeYrw!(-{1-
> 3L$F<j(*`$gkv@jN
> z*oT^SV(Uh_DHsvNN;4N0m%4{Oi3Nroqm({c#Exv!N4-
> bQV0_S(aJ5q7bDx?;v=a90
> zs91@2DzR}O;EyMZscLVC1?xb_57`?IgnSU`Yarx*Dt?~tN`Xj#;4t7{M~eh<Wovp
> A
> z26C1}hhT}-DWvvTwQ;wE-qg9e>jRA=*5t7F7~NXC-
> |{Yhz3INvPf3DIciGyWj5iLq
> zRA>+Qr6G4&-
> @f5XK0Vz1*{d?Ut|YB7lk<*)TFRc(4y4|FoE%qPcKLG~%FP3x;cIqR
> zC@y;bm!4O>?tCP*S&}+9eBG5S-!*Y64=?@J|Mv+%&MCS(-
> (37o%^jbc>}p?;sm}4V
> zM06R6UX=~*Fn=sU8CnU(M^)}jR_?lTFl-
> BD>O|kxVAw`w_@LH<#&%+AoZjdg>v?&<
> z#yGaPzufi~yO=M5zW-C1oj{)M?S~IGX09vk_~O*kOkZ1{w4{-
> h!cgYy>blMg(6)aH
> z<<}PuRV7TO7LHfD(mnf7*yv;Dr`Q*rjUw!VIM3AxbFJ(bO*vPkG<UtB0v~}(A^
> EUp
> zpGZHY*I4Sb3}uAQv#Wg1B6OZzp&qJc?*+{L(VV4D%}vV%t~wjs9oF+wk5`~|K
> eEPD
> z8(f0}^xrkv0ea@O%SZUve!u-
> ck^Xa7VEwl)ssD4;|1Cv91c}|d&2qd;9k}vQ!@$|-
> z3@<=`NU_edsRFOAZi_i)tg@=E@KBG$$XOvqK9-
> @3VWc`3>ku`&JW5pcJ;EOTZ{vRC
> zg%ZPWo%^zPDeF;k!HM<m+twN=srD#&^$Yu>B%nX3qqs5%2}tM-
> T)x6wx#?+XXl8mU
> zQb)nN{tkm*vgkU^^E#Tf>ogTo>+35XExL>+m&y^V+~=`_W7AY*UlGT;jKi18`J
> o)`
> zad<+_rS=tVcT_XFoT%oweT6)unwj0cW;=o?3LI*pcnNtTUR&QB+ii8QYgBliJ*D
> z@
> zi!~astlz_xde#|q5qrlzZ*WL=B;7<@j#$}tafq>gHwGN6E*yuwGj_eTDD8k0Jm%
> jL
> zzD$eTdJGvf`0joUR_7ZGTiX}5=6=fH>A;DTCv*td!-
> LTB^z$a>*0C2R#zHB{YQH?a
> zg+9<<mdrsNv*-|02f+afVa8Nak*|bHPT<a0Qk}0vIxnk)E=-FttZd8LumS>-
> TaF1H
> zQqyfo;M)B_3}Q%qB!_>Y0cB?Gs1cOo)6WZe+`yHki4Z%Ke%@NF$W6|t7-
> dv&z#8PS
> zA~q5z>(HLDsY;#JhKUhOI7RFIN~8_Ao*fdsrcoJ_J0W}xIy**c8lQn%29^hwJZ(4;
> zi>>b|v&P!?Opfgv_G7`SR~<`TtaQv?0&=YmUia)4P<8g&SoKozOP5*Q3m2!KLr
> #V^
> z7po~=ckj->)=qq>=%q{Ra+i{nSx^ltptg?r)xm4e?vU&)C0VsAw(B#Z)=d54u>Hls
> z>z>^K;_57=apJDxU6<9lpTTQ%w%g1dQ6??6XXjwjWcA0_yHb%0ST&N~r`@ct
> J-+^p
> z63sH5ONfr&fl?LTNmRZ*TdXrV&XA0F_fi^#rjhnGS6JVh1@#qH_N%BeYA)%h
> ?ZaxR
> z<d)ANa1r@t$F6gcMrgEc_b}Udyg5QGRsez-
> kq)8x^b<#>Lufu7{73cVn>6qb?WlFK
> z-
> gZT)N&GE_GTDKPlGW%qQIB<tz~u$05SLGtPAAA~2}Tzn1U*UorJA~zj>+LKb0
> Rp|
> zwV-a-
> (OM~M>DFod9>;GPza!;EdVFAOB=?Bz@g|OxAEX^UNdBb<%Af8#2f)%jlWof
> @
> zwv?(4*k~03#vmAD@s@1ZvzIK{Z&^plR~qCiO;t6Qy6%E}?<n8jhWUu!A`dTCX
> FRd8
> zlIP~Qdoavj5%7newq-rWAC3ziQlHk9g;cd($(*{`e7fk3LHFSYyir(f`AfgudGxP(
> z{<N{|_OZLlX5mP3*OfbR!Q)Fkyf7rYk~?-
> ClU=1nC#eEe`xWR`ff~xHKsO_|E7`s4
> z=-g*0O73H#+{&`+$}NS}Z=uFr$t}C8ax*A50vMmWtFZ1a1Ey;iLBYT&;>}Q25%id;
> za!9^%PKc|D#LAgGM<$$%QAG;F%Rv%FYGFI)Br?AyrPFRZmuo?fv7WoXGoy
> p@T~|5@
> z*4Y?S9kU_0-+!aTT2{3y>2{9m&Mc%avJzFDS?wdJ^-
> 8DC&e!d+bxN0U<vRW|gzL~=
> zV?q1dbWZ}C;@@Ie``h$$6_^qKR;O)2lp@-
> |YJYec9#s64_m{mR$lbOqGmIInc`r+)
> zK+^}HefrdwdrY=SDdbeA!5}N>b-
> RucAO@*<uo=@_;XVVAh1B_ONWc}TV~yCVQ%5#e
> zyN?%Sd6O)<Pcc*w1R$Jj{14=lYKF7U{hSU{HOhGdhRbH`VtT09Y_71z>cc$346!
> B>
> zW(b23EwQyz(HIBP_lXTI1Nu<7ncgumVEbL<I#x@>)subw2+O$>a@F}VaxOv{
> =472i
> z$P^5_lGP?q8+`0Oq@AJ@MRvucXgNxlp_1i^T$Q^(H#}_zkQ?hhVJ|0W+yW(
> wFCXk8
> z3-)`IKW-Vu6GNHG|2mP)$K1v^K%%-
> V{pk!|*$Qpne=B5Ii{MH3RGXoNPB3$*sf~-s
> ze%Z+940s(fk>y}8EJ`TETx1C_(-
> `;OjQA~qseV9Xjc|PG@7uL(DDjM02^GlN0?5O|
> z=U4U|FoS((g53AgGPK3<DMWC2#uWT}Uzqaz*!8lKf9Xqu`JzF7P+{PXd1YqBQ
> |HHC
> zxpLsXpo<mv{i??&vYEP%7wc(7ikuV4sYEMF-
> (ULeOYYU*?b_jsR;LbmDQBNY>A&jJ
> z^HL8ig5MpI_`#J!BKbg{61fR6+(-T8JgRkn{mjPqIR6Z)PpoVQ(FR>j>W1{Z6M;9D
> z`a;lJ;s<%%8JlFZyV8;Lwk_*rhzZui!*P0GjC-iY2CPSe%_*J^Vm6mqeM-
> >CK7$MC
> z!YWw}p@?Vj+N#upD&hQihWIEKKGN3?by3FSV&wND-
> 8v5R#011w&*EW!<c-W<<?h-q
> zzss=M*}qVP?TA0bLx@gyi^3X2Oz`Br+oseGja@HR!0Gm$6|KX=V-
> >Va!grm!klak?
> zgSOz|bARN}&$<ECoi$eOZ*_=J@5cG!;cSlJnQF|V>8vBsKOb!ehA;?Sd^mhs|B
> 6^_
> zp8h1-
> ?`JTyI3(j*9e&3RS33&WX||ge^0#<7iuj!+sbh1W@Z3lz9@t$dAEmPAFn8G%
> zG`zwtih4{Z;cII?+I`0~i&fdl%0yrJu(NCn%Ztx?pfU&nub4u1YBme$XyJ)#;W_8_
> zqx0>bpKpI7nL4r8&v)Vx>x7m#UC>%~{93x$Iz3r2Cu#AJ2lNV?<0Ma>w+3>P?
> Q-Ju
> z#)>(OL%L}WM;=~be6U2WMs0_}CU!YT<%9Lsj0?Kyg$nR?n^{Mw_Xq6Kcoz@
> 4bQI7A
> zJDcSfNuBkER$vdjYIT2iqA&~aJ;Il@)^qS`e`NTbntg^oQEkbeSYJOTFr#(+JrI3_
> zyD=!<8Wh*^e1V|aupd-!;cn;sLUn{Y)>oTD>>0=-
> %sm!W;s;V!6I%Uw#4e1GBbFD;
> zM;!<sWn5ihlicgD7_I57w|G!RlQ_nG9@HTO;Pfdf8}UEv_b4lJXNLW&FUyPx=ja
> 5u
> zhOF`G-
> PgRrf(a!rccZy!FrVr#u>~Y7uM0^4RUZJ=@AmREc2h2q8>cH?==A)T{Y)W^
> zYgqr}k4G2BuhOdHE4!FUVxk3r#ivL;UCs*BI53uA%>8E1J&?j6q`%(X&hkjkU}d5
> P
> z`YCK45!OI<Hf46XgA>aShfs4GST0MCI(Msq2am19d;}S-()*+{9p^}F2K`6);Tp$Y
> zxt~T#0cQXZxEv4qQ<?9{YN*_L(m$dn{pv{{7JhS+{ptzoet88yP)~FiZ8h|TurHAK
> zWsR@1Jp#;3XQxvp)Ko|p-
> 8ZF74|BVvo9G*x95CsT@jzr67@O?Nm1%hU)VBcMc-yl0
> z<k(@cmQO%V!!4&98lOoHPMbFw?l=#?TBe4LAFV|Oj?uQe3-
> jK#w^}FhwKz8yo&Lvh
> zj;8w*O*?45X|4V&6hw{Xx`?uO*zk=K{!TNWLxS9OmQ>1Bc`S$UxX%+!GJ{TJ=
> #|&p
> z$EUqJ?Cy}#6R{L8GzcW9*^8&eu@Yp5Wv}TC$e3C~BDI-
> <v6+&$a6$z2mxqfuZc9we
> zq7tNZBvXjTOJZ6gw@8eHhP|++V|2Mi5Q$Q%A|<|Q8pog%5}uVp9~qP?)@7
> n0!u_yq
> z3kn8%Ia$zZFSi11i#?>Kn#g{XUbUB-
> k~>3>()CQssm}nH<MOO(V?3xWCl9IPz=6=D
> zkZnWk_L&VqFG9`EK<XrMS<0l2)B`!t?4Zigs!7~sD@HA<KZLe84=rbnW_?cGz(
> pns
> zjvB9WyFdw5fT@bqSX~iBzhZYzg{rucgewJF#$3cOOp>9Pnd=J@)Y%tgw<KEy8
> =0VB
> zbx=^YWipQOWy3qN*bZ604XJcg3baA%@dxur1y89D<`(FSP%u6BaV|g-
> FAhY`RCVJt
> z90DdcNx;%yhC$8d4i{LUov{cYn--%ECS9sh7!?^FYY)XZhRvNA6sHv{UKJDvFl$Z0
> zJZRT?EvqLPf(KbZwz4RL$Fb3Cc>d(+?yQsrT#ydQTnRnTb}JxBglHp4wqXHD#siX
> M
> zlNOMq$X25xN2k6*k*x+to_>LY!BKc^Aw*OQBq1<xY!8oXK`!uL>YQ#)!=4J^9
> U+El
> zZ8)tkPl31??kA;cnl`y4Uc!~#fW6>f+88U4>sWCL8YAqOx~IUwx@7}W+mFlJmN
> Gb6
> zZaVww2G_;_8=Lf!WU=2&QX6|t#54@6^I%3G?8grvx@oOs3^3x2o3I`?TJn=y
> ECD)a
> z;517;F2xj7R1_2x#VL#kouZmRdA{I_iWbAUW}LxFFV;*p8m<Xxn1@2fP|a(=7|
> 8rr
> zFa`surd9ky$Bi`#%{UO_J@r8z^a0+0t(OKrCO#H1h?sg5F^HIgN*5AFfYH(T6r=R
> K
> ziOP+Ch{E6q)(CUL<5SAA03+bl<5Sle0=5QXJwgM82=IZ|Xeh)Jg3_Qi91Vyrz~=~
> _
> zP{3$44go&NJQ|-
> hR$0JktF6J1(JtmK9AdZu_%sd>D++i*tXR=5C197Nj>%0`Zw>FD
> z^aD2CY6|e#YV8~hpW*yBmUvdG$=Gb+?6(hvliyfu;oJ{6bAIYuk?Me0y^rtroc
> M*~
> zD|lKF41l-J{iC-S36=yK|E3x2lp_(v%SSp~<tLzz(`i2O#KJKsso8n8WrxoaHZ{+2
> z3@~Pz2-37iDC!RhP4A&UEZ@jbyuOF6hy%GrUBd_~!CH<}=z6yk;(-
> ZZXTat~hMck7
> zk+M&7Y5##lXd#yU3?na{Q)lhgdiMeQ#`(p7kNAO--
> i+GZx5<TQr`q5%cJhxr%4LNL
> zuI5Z%5TBDAST@<(of=kenuxF!jlMGD*PB~P*QqfB=3k5*B8_qV#44;Wovy~
> WWRhC|
> ziGExhf~4CaK54uMM)k?iugIrP_Zb5m1P$kw2dx$_U0~I<2mH6ON3sYugSyUu
> eXT+`
> zf}Gbwc(^Y_$&y97bVXgX7|VUs<mZ8sh5ja1kKHL=v0n`j`5Gug5yoD1b8h#OYTl
> -A
> zGn+lQX8(&lV|B%{&&OBfTdOny=$`RQQ&A(YUd;C$gm6V<#J(6~>ha(k3%}|X
> 03&G!
> z8=Ua$ynvo2=IsgX-
> X(4M;5QE4>9^8*CYNkjKUgM`YIHi0inZQWwkZ94&w{l)$EI&U
> zaii#ssA76w++%WNA2TLX**2wd5a~SWytI8iS&SZJ{H|;9>>l3mX>!N?JO(6`mu
> StV
> zrLxUGbnt*8*FvppCmqlc+_z*ICygTd&84fUC6=RTe_pmK=%3cUf^M+Fv0Pd&
> 7N)oK
> z)I4du*dh}W!7%XRp1m&^6J+W0y%@4vVjSlMSL?LrAGC`d@?ul64D&@Qji=9
> C6SJI$
> z=6-
> eX{g2uIy)StB1FZH7t7w1)PiJKtm>U42Xn?RLUR~!dF&uhR&_OdW8q`KC@X;<2
> zZYftVko~9RtI#1%(7gu7Wl#o2737#hqvcasxe3E`k<hu)J>l-6Hhv>S#m&O<n{0g!
> z411W~g9-
> v|wS?;#2=|K(I1Y&1L#Sc(D4ay6AUn)wG~vCSt&t%Ygoko37RpBfG@^#U
> zo=Ey>QG;ZLJT(;VTtp3_{B@A>GS8xX`pne_9mJqNRq`@gKv4br5ftpzD9L$BqR
> Sy)
> z6BY$`Ku1PAwb4)_of+Q_MwZLeFLGp|w~o@)(RhuO=%BG<YCKs@h12b<Lo
> _m!dnn{#
> z)`;$33%#+WI4NSt`j@hAADoW-=La9QQ27s3Bgd<%adT;#LHKN-
> Z1C&RIfd)dZRXN_
> z<a$&UF|LATDcEvED-t3*o$*UjAC#0?$dc4g-
> @+wnpt*)<N%an^4rv5gHjebRcCEJ4
> zfCWgn*Ir|umOZ%$F&2wf6b{kBo>uG+O$Ac8Q#Ovx6(vXa3L|?VEUeo49;TC#
> anQ!j
> z<iiADFyB89;(SGnj1WD-
> LtyH+Il0Eab^Cuk{@+&r&scWAK!Zzfo0E6zn|v@$jaeMD
> z*7UMg1sjMRf$ODM6QMU_O}CCWH%zx$w8O{^6WM0DULqKVK9Ta7n=Yk<
> RpE~Ok#_!-
> zSo}YQYzLD!VQQ$O@u7lQ0X-+4#$#i3>Ud@f0UXnB9Y*wZaQHO-
> 7snt&1{ubofWUdv
> z-D46fZ;~P`Ii#?G_i3Y}2@1L0?E__|pSl%|=Geqn&r>!FSUEhkb7kpyG2-
> ~$mwx+{
> zrIU!`cVBvN&WZ^jfmIFI0-
> MLINK4u58e^tyoj&4`wP<d)4g&8+jTFl*UR`_Ns?HRR
> zv_7T3(^JR!hncA<{$Ump_DN*dFy&6+K>~?I-
> +M53Lh!ma)~cOg^1&Q;Q12c?hCCFV
> zw8OZn`1^o46J$FG%t#NhTr<H8@9XHi0dO<-
> =x_Rs=^g&zDZQR?%jubRJtQ7qwGmW-
> zvB&rq_F*~?U^9kJ0ess<15$J_mxmrcr>Q)Y{W&eFx%6A7EIro4KWD`e<Tq4@
> *>V>s
> zk1mB4XVw^=ixW>*%zZwO=aW_^?_1UWMSyC3N`Hk_4T52H91k984?$Mh%
> V{&fn4DV<
> ztu9`b<d7){kLQ7ywe*Z|;7`GS&(Swkb5+(B$nBQljaixG{W#&Rz26e=7xxbib90Z
> V
> zBnO)u0j)M*$0wd1Gk3iKYY4ttRdn2gs&_ckuD@wFy~95|rPniVIXTm*hs5JwFE
> 0~<
> z?}_n`UIcgz@j}W-yhgNn3-
> }BA$ZQuDEONnz4&LDwc3`;gWK{ZduSm`sT0MT1h&x!4
> z{3y*@dU`lY+=T=$NJHCA5(X~}V|G@i@qR+hB=5Jx`{7@<fcNKq;5&Vdby|O|)
> AsO`
> z{#vK?K&LPEonH7Cc3RPqg5G){XNji#^c77B`O(D5MO4xF5G)~^q_8?G2c{1lkR-
> Kp
> zu^gh@T%*nG#Q@y;l>San&GZj5Q<eTfG^iO2L&M!H52!4GZwr}+bC~1V`~F}
> &%~)~g
> z)#z4I$4JKIdov66*84s{9L+2iQ?EyjO}9L1tZyOp<W5@Mc;BjfuCTu8Z#bK*ClTI~
> z4`~LE%LBaG3?1oY>^<m*c_q#|XT>SrF7moAqOsQA*LiWg+lQEKGyBuJN{*Gv
> eU0@z
> zqfUM#hzia5|G~*~Y*>A9?iEmM(>|Ooxoga_NcUolC?B$JUTWRc-
> |4AiTc6UyOh)eL
> zKRaO7|2$6%v6oFFQP}QesH0dOq`ZZSOmh<L3Oy%>(TVnH_O!j~=IM0*ne<y
> _OAlM!
> z_)P1DqE(I0uv}MxMa?2jNSj6L*_HQe68o4hOf%!H;yn3m_p?6A8Ji}hN^aNuvy
> !=&
> zIvZCaXm4kq_;9^@@k1sd%S-
> e!Nxcg0B1KtAvfm^uVvlG`P$Gj31g<rDm7pc9Ix15e
> z9r$Yxorswd_0b#$WTb4h6u6_m0H#LWAxtgAanzVAS;TrXwRhU)esxFV4${6R
> K`M8&
> z$t%6K@JZNl+6S`tlNo#;#|`$O*YwJKu65>RXNT<~b`n<_kC8c?PWHr7Cq5}*3Sk
> W+
> zogF~e8n|%t7046M7H0U)9Cr-
> 2qMkiyvs~>%XKfk)G_<w7_@GC&LzM4WAk$e~_jJ@B
> zB0z!WK`c-e(R2ZfZzosXF>gNNOz$5oGknI-xv}5y`@MJ1jUB!3+}OMP{(kt}*vYZ;
> zVwFYb#UAJX7x<qlJ}*|m?{e~ek>3`6*YJyKxum41Wb{vQ@#wU|l;Ywwzo4!E;
> @9zu
> z(z5t~KSf0cOpX$Ziq`xLcsKC7i{Jl?dP05A#7I~jT-$>%o_332CH`JY_MaFuJuW*^
> z<^eBt)RzCG<{9$5u^2XOenq3eymr`mqltAFn^;$#?m5)N^78d>VG3Dpk$8)9zh
> s|(
> z-
> 3!DNLZIwLk&t*o0g78=v87z%@0FoOUuF^evi?j1en8lm{?=yCZxP>3%hc=l_MB
> {K
> zzfW{Nb0&E58KYdl1^cNBqyBk{?Th4ZQ6&6*r~lWZe-P7>O#K-
> 40%#|gBnx@O0k@a=
> zyJvT!Gj6qWfIiW^SCNUl$-y^I?2Y6%O6)F?QBJ=~x4o@z%Ra!DZrfli!%;Z)Y;V2$
> z46GIJo{fF7fu?#U3CG&4!z<XubkxPQZ<?>Q5@l5okSjYDd4h`i=RI>4hg4j9A7O>
> =
> zGl!8$v#&DW1uH&v=CIZ2U*fkqY|>=#N)Iq1Xqimqx=O5g#k$kka=0RGGKm(A
> $v$8e
> zB)c*Fx{$d?1?$->X>;X0R;WBqCM-
> ;Zyf~Go&xmmsUq<p;qJ+{>Jvg5_16FXr{c>5N
> z^G8;6Xxnah9-K^7{X|mybc=>5M!Uu6VvE@3@>^-
> 8ME;340ze6lCFB5Op!32qnATd{
> zBC`!7m@6*k6F)?u^cYcf(Q(K<#9BEi@b(305!R)bt&629QPV8RTs&^4a78ssIxa4
> Q
> zlc1AfQ^|&TE737J8n<R~Y03Q{)Cth+K=w@DY)rHJ7#3kD@l0cX`wPp_FZXaLg)4
> ?*
> zI%{{-
> yKA)Aa4K$t@rL%D{kiR!ZS}Wzt*G}H&Kib&`DHU0>m9*KXdw1>HtuL}cZK!f
> z0UiNQq?RK9!gf1?!?)RUs$>VGwS!RQtxyUl&O109FN)2JwHC!%KAT?l@^DMt
> =H$x&
> z$1H!<^tHP7EP~n7#>&Y?_ya!)D1HyiL%t#AM(v(}6!u8qe${q!uWDdkHgWT1Pv
> D~a
> zr6>PI1fH7-^-%xIA)DVBvU$9Uh|M#lYWwnRzP1-0|B;XF&j5n?&oY4-
> ybkkXt<r6Z
> zi%Av3rF<I|fB)X}P8jKLL(hlFKIFtX_O?A^?eNGhZjcaHf^>13n4=Uxh3)CWL{VO
> o
> zYGk7p8Ai2d4Z~%vnfSIhf+~HZZ-i~ghy;ju*9jItjchV#uPWkiKvsn-
> EOWbA;EKWY
> z9-lQ^mum52eDo+9io4&gFzU<<4Ofvw3}+|ia6T!9!0F4lw$C>jw0CRN-
> q6~LTH6Xg
> z^d$d9^6P%`kM_`b_vYli14o>F<fdfT)=kOv{BGd)S$;S2`%`{5@w=JdE&M*m@
> AL0$
> zO8)FDxUpmwNR5ML>1w%CzXOOn8rLxHeRlf5hsQ(!5%+}`H$H{~L`ZMqrkdiJx
> kIr~
> z-!#9tT2zMwR!f+bSj%}PInAHl#YdtWs|;36t+AM0KH2k!^ajXo;;K3r1%*p6`=7XJ
> zK`Fu$b(VSeE!j0NS8Mt$k#(Z|T7dOx)FgFQw9$^{Il(~C)xu$R7}?ddBpH*XO}8G
> 2
> zhGnt-ROwGSf11&lOyss^gWLC2ZcJ{(?&8`>-
> tI!}mK+i+PuV|FF)cra&%jUnX1ZD~
> zvK}o&<#PvL3##9OBB*Jdv_Vnz{}fh#NMZG5VfAw68bW`8RSU>Xt43CPtE#=h
> S6e#~
> z---
> 2ZVOZ@CkMmFqX(eH`xwEN6p1BHOJ5iNX`%01%QN`A|lCYBIpb{H^sOwd>+;L
> ^~
> zZ5E`)2aOKkOwz&J1&Y^atDwBKjORo8l=vabZ|yoBA58pkOUX7~?&f8!y-
> aVsx1$jW
> z{{HoE$?TiR8I66^`C}bkB!7^pUDHwfuO^#5+*~A%ymyC}(6?c*#^BJ#k6Fpjf}>3
> =
> z<c4yr+1dDTgX`F<d~h5-Q+p8Wq9|3T%1V-$U02FC!-^U$uTabwAbV`45g}Y5-
> SdZZ
> z*G$N7)qL(#36ZQmPys|JjD$oumc^4=CM-
> usSt;$hf%S$~9mE!s%72X47(PfFjDIuj
> zIb;SNUv{`b`I;HCmF8ZPM7C@O(|s@N0@*u~t5jl@ZOB%om#vB|_a%-
> uttlmd$F%3@
> zbMf*+y#wO?1Gf9op>=He)fs6#w`OV|L2$}6KHAZ^9UW+$yWTfy8=lVv&y8E
> *M0{(o
> zl?+GfY=+MD-
> *B?|@97Q9zCkH=g5!`)$$yXK*0A@n_OwOPj+_fnK>|DS*V2QhExla5
> z2o5X!{F>7^cq1oRgQlmPgJ!yMa8vQD+)KVcbCQEM9UZlzks)Lbi<svW<Xv4{%F
> E!Y
> zqTF@rZ`8h!LE#&@W<=F!L!}M)Rld@B{}<y-
> P#j|oKs|kf2WHj$64LOvQX+ylr>K-&
> zDT0Y^aGrc}A*;@xM|l5$up+KONpO}&r1a}X&7SecQfP_rJzr`8mXQgW)t?J9n0i
> 0B
> z7pGVfEJ%2O3-
> U`NPHx^<*y`NOu#nL~aK}zg?W4ubt}L6>2s~O&8{FWp4HR2s{Q5F)
> z>ik8B9seK3mukx2S5NnSF^F7Ocwrp?ndaT@zH3p8`_mM&c|`cGK%5*AVX7;=
> tg9fx
> z)KyKfN>j8a{@HZqVY~zKT;#s;?YyGB+2?HP7w5MKQ~yQ?F0|}{`?Mf%6wM<>
> ;)k=_
> z{V&iEupSXLdnU_{`E=PY*3^SG$6*5xYSGLzK8SN=Nw7pM31UrsHiYlX-
> x&cPc`kCV
> zJWv3i&*|Z_SX1Ld_#RO!o0E_Fe-
> V7O2Hzu0@$CI@Xj`iLqj*_clp6_G`rOwd#fSQp
> zq#VaDv-
> CVibyTE(q9%%#AE%@blBCE~k0)QNb1${OE53`?C3mdSYG12Yo?_*3<<ZCV
> zvimWh8`WBF4f?0o(r?cs7!+P}rD~`G6sb~SWc?<k_UDd4<?~wlt?4bOpZ5b-
> IB$`T
> zl}cvGYN1jpEG8xrs17`WfKxi~I9Rl*IllH;T!<$$m2#>OdjoNcOL21=!Z8Xkv^L*r
> zsB6a8uKQ=)zN4#wyEo(OIY7d@pBEAiU1=Bsp?G2f&NpT$&eX-
> `!_sgle7#^<cc#Ov
> zvpi4=TV;Jy*ebD3g{``m7z7}sqxRlR<Gn%Hs<P~VXf%D~s<Q0EddUZ`+M?i97v9
> 3E
> zw{dQ=_r?Y2T;|sHwp^8I)E8n(we-
> z~lB3?NRBu|=bS%4@^`@ioE)Ia^ChxlCBb@lw
> zu9;iA>J~Ok%1n7U*2X&b`HP^E+P>L;Dp`NzFFKMNF~*SUd}JUjcCP)wY7prDv
> p?s?
> zf$(d3bOB5lEaKN=&3uTawZdR+q$|+2QEOJ`F(MQKVx3{xi(0;-X0W*%-
> ^MNz(e9Sx
> zZ$!A;7`p}gPBIp^e1;E9*cCU{-=Yu0H=plT{-
> dVV393wO7Nt=AZq%#})y*(=t5oUa
> z3fgbY9X=x8ihu`Uuc33tpbU%H#=R)xwxqYk*vWv5+AZvFIh)HQw{#>QE?^*!5
> NIHi
> zd??fSF#FkSqBxh4KyUn34j#FOA9#qDrqFG)75J}-r?uLbJYYO6zy252>f2{|*suL_
> z-
> n0F_(^WtLEc!nCUQwxtIO;ib%l#ubU$5dd?Y_5w^ZA@ji^=YzQXP4Bz?pYyWYy
> Hw
> zi-pRa*<<0e2aig1TG(Xq$R>N#<n@J3`kcN=i!b!xH-aX2giZdI-
> YNKvCYwMwTp;)m
> zQ7Bge6Z3EJ5qT5cva<ZA71^G<HOGZxg`Ek)M!iTnLyR@mw_+xrYUimnAB`%r
> mS8Fv
> zrCMO8?^{mho%?c_6Ddm;O&EWgl?QWlh=A{@Z=>j&uDe0qYI(l3+#Qitq5MG
> $3UlMn
> zka@Ps;_0{NFHKP6XI3DpaoSgH-
> xb%zTYyN9B>2kHZ&}7cWt3$DEDEUvdy^272RWFT
> z9-hHl!@-|mzsh|l6Dhn`^-
> =MtqA+Hk3rFu9<}V9#xRej+%>2=RC?FW0vuS5UFnhjk
> zCDv-}vK@@cs7O>%<g(9)t-
> R`&*RU1BP|b9U3S03xeJe&IOAA_2#6%y|!QEr`s^YoI
> z+!3100cGGLTq|echy?iHJVN45zkB2gC@S(7JksBhzTbbP78u1<H*dauO1qRanN
> CR)
> z;p<ygIlN5H&)~l!s~Dbe7qM8P+uf0UVYR82CpBGogoSUqrs=_xc_?=O#RQ4aZ
> qfv*
> zHZF_&dau$sR6u2kFTC=$-P-
> N8e9%q2M`L1#WhiCj{Gl2#9KQ{W17?JuXPbm^zW;>Z
> z@To4xybc*NUife#QB9TjfA9r9N&za+2X6K*;?w3D1h0G|p?d^^vPc_a(4=?oql
> u11
> z<uXJSc<JY=eS)ua7aSw}z@|<)!-
> 8){uR%M3?8$tvBN_E+S~=xgKIYcU2MJx(>@`y3
> zT-si0cxlnvQ15>Hq*it;D_byD0c9H|E5>c9Z>Vi|oH`OKiv@|DD`mz^Ul_mb_@-
> (h
> z9@oosF&u=2-z*#i-`R@ka>$JeithP1zl4Ifw<?QIt6=n+k;}o3yiN-}EZqHd?xZtK
> zr-61fcT;*<|8VMf{_f*`b8Y|nw+MyYkM-
> aBJ%^N3c3K4F#t{*a705TeyBcq^#ir4c
> z9r^chNljc8+$!4HLC+MfHxCY@wf4g{Vmx!#vdNHs+jn~b%7b_gdx#;1nQ;z2p#
> {M3
> zaL6=bhRd6|++rdp#(x6@qrj%+0OP9bIzCiyeumk6U_&2I56)T^Cx~ZujA<^oc=
> 6U5
> z()aVl&C33f_Svz=+up7Kv_$96>^&Kuw-
> |#0U+x7<0>rnPmBtN(WPGMRXV*rB`=i_s
> zg%!M=&#bT6OjOMhW{I!*mZ*Xol;*3}=j@eXHLpjR7ey8H=QHbbc2-
> o)5=3HO^~A7(
> z8<Z5(%wx7Bs^;}5vpf=eEcEAd>vQ&h><jo<f;ok+d4nYhA2%p1sG7&@!%;O$x
> B=pG
> z%g#g?n|Fhfg3LT-zY<mRdX)JKQ3d_^-
> 1?lY4Xas#y}hsbjHm*|>j<mnF<Tu~Q+Ifn
> zTT|EI_>7V~9QvC50|ba#itcnrnSW(zqKcREx%D~wQ~N@9s&U=o;rMY>!AVN
> <RqJ#1
> z-
> l&=yZ18>Vm0<;ol%(r9@tOLXyWRuQLu8p{WzcKxN<SiRD8c8`x7@kbi;Ai++sAyl
> zW0c^t>055Hs^G$*I&lo79e(36SHib~rNCBbtmQs^$*0(3k9{sxn?WbDto(`j|Nfc
> B
> zt2@t+t^VMc-
> qnYuJ~XB)H6^{ND80GpjNjaN$QiHQQe6D{8Jl@}mZwc;^t6mcSJkp@
> z_H$?Sqz-$M^>_Hj;=M0r)?a?rXP?{edc9w-
> WFODCu${(fCp+gMo?*}hW~q?~Ve|R_
> z@BHb$>PtTTWE>!#?nj>JT-
> Ni4@4;G32txObYMv{kY<A2aO<WE%24XeeDpH^h_$O?(
> z7mnK#xW2)48zD{Nfd>{3zvL<wd=`~@_cBvg>Pa8>q~JU8PAVsGFF={T2QXSZ
> MjkeR
> zm3)3;nLGoksaMBR*hNxo5*)|Y9HDYUDKO;ohwU$7ULCmoI`=Abe`K=-
> <%iN;htUOA
> zpTjsmo2)e|9=Ng!TN}~di2SGK^Rsix$9y?h{iQzt>=$rr{7)M)8^R(Z^N&6ND*PV
> c
> z)9A{OF#>-hlJ}!G8!yIVq92dw=yYiF0#Qi;t>)WfJWhtkju?-xA-Wu3Jh*4A!zlT|
> z^)1BZGJTPhcpQX2`P;W8IGBje;S|IA|NP!kB&sZsKw;jk(Uo#A1@Q&TJ;xVkec6
> `H
> zoCJfs*u*tYO*XBddAx@m&cm;GJ3)U95V=C*lEeIh4nx(Je-
> !)(iRd3qEs4sPD5j~a
> zwYRyQn|l|65YuPw`QO5BvD&-t-
> }!DyUgSapzNX2KGRE>t9uUY<g?{1suwRXXn-`ck
> z$Sos2+F6|r2BW@>gl{gpo|Si~^Pv0BgLu{`5NEz$5I275eS;XH-
> u@pD|As+)KoOb;
> zo$mRiCVMk@Fw?^PMh5sAAL6nNfvw8cP8GS1WEoNZF#gh4@a~{-
> Ejm+~M@@n#KY83I
> zjcf||i)`@@K+is2lkqqA%KNQf^ky*7kb-gT*S`>6VzhX87ycFS9{%UyogTvb=js={
> zmIrvx9StvJEB@~0iYE)d7ylLTUIoJc41V8t{estE0H}`%s674P?`6xWC|X9udl?Ab
> z$eu!U)1TH6LhhRH0*+s#%S@<gE_F*U5}nH-
> vA&7fNneQtTQ7kjbn}S<Z<nU#vnCP`
> zqDWD(3cnQVvXH)%q$V}RrrGB6)TYItip^&ou}JfqPt1@O$YhSQl5d(`Uw2f%`>
> =z{
> z#&Tl;=421dv+No2s<q2U%mAb3bYEq3UOu??q8dB4gtb;|7Gq>XRuOO&v|53
> |j9mGa
> z+YubQxj;)JG2rGDdE_Iuk08CewpD|epet(iZv3yb+lP@6yR^(d>xkdJ{n3tC&>!+
> G
> z`>M|eZ+co4MK=ou1dPJ>Nx9}W_##;u$y0~LhF(Ag@PzfQf)qOhvezEHX2!37q
> hjm^
> z`ye1Px(28>ow8$gZkNV${~_>YaujQ2PfL^z0J_uz#9`{t67;kj=?>-4ZdPzG%QftJ
> zIE?HN8Y<B`jASlwFvBnO<VMlc!Tbj`AMQSW;r>K)Ybl%KPL0L5$2fZ8s1#GmM|
> sMj
> zCDuNZlhau05@<&}zk*Pe(%SbJah2Kv&|BxKhiyHPGk{+6v(>8=g>#siqoA)?^Q
> BE&
> zJfZ#Os|AFX`?g<38eGplzaB-
> dMfW4P!`;&t7~t<ga3Mb8r|mz#`VKO`G>6pv_VXde
> zrr3%4b96G+R5Lya(7+~n3!e~2l!-SGc*$^K5oHvx7<0V_cjxN{Ia_i=N{<n4PkYzR
> zNAtO)vB%ClsxfG<?JcS8*;EwE{gPpLbkT@m@C&y0^3xo5AAKXJbEn+<gub47
> FtkD+
> z<-Y-(t=xX4zZ^Bjw;4jia#QICKtL0SXUv!b1c)p~SoWus-
> &~@GF|*h=q&BKDwLASM
> z{5<Lro3>IDKbU(vx%Q*QerKJldDoARLX({OhG|<yjnG8jr)PbAqZvauJ|~VEpZB
> 2G
> zui`>zB-1l`UGwMY^|JS-*Bi3d2QH9~px5IAdTr8nG$h$m+Y3on9>6e-
> YH%}s70^&#
> zeO1UK4|iid><1%R!v|Z-
> O7vETJt^u#8KY3#l?{0^6hDeoovUHLj9IXe4Dq>e6h03Y
> ze=ef;tD#<~@T7$!kPE%vrrB^(I2)J)V!($H2FqOpFErJYp99<_*ba_j&HF6;b<Ow
> B
> zkGWUQHrm3jJ9~(xhlu417+WxYnjX5>+hd1OJ?$?rJ#0cG><*Rgd-
> Rqhdp5DU{E`VU
> zzQ=|K(`Y{d?xH1cK~1ej&+fOs3bO2wbyMnUX27X}TYRSJUd@16{LvIutIQlsW$
> N9%
> zpAX1?_$^QVObcvZ5bfXJJUIO~)~a=FhJPM44=T?ytR8e8ghFUIeodps?>*+jE$
> 5CH
> zG85Q6%hqU&VA<0&1r}mS4C=8fu5({`JrDes{d4Z;qrh+UEgXz$L+JDC&#F=I-
> +K^#
> zYv;*|q|+wKDRZAW$2tT3ON0JpQtsvazi_&HmHLxwS&rNnDa7oUXhGTXv!b(
> hm0Qoq
> z>;Gj;5V*9@zm)v@^{&j_;v0C@*uz0Zmr?rzv0Fq4R0-
> uqENsruAZZCG*q3guVSi5=
> zTRrI@Y<z=ws<vPFIKrvzEMVPI8YpmZ>I6&CYo@|(Qx2g-
> hh1v}GTaR=a?b@ze@HJ6
> z|K<4BJ`C)>v7iv&H;{6o9|6#0kOxN?9)FVf^5L}eA$^7DI<o7(<9~$kv9O3y2tUN
> P
> z@IDZp#}{JrCz<j>(fS$g96ct>zq=D6$c)q9j&VEqD;1Wk9x6H}^y*VG{@ot_=PEa
> s
> z>A!w9m+6asd|e&mx|I_X>Iqx*kgWQy(|_D+jqBrKQ&~TMNjD`<W#q~?PY>z
> 7g&5m)
> z)(*M{ZWIdo-97wI&l6az)X&q@cl2!b5ofiWmzm(-78IoiYg$gvc*rrNwg>ZYP-
> <Mg
> zw63Xt5(=>7jyiXQs$`K?GdF*gX??Trw=v7JT0RxDu&^lo)>PS6b~bi5xGx=}LOR+
> S
> zbn_{s|5@fhda$@<vX%I*u+~|-rQUs=`2uNK-
> U(`8LT6)FgS)*TdEcGBihr>xN?HzM
> z+D_(s?krWj##fx0;5J<!i!p(Z`;IE7*BEGy_nmGKc7EATk@8NwyXo!wRGOY=qto
> (H
> zB|N;Ggs!6RYM7dfnl#Td<MdMRuKcoKlu^1I*G^EOplD*Hg7thy+3GUm^Z~1
> wez%Ug
> zGL{b$5Dw|=?nNIs!!#CgfF}+js%41cJsyz9ZHiUP>{ph2j`X~+)@Nybxi@kXxvxQ
> K
> zY%2&=>+Dcg@1`T_%RNAG3S#C{^c_J`Af`w3++5c*s85h}6)>)~mr>%p=NIX|C
> ijgm
> z38krp-w|z28)iRaRLVHZS<tkk@Dk5V&{te$R5JtZSxAOYxrhE%6dcb!4qat`#2-
> &|
> zo_G@NDN<~(gm(>E;pdhMf^igWoz*hW2=w!|^p}ntVU-
> jzCg>senjDs>@ec)!D>gbO
> z<Mr-iJV0tXCI8v&Vip5>yaD>*L{pD{yv+!xvQv@7so~c*c<}c^Z22Y=E4wv|tu-
> 5^
> zn#9VdNwFIRpF{O;ZR~KrwAvEw|ID|<;}bNU8UE{oiLKd%K@jBP+^%H=4$(s;2
> Ly!`
> zr#@kGWSp;*EIZuq(zFD8o!pyf8q_qE#Va2!rIO4R_w}%@Eo97n*k^q>%=)Nh
> o$0eK
> z39~*xR&$|`-KTSJ0yl?)9P8`tZ@*&LbBB4{lq+o+*n=vL4)OF9^Fzb@b9$P6fIoR;
> z5xltoQ7x%xgh9nP%NCBkJM=oM^$bDMa;n<-A8V)O#Ln6W-
> IGuv2)MW2{c4g>91k0>
> z@r~yi;T)j{l65`{Fy%gxOEhCg9(RK`8<4q~IKm1+q7&o&*O!B@iQG6`W{~|kpWr
> 8v
> z&7ZJSqQ*sG6=J4STP9eUdY8fmSQCPF=i<!Bnu#d0Io2#J)w%yRI%GE!&rQf3N
> wONm
> zzYd6l%aFYP@k}%yBmG5h1Wa}oYU*20<J9-
> C6({f4qSp!&oW|A~_c2%=wP)wjepZu#
> zqYHO6vP{?+OybUJ`J5&<jQL@1mwF~X;Fh)(WC|CKqG0VCtVw-
> 1Xqa2=*5?p9f5`*>
> z1=$U_f4PHpJD5w&M>bVXMk2Pn4Q@HBDjkP)bNjbnUjo87(wIVSPV=~?Qsu
> XWs@`1`
> z<;NjKzkLZXJuct@oXzxuO(WyP$}K#JG~D<6JaW65jM8ptuIQ}YZZmK!)ZN**y}
> _OE
> zdpobM8=jy=n3+t7V+(70I3a7HzX7*q1@r2RrWgR}wT;)NA)AM5u{?)yaNMpr>
> 3-Sl
> z$8(E&irTGg3SLuCHW`)0V%-
> z3;sie0;O>jcwuNO+SJ{g&B&>jHKN8KO^xHKp)tVsp
> zQp6hhIkg4|^jtMp)m+mg-pKTE^(>N>?P0QE!C1~JIVm8JBz%BTNSFtBPct`)-
> IyDi
> zxcdbY6#8Mufg<Sq;sQmG&5yP|9kU82;{b)LF0PFKo0AgEB>n1NNEjWRRdDkC
> $+caH
> z9qpB3@=xjSXA@uj@}V@^sTVH5-
> +!*%`fuf*@1gTO^i%ezn+(3}Hz|TYCwJ%Hggs2G
> zgn${~hZ@}1ac(SmqxsCv<o$K-
> 1xUfmH$Cnbup5>8Z>BzxpVM!BqGe2TwNmb45Srn|
> zJ?;*kLc7I^O~plFhq%+nvO$DLSjP|Ow&qy^I7SSFAGD6zoni%@jdwS=Dc&~72
> IK=Q
> z$Y?kM(P+SZlkPAYCxt^@KaAszmSZ&<&C5G$@2YnbBH#zyOE7Z*c(pH8E?_h
> kMe0;A
> zfD;11Za##GIE_E~sxzhcxQXX`%J>14mOX^ej2$C7GS}8H*DB@eK^+xVGQQ)U
> 3WjN9
> zk2{sr(OJ&l^i%rFkY-fq9=#+Uzhl;U8q)S5hSXOit(8r5KdAGAReXaA*)+%KemGO!
> ze(Q1POV}E4!>mx*a}W4gqtP04x{Vy!$p_2^7jT!6P5;|c{D%{$=&!-
> A22z!0dpU7J
> zE{xIt&g547;esG22XAGr6P(LynacbqC?iGP2zaj$yvp$=WT{&Fsc>`-
> ^=KwN@+7jd
> z!95s}NS_<9#kkKc1u2lmBu%m#kkH`>NBDK@h(Kid29<lgbKH=0dy8-
> ME2L+S)}P9Q
> zHva=iCIqZlT-
> h&Bg6!XeYECUET#P9V%Hmrwx*aOJF@R%rAQFsKMmCg{o%hp!D6-Fe
> zlIp{0)6p4+418nJLYZk-Vn=(aK6UCZ{xdrK!&7=KO?>qe5N75cz2F684K&1rl7aHy
> zpP^Afa_N(v5vDp&*J*xc>Y2$t232S6Mwes6GF#j=3^xC+)IUb#suJ*0CMJf)zL
> U7?
> z>T(Sqn`d<1a}7;3beb=fI(NAp-<MMMJJh7S?q0YC`8qEqUwx-
> }iD+=MqkOl8`EKy}
> z+Rq^$uwAI^ZfumVKFqgJ`99ov&#7vc-
> nE~p0`6+d8K>nBg*hiFC(e;I((7CW$?DA4
> zS>SVX{Xv4ZVgv5x;EN28a>pNVw!MgyrNVM7o&CLVTsY;7gjLgBxAOVLg3rYr?
> O3S}
> z2X(TCu^F7XM~NNxX#1XiN`JW!>mO#Nj?Z1>S;Yt*-
> Vgww%F(0EuvPZ4dMEoWn{AJ|
> z$&h$w<6|~M&%V~f`;fAmm^VJC;O|Mv&f-s=)CQ$R2qc9-
> P|36_v7>!JpE~t7ot@v|
> zAD+_dVTrH)Of2voy}+&>@$Bj${)K$6ei-
> K21$Eo5WBd{i(GfH~I!9;iBkoPXZ1@Q_
> z(WiB`&#<v=|2^&7UicArzGyO^tEOe7w4AHz?3_v={J;J&U#OBoO(z=89&uk_x
> H}sk
> zF+3f6jX{-L5lX{v__aKDeVFi4kZ@&~uq8;qqrby-x`zFKz-?}(p58%fgfkqk`PHN)
> zp|f+ML9^#-8z-
> Z;b8is<0|vl9e%=6(IE_uwv!6IGwuj$%&3Unp@cSWtYx$kTDiAy5
> zFZ;>6X$Z=dloon>D126ivVWkRC;0sZzwh#U{yF%Wn15dEbbdSdEm;6u{GLR5A
> HU-S
> zQ~6)^Q{;c}L}BGh%gf3RDJ%FnG=5lF*_bgT+xM|A(q8r1=f&PA_)R8(i(mZ|K}
> @j%
> z6_CkW>Aou27)u9ozpxt;%ZLS7;^DCe`}Emx)!6wrHagk+X~k!j&cP~_pwi#q-
> hhw8
> zSH)!!q<8was9rX6lfrqHeyc`mmyw(D{|Ub$Crt`IhMNVy&R^z1$W0spzSIm_Gc
> Sj%
> z;7g%OBak;Y0<OCMz-
> MEzP079X+{QYtAn32b!SanJR=&u4$jsR1uxDRSO5*Wxwl9A!
> zHJL5?@8)ZZjvyDPFMhq)qvb@HkJ^zu3)LqDmEU{o*zL`$LXsbJpJD<cqVHuvo~
> &HW
> zmv=VqY;a#J$TEv80yYGW?PQ|8ID+o~W$#}At17NGV0Z^21`H-
> BD%RT(L4yJ!pmGrt
> zAmO3}6Ci?$4S@s_3`tB*0Igu~gh~jp*n&l?RqLhNV!c~!jRb2oSX)u4qSA^;+Z|8
> Z
> z(l*sdqkPY^*38-aoFsrXzVG}0-
> xrwKXV0F?nl)>!S+nLA=>_fgnz}S_R_#Xmp^pdD
> z=#P574otfFE{d7ee8H(>!D-Z`>gM5LtIF|dZe^ZrsqAi{{i&5R+Tpkk`#(kFz(F|f
> z&=yLRM07FfV0a<0Z?WsJ1V);Qkw$5(EQQVDv+6RQLXwxV-
> Ji>4w$QZa)#W@t!!5j8
> z(1ct|IOJ?}|AL2Pekw9=`T}jKV440vbG(ya#nolppXGkK&w}-
> cO}Q7kPZOyiGQfd8
> z1X7U(lD>mV_H->-
> %6bAR%xGsex=plZlBh{K+NnlRcv%bw)L|WWo!(Ws`0BdMYD~id
> zqMUUz+=2*1KcKK|bo*MsE=4hD<hbzJVsES~Mgu`92;worJ#`i_LFHjDk_lKRA
> %1wM
> z#+}Q!Qikdr?iX@k0Ndj!8$S#Mu&Fl|tq96s5UitiP*qPKeXRaS3(gMD1}falMXYH
> s
> z5n$u(G@zS`0c#~nh?25uB8VayjJu7!RHNHXD>l{^T#kaniQ!(0yD_UB0Gk<+MV
> |$h
> z4U4Y-{w0&0H{kY6g-
> pM6vU3fb6BpmvAGY+GPu<15ZS5TimIoj;`ly%~t{r}OR(OUb
> zaj{yAh-
> oy6EiAtu0otGuV=>RM$a42ysWb@7%dz1;FvrmD0;2%q_{58rzpA+kUoMXs
> zxrRQ=rkSEGod$_$Dd&Us1ckObUvSbi6YSkIJ;LK+H5`_-?g`}Y<Eqg~-?;}NvZZFS
> z$qZ)zoqKx?&SlKm6jMX&352a-1ITBuI~Oz$?V}AW2x;?8tz}Kd`tZo;Y-Eq0uyI7b
> z*Mg91Gu9xR9qw_+2B~E8J(l8Q2@2YE_f=Yl??BQt@tTh4l`6K<5c^5hYgr+qF>>
> V4
> zSJALSJO8F>NFAQ-tMT|7F7(o8-FP-
> ^Cs^wLc)a`5<6&KBto>&svyeOf_U?_x{u3t!
> z)Ks=$e~l=615C#MLb;NWH6}I{fDs}EMSX(wvfbXF=4;iSLULmYnIqW8wm_&YV
> #sN9
> zQ-KwOTue;FT_Ge?lTjVU20)(A3zJRev+jwAg}~aJYHY-
> !t%$h0A1wj83SS<cW%4zP
> zg{cSr7`;{&O>}jc_h-8g&oTK{A>T;pce<+(t0tqWHnXZG6FZPq?VYCiMy`r6`hcHb
> zaMwiB`>0pb+x|Aeeux{)%#SFaqi;Mr(g028aye==Nn=T6(?;g99$q_6NW)}?ueE
> z%
> z=JcBIg%PxKW7&X6_Mc_lh(l@HaND^Js+-
> ko3wE=FWx@OKs74Ck5y>SgoQ)^ZyX(Z5
> zSy=AV2W;lF(k5Bx#7b*h{qOU%)o%hdYAHNTNVuX_=Hjps_FhiT@$7`&JNP5B
> t*(w@
> z*`3I-2drpg<+<G*!KaM%bQ-
> TNW7B<13d??tB(2L_?|yMP6TReqg6GQ_wH}Ai+<LAB
> z!RT9cIknjSU$>gW$Sn81X6f@lBJ15xA%nvw<Azm;XdN~Fsmc3F{hhJ$K!=d^N
> 9r^~
> z91d@&g-
> TOqM7{f6w4*V9NtcoBZqE_IlOlGYqhKblfv=KY*dE$%EMV*1wHVgW0=C|*
> z!Y`;eFxO(0u2l)zS@UZ%*VXiviA|gUbsSNG2D^{QL>{8jt(h&&AS#`q-
> y0(K?VX@C
> zG!G)TxLW|=%STW*<63+79yA{nJYEoH8+-M(r0S$-
> @d|15IdTxT!*+48KBC(i%q;4o
> zMqu2hy>IzQOnLOYacC5^32#GpQ7Ujhv8K~UfP$twkh{dj;W(7R{QzbJAKXxW
> T2x+z
> z%Vk)$*Uf^W+cXe~eUS%LS~(~asS$g+oz$XE<?4NooGIPwhMCE3Ajp>q)X2w
> (GA@$(
> zWh*Ho-
> u+j$P{TEglWEhh%iQIj4w+ZSZKb2$Z)fR#iTkNBV*^793waQxtng4{+`eD>
> zmco42B4cxw``Jt(8>k2$AV-ORIe?19-{6lAL+iFk{6}s4GZ`N?taa`#d_)%2+3ub}
> z%$D|wy>1VDR}MZ0^Q8OZR>DqA3Ucp)nx&c>7L{qxs|Z3GvDh4q=52Zd%8^n
> Hs;gtr
> z<Jm&AU+;wdx+c8eTgYhSM>3m~>xV}C8Z)-
> ieB8$#Yc#+HeV7brI0)6#pOJL)54$7l
> zI=;Y4J@N{%QYYgfTE|d1iU!Nm6PiMdXPJh2w8}@@Z538gt3b!`8wIs#CgO)j)Y
> VZ>
> z%XSN}vX;zC%U0oIGU}!vaPMO5M)$TnsbABnEQIRL`5K=E(|!Wd&vx&X^K;^9
> 7jie6
> z-
> (ZRTbA_v_Zzcu7NcXY42fwvAzb<1HTBF5v(GdaZrsw^M(F&db*R9Q5wI;I)=ND
> A*
> zfQQ7j88@xTSoLzoO+&-
> +FK4V8YHe|g3+h(Wn1$S`vg<_pxF10k2IO<+$>aBY09fvS
> zLl+-
> MOpG@LO+{GU#^p#q!~KJrJlx|h6Y8D`>Xu`Iv+CriYIht!t&@|2v)$~Sv1GnF
> zADM*Ya9t;OLai#<Eb4LsgW~@PGGH5rTGK1f7xKqfXzx<Ea)2?|v}9Q(cn?J~?T
> ?T)
> zJfdA9YKwKNX|Tz1w?q;>U=l4sqNYN4G6a*JCfiNe%f?Qu+jz3nxk(0P@pY@&4
> ~cRy
> zd4?9rvr`v;%c$)$!0>A`53CUrR+X5rrra<>e_XP%TR5d|V_(Vd#NA3uCf$2^$i!GL
> z-Mi2ZO62=M(Y1B-Lrs%v^hZ5k<CiV3-
> N+v>zpeqH*R4(@T<!z~6D=_d?{3JS?IdJd
> zCuZDi_Z!jiIKGb*e=6gN(Qt<QPh6Buk~jH{V7wJTv<>Kwku_drR#z3<=;?!QP}lg
> q
> zw<?VPf|i9>tdxKV`1W5^1k@h*{hY~8QO;y%1>7faKffGf7d+pXJ=xg=_b+^R62
> 9DD
> zT(|D+62u=NHYyE|KXU!`$ae<ZkKpWYj)06j+D@8he>EK!a`N^D?!3-
> SbbCYngT;Ln
> z_VFIT`t812w-dB(O+Q0Ko;{1!!AI-_PQ<nBq+s_r<imkI=(L8Ba6$II&m{+}wiRXn
> zU*ITyUX0Jsf8~(3r0QWu;SEP*%5rh+yw2H&(=q$;`~@6mm;hSY&;V;ahyh#AB
> ^nx#
> zQ@<Q!)G<6%PhWP=F)6G^H5+l?{edw08WfU@_tkt4)zf!^7q=_zBvTrqN@;B
> n@8Mpr
> ztmf0fAFRs!m9)CL*I~fg%G4de%5cbZ=ER+T5m;Lo-v=w-L-
> q8X;0>L^+Q+~O91E;`
> zDy;G=Y4y&Y9l&a9dW=ckY*O>7spVJF>N_H-
> ({L$Mru*Y5A`Q=VztA6N%6#WPPGOtF
> z3KNj|&OMh335Z005X^){6PX*b-
> QSp4q_)yrKqYmrLcTl}XP`9pwsG3lTWjiE!h{3u
> zh@g4q*gohg8yOy|r|$%lB_W%7^<GBDwH>4&wsjo?LiO|=y_>v~@<3xr8&D
> qB;0gx$
> zR2;~!r0Rd*P0mt&b)r_&8fw192~zS(9EVDc?)7*`rT>ABjnnjQtEO<*3$`lHD_kF-
> zj4q}a!{U={h$CaK`Pn6cGvv|&X(GA&6uA_xV*()T3v^LjbcFK)1qk;PNDHXPGu#
> dO
> zW2$?O7LtbO=tw9UXP`k;mSfgdCa2gf&2XXL2#+?plPS6y-
> 3D9cr)Za^dyb??*y;WR
> z(Kv|wkvzA%cgVBB{jNM4-L-gH1_s9p>dCQh;(*@-
> V)ezEjk}1|<0KXvk;mTQbdl8z
> z4%O2q6G%$7V%<(g$9^<6I$Log148xm(Te@!4qf05=Fq-C28ZhDJHe~8K-
> 3a|_JI7l
> zq;4a1oEdK8c+<kDeKVxK9nm}%3E%AQV7M9AY>I?$cb`Xi_?k|LOwa)$+fL{@A
> Zmt(
> z>ghY&w*+ngbmN>O030S^Mgq8O_Z(kgml24Kg9YegBjFA1g$O@Xle|V4+GB{
> pp?dnj
> z^mCwj#ZndcvlD6D$c#FWa10OC(|52dD~8KauMyyK^g6<IFEJ0uSU%%WXsDj
> QoXWB8
> zu5=;rZ`5t1N`v!nQ*GNcx>>LTVs>gZ)fSxR>-
> %y%_{5FVq?ftN^#=!JU<qmuut)Zl
> zM5jOoLS}*Ze}y5lFdX$$&UwWnLbluX4O?D|+W^kS7o#ui@qKv^Unl~mLs5d}
> I-a~b
> zL4OZ&Z<pdL1JXSP>O^14c7HXA8FNyl#eD_+DR1&ilywx>0RVGA9L+svPew$Z
> eKQ@F
> z#?{T}wX)oo1?+^Z!Zj2Ob$bz*?Y`m5u@X7D0j)Pyi|DAN3Zj8s?x(#`92Q^6%G1
> RO
> zu8Vj8rDpYR=@{vAjd2}+xIaa%HLDv;1M!LWacU)mhbrSh<+_c~e9<<;3{-
> ^rDYU?$
> zNbq@P+MWa%9IB@uEft<+biY(!K&YNRXf*`7IaGm9F^BdAGB{LEANka>b|Q
> *A$#6X-
> z^h2y;9hYX+J%*nmwV&0n%?N9-
> VT~HLGplg9G|qN@a7ShcjzMVeVFZfDOdXHBrf(Vg
> z_JWR1TimBXjZNPpC^3vf$?EGKA7hO=kR%Kb)zf!^6QU)_2x`BZ2ozUP7ZyujbP
> wLM
> z-
> 0vtM0J`%nAcFx&xOd?^(*do>L2o48SKWHaBD2ArYU4VH%XI|H@dX^VM)Ewz
> Y6U5E
> zbyZB_Zj<hilMJteMT7xfMz)8j>E=#q%J5J<eKg)$V$3L$o%KZzF{AcGz~E3leJ6;6
> z;9^uz$}6g%BCw!>-p@=Ru=rGg#a~V(7U|IV(c-
> qCLEYRmE4<2x68H5}Nd&a3w772}
> z0)<zhVCiY!mn(oqw;Iw69s8-
> F6;C<Aen<cn<0<!>VC%Y^XGKiR!0)CX#IwRGMOKl9
> zEZ~(x6`wbtd)tp4eoo~nW^Gos+c=hBa2lei8Jb<wdEI^3uN*80M7nWKnIvP`Fa
> x-K
> zykt)^*?u6yBD?ZxEt$oA=FCI7X`-
> ~q%9z!2q>hh|F}1JDA{}5Lxp5xRLTvmx3wbrV
> z7h_C`$ESP)bkkYP_x#1+(lNG-
> 76Tu(5(_p=5XX#*)arPqyNc;7Iy&pT?qNH2(0MUD
> zR8K!zJ-?Ijed;;iL-
> q7|@<429kcUDw&|zdKv5BccHGG0n(ap)P;4y_48U8v29MN<y
> zMOkcKWPJZ1Xan==0CI+h>gh*AzMk=Ykn=rMPyb+$+kwS8rUvAED&+DDkS7
> ?(7oh2y
> z{(^6ZgnSM2>Hu<vhwAA^Ltf4JKFIkVs;BP+r?xB2;`|tc^D3qW<a{dR@++8BxKq
> re
> zE$+jhw(zh>MwJ8ooU<G>hFN;fz9hJ*<CQL-fw~xp-
> x+D$z=AudCc{JZ^rNe}obi3t
> z<U4LhW4xs5?{|b)TUFagLFRy}@~KsoUp&_`Mx5D{7D;6$C7+s7eg)5<;87)G;}r
> 6$
> zTYNFOOa;z%2>$TNy6`QHEbV?VT6j<d+!OeE2$^2YVms))7#^ypkE&zqtK*(Om
> f|p}
> zdWKIJbSB^nnQMCi&)`r!{fO>g<!QCC0zRLa0GE8KfafnKc)DO@J4t8bD8a~;B6k
> !c
> zFMxfmNDLmQXje4?dEhEMGWNkc^m#0|1C%g4R8K!@ygQfC{o`E*gzD*|ya9
> (UZw@o)
> zpge|$>giJz^bbXnsyBB;jIr`*mS!xJH_vCJVR)#XeuVsqq5T|!1#=?E>trCA#a!FB
> zErUb#^qt^vKiWY%SUQF-
> qVOfLiw;ARWw}2FHCZA)3UbT6ZIqH%;^Fie(+EQcjLq;+
> zJ$)xw>@_o%PVF1m0F;f`#>GH1GE89(I17Q}+gQBuTd1Bst^gNedsc`oMTqUM
> (uXRs
> zWkYT?UCAasgvOK3;@TsP!J&HkPOvOiL<qp>Z>j*e^j&Gp<Qp1|Fmre>{Thb%
> {1&RG
> zPnfw-Z!=-83y4q{?SuI)SpAwFM4ldgIyC!S#L_w-ONNK)={v#sk$Pi8KLi{>j@SZ6
> z`7!{wa@_;%Mhp+t(<d(z)O!Tfegf((BEJ;9|AYzi5KxZv6*A9P2*X45^rM({7^C}{
> zl>wo8`cCj{_u30cgoa!<2)QN;xwe8jExFDmRKiqF9BV+*UL$c6B<^dzxWf>a6vV
> Ep
> z8jS#z$}Vfu#V^+W8){zOZpJ;g5@$KIVXIvl#(z0&Q8SFbd8P45>rMgF$Y<GWcxB
> Re
> zgp2HKJ(g4OTr;(p+ogV*bCu+biGLm_b~F~1tlH)T5N5Bn-
> *eytteEAMQ?31QH;_<z
> zn;42=D@5!M5B%l80i=Ohg$HQyjvyCjL}#=OJa9J>Vm~Vn)x=K4*3h1QIMXB82
> d8=@
> z1k>Or2d|YAW*FH495g>6!&Hp<L)+4@dmQJnp!R#Dgjb~m*~!nNO3Edwr0O
> e?m}=Fl
> z$OVYn6^1nu006SyV!Ps5{kvGDu@YC3;cncvflP%f*7W*%sY(rRJ=w{13Q1@V5
> CvMS
> zt?3$wN5N4KocN2IetIO`tlGd1EWmqqIcEL@P)x(3u^{h|zG*dJ5ik(i8-zj|ez+nQ
> z?gN?z&4+~~fY0KhGvvP39=WgKVkBLK!V>yK0saIedecv+DtXh81Cmz%7^98Is
> zf^-
> z8Hs{pzHzq`<~gtCpd_OaYYp2_M^tr3q^dAqqN?k)s_7CB7+=JyZj!1toy$O>5XRl
> +
> z+=^h_JIYH%6kD3bcQuPRn?;COU{ry+G&Qp;Fo0*rh4yE~EJW0A-
> r^=p?>L<sbKBWT
> zH>>gNCCt+1UnjG)S$IUTk$WQ=xk>h@#IT3WjEiU{S}1UK{OB9cx16Ta)phB;-
> jHoP
> z?g-
> =sxLNCMSOLfSl6r=~co^o9ha@Mgn30?#D?i=OamPnfPsBkCPU0}heh`t5{=#^b
> ziAobit6-K+HvJmJ#pQ>cp@TIz+E;_~S4P(9U^^I>OR(4oge)It=s0#cjqdo^r?moy
> zDW9X;#P1+_R?BG=0fyfjEbHDa!UJ(?G8&Se$@~=MDZd)J2W67ilwXBWfCtHC
> 9}jRp
> znv|kDjS&lHb)c*d42}_@2QEIMKzY6!1<LdB!Sbft$#rB#fll%zlZP79YBHYX0Z%a^
> z>seg$KnN<Bx1_-(WJU_D+J+jUx=-
> 2KP}IFD5+w&WnLPzK!Lf`j2?f|aEUhNzF#{}8
> z)MPwXoB0@}k6)sk2zrkSNFW15Q%2K2qNF;O5b{bmuUT40C4GlS%|@CQ+s~
> tjTWfnG
> zV4!GjuF2V4o3UB;?`#gO*qo4bb1GA3Zl(|eV|aKwMldbyffzX5K0MB=CzPfbsZ
> 1)z
> zeX$n3cbfvy7u=6?@R7VW^PwoJiEfvBY(nDKbS3x5r5bHb5Bqx@Z5kn+Z8QVb
> WZvl)
> z=^fMJCfj-hiw9`{)J?USn~)gShiXV?Ex*C0^|ky4-kS{;Ng`yC#*d<Ef|j%XFr@jq
> z_R@SEmS`ezZN_?KrVfZ}ji0#I;MySIwuz*w4TE}uO4A5KTew(SQiSR}wq#rQN~
> H?M
> zigfjpG$o=TB@9(eIowNGrYQrOlCicq%MnH;!IM(qDdCAe;v8MsFGe6CD(9cWr
> $l1G
> zx<>IMa*+bkh(EJ$<ZstbcJ{%oGtcYIa{->eshI54mrr&s3{G~Y<5>Xr5Zv`}x5Dkk
> z_d6;lJ5J9-
> |Hb*D=zX8QfbN*ZKhpQ!GhzKh$U6z{Ot|mB{T$BeY_;>33Xj9mXe^J$
> zRiyFVYY(I>o$NHgUAb(s(*&1<-uH7n&%pCSxT$cF^#j-
> +ve<F62UAU@b+gs2JkQe!
> zA$N--Sm*t2F`XTSgNv;{!-7Y{A09jb{`tX_Fz!pBVvF34OhwCKV1d)cr-9ULA?q1z
> z_S{!r2ol8VixjN9leOpffd~sXh;gdbeHm5@WF(sK_2)`VqY0b!fN3nIVF>KkvIhVK
> z{i^|z+Z;#omkE;G{SK6CXz0@;LJx}($J-8>yHQ5UT6dhcV9ra}4I4WqfPem5=EYg2
> zQ!YZ`jqc@m2%hSYvo8Z&M-
> wfE!}IM|U@=jb!qa{pzJvgOfJ%dm&1(C{89rPgXs{48
> zW)mIT-
> Fyr#Q1D$C`Qq_59#Vd9*32xc&l~DTj2R&q{3Lr|Bvo^dP^3Xczi*3aQ_NQ-
> zCf(eKw!-
> +sEd*h>6)8Hzz6XKe_|Tp&uoe<4ArY^RLAYJ#nKcP3MAd7)0lO^YT<2`t
> z)-
> 7&z8Y;I4hc<=>d4Z)2oUu6GecKm!B?HGT?(S~&1!gcX1!w<k_5}`O;IWH)xZn2$
> zo`gU<VRjh^f<zUtRCen58W1_Vp|=K*m}(D<2H4Z#7QiistAqOy+|zJQkGLM)d
> UWp*
> z&y8V`(U)0&W04CI!X>KF6hP}f2XOxa5(x{=aflp^mgEo@G~`FlaWL&AYjH>-
> &oh}Y
> z+*;g#w6|&njy3E9KQ(wQ{5iqXnzkYnZU-
> ?dcdino%gUW!;7bfN%(4h|2GyM)>`Bnp
> zD4Lo$`x5>J^D5i~#>1y<_o7I4;gXoVFrAsX&%G28aDSz2Na4{b|2dv@>MPV)3I
> -SI
> z<PyW-
> k;;Y#01V;fpPi#fIW`h2F%nA|+~5NTd$hW{(aaXr*cy*h)+Qv~{4|L<XBReH
> zuBjsNtq$Tr3<DpW^|(}ML-
> 4^JP=)sxk@7E?{W#@&)ku*EvVFhR{Vfa#Iv=yo?L*+A
> zWgRQL7zwf>@LqH}t1H>dMq`Pe^a4j51A=1>v{T}+Ed|r>iF#dImir8t$)w_0%X
> X8(
> zjldCzp{a!pXG)H&H|I7vYzM)R6KBUwOuG3IM#5FG&)m9OD!%bGJfy(Lpv>Mj
> ^7G!7
> z&P2zJibS$W)Cr=rlPy%?%IG*~Y22p+pwZHdE+_2tIgZhB<SJV?Ki(D*9__>aZ_k
> Qk
> z*<aV5{Qx}+`2a>qbL+{VNK(^xKeKYObMB2;ONZxnxGPby!|5aK)}Ri%&2HV-
> k3>F?
> zBHtZwt#FqfX1*QfX9KZ#&nFJ-
> ex!ilk4u7^t5!7638urpGT1FVFNTNQ=LZNgLX&Z~
> z-#$eKQf>p8PY<YZn?b&@BoU`u5F-5BXyR-
> KMUXJvcZ7*>d=d700^M8#{{Vs_FsT?h
> z8UiFOI1m1n!Q;bAg`^=3zJX?Di8t94mYm$=2&}uG1&AE<?cOYcg8k$^Oa!*NZR
> 8FL
> zmABCHZ0C!kD9JMZ)8=bHiQ?PZr-xyHuwZ;oW0-
> C}f?^{N21DTk<4E_kZJ<6MAEs61
> zA<j~$*t62Gx*ri0@3Nih%B1QrLONXU|6BG4hKF$kS5oz377NUbC+O^3K0?<2
> 4~c0>
> zbbyd~yKsUI_cFLG&{*)^;{FsJHx?90r+_gQH&68gz&I}%C(z<rS11+<TH-
> mG&7sd^
> z>AK{w2LcMp3J`+RAT`q@szFG{d}mT25J<;nHskaW?6PZdOQ08oMV)AI=R>&&
> AJMc2
> zW<}c{rk*Kn;>W3#uNGlYQx^GgRe6>bM270v$g@ER(#U^9P1wla3=dm8Nal*
> E<F!I5
> zr;b<nn#fvo3ZI;zVxZBzQ$<{OaQJLZ0riIZmPXy}wh_cew{nC$N;I|)U<2=R58kBe
> zD<D7=W?o$QX$-
> (GXZ#)J5UhXY4UMht4*&|bx_ruQav7UK?nI2}LMt|%oOJWi-H=V@
> zCJ59iHDd5N8IQu?>8iv23g~Paf+&T>CggF3oWzhq6LL30dNO3538`ZU4+SfnV?
> w^g
> zkUudb%Y+mmq;QIP*@cQXy^PP?8ywo*9qV|TevVhI6m@{V<ICT%&o8E$w
> K>@Nw;s0u
> zUy*e4nM{ze9tznesYzWS9>4)e;Xu>zEIZ8<_g7F+Q#?aPnUMDx@=s8G;V=`jj
> Ul@k
> zl43%B&XC_RBw#`wV94_f>1#s1$B>^eB+-
> PdVh9X;RwuE$y5)?N9o<PGI`|j`gs`a^
> zp!+~k>1%~X6`GEcX(cd>O`TkB#e+O>q%D~!t1un~iPCcO>9*Htk_kuE$ZUB!zL
> <!y
> z02aoy35mA4d%^hO?8u1a_k5k8qARk?`1x#ih!4zLQ6GYNq6O3F;qUfWFy8@
> MAu0|e
> zt=@-9vpwbR<8`5?i8Yz)LMzsR=58Z8a@Ik6iC-()OAA_x^)1{-
> z_5wW{Y5}3BMQ~2
> zC^B3i8k#GBZ_ak_@O}S+U}u25|6Y@`275I_ZU(Mv#GSwi%W%l`8j$v2DQ4pU
> JR}<_
> zhPw)9`m*^sr66>pRA@jDK_`jk5|CBFubt*WvmJelZJWJ7IooCrD%A8cJZ{T57kT
> Qc
> zxLxkA*d|zMUO9<-
> iv|K`+<qh*ad?{6juRwbipN2M&&u9~JGpNK0gVvsb=YpsZsi6o
> zC%l62-3{Fn1Tr2IDzx|wDBLYb+3OyUUI=qPyacj$;SLkH3fags8m@puuquLk-
> H*X>
> z6x<?bsmcseP$<_<KzvV?bhPgHK!H?yz*#-nIR<V3+y!t`;1<DM33nab-
> @ZNBS%c^2
> zc;b&k^X}by(I$YuUieF(*Q-
> }goOAIK;@kn}BL053MEpJ#ZW!F#cz+dc0)Eee`vA^4
> z>d=32hloOO;^T4PM2{mAOw^vedet7-aPwp*2=^4+XK+sUIP=ecM27zE2H4-
> X@#0{&
> z=D$d9ZN^8T=27mGCrMi!<6a^^DxvXg2ZM+fv7P9_PFR?jxTC1`6uj9^xF+W{W
> y1z@
> z@MGp{xc3lq43Kk=GFcAh7;bv1R=8&a9!4(O%^ii$sZ?-
> (6kr(%P0u1x;bS6`n%%#G
> zgu~YqK4f11$k(}r_n6n$`I=d{!Mrx`_2R;6^ZGbn&voDXhFG{rKJFLDTYA157>C>I
> z+Ek|op*Oqp(3`QB?uYt`_JP%A&9d5T62FiQ?lKuL+O-
> (Z+m$P;PZi*m?w$biz76*$
> zxE8q6QS0t-$G~O5Ii#;H{)3te!Zqy)G-kOs{Y{M`zQHTn-Sp2VQ!oxg-TnRaN2pvx
> zx1b>j3J+DP=Fp1fBbQBql^I)v((BOa?i3Way3@(B7Z+|fuc>@JH$0@U(F6=-
> z^Rd*
> z^fbO2gVG42nyj=Ca3(Q!Xzt<|U>s5xYB~?cQDa)M2gGE~UeHr9puku%9}k~2#
> _1-5
> zLA}<jv>wG#h*B=?MO`T|B9?_Gp(7bdQMqoiLsxCw_wd{ZcfWDnP)Y!<J@*)
> Vu4>*6
> z)Y*z)ED1AuWGuND^k>GB-Khv!#tH4e;08T=L-gR$D+3YS<Dd__#W_*IY-
> &Wu<|Y03
> z0$6dQ*bekMsPd{v3>eOI8@8y$<7l9d#x3H<-
> @tRej^vH^PzYu9fw#fvsS_hmXQJrv
> zv1ABI&^?j>K?m$E!u&G?olOBmCUfjSdhJ^Fx`k*H7@Q&2ld6w|Okt;D4qe%a
> ^MSP_
> zb~WxF!BQR?gXfcJ>oOYfZ9CRq<0>*TFSc87*Xy2s3SpyL$bm1D-
> ;Ly99ILk%#uhA+
> z&UXK%apdDo_!z-3dZqIs$l~tJq$q6K0sk#VRp6a{u)F|nW3||53WvNJif``5<3xI%
> zP?zyomOCYxkm)kiM1q8!IS*yK=lOzvPum5pbn(HN?z4R*@%cJ*SdX6Wo*8c
> Uk0Z6s
> z*p%hAm`)G-
> U(PbMeH>;XX1ylceOtDVv&6mb^~l;S&@6FiED*SQIa(Lrs<Pd>unL7n
> zcZAJmF|)y{`!Ynr`ZJ9nISnI_=*D*f3s5tLV(szjd72dvf&GVtlH`gAXt@|1NXp}p
> z=VEXDJCFkosF6)FSUiPPvi_Yv+@B(K&FW$J$>m^tf|Z<F`NaeNv86_KxQ=Kh<
> Ozf!
> z9g(th8zJ^<VB{cF0eGh2!wh%Z@s==Nmw_B`@-
> isI{l~F_W?a=uQVc@4W4i)AKFp7O
> z6=B#1agk(F9XY^jue$~jxRjV1M6%q)zAs19`nF;>c3P7*0IPd4lp~0^?vy!M0aS!C
> zM~-eoKrX1p$Q;`R8+qK%qxz)kcZdLCR~Zjq5H-
> O&dZkZj<W`nKnd~bg`~E;ATkC9S
> zU}&uYxbVe2RevY)_f7V<EN5<Yp8x?cd_SN>e8vGfTHQMk9x<PtVg|sV^G5&`
> ?7l1`
> zTMFeZ5-_;od|7Y+3{BWJ+!r?i?>`&sndF1m_iB4;YXA==;bQWo>s|;&4f-
> ~XkgmI*
> z9Rc7jkH7)@6~d1(@Lj3l{TXMv{uX1P>ozbYF1%svy&yevXt3J~0<dT{_#MWYrG
> XBk
> z*jyz52W{J{R%{<n!|nD7!LjfsV*SduQDM1U0CSJH${pr~Ge3Rz8{4Wr99^{)YgiN
> 4
> z^oq(%PE=uhE4s5)Cumv$kq6|y92du97h2uXAg35<+%%nWG7?{Q1}aREbq`Iv
> e<DH*
> z5L=PS{_HrM24S{V|Ct&Y+K5Nh`9b)d3Ez*ZSPDazzV*X+o8^SKx@mFSc{Q%-
> AG+zm
> zyEwWzZt1z$$^d}Zuq85DMr_MQgEhO)p+kd#6@mrdnjsqy+UlMGBNyr?V}@
> 2Y#|9_T
> z_T_bX17Zd335&mpA%qa#={C*I2!cTWsB)heoY*O-
> 0NWfz&jD3fvs4@Sm^_E8aT46i
> z!10z448sXMtZL@UO(q?J7?H&?Xk#8f@r@ox<+0xY9I&6+4?^fubVa229og=KG
> NeuB
> z;OCb>G1v#2fOgDancq?Xn${v0i}FZrxWc-
> 1eA1mShCYr9?Kvm(;_>Ia3bhB@2HpFQ
> zAwbRUop`>Iu?ye<a@W6QC_Z>nsD3w01V;py=?~n6_bbF}IsviWilark&34!7kL
> k?y
> zR0Zzb#YeiwMtYy8xJMCZVKBlYKwWL4`)52*v)%61XlhK^9O>@G+=upIyWK+I
> x#>BS
> z<Q^T#yV-pa8Wk#j?&6;A&uwHJ?uEQFH={k9-E7T!t>)eA#%bO?-
> 8D8kA|)d4@I3eF
> z-
> U7V<U1T#(aKC9|;_xqIjAMQYWGlo6fIiOx{Sfmwc5#Axu8odJPeM4*0=f%ugC}
> -z
> zd#})8gta2A!gIf4+8EcmzbK*)ZTy=14ip$|<JY8(zmG;DyFCbf?l9X}uAEst2+d~`
> zz>;T9wTUbj!o=)pNjLLk2}nnh+Dq=VKBSA6Kz{3l-
> )=zN<pb+SWQ<kV265YJUEK}n
> zqNI7N5&I?gcN9U`e`*u0ltj&L4^1?f_L(|8(hTU;O|opd+caI0O*e^>Hp30=PEM
> *m
> zLS#(8h?rYUO%KSponXI^nT&c}UzhXJ4At=Dh=we8qqGbce!k>>MwQlz1SqNo
> 3T~yv
> zRyQgIxS#w{tEbcg6iN0XlHrUIK#Wer9Gi2rFWVpS`@l$}LT>c4r)_*+bCYbYf|T(^
> zsuXMNOYV--
> k$Ol3ENLWbSm#ki=CF(v+JiT3?gnmfjuN89MprlVVPZ|)F0?MT+rm%8
> zRKkQ1BHMHsCLQldAad;a8D@v;@p^;<n(9t)tibu!835=EUJkJ*F|<Ds8&u6n6(4
> _~
> z3J+0v3!s+LyK$*1aPD&8WlpC!9n7jjp_km%$W0=~nTWe3;>kcZ?7?6@8*wfo6
> 7Zze
> zzXRW}&wUS|bB1Drc^`xJR(+wb`+|Jqey&9K7<3ELKXLvEupPq+oGJsMfZYx{)K
> }7Q
> z5LY-
> 2DbeUy9HQH(;|UOMPLXZYi9!nd69qcp#^D&Q(Y+22LD4>tM)+*Rb}tY(a2_Re
> z3J|i{0@|P{CGJazOQ@zHCe6#BI~*<ilDiAFAx%+qHvnOz<kwMCI|5jzx<u125!
> Un!
> zJR+xZIV-#s3KtMj%-;hQ04Py?-
> G?PSh`XpFlbpOqTgQOmO3c5RnKiN;x0cQjutC(^
> ze46c!j#M}aY>Eo6;RAiznD8hmeIQGjsHI~OabG)Y>3F3?hPkgn=Rw+tg}x(wldG
> NN
> zB=oBzj1g*`Q+ZjeyhJ^J3v{57y}9XTgR|Yl*(q#ootvfw;vVpa)><aPBg_@re?{fM
> zC=Mg4L|eRz7}l+Gx8Nr+g>D-6Cu5No!vVr2N^|JKT4xl-
> _op2Pa~dPHEXH;>1(Yrl
> z-9Ktm;AA3LY+Fe3TrQH}i(8Di)<!^jA)ceHia+UPYoXR1+_1f>`Az`m33A<e;-)>p
> z6@gez-R7*|pc-+2*EXl}Vw^S!^#F1U>JbhS#h@by7|^ssz%+QA2`VHBX1mY-
> St|-M
> z{3V*D={R^CPwQbAiSA}?0Bd}0aW4gNFhX}7fx_(0WpHvMS{sObLImr0IUjIjJk
> Qkt
> zIO5#>@MlsK0fOjoziSlrMt2i13`DlL-$CBt9}(%lm*G+6H~D*zf*{A&*I|1y!~SHG
> zoJ_91kP}+$tub1I?OJ3&ikvkyBvQx-q(IF#+k_tpgJML+<BT2@8OO7~-5;P{=J<2>
> zG$IX{xfh7l6K+xT7zJ%6>Snq>9O+p-qcB-WV;#^6HcXK-
> `X5curfhWo4Z=X_KT{xn
> zj5nPoA7}3M1Qn!Wu!AhIk{LZ}T;0ZEN+aM(&LDT6LPe0l63t*?B!jlSw*8dl48JAg
> zRBx~ZF%N29^oYUyJUNlKUj(dE36_srBlfyv4xC!um53>s>~kyllX<#><P0SYYdtQ
> v
> zqf3*1F^*&O?lyDR{DZ|OBLS`Cpl1x~{ND@PeLpkm`;>Oy;{=fPn{C}A%VpHw$o
> v6l
> z*&)7Xb@tr~Ot*v_6}2Eo;LjFT<ZOOh6?gIvf<GQz@GzBU5&f#LFKB|2{sQncK;j
> vE
> zeEl(WW4@ZBg*NG{G@xm}G$V=JJArn##0KbP+%PvE{OMz{r0Q%kER2rO%|
> sD%!3dB~
> zK?Fme2FZ+}L~eAS#6zUj$HKs^?gWz~r^h2XLiI?h{s6Tu43L~r@KqoYK94ogZ^K
> 8w
> zB>FbqePTQ<xEu%ha?^AUY;CtZ$QFVLZ5}t;yLTU9`QZUDkw9}NDbOlsG>k<b5
> 6qHp
> z2YS#4cxO>lKk8k0vH|cH5D!gPf>{`MiN+0h5MnA^NO=J`XYmTg`HTqh##^w(D
> F6{g
> zJ&X#py8TVDl>3yV4OwoI!Y_c|2T6)(vTW(o9>~$o0)f7T`k=E*3v_4?PZrK}Peq1?
> zzmDZkNw`hO{b2kRY6de&Pvzc#q9bkfC}kHdB*#CXcxOGv06$uB=TH^5gW9u
> V>Jw@n
> z>{-|J{!UzJ#?^jKus0^#+{-aA!EP3ge|DhSK*kQa)tKTH>rXCx*Dxw!-
> YH~?D@J%6
> z_-
> ~<sD4BkbW1L1e5d&n1&=z+h6(xh;?*lh}{K}nTu&J4YXFTpV@<;C+bFi$tT@2wb
> zlRm!PSAY7@?u0{pPd>!=dE6m5FKOe}+N}`~z48ZE0a5L8@O_8*|KQ)D+aEMN
> 2sl!%
> zmC*kD1BdvYc8Kq&z(LE$?xl{uyJw>6qPv4>;#Zg91_Vx&Ks46I*YOQkof^nJc(JL
> h
> zU2dkmw6{pe)+-;;Q+oB5^xzj-oN!Tc!;zugtu^?8tGKb>1R4-
> d%&qMvcT_f!bVV8G
> zrHso!%Lx#^kl!t}*~w#b5|Tn2@VW}$fY_zH0rWn+n+yL6;}PhVKny_x#RfU-
> aTDHX
> zb=M*in1#Ht4?jW3`;5}YiRu=)KNCA6TWTjjn{VR<oq)8hW<nx&GPFRws>#N3!
> WMp;
> zlJE<beGcz?ZK=sh4)ey*)5F+;NDw2z@+xVjBx6HSJUW&ad6y^u1RvR)pW*%P
> 3J>pz
> zG{@oE`8pK94m^RDSDs?i>W*MH(dZUq1Z-H*%P-
> U%iBH{&(O*)1Wn4`3cKO@*eY;Ec
> zysyrmeMj&D_Uw3U$^ov4s4QH2t04y<OkzS{H;V~@l_e$wXKcoV;MDY(kPq6
> 0Y-tyA
> zV<bdw-
> c*eG@r`?Iu>*r(qfsxxsh+qc6(It4bO^zY4k6glAq3lon3lA7_=@nus=^yE
> zk4CSD6|=yudnWo2f(t^5_s`}>(-Zl(Pfc>|)cBeyQoHuiZTlzUz-YPpG~er3&TBKw
> zBO@AEVWGpZ@Tur&(VLKgT7+P6)^tuw4ZgS5CddZi4?hoW?G8keyK-
> 7_=j=dY`KYb9
> zcple)b7yuWP=gTg3Zy41)#_`5R%sOzB5e>AB5e>AB5e>ALe%F(g?!L1WJ|k{8~
> q_s
> zSUWiV#I*bW5&D;gg*gJl%d25Kp#sRkHrw(KVj=etl9A7emy3XI@v%sYG=_#Ki
> $sM;
> z^F)P6^F)P6^Oz8eDo9EQj|0LYkf9JBCWP%osp^HWouWh7P9`KFG#V!|yiKVH
> aoo+=
> z@*l<fD;cdqS`6kUDe2exU{C;p26vE2WS$|Zx(8F6cQ9Sz*sV#`{}dwD97CVwCR
> P7D
> zDquiT^@C9X7bR71j0(6osk%BUU`TM81u^tl-
> VMFIm+Mzv?Y)fmf4OqyMDNQm|CiA#
> zxv&!zekNhnXH_WZhGg&k3%sxF>HY-
> |bni!j6F3&iX$1?S2eaZYw5=N%_>%ah&4}3a
> z2O(Q7n`nbJ-
> Qqrnk%lcCV(22w^Km_WZ9>uu96i<cgrZ(snNV}|*cXGa0HNbleh)Qb
> z7PJKnk1*x#@afF&VJN4to8iC&KM2?jKoGb9>@b22z=+F}^CP{fUtb)^^%{|W
> R60l7
> z--en8L=K0>4)$FbugO&NE?-BsODJ#GD<BD0e-
> ~>dWRKnEtda(h>Z1Zk^ict%`KSO=
> zdQ<=jJt}~79u+_`Hvzj}?gk-gZoJ24s$Mj2pmk=rH$9EZ=NpEF-
> UJEnUK1zZ(D_qp
> zyU#qeAC{?v8Z=yH!cm!tmCx7a?8b6~bGAR%7u7rGRb;^%4|ln*Nr#U;^=&v-
> _uTbz
> ztga8ew!cX6<8NnO#%DF$hriQ@zny}=ofdyPJ^bwy{AqyT&mSQ8^9Kn2`~iYLe
> }Lf6
> zA0YVi2MGQ&U>ETBa>hrn%OyHDp2h_&2~Ncc2%$9ibSJPGdIP6i5LuatXl2aQ;
> m`p=
> zrm@<(CjyxU(K)-;bc_0y`D6sqISEJQ0MVGq`3SrRop2ZLL(JTTOkeJXOH6jb40z7g
> zUtkRAoU<Lxv<nQk)14;vRKP*}KYB}N_y=^<7=3+Zlm;WhI4VShaa4#1<ERknE2
> Bb)
> zTC3A&S;TF02$3rxKxMaJ68!Gm_$e|s+=DU}eR^iARR?$leMB8-
> 6H;hX>421RI984H
> z`ZBsD4nv`1LoT$1#yAugT3xCVp>5qgC=S*?Z~d^}*3bH3Rl;X+Nk44x>D5v4!06u?
> z9*)9cEEpbo5u^J1wD_&N`)zIQ=Y5XShl!zW93}c;vx>YaFg8Co0pqCH{Gh+HebG
> N(
> zjmkn+o}iWA+SHTlXo+2lC2C;WwE@Fs$l&FV)Te3cV+`tKU$ueFjxbDrZ_E2DW
> WT?>
> zUWZ?vHjixa_LbqmgYUqfdsGMYHTakBi3j;E_{D(hVEOkxRQkZd(;t1P^l1lApLD4
> 7
> zRh^_qdzFH3AuBkFls3cIv#qvUZJ*jk4vD3SJ$xd5s);|mf!np(YJKr1#A^c6zR>S6
> zV#R&FlA>}B#UAdXMaZ|vPB<($BhhI7v}C#G%c?34oT;E^Vtk(91Opfxf<5b|B_
> EJ3
> zhsg(n4xv<`^p`=9i4v~|I+>T_%(&6tdD#9}+8glmd=Aw22xJ;Q(HeQR&LIDuwaK
> *;
> z5~LblCjR>1bRiCHd*WbuoIk-?$5wYU7{i*)_F<(KvIgD`ntmIjndG1Ql0V)-a@+q2
> zK27;GzVy8Bz!rb)VWywzOJC<pf8JrH@99h58^d;6{y$*1jIF*8ejV@S+VNhpJ6;
> wH
> zqs?`^2bsh1UTbY187X{(jwx!?N787ad8E~dXC0?S#4`t7)aE(}W{a3{tJj{SG<V#7
> zp@{jovmgPKf%6Pn-
> 77RK32hAX5CU3(q;RSQ9Q$MCdb$YU$G}FSqno>7^oWL;=M1*G
> zpQ?uI1H*O)e*7@zBcBO8l|t90z=(`1f(87xRlnhA5SG^JjtB0;ms+qA-
> G4Mkjh`_&
> zjh<~6&?o~isY{!CXDo<3ZWEc!>IB3n{!dZ}CWGJH5&9dOmlNE{_)Ya)*1LyO_^Y
> o4
> zRvNX<4H8(K35CIrH1A#r28s}`WfUbb?Q<8-
> 4dJxMEns`%#EfkK@RRZd%hQx<+=(n;
> zF`;=*zi`;)K7!w&*0{<vi>3tkRatQwX}vy(hE{HK_jH1pF@O|DYap|E$V}Q3a~5Jb
> zhy^}Y-h2R^2UInY*>@MHDk-
> tL1*ryhuQaf?xvvoRQ&_*sZrovlfwRspW8jRW&q8c<
> zgezjq;LG->^(Zma+C4Zz;FaRBV-K+3kKdH88Lb1wOkzw$Vkg;-%&9$h&>Wh-
> ?Jw;B
> z&h&>73!=&F|BC&sz5Qw-5Zqz){(rK5LLl8`QGsV!2|-
> A8P(_b_(YoZm!?(}*MQOyQ
> zWz8t9YDQ71Aww?{B7EKI58+S%16~?dOdQZ+ObCYp(Q!U#7qX>Y$c;9HtP`B$
> @%W!*
> z`9^yl{{j<9Q34u<LD+M;0Wz3#Dsk{m#84>KgjS3f!X1VZIUTTndwS{u>#mN3zT#
> *J
> za<Ws-
> 2m0bFhY49dkEuV7gfPPD26Dmx1tTG!un4`%`}5G4;hqRKqivtyF!HFMn)8r6
> zD2vlu+>byia?TOkDyf=NAsiDYRsWg7G!qJr&L=|k+ZPu+DO}l+Wv7Y8Ft3>p$m
> )qm
> zGozsrlAh@%GP5t(0b7bVWNAhknZ?1uG%y;sm^!K1Pt*t2iI%_cRW|QL_dc7q
> PUXnH
> zKil)pmdssd?n>sIo^fUB#^@$~lM;rG9a);JNeNVBCugiY_l*yG9%Ov@3V}C0gB
> |u6
> z{L6e7)MYIEKo3;8kX^tk=x6wSrLALvyG0g{0DoFXV{vbF&vMyW_@=CIb!Mh&
> X*jh4
> z^JP%rsf^KvhVg>VQq5Y09;79fDI)TRjZO1MV$YR*bi2a6!t@E@v0R}BN;?pQaj6
> YD
> z|JXi=f@~Aql_p9*oE@6M>9Jar0{sE!UxLFy(k#x0z3BOfSDX~CzYyw-
> !jByfysqeb
> z#ThB<G}_kYB&^Af?gu0AKg$s?inAH9^Tl7}JBnGG#;LaG2)^$LV>1#faO@aIO=
> ~B_
> zuc0xMYYq_LRYc;;cwF?;Ap&9RD^409BnpFBBI_<OjmU9?+bWl}kqs!nICm(bHY
> c$r
> z8(Fu8aN;s<D>HUG3a%;f*=~1;LQGYPbbDn2Or-
> 2ST3<=ylqY`~%=+NRc)I<H9}iwx
> z2DTh>Smgyuru}5?tX>D!<ot*Cx&6mkoAIAm1V!aPh10P#*nowNl@Uwi0A{j*
> #^M{q
> za1ISU=+gR*&1_rQgYqf|OD1so2)31oeX>95q^kkDXY`E}>xUPr)o)b|eZ`q3_yz
> Q5
> zkh+#~Xwr&Z!F(x_m+su5YK=^p(6=xNg(|la*+OAD!tm!0q9*E-Nw-tu-
> BlRlg4H^*
> zq9`pz=*ie)V$xrW^lLI=P}xCw{Vejd1>Da}xf~`F>`2>2%Cr2iMHS6goH@!5z+;W
> _
> z!<2X!6LqewEwoj-hfAb|WBb6U_Uw#ajC=!j;*vHt436u6#3B|*-
> tnjB_sSC&#~0=c
> zIEEtjqsc%KVaV+E?62t;A1M6c_Q_8Ey`<$VV>-
> qO8!h?wG34Im6E1OJHmS_4?JYmI
> z#ns3Uvxai9^V}4~aJl(maolsW_<IL`cYAIge>d`X_vecF`+58}`x(iYH(=jlLi`FG
> z2%B(CL*fz4CVa%Rj0q{3UxVeyj&ntX7^CC|s4-PkCCtkg$KoIT;}pt`S0*GvA{d!Z
> z$*1_j?3uD(qO$^5DsVbn8^87#vE=NNFlEUE4eQRZnrmTm2E!$`yARk93JZlw1ii
> 7g
> z5qx=I`<jdcP_GYQ&nea{P+6i<H#MH76aBh2!@C^Q*3ZZ@W6+LG2a}6%a@*L
> <#ER3n
> zAONs~kD)A5eANPmW5h5MK7x%dW5$Tg*ZP}=gHFOV9xyIp<t~QKII#tjP+%
> hlwT1U+
> z;wS;#F1?8i<c!TsuE43m3Ej!(iQOUJ6V~(!|H0pScKo#>*{P%zZ8DZk$WqwkAez
> BI
> zFaSVd7>|l!+HY(lw9JUy&q<W|vBdBzjPnfjprmK|ob#gBi70&c2FG9GWVxwZ{
> =?N$
> zs0)|*2D=}~X<K}vdt$JSp}5}HasRN2F%sO3Rk#J)<0pe3lTGUjHXA^a?S57-
> ulKQx
> zb{LZKO}Yk62jC72barDy^uT!W6U0vxKUw^~;`bB(Wbp&y4-h{^{K4W66Mv-
> mqr|^R
> z{50{?#h)VnH1V^<pC$er@#l&^PyBrG3&k%MzfAm~_{+t=LHsK5tHoa<{yOp3i
> @!nq
> zP2%4v{ypN~FaAT~Zx;VC@t+d^S@EA2zd`($#BUV;HSxELzeD_;;_niFxA=R-
> cg1fO
> zf1mg*;<t+5Ccg8b;9vX%@e{>Q7Qe6f{lq_6{DAla#7_}_u=vBoA1VGQ@h=iTP5
> gB6
> zr-(mI{4DWji9bjDx#G_gKVSSp@r%VT6F(^aa`A5vze@aS@z;pIPW<)aZxDZz_;-
> qb
> zkNEeC|B(2b#eWPw`!V|`^oq>|y(&+lJYI1eR^0m68e=^I_ilmEeG8P2L?Bq4T&L
> +}
> zeWkD&wpT)RYI`|u2n3}tD}(_i?nK03E_WZ^M!flHWin>DBR{#mthMJ-
> O32WQv%ynq
> zr~`<u*Cq;A=*3~tp@enWQz$~FTg`HMq~TuCPsx;-
> `|uO1KKHH7{B#X_0+}cTEc-;b
> zL74A@B2@kwnEu6NA4XJu2tqhj=B$7gBPV514UruK$Q{C#N|Twq{R~|iwQW
> &lC4CIK
> zc4`C>Qa1m-
> y()3eC+0Z&m^sc)%F#|7n@CWki@9GmgkPc>{Ns3c7Y9MqW;9DHBs;<W
> z9kl}FWz_U3lt46y%blZ<>b!Rwr%0hqyCdG5k&TL>wvc+qN-
> (FWzkFLII?HY^m#N%k
> zw{}sRCHmLr5#I`?LDZiG<H^7{wtzNmdKlBRvj!y8Va4DjPmRF+N@e>GJp26Ms
> ZP_9
> zQ@=Q1SwWsy7T#3okG~V~Ut#>gLlJ*m`}ljCM)~9KM*QzH{>b5o-
> @ASM9Zd=T_|GH$
> zBF4Xg@&9m23_KCIn-
> MRS@#c&~yr*qEoV?KV>_fi#twFpK81H_@tF!TJC5<lk#eG!d
> zeig~R4XHjXMXJ}%N2=LK1ycL}{=PZ}wqMxO*#*}O_XS+vQ9YdjaKqsyz|DYL2)
> 7ij
> z8tx9bC*WR%+XeRtT(8kRos;3thD(FH9Bw{b5Uv_-
> 6WnIFMz}x2eFE2GOi$++xHI8~
> z!cBtvCR{OGHQWZcAHn?$?ghB*aC_kX2G?V3Pv>~Jp>UJnX2H#aD}k$qy9Mrt
> a8JNB
> zz`YIU!tIAU`l6mr3fw5T>2QT`Rd9E}Jq7n7+;+HKa390Pk3$-`Z@`@iHwrEt?sB+=
> za6!1WaQDD%hWiEFt8nkZ?St!gaZhJ3+(mFR;0obZ!mWq<5!_R7zk~ZD+&;K&sl
> W?d
> zf4Grwli=pS6~e8A+W;5)xBHtDoX2od@x0F`I_n=wcLGy0oQ8ALBhiL6OmxZ~O
> Lwv!
> zndA(cHz5*kf2?@@${hZN70gM6Yv>QWCHTu3mNx9X;Uh+#f5C;LMvtE`F+F2a
> nN#i*
> zIVDceS;(aD$2fDHeEgg1EOizjycGY6oeI1!K-{2{>&(YHzgIW~__Yur%biiq1(6v1
> zQjXYjaj~73`%r{9P730eB6Nw9hr9yL>A3zb;7oUNoN4$sNMN8xs}Add2?AcWfp
> is!
> zuemMiBwa;Rc}Rr6uB}gW30fnTQ4UPx0VlbDQvbTPT(1OMro{)#UD63YQk?#1t
> 4hGP
> z5b%{FmbPX9P!j*e_}AYVjPPL*%rnhY(8B_>QVHS}3Em5YLITcAX#-p4M8v6-
> FGG>X
> zB;;0!*oF8#ALRv|W$>9Y5Xr3ozbf&i2((pzaErG9peX_V0!YI)4&tjqrme0e4sk99
> zh8GxEE*8qMke47|;^86*O#!4+ohzLT#LslbJ9F^mTsYEe0pe+WW}>9)@taha8`
> X*>
> zLi434>l)LhDKVJrh;Dm1*iME&`a|WPgVKwTOF8nZfLn-
> ~1#o>Qv05oD5O5|s=ipz!
> znSl`UVUfTW05=q&%yPskcdnCs>7_VXcrQTu3Q0pe^Sicf05~iVNXa8Xv<0!82fi
> pn
> z%?Sy)t_YB@RffP_0zA#aa|uc(uC?umsS?B`rxzekk1v-
> Yj|!6ysXYa;2n*>eXmCV|
> zN`X8WhUeLEqmiCr)6k~>Tk!Wcb@(dq=L<ecP}gOGP5ug)d?x{?<S@!ozl5{6R*
> V-S
> z)-uGp4$n%7PYGG-
> EP}6m%ob9P$&(h*_G5@2&zfs5l$3`O$#<j);+QSLG`8(KrnP*O
> zNlvt!;HL_O)L$B9+E>9F+x>q7KXZY}{=fyx|DVEC=X4g`f-09g<CFsQsH6-_T^9e8
> z%WNy<y#FT0j!INXkYd`H9ADBQUk?I2lvE?kb2zwrxcSZgNTn&IT#DfQ|4nUvZc
> P1W
> zL9S0h&ocw^VGtzkc?ZGM|E5elINXHYK`*M*sJ)KLo-
> wEo|JuuiFGH2&%+7Kr=X(84
> zE~tyz%d!aVvp=H*W?xOJ_Dd|~E~Qq5@L*KkIZqs3+ViBRQ&`z+6RNJmk3UB
> bCtnTk
> z3jw8KguRZ}i+$DhEQ5Ta{zoaH`CHjS9kc{G7-a|b4*PzAc^{6p_P4jz@4uIKok3D2
> zv=Uo7xl`M(Ysw`>X&KSAwYBHdU*3N!)jO|c*W^z<Aqf4?^P}_qs_hetCySr52!
> 19R
> zO6@v+^5@u9{M4~d_|@g3ZC_6gdh}TaEz;@%8c*feaHDyX2hS6(BEO|TpHSZ
> 9o7Fn0
> z<CFhYKlit@{$`FItzHyKXSG$EJ^)>^1Y;%2;$`qJmcGGX|7d7c=e4O>N;K3AVc+m
> &
> zN>t5@qa#nBwp8;~<r-mWpR-
> 3jUp4>EM;7CuSJ=^&9ZOhUmLs#%4W?~>;Ky_O9#JWz
> z<B{2+OS1LNMH~C`CJ0??@9^h76m-
> k{7obPsD7rvu+_mNTbJy}{5AaIN70PD$v<UFe
> z+Fv@dU@ZiGtQA8d!|Q5zy%H4O!?S-
> _9bM%K>*(dvzK&W?jtgi<psc5+FitEiGoiO-
> zIF~{K@z*SoGdJK)S4x_L$DasWAGP8DVjoWY3|I%#5no|mC=^g&TA}Ols^jNt
> V7(#L
> zv7OI`ge(=iif!v$)HlUB3---n@D;L@cCn&un#46NKxKl-u7}&^?7?kyJPUO+JhV|L
> zENZi4|8TGrtY03+0amNK80}|mZ@I8v&<>RkoGpW&i&(UqQK~HxEOvE$wLC3
> NYi#Y7
> zO93TE2DBxn3m4MTNL!*pyI@KF(1PU!&besbvjJ}@>cyI=^--
> ;QvF*z$OuQ^}W>&^T
> zXW^K+`T28~E(n&E7FWz&P#(;kUz|U;qM&$T?($I=Fko&)`GUC>*Hr`ymJD4W
> Sg16Z
> zUW&Jh2wqa0GldqGMp?~LU>Pkn@ShFZBGi=H{V|@r4A#V%=!Y`!TdkwR%{
> P@U)^6Y4
> za^K!|-;wp+#+oa(eYM~--gR)a$Sx7C(2~zL`1F4zp1M}f`E$4JOpBw(k!J!oDb7mh
> zJmf<wowTiU5px0l>9|$tyldg}=WpRFL#edBb<B4uX#XH!ssP2=F)2CGT4mYR)
> @GfH
> zmYxo4G3#|vhvAOlJWA)KM1L3KU-
> ?XPxApTw+i@KUNBdfyjXKkgPr8a8BQ7%dQjPV?
> zV89W|WR9NR<Dc<hUbfHUtOl(zg#tr`aE{I{uxB~AeLnzRC8c$iR{$EX%0sVL^TT
> 23
> z(#qgN=cm1_rDK0Ps0?9`Tr6^>oan}{83+lACAb7MLn&B^kk}StT&=YqXJ;e*1jOf
> <
> zm6m)z-t;$T8Hgv!*K%Oe+6|)TLD=s3$VYn?EAQIF>MyH3gze$8t#!RX#-
> 2(cP@SOT
> zI%%3%yJUaJwz-
> g=<SC^$S{_)(=v+y^OAw~z<cbF5$M<3O1HmO_3yX>i&=Huwu9ZIu
> zqwTkqLrDu3KbG#I>!OtD#MDq{E{U($79p0~w+Xp{RN<eSv+!8@@My=%I?hZ
> GuNG#`
> zCX?=HSFkO@RGr6C*%F;cG=))@nPlt+9o1#1uRfkNT`fbF!wExw^mo>tp9?690
> aYm|
> zpB$Kie;o5N{vtd%7NgCJvnPvC7poJMNnf5~Xzbc3&a$?#Ymrh%<w}VoFd8P#
> =lbCE
> z<XcB@TAFrHS_vFy2y7eJ)<$Lr$<I<u0W=J?<6G!xi&2Z6&C&7;XDNaLDcd9#Kl)
> Y2
> zCCXnK!r!r6NqM1p={&7%1)WQ<U$27BaW%?|#*+4doOQGCv7UrlXNbLUD|
> NjPudbBe
> z9#rK1L3l4i&Ar%clN5=^QBN%GFGTC-
> q3u~p0Qi^+eQhRsoEgq!<mL4X0m+e^$yk;T
> zXgQ&7;Llg<X-
> lLAMjTn)hg6t{^aV&q7+Hq)8o8$Qsn8xK0SfA~nefNso%7<1sr}jM
> z2xX3JJ<<*JVa_18&zo3h{g<LFo&P1qyISAy=dIGL?8*twJ;p6WdwA<fQ25tSzP|
> )3
> zPY+Yp=UPd>G=d?vZ^_pHCv8GHQ@qfOR7nTq7W>z={fy0>x<PqlY^=Hh?QN
> =qaCHN<
> zlH#wSU2M*_O^8_=7Hhf41(imx)ZvI!|GE}0vE?XqT0ZqFk6L3j2-
> `o9|8&L2^}r+h
> z5snLE!^nA*v8o4B$70_*A1P@mV~XgI_VM#DisQI=5j2^gNf8~UX((-
> UG@|oD(fXZQ
> z|A|dn!l+|fNH1_kiqudncePy5^0X|Lq<FTlE&<FP!O8EcqjdhA5>MCN*#3g6Ru
> mTt
> z4Zf)vbuHa^Ia_-6U}X>9eubOrN7iDdE2=EqcC29Go*B$ra7`euytJ|;KaiVOTwJ;!
> zFR-
> Aryu7k3Sdi~H)9_v#SejQ}lsCV)AW&IRkRO;|u&}heAW&3N6fDXsF1kK1SX4^M
> zrFktWSW;Skoy~(^CgxQH1HsZj#S-
> LSP#y?gS5^>MkXKnzRI(^gTv|~PC|wxH&kN>7
> z@+d1UDhVQ{0YtNR?(8+iDTA8>HyADv?l9zSS$V<y$|6`^mK0Sim|HZ0rkBEN3
> M$I1
> zrah~$05vSGEFc^iGqVEA@+tx)rNKa1d1+ZedGU3DioB($ciw_>0-
> G0DSXr`wbw(wM
> zi-!gRvkHqU0{CB9QHg--5Tm@HqOv&1{1}Dx^rgx#SWui-jtrL-
> 1q%bEB}9fsT2NZD
> zw4g+?mT$g97A4V%^8)!r3l|oYBT)yL3=KFrCD)XcE-
> MMls6@6)3IY=g3((#f<>jU2
> zy||Mts?B1^fM|%20%DIxV?|K|BScX|P*4{kjDr03WyEF*7{&v1rI5S`jgTCaPzn
> hJ
> zh=mOhMJ+)5)P;c{anDRiF@n0h;=zIIN-
> F~ug{76n`GF;Q71tnEL7<|vvV4KGG2f&}
> zK{DU+%GlN*@?b$=eo>HVko~06@<74zyd`DD1!Dq%UcGxRD9i&<2F3+aiUM
> Z_hAp2o
> zY0%hSy(bptl`LW#OTMM~WDN_~b!g<`VxguyG}Hnx0*bp9bW#+&j`YD-
> r55H;T836C
> zx*m01fP97u`kYya^8cUosr7rT_Y`M+B6u5a6kH-)^HEb|T`$N(o^ifsl*}UjBI4;R
> z=PaRx2-
> R}<X7Fbu*jWzZfMn(u5Z^*pq=M4Qpb7F(FH(bVhRpI9XHs5KaV2Em83XeJ
> zLjnUUBK(zEnqLX|I6ZGkK_qMvM)M^MFn_vga|kqSyKa*fCa!b62K~q+^pW2
> Bynu6t
> zGf>8f98V2I-
> vn4p@6%E04AHizT@A&W(%wjugTBG8%H$Zi6k+)&f!Yp7A6y4IL#$i@
> zX#8sT<d~!YIas+6!DFDL0F+;8go(wssh4e!g1p#{#PkKA?}Bnl(D~OXUql2b8X{7L
> zEQlRgq5qim#Q|L(D<Ng@i}T^Zb#1v$ukrc$0I^~WIGS1anh6dZ6F|6hha!$kDw
> oVh
> zheT4b%xx=ym`IZjfi)&@5z{ZLfFvmiE*y{FAh7Zg!-wV<L#Z4%boiVA!p3_9d)S0{
> z82udQ5^^gR2Ip5U)Sj(t^$?Eps7I@f!0I9$>rB*v><HJ>I8-Bv{c;{K!m%<({~Qk(
> z-
> Lj;zxLAKWJskXxb8u{W_a07<ZprZ(85u|L@BCqy;b7vxsH{0hCO8)k8#X%&8vz3
> W
> zIRPPIUg13aInMI3<@ifL4ChEEApwsB{NwB4=nupz#6wwS&?pR?KROHWo&^r
> #+?cmR
> zfxJb2E<$(_esNW%@|@+we59pSL#?%}w_3P6o=s8&<ci)IMBZEv|8<Q|sN32
> y?AXMP
> zA#^N9y958amae#ZME4k!8C|{X5H@N5*hXjhInq?<I$D`vB`fW2{PSd`<IIL6WL
> njv
> z9VhX)DUJiTtM6gymZXjR`HRZSNE@V!St8K`@VOU;a($slZSIb-
> YceQ<0|GDC(6eO9
> zXZ8fN3hFM3(}hlyO4LR>9p9H>ov6(>dKANY<zmKyE9++>W)QNy02D*&3`SDT
> hPANk
> z+mAE1<tQs?+Rs{@JR8$Q>1lG|X8}V~U}w5a)&tP$M7!5`tl*i3+N*>({PZ)>mYK
> -w
> zay-Ax{)u$phH{K!C$5={-
> aBFOn2zv8QF!DUp_!<sj@6mk?vk<A+<;&_AQrtq6s39V
> zemwhZ1@@F&CVUs&15-kbgp3%Cxk~=#nxd}*Dz#X1-
> 9j!fV!4PGXi6SGmZ*W84$Y!h
> z2Wy-7?aMgk(sk>YRYvv#9nc=hKE$r5?G>@?>)Nhf($=(_cx$~-O{vxY#`^RBxjh-
> 8
> z2E%sCd3pa_9_eqU$SO(+yJ~GZWFq5|@}jNl{*~&wUneE98jpG^t>OpEQD+A
> jCj<8B
> z0&u@wQ>gZ9T}kNo4+n-3MrUZhuC0AZ%um-
> 3TE6=7>jr5v*ZqyrTsvE2IiX*Meueh$
> zgIV>uS`J5-X7#g)#YGquJI>TaC9v6GZOV*U&h*l9SYjM!Qh9-lO%hH<p9j}=(iEo!
> zt{F}&1Y-h5frohlBY!HwV*>N@Fs4=;&wPYpYz=eHP%7_JOE5|;!Z1A&J5V8-
> ^uVc=
> zQ2m1i6%x&%0<Uld3QJ32ee&Wj)bW+ZJ9wNxUNAr_dSGB-
> MF1ui{K(gIU9F$67hvzq
> zy>S+=RvLRFIMM=pF7B|S1Z97$c2BiP+BHtxoxmAMwK8)a2iQgrn1x@u|B$^}
> Ht6(R
> zxDxOP_g--xM(3zXz_B{(h9Zzg=P%2_c|pv}YgyDgRPQcB|H2)(-
> WN?X4YfJ^6fBAK
> zN}WRYg3_jI`|A|+4DG+^tWg=@r{3a~-#KK&nW4Kf7}|<xa4amyE3-
> pHTHMg+Fv`ei
> zblCENWdc|GI&$}CNkrP)5~pHzZ94El{N~~-wT}$c!a^F0Ddtivb-
> osDz!5U_HN|Um
> zUfN;;3_MF4Q;|YfS8$El6v15?+L>#%xO<a5F6Rw%5Rbppf!iRQ_GoIim>?{MTC
> =ud
> z+c4asqiOKlq7wXs{Wb^|s2EI(2JN^KoLgQXu~Rh1FU`}vGL_H0A^`~4EoET-
> Ah6ou
> z@cSXMh>`>41w%R%1%5fuVVq7xK`wC0(U?cEmIpcRIym2XwtkQEY+uNBroP
> 0TPP!V<
> z%eQ@N#?B`k4$msBaI`}HJ{YfhF*%QI-
> <1A6o>L05v|HliM*YGXwNFpYnA(y}7fti+
> z`Nv=Sf5SIZGR9{GCSEpUMo!kOsh3R;q-
> V^^m^dpVeM}&4A!h?9=(Wp9f&Fa|Tb*1n
> zv==(HKz>0G)>W`Vun^(23c{vaT%^5LU|D%7EW4P4upOFYSb#YXm|#W5z-
> j_Jx^y7_
> zC*U{~<Dk7dhttf^bRoh_jupYYa+%hM#Tn`6{|r2bz+Eore;WFMi82PA<y--
> o%pPGX
> zde&S>Y>q~!LK;&x`)Rs8-
> >6*m%cq6VsRB`2OjpQp=Bh$G7rKCzL!Q)uZIMb4bu@5*
> z?JZzjjA&l?Sh7gfqr;7R2rM3~z0pwzOUuYx)G-ay{x|HJ=Vwl3ZO-)&A4b_bDBb-
> J
> z!Ep#orH{`XKRF}a$tBZZ>QU$elUAJlvnKWOf?#ENiB9vJ4rRKdxVdDo3FFhVX3d
> b6
> zJXoBJ>FI}zGySsk3`ROwJ`*w~Po0iPR;N+hl3GS4K|A7%f&Js!BCG9jU0H?bN=(
> Ul
> zhIDY<WaL9#DND4lS$LZSUK<~?>ZyG`x=v~sdfZ_sL;q>mO6kd?OHgYP`I{OwEk
> wB}
> zeUj*_0sM}RosJlU;R=C<&`}l~Ivw|Hb9FuUwXnq5k_RP7=VkfRSesbqv8N&b@
> shtk
> z9ph6cp|iGil|#0T(xG9hJ!3pts2DKPs>qeuLEwEp4&SC$#P(sI&s9h5b(9HtF{8YN
> zvO*xj!))_I#W@6908?tO)RB`nlA_g8HDm`cQX{6W+#W{iCd<Sg*I5h)IdSwe^B}
> oU
> z$MVCGj<W6AX1kNgaW0#`n3K2pl}k7r;f!!l2EEwC5iQ;Z2P!J(%L<2q%LliYzZivM
> z>>Zn=y_jAg<M!Bi2hG~~7ADA61f(yZh92O=)ES(F)cO81Y+yPnA(PEgr;5Oki+ec%
> zGk-O(;$lo|lHWbsg|?5UP1<n^X&~LIT}H7gF37v40s?GSX%N-
> ))Ok#<4V=meKw|}%
> zmRG*00F(Y^UXAmxF)>gNn}GA_d|@Xi10ppf#I_s9$z_qYRy#V^DU!~)-
> c9#|d1E-P
> z-cgHl^jGemuzf7+$h{%tAiH*#^D$m-
> ?2$VfVZa_D`owUgr@Whu=X6LbFE4WKq4L%>
> z)8t}~xV;`fJ#R_gBJ`}f6h{Y#g+&Vr4>?4HyytoX)uXMZz&@1=Uc7-
> GW@_yyGG=h;
> zjVTWY_Krti#Ohat!><#0IOQBqXFAdn$crVAf1Zt`{TvG6;ye!J566J*&$Z%O-
> 3g!&
> zo#CT&sgSuE(oF0+U(She4v@Cd_Fw0N7C7>^mK{4M*tPa6u72d1Y|-
> <!T2F73>+ee}
> zSJ0a4pX-
> RmmhE%6uCc@?EqKOTA!_CAfFM36z=C3>syA!W@!4VrE7e+SEPqZ#*%M%K
> zV-
> LYuHQif7zKUIM$@y!YJB^;Rjjk2(qG@C6WK;9IuEbW1cC{ThI(KVt)b`Tz*8KYx
> z6%x`A*J5*}FXyI6ce)mY>q_+e4zAVYY$-
> 8E9^m>9Z`U$+B+QqvJjpA%52VcG45dmV
> zox@gY<@`1E3VWIwZEDo()RL(*LR$+<wy;vaD-
> `{OtKYfmoa3+QV)s&;4bR8xYP?$5
> zJ&Y<G9`{+=YQI}!kU*?E>pJ?%RmI#Z#+{*@f6{s%=9&!%)O=Z4z<nYXo5YNs$P
> lgL
> zrHEwGl>kbAv3il^OIzRA70(|1QoG@de%Hzy+se#aaostua$kcdgGl3g8f0vp9LR
> 0T
> zZg1|2al01o*b)?WT`S!lo{6R98Ow`;S>>e*uyTm-k@v`RJX39`&;c#{JpZ5!ngcZx
> z?F%}RH+G#xbX?Yve_dNoow*tY2&pw&ZlJz*Fetq>7yfu`FV&0K1KYo@g?E`yy
> q2TT
> zvOl5R_sc;)9Ci*~XSCTS(Q9rFlP{MQl~fch0%!6B6Ka#3ESp?l+kAFWNq*@vtbO
> CO
> z7{hb0)Jum6Q%kTwdWn4CJRrVJ!vfdwSTnq|Agi>j64Mq4(|66r$pjVUEh?B$x_
> q{i
> z1HCZ=<7Dpb8j8^**GBM9_r=*AuzoF-
> *zoUHb&%3ZWJ1q1NXrqTGaddAJp*$D)){D9
> z@{G&a+_YD1zvGEGp>!z#<pgkwEN4~&GPh32b*TJ?u}Xl7J(Zr+B?0idmVUH^J
> VWUn
> z%S^(-
> y#mp&=*e`^nhWdPvHoJQtNr5PrP3N}IWt8*6ak;arj|n)%D&aEjbq8A>LtPx
> zI_hO_99{N*pA&Uo{^Q;<?v&P@T<xWwUCUB}ID~?_Radv0-TCg7FjQ*o$r*(-
> 9c6O|
> z9_=B~vejb6)<|bfN!_zWQd72TI;%DM>t$Eze0}w@CHU)Q*D!ck{d&sp2&=Yi3
> )k1f
> zkJ_$YPwv&8C(L+Ohp%scT68JeryORVP*D(E8d+aUy7J_#)pAIODrY^3X=QP&c
> 5L<I
> zAT)2T9JQk`-
> 4Qw+BOA5#*}Xg+$D4GR@ur!0Y*+SXLG++154EMcR_;cZ;OQ9}Zr7W!
> zcjkCq_mX}caHtkwOR#Wsq(gZ6f(MabbI@^NH1))eby<V1#UsbD{xWS1*oK{t
> &MggE
> zs*IL;vEyWa{v5yi$GSSc?<@w_xX_-
> W+R@k1eqR2z=3R?lj<;27S6<Lk6t`UMvZP(V
> z!dg<V=SZ9VvHj~>xV-
> #ry{QvW2c$m7u{z6UU(GjKIsH0^9b;3%_+gD54cfCzV*5@_
> zN4pWnGkT6$*VfO=+t#lmp0uOMj_n)dPSv*-
> EWlozS(Ap0LVfu>?}BL=Y?qwrQzv4Y
> z3wZLM&81`N*t46o&i1S;Te8{%$v^(_hW*O11|>J=P^^scpyIeN`aCdustaN3T7
> 1&R
> zqL5g8S{UtF2eEA|FdXI?RY6!Oct+J>_LEDvY>7sV!;GI_j-e6bQ=SxpqRCr4jjQYN
> z<mGMg)Dhiz=Yer8H|;uH@8h+s$_G!2vV0W1zBIN4w7);RwBG46#6i~hSy-
> fb*!Zj{
> z%Uf2m6zej9Qjrj`=j>2sECN@YDYR?#076f#rn7U!vM?XX_50c@{?D8!#x+(vCzR
> `3
> zX<1odO6N(+I?g;Byv<!4ix9`scr0%dckN?&+!&kQ`@(dw?bvxK>^q|&?rJ`d&0n
> c_
> zC?+LYM>(*L&-r;+^@}GCvE!3}mhP;6pCU9Jj9TYyPjb=oL-ef-qa;#>hOvg8-cjLP
> z1y1EjD;?$E{`?tx;+d66{&aTC!*w_OU5HlqR-(s-5e^;E5jGo>`3>b^IQVN{-`G5u
> zGBzwaU!LpZotX0_`Olo?ban)~!=;<AL+<(MM)`<1vUszQ`RShaOj<>`Qhxz{k&x
> U`
> zm*BpqOPq`nZcxtBefkK$R4i6pPdlxh-
> 738xI__ci3BjWLU>?>0iwv7oT*0M84xTd$
> zf|ql*K7YfE7WqA%%gD7(9gny8twKg@(RKocQ{$hHuO;yHY#YwG+WDfcyyqyk
> 9Od5%
> zIrYCiT!)FPWx-PHPc2z0xQeBF){lSxy}iVnVT-kwcv?qS%eh!>M&U2>X;hpe;dzc~
> zui}`Qt9Qo3V#*oJ09tP*+*DY5X273?Z`Pg_J*PsBx2467=O~LfTNTS6lrvmEpd<b
> M
> zn8V^3jhs`<K}nM^<9i+~in^aK2w6tGU2n>vEmrSsA^bM>DEwBNA8-
> 5N9XuQvQ^V)X
> zoX%K!cOY@bIl6r6C~6xdM;9Ya2GZ+!JB-
> V}6y)jczE$ky0&@118Myao7E&qR7&g1Z
> z&>X2(NAYuTua^zC>ywn8Y3b#eB^_Dq^@PPDKu@cug^m_Y%4Y9;m5$TfR_i
> >aH*c{p
> zLOIlWyf?Na`Jd~dY<{t$B(E>AeH7DJ%QERl->nT<&wZ0Xc${ywGyRtGyg7Eyg5-
> ~<
> zbmb56EcITWNqaTV+10<U9Z#qfVF|^?cFq~`&gZaHuF-
> 1Dd17yua#zcR=yI$Mf0%Nz
> z2pv`t_v&&N4(sFJQQfup^YZ_)FqW9D<|U9Lw5^clW(wwYwSGQMcpV3h;z^w
> C<IKeF
> zI;H83#x;}^T5Ha{Q^s)hQc!ei9Z8cHJlILw{<gF<?Kt~*ZJ<-t@OODSH|et~U7rm{
> zn(){DCg0O;HP6}lbWYW0!=L`D`TR_u4a>}Pym=<-
> Gi_(H#A~?UJg?PfRjNLnqxG5g
> zhp@u)h(4=UnCEnTrUlIVKR?!Tf2~jFcJo}K&xY~ldAvTWnwzxz7xh_nyFQ(3P52
> b^
> ze!6-8%vCtv(r3eF^M12FtMbhAA`{-vJX`)E>C(2F=OgC1R-X-v%rnD;574L6-8}dF
> zS?je`pK14+_f`6I=IgUzf_Wccz8|5_w7>jG({IzKvss@Fx0v^GeWvA@_tEBgiV2T
> 1
> z?|<Ga`82$0o{#D?ZKFP&Z<+9U=6$k0tA?2OzUKL#j}#w!^jWpdyg#l_=XUeH%
> 6u;}
> z;WNy0ta%PF&))j1`ecvhyIY^mtLFKX3ICx!8`hZj3iJG?c}_LYk@{>n&AcC_Pv_G
> Q
> zC4c85^L$;OX}{EG!;j7T2J?NDd6t;xRp$E?eKwqL-p?@K`<Ul}-CE9H^_lj*KC8Bw
> z@Mq2YgXa52^Q<<{3iF(=&#G*FI^)gzF!McN!jsL@u}@DTc)#AvYx(@!sh@uG
> ?xeOK
> zUNp{eu0L<!pKnWjzwhPwN2g}s{kz|v|BZW7-
> @ahSJ9EFAiTBg)iTmY)sb%kv4u11?
> z#IKsW;K}KmQ+vMsYW;UtU4r)!Rka^KminiY&fW0+6Q(2n!}Iq&{A6nSmB$VJd!
> J!=
> zZ@sLr;F;7%Qy;GTXEooi9`XE%&!yh@MfbnnG;hE-
> C#~U~=U)D0>YOtRCb&OG`Bl3<
> zEH8f{b?%Qwobm8b<lk`gP4BF0NbS+>sXo7+cs|}ojQP&4t*O(3OMbfU3dB!)^
> sMX8
> z`Bm!U{R=+7_oqi9|KPOCm%fx*_MIOLxcgUtf8P51DGk3)ExaIi<&Iyc;C=bu??3
> XD
> z)Yd<ra>d8rz6|C4YX23}8dH~D@_6=Jb0;GI&5Ltx*_N98x69vHbMnY>&hB%%4
> }1O9
> z)Ph^L{BgvELy`Vx#}4oPTIyf-)IR?FahKx#?YBRh`rFh&L+*WX_S3B2khR-Fzf1jR
> zzus^B`|Nb2zwM*+=U-
> 2~aMr?<&z_u&_X~RNSiU{A+ZD$oeDaS`<DB(R4E)_OZ>0X|
> z7a2(>uLgeieYEVT&2OaMw=({y<nO1Ba~^wh{R0!<Ouc$XlUw-
> %e9!vcBeUOsGxg#Z
> z*Pik3k)PpAn+-3_x%REpKel`{;f>>gug7xJt9$H7UDEcSOYi-`q;byne)sOUV@K)(
> zuXU@q@VCTQpFLL%`F-l87q3am4~;?nZ(8)xmfxpdx#Ht-
> b1SFfy<)@4?6*^2S~RAA
> z%38E%^54IE)}FUhN3UOb^nlCGL;c>kap$$~q`qJB)_ISv9XQS@8+1*rvom$+yR
> WW$
> z_K4$wj|b+Axn*bS2iFdrec<~6z+3dgH%@vtb<xY8?7jGxXpiI<etOkI@20-
> }L|(5u
> z*6{r|xo?hmFZJ!Z!S7biL3_;GcFVahyq6k!ZO{7imZ84eFFvba%KNGFPWxfcOP)s
> k
> zl9wO7a{K$Kf!BMV{Nma(@m}(ac~|U8{bJQ`ZmWL^?KkY!+T%ammAdD|tB<(
> vk#q6=
> zjKJ-
> S{*W49>E4$0*M4Z<1HJb&{~`4!YyUd9cn{+5JO7dJwSP?gaN{kzdmbML{G`A2
> z<R^bj-QV~4Ay++_hWZ76IP&@rQUkZXyQ-{&^tkSa#h-
> tWdRNi6hh{9=f048Ax|I*7
> z?oRz%?PY&C=9_1s>z`E@tlFLWey`sxAG>ZW@b!Au@mqJNJ}{$Cc*Y56kE+M
> dOo;n1
> zb<UeduHAMY@atakhu6|ROx^nC$`jvv^|W!$l;F4pRUf8~zkc_TC*<@W=WM
> #AWWtsY
> zQ*&~UC_b?G!g0<$PhS1^&p%APc4yq`KTZIBB?lS{FWQrO{R4w;4JM-
> esw?j~<N7_R
> z5B7ax*vF4eLw(La`L6H0w`Jz0%P#wO{G@v4v5$V%<GA;>RIPjB{qG$}uXlz$uy
> *eq
> z?{4|`=i{7rN{+5~0w2sCefqmwZcII?VR65U@jZTR|A%*O3GJ+VJ@EY0dZ!_KO
> UbaE
> zTW&jIO39gx8THQk8;=<C>^oaBE=<4s)0Xq=oqO6Yd~p0bTYC4~cX!Lcw0bA)Cx
> 5y9
> zH*aq_+xhYDuRLdby|aC$`|nwAZ~1ZgCF`75P=4B5w;uT5_ggmpV*OjwXQd*)
> Wg~9C
> z=J#95|MH9T8crEq?>M2W@BU=RmPtRm^vxyz8in)|PoEdsvE{t$hTn0;ox7iR(t
> 59b
> zE_uh6v*X>AixwY;_&xT9?s{v><?&l59)Bb9FMGQ6xWR92Iq$ot?A}w-
> yWZJ%Yr@ID
> zcyr6}2gem3x$#2O@195gIrYsgm)-XC7d@Asjr8k_)82h!%kYLDU;NG_)bFv&-
> a5bN
> zjV<?A*NuER`*f6_I;Q7;wr_c0BJP*od=B#ef5>|eu&9piad_-qQL)CdVlN;dD(cEz
> zIz*ZjyHXceg$0*g1nXL350=;q8cj4YMtzMfD;G=DSh1JbyNOX0d*eH2W-
> ePmL*9_z
> z`#sNp@p$gcnR4b#xzp}BmuB{xnIo>cmKNCIpgY8WHq)kYj_7))_92Z*4)Pd2_P
> g*C
> z;-
> 27NWT|y}g8X_`8aw5<nEft4@0+A9Q2xXZK^u;Vm1JN3JShg!)4SYXbo!{+?a<uY
> z$DWtlO|B1YJm}pK(fKF0>KT(-
> gL~rJ%vMLl?W(2^77zR!(*JqDpMi(PrU#<*>V?3s
> z-s7g{m|w-x$HL;G8-
> e^YeJcI1{*V|p;AzaRX@0<;%^KO+gJRFM6>~g>LV3uzJ=@A2
> z6d#@Ilc?_w^`qFfETYo^vC*Ef^;$mZ1oUC~KSci`?z5R+p=(8dXdn3#)_%2Le6}L
> F
> z_PpKDJ~G?3+;(7}I7nPDVbdu$;P2GXwAXvZ=3RXDPVL=eH;K@e&a>Ss_8c6v_
> m+=6
> z@Yf@BX5=36<Y(KyKDPt-
> C9PK9S&%Khh_r3K=xQ&Z_Zd`WnJD&&TDyIs6Xd6OG<SZ*
> zEOE-Xv+t&bL3v2OJG;^h;=(;&lxf@<+MD9Vn;8#xi5}H||NcmAl&{Kn%aEO-
> _xZ(J
> z-
> n54L)n~fSJF{I3`|hRT)uRB2Kkqwvz&7!)OOrCEzH<Qj@29*EY!$Z$4yw7|{SRnQ
> ztLL|O`;S=vR$O=A&!9Yt0Vi~Z&Emp|D{5~U1N`VOzgpLQlh`Ko#|O<EpuOq8d^
> TJC
> zgJ>9>+FRZh+9!!WpOy5T*y8-?-
> (nkKeNNc(KJ8o4G33Xm)4MtWJ<P^#+#2y%;xF^O
> z+@QVbyR7w{uuAL|axJ{tXV6}W>`~{>mW%#Rx7u!RitTBn!x*=P;=D~|dOacD;
> I^uE
> zDteA6+zO1{c^~>S$@Od6;R`Y4PK|y}zK|bDOWa>+gxKQ2u|B(^QNBg}*!n<`&
> (;Bo
> z4;;Ve_#MY@Iex?OYmQ%W{F37r96#sy8OM1XKjrud$GIFo=J*lEe{%eg<3Bk5
> o#O`_
> z-
> {<%q$9Flt!|`p7Z*hE+;~N}b=lB}OS2@1I@nw#G<M<NC7dgJb@p+EVaeS8JGa
> R30
> zSbvJ+lN{%8e1hZS93SKOD91-
> QKFsm293SHNAjbzd{)OZH9Pi_JFUNZrCRVKevup5m
> zBF74j3CG#hIh|t#$AshTYMjoof@8vQc2!R2Siv#jIJ*j`bFAQ)aGYJ4(>YdfOgPT2
> z#OWL>I3^rtSLAe#6&w?evny~q#|n-
> K$JymMonr;ZgyZaToX)X=W5RKESx)Cz!7<@D
> zy9}putl*e%oL!pJIaY8?IL<D`=^QIKCLCu=`v4p(IF|MYiW(VU*I;zppk_i?r2UIZ
> zm74X0FxT66auOOpbG$yYcO`IVN36^egswfR_BH$p^C1%Pb=S3?!jvCdN0OE>
> pCZ{u
> z{D<`t&b3=%Xc`6cH)3D+*F`}>yNW+_csLT~v&1T<^ym;FtJnI_*4JSE3=_)W@IJ
> yr
> z>!^j(a$$Z%l85Ya>n}_{^X9`d&sN~huGX#9AYt6IYhN4*=!W#`$18;k*M9Jfavba
> m
> z?pJ^8ei0!ws<r)WY;#|5Uw^YQK1v95%&6xR(Fxp{%V%AR7L<+)w?}?(0C(=0DS
> k@9
> zF>8WYIvD1kWYMY_S+Roai%tz^g~NQ9D9SFgj~50SCOWE=f#BZse*0>baJ7+x
> CbJy!
> zn>qWM^)O+Q{_9D{zqSQ;_V!v|BnXDvua8b02=jT8livGvqTsT*$>_e$$luhnON
> S*1
> zdtGV`zp@49d*sZWSL$S8q^wlpsA`zMc4ON%!v(9v4$nhAz<dtWtVG-
> xF3g!fM%lCs
> z%InPfWlJ<d=9sbFV=sDwJLt;QkQ6~YdF^bg*_eLLwN}-
> %LWfqlOD0^#{5NgZ9?%MR
> zlqa_a%vNCdkVE5i!jNPk$!RXGPb&V>tXrz^sAk{$>jmUTUSa&xRH6Np<{94oks
> qIi
> zcfTJY46op>pSBO<PyG<2OcU&DRcZCxT$rDdep~l6Nf&-8{nLJDQU~1Da_0-
> _LbG~p
> zM)f@A18&)Zt#d{SyJ9+cH{Ig~?lXJ4^cp3cTK@ER&q|p7{JmLaM++meI!$%Bh
> wW?Y
> zSAJQe1@YAotA4gv|BK|;M~o5d8)d9$HW}rgxjo%stT5VU|Br8bV|!{*p}`+xg<
> W~W
> zro~o3{wB50S~E^qR&Q6-
> #4v1s8FQUF>V<Z*dW9d6w*$9)$vLfFI9vYcth6fFKB_xz
> zKB*T*^gq$3rE7a|zuP+7ZoH7zw0%m~y(nMj=1DWg3wxBOA1{wZckbxm`{RX
> P<x;Nh
> zn1=4qz0RH!gk?RgtarYF^(4v2YqolVF#UPkiVLrKgZrFS_52A!bFb<bzNm)nrBB26
> z11AdOZY(_GUi$^C*ScFh-
> Z4=a_PWpGXD^YTZBK92nIyb<TJP1_{wTj!dw$bQ60C=d
> z_ncbe`oV7Oxf7FwRev<;nGpi>e=@c8nGTbMuDf2X>zCOa+)i0%rcD;y4__Yka
> 4*uM
> z+%DXmEbM=}!LxBP%EN8zRre`E>+c=Y8Vu_R?$XxxGp7hgck~Tg+7R21<$U4j
> oWnn)
> zioLcU7?`;V=1*jq_le%AqO!$|gg2kzeB=7;Q_po`PWp;7U%vAJ_sqC6i*@4YnL7
> @C
> z-
> O?A_^G}}XsS~rd2xZE9^#XV9(bG4yVo2+?!z(qDVfg+hCu_x8e$JyaYhnDD5y#q
> U
> z#qXA;E^S@`=cfs+4joGo$Cp~~GJPV>hZe=|8J;4>jeU8r>*O}zzR-1NofL8Af-
> dF0
> z)_H=v&5|E?YD8VCU6UK09l))fwPvtJyz4h(U+VZka2skaDy0#>KD6X~mE?xtzTa
> y4
> z+To%*nQYVfEtcom(UHEx#iV<uuiUGM;m?#A`e(9Oc3q9P>z<-
> }^pU=Ez+LUo#_Wzb
> zf4tt@qjRztnE(BWj-
> Ak*+hE9+B++_8Ro|?Q&A=T|&Ebt&ENi{mW3xN*SJ9@Fn_8Tv
> zYfyPeGj!+lJw7c_yz)BB*7g|8hsmOii%uqplLEH>@iZCddqJ%t8YGBwU+Qb_T
> @3Sk
> zazCp@<S=plf2MvLu&E}vozw2F8!B!YSiNjDTbS<>=is%uDlvWf#<AZuLHQo?i*
> #0r
> z1HZhuVWbz%2Xo>Y>f^;>^1RauXRHsOuX7H@iDSA>yfpV=OK?}rpI9SKOpH6
> @(CT}f
> z?~_qZePhKB%eVQ~evk9n`t@$EP>N%A2Cmt)&K2Cwr)S=c5%a<a8D>uK2Y1k
> qPIfV3
> z-F^RA*RTuLm*V@2x@d9n)v_-
> gA7FcUbzs!)DDl=$p?mx8hWRv!DE(QvDDk@8d`;e%
> zy5R0Nc)MSuc&v;6FDo>#ULrZ?gXTwwPmc9Cu(mqJPrh}0d$_nhwfgUJy)Dwi
> UU&@=
> z&pz9_U`990e^dGT=LU(pXO#Q;=xSO&&pRmxic_!r{OvFoSWgmJ^Ut647p+@
> WEO*%!
> z`3ssoU}8Tp@xukD$-
> cOrP;^z+>MJ%n9QZzSbw^CE@z7Oa;?k|Yixb{sdKs=N`%rOw
> z-
> {Doh(;+{ZtE0qV@m}50iTAssJhK&j0(y(WXz#sQF<74wU8n8}6rHyoce;>=^`VdL
> zcfn6wJ#yv+x2{;fnbjM=@D-DtY+BBEjqN|8<GI@2;_2?sEAQ)z=|>!z=-
> ?rC+*z*n
> ztY%18Tx=QWD(>9r`m~!3()Ih&F3Lq+yWhLm#N-
> &jy?3^CSFuc5Mep0!XnB5|73d&t
> zSr*vlL=RY>5q-@+tXqqdorAAjn2+TlJsQ-
> hCw^!*!*THGdg!+NDZJ~v#C^+bPlgp9
> z3=?;T^{(8l;BFU&6+Icw?!n#Nx!ajxeOHD_7w&fA?oQn8z_7xe;cPqZw&m{j4C~
> u5
> zOxkjHYwm8vaCQrZ70tQ38F$OLy9vYk#tf52+})778!((*k6}e!?zZOc+T2}}VZ9Z@
> zqy~3a<L;^qXIExeQHi@NaCdozNjZk~Ww^UEcN6Z;w`TS6o?*p1?ta7FuNfw<7
> }mew
> z?&sW{$FSll!`Zpq{g}J|<nD(IlRp^NKj7~B+<li}#T|yTZ*lic?!L~j{u;yNDtBMz
> z?%%lkBEyOc3}>I??z7x|nqmDZhRI3pKEd6`8O}b+u;K`J|H|EmxcdOZ`d=6(`?-
> 5B
> zckf|1TVz;~#oY$({+VI2i(&l^?%vMbKXLa~hO@UYtk}%mKXUg*hRF{M>%Zsj
> @3?y%
> z!-{Vi&R)yiYq)zgcdufYWHPK@!QIQbdnv<;B@AaT;_ijq{T0Ld`3#eJ+&zc8Gr0R}
> z*6y-bGpyiPzl!^3@^;CwVkL9yS8)1rPUl#$jQcO;{v0coFt>g&r!V4kjui_zeF699
> zSn(D2pU-
> giJWl6WF_+WlaC!!(bFBZ8`_Jb794lrqw|*w4&){^971KF=8u#Z|F_rs&
> z!Ep8zPUl!LnbRk6`b19WSU-XLkLUgzEA-5*AIIrqIh|w0816rs`*W-q#oYRloSx3<
> z94pc|eFUecGOXZOujBq&h6%@t6z0}zIDI&$bF4__{z=@QV}+Wz^@*IG!08+-
> hH?5(
> z?$5D8#r@+M&W_`Bjuo+-uH^I>PUl!3&HbaeKgWtl=GI4WdN`+ZtQf-
> SgSkJ)ib33e
> zAj8=MIGtlfe@^em>3un!V|^d)AIAMTR)jLQK7`YQIh|ugZ|)z&{W(?yGPgc})B
> QP}
> zV}&25_u}-=8CGzt_vQXR3=@u}_rK-5KyqgjvcskSgQX<b2G=_zvlKbxVt094Lf^Z%
> zK0^0Nm!ZGSSRYjZ*E58aA?IBd9~|QA*AUk$WK&sk#pUZ`ZB&z5;rfTfm(kyFi
> MxAc
> zWl(DxKe;Tq?Q-
> dEyS69adLaEmIdadX%==bb8okE#DoLwAes{6!v48o@g}DABK9$Iy
> zF1^zq{H)uE>wS`2S^wCj+_LCZJIC9iduDmX6PMsgS5~d*j_V(?qeAvmmr8G|)X
> W;?
> zk8V;)@yun4)wU%^-
> r{<RL{!dx?h=*p^4k2yxPB#zs*sm1t1D__9_*m>7S;5xT+Y0|
> z(e3z!K%^h7PTsh<8Ds%FmQeakEB#xSy+fC^n)sgPXI(4%oy+yI`eSxq<N6g=%!
> &^#
> z<suU1X|_`NRjiwx@6v4c<NFCIxIaOxt7a16`=ic#PSh)p?hjQJrG)8LvU4>PY57}K
> zC#8j1JHoURdbdD&zZ%)4g&>vN>`_B#{)?>iWd!fk^Icyra76m;nu@Z*@Qn#K
> UL>|h
> zcj?;K%L>ib*bVLax+A({tTW3Ar>y*ByJyq*XX-
> ?h7yd|mck_HD8a}9=tb))vuxU)o
> z#g#Dpg8JDNgj-
> WJxzFDI3F}$XrlG!~(C)BLTx2HA@4#n@O2YT<yOuRMO6ynCm{b;i
> zd!91>^dGJmzg^Sp%EH`+-
> l3`=se837qKYuB*UGaq*3tUb*vP61cRiA~L=3Nu;r&`%
> zuPVHII`-
> EW=c&A$T4h!fwp9E1M!CB*{F&B@>cWXX&eWT<oVK4cZAlHGbx>}(afhEH
> ze^=XQ*AQZ#JMG;ZP0RPTuEI(f-nYz2^(b6llWX-
> dtc1sL?y?ms+&>{N>gQSs^=tOK
> z*lR9L-
> @0K?O~Jdz=IZx@ZIIsevrRRHOy}d{JIVdf9ofjLmQZcI#_QD7Ug#duIHH#D
> zIJ{iguT5!v&2N%jOW50ET<G*0U67vBR90I!v!v#Mr$-
> (je>I!wYYW2{^=;R@3~i4#
> zHaWG0RYP}Ho-
> l~IlbhRH3!{Cz4ru;@*4Mrk8P>v(ouA!}^!OapYuqZ=TFBk&(xJ5j
> z<=3sXqK;5|eD@XY18DpGwoPUoLGLi~hg}L9zIHoOSD3MA^OFx-
> Xn&d9KBBHLVqTb&
> zFs&4(_pU>BUBTn=e`?hFK-+f@JF9v^i<41%CXiZ4&+3?5Pl#*VX5i?4F6j1g$f+l6
> zaEa^l`c-3epLevcFVqga>UQiEjo;2mUtfp{np4*G)kG}sFP*Q~7sglrLHX?@IA4b=
> zXk8TzgwX>>O&Hsb%Cma6%m%`TwGHlG+)3+G+da2|;63=<&G*x2{k4_{H58
> 7HO8i;Z
> zjLQ2)&rJ;ledW|aC$edJs|2ghgtZS&-
> @T+ROVf8v{!Dl`s_T!<&QgBvx@CVRy#MU`
> zyDOhpMf!FRStH@6p1Py5W3+#M>7{QZ996Yi|I`-uw@8A|^+v+^=Sf-
> bXVUu2_qA^<
> z_=dLVx~(^LKj@XwSjbs^>DZvjxW7g&_~$kj?6o-
> yOI@bz|9D_f6QT0W*1LagO!?RK
> z&TJyA`QX%2v5}5nsUf7P(C&xI!$-WK?R#ukL{p)ctoDtqyJ`QM(KoxP;B_iU-
> D4KE
> z2mOf-
> Rx;ti;8o?{oyPL(f3$U$3BMkg?Yn9orHgj)G9mZd&aV@X(E2^qagj{8bV9bc
> z;tkrK?%N-
> d2^%(lQ)|;?%HJu6T$zwzvuo##+SL8XQPxZ_{Haf0+XBw>iN2~6><8zC
> z*Q#`{3AQi2U1xnWVepJ+x;vh@U#hq1vaXqsFui$`E2TPvn|$8&LNlSmci%KI%
> %S~T
> z=UmZ7*z~eldh_PDp#Jr%yE)qk&zh#?q;JOkKK<$L@isz~d+kfhvuXQ1(<8%1(3
> QH=
> z_*O8|NtK@2HiF~ybC*Yq!SO)v;gV}3ls>9x^R^3(KVFbE7oN3Vw(!O}n%_)?Pjk
> Vk
> zQ{72oHFWEbyQVc4bOB@9m7R_4UvKTcuDQ@QOVhQ#2KUSKgFP-
> Z7aEtDY1gYK?cW+t
> z(n2Wz!}7x#J+=>hwwHYip;J$XM-vCo@wt{yL<=E)^o)x8d(!%f^UY`>-1z<S`hYx?
> z2N6HdZXrx|Qf5}!OZ)rvUiVuF`L{+*l7EBy*ZQ9R^;-
> (M{%eCq9LD#feno&!OX277
> zwQbw|hU1UEbWmDLVPbk#Q?I9X=(g>h*-
> {wPt?K?Bbvl5XEDX+RDLC%!HsD<hZ9ip0
> zNh@J&|6Ze;R;z&FQ^M?934Qnfy!$~LTHbYi`n3}Bg7-e0=1ci)(r+rz8)w(3RGYTn
> zh5dK563R@9JJh-s@<(b9yx&TwX6^CRW(aNnR;Oyz6CW*cY`f-
> gi`_s!e(G9XvFqii
> z$%#90zmE8y7VC;T#N|tG)NX_BN@u>TEB?}`RLGh=c-
> ~3&oe8fi8Y;Q$Z+MP|AAPoC
> zU2)gCs;`g7_#@rvTz(xfZtv#W=NsUD6Z!qzi8`X=rpCiBEptHkit{V$h{Gcr9t>LV
> zj_%$UlIn;%$?-
> =mdvrs0>5D=gvDUrt8TQ{(`iP57>xfQqExX)XOY>`W>9MuwKX+M=
> zVN(?t{`4i$T6F%-
> A>Vb98@k8+_NBGxuwPf#?T9tH+g=X07H9puu}c59uMFTmdAXyt
> zm^W|s*BzR6M|#?o{MzD4yR#FA?6pOA<EtlXi+STSA8$L0`%Pr})gNn%6~w1!
> mS6Bi
> zx9zoYwZ*NqyASRei2E_*__e^=V)GH<Loa?w^H*PQT3cM3F{Mp=PZ`py-
> gsO~wEex$
> z*wNvQ(Y@}5SWEn)vD=va;jZX*zxib?u~)Op>t^<+{9L{nUQ4vD(fRz7THZ+4-
> s)IO
> zyy5<4_7^Q^eiv@ls3qpUZvH6$2Op#--o92-TwwdK^7Zjl{-
> y5xSX12GXYu1JYAT<3
> zcgEEedxu#Kd7-8GwYVEtQ><Bgd-;8no}xUq+-
> +J@+?Vy|HPulXUvclTmDuY$=SQP^
> zIAZ!o?}=8TVo#g*WnHN}``rK1O8n}Zb6pzNqwQhy{Uj^#Soz;KWQNlE>h?ge5?
> kr+
> zzS+Fl4&#dtYFLS7#(KR==}yB>IV08(4_B}BXSr`bNBYdO;WfnBSN*CT^QH35IG0
> ~t
> z?73Sp(Y`Kie;MajRu{i%F~#n^_gmz5<^`d;IA%(x;KN_i{mm&CuT>M9jka^LKJg
> mq
> z?JljXCSKn*Y0QMFl-
> }ewp_=GzGc>WX3*29T1B1)gs)|$EUE8y9ZXmkfT^?6ew67*x
> z-F+o>-
> @nqds<?9L501U2(eOD}#VTU&i2bK7l%xD_y%t_Ytn;nxOqBs17=OX_{K{gD
> z_1C+UnorwryBlI<@#iT&KK*8s7t+h$46iI!4DEDy^|M~+zJ4>mk~q)bZu7a-
> v_7}p
> zT3Ja{yxJcA{s677>9>VSVqJ%2gW|*PV0rr8xmHo!cW?Ez<ae}wTHPI2QJj46^Bo
> J*
> zX!&yQHmxY0KegdN!*3g5`rGb7YfZb}xMO_PuIP5YKdyr4xBOu0;QF5EesjNR1#
> xko
> zMOUi+Oylo(AeI+P{l~3*b}Hpx^Lu!C@m}<*=XW>L{M!AIUrt=mxmCsbduac=
> {>RF4
> z;_#ETUSB&&<IjC4loPu*oD;lpEger3e_ksqUY@<OMU8T}pG_YAIj*c&z1Q3;rB
> Aj-
> z_n=2YS#f;MccZ?FqUA6B_*xk;^JxpuA5v-i`R4JsGNSK;5zcdhX?U;Pre#F$SK&jq
> zbZCq5Z{~`n#f|NUK6JZ8<v;pKcxkap#ISO=$J6#*>uG)|v1Mz`w^iLJzu!DvSxT&
> A
> z2%W#PAuWITyzo+D%~}WEl=i0ey&x~2h_{+IQHe*JWBRgZD~Z@+`qd#9w$u
> K#?wLTu
> zE^Q({e?6bJ*FnFF`B~e1+;%sq(;34@{E`15E8^-OyX+k3_%`UF@FA=Bx-
> Au}i<H06
> zKgYe#x+3r6as4fohsPuFU6%ieEyKEp(f)n=k?=0dy3UFYt^ZRR(>wHd+}o@j@n
> 4-k
> z7Dn68x?J&1R@maz2M#Tw{bSOT{MT99j4#S4?$iAHJr!PO)zACttIQL$eYVIO_b
> O}3
> z^=Z-
> P@@V=G^Td}~>DNwH>$r%@cf+&%7g+}@XsetLrS%*CTzHZ7pn+?XBW<aCu
> 0I!_
> zXN|nGDf+~^0OV)>i~MI<qo%w*Y5N79w-EVD;aQgVl;(P&Cgtz?%W-*G-
> ;A*xaq$6l
> z>tBgav#O5RJZaBRT7UIl=Re8neLF3`LX&zJf8A^0N!E+qQ`=cp#`6K<^k!Uc*1Fp
> d
> zW>k990o}>Z$34y(dpRqtzl_SO{)=&svd-)~d1T3US{|#H`46)uOkSFwyo0vyS1-r?
> zk(GGG+3KwWO)uwF{)4R6tEYc+H<9w6`Fh;_ti^Y4FU!3|+e7@D{JUAb9z5!Ap
> H0U%
> z+1qh<vW~7CzCY*prkMYsxB0iSen@@b7OSNF!Tw$T&8(IUwk&r%NXvKV-
> MAZB$Jf^L
> z{C)*}zh%D3zm|1AVr|dr*Xa8q^KJg+tRru0diES$8Pn6h%fFbVyH?wOs=flc74P
> %U
> zWi8&=?e^E%wEgG4&p(}2>iC<VyY1;h!+*%n$r@HqUioestq<}c|47!;iSENggX
> wsr
> z|B!z$>*rTDC*O#n@{r}{@5%b6miLA1I9fhMe*X5X@c5i+Ez41U^!fSUW>u{|J
> 0#>M
> zI=%o4#$VkX|A{&?ZolxTZ_I*k_NBW-Z=KQ3JLo5|f~(5Q-
> R_*oLb7`a_}sbE+x0!`
> z<_g=7?O4(_a;ZF0Kf+~6hg@NB#epFcGlm-
> `k5k{T<DM(1e;v`F(bpLU?c_SAH}%gI
> zlv{OcZl=tVUwv_<?Xcurp_P2|&1-XJ8V)Vh)%W}&SID2VrB~LJNcqIP1BYE!<O-
> c5
> z9qOm~%#qia_Bx^8Pq{+n$jhJGeX~gZ(p%Gh?$KOfc;L;tmz!kBSD!rX`0!S)5IpL
> a
> z*7dq8<e#1X@MG-TTw&Difc<|i9cJh~uvSi~+E0XTOFg<-
> {j$Jt)FB~zce^LT!L<qh
> zvHq#I;kxbmjZ55~2rIfgSt53vXXrh9?V&{jo(Pq`f3$O`VuE~B?=kWnnkRy8`uUx%
> z8RHGV&zkA{dioP#SdE1zn_JB>=#C`)G4Sgr!tHq9QGNqw%g+odJL&q*PlO6D>
> ^e^g
> zS#0=jXS~A~XPyZ1nAJpGYK6S<#dkJAe?AdrY#&v6(X}~-
> b2Fo+_9*{Um_O<B@w$Vv
> z<O?p3nd95^sqp98`SZuFpCEUR(y2!}KNU3P4sIK}X|Y`RW=r7l-cN-
> !&z@z4?U^pW
> zGWw>{bJ$bi;seFvPP-
> ?_$45WEac$C5VN5k)W_Q0Oh8tI#K3~4#sSsA{had0Pnj+7*
> zcqwPxj;F%c4V}+juIy^4Qs(wIlTSSr&ba;->RmcR-lwC>`X3)Y6(%-6>sjOQaCx2W
> z4wXNY&l7G>a5y#e*%Z0M1;2O6&GLlNW$Vwrw`{sRzi!Nyit;>RZT~Klnzf!Mf3
> k9J
> z_%D6(gf?CQgB}f<VK}nBd)IG==fQm1P5iz40z>SDa)}#f<_U(fi{-
> PvT48v(@{ZGQ
> z-{uK7pGThSa$9G(v#$0&+kJV$zP5wAzRF)=uyLy8_s!Kj;pY{(H7i}3E^nmYP}cKJ
> zo{;yt&+Fzn3k~h;UN);-_nDA3*S?V|Z-`;xx}b~C9i9n`(!+0EIXK>6J1sJzV!$)u
> zg#K~akxPB#eM#d#U57psQm4n9>@|OxJV(Cgr`1!Q3As@j+rHkDBENe2d~Un
> 1p9y`k
> zPUb}&SuAheuFKg=;xpl<+ru9hx{r}pyYhbVmdnqCPH968zdc+e|F*;O)Ge={3A
> g(8
> zKUL{J^9^pXCstpo`&@W5Z?|f4>X(KIfy?`}cX}>tkZ*3BHBxV=F?aCcHNBq;OYZ
> #n
> zcv<``!==_gb@5ID`n<-
> aI{ds?{{G;?Gqq+t7w$D)GVsP%6Xb0}eXdma9_Zd)<@_8M
> z$hUj-pWf=%=fdhKs_~!olFNOX{ZJ?A-
> g9B_UA_J5Z<fj{T~6J3qudL@`)Z%1Za3!{
> zCWm$3G`7VHVZm0#*gX^H8D#s8I(fOj5FDp1*U5cm8d}<fO>mBSA#`fg|BFi7
> mKsvl
> z`<)3J|3ZjydFipyIYNG{$GF%PnJ<K}m@T!Pt}Hc(m#XM$Wxo)rR>_a+GfiXY*ib
> 3o
> za_xoi-
> Bfve_pD)tN%MQZ9+Uq<cu{>y%Np{j25tDm`?{ttg~cPMPVrWcH)zMN^;sgk
> z6ndOhCR|*XVfZ!9t<N9fFNM>I4t@K#$S??luLi30FNF?uOIO|zyGZ^;sXtPzSG^
> QE
> zE-w3MM4d?n$36C?{@n9YIO|{cq+hL-
> @~D6lUGi?e6vn34*;RUQvb<J9m(bQ_UkU9N
> zCPqyeJ=akCxZmPwEnf-
> e9qXKF?6=(T!@=fW4ZU9pZ;!ctJ?Y$3!=H0KmR^j1CG2`}
> zX6dT~D-
> DZdr(Zlc{gu%Dr_p(P=P#E3mf6nj&W2Y)t6o$3JbAD{KGWl;x{fDa3E$m%
> z;5g)LvZ2d}I*T_xc_kz)ytTUa(aG`y`E#law0<o#Z`sc-{oHcHonMY^>e}_S@blQ8
> z#vcriGt>w^bi`x8YoS~2+6AL~r5b_)uCAOg=CzPB`Lodj>n}I#s&F{@N#<+8@$T
> _C
> zyHn;EGIGD3FlYa3A?xYzO<to%%VEvkAo~7mLG5=p?Qn}Ux$@57QL$Cu2##k
> P4fgFn
> z&(O*C^M_0A-w5A#xjbf&{Q~*mmM&Y$guM}NxX$`b-Eq00-
> +%0DuSkC*9Ekqq@Yo|u
> z<>LGFuwg6S2oCRGR{!-
> )hJ0k+X>r)TH$qOry~9p(zcl=Cdcfk9_umNPj}CS^wrZg~
> zcH6AB6{^1#THMzAJ-
> @ot@U~9ij@6ys3Kh;zvLB+4GIZ~MXO^b_Tj5sXuAi?BUuN(g
> z^7d)!xVJ+04WVNL`{@jymtSSSY3*CVu5D=b)9+RoPVMQH(d6h`VbTiQkvTml$
> SXBD
> zKXC8Uw}NKbFyZj~6^3QOldmjo@J_hm6Esa}HC{e4CqMjq#XF($fr;0<dM=gsI
> @#Cm
> zN!&Z=Uq1Q%Q|HQmx>tUF;+O9Pk3o7L!-nB<RmS7XvhDAL-
> +UjOJW@s{f3t6JSe0w<
> z1kLgZAw4e4GK`*9;d9#x?}cR})7`romKmN-t5)%gj_-vLla~)4<+I%I#hSO5>-T#v
> zl<zw5eCa<Y$QMogweBtbd*S}IKWFS|GRH94@wYN}*S{AWe@ax5=F8*}TTA
> 6NJN;hR
> zTR%6g@1?o&@TH?VEqwQ07}%?R;IXxH3~g6ExAtoFL0Dita(wG;3k@%X8Tagh
> J_uhP
> zU9X?EVxoMa-
> @&)NM}81)%&L0W=ImVgrHnPJe_ZoHnAc`mz2?hS7@ow<w)HvjL74eN
> z&8>O!mKj<Ph<x<fn-9XKZEL1HJGflFaM!S|?OWyx?z5|jYgf&aD?HT$Q-
> kt_>8mc-
> z-Z;HjZk@I4hxeoMg-V^v=hXUnx#2>_it&5C%@>-
> ?Tbmc+^M(A$@Gsl%J)JMyOII$?
> z{t+c-?|)}^3Fp&a4I*LYFU=3&J<fjPB<v73{oc3>VS<=h_I$-*8-
> x)7yOO@&GEtcQ
> z%Y^*h;&I_|w>KZ$?CAG!uP_dzhvyYyDVlKZIG(<Qk&Zt-
> {hwUt?(3Xx#k|QYDI9m_
> z3gb$5-
> W%U+^`#oWy1@Jhe~&HVEXrnq7bzH)@@6jXCz!h6S%ErqP;)tctBYUn#=;k$
> z_#G#H|Nk-FF3h%uJ=Lj#|KlI~0vl~^;9n<>*;k^N9%_(7y*RP(1u5FyMC-
> w*Nek^C
> zqizo50e>a`T`hj;o&b6|uw>5s>tvc$_SjNEuJ8o&OK(@-
> 6t12(N#muA1p6w=Ahbk|
> z<`79Q&)@)0zfNclm+~s<JvC}NFx8O;dXJ!VNsz1Qx3DEsE+#Y7J%)O^W1v*5_E
> PCn
> zD&#ADKdfwTZ;#*7Tk3Z}9R*ldMty_$m9J?@*jML9I)3fmmg*>AdRrw;Dwgrk
> PU^>K
> z%-
> &}*guo}JI}P<KASX5;srJ0RFdMUfC1*?C+CY1gK^j;prhO?Io|&Fb#<S5Exx`k<
> z!guDF=?22SAk`gOV!&_ZKUN}4y)YjRJUu6ljrk&XUHG@w#(ePGfA&Sb(GPX%
> 750<(
> zF@}pP2$xFRHnTIVg=b5>6e!P<X@5-
> P_8`!mguTg_qtxmMDF^qos$hojYYfk2*&|tC
> z@;nQkD{}wYCeL4*JZG3Z&oOzPYw|qL<hgJ=ZwKuPH9=t;i-td@JtBp=QA-
> hiyUxZX
> z7A~1`RI+kHu5i?28mS~H6;uB}iZ%wcv?NnCEydN1264bx3RCS;+&Gcpk}?>OK*
> ^RL
> zZ9AYPRMZiG`VW}|unnWW5{Zg}*XYz*RiaX+)M&tFCn43)_K06#NC@*mCkg
> Ql@HTN0
> zk3fG{-
> vCn|LV~;4cXFy$*%hpRnwa#92b(2{kuhNB53Pb~m5Iq<_Ad$SoJFDyK&8xG
> zCgq=?iqb@C(y75Mu#*WUGST`?B*a#$V!;TFUFFbtu$2b?ASs<XMVFkMq(M
> V!BO=oa
> zlI){O(Sb!9_x9~&9)5l)cC!9SI<P|uq0p*eQj97#U6!7t)0puHq$r&#0a8L+U#2;F
> zfkYC)A}^S>DbN)Trh~v(8uD&qlA9mpUZn)?Qe+|Vks8P{L=~g7jY_vgEOSjsQ6
> @%#
> zy`U5uw7RB>MsqosO0p&?Mu$d=lA?8q@Y<sa$?d4vv3jUnJ5{S}D|0o956y@A
> hxqz|
> zkt0YtR+E$nNugv|Ch1@SNrTc;Lt?2)77A5rsKDgtNSXl`raA^~FCy0<f;eQ!QaW}r
> zUo8qfF$wGdC8&le6F}O)HoT*C3Dn47G}xn|Ri&mp*`nbkFlQ7aYtu10LDN<it5
> btc
> zbujWq`HVC&rB2ampyVK9_(zEz2?_p@Dm5)VwkJm{H=4Xrs*`ka@iI`D7Y*fw;
> Alk;
> zOeUGsizG3O=U^ePg0i!ULravjTEPmXT9%}a1|w0daTP-
> zm=ES*k9lB9$e%HT7*2O|
> zM!HUoy0NhF8ADKGd5l{~$Fb`t$~Z!05|P%MF<zIC#)F~g6Y)A@ykwYW$x>As
> E%ugz
> z3c{MC86aQKmp>x=@FcYotSWSbh66}O)qfT6<<Je|8OxoNtW-k-
> RHr0?9AcEIs%WJ#
> zESHfoEty#brS>Z6Kx7O<<)ecfd6-0KcF<4J9tXC9VWy)H@a^z%x$sCak=jT|z8b4?
> z%fU*c9Ik`W21g8N<-
> vS#gbD=Prim)(P|)bGzS$_Gqr(l1Kz5abz^E2<ODL)~61p?S
> zHc7j63RoPYBNikSnMm8P<;cQ1J(R(o%CN|G4=)UrCP|G01(X59QW+K*7T!m6
> L`k8-
> z#IUqK#lqkVW{Bft$*32ufGtb{hh-
> &g!El(Xiq<5hB*kiFCc~U04>sJT<M<@K|0SJE
> zsJ{yJ^`NbdIExuCYPK?`<9rY;XiKxb!XXC2tPwRAvN<c$wuL&gP^Y05X0&MY3uk
> +2
> z5Xz3e-I#`GE!F(QbnH}yKKp;mC+Y=NQ;=rXc6N3sF3yJ<-o!=?kI8hFg!3hw+a-
> bA
> zB#nPKQ)2oP*$f_65jdk_F3Zr;yxtBZVMnzE$zX=gWFUtZO`Haro;niV_S~YSi^Pv
> P
> zH|9KinlHAJkQZ>Sfq4gNW0p!FgVvx1-
> Na}m0X2lW0AI+F)Rd^b>t>ZJ!zvKjLvwia
> zC)JlxO8;iNvH|UL$fp*hjoK7VHM2D<sLLQ;JFJYjqG4r0n{oc2{Ru5+8ui$*a+K`6
> zPO=NbdY3e>#hg%&ls|CKY)3IoZOoPw&i~jtAGOz^4rDe1ltFJa>XyPjXw(?Wbj
> M1%
> zrday8>N47SWUJK>&?bkaM|<sPP0A1I)~Ge@W8o!hzSyg!AFg(dx|?w{!F4?9{
> bbT+
> zHm7vJ1M1Um1r*e0j@sT)lO9@r$MJw^=*M_S9Zbg`wjY4|9Bkz#Juz*vY?TsEL
> rR+M
> z(Bg#j`*-=m`p{CVCTOP*wc~z@ACv~xuVjG$t#UEBV=V+yJ%vH^f3#-
> k3N123DhAO1
> zP5H)vymfRmMrr?bNpKDLZ}P)*;1!3Hf0qwdzyEtaQsAAzbX69I7i=`R3u)P(TnM
> Pu
> zp*>u(onaY54)y8^ZPJ^L2K^wc)RRg=&iKBQb}kF|@#4!`Dqm6Q;r<m`JTosR+t
> Wa+
> zm26~@dLY^i4WW8V(c)wP(9sGoN&v^fk4XtN-
> ^xBBsgjTrTH}g=+KVsX*EkXuS4vp_
> zh12<8ONYJZd|}jNcHCHdK<i7E?=sXwj(gmw6&z=TmT$D8+V}subf~8n=gyMG
> OFR*f
> z^oFvxv-!MH3tA+ldDcMC`O0b;^_${bB$N!Gn9TtHIzG;`G2W-*o6Zx_t~jPD<-
> >Ad
> z_Rrc-
> Uun13p@1JY8WeLMPCF7T`QR>G=m7S<7zz2|c}8K)uO+>IhLUA@NpmdJw~2F
> c
> zTx(!SEqREBnF#JVvY89EQ=DhvY!Y|h&2>hjU2y!N-
> rGbTO37ydOiOJ^m&Y<6R;m!4
> z+CNDhs#Eq=#)QV}yfmtiNIZA>JW}nYjPj4vxF&1-
> Bhx?EsXx~xxa#6Ul*xh7+JK}~
> zP!=xn&*}rqole(caWLv&8YMgLmFDH<b%HvjJuGszlr>7)s9%`X9cmB9wu`@_(!
> f<$
> zB-
> AI?b{ss1!_0=oC@OW+^d&w=LQh7Udo2A>+76V^rkHP0sh|#Qc4~n(0NLysH7
> hf#
> zQbkc6DF5N`uE9Fc!5F6|eSmK^8@9{?0~_UFI&#ots2ogf(^$rr-
> e#z;+i0WB^!$pQ
> z`<TxE!_BPSNTrgr*Z*~jk`$ymH1-
> v=x`?$@((TN&pRhhs%&{si5qHsHuqxShk7G_W
> z)Gk}sNMlh^)@{)$EjwFd7HOF#YDdx;#ufY(vmA+0(b{xwl7#rVhll$5gS7zn@PII
> X
> z&tPA7g3tbe0iL0*!Ts^sJ+yz2C#H|jfqs6jq2PjNS3f`W1+5$3QIjZS(?Jii37!{i
> z_a&P`yvQ2<OzgeLBL1B1??q<v=UiVeGD-3myhy3iWy+Q-
> U!h{9%2ldXt6syZX06)R
> zb?Vlu-=N`VjT$#;Dr;ubyhY1at=qJ1*S>?TT}OKd$4*Y2yL5H#*1d<kr;DI)b#wRd
> z^z!!c{k)f-e?VYR@8FQous(hJ^&c>B(BL8A5s^{RG0NDuc-
> 7Eh35n{Y<l&kWtuA#$
> zTKdRQqsNRLSHktm#xZ8&9DA%(vp8Ph9uMlGM_ckLIJb3yXVitw?AV|kPn^l8!
> +O`!
> z2Y0|m@R*n??qit0c}!=e|11}rdBp+;IAg&zY~h?tM}m?q6B`$#apd1DlVwiQdz+
> p9
> z<J^*2dPQlV#V=!x;@FSBqV#(kcQtV2#@VS1WQnyZqxFn$iBG4Evstz~Q_Ox1
> Gbwsz
> zLJu`9TOac32P+q}2#(edaeabopu%m=IA&Y6Jt>Zqjw{$Iz+X}GPHfLuZk!w8jMI3
> Y
> z&-
> Q;!=~%mkcZf|xnC}p?b7nRRW$%r`rL~;9^#DG5;(zdC{F=^lr5#tiNg(aUGCpyB
> zfOj<5o{e!|_T!;U`Ig#JQT#DKN&cpM8TZ+ZyT<I49l5X}Jqq?Di%M6rVU42$TUq
> p^
> zr7o)6rfU&QTPhXKQ`}*ehr2vX+SnGb^h!D!phTqf)ZlO2!8L|M$uX%(G0{hwS+L
> wN
> zf3#Gf<RMv(7@qZ+6gp!Hp?R`!#`hn599074vVl~j{d=^9nFeK%?8oEi%*I%jk<@
> OC
> z^~2=H{4M2YoHro_*9z_6f0Q9g6<r8z!4LZe?yRwNu!Pt%F@|NYF^!GA=Hu;^o
> gT1x
> z0$LbB>nu|3nzwAzkhqs4okIMta%cNVIP=53YBmP3c|7wmZ*S7tIEB7NQ(*q>
> 4y^_6
> zg#>||u`e*`o0t8sV--
> Cn{dGL^k;?R4fqWRpENoH5FAsbF;*6m9r7_0&J7qD(Dt<|d
> zR}Megui~Jk|DAfVj8)vSSjH=EX~OL~{Ed3~|4Tb-
> Wi~4@?h~QyBeZ}dy@znG3Fn!t
> z#+XeRy37YZsXdyG=9cYO>P7f|upHma$ELzP#j-
> {$d1CKPJk!B`k3YOnqoMaoydv?s
> z3Hs5qM8JI`HEKBFCi3k*#0fwKfIG8zdK?11UQ5@^xRZ-
> MK7f<pgpyt}E&ANsLy6a8
> z3QoPl-8EW|sJLJyUP0<E3(?ZsHrgb-
> *aQdba6iR2P{x^I9Gl7w$Du%I=~|d=DWOET
> z*C35WPB5$M2K9nH*`|PJ4;cUB%y`DL#}G(?-2_CdOjut@bQEFdTWIqX-
> z2y%ZF-t1
> zz0X*YTBevDy|zp#`mb{3Hh3vFMHZ~o!WAvJ4G}{HVsXiVR$66$xX+ZJr02Mmy
> `W~`
> zsj{C+jo33S8Iys_K$MJCMk-
> gvTUI6)dEi2hEIw%jyNM(nT1Q91Es{vQ_XH1k&52fh
> z<yfeCxXNO@lVx&O!R$g6Cd#6vuw!`Mk}T`R6W;Mkm;oCt8ahI4uv^wPFe{c$+
> >3k4
> zje9QAtvmDD?h9)N-
> 0#6taaWLoe@Kvro3p(g+*^Zs1MP$!Zh>%j1`Ow^;KquwGs?=-
> zc>BXcrGYy$Ng8?wBP7r(w6ANh=b(a18-
> ti2LbN)#3pA*ko&6v%$frvl)F%Yf30B6r
> zCnTjPdnwcLxwlTKNv9V2JkyXB^uxS?%sgB@`nU%9c5<Z50iErI;!Fp3CfKj!_dTT
> a
> z+1eQGBjd~utsO=I2a?63lFipN50-DyqnfnZF}D?ul8A*~Em;$0t4ADpf?+@014c!>
> zA%OPp@Z1RfaK#k}6i?`*lKpto6r|aiWg1efaIg>M3u`wPA6IPVc^SiD9&T_p>`i
> m}
> zRLH*2{ypFx1Do$jdvI8`kB^~JnM-;<j#<FfK)=Jb#%csPL7SMt)HjsxjTz5wq%~^c
> z5bV^ANhloT5e$FsP})#P@8f0jf}V<VGxn3h{j)LI+)lOhb~IhvNOv_%M|tD`TPW
> @c
> z8dp^xd!I1Nzou^#zY=?={CE6I?;b1%?oHuJhFOZke$7gTJsa<L;Esx9^|t8uW#RI
> D
> zOcHEfY+U2u87up;!gxOY-
> @m6ZS3f$MD=psW_(E)%(xzohTUmEmOVf1<Te+~Zemp+%
> zZCZcqRvD9GH54NJB)*O7&cBx)o{S=&|0EsEky*Xd6d?i1W<mPq?Y3ySS(Y2q_k
> tE8
> z*}-
> Gqme|016K7Aje}?BSIPbxIv`F4xV+gyUCFA(7LN_Z|>l^2mIKfcHG=m~o`bjew
> zNp9xlDq0$r<@z^gcpYH6s#d~#Di%s$a^Eim?EI=@WbSbF8SYXWOT}i<-
> DNmslR<g$
> z9gn?|S;@rjd!)L;QWU?9p#^YkU*T{z#b)4zM^0Cuv)(Vg-
> |_8U)Ho0cZ_B@)IU{!;
> z3&(a;*a?>9I8cmvy*d>qWU^?u;t$t+l^XaWLCqHcPzd-H-5!eKrttVxQtjcNjLt>Z
> z14^xEd-
> ETYb>Y%|EF`w4Pt^*OYw_QEmc8ubZIzDCw4JqtnK<qq;E2%@e5CgH-;LAw
> zp2hpW()$j_YKi~<W}If}Nh7tnJpP;XP$ET-
> P$&`e^v%aLX$&x5%M>N?!s9iT;;+VF
> z(-FHk;Z4SDsI|X(7huVxdN40n(bBLi7jjfG^S`3k<d~l%VHxl$r>8*d91r*2Om9(R
> zS@4JZ8SFF)ZBV<@9c0`E#raiH()O}=KT5M(8BNVN?vLOj@V`0k_k}!hoF75g)w
> mwU
> zuPE8CWY=|;c^Fp`<@Ne0`tf=&M^k2se#!*Bb-
> 8k$o}QB@Pc8=*YwYzw`l+NMY17&{
> zsIQ(>AYJY4gMy|4hq5;Msd|V-BH|<B<Krt<tdN$RJR&){B79$25&kORcb1m-
> xui8K
> zkf59;X|Ep74RALB+lq#+lh8Uj{?PhxJhTP#b)4y02HtLoq<sg&mn>hV`7oI$!zz^R
> z91a7n%ulB=e;;LJGTo5yHGXr4{=;a=@J>wveAD0vWyI1-x8q8h?-
> Y=U^pzyz8*js+
> z&1~GU!@IQj6}YqufH&X!L2cvxcR!eU;7O_nxIzK&zKk#2#6!FG(#jO~gjf#ji(&jy
> zli72|Iag6Rv2ht=;i||OyD(2EEBqCv{5@_l4P$<|ABNxB3<C~u?gV{<mL6w<()TIs
> zwyV+2&XB{P^ti&toet?t*mw`AaJtDLFDXUK)`2_JC;=t#p@MxmC*Y%G+pA^z
> tnQ0>
> z#vUH0)JExI`FF!5+P@`<u`l?g(W{tzC8fmT{wm{3N(slN6p)_j$bofUvhrkk;K+{m
> z8~!fe^gBafJ0u;x$V>F%AClU4!W&I^uL5^ran!?hiu)z_KYnL~w^8u^9$N`U(w2
> +w
> zL$*T1p25N<Lwmyc6Y_>@OVc~TrfHYFTuf7EQo(&eRvO&l{PaCO<cF;@)Mh(D
> ?YJ-A
> zM2X>J6+59%qN^sUZ{j=yZx6866bt=HLr)ycLmAJ0F+Uu$*zEz+b04W@OS;`)x;
> Pf%
> z7@PpSG8q-Kz2mpG@yZ1D0YBdFlv*La9os-
> {v;90gpTjSGa8#DT{z4$^%6h_BC5^Q>
> zt4f4F<fEj^XPP!En<Za`_cM#S^=Dod9N}>-g>yx$Yy6H-2`!;5$N*;n#yNsi#t~3P
> z(;MgPeTrHp%;#i<HCvSIIANKi)F&+YGtQv!JiwfH<8667abb7pM}QpIuVnd^Qpc
> TJ
> z-
> Zo2gyvMh#v?nUbg7v#_sIO$GQyjOHkheGduZ3BM@jgl@v;f@Q#CwD64j~(T(
> TAO#
> zL_-=HXcLK$it)BF>QIqx8~@vRv9ng>0B^Ra;eQp>8QuqzzIZ6v`m)SNlBv<(Jol3B
> z@0R(P=Z~!j>jQh=zfo?MKFgE6H*kE#Q)9~+7UbW3P)y9AR5)8qN=O+Lt<i=@
> CBzI$
> zQ6|KOr#W{)k3lJ#=s___pp0RJTAEYfIc5sfUL^F&e?y;?dHSp*Yz}}WVc&q_H&1
> w;
> zz)s&x-{m+0Nc(ce{Sq7_@B|&-
> hD=k8>HCrSNE(y=eta8PaY_3>ruiH99g35GGPH*@
> z`bLuY|5SWzLCCjsOH0auxh1_kY#z^UEw%&MB^M)o_C@DkrO!eYoqjmf4vt(
> *t~g^u
> zAH3Iqr#+_9#`^g9ej^LX<bomDKBEoqH-
> jKe)Xs&PlGtf6uGCVf5Bqi+SG!Du*C6o6
> z*#+utN&^jLT}(n@3X;wx)b+)3W#z-
> x$66QeZFi&6!}*bUD6Dh*m27`D&qL}5#q6`u
> zpgjVVLa;u|=G4JSNjSMFaX#_XfQ_gUkL->r-
> oInF$Q<a71g;|4y3vyENa@CRk|mwR
> zNBXDYqb4@?E7^L$Hz)2s;QQ4MMsGG2Vd+pe1-
> 5g1JL7nSw~TO%Vs}>2je9NF@{o$}
> zcp1nl7GmMLHqvYjg0n;>Eotpu)LPnfM0bSL3Xkd7+i;}AIW?w<oc}xTS<8G_?M
> wNy
> zw+_}>VIB*QZ_+I>?B$HgMmN+Tg7Rf2emH-
> }o33meFsES6<2sR@_~YIx>efIR;E0bk
> z#qLPq$Yi`p#r9ZOkN<D(*)yeHc(#Nm^=gncrqu@i9}f9oyOHiGW67j_5xkEO0P
> 8+1
> z54)!z?J6;UEQ@IhsL#)|v>%IQynkd`u96;?Ow(p{j_ux9ONDE^aDBG}DJfz8AdT?
> m
> z?`HO{miC5Fa_t}o9LY_?vvm!&arT~MG!?CBHZL*W0x+(yFcywi@lapV$>6`UZZ
> OTm
> z*f($nFU?!9p7B?*;}xqPDGzB(#(eNiEBQ;i#HdRm9QN!yVOKMhwn*u2QqdvZ
> =pG+_
> z_1?c2q5J-gl*8b?Tzo#l;5KU)lkluwS=n)nmAL=kms?tYvmKSfyd}eKsdS6Xe5}Nn
> z_)cIk+5KEBPsz3y(;TFBYU*eC1<k*izj<DE&_i)dHUCLEcXPS^UP-
> U7%sd$AoP~d&
> zzgG|8vH@rF@I-(3sqb)rClPL|s{zdFpZ98SQ}x<X9FNyVs!4Pbyt!3s0-6NrF%_uN
> zO2WIE(MlC%2sDe)K?anSIpEAA5+fkSNbpNeg3&Dvb{&)AC><~zcW_@4M>`z
> PP`@X>
> zFQs3})GO0;fvXuwe=X*R`$3W>TXeJBS$!Av-
> 5N@s?R?1inhW*rn6I>OW{z5h3y=7$
> zMA8WB3uzf|iQ`y|vwn%nZf4-
> v6ayUNJ6j7h77FK#0)ROMPmY<+4x9~0dSy|XILBgd
> z8|0v5<SDHUu;-
> fQU>sQszu(x|5!1oUsQ4B$_hoM%^ha&Y$T{v!r@$N&XPoMSwFZ+h
> z+y7#FDJ4^`!tDg#rMSYzc7nVhS5hglowD;N<}c~3koMDYtu6gZhCfN}rumuXCU
> J)E
> zHPiVAwjFkt7T;@q>HEzC-df%Ocs7M^I=qt`Kxbj>oo75T^;T-
> b;L3Sm)KIu{ZE`N@
> z3Wf8B3+<6{O1GpmR}vQD87$qBW;Lt^sYxq#=>O0&*p3|T#o_vteb?;(9AG;z|
> DKk8
> zPyg@84|_89DTxOrw_>g%aep1Z5@!oZiNXIzu?$+4`5%s2?9bf4XqOMM`sCjv
> Quxn2
> z#&}}<D@BU;XPUwUV*D#jiuWhQm;FCl>!!snT(9x}*Davb_=3Mu#r#P%h<HL
> N<6r4g
> z#ru=u7cTwZ_4%tFfH_&ipOhoIjL%l2m<8s+EW;PCw8l_Y#Q4mfN|nOapdUYB;
> -tw_
> zzL+{~`iz;gW`CJ6XYRcDUoBX;Xz`Mz%a*TLnYn89*K5{(^X<Cz-+jN~hmAjO+PvjI
> zTYuWNeaFsSKO1&uiP?Mh?%V&%frE#BJ$&TovEwIlPM$h_=Ipui7cO4<?edkY
> *RJ2V
> zdF%F_yZ7!t`2CNEe?EGg`{Zffv*#~fzIy%U?Ys9M^8c}djE^h8D3*eZ|8@EQ*ZK
> cr
> z`Tv!Il8@7=f|CDr`Ac?wC(TbJeM-
> i8o%tM!eX%Nq!aW?^$<xr&&yUZj{>D6qYxODV
> zb%RtsHSn8QFrO}5Ha7Rh6)=YT)GYCDlu4~iG)~?AoqEHa7IiVo#ln?Pxe}B3d8Cg
> |
> z_r%2RDRdDX1HTS3fB4DpAsv3i-
> @ju_Oh<TtUywh1+W`P7%|JoF5|{G?G@KPYgTk{U
> z^akB$a0iJ6099zZ6j<7TRy3LhC`hB9hk?2@x)A`H)1vWA0F<a{bYRo~)BHSAO&?
> Kp
> z8l+DkT}+ceT9^)int-k~0%-
> u&U|fttKqH$@69WWHPXphA!V~Cf)1+`eP~E0hatCN~
> zqfemJjZ#6s8^e)WjEnIIgeMS=Ko|mazA`qhQg989>(4f@R>9p<X|EdhrI|GuTu
> b2-
> zo*QCFT>s*FW(2IrQ48Eah=m%v*{|?A_@Aba8cd_$Ph*x-
> IKK(Ocre}*DcSbTN`tm)
> zn4ajrwQd4?2eAd?Ny*8D^&z|~Wh(i9BmJTzFUj4=g;Dm{0zSrv)VltvP2oLsN!q
> xB
> z%e2dsOuBe_!0yo)Q!WX9Q%XEtyeFFsz_d4D-
> }+~K8q;Ii_5W#l#@aV+ga5q#jp-KE
> z_WpVLg~zOaCRZuFqPdm&iWWvltO2}#D4oN4(c9x8u>Zt<MeV=(!;Yyt+>b`P
> N=#Fb
> z@rz*@q{Yq$anxqte-
> w4r%*tmR!Hg%IcxRlAYV547@D46&9Wvc*vkW2WHN|l3Zke>7
> zD}}_pTj}g01oG2BdQz@T5*U~9h;yXEca)^~7|sTE@62!im~)3a#5fDYT`m>uVd7
> r3
> zjJ~ssd|)~f2dv!qF2nP<aCn#Di9Bl2U^<~uTS_<BWoEIZn+L^9f!&68rZ+~qL5e7a
> z;>BcIw@u6asd(55qB+OK=TnNsxa<t2#QdZ@u|;B@pUM~S$>MCm$Zc`tBgOj
> f^G)Zo
> zj=!6;F&@ji6Pz5PRXVBEe^p-m1_aj{e>Y!aJeIE`wV@~FS{ymE84k-
> A?^0k~Nz?ep
> z+j3%ooTTzfaan)-tMamu`0tihipBDDfc|5YFrK-
> aejg<DLTUW_bbFIV+P}+@F&^Wo
> ziy22K|H7lnKO1+kU$A>VpBj5hB3~T+@RSyB7O~#Q&KsDXI{Y5cA5J;^foeL!8s7
> ks
> z9pR0U*fBW~sz3*u{K^>H6fj7p#Dx@h4+FhQF-
> Z^rbsoWLBu3T>^Z`Xh#w9_R6foQt
> zZ#xVurokO2`WzXn0SjYTqtq=kp~*~W2}!Au!{B@b6wzptY#|Dq-
> Dqs1<H6t(#!c41
> z2iN>r4Idw=l_P9NDkBpj)iER<G%i7wpzVpka{~2?0|vCRD2+-
> B*2KVHsg9%m(Ib^~
> zT_z<ag#e2<luca<oVr0_b-
> +u?2o+sGri@U=s8Zr>;S(B~23&hpqdQfpR*uvu6Ocj4
> zPp5%}AuP}&H!F{fmZ!i^snJ0cV;K05oJKP910y|<uoOoPGNhqQ!oV4{QUisP!X$
> z*
> zF3^%x;0C#X6}U*c2A0A=KCp%bxtXM+Opv8SCZtBjz)7|gP8qE;b3=tgWup!zjW
> SsW
> zR_x%~ffN>wxV4d3L=%3alM<2=qg0rUF<d+-7BF!~B_*g*A&8U?TucO`R;-
> dytrkcU
> z%)r`$QNWR^1Qk11S0`ykDC59kt4@dK6sRU*^ovRw24%xM3;f_2+5kqkmFiQa
> !P>(X
> z0T}3UVAsopEV&bOX|UP{Q-Rp7co-
> ;myjBTj>y*%{xF6`Gf}Q~E#cGu5==g$cB)3^Q
> zJPZgjGR7oMlrjMe#o8%yhwYGa2+t<|P+-Zwp#PyhF5dqn8tZGu{w4Wi-
> ;th&LJPx6
> zliZ+Bs^A$~n<^?wNrf)av297uz_4m0RHozxAsC-
> oU!wONVsu&%NkQ=l_B*Uptp>`E
> zy4#?-BtJCw7zq`RZN%u8n4F-
> BRiSn_$q)NG@9vTxVt{y3AXrF4%9U0SZ31u)gY#xm
> z{RMt9UKog4;D^tn%lQ(|fG`rzaVW<=6uS}y-
> ~c~2;zZr<#2)YfA0N_zVqek%u)9wP
> zvEu&k$};zTzyo}I$r<VnCHnzmI-
> 3AverqUpCG#ovBU34MCt8Z#NIb>9q#wnf6F-Uv
> z5GRU5NPUV!NmYuy386TQJS)S}zYW+c*o~Z_*qvlk>_;|H96~Yydw9B%nH0N
> |G>ZL5
> zJjEfTA7IY_U*ZGUH#CIE0S5#IlQtY%Qyf6vmG&h;p>E_pV9$^ca)Dwua)@F-
> vX$aM
> zl1Z^UnMAP%(NgS1A}9tO<P>`oXNrAD8;bo&eToA}S&Dthvr?FkE4fbb0Fpy-
> FfmXZ
> zMmA8~pDd!d519%$q>mTT1NQI?A*0bhz?-
> B|97ePpCjbtEbYlQ}y9JX$fZcuI%T~k#
> zfIsdp=hz8wfS(6x1K6jRH)(|K0e+-D$5jDie8TZFSjz+j`;v!%L;Cb0mjMrO^&&Zd
> zdx2cDxqB;jX95ll4W#@cKN;XgtOtyIBL9f1R&7|df>oEYRV&(-EmO9tl~u*Y6$1*!
> z(SU++l+6fC_W|*{yFi#vpw2{Gso}ba>C(WPD4*8VS=_idckKuutrI2v&&A8xTyLi
> h
> z34r;JhTb5>8$-yYE%>DaM*kG}YM6bIVf>acyx>l*WGM!}CN-
> Tk;TV9wlHEsSxA%tg
> zoTSr@K=&Y6AHse#VCmZ^oH;U`70B1W{T&|rPRW=j;|zCv&2J%s-
> C&rz<DD$&TWvO*
> zmfW~5?@OhQ7B}!``mJe*MJ(tU^cIfvg?LeAmv%}}lRT4$bX!%@123(DisnHI&F
> +Xv
> z_gRf;nV0Xc(voal;2MT;gEC{%`@g6s%RE^<eXKMne^aSg-
> n%oe%c9F<ls~hfV%Z{!
> zl9**a=CYU4VfU;)Rg0$SNVl?Z)r!{tEH!(uT_lMX4Yh-J+SnSbC=2a)e-Fnvlqmj6
> zwx64(&g#fmb7|0@OFBPe>XJ<f_rL((fEJ(+Juo0JEVKp4jE(f{TM*+HmnB<n%R
> E@w
> z3+IjXBz+rc{sm~s@?)6?<ENNsrl2q_Rilk&_uZmk$qROp!TvN(U<t`M>_yN|nH
> CKv
> zgw%_W=Ds95%Zp^U27RBP#6TMv3#!7PtZ?Bs3hF#OT@3)Y{?hGnod7q2p&h`
> 24iE{C
> zPfx~gvcjVyqj2O*h~aeRBq_r+^in0>HO8BtfN&XucatfGc{IgM%Tz>fkT1KziEnV
> z
> z`^D^rTG2Ya*moGXYl?S*@r)05bMgI&y&Uz$+rt-
> gxDRR%_wyOXzRmK(y+qVeQaE3v
> zmrT7DzNd=3vir;`*imC&^P%N8{BtH<3(lgM?iCD;mOI!NBo6TPkTh=mTm0b&6
> b;hU
> z!S0NbeqC6Y2h+Rl;bz}-
> TaLDbI5h7a;0n{n!t*xV1!5ZS*_~mmKS$VkYY%|WHh`Ox
> z-tf+K1(3c`b!hGz;05*b-=>G}a4()3rsaW^4ZnYqo<~7?A+)UjB)t%e^0t6^GJd~l
> zZa4McYoEq@)M+$dwpVAoOU>kjEiw(}q$S0NbYI$-
> `f%P8q_Nn1)ctqzmGWStE{;iz
> zAITr<H995ndMSM1zcPSj<>obz+<F{Sn|qT(fP-
> 3k)3G&7JxrZ6LTxtoUIx0X4WqYd
> z;Y)J(vlgE9ZJ9r&Su*`xk}vy`8GAN+?@HRYN-Cei<DC*t00+SchBwHi(?pc7lyfq)
> zclHGluG?@#PlM2f#}Ui^iM#IRmPnWt66vlw(^G}5msu#m`}9no4%0b-
> ?{oaJ8_(4v
> z>3G9V`rGp_G%eFkhWI!O2?HKufM<3t%HAb~^Xv{<HqhQQ3uUUgtf+EGX@
> ^oNnd^1`
> zZ@DTyPfSwmyI-
> s!_RW&aJqb3olv<^XeNG_r!>L4)rZu*A_XJQ<FY{3;HF$$4UFM-o
> ziPor+Ihn}ZB0&Q_3*@TNM5aR|Q$J&H8SH<<iB2e(a<fPzf|`Mn;l92qTBePMt
> @0Qd
> zYz%8+T9XLa359PNVq~dQx4bMmDLEbfgB?$e4wcQz;7CBjnT_CKQlpTkPlW^>
> dBsUD
> zCLK1tfhE|YPE%>Y!azZ;v5+&0heSwW@CyVLZ0e0vYGj-
> mp^TT<{!5lj!hVu*OL>^^
> zWFiURtB~A^6d8#~PKbnCX0Xo<#lto*aIh>I6!C)z16Dpux(PKRDN(Hg8wd#rDX
> KWE
> zcPRyIH*g>_a4_(}>NYi28yN*!d`)YvARF^AQ0Kv+p}r_vPahJYi_yXsKU_FN^BF)
> Z
> zB%Oj}h=~j(c^6q|lW;|f&xCHuuep3vRd65>nIMCc7^8?1Ba=Z6Qrr3z6H=HW8
> Njj^
> zw9g`oKq68=?vWZMa*&Kk<K*p985^lf&=xImWBRnpii*#eH?oK2!gB?z1mw@
> G&+^WS
> z{%EQ(DVBvv#kK);mKsHCA3Y;@OTgzLVCZW!Kq~;byeDyS=}B6`b4LJMfc60G0
> 7j37
> zFs%S%9DuO^ZD2U=02rdcy9D9`mIH1H&=J7ar5&sbAPsy*fdATqqaCFYl9bGb4
> R8`{
> zr_CUKPk?6NmP0}=kSK4@v@K(}@NgX*52)hQu=yVz4rW6@9B^e4o|CnjE>3`
> >6Es+4
> z8a6gEMavxF;o5i=))x@M!&9^|1!0mS(VL|WwjQHlH!U0oub4LI7t`363<3xO@B
> nZI
> z=l~!Cs1HyTfB;mf;zK;@`;s;Q)&S4y`H~9&uNwK1T!8pZKI9?b`vA8At^-^KxBzez
> z;1IxmfNTH*zz%?|0Gj|d0IUO81CR-
> @3}6w!e1HsqnE+D(CIRRHMgyb)XaSM|5&+@>
> zVgMol1_AT~2n7fN@BnZIum@-
> XP!)gxJp2rJ1K0pC6CeS=51<V|Re<{qfp36JfJp#a
> zfMkGpfPMf@0385i09F9c8o;>*zy^Rx0D}PR0jvRXL1sq*G6A#z{Qyv=?tPd>_3
> qsX
> zp=}rH1Wp9;VAd9!Ikqb}yoBzrRoW)QacClppBh`z8UjZ|s*}{|iAlN?8N5T3aHJSb
> z2h<4gW|0fW#5#{C!aFrdMc3g0Va$Rltlr_ARc7OEBO?Q~@jCUe!N4J&RpU7*;
> ~A{f
> zXyJ{ii~%QH0Zs)LDM1>xFg$<Z8uOH1!C>7bQkF=s7MqMKGE`uvgjqoWk41$y9
> WkW{
> zkeB&*VH{Qp62&l)F+<_(GD$NEo>Kwi*lPN$OamA6OMo#T<1ww_<_0)WKIo
> U41U12q
> zbV&!fG9f{goT5r`Asy`O?0`&6ya-
> M+l19LM#3T}B9m2ue47#`s?iWZ;goFk33JB~Q
> z0R3}B7bh9$Y({nK;jpI=u2O3q9Gx+J`b@_G@aqKYcS`HRFocK#{Z$w)CJ8DE4i%
> |o
> zCUC<y+i)A2xseXBNlH8%IKwk$gMLc5AumIB5>S<zSZGe@1a~x@pwVak#AYe
> TKkWTL
> zs0e5wY*7-Oq64`>3g8Rn#5~{$^FR+;et3{XLj4j{-
> Mc5N)HuZ9_!^DwNSx@&N!x*h
> zjEV)BkAbux@F<-
> 3K$zrTy$c|BuQ##U=S}PZasjONdy^ml*)QHC0w4oGcEFn`03rZn
> zf`CbojDz0fI)MElZ?J~--~SZrVZ8<Gtg4ViaEM39t6S=srDJmZR)##x%1h|9xg7Yz
> zo|}JqC{-
> ?ovswP6QV;5@Qg?D3<mK*ZmmGteWG27MKf~Ao>pJOI8Xj7J+aAD=`(v0=
> zJU~AD@KFJP@!kPV`kB(=d0eDn+%%K)r0|GicEcEK5q1r@H*i0sOFz@}P2(UP`
> 7q5B
> z{qztw*CcH$8$lTYNM*w?MU~Ao9!6UR;p7lc`e9mr;O=LV7KSM*Ez@`y-
> vHsJnxuv6
> z@kQWXXOSL;qdWuMwCtvFF}=*4rAd&k46)i%j@UmgN0M{Pk*OytkR1T`0q
> W;eAPRtZ
> zfE57vvoGaVB0v*^{~{p0k^oHa18-
> x8IF{T?Yq`<vBzKMleR+dV(@WWYnqIS`Io&e<
> zfllW1Y>WJTyPDI_SkM=A`!wCL`={xL{(>IU!#w^`i~N&4&FPl>HS+#6eUh&^eZ
> NKe
> zEB(#smhy4zZBE~65&vl)bNV_9`tHHzbj$ib9cxZEt-
> k@o+~Dq+IenQ$`U@wU(@o{q
> zca|IZ0>HF=8cgEH%yuI~0X{}go#RGE1DMh+<(IS7oNmfL#@lW%r(4EP-
> fK>`tlz!+
> z&FPl%t9Hzse!--CnEz%Ax~Y7SzTk{`e9Qd5IcrY0Y#+Ky=5)*S&;4djx8(oB<xkUP
> z*Uagb=`X!uPPa_|_q*nFOZjgs>yBb57{5&02l~HiXim3m|0`tXbW8sHo14=&S=
> 7(F
> zmgaOz`QLUmr(34K--FSS*M;ybjkA{Z1TzT?Qb4yXXOqv(>6YzyS-(%yn-
> 2Ok{Y#ZO
> z-LjsRYd=k2kY-
> M|<nNnN=5$LrCeJd;=77nwr96EyjNyJVdA5{i>BZ*xS+=WQOWg@n
> zb-
> w<DH?e_zdz@oz?O>dX(8}QdAx)|`OS#1DVfkRt9`G!Mi!o_O*TDY{4=2$#n9wo
> q
> z`3~#^N}^ll)25?2-EtgJj{7wIt_9t)pJ*nU$G5B>GR2&3$)D>obGl{yXRYv{^4?@3
> z?-
> q7{U*3y0n&)FFhufPzO<%p)qo9teZ81JumS@6GM%qr3XUle^*unC{I_$9B_*{
> +q
> zOZ90P@A@$o_BL+^Q-5S@04e;n-
> ;HVM9(WKb+~{%U;p#mzhMWGx$ny@9_O<i12RRLZ
> zKPi37`mI&d(~NFee;aF?(=Gd(b3Jpqr98iCU{1Hpe^o<sx~06V<>qut{>CU69Sh
> M?
> z@GK~&WjYf*&C{{ubF-H@-IC84-
> XEvG_VpzB0Qf6P&Od(cNqzz_rJLs8D#()v0H$=y
> za_WN3>6Ya?pfsmj@~_!yPPa^d&o*<qWj)`&^=W$d2j+Cs@?p99=7Eghcim(h
> =-~L*
> z<ACLRVEh^{nvPYDas1YPA|1>-
> 6YjX+Zxe(o4cGwq0*{01ar_}~h;dIKmxq_u<EAu4
> zD{l-
> |P|ue2@P04L>lolm08)F%<mpT9`@gVo5B7VJ7XXsKsoeVf>O}?tnC53nSHhj1
> zVF0Fd({Zu(5iimN;A8Y2C%uRdz{lt!(2jnBE<XiUeE~ie{}9m50w`z*_Fwfgtp3m?
> z$yFlb`xc>vlP`TYV_iAHGx~V|HvOR={)&>@h}&M|TL4Ty!la!nvq*!b!19#RvFta8
> z+nLw5sr)g14_kA(WqZA1XHK__|EQxm-
> LgI1aWJP_#$V%TPEWIFXA?Sonx5z6P34qf
> zBB%YG&1G#Wr}|wgNlx;O0MFMe6u3<va=KO`mjNCEd;qX^u0&b@I0Co<1O
> vnZqykI=
> zSOTyG;4r{tfENIjyHz5M0NMd40Qvw#0cZgx0W1R80B{K4F2D<b^4%+uS^%v8
> >;Sv~
> zh5#f0Oahn>uo_?^Ko&p_z)gTh0OfmBB6R`m0K5P~0U`j@0FwY_1FQhp0+0=
> G4&Xk(
> z8-
> VKaN~8^dGe7`9Jb)fx3BXo>y#P4?mjQkUDBBa_05k+>1>g+e0ni5^7C;Ly9Uv26
> z1HdkT!vL26asleQR3aS!<N(0{@c?51G5}TsYy~(Da1|gIpfuD~EdUz;Cjc*iegN?R
> zV*%y^;IBa`FO@omnq4P$^f>^I7SP(ND``yKUMfur_aM(pfzCnyq!?X-
> 5`zT5sRkI!
> zn_0FmeAA|MhZFgv1n@YIp^%Q}{G>-|aD`}NeBiS<-
> 0{APR6jTv^VDciP3dJCT9=Rz
> z6se8J6kQ3~g?=7zWI>Z~CE1_{1rMefU%yJ}yK3R|ElLMp0z#aNV22)d#od7w_<
> $$@
> z49c==kB>|HDI-&rh5VB+6}a^PhvYG6lh&04QckH+r%)B}kwVJ=Pvm52-
> xLpJlr9cF
> zuL^=gKR7BU1Ih$Ps#27m#tW8PflCPE26q?Wi>Q%h`>JA;?y#>On&c0suqwB7t
> &%h>
> zQ}7&`Bn2Qpl}&&R`vj#L${|B8f;36dt}!u?6<oG_Qra&m5_p7<&NS%|!nSNEd>s
> bg
> zq-m8Hj)qxJOQX}k=Uy~2db*SiQ-
> eKSka|o3mrx`S5+QZUhJg0SkCE4xMtgUC;Gh$Z
> zfuPRdtC$qG|F6Akfsd*>^B0MfX0@WVwLaEf&@7-
> #NJ8Wd$uOBAqj`}@0C{YjWF};E
> zG7~bHBv4fFwYEN56_s|?3Po^PYpbiZ4_2*JtNTNx)m{BjwX|Z_*4AQmTdj}m|
> 9>9$
> zF`3DWNFP5hd^vaSJ?A^$`ObIF`ObH~b8a|N52uW}E~IW7%UiO?Fy3X(QYK^-
> Ln0>T
> zh2l}1BJ=POLDmV@i7$vof{B(+;bnjk+4&qt&*<lQWBhQk(1qGL7BniU@_{`Pe
> W&rZ
> zlOM><X9)RK0(Om*MnT-
> AvW|sZ`sxhhM#pcE4C;T*JQ%l5E~*&D^<(S1;*E(OGz;TF
> zC3l&^^ABSJSRRXeJ32_O*VyUceg(Fy(JO^D^|&a3tQF_;(!7Rv3Ty+1app}4e|h
> P=
> zYZzzo9wf;(-*n(@5I!-%h+)iNoIqzZYW$Y?9c}5Ze(|w-
> VE7=Ay6x<8#87+&%GZcT
> z^3Rt{L%5AOveky+;LyRNMZLx!nbKL$C||=^@lC`!EJh`{U$F(90Fpz%TA98f)^dT
> u
> z_qLsy+*a-
> U>@h5cKY<m=WP%PTA>mzs=KK)j_kUrWlOx44<A>Q(Kt664(p<r{`s6y}
> z>*AN>iD7INzXUUlWqC`bLx=czfh<9LbVV`|b)2q>H6-
> T5%`nEN8K>4?&HI&n>Z@Z+
> z<7a3uqV@P7WOeXeGHw<5$VxtqsTA|s&J1If&RMV%t0SV6s>K^~$JVC1I?`R
> Dcaa<d
> z@8|V@in8ty`Gmwi$nE03J}Pr<(0M3Hd!Kdg=$HS~*(T9nw1pF(`+hvtPE8rDz?+
> DK
> zuqr4k*gGZ=Pp8^gw~NxPt@r}9VO-)G7re$-
> 1&8D)AxlKQJtpc6%}DS{_h*s3W#L#?
> zAlVs$w@ExIozjfWN|qJ#z=e8)j%(r0sKu8?_Y?4BFH7o>rKQ+MN>3!O@sxZMs
> cjYA
> zg|UD&BQbI80{(LM6JYzr5mmnGaEF!OE6(3|-^LUiKR|qY7@dQ0H%nN-
> Ca9mh#wS(q
> zu!{@HLY$Yh#K@<{I~dK<?ec3V@)5_lcH-
> ulzZKH6r^*+^bpJPQY@p#Be|?R=3TOUC
> zgd>VmQ9H!@#pzgti=!Ywc)KN0|B2Q@+yilW(5R1g$5L2wF6`>%(zUUuwH;zy8
> 10Rk
> zo^ErYSpd0Mh36PV450uNnjA{76d#3)mrQH6LW;~}t0@zk@@w~n`NUU{5-6-
> t;b=he
> zwb+@>A)lW<C%P6nwwrN&a6XcZrV^98;H`kYyk<B1U9)+e=??^(mU`<$4Yl?D
> reL7n
> z#OihCvnD){ncFmH%TMG}5Fz2xJ#sWMb(AmN!NC|_kb-
> #R;;Z!g&RJBu+$`!X=rv>f
> z<~!cSA|!U8bTy6D{`#OVTe58FYHR#WwE>lFmaMX+!Is+!f4#q=sVW$1P)Uazu
> b`-;
> z*95QKC9=vCR3E!<T%xKaVDMZa>BW5p&LT>~i&}m?vcF%k;!8gq4t}*Hp+&X
> OYfk8f
> zWb9<D|C^HkYfVqgoF7ZHMi!c$q&XkwN$_?)sKH<K-
> %<wIec(3+fpm1?WGOyQIve3l
> zAG3U+`_n0zZWyYruqRj6HP~V}dCT9t4hQ{*D<7+Gm}|0~DQ1gKK{sRg;-
> <RH$pxv&
> zTGmxuj4P}T`dhK$=q@FgFZiS4$ky3E5-Qoqr@|VaQa{ziyr;bf0}DK(6Roi|IJ81^
> zE`A&lknAipr&tjSQd7;P81UHj6hsQ~A6-;oe!h|4$RpV2n(VlI@LBGRt!ab*bIVk-
> zq^P*agFmIyOo0Y@bmEW!kwc-00U9S)AZ`j>B0Br-
> D4MkB{dmS=6bCCL<2V<9Ls-gO
> zmrUaU-
> D5jr(e9`TeczO0w^<nsLWrHjPr*Q#?wD!{=Pq=U`G!@>3Ut2kCnA?YykX*M
> zZHbDG+gu3+GQuae=$k9&*TL(DYF{v7QutS!D<?0UY|dBQUA<bA+l@yyAr~G
> `%1YvF
> zPb)nhObT$|<pz%ju2|@_R|^ghpM9<LtTE>Yx~WZaU|NVwS9-#X$v8Is-
> SF3IU6(6g
> zQtFQ1zo|QE8?dd*VrSr6NiVq7<_1t#CK<!R)QXLHskyvo{+i3Y7ni>mM^d0C;%L
> Uo
> z6xG(+nQRwN9POe|@S5$D=`@!G4*qErBZnIeWQJ&U|HXPI7Dm_H;=Q;a-
> DDr*x5&wi
> zNry*PzFWYu(Xm!zanUg_9uCdA`{l4I`%fE@<4#vqG7(>ArqUfeq$MR1qdB%i{k
> GGx
> z5*#T_vqJc7%YuoQ=+=dbMg>Ol0ut}Og6+%!%?#Un&<D|NI#3}s7Fi*Z2TY_Y$
> WG73
> zD|#jj-eE_2-
> P5Qx*o>)t=Q@cqmVn}Kv(*rIGg_YLCD8=g;dMsWrZEAHPzh?M)xl%c
> z6qzBriVkVQ01cu|X}PfpRd<ejEal1)zopQYL~miH;jC=pR3Gv}(LONVSUdVf6SIER
> z;RU-
> uEBf<962~J&B|cPys}_}PLWOi+^*9Gf4A+!S48~v=3mH~ASW5AZiL|U+2;B9N
> z*%dmgK_YhI(u0Ub=EkMF-
> Ka%|;)tL_=n6U^LN7dEdrj#3IL8+oM_>uS=}v3|kTT(C
> zNuAP;qRXV~EmP|-
> YoYKWg;P(MW=f4>8iqun{Y|5)tF;PSzyy6#Yq1IRnmh&vI=M~5
> zG&9yJJCF>O2QsK~5+$~gIPS8OP}|8`%gl%!4A0A=Z~>zOi+#(gmwZZL;+vC$U2
> WKY
> z1S8v;t~SL`*~V=|>Q2@~YQQo&^jmU|DV-
> ycz{D|0@RBVPRs=KE5pBW2K`o{nv#`Ml
> zUdzzg)2f%sQNAF0G}$o`QLnl@3^V@dce2w{;{nuE_a%)VqWZ8!hy7O%K20w
> BcQNfx
> zneAcpoT^+HqTQG31Er8#63*%|7|~Pajy`ZdE0W1{YRI=z2U`W#AgJw}wLzp=)2
> V0|
> zyWJFipgyUg$uWQ%;8RIOvxP(7Wa$ib`E(R36g@kqQ)bOlv))@h4c#hr5oX^Gk}
> %R_
> z?_Mpo8^onG7YpwQ%cJ>f;n6peP6wG%QyL1HL;>Z=eT9U0%JDF;)Rf&cI#W4
> mChs%2
> z7*QLHa<n5=Q-vl9j=gh`-
> FBQ_hq{|4Dl#WBB}Z=J@T(^V%@_kjECH>UQ{h+w)GgAa
> zlKV{K3G=VxvdaY$g!YVNEp5ppwg?J|!U1h@biJbYXpVOEM58bv^yHMKNQ@
> RPm@5Tm
> zIF`xQ=@1!|xoa{TJ!GXj9E*zq8T8TWOofls!E%MO;T?45*7s<dP~#C5e5K)mrzi+
> Z
> zKoJo*9oXb8j29q48ocaoUc{|->j$RLBXpIDUI{xtI--dP%OSFHC<G)!S)nii5c%h%
> z0b4y<uuvnl5|V4_4u!~5*NLcIp%lnk$z3Mr$ZUzHCfw>C&^a`x$$1`b&Ke?>{rJ
> NN
> zc71APDJAAn)R=G=iE!|Nh=3h(L!FgJZW=Ao49l)R5C~B|nSgpec_nL6hieU~cdN
> Pl
> zT+<9CLASN1C}p-
> `84KbM*~I2dD1~+LsNCc#>=m+dHSQtU1H^R0n$b;`={>OHX}U<`
> z5b!8rv@n_3r*xBrkhsdo+NYf^yS+tCL$c!Kv|rJ=)*#Iu9P}xGc1T=9rh7#899!NG
> zM?O~hU_14!vE)PBupAOXAxE#C6cbC1QLaf8srG~cYMdpX^ccl^PJzU;GK+t;j#
> -tM
> zpH7#xJzZ9g`n6V0v;=;n)p&GWYnjw?B}3F3>x^~Ba*-
> ~SEf;Nq&vRidLB9l@$x&u$
> z3d&Yil?Ddp2){Ui?t0K<6e}q^Xn#<1I=M%5@MKaRs-Yxc-
> iD4s9mC_WTp#Xt0gO55
> zZ#mAPm*^C|x9;4eg&5!Mu;K`UqZp>KnV9?j#3T<Ee$GMIUng5z(dDuKLW70
> EMWri|
> zv@Gr%_gdoVh~2^4Sy2j!B2Xdr-`VL4A|pxfw4sJ@mP032f909;V*4G=da-
> T6JnfBV
> zU-
> aUP2NOGk7vL|y#LKH79v6M^bQ4y;bNuI;75;#?v8tgdSRwXN=6tTA*Hw8N0=4
> zk
> zR{Wtp$J~z@OwWw3o|^@|20`^Jjl#+&CbUwjqO{r<m9Fna)xhsT3~QYFr^Lc3
> R8BMC
> z4OTVQ`%zaKSHX;8v@rgbH`=yrf(gCixeWDeP{x&XX!~<!T<6@<8DG(D+OmZ<
> r_?N|
> zQe;d_Ayk@9opzu`E~nioxu{bRan*MP>beytTF7siV!tu$>-
> ;{EK4Y&AXI=3851taz
> ziRX3<n^&XB_x${oA?Q6Fm~?UpsvxpjTjFYxFcS;AUw(d8jYK^}bv8=dT@~%!_?
> hcs
> z9V{_Th=y1?G4zeIo=n8ib<BGy2c}+Q;3K`qRov&V)VVJeOHKh;9_QkXUZ0`(Frw
> Lz
> z<l}zNv8CR~2NUX}DQKFh)pNlDN1M0R895+CV7_aiH%lv=fy4}}D+wnHsh8x$1F
> a|}
> zm7+nhWT_8P-
> 56D*{!R<NT{WZ5&rH7MV=)sf0*@Rls%;Ub(Fl1JrH52Xo7UKi$}*Z5
> zm&hok&kvk_;N*kKUxhW-
> 8B_$b@K>kC%7SF9DDO(H0z+;9+_i2x1a~y#wjZAlbABwF
> zTV7qGo}O)>1|hg|vdNV!G35|995RLI0}GMi%7zaUCkTm+ZYbC~+hHy>r-
> #hxOUy|H
> zsY%4`T%(VQr>0n=SAC(6GoQ?*_=41`1{`}}glAymdr>&zDV<#$^^_Jj&-
> BbWD>~a#
> zTr#V*v}Mlh(pj_Sm<>U1O|990!^D%A^V0e(>i<yEMx&+Cvu4kk?U^yBxYScxa
> @HKr
> zoXE_mC(<&jIWlWbY0-?9R<mkFwb!g#-
> yXJe9cjAOmg44?NOO^AR%Ax8r*uv@?3puT
> zX4n%homo^AnG=Z=&7NWU>U}dx%*D}!ud@Yv|3{KW@Emp0(|o4Z0qmjFF
> *)uG_efPO
> zCH)+!o2mM;<M+@lQ)pk=q8pvfS<*n^l?q$dB>nRcvq*ML+2ac-
> 5r33JW+4bh`4p`K
> zsm1W|kg2hnDiW;<VdWLpmO^Nwl-
> r@;7)qS{Wnpo$kerTA@`NYZ8b6Iz(yAuhDu$D%
> zT@Rd(wbL?9KGB#)laXC<{p!t8&;4Ut<+kw;65rXrJ7xQ3)6d%eGv9MM$==$DB
> Q^+*
> z%=a1x{eDzgmFWU2M^I{%ag}pdwbo08R}FP!nYLe9yyH9<Ya`llt=|j#TMWkXn
> r<yB
> z>_1hWvJ*yqV&)R2O-`IfB~E4GB!$x*jYtiwuC&lx;LfPYl4l1AZzCdvB~UIsMsuya
> zp@9yKj+$;&=Yj~8W~s8^SsbuU)HHuWrw+jFK-
> khyKyg5g@D)P2GOVm>Nz|rg)XG&O
> z4aJmg%}3cqxo8C+=7F!21+;IW2=KQaPcSVq>bwo&xDQSk`Hlb`5?{S&fj5QfGV
> oCa
> zxO2f6tft#IkBRXMQuD-
> r+#30)ag%E>P*CA90c)jlS)*Bmb0@u$&Ouk}QbSE6Op6}y
> zSK9>jlAl`Bgy7XALv*(YU?y&`T+ZL4>1Sg3%M_ZvaDu{Ub>ecmB-
> Uv;LRf9VYIHQ?
> zTCEN|buPi8aB#eUZQQYruH;5f(bUqn#O=VZ=m5j9Dw9|zyceVqL0F}f6M;&Ng
> *F^L
> zC`_4cQ8Y0&dFv1syWJ?9%2vThPTRJ*o(pUs8HNUwG(Xe@-
> (`WSp3W=U?(TTrC}&ps
> zjVsMk>G6>Dol3VvbO$<y;)~rU+bc$PYY+lgvlJ^zf?<P=@oF{O#p8bYIQo7>6iYS
> ~
> z<$NDLNCJnVbX>?IrV12njWHsf3xu+1&7aUH#0ik@c^D}D?969gN|!{uTfXz*<s
> BD)
> zc%h<!tISqIcR5^P?IUF_ZVZB+)Lhe8idlCjyxsVHRGx1sJ@pLn{RYm&!#MLeD!${
> 8
> z&3BLIe)c~P+97M`cd~TnSh>StT!PQTrFXdTz1lR>E)9UK!mcK=9!A+~zz2SNQTq
> bs
> zF84>p&)#Wo?fSyzulcraEIhvEM?KdMmk$l7W0qhMO2X5&BRNV>yWObNyE
> W=M^o20K
> z^@Wu=YypzKvU25%E^T`J{i~Ljk@Ilq@-
> y;0hSxr?*wM5k@$EYQb;r#<^UZNzcyGA!
> zR1GQNH&Q4q^1A?oN!BR#DSwBuH9Gtpx}1$pe#4Ww0!%JpLt1WPfWR1-
> jz_2_ib<+=
> zIkd(sE_G06EW%|@pKjKQRSpwJs$!cTR0qs3EWMjMYG{8|*7d`d2DYr_9P3yn
> 8O~N=
> z@yvL9xkU%I62gOLp;<hWGgkM6#6k979Zy(3Q<YDKv(;}=K0cydSv*ty2NfBs4z
> )X_
> z<)4Vs3#V_PgK%X;s35TAN~xd{JUl#dVaAz0h!uoRqYk4Szusi)Go*Ej!4tz{;%y7Q
> zOhL^?kLdbaGW@!f{?d;RD-@kWN(0-x-
> mYo#<WX~h*ua4TrPtz%5(!UZ2>HXi&2i7)
> z&gbsmOqZ)H9HZqo$T_0(OQAfk-
> 92*aa^=!ga^WVQvg6OxY=+*~<jPB9AZC8$f~T#^
> z^XCVn-pI)t(w`eI`J~^DJP(bbKi$M{KOHQG;q!&~{m|WFsPjY5$B)%l`IUea+Dc4}
> z<Rhhdc+xj;{mFL6FHBLk`%B|UX{?5vb%1~UOI?N1r;yiRn1@4mwtNQ1Px)Qut;
> YwL
> z7RzZN{NQN|gO?sY>O<>1?OL?41?b_ABVsX(3R4RVCpe0no)mUOInT)@XKp?
> RQ2$(c
> z9h}Bo_}nruytc-
> 2>%Je(eeL2L11_P%J4AZGVz{T_&>mk>wr6aLTZ+VRLz@X_x6|NX
> z)+Hn8MHpy}P!z;$BX>O>N*NUW)g)4AD71R`TVvTMr>6$2Q&@Xe#iPx{E=EB}
> tT>5z
> zdO^|bUJuva^q&%V8I<ssyvYnj$+HzYSG~E{<~0ZGv2nO#h+D3R&plcVCSkeg{
> 1`7+
> zXLzOp^^(!=A3w(XF@K#p^Wl*PckeSgeM2qA`K}>qG`Yuu!&Cl|=?S^|$dCI6d(
> P*s
> zzeCq=-
> 1tUsT$_lQ=@d)PO+ypqEOb6VejzbeT}yp71h2{@<UMMzB~k9%kWzkaHn(i|
> zmy?mnA@Lk8ebp;Qy)eGaHCQiU>5}%E55AHGUjeb`q#a;`(rrM@(ev|RWD+V
> h)&;RH
> zl8fgPF@L~Gd-
> $T5ALpCY8?^v_|4d7RtUdVeQacAKp^O3_(Q`p{xXK*)OS=e@)6}xS
> zRQE8WS@$r@SohL2!=ECJeB-
> _+K3!apcF1KVzC+~~$`?vEcg4Em@;fN_Ey{hUc=NS!
> zNR@ddRv2J4T8&~KGR*_w*8ZEcT_USP&ucVr{DpYo^lKeWet@+_5d6kO3zw
> #&5!FtL
> z@yw^6{H@B5^6eI~Gs--xhNne4zE-
> n9_9*%6C#u7}{ho!oqGC(FE1n}QdZ2!3^)qK$
> z{mhv!daQnF^)qK${mhwG_Hd}|47#1qoj9!LdM#n7_V~Y5*>U-
> ms|A<Qlp#4*_TQRe
> z7L<y88+@O+g@Ri*26`_o`SkTy3q<JeLek~jP%eOI=<+j3i{tA$+VEaKm*-
> E4Z4LM=
> zqWxT)d}%+n;>$zO=y+s?xVsdn44&d>3Ih)MYPFH6PJc2C?;8`A6Pbb27EOhNO
> HW2N
> zd^Pa&p>xYRq*X^pDD0q5xPIcCH2DQEqZXDbc!_B@D&ar5G#O9BriHU-
> I@29EtxNq5
> z!2KS+N^rD_#KNRo+^9ok$b9A-pwSHXUg5D1-
> >O6m9$0+GJUU<|gryxewr~fIh{L`v
> z9*9Qw6GRc|VMXK)Uc(#b+8j>q(7&5;x(1#HebsfER}Fy%>z*Y_w!oW9m2~fya
> JDnx
> zAYlAe_|_X>KA;k?3eX1V1zZi-0=N_KUBDi|i-
> 6YvZv*nK#y8>sCSV$1HlPAf2RIMV
> z2IvB81o)r}x8omIrJcSkozT!?#(HST)Yhmer^E~~A#799_D!vOqS%R4L{<zD7d1b
> 6
> z&?K;)<i;>GT0)?Ot5q$~+lPm1IIFMOX!%R0m!);q%M|du65klF7kk0v*Md#x+t
> M;k
> zE25jj+3Sck%dgOL{eZQdnf^>XEzYRx`3bZvNIDNn5#Os6zj+44!V&505+8RrGkr;
> 9
> zy82TZ;YOg6$Xxz`jA1??){KwFcy=^?i_mfZQPdk}o8$_2T&+PnF!3c$&NX`h_P<g
> w
> z`_%ihI1?rB_1frA>#kO`jWwcuaFx#~bI!V)nxnnpv7mP7^y(Jurgw^H?@p;0j4~-
> D
> zL!nXfvk^Le4ZciWBlx6egq@JZTC7RC%T25{&x=Kh1y;|Kt<G&eWai_PZg>ANa4
> y-~
> zPWGNr_ltU!JbT&@+9@s5+~wInMfNo0ox4PCEV;Rq9p4$~L!DGeD@rfgJ0&|;
> 8eM8l
> zHL1$(*O;wt`nLslJ!q`C@~;=8k=z-
> n_rg}7#dL!+GmTQT%Nb&qtXt0bhBbVVYNsCD
> zPr>(doq3z^3^0u<d>yq2z}V9O<VCLbcBo}J12pufz$xLHn(TE!InTzAdSK-
> @<6F_5
> zBv)8kr}Sjw2X`4ezouRZPUFmFwJW&+lF}%8rY<#7xVfkKMLzS&UH5YI*Y#|-
> lI&^d
> zozi8|)jw6Xe55>Zm6~IrPLo?tA&#^ty|g5fJGsg*oVdfKL$9op^I>={XvzoU5ow(
> Q
> z$(8H!xl+p>j(x-
> w*yC8&oet}u&Lfwsf7JLj^+PSQO;2VDXE`%{WSphUE^i+dUR}Oi
> zwUbNUJ}P=XD!dahvZpLr^ka5GD?6>wPN|c91j~HihTVG?pWhVRb?n+t1on;F
> w*RqD
> zfANnquBiUkH+{eV;``%TuQ~J0zMHzQs`|IfColfQ%G$bbKXvl^#TV`h-f;f*^NzlC
> z@1;DsPkRc|@t<BF(TMbDpqqgGOrMy>qgRDvAr7@}k%xt)6aAu*wkWqPV-
> u1%rpv-4
> z_DW%+wcK{26Y{Cr31>K;NgUYD;UvZx8TsI2>56i7&<36f&o~^BK!rD*z`=mYH3`
> h0
> zaVDyYN*s)Y_tH<FzT@(Y0!@efh1s&&&k0u#e}$&f&I)^tOb>R?B<<~R%v0<t1
> 5Q%M
> z6EWytVJAnnVlR-
> DNA_q|E@GNnh{I^%b0Q8w6HXt+uv5eqfjivqA`TX!QzSQnb*i&E
> zShvCt68UkT=c+Rb&tTp<q~9yQh^_ZvF;4fC11Eji2z&2+;FP03^Vsiw-
> Y+aPwr%<4
> zIrpxQ7yUR|Uoet&1#E^5MO%0z5V$3F9cq3pBz*=C+Yb4C4Z+%)rh4zP{=X?p+
> }DJe
> zlfq?fui$aC+`x?IfmYN-
> 7xQ4HaLb~u7rbX4fu&7>V3oh&+&X_#px*E2*&TQ_@H=<j
> z%)`pN0P_qnw?fzpJp4_WYryD0FGF4dj7D*^YW^w`Z;>BjXZpjrZ3uFluM^{p?x
> S<-
> ziUZ-
> x_HHnY+0wY_8yaN|(6Aa&TFD15dbW`GW$if@d(?QY78|%Y<y7oRVtgU<!e@J
> +
> z_iRA}y{BDiWbb?QzGxSXYVQ;~PK!ovu-19F-`8Q1-
> ^IO$4M}Obn=;jGfe>p~tgvXE
> z@MGo&KyYb$AW8*4Gx3R*VcP^Sr8h<+-
> @$Oil<l%veCR=Vyyc>QIsM73KPAgyk>D?R
> zlNpi^Bk5ySttwl^v<w?-
> d}43u+*PZLRfPon!F4?U;PThk*Va2iwXUq!myHVlqQ=E|
> zuS1X@A;I#GZC25?6`W}zY^hTU(qeGNUiCtHMDnTq%+8nbfu%H!Jak&d)%UD
> JSZ`7c
> z`8VAai^sawNykHVc4-
> u!9E##lK1f)!GlA`y&Wb=f*j(e>|HPqAjH7slW#UGOss{3v
> zA&eX-OlMBnaR^+~d*o($oI!&8ak5Q2P9c;O(Ex0F#dBWNYS~Bms{=h_m&-
> ~ql=uPY
> z=d`oY*HhmIp&!XzgDBb%^3>_1Z*vlK4L_aRGecvn!yJe`wwwWSy=b`fXiR^-
> Wy)2j
> zv?{lt<kGSYx&355`T>2MpYSW?h>sJFxWvFuD$rvg++|ME$JAz=UMqg;cay9>M
> IC2n
> z^_3&(BMt{$x%gzuzOL(`$cWRLC*|t2Vaa;#JTmKzGP@GEr<sO9eTu-
> do7gYqA>>t!
> zy5@=p=f1iWS}(B6mo1joIP@HHU|iWSWN-
> PSgLf#cx_?e1D}x{WYt3Sv$W~^}+idUb
> zUW`6iJk>5&EL~IXz9n1i!SWj#pN3D(K(yqNJC=WF^vE;+vgKj(P>8qn#|wR(8ar+
> 3
> zdbbMCl#^pn#J~zObp4dDaki?b_LDfCB#@d<BEq-
> mE3Ym#t_EBN;8pXh@*muD;zJcy
> zhT>*_Sx2(RNN+KW6oA*pThF$_F=NE7{4>FEuWpY(=!}vXgYO9+UmtT|xE#oo
> EB?-e
> z?Z;Ibn*qG|?y~?bb7R##$C1wgjs$QGavb23fKLGU4d(GG<TL)J{>yj&0MPG<m
> uVRu
> z17IF(4t#bj;5Y?*J`up@X94)ztA6{`?>dA`!?^(Cg;a=-rwRP$B4pll+~E6mfC=aT
> zoC4sPE2Nd>AUzuaq<NDHFG0xnmjd|yG63;h2bc=DP5s`Ako0W_Fu$Du#(Mx
> j`kn^x
> z{qq36{~VY?{%D@De;I?{{PwX9Klt5CPvOzu^fhLX>xhhNth#ie>rU_qzVJ8s!b^
> wp
> zm;HON=egeJ!lUC47V7kW$?&&}D~$ty7Xi-
> !C`Y_VJAwBbDcFa0ZS1>PA=ud0_u|gy
> zzjt}-+Ix;Jm(Tk8jxPVxOy5ykPW<DIAK?6GUi-
> _&VvC`?$KNr>8^?aK!uZFdDvU{h
> zCHWQBD{=F1U*B1ev`yT$@0ch16o!Lk<MYOkCm4B0NkG)1g20e~{TBP5UI2^
> Feufv@
> zV%?TX(I=gbkZt^(n=3_}^AIv#DMGg0JcR6%_TN-#d>Y|>2-
> yd2KzJg;281UeJO$y&
> z2oKy?Df*V(2v5cDTM&L8;cSE^LIdGM1mibX3LX91*H;SqZb3*Nu&WWSN4Np
> u`v`jx
> z_91Lzhzqyka^7zQk6F(L-<0p`LJca`$b!0xLrcH^o}gjg8ys2Y!%j6J=Os~@Ij>=7
> z^;el7j595xt!vt1=U)(SPb53m;#1%0?w;Ot6eC>TMLwL1y|^-
> X_BmD6HMMn1@TJVg
> zrOTF|yF$MId-$7E1XPpHDFWu-
> L+PzD{Edr32l|XLN92v)j*k1hOV(Y&ev;RYpUZIT
> z9WvbX_5JJ`jq-~&ittXv|KT_GeZ!Qm`~BVYp?p-X!uy99->c$(2l1cTc3|5{#;e<2
> z+eRyk`?By~v{j^70tI==zJK0l8cqAo-
> &f*}j9;6cec|Q(?;1w&MKa}GuU8r$qC@wo
> znC#0xifhXQ?mqcYf0NEkTCe<poyVQOt~83?s5HL)`%2@9?+1<Bkw4=zWL@w
> 5YNc`T
> zdvaVW-
> (MldH;&DD3OL5;i_gs?Z{Uz?U3?}kAVnGs^%&);cpDvMhH)hT+pqe)<NG)G
> z4%b1&@`Ll#Z}oh?3j6v#ytv|sfN?gU7SIS-
> 0XPrP3Wx(b0oMX<0Q?)^Zoq#5_5t1i
> zd<ZyoY`{1TumG?K&<yAXTnpF+cm(icz%Ky50*uQG7$*Tr00BTN-
> ~zzqfG+`d0UiYW
> z58yX|{38R#F@ULnLO>0m8L%F3E#Pjze*m5W{1os9z_@Xs3s3^62P^}u1#|;$0
> _*}j
> z0?^mNi{;%rs!D#Zerv7DfL7SocPb*0nH*fGcijxQAMhODEx@s;k0L+~pdFyo%*
> DHN
> z0X=}50QUi&1^fXp0r92-
> ssV8T<!Tq&OyuoK<2=ABz;ZwXpbk(4r~u3dlmeyzP5~Sb
> z7!Sw;7=ZWRsx;mKybU-
> A_$}ZyzyZL1z>9zv0DA$C0(JxL12FzwfbD==0AB%I3D^MW
> z0K@@pfK`A>z<j_bA)p{#Tx<(myT1%=WxMz6LE&O`v276t(`sBq$i9QH<(Qyx{
> AXnQ
> zD=hOaZ4O78xT+(*BvYR1ij<eT-
> e<leE?%4eNruNGc;S^w;~x<|hwvnX2N0f&@I{25
> zM>u;zQ0T=)2q)tA6oj8bxCigq6dy&%dH#I}DJdr2(|+(dgp`#ncuxI#GeQ&LR}gY
> u
> zd>2B_mA51O48jSB&pG=o_{~mWJbqI@HxN=Ee+Omf9Q`1|6A-
> ?Ja1z1;2v0+}AK~c;
> zUqo1d@HvDm<`W3jwQ)j)#n+8k?3X-
> dy}gf_2_li6azG!(gN+C`f#=Mdwha@Y8ibKq
> z4|G*&;%7<0|IBx+qn2>0OI44ne)x`QV-
> fupYoLz$ZE8v+6HT3P(P>IHpO3W}I~u6L
> zb^8(J_$#j`jx5)=#-
> GPq_vN=7W!=~P=ost%^tX@G_Zx58@>zXv?tbt@d7t;tlP6zW
> z%KNRq+w=6vk33sbZXUet{*E*6{N`h~#>)4u{-
> EI1ldi2j@%2l~*WUE}jlNGEdCk;s
> z-B$kYL$_D_ZqspJ-gL?L${(8l-#eb^3x2-
> $k!Q=3kMF<w*BhT){QVp5^zOd=g2u^n
> zuK82P{tb(EzjW=(@80^}>lf`>;@kSG?pOBwVe0hDHvLn@lnE#7dgty5uRQkXp
> DSM9
> z`P^H7di@t?ufOpbe{|1}ulv-FyKg`7m2U)&j-GH-
> dear@?k6j&moGZ7^M*O|&id}X
> zzYA6Ge0BAL$5zj~>bC1w^sU};aI5)n!yQ-83jgGTt5#g~Lc!`UzWcK^yKa2vt;r8<
> zdt&uV8xvJe{_D-
> =myW1E@6m!Z%4<Be=czsNdarElg8b*d(ZN6Ol&y%&`+4m(Hz$s}
> z^#96!^z5|giN9Qa!UI2fvuy7%r(L%A<i&SAw)2g$@*Ura#lLmrf6lt%^|BcYb}w5
> 0
> z>VI#3=zspV?2!*XcshL9u|0eK{Xp6Ds+GT}e)Pf3H~#9$vg;oW%}ZB2b^L>0`&Q
> Y@
> zYremEj{lpd-
> t)}nveQp{{Fl4GKd(4^)%vn<<GDY)=$_Dq<9^Uo_WT>uuNn8?^_PF<
> zy^6Ba%kKE~oI57}=HffgD7)~ktp|2THU##*)VQ$a3*+{j*3ffl-
> *uZ7T=(a>C$4WP
> z@D)FN*ZhfJ{K@P~7T^3`<Adkty?EvF@h9K&+ACM=7(4Ir%lwNz@tv=xXZ@^
> j?u@mk
> z{PeV+mAn!B%8EHV{^h}km+iabk{#RbFZpHLy~pmX|9Zu_4@{U=5Io?SSy~&q
> `{@e`
> zzI<-
> p_J?17<iht}d;HYf{`bli%dVUMP~D}IK38*2wE2Tezx=Inn=d@}fam3}KmF4u
> S@?P5ULO$Ea$Ja;8f&T|O4^B`3
> 
> literal 0
> HcmV?d00001
> 
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleAll.bat
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleAll.bat
> new file mode 100644
> index 0000000000..8f589565fa
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleAll.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\SampleDevelop
> ment
> +mkdir %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\NewCert
> +mkdir %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\TestCert
> +copy %WORKSPACE%\Build\Vlv2TbltDevicePkg\DEBUG_VS2015x86\X64\Ca
> psuleApp.efi %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\SampleDev
> elopment\CapsuleApp.efi
> +copy %WORKSPACE%\Build\Vlv2TbltDevicePkg\RELEASE_VS2015x86\X64\C
> apsuleApp.efi %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\SampleDe
> velopment\CapsuleAppRelease.efi
> +copy %WORKSPACE%\Build\Vlv2TbltDevicePkg\DEBUG_VS2015x86\X64\Ca
> psuleApp.efi %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\NewCert\C
> apsuleApp.efi
> +copy %WORKSPACE%\Build\Vlv2TbltDevicePkg\RELEASE_VS2015x86\X64\C
> apsuleApp.efi %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\NewCert\
> CapsuleAppRelease.efi
> +copy %WORKSPACE%\Build\Vlv2TbltDevicePkg\DEBUG_VS2015x86\X64\Ca
> psuleApp.efi %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\TestCert\C
> apsuleApp.efi
> +copy %WORKSPACE%\Build\Vlv2TbltDevicePkg\RELEASE_VS2015x86\X64\C
> apsuleApp.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
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleAll.sh
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleAll.sh
> new file mode 100644
> index 0000000000..040024553a
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleAll.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/Caps
> uleApp.efi
> +cp
> $WORKSPACE/Build/Vlv2TbltDevicePkg/RELEASE_GCC49/X64/CapsuleApp.ef
> i
> $WORKSPACE/Build/Vlv2TbltDevicePkg/Capsules/SampleDevelopment/Caps
> uleAppRelease.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.ef
> i
> $WORKSPACE/Build/Vlv2TbltDevicePkg/Capsules/NewCert/CapsuleAppRele
> ase.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.ef
> i
> $WORKSPACE/Build/Vlv2TbltDevicePkg/Capsules/TestCert/CapsuleAppRelea
> se.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
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleMinnowMax.bat
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleMinnowMax.bat
> new file mode 100644
> index 0000000000..6e4afd201e
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleMinnowMax.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\Caps
> ules\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\Sampl
> eDevelopment\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\Caps
> ules\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\NewC
> ert\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.p
> em ^
> +  --other-public-
> cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestSub.p
> ub.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\Ca
> psules\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\TestCe
> rt\MinnowMaxWindowsCapsule
> +  rmdir /s /q WindowsCapsule
> +)
> +
> +erase %FMP_CAPSULE_FILE%
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleMinnowMax.sh
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleMinnowMax.sh
> new file mode 100644
> index 0000000000..4fb963c93c
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleMinnowMax.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.pe
> m \
> +  --other-public-
> cert=$WORKSPACE/edk2/BaseTools/Source/Python/Pkcs7Sign/TestSub.pub.
> pem \
> +  --trusted-public-
> cert=$WORKSPACE/edk2/BaseTools/Source/Python/Pkcs7Sign/TestRoot.pu
> b.pem \
> +  -o $FMP_CAPSULE_FILE \
> +  $FMP_CAPSULE_PAYLOAD
> +
> +cp $FMP_CAPSULE_FILE
> $WORKSPACE/Build/Vlv2TbltDevicePkg/Capsules/TestCert
> +
> +rm $FMP_CAPSULE_FILE
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleMinnowMaxRelease.bat
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleMinnowMaxRelease.bat
> new file mode 100644
> index 0000000000..43c609e4b2
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleMinnowMaxRelease.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\RELEAS
> E_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\Caps
> ules\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\Sampl
> eDevelopment\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\Caps
> ules\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\NewC
> ert\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.p
> em ^
> +  --other-public-
> cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestSub.p
> ub.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\Ca
> psules\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\TestCe
> rt\MinnowMaxReleaseWindowsCapsule
> +  rmdir /s /q WindowsCapsule
> +)
> +
> +erase %FMP_CAPSULE_FILE%
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleMinnowMaxRelease.sh
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleMinnowMaxRelease.sh
> new file mode 100644
> index 0000000000..29d46dad1e
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleMinnowMaxRelease.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.pe
> m \
> +  --other-public-
> cert=$WORKSPACE/edk2/BaseTools/Source/Python/Pkcs7Sign/TestSub.pub.
> pem \
> +  --trusted-public-
> cert=$WORKSPACE/edk2/BaseTools/Source/Python/Pkcs7Sign/TestRoot.pu
> b.pem \
> +  -o $FMP_CAPSULE_FILE \
> +  $FMP_CAPSULE_PAYLOAD
> +
> +cp $FMP_CAPSULE_FILE
> $WORKSPACE/Build/Vlv2TbltDevicePkg/Capsules/TestCert
> +
> +rm $FMP_CAPSULE_FILE
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleSampleColor.bat
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleSampleColor.bat
> new file mode 100644
> index 0000000000..3e9f94c530
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleSampleColor.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\Caps
> ules\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\Sampl
> eDevelopment\%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\Caps
> ules\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\NewC
> ert\%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.p
> em ^
> +  --other-public-
> cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestSub.p
> ub.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\Ca
> psules\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\TestCe
> rt\%COLOR%WindowsCapsule
> +  rmdir /s /q WindowsCapsule
> +)
> +
> +erase %FMP_CAPSULE_FILE%
> +
> +erase %FMP_CAPSULE_PAYLOAD%
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleSampleColor.sh
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleSampleColor.sh
> new file mode 100644
> index 0000000000..a1c6f28cde
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ge
> nCapsuleSampleColor.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.pe
> m \
> +  --other-public-
> cert=$WORKSPACE/edk2/BaseTools/Source/Python/Pkcs7Sign/TestSub.pub.
> pem \
> +  --trusted-public-
> cert=$WORKSPACE/edk2/BaseTools/Source/Python/Pkcs7Sign/TestRoot.pu
> b.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
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Lvfs
> .ddf
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Lvfs
> .ddf
> new file mode 100644
> index 0000000000..f2c925a6dd
> --- /dev/null
> +++
> b/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
> +;***
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Lvfs
> GenCapsuleMinnowMax.bat
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Lvfs
> GenCapsuleMinnowMax.bat
> new file mode 100644
> index 0000000000..dd8274a1cc
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Lvfs
> GenCapsuleMinnowMax.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\Caps
> ules\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\Caps
> ules\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.p
> em ^
> +  --other-public-
> cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestSub.p
> ub.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\Ca
> psules\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%
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Lvfs
> GenCapsuleMinnowMaxRelease.bat
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Lvfs
> GenCapsuleMinnowMaxRelease.bat
> new file mode 100644
> index 0000000000..2b68a98f98
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Lvfs
> GenCapsuleMinnowMaxRelease.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\RELEAS
> E_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\Caps
> ules\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\Caps
> ules\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.p
> em ^
> +  --other-public-
> cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestSub.p
> ub.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\Ca
> psules\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%
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Lvfs
> GenCapsuleSampleColor.bat
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Lvfs
> GenCapsuleSampleColor.bat
> new file mode 100644
> index 0000000000..1dbbe7341d
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Lvfs
> GenCapsuleSampleColor.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\Caps
> ules\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\Caps
> ules\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.p
> em ^
> +  --other-public-
> cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestSub.p
> ub.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\Ca
> psules\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%
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ne
> wRoot.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferX
> dr.inc
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ne
> wRoot.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferX
> dr.inc
> new file mode 100644
> index 0000000000..d3f5a12faa
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Ne
> wRoot.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferX
> dr.inc
> @@ -0,0 +1 @@
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SA
> MPLE_DEVELOPMENT.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceP
> kcs7CertBufferXdr.inc
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SA
> MPLE_DEVELOPMENT.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceP
> kcs7CertBufferXdr.inc
> new file mode 100644
> index 0000000000..d3f5a12faa
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SA
> MPLE_DEVELOPMENT.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceP
> kcs7CertBufferXdr.inc
> @@ -0,0 +1 @@
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SA
> MPLE_DEVELOPMENT_SAMPLE_PRODUCTION.cer.gFmpDevicePkgTokenSpa
> ceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SA
> MPLE_DEVELOPMENT_SAMPLE_PRODUCTION.cer.gFmpDevicePkgTokenSpa
> ceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
> new file mode 100644
> index 0000000000..d3f5a12faa
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SA
> MPLE_DEVELOPMENT_SAMPLE_PRODUCTION.cer.gFmpDevicePkgTokenSpa
> ceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
> @@ -0,0 +1 @@
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/tem
> plate.metainfo.xml
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/te
> mplate.metainfo.xml
> new file mode 100644
> index 0000000000..5d550c1f48
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/te
> mplate.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>
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/
> FmpDeviceLib.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib
> /FmpDeviceLib.c
> new file mode 100644
> index 0000000000..a863d69381
> --- /dev/null
> +++
> b/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;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/
> FmpDeviceLib.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib
> /FmpDeviceLib.inf
> new file mode 100644
> index 0000000000..6fd618974f
> --- /dev/null
> +++
> b/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.PcdSystemFirmwareFmpLowestSupporte
> dVersion
> +  gPlatformModuleTokenSpaceGuid.PcdSystemFirmwareFmpVersion
> +  gPlatformModuleTokenSpaceGuid.PcdSystemFirmwareFmpVersionString
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib
> Sample/FmpDeviceLib.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib
> Sample/FmpDeviceLib.c
> new file mode 100644
> index 0000000000..80ce83a14b
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib
> Sample/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;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib
> Sample/FmpDeviceLib.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib
> Sample/FmpDeviceLib.inf
> new file mode 100644
> index 0000000000..af31fbcffb
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib
> Sample/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
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlash
> AccessLib/PlatformFlashAccessLib.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlash
> AccessLib/PlatformFlashAccessLib.c
> new file mode 100644
> index 0000000000..079c3ef2d6
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlash
> AccessLib/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;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlash
> AccessLib/PlatformFlashAccessLib.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlash
> AccessLib/PlatformFlashAccessLib.inf
> new file mode 100644
> index 0000000000..9b29b05bac
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlash
> AccessLib/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
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescr
> iptor/SystemFirmwareDescriptor.aslc
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescr
> iptor/SystemFirmwareDescriptor.aslc
> new file mode 100644
> index 0000000000..884da36b97
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescr
> iptor/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(CH
> AR16)];
> +  CHAR16
> PackageVersionNameStr[sizeof(PACKAGE_VERSION_STRING)/sizeof(CHAR1
> 6)];
> +} 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;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescr
> iptor/SystemFirmwareDescriptor.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescr
> iptor/SystemFirmwareDescriptor.inf
> new file mode 100644
> index 0000000000..dd85c86d95
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescr
> iptor/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.PcdEdkiiSystemFirmwareImageDescri
> ptor
> +
> +[Depex]
> +  TRUE
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescr
> iptor/SystemFirmwareDescriptorPei.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescr
> iptor/SystemFirmwareDescriptorPei.c
> new file mode 100644
> index 0000000000..d21ee52184
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescr
> iptor/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;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpda
> teConfig/SystemFirmwareUpdateConfig.ini
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpda
> teConfig/SystemFirmwareUpdateConfig.ini
> new file mode 100644
> index 0000000000..126cd123b1
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpda
> teConfig/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
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpda
> teConfig/SystemFirmwareUpdateConfigGcc.ini
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpda
> teConfig/SystemFirmwareUpdateConfigGcc.ini
> new file mode 100644
> index 0000000000..e22f136f8e
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpda
> teConfig/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
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc
> b/Platform/Intel/Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc
> new file mode 100644
> index 0000000000..3bd9f150b3
> --- /dev/null
> +++ b/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.PcdFmpDeviceBuildTimeLowestSupported
> Version|0x00000000
> +
> +
> gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressWatchdogTimeInSe
> conds|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/Fm
> pPayloadHeaderLibV1.inf
> +
> FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/Fmp
> AuthenticationLibPkcs7.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/FmpDeviceLibSa
> mple/FmpDeviceLib.inf
> +  }
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FmpCertificate.dsc
> b/Platform/Intel/Vlv2TbltDevicePkg/FmpCertificate.dsc
> new file mode 100644
> index 0000000000..237ec87ac8
> --- /dev/null
> +++ b/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_DEVELOPM
> ENT_SAMPLE_PRODUCTION.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpD
> evicePkcs7CertBufferXdr.inc
> +!endif
> +!if $(CAPSULE_PKCS7_CERT) == SAMPLE_DEVELOPMENT
> +  !include
> Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMPLE_DEVELOPM
> ENT.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.
> inc
> +!endif
> +!if $(CAPSULE_PKCS7_CERT) == EDKII_TEST
> +  !include
> BaseTools/Source/Python/Pkcs7Sign/TestRoot.cer.gFmpDevicePkgTokenSpa
> ceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
> +!endif
> +!if $(CAPSULE_PKCS7_CERT) == NEW_ROOT
> +  !include
> Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/NewRoot.cer.gFmpD
> evicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
> +!endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FmpGreenSampleDevice.dsc
> b/Platform/Intel/Vlv2TbltDevicePkg/FmpGreenSampleDevice.dsc
> new file mode 100644
> index 0000000000..61bdd36a96
> --- /dev/null
> +++ b/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.PcdFmpDeviceBuildTimeLowestSupported
> Version|0x00000000
> +
> +
> gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressWatchdogTimeInSe
> conds|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/Fm
> pPayloadHeaderLibV1.inf
> +
> FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/Fmp
> AuthenticationLibPkcs7.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/FmpDeviceLibSa
> mple/FmpDeviceLib.inf
> +  }
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc
> b/Platform/Intel/Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc
> new file mode 100644
> index 0000000000..304519b294
> --- /dev/null
> +++ b/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.PcdFmpDeviceBuildTimeLowestSupported
> Version|0x00000000
> +
> +
> gPlatformModuleTokenSpaceGuid.PcdSystemFirmwareFmpLowestSupporte
> dVersion|0x00000000
> +
> gPlatformModuleTokenSpaceGuid.PcdSystemFirmwareFmpVersion|0x00000
> 000
> +
> gPlatformModuleTokenSpaceGuid.PcdSystemFirmwareFmpVersionString|"0
> 00.000.000.000"
> +
> +
> gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressWatchdogTimeInSe
> conds|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/Fm
> pPayloadHeaderLibV1.inf
> +
> FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/Fmp
> AuthenticationLibPkcs7.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/F
> mpDeviceLib.inf
> +  }
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc
> b/Platform/Intel/Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc
> new file mode 100644
> index 0000000000..59851f2b41
> --- /dev/null
> +++ b/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.PcdFmpDeviceBuildTimeLowestSupported
> Version|0x00000000
> +
> +
> gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressWatchdogTimeInSe
> conds|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/Fm
> pPayloadHeaderLibV1.inf
> +
> FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/Fmp
> AuthenticationLibPkcs7.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/FmpDeviceLibSa
> mple/FmpDeviceLib.inf
> +  }
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FspAzaliaConfigData/AzaliaConfig.bin
> b/Platform/Intel/Vlv2TbltDevicePkg/FspAzaliaConfigData/AzaliaConfig.bin
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..da24c02b5d25ce888c630c6640
> 95902b4bb035e7
> GIT binary patch
> literal 3708
> zcmd^>Pl#JZ9LMK3`)XRdt$F?9>(+TQNqa~UwYzRL6+{xdH3}71P@h!~iwKK?Q
> Ysja
> zyX|(<qQVxzbj5>fq4Da)Ts;(X@!&zpF$WI;5lLww$LD8u(;7lcLET;q4D-G_leaV9
> z`ONQ|ZR6t$o%9hYzfnH1u=S6uQmNdpwECI9F1+yKF{PAjL*H2Jq)QXOgh~bL
> df(Yj
> zx{Q{={HK>X>1pl1uVg3l=gxJ~cL&<PZ)v%co*%q_JNnyNCp|Z$e>&eufBh)t{i$
> qa
> zymz6Ko;kF<fYxKYbk8T9^zHTcrQ*MT^i#$MdK~@MXPtDW{K}NLuFTl3<m0X=
> (-m=j
> zxoZ39zGO`wT@kSrDa94Z8J=B&PSA<u4bN^KJufTqyc{q*yDGXWlW|oJ8lGK47
> HtDf
> zGYxc2)@+UWHJLIsS#>R$wk^39x8#&*q1$rZw$W`_Fm2JUDS6xE|21XSG|_d
> wU+4RE
> znKN}^tDE}4qiNQxW^7I6<C;>Yro`3NRa-
> ~bRo2weO(nLeSfk1ro?RE+MR!%+@QkN|
> zrz?1RVBOP<7MszNaYi3BJiC@!v@JCm(@cx`ZMA0GY9(%~l4+||7vWKaClMY+
> c+gjQ
> z+voj#HEa4xy9}OWcz*^@GMnznsNr~Yq{O;PtS`?xHS5iqf=FDD$QES96{Kg1=%
> Vbl
> zMS0m3VWGl$E3CW1e9u<Gcp?p(Fh7yUJWDV&4O^=))-
> zRfRj$~oyy~jx8oGwAp=;=d
> zgfMm;)-J+a4^~2$ISxBz80x{6z}V-ob`s`B_psR-kDkb~#xiTnvqsGtCt0KC8g{rB
> zP3}XBd%`+dBTUHSrj18!G|jbT+HgnXu7tKL6RwMAeYprzYp?|qQi3JV)FNz&%jj
> 7X
> zX^A6!(MI~Di}ai+pbL7+7W9NGXwC#()Zf`6<3)4@UD4NUh4BhH(b+iB$8Ey<5`
> 7Om
> zdQz(``s;53YS<Qi?D>E-M4TfHuF7zggR5<Dbs4T!2V8}46~a{+uCj2&9^kCPc!hIM
> z_&yD;%5c?#s}Qb2xGE303gIe*t1?_onwngSH)>SiJXdw*(`=pbI(mb%kTWcEhB
> rA2
> zIYZCcqnz27oLR(~l{m8=XBH05tjw7?&V+lSxhFc{O#D8_N*nw2{oOo<qvGU<2c
> vs-
> z?0LODv*+M8doKOUJ#Jx-
> XV~NJ!5(viJsyY4fIW_$SqhgaTq?L!aQOgxCKq*<{&yGX
> zkp9CRfsW}z{=PoG_IH0bPe#Y_=;&{`NR8(s_2z*{We?Ke!e^Mkh0nBIcm&&M
> 8Xkpk
> zF$Whu%LFd=n5yL9Lf}H+A~)n2c_4@3;w!jVgA4M2EaX1N8(HTwj~tK_ag)35G
> wbjA
> z<7<!4yD>cc9uFV911CMxhZ~yh!&U!3uUB~VR348M9xdb1!oZ`MA&-
> 1bp24F$9_ib7
> z<ZJTq-
> I*QoNaN8iJj&vc3_L2~(UBpKUc#eGc(jH`zW(_d9mX{LDbsp*BzSZdk50Na
> zcXQ(|dCtUn&NkhnXLF`O4mZf-207bMj(qny&$*(TN|D!!-
> 0qRzC2~AVUbAKu`urxx
> z`Ax-mm+>y+Jd@Xo-
> 0u1OCdZW_uj7pLY=(Nlvx(3VIzscz9+{7(zIzV1OU&2I*UZ;H
> zWLQt8t)~8r)UF%R=vCNs4M)egTR9b1a<AD+Zl9~<;0B$b6LgZBH1p_r^nC7h$
> MgT}
> zgGV!?HL*tx4`Z4waK8)dxiws$?v`7l^(fC>yTo1d^~nE5K0H#7;CB7D2Hf7NN4M
> @8
> zHA%Q@KgMm@!(F>wZry{scKj6e==4xMQYkzSwVSzj1<zInp82egsOc-
> z^wE0cJ=zy<
> zWce8N=$~Zy5}xe6gC{=Avx6)jBg^0SxppDYAJgysBGC8IOFqyO^vV7}@Au<m
> e3Aa)
> og+TA{`cR;E`u>AJKSaMh8|ZiFi`_ua(_elr(C^Vdb2!j{0U29Y3;+NC
> 
> literal 0
> HcmV?d00001
> 
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModeP
> ei.c
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModeP
> ei.c
> new file mode 100644
> index 0000000000..bf6c7efba5
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModeP
> ei.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;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModeP
> ei.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModeP
> ei.inf
> new file mode 100644
> index 0000000000..27200bca15
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModeP
> ei.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
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLi
> bVlv2/FspHobProcessLibVlv2.c
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLi
> bVlv2/FspHobProcessLibVlv2.c
> new file mode 100644
> index 0000000000..8a97e25bd4
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLi
> bVlv2/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;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLi
> bVlv2/FspHobProcessLibVlv2.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLi
> bVlv2/FspHobProcessLibVlv2.inf
> new file mode 100644
> index 0000000000..b789b27f4c
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLi
> bVlv2/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
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/FspPlatformSecLibVlv2.c
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/FspPlatformSecLibVlv2.c
> new file mode 100644
> index 0000000000..2b03cfaec9
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/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;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/FspPlatformSecLibVlv2.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/FspPlatformSecLibVlv2.inf
> new file mode 100644
> index 0000000000..578066d98f
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/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
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/Ia32/AsmSaveSecContext.asm
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/Ia32/AsmSaveSecContext.asm
> new file mode 100644
> index 0000000000..2546a09a1a
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/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
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/Ia32/Fsp.inc
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/Ia32/Fsp.inc
> new file mode 100644
> index 0000000000..23295587b4
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/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
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/Ia32/PeiCoreEntry.asm
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/Ia32/PeiCoreEntry.asm
> new file mode 100644
> index 0000000000..3d34c62ea4
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/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
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/Ia32/SecEntry.asm
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/Ia32/SecEntry.asm
> new file mode 100644
> index 0000000000..b7026c433f
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/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
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/Ia32/Stack.S
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/Ia32/Stack.S
> new file mode 100644
> index 0000000000..9bd29ce0f4
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/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
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/Ia32/Stack.asm
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/Ia32/Stack.asm
> new file mode 100644
> index 0000000000..95e56cec9b
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/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
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/PlatformInit.c
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/PlatformInit.c
> new file mode 100644
> index 0000000000..d4e1c2a425
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/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));
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/SaveSecContext.c
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/SaveSecContext.c
> new file mode 100644
> index 0000000000..382e617b27
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/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);
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/SecGetPerformance.c
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/SecGetPerformance.c
> new file mode 100644
> index 0000000000..c5c22a29c2
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/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;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/SecPlatformInformation.c
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/SecPlatformInformation.c
> new file mode 100644
> index 0000000000..a1ba35d47d
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/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;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/SecRamInitData.c
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/SecRamInitData.c
> new file mode 100644
> index 0000000000..33734e3111
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/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)
> +};
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/SecTempRamSupport.c
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/SecTempRamSupport.c
> new file mode 100644
> index 0000000000..8dd1367980
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/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;
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/UartInit.c
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/UartInit.c
> new file mode 100644
> index 0000000000..2a9ab17120
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecL
> ibVlv2/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  ;
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c
> b/Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c
> new file mode 100644
> index 0000000000..11832bd295
> --- /dev/null
> +++ b/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;
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf
> new file mode 100644
> index 0000000000..397c2ce2a9
> --- /dev/null
> +++ b/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
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c
> b/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c
> new file mode 100644
> index 0000000000..d3b9145db0
> --- /dev/null
> +++ b/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;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbRuntimeDxe.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbRuntimeDxe.inf
> new file mode 100644
> index 0000000000..670db13465
> --- /dev/null
> +++
> b/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
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.c
> b/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.c
> new file mode 100644
> index 0000000000..aa4fab013d
> --- /dev/null
> +++ b/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;
> +}
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.h
> b/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.h
> new file mode 100644
> index 0000000000..89e0212f98
> --- /dev/null
> +++ b/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
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceDxe.c
> b/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceDxe.c
> new file mode 100644
> index 0000000000..32aa216728
> --- /dev/null
> +++ b/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;
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceSmm.c
> b/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceSmm.c
> new file mode 100644
> index 0000000000..d1360bb90d
> --- /dev/null
> +++ b/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;
> +}
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmm.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmm.inf
> new file mode 100644
> index 0000000000..4e33c3b9fb
> --- /dev/null
> +++ b/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
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmCommon.h
> b/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmCommon.h
> new file mode 100644
> index 0000000000..236e487111
> --- /dev/null
> +++
> b/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
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.c
> b/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.c
> new file mode 100644
> index 0000000000..e46c65c3fc
> --- /dev/null
> +++ b/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;
> +}
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.h
> b/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.h
> new file mode 100644
> index 0000000000..9edb1bcaf0
> --- /dev/null
> +++ b/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
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.inf
> new file mode 100644
> index 0000000000..aa2b63fe13
> --- /dev/null
> +++ b/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
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/GenBiosId
> b/Platform/Intel/Vlv2TbltDevicePkg/GenBiosId
> new file mode 100755
> index
> 0000000000000000000000000000000000000000..ef1578f2bcb8922905e0693035
> 245c4329809aa7
> GIT binary patch
> literal 12236
> zcmeHNeQ;dWb-
> yb;!9rw7c0^*Z3a?>pY_Qjok&SGi=xc3cj4fozCgtOKwfk1P@oHDI
> z`&L*K20LpRwnCr~k}^};!SRfT={Sj#P!OLZu&@nv8)ZrpXvyGCp<QPk>VN`j;<Ek
> y
> z?%lU~T9VMt@LzrHyXXGyIrp4%&;5A!>D~K$o7THrE@7uKQ7(w4hBbF1=o^2
> mIE_LV
> z7l@_eQn5&!hbr<KcS8nQM+4>x)M?1&$lbu*do(xm7lE0{L$%BxLZB^k%|${m
> v%RQM
> z{MyTesQtd?W_}Ef&Oj;cl3xb06#S*&F&_tJCZ9H#!)OzRZRU1hW}Dafo)vs*fe=
> qU
> zqPdwZ@R)7>E#L!wD%twGz<2t08j{Rx&;G59MtWC9gDawuSZbFy8TYPIJh(3T8
> #ec#
> zr20Xf3z6Bj7MZal|DnNuxgp}4_n&W_I9zeyZ+`j8zTg$-v){H387p1rsFHQxz3Ja3
> zSazlc2S9g4v;-$g@Nfy<T7rj4@UjxTxdby7cG6MUZ39sH^XDb_PfBo833d(&+t-
> )y
> zF9CjhOmj1q^F_4~hSAp_j~PkJpRf!=U|0eijy1yQ*n-
> +%Bxa<NW>6%pL||Y@BnJ|a
> zm=zMC_<$Kh<47_dSi9CpCIkLhNDQQ`Br2gSu+s>HcN!soB+A-
> A*q;!gJ`?OvAR14a
> zB6L?GVwoZu5BQ^2q~Am{+AcWK?~la9hD{x<ZN@6^HN{e6vD8p3v4>^&SB|
> X766XMG
> zDr8-
> moKG(BI4_u)z8s0n<7#>wW!BY7tcimKJYV8+akzkMBrX%r0W+P!nmX?S6b@_
> d
> z^D&4TDGa+wF+nRy5#$<DOvGAJOyq^6=L=Cs>J~yLg&q&-
> g;=koUl3wBX(h&w6rMJc
> zRteEWiecNDKJCuZk=ynh*?yG}Bk8mGe13Sss>ps9wb>`(Q}&xsl%90oc7%enD
> ZhFK
> z-
> scye#V>2~i`k1Xi>FRPOMWqX6DIG}l*H^+m|;3KAu)Rw=8`;hSYq}vtP?*WF?$<
> c
> zN<1bpdmXMP-
> YqeEALi6OH6Ssg5N;;kAu*#7zLB_7Vn!w0N!%<kqZ7WBxL#sLDZGPN
> zmzdECvqPt9BxcmY1H=Nj;g@%2{x$vXna=L6aPt^AQx9wITegMw?$g}ahaoU
> MHYfFD
> z-b1*x-Pcb*jY!?Fe-
> iY09nss9tHbZhzb#AWTx;J<UOM_TY>4!P>i|XawZmjf@wIOz
> zvPUbZz?GiVZoA{isI^3lzHkNQp+9|k;eHQfF@OukS%<;}$21S?@>8!J8H3FBZSX
> mL
> zT0hqAsiR1?3G*#|ue-
> upkTp?cJ$rlV6vlqUSDBvBMnvY7@h8SK_p{tHGe6B7`|x1(
> zU%XQN$VBEROJB|$uYPG_cp|ky3cDfP?$KcMB)rUS_#~f~^_5b|fzME4)#ifPc
> VM{a
> zMZor=rl?r_5Q^Xb?|lAPh4_)0d&eqH{y>$UI|viww4LepXc^6u^}vM#6x`1rM5
> H#?
> znEf-
> SjXZia{v_JLswSJF*$Nu4WASrHJa?3uY24QQIz$f8@P7Uv1S`i+6tqY&X!#GU
> zCux_S{05+?l3Q|Cha2$dvhmX;*1zu%&GlxV!rGT|mETZa+WPNz%B>q;1~x4X
> uv+tk
> z4<l07W4}NdyMo9rg~#L9mFQ@LupOIuMQ3kjt?HLGPZp^78q|&;Dx>DioyHw
> U)SR=m
> zzpkwAfd1^AsyxPWmnusS4x;?pY`ZD)S1JBkmX|nW@3v*PZ`*Ua9&^v!&j)wL
> H{CE1
> zIyU?P*y!5uX-
> TmvJ=iHnho=GQ>I6_mGSe?gk?Or?p<_f=RX;7RyS#eu`>1&CavV%l
> z?da$<CQD|MrxGQE3Z>#;|NU?C`SeU#_3(>m11n^|GJX}>KFbaK_pJ&GqR@
> G4_+7Zg
> zghmh-BcrUy{Op78WsZM5mCm}-
> Gv}wcC^Zh6YQ$dn(2G!dlznyOt{88GJqWq6_j8SC
> zv`?}7euII<>fL=R=5)`bdyM<%;GRplH#o<=gRoX`ugu{drnPjB_UYcq|FYftF`O($
> zFHZN^mCwPwa^>FLbKK)IwBVlRa1XW8J=&*xEk*b0o$d|NJv{tA5BCbudvK0>
> VOT4;
> z=XSVfN00XD-
> gjo~=zRmMV)XXVJv_`m5BD?`y|2%4?=@H}xL4zF4>M9mkM`+adC|QO
> zz$v=-@MpQVOU?5C&C)1S?maZey(?$k({oo9mj+@g-
> J^ZF7yP&oz1+63oHmwojg4Hy
> zCjqQ;1$KMnw$En(rPo7xc%pjvDJ=KuXXGA}K6yiW<_7D0xxRAqvD-
> ZgKe7v9UM=OG
> zY4hrfxHI9{v<B_>OmefD-
> 5*CT;yyaQ1Fc}LlIs_3rIQ;AW~<RGJ>!BAEQj5>3aMD_
> zllS7VP%m+A?TF9KolCcB3#ALJ3k#(SQ|G09ZddL+;9Sj^s@*%0Iw6~?ts1H<Z~E
> R!
> zky?~nq9m%Hp2G7vl&N9kw6C&^@sU>0_H6)rlgAN3q%O`~PUbVB`soQq>&=
> hgw$E)h
> zdPaos6#TjLd;2z=c5a7s#y4s2+wV3^jQXb7F#qd(zEJFjj*Rb(5&Yk!@pr(@-&-sB
> z+gyWVP{ubQ%eA8qL=m3nE*s9>f?e|$nW>j&Dl)zoGRI$@xoo88g=Mc~rglyQ
> Gq1Do
> z>|bI0M|<AN+~Zl8u{^bz+dVZScT9j(;(+4D)~;o0J=rC&KH{6?nPt@X7G3*Cd1Q
> Il
> zyt<+=qyhMvp1l1w4yfZq*MlBrBN)FuM;7TgLY=M~iF)cspXb>zdte&<OS8D_*v
> t8{
> z;k>o1;Ujgf8)^46WtMyB1d5HcoPYF36ipv>t^FkRPI|IV+RDvySQ{Jr@W@D=$K
> gQX
> zJh`9m?dh4k^~L8|3XP?6T7GJz99605v^*q^jXBTxalFrG<FZfkOwY~Gh4-
> 8l5wRjJ
> z62g~A#1lGS%p$QqJrcuvmmZ2l&2{?X<b~p{UWgZD0twS^Q7E3W=1O(M2K~`
> UP!Ggo
> zp-7)>u7~1@e!r!(wE1IKSh{?7`*h>hjxAgDj&@zDH-
> qaCT)V0_67wg9l)fUHZXs<j
> zW37>RvLmRctVlFs4K3FP%|tR1kFC=O8@%;;{hF2aO)FQ`*RR%f=xmD*3?(9cV
> M|{c
> zSf;ajx!w`8%&6WLPYlEp=vqAH)mx%bU5X|3gqbuGgJ#ex+xH~>eF(~Dr#Zf@h
> (JAq
> zvK}GTSH$%#GIkP)#Yz2oL|L?MY3XV=I@(p7;l4kbGWB=}JUtnXr=meU>>o6Bb
> C*A0
> zMThjoh%{b}5eL<>%ePHz@!d=ftvwx^+Kuk7cKXCNU)R=-Et`#-
> TQ+X#nnfL(ffm=V
> z3YKR0?OIfREnj%>>L}_y$mbsfo%%4JKMbm4<-84gE9hC!y`Xj2*P5|&-
> UzxIGz|K8
> zpbvmnV7Gk|v<dV$XdO;a)1VK6^0E66XgerZ9h2+sF5$Yz?OIf+X>6~fj&Cdv{0h
> fD
> zU{U2>UsbuW`U{q}OWbhDwO6k4e1$KI&BzPkV<&WpmMZsfS?j!t&VAbb<>l
> +jj<y_Y
> zfxcJ4qAvcO<~l5eCeWg+^(rJ3pZ)Cyf4P$%R(#qzguDa%7x+xHZS9n{Mzj)JZ$jh
> @
> z4jRp%McI31ZOx#%2FJLYocyv4(p&n<=gqa?uXFMTRcFX=0>20RtDXG#tgp9%9
> |r#|
> zC;yIg1-
> &i%+aoQuyNtzN$m$q3e^Iujs`CEwma3Y4T1!=Jx?*!xec8sUT2veX=P0^<
> ztffkOwFdGNXxojp3_la=-
> auU|>KLYT>0AWPMc`Zn&PCu{1kOd^Tm;TV;Qwy~@Y2ga
> zyzq01q%7m8D9?<QppWj=+<f=AXH0Yd`jdS85WX?vPvPS2uj9KJ=m}uH{7oYB4
> |P0i
> z;`6ple6O9x8!^wJyO8-_F(3KM$aT=maxEyoZ@Q8B-
> JBG!|MAH*KA3>gmouPG0HgSS
> zPW)zWH~M$j`Uv^FVa@#|<R!>!kk=z`Lk=MiBJV@~Hu6E_r;(2$+dBRb^>pwp
> xx=H2
> zx&OQc?8R4H^^Y|y&DPi)Ql<@UZR_-<J-w-
> zm0G!pFWqsy(YwZb^@@g+tX#cJVIjQ9
> zp?=HX3u+}44cjGr;x!Wk!W)ZQrnjZFV}<4KE1<qu%G;ZY;M091D7-{re=;n*!J!!R
> zDQYDYr|=d(2N>Wb%qZnmVIXP=ZzLAMuVwDSZwLUac+hY8h1U!lp@hHRG{
> Ql&w2|-z
> ztau^`bBcT|047xW`y&CEi$e{5yi&K))0>2JAl~0^#;iXy7$v+#z?@5*i}J1p0Oy;X
> z$YZ)3nST$boV-
> &3hK{nG?Dr?$H?ZX%z#8EDvBwqywdLAT#%p<;`nYxu74&fpF;R}0
> z_X)UuD91H*0&+FTTw@?ohHGmZGS?O5xCY-
> wVG?CKQI_dWWUe2|aqT>TMqfeMw#$0v
> zoyc5oEOX6GLaq~Kr(HmCH!{DnP>yT17EW_f*!tK9;xw`?$2DFD2G>62xS!Z^52
> 8$8
> zX@`5vqhNSZwiD%;?nk!erXV*(hTTaN8534LQmCdr-
> shQu!9((|Qm8<p9MfaSwm$A@
> z_keMU<ftFp?q3(=*x$z>_ZZ~}3dxo`2uyus$vZaK%$)PmmV3$}xAdF1%Y(_6b
> @aoQ
> zd#NDDG3H+rdH2S-
> `Pg!=I^_6qy6*SLop8wUBeVx{whpk0<)5I;*wL=MYXrIDg*uSp
> zxcxKAbenR#J8|ZB=%fC39CCaHOhfKQ)Y*wL%voexUo-wZ-
> >lEQy8|fG`}k!XXm<i~
> zhjiR?a*PL{OdsNx`sx)Fl)JJ}CLxcR&mQWs(@%9F&e{N!GEAfnGh*)&tS8K^KSK
> Qq
> zWcGn`i*w$o&$C>JCmj{GK8SrPaX(_Ex{apx9fg%;?k@@}h1^FJrggPnD9lx+_63
> DG
> zqVTuy>@1f%mRjeEFV)EPtT20_p3MrY1;q8KFn1`duOjA(R_l$lT>h0(ofQ=3w=
> uPT
> z6vl-
> YB(4*M89B^1tOtcTDr(*<%##89!TeEJ?bw{h3iCvv=BvW$<iUBV@RvyB8AM^8
> zJcQspQ+T1ooKFg0EV2Dlj-A0dZkqU2o;~Keq>KwUySR7Q{<-
> i(Sqg0X=fa6+H3e}W
> zg`^Dexe1i^sMjSf7JmxLJ0=`S;xOnAhkU7h?kx))_V)l+e#`b}zIYheY5y;QJI7}2
> z{{Yxd?9Yn;c7J$N?H_>cGm{G^xu2Ere*w((3<7@<PdLcCH=L;p&_6!2PNF}opO
> 5}r
> z3ffw*zo2ZMSPlH_Lz?^Qg8YrZO&QJ2zu&U`c3^vableu~1-
> 27sg9SW2ihTlQ%Jc7}
> zb|U{<z=vobsRsRfyoCR~68sWyCG2ClN`3s|%I5;xFA!DY$0hPP;5Q!7+)V}fk4yL$
> zI5rFVvj~_sjHqvZ8RiGD-
> M<?2Z*_^h&w+Kc=>~2u^k;tALg5F#5Aj<E9{ZmFcHRTr
> z<7iL&-v;KlPtGrn$9~{OwC6lzdwx>26XpL2nAfQMD3kwQ3E#QNQGUK-
> k0bT~YxuT{
> zqKyACU_OtDsgK`f`8-wrREukXo#WL8ychGI-wr5$Bk*bX%fFcuZv(cIj>6Z7e+c~;
> z2lj8s!KXhD0`EZlHljQq@qUba_-DuCJHYn-wty$FK*CB|sZhupz)i-s?k!!$rjD)M
> zxKU{s?Q_t^HU}#hH~OOSUVqe(2U)|P+9hyE9f+D1zE-
> ViSiM$|VMKzvfYvk!brue$
> z`um4$JHE~B(#-
> m<mYaQsjcCR$&sveEW@)AP(M>wc^S9woB>Y2$84C)d{i~Z>ZtiG<
> z2?s~s5f#RUO<P)9HW^#iuixtHHo99{H~H90d3!UEOd0b0-
> odYr{5G~3XLqVu)3nBm
> z`=7=@z_7xp*iLWnF44)mq&=}nARaWgS^#~b6CcCOVq?LxySfr8)Wy^0X8TrXz
> 1Yqh
> zq_bb))csPYfMLqBzq)Zc%V-e1a5{_Y3y$!!piu6Y-eH{;ZdAgp{#eY!l~(yBbe3CR
> zxF_qZDNKOkU^u#j>#}nt=iJ3Lj9@Zug#EE#)D-
> ykh}S8rJ6?!a>HXZ|MOvpqM{pS5
> zfla0#7kc})hY`4~1OCA8xOMAn?if`0f>v_fcUJTobsu=PqQSoOJ6lyR)YK}>qR@a5
> zz6%or?`4GnmUn(JWun~}ovoI?e?S-;2aPVXFOtOTXj{~uOqxkC+b21-
> 3Kx={cGSn@
> Oj(!g3>{OC7S^N)t{R~b3
> 
> literal 0
> HcmV?d00001
> 
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/GenBiosId.exe
> b/Platform/Intel/Vlv2TbltDevicePkg/GenBiosId.exe
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..323b87c444915b173b7f32d54
> 81c67e4471b047b
> GIT binary patch
> literal 384000
> zcmeFaeSB2awKsl}OkjWs6ExANh(UvI0U8@yL7)a?lv+|Vfx-
> 8;ig<``RA&^uM4^+Z
> zOpeo1B`vo0Dpzl>ZS5^>siFlMUL;_#jg<D%mRo~QuI^z{jT$A;$UNWg+UJ}(LxR
> 2c
> zK7ai_pC5cObLQ-|_gZ`HwbxpE?REC4zjl>TWEh4If7z^IY`{1F)ye0le{`XE^ck;=
> zHr9`Lef)-kxv!6(Z!W&Ca>>2-
> +<xyZcU9hc%iVY16RrHpZI$=N?yg*XcjfFW=T+Wy
> z&%)a#mz0dGvYY<h_l6Z)N6ZDz-
> wV@ET(DApFJ6$r_t(DGvtXTkf3o0d`OYjDCEte^
> zwBoyQ@vSE79*@$7kYUU%C^FPd$$AH-%P1-
> sRWQOZ_M+ES1#)}UG<=ofua}&t)7OQD
> zQH)>w=X@KL!!)yS4}4oLfUL*L^6h@{rqRB)*f>|NKK-
> NfeV;M*Q$Y4@E6yJi(AlC%
> zAF|fu=xs}*DEZ+Y^oMk@uk4!VU!`H(Jo(;*w?uC-
> jH~~K0`~n~eDBK#tOG+PYcONy
> z=TP1SZk&Yg9WGb!L%7y17ytjq|7SQ5v3kNCp@H4_hcA+?c0ugp&Hm!($@m-
> |9i#ej
> z1BF@qOJ9j=b8c72utEWAjxVh4I1$j>{fYM2Nme9a&GI*xl?9g>YTgNQKQl(X?5
> SSL
> z>J6-3AF#rKMm5n>oh_Dz&AK8~FLSFu<f;A!B%VaYE-
> ~k`5h5&WQ1579p@HpIG@5mV
> zXykWe92!37Y2-09(otLq0RHPJ4uD*JRb}5ZuSVm#8@n-g(7k5~9-
> kqVV&kO9ydFSm
> zV3d?Q?5RQ9<}%inUVOu@O%(ANf(W%)WG-
> jz&H1%I02$J~FPP6r8|=gtb{ixvK0`=k
> z8~9~D$2K0yZ{y$5hWa|lNVG?7LU$8vUOw2P1iK0I7htDpih2k(F%K+rtB_NrVlE
> `{
> z1`YtSFduTNS;M<MBgqe+>1Sg%4c9+rvt*B5BE6r(JMD7EZ?iQzdM(-
> 8pq}(gEt_A_
> zpjAS~h1Ck@zVHC|%X!hL7VG;~XaI<(^{B-
> db?d)w*hZP&4f!_jB(ixn`X&5vnf>D#
> z{+Me2=;Duw`Ujdh6V2SPjrF@(aH0*>!ym)!9~0lgkHfGe8uNP?DjTmL*Z5cTRK
> ZeQ
> zmD;o)Q|RSgVEhJ_e)!|HHQgbj_SIx)ptgNcGQr}GL>E2*Vpt{QM%d(!R9pYiY_?
> II
> zQBF*OM0>CWCe27Cc)LMWU~oV{QtHMxNei*U%qA<v%i!iQ@gry9_fJv@h2
> IUSRPQI*
> zY}l*;@m3o_8r7>ZgG%H5h0(%Hi#Y{FsRY3qRBMo}bAn%!O0j{k8ZOYjc>nO&I
> Wp3z
> zHWoChzrt_;Hu#csCcd-4?p9`8({OV(8Z{fpu?`urzy?gp<>~9G5?Y8*)1^-FAhg^4
> zwoGIoEC9ljAX;`;)Ljn36uB4QRk$cAS3p=`t|G#xh;V@yVTN<GlL*_`!$$S|=v)sq
> zi_`=MVG$6XN`!XT2f%mfVVfX)&9^8iS3p=~?jyo3BK$9re7lDa5n<W?A=R3t7kL
> oc
> z?XH(uZuf8^5!zk19E3JY{W+Evn3ZVMoQMw<^&%WWgf|nR&C(quxgOf>Ug{
> w9p@(OB
> zSbD01&}M0Aj-
> @_x2@x(Q!XhuiH4svBJrUY0jkpLGI778Zh7~<51j5N4mi`a|;ALs0
> z!_w253eD|AxR(eYhvNm|7oo|VpC<bqIqSM4-
> hWASxGoBs7ou@>mUP2c+umrs-jFIU
> zJ-
> N<MkASMHuf55tAE<p@eFc+g#dc0jO!m*AggRptei{{k<;*g`#;b76LF4rmYy)U{
> zJssEcqW505__jM2F1Y2+*lq5wFW+*P{FuA=?%NFNpS4t94NV12SC|GVJ6y(&
> V6GK_
> zWN>kLrm(ghH2f?uNPCF>TG4Yg2}x~w9yGm7Pj`_1SnG!-
> Ns2mvw&Znc0KisxDX-h$
> z*=L_A!{y3^50~bLXrl?jQH&p9^~F<!v8lEfP^D38?g%hqOi~HngT^2`!s?r%_WZ
> Wu
> zZ7OgS&><OZp9^>LP(9S+u%-
> e$JOtC>j>Dhf0j${0E`kR?L5Yk5WWsm`u+BKVifhs`
> zi`~cdti|`-_r--
> 6fyH;<Zp^wRdaHTa;yZ7<^q#w;x7{5z9PKOog9$TY5QNMnR>&XR
> z>`&~9)>;u<6~_B3qbFJQxP*!v5gnz=<A+DaMgbtcwICVsXNqw*<I8NTZKrC-
> c(T3d
> zuy}L8fKsh?+Z>N7i-Io}!n0YFEO6_?Pl~q}CPRVDABL(wne|^HP2=dzg#4}kl_RBc
> zA&^Vu0#@FKW_J`EYh7G=KuML`(y6GA-
> ZiLT1xL|`9>%v6ChPr~{b2DG7{r{BVt;xj
> zUX^Oz`!ZNRSh7-
> ~9{5)%K|87Xp0N6rzD|bvtw_H$%hzDl_gi6qqlFuD0%5sX8gDO<
> z`!mam?}UUu`SL>4I&`?vtbh=vBKsQE>XX^zSkT;%s^1q@&tYsKa9T(<o(dt^1G
> DN1
> z$uC78PXzfEZc{>1Uo<Eq+X31GF@}OSx^cY^*X+oCTthnMFUDlNG^W2P73eQ
> <s=a4O
> zm(bwFXfTf-Qr_p5pPE;0Wzj;@QFG}I=q2OJb;iQAz-
> BbWxA)FlaFtl}3qt+1uQsGY
> zy$hdZQAem7G-YesDL28k_GG9l-
> rQxthr9WM*_eh+pD_(y6sjeYNK+ZDT)}REsaE^X
> zLkqIlav{y0_h&=BqmCLqLD$%s&0K{+w`K+6U3Jj_2E1b?w25J4X5e<C`u17UTie
> 5z
> z4ql2<It`(2+y(QqitNmkpl(<VtCGTPR;b&m?_HS0{5FhhZo2V0*ROJBnD8Us6X*!
> _
> zAJfaecyk|n`JC?MwN5WvCu*AQUIJ#a`uJQ=FEymuf_hR}oh#Io#dl`YUjrTJQ8F
> ?B
> zcMtNm;y@gCqPJL)fkw6D9=l8ZC~Qz~+$BGu?ZYahuN&0$O>#5Q-
> aNu4851Wm5PxW_
> z5rw^xR>y|bFQI23jwtDvCChRYbkqq;Dd>)OxqG)G4{HX=gF22pcm!czym=p4R
> P&(-
> z!spFSEeN+)6T2%2fSIg*e~yPm8q#bhi&$9|%K!_D9s@&Ckw7xit%8+kr@a!kN
> A-=D
> z4%rf*KB9P|MD1R}`w)Zu80&^6Lx%r9oYH^3m!+i;S+&i+XGQims*k_ww3d^c
> GWCoN
> z0(2A36aWZN*QX1R@GqPS0mlGG3Q7>F1QYc4kFte;ht(o-
> $A#ba>F@!&ee{qMqHSns
> zdpw7tCq8ryhn{2Fj|>fMw;%8Ei>82sT)S&(@y#EFjNs}m$@&2?Eu*b+E)3$Y!Tj
> `R
> zhC@s-q6Wn7Sprf*bK<AvZ-
> ~aMEn25J^0{G<e0Cj2KB2FOuOrmOFORhDk2mk9w3hbS
> z(z=dfTc}>f<n>4^U?!;vP)x4c`n*X<^C^C?vbw5LYSgx;7r^Y-
> ?x8IWwrx#DoC&dv
> zEgMZ2NkyPokdFcrVv^blt>B{2kQxOmE3LoFfP&5rj3;dTp+BFt=g^;%k-
> g}|e2rm>
> zgQ4%7yiV*ThMT<@G^EDB%Ia}S`*vdZ7BHx1Q-
> %R$8gK44VnH=Qs#XXCGf_wHil>p-
> z6FXlOyG?h5Iss)g9fiSYFgfsQ!#CM7oPo~FRI9!lbD|V;A^?jD)%;Hh7II1+qqig7
> zjq1zeSm^tdX{Y6(&TVc#d|Tjh4WO21&!|Ht2aMQwvrb0c{AbYW@T~o8;ecbW
> 09K<W
> zLJ>Kmk^?qtP+OW%*9nPb8yG*#Ofr|_%juuGQWJxIY6t3KBTBz*xcVd1i6v(LD
> r;Gl
> zKXZ5LIWQ3Svew)x-
> &KdU6yZno#MXlNmV%b{=nQ=$_8!U$UdbLk`fyQayf<6BHNM67
> zL!+QzMO0Zc2LO0hOLz3tA0qN?L`UPx$YS;Tdg{S!rX=;?(TqR!;3t`))Pn;+60mWc
> z-
> a3Xj_Cy!0JUQM`U?V!1DNf?2PjFcUHZ}{OHogO>abe5H(Q^)M6>KN)ThMhRPq
> t=P
> z`ES~`NMG!@ywGre+_Y__UFzD~`BgrU<3F^OU5-t+3NJ2*O&-
> }EJ^SKY3StvRc1KU&
> zqDn8GSr|J7H^*FjOHr&8RK&OXMs~;cSa3tOtvap!jV^d-
> +YW8T>@%Vjt%Y!P(abyO
> z87l2Rw6&1;pIc<1fbIVlcXzP;SJD0^_>!5G4n45~hDhQ)Mnfa?i52oSA%b(V2(Tai
> z!nId>l@%&!`2uKd*7{)T7py-
> en+G1AWnJd80#k}QRxCS3LXol2R)eqTjTO^RC7x&*
> z%jZskIrfDc)h^68+UC$eUA!YOZ5TBBvdxZfBJD4*-cNiS9iP|}J$;^agFo??XxUZk
> zc3VfS*FOA_Rg}EUms}7?*4}j8jW=xddDaTV<<e(;01E#!?ND^y)Gv_6xvB4gDT
> YJo
> zD+Hc8|CE8)NUP3Qv}I~pMf4Qw%RXy<5R~~E8`PPaOaaWJbz`Pj-
> ;DWzVh1Q)fF>?S
> zfTbVTS4=%A7M!}EEH-lLf{Ix2)CFUsCtCHss}_V+r?eQ*l`jiSonJHHmaX@e-S4|H
> z@p0@$&6E5tE}yXwM#PAn0rgsdKm6ZO%v%L&d>i~&WvwQ6D|Ga1_ig~$V5
> $J+P<T!W
> z832A^{@GKb%9(y&cBWr3Ic85)XU2Z&eEcltW0jtdC+6nkOqu1?TehWU9wk1x
> `oz8B
> z^yEEF5B+nG{ieOw9)(%=E37K$!l4tcRLXeAdoE0c_9jDpuoGc*9voS5i3U8DsWa
> Z(
> zN#nOq8^6z*OL<YKHi}>6x@v%#tj>jsb97*nhBR-
> c0%T=%tt_|2ReKS{)b5Hmm%{qN
> z{KMzp?QsWd9UNEZ;{Z&x+J3qRhlbQR#2x$?mWL)8>w<_C>VxO{MWC|k`@
> oE37y`<k
> zCjBd#5zWXxa(}>z^mWW)XyB2|2q_#$&hc513YeWTn4MCXpuWZ|mc%qX@
> UC+nu%0ie
> zP?_t$<!qJa_;+Px=WyJCcl<ri__XiE_}rNX?aasHv@bO-&Z{BqV|})7kiWC>IQ|a2
> zO?tnuIrUhWAyg2gI}*k6U?X^D&;i>>J!wTY!gYu@!!;OZuKU<_P#SnqsD7!P0m
> l@I
> z`!F602UiR(G6`wc@q?AsJXrwKeQ1Zar4+yi`aYz<k+e#-Y&1=gia^nrj{=f5No_vO
> zgF-
> `U6s)XzVPmz2asyFd0ZKu`0@M*SL!+4Lpm<N)W~Ubrv`OkZFA5E*QLwT~xhRf
> +
> zM-
> memjxPNTKVa3d2H~ngom@^re6AbRovhz!MRw}tYA~@zWOHX&J$;kFB}3ce
> &D*ol
> z@%TI%J<W=2-
> *N;|nC<bdGq!XMEAq8H<GT#L)&>sEh9!!dNgG<jRh@5j9tm#V3OzbA
> zuX_FVEr*NINc^ocw!Ag0s4OMbBkNgxy;KjaZ=F-
> se!yryJUqDh4VVoK{yJyy*U8|A
> z)+Iw=U^@rj_((?POAgyMU@mgD*(+MWOj1>+dPYV=+H6B*wLlnBX8YJ&>IY
> kBUNAl5
> z2jTVyf-
> PU?Pb|OZ_~L0qle&{v`0z8n)MqR^15Tke1`(bKSpX$NFUW7$Z~!DrGeP={
> z>cdxUUcO*OUeKO(Hg=*F+CMGikD-
> 5EsA^=+%Z#_`_qRs&twehv1ex~32T0<xe<VUm
> z#pyes6R_gjQOFIz+*+?hhP6xf?mo@i+`W5R30>M);fLGO@9#DYcfH&{Xnr0qe
> j>9G
> z;kHsEM$vi!WK)#OhK!}uo27?jLRMk&dB&v6fYZGSTG5@58qyqq6zf>ZR_P5U
> WM-}v
> zDQi?;(VHBO(7KAyUY}kHIz$}~il3B))ec?vzaKxDeoQZ)gLmiYrL*+1BSv3!die!R
> zPERjo>GdNh7Pprg(p=u}^m4yYMzu4OD6sTmP|CCPx*niVJNG&${sKYvppd24
> <z5sT
> zQlnsH^`ML5uTVR%LA84h#RAhprKjx@;o|b^T#e;E2TLp;i|Ee-
> &@FC9G^EDD%IZWH
> z%TizwC5~8CAo$bz(qw&)73q-
> }QJKVu0+_;x?ncV2Sry4pFDHI4lOnjZ3AS)=*s3qX
> zcJzw3{D2I$yoRxb<>O=vwrt{$`m*?gKBM`IXe0g*F2<WnC}-
> HXLaEb<b+%;}J)m2R
> zzgCHck_}kQ^;Bb@kDN$%P&)!)WMEp@cOM<uB$j$3q=qjU>BPb>8B$igg4yk
> +3AV8A
> z`|!^k2UzNX>WFgs=But(AW3uspo;Xbk(ixDA%)dwdcL3<m{#8#{MtcwgggjLU
> ^k<c
> zKp0lju4lVGYy+2iX*>%M@#bD5dIHEJ*}eF#-
> U{218HP9woE0mwI~h?{NWnqi8WmIK
> z&1<Bs2K7fwbr1_*A>Q1djh(?h%n8JIRSL0r%y>n3-
> 9Ig)?)Rh1una&D=}*Eugm#Kc
> zHc(yPhu8>sQ55MDlS1hG#vY%;88dSuh{BRT8R-
> IUP}qh2<6R`m9|u9uU+!>ZrlDnt
> z^}|>V#1+Erh(uw$D~yL-nb}U6*$$py;I=30d(&I6RJB5-t{*ARC;j31RRQ{=Fd~a<
> z+gq`+Ye8njiX+@Jx_5MZ#wwUDBU+qZy&qdT*5UXO-
> @O+c`cwQsQ8ZBf#>(MXQbOIw
> zKDKsl>GBtC;a4fXUW>m~v?W~_9rodm(eOwOcaU(hbi}96cFV>8Q76I8Wq3~_
> X)kw4
> zzdi9FxxGibx$eqe_dx2$d!}fA*mg_koH}j^{Y&VF#pXIr;X?H*?EyH(PaNQLpi14
> D
> zt0B#20Ip+|*U0XtIKbqJC)VKjCAO1&w}a!Vd>rsgCaZ0j|1J&<sd0#t{ShM8)LIA`
> zKZQX{(HB9;7@n|rx$uM$AfLtIjPy}=%!2H}Irb;VKn5fX%B_sPM)lMUY=~a3_=a
> #p
> z`ZM)(k!`!&Cv&e)>@rMgpEU-
> yvbNo}%sb_dSmr)h<}vsgZo>Z84jGYT2r`~?rSsM=
> zL;2I{k^@4FSLhsn+JUD(o%6ue4Q~q{ay1-
> y=s`Q)S_TbMiW$NVBQjc@U*lMKwtq~G
> zClzs2XdDjwShs!eBEq(vx94g&@W-
> RS=YLFpehsI6Cq65Eyy`8s>L<lRmOn7K+*z+U
> zt4UQWF#rAd^rfEyAMdGIaFrW(?Soj--
> O^wE{PN6^E_?H6{t=mnA+z_e%)?skzBuy`
> z4o{7G8e8t}9MO<wC%{csR&QV<5OYK#ap|x75QD6eY!hM8g@2d0AQ3Y*i$#
> OugS<d|
> zM$;Sz@hjR8JBZ<f)Tpz)h&7}}%*yI&FX9p)=BhNZ&kF71G<xKWWtfcn;!}<L%G
> G~D
> zSLhySGT(&LBG7xS&|W|fUv}mrqpbS9E2d`ese9u7a`nP775*I+)a@{RAh}UU)`
> Tnt
> zAt_Gq%-_icUxRuakPu_Q&GW#`Asly;F2#5VT$2ko-
> vd`hxcdIE`kn(fOT!7ZH0k0^
> zJoYab%}3y&cdnSaysyXzejRZe_!|9BVggzhRQFmleWz_r#$ddAQsMw$O8O5G
> HCCw-
> zU5>(G=uZE!5cjab7QIrG`R96tI#_XRau1*}RSn(JgQj3oJxy);cyLn|nnEKTb(OSl
> zY3AFx+8{Lq{B;iMiv;y6?>VT?!6Mo!c+%QweSjVnfsX2(r+q*QVsOa(9kT>MrUK
> P0
> z!vXWafc4YixIrJO2KB^IlHmq|o8d$FE$m|h!k>hPqvC41Ro@f;6Ba=58i>G}<$Kc
> V
> zwT?(T*tZ53Fdm;EQMdQRBjjmwPacXI8^uh7I{ezLBNAwKjfE?&A<_5;qq*={G!
> <@7
> zcA<zpnThx%(D>m!3L10<K>p+v7*L?8@b(6D<{H=skzyw!J@MuqW7+ISuo_av
> {pdcN
> zKlHkyXv>o?569RYI*f*s4QPo4MOVPl@+aqDJ6QkZZhLah*fiJMY$^E7Z{TX#NV
> XP?
> ze+}0hz%a%~rDhin{|9aQ;|~UmN9u$Eq&Q$viY~%GRnob!snuidf;<U9V^P*Ivy
> }Vt
> z0$v6$OTf#pSd|Jz4TMRC$JVyrbYsq1!JlG0PfTxN2K0}`pjL>p=@>2b&@jqhneE
> 4D
> z_#VIdJ=VssL9%<nO@vBNg38znP9Bj|1MQsZ9fl%I8jt;o_mrkW{SDc2qjxrV(!U
> ~Y
> zEdRnE;Ciq4^Iw1VeZ)h}<=<XoG=|k=I51dHBqQAH9=`09M@Fn@?iEcm8cPf~S
> lNzH
> zAHUdx=xB1LzBdUu=u0+0xO(Y*csBFsKeE5-
> k7!qo0lSXz&g^o;w<<c0%|AHaesl6R
> z)e+i{wvhjX0l~%*_GkZVTmiKiVkIM+#;S{OAHUQkCl?rUt5h*99=8Dc8bXIGytk
> ~t
> zu}bRgmzX%(JhJIDWfe+G*>WFv_3ZX?WUQWhLV@wDiI}qbMhP1PoL}9l;nZJ
> 7*|$ch
> z27L=S&MuHf91RD#Mbzj5U2K&+e;7$jB`@I9D(7|M+Gp_DV3j<Dudtf>dofjFp
> <wn#
> z$PRTBEvld5!;V`p`KQP7TUZgm&`>uZ>EsL~%0aPivu?u#*_VvK#7P68{S9g!8~8
> @9
> z0YpxQ+R4`PHe(5TTNo`?e*<4BXzIc<q(@><)kVefgM;bFr`Y#8Ov3?@i-
> F)v{uPJo
> zuf^Jc!ise!yw!oCS<@MAg#b?Fa|}{68H=OfOS39wfRFkPW=?<n!RY7*SQGQ9A
> 4dBX
> zcvx7;wzVH4UK;;~If%(<(Gq&X@fqzHI3pJ5D3%Lo_{@p=W?Az{eG@rdhMC|;l
> &(i%
> zlW#3y8`NP$126%feWsWR%KS89mw4)|^wzOTSShTw4^e64hEoBW{uw@O_
> Xmq&<Yq7r
> zixau5`4li^OIL9*>Bn5Q%84!MYt8J-RluBY=Nb+bikcSzN}_)QI{Ih%B>EShUYLze
> zId0j}D0q6DdPc02We18oR$L7#7!%7_wJx9a{QW^an7_HW9r6j2T&zxl<wJ5w3
> CRts
> zt1HPczYKuDuW0tONB3Tci|5}C84ob4Y!Yv6=`W7Amo}(>#d;i*5IT}!ir0+gwq^}T
> z!cKfkWjI^z#{?W&UqJhmHJ^nxrLAk6wwQtMv=u;%f^7wkY3um(Nn|Da2;+m
> WVKg;)
> z6xV7j9{K|RkUr%9Bcn&R8PIJC#qXRcz4y@Pwk7ld_p?he1JQf=9bU^{_6kIe7$d
> c9
> zV}PN}+t<)bk}L#lds*geENEZT$d0u$=w+jVb4gM6Oe)Qvo+)tl+;r~Vj>Jx;iQ-?=
> zT;y3McH>urI`E$8sZ@%E$@>0OTP1=B5N+59!geIa;y167iB6WJcJs4sCqKWxou
> 9vK
> z=jW!4_+0c@o06{-
> x9}G|_Wcd=l~^xd|GG}Te)0mop895@3tt@xqAP%9!Tw}2u@65|
> z^}b}Pn->wEHEST5*eh_P?_{6R-
> XVlT&0wwpa4&9W%PTR82+K4X+48ZtOhx(|v*i`M
> zDdfjDNhh%B%<Qj`;O9f*h5aU5%$An{5{9)DUr?t=!~IJd5|p!ndi?C!oHvZKg3d6?
> zP+U6N{t53%kG^ZebtJ<R&)^d-
> <ZE7gA2<zA)4CMc@>Br>Q3gN5vy}c9@FwSHI5>_E
> z|JL#07bqQb^wSl9SV0%c?Cw?EI7!yrn489V{NUzXPP<LI?{sJ)G%&5~^_|cfG0e
> dM
> z%lGPTTxTxIV5`c1;=S0+@>e}DVguqKM&`^+B{a-
> NT;6*EE?&b0iu^1Zo+*|Umdgmc
> zgBrj32qxX}rbcW)bjiq!&IHsKKra0@zpDT>yl1_tJ+Sd+&EL6fG&iBD*(nA@EyvOi
> z9CcQX$RC;Dg)lb&OzNq#A$ow+Nh70G2O2@YEhCA{>3oW9dP76gyO|aLNA!
> N=p|?|3
> zbjQ-`LYNKcqNewLSv|Y-
> Uj7g1ZG(==@wWzhS{Xm$pd4)pQ#j&g>o;{<9{hz~`23KB
> z@B{whltKPt_i^?^#Z{%)6mT1CFG!a?(7mDuxJwQ%35)!3X8(W$0&X$a@S;%tj
> O)VO
> zZ~|tsIvpy*jX-
> Efa|ytuvbs_{af#A>1(iM9?M@=t9F5~E4vzYK9FiINGHkGmLqlpD
> ztgJGJMRXVmJc=$f1=TfUMRV9X!74Gin^@mXU!xmKNXH4~HX01%v`7FuVTG
> Bu$dO>;
> z-
> @p#$ctuV4sMZ|6vpEMX#GkT<3?Fh1W6Iblh;pY4D@rz9h@__aZp1YZY3EOA--
> m@j
> zhW;*ql0pjn1g3J;VzUZPLgvEScJR7aW>3>24j)43ipy(k=7G&wMV+r1kv`;*c`s4T
> zg5f7_S%UH>76JG<P4GqQ0WvhL7NVg-
> 7*@iO?hf!C(+77n%h0QG@(y>B?2INq^N9H*
> zz|3}1T-
> a2qUct&#Z<LX5F>ZPawS_{hsFJxuwjQ6s*12($ho)mDcQ4=}c8Nryd!ayb
> z78bcS0T|cZM&&4s_YY5%@g6!UPUZ*lF;k&WjaXv87M(!QwBHdMJ8&!Yhgz4
> 4V*m04
> zqOQoPbKC#E`b@0GZkbu&^%<OipZEgt<_cKP4eVk16{sC~Kuo=fXE%Jfmr8a0
> C!WWk
> z4X%PA#gc6b6z6o5h<upm7GiPOUVx8P{E#YbtkS3gP}$g-
> X;9B%c?!}}3EtPMjIi1~
> zLs%8>ue<+dEF>D$PxK9}FjDhpE=N8p@KE+Vc-
> 9#qqiNXMDbPVMn(%7aVD)Qn9Ns{@
> z)mz@^;_a~7GmUM-
> mpxBo<`!=B9N9OzJcsrqZr7;KJ7~**_Umww)Ly6x==;PzG_E@E
> zgEjzT((Et9swJ@(w|8b|8<~;%dONP+!3AF$gZ&ab*HHnN3Lq@zcV6)cP9wWf
> ^1R&$
> zuLUZEM)-
> IJknF_0XY6ubvz+_V+*&M6wr$5PBH*`Mglg^hy~?h}Yh8vE6VMe%CN|pD
> z`0W;<+6MeyZdc>AF2iyW@y>x{YCWr+BTVEjRkCdzZvZ{N32Vt!GC@FDW}?j(a
> D68x
> zCgFIk+r&7a?0J^i_;@XCq{!H?)kdZ@S_yKc!Ai07xXF&<Ci{e&q#rj)DsB=hZW0
> M@
> zvOR?L`XLE^t1Pu1Bs7}sM_~uDh!mULi^a2X5bp+c+7yb(Y`B>8Ae+yJz}=iLaL=P
> &
> z)0s^tsdhYaz^&2eDG1vu)jIxeql6^I{cPr}xHZ3WDUojY1Rq|cA75<Giqzj^R+uM
> X
> z!DcQ2SSm%b!s^0WfxuImXg<D)pGC1TAmWbCu)x<;q{hDwGNi;88!l6q4|ZuU
> _oKhs
> zUar<Rj0R!5)jus1fQ6{{PpdDD%5z3%Sdl6)suGME3-
> ?p+ov818NUF+E!J|n${_Q{3
> zUlDOgj;Ft{|F9$UCRA!4m<4?vh%0R(x)7p7{MN!Q>a5b*Vy1E=LwgZV1Z{g8C7
> uKu
> z1-ckCJ+LU4I2{c@^FdJ{J|_#XF02reVFbIntT|=L`hDEp#ojy({Lx@bM)2*sqaFHt
> zZ)$#loiapYSl>z0g(s&F{_Dg({I3X#U}1fyO5VyiRxfBS;2w4J7<&aJdwuE0DGs<D
> z{01Wr;O>g4x88SGSM0p_jH}l%j8bXxTfGm3iIKwsJ=nzOwXlxieRc?$U|amE5ok
> 2s
> z)9Uv{PnP6tP|&E05iwF%*bwzS$vN21M^R{RgEC0~S|PFB)))P%_bX82eAq5?H
> dq;d
> zsO)I;blsZlo)g(CVzZ6_ki81NSpOz;4*UeWNo{|?=^^8V7=MgGe9F=21Wqtm?S
> K_P
> z8bm*x<WQh!majI{uXVh-V?QL3VFZ>46qgVJ6{uw<!T{8Z3K5E{GLhG?-
> a}^^V4!jB
> znyhGgOuWxXM`i2ISwaasqSweSMVp-
> OVZ{Xo#8+fj%YTpGHly5H8FHn4q12(kB7?w)
> zogy0SMD;qNsTi=4YCA5d2SIt>4yr@%v4LWc@l}^vX$<piAX6(TYoo2m*p5QFB
> D}|)
> zh6eQuM>>!!P(QY#fTf796=t5zTX5v{7u7bxSi{P>^Hi4~HLw0}``_+9U>7hNO+N
> KQ
> z9lx+S7N7AHVjIT&k+u9rAbo0a3oc@xR|Qx`!W9^AzEA{<Y?u#H^UdLPp(;Nl8b
> mL(
> zI-
> ~|$N4T(@wHacQi?y?1#*^5Hn=uC$Sw2d(Z(0ej`AFJ~t23NGvD_B$J`o8rj3bT-
> z1OPnN2QnJOGD05pGTICXQ6d?J`avD1-
> dIgerqWb&Si13{%dth?A`lfCB0UAJCuDEM
> zTa1syj}%77tep;;;#~zX<YjbIYr%+bynhnq&D@x4s6b8gHUvkY!{A7!-=?CfXS9he
> z9`;2qh9ne3FU-SoHtrQcU93EYJjBm0VFzsTfHc0PDp|i*l;T10bNED+tdkJ*cW~ZI
> zoF(Ki^PuzvmlBBf?suH){m4+@$RHCBj;>sxa8_XBEBlX12pT&$Pz$(K21$dwq5
> @V5
> zbQAFr-
> <7Q{S%v|fR`0)mj8)FdBB*1zfYC4J4d|il+SM#U;Dp~+2|uTmti&gBfy?<T
> zS<YYa8IR!;tC+R?22Dr{<~nJAvV1vjASPbI62>t=lBS%2^3voS-h$o`*L**1LKqeg
> zMFCNjDB72tg`KMXNok?U7ksgNE?5H<x<B4Nwn6<IDhQq`3rbi3NyB8{pPE}*8
> CGq&
> z5VsnGFBV^kVyF@1E~4lmr)YnCYbEl3j#&@*)RQ{!^Xcn>JpFV`B<S1$nM}v(rV
> HTL
> zif%d=7l>OY(ce7XM2qd{KZvVw{~a5+6k>K2J%Q8OC2-
> x38QiC5@EnM}GlS=8AHWHg
> zKqpR8zeYq+%QL3C3v70xwltyMJt&kyZ+!`Z9sDURGZvf2D8~|NbeYI%ldQ<0b|
> q}X
> z<gb8a!(iL&%)iKZFvgS%*SY=4<5&I;9S2D<?M5%4^7Q#9@7g@;!^QFSxu^vg6i
> =SY
> zFJ#+~l;%<7=-
> Z`(^ljg9;vLYimm@(Co`Bs4TCQCDFXdRVS)5;70_G=tj>^@CM0F3f
> zN8|=?a^qj&KGhen5HtX{k$8T(<M8Q>dpyzlFg#jVlk~5Oso?O4>ghCHv6D3?V
> AD#V
> zBH(HuopTLAY}>HFDi`B$uwbfabr^?kxY%Cf@R~=o`ei|8$F=f|Lx~s%Dl1-
> C<zgKo
> zDrX%+YFhCz*5SdNJ!fhlorVESYFLOuuYG8gr3>tX78bK&xJUbcUHtK!edrr@tbJ
> H0
> z5VitF_n%}ev3X$Q{WnXy=jB*A5H{DLx@}ns)cI1g(zZP?_5%(17Gs3BX>}c*F4u
> Dm
> zSZW1JX#t`?ky6JR`J&fiJSK=C!TBlm$8_vwFY=#E%{P35EsG@(cE>Vd(Tnw3FZ$z
> M
> z$WKJ7N(c5Kpc<iUE)auP>P2ydw*mE3#)%1m{3uL@I5#iCpA^>@x@KoFnPZ
> MYnWJmo
> z!DMu!OPId#gHWW%lS7(YSrIL6zqYvj1~<|ARy-)?i94@-@rNpm=y-
> FAZuB%yqmO$V
> z%`9YQT)52PVPOob8;6Ht)Ok`AEKZ*`V$;H<_gz5JO`o)^6@t1^7K=8s)H-
> N89sfdK
> zSE9a5nF+Fm$W>KegSt!XHWoL%Tp>t8`Aq=KoCVzj8xC1TO3+eq{qle=1`q;q1B
> 1*r
> z^zgFy3^A+sO|>GuYk65ctMplZd(81b&KwU6Hpff_5F=bYr!*-
> S+6ouJiikNDdp)h#
> zw$K8R6nhPnV&;0-ME$_DIi>ek;U1(KL^Qy3(l(-7xYJXFJL<YWh#L2r)gGW}RI_w}
> zsOQt9wK6f{s97OKycesHB(p<^2wn)e8~coW!q)dri}YdOpYe$_#XST6BxX=fn(B
> L}
> z)%WrE3<wYGc~AOHjx&0Jhdp61d$C6kViAU&>B~&9O6X>=!g$lvEwA>pd`Vu
> *sLL3t
> zI3{S1(bpgwWc0O{(bvpH+FQ}>U8vi8+SA^9m@GL;NsD$)95)D0W{V$$jE`CLgO
> JPN
> zpc4m)VbI==nc5AC^d@cS9*@Da?SH9lYiu)MuV1+s@i+yNGv6*wK`$oiouVO4
> Ht$T-
> zFL((SiJqi>^p2yjFsof)vjMfG3H2v<(dZ?dg4?0R;1nSFP7Dy)g(b`>60n5>i_C*u
> z5CUTkF@h!kuGl0j`XoRTt%Q>^Ei`Z+Tsb6a_ai8YIaI{h;rqxihL*}-vr7K~g#Wn(
> zqTc_?TSq!J)3N7k2HErDJul+fd+L&Wj`8Mp&AA_VIOo%zk>gGwWIstQdE3z+;
> G7F=
> zzCg~g3H3Bq3z~B{7cH>y{-
> By6RqVClm*ENw6y>=RU`8(g6{j+YAykKCH8!LxVb?#d
> zE1~%T)?uJliARzj6LR>q;aGn4_&>$}$s^ibx7X<QA*$Yhx=&rL!M6?N>*(=y9Ff6`
> z)a&7}c>RzfxGjz}FHxT9m*<D%FH*%>Do)=i#yC(AyOPSRm`1XJOR)n3@iY!5{1
> *{p
> z8p+R4Zq0q8JWjxb&wAEx>H(b4VsD&aml|%AUgyr%J_C~>Db@bQrXsHgGr`<
> |Ci9oA
> zuV3J4H~kuP3k|foObj;Dtz3IM!PD^vFl9Y@#~)XfIu7HpkiO__D0LX%g6K3%HB
> U)l
> z^n6`XL@g=3G^;(WpOV*lxh$OD@&yx2&lApZbp_7B0OI76JH)T%8FL8+(r7%9v
> WQJ0
> zINEZ)&j9w1G;}3hJ8Kqw<s3bhuPut@a)a4E(!=jx;$X!1_H%8gYr2@^N=yc{N&g
> S6
> zl!*gn1rn@{!|A-
> WACTI%%a%v7#YN?SUK9R|9<ZE__y0)w$`KyQ|1R;}{{iKOxArEf
> zZBuTKQtUSH%i}YF!QwM5_lxOV=oz{j|H~^F<Z@|zYZaHgU$)0AtXf|u3=%J4!z
> YXD
> z>Pv?iX%J~CjFm93L8mRCJt__rHZ>tDbsFKl9)y3xOvp(h5Q_Iv9WJ%q5FK?X3?{
> h!
> zLXpwCnFHL-
> M8mS1`T4bCv_k_xQKnI>@SteTL&2f<Ju5aFtvx6<Tkf&FF?eR;b7EOx
> zVbGd_5{7EFJgrSXwza}%b*N%UUfsAm$E!l|lYN<U!KjY9GW3TX0*AfqjWeQf
> u3gKG
> zhthOG|6)l6fg4)??mJfhZtppc{`J@^9Wiq4)$cw1od17310#W@3sn1?j@klKTwt
> >*
> z;MlA8{;Vru?;DQtr!5a(g=~1$@}E4YZGS<}-8{9NzdVHXJBl=$+(KI1g)fbeTVB=o
> zj;HZu+8NP}Q+uZ?v4<`j4q79``+d<%8F7CQn(yMg0xCW!@F>2&dD^bbYa7RIEi
> D^7
> z9l9{$c&KcUk-
> JZK<+z5}c2KmvTgx@DsBCzQyoO9^r_Zs+{e$G;Q{oXX>1PsbA5mn@
> zCkuUURzQ1bE_HK%#MYZOm%1G;c?yI}EbwsYVkmjX>K;K1DmUdB!C-
> `L5I=6!G!1F=
> z9cRsnZ-m#<fI9r(bv{3&Sck|p|A37vN-
> O~pFhEL0vc42Otqi^>N8$xv#6p273`y*m
> zy%vQklWeX`r`u|d0EgcdJ246J&SyK`c}H#}+1_sd8;mwYx%P-
> xl$G!EOwgf2nGLpd
> zbK*C5VgKsSqBXi?v#K+`br_!B#BNnl@X<EuPG`0%QE^wDVJ;ngtf%nod0tQ9>i
> {?B
> z4+47F3zS)C)(nEUJ`ZA+85jg{aUMja*;R5ZDHUD_J6Al-01>V^EP8Dd>ds(e3=f`T
> zwlI?;*z#`zvQLj3@<hsV(e$$*o7m?nh@Q%rSgxcniXZ_?iegwu=1Q<BOuLT*7
> Wkm$
> z-hH6aYv;SgHDOYu82H#j(g@s=8PW(JU1M4c91%d$Ex|9kC40kOH^fkr&-
> J<?lTbO%
> zrzDx^LpOad4q(dp9fr!DLvY)AcZBwV7eba3s0RIr#doJ>kF0D^pY>1&G9DD_NC
> <bq
> zfB<J34o2s3H4L>%&^fNgB=&JDog|>4leD+d^!OIY9~pu=GT=cx8lRv*2^%B`Ky
> QIu
> zVS6em;cIw!v4x~)DG2?nP{`E@aQPiba|(yS{;xhb+rx~^nZyKEo9ke0T$tYqj2(}$
> z8761kJ>+1TF$j}|sD#~^^wIP-*eng^SVBfJC(|A`jPG<W_?NvjI+A=j24;{tTP+VZ
> z@$3R@NgR8^A<mZk-QqgqC-
> }4Qw+MfZhH>=EltKFCc=lcNizJo#v(b~GyzN<XU?=nI
> z_EV-P^D@)8vw{ucW-
> Ld?o9&p&FzidQj&XGLmn8=8W*`ErM!oVM9xuQJHlLy*U=u1W
> z>+mw6BXb{A+tnX=Rhv~prw$2lSXO1D7r|)9-
> |`_Lq?jRO&g~3bZ2y*i9i4lYcXLhv
> zx|5XpgBV<^k^HypC-
> M`o9>mZ8!TLU0DxCU>hf`Iy>*GC3bJZU`oN|H9I@C7Vg!=Ux
> zVhS_&S@tTa0I7eAz_GKDl$G;qhSrDCDw#bwB^VpS?Q&aI<?tMT=C_0RG)gy
> pJi99L
> z=DLW^^Qy7}=4lvlj1OjCCGDev62e-
> *R*`%d#Ej2~B89Ff_C@V8gw<UaauWMsnq?3C
> zWRCVhS%@{LpGlcN^I1HhCoTq8z2!YeuqT%-
> KNopsnTib3vjh=JN?3x&4p@>4a5?j1
> z>3@4Xk;sQmz}C>J!mJ{n3Te)zTww4gl9PBc0?$m~Ppp(+K`NZ>Qh4D95uDJmY
> %+uf
> z83Pvkz&l{NJA?g7C^79<o^p&|35+Z#iroQM--
> +6MRS+?t5J55Y5K}|1kOYy6X|kL9
> z$aFUyOy5r8**bJUjuBu244zz+F5m{tA8rJaBklcb>Hy)uAPGq`uSgE{8)A1!_>KG
> w
> zFyeq1AO;zVdGHhRSGAuwpx4(Pe>A*y6=t#HpYhuDq@+D5_V{O*pKAt<=kf
> HNE3D2A
> zI97pUWPW}CAJ)-
> iEtre0*D33n$*LEM%1PukU0}19^OH@eGkz<T(mHaXR`uo$a>Q>3
> zVQoe-KnoiMXOjL(aWf8B?gpbeX7d~vF81I+<5w#pK2UPMw`X-
> 1y__z3IiiPyEuDmw
> z>?N(Zmo3T@mg43GA`SLd1`t?tSNVX}0|h+ExnJ{nTfr@Bb}J@YSJ6!P5M9<4w
> &EZx
> z3UHn;7c8*NpONONNGL$C&0US=I#GDq?5b<zQM25J7S6gbAM*lC5dhmNr^i
> 7>kV@G;
> zNY0rEgtBRooK-VO^zPQr_8w0;IsSgUr)&Z0l8>Izm-
> sO3m_7Q_un=@c|Lc46Mjua#
> z)Tj?SJ)`den@ch9di2N3GMq=(JPBpsNfy_8IpfXwTFj<<5S^Zn2wOfiD(OY!0&7
> HU
> zLT&hsPzOYOormXuHhKOQJ*v@&W_S>-
> mxmBt%iKdmm0m<Hutvlt)RitGYCC%`0Ah=z
> zCoXoF`c&Nf2(o7pr^ihTPk792t*D;+^$H~CVhodWS3!dEN_{BBeurJ^lTv?tSu4_
> s
> zk&50=ov>^LqAXRi0W%Jtg|RX6d4gl~N@aybeVe{lWTg~KLaSk7b$B9iHcZ4C4
> NB3P
> zSyMf$1`Q@>)<A|FjXaR|_^y*5!1W}>19}GMefOvdxaRjHpn>;?5GnF2q2>I%s
> R(H2
> z7-
> ;>*<6lApJ8%FqEnhJ413;+p2RMlbB&nT2Nk(rP?vxWeFj1)VW}4WikwDV4@>T
> DL
> zaKbb79LmB=&MJSQ7fDScm31v1h(arvuM9;^D_-
> {=0LQWxQsibWIjdLzN2#rsYd}6N
> zF6ibgi61D8jm`bqh0J}HB<Cza^&K+<1#q1(&kL<9SSML1XN52@kUNvn+rQw8a
> {|cv
> zE6=rf;FDa7njv0z@<@I|KW`YMpO5E1+4dGjvLWNupQd>NW?EhnR`yhS3%24
> Q=dokQ
> z{6gr)p?#oW%ehz+!sVG3>I$}u<uyHacbm5;dY;!w;@NKANCh6P6lXGipfpyT=E
> 9O|
> z7KWc6fUZN(O;#sLea!huLwq95v#k8G<r5_n9$pwR1{%%z=#INE`JA^Wne%KI
> yFqh~
> z7j&e6+PMb;Q4u!lyb$UX4_mzbK^|E!L6=O3l4T7#zvYOXD&Y8nX29FpccnF3ed
> B;2
> zSYsnPQ98!un$xiuo_*zd(^;Hl%L$1YL-
> )KJa|kC_^5H?;N&mAZfeY~1wESvjx9Be0
> zbc_?+PG991C%ltsgKj2+v<6^w9oj;;k!1Gq`?cQN_SOo|dJz@Tdpve<y-
> nhdp%!IX
> z%zSz}=2K`WUlgO#nk|ZhS8UGm%+WVd_hC$GLa3Z))X$LuZEGQV2H5R@X8_
> +Q5Pzt&
> zw3)g1;BK;hH65|l4DDj-O^d7!riM`tL&#qoXq{8Jvi@l{7Q-4E@>k32#kjUg<FCAc
> zIt33`^40>}YA~-t#o&vfryJDA_mLMkgJxA`oPE3g=`bND5>lP*mdBe{!NW!1>*-
> |V
> zF_Q9FB}oD9`o~tzEncU7vy0f0ku_=yuC$jdNX+$+D)j4)T}7{4fI8K0fa3#qv=^o3
> z7H<!$-@n93gRq*U)ZgluF7q+eGToH=yQK9-6_J%trMiK?>(?ax>DS=>f+IU-
> m#@Qt
> zDBHo(bzyUvSCHR0iJi2CiG8aC$6<i*kmtug#g!;9(N}Wb>h1>h^hc!0C+l6jYz(Kq
> zjd2w~^dbfhq8FGONnoB@G6j(>3&<5+Bae9bHh|rRq}<!KgF<2BLxz-
> C4jyEqGm2fm
> zqztFgIDW~y+8{f-!bt9ztghYZ@k?A_bIOSzi>{4IZWDJQ{av8X2^jXxoafeyo4-K2
> zV{dIyqiZJ-Q`x?RhN(b%uDbeqxo7TVenI#-6T@bom)&0x7-
> vQhq9$za^+MF;L3r$k
> z#^dhuVrpUFJo(v9x;IvN&f*8FR2RmbYz}{&_NW=`W2Cl2_rr9!dC*QBZLg%K4i
> *>3
> z&Bd%UHm{DrJNbB|$MZz)%|qa@;dO>1;g312Y5?B87l%s^mYg~25gxaDE9LQ?
> N-zt#
> z)@OwRhxXZdnmup?_sO7{Q%B`Q=*O5bo`sD#f+z3rh>#0xK0^^=6Y8=pQVAY
> s6~}^W
> zU<41a!1UjX7?CUsWqn8qhf>C2Fg&vb1T549T<js>{ColcR-
> ?ZCs)qm<SQEe|)T`|d
> z0nf7Q%>f@y<6~k-7x8v+iNy5?5627C?y5$R{y-
> 6q!E>@3V6EzVi{KhW0;$<!uoivw
> zcWe(&fapa4gAw&e<|?WW6tPw*p&%=V-Z*PZH6Ij#58Gdjq@9CEP#y4Y=R-
> |nFaHPY
> z*c|sbkxhau8^GIh+%ta8NyT=O#Vi@aV<pf7pUd%dXM!A9nJ0nv_)nCG%lJX5
> v$VQ@
> zl67}k`a2XyWbojWRp!a?fOaT1jOoKDz!aA3J!F+B_Rmdejvw^leHut3(H@OXa$
> 8d7
> zDuV*`pydDC6J7lV+Qv<Ct3u0ct=!HKRPlDC2R`q#hJzQG4}YPzwQ6r`5PFg7Qdg
> ?G
> zb5i{$k5K&q66}#`JjYq1X1bI#8Kw(t4!BaiWV2KP2bPIcBN76s=H@e{`k2UPXusZ
> G
> z@ksTbJp|0pCqN>f?OPpIfB+X*6ChIk-
> X@0tY+gYZ;INtob+POUVp*UtOx0s}rX_^5
> zlmbsl+(&`mCjyT{$Yd+3c26~q{d}tk2QWDTK=%x3b4YF~P0cOD@@20qPEkLXS
> oo;m
> z>@A9v7O`R(0U`Q__MG)vbv+)1f@jiSji;OVtd+=o2}hAeA-)wd@$;XEOwe-
> JX9j_B
> zBoc1KULL}ULowxv13EY`vp63fL4QaQX_KDzO0*a?+}YyV!~ci;vnpgeIreh%_B^
> q`
> z@_LdwAG*v<N_T<H4G=<|e|F7AdsGl-
> &CfqWUb8bPF@aWySwe5YC~ndWk&AXCyeG-Y
> z{ztiJx4mF9bI9kX$U%i;>^NWZtdGsFu+0AA^tU;pxrwX?&3QIKCh{cNrsvWGx&
> qm%
> z{obj!u7p<Ip2(TG-
> ibRP6Zbt4P43JLF>&wp*2Wk^E+BUSiF4=92oQZ0URwuAa^icu
> zCUnmK3a?#b$N!w$j(OJpk`#O5e~|K=ZG^i-DYN-
> x>&MED5LfN+e|q#+zy3mmjyLH&
> zctb-B$Z?{Z<q{bD&?8cJU{dF6n#t-
> vph(=npbKo)p|&)khP|RIA?*2p6KUW+#(*{`
> zHm~abN+<-sVQuJmRpa48m9u7$p-(e=41z@Zu-E6W##wAQOsc-
> W8prJ6(LY$UP_J!}
> zw0*((^Mlso$2*@3vUM~zPMsxvB%hRm+UhXiq4V(M^bbUL`i*6L{&QOKY6S
> G}gZkV@
> zUqEyf>)<gh=jefPX8TEEJw9XJ%!@)*p}h;otA*~Is@4k*R#gwW=-
> |icN@fFUN;~Su
> z8ywcA#{wm2z?noaEAazoY&kH@DogM*_2A~&BYk)pi)Q4|J_LSoWI>gtqQ;@
> (aqVI_
> zRN#1sscLeLiVvX`bf-
> auuB548J8D9X3Ymm7uw#~RIyp~md^%w;JPb13jsA)RbZ0J9
> zD_o3lu@LCOgE%02m55~1#SYnj`L#zLAzMcQs9<)TSEX5+isS8b>G`+-
> )HSH~JA_~y
> zKpedRqh1g@0VhHU_rBFa!rm%~mEnG2?A*2b_MF-
> A1K2{x0ci<c)#}A?KB%v!^<p=X
> zd|0f1<5ZmsbqEB~A;GrHh-`TcZcz~sKi&hz-
> h&fzBo^ie55%{R#M&{t)Cczk&zFN$
> zc-&{+%Q9KGlYpm~-
> JqWCk7qR{8%f}seKh%bX3fbWbk9PbJ@Xh(tyHVvuX6LaNkf{I
> z0M`ew&wSC5G(IDY*xTUKl^y%Vr)9>OeZ)jzS*20dcu}I42m`Hni{Y5)m(YJ~w!{z
> k
> zqjfxA1C4_poe~_DkQN~iak<I>CmwqA>-{D`cFe-
> Ag~+}AWM003aOQjep!t5h{2s9-
> z0W4eBihc8C>SS;}{Dtt_(O#6+I^fmPdW_t0)Nfrc@W+!oN1+RSF3QPyDDC!PtY
> pKe
> z+F_Z20)|S#q7sNZNWl9NvFCydPH@VD%LLs%-
> ~VUFcj3(7<sx{tBLI&Hk7~x2F#(+C
> zddZ>VcSDEr#>i?OmLf~>hp**P69UEU4LpGHolk76-
> &jHpAP>HuXNc=&mV+zER7W#>
> z+u<klgJuS>F{y9ttkgF^52v(^jT>*c?3hKrE@uqg^=pAD!+rG6?N=WE5MQm>1
> u@Ob
> zCpzB#m%U!I9bC-
> a^dF>Yn?rW^l~MjKiSl=0e`lJUiWf}LPGW;+tsJE{eHC(S{*!mG
> zA0;Q<S-w``BxO3-
> veg4@1y+G|T{z$4=VTopucm$Ao>2)Kv&vS0T@z$7+$OpQPhRC(
> z#rSHLQ#a+d%`$i>7BdYG#cGm(MaH#|-c7D$ykF9-
> %|z4v<h<QottycP<N?Qz234d9
> z-InfyhyfU%wq6|to_(}ec(zSQ9gZb$rZ`hHWUhuYQ1-
> VikA5M1ocTh9sEA9<IlL%T
> zCAOnrAJNZ8@8AnGstK6;BIf}u=WxNen~W1E4YljvQPy5LH8jBYW{6{xIbHoi?$
> $YX
> z$?XiQ{0<juqj0Y<xX<z%+Ef&gyo7)dKaqjyk55lLgJL6gZPRsTnUE)EQmCXD%2N0
> j
> zNt{;579s#{)4<4Cg0EPHM(uqM=yomLcvEEs?GgZ>sl-
> BI>k!@RM@lv;vx0P&TNGHZ
> z4|L3|;2{`b04D~o*jQl2uEH^L7boyZOwCzqlf}Yc@rR>0d<17iAzM{=Y^H$QVe=
> 1c
> zb8WLZU_ap)y_}90<dDda%t<@*E6sVkAd82@a9a+NWrxtFbco;Nr1MO)8{rdr
> R`gV0
> zvF(O@H*_SPfk3iK2VV3bU$%GJseg6ruYLMUyi@wPsrq(hA?4bhqulx9+cCBzQ
> %_OA
> zH}R8htG0D!A+(8k?x`YJ>m|JE?El%2m#NdCrCra}g*Qu4NgKVnh>XHab|lV4+x
> $lw
> z-
> T@7k+(~bjVeuyuYfx^b<ddqkE|~ZYsJG;PgSt%~%E7UItA$X0W}}nhn|N^)dm<
> @b
> z(CW7dK;D~h+DcJ|hr<*6miOVv6<&$cd7$&Kybve0KsS}wrr@G8D2;1>uqYt@
> U@{f3
> z+vK;j*~Y8ZSyk;_MteVAv$GRBT{v~dkGmWN;^(z!tu|gI+g9N-
> zKNe?x_;}9>GLrC
> z65C_YNj^5@W$JmT7MJNRyk<IEQU4)JYcRbEZSx<QelL7LOYWqv4C-
> xPo_vnMe@y7$
> zC+W~HKrn}U=y>UuGKjWoyGcV{rYgO3xbT_|c}>@q4jnw1(V^oYmXMa5)tKg
> Uo*i<c
> zqZU*NnRFzcBPIA}iz(hu#a{>v;N8)wpQ13hxs6|pS#lpakk}J!xrL9QY+BE%!N=y
> ~
> zM{u*i#t&C6n_yRnA6fdyDZ$MN-NwpZOzil9U^3-
> HEe;UB1yvibaO4m^am)}uQzR<5
> zdG(gkQ*dhO5nr;6H!PtwnJ{o2-
> ^9=1!AJMtEJ7>AAK9wZ(toLQ)`uK~)6sc6wJ78_
> zs-
> NCTr^AnDQCijmZ%SB!m8d`Lf^1~B_>h^~dBh+k@{TutN=NK9Nn#}sV)%MMA
> HqdE
> z@7|fa{o;DLbC-
> Zd>@sx=f{v~jx$t`U*os>9V|(uM$V+GVs<DQ*<S5LvA017#k>&7i
> z{OFc29Ot2En$x?m?6ptWL*}DC0Us+;M5d6k;%Y7=5l|zEl1hIYRqVk^whh3=u@
> d~`
> z14H^^6MvRI@Fgq7i{OjjS_cMatJ>D!3#-
> )lPAq?WGuXoKjqk$#S8rxK9*&H^hL?@^
> zGP$d_WH}g35O@Iqfr0EzkIx~EA2~mEF5bq5^HHP|XiY-V%~&)59H;gmx~uq-
> Rh7Yd
> zRo&4((w4K-
> e19kIruQPKXTS3_y%X2=D8>8FkBv+5g*4YX4KtJ4Xof!_96)oC&O7#?
> zIT=+1(>jrLolZy-A}`6deqjhd<LZmagj{Um=j7m{h@L>|_ybJYr<t-{m;yoZ#}D5b
> zg9~X(4*5V6mE!|827A*yFB35G;`q<U&PG5WxH()9KXPFV{tc!Y!U<S9^x{1;%T
> X5<
> zR(LAZ#?Eppe3nn}dn(A0x2TYr=QO_%iJ0=v+W3*h(TM;S8t;MMW#f<W#r3$0
> 7uPS9
> zgTw^jYUC>ha|$B;FX%2^V~lVmM;N=D=ouC?=vkUCg0}}Jnd$?i)yB{G!I?>Yv5
> 7w~
> z3O;%oDp(2r2)?*-
> _Oq0ylpkMccg0&ZD2#dAB?k_a;%+q3k!ayu!oL(>57Z7hf|Io<
> znRp(zgD=TfgUR=}r&2t=Hk{(irC+|Cv%WMbmE)VF38tjzh{xF?eV=oiT8?_HDSo
> b$
> zHtbB=R2v(_W<vUg;b@)`%OiY%KABjClK3Wm;@~qYB|q`x5k|4RfpIeihw#RS
> @hO1G
> ztFbfCIp`D_7d_i*V+D%`MGol7!Cx0VS-
> tg*e#AX6PYcl9%o+BC9SRuf6Z_L0*kZz9
> zOc3_jQiJ9p1d#eHkF@IrzwwW6WQ=qs+xXLxo5@5J1jt;O4CxmV;pSm1gzIqcv
> Do&n
> zozJeo7qk!cf>V`RLc-fv+mbf8pCcDIByXH0#rnj&F;;@G6luB0?9!#x^#gAl#_QoS
> z*9nplUWO$TOWANrninK|m7QF`)Q_{I7*dKKW2`p9QccSRnwQdQo<Fre{bTF{
> O82gW
> zgvyBB31~GY!9Dk2;yEz5b`PD09`Hoi4co+PN}45C$%IJ+oA^ni{fyT7ZQ#12^$Y31
> zyT_H<ke8`De&o^mF1*(IY(;(dU!`70q5^I6AMMuX_LHZ)lRg3RmR2w?oOW+j;t
> Z7p
> z$zNopXbBc2{h85L8}HzdJbWe#ZOKlrM;(|0cF3{KTPn3dml<4#8JtRNU>y$YM$
> Q{i
> zkyw><a>p`L&7ZMyr}p97xnSuO4wbGz5h^@PeaZ{`ein5eo@M@-
> Ou3T`LS&?K#nu~8
> zp-
> ~k{d;uF8UEH3>D|ka)6nMP2WD5b3^&1&{ls2%Z6W@xBJHX&IU;S1CMD1ph*
> |rd$
> zWY1-
> Pfm!GC6{sJ!?H6p~M*JQKr`ibIxOU_Fcx+T%_e&Y`Y$tYUW!5bRl~J6;gq|U{
> zqFo(9#JhouwzWH@!uh!heoxPl*N7Rx%CYgRwoR(>xUrJ$s25frz@>n25fQd!2
> 1Kh*
> zij`{xE<J=Pvp4ZYAB;(I;4$s@r$=D90l@gKI!sus2_dIO<{sx_5%_|+4A<=$bPVDk
> z-Yu`s;oVR_Op8{Y%W)Asc}J+H#uC_gdw6B&Z-^jZfQ-
> yIfU=z&8xVo+#fj}Gg)C5g
> z(9%Rtm&q~<h-
> 9)f08z4SK0ebwWo`077F?%`8a#CfxJNaX_<_pkEXvwjb<wc`{5oU<
> zjjnkznaDMp87l~Xrptmawda@4uv<7yTCg-
> !KFF!kz!F_lyT{u&dKK@gi`K<Au?NN@
> z7cCnR-
> $dNTeG{z|FAn|5lHSGl7;rRFb8su!HW!~_+&FS@Un(@LF4piakZ_Imn>rn1
> z5j)LlV=GpIt;D;Gr2I_kpL9apX><xl{lFoN`mys#H!(^GkweMAQrMlB^rXSWk{5e
> +
> zCU!kC+DZ`HC}}?WPuQM&va!KR5jT#?WKp9kUIZK1UXx5*kDoS#zypvFVfBm
> ep`+4}
> z?pJ&hL8m@^g4M>0qBhD~Qm!GrttsAINkJDn2GX}vbA?{gDi_nxNr$4aK)#~q
> F)5p#
> z1!e}^qnapkPVKt5x5KEB^S0nZ;-
> S@jMlf*zjJF5=5|K>&j+Q{QCqbNXZQwy$@~%K`
> zRy#MbR}OJ2jE(|irF|2AV|8eMHS!!1vq7~~3&h5HTxl!Cf^bu%x*jtT&VsiLX>2L
> H
> zMM$mCMIums<^=+~Z^&k9RJn$Y<H*rq%Wpv~dmsG9c3gENCIS~O(7l0VTO
> BFFW_4mZ
> zFH-
> W^#!s<!yh!W{wj>FjAnYQ`zbKhH2<sGlsf}NaO~X=&8k97oQd961Ry%LB9UdaG
> z1Owi?u2ID|3HBH!0fG674lx@vJejjSD<Z3n<&AdJss&>RzND`u+-
> WJXJ%|wUA+-IX
> zbrnzC286vPTvjCm;lsSot+K2(vbhm#{s<#TV48w**a=4PzO{+^5TV8{GAF(4eey
> $0
> zTB;1ysC38SOc^V|UwB0?^1$AO3S~6O%C@YoGnTj28Na~ax!<lcV)$EuzwP+T
> ey7eT
> z#CHk)4xzjUf2ZR5Ec_Y8#RbLsUtw`kaj_52YSjR~8-
> E4(dk=p{@Mriw^<M!>3v&=f
> ztG@ZYI%E2pI%C<Bb;kAIuQT4p^$&2b5#JZ%_nPn48Q;fu1b>eMW-
> h)>{9XDCaE&e)
> zZQy_IUm-7xM*H-
> g;?cu~gXGb}`O`mQ<ml0(Mh8ZZF3H8y;NZ*lL>*@t5)u(~#aS$+
> zeBTu|^GlN>GfM=-
> C&!KB)fjk|ARzA?<SN7((;D)xEDUazXUi}aI<L_x#Ofc#IQRx@
> zr$8fK@QaB4KP})$GUWg+To#^teQ8I5NK*+g*>y@0AJic>iLVhi-
> VDNI2y9M2j75mf
> zs=_g)*ru3@+FXLe3%EFo1xR7$ceyaSju)~o+<uY%l{)>CH<q#<`gij&IAG!Zt%W
> N?
> z5FCB_9&#L!DEYeVM}Qh~Cdq^&L0YNSKLaABoX=yVbRJOCCF&Us41x+X&*b;
> VPu3zS
> zTV5rGAJ)tPO|#u!DM#zM@_s8!5O2As{vxLVDaU?6-
> Jtz~<L&>d#cM!%dnFzb<hGjq
> zw!MAw*yK1n+SGKR`Mi!Z&V825c48IKyx3OT@N~{)wIR)wj4(=&>EL&D4Q%8
> sW*V+a
> zKFJ%oeN((@X@{J=Lf6J&H--ahqC4!o^u0@G@Z!ZtN7Ag$9fn-
> U9!I3&mD8QNVQfit
> zLD?=$BK%<(*W7gDb)EpS&A(hef!V&Q4*6#?R5&(uaCzmhS%&)8PbnXV^29O
> a`qV<?
> zK1u7hJEeB~nw>*#AcWVH)-
> V5*a<+cXG3D`|`D=S{W+JixV6xatH~pcPzwFJ2%CQVJ
> zHO)5LPm>t&s<nAzhfJ|?=5s7EnnDiDo%t|jgt0d<E^}b!cww9<KqVL9cDyfh5O-
> V0
> ztc+}5-n{*m=oEb38};M!f#}JZ>CVy=sYg2z9qf_!!Eu=g8_0Li?J7*x_sEllxH&@1
> zdXGeidNN<FZRbO)?PAa2{<pKYR(-
> p80oc(WXPUY{UvX%Cit{ojuYj4P{NMM;tA;e^
> zqn=b&7jruBc&hZvSO>zo5SiOG-
> CYJWFQWZ|Jqor=!W97Er(jiLMK;QDbsOW&8|ULW
> ze9|A<h``0_f0w|;&G<@xEWPTZ<ALsUu@{+hu)!GLi5L#IFXIP}Cb5Yb=~?mGa
> uiDD
> zR}T{S$gY=J8K>UieerN{-1<;tefn)mI4du`TJZKwI2H!=b{Tb4(S2!T4xk4(0M>2e
> zM8^XnVgZZvq`x=_>;wla)H5ObYq)u!>MVg$p2m>lrErt9;?2uMn8hz9j^+@$Fg
> UsI
> zHDs0drT@YjArKD7I0pxfOTuxF?Yu-7)Of2d2Z8-
> eu&)m66L}K&<$xnRmlud<k{E~E
> z4`2n4Zp;1>7m^!L2D}@1_As>?a)U&Y%w4$e2-
> B7SoF_~Gt5Ls#dUK<+F0e<Q4z@Y+
> zv={=O{yCfxIUT&kq}bTuG|nEr`-&DWbFit1_R<W10yXM4bk3O3^?(-
> s_3Q>oUN0oq
> zuSXi5<gU9UbI;Zx`6<Y{NB)uGUZeb8l3idA$rrgKzepN6t&1eKr~`h3rn-ayXE+3|
> za|m3g30#LbsVtve0uOo!{QFaR1Y(t4qi%;HcX{dpdkFmYYKN!g4uRZf7+M!K6`Q
> 5t
> zBnrc7(+-=Pc$|gN)?zu2whxxV2W{Gy-
> V4f_{APs%pE?F!pI=M(LV<sd@Wah22mS^Z
> zUPp6>yY2J%j=szTwYw;GFE}iEL0A-
> dAsN{nZ{F<@y8=KsW4P~oc`O20jhYQD<+8{H
> z_OR%_Cma^xQDk;r25G3FJM`z%_Q;OKPDuSk^aR@zqde%Z$w$AFD)iOwc+k
> 7R8a<m(
> zeUIDdGxwXz(HPu3$*tf<L<&I{bt{xO1QT-2<m|9jE_>EI2V6F-ad0!z<oIl1Pcn?{
> zm3}+>1-G2kn0_}k28CmVk%S+RgPtYj6u$XK&%+<b-
> {K$D8B_6hHU8fJVV&_h{>pKE
> z5x$q>@89ruJ^miVJtN@$D=2g?^Dm0rpFUg_4;$|O=7oPm?&nCk9OcaqfPZ%
> LAph(i
> zJug?FDly}8j+1TqnaF|DC?NjbaDtpf4kkRqWAY?&{92@-dx%7i#M3OYfpv-
> n*5Jz#
> z1xzGR0t-?2Fdo$GE^Dq3R5--
> *vY!hjeAGLQd~S?xu3>T8ly4QsA0Dix!D%**1`&$|
> ztxj497KCsBV;VeN17F_T7{Y&Ps*&^$@X>UQIh!s`Vbc`V4WAPWLKhY<VRT!KP
> hVj~
> z?>C>pE~*EAoJVQ>?Nv%0cJyNBFxu!67gm?bMz~9Ghi?@y8kx_#7?AwJ!&>x
> v4!w6l
> zBXU{rK6j~ra{=kC!7*Sc3-
> 7H!w!w08s7sOxx;ke02nQdvqs}i^s0$X7RupPEW??B<
> zF*q^hdd>Oc`nWjc%bH(RYR#@Hv*uP+L>e2yVYBOJb;iQ%=ZHinDQr*9uJSKT
> P7t)S
> zt7@#P@zi+L#M)D=C4u<Sqd4Jje$|EXBS)jYX&>A_Id$Rvsq24HYK_9XeB=Lwjf
> &kS
> zHI8+uUtJ4*M}I_q+=(BVbql`<w~69W0nd9In)Mx;=|iN=5L+9q1!>5I^VjZFH$Rl
> c
> z+h)y*?2<rsNojUTnfd~{3}bhLz@Qt+!VR#Q#<mEW@muF*zdAPi)r#y_&sF6%
> ;8vdz
> zS#Z@n>tJnr?O$s5)P7u>&AxHnO?ZKwb<ld>+JaP`moVf~x(nsm?Av(1EtmwK
> *DxRb
> zc^v|=A5QccAoT`dxwFdO7|uqk%G7#sxdS(B^}9!}$PCsmAcWRB+4PknIfvtgIf)
> y?
> zq<`CL+wqpw+&^bMw*1)n-
> cxm)^Vsmd+}ie)p?5k$y9<B;s|483ROB6;O@u{rs(yF4
> zX;_1~^2EF9vgOl}U6~o75#uGY_L>Mw)pw4!0J7IN0UX%%KouSdyBfPRNTRJc1
> 6%Ef
> zv(X?Tfgyhw?~j#!VL|jt6jQEo1ILs_GT10DbINmFl`Cm~MbC6>qPqDo1M{pK{E*
> A$
> zvU$l(+YzS0tBml877Vo;k^%nV^+>pbX&IcSe(2mHkoCDa=p#p~DT_ff)1Med_
> K!0d
> zBE0YHhE!rNU>dwd7>UuT6mR4GmH1@d0Ke-
> h;oui?$QEO0t>#iaY7?wBmRi0|HDE#G
> zyoRfk_`7^kF__@fP@hG@;kttOCL!7SCFzX$6CVd#I0ssQ%@K)U;yv_8zwIj3^L
> Iqn
> zQf-
> 88)VC6S@cbI$+x|XJUA~Q4s3P%kbdn`RTGIXSRi*(dQ*Er=2>+xZm13oEWA=|}
> z3vF97X4}j#M`B)}_a8~`Z7`cXzf$N)_CF|+sqYg)WL+w>bs<luu_>EM5Cztt!q3fn
> za}|C`2rI==VmL<A1@EEJTo0fH4fDd;Hgdv#&~jL|ybdHGetXl6wXa{NQum{tn;Z
> p+
> zaOD4)|Bd`}xU~F(8IXTC5qN`-%moGtka5l#5!sE9=Kpp^*z)R!QqIY1e8$a~76`K<
> z@2MY*;^MBQ9Rsj@iZO3Nutie9cc#8tU}am!%xu{cJ6!$S_?Ag44#SHy9{8u!_X
> kj^
> zc2{a)mC^dGIpEvM)g`<|(08rQR)1Z~uGrzLQk!_Qdh3;~R~B53JN?$qE$Kq*gAf
> 1J
> z+KK1eHY`NV51+GkwwBfrhYh~PdOyE{4gTSCH)V={^#TNFEvZMY0UDpzRM-
> $!w<GKe
> zV~IdW{Q#n%Dw-
> Q4yZ^Hx%enr~vraeB!~z`nfLZIu3ty=X|BjRAM8f;VgE{5%G49Na
> z`3;3$;TB9|1MWThJaYXwKVYc@;79nz$XN>l=6-
> <T$S!=w4^}mr&*LKXaOG9z8eEtS
> z{FQ14Dsu`h!`V($A>37|(0VwHDy+VNrsCVDm=_W>vcA!*;RRk|WLCMAaU{@
> Okdazl
> z%%<@CI_bgd!SExM;H`!x-
> #p}(gF848meC<$%J1*fOfmO?gMhe7T_6x}F>KlXnGKPr
> z@q~Z!{-
> eM=@QZOx1RJla%~tQA1IzGX{BY^L#V<pYjcJGPJG*sk4Sdw#i@yoW1JgEr
> z@z4O$OZ#E_R*t*;GVDhqsv7dA${yU|8*c3IolFBI^U5ACW|if}D?VePEw90r7l
> CKq
> z0uIb7@|{xZk<p878GXQ!(bjJ*{a?%H%KwFY8fQX2N$tF*BG?mTcE5HwPdLAH
> Z%#PD
> zX)!z=iz@vGYiPelSiVFT+PeWp*NOP*a)f6O`yRmFP5@6A(8MLn<m-
> lQc%Hxk&DksH
> zn6)o3L$!pT9mVVL$$xIV73I8_Ea7KIF`?{ospp|j;5@%$1#l~R;yp$~Bka97<tzw#
> zEk2rNnSCG~{>iDx0(DpD80KrQ_9{^6&xXn;W|A2E)4z=`)_H%g=$Q+9=*mNTD
> se94
> zJQ;e-
> N#aTb@Ef~4PWS^)$0zHz<D3EZqIS<B92?mo_DO!XJ5k_74}%q(_{pWIoq6~R
> zv}2xIMMqrCkQ@~!9Be~gpniaT7I$^(!kcBNq=UkLXyKsCn^$*~lLVdVx-
> }^;m5y&x
> zHcC6w^+gZL*B;YV?W9W$d4a0+qIBUkO17fDl0!KUC}~&Z-
> P2ZEH;}<k$F{GX)GGJG
> zYSrt+1mC1f*uYOoK;;FKTHAQB<w&um0lLoE(lxBe*T!dOl8K!tqwm3QNkC2Us
> x@5I
> z`BvwV;O4FHb&%9LsLhnL$wXOR=qF@~%H*Z-
> c*CRJCckx}EU%C#+m2Y^VI;M_fkYZ?
> z(6!?(N0Rt?4ent#kXLwrAU^SyKtf<h?W9(Ekj{`cS$X``kQb=mKk6A$7hdyMl3E
> Mn
> zx*i@G`|w2I!;|u<)By0P4I8rA9SH`pnQg~!9psc3#07#c7E)VX$U2Bpyf~&&9okC
> &
> zh)y+*H|vw9z7Z7V!x{d@6knt9`I9(j_<V@IKt&xp!;I&y&C}Q!dOECr>a-L4Yo-lF
> zKo#$w5KOFPemQY5du~Fo<y-
> iTgeUR@|8|6)z^}0+SNO)OWTFzER*Ij=`ZYU3pBSx?
> zPgX{bwuX+b487Z0|L)5Aw_77`uZ+C8Bk^}Ov?KIR0WxdY1UA0jrZ+i?u__OxAS
> W5x
> z4N`Z9Rf~i}*yVGqHe!+FBtaTlgA*`Pcz`0bJ2khV6X??$F<w?=cd~6GP+19n#?|?
> F
> zmnSde_3ZV*N54U!6mKEpaNrF_pWF81EB!DET0`$lEWj$GHAQNdrwdlfMfxk!
> GFUUK
> zAm0D^*mTXNLM9p3NFWd-
> BhI!@*u4)q+aQ&F>`0W^S81H~Wu#kiPdLtYYH>=Dup8}s
> z7KiLOxrgaKKxMw-4#mPKao`xDg81RZm|z?+*1realFo1~MarB5b9L-
> &gmF*DtGpxt
> zGBi0fgNVAFj`t->lxs++%tA24M}}l>by3|J!@>6Umd2-cIrEv!h}OtE%eNM+jJ(q-
> z<BzuFJ5vVPSiYrTW&OK^d0SxKPNz94n?vtH3!EyRtm01MR-
> co^G~gTr1L7e{Z$pOK
> zI8cc_vCm8QVc_QRTt9FKGJR=mj6IORBm<cVwn~NN2Mbopg<Xq*c!nD9j$VS
> #TcZf<
> z?EWY2`r0#V{|Pd)l41=qry-0kBaN*HJo9yl6ha|#RU(ayj&I_17IC2a5N?TYqQn|e
> zoHDq^2)2yGDiBhel%z3B(j(*PTa)@?6En#wf{%V3!Bo7q6+eP6el5C(Vw#wXFS
> {+A
> z(<`%%WXOdTStH}P2D(I8(*E#>*7`Sv$8V;;3*mEl^{~G+^d?93&GgsgzOW{-
> 3l$=7
> z%1FHF8DKmmvKM*K!q6M>Y$U?!jK}ZAL?;&`pEOls(+)?^sPEj3?r#r}b$n79Rge
> aI
> zL#zy%;|64zi7;ZZvVF(QQI$@MHw0V$55^ME+!%Y@1;g}zJbrjm>_nWo^Mrm`
> FxtcL
> z-Vm#8jXb_G@&uOiPi*Ng62Jq)UqMHV-@k>{gPVN?qqgGq6I%{r!(jVL-
> ^k3vXct-d
> z^^XIsa0zXN&_ey=)3!AGrM>quf!5FyD?{(K)<3?o{)yJe6Cfu8PCZUeJx*AV^4_
> %9
> z9+`x?kAEuW$8(r}O|_XG4OsvQ=s;o@Wa1`_t#AnsR3gC~Gk0||w39-
> `y?hZWB=%zH
> z8`PzxB6yAjl|komq>;iIS;LH$d(dwh14cT<7^t67;Aoyj8nqk-Tl4`YknC%K_`cX_
> zT0loIi;Hk258D@&u_>f1nD~&R(#EnaN8p2lt!1T{nxE8mTC)0%AJ8w;{e9P2oxzq
> @
> z0gXh5cR^C(-
> {m^;CU*lL!*#1rvNEwxWLYoW)vu;IwhV`j^~sp@!GCQ~A7FBT{FMow
> z-|_M#sK1DT9&Iw)@aP6s{{tveNnBf{*4MaKfO~8m2}Yfb%GkoDp-
> xvXLS7>>JFUoS
> zChkO5GxvRUt5Cq4E8GPeS2I++Qy922Gj7O1*eo>pGsWpB=CM`3b6WlC=mo
> *ek$0hZ
> zutDjb3kd#JfDL>}?8w?ZqyVo<7-
> rS4W(cr2efubwfWMERzqxxM$kx1{6f0?s9F=)@
> zG&3r5slHnsyVwe?5hK4QR_2WVsMh+oWlFydC6vdvS142Y!(J0i{0Ug{mDS^3I
> OqzI
> zl75&EBx%a^;j3ez{H8@*b4_bq2Gg@9p2nW^8Ys1b=A05o-
> <ASv<`z6|0dA48`l5OF
> zQY4Jps*r*#(!M5^SM?rNJv-mM5h-j`Q-pHA_Q-
> 1pcRjrchl!ZJM>$oG;h~Gh!$Zg3
> zfQNZg=YGVhb3A1J9Q_XncI0gcb7Cc~F*%m<HCelt#I6axXiw6AhU15N@KP?a
> #PnNj
> zH2XjEsr9Izlv_!;g@;YZ<o`?E`@qLpRr&vue{^V55+IQ%6$%tV0$40)YpAxhfr<ns
> zk)W=u;#%1uu!=M(EmGPriDo(-
> tzTP(udGWgeq~p7msMPf77S3E0Ci1km8exi>FNy=
> zC4Q+(z}S4>pL3t*nVBR-{q6Vnd%b>z%=0|=|2_BIbI(2J+;f}V)1X3BRpAn-
> 850%U
> z{ZLr&$Eot;9T)k|E?jq7Q9Whu@=5hjVuUDfE=pVK=90F|+H|6CW{I0UHG2pn&
> !u&I
> zER(g-)N-
> R2PoGk5{$0MPOjbQU@u{G*_7#pbo)ZI#)iHBp<F7PGLf@h_^ba!&;W1}g
> z1bC~#EN+?vnso$tpPI>v)spS0>JMyB73ASPtlgdOLRB{;r*Ql(i3Z~rY>fQ)!DWiy
> zee577rSuYw#K}eND}e5YIrF3;ZE=I&3QJjTgLP&&SeWfwp+jY9dnp{8lYE6fMYe
> MD
> z-
> e=QUB`!dTU<9t6JOWm2kn!^B0iW+Lf%&JQM0p&X9_CM2n)vVzKpMdOxQw;
> %rJn>f
> zuG@1-2RkZZ1-
> J`Qv$u8(%8fo=T0kH19LM>XEt#!0Lcm3XrYq%6hid*Bs)@1N7T=|G
> zX%6!xNVtu|b?M`wpJyQgAN~$99?-*s(yuvKw{0KZPI$1f4@m;b=1pa-
> qq|Evo;zw3
> zp0hSN&R=T4>N~JK4QNm?z56%{s0c0rKxI3OZdn)+%-
> ~@*@P;&1U7d6r9FOQV{K_XL
> zkCwG0SPDyJ^eQH5G|S;|FP1=(w+YF(BogTUMiVY=@_sbIFbwCTXDFU8Plx8>
> >Wa4-
> z?$)xHaLqm@6Bk3JG2_pg-0)ac_Y9^$aZ9VZY^5)nj2|m3Jkz+TtZ{T>lbI=Vt07C~
> zXcj}$Y*x|~mfTJBK+R6jt7f;4rkVnqX5Ye)MAPHpZxqAJ_HTX(U?P7av(@N}&Yl
> >3
> z@wHmRwO0S>ir-&Q@e$Mj#bf%VP<s-=E5OsLu6som3?)9=KHI-
> ER(0DpaT2q2tDt8M
> z+a2S+mp?s*-va<4Fxu3nA~4S=Y*UD{OT!Az`*SK-Sx|vaKY-
> rv2+<oIZ6U8HL$o_>
> z65KhN_}*@y3s}a8<i-
> E3c)*HEW59}+_e|3!e8_DyqSSMIG~cqgz0PhGrXZr&1kwmo
> zkXVeixcg{t2%IL#0E*V)=dEW!n+(A<pyGRtPxMS^vpd6@9uJAm<pI%I77-
> oaF8Hs2
> zZEU$um<rOuoh3wdKtaqbdO3X3;yUh7lkD(GHS~tnH<r7?ZxI^|72CN%Wtvv}y
> )`yI
> z{3&H%iz#7_Z87!26x4<mHjo3PH9;hMVoSwA&mvJyu$EjN6nK$gT(H?5j_J#UL
> C9w~
> z6BBOu&(s~S(ILsg&A`0|;{b|&TkIhhrEhqQ(~HwJ;YrIHAC|r%!in+=!Zq%eVq9(r
> zE7}hc@({~x4c-
> muD!C#E*8)Xb9K|QxwZ5WBahj(Ix7^3&=0~v}yC=+0$qTMJ%)rTn
> zRv&9GW!N4a(Keh*=#P_0{HBDv{WIE_f+Q+*qT^CI+3q+AvZ&!<M^<RO4<yI
> Zb~-rY
> z4}x_MkSRc(|KyMv%0B{fZ_FXQ8AF+xkL|Nq1>|N086H$nQ!m=3jeo_P+1MZ
> KT@qXM
> z-6gRt{H1wc!}Iez_wn}|{$ewZ{;y=ljM5o1%4YC9%D-
> ~LEAny2WF}ts_>x$CA2vNt
> zFNyu~drM-c@;r<0s|f!U-
> #7By^aJWGDJ?BMw(MB`m6uc;d+agCmK=NRjAM_Dhw^pq
> zGXT`_hWP5!k~<{mjwSy!mY0yOK*=fLwf8O&B(3WHN0OKcdqZPQ$2G|Zm7~
> YR<cyB2
> z<XhYoUPdZCrtIpubGAd)Pq*NAu1`2Gq$gcqL#`aRy;T!cBCkw*@3SB?w(9RpK
> 3Y_^
> z;-
> EAb&nMiRjcOZLdwRb}DxEV!)iR5MR^<yZn}I?_gK0xT`{bs$JMmtIF_zh|ld1|d
> zCZ>Pj_`7zn178p4$g$8D%oN6Rvms0Pb^2xMc`V=1gauyTg2D^niwQ_M1PQT{
> 9VUp|
> zVFF|+c=zTc+?isqq)O8_D=`~p_Lo(X0lWYCdLvz?Xq!^J*N>n~n9yauG9f3&*~Y
> K>
> zd-
> 8nyDK9wNU<UU1g<i>g5i1lNODN49k01mywHq<jGv=q`>1lcsz^ij)O=*Gt<$-K>
> z9rKNYz7!g%V8pa|6^sdmvrU`RO%L`pcF|L>g4xyAElq^JBXjOO{;StN4(O3L(w`*
> D
> zpGH0NWmJ|CriN1g3*3yG3S{|t_00S;L-
> ovCZt(e#<+r@HNIfIzL+TOzN_{YmdZxa(
> zN}uuqx8>snRp!+*R;8(Do@k4z{AHac0_qtftDd+Psb>`4?0)x6<$&aiOr;*tuc>G
> B
> zV(J;an0m$%6su<*AWrHLJ-vEHZ<EzC%2-
> rpRw3rcL@$%nGxrmuGWGQ88NE$a&)i3-
> zMp9|@ZWG_$(%mAesYmpC6!py0pHQzOjhjz-
> fx8fqWTbJ+t7i<prk?r8^*$d%y8a|1
> zRH$c0sK>qbAEcf+35;a}Y0qiYGjmY1_!YUuz3(5xd4Cl3%-
> 6sfQ_tM)U&v^?08G?P
> zJ@Z-S)@Petby&_M^-
> LP$BC9J<&v2m_`UUC31hw6bDZa#A=__Mzelza3$myn@VEW(*
> z0=wGalz^#h8vlscWMk72r12YDf7{b~aAV`ap2lZ(cjr|2?#Aa(*$k*y=-EMu_;hD!
> z#6dt%5Nu-
> Ok9>4zi`)CZLNJ`=1rH_x(uOb7)RSrL$zqb&v@?6vQv6Qz3_oHF&d#)X
> zB=PP_Qp4w@&2LHSk$b5hmCa@)GS4N*!q0xeWZ`ih!|RFI*z}zAG)>QK+^Xg
> p+ocz;
> zvk6%w>1<4If?7a28-X6-
> 6`<#SK$uDty|DmxI8+JV3UoGMInvpL<w$1}mJ{l1LfwpX
> zHlc1tI-4-RbT(lc>1@I@(%JN)jlm{d8^h_Fvza0Anw<gTsisYp`=}ry)yi||kixp8
> zw8^8}tMoZ{zJ%V-
> Nl5eD#;ie9$`ifhP6RtlPWfA<IjA%ThaEA&HvDxuG^X2pYVezy
> z=G1vp4ac+6tzELqH;TTy@t|gtN`oc7$hwb`Ksp=4qSVXM+4zAJi)_^%x6v}7n6q
> b)
> zNv<<=n#5E#J56P?Qz{#?q(02~H?IRt+v+h{T6#CCZX=RfTC5OMHhP!J=2Gc%9u
> dZx
> z%BBY~;4cuv2c29?@{hEm<=DAOg20`h?BKrkLtaBQsoMa;?2l_W)CTJhbTZ30tK
> wbB
> zpl)&{tLo9p7&P|XK662Drm5>X&IO_t=-OQxbE_dv-e>RdH>I0xWS-
> nZBQsh3n$E~x
> z9?>s4qkV|}Gj_t5d2)}RCu?{FosrH+y%L7m3$xLXzb6_J>5QH+<as9483nClz@O
> 28
> zKNISVEZlTP&lpZT!w7m#p8-lY^=Df9^E#t`!|MJ?I->^@?ju);{tB9=Ga^f<GfJT|
> z3dHi6rU$*w$d?%DjQS<wxFbpi`Me|48Ku0=hzz05=#HM&6bxF*Yi{m9e-
> Y`79*lHG
> zDbw6M80d`pr8ByNju@0EtC13#?(jMz$}^o&%5+9|^faY5wx(!~rp6tD)E!D&pf
> kGT
> zRcpQ@Uo$$RRH!pj2TW)54XJemC6J@vbVgn2#vReNNQ%gep?boddZLgUUw
> hyw{(_td
> zSzL(GpkYs@vBxwEJ<`#9UevWnFmZdR(6rg%=S5Z53es7bsE~G=3Q5tXLeh(=k
> o00I
> zq@AdcPEx_vCVI{oqCzTRGi)j(E4fI8H0;+GQz7l+T_>X0nfX&~!@srI)@Rh<t-
> Nov
> za(m2<1d*JIYj)S29xgqTlq3Jl>|wh1bU#VDhu=YdluEmTg?<Tgy+rVSA@2oBCE2
> DR
> z;o8;WzHX};%ySn?rCp{}>N2HL7suiamM#bN?%HT(GZKJw*<|R7;4g<UI}DL_pk
> ^xG
> zajW?)?r*J?QZpqqOV{;6cz#M--N!x}(gDCH3)Ynjo}{qrbZy<9iT0~H`Nbto`@8up
> zS>1?knHDXokca72$7N>g>3!wpSnu}OiTJyzG1INzy+euQ5o+NmI7?!)+ncZ%nf
> o9$
> zK!mJ@mav9*Sq<-
> ;zJ@y~EnkDa0zY{9@=KcCCw%$C&!TLhiiXy%sxFB+yqKh_`z%Ap
> zF(Vjb!ndlf8jJRWpP{KCp|rMrGHlz;P|f<*9eZB^$PKM~R{afQP~W&?ue5WSra
> krj
> ziwqJ#q}Cu}KKJBZt2kBK{N{O&e0vYJ__haWfDw#KX^Xr6N)M!U<lZe@Wf(pYH
> Y5oi
> z)C-y=4NZGi;YL->qESGt{_)AfvROc5P8Oy~cPliL)o-(JfW>nVFMD}4Fg!1)zGC=G
> zQYpR(<piE*RstHoicM813d2mL7)*Sr6#WW^O7Wmk{DYGh$y>ZC)~}$x;AvHg
> R~DvY
> zDY3a7s1)ses!DNAVV1BZs1$olrPz~N*JCQhgSN69q;H{0Q4Fpomhrb>hp7~OM
> _@O|
> z4)fF_m0~{Yv?@hE<9<I|bODv3K0}q_bEp*ceO|{Tm7)R#!>F197>4x$!y+-
> }0;_@D
> zm@@0QU!+nzm{%#%3vm)&rKp4n_wKtxQie)VoM~pOxKdP#A4Xn{>pnix78
> Fsxo=|(K
> z5~M#0KrkGr6n(*O{!&;lD#e|qQdESg6btGpb1!c%u18v{5K&Mm7Njk8-
> zROE1)b=d
> zS>nDuHG9|~X8J+6KU9h~n&L+E;+G1qQnb>u>akRc)>-
> =sQ3aJ^j|qc&q*C;p=wzw(
> zj!?yF@R+RLQecZaJgrJm^+~0u`U91sHNgTxl_FgTRf^I0Nu{WQn_UKr8xxSoaB
> YYn
> zQz_~NS*nsG++e6uwDuK1S1Lu{yzaZgQcx)}Sf~^gu@Jw0w()yRDn%7qI5?;j73
> 5O{
> zD#akpq!B=+SUdvW=F>`q(4bOOzP|+K%ZvInJ<K;)n#n3f)g+ao)wph_sT9>XXc
> |P#
> z-
> lkP44wy=@E3?%`2)Jm_LY3lkUZvROVc}JZEZ_zouTuN~I+)=XkhU{zJtzY<Un<3C
> z2#-
> {X0{nT1owrJSHLX@rDNL&vkfCA?)Ekc#tqCcCC%)1u_E4O(ipt&WKL5pF#H+eK
> zP0x#Ywf0-
> 43|P>ZfE_ASEDoZUle`VqMv2hENYsW972Tqo?}e%t>CKASzxAR1Q%xHF
> zFqt_R!)wC*{&~;=SM^1@MWvE%@kA}$lXy!FUvc557Z#o|S>QD4#X(xF#?xv
> wp023z
> z3DYp%V`?+67`>Yjie}4uzfcUj#-4~&!!zBIG3BZ_Fnh_@ZJ;kwGQL{%rxjHHdLd4c
> z8O}QmvcV`D>;mNF2m<i&^Vjr@0vme9dyL(YV8qii8Fg(^SO}V8RpYCT>ZeT?<
> ^hvJ
> zaZ(KU==_)}4p+EK3#utpIKEmna|^1OLp5IKs8Z{(!ZaCA*cIs<dyEh6nM|EuXJ8B
> f
> z716{kIA}1k8K8erX$+xX_QUlbKaU`XsU1~)k=k(()DZ@OI!XjS34_oFpn3ct!xp0d
> zUrCfzv}A9v{uK`4B%Pn?YIYA>GL%Z5HsQy|%pF$bHIHHIO!;Us#UEirp70ceiP$C
> m
> z<8y`j$KQX{XoQ^KN&omLc#v!Ll92|(()M$vZOeJSErFBGNDV3BrOCte;`wW-
> ArF}v
> z(jp~e(aRJyr25$6eq?}(5C3=7kmp%B0Z2_IRhqH>@NQe8%4yV)z6mWs6TSf@i
> O^&n
> zI|9GDPEteeGJPQx?V|l2a2Y!v5D6!yQ9~+i!VP;>qb5y(6{Z@2e<L4Pq=r<?tEwS?
> zJj^^>H(1hfJc=%lgzm73sX-
> c_yD8E{Y7o38a+AvCpZ1GrBK4W+)~~l?4>qbF;9Q5d
> za3AgiGQ;=rgLAZ!s&3sfieWc8%^os=K_*bwJFkd`^p@V*%Wvut{Ys!d=Cyer0g
> aNu
> z5tdugR~87=eac4n+|>mF^(cMP1nMfqozP<WOgFlN;)C{non<a#2G2R9gn@=
> Ni2JO?
> zJxJnA(*vkVKeU)PRHgVS_~K8O#NP0eC9xI!E#|#m?>s-n-
> &gqizpX31;=q#F?awWV
> zZT$6;*qaY7iQUZeR=#@(U&Qx4JS#`2_f>SI(&~l!v{%!Y*1f*~!r&*mord_Ir7u0
> @
> zx&X$1w!ZZ8*NL$F`TEk48&$)9Q(qeBLwhl$@ssucOMU3Zn32-
> IKp$Fnr`q}dOdop9
> zXM;Yznm#l&Qa#Om?8rE<Mu^-=U7vg(`bN%>z06F@Pe7$P-
> +lBw`PtXzQzlnPJt<#Q
> z?u%FW9O$z4Gw-
> ED_R3~m^O6D{IvJsh9yrp~9@iyS|Ey$o5r%v&;r&_{P2iPCdhyFD
> zl_H}QK`?4*1^ds=XDf;7IF7Iu_w#?U?#q!i%4uEEokmnfVRbCHx_cYW4XyFjxJL
> mK
> zpr;0Egi+(V2^{6}8ty(vR5_knTRzcozU8q?ZBj$ksorWLW-
> axpReRv`M9mwaS5_ex
> z1>M1W$9m!u?l)hsigazt607+@7;vQhP1fS4eL!aPu_G0h<=a7uKp*-
> oJFbRn8aVXB
> zrnPK3j9c+?UrpyLR@n*U1Ymeznk#Sz!0B95r*rsnEUqg?QU~MGN?5{YbrQOR
> J8$d~
> z4Ri_??lu187AP`!%RRpHpoq0OlO+H_k_w**>mFYCWb_4pDZP`=kMHU_y8i_
> HAW&*7
> z+jtLWl2>vVIB<-RJJ-
> w}o{*~qTc@=A1aW@h8h#D!4nmSWl#$$NNZPgpCzPAnA%Li9
> zB%bTKaB;11`4tN$Qn0jLq}6A)qs=9o)-=SXOHc{fU0N0L-
> My%>Yt;uyynAUmK<w%(
> zRrQjqEvcAEaCo;!YZup4%-cXn&r;4n+1L8$YxlA<fe(4!;PWh`HkGz}*@dy(#;S)J
> z_vtj<7$_^JP*q*O6<%|&1+U+m?a&GOs!e7qhW){YPOf{VWn4eqx*1>Cv`0#
> 5Jr#^s
> zY~Hvvx~~x_jrFSOZj)EuovGDDa1E`StFp2XN%rce09GrnErQkTZAwl_!=E8xrs-
> ~4
> z%$Z!_p2gr<WxG-Ux2CStV@uLaU76Oqb#V-
> V5%8E?e<|=@6<nVmK9~Ll$6zJU+F~sH
> z7Qkb@+>~kEV283c5Y^B~U+=NjZ%8fTEc|EnPJ*``sp=BZ!2(OJYVk0;2D3Z)a~_I
> I
> zak>FJo{8FPK|?lY=z6x;1$JACFDy}ik+5&b$RI^;n^4JIRvtL90hPEHeLh-X=r$51
> zL%ka`vW;E%Qn7i{mA))Kyr`f*oc0L%lUlc>tSWo1VZs(}%_}o(H5hl{GgBw(x>5^
> |
> zRCWJv>z-iTNgi|dim!l)|KcylY3eO(cf7Z#-{V-FK-{?V%Otyo-lf?At?L0WpQ9As
> zKt9{qH}!BNU)@h*mdUxW_IB%FPnu2qot@8$0Hj_n<-
> ipJ@<*4I<HXI7y&UC1>z$rJ
> zq+Tfll8wY;HS{D_vRx5uq<+ADr-nm~9yS$B%UlaZK%7k$-
> IY$nWdud;=JM22ODLx&
> zQO<W?3B2e;F06R=2H*RhrRBqq5#v#up?e=~mn42Vmy$-
> GIR77z9Pk$+&$i9%h?cBd
> z3u#PUY<M1PM}0aTpftV#gz5<YLG`hGc!26-
> s}K>7rPjuAVGI+g(VwVI(u~~Gvh>qk
> z-kKQAE^7=D02%M|bA>L%hBa#g+b(Ng=g8TRsqMZ0r6cS+^;^3`zpsB#zZX5A-
> ^KUy
> zd)=nmL3_;JV~^M0XOD_|?Q!Nk_Biiu9(RAXVt_}cF}8h|J<GTE^UOBJx9`_?_s}
> >q
> ztD>6s68_t!$nCrA^!yHfk1db&_EqfUO>`wQd;TGskR2pXruIU;Z#}@f_pGu#PF
> @bm
> z|J(J(=(OQ`Vh*54jzF0wYU_ASEmjiN8&YL_s-$X|sI4Iu^sMIL0TPVY9J?qv;zd>_
> z*Sx`ak-
> rN#3vb#d^)7=m*5bN9YwIkYz1j6@C4AP_#d&V$Wnxs2ctHxr#Bt~XxG`Kk
> zX>que)iHNo5CJQ4y31Pf)0Lc(Su>xSOMzVZr{uamD+oSV(ysk=-
> szdGuhs1c8pkY&
> z@f~Ujo+7CLZY2j-
> V*%o76rdvUeZ&~~VEkPvIQV?_h3GS=B|u>?){f?>H)k5_^A>l>
> zGP<uT$i~`dyG8cF&0}MtZdk&<k3lrP7XwuRYsWVG_7(Yi_o}*H4nRa>bobs`_F`
> ID
> zW667n2*Ll`%Wc&NEi0|7)%7r0V(;jMr*vcD5csNN|7x8m*KH8D0~@^S3#{@oj
> qq=P
> zlGzK$@7^bHxj4~&8ox)lS+Hr;E}+Emw=SRzkJq=3hzA-
> m9;k7|NX@fz+uw@2F`8-O
> zlz*^}aVG&*5Ds@^XP^-so51Jql(EcR=^L_9j*;a^f86jK-Y_fuwOaS)sCDeb8=A(s
> z;$R8}<>FX*m@#B%su}V_LsR&nqxtv67*hAUzH@~TRsUSvUWKzl5qWfy_l3X
> se%Iy6
> zQ9o%GzPn)5<oS%7Rrg;SRd<)YsyYDaGbIm@)8Fs<w6Mv0f_Rf5>tA@kYh&1o
> Z!onA
> zwh?%GUF5FFx8lUYR`^W56?VUCW4;ytNJH(k^98RMy$Pqqt6n_YE+bpE0Kwh
> wpAu|^
> zd53cEaCco2k_h*xy%GtJc?kN3lOQ%k!IiIxuqW<a1wEm9ty1BYud=(n(>DwsaE
> GQ}
> zl=9}bfxnQ=7c=ai$Q0P9?u<-K5BcU8$IJ}Emn*lC$L#vS-=V<JC3OBCvZf&$+f$PL
> zXKCWL-
> 4wQWVPSj2@o&tJzrA9ll+TpBpCYUr_w<rz{O_PT@O_&5eK#(jId5QSV63O{
> z4@eUK0K3r67Q6KisaHxmK90Yg;Obvncy;%0k8k0cu!Ua$<0s?BoAWJvX}KC3w
> 9ser
> zEmS$~jrkT1fyLm4j7oJ4w;X<CDvd|2di1K2^3*}DTM6ie2I{;2AVLU{#0Yu89}Jsh
> z)9@-
> KbROIQoZ6SVU02HhdOsX{X2p%TN5KZNYRlu;oMjsaA#&5*pqr_zhS6$gsS7T}
> zLIcaPZytUt1udDB{0kuywKrKJ9KiJZ!QZ0?l9_bl0ET(>O_dEz)m5o=qz&?QL-|NB
> z0E0_oUY==fd0_g%O5HYdA-
> vx|TanX^rfzG#FyXer`T1qzv}D2tEGgM%IA#Z#E76!u
> z53-
> F{m0Z}<`XKF+{nEFlPt>=(#P&#SrSce+ZR}0BUw3O<@PQ{IxG%EmdXK_QbPtpJ
> zW5ae;b#+-E2I?iVs;=)(y<D=|{6-
> G=a{i&PoGWeh4y+n;@1DLfSYd8Fp@(Kq54yhP
> zGZ)%I5i*g(FY}q3!*%OiT$63>ZE^L5b^gqcisAi0?m|B|O2WBO+HpFdu?rxYdaE
> 94
> z?ZtHb6^5=i-S~jnUt$+ZmklwxkI+>ubZr$`ylu6WaD76vmc3nYp7J`!x&72Se80{Z
> zzD`a0KpVW?9x$<=W<AJ?Hr+sH%4foS-
> AHcGo@G~<Ri+Ee$Fa_7XzgEDG5lH;h6_D^
> zPxRs8WBE?4dmz?+Bgn}+M!65p{)_864KtXACYArNMzD3nWbY#pZ(dmA7fCU
> k<!1`?
> zKFMwxY+3vF#?Dkd)Grt|JSANZJU)(4#&ffxmgicm*_Q^*ei(BI*<KmkTiiuq8GJ
> YO
> zHarH;kiXk!#Kv!=urLnb!~YH+KpHXqWUqSk^6K)=XE&(bT{oD}Le5m8`T7oEhb4
> N>
> z3&XK958gD%EjW`^WH{C3!Z*A10YcJSl{8}+vRQ@HKel)RL%UVCX0}?E*2;#~>
> Qy&p
> ztQaO<_G`*uai()rB8+1cni`wg!B~vgZh9nRMei=1?Mqj$t(r_$Rc_p>9H_P|EQ%
> aP
> zk$?xoER3elpY66rF$Jx4EV|Rt<4jEnh#R2ZTm}r?t3;$$mG5c&Q;V8L*Olf@$Q6u
> Y
> z#qe`1x5FnH>1+H$YOJ)X`<(zsrk>d?&#+E(-
> _5T;jpY<?^#+crln^=FeGegNOOeSc
> zU3RNN>YwU-
> `3NAaN~M&q+wwJXt#tLO4sI_c#dVqEuS;*elQ$o0H=ik@>Y=PcA-P-_
> zBs|8w!^jRHm#+XT+RRqfWH+|x1!FgUx$aB(WWQG&J^T?5Pgv06CN}%lzv|)=
> !LxN7
> z!vJyRR#`S{y?ks@<23O6k>Dv0w{S=4t@{TA!UOyo2!)Lb%4GE$V&h$;?(1%U!Y
> 9gZ
> z9U_h$q0(8_Y*r!Q<$dT@g_o8&!b^P_)yobli^Upv6v4HB3KeF)-
> X>|r3dY3Hmu--@
> zs<QgUhC<1)p_mjM;3XTFRz@S6T|;Y|gXUR-
> >mRpE`4ZV~H8%9M84y$JT<Q_)V#kRQ
> z5gGmmpfW78&%W-
> Pg6@a7ue9}B6^i|<9@$M5zS2KE0cgB(Xb#v*A;xpcT}3x!m16zp
> zxSvm7R?+PogUZ<WumUoBhFclS++{(FaPS2+`E&54D!lT+a3*(b)L-
> q}s=Bqx>gJ>N
> z`TSONoaFwtLHroJR?KbUmHiR7*0HzbYW9nfaKSXNamihsyL|d(NBl*(ME_h03
> gd&F
> z_3Jv0;UL_ZxszR`6+K5qUtq7iX&aP_V~pN7Uf(#vnGIBPyH2BCRC74*d$0Up>I~
> hw
> zc;>Op-m={dM^?uh#;Wend20MA@_X~Csl}TS$Y7%L-
> m6o;u1fu?s^Q27KhzQb;D`Qt
> zI1M_#)CWP~YCQaV>RS4j<2Rr4;#cv<Ra3b%wmH-
> HZN;XB%Wp<wQC8NE2c)xSE!8!b
> z^AykXK0Y@u<Yy&+J^Y=qcjGZVGd5mQ(sOCa#!E^mx98H*)b6rWpOwBRDjn
> Tol-5#}
> zq;{94`byP?{}rX$?9-%nm#Bq(_}_}(+!Mu8#w;2#M!lo_IsS(D8{}_*zkdEQ%Rh4{
> zz5KI>csibr=LpXco})ZRc^>9@nCBSJF`nZ*$Ft>HdShjyWn%$2G85|bx%@5U?{f
> Ya
> z<qv-7$tO0e$A#~{_dy74EP@E&2-
> 9ZUFBs3>wrD&Ugn9WvnEl5WzdBC656q?(tg?Xg
> zwY*YRI3_RqF{#&>JV;wep~Rba@$UGm=40a}WoPW|xwI_xTZ7&U2EA_-
> 6s@)eY4T(B
> z+tSnvHVQojDK{6SqX+ab7_;A&rC!j;R^4$m^t&JjWv`?SH}coc-
> );PL@wbV;E&P3r
> zKVUrvSkK{E$Fq)S4bK{$)jV+){+UXil|17-<2=iGmKTqWhfy!(_47B#--yZ%$L5kU
> zAW$$C_DydK#(}<(#)lP+UBQ0UoMl$0*CFqT-
> <26#@JjtF%qKm%C*+N;I<q%*a6M<^
> zF>g4b{wX|B|COc=p5{5y*?O465RGMx)%A}fU`1rR4hhoX7ypU4-
> 1#s4GSx@HqY93*
> zZ&vUq%oPV`%lhjFTG|k&-VSU{dmPWu0{Jnv_LQqV%2fH-@QmxKUg*umv-
> i#u-fq6G
> zYCR$AFRj+kT>Z?~&l3G4^mDC#Zpwal1F7HDF%Xs;b~%to*1abXGX#{9n-
> ^95d+vT;
> zrvIW?Y;G*^_jmtQ{oeLdoBw`6Z`D^2X{G;~!)>tAqo&d#2*p|B*ax6tXOgkJz1p
> 3|
> z6TaJfugaA!=q<blsi=PRYq6);kjJjTPy9AjoJj4GmvnO}dI6yPULxB#x^las@K28L
> zLT^Enud6!yF+w1Nq2?^NGy@&w=x(}osB_&=MJ(3aegZF?-
> 0ju%7YCGE!nOm-#Eo#K
> zk&6mtkwGmsy==qa<#v-
> ~y9jRH@oUhbP(C(yN`Lkrr9VMu^2ciZjiX2r?!|2=8=`ZQ
> zquQO8y2L_ZM|kv7a<22;&I=1f2R>!;5XmjG`|X>24#aGT0>lBexQ*xA3Kof#SX
> d8m
> zm!S!GmsEA%=^>JEC#<z}{z4j)T@IS;a?oU#gOg;J0|MuOmt78U<aFTKftSr6Xv
> b1a
> zbMo062Ti;(I7$1oN7?sS_SQY9AA5&ly<<2O?Z>W^0W&dylGv8a&gJ+!XHE$`h_
> +o2
> z0;&G3ML^=hne*Hi7Zd==r}RLwlc`S{KxzVsn8Xzw?`5iGP}V%pQG&{}lr@zo%w
> xB~
> z0#{~AH#Wt4P#(9&L+$Y{QU%&$osT~;U`v|aaZZiFDf2EivItKm3)4^>ed#;{^U;K
> 9
> zAwDhnzlTpNLQuutQUof)ryJi~04kp{nK(Pdr!QM$&24UkPj5qq2}krN@#*o^m
> hS&2
> z_|y~v>1Rx^f=Oribm;{JK=LU)kPM&J8bJPE!KX+6Q;m65e0q1if%#SODK&B-
> VmvKT
> zdEsg}pZqC)gsW>9b%@T-
> m^;P&Ki^$Czo7p<W%3#!iCwt2)>>dlBB8DbTRc{^6{(NE
> zhUt{#;9(<d9bp}}6xYEWOy|4jAYGA6)Ti`yD6^~0*I@*!mCJa_A=_A`ptP!7CL$))
> zSv=j$%FHSpXCoTi+Q?*P(~h2~m-{~ukD9KO8z*I+l4~-
> }PI;u+;nQ40AVnC<9M3VW
> z1-*fDh&>i!8s0ISL%{2gA+T~MBUiT}+Cy=n)+Ai*0(&(i#&-Xn+JRfsB&!MSFfSLu
> zdVKCt#wT)u{aMI)2)>2P*~vq6FGMW_UouLZJP?i258voBvGsVT0nLMt>y4Ir@
> Cl@G
> z;K=$o<`p-
> bGN!@du4^p18xdY9>Z!F~^bgq`VrPH<;917jSO<gn$@d>tgefNHpR4-^
> zf1L-
> =)clsB`2NJy$ih7Q5L|D4EWD#Ex==F0?>~UclY#fQkhu_e!AwXle`AQ>cby$V
> zZaBdxNL$g4u$t=(S*c8tZHt*_E%xNGK1K;F=c~eD>nyI>u>LpDj;Lmz($}oa?$mt
> E
> zKW1P$*HsJUS4-
> ;|puhD0V0(3XMY#p~p;S<1dId9JOzRnT4|5pEI=0WcE3{xBtrs>A
> zID9=GyX|V_z$C&U|3#^+GE=v*4kFhb%fvCaUa&7*1N$w=EJ4tZG94PnzyVkJ
> tbhf@
> zlJs_>-OA?pCSus?-AgCnNUXqhGj@pS%9XJbE}k<s-
> gdu1jiFRt$>mW?HsN{uNnKPu
> zMnMzu1&SJ(?%G9Mljfh5S4Y<i@i|1+Z(|-
> ieTi_m0$@>zLHp*i{Hb0MyJ}DDytyH2
> zW*he8Fas8j{HHy~;nmD$m3V=B@tpj~=MyIn2<=paJN*q2+KJZ{QT1rInof@h
> +k|$q
> z(*vp_>`)}qz~uN&U;pz3_0K4-pJW%fRfY9OiGBSl!hPk;sQ#7ImT8j7p}z;$Q`C5i
> zzfE*4kSG8kX7%yiYH#I4`@1^%)dAWie3q={gr9EJ4UUV>3XY4mI$?38KkLh>-
> tb_i
> ztZ7=@m$-UKx|4O|M>;zEjfBSftMj%iFthtnU2#a~lfLs3O^3jr8SpUPf4`EQ?^Z($
> z`(me)3VB+T*mqt<xUbF&JD+Q_nek!k&j-
> T(FqLF>)6iJC>Qb59$dItIe(xeX0K01D
> zHaiE~IFviCAd<}qw{V4Lf>BAtv&(0eB;3O_*24m#nnz!+Pu08?ea%k>*KSx_Q{X
> Ad
> zXA1E1+yFm=eVx!$bdfbVM3VqbYZ=-
> QQbWNa8$im?<Z?(*NT8BY;$+=9A)0>jj1W@8
> zcB!~@xhD!)J7ybonZd=T<EW~N@z;g;>lg#@m%U{;gaQ7ZT+pyfiyOueUf{mT
> A`>+%
> zO6(hE_<Qj5sA0F6s?3y(pVD2PZZ(-
> RT>r`Jo&#BkFq<Le6Ut!M<lghLN(gMVk96E_
> zC~!@P0`HMSEgguiT(v?fVY_=eItv{k_aSf~ADialI_@M6&OTRDSN5tBu>4ym7!J
> 6f
> zYtk<~y<?{PA#WnWW_tG>fRVe_eOF;qo9*3B`8JP04t<-!ud>$4-ODBbJ#*)D2-
> QT#
> z9QVnnhEEjM@P29#qE}^qWCIen6YA4VVVkLo{2BOJ!5R3bA*L`VPUJ<f5Xogf)
> 9eP1
> zx6TDq*zQ5Kjku<;ZOwJRyvzVb3a0R~!toDymjE$IcE0;2<SClMQDQ&-
> HiZw)Rjp!6
> zbL;hU>y+Ue&kvs_GsJ1?@C|DCqF8Q&!mWQed~z4&hwr~wm_3n-X-
> V3zrNQL8fl6JH
> zor3v^`!$=-#mkXf;t6S#Rykf}Jv2sW99zi<N3HVz#(HQa{?k!QJnDL=`z0suS4ZMU
> zk$<EXZ+Th9bB%4sxJQ?Qb<tijj5)!veqg6dGKOWlo<$q!S>)X1b3XB>3{nh!v~R
> <o
> z-98FGtEgE{>ij7Uc;}zjfUy31CfC2~=<*@sDf>cO30aj<{eJ%l1YtI9+Ge<QO9}z#
> zK7-
> N^@eYfc%$}3)tA|Q2)KAUJ+)&jxkZ>c|#sl$$`}|3UI3$%_aY52GO4_u)**#Vj
> zBuz$1Hy0;ep`^NE{WW2!i+xh}QBK>YxmB`alg65V7+*TfC;7KcFWVpBCwU=Fb
> 8q7$
> z1T8{ll3KSb*3OEFOZ?+?hX4E$8nAe?N@#ywTj@5vCEU!5)$n*<g+-
> `ALt`?`T!Y#l
> z3yZ3*oK>fa$&an4qHlQeV%Z)%RQm>k5!xQN?LuB|=)JhCaR83J>Y>@UD&oo
> Zd8x%c
> zyv5p22IQ8%R^RotmVV#G2z7GD6_182WZ?7PA)(swTy~c{M1?HZto2^|hEVi)y
> X2WW
> zmr1gF**jt~v^!uNbryPJx%pmE-c0s|)F(@bp}-
> P?>?c@uOevLS_fqmhZV$kzGf_Yk
> zwR8A!enM!Sk(n*%z_8(A<>4bo1Tf6Far)xZexV?3bp+W5-
> e!>X%X~RwBR`V6nq9m^
> z;pNQ5ggXG+$li6kiVtejHpq(2Ed!fuDb6F_4j2Ws!tSy7E(j156g1FPdh?QmD>FW?
> z4uh2zXIGtb8oF_R!sUbnyf+<cb`$=6(p;S39$IW^o{+&vRrl9OMMKWxQHa(wM
> E6|p
> zYH3?yuy1zvY%p`Fg!{B{VAQ=U^>|sj74aS@h<l^+WF)?aRRXtegaH6a_5_lzt~a
> E;
> zzPI`~&A0)w$^d_?UT(OBzo}Q|--
> ZViU(TZSoOhsX%Gs5}#>$7jt*ZM|LeMaV@PxbE
> z7aU>cpDOK_QEBqS7Sv%SmHLuAg8#{4aI_L@2Pp?$LQXW`lXC;2&UCad1e(_t
> Lvx{r
> zCM^b<5+;|oxMr)cI^h<cs9~-XS8w=QLLV8`4-
> 4snQLPQ$r`Wg~y>wpysw}Q)e`YLL
> zI_=@(KlLZ#SHF6^&i72A$A^!yUa=mW)L<<K?`Sp?8&kUreFw0(oP>?XxHtOL(
> @W&6
> z{i%_<fH4QM=fj+OJl!EmZRD4|v|EOCBH-
> futg%mZwr><SJp<(}z{xb%G}MZWf~4r8
> zR@5}i7G>qy7ltae*a&Y`*QI<w_SP_6xl-fGs)s5*#cKkB*Chf$)Ezuq2;ZRaHWJUi
> zEr_{2h!JTNTTG2DZ6(;e%Y-
> ep>)hO>f2ueNQz6L7RB){df)c2)3Mz3|_=1R<M^w<j
> zH>)~w&R0&N&Q~sKI#=P=z_WvxbAlKV^@0Y*+<yrKK?7g4II2-
> 0VFOiAK?7q>=lCdS
> zSZico<EYf;Xv}Ce4~L5r9<~*S*-qVBbHlnhBr5lb$f-n(q7qf`5ES^&+jn!V7`zJ<
> zI-Xg^?oMD`;wvjk)-*yA7qzJb5sNH;Xj7*4L591bwwK>^?>4B;X_&3B+c-
> N&sdE}C
> z6nDFD=7&^oBRHqQvfW-6X0YrtO{q8h&!oy-
> Qka>dH11)pAYHdg(=bw@RRNjw6{`Am
> zasrGOck-3ru<v3ejF&xSDdL`Bmi1r%qyv^R%qu9KtEn2t8!C3F3;vSf+$lK~R);gG
> zrtyZ^yHt7*Q!Wi-vFxaTU#`3Qy}@jS>*wrt6EI^Nb|#f>SX;3o)jz(3^{|SdyB=Oi
> zZ(e#C<U51UiW_IdVs||($CwIhuaa-U@~!h;<cvt;sBTWE$<$;=|2LnloXr@uH9-
> =%
> z)bJ(OKlyiLE0Ywe8fnH|SYDJpu7i+R23Wv%t*VK7GFDgAllHFfT169OquJ#bym;5
> c
> z)J?VW#E!zbb<X<NvOlfY^+P&(aKn=`D7&m5F_-*W&8e5e_PQH-
> XOuOLl}Q1eT31)m
> zv68lQKI{AWuGEv`OF8`h=lAn$>*q+=&%@Tw5oBNujU%_)0ixj<svrNC)tv`@Et
> jR9
> z8eazZ{`^`zG+kJWho-~d8=YX!Th=s}IuIC?bX<tQFl`u{X`E+^;@S3l?)AMwpt8pK
> z+l4NYfX)^z9NsC^R372wQS%6qAie*|5O~r%DAH@}Y!k<6FJ-
> nG>HQeeD^@aWC$HaU
> z_0=k8+J4v0-KLL<*fnpc*siyX%>@Q3Z7;d{&czB={B5UZEKle2`ttd=sfD1=c5A6R
> zAoBg8@E~fi=mqP=T+TO}hMw7kwYBs((y<`tK4c2aQ<7J`Vmg+$CeJ=sjGH_0b
> !vK~
> zJVwbm-
> >rX5US`tfQzk1(ZkgS`**a6RLw4!I9YD8jUQ$+bRLOa_QWaNOpg<Z5tn-~1
> z#aLTISn>aSZBfN&8RxrW3M=+0eZ|V`78X`4SrO7e&LuXDW)kIIt~s%O?rq0*t{Y
> wQ
> z-ie7-
> weBH!MKAmDjqTSmvhMJV+vcuUsvo>z>E~D1y3b8Y^%YVv=o=P1i<Z|@U-
> x&%
> zkhAv^qz_mSq}(NU1qoUb?tic^fkM~!llbJvX^p%TD^WPH`yYFmiEROo+QdGh
> v?G3E
> zKWY>ENOpP23sz=xNsKbzK24bt+pb@C8-
> B`0W0+?)jdng}O+=u(4+@FZV^FOc*)%fE
> z+#V^QVKr(&F%9eBT;pix;~QuKT}cgya;Yym4Tw{>vD^~m$J0#aKUFMS5Kaoh(
> ?ahY
> zElaPc5%g3ImUDLI=r|@465aIDIV@tVNClu+uyHDQ#o|c)KQ6i>>Cm|7Q7G+({
> Dg+R
> ztqd1Shs)G#ZfKr^P3<8+5C$SAad>mJZ<LNYE}2s=*T^&j%}Hh0#%1M+%*<vd
> TV}k=
> zhO}2iC{afmG4>equ=?WH<`NQF0jN~yM_m0-
> 0*3U4^wfSZ9WIXY&J6RSO(AbN^y{uX
> zUJ<6#Wv*|@T&5b@#_8vO+`Y)!V4BNu@56ttrX{Olv-
> `;(G~pl%rh#bJf>|c;n9#}S
> zM{|Kr*8Ax{C3*RIHf`r6ou?Pi+5Rh{7u0f|yAr8nC}V{fC}nbwew5jD&bEneQ&8
> 5D
> z@ojq`VCmvz`Ka}8_Vu3^*8h=d>i+?RA*$b}OtzCRsm!iqO8o<WLH(n?{<nnnK
> WBTu
> zN&PRZ-
> =|FOSN+QDI&E?A^wRgg|0wmRMrtGrmoLKV*e$hs@340v`>4iU$Ue$y#0+I_
> zhGTT+`8G!H2;2CMDQ%qZzK-
> ZIf{{;|yp4QGWp+QGl^>(wi>bi3gK1!@ZNG~22B?Dx
> zQo`4`Jgo8iwv~&Zg0GDEZc$;4KBccwncWSAH9kd;q<N6ys)lnSfxb$;4cO*Ladk?
> v
> z&ez=-*4<oOH|mJ<+#^*5z4a-5-
> OB7<n3?ZwuGzC{?;D1tca5Wxfk=b_!<jCz5zs_A
> zS8Qo1hViRs>^NQHz^M^2c$Nz;jTu(SefI6z?N@3>89wh2qI)r|{}$pEehU!_zg3
> +7
> ze(%-
> qSul}VKCfn0@4A{xGgr;4erfQfpQZ+5X~NQc5;rG|tINmDA+By#FP^3^pNB!^
> zyqX33Uiw{Tkhf}{Kg0rV&|<EdhneNP>b<$WKiT{I-oaTv>o`pO=u0c-
> &B^o=Q}@!Z
> z%J$xTTm$KDiQhb<fwZejuHZ_=-
> B)(Zc<HAv4W@n?`@jc3^muj5Ga&EbYIzkHHmNe-
> zq-vUk4X2v5?nHW0laHz+iXL{HOq;Ad*4pLsDrw8(3-
> (>P_KMtltid&c0A*B8YH&Xd
> zuKOH6H9>2uY3*^ewsLj6p5C7fG<a6>tiEz>*zga1AZmBOK85mg_GNkYX{3OC
> a^?-W
> zfPG55$=Ij;Cee=&-wE-
> TKyad|_SU3QCKu{QyqCK<o=3jnH;dOOV4r?8Cj2X8pF+MZ
> zV4vP*#lg3Iptxe=+xnn1QN=!`uh`h9muD1I{4jGoV4n_mt~)G-
> X<e=RR8)Xxn9MVE
> z<Kep=-f-
> %tX0YMFFtv5``hEI>MUXWs?7?WZCVL5U0(OCt#FN~Hxu@UpjIz9S4l9ha
> z+hOct3NeO&{mtR?EV5CNvF?K<x1B_R#&1y7VfbLe;A|u#3NHC%btiwi84gAb
> gN=CU
> zWv%4PIA=Y=R`dEN1J<H`uQ7$wvkFE;Rch2u>ce1VBvZMuVTETEXr&ZYv=WA
> DG`*sl
> zYRJH1nrWF+uZyooI3dr>&y<7>DdG@_W&2Dc#R3G4M07?Y<JUiFd_(JDYosN
> *7!U@D
> zkZ6*q9APvtsNbu4s_Ay$(z&Ez?Vq}x4e=L$4~D<)nmKtkpvwIV1kd}ihn67&z~9
> gE
> zSjU<EE}#btliTLGvu$amrt$RB<v=5K>++cH1sKn)ST6pr%3W7j4$MQ|<iY40_7iR
> u
> zqWf@V66MVEA9tDB>L~ojd#?5r!U$KM6o_z%7>IE7XRd)rgmhqd@6U{IJqh7
> @(Fj+a
> z5w4nuaETO%a8(9`>w|@}-r8#-
> ht5SGS@m~A9akEKPpzpg>sT&f!||QB*37N={A+Re
> zC&5JL+M3h!1%t{$(7C4ObbXoBLn&iR?kef1biYEhX(AE{9sc_9@_;x(WURjAPy?
> 3w
> z<|SgXfp7r7P~H~^B{~<&0mT)+TJoLtQ_bf2Oisy8w4dl5Q@pe{JzGvGh9#!YV!1
> X^
> z8$-Flu-LpjyudsrOw{%exB$!S#={e}T?OwOqW3JKqlwzvEc4+7+FvuT$&VekCZ-
> x7
> z>HXm=dBL9p6Z4=N!ts;F!;cMB&$7bFkv4}J#J{vJZT>PMObzh^{L}_H=$|yny1#
> u4
> z4ajEIj!u1|b`x))5Zi{%$4&gh%et{^F+N#cnk&sc6)~+L@ebkJj8eu<yKvH)r#tHk
> z*b2KAcDA@+AVDYr?v(Gcp}+TcIP2KNkNW}J595rDq4LH^mnH`i9Hp4oX#)IYj}
> mt&
> z@y$Lll2fbd^+`S5&Ze*`HVzWq(G9|*xoZ8F#7+%yN5o<6s`N{}^&*UC%Srq%j
> uMYp
> z55ZpVl-
> K~jBpoFFo}<M#yN_b(ZZ+KRZ>!48z803F+5PbZYd%o7t^5R&9|?S39qsYA
> zdD{aBK1l@Olral;YIum@QE;3~!*s}8gTt}%O>?!_#B<LOQmb4oZmkdMtI((ZZM
> *N!
> zE$!`vr70KZjl<IPseh=a?&US%j`uNCJo_F3nq4dksNKMrw74qY+l2eosn*KA3gy(l
> zz6xd0Klc=u0c=<LZ4bOau@kj-
> f|dva&+1&PfSz0<%0E@2uV(k9u&6MSZWF<@+9Jd*
> z0A;~=A4v{P(Jvf0ihjYp5ndsjH;emeW=U1ohZyR<ie37k%^Mr5ztYRQ*w(7<3W
> 74T
> z)q`gDdVl`{Y6yves=A&bb*A<<gGNahHyD{&9Fjdk(_p%3$gb$n0sXI%Be;Ypux8
> 9O
> z4yGLX*g;Y@G#$G6IQK==yVyM}D&;=dXNhiTJhZAb_c7viW!zm}`HSA!eM|`{z
> hnaK
> zWH2bVhS3At)UJfPJ`BL3c7H?DKnI)ZA?_8BGdGm6G;qI}$?WmABs66B3KpN_4
> o%hj
> zG*xxF6C_ObDrBcZzU4zwi}z@lJI-jEaLdeSh;w;!+iUtN6fRJ@Sr|^a>(F!pa@iny
> zM;F+aVbxjT9w7;8MBYntC-
> +s@XegJUBqHXn;YCwuisCAuSs^`4j=o7s>44;k9=4yF
> z93qT)1kNRl6#5PO45N-nQG`pD-
> )8bRXq?p~(s?)OjjDKh5_es5tsMoF#y230zxUPR
> zo89-
> |TttfH)9>YX1zkdxaNYtVi%k0#_qjjXp2^ZQdU9#<hU;(3r^%uRQzKPQCwOcP
> zrkt&7JbAt8?a<mD4y+QfT_kDpgbDjAOS;zqh}5E3`wUx)CkFH>S`^RyBI>85Zw{
> sl
> za8kZAY`MY8)N<p_jFo%>Op<aTDBwr5Fb`k&nJE$xEUo__32O3(EMv(P^KBRK
> 9~eoe
> z@<LQCYVK`l!$W2~pE!9gIjjhGJ$OYXFBe&h`-;Uog_KoWai?J;j-6s$<;RlG6x8)M
> z#dX<M`#)j@bw!DNT`I!;@ec)cp`3_kYE@bK_;7(Tc)e<We^=0kUzAPl?`4H;h!Q
> 9F
> zMEzY`*aqwGjw$`U-}m?T1$EtAT$lCt7ZXSFu#FP?x>SUlU09dzuPU3=-
> w0cR^|Nzb
> z+;~B@7Qq#bUjH1=nHH%adB|_qxfh{Qp<F~7w68)v#2Bx*MmoC|$1MyXHC(
> S3)<mKW
> zwjS`+NUyy;o3gek>AH~$bHWf9*?Was!pD?&2Ya$&vns9)9AaU+z3f`8$ZN~vR
> o$Xr
> znc9_1BK9tYTb$VnE1R9<R~`nqoO|?!eXww9Y~S+Z&8R;&0Na&Ww$d)i8t+{68
> IH!G
> zv5_J9$`mwhxQ8E_-
> nnqIV%Ys~FkodTfw@mW4LaY3lRX9NxW&pY1^*Qd>s<7CA8h4x
> zEBKvO2#0K=Lhev7f))xvjT#jq+lO4O74kn6%)C`&HWF-
> 2U)kIipTGkFM=edloL;sP
> z7PV<Sa$AY})AEF+fE<s(oTi(vo!*|jnQ=FAFrGQSp*1eAW|;I@(CnLl+6_-)pI*7B
> zX`EH<r<qy{+E<D7<f7K`RY+&yd>WeKlO(GJ^cMfKsl{C^ZX7Cc{{%RL-P*P!4(CD)
> zF+<LeY7CpkF%UtwcrGQIoylTcwB}{$kkT*w+>_p>aoHDg)H3%}TSv0;%_2%|P
> +M)8
> z6YeH20QF3LdbSv*)M8_sJU(g1n5nfkP=XLMa7qz0psMR@25c%k(^p8bk_A|N
> >XpU*
> z0`|7s!<u1YaU}M#mwRekfYtM1_`{A<VbWA_!rh3bhau~$uy#<qOfPSS)CoC~
> _gw&y
> z+@har`Jo;Yud~?@YgzJPtr;AV8#7@YTDQZg$E5%o##z<`HK-
> @pe}y&ZQ~zj)7y>a&
> zYZwE)hSV>Z|Hxk>1}hw<GSG5&#r{_)BUw(K<N)m#dw&m0t$ny5N@CqgE#6
> hj(6*nn
> zO-}|4GcnA2^}&f)lVvKecJqyg<u^oIHoqk}oN!;aLTcFP(1~}flA34YX7d?|hjp-a
> zlxrIs8b?=I&`NK&x5NfIicYxeI4_e5PA;(sS=xnRRhlgzN=+v^7dfQkioUn_N`+KN
> zI%@B>=8bO`51a>0o?m4h-
> 7Yc;Aq>_FC?z)p>mTyaz7oL{ss|#P{FuWY5Qu6WvBJwd
> zLxf>jAYStbeR{{Ktb1s4%x@F=p>a7(dQrOxDU8PL2IAlZWt}eDg5ly6r9>3mJcsH
> =
> z=G5u%yY)p1uz+!HetWUm{hIsY85j)X-
> o&w%Oet}w$R*aba#|@s6+%&Dp`Etxe13*+
> zuC=YZi6P-0xffHf%x#~|C3G*Q#*VG(eyfExy@=vmZk<h5#7)CiIO4JD-
> Ag9I3GQbK
> zQ~5M%w5dGTTtS;H*s)~SZVD0Ec<z^!L@4`=is2ss&H#?OC$kz~AG+ZWmK&(
> n1Q!t3
> zq^sGO3-
> E!^+}D+Q<r<ce5FC+447S|LPmP`4u>wq7u<v2GvDiz$Lobh)3uI;N?rFfX
> z5~V0;*NMRa@Z#Yb*^8)P#3XVf*8dTJHqRg+E&uM=H4MM?4B1)10Oa<B-
> E5zuS`h#T
> zv_x<TKy)l1_$rN);<KuYm4Y|M4N@QoCET%V!_j>swGg_ow1@GH>I-
> lP49#QEG`N!^
> zHwCgm+2NT{&;^UU0Fl6#0MK=k!4-
> W3V>W!7&Kjv{tdrH~OA64kApP)5I*K9n&IyPN
> zJtd0f1t&LxM%JL_3-
> t$i`!5WH=s#q8P=u&s{zUBq1v`Vvz6ym4339dGiAic~O~*_h
> ztO52JF>rZNAA<O6ii$9|df4J>N%iYQ)k9i(?4CTil#)Eig1G5kmvty8$IkC?ebd<9
> zmu-
> kgM9YkxwT?hybj(Y1(mUz$a)MLZKAdb1h!))cL$HiSuDo>pc<2!O<@@Ow+|aS
> K
> z#!53{<rwzKr7}rs*?@Br$i3dA;YdG&b0T3mXiSHDqyCq+&ki71)qS4<0(m`vxX)n
> e
> z8zDvvrUyWP+AMLSehmf?c}cMa2@pY$05Mw6J&!hrlbgsMc2gUq0k~D`ra!vE
> K>^3s
> z?q2I=?o6<czR7fpHS^4G3nEN!$7W6`2%Xk|DKl~Pqbql_n(SVj<gx0+%rW3C+n
> Lnv
> z^3Ed)y7@OB3=b1P!Il0dpT2!+dIe2RZyqKf*yHpjwrvgU4~>41CQ;AXsm1LCOth
> bx
> znXQ-
> ROsx_ycuJr>mEXXelYEfTc2`mYbQqM;Ty8%hc`u=$QMADwM=#1E_qj2~+!hbE
> z!SGXv?BqQHnR$HL{UH3Bq<V#$XFEtpVekp*oM0J9v249UHpY1^1s1aM`SmR
> |@_(nl
> zAM%yt`#W%y{*M1;{hg@Y0eDTWZ2eL9GqVMGu*E|@6gpe{HjRz%s(m*X4r
> 9n~o{r@^
> z#G~20Y)2*;B_yxoEn(7~hJ?{MUeC=2{8G40%G4gBgckRZFJWTfuOE-
> +Mc;++jeCT6
> zdsLNe$t&G&00a~70FUH_3xph@^ke%0icX%bFeZwZh-
> _DblXDbCOM@^qAz4$L*AbRl
> ztP+sbr4}n2=$Bfov{;a&7Arxl<J`UqrP<uF6oHxGm^P5GN7lP_Zd)&}+m+l8!gfJD
> zwOGFs2&6m+qgkMQP$$t6kumo#zvVoGsz|u)rUfatZiSHlY!IgQg|Pf&5T>SXQ
> @sh7
> z41)CKW>w0I3OWb*rlg*2Jd)M#Qx8;8vpdI5{*_M*Y!?;;6Sm`6r)?H`nf4@xHJp
> hs
> zYMiWLk-)O_60_jvCIK&TI#mSOkO(wWLz>-w--
> d|+>OR)^N6I=|#}GI;|7n}&aj#`y
> zLW}PYP9RU%Mm9f-4Ie`)a#~o2de-c23hU^rFe;<j6hQi<2*er>7<s{;e{K^-
> wuO`0
> z%9sC`r@@LM|1n3i-
> }ab!uNlcO39uB3_bs``Ax(gq^ewFcTCALh@CN3|7w1_#<`JFl
> z6y-
> |VG%pU<42L7`TXvK3Q|9gs{k*)BOuIYZP1rjvHYss(+idqEMiugums@34BtiNu
> z>TIDLau#WaecC75D&3c(Y*q_`Er|qfq>|Ly8)ITm<J&g>jy<M@WtwknaUWO{
> *2G*4
> zq?@xS>hnRVN0nT93gE|Ygt7J>GROT8x-
> GyjPyg4mp}QQ^nuKOmcG83clOE0952~<&
> zXslbd3C$Aj?_M!7Ei`LC6YL^^d!rGJ5WBG5MAsls<Qo5+F#;s2G3|P&2KD4&7tq
> t@
> zr%(p(>7l!bydfc+*;eg-^eew+Km!X?2lNhnI(rH}9nBvRV~wbrE1_Us?-v#{9Z0R6
> z7i-sLR63J0FX8^yH1hawBIewD%()5IR1kAvJ_hf!3kqT`&c|GwaIY<hS(1-gl5i8p
> zs8_xoRJvgcmM7eQ7R0Q`$E--
> Wr=yt8wKfZ)Y}X{*zxYUya2|H+1qiDn9!cc!viWR3
> z(;saL^d=|aXvvf&$BAbfYIfKALZ;yL@xDmm^=^Fa`O-
> aJ1GXCj9Y*_wcGTy=)s}+8
> zvJJJu@b=ett~<12loxhChf)h;5>as^Xw%JMNyX@Xudm?=8x-
> zavkf$mnslc^p(?jv
> zJqx&?X4yw|yfIudwSs`RuRR)X6mN@#1kV%I^)Ch3&ODVoov(o29Y<2pIJg|G
> DR~NK
> z`0EL+1qR>!VIq&;0Uen{d({DpXLiOAUj{PnExpt-KmprFn1iXs`t>%1%iTXSPqw!s
> zHGyRFTh?)Iats-*``!uzD~rL&nc2z!vD!lseHE4)O2_h0VfE+R9@US$IV|tv+Y*!u
> zMF^T4Xc)C8W)e5lUQX<~i;}So+7xIquc)M|L8@Yj$t*L!DPaTl`_R<mH3-
> sk4_V1<
> zMxq8<e61P?1ut%GH0upMAq-AS-
> V0v=w9W<%lS}ko>V7(6B6aVqVVg=T?4gHmnVWZ`
> zZBj|qeo|YRtM#A2>x|UmCFt%;I$oC)hwV=02UIupt3&IekAebydvqSi_;Hicc~J
> !%
> z)Jd@af>XSq=KCAK7SwO0xnC%vD%A}6MXs$}?elq&rFQ#SAnYk7jL1}euZtXZu
> !Y@L
> zi8}+CP^8MB#UHt$r~_B|Pdac_*nxMqVOMYsFc10Ni{SDn+TVmbPM88Xxv&o
> R>wXhg
> zCK%C7`HxhuiJ`nd+~KbQ+@PgZUEJO)fyS|a5RW&~`TQvG-
> BAO|$>_+eh?_<kkRf`L
> ztXs?)KYlSk3H{91kCG;p$?dyb9Y9?8<N?)=xNv0m9g^gEc^*O#aKnr9=+%W3dZ
> @V2
> z9SxLs4?o(KX&36&hefUqiqzI^rtchsk{Y{s^;HN(n%#f(S%)RPTVDD-_LG#38AD-{
> z&!*tEvgBMVpG_pjO|E{g-wmF%LQUtS+;P4ha{s0{_dRc;ZFlP@-
> {F5V9HYa7KeG;#
> z>$k<Z#ulkF<C&W8YYbWn@^*xI@Ai3<)pJYWYe?^bc@a7a?N5sr$B>?c`nJi~i
> OQ`I
> zJJAj>{)TrbR`ySlG>STe^yx@4F=f3SJ&JxjaPt8QZ)WWCYf@k15Z^ipivvAL3x`;J
> zIFBS5ZT7RopjF;>PX(my;?1%4+lb86>NA5acyw>u>0zQw<>qEr^&J~lP7zBWf5
> >Eq
> zDAtE+Zd*(xm>np4O=s%yxe%BnGlSKoAiTwW%p?MEX+h$?@=h8O8-
> 71zcG7xS;!1pX
> zo?tzjvMxnC{D3~d_!xZ%<gDs+U^a))XWlx*abu~Azkl)bB0Nn@!yES1bv_<H0y
> -e~
> zsrlYQA{eVcj&V<wfHTHaRd~X!z^?~v1hWJQ)>vQp_Z6&v(D)g-
> twpO$(4KHVU5pX)
> z)^QC9_Ye63xFHVd>BT>?R<$qi1Vcq*bEa)Y9)z5BywD#~CVN5sxv%8OVkkO>`
> psLX
> z!crGow_@${e4W1Y5_1L}gKS9{9$aMfsK;$jzmFtu`U~)HNJJ%EGv>ILaSPIRid*J
> c
> zSx?v-hXVdG9yKdCD~Cl=EO`<oByWS9p}whecm76bRvj=r9VfV7AC%e?1|5i-
> kg9E_
> z+paqEI|exZ0IVIC1ebJi?*21e4edwnbfMxQ&i9Y2?6}(!70EoIsF)60A+JA_uCdX{
> ziCa^K@AwRpuydySh_4^)WL{0;nj-
> 8B<})mD*lo`6Nk+5P3j#o?nQh0r_x{X7hy6={
> za}%|3rVs0&jR*NzON1JXR;7>d<RXeUT7G~i5APrS!b%M7u{A(`QMK~=DsF<U
> (7%F}
> z))#2;6SYgiO6=S0^SO}*EA@Dp9C&yuQrYCI5M*_s;Oq2c-
> 8;lFw6!N6c)PI+Uq2*(
> zo1t)p`!e&~q_F3^6Q9kivV+vgO=PhGT%!?w^O<))H6T8oz<V^>l!If_Sjn4aNg}q
> 6
> z(~}Pfi(+kS!}{wB>p#WnCtbb!{7^ytKDDo31-S3oGGNY8-
> lWRmrZqTQuVuTMd%cZE
> zx899Svt6f;(<ClhBLetgKT`-l(_2V0Cf`cH4;w`<I6O0eU-HX@hh0eG0zU%b2ZT8i
> zWY2d4zsz?bpCOrK1UwWcerg%LFR_o%k5|He+^Bv?jL6MpdN+f%%JGhxw%
> >c6hVG`z
> zw^}lorpiAM6L34=Z@N5dG2Dd~^j)7*`W~%k&D&NQlPiOh^lZIHX$?LWU4Wn
> LH#a{`
> zCko{kBk>)H1pH#dyx`UxbAt<wU|GyN!^M^TFT*Pq_W!`Y?d~4<E^o;R$U3}P
> _g=md
> z?juhLHkG@(2bC<0%>IP0W_O8?T(FNz0EQ?qdE``|_aGk$cUG8p;9m>#?&Yi5
> &GeBr
> z;Ak`BWw)7T`<xkK>}-)DkXsD?T_b!AaPwjgZi)PiXc}CL4lvu;Cwm%!!a{!9X4;M=
> zyH#C*NrE>z;o||5G`vqesY_OqZlZRGnahC5fLT{0+)bNwg`}P_5^(zfZ>%j!mmFI
> j
> zX2}|m*a%tpg{Ot#E{9;lLv@0G!;6p6Y^-B%{}hew>)xYs`RCq=hMYr**?t1tTlfgn
> zqpfpjZe1do1Ny!XSwXGYov=eBswQnkq#m(?)}2H5&nxc!eMjIUPH%gSdls6Isc
> vyk
> z+Kis-_UhZ}!wFQ7U#=MD7w5m0J|-
> {JkM?{(Q2logE;WV@{qtUfp2no(YV}MPSl>yS
> zxnvRK^j^t3C0{hD<aYv3i%*0-V|2KGEiC&=Up6`4TAVXR&Y&eer-
> #1#ZK&d}Eojwx
> zElf38k((6v(5Z_T7Z<l<8NGWzKi0*dux(*s{R7rT@+~gTmsA#wby4%L5A$vI`Gie
> X
> zU4u5<y8wm__f-
> %`Ty1UbCBR+Ehac_$jnGE2W2kINzE3r1;sq_!WJ|b*o>YV8a9KLJ
> zQ;%4oHuTGj+ZPS}uOMVHf%p$r?bNQh?#KGJy3^HRe!=C^;{3f!)xT)yZK~r>?j
> 6C<
> zKkx&COYUvtlt{8*&Lzp2&1$kW`<8E2%Uj&KFmJoh+t<C5E(juh-8+J}wu!8-
> DS)a7
> zNON|p61KQ=Z668ND>d~dit8O*0-
> }NJ+*nS0!u_08k`AXHvBGWaTZ(g3lOwrVB;Uq9
> zYqhzH=7>9DFSO@BtdFV1H)_Sl=iK6?UaGpzpqRey2ZA>Dbw3!qwN<$lUMvH
> (A`OCh
> zWle8Y(p*)>vT#TvomD{U5i6m61$Wy71!TACttEhgxSfpU%`B@#OSh{M2~k~N
> w}`Wq
> zo>l5}R%Dya`#q^gjBIy&48t6&R_#)?dRn!5Nj+lCRkio=Dfnl%>Wyjz0Jhhv*76*s
> zTBXic8&GC%>^ch=bp4m8Q~47?d#bvHnyJNFyJGF{=<B{Ws#b4>z2$~u68Vn4
> rl6x+
> zm5^IgXkJw43xcmL!Zy3Ps`l+Hsi})?;hku|K+DxVWJ_eT!oOzs_pIeKE0Oj1m|wt
> Q
> z3~z*@=ed;B5L(|Lo2Tl9apmo|1k0i+@E3uJU!j8qGoWzQ@e=_he~Y_28LT?1_
> 84L@
> z;nhCuGMMnyx{TJ7fHMYKbTp7UTin7kg^b|5`d-
> 9H<F^U2J1bZQB`|%0D_cl4iKT8j
> z#1$ZqJ;J0fVy+7I%R8pw7p~dBx-
> ^TKkawFu4ZrY0IDbQaVL|V8Y3o(E>Sy=S#b$TG
> z<LYsxF$EfpFuMDve6Sw-=-
> u5zDluXxp5?3A{hkYK!@L8ZEy%l%kA(ZNj|Lhs9dr+Q
> zhV$cpHqRiA+>hRU?}iq<kDrid@awIO-
> j}<B(fgJ$DRs#>=_YDjo@YRR(!FK9=Na^L
> zm$AlW^#+D1U2>2R{~D}dLHPbC+&%Q7@eK4_|Av>s`goq97kqcG<p!cmEZy
> Bt*Igwa
> z0jCf+;Vs}4x&^9)tLsv$#VPQ~O3!c1mWyMgV$nV$X`POii--
> 36<>DV~7ctj;P2XEp
> zpOy=sU(3a@#rYS~gXE4s(#K#Kwc4M5O+ZRJZPltP<`g!shdUsjI0e1CcNwQ}+@
> z8T
> z&14lHE+?8b>`%k8&-
> 7)}rt0FHgDY5wJRAZ7ubj>9a7VC+<xKqMTeZG$ihE9>wz#++
> zic5Cs$FCN?u&;%Mec2aAGfpbbw@_I$!aiTXM14HWcU{<s0!{(oG1@VA&JX=?
> _Y&Y<
> z&qu&1<k3><^yJ*IQ9;W*y?ec#SP`c{ZdQ5~YD0f&ar>g7-
> w87;Ch=a|`pk9r>pQEu
> z#U%Rt8v4_U^H;-
> U77Tr`+P_c}4E?7}o>^y{!kNW6`!BTt`d1LOsO8@b^Iqoj!YQcn
> z{G;~z;xgt_hE{zz2Vb)<$tVdMd-u#Ln*a&-A3qTpnVYt<Qjb`P#uS`aT;NTYFjD90
> zCtwO*5YF_zCBT`7xUYj9!_k<62ZM&f(u7T}atkQJ%Uf*O4wwQZwbhxYU!8ejb
> >=sw
> z)%gLv@Q)kbc+=|q0)PruXF>{@f=pIvSd&STUpJ>^3e+xDtEW|~7nme|t=jwb
> V%6%c
> zaCOdXwLAq(0T=I)X1Z#pFa;mSoS}#*_*=kUz!cmURjaqc-WD+h+?%Hww-
> $FaVhT>6
> z&?2Uws_O&5oVgt`231{`DInUtLz=IJG^e{aL19vl=(m&uI+wvdY`xdFMAIqZe(R
> 4s
> zh3teU7uvhC@jFBb@Maam5}Jp`bjR@h3%=PvQm8-*_TFBMZ1-
> t@>ao{zDIV#z-a`&x
> zpp5v(`9y%ivz`f1_)fx8kLWkn{&xS8XupUiXVqjFW;MCRHTWj)9ZKXmN_InPG`
> m>w
> zJh>&QN33<L!3e#`Q?|WCg|X`;oW`h4Lcih?3ZX5o$ye>ywZgdac8+f#5)jpl_@=
> vy
> zp;5T<hP+XAvzvFj`p>q#;R&02tey0-
> #e1Bue(5JCKj~M~GoC^!6CA=AvQ41)rWgJ!
> zzKK-
> R@lELmA%P*^WbzjJwEd<DmL!Q|+Vz68r*@5Ah`EhtBp0;w$YX|{7BRV^;69?G
> z`)A!RJPFR!v3V?)UysT%tXe;;=>o?m<JWj?`)l}pO?x%J$FyVP9IvYCz8buS;O%}M
> z07t@IqDoapytZR;YVih|7eilFlI;DYP8E-
> U0#Zg|45}zmryRD8GSA42x&yGO>G?E9
> z;q)%uxQDw)Q^Tcce%I}(srvM{716q<>fi6!r1Iu<ui=rIE%-
> FMpAT9?OcY&NY9h!M
> zH~5SN8VGZ@Zxa9$?wgZS$}z^j1SypycNI1~JX>7P<fII^O9e@l1k>Ev8ii)}*OQa
> #
> z#-jHHNtL9Cot_2go*uTwaY*j~2li|-4?jy60bg8hR^#REv-
> q7w+&+R`{m&sqoM>D(
> zh~50~cMVE|oomeWq2pc2zXEQ_HJ3BPIq`WTS~KkBVA(+BOzU8J*)^PYOs%;
> F^MfEZ
> zX@*0sgPCQROI*2GZK;HWx9Kco^EKc*r+nX6p=Fh!7%~@GrQ92c@=3SKqf7$
> I7fGhR
> zqMRco9p|8bGMgSu6NXZcRi>q-
> 3eKNUby?z?MXf_OOYQqK()wWu(1g@Y{oILUhS|Di
> zq52l=n)|E%z2|-#;OxCTbnIfy0`s-K%TNYk>@ISHBfG*YDo#r-
> RL5gUon=Z6!Yb?j
> zm+!0hk>iU2`P#k|ZaO;h79~#hlf#N|tGSOunW)sRbeN(r*gRwH(%3cpeVV^F^
> Y;LM
> zvGVfr68`L8sr{CfaKD_pb!qH3{DJEw;XmGDGCd6EYi!Tt`Fb>a9dPEozc!o+);q8R
> zKjTapBN1}L+w6YyBTK<NKwZKtj^$1zfhQdYG8m;lSeU?0kI7_=xqYaleWqJYEY?
> 2h
> zk}2pq$5#!y;>kmP6Y&0{ER1{01o*J4+^g3nLo75*3Hv*DN`D8AsxOr&i-
> |L&hmnL`
> z_;WRqunQN<kc1}`fydf^zvJHZMiMsh&~;u+IBreWJ!+WA4VqSUaCkP5C(?j1B
> ~l6!
> zB8|3AiImq#A~lbv7AyI%%l<^O)6WwVBmbDnY_<e*sZu0$S3K3rbQ%Z?8BU
> WI^zN0e
> zq?a7#KdF}|d3%{1as<pN%K*KljR?_u+%|?0dXww|mxP0j&^t<;ypPG@(ff<G
> ^)+n`
> zEG95TZ?^r1A;xGx%_Q`7#MwB{z`mlamw1Ry`%Dn<$A=~%V7y%#lUYXf%RA1
> s9$%Zr
> zd<>u2ORiN%h>mw){sG}wY3_%KSh*>TxHw~n{<!7_4J>YYb;@P`HaiDcVdnrF
> _j3-g
> zX+J01L}8Y34lvGU8$j*N&2)YHgsuaV(A9iYTXX-`Hy5O(4aZvnD-$}62foI0GsWI|
> z+*N|2o?wLmJv)$IcCF>boxl)lPr7*}#sHI1{E64CTN?Wee^>GM3I5*7-
> yZ&A6(tp=
> z{OSLSGX5$m%1gca&d-
> 0b5He@R`k=Y|PaWv{NkmYC1AQk*IpfJM$9cy68PJe{u=%!4
> z=$vr9du`MrULn%=xG!jh>Rm~UrFWmQ?`y;F)X2qw)q=Z*GH7aWfFWQSf)hQ
> Q8Kj<A
> zRrh}|Fv+?m$sI;n*2CpWX2$)(-AbaEk1(+bi)I;tnkf1og^sd=n>S!>-L4Xo<6th!
> z7yP5rC)|u6vPY3lkx^j@_xulh&P|HkqsXQ~81A4ZG{!BiFG#Y5Bsl5kmjyBT;G}}K
> z1*tX@k9%)^8=A)3Z_LyxLqqF$`-itF5PN6e93Azat+-})br>?>9Zsj#4aC~tJkh$J
> zQ%JfNqW#n?^s=pzOCfQUD-
> )cFR+*5Z&>ll)(81zn43IGe_ynou#Q9v{Se^SoX102*
> zmYkBQ)oY7$zM-
> &6=JooR2{5$LPKmUiyG>wdXdG|Hd|t23?%QE%qbj1@_*7}_C&xAc
> zJK^pM6NtL%pjE*=Eq34or{Cq_VGqL>@FUwu-wqeJ)1>FDwb6ZF8-x-
> o7<ZQB6}Fv?
> zXcoyXa1TO~BAOK?PR=KXzm@Gdq=|k>9=-
> }BDLC(Ly{0CAE1N%<8PxQPU>y%G+SsF-
> zE-S35J8YJ($?j%bo3BYWP+1PN$>Y-
> D=w3Fw+4_6gu*blsH|IM0!pqyn+5USuDt9ek
> zd#mjsOjpbjjp}u5_)bcsEat0S(RMg}8OL7_hgY;6F216zAA67BRM%mDMcZKv;M
> |(k
> z!f+N4xTeFI;CidWcD>c%)UEz{D^8#mU2nBZmEt`>CtUsYR);02I4>-
> Ucr!e<@odgE
> zVp}hIBq1?OV6eftGHV?QX-
> h;u3ewa4!W@rWuN*b`9AWtwRa^N=UwjFZd!yNQ)%iSO
> z`mjBd%0KU>KT-
> aa((8*`6qY|H>Th_hnAeCI1N=o(0$Gc~^kMs_l>a4D^F}=m(+Bk3
> z3)p|XNv*cCLes|2FgO>*V_g%BN2O=VpRh8fSh$7dO-
> cX5S4q!#B6&453QSiECzqXv
> z!;#{RSBSI5$!=UPrLHSrA%dA@o+L&e&ClT=WpY##Sef1F-
> ?j<t9k$8mi|xo+&MO;Q
> zYpPN|w}}znyXV^fNvRRuD^-
> E32`*n05s9@e4qNhy$>Jkwf~CcI?z+O3_>{gS%IxlZ
> zINy@o?M&B(rka!Y8P9Q;uHNq}czamEUBwlc-
> ^L27;B?wdQ+!Hafik<d1{Eki_j>O*
> z1MVff9)~T}f8L=fTshUG(2t*Sxf*YdGP0!GF~)I@IhN*feAYL{_l_Yn(G0Qlsgbi`
> zPs}T2WlYzpIlyZ?q~i&_ae>Jzz1w`Hf$xOm*?K8;-
> |6*qH5f>GH{YEF1q_LCn@^dn
> zCb?yH?>C)R;8*#5;%7BP-P(%ccd;>k9YTBA|GYcAS!x-
> dC95w6(9>L&c1R|7{<1X8
> z1`q9hw&1$7(iV5)eI5^bJs$L8n`&31osx7OBTo!F^1r`Z)DbS#n(sciv!EkBrSFI`
> zyUm;fgE)DN)E$$e>mv0`Rvkfyl3kZ6y^hmC#RFkycM(WbGa{JO*qQX!F$U*p8
> TwRp
> zYo9Lu5J<=~=S2HuAtaU>BpPHG^?b>c%hlj61tIO3TZi@@46kL1GyK@Ue9Zvya
> 4#+A
> z@bYZG7d9?IhDitfKu7mZos#VG@Hr)f&puFA3urLVTsn20d;50;p8$=0N)I1pb~
> pXI
> zhmWE0&DN8)uqPj;5B28bK^KO-
> 2bk5H1t(pY?$Rl+xG;ggcPigS#R0GERZAK2wg1a{
> z>gPst_VRh<_5COJzBF(~e`eR2vC)Z%hW?vpW*&S07L-
> !u^PV_QBJ=K8ZrC{LU_M~F
> z%lb%}W6Yq=SDLuw+}vF>XqjsoD_g<!IdV$h`L=|ZzrX?D;Z$!x*Dcp9P{N}8!2ny
> 3
> z3d*O!Ru0VYm_eWO-VZIS0a<WzQ731RaOPvS>7>rXsmIQ?I+f^{MU7*t&d}-
> (^=q!Y
> z8F>dR0krUN*=6xXO_i%S9(oui>$_73gw>CHZ^<5}W08Ds@F@G|@V@aSY+c
> Qq$+mlF
> z*uVx{4s^UGy8UOIun8`y8U7;Op?CF7hteFBX+6M-!w#{8SYtbeObo<H`vG-
> 35D{b=
> z2k@c~>Nd}l)4kXR>6VSA?uk<D$t?-qb8p3--
> QRFN2=l(+$;B1;OsU%PSmrT*mwA6t
> z(fvYk-@GZiu3#e-JPbYz{`R}!WyAeTb6dGP<Hy$FZ3<7gZ|$-#TT~I3{QDF3X_-j-
> zR-ab;s!$Fa*5b!s#1`km;11;fy-
> DXu=}pY0XokUDZ7_fpo{k9QJwYSp`$kONk2MDg
> zs-
> jk6C2UtoX`?EacZ{2Gwg52;`wxCxI|V<EcAhZU*#WbLimR}MxMdL#`2BtZ2te03
> zfD6s;W)$<(Y$7EaiqQC?+|BU9q$fa=sk`D3a{g)X3+?Y&w1#eZCp9NrJJnd}{s4Yy
> z?wr)(I~giWVBDS1A#YC1JrQaODv1DjB}x1)PL5@^z%s2+cYTx`2;rz2-ei`$Dhezf
> zRX?6O-
> (v@XxKQx<J!THQ;QLmZH_v^`H|@h80xIb^*H&BjdC?f5=9t!7=nC9<COoin
> zn5}9qk>mV~KZ(R;AoTMZ-
> $)S8hSZLM*Q+?~`QpA9*z~H@v!gf)Q@=P_rKYi2R*91l
> z(%R2>Z<sRPGPKMaQshl8Lrx)X{;N&)uP*Gjy0wctpj{`N!q~Xo!0_SZoq8#CpY!
> W}
> zxPXx6eD_Cm6%nW4Qzo}CEiAKp(*u4&^iK@`4Sa%_ITX(F8|LNLrzBVSI{qfC<G
> kWJ
> zka3^y?kcRqr}T9wvwQkqqdMfR5>uc>NQ1zG5O-&rIaHJQ45Wa|guoIv-
> ~@xaE1O|H
> zEA1H4LEwVliLVI{6`d3^uZY_&?NItM23w!3%|`rIP?ok@tp5tf75<@2sThSra`=X
> <
> zolh&jJe?@VX@Dh4TT>9sO9pYG8G6NY7cS@p)}!XDt!;e>hci8E;$e;G6G}4SHh(
> h&
> z_V7z#GjCQ^%U}^ycX}xpqfa|La;U-
> TYv=sLQQDeeSyt<{32i;p#}I+Vgm{qAE7KYi
> zqAQmV`R3==C+{LzvR5rGZL4<w)3(cz^*^48d}|MWBbv3BPg{DR&X(^X4N+JP{
> ;-6K
> z6k`}ke{@Dzrz3p>f`uTYK2<L5g)LB@p{dj-oZs2TSKZ-x|7kku8=?(-f@r_xpLDA#
> z3dz7y>WHCQT>%BR^g9wLLEX}qI7~0UxC?ZmDkwKFA(wegM{uIzTV;4|>K=Ik
> #j1I3
> z%62>S)^<SP9%ekGJ~AQIOiZq5VSWuY^P|IFK1)_vnz2vO#uDvRxA9PQ*{uq<
> 8!b4K
> zQvE+PRmxLiOIH82h?Sf8oCUzba_kG%dJNr3BTzRi^z}RtV~s1rJtz8GHm_s8arF
> Za
> zmy@m@<)_ZmKlD4zIGz9U)tZa^v!p9^cl#<-r|p1TCaklDI-
> h_Jx`&|>vP2%DsqTJ0
> zyuk_cu@og?_W^>F^i~!-
> dS7scgn@PDd`L#qb?NLN!HU+iDB9brQOJH`t_lj#yQONP
> z5IK(_et<9?Pg5y+SG?^{XCZvUkcl8g=@~_lt)K79gJSjW<0513T|qWIqbRcV^1VF
> B
> zrgtC53NQam>8(4J4J&@`8K8REo+^Oq^;FtSR&VL76529CnGf==!+A=lcV8w&5c
> dGz
> z3xoRfZe?s0Fk3PPv_vK=s9=Jr&J(DP5~w~AsP+@6rV^-
> HWvuA~RUQ+9gYkCYq6gxi
> zNDgTU$eR&oM?r4<CH%e6ZF#U4HM5{=i?J;-
> 3;OE6c(b6aZ9(R`t@<_$!7PY_BkMFJ
> z<b19GRVP^wZ&jr&?vr+;h$(UNcGX^&JYg;;1$WZGY`0S2pXtpuY0}+?=t}Al{g!n
> c
> zj{$q)KW!mF`EktG!kF@o8K&Se`DfE8W{yAIQlPGn^m+G8S&!XO*5d+6re9lF4
> Vd9D
> zme(dX>!sA4^lxf<v~?TO)-CnV;bIV_Ox`5Qpv>-
> Dwr#FKqJ9fNV%Z&9eS%9^mf%>{
> zhZOEvldA5gA-HgT6Hi%(LlP*aY8-
> zR#+Mma(2izar%oZ(l>xVSN=OV*li&~GbxJOq
> zVJ@&|wVZsLV7dF5ufz1+9UMsK>JYe(N?OCL#`{`T>L6DHv0{3eV_S8^P>n+jgT
> =d}
> z&KnFsUrbI^j^)73_seo%xQl}N8d1a3m7>DozTnQnv)5x**dSG!IE`w;n8Iq_)``Yz
> zNi25DYqe2p9lYgu$7P5zyYbB5p<L9E6QhO<e_ajHIy%i>C0LJi-q4!3_#R_&xkKtb
> zQkQJ9W{pXXfJUO4Ft(6^o+RO_9<uS-
> elL0YDwI=TbNvJ_s!(7%$Aa6+v&d~DMs%CP
> z6K<E!`hUoKANV?pD*yjBNg=dpZ;CBcC=h7*+X991zx+u<gDo_g#0IONpjHS4r
> P>>)
> z+Csz4mE7K5DcY=cm(?P;-
> |FJZ?jjUzFvV^Y_@M@<8nvz|TlKlzxMZbnLyhG3{+xN9
> z=RP-
> 0!QK77e!uVQ_iJBy?mY9%oS8Xu=FFKhXU>?T3XX*hmzbY)WtZ@`pI=JaKU%sh
> z>`!+cLeKq&p=V9k+5ttRog&)sj@oav&RxPhXI=6R6W43>x|3B*?j(f*Qv4uNh)-
> l9
> z+xY#PsU)=d(VimOlq`L-
> ^NHYZFU8xmUrCAcCutcIzkj{j<oB=kfV|#g1LBlm&7Lr3
> z4l?D~%y|c+aVHoyLAjX*=O>R1%sq0+i#fv{ZB8BmKz1f|ldD!D$Tf}LJMUD@q;
> aVC
> ze#oYzf$DRg`x?E^SS{gNY;k>d6iHSjyW+`yPU9ioR22HmiTZ({dJT{>i-t`zq}8|-
> zE|4Fpo?hz1p&|CExsO!kBP8KZ>JzR$3}5Ywd2d*qbmCU)`#^3g^BTGhql`qv?0L
> mC
> zLlNb#L8PE{L!>Zx{2`L(A}-8Z7TfG!=KTjeCp`6e9erU<#(9xj$IUmfx+KqPhw_dK
> z2JkOUWY7TqNAjoV<|levLqH6ooD3zboA#pm0k_CQ=NE(69D?{n0ODgI2<S_i
> $=udI
> zW7+&2LJ{J+8?|Ya|M+5EVZ{|R6t{m6^3ARSUU>v~{$s_hJk@Vy$QS<fbthvDd
> M~2E
> zGro{N&+s-
> SY|o4U89xdWKWd4!#LrzvuZ_h@Y(Z`OMD|{XjL)|@e{KVGd`_G{9D5mF
> z7-~aK?GQ`@qU%4Ro-
> w*+VE1c*W5nOj`2w9U!$0b1;@a<EKwQjL7l<|^%vX*r4&mf4
> zJsKctEBy%}%qw2~j+yCi!%V9z(_!%xXdwc8#eT?CS)@OE3;l@3O|Xo=3<Ukms
> f&CB
> zd8?W9QeA7|qx;0v55a}!lK%kS9IoZh00mI;S+3{h1#!C9Pw#ifR?`XI*DZJkL9u58
> zJNATP?eR{dShomq^NX*{IMMe9vf`@dMNB0~5<i4=3z9^{bqdbLoSNduhs8b
> ZUJxCN
> zcJSCA8V&N+0OV)J0;#?HC1L?S)VrRR8x}0Ye4XGhYu;r`P0Cpr06MP-
> kkmG3d+Og%
> zzu;0f&mo^>_I~_TYYk=fgDGe-ZLHq}wA>GgG9vevS#pK%s>3q>5nk}&p-
> O3PN6>kM
> zdB?bmY;a^WQ#3KMHnKy!CpT{uB4f=@lOU-
> 0YE#XJ;@OZYz7J_LsCXf<tGhsW?+EIi
> zKV6g2G+`Y-
> Vmzsne>uw}?{7mez9u;A59ZgqbiRA!?y>7@`XzS7w;7h3WkVIzx5xNp
> zSYHr5*SjDrh{lD9n;#Oc1;YF2R}9x~GwW_tIgTJATXUiJnV(0>y0N${a5LBI`C0@w
> zVPaR79N2gVY@y(LoM(wgzplZQ@epNrfj-
> Cbe_z>TJ@v;(Z5)3sZuw==+JuRl_p9Xs
> z;oTOkjroH&RpD4I|IbKSA2D7YmSrvf(Zi9JhlyQT*783;6v49d2d|co@(15s4Sg1P
> ziS&Yx$SqOw3O$`&-X-
> C1$V@YrMbnlUg>6L~)W7cWOO)0^HxgnK#Zg^EnNh%R#luQ{
> zd)L&`@dgad_#_LM>kEuwR^dd8U5@hEi;zd`k}M!<8)FDZ4caF%A4e}A(uDy%
> OU7aA
> zNV(-qW5=s;cH*{Cr*-
> V7yzBva=7MsZH_1LGjvZO;(5YHqjyYJPQmhaEa+9Gd5#bnY
> zNE5SbB&4!ku_G5x*A3t;=eC#1-~b4A*$tICJ7`-}Y}1vcx#bd1KGFoH>vrl+dJgrD
> z&%K`+k@!-XpVIIl85zEygo}n*_FyDNvUqAbkTSI|>=-JOk-P0(UUe57eef!prd+r!
> zSx`2=raYe7MGRY;RjWSmUDxcvmtQ^blD0|ecF$bey3mEv3N`I6Z5mu(Q#J>s-
> |o`7
> z!S)5{?-
> YkaWXVUz6hkPVsrfoRC4URkV=`A|Un9UbwaSv#hws0<T@gq`qd=9<tS?hB
> z4b%lsS9IqP)@-
> OhMHteMDpDHCx}BwUFE~{0I9L{1{Tg0+3@>PC`$1lvkXPr;M)Rkg
> zvVB2nnHE{<UYB}jDH_V!odDkPhRkZ5!DIwpQ}6tyo_L#-rds3xtiEi112~ta31C&L
> zZtzL1_hs)uFZNiVbLPVJ3tcF!Q0?y0+TQhx%GTvDp#j&u?XuiaWc-
> ;$W%$+(klyPs
> z8%28We*x*eg?{Y~`jsNAUqSjPP*J2~3IuZZ2S}HVk=X}1r0-92y)24gtjk!c^v=h?
> zx=o7KjBKy_vSrVs_y^hM@~=#`L>5jrXr)0oEnvFt)xzZpL+jU;&0ho>y9|vzRjb}-
> zsOeF4jWT=IH<Yb=)=_CsdxL0ms!y9eFTcu|oaiVs8Yg<6SVZsnkG?(FchZgmmIX
> Pa
> z#^MhKeoTs|MLVVF_DXG-
> ryH;Y=(BMz(|O$d_Ti>4o|4LnYYD_g<85}u#iX0zjXU<n
> zGt(4XdM!L`xLIlga|6eI6AO5GfOD<1)GxpKu+mPfFV9R;KzO#?xQOGfE8umvw
> VQoA
> zs13iYUv#y|FG$$F=xUcc(@+V@uNHQLh_d7>Z(0!=fL28E)8!-
> a)Pukaywmw`D*WmN
> zSt}!3P7=B^lZ^L2H?`DQzAGMvj`r6|NOn!FcX=DUY_sXoGUf+QL)!v$$NceX=3S
> UL
> zz(}WRYb!D<@%<5fX1JxT@dXa<^Y2TpA3Xud_Aa^OSlcIqf_nnyAZx&?wX$vI+
> {nuq
> zzIg0YBOc>=Gw`~t^CVTt=SN<CHQm(vu%<;8BP^Zg*X>`01Fd~f_DtKoY3iNXP
> &V;d
> zEIZJ{?xUTg%m37+jHiBSU1PJL^6Z;GUZ8*=_V3NKy_LG&nTyIMzGx5_e3}LK<z
> EgH
> z$5VeLAg*ZcIbolMo#mq9UU6SruJsWXEeehLKDyQA2*Lk41m7~v+k-
> S2EVU$*Kg&D0
> z8oZawOx{&<udQU~ir<>b<Rv3!1on_im7b&)xld?WbS8vZZU76`5jo{!D4{^}!p
> W&G
> z)6zTh37bqN{<LLY;OAeLQIgl2xn$!)CR)8H-A0l3#2?9dzkdyOp2<0!hx@{Lcu#PT
> zR}>IKtmQa9R0)6nhu)bR45&HB8IG+%&ounvD`wI2f|+5wkpCS-
> Ar`mr`LbZzo{jCR
> zX>^Jv>3a&3^x*uu7vPnW4w%E3%zUorCTxf;n6O_6=hVIePTYjuSK9P~&)EBz{
> fx0I
> zZq$VBL)fPYd!L)IMXSXVcHhhh`|3*v6ZYE_!Q3$l)IOWA_r2|eEfeNot{4P)Hdpk
> U
> z@PZ}2n=24x`faXIyv-
> HN_RIl<nJc1L>!QOX=B#C|pvoq)Ku1V1!Cawm@mzr<1WjwM
> z04e@lVR53saIWYRsx?=<9a!dyi0mTBnkx(u#UBj(7|1rG?y1(U-
> I_6mN+nnBwi#on
> zRD0-1ggs_#JEV!D$F^rl)stR;RT&3xP$xRWUet<H;M-
> LUviZi3Tc$Cv=8xADpo<a2
> z7WL1D+JJ7>z@n(EaH+cS#|C4L^T$h$hfz$@Z*oWF?ayIxXlypZ(Va@mtq#Qy
> M8$~M
> zX`i=S)@Liz(-
> auZbBCLEE@0uooTU{IM)g{GXv>O83xkH$m2T;A*NU>{Se51()&TNZ
> z8RJSjm7)9UxvdqI8^#cvS*VPvJT=vz@4A#PZUc}U-
> 3#DS8h69pH8@OWKUGr^*nC94
> zBw*(2F3|_U3-
> @c219O;CfN!RB<&ryVce5!VSn4}CL*4Ed_u6Wp&uo<X;0(2Ww{_VX
> zpsqi=X`HPA*c7iFP%arM4j2y+_q%Fsl}U#CY$%xYkDF(SN(w{%`4^$W9k0ZxM
> QJ?>
> z<Nd-2D=a4vm=izYgpRjELgz{j!x-
> (^*h;vy8Jn|K&|L$Atvi%2UB|#1WSMpM2QzFX
> zR~s()+TA+LBFNgWtBNT}L#;bDNGvsRnW0m&G9NNaIaN?*0^C_TKq@<<v&Z
> GgKfowx
> z-7!RMOjzW)B1A<`5(L5^vb-
> C}5(WXlwI%K=LMLC*r`s_1Ma4dy{8_khp^#^^+uz-`
> zUK}6b2;uz*&3F{=Ute=|8FNp6JJQQ@+~1{MD@#5{R5^9_h4MZplxqd3c%)p
> W5Z^G%
> zmk-
> !(;fkGOO_$D8j{Y8_eU$gq%`Gam#Ir@^epUcMKko_qxt}$mT@pD6RvDSPPq`
> OV
> zBi=j1YfXH#Y2SS0{m<(NF^x*@9VeINy`@|w*|hH-
> ji&Q#RoE9yB~lvMI%LSL_Za-c
> z#p}JH!g_DWO&<t0d))M)kefdClr|0d)5o6Dx*?lB6gO)6@F7H(9z(^`hXD^bn!yjI
> zkGCm;>0=bA=+c9$%fPfwFWGue$C1=hf4$dRTGuxl{tCuW{l`ClrIGt!Db5>3>xa
> db
> zCKVfDo?zSR!xknA+h|j~O*Rw-
> jS?1JiWL+sOu#XdO@J?u3JQbC#?V=`Fae3sP4U9S
> z;)E_Y*#sS<$>#0AGTB5BC&-
> 0`Nzn%bKW5hmN1A4a!K0QUT9_b>vaA|3!3_>(q`EI%
> zKb-rf(I&ENZ#?@IlUd~VmG8P1XrIkVhWTp&0(rA=hU9y#d$f%dh|#;@lSa9_-
> 5R^k
> zR^;cY=j!@`W%elYE<(MNj{g5b-
> fj=>aLC(@qA5FdhiQ_)w((M^K$v&Dl%?ljS|mKk
> z5VA1CNi08L7F}>ndPIaQ^4%SOM(Oq-
> Ye*%*sU8crqlkDZTw(7XgODxmu!Ia)RYC<s
> z#>Z|aj6uk|3(TaLkc&PXo{$GoJcy77OY1~y5VEQ2175B@8Yj<$>uWiheb|=Q{q
> c+~
> zV@nsHxr;8Z?Pe7%uib3nme-
> z3Jdqj0q$(y2TdN`yWTv_0^@Ey?^e_0ZzTxV1uZ|1e
> z+8eG87uuSvn4YEu5oO8#H(deZM^*p}w~>~QB(IQMGVY%D2T(=}IK>i`gOS`Z
> b@q;W
> zAI!5;8!d0WSMz?il(yBkv|1L3NQ5>68opWw?f_4L_SZy;=MbEHSM@#JDNIyG)
> Kq-1
> zWEGa<WD8_E^y=K!$FpA`6Vj>)PTP`ex5-
> 3JdtbTF>O)gcMp{#dc3bNXry|{Mk>%+W
> z+cfNZy`VC>Yae$%`}Bk0WLyWGC_AH7@oX8O*kEx<%(~bYvGCjo5X%$KbSN
> yz%mq62
> zTD|ricyCleZ7H^jT+*K;J5_cpzF`?_Ry!IpVVid0a^1Fu9c0$=*Znd8^-S9Hl54&4
> zc=j}LGaU=3Rp_|(wC<4HWJ7sR@-
> xFDI<eQwk~lG8n{ErqwHQPM_jJ=v>55WYC^?hW
> z6Hy?+KF&@P9Co&HZjxr+GhrJ(mGQx;e1Z6wzp9|8%vvk0aaY}g-IiXB-
> CC<NZ5?W+
> z7`-J-
> w`J{p?as<IQ%nyXZ#jyhRB4LBi}OhCC2@T5f}QB0=UdgN{g6IAWs?EZ)lMh#
> zNs_tmY`)NPW{V)%MoZR*EGoIPsV~>9M%HfEm7xP9!l-
> d1ce^Fpo^I;G(G1`HUbC>I
> zWEbevr|Nk28Sva)`<N2harQl00<my3X?cEKSG?^ted<v1OzmUyUAyCL+8Sc^o
> L@Ki
> zsmbs{s<bW^yR>QOQxmrRr)u#V>%Sp86OyidB2)K-d7RKvto2#zN*&(bJ-
> @a;ffr}4
> z<{rY*x00{iu-
> N~mt<!er|JA<qL+O7M%m)P%Nw&ln;jB;ac0<*QyU4m^epYn`E10;9
> z<eL1vHQeI7he*7tjpVddBbi$VDIPQGdn`9hrsUekVu=sp35Rgi+A|#UGH@?@
> 6Xjrd
> zzgy_Ks8=U)rnl*Z{G5!v!-p+{k`7Bi4Pt#w!NjJ=(@l>{bE|XV@`FAKxzz3ts@>OI
> zpCG=^Z&H;p<rv9j6<OP5J_@>Wr%^%1aHeS+lJk62;qt2PUWey9nLcskHf$M2
> @=Q)z
> zu+U4kVA<aKtkzTMrtKMH5HI#SMv==goJ{Zh!u%;n&~Ti($LB990}KXvBkH0aQ
> <e4P
> z>PT6%XJq^idxxq+_U{j8@8CVX*?cm{Jb2N{nUfwH#7>Gmss7|=?m(R@*9+V
> aQ}!rb
> zQZO1<+Gg9wVOjq8YvfpLh8^s3?L%F<ndyeb8&}2bYsWA)VOPbVRJ#&hpo5)
> w>Q|<8
> zO><_F1%xo&!?cNvqwE7Fc|DI<*+0-
> C(=XSIN+ztR@&@j)Zxjn|m!~ID+t~YW`p^x*
> zoEhMw`Vf2^&fd^Bj`P0uC81@Hhus>Z4oacD{j9GVy+w4I8GFG0`dLiTHBSH4tV
> =qY
> z=V)KGq`8W)_qPwI!5Dw{%g`g<)^9^#Pv%q2Pq$Ok%-
> a6fzYdUKLEn$X6a^fx0$7y0
> z1wraQ<+3WEQ}A(n0!*UyGj`vU-
> RR>!dwXmf8Vv6NtnkaYYH0Q`YcN(O_u{SjY=Pv8
> zM)ScNPo2msy?o-
> =4(a8x^rY=lJ<F>^`6FGXh2{`bMS9v!!oIPPdPWkr)1;1HJKaXW
> zKB{m_W@&xpE$OLskCQt8^Fz}^BC=pwI~5tQ)W~4{f*I}iZT&sTe^E#tOp+wm
> 5_v6t
> z|NB`WQSAElClJxz{`kL><7XM8M%wG6X-
> 4Z6A~2)EO70ZaOTG7`ZCN8j_NR^h0CqUy
> zyY6A1_^^fQ8)-Qudizmrf4z6R1LeIV8Ejq4BBf7ssAc$=L@7be|L5p)q<Qt;g|X!i
> zD_4DTV3uzd&!Lq4%O6oBJEHnQ^sUd<^?SQ?(!swWV*F!ZR{t<|c(diqZhHqK=
> #|RR
> zp+Lf<gl&u{<Hw)C7`Jv$er^7vB>!`9@-j<~I1nbk(vtV(-<`jJ<ijoJ6rc;*d-NGy
> z0-6uhM`5mV%e6Z{9U&MayvUb-
> r{2g6?7{^@H5jKw_&`4u9t;?`9w_zRZbqRSb5tZI
> zM=2PbeHFohNc0MSV#E~g%CK{n=v&Y(jE^T}v5(g0_O7{^_HA@ORyOg}Y$AQ
> 6O71~9
> zghpeqb?u;taTSW23hvI{RXrn?e}(!By(9~6)WANpY}IF(25)}}#maDY!?QiWWfNA
> Q
> z&<d5H(PA=)KdGyu-
> %V8f$(nH(#d2F5LByk?>)aLBFz(W(!MoWr;0D|FCjf>8oRq&$
> z)|@bL2W_=Y>=W|O=f9f6Bf$t?g<CB~D*W>ximEBA_a++e&<E6sg{nuc(>P)k
> m!KLt
> zq&29>v<%;pX<NCSLT^bgytb0<7vXkhh}*A%k(`sP*h)DWvmo!!SQbntkW(NY
> e+s5G
> zGOaSAvC}E}EXI{^M_5*ceTlbS`j;b}I!KqLRa^y*CDZ|ozj5);JwYg2_pb#{I3Qd0
> zrViP)NH0FJFGFw{1KGqmWJ8_m<M@+{PDnn7I!5?zzxIUu%lWMk1~oOMrhh
> Xmgdrhr
> z6^u=N0gMxp&%^!&p}qbDZF*HO4jR1;swkJ08u|f>Ue-
> XN<)$6we1+`Bpr<2N#dSD*
> zn2fiimoBKxze46l?{CR$6rP`vyut=LwuQ3EebkkMLRb#CK7_gzQ~NtV7B#iEA!Yo
> f
> z!3H9*hg)-
> x(ywj<=;*u8MjM1vsOD~S3bmA<ZBvlT^T%#0qo(=FZAa_vsBK!41P)E`
> z*L5xlFXHbC{uc6g9e+i>z2w@fq%=}~p~*U|&onXIx^~#uK04g;(z@YY3pCQ`@
> $MSR
> z(s(WRvBmf91=jxsAW>po8%O>TA#<8s)EgPDqswB7QCT#4{e6!jmb5RJp($o`Z
> &0;h
> ziYYHOoz438uMd#iCK{#~U$t6jU+cgb=ru!@HJnZLv9J;GizW*6FR!NEsR6#JjdJ*
> @
> zuq_A_XzjF5bor`jnXJO=JM?VdG-
> ;5ZeDAK5eyg&nf8{5g+K=$36{~)eJ4(_P$aLs6
> z{v=nACl<PI8U+UEkP?IMj0j6`ccrV+uD0=3QvS#JE!d^19cJW=xZIHK7{XMzu~|6
> E
> zT7_`Yvx57%mT5g+<tHx-
> 5)3gd;7L}Avx14kV8V14i)DFOxeovD$(^$f$wnhaWdnJI
> zY*SsfB5WGUZ0TN%&3N+LA}MQO{HeAk)gN_T0uE7LYMI=4W@MF@T9+`S!
> *4F%`nG9m
> zNqeh=jr<2)_r#ytRA<0mDFIlJ*>RLA>RRf$?^<23;sE>Ix@po7?Q7p?zzW6gTBn
> Fu
> z?tEB$u9whX*u1ZkG-
> <@M;8Rz*zz6QWD6D{Hkz`M0*rN6YC%8s&u~k?zzcR~Q_74Ye
> zJ_DR$EJd<_C5Q7|q_u989NMVMHE-
> 1o!=`#}F0d)%PsxE9{xF0CBH#>ozd`EO@9#M)
> zq8$%y;#VnRk0Q_wYI*D_;%^jD>*Y_(bFy+Dh+uXY@KP4LFJG>g)p{w~54oZZ
> HB^i{
> zVE*j=l2s@iwtKvyg#CG4Q42q--
> ^0~>i`WluTUh)q{+isjU4_Tn%u!2SdF#`9KVyF_
> zQMy`$-bjAeG(Yh+twPC?Y1cakV%;s~mO{%`j;YvJh56cYnvTSlXYSK`y?4+~DI&X;
> zXC71$tVft_HRq@jnjV#3UlmSX=JKmFz2o1?&o79|&-
> spzS$;}UF4d{g+vHLar<_XH
> z;H?XDCcoQ7Oe}GyeN|ZX{IFlooxGp@CJ*jE4Z#TX3&gd)x{ha~H!u960z~YsIels
> H
> z-
> Wh&T6}yP5_s0803$MG0X?~qm<t2s{z54BLIn7$2m`1PhLqV%lfZ`gwXY6pLtnqo
> (
> z{2rM}#>XE(nxS8Ycl0xVm$$ANx9D-
> Lg)bx3j#mu5YbxtwiL;>M9ea@&$}<Zm)az=}
> z=|Wv3uHI{M1%<K6H4~QTSU><gxn|tbSj&Pa<R!5dhNusP^h=SontQJ|8(k4lb
> F;!F
> z-
> dUe96IgfjIhuh2U_yTFtpKVTR6Vn#a;f@ARgK0qc;DP;Yx3M661H_<qxU5jr7;uA
> z53K67I0rGwr;UttiktpXIQq>Iu={2N8_D+sX@v#lQ#hKhEAmZY|68G}BEt9hdp{
> mF
> zqIFHB>!w*zT+mHZLtJE*j;r^VcVQg(0bjF1Fv&HQARGyy(2Yy|D&*Tjs%m{!)ec
> ~Z
> zr8xX(O%iXLriqQkid%dh4pUl~+P5(<6@D87Q{gvZC%~e@etG{JF=a(XDCsZ3l=6
> &)
> zDF@4ZbxB|{e4(FeKSUpMSpC#HKX<5pijiyjsg{K+D!k?g9Se7(+AhdO_QJjH9Sz
> =%
> zAP9{UiV5%og@@<6D!fm+Y(L;c)srdarusWDJ_{8~U%bPBqF{K-
> HGI(j6*2Se=?pw>
> z6k9Au%7(l+jh0xfcUA<bWsvE=fgAz5b_bIoNbV1kK;p;fj!g~JX^5eA|FLXB;K!)1
> zjmMAjXlCVepPl!5o3Jz_6N^Ps@yG?YghCUIS#hE|Fv(l)p-
> S&&B|11VE8F)nuA$N9
> z)~rnSz{0S6Seg54Fy_bg|JjfG9C5i;9<2XiiJ);L-{L$h4QS4k%42|E$bTSkrFC-i
> zmSx7gdPos4uaCDxn3vsfcaHb-PX?M3j#h+;n-k<V5MKGmT_$-O247-
> J8{b3CujTI)
> z{x0Irgz*S{Z5>Tt1LcP~kJ);K?wdALFMybif4~s!kEUkDH!Fd6v}qv9AJNMpv~;S=
> z^@F#hl_>r9{KfTiyyf>G7X{tg&qr$qS;;eE;v6w3TWM&tp?H<R*}A&Sv|hR;+<o
> @G
> zzus8=sM=5RZgo)c5K+!_miQ=Wm>L$O{uO{Jjb2;}4JT-
> j4F62TO2Bxhio3*6IN49S
> zj~xh-jw-6c8_rt1it3I{8vNFGNskqiLjL4)oU7zvFlqEo=6dg+oJJ@rtOfla@t+f0
> zQvm|U-
> z%5x&Vk?KBF8&eOf<*duL+gKOSv~~osk#|Qw>Y5=v;WGh*IlLv`cH1<&)7Y
> zb_B@#^}Uvh5i2``VWFamR%l2sO&hAc;ZH>1Tqrnq7r`+t@s|p4bW#Bmurkg8
> 86-KY
> zE_bkmA2`9mb_e-
> uQOL5jHCom9Aj?m9hwX{q2wBun{dW_qR6Bj%q6<}(?h2o+u*}7W
> z+PQ4;&}kIJ32E;^SCBsv@~bIb8YY8fs;2q@CFdU5#6rtr3XmIIE+77{*jf|CIQTzy
> zC!Kxx=M}@B?%;Qu5UxTR%DPL8_}q|pBi#D``uC|f6LU2*ka4h{uC2g<YfHt`7l~
> Nc
> zmZMaMtdv=DccXU^yK+?HrVovx7JojHMuiN>hsKD@BdM%B=BvTc<8|lZ<|}
> ^{;(g>^
> zo3@(27wvCI?VD?TQgd_7(caJRh>*w^sj~Mou;!irTkShA`=D*V1LG7w*o*}c<1
> ?||
> zTI6?*K2rVn9A?nn?-Kt226B0r&rmC?=CXpQ6`dd_dG&raD|)QWm0-
> MiKP96>T7a+V
> zKZ0)-ogY1%za<>msGoeasY~r%*75gpZqJ-
> 9X>!@EBxw2kEfLP`Ez;oSaz)fx!Q@iO
> zm@ORM)G6w@-
> kRGZlS`Pm`2unq2=DK2u}qBeN5P2q*jn}49&afWW81LIjFoJnFf;nN
> zZq_;dkasvn@YBym`!wEm383htAGZgc<dDs-
> ?i~;s8(|kZLi0feXU;3UU%4C{3*Lu7
> zX&b!Z5GLDKfWrU|x0577+E6&DSxXfYFTT4-
> b<wEAJhq3u0hLW<YQoAukl=D3HQ8e_
> z(j_)JU=|$KpW|3SxKq?}MYv1Ua=yjh(ctF85|?Ym^vpC(iOFZV9`OZ=^Uge1twz
> 40
> zm_r&ke7~XO2ihFKXI`h{2!@k?bmzUvQXoUt3LtG|vi~*L2h1D&hnX27{J}&()CT
> EE
> z`>2qspLVZ2y-iYWGY@X1cIj!G2)op_LQGGpV!`fbu+{M+%M{_~>9IUFv-
> b4!Jf?_A
> zH<Bb^8AkuD1CrlEeIWY~aI34$U(O8Ob&4$LHu|11B|BG?EtN#Ysl5uf_GHDfD
> BYpR
> zjD2EW%B>-7cWOCt>d@{~Ga&->Ki);#-
> osb?ZsM>fd2mTQbvk`aNf_pgOTKY+Jf-We
> zaMy|bQb}^?rg-W|z1LNyvo`~!dC>=GV~2u`-o(#o*^J4`jl3p1^^Cz=?R9oaY0{}>
> zJQI^MS$(t;=i8}>Ujei`h1_g4l(JD_Q*T<JQ_u1DzB`i@09@o)i7wUcT@{)3E$p1)
> z52H;rz(-2UDVYvsx&5Vz%zgTX{}dzcvP-QB=9lcRT{TSYr}{K6w8kjN{p?A<F)A?G
> zsV9=PYfSu^^5h%y6S7L3Ma7eT?bg6l{!SxY%kAbWfHiM{S!6nt87DsiT;H4o@!9
> N3
> z!VTVH$ilok&Am}0Z@Npmt8JP-
> $FeE?;1)<NalI}X*BXeAHS0!0k^0lMrPT1_`o<y2
> zIdekQD~wrF6^ML`r!JN_)M-SaWh}G7gGZ>CvUIARv~qi-
> Ur|h^Lm_NSb21;(<foJO
> z(Kg9PwYR_=bI9SRWTJSRoPE3Q6_CSr?;3~6SmG0|&7rDfQGI~1V;2T2YJRpu=
> mD=n
> z4+DdGe*@?aJyS9rYLMAEDWFDZ00iaRN14+okQ0Ptr+w#Q8$o)&<Q+7H!}+-
> d+(;m3
> z@xP>&_+a%buo;U{4*cH%Vo3-
> >5>4F@>dT{+6x4}sJ=;1UKeOR@AMQ5t6u531z6yDb
> zcWdY@q@0XB$M=#aZSC$(Eh3td7?Tw!*sFPK%vw!~NX@$Cn@0*g(-|Hj-
> A!zl6tNBR
> z38TozH9nGMk5W<Sh1`e95+pjIR*A}zUE>`OYL;D=Ke=VHVn7Yv&k;0b!(fdH29
> e61
> zuCkjdoNf#S)1q|t5^@lQNS0Z$k?Wc-=Y55o!rcDS5kzK}RL-J(bD`BnZ`_&mm-
> &Se
> zt2Sl=6;4zIZ0vPu?A7xKX+-tG3Z21Z<9SC}gSXuV9~)x-yiB$92Ve48?Hf8?nueFg
> zpXyKt6Gx|FGG4Lbh^)mR9ar4mC0|VVq@C61ef$io6AT+0i3wtov?QzkkR5f0y
> 2+7h
> zW=Zc*W@+zmI(r6<Nq5ZQ*=_7movp!PLsi6SL)Av^{Hy@Pvr?x@3Fdzi;bt1k=
> 1<+x
> za&59x$zzEtiat)=ky*H-%#Ek?6d6?-@ARwUs!-
> 9J$*LCVCB0?&59Y5gO2Wsby&zem
> zBW;7K2!4k(f>Nv<>7|rq11+7>hfKCv*$jGarYdWt&o^|$Q!mmQE@=Q!i{!zZjU
> DcD
> z&0a#r1{^kevWC(A&_7)%UR=e!;B9T>=uXWd1py(eLtz`{7U<OT-
> c_?QmL~rF4Yh*S
> zx>xgxOM6RtLzCk2JDa6wet0X=Pf)1Wes3^=09nZGt|=pDjFa|mxK%@A_G(Ny
> I7DMf
> ztr=w;N>cY&$3UCwB`iP_IvT8aqX${^%fk_*&GfXDX6ia%j_@YlRTyt64T$u@35!
> _s
> zxLMD;%w$C^&5X7*Leh*C1FXq~U46!uNTjt>xlITC*#by(&c4PE7Vyz|&$XOr+
> <SR2
> zZcq^)xm;txcdbCl!B8+osQ0ufkjsnXmo|D2yZA75_d-;pYPg#>6BTY^3l?R8sA3Z%
> zgRDNxm{~Y(5eqn2<-
> cANVU;GJnS7KSn2yb<y2Q8H@GUVyyI0dCp;BtnM7&llb8B_f
> zOZDF36^<WqEd-wKj0>(eaRwLCW#%4Xz}ym`@*2X*9-
> E79Z8b|4H7Y1*{bA_^d8@Ix
> z`Ud9t+TnsIf@8;~L0AO7A@@@W*b6h^__epgrq&1OZk|rAW>37zB#*j5Xab*
> )ukTX^
> z7}Ie}9b>ZH=tyzJg?pt}D4E1|mOGyCp8Gb{#S)k8p&#-JwIo-
> g*Io$OWg4W=_LV*J
> z<RR5);EO?}pn=kl6w`plWqrN3eYF(>jO3?LcrUc^Dou9?EFh@O5nxY#xEPqm`q
> BpP
> zP9K=I?U$;`)UmtTh(?v<CXEKDf^ou`uSK9S_lla;#{=SP;s%g&d;o9Xv_~SfIb&39
> z{HE=_`!8+U)(Eg)vKd)4R$S9I`M}0*TK9r_Yp%X7vJkDTZpIna78Z8FUZV)!Uk`MV
> zD3lNOc-P#?bpH@>=%rZ)CA-c*;$RV!+)-
> uTHaL<p2OA;?L4qbJ#%l)~+j7Q>V*E9;
> z7RyHeGAyt~25K%28ESGq&W1#}iRV|h+(kENF@Tl6sQ2Xn0nN=fLbz3WOy?m
> 1gJE3n
> zeQbwMy*D-
> pJ<vU#GLM`09M^f=lAa)o3w{@r$Yg~;J<9Cq_!`04sIPRXt;l^D>V>)*
> zy{9i12&AxnZ0A(_RdcBgvff~WH|a9#GffJmetHb2@TYZY7@t>rjpY&`Bne6(ao?
> ;>
> zL5-
> en5%UKRO+SgZtcg?<G7u)(Yl{J`D}<ke0#Q2<f69(xr6+_L<f(J8(M!U5oOHrM
> z0W+=>g35EQwLEPink+1>I+9B@C&+Io*eykpb0UmkceB_^R@FvwXVs&WVA
> -Q``y0H8
> zaC%!k{NX(XOdl<oX@Ep{i2cP$zDNRwk6uwG)g10!8@*>;Jmpmsm$%5+*dXB
> D6)oQ8
> z@B5wkfGdKn09Mnm=c^WsX3vgZBU|7;zb<z--
> V{viIJCtX33Jdgzo~NV0=OCHZlPl8
> zQx(={{|6zgb`h5JdBa9q>NoEvzxJy%{BCP?{vUizL3Hed<A?iKnm5v47>P*pyV`_
> S
> zM7av6n*%-SPOYh+TwBzg)3S`&m9?&H?&_$}ys$!xK1_vH-b^<k-
> s8h>T*C@&N47q@
> z4)BfMJ?zX|XMD_6i{f^zdw@^U0<%jV=rba=fX#ORjpC4J?e=K4nq+s#bw=1_
> <<4`}
> zDy<z_U*2AKz?92aN)J`9x;p+$(}Co{a}t+P!3D(?+;S5jnRTdQ!-{GfMEjohYxaND
> z8Nzb^K&1dTt|bIldw`|Afm>J%uJ1$Y0MT_tBj8}RUDfs87XpZ%b`bM70j{KFDY
> dIy
> z_3rpHbqApOqg*ZLv|K?g-
> &G8@TwsG*MzMHF0Qn>z@_0~@KQsP}YB+~g`wR!2(9zmy
> zs;yvM05MhMaE4WE&hGCQ#+pAEmc7rqkVlaw<p~=`aIU{+b*6QIDL<-
> d0!|n!lh0N+
> zHaC;UgdXq;37%pqI7TyCk^9zxO^D@W#!TxDy)-
> m0cgcPAoA>&#hT+se&tt+&z~2p}
> z<F1gV?XDA>mw!ZDV8tcPF$GGzPk%r)@})8LfruD^cnZb9VTvIJ@{!VH>$vareu
> k(~
> zYU>-t@D~Q~-x-
> C^EHJX>Lft|F^n2$B#5dXj5zDl*QWBxYpDJsZiPPrV0e!qtA8QBl
> z=jBh=>sq~HsiCyo!||pi#Li~Wn`a3<S=0=Ar|HEkYW(`1q0Y$GdEOlA%d|AI<|52
> P
> ztqx}^`qT(qnihYmqGqN%bN1_FpW0a4pL>Qv^*+RVJygHrV0r5+g3;)uK$c_h*v
> OXe
> z7%D$i@$FcD*D<bsv#a*E5+#}PV)-
> fSo66gp_U)?ujiTrhmLG!pHI)+68bxoL^j2w0
> z6=SGFjal@OF6C;K@0FO_W7aDz7#8gTjMYu;lL7U#_)~Sm)`UKRn`Y7Bsq26`{P{
> n5
> zh4ir48&P*$g`;z%6Bf*@t;kQ!9}QCrXzbgN|0s$u{IdU0e~3Q)@aGryFu`CR-
> mf~Z
> znCQKMKEM_xjwRKCC1U4&%3^)C>ucZPYY{tsjwVTBmRxdqc8e^g;%%oYf?b2
> M4n?4j
> z7c1;b?x;3@U_t!&SUD$=YWw2J-
> %tk<=sc!5{OZ*^=NeWcxqNiR1n;p=2Gvkc2^6MY
> zEpwZ<#8nQ?2Vkt5+x*U#Pu_l|W66kZJ+}|&zP3JYAMl$IDAFf*n;cx{Uvsuf?2;
> d!
> zax=aNs*^Z6{7}IMv%52goM%&!T?=&bzAtc}uy05IcrZcC?5T!~9S4sneU_~Pgua
> 97
> zx3zmlaC;_yp}8GAY{F{ZY%E|!H78a6>7&L5f<ql`w$H9joxXHMO338mM4s5>p_
> V3~
> zzM$6CWKg-TP|kP>vrT>6j#JyWi-
> j!tyLIynYL~uUHRG`}?(;2Y^WP`mj=kgE9W^@+
> z;%shDvj3zV{YPXftoL>;9H%DkY4rYXyf7^HQ!GA=d}!5wz#zdZZ3~SiCVH1UVnP
> qU
> zXG}f3(JOANv4`2PSv@M(Mruwxsgp!--
> W_j@XKW{5Icdi$M`X$jmC4IXMp{0eyrP=R
> z0LHb{kO;E{&6SDCn&Nb^_Haq!#QYgHgZ<~ow5b@B=kbw&=JJpJo5X>J75m+
> rF%Q~X
> zUesQ4r>EixF@Jpio!&<gY`bHqIAdPB1qtaE<xv7iv^`I$0fqK#)$5q;i9fTXvWz2-
> zPSY`VWs;Ydk0hFdHeXI66ta;vPqj85mp_H6Bxvz5goE}@ARM$-91-
> FyPwqWw$KE3{
> zQ;nRu%ch7d{N^U=!{&b3f@3$=&9`>n9fwIy^gbS@_0A6=NU(u9B7U$}C!Xed
> c-5hf
> zHtX=J=62LiZtglp(_-
> ^wWNaREGviI~jm(T{d&}kCpO8`AaVW3Lg6g7ZzUCLmY|y;d
> zu66mT&(~bvjDd&vGYcn_VeWgNk4v)pkj~gVoaO2=KT?;M8;k0K0C%Z(XQ3_^
> MC%gf
> zb9E6k@1tQ|@^YAJ!)+A#m4#MNqvi+r`|3mZ`{DOXZ8F+b`#XrSBH3S_n1DF-
> yX13K
> z?RCF{#JOFn8v8Kh-`d|zS_fL%Yw_w-
> (YjY*rEU6M^7+d4CLFrRRPAOMpTD2ja%|vd
> z`63gd%GA-Hw2toQstH$0HKpV$;gY2-J}hS2-+4<hByg;41hP2-
> @wq!TodUht79^y>
> zm758)K+>mpm{)`MoLQByJXOWUS;cU90X^eDBtp;YYk${HPZDh$q_2pBtVglD
> ZtpsH
> zpdlV_494fC8lP)lQZfs+I2O!>6K2i2cQnWfV@mA{r_A!NnJwai*V*+y*q#;_<yd
> O`
> znWf|8T5fc4Wi}++mzJyk4W4e5hTk$f?TP79+dj^)*fzIDEZf{;vQ{ISKpxn92)!K6
> z9)WI-j*3z@*&uo`=Ti-4SuE+8b3e>%eBz2=Hdcorli56dj+>3`!ukep!dlfGMV01?
> zeU{G72C|8z^K=U|7f0ue30}E_YMa`K*kcY3)bACjv}}IXq<9!}1IM36HOXgq*@Y
> 7{
> z#cL)n$kYM8wjF}6!^ux@wKrSd;az=Qz%WI(-
> ?dS22)pYO0t@H;n9BY8k4|ikEw@#`
> zoaQYbwN=0>TTzDYZt?nkj`wSLhMR+6<}PLP29jH5Zwks&ts5v_3}@^{kLGTBa2
> &l<
> zCB{~q9TYue%doKMJt}&6v}l*o6|KzPU)c)VitZ92NR4x!t(RocWqn>uRel!)wMo
> op
> zHfr#`?W~LFl<9T?tYxBOFlfDmG$S4}xGc$E>6K6;B+GQA*Rwc43u)XOMyobXvs
> Tpx
> ztvV&zsv?@>@G|v%$<-H0<t@l5nD4lLfL=e^s|$-}!OxO%tU1os6srG_Awp-@-
> 5htK
> zKgWUjcJ+RVcaQPW5c5oMXL+wK3R-
> 7<q?FAGJv2djGZtE>GixtMUa^Ih!br;m?|0vM
> zbL0`dxTqKh!Hw`Z$5%AAi+iD3qKuPY{7#cdiJC^|ub6EotU5_*nW@=FfegOhYh
> $0N
> zbeTovUm7I~i2)hB<UqBwjV&{zZM+NV3^Oc1W6`I7VD3fM7=Enmu+)d&<?mi
> pMaOe)
> zo(c@mqw79qJ$h|(l>#MRJwq;BDC-
> (<?02@mOV~OFuwcujY%V9cW%mBv_Bj0;N^hi4
> zX~wib{W^+e{eJ7yTJ$AXPeq9?_qMFsrnbJJwc|b5V_=nmW|JnMhLBfJ36$P(^
> HdA$
> zWvt}0Na|foQ1-km^#;AO1hTd-
> _j_XrfWX<ewM)W<N3%RP@;?|f>(jnu;9o52#agcL
> ze#6)fFBWwvU9*(gJJvM|v!_!iUWI;#_AoExR*MldRjjX_+FlYtu&4nyo;)q}{g%2
> n
> zcP;U`D|q;0EsKSZTInoMSnP7O^a{(7QVtf!Wt`SrSda)36PzK^&j4%(*i(N`DDcVu
> znRx0U`!FURUpmk5I1eRKcWswys4>&UFD>Z8$A*86Uh|no1)mMjbuB|MLIrT
> E%e*Jy
> zM<KdgN{23G_PlD#fq#_%U7tgHk6Y>d5^s&=v|juqLG@yf5W3t_^l*)$h?gl?X
> Zh15
> z-
> L*SaL8Yj%6g!>5<3hcJ_WmoNBUH12f)&cI_x|lI^h3#kDn_72fm4$Vc;oMK=bI)0
> zw;rNo*S~JS8zB~@#C<X=G9^`32A^pM8RF7rPzx2srA5Dx*>513bnEsh`$lDl+n
> Hj<
> z7cu?u8r-L2HHXMAL`7F9;q;&cUvp_C>{ki<U8M^b-
> }vy5`YTL7bvXvz!q!5ST^@fD
> zJht{weKb7vt$SnZ*tMuLMbqmfMA1}KxqzSedfhD)hGbEgyo2v5tXca5V2Wv_
> &+d(P
> ziZiQ^|4rR+$7jvrCxl_&m4C%Jm-%lZnFILxrp)J#${c*R{3R~`4P)i!oASSA--;Sg
> zD8J0*KYpzId{h2!zeWCLP#LuU)3(2DZFKE--
> >m(kKorVH=_cg;O(b*Bz7>44_K(UO
> ze7E*j`t2VpKi{nV_HFF;Hy;`H-
> }DFwSAX|SARZe9BCLP&`@;NvaKS)L=JLC5*8aoh
> zm#vd)!sbKryKl-r=WzK~RQc_XWDfA7Z`OYMc4+(c^$PWoR-
> hqilG~q8IX?)27Z7yd
> z?!bWIXq~N39=u6B)Z{J=O54U}jA|@d`y2ecs>AKB4v6REMJ4dY;q#6vzc9e={x6
> sB
> z@~Zs2<<;`wFDn1NnT4~aPV8!#o>?-
> hk}x;gANUV`%XvOK@1=ZwrYCbFUzX0QQ0$Aj
> z7k~NUt1tFVe6D5xf!8xV2bRy8`XG<W(icB9c|M8mF6Wnoca_gxIIHsbrL(5;Th4
> FA
> zfnOZxOa3Bu!?Ts)VUYm;tpgXZ+ZXQ7ZtG5I8<+lK;v958p8K&W)}Kv%FCV_qg5
> &I6
> z-t3i3Rki&}KJPhAF7b{X>Fh%iMmzP4p?<je54t(FxugtL$Qj3(?6cHO`Tpgxe#&dS
> z&MOPzPa%Et6Sp7%35qvh8>LgbQ!{|Af7!Y&?|$l#v6$QmM>E~xDk8O+@A%
> 2mv!NpS
> zO0~Px4u@gHaJ~}nCEBA+ZQ?cAspm-IY!`TwV{%!=Xx-
> gm2~2rc>Qs{Hj$x(`ZGq}{
> zrN_pMh1M^c)w{R%jrcP!vPF0O7%;6YElmx$Tk8j_)2t3#3#NVzW`{!SYi4!z$GV
> 1&
> zj6c)E)(%%U?k85bR$7G_<d_I4l<wGQZP8OmkNwe*E?))#(tqs)hXCm=<u%?S
> OfdqP
> zvpG!fkS-|R-Iq9lBQ;%k;-8Ry^qoSwVscw6UFYjEUpjw-
> )k9C!WA5u#k0T@Xcwccn
> zT*_;_E;i1?dW7j+Jp{#j?P9+kQzP|Q{|VJYF}W)0!EKi+n1B8*MtADbFrweZYoR0
> I
> zmp#htxA_=<rb9o(n5<rrdMVyki9$ZvX|UoON_mMtV`-
> CbRINGH&yYO0`rdcOpGg^v
> zC)+n7rziKu)7e3~Lmi}FE2=}GbjRZ=B&Fx=T}NfIs#pBUP34c14_A@t4n^R<j%Rs
> 1
> z^;L4t>r$T&kXijKkO~{ftU~E*yJgW+xL(OPVW8a{!F8SyRS+*bUCL{`rSl`W4%0ha
> z3yPP#$j5ahu!BB7@#Dg^VscMR28D*&bjqVD$xc0wjNktfKB+QUy>Q@e?mKJ
> fhyALt
> zXl63`>*G%vwi~@Ic6<ZY8E=#Qc-DH(q_i-
> }$JGn6nGE}i)qwe~K|N=9_tl)KHYx=M
> z2Ht5H_*?`7IkPkh7Nwm^7;Cx4Ys3^Iq_!}<!+@Z8trz+jsEA--#vQ_dVsigPL$e*C
> z5ZmF5KWX&Q;5`jysB`YQ3en(h>n)st%U!TmO!D!mdoX=Q+bi7qD9Zg6S$x_`cj
> %U{
> zOiItBSH*3l3UumOdG~dhtOD^TA8ZD}BeOc{`O%5T9!wGj^K;NA;WQbiYkAa9g
> URRd
> z88etah6JV{RT6fwNW$u1Fn4mH(B#3hTF$`q0e>r-
> )p($p5WW`sVv=KRHi*x}1HZs?
> zDOa!8dbf9>6SZb%mzMVuo7+86jkakc*F)IvrR30AEhlE{rZ#xj1%P#HOH7xf83q
> 8?
> z)O-6&fU{oBE-C57@nSAzAdFtp9sM*plhQNkEl#^Yr(VyA-#>`~lF8}?q-
> =CZSz}0n
> zP>>4lXyG~qpK^o;^JW<00mtBjIUPDD4YudWp^J31o?yec<iQJCwDXeeDzR%B
> 2V0+u
> zt&@~LXa_`t4D(tz9_VK{zvbAX40}iJWvJ2_?+sEfPh4!NIlORNVh)L|j(18~=*n+N
> zaF+u?60Fvxzb?TtEC}KSewO<h&81t_!&T~G64J7Avz*FZJ0av*>Fgd-
> W;*mtzPcdo
> z0-bujIDY@}WXPoS5`VIN*ie`466){|^~zj6$|YY27eZ*=TS;u9sXMh!V~KxSSbP8Y
> zS4J|oq*Ggojz48T_%uOHk<D%+sv)brw{QLjm5_P0GABC?glqu&jK!U1)OT74Y
> 7L3j
> zXZ3717`}!&+aZ85>Hi?+;g;tQ9gbpCs|~K6><VPE_WEfK7#@f3duD6%G0lm^q
> mT6|
> zd=EmG8YRRfPRn#C0~_VCP_xYO?~nWP>}OvbGS6b}Cb*LVA!v-
> mxVzeu>plXU)()O(
> z=wqu+R0DX30IDC+HP(ILn}7E*67hW7p;zu+=9x~dqyjcpPV$>XP1F~Lb?%o$ty
> cc<
> zQZ)tF`0j2xX|b|*sNx;UoiP}?V#)&CX?-
> Hb)O?6Pr3<d7VCu_@NZJDV=iJxXb;B>d
> z!S-
> qX1}o&KD8kaIgaBs^ycHtfrWP=x6Z`B;$2i8Iv}WI|0O0NGY%S#X<o=$`S8HDN
> zCcnp;N#vEp-yC5oNIeQYanu?V?FJjcyr-}zEn~6i)N&Qjsi)?>EspDVfb~GudELnh
> zfvn?FUgO<(L4@mv=^fV>6fbkGDusYq4s89?ymi_w;`)loZHL}+9@C44-
> 78gWsi#!^
> zTQXVA1h=Hi^OHHnK`>*}nN%!B*|{gk<Dc*gM2Q_$PX4eFT+Im1rnZsOx^=t8
> jj>3U
> zLcKIBrkhfGInER0e&bfz2k2A<uB%%4L<U_`VgcSC;ln*O&A$**?ht~oLG5jQ_Jd
> ?-
> z^!D4N7&vN_^N4;Cd|hwr4kbv}ZP&`nU|<88e3so>(oD@P8p_l|YRgp3jvILjJr{
> pW
> z1}t_5Zf}D>e=#R+XIu?qj;O?q4{t~7TJJ5nihkQ!Ce!g5HtN<<%fxBcvMRyKW6O;
> (
> z%y8qwJ(l74LI$?Xd=c!{mN_;el)2?(WqZQ1aS}N*X(#y_ynnkgEC_8EZsy?XXLA<
> H
> zhN88Qsf;@daDz9@+7kPhcLe+(cND855+<LkX27ENhLgtfcLsr5zzbs;NmHvP$i
> W0N
> zg-
> =&(?GRF^W1i~>B#zxxJ1{q6X_H+I?X|yWIYm#!@+Xp1a0+O^D1NZ@dG(`nU~
> sBt
> zn#2h<Smr(G50*s~l<ru<Gxu%f7H80GMmkO06URt*zbhrVw<=L1T6?8BF~br+
> v(bQV
> z{&G510Gpp-1%Azai$B#>{PhYS!tn-
> SjZ0OW<TwNHVfSg?OHtr3#bkeVqB_~B7R2to
> zc+FACPL&;7H7Ao*;K0u_*1F_NF$9flHBsq~g*<H%QqM7MPj_kEXO})qWLVSu
> EuIcy
> zxFxVdP&kIfGua=*npHsEtAvnn7}-rQdk@g-
> qsNm2G0`d#ZUkm)pK^nSf#t4<NIiG&
> zWX?+fexiX-
> d=`trFE`d>4@;bkVfktF{_`~|(lwVeNWA(fEIkR8qQQIgRMpVxX=Nrm
> zmGshk@Z76FX~!0x9GT<^^{&q<&@Mu^dJN}o73Zpb%CTIAp;@oGX+-
> puIMcRbnb;W_
> zh(~i1I*#u061OWh*AB}fLZY_jj)v4;5bt;VRhrmjo0pgbX`c-_6OLi5!id4`wIXK+
> zkzBb1xs@a)5?SR(A~(*i-
> 7}l322z)+`pQ<(G9w~NXR`Xxu%gPFR3=%vGWw0<#93^G
> zz4P5CBdBtg>;h9ZCYZV2E(SDUbbcb<_9JSm*2h1;lMv@}D2o8i8%}pzq8f3RcIp
> BJ
> zvi9uI(`GvbQqRTP(n_9E+FLUC;mf|n?8KQX{WNmaDs={5>a*Fo{IDMI#EB4iR8Y
> oB
> zkjqRL=(N&X7z9cjlVtD&0sYIL7FiKxI`qBK2kl+x8kGBh(jA|*xd(e!-SEA~xUTmO
> zzsYV1yJnVkL>c40u*%AG2+fV4`R^bJ!%u%KF-<n3{q^2`Yyu^9lXJh2ll$Qyt+2Hz
> zNnGGaP0}y;6SEel3X2vpS%uQsD!?Z@_0%L?=@zGdgy#j5^t<P(jBsh@QeN#n
> H77Dj
> zhw0rUEhye^Pq%#CsWM>epQeD;4{4HC45m_U@=e8f)3=Y=H@)Gl9!u~GVfI
> odZv5he
> zn%DyqYhusxcX35ctc|~o{JqTI<jFO$Dg4gh?+E_>M4B`CJ)ghW`0?Y$yMHC)OUI
> 8d
> z!%yT@lWJnG^H<5=oBSO`e))-fi+|(zR#Nz0y74PhYGT)sFB7kc-
> Tsc6*dGahhqw>(
> zyO{U?Rap~zjNj$_JxrP#_`RFI#$zaJ^0>({{uln0C|EkV%*BkKe8iDddGe8ZEkA0)
> z<jE5!S4^HfNqW)XpVP0h;K(ehNbao`Tc|K|2`msRx%^NDh?VIH`IVNWjC%-
> 3kiJ&O
> z59OL=jh0QBDeG&?+e@&YDd!9u^uUHOsqnHclZlG-I4$-
> n8Zp>GfBL;&8=1jJkvT_L
> zYSdM_4OHC|Tj}S~g>-
> J0C(w@r$8PrIc*8xcnx;bdm1q{E@xK&$kj?<H<+2f0OeOgr
> z7j)1;`zj0Vs|?yVHG{iM<)eK!t9_9&5J}3{m$cVHKRWbR*%*Ja7Cqt*WeG`HD4u
> mZ
> z00wM@R(bo+q*<4oB@<Y;akk<rZ;MMzg-
> Y^UqU|a814JayXhVa^=@t0$O0!6>OdedR
> zHKj#jH&i*VYyR``O<g&6?A=ehDlv^patxq6IrLsB&`s@PyIM9V%{WcDlLuENjt2
> Xc
> ze!4*wsdVNA7DmcB2U`Gex@IVrz{f0JorYS@p#osdt^VY0iJ7`-
> s#}&E_{H%r9r(rk
> z=OvLI;vp%wj`G7MEl=DPR`a&R3Q)%~8=e21i4TQoS`v+6n$?MG!Zgbgm$`Z`Pn
> -vN
> zRVLrKEpdix(w&Ku+$WaK?$heTB=>1qJoO(@q%K#Jd_>)rxHN=*XX5Ng4WK
> GN&1w)E
> z)N+{+>jen2GkrmgE(&UNc2J{PL5+?NY6RMae}l3wfa1)OYQ6cj`x2am%rB)hl-
> 7uK
> z%(4!%P|>OOW=4JUds{GNP#RVsVS;3Tl~abz?=>)XUGx-
> 41)ajCt|+~=4pgC63H1M|
> zWtgpWr!L38g=&O;fp-_$9EMhgp^af^br{;}hip?Idoyp|JC?!2Q*z_wK&=Zyi^75)
> z3**`d=^rw67<xPmtqDU<grN<D1Ua(lV17M1_0)7T#-_usH7E<yjZ3-
> MTXb4vx(PQa
> zng>1}Y&zV1vOnFFqp{S#tZQSOHnJ=vGS_*rkvMV##UnT9S+wt<n0ha}LXg;Zn
> 9D13
> zK2O_sP{8&b6tH~<OHjP;upD0{nr8Lu_8k-
> &z3*@cOe@Rw9So+~7>4@}H~TR4>-HTK
> zI&|ORMq-6-m9MaIln#YB3vO-EQ+OX^-
> {ICXitz4IF7|q7MettOcQCx$zQf2#KHkfU
> z@&2XjZKfCAYw>_267aVk&akTJsj7^z^{~fD4uM+0rCjXQMypcTda$b4)<YtwO
> 02jl
> z6;>5R=DvHO29F%+2vN)*>@Gp1I6Ls8u;R}utf|5UI`vu-
> &whlgEQ5F%*D{%12hn!R
> z_}p~{vE8S1&fNKcx>Eu5(;4B{!WcSq*s_mBx-
> |Z||H1)A^|d?l9!g|EuOH3uvShN|
> zk>}4-
> g{`ge4V}EOG*_Zvcf`W}?ufyN?2ashXhcT(HB5CVl<ufkAt^m=cSMaX+8t3u
> zvQtm)0@qn#YGjL-Q{!!0cy)LiX}NL5glvb{4Ke|y9|u3+Z!X_+X(p>^)2hyDne7lB
> zYdNO58Wjn4L8&gj)_X@y7S%}*=T&sB%37BYc7;%ZGx<V62GLHMc@MgROzS
> 2tmPx5J
> zhcmydc<K)ZL!V=7W){^4p<2<)*HZFQ5E7KEu%XFfSw$Ec^c0CNgGsUDQ_o^3
> 5USsR
> zmLpuwrCjWN1SS^lcZBI3mlG84!5RK&8>U44^SRuaSgo_gNo4M4=Y#bQRdara
> $n72$
> zyL!Xt3ZJ>4GOO5hR&RJ+;hDB{rm1j!$IjN*XpY<2T0)AToeEn!vkI|zuy*RHcKSP
> 8
> zH%8hyrMR6g<znwMRgrdv>0LW*XX_is`|TW}oJcztU=g25DKhsO6wNZ8ve8`-
> LHF@w
> zbL)ra@FA-gHn*0%uf`v>F)iSXToOl*8pk7y<1dk`I~7clK3YpCPJ3Y*9{9WbC8fy9
> zINqjX7g^&YtmMiY!XyuZe94-
> Hktx|+3M_^}N??M$uo;BG*%*6azdEIeHk2^dve>%@
> z?iSKUVK2<spY4UU9OvU~znacJzY&u-
> N|H$_GWWf?RJ%hgfpJ$(%Zwp3c)t*<U_0y!
> zXA21l=)-!sL!oqsWQa^kPqyq8&gz-
> YO3H{zB9cG!uYktf0s#8F3EdA>K*7V)Hp?u~
> zsb}Tgx1oF?z`jr$9mZza9sIC$2}JFeSs;(=c#B}y%mVp&nGTC!@5};ud_pP0?V!0#
> z@N<``+-
> 1uB!<?{6Y^B9hwyyTs`LU)iTe4P&q*OIC_o0%}Ok~OR#;uHrNB|m>iO3)(
> z*{RQO#YC!UbTGISHngV{N~fmNP03C@HMqL&FedW7$l!W{Q50b!F6CnHgcBl
> !5~g>9
> zOHjNe(|tl2q#XV831uJV;F**nb6?OH>QL<qOhj*}gZNxvB6>qb!P7AjcFswKM~
> US2
> z@m*?rOKm1=QG3g}+a@VW&2^x0(zD*iM0?w`9=?PrUALw;O?rXY+}|sMb!J
> GgxOTD1
> z0U_HqO;GE-
> >$w~Y{YWsrrh+%nc8Nn<R|IWqotO}a7fPt{^;=j@IKIO44sC+sO|#7?
> zb{z(2ZUk-L!sweT3W&_z0J-
> Ptu<Xpw4l9^xo3@h*rc;#^l+Ehd;N?COAu+BhBSCB}
> z9`GGG%glfn3}JX;!fU@MOl;iU{u~>y#*wlMr}X+n`tvh2a90Wp|8mds8qW66_!
> pt!
> zKx8@AHUgW23MfxN<2D(>(70-)`Mm`imuR1{+1hckaH4cHuFs-
> z%WaeWtd{6Rc?p;a
> zXk1~{5EUDtbVmi)NOtNe8sBoe(fDAbvw9)s2#vdxi@i(Xbzx_P>0M_Diq|~Nr*
> V&R
> zBApe(`aP3UWbPkkQ;)1_Ki{TACdv-Ir8_R*Gc=xR(_2b!tQL5tEuBjR=_R)t>50Zu
> z$_Uwaw;9<RjT>luT&=gx;=&B0@gSvROX&^c3p8$>j?%)$1jeDRazMy#vXRs1e
> M&m%
> z0*#l0H_%q;(Dug&+P>`Mgn-
> 7CP&8ih&IsDV^bT!;;+;3uN83J{8$sK1ItY<cWbSUr
> zJ9it~DA0J&#LT8iM&li26qHTriT&1UpT<RE$xb8AwTNj7=${B$;n4)GxLi2}_!OMZ
> z&Q%X|=$U+VaoPns^@>qJ4Y<yv^uo^gV>WqYH*50ncj@oI@vxm$=PbV)U+
> mtn<KWL2
> zIK{Ft*Msg?ft-
> XtGME5*QOj(TU*)jy0+#cd$}!V`GL&>uY#m@+E<0B0=bG2T$#VcG
> z*ZD0oM&&xy3=J$-{$oKwvNiApW!W0|RhO-
> S4^y@VegfGV_z9Mwy0Y1goomz({;Y`g
> zfutf0v)ow(m=%4#Qsp<Ay=B(`)Vx6hP+f%ho@4md(<~7z(5WYu2nSCQzV!m
> Wr!UiF
> zo!ujRTN%DF!l4ED^)#!5c-
> u|zqwZA9uVuiQrW<FPe3y|8CJGDro_n4Cby9b1O_Zyg
> zK@9?~qOh8qNhy?04YSlscIs&}=L+L0TiMbM#P82A4kBE|rCjX&8%!hQDq(szJi3
> 75
> z9X-V#9{rS~fBww*O&!KaDKfVV!VMYZ1QDmn;-
> lDw1o8sA02^>3i#vo}_$l9>UEs{i
> zhY+%htMlNYz%GVB2<&36!^dM0e5`O1LBKAQQ0(GmxIu`IFulWvpm-
> &fK0fvo<KwS6
> zN`kqH@UiGL$namPU>EEi`V|b>#eNFPru3}$j!8uOJ^oZy-
> OtTDAcyT~!j0LKmf7`Q
> z#gDC7X(OOyr;!nkWlcgAN#xEVPl2dp(e&w60q{WzJ1kMnqQ(JHDGV_BPa!TV
> A|n^k
> z@Qe^uPXvjlI{6?#qD#5h`#jqiAriy%5u)m}wJdT)ALT@ds!3-
> <EHYQh=qx6x0F}w@
> zHZ^Dt3h1ocNknRgTlqm~>rK#a-
> !R_hpdh7V1L?MDg*nLBNw}V24zjf)5V9L=W^3^N
> z-EEZxa+U`|AgZmm*&ur%f{$s(7;yynP(l&aJx53I5vF(e5ESoQlYFAuU5t;~g~Ep-
> zbFa^&msg%>L={vpvtj&B$RnMVoA+#oo{e7XC!_toKBeAoPl=kkjhKX_Y*z2-
> >~?bJ
> zjt6K!I!;o$(t*I1jl8)(kYg-%R7JG{%2C)TC#6t2wTFz!PCX-(^LhkRc{l3@m~tr>
> zdrRRqA?1YWBb1Y@@G;d(IT6Y^{%T=Lk-
> 6ti8BIAs=SQU%pUL>r3%ip4b9Pi3j`olp
> zJ%RV|2s`QnAy7`0qnrZ~eEgCj6JgIvD9Tv~w+ZnPrg!)d6mQi;A0ICi<6|O*?3t7z
> zb5EZP<y<twNiU<>(QXRLru3}$-
> i7J3Edtf;$xc1ZRLx#xsy5TNyy_6$WKw$8dmkSB
> zv&$t;#r*DOXJ@u{Zl*(-
> WwvIiF@@wcv|KZKbW3L=q%#W3=)+{>1~nCvyY+aDbj|3_
> zmhI?JDA4@wmcJ%`nNiyehnss5a62Swr8^XZX+F<%>IG}9Y0_GbH4~95vE4RA
> *!Vac
> z{ZA)%K>rFG{dXvo?$~KC^^DN}g)({a4;tj%v>MRAO9}nM7{mS!(?{w5D8IjZC?`t)
> z*sf<%ip)KC(rEgBd(LU}AF!4GF6S&glyg4uZ$<Rq1wsn+e`y3CzjV`TfDa`!`iC)w
> z_z2TS>A&2^$IfDWOuS0?P-O0D_*?FxcN+Z%O$<5bb_&XN=-
> KGK3nS{V+kNUX<Hps=
> zPEi785SdA4;Ao7qK)4wj5b2H{z%c0a%o<hYP}?YgPpcC%_BsBPZUmf?$ttbg7N`
> KG
> zi1u~10ebPEqw@T1LAetjHWN{Q45=>ZY_E#xu)-
> V(%dFB0GqXy4Mxu9Sm3ooJH>H5g
> zD)l?tT7j)T;Bv>{C8Br|xD=QDhK+5cJ?tbf6$}T1Kw&otD3ne;p;9~bj0}RdNT>hS
> zi2*^UyOfK)_rTM_P7l*Z2Ejc?_?_NGIgvqd4Az60lp=FG;djO2!~c7ez_&Rd8kqz
> h
> z2O)()&>q3ZPn{SL;6n*D2(FqC!AF=rG6+5~-
> p9xGVtgFI$raeN@bLr;Gj|>bxV3~G
> zJqbKULD`g^^<K?wk#6_O_WjwcU;h{V$`NAr04jkNbhyHf>nW7(*b0PXr=IHYF
> |1$z
> z=w|PrfiC4@??W)Pu)_=1ucqfU>(^|V-
> @t8@6Y20%IWCe(DKhu+aWt@gnx=703(38*
> zf$b3O-h%Ufq@7#RCD_1b6@#&w#Gfe<`S}=fIyJBw=PRz0T~+O-
> nebs^c<E0qrc{ro
> z{)NOLm2I;Z;kJ0$RzdXwj4A9erVwjW!<e3tA@aQlN&LXg?*YbK%EjIs*j|XSFnw
> f*
> z+)(Oc><P+=VC;1cs$qphWbR>DVn_>z7pj?1|K~zA-kN=ZD-^1~{Hvl-
> u>~AJG#i^u
> zsNNMpK^Np75sj2kqvFgXBPa;dI}`|tx2(iR!Q;g!7`#L%P-N~aaJ}5|@6g7E3B<-=
> z{mn~TP)S;dY3oY?>J-ag?5lNJria?bTV)=n1lG&Pv^u>H`S0;nKU&ba*hc_y&j*T(
> zpG_hO?VoKLL@}eC)MTfg+_;&s*Fc0)Nv+NtI(s8w?E@-Kumcu8Qx-p?t)n-
> Cxpc=v
> zJnhDTv1IykuoBR!!hodn6-uWzk}=t-XM|R#9a)fRj&-
> t0K&vk0Vs9PXDWugfeS}uO
> z9rHWtG0KV1>btO&&!iNY`y-
> so4YYAw$GFrH$+3~L|HjDyuI!N5!fAdJwPv$fEdVPP
> z$fPXNw;V6v#@BBgyhsM$wlReDtMDrma@!T-
> _6c5z)kKUTx$*{v<fVA~V%Btq<i04p
> z4kRYd4d~`Hzkn}W0XE?WM&-
> LI!_3(D_&e9Pwp<t}ngpojbU*+5T?JK#(7HSo0pNrZ
> z-
> @yFjP(G%29TRikrQR+Q=f42Qw`t$Rf{}R0Py^=Io!Ul`vOUk~mZZpQo4pEE;u+3#
> zhc2>>YMJqz9wtW_8EVhg5l&R?N<BnA4APZQ2I;B4<-
> I$#ktd@kmOslCWZWo<SD3u`
> zy>FjxVPABUt}@;>)5fur?w!f{x{rw5Sdpxw-
> `K<9nHvHvV~vM0h%Xoq3R4p*u28xo
> zA!_Q>Gcq1FL}>CzC#D4B!KGa6t%NUy;~`8R84q9mv$_E7$X3dUjE9Ra(0EW}?l
> <tP
> zaN;qQTQI2~o{^WS?g1PA@5=bxNHCg__x?;&8}34_1R*f;o?DHPZ;asMfSbhw
> d?=w9
> z`OV`Z_z2TGd<cs7z_5>xM~m@s`aI!7k-4874LLS)@-cs2Six}c-$6my4m}&a<jse6
> z{y~U2pcyE0ESgy|Mz+JzOpFQzG^4Pi8HKp=fl6=%inW{#PN$aqdIU!=yLmgnkx
> RMQ
> zyBro7(oC2>LNmAj$;Z(a%8AfS>G{HuB6I&Z<-
> bldXej>YG&4Tzl5p~W=qE)qvmAs#
> zGjkoyd?SL7AGk?8z=slwX6B6ixqy!_y~Br~csCsM@$pbGK3<<Id?+&aFnygn5s
> SmI
> zXy#@L%6914=)DIk?a>Tl7mUc!4EBxjHeKct2%gpPHW|PMQ}Icr;?IB3VCYCogz
> X$W
> z4BHvT;Y&b53L6Qf6yicC>coXmhKP`a`XeaY$asp#OD^SN?+v(0NJ3%y2nn6>hL5
> t%
> z#VG6I=o$O6LfI$cqe<xPS5<09C}xh@81z|*!`$0!3|iXA#^C#3E+V02AOsTfm9q
> OH
> z_*mz}i-3fbP$ZOttAzLn(>r{aQg-@~kB?2o_;~yr;X{$R4^4)IehDdHmk}`FP}9GZ
> zf-
> sojS?>+pFjn`U79kUki=njN>C(B=O%XzI+s;Bk@!Dc2LMRG5UZW6(Ym}Vq)H5<
> a
> zy%9motqh_Fp}3UTKf+2v#DwW1gfjA<K4LZ&Bj!tI3o(k!)xwJZtMii)N-(?pcju=u
> zwD)sgEFzR8Af!Mje~#eeeQy@wLkUGFU9gf6A7T0kp}h7-
> A0Hcv@p1ng;X{$R3pvc5
> z`zIC<`3pm47|u_ND2OW*cs6=Jc)t<KAp~%}7>p@AIj0tHJ2gT%?g0CGm$8_?y
> m1)*
> zvOhvL3Olk<2$Lo1k?hnnLN>=h<ALgOt`kp!@#Io2_Pz}J2+<U#kC08zejiQk#b~;
> D
> zw$P-
> =++?`%|0!hi#*d1~rW%A4$mX~RKB}B}65vA#MK)>JM~IIweS~bbz3$_qtr#Em
> zX9*vQ%)NOOWb;|NK7an9WOF$MWjpk2^ftWD$fmgWPl*u8NoMBtF_&!Kb
> N(!pZ6kN?
> zaI?^0gh~{4RH6{4#K@TJ)H6aQ=SHwH!3iV*R$R)(-l_u;tc2+!RPwby_*hw2jFrpI
> z6jl_O^C;&36e@Z7g(51s0E85%WL^Xx2i@!%;6n*TB_D;ChEx)!k5I`M@c(U#fi=
> bW
> zI1A%-Y;c5+K6qHJiOyyg3ixNpT;@^`SH1CU^loV~Dk<)M-
> %{e0>cqQ}ouY@>y;th=
> zt7f0rDj+Iwpbr~bev>c84*WcwT1_yWUBfe6eZgsbQ;X>?i%aFQ6{US8wvJ`&84
> -z_
> zqp(?l#LP%#yuu3AN^q~f8BJ8ja%#W|4>((nu~jY(=tQe$3rZ5LB}K#8j`tA?mc3f9
> zx&^*YZrMsd)pak+N>yQ^RUzKCo@^)@Nvcz`DOHp8zfv@KT~APFotoXiYax;4
> <VHm$
> z!XMbHZz8)zTcy-
> GIGa_VG^=$lK8ggw*5m69TstNXTH#yO6v$nNaPJ!6HVfQVf!mBT
> z6~9vXtNp!pruNEYr`Ga#agV43<|a-
> b1=)SvRl*uv$qkkToCUEC0O%xu4gknLG}*aY
> zK;x;ic?m_|#0`P20^^)m;vH^Tf40NDCiwhiLD!87zRr$(oe@APNlbBhs|sH;9WoA
> _
> zZ99OoJJg#T@({xOc~Pfzv(oIkBc~~StLGT$1I)WDP>a4PcYQW1r9*@F4=zD463
> W4i
> z4^k(04+S~byWHhK*$n_zjOLlsp*jBf=V@nmYAU4@05|FpE-19F6-
> Lt?v#i$k%<5^~
> ztAGrx)5_GL<hNu>unGEi7%sLU`f1RGiPQOlVMrA}_1^1`kz1#DRb0jjv0Wu)Pj*
> @z
> zWCX6nc8XW%(LYY{7L1}ZS$#*7WuU#Uvg!k-
> JH>l)#O6C=sE4N2qI&Ocm(D+Mu?B*2
> zns*)NjRIFc=+yL)L3*dwJf0K19SSyj-!d(CdEo#_?j4$a?No)G>y>qvo$K|$g0L#3
> zr^2Esj2j7IZE9`SQ*+W7=X&pQ5=g*<UCPDYui3#4d2r!euWdirx!%bGJ`Y}9%!B{
> #
> z6!Bn1=9Y$YEr&3ibY`O^o|?{=Zez<<Z|*{r7;kzv1sunoZ-$rg2lBKhx{~N31umCp
> z9;S#q%>dg1oqA&WKh1LJ1*^1rjMGA+7!K!Q=du$BwzRnIJ;wZVNo5F@ZKKk
> p{4_Vc
> zMVgcSH0BKZFmO)r)5xLY;mUgB-L5{bs|ODQ=R1CyAHPMKR`#xKb-t2*Kr5%-
> _$uk0
> zvzC4kLnVw}6ebA0D3nfB7`^Bzdg*oNz|ThH3MAcYoGcR1i%WTp_w9d=&`X%!
> &DnzD
> z{cFyrmph8-<*q8xiz4%<=b*)r+<ni}vu-
> !4qnUVLw_9fk6~T3tbRb8=kNe4=?Pz#r
> zWaX(fv9Fv~6MK!n`%bTkz3;4=*e(2>adu5?^EoxKYl*vozf1W$gTGJkx0b)L&W
> 1ls
> zo==kJWBlI7?-
> %*|ubvJ6`sFpTpOA0qMVvEVP!roSuO{|=;`S4_o%gR_S`)jvrY4pn
> zyoxlx;CF<-?=?`?fAehk?M<AI=kK5S`x$?K;_syEfzRL7`~~N!{~tRqo_Sc*%&lYp
> z-
> #Rb8GY=*IrRT*tU!$Y=^5V?Rt$N8U7~;M;j=5WZaKA?1k2t&<dv|qg`NJBC^~s(
> 6
> z@4fzgcI5ZG+M#*>QlG6IT&|5Q9M<e}KYg06e5Z-
> ?x|}P|u5_*WX~WI;9iNb%c|~(`
> zr2-
> }17Z{ucrG`8co#VavYGJ_oDVxhkZkfHgzjZlq@ZUv|SsV#8?Z$18U8Khy5W8tY
> zx(U~K<}=TC04ra~TvSz!wX#VY+1kGPY~7v)?-kfRPK0m`P0GRr4BW-
> T9TV5edw1f0
> zc4<ZHSC|Iu(h5Muy;Eo#cSocvxu76liZ4G7$}dl&eu>52f76F<h@P(o|3io1|M2&
> l
> z^b3YCJ{|v=VBC2MKe@T=PSfl^#Mc1nC;Yw$={O6Y=cQqS;j9`aZuW$Cf$+B3PL
> uC7
> z{)?I^nx?yJo+91cCqFN6XV=ZmUx^gD)y>L2cUH1_-
> qdKJVPaRPKzLV23q6rSlWS+h
> z5_g)%fP3jK9b2~}AG;}ZBRM$5C{hhtI<L6U-
> 755}UZkaAVppg@ct83#L(ew(&(D2>
> zhfhSAx)~6Ua}p5{Ql@q~gw)^QeVKGdNKjscknn*<zjHm{zF49fjAcsfT9N6QDZ
> x!F
> zcE^c-_tBeS3Q`_jl%k!>k+>-
> |GllzK9|}kcpxhuZy*s8s2ZfJGOgQDR@!UGF&Dzq#
> zGq$VtHJUZ3AR`5J7e9S^laGLP{3a&(gLqf%NM(Ma?=g=Tq1YpVp}2WqCG@e
> AN4Bn~
> z!P_@aXL8Ewy&Lujg}D8|vxBW4&o$oz)kiW0@M191`kcyWufy?R>)IZrFgFYA3t
> D^=
> zjhUM4FHP5O(q&eg#wEDeX;Vq!qI|XUZLu!*Ecx-
> Gk=$F3+c7I925{Ue4Dq2$ekc^E
> z&gsH1KQi}u!d@@@qnm)5TH!F~yzOs<yv%{cM*G;bG2O&y>Jm9`pn)_yPKto
> Ce(r>Z
> zfSgG-&#N`iBAaMpha-XT5_=<*^&Lh%J({lDkZIbGd=)mfA-
> Q(L%DZpM)NbJ9!sQ>g
> zlMA!>@qI<)dVx$>^~~*bVc1tJ=laz{vWn#%<I#%4jaY1*+-
> O*0VMAROa~Sy1Z$b=k
> zl)FT<!$DdSw+9$#SK>@vI}Y5EYqtvnOB@DtfmMKkpD~Uitea%>ysHhgkAX0;!
> +=0|
> zpX!fb;Gdy8qYE@5>Dso|wQaF7?q9sv4<xQrfEM0+oF7PhFiA{eo?fX5^srn(8lH
> Gh
> z{{0HFW=YIZfE8cjTm^ugI4*xV?$!)H&(Jc$l!J!Xg$<v7=fdQV`83mOxHX!22sY%?
> zOkIU@EQ7oX#?}QGTSq?HvMyb_ExC4Egl3jTF!uG|6=95I^Smhr+Q(R!I6^bkz
> m8z6
> z6^$!Xtx9u5FDy)dc=H>zu>-
> v`YiFFQFXmZH6|?bCjX_G&J~rHu6qy(C69(OJ6sL9w
> zAF}3+)pMZOUz3y2eUpS*U9qguRfQVD&yDlGee&1Jz^ue2X5BuW>51X=bf35
> 3^ROR0
> z_~_E~<Rv35v%MAY&`}ukPP4e_Wb%$Dn4tr-
> mCJR|C918Pqj4UHXRh6x{?%2#x_-5i
> z8;)jh6OOxYYb2gJn$$GoRPuCPp+`LRFh5pbZjb9wxM_$>Fma5TZW{Uv;kMv7r
> Xu4m
> z+LM<d|IR<V)v9nom7ju?v7!|1++Y>l19pzlc$s(6D>RZ}J(%lem6HG82LDG!5oO
> *_
> z;U*6Lt-
> zPNt>9v^{pO=A^*J!nT`RB1AP0v^cFPwn2yO_od%pbJhu#cRkn*Ua6uLkx
> zxPs`3Ozji+UvxF#<|=MJxqzEbl53y9!K=5B8g<7c&3KoFm3zKi)AoM53$2#J($)A
> s
> z(p_l#?Jl&s5gZ6J5g-)N=TwgK8&DI%IZkdy>}oS6gTr;q`lb<K{w)$L9XD&;E9=4p
> zV|5%3b|~qUMe&r_Cf;^NPF<%!TaKquRY|<<SA<uTtPq)JO6t88r`hS#bnVXM
> +MOdU
> z=X#%}(_1e|k}9F&e43|^G1mfRp6DS1`3~m34>K||oL#j)whLB&41F8C=g*M%
> pli0T
> zVt)K_@{QwKF3QyIl={*oc%#Z4cO4qB<AQ?!<V;(Vd!h#i|0dugUAx|H^!|l=M*
> $jC
> z@&q5h_xSn#O8JaFPbXib-
> Sgpsv>V5VOxP`_XPSDL#TA^y=${m;7JHbAACkHrmt<ny
> z)O4Lc3o99`b0>7pfrSRs#a2c`I9-I$Q8hD6TRZiP!RzlmzYtE`=7%XTQ60pOizO}#
> z;t8LVuM6HvVu_1`RAsTmc|knkQ}d@w;*le3B$9E=1g!`4Y$+qUBtOBP3Xik-
> h)E;f
> zb|G^_ckNbslpjs2{5+~32{3py<1PR(B5@ibyYNC_Ezy(r>crWtoql*-
> Vp<qRWB5Zp
> z=N=$0@OZ|Yj;FR4=eXp}Wc4%^qXjzkEQ{a&1ybS?mlvE5JdRWVH5$*fG4tvrq
> 8}8C
> zckmsDx;!%-
> 3Qx3ff~%7wskaBIms{#)ORezC4uz8kMPzO;HsJ6Bk<PpAR{^mc1TT^(
> z9<#cO$!Apen*}7Rr`6p8oqAIDuUXyoLfv<cuKPJbZI<yJf3Q3=9STphaN>PMb&
> mz9
> z>n-
> (CORezC4uzw2??5l3x_=94)DilX)~AN`unA!xx%N@I{eGIYqBL8(RmaRV%+6(^
> zu~GDRa_!@>d(Ka;eQaFIoOxZ4`4&g!4@by+hp|TA8KF-
> %nWo3_wW`W>>N%1))&)uu
> zSGYiF;*^|p(mu|AW#|9Pyg&XjsQ2eYv1_-!_Py`pBt&GI>$l`vaqt<7VMh-
> sU+dTR
> zt1h=yu*y~NJCO=jMJwoifg;?pkJW%Jc#fy2Ow(3PpBg12Zvy&CdO&l#xbw=B
> M==%0
> zpU(8_yg+p}kMJ*1sEw;jjPhKv^GD})IL@Ewda6{pja6<UH<+eFzC}yBYqcchXN
> &u>
> zQMtbEwf5{H@VTy2&vA+4U7#dUBDc6(RdsRzD3+hhyRgSQ?W2KP<~KcbPg8
> g8W&zC9
> zZkb*C5FP$dcIl+8!8~-
> @7gQ<O=jP<v%^DG|30L`becvyFmP*LZG(A+>v^m}MQ2r4^
> zlwG$uT8>!X^xC>t?p?od+^kvaCOrF=GcI>;MxC`CKJBb=UHwO{UowH4Jnx;*V
> |COL
> zle!+VfMlW*=UUXV2sW5}rJNP%VP{q+@;qM^rWkAHEDO0`>p{?nAf{>3L_`F!
> 7Znag
> zgs4d73*&#OWOjQXS?&I*=8(6T?*B4D&F{$T?`K599zNgacVzyQd{u}*5oXZ}T=
> #TV
> zFbW2xq{)mta8pg}Z}|IP{QWb3-
> {<dF{Gqok`ZuoVZT$F>QSZ3@{2%?3&(N98HTL)Q
> zThZV0r}x+VzYp`PKfM?E=S&W8Mf)&)#Gn`wTf*i5Aw@25cepzm1~WCos7QT
> 1f$qGM
> zJU-
> 0$aChM$x;J|DzZVv#r)y2<)S_rW!16~RqH|;67`K=C`UsBh;^BuCaFJ5Qi#d1&
> zXPbfkA~~?=dPoa(i|74`(*(MMu;o}^OQFbJ7?tC>Hn$umulL{TeNma+jgAmgsc
> }tt
> z|2K2r10Qv9?Yl`fvO-{k291gkF)A9g(P#?>G(y&*65T8;>h*t%xLvhc*dSU0geA(d
> zZpEvp?WL_$ytS?GmbO-+1sf0{c+)m$o{eqV2Aj6C-
> L#F8)&*1YzTY$R`|WQxL9Oq-
> z&*!4q{q6kD%$zxM=FH4FXU;%|4O$B$xrY8LlCLW{4f(3x&??Ja*zCw9o0CFYzQ
> oOc
> z_|i}fAM(}j-gYcx1ZI}H3XExK&kSU!9N>~!HSU)jP_%$BtBBeuQe|iIB?zNT;5qvm
> z)FNGFjaB7c*;V%NGQ=)e80;!Fq^^>g)o82A4y(%NKr&3!$;&C<5rq|TFJVBhE2a
> &z
> zOk}=ivG+w-Fd4wz1R^D>Pcxt2jYy?~-WTWPpNja%-
> nGX<;tBn0s@_<P*yjYikAO8$
> zQWbe$9PfRxw)oU&kDL6^N*?1~A$$R)%Hp`M71gAZ*F!X;E~MhJqcK%X925l
> x?%*2S
> zd4QT}U^J#}F+;yvIC-}<NOc~A*S6Wk)%`0ju#(?}7dJZHyRH7X>i1TiLd1T{q#7j6
> zEy2ZLg9ZDEaq6>Hj-
> T4EPpE!(MWvPe9Fx)RZL>?O`&XUBf;QS^pNz}N1`Bo(;Z!YO
> zJz%{;koXsC$D`@RFstIlZO#{K$Dazq#e4{h&n7~>vN#^xPISPUpgy8N*QFtWM
> 5S58
> z>{FN>xW8DJ_P)5lb87S*P@h6psIO_3P8M?lvN{y`K{f0o##HTNd4{6F^v-
> v13nJcm
> z#*hM;deGuD>v|C<KQx_+K?qV*lE2AhA;fVYgi!QhCJB*2QD0gJkrs+dj=SyGCs
> e;D
> z6qV$KcKM~%?`n$9vC9TU>(T}6>a?clRO^)wEf>Bs6!kh^Je)5St!p7ggXvhX1>Ds
> _
> z?jnJiRQ-D7boLg@$DN})z2DrGSa2Mo7`C&`{|+a2-g#L?5YP-
> Fv5oA?cgy5mTk6Cl
> z15w+TTq<>wyx4uS(bik?jKd1@MOzruT)CjTSmc=KU!#4s(rKe`)$6O|d?U*~1s`
> %&
> z_ZgNtqPRNuuVw|>O}O6yo?>nl$~d~Xx+K)4#Z@KbguU-
> F;%XD5gDpEWWN5oBu72Kb
> z#8sCiJMNMyyOKq$(vFjvE3PiJs@&0;Ri%ilvz=9HNL{6fs~fB;Z3%e@p5(l{^{Zs<
> z9C5XjX~B`j)w|4>Ev_Ofaz#};fkqNlyV>^{QMDV)v|B{gR;1ga%9d%TkZX4Kc=V
> ew
> zyJEgp%xMy=(X%*S2Z1IrtBqWR!mUUGJj=+QYa?p$w>wfNh<Ze(rc;-q-
> Si+}>nS=R
> zBvJErL6J45rDnci&D$}yrRE~k44DFf0bxflMDoQ5(4#?OK7X?{QR~75Asu8V`k!N7
> z;0UN2Y~IHa(9SCOE+X&RF#_&~vBfboZjcvk)&S7<!fgKcz+jFYX@>tnnP>Wke7
> t7d
> zvM-
> kY0#js`eer1bvBz##mKDZK;zJY4L@8+5TT<2WU|&3+dygI{ld4*q4xh*+>Eo@h
> z#&1_mjXnI;;0b$%ChUgB$~IVvvF0eYlVH3L_Rb*pFQKygppS3xsDBIPyKXY3I$X
> c#
> ze*ZEzbj>avCv`<Gz;%nb-ej<<O_l!mpF_cTs5tJQ8i@PL1F8f7P;1=;5D#u<ERN;3
> zVA^%PiW-nq9Q4EBHx-
> pE8bZKUE3oozf1<YBt!=D;ni{{(6Ti18dSobaadbubw4ul`
> z)sgaP%g#+)xGY}uqu9Liq8LK1ulNzdKb#oK<2b4Pkw;yD^5o$bJfyY}?M2$?h?N
> `K
> z@@iG<qBzxduBQ9l#G#=Wafjo9q8as`hC*rDtMluB(($g(l^SCnP)JeiDo<>VJ9c
> ML
> zu-
> <>&^*3FA!!EaLsKfLx<Qu25zS@QH26M@E7#D_Y_gC$^dg0>O=%EQy_5J1$h$
> 2d1
> zU!(oY*IFNdCbJx!gtPa*$F;{V)%}~xwRpzphPUFgXChSlFA8=wP51k-
> F?|h_`Z4pb
> z^=?~UlBgY3TJc`hP}Q%S_bod)+FBGZu6}RHvGF4nhpX=$T;iD%ZJk>E_L5}v+m
> RdQ
> zte%wyC%PKSqO%6%VXpE(wmriisPy7Jg?yivD%{MJ(7Yu+7f|v8rK*2a?}?n82=
> *hk
> zc<I80iMp=(g$ox3c!IDD^T)Bb++eq+Kb{AzLqqS-
> 8?%1=?D=psdX)Wv%g^%SH4_s-
> z6$s5mxeJFnxCCpEcPc(U9w<YB3EzPK+WA9o@ReU)4a6D-
> nKQ)ejfXnc;>Ef0VzBz>
> z-
> nCQsI6gkxqf6s%4EJ@gv?8qAeQ8+gd+_JMUmtWqLvJvDFQ6bGJk_tFzkPkxd+
> );{
> zt*2mTb$ZG1I=3#b;RP{+VnI)I{tLNgVP=@@jXs0NMA2*bbk(EK3FYWe&}jg4iu
> X7F
> z!@G73-
> dK2`O=+WsO5lD8q7VsIH1<_rvgB%L`i0A?+m?;Rex`cno+X7f)jOB`BVM})
> zOTUt^3yO{*7XtX#4X{!7a!4jP-
> BKD@r9mmx3p%(KI&kSEE}#UuV(1O#&WrnN_@wwW
> zoloo#|5QBrdT+Twb0S7=UsGQx3bW#y!&79|AXz1XxcMj$K0crR0rrj93vTYgxL6
> p!
> zXaTD7?=2)0u^4&_)M{Ri$50pgdFU;Yq``Z$&U|RA&OASUD%mR3Camygtho=8
> 7K~I3
> zOr(|$19)xd1q~8UHxGH&PGq^ynUt>PUwhZ`Twx;7kL>l~JP54icnMkMT0OK;
> m+5Wp
> zVRr~fV&eb+1O7y_!Z*4lbSuE?hki+%Um{pD0p$MqijL^vvEDW8>}c!QS#H$hjn
> c}3
> zz*x+Th@ALJB+~e-Pi$m?xFB5$^bh?~*H<4;552i?Xu>oO`Jsl};t6KmdgJu9WB-
> AN
> z$g%6zj(r~wsZm$N<W>A4Qnjiz@$gudyT0U@btQQ<(e#*=1Bqs)fX_&9_L$J=I
> ozMg
> z-Y}KiQq_8cytr9?#k{e0zh=D_?Srh*_i;ZDZ*Shm{Q}O8VEA9a=jZSYQ^`xz{N}Bk
> z%%qJ-(pPHB&iB(xIKx3dq*ABKW!l`&67FuosXM-8y_U-
> w`}pQ`7J8KXyrZ+)$X^W;
> z?6OoR^thNZQpKrpRO(~rIvc})lgO)?#$@)#c6+*Un1R*xqFrdur}*53=S+LBH|b
> Ze
> zA&F5OxsCsVjcw{=y)!4oGlWoI7c|(=OiQk3aaK$8`qtoooX)OJ9EN<*Lf)*0ZG5L
> 0
> zd@n?y7QQ^+mV@sEVgp4a@qNk03HU-
> QqbYw71^Lxq?io(`@8HeR@RjW94$0*t_EGU&
> zfnyOQ&sr2};k%p_*!&{&y`9*Ep(F#o$2#$a220~RhY)Jk2>2dC6-UEYva4-
> h%w>+F
> z;@gg63&gh*g<AaG#tLkFg};A{B!6f%7+z3bXrl%GmQ;gvf^g~~sXv=5=CDwUD
> >5va
> z#UB&wvedxcxlQ<Z{5|-0-
> 5xipv*@2j8#C<@`u_n*{xH=D0Tr{c1;1b)tm*$MA=C~*
> zBfBN{vpB0IS@<8Pv#ZYxL;k4rpJ(u0fI=;N=duEu{(|pC#3o!U_`Yr91bi_&YkZF<
> zgc@tV%Z$f;sN!h&N_O=S%t6`0<f!;=g10OAWeW<m_~j{9VB;(N(u^d11G}Jnri
> ~W(
> zh4-
> >sSl>iAb*<E&P37ZRs72+Y@{3iL+I?qk6FwflwBziS@ITsRwTI{1a@zA_B>6+v
> z5_7W5LK|VUM^Y{RC!BgnkjZY(92WYK?Xk*I1L05Bo<VpzvpsH9XSFAdHs-
> YF4@mNd
> z#H*X_dC*1}?U7W|o*jf!+XR{H_AF(gAK4zOELHvq+cV9y=R#CxjgP6U+U7SI9}
> |dY
> zxJ)|dB^z6ek1~tX4x%8)|1XfN*)91F-q<b48PAek-66S-F8`YvJrshcw7%b!GyUrQ
> zEO3bStjg?n>t$`qNjrh#5Eyw_)p?;^zJ)qb(Yw>~$fLp-D1+8kS_XmOhx{JDIv{!7
> zA3rY(u<{#q_o+}{eS-R-@&y9-
> N@gN(oEJA^MGt*k{G)y4yip~B`=6kwr`GEOkqNwR
> z1A2xDRJ2E+>p(LX$FQhQcJnokRg<$%#vu=WPk9&JRvdl#c~B`Yaz2y1OmanAn
> 3Nxx
> z6q>tK^z)w$DXd_jpTBgML;J)GzeQOn<AD-
> a!#PqZ+!#dL3P!>{)Z8^i$hCy@^(6zq
> zgul1oH?|klnbxb%JYcBkUAqre+wc~4D+5gW5{p1HimTTV!4<P?6&=hET8Ljw5K
> sJ3
> zz89NB_*mxrj83k1!{2ExR<@w{Y^G1nE^&ztt~@&r@299Yc2JXd4oZTHAC^}_v
> >ktA
> zGgLBe(EJU5n+jpqV4+_VklxgtsoQM#U9pXDIan0X7(GiM7j%;F@-
> Y}qR<}B8?6GRR
> zN{Z`AO*DR@(jH0cPI>s_9RARkuUY&_>z_kk+UC#~tv*z<bi(RGWlN9oKD+D9
> o>$`?
> zRjsQJOn&nnC@QMn$moxze{B5`8_C;!TD2FM3$Ez;YNv2zs4^maGpg0WH+0*
> D8{5+D
> z4n?Vk3{3>MWLD2^(>dVET}!H|+83GN&e2pUI;mm&!KV&yuyw&T#Yo}RbjY(
> +=Xv!g
> zDyWP+!2NDuMe*B%n?5e>f(Ht%*VvZ()dLbW!L6-
> uLy^<qUUejL3ii8VhaS*|%z_f}
> zW{U;;D0%wirY2us*40m!A!8=HZ$P}22ednwb=^~)Vs<6jgDU5iC&)Ic6~seCHsf
> #~
> zgbQ4>v7a>8*E)sI3~kjkf9#bkngixMHT1HB<{C1zfi#!foX!_=mB4*I$z3)yqtLNp
> zR1e|uPMA?<7e#yW8W5Fy5F~1PXEiXPQ{$jq)R!OeFdr5CfRzjTa1jb_?cIcUG_)
> &I
> zTMJb|^=wbWB>afp57!~dqJ0Vn%|(KP&_kHIY9i+|*LYm)iIQT_)Zz!CIKk5Hsos
> g0
> zc7W4279taU{;y7*sM8d58K$88^>rS(b~QfR4HYiaFT<`ux8`s16Bi1~&o=!QXnW3
> p
> ze}+qsDUtV3A6_?XJRI%304R2(VUl|FCDNMz)H-
> =Q7LTOSRB$L|<q9}_da4T_cVF&W
> zimvSh$)#)Ma0L!qK-nroWm2g11QEl*&~*(moLVq+9Cil`rx|KNrn-
> ~t>Y&QenL=}s
> zQ_4|Sy<m;3<Tu#MK94Y>?YU^2=HZx#?lys*ecfQNa*f483yTY~vA|J>8S3XPcB
> 3DY
> zM>ZN*=u8?5mZM(#k&OjaL81()4i=x%Dth)VR>!uw!q-
> ~Wz50`^M&ppf40TJUx^j8c
> z&b}s-sSf3+g_-KU1B_&uGh5bd8Hw^?bco>M;bJ-
> z%1oo~V^?w&)SJ3geHWr?uZs;;
> zzmP{fQ3p-
> |UbPP`*)Ty`@;R#|hcF85?#mHdTo!ysBQ~<w((9|f$U<BnNqGlB4@;@x
> zxohnDRf&xidG1)R&2tz$V=bP0%HlcgszWCm%PU>;Txc!YV&Q$66K`=|pQ(NW
> nPIs6
> zTk@zoJd-a}w9MkX{ZQ($-
> N5Jmap;6P?Gfy;TtSRKFivCOnqqx_Wvs3RzF?a3Ld_0b
> zehePBX((>tGgW;CmlK@0*!eUr!hgODE`Nb`z6F$ARqZQ2WuI7)USOrde<3>hS
> _G)c
> zt`vT`GgbGGZ31kTN8@j9=QEX(3#o531XzwrjWvjCI5?7j*f`9OaE(`sJPs3~_{;&(
> zUX3V^R#=EWiNWBY&Q>B?l|eKO5n$OULv}umC`(gkWf1*E(a~hY`r6Uu9X%c
> Cb-vX4
> zy41S5$5-<-
> i5H*n>E(HjBo95nIVAc{o_(0;c_6&*ERKf|*Ju{Pe+0KW5PqHruMsQ(
> z<Wiq?B5dc=2(vV`?E5xlClTSg;{D0!Avfjf1~*DbK~qt@|Ie}DhPZD7tbQRH9YZg
> W
> za`_zDs##`B45iL!BaSjnQk{?(dtE5Yr4GrX2ajakS8z^%N?@$9xbtfVC&LzJn7P3d
> z{o~}Fe>^5$q?ZG==TD6-
> IDcA_!zhOm&t)h<yQ4*kZg8%H63>wm%LM@dxzsFqG(2YK
> zb5P>0|FS7j0!-
> 1k=z$~fMS<+nhxuZ@whtY7bG>Vykbd)sPdheVlXv!@LB^wfL0)0>
> z@M!PaC4eF4de?>sJtFtUeQofbE9Cs!CVm%f@COh9-
> %h;5M+QV3p`Japd4;&?D41$~
> z!@Jh#D2_5soe@m~o!^5v8lAWCG;#ysRK0#d@fqvJ124e>glL!X-
> p;=HGcIbQI%kA>
> z_SB9(1L*itJd^b0kxS<}vooWIMn`Zi4Fftja>GCg_$Z!<Xcl#CQgvHA*e<kbcbKF{
> z5{!Fli_aWQN3lN4Lv*-m<EBE^pxF{MUQ~=tMWq-3dBm&FwE`W`huL-
> 6&DL3iZXCia
> zY&c#06$9POUB^Qr;!gP(E)*Z&)Rp`$I6gHEfOj{*#dCn{mwbY0ID6I|P|paXVfxh
> 2
> zEAR%rTj1-
> 9`Ov!~AtopBnhvZ+LEg3V0M8DN9)`5&!x$x^xcArBDYr<CZn$`40vhK@
> z>S?n&$}Q`bbqhT1)btOjK6>DT+;U5Vv)9ebN12^59vkfvSE0^=VEc?<+8dpL1siq
> (
> zg4fC3X5yb)MrL%lqwmxJ_Z;j>9IL7}^nEsYw6IuLJKmjwnYIgc;cCy(coN3oZ(-MT
> z^7|NS$!9s<;DYeVc-W3`OAs+muOGh-
> yxXN$Pxvjol}_GI*dSP|Gcm7tXhvOn>1W|A
> ziYut|Flri37QlRIZP%WBoK!Xi0FAmX0OCSzEQ-6NF#Z;N(#g|Vs)dyC64aa-&PxOj
> za*dSLH@fw4_h=ZFG+#Cx>*PdN0~8s3E?j6-*R>}PdpFbY<jW-
> Wh=rM>HFG0#u^l*w
> zVb?Go*|OR&EvK}R3tI0xh(kDqsQ{p>>pB}w22&n{ghP40u05{NcJot}korSBr2?t
> {
> z7PyyZ0(`Bp;BE+pgCJ)Fr#7<D$1IHXSyu(wsvUTyqK9CrmLOA&?HB{R&YO*;<U
> ucY
> zfy4ChXu!!Ziw4&K$ed;%$cs3<^JqWpcW_ym0=IhiDr{Z5s(qbHNIj9M=&3EzQ(I
> C$
> z%gPc9J{@g*8tx0~AJ22#Yu$z(zuPec<G!cCK-
> Io2sK2hOpl(a7t}7`KCq@*~#v>RL
> z#v@1VC)B^*MFQJ&1kU*@rj9&-
> (CYQa;ndL?$fj8t&;^K)lrv!5GP|P4^~d7y?wK~R
> zkgdYE1!Fihk(RP8?|1Q(5A}p+;24hGVSuj)cEU{!`^x<a0Q4(s2itbiTATbQ49udG
> zL9a#8Q4ObPX7#J@e}|K+E%VmF$plDL)OA+9F{7^CyKz@8kGW;s#};@hG1crp
> 5UXoX
> z&POIA>w=xQ1c3wb;*lGuk1p?{l`CtG%t$QAx(^#3ALN#sku-
> 4<pa&=0;H!kqW<g#1
> zjJghQ^m)p<V29uZS+|BAJ0kJTv1-
> b?9PFI3@O9e%vSfj#h{$Q^0eVoE#P)%h>0!7Y
> zNs)`zI+A6;C3%7fUmyha=-
> 3FNc>`x;p>`3^0?CwUYd#v1l;Z+*n9e&BwWE*B@O3PO
> z{{u4D=W|F;7C>lnI$px*NVKzurTBUzb5H7{@QI7qGgW1az5GP5_Y;e~lU|~KP!
> 2Xp
> zI$wS$=`rrUj(l)M>t*9kXpuJ6p-oVs7|NtpBz(Ow-=>jj7`bp9)Q~}iV-A}{h-}L3
> zK_kt5n`B_0F>*1oT1nlAUZqf-{NYGmB$D+AD)Orp93Hl0-
> B#DjB~{7GLLnd8R%|m$
> z(ns+c?6HP&XSJ`0hi5zM)u=-(#7#|I1J*w6IR8zj`GJ`4VVnTZIG0-bQpBY2P>1$>
> zsqECx3*CxMEA-vhe9y5MkB^P~-
> RI(5C=XzJI2VU64owx<5bqUKm;8_!fFsmQs8|$X
> z&=qPW**>Pkt}MdOy)~tTPl0;WrbS=J+G8;02lj)}o$&1f7!0Wd1N(ywM0qybLn
> ocV
> zy_Z2$BT=h-E&bH;kFB5D>l59w(NKuy;50Si+nf;iPyOmYtu-
> OGJJHvNk{#g0kEgKW
> zvXXQ(3ahI_U7C)gzU!c)z|2(7NHtPp$gUCFDxE2`8#%SY>T8>IW{u1o8HCv~MR
> TNC
> z64*K`Q6iln9eRz0$Vw65<_MVt)R?JG&LHx;XRW3K5uHgRB07WdS%}EmglmDrI
> 8W!)
> zOn(?|*yqCvqu1}of<#M#FnkXWfnTm}uyIhU<&h-
> H?z5^lGFqj7vzqqIa}FBkXq7kv
> z&c9yJgjNYc7bnn1h>b#pxX~|RF{$<8ID`)7Lo=5yko-ms-
> cYT6xWyutoQKm|u22lv
> zS|}AeQ8LW58t-vLDv*G37|T!4VgN>&3$a^)`aRl+Gq|T)OGD9YBLs!7-
> >)wE7F*}m
> zg`_SSS?HKK>7ThXQf9uys+HPa+gf7U3;pg>!^Y3RQR4B03)Dk9<xHJ1M$pgCujZ
> g(
> zzz{CY*`|mwfPYfMzY3q{qf=hY5f=SRZ0ERv=&b(t;Jg%B8l4px@VSmO6sr5M8`H
> mV
> zs~2=vm?yWQ`V^Kgq$^h8=<)ajf`hod+TwM#E-
> 1g@L`~pmdO5D^D3rpPd6X2C3L~JL
> zBx0bU5_#PK7exG5C?1YdINbneYL~=X6wkgB?1mzffrA`mf@382sumX0WkcFv
> YH@=U
> z9@tRe>vv^rxc%x#sAX7xsH60Uv5MHXwoH7UE$`J*(exi^NXUPmNc2VwDTjI
> m(rTtU
> z3A|-w-)}L*ZOxdSFEkUGLo7{={kkQLl1(U9M#iDv3pc?0g|5Eqr%u-
> 3V8g<OnvNb=
> z-
> !B5ZEO&gr0td@_$AhWyR{@2C7vyh5JBI(K3nx*HcuwV~ev&nq$xd^19V07<H
> 5=KV
> z@V10?E7k}f*L3Wr!T3!@@mIeZha$#P^?JqY(F0z7eKnr0I$Uu$`X?{H;`_(^5=U
> O)
> zxcc+xfmN|ORsC+{_=<NI&i5+@5`yAe`c5_Pi`*B#iJGN?H!JqT^i|MR@pkN{{&
> +)Q
> zys;ntGY7W-
> Fg3sW7Y!G^|8{gI<5|QTisFsv_+GrL^AsQfxfwd6xB^k60`+PhR1dla
> zToG)5i{txuCi4$I8wb7xQfM44X-
> LN#2b@D$+AQt$#2N?DUOWHJ<fzm!3HGOJvG<;1
> z@OO1FJ{FeY<L1i6-c_UUcMXzOU5lhuw;<`B#Wnc&q8}g2ZpFvSd-389q^-
> IKX{+u-
> z+NxFeCSF{PG7~@L=M@dl2u@kzMUUt3Xj)_;B*t|K{TxmXB5xsV{Q^TleKO7
> <VL~u4
> z<~{QMP$=Ve<Yj~H{2(XdcM6Qthf&_!^}o{p(e;o1$FTaNeb58J#(%u5lg85CD_
> #eC
> zWG@3>12|t4xt4)xxd0a{mclpMtjys>Ojy&G%UoO<YSTmUJu{s`rIv?%)_|*_Q
> r-NG
> z%=imy$k0{}K4w-
> MzAA%HM~}Kv>IPCbVo>eL#|ourC~`#;KB3Bw)Zk~{GU#E7aLi*y
> zVU6;+mX3*!<u|wx$57xt&uuq2uh$>KX=bjqv9_yM--
> 9>;147?UQ?lq3n}5Rh|7tBg
> znOd+z>B+9eXKKNjNa#>E;!LDv$5mGgnI>Cg`tPT+Bo^$rmFhE)LY9~cYe-
> EdW>#N#
> z%0Z^nxqqs|$qmfn&;VnKEg8Z+Iy{M3td&NCP&;s`iu-
> RcHR4<huE+BgV{nh9dWfPc
> zjZ@!0OWm*hzY!lI?6*s*gGEcQ&eOP7Sh!Ah;wr1wVy!|#9nhx?O3|!YG)l#|lC
> P9n
> zC3Zv_)gk^3&*YS#x?RF=$DoWoI1`VcOWx)rIzh0<`q)ztEZQ@B$kpOUV)9bGCf
> vjK
> zBQXKa1|{=mNauqICI}M*yU{(u9hfhm_pH}U5cGf!0rj5`2@|xifsor{br`EIi@7n1
> z$q-
> $Td7`+Q6k4k(afwBV3E#}>H7K{vRZaiFUYmlfm`gRJ?lopsKYBv<8sDexm4<{Y
> zZoUO7iV9KcRo4|Q#hR(8LX>f6K*g?H?(R&D&jx@|gS#TrKxTz3f<6$;{>p>WPP
> pA$
> zOCpgM(Y~o1>Ho^GJ}xx%8ku2F!4P)LurjP4`kI4ZHDu^vjA%WqU)rc!POC<8-
> v8a8
> z`_Q4?(X3m0)IoQ=)rf^=nm4jZ2Hh@5AA8VgNZkk-
> bOVn&8o@vp&O!GHhMVSjqkQ|<
> z#M_4op7ymugO`P~-vDPzcryBjiP-
> MOH&E}6)#Y&ZB#SiFo1~#ubT;AaZ$skPoUI`>
> zX@s-ieoT`_IQt&q>^m&ZX5^*{Q6*#dz7#tG!{_AS{WD~!E*-
> sDMl7^?<Fnsut*Iqg
> znG=!$il02c`a@Kj>0oTLBGU6A;%^RHU-
> CTKNbxrv3(Fqkka6q%BBQSkx%iN;&ceuc
> z@H`wc&Q*^+>0lQP8R{p`GqZZ_-z5iTneTw$p`lfjC)j1p`Wq)-&nza;9TLI`Q|Hrq
> z>b%CPZyUywqdu%+&rzp4>(h|BK4w-
> ytG?9C@F=zSg{(y?E4~nDU;#RO_cBVot)WL=
> zZW?*v+5FrgOs(7oEQdpjULO3NWkPmCQ9WxbUb`YEsX?qjAW>=0ev7O&R`N
> l%QO2*`
> zDLFiN+QyeeY|MRZD-
> grnl#Wivt4(}`zD59<zb=!P)xN=HU*_J96PfoF_xNafRznz*
> z2SlX@dO5tPSD({sANcn94ZYJi(^xl{Sm1%g-~E>i;g`Th&5m`2zKN<VqR-Z=56$>e
> zKZbRpHa{-
> ~eGd#S2<(tfLKlFDf3`Hu>@U;9`0c3s%TemAA7%9qPBUZ9q}Zp9(XXbH
> zO4O0%?lecKb9K&<`^sJ~M*H9tN(nDsdqR6yqtg#an|mB>zFIFOtig`1tWqyS(p
> hpa
> zWCMpfkz0yT$w!1c^)d~ywb+k)A=b$ZmecBe@KMDgQXE+6w2Qvc0*E#dtQ-
> 5Sb>nHF
> z=^CwfkZyIwHt@QG|1rl@sneZk*}xht7NG)8w5X=g*np}KuRJlXD#cHdtQKt?L;
> $O*
> z*3=?0k$Na1Y=-3vni9+BnoZtbj_!zis_TlEjcO6;b`f}ni%CIL*WC|J0#~Bvv`41;
> zT3U8Ee)Z@&mRg#{E@r>L6#@(x4j;}EBD}jaXZ4@quhI^XKkK~jhw#_lt=arF5&
> V@M
> zD@2A~jjnSfK6_1<aCAO1;?~k<IQdPYnSkH6d|CMII`p{JvA@+z0gK<HW3Pnhvi
> Z#h
> z4y{IRDMH<!5N^=?#>kl2{KjRT-
> rm!BhO6zJF$7|v*W_uTTQv?hJ8<~7Y#abqrS?4P
> zz`+LAIIsxy_lF%g@E9jMPyOz&(V6KXMxiIM#-
> R67RZEzIPKgw4!HHmyQglNJP8gD1
> z)bXP6f>DoJUo1;6hJ93BB6x^bN);aCu9OcPM_&xhaYB@GAOx9*!bJWtrrwzh
> @V>jq
> zuTGT(U#YM@w&C=BjE#44ppoY_w*ILf5rxnm%Ufx$uTB4I)nDQlfMI||rWNK
> E8>#zC
> zAg8}alOiyG04Js^0D>^m{*b#Ei3m)xt-
> cZ`851zMseNb<Ml)uG!sHa>3Ev!Aw1V?$
> z*scB|GaW=-NBDDAYJO-
> n8m!*an++K0!i%g|dHU5atygW~#W}CGTd!IX|JqcOC&#(f
> zX6qFgv;(m}Y5R*D$DL`UD2h<JbhmHitsjlpdcv%<7g(@`1K2m|IJk^&Ad4AHgp3
> pm
> zfJPqoT^~%->ts-OcIwxRj}6MeClwa)BCQxJOr9w_+U~+-
> g~?O!h@b&jhV4cW#JrXB
> z6Tx>-3yVh~Fm+)Qg=i?e)EpK-Jk8C+hV5L=elOx}8i2B05Ys-
> =X6McDrB{uC!mXe#
> zy(h0M)sy-
> $ReA;q7$=){65IL^KdF<Yi<5ffPWDV0rp&_RI!JKQV$f+l1RWK?+M0GX
> z;US=ZB1}<ho?n+x=ZV*spo7)mA{J3DMfgT2qIJX~00<^AMZDxFA|G$Su66B;V
> @<Ma
> z54P=@y$bB!x~B$Tb!~f^Rs$p8*1BhnJPG}7O8DLZ(MT2;SYT$vh$E@MbF+n#^
> ?4xW
> zXM~j4E0cbfw}T-sd?!{-c-
> e&_xtw7Ak6%VwrQS+?&+M$)n|8T?9tLu|U%e2Zh%E}Q
> z0#1gupjSX`veSL7g)9KWv=#nmI+?@e<yPR2;X`#5=a+T-
> 4Ue9uM2+ihj^ZaR0PMfe
> zYxogz$!JlVH;4?<!jpb&IG3;+@0<QiN(EFsY&=+7%8}0ax^})vuEr<MU)XQJlxsNL
> z&*clhnq<FVVXa6DsL?tNw$#1EUpgw-5tFxQx-
> ^PXtBHaF#<!+j(oql*8;Fh2W3{~U
> z#MToFbY7t(FcT{$SNe9x);y1Awqu}PZG@2qxI=()QHjK0M?kICiEI!kzQq1j*H*6
> <
> z*}sCVIB#bE!r^~4SO01u_Q_}Y@iabwbM&QFJh&p45rZ{+#`x59Z#Xye{=U;fyY;
> ;B
> z2Y^`QpQ6_nW_{@M>|M<Q_zyYvHnHve_c9zN*{`t;q|ZyM6I>n`O0>8h!7m3
> H_6iM%
> zCz-w<+VY8*HXO@KYku{p=+|+t5?B-
> e&%H}Cc=d!0a1@E0AZhoWKKA*3p9^6&jy(~v
> zAUWp@#-
> (^?ak@Nh4;`((iPbEJ%{cO*eaZz3@r;hsTK}tpk6nN41iSv(?ySl!eP*=J
> zqkgpM<F;ppqdd=1%lrJtE-yJj<3~|jG_1T@gczAuUOc9aQ92rqMdT3o`v-
> OvyXL=t
> zAl}6QB=0XOFDcMZ2MXT20k5pJkiGs6m2IExQtv)4tFUKWuFDy@MgOz*r_(?7
> dJgeh
> z)Pw)Qs5{HCQezmR$mzy1HN?vr<XB9qSh$_>S}b$I=X%MRxn@AAzg}G=1+G
> Bnb157t
> z7zz%m+rSOE<S^@1oR9cd@ZHQN`&Ex7z`ulbHw-
> 1ivCdG~qTlk5jgLCJ8CMGHV}syx
> zznX#JHo{i;7*z(qk6Q7X@ld*XHMYTi_0Pwok2x^Mu0Tq?N?9rW@nC;-
> FueqWtG|M)
> z26r^=UdlBhV|G*SVU>8Q7Pi<80a}!P?is-
> WZ}bPiu?Z^^kIS_b!V;bh`s5H3WR_RZ
> z;E31fz>+gUO@IzPC9?$1;9<r=$#eA9&h#+dcm|@o5VE)r5Y;~BTIa|mUZ?4R8k
> ?Pq
> zTcm3>{yWpacra1Y1XVT!1Y68%iX_sf`x%l0axS1gcvL8YKIFQ#Kf22;8DQf*px-=0
> zI#J+=N>b=4-7-
> a+$n=pED2nxv(fk_Xv|(BpcH@Sv|E;yD6mvX<^q?tPuo%nFm~@Bi
> z^G3ClB6kXh{|5Cob=Z0s^*`g*qtx_o`NGXi@T-ZseW-
> }L3+||~yU@%1NujNc+~I_4
> zLw-
> Kwt0CF(+3p9}PFJcsp_H_?HwH3P18~W#zP?)KbiKEE5_|zv^k#;rdz)`Vl8%8Q
> zAv+KiQWVk=t+4LFTT$!v;2Y$Ji-C$ZD!OR&kQ-
> cKzlGYOY}5c#sXCx5v{BQL8Z~BC
> z`A*aZQGTcm$#HOs4(DSy%iByo(lPyW)QrAvGxRg~EVS_He8{nwk=SarmKWaj
> Yxv3?
> z?^mA!g0V_8LuYd!cl#>IZe=-BXGvX$J`SkmkC;I@pk{60ECYrez}5sEIy9jM%kgSo
> ze*~VNYzd>P=r|J)fmp?ssF$HyG$#YTk4Nmm@=aVKTfR5-
> ap_`jp|GDQg5&3ZO7|h0
> zXF8EU$ciCM(tDd38XB;;7>(hfSK|qbYzY;ObtGLREO!wIrVTw5Or<&!b#w>L(DT
> |s
> zE?_K+{sY)Toq}q(Hbgnj%=4|xtOqx*Gc%U;P<y$;H-
> <V_%7!a1p5P0tx3tdIk`9GQ
> zE;Kc^<f)_M*!R2PIHH;dnduHkHAKE%ou{k8Vw)EnP`%fXpSlUSheP)QqmZ8;Js
> 1t~
> z1T(;lgMAZpDH4mDa*RsA>wnM9Ew<Y=qADzn?hv9z#&KbY!GFDIthsiCauwG
> #X5Lb_
> zqxIQx6p=zijxch2>}`GpKle7n?PbV~C&Z-E0kqL}N%V(2V3;f#ullVt9&94zt!B0a
> zgKoo!wO7J;BgKXA?i(4fn-
> (|ypo4ig&Wj7o`XV1oUYEE5K;9QO@++X`|Aei?VR5*8
> zH?vHb?e5%%Qwj1uQ9HgvSG6t=J_GrwO_0n5aF@|O7Jt0MS~Xho^qFE*0TC
> *{x!I$P
> zg+icS9mXCe$Np@+$9}Fm>#e1KDsbd~ISWFUZ{8#SrmVMCe#Be1>wh2%Lgz
> Q{k^jc5
> zw^sf<J1B-U;WHT^(?0t>ia06rHj}?V2B#sx`}ko<VCA>oBmdi(w^sfFJLrSdzbyk{
> z+Hb!{e#Tw232eQ;7Kt_q?#n>rzDNG+GjFZ>^TTl1GRR--
> d~N#IyhrAVS#PcUZU_At
> z;LJwP<Tvk;p9Z4LTPwfEk)Mun83>KPd5`>5-e=yL{Em20D{zvFr`p%@2-
> <QS5}wXq
> z%kT?&2ZYeu0?kN6d6*0(s(t9RuFyqd?jz_a1oic$jx!hYFm05iDXu6qK0<1>nu9P
> W
> z;*)+q6ngGJt$j6H-$WzI5#nvY1PlbV6Lr1nXE+68){Y3_fCJMAK-sJIq7jIc3B{wt
> zS3SM1q@kLs$H-
> *9{SMz2$Jew0Z?KDZTglwhdDU7s&wi7>&`iUm1Fg8&nVH&!UIWfB
> z2lb#fpbZ-Js!A3_52Jxa=AN@*%X8g-(D!E+xJI+SVj47C`71s6EQp){=jXBa!o5{C
> zj-J>AKBw;AEJ@e^-
> lNwOqMRo_{lpThH*qMyGG<cf;Z?Gpm=T)FhkR9{R|l3R7cdoS
> z^$N#&LPLf;0GG__ha$asJe0S$SvySW5AgOgHNBbmmYdBFOt|ts+J{Ssu$_Tc
> @UC^7
> z(4mi0{AuWk6Z!lVomB#%2g&|({0J%3tOK3lz<~IIa_!v)N{71f3e?8tp8@2oMG9
> Yk
> z2e0A1RIe_4NN?U)VrXz4;DcT8wIjS=ooHT`@}=TSyD+~x{GiS`kuO_W69OIDHN
> iJC
> zpnhpU$^jCc#ZO#)5_%!0pdT2hGQ5wE<!5!>VC1g&1ZJoX4n}U<%tXIhuF;_%z
> *xSk
> zSBtHb4jy-
> mOc#ac1w%L!pcjx}R9qSpF2W^*jAF)>P!O>cBe1Wfah#LaAjw*ej7rCi
> zV)$p5fl$S%8{%WxYGN`eK7o$`mDY%w;}nr&hTxIylZ9wx+Gdgg_PfZG_*g#HtJ
> f{)
> zHc`65&0htEf^EpLnZ(BVXbXV4QCH+dr)>;gXFzp#%FRWYJ>H{z7iRl2NcaRYvM>
> #N
> zfGl&9?WS~G=&9Ah$X7LHEkwniVcY!<M%Iv_wE)-t3`wyTnd|(ng1i!|!~X{-
> BG>Ii
> zt%zYzMs^}P-
> fF~y7<mqZnfNojx7^VP4XGO;{tV^LMm&falWM7q6H(f=Y!U`3)*#S3
> z(_!6mA4-c0PdWuxa60YiiwZpA!~@ryxt87kQZ9*?&4BR@-
> ak2ZetPDJ%TBDWn@0_`
> zdR2n|`c=^)Y4b~SL2mje>5YZRM-
> h}9=OQRA|AjP07#5Ue7Ad~`<t$Rbf1y(S38Kf|
> z=x9hy3T9R(EtMR45B6mW0P&O3XY@b<?t8_d2`aT>p#vhnb5s~w(0fW#gK`IS{
> FkWF
> znW07}&b4Gy<H+YUHN>04rUo7MW!uLEEvV69MjOPm@l!g-
> qQ>11WKjd#zH`;vFsj?$
> z92!znL%cc0h~270+dGH(DOsLL@DGEZlI7ch?yP9bb--
> $eJ4Y4(PDk+=mg#P~g@9Ix
> z1$nT}pP<|6+?X4ckCFfL%={+991e;w&{AAamC*-
> JCY*yUb}hpm07c?}42KM3*1+%1
> z+7Lh7Bz)ovP31$rnvXH=7&4&DdFrPP4nEP4As4_y%&gwMSLeVX@vSmo7;m
> XheV5v1
> zY6jN2k;;_kpwux@lfoE8h&zB|nRP`4b%O|J4Wa<UV*T6u3PV#vfeU>~7qiY{R$
> o{0
> z8mYi$J9w?-
> $AX^J4+OH4kjD#TXYvd{CYxp2q6>j1fFq1_H$`BiKGE+(v1<oLGW$J*
> zyMW@4zIYvkYC{XaMaf^Gl*~@^9JLiPLZ2e6+J}-
> Q;8VL^ob;*3BvZRSuF4=4J!q2g
> zz3i1y0^dudWxS*B#N4NCGPkkTH7Ec(5+q@dH=$CNY8Y2Fkk;DX)i6z+m%-o-
> O}D+i
> zHVcFCf<c=cSLGn;l|kB@Tmb-7RY8BqZf#_Tw>$)m&;{=8ed-
> uy9Znax*=&a}Fl{!x
> zgy{8Fjo*ZKIV=}RYUdy%a3KQ=i%Dv0k_H{QCX$I;nCOZwFTvsogsE4jFCh205pA
> 5W
> zgOX=Eyzy_9y*w{Rlh9FpDl9oOp`)xl`e~}n#%-?;&iq^?_Ng&aQcJ2VbppjSeJx*L
> z`oS&4^##U|>QjH@52wB@$K&J)tU2|nU5_^tkMz{gQ!p@O`6+BiwSY{OrcU6
> Vz~RC0
> zE&ayUbn5{;Z2a0@A>tvTL!8}*weW7rGK%=!ly0;S;ox2)T&+$Em9F8?4ZVwWY
> xHi!
> zNOg=}fK{nHNG?mtXMjV49Kb9>Ro*R`w4j%bF8x)mXB@R63`vNPAzqwWjE1
> a=%*M~W
> zWi#o_I^4Om75ru*%!5l>_aCsmFELO9>a#boA{dn+nE+@sdb|Xeq2cfU7CIwX
> $^-jQ
> z?PBC?$Kf^JX1X0WT42S^u0^ntv<X(y4GMHnX1T<SZBgJcJ%L*baBL`Q)DR?;O#
> y~5
> z7hp{R7NO3&ODKS7M0Ca^GVMeLmj(O`(EQzp-
> +oMO7@5>eA<EVR;^Y7{X?qxISWd|r
> zxsH++M9UMRU1<>wF|a^1gp+5ug`8=>g=17lg=mQfTlT+W&jhe|`_=I`3e8kC+
> Q3Nk
> zkW5OQC)jl)KLzYCq_tQP(Y_X^c)=yT5U$<_xyr-
> s&4}&%GdxjP0kzR1_osB*j2w^g
> z7l4}y5y5L3_uJmwxOE`EUfp+t;06q4IAR##5;NT`)W})gGN`9dt6REw-%RKpcFPo?
> zhCZ}`b+@nx^<>y|OFMzs@QdI)536SiD=6$7Y31>=Wgt3FR4k6wUU@{g3k<~5
> 7BM=;
> z#e!|jdKhjFh#q0KiZcE<Qnm95iW4!2X|i73Dx<zMYs3nCy*=BOjOHnHkE>A*T<
> 1uQ
> zN}vSkgea1(jGD|Gd!s)S-eI1}-
> m@BcQ0a&&XU))kQJJ9^hc@sbU;W@qLKTaYqOv~q
> ziy00NYsk<FfQOh_UGoLWp$GV1F)`xS5_TB<EPJs!x=z<{hgHKh*){ZXt@slN32
> O{N
> zqe)zJ4a}_m5^~h=Fls<=i1#i;2M#A_(NQC#0EZKJ2SqNcalL0)t&=Cx^>PU7VIEE
> x
> zcRh=j6@Mw0FJO4P0X=AdM>pULRs+6bmL$fH8Dg+f9mW{9xGk(9bpx1LO*0
> K3qa}F@
> zBV6wDm*9LyNjar(&e9Tg{~%WS5H6EKog#&yxi#H$Tz1`nsZ=YaZps$X@n(p}%
> xWvN
> zln~mwdvx4`G(f>TIucze<0J(K_vD|;<%xEj%DB0B-v1SrK(YXW4GYmP-
> )|_11qbX$
> zY#<s3j$L*F)FsiK*P<MR*szMh<-
> 1I+%ua=VS(Xei=XkJq#NHRgUh)j2AEe5XyMPu}
> z@;X)XP!~k;b9yrR3h=fl;lcQJOhy><l`3*)rWZmsu<i&Jp`KZ+iNTIY`J~wxrFvCH
> z@1OPK*98wE0h@C?LjBjbzV4uex|2B`BdbqH)CU0U#+S51IQ-
> $JT_su8Xrn)Yy&nS^
> zos5BuP98+J%T!CN4l6an-XR)-
> 5DhYLZTXQi_Adkg1&5Xw5Wb@uPNZO7HGT!$s5}z#
> zZlrqXhN#_KamobqfkF@?mqSDt`7k{O)<fKdR_ZUri&aaB(`2ASj9x;SYdCS8p4T0
> M
> zqDl=w6j;MJ0~~U%wPeNVw>y||8uk&C6&;qWIL*k45YL`i^^|4T194HM9(LAa1
> M7N3
> zV*Erlw1(+-i^S*@iP0evqeB)OkQg0uoT+03iP27p(ILIwPEQykF*-$Jbjz|*BnEu)
> zjKna_=mEQGi4nTY(TwZ$BETY-
> teswiSg?df23R*k<i^0~GwhoDCrX2i6S+|=a)W9$
> zVJRv-
> F=pB<xpA728==__41S5h;TSLw9k~BoFwmkS1FSI+>9NFMK#(N2>Bc7yXJ4SW
> z0EfFG6(1@+u*!>exG)#M9mmI`_+mnb=c*sUVHhF=*6ZJ#Mc)tzmEx*>^?r+
> 0)e|>S
> z>xh5=SkrxC8B^rCPlkq(G#yLUh@|PDr0KLIjp;gvq*?4B+&A<>!Rk7ZG@~I^?XI
> (d
> zHQ_|k%=lcU>;4}~8twOD%LlG6G!f0fzCa{|8P9jw#?o%HwlGR&%8E#4LqFHeR
> gT`g
> zw_<xr#U<vREf}_#Q5J`4_>ixj&=b8y2f&=C@*z;I5pN(vr5x_etS-
> Dwvm7?>y%_9r
> zM7^#@{e^x6K*78AJftR&l7jEK-
> ne<2A0sc<4Z;C@>Am0uL`|7RWA4f+Y9pkF6=26~
> ziF?#)X7#lvqpY9~r(dBkD$)n!keAvJ@$D><EkD^0>$M(rrQ~W$)(Kih(Uw{Vv5e
> cN
> z32?Rm>`qchCD%ZLFtL`2R*Y|N^K(E8Bht0(cx#2HjsrNXA5hxDM1lj}`UQ<h`ltaT
> zI`ybQ5WosltWSDlD8VDBN*t)+af+jO(1FcHaB(<8VVv>6Aljujzdh<<=J&NG9|2
> x!
> z6=a=7mF*C0*r4{Put022-VKQ4t6*kPI)gx2>Iy;T9)g-}xf7Ymf{d-SXkoF(OR+5y
> zKt^7V$*3--
> sJ}y4SeU$EVbTN7Z>;W<zXuY!TfI@*%XlS`rp8|h;fhQA>G}k;arDxM
> zGDWc4&zD))!SD~~VGQbiS7eH6a@4uis`D<Xb8GS*)I(^_jsu0url|Q2=;tlyO9cA)
> zB*irtpujhPl?azKV3z0D>Qe>axnvmtET3dV$~BR@ki}j$Ro4wPUZ}edVrKok!cK-
> 9
> z)4d75SSX!X=oS{*_BiRXCHdcAqSOz;v!ZP(N_No~i){Ebp}r+hPiu$DrvS>t9ZVE|
> zaHu)BTWsHAd@nZf^%o`2rc@*q*1c|&9gq~7ri}zB){fH79@jLTtj>k(vik8Ui%O
> +Z
> z>QfBpqxtc1)|D@*k5l2%qy7%Z0~~XML*;+Z#gldV(Y7aH9jUK;qYhFS+B&8>0
> WJ1!
> zquQGeLqdtcR1fvLutb<wyv=>E!spo!udX~=vodakBJX(G#2RK;pZe85^d8!_$D?
> x{
> znv*X3t&QI_dk2QiHi%K|$~{pdmJKm+fE7?4OdS0(4lw68Q(A_q@WK+9x9e4iB
> `{$i
> zs8aiHC2h@&YXgV+C^K1va><t5EM1y0d}Zs8$cO*pmPZaO>Hv&Aj+4@Q%X7
> *+3T8`J
> zVx1(yewCb$y)B{&bVEM^?+hyQ;8B!*34E}sx-
> Nan8=?>B%jidB{bi<zrFywwwHS7Q
> zD)qZt94)qib&EwmGEO%7rp1qO5JG2z;e|ajdlYKCX@^ArrR_;W4R?G(l5}Nufn
> 78n
> zX6*t!R|!c}CD4t#l4FPmz4xHnqpJ}nt3OGXQ#g1ZqzOhVKO|(0Y+ArDVvN!IQ5a
> *O
> zm7ywOxK>8Y4_YhZG(T`~_|>W_1rc<@jJknS-
> rxpIf!eK{gk5s4hs9rodW~UGTlVT-
> zx|!6T0`#1~n%XQvJuSOkV``WxT|EH4r=|luRuCNE5pY=`Xf?+G)Epz~6ON+a*o
> qZM
> z?wKmH9{Kq8!VNt3><ZiV!c)vb!Wq`!A?W+8kz^o4k7ERdm|4Aa9jR!T>PF7W7
> |!12
> zpQ4%86%OcCQ9TxswW)f9@eHcRk<PVqFqw1hJ<zUaRFAX~K>kA9QG?Jbl`v?
> (mI{+X
> zCh&l5GYnw(I~L&(36<&<jCi{t#%3rD5u0KEwT^~726=$_L}Cgsln^B(Y=*omlgCy
> {
> z&{Nh)787N_vKhYh$r_$>pg*_aZ+=!9-
> XexWnCCw7NPn*3a5hGpgC1fy{4dA@n;yn+
> zDD)7+Vb4MbJ)$BlureyP0^X4l4k{oh0uH7yC;}p2TC+`l>c6$=@C_2BRa>uw8=z
> Cw
> z+yI>_xB)uV5lpE$#>0$G6^F5)Q~l}XLX($1vH9>k3}FXN#C-U*f6EN(urVJBO~icI
> z9@I49uum<KmV~XA+=ez($XbQw!}(z23h)i1_J4fyVWx@940<INTn4uP-
> #%%n=s+x2
> zdoe(m@jf#_=bAKqc)3l64{xUgf<7%&c~F7~tpUEF4o;l;YPzWJZ8zRdSHt;g3uKk
> W
> z2_YLe^c+Vyi%@Sa(4@i!<40fx4nG}VfsQ`yC|$P4?RbUB8vYS_Yjax2b+!o8W=
> H)k
> zdfv5!DRwvKt8!=kHn6UrMX33i`Z<?_#rDoFnk}_~Ot{;W`Yn(=mao;6moCE=IE`R)
> z6ghN`F5dqR7K$;rHOZV;YUaE&{4G4N_=p(_#v6*@q@Hu&p#1Q+Spy2j^$Wa
> ~AuZQ0
> zq<JQA#S|15r!l<hjiz_FZ-RnalAyRime^<-h<UH2`pj4^8nIPrgG<OzWFZ|t>)n{F
> zEQHd$PXYy^qWnD=DEpcYNP%^`B}sTF9m`{6j5JTB{jtatNEec!NFi`em2r3#g9Sx
> <
> zj*{tq);OvKi(Ggl(Up>`M8hv=WeG4t23ubhavi~;j_2hJF`Rs5n?!9Ij{BkjhBD!4
> zJTy78*v$AZp}gS=cwHif6B<8KiQHu6mT2%R!#v4)9dceIFlOhpW~i}X0*j&VKpl=
> @
> z3}>zL)teArHbdLMp%o8;p;?5=57-R-XJKe;)a^JxedJ@VKKt+u2I!Ne37lteo*N}#
> z!XM|T|4(|Nw-
> _2==OfyeqkbD$*Uuu<ntHqbFv=R~1aoNXmO1d>(9^utC1RSQ6Trt8
> zqY87X@kmi{N6N?;Ek>7LMoh3o9X!&|py!nw2cyhIEvJP-
> n*OEE_UjdZ)qYI1=c)M+
> zl=kY#2G;Fo5o(R!YJci(Zpl|Hk_O#uNz)*AKRfdnG3H9ysc@@0JX}l<PIrm>j=U8!
> zy<^b;H8MiQ_+jIEtVSA%k&?y0!f(R|gNg{(mSowEC~ysba{og9G<#ICDdjGfBe
> G}C
> zu;~m3nOgPw!XlHf$ux*Hn@w%t&?cKrZ@9)HlR02pJUouoSXp#A`8OwyRZv+
> 0nr!}+
> z?SYvP&dNp%{dc~4Y`z0A8(1SI{JZOF8?i(_`L_sqB=3VeFkaL`WX1)@9Nk%G^SS
> EA
> zoK~+HyGHgJMlu}Hk;!v;0Bd^Mh{yvH+G)hOw3jFR82CxvGE7^rH^bz`_AL6yCB
> g%0
> z8;Ab%DGj65|H2ccy7;?8l)F-
> &S6^k?aOAb&Ph<Wdgrb&dVqBMH&4SBdvcw32J+XMG
> zVWJAymCR*<m=KB~gp)k+LU#8ieho_f>q{c8kIh)_!HJkmGxb=0ewH**Fj=n0
> vUoaD
> zmWgjJ97U|KPxe?At*YULQ}hDIVp1#<&sPsYRM}(M2G+bFWBEnd<jU13O=u
> N;U{~b!
> z<i{G#T{)w<3(lpPm2hS>zc$lqrdWJBITpE##*9L%V`hk(@m(sDoplz)*l;V4zJD5N
> ze)PW#Vf?T}A{c2l`vmi&lz8z`OFZiQ_&>vb{Vo|C_u-hGqU?!pg0!;48I;swAl*(`
> zCid$`WWQ~8iUkl_A7Q_KB)bN&Uw;6xW7lBp*HVL6qt12Kuo+_M6F9$c(;=p9
> 9e6Cm
> ze$*QV)Rh+t>rv#>hTRIW13kql``&*WK{7|MVZUzXd8ZBg)6$437%JF$8ymJXLT
> pi?
> zD}=D(q9|7%VsbgU4V&(f-
> AA!uU!7gI*sx!&a}ZElyF*g9SfTo4e{H(xR>&&L3Po=-
> ztO;SmKBMJaAdcBtB6S-
> TBG;R=XmiU#N@$0T4>M##+lYV**XERyf_@Uol{v|F@l=;k
> zZI;Glvt%=*Doxs7q!^{Qj{g0j#_Vdd>@eLSCZ=ygeA)6XW6Tz+h>7Vf*?b#KP91
> p)
> zjmNwK^{ffTpu?i}BMFN|Yln=7VE^Kn?2?s^deJAlWPP-
> CaLFFo&^e9TBCq~+dp1`i
> zne{#OML8PUasd2Kv1hlKl|x2wRH<_41g&B1uxGd1vSYsN^$lZQW@N{Q+q3=I
> ^@u%t
> zI|PJXk1T6MMoB#)K~l2QHub!1BuJ;Y&%vS%_c?9Rh7JoBZRoH%MsS~_MH?G
> nI-s^A
> z)<#BxbczJ=eA<>EvS<_u(qT!E5pCMd7_<&qD>m(SAtr3DwGH4QX^O~^GSd{
> wndCS$
> z1uK)I+q8W+qM+r-
> h&JtlYz)MveUD%;%%&|Eh&1^|t(IhB(|*_~O>lbyqzP==l^-ol
> zs2Y011??<M8NniqJ)H8u&b8`|Ks^@yel94L`&ez*4rbfCcU+QX*#4w4$6?y0<m
> p(l
> zS|m+}mOS7NEqOlNxV=-<-
> u8SclIL8ATe}ZsWtCw^kvuof$;<_*|M!w7JGg_jzp?bq
> zS@!PZM1qKXYU=BS9osf}x9n|x`U7(eSRbvjk1vS_zd5F2&V!k|m}ntN)U~Rsc#
> Ol>
> z0~VFb;q(dg#3qy%-N8?Za-{=d=cCfl)RRSr710yDS$r7C%hhinCG6pC!-
> sk(MtG~M
> zDw-
> |y+}m7>viXlVd>c5#B_;Xoaa@#R?JB#u=BES?ei9F(OB?0DqfgJ(79JY%ausyq
> zVZ&=YM4h%)_S_|Vn`<0+Ocp$tlAH`Y_BOx3it*1n2iCmBPUz9;+xbPMPdtBdt
> oeDo
> z_HIk?i-U$v^+nD55RDM$o1#0UH1EUT#SiZ`fsLliR-
> 9onL=P=rb&_}6Mk(W!HT|Wy
> zETYF7YrYVLA*Q-~OJxbB#1dOs$wv7Uw7jo8+);dz&$aWAJC-
> 1x@s0e9ZLGv+bO%32
> zc^{gJ%Hz%aF;w2XY3v*{Z2)q?l}HdfaZ)k3A)Xy*0KG(VpokRcl*;K0(<Py6l|*NT
> z>u5h;z_pLPX<hWS6Io2VVu@)eIlhsf(La~P^urGREWQs%migd)aa|{H87fa~#}~
> so
> zyza)1IR!_({%9M-cz<dNB0fa-
> VYct*HLd+kudha}gn_6B43vBQ$*VH8Mh~6SFg1aT
> z0@TaTkmKMOFCJcvSPTFhKe1L&Tq!9y?*-
> MJZ;UqWPRz@PYnVzNf#;ZsU6y<g&!%gl
> zhtFx4l)&_^ZnFv&Rcj+QctQgD0(S6ZweCuutcEr=`F$xuSR<C0Diq;o^v_qsHp;^e
> zexB!jh`O?PGk<_8gPJNzs6q#kX!@=OoLHmZFb<0fA$Su=h7eGs_9yp&HUNT
> wAbR-I
> z4Y&>ok8|^*hc0Y5N%#`Pg&gl6>jDu8Pg+{=RSi(A8u$xf#wQ;e_%nu9QOftH=3
> Bsv
> z81xFjxLxN9k!gSx6z{<qb5nZ*!v|@A<+ONffa`Ef-@DfyP09P9?LoJ)hs)T*rePjw
> zSTcf}X-
> wzDn#)0$c!HnN<Yh7au!BE8<9*1F4DpTp;eByUXdD@;c^bY@aMOWGyo8Gh
> zd8-
> WMviP1o`Q&C{5e(qxSUS)+P!_os9mt<rx4drS<9OcFyb+)9OlVc7LqjD3^kh6_
> zd^!XykZ5iJoL_xq4ba?;<6PtpeaLLw;&_6^E{-J#li0{lOvdI!Wb)xr7>q<JUn3Q3
> z-
> T;8;4t^q#Ts$E^p{~aDYZLs8N6yn^2vaa+isAF_6sBY}n6X?UXT~=&1N7(gmX^%k
> zpXPnFV%PpOmK%l$smW&Cjs!d&hVkS-
> jsazT{bv{=S{;Q&7;cc*+gye!@NX3cBm62i
> z@@HHUW6kUEoPe*tx&VITG7hmq?~lGy=3To6Tt`(*gJ-
> iegwCjgvBbm3VFWJA>lVW_
> zZS&Pq7{VL~h@5STT*|(9atRL=G&7@@_rafqm_^X{<FpS#B`}pm$b$yrPD!9sP
> p6>u
> z1O~^($1afA?&t@Rhg4;3T#Kx6sWhHoJLsGw4=8z3Twa6U@nd{EL0Aq-
> c}VTkZ!3a>
> z`wx?TFBY0!o%T&lh33_OSARW;5z)QPTR;gYi$KYVNTxid#OE^}!P0z+ZCruR=nj5
> z
> zGJG1c9(wSN=oxEL{+*s&t;tYBUasa|>X?*mcs&`i6m_3$sWBPOMA`gDq8|4pP
> RdM4
> z9tWOG9>lC`hQ@L6jYNNOTqelHv3zKa5=@D2<SY^!Z<sy#Q{*vMQ(H4$Ynho
> RS=PQ9
> zjCRKm*v<fW^vR>)qXR8-r7FZlZ-SLQeFyDb+Ks#zn*nB6Nzuy({C);`R$dnR6{&I;
> zDTLFN9ZfrL0!{1H?__fg3E9JwKN0w{^~mVyDCBz{lwnCM0_P2)JK?y4si7o3I~~
> 7r
> zFxGr8o0f>+Q^r5s)8W9`2{TrQ-}{OPc1)k!@q5sZ04)H+<t5v3zA2zSbEP;f4Ru6!
> zPvj_CjT$0nNyAQKS-*sXH^wZ&ZBA&D498?LAk?K<D%^o6m>k#4-B8AS-
> ;{g^XtH@X
> zvia37uCVLD79DPN5dY`mT0}~EX&~l2`^+B#+5GKPOJpP`U`GeIXj={BJ9G}b3@p
> `P
> zJ=_JdK$>7h^fcN9ZV>+D^I1&wr7;C*DZ3gEkyBr;#Mfd5gOUu<)_UA)^H;1x(M
> hh<
> zBxGP|c55KkIHR)*A(=@b*J>6ca^vJpX2jfz>S7xg;WPPt=0=uxIQIdL^76g^7!LQ
> 4
> zt|fY)3~?GMb!s9L1^8JF{M1)t&6#3T6Q#nKeuukMvfs`!C7dE9d|pFkgPbe{%+;
> @|
> z-
> f$L9;`Y?wVu>AWfos)gRva7M!Ma^br^OR|c>nFVv`+7}64xOK5o7S_=s#SZDzGt
> m
> zt>JATp<2V4LRJ!{;gtABmV$UM_>A_rV)8Sle_EpqjNwY*esWBD?_)IPjwxNl7(s
> ;R
> z_Im;DN;Gf7jLjLPuEX*j?`Yn)YFxaT6^@Y_A`Gd`3ltNqzFrp;P`^41CT*=m6e6Og
> zAp{<P%v`V5Rbta91?i?CR1wl=tc2L%L&3(U@fnk647T+NCOS?oB=4XE6AUZ3S
> M7E%
> zJy`}^7CBoY4~#)}96^sBs^moy`fwvB(><<AIQPlf4eZFfT;ArlKqb@tR||jQcjUO2
> z&IK(N!_6CH5i(vNFnN*VS}Np?&wf)X1kR5Xzg#A7g4P?XqAPse74WZXUVwH8
> SW&~o
> zgh)~d6FAf+_@X{sriOqzmJ`l*h$WE-_61Zq#xGt8mw6)PQjB}VVk%XOE{5)+-
> sTs8
> z4vFFY%6IW3)1IGrz!k1}9v>3&xsjhdBOnjW`&Kqm08N6Uy)1$z;K5!5#W%79EP
> }Ys
> z@vGSV$O!{~^IR6OgP*QdnCduH@L%eJ?9GSHB~A{wDk#CS3KGl}ljmfZc}~e9
> 0>j}#
> zo=r9l(>tvd<w6ZNhJ0pogV;+b$q!=w5IqL8WG0xvX`-iIeNhzNxWc#xv~VTM-
> $VQL
> zl(um?va!h@e1X#<f5q!s=>IthzhRP3T;ZyB&2cTq-
> }mr$THYMj7xDK1{&wImoj=EQ
> z80m$0{u{n~@pn9)C*sdlSeRF+|K%4J6c)Ns);WOhW*)r%6TT1P&*lEme|dPDp
> MfaY
> z@WW%~xGpM~<NC6Dj%%f7j_VJ2ejRC7;QL1W{z>5+*K7E`4}V_)%op*!9)Dj
> NgSy7$
> zjdS6@%)fj-7L0T2l)`bxi~`EzM)9ZT*wN$0jTu)oZroU7?<tDUEs7qf;jk)-KHzaR
> zc%g5ABQHHOis6}YAvOhmL@35$?N`5NKVX{cXo8<Aq!vbH@m`m32Ck4Pj*rL
> c4M{P%
> z(#S5~*x-tqTUVY&Z+q%9bb(+u@EfL-
> lIX=l*l6UZevvUFYyB>fu@Nk`5G;wqr=IzM
> z;OBrK_Aug(&N>3{MbkRwBi30&+}n1<uf~|#5dD=~GU(l<+A{UVMVODKpTp
> @_>w?3V
> zs^3Zs!Xk;V^^J_aINCQo<3B{r$A|k5rKfYIvlUt5KePz7*@~AnU|#Xf2&Jib5rxN
> N
> zl{ynlpnh;Zbu85Nz+!HB3Uv*LrxNE(%dz7t*)@r$(BTUmHQB(rCKjR2&eZfrlm$(l
> z(^JS}c?uyAKFkQlK?qcn9t6oTlo2Sh<S$xi&<_Ue1AE|Ll1|~6FmQAo-2$lCl?ag}
> zZZ<2h-$X1ooO`NjJwrTqsQ5*SunsK0y!s;zpKvuTNislN(2fHB@4Si*C{t7$kh3hF
> zhChqN-f0f~luEDb8@bH;9P7Y8#M^-
> o@*ekPeH1@XJX*b^M4#>Chx62eDn~Ebz@d_d
> zEPjZdXYoU74yd@dMjW-
> IN3>fPyN#<fl6)_}xhO{GSf}_Lj$6aq&od3w3u_l79D3pm
> zVB0@9R&`H%0ve*wf-
> v;4^NWf0PZ<K*^tJN~#A_A=?r*zxAun!&;J`(3JLCHc_EaBP
> z=BZA5*K7gJnhtR#ykv58)&@lJL~!G47vkEw=pVh+M{d5Q!E^I1HzkjK6l<})1!!=?
> z1l$`JeWxIL$g|{}gU=3?Z+yIDj%!1F@5_7}O}dv9MSBVg+Ms55?s!pOZQ*;Uv8
> M97
> z1!=wb^Wewn`_~_{Zq)kA^VWSfZ~f)@D0kgw^P_tTqI;$EcDr=Qej8Sx@}hh4q
> kEye
> z@htgI8)}1wiSEfGhI{k)cAfneWyDeEa{S$kzYzXz#ou-K^W$$W{^GS?>5bJs(u;3}
> zZ-
> wtZeD~qIAK(4>9>DhizSH<l<9iU_g9&$ntWeNjkT&Fq53$kD<F5sO?JU~|I_`UQ
> z16%BT)~z=wz%h#=AcqB;h@3x|STSSJbV7Ni6UP4Y;Io6MxAFwkf(0`u-
> 7{g1i|sXi
> za!B_{1^eVeyaEJ)H`L-
> egue~=TYq`M>HF7xwjlafq2AwwdOvg&P23Djrmy~*AN`y3
> z!a4`!1_vBkfEJoQ`)fh;Z|qs`nuTC(M-G(T3mp3JH-NuE{JDW(5&lZ>cNYFY>xrQC
> zM0}UxyA<Cg_%6YBF}{oOU4-
> u<e0%Wi!M7XV?(DwNG^#;)bMbc_{_bMgR^MD+017zz
> zLVlyQj($Mf0Hf2g`i_oR=AVqmdivTT*fll;i{ht}KjH<8o{?{a55Sd?cMrxtKRDEL
> z1El0GPu2<I>#l#uT|U%f71#bzzm0tK;IgGf@rzhRtN}Wk^rudo18oRb6%_QCtO
> M#Q
> z92(^;j_Kk6?sP4}bg?KtOR&0WFjl=NCYauGa~4+m{zsIKjYC>a6QK+%T7@P0ux
> hzb
> zLUop*#VjBr|37a2f!}b|^U3qSaFqN;K6>JFd9VamL`>C^I9^{GP`|@`OgX&EZTE
> qp
> z=S16L)Yn=%N1K)q?4fEWv;icYoP!td0_a6}LT}M#p}kKfe9ClnkS@LY{GU4GFgga
> 8
> z)!HxdEPkt+U$DtSzj&(Zid6jge-3f3;9OZ0pDo8=aHTc8Y|ShYuP51Y$Z041r!>hN
> z^fvfUpWoEzIUSO{p`_*KCxOl3k(}3p-
> >&3NeAuS1Zr90n>$=#w9y$2~M8UiYp2>1%
> z*XW1YLa>(plC$iw+XrHIr>(YkVUpHu-
> |LeD%0N>r&Nx%lp)P>wGrnOpa>FMo;cEwD
> zdJt|FLGrNvKn4~|-
> DBiLd(6ad>WUQ@zNB5ll#XZ{<WccE*Yun3AmEk9VFQAq;n4if
> zV(7GRTTM+lTQ1E{ElWihfv<=RAXJyIEAiQSh86eY_-szcVCq}o5(f&)n!Vh`Q)ui?
> zoJx8Swnse}_{sZuLnO9ZDbp@=T5>V$=O@PREF0>PdM$)CzO?6|u=w2K`3vLs
> 7G28|
> zaYy36T`_$_^vDn{B>u-{?l_@MD84#T^5Tqn8z9RzG!|CR^{gx;#Hb-
> O;Dh*YSxzGk
> zsYAO3&0Oi_vGZdWS1&KR&t3igvO=|$rPK}Hl5oFxbHd#uC`kQiH`WB6*fHwsG
> tnvQ
> zxR8up?N*QAS8S^+EBD;&ps!j+u+@A4<?cApW`+k}HEx`1{JS*ordO+4C4-
> c|Q2Cgl
> z!BZ`THH=pm@%Pp4m{f(LRk>ZFL?!h?D&bmOZ+s_zHoSZDP09D32KEcxaF92s
> h)k67
> zqkY&!c(Bp#SDWB!9j}{;!BURyEJOEjoLkQH+MAqkYj42LTuma6?JhT=O>2;bunr
> b0
> zIm@3Joi!D~5fM#Bx;Za2lM6*Im3UM0T)AQf>ghrPk+)J4tkbZ|8*tw<ld<;(KbN
> {z
> zPP2T`)uqsS%VHZU|H0~DX(JUb;-
> *w;9NJ5Dz4<tztr74xGpd6<>csuqD4p2(*c?Kr
> z<;Uli!1@(!1e00`xIV2Mj2lqr{DYOcA-Hf{5v+qSZsXis#r9YG%DroArA<5?YTa1X
> z4<eS=tAON#XQ6g<XTG<v%;P>ISVF2;&9aujLlbI27t7-qI&TFExRSr%$Lsj0+ShO%
> zbu25V;<M+zDWTs$X3If4Oil}M4+*gJt1qJty&<9Uxt&GG`Hema#6HH9np%;10
> 3k-?
> zm^HLLmqTcBi;J-
> 146d2W0NI#9UoM!Xrdte?zy&>E1Zg)kR=D3putD1yg9+9UE5|XY
> zK@6vTG(DjvH7F_;cM5y%GL(_!U5xUI5Q$V%1=dy^X=My;Zs#V5x!uFkX%L)P
> ?dz3y
> z4260~Jj1cWQ_0&|x-
> bIboiD@>%kZv4*&4mfuzr``F@u0daHet#ohV|=DVK~Cu&@MT
> z)rWG}wIARePw1@tG;W{2prr?kG)8>sjHdIKoUVJSt~0UVSaj8Q4w|l_)j_(dja?-
> I
> z9HQA7{q<Qu@UBz_bG6t7(idY@V*vRvI?4FU$p!e(Ow|dpbs>jdT<F1Oc>;}2P
> 9yMH
> zQfx6ydSK+p7172rSL6~{#;Sv5D@P}fC5W3KwmhI!q6_6}d0-7-
> )C~@FCA;|XrZ5`L
> zyUO+-WZ35*Lx+P5!Hz`jahQI;^`0REjmtuY-6X?q{6d>|!}(Ieskwz!alH;t;$~=}
> zH+(iG?$pB60=A=}LIe(nm&wD$Ksnh+dQ5vnxl?DQ&PbiE``O~V4iF7NX3^|&M
> B25%
> zdxTY?%&QkX-RujP_5^uoH8Y`I9r6z<2H5a8trRiT6^=T>(+M2uya`(`QLXt585ZJw
> zRAI(PHq7j>BsDb-
> a*Q|dz8kDpB2s7SJS4YcU`NgXjbXQgWQE<1y%wtBGw%O9OYg<S
> zAumfjTlxUt!b6a#NFOGr-
> h=LKX&m>PpiMn^vc>CQ>et9nAwVORXU`||aQ=bxKH6~R
> zTrwRl>98*g39(}BW7+`o<;*3dkeRQ_qqC;Td;-
> PRAVL7kd=kz>m|}Y>;d{^^cPe2r
> z20p}qJaJ->lDy3=NHr6Ka1O2`1KF`;jQPr<jT1Q)=mg0AiSfF!dNsLUdcZnN&2cZs
> zD1!sl!HJOz$WFB7=y5`kIMJ`Jk~~?{07FS(SAoNoxq_A>ZfL?hnFcW37=g!oOUlJ
> T
> z9^KZTEJk+S2ne-
> 2{IJ4FYn=6bhUsgfW^b(sqZljC7Go2Q5V52*n?vnA1sDbE%4toF
> zz5TGl-
> )9N1UM;}XUxf^Q<rOs(I5rb1oO*r}2$7eu+<{<kaF^t0?7@Da$V@Z6pivKa
> zMB~Qw<V1{6EmOs<1`$6+{wf1l#8}osmOjb>^%@qCnC`$aBaOe!iw;U~?hOB
> U)WHkr
> zIVi`|KH@&A`=2Kyml!4{y7PdX9<Lm!%ON!H3D<<4-
> @q{!A~%KeRG(H>BER?njMjUG
> zAL1pL2`z?I;XC*Nd54wYX;{ACzQJRJoHQBm{s*z0d-
> P(v5gGQbVW$XZLp%<K&@@!v
> z)Y6Gm{)k*jHhq*on|2Wtq%wDeRRS=+j&Gtb@r`TMq)>?H@}d=&;H^FoHxH
> xiBRpIt
> zB#XE*>-
> h9oFIp$(#FJ+>?0Q%mdAH53m4;HG%Cj(k!}^ROuMWrJ)2vTKpF0pfAAE~Z
> zo8Z-
> H;s0RQm5lNA(d|=YV<3Ei1K^5b0NA}%IRK^(11JuJVF9qK7&Qz4cmLs%c^lx5
> zU(3azG!Xu@1K_nBfIt|2Np|*c=e&*XDhq_qaR59x44^y^u5bX{J`7-
> LAdH2sT}ACM
> zfN6m+-
> PbHKo<0l!7g(O>0LUK(aA6?)DF?uTujUeAVjv8bv8!ku1~5Gku5|!>a~QzP
> zK-
> lL1SUC)!CJ@FgwRROZ4FjkRgg@&5m^ln!ZXi6@0dUGNfO&!N6%K&Ih{KZ2Z~j
> 0S
> zr_XF0-
> W~?9AP~OF0njoG;JQF~o&(^?VE{J<!gUUSWy1h&4TNd<wR$r+3}8_pe2oL(
> z!eIcRKo|>fyM*J10o)Y`&u{>|_hc>|?hS+y^wBP1|1f|^AYAPL*g6bgc_2K~0r1
> E$
> zfE9u8EC;|Ba{!ult%j5cgfDTxTsaJ8t-xIBfH`v*%sPRoalqscgLznBE_1;A_K9qo
> zH0|0TFtZ&nFAsxxTwq}3uu1pCFqo$VW~u{b$uO8r0&}(l=IUWEPYcXsP83Fdo-
> +()
> zi@=mQV2&9E^BiG91@Pi<fc<V`Zu7Sa*s&HEcD0b$EjeH)L0^VB!h%h&*JxrZO
> n!iM
> z7iKlgDY&9leGV2ROncnGL5+y@Y`vX;`3o94RbwYGOL4vWl%2pV@X48ECol^%k
> Ynux
> zWP!%%pBFeQDf6p7JApaM1M1gy0xOw{`yK2ARx-
> `6Ua}LIr81zNvlE!*!g}?joxm(u
> z<UMF7Fw69SYOoWSWhU<bv=f-
> 6#;@kv3CvO(P_yj>W|>>B&bJeoWu9M^*$K?z4=Asl
> zz$^>u)sgd^&A-
> mC{$eLE%Z&lmZ6`3xt@Y}^?F81c$gf_u6PP80^@^RqEO*tbr|bk~
> zx!12AvJ;pk5>U(R1ZG)YuWq*!m}P}uEwB@i<<Zq-J5^(+A=f&Ndc-
> fX(~xluN4Z~>
> z+G)%yqguJ`H0I?fu2=oC7Bd{ThNIT6y6rUPl~JnN>@?=(sH|5n*lDcyY03MvoyN
> Q}
> z>eRz_8uN0L)vM(?Eu+ti_Dx)Pt<iy4D<i6Q=`@TSTpC92$A$xeR&YHvP9d&s#d
> <G%
> zdua8eTw8`Kv9NsXOm;2yCR(Lp7M39lF%Gb;+fmF*MJ%ha_u#YPFIidL>f$nHg
> p;Dy
> z0F`o`2`$N+pAuHl>(kR%3|xq~QDS+~<r9GfmvG_6OiBHdO-
> Wj#b*3pPrc2_$hAQdH
> z&T{vm84hzVui3stJS2PlVW>d|ak)5y*{Ovvk;)vcs5M6uaW!|?>j1cD7=XtgE_M
> Kv
> zH~}J9#q{DnPt=Z0f<f~gF;ELP0L@PQi>p>Dw*e3PLA^RxXGxuHbyKi+^V9)2M
> U!ap
> z3Dfvkk8MY9d~7A38KnedLoR54uw8?a9mZ|`OieIFn3Xe>jx2~>t=Hn_R$s2mb
> 8q!!
> znhUr3*0TFuA@*&kM=#gsohWReU2@q|Efm?V$V}M;i1@ab|5MR&awSvi)j
> Q`(hqIf&
> z(Ja%iey-D)7i!5zSub<c^~EF;A>l|Sz*Vic+?>7j7X^mBAJSK^+=(o>fh3x)gtru~
> zRj0@3j8%w)h(}K}S&7#SbBwd?P&Rl{7h5pZa5LnHfXbd5ul2L@)?rha@hwG}&
> ~?27
> zBL@9qU@-
> Ee;(|?PzRAa3Kfv8nJ(hHi6zhf}s!(#8G@OmBcUMavM#gK>a9(=dyhdAR
> zd#VfBt@4`S(AIrVzt-A(TOT3gxfkRjy`T@U*o6bR)EdYfLw7?R8=fD!?%(Z!{JP$7
> zne!tJW*|>+1MYeY&aKu?G-HigXIBG9txx&YsTvzSY7bDIT-
> R^i`))+XH#qCwo+;^K
> zt0XNrIBHqan-vy2AljySP5;v6#zalsYfA&~wz<=xCbG7GxT0hic4Q1ZXst<}NMtP}
> z0Dv7CbV4>j!!Q8s$e_5j0Tv7cz>W;Z`)q)!VF1{zlsW*88wP+)nco5M?!&oAVpE0
> _
> zhjtYm!vL@;J6QnqLg@R$0L~7C!Q3c81AJu|z&U~N0tdj|!vHD*;h+Ox-
> Y@{{`=A-L
> ztEd<TaBd)ctpi~6Fo5#{Vd$dl5|Z&;I(#Y+hQ-
> |mXmbMKf)iYLrFd72mZfB#C(d><
> z&pP`TFAIA>|I)0)u-
> 9NWT8|Zvw4#WVSLUf#L>e}#gU{OX2nVPTr$h9n>nNX4ar`oO
> zY&If1VZN0V6m_Nc`0BT$E-
> V0$y1f~xE5p)0My713+rr^$q%NOxrLMe()Sbw&>I&@!
> zNT@|7VD;8`wl||B`8ZOS_|~htrdpJu)TJc$tLt<cTZKS8kFs7$F5Ezzk-F+AQulw3
> zye&+=Z4jSZR6X`WOKeh%;u6G&sGvoYU0+;1VY>Ai?c~ZnXkHV#q`GjX^_oH#
> XY4+0
> zUK6^sdTfpLn&73l&(2Z!#OevP)@y=;(bBS1qTW3|yR5o!uJxLQmj%?@<~5<qt
> H;i>
> zUK6|=>tFra2z;TpvCTU4(Nh;121Ccej@qLZAWjRvZ$wBM1l<*N9K0ONyg=i-
> iKl>N
> z!l<QHQ2)Ym7k95meSL%AEnFXL(rVXZL-
> DLmEb#Rw=2gle#aF@)ga#kyEJB~~U3md@
> z+X-YXEbK(p=v_-
> yFh;Q)!%CxTT%0ZK8w1j#yoe^wLDjt{AKU(JnS#5)=uJosJ%yq}
> ztNBrij|_Tr{HBv_cSUfp;&n*NZodlMO96sTzQsih;ELW|uMVc983ok;b`P&)ZFVI
> s
> zkJ**5y(86<Z`E>Wh$ZV<63$wZr^3o6RiWLcJy<m0Kq-
> 6TThN%pYL&BSk^Y3==7r*E
> z;I^i9S<8G_|3<2H|E^%EAJM-
> >OE0wha=Kr={pZ{c4*At?o#^P`9ih#nQFb3UmSp!a
> zSDGKv$3@;KL){H0KQ|`2kJB5`#~bkBKyf7UN55z~`GF%D@{hBy9=Vghmt9Mx
> vzE|^
> zoqVcQONpbF=aLRqN>2Q+PTm1+c~&QX%>JF0JANOZq5F3e3;c-
> w%^tspRc`lU{Qf~F
> zI=c6jj3}_eUqcj-
> RcMAAh%ab@+Tg$JvaCexzrUI(s}`~V$7OdggW0@(Ig@3;+PvP8
> z$*}-Ag8eYN$JafL-l<nt8Tep-qBb9kaEKk0wFU12>Qm+&&d}kSJ1d{w)E+-
> PUw_k1
> z&RsADgy^J@VcmdwO(x8YZ0h8alCr4_1JugaEk+Z_L0O%s@$KaGq70p~h1bte
> 1%0ep
> zM0c!c10+`$YZb{={#9^w+f(3bLJY)<Ho(?GnFZxq#V)WOB-
> 9V?G#vfh2b!aC#hRM=
> zC*6B>-MY!$(j7RF-W^-e1PfY-QN0{>EN2~7=S&3RIBJ7UOMgWhD-
> 5W4RwZ*xB@~#y
> z{9{ff$ucl?rlF3x0V9~Sl)>4B(qpyjrvr<gY%EHNg`Pt2p3SS^zNx=rKQZ#FJvh@M
> z5_-pB-Bh-}-e3{z);-_ttR#d=exF@Q>ywU3IDB&|xy`ENI!7gaf6z^}D@jh`_~jY@
> z?wGJFD*97)Mfb8Ia_Cb?AKq_=zF-
> >De@HimbY5%farB$;g{W^(#h<gQC}S0vaMx@?
> z`tYVaVO5bZRghk%<u=7?#nUJQRs1Epinb?AEBJbNE2^w2&T+KjmEIi2Fx<V4;}
> KQ#
> zXIF7At6(emdUz{3LWWR#)0tks!Bk;)h}8-
> XYg7Se6eoX|TCI>#KWq%$ZB?<zR3Q=C
> zINes^zz8C><xIEQevkQf?P20}l=+sfEp*dx9tVIj=3bzNi9c(OHu9Zb8kV75U(cgv
> zj{t4<>x3R2&QukTkVDFk_T6Y{=D53ueCADfJ?b84n|W0y54zy0&Mvv7`Lxj7ug
> Qkt
> zZp_UhDd2(eY$0Wt*)RxLjT)ctI6`3qhboa<icmHGWVgZ8x*LdLL)oK#iwb#x<35
> N_
> zTJUqu@)YTczv!rVT6V=a%TuGC%5zj~1M7-egxWi3DsHtZzFjJAP5MP{d-
> mw+d8;pu
> z5{ZWoJWqNdbiqOYhr9QIkF%)u|2Jt$LrJ@#q!6J(D@Fbkq}X1e2DG#dwn#7u1
> d5=b
> zmKsV`gbftzpOo!Nmu0njiQ*Nt2wqVU>lI7U7E`RWMXm<y)vCRkmU^9Kqekt
> O0D=78
> zpEJ+%?6YY=^!NL{e&5%xeeILy&zYGsXU?2CbLPyMkH(7sW>s0e+2AwVy)IsS1
> ni4f
> z7H)o6yrxW6@BhKDoon1&cuKQQd;mKpiW&(a#c3D2fZ}`!#RnwH{{6Ye`=xSf-
> Pw#K
> z$&WuOEvc=Rqf8p_>s)bPB6S$o6H;Rf&y%vSp06Ti5Lo%i^ol37|9zXU&8K6v`R
> %B(
> z+5k4&y%U``+87l9``RcAcZ&&rT2W)8)u!HRv#BtO+Tet2ig$DXIx#k7Bs;!CZz#J2
> z!ANOiicX@)oAZFVOC*U%AZq*ti+8izOcHj1V;q|xL(z@62w1#<f(6&NXq(x#+Q
> L@@
> zRJJG)IAD!yan0Wk!x}6mZN-gOK{Jj{sUWlI=33P3N%C-
> vBu~P`5n~5s6<dmg1YxdM
> zd%K<d6<GIpHd7s5F8y{I6l%z804kg%)f_*^j#I2gQ%ME?(Z17|AvbYYXs>%53%
> gE6
> z`8L%mNEkBg+aXn?Izp*#8t1-
> @M(IN_6+gN?bdTPlmY(gawLey^|Aj}RYU!MBjzN5%
> zWe`NeihzAfD+{;IBsnd;0Sv6A-(+}gDB}M9K=|%xd-s4p=VP264)P~i-KUZ7lH{Xu
> z%6cHz^Z;9dvRqd@aAWeebwtg{wLL%tk|!^*2qa7SBidqUTt0y&W5wW*Rk&
> E*FYb{G
> zokTZmM6U>g*EWCAdg>W4U?`zRmDd=;O?Mwb07bkV0k_X2b-S`~Uo@#-
> hojI*hE?Pz
> z%wingPExzv3w%NMD6rpCoe=DVCTzdVqj_J5rrM2)+!u6P8YV#VtuZvOuqkFF
> NHK*@
> zcRP?55t<Qj49(}BGkFG@tH+5Fk?haSsYjNhYfox*tpT2w83^dr3Qy6s_ArrCV#3I
> |
> z-tcT&UkbC@{RJcEoEV-D*(5c>lQ65(-Q+l)5wOQoS-
> 5vac>a>5n^?qXY$Ulh_UoYA
> zIfZu;J-=-
> rLN9D~kLTSXo>Fb7?A@VdnS(Dpp6AE#tSQIS3D0Fntcacwa176{{w<{E
> z8A77u9?o70HTwnY+FM*@fajrr$e%8`X07mPlad@YfE`d&-
> Rv?({CXsfyv}}2EF)^4
> zp5;%;eo~Lb$slz4WI5*hU6*wV&{)sIv+Ulj*F(9dx(p-Lt!`Rb&a26)kT$xMyB15`
> zKm@*INQZb_WCho!-|F$0r^iNi@jhNL+3-PfgO7s4)#oZLetf+ihSgAuF3s-
> VvYekM
> z{zc(WT#UhLDuRw%bDTKsuCN6q1t{^ZaFGwy!na^H)`I7IEg=ZXBKPX)ZX=Q?Y
> QYHD
> zx1h3czdI1N;75dn`C9u%5!pD<2y4!#s4g<FFh4}II%Kr!qlD(2A)0r3H17-@{id|{
> z+-
> )7=(=jyf^@DndX0Omp#?g#`J(|kGy)8m>$Dt#l31OcFJ)wDzAk<xlp}8(ZbDc+X
> z9m;`)Q;pF4w-
> }m(ezXqJ+#@vGk#Z3=Bj6aCpZ#k{%_)W^^sD}yS+$>go*>!G>tP_K
> zcl3mVXg$#CP6}%9+iE^bFiuJ=$LY3q_05x{7K+x2t!TpM4y#1l9VKmZp{Mm%V
> wE_v
> zyb>0P@Lps~REY@KS3+61r~eXG;tJt`e{0yWmy80LT+1Z0GJcF2irjAwksT%`*M
> ^v?
> zw^Q4->`n@fstCl-
> gE36=HdTzoB<ksO_dL=i!ZZT*n3|Y8DZ=zW#tg%hWmzy)Oz~Ft
> z6c`HAwE_}ZIfB6p^r{BYbWMoq8jtB3&g}FtbJ}}9Z~Xgk4AW=);2tstn(TD<t~jO<
> zu*XzcxRrknX<9uprd8}G3DDeoNPwpCuQ9T9v(6CBPLF11wk=dqgKqYN7@B97
> qlt<-
> z-QEAcF@i?GG5-BUe~9M$goKrS*s4ik`)h~{tV^d+4F;bgt6-rFpA<}@-
> QoUQp+3lC
> zR$@7usA|)1ZBR6h<xKmnCIp_+y;a8U{IMBQ#M(XCpNQ3Gsn;+<vZIJice{}a5r
> ag)
> zzCOyrjfv{>DS4nCB;8m9eh4JR9M_tQs#l&ShRPG@E{mb7dylT}IMt9tIfQPYo@i
> 1M
> zYEfJK2p*yf*mQSt9Nh@mqib5!!as%N-
> &ZAc5g+)64_YYs!W9tBS_HKzj$kT=pzb|_
> zy300pr&n~x5ZoO@a8fyffK7L65nmBKBj6Z<5C1Vl@LWSsJ0yb9g5gf+HoFf%N
> D=gC
> zL5PEf;fwV?YJc5(e04`$tn`Y_F?@d;!*{7yH9~>{M*GwMBYY#^7`|g7d_Sf6s#iL-
> z>u8WxPZ0f2;W_Fp_6AlmR8j;k`fBa!WnSRY{!3%%>fX@J>n_{0DZOHo&<!N-
> ?_%g~
> zp{qfK5M97%|2Vo4ut(P<@4`QX<lRSBhTJ5MM7G0OR4!pEMdV4JdxRdAU`W
> 9NQTC#t
> zZE!h}?4nZ?Cu0lpyU(<^KY;xYGN^G@kiYHjA=1|{ZHb0NTY8Ds!^9HkVHW{j#2;
> })
> zRq5$6(31cy94qukR)6j*gMI;~F7$iO#(;7&Q|~WeKzS&=;vo@srk4XpgLT-k7I{q|
> zBrIUlT@T$n;)4j-
> 6INNcAzK~N^d#%c%AH&HxknaxB4QXGCKwoszaRoZC~coIhN!!9
> zU}y;D&}dwD?{SRAFb77jh?jM*M#^>RF59*ty<&svu*utEj*r!0y;l>$Isi7^)x_%%
> z0sA^A3)c|U;YTWk;jL7M+>Z3tBd*=K$he{IbB|ihULN&?9pn>Z0vwcJg00kvx)n
> d>
> zKKNs1odJiqTYB|CwB_{8DCu2~<*L>ZEzw|WitjRg`|(QV^XR>{@<;R<dOr_}ky
> 1}6
> zn`y<9*&;Hf{W@Rc*|8cw=tpW_W43>cHZK6P2@<DZCKK0Me(#+>H}T+txrw
> 7Ln45T%
> z-!Cqln|Mbv@eBAhw$4qQd-2@FVQs{^;P>!5<|YmS_LB37J@L-
> DiO#0EiPL~z`L4N%
> zu9mrpeHYD5d<6KnkZ<Cs;9qnTz6kzS41110R*tf#s?q#8#BRqNRejW<V-
> KtGP~*lY
> zYwhmvqmG(z)KN$Hw{;VbtclhRqxC~LDScKV)xZ=3;|?3C*#A(&s#05ZaJp_VrK
> !;@
> zCh%ucoBBCLEeAtw35}j+k1U-JQE%HFL(3-}So)y`=oM-(j%=yEVTra|6IiRQMyt*>
> zwylf3mO8yM^=76fpL+!L6RDDZY`R1b9$qzT>zGnSAG86@PT;{)kEJHT*wMhm
> Su(D$
> zr3S?`BKx}S<OQ2XCXK*;ipZtHwzmw0pyEb01w{E<!Gmk5dgR{~t9lF&L}Y7S2|C
> K;
> zrtb%t9-xL=Owxv#P^b^e*!LnYu#bBpN1qPd-uU8LU=Nrzip1>J;{17!bAazcvJUi;
> z6ou}nNYxf6nI5#B>amb74QNu%?DA}HQ9xPrp!@ZWg^Q+1=|^M(sz|PRyE@
> W}no9Q0
> zO<brAOKm;H>U%D>txG-
> X%`J7SA6trCCz|0d(RRL!WW;>?Ih9<@JdD7GzXEPC&S!wI
> z9L4SYDgb_C07Qju?47Zb=Y4*A*MZi2<1VwFqqIE$5<~>(2_}%qHNwj8K9y4?v!
> _!Z
> z5x=lc_@eDH$Yb3$<ubYE<3P$WG}rbdqx}Iaj=OBz7S&X)%|2J6-
> &>>ZHx4t8vXyKy
> zsE6HeJi}xM4RgDE{4{?r&6hb<0*+)gE-
> pwmu`#*Xz3{lL40wN`|2FmPfc2W>nkV#R
> znJ3pg%KhVwe`2$n1D$Z=9<2&KaAIjNB(eAxkHLtG8@3X*3sMeRXJENb1!UW
> {VOmeS
> z6TO1hn!N4(j9KhFO>X?u`m1DV>q_wlQHp|<Yw9*mlcqK5rYX6$ZayF2Gw9Ib!
> t6uE
> zv0UF@tl~PSaHR55(#^T1&6ZS3k0sqq(yI5xlP<EP@3W-
> m7JiLDwWQKJD#ebQs#4Vk
> za<hS4R@fvE?I6?$S|N~!DpQ9RwYxjOW<lXj!DzF&Mks^XFbrmX;kvLW*%}Szf
> nhLB
> zg$u&6?oY3{-
> (c<^26Iv2Bw*Tie92a)THV6$i^tgDrqF8~{xKTmws>s&HhtHAg0rIU
> zv>WHdj)F5F+I5A!(kC=?t3Hg-
> kKrtYb!e$@^gda*%vw0W&PN*_+hnXsejKJIVKr({
> zKP`*@xt;0^2B{Al|5V(#*gmyXaF+S0HhRql8x}9_r=3Ebqu&p`;ppWTKg7qR^_K
> 0j
> zF|pqa`TfI;Qkbh)a~`1!$Z5xx)MH&B*fkB(9N?T>^J-
> PP_ukN0|M#l2DORP|537<C
> zLhG9U?^WqE)FMge#sh^n4{GUmAiWpC_?()k?Z7B;<N??ss4`)1cx|n?MrVrpF
> X`t`
> zWYcqahH#<Oyz02E?z3MWffjs<HSZ2@@&2zEEe<#5l|WZVN7PbOK#Kz-
> G%t*cdj!J0
> z%;sp#dtij-4bD3*lW>JPXrW>9z$l4=1BEFs5>fimray67HwUCT1Z}yho!r>;CnPZA
> z`u^WbDr#Lv2GYlkGDcG^dB}7Lbr5mQE_Y8zi)%qOJ*(oz57;ML#yQ!RaROSr9H
> Yf(
> zbFqnNQEa!7orHeuEVH>r<7S!B)4IiLrCZ@7mVZscYt((;d*>$3zhZ9UH<uIFlHV2l
> zzQ?bUcW>nPDSn^j`T8s8CK6*`>0gEaP^mwoMgZb_6|YC@(;@bKOtt<Tx^6ak
> zk^>B
> zzl-
> >NjNh&N*7ExVzqmpd=m*vAJH*s`ZTp93U1$4;?^$>Nc^4^0L8ioWx@1OobM
> OyE
> zMzO&v$9AU<MLZ<GQ8l&rXX3u3cMkC$#o+cs?9<~F$$P7&-tb4lyKI~M-
> kq@%V~6R7
> zwcc`lk!c~dRmockLLxsvg-
> Kx>J3}95XIIT4mUDWK7)jf2t1L7D@wNa!QAA~J8ANBD
> zfIv+?Iv<6qhDE`_h8+qFP@UX(uD#iK{@}E&g`&@c?=K;1F}5l3OXyN0e5v6nQm
> `Fh
> z<D8dJKa(3<UYhn;*p>PIGM#|sD^koM1STn3UT%1d6qLGgw!PWd@-
> iuIQyGTJP$>ms
> zMJa|zVR&wwZErTV3{88ixUf(Y^gC)zAEwrW94~bPAucG5jRYxlPwo)ZWKs>Dt
> hP`p
> zavn4fCkH&!qeV<9&IE@ke%o(|jxz`MudO|EL)MTr#MiTi{B!<1dbe6K;IETR|HR
> QC
> z(3u%1SjMbM-u6KWsm6Yy&rQ8r%YKSQHrVPiYG7$^w!)V}i6^c~U-
> 1S>+pQIXF_Y+f
> zM*?%j^9-!ggK-
> 4fnInPiR}g1%8|A@9wK@wtphEX+SBSz}Ifb`s>?{12@xcJ{Y>@pH
> zJe1)k9j%u_O-
> B<9t<vls8wqR=g$k_FgCXBOAA;?X+gDRB+y9H#0OQMA5q=Hnpt5!c
> znN&n&T@r%r#=)j|N<_xD`S-<o=BjmQ9w-
> n2fm8OSM*Vl)7%2b0i{>Ua@;jg3gC8i#
> zh)_P1x8I;K(||Ekv%}yko!exAhgW<M4mL7Rk}q}V=Oqv=v?1X^g8XVZ+G%p~)
> >do%
> z;7Fv8GHWopn!m5we6a8?3|yM;Jyu0sVObRW^G5(XNnn}+YTQsXl2&*82w)W
> gv&ef8
> zf_W*Cx@18cUg)o+ma9+;q?YckZFc`P0@!y1rb6Y`L!tO}KR5!|9RgFKvM^F;eT%
> zo
> z1hA{aLbcjPO>wfkY6P&iS)pVz*<$B{<YYUWq&DpcHBwtZF+@@@p(Umo(}bE
> )gb&ti
> z5?4j7+Z>m??FEKO*nmKf^-Jk-
> noRp59Yy|u?1z)%$CiN5zB0j8r=P8Fb&rn#CX1Nr
> z=`?%Cno`%|zBB^Z3W2FmPh1CamyG~+Nm!`GgiSxo_Su#Zz)lYfm2OO-
> EP0+X0$6oe
> zsAnSw8;u$POdF2SMt)^80xJA^U*Xqto;eu|r^|N)rV78#m;JgH_uvR%cL+=so
> @fp0
> zIE3W35x}kv3q9NyiW+#;2w-
> mu3mxYR9oOP!jR1C3Sm>d?&_kQugb~2{r7pw5h0(sy
> z(XFmX%HcKLY4aADT701uEp9)W9$*EnXIbrz^#vW<?7lWa4!4B`9qkJ`y4Bq}0@
> zhy
> zK}Y(6j%;z4j{r6+EOde|bV9S6IRe;(u+Z_o(DCf29s#WAg;3g!^@WaYasNZg;Y8R
> b
> zFty_$zR*LOoz|X)gMC3@BB_QSdJDr(y$37Y8Wwb%FX*@yX9jEyIWd`cd05afz
> Mx~8
> zokDvJFKA|1&{4jiqwsGY0c>1Y=n=lqBU)Vb2w?w%47b`PeWA%_x0jT|3;lt>RJ
> +4`
> zp@(r^)Cgc&=(nyh#uqw<^Q_CkMkC#eDJyZ5FL6|}`{eV1%_gLVHai^9$O_pt
> WD-A$
> zA+voXuzn4SfN4+!i~;!E5UiicAo-v}6f481FK4t9*ZrEgiH;?66JNY`ZelFYZ{Ybt
> zo^Rp#nGeoQyvVx~dA^9}%{=eoIl=R(Ja_T@O`d;An$bLenCFl4{2x632AFs7d?n
> 90
> zo*(9UGS6r6yol#@JcnvlFdnj66OUIl$T2y{XwIWT0VGrh->3w-
> 6V|<cDtLhPDeU;x
> zI(-U!$7so>R?g;v2)26$7}G+|4#6DT)WYhAh4VKkf3lT<B1svnBMi_wxv>q^$u(c`
> zd|?xNsbi3mmOs$yo_TIq`HFYrq@ig;jbKbe+dLB3erafcsfz$c7wH-
> ate4sdOd6WZ
> zD6Q_pAy_YJlJvBu{Zu+$v!FgT?im7?k2Zsf2EOV<2ih=;26vbfNL8U;-9lBZwhejd
> z?%6zL&n5cVK>C)dMCy2;u}h*vGgUxc9<VLjN4EF=J8Ky4unxprf^h6oe&{&^ve
> T^j
> zwDJ8wPRe)YX@6pq(y~;aI!48{kfRiItUm<3`lRJkC2K2dHLFcy(b@(EqD03#1Va3!
> z-S<)Ae_8LTAthUkJ%-
> 1`F&xiBvwM4#pK?FL=U05S6sMW@gD_AE`OZj@Qwd<8nfZk(
> zSn8aDn~v_JelUTY@D6Y*3VLqnu#}M;n?eXT_Y%7i>$xfDCQ0=FL3Sk8Vkr(L{q
> oFK
> zXe_8wPfVw)N?(4-7dZoS8kc5l0~m|zb$)I5FllkNnT0?O5!9i+#4BEb=kA&>3L!f%
> z?VLJVrDG=MuQNcuz4w0n`ySAx`>VR+vV`Vlo8HQ|iiz<J>Ucs+mi5KSd?2!5dqp
> jI
> zi3941+jWJ<O!2<v*!T2fvs>FMLlA}bih&%rWb6{=TeU&#7kW~&d&^>#QyW<b
> N*yrd
> z*TB^@*fT-V4UILc-Y+-
> N)D=99YOD#)Ak$<IuFX|FfoSEhhgP@XtAU)hIfD3H{WyQ|
> zR#=HsAc{vT7ea{!iwRmb36?(wil32^&aozUb_X+g!>5I|R<x0!heVYsmeK}BCG
> UKU
> zx7p@e@`jCD-M--
> CPW!l3J?VVr7}eWn*V7QN23y5z*}KXrHEfySL;<iydf)Du%%-g}
> zWM^Ayh<DfjQ7qCE7eQ&2J-
> ?dRjWnIk!(i89^$B(ejm4{LsZQ@3)1f`~+h_Z}S7w4R
> z{8#s_rNrpG&q4R|--W`!JTyq$>~8g}pEcKrCCl<nogBF%PmbK2y61Ku(|y9|{-
> L4K
> zYUSo!UXBu_W<JUTZl7Zac+37b(Jb<foxoZiqR<9}Cn8!0mR(O}C?od0_PJjj^YrR{
> zl@zl2F|k`~&M={m1k7}l&ngfxzLa;Ul(tS_trXhmonavzZw=9}9#;jJPn|utI(Til
> zXXi``5bRQwvMu$6U#PKscJr&#dn*IWvymcw3!N|(ey!o?oOsclQ&c~MQb$BN
> !lYIH
> zor2-
> mul|Sel?QA%w}#VBJmmu%>x+#6mTK*ajxz(&xZl`}h_J$(*b~sXI{ie2M=;x5
> z9lQ+cHYr40+yq59%YbWg&7XW@l<G3S_PJjkvvc)cYmBXG3@Rl0AeN%WFcJk
> k=Nm(s
> zPmFEg?MLs8T6`=YBOLu%UBl3{?r~<R(ZujRMbv0=E`~V1b&LtK^Xm&=SBsU}X
> KC;q
> zX1MU%p0M_@VNOj4r~HXgh+`1&uq%!Z8jZzLPxLv}cG}r%DZ2Piq$za9(8Yciuv
> 2;&
> ztkqslzExii$k*{MkBwI7d_%Yy5#BR``XVHD8qKU4+4HOYd;G9PGtV9&mj_8^SE
> qZc
> z)Va}(kcS*cboRzUIjlz!-pl3Rw?>wKBMY`~8;0HrSrTj;ZY&pU>Ah7*ueRzycm!fM
> z8W2X7Uq|jeSbl-
> B2J4aJSFOn}ar0;~^J|h{HDczHe4>~Bd41R#SA~?N`2zVtWSg*M
> zK1ZiAF^~#dCg9Xb!+LelCiLkis(g-gS<fEUS|Tg#Va;ihr@b7Zt0IKn<&$e!*o$UY
> z7em6c^()A`fD;gPJF9$A5$EI%W{=l1$i>;i>&rGo5nAQ9-#nN<>KM${FN@k-
> gC#Od
> zZ61wSq3?qledP9j<8Kdc@29<TH&T25z45BfS2R9e6>o^qR)f{3FNLjrUMOv^gC
> *cF
> zr0tCI?i32vP$C8GJO}At<sl;p#^61?%k4z^M>Mti8$IdGRg!?xBdUicwo4UYI&$tL
> zsQ}UmCS}jBkCV>&jHOTa)szN%(^iiog{{D)CbnPjHLcrX5?uc^HJ8?H8<$k)nMAc
> $
> z(L0#V;tO1o^iuP#X`fFbfw*g<L?BfKQpF1h8m9m~XSL4@b3QKuI^O5J1YPCeY$
> uST
> z459MOzi66NLPCE?3T^zhk%V=Rpgx?P)rfxt!Il~a5uX<7An+z3?&{bZIQZHoX~~
> Cc
> z8t+1%ZFs6fc#kRW9;Rak{I!NWN+h}jWxV=?Aq|EP??8wmNs<pg#et~|6<$lxc
> %i3~
> z&SToI#(%efyuf@`V|D7(P)o;$rp0aWABglIU!P{z{dMae4gH2&=qqIv{?Ue@!e
> M=b
> zdQxlF9-CfFKHByo_qM!I%?zxGRmB(6&%bZ^M14uWuy_?K8;vjG-
> GEn2agzUf?(!r2
> z*Yj45^<T$$pP8+DnRd0k=#Q2jEdHA`<UnhDh4SGSTh4}wC}rT><%jwr-
> o0{yFXDZi
> zLvEjL!LPXF=pzRxx#?h_wIEL2v7$=+$_C1rk7+~JE9@5~9<5sF9C_k(RGT-
> <U~vUa
> zUcLGSjd&}L*5}+fg#k`JTz4){HOKehPBU1%RP&mAQ=hvR$7%ij1|I1-
> ye;eSc<FOr
> z(39!!KF+lE-
> 6`&3pG)(l*^Ohy?3ZN^nentT)TgufL=hMznre>U8dA=x<N39vgss@*
> z!#Y>a9~`xUgJ|2TEnac*;VK<CM-
> IiN^f^0*8mZg#+{7pQIq~(L&0Imy2TZGG7ft(J
> ze`eadlGTwAoo>3r;1cRf(0pau>Uu23g{@(DWVl*;iXOq?c2~f}^!Z3``1THpKaTM
> u
> zezcaAd5UpyUGeB*efj4l3CG?W@TrS(3(8wE)V_P~yu_k=_?&1?_stKwS~LCK
> A9w;U
> zQ@veooVH&0F0Dzc%r?vwYqE!H9;V%|-
> GReW$Fc48UzZ2RlJ~Z6Ld?K2XV@Gy^2Nm!
> zexCcn<0Y5T0J8l)z%8-+=~i{XaKkO-LJXK<ms<=P+IL$c9fFObsfk=Gmmk7)>Plv8
> z52+%W<v#?sAv_<-
> w(YQ8gU7Zv3z@`{D?_Y4zthSHoj`GDpXbKJvGR}}D<yWbLae$~
> zN(`$We7SRt-
> Gv(wOo&fBVK_!tFxa%zuYT`sOT1Sdo(5X>5Zynnl(p&a$&;&MCFkJo
> za^K-q^Ac7)8-I`e^doX2z>2n^c#PgP{hmIu%Y9NXF8kr|qg-8e%JHz$itFg}zt_>g
> zljLo)gBTS!(8^_|?f0x*nvm)*9*u<fefs%nOu&a{AQCUH;aZXMB<7q8YkcG+w!
> O;j
> zjhj`?7%6^)o47UzU(29he4EmDoaOVMt{HV5bLd3zjTD4ADLtT*;>|NC{lY@Ih1
> W5x
> zS@X#bVhya+jlU;sT|9M=M5!C)qLY4p<kYntvpfN&(_sThJDlE^zL1mE&FDwN9
> 8~p9
> zVmX}@L1ag_q$;_w?f0!BeH|5ScH=)}q^B7r&VQeF)3wUm(mo2di(09G4|=nE
> W@!jI
> z-6LaTf$DUN#sWxRU`gzO;uw9+wmpz*d?4-4RCbj`>_mMHO?B5-
> 7O#*m&J!F~fWft=
> zq0wE>ntxA2lk1p7q(nn=R$JdqNzPVCeygo+R9m0?8?mU+>L~X0YBpT$jy$OK3
> sb13
> zsKANmqC$OoUv&qaidH^EO{`Fu#>&E_UUPs`45*@m*k|?WUOdipkZ>Z=c@
> rlu0#Mm;
> z4ll@b)r~XV!;h(#zk$y_ks49ohB)3hNbR%lRG+m}G3nAT3#XNVwCQ>7muzsSe
> %ZE7
> zF@9^q9X;2$3HP-{SvK}15|;&H-
> sEMu9K@BT*;U#4Ph1kl#)DA2ABP%okbHf@A|-hF
> zTJ{<F`k?=IkbEtJv+{ksg;ywl$;<8iJqW?Xg|j1}ysei*%1kbw(Ks;UM~LQrFPhO8
> zU+$Rb(nzK4s(E4)hM`2ELFzV!PxkyY5;pNpPCvW>vhR{W6qR=gl=C{mb3Bf1Pb
> @OY
> zcvkyW65N$;^|ms}*qi8RaIcR_ar?Sepvpp=`b6y)kkayTb(<}*$K_iT3Km-
> jMoY8U
> zd)(H&hve!q>p>~`=)AF2>D~%W_@3L%PC&+ui$7p^%nI>%{)c6Fum!Neby?x
> 6f_rxy
> z51+{6p?usO-
> ;d#;b5+Dx%MV|L9IHuOFFp(jV(e{<wc7$h9NRwA4`6Q%5xK4$k=;V1
> zri92-
> KZuQGK9NU6`M6O5BHFKBFjKFz=s#R9sZa$ct1f75TVG&hi7Cf%TYC@5)pU6p
> zU0lIgUlp9W5MxGnJqc_~*k7E9$K<i?>n0lA=7i{OrPncf`jO4eFznP^L^}0<2GKu;
> z9DI@}Dza^>yYdFZ=7)-(+SDKRB!6OF;L{Z7oAZg!G(bYheE;W3{aI20FQ}=Jcds*(
> zF%gC2CEc|9cn;WpekgT3;c^9{;<`f+I`b~%+3}6L(gQ;sHSV@Y>CK74Bv4}<ou>X?
> zdrTXw>ViGq$vfo7y=rWFg~Pja2KVhc0DTEloT*H4ut6TM(`5Xhe}a1p8E#M17`{
> *X
> zKLe6Kfdnb^@ufY{X<XXuv_a99rtqKcqXVr%wmIc5e%YoQoo0n^&9+?IHoPTA
> fa(sQ
> z8eP_$lUZfhp@lvC0dJDxj6{{Sd#K|i_rw;O>8#Nm6WluPwkIUMI2cNQSOohVb
> 13P>
> zr|6zSr|rO>=a|Pt3Lh{y`N>PE$Z}7L+uq5&_YxO<z5fMg7GY?JD6<R76f~a_+N)
> Md
> zX>y4hZlq0u<AV&%sr5ngsdSbwj%SWQ^S#R&?z1+QRYB&ZP}}!imMjBYG4~(
> OdN3_H
> z#ce?hlvT+eBbMuTKjTYwdMW1<#T0v>(QeiS=o$AO6(F!F+qOB^w(0n`&FL40I
> u3P9
> zNSI4#DR6i!8%c2EPwf9SI*4BM{)UNU=#6vxpimt_|3}`|J~dq4x>u98$GRh|W{
> @%A
> zcGI=JBviQKM@+~ZBzSj+a%Q*E&>>2KxBJMT<Mw#LTTNGuI<6hEG|Sy*Wm
> s|7M8(mQ
> z=CmtOd$(Q4$9*1ypb~@0=@bbKUZdEZ>amz>86y5~rO(8$K<v(P$Cj{o=6hkK
> !NMo<
> zSSTMiv4q9fR9$uV3e!^~S@)`lA?xDY_;K<GWZm1{HBrg#6Lu@AAk@^M@u!
> Uh;e}yM
> zHmQe&f{-
> pB7kgrnc8}Pri9N3zg#3lQ#(3+K*O<KYu1P~3|Kfh~NJtbzWcoL(VV8!8
> zoE}F+Ewoy+L8z<q$x&zkGtNx96x@oLWT@jX-(BKMmbRpZLWF6j`C-
> +oij0cd%Cz<Q
> z(a<@)@3^h|4#`#J{m^kitv?O5d|;`wfo1Ill`OGErUa{_*Oy*ypMFq(cqRQ~H3R
> 8v
> zmby;UO(!=~b;C42b&TDxbUeXsDs3^%^bS)%)FFsS6-
> FsIw%vJho!Q>0n@X3Ui$(2b
> z{oqY*=_XOw2Yp%MA={S%Zi(F&zvELt+HaD*sYXY*vn-
> 9qJkk74|G_pxS2s)y6{BH#
> zKqGr}_E=bgW7~uNIV;4gon8>bi=Oc&w~Mxjv>^}a@ls-
> UNC~fr6i+j~$~douwda0C
> zKmk}e=#*~_i~a))A1fLa<W26fc+nox7i~Q;XKPg^5B^OAmu$Uh$v>cV;PD$cI9
> ?|T
> znty3=rhA4S?khaw=~AC-
> 3=y3dM>Oc1!@8d7KOU1;?s|c~q5k$ta_odo@S+cn+y!pG
> zpmu7{-
> k#@^k3OZ5Ommq7t64IJL07@4c9UH5K3YW&v*F(l>4rR0Qwu)`UbB3gTyswN
> zP{jjVWPGHmkxNZJO2=Ehca?_YVU1ntdxfjW@l`4|4kXlIWgWZ5I`-
> OmhvVij5*OWm
> zamCcmeVxOztul3c?Zwqo3(t;_YfN0M-q|UDVVRe(9-
> ecZ<$U|Ru~VmZ*03t|3g}KP
> zb_~xmrrxf8!U`SM$W<ZIn3>D7_4ul7JNI^W?o?=*vK|$oJJkpK*rWz6*4dd~hi
> +0c
> zV{0D0Nn9|3K9KIK=6GRa24q;ZF#|FTV+2wS9ndsi$*=($kQQX`h<SXm>9+R)iT
> w6E
> zc^`I#Sth0<yVsz$8Gi+V5Q?!9aQhBYTNZBDgVxbENz$3?L2LV2oRl{-
> aW=z4%+uZL
> zJAtdRtZyMA%fD%etdAkGAsCeH*g+%3bT=uENCe!zh}7-
> M!o4$&2#!A0_Xv+{;D{F5
> z`)6xfm0V-zR4~2fC~3FvnL&nQO+hUvo$W<LP%ORB#>9s9-
> 9oU^9aD}J;d0J#w;{7a
> z>MZe)?cKsiiQOZ%YK2vBH@$0>in^2-iYSf+g|3PjB71GjIJSLvlNEV(SmgcREfb<l
> zY|n9Z@ghB>FH(u!d0~;e!Xo!mI|i?U9CW^?mkmr&v@GlAuy?C+i6!TRMgB{9k
> qjB<
> zxO-SMiE8N~eUVD+e)fPN8JI&<%a2--
> J%vYUQayi4&jd@rwsvya%y7qTfwuIdz}{-f
> zp0s@$#ShVYlN)i8+on(N;!`tom{xanCJ^mN$Y9k1jRgPrY+JV=PcX>F?q=5zLLzU
> 2
> ztryJBY`bY~YP`70Jl`7{2U7pa!ooD|g504j{$rmgwquwNUnt)LlS?wA(^5xZXU{h6
> zw~Czu&e<CbswH-
> w;hI>N329maZa@3Mka?DW!}lvSSwUtxoP$tTEMBA>%oQrY^Gka=
> zR#r!OS%A%Ods$tN%8Gz}S;jTB@v=TkZjTtFG}RvSv@OmYpe)ZQ?Q3FX9a>)2
> 0m+Mw
> zcv%s!FU#2FK3l7*leuzL@l9pQ^CQ+`HO2bkk;5i=Z^xjHTUT5Hdi@W36?$>AnZ`
> ?N
> z4^j~Qck%Wp{o291yS*9m4o#edWV-
> h{HdV#UUn9ZKZeLh}PmKhhK1Z*Iu<F~*%c+`s
> z^n&^3OeU}Cb5zJs>PUa{GOm5&^oF%QeU6tN;9IiiA*}t$v<R|Rzee-
> Vt(R2qi>;R|
> z4J>nJmMdE^>2bgQ4P5efR!q7rK1^)I<T?n1Y#f4{W7=MKqT@n$EutvoI#x^s*
> ?yHS
> zT5fS)xId5@57978iWuR{Mgv>0aMI&W`>i_RL(HcOXIIhXM_4;quOu4W*3&!C1
> J*PD
> zws<hHwUYq9E6efQEc||q+=}qKGKQb6oxJqb0KW%R%J#+${!g&5)8q0`3(I$|Z
> A0Pi
> z*ec3454J;p0u%i+k<DK9%8<@4ru4X*l}CIrrN=Gim0wJGrr8~OiL_tzz`KLRlxJ8>
> z>2Y%e<IZjiKc-
> jQU0O^jm1c`6&y2X3@=W<+$}{oBlu`!aVn`dAlr3kBv@(IRanNFj
> zEoU^5yOuLXT0tQcLcd?s3GDnO#IQYM7+Es3WXMgpM;j*hXWML9qsbHDoc|
> UP&b-)&
> z;FmSP^V#Xx-
> HI0n%NmW(FuwP=2?kmdfwHV2r2G;$b+cuS#%F9_&s|#9XnH2wbXTtJ
> zuJp5KD!b8z@2WK$`x+YSt{+{vUk|Jt>|}7lYjQ_Jo4fvkoA8|2#@XT5&tczxL(~3_
> z_xdlaI&}2SfK#H{q?kx#JJw}a+?j18#MvFW#ycAt@3`qr*Ry7@uAyn|O;bIvx5I7
> 2
> z|C|utEUV1;+o-
> Ka{G1R2*|r_hvshiJVs%C8j4hPdR`I51ptFhW{=!eSK?(ZmH0FL=
> z>ZtBG&Q>c3cUyy>c@Q3Wd!un{A!n6j`JxI3N3D!hbbQQKK`K*+uO^VGmQ1E
> xj}dNL
> z;wB8dTIc9^Hy<R(uWz|YABJvR;8J*K1WPEENs4f^+tjNmM}M@K#-
> dH7y(d%pmgQX>
> zUk10zFomkP!S?IuYfEzkRDN!Eu4xCS6R^GlF`9OmY4bii@BIG2OsZDz`;|KAeL2
> GV
> zmeyKgCr<_ALtM<-
> ddIedRz}R+5a^H5dUn}DiI>l}`;@kxUG|yvmJc74Yczh9#JrV1
> z?;yxn`C<H);sneg)^p^6>|G%6@NH<Txj_?9?~qej{8h|oV&$d#&Q>AvHR#)of
> D`i^
> z6&z)+mk<9^MB7ssQ;EJ&Qi+``uc*ZLeKb%OtG{JpzuM~!;gU2k=eQJtGZL%kv<
> tGm
> zPhww*-M@c15UYVo+~?+5k-
> N>>5mSjnExg7T`8Lalk*3S54`Gp}g;&Ij^pL(tC3Z8y
> zA_JAU&pk!er4mm$SS9YImOUEN5=-
> 757WszqB25eb#J|UC=^=fQO6<Dt32JF8gd*&F
> zt;n9jgD||FSL(UB%Dn$iQj?S^LcM5@b|4FSai4pGrG2v4p@&92%&(GTc!_mw
> hhMY#
> z(hFuv2vfrfaG#sNW3zj5x$>MG&byeESkD!})?bJoJG60?z$PrZqjTfWVsE#FI@b
> vO
> z#ocemcGsFB6Yy7f>cTx6p666MY<8IAXEEXGrs5FQ|HsrYh~JW)h9=Il1rYC2Z-+li
> z0cAq6)Od`AO-
> 1_njh~iy113j;%9MD$(rb$h^IAp<O2SFMlqcS2M+8yKrkkBwnHSH|
> z0bA_A7>90ZE@~@|kusf{sPLui4H@l0qwN9oGC7(SW+J*`v)MpjTirLE!9Vi%LZs
> Rv
> z(>=@3@>ncPja@R<-
> SB;LKyoksM#GrRdU=1O``EATeQulq;|{(?tD@OV4@Ax8Il^Kn
> z+qFa2FKpBGyWP5O+01qE9bL};<oDR0FKn_unTPDpS2oz6Z$7}EyFZyBNY~Kz%
> w(<=
> zvLUopWxICskZ;7Hb-
> !+!V5Y%r*Dmgt&?Nax4@yq6TmDJ$Ffq&YI5Cl!oolMf=J)WB
> z@6s!llk%1=ZK7tJL^JA;*P)5^+$|a9F27sh!TNE!JNI_@t8DW?sGqkOrHoB#o_m
> U=
> z8?@cy+iDJbB5PEMiLY?}u0>+xSHC-
> T7nu%=MaQ@X$M?I*|0Rw;8gjDLgyko_+aq|+
> z2@mlweq|V==ao(i7@Bw;bAvcPN9Aq)*(;Z~fxL&8w{)cP(tWk*b7o?eU|ME<
> fn`Wv
> zrc{{iqxDJ3Y;mHur{i(bG1k9EA~T^704@w+CTvX_UIDq$7mgqk4?}z#IeSKm{iFo
> 3
> zbnuluJU0iv=3J7}Ov@t@b}{WqdQxT5J667hb=x;@>Qx`W!(<>mP<j3FJ{nZhK>
> p%G
> zSu=V4M?`G4`_5aTsTv!U`lXuplLM+#zh6a6n1ABUtfjGppnmJezK{YPRmJ(m^DI
> n1
> z4r9T8WW@n`wE~=kvSP3}#pA7g(j5OsyB@HW32hMa;si!w>zrFIT(ophtQt0*_
> x!ZF
> zZ-B`~)PFZ^&#cGYLO2JgZx4e+_4t?j{U2Kz3%6!bi+oeJ`}|W335~r1C=H$YyXC&I
> zMORJOulfsJBhg+-q3tIfZDZ)Rdu^-;2DAY3Ja^jq(g0I}Z(pzBRJph-KJUkv%xv=3
> zKjH8kIOOb2LF>Au@icRn;i0SWnEqG8V@wQ>v&-
> @DkmtFtd?|)U1n==sE^gPq1$dkt
> z!{Z}{hu##HB_U?!Ar;KOK-buwxi5Or>)&tIA3E^j9FfT~5AZqpa9)3S$IeCe)+?~l
> zVg=>iV!0*nxQvJ7!v>okn2evOPmq3o*(%(2yDX25x30TdvN)N|oJ3|tg2?Kx6_(
> ds
> zHorlIbm@BS(}(5^v*gA*DmRdB>+{Gwp_<;JYjra7B~s3Kn!cKu$_wkOWT|`0((
> baE
> zJ1vQ>qV{!*rBJkA6{Ge~yoM0Ax`#Z^o%zKWwIg^>ZRO$?e=eZ*S>zqIdIj=0m
> (iQT
> zSV)rV60X^<$z0Q0bRCnt?If1za~VAl0pz~#DrndNVV}>7nDnFS)_|1kM;4I@6n}
> u#
> zvAF-
> u?pzx_5{_M<Ovj=QV*XJ<Unp!PNze@0{3LSDb?KUZc5>F=Y|&%wO&8=cx=C(
> a
> zy9Zndk+6+Fn!9LH(@)$|CN4WPaVfq*)90Oba@|n?c>B9xh(!a81Wn<crBc(+p
> VDzs
> z9;x6i9~7w&a;CkmU?mc89+?X{`DQuvoi=yv(_@2r=P#)2;cek%Hm-
> UnuSDT5+y|VL
> ze&LjkWApOJsthykQPAfVNICB!M%cujYj={Jah~^q?kRlBvM^50=If0jx~899knO
> UY
> zExNubd7JGY&*%ZFRBbe>^cz)b*rc2uSlV%v88RUS)@=x(9$q2@aVPo<J84m
> wLm%cK
> zkhgRYdz0JwmFeeacG#Y6Md)FE&_6EGsfDQi0)Ha-
> 869tk;NRSFq;<Oh{)C}bFcgh(
> zQJDFn)R_j1E8{h(Q-
> L)UKa!df0(59EFK+=b4@M8Lkg002)cFgzm<$!E7A=fVp`x={
> z#j34hg%r-0LE~gIbr2?(*EL-
> @H|uY<=<&?tZOtUeb?Je_Ev_@tWoGh+j92fS&c_aR
> zV!~TQ@IXcLe6N<2zcnm^yt!YwgT~&;sY_`<J+9uTF1@yE9rurCKE)ONrrT|MlCf
> Sl
> z-
> {(e$$UFd4OWwd*^O;S+HM`S)ExSZ*rd!<M9V*5z&gGTu;%r_p`7T{q=tCl^9~S
> Pw
> zm&e#k{^a7@%pCxvx9FNk)#UQ_cym<(Cr~0=pj>N_kS(u2yd~iCJw<dGDx9Fg
> Z0PM$
> z0vqKAed6Q~DuS)8djcX9j|=+kNWfUs_Z0qyXATT=LO{f@p<sO6pSEXeDT05iw
> 9~aG
> z+oi{xz079TaGyuDaz7gg@MBEwPw$)TH*4FfPW3%j5t}7s^J_^Fj1S6hkJ&NyFd
> c2M
> z%vM~GGZ4R1{OxLjvwlol<T6UgT0x83VKyH2out_3sJF_(Zak1?%m!UtUtHvu*
> mC18
> z7A<usvGIlW$#!*;G-
> rk8@~VfNP3?x9kImU<_??Htb9uqC!9Hs@#hw1^w6?*gUJ(5@
> zjt*M&Kc5R)bvf|vlh?}%n9STq%g@-
> U(WHjg;b@|JKETqt%XTf}n%<(TMw9igv(coB
> zmI-x;POl4uqlt$+&lNr!8%-j3Kbj~PSO2d<s&0E`CVA_hi25Cj={b8-*bGk={>rcw
> zbd3q@KLT=b&c^e_*~;R0cCYXz*YyzB?BM~k7k)sRz=bm$pt~mr!@Ba?Ia|Kvr
> 7o~p
> z+m20|%F&UUC5qE5qCUGCg7N)>^0)TB54G~(CBaIGUfu9~FKJeu+x{z2WvM7
> cScjg~
> zTi*jsTU@7&wn)fcEwst;yw`e9&uD!ow5C*5%Yw-Ov5m5v6+*biIRm-
> #2eX;$RJDAH
> ztM&gK;<>h6Xs<oZ$wy7FGkk95d9XR37jR2%;^sfI*~0DqvQ6=Zde~Z_UepPas
> S~YY
> zQ<T>-%ZtqzxrsY0!B<NOIO0C4`84a-
> O5HJ8>1KNz23zmhMzUsiT`U>XV0wtmzD!+^
> z^j1N}yeLF2LBH1B7>bO-
> L>aF&GR{W6GwU^f_m1#pDP%#KpunxCUT{M~3Y6|o)Z4}Z
> zh9ECxJGn`{{(IB;!)}(ooB^e~Ti8qTN4zR%q(t#p5-7K*Hi$Ko_k2Y%i$aM`Wn*&V
> z`v-
> y^a}~v9yB2XRd`qcGvQJ|la1!GGIs)8nzLfOd$*DOeb!Mj~8Sr@?_^!`oGo@^c
> zldQl~{I}%8-Q{1;3352ba;Wl9<se5}28F*G#xtIdXD;IQ&Q8rvZ&3{rtIk}0XnKpv
> zPTX*6F0Y&Cewnk{rJqjVO_N{9t8CX5Tx0Er|GB~X&mKMkGOBUzy$OE^({W6
> $OS$AS
> z$|c>K$l7DpKT2nbx)R=N40_Me8;AEPpT%K@h|VC{4@ndG%)^Y>Hec^S;@e_
> sPi7}E
> zRx>K_Fe@STF$^;DYRs#6HhAk(tNYkRjEUXTvzetl1`q}hpdeb@$yqEUmXWVo
> dW%43
> ztwikTW>nXDu35XMv)!K8%eC47Y<LV7J}3!h7*12zP@H)qrWeb=WvP?pDWz=
> ~bP`mP
> z>56+0B<J1ZiRr|KGjr-5xmG7LKd1Wy&3~csC(o$~kDLZAh@9L9S$L6Px3-
> 41iqwQn
> z)9g!Q^rhYijJ5lFlkH1e_ysL`n$G;(pUqrMJq)a-V^ZEEDZ->0vgkw0lF4oZofLH<
> z{*3_3`L;gdW%*CWWz}rfS94a4n9X!|jfb^36dA3%i5SUGe4RTR_L_wUCxvD%
> &`sX1
> zUAl_Cc9Yq;a)kuY4}KUZK^wV=l%QOfazF`^p4043dD@hqY-YZ)*rKZi!Piisf5kVK
> zPd<FAMKlwWk6d1Pjmj%k*6s_O5;{~ori=)Cki5vV9!pajObnN^f<m9GqRW>iH
> #wtn
> zGsOHr0IZQfR==j+7MC<bc6Bg)FLeA_2;V1!S=zOmF&d<+^@e{Eg1T4R=el&4?
> V86m
> zy+v0I(zSld_rHj{aFG7BA8f-x+C$ED^VY=%=?LBr(#pl%kP8Os>Ex|{YJl;$%;z$C
> zLp*V-Wj22*Px|&3wm#%Cddf9z!u<9a(q3k-
> +|Y)v5+k4A*!zip&+k9^{gU6Lugy(d
> z`t`Yq%eY^}??Qfa`CZTNWBd}MM^}vY|0+k18a=uyzaWt%O@q?#_dNc#@=H{
> `>c0xU
> zR+b<}tvmd|xrsYT_p5KrP5k$_<|gLx_hjDP&%5vQeDpWxCZ=wfoA^2Rf8g7H
> ^0&aR
> z=RYWGJm<pkzx1zCx1+{a`8T7-A2J4%$B)rt^`T?Ok3VdD&G_--
> {Ax;Izh#P&n_rXO
> zJ6m#~#;oy4EjejP1!oaL)6WDX*x~p@gE*6Mxo0(NG>BQmNbUB7nuKi$3K4_
> 4$*Zgx
> z!~^>xQFRF7rMRD&?v;f5wv!iw3~wf-SiP+-
> {njC7MwP{%mV5#%J^tafB?NJyAy^Oy
> z5<Pm9CV`5b|9;gWRz@pRd9$H368h9zHrb{5a<e-
> uC{61{%psARR_tW=SRMvD>lEn=
> zejQ@T+ud*cj!#gkEPl~!rh$E*0||qD6y{r|#iobZ;{W`0sYBT-TAP01I;N@qrJiSW
> zH#|Yio5JyQx(N0LAI|k*cB~IvBsVpD8|hRGGF}C@Q0zXp8&VU%zBYjC58?W)=
> PB42
> zt}ytivG|A$|6GJYL)!p5zO;*-W}U2PBi594Og!YSN((hSAx*N+<Tge2DNltS?c_~_
> z;-b`z&@pK!UXxma#WeXa;RRm!Nb0>2Oh-
> zz_Atv*=S46JQ*ZS+FG`)kCfZs}kx%l~
> z`AF(G|B30b|FkSM&VO2%%>3CfAx9B(QK~V@{hHLQDEE(~FpdN;9n7~&7+6$
> Y!*ZdB
> z>Ox{!B=-=bw}cp-
> 7Gg9t#ORn1BS@~6v|Mc1SJT))$DqX`cS?JYFP0U#rG{}871MhH
> z!#^k3lkJge=;=7l!vwT{j^)U@bnj%p4WpsQvZ3Q(jD}4xAw;o})JKiqR`>0~v=iEA
> zGYg;BTE^M`>!mPu1fEsP?U}oxyX&I6b<y3j=<fdDj(&x*eicvd8EqBF+!=v%MtA
> e0
> zf*y$8t>I4pwrAEycN?O+<<Z?k(cK-
> ~3CWmI_$)F`Z_!m_#Rx{>Z>dX$8v#Pd1+Jcj
> zlyGe|W)$8W8HL}G3C4<<2RxcV9e+z5nbYyIaQBQdyYNgyMOUFRf?arOIVv7<
> fy-xO
> zsFdu&hKkvRH?IkYt#VW@HdLkymBT@0d*))5%|8TiwoA>hJrfeXNJJjp+q~Uw
> w&+@!
> z%s=vGWU)O|bc|=*7mYhc7rxBv?U}U!#kXf>2YGMLgsreWb4B#E)RqUcPcAQ
> 15ZkY{
> zp+Vo9t}mcWOrZLsF(oox&pllzTWynfyoCoQcmfJd*LEM6t}Tz4>H6-
> !GRB~E=&#W#
> zuRHW271E`vnXXmcGSjtQq_^nGI*@H{3@mjgB-gA*-
> g(LmbzHGzY(6i>N1q}9>~$Z~
> zNT(5NRxYF0X2+Y_G0l@a(Q#z^Y$n<)7It;>wbi}r1~oRcQbU+z1zBqpu=Rz2z{z}}
> zAj`3tF{{Om@de38#rhN06Eg5L3(87n{$hEo=R;!o@n!g+o9XqU6_k7z1PM#ly^*
> O)
> zciFD#Mh0EQ<O@G!29)Nil5X~PI##T|dB_Fs{*T9)Jc4gGCRZ-
> *7pns%Kee36KeEYG
> zFfsY5Oo?-Oq1liZ!>t^j>(Udv4sKXHGkVLC0Z%ZU@HIG_>-x51+2PAn$1gjq10t-
> a
> z?ya5~-DNYUT0M1DJ%eS3D`NG$lwKRFr-
> xkNx)B?ZT#4X)J#E?HPn|(MPb#nHZ4axS
> zdRdqUN9Vf4YT2$kzy`}DS5_X*JCzR^J+Sg{#h>N|{T7>Sz!<3s!+P=%J-L=t+cOf^
> zs%$>5egkvbDusFn`V54H=L-
> MBlxuq?1*DN8ue)qsBA>WPy6;l&&e;%=&1g`F4;&gU
> z^v{>2912}z7<6EalHiRkQ5Dh}hTUw@wf3eZ7!|p}T7M_CVhv+Ce^`7WM=fL64
> e`}%
> zl+t2`-JnqB4T2>NyD1*;lLQMJJ{5A$fLPwJn?gkiCssI;nfo<~3B=w}w%oDw88s1R
> zW7W2B72nId+TGU}xvZ;cz#6fuy$rF_TlD$Wy4o6Q9kQVAjqY8#%XXba+oZSXD
> i-Ws
> zYF+L7F&5lKpNg@dhg{&!Nyk_)g7++_T-
> ?%?0SitoXTd5wLvk6tENm60<%NBztLX`Y
> zF1VGtnw~J+3SaALEdBwtbzfC_^Tck|osggzd(~UDea&dSQgwaSgt%Fp>k<nt&
> fYn0
> z2j3!C-
> ?G^|MnB2h!Z(z}no}!l#<L3cWBKl_%HKIo`L??Iz?`{#u&+Ebm5d?WS)Op+
> zF~WV`kL}_7QGkh#1+MDW7~vv#PdMe`W~>MZH@Tc}KmLvgr<aAba981rC!v
> E+ixAA+
> zIc^&WvW!SUczSScc4PL&m@K_Ttd>~u`jDfwR?3^4bvR5}_LupovE;Sgtc=;Hn7
> _E1
> zwE|<)Qz&zL<~n7=zrry*Mx!EJ-c`osT1@zOZ-9W(gj{Ze1|}22i*8(8;&LftG&5J5
> z@YF;Disy2D7MELUTfUk~Ac@j|vK;;hxm@?c5No$_%_OLi-
> lD6xeEqe?<^8e7`XlTd
> z<8lwVz+H+QjRb83?;A_GxQ~A<Xsk))jdd)$K3FnUWBvMM@W=>z)<w87pyc(
> 0%mX*L
> zyi0FcHQ<Q=W5U<qJQVDk-
> fXNVF7Hx87=Qa3V|?Rs%X(`sTyCwk7=AV`4`ID%%C4DM
> z;&N+tVg*^Z(8=6k9{D@0_q4c2Wl<?{c|DYaaJ8Or{~IIRcVXuk;RGlyKXz4&a1p#
> G
> zoN{qZwhG2lMtwQqez!q{)62q_;jY3aW+-
> rZh+yuH(Z=QZItt2n>Dub1;9zZ{R7{rM
> zV(hsBg+@2}CzjUzaF*7)!le`t@NhPhQXAxTO&1ohhM=1*y0YFo4{GPS^uVI!W
> *b2=
> z_iF?R)^C?~ydIWLcjJ$THB23g0Ag5ogJFXeF1<@XQR_#Vf+o=<Fjeg>9jBtmF*R
> k~
> zcxK0B*$1{(Y2Db;uyou>K6YQYE0$~q`*Xr%Z>IQR$@UGc5@V^@;-
> au9tpo>3rB;Fi
> z<h2qU;G&h_0KmfMfELRW3p<YRj5JO&#$aq@X;=yb7$pirM4)DDw2EtW*lzH
> 94Qo&x
> z)!=u>$0&Xs^vvaTwPj+v*`h1U#Pg?!;(CDMC-
> rO0&h&}mp1OXeIHD_~y=q!gLc;O3
> z-qryIe{D>{qSic6F8nX8>4gWU?Z%|YQc6>|lJ>59)h(CTT{d4!!t@qhZLC~kQlx_w
> z!_Z`SKU^Q{3?6cUJA8SpGeq#gSV=B!_Dz;<d#0|uGwfzdM$TRqx?s~tASxtf&J
> =L^
> zeR{L?S&0WzTag&s*O<gmJ-
> qUY$Y2rB4}xnZns^9deFHHxmc)apFxb3Io>)A~^$?ak
> z@?PvTyD$9#N|eMy4J1K4+<%Qx<mMPfKI653a1a!r#KRE1Ka#5vyr+nAac{B}F
> T_J_
> zIYl0469_BT5)bLAaNP;V(Nw2KmCUV~xD8aZnQ98k=XGsymA{I&e9#T|O-
> @}&w-+y*
> zphjMssp9tW%xJEtuUC<a%Ticqby%T-
> tAm3U^9IbPg;v0yzZZHBz%<K9X$*t|L6@>$
> z%xVsQ@)=#TnazCnQ(i$879Fd0wW(LfQMM{|5f0WS%@V*DWMLbLPupXBs(
> bRHt#y~}
> z8iYLQExN||^slj2Nq7|_Y!wf=z+H25tW_fT7@yvi3i!09yj7-Sj?ZQEvhasD4Cm93
> z(c;5cz)!(2hSpGG=Yxi^0QT<>W0g^th=#G}o-
> O0k0WgG5Cwo49E=G|*`f)s@hycZ>
> zmoAG@B!c%8Q7-
> P|Hj#!;tIH{JEI#Ntds+DP6q<R(BtMK<WqPZkVeA0O@?E;Nx_AE~
> z*6`^qYJNGAWOSoI`5njS#+m;`UObfR(zVs476z%-
> @`#wX&U=FSl$@T+D=og~Sp)W2
> zC4Z3cZY5@SDT&MCNu@c}D<rIDenlyTZyh6MleAsE&pb_{`OjoOGWbE*Tuv6j
> lKfkR
> zqLbHvo6YMDE274#ebl_f{#qWs_~$`=RJ~VZ|EoxCy^J2Gdt?8+?y~v)mZz>U_
> Wu_-
> z8U!w!6<+rU8{0!Ja7&Omkx+`@W9<LAj|S{tMc(=s$cZ!98<)%IW#Ny=qkmLP8
> ~dA$
> z;s2JHu8gE$B&G-KEWv25(hG(q_Ma7_$e-
> Zz*uW(~vH!x37)2uZ82jILT|kjUIYo|R
> zhX>pyitIta6;{5^*gvdfB&PQOk<aVOc{aOZ4IfGA<QfH+NN*80u!7?qkW7f?tQ
> %zW
> z{iH705HUe^iATLB5jRZwxi)0PX)B1HEpYFWG$&}jFS9oUuO#~*ucS9mmpBi+lJ
> wT{
> z(v1f)>!u!ycNT99F{=q2lMJa+r}Dit+vO~^aLDD2=jEZK8}Ff{&yk0c9?U~YH}X)@
> z-
> )Yu^aZ<9{6;7)cQNm$E{bth70`lz!`W5@l6|sJ!d*5$#m(A}|xm$FN^_w*@F4^e^
> z<*?s)$OZ1r$iS%IMDVeG^S%!UTrx;Gv3~RXec}?mENnzR{-
> 4utx(WFcQ*U}8NvYqg
> zjZx%bI!LVF2vGfIGVWp#MI!iEzj@b(0*VZjQ{?yeiXwVhxDOdyIFBd|%zh5)H&
> 0Sf
> zKCf$wJ09O{(-+k6?sxC>o@!sEWxWA%A-
> RR3Quo&68Qo<wJ4lk=qN|#G1W&b}`w>5E
> zau2z{y&XvyRj}l#W`<VtRQvGKpn?Y|C)VVLSOxX6@I&@{6s~5cO4Qdm(J`Y+p
> aRHz
> zxHwylzgm~x;0?eF;(<o$Rbd(_y%|xJ3zXILR=n1{Dc^>t^b@oFtibmbY}(s_ju_2
> O
> zXfg{z`6S?C@C!+%drvamWi#81WV*(B$@gPCaj#biLXvsN1+E5B8Idf4kM)v<YX
> g$?
> zQ%;OzKf@Ug!NbeKI>czi3~}REpjHINFZq2%bAf}5U!e+Olc-lSevOIph>Txf-CNc%
> zx}gGmv##Cr{>NiP_#!<Z)-eRAjxpvVF(O3po(Rgty=6&2guZej{Dkclxr|;Ga)`dd
> zX-CM&Y#MbSaj(z-
> VfH6!83`>h=mwk;#WMq=Ku3LG^GLt&LAk>Uz}or9)!u4A`jvs<
> zKzaGM_maiR%gS68Eu}dlHoKqM*jbDJFS%hwSLvzAxbSk54OBH1wE8h~UhER
> 0nqBIh
> zvJS=g@mg)|#y=jv^txQjK<-
> >TTQ@;C<_ug5M;Yg;^~#yG8KQ*Ds(Z4e^>xQq2@+x-
> zHtJ*D^)uFq@JFZ${ml>HA+vhO1@21ZQ^c$he2iH?(H^vuqnsGCzLD)Gxr|;Go
> <Vl`
> zo>q~X(tfe$k)vW|-x4o7;<d<*`4Cv+xT+dJ6}!Q6MlTPdO)!xElHC}1VQE1DFE-J)
> zHTkHw<l@`r-%5|b<4JUF&W)4XXN%jrEavtZsI{F?F*QBpn-
> hZ)Zn6?g{UEh`K#3<<
> zO3gCAnbgEyGXqUr8Fhr|wO<4bg#<pNat3X6ABd&TS=Q$2c3Q`jK*fFngG*rj
> @!w4W
> zQ651~?z#)q8muLlc78ZUr$DBL;%|Fq6X5a{Eoir9>~XC<idGnC_@Kpl$q#X;?oW
> )s
> z$(31}l>QSsxlO(C5f*gts>|OkOu7V|ehmN7t}pVu-4<@7*%nXsr78P(@(GcR45-
> i$
> z?WYv7b|u%G!27Uoc+b(xo(QVBp4LOIb1l5^3ccb2STO7rx~Ft{h3>NXJ4u+{qH9
> cq
> z%b!2&6}^6V4ts@%T;LWUoT6S4!N+>Vva5q$v7d5cy`uJR^$NW#{3n7d8h>7+9
> cPqq
> z4|RZl-i|XW$|IT}{NmS8qGZQe2T73UJ3eUgd|iwpKk?&vND%=_o}YP5j3N=dr-
> *WK
> zix&kH=`E+o%l{^d=w;#i6X44CU{)-i5g`~&5bmI$d|uZU_intXjmu-rKl(6{CSV&l
> zbR@QU!wBhKiEZYCQOGvB_iUp(roLd2-
> lA)aZN3sC(%1Y59umnzE^rf&l@Z%S@G-VI
> z_X7cu_E1iYZGOq-
> v0O$k3!gdsA7>k^^#4z=4Tr&)$`CXEt^Z{i+pK{ku+4POHeZWT
> z<g<P_4=Ex*u}$KGF^WX+o+8S{o&NrSBD>2evi&YmL@x_#XzjuqY5tMerjvqjk
> l>1b
> z{P@9a^An^|q;@9PTn(wbY{K<Bx#r}U<T=i4azFTy<smop81oIjg6x?GejyX--
> k7LM
> zcbp^wPU$VW#+ax#MzTe8shH;EAs4v+M6^Uq6v4-sXz;3lWV<LQ#zc3rsU(-
> t%R)<X
> zI1~MS+nnkV+137e+Z;<wf!-
> O}<}Uw5851poBrs86L*5^wNUPU1LM9TRnCSb6mWUz|
> zyr+oSke|IWph!<SMQ;6!D595zx3hDyuoq@1azaz67>7$tDGJJW>DuZZ{ozOqa
> 8is>
> zrr0XOXFQzWlMrJSzl3?P@-
> `bRLRQhemp8i0=C7k<6cDR!q`W;JBg`ziQH)hQ<O26)
> z#7RV$2tLLtPrWxF%#)N8W0h;VL>Rp+yb*c)j}BADDxs|S=Z7hd&l)aorvFzNt1N
> {i
> zC02PUMv)U2mr+E3VwH7>lZYY_e2i6o@ScDoJIX0?>7Am8UKZ+bY%FYKI#K+
> W2*GHW
> zYNw!lURTcZ#hsgB>L3<)w}gzJmF`2xoEYOBzfbkuK4H0xc@e6PWdA=KoI=LYy=
> NTV
> zVPFLhwy#*_BgQ!rE)Vsagx6ET9_1mi|GzIrrU*X9ICotUkZBv`#29D#zluzHS@;7
> =
> z=Knd2^W4*AjB^zvDKXB`F^c@r55XZt1SrP26rmb1P6QugoR41~P^7z@BFBDO
> 6w%AV
> zuMdTBbhx|D2n;woVw@`|D4*9A{pJV8IOXj>HO3~#nd6Y+?ZaO)b_Qcn{ytI{
> UTG{k
> z3lu^=(Y+swbjPw33DaA2jg3X8$EdQ~55pl<Jmdm*E`l|pN(3L{lk46cP-
> Qda#Q3E8
> zQ=*Dq7JfuA<$Uu0<yiDnc7(_D;EN$iiBD$4DDpU6BqnkNC_XtIi5gKPf{*dZdoK
> $p
> zvZ<URe<Ny3E~A%)?;yttZ8Y~tV^K2&<-2rkb#LA>0s};nCG`$AzzD5XZ_~~-
> jX{YU
> zG`ev^C@$j`AB`(>7q6JUaSc@H*i4fRY+ltdD4(nhc3+~CiS0?jlunKgY-7tS%UqYT
> zOz&e>XC?T@z%3(gbvYr_xt{Z@Mk5<xe5QvPo&;C1iKVzW-
> *qW22jR+=X0U#N$u|G$
> zG1I*Y_XDADn4yqdb34hPHs7?}Eh99UjSHg1-
> 7zWH?)CtWB_K=5sj>nheqF0}yv1uJ
> zXzh5*>t<A5v*4`Vd&~dr8NFZ2(XX1X8)~{K=r{#m0dLs%X8nVv_cpQFD^pbJZA
> ?8#
> znc#$MTMDrAji#qg9G0{H_;}@XzwY68P^)NLEHLNm`QRw$>-U&w(Rwu-
> =T7Cp&&bp4
> zu2~W=#6FoGQuUiogK&6GXr}KQz(mTtFhNDC{(HEj0n#-
> LWJ=h?m8l~inQS0tFDT{W
> zz0aoEvc|Nob(Fx?HE0$l)E>K%Hz`gGeABkDNesnw*|Kj+&8oa`XmJf5AnX{`kjkt
> V
> z3Ya%imebu%7KF(%z2$x~fF|3)H=ug*6W`;((>j}<FZ>K+_K_K`cFpT*ZLAyii+>_
> b
> zqQG=?_8lc>g6Z6I^xUlv@EHbFb}e~x7Qnyo--2Cuvz6HvU2PYh4B-
> 05E<7`aH?t8#
> zE?jakXmt-
> VzG!PwMtP0OC>8toxE8Kbnki*u5+8+DC|4I&S_LGQpBU0h+wn>T;Xz4e
> zt<e2GD+wZbL+3H<$TQ1lv%AF%-_<4G{lZ-
> mtLDyb`|@T}g6+$jiM*rgW@OU6xG9&{
> zT{eF<<)pXhszGUleR*@e5)uwd9&&+ufOYUl1ef;Z*^-
> 3q%lq|3fe3zxa`Z1~m>X`F
> z2-eHObn6jXRb!=~!XB)%Br|fu*lsff!<+SPjpWw5bmOg;-
> itN)Nv$!&hx%?HvYF|W
> zkjv|8EMhlXbUh?_o9!g((!<cyuB-5LD$Pck>afvoBL^G&-+}`-gMZ;l6%ox?%3&r1
> zFb%H)Gd_TkQTdhfd3K{O>#u5^S19Y>1DKz_3e5G_ilebk-
> cS9qT@P?Ad<pm&3Za!b
> zl}C^;UeG<a@Ph8L`Lm1{bQLf3_&u7Zp-+X1?3rHC2zkLnp6AwI661vk-
> Vevh#r?D;
> z;D!4rNB;s|_~2Ucf?gI+EY!27t}yLCC5mkIDYKsU0pQyVP%qdFP2;d_^RRPB%eG
> DS
> zTAtE9H?e}>Px!rm>)gbwZF3Xz`PFQnn^?JnJ(Ik9E5CYvWB6Uj?>+oR+P9e@%_
> XE+
> zz~2w@_hx?o=)TQuyV##ey4gROo0#}3xa-Gr6Tju%Zr=Uomva-
> 3JvBG6g!hN>dk-*!
> zyqm)Pp9+-qPww0N;vdMD-
> ~aF%`^UM7H}SibUn{?8zZgD;rR|b`Z$GEm?EZhapYtyg
> zOs{P}C+7(*dy0r+W#_l`y~24yrD$T&fg|_*MRCNI%xrfStkFG3M=7bZ>@M#(&
> 3yoL
> zLO~ipw(r)CH6?ak7g`F!fzxH1a1_n9?dMdlW_N0nK17G`u-~0siPf!c9{m|_3gSxi
> zvK6)Lgd9?R#;5urr~3A?7k<Q(!Tb*3U_a}r;pW1|0~`<-a8ELGxzrbJg=)jx1sWU@
> zm72|W;@gEUUQV5kw`+@=;a}wXx4z7=HY9mN0AWX?jjH;t&bJ{7l{Qhj>j*Z(C
> d%9A
> zhev&+U#LVoQpUy4#7a`ezY1TdBxStQzwjj~$)*6JyrliMUDHZx+JAe?)Si7kFC-
> s*
> zOhWByFvfi={cI&gW}7*!q9#p9q2<Ics3GneDgcY*qBFsdXb>WK>=RM6V;G3+S
> jf7s
> z@L9wwCo_To8%FVOx&CZxk-
> {q87v7)&K*&xCu@4D%Sok6&+zXh8AZ>|o1^>dIDHjoL
> zkE*lB6K+rP(fOQK(g_bF*F3DNcw))ud}Cj;h4p;=Fw=JMf*ETpWoL*4Tb316Xi&
> a4
> z7C4Ex|0_Nel7nsAadN!L$U*ps+b<s1w^m1o=7_0#xQ__Mc{c$~*dh*1bTp*S
> ogtzG
> z(5%0W*6JVYt~#A>sAG(0?W>Eovd@;YpvC74mBIX~bit^4J^>1A<dC;q43#_Fp
> GaLP
> z;;v?WT+Pt*bHfN{a3Hc3K>WOTgrY##u(w1J@c;N$YlHU^ER~_7=PiEd@SGmw
> cVX%q
> z?IpqkfaS3L=A0+uj(9)#Z>pgKBs$J!tMTfyK5)Z_dQ)e>9II!&F_GvbwiKs&R#KIr
> z<IZ`*=zo2k&i1U&wM<q7jInkscHt#blU9}7yErvd;hS&ae5FZg92Yx|RK&(GZY8
> WD
> zgDHBlPx(Vq79O$W_333bi4I~~)aOKdid+4{6v|89`nmA?B>3PCJqS7B*|CsKV(D
> 9I
> zM_vCe;l8X+2;MlC@0>lJn?tks2&`vt>giNAluc&e$Rt|NhmzE`U?^-
> G&4yqW#mgNa
> zR!MPsk&`PX^KDWKC#y~+QHZ}{?*_*X;Y~q3CR;tCIHO@31oCFy<BcyS9&daB
> >eR1Z
> zR@F(8RV>icE7j+CqNge#(V_mGj+ATM?2#T?&Sq)FD`{w{T2WaX?JoP#%Mdb
> XAY_)h
> z9=rQ*t{s)kTxk8Udi5=JlOaHg@IxYosF$i0v2HfPBr|XHaOqp1Waf1|xFfDo`>zER
> zP3m@!;#GoIxlX;}P<8j0D|uQgs%M*OsZIqOJ|vmX_wf<vdqQsWwit39I`&J5bs
> %XX
> zr06&iQp7L_k?I(4O$eimb~loXTTOxKO?L{T)XnY&72l~Rf{MDUdD?DI`m9*NhR
> dTz
> zS${}w>^5|0e}V`<FDExFsT+GZ=zJPjtLIEj8f5zw8#sra=otrK{PsH;6nSWIhfpUf
> z^Y$N784!P~SS*?Outo=tA6X_!zfTW_d_ZZdU_j}J1(TUs23McHnL|82J`GAMeh
> Y`A
> z!c+u+GDfU#c2{%0EhDJLiwO$mqSMX$iBp(<tj<C&_BS;4CDVOYSC>1yp>1##V
> JIAV
> zG|aDBSy}usu(>%3bw!v%_UAL4Dp>e_3j@EOU?=IVwRWK2ej>lDS2k_cxjB=h
> HED;)
> z?&vY6_-{(O$C46EXSat?(3q8r2nCsAXUZ;WPRF7T?4lk-
> Qu!VHVq1raXYoV$yn^oX
> zBA=)7c{0^>5hyZ&`(cr<FR@AXsl`J%^=M6D9(}&>H^z86>!i%i)cAnYuG4A)n%l<
> 4
> z7ZgS9zl|CP35mz`nmF~#BqU6tNJ<G;n*9s7ds!Ac2rHWTJfQCA_rO@|jLX}ebT
> xYF
> zG%j!KaW7xNQ&V+ztv<VcJrN#coj#{mOtqjK1nkkMec%|BeLJO8m3F`5QL(8*`
> NF9E
> z7b8)v`ZCzKpBW}q?(=0u<l{vYXInjL5;vadDWOA+C4?lA#5^NVa*t5kHW}u<wV
> OV4
> z4*3Orh?W`6`M7X&7z<f4%H&fEf$;K>hg{vq7*hDVz2Z802Embleyqw=Z4+q`Jf
> F5F
> z42DFPpbPkHOW%3@QyNkohLG5F^uZSQ#kUDN2EHiU5`0kp_g_Q#oNtKMh
> 6IG9ok**N
> z5@4;DtE!#UKask?&EttvJWp$TX=v8R^)hvqdh4vFcg^i3ltx6xuz^YgfSWZ*eQ^
> >J
> zWOU(WQU;A+;_bhG@bZwtUFQiJ?ne-
> DcRlu&*9RSVP@QK$Q+l2FMkJ~_h)ay|hPDIA
> z^tUX#LB^AY>g87;)5)V@PSvUwAnCOPT*7x-)R|wKUVb<u=dpsBQ$t^5i;e-
> +=H^va
> zp$}DOb`lcu;ICDcEIxzzP0*fx6ODF*7Am={lu^x$ViAkRD6k!wmELx0VFq~&JH*t
> t
> zmq|g;8*g#|bmmkOcRf%7R;!Z82XxDGtEipAQ<?htShYH#l!L9(A5V}TNIDA$!oj
> Vm
> zqB^L1tkNFN`QGRr7L#W$>V@PJUn^4VPE*7k4w4wFyg03yxY%fVaDau98RT!
> kwss=0
> z;p@-
> C%n{&^mLLQ@O|yE%fU&}H+?b+MS)A>XmuXa4r!4sAW^bVfy|_?pW$#uV?f
> $^i
> zXgx3pF}Q%qvy3MPvP8TY9%<TZ09HQpEqBm-
> YyT_Ex3X6gYPU9~Bp_+yO2Qr~33`X1
> zR@kn_{qE8dR-
> BTtJBUcMJIfgyo*qs6Ii5Ya<`W>EUa@~@C4vg|c0Y|{8pRkYD!R6C
> z@W%dJ4X5{Nk|mM~ZVpG3>`yP>L3^K|c4+L)&Z)MuR=@-
> 94<K?E@2F~Zn{mSl6>lN}
> z^<mGmm_k)Q%w6pwbb7N*`wNTVF5Z;pawoe_TpA~KCr<&fcM*CK25>O+u
> 585*b8Y(@
> z+UiWAy>qiE9H5w;52C~8enI<#H3#aT15U;c?S~|d2!n_`SaFQE@upXtDv^#-
> Bi+tT
> zInqSB)$!C;H-
> SfFdrnmj1ur7)7^_|_5+ygMif#|DXV0x}m&H5Rb`m*hkPVWki%D*y
> zHBD7hY?~B>UFV1>(<V8gpkX4#lq7V>KebN}pRaen8vhXfz9$H(YMpN|+tzD+
> uO890
> ztJQV9&gKDPo}(|(i08Gu9j-
> =CftL5Adl~Twx>*|@UB8~1YP0q^Xv^)54~b8B^6WBP
> zv4)N(LpalIz{uFK@OyDqQ(udFkVK3J;tls{a^K!*6A)uO0&$|YZ^Dap_03hCyjn#7
> z&l+CZM!V#rJF-n1G`G{MY~zMp(}rx*W};h}8q^(}a-
> +Vo&9o`b!Y0zywuU)1H@t&)
> z*X|_NXE#cA0|&gXoH6W8^{OeQH#z}c;(T*X`ESZqJt0lKviKFAX-
> p!~BXFqa;T(^^
> zd`7`Z`4`d07#uR`rNc^|DA+Uxkw`ew7DfQ<7w6S0X_foL#iH<zK;P)pQ`?hX-
> =OvU
> zl&s?lc-EBai)flq(|;wU`gA)ZmiUJ~iPZ7H=jNboe)T9T4$)hiYkJ5t<Pm0&ujZuF
> zo`ZXlmu0#dKN6n|(d(tDSB^UflQ<~FxT6skXPRM3v1TnGXi6~ws0V|287`>|j5n
> j{
> z*Sotf3R_+LV{@pop#35LpLG!b_rEg#2VpA_qnck+Z^^b`lp+WjvAJ$0q8jW}%Y
> 2q%
> zJ3Dmj!JoiDkW4!DPR9fyGkS~A$cx6B`~|f&UN!<?vXL>VI<-
> *aED{+t;G8#!p*5(@
> z;$>rRv%5Tcb0V6uZ-
> FfE3OEbpdpQury~9*Pq*rgY0wrzP!!HjNW(ylw)<(T$r4oM4
> zBAPGZvY>?Lqc<=%F5ikZ$0#e!rkD7e<J8trzb?J3u8Lsa%mrp8Qm77fX&aDxk!b
> Em
> zHsUj8_Y&QAwENpeFnCmTRI>U+$Gb}iygMrHZ2<zyqBm>=4-
> k+KdUHsX5Bl6W@En3X
> zTVn`O$~sCZUS7&M5#@7kkn^$88*C)x422u)RTUIwa!W)!;$BJt*iR9r0Qkt9qu
> mTL
> zrw?j$DNZ!LGAXn4yU}Znbt8`#jMoeQ5q>j0g$Uf9Ys{Dl*C>Xcw4nUFvG5U*^
> MkRt
> zbnb`^K1UN;6|v!?6j!9GiB(*gnpPypT+l$)mhO1?fp%{ePtb=M?^@iINh)_Tv?>
> Q3
> z0FmLK^8g)z9PfFkM2>@K5%qW3i-
> *&rulkkypAJ=3wADajp*gpi%$kH|ZarX<^~>22
> zNi>;c_>36l#_=U=k7mAC<Kv`Q3x54OuZD6cpJZ4V<wX<=0vOp&q&MpXB}8B
> qDyA$i
> zNTE?ROp8$pC7nj;XcXje*@5GhpZnW|FX^mUuLg2l?Co1a3z~gT_no9Fn-
> uwp`mGm_
> z1SzaZ5R;rR2&Nz>GkJBXrh#A@0&~=+_s#COg$Y9-
> +uzAolkLPW9*D{IfzXOWy#@j+
> zP6v~N0a<W5Cb~8d46QekW%I$p&E{pGKS@&z!dvdi273Bb!!#&4nbF}fLFviN
> A$llb
> zKv#<}Kpch`Bs0HJg#s*&cRy_^$Ko-
> *y6^Ea)GwG3Awc(2Z_`J5#{tl3MvDRCfEqh?
> z3C%iqv_XamRVi5S0S}?@k60t5fm;aaf!zE_$h&?lD~Om&Sx_@;MC$FXf#L%ql
> <UTJ
> zwj{b>KN?XlB2y*_^sg7qLh7xOj6`e7PJar<zjPnxX!V1;27d93=6NvN0gj(Z>$C-0
> zo@0gAe9a)L(`Rx21>I|A<3nBt?LCk3t-TvSKGxp-
> vG(o{+gk@=SbL9mS6@&fYCm~M
> zG{U*f?r!=yeIKOUxq<;FZ`(NBong-dIWu2m4|h}Sx!)@rBJzRll}JmJ+yNin)D68e
> zqFo>QS}@z`%hs|#FjCZ4B;7A~D$Se9452~)K&sI{6hLz6!MekxU~am@g|9((I3?
> 5_
> zrnsw0=ncSx43$#92eK7jjR=o`E-
> 5de{=#`oU@>CDF_}xBHI!WQ4(ko*_uoJip_<tt
> zyqQnYh^}xxbTy&|y3b1YbG<Sh+UoHk_anV9t5K*6o#eh<N*Cxvb?ysM!caFl!
> )2qi
> zHsHNr1GomfBbQXTrBQ-
> rca@zPSnU=@2?AsIhg_px8ICfFcU<9SM(HTXl(UoE<Wjnu
> zy^>bvYNCX2qm1YslTC^p?f$YLVupSqEh9||3_ShWv2HhCd{^}IgdO%g0IM6T#
> bz@>
> z|JhUv9lZoK{$PB$>mM0kqH&{UsEz2&evtRG&6<8|E{znyhl9uXI75WxZ~AA-
> N9zXx
> zxTA!FW;JX7^xAO<%isOamtS7^VgEqkVSj-
> B1OHU{<*OlOjUhs;`r~USM9?UKyr?s#
> zlPY@c11#+^j<PDS;TtaxJ>K|NrdBe9Cz#tc_Swt~;lymJui<c(_N4kwk}b{TaP%m
> n
> zk4$q&YK3KH$R7wLH6sb(o(DA6Ai!l7XC%;qLZ2DqYDP6<*Ql~kHN?hD9Rdm!O
> #dD#
> zcHZ9j*D~gg=sDCreP49`a!aTv#gAXkUfu83pC=(|3mj(3=%ju$rt0SAabKM3Rsh
> 1N
> zkzFe&oqp!7eS^&{C8#%L51*I#Au06WKK*qWaSklXYEVsFcIA677j8z+==@M9
> RyseF
> zQ5A}v*xt#hg}gTdBZ^p6?t;oHH}!bdq-
> +_bYC{F%;Nx%ZwyFm0QyaC<k5#NzN}--Y
> z%$u2Xqh7Wh2;}4G5~`XTa#q2CP#!WjJP?~39th>1+WaP8m6%F^;&8w}9;^~zY
> (;Ui
> zh|nviOLYi_*uc;T`P~0Nv}TuJhHg_QR%a3K397Ye*zo>jTdptNS9K9HTyzl|+Z(If
> zhB|6B2mH{Wn{xHbLzi4S)WeCg|NS1`wdIPdpO>wtWAr1MfwZ`xMK2G%=d#
> OpK2}rm
> zPie73?JDlMYlvezz^BFi3tm2E6B$w8WPFPJ69yh{{99tlAzCqNuR?Ar`Orii_lLz*
> zmQOW)F_}mAaaVrYyGVI0wrPMh;m!5sYr;YMO^@<NOlrQMnVyk02+K`JP;B
> NkFHyIk
> zzvXSQN2S+T>8TUaD|S_M94CVk<l>yZ;Qcsz&+@&+^){wp5E&d|M%^^1^Pb
> Q(YFk~!
> z1akzi9^5aej+5+sKeNi!Dqs|bvZ0Cd?VwNq`n`hvVKCCUgnF^^)YU8ck@%}_3e
> P3%
> z_vaF3ywS1QJz%p<#`+%l6PRTN3kQcordRa&{Ej6*#)zl((n|FCR(JCx;l+$VYjl0c
> zfkCQQ+idexDldFkep>SsMAM;#snZSXHrW#;5BnuK0-
> KOOmrz0jJ3CR!3wK*0s(OO4
> z1RYvRtL&uQv5piTWN6h*eY9QMY}=Qy5`%vvfG7Yzo*i%w3{UX$3q8q%>VPT
> 0uaH;A
> zQObdnPLDZX=@~Vx)r;eUhS7F$4qO&hbUX`W_%e~>8QLTnn;e{U{gLII<OO!X
> PiKij
> z`6lP?V5>tZ<TZBV75jCB@X`yl7Zg9B9ab0jqc>YE0*^bvoa4?oz06}sknIoXqQve4
> zr&tP%n(+H76;*)~J=2=PF~$%QNXf2lKaEzAyPK@Ye+i3hEibZHMLznbSdkvm7
> pcUq
> z|Ky;^-C>cRpmw>&-
> F6tbP<T+!#OJR|*ePnhZ_B)AD)=seTy9Br6_*jRpP=m<8HfHa
> z_TB|N%Iex1pIpEJ1}0$8s9d53MFB;@3pWXvQM5*rNEEN2MLUhC6lauL!o^8S
> hG8si
> zNlPtOte4UjTeTFiB^r<e!O}{VYTCwQ)YR^Aa*nahDFe+R-|x5f-
> tWAV1hL<DzUTS=
> z&+|{7_nr6M@7jB>z4lsbuf6tdKf@nDIN<k}t0)wQHrW9n6IJMW@^6DiZ6f4V0
> $JGv
> z`L>XloB;I%pQMi+A(5+TrK!*lz^mgbQ_;!;jQ2j)SJ0c6b|%~Q3G+SBFiH++2%&<!
> zk{C9+pS8@76mMPuw<)?bg}QGnNP`PtWTRQdL>gb@umGkA$ic2cqkkPtHlaZ
> o2hPdJ
> zn;c{K#T(H_YU@#4PBBA&iM1!wG|~)nr>(v96Ehg5%M+fcJQG~Cry+ymU$6{w
> ;aG`*
> zc{trG5>eF2q&GE>?2`Uj%EcpJw7Hy@nG0YhsK>^;a?y}F7vYipXQy+)8RupaiK-
> X<
> z<4xu#he5E#w-2rVhIoj5ZmJl1z%}iK{B)>mZbPNXkh#?-
> X?GF7Psb9GGKD=6z%m#;
> zXlGc8am*RFI=$-
> r?rL_nFkP#Mi8j0py4yN0Y<&m=6iTSU2L_Q3__V1Vm?pgnl>-^`
> zN7#pD;7iC5O6`0;|CE_~BQI~kx2)wjQmIXCKoHd>$2q3|0XEKVG^G2Jry@v7*`
> ^*O
> zgj$TlhxNBe^?pxiJmcOf$;H08AISmQzs-k3D_Z$w7{3Hs6XyaI6bz#hl`RZE0t~4J
> zh9R8qrxMN+*{%^PVbBT84h`qd!<<@$l*`rnkC-
> <dwPzryokz?FTU}*pO~6|hILx^^
> zXu#N}Cr7C7K>6(ToQsz=rQW(yw8@A06*+pUvY5j&L;?e0xn)&3aT(+3gexLdCg
> VT^
> zs38EXt9+bPjPm2HOg)c7L?XM3>>;^0<sR)+GrylDWok~&LbI3^J_)1$Xg8rw+LT
> Ye
> z988{_9Em9w{|(<53^(tf10wTn>OZiM3^Jee61J5uJtR=-
> x7<iyxCnALYuQlTZ{~aw
> zr~ycFR}!riln+glWL|Oz+bGoJ2jZvn_DB%+(v3IZe8{{(`$DC$us2ridui4$Zr)ai
> z`O9n08rZhxgwWXo8$)MC_GCr&W=;L;lKxXad?-
> 8nqp5rG^ctS_Ol=Jhf=wR&{iJ<U
> zTSEh0hP-w!$;RneJ8!vt{yrJRrQ$GuJ>_Ktrf#PPxqDCPqI`Hkhca~rDobW|iOlR~
> zJlDC<J<^}!*hdE=Gp5VQ%`>X9g40){O))=c&$@>%)s_&>a3&D>A(?rGGlR)Qv=
> o*P
> zx8kUt(W5QVKtU4LQbBh$opuj0u)2_NW`dgHf<I{+3JF)J;jU$%V3i#jY|!)94n^*!
> zRX5Hl={DJ8pE0)xjYUz$InYJaS1OA26lmzR?#0YSVA75O33d-Ei$Y6iV8k6YLR$#)
> zTYf2VFv=)ah{V~BI0EZvFOIGj+4KRcZ8&@6`nP6Lb9#~6a^@CD$(A)8(b5sN^gZ
> V$
> zbPo@K+#)Wpd`1|9=4zb|-e9n)>G};lj>OqWR#OMdFbeR3Q3BKiNZf-
> 8V#N(4<^8o)
> zpd#{}R$7SZ46L|BEAIG~wcNN(<<zO_0=^?nPofdu<CTp<7i$6wL4G6=F?fPwY6
> `PL
> z6Oc`oJbSQ_%_g){Ri5C-
> NFi9v=WO+YHaDzI1b(?UQr(#SfXQc`<g*9!P}%WqmK}nd
> zG1~9nHWc&PV1VIiP8Oz1VRlPCnr!`P+OB0dEgbJ~HUnUG*0iP-
> reG%^!Q?M>A!L0p
> zS<hxkR!;l{_ju_Z%n##0YqK2C&@35Y_6f4oDME)%z>F5)p+8OgJ+iFCyGEfrYuY
> ZG
> z<$5HDEG6+e+_mwlo2V*eQRLYBDpIYqeZBy2eCcr-
> xpJRIuC&$vjlT&eV?S`wtk9-%
> z#N!T>1q_Dyl&w4nQYvR4QiWX$lbOC>g8`Z>ivg#zB-
> mX@{029Tr=AF!iD!$9uMSK+
> zL(omQ$vnBtgVS5wsJ3WS+hk|#T%2cMQQgiC%66mxRJYp>N^bHxOph;Zkv@
> f;ipr)n
> zjc4d|w0@8@_Eb2{t`*ODc=myoR8JUsVxK_0*)5$znXb3TJO|p$U~B0?SorG(9;
> 3Yw
> zdl79oY(Qxj;A@58<MfU|3ap0#Rh~VGCp00(y^#Df3<wy2oUxJ70vY{1o&NTCX
> }h|0
> zF0?>(o+o^=nXbUVvn#2bTN3%;P*-
> O{^Tep&?ia<fpBY@hhitX<EV03?;DB#tsJ1g)
> zR-1+l76V)&tCL1a44hl4E&F!06?lMs6HkIKTq_=I|7C>Eve;(XFEdN&zkJ1=rH0g5
> zGO~JVq{;H2&2pAxc`$JvviubTr&Z>i)+m;ED=grR&q*m~*(|>$^QH1_DW(5%^
> mJD#
> zHKfjxk<~<-CDzZe%haxZhea7M4-
> &rym+}2S`Hubz=s$t)|BiQz(z>RC?YNI3h0#fL
> zTH4j45`TYkIbUAjiw9$zU^Y7)nvCbI2xh@i;lKkVubgiynYx;qVv4jg*mnt!R#Tip
> z><u(oOp7F^CLY#}gBo!T{BEW&L_&AFSW5Gg?o5OWGEkqjm>Kz!1<8|WgS!g
> F^QTcL
> z8oY)di*7J&rtx*SdL&xHM+LWUmHN0TIFAq6D!V9y>smbF^VEHXuKLiB!D4_*
> WVPuu
> z9iyo`F&9lZC`GTNcp^fht7gcIm@Yko*{CY?r{LDCYz?2NPIQuvAbvjM2U^Dk+Glj
> H
> z@OYMu3i>p9_gM74c%}=zAc3Ij(0i*;KgQHRG`tdV3Ci^gDc2$!@mzOAXbb-
> <<yqzo
> zHOwl0a`WMUXIj54xQFv&gZWmjPNqS!JNGHRMP~4hmh?4Ih8O@nH!|aS28
> B*nzx%3e
> zReGWdjJAYgX|6y+n)tTBx551YlVCDKRxv~;7rr$3Q@jQ1h-
> `LMu6kM;%RG0MVK37<
> z0-X^XP8{~)i3v#N;Y)%qW+d=MlK{V37)gMByeApTb-
> PGQ$|xt!u{${FO)McS7Lo-C
> zV5!y#CQdJb0v=0<M``Og(aUhBJb-
> tx<itzrU#rIkQ_k2R>=(M9Q?cANW$M98nHsz?
> zAjg+EhpAKMFmZg5ns@p-
> EQB@Sn1>in#Y(=O8_ivle0x<jRylUheBi?1M?}t&3$W#y
> zC>82g7cp&Xx`D$2DWPK0NwFPCLDO^nDQe*b+=z(3mYrz&>8in%ojB-
> &$aKOEnHK0=
> zHdS!UUWG-
> B$bNi~y)2VGfMGdQROJfql&L8h2<TdqQxSCe13G)sVsFVBa2Dto@S4iN
> z=$_O^aulsUkoB5Ngi;O!ct@r`&>K|qJ0dX}#ju3H@F2%$unGq33e3yYGWZbm
> #CzHp
> z{u)jRhh26$BT>+`_$p{{W+x5lRq5!oAk_C(v0=pouyx{JhGV;RTxEMsrP3>oFdto
> <
> zDSFhQP0q}F^GtCnD)>y7Ne_ZY?ZS@<!L07+4i8deMo>Q3;Ur%mlZ9B@V>v=x
> c_@3C
> z4s*&51GvX*U8CR1h4Sp#X}=C;{L}9fnd%9BK|3e9Vnb0lZ<+EvC`uFN4`$pT6rc
> UC
> z__8C1XJD=v=gy+b;D06GTl*%~Yrx0TkCL`Cm5q+#)9!cd5h3lq?XQ_}4dfyAyO}I;
> zgq4eGM>b$2bU`}BilFa_<Vt=R{I#q0FnNOuxhmA&ai-
> EZ5NZ1$1FHt8%ktT)&lNL;
> z!h#a|Ysj`ppVOQk#pu4&JWQAN;BHsiFsVS%`*gx|g(9GX1iA#=@NW(`O#UTU
> q8WUl
> z6VyC`u~6*Sv%+w}8b6Wa@P-
> U9K}I^HXdQ`rP`^l8%N4|q6v}A7MrXED!403H6(<vb
> zLzAZ_3o<`rFldPW*3+L;)g7Fd9)F6o7n|N}Sv=6W@F~QhM8W(zsNRJ)*i;RzF#7
> LM
> z&Aup(W^^2?`{|v5K~nG&X(;XpE&vhG0A^|P!WtxiDN*;HV)Z&qW(^rEBh46D
> J&`Z<
> zX69y^u?wPc@fT>9>`vScwJ-
> BBhU1>S3>~NZqU9Lm5VKh9W7GsBaeK6~DN@};tjc~Y
> zSlwx{x(AYzR>XuUQSV?7#951~AvIQvtOi)D8c7)!R+~VaSfDY{B&r+}S32wnLS=_
> O
> zYqbs4DW?o|uoQ$ZtKve+whHy_>x>{lQwIQ!C6=7{(jlFwj^rCyz}FT@O~53c(t-
> $1
> z1>+L0Ua2NWFtNyyahR;wI}uVUT+D>ZRGX}4;w%A>D}NvgLT_Y;9J<2uR|0s%
> @uKrM
> zWRwr<Oy<hvd+~r&^1_#Eq<>&j!GbLlgOMu{8Ar;@3y*Nh+Xu4rw02K=^H7+
> }m~?vA
> z>h!dc(~Y6Q8+5T}EyJ;~7#ui!^Kza#iW1(jY>NK$@QR80(;dr(>rW4_z}Yce$^@H
> n
> zYw`qsjh1eWRc?)Zd<o8+$53n#dU;wPe@S){D<MHmbW%Xg1Jf!M)+h!JObe*
> +2-pUK
> z+my=ohy1b91OA_v=I4~QM@tWIL1h7tZo{2Dk!&vQ>{Vllb1A)$Wd)n9gW0_A
> #lcY&
> zn*NlSO3NHcEYmFD?jV?{0-&t$4NM*j76$OFb<B5q2-
> *$++2I)oK%y%ioUAUw;L2Xl
> z8ThOtu@?EQ8@QO*n)g=9FcxDOdBrS44%`?hwB`p6HDk03CB$@S7c;+gC7Bs
> >n4J+~
> zQP84)GW80(W{RhELyTOSMSIA4=qq@1({{DiR}br$qOUSOLtowAD^;C;2At$Sx
> fi56
> z|Mo)hZH)?UDG=#j7+iXm=%jlg>5lZHse;`mqh7VLaS|FBv>2Ex=3DjtBcOHoEVT
> o|
> zzt=N>goo{gl{QU<oI*6q2X2P(!&AePScWa1u&$;^#Uz5RDa=yyMP4sNlF>2~;X
> *{<
> zNC`e*S?tyLw6|E>FeWgM^Hyar1uHo6G&Yg<k0Oic)xP8@CSYHo4$xS<3$15A
> a1;-a
> zHsUAFtI5Y`b2Q#Eoq>pt;Rdnci&e1?#Az&?5=eyxt4Z=wj28}Wca*D&*QM=5%
> a8Ft
> z3>3b2kM<WBdU=tCzb2cQfEoxKIBt&jtEUH3V^{;hO`xEy1O;YJSAs5V-
> Z(B;flC?G
> z*XzntQLNy>TY;>HMwu|j3R5va9r_JHK`z69NALC5nHszgoyiAi9feNE{b=YkAie
> W2
> zmfm+nJ{Z08gZ?@BaanO+nX%%Y3&$hx7h*Pcw)k*3O8z}57$@AyrUR{KQW1
> BDPcqe(
> zQJ+aHoj1#|S?t+dD4!e$8l##~&*_!g?XXSY@oxv}pyf#p&M*V8SQBSqv8X<rXr
> =2*
> z>NN>z)l0+E9a@nG&es5;p_*wY*&5B9nCkY2|KEm>v=`oR<I8L;UTH*Q9<Ofw
> `!iz6
> zfsY|#=*Xj+2Q4ZqxV#}?-03O)9tK7@i-
> yD7Z6Hf42DhhU>>N`ku%ysymK5sp(jJ9H
> z0;a|Ob(p^bOP4@ccj)?#^@eT8U4X{;2$Y+qTZaFh>lp#2UWJ}Sy6N?Yqhz6vtgti
> 7
> z8eQp|{9l(gtFQda)a@|1GP8BXhwEzqiU95&fbpgOq^0TQyk&TFOksfJvEUb`;l*
> ^e
> zYc7ukKUu?1dJ|I-
> p4b)JWpl`c?>SnNnZKc@@Ks;=*)%O}`Rh)9ucuwt$KF|5#Z`9g
> zolP!*va*w?)9|Q|^Qj!&_3<d;k)CN31RnlIDsIk0)j4>%WZ`OYn3Sn~pQMd=R&
> %-f
> zF6IO<8ED4YNGv6@%TGa7NUz4I6HMaz<N>kKlT<uuwY+y0b(<*I%(bq^EU)(5
> %tAk-
> z3z5?W23PluKN=y-
> EAwJu7?cbbpM>r}2<N3^LOf@z<(8|zNsa2IM(mwcsK!6*VzE79
> z;ROCv15XH1Du{ZrQ!ezGXG>k+oFpn<&gbHWA9!}jlSAKW7-
> 6k>goOvWkB{PYy-*za
> zc~J~4v7|pPif(r6o8N?jm{*UbvGAZLZqsB+_culU;a}w9AI$ad!a7teEbq6ylkA$|
> zj!viVtbc}YkoB77+s0m=vryS!mBG)~3EQ~z%PU}{KKNPVBl<=C`SYgF_0@s{1c!^
> ^
> zHR4YG7T@1sPJ!TC@V|lYkmKV!&f<H#^og&)0N*Qm;|sQ>epl0|lS$vA{|$U^2
> f>d+
> z-
> _M;s@f93^)Wt+9%|D!v{1!T`8T%u3+G(5@1X41SvqN{KrIGF@2WrAEIen~HQB
> Irf
> zm2M0AiESAB*W2qvj^u`Bp-
> sektSqidcYn#o_JZ;yCp0P;93;l=<lsb*3LWlsgWYx&
> zHcXn$H4E@PTq&+-I}=*bHc1WwGM}6+$h-
> !dWMSsCP)Ej$zM4ooo*wr7Q#0mo*&!G2
> zOM=SO;AV|VKQ}5eR5wF?Wq_-
> fts#T!0Ul&z^;E7PZ^mGm)vRgkk+dbcfG*$f;Cpdy
> zWGRduEZO6tSxh_l4f?WZNMWrJX0XI*O*FBH7zQ;Hmq3NPG5&~+i@MNN>
> _RVi8KM1z
> zo`an~5WKBq=t%U+LYS+778>3qbeT9E3-
> &G+bF?5mL1GKakD;ez6}p*SJKr}zgPNw4
> z`e-
> 3?(mRGjnfN0D*_<p+4njY*Yf7b$lXw$Buo7{Y67ZqZ&hawL+h|vF1^Qrem~kO6
> ztXRS_Cum81us>!tm$_9Y68W5dn0!b2-
> biX<wfL(C!e;_x(Yc>m&5klSZerrUzyrX_
> zyXr_Dx-tIvZ{$7Tov{EGkdF7J1i^$oT*a^<j5>jz6CC%}kvkmdr)>g9(!l(hh&jpJ
> zjb4;a`XMKQ#SGI)^RsLg%8X`w<N#moB+!ut=4aVQQR8tpm_R2z!s4-
> *K_+E9CUTr)
> zK5~G$qSF*44b9JqKgbv0arYpb@-
> 7J?Jr*;}B#p<!W+$1uVRmXfIFc;|S<D~<jK{>+
> zoMb+7fWPD<(2<7b=R~PZ=5AQMI_0TO0^IM!CXL5Lp_5D*>`)EOuASg<GlMi
> 9{F>l)
> zi)4#chYvWw?@1WB;!kO4eop+Gd;vWQVg2fqIb5O>IG15MX?_+}r^#9jPm+e
> Nu?bww
> zAV>t5iC>fV=`>m~u2tO+PMG9vI_k#^&~W^gyh2KmS75;|*6~hdfCl5Y<Y*>w
> s!rlm
> zu(th%$7Bw^IfCMDuc6Pk_tNLbT0dMhL_KsyPbCgZ!e0|d8DoP>Frx>qyuE?eV
> mx84
> z6xPhbgT<j5Y)S%6?~UbQt0rvD!OeJ}+_eD)A6;>!7%K25(1X>AO$=z!!H2m?Yu9
> <f
> zv3$r@KRUss=#xKSlI1X8Jvu(LUb?Rj_0Vk<{t$Ka^y4XftzV7?n|smYSo{A`$+Gy
> h
> zSAo@np0T|BV3sHN{G+qb@ux~ee+Ryu5BgD2V_Zp(nR6P^NW?%XE7VDCVz
> NVt3sG7{
> zi?-
> G_K6nZ~=Tu^h5$?spFy<<?<&?JW$?_!MK{a#~W>kYVnEkaIQ4LjI^+Wi_U<*X
> `
> zu7v)YTGkF`cyLtb>-rnjFD++nY2N}j#SZ`^R1PlOj+Utj^hTYb6~zWg*=%rPv?%v}
> z$@ubLIYhh*Fabk<;=*k_V#|SCCd^eQEz$B^8rv;ck9EDV*ReFW?PiO6W)0n{%
> Y+>)
> zm{sqF+15|0SN(hjzwRAvGehxEAYEZK>-
> h3n{CX40{u%sQsLPPNFq2;~c}e&+NOfXa
> zwo^CndN3gQeao`%Vn-
> D**pA7vU(mQ8%SN&7T|V0B0WXvL;78Ag{O4Ds+0gBTR5x=B
> zVRwO11eTr!2YcFc$J&3zlCSm-
> a4)#9YE%Ys!SC2Q(O=7Hs3HxJ0WjFE0hscyu7xzp
> zYzZv`XY36eWQ|lEmE{`~+h7Nswn*Gr*f}d9i)^`$`%tSR9^9s*Ri@Uo*1iex5P`t#
> zn#d7~N1!by(7Fez?i~og1z2Y17J#+L2{T%lq2XsW#DX+qQ$ln)Apw(#H}y;~MG0
> 7k
> z8%5Me4knG2t0pXAkpazDJ2m@*R|C!LT7Nz{P~63Zqi`r%i++YZoGAx$M+(d_
> <-i)K
> zw*D^dRezr$4=;_#s50qbYn4snWT@;h6oEMy5T!ciUJT=0$dA^~$v1kTU$1jG7S
> ~$r
> z_wSF-?!M)<_|rwqIKHq5bBorL6nU?YHDlIpY;KYF&@QkmM)TJU#K`8<--
> O<%*%vC;
> zf#Kw!<{M+L?ffwBhC$7-fv<KSJ-
> R%$Gj?dwZ*n?v4o5!ij&yWSdSlWa3^QWyfvl`m
> z;Spo_6MBn3Sz+(0kC61r@b25^-
> !iH3wb<;gsjr1Du4xQ?GWEmI*)?sUzwT6d2pW!{
> z76kQ2(81()ZlAAlo_!SYUW?EEZ~fE7ALIW)dpfUIeQY>p{|KX0Yz<Zco2q{5^;4vB
> zAkUnkem_FIr)5@`o{jhN95k<L5h6j_M?kvVQXVg@Q#--
> Q{Jja5A6gv^zYOp_YOA06
> zEB06bLt<|esJml!g{0Di-
> ;Do&%?COFa83Gz`Qhw=MFZ(_`?>ZO!;V83+$;2Hy5o!g
> z;SzLq#Z!T%2#fcz?+JXRm~+l;z4$3F%3YVR;}`oobZB%R0IE2zSNka}|1bU5>HP@
> M
> z0(EaLaMOD+LN@3caQdijdQ(i(^KbP$LTE(v4eL}H66CMKuS0OG60#dhSUUv!H
> |iWd
> z2f@?yLO1+6s4$Xf=Xh1Z$AIstMPP#1VBVvHgSfM|9pcU{(cvL}3V5GdjNfGb-
> hTY$
> z-`;-w!ato>bnpT~R(3^)-^zzT!Bb25i|x(_FT=y0ek*ZDxcGYV(|g^KAq2lj`<!U$
> zcI-5(9$!Kdbf|j#MrIH#*oChnt0(y^CoawmUl|*&-
> )3h;QpMp*V;b|F*}4eaZb0RN
> zX;IH*!Lmj;)C0|BY8aEmG!ka>;A*I;2X(nc`OgerZ*rKE6**iK4q#4p<$(%y@2QN
> $
> z>Pe|th{WFnWB@Zx!=oj}Q>0qFw5eQu6Y|0=2{W7-
> 4Cl0E^{^}W=+|`;&q@+G;Q<g^
> z&YwxnWTbUE;m~lk=ROaYAC7#IiKEn*4LnpA8p|6x)H|@nl0L3~;M<RpXk>=e
> PWVCw
> zY+jCl#;m7UO;uSz%6V)sU&_^O_Y+49_UwpN?uZU&BoozN!^QVc609sXm>)2
> wutV)Y
> zS}}pcP%wspG4zZ%KA;&UlEA#d6FSC);fa{3AxoD4qxN_TF{ehH01Dx0<Fj4D+LI
> qA
> zM{qyQK>HeR9k!msE}U5O#CKqgvFzmIh>nPBvg@**Bql~y9e$zys45HA@e|
> m(061c2
> z)eJaMHfjC}s&C&*l7{9yN!}dO{T@zr<rC_eyHa3~jrANG&ahRldkP_e@=PK_Pp
> PNB
> zLJsyOwt=q_FW{z`PBV|cHiQtVEYh8o=KdW1f~iOH*39q>VbCv%DU+L7!;DE{4
> Ch1g
> zLvFUg%+EHNbFWjZJS$fh;{mM3RcOC?n98D)kBh-
> S7=h*Ee|=RLC_m0A%Shobi#7U(
> zz-;L({WS+D#gd!UQnA106@<iTrQC_GsN~VC-
> jUS&wLio+|F+>2XH@@vMzASe@zMie
> z7p2~<#zJ5|<fFstPB?U#$jD%wC_tLkrxD}?{NjP_Wx;tAQ)~^(5A%>ntVw;-
> rqu+%
> z<T)C2vju%#KqqL>yDjMB0Ob_A5Eket^$GCCV5WKd%GZQ?YJjGVj}X<M9=PH
> ZOQ#0N
> z2dnuFlr-@;ZfRm+Ge#Go!Xc-IL5jfwX6s&^aF3)qm6(JlGoL?5KH;(P(oO1Ra3Tn>
> zp<KN;iX`^h%!_sA$x3LBfYPqV9U25UB`-
> _*Ia$rCQV$A}$q6`f+@gd+4Ao!%WWM^7
> zgJnsr+NT3t{#RQla^uxD2`bZ~@NkJ!u0nbvSLQn{S)^ec&eYTOy=Cfm!iVUcd6U
> DF
> zCn6aAH~358Z$P;i+|ylP^?lG;|I_9mlb8sxUV0HmsRyh$zekQ}JcJ%GX=~KQP<c
> o_
> zF%9`AC=3`1Rd>Lav4uf*cV_rb3O5w<=6oSDXx^!ot#Sd`h9k?geW~KmIVR(ejS
> yPw
> z4*l`8eTV)C{ROt`RL?$we4~)1suP1DaITJ2p_ZdnMZuxEPr`gdeld)3q9}#rl&ZnO
> zg@l(Dt6W{{z!v~szDR{eb`3T<fb$kXO<`ky4c)S24fTwcBlT`jIPIaTJWP-h2^<9O
> zmMsWhyq>*`Tuy<cR$)*6fNWETd4&gr7VB0(uBHYTi0E~yRd@~FDlglyXAjppb
> O5fg
> zT)k7J>$6EUAa#iwg06AJ4LETtH$$MwyxjNa`3m)YC+;d6_fp2a7E9~$z_sT&auhj
> I
> z94@4QY(Nyr<PD^12&lCxrsx$1sT(0asvM1^fNchte_N>!t>h@fAOYwB)B=|6c
> UG97
> zB~&+oPEn|DLqNel=s{sw#^L6FrkC-FJ+i8uZa-G^V4y-
> *azFg;4bU*7^~)c@3$0%?
> zUI0zrlU-{W7_H5xl5gOBzJK-oCm_=}U;Nv?x#N}+4-
> S#pgdbf(rAw$q_M`^{zr=SD
> zC0^R9zW!xfLVpby7!~|<h5F`+tQD+?oE{Hs#QGDkg0^p3)!R@vjQ2Z;K6Y}99KI
> |(
> zu&R(DYf%YR(8aCl5j@%HRe5`|vuuH|?=6}QtlEL5`5B5$Ir9S#jb@{}d5e~|P!+^0
> z*H<XaYL`wesdh3NWO!_hY1FB{i{hX*&b3ut-W@q|LHIP*MirJitSwjIdV_qY`XiJ%
> z5xhgk@(~%Pn#Dqy3LI__d$2zQaSU$hq+_}Db6yE(&iENPEzuvJQFo}(OsMe|s
> *X^t
> zaIe`!hDPi2P)(U7jx#74$9@N>Qr=OeF-
> EHAi+|fAWw)|QYe(QmCqyrt2)eG+S*8`=
> z#YjeP&+d--
> YMX(GsFiNCP>C!0{LI=|X$rjx5Q))!f^nMUO#tKXst|s;cLbvT1@vV_
> zGVw$kMzCQQE@+@-
> yuVB>1%bdh@zVV&4w~Z^`z3qT3ntF6o;mFxzJ&M$Y{^tRkYGlM
> z1cG%o0VUEbQd6NeIV{qyI;AmgSIa;Yu*N6~*<x7e&<MkHJ2uRiEZ;`rdg6~)i1ct
> +
> zXZkgSCr;r_7HhZ(>SX^ju#82FBT?Al33y8~zc9&6cHxc<a3^9G_fpJ@?drG0;IYP-
> z1cL~O4rPA43*`q#wyW!qycL^h+zU47r3V-
> ot<B}9IPVd(a{8fxuetu!mw_>3^?ZRo
> zcpl6HfeP#{Q{S4(T7ezIg=bzU)y}ebJOrq6NOJu$JOGE?Dv274HK~QDZ2a8DAJh
> mZ
> z`X>5OiDAlA9Q&xUGK%rBYJ9wYp~S6SgdgmmiIE^^5yX8GDG^p}fYtz9d@eJK
> *WXHT
> zHOYbds)bvu;c82mP&|GO!POuKuH3@SA>29f`pHZPrK_FJ2<i@j^djf8E#xRdVj
> oXd
> z(GHb|U>4?^XyB96xUWCnMB_hbzHlHcd3vAH_7<!xMxG0h#NSBcJ~?FVQha
> {P^*K9Q
> zixq?2CQS@viUh~%85pf+_dU|UJ2qg{4--
> SDC$H72B14B)7zCI&{DNzxVclA;IG!ld
> zwpEP=i^nUsiiBQ%m&W&Lf{U3q)FkjNgd`^7mS(jSy$Dhs$0m!_GB8@($xm_K
> BZ*m2
> z{m{VI0shs$p$e?$3)Izqt*&-E>Iw^yx}iJ^Uxo6dbPv5-W5k93Rx_p{;-y>EC&XFk
> zV>;0n#cRh)-PW3wqJ+ANJeh_n4rf}+$%1&i2$9Ow0=-
> ZgHM~XTBT}$VXtqUt3Dq61
> z+#+;3ZJ}V5Tw$%@k9Av~yw3*w(FELP1DZ_0H5^C}4Wuai0klnGNnWS=C#*(j
> 2Am7s
> zSr%lI5RZ=#Y(BU{>Ph(Riid~*ObL+Xu`db&G^eo!|HJD`JlS(gJYy?MJlEp764$-B
> zE<?la>Hn|&Wo2cXKNBw}H|H3C1n9R7`MiVcAGk)|P~!RWO(mYy_??IA$GFb
> C5qROc
> z8sWa1OFR>ZlkZ>qgQJsw+1WV~FW1+vU;lotzZ1Lz`t=()5W(_&(BF|?@w^hxK;
> &t!
> zyO8&4T>Q%dGkIJtAmjhRjBxFl*+}YIX31!PX&#<-
> tWWc8tI_ghsU6t}NCVU7APLe?
> z!SvLRb49OG%fgUu(Qi(==**3>auzvUOt(vBr~D80E9|6E=A-Q_=yv`ljY4un2Ksa}
> zkbQ0eTR|^bmxi%7cY`Q&0X;t7gJWzC$@40-
> <2;AsLujycrv93@@NShE`Z?&c??i}y
> z+hFOJ?+cAa7k!m<(P79L_r+fpXtIoj@?k!-XTkLWVx{}u97g=)cFXc9bv*<SCi)>X
> z$fF5WbxXXmr9v%oflLGlk+sO7JL#{@cCd3)ll>lz7elgQ^}I(uE{f`h2ELB*uYR0r
> zrj{@MZFTGKpe+?&i62{3_D|=B@31vho*g+dGhES&#_`JiXk%Er2g}rXoyZ9t(I!;
> _
> zfrluk)YsT_SOz0c_0UGeEG(5x)!FgDRz%rdu3nPO>0oIuh*$2YP{G@TOi1-
> Ub~&5W
> zU-2V}k3!;driDh!v<EuHjYKOe9(cM;9qO=XJ!fOK!S+dz3!DxP>>;oU<Lb79M)tKj
> zXUXeD#4uf(8_{f{HvM8I=^k<of|3vQkN}>l5wE4`P*!zYytIb<re(z|*H);z9E`qC
> zW!a?iEn;6lHmKyR<hkN+jMHj>Q9whaLXDbBO3-
> *{Lo`9_G{7g%)3CH0bROE~P)B9+
> zMApYv3!j7mm>7&na6&RT1mm<0RyOdCHda3rhi**X$l5FY5=$ELaaWj>8Vz#
> OFkq>~
> z2+^#pEfIi-
> 1*7({m1<Jix?t06#!HZK(w7`qmCd9M0&O{Tq|~dngUUuk*S$2q#Pcbx
> zY+RQu05{_DWaS>~FFV(M%h4W4qu;z%2B0;DYBh18Zt#<Hu@$v3O~h+4sYj(z
> ZDF~<
> zB=813(Nz;@1Y!JJ^B_DgII&FT36v{11qkC(FWTR-
> s(mHCU<r0c&oy$moNkJ)r_st9
> zMP^-
> (E^JTM*w!o*nk24=cqguPWLzI_>|gsL(sxPK6#q9iA%qJKLRXr^JP~#N_o9LI
> z(aH@yN*Jr$0LyMY*a!O)f#+d;bU_56ZEn}4j0V;vCub&87p+{|E19)OrVhy*RKt-
> B
> zV#P|=MN6@C0G1=_we=QVhHpUAB-
> Y?&d@Gzzk3U;zsC{z=wXGJ&R=y@fwQl?q*C2NC
> zMpubvExRNgzih?1@SR|3!V9_T*G1T>u_^YqbRDZ%-
> ^*z_@o!k}77ce||0*%|icG?P
> zw}@D0V&X0cf|HTtVLw58*=FxAcj}^TMRel|nJ3i8p>i-
> =#F5jaW`Zh)xEPqox=C0l
> z8mLKP^&1@{aM_e@SEm39fw9UOY<fgr5oz}{Y65(fydgQ)q-
> z!*&{+EsTCFm==;EbM
> zm#ZJoGwH5Gx=!vJao!lyT^TD~sh5{Yom`{Sb=KAPAun97{%4dc@iuO0GNvXjG
> b2A@
> zd`?+$u2TVt^Etgev*E@R?L<9OS%+IMNhro(hO4&wW90On<RuQ-
> BiOjD$VvWi*$QkG
> z-
> G$vtZBTsfz*jLhGAR?VF3hN;<YP`M8R4uv0ngC`V`d{Jmpxz;r<c}mu@f(?t@Te9
> z=vsdS+^BQmVo7P-
> Vloy7A$gL6bJ$)YHh3W)a1d3TYFS;*z6ZQ$)8zMnn#5n}>*-;<
> zcwoa*j0(?wRHDX9*Quj7Fw$=I5B%;4U~>vfGrC*Pw<s8UD_$AHhKe|y8rhYp
> r`n~>
> z1B<LvhoFO#BdT!1o$WRLC6WG0`<+mCfDfVTPtd~*Jn<}sRnd!$s#o7aJsS6yG
> #TaU
> zK&3FAWN{D;1rym1x$?hqAacZbz}BfX=+@8!woa|Y6F0v{CZ{@;)XSS6D_t8ME
> CZW3
> zDr7iGf(m<z#6%im($(E4)gUIF;ooJBf4dpHhUx)ur+O6#?&(L{jB9t)CR85{ywOm
> n
> zwz6?-T8%$by+RvtmrxNqEL#*Ej%I5-
> lW553fqgs?%Osah#*oK=73XDen|8<UfG?DY
> ztAAM6>2n}K;xVKy&=`B84lV$i4m~1A=3%5$Y~V)i`wKQpx2#Q-
> !O%^NL1Y(jQP}E1
> z8Ax^f>9%E|O{H#Rab%>lO(mH~D+uID1ZL#(BpD}t{W?X?$W?zY7jC$xDvv(>c
> xj6|
> z9Xc=0Z5x}W_wsb_j#TgF@mX-Butd+om6bftIJcjcwk5cmr3h>(Q-
> `k?wt<Q89#Rze
> z8-
> SDpzupZGN9#TZ{^u6{EW*QwwN|y@Ba)~oS09|iWa+PHQ~mK>%gQ*6lOD-
> h4nMV2
> z#N#ltwB?3LaysaB1R;)iY=)qE6TgRXq`3yg)qT*DSVQz*H^YBDWmj+ibsnpf^Pwj
> F
> z8%AuU`e0g>_H-KfUkSivK*vF(f%gjk>L27F={R5DrJj4Ac&R7iN34$X4oPL;IT0b8
> z+m6=y(Y8&&R$3KkIDVs1O<WK7<fM3<c3Qc*3+IlK1L)Zb=1H%c?j!X$p_|lq?v
> U~&
> zMllnbI~QqqW=#JHSif97`435hej!zFo*@!PZWXDjSxpXtlkQ`A4}Gm_VLY%3wb
> 7{*
> z8X^$gw7fqtR>6yqx;3S%>PlDoU#VOfIWi&aTN8MsF0g7(;F0r^xqAYu&a=L_s=
> MN~
> zbY>y7mF02KKI%i5!od921@iL;{s7tAkSLn?EK*{Y$>=JC#p{<Meua8hyFAqJ>x8?
> n
> z2Y1(UhI?5&P5?CnsK(<ADOc}L>B;7`3-KY+z`G}Oa!ec9%<2XrgY5quY`{8>q)NgU
> z3H#$Ktar&=OMr3Mbe35m_!F{Z+#e!ta#F8Iv=-
> yFMaZ&Dz3N1I#zeXokrF}Nqzfi3
> zO}X;6v7&tO`Voj#p%T(5%Z=Bv9TMZ>$_kz3`Hc8AW42d7;MbIP*NF>jrMR%>
> ESsbs
> zuEvp^W8?MtlHMt;nwLzxKiz>ujQ3JKj(X5c-T{t|#d(h;u88V~2EOJ#v@}-
> F2e@B1
> zgVE!)KH{ZjYcx?4bMdYs?qsh(vT<?ama9`U;n=@-vL8h_aT-
> >rzsaE)m>#0jn?$&3
> z5ZVTufu1#9WmH$>s>kp_Hq14CAFK_=zr)JHD`rYS1zh}!Rspf@|GF1Dl2w&>9
> >;ak
> zJ@60V%EtBSq7u(`TqmN09`C>QmzAB<D?)BR@lomU+!NM4hJ2Uc+J(zLvj=4C
> 8E)z)
> z?bWr|dtD8ec?y``s|LgTgU5Xp)*W|a4RyXQ+sV3YiJt*5IU663@*`F*`^+xUYB<t
> i
> z#~yqdCD2F!{kNom*~4O3{v8s<&sF#g`*)0IB{-
> pG;vl@0cC31zuUILLLqR_96mUzj
> zRYyEtK&)?sw;s%Z9Z&@f7097qI+5ZGk2LTut8p1M7wFe}2#>Y~ndITUmhX`U-
> aVnq
> zdgXSS$qk^ATNl)Oa^T)t{(A5SuQH$fwKW4j2d*i`?gLkbL#Hz(t{ir7?IgSlSH4FY
> zc=v>s9TV4~23OEnaOJPYRi6B{%>(+t)s}RaiQR5u^H;}~Cx7i@PV8dTN~!wM9M
> Oj7
> ztE2kiEE(_obR_E>UYJ4|@BH8k!UCevpM@}C(nRU{a`hVnMQ*!)KCqIquSB|7F
> n}6j
> zW$&Az>w0H2u80$MyCs1ZpsxRP+MD!S)iXTOz`F+<^DrW-
> y0(qr*xrI1#JY|%Akx4)
> zxNAbzG4n&V{`JVOl?kA>`KxIlPyU)u@fNSdDB0_m>tb3*&DS_UN?FNbSE)%o
> j2|iV
> zr)bzXOs`TphFT}o3SSWH*hw8tPYnQ7In<Hy*Zk~ip&3%?gf@{>eu`9r?Ti3|9Yqr
> *
> zC;Z$sN{~<^uaugoQ0w)>Rcf5hq!{36NT?bsP$62EW7Jj#r`RA>s98>CS5kE~sYaX
> U
> zA=FD^(+N}w&FUurV<+;5@_Rr%Cclm9Tk_ka*5KC)FeFw;&q{m~2LpIX)m_p0
> 7E+b_
> zz>JYf)QiHSwG56l@J=C+n5@NkGr_UGm6gs~tY<)^fp^s68LUMnMW#7Mh6k
> BK?+h6n
> zY2e)xx<zM*QUcNb&|g=_>uKY_UY%uX7^QEA*0(*H=bi8^>L9~Szh;9Ien9O&
> c=Dd(
> zF!cdq*9TKGJkr3shwC6wL|`|=(+|jD5N0xvD_7%OnO#RD>c<PxCpzJc>Jo$>k3
> ##2
> zLvIQ(IMTp7DE%^cUQ<bvS}LTcHf~}<eP}p_M;dtN*~2}g9Oa^vqty|q+s!l}b^O
> gj
> zrjZ6ddBW3FONlV}squQ6G!<&?Oj|cis_Zt<x*%Rlv!zTeaeX-na-y<y)a%qz{lE?x
> zM1s}>{E_(*X(V(YbQYNZHFTLp;Ao$6%qtfF<*Mscn_s7Dgk<B3u@^pYeR&pN
> r~<Bq
> zp#;ly7G-
> s|em+NiPqGgeO7mD47kjB(y><l?=AcTa+B**k``9w_?W;h*oR>*=&$(9u
> zkd8VWbr7#@N2^t)_6XYEvY?`3h_@lIT>ajaVi+l^LS1gm7SX+ul~4_Aat{qgc9?u
> 6
> zGf%6$N&yb2L~C26VdR~2jN^PzKSiq1+D21B{6+nEViJP=h<JWxyuKNb6>6fvid
> b(&
> z4IGaJcQDc3EXd$U1MityVLQRyT7dzP2HwG|5%A6NGTh1(dS}SsNCWRkC&to
> =DoSgH
> zhpC}Avy5?0&5A#dN735bb=Ve!HQKNy9oAeHY?jJ7zz=G2Kxhm``xAPg__<#9
> NA~Nt
> zfPQ;L_f9+2FTstnBV<p(q4c?$$LCq1J~Ro#BMrQJLbEe9$s}688;BHVPzU!*TeJ!9
> zW$GK65rExA7LoBlBsn<PXd0mEO0-
> 7Oe8tyE5~YpmDhulYEawp{#TQ6eouoO=S_Na{
> z@s*6C_DOTdL54RVA|e2LknC|vy5$%pWq724cU0aQR^D-
> %hRsZ<Hxn>8(!jeXgv}g#
> zn4r{GG(kmS!32Gpi9liTS1T+&dBT{aL+3}Q>O_UA`NdXwEhb6S8>7esoPpk{-
> U0xX
> zS5T<*OV^j1Kt@#qZ3e&Bs7UozoY;&AFfq2O+acER%I%^iD)5~6el82Fwa6;+kV
> QOv
> zo~GwAG;c?+P|Fh@Y362OebY3e!C{C*J1o1z1vxJ2hsO&65pRZPu|#9uT!}t39q
> pHl
> zCOeH9Vux`U5J|@D4zrC9Un53~%#5j>CuMwLswsWEjC_EOWc>n?h1B@BGN
> 90;E<>LZ
> zKZp1R?5<@t-v-TXouX8(Y>*jBB_3?JAcoCwN_7(B-
> NJa59LMTPY+^n3(ReXD(!hJB
> zdA^bGF7ur4kp|wmlS$9qpbv#>V8cjPVgqA?YxoOJMKdQ)p<%&|M!rTuB4iKd
> UTIPA
> z-JPKIOsfyf86IiiJrnbFgm+=i_ecZppM|;YSgd7iV9sBSxjX^$puzl$s5*17br0F;
> ziFqB<>H~9zM;ds~#Jq;^F3kBJY2e)xx~dnQEX{`*ny+MRV9sBSxjcpZ!AlM1KL)o
> Y
> zCprm*amYIjPc1o1!DASu*V9sG!p0(BZiBh#z#ogXmNDZ#iplUu1Miu|TuOLXG
> 5H>8
> z;2nzXyFk5Hj<%?_l0r-YMdhz9syu~zt1}zZ5^1rC$zL5)o<e6*@n|EXehy_-ExL?S
> zrWMWsDE{OKJ@KuWBCU>25g8N(_aeR?N2f1hwtci-439MMj-
> oGxic=R&qdN50RJfGE
> zv26b!Q|+zb860Wg-Ld^wrhN=O75qXb0$TD{D|kL(4`-
> psM6yo(r9zRLMek^eyaMsH
> zx{5m#Qxdcpfi(Oz58!?rk}P1peUOCVkp|u~`n$Ih+}+=0K%{|p<R>TG_OQGujV
> =RX
> z9uw#zKZZvdc&91o?uz(pw)Dk}J*9lEPFP5=z~!W2c%*@Mhy6*RBkY2ODjnh-
> qhD9X
> zRD0JggCh;RdqNkw$qwGZ)G;&>!6H^!?L<@=&VL6tStcF?y`{c$sb(+V=V>#pAr
> 5^A
> zHp3$gyn8~6($$QqQypU(K{D**kI6uEGR$ELIDwpMrYGI_Ez-
> cdCv=uDTY)g!SYfvR
> zkTz5^TRHSr;%2hcaV(w^X4ji&430GL?g=gKsaynMv^Oh(xU^lxOypDzMx5Ebm
> v#-^
> zdwz>F@J^gLQO`%5<AtIWrnqo^9A3Y~vq&>dpFZ6_)0tZzY{~FQ1Mi;Dold#2K
> >;L<
> zC_BEuOI-;7UB_?4@JIvilx3po5mXBV)kj5tY4ZLJF3jU#IoXxT0#_ysk2LU}A*>S#
> z?iN-CL>hR<F7fIs7n2DMyLO5jKTp^-
> 1@5%$dMmLKq4H$01Y~U`uwH@P?}D8OSaJ|Y
> z9BNPrXu9mQHa+>p`hO$sOM8vD&ktj7iY_d*D@OmXvMXbR(KW6#%fEIcgho
> EgTEm<D
> z-w-KsMxNCy9-
> N^)=60%|PI;xIjDde{P&fpWN>=Uj6e0{8U!ybJh25gw!;D$%d0m|<
> z@W)>ePVdrgA24DUj<Wh|cQ@j|%Y-
> <Hfkleg%r?+9ruzv*#Cle40*aN2smKQf*rOzb
> zgPz*Fp<>+gLSK<>TnOv|9&|q;!I|juNA?wCHM|_U4GfsW>ym@)Ou#+Fmk6l
> D$`>>l
> zYt`#W1%zth!S_G_@dk_U3g?cOwy;Pz;TlDfXoCsDSUBzqMYTo2#!5I+hVvBss1
> 7g%
> zYOE`957eX3sDCtY5GPCa_pjF0z(GvFYmQ^&Pe_GfSRe|0hxmzF;38-
> sbTAl&KK$eZ
> zJ@M|=aZr7jNCNyUEsjOp{k@61KZZefnT5g}hGroCA~bs9Cp4AP!;nS(+8?2};m
> k_3
> z!;ub1R5rH8IOlEblmwbE*Kow6GS{%vDJtBTDC#<0)DnRM#lOU&ZjhoT&S#*Im
> 9YCf
> z-
> $Za}SAvHiX=>>tzNM4MvPndk1nfSPCDG2Nz#v|p6**GYV<KWtj<)<B4RCC`+`
> n2o
> z&vs*!wnhq2zZgFmVx(4}k`uB<rH6Rf#IVWLvdb+N*aKtAii@nI>EY^l$-
> v(~#le3y
> z326aumU<s%z_GmKo(XUsa?504C(M|Ul%1KM3S0SiCk6lp5FEr|lp|mw7yl*kD
> g%`U
> zL>IwKolN{2n2Xa7k3|laV2G;(7cF<@>0mh+r%Nzf2SetMJ%K#wi7Q<3(V<HP3
> Da_J
> z#0V{`l{BgVBkzq?be|CA0hnl@(Z8+q5c1RVYWN<UNm<kKDuMz!NGcuJwi*ga
> )L)^7
> z;?X{`D%k?`$M(`xC_A#LP<G^omL$GMsdI!}(xs3`nu?==?ZC>)xm8))Wg~YArj<
> M#
> zLTa?os(mOeio4a8Mk^w;xY5e3vA|ZK0f{BF2Y?#c513oD^7*7j7BQlM=VPVMQ
> ~S6z
> z$|>OYi~uhMAd@o^pJr(FiT<^ZQy|ied8z*!-
> 1^L^S}Z@$U~XO76~KY2xjkCBB^KBs
> z>vy(9s<(Lkt7kHH=@u$62u7N2!-
> UdOAApDkHYag1j4daOCbkQj7_4;ePJs%3+LHGP
> zlOfuIr(=Pq5j|GAIfH95>t&OT$RtfuvME-%iCXl>?iNQ^jj+x>x`Cpl8{I0sZ(iJB
> zYmaCdR5!#*Hz0DXa-
> $B>?N9HTUvJ~OYJNSYVWQ>}eq!bjC4;MpTIIUWq0QI!*5+$t
> zm1_|>7FZ`-
> Ziz0EV3@1U&0KY{(mK#KK~~ijgK|11LvoSSq$t$|tjVtA&6+C+<uvtI
> z=$HUQOgO4Q73{b~X_J_Xb<9E?lTiCSOA$sRA+4p7bCQ?4m~#q_LdsOB0Oj~|
> a-;(V
> z?;6z)n^{pmM*W#}BSTh~c=B*<`MUmn%=||1o2)DGyo+x)MoT>R;kOo76Ry
> W_y?`qh
> z;lEl_;_(bP{$G|0L@zFJ1>|59{{+|j0Pngc<b6J_D{%cB*E_g8$C~Z@FNJ4eYBZ)t
> zV<|~)PON)Qti;ob>*2K}o&jii&&M?q*X6iw#Pwxd&isK$JC5d1<>P6l>isps7o=
> @M
> z=-
> ovQ)iH&wN6m<G;69rZLpY3CT^KqU_lrVflNXtZY$<iZOw<uN7T68_8nBwpWF3
> Re
> zn){kdz=D{4F%~oLWbXM>#qd;j(zeI!@jdWb;8!f+htC&CV+ou2fW?GroB;o|tN
> }nq
> ze{Y25HrtW>b+$xT-
> +*xq3;kM0>0vVBEZZP+HOgd}>yG^v%zg>2@Ude6_@&=6Esipc
> zoQ}+!)D8H7lO(0$NZFM@xYu%)JMC9c(Wj@v(|?}4nz7$Qp~1#xw*3nXzffb)X
> fbHQ
> zIpUZiit}?M<HynSMgDK&NAe%cl41Hfy9jrj=O&ElAsG7PrP1)$aE*{tp%L2mT|
> Md)
> z<5fQY>L%0``X4F?#!wH8)m`jO2!zB(J~)cGkeCSxxHyAw+{U)LvELF?&xaoz_3b
> &=
> z)^(?<DMsPGguMZi=cEJgXCMw%Qg6EgZ)V_(svNb`6&PUPSnU0?#T7V_fhSh
> =SKoC7
> zo`yg>V0IlCf=pFtxop%$I>6bxVXzJ$GsU`Z`X=-
> Nt_ZFTxSqqc3)dfTdHQGd&+ebo
> zKbH%`oZgq2e`ARY7Q#8&nGG?$`>dV6gNVch`#4~vQG4Y59@2u2d}kjAQ(rO{
> hb*##
> z(L@!l8CqA_wz3-
> AG!DgmX6P%p&kK!C>_j454kDA_%GE7GbeXyHD}3pJ4U_yb$_%bM
> zS;Uj5)oC&%IQo)2m1zZ25IlS;SJR#3lK1sU3&WYE9qJ1Jz~S$*Acb3}{PQH1DPOq
> r
> zeh9d5C#M)*=oB_t1T;jJe>P4N<wOU{=Rj!zH}t^99x2s|YPO`t(s-
> OyIorSbmt^M3
> z7A&~jTu<h!U5_7981&$%#}|Y*gdSW074+=VD&_BR`*FzkmdT<MWchwd{T2
> =cJs#7c
> zh7!5VR)__zLWD90-
> |45bxRSgqG!}RsITtxn6q;tR<*}xiUWM^tAVpeigD{y`+`HW_
> zQdj{R;d`Q!6=!mG=9{yZfaM_Qa$+yM%l)gLBM^^I{if$TGK;hw1(yt+PMPJimj+
> ut
> z6B{=Jh-_onv3P{VDjCj%K}{=l2arZh6I^!K89JQc*ut45T9|9INKSE4|F>s5NuHtS
> zo_!xJ3u16dgxMna94D%2yWjqHiRZfYm`jJN1J4hmV4tUrv`d5fY&NrV*3CsaZy?
> Q1
> zTm^W(=X0jpXL>dellNTe!0x|NDD>l$;P#c(?ejt<xZjNPgBJ9VA+@7Ogb|jEDx4
> M&
> zOGXufMX}A3sEu~8Z%>vm^Zy<BZ89(iz!79j^^OP;wl7MljUYGYz(0c^2PdsYhC
> qQ7
> zhZf*|bLgbxgTm6#2B)H$nd2iihGi#}=iu5}02FC;wfcxFrX_LdC-
> du~bWo|hg_>tQ
> zUzWj1R`7pmz7}ex__}V>lW;&-
> G`_7NOf&D0*yw}tu>2r6(md@OqkmtRsEf)?;U!b?
> zXBA_1KL9n|WjWQ&{+c90`ke3oTeb&AhOq^gzvg*M1t!KFbUKz!lKKA=dekHu
> K<GRi
> zbSrBaR3|JJymzXfqT$AbB54%R$Kv9t0w9c|%&?>GD0JW107#BFYB6$Hrmk}}g
> !%vq
> z3dRZug5523qJEk|h{trVr$Hd`rj@p1_YthJ>s0r_E=Y<w(W&l)ae@83KY&}&wud
> v%
> zk~(qI)aqADFqkP{a?>h&wpB!i>sZM*f)S*W{}Ux)CEuQ$Sapt!71PE`!6>JV7aR}f
> z-~>7Kk2AFzXi^)sic5}9o~vWPyrI3NL0eT9QEXD-N%C`_hIS!r@Lih5*I#o}E`Wu=
> z*wHL-s0YG(0-wMgg88qY191O7P{C4{LtG{o*bq^dM{%#-Fv7ojNH&rw-
> 2jCe{DCOc
> z>G%mAlrp5$YanN00ziWMO~?xjIgKGrCgcf*3}8s335hd=n}P+mn~<+D<Sz_)-
> h_M^
> zA;Hb&r3D2~?7?TQ4UV+tz<H8*39q_Pv;jWBmrt<HuSYRsm00<=E>gYjCjaWQ7
> $L9@
> z2HAEgNxTj}paEE+J8=^8-ej`-
> 4{%W;mmwQW$e$VVH*kG$oe9~;kXDA&nUI$l@;ipC
> zG$GG0WCue+Cgj@;`3XZ7nUGZsfrHQ5Bz9G|?2&RXha93iAD4n4tg1%XJ}^}Bt
> <qSD
> zs-
> tFF4hmyYC#PF+BaZ~V@K^{ET!@UsXjy%_ZFLed;HWJ!o1gAqT#mj#a&YiggIpT
> ~
> zKUwbdSpLA**;;iutBiM)s|hYNzlrh?%~LFz#t#4E85+%ZKvt-
> VZhvhD3eEbA2G(M=
> zQzUVD6!+@2;JNRR9F=Qfy%aqm)=NHqSl(b65yRdU>Q{wQ7%`|uA<N`lVxi3u
> #J7~I
> z$6Vi!672xk`;%y89oA|_R3M6bb)EMiY}#E1*1krvsV`wRH1s4Jt}49VmCQ@jg0P
> Kd
> z!UBQ{!fEKRTnc4Y@cz+hY!0Apv31i1lCy3;K!Fl_aO1L^^O2^W71yF(W1V28dH4
> #h
> zEgA!waru!f#K9gq>fp(eF4f~XLeKEv;H6x*f`BF{b}lz(v$9O*ldL9wPr&vBgUrH!
> z3O#;B!D1mwn>q=t5XOFZYTe-
> AWD~dw$;dDo&aOkS#{_>2iKF5cJxf#O9E}R~+R1=V
> zo01+~c6^{higg!0R^qu3R|&2ga0PL##`Q3+@8KG<vBa|(za#OBKiTCWXCQq7_
> #22n
> zFK+_}4!}MaZQqB_0hbroskp}Dx(rttu74nnk8$0J=Mb)LT%JM4|I0cK2sWL_$<4
> )v
> z6a7!{8qfg)2gbU$0^jwx4&plHapaYgW&V5bmXQtI|7qc};J4<#(^@<Gk6x;Nahl
> ZC
> zFm<&&@Epej5D>8<4v;)p35$*>R}`g2;>|X~(aQZ=3>(ePSf%@;r93<ndhX|pR*
> 5l&
> zM-FZh>Dh`OqZjSoP{C7P6Rn_rSjarQiS39K%tIiv`VX*h@}8jAy#701Zw-3P>l=J6
> z4R#8rw5vwGUKVUKuP^ZReD$YO#luDRQAd%sw0tdu;qtmJZBv8M+tmWJW
> ^APkP(HCf
> zFx#wMW}98XFBF5vO#%e_3i|VQ=1T1-L0<FSn-
> JcA;Od9c=Hr@$>r7l1;#!Q$L;m_7
> z{)3qd#x?Z`GM1@F{!=?eT%A|cyJ??CP%%zK+1>5*hbWw5ThNgNgNG(nd!)
> Mkgooz9
> zk%T2e3x5bfx>PD4rLLvOUKX5aUT5<4{N#k-
> SQBs_14cP5>1e(hhtectnk=^%a3ry3
> z*IZ#6U~EzsNnC*KwK1&NA8N9)4g9ngSfDRigCCbR#_lHL!M)b4v<}%(iBd1Mp{
> &#x
> zj%VQ)MNW;?KUw18^|ZNuf!|-^+HI~gkV`SH-
> qK^}xvKpDNM{Rzz9ih}PG7PL{Ac=-
> zIl0Kw3Qpw6#mn^G8)64fSzhSS9vgkwCC)yLW}*oVTRQ5;7sHF2A$H)`bHcYc5O
> AF7
> zW!PdC&!B@oleU1*<@vW=CoI>aS2Ft`y})SeDGt`9$U1o<1wta^I1v!kZC4R4JX
> 6S-
> zC<HKt;~?Verlm~<Q73RXL#_L3PJm8fqhdB)X~zD*Iwv+Y>fa$!X)=Z`qR_?zjreu
> |
> z^RHjlW-D4cu6q5TKx5dXg6#M*`V)wr#I|~EaJFEQbh-LZ4I>{P!AFO}Xq7H-h{at{
> z{2A1=9sWm+slYR2;CTVw#%ob;GKao858qV%aM7M8#{<uosX2MXOix4g5hbk
> 5*<7wJ
> za0UN?z6*NkaA1(yo-dIv(p`sjXz4apsGN_T(grq^sZP`AVf_m_UQ(bJ;1*)ib>-
> @9
> zSw7Aj+tkBITHU3S#HO(zVC_=amH4)@T*Z@GDKx1`Hkm3WgIV{B0fhNy8bD
> H-NF>pW
> zH-
> ic=GtR@@<Jtu}DG&nd54kS0Lfzz`HXoe>iFp#ztV+*+2XP<)QCTE|$y10W^WX
> WP
> zeu~)9+KG7NbTIxxlsqwc;&~p@cf|_VN$tekOB_l7RHl~^V!Z}>4kR}5(aTHron#r
> ~
> z4e7{%CVRjk>eCa2%=wxXLs0Hmu7Hm}=Er<ZFsy@^j?^nujkAGQo2ml<rxJ64
> NSUf~
> zeHlXUTXieO2gw`2RgHjg1QnM<ol{nbf>7tk)@=xw53WIgtGi_NaY35v{Wb5903
> xo^
> zAHFzafOpDrm(rLYz8}V9zVz(R03lgh=fVO*Z5839Z8b_iV+ur`dc;1<bmo+LksWx
> 1
> z9|4wtCk)7uQja0rai5Je9boYJbHECIU*=IRnd&3Ga2n}mNB|s7ST>xGW4(`@i}_
> 68
> zf)4FNjSbMX0Xp25TtvB4>Jk`gu(#=iRO$#D0^q&G!2|v)gby?L-
> K@jUAk4M;S)74N
> zH8N&p9!jrN8(2^8yNdmR!2p)broEfUk`;pwGsIkL0Cw6AtgJpTi;mj^vqRHxzZ~;
> d
> zzK#OR5!e`e#F_MPFPwGgkEiZi`TmrZJ28jVS2r*tG1*at@K$w~YnvcZ4V4Gt?#a
> sH
> zwhJjW1?<#A8z-
> (MOu)CtGe+a&Y}%FJc^VEgKy5jL{pDHM4Z<v~{)iSC>WEv_xl#C?
> z2|t3OSPnyzzVrQDo8;`Q_%&Gvc$BYcAF}nvyV$xp>%sG}lmQ6Wu_gkYllGOP!r
> Il#
> zXwcwbg<`?CcIXC#rqr2ma-n?EXGp0^8|<U+E8XN3^;EPcSKW>-
> gfQOeHcqocAn-qm
> zJhTT*>=0BT>l|6n16NqLR2Sr!GKZsnyy`kgyk!Jq^9nz#YUj*NMx6i%XR-
> |HnA=aB
> z+8?pf;#Y(X_Dc((ln<dP%0pQXmaAu_OPj~e&#ysZhz}M49h6a?uW1AlYmka1x
> s%$Y
> zHzTQ8{*AjLA7@2A7#G=f(zw@Q_F&nddU_ZUYF8Wai{s*e9xzw#B}2KP(;^M
> 6a1rzi
> zJ)|FSw&rVqOPma7^}rC(Za1nm`r%rpI!YsVe$@%;M5p!H$~B7E$BO{ZfpoDZ^
> $~th
> zvQ~8)sv1K!C)o4eB`^p&CtgNQYKW6|yV?bd3I#vEYJhqP10~YnVRJ8}UAhJJ*{;f
> U
> z+G}*$?J7&BJwVl2Z~*y`c5;FG<zT^Hkp8kw*sE^0kl6f7cW{Yh3hDz$Utp2m%rs
> 7{
> z@~ZPKIDmcu<v<T;3-
> E?av~YQ^@S!7GPOWg??;dr$zg%Hg2{bII<NfL#7%;ky_e&jr
> z7nMYDdlvTG=d5F5;IBOg)n_BXlV^6dai$AlV0N^BHFuVPb|kCqR@V$AU+f0^t
> rdA&
> zhO)~CmXE}krg1xm%U0v@WoV+LdTRi^Tm6nIs7YOEBQ2Lm?W(_yG@kyMxZ
> ctX<kgF0
> zS#{sh@%%R471Xo=6=}`$*Ypz|Q{bq%Dq4CV#`lQ!E2ViT*TeD3-
> 4)uxlPwy`RK3&;
> zCw}f$hiTGUl>kH4V8NxdSn5WjphErS=hjY%0Tqe13(>I02rxz?Vm4bH;!5_1{65C
> 1
> zROpQYyW7Thb!w8#EzmM9ps;vjcdLV^BlZLbEvY2ySa<C+Rjpg_#FlJGgJ+O1Ef
> %_}
> z$osx%yalz3<+ix{FqAMm0$|$~1WY`hlR)Cw{WHu8*OT-
> X4ydY)kXXU<tuukpnLHfg
> z17GBb4+~VyP8A=&rwtyG@=;(dxo2~#Dri239WS#x#pw`M-
> 4)ucYLS`%W*NX@0UQBh
> z!ygRcvw*h(kcj(he+Ri?oBJoA&Jl|B=6x#aTiXly>J|CM^;|wR49$YHPaJ;&Zo^oB
> zQPL4Aw97%ybLDg)m@8R~n5cA2Qq#+*bBPd6PLXBQvXWFC@d<XIjfZ`>CiPY
> P2#Gqt
> z8p(43tu7WkupcFC3NW%+0@|o!3hZvc602(fN%u1N4qFTFRxKzEd5X<NBM3%
> Legh@7
> zJ%F{^mPq^>VTo<HkvQR{EbvYkTp+|EK9A7|z=+CMKbG(i&en1UIeD(5?gJ*n7
> =JS(
> zYZN&yEv*o=!PH!QTCS!z1@=QsQQ$iMpiP^ayi{@@!(1-
> cxnmM>z8$snq;qk)x%*-B
> zAg*I_8ha?i-
> sEg2*$MqNM=&C(dEx7N>PwXKw;%^9IXyPrZfMp@nvG;_>#=EiAT~ih
> zbg5+!+!3zGk(<I}G9-+olF{JDNnyQo?om9FQfQ{j)iao+#c-f-wdOfAVX2DXLb5T(
> zG$!l32(300YQFHPf7exkor&PFol96w7xB7a7XjA#2*@v_bEa4ECj)IMw0Ea6*1o
> EJ
> zBallga=r3I6~D+CftXI+<*8<;8Ze-1mnVD~cAJEG0KEnC2pfr_(-8s=sM-k-8vL9E
> zE+h+<s~sQdf`ScyjcQ2@$Bq4Iy%~m2ZP68Aov)qh3t$cc<metK-
> 0qyQCnvmhfyrk(
> zRL9Fjz$37OvjMQhxqAO+k`)nx>QLV@hI*6Q01AVUo$4D%JNZKr{SVST3g6D>
> b2JLF
> zeSI9ulNt6G8)XEg`VtOk(H)K68hqEH1IEf;Qxlv_CLsn&zQsoTPy`e`GHz$|tmruI
> z{jI)_a+&SV)o2n8lz9?_)jQlG>!}*G>rpn-{9#Manu_3JVU4vQE5vZD?9u;oudd1_
> z^<Q8N<o+{_#E<Z%hskIB#gacc6P+C-xeywObA0L-
> ;h_Swl0C@PRulvY+^Z9~+ex6S
> z%_g8l&d6IHcJ+oxkn-
> T>FFj`{zd&~6EpX5pMYLSf>iFyO*l|j!<$#n#I@AMvWSZ(6
> z*+U84+O(9X9lVl%6}Dr{6GDiP)qTqB^ALeva`1EJ*=H))>-
> $+5@#pmVu4hfG+hWV^
> zOqbF9Tc!_07a!+)*|EM`g{khNL}g6K5&X+V6gisTwUR6O&%u2bn&63ApE>qbF
> a(~U
> zroR|64V1VCA76h2+nBFrYoQJLRVvWbU$N0dY9q+bnph9Jj0@)OgnYV0%wJP
> ZfrZl%
> zwwV}W3W5Or6hbgeWU$OsYUC#M3;c+-`d9=wrDmHHIXv#92-
> Cw~^BzhaTuF9D#<ze)
> z_<N!O{|-
> L7HPP4c?o#8$p{3Z!my4z=;cI*JS=JDoB@4LFUOmyz%EL1dBEe=OInWws
> zbc|(g56qmu2lAi|Nbf~W`)F`*nL+SZP!EZlAuNQwSHl*jF~m@~u<{onIaSq!IZT4
> 2
> z`&;nEX#^ZYJ&6LO)EOpQ>V0a`#xmvC_zU7sL6ZVZrY#-nj})~yNc{=-!Dg2l=+hsb
> zCz7c~AweTwC-
> PAu?h|(ZEcuGGLztwcQp=FFQ&&Hy?t&vko%D>RJIgT@^w9<P9IxQE
> zQ+sxg@<iIlr@d=yU{a!$#XvNM?>wQw7;IBFpksp7EbRXrM6p4PgE%8AMu!*Y
> pIq`s
> zBdEl=S=baujBq>f-
> @*dXZ2E2XahjA59b{;ZPIWmAB}3ouf;MjY%9&zt?;g?{&!nZ_
> z=r4Wdm<Q9kdqGJ3nE1K9zPjT_TD`~lo_Cz@3%EjXfxmudY^Q@_I{z^%L8x9S
> xW2>v
> z|JmPB5uX_!4D94<HMBeZ!sC1|KF)U(;4}00<R0U@ItxV?+Z{raTYCWGx*RBhY
> K-N^
> z`G!M}4d!Wlv8b$9Zl=C;YvC=|M`og>OqW~YLtf}{!a2f?Cq!CPQ9M-R)XD-{K-e)i
> zmMv#gCdj&CjPp>&hrr8TC|~IB&RBWgv`Vi(vL3Ii@C}50kSBmXg?Dq{UoaPe>
> OQC;
> zk&P7AxQT3})EWRmSSTAEcmyMN7^95?)tz#FCRRpv#^n4=9?%I)yP~swT*=T0
> ^D0`7
> z>4XrbuIL=^ubB5Zo?qJ;Ez3*t#L?4}Sb|6tonU#DICJu_pePp&%PyYf$v>e-
> Imc%L
> zU3-ZR@ZmX;W;<N#A4Udjz`gXmau=JFn#5+JNi9MT*oa~}y-
> 2$QPuq*&yS2SCqX&4e
> z^eudTjwH|X>fFiqg)eX~&&84<(3*rQ!@;~dq#MelM+p38Jwo7R=@EiGHhY9
> %*YqAC
> z@AV3KwO7arC&WcjH@$H#FP8TZZB**jxyV971ntZaqMaE+v@=79whb{gY3c
> BPh(Ek4
> zJOOhET0P8|1$EU~XhVoD7%A61nxDx}l;5Gzyx3K_(K%AO-
> r%<Web_Ksjy_$OZdfkp
> zGQuN08hBx0!!h%#(9)tcp#XIX!(y-
> L%FZahr(#}NApHJ+M|S35`6#)$GKDi|$B@c{
> zcE(CmIM$pivz<U4gn+%!o-9<#RR<}l6%!(LkP#wvkP#wvkP$-
> CS7wB~*DK`JULh;o
> zAsJNrZ2sv{@BfeRzf>&T5$Imt2Hyz{K=uPzm+y*)+{H*nKl^SF1>NZqkxr=$9il}f
> zBSfkvBSfkvBSfmlgjiBRQ$l%ki-<snLV1`F))TdAI)wF<8NzxpA>POokH6+^YDK8y
> zY~#!SIo|gMQo>pchNjo;+E8=~z|fEm3W<y}_-
> pzzwt0up`KImk*ZfVGSf>~{Jl|jQ
> zQbs_LzvkJDfa(64`iy|f{53Th0TV(GSrj9O?^rfC{qpeg+tM$y++S{9etG)KME92|
> z%Q>+V1>WXeb$BH*T9%i7KZ^I|1JqyfgXVn@B!PXQ$`nKpEtpk*k$u?|;Hz^JT
> L74N
> zSJ;-
> *Cc0ovcdD1s)3BLC4Nb>5ALrA@y#80%dx{N!p&ko+qeG_c3c&+}hEvOXqzR*-
> zoe+40Y3WX$&h&l^;}m`~Y?$Ci0jmLs0w;idj$nf@V7YU?)0(>N#W9?(;k2XDINJ
> 6$
> z(q80j4viJ;E$FYwP;-
> l`A!`xNYuO8yVDVd6Dq(x9HfND^0J%ORfJ~neK%UPCAg5;p
> zkkK;&$mbaWWOEbHx+fb-vQ_*$tyoMoknRoCPK8>6{UIWa6C-
> beg<I>g<Qp1)YHfAa
> zgI(}Ud84SfQtzNrUwB8XvK7+}#vOP$AH^H@I+Eathb?NqH27Fk--T^;-
> @9A3)pe2A
> zwijdF^lOd>4oA5Tzu85<W}#oRrC)QJe$7HZ9U$~`2MGP#0YX1_fY8q!AoOzw2
> >sjv
> zLO&hQ0{ZO<d<egs&$D7QC$xAy51fn;YJ)?~pl0Ov*yV!6D#a!VEf}f8rUODu<F!
> =-
> zW;%qfY^lr6_|_0|2wmwNR0%?3B<DlO9&ExEZfIQEf<*UZ;}DY;xB<uQ{1y6uo
> ^c0I
> zO)U_(W_6ADQ-
> KHRKmV>{(I42+Vsy2Y85WEv<BSkd#u*`^j59){t;`4^X{}A8^CE3C
> zLr7c+0V%UXe%y1o@KbbdvOje!+Vs+tH3xVEy<-
> k^2`hAI?SPnB;q!!F_n=u~HxxED
> z^g>r;s)y=A7ni0)WM57ii_dDGcfMb+^Kb!XB^=K3|De%jS7+!0V}GN2cq#YGjO
> |PV
> zX0-RkxjS16cBTr_pEK-
> XQfME0iEiAiA#XD5nV#~ZAJsEG*zc@gw9mJpu+Wt!>%#9$
> z4B$LkQkQCp7MO0@Kw;BmNT-
> k3qjl_IhIF#7+Tdn;7^c0q`TYlUzdOHypFclcJ+j2x
> zl}8#Md<Xs1pgziL=r7-
> WpYdJjiw@Ukr9b$1@e4mY{*dFvFaGTK{^P}8d5rj|ulpgl
> z&=u@ON}Zwa*%ix<4UILiODt8KrYGQ`hy?z^MlRRtin-ut=jsTieqrC!{iAr$6zX>#
> z)gI2HMab7EPCRzrXDokuveZQ~s|rpfif*(N{d2D;REW+Y#4~<PUbi$kj6NQG2%`
> $Q
> z?*T*l1g<|CnLSyi-{@{UZ2K$q4g9%32g=(Ii6&36PF`JRu>XKqUTn5kijhvlT^{T%
> z#IEfCY%GucCphYuQd=Mx)@{~-
> nOaC1bo<Qs`v_*D|F<jp3w=bl?Vr%o<R5j#=XnP<
> z`>%Y?_*c2&$6fI+_?+<vxZ)2+x83IdDg2f_i|@i;_xI-
> 8{$8G%B@>2G=eoZKox}cK
> zDmGMl3Lm0j%INixH9F}YNg4I5`)Q7PW~YnRTpz)#5z}u?*C#nm%{U?)aVO3!
> @Pae2
> zpFv99q{IBEW4MP9kOGmCGcDp+A1lYxIfxH~k3{!wo`BOM6KC!-
> m{Nzdh3i7YHV1C{
> z5c0Xhf=^iZ`hHME`W2zO_-
> &{DhTR*OTT0CW?UP@yX!+Eq?HT=N3{JxmYXKRh114qZ
> zQX6}s$n7?f*xX~Fm?8gujlq?WH#JE=WAU<AU5RI!?=s&#IhIfP7FpAY4-
> r}H35Cv&
> zRBsy;164@6W;989)X(GCH-
> y6;k3#H86VtZ=!oQF&n4YG&MqSPfs))_Y`U~BO>Nz||
> zQd!|*OD3;+U1pp*wKo)CsO2v8!7(T^6_{dc4J5VziAjB8%tAZ|J(2IJZ{CB=1FpK9
> z$>#`GVQQ@G5Y51xu))1c?IrFbS-
> x;KSD2vVtjCwpaYoebP+NV`iWD>Svh8UDa*U*M
> zLX!kv$sQ~Afcw*Urgjaa#)zB5xQfJ2asY|bdhVk-
> bo#cvv>iCp9y%UGli2?&{<q%#
> ztGhwqK8yGN$?^$<<jACgv}Yv(CDlg})AEbjrSyG%|D0QuIzBDyMoDQmiq;y^^)
> ewM
> z*C}@hy8`I&(y?M-
> z>7UX*cHfxd9PQ<tGz;2*bs_NXkJ>zKa%Miy=D9;29h!qG#rEQ
> z=VSvjxO2kTc*k)RiZ>yJ{z9_PP!gvP@$bz~{{!A#-4psh>@7i09#ir`zO3*>VXGY&
> z`eRQBJ*;f76FMm93AvO-
> <aM5(hssP2K(Og;yA+4fM+MrQhv*@hoZhKE1gpqCN31J<
> z4TnP5C-&ETL}gkE14oZ1!u0FN3Z0e=_vP71&>5Dl=5Coi;Z!p!%In{jEjlwF;(#SZ
> z?6R~Yj*Q}9*D5%TJ58Ci+fU2~mWiIf<SjOBpL)ust%q`C-JflFZ<NFp6IYTrhi8-w
> z-5A@%?NUP5u`f@Pbt!?1?BI;m=dS+YfY0b3?j`c3Ww6~oLw_0Xg1L-
> |AGE*kW)rXq
> z_8FdUwq^9HS7q`D=%>qQJnkuVwqj%98nVLCnWfrF!>$z=FM|P3V~jpD^cVC
> f)!bER
> zK{|U1g`<C1*>r#S1}q<{mn%FeLhnsZ;|w)$T6YM}r7qa~(}n^B$$Hgt15$v!Lj&+
> 7
> zb;Xbi><8?B2?+;FGdmacGRGtKdg?g;Lbx-
> 7KDIybh9=)$&w81s(Y2=1TUVah4m$X6
> zXAc<J*@W2m;?MbxY}OQWs4Ww~_1!xy;Cmn+$V0f+%+9T&Gm~=;5Rfj2z)
> OEz?9&N?
> zVQQ~u6EGwRLuI1tt~Qm(euPTNVQmxx>MxERimI*jMaz+NDzY?}r<EDM9Tn
> G{+;Wuz
> zRfwTV(QbQZ!$r#GBel1fL!Nvxly%{c{&epdKWThr8rV|kVXZHaGyNxP<__$xtN
> bU=
> zbNi=fP2itB36zok91h3QVFM91UPerj1DbgT8%u96!#Fy6(4^&0EA3j|pZcm2Qzo
> $c
> z2$q$IfAS2JNzVq%3FJH3y77f+^;>O*?)7XD`U3ki$z2b!Ym&mMV7`1=UUIlX)jF9
> <
> zVQ*m&3Pnzl*ur7Dhv7~iOij|~k#DccRjbg)g{bxAMbW(E@RRY!^oaiz#IFnVAY
> ~u<
> z6<Ffw8c>H#zU(FwZKrOX{H#2@stwJ(p6yy5K*y+-
> hdH@$ChD=auE<Vl9<G)e?%4)r
> z)aSAI#ppLsC(B>oI6mu)etVfAWyc+#-@~U=<py^PI))>Tpvu4zN$Bj};;-XZbq62)
> zpv1HAN%C@;aUElajn0KnG2}^a))gMOO~R$I!Sc8-
> D=H6W4rP_+<!0`<!Nm_%SueNo
> z`5>ROU+&;@6Q6Tl?&9+fJj<?gKne}pGOSzl=2l}vSnoZJzJ5$5*>5``p(PhaF&)|C
> zxyfP14E+IaoGGRf#^v|-q(9onIn*0_XZxTLjLxU#)AYjVnHE2vry55pa5!97er%X{
> zayleTi=<bF<uEMz75JPXaK2vW0UJhPrZ9<MH^!PEm)!^I0^KmLyRqgJa~5bU(
> WtvB
> zm#!22bxokVSNV)SGY;*Z@!)b1N$#3f>U&@`Cj<a@$T5sXs;?Mu7$%OHWItB
> A^cfwU
> zugh;L4mJtrc)+=YnY-vZW5*T@LP3le)Rp`|N6t{tz2X~S5NBFx-
> UGuR0y&g(Uk>!U
> zw{BqaU3ckh|EoIB6Q&pKN=%!Op_051s=;7T1f<Z7N5L@cH?0X)rla>OeKJ1gOY
> SAi
> zHrhe{Z9~WHN;e`JzbEs+L1pT?2f8?03T5Fm-
> %w6>WmnZH>W^3!i%=Zz>rwZ<#xpCu
> zYRoR2f}NHpLm!ij*GUGLl&b+tB>q#(qZfrFe-
> rP31_W~5V>}&L5IrVW?q0e3<en$@
> ze7P6MeT3W#<z6KBv2q_T_la_!EcZ+0K3(p`axanl9Jya3_cFQ9mHRxo-
> zxV7a$hL-
> zpxhV9eX-
> m_a$hR<WpZCB_Zqp^$$hQd*U5do+&9R5que*i{b{*xmirdDKQH&Ka^EiZ
> z9dd7!`);{6$$h`v56JzX+?(azBKKCgx5-_}y<P4da_^LTO72~9_k1e!m%CT)KDp<~
> zJzwqxavvf0Lb(^oeXQKa%YCBUC(Hd(xlfmSvD{1KK1c4?$h}PNbLBoy?zhT)f!r6
> $
> zJt+4@a$hX>kldHbeHrfQ_72ll6W;G&*lBK&H;x%lS2s^;Qtw>-
> &+hFDe;e>5248%%
> zI}MB{3}Pjk>s|1zfd3KUHy!}|yBGC>KbY9;hTjVKhX~(9_~&}VA4n{9!`A`+O2W_
> m
> zJ>aW*!aI1k18y|o=DY>CN(+Z2dx^2`^mYL5&{cp75pIHovxPKm)6u8cFumra-
> i25@
> z8EfM~#5y#Yo16asfBzRKu;}f6p0DHDfa`f&O}JWcb>Q;7)6a7*uFG)E#kCMu2v-
> fR
> zZ{hj@uIF*Rg6klzk8%A2m$$i}rvTTvxTfNogX?BoOK>g6^(d}QxPFD}Ag(rCM{w
> o+
> zv7e_1*LYkdxNgN&g=;0Q$8f!fYd@}!aCPGH{HdR32(AKLV{uK#bv3SexEA7Cg6
> k1n
> z8*pvL^$M=HaeajAZ@7-)^8LA=X9TXZa9xP&GF)Z27T^ludIZ-
> `aP7dgAJ?C7eS|B8
> z%iGe=GYZ#aTqU^X;<_8xQe10rZN&96T(96di0flqM{xPxMLb*+arOGUtk^R#Z
> <Z%-
> z|13}0tFt|2(`Pv#9dFI@bbRM>Pua|3C#<grH9uO)aP-
> <eCAbQA_wy8P0dAfzdKP)^
> z_dMXai=XB1ZqHQDt)7MWzt!^~zK8Jren35d_b+;u;C;U5PQ3Fw<1Ioe^Ra>PrJ
> jo&
> z2!2@t=vy;#I1eEn&scm5;p<(VJ3RM#3O%ReSgu0PwVq1PHTXYAaG0MFZ@%
> X~!Qg(x
> zzem2?H2R9Y7-
> @eQF+xa#fB&=Pai?y}b2qSCg0kF!Jp00kWj+_*?+4B9av<h=<|6!T
> z&}bs==Sa!N_JZn7mj{r}Vx)7Ql<t4JeE+Mx?*WjjD(^iBiNrM2SZN<xq&Jbk0@=
> ;x
> z4>5!gGrKdJEbKpbCJBFnli8WOJ40q?hC4I+2N45BOBE?q+R{F&pj2%iwXsD@D=
> PNU
> zKH7&Zt+XO)#g_W0wXdk?L#6foe&@Sq?zwkncPC*Y_Rrn@=G=SFzwdnKJKs
> 6yJKs5%
> zWs%gSbi{oU^ekGKhj9vGq*1dBUs*K93_@i=s}i_ovQdgom!sOqWm1`X622pE
> Of_mD
> zTo#hF3w~X|EopISx7w|-
> Edp=GJqM6hgK89^Qfgf7MeRBG&cgLNuA|H4Xuf6{g?i-S
> zXu9XAjeZRJ)Ij4o{2ERnJu`^!A|5HlJTCE5mD~r>ZU%q_d1)BGF+3-M7ek(-v0SIq
> zoyKn+DHK3?;lk#$$$@NrEWc1H%F9l}pQ$iC^80R$Q7`VK?M{M1E_}!fygJ+dg4
> 6^4
> zH2AizS>k2ajg7ld)5d*POApqBxjK!1kb~jN^{BCuu9*_3R?yUE`zCd5E_76XgYG
> @>
> z8$he9BXl136Po6;_+?C|k(!IUI#Mb?mQ(hK+|A*REs$=2&w9;`QuiXAh3~UIE~c
> iX
> zo=ZrV@_U!A|1QmUSE>X!Z5VubIeaz&Sf1;Uv&88Fo^@~pdD?^TLb5-
> =saf_{Azy3>
> z-`V;Jr*3#G?ejF-
> XaS{mQKmAe!j^eX(>p0^5GSW=bOJFmxMPg)o96HtHIKS2AlE!n
> zml)x9hMo?nVQ`AlQ(9yiDY56wz%?Pat8J(!X`!8^pX4R^Fc-t)f@gDoFE~!_Je12F
> zn#tD6<zn?v)~lr_in&8ow>X)e+p(Q54pqJEq4Z>-
> ==N|BfomCn;~6Y$Vw;UZc|`7{
> zHE(&Soig5bTK?paY84!i0o|o+6?`O?w5=oGXbmv`056G4&NtZgAdMb`i6Kpnr8
> v4O
> zXwG8m&fuQ?ZjQ;IWicK{8cH36AJY(tr_?>)$NB7l8lX*D<|d}RN)5#9QtQ!s<Tdtr
> zq+iAui#-_SJ4b&8AIc?1Q<ZXwIXm!`c;r>ejde(CBgQl2PL2Xf=#N}Tn0<|O!!4fW
> zN<*r#+)0G2p)Yk2lclURVjWal5U#U)nu8>oLN07QQjezB4f@!AV3PuV<7y1<KJ
> >Gr
> z>M}gD*JZyS(<4^Xx3nLB9CbO2v<|>kxMQ!(n&rrD68JdqAwBDwuPF5|z@LM
> WyQ}3V
> zM<7E8F@ad*gL#s%K}Vd5iIUlL+==kgkC+}(#`KPs3^E!b#T`AOaYCG?P<vV6k_
> Dya
> zkq6~h71D1M*wui$izkj!*!DP<*@oJ`2r~iR4}lv@?RFBY^_ssprncL97v7TZY$|O4
> zZtK)){EcY}v&K2=AVuhRJit`CbUIRIN7I-
> ynR%o}iaL6H&mN97WZDKLMFo^*Epvt-
> z?MdYKYEY2lvAS;O#7ZHT0fb?@H_xnV_BG}iTd8p+FjizwDA-
> 7<5<+|HQV$??)+^)N
> zvlP>&*@ro3!)4U6gK}_G$M8(ItlNjo(PX^NQAGwJD5+%pz~89kT8*4UaxpF83
> dUd@
> zLzCA0P5H>t3j0@%egbMa@FAvlZdENgl@2}K#GgrBDoPPk^CO7Ol*yT9RKoV
> wg_hip
> z)*VBAa-?`ZpbHXbJ2=@<-
> TH|fzi^5YieXqME~JCxM1Ev$ELSb`+YSy}H8(4aucEb4
> z^3!)fs}iI&d%9Wt?$#CGy1j-mWByV?-
> m#q?PcG8_(rA664+u+vgPPk|=2`SpO7#~D
> zZmFi!;8dyXVOZTio>C)aZ#q*{YQS^#K)bj+p>lx3fXe}6fQ09jy`9dqJ6-nXolLP<
> z&Sq+ba%rbCk;$3Y6L@>Xsm)j19=3|X(oCjU$XTJCYT-
> I}r?X+O?o7<r+^P<yHel!@
> zcscoU`G_5UGE*qlJxOkfFixiCa75y4$XA_Wp@f^9q|b^t8T}P|+hF7o$oziY4^un
> B
> zx?oR4sYHp$Ff#U&ky#pi$o?UXTAJ2!iMVq1xewe64HNEU{LWtL_23SU;@OY0
> U9x@1
> zETDw;AR~LmPa`EtEe|cLruuZhLTpT5T0wt7jZxquafVQu_G2(7(v^K1M_f`O)Bk
> os
> z(l`6bEV$y2LxTJl#*8%cd9PBgRtpoT;JlluIN7r2)hlE{R(#oWN^Zt;dgnG&G+xbR
> z<m{=WdumE=lj9(?1tXvb>6?ZxM-
> vJ78cd^<Vk$*l=4(+0l=d7U$jmjImeiO=20y0f
> z9YhQnp%zdB`!ww;sOPe7r=00}sQ(J|Z!!XngSM2t(nBeg%DYaVZe}PoOY6*Ls;0
> %b
> zIW#Lg6sAhJ^~&`cnn87=Q?I&C+JBw)T-
> |!RB*o)y*Q<v^A^`aS5j4534Y~8s+}dgL
> zOC%9$=bqag2pcC52e!Ou8D;@-kk-
> 9mt2VfFy9;y`LCZ6J7wehhAC3ZKE^pd4$KKJ}
> zY@V4c-
> DZVXIQwAO#oB5Rl6jja;s2n`2~LK0OO`YcAC{;&z8U?PcwwGzZa;SJC(>^A
> zC1PVv|LFMm{;|~H=!g?fq!Rt9M0}@{nXI{<7WUHZbiD=~$XaKs=vj@9&B?hn
> H(LXX
> z*7A5?L(|DrD#e2IT+XaluDMRFY<e$A&@JVh@}$U^iTdQE>*-
> G9M*@$f8V>4fVLT_?
> zN%Z)gB$%IKwU+T9ftzVY{`rx?X9?P+!T&?(2m1A#GNrD7OlFTTh@LeKiOt#NA
> Z9a^
> z%{EUrw;PeGwtSkzxXKb;BufY6I8zlNp2k?f$e}>$D5VEN9H)tp*1bic8jQZ2V!1Ts
> z50Tmoy95;%t8aAFwQ_}g!f~b}jrK&EYsPMz(zMwJk{-
> c;Z(+XsA>pwErQ)&S*xp23
> zr8$_%=8tIps5-
> NSTHdLbj+Dx?CC77Xb+6=L5M6iIVL;s~Y?=k_i^a!M<GLmn3zHa$
> zFBxWJG@f9f#nS0Z>>V6IATy>BU6JS%s0F9~!CYJ`5v@}nMmSuD;8=+<sm+O_
> )$PR-
> z$4X;*6h;lt0NPqCvWnB3j;#CiqQ~t;9`YyeZqOs>a1Np!V*BQZni`)pav#9hjjKda
> zeBuZ}9InvV5IfPNFBOk7*Mu)anBzg61|`VCdD(G{j%(r2Lr6cSWt1I{;W;KDm{k;!
> zL#B@67-5S3A*RRb{rD|lyuz9NDCQv7;GX(LYN16}*gQt*%S2{+ljS;k%SIb!oi7z;
> ziDsc|f_eg(IR!H*Y9XmN!PFHviZ+6y_^1YxWBXai?1e)pq{P|J;$aNk1P^?VR&y9
> f
> z=cHK{ze<fxT!Z0-ldDg2Ix<};Vz|M!0|j|lylr%<^$AXkoegsvo8>QN;+TI&qckST
> z4Kbb7bN6VtMUz%<+)&KD$<ciQN9fK@+`ndk(_}sJe~oz=M<EKODW|N<RCT
> &{uU1Yx
> zQ_Jjhc5SHcb~aSm-l_YLS`fMfqe(MQ0a?_Bo-LOn8x=RhFJEg=bTdb)5M-
> %x4aE(H
> z^;K#FICb$g0z(;Z%B|L%Qhj;?Lp;o0a*+_o!$fcjB^{d`n4TDkQXyJ@oG(`zbuRjG
> z>Hx{_)H_Y$jvDWv{g|0-*moB~n7$TKK@-k>xi&=3%i-
> A$&z?D$8{2)ej4QSvJmua&
> zxFe8SL0W9ROQlU-
> Y?XREGo6`24=V#cnIz^5+5D1IMer`?m!Ym%M=F(TroJ$iz#P-e
> zCL@!~U~btC?yYBGr0NUB!yX$2G?n^kJyx0qEvF#|MT<dQNmQ~3UR<9UL|x
> DLb;UJX
> zV^bg+XKLr!O1PFm%})<P7#*^Mw_I5u2Qe?|sso!JrZu78WpI~67_&Aja#}RDQ
> tLTu
> zZHM|IrfTqDUzyi^0WBkFk-
> )L+h}I!c|HLwq+j(_XFBYUNt2mrf6BnbWq7GLyD_vS!
> zN;;U9bDkfPEv%I<*PipBI@igmk2n3BDYdLHcD6ir+ESv<rcZkm)~Bo_8QU24Z&J
> (6
> zE3~@K+FYNlPS!Akl@;1f<4ta>fm>-mVCq`%Zf-e~s4ub9F=G=WTcbXkHBWY-
> j=2U?
> z^y|2*R4*2#x)rtqzJ!a-
> Yt<<)Q7>7(c10qQSjp?cUT`_CE@#Ks<)^MvukGzUICd(G
> z>m0p<Xw~8TVO&bhRpxN5LI`!LTE!C;SK*J3?XJ~AtyZaXt(F(%!MVWqTyU+ur
> o&!>
> zmRnifiaFBaN)FpJ*XP*wDUHO&Lsn>+R#vwakvy#|(%2_(Rj7uv`Acg8xjI|Fb{<l
> @
> zGsw~O{j@O51OK8fAy>dVEl0w+8UD&<t7?C0pnC`Mqq}+gP=a~y9~tb&v<39
> D?fQh*
> zT2YZS6stPZzNH=)mg^?GgFZqmwt|&)u6c!R35^vSaqDco1ehC|m=Xl5P|f{Tn>
> Gm5
> z8oKXk@b!Lw{yAPR)e6(D)1P;-
> tfR+^tGQz+S<B$rECoT$j7b0n1Y8o*qXl0z@8%FX
> zhS6&lqrI7oSIAI#&#5{`bY^%`sOeXQQlVCWiuyVoE0PD}*ogv%n3K(5hzRXn#;Ic
> T
> zT*N>zhvBMTeRA@QkkQ#>fIziMwFA9-
> 9A|J6Is>Rdm}sF?!)h4T5HiJ$&V0G<RP*I}
> z5wo0373)|S3RTN>FY7WkpLCXbitg(Yy>bP`f);V2P-
> 7e<KY*nOcP_)(z)r_mecDU2
> z`HbgeolBgqf^!a(lLG_iUA+3V{(Po1#R0cYx14i1j`i`HhZ>+*bo8KWa*|UF2D-Km
> z^3>)HE}mPh7op$BkR7Wa(<B^dl*0r>Z|X`RhE^Ofd?Gofi^~)%z}fYR^G-
> E0gD9D-
> zNAhHx$$BZPS5r`1MU*2&8sWcQMZO50fjWXYGCc-
> i&Q`3Pn=NKMB&f+##_F31lr5KL
> zgvjD&MXHop0jRi8<cyOmpx7QFwMfJ--
> ;T2q>Wo(>)N^Mh)PsOK05t%*27S@BL3lPJ
> z%t~@L81h_ot|m@{!Ds@c$H7(*gaIukT$Wn16^n_Ez<*_NFJhzJbf<!bGazf24)
> oJb
> zHzrbz_BCA2)zKnGGShD39j9g`zVNSc$oUf1y;JBpI7X%Y31zRW=NYRcS=)EiYhXj
> c
> zQ6$&NX-xrKbbQ)5G{;UrqKgev59||8L!AA{%k)khZI<y)`YhT^(B_SH7F?ls^b9?)
> zHX+f3#tk~kikwkq8Dje7GWFqR9KTYG1o7nxxXty*p_pyxcF|x^R74{W%vdlNtj
> Ztn
> zcRRG%@ZVMNzL>)gfS$NIl&@MH%jJL~rmnqnOm}rsuWaLeV`<#XU&$(_ahp
> PL8m?CR
> z^J~VRtwNHNYLhYCgTcJ5TY7RubndZ$QQKxfQ^t^BZjel=p|C^_Nn<01_2NEok
> +l3e
> z@za33RQ<m6HL_Q0Hz;!1LTriKNW(OCD-
> rlTv_7Hk1RMpV0NVg<^j8(nov0UJl{j6f
> zW)Bs%(kwB5#I08RVVU24p*Z~yC;zCeqz)!L0_^NKBS^n7&S-
> DWQ7HLC;}YhboM&?N
> znwmBbvW0WboVHNrNUef0M8hOuwIc)lR`YC*&!p6x)pBkvyFBc%SeQ1|#t7
> M1{>zM|
> z^W!oZhlS@uZSXPeXbb2C3!G2f|LufY`yD-
> `)$<D00@s|I?a;Z`p${^cxpEv%3uc*1
> z*mFm*7pESAa}V|j&At<;A=XPULl^pYmY+y{?pX@cCk;(4=M*Q;zCTFc@G<9K
> oO@+J
> zGwNEHH}xlcqBgJ({iV^m7(EIp(uF@`c~7m%X7FjCD-
> @d9<%wF#8(aJ6?3ghpeXh>x
> z`_At7lJ=5q%+bv=vO=l3`zJiFJ2~^oXg*RKl0R)(7oJ&?>YR<r{tKf&Anncm9^q-W
> z720`*XFsN1m_KF5V)?8O)xC^<IQ|j)a%v-
> _g~@Dvv0ROg%jk(IxB7fuqt*6qK<@(d
> zHxetXO9+=LsJm#HOl$?L+3G1j0!!f<q^p@HUIh-
> mTH8Z%UjXe6Q|e0XilyVy@q62d
> zZ|BbOBU3f`NDgd^CA2NRWv$Y(dUFFGslPVmXzjYHtJN~8E6Lj|EhQVZB-
> 9NW%`U0e
> zY55=IW#kO|A=W>&l`Lr#hb-
> D2tx(xNa<I>RUNTCr;4WO>vMYmSnnI6f#`5;AkxrK<
> znvaw!SuYKjOR2hh(9Nat^#QMt%y2#K(oAW<ofyt|v5GgGnZLANy0l)5)u)nfWi
> (qG
> zDbK`RiZ+eE)CbFL@2TlD{)R?U|E5kT=ebU0=NzRqInLfA!n!kig;<7GX~^!q8C}~`
> zsBP}ZmEA?HQn%ALc$)o7l70%YIa@PtTctwF6!I1=&Vqi(NX1sZqFd!!JL`Zm#*%
> M|
> zxb$8bTXK*Jf~VbAMsYMUkUKZUGPSi7v?V!haDv{~l*(w+mQFF~9inYzE9|Rfh
> gE0C
> zHFi4@E^AX(O-)m?hB04%*-
> Ok7YGYnGi`gV~iCjP8*p{mTJ*Z*!JS@*FBsudl<GHYm
> zV4Vbf8xBjq&X!v&&3k?MW!e|lhZn;zz|Rgx?37xm)Pp!dQeXH4?1S7x#tWZ!Yu
> vvB
> z_ga~c_qSR1zhK?pZr%T)b^lK5{$19+^g?z&bw23M^*#29S^RO$iI&uSuISkbIf-
> pZ
> z!il|cXX#6<*tUs>+1Z9VY;O)$t>xU(j6V}@KMoe%XJq!=W}HkK*)T?;M8)HnDD
> zM^
> zmtnPWT-
> #9(DYm>GNL`*LzzbbLC~TW~)e5;9)yEpafnt>=WD0K5tsS6w6z}(1_gV|X
> z{5o4N)V$H+pZz-LEyDR`=Y{cQzMii;ce!uEQR+0Vtq+YRla7AFN0l5L*=s$j_~>wK
> zaKwHC{oVH7t=mpp9fOs-Wx7iJ_H+hH;|#6eYwmPKtHO(ASm;o>+3%SAi-
> id<gB=@2
> zUnvTj3}TlGlQ6RAS#1=(NUC0{)+?2=M}xuH4D@bgsB)0xfdZAlPX7fLIPsyOYL9a
> T
> zROKa@+iC0BGSs#6)Si1G91&ToXpGi3$dM{?Y$Kt{8z!mKTGa#-
> 85ji;_w`n8LmK;n
> z3k7x6NkWm1ER%(t+dVPgP1lK4tM2p!>|(0xX<b;ziW=RenmbpgaZWi~pN1w`
> XVRm|
> z&g#*0-Fn*UZYLIy4~j5nI5{|^_2{rCEKiH(F(aAG!_o&jx+$lG#Acx27OlO%ZlN>q
> ziCN0g#+X=x1XDyQN}V2OuttsYbQy~n#ljI68g>@Gg^s<Xaq6al5p=^jr)yKT=$#
> kn
> z>ouO40I3qzaZqy582{QcUMvo03ME~7^3xWUn`;4Xsa&7RJJm`CYaFNwS*r=vi
> =i0f
> zZH~|@(0U8g!Qxt1E3B<cPPvrDT7)oH8}wj4%%hii&~}^n1sUXg|1CS{UoTM>k
> okfT
> z+9*`8MLJtvyGR*l3syv3Z$Z563&w+3T_oOxj90-
> {C1<AK)!15$s#mXJ=nRM#+VTRl
> zPh-
> &pBY{m|95{{^cMZHYU&MGpxv_>*0t1$+WzZq#&J?n45Z0%WJ693wcfDUG5I
> dyv
> zW=)?ua`eMYb1|uw#|mJMTyVseLJYq!UHnK~T>}cINtH*1mFHethqR%@0GF
> GEMN}Y`
> zf2Ip)P+&UNHw9X~q}QA%fqGVt!DtN45=F(Lqb!73X`fq#Wu2B-
> NGLO{c{nOrq|u`c
> zy_$wC`5qlv!7G<2C{PB5)ii7w7X74_C{;~xhSlw95|UCc$7wxx11%;&8R}{d#{S|0
> z7u?E|HCw0}dWg8w8;H%gg!4n$=PPUS93M{Uu?Tnm%E(&wP1^n(Rc`_;9O5c
> yAg;z}
> zM)pL~;*u5$9Oqnxd)g<++;tA2dhp)(*D&9x=}{2YFVJRxxOlF|`8*{Jvg=W)o*uni
> z=i^Zd={qWV^d{pr*+FZxAEc<z&g?0bu<}Gb5%=4g&_bj2pacIz3)I*TijHQ=1M6
> |o
> z4y>y!x3Trp&?V5mL{nWHFZ!OyK2XC-
> dbNJt>eZN75Iw!##D1?CFPm?eYbW_?J;s5e
> zyEE&L!J6Z`MqQ5i^!6~elHK5DPwNO)8I#&V{2)>qgqBFO<DDMYnfZ*gE;FBLb8
> I?I
> zc_|}j;w5{?sZlo;C}B(Vu&p~!9-y_knYmNv9Hc-
> ^b1Q3h6N|R;gBV#$d<T*uoL3Nz
> zdGuioX0Og^v5*Hba*x9zm9oK<f!a#WFZ;D5NJ3VG&xSA<ce-
> Avl{e=?n9;UI1#NR2
> z<8W#d=i%Dx7e-
> Ie9D<gGhC*r3V;q0|C~a!dvJF5|P)jM7p+Q_@MqP?IAA`I7lfX!H
> z%yQ-
> c&+lk;u0z;<)XXt6kXIsSsU@cT4W~#9TJI+xMJtP*|FA{(5+~;bh!ex#$ZVEF
> z+6V2aCbUfA{&cRtNMCmjs7M~8JX+{{i{|nz6jG#GAlIlHJ`d|*T*DC!b1S*HSZX
> #^
> z8P4pA90t~bO$5_!mbdMudooY!pnZgI`R`js7(9dV#=_+yJ#7j|uPn8zjgPEypJ;j>
> zdOw?fCz1|JV0PX%*9^IEq55fEpV4wNeS00+QLh7K)?<H8^b`&UQaw07h>~JG
> K-{H5
> z^AsQ9QciX~ZKK6~&~9!W@Q=P@N1yKZYVnDwahFs1oldf*XRSER2_sQVUop
> =c92IlE
> zh05QWYSHqaOb*@X4DkpDwM!rA5R9vm&>z9vkmhrkvj(N7krlUz=&dcF3)f$
> 0zm)MM
> zO0e^vrD&hGH)EVk>T?gM^nT5fKL&r1Ud&M>T5CC$L2utIsiSlyb_<2$I<y(PM
> &(!=
> z_3od@L7PNOr(CbfIhQa93W3YWfneOa5H`*7w^RJ^LVB0h^+2l4pl*2P0?(8=P
> uHs9
> zgjTd}F5N<OU@D8%iqN(Fe!CSnw3bKYOIrDLX{$eu)+kZL?$6|RB65=_&~Tn*<
> PK%}
> z3s28T^e{b61V7e9YY8QCk~tWB!+hMDj;$!(EZ0eurDU}&+1m+k$#&EuR~0zZH
> s?Xv
> zea1SJsh!+~x(k)RHPxc!C+3|Q=Z=COgBhRUC+fbLr>PAG&%4k=$~e3AIZB*!h
> %FRb
> zFl}JD6NvjTotAVlma()rW38A`JoDmZ`iI#cLjS;XmngGEqaYSGon4ohMe1TDHU$j
> @
> z7u#Fe&)GQe3@=)RiPnerwsi~UaqX=&%@#`4!W1UIoV(NFf%7CR#Q5u(2Me
> WKc@{RL
> z9JTQMevDvb+w5SV`zL+iHw2T?7;MmIu#{A(V_6OF<XMtY!&o8BOu2pKxr1o`
> Nj-y$
> zt}n6Q<?3f(>4U^^b(Y@IJcQ<^UmiqVgzbHJrgmV*M115#?&zvH*MGSWF<6g
> eSYDmQ
> zKbni+FP19JICY_=My;b**R5@&%=}x%P2m;&g<_Fk`A2I3o>b0x8T+&5HSVZf7
> wUAH
> zJ~iNApR(Aa+ZS7|U>S!m=a9`fn$nxn1hx+cb&Dg7C7!VYlM-
> ~ce(imd+<{7dl67iY
> z-
> Eu#sv6W!%(NQ$tY5gJGgBh=cH7|8^3}@B>asbmeH0y!P$)Y?VbOBv=9ERId7~J
> b+
> zNv;R;aRau62dYZ3=5PL8y}E0RHuuiBTf>qjRu6JIHkTBvMFBksSS_0?#Lk|R0^F_
> U
> zlmc#I4(8)HON^)2X+-g}dNo%itp!OeVBs{nSy{O=O5QA%C-
> lA|z3^(LW2^mRse(03
> zYY8*70Ler%I$BlK)|!vV@!@gGV&?;%h*p^Womr(0&xGys0b`&;^b9LwA8hE<
> Sw6MT
> z%Muw>f#fundac_3J{*_w`nv1QTm1)dJED6s?!hnmHV4LXMlkOz-
> n3*ktNns^7vw=6
> zvWxm3p5RHFY;zj7oZ!dv;AsURXOP74#4~Ft@djc0n9#CB_C~X=BnR1NNs9xqY
> v-J{
> zRZcSQWh`pVg4oSCnR;yYIX-
> NePLLn<_FOYM0t_he6y{e<k27tv&LU+Cp5>(S{U|*(
> zu;!dYN!Oem-
> JCAZa4;!Gdxtj1EYlNNeMF_UNgV1=rv`^{+Dm_WWdCqte6Sz;WBSv>
> zqa%q_Z2St|_ouFa(8I<1(V?MO3QxF?4Z)=4&i&d;_5M>#-
> HQ8T&m@#{QNKFs-`{m#
> zpQ`!yy<0JE_3saF>Q{%&`wjhS+456XtbEC-
> t6sYL$JU(o<1btL@}GFc=|A~X|Lu%d
> zzUrsXeDzsB<E&f%nzJ{Yb8gpp=U=d~yJu7H<}F*dUAX<VJ1*LJ@vcjDziv;guRo
> p`
> z*t>7=(#wX1M@Gk9Kb}nOKXCB!E3Uli(A959AI?l<bME9+zHrTv;&iE8xz?-
> J>NB%*
> z^Vhxc`ZwM1<_?c9gb$@1^ZW&ABcvhwMe6OvuK+D9&r{5z{&^Y%wck^^pP
> a`!Wb_SJ
> zB4_=WOqFB*Fb}XlHs=exuw2-Z`8}4hzkb!66Z0}Q=$$Q-
> ^v%ZZ@nn`Mnv;<uGSlLW
> zYzlQEa*aDCf*R#GpI57S22VhgwLD5A&M+L%Qsx`1XYOcOJZ;WJWc=7>n}+4L-
> e;_r
> z;iB9}T!%1cq>Q1oF_NyC=M49>@)3Du(&0B1c!|EOgi-}PIQg07rmZIDxq-
> $`R_bkk
> z)^77ky&WRFQZIIhVl~g&GBVh%nW(M##Rzu^e{ePH_sq&SE$@wV7Cbqp<S
> 3VA5KBn2
> zi%2AJb0`~c!%NMzVQ@B7w($z|LBZ<1<V`HrtBU~(mpkY;#A+7h)}?M$ZnkW5j
> snv*
> zW#{Zo^b5x7lX8e_bgq^LV*Svn-h*(YoKVfg<Qvm-
> Np8%aBR@F<o9Rod3Dy9KNmA!2
> z;mqy`mLJ`ezMAW^{c^2GDn=(09{1VY6wW88AIV4ZkJ2xg{nCef8_vhCDWja~O
> )V^Y
> z1D>oeYk-s!7of%@Mzqz~vDs=C=2ziT*`Z}t&`s@zdDadovoh|IBfc+A?!-
> abG}n=(
> z|C61|t@zE@r&M(>O08%=xP^AZW8fw84S;A#mX6h0CM_K=EU9cBA{PWQiy
> YN{dBlE%
> zCuj>Vg=?}kRzaNODN7Km{gSj-jv>?s_owk267APZG*-
> K1iN<TUH0hp=$5AgoDtvZM
> zXjBsHYuk)(2FMye`Hgcb_D<}3*tWP*$7f!gil_CR;mdGuZobzO{#pU0b5zcSWm
> Ge7
> zMr+3Okp?&EKY2PAapcw6c`NmA>|exY#*E5aowh}39rQP5#I!|S2&!tl+S3o0tC
> Q5J
> zh;>x3|3gkIv$a$@(T<nboQfvj+X%|rd|sOQwh!m;Y-
> i0Ur;$fEcAdr_=izd7wtnpN
> z1zXyK*|-J!w9QzxRqaLN9PgQG<P-
> Mv<dl<9PCI=mr;+O6R%P#%rRLYHud@})*;k#V
> zzn#b8c*$&_S$FZ0qetI*^v0t&pzM^l9)0UgM^9h55+{_s<t=Yn37tsq(Xpeq;Iy%>
> zb9am#Jc{$ja7fwM*e#&2({=Qgqll$&Oj$mkU$yGgxk_cWQVE?;25*1F6r64<G
> dO<#
> zh$l$$I|kG?@yngT?3B_(=GI2<E8)#4*D~s0>P$cQ{vGXsx$4GKF=hTH=Phuo96j
> 62
> zUOkGQQD*AOq|a|GakZ0UV%o{cnTTvtX62JUTwUOpyE*T`#?H=FqYo<7u+l
> GQK5~~S
> z=V9EJW@e;v{(l|0%h%#0Z|+2A9PWgq{j<nN#-jw0ebP*aV;bUY-
> !Wye$foq?7=>pY
> zu%D+SG1tk(i}b2NGH(NBOXEXokp6}nctWJ`4Y_C(YilWtAo<JFNn@CUBuz2!=4
> 8^B
> z->KnjfMdmWN<x`@GVzhUmhE72a`BM*eev-S-
> 8M&0?chSD;S4X@p7_lgYIlMjEE-}L
> z(&rbT_G)Q%Il`Kj)CoFsb(nIEQmDC&w@+(RzE<f4{j^<9*;~p}f<>~J7RWPzxek
> y5
> zj6#lcg)R67meFWNsU#Zq)|Bc5ooH2%L+#}o_y&@&T`IBuo6~u*sneP-
> Uu>+R{U%p^
> zxaJ(3`q=6DfH~LFj5XOau)dqM-Q;y%tj`KYz~;nDj+49mJqk%+I*3-w6YAr5e?5Tf
> zTYMYr-(Xv2n=mWTW)2j5NjrMFD07rkgrnMiS!a^=u^ug_1bXp|I`&-
> ydiJ*+Pet%C
> z$Fj0wz+Kfm(~dK88RwhOJMc`I!0}BTd9sbl&L^(r84WgN2X)~*aVebtpzejK@8-
> ;}
> zh&Z<GlO`W%MGcgU4<vV5J;*ns@wGMJZRo~#2l3qec0VlFw=dwcqw$_JCJ4
> >AgM)gl
> z=F_Vw(>Z2fi{@y|V7DIk9L;bgPwJ?3e8WQv#|-
> 9ulMT+{S9F6X!vp;OfJrZ^#pc|6
> z3vdbZ0IAAT)~P`(;g@H+Q|~S<r_=2vnva<yY+e$tFjglIFUd#n8cvSI`*!s9V9z${
> zS1CM=V&5n>%ong*)4h<iO9VR~;{^}<Me%t*zE6%0qz=Z$6Nefb77vM0L$X%
> KKG;JS
> z_4FRX=KFf(&;dO-
> 9CxSsaqORanLDp=ub1fc&iuq&jOpPW^M<#)h{X@Y#s+c9A(6w?
> z*?Ao6iE~BH=Y$qAVyFIxE!)ftdN9J^8r2ZOQrk)ikwQD+?hvj^@-
> 5p1+dkhgU1|ZS
> zxtFv3gVR^Y1F{}?^79h=8tN-$#Y6O1ou{LngQ27SuDOkNwjLMGE3n9-
> Tr(%LwVIV1
> z*<$22snltHGieKr+FY~bUTduw>(V?XC$mj}w<epUNwf?t=-
> !?_E<NQ2XTo=$4o1>T
> zDTEr7&pi8&=h+-
> VNjXdHH2tIL8(yUzm#ciU$X~9`@~26iGk?jmc|G7{<SX`xCGfpj
> zb++3BbL2RUr(F>r8E=LA&0y{&R+qA(%MnbV)0TLFouZU2$W!v+OoP^v9D8w
> W#SsqY
> z&7#ZU2*TL*aL?rk_R(-uB6~57Wt4fZe0e4(-
> !T2o)|W_2NnPqIjBRvuA?=QMG?(&x
> z&C?t?vGzq*E))=(38Otf9tyNte~`8`3EFykJZ5W3c@ndX-o!3IYKT~y^Cl%;v|Oh4
> z7fQ?MU0GAc#>K|NjNXln%F^lCqkSVKq#i_<OHH5sJ%I}55$u`UIj1bjmvXvnp
> O&P}
> zbYp!4bfVr*#_P0+j?#(s&hLTC*8*nnM2$f+u6AC{Y4Gf98A)&q5v;##Mq2DS!gf
> YM
> zdn4a<mj5}H;atezAZ?({{)%U<&~i@qS#8FVGffa9IgisnrU(2(=6kowDiZm0J!l|b
> zbs=@l42&l>QtzD6npv)Z1m}`d2P@iPnXSp$<TcQW^R;QDDDxJ!13T@`)6-
> 5}Xvy>S
> zq%>S9I)Ho8DmQZlu`%u4mgMAK;ZM#obDBe_t!0^v&4oy7zM++j-
> 7=d)1vU=MkL#c!
> z1%)SN%xlKDCyU=qi#cw7%ezJ4H}Zzqwo(qtsr4LziyorWcuO88b-
> `MAl|5vzzF_a4
> z39zyGZ=pReG1Nt{pCzXDCllkrY>0Vr&qWe#Aefm8x0{w>zLCS0Kzz9>NxcJ~_+
> =R*
> zlf{ni#8WanD%L2h2VR|(OJ=_Xv1bm!XvWO#&1{bHw+JvC#gca(ADQO|c?t(mI
> )z73
> zlrQ8;(~p{Ua`Q}X3HE&uPrI!qQDfI3zKIoGO>9+mDL?t6qGz|kD$Zhkae#yAxkdk
> O
> z`t~5LaQO@mwJuLEN>Hd1_U2~fV_SZc2KG2bX)TV-
> )F?lxi{mU>w0QO#3A0sO9M~Ax
> zsR<5&jT6Udv?~+cKKBDqr^S8w)E#jrAnn4))4_<hIXyY=geM)D9ptP#UY+H8lY{
> V=
> z@J2I_&FMK)7#E%g%27Ap3b+0++C?-^!FwU@A-!xm2Qv$)wQ$>E-
> xN)svVi3xzf<GN
> z5y8?N8qFun>n5GB?X%&(h48h<uYzS*9?Dtf;hl%gQmWJZ!*k8;JWWq!WHx&
> Q^8eB_
> zvn7NXfwnG_sS(zfoU3kQz;A<@5W?NE!<M`d@Nw{tb#7a%N^P68qbZXUj9)f
> X@>bs@
> zW7y8NSNm(8J?MjEOhBtkj!8IAklt5p8c2QVoB1qj?(Cao-
> =qUdnXmt4LSt6q{h$4E
> zK&9{>H5&34e&70OAHEQ{*x${n`7a#)Miu-
> mQ|<lPDcq!jzvZgEKNH{i&tCl~e{;R&
> zf7l$b?8e65vNkVMgLH3N7W^$=*503q-
> (33ReX~>xU{0sw&*aFb;C`)Yv%r3^X!!O@
> z8-!Y`f_u4Jwv3J7=#4l1?9Fd^>(AZt^KX0mt?#()7jFN>cfRY6U;5==x${?l?Z3bK
> z*WdHryY7D9`|tUU4}9=LzxiAL<KEx?@b4V^$nXB%eINbU@8ACifB5kSKJm#<J
> ^1NA
> z`kxQ|@t^#!hyV1?{`VuF`SZVc^e_MFvyc7t-
> +b=z&p+{nFMjE7zx?D^{_gLe`iHOn
> zpQr!vYyb51fBwJ!^2|5B`K@Qa{hj~!+;_kC{pbJn-+u6dH|8z8@vg0nc`tVPU+nx}
> zF#VU>7`d>&-Wd5}m%p>)7mi587DCSB491IL9i>>xQ-
> @Ejs9Ev!^cv{G8p}3yg484W
> zUq9&d_{@}#x{+yrMMh!lW$RyAHfj*5&6RMAX<?6}O!!>A*tt_~ot%23Myk|
> Cxg=bN
> z$~9dsNxAmz+c`bGlV7P&Du-
> *MGmOjO%{(qOJiIBF+k_ijW5YOC0)X@WaX`DPl{EMg
> zOyeFOhAHzkz7Yexumr#-
> W9n5H*5m6jIt_eCMsG94XJrZ;`Qr;SS&q5!u^F$9L+zQ*
> zrJ0hx<tJv4zCyZ8Qz0#;11KThyh0j`&$x`E@a3AimxBk>^I#8wJABi|tNQQoiJOw
> ^
> zKj4cu`VJqz(Z2W&j<}f`<1(H?c!h8ZVHEuJT$L+BW_^wt3hHLNd`*d29pVa$>^Y
> +*
> zhj$g|Cq%Pb)9q~*GX{RM<|@=YPi&TpbK%aWPm9h8{CT0A(!Pa+;9zEUo#t;T
> 4ZkRE
> z%cVBk9?rX;Y{-
> +&(M8%2t>J9SpN#ZdQQpu!z#^bMIbb0?L=U$#PjLors7*U8+11*a
> zbb0oL=%Is@JArSt<LUBz30gDCt})RIwr*GL(KSd<PFH`S^bBg>=D`<U|3SK~c<+
> U$
> z-
> z>9UX#I=)X^pLED>X<+)&Tc#89mYfY*B}>j*?)ZaGCur_8QJGY##a%hP&LOyRa
> Rk
> z<*I8jo}hkP&YNqc%aQU05{zp=vht!D?M!wPM743m$-#I*)-
> Ks@q9JViOKPCzfRkA{
> z5Y1j-
> qe**Pa&Ul&(Vwy;_G(g8Cn!BjYa7oncGTE&6v$QN0>)9UUTtEZ72v^ijC_%D
> zbM3o^+DW4?qXjK@dvhlMWz}YN5#ma0qls-
> V1z985fw&jpPbk%1OxcBC({{0V<bte^
> zar=0hSc2t+K87Yw;YW@M7N(V~>ItRV&)38{@qFj~QOEJ-
> 9K;J&Z!XmJ64cFN<>lE)
> zwD~yRe1mwB?-rZ_#T*T-ndf5pPKU}%TTaF`J1-
> WiACXLE4R0%W`S|h`YleUu+sjpA
> zNm(~X@(iElU|OLTf0_o1(ZNXW<E4KPPjI5$eL($_A$LW)&hzyblf9jg_mqCLM5
> X4Q
> zxyp(D#$K4`j}Bv>+;9UEhMCeDedz%*o6uuSZ>mhA3hJ2ry1DKuj>L31k@BC9;E
> cUo
> z83A}!H)bO_=Nz1GH<6htBTThiujRXs;EP#UL(un`Ne^F`VvXu&$MSP5zhZeNa|
> H8W
> zoR?NBcOwcc^StgXzDBR(Ry?P1U&5hXC3m*_IyY0ylyWMMlfscDPX1H4FY0$w
> K%nMK
> zc!e6iCWZHIX-dD(Ugzq0nMurqz!y<8n)PZ1-
> ?T?rflGC^peK;kSvOax=DV>yT&IC=
> zP?h*R<Cfg(>TZz;ns;>%6GKeU%(Ilo(dB8pbG<sE1YvN%wT={ehmW)%VH2k
> W8tPD1
> zm}z{}%R}Kzm}z{B38(%wo<SFU1uUcIz$Ogx!5kKJv(j;kPBl}U$>hp7MaD0io2`e
> Q
> zQQ@d;o+;?Ll{&s+1~YCGHj58~WmrTD-
> )y;9o}MT$n;={sXB%426XjxI20=_Z_*xM@
> zY9tlT<KRI_w~Ftld70}9#R3Y3t5o)8-6=eDm*#O_MKxLPCdx-
> pwoo`cfCm`8+tg>l
> zW9^Y6;KF|j-*vLQ&2zCnhuJ<p6-
> U1E!=T*xnv2htx!@}QT?UE(kLXQ$ZYi5@WMiH~
> z>G)wl$V|?PGvO9lDB)9LM?Um1#J%+%1vc*+?T_b6`t8s7Nm~ormwC^&WA3
> j3hq2Pk
> zGxk(8?!j$^i3wK|-
> T0HY%smh;T!+du&mcl@FKtQJSFT<INgBmdY<H~Gnuqf9q+L{(
> zc~^yC$)MuNBf-
> 1rO0h6mfXbrrj_uuV?&cj`KwdQni!@BGx`H$dD9AS5&P!JHH{LmZ
> zVGy<Pj`xq;lTe9~{px<-y~lU&)NV}O4tHdzPu;Aa`_)mnSMJ-
> VuGj9Ms=@8wmsE%S
> z_e1{k4&VQ5{hU&#!(}=OF7tc#{d8mMDeVra$F<w99@1`~x?j74>O<PSRJ~ifSE
> `$}
> zn^bx2rqm(r?p0&j-LK-lyAAHZc%M33yZvgdc88SGZc;t-
> zJ!V=V(N?9?N<+LcSzl@
> z-K6>u+{DPBx)bhTDyeRTJ2E=1=6pA&-4QhecP!PXcEC*}ld4O*ed-
> MD4yhH|9aYcV
> zP5*xNn0DjpA?*&RW7<uqcWZaAx<$MD)SPyQRbIO|nNhogDz4p_>ecR*%F
> *t)TBF_l
> z>iN5v&lT!v?H*8%!%ZF-
> P>;fmCz9$Bz8~4E9@g%D^^osA0C#^frtX8gw{KkC3%7sY
> zh`NXFmB7z`f2;4_40mKGuIAwGyKJv2^7+akmG|94a2bEhcjIu!#s}3dxXA;Tsf}>
> 2
> zj14FU?q#6sTK{>4|NP8*6DpM&)%X&hC-
> F@8QMkmD_|sjp=2dG>UAuk7npNE^PFb;L
> z?b=nZUNzE?qazJDDq|B{4@fKLQH&>`rv!*joo6>i&xR3gp_%E)xmE4P<;bhms
> dDY*
> z96m2-
> y&BPT(^*AZD%m&Ljd$}H<#5hg#jXx>CY!M>P3svmZA%N7i53u(d!B8JQ_28d
> zoz;_zW$U$mPG)suw0{iqL+GR77NFszB?hhTj7?8q<4zkf8Nb@$WENn*kubDO
> 3v@=b
> z#F|6Sa&@*`!bQx%oTXU;7m<6Sx&r1NSi{LEp7V0z$#tAO$}YMCvE=M5o_6{|
> ebzdu
> z&AmUoI-
> 6gRwyEn@<9%})jsq^FZiuJV7c~9Izk#NP6rnXIwPOs~d3?j^8=RRBEn7^!
> zhBL$ag4w2xy=Lo>eb{F`g4xKpx<b#r77rclEnYh1{VKe#c=43O`;)ngh`c9dr_GbW
> z{>3l1=)3}{6~(QBS)JMG9@dvJCf5-;FQmp!Btq1JSIW(H%5_(J4{&GOfyjp-57YLd
> z?{RMA=*Zy6+1ef5pE?`0LhM9#U5hfE47`~7wf?FlXU_}MN-
> SB;K5j}o+Imx_b{4N_
> zK0>cH*PCW*n1%VDJ_mMD`^7-_-
> 0WxXOAq!AvK@4`e3OuFvhUICf1b$XoJ^5t<myjx
> zs3%XwcdYQvoy%ecmS5+<n(jjhwf6abb^DHZyWju7$GB#^S~l3DL2e3jI!o8-
> @(I_P
> ze2g5WjIs0Ye7^jen7zZEGJt&^EkH#QY}TU+YHDTF5cS`p{i!1q85;GM`1D^azSyS
> +
> z<)yxfW0$auV);!Nkqvf>qVLJ6mmsgO91^`4%hrsi)SNv|HfuQ?2aB()!G(8hvhU(
> a
> zu=2ewd*`Xhc8&++o2U*(*!-
> $5xyC{7ZgvrIR6vchV8^^T29Ujp!PuZp*?@DXMKUz+
> z7nM~cj)~3MKTFo`-
> dNU^odPWd?9x)IHmAn=C&yC4+vVzfy$3XtI_KFb9HE*M-J&(#
> zT;J!Tk8~kTh4M1GC57zgB+}!K8NNRsIdG-f_Ln+mzbtka;>Xo0>dScrI}Bv3-
> dVXD
> zq;AIP+3NI@%XH52a|#@1<-
> 1;KUOfewd;7My+W5x_<!p~@*}Gr9A{~;=d*J^J<T7RR
> zt+>DIBDsGY_hUQdo@sWrJo5cr(pbtPUy(8Uk|_Cj4#vsqpCx_aCnMQg?Pus*
> x#c7;
> z?!)1Z(;U8n=c0^<z{flh&`2a=6nsyIvtv?->zm|Y?s{mJa8Z8eYE<|{Y&i`(IOB`*
> zh$|2By}~s1Q00LY&lF@%tOM>%=6Z2Pw+E4q7x<Densx>8Y3r~bspc?CkacotF
> U@)G
> z#7-%mCn=%QjX5*)&dATUJ7PIZ+9^#Xw-
> Jx6^hB|0A1C=TitMvs4ap4L=`Tac32E%e
> z=f<2N4t>hrxnLHjzle|UIQt5&M~kv~C+=3WUZLW9E2l40b^Smw&&$jslKn0S?
> qEFx
> zt7)nEiW^Dfu>Kr@!*!lQ)~V%r*oT9K0xx&2It<M?zGIeiX7qVGPPSZ`#}72%UY!
> T<
> zI9MX`d}I&%VP+<X(_$fUc4#~4<>s*n0+g_1F;}SJ3rdY#Cy_JBqYj%ewA3s>$$O
> pa
> zIlk{<H*e5h5+y6_qKHT7Vc}#^0(dpittH9S;Yu+Bt3#}Npm^kgtFCskIGm{Nxl+EU
> zzvX+lJY6c_8&Aa|zH7&NHz|;But0Xz)xbmQc4o4cnJBVS0yG-
> ggu|fD$5W|6(l)VA
> z9j@nUSn`1ZB0sGKzb5K5l2H~74ZVZhEb3U{T9VK5xAC=70B$n{ED&Xi4p!y@5>
> 00+
> zpo8J9#gH&zS|Y%*H~6z<5!B%-=$`R}<e-
> ejoIYQ=lbL$4)|%o$`nt+m#TVoQ^jI#g
> zGqDngU#QLcjg{~DxuEi-gqb04pw4C{bnWxyVV@It{|0<;;(EY2fL*&TQM-
> 3vqBh`u
> z6QCP#0pNVV_17cJIdB;Va08$V;&>xmM1h1ye7L*dZUAfobniYNvjU{Sdjftgz{C
> 04
> zPpNW6#0DM}`E(uPUjkT%=Uqr>Hxl*vS@SZ(rPFmR7Zs*TSPV+1@mVyG117Y
> %uhhKl
> z+u&x49*eBQPT~`d@{mr~@&(oxJksfEE!PNB$?&zLjc*QRF@sN2c;&kI?x9a6)B
> }KH
> zfO`OU0&WEy1<V18fWv^TuYvy`B-
> AZ{8XyJO0k|A~V}LzZ;hRlx_W|O32J8at0Bi(w
> z0nP?EfHMJS08R(21*`$A0;~Wi!1JF-sOJFB0-
> gbU9q=^ZDZrC}F9IG1JO+3a@Ce{x
> zz(ars0S^G~2iylZ2Dk@sC*XF#&441{FklF<5wHgE^#_m+;9kHjfFfWYpbMY?Pkk
> Ku
> z0UiZB47eX~2jEt~Q9uQd0&D}U0X+4GzyokQpavKNYy>F4W1!pp0MfMofPC|
> A=T4<G
> z@1jnyLd*rcZn8P~3X9oj{x!F|g5~jP$WO0Zor}PSGo^BAe!5(*I_N`OEHP)bKs}7
> t
> z61h1h>-=zw*E8h;Rv(ob*)Qk6xpT;-
> <gD*s@2IP4d3^BuYG6p)1+I$=&iD#n4Lv45
> z^9?(O!VFN<9!6|2yx-vld73U5C*Eb8X>Dq5$rXnOOt=^oG;nMc-
> j<jq0`dyWi$JV2
> z5@nc7?i#FRm%TUQeg-aOt9|dz;R)>$@FvjsP3OXH1`nhU-
> _4X!6SBmwHtuqZ#X_Z8
> zsP0x9dwP1{t*lpy!;JDQ#v@iFjXJ`iH$xN0w{`iwR(+?`{*lW@Mi1h&+4Su8Z4Tx}
> z{497HCorT7rP}5#JD9${*Kz>wwr=tLwu_4p6XmjQ>$x&2%EdVV{K7oqO%}_rj
> +bXR
> z3b9o+4+8|;GaJ5hv17vFa~Zy_Hwkv)Bc8K*fTr*LI~k=Af9R?Z>ahPwc*o6F>!2
> G_
> zz+04)dEkzD@P#fvZVXBEyJBJI&Pt&~5l8u&<#UDuy<O_OtCV`<BxwF7q=mq5
> <hTc6
> zZvR`%v3ywjcwF@Y#sF(Sk9$A`u;+=mItn-
> j*z<+BIt(}pa9;O1CZUdfF|O2?5D&1A
> zFHZ34eJY`P{{-zG@yC<#<lo=%bI(8X<y9lM|JesWUWs)-
> whZqRI}astN4BKmhd7u`
> zp_ZzL`U<5(_>}I}Er<5HrM^PBI+*LJ<R(H`9DNpY7;{o{Eyv9*c)kO0%zw`?%!Aht
> zaM9fZV7$BFXD-|C5kD^d825`-
> dL}&GhY<g{NZ3`F<E{l5e|>`=JAFG2{fUR2C*M7Z
> zcPT#|KC^5&JXZjwYz)(?Y<4`xeIDWNillW6&ktB>F-
> )tp?08J;%x|MVu+pNA;CVc+
> zK^@!aF&uH`WtZKKi^-
> RI@*@~a%q~|Co`IBJb&8t%$_n)%z~g{bf44&Q0xk#K2H^F~
> zhCSNlk8_UP|C?X0kNU28e)*YU|A!;~mz@>%e=y?zr|ZK0?~eGtc4OE-
> n*Zy&!~S;u
> zU)!}ut-K`c|4=0TC-*Jx|4b_E|5zk`-@&kd6u)<*!~Ty);%`12_J1Ve|5H<8|7iZ_
> z<iq|^`hL3@_K&82pcM9x;(tSVasRun4f{va|LI!TKbrpAt_%Cy^`~&{`uVVbwEX
> wI
> zJ?tON|Bl<lA4#bx+#9})=Ck($;dG*Sc7G)7|A19b@!#8{E(P#1>D&GXKDI|40@(
> gJ
> zD}MReJ*p0{{iFD8`a#&=F6ZZ77E`CLjfLXhXQfY%>wjW#|3^*_`$zfokJl~kKd?U
> R
> zAI<--HiZ47^?0}|>~GVL_@B`i_K(KD>p-
> kQ`|nuyHl3Kx+!aB%f3WVO^?l3XaDGw$
> zbF$+9luzeden<K}Q~%|X_%qLy)37h|!(IR8aJUc72H{>+4{(dp@00Uke4^!=zCP
> @K
> zEK>hxzB%lFzvcf2x5m_G0lW<UQTpC=Ti8D;N7cK+{!#w@@SS1*sGQpI?y!H9-
> oNyo
> zuzwW4yWbo3kH-
> J>r^5bG{C59QO!uLcuf)}Q=;N1x7Kc6)j9oNw{2%%mIz{t2<FCT`
> zMB7pBvBmw@|8>9v@38Kp`7Hl@5bh%DK3XpienIjh>i0eo+`q$rZ^{v+$MCm;
> u;2bh
> zkXJPQ<a6QjMDe`wyJ7!mKHvU+*gwh_%dhIwR5y4=^S|usu)m%E$7cG}UjTT
> S__jaa
> zPyKw@Kbrnow=M2pyDRJ;<;!p09rllwKXy;pKiaO3eK_nNP5;ob#r+@p-
> G%+<ALvtW
> z2JkZUvD4r5i9U59U?G3L|2X_1N`7#c)o$*1bm4Zxu#Z|{A6z7?oo|#c@^9^@cL
> VPz
> zUDIz5`$ywHaa+H}Tm4<o-
> iQ8jVZ04}qV;p*Hzl8EzAx@QNMkwhItKR<KfR+E_w!=e
> z>2jX72X+;_I4|L4`>lO#yiu+wKMpI*8F9TD?)d<N*Ij<v=6S~{67HhqaWw!i?`{77
> zz)RxlUI4FF{vU-+$j1S;zb((QtKzBzSjhkFKOR?i0v7Ur*~{YUOu$0^x5DpN7x6!1
> zZCq^t?9nO6&l_GIZ_v`v)Oat$4dL|9CbW!aJ)MnvzS{=ZzW9#u$1MIRM#7lz3~T
> 6T
> zw;%fd+Qs4W+4QIX+hbw>D1UYLhyA1RcgMs2QGU5_AnYHF|7^s6F2YCe+ZT
> =>^?${s
> zLhqv%o$h!nOiPxN7wPo$V=MJNe=hwJ?w?uFc(!kff3s4(6>ulu7~o;R7Xi-
> z)_iWI
> zIv=nbkOJfYHNee)cLLr6I0pD6;4#400N(+udVHli18_cICtx4oN`MEr0dO1OF2ElG
> z9s@iD_#R;G=U1w;0UH5vz#+gjfTMt41N<)F5x`dg&jQpFE7gw!&H!`)b^$I0Tn
> @+q
> zJitwWI{_a8d=l_CfUg3+3HUd_nlG$WX9CUvYys>Bi~$Y<YJi&nzXf;z@Ce`uz*h
> m!
> z0akr+r8*0+4G;&U0F!_@z}o=t27DOsNx)-(uK~UXScCdF3((7Y!8N)Zr`5_q&8fn)
> z8><dL@yI(>UIrhmsA2&wH-
> yb5G4*+TIRrYperyKAc9&ujdRc8m_Akqa+{}#I^uBvV
> z3Oj<Z52@ykdF8CjO<=#NQ>}a0;!`s(cdyuA$|IMen@bqeG@ya3l={gP_~OWd
> -ha7#
> zuo`zK>QmT4G=_x?B&xp69EQuedeLQBMxeDmh<umtb2An585E@+M$EoUZ
> X8RrV>RUS
> zRmK{^Qb)q`uzd^mL;BMu`!rhWou`b~iu+5mg;GvkdCGXEP<0!aDs>-
> DJOK`USnq|w
> z^K~l@7IJPsbdjm@FjlS#ee*RJDw)Q8s%!$NkFF>}$yszck#JZOBuOlnLs3AhZ!8}
> w
> zXFz*w-10azc={C3LNMwt*HKh;v97&Z&PP*yj-
> }8w2(`YtNPII`;HwPci>xvANnpyw
> z(P&k@W5q#Ks-~CvSzSX|-
> z*nh7|*L;vYtU!SE(aRmppPMj{0W8*!CrykUB+w1ZE71
> zUA`=3U5zLza#G@CkNBAXwoX;}Af;Ez2XjjOmi5->4!r&@-
> %5>2K~bOURwRoq&U|@r
> z`5<``t9VD;++Zo|=`~<1r`YdtP>gxMVp#%9;D+;_4N^9|0y<y1Y`}9}>nk})y<S+2
> zsZTL{vxmBDffxtXr(4HB3AU|B6{|>2e=$dG;Zuypno3>BdsMafY~>RXQeS8NTR
> eI%
> z)9$xvh_Qy|^ElV^%Jb^I`l+9LI8kqR>nEL*I=JG1Ed1)nA6qtnrIKQ-QXzF>YUe4V
> z^;)G~(|j$Z2VHIzF6kHEIH)de4ux`kkXZU*`oY{%WuAK0=4OQZb&ZV_`2+essdv
> KN
> zqwmLE@ktpxecFt(%-
> qzWUO|o;O$_t?Dou$o@}l|zTDETI{b1HH*j%XRiBU3WC9!1#
> z#d<Z*8t<!5PP!i2+ME(9@nuYX6x?IXAR=ugR>~!@jv#FO8sgwH6Xgr$lLlYi5R@
> 9y
> zoZ+`&l|O|7hj}RVWn#tKF<A;x>ZTBVW9nCRsf5~6A1v!9Y|e%h%4bR_<5!js^$
> %w%
> zjk@}K`x(@}gqVsiEmu&Rd%|xJCeJr)*8{pmBg}`1K^)A}c=I&h48g9Zs9Qe5e96#
> T
> z-m2%&OVp>OOOaP-IBJ?{@2|RET-
> Ni4`Uf%S_zY=~DCI^cg(hDMrw*LP6^(i_p4%wd
> z{_q=wc~nxtl3=++3y=fYb4e?Wn7S-
> 6K9U&18S6Q{m~9U}euVGO9_$+&O%9&zsPJEp
> z|J<W^ZU+DOMqKm8c3H&k0stGzyURS~32Q{`-
> W*sB&<w>Xl+ehXNig9~XG3*0{AVXj
> z7>G<rbp*oh^Khtz!%SqbOEr|<U}*-
> X205B<OctiJ7tM;$VMvbsnbNs6XO_KBb4I|Y
> zg@02fq?R)ncQnR&rC2GJ#k`-u5X768yc=PpxH?>8Wz4B#*|kuc-
> w1OjuZpqFPG@Fw
> zPp{LveN*p_O<Q_<FLWGdHTbVG?-i!<umj7U=kWDLhrLh{2527k-
> RjP;$AQGcW^M$l
> z!te*2KjY?lbbR8rzY58;bF~Wc?k*rYiNvPhbeA1z^7`p2RG<IcM-
> ubp)xbo`xuNP@
> zg6dO!qp|ULn(Yc@x9)YFqbQkT9Ymf)PzOt<^<vJ+W7r0h(@eHjoOd>$mN073
> Y~aTq
> zPaJ5ZCHE(i7KF6M%D5+zM&JIyp?ErV#aIGmv+hqMtpkbi<lyK?dN_6|c7rMve
> SSe{
> z4sz$Nm8SoEB55WQDTh1^;=!T^HbK2xa#7&>k+1Ig_(xv(DP8Y;UdA6>53U?&x
> Xa8-
> zzFDhZhkiIuwu6K`@j!pVe_j7Yfp#fCe)=hZ;hj_b`xS7{0IUR@26zeJrGQfb)SIpH
> zUB2Tp<sAKf3}F12F5}XD8Gw0^t@-
> ZdfS>Sz@7DqN{z3qsWBxO>b9~02O2=WlWw@m8
> zVrZe$zXC4vF8c4M;W~f{;7ouAAg(M2@i_`0&Nuq*O>pV|vjF<v3}8OL2sjV$9{
> >4n
> zxWwlk0Q37GfZ={0z%u<gfc~EY(Ekh&h4e8rD}Fz&+c0%n%kZA=zy9-
> =KC|ML3H9t5
> zq66c58}O*Z9VNmicrhOn)xJLp0x_>=z9If&$&?9pLhe}ng~fmTY1jn*BWyo*#}s
> *y
> zJT(Vk(TO)N@(^i!*F~@wgj<8ly4wer;g0QqT?*Wr;j&IraLH@Ea9;s;1zhs>Bd<*;
> zZuqzd?yKMy;r=w-ZE(pmYv7&*_v_me>Sy5I0@r~%26r9Y%P)lf60X_?+Z;Gw-
> <p7>
> zJ#1*;;^-0e2;Ar4J`9({zaK6y(wmoY<tcbx>it6g3#DViFXfu}FQ)rwR@VPmzm!1)
> zsdf1^xH%UKEzR@Ean~+*Nq)|P*U7=>hn?!eholQ83m?+`!^ZUF<+mUUP{iO`
> kOds=
> z{U7D$-#IJX@=xenm#<iL4?2~@H_hL)&aambd|7Vp{ta<&eD9MK*=o-
> XN45JQg#YyW
> zpLo9`-c7$Z{+qno<GUYiGknYs|1pIBi}yYCzE`P#c;D0SgOO|GYNUU|-
> 8#nWF(7;W
> z6K{CJQRyeHd16Z>G{!TZef)2q{H{`)Z;+VJzb&EH#QOb^rVnU}_yS)XdnPQ8U+6
> RO
> zjN;n$Y>>xuw<Ofjci{OK5-R^K*wG_@hNsKAW^Zx(_1H7t2C(S%-
> cLU7@`Akh{O|o*
> z>Z>8kBiAYZWy;O|m^3{L?!|yB0UY!E3gDxF#{k~~yd0I#3m5@R156xl8sHdx7V
> yh}
> z`v9K>d=s!1;Whz=0Yv~W*6;VgyZ5~dHo$;;0UrX~1Go$DZonOYTLCu%<^V-
> N4sbaj
> z1sDSi0rmmnfIWa+fE|EsfL_2xKo`IPoDNt6SOH-
> 8=iiAjIpFJnCjpNG9sxWEcmQxe
> z;9kI;fLj4C#bCupU-M)S%5gS$wpR@-
> 32*i<@;K9AT$2`VbsOf|Hs9?#hJ7U;75?mb
> zUF-
> nPi%2)li`aubKYR9s{G)zMFPaATm|%OsWEpXzeoQ}$Wj8<RP}=lk+(ORys*ry=
> ZjZG+N4<D9DmnW{lYNQ{GdHj36{y$a{V$uKr
> 
> literal 0
> HcmV?d00001
> 
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/AlertStandardFormatTable.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/AlertStandardFormatTable.h
> new file mode 100644
> index 0000000000..3b0f00198b
> --- /dev/null
> +++
> b/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
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/ChipsetAccess.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/ChipsetAccess.h
> new file mode 100644
> index 0000000000..31ccfe6d5f
> --- /dev/null
> +++ b/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
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/CommonIncludes.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/CommonIncludes.h
> new file mode 100644
> index 0000000000..eab47b28d9
> --- /dev/null
> +++ b/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
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/CpuType.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/CpuType.h
> new file mode 100644
> index 0000000000..c195dee773
> --- /dev/null
> +++ b/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
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/FileHandleLib.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/FileHandleLib.h
> new file mode 100644
> index 0000000000..5d733a0240
> --- /dev/null
> +++ b/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_
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AcpiTableStorage.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AcpiTableStorage.h
> new file mode 100644
> index 0000000000..7320bf6cfe
> --- /dev/null
> +++ b/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
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AlertStandardFormat.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AlertStandardFormat.h
> new file mode 100644
> index 0000000000..f0459545e4
> --- /dev/null
> +++
> b/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
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BiosId.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BiosId.h
> new file mode 100644
> index 0000000000..e86fc852fc
> --- /dev/null
> +++ b/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
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BoardFeatures.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BoardFeatures.h
> new file mode 100644
> index 0000000000..ae3c2d9aea
> --- /dev/null
> +++ b/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
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/EfiVpdData.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/EfiVpdData.h
> new file mode 100644
> index 0000000000..e00e582ce1
> --- /dev/null
> +++ b/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
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/FirmwareId.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/FirmwareId.h
> new file mode 100644
> index 0000000000..fd524b8ce5
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/FirmwareId.h
> @@ -0,0 +1,61 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  FirmwareId.h
> +
> +--*/
> +
> +#ifndef _FirmwareId_h_GUID_included
> +#define _FirmwareId_h_GUID_included
> +
> +
> +#pragma pack(1)
> +
> +//
> +// Firmware ID
> +//
> +
> +#define FIRMWARE_ID_MAX_LENGTH      35
> +
> +typedef struct {
> +  CHAR8    BiosId[8];
> +  CHAR8    Separator1;
> +  CHAR8    OemId[3];
> +  CHAR8    Separator2;
> +  CHAR8    BuildId[4];
> +  CHAR8    Separator3;
> +  CHAR8    Century[2];
> +  CHAR8    Year[2];
> +  CHAR8    Separator4;
> +  CHAR8    Month[2];
> +  CHAR8    Date[2];
> +  CHAR8    Separator5;
> +  CHAR8    Hour[2];
> +  CHAR8    Minute[2];
> +  CHAR8    Dummy[3];
> +} FIRMWARE_ID_DATA;
> +
> +#define  OLD_FIRMWARE_ID_GUID \
> +  {0xefc071ae, 0x41b8, 0x4018, 0xaf, 0xa7, 0x31, 0x4b, 0x18, 0x5e, 0x57, 0x8b}
> +
> +#define  FIRMWARE_ID_GUID \
> +  {0x5e559c23, 0x1faa, 0x4ae1, 0x8d, 0x4a, 0xc6, 0xcf, 0x02, 0x6c, 0x76, 0x6f}
> +
> +#define FIRMWARE_ID_NAME L"FirmwareId"
> +#define FIRMWARE_ID_NAME_WITH_PASSWORD FIRMWARE_ID_NAME
> L"H#8,^-!t"
> +
> +extern EFI_GUID gFirmwareIdGuid;
> +extern CHAR16   gFirmwareIdName[];
> +
> +#pragma pack()
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/HwWatchdogTimerHob.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/HwWatchdogTimerHob.h
> new file mode 100644
> index 0000000000..3cd6c843b1
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/HwWatchdogTimerHob.h
> @@ -0,0 +1,134 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  HwWatchdogTimerHob.h
> +
> +Abstract:
> +
> +  GUID used for Watchdog Timer status in the HOB list.
> +
> +--*/
> +
> +#ifndef _EFI_WATCHDOG_TIMER_HOB_GUID_H_
> +#define _EFI_WATCHDOG_TIMER_HOB_GUID_H_
> +
> +#define EFI_WATCHDOG_TIMER_HOB_GUID \
> +  { 0x226cd3f, 0x69b5, 0x4150, 0xac, 0xbe, 0xbf, 0xbf, 0x18, 0xe3, 0x3, 0xd5 }
> +
> +#define EFI_WATCHDOG_TIMER_DEFINITION_HOB_GUID \
> +  { 0xd29302b0, 0x11ba, 0x4073, 0xa2, 0x27, 0x53, 0x8d, 0x25, 0x42, 0x70,
> 0x9f }
> +
> +typedef enum {
> +  HWWD_NONE,
> +  HWWD_TIMER_EXPIRED,
> +  HWWD_SPONTANEOUS_REBOOT,
> +  HWWD_FORCED_TIMEOUT
> +} HW_WATCHDOG_TIMEOUT;
> +
> +typedef struct {
> +  HW_WATCHDOG_TIMEOUT         TimeoutStatus;
> +} HW_WATCHDOG_INFO;
> +
> +//
> +// Watchdog timer action values.
> +//
> +#define WDT_ACTION_RESET                    0x01    // reload/reset timer
> +#define WDT_ACTION_QUERY_CURRENT_VALUE      0x04    // get current
> value                     // DON'T NEED FOR OVERCLOCK UTILITY
> +#define WDT_ACTION_QUERY_COUNTDOWN_PERIOD   0x05    // get
> countdown period
> +#define WDT_ACTION_SET_COUNTDOWN_PERIOD     0x06    // set
> countdown period
> +#define WDT_ACTION_QUERY_RUNNING_STATE      0x08    // query if
> running
> +#define WDT_ACTION_SET_RUNNING_STATE        0x09    // start timer
> +#define WDT_ACTION_QUERY_STOPPED_STATE      0x0A    // query if
> stopped
> +#define WDT_ACTION_SET_STOPPED_STATE        0x0B    // stop timer
> +#define WDT_ACTION_QUERY_STATUS             0x20    // is current boot cause
> by wdt timeout?
> +#define WDT_ACTION_SET_STATUS               0x21    // resets wdt status bit
> +
> +//
> +// Watchdog timer instruction values.
> +//
> +#define WDT_INSTR_VALUE_MASK                0x03    // Mask for just the value
> +#define WDT_INSTR_READ_CMP_VALUE            0x00    // Read / compare
> value
> +#define WDT_INSTR_READ_COUNTDOWN            0x01    // read countdown
> value
> +#define WDT_INSTR_WRITE_VALUE               0x02    // Write value
> +#define WDT_INSTR_WRITE_COUNTDOWN           0x03    // write countdown
> value
> +#define WDT_INSTR_PRESERVE_REG              0x80    // preserve reg; used in
> Write Value / Write Countdown
> +#define WDT_INSTR_WRITE_VALUE_PRES         (0x02 |
> WDT_INSTR_PRESERVE_REG)   // Write value with preserve
> +#define WDT_INSTR_WRITE_COUNTDOWN_PRES     (0x03 |
> WDT_INSTR_PRESERVE_REG)   // write countdown value with preserve
> +
> +//
> +// The Generic Address Structure is defined in the ACPI Specification and
> should only be
> +// changed to match updated revisions of that specification.  The
> GAS_ADDRESS_SPACE and
> +// GAS_ACCESS_SIZE enumerations are also defined by the ACPI
> Specification.
> +//
> +typedef enum {
> +  GAS_SYSTEM_MEMORY,
> +  GAS_SYSTEM_IO,
> +  GAS_PCI_CONFIG_SPACE,
> +  GAS_EMBEDDED_CONTROLLER,
> +  GAS_SMBUS
> +} GAS_ADDRESS_SPACE;
> +
> +typedef enum {
> +  GAS_UNDEFINED,
> +  GAS_BYTE_ACCESS,
> +  GAS_WORD_ACCESS,
> +  GAS_DWORD_ACCESS,
> +  GAS_QWORD_ACCESS
> +} GAS_ACCESS_SIZE;
> +
> +#pragma pack(1)
> +
> +typedef struct {
> +  UINT8                       AddressSpaceId;
> +  UINT8                       RegisterBitWidth;
> +  UINT8                       RegisterBitOffset;
> +  UINT8                       AccessSize;
> +  UINT64                      Address;
> +} GENERIC_ADDRESS_STRUCTURE;
> +
> +//
> +// GAS_SYSTEM_MEMORY -    When used as the AddressSpaceId, the 64-bit
> physical memory address
> +//                        of the register.  32-bit platforms must have the high DWORD
> set to 0.
> +// GAS_SYSTEM_IO -        The 64-bit I/O address of the register.  32-bit
> platforms must have
> +//                        the high DWORD set to 0.
> +// GAS_PCI_CONFIG_SPACE - PCI Configuration space addresses must be
> confined to devices on PCI
> +//                        Sepment Group 0, Bus 0.  This restriction exists to
> accommodate access
> +//                        to fixed hardware prior to PCI bus enumeration.  The format
> of addresses
> +//                        are defined as follows:
> +//                            Highest WORD: Reserved and must be -0-
> +//                            ...           PCI Device number on bus 0
> +//                            ...           PCI Function number
> +//                            Lowest WORD:  Offset in the configuration space header.
> +//
> +
> +typedef struct {
> +  UINT8                       WdAction;
> +  UINT8                       Flag;
> +  UINT16                      Res;
> +  GENERIC_ADDRESS_STRUCTURE   GenericAddressStructures;
> +  UINT32                      Value;
> +  UINT32                      Mask;
> +} WD_INSTRUCTION;
> +
> +typedef struct {
> +  UINT32                      TimerPeriod;
> +  UINT32                      MaxTimerCount;
> +  UINT32                      MinTimerCount;
> +  UINT16                      InstructionCount;
> +  WD_INSTRUCTION              ActionDefinitions[1];
> +} WD_HOB_DEFINITION;
> +
> +#pragma pack()
> +
> +extern EFI_GUID gWatchdogTimerHobGuid;
> +extern EFI_GUID gWatchdogTimerDefinitionHobGuid;
> +
> +#endif // _EFI_WATCHDOG_TIMER_HOB_GUID_H_
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/IdccData.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/IdccData.h
> new file mode 100644
> index 0000000000..7e3b965666
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/IdccData.h
> @@ -0,0 +1,104 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  IdccData.h
> +
> +Abstract:
> +
> +--*/
> +
> +#ifndef _IDCCDATAHUB_GUID_H_
> +#define _IDCCDATAHUB_GUID_H_
> +
> +//
> +// This GUID is for the IDCC related data found in the Data Hub.
> +//
> +#define IDCC_DATA_HUB_GUID \
> +  { 0x788e1d9f, 0x1eab, 0x47d2, 0xa2, 0xf3, 0x78, 0xca, 0xe8, 0x7d, 0x60,
> 0x12 }
> +
> +extern EFI_GUID gIdccDataHubGuid;
> +
> +#pragma pack(1)
> +
> +typedef struct {
> +  UINT32    Type;
> +  UINT32    RecordLength;
> +} EFI_IDCC_DATA_HEADER;
> +
> +typedef struct {
> +  EFI_IDCC_DATA_HEADER  IdccHeader;
> +  UINT32                Tcontrol;
> +} EFI_IDCC_TCONTROL;
> +
> +typedef struct {
> +  UINT32    EntryCount;
> +} EFI_IDCC_CLOCK_COMMON;
> +
> +typedef struct {
> +  UINT8     Polarity;
> +  UINT8     Percent;
> +  UINT32    FpValue;
> +} EFI_IDCC_TYPE_2_DATA;
> +
> +typedef struct {
> +  UINT8     SetupVal;
> +  UINT32    FpValue;
> +} EFI_IDCC_TYPE_3_4_DATA;
> +
> +typedef struct {
> +  EFI_IDCC_DATA_HEADER  IdccHeader;
> +  UINT32                ProcessorRatio;
> +} EFI_IDCC_PROCESSOR_RATIO;
> +
> +typedef struct {
> +  EFI_IDCC_DATA_HEADER  IdccHeader;
> +  UINT32                BoardFormFactor;
> +} EFI_IDCC_BOARD_FORM_FACTOR;
> +
> +typedef struct {
> +  EFI_IDCC_DATA_HEADER  IdccHeader;
> +  UINT32                ProcessorInfo;
> +} EFI_IDCC_PROCESSOR_INFO;
> +
> +#define EFI_IDCC_PROCESSOR_UNCON    (1 << 0)  // Bit 0: UnCon CPU
> +#define EFI_IDCC_PROCESSOR_UNLOCK   (1 << 1)  // Bit 1: UnLock CPU
> +#define EFI_IDCC_PROCESSOR_CNR      (1 << 2)  // Bit 2: CNR CPU
> +#define EFI_IDCC_PROCESSOR_KNF      (1 << 3)  // Bit 3: KNF CPU
> +
> +typedef struct {
> +  EFI_IDCC_DATA_HEADER  IdccHeader;
> +  UINT32    MinFSB;
> +  UINT32    MaxFSB;
> +  UINT8     StepFSB;
> +} EFI_IDCC_FSB_DATA;
> +
> +#pragma pack()
> +
> +#define EFI_IDCC_POSITIVE   0
> +#define EFI_IDCC_NEGATIVE   1
> +
> +//
> +// Board Form Factor equates.
> +//
> +#define ATX_FORM_FACTOR		0x00
> +#define BTX_FORM_FACTOR		0x01
> +
> +
> +#define EFI_IDCC_TCONTROL_TYPE          1
> +#define EFI_IDCC_FSB_TYPE               2
> +#define EFI_IDCC_PCI_TYPE               3
> +#define EFI_IDCC_PCIE_TYPE              4
> +#define EFI_IDCC_PROC_RATIO_TYPE        5
> +#define EFI_IDCC_BOARD_FORM_FACTOR_TYPE 6
> +#define EFI_IDCC_PROC_INFO_TYPE         7
> +#define EFI_IDCC_FSB_DATA_TYPE          8
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/ItkData.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/ItkData.h
> new file mode 100644
> index 0000000000..e7bd29e6e4
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/ItkData.h
> @@ -0,0 +1,70 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  ItkData.h
> +
> +Abstract:
> +
> +--*/
> +
> +#ifndef _ITKDATAHUB_GUID_H_
> +#define _ITKDATAHUB_GUID_H_
> +
> +//
> +// This GUID is for the ITK related data found in the Data Hub {E7060843-
> A336-4d5b-9598-13402F5D7375}
> +//
> +#define ITK_DATA_HUB_GUID \
> +  { 0xe7060843, 0xa336, 0x4d5b, 0x95, 0x98, 0x13, 0x40, 0x2f, 0x5d, 0x73,
> 0x75 }
> +
> +extern EFI_GUID gItkDataHubGuid;
> +
> +//
> +// This GUID is for the ITK related data found in a Variable  {3812723D-7E48-
> 4e29-BC27-F5A39AC94EF1}
> +//
> +#define ITK_DATA_VAR_GUID \
> +  { 0x3812723d, 0x7e48, 0x4e29, 0xbc, 0x27, 0xf5, 0xa3, 0x9a, 0xc9, 0x4e,
> 0xf1 }
> +
> +extern EFI_GUID gItkDataVarGuid;
> +
> +#define ITK_DATA_VAR_NAME L"ItkDataVar"
> +
> +extern CHAR16 gItkDataVarName[];
> +
> +#define ITK_BIOS_MOD_VAR_NAME L"ItkBiosModVar"
> +
> +extern CHAR16 gItkBiosModVarName[];
> +
> +#pragma pack(1)
> +typedef struct {
> +  UINT32    Type;
> +  UINT32    RecordLength;
> +} EFI_ITK_DATA_HEADER;
> +
> +typedef struct {
> +  EFI_ITK_DATA_HEADER   ItkHeader;
> +  UINT32                HecetaAddress;
> +} EFI_ITK_HECETA_ADDRESS;
> +
> +typedef struct {
> +  UINT16    VarEqName;
> +  UINT16    VarEqValue;
> +} EFI_ITK_VAR_EQ_RECORD;
> +
> +typedef struct {
> +  EFI_ITK_DATA_HEADER   ItkHeader;
> +  EFI_ITK_VAR_EQ_RECORD VarEqRecord[0x10000];
> +} EFI_ITK_VAR_EQ;
> +#pragma pack()
> +
> +#define EFI_ITK_HECETA_ADDRESS_TYPE    1
> +#define EFI_ITK_MOBILE_BIOS_TYPE       2
> +#define EFI_ITK_VAR_EQ_TYPE            3
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/MemoryConfigData.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/MemoryConfigData.h
> new file mode 100644
> index 0000000000..0fe759a16e
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/MemoryConfigData.h
> @@ -0,0 +1,32 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +
> +Module Name:
> +
> +  MemoryConfigData.h
> +
> +Abstract:
> +
> +  GUID used for Memory Configuration Data entries in the HOB list.
> +
> +--*/
> +
> +#ifndef _MEMORY_CONFIG_DATA_GUID_H_
> +#define _MEMORY_CONFIG_DATA_GUID_H_
> +
> +#define EFI_MEMORY_CONFIG_DATA_GUID \
> +  { \
> +    0x80dbd530, 0xb74c, 0x4f11, 0x8c, 0x03, 0x41, 0x86, 0x65, 0x53, 0x28, 0x31
> \
> +  }
> +
> +extern EFI_GUID gEfiMemoryConfigDataGuid;
> +extern CHAR16   EfiMemoryConfigVariable[];
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/OsSelection.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/OsSelection.h
> new file mode 100644
> index 0000000000..e7bbcf67c9
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/OsSelection.h
> @@ -0,0 +1,85 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  OsSelection.h
> +
> +Abstract:
> +
> +  GUID used for LPSS, SCC and LPE configuration data entries in the HOB list.
> +
> +--*/
> +
> +#ifndef _OS_SELECTION_GUID_H_
> +#define _OS_SELECTION_GUID_H_
> +
> +#ifndef ECP_FLAG
> +#include <PiPei.h>
> +
> +#include <Library/HobLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/DebugLib.h>
> +#endif
> +
> +#define ANDROID 1
> +
> +#define EFI_OS_SELECTION_VARIABLE_GUID \
> +  { \
> +    0x86843f56, 0x675d, 0x40a5, 0x95, 0x30, 0xbc, 0x85, 0x83, 0x72, 0xf1, 0x03
> \
> +  }
> +
> +extern EFI_GUID gOsSelectionVariableGuid;
> +
> +#pragma pack(1)
> +
> +typedef struct {
> +  UINT8           LpssPciModeEnabled;
> +  //SCC
> +  UINT8           LpsseMMCEnabled;
> +  UINT8           LpssSdioEnabled;
> +  UINT8           LpssSdcardEnabled;
> +  UINT8           LpssSdCardSDR25Enabled;
> +  UINT8           LpssSdCardDDR50Enabled;
> +  UINT8           LpssMipiHsi;
> +  UINT8           LpsseMMC45Enabled;
> +  UINT8           LpsseMMC45DDR50Enabled;
> +  UINT8           LpsseMMC45HS200Enabled;
> +  UINT8           LpsseMMC45RetuneTimerValue;
> +  UINT8           eMMCBootMode;
> +  //LPSS2
> +  UINT8           LpssDma1Enabled;
> +  UINT8           LpssI2C0Enabled;
> +  UINT8           LpssI2C1Enabled;
> +  UINT8           LpssI2C2Enabled;
> +  UINT8           LpssI2C3Enabled;
> +  UINT8           LpssI2C4Enabled;
> +  UINT8           LpssI2C5Enabled;
> +  UINT8           LpssI2C6Enabled;
> +  //LPSS1
> +  UINT8           LpssDma0Enabled;
> +  UINT8           LpssPwm0Enabled;
> +  UINT8           LpssPwm1Enabled;
> +  UINT8           LpssHsuart0Enabled;
> +  UINT8           LpssHsuart1Enabled;
> +  UINT8           LpssSpiEnabled;
> +  UINT8           I2CTouchAd;
> +} EFI_PLATFORM_LPSS_DATA;
> +
> +typedef struct _EFI_OS_SELECTION_HOB {
> +  UINT8                       OsSelection;
> +  UINT8                       OsSelectionChanged;
> +  UINT8                       Lpe;
> +  UINT8                       PchAzalia;
> +  EFI_PLATFORM_LPSS_DATA      LpssData;
> +} EFI_OS_SELECTION_HOB;
> +
> +#pragma pack()
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PciLanInfo.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PciLanInfo.h
> new file mode 100644
> index 0000000000..46c45b0303
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PciLanInfo.h
> @@ -0,0 +1,39 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  PciLanInfo.h
> +
> +Abstract:
> +
> +--*/
> +
> +#ifndef _PCI_LAN_INFO_GUID_H_
> +#define _PCI_LAN_INFO_GUID_H_
> +
> +#pragma pack(1)
> +
> +//
> +// structure used for Pci Lan variable
> +//
> +typedef struct {
> +  UINT8         PciBus;
> +  UINT8         PciDevice;
> +  UINT8         PciFunction;
> +} PCI_LAN_INFO;
> +
> +#pragma pack()
> +
> +#define EFI_PCI_LAN_INFO_GUID \
> +  {0xd9a1427, 0xe02a, 0x437d, 0x92, 0x6b, 0xaa, 0x52, 0x1f, 0xd7, 0x22, 0xba};
> +
> +extern EFI_GUID gEfiPciLanInfoGuid;
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformCpuInfo.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformCpuInfo.h
> new file mode 100644
> index 0000000000..f1756662bd
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformCpuInfo.h
> @@ -0,0 +1,180 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  PlatformCpuInfo.h
> +
> +Abstract:
> +
> +  GUID used for Platform CPU Info Data entries in the HOB list.
> +
> +--*/
> +
> +#ifndef _PLATFORM_CPU_INFO_GUID_H_
> +#define _PLATFORM_CPU_INFO_GUID_H_
> +
> +#include "CpuType.h"
> +#include <Library/CpuIA32.h>
> +
> +#define EFI_PLATFORM_CPU_INFO_GUID \
> +  {\
> +    0xbb9c7ab7, 0xb8d9, 0x4bf3, 0x9c, 0x29, 0x9b, 0xf3, 0x41, 0xe2, 0x17, 0xbc
> \
> +  }
> +
> +extern EFI_GUID gEfiPlatformCpuInfoGuid;
> +extern CHAR16   EfiPlatformCpuInfoVariable[];
> +
> +//
> +// Tri-state for feature capabilities and enable/disable.
> +// [0] clear=feature isn't capable
> +// [0] set  =feature is capable
> +// [1] clear=feature is disabled
> +// [1] set  =feature is enabled
> +//
> +#define CPU_FEATURES_CAPABLE      BIT0
> +#define CPU_FEATURES_ENABLE       BIT1
> +
> +#define MAX_CACHE_DESCRIPTORS     64
> +#define MAXIMUM_CPU_BRAND_STRING_LENGTH 48
> +
> +#pragma pack(1)
> +
> +typedef struct {
> +  UINT32              FullCpuId;                // [31:0] & 0x0FFF0FFF
> +  UINT32              FullFamilyModelId;        // [31:0] & 0x0FFF0FF0
> +  UINT8               ExtendedFamilyId;         // [27:20]
> +  UINT8               ExtendedModelId;          // [19:16]
> +  UINT8               ProcessorType;            // [13:11]
> +  UINT8               FamilyId;                 // [11:8]
> +  UINT8               Model;                    // [7:4]
> +  UINT8               SteppingId;               // [3:0]
> +} EFI_CPU_VERSION_INFO; // CPUID.1.EAX
> +
> +typedef struct {
> +  UINT32              L1InstructionCacheSize;
> +  UINT32              L1DataCacheSize;
> +  UINT32              L2CacheSize;
> +  UINT32              L3CacheSize;
> +  UINT32              TraceCacheSize;
> +  UINT8               CacheDescriptor[MAX_CACHE_DESCRIPTORS];
> +} EFI_CPU_CACHE_INFO; // CPUID.2.EAX
> +
> +typedef struct {
> +  UINT8               PhysicalPackages;
> +  UINT8               LogicalProcessorsPerPhysicalPackage;
> +  UINT8               CoresPerPhysicalPackage;
> +  UINT8               ThreadsPerCore;
> +} EFI_CPU_PACKAGE_INFO; // CPUID.4.EAX
> +
> +typedef struct {
> +  UINT32              RegEdx;                   // CPUID.5.EAX
> +  UINT8               MaxCState;
> +  UINT8               C0SubCStatesMwait;        // EDX [3:0]
> +  UINT8               C1SubCStatesMwait;        // EDX [7:4]
> +  UINT8               C2SubCStatesMwait;        // EDX [11:8]
> +  UINT8               C3SubCStatesMwait;        // EDX [15:12]
> +  UINT8               C4SubCStatesMwait;        // EDX [19:16]
> +  UINT8               C5SubCStatesMwait;        // EDX [23:20]
> +  UINT8               C6SubCStatesMwait;        // EDX [27:24]
> +  UINT8               C7SubCStatesMwait;        // EDX [31:28]
> +  UINT8               MonitorMwaitSupport;      // ECX [0]
> +  UINT8               InterruptsBreakMwait;     // ECX [1]
> +} EFI_CPU_CSTATE_INFO; // CPUID.5.EAX
> +
> +typedef struct {
> +  UINT8               Turbo;                    // EAX [1]
> +  UINT8               PECI;                     // EAX [0]
> +  UINT8               NumIntThresholds;         // EBX [3:0]
> +  UINT8               HwCoordinationFeedback;   // ECX [0]
> +} EFI_CPU_POWER_MANAGEMENT; // CPUID.6.EAX
> +
> +//
> +// IMPORTANT: Each CPU feature enabling entry is assumed a tri-state
> variable.
> +//   - Keep the respective feature entry variable as default value (0x00)
> +//     if the CPU is not capable for the feature.
> +//   - Use the specially defined programming convention to update the
> variable
> +//     to indicate capable, enable or disable.
> +//     ie. F_CAPABLE for feature available
> +//         F_ENABLE for feature enable
> +//         F_DISABLE for feature disable
> +//
> +typedef struct {
> +  EFI_CPUID_REGISTER  Regs;                     // CPUID.1.EAX
> +  UINT8               Xapic;                    // ECX [21]
> +  UINT8               SSE4_2;                   // ECX [20]
> +  UINT8               SSE4_1;                   // ECX [19]
> +  UINT8               Dca;                      // ECX [18]
> +  UINT8               SupSSE3;                  // ECX [9]
> +  UINT8               Tm2;                      // ECX [8]
> +  UINT8               Eist;                     // ECX [7]
> +  UINT8               Lt;                       // ECX [6]
> +  UINT8               Vt;                       // ECX [5]
> +  UINT8               Mwait;                    // ECX [3]
> +  UINT8               SSE3;                     // ECX [0]
> +  UINT8               Tcc;                      // EDX [29]
> +  UINT8               Mt;                       // EDX [28]
> +  UINT8               SSE2;                     // EDX [26]
> +  UINT8               SSE;                      // EDX [25]
> +  UINT8               MMX;                      // EDX [23]
> +  EFI_CPUID_REGISTER  ExtRegs;                  // CPUID.80000001.EAX
> +  UINT8               ExtLahfSahf64;            // ECX [0]
> +  UINT8               ExtIntel64;               // EDX [29]
> +  UINT8               ExtXd;                    // EDX [20]
> +  UINT8               ExtSysCallRet64;          // EDX [11]
> +  UINT16              Ht;                       // CPUID.0B.EAX EBX [15:0]
> +} EFI_CPU_FEATURES; // CPUID.1.EAX, CPUID.0B.EAX, CPUID.80000001.EAX
> +
> +typedef struct {
> +  UINT8               PhysicalBits;
> +  UINT8               VirtualBits;
> +} EFI_CPU_ADDRESS_BITS; // CPUID.80000008.EAX
> +
> +typedef struct {
> +  UINT8               PlatformID;               // MSR 0x17 [52:50]
> +  UINT32              MicrocodeRevision;        // MSR 0x8B [63:32]
> +  UINT8               MaxEfficiencyRatio;       // MSR 0xCE [47:40]
> +  UINT8               DdrRatioUnlockCap;        // MSR 0xCE [30]
> +  UINT8               TdcTdpLimitsTurbo;        // MSR 0xCE [29]
> +  UINT8               RatioLimitsTurbo;         // MSR 0xCE [28]
> +  UINT8               PreProduction;            // MSR 0xCE [27]
> +  UINT8               DcuModeSelect;            // MSR 0xCE [26]
> +  UINT8               MaxNonTurboRatio;         // MSR 0xCE [15:8]
> +  UINT8               Emrr;                     // MSR 0xFE [12]
> +  UINT8               Smrr;                     // MSR 0xFE [11]
> +  UINT8               VariableMtrrCount;        // MSR 0xFE [7:0]
> +  UINT16              PState;                   // MSR 0x198 [15:0]
> +  UINT8               TccActivationTemperature; // MSR 0x1A2 [23:16]
> +  UINT8               TemperatureControlOffset; // MSR 0x1A2 [15:8]
> +  UINT32              PCIeBar;                  // MSR 0x300 [39:20]
> +  UINT8               PCIeBarSizeMB;            // MSR 0x300 [3:1]
> +} EFI_MSR_FEATURES;
> +
> +typedef struct {
> +  BOOLEAN                            IsIntelProcessor;
> +  UINT8
> BrandString[MAXIMUM_CPU_BRAND_STRING_LENGTH + 1];
> +  UINT32                             CpuidMaxInputValue;
> +  UINT32                             CpuidMaxExtInputValue;
> +  EFI_CPU_UARCH                      CpuUarch;
> +  EFI_CPU_FAMILY                     CpuFamily;
> +  EFI_CPU_PLATFORM                   CpuPlatform;
> +  EFI_CPU_TYPE                       CpuType;
> +  EFI_CPU_VERSION_INFO               CpuVersion;
> +  EFI_CPU_CACHE_INFO                 CpuCache;
> +  EFI_CPU_FEATURES                   CpuFeatures;
> +  EFI_CPU_CSTATE_INFO                CpuCState;
> +  EFI_CPU_PACKAGE_INFO               CpuPackage;
> +  EFI_CPU_POWER_MANAGEMENT           CpuPowerManagement;
> +  EFI_CPU_ADDRESS_BITS               CpuAddress;
> +  EFI_MSR_FEATURES                   Msr;
> +} EFI_PLATFORM_CPU_INFO;
> +
> +#pragma pack()
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformInfo.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformInfo.h
> new file mode 100644
> index 0000000000..cac31e2a40
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformInfo.h
> @@ -0,0 +1,433 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +
> +Module Name:
> +
> +  PlatformInfo.h
> +
> +Abstract:
> +
> +  GUID used for Platform Info Data entries in the HOB list.
> +
> +--*/
> +
> +#ifndef _PLATFORM_INFO_GUID_H_
> +#define _PLATFORM_INFO_GUID_H_
> +
> +#ifndef ECP_FLAG
> +#include <PiPei.h>
> +
> +#include <Library/HobLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/SmbusLib.h>
> +#include <IndustryStandard/SmBus.h>
> +#endif
> +
> +#define PLATFORM_INFO_REVISION = 1      // Revision id for current
> platform information struct.
> +
> +//
> +// Start::BayLake Board Defines
> +//
> +#define BOARD_REVISION_DEFAULT = 0xff
> +#define UNKNOWN_FABID		0x0F
> +#define FAB_ID_MASK			0x0F
> +#define BOARD_ID_2   0x01
> +#define BOARD_ID_1   0x40
> +#define BOARD_ID_0   0x04
> +
> +#define BOARD_ID_DT_CRB     0x0
> +#define BOARD_ID_DT_VLVR    0x1
> +#define BOARD_ID_SVP_VLV    0xC
> +#define BOARD_ID_SVP_EV_VLV 0xD
> +//
> +// End::BayLake Board Defines
> +//
> +
> +//
> +// Start::Alpine Valley Board Defines
> +//
> +#define DC_ID_DDR3L      0x00
> +#define DC_ID_DDR3       0x04
> +#define DC_ID_LPDDR3     0x02
> +#define DC_ID_LPDDR2     0x06
> +#define DC_ID_DDR4       0x01
> +#define DC_ID_DDR3L_ECC  0x05
> +#define DC_ID_NO_MEM     0x07
> +//
> +// End::Alpine Valley Board Defines
> +//
> +
> +#define MAX_FAB_ID_RETRY_COUNT  100
> +#define MAX_FAB_ID_CHECK_COUNT  3
> +
> +#define PLATFORM_INFO_HOB_REVISION	0x1
> +
> +#define EFI_PLATFORM_INFO_GUID \
> +  { \
> +    0x1e2acc41, 0xe26a, 0x483d, 0xaf, 0xc7, 0xa0, 0x56, 0xc3, 0x4e, 0x8, 0x7b \
> +  }
> +
> +extern EFI_GUID gEfiPlatformInfoGuid;
> +
> +typedef enum {
> +  FlavorUnknown = 0,
> +
> +  //
> +  // Mobile
> +  //
> +  FlavorMobile = 1,
> +
> +  //
> +  // Desktop
> +  //
> +  FlavorDesktop = 2,
> +
> +  //
> +  // Tablet
> +  //
> +  FlavorTablet = 3
> +} PLATFORM_FLAVOR;
> +
> +#pragma pack(1)
> +
> +typedef struct {
> +  UINT16  PciResourceIoBase;
> +  UINT16  PciResourceIoLimit;
> +  UINT32  PciResourceMem32Base;
> +  UINT32  PciResourceMem32Limit;
> +  UINT64  PciResourceMem64Base;
> +  UINT64  PciResourceMem64Limit;
> +  UINT64  PciExpressBase;
> +  UINT32  PciExpressSize;
> +  UINT8   PciHostAddressWidth;
> +  UINT8   PciResourceMinSecBus;
> +} EFI_PLATFORM_PCI_DATA;
> +
> +typedef struct {
> +  UINT8 CpuAddressWidth;
> +  UINT32 CpuFamilyStepping;
> +} EFI_PLATFORM_CPU_DATA;
> +
> +typedef struct {
> +  UINT8 SysIoApicEnable;
> +  UINT8 SysSioExist;
> +} EFI_PLATFORM_SYS_DATA;
> +
> +typedef struct {
> +  UINT32  MemTolm;
> +  UINT32  MemMaxTolm;
> +  UINT32  MemTsegSize;
> +  UINT32  MemTsegBase;
> +  UINT32  MemIedSize;
> +  UINT32  MemIgdSize;
> +  UINT32  MemIgdBase;
> +  UINT32  MemIgdGttSize;
> +  UINT32  MemIgdGttBase;
> +  UINT64  MemMir0;
> +  UINT64  MemMir1;
> +  UINT32  MemConfigSize;
> +  UINT16  MmioSize;
> +  UINT8   DdrFreq;
> +  UINT8   DdrType;
> +  UINT32  MemSize;
> +  BOOLEAN EccSupport;
> +  UINT8   Reserved[3];
> +  UINT16  DimmSize[2];
> +} EFI_PLATFORM_MEM_DATA;
> +
> +
> +typedef struct {
> +  UINT32 IgdOpRegionAddress;    // IGD OpRegion Starting Address
> +  UINT8  IgdBootType;           // IGD Boot Display Device
> +  UINT8  IgdPanelType;          // IGD Panel Type CMOs option
> +  UINT8  IgdTvFormat;           // IGD TV Format CMOS option
> +  UINT8  IgdTvMinor;            // IGD TV Minor Format CMOS option
> +  UINT8  IgdPanelScaling;       // IGD Panel Scaling
> +  UINT8  IgdBlcConfig;          // IGD BLC Configuration
> +  UINT8  IgdBiaConfig;          // IGD BIA Configuration
> +  UINT8  IgdSscConfig;          // IGD SSC Configuration
> +  UINT8  IgdDvmtMemSize;        // IGD DVMT Memory Size
> +  UINT8  IgdFunc1Enable;        // IGD Function 1 Enable
> +  UINT8  IgdHpllVco;            // HPLL VCO
> +  UINT8  IgdSciSmiMode;         // GMCH SMI/SCI mode (0=SCI)
> +  UINT8  IgdPAVP;               // IGD PAVP data
> +} EFI_PLATFORM_IGD_DATA;
> +
> +typedef enum {
> +  BOARD_ID_AV_SVP   = 0x0,    // Alpine Valley Board
> +  BOARD_ID_BL_RVP   = 0x2,    // BayLake Board (RVP)
> +  BOARD_ID_BL_FFRD8 = 0x3,    // FFRD8 b'0011
> +  BOARD_ID_BL_FFRD  = 0x4,    // BayLake Board (FFRD)
> +  BOARD_ID_BL_RVP_DDR3L  = 0x5,    // BayLake Board (RVP DDR3L)
> +  BOARD_ID_BL_STHI  = 0x7,    // PPV- STHI Board
> +  BOARD_ID_BB_RVP   = 0x20,   // Bayley Bay Board
> +  BOARD_ID_BS_RVP   = 0x30,   // Bakersport Board
> +  BOARD_ID_CVH      = 0x90,   // Crestview Hills
> +  BOARD_ID_MINNOW2  = 0xA0,    // MinnowBorad Max
> +  BOARD_ID_MINNOW2_TURBOT  = 0xB0    // MinnowBoard Turbot
> +
> +} BOARD_ID_LIST;
> +
> +typedef enum {
> +  FAB1 = 0,
> +  FAB2 = 1,
> +  FAB3 = 2
> +} FAB_ID_LIST;
> +
> +typedef enum {
> +    PR0  = 0,   // FFRD PR0
> +    PR05 = 1,   // FFRD PR0.3 and PR 0.5
> +    PR1  = 2,   // FFRD PR1
> +    PR11 = 3    // FFRD PR1.1
> +} FFRD_ID_LIST;
> +
> +
> +//
> +// VLV2 GPIO GROUP OFFSET
> +//
> +#define GPIO_SCORE_OFFSET	0x0000
> +#define GPIO_NCORE_OFFSET	0x1000
> +#define GPIO_SSUS_OFFSET	0x2000
> +
> +//
> +// GPIO Initialization Data Structure for BayLake.
> +// SC = SCORE, SS= SSUS
> +// Note: NC doesn't support GPIO functionality in IO access mode, only
> support in MMIO access mode.
> +//
> +
> +//
> +// IO space
> +//
> +typedef struct{
> +  UINT32  Use_Sel_SC0;
> +  UINT32  Use_Sel_SC1;
> +  UINT32  Use_Sel_SC2;
> +  UINT32  Use_Sel_SS;
> +
> +  UINT32  Io_Sel_SC0;
> +  UINT32  Io_Sel_SC1;
> +  UINT32  Io_Sel_SC2;
> +  UINT32  Io_Sel_SS;
> +
> +  UINT32  GP_Lvl_SC0;
> +  UINT32  GP_Lvl_SC1;
> +  UINT32  GP_Lvl_SC2;
> +  UINT32  GP_Lvl_SS;
> +
> +  UINT32  TPE_SC0;
> +  UINT32  TPE_SS;
> +
> +  UINT32  TNE_SC0;
> +  UINT32  TNE_SS;
> +
> +  UINT32  TS_SC0;
> +  UINT32  TS_SS;
> +
> +  UINT32  WE_SS;
> +} CFIO_INIT_STRUCT;
> +
> +
> +
> +//
> +// CFIO PAD configuration Registers
> +//
> +//
> +// Memory space
> +//
> +typedef union {
> +  UINT32 dw;
> +  struct {
> +    UINT32 Func_Pin_Mux:3;  // 0:2 Function of CFIO selection
> +    UINT32 ipslew:2; // 3:4 Pad (P) Slew Rate Controls PAD slew rate check
> Width
> +    UINT32 inslew:2; // 5:6 Pad (N) Slew Rate Controls PAD slew rate
> +    UINT32 Pull_assign:2; // 7:8 Pull assignment
> +    UINT32 Pull_strength:2; // 9:10 Pull strength
> +    UINT32 Bypass_flop:1; // 11 Bypass flop
> +    UINT32 Filter_en:1; // 12 Filter Enable
> +    UINT32 Hist_ctrl:2; // 13:14 hysteresis control
> +    UINT32 Hist_enb:1; // 15 Hysteresis enable, active low
> +    UINT32 Delay_line:6; // 16:21 Delay line values - Delay values for input or
> output
> +    UINT32 Reserved:3; // 22:24 Reserved
> +    UINT32 TPE:1; // 25 Trigger Positive Edge Enable
> +    UINT32 TNE:1; // 26 Trigger Negative Edge Enable
> +    UINT32 Reserved2:3; // 27:29 Reserved
> +    UINT32 i1p5sel:1; // 30
> +    UINT32 IODEN:1; // 31 : Open Drain enable. Active high
> +	} r;
> +} PAD_CONF0;
> +
> +typedef union{
> +  UINT32 dw;
> +  struct {
> +    UINT32 instr:16; // 0:15 Pad (N) strength.
> +    UINT32 ipstr:16; // 16:31 Pad (P) strength.
> +  }r;
> +} PAD_CONF1;
> +
> +typedef union{
> +  UINT32 dw;
> +  struct {
> +    UINT32 pad_val:1; // 0 These registers are implemented as dual
> read/write with dedicated storage each.
> +    UINT32 ioutenb:1; // 1 output enable
> +    UINT32 iinenb:1; // 2 input enable
> +    UINT32 Reserved:29; // 3:31 Reserved
> +  }r;
> +} PAD_VAL;
> +
> +typedef union{
> +  UINT32 GPI;
> +  struct {
> +    UINT32 ihbpen:1; // 0 Pad high by pass enable
> +    UINT32 ihbpinen:1; // 1 Pad high by pass input
> +    UINT32 instaticen:1; // 2 TBD
> +    UINT32 ipstaticen:1; // 3 TBD
> +    UINT32 Overide_strap_pin :1; // 4 DFX indicates if it wants to override the
> strap pin value on this pad, if exists.
> +    UINT32 Overide_strap_pin_val:1; // 5 In case DFX need to override strap
> pin value and it exist for the specific pad, this value will be used.
> +    UINT32 TestMode_Pin_Mux:3; // 6:9 DFX Pin Muxing
> +  }r;
> +} PAD_DFT;
> +
> +//
> +// GPIO_USAGE value need to matche the PAD_VAL input/output enable
> bits.
> +//
> +typedef enum {
> +  Native = 0xFF,  // Native, no need to set PAD_VALUE
> +  GPI = 2,    // GPI, input only in PAD_VALUE
> +  GPO = 4,    // GPO, output only in PAD_VALUE
> +  GPIO = 0,      // GPIO, input & output
> +  TRISTS = 6,      // Tri-State
> +  GPIO_NONE
> +} GPIO_USAGE;
> +
> +typedef enum {
> +  LO = 0,
> +  HI = 1,
> +  NA = 0xFF
> +} GPO_D4;
> +
> +typedef enum {
> +  F0 = 0,
> +  F1 = 1,
> +  F2 = 2,
> +  F3 = 3,
> +  F4 = 4,
> +  F5 = 5,
> +  F6 = 6,
> +  F7 = 7
> +} GPIO_FUNC_NUM;
> +
> +//
> +// Mapping to CONF0 bit 27:24
> +// Note: Assume "Direct Irq En" is not set, unless specially notified.
> +//
> +typedef enum {
> +  TRIG_ = 0,
> +  TRIG_Edge_High = /*BIT3 |*/ BIT1,	// Positive Edge (Rasing)
> +  TRIG_Edge_Low  = /*BIT3 |*/ BIT2,	// Negative Edge (Falling)
> +  TRIG_Edge_Both = /*BIT3 |*/ BIT2 | BIT1,	// Both Edge
> +  TRIG_Level_High= /*BIT3 |*/ BIT1 | BIT0,	// Level High
> +  TRIG_Level_Low = /*BIT3 |*/ BIT2 | BIT0,	// Level Low
> +} INT_TYPE;
> +
> +typedef enum {
> +  P_20K_H,	// Pull Up 20K
> +  P_20K_L,	// Pull Down 20K
> +  P_10K_H,	// Pull Up 10K
> +  P_10K_L,	// Pull Down 10K
> +  P_2K_H,	// Pull Up 2K
> +  P_2K_L,	// Pull Down 2K
> +  P_NONE      // Pull None
> +} PULL_TYPE;
> +
> +#ifdef EFI_DEBUG
> +  #define GPIO_INIT_ITEM(pad_name, usage, gpod4, func, int_cap,
> int_type, pull, offset) {pad_name, usage, gpod4, func, /*int_cap,*/
> TRIG_##int_type, P_##pull, offset}
> +#else
> +  #define GPIO_INIT_ITEM(pad_name, usage, gpod4, func, int_cap,
> int_type, pull, offset) {          usage, gpod4, func, /*int_cap,*/
> TRIG_##int_type, P_##pull, offset}
> +#endif
> +
> +//
> +// GPIO CONF & PAD Initialization Data Structure for BayLake GPIOs bits.
> +// NC = NCORE, SC = SCORE, SS= SSUS
> +//
> +typedef struct {
> +
> +#ifdef EFI_DEBUG
> +  char         pad_name[32];// GPIO Pin Name for debug purpose
> +#endif
> +
> +  GPIO_USAGE     usage;     // GPIO pin used as Native mode or
> GPI/GPO/GPIO mode
> +  GPO_D4         gpod4;     // GPO default value
> +  GPIO_FUNC_NUM  func;      // Function Number (F0~F7)
> +  INT_TYPE       int_type;  // Edge or Level trigger, low or high active
> +  PULL_TYPE      pull;      // Pull Up or Down
> +  UINT8          offset;    // Equal with (PCONF0 register offset >> 4 bits)
> +} GPIO_CONF_PAD_INIT;
> +
> +//
> +//typedef UINT64 BOARD_FEATURES
> +//
> +typedef struct _EFI_PLATFORM_INFO_HOB {
> +  UINT16                      PlatformType; // Platform Type
> +  UINT8                       BoardId;             // Board ID
> +  UINT8                       BoardRev;            // Board Revision
> +  PLATFORM_FLAVOR             PlatformFlavor;      // Platform Flavor
> +  UINT8                       DDRDaughterCardCh0Id;// DDR daughter card channel 0
> id
> +  UINT8                       DDRDaughterCardCh1Id;// DDR daughter card channel 1
> id
> +  UINT8                       ECOId;               // ECO applied on platform
> +  UINT16                      IohSku;
> +  UINT8                       IohRevision;
> +  UINT16                      IchSku;
> +  UINT8                       IchRevision;
> +  EFI_PLATFORM_PCI_DATA       PciData;
> +  EFI_PLATFORM_CPU_DATA       CpuData;
> +  EFI_PLATFORM_MEM_DATA       MemData;
> +  EFI_PLATFORM_SYS_DATA       SysData;
> +  EFI_PLATFORM_IGD_DATA       IgdData;
> +  UINT8                       RevisonId;           // Structure Revision ID
> +  EFI_PHYSICAL_ADDRESS        PlatformCfioData;
> +  EFI_PHYSICAL_ADDRESS        PlatformGpioData_NC;
> +  EFI_PHYSICAL_ADDRESS        PlatformGpioData_SC;
> +  EFI_PHYSICAL_ADDRESS        PlatformGpioData_SUS;
> +  EFI_PHYSICAL_ADDRESS        PlatformGpioData_NC_TRI;
> +  EFI_PHYSICAL_ADDRESS        PlatformGpioData_SC_TRI;
> +  EFI_PHYSICAL_ADDRESS        PlatformGpioData_SUS_TRI;
> +  EFI_PHYSICAL_ADDRESS        PlatformGpioData_SUS_PR1;
> +  EFI_PHYSICAL_ADDRESS        PlatformGpioData_SC_PR1_1;
> +  EFI_PHYSICAL_ADDRESS        PlatformGpioData_SUS_PR1_1;
> +
> +  UINT8                       CfioEnabled;
> +  UINT32                      SsidSvid;
> +  UINT16                      AudioSubsystemDeviceId;
> +  UINT64                      AcpiOemId;
> +  UINT64                      AcpiOemTableId;
> +  UINT16                      MemCfgID;
> +} EFI_PLATFORM_INFO_HOB;
> +
> +#pragma pack()
> +
> +EFI_STATUS
> +GetPlatformInfoHob (
> +  IN CONST EFI_PEI_SERVICES           **PeiServices,
> +  OUT EFI_PLATFORM_INFO_HOB           **PlatformInfoHob
> +  );
> +
> +
> +EFI_STATUS
> +InstallPlatformClocksNotify (
> +  IN CONST EFI_PEI_SERVICES           **PeiServices
> +  );
> +
> +EFI_STATUS
> +InstallPlatformSysCtrlGPIONotify (
> +  IN CONST EFI_PEI_SERVICES           **PeiServices
> +  );
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SensorInfoVariable.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SensorInfoVariable.h
> new file mode 100644
> index 0000000000..19eee2b729
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SensorInfoVariable.h
> @@ -0,0 +1,279 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +
> +Module Name:
> +
> +  SensorInfoVariable.h
> +
> +Abstract:
> +
> +  GUID used for Sensor Info variable.
> +
> +--*/
> +
> +
> +//
> +//  Module:         SensorInfoVariable.h
> +//
> +//  Description:    Provides  structure  and  literal  definitions for the
> +//                  Sensor Information Variable.  The  BIOS  will  provide
> +//                  this  variable  to  runtime  applications  via the EFI
> +//                  GetVariable function.
> +//
> +//  Notes:      1.  When defining and initializing the variable within the
> +//                  BIOS, the module will define the structure  using  the
> +//                  typedef  macros  in  a block. For an ATX board using a
> +//                  single Heceta 6P, which has 4 temperature  sensors,  6
> +//                  voltage  sensors,  4 fan speed sensors and 3 fan speed
> +//                  controllers, this block would be declared as follows:
> +//
> +//                      TYPEDEF_TEMP_SENSOR_SECTION(4);
> +//                      TYPEDEF_VOLT_SENSOR_SECTION(6);
> +//                      TYPEDEF_FAN_SENSOR_SECTION(4);
> +//                      TYPEDEF_FAN_CONTROLLER_SENSOR(3);
> +//                      TYPEDEF_SENSOR_INFO_VAR;
> +//
> +//              2.  When crafting code to access the variable, the  module
> +//                  will  also  need  to  invoke  the  typedef macros in a
> +//                  block but, since it cannot declare a structure for the
> +//                overall variable (because array lengths will vary), it
> +//                cannot  use  TYPEDEF_SENSOR_INFO_VAR.  The  block will
> +//                typically be used as follows:
> +//
> +//                      TYPEDEF_TEMP_SENSOR_SECTION(1);
> +//                     TYPEDEF_VOLT_SENSOR_SECTION(1);
> +//                     TYPEDEF_FAN_SENSOR_SECTION(1);
> +//                     TYPEDEF_FAN_CONTROLLER_SENSOR(1);
> +//
> +//                 The structure buffer should instead be declared  as  a
> +//                 BYTE  array. Pointers to the various sections can then
> +//                  be built using the XXXX_SECTION_LEN macros...
> +//
> +
> +
> +#ifndef _SENSOR_INFO_VAR_GUID_H_
> +#define _SENSOR_INFO_VAR_GUID_H_
> +
> +#define SENSOR_INFO_VAR_GUID \
> +  { \
> +    0xE59E7B4D, 0x06DC, 0x44AB, 0xB3, 0x6D, 0x5E, 0xD7, 0x78, 0x9C, 0x53,
> 0x0A \
> +  }
> +
> +extern EFI_GUID gEfiSensorInfoVarGuid;
> +extern CHAR16   gEfiSensorInfoVarName[];
> +extern CHAR16   gEfiSensorInfoVarNameWithPassword[];
> +
> +#define SENSOR_INFO_VAR_NAME L"SensorInfoVar"
> +#define SENSOR_INFO_VAR_NAME_WITH_PASSWORD
> SENSOR_INFO_VAR_NAME L"S4k?A^7!"
> +
> +//
> +// Sensor/Controller usage definitions
> +//
> +
> +#define UNKNOWN_OTHER                   0
> +
> +//
> +// Temperature Sensors
> +//
> +#define CPU_CORE_TEMPERATURE            1
> +#define CPU_DIE_TEMPERATURE             2
> +#define ICH_TEMPERATURE                 3
> +#define MCH_TEMPERATURE                 4
> +#define VR_TEMPERATURE                  5
> +#define MEMORY_TEMPERATURE              6
> +#define MOTHERBOARD_AMBIENT_TEMPERATURE 7
> +#define SYSTEM_AMBIENT_AIR_TEMPERATURE  8
> +#define CPU_INLET_AIR_TEMPERATURE       9
> +#define SYSTEM_INLET_AIR_TEMPERATURE    10
> +#define SYSTEM_OUTLET_AIR_TEMPERATURE   11
> +#define PSU_HOTSPOT_TEMPERATURE         12
> +#define PSU_INLET_AIR_TEMPERATURE       13
> +#define PSU_OUTLET_AIR_TEMPERATURE      14
> +#define DRIVE_TEMPERATURE               15
> +#define GPU_TEMPERATURE                 16
> +#define IOH_TEMPERATURE                 17
> +
> +#define LAST_TEMPERATURE                17
> +
> +//
> +// Voltage Sensors
> +//
> +#define PLUS_12_VOLTS                   1
> +#define NEG_12_VOLTS                    2
> +#define PLUS_5_VOLTS                    3
> +#define PLUS_5_VOLT_BACKUP              4
> +#define NEG_5_VOLTS                     5
> +#define PLUS_3P3_VOLTS                  6
> +#define PLUS_2P5_VOLTS                  7
> +#define PLUS_1P5_VOLTS                  8
> +#define CPU_1_VCCP_VOLTAGE              9
> +#define CPU_2_VCCP_VOLTAGE              10
> +#define CPU_3_VCCP_VOLTAGE              11
> +#define CPU_4_VCCP_VOLTAGE              12
> +#define PSU_INPUT_VOLTAGE               13
> +#define MCH_VCC_VOLTAGE                 14
> +#define PLUS_3P3_VOLT_STANDBY           15
> +#define CPU_VTT_VOLTAGE                 16
> +#define PLUS_1P8_VOLTS                  17
> +
> +#define LAST_VOLTAGE                    17
> +
> +//
> +// Fan Speed Sensors and Controllers.
> +//
> +#define CPU_COOLING_FAN                 1
> +#define SYSTEM_COOLING_FAN              2
> +#define MCH_COOLING_FAN                 3
> +#define VR_COOLING_FAN                  4
> +#define CHASSIS_COOLING_FAN             5
> +#define CHASSIS_INLET_FAN               6
> +#define CHASSIS_OUTLET_FAN              7
> +#define PSU_COOLING_FAN                 8
> +#define PSU_INLET_FAN                   9
> +#define PSU_OUTLET_FAN                  10
> +#define DRIVE_COOLING_FAN               11
> +#define GPU_COOLING_FAN                 12
> +#define AUX_COOLING_FAN                 13
> +#define IOH_COOLING_FAN                 14
> +
> +#define LAST_FAN                        14
> +
> +//
> +// Fan Type Definitions
> +//
> +#define FAN_TYPE_UNKNOWN                0
> +#define FAN_3WIRE_PULSE                 1
> +#define FAN_3WIRE_VOLTAGE               2
> +#define FAN_4WIRE                       3
> +
> +#pragma pack(1)
> +
> +//
> +// TEMP_SENSOR_INFO - Structure providing info for a temperature sensor.
> +//
> +typedef struct _TEMP_SENSOR_INFO
> +{
> +    UINT8                               byDevice;       // Device index
> +    UINT8                               byIndex;        // Physical sensor index
> +    UINT8                               byUsage;        // Usage indicator
> +    UINT8                               bRelative;      // Relative vs. Absolute readings
> +
> +} TEMP_SENSOR_INFO, *P_TEMP_SENSOR_INFO;
> +
> +//
> +// TYPEDEF_TEMP_SENSOR_SECTION - Macro that can be used to typedef
> the
> +// TEMP_SENSOR_SECTION structure, which provides information about all
> +// temperature sensors.
> +//
> +#define TYPEDEF_TEMP_SENSOR_SECTION(count)                              \
> +typedef struct _TEMP_SENSOR_SECTION                                     \
> +{                                                                       \
> +    UINT8                               byCount;                        \
> +    TEMP_SENSOR_INFO                    stSensor[count];                \
> +                                                                        \
> +} TEMP_SENSOR_SECTION, *P_TEMP_SENSOR_SECTION
> +
> +//
> +// VOLT_SENSOR_INFO - Structure providing info for a voltage sensor.
> +//
> +typedef struct _VOLT_SENSOR_INFO
> +{
> +    UINT8                               byDevice;       // Device index
> +    UINT8                               byIndex;        // Physical sensor index
> +    UINT8                               byUsage;        // Usage indicator
> +
> +} VOLT_SENSOR_INFO, *P_VOLT_SENSOR_INFO;
> +
> +//
> +// TYPEDEF_VOLT_SENSOR_SECTION - Macro that can be used to typedef
> the
> +// VOLT_SENSOR_SECTION structure, which provides information about all
> +// voltage sensors.
> +//
> +#define TYPEDEF_VOLT_SENSOR_SECTION(count)                              \
> +typedef struct _VOLT_SENSOR_SECTION                                     \
> +{                                                                       \
> +    UINT8                               byCount;                        \
> +    VOLT_SENSOR_INFO                    stSensor[count];                \
> +                                                                        \
> +} VOLT_SENSOR_SECTION, *P_VOLT_SENSOR_SECTION
> +
> +//
> +// FAN_SENSOR_INFO - Structure providing info for a fan speed sensor.
> +//
> +typedef struct _FAN_SENSOR_INFO
> +{
> +    UINT8                               byDevice;       // Device index
> +    UINT8                               byIndex;        // Physical sensor index
> +    UINT8                               byUsage;        // Usage indicator
> +    UINT8                               byType;         // Fan type
> +    UINT8                               byController;   // Associated Fan Controller
> +
> +} FAN_SENSOR_INFO, *P_FAN_SENSOR_INFO;
> +
> +//
> +// TYPEDEF_FAN_SENSOR_SECTION - Macro that can be used to typedef
> the
> +// FAN_SENSOR_SECTION structure, which provides information about all
> fan
> +// speed sensors.
> +//
> +#define TYPEDEF_FAN_SENSOR_SECTION(count)                               \
> +typedef struct _FAN_SENSOR_SECTION                                      \
> +{                                                                       \
> +    UINT8                               byCount;                        \
> +    FAN_SENSOR_INFO                     stSensor[count];                \
> +                                                                        \
> +} FAN_SENSOR_SECTION, *P_FAN_SENSOR_SECTION
> +
> +//
> +// FAN_CONTROLLER_INFO - Structure providing info for a fan speed
> controller.
> +//
> +#define MAX_ASSOC_FANS                  4
> +#define ASSOC_UNUSED                    0xFF
> +
> +typedef struct _FAN_CONTROLLER_INFO
> +{
> +    UINT8                               byDevice;       // Device index
> +    UINT8                               byIndex;        // Physical Controller Index
> +    UINT8                               byUsage;        // Usage Indicator
> +    UINT8                               byFan[MAX_ASSOC_FANS]; // Associated Fan
> Sensors
> +
> +} FAN_CONTROLLER_INFO, *P_FAN_CONTROLLER_INFO;
> +
> +//
> +// TYPEDEF_FAN_CONTROLLER_SECTION - Macro that can be used to
> typedef the
> +// FAN_CONTROLLER_SECTION structure, which provides information about
> all
> +// fan speed controllers.
> +//
> +#define TYPEDEF_FAN_CONTROLLER_SECTION(count)                           \
> +typedef struct _FAN_CONTROLLER_SECTION                                  \
> +{                                                                       \
> +    UINT8                               byCount;                        \
> +    FAN_CONTROLLER_INFO                 stController[count];            \
> +                                                                        \
> +} FAN_CONTROLLER_SECTION, *P_FAN_CONTROLLER_SECTION
> +
> +//
> +// TYPEDEF_SENSOR_INFO_VAR - Macro that can be used to typedef the
> +// SENSOR_INFO_VAR structure, which provides information about all
> sensors
> +// and fan speed controllers. The other TYPEDEF macros must be invoked
> +// before using this one...
> +//
> +#define TYPEDEF_SENSOR_INFO_VAR                                         \
> +typedef struct _SENSOR_INFO_VAR                                         \
> +{                                                                       \
> +    TEMP_SENSOR_SECTION                 stTemps;                        \
> +    VOLT_SENSOR_SECTION                 stVolts;                        \
> +    FAN_SENSOR_SECTION                  stFans;                         \
> +    FAN_CONTROLLER_SECTION              stCtrls;                        \
> +                                                                        \
> +} SENSOR_INFO_VAR, *P_SENSOR_INFO_VAR
> +
> +#pragma pack()
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SetupVariable.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SetupVariable.h
> new file mode 100644
> index 0000000000..32f121892b
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SetupVariable.h
> @@ -0,0 +1,1344 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2018, Intel Corporation. All rights reserved.<BR>
> +
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +
> +Module Name:
> +
> +    SetupVariable.h
> +
> +Abstract:
> +
> +    Driver configuration include file
> +
> +
> +**/
> +
> +#ifndef _SETUP_VARIABLE_H
> +#define _SETUP_VARIABLE_H
> +
> +//
> +// ---------------------------------------------------------------------------
> +//
> +// Driver Configuration
> +//
> +// ---------------------------------------------------------------------------
> +//
> +
> +//
> +// {EC87D643-EBA4-4bb5-A1E5-3F3E36B20DA9}
> +//
> +#define SYSTEM_CONFIGURATION_GUID\
> +  { \
> +    0xec87d643, 0xeba4, 0x4bb5, 0xa1, 0xe5, 0x3f, 0x3e, 0x36, 0xb2, 0xd, 0xa9
> \
> +  }
> +
> +#define ROOT_SECURITY_GUID\
> +  { \
> +    0xd387d688, 0xeba4, 0x45b5, 0xa1, 0xe5, 0x3f, 0x3e, 0x36, 0xb2, 0xd, 0x37
> \
> +  }
> +
> +//
> +// {6936B3BD-4350-46d9-8940-1FA20961AEB1}
> +//
> +#define SYSTEM_ROOT_MAIN_GUID\
> +  { \
> +     0x6936b3bd, 0x4350, 0x46d9, 0x89, 0x40, 0x1f, 0xa2, 0x9, 0x61, 0xae, 0xb1
> \
> +  }
> +
> +//
> +// {21FEE8DB-0D29-477e-B5A9-96EB343BA99C}
> +//
> +#define ADDITIONAL_SYSTEM_INFO_GUID\
> +  { \
> +     0x21fee8db, 0xd29, 0x477e, 0xb5, 0xa9, 0x96, 0xeb, 0x34, 0x3b, 0xa9,
> 0x9c \
> +  }
> +
> +#define SETUP_GUID { 0xEC87D643, 0xEBA4, 0x4BB5, 0xA1, 0xE5, 0x3F, 0x3E,
> 0x36, 0xB2, 0x0D, 0xA9 }
> +
> +// {1B838190-4625-4ead-ABC9-CD5E6AF18FE0}
> +#define EFI_HII_EXPORT_DATABASE_GUID { 0x1b838190, 0x4625, 0x4ead,
> 0xab, 0xc9, 0xcd, 0x5e, 0x6a, 0xf1, 0x8f, 0xe0 }
> +
> +#define PASSWORD_MAX_SIZE               20
> +
> +#define MAX_CUSTOM_VID_TABLE_STATES 6
> +//
> +// Overclocking Source Defines
> +//
> +#define OVERCLOCK_SOURCE_BIOS       0
> +#define OVERCLOCK_SOURCE_OS         1
> +
> +#define PCH_PCIE_MAX_ROOT_PORTS     4
> +
> +#pragma pack(1)
> +
> +// NOTE: When you add anything to this structure,
> +//   you MUST add it to the very bottom!!!!
> +//   You must make sure the structure size is able to divide by 32!
> +typedef struct {
> +
> +  //
> +  // Floppy
> +  //
> +  UINT8         Floppy;
> +  UINT8         FloppyLockHide;
> +
> +  UINT8         FloppyWriteProtect;
> +  UINT8         FloppyWriteProtectLockHide;
> +
> +  //
> +  // System ports
> +  //
> +  UINT8         Serial;
> +  UINT8         SerialLockHide;
> +
> +  UINT8         Serial2;
> +  UINT8         Serial2LockHide;
> +
> +  UINT8         Parallel;
> +  UINT8         ParallelLockHide;
> +
> +  UINT8         ParallelMode;
> +  UINT8         ParallelModeLockHide;
> +
> +  UINT8         AllUsb;
> +  UINT8         UsbPortsLockHide;
> +
> +  UINT8         Usb2;
> +  UINT8         Usb2LockHide;
> +
> +  UINT8         UsbLegacy;
> +  UINT8         UsbLegacyLockHide;
> +
> +  UINT8         Audio;
> +  UINT8         AudioLockHide;
> +
> +  UINT8         Lan;
> +  UINT8         LanLockHide;
> +
> +  //
> +  // Keyboard
> +  //
> +  UINT8         Numlock;
> +  UINT8         NumlockLockHide;
> +
> +  //
> +  // ECIR
> +  //
> +  UINT8         ECIR;
> +  UINT8         ECIRLockHide;
> +
> +  //
> +  // Power State
> +  //
> +  UINT8         PowerState;
> +  UINT8         PowerStateLockHide;
> +
> +  //
> +  // Wake on RTC variables
> +  //
> +  UINT8         WakeOnRtcS5;
> +  UINT8         WakeOnRtcS5LockHide;
> +  UINT8         RTCWakeupDate;
> +  UINT8         RTCWakeupDateLockHide;
> +  UINT8         RTCWakeupTimeHour;
> +  UINT8         RTCWakeupHourLockHide;
> +  UINT8         RTCWakeupTimeMinute;
> +  UINT8         RTCWakeupMinuteLockHide;
> +  UINT8         RTCWakeupTimeSecond;
> +  UINT8         RTCWakeupSecondLockHide;
> +
> +  //
> +  // Wake On Lan
> +  //
> +  UINT8         WakeOnLanS5;
> +  UINT8         WakeOnLanS5LockHide;
> +
> +  //Spread spectrum
> +  UINT8         SpreadSpectrum;
> +
> +  //
> +  // Boot Order
> +  //
> +  UINT8         BootOrder[8];
> +  UINT8         BootOrderLockHide;
> +
> +  //
> +  // Hard Drive Boot Order
> +  //
> +  UINT8         HardDriveBootOrder[8];
> +  UINT8         HardDriveBootOrderLockHide;
> +
> +  //
> +  // CD Drive Boot Order
> +  //
> +  UINT8         CdDriveBootOrder[4];
> +  UINT8         CdDriveBootOrderLockHide;
> +
> +  //
> +  // FDD Drive Boot Order
> +  //
> +  UINT8         FddDriveBootOrder[4];
> +  UINT8         FddDriveBootOrderLockHide;
> +
> +  //
> +  // Drive Boot Order
> +  //
> +  UINT8         DriveBootOrder[16];
> +  UINT8         DriveBootOrderLockHide;
> +
> +  //
> +  // Boot Menu Type
> +  //
> +  UINT8         BootMenuType;
> +  UINT8         BootMenuTypeLockHide;
> +
> +  //
> +  // Boot from Removable Devices
> +  //
> +  UINT8         BootFloppy;
> +  UINT8         BootFloppyLockHide;
> +
> +  //
> +  // Boot from Optical Devices
> +  //
> +  UINT8         BootCd;
> +  UINT8         BootCdLockHide;
> +
> +  //
> +  // Boot from Network
> +  //
> +  UINT8         BootNetwork;
> +  UINT8         BootNetworkLockHide;
> +
> +  //
> +  // Boot USB
> +  //
> +  UINT8         BootUsb;
> +  UINT8         BootUsbLockHide;
> +
> +  //
> +  // USB Zip Emulation Type
> +  //
> +  UINT8         UsbZipEmulation;
> +  UINT8         UsbZipEmulationLockHide;
> +
> +  //
> +  // USB Devices Boot First in Boot Order
> +  //
> +  UINT8         UsbDevicesBootFirst;
> +  UINT8         UsbDevicesBootFirstLockHide;
> +
> +  //
> +  // USB Boot Device SETUP Emulation
> +  //
> +  UINT8         UsbSetupDeviceEmulation;
> +  UINT8         UsbSetupDeviceEmulationLockHide;
> +
> +  //
> +  // BIOS INT13 Emulation for USB Mass Devices
> +  //
> +  UINT8         UsbBIOSINT13DeviceEmulation;
> +  UINT8         UsbBIOSINT13DeviceEmulationLockHide;
> +
> +  //
> +  // BIOS INT13 Emulation Size for USB Mass Devices
> +  //
> +  UINT16        UsbBIOSINT13DeviceEmulationSize;
> +  UINT8         UsbBIOSINT13DeviceEmulationSizeLockHide;
> +
> +  //
> +  // Dummy place holder to prevent VFR compiler problem.
> +  //
> +  UINT16        DummyDataForVfrBug;  // Don't change or use.
> +
> +  //
> +  // Language Select
> +  //
> +  UINT8         LanguageSelect;
> +
> +  //
> +  // SATA Type (Ide, Ahci, Raid)
> +  //
> +  UINT8         SataType;
> +  UINT8         SataTypeLockHide;
> +  UINT8         SataTestMode;
> +
> +  //
> +  // Fixed Disk Boot Sector (Fdbs)
> +  //
> +  UINT8         Fdbs;
> +  UINT8         FdbsLockHide;
> +
> +  //
> +  // DisplaySetupPrompt
> +  //
> +  UINT8         DisplaySetupPrompt;
> +  UINT8         DisplaySetupPromptLockHide;
> +
> +  //
> +  // ASF
> +  //
> +  UINT8         Asf;
> +  UINT8         AsfLockHide;
> +
> +  //
> +  // Event Logging
> +  //
> +  UINT8         EventLogging;
> +  UINT8         EventLoggingLockHide;
> +
> +  //
> +  // Clear Event Log
> +  //
> +  UINT8         ClearEvents;
> +  UINT8         ClearEventsLockHide;
> +
> +  //
> +  // Expansion Card Text
> +  //
> +  UINT8         ExpansionCardText;
> +  UINT8         ExpansionCardTextLockHide;
> +
> +  //
> +  // Video Adaptor
> +  //
> +  UINT8         PrimaryVideoAdaptor;
> +  UINT8         PrimaryVideoAdaptorLockHide;
> +
> +  //
> +  // Chassis intrusion
> +  //
> +  UINT8         IntruderDetection;
> +  UINT8         IntruderDetectionLockHide;
> +
> +  //
> +  // User Access Level
> +  //
> +  UINT8         UserPasswordLevel;
> +  UINT8         UserPasswordLevelLockHide;
> +
> +  //
> +  // Maximum FSB Automatic/Disable
> +  //
> +  UINT8         MaxFsb;
> +  UINT8         MaxFsbLockHide;
> +
> +  //
> +  // Hard Disk Pre-delay
> +  //
> +  UINT8         HddPredelay;
> +  UINT8         HddPredelayLockHide;
> +
> +  //
> +  // S.M.A.R.T. Mode
> +  //
> +  UINT8         SmartMode;
> +  UINT8         SmartModeLockHide;
> +
> +  //
> +  // ACPI Suspend State
> +  //
> +  UINT8         AcpiSuspendState;
> +  UINT8         AcpiSuspendStateLockHide;
> +
> +  //
> +  // PCI Latency Timer
> +  //
> +  UINT8         PciLatency;
> +  UINT8         PciLatencyLockHide;
> +
> +  //
> +  // Fan Control
> +  //
> +  UINT8         FanControl;
> +  UINT8         FanControlLockHide;
> +
> +  //
> +  // CPU Fan Control
> +  //
> +  UINT8         CpuFanControl;
> +  UINT8         CpuFanControlLockHide;
> +
> +  //
> +  // Lowest Fan Speed
> +  //
> +  UINT8         LowestFanSpeed;
> +  UINT8         LowestFanSpeedLockHide;
> +
> +  //
> +  // Processor (CPU)
> +  //
> +  UINT8         CpuFlavor;
> +
> +  UINT8         CpuidMaxValue;
> +  UINT8         CpuidMaxValueLockHide;
> +
> +  UINT8         ExecuteDisableBit;
> +  UINT8         ExecuteDisableBitLockHide;
> +
> +  //
> +  // EIST or GV3 setup option
> +  //
> +  UINT8         ProcessorEistEnable;
> +  UINT8         ProcessorEistEnableLockHide;
> +
> +  //
> +  // C1E Enable
> +  //
> +  UINT8         ProcessorC1eEnable;
> +  UINT8         ProcessorC1eEnableLockHide;
> +
> +  //
> +  // Enabling CPU C-States of processor
> +  //
> +  UINT8         ProcessorCcxEnable;
> +  UINT8         ProcessorCcxEnableLockHide;
> +
> +  //
> +  // Package C-State Limit
> +  //
> +  UINT8         PackageCState;
> +  UINT8         PackageCStateLockHide;
> +
> +  //
> +  // Enable/Disable NHM C3(ACPI C2) report to OS
> +  //
> +  UINT8         OSC2Report;
> +  UINT8         OSC2ReportLockHide;
> +
> +  //
> +  // Enable/Disable NHM C6(ACPI C3) report to OS
> +  //
> +  UINT8         C6Enable;
> +  UINT8         C6EnableLockHide;
> +
> +  //
> +  // Enable/Disable NHM C7(ACPI C3) report to OS
> +  //
> +  UINT8         C7Enable;
> +  UINT8         C7EnableLockHide;
> +
> +  //
> +  // EIST/PSD Function select option
> +  //
> +  UINT8         ProcessorEistPsdFunc;
> +  UINT8         ProcessorEistPsdFuncLockHide;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU00;
> +  UINT8         CPU01;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU02;
> +  UINT8         CPU03;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU04;
> +  UINT8         CPU05;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU06;
> +  UINT8         CPU07;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU08;
> +  UINT8         CPU09;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU10;
> +  UINT8         CPU11;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU12;
> +  UINT8         CPU13;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU14;
> +  UINT8         CPU15;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU16;
> +  UINT8         CPU17;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU18;
> +  UINT8         CPU19;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU20;
> +  UINT8         CPU21;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU22;
> +  UINT8         CPU23;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU24;
> +  UINT8         CPU25;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU26;
> +  UINT8         CPU27;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU28;
> +  UINT8         CPU29;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU30;
> +  UINT8         CPU31;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU32;
> +  UINT8         CPU33;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU34;
> +  UINT8         CPU35;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU36;
> +  UINT8         CPU37;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU38;
> +  UINT8         CPU39;
> +
> +  //
> +  //
> +  //
> +  UINT16        CPU40;
> +  UINT8         CPU41;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU42;
> +  UINT8         CPU43;
> +
> +  //
> +  //
> +  //
> +  UINT16        CPU44;
> +  UINT8         CPU45;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU46;
> +  UINT8         CPU47;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU48;
> +  UINT8         CPU49;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU50;
> +  UINT8         CPU51;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU52;
> +  UINT8         CPU53;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU54;
> +  UINT8         CPU55;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU56;
> +  UINT8         CPU57;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU58;
> +  UINT8         CPU59;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU60;
> +  UINT8         CPU61;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU62;
> +  UINT8         CPU63;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU64;
> +  UINT8         CPU65;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU66;
> +  UINT8         CPU67;
> +
> +  //
> +  //
> +  //
> +  UINT16        CPU68;
> +  UINT8         CPU69;
> +
> +  //
> +  //
> +  //
> +  UINT16        CPU70;
> +
> +  //
> +  //
> +  //
> +  UINT8         CPU71;
> +
> +  //
> +  //
> +  //
> +  UINT8         MEM00;
> +  UINT8         MEM01;
> +
> +  //
> +  //
> +  //
> +  UINT8         MEM02;
> +  UINT8         MEM03;
> +
> +  UINT16        MEM04;
> +  UINT8         MEM05;
> +
> +  UINT8         MEM06;
> +  UINT8         MEM07;
> +
> +  UINT8         MEM08;
> +  UINT8         MEM09;
> +
> +  UINT8         MEM10;
> +  UINT8         MEM11;
> +
> +  UINT8         MEM12;
> +  UINT8         MEM13;
> +
> +  UINT8         MEM14;
> +  UINT8         MEM15;
> +
> +  UINT8         MEM16;
> +  UINT8         MEM17;
> +
> +  UINT16        MEM18;
> +  UINT8         MEM19;
> +
> +  UINT8         MEM20;
> +  UINT8         MEM21;
> +
> +  UINT8         MEM22;
> +  UINT8         MEM23;
> +
> +  UINT8         MEM24;
> +  UINT8         MEM25;
> +
> +  UINT8         MEM26;
> +  UINT8         MEM27;
> +
> +  UINT8         MEM28;
> +  UINT8         MEM29;
> +
> +  UINT8         MEM30;
> +  UINT8         MEM31;
> +
> +  UINT8         MEM32;
> +  UINT8         MEM33;
> +
> +  UINT8         MEM34;
> +  UINT8         MEM35;
> +
> +  //
> +  //
> +  //
> +  UINT8         MEM36;
> +  UINT8         MEM37;
> +  UINT8         MEM38;
> +  UINT8         MEM39;
> +
> +  //
> +  //
> +  //
> +  UINT8         MEM40;
> +  UINT8         MEM41;
> +  UINT8         MEM42;
> +  UINT8         MEM43;
> +  UINT8         MEM44;
> +  UINT8         MEM45;
> +  UINT8         MEM46;
> +  UINT8         MEM47;
> +
> +
> +  //
> +  // Port 80 decode 0/1 - PCI/LPC
> +  UINT8         Port80Route;
> +  UINT8         Port80RouteLockHide;
> +
> +  //
> +  // ECC Event Logging
> +  //
> +  UINT8         EccEventLogging;
> +  UINT8         EccEventLoggingLockHide;
> +
> +  //
> +  // TPM Enable/Disable
> +  //
> +  UINT8         ETpm;
> +
> +  //
> +  // TPM question  0 = Disabled, 1 = Enabled
> +  //
> +  UINT8         ETpmClear;
> +
> +  //
> +  // Secondary SATA Controller question  0 = Disabled, 1 = Enabled
> +  //
> +  UINT8         ExtSata;
> +  UINT8         ExtSataLockHide;
> +
> +  //
> +  // Mode selection for Secondary SATA Controller (0=IDE, 1=RAID)
> +  //
> +  UINT8         ExtSataMode;
> +  UINT8         ExtSataModeLockHide;
> +
> +  //
> +  // LT Technology 0/1 -> Disable/Enable
> +  //
> +  UINT8         LtTechnology;
> +  UINT8         LtTechnologyLockHide;
> +
> +  //
> +  // HPET Support 0/1 -> Disable/Enable
> +  //
> +  UINT8         Hpet;
> +  UINT8         HpetLockHide;
> +
> +  //
> +  // ICH Function Level Reset enable/disable
> +  //
> +  UINT8         FlrCapability;
> +  UINT8         FlrCapabilityLockHide;
> +
> +  // VT-d Option
> +  UINT8         VTdSupport;
> +  UINT8         VTdSupportLockHide;
> +
> +  UINT8         InterruptRemap;
> +  UINT8         InterruptRemapLockHide;
> +
> +  UINT8         Isoc;
> +  UINT8         IsocLockHide;
> +
> +  UINT8         CoherencySupport;
> +  UINT8         CoherencySupportLockHide;
> +
> +  UINT8         ATS;
> +  UINT8         ATSLockHide;
> +
> +  UINT8         PassThroughDma;
> +  UINT8         PassThroughDmaLockHide;
> +
> +  //
> +  // IGD option
> +  //
> +  UINT8         GraphicsDriverMemorySize;
> +  UINT8         GraphicsDriverMemorySizeLockHide;
> +
> +
> +  //
> +  // Discrete SATA Type (Ide, Raid, Ahci)
> +  //
> +  UINT8         ExtSataMode2;
> +  UINT8         ExtSataMode2LockHide;
> +
> +  UINT8         ProcessorReserve00;
> +  UINT8         ProcessorReserve01;
> +
> +  //
> +  // IGD Aperture Size question
> +  //
> +  UINT8         IgdApertureSize;
> +  UINT8         IgdApertureSizeLockHide;
> +
> +  //
> +  // Boot Display Device
> +  //
> +  UINT8         BootDisplayDevice;
> +  UINT8         BootDisplayDeviceLockHide;
> +
> +
> +  //
> +  // System fan speed duty cycle
> +  //
> +  UINT8         SystemFanDuty;
> +  UINT8         SystemFanDutyLockHide;
> +
> +
> +  //
> +  // S3 state LED indicator
> +  //
> +  UINT8         S3StateIndicator;
> +  UINT8         S3StateIndicatorLockHide;
> +
> +  //
> +  // S1 state LED indicator
> +  //
> +  UINT8         S1StateIndicator;
> +  UINT8         S1StateIndicatorLockHide;
> +
> +  //
> +  // PS/2 Wake from S5
> +  //
> +  UINT8         WakeOnS5Keyboard;
> +  UINT8         WakeOnS5KeyboardLockHide;
> +
> +
> +  //
> +  // SATA Controller question  0 = Disabled, 1 = Enabled
> +  //
> +  UINT8         Sata;
> +  UINT8         SataLockHide;
> +
> +  //
> +  // PS2 port
> +  //
> +  UINT8         PS2;
> +
> +  //
> +  // No VideoBeep
> +  //
> +  UINT8         NoVideoBeepEnable;
> +
> +  //
> +  // Integrated Graphics Device
> +  //
> +  UINT8         Igd;
> +
> +  //
> +  // Video Device select order
> +  //
> +  UINT8         VideoSelectOrder[8];
> +
> +  // Flash update sleep delay
> +  UINT8         FlashSleepDelay;
> +  UINT8         FlashSleepDelayLockHide;
> +
> +  //
> +  // Boot Display Device2
> +  //
> +  UINT8         BootDisplayDevice2;
> +  UINT8         BootDisplayDevice2LockHide;
> +
> +  //
> +  // Flat Panel
> +  //
> +  UINT8         EdpInterfaceType;
> +  UINT8         EdpInterfaceTypeLockHide;
> +
> +  UINT8         LvdsInterfaceType;
> +  UINT8         LvdsInterfaceTypeLockHide;
> +
> +  UINT8         ColorDepth;
> +  UINT8         ColorDepthLockHide;
> +
> +  UINT8         EdidConfiguration;
> +  UINT8         EdidConfigurationLockHide;
> +
> +  UINT8         PwmReserved;
> +  UINT8         MaxInverterPWMLockHide;
> +
> +  UINT8         PreDefinedEdidConfiguration;
> +  UINT8         PreDefinedEdidConfigurationLockHide;
> +
> +  UINT16        ScreenBrightnessResponseTime;
> +  UINT8         ScreenBrightnessResponseTimeLockHide;
> +
> +  UINT8         Serial3;
> +  UINT8         Serial3LockHide;
> +
> +  UINT8         Serial4;
> +  UINT8         Serial4LockHide;
> +
> +  UINT8         CurrentSetupProfile;
> +  UINT8         CurrentSetupProfileLockHide;
> +
> +  //
> +  // FSC system Variable
> +  //
> +  UINT8         CPUFanUsage;
> +  UINT8         CPUFanUsageLockHide;
> +  UINT16        CPUUnderSpeedthreshold;
> +  UINT8         CPUUnderSpeedthresholdLockHide;
> +  UINT8         CPUFanControlMode;
> +  UINT8         CPUFanControlModeLockHide;
> +  UINT16        Voltage12UnderVolts;
> +  UINT8         Voltage12UnderVoltsLockHide;
> +  UINT16        Voltage12OverVolts;
> +  UINT8         Voltage12OverVoltsLockHide;
> +  UINT16        Voltage5UnderVolts;
> +  UINT8         Voltage5UnderVoltsLockHide;
> +  UINT16        Voltage5OverVolts;
> +  UINT8         Voltage5OverVoltsLockHide;
> +  UINT16        Voltage3p3UnderVolts;
> +  UINT8         Voltage3p3UnderVoltsLockHide;
> +  UINT16        Voltage3p3OverVolts;
> +  UINT8         Voltage3p3OverVoltsLockHide;
> +  UINT16        Voltage2p5UnderVolts;
> +  UINT8         Voltage2p5UnderVoltsLockHide;
> +  UINT16        Voltage2p5OverVolts;
> +  UINT8         Voltage2p5OverVoltsLockHide;
> +  UINT16        VoltageVccpUnderVolts;
> +  UINT8         VoltageVccpUnderVoltsLockHide;
> +  UINT16        VoltageVccpOverVolts;
> +  UINT8         VoltageVccpOverVoltsLockHide;
> +  UINT16        Voltage5BackupUnderVolts;
> +  UINT8         Voltage5BackupUnderVoltsLockHide;
> +  UINT16        Voltage5BackupOverVolts;
> +  UINT8         Voltage5BackupOverVoltsLockHide;
> +  UINT16        VS3p3StbyUnderVolt;
> +  UINT8         VS3p3StbyUnderVoltLockHide;
> +  UINT16        VS3p3StbyOverVolt;
> +  UINT8         VS3p3StbyOverVoltLockHide;
> +  UINT8         CPUFanMinDutyCycle;
> +  UINT8         CPUFanMinDutyCycleLockHide;
> +  UINT8         CPUFanMaxDutyCycle;
> +  UINT8         CPUFanMaxDutyCycleLockHide;
> +  UINT8         CPUFanOnDutyCycle;
> +  UINT8         CPUFanOnDutyCycleLockHide;
> +  UINT16        CpuOverTemp;
> +  UINT8         CpuOverTempLockHide;
> +  UINT16        CpuControlTemp;
> +  UINT8         CpuControlTempLockHide;
> +  UINT16        CpuAllOnTemp;
> +  UINT8         CpuAllOnTempLockHide;
> +  UINT8         CpuResponsiveness;
> +  UINT8         CpuResponsivenessLockHide;
> +  UINT8         CpuDamping;
> +  UINT8         CpuDampingLockHide;
> +  UINT16        PchOverTemp;
> +  UINT8         PchOverTempLockHide;
> +  UINT16        PchControlTemp;
> +  UINT8         PchControlTempLockHide;
> +  UINT16        PchAllOnTemp;
> +  UINT8         PchAllOnTempLockHide;
> +  UINT8         PchResponsiveness;
> +  UINT8         PchResponsivenessLockHide;
> +  UINT8         PchDamping;
> +  UINT8         PchDampingLockHide;
> +  UINT16        MemoryOverTemp;
> +  UINT8         MemoryOverTempLockHide;
> +  UINT16        MemoryControlTemp;
> +  UINT8         MemoryControlTempLockHide;
> +  UINT16        MemoryAllOnTemp;
> +  UINT8         MemoryAllOnTempLockHide;
> +  UINT8         MemoryResponsiveness;
> +  UINT8         MemoryResponsivenessLockHide;
> +  UINT8         MemoryDamping;
> +  UINT8         MemoryDampingLockHide;
> +  UINT16        VROverTemp;
> +  UINT8         VROverTempLockHide;
> +  UINT16        VRControlTemp;
> +  UINT8         VRControlTempLockHide;
> +  UINT16        VRAllOnTemp;
> +  UINT8         VRAllOnTempLockHide;
> +  UINT8         VRResponsiveness;
> +  UINT8         VRResponsivenessLockHide;
> +  UINT8         VRDamping;
> +  UINT8         VRDampingLockHide;
> +
> +  UINT8         LvdsBrightnessSteps;
> +  UINT8         LvdsBrightnessStepsLockHide;
> +  UINT8         EdpDataRate;
> +  UINT8         EdpDataRateLockHide;
> +  UINT16        LvdsPowerOnToBacklightEnableDelayTime;
> +  UINT8         LvdsPowerOnToBacklightEnableDelayTimeLockHide;
> +  UINT16        LvdsPowerOnDelayTime;
> +  UINT8         LvdsPowerOnDelayTimeLockHide;
> +  UINT16        LvdsBacklightOffToPowerDownDelayTime;
> +  UINT8         LvdsBacklightOffToPowerDownDelayTimeLockHide;
> +  UINT16        LvdsPowerDownDelayTime;
> +  UINT8         LvdsPowerDownDelayTimeLockHide;
> +  UINT16        LvdsPowerCycleDelayTime;
> +  UINT8         LvdsPowerCycleDelayTimeLockHide;
> +
> +  UINT8         IgdFlatPanel;
> +  UINT8         IgdFlatPanelLockHide;
> +  UINT8         Lan2;
> +  UINT8         Lan2LockHide;
> +
> +  UINT8         SwapMode;
> +  UINT8         SwapModeLockHide;
> +
> +  UINT8         Sata0HotPlugCap;
> +  UINT8         Sata0HotPlugCapLockHide;
> +  UINT8         Sata1HotPlugCap;
> +  UINT8         Sata1HotPlugCapLockHide;
> +
> +  UINT8         UsbCharging;
> +  UINT8         UsbChargingLockHide;
> +
> +  UINT8         Cstates;
> +  UINT8         EnableC4;
> +  UINT8         EnableC6;
> +
> +  UINT8          FastBoot;
> +  UINT8          EfiNetworkSupport;
> +  UINT8          PxeRom;
> +
> +  //Add for PpmPlatformPlicy
> +  UINT8          PPM00;
> +  UINT8          PPM01;
> +  UINT8          PPM02;
> +  UINT8          PPM03;
> +  UINT8          PPM04;
> +  UINT8          PPM05;
> +  UINT8          PPM06;
> +  UINT8          PPM07;
> +  UINT8          PPM08;
> +  UINT8          PPM09;
> +  UINT8          PPM10;
> +  UINT8          QuietBoot;
> +  UINT8          LegacyUSBBooting;
> +
> +  UINT8          PwmReserved02;
> +  //
> +  // Thermal Policy Values
> +  //
> +  UINT8           EnableDigitalThermalSensor;
> +  UINT8           PassiveThermalTripPoint;
> +  UINT8           PassiveTc1Value;
> +  UINT8           PassiveTc2Value;
> +  UINT8           PassiveTspValue;
> +  UINT8           DisableActiveTripPoints;
> +  UINT8           CriticalThermalTripPoint;
> +  UINT8           IchPciExp[4];
> +  UINT8           DeepStandby;
> +  UINT8           AlsEnable;
> +  UINT8           IgdLcdIBia;
> +  UINT8           LogBootTime;
> +
> +
> +  UINT8           PcieRootPortIOApic[4];
> +  UINT8           IffsEnable;
> +  UINT8           IffsOnS3RtcWake;
> +  UINT8           IffsS3WakeTimerMin;
> +  UINT8           IffsOnS3CritBattWake;
> +  UINT8           IffsCritBattWakeThreshold;
> +  UINT8           ScramblerSupport;
> +  UINT8           SecureBoot;
> +  UINT8           SecureBootCustomMode;
> +  UINT8           SecureBootUserPhysicalPresent;
> +  UINT8           CoreFreMultipSelect;
> +  UINT8           MaxCState;
> +  UINT8           PanelScaling;
> +  UINT8           IgdLcdIGmchBlc;
> +  UINT8           GfxBoost;
> +  UINT8           IgdThermal;
> +  UINT8           SEC00;
> +  UINT8           fTPM;
> +  UINT8           SEC02;
> +  UINT8           SEC03;
> +  UINT8           MeasuredBootEnable;
> +  UINT8           UseProductKey;
> +  //Image Signal Processor PCI Device Configuration
> +  //
> +  UINT8         ISPDevSel;
> +  UINT8         ISPEn;
> +  // Passwords
> +  UINT16          UserPassword[PASSWORD_MAX_SIZE];
> +  UINT16          AdminPassword[PASSWORD_MAX_SIZE];
> +  UINT8           Tdt;
> +  UINT8           Recovery;
> +  UINT8           Suspend;
> +  UINT8           TdtState;
> +  UINT8           TdtEnrolled;
> +  UINT8           PBAEnable;
> +
> +  UINT8           HpetBootTime;
> +  UINT8           UsbDebug;
> +  UINT8           Lpe;
> +  //
> +  // LPSS Configuration
> +  //
> +  UINT8           LpssPciModeEnabled;
> +  //Scc
> +  UINT8           LpsseMMCEnabled;
> +  UINT8           LpssSdioEnabled;
> +  UINT8           LpssSdcardEnabled;
> +  UINT8           LpssSdCardSDR25Enabled;
> +  UINT8           LpssSdCardDDR50Enabled;
> +  UINT8           LpssMipiHsi;
> +  UINT8           LpsseMMC45Enabled;
> +  UINT8           LpsseMMC45DDR50Enabled;
> +  UINT8           LpsseMMC45HS200Enabled;
> +  UINT8           LpsseMMC45RetuneTimerValue;
> +  UINT8           eMMCBootMode;
> +
> +  //LPSS2
> +  UINT8           LpssDma1Enabled;
> +  UINT8           LpssI2C0Enabled;
> +  UINT8           LpssI2C1Enabled;
> +  UINT8           LpssI2C2Enabled;
> +  UINT8           LpssI2C3Enabled;
> +  UINT8           LpssI2C4Enabled;
> +  UINT8           LpssI2C5Enabled;
> +  UINT8           LpssI2C6Enabled;
> +  //LPSS1
> +  UINT8           LpssDma0Enabled;
> +  UINT8           LpssPwm0Enabled;
> +  UINT8           LpssPwm1Enabled;
> +  UINT8           LpssHsuart0Enabled;
> +  UINT8           LpssHsuart1Enabled;
> +  UINT8           LpssSpiEnabled;
> +  UINT8           I2CTouchAd;
> +
> +  UINT8   GTTSize;
> +  //
> +  // DVMT5.0 Graphic memory setting
> +  //
> +  UINT8   IgdDvmt50PreAlloc;
> +  UINT8   IgdDvmt50TotalAlloc;
> +  UINT8   IgdTurboEnabled;
> +
> +  //
> +  // Usb Config
> +  //
> +  UINT8   UsbAutoMode;       // PCH controller Auto mode
> +  UINT8   UsbXhciSupport;
> +  UINT8   Hsic0;
> +  UINT8   PchUsb30Mode;
> +  UINT8   PchUsb30Streams;
> +  UINT8   PchUsb20;
> +  UINT8   PchUsbPerPortCtl;
> +  UINT8   PchUsbPort[8];
> +  UINT8   PchUsbRmh;
> +  UINT8   PchUsbOtg;
> +  UINT8   PchUsbVbusOn;       //OTG VBUS control
> +  UINT8   PchFSAOn;       //FSA control
> +  UINT8   EhciPllCfgEnable;
> +
> +
> +  //Gbe
> +  UINT8         PcieRootPortSpeed[PCH_PCIE_MAX_ROOT_PORTS];
> +  UINT8   SlpLanLowDc;
> +
> +  UINT8   ISCT00;
> +  UINT8   ISCT01;
> +  UINT8   ISCT02;
> +  UINT8   ISCT03;
> +  UINT8    ISCT04;
> +  UINT8    ISCT05;
> +  UINT8    ISCT06;
> +  UINT8    ISCT07;
> +  //
> +  // Azalia Configuration
> +  //
> +  UINT8   PchAzalia;
> +  UINT8   AzaliaVCiEnable;
> +  UINT8   AzaliaDs;
> +  UINT8   AzaliaPme;
> +  UINT8   HdmiCodec;
> +
> +  UINT8   UartInterface;
> +  UINT8   PcuUart1;
> +  //UINT8   PcuUart2;//for A0
> +  UINT8   StateAfterG3;
> +  UINT8   EnableClockSpreadSpec;
> +  UINT8   GraphicReserve00;
> +  UINT8   GOPEnable;
> +  UINT8   GOPBrightnessLevel;                     //Gop Brightness level
> +  UINT8   PavpMode;
> +  UINT8   SEC04;
> +  UINT8   SEC05;
> +  UINT8   SEC06;
> +  UINT8   SEC07;
> +
> +  UINT8   HdmiCodecPortB;
> +  UINT8   HdmiCodecPortC;
> +  UINT8   HdmiCodecPortD;
> +  UINT8   LidStatus;
> +  UINT8   Reserved00;
> +  UINT8   Reserved01;
> +  UINT16  Reserved02;
> +  UINT16  Reserved03;
> +  UINT16  Reserved04;
> +  UINT16  Reserved05;
> +  UINT16  Reserved06;
> +  UINT16  Reserved07;
> +  UINT16  Reserved08;
> +  UINT16  Reserved09;
> +  UINT16  Reserved0A;
> +  UINT16  Reserved0B;
> +  UINT16  Reserved0C;
> +  UINT16  Reserved0D;
> +  UINT8   Reserved0E;
> +  UINT8   Reserved0F;
> +  UINT32  Reserved10;
> +  UINT32  Reserved11;
> +  UINT32  Reserved12;
> +  UINT32  Reserved13;
> +  UINT32  Reserved14;
> +  UINT8   Reserved15;
> +  UINT8   Reserved16;
> +  UINT8   Reserved17;
> +  UINT8   Reserved18;
> +  UINT8   Reserved19;
> +  UINT8   Reserved1A;
> +  UINT8   Reserved1B;
> +  UINT8   Reserved1C;
> +  UINT8   Reserved1D;
> +  UINT8   Reserved1E;
> +  UINT8   Reserved1F;
> +  UINT8   Reserved20;
> +  UINT8   PmicEnable;
> +  UINT8   IdleReserve;
> +  UINT8   TSEGSizeSel;
> +  UINT8   ACPIMemDbg;
> +  UINT8    ExISupport;
> +  UINT8   BatteryChargingSolution;                 //0-non ULPMC 1-ULPMC
> +  UINT8   PnpSettings;
> +  UINT8   CfioPnpSettings;
> +  UINT8   PchEhciDebug;
> +  UINT8   CRIDSettings;
> +  UINT8   ULPMCFWLock;
> +  UINT8   SpiRwProtect;
> +  UINT8   GraphicReserve02;
> +  UINT8   PDMConfig;
> +  UINT16  LmMemSize;
> +  UINT8   PunitBIOSConfig;
> +  UINT8   LpssSdioMode;
> +  UINT8   ENDBG2;
> +  UINT8   WittEnable;
> +  UINT8   UtsEnable;
> +  UINT8   TristateLpc;
> +  UINT8   GraphicReserve05;
> +  UINT8   UsbXhciLpmSupport;
> +  UINT8   EnableAESNI;
> +  UINT8   SecureErase;
> +
> +  UINT8   MmioSize;
> +
> +
> +  UINT8   SAR1;
> +
> +  UINT8   DisableCodec262;
> +  UINT8   ReservedO;
> +  UINT8   PcieDynamicGating;        // Need PMC enable it first from PMC
> 0x3_12 MCU 318.
> +
> +  UINT8   MipiDsi;
> +
> +  //Added flow control item for UART1 and UART2
> +  UINT8  LpssHsuart0FlowControlEnabled;
> +  UINT8  LpssHsuart1FlowControlEnabled;
> +
> +  UINT8   SdCardRemovable; // ACPI reporting MMC/SD media as:
> removable/non-removable
> +  UINT8   GpioWakeCapability;
> +  UINT8   RtcBattery;
> +  UINT8   LpeAudioReportedByDSDT;
> +
> +  UINT8   Uart1Int3511Com; // Report UART1 as COM with _HID INT3511
> +  CHAR16  SystemUuid[37];
> +
> +} SYSTEM_CONFIGURATION;
> +#pragma pack()
> +
> +#ifndef PLATFORM_SETUP_VARIABLE_NAME
> +#define PLATFORM_SETUP_VARIABLE_NAME             L"Setup"
> +#endif
> +
> +#pragma pack(1)
> +typedef struct{
> +  // Passwords
> +  UINT16        UserPassword[PASSWORD_MAX_SIZE];
> +  UINT16        AdminPassword[PASSWORD_MAX_SIZE];
> +  UINT16        DummyDataForVfrBug;  // Don't change or use
> +
> +} SYSTEM_PASSWORDS;
> +#pragma pack()
> +
> +//
> +// #defines for Drive Presence
> +//
> +#define EFI_HDD_PRESENT       0x01
> +#define EFI_HDD_NOT_PRESENT   0x00
> +#define EFI_CD_PRESENT        0x02
> +#define EFI_CD_NOT_PRESENT    0x00
> +
> +#define EFI_HDD_WARNING_ON    0x01
> +#define EFI_CD_WARNING_ON     0x02
> +#define EFI_SMART_WARNING_ON  0x04
> +#define EFI_HDD_WARNING_OFF   0x00
> +#define EFI_CD_WARNING_OFF    0x00
> +#define EFI_SMART_WARNING_OFF 0x00
> +
> +#ifndef VFRCOMPILE
> +extern EFI_GUID gEfiSetupVariableGuid;
> +#endif
> +
> +#define SETUP_DATA SYSTEM_CONFIGURATION
> +
> +#endif // #ifndef _SETUP_VARIABLE
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Hpet.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Hpet.h
> new file mode 100644
> index 0000000000..e448ee9796
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Hpet.h
> @@ -0,0 +1,40 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  Mseg.h
> +
> +Abstract:
> +
> +  This file describes the contents of the ACPI HEPT Table.
> +
> +--*/
> +
> +#ifndef _HPET_H
> +#define _HPET_H
> +
> +//
> +// Statements that include other files
> +//
> +#include <IndustryStandard/Acpi10.h>
> +#include <IndustryStandard/Acpi20.h>
> +#include <IndustryStandard/Acpi30.h>
> +#include <IndustryStandard/HighPrecisionEventTimerTable.h>
> +
> +//
> +// HPET Definitions
> +//
> +#define EFI_ACPI_HPET_TABLE_REVISION            0x1
> +#define MAIN_COUNTER_MIN_PERIODIC_CLOCK_TICKS	0x80
> //approx 1ms
> +
> +#define HPET_BASE_ADDRESS                       0xFED00000
> +#define EFI_ACPI_EVENT_TIMER_BLOCK_ID           0x8086A001
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/BiosIdLib.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/BiosIdLib.h
> new file mode 100644
> index 0000000000..484b358264
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/BiosIdLib.h
> @@ -0,0 +1,104 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  BiosIdLib.h
> +
> +Abstract:
> +
> +  BIOS ID library definitions.
> +
> +  This library provides functions to get BIOS ID, VERSION, DATE and TIME
> +
> +--*/
> +
> +#ifndef _BIOS_ID_LIB_H_
> +#define _BIOS_ID_LIB_H_
> +
> +//
> +// BIOS ID string format:
> +//
> +//
> $(BOARD_ID)$(BOARD_REV).$(OEM_ID).$(VERSION_MAJOR).$(BUILD_TYPE
> )$(VERSION_MINOR).YYMMDDHHMM
> +//
> +// Example: "TRFTCRB1.86C.0008.D03.0506081529"
> +//
> +#pragma pack(1)
> +
> +typedef struct {
> +  CHAR16  BoardId[7];               // "TRFTCRB"
> +  CHAR16  BoardRev;                 // "1"
> +  CHAR16  Dot1;                     // "."
> +  CHAR16  OemId[3];                 // "86C"
> +  CHAR16  Dot2;                     // "."
> +  CHAR16  VersionMajor[4];          // "0008"
> +  CHAR16  Dot3;                     // "."
> +  CHAR16  BuildType;                // "D"
> +  CHAR16  VersionMinor[2];          // "03"
> +  CHAR16  Dot4;                     // "."
> +  CHAR16  TimeStamp[10];            // "YYMMDDHHMM"
> +  CHAR16  NullTerminator;           // 0x0000
> +} BIOS_ID_STRING;
> +
> +#define MEM_IFWIVER_START           0x7E0000
> +#define MEM_IFWIVER_LENGTH          0x1000
> +
> +typedef struct _MANIFEST_OEM_DATA{
> +  UINT32         Signature;
> +  unsigned char  FillNull[0x39];
> +  UINT32         IFWIVersionLen;
> +  unsigned char  IFWIVersion[32];
> +}MANIFEST_OEM_DATA;
> +
> +//
> +// A signature precedes the BIOS ID string in the FV to enable search by
> external tools.
> +//
> +typedef struct {
> +  UINT8           Signature[8];     // "$IBIOSI$"
> +  BIOS_ID_STRING  BiosIdString;     // "TRFTCRB1.86C.0008.D03.0506081529"
> +} BIOS_ID_IMAGE;
> +
> +#pragma pack()
> +
> +/**
> +  This function returns BIOS ID by searching HOB or FV.
> +
> +  @param[in]  BiosIdImage         The BIOS ID got from HOB or FV
> +
> +  @retval  EFI_SUCCESS            All parameters were valid and BIOS ID has
> been got.
> +  @retval  EFI_NOT_FOUND          BiosId image is not found, and no
> parameter will be modified.
> +  @retval  EFI_INVALID_PARAMETER  The parameter is NULL.
> +
> +**/
> +EFI_STATUS
> +GetBiosId (
> +  OUT BIOS_ID_IMAGE     *BiosIdImage
> +  );
> +
> +/**
> +  This function returns the Version & Release Date and Time by getting and
> converting
> +  BIOS ID.
> +
> +  @param[in] BiosVersion         The Bios Version out of the conversion.
> +  @param[in] BiosReleaseDate     The Bios Release Date out of the
> conversion.
> +  @param[in] BiosReleaseTime     The Bios Release Time out of the
> conversion.
> +
> +  @retval EFI_SUCCESS            BIOS Version & Release Date and Time have
> been got successfully.
> +  @retval EFI_NOT_FOUND          BiosId image is not found, and no
> parameter will be modified.
> +  @retval EFI_INVALID_PARAMETER  All the parameters are NULL.
> +
> +**/
> +EFI_STATUS
> +GetBiosVersionDateTime (
> +  OUT CHAR16    *BiosVersion, OPTIONAL
> +  OUT CHAR16    *BiosReleaseDate, OPTIONAL
> +  OUT CHAR16    *BiosReleaseTime OPTIONAL
> +  );
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/CpuIA32.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/CpuIA32.h
> new file mode 100644
> index 0000000000..78c78319ce
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/CpuIA32.h
> @@ -0,0 +1,345 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  CpuIA32.h
> +
> +Abstract:
> +
> +--*/
> +
> +#ifndef _CPU_IA32_H
> +#define _CPU_IA32_H
> +
> +typedef struct {
> +  UINT32  RegEax;
> +  UINT32  RegEbx;
> +  UINT32  RegEcx;
> +  UINT32  RegEdx;
> +} EFI_CPUID_REGISTER;
> +
> +typedef struct {
> +  UINT32  HeaderVersion;
> +  UINT32  UpdateRevision;
> +  UINT32  Date;
> +  UINT32  ProcessorId;
> +  UINT32  Checksum;
> +  UINT32  LoaderRevision;
> +  UINT32  ProcessorFlags;
> +  UINT32  DataSize;
> +  UINT32  TotalSize;
> +  UINT8   Reserved[12];
> +} EFI_CPU_MICROCODE_HEADER;
> +
> +typedef struct {
> +  UINT32  ExtendedSignatureCount;
> +  UINT32  ExtendedTableChecksum;
> +  UINT8   Reserved[12];
> +} EFI_CPU_MICROCODE_EXTENDED_TABLE_HEADER;
> +
> +typedef struct {
> +  UINT32  ProcessorSignature;
> +  UINT32  ProcessorFlag;
> +  UINT32  ProcessorChecksum;
> +} EFI_CPU_MICROCODE_EXTENDED_TABLE;
> +
> +typedef struct {
> +  UINT32  Stepping       : 4;
> +  UINT32  Model          : 4;
> +  UINT32  Family         : 4;
> +  UINT32  Type           : 2;
> +  UINT32  Reserved1      : 2;
> +  UINT32  ExtendedModel  : 4;
> +  UINT32  ExtendedFamily : 8;
> +  UINT32  Reserved2      : 4;
> +} EFI_CPU_VERSION;
> +
> +#define EFI_CPUID_SIGNATURE                   0x0
> +#define EFI_CPUID_VERSION_INFO                0x1
> +#define EFI_CPUID_CACHE_INFO                  0x2
> +#define EFI_CPUID_SERIAL_NUMBER               0x3
> +#define EFI_CPUID_EXTENDED_FUNCTION           0x80000000
> +#define EFI_CPUID_EXTENDED_CPU_SIG            0x80000001
> +#define EFI_CPUID_BRAND_STRING1               0x80000002
> +#define EFI_CPUID_BRAND_STRING2               0x80000003
> +#define EFI_CPUID_BRAND_STRING3               0x80000004
> +
> +#define EFI_MSR_IA32_PLATFORM_ID              0x17
> +#define EFI_MSR_IA32_APIC_BASE                0x1B
> +#define EFI_MSR_EBC_HARD_POWERON              0x2A
> +#define EFI_MSR_EBC_SOFT_POWERON              0x2B
> +#define BINIT_DRIVER_DISABLE                  0x40
> +#define INTERNAL_MCERR_DISABLE                0x20
> +#define INITIATOR_MCERR_DISABLE               0x10
> +#define EFI_MSR_EBC_FREQUENCY_ID              0x2C
> +#define EFI_MSR_IA32_BIOS_UPDT_TRIG           0x79
> +#define EFI_MSR_IA32_BIOS_SIGN_ID             0x8B
> +#define EFI_MSR_PSB_CLOCK_STATUS              0xCD
> +#define EFI_APIC_GLOBAL_ENABLE                0x800
> +#define EFI_MSR_IA32_MISC_ENABLE              0x1A0
> +#define LIMIT_CPUID_MAXVAL_ENABLE_BIT         0x00400000
> +#define AUTOMATIC_THERMAL_CONTROL_ENABLE_BIT  0x00000008
> +#define COMPATIBLE_FPU_OPCODE_ENABLE_BIT      0x00000004
> +#define LOGICAL_PROCESSOR_PRIORITY_ENABLE_BIT 0x00000002
> +#define FAST_STRING_ENABLE_BIT                0x00000001
> +
> +#define EFI_CACHE_VARIABLE_MTRR_BASE          0x200
> +#define EFI_CACHE_VARIABLE_MTRR_END           0x20F
> +#define EFI_CACHE_IA32_MTRR_DEF_TYPE          0x2FF
> +#define EFI_CACHE_MTRR_VALID                  0x800
> +#define EFI_CACHE_FIXED_MTRR_VALID            0x400
> +#define EFI_CACHE_VALID_ADDRESS               0xFFFFFF000
> +#define EFI_MSR_VALID_MASK                    0xFFFFFFFFF
> +#define EFI_CACHE_VALID_EXTENDED_ADDRESS      0xFFFFFFFFFF000
> +#define EFI_MSR_VALID_EXTENDED_MASK           0xFFFFFFFFFFFFF
> +
> +#define EFI_IA32_MTRR_FIX64K_00000            0x250
> +#define EFI_IA32_MTRR_FIX16K_80000            0x258
> +#define EFI_IA32_MTRR_FIX16K_A0000            0x259
> +#define EFI_IA32_MTRR_FIX4K_C0000             0x268
> +#define EFI_IA32_MTRR_FIX4K_C8000             0x269
> +#define EFI_IA32_MTRR_FIX4K_D0000             0x26A
> +#define EFI_IA32_MTRR_FIX4K_D8000             0x26B
> +#define EFI_IA32_MTRR_FIX4K_E0000             0x26C
> +#define EFI_IA32_MTRR_FIX4K_E8000             0x26D
> +#define EFI_IA32_MTRR_FIX4K_F0000             0x26E
> +#define EFI_IA32_MTRR_FIX4K_F8000             0x26F
> +
> +#define EFI_IA32_MCG_CAP                      0x179
> +#define EFI_IA32_MCG_CTL                      0x17B
> +#define EFI_IA32_MC0_CTL                      0x400
> +#define EFI_IA32_MC0_STATUS                   0x401
> +
> +#define EFI_IA32_PERF_STATUS                  0x198
> +#define EFI_IA32_PERF_CTL                     0x199
> +
> +#define EFI_CACHE_UNCACHEABLE                 0
> +#define EFI_CACHE_WRITECOMBINING              1
> +#define EFI_CACHE_WRITETHROUGH                4
> +#define EFI_CACHE_WRITEPROTECTED              5
> +#define EFI_CACHE_WRITEBACK                   6
> +
> +//
> +// Combine f(FamilyId), m(Model), s(SteppingId) to a single 32 bit number
> +//
> +#define EfiMakeCpuVersion(f, m, s)         \
> +  (((UINT32) (f) << 16) | ((UINT32) (m) << 8) | ((UINT32) (s)))
> +
> +/**
> +  Halt the Cpu
> +
> +  @param[in] None
> +
> +  @retval None
> +
> +**/
> +VOID
> +EFIAPI
> +EfiHalt (
> +  VOID
> +  );
> +
> +/**
> +  Write back and invalidate the Cpu cache
> +
> +  @param[in] None
> +
> +  @retval None
> +
> +**/
> +VOID
> +EFIAPI
> +EfiWbinvd (
> +  VOID
> +  );
> +
> +/**
> +  Invalidate the Cpu cache
> +
> +   @param[in] None
> +
> +   @retval None
> +
> +**/
> +VOID
> +EFIAPI
> +EfiInvd (
> +  VOID
> +  );
> +
> +/**
> +  Get the Cpu info by execute the CPUID instruction
> +
> +  @param[in] RegisterInEax The input value to put into register EAX
> +  @param[in] Regs          The Output value
> +
> +  @retval None
> +
> +**/
> +VOID
> +EFIAPI
> +EfiCpuid (
> +  IN  UINT32                 RegisterInEax,
> +  OUT EFI_CPUID_REGISTER     *Regs
> +  );
> +
> +/**
> +  When RegisterInEax != 4, the functionality is the same as EfiCpuid.
> +  When RegisterInEax == 4, the function return the deterministic cache
> +  parameters by excuting the CPUID instruction.
> +
> +  @param[in]  RegisterInEax  The input value to put into register EAX.
> +  @param[in]  CacheLevel     The deterministic cache level.
> +  @param[in]  Regs           The Output value.
> +
> +  @retval None
> +
> +**/
> +VOID
> +EFIAPI
> +EfiCpuidExt (
> +  IN  UINT32                 RegisterInEax,
> +  IN  UINT32                 CacheLevel,
> +  OUT EFI_CPUID_REGISTER     *Regs
> +  );
> +
> +/**
> +  Read Cpu MSR
> +
> +  @param[in] Index  The index value to select the register
> +
> +  @retval           Return the read data
> +
> +**/
> +UINT64
> +EFIAPI
> +EfiReadMsr (
> +  IN UINT32     Index
> +  );
> +
> +/**
> +  Write Cpu MSR
> +
> +  @param[in] Index  The index value to select the register
> +  @param[in] Value  The value to write to the selected register
> +
> +  @retval None
> +
> +**/
> +VOID
> +EFIAPI
> +EfiWriteMsr (
> +  IN UINT32     Index,
> +  IN UINT64     Value
> +  );
> +
> +/**
> +  Read Time stamp
> +
> +  @param[in] None
> +
> +  @retval Return the read data
> +
> +**/
> +UINT64
> +EFIAPI
> +EfiReadTsc (
> +  VOID
> +  );
> +
> +/**
> +  Writing back and invalidate the cache,then diable it
> +
> +  @param[in] None
> +
> +  @retval None
> +
> +**/
> +VOID
> +EFIAPI
> +EfiDisableCache (
> +  VOID
> +  );
> +
> +/**
> +  Invalidate the cache,then Enable it
> +
> +  @param[in] None
> +
> +  @retval None
> +
> +**/
> +VOID
> +EFIAPI
> +EfiEnableCache (
> +  VOID
> +  );
> +
> +/**
> +  Get Eflags
> +
> +  @param[in] None
> +
> +  @retval Return the Eflags value
> +
> +**/
> +UINT32
> +EFIAPI
> +EfiGetEflags (
> +  VOID
> +  );
> +
> +/**
> +  Disable Interrupts
> +
> +  @param[in] None
> +
> +  @retval None
> +
> +**/
> +VOID
> +EFIAPI
> +EfiDisableInterrupts (
> +  VOID
> +  );
> +
> +/**
> +  Enable Interrupts
> +
> +  @param[in] None
> +
> +  @retval None
> +
> +**/
> +VOID
> +EFIAPI
> +EfiEnableInterrupts (
> +  VOID
> +  );
> +
> +/**
> +  Extract CPU detail version infomation
> +
> +  @param[in] FamilyId    FamilyId, including ExtendedFamilyId
> +  @param[in] Model       Model, including ExtendedModel
> +  @param[in] SteppingId  SteppingId
> +  @param[in] Processor   Processor
> +
> +**/
> +VOID
> +EFIAPI
> +EfiCpuVersion (
> +  IN   UINT16  *FamilyId,    OPTIONAL
> +  IN   UINT8   *Model,       OPTIONAL
> +  IN   UINT8   *SteppingId,  OPTIONAL
> +  IN   UINT8   *Processor    OPTIONAL
> +  );
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/EfiRegTableLib.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/EfiRegTableLib.h
> new file mode 100644
> index 0000000000..915f8b39d9
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/EfiRegTableLib.h
> @@ -0,0 +1,196 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  EfiRegTableLib.h
> +
> +Abstract:
> +
> +  Definitions and macros for building register tables for chipset
> +  initialization..
> +
> +  Components linking this lib must include CpuIo, PciRootBridgeIo, and
> +  BootScriptSave protocols in their DPX.
> +
> +
> +
> +--*/
> +
> +#ifndef EFI_REG_TABLE_H
> +#define EFI_REG_TABLE_H
> +
> +
> +#include <PiDxe.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Protocol/CpuIo.h>
> +#include <Protocol/BootScriptSave.h>
> +#include <Framework/BootScript.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +
> +
> +#define OPCODE_BASE(OpCode)       ((UINT8)((OpCode) & 0xFF))
> +#define OPCODE_FLAGS(OpCode)      ((UINT8)(((OpCode) >> 8) & 0xFF))
> +#define OPCODE_EXTRA_DATA(OpCode) ((UINT16)((OpCode) >> 16))
> +
> +//
> +// RegTable Base OpCodes
> +//
> +#define OP_TERMINATE_TABLE                0
> +#define OP_MEM_WRITE                      1
> +#define OP_MEM_READ_MODIFY_WRITE          2
> +#define OP_IO_WRITE                       3
> +#define OP_IO_READ_MODIFY_WRITE           4
> +#define OP_PCI_WRITE                      5
> +#define OP_PCI_READ_MODIFY_WRITE          6
> +#define OP_STALL                          7
> +
> +//
> +// RegTable OpCode Flags
> +//
> +#define OPCODE_FLAG_S3SAVE                1
> +
> +
> +#define TERMINATE_TABLE { (UINT32) OP_TERMINATE_TABLE, (UINT32) 0,
> (UINT32) 0 }
> +
> +
> +//
> +// REG_TABLE_ENTRY_PCI_WRITE encodes the width in the upper bits of
> the OpCode
> +// as one of the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH values
> +//
> +typedef struct {
> +  UINT32                                OpCode;
> +  UINT32                                PciAddress;
> +  UINT32                                Data;
> +} EFI_REG_TABLE_PCI_WRITE;
> +
> +#define PCI_WRITE(Bus, Dev, Fnc, Reg, Width, Data, S3Flag)                    \
> +  {                                                                           \
> +    (UINT32) (OP_PCI_WRITE | ((S3Flag) << 8) | ((Width) << 16)),              \
> +    (UINT32) (EFI_PCI_ADDRESS ((Bus), (Dev), (Fnc), (Reg))),                  \
> +    (UINT32) (Data),                                                          \
> +    (UINT32) (0)                                                              \
> +  }
> +
> +typedef struct {
> +  UINT32                                OpCode;
> +  UINT32                                MemAddress;
> +  UINT32                                Data;
> +} EFI_REG_TABLE_MEM_WRITE;
> +
> +typedef struct {
> +  UINT32                                OpCode;
> +  UINT32                                PciAddress;
> +  UINT32                                OrMask;
> +  UINT32                                AndMask;
> +} EFI_REG_TABLE_PCI_READ_MODIFY_WRITE;
> +
> +#define PCI_READ_MODIFY_WRITE(Bus, Dev, Fnc, Reg, Width, OrMask,
> AndMask, S3Flag)  \
> +  {                                                                           \
> +    (UINT32) (OP_PCI_READ_MODIFY_WRITE | ((S3Flag) << 8) | ((Width) <<
> 16)),  \
> +    (UINT32) (EFI_PCI_ADDRESS ((Bus), (Dev), (Fnc), (Reg))),                  \
> +    (UINT32) (OrMask),                                                        \
> +    (UINT32) (AndMask)                                                        \
> +  }
> +
> +typedef struct {
> +  UINT32                                OpCode;
> +  UINT32                                MemAddress;
> +  UINT32                                OrMask;
> +  UINT32                                AndMask;
> +} EFI_REG_TABLE_MEM_READ_MODIFY_WRITE;
> +
> +#define MEM_READ_MODIFY_WRITE(Address, Width, OrMask, AndMask,
> S3Flag)  \
> +  {                                                                           \
> +    (UINT32) (OP_MEM_READ_MODIFY_WRITE | ((S3Flag) << 8) | ((Width)
> << 16)),  \
> +    (UINT32) (Address),                  \
> +    (UINT32) (OrMask),                                                        \
> +    (UINT32) (AndMask)                                                        \
> +  }
> +
> +typedef struct {
> +  UINT32                                OpCode;
> +  UINT32                                Field2;
> +  UINT32                                Field3;
> +  UINT32                                Field4;
> +} EFI_REG_TABLE_GENERIC;
> +
> +typedef union {
> +  EFI_REG_TABLE_GENERIC                 Generic;
> +  EFI_REG_TABLE_PCI_WRITE               PciWrite;
> +  EFI_REG_TABLE_PCI_READ_MODIFY_WRITE   PciReadModifyWrite;
> +  EFI_REG_TABLE_MEM_READ_MODIFY_WRITE   MemReadModifyWrite;
> +} EFI_REG_TABLE;
> +
> +/**
> +  Processes register table assuming which may contain PCI, IO, MEM, and
> STALL
> +  entries.
> +
> +  No parameter checking is done so the caller must be careful about omitting
> +  values for PciRootBridgeIo or CpuIo parameters.  If the regtable does
> +  not contain any PCI accesses, it is safe to omit the PciRootBridgeIo (supply
> +  NULL).  If the regtable does not contain any IO or Mem entries, it is safe to
> +  omit the CpuIo (supply NULL).
> +
> +  The RegTableEntry parameter is not checked, but is required.
> +
> +  gBS is assumed to have been defined and is used when processing stalls.
> +
> +  The function processes each entry sequentially until an
> OP_TERMINATE_TABLE
> +  entry is encountered.
> +
> +  @param[in] RegTableEntry    A pointer to the register table to process
> +
> +  @param[in] PciRootBridgeIo  A pointer to the instance of PciRootBridgeIo
> that is used
> +                              when processing PCI table entries
> +
> +  @param[in] CpuIo            A pointer to the instance of CpuIo that is used
> when processing IO and
> +                              MEM table entries
> +
> +  @retval Nothing.
> +
> +**/
> +VOID
> +ProcessRegTablePci (
> +  EFI_REG_TABLE                   * RegTableEntry,
> +  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * PciRootBridgeIo,
> +  EFI_CPU_IO_PROTOCOL             * CpuIo
> +  );
> +
> +/**
> +  Processes register table assuming which may contain IO, MEM, and STALL
> +  entries, but must NOT contain any PCI entries.  Any PCI entries cause an
> +  ASSERT in a DEBUG build and are skipped in a free build.
> +
> +  No parameter checking is done.  Both RegTableEntry and CpuIo
> parameters are
> +  required.
> +
> +  gBS is assumed to have been defined and is used when processing stalls.
> +
> +  The function processes each entry sequentially until an
> OP_TERMINATE_TABLE
> +  entry is encountered.
> +
> +  @param[in] RegTableEntry - A pointer to the register table to process
> +
> +  @param[in] CpuIo - A pointer to the instance of CpuIo that is used when
> processing IO and
> +                  MEM table entries
> +
> +  @retval Nothing.
> +
> +**/
> +VOID
> +ProcessRegTableCpu (
> +  EFI_REG_TABLE                   * RegTableEntry,
> +  EFI_CPU_IO_PROTOCOL             * CpuIo
> +  );
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Esrt.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Esrt.h
> new file mode 100644
> index 0000000000..a92a27cade
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Esrt.h
> @@ -0,0 +1,74 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> + Esrt.h
> +
> +Abstract:
> +
> +--*/
> +
> +#ifndef _DFU_ESRT_H_
> +#define _DFU_ESRT_H_
> +
> +typedef struct {
> +  EFI_GUID         FwClass;
> +  UINT32           FwType;
> +  UINT32           FwVersion;
> +  UINT32           FwLstCompatVersion;
> +  UINT32           CapsuleFlags;
> +  UINT32           LastAttemptVersion;
> +  UINT32           LastAttemptStatus;
> +} FW_RES_ENTRY;
> +
> +typedef struct {
> +  UINT32           NumEntries;
> +  FW_RES_ENTRY     FwEntries[256];
> +} FW_RES_ENTRY_LIST;
> +
> +
> +typedef struct {
> +  UINT32          FwResourceCount;
> +  UINT32          FwResourceMax;
> +  UINT64          FwResourceVersion;
> +} EFI_SYSTEM_RESOURCE_TABLE;
> +
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *ESRT_POPULATE_TABLE) (
> +);
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *ESRT_UPDATE_TABLE_ENTRY_BY_GUID) (
> +	IN EFI_GUID FwEntryGuid,
> +	IN FW_RES_ENTRY *FwEntry
> +);
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *ESRT_GET_FW_ENTRY_BY_GUID) (
> +    IN EFI_GUID FwEntryGuid,
> +	OUT FW_RES_ENTRY *FwEntry
> +);
> +
> +
> +#pragma pack()
> +
> +typedef struct _ESRT_OPERATION_PROTOCOL {
> +   ESRT_POPULATE_TABLE
> 	EsrtPopulateTable;
> +   ESRT_UPDATE_TABLE_ENTRY_BY_GUID
> 	EsrtUpdateTableEntryByGuid;
> +   ESRT_GET_FW_ENTRY_BY_GUID
> 	EsrtGetFwEntryByGuid;
> +} ESRT_OPERATION_PROTOCOL;
> +
> +extern EFI_GUID gEfiEsrtOperationProtocolGuid;
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Fd.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Fd.h
> new file mode 100644
> index 0000000000..a54ac11162
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Fd.h
> @@ -0,0 +1,264 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +
> +Module Name:
> +
> +  Fd.h
> +
> +Abstract:
> +
> +  EFI Intel82802AB/82802AC Firmware Hub.
> +
> +
> +--*/
> +
> +
> +//
> +// Supported SPI devices
> +//
> +
> +//
> +// MFG and Device code
> +//
> +#define SST_25LF040A        0x0044BF
> +#define SST_25LF040         0x0040BF
> +#define SST_25LF080A        0x0080BF
> +#define SST_25VF080B        0x008EBF
> +#define SST_25VF016B        0x0041BF
> +#define SST_25VF032B        0x004ABF
> +
> +#define PMC_25LV040         0x007E9D
> +
> +#define ATMEL_26DF041       0x00441F
> +#define Atmel_AT26F004      0x00041F
> +#define Atmel_AT26DF081A    0x01451F
> +#define Atmel_AT25DF161     0x02461F
> +#define Atmel_AT26DF161     0x00461F
> +#define Atmel_AT25DF641     0x00481F
> +#define Atmel_AT26DF321     0x00471F
> +
> +#define Macronix_MX25L8005  0x1420C2
> +#define Macronix_MX25L1605A 0x1520C2
> +#define Macronix_MX25L3205D 0x1620C2
> +
> +#define STMicro_M25PE80     0x148020
> +
> +#define Winbond_W25X40      0x1330EF
> +#define Winbond_W25X80      0x1430EF
> +#define Winbond_W25Q80      0x1440EF
> +
> +#define Winbond_W25X16      0x1540EF    // W25Q16
> +#define Winbond_W25X32      0x1630EF
> +
> +//
> +//  NOTE: Assuming that 8Mbit flash will only contain a 4Mbit binary.
> +//  Treating 4Mbit and 8Mbit devices the same.
> +//
> +
> +//
> +// BIOS Base Address
> +//
> +#define BIOS_BASE_ADDRESS_4M  0xFFF80000
> +#define BIOS_BASE_ADDRESS_8M  0xFFF00000
> +#define BIOS_BASE_ADDRESS_16M 0xFFE00000
> +
> +//
> +// block and sector sizes
> +//
> +#define SECTOR_SIZE_256BYTE 0x100       // 256byte page size
> +#define SECTOR_SIZE_4KB     0x1000      // 4kBytes sector size
> +#define BLOCK_SIZE_32KB     0x00008000  // 32Kbytes block size
> +#define MAX_FLASH_SIZE      0x00400000  // 32Mbit (Note that this can also
> be used for the 4Mbit & 8Mbit)
> +
> +//
> +// Flash commands
> +//
> +#define SPI_SST25LF_COMMAND_WRITE         0x02
> +#define SPI_SST25LF_COMMAND_READ          0x03
> +#define SPI_SST25LF_COMMAND_ERASE         0x20
> +#define SPI_SST25LF_COMMAND_WRITE_DISABLE 0x04
> +#define SPI_SST25LF_COMMAND_READ_STATUS   0x05
> +#define SPI_SST25LF_COMMAND_WRITE_ENABLE  0x06
> +#define SPI_SST25LF_COMMAND_READ_ID       0xAB
> +#define SPI_SST25LF_COMMAND_WRITE_S_EN    0x50
> +#define SPI_SST25LF_COMMAND_WRITE_S       0x01
> +
> +#define SPI_PMC25LV_COMMAND_WRITE         0x02
> +#define SPI_PMC25LV_COMMAND_READ          0x03
> +#define SPI_PMC25LV_COMMAND_ERASE         0xD7
> +#define SPI_PMC25LV_COMMAND_WRITE_DISABLE 0x04
> +#define SPI_PMC25LV_COMMAND_READ_STATUS   0x05
> +#define SPI_PMC25LV_COMMAND_WRITE_ENABLE  0x06
> +#define SPI_PMC25LV_COMMAND_READ_ID       0xAB
> +#define SPI_PMC25LV_COMMAND_WRITE_S_EN    0x06
> +#define SPI_PMC25LV_COMMAND_WRITE_S       0x01
> +
> +#define SPI_AT26DF_COMMAND_WRITE         0x02
> +#define SPI_AT26DF_COMMAND_READ          0x03
> +#define SPI_AT26DF_COMMAND_ERASE         0x20
> +#define SPI_AT26DF_COMMAND_WRITE_DISABLE 0x00
> +#define SPI_AT26DF_COMMAND_READ_STATUS   0x05
> +#define SPI_AT26DF_COMMAND_WRITE_ENABLE  0x00
> +#define SPI_AT26DF_COMMAND_READ_ID       0x9F
> +#define SPI_AT26DF_COMMAND_WRITE_S_EN    0x00
> +#define SPI_AT26DF_COMMAND_WRITE_S       0x00
> +
> +#define SPI_AT26F_COMMAND_WRITE          0x02
> +#define SPI_AT26F_COMMAND_READ           0x03
> +#define SPI_AT26F_COMMAND_ERASE          0x20
> +#define SPI_AT26F_COMMAND_WRITE_DISABLE  0x04
> +#define SPI_AT26F_COMMAND_READ_STATUS    0x05
> +#define SPI_AT26F_COMMAND_WRITE_ENABLE   0x06
> +#define SPI_AT26F_COMMAND_JEDEC_ID       0x9F
> +#define SPI_AT26F_COMMAND_WRITE_S_EN     0x00
> +#define SPI_AT26F_COMMAND_WRITE_S        0x01
> +#define SPI_AT26F_COMMAND_WRITE_UNPROTECT 0x39
> +
> +#define SPI_SST25VF_COMMAND_WRITE         0x02
> +#define SPI_SST25VF_COMMAND_READ          0x03
> +#define SPI_SST25VF_COMMAND_ERASE         0x20
> +#define SPI_SST25VF_COMMAND_WRITE_DISABLE 0x04
> +#define SPI_SST25VF_COMMAND_READ_STATUS   0x05
> +#define SPI_SST25VF_COMMAND_WRITE_ENABLE  0x06
> +#define SPI_SST25VF_COMMAND_READ_ID       0xAB
> +#define SPI_SST25VF_COMMAND_JEDEC_ID      0x9F
> +#define SPI_SST25VF_COMMAND_WRITE_S_EN    0x50
> +#define SPI_SST25VF_COMMAND_WRITE_S       0x01
> +
> +#define SPI_STM25PE_COMMAND_WRITE         0x02
> +#define SPI_STM25PE_COMMAND_READ          0x03
> +#define SPI_STM25PE_COMMAND_ERASE         0xDB
> +#define SPI_STM25PE_COMMAND_WRITE_DISABLE 0x04
> +#define SPI_STM25PE_COMMAND_READ_STATUS   0x05
> +#define SPI_STM25PE_COMMAND_WRITE_ENABLE  0x06
> +#define SPI_STM25PE_COMMAND_JEDEC_ID      0x9F
> +
> +#define SPI_WinbondW25X_COMMAND_WRITE_S      0x01
> +#define SPI_WinbondW25X_COMMAND_WRITE        0x02
> +#define SPI_WinbondW25X_COMMAND_READ         0x03
> +#define SPI_WinbondW25X_COMMAND_READ_STATUS  0x05
> +#define SPI_WinbondW25X_COMMAND_ERASE_S      0x20
> +#define SPI_WinbondW25X_COMMAND_WRITE_ENABLE 0x06
> +#define SPI_WinbondW25X_COMMAND_JEDEC_ID     0x9F
> +
> +//
> +// SPI default opcode slots
> +//
> +#define SPI_OPCODE_WRITE_INDEX           0
> +#define SPI_OPCODE_READ_INDEX            1
> +#define SPI_OPCODE_ERASE_INDEX           2
> +#define SPI_OPCODE_READ_S_INDEX          3
> +#define SPI_OPCODE_READ_ID_INDEX         4
> +#define SPI_OPCODE_WRITE_S_INDEX         6
> +#define SPI_OPCODE_WRITE_UNPROTECT_INDEX 7
> +
> +#define SPI_PREFIX_WRITE_S_EN 1
> +#define SPI_PREFIX_WRITE_EN   0
> +
> +//
> +// Atmel AT26F00x
> +//
> +#define B_AT26F_STS_REG_SPRL  0x80
> +#define B_AT26F_STS_REG_SWP   0x0C
> +
> +//
> +// Block lock bit definitions:
> +//
> +#define READ_LOCK   0x04
> +#define LOCK_DOWN   0x02
> +#define WRITE_LOCK  0x01
> +#define FULL_ACCESS 0x00
> +
> +//
> +// Function Prototypes
> +//
> +EFI_STATUS
> +FlashGetNextBlock (
> +  IN UINTN*                               Key,
> +  OUT EFI_PHYSICAL_ADDRESS*               BlockAddress,
> +  OUT UINTN*                              BlockSize
> +  );
> +
> +EFI_STATUS
> +FlashGetSize (
> +  OUT UINTN* Size
> +  );
> +
> +EFI_STATUS
> +FlashGetUniformBlockSize (
> +  OUT UINTN* Size
> +  );
> +
> +EFI_STATUS
> +FlashEraseWithNoTopSwapping (
> +  IN  UINT8 *BaseAddress,
> +  IN  UINTN NumBytes
> +  );
> +
> +EFI_STATUS
> +FlashErase (
> +  IN  UINT8                 *BaseAddress,
> +  IN  UINTN                 NumBytes
> +  );
> +
> +EFI_STATUS
> +FlashWriteWithNoTopSwapping (
> +  IN UINT8*                 DstBufferPtr,
> +  IN UINT8*                 SrcBufferPtr,
> +  IN UINTN                  NumBytes
> +  );
> +
> +EFI_STATUS
> +FlashWrite (
> +  IN  UINT8                 *DstBufferPtr,
> +  IN  UINT8                 *SrcBufferPtr,
> +  IN  UINTN                 NumBytes
> +  );
> +
> +EFI_STATUS
> +FlashReadWithNoTopSwapping (
> +  IN  UINT8                 *BaseAddress,
> +  IN  UINT8                 *DstBufferPtr,
> +  IN  UINTN                 NumBytes
> +  );
> +
> +EFI_STATUS
> +FlashRead (
> +  IN  UINT8                 *BaseAddress,
> +  IN  UINT8                 *DstBufferPtr,
> +  IN  UINTN                 NumBytes
> +  );
> +
> +EFI_STATUS
> +FlashLockWithNoTopSwapping (
> +  IN UINT8*                BaseAddress,
> +  IN UINTN                 NumBytes,
> +  IN UINT8                 LockState
> +  );
> +
> +EFI_STATUS
> +FlashLock(
> +  IN  UINT8                 *BaseAddress,
> +  IN  UINTN                 NumBytes,
> +  IN  UINT8                 LockState
> +  );
> +
> +EFI_STATUS
> +CheckIfErased(
> +  IN  UINT8       *DstBufferPtr,
> +  IN  UINTN       NumBytes
> +  );
> +
> +EFI_STATUS
> +CheckIfFlashIsReadyForWrite (
> +  IN  UINT8       *DstBufferPtr,
> +  IN  UINT8       *SrcBufferPtr,
> +  IN  UINTN       NumBytes
> +  );
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/FlashDeviceLib.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/FlashDeviceLib.h
> new file mode 100644
> index 0000000000..43c5e88586
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/FlashDeviceLib.h
> @@ -0,0 +1,122 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +  Flash device library class header file.
> +
> +  Flash Device Library common type, MACRO and API definition. The basic
> idea for
> +  this library is to provide API to abstract the different between flash
> +  technology (SPI, FWH etc..), flash controller (SPI host controller on
> +  ICH, MMIO type access for FWH), flash chip (programming command,
> method
> +  of status checking). This library class can be consumed by drivers or
> applications
> +  such as Firmware Volume Block driver, Flash Update application. These
> driver
> +  can be written in a generic manner so that they are more easy to be
> +  ported to other platforms.
> +
> +  This library can be build on a set of APIs which can touch flash controller,
> flash
> +  chip directly for a platform with simple flash device configuration.
> +
> +  For a platform with complex flash device configuration, this library can be
> built
> +  on the Flash Device Operate Library. Please see the header file for that
> library
> +  class for detailed usage.
> +
> +**/
> +
> +#ifndef __FLASHDEVICE_LIB_H__
> +#define __FLASHDEVICE_LIB_H__
> +
> +/**
> +  Read NumBytes bytes of data from the address specified by
> +  PAddress into Buffer.
> +
> +  @param[in]      PAddress    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
> +LibFvbFlashDeviceRead (
> +  IN      UINTN                           PAddress,
> +  IN  OUT UINTN                           *NumBytes,
> +      OUT UINT8                           *Buffer
> +  );
> +
> +/**
> +  Write NumBytes bytes of data from Buffer to the address specified by
> +  PAddresss.
> +
> +  @param[in]      PAddress 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
> +LibFvbFlashDeviceWrite (
> +  IN        UINTN                           PAddress,
> +  IN OUT    UINTN                           *NumBytes,
> +  IN        UINT8                           *Buffer
> +  );
> +
> +/**
> +  Erase the block staring at PAddress.
> +
> +  @param[in]  PAddress The starting physical address of the region to be
> erased.
> +  @param[in]  LbaLength   The length of the region to be erased. This
> parameter is necessary
> +                       as the physical block size on a flash device could be different
> than
> +                       the logical block size of Firmware Volume Block protocol. Erase
> on
> +                       flash chip is always performed block by block. Therefore, the
> ERASE
> +                       operation to a logical block is converted a number of ERASE
> operation
> +                       (or a partial erase) on the hardware.
> +
> +  @retval EFI_SUCCESS.            Opertion is successful.
> +  @retval EFI_DEVICE_ERROR        If there is any device errors.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +LibFvbFlashDeviceBlockErase (
> +  IN    UINTN                      PAddress,
> +  IN    UINTN                      LbaLength
> +);
> +
> +/**
> +  Lock or unlock the block staring at PAddress.
> +
> +  @param[in]  PAddress The starting physical address of region to be
> (un)locked.
> +  @param[in]  LbaLength   The length of the region to be (un)locked. This
> parameter is necessary
> +                       as the physical block size on a flash device could be different
> than
> +                       the logical block size of Firmware Volume Block protocol.
> (Un)Lock on
> +                       flash chip is always performed block by block. Therefore, the
> (Un)Lock
> +                       operation to a logical block is converted a number of (Un)Lock
> operation
> +                       (or a partial erase) on the hardware.
> +  @param[in]  Lock     TRUE to lock. FALSE to unlock.
> +
> +  @retval EFI_SUCCESS. Opertion is successful.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +LibFvbFlashDeviceBlockLock (
> +  IN    UINTN                          PAddress,
> +  IN    UINTN                          LbaLength,
> +  IN    BOOLEAN                        Lock
> +);
> +
> +#endif
> +
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2CLib.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2CLib.h
> new file mode 100644
> index 0000000000..672c2b45f9
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2CLib.h
> @@ -0,0 +1,58 @@
> +/** @file
> +  Interface Definitions for I2C Lib.
> +
> +  Copyright (c) 2004  - 2015, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +--*/
> +
> +#include <Uefi.h>
> +#include <Library/IoLib.h>
> +
> +#ifndef I2C_LIB_HEADER_H
> +#define I2C_LIB_HEADER_H
> +
> +
> +/**
> +  Reads a Byte from I2C Device.
> +
> +  @param  I2cControllerIndex   I2C Bus no to which the I2C device has been
> connected
> +  @param  SlaveAddress         Device Address from which the byte value has
> to be read
> +  @param  Offset               Offset from which the data has to be read
> +  @param  ReadBytes            Number of bytes to be read
> +  @param  *ReadBuffer          Address to which the value read has to be
> stored
> +
> +  @return  EFI_SUCCESS       If the byte value has been successfully read
> +  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
> +**/
> +EFI_STATUS
> +ByteReadI2C(
> +  IN  UINT8 BusNo,
> +  IN  UINT8 SlaveAddress,
> +  IN  UINT8 Offset,
> +  IN  UINTN ReadBytes,
> +  OUT UINT8 *ReadBuffer
> +  );
> +
> +/**
> +  Writes a Byte to I2C Device.
> +
> +  @param  I2cControllerIndex  I2C Bus no to which the I2C device has been
> connected
> +  @param  SlaveAddress        Device Address from which the byte value has
> to be written
> +  @param  Offset              Offset from which the data has to be written
> +  @param  WriteBytes          Number of bytes to be written
> +  @param  *Byte               Address to which the value written is stored
> +
> +  @return  EFI_SUCCESS       If the byte value has been successfully read
> +  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
> +**/
> +EFI_STATUS ByteWriteI2C(
> +  IN  UINT8 BusNo,
> +  IN  UINT8 SlaveAddress,
> +  IN  UINT8 Offset,
> +  IN  UINTN WriteBytes,
> +  IN  UINT8 *WriteBuffer
> +  );
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cMmioConfigLib.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cMmioConfigLib.h
> new file mode 100644
> index 0000000000..7eea7e1d29
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cMmioConfigLib.h
> @@ -0,0 +1,23 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +**/
> +
> +#ifndef __MMIO_CONFIG_LIB_H__
> +#define __MMIO_CONFIG_LIB_H__
> +
> +#include <Protocol/MmioDevice.h>
> +
> +///
> +/// Declare the memory mapped I/O devices assocaited with the
> +/// board.
> +///
> +extern CONST EFI_MMIO_DEVICE_PROTOCOL gMmioDeviceList [ ];
> +extern CONST UINTN gMmioDeviceCount;
> +
> +#endif  //  __MMIO_CONFIG_LIB_H__
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cPort_platform.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cPort_platform.h
> new file mode 100644
> index 0000000000..9975faeac8
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cPort_platform.h
> @@ -0,0 +1,26 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +**/
> +
> +#ifndef _I2C_PORT_H
> +#define _I2C_PORT_H
> +
> +//
> +//  Types
> +//
> +
> +//
> +// Context passed from platform (board) layer to the I2C port driver.
> +//
> +typedef struct {
> +  EFI_PHYSICAL_ADDRESS BaseAddress;
> +  UINT32 InputFrequencyHertz;
> +} I2C_PIO_PLATFORM_CONTEXT;
> +
> +#endif  //  _I2C_PORT_A0_H
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFsaLib.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFsaLib.h
> new file mode 100644
> index 0000000000..06dab3016b
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFsaLib.h
> @@ -0,0 +1,50 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +--*/
> +
> +#ifndef _FSA_LIB_H
> +#define _FSA_LIB_H
> +#include <Uefi.h>
> +#include <Uefi/UefiSpec.h>
> +
> +#define FSA_REG_DEVID           0x1
> +#define FSA_REG_CTRL            0x2
> +#define FSA_REG_INTR            0x3
> +#define FSA_REG_INTR_MSK        0x5
> +#define FSA_REG_RESISTOR_CODE   0x7
> +#define FSA_REG_TIMING_SET      0x8
> +#define FSA_REG_STATUS          0x9
> +#define FSA_REG_DEV_TYPE        0xA
> +#define FSA_REG_DAC_SAR         0xB
> +#define FSA_REG_MANUAL_SW       0x13
> +#define FSA_REG_MANUAL_CHG_CTRL 0x14
> +
> +extern
> +EFI_STATUS
> +EFIAPI
> +FsaUsbDeviceMode (
> +  VOID
> +);
> +
> +
> +extern
> +EFI_STATUS
> +EFIAPI
> +DisableFsaTimerHandler (
> +  VOID
> +);
> +
> +extern
> +EFI_STATUS
> +EFIAPI
> +FSAInit (
> + IN UINT32 FFRDVer
> +);
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFspLib.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFspLib.h
> new file mode 100644
> index 0000000000..c3235afa90
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFspLib.h
> @@ -0,0 +1,23 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +--*/
> +
> +#ifndef _PLATFORM_FSP_LIB_H
> +#define _PLATFORM_FSP_LIB_H
> +#include <Base.h>
> +#include <Uefi.h>
> +
> +extern
> +EFI_STATUS
> +PlatformHobCreateFromFsp (
> +  IN CONST EFI_PEI_SERVICES     **PeiServices,
> +  VOID                          *HobList
> +  );
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/SpiFlash.H
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/SpiFlash.H
> new file mode 100644
> index 0000000000..335660cd4c
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/SpiFlash.H
> @@ -0,0 +1,239 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +**/
> +
> +#ifndef _SPIFlash_H_
> +#define _SPIFlash_H_
> +
> +#include <Protocol/Spi.h>
> +
> +//EFI_STATUS SpiFlashLock(BOOLEAN Lock);
> +//EFI_STATUS SpiFlashInit(void);
> +
> +typedef enum {
> +  EnumSpiFlashW25Q64,
> +  EnumSpiFlashAT25DF321A,
> +  EnumSpiFlashAT26DF321,
> +  EnumSpiFlashAT25DF641,
> +  EnumSpiFlashW25Q16,
> +  EnumSpiFlashW25Q32,
> +  EnumSpiFlashW25X32,
> +  EnumSpiFlashW25X64,
> +  EnumSpiFlashW25Q128,
> +  EnumSpiFlashMX25L16,
> +  EnumSpiFlashMX25L32,
> +  EnumSpiFlashMX25L64,
> +  EnumSpiFlashMX25L128,
> +  EnumSpiFlashMX25U6435F,
> +  EnumSpiFlashSST25VF016B,
> +  EnumSpiFlashSST25VF064C,
> +  EnumSpiFlashN25Q064,
> +  EnumSpiFlashM25PX16,
> +  EnumSpiFlashN25Q032,
> +  EnumSpiFlashM25PX32,
> +  EnumSpiFlashM25PX64,
> +  EnumSpiFlashN25Q128,
> +  EnumSpiFlashEN25Q16,
> +  EnumSpiFlashEN25Q32,
> +  EnumSpiFlashEN25Q64,
> +  EnumSpiFlashEN25Q128,
> +  EnumSpiFlashA25L016,
> +  EnumSpiFlashMax
> +} SPI_FLASH_TYPES_SUPPORTED;
> +
> +//
> +// Serial Flash VendorId and DeviceId
> +//
> +#define SF_VENDOR_ID_ATMEL          0x1F
> +#define SF_DEVICE_ID0_AT26DF321     0x47
> +#define SF_DEVICE_ID1_AT26DF321     0x00
> +#define SF_DEVICE_ID0_AT25DF321A    0x47
> +#define SF_DEVICE_ID1_AT25DF321A    0x01
> +#define SF_DEVICE_ID0_AT25DF641     0x48
> +#define SF_DEVICE_ID1_AT25DF641     0x00
> +
> +#define SF_VENDOR_ID_WINBOND        0xEF
> +#define SF_DEVICE_ID0_W25XXX        0x30
> +#define SF_DEVICE_ID1_W25X32        0x16
> +#define SF_DEVICE_ID1_W25X64        0x17
> +#define SF_DEVICE_ID0_W25QXX        0x40
> +#define SF_DEVICE_ID1_W25Q16        0x15
> +#define SF_DEVICE_ID1_W25Q32        0x16
> +#define SF_DEVICE_ID1_W25Q64        0x17
> +#define SF_DEVICE_ID1_W25Q128       0x18
> +
> +#define	SF_VENDOR_ID_MACRONIX       0xC2
> +#define	SF_DEVICE_ID0_MX25LXX       0x20
> +#define	SF_DEVICE_ID1_MX25L16       0x15
> +#define	SF_DEVICE_ID1_MX25L32       0x16
> +#define	SF_DEVICE_ID1_MX25L64       0x17
> +#define	SF_DEVICE_ID1_MX25L128      0x18
> +#define SF_DEVICE_ID0_MX25UXX       0x25
> +#define SF_DEVICE_ID1_MX25U6435F    0x37
> +
> +#define	SF_VENDOR_ID_NUMONYX        0x20
> +#define SF_DEVICE_ID0_N25Q064       0xBB
> +#define SF_DEVICE_ID1_N25Q064       0x17
> +#define	SF_DEVICE_ID0_M25PXXX       0x71
> +#define	SF_DEVICE_ID0_N25QXXX       0xBA
> +#define	SF_DEVICE_ID1_M25PX16       0x15
> +#define	SF_DEVICE_ID1_N25Q032       0x16
> +#define	SF_DEVICE_ID1_M25PX32       0x16
> +#define	SF_DEVICE_ID1_M25PX64       0x17
> +#define	SF_DEVICE_ID1_N25Q128       0x18
> +
> +#define SF_VENDOR_ID_SST            0xBF
> +#define SF_DEVICE_ID0_SST25VF0XXX   0x25
> +#define SF_DEVICE_ID1_SST25VF016B   0x41
> +#define SF_DEVICE_ID1_SST25VF064C   0x4B
> +
> +#define SF_VENDOR_ID_EON            0x1C
> +#define SF_DEVICE_ID0_EN25QXX       0x30
> +#define SF_DEVICE_ID1_EN25Q16       0x15
> +#define SF_DEVICE_ID1_EN25Q32       0x16
> +#define SF_DEVICE_ID1_EN25Q64       0x17
> +#define SF_DEVICE_ID1_EN25Q128      0x18
> +
> +#define SF_VENDOR_ID_AMIC           0x37
> +#define SF_DEVICE_ID0_A25L016       0x30
> +#define SF_DEVICE_ID1_A25L016       0x15
> +
> +#define ATMEL_AT26DF321_SIZE        0x00400000
> +#define ATMEL_AT25DF321A_SIZE       0x00400000
> +#define ATMEL_AT25DF641_SIZE        0x00800000
> +#define WINBOND_W25X32_SIZE         0x00400000
> +#define WINBOND_W25X64_SIZE         0x00800000
> +#define WINBOND_W25Q16_SIZE         0x00200000
> +#define WINBOND_W25Q32_SIZE         0x00400000
> +#define WINBOND_W25Q64_SIZE         0x00800000
> +#define WINBOND_W25Q128_SIZE        0x01000000
> +#define SST_SST25VF016B_SIZE        0x00200000
> +#define SST_SST25VF064C_SIZE        0x00800000
> +#define MACRONIX_MX25L16_SIZE       0x00200000
> +#define MACRONIX_MX25L32_SIZE       0x00400000
> +#define MACRONIX_MX25L64_SIZE       0x00800000
> +#define MACRONIX_MX25U64_SIZE       0x00800000
> +#define MACRONIX_MX25L128_SIZE      0x01000000
> +#define NUMONYX_M25PX16_SIZE        0x00400000
> +#define NUMONYX_N25Q032_SIZE        0x00400000
> +#define NUMONYX_M25PX32_SIZE        0x00400000
> +#define NUMONYX_M25PX64_SIZE        0x00800000
> +#define NUMONYX_N25Q064_SIZE        0x00800000
> +#define NUMONYX_N25Q128_SIZE        0x01000000
> +#define EON_EN25Q16_SIZE            0x00200000
> +#define EON_EN25Q32_SIZE            0x00400000
> +#define EON_EN25Q64_SIZE            0x00800000
> +#define EON_EN25Q128_SIZE           0x01000000
> +#define AMIC_A25L16_SIZE            0x00200000
> +
> +#define SF_VENDOR_ID_SST           0xBF
> +#define SF_DEVICE_ID0_25LF080A     0x25
> +#define SF_DEVICE_ID1_25LF080A     0x8E
> +#define SF_DEVICE_ID0_25VF016B     0x25
> +#define SF_DEVICE_ID1_25VF016B     0x41
> +
> +#define SF_VENDOR_ID_ATMEL         0x1F
> +#define SF_DEVICE_ID0_AT26DF321    0x47
> +#define SF_DEVICE_ID1_AT26DF321    0x00
> +
> +#define SF_VENDOR_ID_STM           0x20
> +#define SF_DEVICE_ID0_M25P32       0x20
> +#define SF_DEVICE_ID1_M25P32       0x16
> +
> +#define SF_VENDOR_ID_WINBOND       0xEF
> +#define SF_DEVICE_ID0_W25XXX       0x30
> +
> +#define SF_DEVICE_ID1_W25X80       0x14
> +#define SF_DEVICE_ID1_W25X16       0x15
> +#define SF_DEVICE_ID1_W25X32       0x16
> +#define SF_DEVICE_ID1_W25X64       0x17
> +
> +#define	SF_VENDOR_ID_MX				0xC2
> +#define	SF_DEVICE_ID0_25L1605A		0x20
> +#define	SF_DEVICE_ID1_25L1605A		0x15
> +
> +#define SF_VENDOR_ID_NUMONYX        0x20
> +#define SF_DEVICE_ID0_M25PX16       0x71
> +#define SF_DEVICE_ID1_M25PX16       0x15
> +
> +#define SST_25LF080A_SIZE          0x00100000
> +#define SST_25LF016B_SIZE          0x00200000
> +#define ATMEL_AT26DF321_SIZE       0x00400000
> +#define STM_M25P32_SIZE            0x00400000
> +#define WINBOND_W25X80_SIZE        0x00100000
> +#define WINBOND_W25X16_SIZE        0x00200000
> +#define WINBOND_W25X32_SIZE        0x00400000
> +#define WINBOND_W25X64_SIZE        0x00800000
> +#define MX_25L1605A_SIZE           0x00200000
> +
> +//
> +// Physical Sector Size on the Serial Flash device
> +//
> +#define SF_SECTOR_SIZE    0x1000
> +#define SF_BLOCK_SIZE     0x8000
> +
> +//
> +// Serial Flash Status Register definitions
> +//
> +#define SF_SR_BUSY        0x01      // Indicates if internal write operation is in
> progress
> +#define SF_SR_WEL         0x02      // Indicates if device is memory write
> enabled
> +#define SF_SR_BP0         0x04      // Block protection bit 0
> +#define SF_SR_BP1         0x08      // Block protection bit 1
> +#define SF_SR_BP2         0x10      // Block protection bit 2
> +#define SF_SR_BP3         0x20      // Block protection bit 3
> +#define SF_SR_WPE         0x3C      // Enable write protection on all blocks
> +#define SF_SR_AAI         0x40      // Auto Address Increment Programming
> status
> +#define SF_SR_BPL         0x80      // Block protection lock-down
> +
> +//
> +// Operation Instruction definitions for  the Serial Flash Device
> +//
> +#define SF_INST_WRSR            0x01     // Write Status Register
> +#define SF_INST_PROG            0x02     // Byte Program
> +#define SF_INST_READ            0x03     // Read
> +#define SF_INST_WRDI            0x04     // Write Disable
> +#define SF_INST_RDSR            0x05     // Read Status Register
> +#define SF_INST_WREN            0x06     // Write Enable
> +#define SF_INST_HS_READ         0x0B     // High-speed Read
> +#define SF_INST_SERASE          0x20     // Sector Erase (4KB)
> +#define SF_INST_BERASE          0x52     // Block Erase (32KB)
> +#define SF_INST_64KB_ERASE      0xD8     // Block Erase (64KB)
> +#define SF_INST_EWSR            0x50     // Enable Write Status Register
> +#define SF_INST_READ_ID         0xAB     // Read ID
> +#define SF_INST_JEDEC_READ_ID   0x9F     // JEDEC Read ID
> +#define SF_INST_DOFR            0x3B     // Dual Output Fast Read
> +#define SF_INST_SFDP            0x5A     // Serial Flash Discovery Parameters
> +
> +#define SECTOR_SIZE_4KB 	0x1000       // Common 4kBytes sector size
> +#define SECTOR_SIZE_64KB	0x10000      // Common 64kBytes sector size
> +#define BLOCK_SIZE_64KB 	0x00010000   // Common 64kBytes block size
> +#define MAX_FWH_SIZE    	0x00100000   // 8Mbit (Note that this can also
> be used for the 4Mbit )
> +
> +//
> +// 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
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/StallSmmLib.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/StallSmmLib.h
> new file mode 100644
> index 0000000000..49baffdcc5
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/StallSmmLib.h
> @@ -0,0 +1,40 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  SmmStallLib.h
> +
> +Abstract:
> +
> +  This library provides SMM functions for Stall.
> +  These can be used to save size and simplify code.
> +  All contents must be runtime and SMM safe.
> +
> +--*/
> +
> +#ifndef _SMM_STALL_LIB_H_
> +#define _SMM_STALL_LIB_H_
> +#include "PiDxe.h"
> +#include "Pi/PiSmmCis.h"
> +extern EFI_SMM_SYSTEM_TABLE2  *mSmst;
> +
> +/**
> +  Delay for at least the request number of microseconds
> +
> +  @param[in] Microseconds  Number of microseconds to delay.
> +
> +  @retval None
> +
> +**/
> +VOID
> +SmmStall (
> +  IN  UINTN   Microseconds
> +  );
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/UsbDeviceModeLib.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/UsbDeviceModeLib.h
> new file mode 100644
> index 0000000000..c52417f00f
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Library/UsbDeviceModeLib.h
> @@ -0,0 +1,181 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +**/
> +
> +#ifndef __BASE_USBDEVICEMODE_LIB_H__
> +#define __BASE_USBDEVICEMODE_LIB_H__
> +
> +#pragma pack(1)
> +typedef struct {
> +    UINT8  bLength;
> +    UINT8  bDescriptorType;
> +    UINT8  bMaxBurst;
> +    UINT8  bmAttributes;
> +    UINT16 wBytesPerInterval;
> +} endpointCompanionDescriptor;
> +#pragma pack()
> +
> +#pragma pack(1)
> +typedef struct {
> +    UINT8  bLength;
> +    UINT8  bDescriptorType;
> +    UINT8  bEndpointAddress;
> +    UINT8  bmAttributes;
> +    UINT16 wMaxPacketSize;
> +    UINT8  bInterval;
> +} endpointDescriptor;
> +#pragma pack()
> +
> +typedef struct {
> +    endpointDescriptor          *pEpDesc;
> +    endpointCompanionDescriptor *pEpCompDesc;
> +} USB_DEV_EP_INFO;    //usbdEpInfo;
> +
> +typedef struct {
> +    VOID        *pBuf;
> +    UINT32    dataLen;
> +} USBD_IO_INFO;
> +
> +typedef struct {
> +    USBD_IO_INFO     ioInfo;
> +    USB_DEV_EP_INFO  epInfo;
> +} USBD_IO_REQ;
> +
> +UINTN
> +EFIAPI
> +usbdInitDCI (
> +  VOID
> +  );
> +
> +BOOLEAN
> +EFIAPI
> +fbInit (
> +  OUT  VOID  *pParams
> +  );
> +
> +BOOLEAN
> +EFIAPI
> +fbDeinit (
> +  VOID
> +  );
> +
> +BOOLEAN
> +EFIAPI
> +fbStart (
> +  VOID
> +  );
> +
> +BOOLEAN
> +EFIAPI
> +fbStop (
> +  VOID
> +  );
> +
> +BOOLEAN
> +EFIAPI
> +usbdSetMmioBar (
> +  UINT32 mmioBar
> +  );
> +
> +BOOLEAN
> +EFIAPI
> +udciDeinit (
> +  VOID    *pUdciHndl,
> +  UINT32  flags
> +  );
> +
> +BOOLEAN
> +EFIAPI
> +udciIsr (
> +  VOID    *pUdciHndl
> +  );
> +
> +BOOLEAN
> +EFIAPI
> +udciConnect (
> +  VOID    *pUdciHndl
> +  );
> +
> +BOOLEAN
> +EFIAPI
> +udciDisconnect (
> +  VOID    *pUdciHndl
> +  );
> +
> +BOOLEAN
> +EFIAPI
> +udciSetAddress (
> +  VOID    *pUdciHndl,
> +  UINT8   address
> +  );
> +
> +BOOLEAN
> +EFIAPI
> +udciInitEp (
> +  VOID            *pUdciHndl,
> +  USB_DEV_EP_INFO *pEpInfo
> +  );
> +
> +BOOLEAN
> +EFIAPI
> +udciEnableEp (
> +  VOID            *pUdciHndl,
> +  USB_DEV_EP_INFO *pEpInfo
> +  );
> +
> +BOOLEAN
> +EFIAPI
> +udciDisableEp (
> +  VOID            *pUdciHndl,
> +  USB_DEV_EP_INFO *pEpInfo
> +  );
> +
> +BOOLEAN
> +EFIAPI
> +udciStallEp (
> +  VOID            *pUdciHndl,
> +  USB_DEV_EP_INFO *pEpInfo
> +  );
> +
> +BOOLEAN
> +EFIAPI
> +udciClearStallEp (
> +  VOID            *pUdciHndl,
> +  USB_DEV_EP_INFO *pEpInfo
> +  );
> +
> +
> +BOOLEAN
> +EFIAPI
> +udciEp0TxStatus (
> +  VOID            *pUdciHndl
> +  );
> +
> +
> +BOOLEAN
> +EFIAPI
> +udciEpTxData (
> +  VOID        *pUdciHndl,
> +  USBD_IO_REQ *pIoReq
> +  );
> +
> +BOOLEAN
> +EFIAPI
> +udciEpRxData (
> +  VOID        *pUdciHndl,
> +  USBD_IO_REQ *pIoReq
> +  );
> +
> +BOOLEAN
> +EFIAPI
> +udciRegisterCallbacks (
> +  VOID            *pUdciHndl
> +  );
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Mcfg.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Mcfg.h
> new file mode 100644
> index 0000000000..2751a27d2d
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Mcfg.h
> @@ -0,0 +1,69 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  Mcfg.h
> +
> +Abstract:
> +
> +  ACPI Memory mapped configuration space base address Description Table
> +  implementation, based on PCI Firmware Specification Revision 3.0 final
> draft,
> +  downloadable at http://www.pcisig.com/home
> +
> +**/
> +
> +#ifndef _MCFG_H_
> +#define _MCFG_H_
> +
> +//
> +// Statements that include other files
> +//
> +#include <IndustryStandard/Acpi20.h>
> +#include "McfgTable.h"
> +#include "Platform.h"
> +
> +//
> +// "MCFG" Static Resource Affinity Table
> +//
> +#define
> EFI_ACPI_3_0_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABL
> E_SIGNATURE 0x4746434D
> +
> +//
> +// MCFG Definitions, see specification for details.
> +//
> +#define EFI_ACPI_OEM_MCFG_REVISION  0x00000001
> +
> +//
> +// Define the number of each table type.
> +// This is where the table layout is modified.
> +//
> +#define
> EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_BASE_ADDRE
> SS_STRUCTURE_COUNT  1
> +
> +//
> +// MCFG Table definition.  The table must be defined in a platform
> +// specific manner.
> +//
> +//
> +// Ensure proper structure formats
> +//
> +#pragma pack(1)
> +
> +typedef struct {
> +
> EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HE
> ADER        Header;
> +
> +#if
> EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_BASE_ADDRE
> SS_STRUCTURE_COUNT > 0
> +
> EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_BASE_ADDRE
> SS_STRUCTURE  Segment[
> +
> EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_BASE_ADDRE
> SS_STRUCTURE_COUNT];
> +#endif
> +
> +} EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE;
> +
> +#pragma pack()
> +
> +#endif // _MCFG_H_
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/McfgTable.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/McfgTable.h
> new file mode 100644
> index 0000000000..dc9dc49e74
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/McfgTable.h
> @@ -0,0 +1,65 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  McfgTable.h
> +
> +Abstract:
> +
> +  ACPI Memory mapped configuration space base address Description Table
> +  definition, based on PCI Firmware Specification Revision 3.0 final draft,
> +  downloadable at http://www.pcisig.com/home
> +
> +**/
> +
> +#ifndef _MCFG_TABLE_H_
> +#define _MCFG_TABLE_H_
> +
> +//
> +// Include files
> +//
> +#include <PiDxe.h>
> +
> +//
> +// Ensure proper structure formats
> +//
> +#pragma pack(1)
> +
> +//
> +// MCFG Revision (defined in spec)
> +//
> +#define
> EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_RE
> VISION  0x01
> +
> +//
> +// MCFG Structure Definitions
> +//
> +//
> +// Memory Mapped Enhanced Configuration Base Address Allocation
> +// Structure Definition
> +//
> +typedef struct {
> +  UINT64  BaseAddress;
> +  UINT16  PciSegmentGroupNumber;
> +  UINT8   StartBusNumber;
> +  UINT8   EndBusNumber;
> +  UINT32  Reserved;
> +}
> EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_BASE_ADDRE
> SS_STRUCTURE;
> +
> +//
> +// MCFG Table header definition.  The rest of the table
> +// must be defined in a platform specific manner.
> +//
> +typedef struct {
> +  EFI_ACPI_DESCRIPTION_HEADER Header;
> +  UINT64                      Reserved;
> +}
> EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HE
> ADER;
> +
> +#pragma pack()
> +
> +#endif // _MCFG_TABLE_H
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Platform.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Platform.h
> new file mode 100644
> index 0000000000..4d1932febd
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Platform.h
> @@ -0,0 +1,133 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  Platform.h
> +
> +Abstract:
> +
> +  Pinetrail platform specific information.
> +
> +**/
> +
> +#ifndef _PLATFORM_H
> +#define _PLATFORM_H
> +
> +#include "ChipsetAccess.h"
> +#include "PlatformBaseAddresses.h"
> +
> +
> +//
> +// Number of P & T states supported.
> +//
> +#define NPTM_P_STATES_SUPPORTED         16
> +#define NPTM_T_STATES_SUPPORTED         8
> +
> +//
> +// I/O APIC IDs, the code uses math to generate the numbers
> +// instead of using these defines.
> +//
> +#define ICH_IOAPIC                     (1 << 0)
> +#define ICH_IOAPIC_ID                   0x08
> +
> +//
> +// Possible SMBus addresses that will be present.
> +//
> +#define SMBUS_ADDR_CH_A_1     0xA0
> +#define SMBUS_ADDR_CH_A_2     0xA2
> +#define SMBUS_ADDR_CH_B_1     0xA4
> +#define SMBUS_ADDR_CH_B_2     0xA6
> +#define SMBUS_ADDR_CH_C_1     0xA8
> +#define SMBUS_ADDR_CH_C_2     0xAA
> +#define SMBUS_ADDR_CH_D_1     0xAC
> +#define SMBUS_ADDR_CH_D_2     0xAE
> +#define SMBUS_ADDR_HOST_CLK_BUFFER  0xDC
> +#define SMBUS_ADDR_ICH_SLAVE        0x44
> +#define SMBUS_ADDR_HECETA     0x5C
> +#define SMBUS_ADDR_SMBARP     0xC2
> +#define SMBUS_ADDR_82573E     0xC6
> +#define SMBUS_ADDR_CLKCHIP    0xD2
> +#define SMBUS_ADDR_BRD_REV          0x4E
> +#define SMBUS_ADDR_DB803            0x82
> +
> +//
> +// SMBus addresses that used on this platform.
> +//
> +#define PLATFORM_SMBUS_RSVD_ADDRESSES { \
> +  SMBUS_ADDR_CH_A_1, \
> +  SMBUS_ADDR_CH_A_2, \
> +  SMBUS_ADDR_HOST_CLK_BUFFER, \
> +  SMBUS_ADDR_ICH_SLAVE, \
> +  SMBUS_ADDR_SMBARP, \
> +  SMBUS_ADDR_CLKCHIP, \
> +  SMBUS_ADDR_BRD_REV, \
> +  SMBUS_ADDR_DB803 \
> +  }
> +
> +//
> +// Count of addresses present in PLATFORM_SMBUS_RSVD_ADDRESSES.
> +//
> +#define PLATFORM_NUM_SMBUS_RSVD_ADDRESSES 8
> +
> +//
> +// CMOS usage
> +//
> +#define CMOS_CPU_BSP_SELECT         0x10
> +#define CMOS_CPU_UP_MODE            0x11
> +#define CMOS_CPU_RATIO_OFFSET       0x12
> +#define CMOS_CPU_CORE_HT_OFFSET     0x13
> +#define CMOS_EFI_DEBUG              0x14
> +#define CMOS_CPU_BIST_OFFSET        0x15
> +#define CMOS_CPU_VMX_OFFSET         0x16
> +#define CMOS_ICH_PORT80_OFFSET      0x17
> +#define CMOS_PLATFORM_DESIGNATOR    0x18      // Second bank CMOS
> location of Platform ID.
> +#define CMOS_VALIDATION_TEST_BYTE   0x19      // BIT0 - Validation
> mailbox for UPonDP.
> +#define CMOS_SERIAL_BAUD_RATE       0x1A      // 0=115200; 1=57600;
> 2=38400; 3=19200; 4=9600
> +#define CMOS_DCU_MODE_OFFSET        0x1B
> +#define CMOS_VR11_SET_OFFSET        0x1C
> +#define CMOS_SBSP_TO_AP_COMM        0x20      // SEC code use ONLY!!!
> +#define CMOS_RESET_TYPE_BY_OS       0x52
> +#define TCG_CMOS_MOR_AREA_OFFSET    0x65      // Also Change in
> Universal\Security\Tpm\PhysicalPresence\Dxe\PhysicalPresence.c &
> +#define CMOS_S4_WAKEUP_FLAG_ADDRESS 0x6E
> +#define ACPI_TPM_REQUEST            0x75
> +#define ACPI_TPM_LAST_REQUEST       0x76
> +#define CMOS_BOOT_FLAG_ADDRESS      0x7E
> +
> +//
> +// GPIO Index Data Structure.
> +//
> +typedef struct {
> +  UINT8   Register;
> +  UINT32  Value;
> +} ICH_GPIO_DEV;
> +
> +//
> +// CPU Equates
> +//
> +#define MAX_THREAD                      2
> +#define MAX_CORE                        1
> +#define MAX_DIE                         2
> +#define MAX_CPU_SOCKET                  1
> +#define MAX_CPU_NUM                     (MAX_THREAD * MAX_CORE *
> MAX_DIE * MAX_CPU_SOCKET)
> +
> +#define MEM64_LEN                       0x00100000000
> +#define RES_MEM64_36_BASE               0x01000000000 - MEM64_LEN   //
> 2^36
> +#define RES_MEM64_36_LIMIT              0x01000000000 - 1           // 2^36
> +#define RES_MEM64_39_BASE               0x08000000000 - MEM64_LEN   //
> 2^39
> +#define RES_MEM64_39_LIMIT              0x08000000000 - 1           // 2^39
> +#define RES_MEM64_40_BASE               0x10000000000 - MEM64_LEN   //
> 2^40
> +#define RES_MEM64_40_LIMIT              0x10000000000 - 1           // 2^40
> +
> +#define PLATFORM_MAX_BUS_NUM             0x3f
> +#define V_DEFAULT_SUBSYSTEM_DEVICE_ID    0x574d
> +#define V_DEFAULT_SUBSYSTEM_DEVICE_ID_KT 0x544b
> +#define V_DEFAULT_SUBSYSTEM_VENDOR_ID    0x8086
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformBootMode.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformBootMode.h
> new file mode 100644
> index 0000000000..812077ce14
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformBootMode.h
> @@ -0,0 +1,35 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +    PlatformBootMode.h
> +
> +Abstract:
> +
> +    EFI Platform Boot Mode
> +
> +Revision History
> +
> +--*/
> +
> +#ifndef _EFI_PLATFORM_BOOT_MODE_H_
> +#define _EFI_PLATFORM_BOOT_MODE_H_
> +
> +//
> +// Global ID for the Platform Boot Mode Protocol.
> +//
> +#define   MANUFACTURE_SETUP_NAME             L"MfgDefault"
> +#define   SAFE_SETUP_NAME                    L"SetupDefault"
> +#define   OEM_DEFAULTS_SETUP_NAME            L"OemDefault"
> +#define   CUSTOM_DEFAULTS_SETUP_NAME         L"CustomDefault"
> +
> +#endif
> +
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformDefinitions.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformDefinitions.h
> new file mode 100644
> index 0000000000..a64cda0799
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformDefinitions.h
> @@ -0,0 +1,43 @@
> +/*++
> +
> +Copyright (c) 1999  - 2014, Intel Corporation. All rights reserved
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  PlatformDefinitions.h
> +
> +Abstract:
> +
> +  This header file provides platform specific definitions used by other
> modules
> +  for platform specific initialization.
> +
> +  THIS FILE SHOULD ONLY CONTAIN #defines BECAUSE IT IS CONSUMED BY
> NON-C MODULES
> +  (ASL and VFR)
> +
> +  This file should not contain addition or other operations that an ASL
> compiler or
> +  VFR compiler does not understand.
> +
> +--*/
> +
> +#ifndef _PLATFORM_DEFINITIONS_H_
> +#define _PLATFORM_DEFINITIONS_H_
> +
> +
> +//
> +// Platform Base Address definitions
> +//
> +#define PCIEX_BASE_ADDRESS          EDKII_GLUE_PciExpressBaseAddress //
> Pci Express Configuration Space Base Address
> +
> +#define PCIEX_LENGTH                PLATFORM_PCIEXPRESS_LENGTH
> +
> +#define THERMAL_BASE_ADDRESS        0xFED08000
> +
> +#ifndef MCH_BASE_ADDRESS
> +#define MCH_BASE_ADDRESS            0xFED10000  // MCH  Register Base
> Address
> +#endif
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/MfgMemoryTest.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/MfgMemoryTest.h
> new file mode 100644
> index 0000000000..353c80b629
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/MfgMemoryTest.h
> @@ -0,0 +1,42 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  BaseMemoryTest.h
> +
> +Abstract:
> +
> +  Pei memory test PPI as defined in Tiano
> +
> +  Used to Pei memory test in PEI
> +
> +--*/
> +
> +#ifndef _BASE_MEMORY_TEST_H_
> +#define _BASE_MEMORY_TEST_H_
> +
> +typedef struct _PEI_MFG_MEMORY_TEST_PPI
> PEI_MFG_MEMORY_TEST_PPI;
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_MFG_MEMORY_TEST) (
> +  IN  CONST EFI_PEI_SERVICES                   **PeiServices,
> +  IN  PEI_MFG_MEMORY_TEST_PPI            * This,
> +  IN  UINT32                             BeginAddress,
> +  IN  UINT32                             MemoryLength
> +  );
> +
> +typedef struct _PEI_MFG_MEMORY_TEST_PPI {
> +  PEI_MFG_MEMORY_TEST  MfgMemoryTest;
> +}PEI_MFG_MEMORY_TEST_PPI;
> +
> +
> +extern EFI_GUID gPeiMfgMemoryTestPpiGuid;
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Sha256Hash.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Sha256Hash.h
> new file mode 100644
> index 0000000000..1c9b2b9ea1
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Sha256Hash.h
> @@ -0,0 +1,131 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  Speaker.h
> +
> +Abstract:
> +
> +  EFI Speaker Interface Protocol
> +
> +
> +
> +--*/
> +
> +#ifndef _PEI_SHA256_HASH_H
> +#define _PEI_SHA256_HASH_H
> +
> +//
> +// Global ID Speaker Interface
> +//
> +#define PEI_SHA256_HASH_PPI_GUID \
> +  { \
> +    0x950e191b, 0x8524, 0x4f51,  0x80, 0xa1, 0x5c, 0x4f, 0x1b, 0x3, 0xf3, 0x5c
> \
> +  }
> +
> +typedef struct _PEI_SHA256_HASH_PPI PEI_SHA256_HASH_PPI;
> +
> +/**
> +  @return  The size, in bytes, of the context buffer required for hash
> operations.
> +
> +**/
> +typedef
> +UINTN
> +(EFIAPI *HASH_GET_CONTEXT_SIZE)(
> +  VOID
> +  );
> +
> +/**
> +  Initializes user-supplied memory pointed by HashContext as hash context
> for
> +  subsequent use.
> +
> +  If HashContext is NULL, then ASSERT().
> +
> +  @param[in, out]  HashContext  Pointer to  Context being initialized.
> +
> +  @retval TRUE   HASH context initialization succeeded.
> +  @retval FALSE  HASH context initialization failed.
> +
> +**/
> +typedef
> +BOOLEAN
> +(EFIAPI *HASH_INIT)(
> +  IN OUT  VOID  *HashContext
> +  );
> +
> +/**
> +  Performs digest on a data buffer of the specified length. This function can
> +  be called multiple times to compute the digest of long or discontinuous
> data streams.
> +
> +  If HashContext is NULL, then ASSERT().
> +
> +  @param[in, out]  HashContext  Pointer to the MD5 context.
> +  @param[in]       Data         Pointer to the buffer containing the data to be
> hashed.
> +  @param[in]       DataLength   Length of Data buffer in bytes.
> +
> +  @retval TRUE     HASH data digest succeeded.
> +  @retval FALSE    Invalid HASH context. After HashFinal function has been
> called, the
> +                   HASH context cannot be reused.
> +
> +**/
> +typedef
> +BOOLEAN
> +(EFIAPI *HASH_UPDATE)(
> +  IN OUT  VOID        *HashContext,
> +  IN      CONST VOID  *Data,
> +  IN      UINTN       DataLength
> +  );
> +
> +/**
> +  Completes hash computation and retrieves the digest value into the
> specified
> +  memory. After this function has been called, the context cannot be used
> again.
> +
> +  If HashContext is NULL, then ASSERT().
> +  If HashValue is NULL, then ASSERT().
> +
> +  @param[in, out]  HashContext  Pointer to the MD5 context
> +  @param[out]      HashValue    Pointer to a buffer that receives the HASH
> digest
> +                                value.
> +
> +  @retval TRUE   HASH digest computation succeeded.
> +  @retval FALSE  HASH digest computation failed.
> +
> +**/
> +typedef
> +BOOLEAN
> +(EFIAPI *HASH_FINAL)(
> +  IN OUT  VOID   *HashContext,
> +  OUT     UINT8  *HashValue
> +  );
> +
> +//
> +// Ppi definition
> +//
> +typedef struct _PEI_SHA256_HASH_PPI {
> +  //
> +  // Pointer to Hash GetContentSize function
> +  //
> +  HASH_GET_CONTEXT_SIZE    GetContextSize;
> +  //
> +  // Pointer to Hash Init function
> +  //
> +  HASH_INIT                HashInit;
> +  //
> +  // Pointer to Hash Update function
> +  //
> +  HASH_UPDATE              HashUpdate;
> +  //
> +  // Pointer to Hash Final function
> +  //
> +  HASH_FINAL               HashFinal;
> +
> +} PEI_SHA256_HASH_PPI;
> +
> +extern EFI_GUID gPeiSha256HashPpiGuid;
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Speaker.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Speaker.h
> new file mode 100644
> index 0000000000..b8c817e4ca
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Speaker.h
> @@ -0,0 +1,65 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  Speaker.h
> +
> +Abstract:
> +
> +  EFI Speaker Interface Protocol
> +
> +
> +
> +--*/
> +
> +#ifndef _PEI_SPEAKER_IF_H
> +#define _PEI_SPEAKER_IF_H
> +
> +//
> +// Global ID Speaker Interface
> +//
> +#define PEI_SPEAKER_INTERFACE_PPI_GUID \
> +  { \
> +    0x30ac275e, 0xbb30, 0x4b84, 0xa1, 0xcd, 0x0a, 0xf1, 0x32, 0x2c, 0x89, 0xc0
> \
> +  }
> +
> +typedef struct _PEI_SPEAKER_IF_PPI PEI_SPEAKER_IF_PPI;
> +
> +//
> +// Beep Code
> +//
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPEAKER_GENERATE_BEEP) (
> +  IN CONST EFI_PEI_SERVICES           **PeiServices,
> +  IN UINTN                            NumberOfBeep,
> +  IN UINTN                            BeepDuration,
> +  IN UINTN                            TimeInterval
> +  );
> +
> +//
> +// Set Frequency
> +//
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPEAKER_SET_FREQUENCY) (
> +  IN CONST EFI_PEI_SERVICES           **PeiServices,
> +  IN UINT16                           Frequency
> +  );
> +
> +//
> +// Protocol definition
> +//
> +typedef struct _PEI_SPEAKER_IF_PPI {
> +  EFI_SPEAKER_SET_FREQUENCY SetSpeakerToneFrequency;
> +  EFI_SPEAKER_GENERATE_BEEP GenerateBeep;
> +} PEI_SPEAKER_IF_PPI;
> +
> +extern EFI_GUID gPeiSpeakerInterfacePpiGuid;
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/UsbController.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/UsbController.h
> new file mode 100644
> index 0000000000..5448566116
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/UsbController.h
> @@ -0,0 +1,85 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +  Define APIs to retrieve USB Host Controller Info such as controller type and
> +  I/O Port Base Address.
> +
> +
> +**/
> +
> +#ifndef _PEI_USB_CONTROLLER_PPI_H_
> +#define _PEI_USB_CONTROLLER_PPI_H_
> +
> +//
> +// Global ID for the PEI_USB_CONTROLLER_PPI.
> +//
> +#define PEI_USB_CONTROLLER_PPI_GUID \
> +  { \
> +    0x3bc1f6de, 0x693e, 0x4547,{ 0xa3, 0x0, 0x21, 0x82, 0x3c, 0xa4, 0x20, 0xb2}
> \
> +  }
> +
> +//
> +// Forward declaration for the PEI_USB_CONTROLLER_PPI.
> +//
> +typedef struct _PEI_USB_CONTROLLER_PPI PEI_USB_CONTROLLER_PPI;
> +
> +//
> +// This bit is used in the ControllerType return parameter of
> GetUsbController()
> +// to identify the USB Host Controller type as UHCI
> +//
> +#define PEI_UHCI_CONTROLLER 0x01
> +
> +//
> +// This bit is used in the ControllerType return parameter of
> GetUsbController()
> +// to identify the USB Host Controller type as OHCI
> +//
> +#define PEI_OHCI_CONTROLLER 0x02
> +
> +//
> +// This bit is used in the ControllerType return parameter of
> GetUsbController()
> +// to identify the USB Host Controller type as EHCI
> +//
> +#define PEI_EHCI_CONTROLLER 0x03
> +
> +/**
> +  Retrieve USB Host Controller Info such as controller type and I/O Base
> Address.
> +
> +  @param[in]  PeiServices      The pointer to the PEI Services Table.
> +  @param[in]  This             The pointer to this instance of the
> PEI_USB_CONTROLLER_PPI.
> +  @param[in]  ControllerId     The ID of the USB controller.
> +  @param[out] ControllerType   On output, returns the type of the USB
> controller.
> +  @param[out] BaseAddress      On output, returns the base address of
> UHCI's I/O ports
> +                               if UHCI is enabled or the base address of EHCI's MMIO
> +                               if EHCI is enabled.
> +
> +  @retval EFI_SUCCESS             USB controller attributes were returned
> successfully.
> +  @retval EFI_INVALID_PARAMETER   ControllerId is greater than the
> maximum number
> +                                  of USB controller supported by this platform.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_GET_USB_CONTROLLER)(
> +  IN  EFI_PEI_SERVICES        **PeiServices,
> +  IN  PEI_USB_CONTROLLER_PPI  *This,
> +  IN  UINT8                   UsbControllerId,
> +  OUT UINTN                   *ControllerType,
> +  OUT UINTN                   *BaseAddress
> +  );
> +
> +//
> +// This PPI contains a single service to retrieve the USB Host Controller type
> +// and the base address of the I/O ports used to access the USB Host
> Controller.
> +//
> +struct _PEI_USB_CONTROLLER_PPI {
> +  PEI_GET_USB_CONTROLLER  GetUsbController;
> +};
> +
> +extern EFI_GUID gPeiUsbControllerPpiGuid;
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/CK505ClockPlatformIn
> fo.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/CK505ClockPlatformIn
> fo.h
> new file mode 100644
> index 0000000000..daf5d22d71
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/CK505ClockPlatformIn
> fo.h
> @@ -0,0 +1,126 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  CK505ClockPlatformInfo.h
> +
> +Abstract:
> +
> +  Protocol to communicate product clock routing information.
> +
> +GUID Info:
> + {3C485EA4-449A-46ce-BB08-2A336EA96B4E}
> + 0x3c485ea4, 0x449a, 0x46ce, 0xbb, 0x8, 0x2a, 0x33, 0x6e, 0xa9, 0x6b, 0x4e);
> +
> +**/
> +
> +#ifndef _CLOCK_PLATFORM_INFO_H_
> +#define _CLOCK_PLATFORM_INFO_H_
> +
> +
> +#define EFI_CK505_CLOCK_PLATFORM_INFO_GUID  \
> +  {0x3c485ea4, 0x449a, 0x46ce, 0xbb, 0x8, 0x2a, 0x33, 0x6e, 0xa9, 0x6b, 0x4e}
> +
> +//
> +// Structure to hold register modifications
> +//
> +typedef enum {
> +  None           = 0x00000000,
> +  nICS9LP505_1   = 0x00000001,
> +  nICS9LP505_2   = 0x00000002,
> +  nIDTCV163      = 0x00000004,
> +  nIDTCV174      = 0x00000008,
> +  nSLG505YC56    = 0x00000010,
> +  nSLG505YC64    = 0x00000020,
> +  nCY28505       = 0x00000040,
> +  nCY28505_2     = 0x00000080,
> +  nCY28505LF     = 0x00000100,
> +  nPI6C505_OLD   = 0x00000200,
> +  nPI6C505_RevD  = 0x00000400,
> +  nGENERIC_505   = 0x00000800,
> +  nSLG505YC264   = 0x00001000,
> +  nIDTCV183      = 0x00002000,
> +  nSLG505YC256   = 0x00004000,
> +  nIDTCV184      = 0x00008000,
> +  nIDTCV190      = 0x00010000,
> +  All            = 0xFFFFFFFF
> +} EFI_CLOCKS_SUPPORTED;
> +
> +typedef enum {
> +  Disabled,
> +  Enabled,
> +  EnabledWithoutSwitch,
> +  EnabledWithSwitch
> +} EFI_SIGNAL_STATE;
> +
> +typedef enum {
> +  SrcClk11,
> +  SrcClk10,
> +  SrcClk9,
> +  SrcClk8,
> +  SrcClk7,
> +  SrcClk6,
> +  SrcClk5,
> +  SrcClk4,
> +  SrcClk3,
> +  SrcClk2,
> +  SrcClk1,
> +  SrcClk0,
> +  CpuClk1,
> +  CpuClk0,
> +  Ref0,
> +  Dot96,
> +  Usb48,
> +  PciClkF5,
> +  PciClk4,
> +  PciClk3,
> +  PciClk2,
> +  PciClk1,
> +  PciClk0,
> +  SaveClockConfiguration,
> +  MePresent,
> +  Cr_A,
> +  Cr_B,
> +  Cr_C,
> +  Cr_D,
> +  Cr_E,
> +  Cr_F,
> +  Cr_G,
> +  Cr_H,
> +  Clk_None // Dummy entry for dynamic detection
> +} EFI_CLOCK_SIGNAL_NAME;
> +
> +typedef struct {
> +  EFI_CLOCK_SIGNAL_NAME     Signal;
> +  EFI_SIGNAL_STATE          State;
> +  EFI_CLOCKS_SUPPORTED      Supported;
> +} EFI_STATIC_SIGNALS;
> +
> +typedef struct {
> +  BOOLEAN               BehindBridge;
> +  UINT16                BridgeBus;
> +  UINT16                BridgeDev;
> +  UINT16                BridgeFunction;
> +  UINT16                TargetDevice;
> +  EFI_CLOCK_SIGNAL_NAME Signal;
> +} EFI_DYNAMIC_SIGNALS;
> +
> +
> +typedef struct {
> +  EFI_STATIC_SIGNALS      *StaticClockTable;
> +  UINTN                   StaticClockTableCount;
> +  EFI_STATIC_SIGNALS      *SxClockTable;
> +  UINTN                   SxClockTableCount;
> +  EFI_STATIC_SIGNALS	  *DynamicDisabledClocksTable;
> +  UINTN			  DynamicDisabledClocksTableCount;
> +} EFI_CLOCK_PLATFORM_INFO;
> +
> +extern EFI_GUID gEfiCk505ClockPlatformInfoGuid;
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/EnhancedSpeedstep.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/EnhancedSpeedstep.
> h
> new file mode 100644
> index 0000000000..9b74180845
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/EnhancedSpeedstep.
> h
> @@ -0,0 +1,76 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +
> +Module Name:
> +
> +  EnhancedSpeedstep.h
> +
> +Abstract:
> +
> +  Enhanced Speedstep protocol
> +
> +  The Enhanced Speedstep Protocol support.
> +
> +**/
> +
> +#ifndef _ENHANCED_SPEEDSTEP_H_
> +#define _ENHANCED_SPEEDSTEP_H_
> +
> +#define ENHANCED_SPEEDSTEP_PROTOCOL_GUID \
> +  { \
> +    0x91a1ddcf, 0x5374, 0x4939, 0x89, 0x51, 0xd7, 0x29, 0x3f, 0x1a, 0x78, 0x6f
> \
> +  }
> +
> +typedef struct _ENHANCED_SPEEDSTEP_PROTOCOL
> ENHANCED_SPEEDSTEP_PROTOCOL;
> +
> +typedef struct {
> +  UINT8   Version;      // EIST State format
> +  UINT8   Size;         // Size of element
> +  UINT32  RatioStep;    // Step
> +  UINT32  MinRatio;     // Calculated min ratio
> +  UINT32  MaxRatio;     // Calculated max ratio
> +  UINT32  MinCoreFreq;  // Calculated min freq
> +  UINT32  MaxCoreFreq;  // Calculated max freq
> +  UINT32  MinPower;     // Calculated min power
> +  UINT32  MaxPower;     // Calculated max power
> +  UINT32  NumStates;    // Number of states
> +} EIST_INFORMATION;
> +
> +typedef struct {
> +  UINT32  CoreFrequency;
> +  UINT32  Power;
> +  UINT32  TransitionLatency;
> +  UINT32  BusMasterLatency;
> +  UINT32  Control;
> +  UINT32  Status;
> +} EFI_ACPI_CPU_PSS_STATE;
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *GET_EIST_TABLE) (
> +  IN    ENHANCED_SPEEDSTEP_PROTOCOL    *This,
> +  OUT   EIST_INFORMATION               **EistInformation,
> +  OUT   VOID                           **PssStates
> +  );
> +
> +struct _ENHANCED_SPEEDSTEP_PROTOCOL {
> +  UINT32              ProcApicId;
> +  GET_EIST_TABLE      GetEistTable;
> +};
> +
> +//
> +// There will be an instance of this protocol for every processor
> +// in the system.  ProcNumber is used to manage all the different
> +// processors in the system and passed into the MP protocol
> +// to run code streams on application processors
> +//
> +extern EFI_GUID gEnhancedSpeedstepProtocolGuid;
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/GlobalNvsArea.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/GlobalNvsArea.h
> new file mode 100644
> index 0000000000..e2683b2e5b
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/GlobalNvsArea.h
> @@ -0,0 +1,475 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
> +
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +
> +
> +Module Name:
> +
> +  GlobalNvsArea.h
> +
> +Abstract:
> +
> +  Definition of the global NVS area protocol.  This protocol
> +  publishes the address and format of a global ACPI NVS buffer used as a
> communications
> +  buffer between SMM code and ASL code.
> +  The format is derived from the ACPI reference code, version 0.95.
> +
> +  Note:  Data structures defined in this protocol are not naturally aligned.
> +
> +**/
> +
> +
> +#ifndef _GLOBAL_NVS_AREA_H_
> +#define _GLOBAL_NVS_AREA_H_
> +
> +//
> +// Includes
> +//
> +#define GLOBAL_NVS_DEVICE_ENABLE 1
> +#define GLOBAL_NVS_DEVICE_DISABLE 0
> +
> +//
> +// Forward reference for pure ANSI compatibility
> +//
> +
> +//EFI_FORWARD_DECLARATION (EFI_GLOBAL_NVS_AREA_PROTOCOL);
> +
> +//
> +// Global NVS Area Protocol GUID
> +//
> +#define EFI_GLOBAL_NVS_AREA_PROTOCOL_GUID \
> +{ 0x74e1e48, 0x8132, 0x47a1, 0x8c, 0x2c, 0x3f, 0x14, 0xad, 0x9a, 0x66, 0xdc }
> +
> +//
> +// Revision id - Added TPM related fields
> +//
> +#define GLOBAL_NVS_AREA_RIVISION_1       1
> +
> +//
> +// Extern the GUID for protocol users.
> +//
> +extern EFI_GUID gEfiGlobalNvsAreaProtocolGuid;
> +
> +//
> +// Global NVS Area definition
> +//
> +#pragma pack (1)
> +typedef struct {
> +  //
> +  // Miscellaneous Dynamic Values, the definitions below need to be
> matched
> +  // GNVS definitions in Platform.ASL
> +  //
> +  UINT16      OperatingSystem;    // 00
> +  UINT8       SmiFunction;        // 02   SMI function call via IO Trap
> +  UINT8       SmiParameter0;      // 03
> +  UINT8       SmiParameter1;      // 04
> +  UINT8       SciFunction;        // 05   SCI function call via _L00
> +  UINT8       SciParameter0;      // 06
> +  UINT8       SciParameter1;      // 07
> +  UINT8       GlobalLock;         // 08   Global lock function call
> +  UINT8       LockParameter0;     // 09
> +  UINT8       LockParameter1;     // 10
> +  UINT32      Port80DebugValue;   // 11
> +  UINT8       LidState;           // 15   Open = 1
> +  UINT8       PowerState;         // 16   AC = 1
> +  UINT8       DebugState;         // 17
> +
> +
> +  //
> +  // Thermal Policy Values
> +  //
> +  UINT8       EnableThermalOffset;                        // 18 ThermalOffset for KSC
> +  UINT8       Reserved1;                           // 19
> +  UINT8       Reserved2;                           // 20
> +  UINT8       PassiveThermalTripPoint;                    // 21
> +  UINT8       PassiveTc1Value;                            // 22
> +  UINT8       PassiveTc2Value;                            // 23
> +  UINT8       PassiveTspValue;                            // 24
> +  UINT8       CriticalThermalTripPoint;                   // 25
> +  UINT8       EnableDigitalThermalSensor;                 // 26
> +  UINT8       BspDigitalThermalSensorTemperature;         // 27   Temperature
> of BSP
> +  UINT8       ApDigitalThermalSensorTemperature;          // 28   Temperature of
> AP
> +  UINT8       DigitalThermalSensorSmiFunction;            // 29   SMI function call
> via DTS IO Trap
> +
> +  //
> +  // Battery Support Values
> +  //
> +  UINT8       NumberOfBatteries;      // 30
> +  UINT8       BatteryCapacity0;       // 31   Battery 0 Stored Capacity
> +  UINT8       BatteryCapacity1;       // 32   Battery 1 Stored Capacity
> +  UINT8       BatteryCapacity2;       // 33   Battery 2 Stored Capacity
> +  UINT8       BatteryStatus0;         // 34   Battery 0 Stored Status
> +  UINT8       BatteryStatus1;         // 35   Battery 1 Stored Status
> +  UINT8       BatteryStatus2;         // 36   Battery 2 Stored Status
> +
> +  // NOTE: Do NOT Change the Offset of Revision Field
> +  UINT8       Revision;               // 37   Revision of the structure
> EFI_GLOBAL_NVS_AREA
> +  UINT8       Reserved3[2];           // 38:39
> +
> +  //
> +  // Processor Configuration Values
> +  //
> +  UINT8       ApicEnable;             // 40   APIC Enabled by SBIOS (APIC Enabled = 1)
> +  UINT8       LogicalProcessorCount;  // 41   Processor Count Enabled (MP
> Enabled != 0)
> +  UINT8       CurentPdcState0;        // 42   PDC settings, Processor 0
> +  UINT8       CurentPdcState1;        // 43   PDC settings, Processor 1
> +  UINT8       MaximumPpcState;        // 44   Maximum PPC state
> +  UINT32      PpmFlags;               // 45:48 PPM configuration flags, same as
> CFGD
> +  UINT8       Reserved4[1];           // 49
> +
> +  //
> +  // SIO Configuration Values
> +  //
> +  UINT8       DockedSioPresent;       // 50   Dock SIO Present
> +  UINT8       DockComA;               // 51     COM A Port
> +  UINT8       DockComB;               // 52     COM B Port
> +  UINT8       LptP;                   // 53     LPT Port
> +  UINT8       DockFdc;                // 54     FDC Port
> +  UINT8       OnboardCom;             // 55   Onboard COM Port
> +  UINT8       OnboardComCir;          // 56   Onboard COM CIR Port
> +
> +  UINT8       WPCN381U;               // 57
> +  UINT8       NPCE791x;               // 58
> +  UINT8       Reserved5[1];           // 59
> +
> +  //
> +  // Internal Graphics Device Values
> +  //
> +  UINT8       IgdState;               // 60   IGD State (Primary Display = 1)
> +  UINT8       DisplayToggleList;      // 61   Display Toggle List Selection
> +  UINT8       CurrentDeviceList;      // 62   Current Attached Device List
> +  UINT8       PreviousDeviceList;     // 63   Previous Attached Device List
> +  UINT16      CurrentDisplayState;    // 64   Current Display State
> +  UINT16      NextDisplayState;       // 66   Next Display State
> +  UINT16      SetDisplayState;        // 68   Set Display State
> +  UINT8       NumberOfValidDeviceId;  // 70   Number of Valid Device IDs
> +  UINT32      DeviceId1;              // 71   Device ID 1
> +  UINT32      DeviceId2;              // 75   Device ID 2
> +  UINT32      DeviceId3;              // 79   Device ID 3
> +  UINT32      DeviceId4;              // 83   Device ID 4
> +  UINT32      DeviceId5;              // 87   Device ID 5
> +
> +  UINT32      AKsv0;                  // 91:94 First four bytes of AKSV (manufacturing
> mode)
> +  UINT8       AKsv1;                  // 95    Fifth byte of AKSV (manufacturing mode
> +
> +  UINT8       Reserved6[7];           // 96:102
> +
> +  //
> +  // Backlight Control Values
> +  //
> +  UINT8       BacklightControlSupport;  // 103  Backlight Control Support
> +  UINT8       BrightnessPercentage;     // 104  Brightness Level Percentage
> +
> +  //
> +  // Ambient Light Sensor Values
> +  //
> +  UINT8       AlsEnable;              // 105  Ambient Light Sensor Enable
> +  UINT8       AlsAdjustmentFactor;    // 106  Ambient Light Adjusment Factor
> +  UINT8       LuxLowValue;            // 107  LUX Low Value
> +  UINT8       LuxHighValue;           // 108  LUX High Value
> +
> +  UINT8       Reserved7[1];           // 109
> +
> +  //
> +  // Extended Mobile Access Values
> +  //
> +  UINT8       EmaEnable;              // 110  EMA Enable
> +  UINT16      EmaPointer;             // 111  EMA Pointer
> +  UINT16      EmaLength;              // 113  EMA Length
> +
> +  UINT8       Reserved8[1];           // 115
> +
> +  //
> +  // Mobile East Fork Values
> +  //
> +  UINT8       MefEnable;              // 116 Mobile East Fork Enable
> +
> +  //
> +  // PCIe Dock Status
> +  //
> +  UINT8       PcieDockStatus;         // 117 PCIe Dock Status
> +
> +  UINT8       Reserved9[2];           // 118:119
> +
> +  //
> +  // TPM Registers
> +  //
> +  UINT8       TpmPresent;             // 120 TPM Present
> +  UINT8       TpmEnable;              // 121 TPM Enable
> +
> +  UINT8       MorData;                // 122 Memory Overwrite Request Data
> +  UINT8       TcgParamter;            // 123 Used for save the Mor and/or physical
> presence parameter
> +  UINT32      PPResponse;             // 124 Physical Presence request operation
> response
> +  UINT8       PPRequest;              // 128 Physical Presence request operation
> +  UINT8       LastPPRequest;          // 129 Last Physical Presence request
> operation
> +
> +  //
> +  // SATA Values
> +  //
> +  UINT8       GtfTaskFileBufferPort0[7];    // 130  GTF Task File Buffer for Port 0
> +  UINT8       GtfTaskFileBufferPort2[7];    // 137  GTF Task File Buffer for Port 2
> +  UINT8       IdeMode;                      // 144  IDE Mode (Compatible\Enhanced)
> +  UINT8       GtfTaskFileBufferPort1[7];    // 145:151 GTF Task File Buffer for
> Port 1
> +
> +  UINT8       Reserved111[10];                // 152:161
> +  UINT64      BootTimeLogAddress;           // 162:169 Boot Time Log Table
> Address
> +
> +  UINT32      IgdOpRegionAddress;           // 170  IGD OpRegion Starting
> Address
> +  UINT8       IgdBootType;                  // 174  IGD Boot Type CMOS option
> +  UINT8       IgdPanelType;                 // 175  IGD Panel Type CMOs option
> +  UINT8       IgdTvFormat;                  // 176  IGD TV Format CMOS option
> +  UINT8       IgdTvMinor;                   // 177  IGD TV Minor Format CMOS option
> +  UINT8       IgdPanelScaling;              // 178  IGD Panel Scaling
> +  UINT8       IgdBlcConfig;                 // 179  IGD BLC Configuration
> +  UINT8       IgdBiaConfig;                 // 180  IGD BIA Configuration
> +  UINT8       IgdSscConfig;                 // 181  IGD SSC Configuration
> +  UINT8       Igd409;                       // 182  IGD 0409 Modified Settings Flag
> +  UINT8       Igd509;                       // 183  IGD 0509 Modified Settings Flag
> +  UINT8       Igd609;                       // 184  IGD 0609 Modified Settings Flag
> +  UINT8       Igd709;                       // 185  IGD 0709 Modified Settings Flag
> +  UINT8       IgdPowerConservation;         // 186  IGD Power Conservation
> Feature Flag
> +  UINT8       IgdDvmtMemSize;               // 187  IGD DVMT Memory Size
> +  UINT8       IgdFunc1Enable;               // 188  IGD Function 1 Enable
> +  UINT8       IgdHpllVco;                   // 189  HPLL VCO
> +  UINT32      NextStateDid1;                // 190  Next state DID1 for _DGS
> +  UINT32      NextStateDid2;                // 194  Next state DID2 for _DGS
> +  UINT32      NextStateDid3;                // 198  Next state DID3 for _DGS
> +  UINT32      NextStateDid4;                // 202  Next state DID4 for _DGS
> +  UINT32      NextStateDid5;                // 206  Next state DID5 for _DGS
> +  UINT32      NextStateDid6;                // 210  Next state DID6 for _DGS
> +  UINT32      NextStateDid7;                // 214  Next state DID7 for _DGS
> +  UINT32      NextStateDid8;                // 218  Next state DID8 for _DGS
> +  UINT8       IgdSciSmiMode;                // 222  GMCH SMI/SCI mode (0=SCI)
> +  UINT8       IgdPAVP;                      // 223  IGD PAVP data
> +  UINT8       IgdSelfRefresh;               // 224  IGD Self Refresh
> +  UINT8       PcieOSCControl;               // 225  PCIE OSC Control
> +  UINT8       NativePCIESupport;            // 226  Native PCI Express Support
> +
> +  //
> +  // USB Sideband Deferring Support
> +  //
> +  UINT8       HostAlertVector;              // 227  GPE vector used for HOST_ALERT
> +  UINT8       HostAlertPio;                 // 228  PIO of USB device used for
> HOST_ALERT
> +
> +  UINT8       Reserved112[27];               // 229
> +  UINT32      NvIgOpRegionAddress;          // 256 NVIG support
> +  UINT32      NvHmOpRegionAddress;          // 260 NVHM support
> +  UINT32      ApXmOpRegionAddress;          // 264 AMDA support
> +  UINT32      DeviceId6;                    // 268   Device ID 6
> +  UINT32      DeviceId7;                    // 272   Device ID 7
> +  UINT32      DeviceId8;                    // 276   Device ID 8
> +  UINT32      EndpointBaseAddress;          // 280 PEG Endpoint PCIe Base
> Address
> +  UINT32      CapStrPresence;               // 284 PEG Endpoint Capability Structure
> Presence
> +  UINT32      EndpointPcieCapBaseAddress;   // 288 PEG Endpoint PCIe
> Capability Structure Base Address
> +  UINT32      EndpointVcCapBaseAddress;     // 292 PEG Endpoint Virtual
> Channel Capability Structure Base Address
> +  UINT32      XPcieCfgBaseAddress;          // 296 Any Device's PCIe Config
> Space Base Address
> +  UINT32      OccupiedBuses1;               // 300 Occupied Buses from 0 to 31
> +  UINT32      OccupiedBuses2;               // 304 Occupied Buses from 32 to 63
> +  UINT32      OccupiedBuses3;               // 308 Occupied Buses from 64 to 95
> +  UINT32      OccupiedBuses4;               // 312 Occupied Buses from 96 to 127
> +  UINT32      OccupiedBuses5;               // 316 Occupied Buses from 128 to 159
> +  UINT32      OccupiedBuses6;               // 320 Occupied Buses from 160 to 191
> +  UINT32      OccupiedBuses7;               // 324 Occupied Buses from 192 to 223
> +  UINT32      OccupiedBuses8;               // 328 Occupied Buses from 224 to 255
> +  UINT8       UartSelection;                // 332 UART Interface Selection 0: Internal;
> 1: SIO
> +  UINT8       PcuUart1Enable;               // 333 PCU UART 1 Enabled
> +  UINT8       PcuUart2Enable;               // 334 PCU UART 2 Enabled
> +
> +  UINT32      LPEBar0;                      // 335~338  LPE Bar0
> +  UINT32      LPEBar1;                      // 339~342  LPE Bar1
> +
> +  UINT32      LPEBar2;                      // 343~346  LPE Bar2
> +  UINT8        AcSetup;                      // 347 For Ac Powered Config option - IST
> applet
> +  UINT8       BatterySetup;                 // 348 For Battery Powered Config option -
> IST applet
> +  UINT8       PlatformFlavor;               // 349 0:unknown 1: Mobile; 2: desktop
> +  UINT8       Reserved113[1];                // 350
> +
> +  UINT8       IsctReserve;                      // 351 ISCT / AOAC Configuration
> +  UINT8       XhciMode;                     // 352 xHCI mode
> +  UINT8       PmicEnable;                   // 353 PMIC enable
> +
> +  UINT8       LpeEnable;                    // 354 LPE enable
> +  UINT32      ISPAddr;                      // 355 ISP Base address
> +  UINT8       ISPDevSel;                    // 359 ISP device enabled selection 0:
> Disabled; 1: PCI Device 2; 2: PCI Device 3
> +
> +  //
> +  // Lpss controllers
> +  //
> +  UINT32      PCIBottomAddress;            //360  ((4+8+6)*4+2)*4=296
> +  UINT32      PCITopAddress;               //364
> +
> +  UINT32      LDMA1Addr;                   // 368
> +  UINT32      LDMA1Len;                    // 372
> +  UINT32      LDMA11Addr;                  // 376
> +  UINT32      LDMA11Len;                   // 380
> +  UINT32      PWM1Addr;                    // 384 PWM1
> +  UINT32      PWM1Len;                     // 388
> +  UINT32      PWM11Addr;                   // 392
> +  UINT32      PWM11Len;                    // 396
> +  UINT32      PWM2Addr;                    // 400 PWM2
> +  UINT32      PWM2Len;                     // 404
> +  UINT32      PWM21Addr;                   // 408
> +  UINT32      PWM21Len;                    // 412
> +  UINT32      UART1Addr;                   // 416 UART1
> +  UINT32      UART1Len;                    // 420
> +  UINT32      UART11Addr;                  // 424 UART1
> +  UINT32      UART11Len;                   // 428
> +  UINT32      UART2Addr;                   // 432 UART2
> +  UINT32      UART2Len;                    // 436
> +  UINT32      UART21Addr;                  // 440 UART2
> +  UINT32      UART21Len;                   // 444
> +  UINT32      SPIAddr;                     // 448 SPI
> +  UINT32      SPILen;                      // 452
> +  UINT32      SPI1Addr;                    // 456
> +  UINT32      SPI1Len;                     // 460
> +
> +  UINT32      LDMA2Addr;                   // 464
> +  UINT32      LDMA2Len;                    // 468
> +  UINT32      LDMA21Addr;                  // 472
> +  UINT32      LDMA21Len;                   // 476
> +  UINT32      I2C1Addr;                    // 480 I2C1
> +  UINT32      I2C1Len;                     // 484
> +  UINT32      I2C11Addr;                   // 488 I2C1
> +  UINT32      I2C11Len;                    // 492
> +  UINT32      I2C2Addr;                    // 496 I2C2
> +  UINT32      I2C2Len;                     // 500
> +  UINT32      I2C21Addr;                   // 504 I2C2
> +  UINT32      I2C21Len;                    // 508
> +  UINT32      I2C3Addr;                    // 512 I2C3
> +  UINT32      I2C3Len;                     // 516
> +  UINT32      I2C31Addr;                   // 520 I2C3
> +  UINT32      I2C31Len;                    // 524
> +  UINT32      I2C4Addr;                    // 528 I2C4
> +  UINT32      I2C4Len;                     // 532
> +  UINT32      I2C41Addr;                   // 536 I2C4
> +  UINT32      I2C41Len;                    // 540
> +  UINT32      I2C5Addr;                    // 544 I2C5
> +  UINT32      I2C5Len;                     // 548
> +  UINT32      I2C51Addr;                   // 552 I2C5
> +  UINT32      I2C51Len;                    // 556
> +  UINT32      I2C6Addr;                    // 560 I2C6
> +  UINT32      I2C6Len;                     // 564
> +  UINT32      I2C61Addr;                   // 566 I2C6
> +  UINT32      I2C61Len;                    // 570
> +  UINT32      I2C7Addr;                    // 574 I2C7
> +  UINT32      I2C7Len;                     // 578
> +  UINT32      I2C71Addr;                   // 582 I2C7
> +  UINT32      I2C71Len;                    // 586
> +
> +  //
> +  // Scc controllers
> +  //
> +  UINT32      eMMCAddr;                    // 590 EMMC
> +  UINT32      eMMCLen;                     // 594
> +  UINT32      eMMC1Addr;                   // 598
> +  UINT32      eMMC1Len;                    // 602
> +  UINT32      SDIOAddr;                    // 606 SDIO
> +  UINT32      SDIOLen;                     // 610
> +  UINT32      SDIO1Addr;                   // 614
> +  UINT32      SDIO1Len;                    // 618
> +  UINT32      SDCardAddr;                  // 622 SDCard
> +  UINT32      SDCardLen;                   // 626
> +  UINT32      SDCard1Addr;                 // 630
> +  UINT32      SDCard1Len;                  // 636
> +  UINT32      MipiHsiAddr;                 // 640 MIPI-HSI
> +  UINT32      MipiHsiLen;                  // 644
> +  UINT32      MipiHsi1Addr;                // 648
> +  UINT32      MipiHsi1Len;                 // 652
> +
> +  UINT8       SdCardRemovable;                   // 656 reserve offset upto 658
> +  UINT8       HideLPSSDevices;                   // 657 Hide unsupported LPSS devices
> when in ACPI mode
> +  UINT8       ReservedO;                         // 658 OS Selection
> +  UINT8       Reserved00;                        // 659
> +  UINT8       Reserved01;                        // 660
> +  UINT8       Reserved02;                   // 661
> +  UINT8       Reserved03;                   // 662
> +  UINT8       Reserved04;                   // 663
> +  UINT8       Reserved05;                   // 664
> +  UINT8       Reserved06;                   // 665
> +  UINT8       Reserved07;                       // 666
> +  UINT8       Reserved08;                 // 667
> +  UINT8       Reserved09;                     // 668
> +  UINT8       Reserved0A;                     // 669
> +  UINT32      Reserved0B;       // 670
> +  UINT32      Reserved0C;        // 674
> +  UINT32      Reserved0D;   // 678
> +  UINT32      Reserved0E;    // 682
> +  UINT32      Reserved0F;   // 686
> +  UINT32      Reserved10;    // 690
> +  UINT32      Reserved11;   // 694
> +  UINT32      Reserved12;    // 698
> +  UINT32      Reserved13;   // 702
> +  UINT32      Reserved14;    // 706
> +  UINT32      Reserved15;   // 710
> +  UINT32      Reserved16;    // 714
> +  UINT8       Reserved17;
> +  UINT32      Reserved18;
> +  UINT32      Reserved19;
> +  UINT32      Reserved1A;
> +  UINT32      Reserved1B;
> +  UINT32      Reserved1C;
> +  UINT8       Reserved1D;
> +  UINT32      Reserved1E;
> +  UINT32      Reserved1F;
> +  UINT32      Reserved20;
> +  UINT32      Reserved21;
> +  UINT32      Reserved22;
> +  UINT8       Reserved23;
> +  UINT8       BatteryChargingSolution;           // 761 0-non ULPMC 1-ULPMC
> +
> +  //
> +  //101 bytes
> +  //
> +  UINT8       NFCnSelect;                        // 762 NFCx Select 1: NFC1    2:NFC2
> +  UINT8       LpssSccMode;                       // 763 EMMC device 0-ACPI mode, 1-
> PCI mode
> +
> +  UINT32      TPMAddress;                        // 764
> +  UINT32      TPMLength;                         // 768
> +
> +  UINT8       I2CTouchAddress;                   // 772 I2C touch address, 0x4B:RVP
> 0x4A:FFRD
> +  UINT8       IdleReserve;                       // 773  0 - disabled 1 - enabled
> +  UINT8       SDIOMode;                          // 774  3 - Default  2 - DDR50
> +  UINT8       emmcVersion;                       // 775  0 - 4.41 1 - 4.5
> +  UINT32      BmBound;                           // 776 BM Bound
> +  UINT8       FsaStatus;                         // 780 0 - Fsa is off, 1- Fsa is on
> +
> +  //
> +  // Board Id
> +  // This field is for the ASL code to know whether this board is Baylake or
> Bayley Bay etc
> +  //
> +  UINT8       BoardID;                           //  781
> +  UINT8       FabID;                             // 782
> +  UINT8       OtgMode;                           // 783 0- OTG disable 1- OTG PCI mode
> +  UINT8       Stepping;                          //  784 Stepping
> +  UINT8       WittEnable;                        // 785 WITT eanble 0 - disable 1 - enable
> +
> +  UINT8       SocStepping;                       // 786 Soc Stepping infomation
> +  UINT8       AmbientTripPointChange;            // 787 DPTF: Controls whether
> _ATI changes other participant's trip point(enabled/disabled)
> +  UINT8       UtsEnable;                         // 788 Uart Test eanble 0 - disable 1 -
> enable
> +  UINT8     DptfReserve;       // 789
> +
> +  UINT8       SarEnable;                          // 790
> +  UINT8       PssDeveice;                        // 791 PSS Deveice: 0 - None, 1 - Monzax
> 2K, 2 - Monzax 8K
> +  UINT8       EDPV;                              // 792 Check for eDP display device
> +  UINT32      DIDX;                              // 793 Device ID for eDP device
> +  UINT8       MicrosoftIoT;                      // (794)JP1 pins are for Microsoft IoT
> project.
> +  UINT8       RtcBattery;                        // (795) The Flag of RTC Battery Present.
> +  UINT8       LpeAudioReportedByDSDT;            // (796)
> +} EFI_GLOBAL_NVS_AREA;
> +#pragma pack ()
> +
> +//
> +// Global NVS Area Protocol
> +//
> +typedef struct _EFI_GLOBAL_NVS_AREA_PROTOCOL {
> +  EFI_GLOBAL_NVS_AREA     *Area;
> +} EFI_GLOBAL_NVS_AREA_PROTOCOL;
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/HwWatchdogTimer.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/HwWatchdogTimer.h
> new file mode 100644
> index 0000000000..71fe6275ee
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/HwWatchdogTimer.h
> @@ -0,0 +1,235 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  HwWatchdogTimer.h
> +
> +Abstract:
> +
> +
> +--*/
> +
> +#ifndef __EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL_H__
> +#define __EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL_H__
> +
> +#define EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL_GUID \
> +  { 0xd5b06d16, 0x2ea1, 0x4def, 0x98, 0xd0, 0xa0, 0x5d, 0x40, 0x72, 0x84,
> 0x17 }
> +
> +#define EFI_WATCHDOG_TIMER_NOT_SUPPORTED_PROTOCOL_GUID \
> +  { 0xe9e156ac, 0x3203, 0x4572, 0xac, 0xdf, 0x84, 0x4f, 0xdc, 0xdb, 0x6, 0xbf }
> +
> +
> +#include <Guid/HwWatchdogTimerHob.h>
> +
> +//
> +// General Purpose Constants
> +//
> +#define ICH_INSTAFLUSH_GPIO      BIT16 // BIT 16 in GPIO Level 2 is GPIO 48.
> +#define B_INSTAFLUSH             BIT4
> +
> +//
> +// Other Watchdog timer values
> +//
> +#define WDT_COUNTDOWN_VALUE                 0x14
> +#define BDS_WDT_COUNTDOWN_VALUE             0x35
> +
> +//
> +// Prototypes for the Watchdog Timer Driver Protocol
> +//
> +
> +/**
> +  This service begins the Watchdog Timer countdown.  If the countdown
> completes prior to
> +  Stop Timer or Restart Timer the system will reset.
> +
> +  @param[in] None
> +
> +  @retval EFI_SUCCESS        Operation completed successfully
> +  @retval EFI_DEVICE_ERROR   The command was unsuccessful
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_WATCHDOG_START_TIMER) (
> +  VOID
> +  );
> +
> +/**
> +  This service resets the Watchdog Timer countdown and should only be
> called after the
> +  Start Timer function.
> +
> +  @param[in] None
> +
> +  @retval EFI_SUCCESS        Operation completed successfully
> +  @retval EFI_DEVICE_ERROR   The command was unsuccessful
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_WATCHDOG_RESET_TIMER) (
> +  VOID
> +  );
> +
> +/**
> +  This service restarts the Watchdog Timer countdown and should only be
> called after the
> +  Start Timer function.
> +
> +  @param[in] None
> +
> +  @retval EFI_SUCCESS        Operation completed successfully
> +  @retval EFI_DEVICE_ERROR   The command was unsuccessful
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_WATCHDOG_RESTART_TIMER) (
> +  VOID
> +  );
> +
> +/**
> +  This service disables the Watchdog Timer countdown.
> +
> +  @param[in] None
> +
> +  @retval EFI_SUCCESS        Operation completed successfully
> +  @retval EFI_DEVICE_ERROR   The command was unsuccessful
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_WATCHDOG_STOP_TIMER) (
> +  VOID
> +  );
> +
> +/**
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_WATCHDOG_CHECK_TIMEOUT) (
> +  OUT HW_WATCHDOG_TIMEOUT       *WatchdogTimeout
> +  );
> +
> +
> +
> +/**
> +  This service forces a reboot of the system due to a reset of the
> POWERGOOD_PS,
> +  POWERGOOD_CLK, and the BSEL Override
> +
> +  Arguments:
> +    None
> +
> +  Returns:
> +    This function should not return!
> +
> +    EFI_DEVICE_ERROR  - The command was unsuccessful and a reboot did
> not occur
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_WATCHDOG_FORCE_REBOOT) (
> +  IN BOOLEAN                    ForceTimeout,
> +  IN UINT8                      ResetType
> +  );
> +
> +/**
> +  This service notifies the Watchdog Timer of the fact that a known reset is
> occuring.
> +
> +  @param[in] AllowReset  TRUE if a Reset is currently expected
> +                         FALSE if a Reset is not currently expected
> +
> +    This function should not return!
> +
> +    EFI_DEVICE_ERROR  - The command was unsuccessful and a reboot did
> not occur
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_WATCHDOG_KNOWN_RESET) (
> +  IN BOOLEAN                    AllowReset
> +  );
> +
> +/**
> +  This service reads the current Watchdog Timer countdown reload value.
> +
> +  @param[in] CountdownValue      pointer to UINT32 to return the value of
> the reload register.
> +
> +  @retval    EFI_SUCCESS         Operation completed successfully
> +  @retval    EFI_DEVICE_ERROR    The command was unsuccessful
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_GET_TIMER_COUNT_DOWN_PERIOD)(
> +  OUT UINT32      *CountdownValue
> +  );
> +
> +/**
> +  This service reads the current Watchdog Timer countdown reload value.
> +
> +  @param[in] CountdownValue  Value to set the reload register.
> +
> +  @retval EFI_SUCCESS        Operation completed successfully
> +  @retval EFI_DEVICE_ERROR   The command was unsuccessful
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SET_TIMER_COUNT_DOWN_PERIOD)(
> +  OUT UINT32      CountdownValue
> +  );
> +
> +/**
> +  This service clears the state that indicates the Watchdog Timer fired.
> +
> +  @retval EFI_SUCCESS       - Operation completed successfully
> +  @retval EFI_DEVICE_ERROR  - The command was unsuccessful
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_WATCHDOG_CLEAR_TIMER_STATE) (
> +  );
> +
> +/**
> +  This service disables the Watchdog Timer countdown.  It also closes the
> recurring restart event
> +  if the event exists.
> +
> +  @param[in] Stall  TRUE = Stop the timer countdown
> +                    FALSE = Start the timer countdown
> +
> +  @retval  EFI_SUCCESS        Operation completed successfully
> +  @retval  EFI_DEVICE_ERROR   The command was unsuccessful
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_STALL_WATCHDOG_COUNTDOWN) (
> +  IN BOOLEAN Stall
> +  );
> +
> +
> +typedef struct _EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL {
> +  EFI_WATCHDOG_START_TIMER                      StartWatchdogTimer;
> +  PEI_WATCHDOG_RESET_TIMER                      ResetWatchdogTimeout;
> +  EFI_WATCHDOG_RESTART_TIMER                    RestartWatchdogTimer;
> +  EFI_WATCHDOG_STOP_TIMER                       StopWatchdogTimer;
> +  EFI_WATCHDOG_CHECK_TIMEOUT                    CheckWatchdogTimeout;
> +  EFI_WATCHDOG_FORCE_REBOOT                     ForceReboot;
> +  EFI_WATCHDOG_KNOWN_RESET                      AllowKnownReset;
> +  EFI_GET_TIMER_COUNT_DOWN_PERIOD               GetCountdownPeriod;
> +  EFI_SET_TIMER_COUNT_DOWN_PERIOD               SetCountdownPeriod;
> +  PEI_WATCHDOG_CLEAR_TIMER_STATE                ClearTimerState;
> +  EFI_STALL_WATCHDOG_COUNTDOWN                  StallWatchdogCountdown;
> +} EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL;
> +
> +extern EFI_GUID gEfiWatchdogTimerDriverProtocolGuid;
> +extern EFI_GUID gEfiWatchdogTimerNotSupportedProtocolGuid;
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cAcpi.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cAcpi.h
> new file mode 100644
> index 0000000000..9ec5e1473b
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cAcpi.h
> @@ -0,0 +1,107 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +**/
> +
> +#ifndef __I2C_ACPI_H__
> +#define __I2C_ACPI_H__
> +
> +#include <Protocol/DevicePath.h>
> +
> +//
> +// I2C ACPI protocol
> +//
> +typedef struct _EFI_I2C_ACPI_PROTOCOL   EFI_I2C_ACPI_PROTOCOL;
> +
> +//
> +// I2C device description
> +//
> +// This structure provides the platform specific information which
> +// describes an I2C device.
> +//
> +typedef struct {
> +  //
> +  // Hardware revision - ACPI _HRV value
> +  //
> +  UINT32 HardwareRevision;
> +
> +  //
> +  // Device path node for the I2C device.
> +  //
> +  CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath;
> +
> +  //
> +  // I2C bus configuration for the I2C device.
> +  //
> +  UINT32 I2cBusConfiguration;
> +
> +  //
> +  // Number of slave addresses for the I2C device.
> +  //
> +  UINT32 SlaveAddressCount;
> +
> +  //
> +  // Address of the array of slave addresses for the I2C device.
> +  //
> +  CONST UINT32 *SlaveAddressArray;
> +}EFI_I2C_DEVICE;
> +
> +
> +/**
> +  Enumerate the I2C devices
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +
> +  This function walks the platform specific data to enumerates the
> +  I2C devices on an I2C bus.
> +
> +  @param[in]  This              Address of an EFI_I2C_ENUM_PROTOCOL
> +                                structure.
> +  @param[in, out] Device        Buffer containing the address of an
> +                                EFI_I2C_DEVICE structure.  Enumeration
> +                                is started by setting the initial
> +                                EFI_I2C_DEVICE structure address to NULL.
> +                                The buffer receives an EFI_I2C_DEVICE
> +                                structure address for the next I2C device.
> +
> +  @retval EFI_SUCCESS           The platform data for the next device
> +                                on the I2C bus was returned successfully.
> +  @retval EFI_INVALID_PARAMETER NextDevice was NULL
> +  @retval EFI_NO_MAPPING        PreviousDevice does not point to a valid
> +                                EFI_I2C_DEVICE structure.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_I2C_ACPI_ENUMERATE) (
> +  IN CONST EFI_I2C_ACPI_PROTOCOL *This,
> +  IN OUT CONST EFI_I2C_DEVICE **Device
> +  );
> +
> +//
> +// I2C device description
> +//
> +// This structure provides the platform specific information which
> +// describes an I2C device.
> +//
> +struct _EFI_I2C_ACPI_PROTOCOL {
> +  //
> +  // Walk the platform's list of I2C devices on the bus.  This
> +  // routine returns the next I2C device in the platform's list
> +  // for this I2C bus.
> +  //
> +  EFI_I2C_ACPI_ENUMERATE Enumerate;
> +};
> +
> +//
> +// Variable containing the GUID for the I2C device enumeration protocol
> +//
> +extern EFI_GUID gEfiI2cAcpiProtocolGuid;
> +
> +#endif  //  __I2C_ACPI_H__
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBus.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBus.h
> new file mode 100644
> index 0000000000..b321a026b2
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBus.h
> @@ -0,0 +1,164 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +**/
> +
> +#ifndef __I2C_BUS_H__
> +#define __I2C_BUS_H__
> +
> +#include <Protocol/I2cHostMcg.h>
> +
> +//
> +// I2C bus protocol
> +//
> +typedef struct _EFI_I2C_BUS_PROTOCOL  EFI_I2C_BUS_PROTOCOL;
> +
> +
> +/**
> +  Perform an I2C operation on the device
> +
> +  This routine must be called at or below TPL_NOTIFY.  For synchronous
> +  requests this routine must be called at or below TPL_CALLBACK.
> +
> +  N.B. The typical consumers of this API are the third party I2C
> +  drivers.  Extreme care must be taken by other consumers of this
> +  API to prevent confusing the third party I2C drivers due to a
> +  state change at the I2C device which the third party I2C drivers
> +  did not initiate.  I2C platform drivers may use this API within
> +  these guidelines.
> +
> +  This routine queues an operation to the I2C controller for execution
> +  on the I2C bus.
> +
> +  As an upper layer driver writer, the following need to be provided
> +  to the platform vendor:
> +
> +  1.  ACPI CID value or string - this is used to connect the upper layer
> +      driver to the device.
> +  2.  Slave address array guidance when the I2C device uses more than one
> +      slave address.  This is used to access the blocks of hardware within
> +      the I2C device.
> +
> +  @param[in] This               Address of an EFI_I2C_BUS_PROTOCOL
> +                                structure
> +  @param[in] SlaveAddressIndex  Index into an array of slave addresses for
> +                                the I2C device.  The values in the array are
> +                                specified by the board designer, with the
> +                                I2C device driver writer providing the slave
> +                                address order.
> +
> +                                For devices that have a single slave address,
> +                                this value must be zero.  If the I2C device
> +                                uses more than one slave address then the third
> +                                party (upper level) I2C driver writer needs to
> +                                specify the order of entries in the slave address
> +                                array.
> +
> +                                \ref ThirdPartyI2cDrivers "Third Party I2C Drivers"
> +                                section in I2cMaster.h.
> +  @param[in] Event              Event to set for asynchronous operations,
> +                                NULL for synchronous operations
> +  @param[in] RequestPacket      Address of an EFI_I2C_REQUEST_PACKET
> +                                structure describing the I2C operation
> +  @param[out] I2cStatus         Optional buffer to receive the I2C operation
> +                                completion status
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval EFI_ABORTED           The request did not complete because the
> driver
> +                                was shutdown.
> +  @retval EFI_ACCESS_DENIED     Invalid SlaveAddressIndex value
> +  @retval EFI_BAD_BUFFER_SIZE   The WriteBytes or ReadBytes buffer size
> is too large.
> +  @retval EFI_DEVICE_ERROR      There was an I2C error (NACK) during the
> operation.
> +                                This could indicate the slave device is not present.
> +  @retval EFI_INVALID_PARAMETER RequestPacket is NULL
> +  @retval EFI_INVALID_PARAMETER TPL is too high
> +  @retval EFI_NO_RESPONSE       The I2C device is not responding to the
> +                                slave address.  EFI_DEVICE_ERROR may also be
> +                                returned if the controller can not distinguish
> +                                when the NACK occurred.
> +  @retval EFI_NOT_FOUND         I2C slave address exceeds maximum
> address
> +  @retval EFI_NOT_READY         I2C bus is busy or operation pending, wait for
> +                                the event and then read status pointed to by
> +                                the request packet.
> +  @retval EFI_OUT_OF_RESOURCES  Insufficient memory for I2C operation
> +  @retval EFI_TIMEOUT           The transaction did not complete within an
> internally
> +                                specified timeout period.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_I2C_BUS_START_REQUEST) (
> +  IN CONST EFI_I2C_BUS_PROTOCOL *This,
> +  IN UINTN SlaveAddressIndex,
> +  IN EFI_EVENT Event OPTIONAL,
> +  IN CONST EFI_I2C_REQUEST_PACKET *RequestPacket,
> +  OUT EFI_STATUS *I2cStatus OPTIONAL
> +  );
> +
> +//
> +// The I2C bus protocol enables access to a specific device on the I2C bus.
> +//
> +// Each I2C device is described as an ACPI node (HID, UID and CID) within
> the
> +// platform layer.  The I2C bus protocol enumerates the I2C devices in the
> +// platform and creates a unique handle and device path for each I2C device.
> +//
> +// I2C slave addressing is abstracted to validate addresses and limit
> operation
> +// to the specified I2C device.  The third party providing the I2C device
> support
> +// provides an ordered list of slave addresses for the I2C device to the team
> +// building the platform layer.  The platform team must preserve the order
> of the
> +// supplied list.  SlaveAddressCount is the number of entries in this list or
> +// array within the platform layer.  The third party device support
> references
> +// a slave address using an index into the list or array in the range of zero
> +// to SlaveAddressCount - 1.
> +//
> +struct _EFI_I2C_BUS_PROTOCOL {
> +  //
> +  // Start an I2C operation on the bus
> +  //
> +  EFI_I2C_BUS_START_REQUEST StartRequest;
> +
> +  //
> +  // The maximum number of slave addresses for the I2C device.  The caller
> may
> +  // validate this value as a check on the platform layer's configuration.  Slave
> +  // address selection uses an index value in the range of zero to
> SlaveAddressCount - 1.
> +  //
> +  UINTN SlaveAddressCount;
> +
> +  //
> +  // Hardware revision - Matches the ACPI _HRV value
> +  //
> +  // The HardwareRevision value allows a single driver to support multiple
> hardware
> +  // revisions and implement the necessary workarounds for limitations
> within the
> +  // hardware.
> +  //
> +  UINT32 HardwareRevision;
> +
> +  //
> +  // The maximum number of bytes the I2C host controller
> +  // is able to receive from the I2C bus.
> +  //
> +  UINT32 MaximumReceiveBytes;
> +
> +  //
> +  // The maximum number of bytes the I2C host controller
> +  // is able to send on the I2C bus.
> +  //
> +  UINT32 MaximumTransmitBytes;
> +
> +  //
> +  // The maximum number of bytes in the I2C bus transaction.
> +  //
> +  UINT32 MaximumTotalBytes;
> +};
> +
> +//
> +// GUID for the I2C bus protocol
> +//
> +extern EFI_GUID gEfiI2cBusProtocolGuid;
> +
> +#endif  //  __I2C_BUS_H__
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBusMcg.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBusMcg.h
> new file mode 100644
> index 0000000000..1cfca218bd
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBusMcg.h
> @@ -0,0 +1,163 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +**/
> +
> +#ifndef __I2C_BUS_H__
> +#define __I2C_BUS_H__
> +
> +#include <Protocol/I2cHostMcg.h>
> +
> +//
> +// I2C bus protocol
> +//
> +typedef struct _EFI_I2C_BUS_PROTOCOL  EFI_I2C_BUS_PROTOCOL;
> +
> +/**
> +  Perform an I2C operation on the device
> +
> +  This routine must be called at or below TPL_NOTIFY.  For synchronous
> +  requests this routine must be called at or below TPL_CALLBACK.
> +
> +  N.B. The typical consumers of this API are the third party I2C
> +  drivers.  Extreme care must be taken by other consumers of this
> +  API to prevent confusing the third party I2C drivers due to a
> +  state change at the I2C device which the third party I2C drivers
> +  did not initiate.  I2C platform drivers may use this API within
> +  these guidelines.
> +
> +  This routine queues an operation to the I2C controller for execution
> +  on the I2C bus.
> +
> +  As an upper layer driver writer, the following need to be provided
> +  to the platform vendor:
> +
> +  1.  ACPI CID value or string - this is used to connect the upper layer
> +      driver to the device.
> +  2.  Slave address array guidance when the I2C device uses more than one
> +      slave address.  This is used to access the blocks of hardware within
> +      the I2C device.
> +
> +  @param[in] This               Address of an EFI_I2C_BUS_PROTOCOL
> +                                structure
> +  @param[in] SlaveAddressIndex  Index into an array of slave addresses for
> +                                the I2C device.  The values in the array are
> +                                specified by the board designer, with the
> +                                I2C device driver writer providing the slave
> +                                address order.
> +
> +                                For devices that have a single slave address,
> +                                this value must be zero.  If the I2C device
> +                                uses more than one slave address then the third
> +                                party (upper level) I2C driver writer needs to
> +                                specify the order of entries in the slave address
> +                                array.
> +
> +                                \ref ThirdPartyI2cDrivers "Third Party I2C Drivers"
> +                                section in I2cMaster.h.
> +  @param[in] Event              Event to set for asynchronous operations,
> +                                NULL for synchronous operations
> +  @param[in] RequestPacket      Address of an EFI_I2C_REQUEST_PACKET
> +                                structure describing the I2C operation
> +  @param[out] I2cStatus         Optional buffer to receive the I2C operation
> +                                completion status
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval EFI_ABORTED           The request did not complete because the
> driver
> +                                was shutdown.
> +  @retval EFI_ACCESS_DENIED     Invalid SlaveAddressIndex value
> +  @retval EFI_BAD_BUFFER_SIZE   The WriteBytes or ReadBytes buffer size
> is too large.
> +  @retval EFI_DEVICE_ERROR      There was an I2C error (NACK) during the
> operation.
> +                                This could indicate the slave device is not present.
> +  @retval EFI_INVALID_PARAMETER RequestPacket is NULL
> +  @retval EFI_INVALID_PARAMETER TPL is too high
> +  @retval EFI_NO_RESPONSE       The I2C device is not responding to the
> +                                slave address.  EFI_DEVICE_ERROR may also be
> +                                returned if the controller can not distinguish
> +                                when the NACK occurred.
> +  @retval EFI_NOT_FOUND         I2C slave address exceeds maximum
> address
> +  @retval EFI_NOT_READY         I2C bus is busy or operation pending, wait for
> +                                the event and then read status pointed to by
> +                                the request packet.
> +  @retval EFI_OUT_OF_RESOURCES  Insufficient memory for I2C operation
> +  @retval EFI_TIMEOUT           The transaction did not complete within an
> internally
> +                                specified timeout period.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_I2C_BUS_START_REQUEST) (
> +  IN CONST EFI_I2C_BUS_PROTOCOL *This,
> +  IN UINTN SlaveAddressIndex,
> +  IN EFI_EVENT Event OPTIONAL,
> +  IN CONST EFI_I2C_REQUEST_PACKET *RequestPacket,
> +  OUT EFI_STATUS *I2cStatus OPTIONAL
> +  );
> +
> +//
> +// The I2C bus protocol enables access to a specific device on the I2C bus.
> +//
> +// Each I2C device is described as an ACPI node (HID, UID and CID) within
> the
> +// platform layer.  The I2C bus protocol enumerates the I2C devices in the
> +// platform and creates a unique handle and device path for each I2C device.
> +//
> +// I2C slave addressing is abstracted to validate addresses and limit
> operation
> +// to the specified I2C device.  The third party providing the I2C device
> support
> +// provides an ordered list of slave addresses for the I2C device to the team
> +// building the platform layer.  The platform team must preserve the order
> of the
> +// supplied list.  SlaveAddressCount is the number of entries in this list or
> +// array within the platform layer.  The third party device support
> references
> +// a slave address using an index into the list or array in the range of zero
> +// to SlaveAddressCount - 1.
> +//
> +struct _EFI_I2C_BUS_PROTOCOL {
> +  //
> +  // Start an I2C operation on the bus
> +  //
> +  EFI_I2C_BUS_START_REQUEST StartRequest;
> +
> +  //
> +  // The maximum number of slave addresses for the I2C device.  The caller
> may
> +  // validate this value as a check on the platform layer's configuration.  Slave
> +  // address selection uses an index value in the range of zero to
> SlaveAddressCount - 1.
> +  //
> +  UINTN SlaveAddressCount;
> +
> +  //
> +  // Hardware revision - Matches the ACPI _HRV value
> +  //
> +  // The HardwareRevision value allows a single driver to support multiple
> hardware
> +  // revisions and implement the necessary workarounds for limitations
> within the
> +  // hardware.
> +  //
> +  UINT32 HardwareRevision;
> +
> +  //
> +  // The maximum number of bytes the I2C host controller
> +  // is able to receive from the I2C bus.
> +  ///
> +  UINT32 MaximumReceiveBytes;
> +
> +  //
> +  // The maximum number of bytes the I2C host controller
> +  // is able to send on the I2C bus.
> +  //
> +  UINT32 MaximumTransmitBytes;
> +
> +  //
> +  // The maximum number of bytes in the I2C bus transaction.
> +  //
> +  UINT32 MaximumTotalBytes;
> +};
> +
> +//
> +// GUID for the I2C bus protocol
> +//
> +extern EFI_GUID gEfiI2cBusProtocolGuid;
> +
> +#endif  //  __I2C_BUS_H__
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cHostMcg.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cHostMcg.h
> new file mode 100644
> index 0000000000..1d94ee4106
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cHostMcg.h
> @@ -0,0 +1,138 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +**/
> +
> +#ifndef __I2C_HOST_H__
> +#define __I2C_HOST_H__
> +
> +#include <Protocol/I2cMasterMcg.h>
> +
> +/**
> +  Declare the forward references
> +
> +**/
> +typedef struct _EFI_I2C_HOST_PROTOCOL EFI_I2C_HOST_PROTOCOL;
> +typedef struct _EFI_I2C_HOST_CALLBACKS EFI_I2C_HOST_CALLBACKS;
> +
> +
> +/**
> +  Queue an I2C operation for execution on the I2C controller.
> +
> +  This routine must be called at or below TPL_NOTIFY.  For synchronous
> +  requests this routine must be called at or below TPL_CALLBACK.
> +
> +  N.B. The typical consumers of this API are the I2C bus driver and
> +  on rare occasions the I2C test application.  Extreme care must be
> +  taken by other consumers of this API to prevent confusing the
> +  third party I2C drivers due to a state change at the I2C device
> +  which the third party I2C drivers did not initiate.  I2C platform
> +  drivers may use this API within these guidelines.
> +
> +  This layer uses the concept of I2C bus configurations to describe
> +  the I2C bus.  An I2C bus configuration is defined as a unique
> +  setting of the multiplexers and switches in the I2C bus which
> +  enable access to one or more I2C devices.  When using a switch
> +  to divide a bus, due to speed differences, the I2C platform layer
> +  would define an I2C bus configuration for the I2C devices on each
> +  side of the switch.  When using a multiplexer, the I2C platform
> +  layer defines an I2C bus configuration for each of the selector
> +  values required to control the multiplexer.  See Figure 1 in the
> +  <a
> href="http://www.nxp.com/documents/user_manual/UM10204.pdf">I<sup
> >2</sup>C
> +  Specification</a> for a complex I2C bus configuration.
> +
> +  The I2C host driver processes all operations in FIFO order.  Prior to
> +  performing the operation, the I2C host driver calls the I2C platform
> +  driver to reconfigure the switches and multiplexers in the I2C bus
> +  enabling access to the specified I2C device.  The I2C platform driver
> +  also selects the maximum bus speed for the device.  After the I2C bus
> +  is configured, the I2C host driver calls the I2C port driver to
> +  initialize the I2C controller and start the I2C operation.
> +
> +  @param[in] This             Address of an EFI_I2C_HOST_PROTOCOL instance.
> +  @param[in] I2cBusConfiguration  I2C bus configuration to access the I2C
> +                                  device.
> +  @param[in] SlaveAddress     Address of the device on the I2C bus.
> +  @param[in] Event            Event to set for asynchronous operations,
> +                              NULL for synchronous operations
> +  @param[in] RequestPacket    Address of an EFI_I2C_REQUEST_PACKET
> +                              structure describing the I2C operation
> +  @param[out] I2cStatus       Optional buffer to receive the I2C operation
> +                              completion status
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval EFI_ABORTED           The request did not complete because the
> driver
> +                                was shutdown.
> +  @retval EFI_BAD_BUFFER_SIZE   The WriteBytes or ReadBytes buffer size
> is too large.
> +  @retval EFI_DEVICE_ERROR      There was an I2C error (NACK) during the
> operation.
> +                                This could indicate the slave device is not present.
> +  @retval EFI_INVALID_PARAMETER RequestPacket is NULL
> +  @retval EFI_INVALID_PARAMETER TPL is too high
> +  @retval EFI_NO_MAPPING        Invalid I2cBusConfiguration value
> +  @retval EFI_NO_RESPONSE       The I2C device is not responding to the
> +                                slave address.  EFI_DEVICE_ERROR may also be
> +                                returned if the controller cannot distinguish
> +                                when the NACK occurred.
> +  @retval EFI_NOT_FOUND         I2C slave address exceeds maximum
> address
> +  @retval EFI_NOT_READY         I2C bus is busy or operation pending, wait for
> +                                the event and then read status pointed to by
> +                                the request packet.
> +  @retval EFI_OUT_OF_RESOURCES  Insufficient memory for I2C operation
> +  @retval EFI_TIMEOUT           The transaction did not complete within an
> internally
> +                                specified timeout period.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_I2C_HOST_QUEUE_REQUEST) (
> +  IN CONST EFI_I2C_HOST_PROTOCOL *This,
> +  IN UINTN I2cBusConfiguration,
> +  IN UINTN SlaveAddress,
> +  IN EFI_EVENT Event OPTIONAL,
> +  IN CONST EFI_I2C_REQUEST_PACKET *RequestPacket,
> +  OUT EFI_STATUS *I2cStatus OPTIONAL
> +  );
> +
> +///
> +/// Host access to the I2C bus.
> +///
> +struct _EFI_I2C_HOST_PROTOCOL {
> +  ///
> +  /// Queue an operation for execution on the I2C bus
> +  ///
> +  EFI_I2C_HOST_QUEUE_REQUEST QueueRequest;
> +
> +  ///
> +  /// The maximum number of I2C bus configurations
> +  ///
> +  UINTN I2cBusConfigurationCount;
> +
> +  ///
> +  /// The maximum number of bytes the I2C host controller
> +  /// is able to receive from the I2C bus.
> +  ///
> +  UINT32 MaximumReceiveBytes;
> +
> +  ///
> +  /// The maximum number of bytes the I2C host controller
> +  /// is able to send on the I2C bus.
> +  ///
> +  UINT32 MaximumTransmitBytes;
> +
> +  ///
> +  /// The maximum number of bytes in the I2C bus transaction.
> +  ///
> +  UINT32 MaximumTotalBytes;
> +};
> +
> +///
> +/// GUID for the EFI_I2C_HOST_PROTOCOL
> +///
> +extern EFI_GUID gEfiI2cHostProtocolGuid;
> +
> +#endif  //  __I2C_HOST_H__
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cMasterMcg.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cMasterMcg.h
> new file mode 100644
> index 0000000000..5ca47b2c7f
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cMasterMcg.h
> @@ -0,0 +1,519 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +  \section I2cDriverStack       I2C Driver Stack
> +
> +  The following is a representation of the I<sup>2</sup>C (I2C)
> +  driver stack and an I2C bus layout.
> +
> +  <code><pre>
> +              +-----------------+
> +              |   Application   |
> +              +-----------------+
> +                       |
> +                       | Third Party or UEFI
> +                       |
> +                       V
> + +--------+   +-----------------+
> + | Slave  |   |   Third Party   |
> + | Driver |   |   I2C Device    |
> + |        |   |     Driver      |
> + +--------+   +-----------------+
> +      |                |
> +      |          BUS   |
> +      |                |
> +      |                V
> +      |       +-----------------+
> +      |       | I2C Bus Driver  |------------------.
> +      |       +-----------------+                  |
> +      |                |                           |
> +      |         HOST   |          BUS              |
> +      |                |          CONFIGURATION    |
> +SLAVE |                V          MANAGEMENT       | ACPI
> +      |       +-----------------+                  |
> +      |       | I2C Host Driver |----------.       |
> +      |       +-----------------+          |       |
> +      |                |                   |       |
> +      |        MASTER  |                   V       V
> +      |                |               +-------=-------------+
> +      |                V               | I2C Platform Driver |
> +      |       +-----------------+      +---------------------+
> +      `------>| I2C Port Driver |               |      |
> +              +-----------------+               |      |
> +                       |                        |      |
> +            Software   |                        |      |
> +            --------------------------------------------------
> +            Hardware   |                        |      |
> +                       |                        |      |
> +                       V                        |      |
> +              +-----------------+               |      |
> +              | I2C Controller  |               |      |
> +              +-----------------+               |      |
> +                       |                        |      |
> +            -----------------------             |      |
> +            I2C Bus    |                        |      |
> +                       |    +------------+      |      |
> +                       +----| High speed |      |      |
> +                       |    | I2C device |      |      |
> +                       |    |    0x01    |      |      |
> +                       |    +------------+      |      |
> +                       |                        |      |
> +                  +---------+  0                |      |
> +                  | Switch  |<------------------`      |
> +                  +---------+  1                       |
> +                       |                               |
> +                       |    +------------+             |
> +                       +----| Fast speed |             |
> +                       |    | I2C device |             |
> +                       |    |    0x02    |             |
> +                       |    +------------+             |
> +                       |                               |
> +                +-------------+                        |
> +                | Multiplexer |<-----------------------`
> +                +-------------+
> +                 0 |       | 1
> +                   |       |
> +                   |       |
> +                   |       |    +-------------+
> +                   |       +----| Third Party |
> +                   |       |    | I2C Device  |
> +                   |       |    |  0x03, 0x04 |
> +                   |       |    +-------------+
> +                   |       |
> +                   |
> +                   |            +-------------+
> +                   +------------| Third Party |
> +                   |            | I2C Device  |
> +                   |            |  0x03, 0x04 |
> +                   |            +-------------+
> +                   |
> +  </pre></code>
> +
> +  The platform hardware designer chooses the bus layout based upon
> +  the platform, I2C chip and software requirements.  The design uses
> +  switches to truncate the bus to enable higher speed operation for a
> +  subset of devices which are placed closer to the controller.  When the
> +  switch is on, the extended bus must operate at a lower speed.  The
> +  design uses multiplexer to create separate address spaces enabling
> +  the use of multiple devices which would otherwise have conflicting
> +  addresses. See the
> +  <a
> href="http://www.nxp.com/documents/user_manual/UM10204.pdf">I<sup
> >2</sup>C
> +  Specification</a> for more details.
> +
> +  N.B. Some operating systems may prohibit the changing of switches
> +  and multiplexers in the I2C bus.  In this case the platform hardware
> +  and software designers must select a single I2C bus configuration
> +  consisting of constant input values for the switches and multiplexers.
> +  The platform software designer must then ensure that this I2C bus
> +  configuration is enabled prior to passing control to the operating
> +  system.
> +
> +  The platform hardware designer needs to provide the platform software
> +  designer the following data for each I2C bus:
> +
> +  1.  Which controller controls this bus
> +
> +  2.  A list of logic blocks contained in one or more I2C devices:
> +
> +      a.  I2C device which contains this logic block
> +
> +      b.  Logic block slave address
> +
> +      c.  Logic block name
> +
> +  3.  For each configuration of the switches and multiplexer
> +
> +      a.  What is the maximum speed of operation
> +
> +      b.  What devices are accessible
> +
> +  4.  The settings for the switches and multiplexers when control is
> +      given to the operating system.
> +
> +  \section ThirdPartyI2cDrivers   Third Party I2C Drivers
> +
> +  This layer is I2C chip specific but platform and host controller
> +  independent.
> +
> +  Third party I2C driver writers, typically silicon vendors, need
> +  to provide:
> +
> +  1.  The device path node data that is used to select their
> +      driver.
> +
> +  2.  The order for the blocks of logic that get referenced
> +      by the entries in the slave address array.
> +
> +  3.  The hardware version of the I2C device, this value is passed
> +      to the third party I2C driver to enable it to perform work
> +      arounds for the specific hardware version.  This value should
> +      match the value in the ACPI _HRV tag.
> +
> +  The third party I2C driver uses relative addressing to abstract
> +  the platform specific details of the I2C device.  Using an
> +  example I2C device containing an accelerometer and a magnetometer
> +  which consumes two slave addresses, one for each logic block.  The
> +  third party I2C driver writer may choose to write two drivers, one
> +  for each block of logic, in which case each driver refers to the
> +  single I2C slave address using the relative value of zero (0).
> +  However if the third party I2C driver writer chooses to write a
> +  single driver which consumes multiple slave addresses then the
> +  third party I2C driver writer needs to convey the order of the
> +  I2C slave address entries in the slave address array to the
> +  platform software designer.  For the example:
> +
> +      0: Accelerometer
> +
> +      1: Magnetometer
> +
> +  The platform hardware designer picks the actual slave addresses
> +  from the I2C device's data sheet and provides this information
> +  to the platform software designer.  The platform software designer
> +  then places the slave addresses into the slave address array in the
> +  order specified by the third party I2C driver writer.  The third
> +  party driver I2C writer then indirectly references this array by
> +  specifying the index value as the relative slave address.  The
> +  relative value always starts at zero (0) and its maximum value is
> +  the number of entries in slave address array minus one.
> +
> +  The slave address is specified as a 32-bit integer to allow room
> +  for future slave address expansion.  Only the port driver knows
> +  the maximum slave address value.  All other drivers and
> +  applications must look for the EFI_NOT_FOUND status for the
> +  indication that the maximum slave address was exceeded.
> +
> +  \section I2cBusDriver         I2C Bus Driver
> +
> +  This layer is platform, host controller, and I2C chip independent.
> +
> +  The I2C bus driver creates a handle for each of the I2C devices
> +  described within the platform driver.  The I2C controller's device
> +  path is extended with the device path node provided by the platform
> +  driver and attached to the handle.  The third party I2C device driver
> +  uses the device path to determine if it may connect.  For ACPI nodes,
> +  the third party I2C driver should use the CID or CidString value.
> +
> +  The I2C bus driver validates the relative address for the I2C device
> +  and then converts the relative value to an actual I2C slave address.
> +  The request is then passed to the I2C host driver.
> +
> +  \section I2cHostDriver        I2C Host Driver
> +
> +  This layer is platform, host controller, and I2C chip independent.
> +
> +  N.B. For proper operation of the I2C bus, only the I2C bus driver
> +  and the I2C test application should connect to the I2C host driver
> +  via the EFI_I2C_HOST_DRIVER_PROTOCOL.
> +
> +  The I2C host driver may access any device on the I2C bus.  The I2C
> +  host driver has the following responsibilities:
> +
> +  1.  Limits the number of requests to the I2C port driver to one.
> +      The I2C host driver holds on to additional requests until the
> +      I2C port driver is available to process the request.  The I2C
> +      requests are issued in FIFO order to the I2C port driver.
> +
> +  2.  Enable the proper I2C bus configuration before starting the
> +      I2C request on the I2C port driver
> +
> +  I2C devices are addressed as the tuple: BusConfiguration:SlaveAddress.
> +  I2C bus configuration zero (0) is the portion of the I2C bus that
> +  connects to the host controller.  The bus configuration specifies
> +  the control values for the switches and multiplexers in the I2C bus.
> +  After the switches and multiplexers are properly configured, the I2C
> +  controller uses the slave address to access the requested I2C device.
> +
> +  Since the I2C driver stack supports asynchronous operations this
> +  layer maintains a queue of I2C requests until the I2C controller
> +  is available them.  When a request reaches the head of the queue
> +  the necessary bus configuration is enabled and then the request
> +  is sent to the I2C port driver.
> +
> +  \section I2cPortDriver        I2C Port Driver
> +
> +  This layer is I2C controller specific but platform independent.
> +
> +  This layer manipulates the I2C controller to perform an operation
> +  on the I2C bus.  This layer does not configure the I2C bus so it
> +  is up to the caller to ensure that the I2C bus is in the proper
> +  configuration before issuing the I2C request.
> +
> +  This layer typically needs the following information:
> +
> +  1.  Host controller address
> +  2.  Controller's input clock frequency
> +
> +  Depending upon the I2C controller, more data may be necessary.
> +  This layer may use any method to get these values: hard coded
> +  values, PCD values, or may choose to communicate with the platform
> +  layer using an undefined mechanism to get these values.
> +
> +  If the I2C port driver requires data from the platform driver then
> +  the I2C port driver writer needs to provide the platform interface
> +  details to the platform software designer.
> +
> +  \section I2cPlatformDriver    I2C Platform Driver
> +
> +  When enabling access to I2C devices within UEFI, this driver
> +  installs the EFI_I2C_ACPI_PROTOCOL to provide the I2C device
> +  descriptions to the I2C bus driver using the EFI_I2C_DEVICE
> +  structure.  These descriptions include the bus configuration
> +  number required for the I2C device, the slave address array
> +  and the device path.
> +
> +  The EFI_I2C_BUS_CONFIGURATION_MANAGEMENT protocol is optional.
> +  This protocol needs to be specified under the following conditions:
> +
> +  1.  The I2C bus must operate at a frequency greater than 100 KHz
> +  2.  The I2C bus contains switches or multiplexers.
> +
> +  The EFI_I2C_BUS_CONFIGURATION_MANAGEMENT protocol enables the
> +  I2C host driver to call into the I2C platform driver to enable
> +  a specific I2C bus configuration and set its maximum clock speed.
> +
> +  The platform software designer collects the data requirements
> +  from third party I2C driver writers, the I2C controller
> +  driver writer, the EFI_I2C_ACPI_PROTOCOL and
> +  EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL.  The
> platform
> +  software designer gets the necessary data from the platform
> +  hardware designer.  The platform software designer then builds
> +  the data structures and implements the necessary routines to
> +  construct the I2C platform driver.
> +
> +  \section I2cSwitches          Switches and Multiplexers
> +
> +  There are some I2C switches and I2C multiplexers where the control
> +  is done via I2C commands.  When the control inputs come via the
> +  same I2C bus that is being configured then the platform driver must
> +  use the EFI_I2C_MASTER_PROTOCOL that is passed to the platform
> +  driver.  While the I2C host driver makes the call to the I2C
> +  platform driver to configure the bus, the host driver keeps the
> +  I2C port driver idle, to allow the I2C platform driver preform
> +  the necessary configuration operations.
> +
> +  If however the configuration control is done via and I2C device
> +  connected to a different I2C bus (host controller), then it is
> +  possible for the platform software designer may choose between
> +  the following:
> +
> +  1.  Call into a third party I2C driver to manipulate the I2C
> +      bus control device.
> +  2.  Call into the EFI_I2C_BUS_PROTOCOL if no third party I2C
> +      driver exists for the I2C bus control device
> +  3.  Call into the EFI_I2C_HOST_PROTOCOL if the platform does
> +      not expose the I2C bus control device.
> +
> +**/
> +
> +#ifndef __I2C_MASTER_H__
> +#define __I2C_MASTER_H__
> +
> +/**
> +  Declare the forward references
> +
> +**/
> +typedef struct _EFI_I2C_MASTER_PROTOCOL
> EFI_I2C_MASTER_PROTOCOL;  ///<  I2C master protocol
> +
> +///
> +/// I2C device operation
> +///
> +/// This structure provides the information necessary for an operation
> +/// on an I2C device
> +///
> +typedef struct {
> +  ///
> +  /// Number of bytes to send to the I2C device
> +  ///
> +  UINT32 WriteBytes;
> +
> +  ///
> +  /// Number of bytes to read, set to zero for write only operations
> +  ///
> +  UINT32 ReadBytes;
> +
> +  ///
> +  /// Address of the buffer containing the data to send to the I2C device.
> +  /// The WriteBuffer must be at least WriteBytes in length.
> +  ///
> +  UINT8 *WriteBuffer;
> +
> +  ///
> +  /// Address of the buffer to receive data from the I2C device. Use NULL
> +  /// for write only operations.  The ReadBuffer must be at least ReadBytes
> +  /// in length.
> +  ///
> +  UINT8 *ReadBuffer;
> +
> +  ///
> +  /// Timeout for the I2C operation in 100 ns units
> +  ///
> +  UINT32 Timeout;
> +} EFI_I2C_REQUEST_PACKET;
> +
> +
> +/**
> +  Set the I2C controller bus clock frequency.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +
> +  The software and controller do a best case effort of using the specified
> +  frequency for the I2C bus.  If the frequency does not match exactly then
> +  the controller will use a slightly lower frequency to avoid
> +  exceeding the operating conditions for any of the I2C devices on the bus.
> +  For example if 400 KHz was specified and the controller's divide network
> +  only supports 402 KHz or 398 KHz then the controller would be set to 398
> +  KHz.  However if the desired frequency is 400 KHz and the controller only
> +  supports 1 MHz and 100 KHz then this routine would return
> EFI_UNSUPPORTED.
> +
> +  @param[in] This           Address of an EFI_I2C_MASTER_PROTOCOL
> +                            structure
> +  @param[in] BusClockHertz  New I2C bus clock frequency in Hertz
> +
> +  @retval EFI_SUCCESS       The bus frequency was set successfully.
> +  @retval EFI_UNSUPPORTED   The controller does not support this
> frequency.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_I2C_MASTER_BUS_FREQUENCY_SET) (
> +  IN CONST EFI_I2C_MASTER_PROTOCOL *This,
> +  IN UINTN BusClockHertz
> +  );
> +
> +/**
> +  Reset the I2C controller and configure it for use
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +
> +  The I2C controller is reset and the I2C bus frequency is set to 100 KHz.
> +
> +  @param[in]     This       Address of an EFI_I2C_MASTER_PROTOCOL
> +                            structure
> +
> +**/
> +typedef
> +VOID
> +(EFIAPI *EFI_I2C_MASTER_RESET) (
> +  IN CONST EFI_I2C_MASTER_PROTOCOL *This
> +  );
> +
> +/**
> +  Start an I2C operation on the host controller
> +
> +  This routine must be called at or below TPL_NOTIFY.  For synchronous
> +  requests this routine must be called at or below TPL_CALLBACK.
> +
> +  This function initiates an I2C operation on the controller.
> +
> +  The operation is performed by selecting the I2C device with its slave
> +  address and then sending all write data to the I2C device.  If read data
> +  is requested, a restart is sent followed by the slave address and then
> +  the read data is clocked into the I2C controller and placed in the read
> +  buffer.  When the operation completes, the status value is returned and
> +  then the event is set.
> +
> +  N.B. The typical consumer of this API is the I2C host driver.
> +  Extreme care must be taken by other consumers of this API to
> +  prevent confusing the third party I2C drivers due to a state
> +  change at the I2C device which the third party I2C drivers did
> +  not initiate.  I2C platform drivers may use this API within
> +  these guidelines.
> +
> +  N.B. This API supports only one operation, no queuing support
> +  exists at this layer.  This API assumes that the I2C bus is in
> +  the correct configuration for the I2C request.
> +
> +  @param[in] This           Address of an EFI_I2C_MASTER_PROTOCOL
> +                            structure
> +  @param[in] SlaveAddress   Address of the device on the I2C bus.
> +  @param[in] Event          Event to set for asynchronous operations,
> +                            NULL for synchronous operations
> +  @param[in] RequestPacket  Address of an EFI_I2C_REQUEST_PACKET
> +                            structure describing the I2C operation
> +  @param[out] I2cStatus     Optional buffer to receive the I2C operation
> +                            completion status
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval EFI_ABORTED           The request did not complete because the
> driver
> +                                was shutdown.
> +  @retval EFI_BAD_BUFFER_SIZE   The WriteBytes or ReadBytes buffer size
> is too large.
> +  @retval EFI_DEVICE_ERROR      There was an I2C error (NACK) during the
> operation.
> +                                This could indicate the slave device is not present.
> +  @retval EFI_INVALID_PARAMETER RequestPacket is NULL
> +  @retval EFI_INVALID_PARAMETER TPL is too high
> +  @retval EFI_NOT_FOUND         SlaveAddress exceeds maximum address
> +  @retval EFI_NOT_READY         I2C bus is busy or operation pending, wait for
> +                                the event and then read status pointed to by
> +                                the request packet.
> +  @retval EFI_NO_RESPONSE       The I2C device is not responding to the
> +                                slave address.  EFI_DEVICE_ERROR may also be
> +                                returned if the controller cannot distinguish
> +                                when the NACK occurred.
> +  @retval EFI_OUT_OF_RESOURCES  Insufficient memory for I2C operation
> +  @retval EFI_TIMEOUT           The transaction did not complete within an
> internally
> +                                specified timeout period.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_I2C_MASTER_START_REQUEST) (
> +  IN CONST EFI_I2C_MASTER_PROTOCOL *This,
> +  IN UINTN SlaveAddress,
> +  IN EFI_EVENT Event OPTIONAL,
> +  IN CONST EFI_I2C_REQUEST_PACKET *RequestPacket,
> +  OUT EFI_STATUS *I2cStatus OPTIONAL
> +  );
> +
> +///
> +/// I2C master mode protocol
> +///
> +/// This protocol manipulates the I2C host controller to perform transactions
> as a
> +/// master on the I2C bus using the current state of any switches or
> multiplexers
> +/// in the I2C bus.
> +///
> +struct _EFI_I2C_MASTER_PROTOCOL {
> +  ///
> +  /// Set the clock frequency for the I2C bus
> +  ///
> +  EFI_I2C_MASTER_BUS_FREQUENCY_SET BusFrequencySet;
> +
> +  ///
> +  /// Reset the I2C host controller
> +  ///
> +  EFI_I2C_MASTER_RESET Reset;
> +
> +  ///
> +  /// Start an I2C transaction in master mode on the host controller
> +  ///
> +  EFI_I2C_MASTER_START_REQUEST StartRequest;
> +
> +  ///
> +  /// The maximum number of bytes the I2C host controller
> +  /// is able to receive from the I2C bus.
> +  ///
> +  UINT32 MaximumReceiveBytes;
> +
> +  ///
> +  /// The maximum number of bytes the I2C host controller
> +  /// is able to send on the I2C bus.
> +  ///
> +  UINT32 MaximumTransmitBytes;
> +
> +  ///
> +  /// The maximum number of bytes in the I2C bus transaction.
> +  ///
> +  UINT32 MaximumTotalBytes;
> +};
> +
> +///
> +/// GUID for the EFI_I2C_MASTER_PROTOCOL
> +///
> +extern EFI_GUID gEfiI2cMasterProtocolGuid;
> +
> +#endif  //  __I2C_MASTER_H__
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cSlave.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cSlave.h
> new file mode 100644
> index 0000000000..64cb2b7398
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cSlave.h
> @@ -0,0 +1,194 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +**/
> +
> +#ifndef __I2C_SLAVE_H__
> +#define __I2C_SLAVE_H__
> +
> +#include <Protocol/I2cHostMcg.h>
> +
> +/**
> +  Declare the forward references
> +
> +**/
> +typedef struct _EFI_I2C_SLAVE_PROTOCOL    EFI_I2C_SLAVE_PROTOCOL;
> ///<  I2C slave protocol
> +
> +/**
> +  The I2C controller received a data byte from the
> +  I2C msster.
> +
> +  @param[in] Context        The value passed to the slave enable routine.
> +  @param[in] NumberOfBytes  Number of data bytes received
> +  @param[in] Data           Buffer containing the received data bytes
> +
> +  @retval EFI_SUCCESS       ACK the data byte
> +  @retval EFI_UNSUPPORTED   NACK the data byte
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_I2C_SLAVE_RECEIVE_DATA) (
> +  IN VOID *Context,
> +  IN UINTN NumberOfBytes,
> +  IN CONST UINT8 *Data
> +  );
> +
> +/**
> +  The I2C controller received the start bit from the
> +  I2C master.
> +
> +  @param[in] Context        The value passed to the slave enable routine.
> +
> +**/
> +typedef
> +VOID
> +(EFIAPI *EFI_I2C_SLAVE_RECEIVE_START) (
> +  IN VOID *Context,
> +  IN UINTN BytesSent,
> +  IN EFI_STATUS Status
> +  );
> +
> +/**
> +  The I2C controller received the stop bit from the
> +  I2C master.
> +
> +  @param[in] Context        The value passed to the slave enable routine.
> +  @param[in] BytesSent      Number of bytes successfully ACKed by the
> +                            I2C master.  This is a hint, not all I2C
> +                            controllers support the ability to return
> +                            the number of bytes sent.  When it is not
> +                            possible, the port driver returns zero.
> +  @param[in] Status         <ul>
> +                              <li>EFI_SUCCESS - All of the data was successfully sent</li>
> +                              <li>EFI_ABORTED - The controller was reset</li>
> +                              <li>EFI_DEVICE_ERROR - A NACK was received when sending
> the data.</li>
> +                              <li>EFI_END_OF_FILE - The stop bit was received before all
> of
> +                                the data was sent.</li>
> +                            </ul>
> +
> +**/
> +typedef
> +VOID
> +(EFIAPI *EFI_I2C_SLAVE_RECEIVE_STOP) (
> +  IN VOID *Context,
> +  IN UINTN BytesSent,
> +  IN EFI_STATUS Status
> +  );
> +
> +/**
> +  Enable or disable I2C slave operation.
> +
> +  The ReceiveData callback allows the port driver to return data
> +  to the driver or application handling slave mode operations.  This
> +  is data that a remote master has sent to the local I2C controller.
> +  The data may be returned one byte at a time if the controller supports
> +  the ability to ACK/NACK on each receive byte.  If not, a block of
> +  data may be returned by the I2C port driver and the ACK/NACK status
> +  is used only as a hint for the port driver.
> +
> +  The slave mode driver or application should buffer the data until
> +  either ReceiveStart or ReceiveStop is called.  At that time all of
> +  the data is received and the command may be processed.
> +
> +  ReceiveStart is called when the I2C master is expecting a response.
> +  After processing the command, but before sending the response the
> +  slave driver or application should mark the command as processed to
> +  avoid processing it a second time when ReceiveStop is called.  The
> +  slave driver or application then calls SendData to send to queue the
> +  response data for transmission.  The data must remain valid in the
> +  WriteBuffer until ReceiveStop is called.
> +
> +  ReceiveStop is called when the stop bit is received on the I2C bus.
> +  The slave driver or application starts processing the command if an
> +  command data is pending in the slave driver's or application's buffer.
> +  The BytesSent value is a hint to the slave driver or application as
> +  to how much data was returned to the I2C master.  If the controller
> +  does not provide this level of support then this value is set to zero.
> +
> +  @param[in] This           Address of an EFI_I2C_SLAVE_PROTOCOL
> +                            structure
> +  @param[in] SlaveAddress   Slave address for the I2C controller
> +  @param[in] Context        Address of a context structure for use when
> +                            calling ReceiveData or ReceiveStop
> +  @param[in] ReceiveData    Called by the I2C port driver as data bytes
> +                            are received from the master.  Response status
> +                            indicates if the byte is ACKed or NACKed. When
> +                            data is passed back a byte at a time, the port
> +                            driver must hold the clock until this callback
> +                            returns.
> +  @param[in] ReceiveStart   Called when the I2C controller receives a start
> bit.
> +  @param[in] ReceiveStop    Called after all of the data bytes are
> +                            received.
> +
> +  @retval EFI_SUCCESS       Slave operation is enabled on the controller.
> +  @retval EFI_UNSUPPORTED   The controller does not support this
> frequency.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_I2C_SLAVE_ENABLE) (
> +  IN CONST EFI_I2C_SLAVE_PROTOCOL *This,
> +  IN UINT32 SlaveAddress,
> +  IN VOID *Context,
> +  IN EFI_I2C_SLAVE_RECEIVE_DATA ReceiveData,
> +  IN EFI_I2C_SLAVE_RECEIVE_START ReceiveStart,
> +  IN EFI_I2C_SLAVE_RECEIVE_STOP ReceiveStop
> +  );
> +
> +/**
> +  Send data to the I2C master.
> +
> +  Port drivers may implement this as a blocking or non-blocking call.
> +  The data in the write buffer must remain valid until ReceiveStop or
> +  ReceiveStart is called indicating that the I2C master has terminated
> +  the transfer.
> +
> +  @param[in] This         Address of an EFI_I2C_SLAVE_PROTOCOL
> +                          structure
> +  @param[in] WriteBytes   Number of bytes to write
> +  @param[in] WriteBuffer  Buffer containing the data to send
> +
> +  @retval EFI_SUCCESS           Data waiting for master access.
> +  @retval EFI_INVALID_PARAMETER WriteBuffer is NULL or WriteBytes
> +                                is zero.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_I2C_SLAVE_SEND) (
> +  IN CONST EFI_I2C_SLAVE_PROTOCOL *This,
> +  IN UINTN WriteBytes,
> +  IN CONST UINT8 *WriteBuffer
> +  );
> +
> +///
> +/// I2C slave protocol
> +///
> +/// The port driver publishes this protocol when slave mode is
> +/// supported by the controller.
> +///
> +struct _EFI_I2C_SLAVE_PROTOCOL {
> +  ///
> +  /// Enable or disable I2C slave operation
> +  ///
> +  EFI_I2C_SLAVE_ENABLE SlaveEnable;
> +
> +  ///
> +  /// Send data to the I2C master
> +  ///
> +  EFI_I2C_SLAVE_SEND SendData;
> +};
> +
> +///
> +/// GUID for the EFI_I2C_SLAVE_PROTOCOL
> +///
> +extern EFI_GUID gEfiI2cSlaveProtocolGuid;
> +
> +#endif  //  __I2C_SLAVE_H__
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpc83627Policy.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpc83627Policy.h
> new file mode 100644
> index 0000000000..62d026f133
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpc83627Policy.h
> @@ -0,0 +1,92 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  LpcWpc83667Policy.h
> +
> +Abstract:
> +
> +  Protocol used for WPC83627 Policy definition.
> +-------------------------------------------------------------------------------
> +   Rev   Date<MM/DD/YYYY>    Name    Description
> +  -------------------------------------------------------------------------------
> +  R01   < 4/22/2011>         LB     Update driver for Sio83627UGH support.
> +  -------------------------------------------------------------------------------
> +**/
> +
> +#ifndef _WPC83627_POLICY_PROTOCOL_H_
> +#define _WPC83627_POLICY_PROTOCOL_H_
> +
> +EFI_FORWARD_DECLARATION (EFI_WPC83627_POLICY_PROTOCOL);
> +
> +#define EFI_WPC83627_POLICY_PROTOCOL_GUID \
> +  { \
> +    0xd3ecc567, 0x9fd5, 0x44c1, 0x86, 0xcf, 0x5d, 0xa7, 0xa2, 0x4f, 0x4b, 0x5d
> \
> +  }
> +
> +#define EFI_WPC83627_COM1_ENABLE          0x01
> +#define EFI_WPC83627_COM2_ENABLE          0x01
> +
> +#define EFI_WPC83627_COM3_ENABLE          0x01
> +#define EFI_WPC83627_COM4_ENABLE          0x01
> +
> +#define EFI_WPC83627_LPT1_ENABLE          0x01
> +#define EFI_WPC83627_LPT1_ENABLE          0x01
> +#define EFI_WPC83627_FDD_ENABLE           0x01
> +#define EFI_WPC83627_FDD_WRITE_ENABLE     0x01
> +#define EFI_WPC83627_PS2_KBC_ENABLE       0x01
> +#define EFI_WPC83627_ECIR_ENABLE	  0x01
> +
> +#define EFI_WPC83627_COM1_DISABLE         0x00
> +#define EFI_WPC83627_COM2_DISABLE         0x00
> +
> +#define EFI_WPC83627_COM3_DISABLE         0x00
> +#define EFI_WPC83627_COM4_DISABLE         0x00
> +
> +#define EFI_WPC83627_LPT1_DISABLE         0x00
> +#define EFI_WPC83627_FDD_DISABLE          0x00
> +#define EFI_WPC83627_FDD_WRITE_PROTECT    0x00
> +#define EFI_WPC83627_PS2_KBC_DISABLE      0x00
> +#define EFI_WPC83627_ECIR_DISABLE         0x00
> +#define EFI_WPC83627_RESERVED_DEFAULT     0x00
> +
> +typedef struct {
> +  UINT16  Com1               :1;             // 0 = Disable, 1 = Enable
> +  UINT16  Lpt1               :1;             // 0 = Disable, 1 = Enable
> +  UINT16  Floppy             :1;             // 0 = Disable, 1 = Enable
> +  UINT16  FloppyWriteProtect :1;             // 0 = Write Protect, 1 = Write Enable
> +  UINT16  Port80             :1;             // 0 = Disable, 1 = Enable
> +  UINT16  CIR                :1;             // CIR enable or disable
> +  UINT16  Ps2Keyboard        :1;             // 0 = Disable, 1 = Enable
> +  UINT16  Ps2Mouse           :1;             // 0 = Disable, 1 = Enable
> +  UINT16  Com2               :1;             // 0 = Disable, 1 = Enable
> +
> +  UINT16  Com3               :1;             // 0 = Disable, 1 = Enable
> +  UINT16  Com4               :1;             // 0 = Disable, 1 = Enable
> +
> +  UINT16  Dac                :1;             // 0 = Disable, 1 = Enable
> +  UINT16  Rsvd               :6;
> +} EFI_WPC83627_DEVICE_ENABLES;
> +
> +typedef enum {
> +  LptModeOutput,
> +  LptModeBiDirectional,
> +  LptModeEpp,
> +  LptModeEcp
> +} EFI_LPT_MODE;
> +
> +typedef struct _EFI_WPC83627_POLICY_PROTOCOL {
> +  EFI_WPC83627_DEVICE_ENABLES DeviceEnables;
> +  EFI_LPT_MODE              LptMode;
> +} EFI_WPC83627_POLICY_PROTOCOL;
> +
> +extern EFI_GUID gEfiLpcWpc83627PolicyProtocolGuid;
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpce791Policy.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpce791Policy.h
> new file mode 100644
> index 0000000000..1b2459e54a
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpce791Policy.h
> @@ -0,0 +1,55 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  LpcWpce791Policy.h
> +
> +Abstract:
> +
> +  Protocol used for WPCE791 Policy definition.
> +
> +**/
> +
> +#ifndef _WPCE791_POLICY_PROTOCOL_H_
> +#define _WPCE791_POLICY_PROTOCOL_H_
> +
> +
> +#define EFI_WPCE791_POLICY_PROTOCOL_GUID \
> +  { \
> +    0xab2bee2f, 0xc1a6, 0x4399, 0x85, 0x3d, 0xc0, 0x7c, 0x77, 0x4f, 0xfd, 0xd \
> +  }
> +
> +#define EFI_WPCE791_PS2_KEYBOARD_ENABLE       0x01
> +#define EFI_WPCE791_PS2_KEYBOARD_DISABLE      0x00
> +
> +#define EFI_WPCE791_PS2_MOUSE_ENABLE       0x01
> +#define EFI_WPCE791_PS2_MOUSE_DISABLE      0x00
> +
> +typedef struct {
> +  UINT16  Com1               :1;             // 0 = Disable, 1 = Enable
> +  UINT16  Lpt1               :1;             // 0 = Disable, 1 = Enable
> +  UINT16  Floppy             :1;             // 0 = Disable, 1 = Enable
> +  UINT16  FloppyWriteProtect :1;             // 0 = Write Protect, 1 = Write Enable
> +  UINT16  Port80             :1;             // 0 = Disable, 1 = Enable
> +  UINT16  CIR                :1;             // CIR enable or disable
> +  UINT16  Ps2Keyboard        :1;             // 0 = Disable, 1 = Enable
> +  UINT16  Ps2Mouse           :1;             // 0 = Disable, 1 = Enable
> +  UINT16  Com2               :1;             // 0 = Disable, 1 = Enable
> +  UINT16  Dac                :1;             // 0 = Disable, 1 = Enable
> +  UINT16  Rsvd               :6;
> +} EFI_WPCE791_DEVICE_ENABLES;
> +
> +typedef struct _EFI_WPCE791_POLICY_PROTOCOL {
> +  EFI_WPCE791_DEVICE_ENABLES DeviceEnables;
> +} EFI_WPCE791_POLICY_PROTOCOL;
> +
> +extern EFI_GUID gEfiLpcWpce791PolicyProtocolGuid;
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/MmioDevice.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/MmioDevice.h
> new file mode 100644
> index 0000000000..3c0eb5201a
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/MmioDevice.h
> @@ -0,0 +1,84 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +**/
> +
> +#ifndef __MMIO_DEVICE_H__
> +#define __MMIO_DEVICE_H__
> +
> +//
> +// Protocol to define for the MMIO device
> +//
> +typedef struct {
> +  //
> +  // Address of a GUID
> +  //
> +  EFI_GUID *Guid;
> +
> +  //
> +  // Context for the protocol
> +  //
> +  VOID *Context;
> +} EFI_MMIO_DEVICE_PROTOCOL_ITEM;
> +
> +
> +typedef struct _EFI_MMIO_DEVICE_PROTOCOL
> EFI_MMIO_DEVICE_PROTOCOL;
> +
> +//
> +//  The MMIO device protocol defines a memory mapped I/O device
> +//  for use by the system.
> +//
> +struct _EFI_MMIO_DEVICE_PROTOCOL {
> +  //
> +  // Pointer to an ACPI_EXTENDED_HID_DEVICE_PATH structure
> +  // containing HID/HidStr and CID/CidStr values.
> +  //
> +  // See the note below associated with the UnitIdentification
> +  // field.
> +  //
> +  CONST ACPI_EXTENDED_HID_DEVICE_PATH *AcpiPath;
> +
> +  //
> +  // Allow the use of a shared template for the AcpiPath.
> +  //
> +  // If this value is non-zero UID value then the AcpiPath must
> +  // be a template which contains only the HID/HidStr and CID/CidStr
> +  // values.  The UID/UidStr values in the AcpiPath must be zero!
> +  //
> +  // If this value is zero then the AcpiPath is not shared and
> +  // must contain either a non-zero UID value or a UidStr value.
> +  //
> +  UINT32 UnitIdentification;
> +
> +  //
> +  // Hardware revision - ACPI _HRV value
> +  //
> +  UINT32 HardwareRevision;
> +
> +  //
> +  // Pointer to a data structure containing the controller
> +  // resources and configuration.  At a minimum this points
> +  // to an EFI_PHYSICAL_ADDRESS for the base address of the
> +  // MMIO device.
> +  //
> +  CONST VOID *DriverResources;
> +
> +  //
> +  // Number of protocols in the array
> +  //
> +  UINTN ProtocolCount;
> +
> +  //
> +  // List of protocols to define
> +  //
> +  CONST EFI_MMIO_DEVICE_PROTOCOL_ITEM *ProtocolArray;
> +};
> +
> +extern EFI_GUID gEfiMmioDeviceProtocolGuid;
> +
> +#endif  //  __MMIO_DEVICE_H__
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Observable.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Observable.h
> new file mode 100644
> index 0000000000..bc5571e6d5
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Observable.h
> @@ -0,0 +1,186 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  Observable.h
> +
> +Abstract:
> +
> +  Interface and GUID definitions for Observable protocol.
> +
> +**/
> +
> +#ifndef _OBSERVABLE_PROTOCOL_H_
> +#define _OBSERVABLE_PROTOCOL_H_
> +
> +//
> +// GUID Definitions
> +//
> +#define OBSERVABLE_PROTOCOL_GUID \
> +  { \
> +    0xe227c522, 0xd5fe, 0x4a53, 0x87, 0xb1, 0x0f, 0xbe, 0x57, 0x0f, 0x98, 0xe9
> \
> +  }
> +
> +extern EFI_GUID gObservableProtocolGuid;
> +
> +typedef struct _OBS_OBSERVABLE_PROTOCOL
> OBS_OBSERVABLE_PROTOCOL;
> +
> +//
> +// Interface Definitions
> +//
> +
> +/**
> +  Remove all observables.
> +
> +  Remove all observable guids and all interfaces subscribed to them.
> +
> +  @param   VOID          No Parameters.
> +
> +  @return  EFI_SUCCESS   Successfully removed all observables and
> subscribed interfaces.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *OBS_REMOVE_ALL_OBSERVABLES) (
> +  VOID
> +  );
> +
> +/**
> +  Interface for notification functions.
> +
> +  Functions that are to be used as callbacks must inherit this interface in
> order to be used properly.
> +
> +  @param   VOID*   Data  Parameter context to be passed to the notification
> function.
> +
> +  @return  EFI_STATUS    Varies depending on implementation.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *OBS_CALLBACK) (
> +  IN  OUT VOID*   Data
> +  );
> +
> +/**
> +  Subscribe an interface with an observable guid.
> +
> +  Use this to register a callback function with a guid. The function provided
> by CallbackInterface will be executed
> +  whenever the appropriate observable instance specified by
> ReferenceGuid calls Publish.
> +
> +  @param   EFI_GUID                ReferenceGuid       The observable guid that
> the callback interface will subscribe to.
> +           OBS_NOTIFY_INTERFACE    CallbackInterface   A pointer to the
> function that is subscribing to the observable.
> +
> +  @return  EFI_SUCCESS           Successfully subscribed the interface to the
> observable guid.
> +           EFI_NOT_FOUND         No match could be found between the provided
> guid and existing observables.
> +           EFI_OUT_OF_RESOURCES  Could not subscribe to this observer due to
> resource limitations.
> +           EFI_INVALID_PARAMETER Interface is already subscribed to this
> observer.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *OBS_SUBSCRIBE) (
> +  IN      EFI_GUID        ReferenceGuid,
> +  IN      OBS_CALLBACK    CallbackInterface
> +  );
> +
> +/**
> +  Unsubscribe an interface with an observable guid.
> +
> +  Use this to remove an interface from the callback list associated with an
> observable guid.
> +
> +  @param   EFI_GUID                ReferenceGuid   The observable guid to
> unsubscribe the interface from.
> +           OBS_NOTIFY_INTERFACE    NotifyCallback  A pointer to the interface
> that is being unsubscribed.
> +
> +  @return  EFI_SUCCESS           Successfully unsubscribed the interface from
> the observable guid.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *OBS_UNSUBSCRIBE) (
> +  IN      EFI_GUID        ReferenceGuid,
> +  IN      OBS_CALLBACK    CallbackInterface
> +  );
> +
> +/**
> +  Notify observing functions.
> +
> +  Use this to notify all functions who are subscribed to the guid specified by
> ReferenceGuid.
> +
> +  @param   EFI_GUID          ReferenceGuid   The observable guid that
> contains the the list of interfaces to be notified.
> +           VOID*             Data            Parameter context to be passed to the
> notification function.
> +
> +  @return  EFI_SUCCESS       Successfully notified all observers listening to
> this guid.
> +           EFI_NOT_FOUND     No match could be found between the provided
> guid and existing observables.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *OBS_PUBLISH) (
> +  IN      EFI_GUID        ReferenceGuid,
> +  IN  OUT VOID*           Data
> +  );
> +
> +/**
> +  Creates a new observable.
> +
> +  Create a new observable that can be observed with the use of Subscribe
> function.
> +
> +  @param   EFI_GUID              ReferenceGuid   The observable guid to add.
> +
> +  @return  EFI_SUCCESS           Successfully added observable.
> +           EFI_INVALID_PARAMETER Observable already exists.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *OBS_ADD_OBSERVABLE) (
> +  IN      EFI_GUID        ReferenceGuid
> +  );
> +
> +/**
> +  Remove an observable.
> +
> +  Remove an observable so that it can no longer be subscribed to. In
> addition, unsubscribe any functions
> +  that are subscribed to this guid.
> +
> +  @param   EFI_GUID              ReferenceGuid   The observable guid to remove.
> +
> +  @return  EFI_SUCCESS           Successfully removed observable.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *OBS_REMOVE_OBSERVABLE) (
> +  IN      EFI_GUID        ReferenceGuid
> +  );
> +
> +//
> +// Protocol Definitions
> +//
> +typedef struct _OBS_LEAF {
> +  OBS_CALLBACK      Observer;
> +  struct _OBS_LEAF* Next;
> +} OBS_LEAF;
> +
> +typedef struct _OBS_TREE {
> +  EFI_GUID              ObservableGuid;
> +  OBS_LEAF*             Leaf;
> +  struct _OBS_TREE*     Next;
> +} OBS_TREE;
> +
> +struct _OBS_OBSERVABLE_PROTOCOL {
> +  OBS_ADD_OBSERVABLE          AddObservable;
> +  OBS_REMOVE_OBSERVABLE       RemoveObservable;
> +  OBS_SUBSCRIBE               Subscribe;
> +  OBS_UNSUBSCRIBE             Unsubscribe;
> +  OBS_PUBLISH                 Publish;
> +  OBS_REMOVE_ALL_OBSERVABLES  RemoveAllObservables;
> +} ;
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformGopPolicy.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformGopPolicy.h
> new file mode 100644
> index 0000000000..ef2ad3d558
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformGopPolicy.h
> @@ -0,0 +1,68 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +--*/
> +
> +/** @file
> +**/
> +
> +#ifndef _PLATFORM_GOP_POLICY_PROTOCOL_H_
> +#define _PLATFORM_GOP_POLICY_PROTOCOL_H_
> +
> +#define EFI_PLATFORM_GOP_POLICY_PROTOCOL_GUID \
> +  { 0xec2e931b, 0x3281, 0x48a5, 0x81, 0x7, 0xdf, 0x8a, 0x8b, 0xed, 0x3c, 0x5d }
> +
> +#define EFI_BMP_IMAGE_GUID \
> +  { 0x878AC2CC, 0x5343, 0x46F2, 0xB5, 0x63, 0x51, 0xF8, 0x9D, 0xAF, 0x56,
> 0xBA }
> +
> +#define PLATFORM_GOP_POLICY_PROTOCOL_REVISION_01 0x01
> +#define PLATFORM_GOP_POLICY_PROTOCOL_REVISION_02 x0222
> +
> +#pragma pack(1)
> +
> +typedef enum {
> +  LidClosed,
> +  LidOpen,
> +  LidStatusMax
> +} LID_STATUS;
> +
> +typedef enum {
> +  Docked,
> +  UnDocked,
> +  DockStatusMax
> +} DOCK_STATUS;
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *GET_PLATFORM_LID_STATUS) (
> +   OUT LID_STATUS *CurrentLidStatus
> +);
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *GET_VBT_DATA) (
> +   OUT EFI_PHYSICAL_ADDRESS *VbtAddress,
> +   OUT UINT32 *VbtSize
> +);
> +
> +#pragma pack()
> +
> +typedef struct _PLATFORM_GOP_POLICY_PROTOCOL {
> +  UINT32                             Revision;
> +  GET_PLATFORM_LID_STATUS            GetPlatformLidStatus;
> +  GET_VBT_DATA                       GetVbtData;
> +} PLATFORM_GOP_POLICY_PROTOCOL;
> +
> +//
> +// Extern the GUID for protocol users.
> +//
> +extern EFI_GUID  gPlatformGOPPolicyGuid;
> +
> +extern EFI_GUID  gBmpImageGuid;
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformIdeInit.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformIdeInit.h
> new file mode 100644
> index 0000000000..a8b6900d16
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformIdeInit.h
> @@ -0,0 +1,43 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +    PlatformIdeInit.h
> +
> +Abstract:
> +
> +    EFI Platform Ide Init Protocol
> +
> +Revision History
> +
> +**/
> +
> +#ifndef _EFI_PLATFORM_IDE_INIT_H_
> +#define _EFI_PLATFORM_IDE_INIT_H_
> +
> +//
> +// Global ID for the IDE Platform Protocol
> +//
> +#define EFI_PLATFORM_IDE_INIT_PROTOCOL_GUID \
> +  { 0x377c66a3, 0x8fe7, 0x4ee8, 0x85, 0xb8, 0xf1, 0xa2, 0x82, 0x56, 0x9e,
> 0x3b };
> +
> +EFI_FORWARD_DECLARATION (EFI_PLATFORM_IDE_INIT_PROTOCOL);
> +
> +
> +//
> +// Interface structure for the Platform IDE Init Protocol
> +//
> +typedef struct _EFI_PLATFORM_IDE_INIT_PROTOCOL {
> +  BOOLEAN                               SmartMode;
> +} EFI_PLATFORM_IDE_INIT_PROTOCOL;
> +
> +extern EFI_GUID gEfiPlatformIdeInitProtocolGuid;
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SetupMode.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SetupMode.h
> new file mode 100644
> index 0000000000..6892106a36
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SetupMode.h
> @@ -0,0 +1,79 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +    SetupMode.h
> +
> +Abstract:
> +
> +    EFI Setup Mode
> +
> +Revision History
> +
> +**/
> +
> +#ifndef _EFI_SETUP_MODE_H_
> +#define _EFI_SETUP_MODE_H_
> +
> +//
> +// Global ID for the Setup Mode
> +//
> +#define EFI_PLATFORM_BOOT_MODE_GUID \
> +  { 0xce845704, 0x1683, 0x4d38, 0xa4, 0xf9, 0x7d, 0xb, 0x50, 0x77, 0x57, 0x93 }
> +
> +#define EFI_NORMAL_SETUP_GUID \
> +  { 0xec87d643, 0xeba4, 0x4bb5, 0xa1, 0xe5, 0x3f, 0x3e, 0x36, 0xb2, 0xd,
> 0xa9 }
> +
> +#define EFI_NORMAL_SETUP_RESET_NAME L"Reset"
> +
> +enum {
> +  //
> +  // This means: "whatever reset defaults in setup does"
> +  //
> +  SetupDataResetNormal        = 0,
> +
> +  //
> +  // This means: "the defaults built into the BIOS"
> +  //
> +  SetupDataResetStandard      = 1,
> +
> +  //
> +  // This means: "the manufacturing mode defaults"
> +  //
> +  SetupDataResetManufacturing = 2,
> +
> +  //
> +  // This means: "the oem defaults"
> +  //
> +  SetupDataResetOem           = 3,
> +};
> +
> +//
> +// PlatformBootMode types
> +//
> +#define PLATFORM_NORMAL_MODE          0x01
> +#define PLATFORM_SAFE_MODE            0x02
> +#define PLATFORM_RECOVERY_MODE        0x04
> +#define PLATFORM_MANUFACTURING_MODE   0x08
> +#define PLATFORM_BACK_TO_BIOS_MODE    0x10
> +
> +extern EFI_GUID gEfiPlatformBootModeGuid;
> +extern EFI_GUID gEfiNormalSetupGuid;
> +extern CHAR16   gEfiNormalSetupName[];
> +extern CHAR16   gEfiInSetupName[];
> +extern CHAR16   gEfiSystemPasswordName[];
> +
> +typedef struct {
> +  EFI_GUID    SetupGuid;
> +  CHAR16      SetupName[0x20];          // Maximum "Setup" Name
> +  UINT32      PlatformBootMode;
> +} EFI_PLATFORM_SETUP_ID;
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SmbiosSlotPopulation.
> h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SmbiosSlotPopulation.
> h
> new file mode 100644
> index 0000000000..ac051d1759
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SmbiosSlotPopulation.
> h
> @@ -0,0 +1,47 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +    SmbiosSlotPopulation.h
> +
> +Abstract:
> +
> +    EFI SMBIOS slot structure control code.
> +
> +GUID:
> +    {EF7BF7D6-F8FF-4a76-8247-C0D0D1CC49C0}
> +    0xef7bf7d6, 0xf8ff, 0x4a76, 0x82, 0x47, 0xc0, 0xd0, 0xd1, 0xcc, 0x49, 0xc0
> +
> +Revision History
> +
> +**/
> +
> +#ifndef _EFI_SMBIOS_SLOT_POPULATION_H_
> +#define _EFI_SMBIOS_SLOT_POPULATION_H_
> +
> +//
> +// Slot Population Protocol GUID
> +//
> +#define EFI_SMBIOS_SLOT_POPULATION_GUID \
> +  { 0xef7bf7d6, 0xf8ff, 0x4a76, 0x82, 0x47, 0xc0, 0xd0, 0xd1, 0xcc, 0x49, 0xc0 }
> +
> +typedef struct {
> +  UINT16      SmbiosSlotId;   // SMBIOS Slot ID
> +  BOOLEAN     InUse;          // Does the slot have a card in it
> +  BOOLEAN     Disabled;       // Should the slot information be in SMBIOS
> +} EFI_SMBIOS_SLOT_ENTRY;
> +
> +typedef struct {
> +  UINT32                NumberOfEntries;
> +  EFI_SMBIOS_SLOT_ENTRY *SlotEntries;
> +} EFI_SMBIOS_SLOT_POPULATION_INFO;
> +
> +extern EFI_GUID gEfiSmbiosSlotPopulationGuid;
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Speaker.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Speaker.h
> new file mode 100644
> index 0000000000..9bffcad24e
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Speaker.h
> @@ -0,0 +1,65 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  Speaker.h
> +
> +Abstract:
> +
> +  EFI Speaker Interface Protocol
> +
> +Revision History
> +
> +**/
> +
> +#ifndef _EFI_SPEAKER_H
> +#define _EFI_SPEAKER_H
> +
> +//
> +// Global Id for Speaker Interface
> +//
> +#define EFI_SPEAKER_INTERFACE_PROTOCOL_GUID \
> +  { \
> +    0x400b4476, 0x3081, 0x11d6, 0x87, 0xed, 0x00, 0x06, 0x29, 0x45, 0xc3,
> 0xb9 \
> +  }
> +
> +typedef struct _EFI_SPEAKER_IF_PROTOCOL  EFI_SPEAKER_IF_PROTOCOL;
> +
> +//
> +// Beep Code
> +//
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_GENERATE_BEEP) (
> +  IN EFI_SPEAKER_IF_PROTOCOL                * This,
> +  IN     UINTN                              NumberOfBeep,
> +  IN     UINTN                              BeepDuration,
> +  IN     UINTN                              TimeInterval
> +  );
> +
> +//
> +// Set Frequency
> +//
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPEAKER_SET_FREQUENCY) (
> +  IN EFI_SPEAKER_IF_PROTOCOL               * This,
> +  IN     UINT16                            Frequency
> +  );
> +
> +//
> +// Protocol definition
> +//
> +struct _EFI_SPEAKER_IF_PROTOCOL {
> +  EFI_SPEAKER_SET_FREQUENCY SetSpeakerToneFrequency;
> +  EFI_GENERATE_BEEP         GenerateBeep;
> +} ;
> +
> +extern EFI_GUID gEfiSpeakerInterfaceProtocolGuid;
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TcoReset.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TcoReset.h
> new file mode 100644
> index 0000000000..bda47c359d
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TcoReset.h
> @@ -0,0 +1,67 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  TcoReset.h
> +
> +Abstract:
> +
> +  Protocol to communicate with ICH TCO.
> +
> +GUID Info:
> + {A6A79162-E325-4c30-BCC3-59373064EFB3}
> + 0xa6a79162, 0xe325, 0x4c30, 0xbc, 0xc3, 0x59, 0x37, 0x30, 0x64, 0xef, 0xb3);
> +
> +
> +--*/
> +
> +#ifndef _TCO_RESET_H_
> +#define _TCO_RESET_H_
> +
> +
> +#define EFI_TCO_RESET_PROTOCOL_GUID  \
> +  {0xa6a79162, 0xe325, 0x4c30, 0xbc, 0xc3, 0x59, 0x37, 0x30, 0x64, 0xef, 0xb3}
> +
> +typedef struct _EFI_TCO_RESET_PROTOCOL EFI_TCO_RESET_PROTOCOL;
> +
> +/**
> +  Enables the TCO timer to reset the system in case of a system hang.  This is
> +  used when writing the clock registers.
> +
> +  @param[in] RcrbGcsSaveValue  This is the value of the RCRB GCS register
> before it is
> +                               changed by this procedure.  This will be used to restore
> +                               the settings of this register in PpiDisableTcoReset.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_TCO_RESET_PROTOCOL_ENABLE_TCO_RESET) (
> +  IN      UINT32            *RcrbGcsSaveValue
> +  );
> +
> +/**
> +  Disables the TCO timer.  This is used after writing the clock registers.
> +
> +  @param[in] RcrbGcsRestoreValue  Value saved in PpiEnableTcoReset so
> that it can
> +                                  restored.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_TCO_RESET_PROTOCOL_DISABLE_TCO_RESET) (
> +  OUT     UINT32    RcrbGcsRestoreValue
> +  );
> +
> +typedef struct _EFI_TCO_RESET_PROTOCOL {
> +  EFI_TCO_RESET_PROTOCOL_ENABLE_TCO_RESET       EnableTcoReset;
> +  EFI_TCO_RESET_PROTOCOL_DISABLE_TCO_RESET    	DisableTcoReset;
> +} EFI_TCO_RESET_PROTOCOL;
> +
> +extern EFI_GUID gEfiTcoResetProtocolGuid;
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TpmMp.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TpmMp.h
> new file mode 100644
> index 0000000000..415e53daf2
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TpmMp.h
> @@ -0,0 +1,136 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  Tpm.h
> +
> +Abstract:
> +
> +
> +--*/
> +
> +#ifndef __EFI_TPM_MP_DRIVER_PROTOCOL_H__
> +#define __EFI_TPM_MP_DRIVER_PROTOCOL_H__
> +
> +
> +#define EFI_TPM_MP_DRIVER_PROTOCOL_GUID \
> +  { 0xde161cfe, 0x1e60, 0x42a1, 0x8c, 0xc3, 0xee, 0x7e, 0xf0, 0x73, 0x52,
> 0x12 }
> +
> +
> +EFI_FORWARD_DECLARATION (EFI_TPM_MP_DRIVER_PROTOCOL);
> +
> +#define TPM_DRIVER_STATUS         0
> +#define TPM_DEVICE_STATUS         1
> +
> +#define TPM_DRIVER_OK             0
> +#define TPM_DRIVER_FAILED         1
> +#define TPM_DRIVER_NOT_OPENED     2
> +#define TPM_DEVICE_OK             0
> +#define TPM_DEVICE_UNRECOVERABLE  1
> +#define TPM_DEVICE_RECOVERABLE    2
> +#define TPM_DEVICE_NOT_FOUND      3
> +
> +//
> +// Prototypes for the TPM MP Driver Protocol
> +//
> +
> +/**
> +  This service Open the TPM interface
> +
> +  @param[in] This             A pointer to the EFI_TPM_MP_DRIVER_PROTOCOL.
> +
> +  @retval  EFI_SUCCESS        Operation completed successfully
> +  @retval  EFI_DEVICE_ERROR   The command was unsuccessful
> +  @retval  EFI_NOT_FOUND      The component was not running
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_TPM_MP_INIT) (
> +  IN EFI_TPM_MP_DRIVER_PROTOCOL   *This
> +  );
> +
> +/**
> +  This service close the TPM interface and deactivate TPM
> +
> +  @param[in] This            A pointer to the EFI_TPM_MP_DRIVER_PROTOCOL.
> +
> +  @retval EFI_SUCCESS        Operation completed successfully
> +  @retval EFI_DEVICE_ERROR   The command was unsuccessful
> +  @retval EFI_NOT_FOUND      The component was not running
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_TPM_MP_CLOSE) (
> +  IN EFI_TPM_MP_DRIVER_PROTOCOL   *This
> +  );
> +
> +/**
> +  This service get the current status infomation of TPM
> +
> +  @param[in]  This                  A pointer to the
> EFI_TPM_MP_DRIVER_PROTOCOL.
> +  @param[in]  ReqStatusType	        Requested type of status information,
> driver or device.
> +  @param[in]  Status	              Pointer to the returned status.
> +
> +  @retval  EFI_SUCCESS              Operation completed successfully
> +  @retval  EFI_DEVICE_ERROR         The command was unsuccessful
> +  @retval  EFI_INVALID_PARAMETER    One or more of the parameters are
> incorrect
> +  @retval  EFI_BUFFER_TOO_SMALL     The receive buffer is too small
> +  @retval  EFI_NOT_FOUND            The component was not running
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_TPM_MP_GET_STATUS_INFO) (
> +  IN EFI_TPM_MP_DRIVER_PROTOCOL   *This,
> +  IN UINT32				                ReqStatusType,
> +  OUT UINT32				              *Status
> +  );
> +
> +/**
> +  This service transmit data to the TPM and get response from TPM
> +
> +  @param[in] This                  A pointer to the
> EFI_TPM_MP_DRIVER_PROTOCOL.
> +  @param[in] TransmitBuf	         Pointer to a buffer containing TPM
> transmit data.
> +  @param[in] TransmitBufLen	       Sizeof TPM input buffer in bytes.
> +  @param[in] ReceiveBuf	           Pointer to a buffer containing TPM
> receive data.
> +  @param[in]  ReceiveBufLen	       On input, size of TPM receive buffer in
> bytes.
> +                                   On output, number of bytes written.
> +
> +  @retval  EFI_SUCCESS             Operation completed successfully
> +  @retval  EFI_DEVICE_ERROR        The command was unsuccessful
> +  @retval  EFI_INVALID_PARAMETER   One or more of the parameters are
> incorrect
> +  @retval  EFI_BUFFER_TOO_SMALL    The receive buffer is too small
> +  @retval  EFI_NOT_FOUND           The component was not running
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_TPM_MP_TRANSMIT) (
> +  IN EFI_TPM_MP_DRIVER_PROTOCOL   *This,
> +  IN UINT8				  	            *TransmitBuffer,
> +  IN UINT32			  	              TransmitBufferLen,
> +  OUT UINT8				  	            *ReceiveBuf,
> +  IN OUT UINT32			  	          *ReceiveBufLen
> +  );
> +
> +
> +
> +typedef struct _EFI_TPM_MP_DRIVER_PROTOCOL {
> +  EFI_TPM_MP_INIT			              Init;
> +  EFI_TPM_MP_CLOSE			            Close;
> +  EFI_TPM_MP_GET_STATUS_INFO 		    GetStatusInfo;
> +  EFI_TPM_MP_TRANSMIT		            Transmit;
> +} EFI_TPM_MP_DRIVER_PROTOCOL;
> +
> +extern EFI_GUID gEfiTpmMpDriverProtocolGuid;
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/UsbPolicy.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/UsbPolicy.h
> new file mode 100644
> index 0000000000..16e9f9c6bc
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/UsbPolicy.h
> @@ -0,0 +1,126 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +  UsbPolicy.h
> +
> +Abstract:
> +
> +--*/
> +
> +#ifndef _USB_POLICY_H_
> +#define _USB_POLICY_H_
> +
> +EFI_FORWARD_DECLARATION (EFI_USB_POLICY_PROTOCOL);
> +
> +#define USB_POLICY_GUID \
> +  {\
> +    0xf617b358, 0x12cf, 0x414a, 0xa0, 0x69, 0x60, 0x67, 0x7b, 0xda, 0x13,
> 0xb4\
> +  }
> +
> +#define TIANO_CODE_BASE           0x00
> +#define ICBD_CODE_BASE            0x01
> +
> +#define ATUO_TYPE                 0x00
> +#define USB_FDD_TYPE              0x01
> +#define HDD_TYPE                  0x02
> +#define ZIP_TYPE                  0x03
> +#define CDROM_TYPE                0x04
> +#define SIZE_TYPE                 0x05
> +
> +#define ZIP_FDD                 0x80
> +
> +#define FDD_EMULATION             0x00
> +#define HDD_EMULATION             0x01
> +
> +#define HIGH_SPEED                0x00
> +#define FULL_SPEED                0x01
> +#define SUPER_SPEED               0x02
> +
> +#define LEGACY_KB_EN              0x01
> +#define LEGACY_KB_DIS             0x00
> +#define LEGACY_MS_EN              0x01
> +#define LEGACY_MS_DIS             0x00
> +#define LEGACY_USB_EN             0x00
> +#define LEGACY_USB_DIS            0x01
> +#define LEGACY_FREE_SUPP          0x01
> +#define LEGACY_FREE_UN_SUPP       0x00
> +#define LEGACY_PERIOD_SUPP        0x01
> +#define LEGACY_PERIOD_UN_SUPP     0x00
> +
> +#define LEGACY_USB_TIME_TUE_ENABLE       0x01
> +#define LEGACY_USB_TIME_TUE_DISABLE      0x00
> +#define USB_HAVE_HUB_INTERNEL            0x01
> +#define USB_NOT_HAVE_HUB_INTERNEL        0x00
> +
> +#define USB_POLICY_PROTOCOL_REVISION_1 1
> +#define USB_POLICY_PROTOCOL_REVISION_2 2
> +
> +#ifndef __GNUC__
> +#pragma warning ( disable : 4306 )
> +#pragma warning ( disable : 4054 )
> +#endif
> +
> +#define GET_USB_CFG (UsbCfg);\
> + do{\
> +  UINT16                *pSegOfEbda;\
> +  UINT32                mToEbda;\
> +  pSegOfEbda = (UINT16 *)(UINTN)0x40E;\
> +  mToEbda    = (UINT32)(((UINTN)(*pSegOfEbda) << 4) + 0x80);\
> +  UsbCfg     = (USB_CFG *)(UINTN)mToEbda;\
> + }while(0);
> +
> +#pragma    pack(1)
> +typedef struct {
> +    UINT8   HasUSBKeyboard:1;
> +    UINT8   HasUSBMouse:1;
> +    UINT8   LegacyFreeSupport:1;
> +    UINT8   UsbOperationMode:1;
> +    UINT8   LegacyKBEnable:1;
> +    UINT8   LegacyMSEnable:1;
> +    UINT8   USBPeriodSupport:1;
> +    UINT8   Reserved:1;
> +} USB_DEVICE_INFOR;
> +
> +typedef struct {
> +    UINT8               Codebase;
> +    UINT8               USBHDDForceType;
> +    UINT8               Configurated;
> +    UINT8               LpcAcpiBase;
> +    UINT8               AcpiTimerReg;
> +    UINT8               Reserved1[0x01];
> +    UINT8               LegacyUsbEnable;
> +    USB_DEVICE_INFOR    UsbDeviceInfor;
> +    UINT16              UsbEmulationSize;
> +    UINT8               Reserved2[0x06];
> +} USB_CFG;
> +#pragma pack()
> +
> +typedef struct _EFI_USB_POLICY_PROTOCOL{
> +  UINT8   Version;
> +  UINT8   UsbMassStorageEmulationType;  // 1: FDD_Type; 2: HDD_Type;
> other:Auto_Type*
> +  UINT8   UsbOperationMode;             // 0: High_Speed; 1: Full_Speed;
> +  UINT8   LegacyKBEnable;               // 0: Disabled;   1: Enabled*
> +  UINT8   LegacyMSEnable;               // 0: Disabled;   1: Enabled*
> +  UINT8   USBPeriodSupport;             // 0; Unsupport;  1: Support
> +  UINT8   LegacyUsbEnable;              // 1: Disabled;   0: Enabled*
> +  UINT8   LegacyFreeSupport;            // 0: Unsupport;  1: Support
> +  UINT8   CodeBase;
> +  UINT8   LpcAcpiBase;                  // 40h(default)
> +  UINT8   AcpiTimerReg;
> +  UINT8   UsbTimeTue;
> +  UINT8   InternelHubExist;             // 1: Host have internel hub on board; 0:
> No internel hub on board
> +  UINT8   EnumWaitPortStableStall;      // Value for wait port stable when
> enum a new dev.
> +  UINT16  UsbEmulationSize;             // Mbytes.
> +  UINT8   UsbZipEmulationType;
> +  UINT8   Reserved[3];                  // Reserved fields for future expansion w/o
> protocol change
> +} EFI_USB_POLICY_PROTOCOL;
> +
> +extern EFI_GUID gUsbPolicyGuid;
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/VlvPlatformPolicy.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/VlvPlatformPolicy.h
> new file mode 100644
> index 0000000000..5c0ffa3027
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/VlvPlatformPolicy.h
> @@ -0,0 +1,102 @@
> +/**
> +  Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +Module Name:
> +
> +  VlvPlatformPolicy.h
> +
> +Abstract:
> +
> +  Interface definition details between MCH and platform drivers during DXE
> phase.
> +
> +--*/
> +
> +#ifndef _VLV_PLATFORM_POLICY_H_
> +#define _VLV_PLATFORM_POLICY_H_
> +
> +//
> +// VLV Policy provided by platform for DXE phase {5BAB88BA-E0E2-4674-
> B6AD-B812F6881CD6}
> +//
> +#define DXE_VLV_PLATFORM_POLICY_GUID \
> +  {0x5bab88ba, 0xe0e2, 0x4674, 0xb6, 0xad, 0xb8, 0x12, 0xf6, 0x88, 0x1c,
> 0xd6}
> +
> +//
> +// Extern the GUID for protocol users.
> +//
> +extern EFI_GUID gDxeVlvPlatformPolicyGuid;
> +
> +//
> +// Protocol revision number
> +// Any backwards compatible changes to this protocol will result in an
> update in the revision number
> +// Major changes will require publication of a new protocol
> +//
> +#define DXE_VLV_PLATFORM_POLICY_PROTOCOL_REVISION 0
> +
> +
> +typedef struct {
> +  UINT8  PFITStatus;
> +  UINT8  IgdTheramlSupport;
> +  UINT8  ALSEnabled;
> +  UINT8  LidStatus;
> +} IGD_PANEL_FEATURES;
> +
> +typedef struct {
> +  UINT8   Reserved00;
> +  UINT8   Reserved01;
> +  UINT16  Reserved02;
> +  UINT16  Reserved03;
> +  UINT16  Reserved04;
> +  UINT16  Reserved05;
> +  UINT16  Reserved06;
> +  UINT16  Reserved07;
> +  UINT16  Reserved08;
> +  UINT16  Reserved09;
> +  UINT16  Reserved0A;
> +  UINT16  Reserved0B;
> +  UINT16  Reserved0C;
> +  UINT16  Reserved0D;
> +  UINT8   Reserved0E;
> +  UINT8   Reserved0F;
> +  UINT32  Reserved10;
> +  UINT32  Reserved11;
> +  UINT32  Reserved12;
> +  UINT32  Reserved13;
> +  UINT32  Reserved14;
> +  UINT8   Reserved15;
> +  UINT8   Reserved16;
> +} DPTF_SETTINGS;
> +
> +//
> +// MCH DXE Platform Policiy
> ==================================================
> +//
> +
> +#define NO_AUDIO   0
> +#define HD_AUDIO   1
> +#define LPE_AUDIO  2
> +
> +typedef struct _DXE_VLV_PLATFORM_POLICY_PROTOCOL {
> +  UINT8                   Revision;
> +  IGD_PANEL_FEATURES      IgdPanelFeatures;
> +  DPTF_SETTINGS           Reserved;
> +  UINT8                   GraphicReserve00;
> +  UINT8                   GraphicsPerfAnalyzers;
> +  UINT8                   PwmReserved00;
> +  UINT8                   PwmReserved01;
> +  UINT8                   PmSupport;
> +  UINT8                   GraphicReserve01;
> +  UINT8                   GfxPause;
> +  UINT8                   GraphicsFreqReq;
> +  UINT8                   GraphicReserve03;
> +  UINT8                   GraphicReserve02;
> +  UINT8                   GraphicReserve04;
> +  UINT8                   PavpMode;
> +  UINT8                   GraphicReserve05;
> +  UINT8                   UlClockGating;
> +  UINT8                   IdleReserve;
> +  UINT8                   AudioTypeSupport;
> +  UINT8                   GraphicReserve06;
> +} DXE_VLV_PLATFORM_POLICY_PROTOCOL;
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Include/SetupMode.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Include/SetupMode.h
> new file mode 100644
> index 0000000000..53abd1d3a6
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Include/SetupMode.h
> @@ -0,0 +1,85 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +    SetupMode.h
> +
> +Abstract:
> +
> +    EFI Setup Mode
> +
> +
> +
> +--*/
> +
> +#ifndef _EFI_SETUP_MODE_H_
> +#define _EFI_SETUP_MODE_H_
> +
> +//
> +// Global ID for the Setup Mode
> +//
> +#define EFI_PLATFORM_BOOT_MODE_GUID \
> +  { 0xce845704, 0x1683, 0x4d38, 0xa4, 0xf9, 0x7d, 0xb, 0x50, 0x77, 0x57, 0x93 }
> +
> +#define EFI_NORMAL_SETUP_GUID \
> +  { 0xec87d643, 0xeba4, 0x4bb5, 0xa1, 0xe5, 0x3f, 0x3e, 0x36, 0xb2, 0xd,
> 0xa9 }
> +
> +#define EFI_NORMAL_SETUP_RESET_NAME L"Reset"
> +
> +enum {
> +  //
> +  // This means: "whatever reset defaults in setup does"
> +  //
> +  SetupDataResetNormal        = 0,
> +
> +  //
> +  // This means: "the defaults built into the BIOS"
> +  //
> +  SetupDataResetStandard      = 1,
> +
> +  //
> +  // This means: "the manufacturing mode defaults"
> +  //
> +  SetupDataResetManufacturing = 2,
> +
> +  //
> +  // This means: "the oem defaults"
> +  //
> +  SetupDataResetOem           = 3,
> +};
> +
> +//
> +// PlatformBootMode types
> +//
> +#define PLATFORM_NORMAL_MODE          0x01
> +#define PLATFORM_SAFE_MODE            0x02
> +#define PLATFORM_RECOVERY_MODE        0x04
> +#define PLATFORM_MANUFACTURING_MODE   0x08
> +#define PLATFORM_BACK_TO_BIOS_MODE    0x10
> +
> +extern EFI_GUID gEfiPlatformBootModeGuid;
> +
> +#define   NORMAL_SETUP_NAME                L"Setup"
> +#define   IN_SETUP_NAME                    L"InSetup"
> +#define   SYSTEM_PASSWORD_NAME             L"SystemPassword"
> +#define   BOOT_TIME_NAME                   L"BootTime"
> +
> +extern EFI_GUID gEfiNormalSetupGuid;
> +extern CHAR16   gEfiNormalSetupName[];
> +extern CHAR16   gEfiInSetupName[];
> +extern CHAR16   gEfiSystemPasswordName[];
> +
> +typedef struct {
> +  EFI_GUID    SetupGuid;
> +  CHAR16      SetupName[0x20];          // Maximum "Setup" Name
> +  UINT32      PlatformBootMode;
> +} EFI_PLATFORM_SETUP_ID;
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/IntelGopDepex/IntelGopDriver.depex
> b/Platform/Intel/Vlv2TbltDevicePkg/IntelGopDepex/IntelGopDriver.depex
> new file mode 100644
> index 0000000000..011f929f0a
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/IntelGopDepex/IntelGopDriver.depex
> @@ -0,0 +1 @@
> +\x02^[�.�2�H�\rߊ��<]\b
> \ No newline at end of file
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.c
> new file mode 100644
> index 0000000000..3f0e20c7a8
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.c
> @@ -0,0 +1,337 @@
> +/*++
> +
> +Copyright (c) 2011  - 2014, Intel Corporation. All rights reserved
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  BiosIdLib.c
> +
> +Abstract:
> +
> +  Boot service DXE BIOS ID library implementation.
> +
> +  These functions in this file can be called during DXE and cannot be called
> during runtime
> +  or in SMM which should use a RT or SMM library.
> +
> +--*/
> +
> +#include <PiDxe.h>
> +#include <Library/BaseLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +
> +#include <Library/BiosIdLib.h>
> +#include <Guid/BiosId.h>
> +#include <Protocol/FirmwareVolume2.h>
> +#include <Protocol/LoadedImage.h>
> +
> +
> +EFI_STATUS
> +GetImageFromFv (
> +  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,
> +  IN  EFI_GUID           *NameGuid,
> +  IN  EFI_SECTION_TYPE   SectionType,
> +  OUT VOID               **Buffer,
> +  OUT UINTN              *Size
> +  )
> +{
> +  EFI_STATUS                Status;
> +  EFI_FV_FILETYPE           FileType;
> +  EFI_FV_FILE_ATTRIBUTES    Attributes;
> +  UINT32                    AuthenticationStatus;
> +
> +  //
> +  // Read desired section content in NameGuid file
> +  //
> +  *Buffer     = NULL;
> +  *Size       = 0;
> +  Status      = Fv->ReadSection (
> +                      Fv,
> +                      NameGuid,
> +                      SectionType,
> +                      0,
> +                      Buffer,
> +                      Size,
> +                      &AuthenticationStatus
> +                      );
> +
> +  if (EFI_ERROR (Status) && (SectionType == EFI_SECTION_TE)) {
> +    //
> +    // Try reading PE32 section, since the TE section does not exist
> +    //
> +    *Buffer = NULL;
> +    *Size   = 0;
> +    Status  = Fv->ReadSection (
> +                    Fv,
> +                    NameGuid,
> +                    EFI_SECTION_PE32,
> +                    0,
> +                    Buffer,
> +                    Size,
> +                    &AuthenticationStatus
> +                    );
> +  }
> +
> +  if (EFI_ERROR (Status) &&
> +      ((SectionType == EFI_SECTION_TE) || (SectionType ==
> EFI_SECTION_PE32))) {
> +    //
> +    // Try reading raw file, since the desired section does not exist
> +    //
> +    *Buffer = NULL;
> +    *Size   = 0;
> +    Status  = Fv->ReadFile (
> +                    Fv,
> +                    NameGuid,
> +                    Buffer,
> +                    Size,
> +                    &FileType,
> +                    &Attributes,
> +                    &AuthenticationStatus
> +                    );
> +  }
> +
> +  return Status;
> +}
> +
> +
> +EFI_STATUS
> +GetImageEx (
> +  IN  EFI_HANDLE         ImageHandle,
> +  IN  EFI_GUID           *NameGuid,
> +  IN  EFI_SECTION_TYPE   SectionType,
> +  OUT VOID               **Buffer,
> +  OUT UINTN              *Size,
> +  BOOLEAN                WithinImageFv
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  EFI_HANDLE                    *HandleBuffer;
> +  UINTN                         HandleCount;
> +  UINTN                         Index;
> +  EFI_LOADED_IMAGE_PROTOCOL     *LoadedImage;
> +
> +  EFI_FIRMWARE_VOLUME2_PROTOCOL *ImageFv;
> +  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
> +
> +
> +  if (ImageHandle == NULL && WithinImageFv) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Status  = EFI_NOT_FOUND;
> +  ImageFv = NULL;
> +  if (ImageHandle != NULL) {
> +    Status = gBS->HandleProtocol (
> +                    ImageHandle,
> +                    &gEfiLoadedImageProtocolGuid,
> +                    (VOID **) &LoadedImage
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +    Status = gBS->HandleProtocol (
> +                    LoadedImage->DeviceHandle,
> +                    &gEfiFirmwareVolume2ProtocolGuid,
> +                    (VOID **) &ImageFv
> +                    );
> +    if (!EFI_ERROR (Status)) {
> +      Status = GetImageFromFv (ImageFv, NameGuid, SectionType, Buffer,
> Size);
> +    }
> +  }
> +
> +  if (Status == EFI_SUCCESS || WithinImageFv) {
> +    return Status;
> +  }
> +
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gEfiFirmwareVolume2ProtocolGuid,
> +                  NULL,
> +                  &HandleCount,
> +                  &HandleBuffer
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Find desired image in all Fvs
> +  //
> +  for (Index = 0; Index < HandleCount; ++Index) {
> +    Status = gBS->HandleProtocol (
> +                    HandleBuffer[Index],
> +                    &gEfiFirmwareVolume2ProtocolGuid,
> +                    (VOID**)&Fv
> +                    );
> +
> +    if (EFI_ERROR (Status)) {
> +      gBS->FreePool(HandleBuffer);
> +      return Status;
> +    }
> +
> +    if (ImageFv != NULL && Fv == ImageFv) {
> +      continue;
> +    }
> +
> +    Status = GetImageFromFv (Fv, NameGuid, SectionType, Buffer, Size);
> +
> +    if (!EFI_ERROR (Status)) {
> +      break;
> +    }
> +  }
> +  gBS->FreePool(HandleBuffer);
> +
> +  //
> +  // Not found image
> +  //
> +  if (Index == HandleCount) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function returns BIOS ID by searching HOB or FV.
> +
> +  @param BiosIdImage             The BIOS ID got from HOB or FV.
> +
> +  @retval EFI_SUCCESS            All parameters were valid and BIOS ID has been
> got.
> +  @retval EFI_NOT_FOUND          BiosId image is not found, and no
> parameter will be modified.
> +  @retval EFI_INVALID_PARAMETER  The parameter is NULL.
> +
> +**/
> +EFI_STATUS
> +GetBiosId (
> +  OUT BIOS_ID_IMAGE     *BiosIdImage
> +  )
> +
> +{
> +  EFI_STATUS    Status;
> +  VOID          *Address = NULL;
> +  UINTN         Size = 0;
> +
> +    DEBUG ((EFI_D_INFO, "Get BIOS ID from FV\n"));
> +
> +    Status = GetImageEx (
> +               NULL,
> +               &gEfiBiosIdGuid,
> +               EFI_SECTION_RAW,
> +               &Address,
> +               &Size,
> +               FALSE
> +               );
> +
> +    if (Status == EFI_SUCCESS) {
> +      //
> +      // BiosId image is present in FV
> +      //
> +      if (Address != NULL) {
> +        Size = sizeof (BIOS_ID_IMAGE);
> +        gBS->CopyMem (
> +              (void *) BiosIdImage,
> +              Address,
> +              Size
> +              );
> +        //
> +        // GetImage () allocated buffer for Address, now clear it.
> +        //
> +        gBS->FreePool (Address);
> +
> +        DEBUG ((EFI_D_INFO, "Get BIOS ID from FV successfully\n"));
> +        DEBUG ((EFI_D_INFO, "BIOS ID: %s\n", (CHAR16 *) (&(BiosIdImage-
> >BiosIdString))));
> +
> +        return EFI_SUCCESS;
> +      }
> +    }
> +  return EFI_NOT_FOUND;
> +}
> +
> +/**
> +  This function returns the Version & Release Date and Time by getting and
> converting
> +  BIOS ID.
> +
> +  @param BiosVersion  The Bios Version out of the conversion.
> +  @param BiosReleaseDate  The Bios Release Date out of the conversion.
> +  @param BiosReleaseTime - The Bios Release Time out of the conversion.
> +
> +  @retval EFI_SUCCESS - BIOS Version & Release Date and Time have been
> got successfully.
> +  @retval EFI_NOT_FOUND - BiosId image is not found, and no parameter
> will be modified.
> +  @retval EFI_INVALID_PARAMETER - All the parameters are NULL.
> +
> +**/
> +EFI_STATUS
> +GetBiosVersionDateTime (
> +  OUT CHAR16    *BiosVersion, OPTIONAL
> +  OUT CHAR16    *BiosReleaseDate, OPTIONAL
> +  OUT CHAR16    *BiosReleaseTime OPTIONAL
> +  )
> +{
> +  EFI_STATUS        Status;
> +  BIOS_ID_IMAGE     BiosIdImage;
> +
> +  if ((BiosVersion == NULL) && (BiosReleaseDate == NULL) &&
> (BiosReleaseTime == NULL)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Status = GetBiosId (&BiosIdImage);
> +  if (EFI_ERROR (Status)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  if (BiosVersion != NULL) {
> +    //
> +    // Fill the BiosVersion data from the BIOS ID.
> +    //
> +    StrCpy (BiosVersion, (CHAR16 *) (&(BiosIdImage.BiosIdString)));
> +  }
> +
> +  if (BiosReleaseDate != NULL) {
> +    //
> +    // Fill the build timestamp date from the BIOS ID in the "MM/DD/YY"
> format.
> +    //
> +    BiosReleaseDate[0] = BiosIdImage.BiosIdString.TimeStamp[2];
> +    BiosReleaseDate[1] = BiosIdImage.BiosIdString.TimeStamp[3];
> +    BiosReleaseDate[2] = (CHAR16) ((UINT8) ('/'));
> +
> +    BiosReleaseDate[3] = BiosIdImage.BiosIdString.TimeStamp[4];
> +    BiosReleaseDate[4] = BiosIdImage.BiosIdString.TimeStamp[5];
> +    BiosReleaseDate[5] = (CHAR16) ((UINT8) ('/'));
> +
> +    //
> +    // Add 20 for SMBIOS table
> +    // Current Linux kernel will misjudge 09 as year 0, so using 2009 for
> SMBIOS table
> +    //
> +    BiosReleaseDate[6] = '2';
> +    BiosReleaseDate[7] = '0';
> +    BiosReleaseDate[8] = BiosIdImage.BiosIdString.TimeStamp[0];
> +    BiosReleaseDate[9] = BiosIdImage.BiosIdString.TimeStamp[1];
> +
> +    BiosReleaseDate[10] = (CHAR16) ((UINT8) ('\0'));
> +  }
> +
> +  if (BiosReleaseTime != NULL) {
> +
> +    //
> +    // Fill the build timestamp time from the BIOS ID in the "HH:MM" format.
> +    //
> +
> +    BiosReleaseTime[0] = BiosIdImage.BiosIdString.TimeStamp[6];
> +    BiosReleaseTime[1] = BiosIdImage.BiosIdString.TimeStamp[7];
> +    BiosReleaseTime[2] = (CHAR16) ((UINT8) (':'));
> +
> +    BiosReleaseTime[3] = BiosIdImage.BiosIdString.TimeStamp[8];
> +    BiosReleaseTime[4] = BiosIdImage.BiosIdString.TimeStamp[9];
> +
> +    BiosReleaseTime[5] = (CHAR16) ((UINT8) ('\0'));
> +  }
> +
> +  return  EFI_SUCCESS;
> +}
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.inf
> new file mode 100644
> index 0000000000..3e53680d08
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.inf
> @@ -0,0 +1,50 @@
> +#/*++
> +#
> +# Copyright (c)  2010  - 2014, Intel Corporation. All rights reserved
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +
> +#
> +#  Module Name:
> +#
> +#   BiosIdLib.inf
> +#
> +#  Abstract:
> +#
> +#    Component description file for BIOS ID library
> +#
> +#--*/
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = BiosIdLib
> +  FILE_GUID                      = 98546145-64F1-4d2e-814F-6BF963DB7930
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = BiosIdLib
> +  PI_SPECIFICATION_VERSION       = 0x0001000A
> +
> +[Sources]
> +  BiosIdLib.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +
> +[LibraryClasses]
> +  HobLib
> +
> +[Guids]
> +  gEfiBiosIdGuid
> +
> +[Protocols]
> +  gEfiLoadedImageProtocolGuid
> +  gEfiFirmwareVolume2ProtocolGuid
> +
> +[Depex]
> +  gEfiLoadedImageProtocolGuid AND
> +  gEfiFirmwareVolume2ProtocolGuid
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/CpuIA32Lib.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/CpuIA32Lib.inf
> new file mode 100644
> index 0000000000..c9f0a434ac
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/CpuIA32Lib.inf
> @@ -0,0 +1,41 @@
> +#
> +#
> +# Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +#
> +#
> +#   Module Name:
> +#
> +#     CpuIA32Lib.inf
> +#
> +#   Abstract:
> +#
> +#     Component description file for the Cpu IA32 library.
> +#
> +#--*/
> +
> +[defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = CpuIA32Lib
> +  FILE_GUID                      = 98546178-64F1-4d2e-814F-6BF963DB7930
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = CpuIA32Lib
> +  PI_SPECIFICATION_VERSION       = 0x0001000A
> +
> +[Sources]
> +  EfiCpuVersion.c
> +
> +[Sources.IA32]
> +  IA32/CpuIA32.c
> +
> +[Sources.X64]
> +  X64/Cpu.asm
> +  X64/Cpu.S
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/EfiCpuVersion.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/EfiCpuVersion.c
> new file mode 100644
> index 0000000000..935f11e871
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/EfiCpuVersion.c
> @@ -0,0 +1,70 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +  EfiCpuVersion.c
> +
> +Abstract:
> +
> +  Provide cpu version extract considering extended family & model ID.
> +--*/
> +
> +#include <Library/CpuIA32.h>
> +
> +/**
> +  Extract CPU detail version infomation
> +
> +  @param  FamilyId    FamilyId, including ExtendedFamilyId
> +  @param  Model       Model, including ExtendedModel
> +  @param  SteppingId  SteppingId
> +  @param  Processor   Processor
> +
> +**/
> +VOID
> +EFIAPI
> +EfiCpuVersion (
> +  IN  OUT UINT16  *FamilyId,    OPTIONAL
> +  IN  OUT UINT8   *Model,       OPTIONAL
> +  IN  OUT UINT8   *SteppingId,  OPTIONAL
> +  IN  OUT UINT8   *Processor    OPTIONAL
> +  )
> +
> +{
> +  EFI_CPUID_REGISTER Register;
> +  UINT8              TempFamilyId;
> +
> +  EfiCpuid (EFI_CPUID_VERSION_INFO, &Register);
> +
> +  if (SteppingId != NULL) {
> +    *SteppingId = (UINT8) (Register.RegEax & 0xF);
> +  }
> +
> +  if (Processor != NULL) {
> +    *Processor = (UINT8) ((Register.RegEax >> 12) & 0x3);
> +  }
> +
> +  if (Model != NULL || FamilyId != NULL) {
> +    TempFamilyId = (UINT8) ((Register.RegEax >> 8) & 0xF);
> +
> +    if (Model != NULL) {
> +      *Model = (UINT8) ((Register.RegEax >> 4) & 0xF);
> +      if (TempFamilyId == 0x6 || TempFamilyId == 0xF) {
> +        *Model = (UINT8) (*Model  | ((Register.RegEax >> 12) & 0xF0));
> +      }
> +    }
> +
> +    if (FamilyId != NULL) {
> +      *FamilyId = TempFamilyId;
> +      if (TempFamilyId == 0xF) {
> +        *FamilyId = (UINT8 ) (*FamilyId + (UINT16) ((Register.RegEax >> 20) &
> 0xFF));
> +      }
> +    }
> +  }
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.S
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.S
> new file mode 100644
> index 0000000000..ba1bd448c0
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.S
> @@ -0,0 +1,223 @@
> +#
> +#
> +# Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +#
> +#
> +#Module Name:
> +#
> +#  CpuIA32.c
> +#
> +#Abstract:
> +#
> +#--*/
> +
> +##include "CpuIA32.h"
> +#include "EfiBind.h"
> +
> +#---------------------------------------------------------------------------
> +    .586p:
> +    #.MODEL flat,C
> +    .code:
> +
> +#---------------------------------------------------------------------------
> +
> +.globl ASM_PFX(EfiHalt)
> +.globl ASM_PFX(EfiWbinvd)
> +.globl ASM_PFX(EfiInvd)
> +.globl ASM_PFX(EfiCpuid)
> +.globl ASM_PFX(EfiReadMsr)
> +.globl ASM_PFX(EfiWriteMsr)
> +.globl ASM_PFX(EfiReadTsc)
> +.globl ASM_PFX(EfiDisableCache)
> +.globl ASM_PFX(EfiEnableCache)
> +.globl ASM_PFX(EfiGetEflags)
> +.globl ASM_PFX(EfiDisableInterrupts)
> +.globl ASM_PFX(EfiEnableInterrupts)
> +.globl ASM_PFX(EfiCpuidExt)
> +
> +
> +#VOID
> +#EfiHalt (
> +#  VOID
> +#)
> +ASM_PFX(EfiHalt):
> +    hlt
> +    ret
> +#EfiHalt ENDP
> +
> +#VOID
> +#EfiWbinvd (
> +#  VOID
> +#)
> +ASM_PFX(EfiWbinvd):
> +    wbinvd
> +    ret
> +#EfiWbinvd ENDP
> +
> +#VOID
> +#EfiInvd (
> +# VOID
> +#)
> +ASM_PFX(EfiInvd):
> +    invd
> +    ret
> +#EfiInvd ENDP
> +
> +#VOID
> +#EfiCpuid (IN UINT32 RegisterInEax,
> +#          OUT EFI_CPUID_REGISTER *Reg OPTIONAL)
> +ASM_PFX(EfiCpuid):
> +    pushl %ebp
> +    movl %esp, %ebp
> +    pushl %ebx
> +    pushl %esi
> +    pushl %edi
> +    pushal
> +
> +    movl   8(%ebp), %eax           #RegisterInEax
> +    cpuid
> +    cmpl   $0, 0xC(%ebp)           # Reg
> +    je     L1
> +    movl        0xC(%ebp), %edi         # Reg
> +
> +    movl        %eax, (%edi)        # Reg->RegEax
> +    movl        %ebx, 4(%edi)         # Reg->RegEbx
> +    movl        %ecx, 8(%edi)         # Reg->RegEcx
> +    movl        %edx, 0xC(%edi)         # Reg->RegEdx
> +
> +L1:
> +    popal
> +    popl        %edi
> +    popl        %esi
> +    popl        %ebx
> +    popl        %ebp
> +
> +    ret
> +#EfiCpuid ENDP
> +
> +
> +#UINT64
> +#EfiReadMsr (
> +#  IN UINT32 Index
> +#  );
> +ASM_PFX(EfiReadMsr):
> +    movl   4(%esp), %ecx           # Index
> +    rdmsr
> +    ret
> +#EfiReadMsr ENDP
> +
> +#VOID
> +#EfiWriteMsr (
> +#  IN   UINT32  Index,
> +#  IN   UINT64  Value
> +#  );
> +ASM_PFX(EfiWriteMsr):
> +    movl   4(%esp), %ecx         # Index
> +    movl   8(%esp), %eax         # DWORD PTR Value[0]
> +    movl   0xC(%esp), %edx         # DWORD PTR Value[4]
> +    wrmsr
> +    ret
> +#EfiWriteMsr ENDP
> +
> +#UINT64
> +#EfiReadTsc (
> +#  VOID
> +#  )
> +ASM_PFX(EfiReadTsc):
> +    rdtsc
> +    ret
> +#EfiReadTsc ENDP
> +
> +#VOID
> +#EfiDisableCache (
> +#  VOID
> +#)
> +ASM_PFX(EfiDisableCache):
> +    movl  %cr0, %eax
> +    bswapl %eax
> +    andb  $0x60, %al
> +    cmpb  $0x60, %al
> +    je    L2
> +    movl  %cr0, %eax
> +    orl   $0x60000000, %eax
> +    movl  %eax, %cr0
> +    wbinvd
> +L2:
> +    ret
> +#EfiDisableCache ENDP
> +
> +#VOID
> +#EfiEnableCache (
> +#  VOID
> +#  )
> +ASM_PFX(EfiEnableCache):
> +    wbinvd
> +    movl  %cr0, %eax
> +    andl  $0x9fffffff, %eax
> +    movl  %eax, %cr0
> +    ret
> +#EfiEnableCache ENDP
> +
> +#UINT32
> +#EfiGetEflags (
> +#  VOID
> +#  )
> +ASM_PFX(EfiGetEflags):
> +    pushfl
> +    popl %eax
> +    ret
> +#EfiGetEflags ENDP
> +
> +#VOID
> +#EfiDisableInterrupts (
> +#  VOID
> +#  )
> +ASM_PFX(EfiDisableInterrupts):
> +    cli
> +    ret
> +#EfiDisableInterrupts ENDP
> +
> +#VOID
> +#EfiEnableInterrupts (
> +#  VOID
> +#  )
> +ASM_PFX(EfiEnableInterrupts):
> +    sti
> +    ret
> +#EfiEnableInterrupts ENDP
> +
> +#VOID
> +#EfiCpuidExt (
> +#  IN   UINT32              RegisterInEax,
> +#  IN   UINT32              CacheLevel,
> +#  OUT  EFI_CPUID_REGISTER  *Regs
> +#  )
> +ASM_PFX(EfiCpuidExt):
> +    push   %ebx
> +    push   %edi
> +    push   %esi
> +    pushal
> +
> +    movl   0x30(%esp), %eax           # RegisterInEax
> +    movl   0x34(%esp), %ecx           # CacheLevel
> +    cpuid
> +    movl   0x38(%esp), %edi           # DWORD PTR Regs
> +
> +    movl   %eax, (%edi)                 # Reg->RegEax
> +    movl   %ebx, 4(%edi)                # Reg->RegEbx
> +    movl   %ecx, 8(%edi)                # Reg->RegEcx
> +    movl   %edx, 0xC(%edi)              # Reg->RegEdx
> +
> +    popal
> +    pop    %esi
> +    pop    %edi
> +    pop    %ebx
> +    ret
> +#EfiCpuidExt ENDP
> +
> +
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.asm
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.asm
> new file mode 100644
> index 0000000000..3fdf16f8ee
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.asm
> @@ -0,0 +1,206 @@
> +;
> +; This file contains an 'Intel Sample Driver' and is
> +; licensed for Intel CPUs and chipsets under the terms of your
> +; license agreement with Intel or your vendor.  This file may
> +; be modified by the user, subject to additional terms of the
> +; license agreement
> +;
> +;
> +; Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +;
> 
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +;
> 
> +;
> +
> +;Module Name:
> +;
> +;  CpuIA32.c
> +;
> +;Abstract:
> +;
> +;--*/
> +
> +;#include "CpuIA32.h"
> +
> +;---------------------------------------------------------------------------
> +    .586p
> +    .model  flat,C
> +    .code
> +
> +;---------------------------------------------------------------------------
> +;VOID
> +;EfiHalt (
> +;  VOID
> +;)
> +EfiHalt PROC C PUBLIC
> +    hlt
> +    ret
> +EfiHalt ENDP
> +
> +;VOID
> +;EfiWbinvd (
> +;  VOID
> +;)
> +EfiWbinvd PROC C PUBLIC
> +    wbinvd
> +    ret
> +EfiWbinvd ENDP
> +
> +;VOID
> +;EfiInvd (
> +; VOID
> +;)
> +EfiInvd PROC C PUBLIC
> +    invd
> +    ret
> +EfiInvd ENDP
> +
> +;VOID
> +;EfiCpuid (IN UINT32 RegisterInEax,
> +;          OUT EFI_CPUID_REGISTER *Reg OPTIONAL)
> +EfiCpuid PROC C PUBLIC
> +    push ebp
> +    mov  ebp, esp
> +    push ebx
> +    push esi
> +    push edi
> +    pushad
> +
> +    mov    eax, dword ptr[ebp + 8] ;egisterInEax
> +    cpuid
> +    cmp    dword ptr[ebp + 0Ch], 0 ; Reg
> +    je     @F
> +    mov         edi,dword ptr [ebp+0Ch] ; Reg
> +
> +    mov         dword ptr [edi],eax ; Reg->RegEax
> +    mov         dword ptr [edi+4],ebx ; Reg->RegEbx
> +    mov         dword ptr [edi+8],ecx ; Reg->RegEcx
> +    mov         dword ptr [edi+0Ch],edx ; Reg->RegEdx
> +
> +@@:
> +    popad
> +    pop         edi
> +    pop         esi
> +    pop         ebx
> +    pop         ebp
> +
> +    ret
> +EfiCpuid ENDP
> +
> +
> +;UINT64
> +;EfiReadMsr (
> +;  IN UINT32 Index
> +;  );
> +EfiReadMsr PROC C PUBLIC
> +    mov    ecx, dword ptr [esp + 4]; Index
> +    rdmsr
> +    ret
> +EfiReadMsr ENDP
> +
> +;VOID
> +;EfiWriteMsr (
> +;  IN   UINT32  Index,
> +;  IN   UINT64  Value
> +;  );
> +EfiWriteMsr PROC C PUBLIC
> +    mov    ecx, dword ptr [esp+4]; Index
> +    mov    eax, dword ptr [esp+8]; DWORD PTR Value[0]
> +    mov    edx, dword ptr [esp+0Ch]; DWORD PTR Value[4]
> +    wrmsr
> +    ret
> +EfiWriteMsr  ENDP
> +
> +;UINT64
> +;EfiReadTsc (
> +;  VOID
> +;  )
> +EfiReadTsc PROC C PUBLIC
> +    rdtsc
> +    ret
> +EfiReadTsc  ENDP
> +
> +;VOID
> +;EfiDisableCache (
> +;  VOID
> +;)
> +EfiDisableCache PROC C PUBLIC
> +    mov   eax, cr0
> +    bswap eax
> +    and   al, 60h
> +    cmp   al, 60h
> +    je    @F
> +    mov   eax, cr0
> +    or    eax, 060000000h
> +    mov   cr0, eax
> +    wbinvd
> +@@:
> +    ret
> +EfiDisableCache  ENDP
> +
> +;VOID
> +;EfiEnableCache (
> +;  VOID
> +;  )
> +EfiEnableCache PROC C PUBLIC
> +    wbinvd
> +    mov   eax, cr0
> +    and   eax, 09fffffffh
> +    mov   cr0, eax
> +    ret
> +EfiEnableCache  ENDP
> +
> +;UINT32
> +;EfiGetEflags (
> +;  VOID
> +;  )
> +EfiGetEflags PROC C PUBLIC
> +    pushfd
> +    pop  eax
> +    ret
> +EfiGetEflags  ENDP
> +
> +;VOID
> +;EfiDisableInterrupts (
> +;  VOID
> +;  )
> +EfiDisableInterrupts PROC C PUBLIC
> +    cli
> +    ret
> +EfiDisableInterrupts  ENDP
> +
> +;VOID
> +;EfiEnableInterrupts (
> +;  VOID
> +;  )
> +EfiEnableInterrupts  PROC C PUBLIC
> +    sti
> +    ret
> +EfiEnableInterrupts   ENDP
> +
> +;VOID
> +;EfiCpuidExt (
> +;  IN   UINT32              RegisterInEax,
> +;  IN   UINT32              CacheLevel,
> +;  OUT  EFI_CPUID_REGISTER  *Regs
> +;  )
> +EfiCpuidExt PROC C PUBLIC USES ebx edi esi
> +    pushad
> +
> +    mov    eax, dword ptr [esp + 30h] ; RegisterInEax
> +    mov    ecx, dword ptr [esp + 34h] ; CacheLevel
> +    cpuid
> +    mov    edi, dword ptr [esp + 38h] ; DWORD PTR Regs
> +
> +    mov    dword ptr [edi], eax   	; Reg->RegEax
> +    mov    dword ptr [edi + 4], ebx   	; Reg->RegEbx
> +    mov    dword ptr [edi + 8], ecx   	; Reg->RegEcx
> +    mov    dword ptr [edi + 0Ch], edx   ; Reg->RegEdx
> +
> +    popad
> +    ret
> +EfiCpuidExt  ENDP
> +
> +	END
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.c
> new file mode 100644
> index 0000000000..cb8de2f9c7
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.c
> @@ -0,0 +1,177 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +  CpuIA32.c
> +
> +Abstract:
> +
> +--*/
> +
> +#include <Library/CpuIA32.h>
> +
> +VOID
> +EfiHalt (VOID)
> +{
> +  __asm {
> +    hlt
> +  }
> +}
> +
> +VOID
> +EfiWbinvd (VOID)
> +{
> +  __asm {
> +    wbinvd
> +  }
> +}
> +
> +VOID
> +EfiInvd (VOID)
> +{
> +  __asm {
> +    invd
> +  }
> +}
> +
> +VOID
> +EfiCpuid (IN UINT32 RegisterInEax,
> +          OUT EFI_CPUID_REGISTER *Reg OPTIONAL)
> +{
> +  __asm {
> +    pushad
> +
> +    mov    eax, RegisterInEax
> +    cpuid
> +    cmp    Reg, 0
> +    je     _Exit
> +    mov    edi, DWORD PTR Reg
> +
> +    mov    DWORD PTR [edi].RegEax, eax   ; Reg->RegEax
> +    mov    DWORD PTR [edi].RegEbx, ebx   ; Reg->RegEbx
> +    mov    DWORD PTR [edi].RegEcx, ecx   ; Reg->RegEcx
> +    mov    DWORD PTR [edi].RegEdx, edx   ; Reg->RegEdx
> +
> +_Exit:
> +     popad
> +  }
> +}
> +
> +UINT64
> +EfiReadMsr (IN UINT32 Index)
> +{
> +  __asm {
> +    mov    ecx, Index
> +    rdmsr
> +  }
> +}
> +
> +VOID
> +EfiWriteMsr (
> +  IN   UINT32  Index,
> +  IN   UINT64  Value
> +  )
> +{
> +  __asm {
> +    mov    ecx, Index
> +    mov    eax, DWORD PTR Value[0]
> +    mov    edx, DWORD PTR Value[4]
> +    wrmsr
> +  }
> +}
> +
> +UINT64
> +EfiReadTsc (VOID)
> +{
> +  __asm {
> +    rdtsc
> +  }
> +}
> +
> +VOID
> +EfiDisableCache (VOID)
> +{
> +  __asm {
> +    mov   eax, cr0
> +    bswap eax
> +    and   al, 60h
> +    cmp   al, 60h
> +    je    Exit
> +    mov   eax, cr0
> +    or    eax, 060000000h
> +    mov   cr0, eax
> +    wbinvd
> +Exit:
> +  }
> +}
> +
> +VOID
> +EfiEnableCache (VOID)
> +{
> +  __asm {
> +    wbinvd
> +    mov   eax, cr0
> +    and   eax, 09fffffffh
> +    mov   cr0, eax
> +  }
> +}
> +
> +UINT32
> +EfiGetEflags (
> +  VOID
> +  )
> +{
> +  __asm {
> +    pushfd
> +    pop  eax
> +  }
> +}
> +
> +VOID
> +EfiDisableInterrupts (VOID)
> +{
> +  __asm {
> +    cli
> +  }
> +}
> +
> +VOID
> +EfiEnableInterrupts (
> +  VOID
> +  )
> +{
> +  __asm {
> +    sti
> +  }
> +}
> +
> +VOID
> +EfiCpuidExt (
> +  IN   UINT32              RegisterInEax,
> +  IN   UINT32              CacheLevel,
> +  OUT  EFI_CPUID_REGISTER  *Regs
> +  )
> +{
> +  __asm {
> +    pushad
> +
> +    mov    eax, RegisterInEax
> +    mov    ecx, CacheLevel
> +    cpuid
> +    mov    edi, DWORD PTR Regs
> +
> +    mov    DWORD PTR [edi].RegEax, eax   ; Reg->RegEax
> +    mov    DWORD PTR [edi].RegEbx, ebx   ; Reg->RegEbx
> +    mov    DWORD PTR [edi].RegEcx, ecx   ; Reg->RegEcx
> +    mov    DWORD PTR [edi].RegEdx, edx   ; Reg->RegEdx
> +
> +    popad
> +  }
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.S
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.S
> new file mode 100644
> index 0000000000..3a8d6e6bc5
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.S
> @@ -0,0 +1,207 @@
> +#
> +#
> +# Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +#
> +#
> +#*   Module Name:
> +#*
> +#*    Cpu.asm
> +#*
> +#*   Abstract:
> +#*
> +#------------------------------------------------------------------------------
> +##include <EfiBind.h>
> +
> +.globl ASM_PFX(EfiHalt)
> +.globl ASM_PFX(EfiWbinvd)
> +.globl ASM_PFX(EfiInvd)
> +.globl ASM_PFX(EfiCpuid)
> +.globl ASM_PFX(EfiReadTsc)
> +.globl ASM_PFX(EfiDisableCache)
> +.globl ASM_PFX(EfiEnableCache)
> +.globl ASM_PFX(EfiReadMsr)
> +.globl ASM_PFX(EfiWriteMsr)
> +.globl ASM_PFX(EfiGetEflags)
> +.globl ASM_PFX(EfiDisableInterrupts)
> +.globl ASM_PFX(EfiEnableInterrupts)
> +.globl ASM_PFX(EfiCpuidExt)
> +
> +.text
> +
> +
> +#------------------------------------------------------------------------------
> +#  VOID
> +#  EfiHalt (
> +#    VOID
> +#    )
> +#------------------------------------------------------------------------------
> +ASM_PFX(EfiHalt):
> +    hlt
> +    retq
> +
> +
> +#------------------------------------------------------------------------------
> +#  VOID
> +#  EfiWbinvd (
> +#    VOID
> +#    )
> +#------------------------------------------------------------------------------
> +ASM_PFX(EfiWbinvd):
> +    wbinvd
> +    retq
> +
> +
> +#------------------------------------------------------------------------------
> +#  VOID
> +#  EfiInvd (
> +#    VOID
> +#    )
> +#------------------------------------------------------------------------------
> +ASM_PFX(EfiInvd):
> +    invd
> +    retq
> +
> +#------------------------------------------------------------------------------
> +#  VOID
> +#  EfiCpuid (
> +#    IN   UINT32              RegisterInEax,          // rcx
> +#    OUT  EFI_CPUID_REGISTER  *Reg           OPTIONAL // rdx
> +#    )
> +#------------------------------------------------------------------------------
> +ASM_PFX(EfiCpuid):
> +      push   %rbx
> +      mov    %rdx,%r8
> +      mov    %rcx,%rax
> +      cpuid
> +      cmp    $0x0,%r8
> +      je     _Exit
> +      mov    %eax,(%r8)
> +      mov    %ebx,0x4(%r8)
> +      mov    %ecx,0x8(%r8)
> +      mov    %edx,0xc(%r8)
> +_Exit:
> +      pop    %rbx
> +      retq
> +
> +#------------------------------------------------------------------------------
> +#  UINT64
> +#  EfiReadMsr (
> +#    IN   UINT32  Index,  // rcx
> +#    )
> +#------------------------------------------------------------------------------
> +ASM_PFX(EfiReadMsr):
> +      rdmsr
> +      shl    $0x20,%rdx
> +      or     %rdx,%rax
> +      retq
> +
> +#------------------------------------------------------------------------------
> +#  VOID
> +#  EfiWriteMsr (
> +#    IN   UINT32  Index,  // rcx
> +#    IN   UINT64  Value   // rdx
> +#    )
> +#------------------------------------------------------------------------------
> +ASM_PFX(EfiWriteMsr):
> +      mov    %rdx,%rax
> +      sar    $0x20,%rdx
> +      wrmsr
> +      retq
> +
> +#------------------------------------------------------------------------------
> +# UINT64
> +# EfiReadTsc (
> +#   VOID
> +#   );
> +#------------------------------------------------------------------------------
> +ASM_PFX(EfiReadTsc):
> +      rdtsc
> +      shl    $0x20,%rax
> +      shrd   $0x20,%rdx,%rax
> +      retq
> +
> +#------------------------------------------------------------------------------
> +# VOID
> +# EfiDisableCache (
> +#   VOID
> +#   );
> +#------------------------------------------------------------------------------
> +ASM_PFX(EfiDisableCache):
> +# added a check to see if cache is already disabled. If it is, then skip.
> +      mov    %cr0,%rax
> +      and    $0x60000000,%rax
> +      cmp    $0x0,%rax
> +      jne    1f
> +      mov    %cr0,%rax
> +      or     $0x60000000,%rax
> +      mov    %rax,%cr0
> +      wbinvd
> +1:
> +      retq
> +
> +#------------------------------------------------------------------------------
> +# VOID
> +# EfiEnableCache (
> +#   VOID
> +#   );
> +#------------------------------------------------------------------------------
> +ASM_PFX(EfiEnableCache):
> +      wbinvd
> +      mov    %cr0,%rax
> +      and    $0xffffffff9fffffff,%rax
> +      mov    %rax,%cr0
> +      retq
> +
> +#------------------------------------------------------------------------------
> +# UINTN
> +# EfiGetEflags (
> +#   VOID
> +#   );
> +#------------------------------------------------------------------------------
> +ASM_PFX(EfiGetEflags):
> +      pushfq
> +      pop    %rax
> +      retq
> +
> +#------------------------------------------------------------------------------
> +# VOID
> +# EfiDisableInterrupts (
> +#   VOID
> +#   );
> +#------------------------------------------------------------------------------
> +ASM_PFX(EfiDisableInterrupts):
> +    cli
> +    ret
> +
> +#------------------------------------------------------------------------------
> +# VOID
> +# EfiEnableInterrupts (
> +#   VOID
> +#   );
> +#------------------------------------------------------------------------------
> +ASM_PFX(EfiEnableInterrupts):
> +    sti
> +    ret
> +#------------------------------------------------------------------------------
> +#  VOID
> +#  EfiCpuidExt (
> +#    IN   UINT32              RegisterInEax,
> +#    IN   UINT32              CacheLevel,
> +#    OUT  EFI_CPUID_REGISTER  *Regs
> +#    )
> +#------------------------------------------------------------------------------
> +ASM_PFX(EfiCpuidExt):
> +      push   %rbx
> +      mov    %rcx,%rax
> +      mov    %rdx,%rcx
> +      cpuid
> +      mov    %eax,(%r8)
> +      mov    %ebx,0x4(%r8)
> +      mov    %ecx,0x8(%r8)
> +      mov    %edx,0xc(%r8)
> +      pop    %rbx
> +      retq
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.asm
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.asm
> new file mode 100644
> index 0000000000..44aae7de64
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.asm
> @@ -0,0 +1,222 @@
> +
> +TITLE   Cpu.asm: Assembly code for the x64 resources
> +
> +;
> +; This file contains an 'Intel Sample Driver' and is
> +; licensed for Intel CPUs and chipsets under the terms of your
> +; license agreement with Intel or your vendor.  This file may
> +; be modified by the user, subject to additional terms of the
> +; license agreement
> +;
> +;
> +; Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +;
> 
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +;
> 
> +;
> +;
> +;
> +;
> +;*   Module Name:
> +;*
> +;*    Cpu.asm
> +;*
> +;*   Abstract:
> +;*
> +;------------------------------------------------------------------------------
> +
> +text    SEGMENT
> +
> +
> +;------------------------------------------------------------------------------
> +;  VOID
> +;  EfiHalt (
> +;    VOID
> +;    )
> +;------------------------------------------------------------------------------
> +EfiHalt PROC    PUBLIC
> +    hlt
> +    ret
> +EfiHalt ENDP
> +
> +
> +;------------------------------------------------------------------------------
> +;  VOID
> +;  EfiWbinvd (
> +;    VOID
> +;    )
> +;------------------------------------------------------------------------------
> +EfiWbinvd PROC    PUBLIC
> +    wbinvd
> +    ret
> +EfiWbinvd ENDP
> +
> +
> +;------------------------------------------------------------------------------
> +;  VOID
> +;  EfiInvd (
> +;    VOID
> +;    )
> +;------------------------------------------------------------------------------
> +EfiInvd PROC    PUBLIC
> +    invd
> +    ret
> +EfiInvd ENDP
> +
> +;------------------------------------------------------------------------------
> +;  VOID
> +;  EfiCpuid (
> +;    IN   UINT32              RegisterInEax,          // rcx
> +;    OUT  EFI_CPUID_REGISTER  *Reg           OPTIONAL // rdx
> +;    )
> +;------------------------------------------------------------------------------
> +EfiCpuid PROC   PUBLIC
> +    push  rbx
> +
> +    mov   r8,   rdx         ; r8 = *Reg
> +    mov   rax,  rcx         ; RegisterInEax
> +    cpuid
> +    cmp   r8,   0
> +    je    _Exit
> +    mov   [r8 +  0], eax    ; Reg->RegEax
> +    mov   [r8 +  4], ebx    ; Reg->RegEbx
> +    mov   [r8 +  8], ecx    ; Reg->RegEcx
> +    mov   [r8 + 12], edx    ; Reg->RegEdx
> +
> +_Exit:
> +    pop   rbx
> +    ret
> +EfiCpuid  ENDP
> +
> +;------------------------------------------------------------------------------
> +;  UINT64
> +;  EfiReadMsr (
> +;    IN   UINT32  Index,  // rcx
> +;    )
> +;------------------------------------------------------------------------------
> +EfiReadMsr PROC  PUBLIC
> +    rdmsr
> +    sal     rdx, 32   ; edx:eax -> rax
> +    or      rax, rdx  ; rax = edx:eax
> +    ret
> +EfiReadMsr  ENDP
> +
> +;------------------------------------------------------------------------------
> +;  VOID
> +;  EfiWriteMsr (
> +;    IN   UINT32  Index,  // rcx
> +;    IN   UINT64  Value   // rdx
> +;    )
> +;------------------------------------------------------------------------------
> +EfiWriteMsr PROC   PUBLIC
> +    mov     rax,  rdx   ; rdx = Value
> +    sar     rdx,  32    ; convert rdx to edx upper 32-bits
> +    wrmsr               ; wrmsr[ecx] result = edx:eax
> +    ret
> +EfiWriteMsr  ENDP
> +
> +
> +;------------------------------------------------------------------------------
> +; UINT64
> +; EfiReadTsc (
> +;   VOID
> +;   );
> +;------------------------------------------------------------------------------
> +EfiReadTsc PROC    PUBLIC
> +    rdtsc
> +    shl     rax, 32
> +    shrd    rax, rdx, 32
> +    ret
> +EfiReadTsc  ENDP
> +
> +;------------------------------------------------------------------------------
> +; VOID
> +; EfiDisableCache (
> +;   VOID
> +;   );
> +;------------------------------------------------------------------------------
> +EfiDisableCache PROC    PUBLIC
> +; added a check to see if cache is already disabled. If it is, then skip.
> +    mov   rax, cr0
> +    and   rax, 060000000h
> +    cmp   rax, 0
> +    jne   @f
> +    mov   rax, cr0
> +    or    rax, 060000000h
> +    mov   cr0, rax
> +    wbinvd
> +@@:
> +    ret
> +EfiDisableCache ENDP
> +
> +;------------------------------------------------------------------------------
> +; VOID
> +; EfiEnableCache (
> +;   VOID
> +;   );
> +;------------------------------------------------------------------------------
> +EfiEnableCache PROC    PUBLIC
> +    wbinvd
> +    mov   rax, cr0
> +    and   rax, 09fffffffh
> +    mov   cr0, rax
> +    ret
> +EfiEnableCache ENDP
> +
> +;------------------------------------------------------------------------------
> +; UINTN
> +; EfiGetEflags (
> +;   VOID
> +;   );
> +;------------------------------------------------------------------------------
> +EfiGetEflags PROC    PUBLIC
> +    pushfq
> +    pop   rax
> +    ret
> +EfiGetEflags  ENDP
> +
> +;------------------------------------------------------------------------------
> +; VOID
> +; EfiDisableInterrupts (
> +;   VOID
> +;   );
> +;------------------------------------------------------------------------------
> +EfiDisableInterrupts PROC    PUBLIC
> +    cli
> +    ret
> +EfiDisableInterrupts  ENDP
> +
> +;------------------------------------------------------------------------------
> +; VOID
> +; EfiEnableInterrupts (
> +;   VOID
> +;   );
> +;------------------------------------------------------------------------------
> +EfiEnableInterrupts PROC    PUBLIC
> +    sti
> +    ret
> +EfiEnableInterrupts  ENDP
> +;------------------------------------------------------------------------------
> +;  VOID
> +;  EfiCpuidExt (
> +;    IN   UINT32              RegisterInEax,
> +;    IN   UINT32              CacheLevel,
> +;    OUT  EFI_CPUID_REGISTER  *Regs
> +;    )
> +;------------------------------------------------------------------------------
> +EfiCpuidExt PROC    PUBLIC
> +     push   rbx
> +     mov    rax, rcx          ; rax = RegisterInEax
> +     mov    rcx, rdx          ; rcx = CacheLevel
> +
> +     cpuid
> +     mov    [r8 + 0 ],  eax   ; Reg->RegEax
> +     mov    [r8 + 4 ],  ebx   ; Reg->RegEbx
> +     mov    [r8 + 8 ],  ecx   ; Reg->RegEcx
> +     mov    [r8 + 12],  edx   ; Reg->RegEdx
> +
> +     pop rbx
> +     ret
> +EfiCpuidExt  ENDP
> +END
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.c
> new file mode 100644
> index 0000000000..b7d896d9fd
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.c
> @@ -0,0 +1,282 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  EfiRegTableLib.c
> +
> +Abstract:
> +
> +  Lib function for table driven register initialization.
> +
> +Revision History
> +
> +--*/
> +
> +#include <Library/EfiRegTableLib.h>
> +#include <Library/S3BootScriptLib.h>
> +
> +//
> +// Local Functions
> +//
> +
> +/**
> +  Local worker function to process PCI_WRITE table entries.  Performs write
> and
> +  may also call BootScriptSave protocol if indicated in the Entry flags
> +
> +  @param Entry            A pointer to the PCI_WRITE entry to process
> +
> +  @param PciRootBridgeIo  A pointer to the instance of PciRootBridgeIo that
> is used
> +                          when processing the entry.
> +
> +  @retval Nothing.
> +
> +**/
> +STATIC
> +VOID
> +PciWrite (
> +  EFI_REG_TABLE_PCI_WRITE             *Entry,
> +  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL     *PciRootBridgeIo
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  Status = PciRootBridgeIo->Pci.Write (
> +                                  PciRootBridgeIo,
> +                                  (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)
> (OPCODE_EXTRA_DATA (Entry->OpCode)),
> +                                  (UINT64) Entry->PciAddress,
> +                                  1,
> +                                  &Entry->Data
> +                                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  if (OPCODE_FLAGS (Entry->OpCode) & OPCODE_FLAG_S3SAVE) {
> +    Status = S3BootScriptSavePciCfgWrite (
> +              (EFI_BOOT_SCRIPT_WIDTH) (OPCODE_EXTRA_DATA (Entry-
> >OpCode)),
> +              (UINT64) Entry->PciAddress,
> +              1,
> +              &Entry->Data
> +              );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +}
> +
> +/**
> +  Local worker function to process PCI_READ_MODIFY_WRITE table entries.
> +  Performs RMW write and may also call BootScriptSave protocol if indicated
> in
> +  the Entry flags.
> +
> +  @param Entry            A pointer to the PCI_READ_MODIFY_WRITE entry to
> process.
> +
> +  @param PciRootBridgeIo  A pointer to the instance of PciRootBridgeIo that
> is used
> +                          when processing the entry.
> +
> +  @retval Nothing.
> +
> +**/
> +STATIC
> +VOID
> +PciReadModifyWrite (
> +  EFI_REG_TABLE_PCI_READ_MODIFY_WRITE *Entry,
> +  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL     *PciRootBridgeIo
> +  )
> +{
> +  EFI_STATUS  Status;
> +  UINT32      TempData;
> +
> +  Status = PciRootBridgeIo->Pci.Read (
> +                                  PciRootBridgeIo,
> +                                  (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)
> (OPCODE_EXTRA_DATA (Entry->OpCode)),
> +                                  (UINT64) Entry->PciAddress,
> +                                  1,
> +                                  &TempData
> +                                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Entry->OrMask &= Entry->AndMask;
> +  TempData &= ~Entry->AndMask;
> +  TempData |= Entry->OrMask;
> +
> +  Status = PciRootBridgeIo->Pci.Write (
> +                                  PciRootBridgeIo,
> +                                  (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)
> (OPCODE_EXTRA_DATA (Entry->OpCode)),
> +                                  (UINT64) Entry->PciAddress,
> +                                  1,
> +                                  &TempData
> +                                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  if (OPCODE_FLAGS (Entry->OpCode) & OPCODE_FLAG_S3SAVE) {
> +    Status = S3BootScriptSavePciCfgReadWrite (
> +              (EFI_BOOT_SCRIPT_WIDTH) (OPCODE_EXTRA_DATA (Entry-
> >OpCode)),
> +              (UINT64) Entry->PciAddress,
> +              &Entry->OrMask,
> +              &Entry->AndMask
> +              );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +}
> +
> +/**
> +  Local worker function to process MEM_READ_MODIFY_WRITE table
> entries.
> +  Performs RMW write and may also call BootScriptSave protocol if indicated
> in
> +  the Entry flags.
> +
> +  @param Entry            A pointer to the MEM_READ_MODIFY_WRITE entry to
> process.
> +
> +  @param PciRootBridgeIo  A pointer to the instance of PciRootBridgeIo that
> is used
> +                          when processing the entry.
> +
> +  @retval Nothing.
> +
> +**/
> +STATIC
> +VOID
> +MemReadModifyWrite (
> +  EFI_REG_TABLE_MEM_READ_MODIFY_WRITE *Entry,
> +  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL     *PciRootBridgeIo
> +  )
> +{
> +  EFI_STATUS  Status;
> +  UINT32      TempData;
> +
> +  Status = PciRootBridgeIo->Mem.Read (
> +                                  PciRootBridgeIo,
> +                                  (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)
> (OPCODE_EXTRA_DATA (Entry->OpCode)),
> +                                  (UINT64) Entry->MemAddress,
> +                                  1,
> +                                  &TempData
> +                                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Entry->OrMask &= Entry->AndMask;
> +  TempData &= ~Entry->AndMask;
> +  TempData |= Entry->OrMask;
> +
> +  Status = PciRootBridgeIo->Mem.Write (
> +                                  PciRootBridgeIo,
> +                                  (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)
> (OPCODE_EXTRA_DATA (Entry->OpCode)),
> +                                  (UINT64) Entry->MemAddress,
> +                                  1,
> +                                  &TempData
> +                                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  if (OPCODE_FLAGS (Entry->OpCode) & OPCODE_FLAG_S3SAVE) {
> +    Status = S3BootScriptSaveMemReadWrite (
> +              (EFI_BOOT_SCRIPT_WIDTH) (OPCODE_EXTRA_DATA (Entry-
> >OpCode)),
> +              Entry->MemAddress,
> +              &Entry->OrMask,
> +              &Entry->AndMask
> +              );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +}
> +
> +//
> +// Exported functions
> +//
> +
> +/**
> +  Processes register table assuming which may contain PCI, IO, MEM, and
> STALL
> +  entries.
> +
> +  No parameter checking is done so the caller must be careful about omitting
> +  values for PciRootBridgeIo or CpuIo parameters.  If the regtable does
> +  not contain any PCI accesses, it is safe to omit the PciRootBridgeIo (supply
> +  NULL).  If the regtable does not contain any IO or Mem entries, it is safe to
> +  omit the CpuIo (supply NULL).
> +
> +  The RegTableEntry parameter is not checked, but is required.
> +
> +  gBS is assumed to have been defined and is used when processing stalls.
> +
> +  The function processes each entry sequentially until an
> OP_TERMINATE_TABLE
> +  entry is encountered.
> +
> +  @param RegTableEntry    A pointer to the register table to process
> +
> +  @param PciRootBridgeIo  A pointer to the instance of PciRootBridgeIo that
> is used
> +                          when processing PCI table entries
> +
> +  @param CpuIo            A pointer to the instance of CpuIo that is used when
> processing IO and
> +                          MEM table entries
> +
> +  @retval Nothing.
> +
> +**/
> +VOID
> +ProcessRegTablePci (
> +  EFI_REG_TABLE                       *RegTableEntry,
> +  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL     *PciRootBridgeIo,
> +  EFI_CPU_IO_PROTOCOL                 *CpuIo
> +  )
> +{
> +  while (OPCODE_BASE (RegTableEntry->Generic.OpCode) !=
> OP_TERMINATE_TABLE) {
> +    switch (OPCODE_BASE (RegTableEntry->Generic.OpCode)) {
> +    case OP_PCI_WRITE:
> +      PciWrite ((EFI_REG_TABLE_PCI_WRITE *) RegTableEntry,
> PciRootBridgeIo);
> +      break;
> +
> +    case OP_PCI_READ_MODIFY_WRITE:
> +      PciReadModifyWrite ((EFI_REG_TABLE_PCI_READ_MODIFY_WRITE *)
> RegTableEntry, PciRootBridgeIo);
> +      break;
> +
> +    case OP_MEM_READ_MODIFY_WRITE:
> +      MemReadModifyWrite ((EFI_REG_TABLE_MEM_READ_MODIFY_WRITE
> *) RegTableEntry, PciRootBridgeIo);
> +      break;
> +
> +    default:
> +      DEBUG ((EFI_D_ERROR, "RegTable ERROR: Unknown RegTable OpCode
> (%x)\n", OPCODE_BASE (RegTableEntry->Generic.OpCode)));
> +      ASSERT (0);
> +      break;
> +    }
> +
> +    RegTableEntry++;
> +  }
> +}
> +
> +/**
> +  Processes register table assuming which may contain IO, MEM, and STALL
> +  entries, but must NOT contain any PCI entries.  Any PCI entries cause an
> +  ASSERT in a DEBUG build and are skipped in a free build.
> +
> +  No parameter checking is done.  Both RegTableEntry and CpuIo
> parameters are
> +  required.
> +
> +  gBS is assumed to have been defined and is used when processing stalls.
> +
> +  The function processes each entry sequentially until an
> OP_TERMINATE_TABLE
> +  entry is encountered.
> +
> +  @param  RegTableEntry   A pointer to the register table to process
> +
> +  @param  CpuIo           A pointer to the instance of CpuIo that is used when
> processing IO and
> +                          MEM table entries
> +
> +  @retval Nothing.
> +
> +**/
> +VOID
> +ProcessRegTableCpu (
> +  EFI_REG_TABLE                       *RegTableEntry,
> +  EFI_CPU_IO_PROTOCOL                 *CpuIo
> +  )
> +{
> +  while (OPCODE_BASE (RegTableEntry->Generic.OpCode) !=
> OP_TERMINATE_TABLE) {
> +    switch (OPCODE_BASE (RegTableEntry->Generic.OpCode)) {
> +    default:
> +      DEBUG ((EFI_D_ERROR, "RegTable ERROR: Unknown RegTable OpCode
> (%x)\n", OPCODE_BASE (RegTableEntry->Generic.OpCode)));
> +      ASSERT (0);
> +      break;
> +    }
> +
> +    RegTableEntry++;
> +  }
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.in
> f
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.in
> f
> new file mode 100644
> index 0000000000..9cb8841d65
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.in
> f
> @@ -0,0 +1,47 @@
> +#
> +#
> +#/*++
> +#
> +# Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +
> +#
> +#  Module Name:
> +#
> +#    EfiRegTableLib.inf
> +#
> +#  Abstract:
> +#
> +#    Component description file.
> +#
> +#--*/
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = EfiRegTableLib
> +  FILE_GUID                      = 98546145-64F1-4d2e-814F-6BF963DB7930
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = EfiRegTableLib
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +
> +[Sources]
> +  EfiRegTableLib.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  IntelFrameworkPkg/IntelFrameworkPkg.dec
> +
> +
> +[LibraryClasses]
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.c
> new file mode 100644
> index 0000000000..558763fa98
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.c
> @@ -0,0 +1,461 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +**/
> +
> +#include <PiDxe.h>
> +
> +#include <Library/FlashDeviceLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiRuntimeLib.h>
> +#include <Protocol/SmmBase2.h>
> +#include <Guid/EventGroup.h>
> +#include "SpiChipDefinitions.h"
> +
> +UINTN FlashDeviceBase = FLASH_DEVICE_BASE_ADDRESS;
> +
> +EFI_SPI_PROTOCOL *mSpiProtocol = NULL;
> +
> +EFI_STATUS
> +SpiFlashErase (
> +  UINT8 *BaseAddress,
> +  UINTN NumBytes
> +  )
> +{
> +  EFI_STATUS          Status = EFI_SUCCESS;
> +  UINT32              SectorSize;
> +  UINT32              SpiAddress;
> +
> +  SpiAddress = (UINT32)(UINTN)(BaseAddress) - (UINT32)FlashDeviceBase;
> +  SectorSize = SECTOR_SIZE_4KB;
> +  while ( (NumBytes > 0) && (NumBytes <= MAX_FWH_SIZE) ) {
> +    Status = mSpiProtocol->Execute (
> +                             mSpiProtocol,
> +                             SPI_SERASE,
> +                             SPI_WREN,
> +                             FALSE,
> +                             TRUE,
> +                             FALSE,
> +                             (UINT32) SpiAddress,
> +                             0,
> +                             NULL,
> +                             EnumSpiRegionBios
> +                             );
> +    if (EFI_ERROR (Status)) {
> +      break;
> +    }
> +    SpiAddress += SectorSize;
> +    NumBytes   -= SectorSize;
> +  }
> +
> +  return Status;
> +}
> +
> +
> +EFI_STATUS
> +SpiFlashBlockErase (
> +  UINT8 *BaseAddress,
> +  UINTN NumBytes
> +  )
> +{
> +  EFI_STATUS          Status = EFI_SUCCESS;
> +  UINT32              SectorSize;
> +  UINT32              SpiAddress;
> +
> +  SpiAddress = (UINT32)(UINTN)(BaseAddress) - (UINT32)FlashDeviceBase;
> +  SectorSize = SECTOR_SIZE_4KB;
> +  while ( (NumBytes > 0) && (NumBytes <= MAX_FWH_SIZE) ) {
> +    Status = mSpiProtocol->Execute (
> +                             mSpiProtocol,
> +                             SPI_SERASE,
> +                             SPI_WREN,
> +                             FALSE,
> +                             TRUE,
> +                             FALSE,
> +                             (UINT32) SpiAddress,
> +                             0,
> +                             NULL,
> +                             EnumSpiRegionBios
> +                             );
> +    if (EFI_ERROR (Status)) {
> +      break;
> +    }
> +    SpiAddress += SectorSize;
> +    NumBytes   -= SectorSize;
> +  }
> +
> +  return Status;
> +}
> +
> +
> +static
> +EFI_STATUS
> +SpiFlashWrite (
> +  UINT8 *DstBufferPtr,
> +  UINT8 *Byte,
> +  IN  UINTN Length
> +  )
> +{
> +  EFI_STATUS                Status;
> +  UINT32                    NumBytes = (UINT32)Length;
> +  UINT8*                    pBuf8 = Byte;
> +  UINT32                    SpiAddress;
> +
> +  SpiAddress = (UINT32)(UINTN)(DstBufferPtr) - (UINT32)FlashDeviceBase;
> +  Status = mSpiProtocol->Execute (
> +                           mSpiProtocol,
> +                           SPI_PROG,
> +                           SPI_WREN,
> +                           TRUE,
> +                           TRUE,
> +                           TRUE,
> +                           (UINT32)SpiAddress,
> +                           NumBytes,
> +                           pBuf8,
> +                           EnumSpiRegionBios
> +                           );
> +  return Status;
> +}
> +
> +/**
> +  Read the Serial Flash Status Registers.
> +
> +  @param  SpiStatus         Pointer to a caller-allocated UINT8. On successful
> return, it contains the
> +                            status data read from the Serial Flash Status Register.
> +
> +
> +  @retval EFI_SUCCESS       Operation success, status is returned in SpiStatus.
> +  @retval EFI_DEVICE_ERROR  The block device is not functioning correctly
> and the operation failed.
> +
> +**/
> +EFI_STATUS
> +ReadStatusRegister (
> +  UINT8   *SpiStatus
> +  )
> +{
> +  EFI_STATUS          Status;
> +
> +  Status = mSpiProtocol->Execute (
> +             mSpiProtocol,
> +             SPI_RDSR,
> +             SPI_WREN,
> +             TRUE,
> +             FALSE,
> +             FALSE,
> +             0,
> +             1,
> +             SpiStatus,
> +             EnumSpiRegionBios
> +             );
> +  return Status;
> +}
> +
> +EFI_STATUS
> +SpiFlashLock (
> +    IN  UINT8  *BaseAddress,
> +    IN  UINTN  NumBytes,
> +    IN  BOOLEAN  Lock
> +  )
> +{
> +  EFI_STATUS          Status;
> +  UINT8               SpiData;
> +  UINT8               SpiStatus;
> +
> +  if (Lock) {
> +    SpiData = SF_SR_WPE;
> +  } else {
> +    SpiData = 0;
> +  }
> +
> +  //
> +  // Always disable block protection to workaround tool issue.
> +  // Feature may be re-enabled in a future bios.
> +  //
> +  SpiData = 0;
> +  Status = mSpiProtocol->Execute (
> +                           mSpiProtocol,
> +                           SPI_WRSR,
> +                           SPI_EWSR,
> +                           TRUE,
> +                           TRUE,
> +                           TRUE,
> +                           0,
> +                           1,
> +                           &SpiData,
> +                           EnumSpiRegionBios
> +                           );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = ReadStatusRegister (&SpiStatus);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  if ((SpiStatus & SpiData) != SpiData) {
> +    Status = EFI_DEVICE_ERROR;
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Read NumBytes bytes of data from the address specified by
> +  PAddress into Buffer.
> +
> +  @param[in]      PAddress          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
> +LibFvbFlashDeviceRead (
> +  IN      UINTN                           PAddress,
> +  IN  OUT UINTN                           *NumBytes,
> +      OUT UINT8                           *Buffer
> +  )
> +{
> +  CopyMem(Buffer, (VOID*)PAddress, *NumBytes);
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Write NumBytes bytes of data from Buffer to the address specified by
> +  PAddresss.
> +
> +  @param[in]      PAddress          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
> +LibFvbFlashDeviceWrite (
> +  IN        UINTN                           PAddress,
> +  IN OUT    UINTN                           *NumBytes,
> +  IN        UINT8                           *Buffer
> +  )
> +{
> +EFI_STATUS Status;
> +  Status =  SpiFlashWrite((UINT8 *)PAddress, Buffer, *NumBytes);
> + return Status;
> +}
> +
> +
> +/**
> +  Erase the block staring at PAddress.
> +
> +  @param[in]  PAddress          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]  LbaLength         The length of the logical block to be erased.
> +
> +  @retval     EFI_SUCCESS.      Opertion is successful.
> +  @retval     EFI_DEVICE_ERROR  If there is any device errors.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +LibFvbFlashDeviceBlockErase (
> +  IN    UINTN                     PAddress,
> +  IN    UINTN                     LbaLength
> +  )
> +{
> +  EFI_STATUS Status;
> +  Status = SpiFlashBlockErase((UINT8 *)PAddress, LbaLength);
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Lock or unlock the block staring at PAddress.
> +
> +  @param[in]  PAddress        The starting physical address of region to be
> (un)locked.
> +  @param[in]  LbaLength       The length of the logical block to be erased.
> +  @param[in]  Lock            TRUE to lock. FALSE to unlock.
> +
> +  @retval     EFI_SUCCESS.      Opertion is successful.
> +  @retval     EFI_DEVICE_ERROR  If there is any device errors.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +LibFvbFlashDeviceBlockLock (
> +  IN    UINTN                          PAddress,
> +  IN    UINTN                          LbaLength,
> +  IN    BOOLEAN                        Lock
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +    Status = SpiFlashLock((UINT8*)PAddress, LbaLength, Lock);
> +  return Status;
> +}
> +
> +VOID
> +EFIAPI
> +LibFvbFlashDeviceVirtualAddressChangeNotifyEvent (
> +  IN EFI_EVENT        Event,
> +  IN VOID             *Context
> +  )
> +{
> +  gRT->ConvertPointer (0, (VOID **) &mSpiProtocol);
> +  gRT->ConvertPointer (0, (VOID **) &FlashDeviceBase);
> +}
> +
> +
> +/**
> +  The library constructuor.
> +
> +  The function does the necessary initialization work for this library
> +  instance. Please put all initialization works in it.
> +
> +  @param[in]  ImageHandle       The firmware allocated handle for the UEFI
> image.
> +  @param[in]  SystemTable       A pointer to the EFI system table.
> +
> +  @retval     EFI_SUCCESS       The function always return EFI_SUCCESS for
> now.
> +                                It will ASSERT on error for debug version.
> +  @retval     EFI_ERROR         Please reference LocateProtocol for error code
> details.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +LibFvbFlashDeviceSupportInit (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  )
> +{
> +  EFI_STATUS Status;
> +  EFI_EVENT  Event;
> +  UINT8                         SfId[3];
> +  UINT8                         FlashIndex;
> +  UINT8                         SpiReadError;
> +  UINT8                         SpiNotMatchError;
> +  EFI_SMM_BASE2_PROTOCOL       *SmmBase;
> +  BOOLEAN                       InSmm;
> +
> +  SpiReadError     = 0x00;
> +  SpiNotMatchError = 0x00;
> +
> +  InSmm = FALSE;
> +  Status = gBS->LocateProtocol (
> +                  &gEfiSmmBase2ProtocolGuid,
> +                  NULL,
> +                  (void **)&SmmBase
> +                  );
> +  if (!EFI_ERROR(Status)) {
> +    Status = SmmBase->InSmm(SmmBase, &InSmm);
> +    if (EFI_ERROR(Status)) {
> +      InSmm = FALSE;
> +    }
> +  }
> +
> +  if (!InSmm) {
> +    Status = gBS->LocateProtocol (
> +                  &gEfiSpiProtocolGuid,
> +                  NULL,
> +                  (VOID **)&mSpiProtocol
> +                  );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_NOTIFY,
> +                  LibFvbFlashDeviceVirtualAddressChangeNotifyEvent,
> +                  NULL,
> +                  &gEfiEventVirtualAddressChangeGuid,
> +                  &Event
> +                  );
> +    ASSERT_EFI_ERROR (Status);
> +  } else {
> +    Status = gBS->LocateProtocol (
> +                    &gEfiSmmSpiProtocolGuid,
> +                    NULL,
> +                    (VOID **)&mSpiProtocol
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +
> +  for (FlashIndex = EnumSpiFlashW25Q64; FlashIndex < EnumSpiFlashMax;
> FlashIndex++) {
> +    Status = mSpiProtocol->Init (mSpiProtocol, &(mInitTable[FlashIndex]));
> +    if (!EFI_ERROR (Status)) {
> +      //
> +      // Read Vendor/Device IDs to check if the driver supports the Serial Flash
> device.
> +      //
> +      Status = mSpiProtocol->Execute (
> +                               mSpiProtocol,
> +                               SPI_READ_ID,
> +                               SPI_WREN,
> +                               TRUE,
> +                               FALSE,
> +                               FALSE,
> +                               0,
> +                               3,
> +                               SfId,
> +                               EnumSpiRegionAll
> +                               );
> +      if (!EFI_ERROR (Status)) {
> +        if ((SfId[0] == mInitTable[FlashIndex].VendorId)  &&
> +            (SfId[1] == mInitTable[FlashIndex].DeviceId0) &&
> +            (SfId[2] == mInitTable[FlashIndex].DeviceId1)) {
> +            //
> +            // Found a matching SPI device, FlashIndex now contains flash device.
> +            //
> +            DEBUG ((DEBUG_ERROR, "OK - Found SPI Flash Type in SPI Flash
> Driver, Device Type ID 0 = 0x%02x!\n", mInitTable[FlashIndex].DeviceId0));
> +            DEBUG ((DEBUG_ERROR, "Device Type ID 1 = 0x%02x!\n",
> mInitTable[FlashIndex].DeviceId1));
> +
> +            if (mInitTable[FlashIndex].BiosStartOffset == (UINTN) (-1)) {
> +              DEBUG ((DEBUG_ERROR, "ERROR - The size of BIOS image is bigger
> than SPI Flash device!\n"));
> +              CpuDeadLoop ();
> +            }
> +            break;
> +        } else {
> +          SpiNotMatchError++;
> +        }
> +      } else {
> +        SpiReadError++;
> +      }
> +    }
> +  }
> +
> +  DEBUG ((DEBUG_ERROR, "SPI flash chip VID = 0x%X, DID0 = 0x%X, DID1 =
> 0x%X\n", SfId[0], SfId[1], SfId[2]));
> +
> +  if (FlashIndex < EnumSpiFlashMax)  {
> +    return EFI_SUCCESS;
> +  } else {
> +  if (SpiReadError != 0) {
> +      DEBUG ((DEBUG_ERROR, "ERROR - SPI Read ID execution failed! Error
> Count = %d\n", SpiReadError));
> +   }
> +    else {
> +      if (SpiNotMatchError != 0) {
> +        DEBUG ((DEBUG_ERROR, "ERROR - No supported SPI flash chip found!
> Error Count = %d\n", SpiNotMatchError));
> +        DEBUG ((DEBUG_ERROR, "SPI flash chip VID = 0x%X, DID0 = 0x%X, DID1
> = 0x%X\n", SfId[0], SfId[1], SfId[2]));
> +      }
> +    }
> +    return EFI_UNSUPPORTED;
> +  }
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.in
> f
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.i
> nf
> new file mode 100644
> index 0000000000..4ef48cc12b
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.i
> nf
> @@ -0,0 +1,44 @@
> +#
> +#
> +# Copyright (c)  1999  - 2016, Intel Corporation. All rights reserved
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +#
> +
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = FlashDeviceLib
> +  FILE_GUID                      = E38A1C3C-928C-4bf7-B6C1-7F0EF163FAA5
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = FlashDeviceLib | DXE_SMM_DRIVER
> DXE_RUNTIME_DRIVER
> +  CONSTRUCTOR                    = LibFvbFlashDeviceSupportInit
> +
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +[Sources]
> +  FlashDeviceLib.c
> +
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +
> +[LibraryClasses]
> +  DebugLib
> +
> +[Protocols]
> +  gEfiSpiProtocolGuid
> +  gEfiSmmSpiProtocolGuid
> +  gEfiSmmBase2ProtocolGuid
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibD
> xe.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibD
> xe.c
> new file mode 100644
> index 0000000000..cf4677ed88
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibD
> xe.c
> @@ -0,0 +1,56 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +**/
> +
> +#include <PiDxe.h>
> +
> +#include <Library/FlashDeviceLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include "SpiChipDefinitions.h"
> +
> +extern UINTN FlashDeviceBase;
> +
> +extern EFI_SPI_PROTOCOL *mSpiProtocol;
> +
> +/**
> +  The library constructuor.
> +
> +  The function does the necessary initialization work for this library
> +  instance. Please put all initialization works in it.
> +
> +  @param[in]  ImageHandle       The firmware allocated handle for the UEFI
> image.
> +  @param[in]  SystemTable       A pointer to the EFI system table.
> +
> +  @retval     EFI_SUCCESS       The function always return EFI_SUCCESS for
> now.
> +                                It will ASSERT on error for debug version.
> +  @retval     EFI_ERROR         Please reference LocateProtocol for error code
> details.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +LibFvbFlashDeviceSupportInit (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  )
> +{
> +  EFI_STATUS Status;
> +  Status = gBS->LocateProtocol (
> +                  &gEfiSpiProtocolGuid,
> +                  NULL,
> +                  (VOID **)&mSpiProtocol
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +  // There is no need to call Init, because Runtime or SMM FVB already does
> that.
> +  DEBUG((EFI_D_ERROR, "LibFvbFlashDeviceSupportInit - no init\n"));
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibD
> xe.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibD
> xe.inf
> new file mode 100644
> index 0000000000..2237e95781
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibD
> xe.inf
> @@ -0,0 +1,43 @@
> +#
> +#
> +# Copyright (c)  1999  - 2016, Intel Corporation. All rights reserved
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +#
> +
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = FlashDeviceLibDxe
> +  FILE_GUID                      = F0D7222F-FD43-4A5D-B8BF-A259C87AE3B2
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = FlashDeviceLib | DXE_DRIVER
> +  CONSTRUCTOR                    = LibFvbFlashDeviceSupportInit
> +
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +[Sources]
> +  FlashDeviceLib.c
> +  FlashDeviceLibDxe.c
> +
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +
> +[LibraryClasses]
> +  DebugLib
> +
> +[Protocols]
> +  gEfiSpiProtocolGuid
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibD
> xeRuntimeSmm.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibD
> xeRuntimeSmm.c
> new file mode 100644
> index 0000000000..df395fbc03
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibD
> xeRuntimeSmm.c
> @@ -0,0 +1,173 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +**/
> +
> +#include <PiDxe.h>
> +
> +#include <Library/FlashDeviceLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiRuntimeLib.h>
> +#include <Protocol/SmmBase2.h>
> +#include <Guid/EventGroup.h>
> +#include "SpiChipDefinitions.h"
> +
> +extern UINTN FlashDeviceBase;
> +
> +extern EFI_SPI_PROTOCOL *mSpiProtocol;
> +
> +VOID
> +EFIAPI
> +LibFvbFlashDeviceVirtualAddressChangeNotifyEvent (
> +  IN EFI_EVENT        Event,
> +  IN VOID             *Context
> +  )
> +{
> +  gRT->ConvertPointer (0, (VOID **) &mSpiProtocol);
> +  gRT->ConvertPointer (0, (VOID **) &FlashDeviceBase);
> +}
> +
> +
> +/**
> +  The library constructuor.
> +
> +  The function does the necessary initialization work for this library
> +  instance. Please put all initialization works in it.
> +
> +  @param[in]  ImageHandle       The firmware allocated handle for the UEFI
> image.
> +  @param[in]  SystemTable       A pointer to the EFI system table.
> +
> +  @retval     EFI_SUCCESS       The function always return EFI_SUCCESS for
> now.
> +                                It will ASSERT on error for debug version.
> +  @retval     EFI_ERROR         Please reference LocateProtocol for error code
> details.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +LibFvbFlashDeviceSupportInit (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  )
> +{
> +  EFI_STATUS Status;
> +  EFI_EVENT  Event;
> +  UINT8                         SfId[3];
> +  UINT8                         FlashIndex;
> +  UINT8                         SpiReadError;
> +  UINT8                         SpiNotMatchError;
> +  EFI_SMM_BASE2_PROTOCOL       *SmmBase;
> +  BOOLEAN                       InSmm;
> +
> +  SpiReadError     = 0x00;
> +  SpiNotMatchError = 0x00;
> +
> +  InSmm = FALSE;
> +  Status = gBS->LocateProtocol (
> +                  &gEfiSmmBase2ProtocolGuid,
> +                  NULL,
> +                  (void **)&SmmBase
> +                  );
> +  if (!EFI_ERROR(Status)) {
> +    Status = SmmBase->InSmm(SmmBase, &InSmm);
> +    if (EFI_ERROR(Status)) {
> +      InSmm = FALSE;
> +    }
> +  }
> +
> +  if (!InSmm) {
> +    Status = gBS->LocateProtocol (
> +                  &gEfiSpiProtocolGuid,
> +                  NULL,
> +                  (VOID **)&mSpiProtocol
> +                  );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_NOTIFY,
> +                  LibFvbFlashDeviceVirtualAddressChangeNotifyEvent,
> +                  NULL,
> +                  &gEfiEventVirtualAddressChangeGuid,
> +                  &Event
> +                  );
> +    ASSERT_EFI_ERROR (Status);
> +
> +  } else {
> +    Status = gBS->LocateProtocol (
> +                    &gEfiSmmSpiProtocolGuid,
> +                    NULL,
> +                    (VOID **)&mSpiProtocol
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +
> +  for (FlashIndex = EnumSpiFlashW25Q64; FlashIndex < EnumSpiFlashMax;
> FlashIndex++) {
> +    Status = mSpiProtocol->Init (mSpiProtocol, &(mInitTable[FlashIndex]));
> +    if (!EFI_ERROR (Status)) {
> +      //
> +      // Read Vendor/Device IDs to check if the driver supports the Serial Flash
> device.
> +      //
> +      Status = mSpiProtocol->Execute (
> +                               mSpiProtocol,
> +                               SPI_READ_ID,
> +                               SPI_WREN,
> +                               TRUE,
> +                               FALSE,
> +                               FALSE,
> +                               0,
> +                               3,
> +                               SfId,
> +                               EnumSpiRegionAll
> +                               );
> +      if (!EFI_ERROR (Status)) {
> +        if ((SfId[0] == mInitTable[FlashIndex].VendorId)  &&
> +            (SfId[1] == mInitTable[FlashIndex].DeviceId0) &&
> +            (SfId[2] == mInitTable[FlashIndex].DeviceId1)) {
> +            //
> +            // Found a matching SPI device, FlashIndex now contains flash device.
> +            //
> +            DEBUG ((EFI_D_ERROR, "OK - Found SPI Flash Type in SPI Flash Driver,
> Device Type ID 0 = 0x%02x!\n", mInitTable[FlashIndex].DeviceId0));
> +            DEBUG ((EFI_D_ERROR, "Device Type ID 1 = 0x%02x!\n",
> mInitTable[FlashIndex].DeviceId1));
> +
> +            if (mInitTable[FlashIndex].BiosStartOffset == (UINTN) (-1)) {
> +              DEBUG ((EFI_D_ERROR, "ERROR - The size of BIOS image is bigger
> than SPI Flash device!\n"));
> +              CpuDeadLoop ();
> +            }
> +            break;
> +        } else {
> +          SpiNotMatchError++;
> +        }
> +      } else {
> +        SpiReadError++;
> +      }
> +    }
> +  }
> +
> +  DEBUG ((EFI_D_ERROR, "SPI flash chip VID = 0x%X, DID0 = 0x%X, DID1 =
> 0x%X\n", SfId[0], SfId[1], SfId[2]));
> +
> +  if (FlashIndex < EnumSpiFlashMax)  {
> +    return EFI_SUCCESS;
> +  } else {
> +  if (SpiReadError != 0) {
> +      DEBUG ((EFI_D_ERROR, "ERROR - SPI Read ID execution failed! Error
> Count = %d\n", SpiReadError));
> +   }
> +    else {
> +      if (SpiNotMatchError != 0) {
> +        DEBUG ((EFI_D_ERROR, "ERROR - No supported SPI flash chip found!
> Error Count = %d\n", SpiNotMatchError));
> +        DEBUG ((EFI_D_ERROR, "SPI flash chip VID = 0x%X, DID0 = 0x%X, DID1 =
> 0x%X\n", SfId[0], SfId[1], SfId[2]));
> +      }
> +    }
> +    return EFI_UNSUPPORTED;
> +  }
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/SpiChipDefinitio
> ns.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/SpiChipDefinitio
> ns.h
> new file mode 100644
> index 0000000000..c20ee6e372
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/SpiChipDefinitio
> ns.h
> @@ -0,0 +1,835 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +**/
> +
> +#include <Library/SpiFlash.H>
> +
> +#define FLASH_SIZE  0x400000
> +#define FLASH_DEVICE_BASE_ADDRESS (0xFFFFFFFF-FLASH_SIZE+1)
> +
> +//
> +// Serial Flash device initialization data table provided to the
> +// Intel(R) SPI Host Controller Compatibility Interface.
> +//
> +SPI_INIT_TABLE  mInitTable[] = {
> +  {
> +  SF_VENDOR_ID_WINBOND,     // VendorId
> +  SF_DEVICE_ID0_W25QXX,     // DeviceId 0
> +  SF_DEVICE_ID1_W25Q64,     // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_EWSR            // Prefix Opcode 1: Enable Write Status Register
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId           },     // Opcode 0: Read
> ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz,
> EnumSpiOperationReadData          },     // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus        },     // Opcode 2:
> Read Status Register
> +    {EnumSpiOpcodeRead,           SF_INST_SFDP,           EnumSpiCycle50MHz,
> EnumSpiOperationDiscoveryParameters},    // Opcode 3: Serial Flash
> Discovery Parameters
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte     },     // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte    },     // Opcode 5:
> Block Erase (64KB
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus       },     // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((WINBOND_W25Q64_SIZE >= FLASH_SIZE) ? WINBOND_W25Q64_SIZE -
> FLASH_SIZE : (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_ATMEL,       // VendorId
> +  SF_DEVICE_ID0_AT25DF321A,  // DeviceId 0
> +  SF_DEVICE_ID1_AT25DF321A, // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't
> support EWSR).
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId           },     // Opcode 0: Read
> ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz,
> EnumSpiOperationReadData          },     // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus        },     // Opcode 2:
> Read Status Register
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,
> EnumSpiCycle50MHz, EnumSpiOperationWriteDisable      },     // Opcode 3:
> Write Disable
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte     },     // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte    },     // Opcode 5:
> Block Erase (32KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus       },     // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((ATMEL_AT25DF321A_SIZE >= FLASH_SIZE) ? ATMEL_AT25DF321A_SIZE -
> FLASH_SIZE : (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_ATMEL,       // VendorId
> +  SF_DEVICE_ID0_AT26DF321,  // DeviceId 0
> +  SF_DEVICE_ID1_AT26DF321,  // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't
> support EWSR).
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId           },     // Opcode 0: Read
> ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz,
> EnumSpiOperationReadData          },     // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus        },     // Opcode 2:
> Read Status Register
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,
> EnumSpiCycle50MHz, EnumSpiOperationWriteDisable      },     // Opcode 3:
> Write Disable
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte     },     // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte    },     // Opcode 5:
> Block Erase (32KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus       },     // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((ATMEL_AT26DF321_SIZE >= FLASH_SIZE) ? ATMEL_AT26DF321_SIZE -
> FLASH_SIZE : (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_ATMEL,       // VendorId
> +  SF_DEVICE_ID0_AT25DF641,  // DeviceId 0
> +  SF_DEVICE_ID1_AT25DF641,  // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't
> support EWSR).
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId           },     // Opcode 0: Read
> ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz,
> EnumSpiOperationReadData          },     // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus        },     // Opcode 2:
> Read Status Register
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,
> EnumSpiCycle50MHz, EnumSpiOperationWriteDisable      },     // Opcode 3:
> Write Disable
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte     },     // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte    },     // Opcode 5:
> Block Erase (32KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus       },     // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((ATMEL_AT25DF641_SIZE >= FLASH_SIZE) ? ATMEL_AT25DF641_SIZE -
> FLASH_SIZE : (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_WINBOND,     // VendorId
> +  SF_DEVICE_ID0_W25QXX,     // DeviceId 0
> +  SF_DEVICE_ID1_W25Q16,     // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_EWSR            // Prefix Opcode 1: Enable Write Status Register
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId           },     // Opcode 0: Read
> ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz,
> EnumSpiOperationReadData          },     // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus        },     // Opcode 2:
> Read Status Register
> +    {EnumSpiOpcodeRead,           SF_INST_SFDP,           EnumSpiCycle50MHz,
> EnumSpiOperationDiscoveryParameters},    // Opcode 3: Serial Flash
> Discovery Parameters
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte     },     // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte    },     // Opcode 5:
> Block Erase (64KB
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus       },     // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((WINBOND_W25Q16_SIZE >= FLASH_SIZE) ? WINBOND_W25Q16_SIZE -
> FLASH_SIZE : (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_WINBOND,     // VendorId
> +  SF_DEVICE_ID0_W25QXX,     // DeviceId 0
> +  SF_DEVICE_ID1_W25Q32,     // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_EWSR            // Prefix Opcode 1: Enable Write Status Register.
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId           },     // Opcode 0: Read
> ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz,
> EnumSpiOperationReadData          },     // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus        },     // Opcode 2:
> Read Status Register
> +    {EnumSpiOpcodeRead,           SF_INST_SFDP,           EnumSpiCycle50MHz,
> EnumSpiOperationDiscoveryParameters},    // Opcode 3: Serial Flash
> Discovery Parameters
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte     },     // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte    },     // Opcode 5:
> Block Erase (64KB
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus       },     // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((WINBOND_W25Q32_SIZE >= FLASH_SIZE) ? WINBOND_W25Q32_SIZE -
> FLASH_SIZE : (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_WINBOND,     // VendorId
> +  SF_DEVICE_ID0_W25XXX,     // DeviceId 0
> +  SF_DEVICE_ID1_W25X32,     // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_EWSR            // Prefix Opcode 1: Enable Write Status Register
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId           },     // Opcode 0: Read
> ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz,
> EnumSpiOperationReadData          },     // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus        },     // Opcode 2:
> Read Status Register
> +    {EnumSpiOpcodeRead,           SF_INST_SFDP,           EnumSpiCycle50MHz,
> EnumSpiOperationDiscoveryParameters},    // Opcode 3: Serial Flash
> Discovery Parameters
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte     },     // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte    },     // Opcode 5:
> Block Erase (64KB
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus       },     // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((WINBOND_W25X32_SIZE >= FLASH_SIZE) ? WINBOND_W25X32_SIZE -
> FLASH_SIZE : (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_WINBOND,     // VendorId
> +  SF_DEVICE_ID0_W25XXX,     // DeviceId 0
> +  SF_DEVICE_ID1_W25X64,     // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_EWSR            // Prefix Opcode 1: Enable Write Status Register
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId      },     // Opcode 0: Read ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz,
> EnumSpiOperationReadData      },     // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },     // Opcode 2: Read
> Status Register
> +    {EnumSpiOpcodeRead,           SF_INST_SFDP,           EnumSpiCycle50MHz,
> EnumSpiOperationDiscoveryParameters},    // Opcode 3: Serial Flash
> Discovery Parameters
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte  },     // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },     // Opcode 5:
> Block Erase (64KB
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},    // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },     // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((WINBOND_W25X64_SIZE >= FLASH_SIZE) ? WINBOND_W25X64_SIZE -
> FLASH_SIZE : (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_WINBOND,     // VendorId
> +  SF_DEVICE_ID0_W25QXX,     // DeviceId 0
> +  SF_DEVICE_ID1_W25Q128,    // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_EWSR            // Prefix Opcode 1: Enable Write Status Register
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId           },     // Opcode 0: Read
> ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz,
> EnumSpiOperationReadData          },     // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus        },     // Opcode 2:
> Read Status Register
> +    {EnumSpiOpcodeRead,           SF_INST_SFDP,           EnumSpiCycle50MHz,
> EnumSpiOperationDiscoveryParameters},    // Opcode 3: Serial Flash
> Discovery Parameters
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte     },     // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte    },     // Opcode 5:
> Block Erase (64KB
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus       },     // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((WINBOND_W25Q128_SIZE >= FLASH_SIZE) ? WINBOND_W25Q128_SIZE -
> FLASH_SIZE : (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_MACRONIX,    // VendorId
> +  SF_DEVICE_ID0_MX25LXX,    // DeviceId 0
> +  SF_DEVICE_ID1_MX25L16,    // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_EWSR            // Prefix Opcode 1:  Write Enable (this part doesn't
> support EWSR).
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle33MHz,
> EnumSpiOperationReadData      },      // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read
> Status Register
> +    {EnumSpiOpcodeRead,           SF_INST_SFDP,           EnumSpiCycle50MHz,
> EnumSpiOperationDiscoveryParameters},    // Opcode 3: Serial Flash
> Discovery Parameters
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5:
> Block Erase (64KB
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((MACRONIX_MX25L16_SIZE >= FLASH_SIZE) ? MACRONIX_MX25L16_SIZE
> - FLASH_SIZE : (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_MACRONIX,    // VendorId
> +  SF_DEVICE_ID0_MX25LXX,    // DeviceId 0
> +  SF_DEVICE_ID1_MX25L32,    // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_EWSR            // Prefix Opcode 1:  Write Enable (this part doesn't
> support EWSR).
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle33MHz,
> EnumSpiOperationReadData      },      // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read
> Status Register
> +    {EnumSpiOpcodeRead,           SF_INST_SFDP,           EnumSpiCycle50MHz,
> EnumSpiOperationDiscoveryParameters},    // Opcode 3: Serial Flash
> Discovery Parameters
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5:
> Block Erase (64KB
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((MACRONIX_MX25L32_SIZE >= FLASH_SIZE) ? MACRONIX_MX25L32_SIZE
> - FLASH_SIZE : (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_MACRONIX,    // VendorId
> +  SF_DEVICE_ID0_MX25LXX,    // DeviceId 0
> +  SF_DEVICE_ID1_MX25L64,    // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_EWSR            // Prefix Opcode 1:  Write Enable (this part doesn't
> support EWSR)
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle33MHz,
> EnumSpiOperationReadData      },      // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read
> Status Register
> +    {EnumSpiOpcodeRead,           SF_INST_SFDP,           EnumSpiCycle50MHz,
> EnumSpiOperationDiscoveryParameters},    // Opcode 3: Serial Flash
> Discovery Parameters
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5:
> Block Erase (64KB
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((MACRONIX_MX25L64_SIZE >= FLASH_SIZE) ? MACRONIX_MX25L64_SIZE
> - FLASH_SIZE : (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_MACRONIX,    // VendorId
> +  SF_DEVICE_ID0_MX25LXX,    // DeviceId 0
> +  SF_DEVICE_ID1_MX25L128,   // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_EWSR            // Prefix Opcode 1:  Write Enable (this part doesn't
> support EWSR)
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle33MHz,
> EnumSpiOperationReadData      },      // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read
> Status Register
> +    {EnumSpiOpcodeRead,           SF_INST_SFDP,           EnumSpiCycle50MHz,
> EnumSpiOperationDiscoveryParameters},    // Opcode 3: Serial Flash
> Discovery Parameters
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5:
> Block Erase (64KB
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((MACRONIX_MX25L128_SIZE >= FLASH_SIZE) ?
> MACRONIX_MX25L128_SIZE - FLASH_SIZE : (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_MACRONIX,	  // VendorId
> +  SF_DEVICE_ID0_MX25UXX,	  // DeviceId 0
> +  SF_DEVICE_ID1_MX25U6435F,   // DeviceId 1
> +  {
> +    SF_INST_WREN, 		      // Prefix Opcode 0: Write Enable
> +    SF_INST_EWSR			  // Prefix Opcode 1:  Write Enable
> (this part doesn't support EWSR)
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr, 	SF_INST_JEDEC_READ_ID,
> 	EnumSpiCycle50MHz, EnumSpiOperationJedecId		},
> 		// Opcode 0: Read ID
> +    {EnumSpiOpcodeRead,			SF_INST_READ,
> 		EnumSpiCycle33MHz, EnumSpiOperationReadData 	 },
> 	 // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr, 	SF_INST_RDSR,
> 	EnumSpiCycle50MHz, EnumSpiOperationReadStatus	 }, 	 //
> Opcode 2: Read Status Register
> +    {EnumSpiOpcodeRead,			SF_INST_SFDP,
> 	EnumSpiCycle50MHz, EnumSpiOperationDiscoveryParameters},
> 	// Opcode 3: Serial Flash Discovery Parameters
> +    {EnumSpiOpcodeWrite,		SF_INST_SERASE,
> 	EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte  },	  //
> Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,		SF_INST_64KB_ERASE,
> 	EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },	   //
> Opcode 5: Block Erase (64KB
> +    {EnumSpiOpcodeWrite,		SF_INST_PROG,
> 	EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
> 	// Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,	SF_INST_WRSR,
> 	EnumSpiCycle50MHz, EnumSpiOperationWriteStatus	  },	  //
> Opcode 7: Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((MACRONIX_MX25U64_SIZE >= FLASH_SIZE) ?
> MACRONIX_MX25U64_SIZE - FLASH_SIZE : (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_SST,         // VendorId
> +  SF_DEVICE_ID0_SST25VF0XXX,// DeviceId 0
> +  SF_DEVICE_ID1_SST25VF016B,// DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_EWSR            // Prefix Opcode 1: Enable Write Status Register
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId           },     // Opcode 0: Read
> ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle20MHz,
> EnumSpiOperationReadData          },     // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus        },     // Opcode 2:
> Read Status Register
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,
> EnumSpiCycle50MHz, EnumSpiOperationWriteDisable      },     // Opcode 3:
> Write Disable
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte     },     // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte    },     // Opcode 5:
> Block Erase (32KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus       },     // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((SST_SST25VF016B_SIZE >= FLASH_SIZE) ? SST_SST25VF016B_SIZE -
> FLASH_SIZE : (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_SST,         // VendorId
> +  SF_DEVICE_ID0_SST25VF0XXX,// DeviceId 0
> +  SF_DEVICE_ID1_SST25VF064C,// DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_EWSR            // Prefix Opcode 1: Enable Write Status Register
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId           },     // Opcode 0: Read
> ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle20MHz,
> EnumSpiOperationReadData          },     // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus        },     // Opcode 2:
> Read Status Register
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,
> EnumSpiCycle50MHz, EnumSpiOperationWriteDisable      },     // Opcode 3:
> Write Disable
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte     },     // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte    },     // Opcode 5:
> Block Erase (32KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus       },     // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((SST_SST25VF064C_SIZE >= FLASH_SIZE) ? SST_SST25VF064C_SIZE -
> FLASH_SIZE : (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  	//
> +  	// Minnow2 SPI type
> +  	//
> +  SF_VENDOR_ID_NUMONYX,     // VendorId
> +  SF_DEVICE_ID0_N25Q064,    // DeviceId 0
> +  SF_DEVICE_ID1_N25Q064,    // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't
> support EWSR)
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle20MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle20MHz,
> EnumSpiOperationReadData      },      // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle20MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read
> Status Register
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,
> EnumSpiCycle20MHz, EnumSpiOperationWriteDisable    },      // Opcode 3:
> Write Disable
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle20MHz,
> EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle20MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5:
> Block Erase (64KB
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle20MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle20MHz, EnumSpiOperationWriteStatus    },      // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((NUMONYX_N25Q064_SIZE >= FLASH_SIZE) ? NUMONYX_N25Q064_SIZE
> - FLASH_SIZE : (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_NUMONYX,     // VendorId
> +  SF_DEVICE_ID0_M25PXXX,    // DeviceId 0
> +  SF_DEVICE_ID1_M25PX16,    // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't
> support EWSR).
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle33MHz,
> EnumSpiOperationReadData      },      // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read
> Status Register
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,
> EnumSpiCycle50MHz, EnumSpiOperationWriteDisable    },      // Opcode 3:
> Write Disable
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5:
> Block Erase (64KB
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((NUMONYX_M25PX16_SIZE >= FLASH_SIZE) ? NUMONYX_M25PX16_SIZE
> - FLASH_SIZE : (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_NUMONYX,     // VendorId
> +  SF_DEVICE_ID0_N25QXXX,    // DeviceId 0
> +  SF_DEVICE_ID1_N25Q032,    // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't
> support EWSR).
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId      },        // Opcode 0: Read
> ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle33MHz,
> EnumSpiOperationReadData      },        // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },        // Opcode 2:
> Read Status Register
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,
> EnumSpiCycle50MHz, EnumSpiOperationWriteDisable    },      // Opcode 3:
> Write Disable
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5:
> Block Erase (64KB
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},   // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((NUMONYX_N25Q032_SIZE >= FLASH_SIZE) ? NUMONYX_N25Q032_SIZE
> - FLASH_SIZE : (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_NUMONYX,     // VendorId
> +  SF_DEVICE_ID0_M25PXXX,    // DeviceId 0
> +  SF_DEVICE_ID1_M25PX32,    // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't
> support EWSR).
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle33MHz,
> EnumSpiOperationReadData      },      // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read
> Status Register
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,
> EnumSpiCycle50MHz, EnumSpiOperationWriteDisable    },      // Opcode 3:
> Write Disable
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5:
> Block Erase (64KB
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((NUMONYX_M25PX32_SIZE >= FLASH_SIZE) ? NUMONYX_M25PX32_SIZE
> - FLASH_SIZE : (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_NUMONYX,     // VendorId
> +  SF_DEVICE_ID0_M25PXXX,    // DeviceId 0
> +  SF_DEVICE_ID1_M25PX64,    // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't
> support EWSR)
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle33MHz,
> EnumSpiOperationReadData      },      // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read
> Status Register
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,
> EnumSpiCycle50MHz, EnumSpiOperationWriteDisable    },      // Opcode 3:
> Write Disable
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5:
> Block Erase (64KB
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((NUMONYX_M25PX64_SIZE >= FLASH_SIZE) ? NUMONYX_M25PX64_SIZE
> - FLASH_SIZE : (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_NUMONYX,     // VendorId
> +  SF_DEVICE_ID0_N25QXXX,    // DeviceId 0
> +  SF_DEVICE_ID1_N25Q128,    // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't
> support EWSR)
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle33MHz,
> EnumSpiOperationReadData      },      // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read
> Status Register
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,
> EnumSpiCycle50MHz, EnumSpiOperationWriteDisable    },      // Opcode 3:
> Write Disable
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5:
> Block Erase (64KB
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((NUMONYX_N25Q128_SIZE >= FLASH_SIZE) ? NUMONYX_N25Q128_SIZE
> - FLASH_SIZE : (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_EON,         // VendorId
> +  SF_DEVICE_ID0_EN25QXX,    // DeviceId 0
> +  SF_DEVICE_ID1_EN25Q16,    // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't
> support EWSR)
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz,
> EnumSpiOperationReadData      },      // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read
> Status Register
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,
> EnumSpiCycle50MHz, EnumSpiOperationWriteDisable    },      // Opcode 3:
> Write Disable
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5:
> Block Erase (64KB
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((EON_EN25Q16_SIZE >= FLASH_SIZE) ? EON_EN25Q16_SIZE - FLASH_SIZE :
> (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_EON,         // VendorId
> +  SF_DEVICE_ID0_EN25QXX,    // DeviceId 0
> +  SF_DEVICE_ID1_EN25Q32,    // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't
> support EWSR)
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle33MHz,
> EnumSpiOperationReadData      },      // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read
> Status Register
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,
> EnumSpiCycle50MHz, EnumSpiOperationWriteDisable    },      // Opcode 3:
> Write Disable
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5:
> Block Erase (64KB
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((EON_EN25Q32_SIZE >= FLASH_SIZE) ? EON_EN25Q32_SIZE - FLASH_SIZE :
> (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_EON,         // VendorId
> +  SF_DEVICE_ID0_EN25QXX,    // DeviceId 0
> +  SF_DEVICE_ID1_EN25Q64,    // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't
> support EWSR).
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz,
> EnumSpiOperationReadData      },      // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read
> Status Register
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,
> EnumSpiCycle50MHz, EnumSpiOperationWriteDisable    },      // Opcode 3:
> Write Disable
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5:
> Block Erase (64KB
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((EON_EN25Q64_SIZE >= FLASH_SIZE) ? EON_EN25Q64_SIZE - FLASH_SIZE :
> (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_EON,         // VendorId
> +  SF_DEVICE_ID0_EN25QXX,    // DeviceId 0
> +  SF_DEVICE_ID1_EN25Q128,   // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't
> support EWSR)
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz,
> EnumSpiOperationReadData      },      // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read
> Status Register
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,
> EnumSpiCycle50MHz, EnumSpiOperationWriteDisable    },      // Opcode 3:
> Write Disable
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5:
> Block Erase (64KB
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((EON_EN25Q128_SIZE >= FLASH_SIZE) ? EON_EN25Q128_SIZE -
> FLASH_SIZE : (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  },
> +  {
> +  SF_VENDOR_ID_AMIC,        // VendorId
> +  SF_DEVICE_ID0_A25L016,    // DeviceId 0
> +  SF_DEVICE_ID1_A25L016,    // DeviceId 1
> +  {
> +    SF_INST_WREN,           // Prefix Opcode 0: Write Enable
> +    SF_INST_WREN            // Prefix Opcode 1: Write Enable (this part doesn't
> support EWSR)
> +  },
> +  {
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_JEDEC_READ_ID,
> EnumSpiCycle50MHz, EnumSpiOperationJedecId      },      // Opcode 0: Read ID
> +    {EnumSpiOpcodeRead,           SF_INST_READ,           EnumSpiCycle50MHz,
> EnumSpiOperationReadData      },      // Opcode 1: Read
> +    {EnumSpiOpcodeReadNoAddr,     SF_INST_RDSR,
> EnumSpiCycle50MHz, EnumSpiOperationReadStatus    },      // Opcode 2: Read
> Status Register
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRDI,
> EnumSpiCycle50MHz, EnumSpiOperationWriteDisable    },      // Opcode 3:
> Write Disable
> +    {EnumSpiOpcodeWrite,          SF_INST_SERASE,         EnumSpiCycle50MHz,
> EnumSpiOperationErase_4K_Byte  },      // Opcode 4: Sector Erase (4KB)
> +    {EnumSpiOpcodeWrite,          SF_INST_64KB_ERASE,
> EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte  },      // Opcode 5:
> Block Erase (64KB
> +    {EnumSpiOpcodeWrite,          SF_INST_PROG,           EnumSpiCycle50MHz,
> EnumSpiOperationProgramData_1_Byte},     // Opcode 6: Byte Program
> +    {EnumSpiOpcodeWriteNoAddr,    SF_INST_WRSR,
> EnumSpiCycle50MHz, EnumSpiOperationWriteStatus    },      // Opcode 7:
> Write Status Register
> +  },
> +
> +  //
> +  // The offset of the start of the BIOS image in flash. This value is platform
> specific
> +  // and depends on the system flash map. If BIOS size is bigger than flash
> return -1.
> +  //
> +  ((AMIC_A25L16_SIZE >= FLASH_SIZE) ? AMIC_A25L16_SIZE - FLASH_SIZE :
> (UINTN) (-1)),
> +
> +  //
> +  // The size of the BIOS image in flash. This value is platform specific and
> depends on the system flash map.
> +  //
> +  FLASH_SIZE
> +  }
> +};
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c
> new file mode 100644
> index 0000000000..85f066a9e3
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c
> @@ -0,0 +1,46 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  I2CLib.c
> +
> +
> +
> +--*/
> +#ifdef ECP_FLAG
> +#include "EdkIIGlueDxe.h"
> +#else
> +#include <Library/DebugLib.h>
> +#include <Library/TimerLib.h>
> +#endif
> +#include <PchRegs/PchRegsPcu.h>
> +#include <PchRegs.h>
> +#include <PlatformBaseAddresses.h>
> +#include <PchRegs/PchRegsLpss.h>
> +#ifdef ECP_FLAG
> +#include "I2CLib.h"
> +#else
> +#include <Library/I2CLib.h>
> +#endif
> +#include <Protocol/GlobalNvsArea.h>
> +#ifndef ECP_FLAG
> +#include <Library/UefiBootServicesTableLib.h>
> +#endif
> +
> +EFI_STATUS ByteReadI2C(
> +  IN  UINT8 BusNo,
> +  IN  UINT8 SlaveAddress,
> +  IN  UINT8 Offset,
> +  IN  UINTN ReadBytes,
> +  OUT UINT8 *ReadBuffer
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLibNull.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLibNull.inf
> new file mode 100644
> index 0000000000..d669a4eaf8
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLibNull.inf
> @@ -0,0 +1,39 @@
> +## @file
> +# Null instance of Debug Agent Library with empty functions.
> +#
> +#  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = I2CLib
> +  FILE_GUID                      = 7f62bf44-2ba7-4c2d-9d4a-91c8906ff053
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = I2CLib
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +
> +[Sources.common]
> +  I2CLib.c
> +
> +[LibraryClasses]
> +  BaseLib
> +  IoLib
> +  TimerLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +
> +[Protocols]
> +  gEfiGlobalNvsAreaProtocolGuid
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLib.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLib.c
> new file mode 100644
> index 0000000000..104c2ded43
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLib.c
> @@ -0,0 +1,735 @@
> +/** @file
> +  Functions for accessing I2C registers.
> +
> +  Copyright (c) 2004  - 2015, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +--*/
> +
> +#include <Library/DebugLib.h>
> +#include <Library/TimerLib.h>
> +#include <PchRegs/PchRegsPcu.h>
> +#include <PchRegs.h>
> +#include <PlatformBaseAddresses.h>
> +#include <PchRegs/PchRegsLpss.h>
> +#include <Library/I2CLib.h>
> +#include <Protocol/GlobalNvsArea.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <I2CRegs.h>
> +
> +#define GLOBAL_NVS_OFFSET(Field)
> (UINTN)((CHAR8*)&((EFI_GLOBAL_NVS_AREA*)0)->Field - (CHAR8*)0)
> +
> +#define PCIEX_BASE_ADDRESS  0xE0000000
> +#define PCI_EXPRESS_BASE_ADDRESS ((VOID *) (UINTN)
> PCIEX_BASE_ADDRESS)
> +#define MmPciAddress( Segment, Bus, Device, Function, Register ) \
> +         ((UINTN)PCI_EXPRESS_BASE_ADDRESS + \
> +         (UINTN)(Bus << 20) + \
> +         (UINTN)(Device << 15) + \
> +         (UINTN)(Function << 12) + \
> +         (UINTN)(Register) \
> +        )
> +#define PCI_D31F0_REG_BASE             PCIEX_BASE_ADDRESS + (UINT32) (31
> << 15)
> +
> +typedef struct _LPSS_PCI_DEVICE_INFO {
> +  UINTN        Segment;
> +  UINTN        BusNum;
> +  UINTN        DeviceNum;
> +  UINTN        FunctionNum;
> +  UINTN        Bar0;
> +  UINTN        Bar1;
> +} LPSS_PCI_DEVICE_INFO;
> +
> +LPSS_PCI_DEVICE_INFO  mLpssPciDeviceList[] = {
> +  {0, DEFAULT_PCI_BUS_NUMBER_PCH,
> PCI_DEVICE_NUMBER_PCH_LPSS_DMAC1,
> PCI_FUNCTION_NUMBER_PCH_LPSS_DMAC, 0xFE900000, 0xFE908000},
> +  {0, DEFAULT_PCI_BUS_NUMBER_PCH,
> PCI_DEVICE_NUMBER_PCH_LPSS_I2C,
> PCI_FUNCTION_NUMBER_PCH_LPSS_I2C0, 0xFE910000, 0xFE918000},
> +  {0, DEFAULT_PCI_BUS_NUMBER_PCH,
> PCI_DEVICE_NUMBER_PCH_LPSS_I2C,
> PCI_FUNCTION_NUMBER_PCH_LPSS_I2C1, 0xFE920000, 0xFE928000},
> +  {0, DEFAULT_PCI_BUS_NUMBER_PCH,
> PCI_DEVICE_NUMBER_PCH_LPSS_I2C,
> PCI_FUNCTION_NUMBER_PCH_LPSS_I2C2, 0xFE930000, 0xFE938000},
> +  {0, DEFAULT_PCI_BUS_NUMBER_PCH,
> PCI_DEVICE_NUMBER_PCH_LPSS_I2C,
> PCI_FUNCTION_NUMBER_PCH_LPSS_I2C3, 0xFE940000, 0xFE948000},
> +  {0, DEFAULT_PCI_BUS_NUMBER_PCH,
> PCI_DEVICE_NUMBER_PCH_LPSS_I2C,
> PCI_FUNCTION_NUMBER_PCH_LPSS_I2C4, 0xFE950000, 0xFE958000},
> +  {0, DEFAULT_PCI_BUS_NUMBER_PCH,
> PCI_DEVICE_NUMBER_PCH_LPSS_I2C,
> PCI_FUNCTION_NUMBER_PCH_LPSS_I2C5, 0xFE960000, 0xFE968000},
> +  {0, DEFAULT_PCI_BUS_NUMBER_PCH,
> PCI_DEVICE_NUMBER_PCH_LPSS_I2C,
> PCI_FUNCTION_NUMBER_PCH_LPSS_I2C6, 0xFE970000, 0xFE978000}
> +};
> +
> +#define LPSS_PCI_DEVICE_NUMBER
> sizeof(mLpssPciDeviceList)/sizeof(LPSS_PCI_DEVICE_INFO)
> +
> +STATIC UINTN mI2CBaseAddress = 0;
> +STATIC UINT16 mI2CSlaveAddress = 0;
> +
> +UINT16 mI2cMode=B_IC_RESTART_EN | B_IC_SLAVE_DISABLE |
> B_MASTER_MODE ;
> +
> +UINTN mI2cNvsBaseAddress[] = {
> +        GLOBAL_NVS_OFFSET(LDMA2Addr),
> +        GLOBAL_NVS_OFFSET(I2C1Addr),
> +        GLOBAL_NVS_OFFSET(I2C2Addr),
> +        GLOBAL_NVS_OFFSET(I2C3Addr),
> +        GLOBAL_NVS_OFFSET(I2C4Addr),
> +        GLOBAL_NVS_OFFSET(I2C5Addr),
> +        GLOBAL_NVS_OFFSET(I2C6Addr),
> +        GLOBAL_NVS_OFFSET(I2C7Addr)
> +      };
> +
> +/**
> +  This function get I2Cx controller base address (BAR0).
> +
> +  @param I2cControllerIndex  Bus Number of I2C controller.
> +
> +  @return I2C BAR.
> +**/
> +UINTN
> +GetI2cBarAddr(
> +  IN    UINT8 I2cControllerIndex
> +  )
> +{
> +  EFI_STATUS           Status;
> +  EFI_GLOBAL_NVS_AREA_PROTOCOL  *GlobalNvsArea;
> +  UINTN  AcpiBaseAddr;
> +  UINTN  PciMmBase=0;
> +
> +  ASSERT(gBS!=NULL);
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiGlobalNvsAreaProtocolGuid,
> +                  NULL,
> +                  &GlobalNvsArea
> +                  );
> +
> +  //
> +  // PCI mode from PEI ( Global NVS is not ready).
> +  //
> +  if (EFI_ERROR(Status)) {
> +    DEBUG ((EFI_D_INFO, "GetI2cBarAddr()
> gEfiGlobalNvsAreaProtocolGuid:%r\n", Status));
> +    //
> +    // Global NVS is not ready.
> +    //
> +    return 0;
> +  }
> +
> +  AcpiBaseAddr =  *(UINTN*)((CHAR8*)GlobalNvsArea->Area +
> mI2cNvsBaseAddress[I2cControllerIndex + 1]);
> +
> +  //
> +  //PCI mode from DXE (global NVS protocal) to LPSS OnReadytoBoot(swith
> to ACPI).
> +  //
> +  if(AcpiBaseAddr==0) {
> +    PciMmBase = MmPciAddress (
> +                  mLpssPciDeviceList[I2cControllerIndex + 1].Segment,
> +                  mLpssPciDeviceList[I2cControllerIndex + 1].BusNum,
> +                  mLpssPciDeviceList[I2cControllerIndex + 1].DeviceNum,
> +                  mLpssPciDeviceList[I2cControllerIndex + 1].FunctionNum,
> +                  0
> +                  );
> +    DEBUG((EFI_D_ERROR, "\nGetI2cBarAddr() I2C Device %x %x %x
> PciMmBase:%x\n", \
> +           mLpssPciDeviceList[I2cControllerIndex + 1].BusNum, \
> +           mLpssPciDeviceList[I2cControllerIndex + 1].DeviceNum, \
> +           mLpssPciDeviceList[I2cControllerIndex + 1].FunctionNum,
> PciMmBase));
> +
> +    if (MmioRead32 (PciMmBase) != 0xFFFFFFFF)    {
> +      if((MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_STSCMD)&
> B_PCH_LPSS_I2C_STSCMD_MSE)) {
> +        //
> +        // Get the address allocted.
> +        //
> +        mLpssPciDeviceList[I2cControllerIndex + 1].Bar0=MmioRead32
> (PciMmBase+R_PCH_LPSS_I2C_BAR);
> +        mLpssPciDeviceList[I2cControllerIndex + 1].Bar1=MmioRead32
> (PciMmBase+R_PCH_LPSS_I2C_BAR1);
> +      }
> +    }
> +    AcpiBaseAddr =mLpssPciDeviceList[I2cControllerIndex+1].Bar0;
> +  }
> +
> +  //
> +  // ACPI mode from BDS: LPSS OnReadytoBoot
> +  //
> +  else {
> +    DEBUG ((EFI_D_INFO, "GetI2cBarAddr() NVS Varialable is updated by this
> LIB or LPSS  \n"));
> +  }
> +
> +  DEBUG ((EFI_D_INFO, "GetI2cBarAddr() I2cControllerIndex+1 0x%x
> AcpiBaseAddr:0x%x \n", (I2cControllerIndex + 1), AcpiBaseAddr));
> +  return AcpiBaseAddr;
> +}
> +
> +
> +/**
> +  This function enables I2C controllers.
> +
> +  @param I2cControllerIndex  Bus Number of I2C controllers.
> +
> +  @return Result of the I2C initialization.
> +**/
> +EFI_STATUS
> +ProgramPciLpssI2C (
> +  IN  UINT8 I2cControllerIndex
> +  )
> +{
> +  UINT32                        PmcBase;
> +  UINTN                         PciMmBase=0;
> +  EFI_STATUS                    Status;
> +  EFI_GLOBAL_NVS_AREA_PROTOCOL  *GlobalNvsArea;
> +
> +  UINT32 PmcFunctionDsiable[]= {
> +    B_PCH_PMC_FUNC_DIS_LPSS2_FUNC1,
> +    B_PCH_PMC_FUNC_DIS_LPSS2_FUNC2,
> +    B_PCH_PMC_FUNC_DIS_LPSS2_FUNC3,
> +    B_PCH_PMC_FUNC_DIS_LPSS2_FUNC4,
> +    B_PCH_PMC_FUNC_DIS_LPSS2_FUNC5,
> +    B_PCH_PMC_FUNC_DIS_LPSS2_FUNC6,
> +    B_PCH_PMC_FUNC_DIS_LPSS2_FUNC7
> +  };
> +
> +  DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() Start\n"));
> +
> +  //
> +  // Set the VLV Function Disable Register to ZERO
> +  //
> +  PmcBase = MmioRead32 (PCI_D31F0_REG_BASE + R_PCH_LPC_PMC_BASE)
> & B_PCH_LPC_PMC_BASE_BAR;
> +
> if(MmioRead32(PmcBase+R_PCH_PMC_FUNC_DIS)&PmcFunctionDsiable[I2
> cControllerIndex]) {
> +    DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() End:I2C[%x] is
> disabled\n",I2cControllerIndex));
> +    return EFI_NOT_READY;
> +  }
> +
> +  DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C()------------
> I2cControllerIndex=%x,PMC=%x\n",I2cControllerIndex,MmioRead32(PmcBa
> se+R_PCH_PMC_FUNC_DIS)));
> +
> +  {
> +    PciMmBase = MmPciAddress (
> +                  mLpssPciDeviceList[I2cControllerIndex+1].Segment,
> +                  mLpssPciDeviceList[I2cControllerIndex+1].BusNum,
> +                  mLpssPciDeviceList[I2cControllerIndex+1].DeviceNum,
> +                  mLpssPciDeviceList[I2cControllerIndex+1].FunctionNum,
> +                  0
> +                  );
> +
> +    DEBUG((EFI_D_ERROR, "Program Pci Lpss I2C Device  %x %x %x
> PciMmBase:%x\n", \
> +           mLpssPciDeviceList[I2cControllerIndex+1].BusNum, \
> +           mLpssPciDeviceList[I2cControllerIndex+1].DeviceNum, \
> +           mLpssPciDeviceList[I2cControllerIndex+1].FunctionNum, PciMmBase));
> +
> +    if (MmioRead32 (PciMmBase) != 0xFFFFFFFF)     {
> +      if((MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_STSCMD)&
> B_PCH_LPSS_I2C_STSCMD_MSE)) {
> +        //
> +        // Get the address allocted.
> +        //
> +        mLpssPciDeviceList[I2cControllerIndex+1].Bar0=MmioRead32
> (PciMmBase+R_PCH_LPSS_I2C_BAR);
> +        mLpssPciDeviceList[I2cControllerIndex+1].Bar1=MmioRead32
> (PciMmBase+R_PCH_LPSS_I2C_BAR1);
> +        DEBUG((EFI_D_ERROR, "ProgramPciLpssI2C() bar0:0x%x
> bar1:0x%x\n",mLpssPciDeviceList[I2cControllerIndex+1].Bar0,
> mLpssPciDeviceList[I2cControllerIndex+1].Bar1));
> +      } else {
> +
> +        //
> +        // Program BAR 0
> +        //
> +        ASSERT (((mLpssPciDeviceList[I2cControllerIndex+1].Bar0 &
> B_PCH_LPSS_I2C_BAR_BA) ==
> mLpssPciDeviceList[I2cControllerIndex+1].Bar0) &&
> (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 != 0));
> +        MmioWrite32 ((UINTN) (PciMmBase + R_PCH_LPSS_I2C_BAR), (UINT32)
> (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 &
> B_PCH_LPSS_I2C_BAR_BA));
> +
> +        //
> +        // Program BAR 1
> +        //
> +        ASSERT (((mLpssPciDeviceList[I2cControllerIndex+1].Bar1 &
> B_PCH_LPSS_I2C_BAR1_BA) ==
> mLpssPciDeviceList[I2cControllerIndex+1].Bar1) &&
> (mLpssPciDeviceList[I2cControllerIndex+1].Bar1 != 0));
> +        MmioWrite32 ((UINTN) (PciMmBase + R_PCH_LPSS_I2C_BAR1),
> (UINT32) (mLpssPciDeviceList[I2cControllerIndex+1].Bar1 &
> B_PCH_LPSS_I2C_BAR1_BA));
> +
> +        //
> +        // Bus Master Enable & Memory Space Enable
> +        //
> +        MmioOr32 ((UINTN) (PciMmBase + R_PCH_LPSS_I2C_STSCMD),
> (UINT32) (B_PCH_LPSS_I2C_STSCMD_BME |
> B_PCH_LPSS_I2C_STSCMD_MSE));
> +        ASSERT (MmioRead32
> (mLpssPciDeviceList[I2cControllerIndex+1].Bar0) != 0xFFFFFFFF);
> +      }
> +
> +      //
> +      // Release Resets
> +      //
> +      MmioWrite32 (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 +
> R_PCH_LPIO_I2C_MEM_RESETS,(B_PCH_LPIO_I2C_MEM_RESETS_FUNC |
> B_PCH_LPIO_I2C_MEM_RESETS_APB));
> +
> +      //
> +      // Activate Clocks
> +      //
> +      MmioWrite32 (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 +
> R_PCH_LPSS_I2C_MEM_PCP,0x80020003);//No use for A0
> +
> +      DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() Programmed()\n"));
> +    }
> +
> +    //
> +    // BDS: already switched to ACPI mode
> +    //
> +    else {
> +      ASSERT(gBS!=NULL);
> +      Status = gBS->LocateProtocol (
> +                      &gEfiGlobalNvsAreaProtocolGuid,
> +                      NULL,
> +                      &GlobalNvsArea
> +                      );
> +      if (EFI_ERROR(Status)) {
> +        DEBUG ((EFI_D_INFO, "GetI2cBarAddr()
> gEfiGlobalNvsAreaProtocolGuid:%r\n", Status));
> +        //
> +        // gEfiGlobalNvsAreaProtocolGuid is not ready.
> +        //
> +        return 0;
> +      }
> +      mLpssPciDeviceList[I2cControllerIndex + 1].Bar0 =
> *(UINTN*)((CHAR8*)GlobalNvsArea->Area +
> mI2cNvsBaseAddress[I2cControllerIndex + 1]);
> +      DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C(): is switched to ACPI 0x:%x
> \n",mLpssPciDeviceList[I2cControllerIndex + 1].Bar0));
> +    }
> +  }
> +
> +  DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() End\n"));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Disable I2C Bus.
> +
> +  @param VOID.
> +
> +  @return Result of the I2C disabling.
> +**/
> +RETURN_STATUS
> +I2cDisable (
> +  VOID
> +  )
> +{
> +  //
> +  // 0.1 seconds
> +  //
> +  UINT32 NumTries = 10000;
> +
> +  MmioWrite32 ( mI2CBaseAddress + R_IC_ENABLE, 0 );
> +  while ( 0 != ( MmioRead32 ( mI2CBaseAddress + R_IC_ENABLE_STATUS) &
> 1)) {
> +    MicroSecondDelay (10);
> +    NumTries --;
> +    if(0 == NumTries) {
> +      return RETURN_NOT_READY;
> +    }
> +  }
> +
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Enable I2C Bus.
> +
> +  @param VOID.
> +
> +  @return Result of the I2C disabling.
> +**/
> +RETURN_STATUS
> +I2cEnable (
> +  VOID
> +  )
> +{
> +  //
> +  // 0.1 seconds
> +  //
> +  UINT32 NumTries = 10000;
> +
> +  MmioWrite32 (mI2CBaseAddress + R_IC_ENABLE, 1);
> +
> +  while (0 == (MmioRead32 (mI2CBaseAddress + R_IC_ENABLE_STATUS) &
> 1)) {
> +    MicroSecondDelay (10);
> +    NumTries --;
> +    if(0 == NumTries){
> +       return RETURN_NOT_READY;
> +    }
> +  }
> +
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Enable I2C Bus.
> +
> +  @param VOID.
> +
> +  @return Result of the I2C enabling.
> +**/
> +RETURN_STATUS
> +I2cBusFrequencySet (
> +  IN UINTN BusClockHertz
> +  )
> +{
> +  DEBUG((EFI_D_INFO,"InputFreq BusClockHertz: %d\r\n",BusClockHertz));
> +
> +  //
> +  //  Set the 100 KHz clock divider according to SV result and I2C spec
> +  //
> +  MmioWrite32 ( mI2CBaseAddress + R_IC_SS_SCL_HCNT, (UINT16)0x214 );
> +  MmioWrite32 ( mI2CBaseAddress + R_IC_SS_SCL_LCNT, (UINT16)0x272 );
> +
> +  //
> +  //  Set the 400 KHz clock divider according to SV result and I2C spec
> +  //
> +  MmioWrite32 ( mI2CBaseAddress + R_IC_FS_SCL_HCNT, (UINT16)0x50 );
> +  MmioWrite32 ( mI2CBaseAddress + R_IC_FS_SCL_LCNT, (UINT16)0xAD );
> +
> +  switch ( BusClockHertz ) {
> +    case 100 * 1000:
> +      MmioWrite32 ( mI2CBaseAddress + R_IC_SDA_HOLD,
> (UINT16)0x40);//100K
> +      mI2cMode = V_SPEED_STANDARD;
> +      break;
> +    case 400 * 1000:
> +      MmioWrite32 ( mI2CBaseAddress + R_IC_SDA_HOLD,
> (UINT16)0x32);//400K
> +      mI2cMode = V_SPEED_FAST;
> +      break;
> +    default:
> +      MmioWrite32 ( mI2CBaseAddress + R_IC_SDA_HOLD,
> (UINT16)0x09);//3.4M
> +      mI2cMode = V_SPEED_HIGH;
> +  }
> +
> +  //
> +  //  Select the frequency counter,
> +  //  Enable restart condition,
> +  //  Enable master FSM, disable slave FSM.
> +  //
> +  mI2cMode |= B_IC_RESTART_EN | B_IC_SLAVE_DISABLE |
> B_MASTER_MODE;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Initializes the host controller to execute I2C commands.
> +
> +  @param I2cControllerIndex Index of I2C controller in LPSS device. 0
> represents I2C0, which is PCI function 1 of LPSS device.
> +
> +  @return EFI_SUCCESS       Opcode initialization on the I2C host controller
> completed.
> +  @return EFI_DEVICE_ERROR  Device error, operation failed.
> +**/
> +EFI_STATUS
> +I2CInit (
> +  IN  UINT8  I2cControllerIndex,
> +  IN  UINT16 SlaveAddress
> +  )
> +{
> +  EFI_STATUS Status=RETURN_SUCCESS;
> +  UINT32    NumTries = 0;
> +  UINTN    GnvsI2cBarAddr=0;
> +
> +  //
> +  // Verify the parameters
> +  //
> +  if ((1023 < SlaveAddress) || (6 < I2cControllerIndex)) {
> +    Status =  RETURN_INVALID_PARAMETER;
> +    DEBUG((EFI_D_INFO,"I2CInit Exit with
> RETURN_INVALID_PARAMETER\r\n"));
> +    return Status;
> +  }
> +  MmioWrite32 ( mI2CBaseAddress + R_IC_TAR, (UINT16)SlaveAddress );
> +  mI2CSlaveAddress = SlaveAddress;
> +
> +  //
> +  // 1.PEI: program and init ( before pci enumeration).
> +  // 2.DXE:update address and re-init ( after pci enumeration).
> +  // 3.BDS:update ACPI address and re-init ( after acpi mode is enabled).
> +  //
> +  if(mI2CBaseAddress == mLpssPciDeviceList[I2cControllerIndex + 1].Bar0) {
> +
> +    //
> +    // I2CInit is already  called.
> +    //
> +    GnvsI2cBarAddr=GetI2cBarAddr(I2cControllerIndex);
> +
> +    if((GnvsI2cBarAddr == 0)||(GnvsI2cBarAddr == mI2CBaseAddress)) {
> +      DEBUG((EFI_D_INFO,"I2CInit Exit with mI2CBaseAddress:%x ==
> [%x].Bar0\r\n",mI2CBaseAddress,I2cControllerIndex+1));
> +      return RETURN_SUCCESS;
> +    }
> +  }
> +
> +  Status=ProgramPciLpssI2C(I2cControllerIndex);
> +  if(Status!=EFI_SUCCESS) {
> +    return Status;
> +  }
> +
> +
> +  mI2CBaseAddress = (UINT32) mLpssPciDeviceList[I2cControllerIndex +
> 1].Bar0;
> +  DEBUG ((EFI_D_ERROR, "mI2CBaseAddress = 0x%x
> \n",mI2CBaseAddress));
> +
> +  //
> +  // 1 seconds.
> +  //
> +  NumTries = 10000;
> +  while ((1 == ( MmioRead32 ( mI2CBaseAddress + R_IC_STATUS) &
> STAT_MST_ACTIVITY ))) {
> +    MicroSecondDelay(10);
> +    NumTries --;
> +    if(0 == NumTries) {
> +      DEBUG((EFI_D_INFO, "Try timeout\r\n"));
> +      return RETURN_DEVICE_ERROR;
> +    }
> +  }
> +
> +  Status = I2cDisable();
> +  DEBUG((EFI_D_INFO, "I2cDisable Status = %r\r\n", Status));
> +  I2cBusFrequencySet(400 * 1000);
> +
> +  MmioWrite32(mI2CBaseAddress + R_IC_INTR_MASK, 0x0);
> +  if (0x7f < SlaveAddress )
> +    SlaveAddress = ( SlaveAddress & 0x3ff ) | IC_TAR_10BITADDR_MASTER;
> +  MmioWrite32 ( mI2CBaseAddress + R_IC_TAR, (UINT16)SlaveAddress );
> +  MmioWrite32 ( mI2CBaseAddress + R_IC_RX_TL, 0);
> +  MmioWrite32 ( mI2CBaseAddress + R_IC_TX_TL, 0 );
> +  MmioWrite32 ( mI2CBaseAddress + R_IC_CON, mI2cMode);
> +  Status = I2cEnable();
> +
> +  DEBUG((EFI_D_INFO, "I2cEnable Status = %r\r\n", Status));
> +  MmioRead32 ( mI2CBaseAddress + R_IC_CLR_TX_ABRT );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Reads a Byte from I2C Device.
> +
> +  @param  I2cControllerIndex             I2C Bus no to which the I2C device has
> been connected
> +  @param  SlaveAddress      Device Address from which the byte value has to
> be read
> +  @param  Offset            Offset from which the data has to be read
> +  @param  *Byte             Address to which the value read has to be stored
> +  @param  Start               Whether a RESTART is issued before the byte is sent
> or received
> +  @param  End                 Whether STOP is generated after a data byte is sent
> or received
> +
> +  @return  EFI_SUCCESS       IF the byte value has been successfully read
> +  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
> +**/
> +EFI_STATUS
> +ByteReadI2CBasic(
> +  IN  UINT8 I2cControllerIndex,
> +  IN  UINT8 SlaveAddress,
> +  IN  UINTN ReadBytes,
> +  OUT UINT8 *ReadBuffer,
> +  IN  UINT8 Start,
> +  IN  UINT8 End
> +  )
> +{
> +
> +  EFI_STATUS Status;
> +  UINT32 I2cStatus;
> +  UINT16 ReceiveData;
> +  UINT8 *ReceiveDataEnd;
> +  UINT8 *ReceiveRequest;
> +  UINT16 RawIntrStat;
> +  UINT32 Count=0;
> +
> +  Status = EFI_SUCCESS;
> +
> +  ReceiveDataEnd = &ReadBuffer [ReadBytes];
> +  if( ReadBytes ) {
> +
> +    ReceiveRequest = ReadBuffer;
> +    DEBUG((EFI_D_INFO,"Read: ---------------%d bytes to
> RX\r\n",ReceiveDataEnd - ReceiveRequest));
> +
> +    while ((ReceiveDataEnd > ReceiveRequest) || (ReceiveDataEnd >
> ReadBuffer)) {
> +
> +      //
> +      //  Check for NACK
> +      //
> +      RawIntrStat = (UINT16)MmioRead32 (mI2CBaseAddress +
> R_IC_RawIntrStat);
> +      if ( 0 != ( RawIntrStat & I2C_INTR_TX_ABRT )) {
> +        MmioRead32 ( mI2CBaseAddress + R_IC_CLR_TX_ABRT );
> +        Status = RETURN_DEVICE_ERROR;
> +        DEBUG((EFI_D_INFO,"TX ABRT ,%d bytes hasn't been
> transferred\r\n",ReceiveDataEnd - ReceiveRequest));
> +        break;
> +      }
> +
> +      //
> +      // Determine if another byte was received
> +      //
> +      I2cStatus = (UINT16)MmioRead32 (mI2CBaseAddress + R_IC_STATUS);
> +      if (0 != ( I2cStatus & STAT_RFNE )) {
> +        ReceiveData = (UINT16)MmioRead32 ( mI2CBaseAddress +
> R_IC_DATA_CMD );
> +        *ReadBuffer++ = (UINT8)ReceiveData;
> +        DEBUG((EFI_D_INFO,"MmioRead32 ,1 byte 0x:%x is
> received\r\n",ReceiveData));
> +      }
> +
> +      if(ReceiveDataEnd == ReceiveRequest) {
> +        MicroSecondDelay ( FIFO_WRITE_DELAY );
> +        DEBUG((EFI_D_INFO,"ReceiveDataEnd==ReceiveRequest------------
> %x\r\n",I2cStatus & STAT_RFNE));
> +        Count++;
> +        if(Count<1024) {
> +          //
> +          // To avoid sys hung  without ul-pmc device  on RVP,
> +          // waiting the last request to get data and make (ReceiveDataEnd >
> ReadBuffer) =TRUE.
> +          //
> +          continue;
> +        } else {
> +          break;
> +        }
> +      }
> +
> +      //
> +      //  Wait until a read request will fit.
> +      //
> +      if (0 == (I2cStatus & STAT_TFNF)) {
> +        DEBUG((EFI_D_INFO,"Wait until a read request will fit\r\n"));
> +        MicroSecondDelay (10);
> +        continue;
> +      }
> +
> +      //
> +      //  Issue the next read request.
> +      //
> +      if(End && Start) {
> +        MmioWrite32 ( mI2CBaseAddress + R_IC_DATA_CMD,
> B_READ_CMD|B_CMD_RESTART|B_CMD_STOP);
> +      } else if (!End && Start) {
> +        MmioWrite32 ( mI2CBaseAddress + R_IC_DATA_CMD,
> B_READ_CMD|B_CMD_RESTART);
> +      } else if (End && !Start) {
> +        MmioWrite32 ( mI2CBaseAddress + R_IC_DATA_CMD,
> B_READ_CMD|B_CMD_STOP);
> +      } else if (!End && !Start) {
> +        MmioWrite32 ( mI2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD);
> +      }
> +      MicroSecondDelay (FIFO_WRITE_DELAY);
> +
> +      ReceiveRequest += 1;
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  Writes a Byte to I2C Device.
> +
> +  @param  I2cControllerIndex   I2C Bus no to which the I2C device has been
> connected
> +  @param  SlaveAddress         Device Address from which the byte value has
> to be written
> +  @param  Offset               Offset from which the data has to be read
> +  @param  *Byte                Address to which the value written is stored
> +  @param  Start               Whether a RESTART is issued before the byte is sent
> or received
> +  @param  End                 Whether STOP is generated after a data byte is sent
> or received
> +
> +  @return  EFI_SUCCESS         IF the byte value has been successfully written
> +  @return  EFI_DEVICE_ERROR    Operation Failed, Device Error
> +**/
> +EFI_STATUS ByteWriteI2CBasic(
> +  IN  UINT8 I2cControllerIndex,
> +  IN  UINT8 SlaveAddress,
> +  IN  UINTN WriteBytes,
> +  IN  UINT8 *WriteBuffer,
> +  IN  UINT8 Start,
> +  IN  UINT8 End
> +  )
> +{
> +
> +  EFI_STATUS Status;
> +  UINT32 I2cStatus;
> +  UINT8 *TransmitEnd;
> +  UINT16 RawIntrStat;
> +  UINT32 Count=0;
> +
> +  Status = EFI_SUCCESS;
> +
> +  Status=I2CInit(I2cControllerIndex, SlaveAddress);
> +  if(Status!=EFI_SUCCESS)
> +    return Status;
> +
> +  TransmitEnd = &WriteBuffer[WriteBytes];
> +  if( WriteBytes ) {
> +    DEBUG((EFI_D_INFO,"Write: --------------%d bytes to TX\r\n",TransmitEnd
> - WriteBuffer));
> +    while (TransmitEnd > WriteBuffer) {
> +      I2cStatus = MmioRead32 (mI2CBaseAddress + R_IC_STATUS);
> +      RawIntrStat = (UINT16)MmioRead32 (mI2CBaseAddress +
> R_IC_RawIntrStat);
> +      if (0 != ( RawIntrStat & I2C_INTR_TX_ABRT)) {
> +        MmioRead32 ( mI2CBaseAddress + R_IC_CLR_TX_ABRT);
> +        Status = RETURN_DEVICE_ERROR;
> +        DEBUG((EFI_D_ERROR,"TX ABRT TransmitEnd:0x%x
> WriteBuffer:0x%x\r\n", TransmitEnd, WriteBuffer));
> +        break;
> +      }
> +      if (0 == (I2cStatus & STAT_TFNF)) {
> +        //
> +        // If TX not full , will  send cmd  or continue to wait
> +        //
> +        MicroSecondDelay (FIFO_WRITE_DELAY);
> +        continue;
> +      }
> +
> +      if(End && Start) {
> +        MmioWrite32 (mI2CBaseAddress + R_IC_DATA_CMD,
> (*WriteBuffer++)|B_CMD_RESTART|B_CMD_STOP);
> +      } else if (!End && Start) {
> +        MmioWrite32 (mI2CBaseAddress + R_IC_DATA_CMD,
> (*WriteBuffer++)|B_CMD_RESTART);
> +      } else if (End && !Start) {
> +        MmioWrite32 (mI2CBaseAddress + R_IC_DATA_CMD,
> (*WriteBuffer++)|B_CMD_STOP);
> +      } else if (!End && !Start ) {
> +        MmioWrite32 (mI2CBaseAddress + R_IC_DATA_CMD,
> (*WriteBuffer++));
> +      }
> +
> +      //
> +      // Add a small delay to work around some odd behavior being seen.
> Without this delay bytes get dropped.
> +      //
> +      MicroSecondDelay ( FIFO_WRITE_DELAY );//wait after send cmd
> +
> +      //
> +      // Time out
> +      //
> +      while(1) {
> +        RawIntrStat = MmioRead16 ( mI2CBaseAddress + R_IC_RawIntrStat );
> +        if (0 != ( RawIntrStat & I2C_INTR_TX_ABRT)) {
> +          MmioRead16 (mI2CBaseAddress + R_IC_CLR_TX_ABRT);
> +          Status = RETURN_DEVICE_ERROR;
> +          DEBUG((EFI_D_ERROR,"TX ABRT TransmitEnd:0x%x
> WriteBuffer:0x%x\r\n", TransmitEnd, WriteBuffer));
> +        }
> +        if(0 == MmioRead16(mI2CBaseAddress + R_IC_TXFLR)) break;
> +
> +        MicroSecondDelay (FIFO_WRITE_DELAY);
> +        Count++;
> +        if(Count<1024) {
> +          //
> +          // to avoid sys hung without ul-pmc device on RVP.
> +          // Waiting the last request to get data and make (ReceiveDataEnd >
> ReadBuffer) =TRUE.
> +          //
> +          continue;
> +        } else {
> +          break;
> +        }
> +      }//while( 1 )
> +    }
> +
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  Reads a Byte from I2C Device.
> +
> +  @param  I2cControllerIndex   I2C Bus no to which the I2C device has been
> connected
> +  @param  SlaveAddress         Device Address from which the byte value has
> to be read
> +  @param  Offset               Offset from which the data has to be read
> +  @param  ReadBytes            Number of bytes to be read
> +  @param  *ReadBuffer          Address to which the value read has to be
> stored
> +
> +  @return  EFI_SUCCESS       IF the byte value has been successfully read
> +  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
> +**/
> +EFI_STATUS ByteReadI2C(
> +  IN  UINT8 I2cControllerIndex,
> +  IN  UINT8 SlaveAddress,
> +  IN  UINT8 Offset,
> +  IN  UINTN ReadBytes,
> +  OUT UINT8 *ReadBuffer
> +  )
> +{
> +  EFI_STATUS          Status;
> +
> +  DEBUG ((EFI_D_INFO, "ByteReadI2C:---offset:0x%x\n",Offset));
> +  Status = ByteWriteI2CBasic(I2cControllerIndex,
> SlaveAddress,1,&Offset,TRUE,FALSE);
> +  Status = ByteReadI2CBasic(I2cControllerIndex,
> SlaveAddress,ReadBytes,ReadBuffer,TRUE,TRUE);
> +
> +  return Status;
> +}
> +
> +/**
> +  Writes a Byte to I2C Device.
> +
> +  @param  I2cControllerIndex  I2C Bus no to which the I2C device has been
> connected
> +  @param  SlaveAddress        Device Address from which the byte value has
> to be written
> +  @param  Offset              Offset from which the data has to be written
> +  @param  WriteBytes          Number of bytes to be written
> +  @param  *Byte               Address to which the value written is stored
> +
> +  @return  EFI_SUCCESS       IF the byte value has been successfully read
> +  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
> +**/
> +EFI_STATUS ByteWriteI2C(
> +  IN  UINT8 I2cControllerIndex,
> +  IN  UINT8 SlaveAddress,
> +  IN  UINT8 Offset,
> +  IN  UINTN WriteBytes,
> +  IN  UINT8 *WriteBuffer
> +  )
> +{
> +  EFI_STATUS          Status;
> +
> +  DEBUG ((EFI_D_INFO, "ByteWriteI2C:---
> offset/bytes/buf:0x%x,0x%x,0x%x,0x%x\n",Offset,WriteBytes,WriteBuffer,
> *WriteBuffer));
> +  Status = ByteWriteI2CBasic(I2cControllerIndex,
> SlaveAddress,1,&Offset,TRUE,FALSE);
> +  Status = ByteWriteI2CBasic(I2cControllerIndex,
> SlaveAddress,WriteBytes,WriteBuffer,FALSE,TRUE);
> +
> +  return Status;
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLibDxe.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLibDxe.inf
> new file mode 100644
> index 0000000000..cd10f1de93
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLibDxe.inf
> @@ -0,0 +1,39 @@
> +## @file
> +#  Instance of I2C Library.
> +#
> +#  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = I2CLib
> +  FILE_GUID                      = 7f62bf44-2ba7-4c2d-9d4a-91c8906ff053
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = I2CLib|DXE_DRIVER DXE_RUNTIME_DRIVER
> UEFI_DRIVER UEFI_APPLICATION
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +
> +[Sources.common]
> +  I2CLib.c
> +
> +[LibraryClasses]
> +  BaseLib
> +  IoLib
> +  TimerLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +
> +[Protocols]
> +  gEfiGlobalNvsAreaProtocolGuid
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CRegs.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CRegs.h
> new file mode 100644
> index 0000000000..57455162f6
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CRegs.h
> @@ -0,0 +1,126 @@
> +/** @file
> +  Register Definitions for I2C Driver/PEIM.
> +
> +  Copyright (c) 2004  - 2015, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +--*/
> +
> +#ifndef I2C_REGS_H
> +#define I2C_REGS_H
> +
> +//
> +// FIFO write delay value.
> +//
> +#define FIFO_WRITE_DELAY    2
> +
> +//
> +// MMIO Register Definitions.
> +//
> +#define    R_IC_CON                          ( 0x00) // I2C Control
> +#define     B_IC_RESTART_EN                  BIT5
> +#define     B_IC_SLAVE_DISABLE               BIT6
> +#define     V_SPEED_STANDARD                 0x02
> +#define     V_SPEED_FAST                     0x04
> +#define     V_SPEED_HIGH                     0x06
> +#define     B_MASTER_MODE                    BIT0
> +
> +#define    R_IC_TAR                          ( 0x04) // I2C Target Address
> +#define     IC_TAR_10BITADDR_MASTER           BIT12
> +
> +#define    R_IC_SAR                          ( 0x08) // I2C Slave Address
> +#define    R_IC_HS_MADDR                     ( 0x0C) // I2C HS MasterMode Code
> Address
> +#define    R_IC_DATA_CMD                     ( 0x10) // I2C Rx/Tx Data Buffer and
> Command
> +
> +#define    B_READ_CMD                         BIT8    // 1 = read, 0 = write
> +#define    B_CMD_STOP                         BIT9    // 1 = STOP
> +#define    B_CMD_RESTART                      BIT10   // 1 = IC_RESTART_EN
> +
> +#define    V_WRITE_CMD_MASK                  ( 0xFF)
> +
> +#define    R_IC_SS_SCL_HCNT                  ( 0x14) // Standard Speed I2C Clock
> SCL High Count
> +#define    R_IC_SS_SCL_LCNT                  ( 0x18) // Standard Speed I2C Clock
> SCL Low Count
> +#define    R_IC_FS_SCL_HCNT                  ( 0x1C) // Full Speed I2C Clock SCL
> High Count
> +#define    R_IC_FS_SCL_LCNT                  ( 0x20) // Full Speed I2C Clock SCL
> Low Count
> +#define    R_IC_HS_SCL_HCNT                  ( 0x24) // High Speed I2C Clock SCL
> High Count
> +#define    R_IC_HS_SCL_LCNT                  ( 0x28) // High Speed I2C Clock SCL
> Low Count
> +#define    R_IC_INTR_STAT                    ( 0x2C) // I2C Inetrrupt Status
> +#define    R_IC_INTR_MASK                    ( 0x30) // I2C Interrupt Mask
> +#define     I2C_INTR_GEN_CALL                 BIT11  // General call received
> +#define     I2C_INTR_START_DET                BIT10
> +#define     I2C_INTR_STOP_DET                 BIT9
> +#define     I2C_INTR_ACTIVITY                 BIT8
> +#define     I2C_INTR_TX_ABRT                  BIT6   // Set on NACK
> +#define     I2C_INTR_TX_EMPTY                 BIT4
> +#define     I2C_INTR_TX_OVER                  BIT3
> +#define     I2C_INTR_RX_FULL                  BIT2   // Data bytes in RX FIFO over
> threshold
> +#define     I2C_INTR_RX_OVER                  BIT1
> +#define     I2C_INTR_RX_UNDER                 BIT0
> +#define    R_IC_RawIntrStat                ( 0x34) // I2C Raw Interrupt Status
> +#define    R_IC_RX_TL                        ( 0x38) // I2C Receive FIFO Threshold
> +#define    R_IC_TX_TL                        ( 0x3C) // I2C Transmit FIFO Threshold
> +#define    R_IC_CLR_INTR                     ( 0x40) // Clear Combined and Individual
> Interrupts
> +#define    R_IC_CLR_RX_UNDER                 ( 0x44) // Clear RX_UNDER
> Interrupt
> +#define    R_IC_CLR_RX_OVER                  ( 0x48) // Clear RX_OVERinterrupt
> +#define    R_IC_CLR_TX_OVER                  ( 0x4C) // Clear TX_OVER interrupt
> +#define    R_IC_CLR_RD_REQ                   ( 0x50) // Clear RD_REQ interrupt
> +#define    R_IC_CLR_TX_ABRT                  ( 0x54) // Clear TX_ABRT interrupt
> +#define    R_IC_CLR_RX_DONE                  ( 0x58) // Clear RX_DONE interrupt
> +#define    R_IC_CLR_ACTIVITY                 ( 0x5C) // Clear ACTIVITY interrupt
> +#define    R_IC_CLR_STOP_DET                 ( 0x60) // Clear STOP_DET interrupt
> +#define    R_IC_CLR_START_DET                ( 0x64) // Clear START_DET
> interrupt
> +#define    R_IC_CLR_GEN_CALL                 ( 0x68) // Clear GEN_CALL interrupt
> +#define    R_IC_ENABLE                       ( 0x6C) // I2C Enable
> +#define    R_IC_STATUS                       ( 0x70) // I2C Status
> +
> +#define    R_IC_SDA_HOLD                     ( 0x7C) // I2C
> IC_DEFAULT_SDA_HOLD//16bits
> +
> +#define     STAT_MST_ACTIVITY                 BIT5   // Master FSM Activity Status.
> +#define     STAT_RFF                          BIT4   // RX FIFO is completely full
> +#define     STAT_RFNE                         BIT3   // RX FIFO is not empty
> +#define     STAT_TFE                          BIT2   // TX FIFO is completely empty
> +#define     STAT_TFNF                         BIT1   // TX FIFO is not full
> +
> +#define    R_IC_TXFLR                        ( 0x74) // Transmit FIFO Level Register
> +#define    R_IC_RXFLR                        ( 0x78) // Receive FIFO Level Register
> +#define    R_IC_TX_ABRT_SOURCE               ( 0x80) // I2C Transmit Abort
> Status Register
> +#define    R_IC_SLV_DATA_NACK_ONLY           ( 0x84) // Generate
> SLV_DATA_NACK Register
> +#define    R_IC_DMA_CR                       ( 0x88) // DMA Control Register
> +#define    R_IC_DMA_TDLR                     ( 0x8C) // DMA Transmit Data Level
> +#define    R_IC_DMA_RDLR                     ( 0x90) // DMA Receive Data Level
> +#define    R_IC_SDA_SETUP                    ( 0x94) // I2C SDA Setup Register
> +#define    R_IC_ACK_GENERAL_CALL             ( 0x98) // I2C ACK General Call
> Register
> +#define    R_IC_ENABLE_STATUS                ( 0x9C) // I2C Enable Status
> Register
> +#define    R_IC_COMP_PARAM                   ( 0xF4) // Component Parameter
> Register
> +#define    R_IC_COMP_VERSION                 ( 0xF8) // Component Version ID
> +#define    R_IC_COMP_TYPE                    ( 0xFC) // Component Type
> +
> +#define    I2C_SS_SCL_HCNT_VALUE_100M        0x1DD
> +#define    I2C_SS_SCL_LCNT_VALUE_100M        0x1E4
> +#define    I2C_FS_SCL_HCNT_VALUE_100M        0x54
> +#define    I2C_FS_SCL_LCNT_VALUE_100M        0x9a
> +#define    I2C_HS_SCL_HCNT_VALUE_100M        0x7
> +#define    I2C_HS_SCL_LCNT_VALUE_100M        0xE
> +
> +#define     IC_TAR_10BITADDR_MASTER           BIT12
> +#define     FIFO_SIZE                         32
> +#define     R_IC_INTR_STAT                    ( 0x2C) // I2c Inetrrupt Status
> +#define     R_IC_INTR_MASK                    ( 0x30) // I2c Interrupt Mask
> +#define     I2C_INTR_GEN_CALL                 BIT11  // General call received
> +#define     I2C_INTR_START_DET                BIT10
> +#define     I2C_INTR_STOP_DET                 BIT9
> +#define     I2C_INTR_ACTIVITY                 BIT8
> +#define     I2C_INTR_TX_ABRT                  BIT6   // Set on NACK
> +#define     I2C_INTR_TX_EMPTY                 BIT4
> +#define     I2C_INTR_TX_OVER                  BIT3
> +#define     I2C_INTR_RX_FULL                  BIT2   // Data bytes in RX FIFO over
> threshold
> +#define     I2C_INTR_RX_OVER                  BIT1
> +#define     I2C_INTR_RX_UNDER                 BIT0
> +
> +#define R_PCH_LPIO_I2C_MEM_RESETS                 0x804 // Software Reset
> +#define B_PCH_LPIO_I2C_MEM_RESETS_FUNC            BIT1  // Function Clock
> Domain Reset
> +#define B_PCH_LPIO_I2C_MEM_RESETS_APB             BIT0  // APB Domain
> Reset
> +#define R_PCH_LPSS_I2C_MEM_PCP                    0x800 // Private Clock
> Parameters
> +
> +#endif
> \ No newline at end of file
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CAccess.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CAccess.h
> new file mode 100644
> index 0000000000..bf6ef4c747
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CAccess.h
> @@ -0,0 +1,44 @@
> +/** @file
> +  Misc Registers Definition.
> +
> +  Copyright (c) 2011  - 2015, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +--*/
> +
> +#ifndef _I2C_ACCESS_H_
> +#define _I2C_ACCESS_H_
> +
> +#include "I2CIoLibPei.h"
> +
> +#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_ACPI_BASE                    0x40            // ABASE, 16bit
> +#define R_PCH_LPC_ACPI_BASEADR                 0x400           // ABASE, 16bit
> +#define B_PCH_LPC_ACPI_BASE_EN                 BIT1            // Enable Bit
> +#define B_PCH_LPC_ACPI_BASE_BAR                0x0000FF80      // Base
> Address, 128 Bytes
> +#define V_PCH_ACPI_PM1_TMR_MAX_VAL             0x1000000       // The
> timer is 24 bit overflow
> +#define B_PCH_ACPI_PM1_TMR_VAL                 0xFFFFFF        // The timer
> value mask
> +
> +#define R_PCH_ACPI_PM1_TMR                     0x08            // Power
> Management 1 Timer
> +#define V_PCH_ACPI_PM1_TMR_FREQUENCY           3579545         // Timer
> Frequency
> +
> +
> +#define PchLpcPciCfg8(Register) I2CLibPeiMmioRead8 (MmPciAddress (0,
> DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0,
> Register))
> +
> +#define PCIEX_BASE_ADDRESS                     0xE0000000
> +#define PCI_EXPRESS_BASE_ADDRESS               ((VOID *) (UINTN)
> PCIEX_BASE_ADDRESS)
> +
> +#define MmPciAddress( Segment, Bus, Device, Function, Register ) \
> +  ( (UINTN)PCI_EXPRESS_BASE_ADDRESS + \
> +    (UINTN)(Bus << 20) + \
> +    (UINTN)(Device << 15) + \
> +    (UINTN)(Function << 12) + \
> +    (UINTN)(Register) \
> +  )
> +#endif
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.c
> new file mode 100644
> index 0000000000..d5f8dfd012
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.c
> @@ -0,0 +1,46 @@
> +/** @file
> +  MicroSecondDelay implementation of ACPI Timer.
> +
> +  Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +--*/
> +
> +#include "PiPei.h"
> +#include "I2CAccess.h"
> +#include "I2CDelayPei.h"
> +#include <Library/DebugLib.h>
> +#include <Library/PeiServicesTablePointerLib.h>
> +#include <Ppi/Stall.h>
> +
> +/**
> +  Stalls the CPU for at least the given number of microseconds.
> +  Stalls the CPU for the number of microseconds specified by MicroSeconds.
> +
> +  @param  MicroSeconds  The minimum number of microseconds to delay.
> +
> +  @return EFI_STATUS
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +MicroSecondDelay (
> +  IN      UINTN                     MicroSeconds
> +  )
> +{
> +
> +  EFI_PEI_STALL_PPI              *StallPpi;
> +  EFI_STATUS                     Status;
> +  CONST EFI_PEI_SERVICES         **PeiServices;
> +
> +  PeiServices = GetPeiServicesTablePointer();
> +
> +
> +  Status = (**PeiServices).LocatePpi (PeiServices, &gEfiPeiStallPpiGuid, 0,
> NULL, &StallPpi);
> +  ASSERT(!EFI_ERROR(Status));
> +
> +  StallPpi->Stall (PeiServices, StallPpi, MicroSeconds);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.h
> new file mode 100644
> index 0000000000..604f1f67c5
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.h
> @@ -0,0 +1,30 @@
> +/** @file
> +  MicroSecondDelay implementation of ACPI Timer.
> +
> +  Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef __I2C_DELAY_PEI__
> +
> +#define __I2C_DELAY_PEI__
> +#include "PiPei.h"
> +
> +/**
> +  Stalls the CPU for at least the given number of microseconds.
> +
> +  Stalls the CPU for the number of microseconds specified by MicroSeconds.
> +
> +  @param  MicroSeconds  The minimum number of microseconds to delay.
> +
> +  @return MicroSeconds
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +MicroSecondDelay (
> +  IN      UINTN                     MicroSeconds
> +  );
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.c
> new file mode 100644
> index 0000000000..6a37dbec1d
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.c
> @@ -0,0 +1,178 @@
> +/** @file
> +  Functions for access I2C MMIO register.
> +
> +  Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <PiPei.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PeiServicesTablePointerLib.h>
> +
> +/**
> +  Reads an 8-bit MMIO register.
> +
> +  Reads the 8-bit MMIO register specified by Address. The 8-bit read value is
> +  returned. This function must guarantee that all MMIO read and write
> +  operations are serialized.
> +
> +  If 8-bit MMIO register operations are not supported, then ASSERT().
> +
> +  @param  Address The MMIO register to read.
> +
> +  @return The value read.
> +
> +**/
> +UINT8
> +EFIAPI
> +I2CLibPeiMmioRead8 (
> +  IN UINTN Address
> +  )
> +{
> +  UINT8 Value;
> +
> +  Value = *(volatile UINT8*)Address;
> +  return Value;
> +}
> +
> +/**
> +  Reads a 16-bit MMIO register.
> +
> +  Reads the 16-bit MMIO register specified by Address. The 16-bit read value
> is
> +  returned. This function must guarantee that all MMIO read and write
> +  operations are serialized.
> +
> +  If 16-bit MMIO register operations are not supported, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> +  @param  Address The MMIO register to read.
> +
> +  @return The value read.
> +
> +**/
> +UINT16
> +EFIAPI
> +I2CLibPeiMmioRead16 (
> +  IN UINTN  Address
> +  )
> +{
> +  UINT16 Value;
> +
> +  ASSERT ((Address & 1) == 0);
> +  Value = *(volatile UINT16*)Address;
> +  return Value;
> +}
> +
> +/**
> +  Writes a 16-bit MMIO register.
> +
> +  Writes the 16-bit MMIO register specified by Address with the value
> specified
> +  by Value and returns Value. This function must guarantee that all MMIO
> read
> +  and write operations are serialized.
> +
> +  If 16-bit MMIO register operations are not supported, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> +  @param  Address The MMIO register to write.
> +  @param  Value   The value to write to the MMIO register.
> +
> +  @return Value.
> +
> +**/
> +UINT16
> +EFIAPI
> +I2CLibPeiMmioWrite16 (
> +  IN  UINTN   Address,
> +  IN  UINT16  Value
> +  )
> +{
> +  ASSERT ((Address & 1) == 0);
> +  *(volatile UINT16*)Address = Value;
> +  return Value;
> +}
> +
> +/**
> +  Reads a 32-bit MMIO register.
> +
> +  Reads the 32-bit MMIO register specified by Address. The 32-bit read value
> is
> +  returned. This function must guarantee that all MMIO read and write
> +  operations are serialized.
> +
> +  If 32-bit MMIO register operations are not supported, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> +  @param  Address The MMIO register to read.
> +
> +  @return The value read.
> +
> +**/
> +UINT32
> +EFIAPI
> +I2CLibPeiMmioRead32 (
> +  IN UINTN Address
> +  )
> +{
> +  UINT32  Value;
> +
> +  ASSERT ((Address & 3) == 0);
> +  Value = *(volatile UINT32*)Address;
> +
> +  return Value;
> +}
> +
> +/**
> +  Writes a 32-bit MMIO register.
> +
> +  Writes the 32-bit MMIO register specified by Address with the value
> specified
> +  by Value and returns Value. This function must guarantee that all MMIO
> read
> +  and write operations are serialized.
> +
> +  If 32-bit MMIO register operations are not supported, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> +  @param  Address The MMIO register to write.
> +  @param  Value   The value to write to the MMIO register.
> +
> +  @return Value.
> +
> +**/
> +UINT32
> +EFIAPI
> +I2CLibPeiMmioWrite32 (
> +  IN      UINTN                     Address,
> +  IN      UINT32                    Value
> +  )
> +{
> +  ASSERT ((Address & 3) == 0);
> +  *(volatile UINT32*)Address = Value;
> +  return Value;
> +}
> +
> +/**
> +  OR a 32-bit MMIO register.
> +
> +  OR the 32-bit MMIO register specified by Address with the value specified
> +  by Value and returns Value. This function must guarantee that all MMIO
> read
> +  and write operations are serialized.
> +
> +  If 32-bit MMIO register operations are not supported, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> +  @param  Address The MMIO register to write OR.
> +  @param  Value   The value to OR to the MMIO register.
> +
> +  @return Value.
> +
> +**/
> +UINT32
> +EFIAPI
> +I2CLibPeiMmioOr32 (
> +  IN      UINTN                     Address,
> +  IN      UINT32                    OrData
> +  )
> +{
> +  return I2CLibPeiMmioWrite32 (Address, I2CLibPeiMmioRead32(Address) |
> OrData);
> +}
> +
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.h
> new file mode 100644
> index 0000000000..b68bc1ed09
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.h
> @@ -0,0 +1,153 @@
> +/** @file
> +  Functions for access I2C MMIO register.
> +
> +  Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef __I2C_IOLIB_PEI__
> +
> +#define __I2C_IOLIB_PEI__
> +#include <PiPei.h>
> +
> +
> +/**
> +  Reads an 8-bit MMIO register.
> +
> +  Reads the 8-bit MMIO register specified by Address. The 8-bit read value is
> +  returned. This function must guarantee that all MMIO read and write
> +  operations are serialized.
> +
> +  If 8-bit MMIO register operations are not supported, then ASSERT().
> +
> +  @param  Address The MMIO register to read.
> +
> +  @return The value read.
> +
> +**/
> +
> +UINT8
> +EFIAPI
> +I2CLibPeiMmioRead8 (
> +  IN      UINTN                     Address
> +  );
> +
> +
> +/**
> +  Reads a 16-bit MMIO register.
> +
> +  Reads the 16-bit MMIO register specified by Address. The 16-bit read value
> is
> +  returned. This function must guarantee that all MMIO read and write
> +  operations are serialized.
> +
> +  If 16-bit MMIO register operations are not supported, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> +  @param  Address The MMIO register to read.
> +
> +  @return The value read.
> +
> +**/
> +UINT16
> +EFIAPI
> +I2CLibPeiMmioRead16 (
> +  IN      UINTN                     Address
> +  );
> +
> +
> +/**
> +  Writes a 16-bit MMIO register.
> +
> +  Writes the 16-bit MMIO register specified by Address with the value
> specified
> +  by Value and returns Value. This function must guarantee that all MMIO
> read
> +  and write operations are serialized.
> +
> +  If 16-bit MMIO register operations are not supported, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> +  @param  Address The MMIO register to write.
> +  @param  Value   The value to write to the MMIO register.
> +
> +  @return Value.
> +
> +**/
> +UINT16
> +EFIAPI
> +I2CLibPeiMmioWrite16 (
> +  IN      UINTN                     Address,
> +  IN      UINT16                    Value
> +  );
> +
> +
> +/**
> +  Reads a 32-bit MMIO register.
> +
> +  Reads the 32-bit MMIO register specified by Address. The 32-bit read value
> is
> +  returned. This function must guarantee that all MMIO read and write
> +  operations are serialized.
> +
> +  If 32-bit MMIO register operations are not supported, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> +  @param  Address The MMIO register to read.
> +
> +  @return The value read.
> +
> +**/
> +UINT32
> +EFIAPI
> +I2CLibPeiMmioRead32 (
> +  IN      UINTN                     Address
> +  );
> +
> +
> +/**
> +  Writes a 32-bit MMIO register.
> +
> +  Writes the 32-bit MMIO register specified by Address with the value
> specified
> +  by Value and returns Value. This function must guarantee that all MMIO
> read
> +  and write operations are serialized.
> +
> +  If 32-bit MMIO register operations are not supported, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> +  @param  Address The MMIO register to write.
> +  @param  Value   The value to write to the MMIO register.
> +
> +  @return Value.
> +
> +**/
> +UINT32
> +EFIAPI
> +I2CLibPeiMmioWrite32 (
> +  IN      UINTN                     Address,
> +  IN      UINT32                    Value
> +  );
> +
> +
> +/**
> +  OR a 32-bit MMIO register.
> +
> +  OR the 32-bit MMIO register specified by Address with the value specified
> +  by Value and returns Value. This function must guarantee that all MMIO
> read
> +  and write operations are serialized.
> +
> +  If 32-bit MMIO register operations are not supported, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> +  @param  Address The MMIO register to write OR.
> +  @param  Value   The value to OR to the MMIO register.
> +
> +  @return Value.
> +
> +**/
> +UINT32
> +EFIAPI
> +I2CLibPeiMmioOr32 (
> +  IN      UINTN                     Address,
> +  IN      UINT32                    OrData
> +  );
> +
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.c
> new file mode 100644
> index 0000000000..dd5cceb70d
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.c
> @@ -0,0 +1,638 @@
> +/** @file
> +  I2C PEI Lib Instance.
> +
> +  Copyright (c) 1999- 2015, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "I2CDelayPei.h"
> +#include "I2CIoLibPei.h"
> +#include "I2CAccess.h"
> +#include "I2CLibPei.h"
> +#include <PlatformBaseAddresses.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PeiServicesTablePointerLib.h>
> +#include <Library/HobLib.h>
> +#include <PchRegs/PchRegsPcu.h>
> +#include <PchRegs/PchRegsLpss.h>
> +
> +#define LPSS_PCI_DEVICE_NUMBER  8
> +
> +#define R_PCH_LPIO_I2C_MEM_RESETS                 0x804 // Software Reset
> +#define B_PCH_LPIO_I2C_MEM_RESETS_FUNC            BIT1  // Function Clock
> Domain Reset
> +#define B_PCH_LPIO_I2C_MEM_RESETS_APB             BIT0  // APB Domain
> Reset
> +#define R_PCH_LPSS_I2C_MEM_PCP                    0x800 // Private Clock
> Parameters
> +
> +#define PEI_TEPM_LPSS_DMA_BAR                     0xFE900000
> +#define PEI_TEPM_LPSS_I2C0_BAR                    0xFE910000
> +#define PCI_CONFIG_SPACE_SIZE                     0x10000
> +
> +EFI_GUID  mI2CPeiInitGuid = {
> +  0x96DED71A, 0xB9E7, 0x4EAD, 0x96, 0x2C, 0x01, 0x69, 0x3C, 0xED, 0x2A,
> 0x64
> +};
> +
> +
> +UINT16 I2CGPIO[]= {
> +  //
> +  // 19.1.6  I2C0
> +  // I2C0_SDA-OD-O -    write 0x2003CC81 to IOBASE + 0x0210
> +  // I2C0_SCL-OD-O -    write 0x2003CC81 to IOBASE + 0x0200
> +  //
> +  0x0210,
> +  0x0200,
> +
> +  //
> +  // 19.1.7  I2C1
> +  // I2C1_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x01F0
> +  // I2C1_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x01E0
> +  //
> +  0x01F0,
> +  0x01E0,
> +
> +  //
> +  // 19.1.8  I2C2
> +  // I2C2_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x01D0
> +  // I2C2_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x01B0
> +  //
> +  0x01D0,
> +  0x01B0,
> +
> +  //
> +  // 19.1.9  I2C3
> +  // I2C3_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x0190
> +  // I2C3_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x01C0
> +  //
> +  0x0190,
> +  0x01C0,
> +
> +  //
> +  // 19.1.10 I2C4
> +  // I2C4_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x01A0
> +  // I2C4_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x0170
> +  //
> +  0x01A0,
> +  0x0170,
> +
> +  //
> +  // 19.1.11 I2C5
> +  // I2C5_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x0150
> +  // I2C5_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x0140
> +  //
> +  0x0150,
> +  0x0140,
> +
> +  //
> +  // 19.1.12 I2C6
> +  // I2C6_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x0180
> +  // I2C6_SCL-OD-O/I -  write 0x2003CC81 to IOBASE + 0x0160
> +  //
> +  0x0180,
> +  0x0160
> +};
> +
> +/**
> +  Constructor of this library.
> +
> +  @param   VOID
> +
> +  @return  EFI_SUCCESS
> +**/
> +EFI_STATUS
> +EFIAPI
> +IntelI2CPeiLibConstructor (
> +  IN EFI_PEI_FILE_HANDLE     FileHandle,
> +  IN CONST EFI_PEI_SERVICES  **PeiServices
> +  )
> +{
> +  UINTN Index;
> +
> +  for (Index = 0; Index < sizeof(I2CGPIO)/sizeof(UINT16); Index ++) {
> +    I2CLibPeiMmioWrite32(IO_BASE_ADDRESS+I2CGPIO[Index], 0x2003CC81);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Programe all I2C controllers on LPSS.
> +
> +  I2C0 is function 1 of LPSS. I2C1 is function 2 of LPSS, etc..
> +
> +  @param   VOID
> +
> +  @return  EFI_SUCCESS
> +**/
> +EFI_STATUS
> +ProgramPciLpssI2C (
> +  VOID
> +  )
> +{
> +  UINT32       PmcBase;
> +  UINT32       DevID;
> +  UINTN        PciMmBase=0;
> +  UINTN        Index;
> +  UINTN        Bar0;
> +  UINTN        Bar1;
> +  DEBUG ((EFI_D_INFO, "Pei ProgramPciLpssI2C() Start\n"));
> +
> +  //
> +  // Set the VLV Function Disable Register to ZERO
> +  //
> +  PmcBase         = I2CLibPeiMmioRead32(PciD31F0RegBase +
> R_PCH_LPC_PMC_BASE) & B_PCH_LPC_PMC_BASE_BAR;
> +
> +  if(I2CLibPeiMmioRead32(PmcBase + R_PCH_PMC_FUNC_DIS)&
> +      (B_PCH_PMC_FUNC_DIS_LPSS2_FUNC1 |
> B_PCH_PMC_FUNC_DIS_LPSS2_FUNC2
> +       | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC3 |
> B_PCH_PMC_FUNC_DIS_LPSS2_FUNC4 |
> B_PCH_PMC_FUNC_DIS_LPSS2_FUNC5
> +       | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC6 |
> B_PCH_PMC_FUNC_DIS_LPSS2_FUNC7)) {
> +    I2CLibPeiMmioWrite32(
> +      PmcBase+R_PCH_PMC_FUNC_DIS,
> +      I2CLibPeiMmioRead32(PmcBase + R_PCH_PMC_FUNC_DIS)& \
> +      ~(B_PCH_PMC_FUNC_DIS_LPSS2_FUNC1 |
> B_PCH_PMC_FUNC_DIS_LPSS2_FUNC2 \
> +        | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC3 |
> B_PCH_PMC_FUNC_DIS_LPSS2_FUNC4 \
> +        | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC5 |
> B_PCH_PMC_FUNC_DIS_LPSS2_FUNC6|B_PCH_PMC_FUNC_DIS_LPSS2_FU
> NC7)
> +      );
> +    DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() enable all I2C controllers\n"));
> +  }
> +
> +  for(Index = 0; Index < LPSS_PCI_DEVICE_NUMBER; Index ++) {
> +
> +    PciMmBase = MmPciAddress (
> +                  0,
> +                  DEFAULT_PCI_BUS_NUMBER_PCH,
> +                  PCI_DEVICE_NUMBER_PCH_LPSS_I2C,
> +                  Index,
> +                  0
> +                  );
> +    DevID =  I2CLibPeiMmioRead32(PciMmBase);
> +
> +    Bar0 = PEI_TEPM_LPSS_DMA_BAR + (Index * PCI_CONFIG_SPACE_SIZE);
> +    Bar1 = Bar0 + 0x8000;
> +
> +    DEBUG((EFI_D_ERROR, "Program Pci Lpss I2C Device  Function=%x
> DevID=%08x\n", Index, DevID));
> +
> +    //
> +    // Check if device present
> +    //
> +    if (DevID  != 0xFFFFFFFF)  {
> +      if(!(I2CLibPeiMmioRead32 (PciMmBase + R_PCH_LPSS_I2C_STSCMD) &
> B_PCH_LPSS_I2C_STSCMD_MSE)) {
> +        //
> +        // Program BAR 0
> +        //
> +        I2CLibPeiMmioWrite32((UINTN) (PciMmBase + R_PCH_LPSS_I2C_BAR),
> (UINT32)(Bar0 & B_PCH_LPSS_I2C_BAR_BA));
> +
> +        DEBUG ((EFI_D_ERROR, "I2CBaseAddress1 = 0x%x
> \n",I2CLibPeiMmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR)));
> +
> +        //
> +        // Program BAR 1
> +        //
> +        I2CLibPeiMmioWrite32 ((UINTN)(PciMmBase + R_PCH_LPSS_I2C_BAR1),
> (UINT32)(Bar1 & B_PCH_LPSS_I2C_BAR1_BA));
> +        DEBUG ((EFI_D_ERROR, "I2CBaseAddress1 = 0x%x
> \n",I2CLibPeiMmioRead32(PciMmBase+R_PCH_LPSS_I2C_BAR1)));
> +
> +        //
> +        // Bus Master Enable & Memory Space Enable
> +        //
> +        I2CLibPeiMmioWrite32((UINTN) (PciMmBase +
> R_PCH_LPSS_I2C_STSCMD), (UINT32)(B_PCH_LPSS_I2C_STSCMD_BME |
> B_PCH_LPSS_I2C_STSCMD_MSE));
> +      }
> +
> +      //
> +      // Release Resets
> +      //
> +      I2CLibPeiMmioWrite32 (Bar0 + R_PCH_LPIO_I2C_MEM_RESETS,
> (B_PCH_LPIO_I2C_MEM_RESETS_FUNC |
> B_PCH_LPIO_I2C_MEM_RESETS_APB));
> +
> +      //
> +      // Activate Clocks
> +      //
> +      I2CLibPeiMmioWrite32 (Bar0 + R_PCH_LPSS_I2C_MEM_PCP,
> 0x80020003);//No use for A0
> +
> +      DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() Programmed()\n"));
> +    }
> +
> +  }
> +
> +  DEBUG ((EFI_D_INFO, "Pei ProgramPciLpssI2C() End\n"));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Disable I2C Bus.
> +
> +  @param I2cControllerIndex   Index of I2C controller.
> +
> +  @return EFI_SUCCESS
> +**/
> +EFI_STATUS
> +I2cDisable (
> +  IN UINT8 I2cControllerIndex
> +  )
> +{
> +  UINTN  I2CBaseAddress;
> +  UINT32 NumTries = 10000;  // 0.1 seconds
> +
> +  I2CBaseAddress = (UINT32) PEI_TEPM_LPSS_I2C0_BAR +
> I2cControllerIndex * PCI_CONFIG_SPACE_SIZE;
> +
> +  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_ENABLE, 0);
> +  while (0 != ( I2CLibPeiMmioRead16 (I2CBaseAddress +
> R_IC_ENABLE_STATUS ) & 1)) {
> +    MicroSecondDelay (10);
> +    NumTries --;
> +    if(0 == NumTries) return EFI_NOT_READY;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Enable I2C Bus.
> +
> +  @param I2cControllerIndex   Index of I2C controller.
> +
> +  @return EFI_SUCCESS
> +**/
> +EFI_STATUS
> +I2cEnable (
> +  IN UINT8 I2cControllerIndex
> +  )
> +{
> +  UINTN   I2CBaseAddress;
> +  UINT32 NumTries = 10000;  // 0.1 seconds
> +
> +  I2CBaseAddress = (UINT32) PEI_TEPM_LPSS_I2C0_BAR+
> I2cControllerIndex * PCI_CONFIG_SPACE_SIZE;
> +  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_ENABLE, 1);
> +  while (0 == ( I2CLibPeiMmioRead16 ( I2CBaseAddress +
> R_IC_ENABLE_STATUS ) & 1)) {
> +    MicroSecondDelay (10);
> +    NumTries --;
> +    if(0 == NumTries) return EFI_NOT_READY;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Set the I2C controller bus clock frequency.
> +
> +  @param[in] This           Address of the library's I2C context structure
> +  @param[in] PlatformData   Address of the platform configuration data
> +  @param[in] BusClockHertz  New I2C bus clock frequency in Hertz
> +
> +  @retval RETURN_SUCCESS      The bus frequency was set successfully.
> +  @retval RETURN_UNSUPPORTED  The controller does not support this
> frequency.
> +
> +**/
> +EFI_STATUS
> +I2cBusFrequencySet (
> +  IN UINTN   I2CBaseAddress,
> +  IN UINTN   BusClockHertz,
> +  IN UINT16  *I2cMode
> +  )
> +{
> +  DEBUG((EFI_D_INFO,"InputFreq BusClockHertz: %d\r\n",BusClockHertz));
> +
> +  *I2cMode = B_IC_RESTART_EN | B_IC_SLAVE_DISABLE |
> B_MASTER_MODE;
> +
> +  //
> +  //  Set the 100 KHz clock divider
> +  //
> +  //  From Table 10 of the I2C specification
> +  //
> +  //    High: 4.00 uS
> +  //    Low:  4.70 uS
> +  //
> +  I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_SS_SCL_HCNT,
> (UINT16)0x214 );
> +  I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_SS_SCL_LCNT,
> (UINT16)0x272 );
> +
> +  //
> +  //    Set the 400 KHz clock divider
> +  //
> +  //    From Table 10 of the I2C specification
> +  //
> +  //      High: 0.60 uS
> +  //      Low:  1.30 uS
> +  //
> +  I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_FS_SCL_HCNT,
> (UINT16)0x50 );
> +  I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_FS_SCL_LCNT,
> (UINT16)0xAD );
> +
> +  switch ( BusClockHertz ) {
> +    case 100 * 1000:
> +      I2CLibPeiMmioWrite32 ( I2CBaseAddress + R_IC_SDA_HOLD,
> (UINT16)0x40);//100K
> +      *I2cMode |= V_SPEED_STANDARD;
> +      break;
> +    case 400 * 1000:
> +      I2CLibPeiMmioWrite32 ( I2CBaseAddress + R_IC_SDA_HOLD,
> (UINT16)0x32);//400K
> +      *I2cMode |= V_SPEED_FAST;
> +      break;
> +    default:
> +      I2CLibPeiMmioWrite32 ( I2CBaseAddress + R_IC_SDA_HOLD,
> (UINT16)0x09);//3.4M
> +      *I2cMode |= V_SPEED_HIGH;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Initializes the host controller to execute I2C commands.
> +
> +  @param I2cControllerIndex Index of I2C controller in LPSS device. 0
> represents I2C0, which is PCI function 1 of LPSS device.
> +
> +  @return EFI_SUCCESS       Opcode initialization on the I2C host controller
> completed.
> +  @return EFI_DEVICE_ERROR  Device error, operation failed.
> +**/
> +EFI_STATUS
> +I2CInit (
> +  UINT8 I2cControllerIndex,
> +  UINT16 SlaveAddress
> +  )
> +{
> +  EFI_STATUS   Status;
> +  UINT32       NumTries = 0;
> +  UINTN        I2CBaseAddress;
> +  UINT16       I2cMode;
> +  UINTN        PciMmBase=0;
> +
> +
> +  PciMmBase = MmPciAddress (
> +                0,
> +                DEFAULT_PCI_BUS_NUMBER_PCH,
> +                PCI_DEVICE_NUMBER_PCH_LPSS_I2C,
> +                (I2cControllerIndex + 1),
> +                0
> +                );
> +
> +  I2CBaseAddress = I2CLibPeiMmioRead32
> (PciMmBase+R_PCH_LPSS_I2C_BAR);
> +
> +  //
> +  //  Verify the parameters
> +  //
> +  if (1023 < SlaveAddress ) {
> +    Status =  EFI_INVALID_PARAMETER;
> +    DEBUG((EFI_D_INFO,"I2cStartRequest Exit with Status %r\r\n", Status));
> +    return Status;
> +  }
> +
> +  if(I2CBaseAddress ==  (PEI_TEPM_LPSS_I2C0_BAR + I2cControllerIndex *
> PCI_CONFIG_SPACE_SIZE)) {
> +    return EFI_SUCCESS;
> +  }
> +  ProgramPciLpssI2C();
> +
> +  I2CBaseAddress = (UINT32) (PEI_TEPM_LPSS_I2C0_BAR +
> I2cControllerIndex * PCI_CONFIG_SPACE_SIZE);
> +  DEBUG ((EFI_D_ERROR, "I2CBaseAddress = 0x%x \n",I2CBaseAddress));
> +  NumTries = 10000; // 1 seconds
> +  while ((1 == ( I2CLibPeiMmioRead32 ( I2CBaseAddress + R_IC_STATUS) &
> STAT_MST_ACTIVITY ))) {
> +    MicroSecondDelay(10);
> +    NumTries --;
> +    if(0 == NumTries)
> +      return EFI_DEVICE_ERROR;
> +  }
> +
> +  Status = I2cDisable (I2cControllerIndex);
> +  DEBUG((EFI_D_INFO, "I2cDisable Status = %r\r\n", Status));
> +
> +  I2cBusFrequencySet(I2CBaseAddress, 400 * 1000, &I2cMode);//Set
> I2cMode
> +
> +  I2CLibPeiMmioWrite16(I2CBaseAddress + R_IC_INTR_MASK, 0x0);
> +  if (0x7F < SlaveAddress) {
> +    SlaveAddress = (SlaveAddress & 0x3ff ) | IC_TAR_10BITADDR_MASTER;
> +  }
> +  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_TAR, (UINT16)
> SlaveAddress );
> +  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_RX_TL, 0);
> +  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_TX_TL, 0 );
> +  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_CON, I2cMode);
> +
> +  Status = I2cEnable(I2cControllerIndex);
> +  DEBUG((EFI_D_INFO, "I2cEnable Status = %r\r\n", Status));
> +  I2CLibPeiMmioRead16 ( I2CBaseAddress + R_IC_CLR_TX_ABRT );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Reads a Byte from I2C Device.
> +
> +  @param  I2cControllerIndex  I2C Bus no to which the I2C device has been
> connected
> +  @param  SlaveAddress        Device Address from which the byte value has
> to be read
> +  @param  Offset              Offset from which the data has to be read
> +  @param  *Byte               Address to which the value read has to be stored
> +
> +  @return  EFI_SUCCESS        If the byte value has been successfully read
> +  @return  EFI_DEVICE_ERROR   Operation Failed, Device Error
> +**/
> +EFI_STATUS ByteReadI2CBasic(
> +  IN  UINT8 I2cControllerIndex,
> +  IN  UINT8 SlaveAddress,
> +  IN  UINTN ReadBytes,
> +  OUT UINT8 *ReadBuffer,
> +  IN  UINT8 Start,
> +  IN  UINT8 End
> +  )
> +{
> +
> +  EFI_STATUS Status;
> +  UINT32 I2cStatus;
> +  UINT16 ReceiveData;
> +  UINT8 *ReceiveDataEnd;
> +  UINT8 *ReceiveRequest;
> +  UINT16 RawIntrStat;
> +  UINTN   I2CBaseAddress;
> +
> +  I2CBaseAddress = (UINT32)(PEI_TEPM_LPSS_I2C0_BAR +
> I2cControllerIndex * PCI_CONFIG_SPACE_SIZE);
> +
> +  Status = EFI_SUCCESS;
> +
> +  I2CInit(I2cControllerIndex, SlaveAddress);
> +
> +  ReceiveDataEnd = &ReadBuffer [ReadBytes];
> +  if(ReadBytes) {
> +    ReceiveRequest = ReadBuffer;
> +    DEBUG((EFI_D_INFO,"Read: ---------------%d bytes to
> RX\r\n",ReceiveDataEnd - ReceiveRequest));
> +
> +    while ((ReceiveDataEnd > ReceiveRequest) || (ReceiveDataEnd >
> ReadBuffer)) {
> +      //
> +      // Check for NACK
> +      //
> +      RawIntrStat = I2CLibPeiMmioRead16 (I2CBaseAddress +
> R_IC_RawIntrStat );
> +      if ( 0 != (RawIntrStat & I2C_INTR_TX_ABRT )) {
> +        I2CLibPeiMmioRead16 ( I2CBaseAddress + R_IC_CLR_TX_ABRT );
> +        Status = RETURN_DEVICE_ERROR;
> +        DEBUG((EFI_D_INFO,"TX ABRT ,%d bytes hasn't been
> transferred\r\n",ReceiveDataEnd - ReceiveRequest));
> +        break;
> +      }
> +
> +      //
> +      // Determine if another byte was received
> +      //
> +      I2cStatus = I2CLibPeiMmioRead16 ( I2CBaseAddress + R_IC_STATUS );
> +      if ( 0 != ( I2cStatus & STAT_RFNE )) {
> +        ReceiveData = I2CLibPeiMmioRead16 ( I2CBaseAddress +
> R_IC_DATA_CMD );
> +        *ReadBuffer++ = (UINT8)ReceiveData;
> +        DEBUG((EFI_D_INFO,"MmioRead32 ,1 byte 0x:%x is
> received\r\n",ReceiveData));
> +      }
> +
> +      if(ReceiveDataEnd==ReceiveRequest) {
> +        //
> +        // Waiting the last request to get data and make (ReceiveDataEnd >
> ReadBuffer) =TRUE.
> +        //
> +        continue;
> +      }
> +
> +      //
> +      // Wait until a read request will fit
> +      //
> +      if ( 0 == ( I2cStatus & STAT_TFNF )) {
> +        MicroSecondDelay ( 10 );
> +        continue;
> +      }
> +
> +      //
> +      // Issue the next read request
> +      //
> +      if(End && Start ) {
> +        I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_DATA_CMD,
> B_READ_CMD|B_CMD_RESTART|B_CMD_STOP);
> +      } else if (!End && Start ) {
> +        I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_DATA_CMD,
> B_READ_CMD|B_CMD_RESTART);
> +      } else if (End && !Start ) {
> +        I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_DATA_CMD,
> B_READ_CMD|B_CMD_STOP);
> +      } else if (!End && !Start ) {
> +        I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_DATA_CMD,
> B_READ_CMD);
> +      }
> +      ReceiveRequest += 1;
> +    }
> +
> +  }
> +  return Status;
> +
> +}
> +
> +/**
> +  Writes a Byte to I2C Device.
> +
> +  @param  I2cControllerIndex   I2C Bus no to which the I2C device has been
> connected
> +  @param  SlaveAddress         Device Address from which the byte value has
> to be written
> +  @param  Offset               Offset from which the data has to be read
> +  @param  *Byte                Address to which the value written is stored
> +
> +  @return  EFI_SUCCESS         IF the byte value has been successfully written
> +  @return  EFI_DEVICE_ERROR    Operation Failed, Device Error
> +**/
> +EFI_STATUS
> +ByteWriteI2CBasic(
> +  IN  UINT8 I2cControllerIndex,
> +  IN  UINT8 SlaveAddress,
> +  IN  UINTN WriteBytes,
> +  IN  UINT8 *WriteBuffer,
> +  IN  UINT8 Start,
> +  IN  UINT8 End
> +  )
> +{
> +
> +  EFI_STATUS Status;
> +  UINT32 I2cStatus;
> +  UINT8 *TransmitEnd;
> +  UINT16 RawIntrStat;
> +  UINTN   I2CBaseAddress;
> +
> +  I2CBaseAddress = (UINT32)PEI_TEPM_LPSS_I2C0_BAR+ I2cControllerIndex
> * PCI_CONFIG_SPACE_SIZE;
> +
> +  Status = EFI_SUCCESS;
> +
> +  I2CInit(I2cControllerIndex, SlaveAddress);
> +
> +  TransmitEnd = &WriteBuffer [WriteBytes];
> +  if( WriteBytes ) {
> +
> +    DEBUG((EFI_D_INFO,"Write: --------------%d bytes to TX\r\n",
> TransmitEnd - WriteBuffer));
> +
> +    while ( TransmitEnd > WriteBuffer) {
> +      I2cStatus = I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_STATUS);
> +      RawIntrStat = I2CLibPeiMmioRead16 (I2CBaseAddress +
> R_IC_RawIntrStat);
> +      if ( 0 != (RawIntrStat & I2C_INTR_TX_ABRT)) {
> +        I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_CLR_TX_ABRT);
> +        Status = RETURN_DEVICE_ERROR;
> +        DEBUG((EFI_D_ERROR,"TX ABRT TransmitEnd:0x%x
> WriteBuffer:0x%x\r\n", TransmitEnd, WriteBuffer));
> +        break;
> +      }
> +      if (0 == ( I2cStatus & STAT_TFNF)) {
> +        continue;
> +      }
> +      if(End && Start) {
> +        I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_DATA_CMD,
> (*WriteBuffer++) | B_CMD_RESTART | B_CMD_STOP);
> +      } else if (!End && Start ) {
> +        I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_DATA_CMD,
> (*WriteBuffer++) | B_CMD_RESTART);
> +      } else if (End && !Start ) {
> +        I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_DATA_CMD,
> (*WriteBuffer++) | B_CMD_STOP);
> +      } else if (!End && !Start ) {
> +        I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_DATA_CMD,
> (*WriteBuffer++));
> +      }
> +
> +      // Add a small delay to work around some odd behavior being seen.
> Without this delay bytes get dropped.
> +      MicroSecondDelay ( FIFO_WRITE_DELAY );
> +    }
> +
> +  }
> +
> +  if(EFI_ERROR(Status)) {
> +    DEBUG((EFI_D_INFO,"I2cStartRequest Exit with Status %r\r\n",Status));
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  Reads a Byte from I2C Device.
> +
> +  @param  I2cControllerIndex   I2C Bus no to which the I2C device has been
> connected
> +  @param  SlaveAddress         Device Address from which the byte value has
> to be read
> +  @param  Offset               Offset from which the data has to be read
> +  @param  ReadBytes            Number of bytes to be read
> +  @param  *ReadBuffer          Address to which the value read has to be
> stored
> +
> +  @return  EFI_SUCCESS       IF the byte value has been successfully read
> +  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
> +**/
> +EFI_STATUS
> +ByteReadI2C(
> +  IN  UINT8 I2cControllerIndex,
> +  IN  UINT8 SlaveAddress,
> +  IN  UINT8 Offset,
> +  IN  UINTN ReadBytes,
> +  OUT UINT8 *ReadBuffer
> +  )
> +{
> +  EFI_STATUS        Status;
> +
> +  DEBUG ((EFI_D_ERROR, "ByteReadI2C:---offset:0x%x\n",Offset));
> +  Status = ByteWriteI2CBasic(I2cControllerIndex, SlaveAddress, 1,
> &Offset,TRUE,FALSE);
> +  Status = ByteReadI2CBasic(I2cControllerIndex, SlaveAddress, ReadBytes,
> ReadBuffer, TRUE, TRUE);
> +
> +  return Status;
> +}
> +
> +/**
> +  Writes a Byte to I2C Device.
> +
> +  @param  I2cControllerIndex  I2C Bus no to which the I2C device has been
> connected
> +  @param  SlaveAddress        Device Address from which the byte value has
> to be written
> +  @param  Offset              Offset from which the data has to be written
> +  @param  WriteBytes          Number of bytes to be written
> +  @param  *Byte               Address to which the value written is stored
> +
> +  @return  EFI_SUCCESS       IF the byte value has been successfully read
> +  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
> +**/
> +EFI_STATUS ByteWriteI2C(
> +  IN  UINT8 I2cControllerIndex,
> +  IN  UINT8 SlaveAddress,
> +  IN  UINT8 Offset,
> +  IN  UINTN WriteBytes,
> +  IN  UINT8 *WriteBuffer
> +  )
> +{
> +  EFI_STATUS        Status;
> +
> +  DEBUG ((EFI_D_ERROR, "ByteWriteI2C:---
> offset/bytes/buf:0x%x,0x%x,0x%x,0x%x\n",Offset,WriteBytes,WriteBuffer,
> *WriteBuffer));
> +  Status = ByteWriteI2CBasic(I2cControllerIndex, SlaveAddress, 1, &Offset,
> TRUE, FALSE);
> +  Status = ByteWriteI2CBasic(I2cControllerIndex, SlaveAddress, WriteBytes,
> WriteBuffer, FALSE, TRUE);
> +
> +  return Status;
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.h
> new file mode 100644
> index 0000000000..47536aebf7
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.h
> @@ -0,0 +1,280 @@
> +/** @file
> +  I2C PEI Lib Instance.
> +
> +  Copyright (c) 1999- 2015, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef I2C_PEI_REGS_H
> +#define I2C_PEI_REGS_H
> +
> +#include "PiPei.h"
> +
> +#define R_PCH_LPC_PMC_BASE                        0x44
> +#define B_PCH_LPC_PMC_BASE_BAR                    0xFFFFFE00
> +#define R_PCH_PMC_FUNC_DIS                        0x34  // Function Disable
> Register
> +#define PCIEX_BASE_ADDRESS                        0xE0000000
> +#define PciD31F0RegBase                           PCIEX_BASE_ADDRESS + (UINT32)
> (31 << 15)
> +#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC7             BIT7  // LPSS SPI
> Disable
> +#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC6             BIT6  // LPSS HSUART
> #2 Disable
> +#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC5             BIT5  // LPSS HSUART
> #1 Disable
> +#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC4             BIT4  // LPSS I2S
> Disable
> +#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC3             BIT3  // LPSS PCM
> Disable
> +#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC2             BIT2  // LPSS I2C #2
> Disable
> +#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC1             BIT1  // LPSS I2C #1
> Disable
> +#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC0             BIT0  // LPSS DMA
> Disable
> +
> +
> +#define DEFAULT_PCI_BUS_NUMBER_PCH       0
> +
> +#define R_PCH_LPSS_I2C_STSCMD                     0x04  // Status & Command
> +#define B_PCH_LPSS_I2C_STSCMD_RMA                 BIT29 // RMA
> +#define B_PCH_LPSS_I2C_STSCMD_RCA                 BIT28 // RCA
> +#define B_PCH_LPSS_I2C_STSCMD_CAPLIST             BIT20 // Capability List
> +#define B_PCH_LPSS_I2C_STSCMD_INTRSTS             BIT19 // Interrupt Status
> +#define B_PCH_LPSS_I2C_STSCMD_INTRDIS             BIT10 // Interrupt
> Disable
> +#define B_PCH_LPSS_I2C_STSCMD_SERREN              BIT8  // SERR# Enable
> +#define B_PCH_LPSS_I2C_STSCMD_BME                 BIT2  // Bus Master Enable
> +#define B_PCH_LPSS_I2C_STSCMD_MSE                 BIT1  // Memory Space
> Enable
> +
> +#define R_PCH_LPSS_I2C_BAR                        0x10  // BAR
> +#define B_PCH_LPSS_I2C_BAR_BA                     0xFFFFF000 // Base Address
> +#define B_PCH_LPSS_I2C_BAR_SI                     0x00000FF0 // Size Indicator
> +#define B_PCH_LPSS_I2C_BAR_PF                     BIT3  // Prefetchable
> +#define B_PCH_LPSS_I2C_BAR_TYPE                   (BIT2 | BIT1) // Type
> +#define B_PCH_LPSS_I2C_BAR_MS                     BIT0  // Message Space
> +
> +#define R_PCH_LPSS_I2C_BAR1                       0x14  // BAR 1
> +#define B_PCH_LPSS_I2C_BAR1_BA                    0xFFFFF000 // Base Address
> +#define B_PCH_LPSS_I2C_BAR1_SI                    0x00000FF0 // Size Indicator
> +#define B_PCH_LPSS_I2C_BAR1_PF                    BIT3  // Prefetchable
> +#define B_PCH_LPSS_I2C_BAR1_TYPE                  (BIT2 | BIT1) // Type
> +#define B_PCH_LPSS_I2C_BAR1_MS                    BIT0  // Message Space
> +
> +#define NUM_RETRIES         0xFFFF
> +
> +//
> +// LPIO I2C Module Memory Space Registers
> +//
> +#define R_PCH_LPIO_I2C_MEM_RESETS                 0x804 // Software Reset
> +#define B_PCH_LPIO_I2C_MEM_RESETS_FUNC            BIT1  // Function Clock
> Domain Reset
> +#define B_PCH_LPIO_I2C_MEM_RESETS_APB             BIT0  // APB Domain
> Reset
> +
> +#define R_PCH_LPSS_I2C_MEM_PCP                    0x800 // Private Clock
> Parameters
> +
> +#define  bit(a)                   1 << (a)
> +
> +//
> +// MMIO Register Definitions
> +//
> +
> +#define  I2C0_REG_SPACE_ADDR_BASE            0xFF138000  //01K
> +
> +#define    R_IC_CON                          ( 0x00) // I2C Control
> +#define     B_IC_RESTART_EN                  BIT5
> +#define     B_IC_SLAVE_DISABLE               BIT6
> +#define     V_SPEED_STANDARD                 0x02
> +#define     V_SPEED_FAST                     0x04
> +#define     V_SPEED_HIGH                     0x06
> +#define     B_MASTER_MODE                    BIT0
> +
> +#define    R_IC_TAR                          ( 0x04) // I2C Target Address
> +#define     IC_TAR_10BITADDR_MASTER           BIT12
> +
> +#define    R_IC_SAR                          ( 0x08) // I2C Slave Address
> +#define    R_IC_HS_MADDR                     ( 0x0C) // I2C HS MasterMode Code
> Address
> +#define    R_IC_DATA_CMD                     ( 0x10) // I2C Rx/Tx Data Buffer and
> Command
> +
> +#define    B_READ_CMD                         BIT8    // 1 = read, 0 = write
> +#define    B_CMD_STOP                         BIT9    // 1 = STOP
> +#define    B_CMD_RESTART                      BIT10   // 1 = IC_RESTART_EN
> +
> +#define    V_WRITE_CMD_MASK                  ( 0xFF)
> +
> +#define    R_IC_SS_SCL_HCNT                  ( 0x14) // Standard Speed I2C Clock
> SCL High Count
> +#define    R_IC_SS_SCL_LCNT                  ( 0x18) // Standard Speed I2C Clock
> SCL Low Count
> +#define    R_IC_FS_SCL_HCNT                  ( 0x1C) // Full Speed I2C Clock SCL
> High Count
> +#define    R_IC_FS_SCL_LCNT                  ( 0x20) // Full Speed I2C Clock SCL
> Low Count
> +#define    R_IC_HS_SCL_HCNT                  ( 0x24) // High Speed I2C Clock SCL
> High Count
> +#define    R_IC_HS_SCL_LCNT                  ( 0x28) // High Speed I2C Clock SCL
> Low Count
> +#define    R_IC_INTR_STAT                    ( 0x2C) // I2C Inetrrupt Status
> +#define    R_IC_INTR_MASK                    ( 0x30) // I2C Interrupt Mask
> +#define     I2C_INTR_GEN_CALL                 BIT11  // General call received
> +#define     I2C_INTR_START_DET                BIT10
> +#define     I2C_INTR_STOP_DET                 BIT9
> +#define     I2C_INTR_ACTIVITY                 BIT8
> +#define     I2C_INTR_TX_ABRT                  BIT6   // Set on NACK
> +#define     I2C_INTR_TX_EMPTY                 BIT4
> +#define     I2C_INTR_TX_OVER                  BIT3
> +#define     I2C_INTR_RX_FULL                  BIT2   // Data bytes in RX FIFO over
> threshold
> +#define     I2C_INTR_RX_OVER                  BIT1
> +#define     I2C_INTR_RX_UNDER                 BIT0
> +#define    R_IC_RawIntrStat                ( 0x34) // I2C Raw Interrupt Status
> +#define    R_IC_RX_TL                        ( 0x38) // I2C Receive FIFO Threshold
> +#define    R_IC_TX_TL                        ( 0x3C) // I2C Transmit FIFO Threshold
> +#define    R_IC_CLR_INTR                     ( 0x40) // Clear Combined and Individual
> Interrupts
> +#define    R_IC_CLR_RX_UNDER                 ( 0x44) // Clear RX_UNDER
> Interrupt
> +#define    R_IC_CLR_RX_OVER                  ( 0x48) // Clear RX_OVERinterrupt
> +#define    R_IC_CLR_TX_OVER                  ( 0x4C) // Clear TX_OVER interrupt
> +#define    R_IC_CLR_RD_REQ                   ( 0x50) // Clear RD_REQ interrupt
> +#define    R_IC_CLR_TX_ABRT                  ( 0x54) // Clear TX_ABRT interrupt
> +#define    R_IC_CLR_RX_DONE                  ( 0x58) // Clear RX_DONE interrupt
> +#define    R_IC_CLR_ACTIVITY                 ( 0x5C) // Clear ACTIVITY interrupt
> +#define    R_IC_CLR_STOP_DET                 ( 0x60) // Clear STOP_DET interrupt
> +#define    R_IC_CLR_START_DET                ( 0x64) // Clear START_DET
> interrupt
> +#define    R_IC_CLR_GEN_CALL                 ( 0x68) // Clear GEN_CALL interrupt
> +#define    R_IC_ENABLE                       ( 0x6C) // I2C Enable
> +#define    R_IC_STATUS                       ( 0x70) // I2C Status
> +
> +#define    R_IC_SDA_HOLD                     ( 0x7C) // I2C
> IC_DEFAULT_SDA_HOLD//16bits
> +
> +#define     STAT_MST_ACTIVITY                 BIT5   // Master FSM Activity Status.
> +#define     STAT_RFF                          BIT4   // RX FIFO is completely full
> +#define     STAT_RFNE                         BIT3   // RX FIFO is not empty
> +#define     STAT_TFE                          BIT2   // TX FIFO is completely empty
> +#define     STAT_TFNF                         BIT1   // TX FIFO is not full
> +
> +#define    R_IC_TXFLR                        ( 0x74) // Transmit FIFO Level Register
> +#define    R_IC_RXFLR                        ( 0x78) // Receive FIFO Level Register
> +#define    R_IC_TX_ABRT_SOURCE               ( 0x80) // I2C Transmit Abort
> Status Register
> +#define    R_IC_SLV_DATA_NACK_ONLY           ( 0x84) // Generate
> SLV_DATA_NACK Register
> +#define    R_IC_DMA_CR                       ( 0x88) // DMA Control Register
> +#define    R_IC_DMA_TDLR                     ( 0x8C) // DMA Transmit Data Level
> +#define    R_IC_DMA_RDLR                     ( 0x90) // DMA Receive Data Level
> +#define    R_IC_SDA_SETUP                    ( 0x94) // I2C SDA Setup Register
> +#define    R_IC_ACK_GENERAL_CALL             ( 0x98) // I2C ACK General Call
> Register
> +#define    R_IC_ENABLE_STATUS                ( 0x9C) // I2C Enable Status
> Register
> +#define    R_IC_COMP_PARAM                   ( 0xF4) // Component Parameter
> Register
> +#define    R_IC_COMP_VERSION                 ( 0xF8) // Component Version ID
> +#define    R_IC_COMP_TYPE                    ( 0xFC) // Component Type
> +
> +#define I2C_SS_SCL_HCNT_VALUE_100M           0x1DD
> +#define I2C_SS_SCL_LCNT_VALUE_100M           0x1E4
> +#define I2C_FS_SCL_HCNT_VALUE_100M           0x54
> +#define I2C_FS_SCL_LCNT_VALUE_100M           0x9a
> +#define I2C_HS_SCL_HCNT_VALUE_100M           0x7
> +#define I2C_HS_SCL_LCNT_VALUE_100M           0xE
> +
> +//
> +// FIFO write workaround value.
> +//
> +#define     FIFO_WRITE_DELAY    2
> +#define     IC_TAR_10BITADDR_MASTER           BIT12
> +#define     FIFO_SIZE                         32
> +#define     R_IC_INTR_STAT                    ( 0x2C) // I2c Inetrrupt Status
> +#define     R_IC_INTR_MASK                    ( 0x30) // I2c Interrupt Mask
> +#define     I2C_INTR_GEN_CALL                 BIT11  // General call received
> +#define     I2C_INTR_START_DET                BIT10
> +#define     I2C_INTR_STOP_DET                 BIT9
> +#define     I2C_INTR_ACTIVITY                 BIT8
> +#define     I2C_INTR_TX_ABRT                  BIT6   // Set on NACK
> +#define     I2C_INTR_TX_EMPTY                 BIT4
> +#define     I2C_INTR_TX_OVER                  BIT3
> +#define     I2C_INTR_RX_FULL                  BIT2   // Data bytes in RX FIFO over
> threshold
> +#define     I2C_INTR_RX_OVER                  BIT1
> +#define     I2C_INTR_RX_UNDER                 BIT0
> +
> +/**
> +  Programe all I2C controllers on LPSS.
> +
> +  I2C0 is function 1 of LPSS. I2C1 is function 2 of LPSS, etc..
> +
> +  @param   VOID
> +
> +  @return  EFI_SUCCESS
> +**/
> +EFI_STATUS
> +ProgramPciLpssI2C (
> +  VOID
> +  );
> +
> +/**
> +  Reads a Byte from I2C Device.
> +
> +  @param  I2cControllerIndex  I2C Bus no to which the I2C device has been
> connected
> +  @param  SlaveAddress        Device Address from which the byte value has
> to be read
> +  @param  Offset              Offset from which the data has to be read
> +  @param  *Byte               Address to which the value read has to be stored
> +  @param  Start               Whether a RESTART is issued before the byte is sent
> or received
> +  @param  End                 Whether STOP is generated after a data byte is sent
> or received
> +
> +  @return  EFI_SUCCESS        If the byte value has been successfully read
> +  @return  EFI_DEVICE_ERROR   Operation Failed, Device Error
> +**/
> +EFI_STATUS
> +ByteReadI2CBasic(
> +  IN  UINT8 I2cControllerIndex,
> +  IN  UINT8 SlaveAddress,
> +  IN  UINTN ReadBytes,
> +  OUT UINT8 *ReadBuffer,
> +  IN  UINT8 Start,
> +  IN  UINT8 End
> +  );
> +
> +/**
> +  Writes a Byte to I2C Device.
> +
> +  @param  I2cControllerIndex   I2C Bus no to which the I2C device has been
> connected
> +  @param  SlaveAddress         Device Address from which the byte value has
> to be written
> +  @param  Offset               Offset from which the data has to be read
> +  @param  *Byte                Address to which the value written is stored
> +  @param  Start               Whether a RESTART is issued before the byte is sent
> or received
> +  @param  End                 Whether STOP is generated after a data byte is sent
> or received
> +
> +  @return  EFI_SUCCESS         IF the byte value has been successfully written
> +  @return  EFI_DEVICE_ERROR    Operation Failed, Device Error
> +**/
> +EFI_STATUS
> +ByteWriteI2CBasic(
> +  IN  UINT8 I2cControllerIndex,
> +  IN  UINT8 SlaveAddress,
> +  IN  UINTN WriteBytes,
> +  IN  UINT8 *WriteBuffer,
> +  IN  UINT8 Start,
> +  IN  UINT8 End
> +  );
> +
> +/**
> +  Reads a Byte from I2C Device.
> +
> +  @param  I2cControllerIndex   I2C Bus no to which the I2C device has been
> connected
> +  @param  SlaveAddress         Device Address from which the byte value has
> to be read
> +  @param  Offset               Offset from which the data has to be read
> +  @param  ReadBytes            Number of bytes to be read
> +  @param  *ReadBuffer          Address to which the value read has to be
> stored
> +
> +  @return  EFI_SUCCESS       IF the byte value has been successfully read
> +  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
> +**/
> +EFI_STATUS
> +ByteReadI2C(
> +  IN  UINT8 I2cControllerIndex,
> +  IN  UINT8 SlaveAddress,
> +  IN  UINT8 Offset,
> +  IN  UINTN ReadBytes,
> +  OUT UINT8 *ReadBuffer
> +  );
> +
> +/**
> +  Writes a Byte to I2C Device.
> +
> +  @param  I2cControllerIndex  I2C Bus no to which the I2C device has been
> connected
> +  @param  SlaveAddress        Device Address from which the byte value has
> to be written
> +  @param  Offset              Offset from which the data has to be written
> +  @param  WriteBytes          Number of bytes to be written
> +  @param  *Byte               Address to which the value written is stored
> +
> +  @return  EFI_SUCCESS       IF the byte value has been successfully read
> +  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
> +**/
> +EFI_STATUS
> +ByteWriteI2C(
> +  IN  UINT8 I2cControllerIndex,
> +  IN  UINT8 SlaveAddress,
> +  IN  UINT8 Offset,
> +  IN  UINTN WriteBytes,
> +  IN  UINT8 *WriteBuffer
> +  );
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.inf
> new file mode 100644
> index 0000000000..a78212a0e7
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.inf
> @@ -0,0 +1,40 @@
> +## @file
> +#  Instance of I2C Library.
> +#
> +#  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = I2CLibPei
> +  FILE_GUID                      = 8EF61509-890B-4FF2-B352-1C0E9CDDEC8B
> +  MODULE_TYPE                    = PEIM
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = LockBoxLib|PEIM
> +  CONSTRUCTOR                    = IntelI2CPeiLibConstructor
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +
> +[Sources.common]
> +  I2CLibPei.c
> +  I2CIoLibPei.c
> +
> +[LibraryClasses]
> +  TimerLib
> +
> +[PPIs]
> +  gEfiPeiStallPpiGuid
> +
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/CommonH
> eader.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/Common
> Header.h
> new file mode 100644
> index 0000000000..794c9178f1
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/Common
> Header.h
> @@ -0,0 +1,27 @@
> +/**@file
> +  Common header file shared by all source files.
> +
> +  This file includes package header files, library classes and protocol, PPI &
> GUID definitions.
> +
> +  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +**/
> +
> +#ifndef __COMMON_HEADER_H_
> +#define __COMMON_HEADER_H_
> +
> +
> +#include <Base.h>
> +#include <PchAccess.h>
> +
> +#include <Library/TimerLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/PcdLib.h>
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchA
> cpiTimerLib.c
> new file mode 100644
> index 0000000000..af44c6bd27
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchA
> cpiTimerLib.c
> @@ -0,0 +1,255 @@
> +/** @file
> +  ICH9 ACPI Timer implements one instance of Timer Library.
> +
> +Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +**/
> +
> +#include "CommonHeader.h"
> +
> +/**
> +  The constructor function enables ACPI IO space.
> +
> +  If ACPI I/O space not enabled, this function will enable it.
> +  It will always return RETURN_SUCCESS.
> +
> +  @retval EFI_SUCCESS   The constructor always returns RETURN_SUCCESS.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +IntelPchAcpiTimerLibConstructor (
> +  VOID
> +  )
> +{
> +  if ((PchLpcPciCfg8(R_PCH_LPC_ACPI_BASE) & B_PCH_LPC_ACPI_BASE_EN)
> == 0) {
> +  //
> +  // If ACPI I/O space is not enabled, program ACPI I/O base address and
> enable it.
> +  //
> +    MmioWrite16 (
> +      MmPciAddress (
> +        0,
> +        DEFAULT_PCI_BUS_NUMBER_PCH,
> +        PCI_DEVICE_NUMBER_PCH_LPC,
> +        PCI_FUNCTION_NUMBER_PCH_LPC,
> +        R_PCH_LPC_ACPI_BASE
> +        ),
> +      ((PcdGet16 (PcdPchAcpiIoPortBaseAddress) &
> B_PCH_LPC_ACPI_BASE_BAR) | B_PCH_LPC_ACPI_BASE_EN)
> +    );
> +  }
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Internal function to read the current tick counter of ACPI.
> +
> +  Internal function to read the current tick counter of ACPI.
> +
> +  @return The tick counter read.
> +
> +**/
> +STATIC
> +UINT32
> +InternalAcpiGetTimerTick (
> +  VOID
> +  )
> +{
> +  return IoRead32 (PcdGet16 (PcdPchAcpiIoPortBaseAddress) +
> R_PCH_ACPI_PM1_TMR);
> +}
> +
> +/**
> +  Stalls the CPU for at least the given number of ticks.
> +
> +  Stalls the CPU for at least the given number of ticks. It's invoked by
> +  MicroSecondDelay() and NanoSecondDelay().
> +
> +  @param  Delay     A period of time to delay in ticks.
> +
> +**/
> +STATIC
> +VOID
> +InternalAcpiDelay (
> +  IN      UINT32                    Delay
> +  )
> +{
> +  UINT32                            Ticks;
> +  UINT32                            Times;
> +
> +  Times    = Delay >> 22;
> +  Delay   &= BIT22 - 1;
> +  do {
> +    //
> +    // The target timer count is calculated here
> +    //
> +    Ticks    = InternalAcpiGetTimerTick () + Delay;
> +    Delay    = BIT22;
> +    //
> +    // Wait until time out
> +    // Delay >= 2^23 could not be handled by this function
> +    // Timer wrap-arounds are handled correctly by this function
> +    //
> +    while (((Ticks - InternalAcpiGetTimerTick ()) & BIT23) == 0) {
> +      CpuPause ();
> +    }
> +  } while (Times-- > 0);
> +}
> +
> +/**
> +  Stalls the CPU for at least the given number of microseconds.
> +
> +  Stalls the CPU for the number of microseconds specified by MicroSeconds.
> +
> +  @param  MicroSeconds  The minimum number of microseconds to delay.
> +
> +  @return MicroSeconds
> +
> +**/
> +UINTN
> +EFIAPI
> +MicroSecondDelay (
> +  IN      UINTN                     MicroSeconds
> +  )
> +{
> +  InternalAcpiDelay (
> +    (UINT32)DivU64x32 (
> +              MultU64x32 (
> +                MicroSeconds,
> +                V_PCH_ACPI_PM1_TMR_FREQUENCY
> +                ),
> +              1000000u
> +              )
> +    );
> +  return MicroSeconds;
> +}
> +
> +/**
> +  Stalls the CPU for at least the given number of nanoseconds.
> +
> +  Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
> +
> +  @param  NanoSeconds The minimum number of nanoseconds to delay.
> +
> +  @return NanoSeconds
> +
> +**/
> +UINTN
> +EFIAPI
> +NanoSecondDelay (
> +  IN      UINTN                     NanoSeconds
> +  )
> +{
> +  InternalAcpiDelay (
> +    (UINT32)DivU64x32 (
> +              MultU64x32 (
> +                NanoSeconds,
> +                V_PCH_ACPI_PM1_TMR_FREQUENCY
> +                ),
> +              1000000000u
> +              )
> +    );
> +  return NanoSeconds;
> +}
> +
> +/**
> +  Retrieves the current value of a 64-bit free running performance counter.
> +
> +  Retrieves the current value of a 64-bit free running performance counter.
> The
> +  counter can either count up by 1 or count down by 1. If the physical
> +  performance counter counts by a larger increment, then the counter
> values
> +  must be translated. The properties of the counter can be retrieved from
> +  GetPerformanceCounterProperties().
> +
> +  @return The current value of the free running performance counter.
> +
> +**/
> +UINT64
> +EFIAPI
> +GetPerformanceCounter (
> +  VOID
> +  )
> +{
> +  return (UINT64)InternalAcpiGetTimerTick ();
> +}
> +
> +/**
> +  Retrieves the 64-bit frequency in Hz and the range of performance counter
> +  values.
> +
> +  If StartValue is not NULL, then the value that the performance counter
> starts
> +  with immediately after is it rolls over is returned in StartValue. If
> +  EndValue is not NULL, then the value that the performance counter end
> with
> +  immediately before it rolls over is returned in EndValue. The 64-bit
> +  frequency of the performance counter in Hz is always returned. If
> StartValue
> +  is less than EndValue, then the performance counter counts up. If
> StartValue
> +  is greater than EndValue, then the performance counter counts down. For
> +  example, a 64-bit free running counter that counts up would have a
> StartValue
> +  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running
> counter
> +  that counts down would have a StartValue of 0xFFFFFF and an EndValue of
> 0.
> +
> +  @param  StartValue  The value the performance counter starts with when
> it
> +                      rolls over.
> +  @param  EndValue    The value that the performance counter ends with
> before
> +                      it rolls over.
> +
> +  @return             The frequency in Hz.
> +
> +**/
> +UINT64
> +EFIAPI
> +GetPerformanceCounterProperties (
> +  OUT      UINT64                    *StartValue,  OPTIONAL
> +  OUT      UINT64                    *EndValue     OPTIONAL
> +  )
> +{
> +  if (StartValue != NULL) {
> +    *StartValue = 0;
> +  }
> +
> +  if (EndValue != NULL) {
> +    *EndValue = V_PCH_ACPI_PM1_TMR_MAX_VAL - 1;
> +  }
> +
> +  return V_PCH_ACPI_PM1_TMR_FREQUENCY;
> +}
> +
> +/**
> +  Converts elapsed ticks of performance counter to time in nanoseconds.
> +
> +  This function converts the elapsed ticks of running performance counter to
> +  time value in unit of nanoseconds.
> +
> +  @param  Ticks     The number of elapsed ticks of running performance
> counter.
> +
> +  @return           The elapsed time in nanoseconds.
> +
> +**/
> +UINT64
> +EFIAPI
> +GetTimeInNanoSecond (
> +  IN      UINT64                     Ticks
> +  )
> +{
> +  UINT64  NanoSeconds;
> +  UINT32  Remainder;
> +
> +  //
> +  //          Ticks
> +  // Time = --------- x 1,000,000,000
> +  //        Frequency
> +  //
> +  NanoSeconds = MultU64x32 (DivU64x32Remainder (Ticks,
> V_PCH_ACPI_PM1_TMR_FREQUENCY, &Remainder), 1000000000u);
> +
> +  //
> +  // Frequency < 0x100000000, so Remainder < 0x100000000, then
> (Remainder * 1,000,000,000)
> +  // will not overflow 64-bit.
> +  //
> +  NanoSeconds += DivU64x32 (MultU64x32 ((UINT64) Remainder,
> 1000000000u), V_PCH_ACPI_PM1_TMR_FREQUENCY);
> +
> +  return NanoSeconds;
> +}
> +
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchA
> cpiTimerLib.inf
> new file mode 100644
> index 0000000000..f30d70e01f
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchA
> cpiTimerLib.inf
> @@ -0,0 +1,51 @@
> +#/** @file
> +# Intel ICH9 Acpi Timer Instance
> +#
> +# ICH9 Acpi timer implements one instance of Timer Library. Acpi timer
> cannot be programmed,
> +#  so it could be used by any types of drivers, including SMM drivers and
> Runtime drivers.
> +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +#
> +#
> +#
> +#**/
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = IntelPchAcpiTimerLib
> +  FILE_GUID                      = 0C0AC8C1-E368-4d20-85FE-23EFB3DB094E
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = TimerLib
> +  EDK_RELEASE_VERSION            = 0x00020000
> +  EFI_SPECIFICATION_VERSION      = 0x00020000
> +
> +  CONSTRUCTOR                    = IntelPchAcpiTimerLibConstructor
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +
> +[Sources.common]
> +  IntelPchAcpiTimerLib.c
> +  CommonHeader.h
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +
> +[LibraryClasses]
> +  PcdLib
> +  PciLib
> +  IoLib
> +  BaseLib
> +
> +[Pcd.common]
> +  gEfiPchTokenSpaceGuid.PcdPchAcpiIoPortBaseAddress
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens
> /BoardClkGens.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens
> /BoardClkGens.c
> new file mode 100644
> index 0000000000..919032c2df
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens
> /BoardClkGens.c
> @@ -0,0 +1,430 @@
> +/** @file
> +  Clock generator setting for multiplatform.
> +
> +  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +**/
> +
> +#include <BoardClkGens.h>
> +#include <Guid/SetupVariable.h>
> +#include <Ppi/ReadOnlyVariable2.h>
> +#include <Library/BaseMemoryLib.h>
> +
> +#ifndef __GNUC__
> +#pragma optimize( "", off )
> +#endif
> +
> +#define CLKGEN_EN 1
> +#define EFI_DEBUG 1
> +
> +CLOCK_GENERATOR_DETAILS   mSupportedClockGeneratorTable[] =
> +{
> +  { ClockGeneratorCk410, CK410_GENERATOR_ID ,
> CK410_GENERATOR_SPREAD_SPECTRUM_BYTE,
> CK410_GENERATOR_SPREAD_SPECTRUM_BIT },
> +  { ClockGeneratorCk505, CK505_GENERATOR_ID ,
> CK505_GENERATOR_SPREAD_SPECTRUM_BYTE,
> CK505_GENERATOR_SPREAD_SPECTRUM_BIT }
> +};
> +
> +/**
> +  Configure the clock generator using the SMBUS PPI services.
> +
> +  This function performs a block write, and dumps debug information.
> +
> +  @param  PeiServices                General purpose services available to every
> PEIM.
> +  @param  ClockType                  Clock generator's model name.
> +  @param  ClockAddress               SMBUS address of clock generator.
> +  @param  ConfigurationTableLength   Length of configuration table.
> +  @param  ConfigurationTable         Pointer of configuration table.
> +
> +  @retval EFI_SUCCESS - Operation success.
> +
> +**/
> +EFI_STATUS
> +ConfigureClockGenerator (
> +  IN     EFI_PEI_SERVICES              **PeiServices,
> +  IN     EFI_PEI_SMBUS_PPI                 *SmbusPpi,
> +  IN     CLOCK_GENERATOR_TYPE          ClockType,
> +  IN     UINT8                         ClockAddress,
> +  IN     UINTN                         ConfigurationTableLength,
> +  IN OUT UINT8                         *ConfigurationTable
> +  )
> +{
> +
> +  EFI_STATUS                    Status;
> +  EFI_SMBUS_DEVICE_ADDRESS      SlaveAddress;
> +  UINT8                         Buffer[MAX_CLOCK_GENERATOR_BUFFER_LENGTH];
> +  UINTN                         Length;
> +  EFI_SMBUS_DEVICE_COMMAND      Command;
> +#if CLKGEN_CONFIG_EXTRA
> +  UINT8                         j;
> +#endif
> +
> +  //
> +  // Verify input arguments
> +  //
> +  ASSERT (ConfigurationTableLength >= 6);
> +  ASSERT (ConfigurationTableLength <=
> MAX_CLOCK_GENERATOR_BUFFER_LENGTH);
> +  ASSERT (ClockType < ClockGeneratorMax);
> +  ASSERT (ConfigurationTable != NULL);
> +
> +  //
> +  // Read the clock generator
> +  //
> +  SlaveAddress.SmbusDeviceAddress = ClockAddress >> 1;
> +  Length = sizeof (Buffer);
> +  Command = 0;
> +  Status = SmbusPpi->Execute (
> +    PeiServices,
> +    SmbusPpi,
> +    SlaveAddress,
> +    Command,
> +    EfiSmbusReadBlock,
> +    FALSE,
> +    &Length,
> +    Buffer
> +    );
> +  ASSERT_EFI_ERROR (Status);
> +
> +#ifdef EFI_DEBUG
> +  {
> +    UINT8 i;
> +    for (i = 0; i < sizeof (Buffer); i++) {
> +      DEBUG((EFI_D_ERROR, "CK505 default Clock Generator Byte %d: %x\n",
> i, Buffer[i]));
> +    }
> +#if CLKGEN_EN
> +    for (i = 0; i < ConfigurationTableLength; i++) {
> +      DEBUG((EFI_D_ERROR, "BIOS structure Clock Generator Byte %d: %x\n",
> i, ConfigurationTable[i]));
> +    }
> +#endif
> +  }
> +#endif
> +
> +  DEBUG((EFI_D_ERROR, "Expected Clock Generator ID is %x,
> expecting %x\n",
> mSupportedClockGeneratorTable[ClockType].ClockId,(Buffer[7]&0xF)));
> +
> +  //
> +  // Program clock generator
> +  //
> +  Command = 0;
> +#if CLKGEN_EN
> +#if CLKGEN_CONFIG_EXTRA
> +  for (j = 0; j < ConfigurationTableLength; j++) {
> +    Buffer[j] = ConfigurationTable[j];
> +  }
> +
> +  Buffer[30] = 0x00;
> +
> +  Status = SmbusPpi->Execute (
> +    PeiServices,
> +    SmbusPpi,
> +    SlaveAddress,
> +    Command,
> +    EfiSmbusWriteBlock,
> +    FALSE,
> +    &Length,
> +    Buffer
> +    );
> +#else
> +  Status = SmbusPpi->Execute (
> +    PeiServices,
> +    SmbusPpi,
> +    SlaveAddress,
> +    Command,
> +    EfiSmbusWriteBlock,
> +    FALSE,
> +    &ConfigurationTableLength,
> +    ConfigurationTable
> +    );
> +#endif // CLKGEN_CONFIG_EXTRA
> +#else
> +    ConfigurationTable[4] = (ConfigurationTable[4] & 0x3) | (Buffer[4] &
> 0xFC);
> +    Command = 4;
> +    Length = 1;
> +  Status = SmbusPpi->Execute (
> +    PeiServices,
> +    SmbusPpi,
> +    SlaveAddress,
> +    Command,
> +    EfiSmbusWriteBlock,
> +    FALSE,
> +    &Length,
> +    &ConfigurationTable[4]
> +    );
> +#endif //CLKGEN_EN
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Dump contents after write
> +  //
> +  #ifdef EFI_DEBUG
> +    {
> +      UINT8   i;
> +    SlaveAddress.SmbusDeviceAddress = ClockAddress >> 1;
> +    Length = sizeof (Buffer);
> +      Command = 0;
> +      Status =  SmbusPpi->Execute (
> +        PeiServices,
> +        SmbusPpi,
> +        SlaveAddress,
> +        Command,
> +        EfiSmbusReadBlock,
> +        FALSE,
> +        &Length,
> +        Buffer
> +        );
> +
> +      for (i = 0; i < ConfigurationTableLength; i++) {
> +        DEBUG((EFI_D_ERROR, "Clock Generator Byte %d: %x\n", i, Buffer[i]));
> +      }
> +    }
> +    #endif
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Configure the clock generator using the SMBUS PPI services.
> +
> +  This function performs a block write, and dumps debug information.
> +
> +  @param  PeiServices                General purpose services available to every
> PEIM.
> +  @param  ClockType                  Clock generator's model name.
> +  @param  ClockAddress               SMBUS address of clock generator.
> +  @param  ConfigurationTableLength   Length of configuration table.
> +  @param  ConfigurationTable         Pointer of configuration table.
> +
> +
> +  @retval  EFI_SUCCESS  Operation success.
> +
> +**/
> +UINT8
> +ReadClockGeneratorID (
> +  IN     EFI_PEI_SERVICES              **PeiServices,
> +  IN     EFI_PEI_SMBUS_PPI                 *SmbusPpi,
> +  IN     UINT8                         ClockAddress
> +  )
> +{
> +  EFI_SMBUS_DEVICE_ADDRESS      SlaveAddress;
> +  UINT8                         Buffer[MAX_CLOCK_GENERATOR_BUFFER_LENGTH];
> +  UINTN                         Length;
> +  EFI_SMBUS_DEVICE_COMMAND      Command;
> +
> +  //
> +  // Read the clock generator
> +  //
> +  SlaveAddress.SmbusDeviceAddress = ClockAddress >> 1;
> +  Length = sizeof (Buffer);
> +  Command = 0;
> +  SmbusPpi->Execute (
> +    PeiServices,
> +    SmbusPpi,
> +    SlaveAddress,
> +    Command,
> +    EfiSmbusReadBlock,
> +    FALSE,
> +    &Length,
> +    Buffer
> +    );
> +
> +  //
> +  // Sanity check that the requested clock type is present in our supported
> clocks table
> +  //
> +  DEBUG((EFI_D_ERROR, "Expected Clock Generator ID is 0x%x\n",
> Buffer[7]));
> +
> +  return (Buffer[7]);
> +}
> +
> +/**
> +  Configure the clock generator to enable free-running operation.  This
> keeps
> +  the clocks from being stopped when the system enters C3 or C4.
> +
> +  @param None
> +
> +  @retval EFI_SUCCESS    The function completed successfully.
> +
> +**/
> +EFI_STATUS
> +ConfigurePlatformClocks (
> +  IN EFI_PEI_SERVICES           **PeiServices,
> +  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
> +  IN VOID                       *SmbusPpi
> +  )
> +{
> +  //
> +  // Comment it out for now
> +  // Not supported by Hybrid model.
> +  //
> +  EFI_STATUS                    Status;
> +  UINT8                         *ConfigurationTable;
> +
> +  CLOCK_GENERATOR_TYPE          ClockType = ClockGeneratorCk505;
> +  UINT8                         ConfigurationTable_Desktop[] =
> CLOCK_GENERATOR_SETTINGS_DESKTOP;
> +  UINT8                         ConfigurationTable_Mobile[] =
> CLOCK_GENERATOR_SETTINGS_MOBILE;
> +  UINT8                         ConfigurationTable_Tablet[] =
> CLOCK_GENERATOR_SEETINGS_TABLET;
> +
> +  EFI_PLATFORM_INFO_HOB         *PlatformInfoHob;
> +  BOOLEAN                       EnableSpreadSpectrum;
> +  SYSTEM_CONFIGURATION          SystemConfiguration;
> +
> +  UINTN                         Length;
> +  EFI_SMBUS_DEVICE_COMMAND      Command;
> +  EFI_SMBUS_DEVICE_ADDRESS      SlaveAddress;
> +  UINT8                         Data;
> +
> +  UINT8                         ClockAddress = CLOCK_GENERATOR_ADDRESS;
> +  UINTN                         VariableSize;
> +  EFI_PEI_READ_ONLY_VARIABLE2_PPI   *Variable;
> +
> +  //
> +  // Obtain Platform Info from HOB.
> +  //
> +  Status = GetPlatformInfoHob ((CONST EFI_PEI_SERVICES **) PeiServices,
> &PlatformInfoHob);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  DEBUG((EFI_D_ERROR, "PlatformInfo protocol is working in
> ConfigurePlatformClocks()...%x\n",PlatformInfoHob->PlatformFlavor));
> +
> +  //
> +  // Locate SMBUS PPI
> +  //
> +  Status = (**PeiServices).LocatePpi (
> +                             (CONST EFI_PEI_SERVICES **) PeiServices,
> +                             &gEfiPeiSmbusPpiGuid,
> +                             0,
> +                             NULL,
> +                             &SmbusPpi
> +                             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Data  = 0;
> +  SlaveAddress.SmbusDeviceAddress = ClockAddress >> 1;
> +  Length = 1;
> +  Command = 0x87;   //Control Register 7 Vendor ID Check
> +  Status = ((EFI_PEI_SMBUS_PPI *) SmbusPpi)->Execute (
> +                                               PeiServices,
> +                                               SmbusPpi,
> +                                               SlaveAddress,
> +                                               Command,
> +                                               EfiSmbusReadByte,
> +                                               FALSE,
> +                                               &Length,
> +                                               &Data
> +                                               );
> +
> +  if (EFI_ERROR (Status) || ((Data & 0x0F) != CK505_GENERATOR_ID)) {
> +      DEBUG((EFI_D_ERROR, "Clock Generator CK505 Not Present, vendor ID
> on board is %x\n",(Data & 0x0F)));
> +      return EFI_SUCCESS;
> +}
> +
> +  EnableSpreadSpectrum = FALSE;
> +  VariableSize = sizeof (SYSTEM_CONFIGURATION);
> +  ZeroMem (&SystemConfiguration, sizeof (SYSTEM_CONFIGURATION));
> +
> +  Status = (*PeiServices)->LocatePpi (
> +                             (CONST EFI_PEI_SERVICES **) PeiServices,
> +                             &gEfiPeiReadOnlyVariable2PpiGuid,
> +                             0,
> +                             NULL,
> +                             (VOID **) &Variable
> +                             );
> +  //
> +  // Use normal setup default from NVRAM variable,
> +  // the Platform Mode (manufacturing/safe/normal) is handle in
> PeiGetVariable.
> +  //
> +  VariableSize = sizeof(SYSTEM_CONFIGURATION);
> +  Status = Variable->GetVariable (Variable,
> +                                   L"Setup",
> +                                   &gEfiSetupVariableGuid,
> +                                   NULL,
> +                                   &VariableSize,
> +                                   &SystemConfiguration);
> +  if (EFI_ERROR (Status) || VariableSize != sizeof(SYSTEM_CONFIGURATION))
> {
> +    //The setup variable is corrupted
> +    VariableSize = sizeof(SYSTEM_CONFIGURATION);
> +    Status = Variable->GetVariable(Variable,
> +              L"SetupRecovery",
> +              &gEfiSetupVariableGuid,
> +              NULL,
> +              &VariableSize,
> +              &SystemConfiguration
> +              );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +  if(!EFI_ERROR (Status)){
> +    EnableSpreadSpectrum = SystemConfiguration.EnableClockSpreadSpec;
> +  }
> +
> +  //
> +  // Perform platform-specific intialization dependent upon Board ID:
> +  //
> +  DEBUG((EFI_D_ERROR, "board id is %x, platform id
> is %x\n",PlatformInfoHob->BoardId,PlatformInfoHob->PlatformFlavor));
> +
> +
> +  switch (PlatformInfoHob->BoardId) {
> +    case BOARD_ID_MINNOW2:
> +    case BOARD_ID_MINNOW2_TURBOT:
> +    default:
> +      switch(PlatformInfoHob->PlatformFlavor) {
> +      case FlavorTablet:
> +        ConfigurationTable = ConfigurationTable_Tablet;
> +        Length = sizeof (ConfigurationTable_Tablet);
> +        break;
> +      case FlavorMobile:
> +        ConfigurationTable = ConfigurationTable_Mobile;
> +        Length = sizeof (ConfigurationTable_Mobile);
> +        break;
> +      case FlavorDesktop:
> +      default:
> +        ConfigurationTable = ConfigurationTable_Desktop;
> +        Length = sizeof (ConfigurationTable_Desktop);
> +        break;
> +      }
> +    break;
> +    }
> +
> +  //
> +  // Perform common clock initialization:
> +  //
> +  // Program Spread Spectrum function.
> +  //
> +  if (EnableSpreadSpectrum)
> +  {
> +
> ConfigurationTable[mSupportedClockGeneratorTable[ClockType].SpreadSpe
> ctrumByteOffset] |=
> mSupportedClockGeneratorTable[ClockType].SpreadSpectrumBitOffset;
> +  } else {
> +
> ConfigurationTable[mSupportedClockGeneratorTable[ClockType].SpreadSpe
> ctrumByteOffset] &=
> ~(mSupportedClockGeneratorTable[ClockType].SpreadSpectrumBitOffset);
> +  }
> +
> +
> +#if CLKGEN_EN
> +  Status = ConfigureClockGenerator (PeiServices, SmbusPpi, ClockType,
> ClockAddress, Length, ConfigurationTable);
> +  ASSERT_EFI_ERROR (Status);
> +#endif // CLKGEN_EN
> +  return EFI_SUCCESS;
> +}
> +
> +static EFI_PEI_NOTIFY_DESCRIPTOR    mNotifyList[] = {
> +  {
> +    EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK|
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
> +    &gEfiPeiSmbusPpiGuid,
> +    ConfigurePlatformClocks
> +  }
> +};
> +
> +EFI_STATUS
> +InstallPlatformClocksNotify (
> +  IN CONST EFI_PEI_SERVICES           **PeiServices
> +  )
> +{
> +  EFI_STATUS                    Status;
> +
> +  DEBUG ((EFI_D_INFO, "InstallPlatformClocksNotify()...\n"));
> +
> +  Status = (*PeiServices)->NotifyPpi(PeiServices, &mNotifyList[0]);
> +  ASSERT_EFI_ERROR (Status);
> +  return EFI_SUCCESS;
> +
> +}
> +
> +#ifndef __GNUC__
> +#pragma optimize( "", on )
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens
> /BoardClkGens.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens
> /BoardClkGens.h
> new file mode 100644
> index 0000000000..e153933d72
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens
> /BoardClkGens.h
> @@ -0,0 +1,255 @@
> +/**@file
> +  Clock generator setting for multiplatform.
> +
> +  This file includes package header files, library classes.
> +
> +  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +**/
> +
> +#ifndef _BOARD_CLK_GEN_H_
> +#define _BOARD_CLK_GEN_H_
> +
> +#include <PiPei.h>
> +#include <Library/HobLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/SmbusLib.h>
> +#include <Ppi/Smbus.h>
> +#include <IndustryStandard/SmBus.h>
> +#include <Guid/PlatformInfo.h>
> +
> +
> +#define CLOCK_GENERATOR_ADDRESS  0xd2
> +
> +#define CLOCK_GENERATOR_SEETINGS_TABLET {0xB1, 0x82, 0xFF, 0xBF,
> 0xFF, 0x80}
> +#define CLOCK_GENERATOR_SETTINGS_MOBILE {0xB1, 0x82, 0xFF, 0xBF,
> 0xFF, 0x80}
> +#define CLOCK_GENERATOR_SETTINGS_DESKTOP {0xB1, 0x82, 0xFF, 0xBF,
> 0xFF, 0x80}
> +
> +typedef enum {
> +  ClockGeneratorCk410,
> +  ClockGeneratorCk505,
> +  ClockGeneratorMax
> +} CLOCK_GENERATOR_TYPE;
> +
> +typedef struct {
> +  CLOCK_GENERATOR_TYPE      ClockType;
> +  UINT8                     ClockId;
> +  UINT8                     SpreadSpectrumByteOffset;
> +  UINT8                     SpreadSpectrumBitOffset;
> +} CLOCK_GENERATOR_DETAILS;
> +
> +#define MAX_CLOCK_GENERATOR_BUFFER_LENGTH           0x20
> +
> +//
> +// CK410 Definitions
> +//
> +#define CK410_GENERATOR_ID                          0x65
> +#define CK410_GENERATOR_SPREAD_SPECTRUM_BYTE        1
> +#define CK410_GENERATOR_SPREAD_SPECTRUM_BIT         BIT0
> +#define CK410_GENERATOR_CLOCK_FREERUN_BYTE          4
> +#define CK410_GENERATOR_CLOCK_FREERUN_BIT           (BIT0 | BIT1 | BIT2)
> +
> +//
> +// CK505 Definitions
> +//
> +#define VF_CK505_GENERATOR_ID                       0x5
> +#define CK505_GENERATOR_ID                          0x5  // Confirmed readout is 5
> +#define CK505_GENERATOR_SPREAD_SPECTRUM_BYTE        4
> +#define CK505_GENERATOR_SPREAD_SPECTRUM_BIT         (BIT0 | BIT1)
> +#define CK505_GENERATOR_PERCENT_SPREAD_BYTE      1
> +#define CK505_GENERATOR_PERCENT_MASK        ~(0xE)
> +#define CK505_GENERATOR_PERCENT_250_VALUE      0xC
> +#define CK505_GENERATOR_PERCENT_050_VALUE      0x4
> +#define CK505_GENERATOR_PERCENT_000_VALUE      0x2
> +
> +//
> +// IDT Definitions
> +//
> +#define IDT_GENERATOR_ID_REVA                       0x1    //IDT Rev A
> +#define IDTRevA_GENERATOR_SPREAD_SPECTRUM_BYTE        0
> +#define IDTRevA_GENERATOR_SPREAD_SPECTRUM_BIT       BIT0
> +#define IDTRevA_GENERATOR_PERCENT_SPREAD_BYTE      5
> +#define IDTRevA_GENERATOR_PERCENT_250_VALUE      0xF
> +#define IDTRevA_GENERATOR_PERCENT_050_VALUE      0x3
> +#define IDTRevA_GENERATOR_PERCENT_000_VALUE      0xE
> +#define IDTRevA_GENERATOR_PERCENT_MASK        ~(0xF)
> +
> +#define IDT_GENERATOR_ID_REVB                       0x11  //IDT RevB
> +#define IDT_GENERATOR_ID_REVD                       0x21  //IDT RevD
> +
> +//
> +// CLOCK CONTROLLER
> +// SmBus address to read DIMM SPD
> +//
> +#define SMBUS_BASE_ADDRESS                  0xEFA0
> +#define SMBUS_BUS_DEV_FUNC                  0x1F0300
> +#define PLATFORM_NUM_SMBUS_RSVD_ADDRESSES   4
> +#define SMBUS_ADDR_CH_A_1                   0xA0
> +#define SMBUS_ADDR_CH_A_2                   0xA2
> +#define SMBUS_ADDR_CH_B_1                   0xA4
> +#define SMBUS_ADDR_CH_B_2                   0xA6
> +
> +//
> +// Bits for FWH_DEC_EN1�Firmware Hub Decode Enable Register (LPC
> I/F�D31:F0)
> +//
> +#define   B_ICH_LPC_FWH_BIOS_DEC_F0             0x4000
> +#define   B_ICH_LPC_FWH_BIOS_DEC_E0             0x1000
> +#define   B_ICH_LPC_FWH_BIOS_DEC_E8             0x2000
> +#define   B_ICH_LPC_FWH_BIOS_LEG_F              0x0080
> +#define   B_ICH_LPC_FWH_BIOS_LEG_E              0x0040
> +
> +
> +//
> +// An arbitrary maximum length for clock generator buffers
> +//
> +#define MAX_CLOCK_GENERATOR_BUFFER_LENGTH           0x20
> +
> +//
> +// SmBus Bus Device Function and Register Definitions
> +//
> +#define SMBUS_BUS_NUM          0
> +#define SMBUS_DEV_NUM          31
> +#define SMBUS_FUNC_NUM          3
> +#define SMBUS_BUS_DEV_FUNC_NUM    \
> +      SB_PCI_CFG_ADDRESS(SMBUS_BUS_NUM, SMBUS_DEV_NUM,
> SMBUS_FUNC_NUM, 0)
> +
> +//
> +//ICH7: SMBus I/O Space Equates;
> +//
> +#define  BIT_SLAVE_ADDR    BIT00
> +#define  BIT_COMMAND      BIT01
> +#define  BIT_DATA      BIT02
> +#define  BIT_COUNT      BIT03
> +#define  BIT_WORD      BIT04
> +#define  BIT_CONTROL      BIT05
> +#define  BIT_PEC        BIT06
> +#define  BIT_READ      BIT07
> +#define  SMBUS_IO_READ_BIT  BIT00
> +
> +
> +#define  SMB_CMD_QUICK      0x00
> +#define  SMB_CMD_BYTE      0x04
> +#define  SMB_CMD_BYTE_DATA    0x08
> +#define  SMB_CMD_WORD_DATA    0x0C
> +#define  SMB_CMD_PROCESS_CALL  0x10
> +#define  SMB_CMD_BLOCK      0x14
> +#define  SMB_CMD_I2C_READ    0x18
> +#define  SMB_CMD_RESERVED    0x1c
> +
> +#define  HST_STS_BYTE_DONE 0x80
> +#define SMB_HST_STS    0x000
> +#define SMB_HST_CNT    0x002
> +#define SMB_HST_CMD    0x003
> +#define SMB_HST_ADD    0x004
> +#define SMB_HST_DAT_0    0x005
> +#define SMB_HST_DAT_1    0x006
> +#define SMB_HST_BLK_DAT   0x007
> +#define SMB_PEC     0x008
> +#define SMB_RCV_SLVA    0x009
> +#define SMB_SLV_DAT    0x00A
> +#define SMB_AUX_STS    0x00C
> +#define SMB_AUX_CTL    0x00D
> +#define SMB_SMLINK_PIN_CTL  0x00E
> +#define SMB_SMBUS_PIN_CTL  0x00F
> +#define SMB_SLV_STS    0x010
> +#define SMB_SLV_CMD    0x011
> +#define SMB_NTFY_DADDR    0x014
> +#define SMB_NTFY_DLOW    0x016
> +#define SMB_NTFY_DHIGH    0x017
> +
> +//
> +// PCI Register Definitions - use SmbusPolicyPpi->PciAddress + offset listed
> below
> +//
> +#define R_COMMAND                     0x04      // PCI Command Register, 16bit
> +#define   B_IOSE                        0x01    // RW
> +#define R_BASE_ADDRESS                0x20      // PCI BAR for SMBus I/O
> +#define   B_BASE_ADDRESS                0xFFE0  // RW
> +#define R_HOST_CONFIGURATION          0x40      // SMBus Host
> Configuration Register
> +#define   B_HST_EN                      0x01    // RW
> +#define   B_SMB_SMI_EN                  0x02    // RW
> +#define   B_I2C_EN                      0x04    // RW
> +//
> +// I/O Register Definitions - use SmbusPolicyPpi->BaseAddress + offset
> listed below
> +//
> +#define HOST_STATUS_REGISTER      0x00  // Host Status Register R/W
> +#define    HST_STS_HOST_BUSY                  0x01  // RO
> +#define   HST_STS_INTR                  0x02  // R/WC
> +#define   HST_STS_DEV_ERR                  0x04  // R/WC
> +#define   HST_STS_BUS_ERR                  0x08  // R/WC
> +#define   HST_STS_FAILED                  0x10  // R/WC
> +#define   SMBUS_B_SMBALERT_STS          0x20  // R/WC
> +#define   HST_STS_INUSE                   0x40  // R/WC
> +#define   SMBUS_B_BYTE_DONE_STS         0x80  // R/WC
> +#define   SMBUS_B_HSTS_ALL              0xFF  // R/WC
> +#define  HOST_CONTROL_REGISTER                  0x02  // Host Control Register
> R/W
> +#define    HST_CNT_INTREN                0x01  // RW
> +#define   HST_CNT_KILL                  0x02  // RW
> +#define   SMBUS_B_SMB_CMD               0x1C  // RW
> +#define     SMBUS_V_SMB_CMD_QUICK         0x00
> +#define     SMBUS_V_SMB_CMD_BYTE          0x04
> +#define     SMBUS_V_SMB_CMD_BYTE_DATA     0x08
> +#define     SMBUS_V_SMB_CMD_WORD_DATA     0x0C
> +#define     SMBUS_V_SMB_CMD_PROCESS_CALL  0x10
> +#define     SMBUS_V_SMB_CMD_BLOCK         0x14
> +#define     SMBUS_V_SMB_CMD_IIC_READ      0x18
> +#define   SMBUS_B_LAST_BYTE             0x20  // WO
> +#define   HST_CNT_START                 0x40  // WO
> +#define   HST_CNT_PEC_EN                0x80  // RW
> +#define  HOST_COMMAND_REGISTER                  0x03  // Host Command
> Register R/W
> +#define  XMIT_SLAVE_ADDRESS_REGISTER                   0x04  // Transmit Slave
> Address Register R/W
> +#define   SMBUS_B_RW_SEL                0x01  // RW
> +#define   SMBUS_B_ADDRESS               0xFE  // RW
> +#define  HOST_DATA_0_REGISTER                   0x05  // Data 0 Register R/W
> +#define  HOST_DATA_1_REGISTER                   0x06  // Data 1 Register R/W
> +#define  HOST_BLOCK_DATA_BYTE_REGISTER          0x07  // Host Block Data
> Register R/W
> +#define SMBUS_R_PEC                   0x08  // Packet Error Check Data Register
> R/W
> +#define SMBUS_R_RSA                   0x09  // Receive Slave Address Register
> R/W
> +#define   SMBUS_B_SLAVE_ADDR            0x7F  // RW
> +#define SMBUS_R_SD                    0x0A  // Receive Slave Data Register R/W
> +#define SMBUS_R_AUXS                  0x0C  // Auxiliary Status Register R/WC
> +#define   SMBUS_B_CRCE                  0x01  //R/WC
> +#define AUXILIARY_CONTROL_REGISTER                  0x0D  // Auxiliary Control
> Register R/W
> +#define   SMBUS_B_AAC                  0x01  //R/W
> +#define   SMBUS_B_E32B                 0x02  //R/W
> +#define  SMBUS_R_SMLC                  0x0E  // SMLINK Pin Control Register R/W
> +#define   SMBUS_B_SMLINK0_CUR_STS       0x01  // RO
> +#define   SMBUS_B_SMLINK1_CUR_STS       0x02  // RO
> +#define   SMBUS_B_SMLINK_CLK_CTL        0x04  // RW
> +#define SMBUS_R_SMBC                  0x0F  // SMBus Pin Control Register R/W
> +#define   SMBUS_B_SMBCLK_CUR_STS        0x01  // RO
> +#define   SMBUS_B_SMBDATA_CUR_STS       0x02  // RO
> +#define   SMBUS_B_SMBCLK_CTL            0x04  // RW
> +#define SMBUS_R_SSTS                  0x10  // Slave Status Register R/WC
> +#define   SMBUS_B_HOST_NOTIFY_STS       0x01  // R/WC
> +#define SMBUS_R_SCMD                  0x11  // Slave Command Register R/W
> +#define   SMBUS_B_HOST_NOTIFY_INTREN    0x01  // R/W
> +#define   SMBUS_B_HOST_NOTIFY_WKEN      0x02  // R/W
> +#define   SMBUS_B_SMBALERT_DIS          0x04  // R/W
> +#define SMBUS_R_NDA                   0x14  // Notify Device Address Register
> RO
> +#define   SMBUS_B_DEVICE_ADDRESS        0xFE  // RO
> +#define SMBUS_R_NDLB                  0x16  // Notify Data Low Byte Register RO
> +#define SMBUS_R_NDHB                  0x17  // Notify Data High Byte Register
> RO
> +#define BUS_TRIES           3       // How many times to retry on Bus Errors
> +#define SMBUS_NUM_RESERVED  21      // Number of device addresses
> that are
> +                                    //   reserved by the SMBus spec.
> +#define SMBUS_ADDRESS_ARP   0xC2 >> 1
> +#define   SMBUS_DATA_PREPARE_TO_ARP   0x01
> +#define   SMBUS_DATA_RESET_DEVICE     0x02
> +#define   SMBUS_DATA_GET_UDID_GENERAL 0x03
> +#define   SMBUS_DATA_ASSIGN_ADDRESS   0x04
> +#define SMBUS_GET_UDID_LENGTH 17    // 16 byte UDID + 1 byte address
> +
> +
> +EFI_STATUS
> +ConfigurePlatformClocks (
> +  IN EFI_PEI_SERVICES           **PeiServices,
> +  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
> +  IN VOID                       *SmbusPpi
> +  );
> +
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/B
> oardGpios.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/B
> oardGpios.c
> new file mode 100644
> index 0000000000..5790d045fc
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/B
> oardGpios.c
> @@ -0,0 +1,531 @@
> +/** @file
> +  Gpio setting for multiplatform..
> +
> +  Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +**/
> +
> +#include <BoardGpios.h>
> +#include <Guid/SetupVariable.h>
> +
> +//
> +//AlpineValley platform ocde begin
> +//
> +#define AV_SC_REG_GPIOS_MUXES_SEL0 0x48
> +#define AV_SC_REG_GPIOS_MUXES_SEL1 0x4C
> +#define AV_SC_REG_GPIOS_MUXES_SEL2 0x50
> +#define AV_SC_REG_GPIOS_MUXES_EN0  0x54
> +#define AV_SC_REG_GPIOS_MUXES_EN1  0x58
> +#define AV_SC_REG_GPIOS_MUXES_EN2  0x5C
> +//
> +//AlpineValley platform code end
> +//
> +
> +EFI_GUID  gPeiSmbusPpiGuid               = EFI_PEI_SMBUS_PPI_GUID;
> +
> +/**
> +  @param None
> +
> +  @retval EFI_SUCCESS    The function completed successfully.
> +
> +**/
> +EFI_STATUS
> +ConfigurePlatformSysCtrlGpio (
> +  IN EFI_PEI_SERVICES                   **PeiServices,
> +  IN EFI_PEI_NOTIFY_DESCRIPTOR          *NotifyDescriptor,
> +  IN VOID                               *SmbusPpi
> +  )
> +{
> +  //
> +  //AlpineValley platform code begin
> +  //
> +  // Initialize GPIO Settings:
> +  //
> +  UINT32        Status;
> +  EFI_PLATFORM_INFO_HOB               *PlatformInfoHob;
> +
> +   DEBUG ((EFI_D_INFO, "ConfigurePlatformSysCtrlGpio()...\n"));
> +
> +  //
> +  // Obtain Platform Info from HOB.
> +  //
> +  Status = GetPlatformInfoHob ((const EFI_PEI_SERVICES **)PeiServices,
> &PlatformInfoHob);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // The GPIO settings are dependent upon the platform.  Obtain the Board
> ID through
> +  // the EC to determine the current platform.
> +  //
> +   DEBUG ((EFI_D_INFO, "Platform Flavor | Board ID = 0x%X | 0x%X\n",
> PlatformInfoHob->PlatformFlavor, PlatformInfoHob->BoardId));
> +
> +
> +
> +  Status = (**PeiServices).LocatePpi (
> +                            (const EFI_PEI_SERVICES **)PeiServices,
> +                            &gPeiSmbusPpiGuid,
> +                            0,
> +                            NULL,
> +                            (void **)&SmbusPpi
> +                            );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Select/modify the GPIO initialization data based on the Board ID.
> +  //
> +  switch (PlatformInfoHob->BoardId)
> +  {
> +    default:
> +      Status = EFI_SUCCESS;
> +
> +      //
> +      // Do nothing for other RVP boards.
> +      //
> +      break;
> +  }
> +  return Status;
> +}
> +
> +static EFI_PEI_NOTIFY_DESCRIPTOR    mNotifyList[] = {
> +  {
> +    EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK|
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
> +    &gEfiPeiSmbusPpiGuid,
> +    ConfigurePlatformSysCtrlGpio
> +  }
> +};
> +
> +EFI_STATUS
> +InstallPlatformSysCtrlGPIONotify (
> +  IN CONST EFI_PEI_SERVICES           **PeiServices
> +  )
> +{
> +  EFI_STATUS                    Status;
> +
> +  DEBUG ((EFI_D_INFO, "InstallPlatformSysCtrlGPIONotify()...\n"));
> +
> +  Status = (*PeiServices)->NotifyPpi(PeiServices, &mNotifyList[0]);
> +  ASSERT_EFI_ERROR (Status);
> +  return EFI_SUCCESS;
> +
> +}
> +
> +#define V_PCH_ILB_IRQE_UARTIRQEN_IRQ3             BIT3 // UART IRQ3
> Enable
> +
> +/**
> +  Returns the Correct GPIO table for Mobile/Desktop respectively.
> +  Before call it, make sure PlatformInfoHob->BoardId&PlatformFlavor is get
> correctly.
> +
> +  @param PeiServices             General purpose services available to every
> PEIM.
> +  @param PlatformInfoHob         PlatformInfoHob pointer with
> PlatformFlavor specified.
> +  @param BoardId                 BoardId ID as determined through the EC.
> +
> +  @retval EFI_SUCCESS            The function completed successfully.
> +  @retval EFI_DEVICE_ERROR       KSC fails to respond.
> +
> +**/
> +EFI_STATUS
> +MultiPlatformGpioTableInit (
> +  IN CONST EFI_PEI_SERVICES     **PeiServices,
> +  IN EFI_PLATFORM_INFO_HOB      *PlatformInfoHob
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  EFI_PEI_READ_ONLY_VARIABLE2_PPI *PeiReadOnlyVarPpi;
> +  UINTN                           VarSize;
> +  SYSTEM_CONFIGURATION            SystemConfiguration;
> +
> +  DEBUG ((EFI_D_INFO, "MultiPlatformGpioTableInit()...\n"));
> +
> +  //
> +  // Select/modify the GPIO initialization data based on the Board ID.
> +  //
> +  switch (PlatformInfoHob->BoardId) {
> +
> +  case BOARD_ID_MINNOW2: // Minnow2
> +  case BOARD_ID_MINNOW2_TURBOT:
> +   Status = (**PeiServices).LocatePpi (
> +                             PeiServices,
> +                             &gEfiPeiReadOnlyVariable2PpiGuid,
> +                             0,
> +                             NULL,
> +                             (void **)&PeiReadOnlyVarPpi
> +                             );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    VarSize = sizeof (SYSTEM_CONFIGURATION);
> +    Status = PeiReadOnlyVarPpi->GetVariable (
> +                                  PeiReadOnlyVarPpi,
> +                                  PLATFORM_SETUP_VARIABLE_NAME,
> +                                  &gEfiSetupVariableGuid,
> +                                  NULL,
> +                                  &VarSize,
> +                                  &SystemConfiguration
> +                                  );
> +
> +     if (SystemConfiguration.GpioWakeCapability == 1) {
> +      PlatformInfoHob->PlatformCfioData     =
> (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2CfioInitData2;
> +     }
> +     else {
> +      PlatformInfoHob->PlatformCfioData     =
> (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2CfioInitData;
> +     }
> +
> +     PlatformInfoHob->PlatformGpioData_NC  =
> (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2_GpioInitData_NC[0];
> +     PlatformInfoHob->PlatformGpioData_SC  =
> (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2_GpioInitData_SC[0];
> +     PlatformInfoHob->PlatformGpioData_SUS =
> (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2_GpioInitData_SUS[0];
> +     break;
> +
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +UINT32
> +GPIORead32 (
> +  IN  UINT32 mmio_conf
> +  )
> +{
> +  UINT32 conf_val;
> +  UINT32 i;
> +  conf_val = MmioRead32(mmio_conf);
> +  for(i=0;i<5;i++){
> +    if(conf_val == 0xffffffff)
> +      conf_val = MmioRead32(mmio_conf);
> +      else
> +        break;
> +  }
> +
> +  return conf_val;
> +}
> +
> +/**
> +
> +  Set GPIO CONF0 and PAD_VAL registers for NC/SC/SUS GPIO clusters
> +
> +  @param Gpio_Mmio_Offset          GPIO_SCORE_OFFSET or
> GPIO_NCORE_OFFSET or GPIO_SSUS_OFFSET.
> +  @param Gpio_Pin_Num              Pin numbers to config for each GPIO
> clusters.
> +  @param Gpio_Conf_Data            GPIO_CONF_PAD_INIT data array for each
> GPIO clusters.
> +
> +**/
> +VOID
> +InternalGpioConfig (
> +  IN UINT32             Gpio_Mmio_Offset,
> +  IN UINT32             Gpio_Pin_Num,
> +  GPIO_CONF_PAD_INIT*   Gpio_Conf_Data
> +  )
> +{
> +  UINT32    index;
> +  UINT32    mmio_conf0;
> +  UINT32    mmio_padval;
> +  PAD_CONF0 conf0_val;
> +  PAD_VAL   pad_val;
> +
> +  //
> +  // GPIO WELL -- Memory base registers
> +  //
> +
> +  // A0 BIOS Spec doesn't mention it although X0 does. comment out now.
> +  // GPIO write 0x01001002 to IOBASE + Gpio_Mmio_Offset + 0x0900
> +  //
> +  for(index=0; index < Gpio_Pin_Num; index++)
> +  {
> +  	//
> +    // Calculate the MMIO Address for specific GPIO pin CONF0 register
> pointed by index.
> +    //
> +    mmio_conf0 = IO_BASE_ADDRESS + Gpio_Mmio_Offset +
> R_PCH_CFIO_PAD_CONF0 + Gpio_Conf_Data[index].offset * 16;
> +    mmio_padval= IO_BASE_ADDRESS + Gpio_Mmio_Offset +
> R_PCH_CFIO_PAD_VAL   + Gpio_Conf_Data[index].offset * 16;
> +
> +#ifdef EFI_DEBUG
> +    DEBUG ((EFI_D_INFO, "%s, ", Gpio_Conf_Data[index].pad_name));
> +
> +#endif
> +    DEBUG ((EFI_D_INFO, "Usage = %d, Func# = %d, IntType = %d, Pull
> Up/Down = %d, MMIO Base = 0x%08x, ",
> +      Gpio_Conf_Data[index].usage,
> +      Gpio_Conf_Data[index].func,
> +      Gpio_Conf_Data[index].int_type,
> +      Gpio_Conf_Data[index].pull,
> +      mmio_conf0));
> +
> +    //
> +    // Step 1: PadVal Programming.
> +    //
> +    pad_val.dw = GPIORead32(mmio_padval);
> +
> +    //
> +    // Config PAD_VAL only for GPIO (Non-Native) Pin
> +    //
> +    if(Native != Gpio_Conf_Data[index].usage)
> +    {
> +      pad_val.dw &= ~0x6; // Clear bits 1:2
> +      pad_val.dw |= (Gpio_Conf_Data[index].usage & 0x6);  // Set bits 1:2
> according to PadVal
> +
> +        //
> +        // set GPO default value
> +        //
> +        if(Gpio_Conf_Data[index].usage == GPO &&
> Gpio_Conf_Data[index].gpod4 != NA)
> +        {
> +        pad_val.r.pad_val = Gpio_Conf_Data[index].gpod4;
> +        }
> +    }
> +
> +
> +    DEBUG ((EFI_D_INFO, "Set PAD_VAL = 0x%08x, ", pad_val.dw));
> +
> +    MmioWrite32(mmio_padval, pad_val.dw);
> +
> +    //
> +    // Step 2: CONF0 Programming
> +    // Read GPIO default CONF0 value, which is assumed to be default value
> after reset.
> +    //
> +    conf0_val.dw = GPIORead32(mmio_conf0);
> +
> +    //
> +    // Set Function #
> +    //
> +    conf0_val.r.Func_Pin_Mux = Gpio_Conf_Data[index].func;
> +
> +    if(GPO == Gpio_Conf_Data[index].usage)
> +    {
> +      //
> +      // If used as GPO, then internal pull need to be disabled.
> +      //
> +      conf0_val.r.Pull_assign = 0;  // Non-pull
> +    }
> +    else
> +    {
> +      //
> +      // Set PullUp / PullDown
> +      //
> +      if(P_20K_H == Gpio_Conf_Data[index].pull)
> +      {
> +        conf0_val.r.Pull_assign = 0x1;  // PullUp
> +        conf0_val.r.Pull_strength = 0x2;// 20K
> +      }
> +      else if(P_20K_L == Gpio_Conf_Data[index].pull)
> +      {
> +        conf0_val.r.Pull_assign = 0x2;  // PullDown
> +        conf0_val.r.Pull_strength = 0x2;// 20K
> +      }
> +      else if(P_10K_H == Gpio_Conf_Data[index].pull)
> +      {
> +        conf0_val.r.Pull_assign = 0x1; 	// PullUp
> +        conf0_val.r.Pull_strength = 0x1;// 10K
> +      }
> +      else if(P_10K_L == Gpio_Conf_Data[index].pull)
> +      {
> +        conf0_val.r.Pull_assign = 0x2; 	// PullDown
> +        conf0_val.r.Pull_strength = 0x1;// 10K
> +      }
> +      else if(P_2K_H == Gpio_Conf_Data[index].pull)
> +      {
> +        conf0_val.r.Pull_assign = 0x1;  // PullUp
> +        conf0_val.r.Pull_strength = 0x0;// 2K
> +      }
> +      else if(P_2K_L == Gpio_Conf_Data[index].pull)
> +      {
> +        conf0_val.r.Pull_assign = 0x2;  // PullDown
> +        conf0_val.r.Pull_strength = 0x0;// 2K
> +      }
> +      else if(P_NONE == Gpio_Conf_Data[index].pull)
> +      {
> +        conf0_val.r.Pull_assign = 0;	// Non-pull
> +      }
> +      else
> +      {
> +        ASSERT(FALSE);  // Invalid value
> +      }
> +    }
> +
> +
> +    //
> +    // Set INT Trigger Type
> +    //
> +    conf0_val.dw &= ~0x0f000000;  // Clear bits 27:24
> +
> +    //
> +    // Set INT Trigger Type
> +    //
> +    if(TRIG_ == Gpio_Conf_Data[index].int_type)
> +    {
> +      //
> +      // Interrupt not capable, clear bits 27:24
> +      //
> +    }
> +    else
> +    {
> +      conf0_val.dw |= (Gpio_Conf_Data[index].int_type & 0x0f)<<24;
> +    }
> +
> +    DEBUG ((EFI_D_INFO, "Set CONF0 = 0x%08x\n", conf0_val.dw));
> +
> +    //
> +    // Write back the targeted GPIO config value according to platform (board)
> GPIO setting.
> +    //
> +    MmioWrite32 (mmio_conf0, conf0_val.dw);
> +  }
> +
> +  //
> +  // A0 BIOS Spec doesn't mention it although X0 does. comment out now.
> +  // GPIO SCORE write 0x01001002 to IOBASE + 0x0900
> +  //
> +}
> +
> +/**
> +  Returns the Correct GPIO table for Mobile/Desktop respectively.
> +  Before call it, make sure PlatformInfoHob->BoardId&PlatformFlavor is get
> correctly.
> +
> +  @param PeiServices               General purpose services available to every
> PEIM.
> +  @param PlatformInfoHob           PlatformInfoHob pointer with
> PlatformFlavor specified.
> +  @param BoardId                   BoardId ID as determined through the EC.
> +
> +  @retval EFI_SUCCESS              The function completed successfully.
> +  @retval EFI_DEVICE_ERROR         KSC fails to respond.
> +
> +**/
> +EFI_STATUS
> +MultiPlatformGpioProgram (
> +  IN CONST EFI_PEI_SERVICES     **PeiServices,
> +  IN EFI_PLATFORM_INFO_HOB      *PlatformInfoHob
> +  )
> +{
> +#if !_SIMIC_
> +  CFIO_INIT_STRUCT*           PlatformCfioDataPtr;
> +
> +  PlatformCfioDataPtr = (CFIO_INIT_STRUCT *) (UINTN) PlatformInfoHob-
> >PlatformCfioData;
> +  DEBUG ((EFI_D_INFO, "MultiPlatformGpioProgram()...\n"));
> +
> +  //
> +  //  SCORE GPIO WELL -- IO base registers
> +  //
> +
> +  //
> +  // GPIO_USE_SEL Register -> 1 = GPIO 0 = Native
> +  //
> +  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_USE_SEL,
> PlatformCfioDataPtr->Use_Sel_SC0);
> +
> +  //
> +  // Set GP_LVL Register
> +  //
> +  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL ,
> PlatformCfioDataPtr->GP_Lvl_SC0);
> +
> +  //
> +  // GP_IO_SEL Register -> 1 = Input 0 = Output.  If Native Mode don't care
> +  //
> +  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_IO_SEL,
> PlatformCfioDataPtr->Io_Sel_SC0);
> +
> +  //
> +  // GPIO Triger Positive Edge Enable Register
> +  //
> +  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_TPE,
> PlatformCfioDataPtr->TPE_SC0);
> +
> +  //
> +  //  GPIO Trigger Negative Edge Enable Register
> +  //
> +  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_TNE,
> PlatformCfioDataPtr->TNE_SC0);
> +
> +  //
> +  //  GPIO Trigger Status
> +  //
> +  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_TS,
> PlatformCfioDataPtr->TS_SC0);
> +
> +  //
> +  // GPIO_USE_SEL2 Register -> 1 = GPIO 0 = Native
> +  //
> +  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_USE_SEL2,
> PlatformCfioDataPtr->Use_Sel_SC1);
> +
> +  //
> +  // Set GP_LVL2 Register
> +  //
> +  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL2,
> PlatformCfioDataPtr->GP_Lvl_SC1);
> +
> +  //
> +  // GP_IO_SEL2 Register -> 1 = Input 0 = Output.  If Native Mode don't care
> +  //
> +  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_IO_SEL2,
> PlatformCfioDataPtr->Io_Sel_SC1);
> +
> +  //
> +  // GPIO_USE_SEL3 Register -> 1 = GPIO 0 = Native
> +  //
> +  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_USE_SEL3,
> PlatformCfioDataPtr->Use_Sel_SC2);
> +
> +  //
> +  // Set GP_LVL3 Register
> +  //
> +  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL3,
> PlatformCfioDataPtr->GP_Lvl_SC2);
> +
> +  //
> +  // GP_IO_SEL3 Register -> 1 = Input 0 = Output if Native Mode don't care
> +  //
> +  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_IO_SEL3,
> PlatformCfioDataPtr->Io_Sel_SC2);
> +
> +  //
> +  //  SUS GPIO WELL -- IO base registers
> +  //
> +
> +  //
> +  // GPIO_USE_SEL Register -> 1 = GPIO 0 = Native
> +  //
> +  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_USE_SEL,
> PlatformCfioDataPtr->Use_Sel_SS);
> +
> +  //
> +  // Set GP_LVL Register
> +  //
> +  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_LVL ,
> PlatformCfioDataPtr->GP_Lvl_SS);
> +
> +  //
> +  // GP_IO_SEL Register -> 1 = Input 0 = Output.  If Native Mode don't care.
> +  //
> +  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_IO_SEL,
> PlatformCfioDataPtr->Io_Sel_SS);
> +
> +  //
> +  // GPIO Triger Positive Edge Enable Register.
> +  //
> +  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_TPE,
> PlatformCfioDataPtr->TPE_SS);
> +
> +  //
> +  //  GPIO Trigger Negative Edge Enable Register.
> +  //
> +  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_TNE,
> PlatformCfioDataPtr->TNE_SS);
> +
> +  //
> +  //  GPIO Trigger Status.
> +  //
> +  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_TS,
> PlatformCfioDataPtr->TS_SS);
> +
> +  //
> +  //  GPIO Wake Enable.
> +  //
> +  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_WAKE_EN,
> PlatformCfioDataPtr->WE_SS);
> +
> +  //
> +  // Config SC/NC/SUS GPIO Pins
> +  //
> +  switch (PlatformInfoHob->BoardId) {
> +    case BOARD_ID_MINNOW2:
> +    case BOARD_ID_MINNOW2_TURBOT:
> +      DEBUG ((EFI_D_INFO, "Start to config Minnow2 GPIO pins\n"));
> +      InternalGpioConfig(GPIO_SCORE_OFFSET,
> sizeof(mMinnow2_GpioInitData_SC)/sizeof(mMinnow2_GpioInitData_SC[0]
> ),   (GPIO_CONF_PAD_INIT *) (UINTN) PlatformInfoHob-
> >PlatformGpioData_SC);
> +      InternalGpioConfig(GPIO_NCORE_OFFSET,
> sizeof(mMinnow2_GpioInitData_NC)/sizeof(mMinnow2_GpioInitData_NC[0
> ]),   (GPIO_CONF_PAD_INIT *) (UINTN) PlatformInfoHob-
> >PlatformGpioData_NC);
> +      InternalGpioConfig(GPIO_SSUS_OFFSET,
> sizeof(mMinnow2_GpioInitData_SUS)/sizeof(mMinnow2_GpioInitData_SUS
> [0]), (GPIO_CONF_PAD_INIT *) (UINTN) PlatformInfoHob-
> >PlatformGpioData_SUS);
> +      break;
> +    default:
> +
> +      break;
> +  }
> +
> +   //
> +   // configure the CFIO Pnp settings
> +   //
> +   if (PlatformInfoHob->CfioEnabled) {
> +     if (PlatformInfoHob->BoardId == BOARD_ID_MINNOW2 ||
> PlatformInfoHob->BoardId == BOARD_ID_MINNOW2_TURBOT){
> +       InternalGpioConfig(GPIO_SCORE_OFFSET,
> sizeof(mNB_BB_FAB3_GpioInitData_SC_TRI)/sizeof(mNB_BB_FAB3_GpioIni
> tData_SC_TRI[0]), (GPIO_CONF_PAD_INIT *) (UINTN)PlatformInfoHob-
> >PlatformGpioData_SC_TRI);
> +     }
> +   }
> +#else
> +   DEBUG ((EFI_D_INFO, "Skip MultiPlatformGpioProgram()...for SIMICS or
> HYB model\n"));
> +#endif
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/B
> oardGpios.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/B
> oardGpios.h
> new file mode 100644
> index 0000000000..0e19819b22
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/B
> oardGpios.h
> @@ -0,0 +1,324 @@
> +/**@file
> +  Gpio setting for multiplatform.
> +
> +  This file includes package header files, library classes.
> +
> +  Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +**/
> +
> +#ifndef _BOARDGPIOS_H_
> +#define _BOARDGPIOS_H_
> +
> +#include <PiPei.h>
> +#include "PchAccess.h"
> +#include "PlatformBaseAddresses.h"
> +#include <../MultiPlatformLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/HobLib.h>
> +#include <Guid/PlatformInfo.h>
> +#include <Ppi/Smbus.h>
> +#include <Ppi/ReadOnlyVariable2.h>
> +#include <Guid/SetupVariable.h>
> +
> +
> +GPIO_CONF_PAD_INIT mNB_BB_FAB3_GpioInitData_SC_TRI[] =
> +{
> +//              Pad Name          GPIO Number     Used As   GPO Default  Function#
> INT Capable   Interrupt Type   PULL H/L    MMIO Offset
> +GPIO_INIT_ITEM("LPC_CLKOUT1       GPIOC_48
> "     ,TRISTS   ,NA           ,F0           ,             ,                ,NONE       ,0x41),
> +GPIO_INIT_ITEM("PLT_CLK0          GPIOC_96
> "     ,TRISTS   ,NA           ,F0           ,             ,                ,NONE       ,0x6a),
> +GPIO_INIT_ITEM("PLT_CLK3          GPIOC_99
> "     ,TRISTS   ,NA           ,F0           ,             ,                ,NONE       ,0x68),
> +};
> +
> +//
> +// Minnow2
> +//
> +#define MINNOW2_GPIO_USE_SEL_VAL_0_31        0x00000000
> +#define MINNOW2_GPIO_USE_SEL_VAL_32_63       0x00000000
> +#define MINNOW2_GPIO_USE_SEL_VAL_64_70       0x00000000
> +#define MINNOW2_GPIO_USE_SEL_VAL_64_70       0x00000000
> +#define MINNOW2_GPIO_USE_SEL_VAL_SUS         0x00000000
> +#define MINNOW2_GPIO_USE_SEL_VAL_SUS2        0x00000001
> +
> +
> +#define MINNOW2_GPIO_IO_SEL_VAL_0_31         0x00000000
> +#define MINNOW2_GPIO_IO_SEL_VAL_32_63        0x00000000
> +#define MINNOW2_GPIO_IO_SEL_VAL_64_70        0x00000000
> +#define MINNOW2_GPIO_IO_SEL_VAL_SUS          0x00000000
> +#define MINNOW2_GPIO_IO_SEL_VAL_SUS2         0x00000001
> +
> +
> +#define MINNOW2_GPIO_LVL_VAL_0_31            0x00000000
> +#define MINNOW2_GPIO_LVL_VAL_32_63           0x00000000
> +#define MINNOW2_GPIO_LVL_VAL_64_70           0x00000000
> +#define MINNOW2_GPIO_LVL_VAL_SUS             0x00000000
> +#define MINNOW2_GPIO_LVL_VAL_SUS2            0x00000001
> +
> +#define MINNOW2_GPIO_TPE_VAL_0_31            0x00000000
> +#define MINNOW2_GPIO_TPE_VAL_SUS             0x00000000
> +#define MINNOW2_GPIO_TPE_VAL_SUS2            0x00000001
> +
> +#define MINNOW2_GPIO_TNE_VAL_0_31            0x00000000
> +#define MINNOW2_GPIO_TNE_VAL_SUS             0x00000000
> +#define MINNOW2_GPIO_TNE_VAL_SUS2            0x00000001
> +
> +#define MINNOW2_GPIO_TS_VAL_0_31             0x00000000
> +#define MINNOW2_GPIO_TS_VAL_SUS              0x00000000
> +#define MINNOW2_GPIO_TS_VAL_SUS2             0x00000001
> +
> +static CFIO_INIT_STRUCT mMinnow2CfioInitData =
> +{
> +        MINNOW2_GPIO_USE_SEL_VAL_0_31,
> +        MINNOW2_GPIO_USE_SEL_VAL_32_63,
> +        MINNOW2_GPIO_USE_SEL_VAL_64_70,
> +        MINNOW2_GPIO_USE_SEL_VAL_SUS,
> +
> +        MINNOW2_GPIO_IO_SEL_VAL_0_31,
> +        MINNOW2_GPIO_IO_SEL_VAL_32_63,
> +        MINNOW2_GPIO_IO_SEL_VAL_64_70,
> +        MINNOW2_GPIO_IO_SEL_VAL_SUS,
> +
> +        MINNOW2_GPIO_LVL_VAL_0_31,
> +        MINNOW2_GPIO_LVL_VAL_32_63,
> +        MINNOW2_GPIO_LVL_VAL_64_70,
> +        MINNOW2_GPIO_LVL_VAL_SUS,
> +
> +        MINNOW2_GPIO_TPE_VAL_0_31,
> +        MINNOW2_GPIO_TPE_VAL_SUS,
> +        MINNOW2_GPIO_TNE_VAL_0_31,
> +        MINNOW2_GPIO_TNE_VAL_SUS,
> +
> +        MINNOW2_GPIO_TS_VAL_0_31,
> +        MINNOW2_GPIO_TS_VAL_SUS
> +};
> +
> +static CFIO_INIT_STRUCT mMinnow2CfioInitData2 =
> +{
> +        MINNOW2_GPIO_USE_SEL_VAL_0_31,
> +        MINNOW2_GPIO_USE_SEL_VAL_32_63,
> +        MINNOW2_GPIO_USE_SEL_VAL_64_70,
> +        MINNOW2_GPIO_USE_SEL_VAL_SUS2,
> +
> +        MINNOW2_GPIO_IO_SEL_VAL_0_31,
> +        MINNOW2_GPIO_IO_SEL_VAL_32_63,
> +        MINNOW2_GPIO_IO_SEL_VAL_64_70,
> +        MINNOW2_GPIO_IO_SEL_VAL_SUS2,
> +
> +        MINNOW2_GPIO_LVL_VAL_0_31,
> +        MINNOW2_GPIO_LVL_VAL_32_63,
> +        MINNOW2_GPIO_LVL_VAL_64_70,
> +        MINNOW2_GPIO_LVL_VAL_SUS2,
> +
> +        MINNOW2_GPIO_TPE_VAL_0_31,
> +        MINNOW2_GPIO_TPE_VAL_SUS2,
> +        MINNOW2_GPIO_TNE_VAL_0_31,
> +        MINNOW2_GPIO_TNE_VAL_SUS2,
> +
> +        MINNOW2_GPIO_TS_VAL_0_31,
> +        MINNOW2_GPIO_TS_VAL_SUS2
> +};
> +
> +static GPIO_CONF_PAD_INIT mMinnow2_GpioInitData_NC[] =
> +{
> +//              Pad Name          GPIO Number     Used As   GPO Default   Function#
> INT Capable   Interrupt Type   PULL H/L    MMIO Offset
> +GPIO_INIT_ITEM("HV_DDI0_HPD       GPIONC_0
> "     ,Native   ,NA           ,F2           ,             ,                ,NONE       ,0x13),
> +GPIO_INIT_ITEM("HV_DDI0_DDC_SDA   GPIONC_1
> "     ,Native   ,NA           ,F2           ,             ,                ,NONE       ,0x12),
> +GPIO_INIT_ITEM("HV_DDI0_DDC_SCL   GPIONC_2
> "     ,Native   ,NA           ,F2           ,             ,                ,NONE       ,0x11),
> +GPIO_INIT_ITEM("PANEL0_VDDEN      GPIONC_3
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x14),
> +GPIO_INIT_ITEM("PANEL0_BKLTEN     GPIONC_4
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x15),
> +GPIO_INIT_ITEM("PANEL0_BKLTCTL    GPIONC_5
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x16),
> +GPIO_INIT_ITEM("HV_DDI1_HPD       GPIONC_6
> "     ,Native   ,NA           ,F2           ,             ,                ,NONE       ,0x18),
> +GPIO_INIT_ITEM("HV_DDI1_DDC_SDA   GPIONC_7
> "     ,Native   ,NA           ,F2           ,             ,                ,NONE       ,0x19),
> +GPIO_INIT_ITEM("HV_DDI1_DDC_SCL   GPIONC_8
> "     ,Native   ,NA           ,F2           ,             ,                ,NONE       ,0x17),
> +GPIO_INIT_ITEM("PANEL1_VDDEN      GPIONC_9
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x10),
> +GPIO_INIT_ITEM("PANEL1_BKLTEN
> GPIONC_10"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x0e),
> +GPIO_INIT_ITEM("PANEL1_BKLTCTL
> GPIONC_11"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x0f),
> +GPIO_INIT_ITEM("GP_INTD_DSI_TE1
> GPIONC_12"     ,GPO      ,NA           ,F0           ,             ,                ,NONE       ,0x0c),
> +GPIO_INIT_ITEM("HV_DDI2_DDC_SDA
> GPIONC_13"     ,GPI      ,NA           ,F0           ,             ,                ,10K_L      ,0x1a),
> +GPIO_INIT_ITEM("HV_DDI2_DDC_SCL
> GPIONC_14"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x1b),
> +GPIO_INIT_ITEM("GP_CAMERASB00
> GPIONC_15"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x01),
> +GPIO_INIT_ITEM("GP_CAMERASB01
> GPIONC_16"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x04),
> +GPIO_INIT_ITEM("GP_CAMERASB02
> GPIONC_17"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x08),
> +GPIO_INIT_ITEM("GP_CAMERASB03
> GPIONC_18"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x0b),
> +GPIO_INIT_ITEM("GP_CAMERASB04
> GPIONC_19"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x00),
> +GPIO_INIT_ITEM("GP_CAMERASB05
> GPIONC_20"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x03),
> +GPIO_INIT_ITEM("GP_CAMERASB06
> GPIONC_21"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x06),
> +GPIO_INIT_ITEM("GP_CAMERASB07
> GPIONC_22"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x0a),
> +GPIO_INIT_ITEM("GP_CAMERASB08
> GPIONC_23"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x0d),
> +GPIO_INIT_ITEM("GP_CAMERASB09
> GPIONC_24"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x02),
> +GPIO_INIT_ITEM("GP_CAMERASB10
> GPIONC_25"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x05),
> +GPIO_INIT_ITEM("GP_CAMERASB11
> GPIONC_26"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x09),
> +};
> +
> +
> +static GPIO_CONF_PAD_INIT mMinnow2_GpioInitData_SC[] = {
> +//              Pad Name          GPIO Number     Used As   GPO Default   Function#
> INT Capable   Interrupt Type   PULL H/L    MMIO Offset
> +GPIO_INIT_ITEM("SATA_GP0          GPIOC_0
> "     ,Native   ,NA           ,F1           ,             ,                ,NONE       ,0x55),
> +GPIO_INIT_ITEM("SATA_GP1          GPIOC_1
> "     ,Native   ,NA           ,F1           ,             ,                ,NONE       ,0x59),
> +GPIO_INIT_ITEM("SATA_LEDN         GPIOC_2
> "     ,Native   ,NA           ,F1           ,             ,                ,NONE       ,0x5d),
> +GPIO_INIT_ITEM("PCIE_CLKREQ0B     GPIOC_3
> "     ,Native   ,NA           ,F1           ,             ,                ,10K_H      ,0x60),
> +GPIO_INIT_ITEM("PCIE_CLKREQ1B     GPIOC_4
> "     ,Native   ,NA           ,F1           ,             ,                ,10K_H      ,0x63),
> +GPIO_INIT_ITEM("PCIE_CLKREQ2B     GPIOC_5
> "     ,Native   ,NA           ,F1           ,             ,                ,10K_H      ,0x66),
> +GPIO_INIT_ITEM("PCIE_CLKREQ3B     GPIOC_6
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x62),
> +GPIO_INIT_ITEM("SDMMC3_WP         GPIOC_7
> "     ,Native   ,NA           ,F2           ,             ,                ,NONE       ,0x65),
> +GPIO_INIT_ITEM("HDA_RSTB          GPIOC_8
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x22),
> +GPIO_INIT_ITEM("HDA_SYNC          GPIOC_9
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x25),
> +GPIO_INIT_ITEM("HDA_CLK           GPIOC_10
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x24),
> +GPIO_INIT_ITEM("HDA_SDO           GPIOC_11
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x26),
> +GPIO_INIT_ITEM("HDA_SDI0          GPIOC_12
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x27),
> +GPIO_INIT_ITEM("HDA_SDI1          GPIOC_13
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x23),
> +GPIO_INIT_ITEM("HDA_DOCKRSTB      GPIOC_14
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x28),
> +GPIO_INIT_ITEM("HDA_DOCKENB       GPIOC_15
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x54),
> +GPIO_INIT_ITEM("SDMMC1_CLK        GPIOC_16
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x3e),
> +GPIO_INIT_ITEM("SDMMC1_D0         GPIOC_17
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x3d),
> +GPIO_INIT_ITEM("SDMMC1_D1         GPIOC_18
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x40),
> +GPIO_INIT_ITEM("SDMMC1_D2         GPIOC_19
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x3b),
> +GPIO_INIT_ITEM("SDMMC1_D3_CD_B    GPIOC_20
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x36),
> +GPIO_INIT_ITEM("MMC1_D4_SD_WE     GPIOC_21
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x38),
> +GPIO_INIT_ITEM("MMC1_D5           GPIOC_22
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x3c),
> +GPIO_INIT_ITEM("MMC1_D6           GPIOC_23
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x37),
> +GPIO_INIT_ITEM("MMC1_D7           GPIOC_24
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x3f),
> +GPIO_INIT_ITEM("SDMMC1_CMD        GPIOC_25
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x39),
> +GPIO_INIT_ITEM("MMC1_RESET_B      GPIOC_26
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x33),
> +GPIO_INIT_ITEM("SDMMC2_CLK        GPIOC_27
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x32),
> +GPIO_INIT_ITEM("SDMMC2_D0         GPIOC_28
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x35),
> +GPIO_INIT_ITEM("SDMMC2_D1         GPIOC_29
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x2f),
> +GPIO_INIT_ITEM("SDMMC2_D2         GPIOC_30
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x34),
> +GPIO_INIT_ITEM("SDMMC2_D3_CD_B    GPIOC_31
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x31),
> +GPIO_INIT_ITEM("SDMMC2_CMD        GPIOC_32
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x30),
> +//
> +//Just for test, We make the setting that all is same with Bayleybay.
> +//
> +GPIO_INIT_ITEM("SDMMC3_CLK        GPIOC_33
> "     ,Native   ,NA           ,F1           ,             ,                ,NONE      ,0x2b),
> +GPIO_INIT_ITEM("SDMMC3_D0         GPIOC_34
> "     ,Native   ,NA           ,F1           ,             ,                ,NONE      ,0x2e),
> +GPIO_INIT_ITEM("SDMMC3_D1         GPIOC_35
> "     ,Native   ,NA           ,F1           ,YES          ,                ,NONE      ,0x29),
> +GPIO_INIT_ITEM("SDMMC3_D2         GPIOC_36
> "     ,Native   ,NA           ,F1           ,             ,                ,NONE      ,0x2d),
> +GPIO_INIT_ITEM("SDMMC3_D3         GPIOC_37
> "     ,Native   ,NA           ,F1           ,             ,                ,NONE      ,0x2a),
> +GPIO_INIT_ITEM("SDMMC3_CD_B       GPIOC_38
> "     ,Native   ,NA           ,F1           ,YES          ,Edge_Both       ,NONE      ,0x3a),
> +GPIO_INIT_ITEM("SDMMC3_CMD        GPIOC_39
> "     ,Native   ,NA           ,F1           ,             ,                ,NONE      ,0x2c),
> +GPIO_INIT_ITEM("SDMMC3_1P8_EN     GPIOC_40
> "     ,Native   ,NA           ,F1           ,             ,                ,NONE      ,0x5f),
> +GPIO_INIT_ITEM("SDMMC3_PWR_EN_B   GPIOC_41
> "     ,Native   ,NA           ,F1           ,             ,                ,NONE      ,0x69),
> +GPIO_INIT_ITEM("LPC_AD0           GPIOC_42
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x46),
> +GPIO_INIT_ITEM("LPC_AD1           GPIOC_43
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x44),
> +GPIO_INIT_ITEM("LPC_AD2           GPIOC_44
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x43),
> +GPIO_INIT_ITEM("LPC_AD3           GPIOC_45
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x42),
> +GPIO_INIT_ITEM("LPC_FRAMEB        GPIOC_46
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x45),
> +GPIO_INIT_ITEM("LPC_CLKOUT0       GPIOC_47
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x47),
> +GPIO_INIT_ITEM("LPC_CLKOUT1       GPIOC_48
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x41),
> +GPIO_INIT_ITEM("LPC_CLKRUNB       GPIOC_49
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x48),
> +GPIO_INIT_ITEM("ILB_SERIRQ        GPIOC_50
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x56),
> +GPIO_INIT_ITEM("SMB_DATA          GPIOC_51
> "     ,Native   ,NA           ,F1           ,             ,                ,NONE       ,0x5a),
> +GPIO_INIT_ITEM("SMB_CLK           GPIOC_52
> "     ,Native   ,NA           ,F1           ,             ,                ,NONE       ,0x58),
> +GPIO_INIT_ITEM("SMB_ALERTB        GPIOC_53
> "     ,Native   ,NA           ,F1           ,             ,                ,10K_H      ,0x5c),
> +GPIO_INIT_ITEM("SPKR              GPIOC_54
> "     ,GPI     ,NA           ,F0           ,             ,                ,20K_H      ,0x67),
> +GPIO_INIT_ITEM("MHSI_ACDATA       GPIOC_55
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x4d),
> +GPIO_INIT_ITEM("MHSI_ACFLAG       GPIOC_56
> "     ,GPI      ,NA           ,F0           ,             ,                ,20K_H      ,0x4f),
> +GPIO_INIT_ITEM("MHSI_ACWAKE       GPIOC_58
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x4e),
> +GPIO_INIT_ITEM("MHSI_CADATA       GPIOC_59
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x51),
> +GPIO_INIT_ITEM("MHSI_CAFLAG       GPIOC_60
> "     ,GPO      ,HI           ,F0           ,             ,                ,20K_H      ,0x50),
> +GPIO_INIT_ITEM("GP_SSP_2_CLK      GPIOC_62
> "     ,GPI     ,NA           ,F0           ,             ,                ,20K_H      ,0x0d),
> +GPIO_INIT_ITEM("GP_SSP_2_FS       GPIOC_63
> "     ,GPI     ,NA           ,F0           ,             ,                ,20K_H      ,0x0c),
> +GPIO_INIT_ITEM("GP_SSP_2_RXD      GPIOC_64
> "     ,GPI       ,NA           ,F0           ,             ,              ,20K_H      ,0x0f),
> +GPIO_INIT_ITEM("GP_SSP_2_TXD      GPIOC_65
> "     ,GPI     ,NA           ,F0           ,             ,                ,20K_H      ,0x0e),
> +GPIO_INIT_ITEM("SPI1_CS0_B        GPIOC_66
> "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x11),
> +GPIO_INIT_ITEM("SPI1_MISO         GPIOC_67
> "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x12),
> +GPIO_INIT_ITEM("SPI1_MOSI         GPIOC_68
> "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x13),
> +GPIO_INIT_ITEM("SPI1_CLK          GPIOC_69
> "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x10),
> +GPIO_INIT_ITEM("UART1_RXD         GPIOC_70
> "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x02),
> +GPIO_INIT_ITEM("UART1_TXD         GPIOC_71
> "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x01),
> +GPIO_INIT_ITEM("UART1_RTS_B       GPIOC_72
> "     ,GPI     ,NA           ,F0           ,             ,                ,20K_H      ,0x00),
> +GPIO_INIT_ITEM("UART1_CTS_B       GPIOC_73
> "     ,GPI     ,NA           ,F0           ,             ,                ,20K_H      ,0x04),
> +GPIO_INIT_ITEM("UART2_RXD         GPIOC_74
> "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x06),
> +GPIO_INIT_ITEM("UART2_TXD         GPIOC_75
> "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x07),
> +GPIO_INIT_ITEM("UART2_RTS_B       GPIOC_76
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x09),
> +GPIO_INIT_ITEM("UART2_CTS_B       GPIOC_77
> "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x08),
> +GPIO_INIT_ITEM("I2C0_SDA          GPIOC_78
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x21),
> +GPIO_INIT_ITEM("I2C0_SCL          GPIOC_79
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x20),
> +GPIO_INIT_ITEM("I2C1_SDA          GPIOC_80
> "     ,Native   ,NA           ,F1           ,             ,                ,NONE       ,0x1f),
> +GPIO_INIT_ITEM("I2C1_SCL          GPIOC_81
> "     ,Native   ,NA           ,F1           ,             ,                ,NONE       ,0x1e),
> +GPIO_INIT_ITEM("I2C2_SDA          GPIOC_82
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x1d),
> +GPIO_INIT_ITEM("I2C2_SCL          GPIOC_83
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x1b),
> +GPIO_INIT_ITEM("I2C3_SDA          GPIOC_84
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x19),
> +GPIO_INIT_ITEM("I2C3_SCL          GPIOC_85
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x1c),
> +GPIO_INIT_ITEM("I2C4_SDA          GPIOC_86
> "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x1a),
> +GPIO_INIT_ITEM("I2C4_SCL          GPIOC_87
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x17),
> +GPIO_INIT_ITEM("I2C5_SDA          GPIOC_88
> "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x15),
> +GPIO_INIT_ITEM("I2C5_SCL          GPIOC_89
> "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x14),
> +GPIO_INIT_ITEM("I2C6_SDA          GPIOC_90
> "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x18),
> +GPIO_INIT_ITEM("I2C6_SCL          GPIOC_91
> "     ,Native   ,NA           ,F1           ,             ,                ,20K_H      ,0x16),
> +GPIO_INIT_ITEM("I2C_NFC_SDA       GPIOC_92
> "     ,GPIO     ,NA           ,F1           ,             ,                ,NONE       ,0x05),
> +GPIO_INIT_ITEM("I2C_NFC_SCL       GPIOC_93
> "     ,GPO      ,LO           ,F1           ,             ,                ,NONE       ,0x03),
> +GPIO_INIT_ITEM("PWM0              GPIOC_94
> "     ,Native   ,NA           ,F1           ,             ,                ,20K_L      ,0x0a),
> +GPIO_INIT_ITEM("PWM1              GPIOC_95
> "     ,Native   ,NA           ,F1           ,             ,                ,20K_L      ,0x0b),
> +GPIO_INIT_ITEM("PLT_CLK0          GPIOC_96
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x6a),
> +GPIO_INIT_ITEM("PLT_CLK1          GPIOC_97
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x57),
> +GPIO_INIT_ITEM("PLT_CLK2          GPIOC_98
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x5b),
> +GPIO_INIT_ITEM("PLT_CLK3          GPIOC_99
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x68),
> +GPIO_INIT_ITEM("PLT_CLK4
> GPIOC_100"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x61),
> +GPIO_INIT_ITEM("PLT_CLK5
> GPIOC_101"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x64),
> +};
> +
> +static GPIO_CONF_PAD_INIT mMinnow2_GpioInitData_SUS[] = {
> +//              Pad Name          GPIO Number     Used As   GPIO Default  Function#
> INT Capable   Interrupt Type   PULL H/L    MMIO Offset
> +GPIO_INIT_ITEM("GPIO_SUS0
> GPIO_SUS0"     ,GPI      ,NA           ,F0           ,             ,                ,20K_H      ,0x1d),
> +GPIO_INIT_ITEM("GPIO_SUS1
> GPIO_SUS1"     ,GPI      ,NA           ,F0           ,             ,                ,20K_H      ,0x21),
> +GPIO_INIT_ITEM("GPIO_SUS2
> GPIO_SUS2"     ,GPI      ,NA           ,F0           ,             ,                ,20K_H      ,0x1e),
> +GPIO_INIT_ITEM("GPIO_SUS3
> GPIO_SUS3"     ,Native   ,NA           ,F6           ,YES          ,Level_Low       ,2K_H       ,0
> x1f),
> +GPIO_INIT_ITEM("GPIO_SUS4
> GPIO_SUS4"     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x20),
> +GPIO_INIT_ITEM("GPIO_SUS5
> GPIO_SUS5"     ,GPI      ,NA           ,F0           ,             ,                ,NONE       ,0x22),
> +GPIO_INIT_ITEM("GPIO_SUS6
> GPIO_SUS6"     ,GPI      ,NA           ,F0           ,             ,                ,NONE       ,0x24),
> +GPIO_INIT_ITEM("GPIO_SUS7
> GPIO_SUS7"     ,GPI      ,NA           ,F0           ,             ,                ,NONE       ,0x23),
> +GPIO_INIT_ITEM("SEC_GPIO_SUS8
> GPIO_SUS8"     ,GPO      ,HI           ,F0           ,             ,                ,20K_H      ,0x26),
> +GPIO_INIT_ITEM("SEC_GPIO_SUS9
> GPIO_SUS9"     ,GPO      ,HI           ,F0           ,             ,                ,20K_H      ,0x25),
> +GPIO_INIT_ITEM("SEC_GPIO_SUS10
> GPIO_SUS10"    ,GPO      ,HI           ,F0           ,             ,                ,NONE       ,0x12),
> +GPIO_INIT_ITEM("SUSPWRDNACK       GPIOS_11
> "     ,Native   ,NA           ,F0           ,             ,                ,10K_H      ,0x07),
> +GPIO_INIT_ITEM("PMU_SUSCLK        GPIOS_12
> "     ,Native   ,NA           ,F0           ,             ,                ,NONE       ,0x0b),
> +GPIO_INIT_ITEM("PMU_SLP_S0IX_B    GPIOS_13
> "     ,Native   ,NA           ,F0           ,             ,                ,NONE       ,0x14),
> +GPIO_INIT_ITEM("PMU_SLP_LAN_B     GPIOS_14
> "     ,GPO      ,LO           ,F1           ,             ,                ,10K_H      ,0x11),
> +GPIO_INIT_ITEM("PMU_WAKE_B        GPIOS_15
> "     ,Native   ,NA           ,F0           ,             ,                ,20K_H      ,0x01),
> +GPIO_INIT_ITEM("PMU_PWRBTN_B      GPIOS_16
> "     ,Native   ,NA           ,F0           ,             ,                ,20K_H      ,0x08),
> +GPIO_INIT_ITEM("PMU_WAKE_LAN_B    GPIOS_17
> "     ,GPIO     ,NA           ,F1           ,             ,                ,NONE       ,0x0a),
> +GPIO_INIT_ITEM("SUS_STAT_B        GPIOS_18
> "     ,GPO      ,NA           ,F1           ,             ,                ,NONE       ,0x13),
> +GPIO_INIT_ITEM("USB_OC0_B         GPIOS_19
> "     ,Native   ,NA           ,F0           ,             ,                ,10K_H      ,0x0c),
> +GPIO_INIT_ITEM("USB_OC1_B         GPIOS_20
> "     ,Native   ,NA           ,F0           ,             ,                ,10K_H      ,0x00),
> +GPIO_INIT_ITEM("SPI_CS1_B         GPIOS_21
> "     ,Native   ,NA           ,F0           ,             ,                ,NONE       ,0x02),
> +GPIO_INIT_ITEM("GPIO_DFX0         GPIOS_22
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x17),
> +GPIO_INIT_ITEM("GPIO_DFX1         GPIOS_23
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x27),
> +GPIO_INIT_ITEM("GPIO_DFX2         GPIOS_24
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x1c),
> +GPIO_INIT_ITEM("GPIO_DFX3         GPIOS_25
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x1b),
> +GPIO_INIT_ITEM("GPIO_DFX4         GPIOS_26
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x16),
> +GPIO_INIT_ITEM("GPIO_DFX5         GPIOS_27
> "     ,GPI      ,NA           ,F0           ,             ,                ,20K_H      ,0x15),
> +GPIO_INIT_ITEM("GPIO_DFX6         GPIOS_28
> "     ,GPI      ,NA           ,F0           ,             ,                ,20K_H      ,0x18),
> +GPIO_INIT_ITEM("GPIO_DFX7         GPIOS_29
> "     ,GPI      ,NA           ,F0           ,             ,                ,20K_H      ,0x19),
> +GPIO_INIT_ITEM("GPIO_DFX8         GPIOS_30
> "     ,GPI      ,NA           ,F0           ,             ,                ,20K_H      ,0x1a),
> +GPIO_INIT_ITEM("USB_ULPI_0_CLK    GPIOS_31
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x33),
> +GPIO_INIT_ITEM("USB_ULPI_0_DATA0  GPIOS_32
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x38),
> +GPIO_INIT_ITEM("USB_ULPI_0_DATA1  GPIOS_33
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x36),
> +GPIO_INIT_ITEM("USB_ULPI_0_DATA2  GPIOS_34
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x31),
> +GPIO_INIT_ITEM("USB_ULPI_0_DATA3  GPIOS_35
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x37),
> +GPIO_INIT_ITEM("USB_ULPI_0_DATA4  GPIOS_36
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x30),
> +GPIO_INIT_ITEM("USB_ULPI_0_DATA5  GPIOS_37
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x39),
> +GPIO_INIT_ITEM("USB_ULPI_0_DATA6  GPIOS_38
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x32),
> +GPIO_INIT_ITEM("USB_ULPI_0_DATA7  GPIOS_39
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x3a),
> +GPIO_INIT_ITEM("USB_ULPI_0_DIR    GPIOS_40
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x34),
> +GPIO_INIT_ITEM("USB_ULPI_0_NXT    GPIOS_41
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x35),
> +GPIO_INIT_ITEM("USB_ULPI_0_STP    GPIOS_42
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x3b),
> +GPIO_INIT_ITEM("USB_ULPI_0_REFCLK GPIOS_43
> "     ,GPIO     ,NA           ,F0           ,             ,                ,NONE       ,0x28),
> +};
> +
> +EFI_STATUS
> +MultiPlatformGpioTableInit (
> +  IN CONST EFI_PEI_SERVICES     **PeiServices,
> +  IN EFI_PLATFORM_INFO_HOB      *PlatformInfoHob
> +  );
> +
> +EFI_STATUS
> +MultiPlatformGpioProgram (
> +  IN CONST EFI_PEI_SERVICES     **PeiServices,
> +  IN EFI_PLATFORM_INFO_HOB      *PlatformInfoHob
> +  );
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers
> /BoardJumpers.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers
> /BoardJumpers.c
> new file mode 100644
> index 0000000000..67f5e24ede
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers
> /BoardJumpers.c
> @@ -0,0 +1,30 @@
> +/** @file
> +  Jumper setting for multiplatform.
> +
> +  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +**/
> +
> +#include <BoardJumpers.h>
> +
> +BOOLEAN
> +IsRecoveryJumper (
> +  IN CONST EFI_PEI_SERVICES    **PeiServices,
> +  IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
> +)
> +{
> +  return FALSE;
> +}
> +
> +BOOLEAN
> +IsManufacturingMode(
> +  IN CONST EFI_PEI_SERVICES    **PeiServices,
> +  IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
> +)
> +{
> +  return FALSE;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers
> /BoardJumpers.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers
> /BoardJumpers.h
> new file mode 100644
> index 0000000000..7c1fc88909
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers
> /BoardJumpers.h
> @@ -0,0 +1,30 @@
> +/**@file
> +  Jumper setting for multiplatform.
> +
> +  This file includes package header files, library classes.
> +
> +  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +**/
> +
> +#ifndef _BOARDJUMPERS_H_
> +#define _BOARDJUMPERS_H_
> +
> +#include <PiPei.h>
> +#include "PchAccess.h"
> +#include "PlatformBaseAddresses.h"
> +
> +#include <Library/IoLib.h>
> +#include <Library/DebugLib.h>
> +#include <Guid/PlatformInfo.h>
> +
> +BOOLEAN
> +IsRecoveryJumper (
> +  IN CONST EFI_PEI_SERVICES    **PeiServices,
> +  IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
> +);
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/
> BoardOemIds.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/
> BoardOemIds.c
> new file mode 100644
> index 0000000000..bb3f4c0a33
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/
> BoardOemIds.c
> @@ -0,0 +1,43 @@
> +/** @file
> +  ACPI oem ids setting for multiplatform.
> +
> +  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +**/
> +
> +#include <BoardOemIds.h>
> +
> +//
> +// Global module data
> +//
> +EFI_STATUS
> +InitializeBoardOemId (
> +  IN CONST EFI_PEI_SERVICES       **PeiServices,
> +  IN EFI_PLATFORM_INFO_HOB        *PlatformInfoHob
> +  )
> +{
> +    UINT64  OemId;
> +    UINT64  OemTableId;
> +
> +    //
> +    // Set OEM ID according to Board ID.
> +    //
> +    switch (PlatformInfoHob->BoardId) {
> +
> +      case BOARD_ID_MINNOW2:
> +      case BOARD_ID_MINNOW2_TURBOT:
> +      default:
> +        OemId = EFI_ACPI_OEM_ID_DEFAULT;
> +        OemTableId = EFI_ACPI_OEM_TABLE_ID_DEFAULT;
> +        break;
> +    }
> +
> +    PlatformInfoHob->AcpiOemId = OemId;
> +    PlatformInfoHob->AcpiOemTableId = OemTableId;
> +    return  EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/
> BoardOemIds.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/
> BoardOemIds.h
> new file mode 100644
> index 0000000000..3598a21a61
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/
> BoardOemIds.h
> @@ -0,0 +1,29 @@
> +/**@file
> +  ACPI oem ids setting for multiplatform.
> +
> +  This file includes package header files, library classes.
> +
> +  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +**/
> +
> +#include <Guid/PlatformInfo.h>
> +#include <Library/BaseMemoryLib.h>
> +
> +#define EFI_ACPI_OEM_ID_DEFAULT    SIGNATURE_64('I', 'N', 'T', 'E', 'L', ' ', '
> ', ' ')     // max 6 chars
> +#define EFI_ACPI_OEM_ID1           SIGNATURE_64('I', 'N', 'T', 'E', 'L', '1', ' ', ' ')
> // max 6 chars
> +#define EFI_ACPI_OEM_ID2           SIGNATURE_64('I', 'N', 'T', 'E', 'L', '2', ' ', ' ')
> // max 6 chars
> +
> +#define EFI_ACPI_OEM_TABLE_ID_DEFAULT   SIGNATURE_64('E', 'D', 'K', '2',
> ' ', ' ', ' ', ' ')
> +#define EFI_ACPI_OEM_TABLE_ID1          SIGNATURE_64('E', 'D', 'K', '2', '_',
> '1', ' ', ' ')
> +#define EFI_ACPI_OEM_TABLE_ID2          SIGNATURE_64('E', 'D', 'K', '2', '_',
> '2', ' ', ' ')
> +
> +
> +EFI_STATUS
> +InitializeBoardOemId (
> +  IN CONST EFI_PEI_SERVICES      **PeiServices,
> +  IN EFI_PLATFORM_INFO_HOB        *PlatformInfoHob
> +  );
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid/
> BoardSsidSvid.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid
> /BoardSsidSvid.c
> new file mode 100644
> index 0000000000..77764945c3
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid
> /BoardSsidSvid.c
> @@ -0,0 +1,38 @@
> +/** @file
> +  Subsystem IDs setting for multiplatform.
> +
> +  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +**/
> +
> +#include <BoardSsidSvid.h>
> +
> +//
> +// Global module data
> +//
> +EFI_STATUS
> +InitializeBoardSsidSvid (
> +    IN CONST EFI_PEI_SERVICES       **PeiServices,
> +    IN EFI_PLATFORM_INFO_HOB        *PlatformInfoHob
> +  )
> +{
> +    UINT32  SsidSvidValue = 0;
> +
> +    //
> +    // Set OEM ID according to Board ID.
> +    //
> +    switch (PlatformInfoHob->BoardId) {
> +      case BOARD_ID_MINNOW2:
> +      case BOARD_ID_MINNOW2_TURBOT:
> +      default:
> +        SsidSvidValue =
> SUBSYSTEM_SVID_SSID;//SUBSYSTEM_SVID_SSID_DEFAULT;
> +        break;
> +      }
> +    PlatformInfoHob->SsidSvid = SsidSvidValue;
> +    return  EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid/
> BoardSsidSvid.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid
> /BoardSsidSvid.h
> new file mode 100644
> index 0000000000..6a9995c34c
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid
> /BoardSsidSvid.h
> @@ -0,0 +1,35 @@
> +/**@file
> +  Subsystem IDs setting for multiplatform.
> +
> +  This file includes package header files, library classes.
> +
> +  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +**/
> +
> +#include <Guid/PlatformInfo.h>
> +#include <Library/BaseMemoryLib.h>
> +
> +//
> +// Default Vendor ID and Subsystem ID
> +//
> +#define SUBSYSTEM_VENDOR_ID1   0x8086
> +#define SUBSYSTEM_DEVICE_ID1   0x1999
> +#define SUBSYSTEM_SVID_SSID1   (SUBSYSTEM_VENDOR_ID1 +
> (SUBSYSTEM_DEVICE_ID1 << 16))
> +
> +#define SUBSYSTEM_VENDOR_ID2   0x8086
> +#define SUBSYSTEM_DEVICE_ID2   0x1888
> +#define SUBSYSTEM_SVID_SSID2   (SUBSYSTEM_VENDOR_ID2 +
> (SUBSYSTEM_DEVICE_ID2 << 16))
> +
> +#define SUBSYSTEM_VENDOR_ID   0x8086
> +#define SUBSYSTEM_DEVICE_ID   0x1234
> +#define SUBSYSTEM_SVID_SSID   (SUBSYSTEM_VENDOR_ID +
> (SUBSYSTEM_DEVICE_ID << 16))
> +
> +EFI_STATUS
> +InitializeBoardSsidSvid (
> +    IN CONST EFI_PEI_SERVICES       **PeiServices,
> +    IN EFI_PLATFORM_INFO_HOB        *PlatformInfoHob
> +  );
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformL
> ib.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatform
> Lib.c
> new file mode 100644
> index 0000000000..d24e90c7f4
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatform
> Lib.c
> @@ -0,0 +1,120 @@
> +/** @file
> +  Multiplatform initialization.
> +
> +  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +**/
> +
> +#include <MultiPlatformLib.h>
> +
> +/**
> +  Platform Type detection. Because the PEI globle variable
> +  is in the flash, it could not change directly.So use
> +  2 PPIs to distinguish the platform type.
> +
> +  @param FfsHeader       Pointer to Firmware File System file header.
> +  @param PeiServices     General purpose services available to every PEIM.
> +
> +  @retval EFI_SUCCESS    Memory initialization completed successfully.
> +  @retval Others         All other error conditions encountered result in an
> ASSERT.
> +
> +**/
> +EFI_STATUS
> +MultiPlatformInfoInit (
> +  IN CONST EFI_PEI_SERVICES             **PeiServices,
> +  IN OUT EFI_PLATFORM_INFO_HOB          *PlatformInfoHob
> +  )
> +{
> +  UINT32 PcieLength;
> +
> +
> +  PlatformInfoHob->IohSku = MmPci16(0, MC_BUS, MC_DEV, MC_FUN,
> PCI_DEVICE_ID_OFFSET);
> +
> +  PlatformInfoHob->IohRevision = MmPci8(0, MC_BUS, MC_DEV, MC_FUN,
> PCI_REVISION_ID_OFFSET);
> +
> +  //
> +  // Update ICH Type
> +  //
> +  //
> +  // Device ID
> +  //
> +  PlatformInfoHob->IchSku = PchLpcPciCfg16(PCI_DEVICE_ID_OFFSET);
> +
> +  PlatformInfoHob->IchRevision = PchLpcPciCfg8(PCI_REVISION_ID_OFFSET);
> +
> +  //
> +  //64MB
> +  //
> +  PcieLength = 0x04000000;
> +
> +  //
> +  // Don't support BASE above 4GB currently.
> +  //
> +  PlatformInfoHob->PciData.PciExpressSize     = PcieLength;
> +  PlatformInfoHob->PciData.PciExpressBase     = PcdGet64
> (PcdPciExpressBaseAddress);
> +
> +  PlatformInfoHob->PciData.PciResourceMem32Base  = (UINT32)
> (PlatformInfoHob->PciData.PciExpressBase - RES_MEM32_MIN_LEN);
> +  PlatformInfoHob->PciData.PciResourceMem32Limit = (UINT32)
> (PlatformInfoHob->PciData.PciExpressBase -1);
> +
> +  PlatformInfoHob->PciData.PciResourceMem64Base   =
> RES_MEM64_36_BASE;
> +  PlatformInfoHob->PciData.PciResourceMem64Limit  =
> RES_MEM64_36_LIMIT;
> +  PlatformInfoHob->CpuData.CpuAddressWidth        = 36;
> +
> +  PlatformInfoHob->MemData.MemMir0 = PlatformInfoHob-
> >PciData.PciResourceMem64Base;
> +  PlatformInfoHob->MemData.MemMir1 = PlatformInfoHob-
> >PciData.PciResourceMem64Limit + 1;
> +
> +  PlatformInfoHob->PciData.PciResourceMinSecBus  = 1;  //can be changed
> by SystemConfiguration->PciMinSecondaryBus;
> +
> +  //
> +  // Set MemMaxTolm to the lowest address between PCIe Base and PCI32
> Base.
> +  //
> +  if (PlatformInfoHob->PciData.PciExpressBase > PlatformInfoHob-
> >PciData.PciResourceMem32Base ) {
> +    PlatformInfoHob->MemData.MemMaxTolm = (UINT32)
> PlatformInfoHob->PciData.PciResourceMem32Base;
> +  } else {
> +    PlatformInfoHob->MemData.MemMaxTolm = (UINT32)
> PlatformInfoHob->PciData.PciExpressBase;
> +  }
> +  PlatformInfoHob->MemData.MemTolm = PlatformInfoHob-
> >MemData.MemMaxTolm;
> +
> +  //
> +  // Platform PCI MMIO Size in unit of 1MB.
> +  //
> +  PlatformInfoHob->MemData.MmioSize = 0x1000 -
> (UINT16)(PlatformInfoHob->MemData.MemMaxTolm >> 20);
> +
> +  //
> +  // Enable ICH IOAPIC
> +  //
> +  PlatformInfoHob->SysData.SysIoApicEnable  = ICH_IOAPIC;
> +
> +  DEBUG ((EFI_D_ERROR, "PlatformFlavor is %x
> (%x=tablet,%x=mobile,%x=desktop)\n",
> +    PlatformInfoHob->PlatformFlavor,
> +    FlavorTablet,
> +    FlavorMobile,
> +    FlavorDesktop));
> +
> +  //
> +  // Get Platform Info and fill the Hob.
> +  //
> +  PlatformInfoHob->RevisonId = PLATFORM_INFO_HOB_REVISION;
> +
> +  //
> +  // Get GPIO table
> +  //
> +  MultiPlatformGpioTableInit (PeiServices, PlatformInfoHob);
> +
> +  //
> +  // Program GPIO
> +  //
> +  MultiPlatformGpioProgram (PeiServices, PlatformInfoHob);
> +
> +  //
> +  // Update OemId
> +  //
> +  InitializeBoardOemId (PeiServices, PlatformInfoHob);
> +  InitializeBoardSsidSvid (PeiServices, PlatformInfoHob);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformL
> ib.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatform
> Lib.h
> new file mode 100644
> index 0000000000..807ca20acb
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatform
> Lib.h
> @@ -0,0 +1,89 @@
> +/**@file
> +  Multiplatform initialization header file.
> +
> +  This file includes package header files, library classes.
> +
> +  Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +**/
> +
> +#ifndef _MULTIPLATFORM_LIB_H_
> +#define _MULTIPLATFORM_LIB_H_
> +
> +
> +#define LEN_64M       0x4000000
> +
> +//
> +// Default PCI32 resource size
> +//
> +#define RES_MEM32_MIN_LEN   0x38000000
> +
> +#define RES_IO_BASE   0x0D00
> +#define RES_IO_LIMIT  0xFFFF
> +
> +#include <PiDxe.h>
> +#include <Library/BaseLib.h>
> +#include <FrameworkPei.h>
> +
> +#include "PlatformBaseAddresses.h"
> +#include "PchAccess.h"
> +#include "SetupMode.h"
> +#include "PlatformBootMode.h"
> +#include "Platform.h"
> +
> +#include <Ppi/Stall.h>
> +#include <Guid/SetupVariable.h>
> +#include <Ppi/AtaController.h>
> +#include <Ppi/FindFv.h>
> +#include <Ppi/BootInRecoveryMode.h>
> +#include <Ppi/ReadOnlyVariable2.h>
> +#include <Ppi/Capsule.h>
> +#include <Guid/EfiVpdData.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/BaseLib.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <Ppi/Speaker.h>
> +#include <Guid/FirmwareFileSystem.h>
> +#include <Guid/MemoryTypeInformation.h>
> +#include <Ppi/Cache.h>
> +#include <Ppi/Reset.h>
> +#include <Ppi/EndOfPeiPhase.h>
> +#include <Ppi/MemoryDiscovered.h>
> +#include <Guid/GlobalVariable.h>
> +#include <Ppi/RecoveryModule.h>
> +#include <Ppi/DeviceRecoveryModule.h>
> +#include <Guid/Capsule.h>
> +#include <Guid/RecoveryDevice.h>
> +#include <Ppi/MasterBootMode.h>
> +#include <Guid/PlatformInfo.h>
> +
> +#include <BoardOemIds/BoardOemIds.h>
> +#include <BoardSsidSvid/BoardSsidSvid.h>
> +
> +
> +EFI_STATUS
> +GetPlatformInfoHob (
> +  IN CONST EFI_PEI_SERVICES           **PeiServices,
> +  OUT EFI_PLATFORM_INFO_HOB     **PlatformInfoHob
> +  );
> +
> +EFI_STATUS
> +MultiPlatformGpioTableInit (
> +  IN CONST EFI_PEI_SERVICES     **PeiServices,
> +  IN EFI_PLATFORM_INFO_HOB      *PlatformInfoHob
> +  );
> +
> +EFI_STATUS
> +MultiPlatformGpioProgram (
> +  IN CONST EFI_PEI_SERVICES     **PeiServices,
> +  IN EFI_PLATFORM_INFO_HOB      *PlatformInfoHob
> +  );
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformL
> ib.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatform
> Lib.inf
> new file mode 100644
> index 0000000000..758e47ca70
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatform
> Lib.inf
> @@ -0,0 +1,77 @@
> +#
> +#
> +# Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +#
> +#
> +#  Module Name:
> +#
> +#   MultiPlatform.inf
> +#
> +#  Abstract:
> +#
> +#
> +--*/
> +
> +
> +[defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = MultiPlatformLib
> +  FILE_GUID                      = AB83A52B-B44A-462c-B099-444CC0ED274D
> +  MODULE_TYPE                    = PEIM
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = MultiPlatformLib
> +  PI_SPECIFICATION_VERSION       = 0x0001000A
> +
> +[sources]
> +  MultiPlatformLib.c
> +  MultiPlatformLib.h
> +  PlatformInfoHob.c
> +#GPIO
> +  BoardGpios/BoardGpios.c
> +  BoardGpios/BoardGpios.h
> +
> +#ClkGen
> +  BoardClkGens/BoardClkGens.c
> +  BoardClkGens/BoardClkGens.h
> +
> +#Jumper
> +  BoardJumpers/BoardJumpers.c
> +  BoardJumpers/BoardJumpers.h
> +
> +#OemId
> +  BoardOemIds/BoardOemIds.c
> +  BoardOemIds/BoardOemIds.h
> +
> +#SSIDSVID
> +  BoardSsidSvid/BoardSsidSvid.c
> +  BoardSsidSvid/BoardSsidSvid.h
> +[Guids]
> +
> +  gEfiPlatformInfoGuid                     # ALWAYS_CONSUMED
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  IntelFrameworkPkg/IntelFrameworkPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +  Vlv2SocBinPkg/Vlv2SocBinPkg.dec
> +
> +[LibraryClasses]
> +  DebugLib
> +  HobLib
> +  IoLib
> +#  PeiKscLib
> +
> +[Ppis]
> +  gEfiPeiReadOnlyVariable2PpiGuid
> +
> +[Pcd.common]
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +
> +[Guids]
> +  gEfiSetupVariableGuid
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/PlatformInfoH
> ob.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/PlatformInfoH
> ob.c
> new file mode 100644
> index 0000000000..efa3619a76
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/PlatformInfoH
> ob.c
> @@ -0,0 +1,54 @@
> +/** @file
> +  Platform Hob access interface for multiplatform.
> +
> +  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +**/
> +
> +#include <MultiPlatformLib.h>
> +
> +/**
> +  Returns the Platform Info of the platform from the HOB.
> +
> +  @param PeiServices         General purpose services available to every PEIM.
> +  @param PlatformInfoHob     Pointer to the PLATFORM_INFO_HOB Pointer
> +
> +  @retval EFI_SUCCESS        The function completed successfully.
> +  @retval EFI_NOT_FOUND      PlatformInfoHob data doesn't exist, use
> default instead.
> +
> +**/
> +EFI_STATUS
> +GetPlatformInfoHob (
> +  IN CONST EFI_PEI_SERVICES           **PeiServices,
> +  OUT EFI_PLATFORM_INFO_HOB     **PlatformInfoHob
> +  )
> +{
> +  EFI_PEI_HOB_POINTERS        GuidHob;
> +
> +  //
> +  // Find the PlatformInfo HOB
> +  //
> +  GuidHob.Raw = GetHobList ();
> +  if (GuidHob.Raw == NULL) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformInfoGuid,
> GuidHob.Raw)) != NULL) {
> +    *PlatformInfoHob = GET_GUID_HOB_DATA (GuidHob.Guid);
> +  }
> +
> +  //
> +  // PlatformInfo PEIM should provide this HOB data, if not ASSERT and
> return error.
> +  //
> +  ASSERT (*PlatformInfoHob != NULL);
> +  if (!(*PlatformInfoHob)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLib.i
> nf
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLib.i
> nf
> new file mode 100644
> index 0000000000..6b5cc2861c
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLib.i
> nf
> @@ -0,0 +1,50 @@
> +#
> +#
> +#/*++
> +#
> +#  Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +#
> +#  Module Name:
> +#
> +#    PeiDxePchPlatformLib.inf
> +#
> +#  Abstract:
> +#
> +#    Component description file for PEI/DXE PCH Platform Lib
> +#
> +#--*/
> +
> +[defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = PchPlatformLib
> +  FILE_GUID                      = 32F89CBC-305D-4bdd-8B2C-9C65592E66AC
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = PchPlatformLib
> +
> +[sources.common]
> +  PchPlatformLibrary.h
> +  PchPlatformLibrary.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  PciLib
> +  IoLib
> +  DebugLib
> +
> +
> +[Pcd.common]
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +
> +
> +[Protocols]
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibr
> ary.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibr
> ary.c
> new file mode 100644
> index 0000000000..c31fd754cb
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibr
> ary.c
> @@ -0,0 +1,131 @@
> +/**
> +
> +Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +  @file
> +  PchPlatformLib.c
> +
> +  @brief
> +  PCH Platform Lib implementation.
> +
> +**/
> +
> +#include "PchPlatformLibrary.h"
> +
> +//
> +// Silicon Steppings
> +//
> +/**
> +  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;
> +
> +    case V_PCH_LPC_RID_E:
> +    case V_PCH_LPC_RID_F:
> +      return PchD0;
> +      break;
> +
> +    default:
> +      return PchSteppingMax;
> +      break;
> +
> +  }
> +}
> +
> +/**
> +  Determine if PCH is supported
> +
> +  @param[in] None
> +
> +  @retval TRUE                    PCH is supported
> +  @retval FALSE                   PCH is not supported
> +
> +**/
> +BOOLEAN
> +IsPchSupported (
> +  VOID
> +  )
> +{
> +  UINT32  Identifiers;
> +  UINT16  PcuVendorId;
> +  UINT16  PcuDeviceId;
> +
> +  Identifiers = MmioRead32 (
> +                  MmPciAddress (0,
> +                  DEFAULT_PCI_BUS_NUMBER_PCH,
> +                  PCI_DEVICE_NUMBER_PCH_LPC,
> +                  PCI_FUNCTION_NUMBER_PCH_LPC,
> +                  R_PCH_LPC_REG_ID)
> +                );
> +
> +  PcuDeviceId = (UINT16) ((Identifiers & B_PCH_LPC_DEVICE_ID) >> 16);
> +  PcuVendorId = (UINT16) (Identifiers & B_PCH_LPC_VENDOR_ID);
> +
> +  //
> +  // Verify that this is a supported chipset
> +  //
> +  if (PcuVendorId != (UINT16) V_PCH_LPC_VENDOR_ID
> || !IS_PCH_VLV_LPC_DEVICE_ID (PcuDeviceId)) {
> +    DEBUG ((EFI_D_ERROR, "VLV SC code doesn't support the PcuDeviceId:
> 0x%04x!\n", PcuDeviceId));
> +    return FALSE;
> +  }
> +  return TRUE;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibr
> ary.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibr
> ary.h
> new file mode 100644
> index 0000000000..da1f77f680
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibr
> ary.h
> @@ -0,0 +1,35 @@
> +/**
> +**/
> +/**
> +
> +Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +  @file
> +  PchPlatformLibrary.h
> +
> +  @brief
> +  Header file for PCH Platform Lib implementation.
> +
> +**/
> +
> +#ifndef _PCH_PLATFORM_LIBRARY_IMPLEMENTATION_H_
> +#define _PCH_PLATFORM_LIBRARY_IMPLEMENTATION_H_
> +
> +#include "PchAccess.h"
> +#ifdef ECP_FLAG
> +#include "EdkIIGlueBase.h"
> +#include "Library/EdkIIGlueMemoryAllocationLib.h"
> +#else
> +#include "Library/PciLib.h"
> +#include "Library/IoLib.h"
> +#include "Library/DebugLib.h"
> +#include "Library/PcdLib.h"
> +
> +#include "PchCommonDefinitions.h"
> +#endif
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/CommonHeader.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/CommonHeader.h
> new file mode 100644
> index 0000000000..e0a1f3a0f7
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/CommonHeader.h
> @@ -0,0 +1,32 @@
> +/**@file
> +  Common header file shared by all source files.
> +
> +  This file includes package header files, library classes and protocol, PPI &
> GUID definitions.
> +
> +  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +**/
> +
> +#ifndef __COMMON_HEADER_H_
> +#define __COMMON_HEADER_H_
> +
> +
> +#include <Base.h>
> +
> +#include <Library/TimerLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/DebugLib.h>
> +
> +#define R_PCH_ACPI_SMI_EN       0x30
> +#define B_PCH_ACPI_APMC_EN      0x00000020
> +#define B_PCH_ACPI_EOS          0x00000002
> +#define B_PCH_ACPI_GBL_SMI_EN   0x00000001
> +#define R_PCH_ACPI_SMI_STS      0x34
> +#define B_PCH_ACPI_APM_STS      0x00000020
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.c
> new file mode 100644
> index 0000000000..2b0aacaccf
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.c
> @@ -0,0 +1,157 @@
> +/** @file
> +  PCH Smm Library Services that implements both S/W SMI generation and
> detection.
> +
> +  Copyright (c) 2007  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +**/
> +
> +
> +#include "CommonHeader.h"
> +
> +
> +/**
> +  Triggers a run time or boot time SMI.
> +
> +  This function triggers a software SMM interrupt and set the APMC status
> with an 8-bit Data.
> +
> +  @param  Data                 The value to set the APMC status.
> +
> +**/
> +VOID
> +InternalTriggerSmi (
> +  IN UINT8                     Data
> +  )
> +{
> +  ASSERT(FALSE);
> +}
> +
> +
> +/**
> +  Triggers an SMI at boot time.
> +
> +  This function triggers a software SMM interrupt at boot time.
> +
> +**/
> +VOID
> +EFIAPI
> +TriggerBootServiceSoftwareSmi (
> +  VOID
> +  )
> +{
> +  ASSERT(FALSE);
> +}
> +
> +
> +/**
> +  Triggers an SMI at run time.
> +
> +  This function triggers a software SMM interrupt at run time.
> +
> +**/
> +VOID
> +EFIAPI
> +TriggerRuntimeSoftwareSmi (
> +  VOID
> +  )
> +{
> +  ASSERT(FALSE);
> +}
> +
> +
> +/**
> +  Gets the software SMI data.
> +
> +  This function tests if a software SMM interrupt happens. If a software SMI
> happens,
> +  it retrieves the SMM data and returns it as a non-negative value;
> otherwise a negative
> +  value is returned.
> +
> +  @return Data                 The data retrieved from SMM data port in case of a
> software SMI;
> +                               otherwise a negative value.
> +
> +**/
> +INTN
> +InternalGetSwSmiData (
> +  VOID
> +  )
> +{
> +  ASSERT(FALSE);
> +  return -1;
> +}
> +
> +
> +/**
> +  Test if a boot time software SMI happened.
> +
> +  This function tests if a software SMM interrupt happened. If a software
> SMM interrupt happened and
> +  it was triggered at boot time, it returns TRUE. Otherwise, it returns FALSE.
> +
> +  @retval TRUE   A software SMI triggered at boot time happened.
> +  @retval FLASE  No software SMI happened or the software SMI was
> triggered at run time.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +IsBootServiceSoftwareSmi (
> +  VOID
> +  )
> +{
> +  ASSERT(FALSE);
> +  return FALSE;
> +}
> +
> +
> +/**
> +  Test if a run time software SMI happened.
> +
> +  This function tests if a software SMM interrupt happened. If a software
> SMM interrupt happened and
> +  it was triggered at run time, it returns TRUE. Otherwise, it returns FALSE.
> +
> +  @retval TRUE   A software SMI triggered at run time happened.
> +  @retval FLASE  No software SMI happened or the software SMI was
> triggered at boot time.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +IsRuntimeSoftwareSmi (
> +  VOID
> +  )
> +{
> +  ASSERT(FALSE);
> +  return FALSE;
> +}
> +
> +
> +/**
> +
> +  Clear APM SMI Status Bit; Set the EOS bit.
> +
> +**/
> +VOID
> +EFIAPI
> +ClearSmi (
> +  VOID
> +  )
> +{
> +
> +  UINT16                       PmBase;
> +
> +  //
> +  // Get PMBase
> +  //
> +  PmBase = PcdGet16 (PcdPchAcpiIoPortBaseAddress);
> +
> +  //
> +  // Clear the APM SMI Status Bit
> +  //
> +  IoWrite16 (PmBase + R_PCH_ACPI_SMI_STS, B_PCH_ACPI_APM_STS);
> +
> +  //
> +  // Set the EOS Bit
> +  //
> +  IoOr32 (PmBase + R_PCH_ACPI_SMI_EN, B_PCH_ACPI_EOS);
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.inf
> new file mode 100644
> index 0000000000..9d4823d488
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.inf
> @@ -0,0 +1,46 @@
> +## @file
> +# Component description file for Intel Ich7 SMM Library.
> +#
> +# ICH SMM Library that layers on top of the I/O Library to directly
> +#  access SMM power management registers.
> +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +#
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = PchSmmLib
> +  FILE_GUID                      = A6A16CCB-91B0-42f4-B4F3-D17D7A5662E6
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = SmmLib
> +
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +
> +[Sources]
> +  PchSmmLib.c
> +
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +
> +[LibraryClasses]
> +  PcdLib
> +  IoLib
> +
> +[Pcd]
> +  gEfiPchTokenSpaceGuid.PcdPchAcpiIoPortBaseAddress
> +
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.c
> new file mode 100644
> index 0000000000..4d5997d6e9
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.c
> @@ -0,0 +1,3098 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2019, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  BdsPlatform.c
> +
> +Abstract:
> +
> +  This file include all platform action which can be customized
> +  by IBV/OEM.
> +
> +--*/
> +
> +#include "BdsPlatform.h"
> +#include "SetupMode.h"
> +#include <Guid/SetupVariable.h>
> +#include <Library/TcgPhysicalPresenceLib.h>
> +#include <Library/Tcg2PhysicalPresenceLib.h>
> +#include <Protocol/I2cMasterMcg.h>
> +#include <TianoApi.h>
> +#include <PlatformBaseAddresses.h>
> +#include <Protocol/GlobalNvsArea.h>
> +#include <Library/DxeServicesTableLib.h>
> +#include <Protocol/BlockIo.h>
> +#include <PchRegs/PchRegsPcu.h>
> +#include <Library/S3BootScriptLib.h>
> +#include "PchAccess.h"
> +#include "PchRegs/PchRegsSata.h"
> +#include <Library/SerialPortLib.h>
> +#include <Library/DebugLib.h>
> +
> +#include <Library/GenericBdsLib/InternalBdsLib.h>
> +#include <Library/GenericBdsLib/String.h>
> +#include <Library/NetLib.h>
> +
> +#include <Library/CapsuleLib.h>
> +#include <Protocol/EsrtManagement.h>
> +
> +EFI_GUID *ConnectDriverTable[] = {
> +  &gEfiMmioDeviceProtocolGuid,
> +  &gEfiI2cMasterProtocolGuid,
> +  &gEfiI2cHostProtocolGuid
> +};
> +
> +#define SHELL_ENVIRONMENT_INTERFACE_PROTOCOL \
> +  { \
> +    0x47c7b221, 0xc42a, 0x11d2, 0x8e, 0x57, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b
> \
> +  }
> +VOID               *mShellImageCallbackReg = NULL;
> +
> +
> +
> +EFI_USER_PROFILE_HANDLE                           mCurrentUser = NULL;
> +EFI_EVENT                                         mHotKeyTimerEvent = NULL;
> +EFI_EVENT                                         mHitHotkeyEvent = NULL;
> +EFI_EVENT                                         mUsbKeyboardConnectEvent = NULL;
> +BOOLEAN                                           mHotKeyPressed = FALSE;
> +VOID                                              *mHitHotkeyRegistration;
> +#define KEYBOARD_TIMER_INTERVAL                   20000 // 0.02s
> +
> +VOID
> +ConnectUSBController (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +PlatformBdsConnectSimpleConsole (
> +  IN BDS_CONSOLE_CONNECT_ENTRY   *PlatformConsole
> +);
> +
> +VOID
> +BootIntoFirmwareInterface(
> +  VOID
> +  );
> +
> +VOID
> +EFIAPI
> +PlatformBdsInitHotKeyEvent (
> +  VOID
> +  );
> +
> +VOID
> +EFIAPI
> +DisableAhciCtlr (
> +  IN EFI_EVENT                          Event,
> +  IN VOID                               *Context
> +  )
> +{
> +  UINT32                    PmcDisableAddress;
> +  UINT8                     SataStorageAmount;
> +  UINT32                    SataBase;
> +  UINT16                    SataPortStatus;
> +
> +
> +  DEBUG ((EFI_D_INFO, "Disable AHCI event is signalled\n"));
> +  SataStorageAmount = 0;
> +  SataBase = *(UINT32*) Context;
> +
> +  //
> +  // BayTrail-M EDS chapter 16 ---- PCI IO Register Offset 92 (SATA Port
> Control and Status)
> +  //
> +  SataPortStatus = MmioRead16 (SataBase + R_PCH_SATA_PCS);
> +
> +  //
> +  // Bit 8 EN: Port 0 Present
> +  //
> +  if ((SataPortStatus & 0x100) == 0x100) {
> +    SataStorageAmount++;
> +  }
> +
> +  //
> +  // Bit 9 EN: Port 1 Present
> +  //
> +  if ((SataPortStatus & 0x200) == 0x200) {
> +    SataStorageAmount++;
> +  }
> +
> +  //
> +  // Disable SATA controller when it sets to AHCI mode without carrying any
> devices
> +  // in order to prevent AHCI yellow bang under Win device manager.
> +  //
> +  if (SataStorageAmount == 0) {
> +    PmcDisableAddress = (MmioRead32 ((PCH_PCI_EXPRESS_BASE_ADDRESS
> + (UINT32) (31 << 15)) + R_PCH_LPC_PMC_BASE) &
> B_PCH_LPC_PMC_BASE_BAR) + R_PCH_PMC_FUNC_DIS;
> +    MmioOr32 (PmcDisableAddress, B_PCH_PMC_FUNC_DIS_SATA);
> +    S3BootScriptSaveMemWrite (
> +      EfiBootScriptWidthUint32,
> +      (UINTN) PmcDisableAddress,
> +      1,
> +      (VOID *) (UINTN) PmcDisableAddress
> +      );
> +  }
> +}
> +
> +VOID
> +InstallReadyToLock (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                Status;
> +  EFI_HANDLE                Handle;
> +  EFI_SMM_ACCESS2_PROTOCOL  *SmmAccess;
> +  EFI_ACPI_S3_SAVE_PROTOCOL *AcpiS3Save;
> +
> +  //
> +  // Install DxeSmmReadyToLock protocol prior to the processing of boot
> options
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiSmmAccess2ProtocolGuid,
> +                  NULL,
> +                  (VOID **) &SmmAccess
> +                  );
> +  if (!EFI_ERROR (Status)) {
> +
> +    //
> +    // Prepare S3 information, this MUST be done before
> DxeSmmReadyToLock
> +    //
> +    Status = gBS->LocateProtocol (
> +                    &gEfiAcpiS3SaveProtocolGuid,
> +                    NULL,
> +                    (VOID **)&AcpiS3Save
> +                    );
> +    if (!EFI_ERROR (Status)) {
> +      AcpiS3Save->S3Save (AcpiS3Save, NULL);
> +    }
> +
> +    Handle = NULL;
> +    Status = gBS->InstallProtocolInterface (
> +                    &Handle,
> +                    &gExitPmAuthProtocolGuid,
> +                    EFI_NATIVE_INTERFACE,
> +                    NULL
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    //
> +    // Signal EndOfDxe PI Event
> +    //
> +    EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);
> +
> +    Handle = NULL;
> +    Status = gBS->InstallProtocolInterface (
> +                    &Handle,
> +                    &gEfiDxeSmmReadyToLockProtocolGuid,
> +                    EFI_NATIVE_INTERFACE,
> +                    NULL
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +  return ;
> +}
> +
> +VOID
> +EFIAPI
> +ShellImageCallback (
> +  IN EFI_EVENT                          Event,
> +  IN VOID                               *Context
> +  )
> +{
> + BdsSetConsoleMode (TRUE);
> + DEBUG ((EFI_D_INFO, "BdsEntry ShellImageCallback \n"));
> +}
> +
> +//
> +// BDS Platform Functions
> +//
> +/**
> +  Platform Bds init. Include the platform firmware vendor, revision
> +  and so crc check.
> +
> +  @param VOID
> +
> +  @retval  None.
> +
> +**/
> +VOID
> +EFIAPI
> +PlatformBdsInit (
> +  VOID
> +  )
> +{
> +  EFI_STATUS  Status;
> +  EFI_EVENT   ShellImageEvent;
> +  EFI_GUID    ShellEnvProtocol =
> SHELL_ENVIRONMENT_INTERFACE_PROTOCOL;
> +
> +  #ifdef __GNUC__
> +  SerialPortWrite((UINT8 *)">>>>BdsEntry[GCC]\r\n", 19);
> +  #else
> +  SerialPortWrite((UINT8 *)">>>>BdsEntry\r\n", 14);
> +  #endif
> +  BdsLibSaveMemoryTypeInformation ();
> +
> +  //
> +  // Before user authentication, the user identification devices need be
> connected
> +  // from the platform customized device paths
> +  //
> +  PlatformBdsConnectAuthDevice ();
> +
> +  //
> +  // As console is not ready, the auto logon user will be identified.
> +  //
> +  BdsLibUserIdentify (&mCurrentUser);
> +
> +  //
> +  // Change Gop mode when boot into Shell
> +  //
> +  if (mShellImageCallbackReg == NULL) {
> +    Status = gBS->CreateEvent (
> +                    EFI_EVENT_NOTIFY_SIGNAL,
> +                    EFI_TPL_CALLBACK,
> +                    ShellImageCallback,
> +                    NULL,
> +                    &ShellImageEvent
> +                    );
> +    if (!EFI_ERROR (Status)) {
> +      Status = gBS->RegisterProtocolNotify (
> +                      &ShellEnvProtocol,
> +                      ShellImageEvent,
> +                      &mShellImageCallbackReg
> +                      );
> +
> +      DEBUG ((EFI_D_INFO, "BdsEntry ShellImageCallback \n"));
> +    }
> +  }
> +}
> +
> +EFI_STATUS
> +GetGopDevicePath (
> +   IN  EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,
> +   OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath
> +   )
> +{
> +  UINTN                           Index;
> +  EFI_STATUS                      Status;
> +  EFI_HANDLE                      PciDeviceHandle;
> +  EFI_DEVICE_PATH_PROTOCOL        *TempDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL        *TempPciDevicePath;
> +  UINTN                           GopHandleCount;
> +  EFI_HANDLE                      *GopHandleBuffer;
> +
> +  UINTN                                 VarSize;
> +  SYSTEM_CONFIGURATION  mSystemConfiguration;
> +
> +  if (PciDevicePath == NULL || GopDevicePath == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Initialize the GopDevicePath to be PciDevicePath
> +  //
> +  *GopDevicePath    = PciDevicePath;
> +  TempPciDevicePath = PciDevicePath;
> +
> +  Status = gBS->LocateDevicePath (
> +                  &gEfiDevicePathProtocolGuid,
> +                  &TempPciDevicePath,
> +                  &PciDeviceHandle
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Try to connect this handle, so that GOP driver could start on this
> +  // device and create child handles with GraphicsOutput Protocol installed
> +  // on them, then we get device paths of these child handles and select
> +  // them as possible console device.
> +  //
> +
> +  //
> +  // Select display devices
> +  //
> +  VarSize = sizeof(SYSTEM_CONFIGURATION);
> +  Status = gRT->GetVariable(
> +                  L"Setup",
> +                  &gEfiNormalSetupGuid,
> +                  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",
> +              &gEfiNormalSetupGuid,
> +              NULL,
> +              &VarSize,
> +              &mSystemConfiguration
> +              );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +  if(mSystemConfiguration.BootDisplayDevice != 0x0)
> +  {
> +    ACPI_ADR_DEVICE_PATH         AcpiAdr;
> +    EFI_DEVICE_PATH_PROTOCOL  *MyDevicePath = NULL;
> +
> +    AcpiAdr.Header.Type     = ACPI_DEVICE_PATH;
> +    AcpiAdr.Header.SubType  = ACPI_ADR_DP;
> +
> +    switch (mSystemConfiguration.BootDisplayDevice) {
> +    case 1:
> +      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0,
> ACPI_ADR_DISPLAY_TYPE_VGA, PORT_CRT, 0);    //CRT Device
> +      break;
> +    case 2:
> +      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0,
> ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_B_HDMI, 0);  //HDMI
> Device Port B
> +      break;
> +    case 3:
> +      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0,
> ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_B_DP, 0);    //DP PortB
> +      break;
> +    case 4:
> +      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0,
> ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_C_DP, 0);    //DP PortC
> +      break;
> +    case 5:
> +      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0,
> ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_C_DP, 0);    //eDP Port
> C
> +      break;
> +    case 6:
> +      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0,
> ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_MIPI_A, 0);  //DSI Port
> A
> +      break;
> +    case 7:
> +      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0,
> ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_MIPI_C, 0);  //DSI Port
> C
> +      break;
> +    default:
> +      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0,
> ACPI_ADR_DISPLAY_TYPE_VGA, PORT_CRT, 0);
> +      break;
> +    }
> +
> +    SetDevicePathNodeLength (&AcpiAdr.Header, sizeof
> (ACPI_ADR_DEVICE_PATH));
> +
> +    MyDevicePath = AppendDevicePathNode(MyDevicePath,
> (EFI_DEVICE_PATH_PROTOCOL*)&AcpiAdr);
> +
> +    gBS->ConnectController (
> +           PciDeviceHandle,
> +           NULL,
> +           MyDevicePath,
> +           FALSE
> +           );
> +
> +    FreePool(MyDevicePath);
> +  }
> +  else
> +  {
> +    gBS->ConnectController (
> +           PciDeviceHandle,
> +           NULL,
> +           NULL,
> +           FALSE
> +           );
> +  }
> +
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gEfiGraphicsOutputProtocolGuid,
> +                  NULL,
> +                  &GopHandleCount,
> +                  &GopHandleBuffer
> +                  );
> +  if (!EFI_ERROR (Status)) {
> +    //
> +    // Add all the child handles as possible Console Device
> +    //
> +    for (Index = 0; Index < GopHandleCount; Index++) {
> +      Status = gBS->HandleProtocol (
> +                      GopHandleBuffer[Index],
> +                      &gEfiDevicePathProtocolGuid,
> +                      (VOID**)&TempDevicePath
> +                      );
> +      if (EFI_ERROR (Status)) {
> +        continue;
> +      }
> +      if (CompareMem (
> +            PciDevicePath,
> +            TempDevicePath,
> +            GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH
> +            ) == 0) {
> +        //
> +        // In current implementation, we only enable one of the child handles
> +        // as console device, i.e. sotre one of the child handle's device
> +        // path to variable "ConOut"
> +        // In future, we could select all child handles to be console device
> +        //
> +        *GopDevicePath = TempDevicePath;
> +      }
> +    }
> +    gBS->FreePool (GopHandleBuffer);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +  Search out all the platform pci or agp video device. The function may will
> +  find multiple video device, and return all enabled device path.
> +
> +  @param PlugInPciVgaDevicePath    Return the platform plug in pci video
> device
> +                                   path if the system have plug in pci video device.
> +  @param OnboardPciVgaDevicePath   Return the platform active agp video
> device path
> +                                   if the system have plug in agp video device or on
> +                                   chip agp device.
> +
> +  @retval EFI_SUCCSS               Get all platform active video device path.
> +  @retval EFI_STATUS               Return the status of gBS->LocateDevicePath (),
> +                                   gBS->ConnectController (),
> +                                   and gBS->LocateHandleBuffer ().
> +
> +**/
> +EFI_STATUS
> +GetPlugInPciVgaDevicePath (
> +  IN OUT EFI_DEVICE_PATH_PROTOCOL     **PlugInPciVgaDevicePath,
> +  IN OUT EFI_DEVICE_PATH_PROTOCOL     **OnboardPciVgaDevicePath
> +  )
> +{
> +  EFI_STATUS                Status;
> +  EFI_HANDLE                RootHandle;
> +  UINTN                     HandleCount;
> +  EFI_HANDLE                *HandleBuffer;
> +  UINTN                     Index;
> +  UINTN                     Index1;
> +  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
> +  BOOLEAN                   PlugInPciVga;
> +  EFI_PCI_IO_PROTOCOL       *PciIo;
> +  PCI_TYPE00                Pci;
> +
> +  DevicePath = NULL;
> +  PlugInPciVga = TRUE;
> +  HandleCount = 0;
> +  HandleBuffer = NULL;
> +
> +  //
> +  // Make all the PCI_IO protocols on PCI Seg 0 show up
> +  //
> +  BdsLibConnectDevicePath (gPlatformRootBridges[0]);
> +
> +  Status = gBS->LocateDevicePath (
> +                  &gEfiDevicePathProtocolGuid,
> +                  &gPlatformRootBridges[0],
> +                  &RootHandle
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = gBS->ConnectController (
> +                  RootHandle,
> +                  NULL,
> +                  NULL,
> +                  FALSE
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Start to check all the pci io to find all possible VGA device
> +  //
> +  HandleCount = 0;
> +  HandleBuffer = NULL;
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gEfiPciIoProtocolGuid,
> +                  NULL,
> +                  &HandleCount,
> +                  &HandleBuffer
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  for (Index = 0; Index < HandleCount; Index++) {
> +    Status = gBS->HandleProtocol (
> +                    HandleBuffer[Index],
> +                    &gEfiPciIoProtocolGuid,
> +                    (VOID**)&PciIo
> +                    );
> +    if (!EFI_ERROR (Status)) {
> +
> +      //
> +      // Check for all VGA device
> +      //
> +      Status = PciIo->Pci.Read (
> +                        PciIo,
> +                        EfiPciIoWidthUint32,
> +                        0,
> +                        sizeof (Pci) / sizeof (UINT32),
> +                        &Pci
> +                        );
> +      if (EFI_ERROR (Status)) {
> +        continue;
> +      }
> +
> +      //
> +      // Here we decide which VGA device to enable in PCI bus
> +      //
> +      // The first plugin PCI VGA card device will be present as PCI VGA
> +      // The onchip AGP or AGP card will be present as AGP VGA
> +      //
> +      if (!IS_PCI_VGA (&Pci)) {
> +        continue;
> +      }
> +
> +      //
> +      // Set the device as the possible console out device,
> +      //
> +      // Below code will make every VGA device to be one
> +      // of the possibe console out device
> +      //
> +      PlugInPciVga = TRUE;
> +      gBS->HandleProtocol (
> +             HandleBuffer[Index],
> +             &gEfiDevicePathProtocolGuid,
> +             (VOID**)&DevicePath
> +             );
> +
> +      Index1 = 0;
> +
> +      while (gPlatformAllPossiblePciVgaConsole[Index1] != NULL) {
> +        if (CompareMem (
> +              DevicePath,
> +              gPlatformAllPossiblePciVgaConsole[Index1],
> +              GetDevicePathSize (gPlatformAllPossiblePciVgaConsole[Index1])
> +              ) == 0) {
> +
> +          //
> +          // This device is an AGP device
> +          //
> +          *OnboardPciVgaDevicePath = DevicePath;
> +          PlugInPciVga = FALSE;
> +          break;
> +        }
> +
> +        Index1 ++;
> +      }
> +
> +      if (PlugInPciVga) {
> +        *PlugInPciVgaDevicePath = DevicePath;
> +      }
> +    }
> +  }
> +
> +  FreePool (HandleBuffer);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +  Find the platform  active vga, and base on the policy to enable the vga as
> +  the console out device. The policy is driven by one setup variable "VBIOS".
> +
> +  None.
> +
> +  @param EFI_UNSUPPORTED         There is no active vga device
> +
> +  @retval EFI_STATUS             Return the status of BdsLibGetVariableAndSize
> ()
> +
> +**/
> +EFI_STATUS
> +PlatformBdsForceActiveVga (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                Status;
> +  EFI_DEVICE_PATH_PROTOCOL  *PlugInPciVgaDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL  *OnboardPciVgaDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL  *DevicePathFirst;
> +  EFI_DEVICE_PATH_PROTOCOL  *DevicePathSecond;
> +  EFI_DEVICE_PATH_PROTOCOL  *GopDevicePath;
> +  UINTN                VarSize;
> +  SYSTEM_CONFIGURATION  mSystemConfiguration;
> +
> +  Status = EFI_SUCCESS;
> +  PlugInPciVgaDevicePath = NULL;
> +  OnboardPciVgaDevicePath = NULL;
> +
> +  //
> +  // Check the policy which is the first enabled VGA
> +  //
> +  GetPlugInPciVgaDevicePath (&PlugInPciVgaDevicePath,
> &OnboardPciVgaDevicePath);
> +
> +  if (PlugInPciVgaDevicePath == NULL && OnboardPciVgaDevicePath ==
> NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  VarSize = sizeof(SYSTEM_CONFIGURATION);
> +  Status = gRT->GetVariable(
> +                  L"Setup",
> +                  &gEfiNormalSetupGuid,
> +                  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",
> +              &gEfiNormalSetupGuid,
> +              NULL,
> +              &VarSize,
> +              &mSystemConfiguration
> +              );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +
> +  if ((PlugInPciVgaDevicePath == NULL && OnboardPciVgaDevicePath !=
> NULL) ) {
> +    DEBUG ((EFI_D_ERROR,"Update onboard PCI VGA ...\n"));
> +    DevicePathFirst  = OnboardPciVgaDevicePath;
> +    DevicePathSecond = PlugInPciVgaDevicePath;
> +    goto UpdateConOut;
> +  }
> +  if(OnboardPciVgaDevicePath != NULL &&
> mSystemConfiguration.PrimaryVideoAdaptor == 0) {
> +    DEBUG ((EFI_D_ERROR,"Update onboard PCI VGA When set
> primary!!!...\n"));
> +    DevicePathFirst  = OnboardPciVgaDevicePath;
> +    DevicePathSecond = PlugInPciVgaDevicePath;
> +    goto UpdateConOut;
> +  }
> +
> +  DEBUG ((EFI_D_ERROR,"Update plug in PCI VGA ...\n"));
> +  DevicePathFirst  = PlugInPciVgaDevicePath;
> +  DevicePathSecond = OnboardPciVgaDevicePath;
> +
> +UpdateConOut:
> +  GetGopDevicePath (DevicePathFirst, &GopDevicePath);
> +  DevicePathFirst = GopDevicePath;
> +
> +  Status = BdsLibUpdateConsoleVariable (
> +             L"ConOut",
> +             DevicePathFirst,
> +             DevicePathSecond
> +             );
> +
> +  return Status;
> +}
> +
> +VOID
> +UpdateConsoleResolution(
> +  VOID
> +  )
> +{
> +  UINT32                 HorizontalResolution;
> +  UINT32                 VerticalResolution;
> +  SYSTEM_CONFIGURATION   SystemConfiguration;
> +  UINTN                  VarSize;
> +  EFI_STATUS             Status;
> +
> +
> +  HorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
> +  VerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);
> +
> +  VarSize = sizeof(SYSTEM_CONFIGURATION);
> +  Status = gRT->GetVariable(
> +                  L"Setup",
> +                  &gEfiNormalSetupGuid,
> +                  NULL,
> +                  &VarSize,
> +                  &SystemConfiguration
> +                  );
> +  if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
> +    //The setup variable is corrupted
> +    VarSize = sizeof(SYSTEM_CONFIGURATION);
> +    Status = gRT->GetVariable(
> +              L"SetupRecovery",
> +              &gEfiNormalSetupGuid,
> +              NULL,
> +              &VarSize,
> +              &SystemConfiguration
> +              );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +  switch (SystemConfiguration.IgdFlatPanel) {
> +
> +  case 0:
> +    //
> +    // Use the detault PCD values.
> +    //
> +    break;
> +
> +  case 1:
> +    HorizontalResolution = 640;
> +    VerticalResolution = 480;
> +    break;
> +
> +  case 2:
> +    HorizontalResolution = 800;
> +    VerticalResolution = 600;
> +    break;
> +
> +  case 3:
> +    HorizontalResolution = 1024;
> +    VerticalResolution = 768;
> +    break;
> +
> +  case 4:
> +  HorizontalResolution = 1280;
> +  VerticalResolution = 1024;
> +  break;
> +
> +  case 5:
> +  HorizontalResolution = 1366;
> +  VerticalResolution = 768;
> +  break;
> +
> +  case 6:
> +  HorizontalResolution = 1680;
> +  VerticalResolution = 1050;
> +  break;
> +
> +  case 7:
> +  HorizontalResolution = 1920;
> +  VerticalResolution = 1200;
> +  break;
> +
> +  case 8:
> +  HorizontalResolution = 1280;
> +  VerticalResolution = 800;
> +  break;
> +  }
> +
> +  PcdSet32 (PcdSetupVideoHorizontalResolution, HorizontalResolution);
> +  PcdSet32 (PcdSetupVideoVerticalResolution, VerticalResolution);
> +  DEBUG ((EFI_D_ERROR, "HorizontalResolution = %x; VerticalResolution
> = %x", HorizontalResolution, VerticalResolution));
> +
> +  return;
> +}
> +
> +/**
> +  Connect the predefined platform default console device. Always try to find
> +  and enable the vga device if have.
> +
> +  @param PlatformConsole    Predefined platform default console device
> array.
> +
> +  @retval EFI_SUCCESS       Success connect at least one ConIn and ConOut
> +                            device, there must have one ConOut device is
> +                            active vga device.
> +
> +  @retval EFI_STATUS        Return the status of
> +                            BdsLibConnectAllDefaultConsoles ()
> +
> +**/
> +EFI_STATUS
> +PlatformBdsConnectConsole (
> +  IN BDS_CONSOLE_CONNECT_ENTRY   *PlatformConsole
> +)
> +{
> +  EFI_STATUS                         Status;
> +  UINTN                              Index;
> +  EFI_DEVICE_PATH_PROTOCOL           *VarConout;
> +  EFI_DEVICE_PATH_PROTOCOL           *VarConin;
> +  UINTN                              DevicePathSize;
> +
> +  UpdateConsoleResolution();
> +
> +  Index = 0;
> +  Status = EFI_SUCCESS;
> +  DevicePathSize = 0;
> +  VarConout = BdsLibGetVariableAndSize (
> +                L"ConOut",
> +                &gEfiGlobalVariableGuid,
> +                &DevicePathSize
> +                );
> +  VarConin = BdsLibGetVariableAndSize (
> +               L"ConIn",
> +               &gEfiGlobalVariableGuid,
> +               &DevicePathSize
> +               );
> +  if (VarConout == NULL || VarConin == NULL) {
> +    //
> +    // Have chance to connect the platform default console,
> +    // the platform default console is the minimum device group
> +    // the platform should support
> +    //
> +    while (PlatformConsole[Index].DevicePath != NULL) {
> +
> +      //
> +      // Update the console variable with the connect type
> +      //
> +      if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) ==
> CONSOLE_IN) {
> +        BdsLibUpdateConsoleVariable (L"ConIn",
> PlatformConsole[Index].DevicePath, NULL);
> +      }
> +
> +      if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) ==
> CONSOLE_OUT) {
> +        BdsLibUpdateConsoleVariable (L"ConOut",
> PlatformConsole[Index].DevicePath, NULL);
> +      }
> +
> +      if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR)
> {
> +        BdsLibUpdateConsoleVariable (L"ErrOut",
> PlatformConsole[Index].DevicePath, NULL);
> +      }
> +
> +      Index ++;
> +    }
> +  }
> +
> +  //
> +  // Make sure we have at least one active VGA, and have the right
> +  // active VGA in console variable
> +  //
> +  Status = PlatformBdsForceActiveVga ();
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  DEBUG ((EFI_D_INFO, "DISPLAY INIT DONE\n"));
> +
> +  //
> +  // Connect the all the default console with current console variable
> +  //
> +  Status = BdsLibConnectAllDefaultConsoles ();
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Connect with predefined platform connect sequence,
> +  the OEM/IBV can customize with their own connect sequence.
> +
> +  @param None.
> +
> +  @retval None.
> +
> +**/
> +VOID
> +PlatformBdsConnectSequence (
> +  VOID
> +  )
> +{
> +  UINTN                     Index;
> +
> +  Index = 0;
> +
> +  //
> +  // Here we can get the customized platform connect sequence
> +  // Notes: we can connect with new variable which record the
> +  // last time boots connect device path sequence
> +  //
> +  while (gPlatformConnectSequence[Index] != NULL) {
> +
> +    //
> +    // Build the platform boot option
> +    //
> +    BdsLibConnectDevicePath (gPlatformConnectSequence[Index]);
> +    Index ++;
> +  }
> +
> +  //
> +  // Just use the simple policy to connect all devices
> +  // There should be no difference between debug tip and release tip, or it
> will be extremely hard to debug.
> +  //
> +  // There is case that IdeController driver will write boot script in driver
> model Start() function. It will be rejected by boot script save.
> +  // It is only found when DEBUG disabled, because we are using
> BdsLibConnectAll() when DEBUG enabled.
> +  //
> +  // So we use BdsLibConnectAll() here to make sure IdeController.Start() is
> invoked before InstallReadyToLock().
> +  // We may also consider to connect SataController only later if needed.
> +  //
> +  BdsLibConnectAll ();
> +}
> +
> +/**
> +
> +  Load the predefined driver option, OEM/IBV can customize this
> +  to load their own drivers
> +
> +  @param BdsDriverLists  The header of the driver option link list.
> +
> +  @retval None.
> +
> +**/
> +VOID
> +PlatformBdsGetDriverOption (
> +  IN OUT LIST_ENTRY                  *BdsDriverLists
> +  )
> +{
> +  UINTN                              Index;
> +
> +  Index = 0;
> +
> +  //
> +  // Here we can get the customized platform driver option
> +  //
> +  while (gPlatformDriverOption[Index] != NULL) {
> +
> +    //
> +    // Build the platform boot option
> +    //
> +    BdsLibRegisterNewOption (BdsDriverLists, gPlatformDriverOption[Index],
> NULL, L"DriverOrder");
> +    Index ++;
> +  }
> +
> +}
> +
> +/**
> +  This function is used for some critical time if the the system
> +  have no any boot option, and there is no time out for user to add
> +  the new boot option. This can also treat as the platform default
> +  boot option.
> +
> +  @param BdsBootOptionList   The header of the boot option link list.
> +
> +  @retval None.
> +
> +**/
> +VOID
> +PlatformBdsPredictBootOption (
> +  IN OUT LIST_ENTRY                  *BdsBootOptionList
> +  )
> +{
> +  UINTN                              Index;
> +
> +  Index = 0;
> +
> +  //
> +  // Here give chance to get platform boot option data
> +  //
> +  while (gPlatformBootOption[Index] != NULL) {
> +
> +    //
> +    // Build the platform boot option
> +    //
> +    BdsLibRegisterNewOption (BdsBootOptionList,
> gPlatformBootOption[Index], NULL, L"BootOrder");
> +    Index ++;
> +  }
> +}
> +
> +/**
> +  Perform the platform diagnostic, such like test memory. OEM/IBV also
> +  can customize this fuction to support specific platform diagnostic.
> +
> +  @param MemoryTestLevel   The memory test intensive level
> +  @param QuietBoot         Indicate if need to enable the quiet boot
> +  @param BaseMemoryTest    A pointer to BdsMemoryTest()
> +
> +  @retval  None.
> +
> +**/
> +VOID
> +PlatformBdsDiagnostics (
> +  IN EXTENDMEM_COVERAGE_LEVEL    MemoryTestLevel,
> +  IN BOOLEAN                     QuietBoot,
> +  IN BASEM_MEMORY_TEST           BaseMemoryTest
> +  )
> +{
> +  EFI_STATUS                     Status;
> +
> +  //
> +  // Here we can decide if we need to show
> +  // the diagnostics screen
> +  // Notes: this quiet boot code should be remove
> +  // from the graphic lib
> +  //
> +  if (QuietBoot) {
> +    EnableQuietBoot (PcdGetPtr(PcdLogoFile));
> +
> +    //
> +    // Perform system diagnostic
> +    //
> +    Status = BaseMemoryTest (MemoryTestLevel);
> +    if (EFI_ERROR (Status)) {
> +      DisableQuietBoot ();
> +    }
> +
> +    return;
> +  }
> +
> +  //
> +  // Perform system diagnostic
> +  //
> +  Status = BaseMemoryTest (MemoryTestLevel);
> +}
> +
> +
> +/**
> +  For EFI boot option, BDS separate them as six types:
> +  1. Network - The boot option points to the SimpleNetworkProtocol device.
> +               Bds will try to automatically create this type boot option when
> enumerate.
> +  2. Shell   - The boot option points to internal flash shell.
> +               Bds will try to automatically create this type boot option when
> enumerate.
> +  3. Removable BlockIo      - The boot option only points to the removable
> media
> +                              device, like USB flash disk, DVD, Floppy etc.
> +                              These device should contain a *removable* blockIo
> +                              protocol in their device handle.
> +                              Bds will try to automatically create this type boot option
> +                              when enumerate.
> +  4. Fixed BlockIo          - The boot option only points to a Fixed blockIo device,
> +                              like HardDisk.
> +                              These device should contain a *fixed* blockIo
> +                              protocol in their device handle.
> +                              BDS will skip fixed blockIo devices, and NOT
> +                              automatically create boot option for them. But BDS
> +                              will help to delete those fixed blockIo boot option,
> +                              whose description rule conflict with other auto-created
> +                              boot options.
> +  5. Non-BlockIo Simplefile - The boot option points to a device whose
> handle
> +                              has SimpleFileSystem Protocol, but has no blockio
> +                              protocol. These devices do not offer blockIo
> +                              protocol, but BDS still can get the
> +                              \EFI\BOOT\boot{machinename}.EFI by SimpleFileSystem
> +                              Protocol.
> +  6. File    - The boot option points to a file. These boot options are usually
> +               created by user manually or OS loader. BDS will not delete or modify
> +               these boot options.
> +
> +  This function will enumerate all possible boot device in the system, and
> +  automatically create boot options for Network, Shell, Removable BlockIo,
> +  and Non-BlockIo Simplefile devices.
> +  It will only execute once of every boot.
> +
> +  @param  BdsBootOptionList      The header of the link list which indexed all
> +                                 current boot options
> +
> +  @retval EFI_SUCCESS            Finished all the boot device enumerate and
> create
> +                                 the boot option base on that boot device
> +
> +  @retval EFI_OUT_OF_RESOURCES   Failed to enumerate the boot device
> and create the boot option list
> +**/
> +EFI_STATUS
> +EFIAPI
> +PlatformBdsLibEnumerateAllBootOption (
> +  IN OUT LIST_ENTRY          *BdsBootOptionList
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  UINT16                        FloppyNumber;
> +  UINT16                        HarddriveNumber;
> +  UINT16                        CdromNumber;
> +  UINT16                        UsbNumber;
> +  UINT16                        MiscNumber;
> +  UINT16                        ScsiNumber;
> +  UINT16                        NonBlockNumber;
> +  UINTN                         NumberBlockIoHandles;
> +  EFI_HANDLE                    *BlockIoHandles;
> +  EFI_BLOCK_IO_PROTOCOL         *BlkIo;
> +  BOOLEAN                       Removable[2];
> +  UINTN                         RemovableIndex;
> +  UINTN                         Index;
> +  UINTN                         NumOfLoadFileHandles;
> +  EFI_HANDLE                    *LoadFileHandles;
> +  UINTN                         FvHandleCount;
> +  EFI_HANDLE                    *FvHandleBuffer;
> +  EFI_FV_FILETYPE               Type;
> +  UINTN                         Size;
> +  EFI_FV_FILE_ATTRIBUTES        Attributes;
> +  UINT32                        AuthenticationStatus;
> +  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
> +  EFI_DEVICE_PATH_PROTOCOL      *DevicePath;
> +  UINTN                         DevicePathType;
> +  CHAR16                        Buffer[40];
> +  EFI_HANDLE                    *FileSystemHandles;
> +  UINTN                         NumberFileSystemHandles;
> +  BOOLEAN                       NeedDelete;
> +  EFI_IMAGE_DOS_HEADER          DosHeader;
> +  CHAR8                         *PlatLang;
> +  CHAR8                         *LastLang;
> +  EFI_IMAGE_OPTIONAL_HEADER_UNION       HdrData;
> +  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;
> +  CHAR16                        *MacStr;
> +  CHAR16                        *IPverStr;
> +  EFI_HANDLE                    *NetworkHandles;
> +  UINTN                         BufferSize;
> +
> +  FloppyNumber    = 0;
> +  HarddriveNumber = 0;
> +  CdromNumber     = 0;
> +  UsbNumber       = 0;
> +  MiscNumber      = 0;
> +  ScsiNumber      = 0;
> +  PlatLang        = NULL;
> +  LastLang        = NULL;
> +  ZeroMem (Buffer, sizeof (Buffer));
> +
> +  //
> +  // If the boot device enumerate happened, just get the boot
> +  // device from the boot order variable
> +  //
> +  if (mEnumBootDevice) {
> +    GetVariable2 (LAST_ENUM_LANGUAGE_VARIABLE_NAME,
> &gLastEnumLangGuid, (VOID**)&LastLang, NULL);
> +    GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&PlatLang, NULL);
> +    ASSERT (PlatLang != NULL);
> +    if ((LastLang != NULL) && (AsciiStrCmp (LastLang, PlatLang) == 0)) {
> +      Status = BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");
> +      FreePool (LastLang);
> +      FreePool (PlatLang);
> +      return Status;
> +    } else {
> +      Status = gRT->SetVariable (
> +        LAST_ENUM_LANGUAGE_VARIABLE_NAME,
> +        &gLastEnumLangGuid,
> +        EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
> +        AsciiStrSize (PlatLang),
> +        PlatLang
> +        );
> +      //
> +      // Failure to set the variable only impacts the performance next time
> enumerating the boot options.
> +      //
> +
> +      if (LastLang != NULL) {
> +        FreePool (LastLang);
> +      }
> +      FreePool (PlatLang);
> +    }
> +  }
> +
> +  //
> +  // Notes: this dirty code is to get the legacy boot option from the
> +  // BBS table and create to variable as the EFI boot option, it should
> +  // be removed after the CSM can provide legacy boot option directly
> +  //
> +  REFRESH_LEGACY_BOOT_OPTIONS;
> +
> +  //
> +  // Delete invalid boot option
> +  //
> +  BdsDeleteAllInvalidEfiBootOption ();
> +
> +  //
> +  // Parse removable media followed by fixed media.
> +  // The Removable[] array is used by the for-loop below to create
> removable media boot options
> +  // at first, and then to create fixed media boot options.
> +  //
> +  Removable[0]  = FALSE;
> +  Removable[1]  = TRUE;
> +
> +  gBS->LocateHandleBuffer (
> +        ByProtocol,
> +        &gEfiBlockIoProtocolGuid,
> +        NULL,
> +        &NumberBlockIoHandles,
> +        &BlockIoHandles
> +        );
> +
> +  for (RemovableIndex = 0; RemovableIndex < 2; RemovableIndex++) {
> +    for (Index = 0; Index < NumberBlockIoHandles; Index++) {
> +      Status = gBS->HandleProtocol (
> +                      BlockIoHandles[Index],
> +                      &gEfiBlockIoProtocolGuid,
> +                      (VOID **) &BlkIo
> +                      );
> +      //
> +      // skip the logical partition
> +      //
> +      if (EFI_ERROR (Status) || BlkIo->Media->LogicalPartition) {
> +        continue;
> +      }
> +
> +      //
> +      // firstly fixed block io then the removable block io
> +      //
> +      if (BlkIo->Media->RemovableMedia == Removable[RemovableIndex]) {
> +        continue;
> +      }
> +      DevicePath  = DevicePathFromHandle (BlockIoHandles[Index]);
> +      DevicePathType = BdsGetBootTypeFromDevicePath (DevicePath);
> +
> +      switch (DevicePathType) {
> +      case BDS_EFI_ACPI_FLOPPY_BOOT:
> +        if (FloppyNumber != 0) {
> +          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_FLOPPY)), FloppyNumber);
> +        } else {
> +          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_FLOPPY)));
> +        }
> +        BdsLibBuildOptionFromHandle (BlockIoHandles[Index],
> BdsBootOptionList, Buffer);
> +        FloppyNumber++;
> +        break;
> +
> +      //
> +      // Assume a removable SATA device should be the DVD/CD device, a
> fixed SATA device should be the Hard Drive device.
> +      //
> +      case BDS_EFI_MESSAGE_ATAPI_BOOT:
> +      case BDS_EFI_MESSAGE_SATA_BOOT:
> +        if (BlkIo->Media->RemovableMedia) {
> +          if (CdromNumber != 0) {
> +            UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_CD_DVD)), CdromNumber);
> +          } else {
> +            UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_CD_DVD)));
> +          }
> +          CdromNumber++;
> +        } else {
> +          if (HarddriveNumber != 0) {
> +            UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_HARDDRIVE)), HarddriveNumber);
> +          } else {
> +            UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_HARDDRIVE)));
> +          }
> +          HarddriveNumber++;
> +        }
> +        DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Buffer: %S\n", Buffer));
> +        BdsLibBuildOptionFromHandle (BlockIoHandles[Index],
> BdsBootOptionList, Buffer);
> +        break;
> +
> +      case BDS_EFI_MESSAGE_USB_DEVICE_BOOT:
> +        if (UsbNumber != 0) {
> +          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_USB)), UsbNumber);
> +        } else {
> +          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_USB)));
> +        }
> +        BdsLibBuildOptionFromHandle (BlockIoHandles[Index],
> BdsBootOptionList, Buffer);
> +        UsbNumber++;
> +        break;
> +
> +      case BDS_EFI_MESSAGE_SCSI_BOOT:
> +        if (ScsiNumber != 0) {
> +          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_SCSI)), ScsiNumber);
> +        } else {
> +          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_SCSI)));
> +        }
> +        BdsLibBuildOptionFromHandle (BlockIoHandles[Index],
> BdsBootOptionList, Buffer);
> +        ScsiNumber++;
> +        break;
> +
> +      case BDS_EFI_MESSAGE_MISC_BOOT:
> +      default:
> +        if (MiscNumber != 0) {
> +          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_MISC)), MiscNumber);
> +        } else {
> +          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_MISC)));
> +        }
> +        BdsLibBuildOptionFromHandle (BlockIoHandles[Index],
> BdsBootOptionList, Buffer);
> +        MiscNumber++;
> +        break;
> +      }
> +    }
> +  }
> +
> +  if (NumberBlockIoHandles != 0) {
> +    FreePool (BlockIoHandles);
> +  }
> +
> +  //
> +  // If there is simple file protocol which does not consume block Io protocol,
> create a boot option for it here.
> +  //
> +  NonBlockNumber = 0;
> +  gBS->LocateHandleBuffer (
> +        ByProtocol,
> +        &gEfiSimpleFileSystemProtocolGuid,
> +        NULL,
> +        &NumberFileSystemHandles,
> +        &FileSystemHandles
> +        );
> +  for (Index = 0; Index < NumberFileSystemHandles; Index++) {
> +    Status = gBS->HandleProtocol (
> +                    FileSystemHandles[Index],
> +                    &gEfiBlockIoProtocolGuid,
> +                    (VOID **) &BlkIo
> +                    );
> +     if (!EFI_ERROR (Status)) {
> +      //
> +      //  Skip if the file system handle supports a BlkIo protocol,
> +      //
> +      continue;
> +    }
> +
> +    //
> +    // Do the removable Media thing. \EFI\BOOT\boot{machinename}.EFI
> +    //  machinename is ia32, ia64, x64, ...
> +    //
> +    Hdr.Union  = &HdrData;
> +    NeedDelete = TRUE;
> +    Status     = BdsLibGetImageHeader (
> +                   FileSystemHandles[Index],
> +                   EFI_REMOVABLE_MEDIA_FILE_NAME,
> +                   &DosHeader,
> +                   Hdr
> +                   );
> +    if (!EFI_ERROR (Status) &&
> +        EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr.Pe32-
> >FileHeader.Machine) &&
> +        Hdr.Pe32->OptionalHeader.Subsystem ==
> EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {
> +      NeedDelete = FALSE;
> +    }
> +
> +    if (NeedDelete) {
> +      //
> +      // No such file or the file is not a EFI application, delete this boot option
> +      //
> +      BdsLibDeleteOptionFromHandle (FileSystemHandles[Index]);
> +    } else {
> +      if (NonBlockNumber != 0) {
> +        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_NON_BLOCK)), NonBlockNumber);
> +      } else {
> +        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_NON_BLOCK)));
> +      }
> +      BdsLibBuildOptionFromHandle (FileSystemHandles[Index],
> BdsBootOptionList, Buffer);
> +      NonBlockNumber++;
> +    }
> +  }
> +
> +  if (NumberFileSystemHandles != 0) {
> +    FreePool (FileSystemHandles);
> +  }
> +
> +  //
> +  // Check if we have on flash shell
> +  //
> +  gBS->LocateHandleBuffer (
> +        ByProtocol,
> +        &gEfiFirmwareVolume2ProtocolGuid,
> +        NULL,
> +        &FvHandleCount,
> +        &FvHandleBuffer
> +        );
> +  for (Index = 0; Index < FvHandleCount; Index++) {
> +    gBS->HandleProtocol (
> +          FvHandleBuffer[Index],
> +          &gEfiFirmwareVolume2ProtocolGuid,
> +          (VOID **) &Fv
> +          );
> +
> +    Status = Fv->ReadFile (
> +                  Fv,
> +                  &gUefiShellFileGuid,
> +                  NULL,
> +                  &Size,
> +                  &Type,
> +                  &Attributes,
> +                  &AuthenticationStatus
> +                  );
> +    if (EFI_ERROR (Status)) {
> +      //
> +      // Skip if no shell file in the FV
> +      //
> +      continue;
> +    }
> +    //
> +    // Build the shell boot option
> +    //
> +    BdsLibBuildOptionFromShell (FvHandleBuffer[Index], BdsBootOptionList);
> +  }
> +
> +  if (FvHandleCount != 0) {
> +    FreePool (FvHandleBuffer);
> +  }
> +
> +  //
> +  // Parse Network Boot Device
> +  //
> +  NumOfLoadFileHandles = 0;
> +  //
> +  // Search Load File protocol for PXE boot option.
> +  //
> +  gBS->LocateHandleBuffer (
> +        ByProtocol,
> +        &gEfiLoadFileProtocolGuid,
> +        NULL,
> +        &NumOfLoadFileHandles,
> +        &LoadFileHandles
> +        );
> +
> +  for (Index = 0; Index < NumOfLoadFileHandles; Index++) {
> +
> +//
> +//Locate EFI_DEVICE_PATH_PROTOCOL to dynamically get IPv4/IPv6
> protocol information.
> +//
> +
> + Status = gBS->HandleProtocol (
> +                  LoadFileHandles[Index],
> +                  &gEfiDevicePathProtocolGuid,
> +                  (VOID **) &DevicePath
> +                  );
> +
> + ASSERT_EFI_ERROR (Status);
> +
> +  while (!IsDevicePathEnd (DevicePath)) {
> +    if ((DevicePath->Type == MESSAGING_DEVICE_PATH) &&
> +        (DevicePath->SubType == MSG_IPv4_DP)) {
> +
> +  //
> +  //Get handle infomation
> +  //
> +  BufferSize = 0;
> +  NetworkHandles = NULL;
> +  Status = gBS->LocateHandle (
> +                  ByProtocol,
> +                  &gEfiSimpleNetworkProtocolGuid,
> +                  NULL,
> +                  &BufferSize,
> +                  NetworkHandles
> +                  );
> +
> +  if (Status == EFI_BUFFER_TOO_SMALL) {
> +    NetworkHandles = AllocateZeroPool(BufferSize);
> +    if (NetworkHandles == NULL) {
> +      return (EFI_OUT_OF_RESOURCES);
> +    }
> +    Status = gBS->LocateHandle(
> +                    ByProtocol,
> +                    &gEfiSimpleNetworkProtocolGuid,
> +                    NULL,
> +                    &BufferSize,
> +                    NetworkHandles
> +                    );
> + }
> +
> +  //
> +  //Get the MAC string
> +  //
> +  Status = NetLibGetMacString (
> +             *NetworkHandles,
> +             NULL,
> +             &MacStr
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  IPverStr = L" IPv4";
> +  UnicodeSPrint (Buffer, sizeof (Buffer), L"%s%s%s", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_NETWORK)),MacStr,IPverStr);
> +  break;
> +  }
> +    if((DevicePath->Type == MESSAGING_DEVICE_PATH) &&
> +        (DevicePath->SubType == MSG_IPv6_DP)) {
> +
> +  //
> +  //Get handle infomation
> +  //
> +  BufferSize = 0;
> +  NetworkHandles = NULL;
> +  Status = gBS->LocateHandle (
> +                  ByProtocol,
> +                  &gEfiSimpleNetworkProtocolGuid,
> +                  NULL,
> +                  &BufferSize,
> +                  NetworkHandles
> +                  );
> +
> +  if (Status == EFI_BUFFER_TOO_SMALL) {
> +    NetworkHandles = AllocateZeroPool(BufferSize);
> +    if (NetworkHandles == NULL) {
> +       return (EFI_OUT_OF_RESOURCES);
> +    }
> +    Status = gBS->LocateHandle(
> +                    ByProtocol,
> +                    &gEfiSimpleNetworkProtocolGuid,
> +                    NULL,
> +                    &BufferSize,
> +                    NetworkHandles
> +                    );
> + }
> +
> +  //
> +  //Get the MAC string
> +  //
> +  Status = NetLibGetMacString (
> +             *NetworkHandles,
> +             NULL,
> +             &MacStr
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +      IPverStr = L" IPv6";
> +      UnicodeSPrint (Buffer, sizeof (Buffer), L"%s%s%s", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_NETWORK)),MacStr,IPverStr);
> +      break;
> +    }
> +    DevicePath = NextDevicePathNode (DevicePath);
> +  }
> +
> +    BdsLibBuildOptionFromHandle (LoadFileHandles[Index],
> BdsBootOptionList, Buffer);
> +  }
> +
> +  if (NumOfLoadFileHandles != 0) {
> +    FreePool (LoadFileHandles);
> +  }
> +
> +  //
> +  // Check if we have on flash shell
> +  //
> + /* gBS->LocateHandleBuffer (
> +        ByProtocol,
> +        &gEfiFirmwareVolume2ProtocolGuid,
> +        NULL,
> +        &FvHandleCount,
> +        &FvHandleBuffer
> +        );
> +  for (Index = 0; Index < FvHandleCount; Index++) {
> +    gBS->HandleProtocol (
> +          FvHandleBuffer[Index],
> +          &gEfiFirmwareVolume2ProtocolGuid,
> +          (VOID **) &Fv
> +          );
> +
> +    Status = Fv->ReadFile (
> +                  Fv,
> +                  &gUefiShellFileGuid,
> +                  NULL,
> +                  &Size,
> +                  &Type,
> +                  &Attributes,
> +                  &AuthenticationStatus
> +                  );
> +    if (EFI_ERROR (Status)) {
> +      //
> +      // Skip if no shell file in the FV
> +      //
> +      continue;
> +    }
> +    //
> +    // Build the shell boot option
> +    //
> +    BdsLibBuildOptionFromShell (FvHandleBuffer[Index], BdsBootOptionList);
> +  }
> +
> +  if (FvHandleCount != 0) {
> +    FreePool (FvHandleBuffer);
> +  } */
> +
> +  //
> +  // Make sure every boot only have one time
> +  // boot device enumerate
> +  //
> +  Status = BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");
> +  mEnumBootDevice = TRUE;
> +
> +  return Status;
> +}
> +
> +
> +
> +/**
> +
> +  The function will execute with as the platform policy, current policy
> +  is driven by boot mode. IBV/OEM can customize this code for their specific
> +  policy action.
> +
> +  @param DriverOptionList - The header of the driver option link list
> +  @param  BootOptionList   - The header of the boot option link list
> +  @param ProcessCapsules  - A pointer to ProcessCapsules()
> +  @param BaseMemoryTest   - A pointer to BaseMemoryTest()
> +
> +  @retval None.
> +
> +**/
> +VOID
> +EFIAPI
> +PlatformBdsPolicyBehavior (
> +  IN OUT LIST_ENTRY                  *DriverOptionList,
> +  IN OUT LIST_ENTRY                  *BootOptionList,
> +  IN PROCESS_CAPSULES                BdsProcessCapsules,
> +  IN BASEM_MEMORY_TEST               BaseMemoryTest
> +  )
> +{
> +  EFI_STATUS                         Status;
> +  UINT16                             Timeout;
> +  EFI_BOOT_MODE                      BootMode;
> +  BOOLEAN                            DeferredImageExist;
> +  UINTN                              Index;
> +  SYSTEM_CONFIGURATION               SystemConfiguration;
> +  UINTN                              VarSize;
> +  PLATFORM_PCI_DEVICE_PATH           *EmmcBootDevPath;
> +  EFI_GLOBAL_NVS_AREA_PROTOCOL       *GlobalNvsArea;
> +  EFI_HANDLE                         FvProtocolHandle;
> +  UINTN                              HandleCount;
> +  EFI_HANDLE                         *HandleBuffer;
> +  UINTN                              Index1;
> +  UINTN                              SataPciRegBase = 0;
> +  UINT16                             SataModeSelect = 0;
> +  VOID                               *RegistrationExitPmAuth = NULL;
> +  EFI_EVENT                          Event;
> +  BOOLEAN                            IsFirstBoot;
> +  UINT16                             *BootOrder;
> +  UINTN                              BootOrderSize;
> +  ESRT_MANAGEMENT_PROTOCOL           *EsrtManagement;
> +
> +  Timeout = PcdGet16 (PcdPlatformBootTimeOut);
> +  if (Timeout > 10 ) {
> +    //we think the Timeout variable is corrupted
> +    Timeout = 10;
> +  }
> +
> +  VarSize = sizeof(SYSTEM_CONFIGURATION);
> +  Status = gRT->GetVariable(
> +                  NORMAL_SETUP_NAME,
> +                  &gEfiNormalSetupGuid,
> +                  NULL,
> +                  &VarSize,
> +                  &SystemConfiguration
> +                  );
> +
> +  if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
> +    //The setup variable is corrupted
> +    VarSize = sizeof(SYSTEM_CONFIGURATION);
> +    Status = gRT->GetVariable(
> +              L"SetupRecovery",
> +              &gEfiNormalSetupGuid,
> +              NULL,
> +              &VarSize,
> +              &SystemConfiguration
> +              );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +  //
> +  // Load the driver option as the driver option list
> +  //
> +  PlatformBdsGetDriverOption (DriverOptionList);
> +
> +  //
> +  // Get current Boot Mode
> +  //
> +  BootMode = GetBootModeHob();
> +
> +  //
> +  // No deferred images exist by default
> +  //
> +  DeferredImageExist = FALSE;
> +  if ((BootMode != BOOT_WITH_MINIMAL_CONFIGURATION) &&
> (PcdGet32(PcdFlashFvShellSize) > 0)){
> +    gDS->ProcessFirmwareVolume (
> +           (VOID *)(UINTN)PcdGet32(PcdFlashFvShellBase),
> +           PcdGet32(PcdFlashFvShellSize),
> +           &FvProtocolHandle
> +           );
> +  }
> +
> +  if (SystemConfiguration.FastBoot == 1) {
> +    BootOrder = BdsLibGetVariableAndSize (
> +                  L"BootOrder",
> +                  &gEfiGlobalVariableGuid,
> +                  &BootOrderSize
> +                  );
> +    if ((BootOrder != NULL) && (BootMode != BOOT_ON_FLASH_UPDATE)) {
> +      //
> +      // BootOrder exist, it means system has boot before. We can do fast
> boot.
> +      //
> +      BootMode = BOOT_WITH_MINIMAL_CONFIGURATION;
> +    }
> +  }
> +
> +
> +  //
> +  // Use eMMC to boot OS and turn on AHCI, when SATA HDD is
> diconnected,
> +  // SATA AHCI CTLR device will show yellow bang, implement this solution
> to solve it.
> +  //
> +  SataPciRegBase  = MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_SATA,
> 0, 0);
> +  SataModeSelect  = MmioRead16 (SataPciRegBase + R_PCH_SATA_MAP) &
> B_PCH_SATA_MAP_SMS_MASK;
> +  Status          = EFI_SUCCESS;
> +  if (SataModeSelect != V_PCH_SATA_MAP_SMS_IDE) {
> +    Status = gBS->CreateEvent (
> +                    EVT_NOTIFY_SIGNAL,
> +                    TPL_CALLBACK,
> +                    DisableAhciCtlr,
> +                    &SataPciRegBase,
> +                    &Event
> +                     );
> +    if (!EFI_ERROR (Status)) {
> +      Status = gBS->RegisterProtocolNotify (
> +                      &gExitPmAuthProtocolGuid,
> +                      Event,
> +                      &RegistrationExitPmAuth
> +                      );
> +    }
> +  }
> +
> +  Status = gBS->LocateProtocol(&gEsrtManagementProtocolGuid, NULL,
> (VOID **)&EsrtManagement);
> +  if (EFI_ERROR(Status)) {
> +    EsrtManagement = NULL;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "BDS: BootMode=%02x\n", BootMode));
> +
> +  switch (BootMode) {
> +
> +  case BOOT_WITH_MINIMAL_CONFIGURATION:
> +    PlatformBdsInitHotKeyEvent ();
> +    PlatformBdsConnectSimpleConsole (gPlatformSimpleConsole);
> +
> +
> +    //
> +    // Check to see if it's needed to dispatch more DXE drivers.
> +    //
> +    for (Index = 0; Index < sizeof(ConnectDriverTable)/sizeof(EFI_GUID *);
> Index++) {
> +      Status = gBS->LocateHandleBuffer (
> +                      ByProtocol,
> +                      ConnectDriverTable[Index],
> +                      NULL,
> +                      &HandleCount,
> +                      &HandleBuffer
> +                      );
> +      if (!EFI_ERROR (Status)) {
> +        for (Index1 = 0; Index1 < HandleCount; Index1++) {
> +          gBS->ConnectController (
> +                 HandleBuffer[Index1],
> +                 NULL,
> +                 NULL,
> +                 TRUE
> +                 );
> +        }
> +      }
> +
> +      if (HandleBuffer != NULL) {
> +        FreePool (HandleBuffer);
> +      }
> +
> +      gDS->Dispatch ();
> +    }
> +
> +    //
> +    //  Locate the Global NVS Protocol.
> +    //
> +    Status = gBS->LocateProtocol (
> +                    &gEfiGlobalNvsAreaProtocolGuid,
> +                    NULL,
> +                    (void **)&GlobalNvsArea
> +                    );
> +    if (GlobalNvsArea->Area->emmcVersion == 0){
> +      EmmcBootDevPath = (PLATFORM_PCI_DEVICE_PATH
> *)gPlatformSimpleBootOption[0];
> +      EmmcBootDevPath->PciDevice.Device = 0x10;
> +    }
> +
> +    //
> +    // Connect boot device here to give time to read keyboard.
> +    //
> +    BdsLibConnectDevicePath (gPlatformSimpleBootOption[0]);
> +
> +    //
> +    // This is a workround for dectecting hotkey from USB keyboard.
> +    //
> +    gBS->Stall(KEYBOARD_TIMER_INTERVAL);
> +
> +    if (mHotKeyTimerEvent != NULL) {
> +      gBS->SetTimer (
> +             mHotKeyTimerEvent,
> +             TimerCancel,
> +             0
> +             );
> +      gBS->CloseEvent (mHotKeyTimerEvent);
> +      mHotKeyTimerEvent = NULL;
> +    }
> +    if (mHotKeyPressed) {
> +      //
> +      // Skip show progress count down
> +      //
> +      Timeout = 0xFFFF;
> +      goto FULL_CONFIGURATION;
> +    }
> +
> +    EnableQuietBoot (PcdGetPtr(PcdLogoFile));
> +    if (!SystemConfiguration.QuietBoot) {
> +      PlatformBdsDiagnostics (IGNORE, FALSE, BaseMemoryTest);
> +    }
> +
> +
> +    #ifdef TPM_ENABLED
> +    TcgPhysicalPresenceLibProcessRequest();
> +    #endif
> +    #ifdef FTPM_ENABLE
> +    Tcg2PhysicalPresenceLibProcessRequest(NULL);
> +    #endif
> +
> +    if (EsrtManagement != NULL) {
> +      EsrtManagement->LockEsrtRepository();
> +    }
> +
> +    //
> +    // Close boot script and install ready to lock
> +    //
> +    InstallReadyToLock ();
> +
> +    //
> +    // Give one chance to enter the setup if we
> +    // select Gummiboot "Reboot Into Firmware Interface" and Fast Boot is
> enabled.
> +    //
> +    BootIntoFirmwareInterface();
> +    break;
> +
> +  case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
> +
> +    //
> +    // In no-configuration boot mode, we can connect the
> +    // console directly.
> +    //
> +    BdsLibConnectAllDefaultConsoles ();
> +    PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest);
> +
> +    //
> +    // Perform some platform specific connect sequence
> +    //
> +    PlatformBdsConnectSequence ();
> +
> +    //
> +    // As console is ready, perform user identification again.
> +    //
> +    if (mCurrentUser == NULL) {
> +      PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
> +      if (DeferredImageExist) {
> +        //
> +        // After user authentication, the deferred drivers was loaded again.
> +        // Here, need to ensure the deferred images are connected.
> +        //
> +        BdsLibConnectAllDefaultConsoles ();
> +        PlatformBdsConnectSequence ();
> +      }
> +    }
> +
> +    if (EsrtManagement != NULL) {
> +      EsrtManagement->LockEsrtRepository();
> +    }
> +
> +    //
> +    // Close boot script and install ready to lock
> +    //
> +    InstallReadyToLock ();
> +
> +    //
> +    // Notes: current time out = 0 can not enter the
> +    // front page
> +    //
> +    PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);
> +
> +    //
> +    // Check the boot option with the boot option list
> +    //
> +    BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");
> +    break;
> +
> +  case BOOT_ON_FLASH_UPDATE:
> +
> +    //
> +    // Boot with the specific configuration
> +    //
> +    PlatformBdsConnectConsole (gPlatformConsole);
> +    PlatformBdsDiagnostics (EXTENSIVE, TRUE, BaseMemoryTest);
> +
> +    DEBUG((DEBUG_INFO, "ProcessCapsules Before EndOfDxe......\n"));
> +    ProcessCapsules ();
> +    DEBUG((DEBUG_INFO, "ProcessCapsules Done\n"));
> +
> +    //
> +    // Close boot script and install ready to lock
> +    //
> +    InstallReadyToLock ();
> +
> +    BdsLibConnectAll ();
> +
> +    //
> +    // Perform user identification
> +    //
> +    if (mCurrentUser == NULL) {
> +      PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
> +      if (DeferredImageExist) {
> +        //
> +        // After user authentication, the deferred drivers was loaded again.
> +        // Here, need to ensure the deferred images are connected.
> +        //
> +        BdsLibConnectAll ();
> +      }
> +    }
> +
> +    if (EsrtManagement != NULL) {
> +      EsrtManagement->SyncEsrtFmp();
> +    }
> +
> +    DEBUG((DEBUG_INFO, "ProcessCapsules After ConnectAll......\n"));
> +    ProcessCapsules();
> +    DEBUG((DEBUG_INFO, "ProcessCapsules Done\n"));
> +    break;
> +
> +  case BOOT_IN_RECOVERY_MODE:
> +
> +    //
> +    // In recovery mode, just connect platform console
> +    // and show up the front page
> +    //
> +    PlatformBdsConnectConsole (gPlatformConsole);
> +    PlatformBdsDiagnostics (EXTENSIVE, FALSE, BaseMemoryTest);
> +    BdsLibConnectAll ();
> +
> +    //
> +    // Perform user identification
> +    //
> +    if (mCurrentUser == NULL) {
> +      PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
> +      if (DeferredImageExist) {
> +        //
> +        // After user authentication, the deferred drivers was loaded again.
> +        // Here, need to ensure the deferred drivers are connected.
> +        //
> +        BdsLibConnectAll ();
> +      }
> +    }
> +
> +    //
> +    // Close boot script and install ready to lock
> +    //
> +    InstallReadyToLock ();
> +
> +    //
> +    // In recovery boot mode, we still enter to the
> +    // frong page now
> +    //
> +    PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);
> +    break;
> +
> +FULL_CONFIGURATION:
> +  case BOOT_WITH_FULL_CONFIGURATION:
> +  case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:
> +  case BOOT_WITH_DEFAULT_SETTINGS:
> +  default:
> +
> +    //
> +    // Connect platform console
> +    //
> +    Status = PlatformBdsConnectConsole (gPlatformConsole);
> +    if (EFI_ERROR (Status)) {
> +
> +      //
> +      // Here OEM/IBV can customize with defined action
> +      //
> +      PlatformBdsNoConsoleAction ();
> +    }
> +
> +    //
> +    // Chenyunh[TODO]: This is Workgroud to show the fs for uSDcard,
> +    // Need to root cause this issue.
> +    //
> +    DEBUG ((DEBUG_ERROR, "Start to reconnect all driver.\n"));
> +    BdsLibDisconnectAllEfi();
> +    BdsLibConnectAll ();
> +    DEBUG ((DEBUG_ERROR, "End to reconnect all driver.\n"));
> +
> +    //
> +    // Perform some platform specific connect sequence
> +    //
> +    PlatformBdsConnectSequence ();
> +    EnableQuietBoot (PcdGetPtr(PcdLogoFile));
> +    if (!SystemConfiguration.QuietBoot) {
> +      PlatformBdsDiagnostics (IGNORE, FALSE, BaseMemoryTest);
> +    }
> +
> +    //
> +    // Do a pre-delay so Hard Disk can spin up and see more logo.
> +    //
> +    gBS->Stall(SystemConfiguration.HddPredelay * 1000000);
> +
> +    //
> +    // Perform user identification
> +    //
> +    if (mCurrentUser == NULL) {
> +      PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
> +      if (DeferredImageExist) {
> +        //
> +        // After user authentication, the deferred drivers was loaded again.
> +        // Here, need to ensure the deferred drivers are connected.
> +        //
> +        Status = PlatformBdsConnectConsole (gPlatformConsole);
> +        if (EFI_ERROR (Status)) {
> +          PlatformBdsNoConsoleAction ();
> +        }
> +        PlatformBdsConnectSequence ();
> +      }
> +    }
> +   #ifdef TPM_ENABLED
> +   TcgPhysicalPresenceLibProcessRequest();
> +   #endif
> +   #ifdef FTPM_ENABLE
> +   Tcg2PhysicalPresenceLibProcessRequest(NULL);
> +   #endif
> +
> +    if (EsrtManagement != NULL) {
> +      EsrtManagement->SyncEsrtFmp();
> +    }
> +    //
> +    // Close boot script and install ready to lock
> +    //
> +    InstallReadyToLock ();
> +
> +    //
> +    // Here we have enough time to do the enumeration of boot device
> +    //
> +    PlatformBdsLibEnumerateAllBootOption (BootOptionList);
> +
> +    //
> +    // Give one chance to enter the setup if we
> +    // have the time out
> +    //
> +    PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);
> +
> +	//
> +	// Give one chance to enter the setup if we
> +	// select Gummiboot "Reboot Into Firmware Interface"
> +	//
> +	BootIntoFirmwareInterface();
> +
> +    //
> +    // In default boot mode, always find all boot
> +    // option and do enumerate all the default boot option
> +    //
> +    if (Timeout == 0) {
> +      BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");
> +      if (IsListEmpty(BootOptionList)) {
> +        PlatformBdsPredictBootOption (BootOptionList);
> +      }
> +
> +      return;
> +    }
> +
> +
> +    break;
> +  }
> +
> +
> +  IsFirstBoot = PcdGetBool(PcdBootState);
> +  if (IsFirstBoot) {
> +    PcdSetBool(PcdBootState, FALSE);
> +  }
> +  return;
> +
> +}
> +
> +/**
> +  Hook point after a boot attempt succeeds. We don't expect a boot option
> to
> +  return, so the UEFI 2.0 specification defines that you will default to an
> +  interactive mode and stop processing the BootOrder list in this case. This
> +  is alos a platform implementation and can be customized by IBV/OEM.
> +
> +  @param Option  Pointer to Boot Option that succeeded to boot.
> +
> +  @retval None.
> +
> +**/
> +VOID
> +EFIAPI
> +PlatformBdsBootSuccess (
> +  IN  BDS_COMMON_OPTION *Option
> +  )
> +{
> +  CHAR16  *TmpStr;
> +
> +  //
> +  // If Boot returned with EFI_SUCCESS and there is not in the boot device
> +  // select loop then we need to pop up a UI and wait for user input.
> +  //
> +  TmpStr =  Option->StatusString;
> +  if (TmpStr != NULL) {
> +    BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r",
> NULL);
> +    FreePool(TmpStr);
> +  }
> +}
> +
> +/**
> +  Hook point after a boot attempt fails.
> +
> +  @param Option - Pointer to Boot Option that failed to boot.
> +  @param Status - Status returned from failed boot.
> +  @param ExitData - Exit data returned from failed boot.
> +  @param ExitDataSize - Exit data size returned from failed boot.
> +
> +  @retval None.
> +
> +**/
> +VOID
> +EFIAPI
> +PlatformBdsBootFail (
> +  IN  BDS_COMMON_OPTION  *Option,
> +  IN  EFI_STATUS         Status,
> +  IN  CHAR16             *ExitData,
> +  IN  UINTN              ExitDataSize
> +  )
> +{
> +  CHAR16          *TmpStr;
> +  EFI_HANDLE      FvProtocolHandle;
> +
> +  //
> +  // If Boot returned with failed status then we need to pop up a UI and wait
> +  // for user input.
> +  //
> +  TmpStr = Option->StatusString;
> +  if (TmpStr != NULL) {
> +    BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r",
> NULL);
> +    FreePool(TmpStr);
> +  }
> +  if (PcdGet32(PcdFlashFvShellSize) > 0){
> +    gDS->ProcessFirmwareVolume (
> +           (VOID *)(UINTN)PcdGet32(PcdFlashFvShellBase),
> +           PcdGet32(PcdFlashFvShellSize),
> +           &FvProtocolHandle
> +           );
> +  }
> +  PlatformBdsConnectSequence ();
> +}
> +
> +/**
> +  This function is remained for IBV/OEM to do some platform action,
> +  if there no console device can be connected.
> +
> +  @param  None.
> +
> +  @retval EFI_SUCCESS       Direct return success now.
> +
> +**/
> +EFI_STATUS
> +PlatformBdsNoConsoleAction (
> +  VOID
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function locks the block
> +
> +  @param Base            The base address flash region to be locked.
> +
> +**/
> +VOID
> +BdsLockFv (
> +  IN EFI_PHYSICAL_ADDRESS  Base
> +  )
> +{
> +  EFI_FV_BLOCK_MAP_ENTRY      *BlockMap;
> +  EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;
> +  EFI_PHYSICAL_ADDRESS        BaseAddress;
> +  UINT32                      BlockLength;
> +  UINTN                       Index;
> +
> +  BaseAddress = Base - 0x400000 + 2;
> +  FvHeader    = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) (Base));
> +  BlockMap    = &(FvHeader->BlockMap[0]);
> +
> +  while ((BlockMap->NumBlocks != 0) && (BlockMap->Length != 0)) {
> +    BlockLength = BlockMap->Length;
> +    for (Index = 0; Index < BlockMap->NumBlocks; Index++) {
> +      MmioOr8 ((UINTN) BaseAddress, 0x03);
> +      BaseAddress += BlockLength;
> +    }
> +    BlockMap++;
> +  }
> +}
> +
> +VOID
> +EFIAPI
> +PlatformBdsLockNonUpdatableFlash (
> +  VOID
> +  )
> +{
> +  EFI_PHYSICAL_ADDRESS  Base;
> +
> +  Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvMainBase);
> +  if (Base > 0) {
> +    BdsLockFv (Base);
> +  }
> +
> +  Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvRecoveryBase);
> +  if (Base > 0) {
> +    BdsLockFv (Base);
> +  }
> +}
> +
> +/**
> +  Lock the ConsoleIn device in system table. All key
> +  presses will be ignored until the Password is typed in. The only way to
> +  disable the password is to type it in to a ConIn device.
> +
> +  @param  Password        Password used to lock ConIn device.
> +
> +  @retval EFI_SUCCESS     lock the Console In Spliter virtual handle
> successfully.
> +  @retval EFI_UNSUPPORTED Password not found
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +LockKeyboards (
> +  IN  CHAR16    *Password
> +  )
> +{
> +    return EFI_UNSUPPORTED;
> +}
> +
> +/**
> +  Connect the predefined platform default authentication devices.
> +
> +  This function connects the predefined device path for authentication
> device,
> +  and if the predefined device path has child device path, the child handle
> will
> +  be connected too. But the child handle of the child will not be connected.
> +
> +**/
> +VOID
> +EFIAPI
> +PlatformBdsConnectAuthDevice (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                   Status;
> +  UINTN                        Index;
> +  UINTN                        HandleIndex;
> +  UINTN                        HandleCount;
> +  EFI_HANDLE                   *HandleBuffer;
> +  EFI_DEVICE_PATH_PROTOCOL     *ChildDevicePath;
> +  EFI_USER_MANAGER_PROTOCOL    *Manager;
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiUserManagerProtocolGuid,
> +                  NULL,
> +                  (VOID **) &Manager
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    //
> +    // As user manager protocol is not installed, the authentication devices
> +    // should not be connected.
> +    //
> +    return ;
> +  }
> +
> +  Index = 0;
> +  while (gUserAuthenticationDevice[Index] != NULL) {
> +    //
> +    // Connect the platform customized device paths
> +    //
> +    BdsLibConnectDevicePath (gUserAuthenticationDevice[Index]);
> +    Index++;
> +  }
> +
> +  //
> +  // Find and connect the child device paths of the platform customized
> device paths
> +  //
> +  HandleBuffer = NULL;
> +  for (Index = 0; gUserAuthenticationDevice[Index] != NULL; Index++) {
> +    HandleCount = 0;
> +    Status = gBS->LocateHandleBuffer (
> +                    AllHandles,
> +                    NULL,
> +                    NULL,
> +                    &HandleCount,
> +                    &HandleBuffer
> +                    );
> +    ASSERT (!EFI_ERROR (Status));
> +
> +    //
> +    // Find and connect the child device paths of
> gUserIdentificationDevice[Index]
> +    //
> +    for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
> +      ChildDevicePath = NULL;
> +      Status = gBS->HandleProtocol (
> +                      HandleBuffer[HandleIndex],
> +                      &gEfiDevicePathProtocolGuid,
> +                      (VOID **) &ChildDevicePath
> +                      );
> +      if (EFI_ERROR (Status) || ChildDevicePath == NULL) {
> +        continue;
> +      }
> +
> +      if (CompareMem (
> +            ChildDevicePath,
> +            gUserAuthenticationDevice[Index],
> +            (GetDevicePathSize (gUserAuthenticationDevice[Index]) - sizeof
> (EFI_DEVICE_PATH_PROTOCOL))
> +            ) != 0) {
> +        continue;
> +      }
> +      gBS->ConnectController (
> +             HandleBuffer[HandleIndex],
> +             NULL,
> +             NULL,
> +             TRUE
> +             );
> +    }
> +  }
> +
> +  if (HandleBuffer != NULL) {
> +    FreePool (HandleBuffer);
> +  }
> +}
> +
> +/**
> +  This function is to identify a user, and return whether deferred images
> exist.
> +
> +  @param[out]  User               Point to user profile handle.
> +  @param[out]  DeferredImageExist On return, points to TRUE if the
> deferred image
> +                                  exist or FALSE if it did not exist.
> +
> +**/
> +VOID
> +EFIAPI
> +PlatformBdsUserIdentify (
> +  OUT EFI_USER_PROFILE_HANDLE        *User,
> +  OUT BOOLEAN                        *DeferredImageExist
> +  )
> +{
> +  EFI_STATUS                         Status;
> +  EFI_DEFERRED_IMAGE_LOAD_PROTOCOL   *DeferredImage;
> +  UINTN                              HandleCount;
> +  EFI_HANDLE                         *HandleBuf;
> +  UINTN                              Index;
> +  UINTN                              DriverIndex;
> +  EFI_DEVICE_PATH_PROTOCOL           *ImageDevicePath;
> +  VOID                               *DriverImage;
> +  UINTN                              ImageSize;
> +  BOOLEAN                            BootOption;
> +
> +  //
> +  // Perform user identification
> +  //
> +  do {
> +    Status = BdsLibUserIdentify (User);
> +  } while (EFI_ERROR (Status));
> +
> +  //
> +  // After user authentication now, try to find whether deferred image
> exists
> +  //
> +  HandleCount = 0;
> +  HandleBuf   = NULL;
> +  *DeferredImageExist = FALSE;
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gEfiDeferredImageLoadProtocolGuid,
> +                  NULL,
> +                  &HandleCount,
> +                  &HandleBuf
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return ;
> +  }
> +
> +  for (Index = 0; Index < HandleCount; Index++) {
> +    Status = gBS->HandleProtocol (
> +                    HandleBuf[Index],
> +                    &gEfiDeferredImageLoadProtocolGuid,
> +                    (VOID **) &DeferredImage
> +                    );
> +    if (!EFI_ERROR (Status)) {
> +      //
> +      // Find whether deferred image exists in this instance.
> +      //
> +      DriverIndex = 0;
> +      Status = DeferredImage->GetImageInfo(
> +                                DeferredImage,
> +                                DriverIndex,
> +                                &ImageDevicePath,
> +                                (VOID **) &DriverImage,
> +                                &ImageSize,
> +                                &BootOption
> +                                );
> +      if (!EFI_ERROR (Status)) {
> +        //
> +        // The deferred image is found.
> +        //
> +        FreePool (HandleBuf);
> +        *DeferredImageExist = TRUE;
> +        return ;
> +      }
> +    }
> +  }
> +
> +  FreePool (HandleBuf);
> +}
> +
> +UINTN gHotKey = 0;
> +
> +
> +EFI_STATUS
> +ShowProgressHotKey (
> +  IN UINT16                       TimeoutDefault
> +  )
> +{
> +  CHAR16                        *TmpStr;
> +  UINT16                        TimeoutRemain;
> +  EFI_STATUS                    Status;
> +  EFI_INPUT_KEY                 Key;
> +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
> +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
> +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;
> +  UINT32                        GpioValue;
> +  CHAR16                        *TmpStr1;
> +  CHAR16                        *TmpStr2;
> +  CHAR16                        *TmpStr3;
> +  UINTN                         TmpStrSize;
> +  VOID                          *Buffer;
> +  UINTN                         Size;
> +
> +  if (TimeoutDefault == 0) {
> +    return EFI_TIMEOUT;
> +  }
> +
> +  gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR
> (EFI_LIGHTGRAY, EFI_BLACK));
> +
> +  if (DebugAssertEnabled())
> +  {
> +    DEBUG ((EFI_D_INFO, "\n\nStart showing progress bar... Press any key to
> stop it, or press <F2> or <DEL> to enter setup page! ...Zzz....\n"));
> +  }
> +  else
> +  {
> +    #ifdef __GNUC__
> +    SerialPortWrite((UINT8 *)"\n\n>>>>Start boot option, Press <F2> or <DEL>
> to enter setup page(5 Sec)[GCC]", 76);
> +    #else
> +    SerialPortWrite((UINT8 *)"\n\n>>>>Start boot option, Press <F2> or <DEL>
> to enter setup page(5 Sec)", 71);
> +    #endif
> +  }
> +  SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
> +  SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
> +  SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
> +
> +  TmpStr2 = NULL;
> +  TmpStr3 = NULL;
> +
> +  //
> +  // Check if the platform is using test key.
> +  //
> +  Status = GetSectionFromAnyFv(
> +             PcdGetPtr(PcdEdkiiRsa2048Sha256TestPublicKeyFileGuid),
> +             EFI_SECTION_RAW,
> +             0,
> +             &Buffer,
> +             &Size
> +             );
> +  if (!EFI_ERROR(Status)) {
> +    if ((Size == PcdGetSize(PcdRsa2048Sha256PublicKeyBuffer)) &&
> +        (CompareMem(Buffer, PcdGetPtr(PcdRsa2048Sha256PublicKeyBuffer),
> Size) == 0)) {
> +      TmpStr2 = L"WARNING: Recovery Test Key is used.\r\n";
> +      if (DebugAssertEnabled()) {
> +        DEBUG ((DEBUG_INFO, "\n\nWARNING: Recovery Test Key is
> used.\n"));
> +      } else {
> +        SerialPortWrite((UINT8 *)"\n\nWARNING: Recovery Test Key is used.",
> sizeof("\n\nWARNING: Recovery Test Key is used."));
> +      }
> +      PcdSetBoolS(PcdTestKeyUsed, TRUE);
> +    }
> +    FreePool(Buffer);
> +  }
> +  Status = GetSectionFromAnyFv(
> +             PcdGetPtr(PcdEdkiiPkcs7TestPublicKeyFileGuid),
> +             EFI_SECTION_RAW,
> +             0,
> +             &Buffer,
> +             &Size
> +             );
> +  if (!EFI_ERROR(Status)) {
> +    if ((Size == PcdGetSize(PcdPkcs7CertBuffer)) &&
> +        (CompareMem(Buffer, PcdGetPtr(PcdPkcs7CertBuffer), Size) == 0)) {
> +      TmpStr3 = L"WARNING: Capsule Test Key is used.\r\n";
> +      if (DebugAssertEnabled()) {
> +        DEBUG ((DEBUG_INFO, "\n\nWARNING: Capsule Test Key is
> used.\r\n"));
> +      } else {
> +        SerialPortWrite((UINT8 *)"\n\nWARNING: Capsule Test Key is used.",
> sizeof("\n\nWARNING: Capsule Test Key is used."));
> +      }
> +      PcdSetBoolS(PcdTestKeyUsed, TRUE);
> +    }
> +    FreePool(Buffer);
> +  }
> +
> +  //
> +  // Clear the progress status bar first
> +  //
> +  TmpStr1 = L"Start boot option, Press <F2> or <DEL> to enter setup
> page.\r\n";
> +  TmpStrSize = StrSize(TmpStr1);
> +  if (TmpStr2 != NULL) {
> +    TmpStrSize += StrSize(TmpStr2);
> +  }
> +  if (TmpStr3 != NULL) {
> +    TmpStrSize += StrSize(TmpStr3);
> +  }
> +  TmpStr = AllocatePool (TmpStrSize);
> +  if (TmpStr == NULL) {
> +    TmpStr = TmpStr1;
> +  } else {
> +    StrCpyS(TmpStr, TmpStrSize/sizeof(CHAR16), TmpStr1);
> +    if (TmpStr2 != NULL) {
> +      StrCatS(TmpStr, TmpStrSize/sizeof(CHAR16), TmpStr2);
> +    }
> +    if (TmpStr3 != NULL) {
> +      StrCatS(TmpStr, TmpStrSize/sizeof(CHAR16), TmpStr3);
> +    }
> +  }
> +  PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);
> +
> +  TimeoutRemain = TimeoutDefault;
> +  while (TimeoutRemain != 0) {
> +    if (DebugAssertEnabled())
> +    {
> +    DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n",
> TimeoutRemain));
> +    }
> +    else
> +    {
> +    SerialPortWrite ((UINT8 *)".", 1);
> +    }
> +    Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);
> +    if (Status != EFI_TIMEOUT) {
> +      break;
> +    }
> +    TimeoutRemain--;
> +
> +    //
> +    // Show progress
> +    //
> +    if (TmpStr != NULL) {
> +      PlatformBdsShowProgress (
> +        Foreground,
> +        Background,
> +        TmpStr,
> +        Color,
> +        ((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault),
> +        0
> +        );
> +    }
> +  }
> +
> +  //
> +  // Timeout expired
> +  //
> +  if (TimeoutRemain == 0) {
> +    if (DebugAssertEnabled())
> +	{
> +	}
> +    else
> +    {
> +    SerialPortWrite ((UINT8 *)"\r\n", 2);
> +    }
> +    return EFI_TIMEOUT;
> +  }
> +
> +  //
> +  // User pressed some key
> +  //
> +  Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Check Volume Up Key to enter Setup
> +  //
> +  GpioValue = MmioRead32 (IO_BASE_ADDRESS + 0x0668);  // The value of
> GPIOC_5
> +  if (((GpioValue & BIT0) == 0) && (Key.ScanCode == SCAN_UP)) {
> +    gHotKey = 0;
> +    return EFI_SUCCESS;
> +  }
> +
> +  if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
> +    //
> +    // User pressed enter, equivalent to select "continue"
> +    //
> +    return EFI_TIMEOUT;
> +  }
> +
> +  //
> +  //F2 --  Front Page
> +  //F5 --  Device Manager
> +  //F7 --  Boot Manager
> +  // do not use F8. generally people assume it is windows safe mode key.
> +  //F9 --  Boot order
> +  //
> +  DEBUG ((EFI_D_INFO, "[Key Pressed]: ScanCode 0x%x\n", Key.ScanCode));
> +  switch(Key.ScanCode) {
> +      case SCAN_F2:
> +          gHotKey = 0;
> +          break;
> +
> +      case SCAN_DELETE:
> +          gHotKey = 0;
> +          break;
> +
> +      case SCAN_F5:
> +          gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
> +          break;
> +
> +      case SCAN_F7:
> +          gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER;
> +          break;
> +
> +      case SCAN_F9:
> +          gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN;
> +          break;
> +
> +      default:
> +          //set gHotKey to continue so that flow will not go into CallFrontPage
> +          gHotKey = FRONT_PAGE_KEY_CONTINUE;
> +          return EFI_TIMEOUT;
> +          break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +
> +/**
> +  This function is the main entry of the platform setup entry.
> +  The function will present the main menu of the system setup,
> +  this is the platform reference part and can be customize.
> +
> +
> +  @param TimeoutDefault     The fault time out value before the system
> +                            continue to boot.
> +  @param ConnectAllHappened The indicater to check if the connect all
> have
> +                            already happened.
> +
> +**/
> +VOID
> +PlatformBdsEnterFrontPageWithHotKey (
> +  IN UINT16                       TimeoutDefault,
> +  IN BOOLEAN                      ConnectAllHappened
> +  )
> +{
> +  EFI_STATUS                    Status;
> +
> +  EFI_STATUS                         LogoStatus;
> +  EFI_BOOT_LOGO_PROTOCOL             *BootLogo;
> +  EFI_GRAPHICS_OUTPUT_PROTOCOL       *GraphicsOutput;
> +  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL    *SimpleTextOut;
> +  UINTN                              BootTextColumn;
> +  UINTN                              BootTextRow;
> +
> +  GraphicsOutput = NULL;
> +  SimpleTextOut = NULL;
> +
> +  PERF_START (NULL, "BdsTimeOut", "BDS", 0);
> +
> +  //
> +  // Indicate if we need connect all in the platform setup
> +  //
> +  if (ConnectAllHappened) {
> +    gConnectAllHappened = TRUE;
> +  }
> +
> +  if (!mModeInitialized) {
> +    //
> +    // After the console is ready, get current video resolution
> +    // and text mode before launching setup at first time.
> +    //
> +    Status = gBS->HandleProtocol (
> +                    gST->ConsoleOutHandle,
> +                    &gEfiGraphicsOutputProtocolGuid,
> +                    (VOID**)&GraphicsOutput
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      GraphicsOutput = NULL;
> +    }
> +
> +    Status = gBS->HandleProtocol (
> +                    gST->ConsoleOutHandle,
> +                    &gEfiSimpleTextOutProtocolGuid,
> +                    (VOID**)&SimpleTextOut
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      SimpleTextOut = NULL;
> +    }
> +
> +    if (GraphicsOutput != NULL) {
> +      //
> +      // Get current video resolution and text mode.
> +      //
> +      mBootHorizontalResolution = GraphicsOutput->Mode->Info-
> >HorizontalResolution;
> +      mBootVerticalResolution   = GraphicsOutput->Mode->Info-
> >VerticalResolution;
> +    }
> +
> +    if (SimpleTextOut != NULL) {
> +      Status = SimpleTextOut->QueryMode (
> +                                SimpleTextOut,
> +                                SimpleTextOut->Mode->Mode,
> +                                &BootTextColumn,
> +                                &BootTextRow
> +                                );
> +      mBootTextModeColumn = (UINT32)BootTextColumn;
> +      mBootTextModeRow    = (UINT32)BootTextRow;
> +    }
> +
> +    //
> +    // Get user defined text mode for setup.
> +    //
> +    mSetupHorizontalResolution = PcdGet32
> (PcdSetupVideoHorizontalResolution);
> +    mSetupVerticalResolution   = PcdGet32
> (PcdSetupVideoVerticalResolution);
> +    mSetupTextModeColumn       = PcdGet32 (PcdSetupConOutColumn);
> +    mSetupTextModeRow          = PcdGet32 (PcdSetupConOutRow);
> +
> +    mModeInitialized           = TRUE;
> +  }
> +
> +  if (TimeoutDefault != 0xffff) {
> +    Status = ShowProgressHotKey (TimeoutDefault);
> +
> +    //
> +    // Ensure screen is clear when switch Console from Graphics mode to
> Text mode
> +    //
> +    gST->ConOut->EnableCursor (gST->ConOut, TRUE);
> +    gST->ConOut->ClearScreen (gST->ConOut);
> +
> +    //
> +    // Boot Logo is corrupted, report it using Boot Logo protocol.
> +    //
> +    LogoStatus = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL,
> (VOID **) &BootLogo);
> +    if (!EFI_ERROR (LogoStatus) && (BootLogo != NULL)) {
> +      BootLogo->SetBootLogo (BootLogo, NULL, 0, 0, 0, 0);
> +    }
> +
> +    if (EFI_ERROR (Status)) {
> +      //
> +      // Timeout or user press enter to continue
> +      //
> +      goto Exit;
> +    }
> +  }
> +
> +  //
> +  // Install BM HiiPackages.
> +  // Keep BootMaint HiiPackage, so that it can be covered by global setting.
> +  //
> +	InitBMPackage ();
> +  do {
> +
> +    BdsSetConsoleMode (TRUE);
> +
> +    InitializeFrontPage (FALSE);
> +
> +    //
> +    // Update Front Page strings
> +    //
> +    UpdateFrontPageStrings ();
> +
> +    Status = EFI_SUCCESS;
> +    gCallbackKey = 0;
> +    if (gHotKey == 0) {
> +      Status = CallFrontPage ();
> +    } else {
> +      gCallbackKey = gHotKey;
> +      gHotKey = 0;
> +    }
> +
> +    //
> +    // If gCallbackKey is greater than 1 and less or equal to 5,
> +    // it will launch configuration utilities.
> +    // 2 = set language
> +    // 3 = boot manager
> +    // 4 = device manager
> +    // 5 = boot maintenance manager
> +    //
> +    if (gCallbackKey != 0) {
> +      REPORT_STATUS_CODE (
> +        EFI_PROGRESS_CODE,
> +        (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)
> +        );
> +    }
> +
> +    //
> +    // Based on the key that was set, we can determine what to do
> +    //
> +    switch (gCallbackKey) {
> +    //
> +    // The first 4 entries in the Front Page are to be GUARANTEED to remain
> constant so IHV's can
> +    // describe to their customers in documentation how to find their setup
> information (namely
> +    // under the device manager and specific buckets)
> +    //
> +    // These entries consist of the Continue, Select language, Boot Manager,
> and Device Manager
> +    //
> +    case FRONT_PAGE_KEY_CONTINUE:
> +
> +      //
> +      // User hit continue
> +      //
> +      break;
> +
> +    case FRONT_PAGE_KEY_LANGUAGE:
> +
> +      //
> +      // User made a language setting change - display front page again
> +      //
> +      break;
> +
> +    case FRONT_PAGE_KEY_BOOT_MANAGER:
> +      //
> +	  // Remove the installed BootMaint HiiPackages when exit.
> +      //
> +      FreeBMPackage ();
> +
> +      //
> +      // User chose to run the Boot Manager
> +      //
> +      CallBootManager ();
> +
> +	  //
> +      // Reinstall BootMaint HiiPackages after exiting from Boot Manager.
> +      //
> +      InitBMPackage ();
> +      break;
> +
> +    case FRONT_PAGE_KEY_DEVICE_MANAGER:
> +
> +      //
> +      // Display the Device Manager
> +      //
> +      do {
> +        CallDeviceManager ();
> +      } while (gCallbackKey == FRONT_PAGE_KEY_DEVICE_MANAGER);
> +      break;
> +
> +    case FRONT_PAGE_KEY_BOOT_MAINTAIN:
> +
> +      //
> +      // Display the Boot Maintenance Manager
> +      //
> +      BdsStartBootMaint ();
> +      break;
> +    }
> +
> +  } while (((UINTN)gCallbackKey) != FRONT_PAGE_KEY_CONTINUE);
> +
> +  //
> +  //Will leave browser, check any reset required change is applied? if yes,
> reset system
> +  //
> +  SetupResetReminder ();
> +  //
> +  // Remove the installed BootMaint HiiPackages when exit.
> +  //
> +  FreeBMPackage ();
> +
> +Exit:
> +  //
> +  // Automatically load current entry
> +  // Note: The following lines of code only execute when Auto boot
> +  // takes affect
> +  //
> +  PERF_END (NULL, "BdsTimeOut", "BDS", 0);
> +}
> +
> +
> +VOID
> +BootIntoFirmwareInterface(
> +VOID
> +)
> +{
> +  EFI_STATUS        Status;
> +  UINTN             DataSize;
> +  UINT16            Timeout;
> +  UINT64            OsIndication;
> +
> +
> +  OsIndication = 0;
> +  DataSize = sizeof(UINT64);
> +  Status = gRT->GetVariable (
> +                  L"OsIndications",
> +                  &gEfiGlobalVariableGuid,
> +                  NULL,
> +                  &DataSize,
> +                  &OsIndication
> +                  );
> +
> +  DEBUG ((EFI_D_INFO, "OSIndication Variable Value %d\n", OsIndication));
> +  //
> +  //Goto FrontPage directly when bit
> EFI_OS_INDICATIONS_BOOT_TO_FW_UI in OSIndication Variable is setted.
> +  //
> +  if (!EFI_ERROR(Status) && (OsIndication != 0)) {
> 
> +   Timeout = 0xffff;
> +   PlatformBdsEnterFrontPage (Timeout, FALSE);
> +   }
> +}
> +
> +
> +EFI_STATUS
> +PlatformBdsConnectSimpleConsole (
> +  IN BDS_CONSOLE_CONNECT_ENTRY   *PlatformConsole
> +)
> +{
> +  EFI_STATUS                         Status;
> +  UINTN                              Index;
> +  EFI_DEVICE_PATH_PROTOCOL           *VarConout;
> +  EFI_DEVICE_PATH_PROTOCOL           *VarConin;
> +  UINTN                              DevicePathSize;
> +
> +
> +  Index = 0;
> +  Status = EFI_SUCCESS;
> +  DevicePathSize = 0;
> +  VarConout = BdsLibGetVariableAndSize (
> +                L"ConOut",
> +                &gEfiGlobalVariableGuid,
> +                &DevicePathSize
> +                );
> +  VarConin = BdsLibGetVariableAndSize (
> +               L"ConIn",
> +               &gEfiGlobalVariableGuid,
> +               &DevicePathSize
> +               );
> +  if (VarConout == NULL || VarConin == NULL) {
> +    //
> +    // Have chance to connect the platform default console,
> +    // the platform default console is the minimum device group
> +    // the platform should support
> +    //
> +    while (PlatformConsole[Index].DevicePath != NULL) {
> +
> +      //
> +      // Update the console variable with the connect type
> +      //
> +      if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) ==
> CONSOLE_IN) {
> +        BdsLibUpdateConsoleVariable (L"ConIn",
> PlatformConsole[Index].DevicePath, NULL);
> +      }
> +
> +      if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) ==
> CONSOLE_OUT) {
> +        BdsLibUpdateConsoleVariable (L"ConOut",
> PlatformConsole[Index].DevicePath, NULL);
> +      }
> +
> +      if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR)
> {
> +        BdsLibUpdateConsoleVariable (L"ErrOut",
> PlatformConsole[Index].DevicePath, NULL);
> +      }
> +
> +      Index ++;
> +    }
> +  }
> +
> +  //
> +  // Connect ConIn first to give keyboard time to parse hot key event.
> +  //
> +  Status = BdsLibConnectConsoleVariable (L"ConIn");
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Make sure we have at least one active VGA, and have the right
> +  // active VGA in console variable
> +  //
> +  Status = PlatformBdsForceActiveVga ();
> +
> +  //
> +  // It seems impossible not to have any ConOut device on platform,
> +  // so we check the status here.
> +  //
> +  Status = BdsLibConnectConsoleVariable (L"ConOut");
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Timer handler to convert the key from USB.
> +
> +  @param  Event                    Indicates the event that invoke this function.
> +  @param  Context                  Indicates the calling context.
> +**/
> +VOID
> +EFIAPI
> +HotKeyTimerHandler (
> +  IN  EFI_EVENT                 Event,
> +  IN  VOID                      *Context
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  EFI_INPUT_KEY                 Key;
> +
> +  Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
> +  if (EFI_ERROR (Status)) {
> +    return;
> +  }
> +
> +  switch(Key.ScanCode) {
> +  case SCAN_F2:
> +    gHotKey = 0;
> +    mHotKeyPressed = TRUE;
> +    break;
> +
> +  case SCAN_F5:
> +    gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
> +    mHotKeyPressed = TRUE;
> +    break;
> +
> +  case SCAN_F7:
> +    gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER;
> +    mHotKeyPressed = TRUE;
> +    break;
> +
> +  case SCAN_F9:
> +    gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN;
> +    mHotKeyPressed = TRUE;
> +    break;
> +  }
> +
> +  if (mHotKeyPressed) {
> +    gBS->SetTimer (
> +           mHotKeyTimerEvent,
> +           TimerCancel,
> +           0
> +           );
> +    gBS->CloseEvent (mHotKeyTimerEvent);
> +    mHotKeyTimerEvent = NULL;
> +  }
> +
> +  return;
> +}
> +
> +
> +/**
> +  Callback function for SimpleTextInEx protocol install events
> +
> +  @param Event           the event that is signaled.
> +  @param Context         not used here.
> +
> +**/
> +VOID
> +EFIAPI
> +HitHotkeyEvent (
> +  IN EFI_EVENT    Event,
> +  IN VOID         *Context
> +  )
> +{
> +  EFI_STATUS                         Status;
> +
> +  Status = gBS->CloseEvent(mHitHotkeyEvent);
> +  if (EFI_ERROR (Status)) {
> +    return;
> +  }
> +  Status = gBS->CreateEvent (
> +                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
> +                  TPL_NOTIFY,
> +                  HotKeyTimerHandler,
> +                  NULL,
> +                  &mHotKeyTimerEvent
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return;
> +  }
> +  Status = gBS->SetTimer (
> +                  mHotKeyTimerEvent,
> +                  TimerPeriodic,
> +                  KEYBOARD_TIMER_INTERVAL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return;
> +  }
> +
> +  return;
> +}
> +
> +
> +VOID
> +EFIAPI
> +PlatformBdsInitHotKeyEvent (
> +  VOID
> +  )
> +{
> +  EFI_STATUS      Status;
> +
> +  //
> +  // Register Protocol notify for Hotkey service
> +  //
> +  Status = gBS->CreateEvent (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_CALLBACK,
> +                  HitHotkeyEvent,
> +                  NULL,
> +                  &mHitHotkeyEvent
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Register for protocol notifications on this event
> +  //
> +  Status = gBS->RegisterProtocolNotify (
> +                  &gEfiSimpleTextInputExProtocolGuid,
> +                  mHitHotkeyEvent,
> +                  &mHitHotkeyRegistration
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.h
> new file mode 100644
> index 0000000000..b5bb519747
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.h
> @@ -0,0 +1,516 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  BdsPlatform.h
> +
> +Abstract:
> +
> +  Head file for BDS Platform specific code
> +
> +--*/
> +
> +#ifndef _BDS_PLATFORM_H
> +#define _BDS_PLATFORM_H
> +
> +#include <FrameworkDxe.h>
> +
> +#include <Protocol/FirmwareVolume2.h>
> +#include <Protocol/DevicePath.h>
> +#include <Protocol/SimpleNetwork.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +#include <Protocol/LoadFile.h>
> +#include <Protocol/LegacyBios.h>
> +#include <Protocol/PciIo.h>
> +#include <Protocol/SmmAccess2.h>
> +#include <Protocol/DxeSmmReadyToLock.h>
> +#include <Protocol/UserManager.h>
> +#include <Protocol/DeferredImageLoad.h>
> +#include <Protocol/AcpiS3Save.h>
> +#include <Protocol/ExitPmAuth.h>
> +#include <Protocol/MmioDevice.h>
> +#include <Protocol/I2cBusMcg.h>
> +#include <Protocol/I2cHostMcg.h>
> +#include <Guid/CapsuleVendor.h>
> +#include <Guid/MemoryTypeInformation.h>
> +#include <Guid/GlobalVariable.h>
> +#include <Guid/DebugAgentGuid.h>
> +
> +
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/GenericBdsLib.h>
> +#include <Library/PlatformBdsLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/PerformanceLib.h>
> +#include <Library/ReportStatusCodeLib.h>
> +
> +#include <IndustryStandard/Pci.h>
> +
> +extern EFI_DEVICE_PATH_PROTOCOL  *gPlatformRootBridges [];
> +extern BDS_CONSOLE_CONNECT_ENTRY gPlatformConsole [];
> +extern EFI_DEVICE_PATH_PROTOCOL  *gPlatformAllPossiblePciVgaConsole
> [];
> +extern EFI_DEVICE_PATH_PROTOCOL  *gPlatformConnectSequence [];
> +extern EFI_DEVICE_PATH_PROTOCOL  *gPlatformDriverOption [];
> +extern EFI_DEVICE_PATH_PROTOCOL  *gPlatformBootOption [];
> +extern EFI_DEVICE_PATH_PROTOCOL  *gUserAuthenticationDevice[];
> +extern BDS_CONSOLE_CONNECT_ENTRY gPlatformSimpleConsole [];
> +extern EFI_DEVICE_PATH_PROTOCOL  *gPlatformSimpleBootOption [];
> +
> +extern BOOLEAN mEnumBootDevice;
> +
> +
> +//
> +// the short form device path for Usb keyboard
> +//
> +#define CLASS_HID           3
> +#define SUBCLASS_BOOT       1
> +#define PROTOCOL_KEYBOARD   1
> +
> +#define PCI_DEVICE_PATH_NODE(Func, Dev) \
> +  { \
> +    HARDWARE_DEVICE_PATH, \
> +    HW_PCI_DP, \
> +    { \
> +      (UINT8) (sizeof (PCI_DEVICE_PATH)), \
> +      (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) \
> +    }, \
> +    (Func), \
> +    (Dev) \
> +  }
> +
> +#define PNPID_DEVICE_PATH_NODE(PnpId) \
> +  { \
> +    { \
> +      ACPI_DEVICE_PATH, \
> +      ACPI_DP, \
> +      { \
> +        (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \
> +        (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \
> +      } \
> +    }, \
> +    EISA_PNP_ID((PnpId)), \
> +    0 \
> +  }
> +
> +#define gUart(BaudRate, DataBits, Parity, StopBits) \
> +  { \
> +    { \
> +      MESSAGING_DEVICE_PATH, \
> +      MSG_UART_DP, \
> +      { \
> +        (UINT8) (sizeof (UART_DEVICE_PATH)), \
> +        (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8) \
> +      } \
> +    }, \
> +    0, \
> +    (BaudRate), \
> +    (DataBits), \
> +    (Parity), \
> +    (StopBits) \
> +  }
> +
> +#define gPcAnsiTerminal \
> +  { \
> +    { \
> +      MESSAGING_DEVICE_PATH, \
> +      MSG_VENDOR_DP, \
> +      { \
> +        (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \
> +        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \
> +      } \
> +    }, \
> +    DEVICE_PATH_MESSAGING_PC_ANSI \
> +  }
> +
> +#define gUsbKeyboardMouse \
> +  { \
> +    { \
> +      MESSAGING_DEVICE_PATH, \
> +      MSG_USB_CLASS_DP, \
> +      (UINT8) (sizeof (USB_CLASS_DEVICE_PATH)), \
> +      (UINT8) ((sizeof (USB_CLASS_DEVICE_PATH)) >> 8) \
> +    }, \
> +    0xffff, \
> +    0xffff, \
> +    CLASS_HID, \
> +    SUBCLASS_BOOT, \
> +    PROTOCOL_KEYBOARD \
> +  }
> +
> +#define gEndEntire \
> +  { \
> +    END_DEVICE_PATH_TYPE, \
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE, \
> +    { \
> +      END_DEVICE_PATH_LENGTH, \
> +      0 \
> +    } \
> +  }
> +
> +#define gPciRootBridge \
> +  PNPID_DEVICE_PATH_NODE(0x0A03)
> +
> +#define gPnpPs2Keyboard \
> +  PNPID_DEVICE_PATH_NODE(0x0303)
> +
> +#define gPnp16550ComPort \
> +  PNPID_DEVICE_PATH_NODE(0x0501)
> +
> +#define gPciePort0Bridge \
> +  PCI_DEVICE_PATH_NODE(0, 0x1C)
> +
> +#define gPciePort1Bridge \
> +  PCI_DEVICE_PATH_NODE(1, 0x1C)
> +
> +#define gPciePort2Bridge \
> +  PCI_DEVICE_PATH_NODE(2, 0x1C)
> +
> +#define gPciePort3Bridge \
> +  PCI_DEVICE_PATH_NODE(3, 0x1C)
> +
> +#define gPciIsaBridge \
> +  PCI_DEVICE_PATH_NODE(0, 0x1f)
> +
> +//
> +// Platform Root Bridge
> +//
> +typedef struct {
> +  ACPI_HID_DEVICE_PATH      PciRootBridge;
> +  EFI_DEVICE_PATH_PROTOCOL  End;
> +} PLATFORM_ROOT_BRIDGE_DEVICE_PATH;
> +
> +//
> +// Below is the platform console device path
> +//
> +typedef struct {
> +  ACPI_HID_DEVICE_PATH      PciRootBridge;
> +  PCI_DEVICE_PATH           IsaBridge;
> +  ACPI_HID_DEVICE_PATH      Keyboard;
> +  EFI_DEVICE_PATH_PROTOCOL  End;
> +} PLATFORM_ISA_KEYBOARD_DEVICE_PATH;
> +
> +typedef struct {
> +  VENDOR_DEVICE_PATH             VendorDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL       End;
> +} HII_VENDOR_DEVICE_PATH;
> +
> +typedef struct {
> +  USB_CLASS_DEVICE_PATH           UsbClass;
> +  EFI_DEVICE_PATH_PROTOCOL        End;
> +} USB_CLASS_FORMAT_DEVICE_PATH;
> +
> +typedef struct {
> +  ACPI_HID_DEVICE_PATH      PciRootBridge;
> +  PCI_DEVICE_PATH           OnboardVga;
> +  EFI_DEVICE_PATH_PROTOCOL  End;
> +} PLATFORM_ONBOARD_VGA_DEVICE_PATH;
> +
> +typedef struct {
> +  ACPI_HID_DEVICE_PATH      PciRootBridge;
> +  PCI_DEVICE_PATH           AgpBridge;
> +  PCI_DEVICE_PATH           AgpDevice;
> +  EFI_DEVICE_PATH_PROTOCOL  End;
> +} PLATFORM_OFFBOARD_VGA_DEVICE_PATH;
> +
> +typedef struct {
> +  ACPI_HID_DEVICE_PATH      PciRootBridge;
> +  PCI_DEVICE_PATH           IsaBridge;
> +  ACPI_HID_DEVICE_PATH      IsaSerial;
> +  UART_DEVICE_PATH          Uart;
> +  VENDOR_DEVICE_PATH        TerminalType;
> +  EFI_DEVICE_PATH_PROTOCOL  End;
> +} PLATFORM_ISA_SERIAL_DEVICE_PATH;
> +
> +//
> +// Below is the boot option device path
> +//
> +typedef struct {
> +  BBS_BBS_DEVICE_PATH             LegacyHD;
> +  EFI_DEVICE_PATH_PROTOCOL        End;
> +} LEGACY_HD_DEVICE_PATH;
> +
> +//
> +// Below is the platform IDE device path
> +//
> +typedef struct {
> +  ACPI_HID_DEVICE_PATH      PciRootBridge;
> +  PCI_DEVICE_PATH           IsaBridge;
> +  ATAPI_DEVICE_PATH         Ide;
> +  EFI_DEVICE_PATH_PROTOCOL  End;
> +} PLATFORM_IDE_DEVICE_PATH;
> +
> +//
> +// Floppy device path definition
> +//
> +typedef struct {
> +  ACPI_HID_DEVICE_PATH      PciRootBridge;
> +  PCI_DEVICE_PATH           IsaBridge;
> +  ACPI_HID_DEVICE_PATH      Floppy;
> +  EFI_DEVICE_PATH_PROTOCOL  End;
> +} PLATFORM_FLOPPY_DEVICE_PATH;
> +
> +//
> +// Below is the platform USB controller device path for
> +// USB disk as user authentication device.
> +//
> +typedef struct {
> +  ACPI_HID_DEVICE_PATH      PciRootBridge;
> +  PCI_DEVICE_PATH           PciDevice;
> +  EFI_DEVICE_PATH_PROTOCOL  End;
> +} PLATFORM_USB_DEVICE_PATH;
> +
> +//
> +// Debug Agent UART Console device path definition
> +//
> +typedef struct {
> +  VENDOR_DEVICE_PATH        VendorHardware;
> +  UART_DEVICE_PATH          Uart;
> +  VENDOR_DEVICE_PATH        TerminalType;
> +  EFI_DEVICE_PATH_PROTOCOL  End;
> +} VENDOR_UART_DEVICE_PATH;
> +
> +//
> +// Below is the platform PCI device path
> +//
> +typedef struct {
> +  ACPI_HID_DEVICE_PATH      PciRootBridge;
> +  PCI_DEVICE_PATH           PciDevice;
> +  EFI_DEVICE_PATH_PROTOCOL  End;
> +} PLATFORM_PCI_DEVICE_PATH;
> +
> +typedef enum {
> +  PMIC_Equal         = 0, // =		0
> +  PMIC_Greater_Than,	  // >		1
> +  PMIC_Smaller_Than,	  // <		2
> +  PMIC_Greater_Equal,	  // >=		3
> +  PMIC_Smaller_Equal,	  // <=		4
> +  PMIC_Any				  // don't care 5
> +} PMIC_Condition_list;
> +
> +typedef enum {
> +  PMIC_White_List	= 0,  //White list
> +  PMIC_Black_List	= 1   //Black list
> +} PMIC_Compliance_mode;
> +
> +typedef struct {
> +  UINT8		Cond_Choice;	// PMIC_Condition_list
> +  UINT8		Cond_Number;		// the number
> +}PMIC_Condition_Item;
> +
> +typedef struct {
> +  PMIC_Condition_Item
> 	PMIC_BoardID;
> +  PMIC_Condition_Item   					PMIC_FabID;
> +  PMIC_Condition_Item
> 	Soc_Stepping;//define PMIC type, 1:Dialog , 2:Rohm
> +  PMIC_Condition_Item
> 	PMIC_VendID;
> +  PMIC_Condition_Item   					PMIC_RevID;
> +  PMIC_Compliance_mode 				        mode;        //if 1,
> blacklist; if 0, white list.
> +} PMIC_Compliance_Item;
> +
> +//
> +// Platform BDS Functions
> +//
> +VOID
> +PlatformBdsGetDriverOption (
> +  IN LIST_ENTRY                   *BdsDriverLists
> +  );
> +
> +VOID
> +PlatformBdsPredictBootOption (
> +  IN  LIST_ENTRY                     *BdsBootOptionList
> +  );
> +
> +EFI_STATUS
> +PlatformBdsShowProgress (
> +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground,
> +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground,
> +  CHAR16                        *Title,
> +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor,
> +  UINTN                         Progress,
> +  UINTN                         PreviousValue
> +  );
> +
> +VOID
> +PlatformBdsConnectSequence (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +PlatformBdsConnectConsole (
> +  IN BDS_CONSOLE_CONNECT_ENTRY   *PlatformConsole
> +  );
> +
> +EFI_STATUS
> +PlatformBdsNoConsoleAction (
> +  VOID
> +  );
> +
> +VOID
> +PlatformBdsEnterFrontPage (
> +  IN UINT16                 TimeoutDefault,
> +  IN BOOLEAN                ConnectAllHappened
> +  );
> +
> +VOID
> +EFIAPI
> +PlatformBdsUserIdentify (
> +  OUT EFI_USER_PROFILE_HANDLE        *User,
> +  OUT BOOLEAN                        *DeferredImage
> +  );
> +
> +VOID
> +EFIAPI
> +PlatformBdsConnectAuthDevice (
> +  VOID
> +  );
> +
> +VOID
> +PlatformBdsEnterFrontPageWithHotKey (
> +  IN UINT16                       TimeoutDefault,
> +  IN BOOLEAN                      ConnectAllHappened
> +  );
> +
> + EFI_STATUS
> + ShowProgress (
> +   IN UINT16					   TimeoutDefault
> +   );
> +
> + EFI_STATUS
> + InitializeFrontPage (
> +   IN BOOLEAN						  InitializeHiiData
> +   );
> +
> + VOID
> + UpdateFrontPageStrings (
> +   VOID
> +   );
> +
> +
> + EFI_STATUS
> + InitBMPackage  (
> +   VOID
> +   );
> +
> +
> + VOID
> + FreeBMPackage  (
> +   VOID
> +   );
> +
> +
> + EFI_STATUS
> + CallFrontPage (
> +   VOID
> +   );
> +
> +
> + VOID
> + CallBootManager (
> +   VOID
> +   );
> +
> +VOID
> +CallDeviceManager (
> +  VOID
> +  );
> +
> +VOID
> +BdsStartBootMaint (
> +  VOID
> +  );
> +
> +CHAR16 *
> +GetStringById (
> +  IN  EFI_STRING_ID   Id
> +  );
> +
> +EFI_STATUS
> +WaitForSingleEvent (
> +  IN EFI_EVENT                  Event,
> +  IN UINT64                     Timeout OPTIONAL
> +  );
> +
> +EFI_STATUS
> +BdsLibDeleteOptionFromHandle (
> +  IN  EFI_HANDLE                 Handle
> +  );
> +
> +EFI_STATUS
> +BdsDeleteAllInvalidEfiBootOption (
> +  VOID
> +  );
> +
> +
> +#define ONE_SECOND  10000000
> +#define FRONT_PAGE_KEY_CONTINUE        0x1000
> +#define FRONT_PAGE_KEY_LANGUAGE        0x1234
> +#define FRONT_PAGE_KEY_BOOT_MANAGER    0x1064
> +#define FRONT_PAGE_KEY_DEVICE_MANAGER  0x8567
> +#define FRONT_PAGE_KEY_BOOT_MAINTAIN   0x9876
> +
> +#define PORT_A_DVO                     0           // ; DVO A
> +#define PORT_B_DVO                     1           // ; DVO B
> +#define PORT_C_DVO                     2           // ; DVO C
> +#define PORT_D_DVO                     3           // ; DVO D
> +#define PORT_LVDS                      4           // ; Integrated LVDS port
> +#define PORT_ANALOG_TV                 5           // ; Integrated TV port
> +#define PORT_CRT                       6           // ; integrated Analog port
> +#define PORT_B_DP                      7           // ; DisplayPort B
> +#define PORT_C_DP                      8           // ; DisplayPort C
> +#define PORT_D_DP                      9           // ; DisplayPort D
> +#define PORT_A_DP                      10          // ; DisplayPort A (for eDP on ILK)
> +#define PORT_B_HDMI                    11          // ; HDMI B
> +#define PORT_C_HDMI                    12          // ; HDMI C
> +#define PORT_D_HDMI                    13          // ; HDMI D
> +#define PORT_B_DVI                     14          // ; DVI B
> +#define PORT_C_DVI                     15          // ; DVI C
> +#define PORT_D_DVI                     16          // ; DVI D
> +#define PORT_MIPI_A                    21          // ; MIPI
> +#define PORT_MIPI_B                    22
> +#define PORT_MIPI_C                    23
> +
> +
> +extern BOOLEAN gConnectAllHappened;
> +extern UINTN gCallbackKey;
> +
> +VOID
> +BdsBootDeviceSelect (
> +  VOID
> +);
> +VOID FastBoot(VOID);
> +
> +extern BOOLEAN    mModeInitialized;
> +
> +//
> +// Boot video resolution and text mode.
> +//
> +extern UINT32     mBootHorizontalResolution    ;
> +extern UINT32     mBootVerticalResolution      ;
> +extern UINT32     mBootTextModeColumn          ;
> +extern UINT32     mBootTextModeRow             ;
> +
> +//
> +// BIOS setup video resolution and text mode.
> +//
> +extern UINT32     mSetupTextModeColumn         ;
> +extern UINT32     mSetupTextModeRow            ;
> +extern UINT32     mSetupHorizontalResolution   ;
> +extern UINT32     mSetupVerticalResolution     ;
> +extern EFI_STATUS BdsSetConsoleMode (BOOLEAN);
> +#endif // _BDS_PLATFORM_H
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsLib.i
> nf
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsLib.i
> nf
> new file mode 100644
> index 0000000000..d3bef0fa39
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsLib.i
> nf
> @@ -0,0 +1,127 @@
> +#/** @file
> +# Component name for module PlatformBootManagerLib
> +#
> +# Copyright (c) 2008  - 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> +
> +#
> +#
> +#
> +#**/
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = PlatformBdsLib
> +  FILE_GUID                      = A6BC385D-59E5-4b77-87D7-200ABAA83C15
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = PlatformBootManagerLib|DXE_DRIVER
> +  EDK_RELEASE_VERSION            = 0x00020000
> +  EFI_SPECIFICATION_VERSION      = 0x0002000A
> +
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +
> +[Sources]
> +  BdsPlatform.c
> +  BdsPlatform.h
> +  PlatformData.c
> +  PlatformBdsStrings.uni
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  IntelFrameworkPkg/IntelFrameworkPkg.dec
> +  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +  ShellPkg/ShellPkg.dec
> +  CryptoPkg/CryptoPkg.dec
> +  SecurityPkg/SecurityPkg.dec
> +  SignedCapsulePkg/SignedCapsulePkg.dec
> +  SourceLevelDebugPkg/SourceLevelDebugPkg.dec
> +
> +[LibraryClasses]
> +  DxeServicesTableLib
> +  BaseLib
> +  MemoryAllocationLib
> +  UefiBootServicesTableLib
> +  UefiRuntimeServicesTableLib
> +  BaseMemoryLib
> +  DebugLib
> +  PcdLib
> +  GenericBdsLib
> +  DevicePathLib
> +  NetLib
> +  UefiLib
> +  HobLib
> +  PciLib
> +  PrintLib
> +  BaseCryptLib
> +#  TcgPhysicalPresenceLib
> +  Tcg2PhysicalPresenceLib
> +  FileHandleLib
> +  S3BootScriptLib
> +  SerialPortLib
> +  CapsuleLib
> +
> +[Protocols]
> +  gEfiFirmwareVolume2ProtocolGuid
> +  gEfiSimpleNetworkProtocolGuid
> +  gEfiLoadFileProtocolGuid
> +  gEfiPciIoProtocolGuid
> +  gEfiSmmAccess2ProtocolGuid
> +  gEfiDxeSmmReadyToLockProtocolGuid
> +  gEfiUserManagerProtocolGuid
> +  gEfiDeferredImageLoadProtocolGuid
> +  gEfiAcpiS3SaveProtocolGuid
> +  gEfiSpiProtocolGuid                           ## PROTOCOL CONSUMES
> +  gExitPmAuthProtocolGuid
> +  gEfiTdtOperationProtocolGuid
> +  gEfiGlobalNvsAreaProtocolGuid
> +  gEfiMmioDeviceProtocolGuid
> +  gEfiI2cMasterProtocolGuid
> +  gEfiI2cHostProtocolGuid
> +  gEsrtManagementProtocolGuid
> +
> +[Guids]
> +  gEfiMemoryTypeInformationGuid
> +  gEfiCapsuleVendorGuid
> +  gEfiGlobalVariableGuid
> +  gEfiNormalSetupGuid
> +  gEfiPartTypeSystemPartGuid
> +  gEfiEndOfDxeEventGroupGuid
> +  gUefiShellFileGuid
> +
> +[Pcd]
> +
> gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiRsa2048Sha256TestPublicKey
> FileGuid
> +
> gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiPkcs7TestPublicKeyFileGuid
> +  gEfiSecurityPkgTokenSpaceGuid.PcdRsa2048Sha256PublicKeyBuffer
> +  gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdTestKeyUsed
> +  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Base
> +  gPlatformModuleTokenSpaceGuid.PcdFlashFvMainBase
> +  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoveryBase
> +  gPlatformModuleTokenSpaceGuid.PcdFlashFvShellBase
> +  gPlatformModuleTokenSpaceGuid.PcdFlashFvShellSize
> +  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
> +  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile
> +  gPlatformModuleTokenSpaceGuid.PcdIFWISigBaseAddress
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutColumn
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutRow
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution
> +  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBootState
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsStri
> ngs.uni
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsStri
> ngs.uni
> new file mode 100644
> index 0000000000..101106f9f4
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsStri
> ngs.uni
> @@ -0,0 +1,30 @@
> +///** @file
> +//
> +//  String definitions for Boot Option description.
> +//
> +//  Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
> +//  SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//**/
> +
> +/=#
> +
> +#langdef   en-US "English"
> +#langdef   fr-FR "Français"
> +
> +#string STR_DESCRIPTION_FLOPPY         #language en-US  "EFI Floppy"
> +                                       #language fr-FR  "fr-FR: EFI Floppy"
> +#string STR_DESCRIPTION_CD_DVD         #language en-US  "EFI
> DVD/CDROM"
> +                                       #language fr-FR  "fr-FR: EFI DVD/CDROM"
> +#string STR_DESCRIPTION_HARDDRIVE      #language en-US  "EFI Hard Drive"
> +                                       #language fr-FR  "fr-FR: EFI Hard Drive"
> +#string STR_DESCRIPTION_USB            #language en-US  "EFI USB Device"
> +                                       #language fr-FR  "fr-FR: EFI USB Device"
> +#string STR_DESCRIPTION_SCSI           #language en-US  "EFI SCSI Device"
> +                                       #language fr-FR  "fr-FR: EFI SCSI Device"
> +#string STR_DESCRIPTION_MISC           #language en-US  "EFI Misc Device"
> +                                       #language fr-FR  "fr-FR: EFI Misc Device"
> +#string STR_DESCRIPTION_NETWORK        #language en-US  "EFI Network"
> +                                       #language fr-FR  "fr-FR: EFI Network"
> +#string STR_DESCRIPTION_NON_BLOCK      #language en-US  "EFI Non-Block
> Boot Device"
> +                                       #language fr-FR  "fr-FR: EFI Non-Block Boot Device"
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformData.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformData.c
> new file mode 100644
> index 0000000000..9dff93f52b
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformData.c
> @@ -0,0 +1,306 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  PlatformData.c
> +
> +Abstract:
> +
> +  Defined the platform specific device path which will be used by
> +  platform Bbd to perform the platform policy connect.
> +
> +--*/
> +
> +#include "BdsPlatform.h"
> +
> +//
> +// Predefined platform default time out value
> +//
> +UINT16  gPlatformBootTimeOutDefault = 10;
> +
> +//
> +// Predefined platform root bridge
> +//
> +PLATFORM_ROOT_BRIDGE_DEVICE_PATH gPlatformRootBridge0 = {
> +  gPciRootBridge,
> +  gEndEntire
> +};
> +
> +EFI_DEVICE_PATH_PROTOCOL* gPlatformRootBridges [] = {
> +  (EFI_DEVICE_PATH_PROTOCOL*)&gPlatformRootBridge0,
> +  NULL
> +};
> +
> +//
> +// Platform specific ISA keyboard device path
> +//
> +PLATFORM_ISA_KEYBOARD_DEVICE_PATH gIsaKeyboardDevicePath = {
> +  gPciRootBridge,
> +  gPciIsaBridge,
> +  gPnpPs2Keyboard,
> +  gEndEntire
> +};
> +
> +//
> +// Platform specific on chip PCI VGA device path
> +//
> +PLATFORM_ONBOARD_VGA_DEVICE_PATH gOnChipPciVgaDevicePath = {
> +  gPciRootBridge,
> +  PCI_DEVICE_PATH_NODE(0, 0x2),
> +  gEndEntire
> +};
> +
> +//
> +// Platform specific plug in PCI VGA device path
> +//
> +PLATFORM_OFFBOARD_VGA_DEVICE_PATH gPlugInPciVgaDevicePath = {
> +  gPciRootBridge,
> +  PCI_DEVICE_PATH_NODE(0, 0x1),
> +  PCI_DEVICE_PATH_NODE(0, 0x0),
> +  gEndEntire
> +};
> +
> +//
> +// Platform specific ISA serial device path
> +//
> +PLATFORM_ISA_SERIAL_DEVICE_PATH gIsaSerialDevicePath = {
> +  gPciRootBridge,
> +  gPciIsaBridge,
> +  gPnp16550ComPort,
> +  gUart(115200, 8, 1, 1),
> +  gPcAnsiTerminal,
> +  gEndEntire
> +};
> +
> +
> +//
> +// Platform specific Button Array device path
> +//
> +HII_VENDOR_DEVICE_PATH  gHiiVendorDevicePath0 = {
> +  {
> +    {
> +      HARDWARE_DEVICE_PATH,
> +      HW_VENDOR_DP,
> +      {
> +        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
> +        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
> +      }
> +    },
> +
> +    //
> +    // {C8752FDE-B5C8-4528-897D-6920FE771E38}
> +    //
> +    { 0xC8752FDE, 0xB5C8, 0x4528, { 0x89, 0x7D, 0x69, 0x20, 0xFE, 0x77, 0x1E,
> 0x38 } }
> +  },
> +  {
> +    END_DEVICE_PATH_TYPE,
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +    {
> +      (UINT8) (END_DEVICE_PATH_LENGTH),
> +      (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
> +    }
> +  }
> +};
> +
> +USB_CLASS_FORMAT_DEVICE_PATH gUsbClassKeyboardDevicePath = {
> +  gUsbKeyboardMouse,
> +  gEndEntire
> +};
> +
> +//
> +// Debug Agent UART Console device path
> +//
> +VENDOR_UART_DEVICE_PATH gDebugAgentUartDevicePath = {
> +  {
> +    {
> +      HARDWARE_DEVICE_PATH,
> +      HW_VENDOR_DP,
> +      {
> +        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
> +        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
> +      }
> +    },
> +    EFI_DEBUG_AGENT_GUID,
> +  },
> +  {
> +    {
> +      MESSAGING_DEVICE_PATH,
> +      MSG_UART_DP,
> +      {
> +        (UINT8) (sizeof (UART_DEVICE_PATH)),
> +        (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8)
> +      }
> +    },
> +    0,  // Reserved
> +    0,  // BaudRate - Default
> +    0,  // DataBits - Default
> +    0,  // Parity   - Default
> +    0,  // StopBits - Default
> +  },
> +  {
> +    {
> +      MESSAGING_DEVICE_PATH,
> +      MSG_VENDOR_DP,
> +      {
> +        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
> +        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
> +      }
> +    },
> +    DEVICE_PATH_MESSAGING_PC_ANSI
> +  },
> +  gEndEntire
> +};
> +
> +//
> +// Predefined platform default console device path
> +//
> +BDS_CONSOLE_CONNECT_ENTRY gPlatformConsole [] = {
> +  {(EFI_DEVICE_PATH_PROTOCOL*)&gIsaSerialDevicePath, CONSOLE_ALL},
> +  {(EFI_DEVICE_PATH_PROTOCOL*)&gHiiVendorDevicePath0, CONSOLE_IN},
> +  {(EFI_DEVICE_PATH_PROTOCOL*)&gIsaKeyboardDevicePath,
> CONSOLE_IN},
> +  {(EFI_DEVICE_PATH_PROTOCOL*)&gDebugAgentUartDevicePath,
> CONSOLE_ALL},
> +  {(EFI_DEVICE_PATH_PROTOCOL*)&gUsbClassKeyboardDevicePath,
> CONSOLE_IN},
> +  {NULL, 0}
> +};
> +
> +//
> +// All the possible platform PCI VGA device path
> +//
> +EFI_DEVICE_PATH_PROTOCOL* gPlatformAllPossiblePciVgaConsole [] = {
> +  (EFI_DEVICE_PATH_PROTOCOL*)&gOnChipPciVgaDevicePath,
> +  (EFI_DEVICE_PATH_PROTOCOL*)&gPlugInPciVgaDevicePath,
> +  NULL
> +};
> +
> +//
> +// Legacy hard disk boot option
> +//
> +LEGACY_HD_DEVICE_PATH gLegacyHd = {
> +  {
> +    BBS_DEVICE_PATH,
> +    BBS_BBS_DP,
> +    (UINT8)(sizeof(BBS_BBS_DEVICE_PATH)),
> +    (UINT8)((sizeof(BBS_BBS_DEVICE_PATH)) >> 8),
> +    BBS_TYPE_HARDDRIVE,
> +    0,
> +    0
> +  },
> +  gEndEntire
> +};
> +
> +//
> +// Legacy cdrom boot option
> +//
> +LEGACY_HD_DEVICE_PATH gLegacyCdrom = {
> +  {
> +    BBS_DEVICE_PATH,
> +    BBS_BBS_DP,
> +    (UINT8)(sizeof(BBS_BBS_DEVICE_PATH)),
> +    (UINT8)((sizeof(BBS_BBS_DEVICE_PATH)) >> 8),
> +    BBS_TYPE_CDROM,
> +    0,
> +    0
> +  },
> +  gEndEntire
> +};
> +
> +//
> +// Predefined platform specific perdict boot option
> +//
> +EFI_DEVICE_PATH_PROTOCOL* gPlatformBootOption [] = {
> +  (EFI_DEVICE_PATH_PROTOCOL*)&gLegacyHd,
> +  (EFI_DEVICE_PATH_PROTOCOL*)&gLegacyCdrom,
> +  NULL
> +};
> +
> +//
> +// Predefined platform specific driver option
> +//
> +EFI_DEVICE_PATH_PROTOCOL* gPlatformDriverOption [] = {
> +  NULL
> +};
> +
> +//
> +// Predefined platform connect sequence
> +//
> +EFI_DEVICE_PATH_PROTOCOL* gPlatformConnectSequence [] = {
> +  (EFI_DEVICE_PATH_PROTOCOL *)&gPlatformRootBridge0,  // Force PCI
> enumer before Legacy OpROM shadow
> +  NULL
> +};
> +
> +//
> +// Platform specific USB controller device path
> +//
> +PLATFORM_USB_DEVICE_PATH gUsbDevicePath0 = {
> +  gPciRootBridge,
> +  PCI_DEVICE_PATH_NODE(0, 0x1D),
> +  gEndEntire
> +};
> +
> +PLATFORM_USB_DEVICE_PATH gUsbDevicePath1 = {
> +  gPciRootBridge,
> +  PCI_DEVICE_PATH_NODE(1, 0x1D),
> +  gEndEntire
> +};
> +
> +PLATFORM_USB_DEVICE_PATH gUsbDevicePath2 = {
> +  gPciRootBridge,
> +  PCI_DEVICE_PATH_NODE(2, 0x1D),
> +  gEndEntire
> +};
> +
> +PLATFORM_USB_DEVICE_PATH gUsbDevicePath3 = {
> +  gPciRootBridge,
> +  PCI_DEVICE_PATH_NODE(3, 0x1D),
> +  gEndEntire
> +};
> +
> +//
> +// Predefined platform device path for user authtication
> +//
> +EFI_DEVICE_PATH_PROTOCOL* gUserAuthenticationDevice[] = {
> +  //
> +  // Predefined device path for secure card (USB disk).
> +  //
> +  (EFI_DEVICE_PATH_PROTOCOL*)&gUsbDevicePath0,
> +  (EFI_DEVICE_PATH_PROTOCOL*)&gUsbDevicePath1,
> +  (EFI_DEVICE_PATH_PROTOCOL*)&gUsbDevicePath2,
> +  (EFI_DEVICE_PATH_PROTOCOL*)&gUsbDevicePath3,
> +  NULL
> +};
> +
> +//
> +// Predefined platform console device path
> +//
> +BDS_CONSOLE_CONNECT_ENTRY gPlatformSimpleConsole [] = {
> +  {(EFI_DEVICE_PATH_PROTOCOL*)&gOnChipPciVgaDevicePath,
> CONSOLE_OUT},
> +  {(EFI_DEVICE_PATH_PROTOCOL*)&gIsaSerialDevicePath, CONSOLE_ALL},
> +  {(EFI_DEVICE_PATH_PROTOCOL*)&gHiiVendorDevicePath0, CONSOLE_IN},
> +  {(EFI_DEVICE_PATH_PROTOCOL*)&gDebugAgentUartDevicePath,
> CONSOLE_ALL},
> +  {(EFI_DEVICE_PATH_PROTOCOL*)&gUsbClassKeyboardDevicePath,
> CONSOLE_IN},
> +  {NULL, 0}
> +};
> +
> +//
> +// eMMC device at BDF(0x0, 0x17, 0x0)
> +//
> +PLATFORM_PCI_DEVICE_PATH gEmmcBootDevPath0 = {
> +  gPciRootBridge,
> +  PCI_DEVICE_PATH_NODE (0x00, 0x10),
> +  gEndEntire
> +};
> +
> +//
> +// Predefined platform specific perdict boot option
> +//
> +EFI_DEVICE_PATH_PROTOCOL* gPlatformSimpleBootOption [] = {
> +  (EFI_DEVICE_PATH_PROTOCOL*)&gEmmcBootDevPath0,
> +  NULL
> +};
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmos
> Lib.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmos
> Lib.c
> new file mode 100644
> index 0000000000..2a02cabcaf
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmos
> Lib.c
> @@ -0,0 +1,106 @@
> +/*++
> +
> +Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  CmosTable.h
> +
> +Abstract:
> +
> +--*/
> +
> +#include <Base.h>
> +#include <Library/IoLib.h>
> +#include <Library/PlatformCmosLib.h>
> +#include "CmosMap.h"
> +#include <PchAccess.h>
> +#include "PlatformBaseAddresses.h"
> +
> +#define DEFAULT_VALUE          0
> +#define  DEFAULT_ATTRIBUTES     0
> +#define  EXCLUDE_FROM_CHECKSUM
> CMOS_ATTRIBUTE_EXCLUDE_FROM_CHECKSUM
> +
> +#define CMOS_DEBUG_PRINT_LEVEL_DEFAULT_VALUE      0x46   //
> EFI_D_WARN|EFI_D_INFO|EFI_D_LOAD
> +#define CMOS_DEBUG_PRINT_LEVEL_3_DEFAULT_VALUE    0x80   //
> EFI_D_ERROR
> +
> +//
> +// Add the CMOS entry below
> +//
> +CMOS_ENTRY mCmosTable[] = {
> +{ CPU_HT_POLICY, CPU_HT_POLICY_ENABLED,
> EXCLUDE_FROM_CHECKSUM },
> +{ TPM_POLICY, TPM_POLICY_ENABLED, DEFAULT_ATTRIBUTES },
> +{ CMOS_LCDPANELTYPE_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
> +{ CMOS_LCDPANELSCALING_REG, DEFAULT_VALUE,
> DEFAULT_ATTRIBUTES },
> +{ CMOS_IGDBOOTTYPE_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
> +{ CMOS_BACKLIGHT_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
> +{ CMOS_LFP_PANEL_COLOR_DEPTH_REG, DEFAULT_VALUE,
> DEFAULT_ATTRIBUTES },
> +{ CMOS_EDP_ACTIVE_LFP_CONFIG_REG, DEFAULT_VALUE,
> DEFAULT_ATTRIBUTES },
> +{ CMOS_PRIMARY_DISPLAY_REG, DEFAULT_VALUE,
> DEFAULT_ATTRIBUTES },
> +{ CMOS_IGD_DISPLAY_PIPE_B_REG, DEFAULT_VALUE,
> DEFAULT_ATTRIBUTES },
> +{ CMOS_SDVOPANELTYPE_REG, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
> +{ CMOS_PLATFORM_RESET_OS, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
> +{ CMOS_CPU_BSP_SELECT, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
> +{ CMOS_CPU_RATIO_OFFSET, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
> +{ CMOS_ICH_PORT80_OFFSET, DEFAULT_VALUE, DEFAULT_ATTRIBUTES },
> +{ CMOS_MAXRATIO_CONFIG_REG, DEFAULT_VALUE,
> DEFAULT_ATTRIBUTES },
> +{ RTC_ADDRESS_CENTURY, RTC_ADDRESS_CENTURY_DEFAULT,
> CMOS_ATTRIBUTE_EXCLUDE_FROM_CHECKSUM },
> +{ CMOS_POST_CODE_BREAK_REG, DEFAULT_VALUE,
> EXCLUDE_FROM_CHECKSUM },
> +{ CMOS_POST_CODE_BREAK_1_REG, DEFAULT_VALUE,
> EXCLUDE_FROM_CHECKSUM },
> +{ CMOS_POST_CODE_BREAK_2_REG, DEFAULT_VALUE,
> EXCLUDE_FROM_CHECKSUM },
> +{ CMOS_POST_CODE_BREAK_3_REG, DEFAULT_VALUE,
> EXCLUDE_FROM_CHECKSUM },
> +{ CMOS_DEBUG_PRINT_LEVEL_REG,
> CMOS_DEBUG_PRINT_LEVEL_DEFAULT_VALUE,
> EXCLUDE_FROM_CHECKSUM },
> +{ CMOS_DEBUG_PRINT_LEVEL_1_REG, DEFAULT_VALUE,
> EXCLUDE_FROM_CHECKSUM },
> +{ CMOS_DEBUG_PRINT_LEVEL_2_REG, DEFAULT_VALUE,
> EXCLUDE_FROM_CHECKSUM },
> +{ CMOS_DEBUG_PRINT_LEVEL_3_REG,
> CMOS_DEBUG_PRINT_LEVEL_3_DEFAULT_VALUE,
> EXCLUDE_FROM_CHECKSUM },
> +};
> +
> +/**
> +  Funtion to return platform CMOS entry.
> +
> +  @param [out]  CmosEntry  Platform CMOS entry.
> +
> +  @param [out]  CmosEntryCount Number of platform CMOS entry.
> +
> +  @return Status.
> +**/
> +RETURN_STATUS
> +EFIAPI
> +GetPlatformCmosEntry (
> +  OUT CMOS_ENTRY  **CmosEntry,
> +  OUT UINTN       *CmosEntryCount
> +  )
> +{
> +  *CmosEntry = mCmosTable;
> +  *CmosEntryCount = sizeof(mCmosTable)/sizeof(mCmosTable[0]);
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Function to check if Battery lost or CMOS cleared.
> +
> +  @reval TRUE  Battery is always present.
> +  @reval FALSE CMOS is cleared.
> +**/
> +BOOLEAN
> +EFIAPI
> +CheckCmosBatteryStatus (
> +  VOID
> +  )
> +{
> +  //
> +  // Check if the CMOS battery is present
> +  // Checks RTC_PWR_STS bit in the GEN_PMCON_1 register
> +  //
> +
> +  if ((MmioRead8 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1) &
> B_PCH_PMC_GEN_PMCON_RTC_PWR_STS) == 0) {
> +    return TRUE;
> +  } else {
> +    return FALSE;
> +  }
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmos
> Lib.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmos
> Lib.inf
> new file mode 100644
> index 0000000000..c5d8b66591
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmos
> Lib.inf
> @@ -0,0 +1,30 @@
> +#/** @file
> +#
> +# Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +#
> +#
> +#**/
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = PlatformCmosLib
> +  FILE_GUID                      = ECA883EF-0CBE-40b6-84BC-FA4A709782F7
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = PlatformCmosLib
> +
> +[Sources]
> +  PlatformCmosLib.c
> +
> +[LibraryClasses]
> +  IoLib
> +
> +[Packages]
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.c
> new file mode 100644
> index 0000000000..b99c3b0122
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.c
> @@ -0,0 +1,44 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +**/
> +#include "PiPei.h"
> +#include <Library/HobLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Guid/MemoryConfigData.h>
> +#include <PlatformFspLib.h>
> +
> +EFI_STATUS
> +PlatformHobCreateFromFsp (
> +  IN CONST EFI_PEI_SERVICES     **PeiServices,
> +  VOID                          *HobList
> +  )
> +{
> +  VOID       *HobData;
> +  VOID       *NewHobData;
> +  UINTN      DataSize;
> +
> +  //
> +  // Other hob, todo: put this into FspWrapPlatformLib
> +  //
> +  if ((HobList = GetNextGuidHob (&gEfiMemoryConfigDataGuid, HobList)) !=
> NULL) {
> +    HobData = GET_GUID_HOB_DATA (HobList);
> +    DataSize = GET_GUID_HOB_DATA_SIZE(HobList);
> +    DEBUG((EFI_D_ERROR, "gEfiMemoryConfigDataGuid Hob found:
> 0x%x.\n", DataSize));
> +
> +    NewHobData = BuildGuidHob (&gEfiMemoryConfigDataGuid, DataSize);
> +    (*PeiServices)->CopyMem (
> +                      NewHobData,
> +                      HobData,
> +                      DataSize
> +                      );
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.i
> nf
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.i
> nf
> new file mode 100644
> index 0000000000..ddd97c5ad9
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.i
> nf
> @@ -0,0 +1,49 @@
> +#
> +#
> +# Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +#
> +#
> +#
> +#    FSP Platform HOB Library
> +#
> +#
> +#
> +##
> +
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = PlatformFspLib
> +  FILE_GUID                      = 1305A712-33A6-4fa7-BA59-AEAC3362931A
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = PlatformFspLib
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +
> +[Sources]
> +  PlatformFspLib.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  IntelFrameworkPkg/IntelFrameworkPkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +  IntelFspWrapperPkg/IntelFspWrapperPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +  HobLib
> +
> +[Guids]
> +  gEfiMemoryConfigDataGuid
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLi
> b.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLi
> b.c
> new file mode 100644
> index 0000000000..fac998fefa
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLi
> b.c
> @@ -0,0 +1,235 @@
> +/** @file
> +
> +  Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  IdeBus.h
> +
> +Abstract:
> +
> +  System reset Library Services.  This library class provides a set of
> +  methods to reset whole system with manipulate ICH.
> +
> +**/
> +
> +
> +#include <Base.h>
> +
> +
> +#include <Library/ResetSystemLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PciLib.h>
> +
> +#include "PchRegs.h"
> +#include "Rsci.h"
> +#include "Platform.h"
> +
> +#define RESET_GENERATOR_PORT R_PCH_RST_CNT
> +
> +VOID
> +EFIAPI
> +PlatformResetHook (
> +  UINT8 ResetType
> +  )
> +{
> +  //
> +  // Platform need to save OS reset request/types for next Android boot
> +  //
> +  IoWrite8 (0x72, CMOS_RESET_TYPE_BY_OS);
> +  IoWrite8 (0x73, ResetType);
> +}
> +
> +/**
> +  Calling this function causes a system-wide reset. This sets
> +  all circuitry within the system to its initial state. This type of reset
> +  is asynchronous to system operation and operates without regard to
> +  cycle boundaries.
> +
> +  System reset should not return, if it returns, it means the system does
> +  not support cold reset.
> +**/
> +VOID
> +EFIAPI
> +ResetCold (
> +  VOID
> +  )
> +{
> +  PlatformResetHook(COLD_RESET);
> +  IoWrite8 (RESET_GENERATOR_PORT, 0x2);
> +  IoWrite8 (RESET_GENERATOR_PORT, 0x6);
> +}
> +
> +/**
> +  Calling this function causes a system-wide initialization. The processors
> +  are set to their initial state, and pending cycles are not corrupted.
> +
> +  System reset should not return, if it returns, it means the system does
> +  not support warm reset.
> +**/
> +VOID
> +EFIAPI
> +ResetWarm (
> +  VOID
> +  )
> +{
> +  PlatformResetHook(WARM_RESET);
> +  IoWrite8 (RESET_GENERATOR_PORT, 0x0);
> +  IoWrite8 (RESET_GENERATOR_PORT, 0x4);
> +}
> +
> +/**
> +  Calling this function causes the system to enter a power state equivalent
> +  to the ACPI G2/S5 or G3 states.
> +
> +  System shutdown should not return, if it returns, it means the system
> does
> +  not support shut down reset.
> +**/
> +VOID
> +EFIAPI
> +ResetShutdown (
> +  VOID
> +  )
> +{
> +  UINT16  PchPmioBase;
> +  UINT16  Data16;
> +  UINT32  Data32;
> +
> +  PchPmioBase = (UINT16) (PciRead16 (PCI_LIB_ADDRESS(0,
> PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_ACPI_BASE)) & ~BIT0);
> +
> +  //
> +  // Then, GPE0_EN should be disabled to avoid any GPI waking up the
> system from S5
> +  //
> +  Data16 = 0;
> +  IoWrite16 (
> +    (UINTN)(PchPmioBase + R_PCH_ACPI_GPE0a_EN),
> +    (UINT16)Data16
> +    );
> +
> +  //
> +  // Clear Sleep SMI Status
> +  //
> +  IoWrite16 (PchPmioBase + R_PCH_SMI_STS,
> +             (UINT16)(IoRead16 (PchPmioBase + R_PCH_SMI_STS) |
> B_PCH_SMI_STS_ON_SLP_EN));
> +  //
> +  // Clear Sleep Type Enable
> +  //
> +  IoWrite16 (PchPmioBase + R_PCH_SMI_EN,
> +             (UINT16)(IoRead16 (PchPmioBase + R_PCH_SMI_EN) &
> (~B_PCH_SMI_EN_ON_SLP_EN)));
> +  //
> +  // Clear Power Button Status
> +  //
> +  IoWrite16(PchPmioBase + R_PCH_ACPI_PM1_STS,
> B_PCH_ACPI_PM1_STS_PWRBTN);
> +
> +  //
> +  // Secondly, Power Button Status bit must be cleared
> +  //
> +  // Write a "1" to bit[8] of power button status register at
> +  // (ABASE + PM1_STS) to clear this bit
> +  // Clear it through SMI Status register
> +  //
> +  Data16 = B_PCH_SMI_STS_PM1_STS_REG;
> +  IoWrite16 ((UINTN) (PchPmioBase + R_PCH_SMI_STS), Data16);
> +
> +  //
> +  // Finally, transform system into S5 sleep state
> +  //
> +  Data32  = IoRead32 ((UINTN) (PchPmioBase + R_PCH_ACPI_PM1_CNT));
> +
> +  Data32  = (UINT32) ((Data32 &~(B_PCH_ACPI_PM1_CNT_SLP_TYP +
> B_PCH_ACPI_PM1_CNT_SLP_EN)) | V_PCH_ACPI_PM1_CNT_S5);
> +
> +  IoWrite32 ((UINTN) (PchPmioBase + R_PCH_ACPI_PM1_CNT), Data32);
> +
> +  Data32 = Data32 | B_PCH_ACPI_PM1_CNT_SLP_EN;
> +
> +  IoWrite32 ((UINTN) (PchPmioBase + R_PCH_ACPI_PM1_CNT), Data32);
> +
> +  return;
> +}
> +
> +/**
> +  Calling this function causes the system to enter a power state for capsule
> +  update.
> +
> +  Reset update should not return, if it returns, it means the system does
> +  not support capsule update.
> +
> +**/
> +VOID
> +EFIAPI
> +EnterS3WithImmediateWake (
> +  VOID
> +  )
> +{
> +  ASSERT (FALSE);
> +}
> +
> +/**
> +  This function causes a systemwide reset. The exact type of the reset is
> +  defined by the EFI_GUID that follows the Null-terminated Unicode string
> passed
> +  into ResetData. If the platform does not recognize the EFI_GUID in
> ResetData
> +  the platform must pick a supported reset type to perform.The platform
> may
> +  optionally log the parameters from any non-normal reset that occurs.
> +
> +  @param[in]  DataSize   The size, in bytes, of ResetData.
> +  @param[in]  ResetData  The data buffer starts with a Null-terminated
> string,
> +                         followed by the EFI_GUID.
> +**/
> +VOID
> +EFIAPI
> +ResetPlatformSpecific (
> +  IN UINTN   DataSize,
> +  IN VOID    *ResetData
> +  )
> +{
> +  ResetCold ();
> +}
> +
> +/**
> +  The ResetSystem function resets the entire platform.
> +
> +  @param[in] ResetType      The type of reset to perform.
> +  @param[in] ResetStatus    The status code for the reset.
> +  @param[in] DataSize       The size, in bytes, of ResetData.
> +  @param[in] ResetData      For a ResetType of EfiResetCold, EfiResetWarm,
> or EfiResetShutdown
> +                            the data buffer starts with a Null-terminated string, optionally
> +                            followed by additional binary data. The string is a description
> +                            that the caller may use to further indicate the reason for the
> +                            system reset.
> +**/
> +VOID
> +EFIAPI
> +ResetSystem (
> +  IN EFI_RESET_TYPE               ResetType,
> +  IN EFI_STATUS                   ResetStatus,
> +  IN UINTN                        DataSize,
> +  IN VOID                         *ResetData OPTIONAL
> +  )
> +{
> +  switch (ResetType) {
> +  case EfiResetWarm:
> +    ResetWarm ();
> +    break;
> +
> +  case EfiResetCold:
> +    ResetCold ();
> +    break;
> +
> +  case EfiResetShutdown:
> +    ResetShutdown ();
> +    return;
> +
> +  case EfiResetPlatformSpecific:
> +    ResetPlatformSpecific (DataSize, ResetData);
> +    return;
> +
> +  default:
> +    return;
> +  }
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLi
> b.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLi
> b.inf
> new file mode 100644
> index 0000000000..db1a92b34e
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLi
> b.inf
> @@ -0,0 +1,47 @@
> +#/** @file
> +# Component description file for Intel Ich7 Reset System Library.
> +#
> +# Reset System Library that layers on top of the I/O Library to directly
> +#  access a standard SMBUS host controller.
> +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +#
> +#
> +#
> +#**/
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = ResetSystemLib
> +  FILE_GUID                      = D4FF05AA-3C7D-4b8a-A1EE-AA5EFA0B1732
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = ResetSystemLib
> +  EDK_RELEASE_VERSION            = 0x00020000
> +  EFI_SPECIFICATION_VERSION      = 0x00020000
> +
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +[Sources.common]
> +  ResetSystemLib.c
> +
> +
> +[Packages]
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +
> +[LibraryClasses]
> +  IoLib
> +  BaseLib
> +  DebugLib
> +  PciLib
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/PlatformSerialPort
> Lib.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/PlatformSerialPort
> Lib.h
> new file mode 100644
> index 0000000000..fe47e8f68d
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/PlatformSerialPort
> Lib.h
> @@ -0,0 +1,53 @@
> +/** @file
> +  Header file of Serial port hardware definition.
> +
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef __PLATFORM_SERIAL_PORT_LIB_H_
> +#define __PLATFORM_SERIAL_PORT_LIB_H_
> +
> +#include <Base.h>
> +#include <Library/BaseLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/SerialPortLib.h>
> +
> +//
> +// UART Register Offsets
> +//
> +#define BAUD_LOW_OFFSET   0x00
> +#define BAUD_HIGH_OFFSET  0x01
> +#define IER_OFFSET        0x01
> +#define LCR_SHADOW_OFFSET 0x01
> +#define FCR_SHADOW_OFFSET 0x02
> +#define IR_CONTROL_OFFSET 0x02
> +#define FCR_OFFSET        0x02
> +#define EIR_OFFSET        0x02
> +#define BSR_OFFSET        0x03
> +#define LCR_OFFSET        0x03
> +#define MCR_OFFSET        0x04
> +#define LSR_OFFSET        0x05
> +#define MSR_OFFSET        0x06
> +
> +//
> +// UART Register Bit Defines
> +//
> +#define LSR_TXRDY 0x20
> +#define LSR_RXDA  0x01
> +#define DLAB      0x01
> +
> +#define UART_DATA    8
> +#define UART_STOP    1
> +#define UART_PARITY  0
> +#define UART_BREAK_SET  0
> +
> +VOID
> +InitializeSio (
> +  VOID
> +  );
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.c
> new file mode 100644
> index 0000000000..f6012593d0
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.c
> @@ -0,0 +1,246 @@
> +/** @file
> +  Serial I/O Port library functions with no library constructor/destructor
> +
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "PlatformSerialPortLib.h"
> +
> +UINT16 gComBase  = 0x3f8;
> +UINTN  gBps      = 115200;
> +UINT8  gData     = 8;
> +UINT8  gStop     = 1;
> +UINT8  gParity   = 0;
> +UINT8  gBreakSet = 0;
> +
> +/**
> +  Initialize Serial Port
> +
> +  The Baud Rate Divisor registers are programmed and the LCR
> +  is used to configure the communications format. Hard coded
> +  UART config comes from globals in DebugSerialPlatform lib.
> +
> +  @param None
> +
> +  @retval None
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +UARTInitialize (
> +  VOID
> +  )
> +{
> +  UINTN Divisor;
> +  UINT8 OutputData;
> +  UINT8 Data;
> +
> +  //
> +  // Map 5..8 to 0..3
> +  //
> +  Data = (UINT8) (gData - (UINT8) 5);
> +
> +  //
> +  // Calculate divisor for baud generator
> +  //
> +  Divisor = 115200 / gBps;
> +
> +  //
> +  // Set communications format
> +  //
> +  OutputData = (UINT8) ((DLAB << 7) | ((gBreakSet << 6) | ((gParity << 3) |
> ((gStop << 2) | Data))));
> +  IoWrite8 (gComBase + LCR_OFFSET, OutputData);
> +
> +  //
> +  // Configure baud rate
> +  //
> +  IoWrite8 (gComBase + BAUD_HIGH_OFFSET, (UINT8) (Divisor >> 8));
> +  IoWrite8 (gComBase + BAUD_LOW_OFFSET, (UINT8) (Divisor & 0xff));
> +
> +  //
> +  // Switch back to bank 0
> +  //
> +  OutputData = (UINT8) ((~DLAB << 7) | ((gBreakSet << 6) | ((gParity << 3) |
> ((gStop << 2) | Data))));
> +  IoWrite8 (gComBase + LCR_OFFSET, OutputData);
> +
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Common function to initialize UART Serial device and USB Serial device.
> +
> +  @param None
> +
> +  @retval None
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerialPortInitialize (
> +  VOID
> +  )
> +{
> +
> +  UARTInitialize ();
> +
> +
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Write data to serial device.
> +
> +  If the buffer is NULL, then return 0;
> +  if NumberOfBytes is zero, then return 0.
> +
> +  @param  Buffer           Point of data buffer which need to be writed.
> +  @param  NumberOfBytes    Number of output bytes which are cached in
> Buffer.
> +
> +  @retval 0                Write data failed.
> +  @retval !0               Actual number of bytes writed to serial device.
> +
> +**/
> +UINTN
> +EFIAPI
> +UARTDbgOut (
> +  IN UINT8     *Buffer,
> +  IN UINTN     NumberOfBytes
> +)
> +{
> +  UINTN Result;
> +  UINT8 Data;
> +
> +  if (NULL == Buffer) {
> +    return 0;
> +  }
> +
> +  Result = NumberOfBytes;
> +
> +  while (NumberOfBytes--) {
> +    //
> +    // Wait for the serial port to be ready.
> +    //
> +    do {
> +      Data = IoRead8 ((UINT16) PcdGet64 (PcdSerialRegisterBase) +
> LSR_OFFSET);
> +    } while ((Data & LSR_TXRDY) == 0);
> +    IoWrite8 ((UINT16) PcdGet64 (PcdSerialRegisterBase), *Buffer++);
> +  }
> +
> +  return Result;
> +}
> +
> +/**
> +  Common function to write data to UART Serial device and USB Serial device.
> +
> +  @param  Buffer           Point of data buffer which need to be writed.
> +  @param  NumberOfBytes    Number of output bytes which are cached in
> Buffer.
> +
> +**/
> +UINTN
> +EFIAPI
> +SerialPortWrite (
> +  IN UINT8     *Buffer,
> +  IN UINTN     NumberOfBytes
> +)
> +{
> +  if (FeaturePcdGet (PcdStatusCodeUseIsaSerial)) {
> +    UARTDbgOut (Buffer, NumberOfBytes);
> +  }
> +
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Read data from serial device and save the datas in buffer.
> +
> +  If the buffer is NULL, then return 0;
> +  if NumberOfBytes is zero, then return 0.
> +
> +  @param  Buffer           Point of data buffer which need to be writed.
> +  @param  NumberOfBytes    Number of output bytes which are cached in
> Buffer.
> +
> +  @retval 0                Read data failed.
> +  @retval !0               Actual number of bytes raed to serial device.
> +
> +**/
> +UINTN
> +EFIAPI
> +UARTDbgIn (
> +  OUT UINT8     *Buffer,
> +  IN  UINTN     NumberOfBytes
> +)
> +{
> +  UINTN Result;
> +  UINT8 Data;
> +
> +  if (NULL == Buffer) {
> +    return 0;
> +  }
> +
> +  Result = NumberOfBytes;
> +
> +  while (NumberOfBytes--) {
> +    //
> +    // Wait for the serial port to be ready.
> +    //
> +    do {
> +      Data = IoRead8 ((UINT16) PcdGet64 (PcdSerialRegisterBase) +
> LSR_OFFSET);
> +    } while ((Data & LSR_RXDA) == 0);
> +
> +    *Buffer++ = IoRead8 ((UINT16) PcdGet64 (PcdSerialRegisterBase));
> +  }
> +
> +  return Result;
> +}
> +
> +/**
> +  Common function to Read data from UART serial device, USB serial device
> and save the datas in buffer.
> +
> +  @param  Buffer           Point of data buffer which need to be writed.
> +  @param  NumberOfBytes    Number of output bytes which are cached in
> Buffer.
> +
> +**/
> +UINTN
> +EFIAPI
> +SerialPortRead (
> +  OUT UINT8     *Buffer,
> +  IN  UINTN     NumberOfBytes
> +)
> +{
> +  if (FeaturePcdGet (PcdStatusCodeUseIsaSerial)) {
> +    UARTDbgIn (Buffer, NumberOfBytes);
> +  }
> +
> +  return RETURN_SUCCESS;
> +}
> +
> +
> +/**
> +  Polls a serial device to see if there is any data waiting to be read.
> +
> +  Polls aserial device to see if there is any data waiting to be read.
> +  If there is data waiting to be read from the serial device, then TRUE is
> returned.
> +  If there is no data waiting to be read from the serial device, then FALSE is
> returned.
> +
> +  @retval TRUE             Data is waiting to be read from the serial device.
> +  @retval FALSE            There is no data waiting to be read from the serial
> device.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +SerialPortPoll (
> +  VOID
> +  )
> +{
> +  UINT8  Data;
> +
> +  //
> +  // Read the serial port status.
> +  //
> +  Data = IoRead8 ((UINT16) PcdGet64 (PcdSerialRegisterBase) +
> LSR_OFFSET);
> +
> +  return (BOOLEAN) ((Data & LSR_RXDA) != 0);
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.inf
> new file mode 100644
> index 0000000000..0e7a6d3cfc
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.inf
> @@ -0,0 +1,52 @@
> +#/** @file
> +#
> +# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +#
> +#
> +#
> +#**/
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = SerialPortLib
> +  FILE_GUID                      = 15B26F43-A389-4bae-BDE3-4BB0719B7D4F
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = SerialPortLib
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +[Sources]
> +  SerialPortLib.c
> +  SioInit.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  IntelFrameworkPkg/IntelFrameworkPkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  PcdLib
> +  IoLib
> +  PciLib
> +  TimerLib
> +
> +[FixedPcd.common]
> +  gEfiSerialPortTokenSpaceGuid.PcdSerialBoudRate
> +  gEfiSerialPortTokenSpaceGuid.PcdSerialRegisterBase
> +
> +[FeaturePcd]
> +  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseIsaSerial
> +  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseUsbSerial
> +  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseRam
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.c
> new file mode 100644
> index 0000000000..d9d48539dc
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.c
> @@ -0,0 +1,127 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +    SioInit.c
> +
> +Abstract:
> +
> +    Functions for LpcSio initialization
> +
> +--*/
> +
> +#include "PlatformSerialPortLib.h"
> +#include "SioInit.h"
> +
> +typedef struct {
> +  UINT8 Register;
> +  UINT8 Value;
> +} EFI_SIO_TABLE;
> +
> +EFI_SIO_TABLE mSioTableWpcn381u[] = {
> +    {0x29, 0x0A0},
> +    {WPCN381U_LD_SEL_REGISTER, WPCN381U_LDN_UART0},
> // Select UART0 device
> +    {WPCN381U_BASE1_HI_REGISTER,
> (UINT8)(WPCN381U_SERIAL_PORT0_BASE_ADDRESS >> 8)},       // Set Base
> Address MSB
> +    {WPCN381U_BASE1_LO_REGISTER,
> (UINT8)(WPCN381U_SERIAL_PORT0_BASE_ADDRESS & 0x00FF)},   // Set
> Base Address LSB
> +    {WPCN381U_IRQ1_REGISTER, 0x014},                                                      // Set to
> IRQ4
> +    {WPCN381U_ACTIVATE_REGISTER, WPCN381U_ACTIVATE_VALUE},
> // Enable it with Activation bit
> +    {WPCN381U_LD_SEL_REGISTER, WPCN381U_LDN_UART1},
> // Select UART1 device
> +    {WPCN381U_BASE1_HI_REGISTER,
> (UINT8)(WPCN381U_SERIAL_PORT1_BASE_ADDRESS >> 8)},       // Set Base
> Address MSB
> +    {WPCN381U_BASE1_LO_REGISTER,
> (UINT8)(WPCN381U_SERIAL_PORT1_BASE_ADDRESS & 0x00FF)},   // Set
> Base Address LSB
> +    {WPCN381U_IRQ1_REGISTER, 0x013},                                                      // Set to
> IRQ3
> +    {WPCN381U_ACTIVATE_REGISTER, WPCN381U_ACTIVATE_VALUE},
> // Enable it with Activation bit
> +    {WPCN381U_LD_SEL_REGISTER, WPCN381U_LDN_GPIO},
> // Select GPIO device
> +    {WPCN381U_BASE1_HI_REGISTER,
> (UINT8)(WPCN381U_GPIO_BASE_ADDRESS >> 8)},               // Set Base
> Address MSB
> +    {WPCN381U_BASE1_LO_REGISTER,
> (UINT8)(WPCN381U_GPIO_BASE_ADDRESS & 0x00FF)},           // Set Base
> Address LSB
> +    {WPCN381U_ACTIVATE_REGISTER, WPCN381U_ACTIVATE_VALUE},
> // Enable it with Activation bit
> +    {0x21, 0x001},                                                                        // Global Device Enable
> +    {0x26, 0x000}
> +};
> +
> +EFI_SIO_TABLE mSioTableWdcp376[] = {
> +    {0x29, 0x0A0},
> +    {WPCN381U_LD_SEL_REGISTER, WPCN381U_LDN_UART0},
> // Select UART0 device
> +    {WPCN381U_BASE1_HI_REGISTER,
> (UINT8)(WPCN381U_SERIAL_PORT0_BASE_ADDRESS >> 8)},       // Set Base
> Address MSB
> +    {WPCN381U_BASE1_LO_REGISTER,
> (UINT8)(WPCN381U_SERIAL_PORT0_BASE_ADDRESS & 0x00FF)},   // Set
> Base Address LSB
> +    {WPCN381U_IRQ1_REGISTER, 0x014},                                                      // Set to
> IRQ4
> +    {WPCN381U_ACTIVATE_REGISTER, WPCN381U_ACTIVATE_VALUE},
> // Enable it with Activation bit
> +    {WPCN381U_LD_SEL_REGISTER, WPCN381U_LDN_UART1},
> // Select UART1 device
> +    {WPCN381U_BASE1_HI_REGISTER,
> (UINT8)(WPCN381U_SERIAL_PORT1_BASE_ADDRESS >> 8)},       // Set Base
> Address MSB
> +    {WPCN381U_BASE1_LO_REGISTER,
> (UINT8)(WPCN381U_SERIAL_PORT1_BASE_ADDRESS & 0x00FF)},   // Set
> Base Address LSB
> +    {WPCN381U_IRQ1_REGISTER, 0x013},                                                      // Set to
> IRQ3
> +    {WPCN381U_ACTIVATE_REGISTER, WPCN381U_ACTIVATE_VALUE},
> // Enable it with Activation bit
> +    {WPCN381U_LD_SEL_REGISTER, WPCN381U_LDN_GPIO},
> // Select GPIO device
> +    {WPCN381U_BASE1_HI_REGISTER,
> (UINT8)(WPCN381U_GPIO_BASE_ADDRESS >> 8)},               // Set Base
> Address MSB
> +    {WPCN381U_BASE1_LO_REGISTER,
> (UINT8)(WPCN381U_GPIO_BASE_ADDRESS & 0x00FF)},           // Set Base
> Address LSB
> +    {WPCN381U_ACTIVATE_REGISTER, WPCN381U_ACTIVATE_VALUE},
> // Enable it with Activation bit
> +    {0x21, 0x001},                                                                        // Global Device Enable
> +    {0x26, 0x000},
> +    {WPCN381U_LD_SEL_REGISTER, WPCN381U_LDN_PS2K},
> // Select PS2 Keyboard
> +    {WPCN381U_BASE1_HI_REGISTER,
> (UINT8)(WPCN381U_KB_BASE1_ADDRESS >> 8)},                // Set Base Address
> MSB
> +    {WPCN381U_BASE1_LO_REGISTER,
> (UINT8)(WPCN381U_KB_BASE1_ADDRESS & 0x00FF)},            // Set Base
> Address LSB
> +    {WPCN381U_BASE2_HI_REGISTER,
> (UINT8)(WPCN381U_KB_BASE2_ADDRESS >> 8)},                // Set Base Address
> MSB
> +    {WPCN381U_BASE2_LO_REGISTER,
> (UINT8)(WPCN381U_KB_BASE2_ADDRESS & 0x00FF)},            // Set Base
> Address LSB
> +    {WPCN381U_IRQ1_REGISTER, 0x011},                                                      // Set to
> IRQ1
> +    {0xF0, (SIO_KBC_CLOCK << 6)},                                                         // Select KBC
> Clock Source
> +    {WPCN381U_ACTIVATE_REGISTER, WPCN381U_ACTIVATE_VALUE},
> // Enable it with Activation bit
> +    {WPCN381U_LD_SEL_REGISTER, WPCN381U_LDN_PS2M},
> // Select PS2 Mouse
> +    {WPCN381U_IRQ1_REGISTER, 0x01c},                                                      // Set to
> IRQ12
> +    {WPCN381U_ACTIVATE_REGISTER, WPCN381U_ACTIVATE_VALUE}
> // Enable it with Activation bit
> +};
> +
> +/**
> +  Initialization for SIO.
> +
> +  @param FfsHeader     FV this PEIM was loaded from.
> +  @param PeiServices   General purpose services available to every PEIM.
> +
> +  None
> +
> +**/
> +VOID
> +InitializeSio (
> +  VOID
> +  )
> +{
> +  UINT16          Index;
> +  UINT16          IndexPort;
> +  UINT16          DataPort;
> +
> +  //
> +  // Super I/O initialization for Winbond WPCN381U
> +  //
> +  IndexPort  = WPCN381U_CONFIG_INDEX;
> +  DataPort   = WPCN381U_CONFIG_DATA;
> +
> +  //
> +  // Check for Winbond WPCN381U
> +  //
> +  IoWrite8 (IndexPort, WPCN381U_DEV_ID_REGISTER);   // Winbond
> WPCN381U Device ID register is 0x20
> +
> +  if (IoRead8 (DataPort) == WPCN381U_CHIP_ID) {   // Winbond WPCN381U
> Device ID is 0xF4
> +    //
> +    // Configure WPCN381U SIO
> +    //
> +    for (Index = 0; Index < sizeof (mSioTableWpcn381u) / sizeof
> (EFI_SIO_TABLE); Index++) {
> +      IoWrite8 (IndexPort, mSioTableWpcn381u[Index].Register);
> +      IoWrite8 (DataPort, mSioTableWpcn381u[Index].Value);
> +    }
> +  }
> +
> +  if (IoRead8 (DataPort) == WDCP376_CHIP_ID) {   // Winbond WDCP376
> Device ID is 0xF1
> +    //
> +    // Configure WDCP376 SIO
> +    //
> +    for (Index = 0; Index < sizeof (mSioTableWdcp376) / sizeof
> (EFI_SIO_TABLE); Index++) {
> +      IoWrite8 (IndexPort, mSioTableWdcp376[Index].Register);
> +      IoWrite8 (DataPort, mSioTableWdcp376[Index].Value);
> +    }
> +  }
> +  return;
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.h
> new file mode 100644
> index 0000000000..06fa19b93d
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.h
> @@ -0,0 +1,62 @@
> +/** @file
> +  Header file of Serial port hardware definition.
> +
> +  Copyright (c) 2012  - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _SIO_INIT_H_
> +#define _SIO_INIT_H_
> +
> +#define WPCN381U_CONFIG_INDEX               0x2E
> +#define WPCN381U_CONFIG_DATA                0x2F
> +#define WPCN381U_CONFIG_INDEX1              0x164E
> +#define WPCN381U_CONFIG_DATA1               0x164F
> +#define WPCN381U_CHIP_ID                    0xF4
> +#define WDCP376_CHIP_ID                     0xF1
> +
> +//
> +// SIO Logical Devices Numbers
> +//
> +#define WPCN381U_LDN_UART0                  0x03   // LDN for Serial Port
> Controller
> +#define WPCN381U_LDN_UART1                  0x02   // LDN for Parallel Port
> Controller
> +#define WPCN381U_LDN_PS2K                   0x06   // LDN for PS2 Keyboard
> Controller
> +#define WPCN381U_LDN_PS2M                   0x05   // LDN for PS2 Mouse
> Controller
> +#define WPCN381U_KB_BASE1_ADDRESS           0x60   // Base Address of KB
> controller
> +#define WPCN381U_KB_BASE2_ADDRESS           0x64   // Base Address of KB
> controller
> +#define SIO_KBC_CLOCK                       0x01   // 0/1/2 - 8/12/16 MHz KBC Clock
> Source
> +#define WPCN381U_LDN_GPIO                   0x07   // LDN for GPIO
> +
> +//
> +// SIO Registers Layout
> +//
> +#define WPCN381U_LD_SEL_REGISTER            0x07   // Logical Device Select
> Register Address
> +#define WPCN381U_DEV_ID_REGISTER            0x20   // Device Identification
> Register Address
> +#define WPCN381U_ACTIVATE_REGISTER          0x30   // Device Identification
> Register Address
> +#define WPCN381U_BASE1_HI_REGISTER          0x60   // Device BaseAddres
> Register #1 MSB Address
> +#define WPCN381U_BASE1_LO_REGISTER          0x61   // Device BaseAddres
> Register #1 LSB Address
> +#define WPCN381U_BASE2_HI_REGISTER          0x62   // Device BaseAddres
> Register #1 MSB Address
> +#define WPCN381U_BASE2_LO_REGISTER          0x63   // Device Ba1eAddres
> Register #1 LSB Address
> +#define WPCN381U_IRQ1_REGISTER              0x70   // Device IRQ Register #1
> Address
> +#define WPCN381U_IRQ2_REGISTER              0x71   // Device IRQ Register #2
> Address
> +
> +//
> +// SIO Activation Values
> +//
> +#define WPCN381U_ACTIVATE_VALUE             0x01   // Value to activate
> Device
> +#define WPCN381U_DEACTIVATE_VALUE           0x00   // Value to deactivate
> Device
> +
> +//
> +// SIO GPIO
> +//
> +#define WPCN381U_GPIO_BASE_ADDRESS          0x0A20 // SIO GPIO Base
> Address
> +
> +//
> +// SIO Serial Port Settings
> +//
> +#define WPCN381U_SERIAL_PORT0_BASE_ADDRESS  0x03F8 // Base
> Address of Serial Port 0 (COMA / UART0)
> +#define WPCN381U_SERIAL_PORT1_BASE_ADDRESS  0x02F8 // Base
> Address of Serial Port 1 (COMB / UART1)
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/CommonHeader.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/CommonHeader.h
> new file mode 100644
> index 0000000000..d34dd942d3
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/CommonHeader.h
> @@ -0,0 +1,26 @@
> +/**@file
> +  Common header file shared by all source files.
> +
> +  This file includes package header files, library classes.
> +
> +  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +**/
> +
> +#ifndef __COMMON_HEADER_H_
> +#define __COMMON_HEADER_H_
> +
> +
> +#include <Base.h>
> +#include <PchAccess.h>
> +
> +#include <Library/SmbusLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PcdLib.h>
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.c
> new file mode 100644
> index 0000000000..4052724812
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.c
> @@ -0,0 +1,873 @@
> +/** @file
> +  Intel ICH9 SMBUS library implementation built upon I/O library.
> +
> +  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +**/
> +
> +#include "CommonHeader.h"
> +
> +/**
> +  Gets Io port base address of Smbus Host Controller.
> +
> +  This internal function depends on a feature flag named
> PcdIchSmbusFixedIoPortBaseAddress
> +  to retrieve Smbus Io port base. If that feature flag is true, it will get Smbus
> Io port base
> +  address from a preset Pcd entry named PcdIchSmbusIoPortBaseAddress;
> otherwise, it will always
> +  read Pci configuration space to get that value in each Smbus bus
> transaction.
> +
> +  @return The Io port base address of Smbus host controller.
> +
> +**/
> +UINTN
> +InternalGetSmbusIoPortBaseAddress (
> +  VOID
> +  )
> +{
> +  UINTN     IoPortBaseAddress;
> +
> +  IoPortBaseAddress = (UINTN) MmioRead32 (MmPciAddress (0,
> DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SMBUS,
> PCI_FUNCTION_NUMBER_PCH_SMBUS, R_PCH_SMBUS_BASE)) &
> B_PCH_SMBUS_BASE_BAR;
> +
> +  //
> +  // Make sure that the IO port base address has been properly set.
> +  //
> +  ASSERT (IoPortBaseAddress != 0);
> +
> +  return IoPortBaseAddress;
> +}
> +
> +/**
> +  Acquires the ownership of SMBUS.
> +
> +  This internal function reads the host state register.
> +  If the SMBUS is not available, RETURN_TIMEOUT is returned;
> +  Otherwise, it performs some basic initializations and returns
> +  RETURN_SUCCESS.
> +
> +  @param  IoPortBaseAddress The Io port base address of Smbus Host
> controller.
> +
> +  @retval RETURN_SUCCESS    The SMBUS command was executed
> successfully.
> +  @retval RETURN_TIMEOUT    A timeout occurred while executing the
> SMBUS command.
> +
> +**/
> +RETURN_STATUS
> +InternalSmBusAcquire (
> +  UINTN                     IoPortBaseAddress
> +  )
> +{
> +  UINT8   HostStatus;
> +
> +  HostStatus = IoRead8 (IoPortBaseAddress + R_PCH_SMBUS_HSTS);
> +  if ((HostStatus & B_PCH_SMBUS_IUS) != 0) {
> +    return RETURN_TIMEOUT;
> +  } else if ((HostStatus & B_PCH_SMBUS_HBSY) != 0) {
> +    //
> +    // Clear host status register and exit.
> +    //
> +    IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HSTS,
> B_PCH_SMBUS_HSTS_ALL);
> +    return RETURN_TIMEOUT;
> +  }
> +  //
> +  // Clear out any odd status information (Will Not Clear In Use).
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HSTS, HostStatus);
> +
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Starts the SMBUS transaction and waits until the end.
> +
> +  This internal function start the SMBUS transaction and waits until the
> transaction
> +  of SMBUS is over by polling the INTR bit of Host status register.
> +  If the SMBUS is not available, RETURN_TIMEOUT is returned;
> +  Otherwise, it performs some basic initializations and returns
> +  RETURN_SUCCESS.
> +
> +  @param  IoPortBaseAddress   The Io port base address of Smbus Host
> controller.
> +  @param  HostControl         The Host control command to start SMBUS
> transaction.
> +
> +  @retval RETURN_SUCCESS      The SMBUS command was executed
> successfully.
> +  @retval RETURN_CRC_ERROR    The checksum is not correct (PEC is
> incorrect).
> +  @retval RETURN_DEVICE_ERROR The request was not completed because
> a failure reflected
> +                              in the Host Status Register bit.  Device errors are
> +                              a result of a transaction collision, illegal command field,
> +                              unclaimed cycle (host initiated), or bus errors (collisions).
> +
> +**/
> +RETURN_STATUS
> +InternalSmBusStart (
> +  IN  UINTN                   IoPortBaseAddress,
> +  IN  UINT8                   HostControl
> +  )
> +{
> +  UINT8   HostStatus;
> +  UINT8   AuxiliaryStatus;
> +
> +  //
> +  // Set Host Control Register (Initiate Operation, Interrupt disabled).
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HCTL,
> (UINT8)(HostControl + B_PCH_SMBUS_START));
> +
> +  do {
> +    //
> +    // Poll INTR bit of Host Status Register.
> +    //
> +    HostStatus = IoRead8 (IoPortBaseAddress + R_PCH_SMBUS_HSTS);
> +  } while ((HostStatus & (B_PCH_SMBUS_INTR | B_PCH_SMBUS_ERRORS |
> B_PCH_SMBUS_BYTE_DONE_STS)) == 0);
> +
> +  if ((HostStatus & B_PCH_SMBUS_ERRORS) == 0) {
> +    return RETURN_SUCCESS;
> +  }
> +
> +  //
> +  // Clear error bits of Host Status Register.
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HSTS,
> B_PCH_SMBUS_ERRORS);
> +
> +  //
> +  // Read Auxiliary Status Register to judge CRC error.
> +  //
> +  AuxiliaryStatus = IoRead8 (IoPortBaseAddress + R_PCH_SMBUS_AUXS);
> +  if ((AuxiliaryStatus & B_PCH_SMBUS_CRCE) != 0) {
> +    return RETURN_CRC_ERROR;
> +  }
> +
> +  return RETURN_DEVICE_ERROR;
> +}
> +
> +/**
> +  Executes an SMBUS quick, byte or word command.
> +
> +  This internal function executes an SMBUS quick, byte or word commond.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +
> +  @param  HostControl     The value of Host Control Register to set.
> +  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
> +                          SMBUS Command, SMBUS Data Length, and PEC.
> +  @param  Value           The byte/word write to the SMBUS.
> +  @param  Status          Return status for the executed command.
> +                          This is an optional parameter and may be NULL.
> +
> +  @return The byte/word read from the SMBUS.
> +
> +**/
> +UINT16
> +InternalSmBusNonBlock (
> +  IN  UINT8                     HostControl,
> +  IN  UINTN                     SmBusAddress,
> +  IN  UINT16                    Value,
> +  OUT RETURN_STATUS             *Status
> +  )
> +{
> +  RETURN_STATUS                 ReturnStatus;
> +  UINTN                         IoPortBaseAddress;
> +  UINT8                         AuxiliaryControl;
> +
> +  IoPortBaseAddress = InternalGetSmbusIoPortBaseAddress ();
> +
> +  //
> +  // Try to acquire the ownership of ICH SMBUS.
> +  //
> +  ReturnStatus = InternalSmBusAcquire (IoPortBaseAddress);
> +  if (RETURN_ERROR (ReturnStatus)) {
> +    goto Done;
> +  }
> +
> +  //
> +  // Set the appropriate Host Control Register and auxiliary Control Register.
> +  //
> +  AuxiliaryControl = 0;
> +  if (SMBUS_LIB_PEC (SmBusAddress)) {
> +    AuxiliaryControl |= B_PCH_SMBUS_AAC;
> +    HostControl      |= B_PCH_SMBUS_PEC_EN;
> +  }
> +
> +  //
> +  // Set Host Command Register.
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HCMD, (UINT8)
> SMBUS_LIB_COMMAND (SmBusAddress));
> +
> +  //
> +  // Write value to Host Data 0 and Host Data 1 Registers.
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HD0, (UINT8) Value);
> +  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HD1, (UINT8) (Value >> 8));
> +
> +  //
> +  // Set Auxiliary Control Register.
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_AUXC, AuxiliaryControl);
> +
> +  //
> +  // Set SMBUS slave address for the device to send/receive from.
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_TSA, (UINT8)
> SmBusAddress);
> +
> +  //
> +  // Start the SMBUS transaction and wait for the end.
> +  //
> +  ReturnStatus = InternalSmBusStart (IoPortBaseAddress, HostControl);
> +
> +  //
> +  // Read value from Host Data 0 and Host Data 1 Registers.
> +  //
> +  Value = (UINT16)(IoRead8 (IoPortBaseAddress + R_PCH_SMBUS_HD1) <<
> 8);
> +  Value = (UINT16)(Value | IoRead8 (IoPortBaseAddress +
> R_PCH_SMBUS_HD0));
> +
> +  //
> +  // Clear Host Status Register and Auxiliary Status Register.
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HSTS,
> B_PCH_SMBUS_HSTS_ALL);
> +  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_AUXS,
> B_PCH_SMBUS_CRCE);
> +
> +Done:
> +  if (Status != NULL) {
> +    *Status = ReturnStatus;
> +  }
> +
> +  return Value;
> +}
> +
> +/**
> +  Executes an SMBUS quick read command.
> +
> +  Executes an SMBUS quick read command on the SMBUS device specified
> by SmBusAddress.
> +  Only the SMBUS slave address field of SmBusAddress is required.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  If PEC is set in SmBusAddress, then ASSERT().
> +  If Command in SmBusAddress is not zero, then ASSERT().
> +  If Length in SmBusAddress is not zero, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
> +                          SMBUS Command, SMBUS Data Length, and PEC.
> +  @param  Status          Return status for the executed command.
> +                          This is an optional parameter and may be NULL.
> +
> +**/
> +VOID
> +EFIAPI
> +SmBusQuickRead (
> +  IN  UINTN                     SmBusAddress,
> +  OUT RETURN_STATUS             *Status       OPTIONAL
> +  )
> +{
> +  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));
> +  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress)  == 0);
> +
> +  InternalSmBusNonBlock (
> +    V_PCH_SMBUS_SMB_CMD_QUICK,
> +    SmBusAddress | B_PCH_SMBUS_RW_SEL_READ,
> +    0,
> +    Status
> +    );
> +}
> +
> +/**
> +  Executes an SMBUS quick write command.
> +
> +  Executes an SMBUS quick write command on the SMBUS device specified
> by SmBusAddress.
> +  Only the SMBUS slave address field of SmBusAddress is required.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  If PEC is set in SmBusAddress, then ASSERT().
> +  If Command in SmBusAddress is not zero, then ASSERT().
> +  If Length in SmBusAddress is not zero, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
> +                          SMBUS Command, SMBUS Data Length, and PEC.
> +  @param  Status          Return status for the executed command.
> +                          This is an optional parameter and may be NULL.
> +
> +**/
> +VOID
> +EFIAPI
> +SmBusQuickWrite (
> +  IN  UINTN                     SmBusAddress,
> +  OUT RETURN_STATUS             *Status       OPTIONAL
> +  )
> +{
> +  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));
> +  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  InternalSmBusNonBlock (
> +    V_PCH_SMBUS_SMB_CMD_QUICK,
> +    SmBusAddress | B_PCH_SMBUS_RW_SEL_WRITE,
> +    0,
> +    Status
> +    );
> +}
> +
> +/**
> +  Executes an SMBUS receive byte command.
> +
> +  Executes an SMBUS receive byte command on the SMBUS device specified
> by SmBusAddress.
> +  Only the SMBUS slave address field of SmBusAddress is required.
> +  The byte received from the SMBUS is returned.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  If Command in SmBusAddress is not zero, then ASSERT().
> +  If Length in SmBusAddress is not zero, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
> +                          SMBUS Command, SMBUS Data Length, and PEC.
> +  @param  Status          Return status for the executed command.
> +                          This is an optional parameter and may be NULL.
> +
> +  @return The byte received from the SMBUS.
> +
> +**/
> +UINT8
> +EFIAPI
> +SmBusReceiveByte (
> +  IN  UINTN          SmBusAddress,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  UINT8 ValueReturn = 0;
> +
> +  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  ValueReturn = (UINT8) InternalSmBusNonBlock (
> +                   V_PCH_SMBUS_SMB_CMD_BYTE,
> +                   SmBusAddress | B_PCH_SMBUS_RW_SEL_READ,
> +                   0,
> +                   Status
> +                   );
> +  return ValueReturn;
> +
> +  }
> +
> +/**
> +  Executes an SMBUS send byte command.
> +
> +  Executes an SMBUS send byte command on the SMBUS device specified
> by SmBusAddress.
> +  The byte specified by Value is sent.
> +  Only the SMBUS slave address field of SmBusAddress is required.  Value is
> returned.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  If Command in SmBusAddress is not zero, then ASSERT().
> +  If Length in SmBusAddress is not zero, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
> +                          SMBUS Command, SMBUS Data Length, and PEC.
> +  @param  Value           The 8-bit value to send.
> +  @param  Status          Return status for the executed command.
> +                          This is an optional parameter and may be NULL.
> +
> +  @return The parameter of Value.
> +
> +**/
> +UINT8
> +EFIAPI
> +SmBusSendByte (
> +  IN  UINTN          SmBusAddress,
> +  IN  UINT8          Value,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  UINT8 ValueReturn = 0;
> +
> +  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  ValueReturn = (UINT8) InternalSmBusNonBlock (
> +                          V_PCH_SMBUS_SMB_CMD_BYTE,
> +                          SmBusAddress | B_PCH_SMBUS_RW_SEL_WRITE,
> +                          Value,
> +                          Status
> +                          );
> +  return ValueReturn;
> +
> +  }
> +
> +/**
> +  Executes an SMBUS read data byte command.
> +
> +  Executes an SMBUS read data byte command on the SMBUS device
> specified by SmBusAddress.
> +  Only the SMBUS slave address and SMBUS command fields of
> SmBusAddress are required.
> +  The 8-bit value read from the SMBUS is returned.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  If Length in SmBusAddress is not zero, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
> +                          SMBUS Command, SMBUS Data Length, and PEC.
> +  @param  Status          Return status for the executed command.
> +                          This is an optional parameter and may be NULL.
> +
> +  @return The byte read from the SMBUS.
> +
> +**/
> +UINT8
> +EFIAPI
> +SmBusReadDataByte (
> +  IN  UINTN          SmBusAddress,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  UINT8 ValueReturn = 0;
> +
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +   ValueReturn = (UINT8) InternalSmBusNonBlock (
> +                           V_PCH_SMBUS_SMB_CMD_BYTE_DATA,
> +                           SmBusAddress | B_PCH_SMBUS_RW_SEL_READ,
> +                           0,
> +                           Status
> +                           );
> +  return ValueReturn;
> +}
> +
> +/**
> +  Executes an SMBUS write data byte command.
> +
> +  Executes an SMBUS write data byte command on the SMBUS device
> specified by SmBusAddress.
> +  The 8-bit value specified by Value is written.
> +  Only the SMBUS slave address and SMBUS command fields of
> SmBusAddress are required.
> +  Value is returned.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  If Length in SmBusAddress is not zero, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
> +                          SMBUS Command, SMBUS Data Length, and PEC.
> +  @param  Value           The 8-bit value to write.
> +  @param  Status          Return status for the executed command.
> +                          This is an optional parameter and may be NULL.
> +
> +  @return The parameter of Value.
> +
> +**/
> +UINT8
> +EFIAPI
> +SmBusWriteDataByte (
> +  IN  UINTN          SmBusAddress,
> +  IN  UINT8          Value,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  UINT8 ValueReturn = 0;
> +
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  ValueReturn = (UINT8) InternalSmBusNonBlock (
> +                          V_PCH_SMBUS_SMB_CMD_BYTE_DATA,
> +                          SmBusAddress | B_PCH_SMBUS_RW_SEL_WRITE,
> +                          Value,
> +                          Status
> +                          );
> +  return ValueReturn;
> +
> +}
> +
> +/**
> +  Executes an SMBUS read data word command.
> +
> +  Executes an SMBUS read data word command on the SMBUS device
> specified by SmBusAddress.
> +  Only the SMBUS slave address and SMBUS command fields of
> SmBusAddress are required.
> +  The 16-bit value read from the SMBUS is returned.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  If Length in SmBusAddress is not zero, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
> +                          SMBUS Command, SMBUS Data Length, and PEC.
> +  @param  Status          Return status for the executed command.
> +                          This is an optional parameter and may be NULL.
> +
> +  @return The byte read from the SMBUS.
> +
> +**/
> +UINT16
> +EFIAPI
> +SmBusReadDataWord (
> +  IN  UINTN          SmBusAddress,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  UINT16 ValueReturn = 0;
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  ValueReturn = InternalSmBusNonBlock (
> +                  V_PCH_SMBUS_SMB_CMD_WORD_DATA,
> +                  SmBusAddress | B_PCH_SMBUS_RW_SEL_READ,
> +                  0,
> +                  Status
> +                  );
> +  return ValueReturn;
> +
> +}
> +
> +/**
> +  Executes an SMBUS write data word command.
> +
> +  Executes an SMBUS write data word command on the SMBUS device
> specified by SmBusAddress.
> +  The 16-bit value specified by Value is written.
> +  Only the SMBUS slave address and SMBUS command fields of
> SmBusAddress are required.
> +  Value is returned.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  If Length in SmBusAddress is not zero, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
> +                          SMBUS Command, SMBUS Data Length, and PEC.
> +  @param  Value           The 16-bit value to write.
> +  @param  Status          Return status for the executed command.
> +                          This is an optional parameter and may be NULL.
> +
> +  @return The parameter of Value.
> +
> +**/
> +UINT16
> +EFIAPI
> +SmBusWriteDataWord (
> +  IN  UINTN          SmBusAddress,
> +  IN  UINT16         Value,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  UINT16 ValueReturn = 0;
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  ValueReturn = InternalSmBusNonBlock (
> +                  V_PCH_SMBUS_SMB_CMD_WORD_DATA,
> +                  SmBusAddress | B_PCH_SMBUS_RW_SEL_WRITE,
> +                  Value,
> +                  Status
> +                  );
> +  return ValueReturn;
> +}
> +
> +/**
> +  Executes an SMBUS process call command.
> +
> +  Executes an SMBUS process call command on the SMBUS device specified
> by SmBusAddress.
> +  The 16-bit value specified by Value is written.
> +  Only the SMBUS slave address and SMBUS command fields of
> SmBusAddress are required.
> +  The 16-bit value returned by the process call command is returned.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  If Length in SmBusAddress is not zero, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
> +                          SMBUS Command, SMBUS Data Length, and PEC.
> +  @param  Value           The 16-bit value to write.
> +  @param  Status          Return status for the executed command.
> +                          This is an optional parameter and may be NULL.
> +
> +  @return The 16-bit value returned by the process call command.
> +
> +**/
> +UINT16
> +EFIAPI
> +SmBusProcessCall (
> +  IN  UINTN          SmBusAddress,
> +  IN  UINT16         Value,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  UINT16 ValueReturn = 0;
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  ValueReturn = InternalSmBusNonBlock (
> +                  V_PCH_SMBUS_SMB_CMD_PROCESS_CALL,
> +                  SmBusAddress | B_PCH_SMBUS_RW_SEL_WRITE,
> +                  Value,
> +                  Status
> +                  );
> +  return ValueReturn;
> +}
> +
> +/**
> +  Executes an SMBUS block command.
> +
> +  Executes an SMBUS block read, block write and block write-block read
> command
> +  on the SMBUS device specified by SmBusAddress.
> +  Bytes are read from the SMBUS and stored in Buffer.
> +  The number of bytes read is returned, and will never return a value larger
> than 32-bytes.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  It is the caller's responsibility to make sure Buffer is large enough for the
> total number of bytes read.
> +  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not
> need to be any larger than 32 bytes.
> +
> +  @param  HostControl     The value of Host Control Register to set.
> +  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
> +                          SMBUS Command, SMBUS Data Length, and PEC.
> +  @param  WriteBuffer     Pointer to the buffer of bytes to write to the
> SMBUS.
> +  @param  ReadBuffer      Pointer to the buffer of bytes to read from the
> SMBUS.
> +  @param  Status          Return status for the executed command.
> +                          This is an optional parameter and may be NULL.
> +
> +  @return The number of bytes read from the SMBUS.
> +
> +**/
> +UINTN
> +InternalSmBusBlock (
> +  IN  UINT8                     HostControl,
> +  IN  UINTN                     SmBusAddress,
> +  IN  UINT8                     *WriteBuffer,
> +  OUT UINT8                     *ReadBuffer,
> +  OUT RETURN_STATUS             *Status
> +  )
> +{
> +  RETURN_STATUS                 ReturnStatus;
> +  UINTN                         Index;
> +  UINTN                         BytesCount;
> +  UINTN                         IoPortBaseAddress;
> +  UINT8                         AuxiliaryControl;
> +
> +  IoPortBaseAddress = InternalGetSmbusIoPortBaseAddress ();
> +
> +  BytesCount = SMBUS_LIB_LENGTH (SmBusAddress);
> +
> +  //
> +  // Try to acquire the ownership of ICH SMBUS.
> +  //
> +  ReturnStatus = InternalSmBusAcquire (IoPortBaseAddress);
> +  if (RETURN_ERROR (ReturnStatus)) {
> +    goto Done;
> +  }
> +
> +  //
> +  // Set the appropriate Host Control Register and auxiliary Control Register.
> +  //
> +  AuxiliaryControl = B_PCH_SMBUS_E32B;
> +  if (SMBUS_LIB_PEC (SmBusAddress)) {
> +    AuxiliaryControl |= B_PCH_SMBUS_AAC;
> +    HostControl      |= B_PCH_SMBUS_PEC_EN;
> +  }
> +
> +  //
> +  // Set Host Command Register.
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HCMD, (UINT8)
> SMBUS_LIB_COMMAND (SmBusAddress));
> +
> +  //
> +  // Set Auxiliary Control Regiester.
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_AUXC, AuxiliaryControl);
> +
> +  //
> +  // Clear byte pointer of 32-byte buffer.
> +  //
> +  IoRead8 (IoPortBaseAddress + R_PCH_SMBUS_HCTL);
> +
> +  if (WriteBuffer != NULL) {
> +    //
> +    // Write the number of block to Host Block Data Byte Register.
> +    //
> +    IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HD0, (UINT8)
> BytesCount);
> +
> +    //
> +    // Write data block to Host Block Data Register.
> +    //
> +    for (Index = 0; Index < BytesCount; Index++) {
> +      IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HBD,
> WriteBuffer[Index]);
> +    }
> +  }
> +
> +  //
> +  // Set SMBUS slave address for the device to send/receive from.
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_TSA, (UINT8)
> SmBusAddress);
> +
> +  //
> +  // Start the SMBUS transaction and wait for the end.
> +  //
> +  ReturnStatus = InternalSmBusStart (IoPortBaseAddress, HostControl);
> +  if (RETURN_ERROR (ReturnStatus)) {
> +    goto Done;
> +  }
> +
> +  if (ReadBuffer != NULL) {
> +    //
> +    // Read the number of block from host block data byte register.
> +    //
> +    BytesCount = IoRead8 (IoPortBaseAddress + R_PCH_SMBUS_HD0);
> +
> +    //
> +    // Write data block from Host Block Data Register.
> +    //
> +    for (Index = 0; Index < BytesCount; Index++) {
> +      ReadBuffer[Index] = IoRead8 (IoPortBaseAddress +
> R_PCH_SMBUS_HBD);
> +    }
> +  }
> +
> +Done:
> +  //
> +  // Clear Host Status Register and Auxiliary Status Register.
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_HSTS,
> B_PCH_SMBUS_HSTS_ALL);
> +  IoWrite8 (IoPortBaseAddress + R_PCH_SMBUS_AUXS,
> B_PCH_SMBUS_CRCE);
> +
> +  if (Status != NULL) {
> +    *Status = ReturnStatus;
> +  }
> +
> +  return BytesCount;
> +}
> +
> +/**
> +  Executes an SMBUS read block command.
> +
> +  Executes an SMBUS read block command on the SMBUS device specified
> by SmBusAddress.
> +  Only the SMBUS slave address and SMBUS command fields of
> SmBusAddress are required.
> +  Bytes are read from the SMBUS and stored in Buffer.
> +  The number of bytes read is returned, and will never return a value larger
> than 32-bytes.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  It is the caller's responsibility to make sure Buffer is large enough for the
> total number of bytes read.
> +  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not
> need to be any larger than 32 bytes.
> +  If Length in SmBusAddress is not zero, then ASSERT().
> +  If Buffer is NULL, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
> +                          SMBUS Command, SMBUS Data Length, and PEC.
> +  @param  Buffer          Pointer to the buffer to store the bytes read from the
> SMBUS.
> +  @param  Status          Return status for the executed command.
> +                          This is an optional parameter and may be NULL.
> +
> +  @return The number of bytes read.
> +
> +**/
> +UINTN
> +EFIAPI
> +SmBusReadBlock (
> +  IN  UINTN          SmBusAddress,
> +  OUT VOID           *Buffer,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  UINTN BytesCount = 0;
> +
> +  ASSERT (Buffer != NULL);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +
> +  BytesCount = InternalSmBusBlock (
> +                 V_PCH_SMBUS_SMB_CMD_BLOCK,
> +                 SmBusAddress | B_PCH_SMBUS_RW_SEL_READ,
> +                 NULL,
> +                 Buffer,
> +                 Status
> +                 );
> +  return BytesCount;
> +
> +}
> +
> +/**
> +  Executes an SMBUS write block command.
> +
> +  Executes an SMBUS write block command on the SMBUS device specified
> by SmBusAddress.
> +  The SMBUS slave address, SMBUS command, and SMBUS length fields of
> SmBusAddress are required.
> +  Bytes are written to the SMBUS from Buffer.
> +  The number of bytes written is returned, and will never return a value
> larger than 32-bytes.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  If Length in SmBusAddress is zero or greater than 32, then ASSERT().
> +  If Buffer is NULL, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
> +                          SMBUS Command, SMBUS Data Length, and PEC.
> +  @param  Buffer          Pointer to the buffer to store the bytes read from the
> SMBUS.
> +  @param  Status          Return status for the executed command.
> +                          This is an optional parameter and may be NULL.
> +
> +  @return The number of bytes written.
> +
> +**/
> +UINTN
> +EFIAPI
> +SmBusWriteBlock (
> +  IN  UINTN          SmBusAddress,
> +  OUT VOID           *Buffer,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  UINTN	BytesCount = 0;
> +
> +  ASSERT (Buffer != NULL);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +
> + BytesCount = InternalSmBusBlock (
> +
> +                V_PCH_SMBUS_SMB_CMD_BLOCK,
> +                SmBusAddress | B_PCH_SMBUS_RW_SEL_WRITE,
> +                Buffer,
> +                NULL,
> +                Status
> +                );
> +
> +  return BytesCount;
> +}
> +
> +/**
> +  Executes an SMBUS block process call command.
> +
> +  Executes an SMBUS block process call command on the SMBUS device
> specified by SmBusAddress.
> +  The SMBUS slave address, SMBUS command, and SMBUS length fields of
> SmBusAddress are required.
> +  Bytes are written to the SMBUS from WriteBuffer.  Bytes are then read
> from the SMBUS into ReadBuffer.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  It is the caller's responsibility to make sure ReadBuffer is large enough for
> the total number of bytes read.
> +  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not
> need to be any larger than 32 bytes.
> +  If Length in SmBusAddress is zero or greater than 32, then ASSERT().
> +  If WriteBuffer is NULL, then ASSERT().
> +  If ReadBuffer is NULL, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,
> +                          SMBUS Command, SMBUS Data Length, and PEC.
> +  @param  WriteBuffer     Pointer to the buffer of bytes to write to the
> SMBUS.
> +  @param  ReadBuffer      Pointer to the buffer of bytes to read from the
> SMBUS.
> +  @param  Status          Return status for the executed command.
> +                          This is an optional parameter and may be NULL.
> +
> +  @return The number of bytes written.
> +
> +**/
> +UINTN
> +EFIAPI
> +SmBusBlockProcessCall (
> +  IN  UINTN          SmBusAddress,
> +  IN  VOID           *WriteBuffer,
> +  OUT VOID           *ReadBuffer,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  UINTN BytesCount = 0;
> +
> +  ASSERT (WriteBuffer != NULL);
> +  ASSERT (ReadBuffer  != NULL);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  BytesCount = InternalSmBusBlock (
> +                 V_PCH_SMBUS_SMB_CMD_BLOCK_PROCESS,
> +                 SmBusAddress | B_PCH_SMBUS_RW_SEL_WRITE,
> +                 WriteBuffer,
> +                 ReadBuffer,
> +                 Status
> +                 );
> +  return BytesCount;
> +
> +  }
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.inf
> new file mode 100644
> index 0000000000..b13e3de0cc
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.inf
> @@ -0,0 +1,46 @@
> +## @file
> +# Component description file for Intel Ich9 Smbus Library.
> +#
> +# SMBUS Library that layers on top of the I/O Library to directly
> +#  access a standard SMBUS host controller.
> +# Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +#
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = SmbusLib
> +  FILE_GUID                      = 0558CAEA-FEF3-4b6d-915E-8742EFE6DEE1
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = SmbusLib
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +
> +[Sources]
> +  SmbusLib.c
> +
> +[Packages]
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +  MdePkg/MdePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +
> +[LibraryClasses]
> +  PcdLib
> +  DebugLib
> +  PciLib
> +  IoLib
> +
> +[Pcd.common]
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmm.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmm.c
> new file mode 100644
> index 0000000000..062994f088
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmm.c
> @@ -0,0 +1,89 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  SmmIo.c
> +
> +Abstract:
> +
> +  SMM I/O access utility implementation file, for Ia32
> +
> +--*/
> +
> +//
> +// Include files
> +//
> +#include "Library/StallSmmLib.h"
> +#include "Pi/PiSmmCis.h"
> +#include "PiDxe.h"
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include "PchAccess.h"
> +
> +/**
> +  Delay for at least the request number of microseconds.
> +  Timer used is ACPI time counter, which has 1us granularity.
> +
> +  @param Microseconds  Number of microseconds to delay.
> +
> +  @retval None
> +
> +**/
> +VOID
> +SmmStall (
> +  IN  UINTN   Microseconds
> +  )
> +{
> +  UINTN   Ticks;
> +  UINTN   Counts;
> +  UINTN   CurrentTick;
> +  UINTN   OriginalTick;
> +  UINTN   RemainingTick;
> +  UINT16  AcpiBaseAddr;
> +
> +  if (Microseconds == 0) {
> +    return;
> +  }
> +
> +  AcpiBaseAddr = PchLpcPciCfg16 (R_PCH_LPC_ACPI_BASE) &
> B_PCH_LPC_ACPI_BASE_BAR;
> +
> +  OriginalTick = IoRead32 (AcpiBaseAddr + R_PCH_ACPI_PM1_TMR);
> +  CurrentTick = OriginalTick;
> +
> +  //
> +  // The timer frequency is 3.579545 MHz, so 1 ms corresponds 3.58 clocks
> +  //
> +  Ticks = Microseconds * 358 / 100 + OriginalTick + 1;
> +
> +  //
> +  // The loops needed by timer overflow
> +  //
> +  Counts = Ticks / V_PCH_ACPI_PM1_TMR_MAX_VAL;
> +
> +  //
> +  // Remaining clocks within one loop
> +  //
> +  RemainingTick = Ticks % V_PCH_ACPI_PM1_TMR_MAX_VAL;
> +
> +  //
> +  // not intend to use TMROF_STS bit of register PM1_STS, because this
> adds extra
> +  // one I/O operation, and maybe generate SMI
> +  //
> +  while ((Counts != 0) || (RemainingTick > CurrentTick)) {
> +    CurrentTick = IoRead32 (AcpiBaseAddr + R_PCH_ACPI_PM1_TMR);
> +    //
> +    // Check if timer overflow
> +    //
> +    if (CurrentTick < OriginalTick) {
> +      Counts--;
> +    }
> +    OriginalTick = CurrentTick;
> +  }
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmmLib.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmmLib.inf
> new file mode 100644
> index 0000000000..703ea3238c
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmmLib.inf
> @@ -0,0 +1,51 @@
> +#/*++
> +#
> +# Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +
> +#
> +#  Module Name:
> +#
> +#   SmmStallLib.inf
> +#
> +#  Abstract:
> +#
> +#    Component description file for SmmStall library
> +#
> +#--*/
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = StallSmmLib
> +  FILE_GUID                      = A6A16CCB-91B0-42f4-B4F3-D16D7A8662E6
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = StallSmmLib
> +
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +
> +[Sources]
> + StallSmm.c
> +
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +
> +[LibraryClasses]
> +  PcdLib
> +  PciLib
> +  IoLib
> +  BaseLib
> +
> +[Pcd.common]
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2De
> viceLibSeC.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2De
> viceLibSeC.c
> new file mode 100644
> index 0000000000..ad3d201e07
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2De
> viceLibSeC.c
> @@ -0,0 +1,117 @@
> +/*++
> +
> +Copyright (c)  1999  - 2015, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +--*/
> +
> +#include <Uefi.h>
> +#include <Protocol/PttPassThru.h>
> +#include <Library/PcdLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +//#include <Library/Tpm2DeviceLib.h>
> +
> +
> +PTT_PASS_THRU_PROTOCOL *mPttPassThruProtocol;
> +
> +
> +/**
> +  The constructor function caches the pointer to PEI services.
> +
> +  The constructor function caches the pointer to PEI services.
> +  It will always return EFI_SUCCESS.
> +
> +  @param  FfsHeader   Pointer to FFS header the loaded driver.
> +  @param  PeiServices Pointer to the PEI services.
> +
> +  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
> +
> +**/
> +
> +EFI_STATUS
> +EFIAPI
> +Tpm2DeviceLibConstructor (
> +  VOID
> +  )
> +{
> +  EFI_STATUS Status = EFI_SUCCESS;
> +
> +  Status = gBS->LocateProtocol (&gPttPassThruProtocolGuid, NULL, (VOID
> **) &mPttPassThruProtocol);
> +
> +  return Status;
> +}
> +
> +/**
> +  This service enables the sending of commands to the TPM2.
> +
> +  @param[in]  InputParameterBlockSize  Size of the TPM2 input parameter
> block.
> +  @param[in]  InputParameterBlock      Pointer to the TPM2 input parameter
> block.
> +  @param[in]  OutputParameterBlockSize Size of the TPM2 output
> parameter block.
> +  @param[in]  OutputParameterBlock     Pointer to the TPM2 output
> parameter block.
> +
> +  @retval EFI_SUCCESS            The command byte stream was successfully
> sent to the device and a response was successfully received.
> +  @retval EFI_DEVICE_ERROR       The command was not successfully sent to
> the device or a response was not successfully received from the device.
> +  @retval EFI_BUFFER_TOO_SMALL   The output parameter block is too
> small.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Tpm2SubmitCommand (
> +  IN UINT32            InputParameterBlockSize,
> +  IN UINT8             *InputParameterBlock,
> +  IN OUT UINT32        *OutputParameterBlockSize,
> +  IN UINT8             *OutputParameterBlock
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  Status = mPttPassThruProtocol->Tpm2SubmitCommand (
> +             mPttPassThruProtocol,
> +             InputParameterBlockSize,
> +             InputParameterBlock,
> +             OutputParameterBlockSize,
> +             OutputParameterBlock
> +           );
> +
> +  return Status;
> +}
> +
> +/**
> +  This service requests use TPM2.
> +
> +  @retval EFI_SUCCESS      Get the control of TPM2 chip.
> +  @retval EFI_NOT_FOUND    TPM2 not found.
> +  @retval EFI_DEVICE_ERROR Unexpected device behavior.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Tpm2RequestUseTpm (
> +  VOID
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  Status = mPttPassThruProtocol->Tpm2RequestUseTpm
> (mPttPassThruProtocol);
> +
> +  return Status;
> +}
> +
> +/**
> +  This service register TPM2 device.
> +
> +  @Param Tpm2Device  TPM2 device
> +
> +  @retval EFI_SUCCESS          This TPM2 device is registered successfully.
> +  @retval EFI_UNSUPPORTED      System does not support register this TPM2
> device.
> +  @retval EFI_ALREADY_STARTED  System already register this TPM2 device.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Tpm2RegisterTpm2DeviceLib (
> +  IN PTT_TPM2_DEVICE_INTERFACE   *Tpm2Device
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2De
> viceLibSeC.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2De
> viceLibSeC.inf
> new file mode 100644
> index 0000000000..9ee91527c1
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2De
> viceLibSeC.inf
> @@ -0,0 +1,61 @@
> +#/** @file
> +#
> +#
> +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +#
> +#
> +#**/
> +
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = Tpm2DeviceLibSeC
> +  FILE_GUID                      = 294B196A-A3CC-4a43-857F-EEC26147857B
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = Tpm2DeviceLib | DXE_DRIVER
> DXE_SMM_DRIVER
> +  CONSTRUCTOR                    = Tpm2DeviceLibConstructor
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +
> +[Sources.common]
> +  Tpm2DeviceLibSeC.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +  SecurityPkg/SecurityPkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  PcdLib
> +  UefiBootServicesTableLib
> +
> +
> +[Guids]
> +  gEfiVLVTokenSpaceGuid
> +
> +[Pcd]
> +  gEfiVLVTokenSpaceGuid.PcdMeasuredBootEnable
> +  gEfiVLVTokenSpaceGuid.PcdFTPMErrorOccur
> +  gEfiVLVTokenSpaceGuid.PcdFTPMCommand
> +  gEfiVLVTokenSpaceGuid.PcdFTPMResponse
> +  gEfiVLVTokenSpaceGuid.PcdFTPMNotRespond
> +  gEfiVLVTokenSpaceGuid.PcdFTPMStatus
> +
> +[Protocols]
> +  gPttPassThruProtocolGuid
> +
> +[Depex]
> +  gPttPassThruProtocolGuid
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2Dev
> iceLibSeC.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2Dev
> iceLibSeC.c
> new file mode 100644
> index 0000000000..12717a5f69
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2Dev
> iceLibSeC.c
> @@ -0,0 +1,145 @@
> +/*++
> +
> +Copyright (c)  1999  - 2015, Intel Corporation. All rights reserved
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +--*/
> +
> +#include <Uefi.h>
> +#include <PiPei.h>
> +#include <Ppi/PttPassThruPpi.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PcdLib.h>
> +
> +
> +
> +
> +
> +
> +PTT_PASS_THRU_PPI  *SecPttPassThruPpi = NULL;
> +
> +/**
> +  The constructor function caches the pointer to PEI services.
> +
> +  The constructor function caches the pointer to PEI services.
> +  It will always return EFI_SUCCESS.
> +
> +  @param  FfsHeader   Pointer to FFS header the loaded driver.
> +  @param  PeiServices Pointer to the PEI services.
> +
> +  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Tpm2DeviceLibConstructor (
> +  VOID
> +  )
> +{
> +  EFI_STATUS  Status = EFI_SUCCESS;
> +
> +  Status = PeiServicesLocatePpi (&gPttPassThruPpiGuid, 0, NULL, (VOID **)
> &SecPttPassThruPpi);
> +  if (EFI_ERROR (Status)) {
> +     // Locate the PPI failed
> +     SecPttPassThruPpi = NULL;
> +  }
> +  return Status;
> +}
> +
> +/**
> +  This service enables the sending of commands to the TPM2.
> +
> +  @param[in]  InputParameterBlockSize  Size of the TPM2 input parameter
> block.
> +  @param[in]  InputParameterBlock      Pointer to the TPM2 input parameter
> block.
> +  @param[in]  OutputParameterBlockSize Size of the TPM2 output
> parameter block.
> +  @param[in]  OutputParameterBlock     Pointer to the TPM2 output
> parameter block.
> +
> +  @retval EFI_SUCCESS            The command byte stream was successfully
> sent to the device and a response was successfully received.
> +  @retval EFI_DEVICE_ERROR       The command was not successfully sent to
> the device or a response was not successfully received from the device.
> +  @retval EFI_BUFFER_TOO_SMALL   The output parameter block is too
> small.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Tpm2SubmitCommand (
> +  IN UINT32            InputParameterBlockSize,
> +  IN UINT8             *InputParameterBlock,
> +  IN OUT UINT32        *OutputParameterBlockSize,
> +  IN UINT8             *OutputParameterBlock
> +  )
> +{
> +  EFI_STATUS  Status = EFI_SUCCESS;
> +
> +  if(NULL == InputParameterBlock || NULL == OutputParameterBlock || 0
> == InputParameterBlockSize) {
> +    DEBUG ((EFI_D_ERROR, "Buffer == NULL or InputParameterBlockSize ==
> 0\n"));
> +    Status = EFI_INVALID_PARAMETER;
> +    return Status;
> +  }
> +
> +  if (NULL == SecPttPassThruPpi) {
> +    // Don't locate PPI by calling Tpm2DeviceLibConstructor() function??
> +    Status = EFI_DEVICE_ERROR;
> +    return Status;
> +  }
> +
> +  Status = SecPttPassThruPpi->Tpm2SubmitCommand (
> +             SecPttPassThruPpi,
> +             InputParameterBlockSize,
> +             InputParameterBlock,
> +             OutputParameterBlockSize,
> +             OutputParameterBlock
> +           );
> +
> +  return Status;
> +}
> +
> +/**
> +  This service requests use TPM2.
> +
> +  @retval EFI_SUCCESS      Get the control of TPM2 chip.
> +  @retval EFI_NOT_FOUND    TPM2 not found.
> +  @retval EFI_DEVICE_ERROR Unexpected device behavior.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Tpm2RequestUseTpm (
> +  VOID
> +  )
> +{
> +  EFI_STATUS  Status = EFI_SUCCESS;
> +
> +  if (NULL == SecPttPassThruPpi) {
> +    // Don't locate PPI by calling Tpm2DeviceLibConstructor() function??
> +    Status = EFI_DEVICE_ERROR;
> +    return Status;
> +  }
> +
> +  Status = SecPttPassThruPpi->Tpm2RequestUseTpm (SecPttPassThruPpi);
> +
> +  return Status;
> +}
> +
> +/**
> +  This service register TPM2 device.
> +
> +  @Param Tpm2Device  TPM2 device
> +
> +  @retval EFI_SUCCESS          This TPM2 device is registered successfully.
> +  @retval EFI_UNSUPPORTED      System does not support register this TPM2
> device.
> +  @retval EFI_ALREADY_STARTED  System already register this TPM2 device.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Tpm2RegisterTpm2DeviceLib (
> +  IN PTT_TPM2_DEVICE_INTERFACE   *Tpm2Device
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2Dev
> iceLibSeC.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2Dev
> iceLibSeC.inf
> new file mode 100644
> index 0000000000..a9b2948597
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2Dev
> iceLibSeC.inf
> @@ -0,0 +1,60 @@
> +#/** @file
> +#
> +#
> +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +#
> +#
> +#**/
> +
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = Tpm2DeviceLibSeC
> +  FILE_GUID                      = 1EEA2BFE-01CB-40cc-A34E-CB224C800AA2
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = Tpm2DeviceLib | PEI_DRIVER PEIM
> +  CONSTRUCTOR                    = Tpm2DeviceLibConstructor
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +
> +[Sources.common]
> +  Tpm2DeviceLibSeC.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +  SecurityPkg/SecurityPkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  MemoryAllocationLib
> +  DebugLib
> +  IoLib
> +  PciLib
> +  TimerLib
> +  PcdLib
> +  PeiServicesLib
> +  PeimEntryPoint
> +
> +
> +[Guids]
> +
> +[Ppis]
> +  gPttPassThruPpiGuid
> +
> +[Depex]
> +  gPttPassThruPpiGuid
> +
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Logo/Logo.bmp
> b/Platform/Intel/Vlv2TbltDevicePkg/Logo/Logo.bmp
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..26ac1a81dad1de6c6f94c27b91
> d448300a339059
> GIT binary patch
> literal 94434
> zcmeI52YgjU_QxOUs=My4yKZx<y6x|_|NghH+jm{J7gt4ED2k|H0aO$bP^4H<
> QGt~%
> zB_yE*0tqD~gakq$Bq0d_QV1c1gfvJY9sl1m^WM$PeJ?LB$paE{@8=TkyLax~n
> KS1%
> zbIzGFXa4ZdljHh1<oGH7Zsp%q{Ct-
> G`#EmpufwsH=byUHq5i2G{0SOyt$o@Quqj|u
> zz@~sr0h<Cg1#Ak~6tF2^Q^2NxO#zz%HU(@7*c7lSU{k=Rz~xPW)x)o`oR@cf?
> b`J@
> z3c%sRt_~b}RbapstA;pM4R)*?=vXnpvHV`g`}fGX?5@^xId|?>r@Am6$<2ElJY8
> |G
> zyt{Ic<RiHSToE|*%D`bCT0Q*gK1W!47O4kQz}c%0`w*PJYDhmg7KUGTH%!}a&
> 4V{=
> z9RJnu=YG6n#_wX^8I-
> v4$+Qi#GNTq}$Gl&Z7Fm?KqcC;*>8yl`lj#+CX>y)SD?f3F
> zN8CS^wj=*w*wM)U9*bO%9Q53Q6;H;zb<d8Oe~6g;ldz|5UH`}zLmv1z_yR9{j
> tgJ{
> z?kEEo)J3vkVpHIvQGjk4_FGAxKgdBZz2?DB!KE>8^-
> m6&a$^7blB0Vn3XYyTTi(*#
> zbp8YD(el9u&hz{S&23NPk^5WRX=!O`sI96h%`eYOFFYK5B7V)GwbS;@AF*}n&
> o?~&
> zmEZ@i4-
> B}H@=z*4$IvV7vE!ogLtp!llmAtRjNB4B?v|K0?#hUGt28I!TxGGD<ArZw
> z^5&L?hQ@~ahI)=Veb&|2b@r6E$%1@1o0`b=ygO1_nwx7%PnKrJAKSTb-
> {R2`Q+~E?
> z^o<k}p$jPsbbwqvYV@^Mv+L_G3Mi3-
> A>c~*YQ;duhR1J;dwbyVxWMX?;|B9Lw|vml
> z)S@^ZhPSf1Vq?wBe)#L2zd!|~G&D9fpQj|o!R47#nFT3ZlY=Jjn0fog@m~uZ(h
> nU(
> z1~S0~8i#1^{vwo}&*e=47)GR^!H)Hhd_G~x=)yzW&z&uU+31$xx<>kGH_q30
> {LBCC
> z<<{QU_5DV`(IQ3F1+J^EEIt;WxpU#J*Z;Ntu`e-3XlY7`QZ^!N-%igIptq#wT;5;0
> z(5P4co}U=n+|;OeO8S54g<TM6k4t;PeWQ>fo{4bPI%b@2X{pFfMmLX~^~bdj
> e-34z
> z%8H6H>?(VtxV*b}-
> )m=}AavYU53QS4cjhz@fQRT~4c6)jeBOmJ80FUjl_5=`*OX=@
> zq^_U7_4(UEMt%${t|%9nq-
> +VQ2OBVbXX&n_WGonZB^tr{F*hFGG8=OZD1c#l%P8O@
> zI$9Co8rp!l9xyOcRTdmM5;14TtlNX``zT`~BLz}oSBTkXxv2M7oEFDWzk2w!M<U
> *8
> zZmb6dA`6M-M-
> *Wn+001h&Tsy`V|>Uj7p}62_RScfk8>4;OogCvGf~1Uh6aT#K3(43
> z0_`hua=;Y{OCD*gKL;lm;*gJ==Hey8d?dzC(Oa8a7*;fQxme7}X}<r*i{#MKf_e5l
> z*3`yEWuf(Cp7pV`UXmFVA&qOS_~2Y+NoM4GTc`bs?gHB^_B0I3HYhGXP+&_
> Dq3H3O
> zm>PpWu}PZw!3*2)$egmVv6*+x9FB>puBxJ@yy)zy>{A)L@(*q~x_v&A$VtJI6
> IYB+
> zT=695!BtQ1eQ)IMcLpb}dRpJ%?|~KLk3_tEbjQ5xT}um7ca$8Bt13QTU0zswrnJ
> 7c
> z8bp}C!VktTzTVK*qUF8h-k%!vQWy2iW#})S&fdR&+2d=++$huBLl{GC4-
> n6WmtF@G
> zdN#C!_xn5I7mU;sS282!RU9%gi8AJ!=93%iYO0E}3l42fSvP&}ykU_q-Ld(Z@2(s3
> zdHPZW46HO3=OUS^(C0v>t5WM7+?M)_8<Kb~sTY|nW7rCL;QG+9H%CnV@
> y?h26!-3s
> zq}9)6MlC8iwzsw{pRbz%($sXmp`ppF=6J7{FVH}I(vV<AFDK^x@X0@+kaQzj#q
> M>j
> zZx`60fXGEdq#g5<Hp4~qtD4U}a)ki_p3(_BS)!@2syHhvW_iNmhr*})bj_$wqG`
> e#
> z^qF#s6J0;C+q>qox*}AVU06+?elp+T`jC8akOTLREzkWBhouy8{|K!*m04d?snJ
> 1c
> z>DZOj*E*1O0UE7DXlT+oSDsAA;UxI}kD+JvSVTbfu28=B>%Ru8d%u7<@DJ{7
> WjP0E
> zR`0`s<^gy~GeA>aZDGpx_=OLIKl{Vr`>z8~aHFUjVu5rz#a#sA>n2uzuSU${>y$(
> Q
> zg5@XRis1V{x^ev1qh9@6a`0p(oommYZg$NqFl3-
> {v@*8SwZqrhaMOzox=*Og&q!Q8
> zZuPLM_%y}vPWg-cl#Ym|QR19EljuR5gMaA9Ha+=GTz6n^-
> MH?<fwR%;k(Lz*&bQ<z
> zZHb*TVBP4?iF?lgp|F~k>RDQ(MhA|9$W$;VHC6J}mEq6*5V0yNc4hVH6Pkyq
> 6$*~-
> z2ihZoJ6Vi727PpHwG~ANmOU!U^+5E99>I8Y5y2xrx_{{-
> yWhH7j9@*ZR2R87@bWnb
> z0*7pw^aB(GWF3z@;JWGT_s$d^-
> M4tmx<@__|EsPKD@u=OYcJI_KcckKJu+(GysC8G
> z(D7f3eS1K5T;SQ_96i`U3M^EH0T~JyJm2AkCRd|UotTk{eEHA7uqTiR88v*;52#
> >6
> zT{Ugj6N+SRmrHvMHRvBuKe6r5*}HhYjd-
> AL)@zGU`N{M>^M(f9cO8_}?c1yAN#W&0
> zpbEG`<hmgaRzPfh;g_jvr<LWVfCbowPQKNi>@y-XC4mw-<m?I7M%PQ*)_ff-
> Y<~K?
> z6sfwR2vcycZacpd6CMb@@47RE$Dj|*XX){r&}a~+qjP6Y$GsZ>1Ox@j6~XU?x
> #Ss&
> z^Eq0^V6j=ff0tw96W@qmIErONO$~KWfCHyjW2CUq%HvN6$Xi*_%L0coF8F
> G0g+(cb
> zh;x|ETqk75KA^dmL5*vKJq&ANxpI!qPQ`=|=_<%0j9LL#@{=@bDC~zRk0Mo<
> om~9)
> z*4MocTVyDoQzg-2fMkf^rzYQ#ilrNIl}$Gy<>!m2X-1n$sfMUBt9-
> ;^UL1p+5(V`F
> zr`(hkiz00Ilio@7x2_yyDA%=?g^g~tb|v$m0{HTX%*nI(NG!y0vb{-
> dRCnsN=$jHU
> zdG)YsjOzQ6d2df6trO4>35r^?7LO%(c?ULXJFScq4L<4GUBH6k3Wlfa<K7vRzW
> H_L
> zUyg2{cX-
> R2NrBHqzy43O9yluKz7Oww>5ju;uO8d^UPky^%)dmx{*QHIZj?T1m;hnN
> zjNfO3zmXli7~A;Thd;CJg<qxwPYQYP26#zhfu4=k97ngkg9&>7vPVN7zloY^pjjG
> D
> zAqZE@zu|k39kpopoc?Pb`c&l1+Y?tj!59k1vL57M;Do4G{z}1g4isa<*qc(;Ohq2k
> zaNrK5;^(1tFC3F)iSH!^J-
> cV_5Zv3O%vwr+_WQ6|_O2x?bqt$uD~qs56ZZ7C`9#nN
> zoI=I?81>3uQbT8DMJ<9LiK`|=zxvm8W4=HRmNIwtr!K&OrH@K?=QfETK&Y4T
> {Y=4;
> z@F_nLgvxTT-lP<CmLML}Q)N0d>Mm-
> <U<a0{{qK)0JDv<>IMghpSY<s93f$}h769Oe
> zvA3Kl%G94Q|3$~Akig`0);{xneSK`lJbE@d+XE}cnV;5Imz_IX%AFlEf6q_?7PRHV
> zoTj1nZ0tJ&X=O_jOWgymNZa_bIdNT887Ftbp7{<LM!ou1t}F6Vxz?{kD`rc%nG
> yb`
> z+{9`z?CPW2=bAIo*SsYi&L9WiI&WHub^d(I+2Z4*NnJNhruEet`GS-
> P_Z*IGms)#l
> zJKt~8MQnQNRx)S8$kLkfQ^`e{(TgZXdp(Bl-
> ?|J^YEaP2(KO5whEMuY#^%}QDvBT=
> z!-QdavVfwqSl}x#WX|s8WLtJTDQ@1-
> *tZ8VBysMYKa7>#3{sjUijT(O7PW2KueZPW
> zo1HKJ8H4uLsXwEoSen$_*ud+%-@bRlV_)Vb7}2XWwoUsDg?Ek%XUig{{B-lv-
> @$m8
> z5<G?U93i8w2leL0f>FaJe1}Jk^)*qi{hjq4+o%5~CuSLUSf#t=neW2tj8Ob6%S|?
> 8
> zfs%6*5W%S2PgygWpA1GUc-$^!{xyYX`ZfBse}XkSnaYC0BuL-
> %GG*TU%=Z#kjBBWs
> z$)M!m=Xf2kuuPJl<#{PlFaLGxv|mzq{1CX48NCpZ$z0~nUJFzMt|&PcPj2o&&|
> WtO
> zS52TI7UFdFLziWGIF{xUiE;QfyWhI!RC+WEAE2bNJ30NYG$=ZY1$v&f4}YqvB$w
> Qf
> zTcn?NO(1dsOki~$RiDmf5jTuYF*xbgcnaSlr4R;z1V!mlun<4tBF=);9o#fyp}IVO
> z*`1PrbIF~KW0CVoa4_&0%h15PaqkS~5i4XVjEMANVYs5QAcG!Yvl<s%SV;1W1
> ?2yM
> z4(-
> y$I0E0cDYNqUMet)GOx@YiH4oh&6&d1KdZ%OG;)nSzSisEy3<3=%_mTIcUW3I
> d
> zzIVa>B*@(PUN^Bom1E}$axK!4F(M!dP<J46Su(R<Dg_WkZB)`@#N;0x-
> y77@B6g=%
> zqf_T)BzhivRB9?q$R}jv$1RdDoVn|bJ9&i24Ttbk^Oc4Jj0zV;JojS~pzp&obaz@g
> zEjql5n{BXAQ3#Z%0;GWbcD?Z*66C}M2DWvn5-
> hx{v9Lfo#(*oyGibzz&lF|(hy}{Y
> z^b?t%DbArt!s-
> gY#$RS6A!8G0Ia4Bz3JM*3>%g+dcnd5n`;TMWv|n*ubU2!~P>3iq
> zWZ$<$z|u`DkQ?7JjHt%2t_KM6-
> #dSV0)nr055KThugyeFRnSxYheh9CIkawibF)mx
> zE9Z6@Be?e6jwDzZ{ka+yFd<~rCp}={O~FD=+{&#l{DKbIIHO+v6G1;<l?{)5MSIu
> p
> zn*A@)ZQ-
> 2zK2nq(&0FnaVUS~|lKBhMBI*4!v+3r5^HGs_x2dTSkFVg7AEOWF@0p@w
> zNcX;s3z*~9Kl(*-Ahyr87k?f3(jSd7N4|7N<jg-(M~cl;(xj|?K4jD<SR()i@p$A8
> zSYV7m-
> sAdY;zmJ=GROG^3v>m1DCX?}WUkGF#%Rt3H`Bvj#W&APkY3BBT{N$Ct-cTz
> zDTOv#`_QLTH_Xu5rJkY4ieBoYP1Q#%&`j<JUb{#mG;Z|lI~(h3NdUXnRaewim+
> NA9
> z!2-Gf=?hY~uO8Y43sR{ejy?Y!p+DEsa-Iy&Rh8oy+|tzKD;6I4f_rI=JDBt-^X8|&
> zjo_zm*43P;t153$u9eBbla~G)EC{>iCx-bM3!*7pS$sGK0ap(M1{U}n9-b7;(j9e;
> zH~QvVFb{pHAY#mo8C&1cYHW7Qa{poBE}AJPcEz?Aeu4Ul`DOcyzm0o$AUBy
> Y7ZnC0
> zJbq=5emQpT;Ixf1(?e&ag-$<v`UDBU0#b@|e!(mwF)qCF7ZT(j+G-
> gWXhiy91e;A0
> zZe@;@4AVk6XMhNn`;iqH($Dj5S#BGBA@<!N+(dVlapAEqaZT_y)chSY{y>>A`
> 7+Ar
> zDSjj_WF*RreGH><>e}bgpbxE`T96#hTY6m3l3|{|#|2=%`Pu*DD`*O4>4-
> 7C;aoMt
> z83R_|WMe<pS|b9f33}!wtjpcER(Q;Zxwa0*g~4Lyr|oiLSHffP4~>OD9`>}Dddh
> MR
> zE>}iT{dE`^M%B|&1<6}UuzmV(-
> LN2@W8BncpNxpN$&))4QgBBspRNo+dS$+teZnSu
> zyA=z^6ZsY?b%y&Ei7+oR#@&wK2R_a<-
> dV^SqI&Czzv0*F*jbQ85yv&X$aLGij>Z3U
> z>|Z{Pw^G(jK}`;S?nkI6r*jgec*@DS`!bR)XSy;M8-
> oHDdMaVh{Na3pG!|0WKf6c)
> z%|e5a;lH?g#D{$$tamIhUZY)NhsWx|^chToS_gL#eiODy+xU`bd3;n&NuwImn
> y}*9
> z(VwX)%O}Bx$G;3eJAE)pPcHt4B!Kbg9<_3f2JMaoGDI>VnUUf8N4|ij%anwUx
> ~9j4
> zij%2)U7r-
> `#QqI@G5)>#xdtPZMdH{Hzu*BKT7<t^HP&(na9}VsKEVaE&xMD!@d|?x
> zKi53?i7F*Q5ub!wQ<5eBa_pTyoCICgozVgyRN3(qP-
> eygerVY7AQYhMV!QVl=l0Ig
> z$2nE!Ye*UISP-
> @x<Vf8x9UiDZSCtVy2W7KB@eG_PLC=&UE`3^d%(6r4rzfwTcwqUs
> z)7c56XL^pzY5grqDnP+UsUfx%P9`OpVp^{{eS)VJ2H=YXQcGAe29`Uteg;#$%m
> r5}
> zJvTdch5j5^&;biiXYFO-
> VN%c}T_ku+O<2hM6qaW`!I8CVDa%P1*Yr<jMgSTXu&poL
> zc6?7DMdIoHrH|#tuOR`UtJXjI1^tx+%g1sDXPC^W1<7lsFsXeiV>fp)qq=BQWu)
> 8m
> z)VGj@wA~LGNg+a}W>|qDSg;3$OA2c5SOA9bDxEnHXgqh8R?|mm_I_Na=z&
> SVQw9jv
> z6X*YMDfSs!pOFPujnbS%V_B0<QE+Jcng>4#Pg;-
> ;KQL+>i&|*O@Z`Zw%ra0~I2kO!
> z_I0&qYs$poUmrCUg*&GIMvpRNLfNounG+DYaM$dAYq1Ip?wT$3G4oMfk`p
> oYXHqHU
> zJW0KhR!?j&)mkUkSl|=%^RB;K$jOVA>X?60Hr9EO2_P_3W|Zj4qD-
> h{=@ZN^c6{yi
> zyB)uNNjXp#Pbk^;y!gfL5DOHEW}+SGa<@Hy8>;B0C;ta_g^ek^JVo9Z_913(!zc
> eZ
> za^~-
> us>bI>rXG}=9BEKgX=|W?w2uypRTD*9VB*QEToHr}uOdch#MGaNsy_X<p^x7
> T
> z1jqz8A&mt%>h!U_2s6xLlOa5ebx1}T7gta!d1cs#!YBPOa@OrEhUIl5fs{&tlzDK9
> zM42~F{JxB0E(a%7Yl&xwe$7lehS^O|{SVOKyIMvf2Og0>e^skpLr5#{a6p_(3w
> uql
> z;Bukif}e*r%mks{ail(BwNmO@Kx#^ERNP2Ot9d?MBr;MO7nHx9SA3f6kj}ySQ
> Ryy>
> z{5@Xq3amoYKyC9$TX?LO$4q>=DYf%j7#9{!(J1co3&tm0WLNW6Zn2U13Z_B|
> 5BpIm
> zVRAJ;rC;Y=ehMoxPwh;A+grN@ll1NxiXA|xYG4675-cR36PZWY-
> cnQbT^tLY38a}!
> zq~KaHzq3drvn1eKDvesJs4ND!oj9>@w>VE8-
> aH%A0b^pynimolj$+!{3?+kf#>LYA
> zpe!6Ttf_(swR(Nigm3e8BbhH3(1%)6eU=ro^d6jAs!v_$9D?q@j=3K5$y&?ySc3
> al
> z*hpYb&$Zl9J)XycX%Zpep;f^HEHX7-
> m+KK9X|JKV54q4TxuE=!GyV|2XcY1@CzRYh
> z=icziKSH9Q17U#n9TbXluAn@cH;gh%?S@}V=c(Gr$xFsleIZyFb7QRvP8;%|b*{
> ~l
> zxF`HnSojk>S$-mgs+rmQf)<Y!Nmx2Yun@I?c4t-
> *b%U9R;$wS@4oBgvmALW=%GO?a
> zXbYOPrs5RKeD%1%UnD&uB?`CrtTj8~IoJ^~_2(E2byVTQn_mMO=1;>3Ck||=
> F3Uf2
> zD$6*}7H2cx9R_erp6yPeAyqQl`2ORy<poB1eNkIch~FbUwmW&L6e1-
> fJ`TVq6V|b7
> z37;@tudOJ^j9#KZ+GbdxoM4|aY?=6dT-
> R8phqWBSx*zqmRmDekCoFwr?L(h}{_Vj^
> z7ffX<td3Z+XI{XG_+Z2sqm#k<k+Eg=@wipt&;EciJ9{lt-$*7RDvbWznSzY^>PiH7
> zgcJ8F_ozEGI<_6?R+@c4=+m}37p|yuHTxDl#CJ1yE}(~xdgagTUxWJ!{ER#9@ja
> `N
> zf4u0w(3!QajdkZ5n~8lVZpQp2xAZM<z-
> B(yf@I{ga)8rskk>U25oFbZ1+43gn<Suk
> z#>r2PEfc?Ia7Zh;Fmw-
> a99sV(35@jmf;%`0Lh9DUO22?JxryT<5nv==b(r7f1~I@@
> zm)?p64WG3SeJ20lCK7Y-
> m(bfx&Nj6<_}LnF3BB)t^3kH?9%;o*I2?Opeo~lrMI+~!
> zH^oY+i%sWnJa&cppqNuwRf@gcGTe{}#alc2vrJ653kjC$_k^D`0ev#F9$O~<FN
> 3m2
> z%3O$YLLBDzF#>OT>YGqFa@HL&Z{4+J(*JFr{yQFR9Cr)zfG}!%<)ItI+CW?Abtn
> cF
> znCz4G@(t0{oy58ELFA*tst`b;k!z1wIGq^}n@I}SLC`!Bqau040*sBhOiI|;<a&eu
> z#k~jHpal!Ud;P_t!c&e$JZ9Vu?w>puW}fpEAl&PSnbTjrB)g&*FSWse>xb*9Gw
> M@W
> z_I}h-
> cVR#Z!;F=h|0QRkj9MQW{o3EnSjdT4O8vDzJjs|oCVC7nLREud$cjev(vC*T
> z9&$n9=>|nB@r{N2Rcv@3DM$klc2d`}4<JoU4`b<MEFUF3;H3$SXmUic<7epD
> uX>PJ
> zJQ;SVEaMJ~K6ndefluUblkloXER<&L(^$})MS35x;NnE*|Kv~HJPQ{188=s4D487
> 5
> zC9%B4O`e*uARIfuv0p7;GC*p6i&xBt+asxIT~+DMS$CLaQ6bA<$M$Kz!pv^Ym
> c;H@
> zAOXX%jLT|;Nd4K;*ttU(P`tODr77*7-
> J}5E#e;<gG6W>)e(UQIw&{g@$s8ooWJFCQ
> z6L?0m$|b=9C7}n<%e9P>7_4jXGvzd}pn)7Y^AFr~hmY}!dnT4UypG%0YKeH}?
> 9Azi
> z7%5O5&1B&%ezu1NJt)%<S_sRHTLqddLZ&Y*VyEdE1)w%!6%Axy0dctcblysa6
> <4!*
> z&lxLR*wf!-%2G>5nn^A`7IZ%x{rbNwyhnM2r4<wMNFO-
> 8t1ef}jM(G>zj>%~zQTY7
> zJUkt`rUp_-Qd?QPX~MTaq9Ij67MEkQbF9>qA+Z-
> M81p+ghLQ4YQ6|}9+@N;eTfu(X
> zeG0f^0pXnpZ|>4>d*4FzjehMPG@NrtP)&X*upkpR$M>v~lDLK^&DGjDxjgR
> >%idYl
> zemrg^A&Ud?LsngP`evD1vAm+o&x%E)cS0m7=TCg>|Fn1hP;5SWvA@b(`gz>
> Ru)abE
> zgJZcs!of?yk~6Px#|;Zh&=+)Hq_JQO5Q5OUYSy;faA=SH{CMAt1)4(!Xs}Rl#CI&
> v
> z=<&*sb&0W{X4A@!AF%fDiv5mmn+va^*YKADYqJl70+yM2JdI7th3@U)*z(-
> uEt7r-
> z9Y_zA<m6oy{U-
> E@ubtQ{h5`<Jel|VvO$@&V5NI92!T`sy?ej@sMwv$}<f^PJSTMtZ
> zOtwzF&G#1ZBYX6ztl$b(RZEk(BC&%7!dz%aUtdT8tL$4iN^+p3UB|^A7qGfB)y
> ~on
> z`dBmjA<wX8cJ0HT)~0*7RG$bluqzf(Ysr;zU0Ha9^qy?d@;XGrB@$0CZ2rVTaZe
> ^#
> zxED`RSq^V54CLXCd0gP#xOu}{nnj~Guc9&!5O~h>boZPAG6QG}OP&lkzA$Qs
> X)qRH
> z)7DL98W%btBlQ$4Fj4Zr^)=-
> utynlOi{kNWwwMB7Dx8Fi)cSXWUAfRkEn+g5Wgd4j
> zqD+B4=Dt0e4K)^+FVKW_^$_wucg$EIB_qzpC%;*kBHqXdcOC}_lsFc-
> BP@Ym8xHQx
> z;g>sb2;C_=*yy=7k&&8>aiP_|?d4lN1PiPd4<31ab$Ol#ER^Qr6Jo`Jno=jQwmCg
> m
> zfFX(Jz?>l3gqK?Lhy+-
> !JaVS*SWx+>02%`v>B=jNaoHmr5aba5aEJ2_QtxH9pL(GH
> zt%m1DZF!OQ!Jrk;G+A4U(+*w=US2dF^(ZXVc*epBcPxnc>&aW;d_A+KyKaqz
> )b%sK
> z0v&#*PnR!Zr?8+Y39MMpPHczf`dZ-
> W5e{I1ZCpaYbwKC*#EizWFT7KLb}u;+3!R}q
> zr{)J0d$3J}sP;1HtyqwWuwRQ<Vv=BV-PsQdhlkLyw{-3tNBWyVfj-
> d}e36mNROLm~
> z2Q0DmRpsr$fdZe{zfL42-
> z?td{O#)wDS&|@b>qtrSz|#*fkvSgYq<}4N^iu1aNS^L
> zsE1gwAh>8Iq7gkqXHT-KtEpW3@MjUm$iE9%fZF=SEzf?R)myrEGL&d-
> S<>?kETXp+
> z2Va=8vuWUp$d~>sSWs(uKm^wqH++;!doLDnG__y>B&cD6iNj8x;HSQ(LJMP
> E#)57;
> z_?)Op><a2WI?y_Rm15(5i8-sYZEdIbP65p9EC9#L+8oL1Sk$7+9}9~|yJJD%;M*Z%
> zi0Obs>#EEAf(042*a+sC@8Qd&8^stM^w>?Yvv)6-SrS`P@<DX*&j048*h3Igi!)-
> O
> zuqHLliqAhW%u(pfDLr2I-f@9lncT4e4onQ*?j?yVDaHO%U9sljPj^Q~GAIljm`z{-
> zku-{Oq&LGsyYOv&{ue+-
> FC{Zxv@g0z0S0B3nHX5W!b&hS0&e><3inbh;PVze``=XA
> z!tO9Rf_jIC+4)N6fQ(dKnx_IPc3odEw<CQNYZ=%{fx^&78CcMY12>7CBEbwhvi
> +L#
> zw68m)0LDWM*MtzK!!bxr>`E}w;k&&N3sed$uwWdHGGl?Ro;ydjzQZyomZEq
> (i6$5G
> z#+`(B12V?Yzy&|g<fqf0>q&>M>CP5vi|gP6AFD3Ol|jb@2f0?R^#sbZ9a$|z>*i
> 1T
> z7KVWQ#Esf^0jaqtOxx+pq<=5Pf@n#PeHqSopI=BKbnU;}toKJ0F;4o2;E~r=mE
> >Bm
> zKvpM{!dA&LE?F|~7c59V#BzK|)(*P|Kj-
> H0_%(cpWZh%{`*ni?5R<mvHuW||b6Mtz
> zJ%vgC&9d&YgQ4M4VqtmfS{^;`?E73B9E+AzS$Nc)rOS^esd;D53}y@{9zYZ{kvt)
> $
> z@Nnnn7mVgGUyv1ZaQVqwbvI>5O0*H04ecdX+yI|ug3Q_4*Ip<9Z{QeQk)N
> UMczTv0
> zIb<^3AkE?B#S4uEyaWl$Mx$GFTJD(FwRIi~*Ra-
> @t<5B7m%hvevkTn8!jGxhz2e;A
> zEjB5$zJ=!s3(Tkgj<--|N#-vsKzZ_H#V%G}Bv_G-T&8cX`DpyY2WbNLqIzjE`%#A!
> z5Di)d64wrs_=6E2V+AbX)tYqSut57_Go)9{*!GU%J+o*pT_Vd642`C<Sb!Sz@Py
> SO
> zANL-<<j8J%28$>z96pdpq@N{tI|95JK{yNHR43^bt^A7xhyWb48=-
> *(L#@k8+|0OO
> z8&^AI?@lG49ajx<oX*?_dq8vD?d*E<F7Mrrzpy~C2-u!p*L)(m5obx*m4)-J-
> djV0
> zo6)cSjRd-mUa(MAoJDLy+^&qAb&cR3B*0Tg;>gO#oC^-
> _6d&CkI{xdt0^E>%c!ldt
> zPke)&V$A6&j81=K>)VEU<!3A?4C-
> LobW>(AsiC2X2#R<bWBuq<Tib~{qyUYsBP7c>
> zTvvy<K!_XFKes#4(0wexPV}oM;zKf{7G^~+ah;3t|7VLaHk9Eh{AP>_T+5yMbG
> SMi
> zJkTB%n5C_+J)6DzefB)nIp^+K#RjRezXmFUY!)d)1FjdwC%E8a+-
> x{kMH%+KcR!I0
> zV&5H1@#<^OXdsvq%NS8tBVij|E_43H0<FfJ1^(eR6-Ab*H*i6D2-
> 0ix2^}`Eoxn#5
> z$Z$N!k+(k-3d_)-
> NWJTgy9`mpJ)dr3LHDbg_xPy$;XWe3ha@Am45fmfb&=Y`0*MiU
> zEZLsQh|%kvd7bj-C9EZZ!QRdyDa2V`)TlI4a=}5G)X<q`dye0+K!&tSPOPk8rCrQJ
> z19#X51c}bQY3w`Qp#U_erwtzYapjM5UWNuD&zI$c5sUx7@s;jlL3j9?uRQ)W
> Mg+~J
> zdi^rv7wkcSbxGR8g2C8E&M*&gFjfsEbdMN6sTb0?-
> bX{HF+S&f#r50$DNo3a7=x^y
> zHq(b}{ir)rK{BMW&JfUTv4DN4C~c?j>ky5GvoAWN0A#0=(eZ-
> xHa#?VQu_uae__GJ
> zao+xi8#Vi7?p%mKVpbTvV8NUtIcO{xvBHGS20KE>-
> @;58k4UV)V!Wjxp#QeHsenKz
> z%k__ln;iKVwB_2rSRiNmD7LewggTOy9vbMZ81!mN^VNdu4i+C7#j`JbrvN+#Z
> SxLn
> zgz``uDTB_3U35LpHGl=}HUpoU*@kyL#tL(fn`eH@+qKI(qBJ{!P7)!<Tq7@7u;fX>
> zjQB`K4rIu7u|?@Sc`7pw9eC(D<47`^Y#4Woo>MTg;^IPJ0m}weK37$V$Y+R2Tr
> d*^
> zF2wi4w|G|Oa@yA&Q$R^dto^JiIWDfq%8p%_8mYQss}c<sw38cLWI56|y<#y-
> GKW=>
> zmugAo`_HP9Y_>E)O|Sq#*iWtTbf0Sj2-
> ?Zn{FTDAD6KCTq=0*|OfJ34v3pMcio6t^
> z7*HT0GUGrFoLulzAB}ZY$wALDpwK^<M+BYW1;K&}ElaRmlpiY=8XDF=`XzhD
> &1g;k
> zUeKB}wB9dXbwpyXIJkNu;*+K6VTQ<;{&X^FbMC%1x%)zlGe2o_?7M>)+0E&
> Z8~_M=
> z@*2r}xLA`LACeyS3SL0iQlu01G~dx47FdZuh#}c4Fg{p+>ty04Hi9G*L+>^im^%y
> *
> zgv8(d=3Q);TvL9E2`(4=vm5Mrj9SEsNeY^{aoktw1X%uWuAR{Y-
> 1NJQM4kjIC`gW=
> zJZ3Bab~ck`lPO;uDUA}^7oDO2#K&O1cY(MKGvg_e()kbAJP{r+qQj9P$zXW;YW
> Gvd
> z5t9_H6T@uoDLcHw;yWc5dFDOIxt(!A+((PEVRBHczam*V=agF|e1kGl9krV($(
> WU3
> z>s6{uSPZ=2;5TBwQ+@cHZAvUvGjh<?^g9;Fmgdl#npv<wyF^U+sYeOcTq^szI
> ~1U~
> z@d`c|H~~0dUnM>Ovguk@RJGmWmSpXn?q6>&rT6=0^ttEB9dB5WI2bo5p{T
> W-9lHHX
> zdDOPo@EG-
> #zs{Y8+TE?jC>ZZv5G>r|$lM|E$2?$Rs*MHf{!m79`0E0GpciFt4h;wX
> zviTzcvdo$qY2Xw0lQeLJze?ggAFo*O5C_A1ZkDGSr<R*ueqJCfAR{4Oy2(h0fi3K
> _
> zX3X??DVY7Jn-
> qYh869%>u2wygC=Oev{mK}T0Rk>McuF8bm`_BD4Ht3mj0=i|&JyrK
> zV1Yc5k(f$w#{yPXf?>Mb6FOULJH0Oy01hav84+^;f?z>*S#nNviXCa$<NChkZ+
> h74
> z7CVwJ-
> |AYLUX2Ac?#Nb~bSzwZqyUC)M&7E^Cvl`T%Sg;T*4NgE7VpWV;4v%vW;ZE7
> zw}ZlnSC3%fg<l#f16a`URB04rDoRfcyU#ClvkYEd@4Z-n`C)Q6dELXG4Z80-Oava`
> zKzGC>0>sBiY{mj+-
> ZMp+w1UMf=7m=FqwZ6H=D@m=8MOpgXPQrEXkel3{FFE+Tzo9l
> zRu=GGT>bE3(kIsV+VXt&xOv^DhL;>*W?yw@QVwLb>1}z5n=nda@7=d}^zw
> V$;UIA)
> zBc7MVRu)%P?wm+i=joLTu1k8MKwo%7_k}7QXxjPLj0Iy{(7tvT7YiQ>8Fj;%g2O
> nM
> z)>oGsCzE2#?lEZ&kS|&T`Hlq?UX(0$HDV40lW+F!Wfg^)yWhUoW%YIPGZ`YIrf!
> (2
> zuweDgOAdLCKB_~@*hQ;;-}w;j!fDjEr(i*qD)h0hgpR$5I0nYa&-
> IUg#ZqRY@E7QU
> z&-
> pkmkSrtOEhf8}*2i6zT|`%p_;CKg%~D`f>?67$WYp5*$#@?b0+Mn`YCuL}16i<h
> zf$Cys>pKM$79OO(!q>rVTzK)K>CO}w{()g|MX;W(kiWiHs+%c&#{x5e*>Nk0$i
> aTx
> zN4CvnfIwe3nHa`C&SqU0OGVg(@5rD~&psK><vf6bRq3@AMQYS*<DJ#b^4q
> U>jRIhy
> zJ%6OMO)p<eEOf2>7ve1o7L?Z_j*HIiP0jl+!1;UU1!P4pDoTyaiCI!|G&XU?6X_e
> <
> z(2d*>fsRGW(rojfz%_Sr;sOb~Z7a?fq8&S%CtWd{G{wyg*gfZ7<BXYeZ`{0q&1`j
> j
> z5vSWaTk;E+USk0j0A6)JV&1$92<WdP2(2D^Ro1R0<$0+EsoS%5Eh|jhfi=mj-
> QeP~
> zVeC!pPb%h9*Wv|r(Lm<AX5ZPK>FL5%(9XF%3IGS1!~L{4=C$|w<#!(}pcF^F{O
> 5zK
> zp4z|cG4q+U>Z#Btz7EBVS~INx>9#%p^Moa%cg_Bn2zaKaWQB8YX5<3c-
> T(q(64$uo
> z)m4{^XOum&;Mb_CM$`EHg4R?sK^?pC`2EwDFhhaE5Kmr+Y6o+RdleE6Hfj(d
> BBe=X
> zCK*a`*wcDLz1Dy*3Jc-
> @aA4&GWK_O&32SP9+D8h|O!QhrsMEb)n}+TsSoX1|?#ZO?
> zo=yu8^ou&B<q?t+-
> F`{tKC|D2F(}m6oCz8EQS%_;UIzP4&!GTKOm}y9^X#*yvIsAu
> z9jDF0aL*}fPb&$71rA6=6|hK0V4+TF%?Fl`XNs+-727UPdlV2X40Ie?_aY6-QJ$BE
> zmQ8E{K+!kV>h=g_xewh4$E0^l_ZUgFBy;a-7D3yZLhq3-
> 1Pg;5iK{081m=nK8cFt#
> z-
> nZx>TA!I#_w_y&uIPh5AsUp~Iz@*8Z(ZH2r6X*!5VO4~mwk|2y{O9Q2rGv;;{SX
> 9
> zxyoW1QFhPeKdd4(l^I*!M3rEmXY6Qiy<{({sb7kUXaqra&bouuYFLUawj&*C{=
> oa=
> z7+8UfU%qH(axp0Y9K_r);+nLLFR}U<Ah6vDA>g<;-
> |_(tX}jLM8>2cwev}!uZ&{p-
> zhJd$`8(Ats%w&{hi@OD&&;g&bq81Af%;u)vBPSS@?aLRcp|51<C)Q%l?&UHts
> Abf8
> zyCtqG^3sxmCb5?;X;8N@kMya2kIG_D#SE(*@Nj6cj0hSCL>Lab?<2PD=rVwk
> wD^#I
> ztW{*s-28)K3J?-lfQHtB6L<2H!(-<LutFK-
> QDi3p#pN6YOZO6lK4zU}dCo!AMMyAP
> zv;%z_Bf{y-
> 1k@|TTmCZO2fGTo4@7DL5hwPCHaAHuJLeLW2HEV1gCGMZ_JzdE>CZ^P
> zFrh#ptEV|FM)=-KPpJ;l;{Zp<gEyqCnM$qc5a<>RASe_73h}id#tt?09)F|vlA=$S
> zT)6sbqynr=;gf%o6T3nHAR!#ZYyv+Jf=1tAn`2}ue0bPbRK%x&5|4uUI{`&+mXlE
> p
> zz&MgWLA)yqj#63O8?*vJIa+9~Dr@Hg>MIrR<+bkBO?IIRuMxqd5(Xv0h}Bn>!
> xb{k
> zs)F82AR47&Yg`a13%wFq0u@_!MnHm6-
> Z;I8Ll_8<b0|E7WvZpJFoUXLYBmoC+ICuh
> zPTWwNo15boJ%j{hPf%WHR_r19OQ#pmk3N6(@M~G*$fgejse=>5GgEbsum
> {n~wD`pR
> ziu@y)k?*mK5b+;^@4Jo_F`{m(?P<tLpFO8)syqZL7t;Yk&ZZ~7nH)U%T;(Yz3S1R
> 5
> zX$Q`|*h;hZZ+Z3y)b8@un0iP{^{8UNGxUBiOwjOaw@v%iiTGfg{$Usny;YeOp
> OByR
> zoE`TY&s7y4iDMVqU2oh;P&*_pUT3^O`nu#phOUly=n-
> lUrQm_<<K_)z&051bu_}wn
> zRH48Siu7=xwF45QhrQ}_;<DwU-Yg7v2V&BT5`1j1><LAmAN%&8;-
> hir)s}*&mfGl~
> zKp|VD=t)>OM;~k;m6x!dy$*N2{1?JM2H*D)I#rRTP&5=e#44pCsq&TX6w>`&
> U2L!n
> z2DKu9E<ogp@JT;PT=i7R(LJs*TJ-{_L?nhI(UCcF_XdTIy#=|5;2xKap}?JD_8s3T
> zp!-
> $n<cIVN9d`?wLTUDXA_c=O2uq;A;3D0%%KV+ge03f~#jYtY%ufnGvUN_v(nlj_
> z{xNjy&Fe;gHu(PQkjKD?NLFeD;U_#S7?Ja8IbDL5+l6{6X=L*eUIeq0kacJL4I1%b
> zmRoKd|Mi$R?>Q_Xltb&PD|Kl=F~u_q%!P4H;WeTud0}z{1EQ`npZ1+rcFMj$0
> pUh=
> z1q!%=ZkA4R%f$a>X-xTv6k|RD<yvpg;T$ZK8A_N<yggc>fdbM*P_453;-
> h<y?+qsI
> zSyJG{*mnl)n0foAr@j?3>XWD&_=+%m2zz@9l`Mmc!VbwuOgQdMPu|LIvwP
> +ZOIh=L
> zX4E2fhp#@J$5%A}!`on!-
> d^j)x_D+3@W|<pg30t?*tQpbDP@rONPTqXy)W>yzv@VD
> z%oqVrGFuli>Ju?<^;ePM^Nq2<g$ps!w>{xV5F_E)UE_v_{~Kznk+NzlPL*aRlw}
> {V
> zo>>P7FH?86w63bm!^`Rx=;JHqKHtpzE;uw8#W-
> 7%%WV7lF<(F;0*0X8U$nCG=_3?i
> zun@D1>ZOrPFt#KGPRNa4TT@n`XYOE3^lK$Ywdt1I0>nAD+bHbIDK1j<<S;6T
> @qD(3
> zza0CLkXW70s1)XG%|I~jgG36W$Fi2@=IXNiw6IsUPyaoUrl^Ie`L;yVR~2MGVO
> A#W
> z)L<bJI~E%}H;6$;eAnZ#E2~cDnR{=MSVWql(-
> seh3w_FP;5H0ZoIISiVaE0uzoVQK
> zSPcZde$voSO=(B@^Ctzsh3K<tl`(G5Vurf^I>I0WjU(IVojS6&zPij9H4K<wpkhFf
> zO~W-z#L($3VtK-
> jN~lFIUe~+Y8QIFf)Y5|bke9SMIb=%YtUEAjQ6#h;vG?}L@E|s7
> zE(rxh<5sg3S`pTwI9pt87<+T%%sUbmk51h%BYXFXQ|Zx_1;^^no+k2SQ)69Ai_
> `JL
> z%+lVkVfd!T`i9!Gb!SS-a#PtA@kqp+1Ix!nzxt1jPkcj`o~bD|3Sjg9CE*17qh<<d
> zT!<BPm@@t=Gm(fWSZsz}9WwG`>>m+2{%hfre;hgM_PBQk@0mY5De&o(kj
> W{*lh`LN
> zJ7#HC^kUBJT}zH_pU0Mk@+fH1p7|s8%ncxZBl|;P@?G=Lr?D&v=VM>hZs*!R
> L|JIf
> z<*~1A3iK!nxB$Yg2Uo$sXs-xY^xgmjWfo=zEOPc2S<5*2sqYKJ4-
> ^wCuka$TOSiA5
> zCu}X))`D#c*c7lSU{k=RfK36L0yYI~3fL5|DPU8;rhrWWn*ufkYzo*Euqj|uz@~sr
> e0h<Cg1#Ak~6tF2^Q^2NxO#zz%HU;_;1^yp2*qOxu
> 
> literal 0
> HcmV?d00001
> 
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.c
> new file mode 100644
> index 0000000000..b1fb4adb34
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.c
> @@ -0,0 +1,185 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +  LegacyMetronome.c
> +
> +Abstract:
> +
> +  This contains the installation function for the driver.
> +
> +--*/
> +
> +#include "LegacyMetronome.h"
> +
> +//
> +// Handle for the Metronome Architectural Protocol instance produced by
> this driver
> +//
> +EFI_HANDLE                  mMetronomeHandle = NULL;
> +
> +//
> +// The Metronome Architectural Protocol instance produced by this driver
> +//
> +EFI_METRONOME_ARCH_PROTOCOL mMetronome = {
> +  WaitForTick,
> +  TICK_PERIOD
> +};
> +
> +//
> +// The CPU I/O Protocol used to access system hardware
> +//
> +EFI_CPU_IO_PROTOCOL         *mCpuIo = NULL;
> +
> +//
> +// Worker Functions
> +//
> +
> +/**
> +  Write an 8 bit value to an I/O port and save it to the S3 script
> +
> +  @param Port  IO Port
> +  @param Data  Data in IO Port
> +
> +  @retval None.
> +
> +**/
> +VOID
> +ScriptWriteIo8 (
> +  UINT16  Port,
> +  UINT8   Data
> +  )
> +{
> +  mCpuIo->Io.Write (
> +               mCpuIo,
> +               EfiCpuIoWidthUint8,
> +               Port,
> +               1,
> +               &Data
> +               );
> +
> +}
> +
> +/**
> +
> +  Read the refresh bit from the REFRESH_PORT
> +
> +  @param None.
> +
> +  @retval Refresh bit.
> +
> +**/
> +UINT8
> +ReadRefresh (
> +  VOID
> +  )
> +{
> +  UINT8 Data;
> +
> +  mCpuIo->Io.Read (
> +               mCpuIo,
> +               EfiCpuIoWidthUint8,
> +               REFRESH_PORT,
> +               1,
> +               &Data
> +               );
> +  return (UINT8) (Data & REFRESH_ON);
> +}
> +
> +/**
> +
> +  Waits for the TickNumber of ticks from a known platform time source.
> +
> +  @param This                Pointer to the protocol instance.
> +  @param TickNumber          Tick Number to be waited
> +
> +
> +  @retval EFI_SUCCESS         If number of ticks occurred.
> +  @retval EFI_NOT_FOUND       Could not locate CPU IO protocol
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +WaitForTick (
> +  IN EFI_METRONOME_ARCH_PROTOCOL  *This,
> +  IN UINT32                       TickNumber
> +  )
> +{
> +  //
> +  // Wait for TickNumber toggles of the Refresh bit
> +  //
> +  for (; TickNumber != 0x00; TickNumber--) {
> +    while (ReadRefresh () == REFRESH_ON)
> +      ;
> +    while (ReadRefresh () == REFRESH_OFF)
> +      ;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +//
> +// Driver Entry Point
> +//
> +/**
> +  Install the LegacyMetronome driver.  Loads a Metronome Arch Protocol
> based
> +  on the Port 61 timer.
> +
> +  @param ImageHandle      Handle for the image of this driver
> +  @param SystemTable      Pointer to the EFI System Table
> +
> +  @retval EFI_SUCCESS     Metronome Architectural Protocol Installed
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +InstallLegacyMetronome (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  //
> +  // Make sure the Metronome Architectural Protocol is not already installed
> in the system
> +  //
> +  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL,
> &gEfiMetronomeArchProtocolGuid);
> +
> +  //
> +  // Get the CPU I/O Protocol that this driver requires
> +  // If the CPU I/O Protocol is not found, then ASSERT because the
> dependency expression
> +  // should guarantee that it is present in the handle database.
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiCpuIoProtocolGuid,
> +                  NULL,
> +                  (void **)&mCpuIo
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Program port 61 timer 1 as refresh timer. We could use ACPI timer in the
> +  // future.
> +  //
> +  ScriptWriteIo8 (TIMER1_CONTROL_PORT, LOAD_COUNTER1_LSB);
> +  ScriptWriteIo8 (TIMER1_COUNT_PORT, COUNTER1_COUNT);
> +
> +  //
> +  // Install on a new handle
> +  //
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &mMetronomeHandle,
> +                  &gEfiMetronomeArchProtocolGuid,
> +                  &mMetronome,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.h
> new file mode 100644
> index 0000000000..9599eca702
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.h
> @@ -0,0 +1,64 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  LegacyMetronome.h
> +
> +Abstract:
> +
> +  Driver implementing the EFI 2.0 metronome protocol using the legacy
> PORT 61
> +  timer.
> +
> +--*/
> +
> +#ifndef _LEGACY_METRONOME_H
> +#define _LEGACY_METRONOME_H
> +
> +//
> +// Statements that include other files
> +//
> +#include "Protocol/Metronome.h"
> +#include "Protocol/CpuIo.h"
> +#include "Library/DebugLib.h"
> +#include "Library/UefiBootServicesTableLib.h"
> +
> +
> +//
> +// Private definitions
> +//
> +#define TICK_PERIOD         300
> +#define REFRESH_PORT        0x61
> +#define REFRESH_ON          0x10
> +#define REFRESH_OFF         0x00
> +#define TIMER1_CONTROL_PORT 0x43
> +#define TIMER1_COUNT_PORT   0x41
> +#define LOAD_COUNTER1_LSB   0x54
> +#define COUNTER1_COUNT      0x12
> +
> +//
> +// Function Prototypes
> +//
> +/**
> +  Waits for the TickNumber of ticks from a known platform time source.
> +
> +  @param This                 Pointer to the protocol instance.
> +  @param TickNumber           Tick Number to be waited
> +
> +  @retval EFI_SUCCESS         If number of ticks occurred.
> +  @retval EFI_NOT_FOUND       Could not locate CPU IO protocol
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +WaitForTick (
> +  IN EFI_METRONOME_ARCH_PROTOCOL  *This,
> +  IN UINT32                       TickNumber
> +  );
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Metronome/Metronome.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Metronome/Metronome.inf
> new file mode 100644
> index 0000000000..173370d652
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Metronome/Metronome.inf
> @@ -0,0 +1,49 @@
> +#
> +#
> +# Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +#
> +
> +#  Module Name:
> +#
> +#    LegacyMetronome.inf
> +#
> +#  Abstract:
> +#
> +#    Component description file for LegacyMetronome module
> +#
> +#--*/
> +[defines]
> +  INF_VERSION	       = 0x00010005
> +  BASE_NAME            = LegacyMetronome
> +  FILE_GUID            = 07A9330A-F347-11d4-9A49-0090273FC14D
> +  MODULE_TYPE          = DXE_DRIVER
> +  VERSION_STRING       = 1.0
> +  ENTRY_POINT	       = InstallLegacyMetronome
> +
> +[sources.common]
> +  LegacyMetronome.c
> +  LegacyMetronome.h
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  IntelFrameworkPkg/IntelFrameworkPkg.dec
> +
> +[LibraryClasses]
> +  UefiDriverEntryPoint
> +  UefiBootServicesTableLib
> +  DevicePathLib
> +  UefiLib
> +
> +[Protocols]
> +
> +gEfiMetronomeArchProtocolGuid
> +gEfiCpuIoProtocolGuid
> +
> +[Depex]
> +gEfiCpuIoProtocolGuid  AND  gEfiBootScriptSaveProtocolGuid
> +
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/EfiStatusCode.h
> b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/EfiStatusCode.h
> new file mode 100644
> index 0000000000..1d396ffde2
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/EfiStatusCode.h
> @@ -0,0 +1,178 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  EfiStatusCode.h
> +
> +Abstract:
> +
> +  Status Code Definitions, according to Intel Platform Innovation Framework
> +  for EFI Status Codes Specification
> +  Revision 0.92
> +
> +  The file is divided into sections for ease of use.
> +
> +  Section:    Contents:
> +    1           General Status Code Definitions
> +    2           Class definitions
> +    3           Computing Unit Subclasses, Progress and Error Codes
> +    4           Peripheral Subclasses, Progress and Error Codes.
> +    5           IO Bus Subclasses, Progress and Error Codes.
> +    6           Software Subclasses, Progress and Error Codes.
> +    7           Debug Codes
> +
> +--*/
> +
> +#ifndef _EFI_STATUS_CODE_H_
> +#define _EFI_STATUS_CODE_H_
> +
> +
> +
> +#define EFI_SW_PEIM_EC_NO_RECOVERY_CAPSULE
> (EFI_SUBCLASS_SPECIFIC | 0x00000000)
> +#define EFI_SW_PEIM_EC_INVALID_CAPSULE_DESCRIPTOR
> (EFI_SUBCLASS_SPECIFIC | 0x00000001)
> +
> +
> +
> +#define EFI_SW_PEIM_PC_RECOVERY_BEGIN (EFI_SUBCLASS_SPECIFIC |
> 0x00000000)
> +#define EFI_SW_PEIM_PC_CAPSULE_LOAD   (EFI_SUBCLASS_SPECIFIC |
> 0x00000001)
> +#define EFI_SW_PEIM_PC_CAPSULE_START  (EFI_SUBCLASS_SPECIFIC |
> 0x00000002)
> +#define EFI_SW_PEIM_PC_RECOVERY_USER  (EFI_SUBCLASS_SPECIFIC |
> 0x00000003)
> +#define EFI_SW_PEIM_PC_RECOVERY_AUTO  (EFI_SUBCLASS_SPECIFIC |
> 0x00000004)
> +
> +
> +
> +#define EFI_CU_MEMORY_PC_SPD_READ         (EFI_SUBCLASS_SPECIFIC |
> 0x00000000)
> +#define EFI_CU_MEMORY_PC_PRESENCE_DETECT
> (EFI_SUBCLASS_SPECIFIC | 0x00000001)
> +#define EFI_CU_MEMORY_PC_TIMING           (EFI_SUBCLASS_SPECIFIC |
> 0x00000002)
> +#define EFI_CU_MEMORY_PC_CONFIGURING      (EFI_SUBCLASS_SPECIFIC
> | 0x00000003)
> +#define EFI_CU_MEMORY_PC_OPTIMIZING       (EFI_SUBCLASS_SPECIFIC |
> 0x00000004)
> +#define EFI_CU_MEMORY_PC_INIT             (EFI_SUBCLASS_SPECIFIC |
> 0x00000005)
> +#define EFI_CU_MEMORY_PC_TEST             (EFI_SUBCLASS_SPECIFIC |
> 0x00000006)
> +#define EFI_CU_MEMORY_PC_COMPLETE         (EFI_SUBCLASS_SPECIFIC |
> 0x00000007)
> +#define EFI_CU_MEMORY_PC_INIT_BEGIN       (EFI_SUBCLASS_SPECIFIC |
> 0x00000008)
> +
> +
> +#define EFI_DC_UNSPECIFIED  0x0
> +
> +//
> +// CPU PEI
> +//
> +#define EFI_CU_HP_PC_PEI_INIT                     (EFI_SUBCLASS_SPECIFIC |
> 0x00000010)
> +#define EFI_CU_HP_PC_PEI_STEP1                    (EFI_SUBCLASS_SPECIFIC |
> 0x00000011)
> +#define EFI_CU_HP_PC_PEI_STEP2                    (EFI_SUBCLASS_SPECIFIC |
> 0x00000012)
> +#define EFI_CU_HP_PC_PEI_STEP3                    (EFI_SUBCLASS_SPECIFIC |
> 0x00000013)
> +#define EFI_CU_HP_PC_PEI_STEP4                    (EFI_SUBCLASS_SPECIFIC |
> 0x00000014)
> +#define EFI_CU_HP_PC_PEI_STEP5                    (EFI_SUBCLASS_SPECIFIC |
> 0x00000015)
> +#define EFI_CU_HP_PC_PEI_STEP6                    (EFI_SUBCLASS_SPECIFIC |
> 0x00000016)
> +#define EFI_CU_HP_PC_PEI_STEP7                    (EFI_SUBCLASS_SPECIFIC |
> 0x00000017)
> +#define EFI_CU_HP_PC_PEI_STEP8                    (EFI_SUBCLASS_SPECIFIC |
> 0x00000018)
> +#define EFI_CU_HP_PC_PEI_STEP9                    (EFI_SUBCLASS_SPECIFIC |
> 0x00000019)
> +#define EFI_CU_HP_PC_PEI_STEP10                   (EFI_SUBCLASS_SPECIFIC |
> 0x0000001A)
> +#define EFI_CU_HP_PC_PEI_STEP11                   (EFI_SUBCLASS_SPECIFIC |
> 0x0000001B)
> +#define EFI_CU_HP_PC_PEI_STEP12                   (EFI_SUBCLASS_SPECIFIC |
> 0x0000001C)
> +#define EFI_CU_HP_PC_PEI_STEP13                   (EFI_SUBCLASS_SPECIFIC |
> 0x0000001D)
> +#define EFI_CU_HP_PC_PEI_STEP14                   (EFI_SUBCLASS_SPECIFIC |
> 0x0000001E)
> +#define EFI_CU_HP_PC_PEI_END                      (EFI_SUBCLASS_SPECIFIC |
> 0x0000001F)
> +
> +//
> +// CPU DXE
> +//
> +#define EFI_CU_HP_PC_DXE_INIT                     (EFI_SUBCLASS_SPECIFIC |
> 0x00000020)
> +#define EFI_CU_HP_PC_DXE_STEP1                    (EFI_SUBCLASS_SPECIFIC |
> 0x00000021)
> +#define EFI_CU_HP_PC_DXE_STEP2                    (EFI_SUBCLASS_SPECIFIC |
> 0x00000022)
> +#define EFI_CU_HP_PC_DXE_STEP3                    (EFI_SUBCLASS_SPECIFIC |
> 0x00000023)
> +#define EFI_CU_HP_PC_DXE_STEP4                    (EFI_SUBCLASS_SPECIFIC |
> 0x00000024)
> +#define EFI_CU_HP_PC_DXE_STEP5                    (EFI_SUBCLASS_SPECIFIC |
> 0x00000025)
> +#define EFI_CU_HP_PC_DXE_STEP6                    (EFI_SUBCLASS_SPECIFIC |
> 0x00000026)
> +#define EFI_CU_HP_PC_DXE_STEP7                    (EFI_SUBCLASS_SPECIFIC |
> 0x00000027)
> +#define EFI_CU_HP_PC_DXE_STEP8                    (EFI_SUBCLASS_SPECIFIC |
> 0x00000028)
> +#define EFI_CU_HP_PC_DXE_STEP9                    (EFI_SUBCLASS_SPECIFIC |
> 0x00000029)
> +#define EFI_CU_HP_PC_DXE_STEP10                   (EFI_SUBCLASS_SPECIFIC |
> 0x0000002A)
> +#define EFI_CU_HP_PC_DXE_STEP11                   (EFI_SUBCLASS_SPECIFIC |
> 0x0000002B)
> +#define EFI_CU_HP_PC_DXE_STEP12                   (EFI_SUBCLASS_SPECIFIC |
> 0x0000002C)
> +#define EFI_CU_HP_PC_DXE_STEP13                   (EFI_SUBCLASS_SPECIFIC |
> 0x0000002D)
> +#define EFI_CU_HP_PC_DXE_STEP14                   (EFI_SUBCLASS_SPECIFIC |
> 0x0000002E)
> +#define EFI_CU_HP_PC_DXE_END                      (EFI_SUBCLASS_SPECIFIC |
> 0x0000002F)
> +
> +//
> +// CPU SMM PEI
> +//
> +#define EFI_CU_HP_PC_SMM_PEI_INIT                 (EFI_SUBCLASS_SPECIFIC |
> 0x00000030)
> +#define EFI_CU_HP_PC_SMM_PEI_STEP1                (EFI_SUBCLASS_SPECIFIC
> | 0x00000031)
> +#define EFI_CU_HP_PC_SMM_PEI_STEP2                (EFI_SUBCLASS_SPECIFIC
> | 0x00000032)
> +#define EFI_CU_HP_PC_SMM_PEI_STEP3                (EFI_SUBCLASS_SPECIFIC
> | 0x00000033)
> +#define EFI_CU_HP_PC_SMM_PEI_STEP4                (EFI_SUBCLASS_SPECIFIC
> | 0x00000034)
> +#define EFI_CU_HP_PC_SMM_PEI_STEP5                (EFI_SUBCLASS_SPECIFIC
> | 0x00000035)
> +#define EFI_CU_HP_PC_SMM_PEI_STEP6                (EFI_SUBCLASS_SPECIFIC
> | 0x00000036)
> +#define EFI_CU_HP_PC_SMM_PEI_END                  (EFI_SUBCLASS_SPECIFIC
> | 0x0000003F)
> +
> +//
> +// CPU SMM DXE
> +//
> +#define EFI_CU_HP_PC_SMM_DXE_INIT                 (EFI_SUBCLASS_SPECIFIC
> | 0x00000040)
> +#define EFI_CU_HP_PC_SMM_DXE_STEP1
> (EFI_SUBCLASS_SPECIFIC | 0x00000041)
> +#define EFI_CU_HP_PC_SMM_DXE_STEP2
> (EFI_SUBCLASS_SPECIFIC | 0x00000042)
> +#define EFI_CU_HP_PC_SMM_DXE_STEP3
> (EFI_SUBCLASS_SPECIFIC | 0x00000043)
> +#define EFI_CU_HP_PC_SMM_DXE_STEP4
> (EFI_SUBCLASS_SPECIFIC | 0x00000044)
> +#define EFI_CU_HP_PC_SMM_DXE_STEP5
> (EFI_SUBCLASS_SPECIFIC | 0x00000045)
> +#define EFI_CU_HP_PC_SMM_DXE_STEP6
> (EFI_SUBCLASS_SPECIFIC | 0x00000046)
> +#define EFI_CU_HP_PC_SMM_DXE_END                  (EFI_SUBCLASS_SPECIFIC
> | 0x0000004F)
> +
> +//
> +// PEI before memory initialization
> +//
> +#define EFI_CU_PLATFORM_PEI_INIT                     (EFI_OEM_SPECIFIC |
> 0x00000001)
> +#define EFI_CU_PLATFORM_PEI_STEP1                    (EFI_OEM_SPECIFIC |
> 0x00000002)
> +#define EFI_CU_PLATFORM_PEI_STEP2                    (EFI_OEM_SPECIFIC |
> 0x00000003)
> +#define EFI_CU_PLATFORM_PEI_STEP3                    (EFI_OEM_SPECIFIC |
> 0x00000004)
> +#define EFI_CU_PLATFORM_PEI_STEP4                    (EFI_OEM_SPECIFIC |
> 0x00000005)
> +#define EFI_CU_SMBUS_PEI_INIT                        (EFI_OEM_SPECIFIC |
> 0x00000006)
> +#define EFI_CU_SMBUS_PEI_EXEC_ENTRY                  (EFI_OEM_SPECIFIC |
> 0x00000007)
> +#define EFI_CU_SMBUS_PEI_EXEC_EXIT                   (EFI_OEM_SPECIFIC |
> 0x00000008)
> +#define EFI_CU_CLOCK_PEI_INIT_ENTRY                  (EFI_OEM_SPECIFIC |
> 0x00000009)
> +#define EFI_CU_CLOCK_PEI_INIT_EXIT                   (EFI_OEM_SPECIFIC |
> 0x0000000A)
> +#define EFI_CU_MEMORY_PC_PROG_MTRR                   (EFI_OEM_SPECIFIC |
> 0x0000000B)
> +#define EFI_CU_MEMORY_PC_PROG_MTRR_END
> (EFI_OEM_SPECIFIC | 0x0000000C)
> +#define EFI_CU_PLATFORM_PEI_STEP12                   (EFI_OEM_SPECIFIC |
> 0x0000000D)
> +#define EFI_CU_PLATFORM_PEI_STEP13                   (EFI_OEM_SPECIFIC |
> 0x0000000E)
> +#define EFI_CU_PLATFORM_PEI_END                      (EFI_OEM_SPECIFIC |
> 0x0000000F)
> +
> +#define EFI_CU_PLATFORM_DXE_INIT                     (EFI_OEM_SPECIFIC |
> 0x00000011)
> +#define EFI_CU_PLATFORM_DXE_STEP1                    (EFI_OEM_SPECIFIC |
> 0x00000012)
> +#define EFI_CU_PLATFORM_DXE_STEP2                    (EFI_OEM_SPECIFIC |
> 0x00000013)
> +#define EFI_CU_PLATFORM_DXE_STEP3                    (EFI_OEM_SPECIFIC |
> 0x00000014)
> +#define EFI_CU_PLATFORM_DXE_STEP4                    (EFI_OEM_SPECIFIC |
> 0x00000015)
> +#define EFI_CU_PLATFORM_DXE_INIT_DONE                (EFI_OEM_SPECIFIC |
> 0x00000016)
> +
> +#define EFI_CU_OVERCLOCK_PEI_INIT_ENTRY              (EFI_OEM_SPECIFIC |
> 0x00000017)
> +#define EFI_CU_OVERCLOCK_PEI_INIT_EXIT               (EFI_OEM_SPECIFIC |
> 0x00000018)
> +
> +//
> +// BDS
> +//
> +#define EFI_CU_BDS_INIT                              (EFI_OEM_SPECIFIC | 0x00000060)
> +#define EFI_CU_BDS_STEP1                             (EFI_OEM_SPECIFIC |
> 0x00000061)
> +#define EFI_CU_BDS_STEP2                             (EFI_OEM_SPECIFIC |
> 0x00000062)
> +#define EFI_CU_BDS_STEP3                             (EFI_OEM_SPECIFIC |
> 0x00000063)
> +#define EFI_CU_BDS_STEP4                             (EFI_OEM_SPECIFIC |
> 0x00000064)
> +#define EFI_CU_BDS_STEP5                             (EFI_OEM_SPECIFIC |
> 0x00000065)
> +#define EFI_CU_BDS_STEP6                             (EFI_OEM_SPECIFIC |
> 0x00000066)
> +#define EFI_CU_BDS_STEP7                             (EFI_OEM_SPECIFIC |
> 0x00000067)
> +#define EFI_CU_BDS_STEP8                             (EFI_OEM_SPECIFIC |
> 0x00000068)
> +#define EFI_CU_BDS_STEP9                             (EFI_OEM_SPECIFIC |
> 0x00000069)
> +#define EFI_CU_BDS_STEP10                            (EFI_OEM_SPECIFIC |
> 0x0000006A)
> +#define EFI_CU_BDS_STEP11                            (EFI_OEM_SPECIFIC |
> 0x0000006B)
> +#define EFI_CU_BDS_STEP12                            (EFI_OEM_SPECIFIC |
> 0x0000006C)
> +#define EFI_CU_BDS_STEP13                            (EFI_OEM_SPECIFIC |
> 0x0000006D)
> +#define EFI_CU_BDS_STEP14                            (EFI_OEM_SPECIFIC |
> 0x0000006E)
> +#define EFI_CU_BDS_END                               (EFI_OEM_SPECIFIC | 0x0000006F)
> +
> +
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.c
> b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.c
> new file mode 100644
> index 0000000000..8283483ff8
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.c
> @@ -0,0 +1,132 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +  MonoStatusCode.c
> +
> +Abstract:
> +
> +  PEIM to provide the status code functionality, to aid in system debug.
> +  It includes output to 0x80 port and/or to serial port.
> +  This PEIM is monolithic. Different platform should provide different library.
> +
> +--*/
> +
> +#include "MonoStatusCode.h"
> +#include "PlatformStatusCode.h"
> +#define CMOS_EFI_DEBUG              0x14
> +
> +//
> +// Module globals
> +//
> +EFI_PEI_PROGRESS_CODE_PPI     mStatusCodePpi =
> { PlatformReportStatusCode };
> +
> +EFI_PEI_PPI_DESCRIPTOR  mPpiListStatusCode = {
> +  (EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> +  &gEfiPeiStatusCodePpiGuid,
> +  &mStatusCodePpi
> +};
> +
> +//
> +// Function implemenations
> +//
> +
> +/**
> +  Translate from a DXE status code interface into a PEI-callable
> +  interface, making the PEI the least common denominator..
> +
> +  Same as DXE ReportStatusCode RT service
> +
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TranslateDxeStatusCodeToPeiStatusCode (
> +  IN EFI_STATUS_CODE_TYPE     CodeType,
> +  IN EFI_STATUS_CODE_VALUE    Value,
> +  IN UINT32                   Instance,
> +  IN EFI_GUID                 * CallerId,
> +  IN EFI_STATUS_CODE_DATA     * Data OPTIONAL
> +  )
> +{
> +  return PlatformReportStatusCode (NULL, CodeType, Value, Instance,
> CallerId, Data);
> +}
> +
> +/**
> +  Build a hob describing the status code listener that has been installed.
> +  This will be used by DXE code until a runtime status code listener is
> +  installed.
> +
> +  @param PeiServices      General purpose services available to every PEIM.
> +
> +  @retval Status          EFI_SUCCESS if the interface could be successfully
> +                          installed
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitializeDxeReportStatusCode (
> +  IN const EFI_PEI_SERVICES       **PeiServices
> +  )
> +{
> +  EFI_STATUS  Status = EFI_UNSUPPORTED;
> +
> +  VOID        *Instance;
> +
> +  VOID        *Result;
> +
> +  Instance = (VOID *) (UINTN) TranslateDxeStatusCodeToPeiStatusCode;
> +
> +  Result = BuildGuidDataHob (
> +             &gEfiStatusCodeRuntimeProtocolGuid,
> +             &Instance,
> +             sizeof (VOID *)
> +             );
> +  if (Result != NULL) {
> +    Status = EFI_SUCCESS;
> +  }
> +  return Status;
> +}
> +
> +/**
> +  Initialize the platform status codes and publish the platform status code
> +  PPI.
> +
> +  @param  FfsHeader      FV this PEIM was loaded from.
> +  @param  PeiServices    General purpose services available to every PEIM.
> +
> +  @retval Status         EFI_SUCCESS
> +
> +**/
> +VOID
> +EFIAPI
> +InitializeMonoStatusCode (
> +  IN EFI_FFS_FILE_HEADER       *FfsHeader,
> +  IN CONST EFI_PEI_SERVICES          **PeiServices
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  //
> +  // Initialize status code listeners.
> +  //
> +  PlatformInitializeStatusCode (FfsHeader, PeiServices);
> +
> +  //
> +  // Publish the status code capability to other modules
> +  //
> +  Status = (*PeiServices)->InstallPpi (PeiServices, &mPpiListStatusCode);
> +
> +  ASSERT_EFI_ERROR (Status);
> +
> +  DEBUG ((DEBUG_ERROR, "\nMono Status Code PEIM Loaded\n"));
> +
> +  return ;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.h
> b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.h
> new file mode 100644
> index 0000000000..0b256093a6
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.h
> @@ -0,0 +1,128 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  MonoStatusCode.h
> +
> +Abstract:
> +
> +  Monolithic single PEIM to provide the status code functionality.
> +  The PEIM is a blend of libraries that correspond to the different status
> code
> +  listeners that a platform installs.
> +
> +--*/
> +
> +#ifndef _MONO_STATUS_CODE_H_
> +#define _MONO_STATUS_CODE_H_
> +
> +//
> +// Statements that include other files.
> +//
> +#include "PiPei.h"
> +
> +#include "Pi/PiBootMode.h"
> +
> +#include "Ppi/StatusCode.h"
> +#include "Ppi/MemoryDiscovered.h"
> +#include "Ppi/FvLoadFile.h"
> +
> +#include "Library/HobLib.h"
> +#include "Library/DebugLib.h"
> +#include "Library/IoLib.h"
> +#include "Library/SerialPortLib.h"
> +#include "Protocol/StatusCode.h"
> +
> +
> +#ifndef _STATUS_CODE_ENABLER_H_
> +#define _STATUS_CODE_ENABLER_H_
> +
> +#ifdef EFI_DEBUG
> +
> +#define EFI_STATUS_CODE_ENABLER_HOB_GUID \
> +  { \
> +    0x5ffc6cf3, 0x71ad, 0x46f5, 0xbd, 0x8b, 0x7e, 0x8f, 0xfe, 0x19, 0x7, 0xd7 \
> +  }
> +
> +extern EFI_GUID gEfiSerialStatusCodeEnablerHobGuid;
> +
> +typedef struct _EFI_STATUS_CODE_INFO {
> +  BOOLEAN    StatusCodeDisable;
> +} EFI_STATUS_CODE_INFO;
> +
> +#endif
> +#endif
> +
> +
> +
> +//
> +// Platform specific function Declarations.  These must be implemented in a
> +// subdirectory named PlatformName in a file named PlatformStatusCode.c.
> +//
> +
> +//
> +// This is the platform function to initialize the listeners desired by the
> +// platform.
> +//
> +VOID
> +PlatformInitializeStatusCode (
> +  IN EFI_FFS_FILE_HEADER       *FfsHeader,
> +  IN CONST EFI_PEI_SERVICES          **PeiServices
> +  );
> +
> +//
> +// This is the platform function that calls all of the listeners desired by the
> +// platform.
> +//
> +EFI_STATUS
> +EFIAPI
> +PlatformReportStatusCode (
> +  IN CONST EFI_PEI_SERVICES       **PeiServices,
> +  IN EFI_STATUS_CODE_TYPE         CodeType,
> +  IN EFI_STATUS_CODE_VALUE        Value,
> +  IN UINT32                       Instance,
> +  IN CONST EFI_GUID               * CallerId,
> +  IN CONST EFI_STATUS_CODE_DATA   * Data OPTIONAL
> +  );
> +
> +//
> +// Platform independent function Declarations
> +//
> +//
> +// Initialize the status code listeners and publish the status code PPI.
> +//
> +VOID
> +EFIAPI
> +InitializeMonoStatusCode (
> +  IN EFI_FFS_FILE_HEADER       *FfsHeader,
> +  IN const EFI_PEI_SERVICES    **PeiServices
> +  );
> +
> +//
> +// Convert a DXE status code call into a PEI status code call.
> +//
> +EFI_STATUS
> +EFIAPI
> +TranslateDxeStatusCodeToPeiStatusCode (
> +  IN EFI_STATUS_CODE_TYPE     CodeType,
> +  IN EFI_STATUS_CODE_VALUE    Value,
> +  IN UINT32                   Instance,
> +  IN EFI_GUID                 * CallerId,
> +  IN EFI_STATUS_CODE_DATA     * Data OPTIONAL
> +  );
> +
> +//
> +// Publish a HOB that contains the listener to be used by DXE.
> +//
> +EFI_STATUS
> +EFIAPI
> +InitializeDxeReportStatusCode (
> +  IN const EFI_PEI_SERVICES       **PeiServices
> +  );
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.inf
> new file mode 100644
> index 0000000000..f1be5b8d6c
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.inf
> @@ -0,0 +1,72 @@
> +#
> +#
> +# Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +#  Module Name:
> +#
> +#    MonoStatusCode.inf
> +#
> +#  Abstract:
> +#
> +#    Component description file for Status Code PEI module
> +#
> +#--*/
> +
> +[defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = MonoStatusCode
> +  FILE_GUID                      = 4BB346D2-8076-4671-8BC9-7B95CBB9A6DF
> +  MODULE_TYPE                    = PEIM
> +  VERSION_STRING                 = 1.0
> +#  ENTRY_POINT                    = InstallMonoStatusCode
> +  LIBRARY_CLASS                  = MonoStatusCodeLib
> +
> +[sources.common]
> +  MonoStatusCode.c
> +  MonoStatusCode.h
> +  PlatformStatusCode.c
> +  PlatformStatusCode.h
> +  PeiPostCode.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Vlv2SocBinPkg/Vlv2SocBinPkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +  IntelFrameworkPkg/IntelFrameworkPkg.dec
> +
> +[LibraryClasses]
> +  PeimEntryPoint
> +  HobLib
> +  DebugLib
> +  SerialPortLib
> +  ReportStatusCodeLib
> +  PrintLib
> +  BaseMemoryLib
> +  PchPlatformLib
> +
> +[Ppis]
> +  gEfiPeiMemoryDiscoveredPpiGuid
> +  gEfiPeiStatusCodePpiGuid
> +  gEfiPeiFvFileLoaderPpiGuid
> +
> +[Protocols]
> +  gEfiStatusCodeRuntimeProtocolGuid
> +
> +[Pcd]
> +  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseRam
> +
> +[Guids]
> +  gEfiPlatformCpuInfoGuid
> +  gEfiHtBistHobGuid
> +  gEfiStatusCodeDataTypeStringGuid              ## CONSUMES
> +
> +[Depex]
> +  TRUE
> +
> +
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PeiPostCode.c
> b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PeiPostCode.c
> new file mode 100644
> index 0000000000..92dbef551e
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PeiPostCode.c
> @@ -0,0 +1,121 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +  PeiPostCode.c
> +
> +Abstract:
> +
> +  Worker functions for PostCode
> +
> +--*/
> +
> +#include "EfiStatusCode.h"
> +
> +#pragma pack(1)
> +typedef struct {
> +  EFI_STATUS_CODE_VALUE   StatusValue;
> +  UINT8                   Port80Value;
> +} EFI_STATUS_CODE_TO_PORT_80;
> +#pragma pack()
> +
> +//
> +// see Edk\Foundation\Library\EfiCommonLib\PostCode.c for DXE/BDS
> POST codes.
> +//
> +EFI_STATUS_CODE_TO_PORT_80  mPeiPort80Table[] = {
> +  //
> +  // Platform init
> +  //
> +  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_PLATFORM_PEI_INIT,
> 0x11},
> +  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_PLATFORM_PEI_STEP1,
> 0x12},
> +  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_PLATFORM_PEI_STEP2,
> 0x13},
> +  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_PLATFORM_PEI_STEP3,
> 0x14},
> +  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_PLATFORM_PEI_STEP4,
> 0x15},
> +
> +  //
> +  // SMBUS
> +  //
> +  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_SMBUS_PEI_INIT,             0x16},
> +  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_SMBUS_PEI_EXEC_ENTRY,
> 0x17},
> +  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_SMBUS_PEI_EXEC_EXIT,
> 0x18},
> +
> +  //
> +  // Clock
> +  //
> +  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_CLOCK_PEI_INIT_ENTRY,
> 0x19},
> +  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_CLOCK_PEI_INIT_EXIT,
> 0x1A},
> +
> +  //
> +  // Over clocking support
> +  //
> +  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_OVERCLOCK_PEI_INIT_ENTRY,
> 0x1B},
> +  {EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_OVERCLOCK_PEI_INIT_EXIT,
> 0x1C},
> +
> +  //
> +  // MRC
> +  //
> +  {EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_INIT_BEGIN,
> 0x21},
> +  {EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_SPD_READ,
> 0x23},
> +  {EFI_COMPUTING_UNIT_MEMORY |
> EFI_CU_MEMORY_PC_PRESENCE_DETECT,   0x24},
> +  {EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_TIMING,
> 0x25},
> +  {EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_OPTIMIZING,
> 0x26},
> +  {EFI_COMPUTING_UNIT_MEMORY |
> EFI_CU_MEMORY_PC_CONFIGURING,       0x27},
> +  {EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_TEST,
> 0x28},
> +  {EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_COMPLETE,
> 0x29},
> +
> +  //
> +  // Platform Init after MRC
> +  //
> +  {EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_PROG_MTRR,
> 0x2A},
> +  {EFI_COMPUTING_UNIT_MEMORY |
> EFI_CU_MEMORY_PC_PROG_MTRR_END,     0x2B},
> +
> +  {EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEIM_PC_RECOVERY_BEGIN,
> 0x31},
> +  {EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEIM_PC_RECOVERY_AUTO,
> 0x32},
> +  {EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEIM_PC_CAPSULE_LOAD,
> 0x33},
> +  {EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEIM_PC_CAPSULE_START,
> 0x34},
> +  {EFI_SOFTWARE_PEI_MODULE |
> EFI_SW_PEIM_EC_NO_RECOVERY_CAPSULE,   0x35},
> +
> +  {EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_PEI_INIT,
> 0x41},
> +  {EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_PEI_STEP1,
> 0x42},
> +  {EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_PEI_END,
> 0x43},
> +  {EFI_COMPUTING_UNIT_HOST_PROCESSOR |
> EFI_CU_HP_PC_SMM_PEI_INIT,  0x44},
> +  {EFI_COMPUTING_UNIT_HOST_PROCESSOR |
> EFI_CU_HP_PC_SMM_PEI_STEP1, 0x45},
> +  {EFI_COMPUTING_UNIT_HOST_PROCESSOR |
> EFI_CU_HP_PC_SMM_PEI_END,   0x46}
> +};
> +
> +BOOLEAN
> +PeiCodeTypeToPostCode (
> +  IN  EFI_STATUS_CODE_TYPE    CodeType,
> +  IN  EFI_STATUS_CODE_VALUE   Value,
> +  OUT UINT8                   *PostCode
> +  )
> +{
> +  UINTN             Index;
> +
> +  if (CodeType == EFI_PROGRESS_CODE) {
> +    if ((Value == (EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_BEGIN)) ||
> +        (Value == (EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_END)) ||
> +        (Value == (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_BEGIN)) ||
> +        (Value == (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_END))) {
> +      return FALSE;
> +    }
> +  } else {
> +    return FALSE;
> +  }
> +
> +  for (Index = 0; Index <
> sizeof(mPeiPort80Table)/sizeof(EFI_STATUS_CODE_TO_PORT_80); Index++)
> {
> +    if (mPeiPort80Table[Index].StatusValue == Value) {
> +      *PostCode = mPeiPort80Table[Index].Port80Value;
> +      return TRUE;
> +    }
> +  }
> +
> +  return FALSE;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.c
> b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.
> c
> new file mode 100644
> index 0000000000..a1abddc512
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.
> c
> @@ -0,0 +1,381 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +  PlatformStatusCode.c
> +
> +Abstract:
> +
> +  Contains Platform specific implementations required to use status codes.
> +
> +--*/
> +
> +#include "PlatformStatusCode.h"
> +#include <PchRegs.h>
> +#include <PlatformBaseAddresses.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PcdLib.h>
> +
> +typedef struct {
> +  EFI_STATUS_CODE_DATA  DataHeader;
> +  EFI_HANDLE            Handle;
> +} PEIM_FILE_HANDLE_EXTENDED_DATA;
> +
> +#define CONFIG_PORT0    0x4E
> +#define PCI_IDX         0xCF8
> +#define PCI_DAT         0xCFC
> +
> +#define PCI_LPC_BASE    (0x8000F800)
> +#define PCI_LPC_REG(x)  (PCI_LPC_BASE + (x))
> +
> +//
> +// Function implementations
> +//
> +BOOLEAN
> +PeiCodeTypeToPostCode (
> +  IN  EFI_STATUS_CODE_TYPE    CodeType,
> +  IN  EFI_STATUS_CODE_VALUE   Value,
> +  OUT UINT8                   *PostCode
> +  );
> +
> +/**
> +  Provide a port 80 status code
> +
> +  @param Same as ReportStatusCode PPI
> +
> +  @retval EFI_SUCCESS   Always returns success.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Port80ReportStatusCode (
> +  IN CONST EFI_PEI_SERVICES         **PeiServices,
> +  IN EFI_STATUS_CODE_TYPE           CodeType,
> +  IN EFI_STATUS_CODE_VALUE          Value,
> +  IN UINT32                         Instance,
> +  IN CONST EFI_GUID                 *CallerId,
> +  IN CONST EFI_STATUS_CODE_DATA     *Data OPTIONAL
> +  )
> +
> +{
> +  EFI_STATUS               Status;
> +  EFI_FV_FILE_INFO         FvFileInfo;
> +  UINT16                   Port80Code = 0;
> +
> +  //
> +  // Progress or error code, Output Port 80h card.
> +  //
> +  if (!PeiCodeTypeToPostCode (CodeType, Value, (UINT8 *)&Port80Code)) {
> +    if ((Data != NULL) && (Value ==(EFI_SOFTWARE_PEI_CORE |
> EFI_SW_PC_INIT_BEGIN))){
> +      Status = PeiServicesFfsGetFileInfo (
> +                 ((PEIM_FILE_HANDLE_EXTENDED_DATA *) (Data + 1))->Handle,
> +                 &FvFileInfo
> +                 );
> +      if (!EFI_ERROR (Status)) {
> +        Port80Code = (FvFileInfo.FileName.Data4[6]<<8) +
> (FvFileInfo.FileName.Data4[7]);
> +      }
> +    }
> +  }
> +  if (Port80Code != 0){
> +    IoWrite16 (0x80, (UINT16) Port80Code);
> +    DEBUG ((EFI_D_ERROR, "POSTCODE=<%04x>\n", Port80Code));
> +  }
> +  return  EFI_SUCCESS;
> +}
> +
> +/**
> +  Provide a serial status code
> +
> +  @param Same as ReportStatusCode PPI
> +
> +  @retval EFI_SUCCESS   Always returns success.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SerialReportStatusCode (
> +  IN CONST EFI_PEI_SERVICES         **PeiServices,
> +  IN EFI_STATUS_CODE_TYPE           CodeType,
> +  IN EFI_STATUS_CODE_VALUE          Value,
> +  IN UINT32                         Instance,
> +  IN CONST EFI_GUID                 * CallerId,
> +  IN CONST EFI_STATUS_CODE_DATA     * Data OPTIONAL
> +  )
> +{
> +  CHAR8           *Filename;
> +  CHAR8           *Description;
> +  CHAR8           *Format;
> +  CHAR8           Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];
> +  UINT32          ErrorLevel;
> +  UINT32          LineNumber;
> +  UINTN           CharCount;
> +  BASE_LIST       Marker;
> +
> +  Buffer[0] = '\0';
> +
> +  if (Data != NULL &&
> +      ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename,
> &Description, &LineNumber)) {
> +    //
> +    // Print ASSERT() information into output buffer.
> +    //
> +    CharCount = AsciiSPrint (
> +                  Buffer,
> +                  sizeof (Buffer),
> +                  "\n\rPEI_ASSERT!: %a (%d): %a\n\r",
> +                  Filename,
> +                  LineNumber,
> +                  Description
> +                  );
> +  } else if (Data != NULL &&
> +             ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker,
> &Format)) {
> +    //
> +    // Print DEBUG() information into output buffer.
> +    //
> +    CharCount = AsciiBSPrint (
> +                  Buffer,
> +                  sizeof (Buffer),
> +                  Format,
> +                  Marker
> +                  );
> +  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) ==
> EFI_ERROR_CODE) {
> +    //
> +    // Print ERROR information into output buffer.
> +    //
> +    CharCount = AsciiSPrint (
> +                  Buffer,
> +                  sizeof (Buffer),
> +                  "ERROR: C%x:V%x I%x",
> +                  CodeType,
> +                  Value,
> +                  Instance
> +                  );
> +
> +    ASSERT(CharCount > 0);
> +
> +    if (CallerId != NULL) {
> +      CharCount += AsciiSPrint (
> +                     &Buffer[CharCount],
> +                     (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
> +                     " %g",
> +                     CallerId
> +                     );
> +    }
> +
> +    if (Data != NULL) {
> +      CharCount += AsciiSPrint (
> +                     &Buffer[CharCount],
> +                     (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
> +                     " %x",
> +                     Data
> +                     );
> +    }
> +
> +    CharCount += AsciiSPrint (
> +                   &Buffer[CharCount],
> +                   (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
> +                   "\n\r"
> +                   );
> +  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) ==
> EFI_PROGRESS_CODE) {
> +    //
> +    // Print PROGRESS information into output buffer.
> +    //
> +    CharCount = AsciiSPrint (
> +                  Buffer,
> +                  sizeof (Buffer),
> +                  "PROGRESS CODE: V%x I%x\n\r",
> +                  Value,
> +                  Instance
> +                  );
> +  } else if (Data != NULL &&
> +             CompareGuid (&Data->Type, &gEfiStatusCodeDataTypeStringGuid)
> &&
> +             ((EFI_STATUS_CODE_STRING_DATA *) Data)->StringType ==
> EfiStringAscii) {
> +    //
> +    // EFI_STATUS_CODE_STRING_DATA
> +    //
> +    CharCount = AsciiSPrint (
> +                  Buffer,
> +                  sizeof (Buffer),
> +                  "%a\n\r",
> +                  ((EFI_STATUS_CODE_STRING_DATA *) Data)->String.Ascii
> +                  );
> +  } else {
> +    //
> +    // Code type is not defined.
> +    //
> +    CharCount = AsciiSPrint (
> +                  Buffer,
> +                  sizeof (Buffer),
> +                  "Undefined: C%x:V%x I%x\n\r",
> +                  CodeType,
> +                  Value,
> +                  Instance
> +                  );
> +  }
> +
> +  //
> +  // Call SerialPort Lib function to do print.
> +  //
> +  SerialPortWrite ((UINT8 *) Buffer, CharCount);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +  Call all status code listeners in the MonoStatusCode.
> +
> +  @param PeiServices    The PEI core services table.
> +  @param CodeType       Type of Status Code.
> +  @param Value          Value to output for Status Code.
> +  @param Instance       Instance Number of this status code.
> +  @param CallerId       ID of the caller of this status code.
> +  @param Data           Optional data associated with this status code.
> +
> +  @retval EFI_SUCCESS              If status code is successfully reported.
> +  @retval EFI_NOT_AVAILABLE_YET    If StatusCodePpi has not been
> installed.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +PlatformReportStatusCode (
> +  IN  CONST EFI_PEI_SERVICES        **PeiServices,
> +  IN EFI_STATUS_CODE_TYPE           CodeType,
> +  IN EFI_STATUS_CODE_VALUE          Value,
> +  IN UINT32                         Instance,
> +  IN CONST EFI_GUID                 * CallerId,
> +  IN CONST EFI_STATUS_CODE_DATA     * Data OPTIONAL
> +  )
> +{
> +  //
> +  // If we are in debug mode, we will allow serial status codes
> +  //
> +  SerialReportStatusCode (PeiServices, CodeType, Value, Instance, CallerId,
> Data);
> +
> +  Port80ReportStatusCode (PeiServices, CodeType, Value, Instance, CallerId,
> Data);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Install the PEIM.  Initialize listeners, publish the PPI and HOB for PEI and
> +  DXE use respectively.
> +
> +  @param FfsHeader      FV this PEIM was loaded from.
> +  @param PeiServices    General purpose services available to every PEIM.
> +
> +  @retval EFI_SUCCESS   The function always returns success.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +InstallMonoStatusCode (
> +  IN EFI_FFS_FILE_HEADER       *FfsHeader,
> +  IN CONST EFI_PEI_SERVICES    **PeiServices
> +  )
> +{
> +
> +  //
> +  // Initialize all listeners
> +  //
> +  InitializeMonoStatusCode (FfsHeader, PeiServices);
> +
> +  //
> +  // Publish the listener in a HOB for DXE use.
> +  //
> +  InitializeDxeReportStatusCode (PeiServices);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +#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 PciD31F0RegBase                           PCIEX_BASE_ADDRESS + (UINT32)
> (31 << 15)
> +#define SB_RCBA                                   0xfed1c000
> +
> +extern PCH_STEPPING EFIAPI PchStepping (VOID);
> +
> +VOID
> +RamDebugInit (
> +  VOID
> +  );
> +
> +/**
> +  Enable legacy decoding on ICH6
> +
> +  @param none
> +
> +  @retval EFI_SUCCESS     Always returns success.
> +
> +**/
> +EFI_STATUS
> +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);
> +
> +  return  EFI_SUCCESS;
> +}
> +
> +/**
> +  INIT the SIO. Ported this code and I don't undertand the comments either.
> +
> +  @param FfsHeader    FV this PEIM was loaded from.
> +  @param PeiServices  General purpose services available to every PEIM.
> +
> +  None
> +
> +**/
> +VOID
> +EFIAPI
> +PlatformInitializeStatusCode (
> +  IN EFI_FFS_FILE_HEADER       *FfsHeader,
> +  IN CONST EFI_PEI_SERVICES    **PeiServices
> +  )
> +{
> +
> +  //
> +  // Enable internal COM1 on South Cluster.
> +  //
> +	EnableInternalUart();
> +
> +
> +  //
> +  // Initialize additional debug status code listeners.
> +  //
> +   SerialPortInitialize();
> +
> +}
> +//#endif //EFI_DEBUG
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.
> h
> b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.
> h
> new file mode 100644
> index 0000000000..42b7c9a2c8
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.
> h
> @@ -0,0 +1,138 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +Module Name:
> +
> +  PlatformStatusCode.h
> +
> +Abstract:
> +
> +  Contains Platform specific implementations required to use status codes.
> +
> +--*/
> +
> +#ifndef _PLATFORM_STATUS_CODE_H_
> +#define _PLATFORM_STATUS_CODE_H_
> +
> +
> +#define CONFIG_PORT0    0x4E
> +#define INDEX_PORT0     0x4E
> +#define DATA_PORT0      0x4F
> +#define PCI_IDX        0xCF8
> +#define PCI_DAT        0xCFC
> +
> +#include "MonoStatusCode.h"
> +#ifndef _PEI_PORT_80_STATUS_CODE_H_
> +#define _PEI_PORT_80_STATUS_CODE_H_
> +
> +
> +
> +//
> +// Status code reporting function
> +//
> +EFI_STATUS
> +Port80ReportStatusCode (
> +  IN CONST EFI_PEI_SERVICES         **PeiServices,
> +  IN EFI_STATUS_CODE_TYPE           CodeType,
> +  IN EFI_STATUS_CODE_VALUE          Value,
> +  IN UINT32                         Instance,
> +  IN CONST EFI_GUID                 * CallerId,
> +  IN CONST EFI_STATUS_CODE_DATA     * Data OPTIONAL
> +  );
> +
> +#endif
> +
> +#ifndef _PEI_SERIAL_STATUS_CODE_LIB_H_
> +#define _PEI_SERIAL_STATUS_CODE_LIB_H_
> +
> +
> +#include <Guid/StatusCodeDataTypeId.h>
> +#include <Guid/StatusCodeDataTypeDebug.h>
> +#include <Library/ReportStatusCodeLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/BaseMemoryLib.h>
> +
> +//
> +// Initialization function
> +//
> +VOID
> +SerialInitializeStatusCode (
> +  VOID
> +  );
> +
> +//
> +// Status code reporting function
> +//
> +EFI_STATUS
> +SerialReportStatusCode (
> +  IN CONST EFI_PEI_SERVICES         **PeiServices,
> +  IN EFI_STATUS_CODE_TYPE     CodeType,
> +  IN EFI_STATUS_CODE_VALUE    Value,
> +  IN UINT32                   Instance,
> +  IN CONST EFI_GUID                 * CallerId,
> +  IN CONST EFI_STATUS_CODE_DATA     * Data OPTIONAL
> +  );
> +
> +#endif
> +
> +extern EFI_PEI_PROGRESS_CODE_PPI    mStatusCodePpi;
> +extern EFI_PEI_PPI_DESCRIPTOR mPpiListStatusCode;
> +#define EFI_SIGNATURE_16(A, B)        ((A) | (B << 8))
> +#define EFI_SIGNATURE_32(A, B, C, D)  (EFI_SIGNATURE_16 (A, B) |
> (EFI_SIGNATURE_16 (C, D) << 16))
> +#define STATUSCODE_PEIM_SIGNATURE EFI_SIGNATURE_32 ('p', 's', 't', 'c')
> +
> +typedef struct {
> +  UINT32                    Signature;
> +  EFI_FFS_FILE_HEADER       *FfsHeader;
> +  EFI_PEI_NOTIFY_DESCRIPTOR StatusCodeNotify;
> +} STATUSCODE_CALLBACK_STATE_INFORMATION;
> +
> +#pragma pack(1)
> +typedef struct {
> +  UINT16  Limit;
> +  UINT32  Base;
> +} GDT_DSCRIPTOR;
> +#pragma pack()
> +
> +#define STATUSCODE_PEIM_FROM_THIS(a) \
> +  BASE_CR ( \
> +  a, \
> +  STATUSCODE_CALLBACK_STATE_INFORMATION, \
> +  StatusCodeNotify \
> +  )
> +
> +VOID
> +EFIAPI
> +PlatformInitializeStatusCode (
> +  IN EFI_FFS_FILE_HEADER       *FfsHeader,
> +  IN CONST EFI_PEI_SERVICES    **PeiServices
> +  );
> +
> +
> +//
> +// Function declarations
> +//
> +/**
> +  Install Firmware Volume Hob's once there is main memory
> +
> +  @param PeiServices        General purpose services available to every PEIM.
> +  @param NotifyDescriptor   Not Used
> +  @param Ppi                Not Used
> +
> +  @retval Status            EFI_SUCCESS if the interface could be successfully
> +                            installed
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +MemoryDiscoveredPpiNotifyCallback (
> +  IN EFI_PEI_SERVICES           **PeiServices,
> +  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
> +  IN VOID                       *Ppi
> +  );
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/BdsBoot.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/BdsBoot.c
> new file mode 100644
> index 0000000000..3034853695
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/BdsBoot.c
> @@ -0,0 +1,4490 @@
> +/** @file
> +  BDS Lib functions which relate with create or process the boot option.
> +
> +Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "InternalBdsLib.h"
> +#include "String.h"
> +#include <Library/NetLib.h>
> +#include "Library/DebugLib.h"
> +
> +BOOLEAN mEnumBootDevice = FALSE;
> +EFI_HII_HANDLE gBdsLibStringPackHandle = NULL;
> +
> +/**
> +
> +  End Perf entry of BDS
> +
> +  @param  Event                 The triggered event.
> +  @param  Context               Context for this event.
> +
> +**/
> +VOID
> +EFIAPI
> +BmEndOfBdsPerfCode (
> +  IN EFI_EVENT  Event,
> +  IN VOID       *Context
> +  )
> +{
> +  //
> +  // Record the performance data for End of BDS
> +  //
> +  PERF_END(NULL, "BDS", NULL, 0);
> +
> +  return ;
> +}
> +
> +/**
> +  The constructor function register UNI strings into imageHandle.
> +
> +  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
> +
> +  @param  ImageHandle   The firmware allocated handle for the EFI image.
> +  @param  SystemTable   A pointer to the EFI System Table.
> +
> +  @retval EFI_SUCCESS   The constructor successfully added string package.
> +  @retval Other value   The constructor can't add string package.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GenericBdsLibConstructor (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +
> +  gBdsLibStringPackHandle = HiiAddPackages (
> +                              &gBdsLibStringPackageGuid,
> +                              ImageHandle,
> +                              GenericBdsLibStrings,
> +                              NULL
> +                              );
> +
> +  ASSERT (gBdsLibStringPackHandle != NULL);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Deletete the Boot Option from EFI Variable. The Boot Order Arrray
> +  is also updated.
> +
> +  @param OptionNumber    The number of Boot option want to be deleted.
> +  @param BootOrder       The Boot Order array.
> +  @param BootOrderSize   The size of the Boot Order Array.
> +
> +  @retval  EFI_SUCCESS           The Boot Option Variable was found and
> removed
> +  @retval  EFI_UNSUPPORTED       The Boot Option Variable store was
> inaccessible
> +  @retval  EFI_NOT_FOUND         The Boot Option Variable was not found
> +**/
> +EFI_STATUS
> +EFIAPI
> +BdsDeleteBootOption (
> +  IN UINTN                       OptionNumber,
> +  IN OUT UINT16                  *BootOrder,
> +  IN OUT UINTN                   *BootOrderSize
> +  )
> +{
> +  CHAR16      BootOption[9];
> +  UINTN       Index;
> +  EFI_STATUS  Status;
> +
> +  UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x",
> OptionNumber);
> +  Status = gRT->SetVariable (
> +                  BootOption,
> +                  &gEfiGlobalVariableGuid,
> +                  0,
> +                  0,
> +                  NULL
> +                  );
> +  //
> +  // Deleting variable with existing variable implementation shouldn't fail.
> +  //
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // adjust boot order array
> +  //
> +  for (Index = 0; Index < *BootOrderSize / sizeof (UINT16); Index++) {
> +    if (BootOrder[Index] == OptionNumber) {
> +      CopyMem (&BootOrder[Index], &BootOrder[Index+1], *BootOrderSize
> - (Index+1) * sizeof (UINT16));
> +      *BootOrderSize -= sizeof (UINT16);
> +      break;
> +    }
> +  }
> +
> +  return Status;
> +}
> +/**
> +
> +  Translate the first n characters of an Ascii string to
> +  Unicode characters. The count n is indicated by parameter
> +  Size. If Size is greater than the length of string, then
> +  the entire string is translated.
> +
> +
> +  @param AStr               Pointer to input Ascii string.
> +  @param Size               The number of characters to translate.
> +  @param UStr               Pointer to output Unicode string buffer.
> +
> +**/
> +VOID
> +AsciiToUnicodeSize (
> +  IN UINT8              *AStr,
> +  IN UINTN              Size,
> +  OUT UINT16            *UStr
> +  )
> +{
> +  UINTN Idx;
> +
> +  Idx = 0;
> +  while (AStr[Idx] != 0) {
> +    UStr[Idx] = (CHAR16) AStr[Idx];
> +    if (Idx == Size) {
> +      break;
> +    }
> +
> +    Idx++;
> +  }
> +  UStr[Idx] = 0;
> +}
> +
> +/**
> +  Build Legacy Device Name String according.
> +
> +  @param CurBBSEntry     BBS Table.
> +  @param Index           Index.
> +  @param BufSize         The buffer size.
> +  @param BootString      The output string.
> +
> +**/
> +VOID
> +BdsBuildLegacyDevNameString (
> +  IN  BBS_TABLE                 *CurBBSEntry,
> +  IN  UINTN                     Index,
> +  IN  UINTN                     BufSize,
> +  OUT CHAR16                    *BootString
> +  )
> +{
> +  CHAR16  *Fmt;
> +  CHAR16  *Type;
> +  UINT8   *StringDesc;
> +  CHAR16  Temp[80];
> +
> +  switch (Index) {
> +  //
> +  // Primary Master
> +  //
> +  case 1:
> +    Fmt = L"Primary Master %s";
> +    break;
> +
> + //
> + // Primary Slave
> + //
> +  case 2:
> +    Fmt = L"Primary Slave %s";
> +    break;
> +
> +  //
> +  // Secondary Master
> +  //
> +  case 3:
> +    Fmt = L"Secondary Master %s";
> +    break;
> +
> +  //
> +  // Secondary Slave
> +  //
> +  case 4:
> +    Fmt = L"Secondary Slave %s";
> +    break;
> +
> +  default:
> +    Fmt = L"%s";
> +    break;
> +  }
> +
> +  switch (CurBBSEntry->DeviceType) {
> +  case BBS_FLOPPY:
> +    Type = L"Floppy";
> +    break;
> +
> +  case BBS_HARDDISK:
> +    Type = L"Harddisk";
> +    break;
> +
> +  case BBS_CDROM:
> +    Type = L"CDROM";
> +    break;
> +
> +  case BBS_PCMCIA:
> +    Type = L"PCMCIAe";
> +    break;
> +
> +  case BBS_USB:
> +    Type = L"USB";
> +    break;
> +
> +  case BBS_EMBED_NETWORK:
> +    Type = L"Network";
> +    break;
> +
> +  case BBS_BEV_DEVICE:
> +    Type = L"BEVe";
> +    break;
> +
> +  case BBS_UNKNOWN:
> +  default:
> +    Type = L"Unknown";
> +    break;
> +  }
> +  //
> +  // If current BBS entry has its description then use it.
> +  //
> +  StringDesc = (UINT8 *) (UINTN) ((CurBBSEntry->DescStringSegment << 4)
> + CurBBSEntry->DescStringOffset);
> +  if (NULL != StringDesc) {
> +    //
> +    // Only get fisrt 32 characters, this is suggested by BBS spec
> +    //
> +    AsciiToUnicodeSize (StringDesc, 32, Temp);
> +    Fmt   = L"%s";
> +    Type  = Temp;
> +  }
> +
> +  //
> +  // BbsTable 16 entries are for onboard IDE.
> +  // Set description string for SATA harddisks, Harddisk 0 ~ Harddisk 11
> +  //
> +  if (Index >= 5 && Index <= 16 && (CurBBSEntry->DeviceType ==
> BBS_HARDDISK || CurBBSEntry->DeviceType == BBS_CDROM)) {
> +    Fmt = L"%s %d";
> +    UnicodeSPrint (BootString, BufSize, Fmt, Type, Index - 5);
> +  } else {
> +    UnicodeSPrint (BootString, BufSize, Fmt, Type);
> +  }
> +}
> +
> +/**
> +
> +  Create a legacy boot option for the specified entry of
> +  BBS table, save it as variable, and append it to the boot
> +  order list.
> +
> +
> +  @param CurrentBbsEntry    Pointer to current BBS table.
> +  @param CurrentBbsDevPath  Pointer to the Device Path Protocol instance
> of BBS
> +  @param Index              Index of the specified entry in BBS table.
> +  @param BootOrderList      On input, the original boot order list.
> +                            On output, the new boot order list attached with the
> +                            created node.
> +  @param BootOrderListSize  On input, the original size of boot order list.
> +                            On output, the size of new boot order list.
> +
> +  @retval  EFI_SUCCESS             Boot Option successfully created.
> +  @retval  EFI_OUT_OF_RESOURCES    Fail to allocate necessary memory.
> +  @retval  Other                   Error occurs while setting variable.
> +
> +**/
> +EFI_STATUS
> +BdsCreateLegacyBootOption (
> +  IN BBS_TABLE                        *CurrentBbsEntry,
> +  IN EFI_DEVICE_PATH_PROTOCOL         *CurrentBbsDevPath,
> +  IN UINTN                            Index,
> +  IN OUT UINT16                       **BootOrderList,
> +  IN OUT UINTN                        *BootOrderListSize
> +  )
> +{
> +  EFI_STATUS           Status;
> +  UINT16               CurrentBootOptionNo;
> +  UINT16               BootString[10];
> +  CHAR16               BootDesc[100];
> +  CHAR8                HelpString[100];
> +  UINT16               *NewBootOrderList;
> +  UINTN                BufferSize;
> +  UINTN                StringLen;
> +  VOID                 *Buffer;
> +  UINT8                *Ptr;
> +  UINT16               CurrentBbsDevPathSize;
> +  UINTN                BootOrderIndex;
> +  UINTN                BootOrderLastIndex;
> +  UINTN                ArrayIndex;
> +  BOOLEAN              IndexNotFound;
> +  BBS_BBS_DEVICE_PATH  *NewBbsDevPathNode;
> +
> +  if ((*BootOrderList) == NULL) {
> +    CurrentBootOptionNo = 0;
> +  } else {
> +    for (ArrayIndex = 0; ArrayIndex < (UINTN) (*BootOrderListSize / sizeof
> (UINT16)); ArrayIndex++) {
> +      IndexNotFound = TRUE;
> +      for (BootOrderIndex = 0; BootOrderIndex < (UINTN) (*BootOrderListSize
> / sizeof (UINT16)); BootOrderIndex++) {
> +        if ((*BootOrderList)[BootOrderIndex] == ArrayIndex) {
> +          IndexNotFound = FALSE;
> +          break;
> +        }
> +      }
> +
> +      if (!IndexNotFound) {
> +        continue;
> +      } else {
> +        break;
> +      }
> +    }
> +
> +    CurrentBootOptionNo = (UINT16) ArrayIndex;
> +  }
> +
> +  UnicodeSPrint (
> +    BootString,
> +    sizeof (BootString),
> +    L"Boot%04x",
> +    CurrentBootOptionNo
> +    );
> +
> +  BdsBuildLegacyDevNameString (CurrentBbsEntry, Index, sizeof (BootDesc),
> BootDesc);
> +
> +  //
> +  // Create new BBS device path node with description string
> +  //
> +  UnicodeStrToAsciiStr (BootDesc, HelpString);
> +
> +  StringLen = AsciiStrLen (HelpString);
> +  NewBbsDevPathNode = AllocateZeroPool (sizeof (BBS_BBS_DEVICE_PATH)
> + StringLen);
> +  if (NewBbsDevPathNode == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +  CopyMem (NewBbsDevPathNode, CurrentBbsDevPath, sizeof
> (BBS_BBS_DEVICE_PATH));
> +  CopyMem (NewBbsDevPathNode->String, HelpString, StringLen + 1);
> +  SetDevicePathNodeLength (&(NewBbsDevPathNode->Header), sizeof
> (BBS_BBS_DEVICE_PATH) + StringLen);
> +
> +  //
> +  // Create entire new CurrentBbsDevPath with end node
> +  //
> +  CurrentBbsDevPath = AppendDevicePathNode (
> +                        NULL,
> +                        (EFI_DEVICE_PATH_PROTOCOL *) NewBbsDevPathNode
> +                        );
> +   if (CurrentBbsDevPath == NULL) {
> +    FreePool (NewBbsDevPathNode);
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  CurrentBbsDevPathSize = (UINT16) (GetDevicePathSize
> (CurrentBbsDevPath));
> +
> +  BufferSize = sizeof (UINT32) +
> +    sizeof (UINT16) +
> +    StrSize (BootDesc) +
> +    CurrentBbsDevPathSize +
> +    sizeof (BBS_TABLE) +
> +    sizeof (UINT16);
> +
> +  Buffer = AllocateZeroPool (BufferSize);
> +  if (Buffer == NULL) {
> +    FreePool (NewBbsDevPathNode);
> +    FreePool (CurrentBbsDevPath);
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  Ptr               = (UINT8 *) Buffer;
> +
> +  *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE;
> +  Ptr += sizeof (UINT32);
> +
> +  *((UINT16 *) Ptr) = CurrentBbsDevPathSize;
> +  Ptr += sizeof (UINT16);
> +
> +  CopyMem (
> +    Ptr,
> +    BootDesc,
> +    StrSize (BootDesc)
> +    );
> +  Ptr += StrSize (BootDesc);
> +
> +  CopyMem (
> +    Ptr,
> +    CurrentBbsDevPath,
> +    CurrentBbsDevPathSize
> +    );
> +  Ptr += CurrentBbsDevPathSize;
> +
> +  CopyMem (
> +    Ptr,
> +    CurrentBbsEntry,
> +    sizeof (BBS_TABLE)
> +    );
> +
> +  Ptr += sizeof (BBS_TABLE);
> +  *((UINT16 *) Ptr) = (UINT16) Index;
> +
> +  Status = gRT->SetVariable (
> +                  BootString,
> +                  &gEfiGlobalVariableGuid,
> +                  EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
> +                  BufferSize,
> +                  Buffer
> +                  );
> +
> +  FreePool (Buffer);
> +
> +  Buffer = NULL;
> +
> +  NewBootOrderList = AllocateZeroPool (*BootOrderListSize + sizeof
> (UINT16));
> +  if (NULL == NewBootOrderList) {
> +    FreePool (NewBbsDevPathNode);
> +    FreePool (CurrentBbsDevPath);
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  if (*BootOrderList != NULL) {
> +    CopyMem (NewBootOrderList, *BootOrderList, *BootOrderListSize);
> +    FreePool (*BootOrderList);
> +  }
> +
> +  BootOrderLastIndex                    = (UINTN) (*BootOrderListSize / sizeof
> (UINT16));
> +  NewBootOrderList[BootOrderLastIndex]  = CurrentBootOptionNo;
> +  *BootOrderListSize += sizeof (UINT16);
> +  *BootOrderList = NewBootOrderList;
> +
> +  FreePool (NewBbsDevPathNode);
> +  FreePool (CurrentBbsDevPath);
> +  return Status;
> +}
> +
> +/**
> +  Check if the boot option is a legacy one.
> +
> +  @param BootOptionVar   The boot option data payload.
> +  @param BbsEntry        The BBS Table.
> +  @param BbsIndex        The table index.
> +
> +  @retval TRUE           It is a legacy boot option.
> +  @retval FALSE          It is not a legacy boot option.
> +
> +**/
> +BOOLEAN
> +BdsIsLegacyBootOption (
> +  IN UINT8                 *BootOptionVar,
> +  OUT BBS_TABLE            **BbsEntry,
> +  OUT UINT16               *BbsIndex
> +  )
> +{
> +  UINT8                     *Ptr;
> +  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
> +  BOOLEAN                   Ret;
> +  UINT16                    DevPathLen;
> +
> +  Ptr = BootOptionVar;
> +  Ptr += sizeof (UINT32);
> +  DevPathLen = *(UINT16 *) Ptr;
> +  Ptr += sizeof (UINT16);
> +  Ptr += StrSize ((UINT16 *) Ptr);
> +  DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
> +  if ((BBS_DEVICE_PATH == DevicePath->Type) && (BBS_BBS_DP ==
> DevicePath->SubType)) {
> +    Ptr += DevPathLen;
> +    *BbsEntry = (BBS_TABLE *) Ptr;
> +    Ptr += sizeof (BBS_TABLE);
> +    *BbsIndex = *(UINT16 *) Ptr;
> +    Ret       = TRUE;
> +  } else {
> +    *BbsEntry = NULL;
> +    Ret       = FALSE;
> +  }
> +
> +  return Ret;
> +}
> +
> +/**
> +  Delete all the invalid legacy boot options.
> +
> +  @retval EFI_SUCCESS             All invalide legacy boot options are deleted.
> +  @retval EFI_OUT_OF_RESOURCES    Fail to allocate necessary memory.
> +  @retval EFI_NOT_FOUND           Fail to retrive variable of boot order.
> +**/
> +EFI_STATUS
> +EFIAPI
> +BdsDeleteAllInvalidLegacyBootOptions (
> +  VOID
> +  )
> +{
> +  UINT16                    *BootOrder;
> +  UINT8                     *BootOptionVar;
> +  UINTN                     BootOrderSize;
> +  UINTN                     BootOptionSize;
> +  EFI_STATUS                Status;
> +  UINT16                    HddCount;
> +  UINT16                    BbsCount;
> +  HDD_INFO                  *LocalHddInfo;
> +  BBS_TABLE                 *LocalBbsTable;
> +  BBS_TABLE                 *BbsEntry;
> +  UINT16                    BbsIndex;
> +  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;
> +  UINTN                     Index;
> +  UINT16                    BootOption[10];
> +  UINT16                    BootDesc[100];
> +  BOOLEAN                   DescStringMatch;
> +
> +  Status        = EFI_SUCCESS;
> +  BootOrder     = NULL;
> +  BootOrderSize = 0;
> +  HddCount      = 0;
> +  BbsCount      = 0;
> +  LocalHddInfo  = NULL;
> +  LocalBbsTable = NULL;
> +  BbsEntry      = NULL;
> +
> +  Status        = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL,
> (VOID **) &LegacyBios);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  BootOrder = BdsLibGetVariableAndSize (
> +                L"BootOrder",
> +                &gEfiGlobalVariableGuid,
> +                &BootOrderSize
> +                );
> +  if (BootOrder == NULL) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  LegacyBios->GetBbsInfo (
> +                LegacyBios,
> +                &HddCount,
> +                &LocalHddInfo,
> +                &BbsCount,
> +                &LocalBbsTable
> +                );
> +
> +  Index = 0;
> +  while (Index < BootOrderSize / sizeof (UINT16)) {
> +    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x",
> BootOrder[Index]);
> +    BootOptionVar = BdsLibGetVariableAndSize (
> +                      BootOption,
> +                      &gEfiGlobalVariableGuid,
> +                      &BootOptionSize
> +                      );
> +    if (NULL == BootOptionVar) {
> +      BootOptionSize = 0;
> +      Status = gRT->GetVariable (
> +                      BootOption,
> +                      &gEfiGlobalVariableGuid,
> +                      NULL,
> +                      &BootOptionSize,
> +                      BootOptionVar
> +                      );
> +      if (Status == EFI_NOT_FOUND) {
> +        //
> +        // Update BootOrder
> +        //
> +        BdsDeleteBootOption (
> +          BootOrder[Index],
> +          BootOrder,
> +          &BootOrderSize
> +          );
> +        continue;
> +      } else {
> +        FreePool (BootOrder);
> +        return EFI_OUT_OF_RESOURCES;
> +      }
> +    }
> +
> +    //
> +    // Skip Non-Legacy boot option
> +    //
> +    if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, &BbsIndex)) {
> +      if (BootOptionVar!= NULL) {
> +        FreePool (BootOptionVar);
> +      }
> +      Index++;
> +      continue;
> +    }
> +
> +    if (BbsIndex < BbsCount) {
> +      //
> +      // Check if BBS Description String is changed
> +      //
> +      DescStringMatch = FALSE;
> +      BdsBuildLegacyDevNameString (
> +        &LocalBbsTable[BbsIndex],
> +        BbsIndex,
> +        sizeof (BootDesc),
> +        BootDesc
> +        );
> +
> +      if (StrCmp (BootDesc, (UINT16*)(BootOptionVar + sizeof (UINT32) +
> sizeof (UINT16))) == 0) {
> +        DescStringMatch = TRUE;
> +      }
> +
> +      if (!((LocalBbsTable[BbsIndex].BootPriority == BBS_IGNORE_ENTRY) ||
> +            (LocalBbsTable[BbsIndex].BootPriority ==
> BBS_DO_NOT_BOOT_FROM)) &&
> +          (LocalBbsTable[BbsIndex].DeviceType == BbsEntry->DeviceType) &&
> +          DescStringMatch) {
> +        Index++;
> +        continue;
> +      }
> +    }
> +
> +    if (BootOptionVar != NULL) {
> +      FreePool (BootOptionVar);
> +    }
> +    //
> +    // should delete
> +    //
> +    BdsDeleteBootOption (
> +      BootOrder[Index],
> +      BootOrder,
> +      &BootOrderSize
> +      );
> +  }
> +
> +  //
> +  // Adjust the number of boot options.
> +  //
> +  Status = gRT->SetVariable (
> +                  L"BootOrder",
> +                  &gEfiGlobalVariableGuid,
> +                  EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
> +                  BootOrderSize,
> +                  BootOrder
> +                  );
> +  //
> +  // Shrinking variable with existing variable implementation shouldn't fail.
> +  //
> +  ASSERT_EFI_ERROR (Status);
> +  FreePool (BootOrder);
> +
> +  return Status;
> +}
> +
> +/**
> +  Find all legacy boot option by device type.
> +
> +  @param BootOrder       The boot order array.
> +  @param BootOptionNum   The number of boot option.
> +  @param DevType         Device type.
> +  @param DevName         Device name.
> +  @param Attribute       The boot option attribute.
> +  @param BbsIndex        The BBS table index.
> +  @param OptionNumber    The boot option index.
> +
> +  @retval TRUE           The Legacy boot option is found.
> +  @retval FALSE          The legacy boot option is not found.
> +
> +**/
> +BOOLEAN
> +BdsFindLegacyBootOptionByDevTypeAndName (
> +  IN UINT16                 *BootOrder,
> +  IN UINTN                  BootOptionNum,
> +  IN UINT16                 DevType,
> +  IN CHAR16                 *DevName,
> +  OUT UINT32                *Attribute,
> +  OUT UINT16                *BbsIndex,
> +  OUT UINT16                *OptionNumber
> +  )
> +{
> +  UINTN     Index;
> +  CHAR16    BootOption[9];
> +  UINTN     BootOptionSize;
> +  UINT8     *BootOptionVar;
> +  BBS_TABLE *BbsEntry;
> +  BOOLEAN   Found;
> +
> +  BbsEntry  = NULL;
> +  Found     = FALSE;
> +
> +  if (NULL == BootOrder) {
> +    return Found;
> +  }
> +
> +  //
> +  // Loop all boot option from variable
> +  //
> +  for (Index = 0; Index < BootOptionNum; Index++) {
> +    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", (UINTN)
> BootOrder[Index]);
> +    BootOptionVar = BdsLibGetVariableAndSize (
> +                      BootOption,
> +                      &gEfiGlobalVariableGuid,
> +                      &BootOptionSize
> +                      );
> +    if (NULL == BootOptionVar) {
> +      continue;
> +    }
> +
> +    //
> +    // Skip Non-legacy boot option
> +    //
> +    if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, BbsIndex)) {
> +      FreePool (BootOptionVar);
> +      continue;
> +    }
> +
> +    if (
> +        (BbsEntry->DeviceType != DevType) ||
> +        (StrCmp (DevName, (CHAR16*)(BootOptionVar + sizeof (UINT32) +
> sizeof (UINT16))) != 0)
> +       ) {
> +      FreePool (BootOptionVar);
> +      continue;
> +    }
> +
> +    *Attribute    = *(UINT32 *) BootOptionVar;
> +    *OptionNumber = BootOrder[Index];
> +    Found         = TRUE;
> +    FreePool (BootOptionVar);
> +    break;
> +  }
> +
> +  return Found;
> +}
> +
> +/**
> +  Create a legacy boot option.
> +
> +  @param BbsItem         The BBS Table entry.
> +  @param Index           Index of the specified entry in BBS table.
> +  @param BootOrderList   The boot order list.
> +  @param BootOrderListSize The size of boot order list.
> +
> +  @retval EFI_OUT_OF_RESOURCE  No enough memory.
> +  @retval EFI_SUCCESS          The function complete successfully.
> +  @return Other value if the legacy boot option is not created.
> +
> +**/
> +EFI_STATUS
> +BdsCreateOneLegacyBootOption (
> +  IN BBS_TABLE              *BbsItem,
> +  IN UINTN                  Index,
> +  IN OUT UINT16             **BootOrderList,
> +  IN OUT UINTN              *BootOrderListSize
> +  )
> +{
> +  BBS_BBS_DEVICE_PATH       BbsDevPathNode;
> +  EFI_STATUS                Status;
> +  EFI_DEVICE_PATH_PROTOCOL  *DevPath;
> +
> +  DevPath                       = NULL;
> +
> +  //
> +  // Create device path node.
> +  //
> +  BbsDevPathNode.Header.Type    = BBS_DEVICE_PATH;
> +  BbsDevPathNode.Header.SubType = BBS_BBS_DP;
> +  SetDevicePathNodeLength (&BbsDevPathNode.Header, sizeof
> (BBS_BBS_DEVICE_PATH));
> +  BbsDevPathNode.DeviceType = BbsItem->DeviceType;
> +  CopyMem (&BbsDevPathNode.StatusFlag, &BbsItem->StatusFlags, sizeof
> (UINT16));
> +
> +  DevPath = AppendDevicePathNode (
> +              NULL,
> +              (EFI_DEVICE_PATH_PROTOCOL *) &BbsDevPathNode
> +              );
> +  if (NULL == DevPath) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  Status = BdsCreateLegacyBootOption (
> +            BbsItem,
> +            DevPath,
> +            Index,
> +            BootOrderList,
> +            BootOrderListSize
> +            );
> +  BbsItem->BootPriority = 0x00;
> +
> +  FreePool (DevPath);
> +
> +  return Status;
> +}
> +
> +/**
> +  Add the legacy boot options from BBS table if they do not exist.
> +
> +  @retval EFI_SUCCESS          The boot options are added successfully
> +                               or they are already in boot options.
> +  @retval EFI_NOT_FOUND        No legacy boot options is found.
> +  @retval EFI_OUT_OF_RESOURCE  No enough memory.
> +  @return Other value          LegacyBoot options are not added.
> +**/
> +EFI_STATUS
> +EFIAPI
> +BdsAddNonExistingLegacyBootOptions (
> +  VOID
> +  )
> +{
> +  UINT16                    *BootOrder;
> +  UINTN                     BootOrderSize;
> +  EFI_STATUS                Status;
> +  CHAR16                    Desc[100];
> +  UINT16                    HddCount;
> +  UINT16                    BbsCount;
> +  HDD_INFO                  *LocalHddInfo;
> +  BBS_TABLE                 *LocalBbsTable;
> +  UINT16                    BbsIndex;
> +  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;
> +  UINT16                    Index;
> +  UINT32                    Attribute;
> +  UINT16                    OptionNumber;
> +  BOOLEAN                   Exist;
> +
> +  HddCount      = 0;
> +  BbsCount      = 0;
> +  LocalHddInfo  = NULL;
> +  LocalBbsTable = NULL;
> +
> +  Status        = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL,
> (VOID **) &LegacyBios);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  LegacyBios->GetBbsInfo (
> +                LegacyBios,
> +                &HddCount,
> +                &LocalHddInfo,
> +                &BbsCount,
> +                &LocalBbsTable
> +                );
> +
> +  BootOrder = BdsLibGetVariableAndSize (
> +                L"BootOrder",
> +                &gEfiGlobalVariableGuid,
> +                &BootOrderSize
> +                );
> +  if (BootOrder == NULL) {
> +    BootOrderSize = 0;
> +  }
> +
> +  for (Index = 0; Index < BbsCount; Index++) {
> +    if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||
> +        (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)
> +        ) {
> +      continue;
> +    }
> +
> +    BdsBuildLegacyDevNameString (&LocalBbsTable[Index], Index, sizeof
> (Desc), Desc);
> +
> +    Exist = BdsFindLegacyBootOptionByDevTypeAndName (
> +              BootOrder,
> +              BootOrderSize / sizeof (UINT16),
> +              LocalBbsTable[Index].DeviceType,
> +              Desc,
> +              &Attribute,
> +              &BbsIndex,
> +              &OptionNumber
> +              );
> +    if (!Exist) {
> +      //
> +      // Not found such type of legacy device in boot options or we found but
> it's disabled
> +      // so we have to create one and put it to the tail of boot order list
> +      //
> +      Status = BdsCreateOneLegacyBootOption (
> +                &LocalBbsTable[Index],
> +                Index,
> +                &BootOrder,
> +                &BootOrderSize
> +                );
> +      if (!EFI_ERROR (Status)) {
> +        ASSERT (BootOrder != NULL);
> +        BbsIndex     = Index;
> +        OptionNumber = BootOrder[BootOrderSize / sizeof (UINT16) - 1];
> +      }
> +    }
> +
> +    ASSERT (BbsIndex == Index);
> +  }
> +
> +  Status = gRT->SetVariable (
> +                  L"BootOrder",
> +                  &gEfiGlobalVariableGuid,
> +                  EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
> +                  BootOrderSize,
> +                  BootOrder
> +                  );
> +  if (BootOrder != NULL) {
> +    FreePool (BootOrder);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  Fill the device order buffer.
> +
> +  @param BbsTable        The BBS table.
> +  @param BbsType         The BBS Type.
> +  @param BbsCount        The BBS Count.
> +  @param Buf             device order buffer.
> +
> +  @return The device order buffer.
> +
> +**/
> +UINT16 *
> +BdsFillDevOrderBuf (
> +  IN BBS_TABLE                    *BbsTable,
> +  IN BBS_TYPE                     BbsType,
> +  IN UINTN                        BbsCount,
> +  OUT UINT16                      *Buf
> +  )
> +{
> +  UINTN Index;
> +
> +  for (Index = 0; Index < BbsCount; Index++) {
> +    if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) {
> +      continue;
> +    }
> +
> +    if (BbsTable[Index].DeviceType != BbsType) {
> +      continue;
> +    }
> +
> +    *Buf = (UINT16) (Index & 0xFF);
> +    Buf++;
> +  }
> +
> +  return Buf;
> +}
> +
> +/**
> +  Create the device order buffer.
> +
> +  @param BbsTable        The BBS table.
> +  @param BbsCount        The BBS Count.
> +
> +  @retval EFI_SUCCES             The buffer is created and the EFI variable
> named
> +                                 VAR_LEGACY_DEV_ORDER and
> gEfiLegacyDevOrderVariableGuid is
> +                                 set correctly.
> +  @retval EFI_OUT_OF_RESOURCES   Memmory or storage is not enough.
> +  @retval EFI_DEVICE_ERROR       Fail to add the device order into EFI variable
> fail
> +                                 because of hardware error.
> +**/
> +EFI_STATUS
> +BdsCreateDevOrder (
> +  IN BBS_TABLE                  *BbsTable,
> +  IN UINT16                     BbsCount
> +  )
> +{
> +  UINTN                       Index;
> +  UINTN                       FDCount;
> +  UINTN                       HDCount;
> +  UINTN                       CDCount;
> +  UINTN                       NETCount;
> +  UINTN                       BEVCount;
> +  UINTN                       TotalSize;
> +  UINTN                       HeaderSize;
> +  LEGACY_DEV_ORDER_ENTRY      *DevOrder;
> +  LEGACY_DEV_ORDER_ENTRY      *DevOrderPtr;
> +  EFI_STATUS                  Status;
> +
> +  FDCount     = 0;
> +  HDCount     = 0;
> +  CDCount     = 0;
> +  NETCount    = 0;
> +  BEVCount    = 0;
> +  TotalSize   = 0;
> +  HeaderSize  = sizeof (BBS_TYPE) + sizeof (UINT16);
> +  DevOrder    = NULL;
> +  Status      = EFI_SUCCESS;
> +
> +  //
> +  // Count all boot devices
> +  //
> +  for (Index = 0; Index < BbsCount; Index++) {
> +    if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) {
> +      continue;
> +    }
> +
> +    switch (BbsTable[Index].DeviceType) {
> +    case BBS_FLOPPY:
> +      FDCount++;
> +      break;
> +
> +    case BBS_HARDDISK:
> +      HDCount++;
> +      break;
> +
> +    case BBS_CDROM:
> +      CDCount++;
> +      break;
> +
> +    case BBS_EMBED_NETWORK:
> +      NETCount++;
> +      break;
> +
> +    case BBS_BEV_DEVICE:
> +      BEVCount++;
> +      break;
> +
> +    default:
> +      break;
> +    }
> +  }
> +
> +  TotalSize += (HeaderSize + sizeof (UINT16) * FDCount);
> +  TotalSize += (HeaderSize + sizeof (UINT16) * HDCount);
> +  TotalSize += (HeaderSize + sizeof (UINT16) * CDCount);
> +  TotalSize += (HeaderSize + sizeof (UINT16) * NETCount);
> +  TotalSize += (HeaderSize + sizeof (UINT16) * BEVCount);
> +
> +  //
> +  // Create buffer to hold all boot device order
> +  //
> +  DevOrder = AllocateZeroPool (TotalSize);
> +  if (NULL == DevOrder) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +  DevOrderPtr          = DevOrder;
> +
> +  DevOrderPtr->BbsType = BBS_FLOPPY;
> +  DevOrderPtr->Length  = (UINT16) (sizeof (DevOrderPtr->Length) +
> FDCount * sizeof (UINT16));
> +  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf
> (BbsTable, BBS_FLOPPY, BbsCount, DevOrderPtr->Data);
> +
> +  DevOrderPtr->BbsType = BBS_HARDDISK;
> +  DevOrderPtr->Length  = (UINT16) (sizeof (UINT16) + HDCount * sizeof
> (UINT16));
> +  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf
> (BbsTable, BBS_HARDDISK, BbsCount, DevOrderPtr->Data);
> +
> +  DevOrderPtr->BbsType = BBS_CDROM;
> +  DevOrderPtr->Length  = (UINT16) (sizeof (UINT16) + CDCount * sizeof
> (UINT16));
> +  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf
> (BbsTable, BBS_CDROM, BbsCount, DevOrderPtr->Data);
> +
> +  DevOrderPtr->BbsType = BBS_EMBED_NETWORK;
> +  DevOrderPtr->Length  = (UINT16) (sizeof (UINT16) + NETCount * sizeof
> (UINT16));
> +  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf
> (BbsTable, BBS_EMBED_NETWORK, BbsCount, DevOrderPtr->Data);
> +
> +  DevOrderPtr->BbsType = BBS_BEV_DEVICE;
> +  DevOrderPtr->Length  = (UINT16) (sizeof (UINT16) + BEVCount * sizeof
> (UINT16));
> +  DevOrderPtr          = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf
> (BbsTable, BBS_BEV_DEVICE, BbsCount, DevOrderPtr->Data);
> +
> +  ASSERT (TotalSize == (UINTN) ((UINT8 *) DevOrderPtr - (UINT8 *)
> DevOrder));
> +
> +  //
> +  // Save device order for legacy boot device to variable.
> +  //
> +  Status = gRT->SetVariable (
> +                  VAR_LEGACY_DEV_ORDER,
> +                  &gEfiLegacyDevOrderVariableGuid,
> +                  EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_NON_VOLATILE,
> +                  TotalSize,
> +                  DevOrder
> +                  );
> +  FreePool (DevOrder);
> +
> +  return Status;
> +}
> +
> +/**
> +  Add the legacy boot devices from BBS table into
> +  the legacy device boot order.
> +
> +  @retval EFI_SUCCESS           The boot devices are added successfully.
> +  @retval EFI_NOT_FOUND         The legacy boot devices are not found.
> +  @retval EFI_OUT_OF_RESOURCES  Memmory or storage is not enough.
> +  @retval EFI_DEVICE_ERROR      Fail to add the legacy device boot order into
> EFI variable
> +                                because of hardware error.
> +**/
> +EFI_STATUS
> +EFIAPI
> +BdsUpdateLegacyDevOrder (
> +  VOID
> +  )
> +{
> +  LEGACY_DEV_ORDER_ENTRY      *DevOrder;
> +  LEGACY_DEV_ORDER_ENTRY      *NewDevOrder;
> +  LEGACY_DEV_ORDER_ENTRY      *Ptr;
> +  LEGACY_DEV_ORDER_ENTRY      *NewPtr;
> +  UINTN                       DevOrderSize;
> +  EFI_LEGACY_BIOS_PROTOCOL    *LegacyBios;
> +  EFI_STATUS                  Status;
> +  UINT16                      HddCount;
> +  UINT16                      BbsCount;
> +  HDD_INFO                    *LocalHddInfo;
> +  BBS_TABLE                   *LocalBbsTable;
> +  UINTN                       Index;
> +  UINTN                       Index2;
> +  UINTN                       *Idx;
> +  UINTN                       FDCount;
> +  UINTN                       HDCount;
> +  UINTN                       CDCount;
> +  UINTN                       NETCount;
> +  UINTN                       BEVCount;
> +  UINTN                       TotalSize;
> +  UINTN                       HeaderSize;
> +  UINT16                      *NewFDPtr;
> +  UINT16                      *NewHDPtr;
> +  UINT16                      *NewCDPtr;
> +  UINT16                      *NewNETPtr;
> +  UINT16                      *NewBEVPtr;
> +  UINT16                      *NewDevPtr;
> +  UINTN                       FDIndex;
> +  UINTN                       HDIndex;
> +  UINTN                       CDIndex;
> +  UINTN                       NETIndex;
> +  UINTN                       BEVIndex;
> +
> +  Idx           = NULL;
> +  FDCount       = 0;
> +  HDCount       = 0;
> +  CDCount       = 0;
> +  NETCount      = 0;
> +  BEVCount      = 0;
> +  TotalSize     = 0;
> +  HeaderSize    = sizeof (BBS_TYPE) + sizeof (UINT16);
> +  FDIndex       = 0;
> +  HDIndex       = 0;
> +  CDIndex       = 0;
> +  NETIndex      = 0;
> +  BEVIndex      = 0;
> +  NewDevPtr     = NULL;
> +
> +  Status        = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL,
> (VOID **) &LegacyBios);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = LegacyBios->GetBbsInfo (
> +                         LegacyBios,
> +                         &HddCount,
> +                         &LocalHddInfo,
> +                         &BbsCount,
> +                         &LocalBbsTable
> +                         );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  DevOrder = BdsLibGetVariableAndSize (
> +               VAR_LEGACY_DEV_ORDER,
> +               &gEfiLegacyDevOrderVariableGuid,
> +               &DevOrderSize
> +               );
> +  if (NULL == DevOrder) {
> +    return BdsCreateDevOrder (LocalBbsTable, BbsCount);
> +  }
> +  //
> +  // First we figure out how many boot devices with same device type
> respectively
> +  //
> +  for (Index = 0; Index < BbsCount; Index++) {
> +    if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||
> +        (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)
> +        ) {
> +      continue;
> +    }
> +
> +    switch (LocalBbsTable[Index].DeviceType) {
> +    case BBS_FLOPPY:
> +      FDCount++;
> +      break;
> +
> +    case BBS_HARDDISK:
> +      HDCount++;
> +      break;
> +
> +    case BBS_CDROM:
> +      CDCount++;
> +      break;
> +
> +    case BBS_EMBED_NETWORK:
> +      NETCount++;
> +      break;
> +
> +    case BBS_BEV_DEVICE:
> +      BEVCount++;
> +      break;
> +
> +    default:
> +      break;
> +    }
> +  }
> +
> +  TotalSize += (HeaderSize + FDCount * sizeof (UINT16));
> +  TotalSize += (HeaderSize + HDCount * sizeof (UINT16));
> +  TotalSize += (HeaderSize + CDCount * sizeof (UINT16));
> +  TotalSize += (HeaderSize + NETCount * sizeof (UINT16));
> +  TotalSize += (HeaderSize + BEVCount * sizeof (UINT16));
> +
> +  NewDevOrder = AllocateZeroPool (TotalSize);
> +  if (NULL == NewDevOrder) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +
> +
> +  //
> +  // copy FD
> +  //
> +  Ptr             = DevOrder;
> +  NewPtr          = NewDevOrder;
> +  NewPtr->BbsType = Ptr->BbsType;
> +  NewPtr->Length  = (UINT16) (sizeof (UINT16) + FDCount * sizeof (UINT16));
> +  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
> +    if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority ==
> BBS_IGNORE_ENTRY ||
> +        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority ==
> BBS_DO_NOT_BOOT_FROM ||
> +        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_FLOPPY
> +        ) {
> +      continue;
> +    }
> +
> +    NewPtr->Data[FDIndex] = Ptr->Data[Index];
> +    FDIndex++;
> +  }
> +  NewFDPtr = NewPtr->Data;
> +
> +  //
> +  // copy HD
> +  //
> +  Ptr             = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length /
> sizeof (UINT16) - 1]);
> +  NewPtr          = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr-
> >Length / sizeof (UINT16) -1]);
> +  NewPtr->BbsType = Ptr->BbsType;
> +  NewPtr->Length  = (UINT16) (sizeof (UINT16) + HDCount * sizeof
> (UINT16));
> +  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
> +    if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority ==
> BBS_IGNORE_ENTRY ||
> +        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority ==
> BBS_DO_NOT_BOOT_FROM ||
> +        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority ==
> BBS_LOWEST_PRIORITY ||
> +        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_HARDDISK
> +        ) {
> +      continue;
> +    }
> +
> +    NewPtr->Data[HDIndex] = Ptr->Data[Index];
> +    HDIndex++;
> +  }
> +  NewHDPtr = NewPtr->Data;
> +
> +  //
> +  // copy CD
> +  //
> +  Ptr    = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof
> (UINT16) - 1]);
> +  NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr-
> >Length / sizeof (UINT16) -1]);
> +  NewPtr->BbsType = Ptr->BbsType;
> +  NewPtr->Length  = (UINT16) (sizeof (UINT16) + CDCount * sizeof
> (UINT16));
> +  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
> +    if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority ==
> BBS_IGNORE_ENTRY ||
> +        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority ==
> BBS_DO_NOT_BOOT_FROM ||
> +        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority ==
> BBS_LOWEST_PRIORITY ||
> +        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_CDROM
> +        ) {
> +      continue;
> +    }
> +
> +    NewPtr->Data[CDIndex] = Ptr->Data[Index];
> +    CDIndex++;
> +  }
> +  NewCDPtr = NewPtr->Data;
> +
> +  //
> +  // copy NET
> +  //
> +  Ptr    = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof
> (UINT16) - 1]);
> +  NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr-
> >Length / sizeof (UINT16) -1]);
> +  NewPtr->BbsType = Ptr->BbsType;
> +  NewPtr->Length  = (UINT16) (sizeof (UINT16) + NETCount * sizeof
> (UINT16));
> +  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
> +    if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority ==
> BBS_IGNORE_ENTRY ||
> +        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority ==
> BBS_DO_NOT_BOOT_FROM ||
> +        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority ==
> BBS_LOWEST_PRIORITY ||
> +        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType !=
> BBS_EMBED_NETWORK
> +        ) {
> +      continue;
> +    }
> +
> +    NewPtr->Data[NETIndex] = Ptr->Data[Index];
> +    NETIndex++;
> +  }
> +  NewNETPtr = NewPtr->Data;
> +
> +  //
> +  // copy BEV
> +  //
> +  Ptr    = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof
> (UINT16) - 1]);
> +  NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr-
> >Length / sizeof (UINT16) -1]);
> +  NewPtr->BbsType = Ptr->BbsType;
> +  NewPtr->Length  = (UINT16) (sizeof (UINT16) + BEVCount * sizeof
> (UINT16));
> +  for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
> +    if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority ==
> BBS_IGNORE_ENTRY ||
> +        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority ==
> BBS_DO_NOT_BOOT_FROM ||
> +        LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority ==
> BBS_LOWEST_PRIORITY ||
> +        LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType !=
> BBS_BEV_DEVICE
> +        ) {
> +      continue;
> +    }
> +
> +    NewPtr->Data[BEVIndex] = Ptr->Data[Index];
> +    BEVIndex++;
> +  }
> +  NewBEVPtr = NewPtr->Data;
> +
> +  for (Index = 0; Index < BbsCount; Index++) {
> +    if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||
> +        (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)
> +        ) {
> +      continue;
> +    }
> +
> +    switch (LocalBbsTable[Index].DeviceType) {
> +    case BBS_FLOPPY:
> +      Idx       = &FDIndex;
> +      NewDevPtr = NewFDPtr;
> +      break;
> +
> +    case BBS_HARDDISK:
> +      Idx       = &HDIndex;
> +      NewDevPtr = NewHDPtr;
> +      break;
> +
> +    case BBS_CDROM:
> +      Idx       = &CDIndex;
> +      NewDevPtr = NewCDPtr;
> +      break;
> +
> +    case BBS_EMBED_NETWORK:
> +      Idx       = &NETIndex;
> +      NewDevPtr = NewNETPtr;
> +      break;
> +
> +    case BBS_BEV_DEVICE:
> +      Idx       = &BEVIndex;
> +      NewDevPtr = NewBEVPtr;
> +      break;
> +
> +    default:
> +      Idx = NULL;
> +      break;
> +    }
> +    //
> +    // at this point we have copied those valid indexes to new buffer
> +    // and we should check if there is any new appeared boot device
> +    //
> +    if (Idx != NULL) {
> +      for (Index2 = 0; Index2 < *Idx; Index2++) {
> +        if ((NewDevPtr[Index2] & 0xFF) == (UINT16) Index) {
> +          break;
> +        }
> +      }
> +
> +      if (Index2 == *Idx) {
> +        //
> +        // Index2 == *Idx means we didn't find Index
> +        // so Index is a new appeared device's index in BBS table
> +        // insert it before disabled indexes.
> +        //
> +        for (Index2 = 0; Index2 < *Idx; Index2++) {
> +          if ((NewDevPtr[Index2] & 0xFF00) == 0xFF00) {
> +            break;
> +          }
> +        }
> +        CopyMem (&NewDevPtr[Index2 + 1], &NewDevPtr[Index2], (*Idx -
> Index2) * sizeof (UINT16));
> +        NewDevPtr[Index2] = (UINT16) (Index & 0xFF);
> +        (*Idx)++;
> +      }
> +    }
> +  }
> +
> +  FreePool (DevOrder);
> +
> +  Status = gRT->SetVariable (
> +                  VAR_LEGACY_DEV_ORDER,
> +                  &gEfiLegacyDevOrderVariableGuid,
> +                  EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_NON_VOLATILE,
> +                  TotalSize,
> +                  NewDevOrder
> +                  );
> +  FreePool (NewDevOrder);
> +
> +  return Status;
> +}
> +
> +/**
> +  Set Boot Priority for specified device type.
> +
> +  @param DeviceType      The device type.
> +  @param BbsIndex        The BBS index to set the highest priority. Ignore
> when -1.
> +  @param LocalBbsTable   The BBS table.
> +  @param Priority        The prority table.
> +
> +  @retval EFI_SUCCESS           The function completes successfully.
> +  @retval EFI_NOT_FOUND         Failed to find device.
> +  @retval EFI_OUT_OF_RESOURCES  Failed to get the efi variable of device
> order.
> +
> +**/
> +EFI_STATUS
> +BdsSetBootPriority4SameTypeDev (
> +  IN UINT16                                              DeviceType,
> +  IN UINTN                                               BbsIndex,
> +  IN OUT BBS_TABLE                                       *LocalBbsTable,
> +  IN OUT UINT16                                          *Priority
> +  )
> +{
> +  LEGACY_DEV_ORDER_ENTRY      *DevOrder;
> +  LEGACY_DEV_ORDER_ENTRY      *DevOrderPtr;
> +  UINTN                       DevOrderSize;
> +  UINTN                       Index;
> +
> +  DevOrder = BdsLibGetVariableAndSize (
> +               VAR_LEGACY_DEV_ORDER,
> +               &gEfiLegacyDevOrderVariableGuid,
> +               &DevOrderSize
> +               );
> +  if (NULL == DevOrder) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  DevOrderPtr = DevOrder;
> +  while ((UINT8 *) DevOrderPtr < (UINT8 *) DevOrder + DevOrderSize) {
> +    if (DevOrderPtr->BbsType == DeviceType) {
> +      break;
> +    }
> +
> +    DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) ((UINTN) DevOrderPtr +
> sizeof (BBS_TYPE) + DevOrderPtr->Length);
> +  }
> +
> +  if ((UINT8 *) DevOrderPtr >= (UINT8 *) DevOrder + DevOrderSize) {
> +    FreePool (DevOrder);
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  if (BbsIndex != (UINTN) -1) {
> +    LocalBbsTable[BbsIndex].BootPriority = *Priority;
> +    (*Priority)++;
> +  }
> +  //
> +  // If the high byte of the DevIndex is 0xFF, it indicates that this device has
> been disabled.
> +  //
> +  for (Index = 0; Index < DevOrderPtr->Length / sizeof (UINT16) - 1; Index++)
> {
> +    if ((DevOrderPtr->Data[Index] & 0xFF00) == 0xFF00) {
> +      //
> +      // LocalBbsTable[DevIndex[Index] & 0xFF].BootPriority =
> BBS_DISABLED_ENTRY;
> +      //
> +    } else if (DevOrderPtr->Data[Index] != BbsIndex) {
> +      LocalBbsTable[DevOrderPtr->Data[Index]].BootPriority = *Priority;
> +      (*Priority)++;
> +    }
> +  }
> +
> +  FreePool (DevOrder);
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Print the BBS Table.
> +
> +  @param LocalBbsTable   The BBS table.
> +  @param BbsCount        The count of entry in BBS table.
> +**/
> +VOID
> +PrintBbsTable (
> +  IN BBS_TABLE  *LocalBbsTable,
> +  IN UINT16     BbsCount
> +  )
> +{
> +  UINT16  Idx;
> +
> +  DEBUG ((DEBUG_ERROR, "\n"));
> +  DEBUG ((DEBUG_ERROR, " NO  Prio bb/dd/ff cl/sc Type Stat
> segm:offs\n"));
> +  DEBUG ((DEBUG_ERROR,
> "=============================================\n"));
> +  for (Idx = 0; Idx < BbsCount; Idx++) {
> +    if ((LocalBbsTable[Idx].BootPriority == BBS_IGNORE_ENTRY) ||
> +        (LocalBbsTable[Idx].BootPriority == BBS_DO_NOT_BOOT_FROM) ||
> +        (LocalBbsTable[Idx].BootPriority == BBS_LOWEST_PRIORITY)
> +        ) {
> +      continue;
> +    }
> +
> +    DEBUG (
> +      (DEBUG_ERROR,
> +      " %02x: %04x %02x/%02x/%02x %02x/%02x %04x %04x %04x:%04x\n",
> +      (UINTN) Idx,
> +      (UINTN) LocalBbsTable[Idx].BootPriority,
> +      (UINTN) LocalBbsTable[Idx].Bus,
> +      (UINTN) LocalBbsTable[Idx].Device,
> +      (UINTN) LocalBbsTable[Idx].Function,
> +      (UINTN) LocalBbsTable[Idx].Class,
> +      (UINTN) LocalBbsTable[Idx].SubClass,
> +      (UINTN) LocalBbsTable[Idx].DeviceType,
> +      (UINTN) * (UINT16 *) &LocalBbsTable[Idx].StatusFlags,
> +      (UINTN) LocalBbsTable[Idx].BootHandlerSegment,
> +      (UINTN) LocalBbsTable[Idx].BootHandlerOffset,
> +      (UINTN) ((LocalBbsTable[Idx].MfgStringSegment << 4) +
> LocalBbsTable[Idx].MfgStringOffset),
> +      (UINTN) ((LocalBbsTable[Idx].DescStringSegment << 4) +
> LocalBbsTable[Idx].DescStringOffset))
> +      );
> +  }
> +
> +  DEBUG ((DEBUG_ERROR, "\n"));
> +}
> +
> +/**
> +  Set the boot priority for BBS entries based on boot option entry and boot
> order.
> +
> +  @param  Entry             The boot option is to be checked for refresh BBS
> table.
> +
> +  @retval EFI_SUCCESS           The boot priority for BBS entries is refreshed
> successfully.
> +  @retval EFI_NOT_FOUND         BBS entries can't be found.
> +  @retval EFI_OUT_OF_RESOURCES  Failed to get the legacy device boot
> order.
> +**/
> +EFI_STATUS
> +EFIAPI
> +BdsRefreshBbsTableForBoot (
> +  IN BDS_COMMON_OPTION        *Entry
> +  )
> +{
> +  EFI_STATUS                Status;
> +  UINT16                    BbsIndex;
> +  UINT16                    HddCount;
> +  UINT16                    BbsCount;
> +  HDD_INFO                  *LocalHddInfo;
> +  BBS_TABLE                 *LocalBbsTable;
> +  UINT16                    DevType;
> +  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;
> +  UINTN                     Index;
> +  UINT16                    Priority;
> +  UINT16                    *BootOrder;
> +  UINTN                     BootOrderSize;
> +  UINT8                     *BootOptionVar;
> +  UINTN                     BootOptionSize;
> +  CHAR16                    BootOption[9];
> +  UINT8                     *Ptr;
> +  UINT16                    DevPathLen;
> +  EFI_DEVICE_PATH_PROTOCOL  *DevPath;
> +  UINT16                    *DeviceType;
> +  UINTN                     DeviceTypeCount;
> +  UINTN                     DeviceTypeIndex;
> +
> +  HddCount      = 0;
> +  BbsCount      = 0;
> +  LocalHddInfo  = NULL;
> +  LocalBbsTable = NULL;
> +  DevType       = BBS_UNKNOWN;
> +
> +  Status        = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL,
> (VOID **) &LegacyBios);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  LegacyBios->GetBbsInfo (
> +                LegacyBios,
> +                &HddCount,
> +                &LocalHddInfo,
> +                &BbsCount,
> +                &LocalBbsTable
> +                );
> +  //
> +  // First, set all the present devices' boot priority to
> BBS_UNPRIORITIZED_ENTRY
> +  // We will set them according to the settings setup by user
> +  //
> +  for (Index = 0; Index < BbsCount; Index++) {
> +    if (!((BBS_IGNORE_ENTRY == LocalBbsTable[Index].BootPriority) ||
> +        (BBS_DO_NOT_BOOT_FROM == LocalBbsTable[Index].BootPriority) ||
> +         (BBS_LOWEST_PRIORITY == LocalBbsTable[Index].BootPriority))) {
> +      LocalBbsTable[Index].BootPriority = BBS_UNPRIORITIZED_ENTRY;
> +    }
> +  }
> +  //
> +  // boot priority always starts at 0
> +  //
> +  Priority = 0;
> +  if (Entry->LoadOptionsSize == sizeof (BBS_TABLE) + sizeof (UINT16)) {
> +    //
> +    // If Entry stands for a legacy boot option, we prioritize the devices with
> the same type first.
> +    //
> +    DevType  = ((BBS_TABLE *) Entry->LoadOptions)->DeviceType;
> +    BbsIndex = *(UINT16 *) ((BBS_TABLE *) Entry->LoadOptions + 1);
> +    Status = BdsSetBootPriority4SameTypeDev (
> +              DevType,
> +              BbsIndex,
> +              LocalBbsTable,
> +              &Priority
> +              );
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +  }
> +  //
> +  // we have to set the boot priority for other BBS entries with different
> device types
> +  //
> +  BootOrder = BdsLibGetVariableAndSize (
> +                L"BootOrder",
> +                &gEfiGlobalVariableGuid,
> +                &BootOrderSize
> +                );
> +  DeviceType = AllocatePool (BootOrderSize + sizeof (UINT16));
> +  ASSERT (DeviceType != NULL);
> +
> +  DeviceType[0]   = DevType;
> +  DeviceTypeCount = 1;
> +  for (Index = 0; ((BootOrder != NULL) && (Index < BootOrderSize / sizeof
> (UINT16))); Index++) {
> +    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x",
> BootOrder[Index]);
> +    BootOptionVar = BdsLibGetVariableAndSize (
> +                      BootOption,
> +                      &gEfiGlobalVariableGuid,
> +                      &BootOptionSize
> +                      );
> +    if (NULL == BootOptionVar) {
> +      continue;
> +    }
> +
> +    Ptr = BootOptionVar;
> +
> +    Ptr += sizeof (UINT32);
> +    DevPathLen = *(UINT16 *) Ptr;
> +    Ptr += sizeof (UINT16);
> +    Ptr += StrSize ((UINT16 *) Ptr);
> +    DevPath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
> +    if (BBS_DEVICE_PATH != DevPath->Type || BBS_BBS_DP != DevPath-
> >SubType) {
> +      FreePool (BootOptionVar);
> +      continue;
> +    }
> +
> +    Ptr += DevPathLen;
> +    DevType = ((BBS_TABLE *) Ptr)->DeviceType;
> +    for (DeviceTypeIndex = 0; DeviceTypeIndex < DeviceTypeCount;
> DeviceTypeIndex++) {
> +      if (DeviceType[DeviceTypeIndex] == DevType) {
> +        break;
> +      }
> +    }
> +    if (DeviceTypeIndex < DeviceTypeCount) {
> +      //
> +      // We don't want to process twice for a device type
> +      //
> +      FreePool (BootOptionVar);
> +      continue;
> +    }
> +
> +    DeviceType[DeviceTypeCount] = DevType;
> +    DeviceTypeCount++;
> +
> +    Status = BdsSetBootPriority4SameTypeDev (
> +              DevType,
> +              (UINTN) -1,
> +              LocalBbsTable,
> +              &Priority
> +              );
> +    FreePool (BootOptionVar);
> +    if (EFI_ERROR (Status)) {
> +      break;
> +    }
> +  }
> +
> +  FreePool (DeviceType);
> +
> +  if (BootOrder != NULL) {
> +    FreePool (BootOrder);
> +  }
> +
> +  DEBUG_CODE_BEGIN();
> +    PrintBbsTable (LocalBbsTable, BbsCount);
> +  DEBUG_CODE_END();
> +
> +  return Status;
> +}
> +
> +/**
> +  Boot the legacy system with the boot option
> +
> +  @param  Option                 The legacy boot option which have BBS device
> path
> +
> +  @retval EFI_UNSUPPORTED        There is no legacybios protocol, do not
> support
> +                                 legacy boot.
> +  @retval EFI_STATUS             Return the status of LegacyBios->LegacyBoot ().
> +
> +**/
> +EFI_STATUS
> +BdsLibDoLegacyBoot (
> +  IN  BDS_COMMON_OPTION           *Option
> +  )
> +{
> +  EFI_STATUS                Status;
> +  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;
> +  EFI_EVENT                 LegacyBootEvent;
> +
> +  Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID
> **) &LegacyBios);
> +  if (EFI_ERROR (Status)) {
> +    //
> +    // If no LegacyBios protocol we do not support legacy boot
> +    //
> +    return EFI_UNSUPPORTED;
> +  }
> +  //
> +  // Notes: if we separate the int 19, then we don't need to refresh BBS
> +  //
> +  BdsRefreshBbsTableForBoot (Option);
> +
> +  //
> +  // Write boot to OS performance data for legacy boot.
> +  //
> +  PERF_CODE (
> +    //
> +    // Create an event to be signalled when Legacy Boot occurs to write
> performance data.
> +    //
> +    Status = EfiCreateEventLegacyBootEx(
> +               TPL_NOTIFY,
> +               BmEndOfBdsPerfCode,
> +               NULL,
> +               &LegacyBootEvent
> +               );
> +    ASSERT_EFI_ERROR (Status);
> +  );
> +
> +  DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Legacy Boot: %S\n", Option-
> >Description));
> +  return LegacyBios->LegacyBoot (
> +                      LegacyBios,
> +                      (BBS_BBS_DEVICE_PATH *) Option->DevicePath,
> +                      Option->LoadOptionsSize,
> +                      Option->LoadOptions
> +                      );
> +}
> +
> +/**
> +  Internal function to check if the input boot option is a valid EFI NV
> Boot####.
> +
> +  @param OptionToCheck  Boot option to be checked.
> +
> +  @retval TRUE      This boot option matches a valid EFI NV Boot####.
> +  @retval FALSE     If not.
> +
> +**/
> +BOOLEAN
> +IsBootOptionValidNVVarialbe (
> +  IN  BDS_COMMON_OPTION             *OptionToCheck
> +  )
> +{
> +  LIST_ENTRY        TempList;
> +  BDS_COMMON_OPTION *BootOption;
> +  BOOLEAN           Valid;
> +  CHAR16            OptionName[20];
> +
> +  Valid = FALSE;
> +
> +  InitializeListHead (&TempList);
> +  UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x",
> OptionToCheck->BootCurrent);
> +
> +  BootOption = BdsLibVariableToOption (&TempList, OptionName);
> +  if (BootOption == NULL) {
> +    return FALSE;
> +  }
> +
> +  //
> +  // If the Boot Option Number and Device Path matches, OptionToCheck
> matches a
> +  // valid EFI NV Boot####.
> +  //
> +  if ((OptionToCheck->BootCurrent == BootOption->BootCurrent) &&
> +      (CompareMem (OptionToCheck->DevicePath, BootOption->DevicePath,
> GetDevicePathSize (OptionToCheck->DevicePath)) == 0))
> +      {
> +    Valid = TRUE;
> +  }
> +
> +  FreePool (BootOption);
> +
> +  return Valid;
> +}
> +
> +/**
> +  Check whether a USB device match the specified USB Class device path.
> This
> +  function follows "Load Option Processing" behavior in UEFI specification.
> +
> +  @param UsbIo       USB I/O protocol associated with the USB device.
> +  @param UsbClass    The USB Class device path to match.
> +
> +  @retval TRUE       The USB device match the USB Class device path.
> +  @retval FALSE      The USB device does not match the USB Class device path.
> +
> +**/
> +BOOLEAN
> +BdsMatchUsbClass (
> +  IN EFI_USB_IO_PROTOCOL        *UsbIo,
> +  IN USB_CLASS_DEVICE_PATH      *UsbClass
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  EFI_USB_DEVICE_DESCRIPTOR     DevDesc;
> +  EFI_USB_INTERFACE_DESCRIPTOR  IfDesc;
> +  UINT8                         DeviceClass;
> +  UINT8                         DeviceSubClass;
> +  UINT8                         DeviceProtocol;
> +
> +  if ((DevicePathType (UsbClass) != MESSAGING_DEVICE_PATH) ||
> +      (DevicePathSubType (UsbClass) != MSG_USB_CLASS_DP)){
> +    return FALSE;
> +  }
> +
> +  //
> +  // Check Vendor Id and Product Id.
> +  //
> +  Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &DevDesc);
> +  if (EFI_ERROR (Status)) {
> +    return FALSE;
> +  }
> +
> +  if ((UsbClass->VendorId != 0xffff) &&
> +      (UsbClass->VendorId != DevDesc.IdVendor)) {
> +    return FALSE;
> +  }
> +
> +  if ((UsbClass->ProductId != 0xffff) &&
> +      (UsbClass->ProductId != DevDesc.IdProduct)) {
> +    return FALSE;
> +  }
> +
> +  DeviceClass    = DevDesc.DeviceClass;
> +  DeviceSubClass = DevDesc.DeviceSubClass;
> +  DeviceProtocol = DevDesc.DeviceProtocol;
> +  if (DeviceClass == 0) {
> +    //
> +    // If Class in Device Descriptor is set to 0, use the Class, SubClass and
> +    // Protocol in Interface Descriptor instead.
> +    //
> +    Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &IfDesc);
> +    if (EFI_ERROR (Status)) {
> +      return FALSE;
> +    }
> +
> +    DeviceClass    = IfDesc.InterfaceClass;
> +    DeviceSubClass = IfDesc.InterfaceSubClass;
> +    DeviceProtocol = IfDesc.InterfaceProtocol;
> +  }
> +
> +  //
> +  // Check Class, SubClass and Protocol.
> +  //
> +  if ((UsbClass->DeviceClass != 0xff) &&
> +      (UsbClass->DeviceClass != DeviceClass)) {
> +    return FALSE;
> +  }
> +
> +  if ((UsbClass->DeviceSubClass != 0xff) &&
> +      (UsbClass->DeviceSubClass != DeviceSubClass)) {
> +    return FALSE;
> +  }
> +
> +  if ((UsbClass->DeviceProtocol != 0xff) &&
> +      (UsbClass->DeviceProtocol != DeviceProtocol)) {
> +    return FALSE;
> +  }
> +
> +  return TRUE;
> +}
> +
> +/**
> +  Check whether a USB device match the specified USB WWID device path.
> This
> +  function follows "Load Option Processing" behavior in UEFI specification.
> +
> +  @param UsbIo       USB I/O protocol associated with the USB device.
> +  @param UsbWwid     The USB WWID device path to match.
> +
> +  @retval TRUE       The USB device match the USB WWID device path.
> +  @retval FALSE      The USB device does not match the USB WWID device
> path.
> +
> +**/
> +BOOLEAN
> +BdsMatchUsbWwid (
> +  IN EFI_USB_IO_PROTOCOL        *UsbIo,
> +  IN USB_WWID_DEVICE_PATH       *UsbWwid
> +  )
> +{
> +  EFI_STATUS                   Status;
> +  EFI_USB_DEVICE_DESCRIPTOR    DevDesc;
> +  EFI_USB_INTERFACE_DESCRIPTOR IfDesc;
> +  UINT16                       *LangIdTable;
> +  UINT16                       TableSize;
> +  UINT16                       Index;
> +  CHAR16                       *CompareStr;
> +  UINTN                        CompareLen;
> +  CHAR16                       *SerialNumberStr;
> +  UINTN                        Length;
> +
> +  if ((DevicePathType (UsbWwid) != MESSAGING_DEVICE_PATH) ||
> +      (DevicePathSubType (UsbWwid) != MSG_USB_WWID_DP )){
> +    return FALSE;
> +  }
> +
> +  //
> +  // Check Vendor Id and Product Id.
> +  //
> +  Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &DevDesc);
> +  if (EFI_ERROR (Status)) {
> +    return FALSE;
> +  }
> +  if ((DevDesc.IdVendor != UsbWwid->VendorId) ||
> +      (DevDesc.IdProduct != UsbWwid->ProductId)) {
> +    return FALSE;
> +  }
> +
> +  //
> +  // Check Interface Number.
> +  //
> +  Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &IfDesc);
> +  if (EFI_ERROR (Status)) {
> +    return FALSE;
> +  }
> +  if (IfDesc.InterfaceNumber != UsbWwid->InterfaceNumber) {
> +    return FALSE;
> +  }
> +
> +  //
> +  // Check Serial Number.
> +  //
> +  if (DevDesc.StrSerialNumber == 0) {
> +    return FALSE;
> +  }
> +
> +  //
> +  // Get all supported languages.
> +  //
> +  TableSize = 0;
> +  LangIdTable = NULL;
> +  Status = UsbIo->UsbGetSupportedLanguages (UsbIo, &LangIdTable,
> &TableSize);
> +  if (EFI_ERROR (Status) || (TableSize == 0) || (LangIdTable == NULL)) {
> +    return FALSE;
> +  }
> +
> +  //
> +  // Serial number in USB WWID device path is the last 64-or-less UTF-16
> characters.
> +  //
> +  CompareStr = (CHAR16 *) (UINTN) (UsbWwid + 1);
> +  CompareLen = (DevicePathNodeLength (UsbWwid) - sizeof
> (USB_WWID_DEVICE_PATH)) / sizeof (CHAR16);
> +  if (CompareStr[CompareLen - 1] == L'\0') {
> +    CompareLen--;
> +  }
> +
> +  //
> +  // Compare serial number in each supported language.
> +  //
> +  for (Index = 0; Index < TableSize / sizeof (UINT16); Index++) {
> +    SerialNumberStr = NULL;
> +    Status = UsbIo->UsbGetStringDescriptor (
> +                      UsbIo,
> +                      LangIdTable[Index],
> +                      DevDesc.StrSerialNumber,
> +                      &SerialNumberStr
> +                      );
> +    if (EFI_ERROR (Status) || (SerialNumberStr == NULL)) {
> +      continue;
> +    }
> +
> +    Length = StrLen (SerialNumberStr);
> +    if ((Length >= CompareLen) &&
> +        (CompareMem (SerialNumberStr + Length - CompareLen, CompareStr,
> CompareLen * sizeof (CHAR16)) == 0)) {
> +      FreePool (SerialNumberStr);
> +      return TRUE;
> +    }
> +
> +    FreePool (SerialNumberStr);
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +  Find a USB device path which match the specified short-form device path
> start
> +  with USB Class or USB WWID device path and load the boot file then return
> the
> +  image handle. If ParentDevicePath is NULL, this function will search in all
> USB
> +  devices of the platform. If ParentDevicePath is not NULL,this function will
> only
> +  search in its child devices.
> +
> +  @param ParentDevicePath      The device path of the parent.
> +  @param ShortFormDevicePath   The USB Class or USB WWID device path
> to match.
> +
> +  @return  The image Handle if find load file from specified short-form
> device path
> +           or NULL if not found.
> +
> +**/
> +EFI_HANDLE *
> +BdsFindUsbDevice (
> +  IN EFI_DEVICE_PATH_PROTOCOL   *ParentDevicePath,
> +  IN EFI_DEVICE_PATH_PROTOCOL   *ShortFormDevicePath
> +  )
> +{
> +  EFI_STATUS                Status;
> +  UINTN                     UsbIoHandleCount;
> +  EFI_HANDLE                *UsbIoHandleBuffer;
> +  EFI_DEVICE_PATH_PROTOCOL  *UsbIoDevicePath;
> +  EFI_USB_IO_PROTOCOL       *UsbIo;
> +  UINTN                     Index;
> +  UINTN                     ParentSize;
> +  UINTN                     Size;
> +  EFI_HANDLE                ImageHandle;
> +  EFI_HANDLE                Handle;
> +  EFI_DEVICE_PATH_PROTOCOL  *FullDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL  *NextDevicePath;
> +
> +  FullDevicePath = NULL;
> +  ImageHandle    = NULL;
> +
> +  //
> +  // Get all UsbIo Handles.
> +  //
> +  UsbIoHandleCount = 0;
> +  UsbIoHandleBuffer = NULL;
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gEfiUsbIoProtocolGuid,
> +                  NULL,
> +                  &UsbIoHandleCount,
> +                  &UsbIoHandleBuffer
> +                  );
> +  if (EFI_ERROR (Status) || (UsbIoHandleCount == 0) || (UsbIoHandleBuffer
> == NULL)) {
> +    return NULL;
> +  }
> +
> +  ParentSize = (ParentDevicePath == NULL) ? 0 : GetDevicePathSize
> (ParentDevicePath);
> +  for (Index = 0; Index < UsbIoHandleCount; Index++) {
> +    //
> +    // Get the Usb IO interface.
> +    //
> +    Status = gBS->HandleProtocol(
> +                    UsbIoHandleBuffer[Index],
> +                    &gEfiUsbIoProtocolGuid,
> +                    (VOID **) &UsbIo
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      continue;
> +    }
> +
> +    UsbIoDevicePath = DevicePathFromHandle (UsbIoHandleBuffer[Index]);
> +    if (UsbIoDevicePath == NULL) {
> +      continue;
> +    }
> +
> +    if (ParentDevicePath != NULL) {
> +      //
> +      // Compare starting part of UsbIoHandle's device path with
> ParentDevicePath.
> +      //
> +      Size = GetDevicePathSize (UsbIoDevicePath);
> +      if ((Size < ParentSize) ||
> +          (CompareMem (UsbIoDevicePath, ParentDevicePath, ParentSize -
> END_DEVICE_PATH_LENGTH) != 0)) {
> +        continue;
> +      }
> +    }
> +
> +    if (BdsMatchUsbClass (UsbIo, (USB_CLASS_DEVICE_PATH *)
> ShortFormDevicePath) ||
> +        BdsMatchUsbWwid (UsbIo, (USB_WWID_DEVICE_PATH *)
> ShortFormDevicePath)) {
> +      //
> +      // Try to find if there is the boot file in this DevicePath
> +      //
> +      NextDevicePath = NextDevicePathNode (ShortFormDevicePath);
> +      if (!IsDevicePathEnd (NextDevicePath)) {
> +        FullDevicePath = AppendDevicePath (UsbIoDevicePath,
> NextDevicePath);
> +        //
> +        // Connect the full device path, so that Simple File System protocol
> +        // could be installed for this USB device.
> +        //
> +        BdsLibConnectDevicePath (FullDevicePath);
> +        REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32
> (PcdProgressCodeOsLoaderLoad));
> +        Status = gBS->LoadImage (
> +                       TRUE,
> +                       gImageHandle,
> +                       FullDevicePath,
> +                       NULL,
> +                       0,
> +                       &ImageHandle
> +                       );
> +        FreePool (FullDevicePath);
> +      } else {
> +        FullDevicePath = UsbIoDevicePath;
> +        Status = EFI_NOT_FOUND;
> +      }
> +
> +      //
> +      // If we didn't find an image directly, we need to try as if it is a removable
> device boot option
> +      // and load the image according to the default boot behavior for
> removable device.
> +      //
> +      if (EFI_ERROR (Status)) {
> +        //
> +        // check if there is a bootable removable media could be found in this
> device path ,
> +        // and get the bootable media handle
> +        //
> +        Handle = BdsLibGetBootableHandle(UsbIoDevicePath);
> +        if (Handle == NULL) {
> +          continue;
> +        }
> +        //
> +        // Load the default boot file \EFI\BOOT\boot{machinename}.EFI from
> removable Media
> +        //  machinename is ia32, ia64, x64, ...
> +        //
> +        FullDevicePath = FileDevicePath (Handle,
> EFI_REMOVABLE_MEDIA_FILE_NAME);
> +        if (FullDevicePath != NULL) {
> +          REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32
> (PcdProgressCodeOsLoaderLoad));
> +          Status = gBS->LoadImage (
> +                          TRUE,
> +                          gImageHandle,
> +                          FullDevicePath,
> +                          NULL,
> +                          0,
> +                          &ImageHandle
> +                          );
> +          if (EFI_ERROR (Status)) {
> +            //
> +            // The DevicePath failed, and it's not a valid
> +            // removable media device.
> +            //
> +            continue;
> +          }
> +        } else {
> +          continue;
> +        }
> +      }
> +      break;
> +    }
> +  }
> +
> +  FreePool (UsbIoHandleBuffer);
> +  return ImageHandle;
> +}
> +
> +/**
> +  Expand USB Class or USB WWID device path node to be full device path of
> a USB
> +  device in platform then load the boot file on this full device path and
> return the
> +  image handle.
> +
> +  This function support following 4 cases:
> +  1) Boot Option device path starts with a USB Class or USB WWID device
> path,
> +     and there is no Media FilePath device path in the end.
> +     In this case, it will follow Removable Media Boot Behavior.
> +  2) Boot Option device path starts with a USB Class or USB WWID device
> path,
> +     and ended with Media FilePath device path.
> +  3) Boot Option device path starts with a full device path to a USB Host
> Controller,
> +     contains a USB Class or USB WWID device path node, while not ended
> with Media
> +     FilePath device path. In this case, it will follow Removable Media Boot
> Behavior.
> +  4) Boot Option device path starts with a full device path to a USB Host
> Controller,
> +     contains a USB Class or USB WWID device path node, and ended with
> Media
> +     FilePath device path.
> +
> +  @param  DevicePath    The Boot Option device path.
> +
> +  @return  The image handle of boot file, or NULL if there is no boot file
> found in
> +           the specified USB Class or USB WWID device path.
> +
> +**/
> +EFI_HANDLE *
> +BdsExpandUsbShortFormDevicePath (
> +  IN EFI_DEVICE_PATH_PROTOCOL       *DevicePath
> +  )
> +{
> +  EFI_HANDLE                *ImageHandle;
> +  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL  *ShortFormDevicePath;
> +
> +  //
> +  // Search for USB Class or USB WWID device path node.
> +  //
> +  ShortFormDevicePath = NULL;
> +  ImageHandle         = NULL;
> +  TempDevicePath      = DevicePath;
> +  while (!IsDevicePathEnd (TempDevicePath)) {
> +    if ((DevicePathType (TempDevicePath) == MESSAGING_DEVICE_PATH)
> &&
> +        ((DevicePathSubType (TempDevicePath) == MSG_USB_CLASS_DP) ||
> +         (DevicePathSubType (TempDevicePath) == MSG_USB_WWID_DP))) {
> +      ShortFormDevicePath = TempDevicePath;
> +      break;
> +    }
> +    TempDevicePath = NextDevicePathNode (TempDevicePath);
> +  }
> +
> +  if (ShortFormDevicePath == NULL) {
> +    //
> +    // No USB Class or USB WWID device path node found, do nothing.
> +    //
> +    return NULL;
> +  }
> +
> +  if (ShortFormDevicePath == DevicePath) {
> +    //
> +    // Boot Option device path starts with USB Class or USB WWID device
> path.
> +    //
> +    ImageHandle = BdsFindUsbDevice (NULL, ShortFormDevicePath);
> +    if (ImageHandle == NULL) {
> +      //
> +      // Failed to find a match in existing devices, connect the short form USB
> +      // device path and try again.
> +      //
> +      BdsLibConnectUsbDevByShortFormDP (0xff, ShortFormDevicePath);
> +      ImageHandle = BdsFindUsbDevice (NULL, ShortFormDevicePath);
> +    }
> +  } else {
> +    //
> +    // Boot Option device path contains USB Class or USB WWID device path
> node.
> +    //
> +
> +    //
> +    // Prepare the parent device path for search.
> +    //
> +    TempDevicePath = DuplicateDevicePath (DevicePath);
> +    ASSERT (TempDevicePath != NULL);
> +    SetDevicePathEndNode (((UINT8 *) TempDevicePath) + ((UINTN)
> ShortFormDevicePath - (UINTN) DevicePath));
> +
> +    //
> +    // The USB Host Controller device path is already in Boot Option device
> path
> +    // and USB Bus driver already support RemainingDevicePath starts with
> USB
> +    // Class or USB WWID device path, so just search in existing USB devices
> and
> +    // doesn't perform ConnectController here.
> +    //
> +    ImageHandle = BdsFindUsbDevice (TempDevicePath,
> ShortFormDevicePath);
> +    FreePool (TempDevicePath);
> +  }
> +
> +  return ImageHandle;
> +}
> +
> +/**
> +  Process the boot option follow the UEFI specification and
> +  special treat the legacy boot option with BBS_DEVICE_PATH.
> +
> +  @param  Option                 The boot option need to be processed
> +  @param  DevicePath             The device path which describe where to load
> the
> +                                 boot image or the legacy BBS device path to boot
> +                                 the legacy OS
> +  @param  ExitDataSize           The size of exit data.
> +  @param  ExitData               Data returned when Boot image failed.
> +
> +  @retval EFI_SUCCESS            Boot from the input boot option successfully.
> +  @retval EFI_NOT_FOUND          If the Device Path is not found in the
> system
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BdsLibBootViaBootOption (
> +  IN  BDS_COMMON_OPTION             *Option,
> +  IN  EFI_DEVICE_PATH_PROTOCOL      *DevicePath,
> +  OUT UINTN                         *ExitDataSize,
> +  OUT CHAR16                        **ExitData OPTIONAL
> +  )
> +{
> +  EFI_STATUS                Status;
> +  EFI_STATUS                StatusLogo;
> +  EFI_HANDLE                Handle;
> +  EFI_HANDLE                ImageHandle;
> +  EFI_DEVICE_PATH_PROTOCOL  *FilePath;
> +  EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;
> +  EFI_DEVICE_PATH_PROTOCOL  *WorkingDevicePath;
> +  EFI_ACPI_S3_SAVE_PROTOCOL *AcpiS3Save;
> +  LIST_ENTRY                TempBootLists;
> +  EFI_BOOT_LOGO_PROTOCOL    *BootLogo;
> +
> +  *ExitDataSize = 0;
> +  *ExitData     = NULL;
> +
> +  //
> +  // Notes: this code can be remove after the s3 script table
> +  // hook on the event EVT_SIGNAL_READY_TO_BOOT or
> +  // EVT_SIGNAL_LEGACY_BOOT
> +  //
> +  Status = gBS->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid, NULL, (VOID
> **) &AcpiS3Save);
> +  if (!EFI_ERROR (Status)) {
> +    AcpiS3Save->S3Save (AcpiS3Save, NULL);
> +  }
> +  //
> +  // If it's Device Path that starts with a hard drive path, append it with the
> front part to compose a
> +  // full device path
> +  //
> +  WorkingDevicePath = NULL;
> +  if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) &&
> +      (DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP)) {
> +    WorkingDevicePath = BdsExpandPartitionPartialDevicePathToFull (
> +                          (HARDDRIVE_DEVICE_PATH *)DevicePath
> +                          );
> +    if (WorkingDevicePath != NULL) {
> +      DevicePath = WorkingDevicePath;
> +    }
> +  }
> +
> +  //
> +  // Set Boot Current
> +  //
> +  if (IsBootOptionValidNVVarialbe (Option)) {
> +    //
> +    // For a temporary boot (i.e. a boot by selected a EFI Shell using "Boot
> From File"), Boot Current is actually not valid.
> +    // In this case, "BootCurrent" is not created.
> +    // Only create the BootCurrent variable when it points to a valid Boot####
> variable.
> +    //
> +    SetVariableAndReportStatusCodeOnError (
> +          L"BootCurrent",
> +          &gEfiGlobalVariableGuid,
> +          EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_RUNTIME_ACCESS,
> +          sizeof (UINT16),
> +          &Option->BootCurrent
> +          );
> +  }
> +
> +  //
> +  // Report Status Code to indicate ReadyToBoot event will be signalled
> +  //
> +  REPORT_STATUS_CODE (EFI_PROGRESS_CODE,
> (EFI_SOFTWARE_DXE_BS_DRIVER |
> EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT));
> +
> +  //
> +  // Signal the EVT_SIGNAL_READY_TO_BOOT event
> +  //
> +  EfiSignalEventReadyToBoot();
> +
> +  //
> +  // Expand USB Class or USB WWID device path node to be full device path
> of a USB
> +  // device in platform then load the boot file on this full device path and get
> the
> +  // image handle.
> +  //
> +  ImageHandle = BdsExpandUsbShortFormDevicePath (DevicePath);
> +
> +  //
> +  // Adjust the different type memory page number just before booting
> +  // and save the updated info into the variable for next boot to use
> +  //
> +  BdsSetMemoryTypeInformationVariable ();
> +
> +  //
> +  // By expanding the USB Class or WWID device path, the ImageHandle has
> returnned.
> +  // Here get the ImageHandle for the non USB class or WWID device path.
> +  //
> +  if (ImageHandle == NULL) {
> +    ASSERT (Option->DevicePath != NULL);
> +    if ((DevicePathType (Option->DevicePath) == BBS_DEVICE_PATH) &&
> +        (DevicePathSubType (Option->DevicePath) == BBS_BBS_DP)
> +       ) {
> +      //
> +      // Check to see if we should legacy BOOT. If yes then do the legacy boot
> +      //
> +      return BdsLibDoLegacyBoot (Option);
> +    }
> +
> +    //
> +    // If the boot option point to Internal FV shell, make sure it is valid
> +    //
> +    Status = BdsLibUpdateFvFileDevicePath (&DevicePath,
> &gUefiShellFileGuid);
> +    if (!EFI_ERROR(Status)) {
> +      if (Option->DevicePath != NULL) {
> +        FreePool(Option->DevicePath);
> +      }
> +      Option->DevicePath  = AllocateZeroPool (GetDevicePathSize
> (DevicePath));
> +      ASSERT(Option->DevicePath != NULL);
> +      CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize
> (DevicePath));
> +      //
> +      // Update the shell boot option
> +      //
> +      InitializeListHead (&TempBootLists);
> +      BdsLibRegisterNewOption (&TempBootLists, DevicePath, L"EFI Internal
> Shell", L"BootOrder");
> +
> +      //
> +      // free the temporary device path created by
> BdsLibUpdateFvFileDevicePath()
> +      //
> +      FreePool (DevicePath);
> +      DevicePath = Option->DevicePath;
> +    }
> +
> +    DEBUG_CODE_BEGIN();
> +
> +    if (Option->Description == NULL) {
> +      DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Booting from unknown device
> path\n"));
> +    } else {
> +      DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Booting %S\n", Option-
> >Description));
> +    }
> +
> +    DEBUG_CODE_END();
> +
> +    //
> +    // Report status code for OS Loader LoadImage.
> +    //
> +    REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32
> (PcdProgressCodeOsLoaderLoad));
> +    Status = gBS->LoadImage (
> +                    TRUE,
> +                    gImageHandle,
> +                    DevicePath,
> +                    NULL,
> +                    0,
> +                    &ImageHandle
> +                    );
> +
> +    //
> +    // If we didn't find an image directly, we need to try as if it is a removable
> device boot option
> +    // and load the image according to the default boot behavior for
> removable device.
> +    //
> +    if (EFI_ERROR (Status)) {
> +      //
> +      // check if there is a bootable removable media could be found in this
> device path ,
> +      // and get the bootable media handle
> +      //
> +      Handle = BdsLibGetBootableHandle(DevicePath);
> +      if (Handle != NULL) {
> +        //
> +        // Load the default boot file \EFI\BOOT\boot{machinename}.EFI from
> removable Media
> +        //  machinename is ia32, ia64, x64, ...
> +        //
> +        FilePath = FileDevicePath (Handle,
> EFI_REMOVABLE_MEDIA_FILE_NAME);
> +        if (FilePath != NULL) {
> +          REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32
> (PcdProgressCodeOsLoaderLoad));
> +          Status = gBS->LoadImage (
> +                          TRUE,
> +                          gImageHandle,
> +                          FilePath,
> +                          NULL,
> +                          0,
> +                          &ImageHandle
> +                          );
> +        }
> +      }
> +    }
> +  }
> +  //
> +  // Provide the image with it's load options
> +  //
> +  if ((ImageHandle == NULL) || (EFI_ERROR(Status))) {
> +    //
> +    // Report Status Code to indicate that the failure to load boot option
> +    //
> +    REPORT_STATUS_CODE (
> +      EFI_ERROR_CODE | EFI_ERROR_MINOR,
> +      (EFI_SOFTWARE_DXE_BS_DRIVER |
> EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR)
> +      );
> +    goto Done;
> +  }
> +
> +  Status = gBS->HandleProtocol (ImageHandle,
> &gEfiLoadedImageProtocolGuid, (VOID **) &ImageInfo);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  if (Option->LoadOptionsSize != 0) {
> +    ImageInfo->LoadOptionsSize  = Option->LoadOptionsSize;
> +    ImageInfo->LoadOptions      = Option->LoadOptions;
> +  }
> +
> +  //
> +  // Clean to NULL because the image is loaded directly from the firmwares
> boot manager.
> +  //
> +  ImageInfo->ParentHandle = NULL;
> +
> +  //
> +  // Before calling the image, enable the Watchdog Timer for
> +  // the 5 Minute period
> +  //
> +  gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);
> +
> +  //
> +  // Write boot to OS performance data for UEFI boot
> +  //
> +  PERF_CODE (
> +    BmEndOfBdsPerfCode (NULL, NULL);
> +  );
> +
> +  //
> +  // Report status code for OS Loader StartImage.
> +  //
> +  REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32
> (PcdProgressCodeOsLoaderStart));
> +
> +  Status = gBS->StartImage (ImageHandle, ExitDataSize, ExitData);
> +  DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Image Return Status = %r\n",
> Status));
> +  if (EFI_ERROR (Status)) {
> +    //
> +    // Report Status Code to indicate that boot failure
> +    //
> +    REPORT_STATUS_CODE (
> +      EFI_ERROR_CODE | EFI_ERROR_MINOR,
> +      (EFI_SOFTWARE_DXE_BS_DRIVER |
> EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED)
> +      );
> +  }
> +
> +  //
> +  // Clear the Watchdog Timer after the image returns
> +  //
> +  gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
> +
> +Done:
> +  //
> +  // Set Logo status invalid after trying one boot option
> +  //
> +  BootLogo = NULL;
> +  StatusLogo = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL,
> (VOID **) &BootLogo);
> +  if (!EFI_ERROR (StatusLogo) && (BootLogo != NULL)) {
> +    BootLogo->SetBootLogo (BootLogo, NULL, 0, 0, 0, 0);
> +  }
> +
> +  //
> +  // Clear Boot Current
> +  // Deleting variable with current implementation shouldn't fail.
> +  //
> +  gRT->SetVariable (
> +        L"BootCurrent",
> +        &gEfiGlobalVariableGuid,
> +        EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_RUNTIME_ACCESS,
> +        0,
> +        NULL
> +        );
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Expand a device path that starts with a hard drive media device path node
> to be a
> +  full device path that includes the full hardware path to the device. We
> need
> +  to do this so it can be booted. As an optimization the front match (the part
> point
> +  to the partition node. E.g. ACPI() /PCI()/ATA()/Partition() ) is saved in a
> variable
> +  so a connect all is not required on every boot. All successful history device
> path
> +  which point to partition node (the front part) will be saved.
> +
> +  @param  HardDriveDevicePath    EFI Device Path to boot, if it starts with a
> hard
> +                                 drive media device path.
> +  @return A Pointer to the full device path or NULL if a valid Hard Drive devic
> path
> +          cannot be found.
> +
> +**/
> +EFI_DEVICE_PATH_PROTOCOL *
> +EFIAPI
> +BdsExpandPartitionPartialDevicePathToFull (
> +  IN  HARDDRIVE_DEVICE_PATH      *HardDriveDevicePath
> +  )
> +{
> +  EFI_STATUS                Status;
> +  UINTN                     BlockIoHandleCount;
> +  EFI_HANDLE                *BlockIoBuffer;
> +  EFI_DEVICE_PATH_PROTOCOL  *FullDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL  *BlockIoDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
> +  UINTN                     Index;
> +  UINTN                     InstanceNum;
> +  EFI_DEVICE_PATH_PROTOCOL  *CachedDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL  *TempNewDevicePath;
> +  UINTN                     CachedDevicePathSize;
> +  BOOLEAN                   DeviceExist;
> +  BOOLEAN                   NeedAdjust;
> +  EFI_DEVICE_PATH_PROTOCOL  *Instance;
> +  UINTN                     Size;
> +
> +  FullDevicePath = NULL;
> +  //
> +  // Check if there is prestore HD_BOOT_DEVICE_PATH_VARIABLE_NAME
> variable.
> +  // If exist, search the front path which point to partition node in the
> variable instants.
> +  // If fail to find or HD_BOOT_DEVICE_PATH_VARIABLE_NAME not exist,
> reconnect all and search in all system
> +  //
> +  GetVariable2 (
> +    HD_BOOT_DEVICE_PATH_VARIABLE_NAME,
> +    &gHdBootDevicePathVariablGuid,
> +    (VOID **) &CachedDevicePath,
> +    &CachedDevicePathSize
> +    );
> +
> +  //
> +  // Delete the invalid HD_BOOT_DEVICE_PATH_VARIABLE_NAME variable.
> +  //
> +  if ((CachedDevicePath != NULL) && !IsDevicePathValid (CachedDevicePath,
> CachedDevicePathSize)) {
> +    FreePool (CachedDevicePath);
> +    CachedDevicePath = NULL;
> +    Status = gRT->SetVariable (
> +                    HD_BOOT_DEVICE_PATH_VARIABLE_NAME,
> +                    &gHdBootDevicePathVariablGuid,
> +                    0,
> +                    0,
> +                    NULL
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +  if (CachedDevicePath != NULL) {
> +    TempNewDevicePath = CachedDevicePath;
> +    DeviceExist = FALSE;
> +    NeedAdjust = FALSE;
> +    do {
> +      //
> +      // Check every instance of the variable
> +      // First, check whether the instance contain the partition node, which is
> needed for distinguishing  multi
> +      // partial partition boot option. Second, check whether the instance
> could be connected.
> +      //
> +      Instance  = GetNextDevicePathInstance (&TempNewDevicePath, &Size);
> +      if (MatchPartitionDevicePathNode (Instance, HardDriveDevicePath)) {
> +        //
> +        // Connect the device path instance, the device path point to hard drive
> media device path node
> +        // e.g. ACPI() /PCI()/ATA()/Partition()
> +        //
> +        Status = BdsLibConnectDevicePath (Instance);
> +        if (!EFI_ERROR (Status)) {
> +          DeviceExist = TRUE;
> +          break;
> +        }
> +      }
> +      //
> +      // Come here means the first instance is not matched
> +      //
> +      NeedAdjust = TRUE;
> +      FreePool(Instance);
> +    } while (TempNewDevicePath != NULL);
> +
> +    if (DeviceExist) {
> +      //
> +      // Find the matched device path.
> +      // Append the file path information from the boot option and return the
> fully expanded device path.
> +      //
> +      DevicePath     = NextDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL *)
> HardDriveDevicePath);
> +      FullDevicePath = AppendDevicePath (Instance, DevicePath);
> +
> +      //
> +      // Adjust the HD_BOOT_DEVICE_PATH_VARIABLE_NAME instances
> sequence if the matched one is not first one.
> +      //
> +      if (NeedAdjust) {
> +        //
> +        // First delete the matched instance.
> +        //
> +        TempNewDevicePath = CachedDevicePath;
> +        CachedDevicePath  = BdsLibDelPartMatchInstance (CachedDevicePath,
> Instance );
> +        FreePool (TempNewDevicePath);
> +
> +        //
> +        // Second, append the remaining path after the matched instance
> +        //
> +        TempNewDevicePath = CachedDevicePath;
> +        CachedDevicePath = AppendDevicePathInstance (Instance,
> CachedDevicePath );
> +        FreePool (TempNewDevicePath);
> +        //
> +        // Save the matching Device Path so we don't need to do a connect all
> next time
> +        // Failure to set the variable only impacts the performance when next
> time expanding the short-form device path.
> +        //
> +        Status = gRT->SetVariable (
> +                        HD_BOOT_DEVICE_PATH_VARIABLE_NAME,
> +                        &gHdBootDevicePathVariablGuid,
> +                        EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_NON_VOLATILE,
> +                        GetDevicePathSize (CachedDevicePath),
> +                        CachedDevicePath
> +                        );
> +      }
> +
> +      FreePool (Instance);
> +      FreePool (CachedDevicePath);
> +      return FullDevicePath;
> +    }
> +  }
> +
> +  //
> +  // If we get here we fail to find or
> HD_BOOT_DEVICE_PATH_VARIABLE_NAME not exist, and now we need
> +  // to search all devices in the system for a matched partition
> +  //
> +  BdsLibConnectAllDriversToAllControllers ();
> +  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiBlockIoProtocolGuid,
> NULL, &BlockIoHandleCount, &BlockIoBuffer);
> +  if (EFI_ERROR (Status) || BlockIoHandleCount == 0 || BlockIoBuffer ==
> NULL) {
> +    //
> +    // If there was an error or there are no device handles that support
> +    // the BLOCK_IO Protocol, then return.
> +    //
> +    return NULL;
> +  }
> +  //
> +  // Loop through all the device handles that support the BLOCK_IO Protocol
> +  //
> +  for (Index = 0; Index < BlockIoHandleCount; Index++) {
> +
> +    Status = gBS->HandleProtocol (BlockIoBuffer[Index],
> &gEfiDevicePathProtocolGuid, (VOID *) &BlockIoDevicePath);
> +    if (EFI_ERROR (Status) || BlockIoDevicePath == NULL) {
> +      continue;
> +    }
> +
> +    if (MatchPartitionDevicePathNode (BlockIoDevicePath,
> HardDriveDevicePath)) {
> +      //
> +      // Find the matched partition device path
> +      //
> +      DevicePath    = NextDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL *)
> HardDriveDevicePath);
> +      FullDevicePath = AppendDevicePath (BlockIoDevicePath, DevicePath);
> +
> +      //
> +      // Save the matched partition device path in
> HD_BOOT_DEVICE_PATH_VARIABLE_NAME variable
> +      //
> +      if (CachedDevicePath != NULL) {
> +        //
> +        // Save the matched partition device path as first instance of
> HD_BOOT_DEVICE_PATH_VARIABLE_NAME variable
> +        //
> +        if (BdsLibMatchDevicePaths (CachedDevicePath, BlockIoDevicePath)) {
> +          TempNewDevicePath = CachedDevicePath;
> +          CachedDevicePath = BdsLibDelPartMatchInstance (CachedDevicePath,
> BlockIoDevicePath);
> +          FreePool(TempNewDevicePath);
> +        }
> +
> +        if (CachedDevicePath != NULL) {
> +          TempNewDevicePath = CachedDevicePath;
> +          CachedDevicePath = AppendDevicePathInstance (BlockIoDevicePath,
> CachedDevicePath);
> +          FreePool(TempNewDevicePath);
> +        } else {
> +          CachedDevicePath = DuplicateDevicePath (BlockIoDevicePath);
> +        }
> +
> +        //
> +        // Here limit the device path instance number to 12, which is max
> number for a system support 3 IDE controller
> +        // If the user try to boot many OS in different HDs or partitions, in
> theory,
> +        // the HD_BOOT_DEVICE_PATH_VARIABLE_NAME variable maybe
> become larger and larger.
> +        //
> +        InstanceNum = 0;
> +        ASSERT (CachedDevicePath != NULL);
> +        TempNewDevicePath = CachedDevicePath;
> +        while (!IsDevicePathEnd (TempNewDevicePath)) {
> +          TempNewDevicePath = NextDevicePathNode (TempNewDevicePath);
> +          //
> +          // Parse one instance
> +          //
> +          while (!IsDevicePathEndType (TempNewDevicePath)) {
> +            TempNewDevicePath = NextDevicePathNode (TempNewDevicePath);
> +          }
> +          InstanceNum++;
> +          //
> +          // If the CachedDevicePath variable contain too much instance, only
> remain 12 instances.
> +          //
> +          if (InstanceNum >= 12) {
> +            SetDevicePathEndNode (TempNewDevicePath);
> +            break;
> +          }
> +        }
> +      } else {
> +        CachedDevicePath = DuplicateDevicePath (BlockIoDevicePath);
> +      }
> +
> +      //
> +      // Save the matching Device Path so we don't need to do a connect all
> next time
> +      // Failure to set the variable only impacts the performance when next
> time expanding the short-form device path.
> +      //
> +      Status = gRT->SetVariable (
> +                      HD_BOOT_DEVICE_PATH_VARIABLE_NAME,
> +                      &gHdBootDevicePathVariablGuid,
> +                      EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_NON_VOLATILE,
> +                      GetDevicePathSize (CachedDevicePath),
> +                      CachedDevicePath
> +                      );
> +
> +      break;
> +    }
> +  }
> +
> +  if (CachedDevicePath != NULL) {
> +    FreePool (CachedDevicePath);
> +  }
> +  if (BlockIoBuffer != NULL) {
> +    FreePool (BlockIoBuffer);
> +  }
> +  return FullDevicePath;
> +}
> +
> +/**
> +  Check whether there is a instance in BlockIoDevicePath, which contain
> multi device path
> +  instances, has the same partition node with HardDriveDevicePath device
> path
> +
> +  @param  BlockIoDevicePath      Multi device path instances which need to
> check
> +  @param  HardDriveDevicePath    A device path which starts with a hard
> drive media
> +                                 device path.
> +
> +  @retval TRUE                   There is a matched device path instance.
> +  @retval FALSE                  There is no matched device path instance.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +MatchPartitionDevicePathNode (
> +  IN  EFI_DEVICE_PATH_PROTOCOL   *BlockIoDevicePath,
> +  IN  HARDDRIVE_DEVICE_PATH      *HardDriveDevicePath
> +  )
> +{
> +  HARDDRIVE_DEVICE_PATH     *TmpHdPath;
> +  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
> +  BOOLEAN                   Match;
> +  EFI_DEVICE_PATH_PROTOCOL  *BlockIoHdDevicePathNode;
> +
> +  if ((BlockIoDevicePath == NULL) || (HardDriveDevicePath == NULL)) {
> +    return FALSE;
> +  }
> +
> +  //
> +  // Make PreviousDevicePath == the device path node before the end
> node
> +  //
> +  DevicePath              = BlockIoDevicePath;
> +  BlockIoHdDevicePathNode = NULL;
> +
> +  //
> +  // find the partition device path node
> +  //
> +  while (!IsDevicePathEnd (DevicePath)) {
> +    if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) &&
> +        (DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP)
> +        ) {
> +      BlockIoHdDevicePathNode = DevicePath;
> +      break;
> +    }
> +
> +    DevicePath = NextDevicePathNode (DevicePath);
> +  }
> +
> +  if (BlockIoHdDevicePathNode == NULL) {
> +    return FALSE;
> +  }
> +  //
> +  // See if the harddrive device path in blockio matches the orig Hard Drive
> Node
> +  //
> +  TmpHdPath = (HARDDRIVE_DEVICE_PATH *) BlockIoHdDevicePathNode;
> +  Match = FALSE;
> +
> +  //
> +  // Check for the match
> +  //
> +  if ((TmpHdPath->MBRType == HardDriveDevicePath->MBRType) &&
> +      (TmpHdPath->SignatureType == HardDriveDevicePath->SignatureType))
> {
> +    switch (TmpHdPath->SignatureType) {
> +    case SIGNATURE_TYPE_GUID:
> +      Match = CompareGuid ((EFI_GUID *)TmpHdPath->Signature, (EFI_GUID
> *)HardDriveDevicePath->Signature);
> +      break;
> +    case SIGNATURE_TYPE_MBR:
> +      Match = (BOOLEAN)(*((UINT32 *)(&(TmpHdPath->Signature[0]))) ==
> ReadUnaligned32((UINT32 *)(&(HardDriveDevicePath->Signature[0]))));
> +      break;
> +    default:
> +      Match = FALSE;
> +      break;
> +    }
> +  }
> +
> +  return Match;
> +}
> +
> +/**
> +  Delete the boot option associated with the handle passed in.
> +
> +  @param  Handle                 The handle which present the device path to
> create
> +                                 boot option
> +
> +  @retval EFI_SUCCESS            Delete the boot option success
> +  @retval EFI_NOT_FOUND          If the Device Path is not found in the
> system
> +  @retval EFI_OUT_OF_RESOURCES   Lack of memory resource
> +  @retval Other                  Error return value from SetVariable()
> +
> +**/
> +EFI_STATUS
> +BdsLibDeleteOptionFromHandle (
> +  IN  EFI_HANDLE                 Handle
> +  )
> +{
> +  UINT16                    *BootOrder;
> +  UINT8                     *BootOptionVar;
> +  UINTN                     BootOrderSize;
> +  UINTN                     BootOptionSize;
> +  EFI_STATUS                Status;
> +  UINTN                     Index;
> +  UINT16                    BootOption[BOOT_OPTION_MAX_CHAR];
> +  UINTN                     DevicePathSize;
> +  UINTN                     OptionDevicePathSize;
> +  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL  *OptionDevicePath;
> +  UINT8                     *TempPtr;
> +
> +  Status        = EFI_SUCCESS;
> +  BootOrder     = NULL;
> +  BootOrderSize = 0;
> +
> +  //
> +  // Check "BootOrder" variable, if no, means there is no any boot order.
> +  //
> +  BootOrder = BdsLibGetVariableAndSize (
> +                L"BootOrder",
> +                &gEfiGlobalVariableGuid,
> +                &BootOrderSize
> +                );
> +  if (BootOrder == NULL) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  //
> +  // Convert device handle to device path protocol instance
> +  //
> +  DevicePath = DevicePathFromHandle (Handle);
> +  if (DevicePath == NULL) {
> +    return EFI_NOT_FOUND;
> +  }
> +  DevicePathSize = GetDevicePathSize (DevicePath);
> +
> +  //
> +  // Loop all boot order variable and find the matching device path
> +  //
> +  Index = 0;
> +  while (Index < BootOrderSize / sizeof (UINT16)) {
> +    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x",
> BootOrder[Index]);
> +    BootOptionVar = BdsLibGetVariableAndSize (
> +                      BootOption,
> +                      &gEfiGlobalVariableGuid,
> +                      &BootOptionSize
> +                      );
> +
> +    if (BootOptionVar == NULL) {
> +      FreePool (BootOrder);
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +
> +    if (!ValidateOption(BootOptionVar, BootOptionSize)) {
> +      BdsDeleteBootOption (BootOrder[Index], BootOrder, &BootOrderSize);
> +      FreePool (BootOptionVar);
> +      Index++;
> +      continue;
> +    }
> +
> +    TempPtr = BootOptionVar;
> +    TempPtr += sizeof (UINT32) + sizeof (UINT16);
> +    TempPtr += StrSize ((CHAR16 *) TempPtr);
> +    OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
> +    OptionDevicePathSize = GetDevicePathSize (OptionDevicePath);
> +
> +    //
> +    // Check whether the device path match
> +    //
> +    if ((OptionDevicePathSize == DevicePathSize) &&
> +        (CompareMem (DevicePath, OptionDevicePath, DevicePathSize) == 0))
> {
> +      BdsDeleteBootOption (BootOrder[Index], BootOrder, &BootOrderSize);
> +      FreePool (BootOptionVar);
> +      break;
> +    }
> +
> +    FreePool (BootOptionVar);
> +    Index++;
> +  }
> +
> +  //
> +  // Adjust number of boot option for "BootOrder" variable.
> +  //
> +  Status = gRT->SetVariable (
> +                  L"BootOrder",
> +                  &gEfiGlobalVariableGuid,
> +                  EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
> +                  BootOrderSize,
> +                  BootOrder
> +                  );
> +  //
> +  // Shrinking variable with existing variable implementation shouldn't fail.
> +  //
> +  ASSERT_EFI_ERROR (Status);
> +
> +  FreePool (BootOrder);
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Delete all invalid EFI boot options.
> +
> +  @retval EFI_SUCCESS            Delete all invalid boot option success
> +  @retval EFI_NOT_FOUND          Variable "BootOrder" is not found
> +  @retval EFI_OUT_OF_RESOURCES   Lack of memory resource
> +  @retval Other                  Error return value from SetVariable()
> +
> +**/
> +EFI_STATUS
> +BdsDeleteAllInvalidEfiBootOption (
> +  VOID
> +  )
> +{
> +  UINT16                    *BootOrder;
> +  UINT8                     *BootOptionVar;
> +  UINTN                     BootOrderSize;
> +  UINTN                     BootOptionSize;
> +  EFI_STATUS                Status;
> +  UINTN                     Index;
> +  UINTN                     Index2;
> +  UINT16                    BootOption[BOOT_OPTION_MAX_CHAR];
> +  EFI_DEVICE_PATH_PROTOCOL  *OptionDevicePath;
> +  UINT8                     *TempPtr;
> +  CHAR16                    *Description;
> +  BOOLEAN                   Corrupted;
> +
> +  Status           = EFI_SUCCESS;
> +  BootOrder        = NULL;
> +  Description      = NULL;
> +  OptionDevicePath = NULL;
> +  BootOrderSize    = 0;
> +  Corrupted        = FALSE;
> +
> +  //
> +  // Check "BootOrder" variable firstly, this variable hold the number of boot
> options
> +  //
> +  BootOrder = BdsLibGetVariableAndSize (
> +                L"BootOrder",
> +                &gEfiGlobalVariableGuid,
> +                &BootOrderSize
> +                );
> +  if (NULL == BootOrder) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  Index = 0;
> +  while (Index < BootOrderSize / sizeof (UINT16)) {
> +    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x",
> BootOrder[Index]);
> +    BootOptionVar = BdsLibGetVariableAndSize (
> +                      BootOption,
> +                      &gEfiGlobalVariableGuid,
> +                      &BootOptionSize
> +                      );
> +    if (NULL == BootOptionVar) {
> +      FreePool (BootOrder);
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +
> +    if (!ValidateOption(BootOptionVar, BootOptionSize)) {
> +      Corrupted = TRUE;
> +    } else {
> +      TempPtr = BootOptionVar;
> +      TempPtr += sizeof (UINT32) + sizeof (UINT16);
> +      Description = (CHAR16 *) TempPtr;
> +      TempPtr += StrSize ((CHAR16 *) TempPtr);
> +      OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
> +
> +      //
> +      // Skip legacy boot option (BBS boot device)
> +      //
> +      if ((DevicePathType (OptionDevicePath) == BBS_DEVICE_PATH) &&
> +          (DevicePathSubType (OptionDevicePath) == BBS_BBS_DP)) {
> +        FreePool (BootOptionVar);
> +        Index++;
> +        continue;
> +      }
> +    }
> +
> +    if (Corrupted || !BdsLibIsValidEFIBootOptDevicePathExt
> (OptionDevicePath, FALSE, Description)) {
> +      //
> +      // Delete this invalid boot option "Boot####"
> +      //
> +      Status = gRT->SetVariable (
> +                      BootOption,
> +                      &gEfiGlobalVariableGuid,
> +                      EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
> +                      0,
> +                      NULL
> +                      );
> +      //
> +      // Deleting variable with current variable implementation shouldn't fail.
> +      //
> +      ASSERT_EFI_ERROR (Status);
> +      //
> +      // Mark this boot option in boot order as deleted
> +      //
> +      BootOrder[Index] = 0xffff;
> +      Corrupted        = FALSE;
> +    }
> +
> +    FreePool (BootOptionVar);
> +    Index++;
> +  }
> +
> +  //
> +  // Adjust boot order array
> +  //
> +  Index2 = 0;
> +  for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {
> +    if (BootOrder[Index] != 0xffff) {
> +      BootOrder[Index2] = BootOrder[Index];
> +      Index2 ++;
> +    }
> +  }
> +  Status = gRT->SetVariable (
> +                  L"BootOrder",
> +                  &gEfiGlobalVariableGuid,
> +                  EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
> +                  Index2 * sizeof (UINT16),
> +                  BootOrder
> +                  );
> +  //
> +  // Shrinking variable with current variable implementation shouldn't fail.
> +  //
> +  ASSERT_EFI_ERROR (Status);
> +
> +  FreePool (BootOrder);
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  For EFI boot option, BDS separate them as six types:
> +  1. Network - The boot option points to the SimpleNetworkProtocol device.
> +               Bds will try to automatically create this type boot option when
> enumerate.
> +  2. Shell   - The boot option points to internal flash shell.
> +               Bds will try to automatically create this type boot option when
> enumerate.
> +  3. Removable BlockIo      - The boot option only points to the removable
> media
> +                              device, like USB flash disk, DVD, Floppy etc.
> +                              These device should contain a *removable* blockIo
> +                              protocol in their device handle.
> +                              Bds will try to automatically create this type boot option
> +                              when enumerate.
> +  4. Fixed BlockIo          - The boot option only points to a Fixed blockIo device,
> +                              like HardDisk.
> +                              These device should contain a *fixed* blockIo
> +                              protocol in their device handle.
> +                              BDS will skip fixed blockIo devices, and NOT
> +                              automatically create boot option for them. But BDS
> +                              will help to delete those fixed blockIo boot option,
> +                              whose description rule conflict with other auto-created
> +                              boot options.
> +  5. Non-BlockIo Simplefile - The boot option points to a device whose
> handle
> +                              has SimpleFileSystem Protocol, but has no blockio
> +                              protocol. These devices do not offer blockIo
> +                              protocol, but BDS still can get the
> +                              \EFI\BOOT\boot{machinename}.EFI by SimpleFileSystem
> +                              Protocol.
> +  6. File    - The boot option points to a file. These boot options are usually
> +               created by user manually or OS loader. BDS will not delete or modify
> +               these boot options.
> +
> +  This function will enumerate all possible boot device in the system, and
> +  automatically create boot options for Network, Shell, Removable BlockIo,
> +  and Non-BlockIo Simplefile devices.
> +  It will only execute once of every boot.
> +
> +  @param  BdsBootOptionList      The header of the link list which indexed all
> +                                 current boot options
> +
> +  @retval EFI_SUCCESS            Finished all the boot device enumerate and
> create
> +                                 the boot option base on that boot device
> +
> +  @retval EFI_OUT_OF_RESOURCES   Failed to enumerate the boot device
> and create the boot option list
> +**/
> +EFI_STATUS
> +EFIAPI
> +BdsLibEnumerateAllBootOption (
> +  IN OUT LIST_ENTRY          *BdsBootOptionList
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  UINT16                        FloppyNumber;
> +  UINT16                        HarddriveNumber;
> +  UINT16                        CdromNumber;
> +  UINT16                        UsbNumber;
> +  UINT16                        MiscNumber;
> +  UINT16                        ScsiNumber;
> +  UINT16                        NonBlockNumber;
> +  UINTN                         NumberBlockIoHandles;
> +  EFI_HANDLE                    *BlockIoHandles;
> +  EFI_BLOCK_IO_PROTOCOL         *BlkIo;
> +  BOOLEAN                       Removable[2];
> +  UINTN                         RemovableIndex;
> +  UINTN                         Index;
> +  UINTN                         NumOfLoadFileHandles;
> +  EFI_HANDLE                    *LoadFileHandles;
> +  UINTN                         FvHandleCount;
> +  EFI_HANDLE                    *FvHandleBuffer;
> +  EFI_FV_FILETYPE               Type;
> +  UINTN                         Size;
> +  EFI_FV_FILE_ATTRIBUTES        Attributes;
> +  UINT32                        AuthenticationStatus;
> +  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
> +  EFI_DEVICE_PATH_PROTOCOL      *DevicePath;
> +  UINTN                         DevicePathType;
> +  CHAR16                        Buffer[40];
> +  EFI_HANDLE                    *FileSystemHandles;
> +  UINTN                         NumberFileSystemHandles;
> +  BOOLEAN                       NeedDelete;
> +  EFI_IMAGE_DOS_HEADER          DosHeader;
> +  CHAR8                         *PlatLang;
> +  CHAR8                         *LastLang;
> +  EFI_IMAGE_OPTIONAL_HEADER_UNION       HdrData;
> +  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;
> +  CHAR16                        *MacStr;
> +  CHAR16                        *IPverStr;
> +  EFI_HANDLE                    *NetworkHandles;
> +  UINTN                         BufferSize;
> +
> +  FloppyNumber    = 0;
> +  HarddriveNumber = 0;
> +  CdromNumber     = 0;
> +  UsbNumber       = 0;
> +  MiscNumber      = 0;
> +  ScsiNumber      = 0;
> +  PlatLang        = NULL;
> +  LastLang        = NULL;
> +  ZeroMem (Buffer, sizeof (Buffer));
> +
> +  //
> +  // If the boot device enumerate happened, just get the boot
> +  // device from the boot order variable
> +  //
> +  if (mEnumBootDevice) {
> +    GetVariable2 (LAST_ENUM_LANGUAGE_VARIABLE_NAME,
> &gLastEnumLangGuid, (VOID**)&LastLang, NULL);
> +    GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&PlatLang, NULL);
> +    ASSERT (PlatLang != NULL);
> +    if ((LastLang != NULL) && (AsciiStrCmp (LastLang, PlatLang) == 0)) {
> +      Status = BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");
> +      FreePool (LastLang);
> +      FreePool (PlatLang);
> +      return Status;
> +    } else {
> +      Status = gRT->SetVariable (
> +        LAST_ENUM_LANGUAGE_VARIABLE_NAME,
> +        &gLastEnumLangGuid,
> +        EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
> +        AsciiStrSize (PlatLang),
> +        PlatLang
> +        );
> +      //
> +      // Failure to set the variable only impacts the performance next time
> enumerating the boot options.
> +      //
> +
> +      if (LastLang != NULL) {
> +        FreePool (LastLang);
> +      }
> +      FreePool (PlatLang);
> +    }
> +  }
> +
> +  //
> +  // Notes: this dirty code is to get the legacy boot option from the
> +  // BBS table and create to variable as the EFI boot option, it should
> +  // be removed after the CSM can provide legacy boot option directly
> +  //
> +  REFRESH_LEGACY_BOOT_OPTIONS;
> +
> +  //
> +  // Delete invalid boot option
> +  //
> +  BdsDeleteAllInvalidEfiBootOption ();
> +
> +  //
> +  // Parse removable media followed by fixed media.
> +  // The Removable[] array is used by the for-loop below to create
> removable media boot options
> +  // at first, and then to create fixed media boot options.
> +  //
> +  Removable[0]  = FALSE;
> +  Removable[1]  = TRUE;
> +
> +  gBS->LocateHandleBuffer (
> +        ByProtocol,
> +        &gEfiBlockIoProtocolGuid,
> +        NULL,
> +        &NumberBlockIoHandles,
> +        &BlockIoHandles
> +        );
> +
> +  for (RemovableIndex = 0; RemovableIndex < 2; RemovableIndex++) {
> +    for (Index = 0; Index < NumberBlockIoHandles; Index++) {
> +      Status = gBS->HandleProtocol (
> +                      BlockIoHandles[Index],
> +                      &gEfiBlockIoProtocolGuid,
> +                      (VOID **) &BlkIo
> +                      );
> +      //
> +      // skip the logical partition
> +      //
> +      if (EFI_ERROR (Status) || BlkIo->Media->LogicalPartition) {
> +        continue;
> +      }
> +
> +      //
> +      // firstly fixed block io then the removable block io
> +      //
> +      if (BlkIo->Media->RemovableMedia == Removable[RemovableIndex]) {
> +        continue;
> +      }
> +      DevicePath  = DevicePathFromHandle (BlockIoHandles[Index]);
> +      DevicePathType = BdsGetBootTypeFromDevicePath (DevicePath);
> +
> +      switch (DevicePathType) {
> +      case BDS_EFI_ACPI_FLOPPY_BOOT:
> +        if (FloppyNumber != 0) {
> +          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_FLOPPY)), FloppyNumber);
> +        } else {
> +          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_FLOPPY)));
> +        }
> +        BdsLibBuildOptionFromHandle (BlockIoHandles[Index],
> BdsBootOptionList, Buffer);
> +        FloppyNumber++;
> +        break;
> +
> +      //
> +      // Assume a removable SATA device should be the DVD/CD device, a
> fixed SATA device should be the Hard Drive device.
> +      //
> +      case BDS_EFI_MESSAGE_ATAPI_BOOT:
> +      case BDS_EFI_MESSAGE_SATA_BOOT:
> +        if (BlkIo->Media->RemovableMedia) {
> +          if (CdromNumber != 0) {
> +            UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_CD_DVD)), CdromNumber);
> +          } else {
> +            UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_CD_DVD)));
> +          }
> +          CdromNumber++;
> +        } else {
> +          if (HarddriveNumber != 0) {
> +            UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_HARDDRIVE)), HarddriveNumber);
> +          } else {
> +            UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_HARDDRIVE)));
> +          }
> +          HarddriveNumber++;
> +        }
> +        DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Buffer: %S\n", Buffer));
> +        BdsLibBuildOptionFromHandle (BlockIoHandles[Index],
> BdsBootOptionList, Buffer);
> +        break;
> +
> +      case BDS_EFI_MESSAGE_USB_DEVICE_BOOT:
> +        if (UsbNumber != 0) {
> +          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_USB)), UsbNumber);
> +        } else {
> +          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_USB)));
> +        }
> +        BdsLibBuildOptionFromHandle (BlockIoHandles[Index],
> BdsBootOptionList, Buffer);
> +        UsbNumber++;
> +        break;
> +
> +      case BDS_EFI_MESSAGE_SCSI_BOOT:
> +        if (ScsiNumber != 0) {
> +          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_SCSI)), ScsiNumber);
> +        } else {
> +          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_SCSI)));
> +        }
> +        BdsLibBuildOptionFromHandle (BlockIoHandles[Index],
> BdsBootOptionList, Buffer);
> +        ScsiNumber++;
> +        break;
> +
> +      case BDS_EFI_MESSAGE_MISC_BOOT:
> +      default:
> +        if (MiscNumber != 0) {
> +          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_MISC)), MiscNumber);
> +        } else {
> +          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_MISC)));
> +        }
> +        BdsLibBuildOptionFromHandle (BlockIoHandles[Index],
> BdsBootOptionList, Buffer);
> +        MiscNumber++;
> +        break;
> +      }
> +    }
> +  }
> +
> +  if (NumberBlockIoHandles != 0) {
> +    FreePool (BlockIoHandles);
> +  }
> +
> +  //
> +  // If there is simple file protocol which does not consume block Io protocol,
> create a boot option for it here.
> +  //
> +  NonBlockNumber = 0;
> +  gBS->LocateHandleBuffer (
> +        ByProtocol,
> +        &gEfiSimpleFileSystemProtocolGuid,
> +        NULL,
> +        &NumberFileSystemHandles,
> +        &FileSystemHandles
> +        );
> +  for (Index = 0; Index < NumberFileSystemHandles; Index++) {
> +    Status = gBS->HandleProtocol (
> +                    FileSystemHandles[Index],
> +                    &gEfiBlockIoProtocolGuid,
> +                    (VOID **) &BlkIo
> +                    );
> +     if (!EFI_ERROR (Status)) {
> +      //
> +      //  Skip if the file system handle supports a BlkIo protocol,
> +      //
> +      continue;
> +    }
> +
> +    //
> +    // Do the removable Media thing. \EFI\BOOT\boot{machinename}.EFI
> +    //  machinename is ia32, ia64, x64, ...
> +    //
> +    Hdr.Union  = &HdrData;
> +    NeedDelete = TRUE;
> +    Status     = BdsLibGetImageHeader (
> +                   FileSystemHandles[Index],
> +                   EFI_REMOVABLE_MEDIA_FILE_NAME,
> +                   &DosHeader,
> +                   Hdr
> +                   );
> +    if (!EFI_ERROR (Status) &&
> +        EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr.Pe32-
> >FileHeader.Machine) &&
> +        Hdr.Pe32->OptionalHeader.Subsystem ==
> EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {
> +      NeedDelete = FALSE;
> +    }
> +
> +    if (NeedDelete) {
> +      //
> +      // No such file or the file is not a EFI application, delete this boot option
> +      //
> +      BdsLibDeleteOptionFromHandle (FileSystemHandles[Index]);
> +    } else {
> +      if (NonBlockNumber != 0) {
> +        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_NON_BLOCK)), NonBlockNumber);
> +      } else {
> +        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_NON_BLOCK)));
> +      }
> +      BdsLibBuildOptionFromHandle (FileSystemHandles[Index],
> BdsBootOptionList, Buffer);
> +      NonBlockNumber++;
> +    }
> +  }
> +
> +  if (NumberFileSystemHandles != 0) {
> +    FreePool (FileSystemHandles);
> +  }
> +
> +  //
> +  // Parse Network Boot Device
> +  //
> +  NumOfLoadFileHandles = 0;
> +  //
> +  // Search Load File protocol for PXE boot option.
> +  //
> +  gBS->LocateHandleBuffer (
> +        ByProtocol,
> +        &gEfiLoadFileProtocolGuid,
> +        NULL,
> +        &NumOfLoadFileHandles,
> +        &LoadFileHandles
> +        );
> +
> +  for (Index = 0; Index < NumOfLoadFileHandles; Index++) {
> +
> +//
> +//Locate EFI_DEVICE_PATH_PROTOCOL to dynamically get IPv4/IPv6
> protocol information.
> +//
> +
> + Status = gBS->HandleProtocol (
> +                  LoadFileHandles[Index],
> +                  &gEfiDevicePathProtocolGuid,
> +                  (VOID **) &DevicePath
> +                  );
> +
> + ASSERT_EFI_ERROR (Status);
> +
> +  while (!IsDevicePathEnd (DevicePath)) {
> +    if ((DevicePath->Type == MESSAGING_DEVICE_PATH) &&
> +        (DevicePath->SubType == MSG_IPv4_DP)) {
> +
> +  //
> +  //Get handle infomation
> +  //
> +  BufferSize = 0;
> +  NetworkHandles = NULL;
> +  Status = gBS->LocateHandle (
> +                  ByProtocol,
> +                  &gEfiSimpleNetworkProtocolGuid,
> +                  NULL,
> +                  &BufferSize,
> +                  NetworkHandles
> +                  );
> +
> +  if (Status == EFI_BUFFER_TOO_SMALL) {
> +    NetworkHandles = AllocateZeroPool(BufferSize);
> +    if (NetworkHandles == NULL) {
> +      return (EFI_OUT_OF_RESOURCES);
> +    }
> +    Status = gBS->LocateHandle(
> +                    ByProtocol,
> +                    &gEfiSimpleNetworkProtocolGuid,
> +                    NULL,
> +                    &BufferSize,
> +                    NetworkHandles
> +                    );
> + }
> +
> +  //
> +  //Get the MAC string
> +  //
> +  Status = NetLibGetMacString (
> +             *NetworkHandles,
> +             NULL,
> +             &MacStr
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  IPverStr = L" IPv4";
> +  UnicodeSPrint (Buffer, sizeof (Buffer), L"%s%s%s", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_NETWORK)),MacStr,IPverStr);
> +  break;
> +  }
> +    if((DevicePath->Type == MESSAGING_DEVICE_PATH) &&
> +        (DevicePath->SubType == MSG_IPv6_DP)) {
> +
> +  //
> +  //Get handle infomation
> +  //
> +  BufferSize = 0;
> +  NetworkHandles = NULL;
> +  Status = gBS->LocateHandle (
> +                  ByProtocol,
> +                  &gEfiSimpleNetworkProtocolGuid,
> +                  NULL,
> +                  &BufferSize,
> +                  NetworkHandles
> +                  );
> +
> +  if (Status == EFI_BUFFER_TOO_SMALL) {
> +    NetworkHandles = AllocateZeroPool(BufferSize);
> +    if (NetworkHandles == NULL) {
> +       return (EFI_OUT_OF_RESOURCES);
> +    }
> +    Status = gBS->LocateHandle(
> +                    ByProtocol,
> +                    &gEfiSimpleNetworkProtocolGuid,
> +                    NULL,
> +                    &BufferSize,
> +                    NetworkHandles
> +                    );
> + }
> +
> +  //
> +  //Get the MAC string
> +  //
> +  Status = NetLibGetMacString (
> +             *NetworkHandles,
> +             NULL,
> +             &MacStr
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +      IPverStr = L" IPv6";
> +      UnicodeSPrint (Buffer, sizeof (Buffer), L"%s%s%s", BdsLibGetStringById
> (STRING_TOKEN (STR_DESCRIPTION_NETWORK)),MacStr,IPverStr);
> +      break;
> +    }
> +    DevicePath = NextDevicePathNode (DevicePath);
> +  }
> +
> +    BdsLibBuildOptionFromHandle (LoadFileHandles[Index],
> BdsBootOptionList, Buffer);
> +  }
> +
> +  if (NumOfLoadFileHandles != 0) {
> +    FreePool (LoadFileHandles);
> +  }
> +
> +  //
> +  // Check if we have on flash shell
> +  //
> +  gBS->LocateHandleBuffer (
> +        ByProtocol,
> +        &gEfiFirmwareVolume2ProtocolGuid,
> +        NULL,
> +        &FvHandleCount,
> +        &FvHandleBuffer
> +        );
> +  for (Index = 0; Index < FvHandleCount; Index++) {
> +    gBS->HandleProtocol (
> +          FvHandleBuffer[Index],
> +          &gEfiFirmwareVolume2ProtocolGuid,
> +          (VOID **) &Fv
> +          );
> +
> +    Status = Fv->ReadFile (
> +                  Fv,
> +                  &gUefiShellFileGuid,
> +                  NULL,
> +                  &Size,
> +                  &Type,
> +                  &Attributes,
> +                  &AuthenticationStatus
> +                  );
> +    if (EFI_ERROR (Status)) {
> +      //
> +      // Skip if no shell file in the FV
> +      //
> +      continue;
> +    }
> +    //
> +    // Build the shell boot option
> +    //
> +    BdsLibBuildOptionFromShell (FvHandleBuffer[Index], BdsBootOptionList);
> +  }
> +
> +  if (FvHandleCount != 0) {
> +    FreePool (FvHandleBuffer);
> +  }
> +  //
> +  // Make sure every boot only have one time
> +  // boot device enumerate
> +  //
> +  Status = BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");
> +  mEnumBootDevice = TRUE;
> +
> +  return Status;
> +}
> +
> +/**
> +  Build the boot option with the handle parsed in
> +
> +  @param  Handle                 The handle which present the device path to
> create
> +                                 boot option
> +  @param  BdsBootOptionList      The header of the link list which indexed all
> +                                 current boot options
> +  @param  String                 The description of the boot option.
> +
> +**/
> +VOID
> +EFIAPI
> +BdsLibBuildOptionFromHandle (
> +  IN  EFI_HANDLE                 Handle,
> +  IN  LIST_ENTRY                 *BdsBootOptionList,
> +  IN  CHAR16                     *String
> +  )
> +{
> +  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
> +
> +  DevicePath = DevicePathFromHandle (Handle);
> +
> +  //
> +  // Create and register new boot option
> +  //
> +  BdsLibRegisterNewOption (BdsBootOptionList, DevicePath, String,
> L"BootOrder");
> +}
> +
> +
> +/**
> +  Build the on flash shell boot option with the handle parsed in.
> +
> +  @param  Handle                 The handle which present the device path to
> create
> +                                 on flash shell boot option
> +  @param  BdsBootOptionList      The header of the link list which indexed all
> +                                 current boot options
> +
> +**/
> +VOID
> +EFIAPI
> +BdsLibBuildOptionFromShell (
> +  IN EFI_HANDLE                  Handle,
> +  IN OUT LIST_ENTRY              *BdsBootOptionList
> +  )
> +{
> +  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;
> +  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH ShellNode;
> +
> +  DevicePath = DevicePathFromHandle (Handle);
> +
> +  //
> +  // Build the shell device path
> +  //
> +  EfiInitializeFwVolDevicepathNode (&ShellNode, &gUefiShellFileGuid);
> +
> +  DevicePath = AppendDevicePathNode (DevicePath,
> (EFI_DEVICE_PATH_PROTOCOL *) &ShellNode);
> +
> +  //
> +  // Create and register the shell boot option
> +  //
> +  BdsLibRegisterNewOption (BdsBootOptionList, DevicePath, L"EFI Internal
> Shell", L"BootOrder");
> +
> +}
> +
> +/**
> +  Boot from the UEFI spec defined "BootNext" variable.
> +
> +**/
> +VOID
> +EFIAPI
> +BdsLibBootNext (
> +  VOID
> +  )
> +{
> +  EFI_STATUS        Status;
> +  UINT16            *BootNext;
> +  UINTN             BootNextSize;
> +  CHAR16            Buffer[20];
> +  BDS_COMMON_OPTION *BootOption;
> +  LIST_ENTRY        TempList;
> +  UINTN             ExitDataSize;
> +  CHAR16            *ExitData;
> +
> +  //
> +  // Init the boot option name buffer and temp link list
> +  //
> +  InitializeListHead (&TempList);
> +  ZeroMem (Buffer, sizeof (Buffer));
> +
> +  BootNext = BdsLibGetVariableAndSize (
> +              L"BootNext",
> +              &gEfiGlobalVariableGuid,
> +              &BootNextSize
> +              );
> +
> +  //
> +  // Clear the boot next variable first
> +  //
> +  if (BootNext != NULL) {
> +    Status = gRT->SetVariable (
> +                    L"BootNext",
> +                    &gEfiGlobalVariableGuid,
> +                    EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
> +                    0,
> +                    NULL
> +                    );
> +    //
> +    // Deleting variable with current variable implementation shouldn't fail.
> +    //
> +    ASSERT_EFI_ERROR (Status);
> +
> +    //
> +    // Start to build the boot option and try to boot
> +    //
> +    UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", *BootNext);
> +    BootOption = BdsLibVariableToOption (&TempList, Buffer);
> +    ASSERT (BootOption != NULL);
> +    BdsLibConnectDevicePath (BootOption->DevicePath);
> +    BdsLibBootViaBootOption (BootOption, BootOption->DevicePath,
> &ExitDataSize, &ExitData);
> +    FreePool(BootOption);
> +    FreePool(BootNext);
> +  }
> +
> +}
> +
> +/**
> +  Return the bootable media handle.
> +  First, check the device is connected
> +  Second, check whether the device path point to a device which support
> SimpleFileSystemProtocol,
> +  Third, detect the the default boot file in the Media, and return the
> removable Media handle.
> +
> +  @param  DevicePath  Device Path to a  bootable device
> +
> +  @return  The bootable media handle. If the media on the DevicePath is
> not bootable, NULL will return.
> +
> +**/
> +EFI_HANDLE
> +EFIAPI
> +BdsLibGetBootableHandle (
> +  IN  EFI_DEVICE_PATH_PROTOCOL      *DevicePath
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  EFI_TPL                         OldTpl;
> +  EFI_DEVICE_PATH_PROTOCOL        *UpdatedDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL        *DupDevicePath;
> +  EFI_HANDLE                      Handle;
> +  EFI_BLOCK_IO_PROTOCOL           *BlockIo;
> +  VOID                            *Buffer;
> +  EFI_DEVICE_PATH_PROTOCOL        *TempDevicePath;
> +  UINTN                           Size;
> +  UINTN                           TempSize;
> +  EFI_HANDLE                      ReturnHandle;
> +  EFI_HANDLE                      *SimpleFileSystemHandles;
> +
> +  UINTN                           NumberSimpleFileSystemHandles;
> +  UINTN                           Index;
> +  EFI_IMAGE_DOS_HEADER            DosHeader;
> +  EFI_IMAGE_OPTIONAL_HEADER_UNION       HdrData;
> +  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;
> +
> +  UpdatedDevicePath = DevicePath;
> +
> +  //
> +  // Enter to critical section to protect the acquired BlockIo instance
> +  // from getting released due to the USB mass storage hotplug event
> +  //
> +  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> +  //
> +  // Check whether the device is connected
> +  //
> +  Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid,
> &UpdatedDevicePath, &Handle);
> +  if (EFI_ERROR (Status)) {
> +    //
> +    // Skip the case that the boot option point to a simple file protocol which
> does not consume block Io protocol,
> +    //
> +    Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid,
> &UpdatedDevicePath, &Handle);
> +    if (EFI_ERROR (Status)) {
> +      //
> +      // Fail to find the proper BlockIo and simple file protocol, maybe because
> device not present,  we need to connect it firstly
> +      //
> +      UpdatedDevicePath = DevicePath;
> +      Status            = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid,
> &UpdatedDevicePath, &Handle);
> +      gBS->ConnectController (Handle, NULL, NULL, TRUE);
> +    }
> +  } else {
> +    //
> +    // For removable device boot option, its contained device path only point
> to the removable device handle,
> +    // should make sure all its children handles (its child partion or media
> handles) are created and connected.
> +    //
> +    gBS->ConnectController (Handle, NULL, NULL, TRUE);
> +    //
> +    // Get BlockIo protocol and check removable attribute
> +    //
> +    Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID
> **)&BlockIo);
> +    ASSERT_EFI_ERROR (Status);
> +
> +    //
> +    // Issue a dummy read to the device to check for media change.
> +    // When the removable media is changed, any Block IO read/write will
> +    // cause the BlockIo protocol be reinstalled and EFI_MEDIA_CHANGED is
> +    // returned. After the Block IO protocol is reinstalled, subsequent
> +    // Block IO read/write will success.
> +    //
> +    Buffer = AllocatePool (BlockIo->Media->BlockSize);
> +    if (Buffer != NULL) {
> +      BlockIo->ReadBlocks (
> +               BlockIo,
> +               BlockIo->Media->MediaId,
> +               0,
> +               BlockIo->Media->BlockSize,
> +               Buffer
> +               );
> +      FreePool(Buffer);
> +    }
> +  }
> +
> +  //
> +  // Detect the the default boot file from removable Media
> +  //
> +
> +  //
> +  // If fail to get bootable handle specified by a USB boot option, the BDS
> should try to find other bootable device in the same USB bus
> +  // Try to locate the USB node device path first, if fail then use its previous
> PCI node to search
> +  //
> +  DupDevicePath = DuplicateDevicePath (DevicePath);
> +  ASSERT (DupDevicePath != NULL);
> +
> +  UpdatedDevicePath = DupDevicePath;
> +  Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid,
> &UpdatedDevicePath, &Handle);
> +  //
> +  // if the resulting device path point to a usb node, and the usb node is a
> dummy node, should only let device path only point to the previous Pci node
> +  // Acpi()/Pci()/Usb() --> Acpi()/Pci()
> +  //
> +  if ((DevicePathType (UpdatedDevicePath) == MESSAGING_DEVICE_PATH)
> &&
> +      (DevicePathSubType (UpdatedDevicePath) == MSG_USB_DP)) {
> +    //
> +    // Remove the usb node, let the device path only point to PCI node
> +    //
> +    SetDevicePathEndNode (UpdatedDevicePath);
> +    UpdatedDevicePath = DupDevicePath;
> +  } else {
> +    UpdatedDevicePath = DevicePath;
> +  }
> +
> +  //
> +  // Get the device path size of boot option
> +  //
> +  Size = GetDevicePathSize(UpdatedDevicePath) - sizeof
> (EFI_DEVICE_PATH_PROTOCOL); // minus the end node
> +  ReturnHandle = NULL;
> +  gBS->LocateHandleBuffer (
> +      ByProtocol,
> +      &gEfiSimpleFileSystemProtocolGuid,
> +      NULL,
> +      &NumberSimpleFileSystemHandles,
> +      &SimpleFileSystemHandles
> +      );
> +  for (Index = 0; Index < NumberSimpleFileSystemHandles; Index++) {
> +    //
> +    // Get the device path size of SimpleFileSystem handle
> +    //
> +    TempDevicePath = DevicePathFromHandle
> (SimpleFileSystemHandles[Index]);
> +    TempSize = GetDevicePathSize (TempDevicePath)- sizeof
> (EFI_DEVICE_PATH_PROTOCOL); // minus the end node
> +    //
> +    // Check whether the device path of boot option is part of the
> SimpleFileSystem handle's device path
> +    //
> +    if (Size <= TempSize && CompareMem (TempDevicePath,
> UpdatedDevicePath, Size)==0) {
> +      //
> +      // Load the default boot file \EFI\BOOT\boot{machinename}.EFI from
> removable Media
> +      //  machinename is ia32, ia64, x64, ...
> +      //
> +      Hdr.Union = &HdrData;
> +      Status = BdsLibGetImageHeader (
> +                 SimpleFileSystemHandles[Index],
> +                 EFI_REMOVABLE_MEDIA_FILE_NAME,
> +                 &DosHeader,
> +                 Hdr
> +                 );
> +      if (!EFI_ERROR (Status) &&
> +        EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr.Pe32-
> >FileHeader.Machine) &&
> +        Hdr.Pe32->OptionalHeader.Subsystem ==
> EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {
> +        ReturnHandle = SimpleFileSystemHandles[Index];
> +        break;
> +      }
> +    }
> +  }
> +
> +  FreePool(DupDevicePath);
> +
> +  if (SimpleFileSystemHandles != NULL) {
> +    FreePool(SimpleFileSystemHandles);
> +  }
> +
> +  gBS->RestoreTPL (OldTpl);
> +
> +  return ReturnHandle;
> +}
> +
> +/**
> +  Check to see if the network cable is plugged in. If the DevicePath is not
> +  connected it will be connected.
> +
> +  @param  DevicePath             Device Path to check
> +
> +  @retval TRUE                   DevicePath points to an Network that is connected
> +  @retval FALSE                  DevicePath does not point to a bootable network
> +
> +**/
> +BOOLEAN
> +BdsLibNetworkBootWithMediaPresent (
> +  IN  EFI_DEVICE_PATH_PROTOCOL      *DevicePath
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  EFI_DEVICE_PATH_PROTOCOL        *UpdatedDevicePath;
> +  EFI_HANDLE                      Handle;
> +  EFI_SIMPLE_NETWORK_PROTOCOL     *Snp;
> +  BOOLEAN                         MediaPresent;
> +  UINT32                          InterruptStatus;
> +
> +  MediaPresent = FALSE;
> +
> +  UpdatedDevicePath = DevicePath;
> +  //
> +  // Locate Load File Protocol for PXE boot option first
> +  //
> +  Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid,
> &UpdatedDevicePath, &Handle);
> +  if (EFI_ERROR (Status)) {
> +    //
> +    // Device not present so see if we need to connect it
> +    //
> +    Status = BdsLibConnectDevicePath (DevicePath);
> +    if (!EFI_ERROR (Status)) {
> +      //
> +      // This one should work after we did the connect
> +      //
> +      Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid,
> &UpdatedDevicePath, &Handle);
> +    }
> +  }
> +
> +  if (!EFI_ERROR (Status)) {
> +    Status = gBS->HandleProtocol (Handle, &gEfiSimpleNetworkProtocolGuid,
> (VOID **)&Snp);
> +    if (EFI_ERROR (Status)) {
> +      //
> +      // Failed to open SNP from this handle, try to get SNP from parent
> handle
> +      //
> +      UpdatedDevicePath = DevicePathFromHandle (Handle);
> +      if (UpdatedDevicePath != NULL) {
> +        Status = gBS->LocateDevicePath (&gEfiSimpleNetworkProtocolGuid,
> &UpdatedDevicePath, &Handle);
> +        if (!EFI_ERROR (Status)) {
> +          //
> +          // SNP handle found, get SNP from it
> +          //
> +          Status = gBS->HandleProtocol (Handle,
> &gEfiSimpleNetworkProtocolGuid, (VOID **) &Snp);
> +        }
> +      }
> +    }
> +
> +    if (!EFI_ERROR (Status)) {
> +      if (Snp->Mode->MediaPresentSupported) {
> +        if (Snp->Mode->State == EfiSimpleNetworkInitialized) {
> +          //
> +          // Invoke Snp->GetStatus() to refresh the media status
> +          //
> +          Snp->GetStatus (Snp, &InterruptStatus, NULL);
> +
> +          //
> +          // In case some one else is using the SNP check to see if it's connected
> +          //
> +          MediaPresent = Snp->Mode->MediaPresent;
> +        } else {
> +          //
> +          // No one is using SNP so we need to Start and Initialize so
> +          // MediaPresent will be valid.
> +          //
> +          Status = Snp->Start (Snp);
> +          if (!EFI_ERROR (Status)) {
> +            Status = Snp->Initialize (Snp, 0, 0);
> +            if (!EFI_ERROR (Status)) {
> +              MediaPresent = Snp->Mode->MediaPresent;
> +              Snp->Shutdown (Snp);
> +            }
> +            Snp->Stop (Snp);
> +          }
> +        }
> +      } else {
> +        MediaPresent = TRUE;
> +      }
> +    }
> +  }
> +
> +  return MediaPresent;
> +}
> +
> +/**
> +  For a bootable Device path, return its boot type.
> +
> +  @param  DevicePath                      The bootable device Path to check
> +
> +  @retval BDS_EFI_MEDIA_HD_BOOT           If given device path contains
> MEDIA_DEVICE_PATH type device path node
> +                                          which subtype is MEDIA_HARDDRIVE_DP
> +  @retval BDS_EFI_MEDIA_CDROM_BOOT        If given device path contains
> MEDIA_DEVICE_PATH type device path node
> +                                          which subtype is MEDIA_CDROM_DP
> +  @retval BDS_EFI_ACPI_FLOPPY_BOOT        If given device path contains
> ACPI_DEVICE_PATH type device path node
> +                                          which HID is floppy device.
> +  @retval BDS_EFI_MESSAGE_ATAPI_BOOT      If given device path contains
> MESSAGING_DEVICE_PATH type device path node
> +                                          and its last device path node's subtype is
> MSG_ATAPI_DP.
> +  @retval BDS_EFI_MESSAGE_SCSI_BOOT       If given device path contains
> MESSAGING_DEVICE_PATH type device path node
> +                                          and its last device path node's subtype is
> MSG_SCSI_DP.
> +  @retval BDS_EFI_MESSAGE_USB_DEVICE_BOOT If given device path
> contains MESSAGING_DEVICE_PATH type device path node
> +                                          and its last device path node's subtype is
> MSG_USB_DP.
> +  @retval BDS_EFI_MESSAGE_MISC_BOOT       If the device path not
> contains any media device path node,  and
> +                                          its last device path node point to a message device
> path node.
> +  @retval BDS_LEGACY_BBS_BOOT             If given device path contains
> BBS_DEVICE_PATH type device path node.
> +  @retval BDS_EFI_UNSUPPORT               An EFI Removable BlockIO device
> path not point to a media and message device,
> +
> +**/
> +UINT32
> +EFIAPI
> +BdsGetBootTypeFromDevicePath (
> +  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath
> +  )
> +{
> +  ACPI_HID_DEVICE_PATH          *Acpi;
> +  EFI_DEVICE_PATH_PROTOCOL      *TempDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL      *LastDeviceNode;
> +  UINT32                        BootType;
> +
> +  if (NULL == DevicePath) {
> +    return BDS_EFI_UNSUPPORT;
> +  }
> +
> +  TempDevicePath = DevicePath;
> +
> +  while (!IsDevicePathEndType (TempDevicePath)) {
> +    switch (DevicePathType (TempDevicePath)) {
> +      case BBS_DEVICE_PATH:
> +         return BDS_LEGACY_BBS_BOOT;
> +      case MEDIA_DEVICE_PATH:
> +        if (DevicePathSubType (TempDevicePath) == MEDIA_HARDDRIVE_DP) {
> +          return BDS_EFI_MEDIA_HD_BOOT;
> +        } else if (DevicePathSubType (TempDevicePath) == MEDIA_CDROM_DP)
> {
> +          return BDS_EFI_MEDIA_CDROM_BOOT;
> +        }
> +        break;
> +      case ACPI_DEVICE_PATH:
> +        Acpi = (ACPI_HID_DEVICE_PATH *) TempDevicePath;
> +        if (EISA_ID_TO_NUM (Acpi->HID) == 0x0604) {
> +          return BDS_EFI_ACPI_FLOPPY_BOOT;
> +        }
> +        break;
> +      case MESSAGING_DEVICE_PATH:
> +        //
> +        // Get the last device path node
> +        //
> +        LastDeviceNode = NextDevicePathNode (TempDevicePath);
> +        if (DevicePathSubType(LastDeviceNode) ==
> MSG_DEVICE_LOGICAL_UNIT_DP) {
> +          //
> +          // if the next node type is Device Logical Unit, which specify the Logical
> Unit Number (LUN),
> +          // skip it
> +          //
> +          LastDeviceNode = NextDevicePathNode (LastDeviceNode);
> +        }
> +        //
> +        // if the device path not only point to driver device, it is not a messaging
> device path,
> +        //
> +        if (!IsDevicePathEndType (LastDeviceNode)) {
> +          break;
> +        }
> +
> +        switch (DevicePathSubType (TempDevicePath)) {
> +        case MSG_ATAPI_DP:
> +          BootType = BDS_EFI_MESSAGE_ATAPI_BOOT;
> +          break;
> +
> +        case MSG_USB_DP:
> +          BootType = BDS_EFI_MESSAGE_USB_DEVICE_BOOT;
> +          break;
> +
> +        case MSG_SCSI_DP:
> +          BootType = BDS_EFI_MESSAGE_SCSI_BOOT;
> +          break;
> +
> +        case MSG_SATA_DP:
> +          BootType = BDS_EFI_MESSAGE_SATA_BOOT;
> +          break;
> +
> +        case MSG_MAC_ADDR_DP:
> +        case MSG_VLAN_DP:
> +        case MSG_IPv4_DP:
> +        case MSG_IPv6_DP:
> +          BootType = BDS_EFI_MESSAGE_MAC_BOOT;
> +          break;
> +
> +        default:
> +          BootType = BDS_EFI_MESSAGE_MISC_BOOT;
> +          break;
> +        }
> +        return BootType;
> +
> +      default:
> +        break;
> +    }
> +    TempDevicePath = NextDevicePathNode (TempDevicePath);
> +  }
> +
> +  return BDS_EFI_UNSUPPORT;
> +}
> +
> +/**
> +  Check whether the Device path in a boot option point to a valid bootable
> device,
> +  And if CheckMedia is true, check the device is ready to boot now.
> +
> +  @param  DevPath     the Device path in a boot option
> +  @param  CheckMedia  if true, check the device is ready to boot now.
> +
> +  @retval TRUE        the Device path  is valid
> +  @retval FALSE       the Device path  is invalid .
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +BdsLibIsValidEFIBootOptDevicePath (
> +  IN EFI_DEVICE_PATH_PROTOCOL     *DevPath,
> +  IN BOOLEAN                      CheckMedia
> +  )
> +{
> +  return BdsLibIsValidEFIBootOptDevicePathExt (DevPath, CheckMedia,
> NULL);
> +}
> +
> +/**
> +  Check whether the Device path in a boot option point to a valid bootable
> device,
> +  And if CheckMedia is true, check the device is ready to boot now.
> +  If Description is not NULL and the device path point to a fixed BlockIo
> +  device, check the description whether conflict with other auto-created
> +  boot options.
> +
> +  @param  DevPath     the Device path in a boot option
> +  @param  CheckMedia  if true, check the device is ready to boot now.
> +  @param  Description the description in a boot option
> +
> +  @retval TRUE        the Device path  is valid
> +  @retval FALSE       the Device path  is invalid .
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +BdsLibIsValidEFIBootOptDevicePathExt (
> +  IN EFI_DEVICE_PATH_PROTOCOL     *DevPath,
> +  IN BOOLEAN                      CheckMedia,
> +  IN CHAR16                       *Description
> +  )
> +{
> +  EFI_STATUS                Status;
> +  EFI_HANDLE                Handle;
> +  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL  *LastDeviceNode;
> +  EFI_BLOCK_IO_PROTOCOL     *BlockIo;
> +
> +  TempDevicePath = DevPath;
> +  LastDeviceNode = DevPath;
> +
> +  //
> +  // Check if it's a valid boot option for network boot device.
> +  // Check if there is EfiLoadFileProtocol installed.
> +  // If yes, that means there is a boot option for network.
> +  //
> +  Status = gBS->LocateDevicePath (
> +                  &gEfiLoadFileProtocolGuid,
> +                  &TempDevicePath,
> +                  &Handle
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    //
> +    // Device not present so see if we need to connect it
> +    //
> +    TempDevicePath = DevPath;
> +    BdsLibConnectDevicePath (TempDevicePath);
> +    Status = gBS->LocateDevicePath (
> +                    &gEfiLoadFileProtocolGuid,
> +                    &TempDevicePath,
> +                    &Handle
> +                    );
> +  }
> +
> +  if (!EFI_ERROR (Status)) {
> +    if (!IsDevicePathEnd (TempDevicePath)) {
> +      //
> +      // LoadFile protocol is not installed on handle with exactly the same
> DevPath
> +      //
> +      return FALSE;
> +    }
> +
> +    if (CheckMedia) {
> +      //
> +      // Test if it is ready to boot now
> +      //
> +      if (BdsLibNetworkBootWithMediaPresent(DevPath)) {
> +        return TRUE;
> +      }
> +    } else {
> +      return TRUE;
> +    }
> +  }
> +
> +  //
> +  // If the boot option point to a file, it is a valid EFI boot option,
> +  // and assume it is ready to boot now
> +  //
> +  while (!IsDevicePathEnd (TempDevicePath)) {
> +    //
> +    // If there is USB Class or USB WWID device path node, treat it as valid EFI
> +    // Boot Option. BdsExpandUsbShortFormDevicePath () will be used to
> expand it
> +    // to full device path.
> +    //
> +    if ((DevicePathType (TempDevicePath) == MESSAGING_DEVICE_PATH)
> &&
> +        ((DevicePathSubType (TempDevicePath) == MSG_USB_CLASS_DP) ||
> +         (DevicePathSubType (TempDevicePath) == MSG_USB_WWID_DP))) {
> +      return TRUE;
> +    }
> +
> +    LastDeviceNode = TempDevicePath;
> +    TempDevicePath = NextDevicePathNode (TempDevicePath);
> +  }
> +  if ((DevicePathType (LastDeviceNode) == MEDIA_DEVICE_PATH) &&
> +    (DevicePathSubType (LastDeviceNode) == MEDIA_FILEPATH_DP)) {
> +    return TRUE;
> +  }
> +
> +  //
> +  // Check if it's a valid boot option for internal FV application
> +  //
> +  if (EfiGetNameGuidFromFwVolDevicePathNode
> ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode) != NULL) {
> +    //
> +    // If the boot option point to internal FV application, make sure it is valid
> +    //
> +    TempDevicePath = DevPath;
> +    Status = BdsLibUpdateFvFileDevicePath (
> +               &TempDevicePath,
> +               EfiGetNameGuidFromFwVolDevicePathNode
> ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode)
> +               );
> +    if (Status == EFI_ALREADY_STARTED) {
> +      return TRUE;
> +    } else {
> +      if (Status == EFI_SUCCESS) {
> +        FreePool (TempDevicePath);
> +      }
> +      return FALSE;
> +    }
> +  }
> +
> +  //
> +  // If the boot option point to a blockIO device:
> +  //    if it is a removable blockIo device, it is valid.
> +  //    if it is a fixed blockIo device, check its description confliction.
> +  //
> +  TempDevicePath = DevPath;
> +  Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid,
> &TempDevicePath, &Handle);
> +  if (EFI_ERROR (Status)) {
> +    //
> +    // Device not present so see if we need to connect it
> +    //
> +    Status = BdsLibConnectDevicePath (DevPath);
> +    if (!EFI_ERROR (Status)) {
> +      //
> +      // Try again to get the Block Io protocol after we did the connect
> +      //
> +      TempDevicePath = DevPath;
> +      Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid,
> &TempDevicePath, &Handle);
> +    }
> +  }
> +
> +  if (!EFI_ERROR (Status)) {
> +    Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID
> **)&BlockIo);
> +    if (!EFI_ERROR (Status)) {
> +      if (CheckMedia) {
> +        //
> +        // Test if it is ready to boot now
> +        //
> +        if (BdsLibGetBootableHandle (DevPath) != NULL) {
> +          return TRUE;
> +        }
> +      } else {
> +        return TRUE;
> +      }
> +    }
> +  } else {
> +    //
> +    // if the boot option point to a simple file protocol which does not
> consume block Io protocol, it is also a valid EFI boot option,
> +    //
> +    Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid,
> &TempDevicePath, &Handle);
> +    if (!EFI_ERROR (Status)) {
> +      if (CheckMedia) {
> +        //
> +        // Test if it is ready to boot now
> +        //
> +        if (BdsLibGetBootableHandle (DevPath) != NULL) {
> +          return TRUE;
> +        }
> +      } else {
> +        return TRUE;
> +      }
> +    }
> +  }
> +
> +  return FALSE;
> +}
> +
> +
> +/**
> +  According to a file guild, check a Fv file device path is valid. If it is invalid,
> +  try to return the valid device path.
> +  FV address maybe changes for memory layout adjust from time to time,
> use this function
> +  could promise the Fv file device path is right.
> +
> +  @param  DevicePath             on input, the Fv file device path need to check
> on
> +                                 output, the updated valid Fv file device path
> +  @param  FileGuid               the Fv file guild
> +
> +  @retval EFI_INVALID_PARAMETER  the input DevicePath or FileGuid is
> invalid
> +                                 parameter
> +  @retval EFI_UNSUPPORTED        the input DevicePath does not contain Fv
> file
> +                                 guild at all
> +  @retval EFI_ALREADY_STARTED    the input DevicePath has pointed to Fv
> file, it is
> +                                 valid
> +  @retval EFI_SUCCESS            has successfully updated the invalid DevicePath,
> +                                 and return the updated device path in DevicePath
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BdsLibUpdateFvFileDevicePath (
> +  IN  OUT EFI_DEVICE_PATH_PROTOCOL      ** DevicePath,
> +  IN  EFI_GUID                          *FileGuid
> +  )
> +{
> +  EFI_DEVICE_PATH_PROTOCOL      *TempDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL      *LastDeviceNode;
> +  EFI_STATUS                    Status;
> +  EFI_GUID                      *GuidPoint;
> +  UINTN                         Index;
> +  UINTN                         FvHandleCount;
> +  EFI_HANDLE                    *FvHandleBuffer;
> +  EFI_FV_FILETYPE               Type;
> +  UINTN                         Size;
> +  EFI_FV_FILE_ATTRIBUTES        Attributes;
> +  UINT32                        AuthenticationStatus;
> +  BOOLEAN                       FindFvFile;
> +  EFI_LOADED_IMAGE_PROTOCOL     *LoadedImage;
> +  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
> +  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FvFileNode;
> +  EFI_HANDLE                    FoundFvHandle;
> +  EFI_DEVICE_PATH_PROTOCOL      *NewDevicePath;
> +
> +  if ((DevicePath == NULL) || (*DevicePath == NULL)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  if (FileGuid == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Check whether the device path point to the default the input Fv file
> +  //
> +  TempDevicePath = *DevicePath;
> +  LastDeviceNode = TempDevicePath;
> +  while (!IsDevicePathEnd (TempDevicePath)) {
> +     LastDeviceNode = TempDevicePath;
> +     TempDevicePath = NextDevicePathNode (TempDevicePath);
> +  }
> +  GuidPoint = EfiGetNameGuidFromFwVolDevicePathNode (
> +                (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode
> +                );
> +  if (GuidPoint == NULL) {
> +    //
> +    // if this option does not points to a Fv file, just return EFI_UNSUPPORTED
> +    //
> +    return EFI_UNSUPPORTED;
> +  }
> +  if (!CompareGuid (GuidPoint, FileGuid)) {
> +    //
> +    // If the Fv file is not the input file guid, just return EFI_UNSUPPORTED
> +    //
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Check whether the input Fv file device path is valid
> +  //
> +  TempDevicePath = *DevicePath;
> +  FoundFvHandle = NULL;
> +  Status = gBS->LocateDevicePath (
> +                  &gEfiFirmwareVolume2ProtocolGuid,
> +                  &TempDevicePath,
> +                  &FoundFvHandle
> +                  );
> +  if (!EFI_ERROR (Status)) {
> +    Status = gBS->HandleProtocol (
> +                    FoundFvHandle,
> +                    &gEfiFirmwareVolume2ProtocolGuid,
> +                    (VOID **) &Fv
> +                    );
> +    if (!EFI_ERROR (Status)) {
> +      //
> +      // Set FV ReadFile Buffer as NULL, only need to check whether input Fv
> file exist there
> +      //
> +      Status = Fv->ReadFile (
> +                    Fv,
> +                    FileGuid,
> +                    NULL,
> +                    &Size,
> +                    &Type,
> +                    &Attributes,
> +                    &AuthenticationStatus
> +                    );
> +      if (!EFI_ERROR (Status)) {
> +        return EFI_ALREADY_STARTED;
> +      }
> +    }
> +  }
> +
> +  //
> +  // Look for the input wanted FV file in current FV
> +  // First, try to look for in Bds own FV. Bds and input wanted FV file usually
> are in the same FV
> +  //
> +  FindFvFile = FALSE;
> +  FoundFvHandle = NULL;
> +  Status = gBS->HandleProtocol (
> +             gImageHandle,
> +             &gEfiLoadedImageProtocolGuid,
> +             (VOID **) &LoadedImage
> +             );
> +  if (!EFI_ERROR (Status)) {
> +    Status = gBS->HandleProtocol (
> +                    LoadedImage->DeviceHandle,
> +                    &gEfiFirmwareVolume2ProtocolGuid,
> +                    (VOID **) &Fv
> +                    );
> +    if (!EFI_ERROR (Status)) {
> +      Status = Fv->ReadFile (
> +                    Fv,
> +                    FileGuid,
> +                    NULL,
> +                    &Size,
> +                    &Type,
> +                    &Attributes,
> +                    &AuthenticationStatus
> +                    );
> +      if (!EFI_ERROR (Status)) {
> +        FindFvFile = TRUE;
> +        FoundFvHandle = LoadedImage->DeviceHandle;
> +      }
> +    }
> +  }
> +  //
> +  // Second, if fail to find, try to enumerate all FV
> +  //
> +  if (!FindFvFile) {
> +    FvHandleBuffer = NULL;
> +    gBS->LocateHandleBuffer (
> +          ByProtocol,
> +          &gEfiFirmwareVolume2ProtocolGuid,
> +          NULL,
> +          &FvHandleCount,
> +          &FvHandleBuffer
> +          );
> +    for (Index = 0; Index < FvHandleCount; Index++) {
> +      gBS->HandleProtocol (
> +            FvHandleBuffer[Index],
> +            &gEfiFirmwareVolume2ProtocolGuid,
> +            (VOID **) &Fv
> +            );
> +
> +      Status = Fv->ReadFile (
> +                    Fv,
> +                    FileGuid,
> +                    NULL,
> +                    &Size,
> +                    &Type,
> +                    &Attributes,
> +                    &AuthenticationStatus
> +                    );
> +      if (EFI_ERROR (Status)) {
> +        //
> +        // Skip if input Fv file not in the FV
> +        //
> +        continue;
> +      }
> +      FindFvFile = TRUE;
> +      FoundFvHandle = FvHandleBuffer[Index];
> +      break;
> +    }
> +
> +    if (FvHandleBuffer != NULL) {
> +      FreePool (FvHandleBuffer);
> +    }
> +  }
> +
> +  if (FindFvFile) {
> +    //
> +    // Build the shell device path
> +    //
> +    NewDevicePath = DevicePathFromHandle (FoundFvHandle);
> +    EfiInitializeFwVolDevicepathNode (&FvFileNode, FileGuid);
> +    NewDevicePath = AppendDevicePathNode (NewDevicePath,
> (EFI_DEVICE_PATH_PROTOCOL *) &FvFileNode);
> +    ASSERT (NewDevicePath != NULL);
> +    *DevicePath = NewDevicePath;
> +    return EFI_SUCCESS;
> +  }
> +  return EFI_NOT_FOUND;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/BdsConnect.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/BdsConnect.c
> new file mode 100644
> index 0000000000..dfeefc01b8
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/BdsConnect.c
> @@ -0,0 +1,429 @@
> +/** @file
> +  BDS Lib functions which relate with connect the device
> +
> +Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "InternalBdsLib.h"
> +
> +
> +/**
> +  This function will connect all the system driver to controller
> +  first, and then special connect the default console, this make
> +  sure all the system controller available and the platform default
> +  console connected.
> +
> +**/
> +VOID
> +EFIAPI
> +BdsLibConnectAll (
> +  VOID
> +  )
> +{
> +  //
> +  // Connect the platform console first
> +  //
> +  BdsLibConnectAllDefaultConsoles ();
> +
> +  //
> +  // Generic way to connect all the drivers
> +  //
> +  BdsLibConnectAllDriversToAllControllers ();
> +
> +  //
> +  // Here we have the assumption that we have already had
> +  // platform default console
> +  //
> +  BdsLibConnectAllDefaultConsoles ();
> +}
> +
> +
> +/**
> +  This function will connect all the system drivers to all controllers
> +  first, and then connect all the console devices the system current
> +  have. After this we should get all the device work and console available
> +  if the system have console device.
> +
> +**/
> +VOID
> +BdsLibGenericConnectAll (
> +  VOID
> +  )
> +{
> +  //
> +  // Most generic way to connect all the drivers
> +  //
> +  BdsLibConnectAllDriversToAllControllers ();
> +  BdsLibConnectAllConsoles ();
> +}
> +
> +/**
> +  This function will create all handles associate with every device
> +  path node. If the handle associate with one device path node can not
> +  be created successfully, then still give chance to do the dispatch,
> +  which load the missing drivers if possible.
> +
> +  @param  DevicePathToConnect   The device path which will be connected,
> it can be
> +                                a multi-instance device path
> +
> +  @retval EFI_SUCCESS           All handles associate with every device path
> node
> +                                have been created
> +  @retval EFI_OUT_OF_RESOURCES  There is no resource to create new
> handles
> +  @retval EFI_NOT_FOUND         Create the handle associate with one device
> path
> +                                node failed
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BdsLibConnectDevicePath (
> +  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePathToConnect
> +  )
> +{
> +  EFI_STATUS                Status;
> +  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL  *CopyOfDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL  *Instance;
> +  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL  *Next;
> +  EFI_HANDLE                Handle;
> +  EFI_HANDLE                PreviousHandle;
> +  UINTN                     Size;
> +  EFI_TPL                   CurrentTpl;
> +
> +  if (DevicePathToConnect == NULL) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  CurrentTpl  = EfiGetCurrentTpl ();
> +
> +  DevicePath        = DuplicateDevicePath (DevicePathToConnect);
> +  if (DevicePath == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +  CopyOfDevicePath  = DevicePath;
> +
> +  do {
> +    //
> +    // The outer loop handles multi instance device paths.
> +    // Only console variables contain multiple instance device paths.
> +    //
> +    // After this call DevicePath points to the next Instance
> +    //
> +    Instance  = GetNextDevicePathInstance (&DevicePath, &Size);
> +    if (Instance == NULL) {
> +      FreePool (CopyOfDevicePath);
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +
> +    Next      = Instance;
> +    while (!IsDevicePathEndType (Next)) {
> +      Next = NextDevicePathNode (Next);
> +    }
> +
> +    SetDevicePathEndNode (Next);
> +
> +    //
> +    // Start the real work of connect with RemainingDevicePath
> +    //
> +    PreviousHandle = NULL;
> +    do {
> +      //
> +      // Find the handle that best matches the Device Path. If it is only a
> +      // partial match the remaining part of the device path is returned in
> +      // RemainingDevicePath.
> +      //
> +      RemainingDevicePath = Instance;
> +      Status              = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid,
> &RemainingDevicePath, &Handle);
> +
> +      if (!EFI_ERROR (Status)) {
> +        if (Handle == PreviousHandle) {
> +          //
> +          // If no forward progress is made try invoking the Dispatcher.
> +          // A new FV may have been added to the system an new drivers
> +          // may now be found.
> +          // Status == EFI_SUCCESS means a driver was dispatched
> +          // Status == EFI_NOT_FOUND means no new drivers were dispatched
> +          //
> +          if (CurrentTpl == TPL_APPLICATION) {
> +            //
> +            // Dispatch calls LoadImage/StartImage which cannot run at TPL >
> TPL_APPLICATION
> +            //
> +            Status = gDS->Dispatch ();
> +          } else {
> +            //
> +            // Always return EFI_NOT_FOUND here
> +            // to prevent dead loop when control handle is found but connection
> failded case
> +            //
> +            Status = EFI_NOT_FOUND;
> +          }
> +        }
> +
> +        if (!EFI_ERROR (Status)) {
> +          PreviousHandle = Handle;
> +          //
> +          // Connect all drivers that apply to Handle and RemainingDevicePath,
> +          // the Recursive flag is FALSE so only one level will be expanded.
> +          //
> +          // Do not check the connect status here, if the connect controller fail,
> +          // then still give the chance to do dispatch, because partial
> +          // RemainingDevicepath may be in the new FV
> +          //
> +          // 1. If the connect fail, RemainingDevicepath and handle will not
> +          //    change, so next time will do the dispatch, then dispatch's status
> +          //    will take effect
> +          // 2. If the connect success, the RemainingDevicepath and handle will
> +          //    change, then avoid the dispatch, we have chance to continue the
> +          //    next connection
> +          //
> +          gBS->ConnectController (Handle, NULL, RemainingDevicePath, FALSE);
> +        }
> +      }
> +      //
> +      // Loop until RemainingDevicePath is an empty device path
> +      //
> +    } while (!EFI_ERROR (Status) && !IsDevicePathEnd
> (RemainingDevicePath));
> +
> +  } while (DevicePath != NULL);
> +
> +  if (CopyOfDevicePath != NULL) {
> +    FreePool (CopyOfDevicePath);
> +  }
> +  //
> +  // All handle with DevicePath exists in the handle database
> +  //
> +  return Status;
> +}
> +
> +/**
> +  This function will connect all current system handles recursively.
> +
> +  gBS->ConnectController() service is invoked for each handle exist in
> system handler buffer.
> +  If the handle is bus type handler, all childrens also will be connected
> recursively
> +  by gBS->ConnectController().
> +
> +  @retval EFI_SUCCESS           All handles and it's child handle have been
> connected
> +  @retval EFI_STATUS            Error status returned by of gBS-
> >LocateHandleBuffer().
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BdsLibConnectAllEfi (
> +  VOID
> +  )
> +{
> +  EFI_STATUS  Status;
> +  UINTN       HandleCount;
> +  EFI_HANDLE  *HandleBuffer;
> +  UINTN       Index;
> +
> +  Status = gBS->LocateHandleBuffer (
> +                  AllHandles,
> +                  NULL,
> +                  NULL,
> +                  &HandleCount,
> +                  &HandleBuffer
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  for (Index = 0; Index < HandleCount; Index++) {
> +    Status = gBS->ConnectController (HandleBuffer[Index], NULL, NULL,
> TRUE);
> +  }
> +
> +  if (HandleBuffer != NULL) {
> +    FreePool (HandleBuffer);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function will disconnect all current system handles.
> +
> +  gBS->DisconnectController() is invoked for each handle exists in system
> handle buffer.
> +  If handle is a bus type handle, all childrens also are disconnected
> recursively by
> +  gBS->DisconnectController().
> +
> +  @retval EFI_SUCCESS           All handles have been disconnected
> +  @retval EFI_STATUS            Error status returned by of gBS-
> >LocateHandleBuffer().
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BdsLibDisconnectAllEfi (
> +  VOID
> +  )
> +{
> +  EFI_STATUS  Status;
> +  UINTN       HandleCount;
> +  EFI_HANDLE  *HandleBuffer;
> +  UINTN       Index;
> +
> +  //
> +  // Disconnect all
> +  //
> +  Status = gBS->LocateHandleBuffer (
> +                  AllHandles,
> +                  NULL,
> +                  NULL,
> +                  &HandleCount,
> +                  &HandleBuffer
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  for (Index = 0; Index < HandleCount; Index++) {
> +    Status = gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
> +  }
> +
> +  if (HandleBuffer != NULL) {
> +    FreePool (HandleBuffer);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Connects all drivers to all controllers.
> +  This function make sure all the current system driver will manage
> +  the correspoinding controllers if have. And at the same time, make
> +  sure all the system controllers have driver to manage it if have.
> +
> +**/
> +VOID
> +EFIAPI
> +BdsLibConnectAllDriversToAllControllers (
> +  VOID
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  do {
> +    //
> +    // Connect All EFI 1.10 drivers following EFI 1.10 algorithm
> +    //
> +    BdsLibConnectAllEfi ();
> +
> +    //
> +    // Check to see if it's possible to dispatch an more DXE drivers.
> +    // The BdsLibConnectAllEfi () may have made new DXE drivers show up.
> +    // If anything is Dispatched Status == EFI_SUCCESS and we will try
> +    // the connect again.
> +    //
> +    Status = gDS->Dispatch ();
> +
> +  } while (!EFI_ERROR (Status));
> +
> +}
> +
> +
> +/**
> +  Connect the specific Usb device which match the short form device path,
> +  and whose bus is determined by Host Controller (Uhci or Ehci).
> +
> +  @param  HostControllerPI      Uhci (0x00) or Ehci (0x20) or Both uhci and
> ehci
> +                                (0xFF)
> +  @param  RemainingDevicePath   a short-form device path that starts with
> the first
> +                                element  being a USB WWID or a USB Class device
> +                                path
> +
> +  @return EFI_INVALID_PARAMETER  RemainingDevicePath is NULL pointer.
> +                                 RemainingDevicePath is not a USB device path.
> +                                 Invalid HostControllerPI type.
> +  @return EFI_SUCCESS            Success to connect USB device
> +  @return EFI_NOT_FOUND          Fail to find handle for USB controller to
> connect.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BdsLibConnectUsbDevByShortFormDP(
> +  IN UINT8                      HostControllerPI,
> +  IN EFI_DEVICE_PATH_PROTOCOL   *RemainingDevicePath
> +  )
> +{
> +  EFI_STATUS                            Status;
> +  EFI_HANDLE                            *HandleArray;
> +  UINTN                                 HandleArrayCount;
> +  UINTN                                 Index;
> +  EFI_PCI_IO_PROTOCOL                   *PciIo;
> +  UINT8                                 Class[3];
> +  BOOLEAN                               AtLeastOneConnected;
> +
> +  //
> +  // Check the passed in parameters
> +  //
> +  if (RemainingDevicePath == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if ((DevicePathType (RemainingDevicePath) != MESSAGING_DEVICE_PATH)
> ||
> +      ((DevicePathSubType (RemainingDevicePath) != MSG_USB_CLASS_DP)
> +      && (DevicePathSubType (RemainingDevicePath) !=
> MSG_USB_WWID_DP)
> +      )) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (HostControllerPI != 0xFF &&
> +      HostControllerPI != 0x00 &&
> +      HostControllerPI != 0x20) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Find the usb host controller firstly, then connect with the remaining
> device path
> +  //
> +  AtLeastOneConnected = FALSE;
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gEfiPciIoProtocolGuid,
> +                  NULL,
> +                  &HandleArrayCount,
> +                  &HandleArray
> +                  );
> +  if (!EFI_ERROR (Status)) {
> +    for (Index = 0; Index < HandleArrayCount; Index++) {
> +      Status = gBS->HandleProtocol (
> +                      HandleArray[Index],
> +                      &gEfiPciIoProtocolGuid,
> +                      (VOID **)&PciIo
> +                      );
> +      if (!EFI_ERROR (Status)) {
> +        //
> +        // Check whether the Pci device is the wanted usb host controller
> +        //
> +        Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x09, 3, &Class);
> +        if (!EFI_ERROR (Status)) {
> +          if ((PCI_CLASS_SERIAL == Class[2]) &&
> +              (PCI_CLASS_SERIAL_USB == Class[1])) {
> +            if (HostControllerPI == Class[0] || HostControllerPI == 0xFF) {
> +              Status = gBS->ConnectController (
> +                              HandleArray[Index],
> +                              NULL,
> +                              RemainingDevicePath,
> +                              FALSE
> +                              );
> +              if (!EFI_ERROR(Status)) {
> +                AtLeastOneConnected = TRUE;
> +              }
> +            }
> +          }
> +        }
> +      }
> +    }
> +
> +    if (HandleArray != NULL) {
> +      FreePool (HandleArray);
> +    }
> +
> +    if (AtLeastOneConnected) {
> +      return EFI_SUCCESS;
> +    }
> +  }
> +
> +  return EFI_NOT_FOUND;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/BdsConsole.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/BdsConsole.c
> new file mode 100644
> index 0000000000..2fffd9e4bc
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/BdsConsole.c
> @@ -0,0 +1,1061 @@
> +/** @file
> +  BDS Lib functions which contain all the code to connect console device
> +
> +Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "InternalBdsLib.h"
> +
> +
> +/**
> +  Check if we need to save the EFI variable with "ConVarName" as name
> +  as NV type
> +  If ConVarName is NULL, then ASSERT().
> +
> +  @param ConVarName The name of the EFI variable.
> +
> +  @retval TRUE    Set the EFI variable as NV type.
> +  @retval FALSE   EFI variable as NV type can be set NonNV.
> +**/
> +BOOLEAN
> +IsNvNeed (
> +  IN CHAR16 *ConVarName
> +  )
> +{
> +  CHAR16 *Ptr;
> +
> +  ASSERT (ConVarName != NULL);
> +
> +  Ptr = ConVarName;
> +
> +  //
> +  // If the variable includes "Dev" at last, we consider
> +  // it does not support NV attribute.
> +  //
> +  while (*Ptr != L'\0') {
> +    Ptr++;
> +  }
> +
> +  if (((INTN)((UINTN)Ptr - (UINTN)ConVarName) / sizeof (CHAR16)) <= 3) {
> +    return TRUE;
> +  }
> +
> +  if ((*(Ptr - 3) == 'D') && (*(Ptr - 2) == 'e') && (*(Ptr - 1) == 'v')) {
> +    return FALSE;
> +  } else {
> +    return TRUE;
> +  }
> +}
> +
> +/**
> +  Fill console handle in System Table if there are no valid console handle in.
> +
> +  Firstly, check the validation of console handle in System Table. If it is invalid,
> +  update it by the first console device handle from EFI console variable.
> +
> +  @param  VarName            The name of the EFI console variable.
> +  @param  ConsoleGuid        Specified Console protocol GUID.
> +  @param  ConsoleHandle      On IN,  console handle in System Table to be
> checked.
> +                             On OUT, new console handle in system table.
> +  @param  ProtocolInterface  On IN,  console protocol on console handle in
> System Table to be checked.
> +                             On OUT, new console protocol on new console handle in
> system table.
> +
> +  @retval TRUE               System Table has been updated.
> +  @retval FALSE              System Table hasn't been updated.
> +
> +**/
> +BOOLEAN
> +UpdateSystemTableConsole (
> +  IN     CHAR16                          *VarName,
> +  IN     EFI_GUID                        *ConsoleGuid,
> +  IN OUT EFI_HANDLE                      *ConsoleHandle,
> +  IN OUT VOID                            **ProtocolInterface
> +  )
> +{
> +  EFI_STATUS                Status;
> +  UINTN                     DevicePathSize;
> +  EFI_DEVICE_PATH_PROTOCOL  *FullDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL  *VarConsole;
> +  EFI_DEVICE_PATH_PROTOCOL  *Instance;
> +  VOID                      *Interface;
> +  EFI_HANDLE                NewHandle;
> +  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut;
> +
> +  ASSERT (VarName != NULL);
> +  ASSERT (ConsoleHandle != NULL);
> +  ASSERT (ConsoleGuid != NULL);
> +  ASSERT (ProtocolInterface != NULL);
> +
> +  if (*ConsoleHandle != NULL) {
> +    Status = gBS->HandleProtocol (
> +                   *ConsoleHandle,
> +                   ConsoleGuid,
> +                   &Interface
> +                   );
> +    if (Status == EFI_SUCCESS && Interface == *ProtocolInterface) {
> +      //
> +      // If ConsoleHandle is valid and console protocol on this handle also
> +      // also matched, just return.
> +      //
> +      return FALSE;
> +    }
> +  }
> +
> +  //
> +  // Get all possible consoles device path from EFI variable
> +  //
> +  VarConsole = BdsLibGetVariableAndSize (
> +                VarName,
> +                &gEfiGlobalVariableGuid,
> +                &DevicePathSize
> +                );
> +  if (VarConsole == NULL) {
> +    //
> +    // If there is no any console device, just return.
> +    //
> +    return FALSE;
> +  }
> +
> +  FullDevicePath = VarConsole;
> +
> +  do {
> +    //
> +    // Check every instance of the console variable
> +    //
> +    Instance  = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);
> +    if (Instance == NULL) {
> +      FreePool (FullDevicePath);
> +      ASSERT (FALSE);
> +    }
> +
> +    //
> +    // Find console device handle by device path instance
> +    //
> +    Status = gBS->LocateDevicePath (
> +                   ConsoleGuid,
> +                   &Instance,
> +                   &NewHandle
> +                   );
> +    if (!EFI_ERROR (Status)) {
> +      //
> +      // Get the console protocol on this console device handle
> +      //
> +      Status = gBS->HandleProtocol (
> +                     NewHandle,
> +                     ConsoleGuid,
> +                     &Interface
> +                     );
> +      if (!EFI_ERROR (Status)) {
> +        //
> +        // Update new console handle in System Table.
> +        //
> +        *ConsoleHandle     = NewHandle;
> +        *ProtocolInterface = Interface;
> +        if (CompareGuid (ConsoleGuid, &gEfiSimpleTextOutProtocolGuid)) {
> +          //
> +          // If it is console out device, set console mode 80x25 if current mode is
> invalid.
> +          //
> +          TextOut = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *) Interface;
> +          if (TextOut->Mode->Mode == -1) {
> +            TextOut->SetMode (TextOut, 0);
> +          }
> +        }
> +        return TRUE;
> +      }
> +    }
> +
> +  } while (Instance != NULL);
> +
> +  //
> +  // No any available console devcie found.
> +  //
> +  return FALSE;
> +}
> +
> +/**
> +  This function update console variable based on ConVarName, it can
> +  add or remove one specific console device path from the variable
> +
> +  @param  ConVarName               Console related variable name, ConIn,
> ConOut,
> +                                   ErrOut.
> +  @param  CustomizedConDevicePath  The console device path which will
> be added to
> +                                   the console variable ConVarName, this parameter
> +                                   can not be multi-instance.
> +  @param  ExclusiveDevicePath      The console device path which will be
> removed
> +                                   from the console variable ConVarName, this
> +                                   parameter can not be multi-instance.
> +
> +  @retval EFI_UNSUPPORTED          The added device path is same to the
> removed one.
> +  @retval EFI_SUCCESS              Success add or remove the device path from
> the
> +                                   console variable.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BdsLibUpdateConsoleVariable (
> +  IN  CHAR16                    *ConVarName,
> +  IN  EFI_DEVICE_PATH_PROTOCOL  *CustomizedConDevicePath,
> +  IN  EFI_DEVICE_PATH_PROTOCOL  *ExclusiveDevicePath
> +  )
> +{
> +  EFI_STATUS                Status;
> +  EFI_DEVICE_PATH_PROTOCOL  *VarConsole;
> +  UINTN                     DevicePathSize;
> +  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL  *TempNewDevicePath;
> +  UINT32                    Attributes;
> +
> +  VarConsole      = NULL;
> +  DevicePathSize  = 0;
> +
> +  //
> +  // Notes: check the device path point, here should check
> +  // with compare memory
> +  //
> +  if (CustomizedConDevicePath == ExclusiveDevicePath) {
> +    return EFI_UNSUPPORTED;
> +  }
> +  //
> +  // Delete the ExclusiveDevicePath from current default console
> +  //
> +  VarConsole = BdsLibGetVariableAndSize (
> +                ConVarName,
> +                &gEfiGlobalVariableGuid,
> +                &DevicePathSize
> +                );
> +
> +  //
> +  // Initialize NewDevicePath
> +  //
> +  NewDevicePath  = VarConsole;
> +
> +  //
> +  // If ExclusiveDevicePath is even the part of the instance in VarConsole,
> delete it.
> +  // In the end, NewDevicePath is the final device path.
> +  //
> +  if (ExclusiveDevicePath != NULL && VarConsole != NULL) {
> +      NewDevicePath = BdsLibDelPartMatchInstance (VarConsole,
> ExclusiveDevicePath);
> +  }
> +  //
> +  // Try to append customized device path to NewDevicePath.
> +  //
> +  if (CustomizedConDevicePath != NULL) {
> +    if (!BdsLibMatchDevicePaths (NewDevicePath,
> CustomizedConDevicePath)) {
> +      //
> +      // Check if there is part of CustomizedConDevicePath in NewDevicePath,
> delete it.
> +      //
> +      NewDevicePath = BdsLibDelPartMatchInstance (NewDevicePath,
> CustomizedConDevicePath);
> +      //
> +      // In the first check, the default console variable will be
> _ModuleEntryPoint,
> +      // just append current customized device path
> +      //
> +      TempNewDevicePath = NewDevicePath;
> +      NewDevicePath = AppendDevicePathInstance (NewDevicePath,
> CustomizedConDevicePath);
> +      if (TempNewDevicePath != NULL) {
> +        FreePool(TempNewDevicePath);
> +      }
> +    }
> +  }
> +
> +  //
> +  // The attribute for ConInDev, ConOutDev and ErrOutDev does not include
> NV.
> +  //
> +  if (IsNvNeed(ConVarName)) {
> +    //
> +    // ConVarName has NV attribute.
> +    //
> +    Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;
> +  } else {
> +    //
> +    // ConVarName does not have NV attribute.
> +    //
> +    Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_RUNTIME_ACCESS;
> +  }
> +
> +  //
> +  // Finally, Update the variable of the default console by NewDevicePath
> +  //
> +  DevicePathSize = GetDevicePathSize (NewDevicePath);
> +  Status = SetVariableAndReportStatusCodeOnError (
> +             ConVarName,
> +             &gEfiGlobalVariableGuid,
> +             Attributes,
> +             DevicePathSize,
> +             NewDevicePath
> +             );
> +  if ((DevicePathSize == 0) && (Status == EFI_NOT_FOUND)) {
> +    Status = EFI_SUCCESS;
> +  }
> +
> +  if (VarConsole == NewDevicePath) {
> +    if (VarConsole != NULL) {
> +      FreePool(VarConsole);
> +    }
> +  } else {
> +    if (VarConsole != NULL) {
> +      FreePool(VarConsole);
> +    }
> +    if (NewDevicePath != NULL) {
> +      FreePool(NewDevicePath);
> +    }
> +  }
> +
> +  return Status;
> +
> +}
> +
> +
> +/**
> +  Connect the console device base on the variable ConVarName, if
> +  device path of the ConVarName is multi-instance device path and
> +  anyone of the instances is connected success, then this function
> +  will return success.
> +  If the handle associate with one device path node can not
> +  be created successfully, then still give chance to do the dispatch,
> +  which load the missing drivers if possible..
> +
> +  @param  ConVarName               Console related variable name, ConIn,
> ConOut,
> +                                   ErrOut.
> +
> +  @retval EFI_NOT_FOUND            There is not any console devices
> connected
> +                                   success
> +  @retval EFI_SUCCESS              Success connect any one instance of the
> console
> +                                   device path base on the variable ConVarName.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BdsLibConnectConsoleVariable (
> +  IN  CHAR16                 *ConVarName
> +  )
> +{
> +  EFI_STATUS                Status;
> +  EFI_DEVICE_PATH_PROTOCOL  *StartDevicePath;
> +  UINTN                     VariableSize;
> +  EFI_DEVICE_PATH_PROTOCOL  *Instance;
> +  EFI_DEVICE_PATH_PROTOCOL  *Next;
> +  EFI_DEVICE_PATH_PROTOCOL  *CopyOfDevicePath;
> +  UINTN                     Size;
> +  BOOLEAN                   DeviceExist;
> +
> +  Status      = EFI_SUCCESS;
> +  DeviceExist = FALSE;
> +
> +  //
> +  // Check if the console variable exist
> +  //
> +  StartDevicePath = BdsLibGetVariableAndSize (
> +                      ConVarName,
> +                      &gEfiGlobalVariableGuid,
> +                      &VariableSize
> +                      );
> +  if (StartDevicePath == NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  CopyOfDevicePath = StartDevicePath;
> +  do {
> +    //
> +    // Check every instance of the console variable
> +    //
> +    Instance  = GetNextDevicePathInstance (&CopyOfDevicePath, &Size);
> +    if (Instance == NULL) {
> +      FreePool (StartDevicePath);
> +      return EFI_UNSUPPORTED;
> +    }
> +
> +    Next      = Instance;
> +    while (!IsDevicePathEndType (Next)) {
> +      Next = NextDevicePathNode (Next);
> +    }
> +
> +    SetDevicePathEndNode (Next);
> +    //
> +    // Connect the USB console
> +    // USB console device path is a short-form device path that
> +    //  starts with the first element being a USB WWID
> +    //  or a USB Class device path
> +    //
> +    if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) &&
> +       ((DevicePathSubType (Instance) == MSG_USB_CLASS_DP)
> +       || (DevicePathSubType (Instance) == MSG_USB_WWID_DP)
> +       )) {
> +      Status = BdsLibConnectUsbDevByShortFormDP (0xFF, Instance);
> +      if (!EFI_ERROR (Status)) {
> +        DeviceExist = TRUE;
> +      }
> +    } else {
> +      //
> +      // Connect the instance device path
> +      //
> +      Status = BdsLibConnectDevicePath (Instance);
> +
> +      if (EFI_ERROR (Status)) {
> +        //
> +        // Delete the instance from the console varialbe
> +        //
> +        BdsLibUpdateConsoleVariable (ConVarName, NULL, Instance);
> +      } else {
> +        DeviceExist = TRUE;
> +      }
> +    }
> +    FreePool(Instance);
> +  } while (CopyOfDevicePath != NULL);
> +
> +  FreePool (StartDevicePath);
> +
> +  if (!DeviceExist) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function will search every simpletext device in current system,
> +  and make every simpletext device as pertantial console device.
> +
> +**/
> +VOID
> +EFIAPI
> +BdsLibConnectAllConsoles (
> +  VOID
> +  )
> +{
> +  UINTN                     Index;
> +  EFI_DEVICE_PATH_PROTOCOL  *ConDevicePath;
> +  UINTN                     HandleCount;
> +  EFI_HANDLE                *HandleBuffer;
> +
> +  Index         = 0;
> +  HandleCount   = 0;
> +  HandleBuffer  = NULL;
> +  ConDevicePath = NULL;
> +
> +  //
> +  // Update all the console variables
> +  //
> +  gBS->LocateHandleBuffer (
> +          ByProtocol,
> +          &gEfiSimpleTextInProtocolGuid,
> +          NULL,
> +          &HandleCount,
> +          &HandleBuffer
> +          );
> +
> +  for (Index = 0; Index < HandleCount; Index++) {
> +    gBS->HandleProtocol (
> +            HandleBuffer[Index],
> +            &gEfiDevicePathProtocolGuid,
> +            (VOID **) &ConDevicePath
> +            );
> +    BdsLibUpdateConsoleVariable (L"ConIn", ConDevicePath, NULL);
> +  }
> +
> +  if (HandleBuffer != NULL) {
> +    FreePool(HandleBuffer);
> +    HandleBuffer = NULL;
> +  }
> +
> +  gBS->LocateHandleBuffer (
> +          ByProtocol,
> +          &gEfiSimpleTextOutProtocolGuid,
> +          NULL,
> +          &HandleCount,
> +          &HandleBuffer
> +          );
> +  for (Index = 0; Index < HandleCount; Index++) {
> +    gBS->HandleProtocol (
> +            HandleBuffer[Index],
> +            &gEfiDevicePathProtocolGuid,
> +            (VOID **) &ConDevicePath
> +            );
> +    BdsLibUpdateConsoleVariable (L"ConOut", ConDevicePath, NULL);
> +    BdsLibUpdateConsoleVariable (L"ErrOut", ConDevicePath, NULL);
> +  }
> +
> +  if (HandleBuffer != NULL) {
> +    FreePool(HandleBuffer);
> +  }
> +
> +  //
> +  // Connect all console variables
> +  //
> +  BdsLibConnectAllDefaultConsoles ();
> +
> +}
> +
> +/**
> +  This function will connect console device base on the console
> +  device variable ConIn, ConOut and ErrOut.
> +
> +  @retval EFI_SUCCESS              At least one of the ConIn and ConOut device
> have
> +                                   been connected success.
> +  @retval EFI_STATUS               Return the status of
> BdsLibConnectConsoleVariable ().
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BdsLibConnectAllDefaultConsoles (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                Status;
> +  BOOLEAN                   SystemTableUpdated;
> +
> +  //
> +  // Connect all default console variables
> +  //
> +
> +  //
> +  // It seems impossible not to have any ConOut device on platform,
> +  // so we check the status here.
> +  //
> +  Status = BdsLibConnectConsoleVariable (L"ConOut");
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Insert the performance probe for Console Out
> +  //
> +  PERF_START (NULL, "ConOut", "BDS", 1);
> +  PERF_END (NULL, "ConOut", "BDS", 0);
> +
> +  //
> +  // Because possibly the platform is legacy free, in such case,
> +  // ConIn devices (Serial Port and PS2 Keyboard ) does not exist,
> +  // so we need not check the status.
> +  //
> +  BdsLibConnectConsoleVariable (L"ConIn");
> +
> +  //
> +  // The _ModuleEntryPoint err out var is legal.
> +  //
> +  BdsLibConnectConsoleVariable (L"ErrOut");
> +
> +  SystemTableUpdated = FALSE;
> +  //
> +  // Fill console handles in System Table if no console device assignd.
> +  //
> +  if (UpdateSystemTableConsole (L"ConIn", &gEfiSimpleTextInProtocolGuid,
> &gST->ConsoleInHandle, (VOID **) &gST->ConIn)) {
> +    SystemTableUpdated = TRUE;
> +  }
> +  if (UpdateSystemTableConsole (L"ConOut",
> &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **)
> &gST->ConOut)) {
> +    SystemTableUpdated = TRUE;
> +  }
> +  if (UpdateSystemTableConsole (L"ErrOut",
> &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **)
> &gST->StdErr)) {
> +    SystemTableUpdated = TRUE;
> +  }
> +
> +  if (SystemTableUpdated) {
> +    //
> +    // Update the CRC32 in the EFI System Table header
> +    //
> +    gST->Hdr.CRC32 = 0;
> +    gBS->CalculateCrc32 (
> +          (UINT8 *) &gST->Hdr,
> +          gST->Hdr.HeaderSize,
> +          &gST->Hdr.CRC32
> +          );
> +  }
> +
> +  //
> +  // If any component set PcdTestKeyUsed to TRUE because use of a test
> key
> +  // was detected, then display a warning message on the debug log and the
> console
> +  //
> +  if (PcdGetBool (PcdTestKeyUsed) == TRUE) {
> +    DEBUG ((DEBUG_ERROR,
> "**********************************\n"));
> +    DEBUG ((DEBUG_ERROR, "**  WARNING: Test Key is used.  **\n"));
> +    DEBUG ((DEBUG_ERROR,
> "**********************************\n"));
> +    Print (L"**  WARNING: Test Key is used.  **\n");
> +  }
> +
> +  return EFI_SUCCESS;
> +
> +}
> +
> +/**
> +  This function will connect console device except ConIn base on the console
> +  device variable  ConOut and ErrOut.
> +
> +  @retval EFI_SUCCESS              At least one of the ConOut device have
> +                                   been connected success.
> +  @retval EFI_STATUS               Return the status of
> BdsLibConnectConsoleVariable ().
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BdsLibConnectAllDefaultConsolesWithOutConIn (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                Status;
> +  BOOLEAN                   SystemTableUpdated;
> +
> +  //
> +  // Connect all default console variables except ConIn
> +  //
> +
> +  //
> +  // It seems impossible not to have any ConOut device on platform,
> +  // so we check the status here.
> +  //
> +  Status = BdsLibConnectConsoleVariable (L"ConOut");
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Insert the performance probe for Console Out
> +  //
> +  PERF_START (NULL, "ConOut", "BDS", 1);
> +  PERF_END (NULL, "ConOut", "BDS", 0);
> +
> +  //
> +  // The _ModuleEntryPoint err out var is legal.
> +  //
> +  BdsLibConnectConsoleVariable (L"ErrOut");
> +
> +  SystemTableUpdated = FALSE;
> +  //
> +  // Fill console handles in System Table if no console device assignd.
> +  //
> +  if (UpdateSystemTableConsole (L"ConOut",
> &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **)
> &gST->ConOut)) {
> +    SystemTableUpdated = TRUE;
> +  }
> +  if (UpdateSystemTableConsole (L"ErrOut",
> &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **)
> &gST->StdErr)) {
> +    SystemTableUpdated = TRUE;
> +  }
> +
> +  if (SystemTableUpdated) {
> +    //
> +    // Update the CRC32 in the EFI System Table header
> +    //
> +    gST->Hdr.CRC32 = 0;
> +    gBS->CalculateCrc32 (
> +          (UINT8 *) &gST->Hdr,
> +          gST->Hdr.HeaderSize,
> +          &gST->Hdr.CRC32
> +          );
> +  }
> +
> +  return EFI_SUCCESS;
> +
> +}
> +
> +/**
> +  Use SystemTable Conout to stop video based Simple Text Out consoles
> from going
> +  to the video device. Put up LogoFile on every video device that is a console.
> +
> +  @param[in]  LogoFile   File name of logo to display on the center of the
> screen.
> +
> +  @retval EFI_SUCCESS     ConsoleControl has been flipped to graphics and
> logo displayed.
> +  @retval EFI_UNSUPPORTED Logo not found
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +EnableQuietBoot (
> +  IN  EFI_GUID  *LogoFile
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  EFI_OEM_BADGING_PROTOCOL      *Badging;
> +  UINT32                        SizeOfX;
> +  UINT32                        SizeOfY;
> +  INTN                          DestX;
> +  INTN                          DestY;
> +  UINT8                         *ImageData;
> +  UINTN                         ImageSize;
> +  UINTN                         BltSize;
> +  UINT32                        Instance;
> +  EFI_BADGING_FORMAT            Format;
> +  EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;
> +  UINTN                         CoordinateX;
> +  UINTN                         CoordinateY;
> +  UINTN                         Height;
> +  UINTN                         Width;
> +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
> +  EFI_UGA_DRAW_PROTOCOL         *UgaDraw;
> +  UINT32                        ColorDepth;
> +  UINT32                        RefreshRate;
> +  EFI_GRAPHICS_OUTPUT_PROTOCOL  *GraphicsOutput;
> +  EFI_BOOT_LOGO_PROTOCOL        *BootLogo;
> +  UINTN                         NumberOfLogos;
> +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LogoBlt;
> +  UINTN                         LogoDestX;
> +  UINTN                         LogoDestY;
> +  UINTN                         LogoHeight;
> +  UINTN                         LogoWidth;
> +  UINTN                         NewDestX;
> +  UINTN                         NewDestY;
> +  UINTN                         NewHeight;
> +  UINTN                         NewWidth;
> +  UINT64                        BufferSize;
> +
> +  UgaDraw = NULL;
> +  //
> +  // Try to open GOP first
> +  //
> +  Status = gBS->HandleProtocol (gST->ConsoleOutHandle,
> &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);
> +  if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
> +    GraphicsOutput = NULL;
> +    //
> +    // Open GOP failed, try to open UGA
> +    //
> +    Status = gBS->HandleProtocol (gST->ConsoleOutHandle,
> &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);
> +  }
> +  if (EFI_ERROR (Status)) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Try to open Boot Logo Protocol.
> +  //
> +  BootLogo = NULL;
> +  gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **)
> &BootLogo);
> +
> +  //
> +  // Erase Cursor from screen
> +  //
> +  gST->ConOut->EnableCursor (gST->ConOut, FALSE);
> +
> +  Badging = NULL;
> +  Status  = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL,
> (VOID **) &Badging);
> +
> +  if (GraphicsOutput != NULL) {
> +    SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;
> +    SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;
> +
> +  } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport))
> {
> +    Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY,
> &ColorDepth, &RefreshRate);
> +    if (EFI_ERROR (Status)) {
> +      return EFI_UNSUPPORTED;
> +    }
> +  } else {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  Blt = NULL;
> +  NumberOfLogos = 0;
> +  LogoDestX = 0;
> +  LogoDestY = 0;
> +  LogoHeight = 0;
> +  LogoWidth = 0;
> +  NewDestX = 0;
> +  NewDestY = 0;
> +  NewHeight = 0;
> +  NewWidth = 0;
> +  Instance = 0;
> +  while (1) {
> +    ImageData = NULL;
> +    ImageSize = 0;
> +
> +    if (Badging != NULL) {
> +      //
> +      // Get image from OEMBadging protocol.
> +      //
> +      Status = Badging->GetImage (
> +                          Badging,
> +                          &Instance,
> +                          &Format,
> +                          &ImageData,
> +                          &ImageSize,
> +                          &Attribute,
> +                          &CoordinateX,
> +                          &CoordinateY
> +                          );
> +      if (EFI_ERROR (Status)) {
> +        goto Done;
> +      }
> +
> +      //
> +      // Currently only support BMP format.
> +      //
> +      if (Format != EfiBadgingFormatBMP) {
> +        if (ImageData != NULL) {
> +          FreePool (ImageData);
> +        }
> +        continue;
> +      }
> +    } else {
> +      //
> +      // Get the specified image from FV.
> +      //
> +      Status = GetSectionFromAnyFv (LogoFile, EFI_SECTION_RAW, 0, (VOID
> **) &ImageData, &ImageSize);
> +      if (EFI_ERROR (Status)) {
> +        return EFI_UNSUPPORTED;
> +      }
> +
> +      CoordinateX = 0;
> +      CoordinateY = 0;
> +      if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
> +        Attribute   = EfiBadgingDisplayAttributeCenter;
> +      } else {
> +        Attribute   = EfiBadgingDisplayAttributeCustomized;
> +      }
> +    }
> +
> +    if (Blt != NULL) {
> +      FreePool (Blt);
> +    }
> +    Blt = NULL;
> +    Status = TranslateBmpToGopBlt (
> +              ImageData,
> +              ImageSize,
> +              &Blt,
> +              &BltSize,
> +              &Height,
> +              &Width
> +              );
> +    if (EFI_ERROR (Status)) {
> +      FreePool (ImageData);
> +
> +      if (Badging == NULL) {
> +        return Status;
> +      } else {
> +        continue;
> +      }
> +    }
> +
> +    //
> +    // Calculate the display position according to Attribute.
> +    //
> +    switch (Attribute) {
> +    case EfiBadgingDisplayAttributeLeftTop:
> +      DestX = CoordinateX;
> +      DestY = CoordinateY;
> +      break;
> +
> +    case EfiBadgingDisplayAttributeCenterTop:
> +      DestX = (SizeOfX - Width) / 2;
> +      DestY = CoordinateY;
> +      break;
> +
> +    case EfiBadgingDisplayAttributeRightTop:
> +      DestX = (SizeOfX - Width - CoordinateX);
> +      DestY = CoordinateY;;
> +      break;
> +
> +    case EfiBadgingDisplayAttributeCenterRight:
> +      DestX = (SizeOfX - Width - CoordinateX);
> +      DestY = (SizeOfY - Height) / 2;
> +      break;
> +
> +    case EfiBadgingDisplayAttributeRightBottom:
> +      DestX = (SizeOfX - Width - CoordinateX);
> +      DestY = (SizeOfY - Height - CoordinateY);
> +      break;
> +
> +    case EfiBadgingDisplayAttributeCenterBottom:
> +      DestX = (SizeOfX - Width) / 2;
> +      DestY = (SizeOfY - Height - CoordinateY);
> +      break;
> +
> +    case EfiBadgingDisplayAttributeLeftBottom:
> +      DestX = CoordinateX;
> +      DestY = (SizeOfY - Height - CoordinateY);
> +      break;
> +
> +    case EfiBadgingDisplayAttributeCenterLeft:
> +      DestX = CoordinateX;
> +      DestY = (SizeOfY - Height) / 2;
> +      break;
> +
> +    case EfiBadgingDisplayAttributeCenter:
> +      DestX = (SizeOfX - Width) / 2;
> +      DestY = (SizeOfY - Height) / 2;
> +      break;
> +
> +    case EfiBadgingDisplayAttributeCustomized:
> +      DestX = (SizeOfX - Width) / 2;
> +      DestY = ((SizeOfY * 382) / 1000) - Height / 2;
> +      break;
> +
> +    default:
> +      DestX = CoordinateX;
> +      DestY = CoordinateY;
> +      break;
> +    }
> +
> +    if ((DestX >= 0) && (DestY >= 0)) {
> +      if (GraphicsOutput != NULL) {
> +        Status = GraphicsOutput->Blt (
> +                            GraphicsOutput,
> +                            Blt,
> +                            EfiBltBufferToVideo,
> +                            0,
> +                            0,
> +                            (UINTN) DestX,
> +                            (UINTN) DestY,
> +                            Width,
> +                            Height,
> +                            Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
> +                            );
> +      } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport))
> {
> +        Status = UgaDraw->Blt (
> +                            UgaDraw,
> +                            (EFI_UGA_PIXEL *) Blt,
> +                            EfiUgaBltBufferToVideo,
> +                            0,
> +                            0,
> +                            (UINTN) DestX,
> +                            (UINTN) DestY,
> +                            Width,
> +                            Height,
> +                            Width * sizeof (EFI_UGA_PIXEL)
> +                            );
> +      } else {
> +        Status = EFI_UNSUPPORTED;
> +      }
> +
> +      //
> +      // Report displayed Logo information.
> +      //
> +      if (!EFI_ERROR (Status)) {
> +        NumberOfLogos++;
> +
> +        if (LogoWidth == 0) {
> +          //
> +          // The first Logo.
> +          //
> +          LogoDestX = (UINTN) DestX;
> +          LogoDestY = (UINTN) DestY;
> +          LogoWidth = Width;
> +          LogoHeight = Height;
> +        } else {
> +          //
> +          // Merge new logo with old one.
> +          //
> +          NewDestX = MIN ((UINTN) DestX, LogoDestX);
> +          NewDestY = MIN ((UINTN) DestY, LogoDestY);
> +          NewWidth = MAX ((UINTN) DestX + Width, LogoDestX + LogoWidth) -
> NewDestX;
> +          NewHeight = MAX ((UINTN) DestY + Height, LogoDestY + LogoHeight) -
> NewDestY;
> +
> +          LogoDestX = NewDestX;
> +          LogoDestY = NewDestY;
> +          LogoWidth = NewWidth;
> +          LogoHeight = NewHeight;
> +        }
> +      }
> +    }
> +
> +    FreePool (ImageData);
> +
> +    if (Badging == NULL) {
> +      break;
> +    }
> +  }
> +
> +Done:
> +  if (BootLogo == NULL || NumberOfLogos == 0) {
> +    //
> +    // No logo displayed.
> +    //
> +    if (Blt != NULL) {
> +      FreePool (Blt);
> +    }
> +
> +    return Status;
> +  }
> +
> +  //
> +  // Advertise displayed Logo information.
> +  //
> +  if (NumberOfLogos == 1) {
> +    //
> +    // Only one logo displayed, use its Blt buffer directly for BootLogo
> protocol.
> +    //
> +    LogoBlt = Blt;
> +    Status = EFI_SUCCESS;
> +  } else {
> +    //
> +    // More than one Logo displayed, get merged BltBuffer using
> VideoToBuffer operation.
> +    //
> +    if (Blt != NULL) {
> +      FreePool (Blt);
> +    }
> +
> +    //
> +    // Ensure the LogoHeight * LogoWidth doesn't overflow
> +    //
> +    if (LogoHeight > DivU64x64Remainder ((UINTN) ~0, LogoWidth, NULL)) {
> +      return EFI_UNSUPPORTED;
> +    }
> +    BufferSize = MultU64x64 (LogoWidth, LogoHeight);
> +
> +    //
> +    // Ensure the BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
> doesn't overflow
> +    //
> +    if (BufferSize > DivU64x32 ((UINTN) ~0, sizeof
> (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
> +      return EFI_UNSUPPORTED;
> +    }
> +
> +    LogoBlt = AllocateZeroPool ((UINTN)BufferSize * sizeof
> (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
> +    if (LogoBlt == NULL) {
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +
> +    if (GraphicsOutput != NULL) {
> +      Status = GraphicsOutput->Blt (
> +                          GraphicsOutput,
> +                          LogoBlt,
> +                          EfiBltVideoToBltBuffer,
> +                          LogoDestX,
> +                          LogoDestY,
> +                          0,
> +                          0,
> +                          LogoWidth,
> +                          LogoHeight,
> +                          LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
> +                          );
> +    } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport))
> {
> +      Status = UgaDraw->Blt (
> +                          UgaDraw,
> +                          (EFI_UGA_PIXEL *) LogoBlt,
> +                          EfiUgaVideoToBltBuffer,
> +                          LogoDestX,
> +                          LogoDestY,
> +                          0,
> +                          0,
> +                          LogoWidth,
> +                          LogoHeight,
> +                          LogoWidth * sizeof (EFI_UGA_PIXEL)
> +                          );
> +    } else {
> +      Status = EFI_UNSUPPORTED;
> +    }
> +  }
> +
> +  if (!EFI_ERROR (Status)) {
> +    BootLogo->SetBootLogo (BootLogo, LogoBlt, LogoDestX, LogoDestY,
> LogoWidth, LogoHeight);
> +  }
> +  FreePool (LogoBlt);
> +
> +  return Status;
> +}
> +
> +/**
> +  Use SystemTable Conout to turn on video based Simple Text Out consoles.
> The
> +  Simple Text Out screens will now be synced up with all non video output
> devices
> +
> +  @retval EFI_SUCCESS     UGA devices are back in text mode and synced up.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DisableQuietBoot (
> +  VOID
> +  )
> +{
> +
> +  //
> +  // Enable Cursor on Screen
> +  //
> +  gST->ConOut->EnableCursor (gST->ConOut, TRUE);
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/BdsMisc.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/BdsMisc.c
> new file mode 100644
> index 0000000000..313a1ea9f6
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/BdsMisc.c
> @@ -0,0 +1,1575 @@
> +/** @file
> +  Misc BDS library function
> +
> +Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "InternalBdsLib.h"
> +
> +
> +#define MAX_STRING_LEN        200
> +
> +BOOLEAN   mFeaturerSwitch = TRUE;
> +BOOLEAN   mResetRequired  = FALSE;
> +
> +extern UINT16 gPlatformBootTimeOutDefault;
> +
> +/**
> +  The function will go through the driver option link list, load and start
> +  every driver the driver option device path point to.
> +
> +  @param  BdsDriverLists        The header of the current driver option link list
> +
> +**/
> +VOID
> +EFIAPI
> +BdsLibLoadDrivers (
> +  IN LIST_ENTRY                   *BdsDriverLists
> +  )
> +{
> +  EFI_STATUS                Status;
> +  LIST_ENTRY                *Link;
> +  BDS_COMMON_OPTION         *Option;
> +  EFI_HANDLE                ImageHandle;
> +  EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;
> +  UINTN                     ExitDataSize;
> +  CHAR16                    *ExitData;
> +  BOOLEAN                   ReconnectAll;
> +
> +  ReconnectAll = FALSE;
> +
> +  //
> +  // Process the driver option
> +  //
> +  for (Link = BdsDriverLists->ForwardLink; Link != BdsDriverLists; Link = Link-
> >ForwardLink) {
> +    Option = CR (Link, BDS_COMMON_OPTION, Link,
> BDS_LOAD_OPTION_SIGNATURE);
> +
> +    //
> +    // If a load option is not marked as LOAD_OPTION_ACTIVE,
> +    // the boot manager will not automatically load the option.
> +    //
> +    if (!IS_LOAD_OPTION_TYPE (Option->Attribute, LOAD_OPTION_ACTIVE))
> {
> +      continue;
> +    }
> +
> +    //
> +    // If a driver load option is marked as LOAD_OPTION_FORCE_RECONNECT,
> +    // then all of the EFI drivers in the system will be disconnected and
> +    // reconnected after the last driver load option is processed.
> +    //
> +    if (IS_LOAD_OPTION_TYPE (Option->Attribute,
> LOAD_OPTION_FORCE_RECONNECT)) {
> +      ReconnectAll = TRUE;
> +    }
> +
> +    //
> +    // Make sure the driver path is connected.
> +    //
> +    BdsLibConnectDevicePath (Option->DevicePath);
> +
> +    //
> +    // Load and start the image that Driver#### describes
> +    //
> +    Status = gBS->LoadImage (
> +                    FALSE,
> +                    gImageHandle,
> +                    Option->DevicePath,
> +                    NULL,
> +                    0,
> +                    &ImageHandle
> +                    );
> +
> +    if (!EFI_ERROR (Status)) {
> +      gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid,
> (VOID **) &ImageInfo);
> +
> +      //
> +      // Verify whether this image is a driver, if not,
> +      // exit it and continue to parse next load option
> +      //
> +      if (ImageInfo->ImageCodeType != EfiBootServicesCode && ImageInfo-
> >ImageCodeType != EfiRuntimeServicesCode) {
> +        gBS->Exit (ImageHandle, EFI_INVALID_PARAMETER, 0, NULL);
> +        continue;
> +      }
> +
> +      if (Option->LoadOptionsSize != 0) {
> +        ImageInfo->LoadOptionsSize  = Option->LoadOptionsSize;
> +        ImageInfo->LoadOptions      = Option->LoadOptions;
> +      }
> +      //
> +      // Before calling the image, enable the Watchdog Timer for
> +      // the 5 Minute period
> +      //
> +      gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);
> +
> +      Status = gBS->StartImage (ImageHandle, &ExitDataSize, &ExitData);
> +      DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Driver Return Status = %r\n",
> Status));
> +
> +      //
> +      // Clear the Watchdog Timer after the image returns
> +      //
> +      gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
> +    }
> +  }
> +
> +  //
> +  // Process the LOAD_OPTION_FORCE_RECONNECT driver option
> +  //
> +  if (ReconnectAll) {
> +    BdsLibDisconnectAllEfi ();
> +    BdsLibConnectAll ();
> +  }
> +
> +}
> +
> +/**
> +  Get the Option Number that does not used.
> +  Try to locate the specific option variable one by one utile find a free
> number.
> +
> +  @param  VariableName          Indicate if the boot#### or driver#### option
> +
> +  @return The Minimal Free Option Number
> +
> +**/
> +UINT16
> +BdsLibGetFreeOptionNumber (
> +  IN  CHAR16    *VariableName
> +  )
> +{
> +  UINTN         Index;
> +  CHAR16        StrTemp[10];
> +  UINT16        *OptionBuffer;
> +  UINTN         OptionSize;
> +
> +  //
> +  // Try to find the minimum free number from 0, 1, 2, 3....
> +  //
> +  Index = 0;
> +  do {
> +    if (*VariableName == 'B') {
> +      UnicodeSPrint (StrTemp, sizeof (StrTemp), L"Boot%04x", Index);
> +    } else {
> +      UnicodeSPrint (StrTemp, sizeof (StrTemp), L"Driver%04x", Index);
> +    }
> +    //
> +    // try if the option number is used
> +    //
> +    OptionBuffer = BdsLibGetVariableAndSize (
> +                     StrTemp,
> +                     &gEfiGlobalVariableGuid,
> +                     &OptionSize
> +                     );
> +    if (OptionBuffer == NULL) {
> +      break;
> +    }
> +    FreePool(OptionBuffer);
> +    Index++;
> +  } while (TRUE);
> +
> +  return ((UINT16) Index);
> +}
> +
> +
> +/**
> +  This function will register the new boot#### or driver#### option base on
> +  the VariableName. The new registered boot#### or driver#### will be
> linked
> +  to BdsOptionList and also update to the VariableName. After the
> boot#### or
> +  driver#### updated, the BootOrder or DriverOrder will also be updated.
> +
> +  @param  BdsOptionList         The header of the boot#### or driver#### link
> list
> +  @param  DevicePath            The device path which the boot#### or
> driver####
> +                                option present
> +  @param  String                The description of the boot#### or driver####
> +  @param  VariableName          Indicate if the boot#### or driver#### option
> +
> +  @retval EFI_SUCCESS           The boot#### or driver#### have been success
> +                                registered
> +  @retval EFI_STATUS            Return the status of gRT->SetVariable ().
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BdsLibRegisterNewOption (
> +  IN  LIST_ENTRY                     *BdsOptionList,
> +  IN  EFI_DEVICE_PATH_PROTOCOL       *DevicePath,
> +  IN  CHAR16                         *String,
> +  IN  CHAR16                         *VariableName
> +  )
> +{
> +  EFI_STATUS                Status;
> +  UINTN                     Index;
> +  UINT16                    RegisterOptionNumber;
> +  UINT16                    *TempOptionPtr;
> +  UINTN                     TempOptionSize;
> +  UINT16                    *OptionOrderPtr;
> +  VOID                      *OptionPtr;
> +  UINTN                     OptionSize;
> +  UINT8                     *TempPtr;
> +  EFI_DEVICE_PATH_PROTOCOL  *OptionDevicePath;
> +  CHAR16                    *Description;
> +  CHAR16                    OptionName[10];
> +  BOOLEAN                   UpdateDescription;
> +  UINT16                    BootOrderEntry;
> +  UINTN                     OrderItemNum;
> +
> +  if (DevicePath == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  OptionPtr             = NULL;
> +  OptionSize            = 0;
> +  TempPtr               = NULL;
> +  OptionDevicePath      = NULL;
> +  Description           = NULL;
> +  OptionOrderPtr        = NULL;
> +  UpdateDescription     = FALSE;
> +  Status                = EFI_SUCCESS;
> +  ZeroMem (OptionName, sizeof (OptionName));
> +
> +  TempOptionSize = 0;
> +  TempOptionPtr = BdsLibGetVariableAndSize (
> +                    VariableName,
> +                    &gEfiGlobalVariableGuid,
> +                    &TempOptionSize
> +                    );
> +  //
> +  // Compare with current option variable if the previous option is set in
> global variable.
> +  //
> +  for (Index = 0; Index < TempOptionSize / sizeof (UINT16); Index++) {
> +    //
> +    // TempOptionPtr must not be NULL if we have non-zero
> TempOptionSize.
> +    //
> +    ASSERT (TempOptionPtr != NULL);
> +
> +    if (*VariableName == 'B') {
> +      UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x",
> TempOptionPtr[Index]);
> +    } else {
> +      UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x",
> TempOptionPtr[Index]);
> +    }
> +
> +    OptionPtr = BdsLibGetVariableAndSize (
> +                  OptionName,
> +                  &gEfiGlobalVariableGuid,
> +                  &OptionSize
> +                  );
> +    if (OptionPtr == NULL) {
> +      continue;
> +    }
> +
> +    //
> +    // Validate the variable.
> +    //
> +    if (!ValidateOption(OptionPtr, OptionSize)) {
> +      FreePool(OptionPtr);
> +      continue;
> +    }
> +
> +    TempPtr         =   OptionPtr;
> +    TempPtr         +=  sizeof (UINT32) + sizeof (UINT16);
> +    Description     =   (CHAR16 *) TempPtr;
> +    TempPtr         +=  StrSize ((CHAR16 *) TempPtr);
> +    OptionDevicePath =  (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
> +
> +    //
> +    // Notes: the description may will change base on the GetStringToken
> +    //
> +    if (CompareMem (OptionDevicePath, DevicePath, GetDevicePathSize
> (OptionDevicePath)) == 0) {
> +      if (CompareMem (Description, String, StrSize (Description)) == 0) {
> +        //
> +        // Got the option, so just return
> +        //
> +        FreePool (OptionPtr);
> +        FreePool (TempOptionPtr);
> +        return EFI_SUCCESS;
> +      } else {
> +        //
> +        // Option description changed, need update.
> +        //
> +        UpdateDescription = TRUE;
> +        FreePool (OptionPtr);
> +        break;
> +      }
> +    }
> +
> +    FreePool (OptionPtr);
> +  }
> +
> +  OptionSize          = sizeof (UINT32) + sizeof (UINT16) + StrSize (String);
> +  OptionSize          += GetDevicePathSize (DevicePath);
> +  OptionPtr           = AllocateZeroPool (OptionSize);
> +  ASSERT (OptionPtr != NULL);
> +
> +  TempPtr             = OptionPtr;
> +  *(UINT32 *) TempPtr = LOAD_OPTION_ACTIVE;
> +  TempPtr             += sizeof (UINT32);
> +  *(UINT16 *) TempPtr = (UINT16) GetDevicePathSize (DevicePath);
> +  TempPtr             += sizeof (UINT16);
> +  CopyMem (TempPtr, String, StrSize (String));
> +  TempPtr             += StrSize (String);
> +  CopyMem (TempPtr, DevicePath, GetDevicePathSize (DevicePath));
> +
> +  if (UpdateDescription) {
> +    //
> +    // The number in option#### to be updated.
> +    // In this case, we must have non-NULL TempOptionPtr.
> +    //
> +    ASSERT (TempOptionPtr != NULL);
> +    RegisterOptionNumber = TempOptionPtr[Index];
> +  } else {
> +    //
> +    // The new option#### number
> +    //
> +    RegisterOptionNumber = BdsLibGetFreeOptionNumber(VariableName);
> +  }
> +
> +  if (*VariableName == 'B') {
> +    UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x",
> RegisterOptionNumber);
> +  } else {
> +    UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x",
> RegisterOptionNumber);
> +  }
> +
> +  Status = gRT->SetVariable (
> +                  OptionName,
> +                  &gEfiGlobalVariableGuid,
> +                  EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
> +                  OptionSize,
> +                  OptionPtr
> +                  );
> +  //
> +  // Return if only need to update a changed description or fail to set option.
> +  //
> +  if (EFI_ERROR (Status) || UpdateDescription) {
> +    FreePool (OptionPtr);
> +    if (TempOptionPtr != NULL) {
> +      FreePool (TempOptionPtr);
> +    }
> +    return Status;
> +  }
> +
> +  FreePool (OptionPtr);
> +
> +  //
> +  // Update the option order variable
> +  //
> +
> +  //
> +  // If no option order
> +  //
> +  if (TempOptionSize == 0) {
> +    BootOrderEntry = 0;
> +    Status = gRT->SetVariable (
> +                    VariableName,
> +                    &gEfiGlobalVariableGuid,
> +                    EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
> +                    sizeof (UINT16),
> +                    &BootOrderEntry
> +                    );
> +    if (TempOptionPtr != NULL) {
> +      FreePool (TempOptionPtr);
> +    }
> +    return Status;
> +  }
> +
> +  //
> +  // TempOptionPtr must not be NULL if TempOptionSize is not zero.
> +  //
> +  ASSERT (TempOptionPtr != NULL);
> +  //
> +  // Append the new option number to the original option order
> +  //
> +  OrderItemNum = (TempOptionSize / sizeof (UINT16)) + 1 ;
> +  OptionOrderPtr = AllocateZeroPool ( OrderItemNum * sizeof (UINT16));
> +  ASSERT (OptionOrderPtr!= NULL);
> +  CopyMem (OptionOrderPtr, TempOptionPtr, (OrderItemNum - 1) * sizeof
> (UINT16));
> +
> +  OptionOrderPtr[Index] = RegisterOptionNumber;
> +
> +  Status = gRT->SetVariable (
> +                  VariableName,
> +                  &gEfiGlobalVariableGuid,
> +                  EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
> +                  OrderItemNum * sizeof (UINT16),
> +                  OptionOrderPtr
> +                  );
> +  FreePool (TempOptionPtr);
> +  FreePool (OptionOrderPtr);
> +
> +  return Status;
> +}
> +
> +/**
> +  Returns the size of a device path in bytes.
> +
> +  This function returns the size, in bytes, of the device path data structure
> +  specified by DevicePath including the end of device path node. If
> DevicePath
> +  is NULL, then 0 is returned. If the length of the device path is bigger than
> +  MaxSize, also return 0 to indicate this is an invalidate device path.
> +
> +  @param  DevicePath         A pointer to a device path data structure.
> +  @param  MaxSize            Max valid device path size. If big than this size,
> +                             return error.
> +
> +  @retval 0                  An invalid device path.
> +  @retval Others             The size of a device path in bytes.
> +
> +**/
> +UINTN
> +GetDevicePathSizeEx (
> +  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
> +  IN UINTN                           MaxSize
> +  )
> +{
> +  UINTN  Size;
> +  UINTN  NodeSize;
> +
> +  if (DevicePath == NULL) {
> +    return 0;
> +  }
> +
> +  //
> +  // Search for the end of the device path structure
> +  //
> +  Size = 0;
> +  while (!IsDevicePathEnd (DevicePath)) {
> +    NodeSize = DevicePathNodeLength (DevicePath);
> +    if (NodeSize < END_DEVICE_PATH_LENGTH) {
> +      return 0;
> +    }
> +    Size += NodeSize;
> +    if (Size > MaxSize) {
> +      return 0;
> +    }
> +    DevicePath = NextDevicePathNode (DevicePath);
> +  }
> +  Size += DevicePathNodeLength (DevicePath);
> +  if (Size > MaxSize) {
> +    return 0;
> +  }
> +
> +  return Size;
> +}
> +
> +/**
> +  Returns the length of a Null-terminated Unicode string. If the length is
> +  bigger than MaxStringLen, return length 0 to indicate that this is an
> +  invalidate string.
> +
> +  This function returns the byte length of Unicode characters in the Null-
> terminated
> +  Unicode string specified by String.
> +
> +  If String is NULL, then ASSERT().
> +  If String is not aligned on a 16-bit boundary, then ASSERT().
> +
> +  @param  String           A pointer to a Null-terminated Unicode string.
> +  @param  MaxStringLen     Max string len in this string.
> +
> +  @retval 0                An invalid string.
> +  @retval Others           The length of String.
> +
> +**/
> +UINTN
> +StrSizeEx (
> +  IN      CONST CHAR16              *String,
> +  IN      UINTN                     MaxStringLen
> +  )
> +{
> +  UINTN                             Length;
> +
> +  ASSERT (String != NULL && MaxStringLen != 0);
> +  ASSERT (((UINTN) String & BIT0) == 0);
> +
> +  for (Length = 0; *String != L'\0' && MaxStringLen != Length; String++,
> Length+=2);
> +
> +  if (*String != L'\0' && MaxStringLen == Length) {
> +    return 0;
> +  }
> +
> +  return Length + 2;
> +}
> +
> +/**
> +  Validate the EFI Boot#### variable (VendorGuid/Name)
> +
> +  @param  Variable              Boot#### variable data.
> +  @param  VariableSize          Returns the size of the EFI variable that was
> read
> +
> +  @retval TRUE                  The variable data is correct.
> +  @retval FALSE                 The variable data is corrupted.
> +
> +**/
> +BOOLEAN
> +ValidateOption (
> +  UINT8                     *Variable,
> +  UINTN                     VariableSize
> +  )
> +{
> +  UINT16                    FilePathSize;
> +  UINT8                     *TempPtr;
> +  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
> +  UINTN                     TempSize;
> +
> +  if (VariableSize <= sizeof (UINT16) + sizeof (UINT32)) {
> +    return FALSE;
> +  }
> +
> +  //
> +  // Skip the option attribute
> +  //
> +  TempPtr    = Variable;
> +  TempPtr   += sizeof (UINT32);
> +
> +  //
> +  // Get the option's device path size
> +  //
> +  FilePathSize  = *(UINT16 *) TempPtr;
> +  TempPtr      += sizeof (UINT16);
> +
> +  //
> +  // Get the option's description string size
> +  //
> +  TempSize = StrSizeEx ((CHAR16 *) TempPtr, VariableSize - sizeof (UINT16) -
> sizeof (UINT32));
> +  TempPtr += TempSize;
> +
> +  //
> +  // Get the option's device path
> +  //
> +  DevicePath =  (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
> +  TempPtr   += FilePathSize;
> +
> +  //
> +  // Validation boot option variable.
> +  //
> +  if ((FilePathSize == 0) || (TempSize == 0)) {
> +    return FALSE;
> +  }
> +
> +  if (TempSize + FilePathSize + sizeof (UINT16) + sizeof (UINT32) >
> VariableSize) {
> +    return FALSE;
> +  }
> +
> +  return (BOOLEAN) (GetDevicePathSizeEx (DevicePath, FilePathSize) != 0);
> +}
> +
> +/**
> +  Convert a single character to number.
> +  It assumes the input Char is in the scope of L'0' ~ L'9' and L'A' ~ L'F'
> +
> +  @param Char    The input char which need to change to a hex number.
> +
> +**/
> +UINTN
> +CharToUint (
> +  IN CHAR16                           Char
> +  )
> +{
> +  if ((Char >= L'0') && (Char <= L'9')) {
> +    return (UINTN) (Char - L'0');
> +  }
> +
> +  if ((Char >= L'A') && (Char <= L'F')) {
> +    return (UINTN) (Char - L'A' + 0xA);
> +  }
> +
> +  ASSERT (FALSE);
> +  return 0;
> +}
> +
> +/**
> +  Build the boot#### or driver#### option from the VariableName, the
> +  build boot#### or driver#### will also be linked to BdsCommonOptionList.
> +
> +  @param  BdsCommonOptionList   The header of the boot#### or
> driver#### option
> +                                link list
> +  @param  VariableName          EFI Variable name indicate if it is boot#### or
> +                                driver####
> +
> +  @retval BDS_COMMON_OPTION     Get the option just been created
> +  @retval NULL                  Failed to get the new option
> +
> +**/
> +BDS_COMMON_OPTION *
> +EFIAPI
> +BdsLibVariableToOption (
> +  IN OUT LIST_ENTRY                   *BdsCommonOptionList,
> +  IN  CHAR16                          *VariableName
> +  )
> +{
> +  UINT32                    Attribute;
> +  UINT16                    FilePathSize;
> +  UINT8                     *Variable;
> +  UINT8                     *TempPtr;
> +  UINTN                     VariableSize;
> +  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
> +  BDS_COMMON_OPTION         *Option;
> +  VOID                      *LoadOptions;
> +  UINT32                    LoadOptionsSize;
> +  CHAR16                    *Description;
> +  UINT8                     NumOff;
> +
> +  //
> +  // Read the variable. We will never free this data.
> +  //
> +  Variable = BdsLibGetVariableAndSize (
> +              VariableName,
> +              &gEfiGlobalVariableGuid,
> +              &VariableSize
> +              );
> +  if (Variable == NULL) {
> +    return NULL;
> +  }
> +
> +  //
> +  // Validate Boot#### variable data.
> +  //
> +  if (!ValidateOption(Variable, VariableSize)) {
> +    FreePool (Variable);
> +    return NULL;
> +  }
> +
> +  //
> +  // Notes: careful defined the variable of Boot#### or
> +  // Driver####, consider use some macro to abstract the code
> +  //
> +  //
> +  // Get the option attribute
> +  //
> +  TempPtr   =  Variable;
> +  Attribute =  *(UINT32 *) Variable;
> +  TempPtr   += sizeof (UINT32);
> +
> +  //
> +  // Get the option's device path size
> +  //
> +  FilePathSize =  *(UINT16 *) TempPtr;
> +  TempPtr      += sizeof (UINT16);
> +
> +  //
> +  // Get the option's description string
> +  //
> +  Description = (CHAR16 *) TempPtr;
> +
> +  //
> +  // Get the option's description string size
> +  //
> +  TempPtr += StrSize((CHAR16 *) TempPtr);
> +
> +  //
> +  // Get the option's device path
> +  //
> +  DevicePath =  (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
> +  TempPtr    += FilePathSize;
> +
> +  //
> +  // Get load opion data.
> +  //
> +  LoadOptions     = TempPtr;
> +  LoadOptionsSize = (UINT32) (VariableSize - (UINTN) (TempPtr - Variable));
> +
> +  //
> +  // The Console variables may have multiple device paths, so make
> +  // an Entry for each one.
> +  //
> +  Option = AllocateZeroPool (sizeof (BDS_COMMON_OPTION));
> +  if (Option == NULL) {
> +    FreePool (Variable);
> +    return NULL;
> +  }
> +
> +  Option->Signature   = BDS_LOAD_OPTION_SIGNATURE;
> +  Option->DevicePath  = AllocateZeroPool (GetDevicePathSize (DevicePath));
> +  ASSERT(Option->DevicePath != NULL);
> +  CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize
> (DevicePath));
> +
> +  Option->Attribute   = Attribute;
> +  Option->Description = AllocateZeroPool (StrSize (Description));
> +  ASSERT(Option->Description != NULL);
> +  CopyMem (Option->Description, Description, StrSize (Description));
> +
> +  Option->LoadOptions = AllocateZeroPool (LoadOptionsSize);
> +  ASSERT(Option->LoadOptions != NULL);
> +  CopyMem (Option->LoadOptions, LoadOptions, LoadOptionsSize);
> +  Option->LoadOptionsSize = LoadOptionsSize;
> +
> +  //
> +  // Get the value from VariableName Unicode string
> +  // since the ISO standard assumes ASCII equivalent abbreviations, we can
> be safe in converting this
> +  // Unicode stream to ASCII without any loss in meaning.
> +  //
> +  if (*VariableName == 'B') {
> +    NumOff = (UINT8) (sizeof (L"Boot") / sizeof (CHAR16) - 1);
> +    Option->BootCurrent = (UINT16) (CharToUint (VariableName[NumOff+0])
> * 0x1000)
> +               + (UINT16) (CharToUint (VariableName[NumOff+1]) * 0x100)
> +               + (UINT16) (CharToUint (VariableName[NumOff+2]) * 0x10)
> +               + (UINT16) (CharToUint (VariableName[NumOff+3]) * 0x1);
> +  }
> +  InsertTailList (BdsCommonOptionList, &Option->Link);
> +  FreePool (Variable);
> +  return Option;
> +}
> +
> +/**
> +  Process BootOrder, or DriverOrder variables, by calling
> +  BdsLibVariableToOption () for each UINT16 in the variables.
> +
> +  @param  BdsCommonOptionList   The header of the option list base on
> variable
> +                                VariableName
> +  @param  VariableName          EFI Variable name indicate the BootOrder or
> +                                DriverOrder
> +
> +  @retval EFI_SUCCESS           Success create the boot option or driver option
> +                                list
> +  @retval EFI_OUT_OF_RESOURCES  Failed to get the boot option or driver
> option list
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BdsLibBuildOptionFromVar (
> +  IN  LIST_ENTRY                      *BdsCommonOptionList,
> +  IN  CHAR16                          *VariableName
> +  )
> +{
> +  UINT16            *OptionOrder;
> +  UINTN             OptionOrderSize;
> +  UINTN             Index;
> +  BDS_COMMON_OPTION *Option;
> +  CHAR16            OptionName[20];
> +
> +  //
> +  // Zero Buffer in order to get all BOOT#### variables
> +  //
> +  ZeroMem (OptionName, sizeof (OptionName));
> +
> +  //
> +  // Read the BootOrder, or DriverOrder variable.
> +  //
> +  OptionOrder = BdsLibGetVariableAndSize (
> +                  VariableName,
> +                  &gEfiGlobalVariableGuid,
> +                  &OptionOrderSize
> +                  );
> +  if (OptionOrder == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  for (Index = 0; Index < OptionOrderSize / sizeof (UINT16); Index++) {
> +    if (*VariableName == 'B') {
> +      UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x",
> OptionOrder[Index]);
> +    } else {
> +      UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x",
> OptionOrder[Index]);
> +    }
> +
> +    Option              = BdsLibVariableToOption (BdsCommonOptionList,
> OptionName);
> +    if (Option != NULL) {
> +      Option->BootCurrent = OptionOrder[Index];
> +    }
> +  }
> +
> +  FreePool (OptionOrder);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Get boot mode by looking up configuration table and parsing HOB list
> +
> +  @param  BootMode              Boot mode from PEI handoff HOB.
> +
> +  @retval EFI_SUCCESS           Successfully get boot mode
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BdsLibGetBootMode (
> +  OUT EFI_BOOT_MODE       *BootMode
> +  )
> +{
> +  *BootMode = GetBootModeHob ();
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Read the EFI variable (VendorGuid/Name) and return a dynamically
> allocated
> +  buffer, and the size of the buffer. If failure return NULL.
> +
> +  @param  Name                  String part of EFI variable name
> +  @param  VendorGuid            GUID part of EFI variable name
> +  @param  VariableSize          Returns the size of the EFI variable that was
> read
> +
> +  @return                       Dynamically allocated memory that contains a copy of
> the EFI variable
> +                                Caller is responsible freeing the buffer.
> +  @retval NULL                  Variable was not read
> +
> +**/
> +VOID *
> +EFIAPI
> +BdsLibGetVariableAndSize (
> +  IN  CHAR16              *Name,
> +  IN  EFI_GUID            *VendorGuid,
> +  OUT UINTN               *VariableSize
> +  )
> +{
> +  EFI_STATUS  Status;
> +  UINTN       BufferSize;
> +  VOID        *Buffer;
> +
> +  Buffer = NULL;
> +
> +  //
> +  // Pass in a zero size buffer to find the required buffer size.
> +  //
> +  BufferSize  = 0;
> +  Status      = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize,
> Buffer);
> +  if (Status == EFI_BUFFER_TOO_SMALL) {
> +    //
> +    // Allocate the buffer to return
> +    //
> +    Buffer = AllocateZeroPool (BufferSize);
> +    if (Buffer == NULL) {
> +      *VariableSize = 0;
> +      return NULL;
> +    }
> +    //
> +    // Read variable into the allocated buffer.
> +    //
> +    Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize,
> Buffer);
> +    if (EFI_ERROR (Status)) {
> +      FreePool (Buffer);
> +      BufferSize = 0;
> +      Buffer     = NULL;
> +    }
> +  }
> +
> +  ASSERT (((Buffer == NULL) && (BufferSize == 0)) ||
> +          ((Buffer != NULL) && (BufferSize != 0))
> +          );
> +  *VariableSize = BufferSize;
> +  return Buffer;
> +}
> +
> +/**
> +  Delete the instance in Multi which matches partly with Single instance
> +
> +  @param  Multi                 A pointer to a multi-instance device path data
> +                                structure.
> +  @param  Single                A pointer to a single-instance device path data
> +                                structure.
> +
> +  @return This function will remove the device path instances in Multi which
> partly
> +          match with the Single, and return the result device path. If there is no
> +          remaining device path as a result, this function will return NULL.
> +
> +**/
> +EFI_DEVICE_PATH_PROTOCOL *
> +EFIAPI
> +BdsLibDelPartMatchInstance (
> +  IN     EFI_DEVICE_PATH_PROTOCOL  *Multi,
> +  IN     EFI_DEVICE_PATH_PROTOCOL  *Single
> +  )
> +{
> +  EFI_DEVICE_PATH_PROTOCOL  *Instance;
> +  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL  *TempNewDevicePath;
> +  UINTN                     InstanceSize;
> +  UINTN                     SingleDpSize;
> +  UINTN                     Size;
> +
> +  NewDevicePath     = NULL;
> +  TempNewDevicePath = NULL;
> +
> +  if (Multi == NULL || Single == NULL) {
> +    return Multi;
> +  }
> +
> +  Instance        =  GetNextDevicePathInstance (&Multi, &InstanceSize);
> +  SingleDpSize    =  GetDevicePathSize (Single) - END_DEVICE_PATH_LENGTH;
> +  InstanceSize    -= END_DEVICE_PATH_LENGTH;
> +
> +  while (Instance != NULL) {
> +
> +    Size = (SingleDpSize < InstanceSize) ? SingleDpSize : InstanceSize;
> +
> +    if ((CompareMem (Instance, Single, Size) != 0)) {
> +      //
> +      // Append the device path instance which does not match with Single
> +      //
> +      TempNewDevicePath = NewDevicePath;
> +      NewDevicePath = AppendDevicePathInstance (NewDevicePath,
> Instance);
> +      if (TempNewDevicePath != NULL) {
> +        FreePool(TempNewDevicePath);
> +      }
> +    }
> +    FreePool(Instance);
> +    Instance = GetNextDevicePathInstance (&Multi, &InstanceSize);
> +    InstanceSize  -= END_DEVICE_PATH_LENGTH;
> +  }
> +
> +  return NewDevicePath;
> +}
> +
> +/**
> +  Function compares a device path data structure to that of all the nodes of a
> +  second device path instance.
> +
> +  @param  Multi                 A pointer to a multi-instance device path data
> +                                structure.
> +  @param  Single                A pointer to a single-instance device path data
> +                                structure.
> +
> +  @retval TRUE                  If the Single device path is contained within Multi
> device path.
> +  @retval FALSE                 The Single device path is not match within Multi
> device path.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +BdsLibMatchDevicePaths (
> +  IN  EFI_DEVICE_PATH_PROTOCOL  *Multi,
> +  IN  EFI_DEVICE_PATH_PROTOCOL  *Single
> +  )
> +{
> +  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInst;
> +  UINTN                     Size;
> +
> +  if (Multi == NULL || Single  == NULL) {
> +    return FALSE;
> +  }
> +
> +  DevicePath      = Multi;
> +  DevicePathInst  = GetNextDevicePathInstance (&DevicePath, &Size);
> +
> +  //
> +  // Search for the match of 'Single' in 'Multi'
> +  //
> +  while (DevicePathInst != NULL) {
> +    //
> +    // If the single device path is found in multiple device paths,
> +    // return success
> +    //
> +    if (CompareMem (Single, DevicePathInst, Size) == 0) {
> +      FreePool (DevicePathInst);
> +      return TRUE;
> +    }
> +
> +    FreePool (DevicePathInst);
> +    DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +  This function prints a series of strings.
> +
> +  @param  ConOut                Pointer to
> EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
> +  @param  ...                   A variable argument list containing series of
> +                                strings, the last string must be NULL.
> +
> +  @retval EFI_SUCCESS           Success print out the string using ConOut.
> +  @retval EFI_STATUS            Return the status of the ConOut->OutputString
> ().
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BdsLibOutputStrings (
> +  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL   *ConOut,
> +  ...
> +  )
> +{
> +  VA_LIST     Args;
> +  EFI_STATUS  Status;
> +  CHAR16      *String;
> +
> +  Status = EFI_SUCCESS;
> +  VA_START (Args, ConOut);
> +
> +  while (!EFI_ERROR (Status)) {
> +    //
> +    // If String is NULL, then it's the end of the list
> +    //
> +    String = VA_ARG (Args, CHAR16 *);
> +    if (String == NULL) {
> +      break;
> +    }
> +
> +    Status = ConOut->OutputString (ConOut, String);
> +
> +    if (EFI_ERROR (Status)) {
> +      break;
> +    }
> +  }
> +
> +  VA_END(Args);
> +  return Status;
> +}
> +
> +//
> +//  Following are BDS Lib functions which contain all the code about setup
> browser reset reminder feature.
> +//  Setup Browser reset reminder feature is that an reset reminder will be
> given before user leaves the setup browser  if
> +//  user change any option setting which needs a reset to be effective, and
> the reset will be applied according to  the user selection.
> +//
> +
> +
> +/**
> +  Enable the setup browser reset reminder feature.
> +  This routine is used in platform tip. If the platform policy need the feature,
> use the routine to enable it.
> +
> +**/
> +VOID
> +EFIAPI
> +EnableResetReminderFeature (
> +  VOID
> +  )
> +{
> +  mFeaturerSwitch = TRUE;
> +}
> +
> +
> +/**
> +  Disable the setup browser reset reminder feature.
> +  This routine is used in platform tip. If the platform policy do not want the
> feature, use the routine to disable it.
> +
> +**/
> +VOID
> +EFIAPI
> +DisableResetReminderFeature (
> +  VOID
> +  )
> +{
> +  mFeaturerSwitch = FALSE;
> +}
> +
> +
> +/**
> +  Record the info that  a reset is required.
> +  A  module boolean variable is used to record whether a reset is required.
> +
> +**/
> +VOID
> +EFIAPI
> +EnableResetRequired (
> +  VOID
> +  )
> +{
> +  mResetRequired = TRUE;
> +}
> +
> +
> +/**
> +  Record the info that  no reset is required.
> +  A  module boolean variable is used to record whether a reset is required.
> +
> +**/
> +VOID
> +EFIAPI
> +DisableResetRequired (
> +  VOID
> +  )
> +{
> +  mResetRequired = FALSE;
> +}
> +
> +
> +/**
> +  Check whether platform policy enable the reset reminder feature. The
> default is enabled.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +IsResetReminderFeatureEnable (
> +  VOID
> +  )
> +{
> +  return mFeaturerSwitch;
> +}
> +
> +
> +/**
> +  Check if  user changed any option setting which needs a system reset to be
> effective.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +IsResetRequired (
> +  VOID
> +  )
> +{
> +  return mResetRequired;
> +}
> +
> +
> +/**
> +  Check whether a reset is needed, and finish the reset reminder feature.
> +  If a reset is needed, Popup a menu to notice user, and finish the feature
> +  according to the user selection.
> +
> +**/
> +VOID
> +EFIAPI
> +SetupResetReminder (
> +  VOID
> +  )
> +{
> +  EFI_INPUT_KEY                 Key;
> +  CHAR16                        *StringBuffer1;
> +  CHAR16                        *StringBuffer2;
> +
> +
> +  //
> +  //check any reset required change is applied? if yes, reset system
> +  //
> +  if (IsResetReminderFeatureEnable ()) {
> +    if (IsResetRequired ()) {
> +
> +      StringBuffer1 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));
> +      ASSERT (StringBuffer1 != NULL);
> +      StringBuffer2 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));
> +      ASSERT (StringBuffer2 != NULL);
> +      StrCpy (StringBuffer1, L"Configuration changed. Reset to apply it Now.");
> +      StrCpy (StringBuffer2, L"Press ENTER to reset");
> +      //
> +      // Popup a menu to notice user
> +      //
> +      do {
> +        CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key,
> StringBuffer1, StringBuffer2, NULL);
> +      } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
> +
> +      FreePool (StringBuffer1);
> +      FreePool (StringBuffer2);
> +
> +      gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
> +    }
> +  }
> +}
> +
> +/**
> +  Get the headers (dos, image, optional header) from an image
> +
> +  @param  Device                SimpleFileSystem device handle
> +  @param  FileName              File name for the image
> +  @param  DosHeader             Pointer to dos header
> +  @param  Hdr                   The buffer in which to return the PE32, PE32+, or TE
> header.
> +
> +  @retval EFI_SUCCESS           Successfully get the machine type.
> +  @retval EFI_NOT_FOUND         The file is not found.
> +  @retval EFI_LOAD_ERROR        File is not a valid image file.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BdsLibGetImageHeader (
> +  IN  EFI_HANDLE                  Device,
> +  IN  CHAR16                      *FileName,
> +  OUT EFI_IMAGE_DOS_HEADER        *DosHeader,
> +  OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr
> +  )
> +{
> +  EFI_STATUS                       Status;
> +  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *Volume;
> +  EFI_FILE_HANDLE                  Root;
> +  EFI_FILE_HANDLE                  ThisFile;
> +  UINTN                            BufferSize;
> +  UINT64                           FileSize;
> +  EFI_FILE_INFO                    *Info;
> +
> +  Root     = NULL;
> +  ThisFile = NULL;
> +  //
> +  // Handle the file system interface to the device
> +  //
> +  Status = gBS->HandleProtocol (
> +                  Device,
> +                  &gEfiSimpleFileSystemProtocolGuid,
> +                  (VOID *) &Volume
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    goto Done;
> +  }
> +
> +  Status = Volume->OpenVolume (
> +                     Volume,
> +                     &Root
> +                     );
> +  if (EFI_ERROR (Status)) {
> +    Root = NULL;
> +    goto Done;
> +  }
> +  ASSERT (Root != NULL);
> +  Status = Root->Open (Root, &ThisFile, FileName, EFI_FILE_MODE_READ, 0);
> +  if (EFI_ERROR (Status)) {
> +    goto Done;
> +  }
> +  ASSERT (ThisFile != NULL);
> +
> +  //
> +  // Get file size
> +  //
> +  BufferSize  = SIZE_OF_EFI_FILE_INFO + 200;
> +  do {
> +    Info   = NULL;
> +    Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, (VOID **)
> &Info);
> +    if (EFI_ERROR (Status)) {
> +      goto Done;
> +    }
> +    Status = ThisFile->GetInfo (
> +                         ThisFile,
> +                         &gEfiFileInfoGuid,
> +                         &BufferSize,
> +                         Info
> +                         );
> +    if (!EFI_ERROR (Status)) {
> +      break;
> +    }
> +    if (Status != EFI_BUFFER_TOO_SMALL) {
> +      FreePool (Info);
> +      goto Done;
> +    }
> +    FreePool (Info);
> +  } while (TRUE);
> +
> +  FileSize = Info->FileSize;
> +  FreePool (Info);
> +
> +  //
> +  // Read dos header
> +  //
> +  BufferSize = sizeof (EFI_IMAGE_DOS_HEADER);
> +  Status = ThisFile->Read (ThisFile, &BufferSize, DosHeader);
> +  if (EFI_ERROR (Status) ||
> +      BufferSize < sizeof (EFI_IMAGE_DOS_HEADER) ||
> +      FileSize <= DosHeader->e_lfanew ||
> +      DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) {
> +    Status = EFI_LOAD_ERROR;
> +    goto Done;
> +  }
> +
> +  //
> +  // Move to PE signature
> +  //
> +  Status = ThisFile->SetPosition (ThisFile, DosHeader->e_lfanew);
> +  if (EFI_ERROR (Status)) {
> +    Status = EFI_LOAD_ERROR;
> +    goto Done;
> +  }
> +
> +  //
> +  // Read and check PE signature
> +  //
> +  BufferSize = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION);
> +  Status = ThisFile->Read (ThisFile, &BufferSize, Hdr.Pe32);
> +  if (EFI_ERROR (Status) ||
> +      BufferSize < sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION) ||
> +      Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
> +    Status = EFI_LOAD_ERROR;
> +    goto Done;
> +  }
> +
> +  //
> +  // Check PE32 or PE32+ magic
> +  //
> +  if (Hdr.Pe32->OptionalHeader.Magic !=
> EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC &&
> +      Hdr.Pe32->OptionalHeader.Magic !=
> EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
> +    Status = EFI_LOAD_ERROR;
> +    goto Done;
> +  }
> +
> + Done:
> +  if (ThisFile != NULL) {
> +    ThisFile->Close (ThisFile);
> +  }
> +  if (Root != NULL) {
> +    Root->Close (Root);
> +  }
> +  return Status;
> +}
> +
> +/**
> +  This routine adjust the memory information for different memory type
> and
> +  save them into the variables for next boot.
> +**/
> +VOID
> +BdsSetMemoryTypeInformationVariable (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                   Status;
> +  EFI_MEMORY_TYPE_INFORMATION  *PreviousMemoryTypeInformation;
> +  EFI_MEMORY_TYPE_INFORMATION  *CurrentMemoryTypeInformation;
> +  UINTN                        VariableSize;
> +  UINTN                        Index;
> +  UINTN                        Index1;
> +  UINT32                       Previous;
> +  UINT32                       Current;
> +  UINT32                       Next;
> +  EFI_HOB_GUID_TYPE            *GuidHob;
> +  BOOLEAN                      MemoryTypeInformationModified;
> +  BOOLEAN                      MemoryTypeInformationVariableExists;
> +  EFI_BOOT_MODE                BootMode;
> +
> +  MemoryTypeInformationModified       = FALSE;
> +  MemoryTypeInformationVariableExists = FALSE;
> +
> +
> +  BootMode = GetBootModeHob ();
> +  //
> +  // In BOOT_IN_RECOVERY_MODE, Variable region is not reliable.
> +  //
> +  if (BootMode == BOOT_IN_RECOVERY_MODE) {
> +    return;
> +  }
> +
> +  //
> +  // Only check the the Memory Type Information variable in the boot mode
> +  // other than BOOT_WITH_DEFAULT_SETTINGS because the Memory Type
> +  // Information is not valid in this boot mode.
> +  //
> +  if (BootMode != BOOT_WITH_DEFAULT_SETTINGS) {
> +    VariableSize = 0;
> +    Status = gRT->GetVariable (
> +                    EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
> +                    &gEfiMemoryTypeInformationGuid,
> +                    NULL,
> +                    &VariableSize,
> +                    NULL
> +                    );
> +    if (Status == EFI_BUFFER_TOO_SMALL) {
> +      MemoryTypeInformationVariableExists = TRUE;
> +    }
> +  }
> +
> +  //
> +  // Retrieve the current memory usage statistics.  If they are not found,
> then
> +  // no adjustments can be made to the Memory Type Information variable.
> +  //
> +  Status = EfiGetSystemConfigurationTable (
> +             &gEfiMemoryTypeInformationGuid,
> +             (VOID **) &CurrentMemoryTypeInformation
> +             );
> +  if (EFI_ERROR (Status) || CurrentMemoryTypeInformation == NULL) {
> +    return;
> +  }
> +
> +  //
> +  // Get the Memory Type Information settings from Hob if they exist,
> +  // PEI is responsible for getting them from variable and build a Hob to save
> them.
> +  // If the previous Memory Type Information is not available, then set
> defaults
> +  //
> +  GuidHob = GetFirstGuidHob (&gEfiMemoryTypeInformationGuid);
> +  if (GuidHob == NULL) {
> +    //
> +    // If Platform has not built Memory Type Info into the Hob, just return.
> +    //
> +    return;
> +  }
> +  PreviousMemoryTypeInformation = GET_GUID_HOB_DATA (GuidHob);
> +  VariableSize = GET_GUID_HOB_DATA_SIZE (GuidHob);
> +
> +  //
> +  // Use a heuristic to adjust the Memory Type Information for the next
> boot
> +  //
> +  DEBUG ((EFI_D_INFO, "Memory  Previous  Current    Next   \n"));
> +  DEBUG ((EFI_D_INFO, " Type    Pages     Pages     Pages  \n"));
> +  DEBUG ((EFI_D_INFO, "======  ========  ========  ========\n"));
> +
> +  for (Index = 0; PreviousMemoryTypeInformation[Index].Type !=
> EfiMaxMemoryType; Index++) {
> +
> +    for (Index1 = 0; CurrentMemoryTypeInformation[Index1].Type !=
> EfiMaxMemoryType; Index1++) {
> +      if (PreviousMemoryTypeInformation[Index].Type ==
> CurrentMemoryTypeInformation[Index1].Type) {
> +        break;
> +      }
> +    }
> +    if (CurrentMemoryTypeInformation[Index1].Type ==
> EfiMaxMemoryType) {
> +      continue;
> +    }
> +
> +    //
> +    // Previous is the number of pages pre-allocated
> +    // Current is the number of pages actually needed
> +    //
> +    Previous = PreviousMemoryTypeInformation[Index].NumberOfPages;
> +    Current  = CurrentMemoryTypeInformation[Index1].NumberOfPages;
> +    Next     = Previous;
> +
> +    //
> +    // Inconsistent Memory Reserved across bootings may lead to S4 fail
> +    // Write next varible to 125% * current when the pre-allocated memory is:
> +    //  1. More than 150% of needed memory and boot mode is
> BOOT_WITH_DEFAULT_SETTING
> +    //  2. Less than the needed memory
> +    //
> +    if ((Current + (Current >> 1)) < Previous) {
> +      if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) {
> +        Next = Current + (Current >> 2);
> +      }
> +    } else if (Current > Previous) {
> +      Next = Current + (Current >> 2);
> +    }
> +    if (Next > 0 && Next < 4) {
> +      Next = 4;
> +    }
> +
> +    if (Next != Previous) {
> +      PreviousMemoryTypeInformation[Index].NumberOfPages = Next;
> +      MemoryTypeInformationModified = TRUE;
> +    }
> +
> +    DEBUG ((EFI_D_INFO, "  %02x    %08x  %08x  %08x\n",
> PreviousMemoryTypeInformation[Index].Type, Previous, Current, Next));
> +  }
> +
> +  //
> +  // If any changes were made to the Memory Type Information settings,
> then set the new variable value;
> +  // Or create the variable in first boot.
> +  //
> +  if (MemoryTypeInformationModified
> || !MemoryTypeInformationVariableExists) {
> +    Status = SetVariableAndReportStatusCodeOnError (
> +               EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
> +               &gEfiMemoryTypeInformationGuid,
> +               EFI_VARIABLE_NON_VOLATILE  |
> EFI_VARIABLE_BOOTSERVICE_ACCESS,
> +               VariableSize,
> +               PreviousMemoryTypeInformation
> +               );
> +
> +    if (!EFI_ERROR (Status)) {
> +      //
> +      // If the Memory Type Information settings have been modified, then
> reset the platform
> +      // so the new Memory Type Information setting will be used to
> guarantee that an S4
> +      // entry/resume cycle will not fail.
> +      //
> +      if (MemoryTypeInformationModified && PcdGetBool
> (PcdResetOnMemoryTypeInformationChange)) {
> +        DEBUG ((EFI_D_INFO, "Memory Type Information settings change.
> Warm Reset!!!\n"));
> +        gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
> +      }
> +    } else {
> +      DEBUG ((EFI_D_ERROR, "Memory Type Information settings cannot be
> saved. OS S4 may fail!\n"));
> +    }
> +  }
> +}
> +
> +/**
> +  This routine is kept for backward compatibility.
> +**/
> +VOID
> +EFIAPI
> +BdsLibSaveMemoryTypeInformation (
> +  VOID
> +  )
> +{
> +}
> +
> +
> +/**
> +  Identify a user and, if authenticated, returns the current user profile
> handle.
> +
> +  @param[out]  User           Point to user profile handle.
> +
> +  @retval EFI_SUCCESS         User is successfully identified, or user
> identification
> +                              is not supported.
> +  @retval EFI_ACCESS_DENIED   User is not successfully identified
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BdsLibUserIdentify (
> +  OUT EFI_USER_PROFILE_HANDLE         *User
> +  )
> +{
> +  EFI_STATUS                          Status;
> +  EFI_USER_MANAGER_PROTOCOL           *Manager;
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiUserManagerProtocolGuid,
> +                  NULL,
> +                  (VOID **) &Manager
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  return Manager->Identify (Manager, User);
> +}
> +
> +/**
> +  Set the variable and report the error through status code upon failure.
> +
> +  @param  VariableName           A Null-terminated string that is the name of
> the vendor's variable.
> +                                 Each VariableName is unique for each VendorGuid.
> VariableName must
> +                                 contain 1 or more characters. If VariableName is an empty
> string,
> +                                 then EFI_INVALID_PARAMETER is returned.
> +  @param  VendorGuid             A unique identifier for the vendor.
> +  @param  Attributes             Attributes bitmask to set for the variable.
> +  @param  DataSize               The size in bytes of the Data buffer. Unless the
> EFI_VARIABLE_APPEND_WRITE,
> +                                 EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, or
> +
> EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is
> set, a size of zero
> +                                 causes the variable to be deleted. When the
> EFI_VARIABLE_APPEND_WRITE attribute is
> +                                 set, then a SetVariable() call with a DataSize of zero will not
> cause any change to
> +                                 the variable value (the timestamp associated with the
> variable may be updated however
> +                                 even if no new data value is provided,see the description
> of the
> +                                 EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In
> this case the DataSize will not
> +                                 be zero since the EFI_VARIABLE_AUTHENTICATION_2
> descriptor will be populated).
> +  @param  Data                   The contents for the variable.
> +
> +  @retval EFI_SUCCESS            The firmware has successfully stored the
> variable and its data as
> +                                 defined by the Attributes.
> +  @retval EFI_INVALID_PARAMETER  An invalid combination of attribute bits,
> name, and GUID was supplied, or the
> +                                 DataSize exceeds the maximum allowed.
> +  @retval EFI_INVALID_PARAMETER  VariableName is an empty string.
> +  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold
> the variable and its data.
> +  @retval EFI_DEVICE_ERROR       The variable could not be retrieved due to
> a hardware error.
> +  @retval EFI_WRITE_PROTECTED    The variable in question is read-only.
> +  @retval EFI_WRITE_PROTECTED    The variable in question cannot be
> deleted.
> +  @retval EFI_SECURITY_VIOLATION The variable could not be written due
> to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
> +                                 or
> EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, but
> the AuthInfo
> +                                 does NOT pass the validation check carried out by the
> firmware.
> +
> +  @retval EFI_NOT_FOUND          The variable trying to be updated or
> deleted was not found.
> +**/
> +EFI_STATUS
> +SetVariableAndReportStatusCodeOnError (
> +  IN CHAR16     *VariableName,
> +  IN EFI_GUID   *VendorGuid,
> +  IN UINT32     Attributes,
> +  IN UINTN      DataSize,
> +  IN VOID       *Data
> +  )
> +{
> +  EFI_STATUS                 Status;
> +  EDKII_SET_VARIABLE_STATUS  *SetVariableStatus;
> +  UINTN                      NameSize;
> +
> +  Status = gRT->SetVariable (
> +                  VariableName,
> +                  VendorGuid,
> +                  Attributes,
> +                  DataSize,
> +                  Data
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    NameSize = StrSize (VariableName);
> +    SetVariableStatus = AllocatePool (sizeof (EDKII_SET_VARIABLE_STATUS) +
> NameSize + DataSize);
> +    if (SetVariableStatus != NULL) {
> +      CopyGuid (&SetVariableStatus->Guid, VendorGuid);
> +      SetVariableStatus->NameSize   = NameSize;
> +      SetVariableStatus->DataSize   = DataSize;
> +      SetVariableStatus->SetStatus  = Status;
> +      SetVariableStatus->Attributes = Attributes;
> +      CopyMem (SetVariableStatus + 1,                          VariableName, NameSize);
> +      if ((Data != NULL) && (DataSize != 0)) {
> +        CopyMem (((UINT8 *) (SetVariableStatus + 1)) + NameSize, Data,
> DataSize);
> +      }
> +
> +      REPORT_STATUS_CODE_EX (
> +        EFI_ERROR_CODE,
> +        PcdGet32 (PcdErrorCodeSetVariable),
> +        0,
> +        NULL,
> +        &gEdkiiStatusCodeDataTypeVariableGuid,
> +        SetVariableStatus,
> +        sizeof (EDKII_SET_VARIABLE_STATUS) + NameSize + DataSize
> +        );
> +
> +      FreePool (SetVariableStatus);
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/DevicePath.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/DevicePath.c
> new file mode 100644
> index 0000000000..a0b9da880d
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/DevicePath.c
> @@ -0,0 +1,27 @@
> +/** @file
> +  BDS internal function define the default device path string, it can be
> +  replaced by platform device path.
> +
> +Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "InternalBdsLib.h"
> +
> +/**
> +  This function converts an input device structure to a Unicode string.
> +
> +  @param DevPath                  A pointer to the device path structure.
> +
> +  @return A new allocated Unicode string that represents the device path.
> +
> +**/
> +CHAR16 *
> +EFIAPI
> +DevicePathToStr (
> +  IN EFI_DEVICE_PATH_PROTOCOL     *DevPath
> +  )
> +{
> +  return ConvertDevicePathToText (DevPath, TRUE, TRUE);
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/GenericBdsLib.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/GenericBdsLib.inf
> new file mode 100644
> index 0000000000..e3c8a6fa27
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/GenericBdsLib.inf
> @@ -0,0 +1,142 @@
> +## @file
> +#  General BDS library.
> +#
> +#  General BDS defines and produce general interfaces for platform BDS
> driver including:
> +#  1) BDS boot policy interface;
> +#  2) BDS boot device connect interface;
> +#  3) BDS Misc interfaces for mainting boot variable, ouput string, etc.
> +#
> +#  Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = GenericBdsLib
> +  MODULE_UNI_FILE                = GenericBdsLib.uni
> +  FILE_GUID                      = e405ec31-ccaa-4dd4-83e8-0aec01703f7e
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = GenericBdsLib|DXE_DRIVER
> DXE_RUNTIME_DRIVER UEFI_APPLICATION
> +  CONSTRUCTOR                    = GenericBdsLibConstructor
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +
> +[Sources]
> +  DevicePath.c
> +  BdsConnect.c
> +  BdsMisc.c
> +  BdsConsole.c
> +  BdsBoot.c
> +  InternalBdsLib.h
> +  String.h
> +  String.c
> +  GenericBdsStrings.uni
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  IntelFrameworkPkg/IntelFrameworkPkg.dec
> +  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
> +  ShellPkg/ShellPkg.dec
> +
> +[LibraryClasses]
> +  DevicePathLib
> +  PeCoffGetEntryPointLib
> +  BaseLib
> +  HobLib
> +  UefiRuntimeServicesTableLib
> +  DxeServicesTableLib
> +  MemoryAllocationLib
> +  UefiLib
> +  UefiBootServicesTableLib
> +  BaseMemoryLib
> +  DebugLib
> +  PrintLib
> +  PcdLib
> +  PerformanceLib
> +  TimerLib
> +  DxeServicesLib
> +  HiiLib
> +  ReportStatusCodeLib
> +  NetLib
> +  BmpSupportLib
> +
> +[Guids]
> +  ## SOMETIMES_CONSUMES ## HOB         # The hob holding memory type
> information
> +  ## SOMETIMES_CONSUMES ## SystemTable # The identifier of memory
> type information type in system table
> +  ## SOMETIMES_CONSUMES ## Variable:L"MemoryTypeInformation"
> +  ## SOMETIMES_PRODUCES ## Variable:L"MemoryTypeInformation"
> +  gEfiMemoryTypeInformationGuid
> +  ## SOMETIMES_CONSUMES ## Variable:L"BootXXXX"    # Boot option
> variable
> +  ## SOMETIMES_PRODUCES ## Variable:L"BootXXXX"    # Boot option
> variable
> +  ## SOMETIMES_CONSUMES ## Variable:L"DriverXXXX"  # Driver load
> option.
> +  ## SOMETIMES_PRODUCES ## Variable:L"DriverXXXX"  # Driver load
> option.
> +  ## SOMETIMES_CONSUMES ## Variable:L"BootNext"    # Next Boot
> Option
> +  ## SOMETIMES_PRODUCES ## Variable:L"BootNext"    # Next Boot Option
> +  ## SOMETIMES_CONSUMES ## Variable:L"BootOrder"   # The boot option
> array
> +  ## SOMETIMES_PRODUCES ## Variable:L"BootOrder"   # The boot option
> array
> +  ## SOMETIMES_CONSUMES ## Variable:L"DriverOrder" # The driver order
> list
> +  ## SOMETIMES_CONSUMES ## Variable:L"ConIn"       # The device path of
> console in device
> +  ## SOMETIMES_PRODUCES ## Variable:L"ConIn"       # The device path of
> console in device
> +  ## SOMETIMES_CONSUMES ## Variable:L"ConOut"      # The device path
> of console out device
> +  ## SOMETIMES_PRODUCES ## Variable:L"ConOut"      # The device path of
> console out device
> +  ## SOMETIMES_CONSUMES ## Variable:L"ErrOut"      # The device path of
> error out device
> +  ## SOMETIMES_PRODUCES ## Variable:L"ErrOut"      # The device path of
> error out device
> +  ## SOMETIMES_PRODUCES ## Variable:L"BootCurrent" # The boot option
> of current boot
> +  ## SOMETIMES_PRODUCES ## Variable:L"BootNext"    # The number of
> next boot option
> +  gEfiGlobalVariableGuid
> +  gEfiFileInfoGuid                              ## SOMETIMES_CONSUMES ## GUID
> +  gLastEnumLangGuid                             ## SOMETIMES_PRODUCES ##
> Variable:L"LastEnumLang" # Platform language at last time enumeration.
> +  gHdBootDevicePathVariablGuid                  ## SOMETIMES_PRODUCES ##
> Variable:L"HDDP" # The device path of Boot file on Hard device.
> +  gBdsLibStringPackageGuid                      ## CONSUMES ## HII # HII String
> PackageList Guid
> +  ## SOMETIMES_PRODUCES ## Variable:L"LegacyDevOrder"
> +  ## SOMETIMES_CONSUMES ## Variable:L"LegacyDevOrder"
> +  gEfiLegacyDevOrderVariableGuid
> +  gEdkiiStatusCodeDataTypeVariableGuid          ## SOMETIMES_CONSUMES
> ## GUID
> +  gUefiShellFileGuid
> +
> +[Protocols]
> +  gEfiSimpleFileSystemProtocolGuid              ## SOMETIMES_CONSUMES
> +  gEfiLoadFileProtocolGuid                      ## SOMETIMES_CONSUMES
> +  gEfiSimpleTextOutProtocolGuid                 ## CONSUMES
> +  gEfiPciIoProtocolGuid                         ## SOMETIMES_CONSUMES
> +  gEfiLoadedImageProtocolGuid                   ## SOMETIMES_CONSUMES
> +  gEfiSimpleNetworkProtocolGuid                 ## SOMETIMES_CONSUMES
> +  gEfiDebugPortProtocolGuid                     ## SOMETIMES_CONSUMES
> +  gEfiSimpleTextInProtocolGuid                  ## CONSUMES
> +  gEfiBlockIoProtocolGuid                       ## SOMETIMES_CONSUMES
> +  gEfiFirmwareVolume2ProtocolGuid               ## SOMETIMES_CONSUMES
> +  gEfiLegacyBiosProtocolGuid                    ## SOMETIMES_CONSUMES
> +  gEfiCpuArchProtocolGuid                       ## CONSUMES
> +  gEfiDevicePathProtocolGuid                    ## CONSUMES
> +  gEfiAcpiS3SaveProtocolGuid                    ## SOMETIMES_CONSUMES
> +  gEfiGraphicsOutputProtocolGuid                ## SOMETIMES_CONSUMES
> +  gEfiUgaDrawProtocolGuid
> |gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport ##
> SOMETIMES_CONSUMES
> +  gEfiOEMBadgingProtocolGuid                    ## SOMETIMES_CONSUMES
> +  gEfiHiiFontProtocolGuid                       ## CONSUMES
> +  gEfiUserManagerProtocolGuid                   ## SOMETIMES_CONSUMES
> +  gEfiUsbIoProtocolGuid                         ## SOMETIMES_CONSUMES
> +  gEfiBootLogoProtocolGuid                      ## SOMETIMES_CONSUMES
> +
> +[FeaturePcd]
> +  gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport                   ##
> CONSUMES
> +  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBootlogoOnlyEnable
> ## CONSUMES
> +
> +[Pcd]
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationC
> hange ## SOMETIMES_CONSUMES
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeOsLoaderLoad  ##
> SOMETIMES_CONSUMES
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeOsLoaderStart ##
> SOMETIMES_CONSUMES
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdErrorCodeSetVariable      ##
> CONSUMES
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdTestKeyUsed                       ##
> CONSUMES
> +
> +#
> +# [BootMode]
> +#   RECOVERY_FULL    ## SOMETIMES_CONSUMES # Memory Type
> Information variable
> +#
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/GenericBdsLib.uni
> b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/GenericBdsLib.uni
> new file mode 100644
> index 0000000000..c853d3409e
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/GenericBdsLib.uni
> @@ -0,0 +1,19 @@
> +// /** @file
> +// General BDS library.
> +//
> +// General BDS defines and produce general interfaces for platform BDS
> driver including:
> +// 1) BDS boot policy interface;
> +// 2) BDS boot device connect interface;
> +// 3) BDS Misc interfaces for mainting boot variable, ouput string, etc.
> +//
> +// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +
> +#string STR_MODULE_ABSTRACT             #language en-US "General BDS
> library"
> +
> +#string STR_MODULE_DESCRIPTION          #language en-US "General BDS
> defines and produces general interfaces for a platform BDS driver including: 1)
> BDS boot policy interface; 2) BDS boot device connect interface; 3) BDS Misc
> interfaces for maintaining boot variable, output string, etc."
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/GenericBdsStrings.uni
> b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/GenericBdsStrings.uni
> new file mode 100644
> index 0000000000..59a75e548b
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/GenericBdsStrings.uni
> @@ -0,0 +1,30 @@
> +///** @file
> +//
> +//  String definitions for Boot Option description.
> +//
> +//  Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
> +//  SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//**/
> +
> +/=#
> +
> +#langdef   en-US "English"
> +#langdef   fr-FR "Français"
> +
> +#string STR_DESCRIPTION_FLOPPY         #language en-US  "EFI Floppy"
> +                                       #language fr-FR  "fr-FR: EFI Floppy"
> +#string STR_DESCRIPTION_CD_DVD         #language en-US  "EFI
> DVD/CDROM"
> +                                       #language fr-FR  "fr-FR: EFI DVD/CDROM"
> +#string STR_DESCRIPTION_HARDDRIVE      #language en-US  "EFI Hard Drive"
> +                                       #language fr-FR  "fr-FR: EFI Hard Drive"
> +#string STR_DESCRIPTION_USB            #language en-US  "EFI USB Device"
> +                                       #language fr-FR  "fr-FR: EFI USB Device"
> +#string STR_DESCRIPTION_SCSI           #language en-US  "EFI SCSI Device"
> +                                       #language fr-FR  "fr-FR: EFI SCSI Device"
> +#string STR_DESCRIPTION_MISC           #language en-US  "EFI Misc Device"
> +                                       #language fr-FR  "fr-FR: EFI Misc Device"
> +#string STR_DESCRIPTION_NETWORK        #language en-US  "EFI Network "
> +                                       #language fr-FR  "fr-FR: EFI Network "
> +#string STR_DESCRIPTION_NON_BLOCK      #language en-US  "EFI Non-Block
> Boot Device"
> +                                       #language fr-FR  "fr-FR: EFI Non-Block Boot Device"
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/InternalBdsLib.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/InternalBdsLib.h
> new file mode 100644
> index 0000000000..025f06572b
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/InternalBdsLib.h
> @@ -0,0 +1,173 @@
> +/** @file
> +  BDS library definition, include the file and data structure
> +
> +Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _INTERNAL_BDS_LIB_H_
> +#define _INTERNAL_BDS_LIB_H_
> +
> +#include <FrameworkDxe.h>
> +
> +#include <IndustryStandard/Pci.h>
> +#include <IndustryStandard/PeImage.h>
> +
> +#include <Protocol/BlockIo.h>
> +#include <Protocol/LoadedImage.h>
> +#include <Protocol/Cpu.h>
> +#include <Protocol/SimpleFileSystem.h>
> +#include <Protocol/LoadFile.h>
> +#include <Protocol/DebugPort.h>
> +#include <Protocol/DevicePath.h>
> +#include <Protocol/SimpleTextIn.h>
> +#include <Protocol/LegacyBios.h>
> +#include <Protocol/SimpleTextOut.h>
> +#include <Protocol/SimpleNetwork.h>
> +#include <Protocol/FirmwareVolume2.h>
> +#include <Protocol/PciIo.h>
> +#include <Protocol/AcpiS3Save.h>
> +#include <Protocol/OEMBadging.h>
> +#include <Protocol/GraphicsOutput.h>
> +#include <Protocol/UgaDraw.h>
> +#include <Protocol/HiiFont.h>
> +#include <Protocol/HiiImage.h>
> +#include <Protocol/UsbIo.h>
> +#include <Protocol/BootLogo.h>
> +
> +#include <Guid/MemoryTypeInformation.h>
> +#include <Guid/FileInfo.h>
> +#include <Guid/GlobalVariable.h>
> +#include <Guid/PcAnsi.h>
> +#include <Guid/BdsLibHii.h>
> +#include <Guid/HdBootVariable.h>
> +#include <Guid/LastEnumLang.h>
> +#include <Guid/LegacyDevOrder.h>
> +#include <Guid/StatusCodeDataTypeVariable.h>
> +
> +#include <Library/PrintLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/DxeServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/PerformanceLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PeCoffGetEntryPointLib.h>
> +#include <Library/GenericBdsLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/DxeServicesLib.h>
> +#include <Library/ReportStatusCodeLib.h>
> +#include <Library/BmpSupportLib.h>
> +
> +#if !defined (EFI_REMOVABLE_MEDIA_FILE_NAME)
> +    #if defined (MDE_CPU_EBC)
> +        //
> +        // Uefi specification only defines the default boot file name for IA32,
> X64
> +        // and IPF processor, so need define boot file name for EBC architecture
> here.
> +        //
> +        #define EFI_REMOVABLE_MEDIA_FILE_NAME
> L"\\EFI\\BOOT\\BOOTEBC.EFI"
> +    #else
> +        #error "Can not determine the default boot file name for unknown
> processor type!"
> +    #endif
> +#endif
> +
> +/**
> +  Get the headers (dos, image, optional header) from an image
> +
> +  @param  Device                SimpleFileSystem device handle
> +  @param  FileName              File name for the image
> +  @param  DosHeader             Pointer to dos header
> +  @param  Hdr                   The buffer in which to return the PE32, PE32+, or TE
> header.
> +
> +  @retval EFI_SUCCESS           Successfully get the machine type.
> +  @retval EFI_NOT_FOUND         The file is not found.
> +  @retval EFI_LOAD_ERROR        File is not a valid image file.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BdsLibGetImageHeader (
> +  IN  EFI_HANDLE                  Device,
> +  IN  CHAR16                      *FileName,
> +  OUT EFI_IMAGE_DOS_HEADER        *DosHeader,
> +  OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr
> +  );
> +
> +/**
> +  This routine adjust the memory information for different memory type
> and
> +  save them into the variables for next boot.
> +**/
> +VOID
> +BdsSetMemoryTypeInformationVariable (
> +  VOID
> +  );
> +
> +/**
> +  Validate the EFI Boot#### or Driver#### variable (VendorGuid/Name)
> +
> +  @param  Variable              Boot#### variable data.
> +  @param  VariableSize          Returns the size of the EFI variable that was
> read
> +
> +  @retval TRUE                  The variable data is correct.
> +  @retval FALSE                 The variable data is corrupted.
> +
> +**/
> +BOOLEAN
> +ValidateOption (
> +  UINT8                     *Variable,
> +  UINTN                     VariableSize
> +  );
> +
> +/**
> +  Set the variable and report the error through status code upon failure.
> +
> +  @param  VariableName           A Null-terminated string that is the name of
> the vendor's variable.
> +                                 Each VariableName is unique for each VendorGuid.
> VariableName must
> +                                 contain 1 or more characters. If VariableName is an empty
> string,
> +                                 then EFI_INVALID_PARAMETER is returned.
> +  @param  VendorGuid             A unique identifier for the vendor.
> +  @param  Attributes             Attributes bitmask to set for the variable.
> +  @param  DataSize               The size in bytes of the Data buffer. Unless the
> EFI_VARIABLE_APPEND_WRITE,
> +                                 EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, or
> +
> EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is
> set, a size of zero
> +                                 causes the variable to be deleted. When the
> EFI_VARIABLE_APPEND_WRITE attribute is
> +                                 set, then a SetVariable() call with a DataSize of zero will not
> cause any change to
> +                                 the variable value (the timestamp associated with the
> variable may be updated however
> +                                 even if no new data value is provided,see the description
> of the
> +                                 EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In
> this case the DataSize will not
> +                                 be zero since the EFI_VARIABLE_AUTHENTICATION_2
> descriptor will be populated).
> +  @param  Data                   The contents for the variable.
> +
> +  @retval EFI_SUCCESS            The firmware has successfully stored the
> variable and its data as
> +                                 defined by the Attributes.
> +  @retval EFI_INVALID_PARAMETER  An invalid combination of attribute bits,
> name, and GUID was supplied, or the
> +                                 DataSize exceeds the maximum allowed.
> +  @retval EFI_INVALID_PARAMETER  VariableName is an empty string.
> +  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold
> the variable and its data.
> +  @retval EFI_DEVICE_ERROR       The variable could not be retrieved due to
> a hardware error.
> +  @retval EFI_WRITE_PROTECTED    The variable in question is read-only.
> +  @retval EFI_WRITE_PROTECTED    The variable in question cannot be
> deleted.
> +  @retval EFI_SECURITY_VIOLATION The variable could not be written due
> to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
> +                                 or
> EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, but
> the AuthInfo
> +                                 does NOT pass the validation check carried out by the
> firmware.
> +
> +  @retval EFI_NOT_FOUND          The variable trying to be updated or
> deleted was not found.
> +**/
> +EFI_STATUS
> +SetVariableAndReportStatusCodeOnError (
> +  IN CHAR16     *VariableName,
> +  IN EFI_GUID   *VendorGuid,
> +  IN UINT32     Attributes,
> +  IN UINTN      DataSize,
> +  IN VOID       *Data
> +  );
> +
> +#endif // _BDS_LIB_H_
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/String.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/String.c
> new file mode 100644
> index 0000000000..f36860d5a1
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/String.c
> @@ -0,0 +1,26 @@
> +/** @file
> +  String support
> +
> +Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#include "String.h"
> +
> +/**
> +  Get string by string id from HII Interface
> +
> +
> +  @param Id              String ID.
> +
> +  @retval  CHAR16 *  String from ID.
> +  @retval  NULL      If error occurs.
> +
> +**/
> +CHAR16 *
> +BdsLibGetStringById (
> +  IN  EFI_STRING_ID   Id
> +  )
> +{
> +  return HiiGetString (gBdsLibStringPackHandle, Id, NULL);
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/String.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/String.h
> new file mode 100644
> index 0000000000..53cabe64a9
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Li
> brary/GenericBdsLib/String.h
> @@ -0,0 +1,42 @@
> +/** @file
> +  String support
> +
> +Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _STRING_H_
> +#define _STRING_H_
> +
> +#include <Library/HiiLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +
> +extern EFI_HII_HANDLE gBdsLibStringPackHandle;
> +
> +//
> +// This is the VFR compiler generated header file which defines the
> +// string identifiers.
> +//
> +
> +extern UINT8  GenericBdsLibStrings[];
> +
> +/**
> +  Get string by string id from HII Interface
> +
> +
> +  @param Id              String ID.
> +
> +  @retval  CHAR16 *  String from ID.
> +  @retval  NULL      If error occurs.
> +
> +**/
> +CHAR16 *
> +BdsLibGetStringById (
> +  IN  EFI_STRING_ID   Id
> +  );
> +
> +#endif // _STRING_H_
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/BoardPciPlatform.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/BoardPciPlatform.c
> new file mode 100644
> index 0000000000..0372c175a6
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/BoardPciPlatform.c
> @@ -0,0 +1,55 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +    BoardPciPlatform.c
> +
> +Abstract:
> +
> +Revision History:
> +--*/
> +
> +
> +#include "PciPlatform.h"
> +#include "PchRegs.h"
> +#include "VlvAccess.h"
> +
> +#define R_INTEL_LAN_VENDOR_ID           0x00
> +#define   V_INTEL_LAN_VENDOR_ID         0x8086     // INTEL 82574 Gbe
> Controller Vendor ID
> +#define R_INTEL_LAN_DEVICE_ID           0x02
> +#define   V_INTEL_LAN_DEVICE_ID         0x153E     // INTEL 82574 Gbe
> Controller Device ID
> +
> +//
> +// Global variables for Option ROMs
> +//
> +
> +#define ONBOARD_VIDEO_OPTION_ROM_FILE_GUID \
> +{ 0xF2FE1FAA, 0xF04A, 0x4ba1, 0xAE, 0x73, 0xD1, 0x84, 0x6A, 0x6C, 0xD6,
> 0xD8 }
> +
> +#define PXE_UNDI_OPTION_ROM_INTELPXE_GUID \
> +{0x49F2C48B, 0x4D8E, 0x4238, 0x8D, 0x82, 0x9B, 0x27, 0xF4, 0x38, 0x44, 0xB0}
> +
> +#define SATA_AHCI_ROM_GUID \
> +  {0x592bfc62, 0xd817, 0x4d1a, 0x86, 0xf8, 0x33, 0x33, 0x4c, 0x9e, 0x90, 0xd8}
> +
> +#define NULL_ROM_FILE_GUID \
> +{ 0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
> +
> +PCI_OPTION_ROM_TABLE mPciOptionRomTable[] = {
> +  { ONBOARD_VIDEO_OPTION_ROM_FILE_GUID,     0, 0, 0x02, 0, IGD_VID,
> IGD_DID_VLV_A0, 0},
> +  { ONBOARD_VIDEO_OPTION_ROM_FILE_GUID,     0, 0, 0x02, 0, IGD_VID,
> IGD_DID, 0},  // Desktop/Mobile IGD
> +  { ONBOARD_VIDEO_OPTION_ROM_FILE_GUID,     0, 0, 0x02, 0, IGD_VID,
> IGD_DID_II, 0},  // Desktop/Mobile IGD
> +  { ONBOARD_VIDEO_OPTION_ROM_FILE_GUID,     0, 0, 0x02, 0, IGD_VID,
> IGD_DID_QS, 0},
> +  { NULL_ROM_FILE_GUID,                     0, 0, 0, 0, 0xffff, 0xffff, 0}
> +};
> +
> +UINTN mSizeOptionRomTable =
> sizeof(mPciOptionRomTable)/sizeof(PCI_OPTION_ROM_TABLE);
> +
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.c
> new file mode 100644
> index 0000000000..b135e2646c
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.c
> @@ -0,0 +1,367 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +    PciPlatform.c
> +
> +Abstract:
> +--*/
> +
> +
> +#include "PciPlatform.h"
> +#include "PchRegs.h"
> +#include "PchAccess.h"
> +#include "VlvCommonDefinitions.h"
> +#include "PlatformBootMode.h"
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Protocol/CpuIo.h>
> +#include <Protocol/PciIo.h>
> +#include <Guid/SetupVariable.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +#include "SetupMode.h"
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +#include <Protocol/FirmwareVolume2.h>
> +#include <Library/HobLib.h>
> +#include <IndustryStandard/Pci22.h>
> +
> +extern  PCI_OPTION_ROM_TABLE  mPciOptionRomTable[];
> +extern  UINTN                 mSizeOptionRomTable;
> +
> +EFI_PCI_PLATFORM_PROTOCOL mPciPlatform = {
> +  PhaseNotify,
> +  PlatformPrepController,
> +  GetPlatformPolicy,
> +  GetPciRom
> +};
> +
> +EFI_HANDLE mPciPlatformHandle = NULL;
> +
> +
> +SYSTEM_CONFIGURATION          mSystemConfiguration;
> +
> +EFI_STATUS
> +GetRawImage (
> +  IN EFI_GUID   *NameGuid,
> +  IN OUT VOID   **Buffer,
> +  IN OUT UINTN  *Size
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  EFI_HANDLE                    *HandleBuffer;
> +  UINTN                         HandleCount;
> +  UINTN                         Index;
> +  EFI_FIRMWARE_VOLUME2_PROTOCOL  *Fv;
> +  UINT32                        AuthenticationStatus;
> +
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gEfiFirmwareVolume2ProtocolGuid,
> +                  NULL,
> +                  &HandleCount,
> +                  &HandleBuffer
> +                  );
> +  if (EFI_ERROR (Status) || HandleCount == 0) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  //
> +  // Find desired image in all Fvs
> +  //
> +  for (Index = 0; Index < HandleCount; Index++) {
> +    Status = gBS->HandleProtocol(
> +                    HandleBuffer[Index],
> +                    &gEfiFirmwareVolume2ProtocolGuid,
> +                    (VOID **) &Fv
> +                    );
> +
> +    if ( EFI_ERROR ( Status ) ) {
> +      return EFI_LOAD_ERROR;
> +    }
> +
> +    //
> +    // Try a raw file
> +    //
> +    *Buffer = NULL;
> +    *Size = 0;
> +    Status = Fv->ReadSection (
> +                   Fv,
> +                   NameGuid,
> +                   EFI_SECTION_RAW,
> +                   0,
> +                   Buffer,
> +                   Size,
> +                   &AuthenticationStatus
> +                   );
> +
> +    if ( !EFI_ERROR ( Status )) {
> +        break;
> +    }
> +  }
> +
> +  if ( Index >= HandleCount ) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +PhaseNotify (
> +  IN EFI_PCI_PLATFORM_PROTOCOL              *This,
> +  IN  EFI_HANDLE                                     HostBridge,
> +  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE  Phase,
> +  IN  EFI_PCI_CHIPSET_EXECUTION_PHASE                ChipsetPhase
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +PlatformPrepController (
> +  IN EFI_PCI_PLATFORM_PROTOCOL                      *This,
> +  IN  EFI_HANDLE                                     HostBridge,
> +  IN  EFI_HANDLE                                     RootBridge,
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS    PciAddress,
> +  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE   Phase,
> +  IN  EFI_PCI_CHIPSET_EXECUTION_PHASE                ChipsetPhase
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +GetPlatformPolicy (
> +  IN CONST EFI_PCI_PLATFORM_PROTOCOL        *This,
> +  OUT EFI_PCI_PLATFORM_POLICY               *PciPolicy
> +  )
> +{
> +  *PciPolicy = EFI_RESERVE_VGA_IO_ALIAS;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  GetPciRom from platform specific location for specific PCI device
> +
> +  @param This        Protocol instance
> +  @param PciHandle   Identify the specific PCI devic
> +  @param RomImage    Returns the ROM Image memory location
> +  @param RomSize     Returns Rom Image size
> +
> +  @retval EFI_SUCCESS
> +  @retval EFI_NOT_FOUND
> +  @retval  EFI_OUT_OF_RESOURCES
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetPciRom (
> +  IN CONST EFI_PCI_PLATFORM_PROTOCOL     *This,
> +  IN EFI_HANDLE                           PciHandle,
> +  OUT  VOID                               **RomImage,
> +  OUT  UINTN                              *RomSize
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  EFI_PCI_IO_PROTOCOL           *PciIo;
> +  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
> +  UINTN                         Segment;
> +  UINTN                         Bus;
> +  UINTN                         Device;
> +  UINTN                         Function;
> +  UINT16                        VendorId;
> +  UINT16                        DeviceId;
> +  UINT16                        DeviceClass;
> +  UINTN                         TableIndex;
> +  UINT8                         Data8;
> +  BOOLEAN                       MfgMode;
> +  EFI_PLATFORM_SETUP_ID         *BootModeBuffer;
> +
> +  EFI_PEI_HOB_POINTERS        GuidHob;
> +
> +  MfgMode = FALSE;
> +
> +//
> +// Check if system is in manufacturing mode.
> +//
> +  GuidHob.Raw = GetHobList ();
> +  if (GuidHob.Raw == NULL) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformBootModeGuid,
> GuidHob.Raw)) != NULL) {
> +    BootModeBuffer = GET_GUID_HOB_DATA (GuidHob.Guid);
> +    if (!CompareMem (&BootModeBuffer->SetupName,
> MANUFACTURE_SETUP_NAME,
> +        StrSize (MANUFACTURE_SETUP_NAME)))
> +      {
> +      	//
> +        // System is in manufacturing mode.
> +        //
> +        MfgMode = TRUE;
> +      }
> +   }
> +
> +  Status = gBS->HandleProtocol (
> +                  PciHandle,
> +                  &gEfiPciIoProtocolGuid,
> +                  (void **)&PciIo
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiPciRootBridgeIoProtocolGuid,
> +                  NULL,
> +                  (void **)&PciRootBridgeIo
> +                  );
> +
> +  if (EFI_ERROR (Status)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, 0x0A, 1, &DeviceClass);
> +
> +  PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);
> +
> +  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, 0, 1, &VendorId);
> +
> +  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, 2, 1, &DeviceId);
> +
> +  //
> +  // WA for PCIe SATA card (SYBA SY-PEX400-40)
> +  //
> +  if ((VendorId == 0x1B21) && (DeviceId == 0x0612)) {
> +    Data8 = 0x07;
> +    PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 4, 1, &Data8);
> +  }
> +
> +    //
> +    // Do not run RAID or AHCI Option ROM if IDE
> +    //
> +    if ( (DeviceClass == ((PCI_CLASS_MASS_STORAGE << 8 ) |
> PCI_CLASS_MASS_STORAGE_IDE)) ) {
> +      return EFI_NOT_FOUND;
> +    }
> +
> +    //
> +    // Run PXE ROM only if Boot network is enabled and not in MFG mode
> +    //
> +    if (DeviceClass == ((PCI_CLASS_NETWORK << 8 ) |
> PCI_CLASS_NETWORK_ETHERNET)) {
> +      if (((mSystemConfiguration.BootNetwork == 0) && (MfgMode ==
> FALSE )) || (mSystemConfiguration.FastBoot == 1)) {
> +      return EFI_NOT_FOUND;
> +      }
> +    }
> +
> +    //
> +    // Loop through table of Onboard option rom descriptions
> +    //
> +    for (TableIndex = 0; mPciOptionRomTable[TableIndex].VendorId != 0xffff;
> TableIndex++) {
> +
> +      //
> +      // See if the PCI device specified by PciHandle matches at device in
> mPciOptionRomTable
> +      //
> +      if (VendorId != mPciOptionRomTable[TableIndex].VendorId ||
> +          DeviceId != mPciOptionRomTable[TableIndex].DeviceId ||
> +          ((DeviceClass == ((PCI_CLASS_NETWORK << 8 ) |
> PCI_CLASS_NETWORK_ETHERNET)) &&
> +           (mPciOptionRomTable[TableIndex].Flag !=
> mSystemConfiguration.BootNetwork))  ) {
> +        continue;
> +      }
> +
> +      Status = GetRawImage(
> +                 &mPciOptionRomTable[TableIndex].FileName,
> +                 RomImage,
> +                 RomSize
> +                 );
> +
> +      if ((VendorId == IGD_VID) && (DeviceId == IGD_DID_VLV_A0)) {
> +        *(UINT16 *)(((UINTN) *RomImage) + OPROM_DID_OFFSET) =
> IGD_DID_VLV_A0;
> +      }
> +
> +      if ((VendorId == IGD_VID) && (DeviceId == IGD_DID_II)) {
> +        *(UINT16 *)(((UINTN) *RomImage) + OPROM_DID_OFFSET) =
> IGD_DID_II;
> +      }
> +
> +      if ((VendorId == IGD_VID) && (DeviceId == IGD_DID_0BE4)) {
> +        *(UINT16 *)(((UINTN) *RomImage) + OPROM_DID_OFFSET) =
> IGD_DID_0BE4;
> +      }
> +
> +      if ((VendorId == IGD_VID) && (DeviceId == IGD_DID_QS)) {
> +        *(UINT16 *)(((UINTN) *RomImage) + OPROM_DID_OFFSET) =
> IGD_DID_QS;
> +      }
> +
> +
> +        if (EFI_ERROR (Status)) {
> +          continue;
> +        }
> +        return EFI_SUCCESS;
> +      }
> +
> +  return EFI_NOT_FOUND;
> +}
> +
> +/**
> +
> +  @param  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
> +
> +  @retval EFI_STATUS
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +PciPlatformDriverEntry (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS  Status;
> +  UINTN       VarSize;
> +
> +  VarSize = sizeof(SYSTEM_CONFIGURATION);
> +  Status = gRT->GetVariable(
> +                  L"Setup",
> +                  &gEfiNormalSetupGuid,
> +                  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",
> +              &gEfiNormalSetupGuid,
> +              NULL,
> +              &VarSize,
> +              &mSystemConfiguration
> +              );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +  //
> +  // Install on a new handle
> +  //
> +  Status = gBS->InstallProtocolInterface (
> +                  &mPciPlatformHandle,
> +                  &gEfiPciPlatformProtocolGuid,
> +                  EFI_NATIVE_INTERFACE,
> +                  &mPciPlatform
> +                  );
> +
> +  return Status;
> +}
> +
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.h
> b/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.h
> new file mode 100644
> index 0000000000..cd846eae75
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.h
> @@ -0,0 +1,83 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +    PciPlatform.h
> +
> +Abstract:
> +
> +--*/
> +#ifndef PCI_PLATFORM_H_
> +#define PCI_PLATFORM_H_
> +
> +
> +#include <PiDxe.h>
> +#include "Platform.h"
> +
> +//
> +// Produced Protocols
> +//
> +#include <Protocol/PciPlatform.h>
> +
> +#define IGD_DID_II                     0x0BE1
> +#define IGD_DID_0BE4                   0x0BE4
> +#define IGD_DID_VLV_A0                 0x0F31
> +#define OPROM_DID_OFFSET               0x46
> +
> +typedef struct {
> +  EFI_GUID  FileName;
> +  UINTN     Segment;
> +  UINTN     Bus;
> +  UINTN     Device;
> +  UINTN     Function;
> +  UINT16    VendorId;
> +  UINT16    DeviceId;
> +  UINT8     Flag;
> +} PCI_OPTION_ROM_TABLE;
> +
> +EFI_STATUS
> +EFIAPI
> +PhaseNotify (
> +  IN  EFI_PCI_PLATFORM_PROTOCOL                     *This,
> +  IN  EFI_HANDLE                                    HostBridge,
> +  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase,
> +  IN  EFI_PCI_CHIPSET_EXECUTION_PHASE               ChipsetPhase
> +  );
> +
> +
> +EFI_STATUS
> +EFIAPI
> +PlatformPrepController (
> +  IN EFI_PCI_PLATFORM_PROTOCOL                      *This,
> +  IN   EFI_HANDLE                                   HostBridge,
> +  IN  EFI_HANDLE                                    RootBridge,
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS   PciAddress,
> +  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE  Phase,
> +  IN  EFI_PCI_CHIPSET_EXECUTION_PHASE               ChipsetPhase
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +GetPlatformPolicy (
> +  IN CONST EFI_PCI_PLATFORM_PROTOCOL                      *This,
> +  OUT EFI_PCI_PLATFORM_POLICY                       *PciPolicy
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +GetPciRom (
> +  IN CONST EFI_PCI_PLATFORM_PROTOCOL                      *This,
> +  IN EFI_HANDLE                                     PciHandle,
> +  OUT  VOID                                         **RomImage,
> +  OUT  UINTN                                        *RomSize
> +  );
> +
> +#endif
> +
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.inf
> new file mode 100644
> index 0000000000..a0837917d8
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.inf
> @@ -0,0 +1,65 @@
> +#/*++
> +#
> +# Copyright (c)  2003  - 2018, Intel Corporation. All rights reserved
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +
> +#
> +#  Module Name:
> +#
> +#    PciPlatform.inf
> +#
> +#  Abstract:
> +#
> +#    Component description file for PciPlatform module.
> +#
> +--*/
> +
> +[defines]
> +  INF_VERSION          = 0x00010005
> +  BASE_NAME            = PciPlatform
> +  FILE_GUID            = E2441B64-7EF4-41fe-B3A3-8CAA7F8D3017
> +  MODULE_TYPE          = DXE_DRIVER
> +  VERSION_STRING       = 1.0
> +  ENTRY_POINT          = PciPlatformDriverEntry
> +
> +[sources.common]
> +  BoardPciPlatform.c
> +  PciPlatform.c
> +  PciPlatform.h
> +
> +[Guids]
> +  gEfiNormalSetupGuid
> +  gEfiPlatformBootModeGuid
> +
> +[Protocols]
> +  gEfiPciPlatformProtocolGuid
> +  gEfiCpuIoProtocolGuid
> +  gEfiFirmwareVolume2ProtocolGuid
> +  gEfiPciRootBridgeIoProtocolGuid
> +  gEfiPciIoProtocolGuid
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +  IntelFrameworkPkg/IntelFrameworkPkg.dec
> +
> +[LibraryClasses]
> +  HobLib
> +  UefiDriverEntryPoint
> +  BaseLib
> +  BaseMemoryLib
> +  UefiDriverEntryPoint
> +  UefiBootServicesTableLib
> +  UefiRuntimeServicesTableLib
> +  DxeServicesTableLib
> +
> +[BuildOptions]
> +
> +[Depex]
> +  gEfiVariableArchProtocolGuid AND
> +  gEfiVariableWriteArchProtocolGuid
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.dsc
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.dsc
> new file mode 100644
> index 0000000000..524bb74e2a
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.dsc
> @@ -0,0 +1,39 @@
> +#/** @file
> +# Platform capsule description.
> +#
> +# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +#**/
> +
> +[Defines]
> +  PLATFORM_NAME                  = Vlv2TbltDevicePkg
> +  PLATFORM_GUID                  = EE87F258-6ECC-4415-B1D8-23771BEE26E7
> +  PLATFORM_VERSION               = 0.1
> +  FLASH_DEFINITION               = Vlv2TbltDevicePkg/PlatformCapsule.fdf
> +  OUTPUT_DIRECTORY               = Build/Vlv2TbltDevicePkg
> +  SUPPORTED_ARCHITECTURES        = IA32|X64
> +  BUILD_TARGETS                  = DEBUG|RELEASE
> +  SKUID_IDENTIFIER               = DEFAULT
> +  POSTBUILD                      =
> Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleAll.bat
> +
> +#########################################################
> ##########################################
> +#
> +# Components Section - list of the modules and components that will be
> processed by compilation
> +#                      tools and the EDK II tools to generate PE32/PE32+/Coff image
> files.
> +#
> +# Note: The EDK II DSC file is not used to specify how compiled binary
> images get placed
> +#       into firmware volume images. This section is just a list of modules to
> compile from
> +#       source into UEFI-compliant binaries.
> +#       It is the FDF file that contains information on combining binary files into
> firmware
> +#       volume images, whose concept is beyond UEFI and is described in PI
> specification.
> +#       Binary modules do not need to be listed in this section, as they should
> be
> +#       specified in the FDF file. For example: Shell binary, FAT binary (Fat.efi),
> +#       Logo (Logo.bmp), and etc.
> +#       There may also be modules listed in this section that are not required
> in the FDF file,
> +#       When a module listed here is excluded from FDF file, then UEFI-
> compliant binary will be
> +#       generated for it, but the binary will not be put into any firmware
> volume.
> +#
> +#########################################################
> ##########################################
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.fdf
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.fdf
> new file mode 100644
> index 0000000000..43dd987eaf
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.fdf
> @@ -0,0 +1,52 @@
> +## @file
> +# FDF file of Platform capsule.
> +#
> +# Copyright (c) 2016 Intel Corporation.
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[FV.SystemFirmwareUpdateCargo]
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +
> +FILE RAW = AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215 { #
> PcdEdkiiSystemFirmwareFileGuid
> +
> $(WORKSPACE)/$(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/F
> V/Vlv.ROM
> +  }
> +
> +FILE RAW = 812136D3-4D3A-433A-9418-29BB9BF78F6E { #
> gEdkiiSystemFmpCapsuleConfigFileGuid
> +
> Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdateConfig/System
> FirmwareUpdateConfig.ini
> +  }
> +
> +[FmpPayload.FmpPayloadSystemFirmwareRsa2048]
> +IMAGE_HEADER_INIT_VERSION = 0x02
> +IMAGE_TYPE_ID             = 4096267b-da0a-42eb-b5eb-fef31d207cb4 #
> PcdSystemFmpCapsuleImageTypeIdGuid
> +IMAGE_INDEX               = 0x1
> +HARDWARE_INSTANCE         = 0x0
> +MONOTONIC_COUNT           = 0x2
> +CERTIFICATE_GUID          = A7717414-C616-4977-9420-844712A735BF #
> RSA2048SHA256
> +
> +FILE DATA =
> $(WORKSPACE)/$(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/F
> V/SYSTEMFIRMWAREUPDATECARGO.Fv
> +
> +[Capsule.Vlv2Rec]
> +CAPSULE_GUID                = 6dcbd5ed-e82d-4c44-bda1-7194199ad92a #
> gEfiFmpCapsuleGuid
> +CAPSULE_FLAGS               = PersistAcrossReset,InitiateReset
> +CAPSULE_HEADER_SIZE         = 0x20
> +CAPSULE_HEADER_INIT_VERSION = 0x1
> +
> +FMP_PAYLOAD = FmpPayloadSystemFirmwareRsa2048
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc
> new file mode 100644
> index 0000000000..1856ac349b
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc
> @@ -0,0 +1,38 @@
> +#/** @file
> +# Platform capsule description.
> +#
> +# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#**/
> +
> +[Defines]
> +  PLATFORM_NAME                  = Vlv2TbltDevicePkg
> +  PLATFORM_GUID                  = EE87F258-6ECC-4415-B1D8-23771BEE26E7
> +  PLATFORM_VERSION               = 0.1
> +  FLASH_DEFINITION               = Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf
> +  OUTPUT_DIRECTORY               = Build/Vlv2TbltDevicePkg
> +  SUPPORTED_ARCHITECTURES        = IA32|X64
> +  BUILD_TARGETS                  = DEBUG|RELEASE
> +  SKUID_IDENTIFIER               = DEFAULT
> +  POSTBUILD                      =
> Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleAll.sh
> +
> +#########################################################
> ##########################################
> +#
> +# Components Section - list of the modules and components that will be
> processed by compilation
> +#                      tools and the EDK II tools to generate PE32/PE32+/Coff image
> files.
> +#
> +# Note: The EDK II DSC file is not used to specify how compiled binary
> images get placed
> +#       into firmware volume images. This section is just a list of modules to
> compile from
> +#       source into UEFI-compliant binaries.
> +#       It is the FDF file that contains information on combining binary files into
> firmware
> +#       volume images, whose concept is beyond UEFI and is described in PI
> specification.
> +#       Binary modules do not need to be listed in this section, as they should
> be
> +#       specified in the FDF file. For example: Shell binary, FAT binary (Fat.efi),
> +#       Logo (Logo.bmp), and etc.
> +#       There may also be modules listed in this section that are not required
> in the FDF file,
> +#       When a module listed here is excluded from FDF file, then UEFI-
> compliant binary will be
> +#       generated for it, but the binary will not be put into any firmware
> volume.
> +#
> +#########################################################
> ##########################################
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf
> new file mode 100644
> index 0000000000..7917be3d68
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf
> @@ -0,0 +1,52 @@
> +## @file
> +# FDF file of Platform capsule.
> +#
> +# Copyright (c) 2016 Intel Corporation.
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[FV.SystemFirmwareUpdateCargo]
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +
> +FILE RAW = AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215 { #
> PcdEdkiiSystemFirmwareFileGuid
> +
> $(WORKSPACE)/$(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/F
> V/Vlv.ROM
> +  }
> +
> +FILE RAW = 812136D3-4D3A-433A-9418-29BB9BF78F6E { #
> gEdkiiSystemFmpCapsuleConfigFileGuid
> +
> Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdateConfig/System
> FirmwareUpdateConfigGcc.ini
> +  }
> +
> +[FmpPayload.FmpPayloadSystemFirmwareRsa2048]
> +IMAGE_HEADER_INIT_VERSION = 0x02
> +IMAGE_TYPE_ID             = 4096267b-da0a-42eb-b5eb-fef31d207cb4 #
> PcdSystemFmpCapsuleImageTypeIdGuid
> +IMAGE_INDEX               = 0x1
> +HARDWARE_INSTANCE         = 0x0
> +MONOTONIC_COUNT           = 0x2
> +CERTIFICATE_GUID          = A7717414-C616-4977-9420-844712A735BF #
> RSA2048SHA256
> +
> +FILE DATA =
> $(WORKSPACE)/$(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/F
> V/SYSTEMFIRMWAREUPDATECARGO.Fv
> +
> +[Capsule.Vlv2Rec]
> +CAPSULE_GUID                = 6dcbd5ed-e82d-4c44-bda1-7194199ad92a #
> gEfiFmpCapsuleGuid
> +CAPSULE_FLAGS               = PersistAcrossReset,InitiateReset
> +CAPSULE_HEADER_SIZE         = 0x20
> +CAPSULE_HEADER_INIT_VERSION = 0x1
> +
> +FMP_PAYLOAD = FmpPayloadSystemFirmwareRsa2048
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoD
> xe.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoD
> xe.c
> new file mode 100644
> index 0000000000..d35a158181
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoD
> xe.c
> @@ -0,0 +1,60 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  PlatformCpuInfoDxe.c
> +
> +Abstract:
> +  Platform Cpu Info driver to public platform related HOB data
> +
> +--*/
> +
> +#include "PlatformCpuInfoDxe.h"
> +
> +CHAR16    EfiPlatformCpuInfoVariable[] = L"PlatformCpuInfo";
> +
> +EFI_STATUS
> +EFIAPI
> +PlatformCpuInfoInit (
> +  IN EFI_HANDLE                         ImageHandle,
> +  IN EFI_SYSTEM_TABLE                   *SystemTable
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_PLATFORM_CPU_INFO       *PlatformCpuInfoPtr;
> +  EFI_PEI_HOB_POINTERS        GuidHob;
> +
> +  //
> +  // Get Platform Cpu Info HOB
> +  //
> +  GuidHob.Raw = GetHobList ();
> +  while ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformCpuInfoGuid,
> GuidHob.Raw)) != NULL) {
> +    PlatformCpuInfoPtr = GET_GUID_HOB_DATA (GuidHob.Guid);
> +    GuidHob.Raw = GET_NEXT_HOB (GuidHob);
> +
> +      //
> +      // Write the Platform CPU Info to volatile memory for runtime purposes.
> +      // This must be done in its own driver because SetVariable protocol is
> dependent on chipset,
> +      // which is dependent on CpuIo, PlatformInfo, and Metronome.
> +      //
> +      Status = gRT->SetVariable(
> +                      EfiPlatformCpuInfoVariable,
> +                      &gEfiVlv2VariableGuid,
> +                      EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_RUNTIME_ACCESS,
> +                      sizeof(EFI_PLATFORM_CPU_INFO),
> +                      PlatformCpuInfoPtr
> +                      );
> +      if (EFI_ERROR(Status)) {
> +        return Status;
> +      }
> +  }
> +
> +   return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoD
> xe.h
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoD
> xe.h
> new file mode 100644
> index 0000000000..b13611f4f8
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoD
> xe.h
> @@ -0,0 +1,29 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +  PlatformCpuInfoDxe.h
> +
> +Abstract:
> +  Platform Cpu Info Driver.
> +
> +--*/
> +
> +#ifndef _PLATFORM_CPU_INFO_DRIVER_H_
> +#define _PLATFORM_CPU_INFO_DRIVER_H_
> +
> +#include "PiDxe.h"
> +#include "Library/HobLib.h"
> +#include "Guid/GlobalVariable.h"
> +#include "Guid/AcpiVariableCompatibility.h"
> +#include "Guid/PlatformCpuInfo.h"
> +#include "Library/UefiRuntimeServicesTableLib.h"
> +#include <Guid/Vlv2Variable.h>
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoD
> xe.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoD
> xe.inf
> new file mode 100644
> index 0000000000..f2ade1b105
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoD
> xe.inf
> @@ -0,0 +1,55 @@
> +#/*++
> +#
> +# Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +
> +#
> +#  Module Name:
> +#
> +#   PlatformCpuInfoDxe.inf
> +#
> +#  Abstract:
> +#
> +#
> +--*/
> +
> +
> +[Defines]
> +  INF_VERSION          = 0x00010005
> +  BASE_NAME            = PlatformCpuInfoDxe
> +  FILE_GUID            = 025F738B-4EBD-4d55-B728-5F421B601F20
> +  MODULE_TYPE          = DXE_DRIVER
> +  VERSION_STRING       = 1.0
> +  ENTRY_POINT          = PlatformCpuInfoInit
> +
> +[Sources]
> +  PlatformCpuInfoDxe.c
> +  PlatformCpuInfoDxe.h
> +
> +[Guids]
> +  gEfiPlatformCpuInfoGuid
> +  gEfiVlv2VariableGuid
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  Vlv2SocBinPkg/Vlv2SocBinPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
> +
> +[LibraryClasses]
> +  HobLib
> +  UefiRuntimeServicesTableLib
> +  UefiDriverEntryPoint
> +
> +[BuildOptions]
> +  MSFT:*_*_*_CC_FLAGS = /Od /GL-
> +  INTEL:*_*_*_CC_FLAGS = /Od /GL-
> +
> +[Depex]
> +  gEfiVariableArchProtocolGuid AND
> +  gEfiVariableWriteArchProtocolGuid
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/AzaliaVerbTable.h
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/AzaliaVerbTable.h
> new file mode 100644
> index 0000000000..331d0cbede
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/AzaliaVerbTable.h
> @@ -0,0 +1,247 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +--*/
> +
> +UINT32 mAzaliaVerbTableData12[] = {
> +  //
> +  // Audio Verb Table - 0x80862805
> +  //
> +  // Pin Widget 5 - PORT B
> +  0x20471C10,
> +  0x20471D00,
> +  0x20471E56,
> +  0x20471F18,
> +
> +  // Pin Widget 6 - PORT C
> +  0x20571C20,
> +  0x20571D00,
> +  0x20571E56,
> +  0x20571F18,
> +
> +  // Pin Widget 7 - PORT D
> +  0x20671C30,
> +  0x20671D00,
> +  0x20671E56,
> +  0x20671F58
> +};
> +
> +
> +PCH_AZALIA_VERB_TABLE mAzaliaVerbTable[] = {
> +  {
> +    //
> +    // VerbTable:
> +    //  Revision ID = 0xFF, support all steps
> +    //  Codec Verb Table For AZALIA
> +    //  Codec Address: CAd value (0/1/2)
> +    //  Codec Vendor:  0x10EC0880
> +    //
> +    {
> +      0x10EC0880,     // Vendor ID/Device ID
> +      0x0000,         // SubSystem ID
> +      0xFF,           // Revision ID
> +      0x01,           // Front panel support (1=yes, 2=no)
> +      0x000A,         // Number of Rear Jacks = 10
> +      0x0002          // Number of Front Jacks = 2
> +    },
> +    0                 // Pointer to verb table data, need to be inited in the code.
> +  },
> +  {
> +    //
> +    // Revision ID >= 0x03
> +    // Codec Verb Table For AZALIA
> +    // Codec Address: CAd value (0/1/2)
> +    // Codec Vendor: 0x434D4980
> +    //
> +    {
> +      0x434D4980,     // Vendor ID/Device ID
> +      0x0000,         // SubSystem ID
> +      0x00,           // Revision ID
> +      0x01,           // Front panel support (1=yes, 2=no)
> +      0x0009,         // Number of Rear Jacks = 9
> +      0x0002          // Number of Front Jacks = 2
> +    },
> +    0                 // Pointer to verb table data, need to be inited in the code.
> +  },
> +  {
> +    //
> +    // Lawndale Azalia Audio Codec Verb Table
> +    // Revision ID = 0x00
> +    // Codec Address: CAd value (0/1/2)
> +    // Codec Vendor: 0x11D41984
> +    //
> +    {
> +      0x11D41984,     // Vendor ID/Device ID
> +      0x0000,         // SubSystem ID
> +      0x04,           // Revision ID
> +      0x01,           // Front panel support (1=yes, 2=no)
> +      0x0009,         // Number of Rear Jacks = 9
> +      0x0002          // Number of Front Jacks = 2
> +    },
> +    0                 // Pointer to verb table data, need to be inited in the code.
> +  },
> +  {
> +    //
> +    // VerbTable:
> +    //  Revision ID = 0xFF, support all steps
> +    //  Codec Verb Table For AZALIA
> +    //  Codec Address: CAd value (0/1/2)
> +    //  Codec Vendor: 0x11D41986
> +    //
> +    {
> +      0x11D41986,     // Vendor ID/Device ID
> +      0x0001,         // SubSystem ID
> +      0xFF,           // Revision ID
> +      0x01,           // Front panel support (1=yes, 2=no)
> +      0x000A,         // Number of Rear Jacks = 8
> +      0x0002          // Number of Front Jacks = 2
> +    },
> +    0                 // Pointer to verb table data, need to be inited in the code.
> +  },
> +  {
> +    //
> +    // VerbTable: (for Slim River, FFDS3)
> +    //  Revision ID = 0x00
> +    //  Codec Verb Table For AZALIA
> +    //  Codec Address: CAd value (0/1/2)
> +    //  Codec Vendor: 0x10EC0272
> +    //
> +    {
> +      0x10EC0272,     // Vendor ID/Device ID
> +      0x0000,         // SubSystem ID
> +      0x00,           // Revision ID
> +      0x01,           // Front panel support (1=yes, 2=no)
> +      0x000E,         // Number of Rear Jacks
> +      0x0002          // Number of Front Jacks
> +    },
> +    0                 // Pointer to verb table data, need to be inited in the code.
> +  },
> +  {
> +    //
> +    //  VerbTable: (for Buffalo Trail)
> +    //  Revision ID = 0x00
> +    //  Codec Verb Table For AZALIA
> +    //  Codec Address: CAd value (0/1/2)
> +    //  Codec Vendor: 0x10EC0269
> +    //
> +    {
> +      0x10EC0269,     // Vendor ID/Device ID
> +      0x0000,         // SubSystem ID
> +      0x00,           // Revision ID
> +      0x01,           // Front panel support (1=yes, 2=no)
> +      0x000A,         // Number of Rear Jacks
> +      0x0002          // Number of Front Jacks
> +    },
> +    0                 // Pointer to verb table data, need to be inited in the code.
> +  },
> +  {
> +    //
> +    //  VerbTable: (RealTek ALC888)
> +    //  Revision ID = 0xFF
> +    //  Codec Verb Table For Redfort
> +    //  Codec Address: CAd value (0/1/2)
> +    //  Codec Vendor: 0x10EC0888
> +    //
> +    {
> +      0x10EC0888,     // Vendor ID/Device ID
> +      0x0000,         // SubSystem ID
> +      0xFF,           // Revision ID
> +      0x01,           // Front panel support (1=yes, 2=no)
> +      0x000B,         // Number of Rear Jacks
> +      0x0002          // Number of Front Jacks
> +    },
> +    0                 // Pointer to verb table data, need to be inited in the code.
> +  },
> +  {
> +    //
> +    //  VerbTable: (RealTek ALC885)
> +    //  Revision ID = 0xFF
> +    //  Codec Verb Table For Redfort
> +    //  Codec Address: CAd value (0/1/2)
> +    //  Codec Vendor: 0x10EC0885
> +    //
> +    {
> +      0x10EC0885,     // Vendor ID/Device ID
> +      0x0000,         // SubSystem ID
> +      0xFF,           // Revision ID
> +      0x01,           // Front panel support (1=yes, 2=no)
> +      0x000B,         // Number of Rear Jacks
> +      0x0002          // Number of Front Jacks
> +    },
> +    0                 // Pointer to verb table data, need to be inited in the code.
> +  },
> +  {
> +    //
> +    //  VerbTable: (IDT 92HD81)
> +    //  Revision ID = 0xFF
> +    //  Codec Vendor: 0x111D7605
> +    //
> +    {
> +      0x111D76d5,     // Vendor ID/Device ID
> +      0x0000,         // SubSystem ID
> +      0xFF,           // Revision ID
> +      0x01,           // Front panel support (1=yes, 2=no)
> +      0x0008,         // Number of Rear Jacks
> +      0x0002          // Number of Front Jacks
> +    },
> +    0                 // Pointer to verb table data, need to be inited in the code.
> +  },
> +  {
> +    //
> +    //  VerbTable: (Intel VLV HDMI)
> +    //  Revision ID = 0xFF
> +    //  Codec Verb Table For EmeraldLake/LosLunas
> +    //  Codec Vendor: 0x80862804
> +    //
> +    {
> +      0x80862882,     // Vendor ID/Device ID
> +      0x0000,         // SubSystem ID
> +      0xFF,           // Revision ID
> +      0x02,           // Front panel support (1=yes, 2=no)
> +      0x0003,         // Number of Rear Jacks
> +      0x0000          // Number of Front Jacks
> +    },
> +    0                 // Pointer to verb table data, need to be inited in the code.
> +  },
> +  {
> +    //
> +    // VerbTable: (RealTek ALC262)
> +    //  Revision ID = 0xFF, support all steps
> +    //  Codec Verb Table For AZALIA
> +    //  Codec Address: CAd value (0/1/2)
> +    //  Codec Vendor:  0x10EC0262
> +    //
> +    {
> +      0x10EC0262,     // Vendor ID/Device ID
> +      0x0000,         // SubSystem ID
> +      0xFF,           // Revision ID
> +      0x01,           // Front panel support (1=yes, 2=no)
> +      0x000B,         // Number of Rear Jacks = 11
> +      0x0002          // Number of Front Jacks = 2
> +    },
> +    0                 // Pointer to verb table data, need to be inited in the code.
> +  },
> +  {
> +    //
> +    //  VerbTable: (RealTek ALC282)
> +    //  Revision ID = 0xff
> +    //  Codec Verb Table For Azalia on SharkBay-WhiteBluff refresh and
> Haswell ULT FFRD Harris Beach, WTM1, WTM2iCRB
> +    //  Codec Address: CAd value (0/1/2)
> +    //  Codec Vendor: 0x10EC0282
> +    //
> +    {
> +      0x10EC0282, // Vendor ID/Device ID
> +      0x0000,     // SubSystem ID
> +      0xff,       // Revision ID
> +      0x01,       // Front panel support (1=yes, 2=no)
> +      0x000C,     // Number of Rear Jacks, 0x0010 for Harris Beach, 0x000B for
> WTM1 & WTM2iCRB
> +      0x0002      // Number of Front Jacks
> +    },
> +    0             // Pointer to verb table data, need to be inited in the code.
> +  }
> +};
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardId.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardId.c
> new file mode 100644
> index 0000000000..7d774568e3
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardId.c
> @@ -0,0 +1,223 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +  BoardId.c
> +
> +Abstract:
> +
> +  Initialization for the board ID.
> +
> +  This code should be common across a chipset family of products.
> +
> +
> +
> +--*/
> +
> +#include "PchRegs.h"
> +#include "PlatformDxe.h"
> +#include <Guid/IdccData.h>
> +#include <Guid/EfiVpdData.h>
> +#include <Protocol/DataHub.h>
> +
> +
> +extern EFI_GUID mPlatformDriverGuid;
> +
> +//
> +// Global module data
> +//
> +UINT32 mBoardId;
> +UINT8  mBoardIdIndex;
> +EFI_BOARD_FEATURES mBoardFeatures;
> +UINT16 mSubsystemDeviceId;
> +UINT16 mSubsystemAudioDeviceId;
> +CHAR8  BoardAaNumber[7];
> +BOOLEAN mFoundAANum;
> +
> +/**
> +
> +  Write the boardid variable if it does not already exist.
> +
> +**/
> +VOID
> +InitializeBoardId (
> +  )
> +{
> +
> +  UINT32                        BoardIdBufferSize;
> +  EFI_IDCC_BOARD_FORM_FACTOR    IdccBoardFormFactor;
> +  EFI_DATA_HUB_PROTOCOL         *DataHub;
> +  EFI_STATUS                    Status;
> +  DMI_DATA                      DmiDataVariable;
> +  UINTN                         Size;
> +#if defined(DUPLICATE_AA_NO_BASE_ADDR)
> +  CHAR8
> DuplicateAaNoAscii[sizeof(DmiDataVariable.BaseBoardVersion)];
> +  UINTN                         iter;
> +#endif
> +#if defined(GPIO_BOARD_ID_SUPPORT) && GPIO_BOARD_ID_SUPPORT !=
> 0
> +  UINT8                         Data8;
> +#endif
> +
> +  //
> +  // Update data from the updatable DMI data area
> +  //
> +  Size = sizeof (DMI_DATA);
> +  SetMem(&DmiDataVariable, Size, 0xFF);
> +  Status = gRT->GetVariable (
> +                  DMI_DATA_NAME,
> +                  &gDmiDataGuid,
> +                  NULL,
> +                  &Size,
> +                  &DmiDataVariable
> +                  );
> +
> +#if defined(DUPLICATE_AA_NO_BASE_ADDR)
> +  //
> +  // Get AA# from flash descriptor region
> +  //
> +  EfiSetMem(DuplicateAaNoAscii, sizeof(DuplicateAaNoAscii), 0xFF);
> +  FlashRead((UINT8 *)(UINTN)DUPLICATE_AA_NO_BASE_ADDR,
> +            (UINT8 *)DuplicateAaNoAscii,
> +            sizeof(DuplicateAaNoAscii));
> +
> +  //
> +  // Validate AA# read from VPD
> +  //
> +  for (iter = 0; iter < sizeof(DuplicateAaNoAscii); iter++) {
> +     if ((DuplicateAaNoAscii[iter] != 0xFF) &&
> +         (DuplicateAaNoAscii[iter] != DmiDataVariable.BaseBoardVersion[iter]))
> {
> +       DmiDataVariable.BaseBoardVersion[iter] = DuplicateAaNoAscii[iter];
> +     }
> +  }
> +
> +  Status = EFI_SUCCESS;
> +#endif
> +
> +  mFoundAANum = FALSE;
> +
> +  //
> +  // No variable...no copy
> +  //
> +  if (EFI_ERROR (Status)) {
> +    mBoardIdIndex = 0; // If we can't find the BoardId in the table, use the
> first entry
> +  } else {
> +  	//
> +    // This is the correct method of checking for AA#.
> +    //
> +    CopyMem(&BoardAaNumber,
> ((((UINT8*)&DmiDataVariable.BaseBoardVersion)+2)), 6);
> +    BoardAaNumber[6] = 0;
> +    for (mBoardIdIndex = 0; mBoardIdIndex < mBoardIdDecodeTableSize;
> mBoardIdIndex++) {
> +      if (AsciiStrnCmp(mBoardIdDecodeTable[mBoardIdIndex].AaNumber,
> BoardAaNumber, 6) == 0) {
> +        mFoundAANum = TRUE;
> +        break;
> +      }
> +    }
> +
> +    if(!mFoundAANum) {
> +    	//
> +      // Add check for AA#'s that is programmed without the AA as leading
> chars.
> +      //
> +      CopyMem(&BoardAaNumber,
> (((UINT8*)&DmiDataVariable.BaseBoardVersion)), 6);
> +      BoardAaNumber[6] = 0;
> +      for (mBoardIdIndex = 0; mBoardIdIndex < mBoardIdDecodeTableSize;
> mBoardIdIndex++) {
> +        if (AsciiStrnCmp(mBoardIdDecodeTable[mBoardIdIndex].AaNumber,
> BoardAaNumber, 6) == 0) {
> +          mFoundAANum = TRUE;
> +          break;
> +        }
> +      }
> +    }
> +  }
> +
> +#if defined(GPIO_BOARD_ID_SUPPORT) && GPIO_BOARD_ID_SUPPORT !=
> 0
> +  //
> +  // If we can't find the BoardAA# in the table, find BoardId
> +  //
> +  if (mFoundAANum != TRUE) {
> +    //
> +    // BoardID BIT    Location
> +    //  0             GPIO33  (ICH)
> +    //  1             GPIO34  (ICH)
> +    //
> +    Data8 = IoRead8(GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL2);
> +
> +    //
> +    // BoardId[0]
> +    //
> +    mBoardId = (UINT32)((Data8 >> 1) & BIT0);
> +    //
> +    // BoardId[1]
> +    //
> +    mBoardId |= (UINT32)((Data8 >> 1) & BIT1);
> +
> +    for (mBoardIdIndex = 0; mBoardIdIndex < mBoardIdDecodeTableSize;
> mBoardIdIndex++) {
> +      if (mBoardIdDecodeTable[mBoardIdIndex].BoardId == mBoardId) {
> +        break;
> +      }
> +    }
> +#endif
> +    if (mBoardIdIndex == mBoardIdDecodeTableSize) {
> +      mBoardIdIndex = 0; // If we can't find the BoardId in the table, use the
> first entry
> +    }
> +#if defined(GPIO_BOARD_ID_SUPPORT) && GPIO_BOARD_ID_SUPPORT !=
> 0
> +  }
> +#endif
> +
> +  mBoardFeatures = mBoardIdDecodeTable[mBoardIdIndex].Features;
> +  mSubsystemDeviceId =
> mBoardIdDecodeTable[mBoardIdIndex].SubsystemDeviceId;
> +  mSubsystemAudioDeviceId =
> mBoardIdDecodeTable[mBoardIdIndex].AudioSubsystemDeviceId;
> +
> +  //
> +  // Set the BoardFeatures variable
> +  //
> +  BoardIdBufferSize = sizeof (mBoardFeatures);
> +  gRT->SetVariable (
> +         BOARD_FEATURES_NAME,
> +         &gEfiBoardFeaturesGuid,
> +         EFI_VARIABLE_NON_VOLATILE |
> +         EFI_VARIABLE_BOOTSERVICE_ACCESS |
> +         EFI_VARIABLE_RUNTIME_ACCESS,
> +         BoardIdBufferSize,
> +         &mBoardFeatures
> +         );
> +
> +  //
> +  // Get the Data Hub protocol
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiDataHubProtocolGuid,
> +                  NULL,
> +                  (VOID **) &DataHub
> +                  );
> +  if (!(EFI_ERROR(Status))) {
> +    //
> +    // Fill out data
> +    //
> +    IdccBoardFormFactor.IdccHeader.Type =
> EFI_IDCC_BOARD_FORM_FACTOR_TYPE;
> +    IdccBoardFormFactor.IdccHeader.RecordLength =
> sizeof(EFI_IDCC_BOARD_FORM_FACTOR);
> +    if ((mBoardFeatures & B_BOARD_FEATURES_FORM_FACTOR_ATX) ||
> (mBoardFeatures & B_BOARD_FEATURES_FORM_FACTOR_MICRO_ATX)) {
> +        IdccBoardFormFactor.BoardFormFactor = ATX_FORM_FACTOR; // ATX
> +    } else {
> +        IdccBoardFormFactor.BoardFormFactor = BTX_FORM_FACTOR; // BTX
> +    }
> +
> +    //
> +    // Publish the Board Form Factor value for IDCC
> +    //
> +    Status = DataHub->LogData (
> +                        DataHub,
> +                        &gIdccDataHubGuid,
> +                        &mPlatformDriverGuid,
> +                        EFI_DATA_RECORD_CLASS_DATA,
> +                        &IdccBoardFormFactor,
> +                        sizeof(EFI_IDCC_BOARD_FORM_FACTOR)
> +                        );
> +  }
> +}
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.c
> new file mode 100644
> index 0000000000..d4bf5df690
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.c
> @@ -0,0 +1,129 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +  BoardIdDecode.c
> +
> +Abstract:
> +
> +--*/
> +
> +#include "PchRegs.h"
> +#include "PlatformDxe.h"
> +#include "Platform.h"
> +
> +
> +//
> +// Define macros to build data structure signatures from characters.
> +//
> +#define EFI_SIGNATURE_16(A, B)        ((A) | (B << 8))
> +#define EFI_SIGNATURE_32(A, B, C, D)  (EFI_SIGNATURE_16 (A, B) |
> (EFI_SIGNATURE_16 (C, D) << 16))
> +#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))
> +
> +BOARD_ID_DECODE mBoardIdDecodeTable[] = {
> +  //
> +  // Board ID, Board Features bitmap, Subsystem Device ID
> +  // This is a dummy entry that has to exist. Do not delete, just make a
> generic entry that fit for product.
> +  //
> +  {
> +  	MW_ITX_MPCIE_LVDS_LOEM_AA,
> +    MW_ITX_MPCIE_LVDS_LOEM_ID,
> +    B_BOARD_FEATURES_FORM_FACTOR_ATX |
> +    B_BOARD_FEATURES_SIO_COM2 |
> +    B_BOARD_FEATURES_2_C0_MEMORY_SLOT |
> +    V_BOARD_FEATURES_SLEEP_S3 |
> +    B_BOARD_FEATURES_PS2WAKEFROMS5 |
> +    B_BOARD_FEATURES_LVDS |
> +    B_BOARD_FEATURES_VERB_TABLE1,
> +    V_DEFAULT_SUBSYSTEM_DEVICE_ID,
> +    0xD625,
> +    EFI_SIGNATURE_64('M','W','P','N','T','1','0','N')
> +  },
> +
> +  {
> +  	 MW_ITX_MPCIE_LVDS_CHANNEL_AA,
> +    MW_ITX_MPCIE_LVDS_CHANNEL_ID,
> +    B_BOARD_FEATURES_FORM_FACTOR_ATX |
> +    B_BOARD_FEATURES_SIO_COM2 |
> +    B_BOARD_FEATURES_2_C0_MEMORY_SLOT |
> +    V_BOARD_FEATURES_SLEEP_S3 |
> +    B_BOARD_FEATURES_PS2WAKEFROMS5 |
> +    B_BOARD_FEATURES_LVDS |
> +    B_BOARD_FEATURES_VERB_TABLE1,
> +    V_DEFAULT_SUBSYSTEM_DEVICE_ID,
> +    0xD625,
> +    EFI_SIGNATURE_64('M','W','P','N','T','1','0','N')
> +  },
> +
> +  {
> +  	MW_ITX_MPCIE_CHANNEL_AA,
> +    MW_ITX_MPCIE_CHANNEL_ID,
> +    B_BOARD_FEATURES_FORM_FACTOR_ATX |
> +    B_BOARD_FEATURES_SIO_COM2 |
> +    B_BOARD_FEATURES_2_C0_MEMORY_SLOT |
> +    V_BOARD_FEATURES_SLEEP_S3 |
> +    B_BOARD_FEATURES_PS2WAKEFROMS5 |
> +    B_BOARD_FEATURES_VERB_TABLE1,
> +    V_DEFAULT_SUBSYSTEM_DEVICE_ID,
> +    0xD625,
> +    EFI_SIGNATURE_64('M','W','P','N','T','1','0','N')
> +  },
> +
> +  {
> +  	KT_ITX_MPCIE_LVDS_LOEM_AA,
> +    KT_ITX_MPCIE_LVDS_LOEM_ID,
> +    B_BOARD_FEATURES_FORM_FACTOR_ATX |
> +    B_BOARD_FEATURES_SIO_COM2 |
> +    B_BOARD_FEATURES_2_C0_MEMORY_SLOT |
> +    V_BOARD_FEATURES_SLEEP_S3 |
> +    B_BOARD_FEATURES_PS2WAKEFROMS5 |
> +    B_BOARD_FEATURES_LVDS |
> +    B_BOARD_FEATURES_VERB_TABLE2,
> +    V_DEFAULT_SUBSYSTEM_DEVICE_ID_KT,
> +    0xD626,
> +    EFI_SIGNATURE_64('K','T','P','N','T','1','0','N')
> +  },
> +
> +  {
> +  	KT_ITX_CHANNEL_AA,
> +    KT_ITX_CHANNEL_ID,
> +    B_BOARD_FEATURES_FORM_FACTOR_ATX |
> +    B_BOARD_FEATURES_SIO_COM2 |
> +    B_BOARD_FEATURES_2_C0_MEMORY_SLOT |
> +    V_BOARD_FEATURES_SLEEP_S3 |
> +    B_BOARD_FEATURES_PS2WAKEFROMS5 |
> +    B_BOARD_FEATURES_NO_MINIPCIE |
> +    B_BOARD_FEATURES_VERB_TABLE2,
> +    V_DEFAULT_SUBSYSTEM_DEVICE_ID_KT,
> +    0xD626,
> +    EFI_SIGNATURE_64('K','T','P','N','T','1','0','N')
> +  },
> +
> +  {
> +  	KT_ITX_LOEM_AA,
> +    KT_ITX_LOEM_ID,
> +    B_BOARD_FEATURES_FORM_FACTOR_ATX |
> +    B_BOARD_FEATURES_SIO_COM2 |
> +    B_BOARD_FEATURES_2_C0_MEMORY_SLOT |
> +    V_BOARD_FEATURES_SLEEP_S3 |
> +    B_BOARD_FEATURES_PS2WAKEFROMS5 |
> +    B_BOARD_FEATURES_NO_MINIPCIE |
> +    B_BOARD_FEATURES_VERB_TABLE2,
> +    V_DEFAULT_SUBSYSTEM_DEVICE_ID_KT,
> +    0xD626,
> +    EFI_SIGNATURE_64('K','T','P','N','T','1','0','N')
> +  }
> +};
> +
> +UINTN mBoardIdDecodeTableSize = sizeof (mBoardIdDecodeTable) /
> +                                sizeof (mBoardIdDecodeTable[0]);
> +
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.h
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.h
> new file mode 100644
> index 0000000000..8068768a3a
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.h
> @@ -0,0 +1,61 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  BoardIdDecode.h
> +
> +Abstract:
> +
> +  Header file for Platform Initialization Driver.
> +
> +Revision History
> +
> +++*/
> +
> +//
> +// Board AA# and Board ID
> +//
> +#define DEFAULT_BOARD_AA                  "FFFFFF"
> +
> +//
> +// Mount Washington (LVDS) LOEM
> +//
> +#define MW_ITX_MPCIE_LVDS_LOEM_AA         "E93081"
> +#define MW_ITX_MPCIE_LVDS_LOEM_ID         3
> +
> +//
> +// Mount Washington (LVDS) Channel
> +//
> +#define MW_ITX_MPCIE_LVDS_CHANNEL_AA      "E93080"
> +#define MW_ITX_MPCIE_LVDS_CHANNEL_ID      3
> +
> +//
> +// Mount Washington Channel
> +//
> +#define MW_ITX_MPCIE_CHANNEL_AA           "E93082"
> +#define MW_ITX_MPCIE_CHANNEL_ID           1
> +
> +//
> +// Kinston (mPCIe + LVDS) LOEM
> +//
> +#define KT_ITX_MPCIE_LVDS_LOEM_AA         "E93085"
> +#define KT_ITX_MPCIE_LVDS_LOEM_ID         2
> +
> +//
> +// Kinston (LVDS) Channel
> +//
> +#define KT_ITX_CHANNEL_AA                 "E93083"
> +#define KT_ITX_CHANNEL_ID                 0
> +
> +//
> +// Kinston LOEM
> +//
> +#define KT_ITX_LOEM_AA                    "E93084"
> +#define KT_ITX_LOEM_ID                    0
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ClockControl.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ClockControl.c
> new file mode 100644
> index 0000000000..1669f0357f
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ClockControl.c
> @@ -0,0 +1,202 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +  ClockControl.c
> +
> +Abstract:
> +
> +  Sets platform/SKU specific clock routing information.
> +
> +
> +
> +--*/
> +
> +#include "PlatformDxe.h"
> +#include <Protocol/CK505ClockPlatformInfo.h>
> +
> +//
> +// Default clock routing informtion (All On)
> +//
> +EFI_CLOCK_PLATFORM_INFO mDefClockPolicy = {NULL, 0, NULL, 0, NULL, 0};
> +
> +//
> +// Clock Settings
> +//
> +// Static clock table.
> +//  This should be used to define any clock settings that are static
> +//  (Always On or Always Off).  Dynamic clocks should be set to enabled
> +//  in this table.
> +//
> +EFI_STATIC_SIGNALS mAtxStaticClocks[] = {
> +  {SrcClk8,   Enabled,  All},
> +  {SrcClk7,   Enabled,  All},
> +  {SrcClk6,   Enabled,  All},
> +  {SrcClk5,   Enabled,  All},
> +  {SrcClk4,   Enabled,  All},
> +  {SrcClk3,   Enabled,  All},
> +  {SrcClk2,   Enabled,  All},
> +  {SrcClk1,   Enabled,  All},
> +  {SrcClk0,   Enabled,  All},
> +  {Ref0,      Enabled,  All},
> +  {Dot96,     Enabled,  All},
> +  {Usb48,     Enabled,  All},
> +  {PciClkF5,  Enabled,  All},
> +  {PciClk0,   Enabled,  All},
> +  {PciClk2,   Enabled,  All},
> +  {PciClk3,   Enabled,  All},
> +  {PciClk4,   Disabled,  All},
> +  {Cr_B,   EnabledWithSwitch,  All},
> +};
> +
> +//
> +// ClockSxInfo Table
> +//  This is a list of clocks that need to be set to a known state when the
> +//  system enters S4 or S5.
> +//
> +EFI_STATIC_SIGNALS mAtxSxClocks[] = {
> +  {SaveClockConfiguration, Disabled, All}
> +};
> +
> +//
> +// ATX settings structure
> +//
> +EFI_CLOCK_PLATFORM_INFO mAtxClockSettings = {
> +  mAtxStaticClocks,
> +  sizeof(mAtxStaticClocks) / sizeof(mAtxStaticClocks[0]),
> +  mAtxSxClocks,
> +  sizeof(mAtxSxClocks) / sizeof(mAtxSxClocks[0])
> +};
> +
> +#if defined( RVP_SUPPORT ) && RVP_SUPPORT
> +//
> +// RVP Clock Settings
> +//
> +// Static clock table.
> +//  This should be used to define any clock settings that are static
> +//  (Always On or Always Off).  Dynamic clocks should be set to enabled
> +//  in this table.
> +//
> +//UPSD_TBD Check with Jan if any porting required.
> +//
> +EFI_STATIC_SIGNALS mRvpStaticClocks[] = {
> +  {SrcClk11,  Enabled,  All},     // Not used/not present but leave coding
> enabled
> +  {SrcClk10,  Enabled,  All},     // Not used/not present but leave coding
> enabled
> +  {SrcClk9,   Enabled,  All},     // Not used/not present but leave coding
> enabled
> +  {SrcClk8,   Enabled,  All},     // ICHSATAII
> +  {SrcClk7,   Enabled,  All},     // DPL_REFSSCLKIN
> +  {SrcClk6,   Enabled,  All},     // 100M_MCH
> +  {SrcClk5,   Enabled,  All},     // Mini-PCIe  //TODO PNV: Need to check ICH
> GPIO38:
> +                                                // 0: turn on; 1: turn off
> +  {SrcClk4,   Enabled,  All},     // ICHSATA
> +  {SrcClk3,   Enabled,  All},     // 100M_ICH
> +  {SrcClk2,   Enabled,  All},     // 100M_LAN
> +  {SrcClk1,   Enabled,  All},     // 25M_LAN
> +  {SrcClk0,   Enabled,  All},     // 96M_DREF
> +  {Ref0,      Enabled,  All},
> +  {Dot96,     Enabled,  All},
> +  {Usb48,     Enabled,  All},
> +  {PciClkF5,  Enabled,  All},     // 33M_ICH
> +  {PciClk0,   Enabled,  All},     // 33M_RISER
> +  {PciClk1,   Enabled,  All},     // 33M_RISER
> +  {PciClk2,   Enabled,  All},     // VDD_Clock
> +  {PciClk3,   Enabled,  All},     // 33M_S1
> +  {PciClk4,   Enabled,  All},     // 33M_PA
> +};
> +
> +//
> +// Dynamic clock table
> +// This is used to determine if a clock should be left on or turned off based
> +// on the presence of a device.  The bridge information is used so the bus
> +// number for the device to be detected can be found.
> +//
> +
> +//
> +// ClockSxInfo Table
> +// This is a list of clocks that need to be set to a known state when the
> +// system enters S4 or S5.
> +//
> +EFI_STATIC_SIGNALS mRvpSxClocks[] = {
> +  {SaveClockConfiguration, Disabled, All}
> +};
> +
> +//
> +// RVP settings structure
> +//
> +EFI_CLOCK_PLATFORM_INFO mRvpClockSettings = {
> +  mRvpStaticClocks,
> +  sizeof(mRvpStaticClocks) / sizeof(mRvpStaticClocks[0]),
> +  0,  // No clocks will be turned off mRvpDynamicClocks,
> +  0, // No clocks will be turned off sizeof(mRvpDynamicClocks) /
> sizeof(mRvpDynamicClocks[0]),
> +  mRvpSxClocks,
> +  sizeof(mRvpSxClocks) / sizeof(mRvpSxClocks[0])
> +};
> +#endif
> +
> +VOID
> +InitializeClockRouting(
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINTN                           BoardIdVarSize;
> +  EFI_BOARD_FEATURES              BoardIdVar;
> +  EFI_CLOCK_PLATFORM_INFO         *ClockPolicy;
> +  EFI_HANDLE                      Handle;
> +
> +  ClockPolicy = &mDefClockPolicy;
> +
> +  //
> +  // Do modifications based on board type
> +  //
> +  BoardIdVarSize = sizeof (EFI_BOARD_FEATURES);
> +  Status = gRT->GetVariable (
> +                  BOARD_FEATURES_NAME,
> +                  &gEfiBoardFeaturesGuid,
> +                  NULL,
> +                  &BoardIdVarSize,
> +                  &BoardIdVar
> +                  );
> +  if (!EFI_ERROR (Status)) {
> +
> +#if defined( RVP_SUPPORT ) && RVP_SUPPORT
> +    if (BoardIdVar & B_BOARD_FEATURES_RVP) {
> +      ClockPolicy = &mRvpClockSettings;
> +    }
> +#else
> +
> +    //
> +    // Isolate board type information
> +    //
> +    BoardIdVar = BoardIdVar & (B_BOARD_FEATURES_FORM_FACTOR_ATX |
> +                               B_BOARD_FEATURES_FORM_FACTOR_BTX |
> +                               B_BOARD_FEATURES_FORM_FACTOR_MICRO_ATX |
> +                               B_BOARD_FEATURES_FORM_FACTOR_MICRO_BTX);
> +
> +    if (BoardIdVar == B_BOARD_FEATURES_FORM_FACTOR_ATX ||
> +        BoardIdVar == B_BOARD_FEATURES_FORM_FACTOR_MICRO_ATX) {
> +      ClockPolicy = &mAtxClockSettings;
> +    }
> +
> +#endif
> +
> +  }
> +
> +  Handle = NULL;
> +  Status = gBS->InstallProtocolInterface (
> +                  &Handle,
> +                  &gEfiCk505ClockPlatformInfoGuid,
> +                  EFI_NATIVE_INTERFACE,
> +                  ClockPolicy
> +                  );
> +  ASSERT_EFI_ERROR(Status);
> +
> +}
> +
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Configuration.h
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Configuration.h
> new file mode 100644
> index 0000000000..23e03111c9
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Configuration.h
> @@ -0,0 +1,692 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +    Configuration.h
> +
> +Abstract:
> +
> +    Driver configuration include file
> +
> +
> +--*/
> +
> +#ifndef _CONFIGURATION_H
> +#define _CONFIGURATION_H
> +
> +#define EFI_NON_DEVICE_CLASS               0x00
> +#define EFI_DISK_DEVICE_CLASS              0x01
> +#define EFI_VIDEO_DEVICE_CLASS             0x02
> +#define EFI_NETWORK_DEVICE_CLASS           0x04
> +#define EFI_INPUT_DEVICE_CLASS             0x08
> +#define EFI_ON_BOARD_DEVICE_CLASS          0x10
> +#define EFI_OTHER_DEVICE_CLASS             0x20
> +
> +//
> +// Processor labels
> +//
> +#define PROCESSOR_HT_MODE           0x0100
> +#define PROCESSOR_FSB_MULTIPLIER    0x0101
> +#define PROCESSOR_MULTIPLIER_OVERRIDE_CONTROL  0x0211
> +
> +//
> +// Memory labels
> +//
> +#define MEMORY_SLOT1_SPEED          0x0200
> +#define MEMORY_SLOT2_SPEED          0x0201
> +#define MEMORY_SLOT3_SPEED          0x0202
> +#define MEMORY_SLOT4_SPEED          0x0203
> +#define END_MEMORY_SLOT_SPEED       0x020F
> +#define PERFORMANCE_MEMORY_PROFILE_CONTROL  0x0210
> +#define UCLK_RATIO_CONTROL          0x0212
> +
> +//
> +// Language label
> +//
> +#define FRONT_PAGE_ITEM_LANGUAGE    0x300
> +
> +//
> +// Boot Labels
> +//
> +#define BOOT_DEVICE_PRIORITY_BEGIN  0x0400
> +#define BOOT_DEVICE_PRIORITY_END    0x0401
> +#define BOOT_OPTICAL_DEVICE_BEGIN   0x0410
> +#define BOOT_OPTICAL_DEVICE_END     0x0411
> +#define BOOT_REMOVABLE_DEVICE_BEGIN 0x0420
> +#define BOOT_REMOVABLE_DEVICE_END   0x0421
> +#define BOOT_PXE_DEVICE_BEGIN       0x0430
> +#define BOOT_PXE_DEVICE_END         0x0431
> +#define BOOT_MENU_TYPE_BEGIN        0x0440
> +#define BOOT_MENU_TYPE_END          0x0441
> +#define BOOT_USB_DEVICE_BEGIN       0x0450
> +#define BOOT_USB_DEVICE_END         0x0451
> +#define BOOT_USB_FIRST_BEGIN        0x0460
> +#define BOOT_USB_FIRST_END          0x0461
> +#define BOOT_UEFI_BEGIN             0x0470
> +#define BOOT_UEFI_END               0x0471
> +#define BOOT_USB_UNAVAILABLE_BEGIN  0x0480
> +#define BOOT_USB_UNAVAILABLE_END    0x0481
> +#define BOOT_CD_UNAVAILABLE_BEGIN   0x0490
> +#define BOOT_CD_UNAVAILABLE_END     0x0491
> +#define BOOT_FDD_UNAVAILABLE_BEGIN  0x04A0
> +#define BOOT_FDD_UNAVAILABLE_END    0x04A1
> +#define BOOT_DEVICE_PRIORITY_DEFAULT_BEGIN  0x04B0
> +#define BOOT_DEVICE_PRIORITY_DEFAULT_END    0x04B1
> +#define BOOT_USB_OPT_LABEL_BEGIN    0x04C0
> +#define BOOT_USB_OPT_LABEL_END      0x04C1
> +
> +#define VAR_EQ_ADMIN_NAME               0x0041  // A
> +#define VAR_EQ_ADMIN_DECIMAL_NAME       L"65"
> +#define VAR_EQ_VIEW_ONLY_NAME           0x0042  // B
> +#define VAR_EQ_VIEW_ONLY_DECIMAL_NAME   L"66"
> +#define VAR_EQ_CONFIG_MODE_NAME         0x0043  // C
> +#define VAR_EQ_CONFIG_MODE_DECIMAL_NAME L"67"
> +#define VAR_EQ_CPU_EE_NAME              0x0045  // E
> +#define VAR_EQ_CPU_EE_DECIMAL_NAME  L"69"
> +#define VAR_EQ_FLOPPY_MODE_NAME         0x0046  // F
> +#define VAR_EQ_FLOPPY_MODE_DECIMAL_NAME L"70"
> +#define VAR_EQ_HT_MODE_NAME             0x0048  // H
> +#define VAR_EQ_HT_MODE_DECIMAL_NAME     L"72"
> +#define VAR_EQ_AHCI_MODE_NAME           0x0049  // I
> +#define VAR_EQ_AHCI_MODE_DECIMAL_NAME   L"73"
> +#define VAR_EQ_CPU_LOCK_NAME            0x004C  // L
> +#define VAR_EQ_CPU_LOCK_DECIMAL_NAME    L"76"
> +#define VAR_EQ_NX_MODE_NAME             0x004E  // N
> +#define VAR_EQ_NX_MODE_DECIMAL_NAME     L"78"
> +#define VAR_EQ_RAID_MODE_NAME           0x0052  // R
> +#define VAR_EQ_RAID_MODE_DECIMAL_NAME   L"82"
> +#define VAR_EQ_1394_MODE_NAME           0x0054  // T
> +#define VAR_EQ_1394_MODE_DECIMAL_NAME   L"84"
> +#define VAR_EQ_USER_NAME                0x0055  // U
> +#define VAR_EQ_USER_DECIMAL_NAME        L"85"
> +#define VAR_EQ_VIDEO_MODE_NAME          0x0056  // V
> +#define VAR_EQ_VIDEO_MODE_DECIMAL_NAME  L"86"
> +#define VAR_EQ_LEGACY_FP_AUDIO_NAME     0x0057  // W
> +#define VAR_EQ_LEGACY_FP_AUDIO_DECIMAL_NAME L"87"
> +#define VAR_EQ_EM64T_CAPABLE_NAME       0x0058  // X
> +#define VAR_EQ_EM64T_CAPABLE_DECIMAL_NAME L"88"
> +#define VAR_EQ_BOARD_FORMFACTOR_NAME    0x0059  // Y
> +#define VAR_EQ_BOARD_FORMFACTOR_DECIMAL_NAME L"89"
> +#define VAR_EQ_UNCON_CPU_NAME           0x005B  // ??
> +#define VAR_EQ_UNCON_CPU_DECIMAL_NAME   L"91"
> +#define VAR_EQ_VAR_HIDE_NAME            0x005C  // ??
> +#define VAR_EQ_VAR_HIDE_DECIMAL_NAME    L"92"
> +#define VAR_EQ_ENERGY_LAKE_NAME         0x005D  // ??
> +#define VAR_EQ_ENERGY_LAKE_DECIMAL_NAME L"93"
> +#define VAR_EQ_TPM_MODE_NAME            0x005E  // ^
> +#define VAR_EQ_TPM_MODE_DECIMAL_NAME    L"94"
> +#define VAR_EQ_DISCRETE_SATA_NAME       0x005F  // ??
> +#define VAR_EQ_DISCRETE_SATA_DECIMAL_NAME L"95"
> +#define VAR_EQ_ROEM_SKU_NAME            0x0060  // ??
> +#define VAR_EQ_ROEM_SKU_DECIMAL_NAME    L"96"
> +#define VAR_EQ_AMTSOL_MODE_NAME         0x0061  // ??
> +#define VAR_EQ_AMTSOL_MODE_DECIMAL_NAME L"97"
> +#define VAR_EQ_NO_PEG_MODE_NAME         0x0062  // ??
> +#define VAR_EQ_NO_PEG_MODE_DECIMAL_NAME L"98"
> +#define VAR_EQ_SINGLE_PROCESSOR_MODE_NAME 0x0063  // ??
> +#define VAR_EQ_SINGLE_PROCESSOR_MODE_DECIMAL_NAME L"99"
> +#define VAR_EQ_FLOPPY_HIDE_NAME         0x0064  // ??
> +#define VAR_EQ_FLOPPY_HIDE_DECIMAL_NAME L"100"
> +#define VAR_EQ_SERIAL_HIDE_NAME         0x0065  // ??
> +#define VAR_EQ_SERIAL_HIDE_DECIMAL_NAME L"101"
> +#define VAR_EQ_GV3_CAPABLE_NAME         0x0066 // f
> +#define VAR_EQ_GV3_CAPABLE_DECIMAL_NAME L"102"
> +#define VAR_EQ_2_MEMORY_NAME            0x0067 // ??
> +#define VAR_EQ_2_MEMORY_DECIMAL_NAME    L"103"
> +#define VAR_EQ_2_SATA_NAME              0x0068 // ??
> +#define VAR_EQ_2_SATA_DECIMAL_NAME      L"104"
> +#define VAR_EQ_NEC_SKU_NAME            0x0069  // ??
> +#define VAR_EQ_NEC_SKU_DECIMAL_NAME    L"105"
> +#define VAR_EQ_AMT_MODE_NAME            0x006A  // ??
> +#define VAR_EQ_AMT_MODE_DECIMAL_NAME    L"106"
> +#define VAR_EQ_LCLX_SKU_NAME            0x006B  // ??
> +#define VAR_EQ_LCLX_SKU_DECIMAL_NAME    L"107"
> +#define VAR_EQ_VT_NAME                  0x006C
> +#define VAR_EQ_VT_DECIMAL_NAME          L"108"
> +#define VAR_EQ_LT_NAME                  0x006D
> +#define VAR_EQ_LT_DECIMAL_NAME          L"109"
> +#define VAR_EQ_ITK_BIOS_MOD_NAME         0x006E  // ??
> +#define VAR_EQ_ITK_BIOS_MOD_DECIMAL_NAME L"110"
> +#define VAR_EQ_HPET_NAME                0x006F
> +#define VAR_EQ_HPET_DECIMAL_NAME        L"111"
> +#define VAR_EQ_ADMIN_INSTALLED_NAME          0x0070  // ??
> +#define VAR_EQ_ADMIN_INSTALLED_DECIMAL_NAME  L"112"
> +#define VAR_EQ_USER_INSTALLED_NAME          0x0071  // ??
> +#define VAR_EQ_USER_INSTALLED_DECIMAL_NAME  L"113"
> +#define VAR_EQ_CPU_CMP_NAME             0x0072
> +#define VAR_EQ_CPU_CMP_DECIMAL_NAME     L"114"
> +#define VAR_EQ_LAN_MAC_ADDR_NAME          0x0073  // ??
> +#define VAR_EQ_LAN_MAC_ADDR_DECIMAL_NAME  L"115"
> +#define VAR_EQ_PARALLEL_HIDE_NAME         0x0074  // ??
> +#define VAR_EQ_PARALLEL_HIDE_DECIMAL_NAME L"116"
> +#define VAR_EQ_AFSC_SETUP_NAME          0x0075
> +#define VAR_EQ_AFSC_SETUP_DECIMAL_NAME  L"117"
> +#define VAR_EQ_MINICARD_MODE_NAME       0x0076  //
> +#define VAR_EQ_MINICARD_MODE_DECIMAL_NAME   L"118"
> +#define VAR_EQ_VIDEO_IGD_NAME          0x0077  //
> +#define VAR_EQ_VIDEO_IGD_DECIMAL_NAME  L"119"
> +#define VAR_EQ_ALWAYS_ENABLE_LAN_NAME            0x0078  //
> +#define VAR_EQ_ALWAYS_ENABLE_LAN_DECIMAL_NAME    L"120"
> +#define VAR_EQ_LEGACY_FREE_NAME          0x0079  //
> +#define VAR_EQ_LEGACY_FREE_DECIMAL_NAME   L"121"
> +#define VAR_EQ_CLEAR_CHASSIS_INSTRUSION_STATUS_NAME
> 0x007A
> +#define VAR_EQ_CLEAR_CHASSIS_INSTRUSION_STATUS_DECIMAL_NAME
> L"122"
> +#define VAR_EQ_CPU_FSB_NAME            0x007B  //
> +#define VAR_EQ_CPU_FSB_DECIMAL_NAME    L"123"
> +#define VAR_EQ_SATA0_DEVICE_NAME            0x007C  //
> +#define VAR_EQ_SATA0_DVICE_DECIMAL_NAME    L"124"
> +#define VAR_EQ_SATA1_DEVICE_NAME            0x007D  //
> +#define VAR_EQ_SATA1_DVICE_DECIMAL_NAME    L"125"
> +#define VAR_EQ_SATA2_DEVICE_NAME            0x007E  //
> +#define VAR_EQ_SATA2_DVICE_DECIMAL_NAME    L"126"
> +#define VAR_EQ_SATA3_DEVICE_NAME            0x007F  //
> +#define VAR_EQ_SATA3_DVICE_DECIMAL_NAME    L"127"
> +#define VAR_EQ_SATA4_DEVICE_NAME            0x0080  //
> +#define VAR_EQ_SATA4_DVICE_DECIMAL_NAME    L"128"
> +#define VAR_EQ_SATA5_DEVICE_NAME            0x0081  //
> +#define VAR_EQ_SATA5_DVICE_DECIMAL_NAME    L"129"
> +#define VAR_EQ_TPM_STATUS_NAME              0x0082      // To indicate if
> TPM is enabled
> +#define VAR_EQ_TPM_STATUS_DECIMAL_NAME     L"130"
> +#define VAR_EQ_HECETA6E_PECI_CPU_NAME   0x0083
> +#define VAR_EQ_HECETA6E_PECI_CPU_DECIMAL_NAME L"131"
> +#define VAR_EQ_USB_2_NAME                   0x0084  //
> +#define VAR_EQ_USB_2_DECIMAL_NAME          L"132"
> +#define VAR_EQ_RVP_NAME                   0x0085  //
> +#define VAR_EQ_RVP_DECIMAL_NAME          L"133"
> +#define VAR_EQ_ECIR_NAME                    0x0086
> +#define VAR_EQ_ECIR_DECIMAL_NAME           L"134"
> +#define VAR_EQ_WAKONS5KB_NAME               0x0087
> +#define VAR_EQ_WAKONS5KB_DECIMAL_NAME      L"135"
> +#define VAR_EQ_HDAUDIOLINKBP_NAME           0x0088
> +#define VAR_EQ_HDAUDIOLINKBP_DECIMAL_NAME  L"136"
> +#define VAR_EQ_FINGERPRINT_NAME             0x0089
> +#define VAR_EQ_FINGERPRINT_DECIMAL_NAME    L"137"
> +#define VAR_EQ_BLUETOOTH_NAME               0x008A
> +#define VAR_EQ_BLUETOOTH_DECIMAL_NAME      L"138"
> +#define VAR_EQ_WLAN_NAME                    0x008B
> +#define VAR_EQ_WLAN_DECIMAL_NAME           L"139"
> +#define VAR_EQ_1_PATA_NAME                  0x008C
> +#define VAR_EQ_1_PATA_DECIMAL_NAME         L"140"
> +#define VAR_EQ_ACTIVE_PROCESSOR_CORE_NAME          0x008D
> +#define VAR_EQ_ACTIVE_PROCESSOR_CORE_DECIMAL_NAME  L"141"
> +#define VAR_EQ_TURBO_MODE_CAP_NAME          0x008E
> +#define VAR_EQ_TURBO_MODE_CAP_DECIMAL_NAME  L"142"
> +#define VAR_EQ_XE_MODE_CAP_NAME             0x008F
> +#define VAR_EQ_XE_MODE_CAP_DECIMAL_NAME     L"143"
> +#define VAR_EQ_NPI_QPI_VOLTAGE_NAME         0x0090
> +#define VAR_EQ_NPI_QPI_VOLTAGE_DECIMAL_NAME L"144"
> +#define VAR_EQ_PRE_PROD_NON_XE_NAME         0x0091
> +#define VAR_EQ_PRE_PROD_NON_XE_DECIMAL_NAME L"145"
> +#define VAR_EQ_2_C0_MEMORY_NAME            0x0092 // ??
> +#define VAR_EQ_2_C0_MEMORY_DECIMAL_NAME    L"146"
> +#define VAR_EQ_LVDS_NAME                    0x0093
> +#define VAR_EQ_LVDS_DECIMAL_NAME            L"147"
> +#define VAR_EQ_USB_OPTION_SHOW_NAME                    0x0094
> +#define VAR_EQ_USB_OPTION_SHOW_DECIMAL_NAME            L"148"
> +#define VAR_EQ_HDD_MASTER_INSTALLED_NAME      0x0095
> +#define VAR_EQ_HDD_MASTER_INSTALLED_DECIMAL_NAME      L"149"
> +#define VAR_EQ_HDD_USER_INSTALLED_NAME        0x0096
> +#define VAR_EQ_HDD_USER_INSTALLED_DECIMAL_NAME       L"150"
> +#define VAR_EQ_PS2_HIDE_NAME         0x0097  // ??
> +#define VAR_EQ_PS2_HIDE_DECIMAL_NAME L"151"
> +#define VAR_EQ_VIDEO_SLOT_NAME       0x0098
> +#define VAR_EQ_VIDEO_SLOT_DECIMAL_NAME       L"152"
> +#define VAR_EQ_HDMI_SLOT_NAME       0x0099
> +#define VAR_EQ_HDMI_SLOT_DECIMAL_NAME       L"153"
> +#define VAR_EQ_SERIAL2_HIDE_NAME         0x009a
> +#define VAR_EQ_SERIAL2_HIDE_DECIMAL_NAME L"154"
> +
> +
> +#define VAR_EQ_LVDS_WARNING_HIDE_NAME    0x009e
> +#define VAR_EQ_LVDS_WARNING_HIDE_DECIMAL_NAME L"158"
> +
> +
> +#define VAR_EQ_MSATA_HIDE_NAME    0x009f
> +#define VAR_EQ_MSATA_HIDE_DECIMAL_NAME L"159"
> +
> +
> +#define VAR_EQ_PCI_SLOT1_NAME    0x00a0
> +#define VAR_EQ_PCI_SLOT1_DECIMAL_NAME L"160"
> +#define VAR_EQ_PCI_SLOT2_NAME    0x00a1
> +#define VAR_EQ_PCI_SLOT2_DECIMAL_NAME L"161"
> +
> +//
> +// Generic Form Ids
> +//
> +#define ROOT_FORM_ID                    1
> +
> +//
> +// Advance Page. Do not have to be sequential but have to be unique
> +//
> +#define CONFIGURATION_ROOT_FORM_ID          2
> +#define BOOT_CONFIGURATION_ID               3
> +#define ONBOARDDEVICE_CONFIGURATION_ID      4
> +#define DRIVE_CONFIGURATION_ID              5
> +#define FLOPPY_CONFIGURATION_ID             6
> +#define EVENT_LOG_CONFIGURATION_ID          7
> +#define VIDEO_CONFIGURATION_ID              8
> +#define USB_CONFIGURATION_ID                9
> +#define HARDWARE_MONITOR_CONFIGURATION_ID   10
> +#define VIEW_EVENT_LOG_CONFIGURATION_ID     11
> +#define MEMORY_OVERRIDE_ID                  12
> +#define CHIPSET_CONFIGURATION_ID            13
> +#define BURN_IN_MODE_ID                     14
> +#define PCI_EXPRESS_ID                      15
> +#define MANAGEMENT_CONFIGURATION_ID         16
> +#define CPU_CONFIGURATION_ID                17
> +#define PCI_CONFIGURATION_ID                18
> +#define SECURITY_CONFIGURATION_ID           19
> +#define ZIP_CONFIGURATION_ID                20
> +#define AFSC_FAN_CONTROL_ID                 21
> +#define VFR_FORMID_CSI                      22
> +#define VFR_FORMID_MEMORY                   23
> +#define VFR_FORMID_IOH                      24
> +#define VFR_FORMID_CPU_CSI                  25
> +#define VFR_FORMID_IOH_CONFIG               26
> +#define VFR_FORMID_VTD                      27
> +#define VFR_FORMID_PCIE_P0                  28
> +#define VFR_FORMID_PCIE_P1                  29
> +#define VFR_FORMID_PCIE_P2                  30
> +#define VFR_FORMID_PCIE_P3                  31
> +#define VFR_FORMID_PCIE_P4                  32
> +#define VFR_FORMID_PCIE_P5                  33
> +#define VFR_FORMID_PCIE_P6                  34
> +#define VFR_FORMID_PCIE_P7                  35
> +#define VFR_FORMID_PCIE_P8                  36
> +#define VFR_FORMID_PCIE_P9                  37
> +#define VFR_FORMID_PCIE_P10                 38
> +#define VFR_FID_SKT0                        39
> +#define VFR_FID_IOH0                        40
> +#define VFR_FID_IOH_DEV_HIDE                41
> +#define PROCESSOR_OVERRIDES_FORM_ID         42
> +#define BUS_OVERRIDES_FORM_ID               43
> +#define REF_OVERRIDES_FORM_ID               44
> +#define MEMORY_INFORMATION_ID               45
> +#define LVDS_WARNING_ID                     46
> +#define LVDS_CONFIGURATION_ID               47
> +#define PCI_SLOT_CONFIGURATION_ID           48
> +#define HECETA_CONFIGURATION_ID             49
> +#define LVDS_EXPERT_CONFIGURATION_ID        50
> +#define PCI_SLOT_7_ID                       51
> +#define PCI_SLOT_6_ID                       52
> +#define PCI_SLOT_5_ID                       53
> +#define PCI_SLOT_4_ID                       54
> +#define PCI_SLOT_3_ID                       55
> +#define PCI_SLOT_2_ID                       56
> +#define PCI_SLOT_1_ID                       57
> +#define BOOT_DISPLAY_ID                     58
> +#define CPU_PWR_CONFIGURATION_ID            59
> +
> +#define FSC_CONFIGURATION_ID                60
> +#define FSC_CPU_TEMPERATURE_FORM_ID         61
> +#define FSC_VTT_VOLTAGE_FORM_ID             62
> +#define FSC_FEATURES_CONTROL_ID             63
> +#define FSC_FAN_CONFIGURATION_ID            64
> +#define FSC_PROCESSOR_FAN_CONFIGURATION_ID  65
> +#define FSC_FRONT_FAN_CONFIGURATION_ID      66
> +#define FSC_REAR_FAN_CONFIGURATION_ID       67
> +#define FSC_AUX_FAN_CONFIGURATION_ID        68
> +#define FSC_12_VOLTAGE_FORM_ID              69
> +#define FSC_5_VOLTAGE_FORM_ID               70
> +#define FSC_3P3_VOLTAGE_FORM_ID             71
> +#define FSC_2P5_VOLTAGE_FORM_ID             72
> +#define FSC_VCC_VOLTAGE_FORM_ID             73
> +#define FSC_PCH_TEMPERATURE_FORM_ID         74
> +#define FSC_MEM_TEMPERATURE_FORM_ID         75
> +#define FSC_VR_TEMPERATURE_FORM_ID          76
> +#define FSC_3P3STANDBY_VOLTAGE_FORM_ID      77
> +#define FSC_5BACKUP_VOLTAGE_FORM_ID         78
> +#define ROOT_MAIN_FORM_ID                   79
> +#define ROOT_BOOT_FORM_ID                   80
> +#define ROOT_MAINTENANCE_ID                 81
> +#define ROOT_POWER_FORM_ID                  82
> +#define ROOT_SECURITY_FORM_ID               83
> +#define ROOT_PERFORMANCE_FORM_ID            84
> +#define ROOT_SYSTEM_SETUP_FORM_ID           85
> +
> +#define ADDITIONAL_SYSTEM_INFO_FORM_ID      86
> +
> +#define THERMAL_CONFIG_FORM_ID              87
> +
> +#define PCI_SLOT_CONFIG_LABEL_ID_1            0x300A
> +#define PCI_SLOT_CONFIG_LABEL_ID_2            0x300B
> +#define PCI_SLOT_CONFIG_LABEL_ID_3            0x300C
> +#define PCI_SLOT_CONFIG_LABEL_ID_4            0x300D
> +#define PCI_SLOT_CONFIG_LABEL_ID_5            0x300E
> +#define PCI_SLOT_CONFIG_LABEL_ID_6            0x300F
> +#define PCI_SLOT_CONFIG_LABEL_ID_7            0x3010
> +#define PCI_SLOT_CONFIG_LABEL_ID_8            0x3011
> +
> +//
> +// Advance Hardware Monitor Callback Keys. Do not have to be sequential
> but have to be unique
> +//
> +#define CONFIGURATION_HARDWARE_CALLBACK_KEY            0x2000
> +#define ADVANCE_VIDEO_CALLBACK_KEY                     0x2001
> +#define CONFIGURATION_FSC_CALLBACK_KEY                 0x2002
> +#define CONFIGURATION_RESTORE_FAN_CONTROL_CALLBACK_KEY
> 0x2003
> +#define CONFIGURATION_LVDS_CALLBACK_KEY                0x2004
> +#define CONFIGURATION_PREDEFINED_EDID_CALLBACK_KEY     0x2005
> +#define ADVANCE_LVDS_CALLBACK_KEY           0x2010
> +
> +//
> +// Main Callback Keys. Do not have to be sequential but have to be unique
> +//
> +#define MAIN_LANGUAGE_CALLBACK_KEY          0x3000
> +
> +//
> +// Power Hardware Monitor Callback Keys. Do not have to be sequential but
> have to be unique
> +//
> +#define POWER_HARDWARE_CALLBACK_KEY         0x4000
> +
> +//
> +// Performance Callback Keys. Do not have to be sequential but have to be
> unique
> +//
> +#define PROCESSOR_OVERRIDES_CALLBACK_KEY 0x5000
> +#define PERFORMANCE_CALLBACK_KEY         0x5001
> +#define BUS_OVERRIDES_CALLBACK_KEY       0x5002
> +#define MEMORY_CFG_CALLBACK_KEY          0x5003
> +#define PERFORMANCE_STATUS_CALLBACK_KEY  0x5004
> +#define MEMORY_RATIO_CALLBACK_KEY        0x5005
> +#define MEMORY_MODE_CALLBACK_KEY         0x5006
> +
> +//
> +// Security Callback Keys. Do not have to be sequential but have to be
> unique
> +//
> +#define SECURITY_SUPERVISOR_CALLBACK_KEY    0x1000
> +#define SECURITY_USER_CALLBACK_KEY          0x1001
> +#define SECURITY_CLEAR_ALL_CALLBACK_KEY     0x1002
> +#define SECURITY_CLEAR_USER_CALLBACK_KEY    0x1004
> +#define SECURITY_RESET_AMT_CALLBACK_KEY     0x1008
> +#define SECURITY_CHANGE_VT_CALLBACK_KEY     0x1010
> +#define SECURITY_MASTER_HDD_CALLBACK_KEY    0x1020
> +#define SECURITY_USER_HDD_CALLBACK_KEY      0x1040
> +
> +//
> +// Boot Callback Keys. Do not have to be sequential but have to be unique
> +//
> +#define BOOT_HYPERBOOT_CALLBACK_KEY                 0x6003
> +#define BOOT_HYPERBOOT_CALLBACK_KEY_DISABLE         0x6004
> +#define BOOT_HYPERBOOT_CALLBACK_KEY_USB             0x6005
> +#define BOOT_HYPERBOOT_CALLBACK_KEY_DISABLE_USB_OPT 0x6006
> +
> +//
> +// IDCC/Setup FSB Frequency Override Range
> +//
> +#define EFI_IDCC_FSB_MIN   133
> +#define EFI_IDCC_FSB_MAX   240
> +#define EFI_IDCC_FSB_STEP  1
> +
> +//
> +// Reference voltage
> +//
> +#define EFI_REF_DAC_MIN     0
> +#define EFI_REF_DAC_MAX     255
> +#define EFI_GTLREF_DEF      170
> +#define EFI_DDRREF_DEF      128
> +#define EFI_DIMMREF_DEF     128
> +
> +//
> +// Setup FSB Frequency Override Range
> +//
> +#define EFI_FSB_MIN       133
> +#define EFI_FSB_MAX       240
> +#define EFI_FSB_STEP      1
> +#define EFI_FSB_AUTOMATIC 0
> +#define EFI_FSB_MANUAL    1
> +#define FSB_FREQ_ENTRY_COUNT ((EFI_FSB_MAX -
> EFI_FSB_MIN)/EFI_FSB_STEP) + 1
> +#define FSB_FREQ_ENTRY_TYPE  UINT16_TYPE
> +
> +//
> +// Setup processor multiplier range
> +//
> +#define EFI_PROC_MULT_MIN   5
> +#define EFI_PROC_MULT_MAX   40
> +#define EFI_PROC_MULT_STEP  1
> +#define EFI_PROC_AUTOMATIC  0
> +#define EFI_PROC_MANUAL     1
> +#define PROC_MULT_ENTRY_COUNT ((EFI_PROC_MULT_MAX -
> EFI_PROC_MULT_MIN)/EFI_PROC_MULT_STEP) + 1
> +#define PROC_MULT_ENTRY_TYPE  UINT8_TYPE
> +
> +//
> +// PCI Express Definitions
> +//
> +#define EFI_PCIE_FREQ_DEF       0x0
> +
> +#define PCIE_FREQ_ENTRY_TYPE  UINT8_TYPE
> +#define PCIE_FREQ_ENTRY_7       0x7
> +#define PCIE_FREQ_ENTRY_6       0x6
> +#define PCIE_FREQ_ENTRY_5       0x5
> +#define PCIE_FREQ_ENTRY_4       0x4
> +#define PCIE_FREQ_ENTRY_3       0x3
> +#define PCIE_FREQ_ENTRY_2       0x2
> +#define PCIE_FREQ_ENTRY_1       0x1
> +#define PCIE_FREQ_ENTRY_0       0x0
> +
> +#define PCIE_FREQ_TRANSLATION_TABLE_ENTRIES 8
> +#define PCIE_FREQ_TRANSLATION_TABLE     { PCIE_FREQ_ENTRY_0, \
> +                                          PCIE_FREQ_ENTRY_1, \
> +                                          PCIE_FREQ_ENTRY_2, \
> +                                          PCIE_FREQ_ENTRY_3, \
> +                                          PCIE_FREQ_ENTRY_4, \
> +                                          PCIE_FREQ_ENTRY_5, \
> +                                          PCIE_FREQ_ENTRY_6, \
> +                                          PCIE_FREQ_ENTRY_7 }
> +
> +
> +#define PCIE_FREQ_PRECISION     2
> +#define PCIE_FREQ_VALUE_7       10924
> +#define PCIE_FREQ_VALUE_6       10792
> +#define PCIE_FREQ_VALUE_5       10660
> +#define PCIE_FREQ_VALUE_4       10528
> +#define PCIE_FREQ_VALUE_3       10396
> +#define PCIE_FREQ_VALUE_2       10264
> +#define PCIE_FREQ_VALUE_1       10132
> +#define PCIE_FREQ_VALUE_0       10000
> +
> +#define PCIE_FREQ_VALUES      { PCIE_FREQ_VALUE_0, \
> +                                PCIE_FREQ_VALUE_1, \
> +                                PCIE_FREQ_VALUE_2, \
> +                                PCIE_FREQ_VALUE_3, \
> +                                PCIE_FREQ_VALUE_4, \
> +                                PCIE_FREQ_VALUE_5, \
> +                                PCIE_FREQ_VALUE_6, \
> +                                PCIE_FREQ_VALUE_7 }
> +
> +//
> +// Memory Frequency Definitions
> +//
> +#define MEMORY_REF_FREQ_ENTRY_DEF     0x08
> +
> +#define MEMORY_REF_FREQ_ENTRY_TYPE    UINT8_TYPE
> +#define MEMORY_REF_FREQ_ENTRY_3       0x04
> +#define MEMORY_REF_FREQ_ENTRY_2       0x00
> +#define MEMORY_REF_FREQ_ENTRY_1       0x02
> +#define MEMORY_REF_FREQ_ENTRY_0       0x01
> +
> +#define MEMORY_REF_FREQ_TRANSLATION_TABLE_ENTRIES 4
> +#define MEMORY_REF_FREQ_TRANSLATION_TABLE
> { MEMORY_REF_FREQ_ENTRY_0, \
> +                                                MEMORY_REF_FREQ_ENTRY_1, \
> +                                                MEMORY_REF_FREQ_ENTRY_2, \
> +                                                MEMORY_REF_FREQ_ENTRY_3 }
> +
> +#define MEMORY_REF_FREQ_PRECISION     0
> +#define MEMORY_REF_FREQ_VALUE_3       333
> +#define MEMORY_REF_FREQ_VALUE_2       267
> +#define MEMORY_REF_FREQ_VALUE_1       200
> +#define MEMORY_REF_FREQ_VALUE_0       133
> +
> +#define MEMORY_REF_FREQ_VALUES      { MEMORY_REF_FREQ_VALUE_0,
> \
> +                                      MEMORY_REF_FREQ_VALUE_1, \
> +                                      MEMORY_REF_FREQ_VALUE_2, \
> +                                      MEMORY_REF_FREQ_VALUE_3 }
> +
> +
> +//
> +// Memory Reference Frequency Definitions
> +//
> +
> +#define MEMORY_FREQ_ENTRY_TYPE    UINT8_TYPE
> +#define MEMORY_FREQ_ENTRY_3       0x4
> +#define MEMORY_FREQ_ENTRY_2       0x3
> +#define MEMORY_FREQ_ENTRY_1       0x2
> +#define MEMORY_FREQ_ENTRY_0       0x1
> +
> +#define MEMORY_FREQ_TRANSLATION_TABLE_ENTRIES 4
> +#define MEMORY_FREQ_TRANSLATION_TABLE
> { MEMORY_FREQ_ENTRY_0, \
> +                                            MEMORY_FREQ_ENTRY_1, \
> +                                            MEMORY_FREQ_ENTRY_2, \
> +                                            MEMORY_FREQ_ENTRY_3 }
> +
> +
> +#define MEMORY_FREQ_MULT_PRECISION             2
> +#define MEMORY_FREQ_MULT_333MHZ_VALUE_3        240
> +#define MEMORY_FREQ_MULT_333MHZ_VALUE_2        200
> +#define MEMORY_FREQ_MULT_333MHZ_VALUE_1        160
> +#define MEMORY_FREQ_MULT_333MHZ_VALUE_0        120
> +
> +#define MEMORY_FREQ_MULT_266MHZ_VALUE_3        300
> +#define MEMORY_FREQ_MULT_266MHZ_VALUE_2        250
> +#define MEMORY_FREQ_MULT_266MHZ_VALUE_1        200
> +#define MEMORY_FREQ_MULT_266MHZ_VALUE_0        150
> +
> +#define MEMORY_FREQ_MULT_200MHZ_VALUE_3        400
> +#define MEMORY_FREQ_MULT_200MHZ_VALUE_2        333
> +#define MEMORY_FREQ_MULT_200MHZ_VALUE_1        267
> +#define MEMORY_FREQ_MULT_200MHZ_VALUE_0        200
> +
> +#define MEMORY_FREQ_MULT_133MHZ_VALUE_3        600
> +#define MEMORY_FREQ_MULT_133MHZ_VALUE_2        500
> +#define MEMORY_FREQ_MULT_133MHZ_VALUE_1        400
> +#define MEMORY_FREQ_MULT_133MHZ_VALUE_0        300
> +
> +#define MEMORY_FREQ_MULT_333MHZ_VALUES
> { MEMORY_FREQ_MULT_333MHZ_VALUE_0, \
> +                                              MEMORY_FREQ_MULT_333MHZ_VALUE_1, \
> +                                              MEMORY_FREQ_MULT_333MHZ_VALUE_2, \
> +                                              MEMORY_FREQ_MULT_333MHZ_VALUE_3 }
> +
> +#define MEMORY_FREQ_MULT_266MHZ_VALUES
> { MEMORY_FREQ_MULT_266MHZ_VALUE_0, \
> +                                              MEMORY_FREQ_MULT_266MHZ_VALUE_1, \
> +                                              MEMORY_FREQ_MULT_266MHZ_VALUE_2, \
> +                                              MEMORY_FREQ_MULT_266MHZ_VALUE_3 }
> +
> +#define MEMORY_FREQ_MULT_200MHZ_VALUES
> { MEMORY_FREQ_MULT_200MHZ_VALUE_0, \
> +                                              MEMORY_FREQ_MULT_200MHZ_VALUE_1, \
> +                                              MEMORY_FREQ_MULT_200MHZ_VALUE_2, \
> +                                              MEMORY_FREQ_MULT_200MHZ_VALUE_3 }
> +
> +#define MEMORY_FREQ_MULT_133MHZ_VALUES
> { MEMORY_FREQ_MULT_133MHZ_VALUE_0, \
> +                                              MEMORY_FREQ_MULT_133MHZ_VALUE_1, \
> +                                              MEMORY_FREQ_MULT_133MHZ_VALUE_2, \
> +                                              MEMORY_FREQ_MULT_133MHZ_VALUE_3 }
> +
> +//
> +// CAS Memory Timing Definitions
> +//
> +
> +#define MEMORY_TCL_ENTRY_TYPE    UINT8_TYPE
> +#define MEMORY_TCL_ENTRY_3       0x2
> +#define MEMORY_TCL_ENTRY_2       0x1
> +#define MEMORY_TCL_ENTRY_1       0x0
> +#define MEMORY_TCL_ENTRY_0       0x3
> +
> +#define MEMORY_TCL_TRANSLATION_TABLE_ENTRIES 4
> +#define MEMORY_TCL_TRANSLATION_TABLE     { MEMORY_TCL_ENTRY_0,
> \
> +                                           MEMORY_TCL_ENTRY_1, \
> +                                           MEMORY_TCL_ENTRY_2, \
> +                                           MEMORY_TCL_ENTRY_3 }
> +
> +
> +#define MEMORY_TCL_PRECISION     0
> +#define MEMORY_TCL_VALUE_3       3
> +#define MEMORY_TCL_VALUE_2       4
> +#define MEMORY_TCL_VALUE_1       5
> +#define MEMORY_TCL_VALUE_0       6
> +
> +#define MEMORY_TCL_VALUES      { MEMORY_TCL_VALUE_0, \
> +                                 MEMORY_TCL_VALUE_1, \
> +                                 MEMORY_TCL_VALUE_2, \
> +                                 MEMORY_TCL_VALUE_3 }
> +
> +
> +//
> +// TRCD Memory Timing Definitions
> +//
> +
> +#define MEMORY_TRCD_ENTRY_TYPE    UINT8_TYPE
> +#define MEMORY_TRCD_ENTRY_3       0x0
> +#define MEMORY_TRCD_ENTRY_2       0x1
> +#define MEMORY_TRCD_ENTRY_1       0x2
> +#define MEMORY_TRCD_ENTRY_0       0x3
> +
> +#define MEMORY_TRCD_TRANSLATION_TABLE_ENTRIES 4
> +#define MEMORY_TRCD_TRANSLATION_TABLE
> { MEMORY_TRCD_ENTRY_0, \
> +                                            MEMORY_TRCD_ENTRY_1, \
> +                                            MEMORY_TRCD_ENTRY_2, \
> +                                            MEMORY_TRCD_ENTRY_3 }
> +
> +
> +#define MEMORY_TRCD_PRECISION     0
> +#define MEMORY_TRCD_VALUE_3       2
> +#define MEMORY_TRCD_VALUE_2       3
> +#define MEMORY_TRCD_VALUE_1       4
> +#define MEMORY_TRCD_VALUE_0       5
> +
> +#define MEMORY_TRCD_VALUES      { MEMORY_TRCD_VALUE_0, \
> +                                  MEMORY_TRCD_VALUE_1, \
> +                                  MEMORY_TRCD_VALUE_2, \
> +                                  MEMORY_TRCD_VALUE_3 }
> +
> +
> +//
> +// TRP Memory Timing Definitions
> +//
> +
> +#define MEMORY_TRP_ENTRY_TYPE    UINT8_TYPE
> +#define MEMORY_TRP_ENTRY_3       0x0
> +#define MEMORY_TRP_ENTRY_2       0x1
> +#define MEMORY_TRP_ENTRY_1       0x2
> +#define MEMORY_TRP_ENTRY_0       0x3
> +
> +#define MEMORY_TRP_TRANSLATION_TABLE_ENTRIES 4
> +#define MEMORY_TRP_TRANSLATION_TABLE     { MEMORY_TRP_ENTRY_0,
> \
> +                                           MEMORY_TRP_ENTRY_1, \
> +                                           MEMORY_TRP_ENTRY_2, \
> +                                           MEMORY_TRP_ENTRY_3 }
> +
> +
> +#define MEMORY_TRP_PRECISION     0
> +#define MEMORY_TRP_VALUE_3       2
> +#define MEMORY_TRP_VALUE_2       3
> +#define MEMORY_TRP_VALUE_1       4
> +#define MEMORY_TRP_VALUE_0       5
> +
> +#define MEMORY_TRP_VALUES      { MEMORY_TRP_VALUE_0, \
> +                                 MEMORY_TRP_VALUE_1, \
> +                                 MEMORY_TRP_VALUE_2, \
> +                                 MEMORY_TRP_VALUE_3 }
> +
> +
> +//
> +// TRAS Memory Timing Definitions
> +//
> +#define MEMORY_TRAS_MIN     4
> +#define MEMORY_TRAS_MAX     18
> +#define MEMORY_TRAS_STEP    1
> +#define MEMORY_TRAS_DEFAULT 13
> +#define MEMORY_TRAS_COUNT ((MEMORY_TRAS_MAX -
> MEMORY_TRAS_MIN)/MEMORY_TRAS_STEP) + 1
> +#define MEMORY_TRAS_TYPE  UINT8_TYPE
> +
> +//
> +// Uncore Multiplier Definitions
> +//
> +#define UCLK_RATIO_MIN     12
> +#define UCLK_RATIO_MAX     30
> +#define UCLK_RATIO_DEFAULT 20
> +
> +#endif // #ifndef _CONFIGURATION_H
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c
> new file mode 100644
> index 0000000000..ad667b0bd8
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c
> @@ -0,0 +1,89 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +  ExI.c
> +
> +Abstract:
> +
> +  ExI configuration based on setup option
> +
> +
> +--*/
> +
> +
> +#include "PlatformDxe.h"
> +
> +#define PchLpcPciCfg32(Register)  MmioRead32 (MmPciAddress (0,
> DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0,
> Register))
> +
> +//
> +// Procedure: GetPmcBase
> +//
> +// Description: This function read content of B:D:F 0:31:0, offset 44h (for
> +// PmcBase)
> +//
> +// Input: None
> +//
> +// Output:  32 bit PmcBase
> +//
> +UINT32
> +GetPmcBase (
> +  VOID
> +  )
> +{
> +  return (PchLpcPciCfg32 (R_PCH_LPC_PMC_BASE) &
> B_PCH_LPC_PMC_BASE_BAR);
> +}
> +
> +/**
> +  Configure ExI.
> +
> +  @param ImageHandle    Pointer to the loaded image protocol for this
> driver
> +  @param SystemTable    Pointer to the EFI System Table
> +
> +  @retval EFI_SUCCESS   The driver initializes correctly.
> +**/
> +VOID
> +InitExI (
> +  )
> +{
> +  EFI_STATUS                  Status;
> +
> +  SYSTEM_CONFIGURATION          SystemConfiguration;
> +  UINTN       VarSize;
> +
> +  VarSize = sizeof(SYSTEM_CONFIGURATION);
> +
> +  Status = gRT->GetVariable(
> +                  L"Setup",
> +                  &gEfiNormalSetupGuid,
> +                  NULL,
> +                  &VarSize,
> +                  &SystemConfiguration
> +                  );
> +
> +  if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
> +    //The setup variable is corrupted
> +    VarSize = sizeof(SYSTEM_CONFIGURATION);
> +    Status = gRT->GetVariable(
> +              L"SetupRecovery",
> +              &gEfiNormalSetupGuid,
> +              NULL,
> +              &VarSize,
> +              &SystemConfiguration
> +              );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +  if (SystemConfiguration.ExISupport == 1) {
> +	  MmioOr32 ((UINTN) (GetPmcBase() + R_PCH_PMC_MTPMC1),
> (UINT32) BIT0+BIT1+BIT2);
> +  } else if (SystemConfiguration.ExISupport == 0) {
> +    MmioAnd32 ((UINTN) (GetPmcBase() + R_PCH_PMC_MTPMC1),
> ~((UINT32) BIT0+BIT1+BIT2)); //clear bit 0,1,2
> +  }
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchPlatformPolicy.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchPlatformPolicy.c
> new file mode 100644
> index 0000000000..fc19635f99
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchPlatformPolicy.c
> @@ -0,0 +1,484 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +
> +Module Name:
> +
> +
> +  PchPlatformPolicy.c
> +
> +Abstract:
> +
> +
> +--*/
> +
> +#include "PlatformDxe.h"
> +#include <Protocol/PchPlatformPolicy.h>
> +#include <Protocol/VlvPlatformPolicy.h>
> +#include <Library/PchPlatformLib.h>
> +
> +#include "AzaliaVerbTable.h"
> +#include "Protocol/GlobalNvsArea.h"
> +#include "Protocol/DxePchPolicyUpdateProtocol.h"
> +
> +#define MOBILE_PLATFORM 1
> +#define DESKTOP_PLATFORM 2
> +
> +EFI_GUID                        gDxePchPolicyUpdateProtocolGuid =
> DXE_PCH_POLICY_UPDATE_PROTOCOL_GUID;
> +DXE_PCH_POLICY_UPDATE_PROTOCOL  mDxePchPolicyUpdate = { 0 };
> +
> +/**
> +
> +  Updates the feature policies according to the setup variable.
> +
> +  @retval VOID
> +
> +**/
> +VOID
> +InitPchPlatformPolicy (
> +  IN EFI_PLATFORM_INFO_HOB      *PlatformInfo
> +  )
> +{
> +  DXE_PCH_PLATFORM_POLICY_PROTOCOL *DxePlatformPchPolicy;
> +  EFI_STATUS                       Status;
> +  EFI_GLOBAL_NVS_AREA_PROTOCOL     *GlobalNvsArea;
> +  UINT8                            PortIndex;
> +  EFI_HANDLE                       Handle;
> +  PCH_STEPPING                     SocStepping = PchA0;
> +  BOOLEAN                          ModifyVariable;
> +
> +  ModifyVariable = FALSE;
> +  DEBUG ((EFI_D_INFO, "InitPchPlatformPolicy() - Start\n"));
> +
> +  Status  = gBS->LocateProtocol (&gDxePchPlatformPolicyProtocolGuid,
> NULL, (VOID **) &DxePlatformPchPolicy);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  //  Locate the Global NVS Protocol.
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiGlobalNvsAreaProtocolGuid,
> +                  NULL,
> +                  (VOID **) &GlobalNvsArea
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Update system information
> +  //
> +  DxePlatformPchPolicy->Revision  =
> DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_12;
> +
> +  //
> +  // General initialization
> +  //
> +  DxePlatformPchPolicy->BusNumber = 0;
> +
> +  //
> +  // VLV BIOS Spec Section 3.6 Flash Security Recommendation,
> +  // Intel strongly recommends that BIOS sets the BIOS Interface Lock Down
> bit. Enabling this bit
> +  // will mitigate malicious software attempts to replace the system BIOS
> option ROM with its own code.
> +  // We always enable this as a platform policy.
> +  //
> +  DxePlatformPchPolicy->LockDownConfig->BiosInterface =
> PCH_DEVICE_ENABLE;
> +  DxePlatformPchPolicy->LockDownConfig->BiosLock =
> mSystemConfiguration.SpiRwProtect;
> +
> +  //
> +  // DeviceEnables
> +  //
> +  DxePlatformPchPolicy->DeviceEnabling->Lan = mSystemConfiguration.Lan;
> +  DxePlatformPchPolicy->DeviceEnabling->Azalia        =
> mSystemConfiguration.PchAzalia;
> +  DxePlatformPchPolicy->DeviceEnabling->Sata          =
> mSystemConfiguration.Sata;
> +  DxePlatformPchPolicy->DeviceEnabling->Smbus         =
> PCH_DEVICE_ENABLE;
> +  DxePlatformPchPolicy->DeviceEnabling->LpeEnabled    =
> mSystemConfiguration.Lpe;
> +
> +  DxePlatformPchPolicy->UsbConfig->Ehci1Usbr          =
> PCH_DEVICE_DISABLE;
> +
> +  DxePlatformPchPolicy->UsbConfig->UsbXhciLpmSupport
> =mSystemConfiguration.UsbXhciLpmSupport;
> +
> +  //
> +  // Disable FFRD PR0 USB port2 for power saving since PR0 uses non-POR
> WWAN (but enable on PR0.3/PR0.5/PR1)
> +  //
> +  if ((PlatformInfo->BoardId == BOARD_ID_BL_FFRD) && (PlatformInfo-
> >BoardRev == PR0))
> +    if (mSystemConfiguration.PchUsbPort[2] !=0) {
> +      mSystemConfiguration.PchUsbPort[2]=0;
> +      ModifyVariable = TRUE;
> +    }
> +
> +
> +  if (ModifyVariable) {
> +    Status = gRT->SetVariable (
> +                    NORMAL_SETUP_NAME,
> +                    &gEfiNormalSetupGuid,
> +                    EFI_VARIABLE_NON_VOLATILE |
> EFI_VARIABLE_BOOTSERVICE_ACCESS,
> +                    sizeof(SYSTEM_CONFIGURATION),
> +                    &mSystemConfiguration
> +                    );
> +  }
> +
> +  SocStepping = PchStepping();
> +  if (mSystemConfiguration.UsbAutoMode == 1) {   // auto mode is enabled
> +    if (PchA0 == SocStepping) {
> +    	//
> +      //  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",
> SocStepping));
> +    } 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",
> SocStepping));
> +    }
> +    //
> +    //overwrite the setting
> +    //
> +    Status = gRT->SetVariable(
> +                    NORMAL_SETUP_NAME,
> +                    &gEfiNormalSetupGuid,
> +                    EFI_VARIABLE_NON_VOLATILE |
> EFI_VARIABLE_BOOTSERVICE_ACCESS,
> +                    sizeof(SYSTEM_CONFIGURATION),
> +                    &mSystemConfiguration
> +                    );
> +  }
> +
> +  //
> +  // USB Device 29 configuration
> +  //
> +  DxePlatformPchPolicy->UsbConfig->Usb20Settings[0].Enable =
> mSystemConfiguration.PchUsb20;
> +  DxePlatformPchPolicy->UsbConfig->UsbPerPortCtl           =
> mSystemConfiguration.PchUsbPerPortCtl;
> +  if (mSystemConfiguration.PchUsbPerPortCtl != PCH_DEVICE_DISABLE) {
> +    for (PortIndex = 0; PortIndex < PCH_USB_MAX_PHYSICAL_PORTS;
> PortIndex++) {
> +      DxePlatformPchPolicy->UsbConfig->PortSettings[PortIndex].Enable =
> mSystemConfiguration.PchUsbPort[PortIndex];
> +    }
> +  }
> +
> +  DxePlatformPchPolicy->UsbConfig->EhciDebug               =
> mSystemConfiguration.PchEhciDebug;
> +
> +  //
> +  // xHCI (USB 3.0) related settings from setup variable
> +  //
> +  DxePlatformPchPolicy->UsbConfig->Usb30Settings.XhciStreams    =
> mSystemConfiguration.PchUsb30Streams;
> +
> +  DxePlatformPchPolicy->UsbConfig->Usb30Settings.Mode           =
> mSystemConfiguration.PchUsb30Mode;
> +
> +  //
> +  // Remove XHCI Pre-Boot Driver setup option selection from end-user
> view and automate loading of USB 3.0 BIOS driver based on XhciMode
> selection
> +  //
> +  switch (mSystemConfiguration.PchUsb30Mode) {
> +    case 0: // Disabled
> +      DxePlatformPchPolicy->UsbConfig->Usb30Settings.PreBootSupport = 0;
> +      break;
> +    case 1: // Enabled
> +      DxePlatformPchPolicy->UsbConfig->Usb30Settings.PreBootSupport = 1;
> +      break;
> +    case 2: // Auto
> +      DxePlatformPchPolicy->UsbConfig->Usb30Settings.PreBootSupport = 0;
> +      break;
> +    case 3: // Smart Auto
> +      DxePlatformPchPolicy->UsbConfig->Usb30Settings.PreBootSupport = 1;
> +      break;
> +    default:
> +      DxePlatformPchPolicy->UsbConfig->Usb30Settings.PreBootSupport =
> mSystemConfiguration.UsbXhciSupport;
> +      break;
> +  }
> +
> +
> +
> +  DxePlatformPchPolicy->UsbConfig->UsbOtgSettings.Enable  =
> mSystemConfiguration.PchUsbOtg;
> +
> +  DxePlatformPchPolicy->UsbConfig->PortSettings[0].Dock   =
> PCH_DEVICE_DISABLE;
> +  DxePlatformPchPolicy->UsbConfig->PortSettings[1].Dock   =
> PCH_DEVICE_DISABLE;
> +  DxePlatformPchPolicy->UsbConfig->PortSettings[2].Dock   =
> PCH_DEVICE_DISABLE;
> +  DxePlatformPchPolicy->UsbConfig->PortSettings[3].Dock   =
> PCH_DEVICE_DISABLE;
> +
> +  DxePlatformPchPolicy->UsbConfig->PortSettings[0].Panel  =
> PCH_USB_FRONT_PANEL;
> +  DxePlatformPchPolicy->UsbConfig->PortSettings[1].Panel  =
> PCH_USB_FRONT_PANEL;
> +  DxePlatformPchPolicy->UsbConfig->PortSettings[2].Panel  =
> PCH_USB_BACK_PANEL;
> +  DxePlatformPchPolicy->UsbConfig->PortSettings[3].Panel  =
> PCH_USB_BACK_PANEL;
> +
> +  //
> +  //
> +  // Enable USB Topology control and program the topology setting for every
> USB port
> +  // See Platform Design Guide for description of topologies
> +  //
> +  //
> +  // Port 0: ~5.3", Port 1: ~4.9", Port 2: ~4.7", Port 3: ~8.0"
> +  //
> +  DxePlatformPchPolicy->UsbConfig->Usb20PortLength[0]  = 0x53;
> +  DxePlatformPchPolicy->UsbConfig->Usb20PortLength[1]  = 0x49;
> +  DxePlatformPchPolicy->UsbConfig->Usb20PortLength[2]  = 0x47;
> +  DxePlatformPchPolicy->UsbConfig->Usb20PortLength[3]  = 0x80;
> +
> +  DxePlatformPchPolicy->UsbConfig->Usb20OverCurrentPins[0]  =
> PchUsbOverCurrentPin0;
> +  DxePlatformPchPolicy->UsbConfig->Usb20OverCurrentPins[1]  =
> PchUsbOverCurrentPin0;
> +  DxePlatformPchPolicy->UsbConfig->Usb20OverCurrentPins[2]  =
> PchUsbOverCurrentPin1;
> +  DxePlatformPchPolicy->UsbConfig->Usb20OverCurrentPins[3]  =
> PchUsbOverCurrentPin1;
> +
> +  DxePlatformPchPolicy->UsbConfig->Usb30OverCurrentPins[0]  =
> PchUsbOverCurrentPinSkip;//PchUsbOverCurrentPin0;
> +
> +  DxePlatformPchPolicy->EhciPllCfgEnable =
> mSystemConfiguration.EhciPllCfgEnable;
> +  DEBUG ((EFI_D_INFO, "InitPchPlatformPolicy() DxePlatformPchPolicy-
> >EhciPllCfgEnable = 0x%x \n",DxePlatformPchPolicy->EhciPllCfgEnable));
> +    DxePlatformPchPolicy->PciExpressConfig->PcieDynamicGating
> = mSystemConfiguration.PcieDynamicGating;
> +  for (PortIndex = 0; PortIndex < PCH_PCIE_MAX_ROOT_PORTS;
> PortIndex++) {
> +    DxePlatformPchPolicy->PciExpressConfig->RootPort[PortIndex].Enable
> = mSystemConfiguration.IchPciExp[PortIndex];
> +    DxePlatformPchPolicy->PciExpressConfig-
> >RootPort[PortIndex].SlotImplemented               = PCH_DEVICE_ENABLE;
> +    DxePlatformPchPolicy->PciExpressConfig-
> >RootPort[PortIndex].FunctionNumber                = PortIndex;
> +    DxePlatformPchPolicy->PciExpressConfig-
> >RootPort[PortIndex].PhysicalSlotNumber            = PortIndex;
> +    DxePlatformPchPolicy->PciExpressConfig->RootPort[PortIndex].Aspm
> = 4;
> +    DxePlatformPchPolicy->PciExpressConfig->RootPort[PortIndex].PmSci
> = PCH_DEVICE_DISABLE;
> +    DxePlatformPchPolicy->PciExpressConfig->RootPort[PortIndex].ExtSync
> = PCH_DEVICE_DISABLE;
> +    DxePlatformPchPolicy->PciExpressConfig->RootPort[PortIndex].HotPlug
> = PCH_DEVICE_DISABLE;
> +    DxePlatformPchPolicy->PciExpressConfig-
> >RootPort[PortIndex].AdvancedErrorReporting        = PCH_DEVICE_DISABLE;
> +    DxePlatformPchPolicy->PciExpressConfig-
> >RootPort[PortIndex].UnsupportedRequestReport      =
> PCH_DEVICE_DISABLE;
> +    DxePlatformPchPolicy->PciExpressConfig-
> >RootPort[PortIndex].FatalErrorReport              = PCH_DEVICE_DISABLE;
> +    DxePlatformPchPolicy->PciExpressConfig-
> >RootPort[PortIndex].NoFatalErrorReport            = PCH_DEVICE_DISABLE;
> +    DxePlatformPchPolicy->PciExpressConfig-
> >RootPort[PortIndex].CorrectableErrorReport        = PCH_DEVICE_DISABLE;
> +    DxePlatformPchPolicy->PciExpressConfig-
> >RootPort[PortIndex].PmeInterrupt                  = 0;
> +    DxePlatformPchPolicy->PciExpressConfig-
> >RootPort[PortIndex].SystemErrorOnFatalError       = PCH_DEVICE_DISABLE;
> +    DxePlatformPchPolicy->PciExpressConfig-
> >RootPort[PortIndex].SystemErrorOnNonFatalError    =
> PCH_DEVICE_DISABLE;
> +    DxePlatformPchPolicy->PciExpressConfig-
> >RootPort[PortIndex].SystemErrorOnCorrectableError =
> PCH_DEVICE_DISABLE;
> +    DxePlatformPchPolicy->PciExpressConfig-
> >RootPort[PortIndex].CompletionTimeout             =
> PchPciECompletionTO_Default;
> +  }
> +
> +  //
> +  // SATA configuration
> +  //
> +  for (PortIndex = 0; PortIndex < PCH_AHCI_MAX_PORTS; PortIndex++) {
> +    if (mSystemConfiguration.SataType == 0) {
> +      DxePlatformPchPolicy->SataConfig->PortSettings[PortIndex].Enable   =
> PCH_DEVICE_ENABLE;
> +      DxePlatformPchPolicy->SataConfig->LegacyMode                       =
> PCH_DEVICE_ENABLE;
> +    } else {
> +      DxePlatformPchPolicy->SataConfig->PortSettings[PortIndex].Enable   =
> PCH_DEVICE_ENABLE;
> +      DxePlatformPchPolicy->SataConfig->LegacyMode                       =
> PCH_DEVICE_DISABLE;
> +    }
> +    if(mSystemConfiguration.Sata == 1){
> +      DxePlatformPchPolicy->SataConfig->PortSettings[PortIndex].Enable   =
> PCH_DEVICE_ENABLE;
> +    } else {
> +      DxePlatformPchPolicy->SataConfig->PortSettings[PortIndex].Enable   =
> PCH_DEVICE_DISABLE;
> +    }
> +    if(0 == PortIndex){
> +      DxePlatformPchPolicy->SataConfig->PortSettings[PortIndex].HotPlug    =
> PCH_DEVICE_DISABLE;
> +    } else if(1 == PortIndex){
> +      DxePlatformPchPolicy->SataConfig->PortSettings[PortIndex].HotPlug    =
> PCH_DEVICE_DISABLE;
> +    }
> +
> +    DxePlatformPchPolicy->SataConfig->PortSettings[PortIndex].SpinUp     =
> PCH_DEVICE_DISABLE;
> +    DxePlatformPchPolicy->SataConfig->PortSettings[PortIndex].MechSw
> = PCH_DEVICE_DISABLE;
> +  }
> +  DxePlatformPchPolicy->SataConfig->RaidAlternateId                 =
> PCH_DEVICE_DISABLE;
> +  DxePlatformPchPolicy->SataConfig->Raid0                           =
> PCH_DEVICE_ENABLE;
> +  DxePlatformPchPolicy->SataConfig->Raid1                           =
> PCH_DEVICE_ENABLE;
> +  DxePlatformPchPolicy->SataConfig->Raid10                          =
> PCH_DEVICE_ENABLE;
> +  DxePlatformPchPolicy->SataConfig->Raid5                           =
> PCH_DEVICE_ENABLE;
> +  DxePlatformPchPolicy->SataConfig->Irrt                            =
> PCH_DEVICE_ENABLE;
> +  DxePlatformPchPolicy->SataConfig->OromUiBanner                    =
> PCH_DEVICE_ENABLE;
> +  DxePlatformPchPolicy->SataConfig->HddUnlock                       =
> PCH_DEVICE_ENABLE;
> +  DxePlatformPchPolicy->SataConfig->LedLocate                       =
> PCH_DEVICE_ENABLE;
> +  DxePlatformPchPolicy->SataConfig->IrrtOnly                        =
> PCH_DEVICE_ENABLE;
> +  DxePlatformPchPolicy->SataConfig->SalpSupport                     =
> PCH_DEVICE_ENABLE;
> +  DxePlatformPchPolicy->SataConfig->TestMode                        =
> mSystemConfiguration.SataTestMode;
> +
> +  //
> +  // AzaliaConfig
> +  //
> +  DxePlatformPchPolicy->AzaliaConfig->Pme       =
> mSystemConfiguration.AzaliaPme;
> +  DxePlatformPchPolicy->AzaliaConfig->HdmiCodec =
> mSystemConfiguration.HdmiCodec;
> +  DxePlatformPchPolicy->AzaliaConfig->DS        =
> mSystemConfiguration.AzaliaDs;
> +  DxePlatformPchPolicy->AzaliaConfig->AzaliaVCi =
> mSystemConfiguration.AzaliaVCiEnable;
> +
> +  //
> +  // Set LPSS configuration according to setup value.
> +  //
> +  DxePlatformPchPolicy->LpssConfig->LpssPciModeEnabled   =
> mSystemConfiguration.LpssPciModeEnabled;
> +
> +  DxePlatformPchPolicy->LpssConfig->Dma1Enabled    =
> mSystemConfiguration.LpssDma1Enabled;
> +  DxePlatformPchPolicy->LpssConfig->I2C0Enabled    =
> mSystemConfiguration.LpssI2C0Enabled;
> +  DxePlatformPchPolicy->LpssConfig->I2C1Enabled    =
> mSystemConfiguration.LpssI2C1Enabled;
> +  DxePlatformPchPolicy->LpssConfig->I2C2Enabled    =
> mSystemConfiguration.LpssI2C2Enabled;
> +  DxePlatformPchPolicy->LpssConfig->I2C3Enabled    =
> mSystemConfiguration.LpssI2C3Enabled;
> +  DxePlatformPchPolicy->LpssConfig->I2C4Enabled    =
> mSystemConfiguration.LpssI2C4Enabled;
> +  DxePlatformPchPolicy->LpssConfig->I2C5Enabled    =
> mSystemConfiguration.LpssI2C5Enabled;
> +  DxePlatformPchPolicy->LpssConfig->I2C6Enabled    =
> mSystemConfiguration.LpssI2C6Enabled;
> +
> +  DxePlatformPchPolicy->LpssConfig->Dma0Enabled    =
> mSystemConfiguration.LpssDma0Enabled;;
> +  DxePlatformPchPolicy->LpssConfig->Pwm0Enabled    =
> mSystemConfiguration.LpssPwm0Enabled;
> +  DxePlatformPchPolicy->LpssConfig->Pwm1Enabled    =
> mSystemConfiguration.LpssPwm1Enabled;
> +  DxePlatformPchPolicy->LpssConfig->Hsuart0Enabled =
> mSystemConfiguration.LpssHsuart0Enabled;
> +  DxePlatformPchPolicy->LpssConfig->Hsuart1Enabled =
> mSystemConfiguration.LpssHsuart1Enabled;
> +  DxePlatformPchPolicy->LpssConfig->SpiEnabled     =
> mSystemConfiguration.LpssSpiEnabled;
> +
> +  //
> +  // Set SCC configuration according to setup value.
> +  //
> +  DxePlatformPchPolicy->SccConfig->SdioEnabled   =
> mSystemConfiguration.LpssSdioEnabled;
> +  DxePlatformPchPolicy->SccConfig->SdcardEnabled = TRUE;
> +  DxePlatformPchPolicy->SccConfig->SdCardSDR25Enabled =
> mSystemConfiguration.LpssSdCardSDR25Enabled;
> +  DxePlatformPchPolicy->SccConfig->SdCardDDR50Enabled =
> mSystemConfiguration.LpssSdCardDDR50Enabled;
> +  DxePlatformPchPolicy->SccConfig->HsiEnabled    =
> mSystemConfiguration.LpssMipiHsi;
> +
> +  if (mSystemConfiguration.eMMCBootMode== 1) {// Auto detection mode
> +  //
> +  // Silicon Stepping
> +  //
> +  switch (PchStepping()) {
> +    case PchA0: // A0 and A1
> +    case PchA1:
> +      DEBUG ((EFI_D_ERROR, "Auto Detect: SOC A0/A1: SCC eMMC 4.41
> Configuration\n"));
> +      DxePlatformPchPolicy->SccConfig->eMMCEnabled            = 1;
> +      DxePlatformPchPolicy->SccConfig->eMMC45Enabled          = 0;
> +      DxePlatformPchPolicy->SccConfig->eMMC45DDR50Enabled     = 0;
> +      DxePlatformPchPolicy->SccConfig->eMMC45HS200Enabled     = 0;
> +      DxePlatformPchPolicy->SccConfig->eMMC45RetuneTimerValue = 0;
> +      break;
> +    case PchB0: // B0 and later
> +    default:
> +      DEBUG ((EFI_D_ERROR, "Auto Detect: SOC B0 and later: SCC eMMC 4.5
> Configuration\n"));
> +      DxePlatformPchPolicy->SccConfig->eMMCEnabled            = 0;
> +      DxePlatformPchPolicy->SccConfig->eMMC45Enabled          =
> mSystemConfiguration.LpsseMMC45Enabled;
> +      DxePlatformPchPolicy->SccConfig->eMMC45DDR50Enabled     =
> mSystemConfiguration.LpsseMMC45DDR50Enabled;
> +      DxePlatformPchPolicy->SccConfig->eMMC45HS200Enabled     =
> mSystemConfiguration.LpsseMMC45HS200Enabled;
> +      DxePlatformPchPolicy->SccConfig->eMMC45RetuneTimerValue =
> mSystemConfiguration.LpsseMMC45RetuneTimerValue;
> +      break;
> +  }
> + } else if (mSystemConfiguration.eMMCBootMode == 2) { // eMMC 4.41
> +    DEBUG ((EFI_D_ERROR, "Force to SCC eMMC 4.41 Configuration\n"));
> +    DxePlatformPchPolicy->SccConfig->eMMCEnabled            = 1;
> +    DxePlatformPchPolicy->SccConfig->eMMC45Enabled          = 0;
> +    DxePlatformPchPolicy->SccConfig->eMMC45DDR50Enabled     = 0;
> +    DxePlatformPchPolicy->SccConfig->eMMC45HS200Enabled     = 0;
> +    DxePlatformPchPolicy->SccConfig->eMMC45RetuneTimerValue = 0;
> +
> + } else if (mSystemConfiguration.eMMCBootMode == 3) { // eMMC 4.5
> +      DEBUG ((EFI_D_ERROR, "Force to eMMC 4.5 Configuration\n"));
> +      DxePlatformPchPolicy->SccConfig->eMMCEnabled            = 0;
> +      DxePlatformPchPolicy->SccConfig->eMMC45Enabled          =
> mSystemConfiguration.LpsseMMC45Enabled;
> +      DxePlatformPchPolicy->SccConfig->eMMC45DDR50Enabled     =
> mSystemConfiguration.LpsseMMC45DDR50Enabled;
> +      DxePlatformPchPolicy->SccConfig->eMMC45HS200Enabled     =
> mSystemConfiguration.LpsseMMC45HS200Enabled;
> +      DxePlatformPchPolicy->SccConfig->eMMC45RetuneTimerValue =
> mSystemConfiguration.LpsseMMC45RetuneTimerValue;
> +
> + } else { // Disable eMMC controllers
> +      DEBUG ((EFI_D_ERROR, "Disable eMMC controllers\n"));
> +      DxePlatformPchPolicy->SccConfig->eMMCEnabled            = 0;
> +      DxePlatformPchPolicy->SccConfig->eMMC45Enabled          = 0;
> +      DxePlatformPchPolicy->SccConfig->eMMC45DDR50Enabled     = 0;
> +      DxePlatformPchPolicy->SccConfig->eMMC45HS200Enabled     = 0;
> +      DxePlatformPchPolicy->SccConfig->eMMC45RetuneTimerValue = 0;
> + }
> +
> +  //
> +  // Reserved SMBus Address
> +  //
> +  DxePlatformPchPolicy->SmbusConfig->NumRsvdSmbusAddresses  = 4;
> +  DxePlatformPchPolicy->SmbusConfig->RsvdSmbusAddressTable  =
> mSmbusRsvdAddresses;
> +
> +  //
> +  // MiscPm Configuration
> +  //
> +  DxePlatformPchPolicy->MiscPmConfig->WakeConfig.WolEnableOverride
> = mSystemConfiguration.WakeOnLanS5;
> +  DxePlatformPchPolicy->MiscPmConfig->SlpLanLowDc                         =
> mSystemConfiguration.SlpLanLowDc;
> +  DxePlatformPchPolicy->MiscPmConfig-
> >PowerResetStatusClear.MeWakeSts     = PCH_DEVICE_ENABLE;
> +  DxePlatformPchPolicy->MiscPmConfig-
> >PowerResetStatusClear.MeHrstColdSts = PCH_DEVICE_ENABLE;
> +  DxePlatformPchPolicy->MiscPmConfig-
> >PowerResetStatusClear.MeHrstWarmSts = PCH_DEVICE_ENABLE;
> +
> +  //
> +  // Enable / disable serial IRQ according to setup value.
> +  //
> +  DxePlatformPchPolicy->SerialIrqConfig->SirqEnable =
> PCH_DEVICE_ENABLE;
> +
> +  //
> +  // Set Serial IRQ Mode Select according to setup value.
> +  //
> +  DxePlatformPchPolicy->SerialIrqConfig->SirqMode = PchQuietMode;
> +
> +  //
> +  // Program the default Sub System Vendor Device Id
> +  //
> +  DxePlatformPchPolicy->DefaultSvidSid->SubSystemVendorId =
> V_PCH_INTEL_VENDOR_ID;
> +  DxePlatformPchPolicy->DefaultSvidSid->SubSystemId       =
> V_PCH_DEFAULT_SID;
> +
> +  mAzaliaVerbTable[9].VerbTableData = mAzaliaVerbTableData12;
> +
> +  DxePlatformPchPolicy->AzaliaConfig->AzaliaVerbTableNum  = sizeof
> (mAzaliaVerbTable) / sizeof (PCH_AZALIA_VERB_TABLE);
> +  DxePlatformPchPolicy->AzaliaConfig->AzaliaVerbTable     =
> mAzaliaVerbTable;
> +  DxePlatformPchPolicy->AzaliaConfig->ResetWaitTimer      = 300;
> +
> +  DxePlatformPchPolicy->IdleReserve = mSystemConfiguration.IdleReserve;
> +  DxePlatformPchPolicy->AcpiHWRed = PCH_DEVICE_DISABLE;
> +
> +  //
> +  // Install DxePchPolicyUpdateProtocol
> +  //
> +  Handle                        = NULL;
> +
> +  mDxePchPolicyUpdate.Revision  =
> DXE_PCH_POLICY_UPDATE_PROTOCOL_REVISION_1;
> +
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &Handle,
> +                  &gDxePchPolicyUpdateProtocolGuid,
> +                  &mDxePchPolicyUpdate,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  DEBUG ((EFI_D_INFO, "InitPchPlatformPolicy() - End\n"));
> +}
> +
> +
> +DXE_VLV_PLATFORM_POLICY_PROTOCOL mDxePlatformVlvPolicy;
> +
> +VOID
> +InitVlvPlatformPolicy (
> +  )
> +{
> +  DXE_VLV_PLATFORM_POLICY_PROTOCOL *DxePlatformVlvPolicy;
> +  EFI_STATUS                      Status;
> +  EFI_HANDLE                      Handle;
> +
> +  ZeroMem (&mDxePlatformVlvPolicy,
> sizeof(DXE_VLV_PLATFORM_POLICY_PROTOCOL));
> +
> +  DxePlatformVlvPolicy = &mDxePlatformVlvPolicy;
> +
> +
> +  DxePlatformVlvPolicy->GraphicReserve00 =
> mSystemConfiguration.GraphicReserve00;
> +  DxePlatformVlvPolicy->PavpMode = mSystemConfiguration.PavpMode;
> +  DxePlatformVlvPolicy->GraphicReserve01 = 1;
> +  DxePlatformVlvPolicy->GraphicReserve02 =
> mSystemConfiguration.GraphicReserve02;
> +  DxePlatformVlvPolicy->GraphicReserve03 = 1;
> +  DxePlatformVlvPolicy->GraphicReserve04 = 0;
> +  DxePlatformVlvPolicy->GraphicReserve05 =
> mSystemConfiguration.GraphicReserve05;
> +  DxePlatformVlvPolicy->IgdPanelFeatures.PFITStatus =
> mSystemConfiguration.PanelScaling;
> +
> +  DxePlatformVlvPolicy->IgdPanelFeatures.LidStatus = 1;
> +  DxePlatformVlvPolicy->IdleReserve = mSystemConfiguration.IdleReserve;
> +
> +  DxePlatformVlvPolicy->GraphicReserve06 = 1;
> +
> +  if ( (mSystemConfiguration.Lpe == 1) || mSystemConfiguration.Lpe == 2) {
> +    DxePlatformVlvPolicy ->AudioTypeSupport = LPE_AUDIO ;
> +  } else if ( mSystemConfiguration.PchAzalia == 1 ) {
> +    DxePlatformVlvPolicy ->AudioTypeSupport = HD_AUDIO;
> +  } else {
> +    DxePlatformVlvPolicy ->AudioTypeSupport = NO_AUDIO;
> +  }
> +
> +  Handle = NULL;
> +  Status = gBS->InstallProtocolInterface (
> +                  &Handle,
> +                  &gDxeVlvPlatformPolicyGuid,
> +                  EFI_NATIVE_INTERFACE,
> +                  DxePlatformVlvPolicy
> +                  );
> +  ASSERT_EFI_ERROR(Status);
> +
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchRegTable.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchRegTable.c
> new file mode 100644
> index 0000000000..cac61bffd0
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchRegTable.c
> @@ -0,0 +1,134 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +  IchRegTable.c
> +
> +Abstract:
> +
> +  Register initialization table for Ich.
> +
> +
> +
> +--*/
> +
> +#include <Library/EfiRegTableLib.h>
> +#include "PlatformDxe.h"
> +extern EFI_PLATFORM_INFO_HOB      mPlatformInfo;
> +
> +#define R_EFI_PCI_SVID 0x2C
> +
> +EFI_REG_TABLE mSubsystemIdRegs [] = {
> +
> +  //
> +  // Program SVID and SID for PCI devices.
> +  // Combine two 16 bit PCI_WRITE into one 32 bit PCI_WRITE in order to
> boost performance
> +  //
> +  PCI_WRITE (
> +      MC_BUS, MC_DEV, MC_FUN, R_EFI_PCI_SVID, EfiPciWidthUint32,
> +      V_PCH_DEFAULT_SVID_SID, OPCODE_FLAG_S3SAVE
> +    ),
> +
> +  PCI_WRITE (
> +      IGD_BUS, IGD_DEV, IGD_FUN_0, R_EFI_PCI_SVID, EfiPciWidthUint32,
> +      V_PCH_DEFAULT_SVID_SID, OPCODE_FLAG_S3SAVE
> +    ),
> +
> +  PCI_WRITE(
> +      DEFAULT_PCI_BUS_NUMBER_PCH, 0, 0, R_EFI_PCI_SVID,
> EfiPciWidthUint32,
> +      V_PCH_DEFAULT_SVID_SID, OPCODE_FLAG_S3SAVE
> +    ),
> +  PCI_WRITE (
> +      DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC,
> PCI_FUNCTION_NUMBER_PCH_LPC, R_PCH_LPC_SS, EfiPciWidthUint32,
> +      V_PCH_DEFAULT_SVID_SID, OPCODE_FLAG_S3SAVE
> +    ),
> +  PCI_WRITE (
> +      DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SATA,
> PCI_FUNCTION_NUMBER_PCH_SATA, R_PCH_SATA_SS, EfiPciWidthUint32,
> +      V_PCH_DEFAULT_SVID_SID, OPCODE_FLAG_S3SAVE
> +    ),
> +  PCI_WRITE (
> +      DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SMBUS,
> PCI_FUNCTION_NUMBER_PCH_SMBUS, R_PCH_SMBUS_SVID,
> EfiPciWidthUint32,
> +      V_PCH_DEFAULT_SVID_SID, OPCODE_FLAG_S3SAVE
> +    ),
> +  PCI_WRITE (
> +      DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_USB,
> PCI_FUNCTION_NUMBER_PCH_EHCI, R_PCH_EHCI_SVID, EfiPciWidthUint32,
> +      V_PCH_DEFAULT_SVID_SID, OPCODE_FLAG_S3SAVE
> +    ),
> +  PCI_WRITE (
> +      DEFAULT_PCI_BUS_NUMBER_PCH,
> PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1, R_PCH_PCIE_SVID,
> EfiPciWidthUint32,
> +      V_PCH_DEFAULT_SVID_SID, OPCODE_FLAG_S3SAVE
> +    ),
> +  PCI_WRITE (
> +      DEFAULT_PCI_BUS_NUMBER_PCH,
> PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2, R_PCH_PCIE_SVID,
> EfiPciWidthUint32,
> +      V_PCH_DEFAULT_SVID_SID, OPCODE_FLAG_S3SAVE
> +    ),
> +  PCI_WRITE (
> +      DEFAULT_PCI_BUS_NUMBER_PCH,
> PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3, R_PCH_PCIE_SVID,
> EfiPciWidthUint32,
> +      V_PCH_DEFAULT_SVID_SID, OPCODE_FLAG_S3SAVE
> +    ),
> +  PCI_WRITE (
> +      DEFAULT_PCI_BUS_NUMBER_PCH,
> PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4, R_PCH_PCIE_SVID,
> EfiPciWidthUint32,
> +      V_PCH_DEFAULT_SVID_SID, OPCODE_FLAG_S3SAVE
> +    ),
> +  TERMINATE_TABLE
> +};
> +
> +/**
> +  Updates the mSubsystemIdRegs table, and processes it.  This should
> program
> +  the Subsystem Vendor and Device IDs.
> +
> +  @retval Returns  VOID
> +
> +**/
> +VOID
> +InitializeSubsystemIds (
> +  )
> +{
> +
> +  EFI_REG_TABLE *RegTablePtr;
> +  UINT32 SubsystemVidDid;
> +
> +  SubsystemVidDid = mPlatformInfo.SsidSvid;
> +
> +  RegTablePtr = mSubsystemIdRegs;
> +
> +  //
> +  // While we are not at the end of the table
> +  //
> +  while (RegTablePtr->Generic.OpCode != OP_TERMINATE_TABLE) {
> +  	//
> +    // If the data to write is the original SSID
> +    //
> +    if (RegTablePtr->PciWrite.Data ==
> +          ((V_PCH_DEFAULT_SID << 16) |
> +           V_PCH_INTEL_VENDOR_ID)
> +       ) {
> +
> +    	//
> +      // Then overwrite it to use the alternate SSID
> +      //
> +      RegTablePtr->PciWrite.Data = SubsystemVidDid;
> +    }
> +
> +    //
> +    // Go to next table entry
> +    //
> +    RegTablePtr++;
> +    }
> +
> +  RegTablePtr = mSubsystemIdRegs;
> +
> +
> +  //
> +  // Program the SSVID/SSDID
> +  //
> +  ProcessRegTablePci (mSubsystemIdRegs, mPciRootBridgeIo, NULL);
> +
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchTcoReset.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchTcoReset.c
> new file mode 100644
> index 0000000000..5b7822deda
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchTcoReset.c
> @@ -0,0 +1,211 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +  IchTcoReset.c
> +
> +Abstract:
> +  Implements the programming of events in TCO Reset
> +
> +
> +--*/
> +
> +#include "PlatformDxe.h"
> +#include <Protocol/TcoReset.h>
> +#include <Protocol/HwWatchdogTimer.h>
> +
> +
> +EFI_STATUS
> +EFIAPI
> +EnableTcoReset (
> +  IN      UINT32            *RcrbGcsSaveValue
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DisableTcoReset (
> +  OUT     UINT32    RcrbGcsRestoreValue
> +  );
> +
> +EFI_TCO_RESET_PROTOCOL  mTcoResetProtocol = {
> +  EnableTcoReset,
> +  DisableTcoReset
> +};
> +
> +/**
> +
> +  Enables the TCO timer to reset the system in case of a system hang.  This is
> +  used when writing the clock registers.
> +
> +  @param RcrbGcsSaveValue   This is the value of the RCRB GCS register
> before it is
> +                            changed by this procedure.  This will be used to restore
> +                            the settings of this register in PpiDisableTcoReset.
> +
> +  @retval  EFI_STATUS
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +EnableTcoReset (
> +  IN      UINT32            *RcrbGcsSaveValue
> +  )
> +{
> +  UINT16          TmpWord;
> +  UINT16          AcpiBase;
> +  EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL  *WatchdogTimerProtocol;
> +  EFI_STATUS          Status;
> +  UINTN           PbtnDisableInterval = 4;  //Default value
> +
> +  //
> +  // Get Watchdog Timer protocol.
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiWatchdogTimerDriverProtocolGuid,
> +                  NULL,
> +                  (VOID **)&WatchdogTimerProtocol
> +                  );
> +
> +  //
> +  // If the protocol is present, shut off the Timer as we enter BDS
> +  //
> +  if (!EFI_ERROR(Status)) {
> +    WatchdogTimerProtocol->RestartWatchdogTimer();
> +    WatchdogTimerProtocol->AllowKnownReset(TRUE);
> +  }
> +
> +  if (*RcrbGcsSaveValue == 0) {
> +    PbtnDisableInterval = PcdGet32(PcdPBTNDisableInterval);
> +  } else {
> +    PbtnDisableInterval = *RcrbGcsSaveValue * 10 / 6;
> +  }
> +
> +  //
> +  // Read ACPI Base Address
> +  //
> +  AcpiBase = PchLpcPciCfg16(R_PCH_LPC_ACPI_BASE) &
> B_PCH_LPC_ACPI_BASE_BAR;
> +
> +  //
> +  // Stop TCO if not already stopped
> +  //
> +  TmpWord = IoRead16(AcpiBase + R_PCH_TCO_CNT);
> +  TmpWord |= B_PCH_TCO_CNT_TMR_HLT;
> +  IoWrite16(AcpiBase + R_PCH_TCO_CNT, TmpWord);
> +
> +  //
> +  // Clear second TCO status
> +  //
> +  IoWrite32(AcpiBase + R_PCH_TCO_STS, B_PCH_TCO_STS_SECOND_TO);
> +
> +  //
> +  // Enable reboot on TCO timeout
> +  //
> +  *RcrbGcsSaveValue = MmioRead32 (PMC_BASE_ADDRESS +
> R_PCH_PMC_PM_CFG);
> +  MmioAnd8 (PMC_BASE_ADDRESS + R_PCH_PMC_PM_CFG, (UINT8)
> ~B_PCH_PMC_PM_CFG_NO_REBOOT);
> +
> +  //
> +  // Set TCO reload value (interval *.6s)
> +  //
> +  IoWrite32(AcpiBase + R_PCH_TCO_TMR,
> (UINT32)(PbtnDisableInterval<<16));
> +
> +  //
> +  // Force TCO to load new value
> +  //
> +  IoWrite8(AcpiBase + R_PCH_TCO_RLD, 4);
> +
> +  //
> +  // Clear second TCO status
> +  //
> +  IoWrite32(AcpiBase + R_PCH_TCO_STS, B_PCH_TCO_STS_SECOND_TO);
> +
> +  //
> +  // Start TCO timer running
> +  //
> +  TmpWord = IoRead16(AcpiBase + R_PCH_TCO_CNT);
> +  TmpWord &= ~(B_PCH_TCO_CNT_TMR_HLT);
> +  IoWrite16(AcpiBase + R_PCH_TCO_CNT, TmpWord);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Disables the TCO timer.  This is used after writing the clock registers.
> +
> +  @param RcrbGcsRestoreValue   Value saved in PpiEnableTcoReset so that
> it can
> +                               restored.
> +
> +  @retval EFI_STATUS
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DisableTcoReset (
> +  OUT     UINT32    RcrbGcsRestoreValue
> +  )
> +{
> +  UINT16          TmpWord;
> +  UINT16          AcpiBase;
> +  EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL  *WatchdogTimerProtocol;
> +  EFI_STATUS          Status;
> +
> +  //
> +  // Read ACPI Base Address
> +  //
> +  AcpiBase = PchLpcPciCfg16(R_PCH_LPC_ACPI_BASE) &
> B_PCH_LPC_ACPI_BASE_BAR;
> +
> +  //
> +  // Stop the TCO timer
> +  //
> +  TmpWord = IoRead16(AcpiBase + R_PCH_TCO_CNT);
> +  TmpWord |= B_PCH_TCO_CNT_TMR_HLT;
> +  IoWrite16(AcpiBase + R_PCH_TCO_CNT, TmpWord);
> +
> +  //
> +  // Get Watchdog Timer protocol.
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiWatchdogTimerDriverProtocolGuid,
> +                  NULL,
> +                  (VOID **)&WatchdogTimerProtocol
> +                  );
> +
> +  //
> +  // If the protocol is present, shut off the Timer as we enter BDS
> +  //
> +  if (!EFI_ERROR(Status)) {
> +    WatchdogTimerProtocol->AllowKnownReset(FALSE);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +  Updates the feature policies according to the setup variable.
> +
> +  @retval Returns   VOID
> +
> +**/
> +VOID
> +InitTcoReset (
> +  )
> +{
> +  EFI_HANDLE                        Handle;
> +  EFI_STATUS                        Status;
> +
> +  Handle = NULL;
> +  Status = gBS->InstallProtocolInterface (
> +                  &Handle,
> +                  &gEfiTcoResetProtocolGuid,
> +                  EFI_NATIVE_INTERFACE,
> +                  &mTcoResetProtocol
> +                  );
> +  ASSERT_EFI_ERROR(Status);
> +
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c
> new file mode 100644
> index 0000000000..3b3e4b4c82
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c
> @@ -0,0 +1,72 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +  IdccInfo.c
> +
> +Abstract:
> +
> +  Platform information used by IDCC.
> +
> +Revision History
> +
> +--*/
> +
> +#include "PlatformDxe.h"
> +
> +#include <Guid/IdccData.h>
> +
> +extern EFI_GUID mPlatformDriverGuid;
> +
> +
> +EFI_STATUS
> +WriteIdccInfo (
> +  )
> +{
> +  EFI_STATUS                Status;
> +  EFI_DATA_HUB_PROTOCOL     *DataHub;
> +  UINT8                     Ratio;
> +  EFI_IDCC_PROCESSOR_RATIO  ProcRatio;
> +
> +  //
> +  // Locate the data hub protocol
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiDataHubProtocolGuid,
> +                  NULL,
> +                  (VOID **) &DataHub
> +                  );
> +
> +  //
> +  // Find processor actual ratio
> +  //
> +  Ratio = 15; //Temporary - some dummy value.
> +
> +  //
> +  // Fill in IDCC Type 5 structure
> +  //
> +  ProcRatio.IdccHeader.Type = EFI_IDCC_PROC_RATIO_TYPE;
> +  ProcRatio.IdccHeader.RecordLength =
> sizeof(EFI_IDCC_PROCESSOR_RATIO);
> +  ProcRatio.ProcessorRatio = Ratio;
> +
> +  //
> +  // Write data to the data hub
> +  //
> +  Status = DataHub->LogData (
> +                      DataHub,
> +                      &gIdccDataHubGuid,
> +                      &mPlatformDriverGuid,
> +                      EFI_DATA_RECORD_CLASS_DATA,
> +                      &ProcRatio,
> +                      sizeof(EFI_IDCC_PROCESSOR_RATIO)
> +                      );
> +
> +  return Status;
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.c
> new file mode 100644
> index 0000000000..09e7fe3113
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.c
> @@ -0,0 +1,161 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> + LegacySpeaker.c
> +
> +Abstract:
> +
> +  This file implements DXE for Legacy Speaker.
> +
> +--*/
> +
> +#include "LegacySpeaker.h"
> +
> +/**
> +
> +  This function will enable the speaker to generate beep
> +
> +  @retval EFI_STATUS
> +
> +**/
> +EFI_STATUS
> +TurnOnSpeaker (
> +  )
> +{
> +  UINT8                   Data;
> +  Data = IoRead8 (EFI_SPEAKER_CONTROL_PORT);
> +  Data |= 0x03;
> +  IoWrite8(EFI_SPEAKER_CONTROL_PORT, Data);
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +  This function will stop beep from speaker.
> +
> +  @retval Status
> +
> +**/
> +EFI_STATUS
> +TurnOffSpeaker (
> +  )
> +{
> +  UINT8                   Data;
> +
> +  Data = IoRead8 (EFI_SPEAKER_CONTROL_PORT);
> +  Data &= 0xFC;
> +  IoWrite8(EFI_SPEAKER_CONTROL_PORT, Data);
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Generate beep sound based upon number of beeps and duration of the
> beep
> +
> +  @param NumberOfBeeps     Number of beeps which user want to produce
> +  @param BeepDuration      Duration for speaker gate need to be enabled
> +  @param TimeInterval      Interval between each beep
> +
> +  @retval      Does not return if the reset takes place.
> +               EFI_INVALID_PARAMETER   If ResetType is invalid.
> +
> +**/
> +EFI_STATUS
> +OutputBeep (
> +  IN     UINTN                              NumberOfBeep,
> +  IN     UINTN                              BeepDuration,
> +  IN     UINTN                              TimeInterval
> +  )
> +{
> +  UINTN           Num;
> +
> +  for (Num=0; Num < NumberOfBeep; Num++) {
> +    TurnOnSpeaker ();
> +    //
> +    // wait some time,at least 120us
> +    //
> +    gBS->Stall (BeepDuration);
> +    TurnOffSpeaker();
> +    gBS->Stall (TimeInterval);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function will program the speaker tone frequency. The value should
> be with 64k
> +  boundary since it takes only 16 bit value which gets programmed in two
> step IO opearattion
> +
> +  @param  Frequency     A value which should be 16 bit only.
> +
> +  @retval EFI_SUCESS
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +ProgramToneFrequency (
> +  IN EFI_SPEAKER_IF_PROTOCOL            * This,
> +  IN  UINT16                            Frequency
> +  )
> +{
> +  UINT8                   Data;
> +
> +  Data = 0xB6;
> +  IoWrite8(EFI_TIMER_CONTROL_PORT, Data);
> +
> +  Data = (UINT8)(Frequency & 0x00FF);
> +  IoWrite8(EFI_TIMER_2_PORT, Data);
> +  Data = (UINT8)((Frequency & 0xFF00) >> 8);
> +  IoWrite8(EFI_TIMER_2_PORT, Data);
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function will generate the beep for specified duration.
> +
> +  @param NumberOfBeeps     Number of beeps which user want to produce
> +  @param BeepDuration      Duration for speaker gate need to be enabled
> +  @param TimeInterval      Interval between each beep
> +
> +  @retval EFI_STATUS
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GenerateBeepTone (
> +  IN EFI_SPEAKER_IF_PROTOCOL            * This,
> +  IN  UINTN                             NumberOfBeeps,
> +  IN  UINTN                             BeepDuration,
> +  IN  UINTN                             TimeInterval
> +  )
> +{
> +
> +  if ((NumberOfBeeps == 1) && (BeepDuration == 0) && (TimeInterval == 0))
> {
> +    TurnOnSpeaker ();
> +    return EFI_SUCCESS;
> +  }
> +
> +  if ((NumberOfBeeps == 0) && (BeepDuration == 0) && (TimeInterval == 0))
> {
> +    TurnOffSpeaker ();
> +    return EFI_SUCCESS;
> +  }
> +
> +  if (BeepDuration == 0) {
> +    BeepDuration = EFI_DEFAULT_SHORT_BEEP_DURATION;
> +  }
> +
> +  if (TimeInterval == 0) {
> +    TimeInterval = EFI_DEFAULT_BEEP_TIME_INTERVAL;
> +  }
> +
> +  OutputBeep (NumberOfBeeps, BeepDuration, TimeInterval);
> +  return EFI_SUCCESS;
> +
> +
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.h
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.h
> new file mode 100644
> index 0000000000..0ab39b78fa
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.h
> @@ -0,0 +1,69 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> + LegacySpeaker.h
> +
> +Abstract:
> +
> +  Speaker enabling related data
> +
> +--*/
> +
> +#ifndef _DXE_LEGACY_SPEAKER_H
> +#define _DXE_LEGACY_SPEAKER_H
> +
> +#include "PlatformDxe.h"
> +
> +//
> +// Speaker Related Port Information
> +//
> +#define EFI_TIMER_COUNTER_PORT            0x40
> +#define EFI_TIMER_CONTROL_PORT            0x43
> +#define EFI_TIMER_2_PORT                  0x42
> +#define EFI_SPEAKER_CONTROL_PORT          0x61
> +
> +#define EFI_SPEAKER_OFF_MASK              0xFC
> +
> +#define EFI_DEFAULT_BEEP_FREQUENCY        0x500
> +
> +//
> +// Default Intervals/Beep Duration
> +//
> +#define EFI_DEFAULT_LONG_BEEP_DURATION    0x70000
> +#define EFI_DEFAULT_SHORT_BEEP_DURATION   0x50000
> +#define EFI_DEFAULT_BEEP_TIME_INTERVAL    0x20000
> +
> +
> +EFI_STATUS
> +EFIAPI
> +ProgramToneFrequency (
> +  IN  EFI_SPEAKER_IF_PROTOCOL           * This,
> +  IN  UINT16                            Frequency
> +  );
> +
> +
> +EFI_STATUS
> +EFIAPI
> +GenerateBeepTone (
> +  IN  EFI_SPEAKER_IF_PROTOCOL           * This,
> +  IN  UINTN                             NumberOfBeeps,
> +  IN  UINTN                             BeepDuration,
> +  IN  UINTN                             TimeInterval
> +  );
> +
> +EFI_STATUS
> +TurnOnSpeaker (
> +  );
> +
> +EFI_STATUS
> +TurnOffSpeaker (
> +  );
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.c
> new file mode 100644
> index 0000000000..af466ce96d
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.c
> @@ -0,0 +1,582 @@
> +/*++
> +  This file contains 'Framework Code' and is licensed as such
> +  under the terms of your license agreement with Intel or your
> +  vendor.  This file may not be modified, except as allowed by
> +  additional terms of your license agreement.
> +--*/
> +/*++
> +
> +Copyright (c)  2010  - 2014, Intel Corporation. All rights reserved
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  Observable.c
> +
> +Abstract:
> +
> +  The following contains all of the implementation for the Observable
> protocol. The
> +  protocol uses the observer design pattern to provide a way to publish
> events and
> +  to subscribe to those events so that a callback will be performed at the
> time of
> +  the event. The observables and subscribers are maintained by the static
> tree,
> +  mObservableDb. The difference between this protocol and the existing
> event protocol
> +  that exists within the EFI framework is that this protocol allows for
> parameters
> +  to be passed to the subscribed callbacks that can contain up to date
> context.
> +
> +--*/
> +
> +#include "Observable.h"
> +
> +static OBS_TREE*                mObservableDb = NULL;
> +static EFI_HANDLE               mObservableHandle = NULL;
> +static OBS_OBSERVABLE_PROTOCOL  mObservable = {
> +  AddObservable,
> +  RemoveObservable,
> +  Subscribe,
> +  Unsubscribe,
> +  Publish,
> +  RemoveAllObservables
> +};
> +
> +/** Install observable protocol.
> + *
> + * Install interface and initialize the observable protocol.
> + *
> + * @param   VOID          No parameters.
> + *
> + * @return  EFI_SUCCESS   Successfully installed and initialized the protocol.
> + **/
> +EFI_STATUS
> +InitializeObservableProtocol(
> +  VOID
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  //
> +  // Install protocol.
> +  //
> +  Status = gBS->InstallProtocolInterface (
> +                  &mObservableHandle,
> +                  &gObservableProtocolGuid,
> +                  EFI_NATIVE_INTERFACE,
> +                  &mObservable
> +                  );
> +
> +  return Status;
> +}
> +
> +/** Deletes a subscriber
> + *
> + * This function removes the subscriber pointed to by Head.
> + *
> + * @param   OBS_TREE*     Head    Points to the current subscriber.
> + *
> + * @return  OBS_TREE*     Returns the tree after successfully removing the
> subscriber.
> + **/
> +OBS_LEAF*
> +DeleteSubscriber(
> +  OBS_LEAF* Head
> +  )
> +{
> +  OBS_LEAF* Temp;
> +
> +  if (Head) {
> +    Temp = Head;
> +    Head = Head->Next;
> +    gBS->FreePool(Temp);
> +  }
> +
> +  return Head;
> +}
> +
> +/** Finds and deletes all subscribers
> + *
> + * This function iterates recursively through the existing subscribers and
> delets them all.
> + *
> + * @param   OBS_TREE*     Head    Points to the current subscriber.
> + *
> + * @return  OBS_TREE*     Returns the tree after successfully removing the
> subscribers.
> + **/
> +OBS_LEAF*
> +DeleteAllSubscribers(
> +  OBS_LEAF* Head
> +  )
> +{
> +  if (Head) {
> +    if (Head->Next) {
> +      //
> +      // We aren't at the end of the list yet.
> +      //
> +      Head->Next = DeleteAllSubscribers(Head->Next);
> +    }
> +
> +    //
> +    // At the end, so delete the subscriber.
> +    //
> +    Head = DeleteSubscriber(Head);
> +  }
> +
> +  return Head;
> +}
> +
> +/** Deletes an observable
> + *
> + * This function removes the observable pointed to by Head.
> + *
> + * @param   OBS_TREE*     Head    Points to the current observable.
> + *
> + * @return  OBS_TREE*     Returns the tree after successfully removing the
> observable.
> + **/
> +OBS_TREE*
> +DeleteObservable(
> +  OBS_TREE* Head
> +  )
> +{
> +  OBS_TREE* Temp;
> +
> +  if (Head) {
> +    Temp = Head;
> +    Head = Head->Next;
> +    gBS->FreePool(Temp);
> +  }
> +
> +  return Head;
> +}
> +
> +/** Finds and deletes all observables
> + *
> + * This function iterates recursively through the existing observables
> database and, starting with
> + * the last most observable, deletes all of its subscribers, then deletes the
> observable itself.
> + *
> + * @param   OBS_TREE*     Head    Points to the current observable.
> + *
> + * @return  OBS_TREE*     Returns the tree after successfully removing the
> observables.
> + **/
> +OBS_TREE*
> +DeleteAllObservables(
> +  OBS_TREE* Head
> +  )
> +{
> +  if (Head) {
> +    if (Head->Next) {
> +      //
> +      // We aren't at the end of the list yet.
> +      //
> +      Head->Next = DeleteAllObservables(Head->Next);
> +    }
> +
> +    //
> +    // This is the end of the list of observables.
> +    //
> +    Head->Leaf = DeleteAllSubscribers(Head->Leaf);
> +
> +    //
> +    // Subscribers are deleted, so now delete the observable.
> +    //
> +    Head = DeleteObservable(Head);
> +  }
> +
> +  return Head;
> +}
> +
> +/** Finds and deletes observable
> + *
> + * This function iterates recursively through the existing observable
> database in order to find the one
> + * specified by ReferenceGuid so that it can be deleted. If the requested
> observable is found, before it
> + * is deleted, all of the subscribers that are listening to this observable are
> deleted.
> + *
> + * @param   OBS_TREE*     Head              Points to the current observable.
> + *          EFI_GUID      ReferenceGuid     Corresponds to the observable that
> we're looking for.
> + *
> + * @return  OBS_TREE*     Returns the tree after successfully removing (or
> not finding) the observable.
> + **/
> +OBS_TREE*
> +FindAndDeleteObservable(
> +  OBS_TREE* Head,
> +  EFI_GUID  ReferenceGuid
> +  )
> +{
> +  if (Head) {
> +    if (CompareMem(&(Head->ObservableGuid), &ReferenceGuid,
> sizeof(ReferenceGuid)) == 0) {
> +      //
> +      // We found the observable. Delete all of it's subscribers, first.
> +      //
> +      Head->Leaf = DeleteAllSubscribers(Head->Leaf);
> +      //
> +      // Now we can safely remove the observable.
> +      //
> +      Head = DeleteObservable(Head);
> +    } else {
> +      //
> +      // Not found. Keep searching.
> +      //
> +      Head->Next = FindAndDeleteObservable(Head->Next, ReferenceGuid);
> +    }
> +  }
> +
> +  return Head;
> +}
> +
> +/** Finds and deletes subscriber
> + *
> + * This function iterates recursively through the existing subscribers that are
> listening to the
> + * observable that was found when this function was called.
> + *
> + * @param   OBS_TREE*     Head              Points to the current subscriber.
> + *          OBS_CALLBACK  CallbackInterface This is the subscriber that is
> requested be removed.
> + *
> + * @return  OBS_TREE*     Returns the tree after successfully removing (or
> not finding) the subscriber.
> + **/
> +OBS_LEAF*
> +_FindAndDeleteSubscriber(
> +  OBS_LEAF*     Head,
> +  OBS_CALLBACK  CallbackInterface
> +  )
> +{
> +  if (Head) {
> +    if (Head->Observer == CallbackInterface) {
> +      //
> +      // Found it. Now let's delete it.
> +      //
> +      Head = DeleteSubscriber(Head);
> +    } else {
> +      //
> +      // Not found. Keep searching.
> +      //
> +      Head->Next = _FindAndDeleteSubscriber(Head->Next,
> CallbackInterface);
> +    }
> +  }
> +
> +  return Head;
> +}
> +
> +/** Finds and deletes subscriber
> + *
> + * This function iterates recursively through the existing observables
> database until it either finds
> + * a matching guid or reaches the end of the list. After finding a match, it
> calls a helper function,
> + * _FindAndDeleteSubscriber. At this point, all responsibility for finding and
> deleting the subscriber
> + * lies on the helper function.
> + *
> + * @param   OBS_TREE*     Head              Points to the current observable.
> + *          EFI_GUID      ReferenceGuid     Corresponds to the observable that
> we're looking for.
> + *          OBS_CALLBACK  CallbackInterface This is the subscriber that is
> requested be removed.
> + *
> + * @return  OBS_TREE*     Returns the tree after successfully removing (or
> not finding) the subscriber.
> + **/
> +OBS_TREE*
> +FindAndDeleteSubscriber(
> +  IN  OUT OBS_TREE*     Head,
> +  IN      EFI_GUID      ReferenceGuid,
> +  IN      OBS_CALLBACK  CallbackInterface
> +  )
> +{
> +  if (Head) {
> +    if (CompareMem(&(Head->ObservableGuid), &ReferenceGuid,
> sizeof(ReferenceGuid)) == 0) {
> +      //
> +      // We found the observer that matches ReferenceGuid. Find and delete
> the subscriber that is
> +      // listening to it.
> +      //
> +      Head->Leaf = _FindAndDeleteSubscriber(Head->Leaf, CallbackInterface);
> +    } else {
> +      //
> +      // Not found. Keep searching.
> +      //
> +      Head->Next = FindAndDeleteSubscriber(Head->Next, ReferenceGuid,
> CallbackInterface);
> +    }
> +  }
> +
> +  return Head;
> +}
> +
> +/** Remove all observables.
> + *
> + * Remove all observable guids and all interfaces subscribed to them.
> + *
> + * @param   VOID          No parameters.
> + *
> + * @return  EFI_SUCCESS   Successfully removed all observables and
> subscribed interfaces.
> + **/
> +EFI_STATUS
> +EFIAPI
> +RemoveAllObservables(
> +  VOID
> +  )
> +{
> +  mObservableDb = DeleteAllObservables(mObservableDb);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/** Subscribe an interface with an observable guid.
> + *
> + * Use this to register a callback function with a guid. The function provided
> by CallbackInterface will be executed
> + * whenever the appropriate observable instance specified by
> ReferenceGuid calls Publish.
> + *
> + * @param   EFI_GUID              ReferenceGuid       The observable guid that
> the callback interface will subscribe to.
> + *          OBS_CASLLBACK         CallbackInterface   A pointer to the function
> that is subscribing to the observable.
> + *
> + * @return  EFI_SUCCESS           Successfully subscribed the interface to the
> observable guid.
> + *          EFI_NOT_FOUND         No match could be found between the
> provided guid and existing observables.
> + *          EFI_OUT_OF_RESOURCES  Could not subscribe to this observer due
> to resource limitations.
> + *          EFI_INVALID_PARAMETER Interface is already subscribed to this
> observer.
> + **/
> +EFI_STATUS
> +EFIAPI
> +Subscribe (
> +  IN      EFI_GUID        ReferenceGuid,
> +  IN      OBS_CALLBACK    CallbackInterface
> +  )
> +{
> +  EFI_STATUS  Status    = EFI_SUCCESS;
> +  OBS_TREE*   TempTree  = NULL;
> +  OBS_LEAF*   Last      = NULL;
> +  OBS_LEAF*   TempLeaf  = NULL;
> +  OBS_LEAF*   NewLeaf   = NULL;
> +  BOOLEAN     Found     = FALSE;
> +
> +  if (mObservableDb != NULL) {
> +    //
> +    // Find the observable guid that we're looking for.
> +    //
> +    for (TempTree = mObservableDb; TempTree != NULL; TempTree =
> TempTree->Next) {
> +      if (CompareMem(&(TempTree->ObservableGuid), &ReferenceGuid,
> sizeof(ReferenceGuid)) == 0) {
> +        Found = TRUE;
> +        break;
> +      }
> +    }
> +    if (Found) {
> +      //
> +      // Prepare to add a new leaf.
> +      //
> +      NewLeaf = AllocateZeroPool(sizeof(OBS_LEAF));
> +      if (!NewLeaf) {
> +        Status = EFI_OUT_OF_RESOURCES;
> +      } else {
> +        NewLeaf->Next = NULL;
> +        NewLeaf->Observer = CallbackInterface;
> +        //
> +        // Go to the end of the list of observers.
> +        //
> +        if (TempTree->Leaf != NULL) {
> +          //
> +          // First check to see if this is a duplicate observer.
> +          //
> +          Found = FALSE;
> +          TempLeaf = TempTree->Leaf;
> +          do {
> +            Last = TempLeaf;
> +            if (TempLeaf->Observer == CallbackInterface) {
> +              //
> +              // It is, so let's abort this process.
> +              //
> +              Found = TRUE;
> +              break;
> +            }
> +            TempLeaf = TempLeaf->Next;
> +          } while (TempLeaf != NULL);
> +          TempLeaf = Last;
> +
> +          //
> +          // Check for duplicates.
> +          //
> +          if (Found) {
> +            gBS->FreePool(NewLeaf);
> +            Status = EFI_INVALID_PARAMETER;
> +          } else {
> +            //
> +            // At this point, TempLeaf->Next will be the end of the list.
> +            //
> +            TempLeaf->Next = NewLeaf;
> +          }
> +        } else {
> +          //
> +          // There are no observers listening to this guid. Start a new list.
> +          //
> +          TempTree->Leaf = NewLeaf;
> +        }
> +      }
> +    } else {
> +      Status = EFI_NOT_FOUND;
> +    }
> +  } else {
> +    Status = EFI_NOT_FOUND;
> +  }
> +
> +  return Status;
> +}
> +
> +/** Unsubscribe an interface with an observable guid.
> + *
> + * Use this to remove an interface from the callback list associated with an
> observable guid.
> + *
> + * @param   EFI_GUID                ReferenceGuid   The observable guid to
> unsubscribe the interface from.
> + *          OBS_NOTIFY_INTERFACE    NotifyCallback  A pointer to the interface
> that is being unsubscribed.
> + *
> + * @return  EFI_SUCCESS           Successfully unsubscribed the interface from
> the observable guid.
> + **/
> +EFI_STATUS
> +EFIAPI
> +Unsubscribe (
> +  IN      EFI_GUID        ReferenceGuid,
> +  IN      OBS_CALLBACK    CallbackInterface
> +  )
> +{
> +  mObservableDb = FindAndDeleteSubscriber(mObservableDb,
> ReferenceGuid, CallbackInterface);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/** Notify observing functions.
> + *
> + * Use this to notify all functions who are subscribed to the guid specified by
> ReferenceGuid.
> + *
> + * @param   EFI_GUID          ReferenceGuid   The observable guid that
> contains the the list of interfaces to be notified.
> + *          VOID*             Data            Parameter context to be passed to the
> notification function.
> + *
> + * @return  EFI_SUCCESS       Successfully notified all observers listening to
> this guid.
> + *          EFI_NOT_FOUND     No match could be found between the provided
> guid and existing observables.
> + **/
> +EFI_STATUS
> +EFIAPI
> +Publish (
> +  IN      EFI_GUID                  ReferenceGuid,
> +  IN  OUT VOID*                     Data
> +  )
> +{
> +  EFI_STATUS  Status    = EFI_SUCCESS;
> +  OBS_TREE*   TempTree  = NULL;
> +  OBS_LEAF*   TempLeaf  = NULL;
> +  BOOLEAN     Found     = FALSE;
> +
> +  if (mObservableDb != NULL) {
> +    //
> +    // Find the observable guid that we're looking for.
> +    //
> +    for (TempTree = mObservableDb; TempTree != NULL; TempTree =
> TempTree->Next) {
> +      if (CompareMem(&(TempTree->ObservableGuid), &ReferenceGuid,
> sizeof(ReferenceGuid)) == 0) {
> +        Found = TRUE;
> +        break;
> +      }
> +    }
> +    if (Found) {
> +      //
> +      // Notify every listener by performing each provided callback.
> +      //
> +      for (TempLeaf = TempTree->Leaf; TempLeaf != NULL; TempLeaf =
> TempLeaf->Next) {
> +        if (TempLeaf->Observer != NULL) {
> +          //
> +          // Execute the callback.
> +          //
> +          TempLeaf->Observer(Data);
> +        }
> +      }
> +    } else {
> +      Status = EFI_NOT_FOUND;
> +    }
> +  } else {
> +    Status = EFI_NOT_FOUND;
> +  }
> +
> +  return Status;
> +}
> +
> +/** Creates a new observable.
> + *
> + * Create a new observable that can be observed with the use of Subscribe
> function.
> + *
> + * @param   EFI_GUID              ReferenceGuid   The observable guid to add.
> + *
> + * @return  EFI_SUCCESS           Successfully added observable.
> + *          EFI_INVALID_PARAMETER Observable already exists.
> + **/
> +EFI_STATUS
> +EFIAPI
> +AddObservable (
> +  IN      EFI_GUID                  ReferenceGuid
> +  )
> +{
> +  EFI_STATUS  Status    = EFI_SUCCESS;
> +  OBS_TREE*   TempTree  = NULL;
> +  OBS_TREE*   Last      = NULL;
> +  OBS_TREE*   NewTree   = NULL;
> +  BOOLEAN     Found     = FALSE;
> +
> +  if (mObservableDb != NULL) {
> +    if (mObservableDb->Next != NULL) {
> +      //
> +      // Iterate to the end of the observable list while checking to see if we
> aren't creating a duplicate.
> +      //
> +      TempTree = mObservableDb->Next;
> +      do {
> +        Last = TempTree;
> +        if (CompareMem(&(TempTree->ObservableGuid), &ReferenceGuid,
> sizeof(ReferenceGuid)) == 0) {
> +          Found = TRUE;
> +          break;
> +        }
> +        TempTree = TempTree->Next;
> +      } while (TempTree != NULL);
> +      TempTree = Last;
> +    } else {
> +      TempTree = mObservableDb;
> +    }
> +    if (Found) {
> +      //
> +      // Duplicate, so reject the parameter.
> +      //
> +      Status = EFI_INVALID_PARAMETER;
> +    } else {
> +      //
> +      // TempTree->Next is our target. Prepare to add a new tree link.
> +      //
> +      NewTree = AllocateZeroPool(sizeof(OBS_TREE));
> +      if (NewTree) {
> +        NewTree->Next = NULL;
> +        NewTree->Leaf = NULL;
> +        CopyMem(&(NewTree->ObservableGuid), &ReferenceGuid,
> sizeof(ReferenceGuid));
> +        TempTree->Next = NewTree;
> +      } else {
> +        Status = EFI_OUT_OF_RESOURCES;
> +      }
> +    }
> +  } else {
> +    //
> +    // mObservableDb has not been created yet. Let's do that.
> +    //
> +    NewTree = AllocateZeroPool(sizeof(OBS_TREE));
> +    if (NewTree) {
> +      NewTree->Next = NULL;
> +      NewTree->Leaf = NULL;
> +      CopyMem(&(NewTree->ObservableGuid), &ReferenceGuid,
> sizeof(ReferenceGuid));
> +      mObservableDb = NewTree;
> +    } else {
> +      Status = EFI_OUT_OF_RESOURCES;
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +/** Remove an observable.
> + *
> + * Remove an observable so that it can no longer be subscribed to. In
> addition, unsubscribe any functions
> + * that are subscribed to this guid.
> + *
> + * @param   EFI_GUID              ReferenceGuid   The observable guid to
> remove.
> + *
> + * @return  EFI_SUCCESS           Successfully removed observable.
> + **/
> +EFI_STATUS
> +EFIAPI
> +RemoveObservable (
> +  IN      EFI_GUID        ReferenceGuid
> +  )
> +{
> +  mObservableDb = FindAndDeleteObservable(mObservableDb,
> ReferenceGuid);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.h
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.h
> new file mode 100644
> index 0000000000..f46efe0f1b
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.h
> @@ -0,0 +1,137 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  Observable.h
> +
> +Abstract:
> +
> +  Prototypes for Observable protocol implementation
> +--*/
> +
> +#ifndef _OBSERVABLE_H_
> +#define _OBSERVABLE_H_
> +#include "PlatformDxe.h"
> +#include "Protocol/Observable.h"
> +
> +//
> +// Prototypes
> +//
> +
> +/** Install observable protocol.
> + *
> + * Install interface and initialize the observable protocol.
> + *
> + * @param   VOID          No parameters.
> + *
> + * @return  EFI_SUCCESS   Successfully installed and initialized the protocol.
> + **/
> +EFI_STATUS
> +InitializeObservableProtocol(
> +  VOID
> +  );
> +
> +/** Remove all observables.
> + *
> + * Remove all observable guids and all interfaces subscribed to them.
> + *
> + * @param   VOID          No parameters.
> + *
> + * @return  EFI_SUCCESS   Successfully removed all observables and
> subscribed interfaces.
> + **/
> +EFI_STATUS
> +EFIAPI
> +RemoveAllObservables(
> +  VOID
> +  );
> +
> +/** Subscribe an interface with an observable guid.
> + *
> + * Use this to register a callback function with a guid. The function provided
> by CallbackInterface will be executed
> + * whenever the appropriate observable instance specified by
> ReferenceGuid calls Publish.
> + *
> + * @param   EFI_GUID              ReferenceGuid       The observable guid that
> the callback interface will subscribe to.
> + *          OBS_CALLBACK          CallbackInterface   A pointer to the function that
> is subscribing to the observable.
> + *
> + * @return  EFI_SUCCESS           Successfully subscribed the interface to the
> observable guid.
> + *          EFI_NOT_FOUND         No match could be found between the
> provided guid and existing observables.
> + *          EFI_OUT_OF_RESOURCES  Could not subscribe to this observer due
> to resource limitations.
> + *          EFI_INVALID_PARAMETER Interface is already subscribed to this
> observer.
> + **/
> +EFI_STATUS
> +EFIAPI
> +Subscribe (
> +  IN      EFI_GUID        ReferenceGuid,
> +  IN      OBS_CALLBACK    CallbackInterface
> +  );
> +
> +/** Unsubscribe an interface with an observable guid.
> + *
> + * Use this to remove an interface from the callback list associated with an
> observable guid.
> + *
> + * @param   EFI_GUID              ReferenceGuid      The observable guid to
> unsubscribe the interface from.
> + *          OBS_CALLBACK          CallbackInterface  A pointer to the interface that
> is being unsubscribed.
> + *
> + * @return  EFI_SUCCESS           Successfully unsubscribed the interface from
> the observable guid.
> + **/
> +EFI_STATUS
> +EFIAPI
> +Unsubscribe (
> +  IN      EFI_GUID            ReferenceGuid,
> +  IN      OBS_CALLBACK    CallbackInterface
> +  );
> +
> +/** Notify observing functions.
> + *
> + * Use this to notify all functions who are subscribed to the guid specified by
> ReferenceGuid.
> + *
> + * @param   EFI_GUID          ReferenceGuid   The observable guid that
> contains the list of interfaces to be notified.
> + *          VOID*             Data            Parameter context to be passed to the
> subscribed function.
> + *
> + * @return  EFI_SUCCESS       Successfully notified all observers listening to
> this guid.
> + *          EFI_NOT_FOUND     No match could be found between the provided
> guid and existing observables.
> + **/
> +EFI_STATUS
> +EFIAPI
> +Publish (
> +  IN      EFI_GUID        ReferenceGuid,
> +  IN  OUT VOID*           Data
> +  );
> +
> +/** Creates a new observable.
> + *
> + * Create a new observable that can be observed with the use of Subscribe
> function.
> + *
> + * @param   EFI_GUID              ReferenceGuid   The observable guid to add.
> + *
> + * @return  EFI_SUCCESS           Successfully added observable.
> + *          EFI_INVALID_PARAMETER Observable already exists.
> + **/
> +EFI_STATUS
> +EFIAPI
> +AddObservable (
> +  IN      EFI_GUID        ReferenceGuid
> +  );
> +
> +/** Remove an observable.
> + *
> + * Remove an observable so that it can no longer be subscribed to. In
> addition, unsubscribe any functions
> + * that are subscribed to this guid.
> + *
> + * @param   EFI_GUID              ReferenceGuid   The observable guid to
> remove.
> + *
> + * @return  EFI_SUCCESS           Successfully removed observable.
> + **/
> +EFI_STATUS
> +EFIAPI
> +RemoveObservable (
> +  IN      EFI_GUID        ReferenceGuid
> +  );
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciBus.h
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciBus.h
> new file mode 100644
> index 0000000000..40c0d99392
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciBus.h
> @@ -0,0 +1,379 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +**/
> +
> +
> +#ifndef _EFI_PCI_BUS_H_
> +#define _EFI_PCI_BUS_H_
> +
> +#include <PiDxe.h>
> +
> +#include <Protocol/LoadedImage.h>
> +#include <Protocol/PciHostBridgeResourceAllocation.h>
> +#include <Protocol/PciIo.h>
> +#include <Protocol/LoadFile2.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +#include <Protocol/PciHotPlugRequest.h>
> +#include <Protocol/DevicePath.h>
> +#include <Protocol/PciPlatform.h>
> +#include <Protocol/PciHotPlugInit.h>
> +#include <Protocol/Decompress.h>
> +#include <Protocol/BusSpecificDriverOverride.h>
> +#include <Protocol/IncompatiblePciDeviceSupport.h>
> +#include <Protocol/PciOverride.h>
> +#include <Protocol/PciEnumerationComplete.h>
> +
> +#include <Library/DebugLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/BaseLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/ReportStatusCodeLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PeCoffLib.h>
> +
> +#include <IndustryStandard/Pci.h>
> +#include <IndustryStandard/PeImage.h>
> +#include <IndustryStandard/Acpi.h>
> +
> +typedef struct _PCI_IO_DEVICE              PCI_IO_DEVICE;
> +typedef struct _PCI_BAR                    PCI_BAR;
> +
> +#define EFI_PCI_RID(Bus, Device, Function)  (((UINT32)Bus << 8) +
> ((UINT32)Device << 3) + (UINT32)Function)
> +#define EFI_PCI_BUS_OF_RID(RID)             ((UINT32)RID >> 8)
> +
> +#define     EFI_PCI_IOV_POLICY_ARI           0x0001
> +#define     EFI_PCI_IOV_POLICY_SRIOV         0x0002
> +#define     EFI_PCI_IOV_POLICY_MRIOV         0x0004
> +
> +typedef enum {
> +  PciBarTypeUnknown = 0,
> +  PciBarTypeIo16,
> +  PciBarTypeIo32,
> +  PciBarTypeMem32,
> +  PciBarTypePMem32,
> +  PciBarTypeMem64,
> +  PciBarTypePMem64,
> +  PciBarTypeIo,
> +  PciBarTypeMem,
> +  PciBarTypeMaxType
> +} PCI_BAR_TYPE;
> +
> +
> +#define VGABASE1  0x3B0
> +#define VGALIMIT1 0x3BB
> +
> +#define VGABASE2  0x3C0
> +#define VGALIMIT2 0x3DF
> +
> +#define ISABASE   0x100
> +#define ISALIMIT  0x3FF
> +
> +//
> +// PCI BAR parameters
> +//
> +struct _PCI_BAR {
> +  UINT64        BaseAddress;
> +  UINT64        Length;
> +  UINT64        Alignment;
> +  PCI_BAR_TYPE  BarType;
> +  BOOLEAN       Prefetchable;
> +  UINT8         MemType;
> +  UINT16        Offset;
> +};
> +
> +//
> +// defined in PCI Card Specification, 8.0
> +//
> +#define PCI_CARD_MEMORY_BASE_0                0x1C
> +#define PCI_CARD_MEMORY_LIMIT_0               0x20
> +#define PCI_CARD_MEMORY_BASE_1                0x24
> +#define PCI_CARD_MEMORY_LIMIT_1               0x28
> +#define PCI_CARD_IO_BASE_0_LOWER              0x2C
> +#define PCI_CARD_IO_BASE_0_UPPER              0x2E
> +#define PCI_CARD_IO_LIMIT_0_LOWER             0x30
> +#define PCI_CARD_IO_LIMIT_0_UPPER             0x32
> +#define PCI_CARD_IO_BASE_1_LOWER              0x34
> +#define PCI_CARD_IO_BASE_1_UPPER              0x36
> +#define PCI_CARD_IO_LIMIT_1_LOWER             0x38
> +#define PCI_CARD_IO_LIMIT_1_UPPER             0x3A
> +#define PCI_CARD_BRIDGE_CONTROL               0x3E
> +
> +#define PCI_CARD_PREFETCHABLE_MEMORY_0_ENABLE BIT8
> +#define PCI_CARD_PREFETCHABLE_MEMORY_1_ENABLE BIT9
> +
> +#define PPB_BAR_0                             0
> +#define PPB_BAR_1                             1
> +#define PPB_IO_RANGE                          2
> +#define PPB_MEM32_RANGE                       3
> +#define PPB_PMEM32_RANGE                      4
> +#define PPB_PMEM64_RANGE                      5
> +#define PPB_MEM64_RANGE                       0xFF
> +
> +#define P2C_BAR_0                             0
> +#define P2C_MEM_1                             1
> +#define P2C_MEM_2                             2
> +#define P2C_IO_1                              3
> +#define P2C_IO_2                              4
> +
> +#define EFI_BRIDGE_IO32_DECODE_SUPPORTED      0x0001
> +#define EFI_BRIDGE_PMEM32_DECODE_SUPPORTED    0x0002
> +#define EFI_BRIDGE_PMEM64_DECODE_SUPPORTED    0x0004
> +#define EFI_BRIDGE_IO16_DECODE_SUPPORTED      0x0008
> +#define EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED 0x0010
> +#define EFI_BRIDGE_MEM64_DECODE_SUPPORTED     0x0020
> +#define EFI_BRIDGE_MEM32_DECODE_SUPPORTED     0x0040
> +
> +#define PCI_MAX_HOST_BRIDGE_NUM               0x0010
> +
> +//
> +// Define option for attribute
> +//
> +#define EFI_SET_SUPPORTS    0
> +#define EFI_SET_ATTRIBUTES  1
> +
> +#define PCI_IO_DEVICE_SIGNATURE               SIGNATURE_32 ('p', 'c', 'i', 'o')
> +
> +struct _PCI_IO_DEVICE {
> +  UINT32                                    Signature;
> +  EFI_HANDLE                                Handle;
> +  EFI_PCI_IO_PROTOCOL                       PciIo;
> +  LIST_ENTRY                                Link;
> +
> +  EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL PciDriverOverride;
> +  EFI_DEVICE_PATH_PROTOCOL                  *DevicePath;
> +  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *PciRootBridgeIo;
> +  EFI_LOAD_FILE2_PROTOCOL                   LoadFile2;
> +
> +  //
> +  // PCI configuration space header type
> +  //
> +  PCI_TYPE00                                Pci;
> +
> +  //
> +  // Bus number, Device number, Function number
> +  //
> +  UINT8                                     BusNumber;
> +  UINT8                                     DeviceNumber;
> +  UINT8                                     FunctionNumber;
> +
> +  //
> +  // BAR for this PCI Device
> +  //
> +  PCI_BAR                                   PciBar[PCI_MAX_BAR];
> +
> +  //
> +  // The bridge device this pci device is subject to
> +  //
> +  PCI_IO_DEVICE                             *Parent;
> +
> +  //
> +  // A linked list for children Pci Device if it is bridge device
> +  //
> +  LIST_ENTRY                                ChildList;
> +
> +  //
> +  // TRUE if the PCI bus driver creates the handle for this PCI device
> +  //
> +  BOOLEAN                                   Registered;
> +
> +  //
> +  // TRUE if the PCI bus driver successfully allocates the resource required by
> +  // this PCI device
> +  //
> +  BOOLEAN                                   Allocated;
> +
> +  //
> +  // The attribute this PCI device currently set
> +  //
> +  UINT64                                    Attributes;
> +
> +  //
> +  // The attributes this PCI device actually supports
> +  //
> +  UINT64                                    Supports;
> +
> +  //
> +  // The resource decode the bridge supports
> +  //
> +  UINT32                                    Decodes;
> +
> +  //
> +  // TRUE if the ROM image is from the PCI Option ROM BAR
> +  //
> +  BOOLEAN                                   EmbeddedRom;
> +
> +  //
> +  // The OptionRom Size
> +  //
> +  UINT64                                    RomSize;
> +
> +  //
> +  // The OptionRom Size
> +  //
> +  UINT64                                    RomBase;
> +
> +  //
> +  // TRUE if all OpROM (in device or in platform specific position) have been
> processed
> +  //
> +  BOOLEAN                                   AllOpRomProcessed;
> +
> +  //
> +  // TRUE if there is any EFI driver in the OptionRom
> +  //
> +  BOOLEAN                                   BusOverride;
> +
> +  //
> +  // A list tracking reserved resource on a bridge device
> +  //
> +  LIST_ENTRY                                ReservedResourceList;
> +
> +  //
> +  // A list tracking image handle of platform specific overriding driver
> +  //
> +  LIST_ENTRY                                OptionRomDriverList;
> +
> +  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
> *ResourcePaddingDescriptors;
> +  EFI_HPC_PADDING_ATTRIBUTES                PaddingAttributes;
> +
> +  BOOLEAN                                   IsPciExp;
> +
> +  //
> +  // For SR-IOV
> +  //
> +  UINT8                                     PciExpressCapabilityOffset;
> +  UINT32                                    AriCapabilityOffset;
> +  UINT32                                    SrIovCapabilityOffset;
> +  UINT32                                    MrIovCapabilityOffset;
> +  PCI_BAR                                   VfPciBar[PCI_MAX_BAR];
> +  UINT32                                    SystemPageSize;
> +  UINT16                                    InitialVFs;
> +  UINT16                                    ReservedBusNum;
> +
> +  //
> +  // Per PCI to PCI Bridge spec, I/O window is 4K aligned,
> +  // but some chipsets support non-standard I/O window alignments less
> than 4K.
> +  // This field is used to support this case.
> +  //
> +  UINT16                                    BridgeIoAlignment;
> +};
> +
> +#define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \
> +  CR (a, PCI_IO_DEVICE, PciIo, PCI_IO_DEVICE_SIGNATURE)
> +
> +#define PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS(a) \
> +  CR (a, PCI_IO_DEVICE, PciDriverOverride, PCI_IO_DEVICE_SIGNATURE)
> +
> +#define PCI_IO_DEVICE_FROM_LINK(a) \
> +  CR (a, PCI_IO_DEVICE, Link, PCI_IO_DEVICE_SIGNATURE)
> +
> +#define PCI_IO_DEVICE_FROM_LOAD_FILE2_THIS(a) \
> +  CR (a, PCI_IO_DEVICE, LoadFile2, PCI_IO_DEVICE_SIGNATURE)
> +
> +
> +
> +//
> +// Global Variables
> +//
> +extern EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL
> *gEfiIncompatiblePciDeviceSupport;
> +extern EFI_DRIVER_BINDING_PROTOCOL                  gPciBusDriverBinding;
> +extern EFI_COMPONENT_NAME_PROTOCOL
> gPciBusComponentName;
> +extern EFI_COMPONENT_NAME2_PROTOCOL
> gPciBusComponentName2;
> +extern BOOLEAN                                      gFullEnumeration;
> +extern UINTN                                        gPciHostBridgeNumber;
> +extern EFI_HANDLE
> gPciHostBrigeHandles[PCI_MAX_HOST_BRIDGE_NUM];
> +extern UINT64                                       gAllOne;
> +extern UINT64                                       gAllZero;
> +extern EFI_PCI_PLATFORM_PROTOCOL                    *gPciPlatformProtocol;
> +extern EFI_PCI_OVERRIDE_PROTOCOL                    *gPciOverrideProtocol;
> +extern BOOLEAN                                      mReserveIsaAliases;
> +extern BOOLEAN                                      mReserveVgaAliases;
> +
> +/**
> +  Macro that checks whether device is a GFX device.
> +
> +  @param  _p      Specified device.
> +
> +  @retval TRUE    Device is a GFX device.
> +  @retval FALSE   Device is not a GFX device.
> +
> +**/
> +#define IS_PCI_GFX(_p)     IS_CLASS2 (_p, PCI_CLASS_DISPLAY,
> PCI_CLASS_DISPLAY_OTHER)
> +
> +/**
> +  Test to see if this driver supports ControllerHandle. Any ControllerHandle
> +  than contains a gEfiPciRootBridgeIoProtocolGuid protocol can be
> supported.
> +
> +  @param  This                Protocol instance pointer.
> +  @param  Controller          Handle of device to test.
> +  @param  RemainingDevicePath Optional parameter use to pick a specific
> child
> +                              device to start.
> +
> +  @retval EFI_SUCCESS         This driver supports this device.
> +  @retval EFI_ALREADY_STARTED This driver is already running on this
> device.
> +  @retval other               This driver does not support this device.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +PciBusDriverBindingSupported (
> +  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
> +  IN EFI_HANDLE                     Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
> +  );
> +
> +/**
> +  Start this driver on ControllerHandle and enumerate Pci bus and start
> +  all device under PCI bus.
> +
> +  @param  This                 Protocol instance pointer.
> +  @param  Controller           Handle of device to bind driver to.
> +  @param  RemainingDevicePath  Optional parameter use to pick a specific
> child
> +                               device to start.
> +
> +  @retval EFI_SUCCESS          This driver is added to ControllerHandle.
> +  @retval EFI_ALREADY_STARTED  This driver is already running on
> ControllerHandle.
> +  @retval other                This driver does not support this device.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +PciBusDriverBindingStart (
> +  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
> +  IN EFI_HANDLE                     Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
> +  );
> +
> +/**
> +  Stop this driver on ControllerHandle. Support stopping any child handles
> +  created by this driver.
> +
> +  @param  This              Protocol instance pointer.
> +  @param  Controller        Handle of device to stop driver on.
> +  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If
> number of
> +                            children is zero stop the entire bus driver.
> +  @param  ChildHandleBuffer List of Child Handles to Stop.
> +
> +  @retval EFI_SUCCESS       This driver is removed ControllerHandle.
> +  @retval other             This driver was not removed from this device.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +PciBusDriverBindingStop (
> +  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
> +  IN  EFI_HANDLE                    Controller,
> +  IN  UINTN                         NumberOfChildren,
> +  IN  EFI_HANDLE                    *ChildHandleBuffer
> +  );
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c
> new file mode 100644
> index 0000000000..582d8627cd
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c
> @@ -0,0 +1,506 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +  PciDevice.c
> +
> +Abstract:
> +
> +  Platform Initialization Driver.
> +
> +Revision History
> +
> +--*/
> +
> +#include "PlatformDxe.h"
> +#include "Library/DxeServicesTableLib.h"
> +#include "PciBus.h"
> +#include "Guid/PciLanInfo.h"
> +
> +extern  VOID    *mPciLanInfo;
> +extern  UINTN   mPciLanCount;
> +
> +extern  EFI_HANDLE  mImageHandle;
> +extern  SYSTEM_CONFIGURATION    mSystemConfiguration;
> +
> +
> +VOID       *mPciRegistration;
> +#define NCR_VENDOR_ID  0x1000
> +#define ATI_VENDOR_ID  0x1002
> +#define INTEL_VENDOR_ID 0x8086
> +#define ATI_RV423_ID   0x5548
> +#define ATI_RV423_ID2  0x5d57
> +#define ATI_RV380_ID   0x3e50
> +#define ATI_RV370_ID   0x5b60
> +#define SI_VENDOR_ID   0x1095
> +#define SI_SISATA_ID   0x3114
> +#define SI_SIRAID_PCIUNL 0x40
> +#define INTEL_82573E_IDER 0x108D
> +
> +typedef struct {
> +  UINT8               ClassCode;
> +  UINT8               SubClassCode;
> +  UINT16              VendorId;
> +  UINT16              DeviceId;
> +} BAD_DEVICE_TABLE;
> +
> +BAD_DEVICE_TABLE BadDeviceTable[] = {
> +
> {(UINT8)PCI_CLASS_MASS_STORAGE,(UINT8)PCI_CLASS_MASS_STORAGE_S
> CSI,(UINT16)NCR_VENDOR_ID, (UINT16)0xffff}, // Any NCR cards
> +
> {(UINT8)PCI_CLASS_MASS_STORAGE,(UINT8)PCI_CLASS_MASS_STORAGE_I
> DE,(UINT16)INTEL_VENDOR_ID, (UINT16)INTEL_82573E_IDER},  // Intel
> i82573E Tekoa GBit Lan IDE-R
> +                    {(UINT8)0xff,(UINT8)0xff,(UINT16)0xffff,(UINT16)0xffff}
> +                  };
> +
> +EFI_STATUS
> +PciBusDriverHook (
> +  )
> +{
> +  EFI_STATUS                Status;
> +  EFI_EVENT                 FilterEvent;
> +
> +  //
> +  // Register for callback to PCI I/O protocol
> +  //
> +  Status = gBS->CreateEvent (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_CALLBACK,
> +                  PciBusEvent,
> +                  NULL,
> +                  &FilterEvent
> +                  );
> +  ASSERT_EFI_ERROR(Status);
> +
> +  //
> +  // Register for protocol notifications on this event
> +  //
> +  Status = gBS->RegisterProtocolNotify (
> +                  &gEfiPciIoProtocolGuid,
> +                  FilterEvent,
> +                  &mPciRegistration
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return  EFI_SUCCESS;
> +}
> +
> +VOID
> +InitBadBars(
> +  IN    EFI_PCI_IO_PROTOCOL           *PciIo,
> +  IN    UINT16                        VendorId,
> +  IN    UINT16                        DeviceId
> +  )
> +{
> +
> +  UINT64                              BaseAddress = 0;
> +  UINT64                              TempBaseAddress = 0;
> +  UINT8                               RevId = 0;
> +  UINT32                              Bar;
> +  UINT64                              IoSize;
> +  UINT64                              MemSize;
> +  UINTN                               MemSizeBits;
> +
> +  switch ( VendorId) {
> +    case ATI_VENDOR_ID:
> +      //
> +      //  ATI fix-ups. At this time all ATI cards in BadDeviceTable
> +      //  have same problem in that OPROM BAR needs to be increased.
> +      //
> +      Bar = 0x30 ;
> +      //
> +      // Get original BAR address
> +      //
> +      PciIo->Pci.Read (
> +                   PciIo,
> +                   EfiPciIoWidthUint32,
> +                   Bar,
> +                   1,
> +                       (VOID *) &BaseAddress
> +                   );
> +      //
> +      // Find BAR size
> +      //
> +      TempBaseAddress = 0xffffffff;
> +      PciIo->Pci.Write (
> +                   PciIo,
> +                   EfiPciIoWidthUint32,
> +                   Bar,
> +                   1,
> +                        (VOID *) &TempBaseAddress
> +                   );
> +      PciIo->Pci.Read (
> +                   PciIo,
> +                   EfiPciIoWidthUint32,
> +                   Bar,
> +                   1,
> +                       (VOID *) &TempBaseAddress
> +                   );
> +      TempBaseAddress &= 0xfffffffe;
> +      MemSize = 1;
> +      while ((TempBaseAddress & 0x01) == 0) {
> +        TempBaseAddress = TempBaseAddress >> 1;
> +        MemSize = MemSize << 1;
> +      }
> +
> +      //
> +      // Free up allocated memory memory and re-allocate with increased size.
> +      //
> +      gDS->FreeMemorySpace (
> +             BaseAddress,
> +             MemSize
> +             );
> +      //
> +      // Force new alignment
> +      //
> +      MemSize = 0x8000000;
> +      MemSizeBits = 28;
> +
> +      gDS->AllocateMemorySpace (
> +             EfiGcdAllocateAnySearchBottomUp,
> +             EfiGcdMemoryTypeMemoryMappedIo,
> +             MemSizeBits,           // Alignment
> +             MemSize,
> +             &BaseAddress,
> +             mImageHandle,
> +             NULL
> +             );
> +      PciIo->Pci.Write (
> +                   PciIo,
> +                   EfiPciIoWidthUint32,
> +                   Bar,
> +                   1,
> +                        (VOID *) &BaseAddress
> +                   );
> +
> +      break;
> +    case    NCR_VENDOR_ID:
> +#define MIN_NCR_IO_SIZE  0x800
> +#define NCR_GRAN  11  // 2**11 = 0x800
> +  //
> +  // NCR SCSI cards like 8250S lie about IO needed. Assign as least 0x80.
> +  //
> +  for (Bar = 0x10; Bar < 0x28; Bar+= 4) {
> +
> +    PciIo->Pci.Read (
> +                 PciIo,
> +                 EfiPciIoWidthUint32,
> +                 Bar,
> +                 1,
> +                     (VOID *) &BaseAddress
> +                 );
> +    if (BaseAddress && 0x01) {
> +      TempBaseAddress = 0xffffffff;
> +      PciIo->Pci.Write (
> +                   PciIo,
> +                   EfiPciIoWidthUint32,
> +                   Bar,
> +                   1,
> +                        (VOID *) &TempBaseAddress
> +                   );
> +      TempBaseAddress &= 0xfffffffc;
> +      IoSize = 1;
> +      while ((TempBaseAddress & 0x01) == 0) {
> +        TempBaseAddress = TempBaseAddress >> 1;
> +        IoSize = IoSize << 1;
> +      }
> +      if (IoSize < MIN_NCR_IO_SIZE) {
> +        gDS->FreeIoSpace (
> +               BaseAddress,
> +               IoSize
> +               );
> +
> +        gDS->AllocateIoSpace (
> +               EfiGcdAllocateAnySearchTopDown,
> +               EfiGcdIoTypeIo,
> +               NCR_GRAN,           // Alignment
> +               MIN_NCR_IO_SIZE,
> +               &BaseAddress,
> +               mImageHandle,
> +               NULL
> +               );
> +        TempBaseAddress = BaseAddress + 1;
> +        PciIo->Pci.Write (
> +                     PciIo,
> +                     EfiPciIoWidthUint32,
> +                     Bar,
> +                     1,
> +                          (VOID *) &TempBaseAddress
> +                     );
> +      }
> +    }
> +  }
> +
> +      break;
> +
> +    case INTEL_VENDOR_ID:
> +      if (DeviceId == INTEL_82573E_IDER) {
> +        //
> +        //  Tekoa i82573E IDE-R fix-ups. At this time A2 step and earlier parts do
> not
> +        //  support any BARs except BAR0. Other BARS will actualy map to BAR0
> so disable
> +        //  them all for Control Blocks and Bus mastering ops as well as
> Secondary IDE
> +        //  Controller.
> +        //  All Tekoa A2 or earlier step chips for now.
> +        //
> +        PciIo->Pci.Read (
> +                     PciIo,
> +                     EfiPciIoWidthUint8,
> +                     PCI_REVISION_ID_OFFSET,
> +                     1,
> +                     &RevId
> +                     );
> +        if (RevId <= 0x02) {
> +          for (Bar = 0x14; Bar < 0x24; Bar+= 4) {
> +            //
> +            // Maybe want to clean this up a bit later but for now just clear out
> the secondary
> +            // Bars don't worry aboyut freeing up thge allocs.
> +            //
> +            TempBaseAddress = 0x0;
> +            PciIo->Pci.Write (
> +                         PciIo,
> +                         EfiPciIoWidthUint32,
> +                         Bar,
> +                         1,
> +                              (VOID *) &TempBaseAddress
> +                         );
> +          } // end for
> +        }
> +        else
> +        {
> +        	//
> +          //Tekoa A3 or above:
> +          //Clear bus master base address (PCI register 0x20)
> +          //since Tekoa does not fully support IDE Bus Mastering
> +          //
> +          TempBaseAddress = 0x0;
> +          PciIo->Pci.Write (
> +                       PciIo,
> +                       EfiPciIoWidthUint32,
> +                       0x20,
> +                       1,
> +                            (VOID *) &TempBaseAddress
> +                       );
> +        }
> +      }
> +      break;
> +
> +    default:
> +      break;
> +  }
> +  return;
> +}
> +
> +VOID
> +ProgramPciLatency(
> +  IN    EFI_PCI_IO_PROTOCOL           *PciIo
> +  )
> +{
> +  //
> +  // Program Master Latency Timer
> +  //
> +  if (mSystemConfiguration.PciLatency != 0) {
> +     PciIo->Pci.Write (
> +                  PciIo,
> +                  EfiPciIoWidthUint8,
> +                  PCI_LATENCY_TIMER_OFFSET,
> +                  1,
> +                  &mSystemConfiguration.PciLatency
> +                  );
> +  }
> +  return;
> +}
> +
> +/**
> +During S5 shutdown, we need to program PME in all LAN devices.
> +Here we identify LAN devices and save their bus/dev/func.
> +
> +**/
> +VOID
> +SavePciLanAddress(
> +  IN EFI_PCI_IO_PROTOCOL    *PciIo
> +  )
> +{
> +  EFI_STATUS        Status;
> +  UINTN             PciSegment,
> +                    PciBus,
> +                    PciDevice,
> +                    PciFunction;
> +  VOID              *NewBuffer;
> +  PCI_LAN_INFO      *x;
> +
> +  Status = PciIo->GetLocation (
> +                    PciIo,
> +                    &PciSegment,
> +                    &PciBus,
> +                    &PciDevice,
> +                    &PciFunction
> +                    );
> +  if (EFI_ERROR (Status)) {
> +    return;
> +  }
> +
> +  mPciLanCount ++;
> +  Status = gBS->AllocatePool (
> +                  EfiBootServicesData,
> +                  mPciLanCount * sizeof(PCI_LAN_INFO),
> +                  &NewBuffer
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return;
> +  }
> +
> +  if (mPciLanCount > 1) {
> +    //
> +    // copy old data into new, larger buffer
> +    //
> +    gBS->CopyMem (
> +           NewBuffer,
> +           mPciLanInfo,
> +           (mPciLanCount - 1) * sizeof(PCI_LAN_INFO)
> +           );
> +
> +    //
> +    // free the old memory buffer
> +    //
> +    gBS->FreePool (mPciLanInfo);
> +
> +  }
> +
> +  //
> +  // init the new entry
> +  //
> +  x = (PCI_LAN_INFO *)NewBuffer + (mPciLanCount - 1);
> +  x->PciBus = (UINT8)PciBus;
> +  x->PciDevice = (UINT8)PciDevice;
> +  x->PciFunction = (UINT8)PciFunction;
> +
> +  mPciLanInfo = NewBuffer;
> +
> +  return;
> +}
> +
> +/**
> +  @param  Event          the event that is signaled.
> +  @param Context        not used here.
> +
> +
> +**/
> +VOID
> +EFIAPI
> +PciBusEvent (
> +  IN EFI_EVENT    Event,
> +  IN VOID*        Context
> +  )
> +{
> +
> +  EFI_STATUS                    Status;
> +  UINTN                         BufferSize;
> +  EFI_HANDLE                    Handle;
> +  EFI_PCI_IO_PROTOCOL           *PciIo;
> +  PCI_IO_DEVICE                 *PciIoDevice;
> +  UINT64                        Supports;
> +  UINTN                         Index;
> +  UINT8                         mCacheLineSize = 0x10;
> +
> +  while (TRUE) {
> +    BufferSize = sizeof (EFI_HANDLE);
> +    Status = gBS->LocateHandle (
> +                    ByRegisterNotify,
> +                    NULL,
> +                    mPciRegistration,
> +                    &BufferSize,
> +                    &Handle
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      //
> +      // If no more notification events exist
> +      //
> +      return;
> +    }
> +
> +    Status = gBS->HandleProtocol (
> +                    Handle,
> +                    &gEfiPciIoProtocolGuid,
> +                    (void **)&PciIo
> +                    );
> +
> +    PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);
> +
> +    //
> +    // Enable I/O for bridge so port 0x80 codes will come out
> +    //
> +    if (PciIoDevice->Pci.Hdr.VendorId == V_PCH_INTEL_VENDOR_ID)
> +    {
> +      Status = PciIo->Attributes(
> +                        PciIo,
> +                        EfiPciIoAttributeOperationSupported,
> +                        0,
> +                        &Supports
> +                        );
> +      Supports &= EFI_PCI_DEVICE_ENABLE;
> +      Status = PciIo->Attributes (
> +                        PciIo,
> +                        EfiPciIoAttributeOperationEnable,
> +                        Supports,
> +                        NULL
> +                        );
> +      break;
> +    }
> +
> +    //
> +    // Program PCI Latency Timer
> +    //
> +    ProgramPciLatency(PciIo);
> +
> +    //
> +    // Program Cache Line Size to 64 bytes (0x10 DWORDs)
> +    //
> +    Status = PciIo->Pci.Write (
> +                          PciIo,
> +                          EfiPciIoWidthUint8,
> +                          PCI_CACHELINE_SIZE_OFFSET,
> +                          1,
> +                          &mCacheLineSize
> +                          );
> +
> +    //
> +    // If PCI LAN device, save bus/dev/func info
> +    // so we can program PME during S5 shutdown
> +    //
> +    if (PciIoDevice->Pci.Hdr.ClassCode[2] == PCI_CLASS_NETWORK) {
> +      SavePciLanAddress(PciIo);
> +      break;
> +    }
> +
> +    //
> +    // Workaround for cards with bad BARs
> +    //
> +    Index = 0;
> +    while (BadDeviceTable[Index].ClassCode != 0xff) {
> +      if (BadDeviceTable[Index].DeviceId == 0xffff) {
> +        if ((PciIoDevice->Pci.Hdr.ClassCode[2] ==
> BadDeviceTable[Index].ClassCode) &&
> +            (PciIoDevice->Pci.Hdr.ClassCode[1] ==
> BadDeviceTable[Index].SubClassCode) &&
> +            (PciIoDevice->Pci.Hdr.VendorId == BadDeviceTable[Index].VendorId))
> {
> +
> InitBadBars(PciIo,BadDeviceTable[Index].VendorId,BadDeviceTable[Index].D
> eviceId);
> +        }
> +      } else {
> +        if ((PciIoDevice->Pci.Hdr.ClassCode[2] ==
> BadDeviceTable[Index].ClassCode) &&
> +            (PciIoDevice->Pci.Hdr.ClassCode[1] ==
> BadDeviceTable[Index].SubClassCode) &&
> +            (PciIoDevice->Pci.Hdr.VendorId == BadDeviceTable[Index].VendorId)
> &&
> +            (PciIoDevice->Pci.Hdr.DeviceId == BadDeviceTable[Index].DeviceId))
> {
> +
> +
> InitBadBars(PciIo,BadDeviceTable[Index].VendorId,BadDeviceTable[Index].D
> eviceId);
> +        }
> +      }
> +      ++Index;
> +    }
> +      break;
> +    }
> +
> +  return;
> +}
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Platform.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Platform.c
> new file mode 100644
> index 0000000000..2a4a0b92e1
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Platform.c
> @@ -0,0 +1,1820 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2015, Intel Corporation. All rights reserved.<BR>
> +
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +
> +Module Name:
> +
> +
> +  Platform.c
> +
> +Abstract:
> +
> +  Platform Initialization Driver.
> +
> +
> +--*/
> +
> +#include "PlatformDxe.h"
> +#include "Platform.h"
> +#include "PchCommonDefinitions.h"
> +#include <Protocol/UsbPolicy.h>
> +#include <Protocol/PchPlatformPolicy.h>
> +#include <Protocol/TpmMp.h>
> +#include <Protocol/CpuIo2.h>
> +#include <Library/S3BootScriptLib.h>
> +#include <Guid/PciLanInfo.h>
> +#include <Guid/ItkData.h>
> +#include <Library/PciLib.h>
> +#include <PlatformBootMode.h>
> +#include <Guid/EventGroup.h>
> +#include <Guid/Vlv2Variable.h>
> +#include <Protocol/GlobalNvsArea.h>
> +#include <Protocol/IgdOpRegion.h>
> +#include <Library/PcdLib.h>
> +#include <Protocol/VariableLock.h>
> +
> +
> +//
> +// VLV2 GPIO GROUP OFFSET
> +//
> +#define GPIO_SCORE_OFFSET	0x0000
> +#define GPIO_NCORE_OFFSET	0x1000
> +#define GPIO_SSUS_OFFSET	0x2000
> +
> +typedef struct {
> +  UINT32 offset;
> +  UINT32 val;
> +} CFIO_PNP_INIT;
> +
> +GPIO_CONF_PAD_INIT mTB_BL_GpioInitData_SC_TRI_Exit_boot_Service[]
> =
> +{
> +//              Pad Name          GPIO Number     Used As   GPO Default  Function#
> INT Capable   Interrupt Type   PULL H/L    MMIO Offset
> +  GPIO_INIT_ITEM("LPC_CLKOUT0       GPIOC_47
> "     ,TRISTS   ,NA           ,F0           ,             ,                ,NONE       ,0x47),
> +  GPIO_INIT_ITEM("LPC_CLKOUT1       GPIOC_48
> "     ,TRISTS   ,NA           ,F0           ,             ,                ,NONE       ,0x41),
> +};
> +
> +
> +EFI_GUID mSystemHiiExportDatabase = EFI_HII_EXPORT_DATABASE_GUID;
> +EFI_GUID mPlatformDriverGuid = EFI_PLATFORM_DRIVER_GUID;
> +SYSTEM_CONFIGURATION  mSystemConfiguration;
> +SYSTEM_PASSWORDS      mSystemPassword;
> +EFI_HANDLE            mImageHandle;
> +BOOLEAN               mMfgMode = FALSE;
> +VOID                  *mDxePlatformStringPack;
> +UINT32                mPlatformBootMode = PLATFORM_NORMAL_MODE;
> +extern CHAR16 gItkDataVarName[];
> +
> +
> +EFI_PLATFORM_INFO_HOB      mPlatformInfo;
> +EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *mPciRootBridgeIo;
> +EFI_EVENT  mReadyToBootEvent;
> +
> +UINT8 mSmbusRsvdAddresses[] = PLATFORM_SMBUS_RSVD_ADDRESSES;
> +UINT8 mNumberSmbusAddress = sizeof( mSmbusRsvdAddresses ) /
> sizeof( mSmbusRsvdAddresses[0] );
> +UINT32 mSubsystemVidDid;
> +UINT32 mSubsystemAudioVidDid;
> +
> +UINTN   mPciLanCount = 0;
> +VOID    *mPciLanInfo = NULL;
> +UINTN   SpiBase;
> +
> +static EFI_SPEAKER_IF_PROTOCOL mSpeakerInterface = {
> +  ProgramToneFrequency,
> +  GenerateBeepTone
> +};
> +
> +EFI_USB_POLICY_PROTOCOL         mUsbPolicyData = {0};
> +
> +
> +CFIO_PNP_INIT mTB_BL_GpioInitData_SC_TRI_S0ix_Exit_boot_Service[] =
> +{
> +  {0x410 ,0x20038e10},
> //vlv.gpio.gpscore.cfio_regs_pad_lpc_clkout1_pconf0
> +  {0x470 ,0x20038e10},
> //vlv.gpio.gpscore.cfio_regs_pad_lpc_clkout0_pconf0
> +  {0x560 ,0x20038e10},  //vlv.gpio.gpscore.cfio_regs_pad_ilb_serirq_pconf0
> +  {0x450 ,0x20038e10},
> //vlv.gpio.gpscore.cfio_regs_pad_lpc_frameb_pconf0
> +  {0x480 ,0x20038e10},
> //vlv.gpio.gpscore.cfio_regs_pad_lpc_clkrunb_pconf0
> +  {0x420 ,0x20038e10},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_ad3_pconf0
> +  {0x430 ,0x20038e10},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_ad2_pconf0
> +  {0x440 ,0x20038e10},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_ad1_pconf0
> +  {0x460 ,0x20038e10},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_ad0_pconf0
> +  {0x418 ,0x00000006},
> //vlv.gpio.gpscore.cfio_regs_pad_lpc_clkout1_pad_val
> +  {0x478 ,0x00000006},
> //vlv.gpio.gpscore.cfio_regs_pad_lpc_clkout0_pad_val
> +  {0x568 ,0x00000006},  //vlv.gpio.gpscore.cfio_regs_pad_ilb_serirq_pad_val
> +  {0x458 ,0x00000006},
> //vlv.gpio.gpscore.cfio_regs_pad_lpc_frameb_pad_val
> +  {0x488 ,0x00000006},
> //vlv.gpio.gpscore.cfio_regs_pad_lpc_clkrunb_pad_val
> +  {0x428 ,0x00000006},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_ad3_pad_val
> +  {0x438 ,0x00000006},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_ad2_pad_val
> +  {0x448 ,0x00000006},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_ad1_pad_val
> +  {0x468 ,0x00000006},  //vlv.gpio.gpscore.cfio_regs_pad_lpc_ad0_pad_val
> +};
> +
> +VOID
> +EfiOrMem (
> +  IN VOID   *Destination,
> +  IN VOID   *Source,
> +  IN UINTN  Length
> +  );
> +
> +#if defined(FIRMWARE_ID_BACKWARD_COMPATIBLE) &&
> (FIRMWARE_ID_BACKWARD_COMPATIBLE != 0)
> +STATIC
> +VOID
> +InitFirmwareId();
> +#endif
> +
> +
> +VOID
> +InitializeClockRouting(
> +  );
> +
> +VOID
> +InitializeSlotInfo (
> +  );
> +
> +#if defined(SENSOR_INFO_VAR_SUPPORT) &&
> SENSOR_INFO_VAR_SUPPORT != 0
> +VOID
> +InitializeSensorInfoVariable (
> +  );
> +#endif
> +
> +VOID
> +InitTcoReset (
> +  );
> +
> +VOID
> +InitExI ();
> +
> +VOID
> +InitItk();
> +
> +VOID
> +InitPlatformBootMode();
> +
> +VOID
> +InitMfgAndConfigModeStateVar();
> +
> +VOID
> +InitPchPlatformPolicy (
> +  IN EFI_PLATFORM_INFO_HOB      *PlatformInfo
> +  );
> +
> +VOID
> +InitVlvPlatformPolicy (
> +  );
> +
> +VOID
> +InitSioPlatformPolicy(
> +  );
> +
> +VOID
> +PchInitBeforeBoot(
> +  );
> +
> +VOID
> +UpdateDVMTSetup(
> +  );
> +
> +VOID
> +InitPlatformUsbPolicy (
> +  VOID
> +  );
> +
> +VOID
> +InitRC6Policy(
> +  VOID
> +  );
> +
> +
> +EFI_STATUS
> +EFIAPI
> +SaveSetupRecoveryVar(
> +  VOID
> +  )
> +{
> +  EFI_STATUS                   Status = EFI_SUCCESS;
> +  UINTN                        SizeOfNvStore = 0;
> +  UINTN                        SizeOfSetupVar = 0;
> +  SYSTEM_CONFIGURATION         *SetupData = NULL;
> +  SYSTEM_CONFIGURATION         *RecoveryNvData = NULL;
> +  EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock = NULL;
> +
> +
> +  DEBUG ((EFI_D_INFO, "SaveSetupRecoveryVar() Entry \n"));
> +  SizeOfNvStore = sizeof(SYSTEM_CONFIGURATION);
> +  RecoveryNvData = AllocateZeroPool (sizeof(SYSTEM_CONFIGURATION));
> +  if (NULL == RecoveryNvData) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto Exit;
> +  }
> +
> +  Status = gRT->GetVariable(
> +                L"SetupRecovery",
> +                &gEfiNormalSetupGuid,
> +                NULL,
> +                &SizeOfNvStore,
> +                RecoveryNvData
> +                );
> +
> +  if (EFI_ERROR (Status)) {
> +    // Don't find the "SetupRecovery" variable.
> +    // have to copy "Setup" variable to "SetupRecovery" variable.
> +    SetupData = AllocateZeroPool (sizeof(SYSTEM_CONFIGURATION));
> +    if (NULL == SetupData) {
> +      Status = EFI_OUT_OF_RESOURCES;
> +      goto Exit;
> +    }
> +    SizeOfSetupVar = sizeof(SYSTEM_CONFIGURATION);
> +    Status = gRT->GetVariable(
> +                    NORMAL_SETUP_NAME,
> +                    &gEfiNormalSetupGuid,
> +                    NULL,
> +                    &SizeOfSetupVar,
> +                    SetupData
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    Status = gRT->SetVariable (
> +                    L"SetupRecovery",
> +                    &gEfiNormalSetupGuid,
> +                    EFI_VARIABLE_NON_VOLATILE |
> EFI_VARIABLE_BOOTSERVICE_ACCESS,
> +                    sizeof(SYSTEM_CONFIGURATION),
> +                    SetupData
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL,
> (VOID **) &VariableLock);
> +      if (!EFI_ERROR (Status)) {
> +        Status = VariableLock->RequestToLock (VariableLock, L"SetupRecovery",
> &gEfiNormalSetupGuid);
> +        ASSERT_EFI_ERROR (Status);
> +    }
> +
> +  }
> +
> +Exit:
> +  if (RecoveryNvData)
> +    FreePool (RecoveryNvData);
> +  if (SetupData)
> +    FreePool (SetupData);
> +
> +  return Status;
> +
> +}
> +
> +
> +VOID
> +TristateLpcGpioConfig (
> +  IN UINT32             Gpio_Mmio_Offset,
> +  IN UINT32             Gpio_Pin_Num,
> +  GPIO_CONF_PAD_INIT*   Gpio_Conf_Data
> +  )
> +
> +{
> +  UINT32    index;
> +  UINT32    mmio_conf0;
> +  UINT32    mmio_padval;
> +  PAD_CONF0 conf0_val;
> +  PAD_VAL   pad_val;
> +
> +  //
> +  // GPIO WELL -- Memory base registers
> +  //
> +
> +  //
> +  // A0 BIOS Spec doesn't mention it although X0 does. comment out now.
> +  // GPIO write 0x01001002 to IOBASE + Gpio_Mmio_Offset + 0x0900
> +  //
> +
> +  for(index=0; index < Gpio_Pin_Num; index++)
> +  {
> +    //
> +    // Calculate the MMIO Address for specific GPIO pin CONF0 register
> pointed by index.
> +    //
> +    mmio_conf0 = IO_BASE_ADDRESS + Gpio_Mmio_Offset +
> R_PCH_CFIO_PAD_CONF0 + Gpio_Conf_Data[index].offset * 16;
> +    mmio_padval= IO_BASE_ADDRESS + Gpio_Mmio_Offset +
> R_PCH_CFIO_PAD_VAL   + Gpio_Conf_Data[index].offset * 16;
> +
> +#ifdef EFI_DEBUG
> +    DEBUG ((EFI_D_INFO, "%s, ", Gpio_Conf_Data[index].pad_name));
> +
> +#endif
> +    DEBUG ((EFI_D_INFO, "Usage = %d, Func# = %d, IntType = %d, Pull
> Up/Down = %d, MMIO Base = 0x%08x, ",
> +      Gpio_Conf_Data[index].usage,
> +      Gpio_Conf_Data[index].func,
> +      Gpio_Conf_Data[index].int_type,
> +      Gpio_Conf_Data[index].pull,
> +      mmio_conf0));
> +
> +    //
> +    // Step 1: PadVal Programming
> +    //
> +    pad_val.dw = MmioRead32(mmio_padval);
> +
> +    //
> +    // Config PAD_VAL only for GPIO (Non-Native) Pin
> +    //
> +    if(Native != Gpio_Conf_Data[index].usage)
> +    {
> +      pad_val.dw &= ~0x6; // Clear bits 1:2
> +      pad_val.dw |= (Gpio_Conf_Data[index].usage & 0x6);  // Set bits 1:2
> according to PadVal
> +
> +        //
> +        // set GPO default value
> +        //
> +        if(Gpio_Conf_Data[index].usage == GPO &&
> Gpio_Conf_Data[index].gpod4 != NA)
> +        {
> +        pad_val.r.pad_val = Gpio_Conf_Data[index].gpod4;
> +        }
> +    }
> +
> +
> +    DEBUG ((EFI_D_INFO, "Set PAD_VAL = 0x%08x, ", pad_val.dw));
> +
> +    MmioWrite32(mmio_padval, pad_val.dw);
> +
> +    //
> +    // Step 2: CONF0 Programming
> +    // Read GPIO default CONF0 value, which is assumed to be default value
> after reset.
> +    //
> +    conf0_val.dw = MmioRead32(mmio_conf0);
> +
> +    //
> +    // Set Function #
> +    //
> +    conf0_val.r.Func_Pin_Mux = Gpio_Conf_Data[index].func;
> +
> +    if(GPO == Gpio_Conf_Data[index].usage)
> +    {
> +      //
> +      // If used as GPO, then internal pull need to be disabled
> +      //
> +      conf0_val.r.Pull_assign = 0;  // Non-pull
> +    }
> +    else
> +    {
> +      //
> +      // Set PullUp / PullDown
> +      //
> +      if(P_20K_H == Gpio_Conf_Data[index].pull)
> +      {
> +        conf0_val.r.Pull_assign = 0x1;  // PullUp
> +        conf0_val.r.Pull_strength = 0x2;// 20K
> +      }
> +      else if(P_20K_L == Gpio_Conf_Data[index].pull)
> +      {
> +        conf0_val.r.Pull_assign = 0x2;  // PullDown
> +        conf0_val.r.Pull_strength = 0x2;// 20K
> +      }
> +      else if(P_NONE == Gpio_Conf_Data[index].pull)
> +      {
> +        conf0_val.r.Pull_assign = 0;	// Non-pull
> +      }
> +      else
> +      {
> +        ASSERT(FALSE);  // Invalid value
> +      }
> +    }
> +
> +    //
> +    // Set INT Trigger Type
> +    //
> +    conf0_val.dw &= ~0x0f000000;  // Clear bits 27:24
> +
> +    //
> +    // Set INT Trigger Type
> +    //
> +    if(TRIG_ == Gpio_Conf_Data[index].int_type)
> +    {
> +      //
> +      // Interrupt not capable, clear bits 27:24
> +      //
> +    }
> +    else
> +    {
> +      conf0_val.dw |= (Gpio_Conf_Data[index].int_type & 0x0f)<<24;
> +    }
> +
> +    DEBUG ((EFI_D_INFO, "Set CONF0 = 0x%08x\n", conf0_val.dw));
> +
> +    //
> +    // Write back the targeted GPIO config value according to platform (board)
> GPIO setting
> +    //
> +    MmioWrite32 (mmio_conf0, conf0_val.dw);
> +  }
> +
> +  // A0 BIOS Spec doesn't mention it although X0 does. comment out now.
> +  // GPIO SCORE write 0x01001002 to IOBASE + 0x0900
> +  //
> +}
> +
> +VOID
> +EFIAPI
> +SpiBiosProtectionFunction(
> +  EFI_EVENT Event,
> +  VOID      *Context
> +  )
> +{
> +
> +  UINTN                             mPciD31F0RegBase;
> +  UINTN                             BiosFlaLower0;
> +  UINTN                             BiosFlaLimit0;
> +  UINTN                             BiosFlaLower1;
> +  UINTN                             BiosFlaLimit1;
> +
> +
> +  BiosFlaLower0 = PcdGet32(PcdFlashMicroCodeAddress)-
> PcdGet32(PcdFlashAreaBaseAddress);
> +  BiosFlaLimit0 = PcdGet32(PcdFlashMicroCodeSize)-1;
> +  #ifdef MINNOW2_FSP_BUILD
> +  BiosFlaLower1 = PcdGet32(PcdFlashFvFspBase)-
> PcdGet32(PcdFlashAreaBaseAddress);
> +  BiosFlaLimit1 = (PcdGet32(PcdFlashFvRecoveryBase)-
> PcdGet32(PcdFlashFvFspBase)+PcdGet32(PcdFlashFvRecoverySize))-1;
> +  #else
> +  BiosFlaLower1 = PcdGet32(PcdFlashFvMainBase)-
> PcdGet32(PcdFlashAreaBaseAddress);
> +  BiosFlaLimit1 = (PcdGet32(PcdFlashFvRecoveryBase)-
> PcdGet32(PcdFlashFvMainBase)+PcdGet32(PcdFlashFvRecoverySize))-1;
> +  #endif
> +
> +
> +  mPciD31F0RegBase = MmPciAddress (0,
> +                         DEFAULT_PCI_BUS_NUMBER_PCH,
> +                         PCI_DEVICE_NUMBER_PCH_LPC,
> +                         PCI_FUNCTION_NUMBER_PCH_LPC,
> +                         0
> +                       );
> +  SpiBase          = MmioRead32(mPciD31F0RegBase + R_PCH_LPC_SPI_BASE)
> & B_PCH_LPC_SPI_BASE_BAR;
> +
> +  //
> +  //Set SMM_BWP, WPD and LE bit
> +  //
> +  MmioOr32 ((UINTN) (SpiBase + R_PCH_SPI_BCR), (UINT8)
> B_PCH_SPI_BCR_SMM_BWP);
> +  MmioAnd32 ((UINTN) (SpiBase + R_PCH_SPI_BCR),
> (UINT8)(~B_PCH_SPI_BCR_BIOSWE));
> +  MmioOr32 ((UINTN) (SpiBase + R_PCH_SPI_BCR), (UINT8)
> B_PCH_SPI_BCR_BLE);
> +
> +  //
> +  //First check if FLOCKDN or PR0FLOCKDN is set. No action if either of them
> set already.
> +  //
> +  if( (MmioRead16(SpiBase + R_PCH_SPI_HSFS) &
> B_PCH_SPI_HSFS_FLOCKDN) != 0 ||
> +      (MmioRead32(SpiBase + R_PCH_SPI_IND_LOCK)&
> B_PCH_SPI_IND_LOCK_PR0) != 0) {
> +    //
> +    //Already locked. we could take no action here
> +    //
> +    DEBUG((EFI_D_INFO, "PR0 already locked down. Stop configuring
> PR0.\n"));
> +    return;
> +  }
> +
> +  //
> +  //Set PR0
> +  //
> +  MmioOr32((UINTN)(SpiBase + R_PCH_SPI_PR0),
> +    B_PCH_SPI_PR0_RPE|B_PCH_SPI_PR0_WPE|\
> +
> (B_PCH_SPI_PR0_PRB_MASK&(BiosFlaLower0>>12))|(B_PCH_SPI_PR0_PRL
> _MASK&(BiosFlaLimit0>>12)<<16));
> +
> +  //
> +  //Set PR1
> +  //
> +
> +  MmioOr32((UINTN)(SpiBase + R_PCH_SPI_PR1),
> +    B_PCH_SPI_PR1_RPE|B_PCH_SPI_PR1_WPE|\
> +
> (B_PCH_SPI_PR1_PRB_MASK&(BiosFlaLower1>>12))|(B_PCH_SPI_PR1_PRL
> _MASK&(BiosFlaLimit1>>12)<<16));
> +
> +  //
> +  //Lock down PRx
> +  //
> +  MmioOr16 ((UINTN) (SpiBase + R_PCH_SPI_HSFS), (UINT16)
> (B_PCH_SPI_HSFS_FLOCKDN));
> +
> +  //
> +  // Verify if it's really locked.
> +  //
> +  if ((MmioRead16 (SpiBase + R_PCH_SPI_HSFS) &
> B_PCH_SPI_HSFS_FLOCKDN) == 0) {
> +    DEBUG((EFI_D_ERROR, "Failed to lock down PRx.\n"));
> +  }
> +  return;
> +
> +}
> +
> +VOID
> +EFIAPI
> +InitPciDevPME (
> +  EFI_EVENT  Event,
> +  VOID       *Context
> +  )
> +{
> +  UINTN                  VarSize;
> +
> +  VarSize = sizeof(SYSTEM_CONFIGURATION);
> +  gRT->GetVariable(
> +         NORMAL_SETUP_NAME,
> +         &gEfiNormalSetupGuid,
> +         NULL,
> +         &VarSize,
> +         &mSystemConfiguration
> +         );
> +
> +  //
> +  //Program HDA PME_EN
> +  //
> +  PchAzaliaPciCfg32Or (R_PCH_HDA_PCS, B_PCH_HDA_PCS_PMEE);
> +
> +  //
> +  //Program SATA PME_EN
> +  //
> +  PchSataPciCfg32Or (R_PCH_SATA_PMCS, B_PCH_SATA_PMCS_PMEE);
> +
> +  DEBUG ((EFI_D_INFO, "InitPciDevPME
> mSystemConfiguration.EhciPllCfgEnable = 0x%x
> \n",mSystemConfiguration.EhciPllCfgEnable));
> + if (mSystemConfiguration.EhciPllCfgEnable != 1) {
> +  //
> +  //Program EHCI PME_EN
> +  //
> +  PchMmPci32Or (
> +    0,
> +    0,
> +    PCI_DEVICE_NUMBER_PCH_USB,
> +    PCI_FUNCTION_NUMBER_PCH_EHCI,
> +    R_PCH_EHCI_PWR_CNTL_STS,
> +    B_PCH_EHCI_PWR_CNTL_STS_PME_EN
> +    );
> + }
> +   {
> +     UINTN                 EhciPciMmBase;
> +     UINT32                Buffer32 = 0;
> +
> +    EhciPciMmBase = MmPciAddress (0,
> +                      0,
> +                      PCI_DEVICE_NUMBER_PCH_USB,
> +                      PCI_FUNCTION_NUMBER_PCH_EHCI,
> +                      0
> +                    );
> +    DEBUG ((EFI_D_INFO, "ConfigureAdditionalPm() EhciPciMmBase = 0x%x
> \n",EhciPciMmBase));
> +    Buffer32 = MmioRead32(EhciPciMmBase + R_PCH_EHCI_PWR_CNTL_STS);
> +    DEBUG ((EFI_D_INFO, "ConfigureAdditionalPm()
> R_PCH_EHCI_PWR_CNTL_STS = 0x%x \n",Buffer32));
> +  }
> +}
> +
> +VOID
> +EFIAPI
> +InitThermalZone (
> +  EFI_EVENT  Event,
> +  VOID       *Context
> +  )
> +{
> +  UINTN                  VarSize;
> +  EFI_GLOBAL_NVS_AREA_PROTOCOL       *GlobalNvsArea;
> +  VarSize = sizeof(SYSTEM_CONFIGURATION);
> +  gRT->GetVariable(
> +         NORMAL_SETUP_NAME,
> +         &gEfiNormalSetupGuid,
> +         NULL,
> +         &VarSize,
> +         &mSystemConfiguration
> +         );
> +  gBS->LocateProtocol (
> +         &gEfiGlobalNvsAreaProtocolGuid,
> +         NULL,
> +         (void **)&GlobalNvsArea
> +         );
> +  GlobalNvsArea->Area->CriticalThermalTripPoint =
> mSystemConfiguration.CriticalThermalTripPoint;
> +  GlobalNvsArea->Area->PassiveThermalTripPoint =
> mSystemConfiguration.PassiveThermalTripPoint;
> +}
> +#if defined SUPPORT_LVDS_DISPLAY && SUPPORT_LVDS_DISPLAY
> +
> +#endif
> +
> +
> +EFI_STATUS
> +EFIAPI
> +TristateLpcGpioS0i3Config (
> +  UINT32             Gpio_Mmio_Offset,
> +  UINT32             Gpio_Pin_Num,
> +  CFIO_PNP_INIT*   Gpio_Conf_Data
> +  )
> +{
> +
> +  UINT32	  index;
> +  UINT32	  mmio_reg;
> +  UINT32	  mmio_val;
> +
> +    DEBUG ((DEBUG_INFO, "TristateLpcGpioS0i3Config\n"));
> +
> +    for(index=0; index < Gpio_Pin_Num; index++)
> +    {
> +      mmio_reg = IO_BASE_ADDRESS + Gpio_Mmio_Offset +
> Gpio_Conf_Data[index].offset;
> +
> +      MmioWrite32(mmio_reg, Gpio_Conf_Data[index].val);
> +      mmio_val = 0;
> +      mmio_val = MmioRead32(mmio_reg);
> +
> +      DEBUG ((EFI_D_INFO, "Set MMIO=0x%08x  PAD_VAL = 0x%08x,\n",
> mmio_reg, mmio_val));
> +    }
> +
> +     return EFI_SUCCESS;
> +}
> +
> +
> +EFI_BOOT_SCRIPT_SAVE_PROTOCOL *mBootScriptSave;
> +
> +/**
> +  Event Notification during exit boot service to enabel ACPI mode
> +
> +   Disable SW SMI Timer, SMI from USB & Intel Specific USB 2
> +
> +   Clear all ACPI event status and disable all ACPI events
> +   Disable PM sources except power button
> +   Clear status bits
> +
> +   Guarantee day-of-month alarm is invalid (ACPI 5.0 Section 4.8.2.4 "Real
> Time Clock Alarm")
> +
> +   Update EC to disable SMI and enable SCI
> +
> +   Enable SCI
> +
> +   Enable PME_B0_EN in GPE0a_EN
> +
> +  @param Event  - EFI Event Handle
> +  @param Context - Pointer to Notify Context
> +
> +  @retval  Nothing
> +
> +**/
> +VOID
> +EFIAPI
> +EnableAcpiCallback (
> +  IN EFI_EVENT        Event,
> +  IN VOID             *Context
> +  )
> +{
> +  UINT32  RegData32;
> +  UINT16  Pm1Cnt;
> +  UINT16  AcpiBase;
> +  UINT32  Gpe0aEn;
> +
> +  AcpiBase = MmioRead16 (
> +               PchPciDeviceMmBase (DEFAULT_PCI_BUS_NUMBER_PCH,
> +               PCI_DEVICE_NUMBER_PCH_LPC,
> +               PCI_FUNCTION_NUMBER_PCH_LPC) + R_PCH_LPC_ACPI_BASE
> +               ) & B_PCH_LPC_ACPI_BASE_BAR;
> +
> +  DEBUG ((EFI_D_INFO, "EnableAcpiCallback: AcpiBase = %x\n", AcpiBase));
> +
> +  //
> +  // Disable SW SMI Timer, SMI from USB & Intel Specific USB 2
> +  //
> +  RegData32 = IoRead32(AcpiBase + R_PCH_SMI_EN);
> +  RegData32 &= ~(B_PCH_SMI_EN_SWSMI_TMR |
> B_PCH_SMI_EN_LEGACY_USB2 | B_PCH_SMI_EN_INTEL_USB2);
> +  IoWrite32(AcpiBase + R_PCH_SMI_EN, RegData32);
> +
> +  RegData32 = IoRead32(AcpiBase + R_PCH_SMI_STS);
> +  RegData32 |= B_PCH_SMI_STS_SWSMI_TMR;
> +  IoWrite32(AcpiBase + R_PCH_SMI_STS, RegData32);
> +
> +  //
> +  // Disable PM sources except power button
> +  // power button is enabled only for PCAT. Disabled it on Tablet platform
> +  //
> +
> +  IoWrite16(AcpiBase + R_PCH_ACPI_PM1_EN,
> B_PCH_ACPI_PM1_EN_PWRBTN);
> +  IoWrite16(AcpiBase + R_PCH_ACPI_PM1_STS, 0xffff);
> +
> +  //
> +  // Guarantee day-of-month alarm is invalid (ACPI 5.0 Section 4.8.2.4 "Real
> Time Clock Alarm")
> +  // Clear Status D reg VM bit, Date of month Alarm to make Data in CMOS
> RAM is no longer Valid
> +  //
> +  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_D);
> +  IoWrite8 (PCAT_RTC_DATA_REGISTER, 0x0);
> +
> +  RegData32 = IoRead32(AcpiBase + R_PCH_ALT_GP_SMI_EN);
> +  RegData32 &= ~(BIT7);
> +  IoWrite32((AcpiBase + R_PCH_ALT_GP_SMI_EN), RegData32);
> +
> +  //
> +  // Enable SCI
> +  //
> +  Pm1Cnt = IoRead16(AcpiBase + R_PCH_ACPI_PM1_CNT);
> +  Pm1Cnt |= B_PCH_ACPI_PM1_CNT_SCI_EN;
> +  IoWrite16(AcpiBase + R_PCH_ACPI_PM1_CNT, Pm1Cnt);
> +
> +  IoWrite8(0x80, 0xA0);	//SW_SMI_ACPI_ENABLE
> +
> +  //
> +  // Enable PME_B0_EN in GPE0a_EN
> +  // Caution: Enable PME_B0_EN must be placed after enabling SCI.
> +  // Otherwise, USB PME could not be handled as SMI event since no
> handler is there.
> +  //
> +  Gpe0aEn = IoRead32 (AcpiBase + R_PCH_ACPI_GPE0a_EN);
> +  Gpe0aEn |= B_PCH_ACPI_GPE0a_EN_PME_B0;
> +  IoWrite32(AcpiBase + R_PCH_ACPI_GPE0a_EN, Gpe0aEn);
> +
> +}
> +
> +/**
> +
> +  Routine Description:
> +
> +  This is the standard EFI driver point for the Driver. This
> +  driver is responsible for setting up any platform specific policy or
> +  initialization information.
> +
> +  @param ImageHandle    Handle for the image of this driver.
> +  @param SystemTable    Pointer to the EFI System Table.
> +
> +  @retval EFI_SUCCESS   Policy decisions set.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitializePlatform (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  )
> +{
> +  EFI_STATUS                          Status;
> +  UINTN                               VarSize;
> +  EFI_HANDLE                          Handle = NULL;
> +  EFI_EVENT                           mEfiExitBootServicesEvent;
> +  EFI_EVENT                           RtcEvent;
> +  VOID                                *RtcCallbackReg = NULL;
> +
> +  mImageHandle = ImageHandle;
> +
> +  Status = gBS->InstallProtocolInterface (
> +                  &Handle,
> +                  &gEfiSpeakerInterfaceProtocolGuid,
> +                  EFI_NATIVE_INTERFACE,
> +                  &mSpeakerInterface
> +                  );
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiPciRootBridgeIoProtocolGuid,
> +                  NULL,
> +                  (VOID **) &mPciRootBridgeIo
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  VarSize = sizeof(EFI_PLATFORM_INFO_HOB);
> +  Status = gRT->GetVariable(
> +                  L"PlatformInfo",
> +                  &gEfiVlv2VariableGuid,
> +                  NULL,
> +                  &VarSize,
> +                  &mPlatformInfo
> +                  );
> +
> +  //
> +  // Initialize Product Board ID variable
> +  //
> +  InitMfgAndConfigModeStateVar();
> +  InitPlatformBootMode();
> +
> +  //
> +  // Install Observable protocol
> +  //
> +  InitializeObservableProtocol();
> +
> +  Status = SaveSetupRecoveryVar();
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((EFI_D_ERROR, "InitializePlatform() Save SetupRecovery variable
> failed \n"));
> +  }
> +
> +  VarSize = sizeof(SYSTEM_CONFIGURATION);
> +  Status = gRT->GetVariable(
> +                  NORMAL_SETUP_NAME,
> +                  &gEfiNormalSetupGuid,
> +                  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",
> +              &gEfiNormalSetupGuid,
> +              NULL,
> +              &VarSize,
> +              &mSystemConfiguration
> +              );
> +    ASSERT_EFI_ERROR (Status);
> +    Status = gRT->SetVariable (
> +                    NORMAL_SETUP_NAME,
> +                    &gEfiNormalSetupGuid,
> +                    EFI_VARIABLE_NON_VOLATILE |
> EFI_VARIABLE_BOOTSERVICE_ACCESS,
> +                    sizeof(SYSTEM_CONFIGURATION),
> +                    &mSystemConfiguration
> +                    );
> +  }
> +
> +  Status = EfiCreateEventReadyToBootEx (
> +             TPL_CALLBACK,
> +             ReadyToBootFunction,
> +             NULL,
> +             &mReadyToBootEvent
> +             );
> +
> +  //
> +  // Create a ReadyToBoot Event to run the PME init process
> +  //
> +  Status = EfiCreateEventReadyToBootEx (
> +             TPL_CALLBACK,
> +             InitPciDevPME,
> +             NULL,
> +             &mReadyToBootEvent
> +             );
> +  //
> +  // Create a ReadyToBoot Event to run enable PR0/PR1 and lock
> down,unlock variable region
> +  //
> +  if(mSystemConfiguration.SpiRwProtect==1) {
> +    Status = EfiCreateEventReadyToBootEx (
> +               TPL_CALLBACK,
> +               SpiBiosProtectionFunction,
> +               NULL,
> +               &mReadyToBootEvent
> +               );
> +  }
> +  //
> +  // Create a ReadyToBoot Event to run the thermalzone init process
> +  //
> +  Status = EfiCreateEventReadyToBootEx (
> +             TPL_CALLBACK,
> +             InitThermalZone,
> +             NULL,
> +             &mReadyToBootEvent
> +             );
> +
> +  ReportStatusCodeEx (
> +    EFI_PROGRESS_CODE,
> +    EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_PLATFORM_DXE_STEP1,
> +    0,
> +    &gEfiCallerIdGuid,
> +    NULL,
> +    NULL,
> +    0
> +    );
> +
> +#if defined(SENSOR_INFO_VAR_SUPPORT) &&
> SENSOR_INFO_VAR_SUPPORT != 0
> +  //
> +  // Initialize Sensor Info variable
> +  //
> +  InitializeSensorInfoVariable();
> +#endif
> +  InitPchPlatformPolicy(&mPlatformInfo);
> +  InitVlvPlatformPolicy();
> +
> +  //
> +  //  Add usb policy
> +  //
> +  InitPlatformUsbPolicy();
> +  InitSioPlatformPolicy();
> +  InitializeClockRouting();
> +  InitializeSlotInfo();
> +  InitTcoReset();
> +
> +  //
> +  //Init ExI
> +  //
> +  InitExI();
> +
> +  ReportStatusCodeEx (
> +    EFI_PROGRESS_CODE,
> +    EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_PLATFORM_DXE_STEP2,
> +    0,
> +    &gEfiCallerIdGuid,
> +    NULL,
> +    NULL,
> +    0
> +    );
> +
> +  //
> +  // Install PCI Bus Driver Hook
> +  //
> +  PciBusDriverHook();
> +
> +  InitItk();
> +
> +  ReportStatusCodeEx (
> +    EFI_PROGRESS_CODE,
> +    EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_PLATFORM_DXE_STEP3,
> +    0,
> +    &gEfiCallerIdGuid,
> +    NULL,
> +    NULL,
> +    0
> +    );
> +
> +
> +  //
> +  // Initialize Password States and Callbacks
> +  //
> +  PchInitBeforeBoot();
> +
> +#if defined SUPPORT_LVDS_DISPLAY && SUPPORT_LVDS_DISPLAY
> +
> +#endif
> +
> +#if defined(FIRMWARE_ID_BACKWARD_COMPATIBLE) &&
> (FIRMWARE_ID_BACKWARD_COMPATIBLE != 0)
> +  //
> +  // Re-write Firmware ID if it is changed
> +  //
> +  InitFirmwareId();
> +#endif
> +
> +  ReportStatusCodeEx (
> +    EFI_PROGRESS_CODE,
> +    EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_PLATFORM_DXE_STEP4,
> +    0,
> +    &gEfiCallerIdGuid,
> +    NULL,
> +    NULL,
> +    0
> +    );
> +
> +
> +  Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_NOTIFY,
> +                  EnableAcpiCallback,
> +                  NULL,
> +                  &gEfiEventExitBootServicesGuid,
> +                  &mEfiExitBootServicesEvent
> +                  );
> +
> +  //
> +  // Adjust RTC deafult time to be BIOS-built time.
> +  //
> +  Status = gBS->CreateEvent (
> +                    EVT_NOTIFY_SIGNAL,
> +                    TPL_CALLBACK,
> +                    AdjustDefaultRtcTimeCallback,
> +                    NULL,
> +                    &RtcEvent
> +                    );
> +  if (!EFI_ERROR (Status)) {
> +      Status = gBS->RegisterProtocolNotify (
> +                      &gExitPmAuthProtocolGuid,
> +                      RtcEvent,
> +                      &RtcCallbackReg
> +                      );
> +
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Source Or Destination with Length bytes.
> +
> +  @param[in] Destination   Target memory
> +  @param[in] Source        Source memory
> +  @param[in] Length        Number of bytes
> +
> +  @retval None
> +
> +**/
> +VOID
> +EfiOrMem (
> +  IN VOID   *Destination,
> +  IN VOID   *Source,
> +  IN UINTN  Length
> +  )
> +{
> +  CHAR8 *Destination8;
> +  CHAR8 *Source8;
> +
> +  if (Source < Destination) {
> +    Destination8  = (CHAR8 *) Destination + Length - 1;
> +    Source8       = (CHAR8 *) Source + Length - 1;
> +    while (Length--) {
> +      *(Destination8--) |= *(Source8--);
> +    }
> +  } else {
> +    Destination8  = (CHAR8 *) Destination;
> +    Source8       = (CHAR8 *) Source;
> +    while (Length--) {
> +      *(Destination8++) |= *(Source8++);
> +    }
> +  }
> +}
> +
> +VOID
> +PchInitBeforeBoot()
> +{
> +  //
> +  // Saved SPI Opcode menu to fix EFI variable unable to write after S3
> resume.
> +  //
> +  S3BootScriptSaveMemWrite (
> +                         EfiBootScriptWidthUint32,
> +                         (UINTN)(SPI_BASE_ADDRESS + (R_PCH_SPI_OPMENU0)),
> +                         1,
> +                         (VOID *)(UINTN)(SPI_BASE_ADDRESS +
> (R_PCH_SPI_OPMENU0)));
> +
> +  S3BootScriptSaveMemWrite (
> +                         EfiBootScriptWidthUint32,
> +                         (UINTN)(SPI_BASE_ADDRESS + (R_PCH_SPI_OPMENU1)),
> +                         1,
> +                         (VOID *)(UINTN)(SPI_BASE_ADDRESS +
> (R_PCH_SPI_OPMENU1)));
> +
> +  S3BootScriptSaveMemWrite (
> +                         EfiBootScriptWidthUint16,
> +                         (UINTN)(SPI_BASE_ADDRESS + R_PCH_SPI_OPTYPE),
> +                         1,
> +                         (VOID *)(UINTN)(SPI_BASE_ADDRESS + R_PCH_SPI_OPTYPE));
> +
> +  S3BootScriptSaveMemWrite (
> +                         EfiBootScriptWidthUint16,
> +                         (UINTN)(SPI_BASE_ADDRESS + R_PCH_SPI_PREOP),
> +                         1,
> +                         (VOID *)(UINTN)(SPI_BASE_ADDRESS + R_PCH_SPI_PREOP));
> +
> +  //
> +  // Saved MTPMC_1 for S3 resume.
> +  //
> +  S3BootScriptSaveMemWrite (
> +                         EfiBootScriptWidthUint32,
> +                         (UINTN)(PMC_BASE_ADDRESS + R_PCH_PMC_MTPMC1),
> +                         1,
> +                         (VOID *)(UINTN)(PMC_BASE_ADDRESS +
> R_PCH_PMC_MTPMC1));
> +  return;
> +}
> +
> +VOID
> +EFIAPI
> +ReadyToBootFunction (
> +  EFI_EVENT  Event,
> +  VOID       *Context
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  EFI_ISA_ACPI_PROTOCOL           *IsaAcpi;
> +  EFI_ISA_ACPI_DEVICE_ID          IsaDevice;
> +  UINTN                           Size;
> +  UINT16                          State;
> +  EFI_TPM_MP_DRIVER_PROTOCOL      *TpmMpDriver;
> +  EFI_CPU_IO_PROTOCOL             *CpuIo;
> +  UINT8                           Data;
> +  UINT8                           ReceiveBuffer [64];
> +  UINT32                          ReceiveBufferSize;
> +
> +  UINT8 TpmForceClearCommand [] =              {0x00, 0xC1,
> +                                                0x00, 0x00, 0x00, 0x0A,
> +                                                0x00, 0x00, 0x00, 0x5D};
> +  UINT8 TpmPhysicalPresenceCommand [] =        {0x00, 0xC1,
> +                                                0x00, 0x00, 0x00, 0x0C,
> +                                                0x40, 0x00, 0x00, 0x0A,
> +                                                0x00, 0x00};
> +  UINT8 TpmPhysicalDisableCommand [] =         {0x00, 0xC1,
> +                                                0x00, 0x00, 0x00, 0x0A,
> +                                                0x00, 0x00, 0x00, 0x70};
> +  UINT8 TpmPhysicalEnableCommand [] =          {0x00, 0xC1,
> +                                                0x00, 0x00, 0x00, 0x0A,
> +                                                0x00, 0x00, 0x00, 0x6F};
> +  UINT8 TpmPhysicalSetDeactivatedCommand [] =  {0x00, 0xC1,
> +                                                0x00, 0x00, 0x00, 0x0B,
> +                                                0x00, 0x00, 0x00, 0x72,
> +                                                0x00};
> +  UINT8 TpmSetOwnerInstallCommand [] =         {0x00, 0xC1,
> +                                                0x00, 0x00, 0x00, 0x0B,
> +                                                0x00, 0x00, 0x00, 0x71,
> +                                                0x00};
> +
> +  Size = sizeof(UINT16);
> +  Status = gRT->GetVariable (
> +                  VAR_EQ_FLOPPY_MODE_DECIMAL_NAME,
> +                  &gEfiNormalSetupGuid,
> +                  NULL,
> +                  &Size,
> +                  &State
> +                  );
> +
> +  //
> +  // Disable Floppy Controller if needed
> +  //
> +  Status = gBS->LocateProtocol (&gEfiIsaAcpiProtocolGuid, NULL, (VOID **)
> &IsaAcpi);
> +  if (!EFI_ERROR(Status) && (State == 0x00)) {
> +    IsaDevice.HID = EISA_PNP_ID(0x604);
> +    IsaDevice.UID = 0;
> +    Status = IsaAcpi->EnableDevice(IsaAcpi, &IsaDevice, FALSE);
> +  }
> +
> +  //
> +  // save LAN info to a variable
> +  //
> +  if (NULL != mPciLanInfo) {
> +    gRT->SetVariable (
> +           L"PciLanInfo",
> +           &gEfiPciLanInfoGuid,
> +           EFI_VARIABLE_NON_VOLATILE |
> EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
> +           mPciLanCount * sizeof(PCI_LAN_INFO),
> +           mPciLanInfo
> +           );
> +  }
> +
> +  if (NULL != mPciLanInfo) {
> +    gBS->FreePool (mPciLanInfo);
> +    mPciLanInfo = NULL;
> +  }
> +
> +
> +  //
> +  // Handle ACPI OS TPM requests here
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiCpuIoProtocolGuid,
> +                  NULL,
> +                  (VOID **)&CpuIo
> +                  );
> +  Status = gBS->LocateProtocol (
> +                  &gEfiTpmMpDriverProtocolGuid,
> +                  NULL,
> +                  (VOID **)&TpmMpDriver
> +                  );
> +  if (!EFI_ERROR (Status))
> +  {
> +    Data = ReadCmosBank1Byte (CpuIo, ACPI_TPM_REQUEST);
> +
> +    //
> +    // Clear pending ACPI TPM request indicator
> +    //
> +    WriteCmosBank1Byte (CpuIo, ACPI_TPM_REQUEST, 0x00);
> +    if (Data != 0)
> +    {
> +      WriteCmosBank1Byte (CpuIo, ACPI_TPM_LAST_REQUEST, Data);
> +
> +      //
> +      // Assert Physical Presence for these commands
> +      //
> +      TpmPhysicalPresenceCommand [11] = 0x20;
> +      ReceiveBufferSize = sizeof(ReceiveBuffer);
> +      Status = TpmMpDriver->Transmit (
> +                              TpmMpDriver, TpmPhysicalPresenceCommand,
> +                              sizeof (TpmPhysicalPresenceCommand),
> +                              ReceiveBuffer, &ReceiveBufferSize
> +                              );
> +      //
> +      // PF PhysicalPresence = TRUE
> +      //
> +      TpmPhysicalPresenceCommand [11] = 0x08;
> +      ReceiveBufferSize = sizeof(ReceiveBuffer);
> +      Status = TpmMpDriver->Transmit (
> +                              TpmMpDriver, TpmPhysicalPresenceCommand,
> +                              sizeof (TpmPhysicalPresenceCommand),
> +                              ReceiveBuffer,
> +                              &ReceiveBufferSize
> +                              );
> +      if (Data == 0x01)
> +      {
> +        //
> +        // TPM_PhysicalEnable
> +        //
> +        ReceiveBufferSize = sizeof(ReceiveBuffer);
> +        Status = TpmMpDriver->Transmit (
> +                                TpmMpDriver, TpmPhysicalEnableCommand,
> +                                sizeof (TpmPhysicalEnableCommand),
> +                                ReceiveBuffer, &ReceiveBufferSize
> +                                );
> +      }
> +      if (Data == 0x02)
> +      {
> +        //
> +        // TPM_PhysicalDisable
> +        //
> +        ReceiveBufferSize = sizeof(ReceiveBuffer);
> +        Status = TpmMpDriver->Transmit (
> +                                TpmMpDriver, TpmPhysicalDisableCommand,
> +                                sizeof (TpmPhysicalDisableCommand),
> +                                ReceiveBuffer,
> +                                &ReceiveBufferSize
> +                                );
> +      }
> +      if (Data == 0x03)
> +      {
> +        //
> +        // TPM_PhysicalSetDeactivated=FALSE
> +        //
> +        ReceiveBufferSize = sizeof(ReceiveBuffer);
> +        TpmPhysicalSetDeactivatedCommand [10] = 0x00;
> +        Status = TpmMpDriver->Transmit (
> +                                TpmMpDriver,
> +                                TpmPhysicalSetDeactivatedCommand,
> +                                sizeof (TpmPhysicalSetDeactivatedCommand),
> +                                ReceiveBuffer, &ReceiveBufferSize
> +                                );
> +        gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
> +      }
> +      if (Data == 0x04)
> +      {
> +        //
> +        // TPM_PhysicalSetDeactivated=TRUE
> +        //
> +        ReceiveBufferSize = sizeof(ReceiveBuffer);
> +        TpmPhysicalSetDeactivatedCommand [10] = 0x01;
> +        Status = TpmMpDriver->Transmit (
> +                                TpmMpDriver,
> +                                TpmPhysicalSetDeactivatedCommand,
> +                                sizeof (TpmPhysicalSetDeactivatedCommand),
> +                                ReceiveBuffer,
> +                                &ReceiveBufferSize
> +                                );
> +        gRT->ResetSystem (
> +               EfiResetWarm,
> +               EFI_SUCCESS,
> +               0,
> +               NULL
> +               );
> +      }
> +      if (Data == 0x05)
> +      {
> +        //
> +        // TPM_ForceClear
> +        //
> +        ReceiveBufferSize = sizeof(ReceiveBuffer);
> +        Status = TpmMpDriver->Transmit (
> +                                TpmMpDriver,
> +                                TpmForceClearCommand,
> +                                sizeof (TpmForceClearCommand),
> +                                ReceiveBuffer,
> +                                &ReceiveBufferSize
> +                                );
> +        gRT->ResetSystem (
> +               EfiResetWarm,
> +               EFI_SUCCESS,
> +               0,
> +               NULL
> +               );
> +      }
> +      if (Data == 0x06)
> +      {
> +        //
> +        // TPM_PhysicalEnable
> +        //
> +        ReceiveBufferSize = sizeof(ReceiveBuffer);
> +        Status = TpmMpDriver->Transmit (
> +                                TpmMpDriver,
> +                                TpmPhysicalEnableCommand,
> +                                sizeof (TpmPhysicalEnableCommand),
> +                                ReceiveBuffer,
> +                                &ReceiveBufferSize
> +                                );
> +        //
> +        // TPM_PhysicalSetDeactivated=FALSE
> +        //
> +        ReceiveBufferSize = sizeof(ReceiveBuffer);
> +        TpmPhysicalSetDeactivatedCommand [10] = 0x00;
> +        Status = TpmMpDriver->Transmit (
> +                                TpmMpDriver,
> +                                TpmPhysicalSetDeactivatedCommand,
> +                                sizeof (TpmPhysicalSetDeactivatedCommand),
> +                                ReceiveBuffer,
> +                                &ReceiveBufferSize
> +                                );
> +        gRT->ResetSystem (
> +               EfiResetWarm,
> +               EFI_SUCCESS,
> +               0,
> +               NULL
> +               );
> +      }
> +      if (Data == 0x07)
> +      {
> +        //
> +        // TPM_PhysicalSetDeactivated=TRUE
> +        //
> +        ReceiveBufferSize = sizeof(ReceiveBuffer);
> +        TpmPhysicalSetDeactivatedCommand [10] = 0x01;
> +        Status = TpmMpDriver->Transmit (
> +                                TpmMpDriver,
> +                                TpmPhysicalSetDeactivatedCommand,
> +                                sizeof (TpmPhysicalSetDeactivatedCommand),
> +                                ReceiveBuffer,
> +                                &ReceiveBufferSize
> +                                );
> +        //
> +        // TPM_PhysicalDisable
> +        //
> +        ReceiveBufferSize = sizeof(ReceiveBuffer);
> +        Status = TpmMpDriver->Transmit (
> +                                TpmMpDriver,
> +                                TpmPhysicalDisableCommand,
> +                                sizeof (TpmPhysicalDisableCommand),
> +                                ReceiveBuffer,
> +                                &ReceiveBufferSize
> +                                );
> +        gRT->ResetSystem (
> +               EfiResetWarm,
> +               EFI_SUCCESS,
> +               0,
> +               NULL
> +               );
> +      }
> +      if (Data == 0x08)
> +      {
> +        //
> +        // TPM_SetOwnerInstall=TRUE
> +        //
> +        ReceiveBufferSize = sizeof(ReceiveBuffer);
> +        TpmSetOwnerInstallCommand [10] = 0x01;
> +        Status = TpmMpDriver->Transmit (
> +                                TpmMpDriver,
> +                                TpmSetOwnerInstallCommand,
> +                                sizeof (TpmSetOwnerInstallCommand),
> +                                ReceiveBuffer,
> +                                &ReceiveBufferSize
> +                                );
> +      }
> +      if (Data == 0x09)
> +      {
> +        //
> +        // TPM_SetOwnerInstall=FALSE
> +        //
> +        ReceiveBufferSize = sizeof(ReceiveBuffer);
> +        TpmSetOwnerInstallCommand [10] = 0x00;
> +        Status = TpmMpDriver->Transmit (
> +                                TpmMpDriver,
> +                                TpmSetOwnerInstallCommand,
> +                                sizeof (TpmSetOwnerInstallCommand),
> +                                ReceiveBuffer,
> +                                &ReceiveBufferSize
> +                                );
> +      }
> +      if (Data == 0x0A)
> +      {
> +        //
> +        // TPM_PhysicalEnable
> +        //
> +        ReceiveBufferSize = sizeof(ReceiveBuffer);
> +        Status = TpmMpDriver->Transmit (
> +                                TpmMpDriver,
> +                                TpmPhysicalEnableCommand,
> +                                sizeof (TpmPhysicalEnableCommand),
> +                                ReceiveBuffer,
> +                                &ReceiveBufferSize
> +                                );
> +        //
> +        // TPM_PhysicalSetDeactivated=FALSE
> +        //
> +        ReceiveBufferSize = sizeof(ReceiveBuffer);
> +        TpmPhysicalSetDeactivatedCommand [10] = 0x00;
> +        Status = TpmMpDriver->Transmit (
> +                                TpmMpDriver,
> +                                TpmPhysicalSetDeactivatedCommand,
> +                                sizeof (TpmPhysicalSetDeactivatedCommand),
> +                                ReceiveBuffer,
> +                                &ReceiveBufferSize
> +                                );
> +        //
> +        // Do TPM_SetOwnerInstall=TRUE on next reboot
> +        //
> +
> +        WriteCmosBank1Byte (CpuIo, ACPI_TPM_REQUEST, 0xF0);
> +
> +        gRT->ResetSystem (
> +               EfiResetWarm,
> +               EFI_SUCCESS,
> +               0,
> +               NULL
> +               );
> +      }
> +      if (Data == 0x0B)
> +      {
> +        //
> +        // TPM_SetOwnerInstall=FALSE
> +        //
> +        ReceiveBufferSize = sizeof(ReceiveBuffer);
> +        TpmSetOwnerInstallCommand [10] = 0x00;
> +        Status = TpmMpDriver->Transmit (
> +                                TpmMpDriver,
> +                                TpmSetOwnerInstallCommand,
> +                                sizeof (TpmSetOwnerInstallCommand),
> +                                ReceiveBuffer,
> +                                &ReceiveBufferSize
> +                                );
> +        //
> +        // TPM_PhysicalSetDeactivated=TRUE
> +        //
> +        ReceiveBufferSize = sizeof(ReceiveBuffer);
> +        TpmPhysicalSetDeactivatedCommand [10] = 0x01;
> +        Status = TpmMpDriver->Transmit (
> +                                TpmMpDriver,
> +                                TpmPhysicalSetDeactivatedCommand,
> +                                sizeof (TpmPhysicalSetDeactivatedCommand),
> +                                ReceiveBuffer,
> +                                &ReceiveBufferSize
> +                                );
> +        //
> +        // TPM_PhysicalDisable
> +        //
> +        ReceiveBufferSize = sizeof(ReceiveBuffer);
> +        Status = TpmMpDriver->Transmit (
> +                                TpmMpDriver,
> +                                TpmPhysicalDisableCommand,
> +                                sizeof (TpmPhysicalDisableCommand),
> +                                ReceiveBuffer,
> +                                &ReceiveBufferSize
> +                                );
> +        gRT->ResetSystem (
> +               EfiResetWarm,
> +               EFI_SUCCESS,
> +               0,
> +               NULL
> +               );
> +      }
> +      if (Data == 0x0E)
> +      {
> +        //
> +        // TPM_ForceClear
> +        //
> +        ReceiveBufferSize = sizeof(ReceiveBuffer);
> +        Status = TpmMpDriver->Transmit (
> +                                TpmMpDriver,
> +                                TpmForceClearCommand,
> +                                sizeof (TpmForceClearCommand),
> +                                ReceiveBuffer,
> +                                &ReceiveBufferSize
> +                                );
> +        //
> +        // TPM_PhysicalEnable
> +        //
> +        ReceiveBufferSize = sizeof(ReceiveBuffer);
> +        Status = TpmMpDriver->Transmit (
> +                                TpmMpDriver,
> +                                TpmPhysicalEnableCommand,
> +                                sizeof (TpmPhysicalEnableCommand),
> +                                ReceiveBuffer,
> +                                &ReceiveBufferSize
> +                                );
> +        //
> +        // TPM_PhysicalSetDeactivated=FALSE
> +        //
> +        ReceiveBufferSize = sizeof(ReceiveBuffer);
> +        TpmPhysicalSetDeactivatedCommand [10] = 0x00;
> +        Status = TpmMpDriver->Transmit (
> +                                TpmMpDriver,
> +                                TpmPhysicalSetDeactivatedCommand,
> +                                sizeof (TpmPhysicalSetDeactivatedCommand),
> +                                ReceiveBuffer,
> +                                &ReceiveBufferSize
> +                                );
> +        gRT->ResetSystem (
> +               EfiResetWarm,
> +               EFI_SUCCESS,
> +               0,
> +               NULL
> +               );
> +      }
> +      if (Data == 0xF0)
> +      {
> +        //
> +        // Second part of ACPI TPM request 0x0A: OEM custom
> TPM_SetOwnerInstall=TRUE
> +        //
> +        ReceiveBufferSize = sizeof(ReceiveBuffer);
> +        TpmSetOwnerInstallCommand [10] = 0x01;
> +        Status = TpmMpDriver->Transmit (
> +                                TpmMpDriver,
> +                                TpmSetOwnerInstallCommand,
> +                                sizeof (TpmSetOwnerInstallCommand),
> +                                ReceiveBuffer,
> +                                &ReceiveBufferSize
> +                                );
> +        WriteCmosBank1Byte (CpuIo, ACPI_TPM_LAST_REQUEST, 0x0A);
> +      }
> +      //
> +      // Deassert Physical Presence
> +      //
> +      TpmPhysicalPresenceCommand [11] = 0x10;
> +      ReceiveBufferSize = sizeof(ReceiveBuffer);
> +      Status = TpmMpDriver->Transmit (
> +                              TpmMpDriver,
> +                              TpmPhysicalPresenceCommand,
> +                              sizeof (TpmPhysicalPresenceCommand),
> +                              ReceiveBuffer,
> +                              &ReceiveBufferSize
> +                              );
> +    }
> +  }
> +
> +  return;
> +}
> +
> +/**
> +
> +  Initializes manufacturing and config mode setting.
> +
> +**/
> +VOID
> +InitMfgAndConfigModeStateVar()
> +{
> +  EFI_PLATFORM_SETUP_ID           *BootModeBuffer;
> +  VOID                            *HobList;
> +
> +
> +  HobList = GetFirstGuidHob(&gEfiPlatformBootModeGuid);
> +  if (HobList != NULL) {
> +    BootModeBuffer = GET_GUID_HOB_DATA (HobList);
> +
> +      //
> +      // Check if in Manufacturing mode
> +      //
> +      if ( !CompareMem (
> +              &BootModeBuffer->SetupName,
> +              MANUFACTURE_SETUP_NAME,
> +              StrSize (MANUFACTURE_SETUP_NAME)
> +              ) ) {
> +        mMfgMode = TRUE;
> +      }
> +
> +
> +
> +  }
> +
> +}
> +
> +/**
> +
> +  Initializes manufacturing and config mode setting.
> +
> +**/
> +VOID
> +InitPlatformBootMode()
> +{
> +  EFI_PLATFORM_SETUP_ID           *BootModeBuffer;
> +  VOID                            *HobList;
> +
> +  HobList = GetFirstGuidHob(&gEfiPlatformBootModeGuid);
> +  if (HobList != NULL) {
> +    BootModeBuffer = GET_GUID_HOB_DATA (HobList);
> +    mPlatformBootMode = BootModeBuffer->PlatformBootMode;
> +  }
> +}
> +
> +/**
> +
> +  Initializes ITK.
> +
> +**/
> +VOID
> +InitItk(
> +  )
> +{
> +  EFI_STATUS                          Status;
> +  UINT16                              ItkModBiosState;
> +  UINT8                               Value;
> +  UINTN                               DataSize;
> +  UINT32                              Attributes;
> +
> +  //
> +  // Setup local variable according to ITK variable
> +  //
> +  //
> +  // Read ItkBiosModVar to determine if BIOS has been modified by ITK
> +  // If ItkBiosModVar = 0 or if variable hasn't been initialized then BIOS has
> not been modified by ITK modified
> +  // Set local variable VAR_EQ_ITK_BIOS_MOD_DECIMAL_NAME=0 if BIOS
> has not been modified by ITK
> +  //
> +  DataSize = sizeof (Value);
> +  Status = gRT->GetVariable (
> +                  ITK_BIOS_MOD_VAR_NAME,
> +                  &gItkDataVarGuid,
> +                  &Attributes,
> +                  &DataSize,
> +                  &Value
> +                  );
> +  if (Status == EFI_NOT_FOUND) {
> +    //
> +    // Variable not found, hasn't been initialized, intialize to 0
> +    //
> +    Value=0x00;
> +  //
> +  // Write variable to flash.
> +  //
> +  gRT->SetVariable (
> +         ITK_BIOS_MOD_VAR_NAME,
> +         &gItkDataVarGuid,
> +         EFI_VARIABLE_RUNTIME_ACCESS |
> +         EFI_VARIABLE_NON_VOLATILE |
> +         EFI_VARIABLE_BOOTSERVICE_ACCESS,
> +         sizeof (Value),
> +         &Value
> +         );
> +
> +}
> +  if ( (!EFI_ERROR (Status)) || (Status == EFI_NOT_FOUND) ) {
> +    if (Value == 0x00) {
> +      ItkModBiosState = 0x00;
> +    } else {
> +      ItkModBiosState = 0x01;
> +    }
> +    gRT->SetVariable (
> +           VAR_EQ_ITK_BIOS_MOD_DECIMAL_NAME,
> +           &gEfiNormalSetupGuid,
> +           EFI_VARIABLE_BOOTSERVICE_ACCESS,
> +           2,
> +           (void *)&ItkModBiosState
> +           );
> +  }
> +}
> +
> +#if defined(FIRMWARE_ID_BACKWARD_COMPATIBLE) &&
> (FIRMWARE_ID_BACKWARD_COMPATIBLE != 0)
> +
> +/**
> +
> +  Initializes the BIOS FIRMWARE ID from the FIRMWARE_ID build variable.
> +
> +**/
> +STATIC
> +VOID
> +InitFirmwareId(
> +  )
> +{
> +  EFI_STATUS   Status;
> +  CHAR16       FirmwareIdNameWithPassword[] =
> FIRMWARE_ID_NAME_WITH_PASSWORD;
> +
> +  //
> +  // First try writing the variable without a password in case we are
> +  // upgrading from a BIOS without password protection on the FirmwareId
> +  //
> +  Status = gRT->SetVariable(
> +                  (CHAR16 *)&gFirmwareIdName,
> +                  &gFirmwareIdGuid,
> +                  EFI_VARIABLE_NON_VOLATILE |
> EFI_VARIABLE_BOOTSERVICE_ACCESS |
> +                  EFI_VARIABLE_RUNTIME_ACCESS,
> +                  sizeof( FIRMWARE_ID ) - 1,
> +                  FIRMWARE_ID
> +                  );
> +
> +  if (Status == EFI_INVALID_PARAMETER) {
> +
> +    //
> +    // Since setting the firmware id without the password failed,
> +    // a password must be required.
> +    //
> +    Status = gRT->SetVariable(
> +                    (CHAR16 *)&FirmwareIdNameWithPassword,
> +                    &gFirmwareIdGuid,
> +                    EFI_VARIABLE_NON_VOLATILE |
> EFI_VARIABLE_BOOTSERVICE_ACCESS |
> +                    EFI_VARIABLE_RUNTIME_ACCESS,
> +                    sizeof( FIRMWARE_ID ) - 1,
> +                    FIRMWARE_ID
> +                    );
> +  }
> +}
> +#endif
> +
> +VOID
> +UpdateDVMTSetup(
> +  )
> +{
> +    //
> +  // Workaround to support IIA bug.
> +  // IIA request to change option value to 4, 5 and 7 relatively
> +  // instead of 1, 2, and 3 which follow Lakeport Specs.
> +  // Check option value, temporary hardcode GraphicsDriverMemorySize
> +  // Option value to fulfill IIA requirment. So that user no need to
> +  // load default and update setupvariable after update BIOS.
> +  //   Option value hardcoded as: 1 to 4, 2 to 5, 3 to 7.
> +  // *This is for broadwater and above product only.
> +  //
> +
> +  SYSTEM_CONFIGURATION        SystemConfiguration;
> +  UINTN                       VarSize;
> +  EFI_STATUS                  Status;
> +
> +  VarSize = sizeof(SYSTEM_CONFIGURATION);
> +  Status = gRT->GetVariable(
> +                  NORMAL_SETUP_NAME,
> +                  &gEfiNormalSetupGuid,
> +                  NULL,
> +                  &VarSize,
> +                  &SystemConfiguration
> +                  );
> +
> +  if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
> +    //The setup variable is corrupted
> +    VarSize = sizeof(SYSTEM_CONFIGURATION);
> +    Status = gRT->GetVariable(
> +              L"SetupRecovery",
> +              &gEfiNormalSetupGuid,
> +              NULL,
> +              &VarSize,
> +              &SystemConfiguration
> +              );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +  if((SystemConfiguration.GraphicsDriverMemorySize < 4)
> && !EFI_ERROR(Status) ) {
> +    switch (SystemConfiguration.GraphicsDriverMemorySize){
> +      case 1:
> +        SystemConfiguration.GraphicsDriverMemorySize = 4;
> +        break;
> +      case 2:
> +        SystemConfiguration.GraphicsDriverMemorySize = 5;
> +        break;
> +      case 3:
> +        SystemConfiguration.GraphicsDriverMemorySize = 7;
> +        break;
> +      default:
> +        break;
> +     }
> +
> +    Status = gRT->SetVariable (
> +                    NORMAL_SETUP_NAME,
> +                    &gEfiNormalSetupGuid,
> +                    EFI_VARIABLE_NON_VOLATILE |
> EFI_VARIABLE_BOOTSERVICE_ACCESS,
> +                    sizeof(SYSTEM_CONFIGURATION),
> +                    &SystemConfiguration
> +                    );
> +  }
> +}
> +
> +VOID
> +InitPlatformUsbPolicy (
> +  VOID
> +  )
> +
> +{
> +  EFI_HANDLE              Handle;
> +  EFI_STATUS              Status;
> +
> +  Handle = NULL;
> +
> +  mUsbPolicyData.Version                       =
> (UINT8)USB_POLICY_PROTOCOL_REVISION_2;
> +  mUsbPolicyData.UsbMassStorageEmulationType   =
> mSystemConfiguration.UsbBIOSINT13DeviceEmulation;
> +  if(mUsbPolicyData.UsbMassStorageEmulationType == 3) {
> +    mUsbPolicyData.UsbEmulationSize =
> mSystemConfiguration.UsbBIOSINT13DeviceEmulationSize;
> +  } else {
> +    mUsbPolicyData.UsbEmulationSize = 0;
> +  }
> +  mUsbPolicyData.UsbZipEmulationType         =
> mSystemConfiguration.UsbZipEmulation;
> +  mUsbPolicyData.UsbOperationMode              = HIGH_SPEED;
> +
> +  //
> +  //  Some chipset need Period smi, 0 = LEGACY_PERIOD_UN_SUPP
> +  //
> +  mUsbPolicyData.USBPeriodSupport      = LEGACY_PERIOD_UN_SUPP;
> +
> +  //
> +  //  Some platform need legacyfree, 0 = LEGACY_FREE_UN_SUPP
> +  //
> +  mUsbPolicyData.LegacyFreeSupport    = LEGACY_FREE_UN_SUPP;
> +
> +  //
> +  //  Set Code base , TIANO_CODE_BASE =0x01, ICBD =0x00
> +  //
> +  mUsbPolicyData.CodeBase    = (UINT8)ICBD_CODE_BASE;
> +
> +  //
> +  //  Some chispet 's LpcAcpibase are diffrent,set by platform or chipset,
> +  //  default is Ich  acpibase =0x040. acpitimerreg=0x08.
> +  mUsbPolicyData.LpcAcpiBase     = 0x40;
> +  mUsbPolicyData.AcpiTimerReg    = 0x08;
> +
> +  //
> +  //  Set for reduce usb post time
> +  //
> +  mUsbPolicyData.UsbTimeTue           = 0x00;
> +  mUsbPolicyData.InternelHubExist     = 0x00;  //TigerPoint doesn't have
> RMH
> +  mUsbPolicyData.EnumWaitPortStableStall    = 100;
> +
> +
> +  Status = gBS->InstallProtocolInterface (
> +                  &Handle,
> +                  &gUsbPolicyGuid,
> +                  EFI_NATIVE_INTERFACE,
> +                  &mUsbPolicyData
> +                  );
> +  ASSERT_EFI_ERROR(Status);
> +
> +}
> +
> +UINT8
> +ReadCmosBank1Byte (
> +  IN  EFI_CPU_IO_PROTOCOL             *CpuIo,
> +  IN  UINT8                           Index
> +  )
> +{
> +  UINT8                               Data;
> +
> +  CpuIo->Io.Write (CpuIo, EfiCpuIoWidthUint8, 0x72, 1, &Index);
> +  CpuIo->Io.Read (CpuIo, EfiCpuIoWidthUint8, 0x73, 1, &Data);
> +  return Data;
> +}
> +
> +VOID
> +WriteCmosBank1Byte (
> +  IN  EFI_CPU_IO_PROTOCOL             *CpuIo,
> +  IN  UINT8                           Index,
> +  IN  UINT8                           Data
> +  )
> +{
> +  CpuIo->Io.Write (
> +              CpuIo,
> +              EfiCpuIoWidthUint8,
> +              0x72,
> +              1,
> +              &Index
> +              );
> +  CpuIo->Io.Write (
> +              CpuIo,
> +              EfiCpuIoWidthUint8,
> +              0x73,
> +              1,
> +              &Data
> +              );
> +}
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.h
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.h
> new file mode 100644
> index 0000000000..8f5df3257e
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.h
> @@ -0,0 +1,722 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2015, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  PlatformDxe.h
> +
> +Abstract:
> +
> +  Header file for Platform Initialization Driver.
> +
> +
> +
> +++*/
> +
> +#ifndef _PLATFORM_DRIVER_H
> +#define _PLATFORM_DRIVER_H
> +
> +#include <PiDxe.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/PcdLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/ReportStatusCodeLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/EfiRegTableLib.h>
> +#include <Library/Tpm2CommandLib.h>
> +#include <Library/Tpm2DeviceLib.h>
> +#include <Library/BaseCryptLib.h>
> +#include <Library/BiosIdLib.h>
> +#include <Protocol/GlobalNvsArea.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +#include <Protocol/IsaAcpi.h>
> +#include <Framework/FrameworkInternalFormRepresentation.h>
> +#include <Protocol/FrameworkHii.h>
> +#include <Protocol/FrameworkFormCallback.h>
> +#include <Protocol/CpuIo.h>
> +#include <Protocol/BootScriptSave.h>
> +#include <Framework/BootScript.h>
> +#include <Guid/GlobalVariable.h>
> +#include <Guid/BoardFeatures.h>
> +#include <Guid/DataHubRecords.h>
> +#include <Protocol/DataHub.h>
> +#include <Protocol/PciIo.h>
> +#include <Protocol/Speaker.h>
> +#include <Protocol/ExitPmAuth.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <Guid/SetupVariable.h>
> +#include <Guid/PlatformInfo.h>
> +#include "Configuration.h"
> +#define _EFI_H_    //skip efi.h
> +#include "PchAccess.h"
> +#include "VlvAccess.h"
> +#include "BoardIdDecode.h"
> +#include "PlatformBaseAddresses.h"
> +#include "SetupMode.h"
> +#include "PlatformBootMode.h"
> +#include "CpuType.h"
> +
> +#define PCAT_RTC_ADDRESS_REGISTER   0x74
> +#define PCAT_RTC_DATA_REGISTER      0x75
> +
> +#define RTC_ADDRESS_SECOND_ALARM    0x01
> +#define RTC_ADDRESS_MINUTE_ALARM    0x03
> +#define RTC_ADDRESS_HOUR_ALARM      0x05
> +
> +#define RTC_ADDRESS_REGISTER_A      0x0A
> +#define RTC_ADDRESS_REGISTER_B      0x0B
> +#define RTC_ADDRESS_REGISTER_C      0x0C
> +#define RTC_ADDRESS_REGISTER_D      0x0D
> +
> +#define B_RTC_ALARM_INT_ENABLE      0x20
> +#define B_RTC_ALARM_INT_STATUS      0x20
> +
> +#define B_RTC_DATE_ALARM_MASK       0x3F
> +
> +//
> +// Default CPU Alternate Duty Cycle (255=100%, 0=0%)
> +//
> +#define DEF_CPU_ALT_DUTY_CYCLE 0xFF
> +
> +#define MAX_ONBOARD_SATA_DEVICE 2
> +
> +#define DXE_DEVICE_ENABLED  1
> +#define DXE_DEVICE_DISABLED 0
> +
> +#define AZALIA_MAX_LOOP_TIME  0x10000
> +
> +//
> +// Platform driver GUID
> +//
> +#define EFI_PLATFORM_DRIVER_GUID \
> +  { 0x056E7324, 0xA718, 0x465b, 0x9A, 0x84, 0x22, 0x8F, 0x06, 0x64, 0x2B,
> 0x4F }
> +
> +#define PASSWORD_MAX_SIZE               20
> +#define PLATFORM_NORMAL_MODE          0x01
> +#define PLATFORM_SAFE_MODE            0x02
> +#define PLATFORM_RECOVERY_MODE        0x04
> +#define PLATFORM_MANUFACTURING_MODE   0x08
> +#define PLATFORM_BACK_TO_BIOS_MODE    0x10
> +
> +#define EFI_OEM_SPECIFIC      0x8000
> +#define EFI_CU_PLATFORM_DXE_INIT                     (EFI_OEM_SPECIFIC |
> 0x00000011)
> +#define EFI_CU_PLATFORM_DXE_STEP1                    (EFI_OEM_SPECIFIC |
> 0x00000012)
> +#define EFI_CU_PLATFORM_DXE_STEP2                    (EFI_OEM_SPECIFIC |
> 0x00000013)
> +#define EFI_CU_PLATFORM_DXE_STEP3                    (EFI_OEM_SPECIFIC |
> 0x00000014)
> +#define EFI_CU_PLATFORM_DXE_STEP4                    (EFI_OEM_SPECIFIC |
> 0x00000015)
> +#define EFI_CU_PLATFORM_DXE_INIT_DONE                (EFI_OEM_SPECIFIC |
> 0x00000016)
> +
> +
> +#define EFI_SECTION_STRING                  0x1C
> +#define EFI_FORWARD_DECLARATION(x) typedef struct _##x x
> +#define PREFIX_BLANK                        0x04
> +
> +#pragma pack(1)
> +
> +typedef UINT64 EFI_BOARD_FEATURES;
> +
> +//
> +//BUGBUG: should remove these EDK hii definition once Hii transtion is
> done
> +//
> +typedef UINT16  STRING_REF;
> +typedef UINT16  EFI_FORM_LABEL;
> +
> +typedef enum {
> +  EfiUserPassword,
> +  EfiAdminPassword
> +} EFI_PASSWORD_TYPE;
> +
> +typedef struct {
> +  CHAR16            TempPassword[PASSWORD_MAX_SIZE];
> +  CHAR16            EncodedPassword[PASSWORD_MAX_SIZE];
> +  VOID              *PasswordLocation;
> +  EFI_PASSWORD_TYPE PasswordType;
> +} EFI_PASSWORD_DATA;
> +
> +typedef struct {
> +  CHAR8 AaNumber[7];
> +  UINT8 BoardId;
> +  EFI_BOARD_FEATURES Features;
> +  UINT16 SubsystemDeviceId;
> +  UINT16 AudioSubsystemDeviceId;
> +  UINT64 AcpiOemTableId;
> +} BOARD_ID_DECODE;
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_FORM_ROUTINE) (
> +  SYSTEM_CONFIGURATION *SetupBuffer
> +  );
> +
> +typedef struct{
> +  UINT16 DeviceNumber;
> +  UINT16 FunctionNumber;
> +}PCI_DEVICE_FUNC_INFO;
> +
> +typedef struct{
> +  CHAR16 PortNumber[4];
> +  STRING_REF SataDeviceInfoStringId;
> +}SATA_DEVICE_STRING_INFO;
> +
> +typedef struct {
> +  UINT16  Signature;
> +  UINT8   Size;
> +  UINT32  EntryPoint;
> +  UINT8   Reserve[17];
> +  UINT16  PciDataOff;
> +  UINT16  ExpansionOff;
> +} PNP_OPTION_ROM_HEADER;
> +
> +typedef struct {
> +  UINT32  Signature;
> +  UINT8   Revision;
> +  UINT8   Length;
> +  UINT16  NextHeader;
> +  UINT8   Reserve;
> +  UINT8   CheckSum;
> +  UINT32  DeviceId;
> +  UINT16  ManufactureStrOff;
> +  UINT16  ProductStrOff;
> +} PNP_EXPANSION_HEADER;
> +
> +typedef struct {
> +  BOOLEAN                         Enable;
> +  UINT8                           VerbTableNum;
> +  UINT16                          CodecSSID;
> +  EFI_PHYSICAL_ADDRESS            HDABar;
> +  EFI_PHYSICAL_ADDRESS            UpperHDABar;
> +  UINT8                           SDIPresent;
> +  BOOLEAN                         Pme;
> +  BOOLEAN                         LegacyFrontPanelAudio;
> +  BOOLEAN                         HighDefinitionFrontPanelAudio;
> +} EFI_AZALIA_S3;
> +
> +//
> +//following structs are from R8. Remove them once R8->R9 transition is
> done
> +//
> +typedef struct {
> +  CHAR16      *OptionString;  // Passed in string to generate a token for in a
> truly dynamic form creation
> +  STRING_REF  StringToken;    // This is used when creating a single op-code
> without generating a StringToken (have one already)
> +  UINT16      Value;
> +  UINT8       Flags;
> +  UINT16      Key;
> +} IFR_OPTION;
> +
> +
> +
> +typedef struct {
> +  UINT8   Number;
> +  UINT32  HorizontalResolution;
> +  UINT32  VerticalResolution;
> +} PANEL_RESOLUTION;
> +
> +#pragma pack()
> +
> +//
> +// Prototypes
> +//
> +EFI_STATUS
> +EFIAPI
> +EfiMain (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  );
> +
> +EFI_STATUS
> +ProcessEventLog (
> +  );
> +
> +EFI_STATUS
> +FindDataRecords (
> +  );
> +
> +EFI_STATUS
> +ProcessPasswords(
> +  );
> +
> +VOID
> +MemorySetup(
> +  );
> +
> +
> +UINTN
> +EfiValueToString (
> +  IN  OUT CHAR16  *Buffer,
> +  IN  INT64       Value,
> +  IN  UINTN       Flags,
> +  IN  UINTN       Width
> +  );
> +
> +VOID
> +EFIAPI
> +ReadyToBootFunction (
> +  EFI_EVENT  Event,
> +  VOID       *Context
> +  );
> +
> +VOID
> +InstallHiiDataAndGetSettings(
> +  IN EFI_HII_STRING_PACK            *StringPack,
> +      //
> +  ... // 0 or more of => IN EFI_HII_IFR_PACK *IfrPack,
> +      // Terminate list with NULL
> +      //
> +  );
> +
> +EFI_STATUS
> +ReadOrInitSetupVariable(
> +  IN UINTN         RequiredVariableSize,
> +  IN UINTN         RequiredPasswordSize,
> +  IN VOID          *DefaultData,
> +  IN VOID          *MfgDefaultData,
> +  OUT VOID         *SetupVariableData,
> +  OUT VOID         *SystemPassword
> +  );
> +
> +VOID
> +EfiLogicalOrMem(
> +  IN VOID   *Destination,
> +  IN VOID   *Source,
> +  IN UINTN  Length
> +  );
> +
> +EFI_STATUS
> +GetStringFromToken (
> +  IN      EFI_GUID                  *ProducerGuid,
> +  IN      STRING_REF                Token,
> +  OUT     CHAR16                    **String
> +  );
> +
> +UINT32
> +ConvertBase2ToRaw (
> +  IN  EFI_EXP_BASE2_DATA             *Data);
> +
> +UINT32
> +ConvertBase10ToRaw (
> +  IN  EFI_EXP_BASE10_DATA             *Data);
> +
> +CHAR16 *
> +GetStringById (
> +  IN  STRING_REF   Id,
> +  EFI_HII_HANDLE   StringPackHandle
> +  );
> +
> +VOID
> +EFIAPI
> +SetupDataFilter (
> +  IN EFI_EVENT    Event,
> +  IN VOID*        Context
> +  );
> +
> +VOID
> +EFIAPI
> +IdeDataFilter (
> +  IN EFI_EVENT    Event,
> +  IN VOID*        Context
> +  );
> +
> +VOID
> +EFIAPI
> +UpdateAhciRaidDiskInfo (
> +  IN EFI_EVENT    Event,
> +  IN VOID*        Context
> +  );
> +
> +VOID
> +EFIAPI
> +EventLogFilter (
> +  IN EFI_EVENT    Event,
> +  IN VOID*        Context
> +  );
> +
> +VOID
> +SwapEntries (
> +  IN  CHAR8 *Data
> +  );
> +
> +VOID
> +AsciiToUnicode (
> +  IN    CHAR8     *AsciiString,
> +  IN    CHAR16    *UnicodeString
> +  );
> +
> +UINT16
> +ConfigModeStateGet();
> +
> +VOID
> +SetSkus();
> +
> +VOID
> +CPUSetupItems();
> +
> +EFI_STATUS
> +SecurityDriverCallback (
> +  IN EFI_FORM_CALLBACK_PROTOCOL       *This,
> +  IN UINT16                           KeyValue,
> +  IN EFI_IFR_DATA_ARRAY               *Data,
> +  OUT EFI_HII_CALLBACK_PACKET         **Packet
> +  );
> +
> +VOID
> +SetPasswordState (
> +  );
> +
> +VOID
> +EncodePassword (
> +  IN  CHAR16                      *Password
> +  );
> +
> +VOID
> +EFIAPI
> +PciBusEvent (
> +  IN EFI_EVENT    Event,
> +  IN VOID*        Context
> +  );
> +VOID
> +AsfInitialize(
> +  );
> +
> +VOID
> +InitializeAsf (
> +  );
> +
> +UINT8
> +ReadCmosBank1Byte (
> +  IN  EFI_CPU_IO_PROTOCOL             *CpuIo,
> +  IN  UINT8                           Index
> +  );
> +
> +VOID
> +WriteCmosBank1Byte (
> +  IN  EFI_CPU_IO_PROTOCOL             *CpuIo,
> +  IN  UINT8                           Index,
> +  IN  UINT8                           Data
> +  );
> +
> +VOID
> +InitializeBoardId (
> +  );
> +
> +EFI_STATUS
> +InstallBootCallbackRoutine(
> +  );
> +
> +EFI_STATUS
> +InstallConfigurationCallbackRoutine(
> +  );
> +
> +EFI_STATUS
> +InstallPerformanceCallbackRoutine(
> +  );
> +
> +EFI_STATUS
> +InstallSecurityCallbackRoutine (
> +  );
> +
> +EFI_STATUS
> +InstallMainCallbackRoutine (
> +  );
> +
> +EFI_STATUS
> +MemoryConfigurationUpdate (
> +  UINT16                *Key,
> +  EFI_FORM_LABEL        *Label,
> +  UINT16                *OpcodeCount,
> +  UINT8                 **OpcodeData,
> +  EFI_FORM_ROUTINE      *Routine
> +  );
> +
> +EFI_STATUS
> +MemoryConfigurationCallbackRoutine (
> +  SYSTEM_CONFIGURATION  *SetupBuffer
> +  );
> +
> +EFI_STATUS
> +MemoryConfigurationCalculateSpeed(
> +  SYSTEM_CONFIGURATION  *SetupBuffer
> +  );
> +
> +VOID
> +UpdateMemoryString(
> +  IN  STRING_REF                  TokenToUpdate,
> +  IN  CHAR16                      *NewString
> +  );
> +
> +VOID
> +InitFeaturePolicy (
> +  IN EFI_PLATFORM_INFO_HOB      *PlatformInfo
> +  );
> +
> +VOID
> +InitializeSetupVarHide (
> +  );
> +
> +VOID
> +PreparePCIePCISlotInformation(
> +  VOID
> +  );
> +
> +
> +EFI_STATUS
> +BootConfigurationUpdate (
> +  IN  OUT SYSTEM_CONFIGURATION  *SystemConfiguration
> +  );
> +
> +EFI_STATUS
> +InitializeBootConfiguration(
> +  VOID
> +  );
> +
> +UINT16
> +GetStringSize(
> +  IN      CHAR16 *ThisString
> +  );
> +
> +UINT16
> +GetDriveCount (
> +  IN      STRING_REF *BootMap
> +  );
> +
> +CHAR16 *
> +GetBootString (
> +  IN      STRING_REF    Id,
> +      OUT UINTN        *Length
> +  );
> +
> +EFI_STATUS
> +BootCfgCreateTwoOptionOneOf(
> +  IN      UINT16                QuestionId,
> +  IN      EFI_FORM_LABEL        Label,
> +  IN      STRING_REF            OptionPrompt,
> +  IN      STRING_REF            OptionHelp,
> +  IN      STRING_REF            OptionOneString,
> +  IN      STRING_REF            OptionTwoString,
> +  IN      UINT8                 OptionOneFlags,
> +  IN      UINT8                 OptionTwoFlags,
> +  IN      UINT16                KeyValueOne,
> +  IN      UINT16                KeyValueTwo
> +  );
> +
> +EFI_STATUS
> +ReplaceOpcodeWithText(
> +  IN      STRING_REF            OptionPrompt,
> +  IN      STRING_REF            OptionHelp,
> +  IN      STRING_REF            OptionOneString,
> +  IN      EFI_FORM_LABEL        Label
> +  );
> +
> +EFI_STATUS
> +CreateDriveBootOrderOpcode(
> +  IN      VOID                 *Data,
> +  IN      STRING_REF           *BootMap,
> +  IN      EFI_FORM_LABEL        Label,
> +  IN      UINT16                QuestionId,
> +  IN      STRING_REF            OptionOneString,
> +  IN      STRING_REF            OptionTwoString
> +  );
> +
> +VOID
> +SetHyperBootCfgFlags(
> +  IN  OUT SYSTEM_CONFIGURATION *SystemConfiguration
> +  );
> +
> +VOID
> +GetHyperBootCfgFlags(
> +  IN  OUT SYSTEM_CONFIGURATION *SystemConfiguration
> +  );
> +
> +VOID
> +PrepareBootCfgForHyperBoot(
> +  IN  OUT SYSTEM_CONFIGURATION *SystemConfiguration
> +  );
> +
> +BOOLEAN
> +BootCfgChanged(
> +  IN      SYSTEM_CONFIGURATION *SystemConfiguration
> +  );
> +
> +EFI_STATUS
> +InsertOpcodeAtIndex(
> +  IN      SYSTEM_CONFIGURATION *SystemConfiguration,
> +  IN  OUT IFR_OPTION           *OptionList,
> +  IN      IFR_OPTION            IfrOption,
> +  IN      UINT16                OptionCount
> +  );
> +
> +VOID
> +ConfigureBootOrderStrings(
> +  IN      SYSTEM_CONFIGURATION *SystemConfiguration
> +  );
> +
> +VOID
> +InitializeAllBootStrings(
> +  VOID
> +  );
> +
> +VOID
> +SaveUsbCfgSettings(
> +  IN  OUT SYSTEM_CONFIGURATION *SystemConfiguration
> +  );
> +
> +VOID
> +RestoreUsbCfgSettings(
> +  IN  OUT SYSTEM_CONFIGURATION *SystemConfiguration
> +  );
> +
> +EFI_STATUS
> +UpdateBootDevicePriority(
> +  IN  OUT SYSTEM_CONFIGURATION *SystemConfiguration
> +  );
> +
> +EFI_STATUS
> +DisableHyperBoot(
> +  IN  OUT SYSTEM_CONFIGURATION *SystemConfiguration
> +  );
> +
> +BOOLEAN
> +CheckForUserPassword(
> +  VOID
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +HyperBootPasswordCallback(
> +  IN  OUT VOID*  Data
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +HyperBootF9Callback (
> +  IN VOID*  Data
> +  );
> +
> +EFI_STATUS
> +InstallHiiEvents(
> +  VOID
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +ProgramToneFrequency (
> +  IN  EFI_SPEAKER_IF_PROTOCOL           *This,
> +  IN  UINT16                            Frequency
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +GenerateBeepTone (
> +  IN  EFI_SPEAKER_IF_PROTOCOL           *This,
> +  IN  UINTN                             NumberOfBeeps,
> +  IN  UINTN                             BeepDuration,
> +  IN  UINTN                             TimeInterval
> +  );
> +
> +EFI_STATUS
> +InitializeObservableProtocol();
> +
> +EFI_STATUS
> +PciBusDriverHook();
> +
> +VOID
> +EFIAPI
> +AdjustDefaultRtcTimeCallback (
> +  IN EFI_EVENT        Event,
> +  IN VOID             *Context
> +  );
> +
> +typedef struct _GOP_DISPLAY_BRIGHTNESS_PROTOCOL
> GOP_DISPLAY_BRIGHTNESS_PROTOCOL;
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *GET_MAXIMUM_BRIGHTNESS_LEVEL) (
> +  IN  GOP_DISPLAY_BRIGHTNESS_PROTOCOL *This,
> +  OUT UINT32 *MaxBrightnessLevel
> +  );
> +
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *GET_CURRENT_BRIGHTNESS_LEVEL) (
> +  IN  GOP_DISPLAY_BRIGHTNESS_PROTOCOL *This,
> +  OUT UINT32 *MaxBrightnessLevel
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *SET_BRIGHTNESS_LEVEL) (
> +  IN  GOP_DISPLAY_BRIGHTNESS_PROTOCOL *This,
> +  IN  UINT32  BrightnessLevel
> +  );
> +
> +struct _GOP_DISPLAY_BRIGHTNESS_PROTOCOL {
> +  UINT32  Revision;
> +  GET_MAXIMUM_BRIGHTNESS_LEVEL GetMaxBrightnessLevel;
> +  GET_CURRENT_BRIGHTNESS_LEVEL GetCurrentBrightnessLevel;
> +  SET_BRIGHTNESS_LEVEL SetBrightnessLevel;
> +};
> +
> +//
> +// Global externs
> +//
> +extern UINT8 MaintenanceBin[];
> +extern UINT8 MainBin[];
> +extern UINT8 ConfigurationBin[];
> +extern UINT8 MemoryConfigurationBin[];
> +extern UINT8 PerformanceBin[];
> +extern UINT8 SecurityBin[];
> +extern UINT8 BootBin[];
> +extern UINT8 PowerBin[];
> +extern UINT8 SystemSetupBin[];
> +
> +extern VOID                 *mDxePlatformStringPack;
> +extern EFI_HII_PROTOCOL     *mHii;
> +extern SYSTEM_CONFIGURATION mSystemConfiguration;
> +extern FRAMEWORK_EFI_HII_HANDLE       mMaintenanceHiiHandle;
> +extern FRAMEWORK_EFI_HII_HANDLE       mMainHiiHandle;
> +extern FRAMEWORK_EFI_HII_HANDLE       mConfigurationHiiHandle;
> +extern FRAMEWORK_EFI_HII_HANDLE       mPerformanceHiiHandle;
> +extern FRAMEWORK_EFI_HII_HANDLE       mPowerHiiHandle;
> +extern FRAMEWORK_EFI_HII_HANDLE       mBootHiiHandle;
> +extern FRAMEWORK_EFI_HII_HANDLE       mSecurityHiiHandle;
> +
> +extern SYSTEM_PASSWORDS     mSystemPassword;
> +extern EFI_PASSWORD_DATA    mAdminPassword;
> +extern EFI_PASSWORD_DATA    mUserPassword;
> +
> +extern EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *mPciRootBridgeIo;
> +
> +//
> +//extern EFI_REG_TABLE mSubsystemIdRegs[];
> +//
> +extern UINT32 mSubsystemVidDid;
> +extern UINT32 mSubsystemAudioVidDid;
> +
> +extern UINT8 mBoardIdIndex;
> +extern BOOLEAN mFoundAANum;
> +extern EFI_BOARD_FEATURES mBoardFeatures;
> +extern UINT16 mSubsystemDeviceId;
> +extern UINT16 mSubsystemAudioDeviceId;
> +extern BOARD_ID_DECODE mBoardIdDecodeTable[];
> +extern UINTN mBoardIdDecodeTableSize;
> +
> +extern UINT8 mSmbusRsvdAddresses[];
> +extern UINT8 mNumberSmbusAddress;
> +extern BOOLEAN mMfgMode;
> +extern UINT32 mPlatformBootMode;
> +extern CHAR8 BoardAaNumber[];
> +
> +extern EFI_GUID gEfiGlobalNvsAreaProtocolGuid;
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.inf
> new file mode 100644
> index 0000000000..4d1949d05d
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.inf
> @@ -0,0 +1,149 @@
> +## @file
> +#
> +#  Copyright (c)  1999  - 2016, Intel Corporation. All rights reserved
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +#  Module Name:
> +#
> +#    PlatformBB.inf
> +#
> +#  Abstract:
> +#
> +#    Component description file for platform DXE driver
> +#  ------------------------------------------------------------------------------
> +#  Rev   Date<MM/DD/YYYY>    Name    Description
> +#  ------------------------------------------------------------------------------
> +#  R01     <04/22/2011>       LB     Update code for SIO83627UHG support.
> +#  ------------------------------------------------------------------------------
> +#
> +##
> +
> +[defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = PlatformDxe
> +  FILE_GUID                      = 056E7324-A718-465b-9A84-228F06642B4F
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  PI_SPECIFICATION_VERSION       = 0x0001000A
> +  ENTRY_POINT                    = InitializePlatform
> +
> +[sources.common]
> +  BoardId.c
> +  BoardIdDecode.c
> +  ClockControl.c
> +  Platform.c
> +  IchRegTable.c
> +  IdccInfo.c
> +  SioPlatformPolicy.c
> +  IchPlatformPolicy.c
> +  PciDevice.c
> +  SlotConfig.c
> +  IchTcoReset.c
> +  SensorVar.c
> +  LegacySpeaker.c
> +  Observable/Observable.c
> +  ExI.c
> +  Rtc.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  IntelFrameworkPkg/IntelFrameworkPkg.dec
> +  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +  SecurityPkg/SecurityPkg.dec
> +  CryptoPkg/CryptoPkg.dec
> +  IntelFspWrapperPkg/IntelFspWrapperPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  MemoryAllocationLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiRuntimeServicesTableLib
> +  DxeServicesTableLib
> +  PchPlatformLib
> +
> +  DebugLib
> +  HiiLib
> +  PrintLib
> +  UefiLib
> +  S3BootScriptLib
> +  ReportStatusCodeLib
> +  EfiRegTableLib
> +  BiosIdLib
> +  BaseCryptLib
> +
> +[Guids]
> +  gEfiBiosIdGuid
> +  gEfiPlatformBootModeGuid
> +  gEfiBoardFeaturesGuid
> +  gItkDataVarGuid
> +  gDmiDataGuid
> +  gIdccDataHubGuid
> +  gEfiPciLanInfoGuid
> +  gEfiNormalSetupGuid
> +  gEfiGlobalVariableGuid
> +  gEfiEventExitBootServicesGuid
> +  gEfiVlv2VariableGuid
> +  gEfiSecureBootEnableDisableGuid
> +
> +[Protocols]
> +  gEfiPciRootBridgeIoProtocolGuid    # CONSUMES  ## GUID
> +  gEfiVariableArchProtocolGuid
> +  gEfiVariableWriteArchProtocolGuid
> +  gEfiHiiConfigAccessProtocolGuid
> +  gEfiBootScriptSaveProtocolGuid
> +  gEfiCpuIoProtocolGuid
> +  gEfiDevicePathProtocolGuid
> +  gEfiDiskInfoProtocolGuid
> +  gEfiPs2PolicyProtocolGuid
> +  gEfiIsaAcpiProtocolGuid
> +  gEfiDataHubProtocolGuid
> +  gEfiPciIoProtocolGuid
> +  gDxePchPlatformPolicyProtocolGuid
> +  gEfiTpmMpDriverProtocolGuid
> +  gEfiLpcWpce791PolicyProtocolGuid
> +  gUsbPolicyGuid
> +  gEfiSpeakerInterfaceProtocolGuid
> +  gDxeVlvPlatformPolicyGuid
> +  gEfiSmbiosSlotPopulationGuid
> +  gObservableProtocolGuid
> +  gEfiCk505ClockPlatformInfoGuid
> +  gEfiLpcWpc83627PolicyProtocolGuid
> +  gEfiTcoResetProtocolGuid
> +  gEfiWatchdogTimerDriverProtocolGuid
> +  gEfiPlatformIdeInitProtocolGuid
> +  gEfiGlobalNvsAreaProtocolGuid
> +  gEfiCpuIo2ProtocolGuid
> +  gIgdOpRegionProtocolGuid
> +  gExitPmAuthProtocolGuid
> +  gEdkiiVariableLockProtocolGuid
> +
> +[Pcd.common]
> +  gPlatformModuleTokenSpaceGuid.PcdPBTNDisableInterval
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +  gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress
> +  gPlatformModuleTokenSpaceGuid.PcdFlashMicroCodeAddress
> +  gPlatformModuleTokenSpaceGuid.PcdFlashMicroCodeSize
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFastPS2Detection
> +  gPlatformModuleTokenSpaceGuid.PcdFlashFvMainBase
> +  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoveryBase
> +  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoverySize
> +  gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase
> +
> +
> +[Depex]
> +  gEfiPciRootBridgeIoProtocolGuid     AND
> +  gEfiVariableArchProtocolGuid        AND
> +  gEfiVariableWriteArchProtocolGuid   AND
> +  gEfiBootScriptSaveProtocolGuid      AND
> +  gEfiCpuIoProtocolGuid               AND
> +  gDxePchPlatformPolicyProtocolGuid   AND
> +  gEfiGlobalNvsAreaProtocolGuid
> +
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c
> new file mode 100644
> index 0000000000..f7be592960
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c
> @@ -0,0 +1,154 @@
> +/** @file
> +  Adjust Default System Time.
> +
> +  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +--*/
> +
> +#include <PlatformDxe.h>
> +
> +//
> +// Date and time initial values.
> +// They are used if the RTC values are invalid during driver initialization
> +//
> +#define RTC_INIT_SECOND 0
> +#define RTC_INIT_MINUTE 0
> +#define RTC_INIT_HOUR   0
> +
> +CHAR16  mBiosReleaseDate[20];
> +
> +/**
> +  Convert a single character to number.
> +  It assumes the input Char is in the scope of L'0' ~ L'9' and L'A' ~ L'F'
> +
> +  @param Char    The input char which need to change to a hex number.
> +
> +**/
> +UINTN
> +CharToUint (
> +  IN CHAR16                           Char
> +  )
> +{
> +  if ((Char >= L'0') && (Char <= L'9')) {
> +    return (UINTN) (Char - L'0');
> +  }
> +
> +  if ((Char >= L'A') && (Char <= L'F')) {
> +    return (UINTN) (Char - L'A' + 0xA);
> +  }
> +
> +  ASSERT (FALSE);
> +  return 0;
> +}
> +
> +/**
> +  See if YEAR field of a variable of EFI_TIME type is correct.
> +
> +  @param   Time   The time to be checked.
> +
> +  @retval  EFI_INVALID_PARAMETER  Some fields of Time are not correct.
> +  @retval  EFI_SUCCESS            Time is a valid EFI_TIME variable.
> +
> +**/
> +EFI_STATUS
> +CheckRtcTimeFields (
> +  IN EFI_TIME *Time
> +  )
> +{
> +  UINT16 YearBuilt;
> +
> +  YearBuilt = (UINT16)(CharToUint(mBiosReleaseDate[8])*10 +
> CharToUint(mBiosReleaseDate[9]) + 2000);
> +
> +  if ((Time->Year) < YearBuilt) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  ExitPmAuth Protocol notification event handler, which set initial system
> time to be
> +  the time when BIOS was built.
> +
> +  @param[in] Event    Event whose notification function is being invoked.
> +  @param[in] Context  Pointer to the notification function's context.
> +
> +**/
> +VOID
> +EFIAPI
> +AdjustDefaultRtcTimeCallback (
> +  IN EFI_EVENT        Event,
> +  IN VOID             *Context
> +  )
> +{
> +  EFI_STATUS      Status;
> +  EFI_TIME        EfiTime;
> +  CHAR16          BiosVersion[60];
> +  CHAR16          BiosReleaseTime[20];
> +  //
> +  // Get BIOS built time from Bios-ID.
> +  //
> +
> +  SetMem(BiosVersion, sizeof(BiosVersion), 0);
> +  SetMem(mBiosReleaseDate, sizeof(mBiosReleaseDate), 0);
> +  SetMem(BiosReleaseTime, sizeof(BiosReleaseTime), 0);
> +
> +  Status = GetBiosVersionDateTime (BiosVersion, mBiosReleaseDate,
> BiosReleaseTime);
> +  ASSERT_EFI_ERROR(Status);
> +  if (EFI_ERROR (Status)) {
> +    return;
> +  }
> +
> +  //
> +  // Get current RTC time.
> +  //
> +  Status = gRT->GetTime (&EfiTime, NULL);
> +
> +  //
> +  // Validate RTC time fields
> +  //
> +  Status = CheckRtcTimeFields (&EfiTime);
> +
> +  if (EFI_ERROR (Status)) {
> +    //
> +    // Date such as Dec 28th of 2015
> +    //
> +    // Month
> +    // BiosReleaseDate[0] = '1';
> +    // BiosReleaseDate[1] = '2';
> +    //
> +    // Day
> +    // BiosReleaseDate[3] = '2';
> +    // BiosReleaseDate[4] = '8';
> +    //
> +    //
> +    // Year
> +    //
> +    // BiosReleaseDate[6] = '2';
> +    // BiosReleaseDate[7] = '0';
> +    // BiosReleaseDate[8] = '1'
> +    // BiosReleaseDate[9] = '5';
> +
> +    EfiTime.Second = RTC_INIT_SECOND;
> +    EfiTime.Minute = RTC_INIT_MINUTE;
> +    EfiTime.Hour   = RTC_INIT_HOUR;
> +    EfiTime.Day    = (UINT8)(CharToUint(mBiosReleaseDate[3])*10 +
> CharToUint(mBiosReleaseDate[4]));
> +    EfiTime.Month  = (UINT8)(CharToUint(mBiosReleaseDate[0])*10 +
> CharToUint(mBiosReleaseDate[1]));
> +    EfiTime.Year   = (UINT16)(CharToUint(mBiosReleaseDate[8])*10 +
> CharToUint(mBiosReleaseDate[9]) + 2000);
> +    EfiTime.Nanosecond  = 0;
> +    EfiTime.TimeZone = EFI_UNSPECIFIED_TIMEZONE;
> +    EfiTime.Daylight = 1;
> +
> +    DEBUG ((EFI_D_INFO, "Day:%d Month:%d Year:%d \n",
> (UINT32)EfiTime.Day, (UINT32)EfiTime.Month, (UINT32)EfiTime.Year));
> +
> +    //
> +    // Reset time value according to new RTC configuration
> +    //
> +    Status = gRT->SetTime (&EfiTime);
> +    ASSERT_EFI_ERROR(Status);
> +  }
> +
> +  return;
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c
> new file mode 100644
> index 0000000000..5d13e99443
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c
> @@ -0,0 +1,112 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +  SensorVar.c
> +
> +Abstract:
> +
> +  Initialization for the Sensor Info variable.
> +
> +Revision History
> +
> +--*/
> +
> +#include "PlatformDxe.h"
> +#include "Guid/SensorInfoVariable.h"
> +
> +//
> +// Sensor Information (board specific)
> +//
> +
> +#define TEMPERATURE_SENSORS_COUNT       4
> +#define VOLTAGE_SENSORS_COUNT           6
> +#define FAN_SENSORS_COUNT               4
> +#define FAN_CONTROLLERS_COUNT           3
> +
> +TYPEDEF_TEMP_SENSOR_SECTION(TEMPERATURE_SENSORS_COUNT);
> +TYPEDEF_VOLT_SENSOR_SECTION(VOLTAGE_SENSORS_COUNT);
> +TYPEDEF_FAN_SENSOR_SECTION(FAN_SENSORS_COUNT);
> +TYPEDEF_FAN_CONTROLLER_SECTION(FAN_CONTROLLERS_COUNT);
> +TYPEDEF_SENSOR_INFO_VAR;
> +
> +SENSOR_INFO_VAR               mSensorInfoData =
> +{
> +	  //
> +    // Temperature Sensors
> +    //
> +    TEMPERATURE_SENSORS_COUNT,
> +    {
> +        { 0, 3, CPU_CORE_TEMPERATURE,            TRUE  },
> +        { 0, 1, MOTHERBOARD_AMBIENT_TEMPERATURE, FALSE },
> +        { 0, 2, VR_TEMPERATURE,                  FALSE },
> +        { 0, 0, IOH_TEMPERATURE,                 FALSE }
> +    },
> +
> +    //
> +    // Voltage Sensors
> +    //
> +    VOLTAGE_SENSORS_COUNT,
> +    {
> +        { 0, 0, PLUS_12_VOLTS       },
> +        { 0, 1, PLUS_5_VOLTS        },
> +        { 0, 2, PLUS_3P3_VOLTS      },
> +        { 0, 3, MCH_VCC_VOLTAGE     },
> +        { 0, 4, CPU_1_VCCP_VOLTAGE  },
> +        { 0, 5, CPU_VTT_VOLTAGE     }
> +    },
> +
> +    //
> +    // Fan Speed Sensors
> +    //
> +    FAN_SENSORS_COUNT,
> +    {
> +        { 0, 0, CPU_COOLING_FAN,    FAN_4WIRE,         0 },
> +        { 0, 1, AUX_COOLING_FAN,    FAN_4WIRE,         1 },
> +        { 0, 2, CHASSIS_INLET_FAN,  FAN_3WIRE_VOLTAGE, 1 },
> +        { 0, 3, CHASSIS_OUTLET_FAN, FAN_3WIRE_VOLTAGE, 2 }
> +    },
> +
> +    //
> +    // Fan Speed Controllers
> +    //
> +    FAN_CONTROLLERS_COUNT,
> +    {
> +        { 0, 0, CPU_COOLING_FAN,     { 0, 0xff, 0xff, 0xff } },
> +        { 0, 1, CHASSIS_COOLING_FAN, { 1,    2, 0xff, 0xff } },
> +        { 0, 2, CHASSIS_COOLING_FAN, { 3, 0xff, 0xff, 0xff } }
> +    }
> +};
> +
> +/**
> +
> +  Write the Sensor Info variable if it does not already exist.
> +
> +**/
> +VOID
> +InitializeSensorInfoVariable (
> +  )
> +{
> +  //
> +  // Set the Sensor Info variable.  If it already exists and the data matches,
> +  // the variable driver will simply return without writing; otherwise, the
> +  // driver will write the variable.
> +  //
> +  gRT->SetVariable (
> +         gEfiSensorInfoVarNameWithPassword,
> +         &gEfiSensorInfoVarGuid,
> +         EFI_VARIABLE_NON_VOLATILE |
> +         EFI_VARIABLE_BOOTSERVICE_ACCESS |
> +         EFI_VARIABLE_RUNTIME_ACCESS,
> +         sizeof (SENSOR_INFO_VAR),
> +         &mSensorInfoData
> +         );
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SioPlatformPolicy.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SioPlatformPolicy.c
> new file mode 100644
> index 0000000000..32bee75f95
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SioPlatformPolicy.c
> @@ -0,0 +1,82 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +  SioPlatformPolicy.c
> +
> +Abstract:
> +
> +  Sio Platform Policy Setting.
> +
> +
> +--*/
> +
> +#include "PlatformDxe.h"
> +#include <Protocol/LpcWpc83627Policy.h>
> +
> +
> +EFI_WPC83627_POLICY_PROTOCOL  mSio83627PolicyData = {
> +  { EFI_WPC83627_COM1_ENABLE,       // Com1
> +    EFI_WPC83627_LPT1_ENABLE,       // Lpt1
> +    EFI_WPC83627_FDD_DISABLE,       // Floppy
> +    EFI_WPC83627_FDD_WRITE_ENABLE,  // FloppyWriteProtect
> +    EFI_WPC83627_RESERVED_DEFAULT,  // Port80
> +    EFI_WPC83627_ECIR_DISABLE,      // CIR
> +    EFI_WPC83627_PS2_KBC_ENABLE,    // Ps2Keyboard
> +    EFI_WPC83627_RESERVED_DEFAULT,  // Ps2Mouse
> +    EFI_WPC83627_COM2_ENABLE,       // Com2
> +    EFI_WPC83627_COM3_ENABLE,       // Com3
> +    EFI_WPC83627_COM4_ENABLE,       // Com4
> +    EFI_WPC83627_RESERVED_DEFAULT,  // Dac
> +    0x00                            // Rsvd
> +    },
> +  LptModeEcp,                       // LptMode
> +};
> +
> +/**
> +
> +  Publish the platform SIO policy setting.
> +
> +  @retval EFI_SUCCESS
> +
> +**/
> +VOID
> +InitSioPlatformPolicy(
> +  )
> +{
> +
> +  EFI_HANDLE              Handle;
> +  EFI_STATUS              Status;
> +
> +  Handle = NULL;
> +
> +  if((mSystemConfiguration.Serial) || (mBoardFeatures &
> B_BOARD_FEATURES_SIO_NO_COM1)) {
> +    mSio83627PolicyData.DeviceEnables.Com1 =
> EFI_WPC83627_COM1_DISABLE;
> +  }
> +
> +  if((mSystemConfiguration.Serial2) || ((mBoardFeatures &
> B_BOARD_FEATURES_SIO_COM2)==0)) {
> +    mSio83627PolicyData.DeviceEnables.Com2 =
> EFI_WPC83627_COM2_DISABLE;
> +  }
> +
> +  mSio83627PolicyData.LptMode = mSystemConfiguration.ParallelMode;
> +  if((!mSystemConfiguration.Parallel) || (mBoardFeatures &
> B_BOARD_FEATURES_SIO_NO_PARALLEL)) {
> +    mSio83627PolicyData.DeviceEnables.Lpt1 = EFI_WPC83627_LPT1_DISABLE;
> +  }
> +
> +  Status = gBS->InstallProtocolInterface (
> +                  &Handle,
> +                  &gEfiLpcWpc83627PolicyProtocolGuid,
> +                  EFI_NATIVE_INTERFACE,
> +                  &mSio83627PolicyData
> +                  );
> +  ASSERT_EFI_ERROR(Status);
> +
> +}
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.c
> new file mode 100644
> index 0000000000..f9b53ead95
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.c
> @@ -0,0 +1,148 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  SlotConfig.c
> +
> +Abstract:
> +
> +  Sets platform/SKU specific expansion slot information.
> +
> +
> +
> +--*/
> +#include "SlotConfig.h"
> +
> +//
> +// Implementation
> +//
> +VOID
> +InitializeSlotInfo (
> +  )
> +{
> +  UINT16                              BusSaveState;
> +  UINT16                              Vendor;
> +  UINT8                               CurrentBus;
> +  UINTN                               i;
> +  UINTN                               j;
> +  EFI_HANDLE                          Handle;
> +  EFI_STATUS                          Status;
> +  BOOLEAN                             RunNext;
> +
> +  //
> +  // Loop through the slot table and see if any slots have cards in them
> +  //
> +  for (i = 0; i < mSlotBridgeTableSize; i++) {
> +    //
> +    // Initialize variable
> +    //
> +    RunNext = FALSE;
> +
> +    //
> +    // Hide mini PCIe slots per SKU
> +    //
> +    for (j = 0; j < mSlotInformation.NumberOfEntries; j++) {
> +      if (mSlotInformation.SlotEntries[j].SmbiosSlotId ==
> mSlotBridgeTable[i].SmbiosSlotId) {
> +        if ((mSlotInformation.SlotEntries[j].SmbiosSlotId == 0x02) &&
> +            (mBoardFeatures & B_BOARD_FEATURES_NO_MINIPCIE)
> +          ) {
> +          mSlotInformation.SlotEntries[j].Disabled = TRUE;
> +          RunNext = TRUE;
> +        }
> +        break;
> +      }
> +    }
> +
> +    if (RunNext) {
> +      //
> +      // Skip slot device detection since the slot is disabled.
> +      //
> +      continue;
> +    }
> +
> +    //
> +    // Check to see if the bridge has a bus number and assign one if not
> +    //
> +    BusSaveState = MmPci16 (
> +      0,
> +      mSlotBridgeTable[i].Bus,
> +      mSlotBridgeTable[i].Dev,
> +      mSlotBridgeTable[i].Function,
> +      PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET
> +                            );
> +    if (BusSaveState == 0) {
> +      //
> +      // Assign temp bus number
> +      //
> +      MmPci16 (
> +        0,
> +        mSlotBridgeTable[i].Bus,
> +        mSlotBridgeTable[i].Dev,
> +        mSlotBridgeTable[i].Function,
> +        PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET
> +        ) = DEF_BUS_CONFIG;
> +      CurrentBus = DEF_BUS;
> +    } else if (BusSaveState == 0xFFFF) {
> +      //
> +      // Bridge is disabled so continue with next entry in the table
> +      //
> +      continue;
> +    } else {
> +      //
> +      // Use existing bus number
> +      //
> +      CurrentBus = (UINT8) BusSaveState & 0xFF;
> +    }
> +
> +    //
> +    // Check to see if a device is behind the bridge
> +    //
> +    Vendor = MmPci16 (
> +               0,
> +               CurrentBus,
> +               mSlotBridgeTable[i].TargetDevice,
> +               0,
> +               0
> +               );
> +    if (Vendor != 0xFFFF) {
> +      //
> +      // Device found so make sure the slot is marked that way
> +      //
> +      for (j = 0; j < mSlotInformation.NumberOfEntries; j++) {
> +        if (mSlotInformation.SlotEntries[j].SmbiosSlotId ==
> mSlotBridgeTable[i].SmbiosSlotId) {
> +          mSlotInformation.SlotEntries[j].InUse = TRUE;
> +          break;
> +        }
> +      }
> +    }
> +
> +    //
> +    // Restore previous bus information
> +    //
> +    if (BusSaveState == 0) {
> +      MmPci16 (
> +        0,
> +        mSlotBridgeTable[i].Bus,
> +        mSlotBridgeTable[i].Dev,
> +        mSlotBridgeTable[i].Function,
> +        PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET
> +        ) = 0;
> +    }
> +  }
> +
> +  Handle = NULL;
> +  Status = gBS->InstallProtocolInterface (
> +                  &Handle,
> +                  &gEfiSmbiosSlotPopulationGuid,
> +                  EFI_NATIVE_INTERFACE,
> +                  &mSlotInformation
> +                  );
> +  ASSERT_EFI_ERROR(Status);
> +
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.h
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.h
> new file mode 100644
> index 0000000000..738798261b
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.h
> @@ -0,0 +1,80 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  SlotConfig.c
> +
> +Abstract:
> +
> +  Sets platform/SKU specific expansion slot information.
> +
> +
> +
> +
> +--*/
> +
> +#include "PlatformDxe.h"
> +#include <Protocol/SmbiosSlotPopulation.h>
> +#include <IndustryStandard/Pci22.h>
> +
> +
> +//
> +// Default bus number for the bridge
> +//
> +#define DEF_BUS_CONFIG  0x0101
> +#define DEF_BUS         0x01
> +
> +//
> +// Data structures for slot information
> +//
> +typedef struct {
> +  UINT16  SmbiosSlotId;
> +  UINT8   Bus;
> +  UINT8   Dev;
> +  UINT8   Function;
> +  UINT8   TargetDevice;
> +} EFI_PCI_SLOT_BRIDGE_INFO;
> +
> +//
> +// Product specific bridge to slot routing information
> +//
> +EFI_PCI_SLOT_BRIDGE_INFO mSlotBridgeTable[] = {
> +  {
> +    0x01,             //PCIe x1 ICH (Bridge B0:D28:F1)
> +    DEFAULT_PCI_BUS_NUMBER_PCH,
> +    PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
> +    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2,
> +    0
> +  }
> +};
> +
> +UINTN mSlotBridgeTableSize =
> +  sizeof(mSlotBridgeTable) / sizeof(EFI_PCI_SLOT_BRIDGE_INFO);
> +
> +//
> +// Slot entry table for IBX RVP
> +//
> +EFI_SMBIOS_SLOT_ENTRY mSlotEntries[] = {
> +  {0x06, FALSE, TRUE},    // PCIe x16 Slot 1 (NOT USED)
> +  {0x04, FALSE, TRUE},    // PCIe x16 Slot 2 (NOT USED)
> +  {0x03, FALSE, TRUE},    // PCIe x4 Slot (NOT USED)
> +  {0x02, FALSE, FALSE},   // Mini PCIe x1 Slot
> +  {0x15, FALSE, TRUE},    // PCIe x1 Slot 2 (NOT USED)
> +  {0x16, FALSE, TRUE},    // PCIe x1 Slot 3 (NOT USED)
> +  {0x07, FALSE, FALSE},   // PCI Slot 1
> +  {0x18, FALSE, TRUE},    // PCI Slot 2 (NOT USED)
> +  {0x17, FALSE, TRUE},    // PCI Slot 3 (NOT USED)
> +};
> +
> +EFI_SMBIOS_SLOT_POPULATION_INFO mSlotInformation = {
> +  sizeof(mSlotEntries) / sizeof(EFI_SMBIOS_SLOT_ENTRY),
> +  mSlotEntries
> +};
> +
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.c
> new file mode 100644
> index 0000000000..3900603d68
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.c
> @@ -0,0 +1,201 @@
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +--*/
> +
> +/** @file
> +**/
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Protocol/FirmwareVolume2.h>
> +#include <Protocol/PlatformGopPolicy.h>
> +
> +#include <Guid/SetupVariable.h>
> +#include <SetupMode.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +
> +PLATFORM_GOP_POLICY_PROTOCOL  mPlatformGOPPolicy;
> +
> +//
> +// Function implementations
> +//
> +
> +/**
> +  The function will execute with as the platform policy, and gives
> +  the Platform Lid Status. IBV/OEM can customize this code for their specific
> +  policy action.
> +
> +  @param CurrentLidStatus  Gives the current LID Status
> +
> +  @retval EFI_SUCCESS.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetPlatformLidStatus (
> +   OUT LID_STATUS *CurrentLidStatus
> +)
> +{
> +  *CurrentLidStatus = LidOpen;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  The function will execute and gives the Video Bios Table Size and Address.
> +
> +  @param VbtAddress  Gives the Physical Address of Video BIOS Table
> +
> +  @param VbtSize     Gives the Size of Video BIOS Table
> +
> +  @retval EFI_STATUS.
> +
> +**/
> +
> +EFI_STATUS
> +EFIAPI
> +GetVbtData (
> +   OUT EFI_PHYSICAL_ADDRESS *VbtAddress,
> +   OUT UINT32 *VbtSize
> +)
> +{
> +  EFI_STATUS                    Status;
> +  UINTN                         FvProtocolCount;
> +  EFI_HANDLE                    *FvHandles;
> +  EFI_FIRMWARE_VOLUME2_PROTOCOL  *Fv;
> +  UINTN                         Index;
> +  UINT32                        AuthenticationStatus;
> +
> +  UINT8                         *Buffer;
> +  UINTN                         VbtBufferSize;
> +
> +  Buffer = 0;
> +  FvHandles       = NULL;
> +
> +  if (VbtAddress == NULL || VbtSize == NULL){
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gEfiFirmwareVolume2ProtocolGuid,
> +                  NULL,
> +                  &FvProtocolCount,
> +                  &FvHandles
> +                  );
> +
> +  if (!EFI_ERROR (Status)) {
> +    for (Index = 0; Index < FvProtocolCount; Index++) {
> +      Status = gBS->HandleProtocol (
> +                      FvHandles[Index],
> +                      &gEfiFirmwareVolume2ProtocolGuid,
> +                      (VOID **) &Fv
> +                      );
> +      VbtBufferSize = 0;
> +      Status = Fv->ReadSection (
> +                     Fv,
> +                     &gBmpImageGuid,
> +                     EFI_SECTION_RAW,
> +                     0,
> +                    (void **)&Buffer,
> +                     &VbtBufferSize,
> +                     &AuthenticationStatus
> +                     );
> +
> +      if (!EFI_ERROR (Status)) {
> +        *VbtAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
> +        *VbtSize = (UINT32)VbtBufferSize;
> +        Status = EFI_SUCCESS;
> +        break;
> +      }
> +    }
> +  } else {
> +    Status = EFI_NOT_FOUND;
> +  }
> +
> +  if (FvHandles != NULL) {
> +    gBS->FreePool (FvHandles);
> +    FvHandles = NULL;
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  Entry point for the Platform GOP Policy Driver.
> +
> +  @param ImageHandle       Image handle of this driver.
> +  @param SystemTable       Global system service table.
> +
> +  @retval EFI_SUCCESS           Initialization complete.
> +  @retval EFI_OUT_OF_RESOURCES  Do not have enough resources to
> initialize the driver.
> +
> +**/
> +
> +EFI_STATUS
> +EFIAPI
> +PlatformGOPPolicyEntryPoint (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +
> +{
> +  EFI_STATUS  Status = EFI_SUCCESS;
> +  SYSTEM_CONFIGURATION          SystemConfiguration;
> +  UINTN       VarSize;
> +
> +
> +  gBS = SystemTable->BootServices;
> +
> +  gBS->SetMem (
> +         &mPlatformGOPPolicy,
> +         sizeof (PLATFORM_GOP_POLICY_PROTOCOL),
> +         0
> +         );
> +
> +  mPlatformGOPPolicy.Revision                =
> PLATFORM_GOP_POLICY_PROTOCOL_REVISION_01;
> +  mPlatformGOPPolicy.GetPlatformLidStatus    = GetPlatformLidStatus;
> +  mPlatformGOPPolicy.GetVbtData              = GetVbtData;
> +
> +  //
> +  // Install protocol to allow access to this Policy.
> +  //
> +  VarSize = sizeof(SYSTEM_CONFIGURATION);
> +  Status = gRT->GetVariable(
> +                  L"Setup",
> +                  &gEfiNormalSetupGuid,
> +                  NULL,
> +                  &VarSize,
> +                  &SystemConfiguration
> +                  );
> +  if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
> +    //The setup variable is corrupted
> +    VarSize = sizeof(SYSTEM_CONFIGURATION);
> +    Status = gRT->GetVariable(
> +              L"SetupRecovery",
> +              &gEfiNormalSetupGuid,
> +              NULL,
> +              &VarSize,
> +              &SystemConfiguration
> +              );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +  if (SystemConfiguration.GOPEnable == 1)
> +  {
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &ImageHandle,
> +                  &gPlatformGOPPolicyGuid,
> +                  &mPlatformGOPPolicy,
> +                  NULL
> +                  );
> +  }
> +
> +  return Status;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.i
> nf
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.i
> nf
> new file mode 100644
> index 0000000000..948793f719
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.i
> nf
> @@ -0,0 +1,51 @@
> +#
> +#
> +# Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +#
> +#
> +##
> +
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = PlatformGOPPolicy
> +  FILE_GUID                      = 9737D7CA-D869-45e5-A5EF-75D9438688DE
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = PlatformGOPPolicyEntryPoint
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32
> +#
> +
> +[Sources.common]
> +  PlatformGopPolicy.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  IntelFrameworkPkg/IntelFrameworkPkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +  UefiDriverEntryPoint
> +  UefiRuntimeServicesTableLib
> +#  DxeKscLib
> +
> +[Guids]
> +  gBmpImageGuid
> +  gEfiNormalSetupGuid
> +
> +[Protocols]
> +  gEfiCpuIoProtocolGuid
> +  gEfiFirmwareVolume2ProtocolGuid
> +  gPlatformGOPPolicyGuid
> +
> +[Depex]
> +  gEfiCpuIoProtocolGuid AND gEfiVariableArchProtocolGuid
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.c
> new file mode 100644
> index 0000000000..fc784034cd
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.c
> @@ -0,0 +1,169 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  PlatformInfoDxe.c
> +
> +Abstract:
> +  Platform Info driver to public platform related HOB data
> +
> +--*/
> +
> +#include "PlatformInfoDxe.h"
> +
> +/**
> +  Entry point for the driver.
> +
> +  This routine get the platform HOB data from PEI and publish
> +  as Platform Info variable that can be accessed during boot service and
> +  runtime.
> +
> +  @param ImageHandle    Image Handle.
> +  @param SystemTable    EFI System Table.
> +
> +  @retval Status        Function execution status.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +PlatformInfoInit (
> +  IN EFI_HANDLE                         ImageHandle,
> +  IN EFI_SYSTEM_TABLE                   *SystemTable
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_PLATFORM_INFO_HOB       *PlatformInfoHobPtr;
> +  EFI_PEI_HOB_POINTERS        GuidHob;
> +  EFI_PLATFORM_INFO_HOB       TmpHob;
> +  UINTN                       VarSize;
> +  EFI_OS_SELECTION_HOB        *OsSlectionHobPtr;
> +  UINT8                       Selection;
> +  SYSTEM_CONFIGURATION        SystemConfiguration;
> +  UINT8                       *LpssDataHobPtr;
> +  UINT8                       *LpssDataVarPtr;
> +  UINTN                       i;
> +
> +  VarSize = sizeof(SYSTEM_CONFIGURATION);
> +  Status = gRT->GetVariable(
> +                  NORMAL_SETUP_NAME,
> +                  &gEfiNormalSetupGuid,
> +                  NULL,
> +                  &VarSize,
> +                  &SystemConfiguration
> +                  );
> +
> +  if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
> +    //The setup variable is corrupted
> +    VarSize = sizeof(SYSTEM_CONFIGURATION);
> +    Status = gRT->GetVariable(
> +              L"SetupRecovery",
> +              &gEfiNormalSetupGuid,
> +              NULL,
> +              &VarSize,
> +              &SystemConfiguration
> +              );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +  VarSize = sizeof(Selection);
> +  Status = gRT->GetVariable(
> +                  L"OsSelection",
> +                  &gOsSelectionVariableGuid,
> +                  NULL,
> +                  &VarSize,
> +                  &Selection
> +                  );
> +
> +  if (EFI_ERROR(Status)) {
> +    Selection = SystemConfiguration.ReservedO;
> +    Status = gRT->SetVariable (
> +                    L"OsSelection",
> +                    &gOsSelectionVariableGuid,
> +                    EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
> +                    sizeof(Selection),
> +                    &Selection
> +                    );
> +  }
> +
> +  GuidHob.Raw = GetHobList ();
> +  if (GuidHob.Raw != NULL) {
> +    if ((GuidHob.Raw = GetNextGuidHob (&gOsSelectionVariableGuid,
> GuidHob.Raw)) != NULL) {
> +      OsSlectionHobPtr = GET_GUID_HOB_DATA (GuidHob.Guid);
> +
> +      if (OsSlectionHobPtr->OsSelectionChanged) {
> +        SystemConfiguration.ReservedO = OsSlectionHobPtr->OsSelection;
> +
> +        //
> +        // Load Audio default configuration
> +        //
> +        SystemConfiguration.Lpe         = OsSlectionHobPtr->Lpe;
> +        SystemConfiguration.PchAzalia   = OsSlectionHobPtr->PchAzalia;
> +
> +        //
> +        // Load LPSS and SCC default configurations
> +        //
> +        LpssDataHobPtr = &OsSlectionHobPtr->LpssData.LpssPciModeEnabled;
> +        LpssDataVarPtr = &SystemConfiguration.LpssPciModeEnabled;
> +        for (i = 0; i < sizeof(EFI_PLATFORM_LPSS_DATA); i++) {
> +          *LpssDataVarPtr = *LpssDataHobPtr;
> +          LpssDataVarPtr++;
> +          LpssDataHobPtr++;
> +        }
> +
> +        SystemConfiguration.GOPEnable = TRUE;
> +
> +        Status = gRT->SetVariable (
> +                        NORMAL_SETUP_NAME,
> +                        &gEfiNormalSetupGuid,
> +                        EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_NON_VOLATILE,
> +                        sizeof(SYSTEM_CONFIGURATION),
> +                        &SystemConfiguration
> +                        );
> +        ASSERT_EFI_ERROR (Status);
> +      }
> +    }
> +  }
> +
> +  GuidHob.Raw = GetHobList ();
> +  if (GuidHob.Raw == NULL) {
> +  	return EFI_NOT_FOUND;
> +  }
> +
> +  if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformInfoGuid,
> GuidHob.Raw)) != NULL) {
> +    PlatformInfoHobPtr = GET_GUID_HOB_DATA (GuidHob.Guid);
> +    VarSize = sizeof(EFI_PLATFORM_INFO_HOB);
> +    Status = gRT->GetVariable(
> +                    L"PlatformInfo",
> +                    &gEfiVlv2VariableGuid,
> +                    NULL,
> +                    &VarSize,
> +                    &TmpHob
> +                    );
> +
> +    if (EFI_ERROR(Status) || CompareMem (&TmpHob, PlatformInfoHobPtr,
> VarSize)) {
> +
> +      //
> +      // Write the Platform Info to volatile memory
> +      //
> +      Status = gRT->SetVariable(
> +                      L"PlatformInfo",
> +                      &gEfiVlv2VariableGuid,
> +                      EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_NON_VOLATILE,
> +                      sizeof(EFI_PLATFORM_INFO_HOB),
> +                      PlatformInfoHobPtr
> +                      );
> +      if (EFI_ERROR(Status)) {
> +        return Status;
> +      }
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.h
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.h
> new file mode 100644
> index 0000000000..615b32bb08
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.h
> @@ -0,0 +1,30 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +  PlatformInfoDxe.h
> +
> +Abstract:
> +  Platform Info Driver.
> +
> +--*/
> +
> +#ifndef _PLATFORM_INFO_DRIVER_H_
> +#define _PLATFORM_INFO_DRIVER_H_
> +
> +#include <PiDxe.h>
> +#include <Library/HobLib.h>
> +#include <Guid/PlatformInfo.h>
> +#include <Guid/GlobalVariable.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Guid/Vlv2Variable.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <SetupMode.h>
> +#include <Guid/OsSelection.h>
> +#include <Guid/SetupVariable.h>
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.inf
> new file mode 100644
> index 0000000000..ae3c2bf41b
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.inf
> @@ -0,0 +1,52 @@
> +#
> +#
> +# Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +#
> +#
> +#  Module Name:
> +#
> +#   PlatformInfoDxe.inf
> +#
> +#  Abstract:
> +#
> +#
> +--*/
> +
> +
> +[defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = PlatformInfoDxe
> +  FILE_GUID                      = 025F738B-4EBD-4d55-B728-5F421B601F1F
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = PlatformInfoInit
> +
> +[sources]
> +  PlatformInfoDxe.c
> +  PlatformInfoDxe.h
> +
> +[Guids]
> +  gEfiAcpiVariableGuid                     # ALWAYS_CONSUMED
> +  gEfiPlatformInfoGuid                     # ALWAYS_CONSUMED
> +  gEfiVlv2VariableGuid
> +  gEfiNormalSetupGuid
> +  gOsSelectionVariableGuid
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +
> +[LibraryClasses]
> +  HobLib
> +  UefiRuntimeServicesTableLib
> +  UefiDriverEntryPoint
> +  BaseMemoryLib
> +
> +[Depex]
> +  gEfiVariableArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/BootMode.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/BootMode.c
> new file mode 100644
> index 0000000000..c906562c7e
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/BootMode.c
> @@ -0,0 +1,434 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +  BootMode.c
> +
> +Abstract:
> +
> +  EFI PEIM to provide the platform support functionality on the Thurley.
> +
> +
> +--*/
> +
> +#include "PlatformEarlyInit.h"
> +
> +
> +#define NORMALMODE        0
> +#define RECOVERYMODE      1
> +#define SAFEMODE          2
> +#define MANUFACTURINGMODE 3
> +
> +#define GPIO_SSUS_OFFSET    0x2000
> +#define PMU_PWRBTN_B_OFFSET 0x88
> +
> +EFI_PEI_PPI_DESCRIPTOR  mPpiListRecoveryBootMode = {
> +  (EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> +  &gEfiPeiBootInRecoveryModePpiGuid,
> +  NULL
> +};
> +
> +/**
> +  Return the setting of the Bios configuration jumper
> +
> +  @param  VOID
> +
> +  @retval RECOVERYMODE       jumper set to recovery mode
> +  @retval SAFEMODE           jumper set to config mode
> +  @retval NORMALMODE         jumper in normal mode
> +
> +**/
> +UINTN
> +GetConfigJumper(
> +    IN CONST EFI_PEI_SERVICES           **PeiServices,
> +    IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
> + )
> +{
> +  //
> +  // Do the Forced recovery detection based on logic chart above
> +  //
> +  if (IsRecoveryJumper(PeiServices, PlatformInfoHob)) {
> +    return RECOVERYMODE;
> +  } else {
> +    return NORMALMODE;
> +  }
> +}
> +
> +BOOLEAN
> +CheckIfRecoveryMode(
> +  IN CONST EFI_PEI_SERVICES           **PeiServices,
> +  IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
> + )
> +{
> +  if (GetConfigJumper(PeiServices, PlatformInfoHob) == RECOVERYMODE) {
> +    return TRUE;
> +  }
> +  return FALSE;
> +}
> +
> +BOOLEAN
> +CheckIfSafeMode(
> +  IN CONST EFI_PEI_SERVICES           **PeiServices,
> +  IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
> + )
> +{
> +  if (GetConfigJumper(PeiServices, PlatformInfoHob) == SAFEMODE) {
> +    return TRUE;
> +  }
> +  return FALSE;
> +}
> +
> +BOOLEAN
> +CheckIfManufacturingMode (
> +  IN CONST EFI_PEI_SERVICES  **PeiServices
> + )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_PEI_READ_ONLY_VARIABLE2_PPI  *Variable;
> +  UINT32                      Attributes;
> +  UINTN                       DataSize;
> +  CHAR16                      VarName[] = MFGMODE_VARIABLE_NAME;
> +  UINT8                       MfgMode;
> +
> +  Status = (*PeiServices)->LocatePpi (
> +                             PeiServices,
> +                             &gEfiPeiReadOnlyVariable2PpiGuid,
> +                             0,
> +                             NULL,
> +                             (void **)&Variable
> +                             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Check if SW MMJ mode
> +  //
> +  Attributes = (EFI_VARIABLE_NON_VOLATILE |
> EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS);
> +  DataSize = sizeof (MFG_MODE_VAR);
> +
> +  Status = Variable->GetVariable (
> +                       Variable,
> +                       VarName,
> +                       &gMfgModeVariableGuid,
> +                       &Attributes,
> +                       &DataSize,
> +                       &MfgMode
> +                       );
> +  if (!(EFI_ERROR (Status))) {
> +    return TRUE;
> +  }
> +  return FALSE;
> +}
> +
> +EFI_STATUS
> +UpdateBootMode (
> +  IN CONST EFI_PEI_SERVICES                       **PeiServices,
> +  IN OUT EFI_PLATFORM_INFO_HOB                    *PlatformInfoHob
> +  )
> +{
> +  EFI_STATUS                        Status;
> +  EFI_BOOT_MODE                     BootMode;
> +  UINT16                            SleepType;
> +  CHAR16                            *strBootMode;
> +  PEI_CAPSULE_PPI                   *Capsule;
> +  EFI_PEI_READ_ONLY_VARIABLE2_PPI   *Variable;
> +  SYSTEM_CONFIGURATION              SystemConfiguration;
> +  UINTN                             VarSize;
> +  volatile UINT32                   GpioValue;
> +  BOOLEAN                           IsFirstBoot;
> +  UINT32                            Data32;
> +
> +  Status = (*PeiServices)->GetBootMode(
> +                             PeiServices,
> +                             &BootMode
> +                             );
> +  ASSERT_EFI_ERROR (Status);
> +  if (BootMode  == BOOT_IN_RECOVERY_MODE){
> +    return Status;
> +  }
> +  GetWakeupEventAndSaveToHob (PeiServices);
> +
> +  //
> +  // Let's assume things are OK if not told otherwise
> +  //
> +  BootMode = BOOT_WITH_FULL_CONFIGURATION;
> +
> +  //
> +  // When this boot is WDT reset, the system needs booting with
> CrashDump function eanbled.
> +  //
> +  Data32 = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_TCO_STS);
> +
> +  //
> +  // Check Power Button, click the power button, the system will boot in fast
> boot mode,
> +  // if it is pressed and hold for a second, it will boot in
> FullConfiguration/setup mode.
> +  //
> +  GpioValue = MmioRead32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET +
> PMU_PWRBTN_B_OFFSET);    // The value of GPIOS_16 (PMU_PWRBTN_B)
> +  if (((GpioValue & BIT0) != 0)&&((Data32 &
> B_PCH_TCO_STS_SECOND_TO) != B_PCH_TCO_STS_SECOND_TO)){
> +    IsFirstBoot = PcdGetBool(PcdBootState);
> +    if (!IsFirstBoot){
> +      VarSize = sizeof (SYSTEM_CONFIGURATION);
> +      ZeroMem (&SystemConfiguration, sizeof (SYSTEM_CONFIGURATION));
> +
> +      Status = (*PeiServices)->LocatePpi (
> +                                 PeiServices,
> +                                 &gEfiPeiReadOnlyVariable2PpiGuid,
> +                                 0,
> +                                 NULL,
> +                                          (void **)&Variable
> +                                 );
> +      ASSERT_EFI_ERROR (Status);
> +
> +      //
> +      // Use normal setup default from NVRAM variable,
> +      // the Platform Mode (manufacturing/safe/normal) is handle in
> PeiGetVariable.
> +      //
> +      VarSize = sizeof(SYSTEM_CONFIGURATION);
> +      Status = Variable->GetVariable (
> +                           Variable,
> +                           L"Setup",
> +                           &gEfiSetupVariableGuid,
> +                           NULL,
> +                           &VarSize,
> +                           &SystemConfiguration
> +                           );
> +      if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
> +        //The setup variable is corrupted
> +        VarSize = sizeof(SYSTEM_CONFIGURATION);
> +        Status = Variable->GetVariable(
> +                  Variable,
> +                  L"SetupRecovery",
> +                  &gEfiSetupVariableGuid,
> +                  NULL,
> +                  &VarSize,
> +                  &SystemConfiguration
> +                  );
> +        ASSERT_EFI_ERROR (Status);
> +      }
> +
> +      if (SystemConfiguration.FastBoot == 1) {
> +            BootMode = BOOT_WITH_MINIMAL_CONFIGURATION;
> +      }
> +    }
> +  }
> +
> +  //
> +  // Check if we need to boot in forced recovery mode
> +  //
> +  if (CheckIfRecoveryMode(PeiServices, PlatformInfoHob)) {
> +    BootMode  = BOOT_IN_RECOVERY_MODE;
> +  }
> +
> +  if (BootMode  == BOOT_IN_RECOVERY_MODE) {
> +    Status = (*PeiServices)->InstallPpi (
> +                               PeiServices,
> +                               &mPpiListRecoveryBootMode
> +                               );
> +    ASSERT_EFI_ERROR (Status);
> +  } else {
> +    if (GetSleepTypeAfterWakeup (PeiServices, &SleepType)) {
> +      switch (SleepType) {
> +        case V_PCH_ACPI_PM1_CNT_S3:
> +          BootMode = BOOT_ON_S3_RESUME;
> +
> +          //
> +          // Determine if we're in capsule update mode
> +          //
> +          Status = (*PeiServices)->LocatePpi (
> +                                     PeiServices,
> +                                     &gPeiCapsulePpiGuid,
> +                                     0,
> +                                     NULL,
> +                                     (void **)&Capsule
> +                                     );
> +
> +          if (Status == EFI_SUCCESS) {
> +            if (Capsule->CheckCapsuleUpdate ((EFI_PEI_SERVICES**)PeiServices)
> == EFI_SUCCESS) {
> +              BootMode = BOOT_ON_FLASH_UPDATE;
> +            }
> +          }
> +
> +          break;
> +
> +        case V_PCH_ACPI_PM1_CNT_S4:
> +          BootMode = BOOT_ON_S4_RESUME;
> +          break;
> +
> +        case V_PCH_ACPI_PM1_CNT_S5:
> +          BootMode = BOOT_ON_S5_RESUME;
> +          break;
> +      } // switch (SleepType)
> +    }
> +
> +    //
> +    // Check for Safe Mode
> +    //
> +  }
> +
> +  switch (BootMode) {
> +    case BOOT_WITH_FULL_CONFIGURATION:
> +      strBootMode = L"BOOT_WITH_FULL_CONFIGURATION";
> +      break;
> +    case BOOT_WITH_MINIMAL_CONFIGURATION:
> +      strBootMode = L"BOOT_WITH_MINIMAL_CONFIGURATION";
> +      break;
> +    case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
> +      strBootMode = L"BOOT_ASSUMING_NO_CONFIGURATION_CHANGES";
> +      break;
> +    case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:
> +      strBootMode =
> L"BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS";
> +      break;
> +    case BOOT_WITH_DEFAULT_SETTINGS:
> +      strBootMode = L"BOOT_WITH_DEFAULT_SETTINGS";
> +      break;
> +    case BOOT_ON_S4_RESUME:
> +      strBootMode = L"BOOT_ON_S4_RESUME";
> +      break;
> +    case BOOT_ON_S5_RESUME:
> +      strBootMode = L"BOOT_ON_S5_RESUME";
> +      break;
> +    case BOOT_ON_S2_RESUME:
> +      strBootMode = L"BOOT_ON_S2_RESUME";
> +      break;
> +    case BOOT_ON_S3_RESUME:
> +      strBootMode = L"BOOT_ON_S3_RESUME";
> +      break;
> +    case BOOT_ON_FLASH_UPDATE:
> +      strBootMode = L"BOOT_ON_FLASH_UPDATE";
> +      break;
> +    case BOOT_IN_RECOVERY_MODE:
> +      strBootMode = L"BOOT_IN_RECOVERY_MODE";
> +      break;
> +    default:
> +      strBootMode = L"Unknown boot mode";
> +  } // switch (BootMode)
> +
> +  DEBUG ((EFI_D_ERROR, "Setting BootMode to %s\n", strBootMode));
> +  Status = (*PeiServices)->SetBootMode(
> +                             PeiServices,
> +                             BootMode
> +                             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> +/**
> +  Get sleep type after wakeup
> +
> +  @param PeiServices        Pointer to the PEI Service Table.
> +  @param SleepType          Sleep type to be returned.
> +
> +  @retval TRUE              A wake event occured without power failure.
> +  @retval FALSE             Power failure occured or not a wakeup.
> +
> +**/
> +BOOLEAN
> +GetSleepTypeAfterWakeup (
> +  IN  CONST EFI_PEI_SERVICES          **PeiServices,
> +  OUT UINT16                    *SleepType
> +  )
> +{
> +  UINT16  Pm1Sts;
> +  UINT16  Pm1Cnt;
> +  UINT16  GenPmCon1;
> +  GenPmCon1 = MmioRead16 (PMC_BASE_ADDRESS +
> R_PCH_PMC_GEN_PMCON_1);
> +
> +  //
> +  // Read the ACPI registers
> +  //
> +  Pm1Sts  = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS);
> +  Pm1Cnt  = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT);
> +
> +  if ((GenPmCon1 & (B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR |
> B_PCH_PMC_GEN_PMCON_GEN_RST_STS)) ||
> +     (Pm1Sts & B_PCH_ACPI_PM1_STS_PRBTNOR)) {
> +    //
> +    // If power failure indicator, then don't attempt s3 resume.
> +    // Clear PM1_CNT of S3 and set it to S5 as we just had a power failure, and
> memory has
> +    // lost already.  This is to make sure no one will use PM1_CNT to check for
> S3 after
> +    // power failure.
> +    //
> +    if ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) ==
> V_PCH_ACPI_PM1_CNT_S3) {
> +      Pm1Cnt = ((Pm1Cnt & ~B_PCH_ACPI_PM1_CNT_SLP_TYP) |
> V_PCH_ACPI_PM1_CNT_S5);
> +      IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT, Pm1Cnt);
> +    }
> +    //
> +    // Clear Wake Status (WAK_STS)
> +    //
> +    IoWrite16 ((ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS),
> B_PCH_ACPI_PM1_STS_WAK);
> +   }
> +  //
> +  // Get sleep type if a wake event occurred and there is no power failure
> +  //
> +  if ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) ==
> V_PCH_ACPI_PM1_CNT_S3) {
> +    *SleepType = Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP;
> +    return TRUE;
> +  } else if ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) ==
> V_PCH_ACPI_PM1_CNT_S4){
> +    *SleepType = Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP;
> +    return TRUE;
> +  }
> +  return FALSE;
> +}
> +
> +VOID
> +SetPlatformBootMode (
> +  IN CONST EFI_PEI_SERVICES             **PeiServices,
> +  IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
> +  )
> +{
> +  EFI_PLATFORM_SETUP_ID       PlatformSetupId;
> +
> +  ZeroMem(&PlatformSetupId, sizeof (EFI_PLATFORM_SETUP_ID));
> +
> +  CopyMem (&PlatformSetupId.SetupGuid,
> +           &gEfiNormalSetupGuid,
> +           sizeof (EFI_GUID));
> +
> +  if (CheckIfRecoveryMode(PeiServices, PlatformInfoHob)) {
> +    //
> +    // Recovery mode
> +    //
> +    CopyMem (&PlatformSetupId.SetupName,
> +             &NORMAL_SETUP_NAME,
> +             StrSize (NORMAL_SETUP_NAME));
> +    PlatformSetupId.PlatformBootMode = PLATFORM_RECOVERY_MODE;
> +  } else if (CheckIfSafeMode(PeiServices, PlatformInfoHob)) {
> +    //
> +    // Safe mode also called config mode or maintenace mode.
> +    //
> +    CopyMem (&PlatformSetupId.SetupName,
> +             &NORMAL_SETUP_NAME,
> +             StrSize (NORMAL_SETUP_NAME));
> +    PlatformSetupId.PlatformBootMode = PLATFORM_SAFE_MODE;
> +
> +  } else if(0) { // else if (CheckIfManufacturingMode(PeiServices)) {
> +    //
> +    // Manufacturing mode
> +    //
> +    CopyMem (&PlatformSetupId.SetupName,
> +             MANUFACTURE_SETUP_NAME,
> +             StrSize (MANUFACTURE_SETUP_NAME));
> +    PlatformSetupId.PlatformBootMode =
> PLATFORM_MANUFACTURING_MODE;
> +
> +  } else {
> +    //
> +    // Default to normal mode.
> +    //
> +    CopyMem (&PlatformSetupId.SetupName,
> +             &NORMAL_SETUP_NAME,
> +             StrSize (NORMAL_SETUP_NAME));
> +    PlatformSetupId.PlatformBootMode = PLATFORM_NORMAL_MODE;
> +  }
> +
> +  BuildGuidDataHob (
> +    &gEfiPlatformBootModeGuid,
> +    &PlatformSetupId,
> +    sizeof (EFI_PLATFORM_SETUP_ID)
> +    );
> +  return;
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/CpuInitPeim.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/CpuInitPeim.c
> new file mode 100644
> index 0000000000..a3a3d5cbc9
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/CpuInitPeim.c
> @@ -0,0 +1,44 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +    CpuInitPeim.c
> +
> +Abstract:
> +
> +    Functions for LpcSio initilization
> +    It is needed for early onboard LAN controller disable/enable in platform
> setup.
> +
> +--*/
> +
> +#include "PlatformEarlyInit.h"
> +
> +
> +EFI_STATUS
> +PlatformCpuInit (
> +  IN CONST EFI_PEI_SERVICES            **PeiServices,
> +  IN SYSTEM_CONFIGURATION        *SystemConfiguration,
> +  IN EFI_PLATFORM_CPU_INFO       *PlatformCpuInfo
> +  )
> +{
> +  BOOLEAN                     ResetRequired;
> +
> +  //
> +  // Variable initialization
> +  //
> +  ResetRequired = FALSE;
> +
> +
> +  if (ResetRequired) {
> +    CpuOnlyReset(PeiServices);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c
> new file mode 100644
> index 0000000000..3fda6313d0
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c
> @@ -0,0 +1,319 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +  Dimm.c
> +
> +Abstract:
> +
> +  PPI for reading SPD modules on DIMMs.
> +
> +--*/
> +
> +
> +//
> +// Header Files
> +//
> +#include "Platformearlyinit.h"
> +
> +#define DIMM_SOCKETS     4  // Total number of DIMM sockets allowed on
> +                            //   the platform
> +#define DIMM_SEGMENTS    1  // Total number of Segments Per DIMM.
> +#define MEMORY_CHANNELS  2  // Total number of memory channels
> +                            //   populated on the system board
> +//
> +// Prototypes
> +//
> +
> +EFI_STATUS
> +EFIAPI
> +GetDimmState (
> +  IN      EFI_PEI_SERVICES        **PeiServices,
> +  IN      PEI_PLATFORM_DIMM_PPI   *This,
> +  IN      UINT8                   Dimm,
> +  OUT     PEI_PLATFORM_DIMM_STATE *State
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +SetDimmState (
> +  IN      EFI_PEI_SERVICES        **PeiServices,
> +  IN      PEI_PLATFORM_DIMM_PPI   *This,
> +  IN      UINT8                   Dimm,
> +  IN      PEI_PLATFORM_DIMM_STATE *State
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +ReadSpd (
> +  IN      EFI_PEI_SERVICES      **PeiServices,
> +  IN      PEI_PLATFORM_DIMM_PPI *This,
> +  IN      UINT8                 Dimm,
> +  IN      UINT8                 Offset,
> +  IN      UINTN                 Count,
> +  IN OUT  UINT8                 *Buffer
> +  );
> +
> +static PEI_PLATFORM_DIMM_PPI mGchDimmPpi = {
> +  DIMM_SOCKETS,
> +  DIMM_SEGMENTS,
> +  MEMORY_CHANNELS,
> +  GetDimmState,
> +  SetDimmState,
> +  ReadSpd
> +};
> +
> +static EFI_PEI_PPI_DESCRIPTOR mPpiPlatformDimm = {
> +  (EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> +  &gPeiPlatformDimmPpiGuid,
> +  &mGchDimmPpi
> +};
> +
> +
> +//
> +// Functions
> +//
> +
> +/**
> +  This function returns the current state of a single DIMM.  Present indicates
> +  that the DIMM slot is physically populated.  Disabled indicates that the
> DIMM
> +  should not be used.
> +
> +  @param PeiServices   PEI services table pointer
> +  @param This          PPI pointer
> +  @param Dimm          DIMM to read from
> +  @param State         Pointer to a return buffer to be updated with the
> current state
> +                       of the DIMM
> +
> +  @retval EFI_SUCCESS         The function completed successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetDimmState (
> +  IN      EFI_PEI_SERVICES        **PeiServices,
> +  IN      PEI_PLATFORM_DIMM_PPI   *This,
> +  IN      UINT8                   Dimm,
> +  OUT     PEI_PLATFORM_DIMM_STATE *State
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  UINT8                         Buffer;
> +
> +  PEI_ASSERT (PeiServices, (Dimm < This->DimmSockets));
> +
> +  //
> +  // A failure here does not necessarily mean that no DIMM is present.
> +  // Read a single byte.  All we care about is the return status.
> +  //
> +  Status = ReadSpd (
> +             PeiServices,
> +             This,
> +             Dimm,
> +             0,
> +             1,
> +             &Buffer
> +             );
> +
> +  if (EFI_ERROR (Status)) {
> +    State->Present = 0;
> +  } else {
> +    State->Present = 1;
> +  }
> +
> +  //
> +  // BUGBUG: Update to check platform variable when it is available
> +  //
> +  State->Disabled = 0;
> +  State->Reserved = 0;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +  This function updates the state of a single DIMM.
> +
> +  @param PeiServices          PEI services table pointer
> +  @param This                 PPI pointer
> +  @param Dimm                 DIMM to set state for
> +  @param State                Pointer to the state information to set.
> +
> +  @retval EFI_SUCCESS         The function completed successfully.
> +  @retval EFI_UNSUPPORTED     The function is not supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetDimmState (
> +  IN      EFI_PEI_SERVICES        **PeiServices,
> +  IN      PEI_PLATFORM_DIMM_PPI   *This,
> +  IN      UINT8                   Dimm,
> +  IN      PEI_PLATFORM_DIMM_STATE *State
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +/**
> +  This function reads SPD information from a DIMM.
> +
> +  PeiServices   PEI services table pointer
> +  This          PPI pointer
> +  Dimm          DIMM to read from
> +  Offset        Offset in DIMM
> +  Count         Number of bytes
> +  Buffer        Return buffer
> +
> +  @param EFI_SUCCESS              The function completed successfully.
> +  @param EFI_DEVICE_ERROR         The DIMM being accessed reported a
> device error,
> +                                  does not have an SPD module, or is not installed in
> +                                  the system.
> +  @retval EFI_TIMEOUT             Time out trying to read the SPD module.
> +  @retval EFI_INVALID_PARAMETER   A parameter was outside the legal
> limits.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +ReadSpd (
> +  IN      EFI_PEI_SERVICES      **PeiServices,
> +  IN      PEI_PLATFORM_DIMM_PPI *This,
> +  IN      UINT8                 Dimm,
> +  IN      UINT8                 Offset,
> +  IN      UINTN                 Count,
> +  IN OUT  UINT8                 *Buffer
> +  )
> +{
> +  EFI_STATUS                Status;
> +  PEI_SMBUS_PPI             *Smbus;
> +  UINTN                     Index;
> +  UINTN                     Index1;
> +  EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress;
> +  EFI_SMBUS_DEVICE_COMMAND  Command;
> +  UINTN                     Length;
> +
> +  Status = (**PeiServices).LocatePpi (
> +                             PeiServices,
> +                             &gPeiSmbusPpiGuid,   // GUID
> +                             0,                   // INSTANCE
> +                             NULL,                // EFI_PEI_PPI_DESCRIPTOR
> +                             &Smbus               // PPI
> +                             );
> +  ASSERT_PEI_ERROR (PeiServices, Status);
> +
> +  switch (Dimm) {
> +  case 0:
> +    SlaveAddress.SmbusDeviceAddress = SMBUS_ADDR_CH_A_1 >> 1;
> +    break;
> +  case 1:
> +    SlaveAddress.SmbusDeviceAddress = SMBUS_ADDR_CH_A_2 >> 1;
> +    break;
> +  case 2:
> +    SlaveAddress.SmbusDeviceAddress = SMBUS_ADDR_CH_B_1 >> 1;
> +    break;
> +  case 3:
> +    SlaveAddress.SmbusDeviceAddress = SMBUS_ADDR_CH_B_2 >> 1;
> +    break;
> +  default:
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Index = Count % 4;
> +  if (Index != 0) {
> +    //
> +    // read the first serveral bytes to speed up following reading
> +    //
> +    for (Index1 = 0; Index1 < Index; Index1++) {
> +      Length = 1;
> +      Command = Offset + Index1;
> +      Status = Smbus->Execute (
> +                        PeiServices,
> +                        Smbus,
> +                        SlaveAddress,
> +                        Command,
> +                        EfiSmbusReadByte,
> +                        FALSE,
> +                        &Length,
> +                        &Buffer[Index1]
> +                        );
> +      if (EFI_ERROR(Status)) {
> +        return Status;
> +      }
> +    }
> +  }
> +
> +  //
> +  // Now collect all the remaining bytes on 4 bytes block
> +  //
> +  for (; Index < Count; Index += 2) {
> +    Command = Index + Offset;
> +    Length = 2;
> +    Status = Smbus->Execute (
> +                      PeiServices,
> +                      Smbus,
> +                      SlaveAddress,
> +                      Command,
> +                      EfiSmbusReadWord,
> +                      FALSE,
> +                      &Length,
> +                      &Buffer[Index]
> +                      );
> +    if (EFI_ERROR(Status)) {
> +      return Status;
> +    }
> +
> +    Index += 2;
> +    Command = Index + Offset;
> +    Length = 2;
> +    Status = Smbus->Execute (
> +                      PeiServices,
> +                      Smbus,
> +                      SlaveAddress,
> +                      Command,
> +                      EfiSmbusReadWord,
> +                      FALSE,
> +                      &Length,
> +                      &Buffer[Index]
> +                      );
> +    if (EFI_ERROR(Status)) {
> +      return Status;
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function initializes the PEIM.  It simply installs the DIMM PPI.
> +
> +  @param FfsHeader       Not used by this function
> +  @param PeiServices     Pointer to PEI services table
> +
> +  @retval EFI_SUCCESS    The function completed successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeimInitializeDimm (
> +  IN EFI_PEI_SERVICES           **PeiServices,
> +  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
> +  IN VOID                       *SmbusPpi
> +  )
> +{
> +  EFI_STATUS                    Status;
> +
> +  Status = (**PeiServices).InstallPpi (
> +                             PeiServices,
> +                             &mPpiPlatformDimm
> +                             );
> +  ASSERT_PEI_ERROR (PeiServices, Status);
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/FlashMap.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/FlashMap.c
> new file mode 100644
> index 0000000000..f32eaac479
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/FlashMap.c
> @@ -0,0 +1,143 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +
> +Module Name:
> +
> +  FlashMap.c
> +
> +Abstract:
> +
> +  Build GUIDed HOBs for platform specific flash map.
> +
> +--*/
> +
> +#include "Efi.h"
> +#include "Pei.h"
> +#include "PeiLib.h"
> +#include "PeiLib.h"
> +#include "EfiFlashMap.h"
> +#include EFI_PROTOCOL_CONSUMER (FirmwareVolumeBlock)
> +#include EFI_GUID_DEFINITION (FlashMapHob)
> +#include EFI_GUID_DEFINITION (SystemNvDataGuid)
> +#include EFI_GUID_DEFINITION (FirmwareFileSystem)
> +
> +EFI_GUID                            mFvBlockGuid      =
> EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID;
> +EFI_GUID                            mFfsGuid          =
> EFI_FIRMWARE_FILE_SYSTEM_GUID;
> +EFI_GUID                            mSystemDataGuid   =
> EFI_SYSTEM_NV_DATA_HOB_GUID;
> +
> +static EFI_FLASH_AREA_DATA          mFlashAreaData[]  = {
> +	//
> +  // Variable area
> +  //
> +  { FixedPcdGet32 (PcdFlashNvStorageVariableBase),
> +    FixedPcdGet32 (PcdFlashNvStorageVariableSize),
> +    EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV,
> +    EFI_FLASH_AREA_EFI_VARIABLES },
> +
> +  //
> +  // Boot block 2nd part
> +  //
> +  { FixedPcdGet32 (PcdFlashFvRecovery2Base),
> +    FixedPcdGet32 (PcdFlashFvRecovery2Size),
> +    EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV,
> +    EFI_FLASH_AREA_FTW_BACKUP },
> +
> +  //
> +  // Recovery FV
> +  //
> +  { FixedPcdGet32 (PcdFlashFvRecoveryBase),
> +    FixedPcdGet32 (PcdFlashFvRecoverySize),
> +    EFI_FLASH_AREA_FV | EFI_FLASH_AREA_MEMMAPPED_FV,
> +    EFI_FLASH_AREA_RECOVERY_BIOS },
> +
> +  //
> +  // Main FV
> +  //
> +  { FixedPcdGet32 (PcdFlashFvMainBase),
> +    FixedPcdGet32 (PcdFlashFvMainSize),
> +    EFI_FLASH_AREA_FV | EFI_FLASH_AREA_MEMMAPPED_FV,
> +    EFI_FLASH_AREA_MAIN_BIOS }
> +
> +};
> +
> +#define NUM_FLASH_AREA_DATA (ARRAY_SIZE (mFlashAreaData))
> +
> +/**
> +  Build GUID HOBs for platform specific flash map.
> +
> +  @param FfsHeader     Pointer this FFS file header.
> +  @param PeiServices   General purpose services available to every PEIM.
> +
> +  @retval EFI_SUCCESS   Guid HOBs for platform flash map is built.
> +  @retval Otherwise     Failed to build the Guid HOB data.
> +
> +**/
> +EFI_STATUS
> +PeimInitializeFlashMap (
> +  IN EFI_FFS_FILE_HEADER       *FfsHeader,
> +  IN EFI_PEI_SERVICES          **PeiServices
> +  )
> +{
> +  UINTN                         Index;
> +  EFI_FLASH_AREA_HOB_DATA       FlashHobData;
> +
> +  //
> +  // Build flash area entries as GUIDed HOBs.
> +  //
> +  for (Index = 0; Index < NUM_FLASH_AREA_DATA; Index++) {
> +    ZeroMem(&FlashHobData, sizeof (EFI_FLASH_AREA_HOB_DATA));
> +
> +    FlashHobData.AreaType               = mFlashAreaData[Index].AreaType;
> +    FlashHobData.NumberOfEntries        = 1;
> +    FlashHobData.SubAreaData.Attributes =
> mFlashAreaData[Index].Attributes;
> +    FlashHobData.SubAreaData.Base       = (EFI_PHYSICAL_ADDRESS) (UINTN)
> mFlashAreaData[Index].Base;
> +    FlashHobData.SubAreaData.Length     = (EFI_PHYSICAL_ADDRESS) (UINTN)
> mFlashAreaData[Index].Length;
> +
> +    switch (FlashHobData.AreaType) {
> +    case EFI_FLASH_AREA_RECOVERY_BIOS:
> +    case EFI_FLASH_AREA_MAIN_BIOS:
> +      CopyMem (
> +        &FlashHobData.AreaTypeGuid,
> +        &mFfsGuid,
> +        sizeof (EFI_GUID)
> +        );
> +      CopyMem (
> +        &FlashHobData.SubAreaData.FileSystem,
> +        &mFvBlockGuid,
> +        sizeof (EFI_GUID)
> +        );
> +      break;
> +
> +    case EFI_FLASH_AREA_GUID_DEFINED:
> +      CopyMem (
> +        &FlashHobData.AreaTypeGuid,
> +        &mSystemDataGuid,
> +        sizeof (EFI_GUID)
> +        );
> +      CopyMem (
> +        &FlashHobData.SubAreaData.FileSystem,
> +        &mFvBlockGuid,
> +        sizeof (EFI_GUID)
> +        );
> +      break;
> +
> +    default:
> +      break;
> +    }
> +
> +    PeiBuildHobGuidData(PeiServices,
> +                        &gEfiFlashMapHobGuid,
> +                        &FlashHobData,
> +                        sizeof (EFI_FLASH_AREA_HOB_DATA)
> +                        );
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.c
> new file mode 100644
> index 0000000000..6711f54863
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.c
> @@ -0,0 +1,168 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> + LegacySpeaker.c
> +
> +Abstract:
> +
> +  This file implements PEIM for Legacy Speaker. This file is valid for platforms
> both
> +  on IA32 and Itanium Product Family
> +
> +--*/
> +
> +#include "PlatformEarlyInit.h"
> +
> +EFI_STATUS
> +OutputBeep (
> +  IN  CONST EFI_PEI_SERVICES  **PeiServices,
> +  IN  UINTN             NumberOfBeep,
> +  IN  UINTN             BeepDuration,
> +  IN  UINTN             TimerInterval
> +  );
> +
> +/**
> +  This function will enable the speaker to generate beep
> +
> +  @param PeiServices     PeiServices to locate PPI
> +
> +  @retval EFI_STATUS
> +
> +**/
> +EFI_STATUS
> +TurnOnSpeaker (
> +  IN  CONST EFI_PEI_SERVICES    **PeiServices
> +  )
> +{
> +  UINT8                   Data;
> +  Data = IoRead8 (EFI_SPEAKER_CONTROL_PORT);
> +  Data |= 0x03;
> +  IoWrite8(EFI_SPEAKER_CONTROL_PORT, Data);
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function will stop beep from speaker.
> +
> +  @param  PeiServices     PeiServices to locate PPI
> +
> +  @retval Status
> +
> +**/
> +EFI_STATUS
> +TurnOffSpeaker (
> +  IN  CONST EFI_PEI_SERVICES    **PeiServices
> +  )
> +{
> +  UINT8                   Data;
> +
> +  Data = IoRead8 (EFI_SPEAKER_CONTROL_PORT);
> +  Data &= 0xFC;
> +  IoWrite8(EFI_SPEAKER_CONTROL_PORT, Data);
> +  return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +OutputBeep (
> +  IN  CONST EFI_PEI_SERVICES  **PeiServices,
> +  IN  UINTN             NumberOfBeep,
> +  IN  UINTN             BeepDuration,
> +  IN  UINTN             TimeInterval
> +  )
> +{
> +  UINTN           Num;
> +  EFI_PEI_STALL_PPI*  StallPpi;
> +
> +  (**PeiServices).LocatePpi (PeiServices, &gEfiPeiStallPpiGuid, 0, NULL,
> (void **)&StallPpi);
> +
> +  for (Num=0; Num < NumberOfBeep; Num++) {
> +    TurnOnSpeaker (PeiServices);
> +    StallPpi->Stall(PeiServices, StallPpi, BeepDuration);
> +    TurnOffSpeaker(PeiServices);
> +    StallPpi->Stall(PeiServices, StallPpi, TimeInterval);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function will program the speaker tone frequency. The value should
> be with 64k
> +  boundary since it takes only 16 bit value which gets programmed in two
> step IO opearattion
> +
> +  Frequency     - A value which should be 16 bit only.
> +
> +  EFI_SUCESS
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +ProgramToneFrequency (
> +  IN  CONST EFI_PEI_SERVICES                  **PeiServices,
> +  IN  UINT16                            Frequency
> +  )
> +{
> +  UINT8                   Data;
> +
> +  Data = 0xB6;
> +  IoWrite8(EFI_TIMER_CONTROL_PORT, Data);
> +
> +  Data = (UINT8)(Frequency & 0x00FF);
> +  IoWrite8(EFI_TIMER_2_PORT, Data);
> +  Data = (UINT8)((Frequency & 0xFF00) >> 8);
> +  IoWrite8(EFI_TIMER_2_PORT, Data);
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function will generate the beep for specified duration.
> +
> +  @param  PeiServices       PeiServices to locate various PPIs
> +  @param  NumberOfBeeps     Number of beeps which user want to
> produce
> +  @param  BeepDuration      Duration for speaker gate need to be enabled
> +  @param  TimeInterval      Interval between each beep
> +
> +  @retval EFI_STATUS
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GenerateBeepTone (
> +  IN  CONST EFI_PEI_SERVICES                  **PeiServices,
> +  IN  UINTN                             NumberOfBeeps,
> +  IN  UINTN                             BeepDuration,
> +  IN  UINTN                             TimeInterval
> +  )
> +{
> +
> +  if ((NumberOfBeeps == 1) && (BeepDuration == 0) && (TimeInterval == 0))
> {
> +    TurnOnSpeaker (PeiServices);
> +    return EFI_SUCCESS;
> +  }
> +
> +  if ((NumberOfBeeps == 0) && (BeepDuration == 0) && (TimeInterval == 0))
> {
> +    TurnOffSpeaker (PeiServices);
> +    return EFI_SUCCESS;
> +  }
> +
> +  if (BeepDuration == 0) {
> +    BeepDuration = EFI_DEFAULT_SHORT_BEEP_DURATION;
> +  }
> +
> +  if (TimeInterval == 0) {
> +    TimeInterval = EFI_DEFAULT_BEEP_TIME_INTERVAL;
> +  }
> +
> +  OutputBeep (PeiServices, NumberOfBeeps, BeepDuration, TimeInterval);
> +  return EFI_SUCCESS;
> +
> +
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.h
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.h
> new file mode 100644
> index 0000000000..dee022bf9b
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.h
> @@ -0,0 +1,71 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> + LegacySpeaker.h
> +
> +Abstract:
> +
> +  Speaker enabling related data
> +
> +--*/
> +
> +#ifndef _PEI_LEGACY_SPEAKER_H
> +#define _PEI_LEGACY_SPEAKER_H
> +
> +
> +//
> +// Speaker Related Port Information
> +//
> +#define EFI_TIMER_COUNTER_PORT            0x40
> +#define EFI_TIMER_CONTROL_PORT            0x43
> +#define EFI_TIMER_2_PORT                  0x42
> +#define EFI_SPEAKER_CONTROL_PORT          0x61
> +
> +#define EFI_SPEAKER_OFF_MASK              0xFC
> +
> +#define EFI_DEFAULT_BEEP_FREQUENCY        0x500
> +
> +//
> +// Default Intervals/Beep Duration
> +//
> +#define EFI_DEFAULT_LONG_BEEP_DURATION    0x70000
> +#define EFI_DEFAULT_SHORT_BEEP_DURATION   0x50000
> +#define EFI_DEFAULT_BEEP_TIME_INTERVAL    0x20000
> +
> +
> +EFI_STATUS
> +EFIAPI
> +ProgramToneFrequency (
> +  IN  CONST EFI_PEI_SERVICES  **PeiServices,
> +  IN  UINT16 Frequency
> +  );
> +
> +
> +EFI_STATUS
> +EFIAPI
> +GenerateBeepTone (
> +  IN  CONST EFI_PEI_SERVICES                  **PeiServices,
> +  IN  UINTN                             NumberOfBeeps,
> +  IN  UINTN                             BeepDuration,
> +  IN  UINTN                             TimeInterval
> +  );
> +
> +EFI_STATUS
> +TurnOnSpeaker (
> +  IN  CONST EFI_PEI_SERVICES  **PeiServices
> +  );
> +
> +EFI_STATUS
> +TurnOffSpeaker (
> +  IN  CONST EFI_PEI_SERVICES  **PeiServices
> +  );
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MchInit.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MchInit.c
> new file mode 100644
> index 0000000000..7d1a20c104
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MchInit.c
> @@ -0,0 +1,72 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +    MchInit.c
> +
> +Abstract:
> +
> +
> +--*/
> +
> +
> +#include "PlatformEarlyInit.h"
> +
> +#define PSE_PAGE_SIZE 0x400000   // 4MB
> +
> +extern  BOOLEAN ImageInMemory;
> +
> +
> +VOID
> +EfiCommonLibEnablePsePaging (
> +  IN UINT32   PDBR
> +  );
> +
> +VOID
> +EfiCommonLibDisablePsePaging (
> +  );
> +
> +/**
> +
> +  Initialize the MCH Thermal Sensor
> +
> +**/
> +VOID
> +InitMchThermalSensor()
> +{
> +}
> +
> +/**
> +
> +  Programs and enables the CRID for MCH and ICH
> +
> +**/
> +VOID
> +ProgramMchCRID(
> +  IN CONST EFI_PEI_SERVICES            **PeiServices
> +  )
> +{
> +}
> +
> +/**
> +
> +  Initialize the GPIO IO selection, GPIO USE selection, and GPIO signal
> inversion registers
> +
> +**/
> +VOID
> +MchInit (
> +  IN CONST EFI_PEI_SERVICES          **PeiServices
> +  )
> +{
> +
> +  return;
> +}
> +
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryCallback.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryCallback.c
> new file mode 100644
> index 0000000000..070848ed1e
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryCallback.c
> @@ -0,0 +1,338 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  MemoryCallback.c
> +
> +Abstract:
> +
> +  EFI 2.0 PEIM to provide the platform support functionality on the
> Bridgeport.
> +
> +--*/
> +
> +#include "PlatformEarlyInit.h"
> +
> +
> +VOID
> +UpdateDefaultSetupValue (
> +  IN  EFI_PLATFORM_INFO_HOB       *PlatformInfo
> +  )
> +{
> +return;
> +}
> +
> +/**
> +  PEI termination callback.
> +
> +  @param PeiServices         General purpose services available to every PEIM.
> +  @param NotifyDescriptor    Not uesed.
> +  @param Ppi                 Not uesed.
> +
> +  @retval EFI_SUCCESS        If the interface could be successfully
> +                             installed.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +EndOfPeiPpiNotifyCallback (
> +  IN CONST EFI_PEI_SERVICES           **PeiServices,
> +  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
> +  IN VOID                       *Ppi
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  UINT64                      LowUncableBase;
> +  EFI_PLATFORM_INFO_HOB       *PlatformInfo;
> +  UINT32                      HecBaseHigh;
> +  EFI_BOOT_MODE               BootMode;
> +  EFI_PEI_HOB_POINTERS        Hob;
> +
> +  Status = (*PeiServices)->GetBootMode(
> +                             PeiServices,
> +                             &BootMode
> +                             );
> +
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Set the some PCI and chipset range as UC
> +  // And align to 1M at leaset
> +  //
> +  Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid);
> +  ASSERT (Hob.Raw != NULL);
> +  PlatformInfo = GET_GUID_HOB_DATA(Hob.Raw);
> +
> +  UpdateDefaultSetupValue (PlatformInfo);
> +
> +  DEBUG ((EFI_D_ERROR, "Memory TOLM: %X\n", PlatformInfo-
> >MemData.MemTolm));
> +  DEBUG ((EFI_D_ERROR, "PCIE OSBASE: %lX\n", PlatformInfo-
> >PciData.PciExpressBase));
> +  DEBUG (
> +    (EFI_D_ERROR,
> +    "PCIE   BASE: %lX     Size : %X\n",
> +    PlatformInfo->PciData.PciExpressBase,
> +    PlatformInfo->PciData.PciExpressSize)
> +    );
> +  DEBUG (
> +    (EFI_D_ERROR,
> +    "PCI32  BASE: %X     Limit: %X\n",
> +    PlatformInfo->PciData.PciResourceMem32Base,
> +    PlatformInfo->PciData.PciResourceMem32Limit)
> +    );
> +  DEBUG (
> +    (EFI_D_ERROR,
> +    "PCI64  BASE: %lX     Limit: %lX\n",
> +    PlatformInfo->PciData.PciResourceMem64Base,
> +    PlatformInfo->PciData.PciResourceMem64Limit)
> +    );
> +  DEBUG ((EFI_D_ERROR, "UC    START: %lX     End  : %lX\n", PlatformInfo-
> >MemData.MemMir0, PlatformInfo->MemData.MemMir1));
> +
> +  LowUncableBase = PlatformInfo->MemData.MemMaxTolm;
> +  LowUncableBase &= (0x0FFF00000);
> +
> +  if (BootMode != BOOT_ON_S3_RESUME) {
> +    //
> +    // In BIOS, HECBASE will be always below 4GB
> +    //
> +    HecBaseHigh = (UINT32) RShiftU64 (PlatformInfo-
> >PciData.PciExpressBase, 28);
> +    ASSERT (HecBaseHigh < 16);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  Install Firmware Volume Hob's once there is main memory
> +
> +  @param PeiServices       General purpose services available to every PEIM.
> +  @param NotifyDescriptor  Notify that this module published.
> +  @param Ppi               PPI that was installed.
> +
> +  @retval EFI_SUCCESS     The function completed successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +MemoryDiscoveredPpiNotifyCallback (
> +  IN CONST EFI_PEI_SERVICES           **PeiServices,
> +  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
> +  IN VOID                       *Ppi
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_BOOT_MODE               BootMode;
> +  EFI_CPUID_REGISTER          FeatureInfo;
> +  UINT8                       CpuAddressWidth;
> +  UINT16                      Pm1Cnt;
> +  EFI_PEI_HOB_POINTERS        Hob;
> +  EFI_PLATFORM_INFO_HOB       *PlatformInfo;
> +  UINT32                      RootComplexBar;
> +  UINT32                      PmcBase;
> +  UINT32                      IoBase;
> +  UINT32                      IlbBase;
> +  UINT32                      SpiBase;
> +  UINT32                      MphyBase;
> +
> +  //
> +  // Get Platform Info HOB
> +  //
> +  Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid);
> +  ASSERT (Hob.Raw != NULL);
> +  PlatformInfo = GET_GUID_HOB_DATA(Hob.Raw);
> +
> +  Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode);
> +
> +  //
> +  // Check if user wants to turn off in PEI phase
> +  //
> +  if ((BootMode != BOOT_ON_S3_RESUME) && (BootMode !=
> BOOT_ON_FLASH_UPDATE)) {
> +    CheckPowerOffNow();
> +  } else {
> +    Pm1Cnt  = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT);
> +    Pm1Cnt &= ~B_PCH_ACPI_PM1_CNT_SLP_TYP;
> +    IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT, Pm1Cnt);
> +  }
> +
> +  #ifndef MINNOW2_FSP_BUILD
> +  //
> +  // Set PEI cache mode here
> +  //
> +  SetPeiCacheMode (PeiServices);
> +  #endif
> +
> +  //
> +  //  Pulish memory tyoe info
> +  //
> +  PublishMemoryTypeInfo ();
> +
> +  //
> +  // Work done if on a S3 resume
> +  //
> +  if (BootMode == BOOT_ON_S3_RESUME) {
> +    //
> +    //Program the side band packet register to send a sideband message to
> Punit
> +    //To indicate that DRAM has been initialized and PUNIT FW base address
> in memory.
> +    //
> +    return EFI_SUCCESS;
> +  }
> +
> +  RootComplexBar = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH,
> PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_RCBA ) &
> B_PCH_LPC_RCBA_BAR;
> +  BuildResourceDescriptorHob (
> +    EFI_RESOURCE_MEMORY_MAPPED_IO,
> +    (EFI_RESOURCE_ATTRIBUTE_PRESENT |
> EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
> +    RootComplexBar,
> +    0x1000
> +    );
> +  DEBUG ((EFI_D_INFO, "RootComplexBar     : 0x%x\n", RootComplexBar));
> +
> +  PmcBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH,
> PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_PMC_BASE ) &
> B_PCH_LPC_PMC_BASE_BAR;
> +  BuildResourceDescriptorHob (
> +    EFI_RESOURCE_MEMORY_MAPPED_IO,
> +    (EFI_RESOURCE_ATTRIBUTE_PRESENT |
> EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
> +    PmcBase,
> +    0x1000
> +    );
> +  DEBUG ((EFI_D_INFO, "PmcBase            : 0x%x\n", PmcBase));
> +
> +  IoBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH,
> PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_IO_BASE ) &
> B_PCH_LPC_IO_BASE_BAR;
> +  BuildResourceDescriptorHob (
> +    EFI_RESOURCE_MEMORY_MAPPED_IO,
> +    (EFI_RESOURCE_ATTRIBUTE_PRESENT |
> EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
> +    IoBase,
> +    0x4000
> +    );
> +  DEBUG ((EFI_D_INFO, "IoBase             : 0x%x\n", IoBase));
> +
> +  IlbBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH,
> PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_ILB_BASE ) &
> B_PCH_LPC_ILB_BASE_BAR;
> +  BuildResourceDescriptorHob (
> +    EFI_RESOURCE_MEMORY_MAPPED_IO,
> +    (EFI_RESOURCE_ATTRIBUTE_PRESENT |
> EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
> +    IlbBase,
> +    0x1000
> +    );
> +  DEBUG ((EFI_D_INFO, "IlbBase            : 0x%x\n", IlbBase));
> +
> +  SpiBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH,
> PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_SPI_BASE ) &
> B_PCH_LPC_SPI_BASE_BAR;
> +  BuildResourceDescriptorHob (
> +    EFI_RESOURCE_MEMORY_MAPPED_IO,
> +    (EFI_RESOURCE_ATTRIBUTE_PRESENT |
> EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
> +    SpiBase,
> +    0x1000
> +    );
> +  DEBUG ((EFI_D_INFO, "SpiBase            : 0x%x\n", SpiBase));
> +
> +  MphyBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH,
> PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_MPHY_BASE ) &
> B_PCH_LPC_MPHY_BASE_BAR;
> +  BuildResourceDescriptorHob (
> +    EFI_RESOURCE_MEMORY_MAPPED_IO,
> +    (EFI_RESOURCE_ATTRIBUTE_PRESENT |
> EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
> +    MphyBase,
> +    0x100000
> +    );
> +  DEBUG ((EFI_D_INFO, "MphyBase           : 0x%x\n", MphyBase));
> +
> +  //
> +  // Local APIC
> +  //
> +  BuildResourceDescriptorHob (
> +    EFI_RESOURCE_MEMORY_MAPPED_IO,
> +    (EFI_RESOURCE_ATTRIBUTE_PRESENT |
> EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
> +    LOCAL_APIC_ADDRESS,
> +    0x1000
> +  );
> +  DEBUG ((EFI_D_INFO, "LOCAL_APIC_ADDRESS : 0x%x\n",
> LOCAL_APIC_ADDRESS));
> +
> +  //
> +  // IO APIC
> +  //
> +  BuildResourceDescriptorHob (
> +    EFI_RESOURCE_MEMORY_MAPPED_IO,
> +    (EFI_RESOURCE_ATTRIBUTE_PRESENT |
> EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
> +    IO_APIC_ADDRESS,
> +    0x1000
> +  );
> +  DEBUG ((EFI_D_INFO, "IO_APIC_ADDRESS    : 0x%x\n",
> IO_APIC_ADDRESS));
> +
> +  //
> +  // Adding the PCIE Express area to the E820 memory table as type 2
> memory.
> +  //
> +  BuildResourceDescriptorHob (
> +    EFI_RESOURCE_MEMORY_MAPPED_IO,
> +    (EFI_RESOURCE_ATTRIBUTE_PRESENT |
> EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
> +    PlatformInfo->PciData.PciExpressBase,
> +    PlatformInfo->PciData.PciExpressSize
> +    );
> +  DEBUG ((EFI_D_INFO, "PciExpressBase     : 0x%x\n", PlatformInfo-
> >PciData.PciExpressBase));
> +
> +  //
> +  // Adding the Flashpart to the E820 memory table as type 2 memory.
> +  //
> +  BuildResourceDescriptorHob (
> +    EFI_RESOURCE_FIRMWARE_DEVICE,
> +    (EFI_RESOURCE_ATTRIBUTE_PRESENT |
> EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
> +    FixedPcdGet32 (PcdFlashAreaBaseAddress),
> +    FixedPcdGet32 (PcdFlashAreaSize)
> +    );
> +  DEBUG ((EFI_D_INFO, "FLASH_BASE_ADDRESS : 0x%x\n", FixedPcdGet32
> (PcdFlashAreaBaseAddress)));
> +
> +  //
> +  // Create a CPU hand-off information
> +  //
> +  CpuAddressWidth = 32;
> +  AsmCpuid (EFI_CPUID_EXTENDED_FUNCTION, &FeatureInfo.RegEax,
> &FeatureInfo.RegEbx, &FeatureInfo.RegEcx, &FeatureInfo.RegEdx);
> +  if (FeatureInfo.RegEax >= EFI_CPUID_VIRT_PHYS_ADDRESS_SIZE) {
> +    AsmCpuid (EFI_CPUID_VIRT_PHYS_ADDRESS_SIZE, &FeatureInfo.RegEax,
> &FeatureInfo.RegEbx, &FeatureInfo.RegEcx, &FeatureInfo.RegEdx);
> +    CpuAddressWidth = (UINT8) (FeatureInfo.RegEax & 0xFF);
> +  }
> +
> +  BuildCpuHob(CpuAddressWidth, 16);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +
> +}
> +
> +
> +EFI_STATUS
> +ValidateFvHeader (
> +  IN EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader
> +  )
> +{
> +  UINT16  *Ptr;
> +  UINT16  HeaderLength;
> +  UINT16  Checksum;
> +
> +  //
> +  // Verify the header revision, header signature, length
> +  // Length of FvBlock cannot be 2**64-1
> +  // HeaderLength cannot be an odd number
> +  //
> +  if ((FwVolHeader->Revision != EFI_FVH_REVISION) ||
> +      (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||
> +      (FwVolHeader->FvLength == ((UINT64) -1)) ||
> +      ((FwVolHeader->HeaderLength & 0x01) != 0)
> +      ) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  //
> +  // Verify the header checksum
> +  //
> +  HeaderLength  = (UINT16) (FwVolHeader->HeaderLength / 2);
> +  Ptr           = (UINT16 *) FwVolHeader;
> +  Checksum      = 0;
> +  while (HeaderLength > 0) {
> +    Checksum = *Ptr++;
> +    HeaderLength--;
> +  }
> +
> +  if (Checksum != 0) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryPeim.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryPeim.c
> new file mode 100644
> index 0000000000..e6189b7713
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryPeim.c
> @@ -0,0 +1,408 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +  MemoryPeim.c
> +
> +Abstract:
> +
> +  Tiano PEIM to provide the platform support functionality.
> +  This file implements the Platform Memory Range PPI
> +
> +--*/
> +
> +#include "PlatformEarlyInit.h"
> +
> +//
> +// Need min. of 48MB PEI phase
> +//
> +#define  PEI_MIN_MEMORY_SIZE               (6 * 0x800000)
> +#define  PEI_RECOVERY_MIN_MEMORY_SIZE      (6 * 0x800000)
> +
> +//
> +// This is the memory needed for PEI to start up DXE.
> +//
> +// Over-estimating this size will lead to higher fragmentation
> +// of main memory.  Under-estimation of this will cause catastrophic
> +// failure of PEI to load DXE.  Generally, the failure may only be
> +// realized during capsule updates.
> +//
> +#define PRERESERVED_PEI_MEMORY ( \
> +  EFI_SIZE_TO_PAGES (3 * 0x800000)   /* PEI Core memory based stack
> */ \
> +  )
> +
> +EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] =
> {
> +  { EfiACPIReclaimMemory,       0x40  },    // 0x40 pages = 256k for ASL
> +  { EfiACPIMemoryNVS,           0x100 },    // 0x100 pages = 1 MB for S3, SMM,
> HII, etc
> +  { EfiReservedMemoryType,      0x600 },    // 48k for BIOS Reserved
> +  { EfiMemoryMappedIO,          0     },
> +  { EfiMemoryMappedIOPortSpace, 0     },
> +  { EfiPalCode,                 0     },
> +  { EfiRuntimeServicesCode,     0x200 },
> +  { EfiRuntimeServicesData,     0x100 },
> +  { EfiLoaderCode,              0x100 },
> +  { EfiLoaderData,              0x100 },
> +  { EfiBootServicesCode,        0x800 },
> +  { EfiBootServicesData,        0x2500},
> +  { EfiConventionalMemory,      0     },
> +  { EfiUnusableMemory,          0     },
> +  { EfiMaxMemoryType,           0     }
> +};
> +
> +STATIC
> +EFI_STATUS
> +GetMemorySize (
> +  IN  CONST EFI_PEI_SERVICES    **PeiServices,
> +  OUT UINT64              *LowMemoryLength,
> +  OUT UINT64              *HighMemoryLength
> +  );
> +
> +
> +/**
> +  Initializes the valid address mask for MTRRs.
> +
> +  This function initializes the valid bits mask and valid address mask for
> MTRRs.
> +
> +**/
> +UINT64
> +InitializeAddressMtrrMask (
> +  VOID
> +  )
> +{
> +  UINT32                    RegEax;
> +  UINT8                     PhysicalAddressBits;
> +  UINT64                    ValidMtrrBitsMask;
> +
> +  AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
> +
> +  if (RegEax >= 0x80000008) {
> +    AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
> +
> +    PhysicalAddressBits = (UINT8) RegEax;
> +  } else {
> +    PhysicalAddressBits = 36;
> +  }
> +
> +  ValidMtrrBitsMask    = LShiftU64 (1, PhysicalAddressBits) - 1;
> +  return (ValidMtrrBitsMask & 0xfffffffffffff000ULL);
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +SetPeiCacheMode (
> +  IN  CONST EFI_PEI_SERVICES    **PeiServices
> +  )
> +{
> +  EFI_STATUS              Status;
> +  PEI_CACHE_PPI           *CachePpi;
> +
> +  EFI_BOOT_MODE           BootMode;
> +  UINT64                  MemoryLength;
> +  UINT64                  MemOverflow;
> +  UINT64                  MemoryLengthUc;
> +  UINT64                  MaxMemoryLength;
> +  UINT64                  LowMemoryLength;
> +  UINT64                  HighMemoryLength;
> +  UINT8                   Index;
> +  MTRR_SETTINGS           MtrrSetting;
> +  UINT64                  ValidMtrrAddressMask;
> +
> +  //
> +  // Load Cache PPI
> +  //
> +  Status = (**PeiServices).LocatePpi (
> +             PeiServices,
> +             &gPeiCachePpiGuid,    // GUID
> +             0,                    // Instance
> +             NULL,                 // EFI_PEI_PPI_DESCRIPTOR
> +             (void **)&CachePpi             // PPI
> +             );
> +  if (!EFI_ERROR(Status)) {
> +    //
> +    // Clear the CAR Settings (Default Cache Type => UC)
> +    //
> +    DEBUG ((EFI_D_INFO, "Reset cache attribute and disable CAR. \n"));
> +    CachePpi->ResetCache(
> +                (EFI_PEI_SERVICES**)PeiServices,
> +                CachePpi
> +                );
> + }
> +
> +
> +  //
> +  // Variable initialization
> +  //
> +  LowMemoryLength = 0;
> +  HighMemoryLength = 0;
> +  MemoryLengthUc = 0;
> +
> +  Status = (*PeiServices)->GetBootMode (
> +                             PeiServices,
> +                             &BootMode
> +                             );
> +
> +  ValidMtrrAddressMask = InitializeAddressMtrrMask ();
> +
> +  //
> +  // Determine memory usage
> +  //
> +  GetMemorySize (
> +    PeiServices,
> +    &LowMemoryLength,
> +    &HighMemoryLength
> +    );
> +
> +  LowMemoryLength  = (EFI_PHYSICAL_ADDRESS)MmPci32( 0, 0, 2, 0, 0x70);
> +  LowMemoryLength   &=  0xFFF00000ULL;
> +
> +  MaxMemoryLength = LowMemoryLength;
> +
> +  //
> +  // Round up to nearest 256MB with high memory and 64MB w/o high
> memory
> +  //
> +  if (HighMemoryLength != 0 ) {
> +    MemOverflow = (LowMemoryLength & 0x0fffffff);
> +    if (MemOverflow != 0) {
> +      MaxMemoryLength = LowMemoryLength + (0x10000000 -
> MemOverflow);
> +    }
> +  } else {
> +    MemOverflow = (LowMemoryLength & 0x03ffffff);
> +    if (MemOverflow != 0) {
> +      MaxMemoryLength = LowMemoryLength + (0x4000000 - MemOverflow);
> +    }
> +  }
> +
> +  ZeroMem (&MtrrSetting, sizeof(MTRR_SETTINGS));
> +  for (Index = 0; Index < 2; Index++) {
> +    MtrrSetting.Fixed.Mtrr[Index]=0x0606060606060606;
> +   }
> +  for (Index = 2; Index < 11; Index++) {
> +    MtrrSetting.Fixed.Mtrr[Index]=0x0505050505050505;
> +   }
> +
> +  //
> +  // Cache the flash area to improve the boot performance in PEI phase
> +  //
> +  Index = 0;
> +  ((MSR_IA32_MTRR_PHYSBASE_REGISTER *)
> &MtrrSetting.Variables.Mtrr[0].Base)->Uint64 = FixedPcdGet32
> (PcdFlashAreaBaseAddress);
> +  ((MSR_IA32_MTRR_PHYSBASE_REGISTER *)
> &MtrrSetting.Variables.Mtrr[0].Base)->Bits.Type = CacheWriteProtected;
> +  ((MSR_IA32_MTRR_PHYSMASK_REGISTER *)
> &MtrrSetting.Variables.Mtrr[0].Mask)->Uint64 = (~((UINT64)(FixedPcdGet32
> (PcdFlashAreaSize) - 1))) & ValidMtrrAddressMask;
> +  ((MSR_IA32_MTRR_PHYSMASK_REGISTER *)
> &MtrrSetting.Variables.Mtrr[0].Mask)->Bits.V = 1;
> +
> +  Index ++;
> +
> +  MemOverflow =0;
> +  while (MaxMemoryLength > MemOverflow){
> +    MemoryLength = MaxMemoryLength - MemOverflow;
> +    MemoryLength = GetPowerOfTwo64 (MemoryLength);
> +
> +    ((MSR_IA32_MTRR_PHYSBASE_REGISTER *)
> &MtrrSetting.Variables.Mtrr[Index].Base)->Uint64 = MemOverflow &
> ValidMtrrAddressMask;
> +    ((MSR_IA32_MTRR_PHYSBASE_REGISTER *)
> &MtrrSetting.Variables.Mtrr[Index].Base)->Bits.Type = CacheWriteBack;
> +    ((MSR_IA32_MTRR_PHYSMASK_REGISTER *)
> &MtrrSetting.Variables.Mtrr[Index].Mask)->Uint64 = (~(MemoryLength - 1))
> & ValidMtrrAddressMask;
> +    ((MSR_IA32_MTRR_PHYSMASK_REGISTER *)
> &MtrrSetting.Variables.Mtrr[Index].Mask)->Bits.V = 1;
> +
> +    MemOverflow += MemoryLength;
> +    Index++;
> +  }
> +
> +  MemoryLength = LowMemoryLength;
> +
> +  while (MaxMemoryLength != MemoryLength) {
> +    MemoryLengthUc = GetPowerOfTwo64 (MaxMemoryLength -
> MemoryLength);
> +
> +    ((MSR_IA32_MTRR_PHYSBASE_REGISTER *)
> &MtrrSetting.Variables.Mtrr[Index].Base)->Uint64 = (MaxMemoryLength -
> MemoryLengthUc) & ValidMtrrAddressMask;
> +    ((MSR_IA32_MTRR_PHYSBASE_REGISTER *)
> &MtrrSetting.Variables.Mtrr[Index].Base)->Bits.Type = CacheUncacheable;
> +    ((MSR_IA32_MTRR_PHYSMASK_REGISTER *)
> &MtrrSetting.Variables.Mtrr[Index].Mask)->Uint64 = (~(MemoryLengthUc   -
> 1)) & ValidMtrrAddressMask;
> +    ((MSR_IA32_MTRR_PHYSMASK_REGISTER *)
> &MtrrSetting.Variables.Mtrr[Index].Mask)->Bits.V = 1;
> +
> +    MaxMemoryLength -= MemoryLengthUc;
> +    Index++;
> +  }
> +
> +  MemOverflow =0x100000000;
> +  while (HighMemoryLength > 0) {
> +
> +    MemoryLength = HighMemoryLength;
> +    MemoryLength = GetPowerOfTwo64 (MemoryLength);
> +    if (MemoryLength > MemOverflow){
> +      MemoryLength = MemOverflow;
> +    }
> +
> +    ((MSR_IA32_MTRR_PHYSBASE_REGISTER *)
> &MtrrSetting.Variables.Mtrr[Index].Base)->Uint64 = MemOverflow &
> ValidMtrrAddressMask;
> +    ((MSR_IA32_MTRR_PHYSBASE_REGISTER *)
> &MtrrSetting.Variables.Mtrr[Index].Base)->Bits.Type = CacheWriteBack;
> +    ((MSR_IA32_MTRR_PHYSMASK_REGISTER *)
> &MtrrSetting.Variables.Mtrr[Index].Mask)->Uint64 = (~(MemoryLength - 1))
> & ValidMtrrAddressMask;
> +    ((MSR_IA32_MTRR_PHYSMASK_REGISTER *)
> &MtrrSetting.Variables.Mtrr[Index].Mask)->Bits.V = 1;
> +
> +    MemOverflow += MemoryLength;
> +    HighMemoryLength -= MemoryLength;
> +    Index++;
> +  }
> +
> +
> +  for (Index = 0; Index < MTRR_NUMBER_OF_VARIABLE_MTRR; Index++) {
> +    if (MtrrSetting.Variables.Mtrr[Index].Base == 0){
> +      break;
> +    }
> +    DEBUG ((EFI_D_INFO, "Base=%lx,
> Mask=%lx\n",MtrrSetting.Variables.Mtrr[Index].Base ,MtrrSetting.Variables.
> Mtrr[Index].Mask));
> +  }
> +
> +  //
> +  // set FE/E bits for IA32_MTRR_DEF_TYPE
> +  //
> +  MtrrSetting.MtrrDefType |=  3 <<10;
> +
> +  MtrrSetAllMtrrs(&MtrrSetting);
> +  //
> +  // Dump MTRR Setting
> +  //
> +  MtrrDebugPrintAllMtrrs ();
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +SetDxeCacheMode (
> +  IN  CONST EFI_PEI_SERVICES    **PeiServices
> +  )
> +{
> +  //
> +  // This is not needed for now.
> +  //
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +GetMemorySize (
> +  IN  CONST EFI_PEI_SERVICES    **PeiServices,
> +  OUT UINT64              *LowMemoryLength,
> +  OUT UINT64              *HighMemoryLength
> +  )
> +{
> +  EFI_STATUS              Status;
> +  EFI_PEI_HOB_POINTERS    Hob;
> +
> +  *HighMemoryLength = 0;
> +  *LowMemoryLength = 0x100000;
> +
> +  //
> +  // Get the HOB list for processing
> +  //
> +  Status = (*PeiServices)->GetHobList (PeiServices, (void **)&Hob.Raw);
> +  if (EFI_ERROR(Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Collect memory ranges
> +  //
> +  while (!END_OF_HOB_LIST (Hob)) {
> +    if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
> +      if (Hob.ResourceDescriptor->ResourceType ==
> EFI_RESOURCE_SYSTEM_MEMORY) {
> +        //
> +        // Need memory above 1MB to be collected here
> +        //
> +        if (Hob.ResourceDescriptor->PhysicalStart >= 0x100000 &&
> +            Hob.ResourceDescriptor->PhysicalStart < (EFI_PHYSICAL_ADDRESS)
> 0x100000000) {
> +          *LowMemoryLength += (UINT64) (Hob.ResourceDescriptor-
> >ResourceLength);
> +        } else if (Hob.ResourceDescriptor->PhysicalStart >=
> (EFI_PHYSICAL_ADDRESS) 0x100000000) {
> +          *HighMemoryLength += (UINT64) (Hob.ResourceDescriptor-
> >ResourceLength);
> +        }
> +      }
> +    }
> +    Hob.Raw = GET_NEXT_HOB (Hob);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Publish Memory Type Information.
> +
> +  @param  NULL
> +
> +  @retval EFI_SUCCESS    Success.
> +  @retval Others         Errors have occurred.
> +**/
> +
> +EFI_STATUS
> +EFIAPI
> +PublishMemoryTypeInfo (
> +  void
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;
> +  UINTN                           DataSize;
> +  EFI_MEMORY_TYPE_INFORMATION     MemoryData[EfiMaxMemoryType
> + 1];
> +
> +  Status = PeiServicesLocatePpi (
> +             &gEfiPeiReadOnlyVariable2PpiGuid,
> +             0,
> +             NULL,
> +            (void **)&Variable
> +             );
> +  if (EFI_ERROR(Status)) {
> +    DEBUG((EFI_D_ERROR, "WARNING: Locating Pei variable failed 0x%x \n",
> Status));
> +    DEBUG((EFI_D_ERROR, "Build Hob from default\n"));
> +    //
> +    // Build the default GUID'd HOB for DXE
> +    //
> +    BuildGuidDataHob (
> +      &gEfiMemoryTypeInformationGuid,
> +      mDefaultMemoryTypeInformation,
> +      sizeof (mDefaultMemoryTypeInformation)
> +      );
> +
> +    return Status;
> +  }
> +
> +
> +  DataSize = sizeof (MemoryData);
> +
> +  //
> +  // This variable is saved in BDS stage. Now read it back
> +  //
> +  Status = Variable->GetVariable (
> +                       Variable,
> +                       EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
> +                       &gEfiMemoryTypeInformationGuid,
> +                       NULL,
> +                       &DataSize,
> +                       &MemoryData
> +                       );
> +  if (EFI_ERROR (Status)) {
> +  	//
> +    //build default
> +    //
> +    DEBUG((EFI_D_ERROR, "Build Hob from default\n"));
> +    BuildGuidDataHob (
> +      &gEfiMemoryTypeInformationGuid,
> +      mDefaultMemoryTypeInformation,
> +      sizeof (mDefaultMemoryTypeInformation)
> +      );
> +
> +  } else {
> +  	//
> +    // Build the GUID'd HOB for DXE from variable
> +    //
> +    DEBUG((EFI_D_ERROR, "Build Hob from variable \n"));
> +    BuildGuidDataHob (
> +      &gEfiMemoryTypeInformationGuid,
> +      MemoryData,
> +      DataSize
> +      );
> +  }
> +
> +  return Status;
> +}
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PchInitPeim.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PchInitPeim.c
> new file mode 100644
> index 0000000000..38b17156f4
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PchInitPeim.c
> @@ -0,0 +1,808 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  PchInitPeim.c
> +
> +Abstract:
> +
> +  Do Early PCH platform initialization.
> +
> +
> +--*/
> +
> +#include "PlatformEarlyInit.h"
> +#include "Ppi/PchPlatformPolicy.h"
> +#include "PchRegs.h"
> +#include <Ppi/PchUsbPolicy.h>
> +#include "Ppi/PchInit.h"
> +#include <Library/PcdLib.h>
> +
> +EFI_GUID  gPchPlatformPolicyPpiGuid =
> PCH_PLATFORM_POLICY_PPI_GUID;
> +
> +#define MC_PMSTS_OFFSET                 0xC
> +
> +#define DEFAULT_BUS_INFO                0x2020
> +
> +
> +#define PCI_LPC_BASE    (0x8000F800)
> +#define PCI_LPC_REG(x)  (PCI_LPC_BASE + (x))
> +#define PCIEX_BASE_ADDRESS                        0xE0000000
> +#define PciD31F0RegBase                           PCIEX_BASE_ADDRESS + (UINT32)
> (31 << 15)
> +
> +VOID
> +PchPolicySetupInit (
> +  IN CONST EFI_PEI_SERVICES **PeiServices,
> +  IN SYSTEM_CONFIGURATION   *SystemConfiguration
> +  );
> +
> +VOID
> +PchInitInterrupt (
> +  IN SYSTEM_CONFIGURATION  *SystemConfiguration
> +  );
> +
> +EFI_STATUS
> +InstallPeiPchUsbPolicy (
> +  IN CONST  EFI_PEI_SERVICES  **PeiServices
> +  );
> +
> +#ifndef __GNUC__
> +#pragma warning (push)
> +#pragma warning (disable : 4245)
> +#pragma warning (pop)
> +#endif
> +
> +UINT8
> +ReadCmosBank1Byte (
> +  IN UINT8                      Address
> +  )
> +{
> +  UINT8                           Data;
> +
> +  IoWrite8(R_PCH_RTC_EXT_INDEX, Address);
> +  Data = IoRead8 (R_PCH_RTC_EXT_TARGET);
> +  return Data;
> +}
> +
> +VOID
> +WriteCmosBank1Byte (
> +  IN UINT8                     Address,
> +  IN UINT8                     Data
> +  )
> +{
> +  IoWrite8(R_PCH_RTC_EXT_INDEX, Address);
> +  IoWrite8(R_PCH_RTC_EXT_TARGET, Data);
> +}
> +
> +/**
> +  Turn off system if needed.
> +
> +  @param PeiServices Pointer to PEI Services
> +  @param CpuIo       Pointer to CPU I/O Protocol
> +
> +  @retval None.
> +
> +**/
> +VOID
> +CheckPowerOffNow (
> +  VOID
> +  )
> +{
> +  UINT16  Pm1Sts;
> +
> +  //
> +  // Read and check the ACPI registers
> +  //
> +  Pm1Sts = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS);
> +  if ((Pm1Sts & B_PCH_ACPI_PM1_STS_PWRBTN) ==
> B_PCH_ACPI_PM1_STS_PWRBTN) {
> +    IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS,
> B_PCH_ACPI_PM1_STS_PWRBTN);
> +    IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT,
> V_PCH_ACPI_PM1_CNT_S5);
> +    IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT,
> V_PCH_ACPI_PM1_CNT_S5 + B_PCH_ACPI_PM1_CNT_SLP_EN);
> +
> +    //
> +    // Should not return
> +    //
> +    CpuDeadLoop();
> +  }
> +}
> +
> +VOID
> +ClearPowerState (
> +  IN SYSTEM_CONFIGURATION        *SystemConfiguration
> +  )
> +{
> +  UINT8   Data8;
> +  UINT16  Data16;
> +  UINT32  Data32;
> +
> +  //
> +  // Check for PowerState option for AC power loss and program the chipset
> +  //
> +
> +  //
> +  // Clear PWROK (Set to Clear)
> +  //
> +  MmioOr32 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1,
> B_PCH_PMC_GEN_PMCON_PWROK_FLR);
> +
> +  //
> +  // Clear Power Failure Bit (Set to Clear)
> +  //
> +  // TODO: Check if it is OK to clear here
> +  //
> +
> +  MmioOr32 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1,
> B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR);
> +
> +  //
> +  // Clear the GPE and PM enable
> +  //
> +  IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_EN, (UINT16) 0x00);
> +  IoWrite32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_GPE0a_EN, (UINT32)
> 0x00);
> +
> +  //
> +  // Halt the TCO timer
> +  //
> +  Data16 = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_TCO_CNT);
> +  Data16 |= B_PCH_TCO_CNT_TMR_HLT;
> +  IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_TCO_CNT, Data16);
> +
> +  //
> +  // if NMI_NOW_STS is set
> +  // NMI NOW bit is "Write '1' to clear"
> +  //
> +  Data8 = MmioRead8(ILB_BASE_ADDRESS + R_PCH_ILB_GNMI);
> +  if ((Data8 & B_PCH_ILB_GNMI_NMINS) == B_PCH_ILB_GNMI_NMINS) {
> +    MmioOr8 (ILB_BASE_ADDRESS + R_PCH_ILB_GNMI,
> B_PCH_ILB_GNMI_NMIN);
> +  }
> +
> +  //
> +  // Before we clear the TO status bit here we need to save the results in a
> CMOS bit for later use.
> +  //
> +  Data32 = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_TCO_STS);
> +  if ((Data32 & B_PCH_TCO_STS_SECOND_TO) ==
> B_PCH_TCO_STS_SECOND_TO)
> +  {
> +#if (defined(HW_WATCHDOG_TIMER_SUPPORT) &&
> (HW_WATCHDOG_TIMER_SUPPORT != 0))
> +    WriteCmosBank1Byte (
> +      EFI_CMOS_PERFORMANCE_FLAGS,
> +      ReadCmosBank1Byte (EFI_CMOS_PERFORMANCE_FLAGS) |
> B_CMOS_TCO_WDT_RESET
> +      );
> +#endif
> +  }
> +}
> +
> +/*++
> +
> +  Clear any SMI status or wake status left over from boot.
> +
> +**/
> +VOID
> +ClearSmiAndWake (
> +  VOID
> +  )
> +{
> +  UINT16  Pm1Sts;
> +  UINT32  Gpe0Sts;
> +  UINT32  SmiSts;
> +
> +  //
> +  // Read the ACPI registers
> +  //
> +  Pm1Sts  = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS);
> +  Gpe0Sts = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_GPE0a_STS);
> +  SmiSts  = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_SMI_STS);
> +
> +  //
> +  // Register Wake up reason for S4.  This information is used to notify
> +  // WinXp of wake up reason because S4 wake up path doesn't keep SCI.
> +  // This is important for Viiv(Quick resume) platform.
> +  //
> +
> +  //
> +  // First Clear CMOS S4 Wake up flag.
> +  //
> +  WriteCmosBank1Byte(CMOS_S4_WAKEUP_FLAG_ADDRESS, 0);
> +
> +  //
> +  // Check wake up reason and set CMOS accordingly.  Currently checks
> +  // Power button, USB, PS/2.
> +  // Note : PS/2 wake up is using GPI13 (IO_PME).  This must be changed
> depending
> +  // on board design.
> +  //
> +  if ((Pm1Sts & B_PCH_ACPI_PM1_STS_PWRBTN) || (Gpe0Sts &
> (B_PCH_ACPI_GPE0a_STS_CORE_GPIO |
> B_PCH_ACPI_GPE0a_STS_SUS_GPIO))) {
> +    WriteCmosBank1Byte(CMOS_S4_WAKEUP_FLAG_ADDRESS, 1);
> +  }
> +
> +  //
> +  // Clear any SMI or wake state from the boot
> +  //
> +  Pm1Sts = (B_PCH_ACPI_PM1_STS_PRBTNOR |
> B_PCH_ACPI_PM1_STS_PWRBTN);
> +
> +  Gpe0Sts |=
> +    (
> +      B_PCH_ACPI_GPE0a_STS_CORE_GPIO |
> +      B_PCH_ACPI_GPE0a_STS_SUS_GPIO |
> +      B_PCH_ACPI_GPE0a_STS_PME_B0 |
> +      B_PCH_ACPI_GPE0a_STS_BATLOW |
> +      B_PCH_ACPI_GPE0a_STS_PCI_EXP |
> +      B_PCH_ACPI_GPE0a_STS_GUNIT_SCI |
> +      B_PCH_ACPI_GPE0a_STS_PUNIT_SCI |
> +      B_PCH_ACPI_GPE0a_STS_SWGPE |
> +      B_PCH_ACPI_GPE0a_STS_HOT_PLUG
> +    );
> +
> +  SmiSts |=
> +    (
> +      B_PCH_SMI_STS_SMBUS |
> +      B_PCH_SMI_STS_PERIODIC |
> +      B_PCH_SMI_STS_TCO |
> +      B_PCH_SMI_STS_SWSMI_TMR |
> +      B_PCH_SMI_STS_APM |
> +      B_PCH_SMI_STS_ON_SLP_EN |
> +      B_PCH_SMI_STS_BIOS
> +    );
> +
> +  //
> +  // Write them back
> +  //
> +  IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS, Pm1Sts);
> +  IoWrite32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_GPE0a_STS, Gpe0Sts);
> +  IoWrite32 (ACPI_BASE_ADDRESS + R_PCH_SMI_STS, SmiSts);
> +}
> +
> +/**
> +  Issue PCI-E Secondary Bus Reset
> +
> +  @param Bus  Bus number of the bridge
> +  @param Dev  Devices number of the bridge
> +  @param Fun  Function number of the bridge
> +
> +  @retval EFI_SUCCESS
> +
> +**/
> +EFI_STATUS
> +PcieSecondaryBusReset (
> +  IN CONST EFI_PEI_SERVICES  **PeiServices,
> +  IN UINT8             Bus,
> +  IN UINT8             Dev,
> +  IN UINT8             Fun
> +  )
> +{
> +  EFI_PEI_STALL_PPI   *PeiStall;
> +  EFI_STATUS          Status;
> +
> +  Status = (**PeiServices).LocatePpi (
> +                             PeiServices,
> +                             &gEfiPeiStallPpiGuid,
> +                             0,
> +                             NULL,
> +                    (void **)&PeiStall
> +                             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Issue secondary bus reset
> +  //
> +  MmPci16Or(0, Bus, Dev, Fun, PCI_BRIDGE_CONTROL_REGISTER_OFFSET,
> EFI_PCI_BRIDGE_CONTROL_RESET_SECONDARY_BUS);
> +
> +  //
> +  // Wait 1ms
> +  //
> +  PeiStall->Stall (PeiServices, PeiStall, 1000);
> +
> +
> +  //
> +  // Clear the reset bit
> +  // Note: The PCIe spec suggests 100ms delay between clearing this bit and
> accessing
> +  // the device's config space. Since we will not access the config space until
> we enter DXE
> +  // we don't put delay expressly here.
> +  //
> +  MmPci16And(0, Bus, Dev, Fun, PCI_BRIDGE_CONTROL_REGISTER_OFFSET,
> ~(EFI_PCI_BRIDGE_CONTROL_RESET_SECONDARY_BUS));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Provide hard reset PPI service.
> +  To generate full hard reset, write 0x0E to ICH RESET_GENERATOR_PORT
> (0xCF9).
> +
> +  @param PeiServices        General purpose services available to every PEIM.
> +
> +  @retval Not return        System reset occured.
> +  @retval EFI_DEVICE_ERROR  Device error, could not reset the system.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +IchReset (
> +  IN CONST EFI_PEI_SERVICES          **PeiServices
> +  )
> +{
> +  IoWrite8 (
> +    R_PCH_RST_CNT,
> +    V_PCH_RST_CNT_HARDSTARTSTATE
> +    );
> +
> +  IoWrite8 (
> +    R_PCH_RST_CNT,
> +    V_PCH_RST_CNT_HARDRESET
> +    );
> +
> +  //
> +  // System reset occured, should never reach at this line.
> +  //
> +  ASSERT_EFI_ERROR (EFI_DEVICE_ERROR);
> +  CpuDeadLoop();
> +
> +  return EFI_DEVICE_ERROR;
> +}
> +
> +VOID
> +PchPlatformLpcInit (
> +  IN  CONST EFI_PEI_SERVICES          **PeiServices,
> +  IN SYSTEM_CONFIGURATION       *SystemConfiguration
> +  )
> +{
> +  EFI_BOOT_MODE BootMode;
> +  UINT8         Data8;
> +  UINT16                Data16;
> +
> +  (*PeiServices)->GetBootMode(PeiServices, &BootMode);
> +
> +  if ((BootMode != BOOT_ON_S3_RESUME)) {
> +
> +    //
> +    // Clear all pending SMI. On S3 clear power button enable so it wll not
> generate an SMI
> +    //
> +    ClearSmiAndWake ();
> +  }
> +
> +  ClearPowerState (SystemConfiguration);
> +
> +  //
> +  // Need to set and clear SET bit (RTC_REGB Bit 7) as requested by the ICH
> EDS
> +  // early in POST after each power up directly after coin-cell battery
> insertion.
> +  // This is to avoid the UIP bit (RTC_REGA Bit 7) from stuck at "1".
> +  // The UIP bit status may be polled by software (i.e ME FW) during POST.
> +  //
> +  if (MmioRead8 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1) &
> B_PCH_PMC_GEN_PMCON_RTC_PWR_STS) {
> +  	//
> +    // Set and clear SET bit in RTC_REGB
> +    //
> +    IoWrite8(R_PCH_RTC_INDEX, R_PCH_RTC_REGISTERB);
> +    Data8 = IoRead8(R_PCH_RTC_TARGET);
> +    Data8 |= B_PCH_RTC_REGISTERB_SET;
> +    IoWrite8(R_PCH_RTC_TARGET, Data8);
> +
> +    IoWrite8(R_PCH_RTC_INDEX, R_PCH_RTC_REGISTERB);
> +    Data8 &= (~B_PCH_RTC_REGISTERB_SET);
> +    IoWrite8(R_PCH_RTC_TARGET, Data8);
> +
> +    //
> +    // Clear the UIP bit in RTC_REGA
> +    //
> +    IoWrite8(R_PCH_RTC_INDEX, R_PCH_RTC_REGISTERA);
> +    IoWrite8(R_PCH_RTC_TARGET, 0x00);
> +  }
> +
> +  //
> +  // Disable SERR NMI and IOCHK# NMI in port 61
> +  //
> +  Data8 = IoRead8 (R_PCH_NMI_SC);
> +  IoWrite8(R_PCH_NMI_SC, (UINT8) (Data8 |
> B_PCH_NMI_SC_PCI_SERR_EN | B_PCH_NMI_SC_IOCHK_NMI_EN));
> +
> +  //
> +  // Enable Bus Master, I/O, Mem, and SERR on LPC bridge
> +  //
> +  Data16 = PchLpcPciCfg16 (R_PCH_LPC_COMMAND);
> +  MmioWrite16 (
> +    MmPciAddress (0,
> +      DEFAULT_PCI_BUS_NUMBER_PCH,
> +      PCI_DEVICE_NUMBER_PCH_LPC,
> +      PCI_FUNCTION_NUMBER_PCH_LPC,
> +      R_PCH_LPC_COMMAND
> +    ),
> +    (Data16 |
> +     B_PCH_LPC_COMMAND_IOSE |
> +     B_PCH_LPC_COMMAND_MSE |
> +     B_PCH_LPC_COMMAND_BME |
> +     B_PCH_LPC_COMMAND_SERR_EN)
> +  );
> +
> +  //
> +  // Set Stretch S4 to 1-2s per marketing request.
> +  // Note: This register is powered by RTC well.
> +  //
> +  MmioAndThenOr8 (
> +    PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1 ,
> +    (UINT8) (~B_PCH_PMC_GEN_PMCON_SLP_S4_MAW),
> +    (UINT8) (B_PCH_PMC_GEN_PMCON_SLP_S4_ASE |
> V_PCH_PMC_GEN_PMCON_SLP_S4_MAW_4S)
> +    );
> +
> +}
> +
> +#define V_PCH_ILB_IRQE_UARTIRQEN_IRQ3             BIT3 // UART IRQ3
> Enable
> +
> +VOID
> +UARTInit (
> +  IN SYSTEM_CONFIGURATION        *SystemConfiguration
> +  )
> +{
> +  if (0) { // for fix cr4 issue
> +    //
> +    // Program and enable PMC Base.
> +    //
> +    IoWrite32 (0xCF8,  PCI_LPC_REG(R_PCH_LPC_PMC_BASE));
> +    IoWrite32 (0xCFC,  (PMC_BASE_ADDRESS | B_PCH_LPC_PMC_BASE_EN));
> +
> +    if( (SystemConfiguration->PcuUart1 == 1) &&
> +        (SystemConfiguration->LpssHsuart0Enabled == 0)){
> +      //
> +      // Enable COM1 for debug message output.
> +      //
> +      MmioOr32 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1,
> BIT24);
> +
> +      //
> +      //Enable internal UART3 port(COM1)
> +      //
> +      MmioOr8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8)
> V_PCH_ILB_IRQE_UARTIRQEN_IRQ3);
> +      MmioOr32 (IO_BASE_ADDRESS + 0x0520, 0x01); // UART3_RXD-L
> +      MmioOr32 (IO_BASE_ADDRESS + 0x0530, 0x01); // UART3_TXD-0
> +      MmioOr8 (PciD31F0RegBase + R_PCH_LPC_UART_CTRL, (UINT8)
> B_PCH_LPC_UART_CTRL_COM1_EN);
> +    } else {
> +    	//
> +      //Disable UART3(COM1)
> +      //
> +      MmioAnd8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8)
> ~V_PCH_ILB_IRQE_UARTIRQEN_IRQ3);
> +      MmioAnd32 (IO_BASE_ADDRESS + 0x0520, ~(UINT32)0x07);
> +      MmioAnd32 (IO_BASE_ADDRESS + 0x0530, ~(UINT32)0x07);
> +      MmioAnd8 (PciD31F0RegBase + R_PCH_LPC_UART_CTRL, (UINT8)
> ~B_PCH_LPC_UART_CTRL_COM1_EN);
> +
> +
> +      if (SystemConfiguration->LpssHsuart0Enabled == 1){
> +        //
> +        //Valleyview BIOS Specification Vol2,17.2
> +        //LPSS_UART1 �C set each pad PAD_CONF0.Func_Pin_Mux to function
> 1:
> +        //
> +        MmioAnd8 (IO_BASE_ADDRESS + 0x0090, (UINT8)~0x07);
> +        MmioOr8 (IO_BASE_ADDRESS + 0x0090, 0x01);
> +        MmioAnd8 (IO_BASE_ADDRESS + 0x00D0, (UINT8)~0x07);
> +        MmioOr8 (IO_BASE_ADDRESS + 0x00D0, 0x01);
> +
> +      }
> +    }
> +
> +
> +    DEBUG ((EFI_D_ERROR, "EnableInternalUart\n"));
> +  } else {
> +  	//
> +    // If SIO UART interface selected
> +    //Disable internal UART port(COM1)
> +    //
> +    if (0) {; // For fix CR4 issue
> +      MmioAnd8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8)
> ~V_PCH_ILB_IRQE_UARTIRQEN_IRQ3);
> +      MmioAnd8 (IO_BASE_ADDRESS + 0x0090, (UINT8)~0x07);
> +      MmioAnd8 (IO_BASE_ADDRESS + 0x00D0, (UINT8)~0x07);
> +      MmioAnd8 (PciD31F0RegBase + R_PCH_LPC_UART_CTRL, (UINT8)
> ~B_PCH_LPC_UART_CTRL_COM1_EN);
> +
> +    }
> +  }
> +}
> +
> +VOID
> +IchRcrbInit (
> +  IN CONST EFI_PEI_SERVICES            **PeiServices,
> +  IN SYSTEM_CONFIGURATION        *SystemConfiguration
> +  )
> +{
> +  EFI_BOOT_MODE                   BootMode;
> +
> +  (*PeiServices)->GetBootMode(PeiServices, &BootMode);
> +
> +  //
> +  // If not recovery or flash update boot path. set the BIOS interface lock
> down bit.
> +  // It locks the top swap bit and BIOS boot strap bits from being changed.
> +  //
> +  if ((BootMode != BOOT_IN_RECOVERY_MODE) && (BootMode !=
> BOOT_ON_FLASH_UPDATE)) {
> +    MmioOr8 (RCBA_BASE_ADDRESS + R_PCH_RCRB_GCS,
> B_PCH_RCRB_GCS_BILD);
> +  }
> +
> +  //
> +  // Disable the Watchdog timer expiration from causing a system reset
> +  //
> +  MmioOr8 (PMC_BASE_ADDRESS + R_PCH_PMC_PM_CFG,
> B_PCH_PMC_PM_CFG_NO_REBOOT);
> +
> +  //
> +  // Initial RCBA according to the PeiRCBA table
> +  //
> +  if ((BootMode == BOOT_ON_S3_RESUME)) {
> +    //
> +    // We are resuming from S3
> +    // Enable HPET if enabled in Setup
> +    // ICH Config register Offset 0x3404 bit 7 (Enable) = 1,
> +    // Bit 1:0 (Mem I/O address) = 0 (0xFED00000)
> +    //
> +    MmioOr8 (R_PCH_PCH_HPET + R_PCH_PCH_HPET_GCFG,
> B_PCH_PCH_HPET_GCFG_EN);
> +
> +  }
> +
> +}
> +
> +
> +EFI_STATUS
> +PlatformPchInit (
> +  IN SYSTEM_CONFIGURATION        *SystemConfiguration,
> +  IN CONST EFI_PEI_SERVICES      **PeiServices,
> +  IN UINT16                      PlatformType
> +  )
> +{
> +  EFI_STATUS     Status;
> +  EFI_BOOT_MODE  BootMode;
> +
> +  Status = PeiServicesGetBootMode (&BootMode);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  IchRcrbInit (PeiServices, SystemConfiguration);
> +
> +  if (BootMode == BOOT_IN_RECOVERY_MODE) {
> +    InstallPeiPchUsbPolicy(PeiServices);
> +  }
> +
> +  //
> +  // PCH Policy Initialization based on Setup variable.
> +  //
> +  PchPolicySetupInit (PeiServices, SystemConfiguration);
> +
> +  UARTInit(SystemConfiguration);
> +
> +  PchPlatformLpcInit (PeiServices, SystemConfiguration);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +  Returns the state of A16 inversion
> +
> +  @retval TRUE    A16 is inverted
> +  @retval FALSE   A16 is not inverted
> +
> +**/
> +BOOLEAN
> +IsA16Inverted (
> +  )
> +{
> +  UINT8  Data;
> +  Data = MmioRead8 (RCBA_BASE_ADDRESS + R_PCH_RCRB_GCS);
> +  return (Data & B_PCH_RCRB_GCS_TS) ? TRUE : FALSE;
> +}
> +
> +VOID
> +PchPolicySetupInit (
> +  IN CONST EFI_PEI_SERVICES **PeiServices,
> +  IN SYSTEM_CONFIGURATION   *SystemConfiguration
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_PEI_PPI_DESCRIPTOR      *PchPlatformPolicyPpiDesc;
> +  PCH_PLATFORM_POLICY_PPI     *PchPlatformPolicyPpi;
> +  PCH_HPET_CONFIG             *HpetConfig;
> +  PCH_PCIE_CONFIG             *PcieConfig;
> +  UINT8                       Index;
> +  PCH_IOAPIC_CONFIG           *IoApicConfig;
> +  PCH_LPSS_CONFIG             *LpssConfig;
> +  UINT32                      SpiHsfsReg;
> +  UINT32                      SpiFdodReg;
> +
> +//
> +// Disable codec ALC-262
> +//
> +  UINT32                      IoBase;
> +
> +  //
> +  // Install Pch Platform Policy PPI. As we depend on Pch Init PPI so we are
> executed after
> +  // PchInit PEIM. Thus we can insure PCH Initialization is performed when
> we install the Pch Platform Policy PPI,
> +  // as PchInit PEIM registered a notification function on our policy PPI.
> +  //
> +  // --cr-- For better code structure / modularity, we should use a
> notification function on Pch Init PPI to perform
> +  // actions that depend on PchInit PEIM's initialization.
> +  //
> +  //Todo: confirm if we need update to
> PCH_PLATFORM_POLICY_PPI_REVISION_5
> +  //
> +  DEBUG ((EFI_D_ERROR, "PchPolicySetupInit() - Start\n"));
> +
> +  Status = (*PeiServices)->AllocatePool (PeiServices, sizeof
> (EFI_PEI_PPI_DESCRIPTOR), (void **)&PchPlatformPolicyPpiDesc);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = (*PeiServices)->AllocatePool (PeiServices, sizeof
> (PCH_PLATFORM_POLICY_PPI), (void **)&PchPlatformPolicyPpi);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = (*PeiServices)->AllocatePool (PeiServices, sizeof
> (PCH_HPET_CONFIG), (void **)&HpetConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = (*PeiServices)->AllocatePool (PeiServices, sizeof
> (PCH_PCIE_CONFIG), (void **)&PcieConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = (*PeiServices)->AllocatePool (PeiServices, sizeof
> (PCH_IOAPIC_CONFIG), (void **)&IoApicConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = (*PeiServices)->AllocatePool (PeiServices, sizeof
> (PCH_LPSS_CONFIG), (void **)&LpssConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  PchPlatformPolicyPpi->Revision                =
> PCH_PLATFORM_POLICY_PPI_REVISION_1;
> +  PchPlatformPolicyPpi->BusNumber               =
> DEFAULT_PCI_BUS_NUMBER_PCH;
> +  PchPlatformPolicyPpi->SpiBase                 = SPI_BASE_ADDRESS;
> +  PchPlatformPolicyPpi->PmcBase                 = PMC_BASE_ADDRESS;
> +  PchPlatformPolicyPpi->IoBase                  = IO_BASE_ADDRESS;
> +  PchPlatformPolicyPpi->IlbBase                 = ILB_BASE_ADDRESS;
> +  PchPlatformPolicyPpi->PUnitBase               = PUNIT_BASE_ADDRESS;
> +  PchPlatformPolicyPpi->MphyBase                = MPHY_BASE_ADDRESS;
> +  PchPlatformPolicyPpi->Rcba                    = RCBA_BASE_ADDRESS;
> +  PchPlatformPolicyPpi->AcpiBase                = ACPI_BASE_ADDRESS;
> +  PchPlatformPolicyPpi->GpioBase                = GPIO_BASE_ADDRESS;
> +  PchPlatformPolicyPpi->SataMode                = SystemConfiguration-
> >SataType;
> +  PchPlatformPolicyPpi->EnableRmh               = SystemConfiguration-
> >PchUsbRmh;
> +
> +  PchPlatformPolicyPpi->EhciPllCfgEnable        = SystemConfiguration-
> >EhciPllCfgEnable;
> +
> +
> +  PchPlatformPolicyPpi->HpetConfig              = HpetConfig;
> +  PchPlatformPolicyPpi->PcieConfig              = PcieConfig;
> +  PchPlatformPolicyPpi->IoApicConfig            = IoApicConfig;
> +
> +  PchPlatformPolicyPpi->HpetConfig->Enable      = SystemConfiguration-
> >Hpet;
> +  PchPlatformPolicyPpi->HpetConfig->Base        = HPET_BASE_ADDRESS;
> +  PchPlatformPolicyPpi->IoApicConfig->IoApicId  = 0x01;
> +
> +  //
> +  // Set LPSS configuration according to setup value.
> +  //
> +  PchPlatformPolicyPpi->LpssConfig->LpssPciModeEnabled   =
> SystemConfiguration->LpssPciModeEnabled;
> +
> +  PchPlatformPolicyPpi->LpssConfig->Dma1Enabled    =
> SystemConfiguration->LpssDma1Enabled;
> +  PchPlatformPolicyPpi->LpssConfig->I2C0Enabled    = SystemConfiguration-
> >LpssI2C0Enabled;
> +  PchPlatformPolicyPpi->LpssConfig->I2C1Enabled    = SystemConfiguration-
> >LpssI2C1Enabled;
> +  PchPlatformPolicyPpi->LpssConfig->I2C2Enabled    = SystemConfiguration-
> >LpssI2C2Enabled;
> +  PchPlatformPolicyPpi->LpssConfig->I2C3Enabled    = SystemConfiguration-
> >LpssI2C3Enabled;
> +  PchPlatformPolicyPpi->LpssConfig->I2C4Enabled    = SystemConfiguration-
> >LpssI2C4Enabled;
> +  PchPlatformPolicyPpi->LpssConfig->I2C5Enabled    = SystemConfiguration-
> >LpssI2C5Enabled;
> +  PchPlatformPolicyPpi->LpssConfig->I2C6Enabled    = SystemConfiguration-
> >LpssI2C6Enabled;
> +
> +  PchPlatformPolicyPpi->LpssConfig->Dma0Enabled    =
> SystemConfiguration->LpssDma0Enabled;;
> +  PchPlatformPolicyPpi->LpssConfig->Pwm0Enabled    =
> SystemConfiguration->LpssPwm0Enabled;
> +  PchPlatformPolicyPpi->LpssConfig->Pwm1Enabled    =
> SystemConfiguration->LpssPwm1Enabled;
> +  PchPlatformPolicyPpi->LpssConfig->Hsuart0Enabled =
> SystemConfiguration->LpssHsuart0Enabled;
> +  PchPlatformPolicyPpi->LpssConfig->Hsuart1Enabled =
> SystemConfiguration->LpssHsuart1Enabled;
> +  PchPlatformPolicyPpi->LpssConfig->SpiEnabled     = SystemConfiguration-
> >LpssSpiEnabled;
> +
> +
> +  for (Index = 0; Index < PCH_PCIE_MAX_ROOT_PORTS; Index++) {
> +    PchPlatformPolicyPpi->PcieConfig->PcieSpeed[Index] =
> SystemConfiguration->PcieRootPortSpeed[Index];
> +  }
> +
> +  SpiHsfsReg = MmioRead32 (SPI_BASE_ADDRESS + R_PCH_SPI_HSFS);
> +  if ((SpiHsfsReg & B_PCH_SPI_HSFS_FDV) == B_PCH_SPI_HSFS_FDV) {
> +    MmioWrite32 (SPI_BASE_ADDRESS + R_PCH_SPI_FDOC,
> V_PCH_SPI_FDOC_FDSS_FSDM);
> +    SpiFdodReg = MmioRead32 (SPI_BASE_ADDRESS + R_PCH_SPI_FDOD);
> +    if (SpiFdodReg == V_PCH_SPI_FDBAR_FLVALSIG) {
> +    }
> +  //
> +  // Disable codec ALC-262
> +  //
> +  if (SystemConfiguration->DisableCodec262 == 1) {
> +      IoBase = MmioRead32 (MmPciAddress (0,
> +                        PchPlatformPolicyPpi->BusNumber,
> +                        PCI_DEVICE_NUMBER_PCH_LPC,
> +                        PCI_FUNCTION_NUMBER_PCH_LPC,
> +                        0
> +                      ) + R_PCH_LPC_IO_BASE) & B_PCH_LPC_IO_BASE_BAR;
> +      MmioAnd32 ((UINTN) (IoBase + 0x270), (UINT32) (~0x07));
> +  }
> +  }
> +
> +  PchPlatformPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
> +  PchPlatformPolicyPpiDesc->Guid = &gPchPlatformPolicyPpiGuid;
> +  PchPlatformPolicyPpiDesc->Ppi = PchPlatformPolicyPpi;
> +
> +  //
> +  // Install PCH Platform Policy PPI
> +  //
> +  Status = (**PeiServices).InstallPpi (
> +              PeiServices,
> +              PchPlatformPolicyPpiDesc
> +              );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  DEBUG ((EFI_D_ERROR, "PchPolicySetupInit() - End\n"));
> +}
> +
> +EFI_STATUS
> +InstallPeiPchUsbPolicy (
> +  IN CONST  EFI_PEI_SERVICES  **PeiServices
> +  )
> +{
> +  EFI_STATUS              Status = EFI_SUCCESS;
> +
> +  EFI_PEI_PPI_DESCRIPTOR  *PeiPchUsbPolicyPpiDesc;
> +  PCH_USB_POLICY_PPI      *PeiPchUsbPolicyPpi;
> +  PCH_USB_CONFIG          *UsbConfig;
> +
> +  DEBUG ((EFI_D_INFO, "InstallPeiPchUsbPolicy...\n"));
> +
> +  //
> +  // Allocate descriptor and PPI structures.  Since these are dynamically
> updated
> +  // we cannot do a global variable PPI.
> +  //
> +  Status = (*PeiServices)->AllocatePool (PeiServices, sizeof
> (EFI_PEI_PPI_DESCRIPTOR), (void **)&PeiPchUsbPolicyPpiDesc);
> +
> +
> +  Status = (*PeiServices)->AllocatePool (PeiServices, sizeof
> (PCH_USB_POLICY_PPI), (void **)&PeiPchUsbPolicyPpi);
> +
> +
> +
> +  Status = (*PeiServices)->AllocatePool (PeiServices, sizeof
> (PCH_USB_CONFIG), (void **)&UsbConfig);
> +
> +
> +  //
> +  // Initiate PCH USB policy.
> +  //
> +  PeiPchUsbPolicyPpi->Revision = PCH_USB_POLICY_PPI_REVISION_1;
> +  UsbConfig->Usb20Settings[0].Enable  = PCH_DEVICE_ENABLE;
> +  UsbConfig->UsbPerPortCtl            = PCH_DEVICE_DISABLE;
> +  UsbConfig->Ehci1Usbr                = PCH_DEVICE_DISABLE;
> +
> +  UsbConfig->Usb20OverCurrentPins[0] = PchUsbOverCurrentPin0;
> +
> +  UsbConfig->Usb20OverCurrentPins[1] = PchUsbOverCurrentPin0;
> +
> +  UsbConfig->Usb20OverCurrentPins[2] = PchUsbOverCurrentPin1;
> +
> +  UsbConfig->Usb20OverCurrentPins[3] = PchUsbOverCurrentPin1;
> +
> +
> +  //
> +  // Enable USB Topology control and program the topology setting for every
> USB port
> +  // See Platform Design Guide for description of topologies
> +  //
> +    //
> +    // Port 0: ~10.9", Port 1: ~10.1", Port 2: ~11.2", Port 3: ~11.5", Port 4: ~3.7",
> Port 5: ~2.7", Port 6: ~4.1"
> +    // Port 7: ~4.5", Port 8: ~10.7", Port 9: ~10.5", Port 10: ~4.2", Port 11: ~4.3",
> Port 12: ~3.1", Port 13: ~2.9"
> +    //
> +
> +    //
> +    // Port 0: ~3.5", Port 1: ~4.1", Port 2: ~4.6", Port 3: ~4.6", Port 4: ~12.5",
> Port 5: ~12", Port 6: ~5.1"
> +    // Port 7: ~5.1", Port 8: ~4.1", Port 9: ~4.1", Port 10: ~14.5", Port 11: ~12.8",
> Port 12: ~12.9", Port 13: ~14.6"
> +    //
> +  UsbConfig->Usb20PortLength[0]  = 0x53;
> +  UsbConfig->Usb20PortLength[1]  = 0x49;
> +  UsbConfig->Usb20PortLength[2]  = 0x47;
> +  UsbConfig->Usb20PortLength[3]  = 0x80;
> +
> +  PeiPchUsbPolicyPpi->Mode = EHCI_MODE;
> +
> +  PeiPchUsbPolicyPpi->EhciMemBaseAddr =
> PcdGet32(PcdPeiIchEhciControllerMemoryBaseAddress);
> +
> +  PeiPchUsbPolicyPpi->EhciMemLength   = (UINT32) 0x400 *
> PchEhciControllerMax;
> +
> +  PeiPchUsbPolicyPpi->XhciMemBaseAddr = 0;
> +
> +  PeiPchUsbPolicyPpi->UsbConfig       = UsbConfig;
> +
> +  PeiPchUsbPolicyPpiDesc->Flags       = EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
> +
> +  PeiPchUsbPolicyPpiDesc->Guid        = &gPchUsbPolicyPpiGuid;
> +
> +  PeiPchUsbPolicyPpiDesc->Ppi         = PeiPchUsbPolicyPpi;
> +
> +  //
> +  // Install PCH USB Policy PPI
> +  //
> +  Status = (**PeiServices).InstallPpi (PeiServices, PeiPchUsbPolicyPpiDesc);
> +
> +  return Status;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.c
> new file mode 100644
> index 0000000000..a359c95920
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.c
> @@ -0,0 +1,1195 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  PlatformEarlyInit.c
> +
> +Abstract:
> +
> +  Do platform specific PEI stage initializations.
> +
> +--*/
> +
> +
> +#include "PlatformEarlyInit.h"
> +
> +#ifdef __GNUC__
> +#pragma GCC push_options
> +#pragma GCC optimize ("O0")
> +#else
> +#pragma optimize ("", off)
> +#endif
> +
> +
> +
> +static EFI_PEI_STALL_PPI  mStallPpi = {
> +  PEI_STALL_RESOLUTION,
> +  Stall
> +};
> +
> +static EFI_PEI_PPI_DESCRIPTOR mInstallStallPpi = {
> +  EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
> +  &gEfiPeiStallPpiGuid,
> +  &mStallPpi
> +};
> +
> +//
> +// The reserved SMBus addresses are defined in PlatformDxe.h file.
> +//
> +static UINT8 mSmbusRsvdAddresses[] =
> PLATFORM_SMBUS_RSVD_ADDRESSES;
> +static PEI_SMBUS_POLICY_PPI         mSmbusPolicyPpi = {
> +  SMBUS_BASE_ADDRESS,
> +  SMBUS_BUS_DEV_FUNC,
> +  PLATFORM_NUM_SMBUS_RSVD_ADDRESSES,
> +  mSmbusRsvdAddresses
> +};
> +
> +static EFI_PEI_PPI_DESCRIPTOR       mInstallSmbusPolicyPpi = {
> +  EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
> +  &gPeiSmbusPolicyPpiGuid,
> +  &mSmbusPolicyPpi
> +};
> +static PEI_SPEAKER_IF_PPI    mSpeakerInterfacePpi = {
> +  ProgramToneFrequency,
> +  GenerateBeepTone
> +};
> +
> +static EFI_PEI_PPI_DESCRIPTOR       mInstallSpeakerInterfacePpi = {
> +  EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
> +  &gPeiSpeakerInterfacePpiGuid,
> +  &mSpeakerInterfacePpi
> +};
> +
> +static EFI_PEI_RESET_PPI            mResetPpi = { IchReset };
> +
> +
> +static EFI_PEI_FIND_FV_PPI mEfiFindFvPpi = {
> +  (EFI_PEI_FIND_FV_FINDFV)FindFv
> +};
> +
> +static EFI_PEI_PPI_DESCRIPTOR       mPpiList[] = {
> +  {
> +    EFI_PEI_PPI_DESCRIPTOR_PPI,
> +    &gEfiPeiMasterBootModePpiGuid,
> +    NULL
> +  },
> +  {
> +    EFI_PEI_PPI_DESCRIPTOR_PPI,
> +    &gEfiPeiResetPpiGuid,
> +    &mResetPpi
> +  },
> +  {
> +    (EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> +    &gEfiFindFvPpiGuid,
> +    &mEfiFindFvPpi
> +  }
> +};
> +
> +static EFI_PEI_NOTIFY_DESCRIPTOR    mNotifyList[] = {
> +  {
> +    EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
> +    &gEfiEndOfPeiSignalPpiGuid,
> +    (EFI_PEIM_NOTIFY_ENTRY_POINT)EndOfPeiPpiNotifyCallback
> +  },
> +  {
> +    (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK|
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> +    &gEfiPeiMemoryDiscoveredPpiGuid,
> +    (EFI_PEIM_NOTIFY_ENTRY_POINT)MemoryDiscoveredPpiNotifyCallback
> +  }
> +
> +};
> +
> +
> +/**
> +
> +  Parse the status registers for figuring out the wake-up event and save it
> into
> +  an GUID HOB which will be referenced later. However, modification is
> required
> +  to meet the chipset register definition and the practical hardware design.
> Thus,
> +  this is just an example.
> +
> +
> +  @param PeiServices    pointer to the PEI Service Table
> +  @param EFI_SUCCESS    Always return Success
> +
> +  @retval None
> +
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetWakeupEventAndSaveToHob (
> +  IN CONST EFI_PEI_SERVICES   **PeiServices
> +  )
> +{
> +  UINT16  Pm1Sts;
> +  UINTN   Gpe0Sts;
> +  UINTN   WakeEventData;
> +
> +  //
> +  // Read the ACPI registers
> +  //
> +  Pm1Sts  = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS);
> +  Gpe0Sts = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_GPE0a_STS);
> +
> +  //
> +  // Figure out the wake-up event
> +  //
> +  if ((Pm1Sts & B_PCH_ACPI_PM1_STS_PWRBTN) != 0) {
> +    WakeEventData = SMBIOS_WAKEUP_TYPE_POWER_SWITCH;
> +  } else if (((Pm1Sts & B_PCH_ACPI_PM1_STS_WAK) != 0)) {
> +    WakeEventData = SMBIOS_WAKEUP_TYPE_PCI_PME;
> +  } else if (Gpe0Sts != 0) {
> +    WakeEventData = SMBIOS_WAKEUP_TYPE_OTHERS;
> +  } else {
> +    WakeEventData = SMBIOS_WAKEUP_TYPE_UNKNOWN;
> +  }
> +
> +  DEBUG ((EFI_D_ERROR, "ACPI Wake Status Register: %04x\n", Pm1Sts));
> +  DEBUG ((EFI_D_ERROR, "ACPI Wake Event Data: %02x\n",
> WakeEventData));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +GetSetupVariable (
> +  IN CONST EFI_PEI_SERVICES                **PeiServices,
> +  IN   SYSTEM_CONFIGURATION          *SystemConfiguration
> +  )
> +{
> +  UINTN                        VariableSize;
> +  EFI_STATUS                   Status;
> +  EFI_PEI_READ_ONLY_VARIABLE2_PPI   *Variable;
> +
> +  VariableSize = sizeof (SYSTEM_CONFIGURATION);
> +  ZeroMem (SystemConfiguration, sizeof (SYSTEM_CONFIGURATION));
> +
> +  Status = (*PeiServices)->LocatePpi (
> +                             PeiServices,
> +                             &gEfiPeiReadOnlyVariable2PpiGuid,
> +                             0,
> +                             NULL,
> +                                      (void **)&Variable
> +                             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Use normal setup default from NVRAM variable,
> +  // the Platform Mode (manufacturing/safe/normal) is handle in
> PeiGetVariable.
> +  //
> +  VariableSize = sizeof(SYSTEM_CONFIGURATION);
> +  Status = Variable->GetVariable (
> +                       Variable,
> +                       L"Setup",
> +                       &gEfiSetupVariableGuid,
> +                       NULL,
> +                       &VariableSize,
> +                       SystemConfiguration
> +                       );
> +  if (EFI_ERROR (Status) || VariableSize != sizeof(SYSTEM_CONFIGURATION))
> {
> +    //The setup variable is corrupted
> +    VariableSize = sizeof(SYSTEM_CONFIGURATION);
> +    Status = Variable->GetVariable(
> +              Variable,
> +              L"SetupRecovery",
> +              &gEfiSetupVariableGuid,
> +              NULL,
> +              &VariableSize,
> +              SystemConfiguration
> +              );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +  return Status;
> +}
> +
> +EFI_STATUS
> +VlvPolicyInit (
> +  IN CONST EFI_PEI_SERVICES             **PeiServices,
> +  IN SYSTEM_CONFIGURATION         *SystemConfiguration
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  EFI_PEI_PPI_DESCRIPTOR          *mVlvPolicyPpiDesc;
> +  VLV_POLICY_PPI                   *mVlvPolicyPpi;
> +
> +  Status = (*PeiServices)->AllocatePool(
> +                             PeiServices,
> +                             sizeof (EFI_PEI_PPI_DESCRIPTOR),
> +                             (void **)&mVlvPolicyPpiDesc
> +                             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = (*PeiServices)->AllocatePool(
> +                             PeiServices,
> +                             sizeof (VLV_POLICY_PPI),
> +                             (void **)&mVlvPolicyPpi
> +                             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Initialize PPI
> +  //
> +  (*PeiServices)->SetMem ((VOID *)mVlvPolicyPpi, sizeof
> (VLV_POLICY_PPI), 0);
> +  mVlvPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
> +  mVlvPolicyPpiDesc->Guid = &gVlvPolicyPpiGuid;
> +  mVlvPolicyPpiDesc->Ppi = mVlvPolicyPpi;
> +  mVlvPolicyPpi->GtConfig.PrimaryDisplay = SystemConfiguration-
> >PrimaryVideoAdaptor;
> +  mVlvPolicyPpi->GtConfig.IgdDvmt50PreAlloc = SystemConfiguration-
> >IgdDvmt50PreAlloc;
> +  mVlvPolicyPpi->GtConfig.ApertureSize = SystemConfiguration-
> >IgdApertureSize;
> +  mVlvPolicyPpi->GtConfig.GttSize = SystemConfiguration->GTTSize;
> +  if (SystemConfiguration->PrimaryVideoAdaptor != 2) {
> +    mVlvPolicyPpi->GtConfig.InternalGraphics = SystemConfiguration->Igd;
> +  } else {
> +    mVlvPolicyPpi->GtConfig.InternalGraphics = 0;
> +  }
> +
> +
> +  mVlvPolicyPpi->GtConfig.IgdTurboEn = 1;
> +
> +
> +  mVlvPolicyPpi->PlatformData.FastBoot = SystemConfiguration->FastBoot;
> +  mVlvPolicyPpi->PlatformData.DynSR = 1;
> +  DEBUG ((EFI_D_ERROR, "Setup Option ISPEn: 0x%x\n",
> SystemConfiguration->ISPEn));
> +  mVlvPolicyPpi->ISPEn                      = SystemConfiguration->ISPEn;
> +  DEBUG ((EFI_D_ERROR, "Setup Option ISPDevSel: 0x%x\n",
> SystemConfiguration->ISPDevSel));
> +  mVlvPolicyPpi->ISPPciDevConfig            = SystemConfiguration->ISPDevSel;
> +  if (SystemConfiguration->ISPEn == 0) {
> +    mVlvPolicyPpi->ISPPciDevConfig          = 0;
> +    DEBUG ((EFI_D_ERROR, "Update Setup Option ISPDevSel: 0x%x\n",
> mVlvPolicyPpi->ISPPciDevConfig));
> +  }
> +  Status = (*PeiServices)->InstallPpi(
> +                             PeiServices,
> +                             mVlvPolicyPpiDesc
> +                             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +ConfigureSoCGpio (
> +  IN SYSTEM_CONFIGURATION  *SystemConfiguration
> +  )
> +{
> +
> +    DEBUG ((EFI_D_ERROR, "ConfigureSoCGpio------------start\n"));
> +    if (SystemConfiguration->eMMCBootMode== 1) {// Auto detection mode
> +     DEBUG ((EFI_D_ERROR, "Auto detection mode------------start\n"));
> +
> +     //
> +     //Silicon Steppings
> +     //
> +     switch (PchStepping()) {
> +       case PchA0:  // SOC A0 and A1
> +       case PchA1:
> +         DEBUG ((EFI_D_ERROR, "SOC A0/A1: eMMC 4.41 GPIO
> Configuration\n"));
> +         SystemConfiguration->LpsseMMCEnabled            = 1;
> +         SystemConfiguration->LpsseMMC45Enabled          = 0;
> +         break;
> +       case PchB0:  // SOC B0 and later
> +       default:
> +         DEBUG ((EFI_D_ERROR, "SOC B0 and later: eMMC 4.5 GPIO
> Configuration\n"));
> +         SystemConfiguration->LpsseMMCEnabled            = 0;
> +         SystemConfiguration->LpsseMMC45Enabled          = 1;
> +         break;
> +     }
> +    } else if (SystemConfiguration->eMMCBootMode == 2) { // eMMC 4.41
> +        DEBUG ((EFI_D_ERROR, "Force to eMMC 4.41 GPIO Configuration\n"));
> +        SystemConfiguration->LpsseMMCEnabled            = 1;
> +        SystemConfiguration->LpsseMMC45Enabled          = 0;
> +    } else if (SystemConfiguration->eMMCBootMode == 3) { // eMMC 4.5
> +         DEBUG ((EFI_D_ERROR, "Force to eMMC 4.5 GPIO Configuration\n"));
> +         SystemConfiguration->LpsseMMCEnabled            = 0;
> +         SystemConfiguration->LpsseMMC45Enabled          = 1;
> +
> +    } else { // Disable eMMC controllers
> +         DEBUG ((EFI_D_ERROR, "Disable eMMC GPIO controllers\n"));
> +         SystemConfiguration->LpsseMMCEnabled            = 0;
> +         SystemConfiguration->LpsseMMC45Enabled          = 0;
> +    }
> +
> +  /*
> +  20.1.1  EMMC
> +  SDMMC1_CLK -         write 0x2003ED01 to IOBASE + 0x03E0
> +  SDMMC1_CMD -        write 0x2003EC81 to IOBASE + 0x0390
> +  SDMMC1_D0 -           write 0x2003EC81 to IOBASE + 0x03D0
> +  SDMMC1_D1 -           write 0x2003EC81 to IOBASE + 0x0400
> +  SDMMC1_D2 -           write 0x2003EC81 to IOBASE + 0x03B0
> +  SDMMC1_D3_CD_B - write 0x2003EC81 to IOBASE + 0x0360
> +  MMC1_D4_SD_WE -   write 0x2003EC81 to IOBASE + 0x0380
> +  MMC1_D5 -                write 0x2003EC81 to IOBASE + 0x03C0
> +  MMC1_D6 -                write 0x2003EC81 to IOBASE + 0x0370
> +  MMC1_D7 -                write 0x2003EC81 to IOBASE + 0x03F0
> +  MMC1_RESET_B -       write 0x2003ED01 to IOBASE + 0x0330
> +  */
> +  if (SystemConfiguration->LpsseMMCEnabled== 1) {
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x03E0, 0x2003ED01); //EMMC 4.41
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0390, 0x2003EC81);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x03D0, 0x2003EC81);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0400, 0x2003EC81);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x03B0, 0x2003EC81);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0360, 0x2003EC81);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0380, 0x2003EC81);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x03C0, 0x2003EC81);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0370, 0x2003EC81);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x03F0, 0x2003EC81);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0330, 0x2003ED01);
> +  }
> +
> +  /*
> +  eMMC 4.5 controller
> +  SDMMC1_CLK -         write 0x2003ED03 to IOBASE + 0x03E0
> +  SDMMC1_CMD -        write 0x2003EC83 to IOBASE + 0x0390
> +  SDMMC1_D0 -           write 0x2003EC83 to IOBASE + 0x03D0
> +  SDMMC1_D1 -           write 0x2003EC83 to IOBASE + 0x0400
> +  SDMMC1_D2 -           write 0x2003EC83 to IOBASE + 0x03B0
> +  SDMMC1_D3_CD_B -  write 0x2003EC83 to IOBASE + 0x0360
> +  MMC1_D4_SD_WE -   write 0x2003EC83 to IOBASE + 0x0380
> +  MMC1_D5 -                write 0x2003EC83 to IOBASE + 0x03C0
> +  MMC1_D6 -                write 0x2003EC83 to IOBASE + 0x0370
> +  MMC1_D7 -                write 0x2003EC83 to IOBASE + 0x03F0
> +  MMC1_RESET_B -       write 0x2003ED03 to IOBASE + 0x0330
> +  */
> +  if (SystemConfiguration->LpsseMMC45Enabled== 1) {
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x03E0, 0x2003ED03); // EMMC 4.5
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0390, 0x2003EC83);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x03D0, 0x2003EC83);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0400, 0x2003EC83);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x03B0, 0x2003EC83);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0360, 0x2003EC83);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0380, 0x2003EC83);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x03C0, 0x2003EC83);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0370, 0x2003EC83);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x03F0, 0x2003EC83);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0330, 0x2003ED03);
> +
> +  }
> +
> +//
> +// Change GPIOC_0 setting to allow MMIO access under Android.
> +//
> +  IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_USE_SEL,
> +           (IoRead32(GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_USE_SEL) &
> (UINT32)~BIT0));
> +  DEBUG ((EFI_D_ERROR, "ConfigureSoCGpio------------end\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +MeasuredBootInit (
> +  IN CONST EFI_PEI_SERVICES        **PeiServices,
> +  IN SYSTEM_CONFIGURATION           *SystemConfiguration
> +  )
> +{
> +  if (SystemConfiguration->MeasuredBootEnable) {
> +    PcdSetBool (PcdMeasuredBootEnable, TRUE);
> +  } else {
> +    PcdSetBool (PcdMeasuredBootEnable, FALSE);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +ConfigureLpssAndSccGpio (
> +  IN SYSTEM_CONFIGURATION        *SystemConfiguration,
> +  IN EFI_PLATFORM_INFO_HOB       *PlatformInfo
> +  )
> +{
> +  /*One time configuration to each GPIO controller PSB_CONF register
> should be done before starting pad configuration:
> +  GPIO SCORE -  write 0x01001002 to IOBASE + 0x0700
> +  GPIO NCORE -  write 0x01001002 to IOBASE + 0x0F00
> +  GPIO SSUS -    write 0x01001002 to IOBASE + 0x1700
> +  */
> +    DEBUG ((EFI_D_ERROR, "ConfigureLpssAndSccGpio------------start\n"));
> +
> +  /*
> +  19.1.1  PWM0
> +  PWM0 - write 0x2003CD01 to IOBASE + 0x00A0
> +  19.1.2  PWM1
> +  PWM0 - write 0x2003CD01 to IOBASE + 0x00B0
> +  */
> +  if (SystemConfiguration->LpssPwm0Enabled== 1) {
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x00A0, 0x2003CD01);
> +  } else if (SystemConfiguration->LpssPwm0Enabled== 0) {
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x00A0, 0x2003CD00);
> +  }
> +
> +  if (SystemConfiguration->LpssPwm1Enabled== 1) {
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x00B0, 0x2003CC01);
> +  } else if (SystemConfiguration->LpssPwm1Enabled== 0) {
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x00B0, 0x2003CD00);
> +  }
> +
> +  /*
> +  19.1.3  UART1
> +  UART1_RXD-L -     write 0x2003CC81 to IOBASE + 0x0020
> +  UART1_TXD-0 -     write 0x2003CC81 to IOBASE + 0x0010
> +  UART1_RTS_B-1 - write 0x2003CC81 to IOBASE + 0x0000
> +  UART1_CTS_B-H - write 0x2003CC81 to IOBASE + 0x0040
> +  */
> +  if (SystemConfiguration->LpssHsuart0Enabled== 1) {
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0020, 0x2003CC81); // uart1
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0010, 0x2003CC81);
> +  if (SystemConfiguration->LpssHsuart0FlowControlEnabled== 0) {
> +    DEBUG ((EFI_D_ERROR, "LpssHsuart0FlowControlEnabled[0]\n"));
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0000, 0x2003CC80);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0040, 0x2003CC80);
> +  } else {
> +    DEBUG ((EFI_D_ERROR, "LpssHsuart0FlowControlEnabled[1]\n"));
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0000, 0x2003CC81);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0040, 0x2003CC01);//W/A HSD
> 4752617 0x2003CC81
> +    }
> +  } else if (SystemConfiguration->LpssHsuart0Enabled== 0) {
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0020, 0x2003CC80); // uart1
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0010, 0x2003CC80);
> +  }
> +
> +
> +  /*
> +  19.1.4  UART2
> +  UART2_RTS_B-1 -  write 0x2003CC81 to IOBASE + 0x0090
> +  UART2_CTS_B-H - write 0x2003CC81 to IOBASE + 0x0080
> +  UART2_RXD-H -    write 0x2003CC81 to IOBASE + 0x0060
> +  UART2_TXD-0 -     write 0x2003CC81 to IOBASE + 0x0070
> +  */
> +  if (SystemConfiguration->LpssHsuart1Enabled== 1) {
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0060, 0x2003CC81);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0070, 0x2003CC81);
> +
> +  if (SystemConfiguration->LpssHsuart1FlowControlEnabled== 0) {
> +    DEBUG ((EFI_D_ERROR, "LpssHsuart1FlowControlEnabled[0]\n"));
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0090, 0x2003CC80); //
> UART2_RTS_B
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0080, 0x2003CC80); //
> UART2_CTS_B
> +  } else {
> +    DEBUG ((EFI_D_ERROR, "LpssHsuart1FlowControlEnabled[1]\n"));
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0090, 0x2003CC81); // uart2
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0080, 0x2003CC01); //W/A HSD
> 4752617 0x2003CC81
> +  }
> +  } else if (SystemConfiguration->LpssHsuart1Enabled== 0) {
> +  MmioWrite32 (IO_BASE_ADDRESS + 0x0060, 0x2003CC80);
> +  MmioWrite32 (IO_BASE_ADDRESS + 0x0070, 0x2003CC80);
> +  }
> +
> +  /*
> +  19.1.5  SPI
> +  SPI1_CS0_B - write 0x2003CC81 to IOBASE + 0x0110
> +  SPI1_CLK -     write 0x2003CD01 to IOBASE + 0x0100
> +  SPI1_MOSI -   write 0x2003CC81 to IOBASE + 0x0130
> +  SPI1_MISO -   write 0x2003CC81 to IOBASE + 0x0120
> +  */
> +  if (SystemConfiguration->LpssSpiEnabled== 1) {
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0110, 0x2003CC81); // SPI
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0100, 0x2003CD01);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0130, 0x2003CC81);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0120, 0x2003CC81);
> +  } else if (SystemConfiguration->LpssSpiEnabled== 0) {
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0110, 0x2003cc80);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0100, 0x2003cc80);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0130, 0x2003cc80);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0120, 0x2003cc80);
> +  }
> +
> +  /*
> +  19.1.6  I2C0
> +  I2C0_SDA-OD-O -    write 0x2003CC81 to IOBASE + 0x0210
> +  I2C0_SCL-OD-O -    write 0x2003CC81 to IOBASE + 0x0200
> +  */
> +  if (SystemConfiguration->LpssI2C0Enabled== 1) {
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0210, 0x2003C881);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0200, 0x2003C881);
> +  }
> +  /*
> +  19.1.7  I2C1
> +  I2C1_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x01F0
> +  I2C1_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x01E0
> +  */
> +
> +  if (SystemConfiguration->LpssI2C1Enabled== 1) {
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x01F0, 0x2003C881);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x01E0, 0x2003C881);
> +  }
> +  /*
> +  19.1.8  I2C2
> +  I2C2_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x01D0
> +  I2C2_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x01B0
> +  */
> +  if (SystemConfiguration->LpssI2C2Enabled== 1) {
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x01D0, 0x2003C881);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x01B0, 0x2003C881);
> +  }
> +  /*
> +  19.1.9  I2C3
> +  I2C3_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x0190
> +  I2C3_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x01C0
> +  */
> +  if (SystemConfiguration->LpssI2C3Enabled== 1) {
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0190, 0x2003C881);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x01C0, 0x2003C881);
> +  }
> +  /*
> +  19.1.10 I2C4
> +  I2C4_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x01A0
> +  I2C4_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x0170
> +  */
> +  if (SystemConfiguration->LpssI2C4Enabled== 1) {
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x01A0, 0x2003C881);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0170, 0x2003C881);
> +  }
> +  /*
> +  19.1.11 I2C5
> +  I2C5_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x0150
> +  I2C5_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x0140
> +  */
> +  //touch 1.7M support on i2c5(from 0) need 2k PULL-UP.
> +  if (SystemConfiguration->LpssI2C5Enabled== 1) {
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0150, 0x2003C881);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0140, 0x2003C881);
> +  } else if(SystemConfiguration->LpssI2C5Enabled== 0) {
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0150, 0x2003C880);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0140, 0x2003C880);
> +  }
> +  /*
> +  19.1.12 I2C6
> +  I2C6_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x0180
> +  I2C6_SCL-OD-O/I -  write 0x2003CC81 to IOBASE + 0x0160
> +  */
> +  if (SystemConfiguration->LpssI2C6Enabled== 1) {
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0180, 0x2003C881);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0160, 0x2003C881);
> +  } else if (SystemConfiguration->LpssI2C6Enabled== 0) {
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0180, 0x2003C880);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0160, 0x2003C880);
> +  }
> +
> +
> +  /*
> +  20.1.2  SDIO
> +  SDMMC2_CLK -  write 0x2003ED01 to IOBASE + 0x0320
> +  SDMMC2_CMD - write 0x2003EC81 to IOBASE + 0x0300
> +  SDMMC2_D0 -    write 0x2003EC81 to IOBASE + 0x0350
> +  SDMMC2_D1 -    write 0x2003EC81 to IOBASE + 0x02F0
> +  SDMMC2_D2 -    write 0x2003EC81 to IOBASE + 0x0340
> +  SDMMC2_D3_CD_B - write 0x2003EC81 to IOBASE + 0x0310
> +  */
> +  if (SystemConfiguration->LpssSdioEnabled== 1) {
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0320, 0x2003ED01);//SDIO
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0300, 0x2003EC81);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0350, 0x2003EC81);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x02F0, 0x2003EC81);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0340, 0x2003EC81);
> +    MmioWrite32 (IO_BASE_ADDRESS + 0x0310, 0x2003EC81);
> +  }
> +
> +  /*
> +  20.1.3  SD Card
> +  SDMMC3_1P8_EN - write 0x2003CD01 to IOBASE + 0x03F0
> +  SDMMC3_CD_B -    write 0x2003CC81 to IOBASE + 0x03A0
> +  SDMMC3_CLK -       write 0x2003CD01 to IOBASE + 0x02B0
> +  SDMMC3_CMD -      write 0x2003CC81 to IOBASE + 0x02C0
> +  SDMMC3_D0 -         write 0x2003CC81 to IOBASE + 0x02E0
> +  SDMMC3_D1 -         write 0x2003CC81 to IOBASE + 0x0290
> +  SDMMC3_D2 -         write 0x2003CC81 to IOBASE + 0x02D0
> +  SDMMC3_D3 -         write 0x2003CC81 to IOBASE + 0x02A0
> +  SDMMC3_PWR_EN_B - write 0x2003CC81 to IOBASE + 0x0690
> +  SDMMC3_WP -            write 0x2003CC82 to IOBASE + 0x0160
> +  */
> +  if (SystemConfiguration->LpssSdcardEnabled == 1) {
> +    if (!((PlatformInfo->BoardId == BOARD_ID_BL_FFRD && PlatformInfo-
> >BoardRev== PR11) && (SystemConfiguration->CfioPnpSettings == 1))) {
> +      MmioWrite32 (IO_BASE_ADDRESS + 0x05F0, 0x2003CD01);//SDCARD
> +      MmioWrite32 (IO_BASE_ADDRESS + 0x02B0, 0x2003CD01);
> +      MmioWrite32 (IO_BASE_ADDRESS + 0x02C0, 0x2003CC81);
> +      MmioWrite32 (IO_BASE_ADDRESS + 0x02E0, 0x2003CC81);
> +      MmioWrite32 (IO_BASE_ADDRESS + 0x0290, 0x2003CC81);
> +      MmioWrite32 (IO_BASE_ADDRESS + 0x02D0, 0x2003CC81);
> +      MmioWrite32 (IO_BASE_ADDRESS + 0x02A0, 0x2003CC81);
> +      MmioWrite32 (IO_BASE_ADDRESS + 0x0690, 0x2003CC81);
> +      MmioWrite32 (IO_BASE_ADDRESS + 0x0650, 0x2003CC82); //GPIOC_7
> set to WP Pin
> +     }
> +  }
> +
> +
> +     DEBUG ((EFI_D_ERROR, "ConfigureLpssAndSccGpio------------end\n"));
> +    return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +ConfigureLpeGpio (
> +  IN SYSTEM_CONFIGURATION  *SystemConfiguration
> +  )
> +{
> +  DEBUG ((EFI_D_ERROR, "ConfigureLpeGpio------------start\n"));
> +
> +  if (SystemConfiguration->PchAzalia == 0) {
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + 0x220, (UINT32)~(0x7),
> (UINT32) (0x01));
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + 0x250, (UINT32)~(0x7),
> (UINT32) (0x01));
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + 0x240, (UINT32)~(0x7),
> (UINT32) (0x01));
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + 0x260, (UINT32)~(0x7),
> (UINT32) (0x01));
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + 0x270, (UINT32)~(0x7),
> (UINT32) (0x01));
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + 0x230, (UINT32)~(0x7),
> (UINT32) (0x01));
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + 0x280, (UINT32)~(0x7),
> (UINT32) (0x01));
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + 0x540, (UINT32)~(0x7),
> (UINT32) (0x01));
> +  }
> +
> +  DEBUG ((EFI_D_ERROR, "ConfigureLpeGpio------------end\n"));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +ConfigureSciSmiGpioRout (
> +  IN EFI_PLATFORM_INFO_HOB       *PlatformInfo)
> +{
> +	UINT32 	GPI_Routing;
> +
> +	GPI_Routing = MmioRead32 (PMC_BASE_ADDRESS +
> R_PCH_PMC_GPI_ROUT);
> +
> +	//
> +	// For FAB3, Route GPIO_CORE 0 to cause Runtime SCI, GPIO_SUS 0
> to cause Wake SCI and GPIO_SUS 7 to cause EXTSMI
> +	//
> +	if(PlatformInfo->BoardRev == 3) {
> +	GPI_Routing = GPI_Routing & 0xfffc3ffc;
> +	GPI_Routing = GPI_Routing | 0x00024002;
> +	}
> +
> +	//
> +	// For FAB2/1, Route GPIO_CORE 7 to cause Runtime SCI, GPIO_SUS
> 0 to cause Wake SCI and GPIO_SUS 7 to cause EXTSMI
> +	//
> +	else {
> +	GPI_Routing = GPI_Routing & 0x3fff3ffc;
> +	GPI_Routing = GPI_Routing | 0x80004002;
> +	}
> +	MmioWrite32((PMC_BASE_ADDRESS + R_PCH_PMC_GPI_ROUT),
> GPI_Routing);
> +
> +	return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +ConfigureMipiCsi (
> +  VOID)
> +{
> +	  //
> +    //Configure the platform clock for MIPI-CSI usage
> +    //PLT_CLK0
> +    //
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + 0x6a0, (UINT32)~(0x7),
> (UINT32) (0x01));
> +
> +    //
> +    //PLT_CLK1
> +    //
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + 0x570, (UINT32)~(0x7),
> (UINT32) (0x01));
> +
> +    //
> +    //PLT_CLK2
> +    //
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + 0x5B0, (UINT32)~(0x7),
> (UINT32) (0x01));
> +
> +    return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +ConfigureUSBULPI (
> +  VOID)
> +{
> +	  //
> +    //Configure USB ULPI
> +    //USB_ULPI_0_CLK
> +    //
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x338,
> (UINT32)~(0x7), (UINT32) (GPI));
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x330,
> (UINT32)~(0x187), (UINT32) (0x101));
> +
> +    //
> +    //USB_ULPI_0_DATA0
> +    //
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x388,
> (UINT32)~(0x7), (UINT32) (GPI));
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x380,
> (UINT32)~(0x187), (UINT32) (0x101));
> +
> +    //
> +    //USB_ULPI_0_DATA1
> +    //
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x368,
> (UINT32)~(0x7), (UINT32) (GPI));
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x360,
> (UINT32)~(0x187), (UINT32) (0x101));
> +
> +    //
> +    //USB_ULPI_0_DATA2
> +    //
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x318,
> (UINT32)~(0x7), (UINT32) (GPI));
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x310,
> (UINT32)~(0x187), (UINT32) (0x101));
> +
> +    //
> +    //USB_ULPI_0_DATA3
> +    //
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x378,
> (UINT32)~(0x7), (UINT32) (GPI));
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x370,
> (UINT32)~(0x187), (UINT32) (0x101));
> +
> +    //
> +    //USB_ULPI_0_DATA4
> +    //
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x308,
> (UINT32)~(0x7), (UINT32) (GPI));
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x300,
> (UINT32)~(0x187), (UINT32) (0x101));
> +
> +    //
> +    //USB_ULPI_0_DATA5
> +    //
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x398,
> (UINT32)~(0x7), (UINT32) (GPI));
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x390,
> (UINT32)~(0x187), (UINT32) (0x101));
> +
> +    //
> +    //USB_ULPI_0_DATA6
> +    //
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x328,
> (UINT32)~(0x7), (UINT32) (GPI));
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x320,
> (UINT32)~(0x187), (UINT32) (0x101));
> +
> +    //
> +    //USB_ULPI_0_DATA7
> +    //
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x3a8,
> (UINT32)~(0x7), (UINT32) (GPI));
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x3a0,
> (UINT32)~(0x187), (UINT32) (0x101));
> +
> +    //
> +    //USB_ULPI_0_DIR
> +    //
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x348,
> (UINT32)~(0x7), (UINT32) (GPI));
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x340,
> (UINT32)~(0x187), (UINT32) (0x81));
> +
> +    //
> +    //USB_ULPI_0_NXT
> +    //
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x358,
> (UINT32)~(0x7), (UINT32) (GPI));
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x350,
> (UINT32)~(0x187), (UINT32) (0x101));
> +
> +    //
> +    //USB_ULPI_0_STP
> +    //
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x3b8,
> (UINT32)~(0x7), (UINT32) (GPI));
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x3b0,
> (UINT32)~(0x187), (UINT32) (0x81));
> +
> +    //
> +    //USB_ULPI_0_REFCLK
> +    //
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x288,
> (UINT32)~(0x7), (UINT32) (GPI));
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x280,
> (UINT32)~(0x187), (UINT32) (0x101));
> +
> +    return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +DisableRTD3 (
> +  VOID)
> +{
> +	  //
> +    //Disable RTD3
> +    //
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x210,
> (UINT32)~(0x0f000007), (UINT32) (0x00));
> +    MmioAndThenOr32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + 0x1e0,
> (UINT32)~(0x0f000007), (UINT32) (0x00));
> +
> +    return EFI_SUCCESS;
> +}
> +
> +/**
> +  Platform specific initializations in stage1.
> +
> +  @param FfsHeader         Pointer to the PEIM FFS file header.
> +  @param PeiServices       General purpose services available to every PEIM.
> +
> +  @retval EFI_SUCCESS       Operation completed successfully.
> +  @retval Otherwise         Platform initialization failed.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PlatformEarlyInitEntry (
> +
> +  IN       EFI_PEI_FILE_HANDLE  FileHandle,
> +  IN CONST EFI_PEI_SERVICES    **PeiServices
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  SYSTEM_CONFIGURATION        SystemConfiguration;
> +  EFI_PLATFORM_INFO_HOB       *PlatformInfo;
> +  EFI_PEI_HOB_POINTERS        Hob;
> +  EFI_PLATFORM_CPU_INFO       PlatformCpuInfo;
> +  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *DescriptorBlock;
> +  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *NewDescriptorBlock;
> +  UINTN                           Index;
> +  UINTN                           MaxIndex;
> +  UINT64                          Base;
> +  UINT64                          Size;
> +  UINT64                          NewSize;
> +
> +  //
> +  // Make sure base and size of the SMRAM region is aligned
> +  //
> +  Hob.Raw = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid);
> +  if (Hob.Raw != NULL) {
> +    DescriptorBlock = GET_GUID_HOB_DATA (Hob.Raw);
> +    DEBUG ((DEBUG_INFO, "SMM PEI SMRAM Memory Reserved HOB\n"));
> +    for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions;
> Index++) {
> +      DEBUG((DEBUG_INFO, "  SMRAM Descriptor[%02x]: Start=%016lx
> Size=%016lx  State=%02x\n",
> +        Index,
> +        DescriptorBlock->Descriptor[Index].PhysicalStart,
> +        DescriptorBlock->Descriptor[Index].PhysicalSize,
> +        DescriptorBlock->Descriptor[Index].RegionState
> +        ));
> +    }
> +
> +    //
> +    // Find the largest usable range of SMRAM between 1MB and 4GB
> +    //
> +    for (Index = 0, MaxIndex = 0, Size = 0; Index < DescriptorBlock-
> >NumberOfSmmReservedRegions; Index++) {
> +      //
> +      // Skip any SMRAM region that is already allocated, needs testing, or
> needs ECC initialization
> +      //
> +      if ((DescriptorBlock->Descriptor[Index].RegionState & (EFI_ALLOCATED |
> EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) {
> +        continue;
> +      }
> +      //
> +      // Skip any SMRAM region below 1MB
> +      //
> +      if (DescriptorBlock->Descriptor[Index].CpuStart < BASE_1MB) {
> +        continue;
> +      }
> +      //
> +      // Skip any SMRAM region that is above 4GB or crosses the 4GB
> boundary
> +      //
> +      if ((DescriptorBlock->Descriptor[Index].CpuStart + DescriptorBlock-
> >Descriptor[Index].PhysicalSize) >= BASE_4GB) {
> +        continue;
> +      }
> +      //
> +      // Cache the largest SMRAM region index
> +      //
> +      if (DescriptorBlock->Descriptor[Index].PhysicalSize >= DescriptorBlock-
> >Descriptor[MaxIndex].PhysicalSize) {
> +        MaxIndex = Index;
> +      }
> +    }
> +
> +    //
> +    // Find the extent of the contiguous SMRAM region that surrounds the
> largest usable SMRAM range
> +    //
> +    Base = DescriptorBlock->Descriptor[MaxIndex].CpuStart;
> +    Size = DescriptorBlock->Descriptor[MaxIndex].PhysicalSize;
> +    for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions;
> Index++) {
> +      if (DescriptorBlock->Descriptor[Index].CpuStart < Base &&
> +          Base == (DescriptorBlock->Descriptor[Index].CpuStart +
> DescriptorBlock->Descriptor[Index].PhysicalSize)) {
> +        Base  = DescriptorBlock->Descriptor[Index].CpuStart;
> +        Size += DescriptorBlock->Descriptor[Index].PhysicalSize;
> +      } else if ((Base + Size) == DescriptorBlock->Descriptor[Index].CpuStart) {
> +        Size += DescriptorBlock->Descriptor[Index].PhysicalSize;
> +      }
> +    }
> +
> +    //
> +    // Round SMRAM region up to nearest power of 2 that is at least 4KB
> +    //
> +    NewSize = MAX (LShiftU64 (1, HighBitSet64 (Size - 1) + 1), SIZE_4KB);
> +    if ((Base & ~(NewSize - 1)) != Base) {
> +      //
> +      // SMRAM region Base Address has smaller alignment than SMRAM
> region Size
> +      // This is not compatible with SMRR settings
> +      //
> +      DEBUG((DEBUG_ERROR, "ERROR: SMRAM Region Size has larger
> alignment than SMRAM Region Base\n"));
> +      DEBUG((DEBUG_ERROR, "  SMRAM Region Base=%016lx  Size=%016lx\n",
> Base, NewSize));
> +      ASSERT (FALSE);
> +    } else if (Size != NewSize) {
> +      //
> +      // See if the size difference can be added to an adjacent descriptor that
> is already allocated
> +      //
> +      for (Index = 0; Index < DescriptorBlock-
> >NumberOfSmmReservedRegions; Index++) {
> +        if ((DescriptorBlock->Descriptor[Index].CpuStart + DescriptorBlock-
> >Descriptor[Index].PhysicalSize) == (Base + Size)) {
> +          if (((DescriptorBlock->Descriptor[Index].RegionState) &
> EFI_ALLOCATED) != 0) {
> +            DescriptorBlock->Descriptor[Index].PhysicalSize += (NewSize - Size);
> +            Size = NewSize;
> +            break;
> +          }
> +        }
> +      }
> +
> +      if (Size != NewSize) {
> +        //
> +        // Add an allocated descriptor to the SMM PEI SMRAM Memory
> Reserved HOB to accomodate the larger size.
> +        //
> +        Index = DescriptorBlock->NumberOfSmmReservedRegions;
> +        NewDescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK
> *)BuildGuidHob (
> +          &gEfiSmmPeiSmramMemoryReserveGuid,
> +          sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK) + ((Index + 1) * sizeof
> (EFI_SMRAM_DESCRIPTOR))
> +          );
> +        ASSERT (NewDescriptorBlock != NULL);
> +
> +        //
> +        // Copy old EFI_SMRAM_HOB_DESCRIPTOR_BLOCK to new allocated
> region
> +        //
> +        CopyMem (
> +          NewDescriptorBlock,
> +          DescriptorBlock,
> +          sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK) + (Index * sizeof
> (EFI_SMRAM_DESCRIPTOR))
> +          );
> +
> +        //
> +        // Make sure last descriptor in NewDescriptorBlock contains last
> descriptor from DescriptorBlock
> +        //
> +        CopyMem (
> +          &NewDescriptorBlock->Descriptor[Index],
> +          &NewDescriptorBlock->Descriptor[Index - 1],
> +          sizeof (EFI_SMRAM_DESCRIPTOR)
> +          );
> +
> +        //
> +        // Fill next to last descriptor with an allocated descriptor that aligns the
> total size of SMRAM
> +        //
> +        NewDescriptorBlock->Descriptor[Index - 1].CpuStart      = Base + Size;
> +        NewDescriptorBlock->Descriptor[Index - 1].PhysicalStart = Base + Size;
> +        NewDescriptorBlock->Descriptor[Index - 1].PhysicalSize  = NewSize -
> Size;
> +        NewDescriptorBlock->Descriptor[Index - 1].RegionState   =
> DescriptorBlock->Descriptor[MaxIndex].RegionState | EFI_ALLOCATED;
> +        NewDescriptorBlock->NumberOfSmmReservedRegions++;
> +
> +        //
> +        // Invalidate the original gEfiSmmPeiSmramMemoryReserveGuid HOB
> +        //
> +        ZeroMem (&Hob.Guid->Name, sizeof (&Hob.Guid->Name));
> +      }
> +
> +      Hob.Raw = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid);
> +      DescriptorBlock = GET_GUID_HOB_DATA (Hob.Raw);
> +      DEBUG ((DEBUG_INFO, "SMM PEI SMRAM Memory Reserved HOB -
> Updated\n"));
> +      for (Index = 0; Index < DescriptorBlock-
> >NumberOfSmmReservedRegions; Index++) {
> +        DEBUG((DEBUG_INFO, "  SMRAM Descriptor[%02x]: Start=%016lx
> Size=%016lx  State=%02x\n",
> +          Index,
> +          DescriptorBlock->Descriptor[Index].PhysicalStart,
> +          DescriptorBlock->Descriptor[Index].PhysicalSize,
> +          DescriptorBlock->Descriptor[Index].RegionState
> +          ));
> +      }
> +    }
> +  }
> +
> +  //
> +  // Initialize SmbusPolicy PPI
> +  //
> +  Status = (*PeiServices)->InstallPpi(PeiServices, &mInstallSmbusPolicyPpi);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Initialize Stall PPIs
> +  //
> +  Status = (*PeiServices)->InstallPpi (PeiServices, &mInstallStallPpi);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Initialize platform PPIs
> +  //
> +  Status = (*PeiServices)->InstallPpi (PeiServices,
> &mInstallSpeakerInterfacePpi);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Variable initialization
> +  //
> +  ZeroMem(&PlatformCpuInfo, sizeof(EFI_PLATFORM_CPU_INFO));
> +
> +  //
> +  // Set the some PCI and chipset range as UC
> +  // And align to 1M at leaset
> +  //
> +  Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid);
> +  ASSERT (Hob.Raw != NULL);
> +  PlatformInfo = GET_GUID_HOB_DATA(Hob.Raw);
> +
> +  //
> +  // Initialize PlatformInfo HOB
> +  //
> +  MultiPlatformInfoInit(PeiServices, PlatformInfo);
> +
> +  //
> +  // Do basic MCH init
> +  //
> +  MchInit (PeiServices);
> +
> +  //
> +  // Set the new boot mode
> +  //
> +  Status = UpdateBootMode (PeiServices, PlatformInfo);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  SetPlatformBootMode (PeiServices, PlatformInfo);
> +
> +  //
> +  // Get setup variable. This can only be done after BootMode is updated
> +  //
> +  GetSetupVariable (PeiServices, &SystemConfiguration);
> +
> +  CheckOsSelection(PeiServices, &SystemConfiguration);
> +
> +  //
> +  // Update PlatformInfo HOB according to setup variable
> +  //
> +  PlatformInfoUpdate(PeiServices, PlatformInfo, &SystemConfiguration);
> +
> +  InitializePlatform (PeiServices, PlatformInfo, &SystemConfiguration);
> +
> +  //
> +  // Initialize VlvPolicy PPI
> +  //
> +  Status = VlvPolicyInit (PeiServices, &SystemConfiguration);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Soc specific GPIO setting
> +  //
> +  ConfigureSoCGpio(&SystemConfiguration);
> +
> +  //
> +  //  Baylake Board specific.
> +  //
> +  if (PlatformInfo->BoardId == BOARD_ID_BL_RVP  ||
> +      PlatformInfo->BoardId == BOARD_ID_BL_FFRD ||
> +	    PlatformInfo->BoardId == BOARD_ID_BL_FFRD8 ||
> +      PlatformInfo->BoardId == BOARD_ID_BL_RVP_DDR3L ||
> +      PlatformInfo->BoardId == BOARD_ID_BL_STHI ||
> +      PlatformInfo->BoardId == BOARD_ID_BB_RVP ||
> +      PlatformInfo->BoardId == BOARD_ID_BS_RVP ||
> +      PlatformInfo->BoardId == BOARD_ID_MINNOW2 ||
> +      PlatformInfo->BoardId == BOARD_ID_MINNOW2_TURBOT||
> +      PlatformInfo->BoardId == BOARD_ID_CVH) {
> +    ConfigureLpssAndSccGpio(&SystemConfiguration, PlatformInfo);
> +
> +  }
> +
> +
> +  //
> +  //  Configure LPE
> +  //  Alpine Valley and Bayley Bay board specific
> +  //
> +  ConfigureLpeGpio(&SystemConfiguration);
> +
> +  //
> +  //  Bayley Bay Board specific.
> +  //
> +  ConfigureSciSmiGpioRout(PlatformInfo);
> +  if (SystemConfiguration.LpssI2C3Enabled == 1) {
> +    ConfigureMipiCsi();
> +  }
> +
> +
> +  //
> +  // Do basic CPU init
> +  //
> +  Status = PlatformCpuInit (PeiServices, &SystemConfiguration,
> &PlatformCpuInfo);
> +
> +  //
> +  // Perform basic SSA related platform initialization
> +  //
> +  PlatformSsaInit (&SystemConfiguration,PeiServices);
> +
> +
> +  //
> +  // Do basic PCH init
> +  //
> +  Status = PlatformPchInit (&SystemConfiguration, PeiServices,
> PlatformInfo->PlatformType);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Initialize platform PPIs
> +  //
> +  Status = (*PeiServices)->InstallPpi (PeiServices, &mPpiList[0]);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  if (PlatformInfo->BoardId != BOARD_ID_CVH) {
> +    InstallPlatformClocksNotify (PeiServices);
> +    InstallPlatformSysCtrlGPIONotify(PeiServices);
> +  }
> +
> +  //
> +  // Initialize platform PPIs
> +  //
> +  Status = (*PeiServices)->NotifyPpi(PeiServices, &mNotifyList[0]);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Initialize Measured Boot
> +  //
> +  Status = MeasuredBootInit (PeiServices, &SystemConfiguration);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> +/**
> +
> +  Return the mainblockcompact Fv.
> +
> +  @param FvNumber    Our enumeration of the firmware volumes we care
> about.
> +
> +  @param FvAddress  Base Address of the memory containing the firmware
> volume
> +
> +  @retval EFI_SUCCESS
> +  @retval EFI_NOT_FOUND
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +FindFv (
> +  IN EFI_PEI_FIND_FV_PPI          *This,
> +  IN CONST EFI_PEI_SERVICES             **PeiServices,
> +  IN OUT UINT8                    *FvNumber,
> +  OUT EFI_FIRMWARE_VOLUME_HEADER  **FVAddress
> +  )
> +{
> +	//
> +  // At present, we only have one Fv to search
> +  //
> +  if (*FvNumber == 0) {
> +    *FvNumber = 1;
> +    *FVAddress = (EFI_FIRMWARE_VOLUME_HEADER
> *)(UINTN)FixedPcdGet32 (PcdFlashFvMainBase);
> +    return EFI_SUCCESS;
> +  }
> +  else if (*FvNumber == 1) {
> +    *FvNumber = 2;
> +    *FVAddress = (EFI_FIRMWARE_VOLUME_HEADER
> *)(UINTN)FixedPcdGet32 (PcdFlashFvRecovery2Base);
> +    return EFI_SUCCESS;
> +  }
> +  else { // Not the one Fv we care about
> +    return EFI_NOT_FOUND;
> +  }
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +CpuOnlyReset (
> +  IN CONST EFI_PEI_SERVICES   **PeiServices
> +  )
> +{
> +//  MsgBus32Write(CDV_UNIT_PUNIT, PUNIT_CPU_RST, 0x01)
> +#ifdef __GNUC__
> +  __asm__
> +  (
> +   "xorl %ecx, %ecx\n"
> +   "1:hlt; hlt; hlt\n"
> +   "jmp 1b\n"
> +  );
> +#else
> +  _asm {
> +    xor   ecx, ecx
> +  HltLoop:
> +    hlt
> +    hlt
> +    hlt
> +    loop  HltLoop
> +  }
> +#endif
> +  //
> +  // If we get here we need to mark it as a failure.
> +  //
> +  return EFI_UNSUPPORTED;
> +}
> +
> +
> +#ifdef __GNUC__
> +#pragma GCC pop_options
> +#else
> +#pragma optimize ("", on)
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.h
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.h
> new file mode 100644
> index 0000000000..29749277d7
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.h
> @@ -0,0 +1,1499 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  PlatformEarlyInit.h
> +
> +Abstract:
> +
> +  Platform Early Stage header file
> +
> +
> +
> +--*/
> +
> +/*++
> + This file contains an 'Intel Peripheral Driver' and is
> + licensed for Intel CPUs and chipsets under the terms of your
> + license agreement with Intel or your vendor.  This file may
> + be modified by the user, subject to additional terms of the
> + license agreement
> +--*/
> +
> +#ifndef _EFI_PLATFORM_EARLY_INIT_H_
> +#define _EFI_PLATFORM_EARLY_INIT_H_
> +
> +#define EFI_FORWARD_DECLARATION(x) typedef struct _##x x
> +#include <FrameworkPei.h>
> +#include "PlatformBaseAddresses.h"
> +#include "PchAccess.h"
> +#include "VlvAccess.h"
> +#include "SetupMode.h"
> +#include "PlatformBootMode.h"
> +#include "Platform.h"
> +#include "LegacySpeaker.h"
> +
> +#include <Ppi/Stall.h>
> +#include <Guid/PlatformInfo.h>
> +#include <Guid/SetupVariable.h>
> +#include <Ppi/AtaController.h>
> +#include <Ppi/FindFv.h>
> +#include <Ppi/BootInRecoveryMode.h>
> +#include <Ppi/ReadOnlyVariable2.h>
> +#include <Ppi/Capsule.h>
> +#include <Guid/EfiVpdData.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/MtrrLib.h>
> +#include <Library/CpuIA32.h>
> +
> +#include <IndustryStandard/Pci22.h>
> +#include <Ppi/Speaker.h>
> +#include <Guid/FirmwareFileSystem.h>
> +#include <Guid/MemoryTypeInformation.h>
> +#include <Ppi/Cache.h>
> +#include <Ppi/Smbus.h>
> +#include <Library/PchPlatformLib.h>
> +#include <Ppi/SmbusPolicy.h>
> +#include <Ppi/Reset.h>
> +#include <Ppi/EndOfPeiPhase.h>
> +#include <Ppi/MemoryDiscovered.h>
> +#include <Ppi/VlvPolicy.h>
> +#include <Guid/GlobalVariable.h>
> +#include <Ppi/RecoveryModule.h>
> +#include <Ppi/DeviceRecoveryModule.h>
> +#include <Guid/Capsule.h>
> +#include <Guid/RecoveryDevice.h>
> +#include <Ppi/MasterBootMode.h>
> +#include <Guid/PlatformCpuInfo.h>
> +#include <Guid/OsSelection.h>
> +#include <Guid/SmramMemoryReserve.h>
> +#include <Register/Msr.h>
> +
> +#define SMC_LAN_ON       0x46
> +#define SMC_LAN_OFF    0x47
> +#define SMC_DEEP_S3_STS    0xB2
> +
> +
> +
> +
> +//
> +// Wake Event Types
> +//
> +#define SMBIOS_WAKEUP_TYPE_RESERVED           0x00
> +#define SMBIOS_WAKEUP_TYPE_OTHERS             0x01
> +#define SMBIOS_WAKEUP_TYPE_UNKNOWN            0x02
> +#define SMBIOS_WAKEUP_TYPE_APM_TIMER          0x03
> +#define SMBIOS_WAKEUP_TYPE_MODEM_RING         0x04
> +#define SMBIOS_WAKEUP_TYPE_LAN_REMOTE         0x05
> +#define SMBIOS_WAKEUP_TYPE_POWER_SWITCH       0x06
> +#define SMBIOS_WAKEUP_TYPE_PCI_PME            0x07
> +#define SMBIOS_WAKEUP_TYPE_AC_POWER_RESTORED  0x08
> +
> +#define EFI_CPUID_VIRT_PHYS_ADDRESS_SIZE       0x80000008
> +
> +//
> +// Defines for stall ppi
> +//
> +#define PEI_STALL_RESOLUTION  1
> +
> +//
> +// Used in PEI memory test routines
> +//
> +#define MEMORY_TEST_COVER_SPAN  0x40000
> +#define MEMORY_TEST_PATTERN     0x5A5A5A5A
> +
> +#define EFI_LOW_BEEP_FREQUENCY            0x31B
> +#define EFI_HIGH_BEEP_FREQUENCY           0x254
> +
> +//
> +// General Purpose Constants
> +//
> +#define ICH_ACPI_TIMER_MAX_VALUE  0x1000000 //The timer is 24 bit
> overflow
> +
> +
> +
> +//
> +//
> +//              GPIO Register Settings for ValleyFalls (Tablet)
> +//
> +//
> +//                   IO Space configyuration registers
> +// Field Descriptions:
> +//    USE: Defines the pin's usage model:  GPIO (G) or Native (N) mode.
> +//    I/O: Defines whether GPIOs are inputs (I) or outputs (O).
> +//         (Note:  Only meaningful for pins used as GPIOs.)
> +//    LVL: This field gives you the initial value for "output" GPIO's.
> +//         (Note: The output level is dependent upon whether the pin is
> inverted.)
> +//    TPE: Defines whether Trigger Positive Edge Enable.
> +//    TNE: Defines whether Trigger Negative Edge Enable.
> +//    WAKE_EN: only support in SUS community
> +//         (Note:  Only affects the level sent to the GPE logic and does not
> +//         affect the level read through the GPIO registers.)
> +//
> +//
> +//                    Memory spcae configuration registers
> +//
> +// Field Descriptions:
> +//   PAD releated:
> +//    PAD_CONF0
> +//      PAD_CONF1
> +//      PAD_VAL
> +//      PAD_DFT
> +//
> +// Notes:
> +//    1. N = Native , G = GPIO , I = Input, O = Output, - = BOTH/NOT SURE
> +//
> +// Signal          UsedAs                       USE     I/O      LVL     TPE     TNE   PCONF0
> PCONF1   PVAL  PDFT
> +// -----------------------------------------------------------------------------------------
> --------------------------------
> +// GPIO0           UART1_RXD-L                   N       I        -       -       -     cd29h    -         -
> -
> +// GPIO1           UART1_TXD-0                   N       O        -       -       -     cd29h    -         -
> -
> +// *GPIO2           UART1_RTS_B-1                N       I        -       -       -     cca9h    -         -
> -
> +// *GPIO3           UART1_CTS_B-H                N       O        -       -       -     cca9h    -
> -     -
> +
> +// GPIO4           I2C1_SDA-OD-O                 N       -        -       -       -     cca9h    -         -
> -
> +// GPIO5           I2C1_SCL-OD-O                 N       -        -       -       -     cca9h    -         -
> -
> +// GPIO6           I2S_SYSCLK-0                  N       O        -       -       -     8d51h    -         -
> -
> +// GPIO7           I2S_L_R-0 (SP)                N       O        -       -       -     8cd1h    -         -
> -
> +// GPIO8           I2S_DATA_OUT-0                N       O        -       -       -     8cd1h    -
> -     -
> +// GPIO9           I2S_SDATA_IN-L                N       I        -       -       -     8cd1h    -         -
> -
> +
> +// GPIO10          PCM_CLK-0                     N       O        -       -       -     8d51h    -         -
> -
> +// GPIO11          PCM_FSYNC-0 (SP)              N       O        -       -       -     8cd1h    -
> -     -
> +// GPIO12          PCM_DATA_OUT-0 (SP)           N       O        -       -       -     8cd1h    -
> -     -
> +// GPIO13          PCM_DATA_IN-L                 N       I        -       -       -     8d51h    -
> -     -
> +
> +// GPIO14          SATA_GP0                      N       -        -       -       -      -       -         -     -
> +// GPIO15          I2C2_SDA-OD-O/I               N       -        -       -       -     ccaah    -         -
> -
> +
> +// GPIO16          SATA_LEDN                     N       O        -       -       -      -       -         -     -
> +// GPIO17          UART2_RTS_B-1                 N       I        -       -       -     cd2ah    -         -
> -
> +// GPIO18          UART2_CTS_B-H                 N       O        -       -       -     ccaah    -
> -     -
> +// GPIO19          UART2_RXD-H                   N       I        -       -       -     ccaah    -         -
> -
> +
> +// GPIO20          I2C2_SCL-OD-O/I               N       -        -       -       -     ccaah    -         -
> -
> +// GPIO21          **PCIE_CLKREQ4B               N       -        -       -       -      -       -         -
> -
> +// GPIO22          UART2_TXD-0                   N       O        -       -       -     ccaah    -         -
> -
> +// GPIO23          FLEX_CLK_SE1                  N       -        -       -       -      -       -         -     -
> +
> +// GPIO24          SPI0_SCK-0                    N       O        -       -       -     8d02h    -         -
> -
> +// GPIO25          SPI0_CS-1                     N       O        -       -       -     8d02h    -         -     -
> +// GPIO26          SPI0_MOSI-0                   N       O        -       -       -     8d02h    -         -
> -
> +// GPIO27          SPI0_MISO-L                   N       I        -       -       -     8d02h    -         -
> -
> +
> +// GPIO28          UART3_RXD-L                   N       I        -       -       -      -       -         -     -
> +// GPIO29          UART3_TXD-0                   N       O        -       -       -      -       -         -     -
> +// GPIO30          UART4_RXD-L                   N       I        -       -       -      -       -         -     -
> +// GPIO31          UART4_TXD-0                   N       O        -       -       -      -       -         -     -
> +
> +// GPIO32          SDMMC1_CLK                    N       -        -       -       -     208d51h   -
> -     -
> +// GPIO33          SDMMC1_D0                     N       -        -       -       -     8cd1h     -         -
> -
> +// GPIO34          SDMMC1_D1                     N       -        -       -       -     8cd1h     -         -
> -
> +// GPIO35          SDMMC1_D2                     N       -        -       -       -     8cd1h     -         -
> -
> +// GPIO36          SDMMC1_D3_CD_B                N       -        -       -       -     8cd1h     -
> -     -
> +// GPIO37          MMC1_D4_SD_WE                 N       -        -       -       -     8cd1h     -
> -     -
> +// GPIO38          MMC1_D5                       N       -        -       -       -     8cd1h     -         -
> -
> +// GPIO39          MMC1_D6                       N       -        -       -       -     8cd1h     -         -
> -
> +// GPIO40          MMC1_D7                       N       -        -       -       -     8cd1h     -         -
> -
> +// GPIO41          SDMMC1_CMD                    N       -        -       -       -     8cd1h     -
> -     -
> +// GPIO42          MMC1_RESET_B                  N       -        -       -       -     208d51h   -
> -     -
> +
> +// GPIO43          SDMMC2_CLK                    N       -        -       -       -     208d51h   -
> -     -
> +// GPIO44          SDMMC2_D0                     N       -        -       -       -     8cd1h     -         -
> -
> +// GPIO45          SDMMC2_D1                     N       -        -       -       -     8cd1h     -         -
> -
> +// GPIO46          SDMMC2_D2                     N       -        -       -       -     8cd1h     -         -
> -
> +// GPIO47          SDMMC2_D3_CD_B                N       -        -       -       -     8cd1h     -
> -     -
> +// GPIO48          SDMMC2_CMD                    N       -        -       -       -     8cd1h     -
> -     -
> +
> +// GPIO49          SDMMC3_CLK                    N       -        -       -       -     8d51h      -         -
> -
> +// GPIO50          SDMMC3_D0                     N       -        -       -       -     8cd1h      -         -
> -
> +// GPIO51          SDMMC3_D1                     N       -        -       -       -      8cd1h      -         -
> -
> +// GPIO52          SDMMC3_D2                     N       -        -       -       -      8cd1h      -         -
> -
> +// GPIO53          SDMMC3_D3                     N       -        -       -       -      8cd1h      -         -
> -
> +// GPIO54          SDMMC3_CD_B                   N       -        -       -       -      cca9h      -
> -     -
> +// GPIO55          SDMMC3_CMD                    N       -        -       -       -      8cd1h      -
> -     -
> +// GPIO56          SDMMC3_1P8_EN                 N       -        -       -       -      cd29h   -
> -     -
> +
> +// GPIO57            LPC_AD0                     N       -        -       -       -      -       -         -     -
> +// GPIO58            LPC_AD1                     N       -        -       -       -      -       -         -     -
> +// GPIO59            LPC_AD2                     N       -        -       -       -      -       -         -     -
> +// GPIO60            LPC_AD3                     N       -        -       -       -      -       -         -     -
> +// GPIO61            LPC_FRAMEB                  N       O        -       -       -      -       -         -     -
> +// GPIO62            LPC_CLKOUT0                 N       O        -       -       -      -       -         -     -
> +// GPIO63            LPC_CLKOUT1                 N       O        -       -       -      -       -         -     -
> +// GPIO64            LPC_CLKRUNB                 N       -        -       -       -      -       -         -     -
> +
> +// GPIO65            SMB_DATA                    N       -        -       -       -      -       -         -     -
> +// GPIO66            SMB_CLK                     N       -        -       -       -      -       -         -     -
> +// GPIO67            SMB_ALERTB                  N       -        -       -       -      -       -         -     -
> +
> +// GPIO68            ILB_SEIRQ                   N       -       -        -       -      -       -         -     -
> +// GPIO69            SPKR                        N       O       -        -       -      -       -         -     -
> +
> +//SUS WELL
> +
> +//GPIO_SUS0             BT_WAKEUP_VLV               N       O       -        -       -    CCA8h
> -         -     -
> +//GPIO_SUS1             BT_CLOCK_REQ                N       O       -        -       -    CCA8h
> -         -     -
> +//GPIO_SUS2             WIFI_PWR_EN                 N       O       -        -       -    CCA8h
> -         -     -
> +//GPIO_SUS3             SD_CARD_PWR_EN              N       O       -        -       -    CD28h
> -         -     -
> +//GPIO_SUS4             GPIO_SUS4                   N       O       -        -       -    CD28h       -
> -     -
> +//GPIO_SUS5             GPIO_SUS5                   N       O       -        -       -    CD28h       -
> -     -
> +//GPIO_SUS6             SUSPWRDNACK                 N       O       -        -       -    8850h
> -         -     -
> +//GPIO_SUS7             PMU_SLP_DDRVTT_B            N       O       -        -       -    8850h
> -         -     -
> +//GPIO_SUS8             PMU_WAKE_B                  N       O       -        -       -    CCA8h
> -         -     -
> +//GPIO_SUS9             PMU_PWRBTN_B                N       O       -        -       -    CCA8h
> -         -     -
> +//GPIO_SUS10            PMU_WAKE_LAN_B              N       O       -        -       -
> CCA8h       -         -     -
> +//GPIO_SUS11            SUS_STAT_B                  N       O       -        -       -    C828h       -
> -     -
> +//GPIO_SUS12            GPIO_SUS12                  N       O       -        -       -    C828h      -
> -     -
> +//GPIO_SUS13            USB_OC0_B-20K,H             N       O       -        -       -    CCA8h
> -         -     -
> +//GPIO_SUS14            GPIO_SUS14                  N       O       -        -       -    CCA8h       -
> -     -
> +//GPIO_SUS15            SPI_CS1_B-20K,H             N       O       -        -       -    8C80h
> -         -     -
> +//GPIO_SUS16            PMU_SUSCLK                  N       O       -        -       -    C828h       -
> -     -
> +//
> +
> +
> +#define VF_TAB_GPIO_USE_SEL_VAL_0_31        0x00000000
> +#define VF_TAB_GPIO_USE_SEL_VAL_32_63       0x00000000
> +#define VF_TAB_GPIO_USE_SEL_VAL_64_70       0x00000000
> +#define VF_TAB_GPIO_USE_SEL_VAL_SUS         0x00000000
> +
> +//
> +//1010 --00 0100 01-- 0101 --0- 0001 1010
> +//
> +#define VF_TAB_GPIO_IO_SEL_VAL_0_31         0x00000000 // BIT30 | BIT28 |
> BIT27 | BIT19 | BIT17 | BIT13 | BIT9 | BIT2 | BIT0
> +#define VF_TAB_GPIO_IO_SEL_VAL_32_63        0x00000000
> +#define VF_TAB_GPIO_IO_SEL_VAL_64_70        0x00000000
> +#define VF_TAB_GPIO_IO_SEL_VAL_SUS          0x00000000
> +
> +
> +#define VF_TAB_GPIO_LVL_VAL_0_31            0x00000000
> +#define VF_TAB_GPIO_LVL_VAL_32_63           0x00000000
> +#define VF_TAB_GPIO_LVL_VAL_64_70           0x00000000
> +#define VF_TAB_GPIO_LVL_VAL_SUS             0x00000000
> +
> +#define VF_TAB_GPIO_TPE_VAL_0_31            0x00000000
> +#define VF_TAB_GPIO_TPE_VAL_SUS             0x00000000
> +
> +#define VF_TAB_GPIO_TNE_VAL_0_31            0x00000000
> +#define VF_TAB_GPIO_TNE_VAL_SUS             0x00000000
> +
> +#define VF_TAB_GPIO_TS_VAL_0_31             0x00000000
> +#define VF_TAB_GPIO_TS_VAL_SUS              0x00000000
> +
> +
> +//
> +// Memory space registers
> +//
> +
> +//
> +// CONF0
> +//
> +#define  VF_TAB_PAD_CONF0_GPIO0  0xcd29
> +#define  VF_TAB_PAD_CONF0_GPIO1  0xcd29
> +#define  VF_TAB_PAD_CONF0_GPIO2  0xcca9
> +#define  VF_TAB_PAD_CONF0_GPIO3  0xcca9
> +#define  VF_TAB_PAD_CONF0_GPIO4  0xcca9
> +#define  VF_TAB_PAD_CONF0_GPIO5  0xcca9
> +#define  VF_TAB_PAD_CONF0_GPIO6  0x8d51
> +#define  VF_TAB_PAD_CONF0_GPIO7  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO8  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO9  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO10  0x8d51
> +#define  VF_TAB_PAD_CONF0_GPIO11  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO12  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO13  0x8d51
> +#define  VF_TAB_PAD_CONF0_GPIO14  0xCCA8
> +#define  VF_TAB_PAD_CONF0_GPIO15  0xccaa
> +#define  VF_TAB_PAD_CONF0_GPIO16  0xC828
> +#define  VF_TAB_PAD_CONF0_GPIO17  0xcd2a
> +#define  VF_TAB_PAD_CONF0_GPIO18  0xccaa
> +#define  VF_TAB_PAD_CONF0_GPIO19  0xccaa
> +#define  VF_TAB_PAD_CONF0_GPIO20  0xccaa
> +#define  VF_TAB_PAD_CONF0_GPIO21  0xCCA9
> +#define  VF_TAB_PAD_CONF0_GPIO22  0xccaa
> +#define  VF_TAB_PAD_CONF0_GPIO23  0xCD2A
> +#define  VF_TAB_PAD_CONF0_GPIO24  0x8d02
> +#define  VF_TAB_PAD_CONF0_GPIO25  0x8d02
> +#define  VF_TAB_PAD_CONF0_GPIO26  0x8d02
> +#define  VF_TAB_PAD_CONF0_GPIO27  0x8d02
> +#define  VF_TAB_PAD_CONF0_GPIO28  0x8D02
> +#define  VF_TAB_PAD_CONF0_GPIO29  0x8D02
> +#define  VF_TAB_PAD_CONF0_GPIO30  0x8D00
> +#define  VF_TAB_PAD_CONF0_GPIO31  0xCD2A
> +#define  VF_TAB_PAD_CONF0_GPIO32  0x208d51
> +#define  VF_TAB_PAD_CONF0_GPIO33  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO34  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO35  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO36  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO37  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO38  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO39  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO40  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO41  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO42  0x208d51
> +#define  VF_TAB_PAD_CONF0_GPIO43  0x208d51
> +#define  VF_TAB_PAD_CONF0_GPIO44  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO45  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO46  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO47  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO48  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO49  0x8d51
> +#define  VF_TAB_PAD_CONF0_GPIO50  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO51  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO52  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO53  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO54  0xcca9
> +#define  VF_TAB_PAD_CONF0_GPIO55  0x8cd1
> +#define  VF_TAB_PAD_CONF0_GPIO56  0xcd29
> +#define  VF_TAB_PAD_CONF0_GPIO57  0x8C80
> +#define  VF_TAB_PAD_CONF0_GPIO58  0x8C80
> +#define  VF_TAB_PAD_CONF0_GPIO59  0x8C80
> +#define  VF_TAB_PAD_CONF0_GPIO60  0x8C80
> +#define  VF_TAB_PAD_CONF0_GPIO61  0x8800
> +#define  VF_TAB_PAD_CONF0_GPIO62  0x8D00
> +#define  VF_TAB_PAD_CONF0_GPIO63  0x8800
> +#define  VF_TAB_PAD_CONF0_GPIO64  0x8800
> +#define  VF_TAB_PAD_CONF0_GPIO65  0xC828
> +#define  VF_TAB_PAD_CONF0_GPIO66  0xC828
> +#define  VF_TAB_PAD_CONF0_GPIO67  0xC828
> +#define  VF_TAB_PAD_CONF0_GPIO68  0xCCA8
> +#define  VF_TAB_PAD_CONF0_GPIO69  0xC828
> +#define  VF_TAB_PAD_CONF0_GPIO70  0xCCA8
> +
> +
> +
> +//
> +// PAD_CONF1
> +//
> +#define  VF_TAB_PAD_CONF1_GPIO0  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO1  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO2  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO3  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO4  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO5  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO6  0x1F000F
> +#define  VF_TAB_PAD_CONF1_GPIO7  0x1F000F
> +#define  VF_TAB_PAD_CONF1_GPIO8  0x1F000F
> +#define  VF_TAB_PAD_CONF1_GPIO9  0x1F000F
> +#define  VF_TAB_PAD_CONF1_GPIO10  0x1F000F
> +#define  VF_TAB_PAD_CONF1_GPIO11  0x1F000F
> +#define  VF_TAB_PAD_CONF1_GPIO12  0x1F000F
> +#define  VF_TAB_PAD_CONF1_GPIO13  0x1F000F
> +#define  VF_TAB_PAD_CONF1_GPIO14  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO15  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO16  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO17  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO18  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO19  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO20  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO21  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO22  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO23  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO24  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO25  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO26  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO27  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO28  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO29  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO30  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO31  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO32  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO33  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO34  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO35  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO36  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO37  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO38  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO39  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO40  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO41  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO42  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO43  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO44  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO45  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO46  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO47  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO48  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO49  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO50  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO51  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO52  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO53  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO54  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO55  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO56  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO57  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO58  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO59  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO60  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO61  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO62  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO63  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO64  0x00000
> +#define  VF_TAB_PAD_CONF1_GPIO65  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO66  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO67  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO68  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO69  0x20002
> +#define  VF_TAB_PAD_CONF1_GPIO70  0x20002
> +
> +
> +//
> +// PAD_VAL
> +//
> +#define  VF_TAB_PAD_VAL_GPIO0  0x2
> +#define  VF_TAB_PAD_VAL_GPIO1  0x2
> +#define  VF_TAB_PAD_VAL_GPIO2  0x2
> +#define  VF_TAB_PAD_VAL_GPIO3  0x2
> +#define  VF_TAB_PAD_VAL_GPIO4  0x2
> +#define  VF_TAB_PAD_VAL_GPIO5  0x2
> +#define  VF_TAB_PAD_VAL_GPIO6  0x2
> +#define  VF_TAB_PAD_VAL_GPIO7  0x2
> +#define  VF_TAB_PAD_VAL_GPIO8  0x2
> +#define  VF_TAB_PAD_VAL_GPIO9  0x2
> +#define  VF_TAB_PAD_VAL_GPIO10  0x2
> +#define  VF_TAB_PAD_VAL_GPIO11  0x2
> +#define  VF_TAB_PAD_VAL_GPIO12  0x2
> +#define  VF_TAB_PAD_VAL_GPIO13  0x2
> +#define  VF_TAB_PAD_VAL_GPIO14  0x2
> +#define  VF_TAB_PAD_VAL_GPIO15  0x2
> +#define  VF_TAB_PAD_VAL_GPIO16  0x4
> +#define  VF_TAB_PAD_VAL_GPIO17  0x2
> +#define  VF_TAB_PAD_VAL_GPIO18  0x2
> +#define  VF_TAB_PAD_VAL_GPIO19  0x2
> +#define  VF_TAB_PAD_VAL_GPIO20  0x2
> +#define  VF_TAB_PAD_VAL_GPIO21  0x2
> +#define  VF_TAB_PAD_VAL_GPIO22  0x2
> +#define  VF_TAB_PAD_VAL_GPIO23  0x2
> +#define  VF_TAB_PAD_VAL_GPIO24  0x2
> +#define  VF_TAB_PAD_VAL_GPIO25  0x2
> +#define  VF_TAB_PAD_VAL_GPIO26  0x2
> +#define  VF_TAB_PAD_VAL_GPIO27  0x2
> +#define  VF_TAB_PAD_VAL_GPIO28  0x2
> +#define  VF_TAB_PAD_VAL_GPIO29  0x2
> +#define  VF_TAB_PAD_VAL_GPIO30  0x2
> +#define  VF_TAB_PAD_VAL_GPIO31  0x2
> +#define  VF_TAB_PAD_VAL_GPIO32  0x2
> +#define  VF_TAB_PAD_VAL_GPIO33  0x2
> +#define  VF_TAB_PAD_VAL_GPIO34  0x2
> +#define  VF_TAB_PAD_VAL_GPIO35  0x2
> +#define  VF_TAB_PAD_VAL_GPIO36  0x2
> +#define  VF_TAB_PAD_VAL_GPIO37  0x2
> +#define  VF_TAB_PAD_VAL_GPIO38  0x2
> +#define  VF_TAB_PAD_VAL_GPIO39  0x2
> +#define  VF_TAB_PAD_VAL_GPIO40  0x2
> +#define  VF_TAB_PAD_VAL_GPIO41  0x2
> +#define  VF_TAB_PAD_VAL_GPIO42  0x2
> +#define  VF_TAB_PAD_VAL_GPIO43  0x2
> +#define  VF_TAB_PAD_VAL_GPIO44  0x2
> +#define  VF_TAB_PAD_VAL_GPIO45  0x2
> +#define  VF_TAB_PAD_VAL_GPIO46  0x2
> +#define  VF_TAB_PAD_VAL_GPIO47  0x2
> +#define  VF_TAB_PAD_VAL_GPIO48  0x2
> +#define  VF_TAB_PAD_VAL_GPIO49  0x2
> +#define  VF_TAB_PAD_VAL_GPIO50  0x2
> +#define  VF_TAB_PAD_VAL_GPIO51  0x2
> +#define  VF_TAB_PAD_VAL_GPIO52  0x2
> +#define  VF_TAB_PAD_VAL_GPIO53  0x2
> +#define  VF_TAB_PAD_VAL_GPIO54  0x2
> +#define  VF_TAB_PAD_VAL_GPIO55  0x2
> +#define  VF_TAB_PAD_VAL_GPIO56  0x2
> +#define  VF_TAB_PAD_VAL_GPIO57  0x2
> +#define  VF_TAB_PAD_VAL_GPIO58  0x2
> +#define  VF_TAB_PAD_VAL_GPIO59  0x2
> +#define  VF_TAB_PAD_VAL_GPIO60  0x2
> +#define  VF_TAB_PAD_VAL_GPIO61  0x4
> +#define  VF_TAB_PAD_VAL_GPIO62  0x2
> +#define  VF_TAB_PAD_VAL_GPIO63  0x2
> +#define  VF_TAB_PAD_VAL_GPIO64  0x2
> +#define  VF_TAB_PAD_VAL_GPIO65  0x2
> +#define  VF_TAB_PAD_VAL_GPIO66  0x2
> +#define  VF_TAB_PAD_VAL_GPIO67  0x0
> +#define  VF_TAB_PAD_VAL_GPIO68  0x2
> +#define  VF_TAB_PAD_VAL_GPIO69  0x4
> +#define  VF_TAB_PAD_VAL_GPIO70  0x2
> +
> +
> +//
> +// PAD_DFT
> +//
> +#define  VF_TAB_PAD_DFT_GPIO0  0xC
> +#define  VF_TAB_PAD_DFT_GPIO1  0xC
> +#define  VF_TAB_PAD_DFT_GPIO2  0xC
> +#define  VF_TAB_PAD_DFT_GPIO3  0xC
> +#define  VF_TAB_PAD_DFT_GPIO4  0xC
> +#define  VF_TAB_PAD_DFT_GPIO5  0xC
> +#define  VF_TAB_PAD_DFT_GPIO6  0xC
> +#define  VF_TAB_PAD_DFT_GPIO7  0xC
> +#define  VF_TAB_PAD_DFT_GPIO8  0xC
> +#define  VF_TAB_PAD_DFT_GPIO9  0xC
> +#define  VF_TAB_PAD_DFT_GPIO10  0xC
> +#define  VF_TAB_PAD_DFT_GPIO11  0xC
> +#define  VF_TAB_PAD_DFT_GPIO12  0xC
> +#define  VF_TAB_PAD_DFT_GPIO13  0xC
> +#define  VF_TAB_PAD_DFT_GPIO14  0xC
> +#define  VF_TAB_PAD_DFT_GPIO15  0xC
> +#define  VF_TAB_PAD_DFT_GPIO16  0xC
> +#define  VF_TAB_PAD_DFT_GPIO17  0xC
> +#define  VF_TAB_PAD_DFT_GPIO18  0xC
> +#define  VF_TAB_PAD_DFT_GPIO19  0xC
> +#define  VF_TAB_PAD_DFT_GPIO20  0xC
> +#define  VF_TAB_PAD_DFT_GPIO21  0xC
> +#define  VF_TAB_PAD_DFT_GPIO22  0xC
> +#define  VF_TAB_PAD_DFT_GPIO23  0xC
> +#define  VF_TAB_PAD_DFT_GPIO24  0xC
> +#define  VF_TAB_PAD_DFT_GPIO25  0xC
> +#define  VF_TAB_PAD_DFT_GPIO26  0xC
> +#define  VF_TAB_PAD_DFT_GPIO27  0xC
> +#define  VF_TAB_PAD_DFT_GPIO28  0xC
> +#define  VF_TAB_PAD_DFT_GPIO29  0xC
> +#define  VF_TAB_PAD_DFT_GPIO30  0xC
> +#define  VF_TAB_PAD_DFT_GPIO31  0xC
> +#define  VF_TAB_PAD_DFT_GPIO32  0xC
> +#define  VF_TAB_PAD_DFT_GPIO33  0xC
> +#define  VF_TAB_PAD_DFT_GPIO34  0xC
> +#define  VF_TAB_PAD_DFT_GPIO35  0xC
> +#define  VF_TAB_PAD_DFT_GPIO36  0xC
> +#define  VF_TAB_PAD_DFT_GPIO37  0xC
> +#define  VF_TAB_PAD_DFT_GPIO38  0xC
> +#define  VF_TAB_PAD_DFT_GPIO39  0xC
> +#define  VF_TAB_PAD_DFT_GPIO40  0xC
> +#define  VF_TAB_PAD_DFT_GPIO41  0xC
> +#define  VF_TAB_PAD_DFT_GPIO42  0xC
> +#define  VF_TAB_PAD_DFT_GPIO43  0xC
> +#define  VF_TAB_PAD_DFT_GPIO44  0xC
> +#define  VF_TAB_PAD_DFT_GPIO45  0xC
> +#define  VF_TAB_PAD_DFT_GPIO46  0xC
> +#define  VF_TAB_PAD_DFT_GPIO47  0xC
> +#define  VF_TAB_PAD_DFT_GPIO48  0xC
> +#define  VF_TAB_PAD_DFT_GPIO49  0xC
> +#define  VF_TAB_PAD_DFT_GPIO50  0xC
> +#define  VF_TAB_PAD_DFT_GPIO51  0xC
> +#define  VF_TAB_PAD_DFT_GPIO52  0xC
> +#define  VF_TAB_PAD_DFT_GPIO53  0xC
> +#define  VF_TAB_PAD_DFT_GPIO54  0xC
> +#define  VF_TAB_PAD_DFT_GPIO55  0xC
> +#define  VF_TAB_PAD_DFT_GPIO56  0xC
> +#define  VF_TAB_PAD_DFT_GPIO57  0xC
> +#define  VF_TAB_PAD_DFT_GPIO58  0xC
> +#define  VF_TAB_PAD_DFT_GPIO59  0xC
> +#define  VF_TAB_PAD_DFT_GPIO60  0xC
> +#define  VF_TAB_PAD_DFT_GPIO61  0xC
> +#define  VF_TAB_PAD_DFT_GPIO62  0xC
> +#define  VF_TAB_PAD_DFT_GPIO63  0xC
> +#define  VF_TAB_PAD_DFT_GPIO64  0xC
> +#define  VF_TAB_PAD_DFT_GPIO65  0xC
> +#define  VF_TAB_PAD_DFT_GPIO66  0xC
> +#define  VF_TAB_PAD_DFT_GPIO67  0xC
> +#define  VF_TAB_PAD_DFT_GPIO68  0xC
> +#define  VF_TAB_PAD_DFT_GPIO69  0xC
> +#define  VF_TAB_PAD_DFT_GPIO70  0xC
> +
> +
> +//
> +//SUS WELL
> +//
> +
> +//
> +// CONF0
> +//
> +#define  VF_TAB_PAD_CONF0_GPIO_SUS0  0xCCA8
> +#define  VF_TAB_PAD_CONF0_GPIO_SUS1  0xCCA8
> +#define  VF_TAB_PAD_CONF0_GPIO_SUS2  0xCCA8
> +#define  VF_TAB_PAD_CONF0_GPIO_SUS3  0xCD28
> +#define  VF_TAB_PAD_CONF0_GPIO_SUS4  0xCD28
> +#define  VF_TAB_PAD_CONF0_GPIO_SUS5  0xCD28
> +#define  VF_TAB_PAD_CONF0_GPIO_SUS6  0x8850
> +#define  VF_TAB_PAD_CONF0_GPIO_SUS7  0x8850
> +#define  VF_TAB_PAD_CONF0_GPIO_SUS8  0xCCA8
> +#define  VF_TAB_PAD_CONF0_GPIO_SUS9  0xCCA8
> +#define  VF_TAB_PAD_CONF0_GPIO_SUS10  0xCCA8
> +#define  VF_TAB_PAD_CONF0_GPIO_SUS11  0xC828
> +#define  VF_TAB_PAD_CONF0_GPIO_SUS12  0xC828
> +#define  VF_TAB_PAD_CONF0_GPIO_SUS13  0xCCA8
> +#define  VF_TAB_PAD_CONF0_GPIO_SUS14  0xCCA8
> +#define  VF_TAB_PAD_CONF0_GPIO_SUS15  0x8C80
> +#define  VF_TAB_PAD_CONF0_GPIO_SUS16  0xC828
> +
> +//
> +// CONF1
> +//
> +#define  VF_TAB_PAD_CONF1_GPIO_SUS0  0
> +#define  VF_TAB_PAD_CONF1_GPIO_SUS1  0
> +#define  VF_TAB_PAD_CONF1_GPIO_SUS2  0
> +#define  VF_TAB_PAD_CONF1_GPIO_SUS3  0
> +#define  VF_TAB_PAD_CONF1_GPIO_SUS4  0
> +#define  VF_TAB_PAD_CONF1_GPIO_SUS5  0
> +#define  VF_TAB_PAD_CONF1_GPIO_SUS6  0
> +#define  VF_TAB_PAD_CONF1_GPIO_SUS7  0
> +#define  VF_TAB_PAD_CONF1_GPIO_SUS8  0
> +#define  VF_TAB_PAD_CONF1_GPIO_SUS9  0
> +#define  VF_TAB_PAD_CONF1_GPIO_SUS10  0
> +#define  VF_TAB_PAD_CONF1_GPIO_SUS11  0
> +#define  VF_TAB_PAD_CONF1_GPIO_SUS12  0
> +#define  VF_TAB_PAD_CONF1_GPIO_SUS13  0
> +#define  VF_TAB_PAD_CONF1_GPIO_SUS14  0
> +#define  VF_TAB_PAD_CONF1_GPIO_SUS15  0
> +#define  VF_TAB_PAD_CONF1_GPIO_SUS16  0
> +
> +//
> +// PAD_VAL
> +//
> +#define  VF_TAB_PAD_VAL_GPIO_SUS0  0
> +#define  VF_TAB_PAD_VAL_GPIO_SUS1  0
> +#define  VF_TAB_PAD_VAL_GPIO_SUS2  0
> +#define  VF_TAB_PAD_VAL_GPIO_SUS3  0
> +#define  VF_TAB_PAD_VAL_GPIO_SUS4  0
> +#define  VF_TAB_PAD_VAL_GPIO_SUS5  0
> +#define  VF_TAB_PAD_VAL_GPIO_SUS6  0
> +#define  VF_TAB_PAD_VAL_GPIO_SUS7  0
> +#define  VF_TAB_PAD_VAL_GPIO_SUS8  0
> +#define  VF_TAB_PAD_VAL_GPIO_SUS9  0
> +#define  VF_TAB_PAD_VAL_GPIO_SUS10  0
> +#define  VF_TAB_PAD_VAL_GPIO_SUS11  0
> +#define  VF_TAB_PAD_VAL_GPIO_SUS12  0
> +#define  VF_TAB_PAD_VAL_GPIO_SUS13  0
> +#define  VF_TAB_PAD_VAL_GPIO_SUS14  0
> +#define  VF_TAB_PAD_VAL_GPIO_SUS15  0
> +#define  VF_TAB_PAD_VAL_GPIO_SUS16  0
> +
> +//
> +// PAD_DFT
> +//
> +#define  VF_TAB_PAD_DFT_GPIO_SUS0  0
> +#define  VF_TAB_PAD_DFT_GPIO_SUS1  0
> +#define  VF_TAB_PAD_DFT_GPIO_SUS2  0
> +#define  VF_TAB_PAD_DFT_GPIO_SUS3  0
> +#define  VF_TAB_PAD_DFT_GPIO_SUS4  0
> +#define  VF_TAB_PAD_DFT_GPIO_SUS5  0
> +#define  VF_TAB_PAD_DFT_GPIO_SUS6  0
> +#define  VF_TAB_PAD_DFT_GPIO_SUS7  0
> +#define  VF_TAB_PAD_DFT_GPIO_SUS8  0
> +#define  VF_TAB_PAD_DFT_GPIO_SUS9  0
> +#define  VF_TAB_PAD_DFT_GPIO_SUS10  0
> +#define  VF_TAB_PAD_DFT_GPIO_SUS11  0
> +#define  VF_TAB_PAD_DFT_GPIO_SUS12  0
> +#define  VF_TAB_PAD_DFT_GPIO_SUS13  0
> +#define  VF_TAB_PAD_DFT_GPIO_SUS14  0
> +#define  VF_TAB_PAD_DFT_GPIO_SUS15  0
> +#define  VF_TAB_PAD_DFT_GPIO_SUS16  0
> +
> +
> +//
> +//
> +//              GPIO Register Settings for ValleyFalls (Netbook)
> +//
> +//
> +//                   IO Space configyuration registers
> +// Field Descriptions:
> +//    USE: Defines the pin's usage model:  GPIO (G) or Native (N) mode.
> +//    I/O: Defines whether GPIOs are inputs (I) or outputs (O).
> +//         (Note:  Only meaningful for pins used as GPIOs.)
> +//    LVL: This field gives you the initial value for "output" GPIO's.
> +//         (Note: The output level is dependent upon whether the pin is
> inverted.)
> +//    TPE: Defines whether Trigger Positive Edge Enable.
> +//    TNE: Defines whether Trigger Negative Edge Enable.
> +//    WAKE_EN: only support in SUS community
> +//         (Note:  Only affects the level sent to the GPE logic and does not
> +//         affect the level read through the GPIO registers.)
> +//
> +//
> +//                    Memory spcae configuration registers
> +//
> +// Field Descriptions:
> +//   PAD releated:
> +//    PAD_CONF0
> +//      PAD_CONF1
> +//      PAD_VAL
> +//      PAD_DFT
> +//
> +// Notes:
> +//    1. N = Native , G = GPIO , I = Input, O = Output, - = BOTH/NOT SURE
> +//
> +// Signal          UsedAs                       USE     I/O      LVL     TPE     TNE   PCONF0
> PCONF1   PVAL  PDFT
> +// -----------------------------------------------------------------------------------------
> --------------------------------
> +// GPIO0           UART1_RXD-L                   N       I        -       -       -     cd29h    -         -
> -
> +// GPIO1           UART1_TXD-0                   N       O        -       -       -     cd29h    -         -
> -
> +// *GPIO2           UART1_RTS_B-1                N       I        -       -       -     cca9h    -         -
> -
> +// *GPIO3           UART1_CTS_B-H                N       O        -       -       -     cca9h    -
> -     -
> +
> +// GPIO4           NMI_B-H                       G       -        -       -       -     cca9h    -         -     -
> +// GPIO5           GPIO_D5                       G       -        -       -       -     cca9h    -         -     -
> +// GPIO6           GPIO_D6                       G       O        -       -       -     8d51h    -         -     -
> +// GPIO7           GPIO_D7                       G       O        -       -       -     8cd1h    -         -     -
> +// GPIO8           GPIO_D8                       G       O        -       -       -     8cd1h    -         -     -
> +// GPIO9           GPIO_D9                       G       I        -       -       -     8cd1h    -         -     -
> +
> +// GPIO10          GPIO_D10                      G       O        -       -       -     8d51h    -         -
> -
> +// GPIO11          GPIO_D11                      G       O        -       -       -     8cd1h    -         -     -
> +// GPIO12          GPIO_D12                      G       O        -       -       -     8cd1h    -         -     -
> +// GPIO13          GPIO_D13                      G       I        -       -       -     8d51h    -         -     -
> +
> +// GPIO14          SATA_GP0                      N       -        -       -       -      -       -         -     -
> +// GPIO15          SATA_GP1-L                    N       -        -       -       -     ccaah    -         -     -
> +
> +// GPIO16          SATA_LEDN-OD-O                N       O        -       -       -      -       -         -
> -
> +// GPIO17          PCIE_CLKREQ0B-20K,H           N       I        -       -       -     cd2ah    -
> -     -
> +// GPIO18          PCIE_CLKREQ1B-20K,H           N       O        -       -       -     ccaah    -
> -     -
> +// GPIO19          PCIE_CLKREQ2B-20K,H           N       I        -       -       -     ccaah    -
> -     -
> +// GPIO20          PCIE_CLKREQ3B-20K,H           N       -        -       -       -     ccaah    -
> -     -
> +// GPIO21          PCIE_CLKREQ4B-20K,H           N       -        -       -       -      -       -         -
> -
> +// GPIO22          FLEX_CLK_SE0-20K,L            N       O        -       -       -     ccaah    -
> -     -
> +// GPIO23          FLEX_CLK_SE1-20K,L            N       -        -       -       -      -       -         -
> -
> +
> +// GPIO24          HDA_RSTB                      N       O        -       -       -     8d02h    -         -
> -
> +// GPIO25          HDA_SYNC                      N       O        -       -       -     8d02h    -         -
> -
> +// GPIO26          HDA_CLK                       N       O        -       -       -     8d02h    -         -     -
> +// GPIO27          HDA_SDO                       N       I        -       -       -     8d02h    -         -     -
> +// GPIO28          HDA_SDI0                      N       I        -       -       -      -       -         -     -
> +// GPIO29          HDA_SDI1                      N       O        -       -       -      -       -         -     -
> +// GPIO30          HDA_DOCKRSTB                  N       I        -       -       -      -       -         -     -
> +// GPIO31          HDA_DOCKENB                   N       O        -       -       -      -       -         -
> -
> +
> +// GPIO32          SDMMC1_CLK                    N       -        -       -       -     208d51h   -
> -     -
> +// GPIO33          SDMMC1_D0                     N       -        -       -       -     8cd1h     -         -
> -
> +// GPIO34          SDMMC1_D1                     N       -        -       -       -     8cd1h     -         -
> -
> +// GPIO35          SDMMC1_D2                     N       -        -       -       -     8cd1h     -         -
> -
> +// GPIO36          SDMMC1_D3_CD_B                N       -        -       -       -     8cd1h     -
> -     -
> +// GPIO37          MMC1_D4_SD_WE                 N       -        -       -       -     8cd1h     -
> -     -
> +// GPIO38          MMC1_D5                       N       -        -       -       -     8cd1h     -         -
> -
> +// GPIO39          MMC1_D6                       N       -        -       -       -     8cd1h     -         -
> -
> +// GPIO40          MMC1_D7                       N       -        -       -       -     8cd1h     -         -
> -
> +// GPIO41          SDMMC1_CMD                    N       -        -       -       -     8cd1h     -
> -     -
> +// GPIO42          MMC1_RESET_B                  N       -        -       -       -     208d51h   -
> -     -
> +
> +// GPIO43          SDMMC2_CLK                    N       -        -       -       -     208d51h   -
> -     -
> +// GPIO44          SDMMC2_D0                     N       -        -       -       -     8cd1h     -         -
> -
> +// GPIO45          SDMMC2_D1                     N       -        -       -       -     8cd1h     -         -
> -
> +// GPIO46          SDMMC2_D2                     N       -        -       -       -     8cd1h     -         -
> -
> +// GPIO47          SDMMC2_D3_CD_B                N       -        -       -       -     8cd1h     -
> -     -
> +// GPIO48          SDMMC2_CMD                    N       -        -       -       -     8cd1h     -
> -     -
> +
> +// GPIO49          SDMMC3_CLK                    N       -        -       -       -     8d51h      -         -
> -
> +// GPIO50          SDMMC3_D0                     N       -        -       -       -     8cd1h      -         -
> -
> +// GPIO51          SDMMC3_D1                     N       -        -       -       -      8cd1h      -         -
> -
> +// GPIO52          SDMMC3_D2                     N       -        -       -       -      8cd1h      -         -
> -
> +// GPIO53          SDMMC3_D3                     N       -        -       -       -      8cd1h      -         -
> -
> +// GPIO54          SDMMC3_CD_B                   N       -        -       -       -      cca9h      -
> -     -
> +// GPIO55          SDMMC3_CMD                    N       -        -       -       -      8cd1h      -
> -     -
> +// GPIO56          SDMMC3_1P8_EN                 N       -        -       -       -      cd29h   -
> -     -
> +
> +// GPIO57          LPC_AD0                     N       -        -       -       -      -       -         -     -
> +// GPIO58          LPC_AD1                     N       -        -       -       -      -       -         -     -
> +// GPIO59          LPC_AD2                     N       -        -       -       -      -       -         -     -
> +// GPIO60          LPC_AD3                     N       -        -       -       -      -       -         -     -
> +// GPIO61          LPC_FRAMEB                  N       O        -       -       -      -       -         -     -
> +// GPIO62          LPC_CLKOUT0                 N       O        -       -       -      -       -         -     -
> +// GPIO63          LPC_CLKOUT1                 N       O        -       -       -      -       -         -     -
> +// GPIO64          LPC_CLKRUNB                 N       -        -       -       -      -       -         -     -
> +
> +// GPIO65          SMB_DATA                    N       -        -       -       -      -       -         -     -
> +// GPIO66          SMB_CLK                     N       -        -       -       -      -       -         -     -
> +// GPIO67          SMB_ALERTB                  N       -        -       -       -      -       -         -     -
> +
> +// GPIO68          ILB_SEIRQ                   N       -       -        -       -      -       -         -     -
> +// GPIO69          SPKR                        N       O       -        -       -      -       -         -     -
> +
> +//SUS WELL
> +
> +
> +//GPIO_SUS0             GPIO_SUS0                   N       O       -        -       -     CCA8h       -
> -     -
> +//GPIO_SUS1             GPIO_SUS1                   N       O       -        -       -     CCA8h       -
> -     -
> +//GPIO_SUS2             GPIO_SUS2                   N       O       -        -       -     CCA8h       -
> -     -
> +//GPIO_SUS3             GPIO_SUS3                   N       O       -        -       -     CD28h       -
> -     -
> +//GPIO_SUS4             GPIO_SUS4                   N       O       -        -       -     CD28h       -
> -     -
> +//GPIO_SUS5             GPIO_SUS5                   N       O       -        -       -     CD28h       -
> -     -
> +//GPIO_SUS6             SUSPWRDNACK-0               N       O       -        -       -     8850h
> -         -     -
> +//GPIO_SUS7             PMU_SLP_DDRVTT_B-0          N       O       -        -       -
> 8850h       -         -     -
> +//GPIO_SUS8             PMU_WAKE_B-20K,H            N       O       -        -       -
> CCA8h       -         -     -
> +//GPIO_SUS9             PMU_PWRBTN_B-20K,H          N       O       -        -       -
> CCA8h       -         -     -
> +//GPIO_SUS10            PMU_WAKE_LAN_B-20K,H        N       O       -        -       -
> CCA8h       -         -     -
> +//GPIO_SUS11            SUS_STAT_B-1                N       O       -        -       -     C828h
> -         -     -
> +//GPIO_SUS12            PMU_SUSCLK-0                N       O       -        -       -     C828h
> -         -     -
> +//GPIO_SUS13            USB_OC0_B-20K,H             N       O       -        -       -     CCA8h
> -         -     -
> +//GPIO_SUS14            USB_OC1_B-20K,H             N       O       -        -       -     CCA8h
> -         -     -
> +//GPIO_SUS15            SPI_CS1_B-20K,H             N       O       -        -       -     8C80h
> -         -     -
> +//GPIO_SUS16            SPI_CS1_B-20K,H             N       O       -        -       -     C828h
> -         -     -
> +//
> +
> +#define VF_NET_GPIO_USE_SEL_VAL_0_31        0x00000000
> +#define VF_NET_GPIO_USE_SEL_VAL_32_63       0x00000000
> +#define VF_NET_GPIO_USE_SEL_VAL_64_70       0x00000000
> +#define VF_NET_GPIO_USE_SEL_VAL_SUS         0x00000000
> +
> +//
> +//1010 --00 0100 01-- 0101 --0- 0001 1010
> +//
> +#define VF_NET_GPIO_IO_SEL_VAL_0_31         0x00000000 // BIT30 | BIT28 |
> BIT27 | BIT19 | BIT17 | BIT13 | BIT9 | BIT2 | BIT0
> +#define VF_NET_GPIO_IO_SEL_VAL_32_63        0x00000000
> +#define VF_NET_GPIO_IO_SEL_VAL_64_70        0x00000000
> +#define VF_NET_GPIO_IO_SEL_VAL_SUS          0x00000000
> +
> +
> +#define VF_NET_GPIO_LVL_VAL_0_31            0x00000000
> +#define VF_NET_GPIO_LVL_VAL_32_63           0x00000000
> +#define VF_NET_GPIO_LVL_VAL_64_70           0x00000000
> +#define VF_NET_GPIO_LVL_VAL_SUS             0x00000000
> +
> +#define VF_NET_GPIO_TPE_VAL_0_31            0x00000000
> +#define VF_NET_GPIO_TPE_VAL_SUS             0x00000000
> +
> +#define VF_NET_GPIO_TNE_VAL_0_31            0x00000000
> +#define VF_NET_GPIO_TNE_VAL_SUS             0x00000000
> +
> +#define VF_NET_GPIO_TS_VAL_0_31             0x00000000
> +#define VF_NET_GPIO_TS_VAL_SUS              0x00000000
> +
> +
> +//
> +// Memory space registers
> +//
> +
> +
> +//
> +// CONF0
> +//
> +#define  VF_NET_PAD_CONF0_GPIO0  0xcd29
> +#define  VF_NET_PAD_CONF0_GPIO1  0xcd29
> +#define  VF_NET_PAD_CONF0_GPIO2  0xcca9
> +#define  VF_NET_PAD_CONF0_GPIO3  0xcca9
> +#define  VF_NET_PAD_CONF0_GPIO4  0xcca8
> +#define  VF_NET_PAD_CONF0_GPIO5  0xcca8
> +#define  VF_NET_PAD_CONF0_GPIO6  0x8d50
> +#define  VF_NET_PAD_CONF0_GPIO7  0x8cd0
> +#define  VF_NET_PAD_CONF0_GPIO8  0x8cd0
> +#define  VF_NET_PAD_CONF0_GPIO9  0x8cd0
> +#define  VF_NET_PAD_CONF0_GPIO10  0x8d50
> +#define  VF_NET_PAD_CONF0_GPIO11  0x8cd0
> +#define  VF_NET_PAD_CONF0_GPIO12  0x8cd0
> +#define  VF_NET_PAD_CONF0_GPIO13  0x8d50
> +#define  VF_NET_PAD_CONF0_GPIO14  0xCCA8
> +#define  VF_NET_PAD_CONF0_GPIO15  0xccaa
> +#define  VF_NET_PAD_CONF0_GPIO16  0xC828
> +#define  VF_NET_PAD_CONF0_GPIO17  0xcd2a
> +#define  VF_NET_PAD_CONF0_GPIO18  0xccaa
> +#define  VF_NET_PAD_CONF0_GPIO19  0xccaa
> +#define  VF_NET_PAD_CONF0_GPIO20  0xccaa
> +#define  VF_NET_PAD_CONF0_GPIO21  0xCCA9
> +#define  VF_NET_PAD_CONF0_GPIO22  0xccaa
> +#define  VF_NET_PAD_CONF0_GPIO23  0xCD2A
> +#define  VF_NET_PAD_CONF0_GPIO24  0x8d02
> +#define  VF_NET_PAD_CONF0_GPIO25  0x8d02
> +#define  VF_NET_PAD_CONF0_GPIO26  0x8d02
> +#define  VF_NET_PAD_CONF0_GPIO27  0x8d02
> +#define  VF_NET_PAD_CONF0_GPIO28  0x8D02
> +#define  VF_NET_PAD_CONF0_GPIO29  0x8D02
> +#define  VF_NET_PAD_CONF0_GPIO30  0x8D00
> +#define  VF_NET_PAD_CONF0_GPIO31  0xCD2A
> +#define  VF_NET_PAD_CONF0_GPIO32  0x208d51
> +#define  VF_NET_PAD_CONF0_GPIO33  0x8cd1
> +#define  VF_NET_PAD_CONF0_GPIO34  0x8cd1
> +#define  VF_NET_PAD_CONF0_GPIO35  0x8cd1
> +#define  VF_NET_PAD_CONF0_GPIO36  0x8cd1
> +#define  VF_NET_PAD_CONF0_GPIO37  0x8cd1
> +#define  VF_NET_PAD_CONF0_GPIO38  0x8cd1
> +#define  VF_NET_PAD_CONF0_GPIO39  0x8cd1
> +#define  VF_NET_PAD_CONF0_GPIO40  0x8cd1
> +#define  VF_NET_PAD_CONF0_GPIO41  0x8cd1
> +#define  VF_NET_PAD_CONF0_GPIO42  0x208d51
> +#define  VF_NET_PAD_CONF0_GPIO43  0x208d51
> +#define  VF_NET_PAD_CONF0_GPIO44  0x8cd1
> +#define  VF_NET_PAD_CONF0_GPIO45  0x8cd1
> +#define  VF_NET_PAD_CONF0_GPIO46  0x8cd1
> +#define  VF_NET_PAD_CONF0_GPIO47  0x8cd1
> +#define  VF_NET_PAD_CONF0_GPIO48  0x8cd1
> +#define  VF_NET_PAD_CONF0_GPIO49  0x8d51
> +#define  VF_NET_PAD_CONF0_GPIO50  0x8cd1
> +#define  VF_NET_PAD_CONF0_GPIO51  0x8cd1
> +#define  VF_NET_PAD_CONF0_GPIO52  0x8cd1
> +#define  VF_NET_PAD_CONF0_GPIO53  0x8cd1
> +#define  VF_NET_PAD_CONF0_GPIO54  0xcca9
> +#define  VF_NET_PAD_CONF0_GPIO55  0x8cd1
> +#define  VF_NET_PAD_CONF0_GPIO56  0xcd29
> +#define  VF_NET_PAD_CONF0_GPIO57  0x8C80
> +#define  VF_NET_PAD_CONF0_GPIO58  0x8C80
> +#define  VF_NET_PAD_CONF0_GPIO59  0x8C80
> +#define  VF_NET_PAD_CONF0_GPIO60  0x8C80
> +#define  VF_NET_PAD_CONF0_GPIO61  0x8800
> +#define  VF_NET_PAD_CONF0_GPIO62  0x8D00
> +#define  VF_NET_PAD_CONF0_GPIO63  0x8800
> +#define  VF_NET_PAD_CONF0_GPIO64  0x8800
> +#define  VF_NET_PAD_CONF0_GPIO65  0xC828
> +#define  VF_NET_PAD_CONF0_GPIO66  0xC828
> +#define  VF_NET_PAD_CONF0_GPIO67  0xC828
> +#define  VF_NET_PAD_CONF0_GPIO68  0xCCA8
> +#define  VF_NET_PAD_CONF0_GPIO69  0xC828
> +#define  VF_NET_PAD_CONF0_GPIO70  0xCCA8
> +
> +
> +
> +
> +//
> +// PAD_CONF1
> +//
> +#define  VF_NET_PAD_CONF1_GPIO0  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO1  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO2  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO3  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO4  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO5  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO6  0x1F000F
> +#define  VF_NET_PAD_CONF1_GPIO7  0x1F000F
> +#define  VF_NET_PAD_CONF1_GPIO8  0x1F000F
> +#define  VF_NET_PAD_CONF1_GPIO9  0x1F000F
> +#define  VF_NET_PAD_CONF1_GPIO10  0x1F000F
> +#define  VF_NET_PAD_CONF1_GPIO11  0x1F000F
> +#define  VF_NET_PAD_CONF1_GPIO12  0x1F000F
> +#define  VF_NET_PAD_CONF1_GPIO13  0x1F000F
> +#define  VF_NET_PAD_CONF1_GPIO14  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO15  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO16  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO17  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO18  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO19  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO20  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO21  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO22  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO23  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO24  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO25  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO26  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO27  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO28  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO29  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO30  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO31  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO32  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO33  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO34  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO35  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO36  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO37  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO38  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO39  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO40  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO41  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO42  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO43  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO44  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO45  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO46  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO47  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO48  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO49  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO50  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO51  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO52  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO53  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO54  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO55  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO56  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO57  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO58  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO59  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO60  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO61  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO62  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO63  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO64  0x00000
> +#define  VF_NET_PAD_CONF1_GPIO65  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO66  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO67  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO68  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO69  0x20002
> +#define  VF_NET_PAD_CONF1_GPIO70  0x20002
> +
> +
> +
> +//
> +// PAD_VAL
> +//
> +#define  VF_NET_PAD_VAL_GPIO0  0x2
> +#define  VF_NET_PAD_VAL_GPIO1  0x2
> +#define  VF_NET_PAD_VAL_GPIO2  0x2
> +#define  VF_NET_PAD_VAL_GPIO3  0x2
> +#define  VF_NET_PAD_VAL_GPIO4  0x2
> +#define  VF_NET_PAD_VAL_GPIO5  0x2
> +#define  VF_NET_PAD_VAL_GPIO6  0x2
> +#define  VF_NET_PAD_VAL_GPIO7  0x2
> +#define  VF_NET_PAD_VAL_GPIO8  0x2
> +#define  VF_NET_PAD_VAL_GPIO9  0x2
> +#define  VF_NET_PAD_VAL_GPIO10  0x2
> +#define  VF_NET_PAD_VAL_GPIO11  0x2
> +#define  VF_NET_PAD_VAL_GPIO12  0x2
> +#define  VF_NET_PAD_VAL_GPIO13  0x2
> +#define  VF_NET_PAD_VAL_GPIO14  0x2
> +#define  VF_NET_PAD_VAL_GPIO15  0x2
> +#define  VF_NET_PAD_VAL_GPIO16  0x4
> +#define  VF_NET_PAD_VAL_GPIO17  0x2
> +#define  VF_NET_PAD_VAL_GPIO18  0x2
> +#define  VF_NET_PAD_VAL_GPIO19  0x2
> +#define  VF_NET_PAD_VAL_GPIO20  0x2
> +#define  VF_NET_PAD_VAL_GPIO21  0x2
> +#define  VF_NET_PAD_VAL_GPIO22  0x2
> +#define  VF_NET_PAD_VAL_GPIO23  0x2
> +#define  VF_NET_PAD_VAL_GPIO24  0x2
> +#define  VF_NET_PAD_VAL_GPIO25  0x2
> +#define  VF_NET_PAD_VAL_GPIO26  0x2
> +#define  VF_NET_PAD_VAL_GPIO27  0x2
> +#define  VF_NET_PAD_VAL_GPIO28  0x2
> +#define  VF_NET_PAD_VAL_GPIO29  0x2
> +#define  VF_NET_PAD_VAL_GPIO30  0x2
> +#define  VF_NET_PAD_VAL_GPIO31  0x2
> +#define  VF_NET_PAD_VAL_GPIO32  0x2
> +#define  VF_NET_PAD_VAL_GPIO33  0x2
> +#define  VF_NET_PAD_VAL_GPIO34  0x2
> +#define  VF_NET_PAD_VAL_GPIO35  0x2
> +#define  VF_NET_PAD_VAL_GPIO36  0x2
> +#define  VF_NET_PAD_VAL_GPIO37  0x2
> +#define  VF_NET_PAD_VAL_GPIO38  0x2
> +#define  VF_NET_PAD_VAL_GPIO39  0x2
> +#define  VF_NET_PAD_VAL_GPIO40  0x2
> +#define  VF_NET_PAD_VAL_GPIO41  0x2
> +#define  VF_NET_PAD_VAL_GPIO42  0x2
> +#define  VF_NET_PAD_VAL_GPIO43  0x2
> +#define  VF_NET_PAD_VAL_GPIO44  0x2
> +#define  VF_NET_PAD_VAL_GPIO45  0x2
> +#define  VF_NET_PAD_VAL_GPIO46  0x2
> +#define  VF_NET_PAD_VAL_GPIO47  0x2
> +#define  VF_NET_PAD_VAL_GPIO48  0x2
> +#define  VF_NET_PAD_VAL_GPIO49  0x2
> +#define  VF_NET_PAD_VAL_GPIO50  0x2
> +#define  VF_NET_PAD_VAL_GPIO51  0x2
> +#define  VF_NET_PAD_VAL_GPIO52  0x2
> +#define  VF_NET_PAD_VAL_GPIO53  0x2
> +#define  VF_NET_PAD_VAL_GPIO54  0x2
> +#define  VF_NET_PAD_VAL_GPIO55  0x2
> +#define  VF_NET_PAD_VAL_GPIO56  0x2
> +#define  VF_NET_PAD_VAL_GPIO57  0x2
> +#define  VF_NET_PAD_VAL_GPIO58  0x2
> +#define  VF_NET_PAD_VAL_GPIO59  0x2
> +#define  VF_NET_PAD_VAL_GPIO60  0x2
> +#define  VF_NET_PAD_VAL_GPIO61  0x4
> +#define  VF_NET_PAD_VAL_GPIO62  0x2
> +#define  VF_NET_PAD_VAL_GPIO63  0x2
> +#define  VF_NET_PAD_VAL_GPIO64  0x2
> +#define  VF_NET_PAD_VAL_GPIO65  0x2
> +#define  VF_NET_PAD_VAL_GPIO66  0x2
> +#define  VF_NET_PAD_VAL_GPIO67  0x0
> +#define  VF_NET_PAD_VAL_GPIO68  0x2
> +#define  VF_NET_PAD_VAL_GPIO69  0x4
> +#define  VF_NET_PAD_VAL_GPIO70  0x2
> +
> +
> +//
> +// PAD_DFT
> +//
> +#define  VF_NET_PAD_DFT_GPIO0  0xC
> +#define  VF_NET_PAD_DFT_GPIO1  0xC
> +#define  VF_NET_PAD_DFT_GPIO2  0xC
> +#define  VF_NET_PAD_DFT_GPIO3  0xC
> +#define  VF_NET_PAD_DFT_GPIO4  0xC
> +#define  VF_NET_PAD_DFT_GPIO5  0xC
> +#define  VF_NET_PAD_DFT_GPIO6  0xC
> +#define  VF_NET_PAD_DFT_GPIO7  0xC
> +#define  VF_NET_PAD_DFT_GPIO8  0xC
> +#define  VF_NET_PAD_DFT_GPIO9  0xC
> +#define  VF_NET_PAD_DFT_GPIO10  0xC
> +#define  VF_NET_PAD_DFT_GPIO11  0xC
> +#define  VF_NET_PAD_DFT_GPIO12  0xC
> +#define  VF_NET_PAD_DFT_GPIO13  0xC
> +#define  VF_NET_PAD_DFT_GPIO14  0xC
> +#define  VF_NET_PAD_DFT_GPIO15  0xC
> +#define  VF_NET_PAD_DFT_GPIO16  0xC
> +#define  VF_NET_PAD_DFT_GPIO17  0xC
> +#define  VF_NET_PAD_DFT_GPIO18  0xC
> +#define  VF_NET_PAD_DFT_GPIO19  0xC
> +#define  VF_NET_PAD_DFT_GPIO20  0xC
> +#define  VF_NET_PAD_DFT_GPIO21  0xC
> +#define  VF_NET_PAD_DFT_GPIO22  0xC
> +#define  VF_NET_PAD_DFT_GPIO23  0xC
> +#define  VF_NET_PAD_DFT_GPIO24  0xC
> +#define  VF_NET_PAD_DFT_GPIO25  0xC
> +#define  VF_NET_PAD_DFT_GPIO26  0xC
> +#define  VF_NET_PAD_DFT_GPIO27  0xC
> +#define  VF_NET_PAD_DFT_GPIO28  0xC
> +#define  VF_NET_PAD_DFT_GPIO29  0xC
> +#define  VF_NET_PAD_DFT_GPIO30  0xC
> +#define  VF_NET_PAD_DFT_GPIO31  0xC
> +#define  VF_NET_PAD_DFT_GPIO32  0xC
> +#define  VF_NET_PAD_DFT_GPIO33  0xC
> +#define  VF_NET_PAD_DFT_GPIO34  0xC
> +#define  VF_NET_PAD_DFT_GPIO35  0xC
> +#define  VF_NET_PAD_DFT_GPIO36  0xC
> +#define  VF_NET_PAD_DFT_GPIO37  0xC
> +#define  VF_NET_PAD_DFT_GPIO38  0xC
> +#define  VF_NET_PAD_DFT_GPIO39  0xC
> +#define  VF_NET_PAD_DFT_GPIO40  0xC
> +#define  VF_NET_PAD_DFT_GPIO41  0xC
> +#define  VF_NET_PAD_DFT_GPIO42  0xC
> +#define  VF_NET_PAD_DFT_GPIO43  0xC
> +#define  VF_NET_PAD_DFT_GPIO44  0xC
> +#define  VF_NET_PAD_DFT_GPIO45  0xC
> +#define  VF_NET_PAD_DFT_GPIO46  0xC
> +#define  VF_NET_PAD_DFT_GPIO47  0xC
> +#define  VF_NET_PAD_DFT_GPIO48  0xC
> +#define  VF_NET_PAD_DFT_GPIO49  0xC
> +#define  VF_NET_PAD_DFT_GPIO50  0xC
> +#define  VF_NET_PAD_DFT_GPIO51  0xC
> +#define  VF_NET_PAD_DFT_GPIO52  0xC
> +#define  VF_NET_PAD_DFT_GPIO53  0xC
> +#define  VF_NET_PAD_DFT_GPIO54  0xC
> +#define  VF_NET_PAD_DFT_GPIO55  0xC
> +#define  VF_NET_PAD_DFT_GPIO56  0xC
> +#define  VF_NET_PAD_DFT_GPIO57  0xC
> +#define  VF_NET_PAD_DFT_GPIO58  0xC
> +#define  VF_NET_PAD_DFT_GPIO59  0xC
> +#define  VF_NET_PAD_DFT_GPIO60  0xC
> +#define  VF_NET_PAD_DFT_GPIO61  0xC
> +#define  VF_NET_PAD_DFT_GPIO62  0xC
> +#define  VF_NET_PAD_DFT_GPIO63  0xC
> +#define  VF_NET_PAD_DFT_GPIO64  0xC
> +#define  VF_NET_PAD_DFT_GPIO65  0xC
> +#define  VF_NET_PAD_DFT_GPIO66  0xC
> +#define  VF_NET_PAD_DFT_GPIO67  0xC
> +#define  VF_NET_PAD_DFT_GPIO68  0xC
> +#define  VF_NET_PAD_DFT_GPIO69  0xC
> +#define  VF_NET_PAD_DFT_GPIO70  0xC
> +
> +//
> +// PCONF0
> +//
> +#define  VF_NET_PAD_CONF0_GPIO_SUS0  0xCCA8
> +#define  VF_NET_PAD_CONF0_GPIO_SUS1  0xCCA8
> +#define  VF_NET_PAD_CONF0_GPIO_SUS2  0xCCA8
> +#define  VF_NET_PAD_CONF0_GPIO_SUS3  0xCD28
> +#define  VF_NET_PAD_CONF0_GPIO_SUS4  0xCD28
> +#define  VF_NET_PAD_CONF0_GPIO_SUS5  0xCD28
> +#define  VF_NET_PAD_CONF0_GPIO_SUS6  0x8850
> +#define  VF_NET_PAD_CONF0_GPIO_SUS7  0x8850
> +#define  VF_NET_PAD_CONF0_GPIO_SUS8  0xCCA8
> +#define  VF_NET_PAD_CONF0_GPIO_SUS9  0xCCA8
> +#define  VF_NET_PAD_CONF0_GPIO_SUS10  0xCCA8
> +#define  VF_NET_PAD_CONF0_GPIO_SUS11  0xC828
> +#define  VF_NET_PAD_CONF0_GPIO_SUS12  0xC828
> +#define  VF_NET_PAD_CONF0_GPIO_SUS13  0xCCA8
> +#define  VF_NET_PAD_CONF0_GPIO_SUS14  0xCCA8
> +#define  VF_NET_PAD_CONF0_GPIO_SUS15  0x8C80
> +#define  VF_NET_PAD_CONF0_GPIO_SUS16  0xC828
> +
> +//
> +// PCONF1
> +//
> +#define  VF_NET_PAD_CONF1_GPIO_SUS0  0
> +#define  VF_NET_PAD_CONF1_GPIO_SUS1  0
> +#define  VF_NET_PAD_CONF1_GPIO_SUS2  0
> +#define  VF_NET_PAD_CONF1_GPIO_SUS3  0
> +#define  VF_NET_PAD_CONF1_GPIO_SUS4  0
> +#define  VF_NET_PAD_CONF1_GPIO_SUS5  0
> +#define  VF_NET_PAD_CONF1_GPIO_SUS6  0
> +#define  VF_NET_PAD_CONF1_GPIO_SUS7  0
> +#define  VF_NET_PAD_CONF1_GPIO_SUS8  0
> +#define  VF_NET_PAD_CONF1_GPIO_SUS9  0
> +#define  VF_NET_PAD_CONF1_GPIO_SUS10  0
> +#define  VF_NET_PAD_CONF1_GPIO_SUS11  0
> +#define  VF_NET_PAD_CONF1_GPIO_SUS12  0
> +#define  VF_NET_PAD_CONF1_GPIO_SUS13  0
> +#define  VF_NET_PAD_CONF1_GPIO_SUS14  0
> +#define  VF_NET_PAD_CONF1_GPIO_SUS15  0
> +#define  VF_NET_PAD_CONF1_GPIO_SUS16  0
> +
> +
> +#define  VF_NET_PAD_VAL_GPIO_SUS0  0
> +#define  VF_NET_PAD_VAL_GPIO_SUS1  0
> +#define  VF_NET_PAD_VAL_GPIO_SUS2  0
> +#define  VF_NET_PAD_VAL_GPIO_SUS3  0
> +#define  VF_NET_PAD_VAL_GPIO_SUS4  0
> +#define  VF_NET_PAD_VAL_GPIO_SUS5  0
> +#define  VF_NET_PAD_VAL_GPIO_SUS6  0
> +#define  VF_NET_PAD_VAL_GPIO_SUS7  0
> +#define  VF_NET_PAD_VAL_GPIO_SUS8  0
> +#define  VF_NET_PAD_VAL_GPIO_SUS9  0
> +#define  VF_NET_PAD_VAL_GPIO_SUS10  0
> +#define  VF_NET_PAD_VAL_GPIO_SUS11  0
> +#define  VF_NET_PAD_VAL_GPIO_SUS12  0
> +#define  VF_NET_PAD_VAL_GPIO_SUS13  0
> +#define  VF_NET_PAD_VAL_GPIO_SUS14  0
> +#define  VF_NET_PAD_VAL_GPIO_SUS15  0
> +#define  VF_NET_PAD_VAL_GPIO_SUS16  0
> +
> +
> +#define  VF_NET_PAD_DFT_GPIO_SUS0  0
> +#define  VF_NET_PAD_DFT_GPIO_SUS1  0
> +#define  VF_NET_PAD_DFT_GPIO_SUS2  0
> +#define  VF_NET_PAD_DFT_GPIO_SUS3  0
> +#define  VF_NET_PAD_DFT_GPIO_SUS4  0
> +#define  VF_NET_PAD_DFT_GPIO_SUS5  0
> +#define  VF_NET_PAD_DFT_GPIO_SUS6  0
> +#define  VF_NET_PAD_DFT_GPIO_SUS7  0
> +#define  VF_NET_PAD_DFT_GPIO_SUS8  0
> +#define  VF_NET_PAD_DFT_GPIO_SUS9  0
> +#define  VF_NET_PAD_DFT_GPIO_SUS10  0
> +#define  VF_NET_PAD_DFT_GPIO_SUS11  0
> +#define  VF_NET_PAD_DFT_GPIO_SUS12  0
> +#define  VF_NET_PAD_DFT_GPIO_SUS13  0
> +#define  VF_NET_PAD_DFT_GPIO_SUS14  0
> +#define  VF_NET_PAD_DFT_GPIO_SUS15  0
> +#define  VF_NET_PAD_DFT_GPIO_SUS16  0
> +
> +
> +//
> +// Function Prototypes
> +//
> +EFI_STATUS
> +PlatformPchInit (
> +  IN SYSTEM_CONFIGURATION        *SystemConfiguration,
> +  IN CONST EFI_PEI_SERVICES      **PeiServices,
> +  IN UINT16                      PlatformType
> +  );
> +
> +EFI_STATUS
> +PlatformCpuInit (
> +  IN CONST EFI_PEI_SERVICES            **PeiServices,
> +  IN SYSTEM_CONFIGURATION        *SystemConfiguration,
> +  IN EFI_PLATFORM_CPU_INFO       *PlatformCpuInfo
> +  );
> +
> +EFI_STATUS
> +PeimInitializeFlashMap (
> +  IN EFI_FFS_FILE_HEADER        *FfsHeader,
> +  IN CONST EFI_PEI_SERVICES           **PeiServices
> +  );
> +
> +EFI_STATUS
> +PeimInstallFlashMapPpi (
> +  IN EFI_FFS_FILE_HEADER        *FfsHeader,
> +  IN CONST EFI_PEI_SERVICES           **PeiServices
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +IchReset (
> +  IN CONST EFI_PEI_SERVICES           **PeiServices
> +  )
> +;
> +
> +BOOLEAN
> +GetSleepTypeAfterWakeup (
> +  IN  CONST EFI_PEI_SERVICES          **PeiServices,
> +  OUT UINT16                    *SleepType
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +GetWakeupEventAndSaveToHob (
> +  IN CONST EFI_PEI_SERVICES   **PeiServices
> +  )
> +;
> +
> +EFI_STATUS
> +EFIAPI
> +MemoryDiscoveredPpiNotifyCallback (
> +  IN CONST EFI_PEI_SERVICES           **PeiServices,
> +  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
> +  IN VOID                       *Ppi
> +  )
> +;
> +
> +EFI_STATUS
> +EFIAPI
> +PeiGetVariable (
> +  IN CONST EFI_PEI_SERVICES             **PeiServices,
> +  IN CHAR16                       *VariableName,
> +  IN EFI_GUID                     * VendorGuid,
> +  OUT UINT32                      *Attributes OPTIONAL,
> +  IN OUT UINTN                    *DataSize,
> +  OUT VOID                        *Data
> +  )
> +;
> +
> +EFI_STATUS
> +EFIAPI
> +PeiGetNextVariableName (
> +  IN CONST EFI_PEI_SERVICES             **PeiServices,
> +  IN OUT UINTN                    *VariableNameSize,
> +  IN OUT CHAR16                   *VariableName,
> +  IN OUT EFI_GUID                 *VendorGuid
> +  )
> +;
> +
> +EFI_STATUS
> +UpdateBootMode (
> +  IN CONST EFI_PEI_SERVICES                       **PeiServices,
> +  IN OUT EFI_PLATFORM_INFO_HOB                    *PlatformInfoHob
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +EndOfPeiPpiNotifyCallback (
> +  IN CONST EFI_PEI_SERVICES           **PeiServices,
> +  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
> +  IN VOID                       *Ppi
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +PeimInitializeRecovery (
> +  IN CONST EFI_PEI_SERVICES     **PeiServices
> +  )
> +;
> +
> +VOID
> +CheckPowerOffNow (
> +  VOID
> +  );
> +
> +VOID
> +IchGpioInit (
> +  IN UINT16                     PlatformType,
> +  IN SYSTEM_CONFIGURATION       *SystemConfiguration
> +  );
> +
> +EFI_STATUS
> +PcieSecondaryBusReset (
> +  IN CONST EFI_PEI_SERVICES  **PeiServices,
> +  IN UINT8             Bus,
> +  IN UINT8             Dev,
> +  IN UINT8             Fun
> +  );
> +
> +VOID
> +SetPlatformBootMode (
> +  IN CONST EFI_PEI_SERVICES             **PeiServices,
> +  IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
> +  );
> +
> +BOOLEAN
> +CheckIfJumperSetForRecovery(
> +  VOID
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +FindFv (
> +  IN EFI_PEI_FIND_FV_PPI              *This,
> +  IN CONST EFI_PEI_SERVICES             **PeiServices,
> +  IN OUT UINT8                    *FvNumber,
> +  OUT EFI_FIRMWARE_VOLUME_HEADER  **FVAddress
> +  );
> +
> +BOOLEAN
> +IsA16Inverted (
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +CpuOnlyReset (
> +  IN CONST EFI_PEI_SERVICES   **PeiServices
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +InitLan (
> +  IN CONST EFI_PEI_SERVICES          **PeiServices,
> +  IN SYSTEM_CONFIGURATION      *Buffer
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +Stall (
> +  IN CONST EFI_PEI_SERVICES     **PeiServices,
> +  IN CONST EFI_PEI_STALL_PPI    *This,
> +  IN UINTN                      Microseconds
> +  );
> +
> +EFI_STATUS
> +MultiPlatformInfoInit (
> +  IN CONST EFI_PEI_SERVICES          **PeiServices,
> +  IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
> +  );
> +
> +BOOLEAN
> +IsRecoveryJumper (
> +  IN CONST EFI_PEI_SERVICES    **PeiServices,
> +    IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
> +);
> +
> +EFI_STATUS
> +CheckOsSelection (
> +  IN CONST EFI_PEI_SERVICES          **PeiServices,
> +  IN SYSTEM_CONFIGURATION            *SystemConfiguration
> +  );
> +
> +EFI_STATUS
> +PlatformInfoUpdate (
> +  IN CONST EFI_PEI_SERVICES          **PeiServices,
> +  IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob,
> +  IN SYSTEM_CONFIGURATION      *SystemConfiguration
> +  );
> +
> +VOID
> +PlatformSsaInit (
> +IN SYSTEM_CONFIGURATION        *SystemConfiguration,
> +IN CONST EFI_PEI_SERVICES      **PeiServices
> +  );
> +
> +EFI_STATUS
> +InitializePlatform (
> +  IN CONST EFI_PEI_SERVICES             **PeiServices,
> +  IN EFI_PLATFORM_INFO_HOB        *PlatformInfoHob,
> +  IN SYSTEM_CONFIGURATION         *SystemConfiguration
> +);
> +
> +VOID
> +MchInit (
> +IN CONST EFI_PEI_SERVICES                     **PeiServices
> +  );
> +
> +
> +EFI_STATUS
> +EFIAPI
> +SetPeiCacheMode (
> +  IN  CONST EFI_PEI_SERVICES    **PeiServices
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +SetDxeCacheMode (
> +  IN  CONST EFI_PEI_SERVICES    **PeiServices
> +  );
> +
> +EFI_STATUS
> +GPIO_initialization (
> +  IN EFI_PEI_SERVICES                   **PeiServices,
> +  IN EFI_PEI_NOTIFY_DESCRIPTOR          *NotifyDescriptor,
> +  IN VOID                               *SmbusPpi
> +  );
> +
> +
> +BOOLEAN
> +IsRtcUipAlwaysSet (
> +  IN CONST EFI_PEI_SERVICES       **PeiServices
> +  );
> +
> +
> +
> +EFI_STATUS
> +InitPchUsb (
> +  IN CONST EFI_PEI_SERVICES  **PeiServices
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +PublishMemoryTypeInfo (
> +  void
> +  );
> +
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInfoInit.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInfoInit.c
> new file mode 100644
> index 0000000000..c6948d99d5
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInfoInit.c
> @@ -0,0 +1,181 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  PlatformInfoInit.c
> +
> +Abstract:
> +  Platform Info Driver.
> +
> +--*/
> +
> +#include "PlatformEarlyInit.h"
> +
> +#define LEN_64M       0x4000000
> +
> +//
> +// Default PCI32 resource size
> +//
> +#define RES_MEM32_MIN_LEN   0x38000000
> +
> +#define RES_IO_BASE   0x0D00
> +#define RES_IO_LIMIT  0xFFFF
> +
> +#define MemoryCeilingVariable   L"MemCeil."
> +
> +EFI_STATUS
> +CheckOsSelection (
> +  IN CONST EFI_PEI_SERVICES          **PeiServices,
> +  IN SYSTEM_CONFIGURATION            *SystemConfiguration
> +  )
> +{
> +  EFI_STATUS                   Status;
> +  EFI_PEI_READ_ONLY_VARIABLE2_PPI   *Variable;
> +  UINTN                        VariableSize;
> +  EFI_OS_SELECTION_HOB         *OsSelectionHob;
> +  UINT8                        OsSelection;
> +  UINT8                        *LpssDataHobPtr;
> +  UINT8                        *LpssDataVarPtr;
> +  UINTN                        i;
> +
> +  Status = (*PeiServices)->LocatePpi (
> +                             PeiServices,
> +                             &gEfiPeiReadOnlyVariable2PpiGuid,
> +                             0,
> +                             NULL,
> +                                      (void **)&Variable
> +                             );
> +  if (!EFI_ERROR(Status)) {
> +    VariableSize = sizeof (OsSelection);
> +    Status = Variable->GetVariable (
> +                         Variable,
> +                         L"OsSelection",
> +                         &gOsSelectionVariableGuid,
> +                         NULL,
> +                         &VariableSize,
> +                         &OsSelection
> +                         );
> +
> +    if (!EFI_ERROR(Status) && (SystemConfiguration->ReservedO !=
> OsSelection)) {
> +      //
> +      // Build HOB for OsSelection
> +      //
> +      OsSelectionHob = BuildGuidHob (&gOsSelectionVariableGuid, sizeof
> (EFI_OS_SELECTION_HOB));
> +      ASSERT (OsSelectionHob != NULL);
> +
> +      OsSelectionHob->OsSelectionChanged = TRUE;
> +      OsSelectionHob->OsSelection        = OsSelection;
> +      SystemConfiguration->ReservedO   = OsSelectionHob->OsSelection;
> +
> +      //
> +      // Load LPSS and SCC default configurations
> +      //
> +      OsSelectionHob->LpssData.LpsseMMCEnabled            = FALSE;
> +      OsSelectionHob->LpssData.LpssSdioEnabled            = TRUE;
> +      OsSelectionHob->LpssData.LpssSdcardEnabled          = TRUE;
> +      OsSelectionHob->LpssData.LpssSdCardSDR25Enabled     = FALSE;
> +      OsSelectionHob->LpssData.LpssSdCardDDR50Enabled     = TRUE;
> +      OsSelectionHob->LpssData.LpssMipiHsi                = FALSE;
> +      OsSelectionHob->LpssData.LpsseMMC45Enabled          = TRUE;
> +      OsSelectionHob->LpssData.LpsseMMC45DDR50Enabled     = TRUE;
> +      OsSelectionHob->LpssData.LpsseMMC45HS200Enabled     = FALSE;
> +      OsSelectionHob->LpssData.LpsseMMC45RetuneTimerValue = 8;
> +      OsSelectionHob->LpssData.eMMCBootMode               = 1;     // Auto
> Detect
> +
> +
> +      SystemConfiguration->Lpe       = OsSelectionHob->Lpe;
> +      SystemConfiguration->PchAzalia = SystemConfiguration->PchAzalia;
> +      LpssDataHobPtr = &OsSelectionHob->LpssData.LpssPciModeEnabled;
> +      LpssDataVarPtr = &SystemConfiguration->LpssPciModeEnabled;
> +
> +      for (i = 0; i < sizeof(EFI_PLATFORM_LPSS_DATA); i++) {
> +        *LpssDataVarPtr = *LpssDataHobPtr;
> +        LpssDataVarPtr++;
> +        LpssDataHobPtr++;
> +      }
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +PlatformInfoUpdate (
> +  IN CONST EFI_PEI_SERVICES          **PeiServices,
> +  IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob,
> +  IN SYSTEM_CONFIGURATION      *SystemConfiguration
> +  )
> +{
> +  EFI_STATUS                   Status;
> +  EFI_PEI_READ_ONLY_VARIABLE2_PPI   *Variable;
> +  UINTN                        VariableSize;
> +  UINT32                       MemoryCeiling;
> +
> +  //
> +  // Checking PCI32 resource from previous boot to determine the memory
> ceiling
> +  //
> +  Status = (*PeiServices)->LocatePpi (
> +                             PeiServices,
> +                             &gEfiPeiReadOnlyVariable2PpiGuid,
> +                             0,
> +                             NULL,
> +                                      (void **)&Variable
> +                             );
> +  if (!EFI_ERROR(Status)) {
> +    //
> +    // Get the memory ceiling
> +    //
> +    VariableSize = sizeof(MemoryCeiling);
> +    Status = Variable->GetVariable (
> +                         Variable,
> +                         MemoryCeilingVariable,
> +                         &gEfiGlobalVariableGuid,
> +                         NULL,
> +                         &VariableSize,
> +                         &MemoryCeiling
> +                         );
> +    if(!EFI_ERROR(Status)) {
> +      //
> +      // Set the new PCI32 resource Base if the variable available
> +      //
> +      PlatformInfoHob->PciData.PciResourceMem32Base = MemoryCeiling;
> +      PlatformInfoHob->MemData.MemMaxTolm = MemoryCeiling;
> +      PlatformInfoHob->MemData.MemTolm = MemoryCeiling;
> +
> +      //
> +      // Platform PCI MMIO Size in unit of 1MB
> +      //
> +      PlatformInfoHob->MemData.MmioSize = 0x1000 -
> (UINT16)(PlatformInfoHob->MemData.MemMaxTolm >> 20);
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Initialize the platform related info hob according to the
> +  pre-determine value or setup option
> +
> +  @retval EFI_SUCCESS    Memory initialization completed successfully.
> +  @retval Others         All other error conditions encountered result in an
> ASSERT.
> +**/
> +EFI_STATUS
> +InitializePlatform (
> +  IN CONST EFI_PEI_SERVICES       **PeiServices,
> +  IN EFI_PLATFORM_INFO_HOB        *PlatformInfoHob,
> +  IN SYSTEM_CONFIGURATION         *SystemConfiguration
> +)
> +{
> +//
> +// -- cchew10 need to update here.
> +//
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInitPei.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInitPei.inf
> new file mode 100644
> index 0000000000..54277b1e8b
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInitPei.inf
> @@ -0,0 +1,117 @@
> +#
> +#
> +# Copyright (c)  1999  - 2016, Intel Corporation. All rights reserved
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +#
> +#  Module Name:
> +#
> +#    PlatformEarlyInit.inf
> +#
> +#  Abstract:
> +#
> +#    Component description file for PlatformEarlyInit module
> +#
> +#--*/
> +
> +[defines]
> +INF_VERSION 				   = 0x00010005
> +BASE_NAME					   = PlatformEarlyInit
> +FILE_GUID					   = 0A5EA2E1-BE0B-44a0-
> A775-F429C9A018A0
> +MODULE_TYPE 				   = PEIM
> +VERSION_STRING				   = 1.0
> +PI_SPECIFICATION_VERSION	   = 0x0001000A
> +ENTRY_POINT 				   = PlatformEarlyInitEntry
> +
> +[sources.common]
> +  BootMode.c
> +  CpuInitPeim.c
> +  PchInitPeim.c
> +  MchInit.c
> +  MemoryCallback.c
> +  MemoryPeim.c
> +  PlatformEarlyInit.c
> +  PlatformEarlyInit.h
> +  PlatformInfoInit.c
> +  LegacySpeaker.c
> +  LegacySpeaker.h
> +  Stall.c
> +  PlatformSsaInitPeim.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  IntelFrameworkPkg/IntelFrameworkPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +  Vlv2SocBinPkg/Vlv2SocBinPkg.dec
> +  UefiCpuPkg/UefiCpuPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
> +
> +[LibraryClasses]
> +  PeimEntryPoint
> +  DebugLib
> +  HobLib
> +  IoLib
> +#  PeiKscLib
> +  MultiPlatformLib
> +  PcdLib
> +  PchPlatformLib
> +  MtrrLib
> +
> +[Ppis]
> +  gEfiPeiStallPpiGuid
> +  gPeiSpeakerInterfacePpiGuid
> +  gEfiPeiMemoryDiscoveredPpiGuid
> +  gVlvPolicyPpiGuid
> +  gEfiPeiReadOnlyVariable2PpiGuid
> +  gEfiPeiResetPpiGuid
> +  gEfiEndOfPeiSignalPpiGuid
> +  gPeiSmbusPolicyPpiGuid
> +  gEfiFindFvPpiGuid
> +  gPeiCapsulePpiGuid
> +  gEfiPeiBootInRecoveryModePpiGuid
> +  gEfiPeiRecoveryModulePpiGuid
> +  gEfiPeiDeviceRecoveryModulePpiGuid
> +  gPeiCachePpiGuid
> +  gEfiPeiMasterBootModePpiGuid
> +  gEfiPeiSmbusPpiGuid
> +  gPchInitPpiGuid
> +  gPchUsbPolicyPpiGuid
> +
> +[Guids]
> +  gEfiSetupVariableGuid
> +  gEfiPlatformInfoGuid
> +  gEfiPlatformBootModeGuid
> +  gEfiPlatformCpuInfoGuid
> +  gEfiGlobalVariableGuid
> +  gRecoveryOnFatFloppyDiskGuid
> +  gRecoveryOnFatUsbDiskGuid
> +  gRecoveryOnFatIdeDiskGuid
> +  gRecoveryOnDataCdGuid
> +  gMfgModeVariableGuid
> +  gEfiNormalSetupGuid
> +  gEfiMemoryTypeInformationGuid
> +  gOsSelectionVariableGuid
> +  gEfiSmmPeiSmramMemoryReserveGuid
> +
> +[Pcd.common]
> +  gPlatformModuleTokenSpaceGuid.PcdFlashFvMainBase
> +  gPlatformModuleTokenSpaceGuid.PcdFlashFvMainSize
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +  gEfiIchTokenSpaceGuid.PcdPeiIchEhciControllerMemoryBaseAddress
> +
> +  gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress
> +  gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize
> +  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Base
> +  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Size
> +
> +[Pcd]
> +  gEfiVLVTokenSpaceGuid.PcdMeasuredBootEnable
> +  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBootState
> +
> +[Depex]
> +  gEfiPeiReadOnlyVariable2PpiGuid  AND gPeiCachePpiGuid
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformSsaInitPeim.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformSsaInitPeim.c
> new file mode 100644
> index 0000000000..4ffa3a20a2
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformSsaInitPeim.c
> @@ -0,0 +1,58 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +  PlatformSsaInitPeim.c
> +
> +Abstract:
> +
> +
> +--*/
> +
> +#include "PlatformEarlyInit.h"
> +
> +/**
> +  Perform SSA related platform initialization.
> +
> +**/
> +VOID
> +PlatformSsaInit (
> +  IN SYSTEM_CONFIGURATION        *SystemConfiguration,
> +  IN CONST EFI_PEI_SERVICES          **PeiServices
> +  )
> +{
> +
> +  DEBUG ((EFI_D_ERROR, "PlatformSsaInit() - Start\n"));
> +  DEBUG ((EFI_D_ERROR, "PlatformSsaInit() - SystemConfiguration-
> >ISPDevSel 0x%x\n",SystemConfiguration->ISPDevSel));
> +  if(SystemConfiguration->ISPDevSel == 0x02)
> +  {
> +    //
> +    // Device 3 Interrupt Route
> +    //
> +    MmioWrite16 (
> +      (ILB_BASE_ADDRESS + R_PCH_ILB_D3IR),
> +      V_PCH_ILB_DXXIR_IAR_PIRQH   // For IUNIT
> +    );
> +    MmioRead16(ILB_BASE_ADDRESS + R_PCH_ILB_D3IR); // Read Posted
> Writes Register
> +    DEBUG ((EFI_D_ERROR, "PlatformSsaInit() - Device 3 Interrupt Route
> Done\n"));
> +  }
> +
> +  //
> +  // Device 2 Interrupt Route
> +  //
> +  MmioWrite16 (
> +    (ILB_BASE_ADDRESS + R_PCH_ILB_D2IR),
> +    V_PCH_ILB_DXXIR_IAR_PIRQA   // For IGD
> +  );
> +  MmioRead16(ILB_BASE_ADDRESS + R_PCH_ILB_D2IR); // Read Posted
> Writes Register
> +  DEBUG ((EFI_D_ERROR, "PlatformSsaInit() - Device 2 Interrupt Route
> Done\n"));
> +
> +  return;
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Recovery.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Recovery.c
> new file mode 100644
> index 0000000000..53cd2c6c0c
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Recovery.c
> @@ -0,0 +1,361 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +  Recovery.c
> +
> +Abstract:
> +
> +  Tiano PEIM to provide the platform recovery functionality.
> +
> +--*/
> +
> +#include "PlatformEarlyInit.h"
> +
> +#define PEI_FVMAIN_COMPACT_GUID \
> +  {0x4A538818, 0x5AE0, 0x4eb2, 0xB2, 0xEB, 0x48, 0x8b, 0x23, 0x65, 0x70,
> 0x22};
> +
> +EFI_GUID FvMainCompactFileGuid = PEI_FVMAIN_COMPACT_GUID;
> +
> +//
> +// Required Service
> +//
> +EFI_STATUS
> +EFIAPI
> +PlatformRecoveryModule (
> +  IN CONST EFI_PEI_SERVICES                       **PeiServices,
> +  IN EFI_PEI_RECOVERY_MODULE_PPI          *This
> +  );
> +
> +//
> +// Module globals
> +//
> +
> +typedef struct {
> +  EFI_GUID  CapsuleGuid;
> +  UINT32    HeaderSize;
> +  UINT32    Flags;
> +  UINT32    CapsuleImageSize;
> +  UINT32    SequenceNumber;
> +  EFI_GUID  InstanceId;
> +  UINT32    OffsetToSplitInformation;
> +  UINT32    OffsetToCapsuleBody;
> +  UINT32    OffsetToOemDefinedHeader;
> +  UINT32    OffsetToAuthorInformation;
> +  UINT32    OffsetToRevisionInformation;
> +  UINT32    OffsetToShortDescription;
> +  UINT32    OffsetToLongDescription;
> +  UINT32    OffsetToApplicableDevices;
> +} OLD_EFI_CAPSULE_HEADER;
> +
> +
> +static EFI_PEI_RECOVERY_MODULE_PPI mRecoveryPpi = {
> +  PlatformRecoveryModule
> +};
> +
> +static EFI_PEI_PPI_DESCRIPTOR mRecoveryPpiList = {
> +  (EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> +  &gEfiPeiRecoveryModulePpiGuid,
> +  &mRecoveryPpi
> +};
> +
> +/**
> +  Provide the functionality of the Recovery Module.
> +
> +  @param PeiServices  General purpose services available to every PEIM.
> +
> +  @retval Status      EFI_SUCCESS if the interface could be successfully
> +                      installed
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeimInitializeRecovery (
> +  IN CONST EFI_PEI_SERVICES     **PeiServices
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  Status = (*PeiServices)->InstallPpi (
> +                             PeiServices,
> +                             &mRecoveryPpiList
> +                             );
> +
> +  return Status;
> +}
> +
> +/**
> +  Provide the functionality of the Ea Recovery Module.
> +
> +  @param PeiServices         General purpose services available to every PEIM.
> +  @param This                Pointer to PEI_RECOVERY_MODULE_INTERFACE.
> +
> +  @retval EFI_SUCCESS        If the interface could be successfully
> +                             installed.
> +  @retval EFI_UNSUPPORTED    Not supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +PlatformRecoveryModule (
> +  IN CONST EFI_PEI_SERVICES               **PeiServices,
> +  IN EFI_PEI_RECOVERY_MODULE_PPI          *This
> +  )
> +{
> +  EFI_STATUS                            Status;
> +  EFI_PEI_DEVICE_RECOVERY_MODULE_PPI    *DeviceRecoveryModule;
> +  UINTN                                 NumberOfImageProviders;
> +  BOOLEAN                               ProviderAvailable;
> +  UINTN                                 NumberRecoveryCapsules;
> +  UINTN                                 RecoveryCapsuleSize;
> +  EFI_GUID                              DeviceId;
> +  BOOLEAN                               ImageFound;
> +  EFI_PHYSICAL_ADDRESS                  Address;
> +  VOID                                  *Buffer;
> +  OLD_EFI_CAPSULE_HEADER                *CapsuleHeader;
> +  EFI_PEI_HOB_POINTERS                  Hob;
> +  EFI_PEI_HOB_POINTERS                  HobOld;
> +  EFI_HOB_CAPSULE_VOLUME                *CapsuleHob;
> +  BOOLEAN                               HobUpdate;
> +  EFI_FIRMWARE_VOLUME_HEADER            *FvHeader;
> +  UINTN                                 Index;
> +  BOOLEAN                                FoundFvMain;
> +  BOOLEAN                                FoundCapsule;
> +  static EFI_GUID mEfiCapsuleHeaderGuid = EFI_CAPSULE_GUID;
> +  EFI_PEI_STALL_PPI                      *StallPpi;
> +
> +  (*PeiServices)->ReportStatusCode (
> +                    PeiServices,
> +                    EFI_PROGRESS_CODE,
> +                    EFI_SOFTWARE_PEI_MODULE |
> EFI_SW_PEIM_PC_RECOVERY_BEGIN,
> +                    0,
> +                    NULL,
> +                    NULL
> +                    );
> +
> +  Status = (**PeiServices).LocatePpi (
> +              PeiServices,
> +              &gEfiPeiStallPpiGuid,
> +              0,
> +              NULL,
> +              &StallPpi
> +              );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  StallPpi->Stall(
> +              PeiServices,
> +              StallPpi,
> +              5000000
> +              );
> +
> +
> +  Index = 0;
> +
> +  Status                  = EFI_SUCCESS;
> +  HobUpdate               = FALSE;
> +
> +  ProviderAvailable       = TRUE;
> +  ImageFound              = FALSE;
> +  NumberOfImageProviders  = 0;
> +
> +  DeviceRecoveryModule    = NULL;
> +
> +  FoundCapsule = FALSE;
> +  FoundFvMain = FALSE;
> +
> +  DEBUG ((EFI_D_ERROR | EFI_D_LOAD, "Recovery Entry\n"));
> +
> +  //
> +  // Search the platform for some recovery capsule if the DXE IPL
> +  // discovered a recovery condition and has requested a load.
> +  //
> +  while (ProviderAvailable == TRUE) {
> +
> +    Status = (*PeiServices)->LocatePpi (
> +                               PeiServices,
> +                               &gEfiPeiDeviceRecoveryModulePpiGuid,
> +                               Index,
> +                               NULL,
> +                               &DeviceRecoveryModule
> +                               );
> +
> +    if (!EFI_ERROR (Status)) {
> +      DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Device Recovery PPI located\n"));
> +      NumberOfImageProviders++;
> +
> +      Status = DeviceRecoveryModule->GetNumberRecoveryCapsules (
> +                                       (EFI_PEI_SERVICES**)PeiServices,
> +                                       DeviceRecoveryModule,
> +                                       &NumberRecoveryCapsules
> +                                       );
> +
> +      DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Number Of Recovery
> Capsules: %d\n", NumberRecoveryCapsules));
> +
> +      if (NumberRecoveryCapsules == 0) {
> +        Index++;
> +      } else {
> +        break;
> +      }
> +    } else {
> +      ProviderAvailable = FALSE;
> +    }
> +  }
> +
> +  //
> +  // If there is an image provider, get the capsule ID
> +  //
> +  if (ProviderAvailable) {
> +    RecoveryCapsuleSize = 0;
> +
> +    Status = DeviceRecoveryModule->GetRecoveryCapsuleInfo (
> +                                    (EFI_PEI_SERVICES**)PeiServices,
> +                                    DeviceRecoveryModule,
> +                                    0,
> +                                    &RecoveryCapsuleSize,
> +                                    &DeviceId
> +                                    );
> +
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +
> +    DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Recovery Capsule Size: %d\n",
> RecoveryCapsuleSize));
> +
> +    //
> +    // Only support the 2 capsule types known
> +    // Future enhancement is to rank-order the selection
> +    //
> +    if ((!CompareGuid (&DeviceId, &gRecoveryOnFatIdeDiskGuid)) &&
> +        (!CompareGuid (&DeviceId, &gRecoveryOnFatFloppyDiskGuid)) &&
> +        (!CompareGuid (&DeviceId, &gRecoveryOnDataCdGuid)) &&
> +       (!CompareGuid (&DeviceId, &gRecoveryOnFatUsbDiskGuid))
> +        ) {
> +      return EFI_UNSUPPORTED;
> +    }
> +
> +    Buffer  = NULL;
> +    Status = (*PeiServices)->AllocatePages (
> +                               PeiServices,
> +                               EfiBootServicesCode,
> +                               (RecoveryCapsuleSize - 1) / 0x1000 + 1,
> +                               &Address
> +                               );
> +
> +    DEBUG ((EFI_D_INFO | EFI_D_LOAD, "AllocatePage Returns: %r\n",
> Status));
> +
> +    if (EFI_ERROR(Status)) {
> +      return Status;
> +    }
> +
> +    Buffer = (UINT8 *) (UINTN) Address;
> +
> +    (*PeiServices)->ReportStatusCode (
> +                      PeiServices,
> +                      EFI_PROGRESS_CODE,
> +                      EFI_SOFTWARE_PEI_MODULE |
> EFI_SW_PEIM_PC_CAPSULE_LOAD,
> +                      0,
> +                      NULL,
> +                      NULL
> +                      );
> +
> +    Status = DeviceRecoveryModule->LoadRecoveryCapsule (
> +                                     (EFI_PEI_SERVICES**)PeiServices,
> +                                     DeviceRecoveryModule,
> +                                     0,
> +                                     Buffer
> +                                     );
> +
> +    DEBUG ((EFI_D_INFO | EFI_D_LOAD, "LoadRecoveryCapsule
> Returns: %r\n", Status));
> +
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +
> +    //
> +    // Update FV Hob if found
> +    //
> +    Status = (*PeiServices)->GetHobList (PeiServices, &Hob.Raw);
> +    HobOld.Raw  = Hob.Raw;
> +    while (!END_OF_HOB_LIST (Hob)) {
> +      if (Hob.Header->HobType == EFI_HOB_TYPE_FV) {
> +        DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Hob FV Length: %x\n",
> Hob.FirmwareVolume->Length));
> +        //
> +        // BUGBUG Why is it a FV hob if it is greater than 0x50000?
> +        //
> +        if (Hob.FirmwareVolume->Length > 0x50000) {
> +          HobUpdate = TRUE;
> +          //
> +          // This looks like the Hob we are interested in
> +          //
> +          DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Hob Updated\n"));
> +          Hob.FirmwareVolume->BaseAddress = (UINTN) Buffer;
> +          Hob.FirmwareVolume->Length      = RecoveryCapsuleSize;
> +        }
> +      }
> +      Hob.Raw = GET_NEXT_HOB (Hob);
> +    }
> +
> +    FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)Buffer;
> +    CapsuleHeader = (OLD_EFI_CAPSULE_HEADER *)Buffer;
> +
> +    //
> +    // Check if top of file is a capsule
> +    //
> +    if (CompareGuid ((EFI_GUID *)CapsuleHeader,
> &mEfiCapsuleHeaderGuid)) {
> +      FoundCapsule = TRUE;
> +    } else if (FvHeader->Signature == EFI_FVH_SIGNATURE) {
> +    	//
> +      // Assume the Firmware volume is a "FVMAIN" image
> +      //
> +      FoundFvMain = TRUE;
> +    }
> +
> +    if (FoundFvMain) {
> +      //
> +      // build FV Hob if it is not built before
> +      //
> +      if (!HobUpdate) {
> +        DEBUG ((EFI_D_INFO | EFI_D_LOAD, "FV Hob is not found, Build FV Hob
> then..\n"));
> +
> +       BuildFvHob (
> +         (UINTN)FvHeader,
> +         FvHeader->FvLength
> +          );
> +      }
> +    }
> +
> +    if (FoundCapsule) {
> +      //
> +      // Build capsule hob
> +      //
> +      Status = (*PeiServices)->CreateHob (
> +                                 PeiServices,
> +                                 EFI_HOB_TYPE_CV,
> +                                 sizeof (EFI_HOB_CAPSULE_VOLUME),
> +                                 &CapsuleHob
> +                                 );
> +      if (EFI_ERROR (Status)) {
> +        return Status;
> +      }
> +      CapsuleHob->BaseAddress = (UINT64)((UINTN)CapsuleHeader +
> (UINTN)CapsuleHeader->OffsetToCapsuleBody);
> +      CapsuleHob->Length = (UINT64)((UINTN)CapsuleHeader-
> >CapsuleImageSize -(UINTN)CapsuleHeader->OffsetToCapsuleBody);
> +      (*PeiServices)->ReportStatusCode (
> +                        PeiServices,
> +                        EFI_PROGRESS_CODE,
> +                        EFI_SOFTWARE_PEI_MODULE |
> EFI_SW_PEIM_PC_CAPSULE_START,
> +                        0,
> +                        NULL,
> +                        NULL
> +                        );
> +    }
> +  }
> +  DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Recovery Module Returning: %r\n",
> Status));
> +  return Status;
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Stall.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Stall.c
> new file mode 100644
> index 0000000000..d9c24c0194
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Stall.c
> @@ -0,0 +1,91 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +
> +Module Name:
> +
> +  Stall.c
> +
> +Abstract:
> +
> +  Produce Stall Ppi.
> +
> +--*/
> +
> +
> +#include "PlatformEarlyInit.h"
> +
> +
> +/**
> +
> +  Waits for at least the given number of microseconds.
> +
> +  @param PeiServices     General purpose services available to every PEIM.
> +  @param This            PPI instance structure.
> +  @param Microseconds    Desired length of time to wait.
> +
> +  @retval EFI_SUCCESS    If the desired amount of time was passed.
> +
> +*/
> +EFI_STATUS
> +EFIAPI
> +Stall (
> +  IN CONST EFI_PEI_SERVICES   **PeiServices,
> +  IN CONST EFI_PEI_STALL_PPI      *This,
> +  IN UINTN              Microseconds
> +  )
> +{
> +  UINTN   Ticks;
> +  UINTN   Counts;
> +  UINT32  CurrentTick;
> +  UINT32  OriginalTick;
> +  UINT32  RemainingTick;
> +
> +  if (Microseconds == 0) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  OriginalTick = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_TMR);
> +  OriginalTick &= (V_PCH_ACPI_PM1_TMR_MAX_VAL - 1);
> +  CurrentTick = OriginalTick;
> +
> +  //
> +  // The timer frequency is 3.579545MHz, so 1 ms corresponds to 3.58 clocks
> +  //
> +  Ticks = Microseconds * 358 / 100 + OriginalTick + 1;
> +
> +  //
> +  // The loops needed for timer overflow
> +  //
> +  Counts = (UINTN)RShiftU64((UINT64)Ticks, 24);
> +
> +  //
> +  // Remaining clocks within one loop
> +  //
> +  RemainingTick = Ticks & 0xFFFFFF;
> +
> +  //
> +  // Do not intend to use TMROF_STS bit of register PM1_STS, because this
> add extra
> +  // one I/O operation, and may generate SMI
> +  //
> +  while (Counts != 0) {
> +    CurrentTick = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_TMR)
> & B_PCH_ACPI_PM1_TMR_VAL;
> +    if (CurrentTick <= OriginalTick) {
> +      Counts--;
> +    }
> +    OriginalTick = CurrentTick;
> +  }
> +
> +  while ((RemainingTick > CurrentTick) && (OriginalTick <= CurrentTick)) {
> +    OriginalTick  = CurrentTick;
> +    CurrentTick   = IoRead32 (ACPI_BASE_ADDRESS +
> R_PCH_ACPI_PM1_TMR) & B_PCH_ACPI_PM1_TMR_VAL;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/BootMode.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/BootMode.c
> new file mode 100644
> index 0000000000..9fdcb620a3
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/BootMode.c
> @@ -0,0 +1,346 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2018, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +
> +  BootMode.c
> +
> +Abstract:
> +
> +  EFI PEIM to provide the platform support functionality on the Thurley.
> +
> +
> +--*/
> +#include "CommonHeader.h"
> +#include "Platform.h"
> +#include "PlatformBaseAddresses.h"
> +#include "PchAccess.h"
> +#include "PlatformBootMode.h"
> +#include <Guid/SetupVariable.h>
> +
> +//
> +// Priority of our boot modes, highest priority first
> +//
> +EFI_BOOT_MODE mBootModePriority[] = {
> +  BOOT_IN_RECOVERY_MODE,
> +  BOOT_WITH_DEFAULT_SETTINGS,
> +  BOOT_ON_FLASH_UPDATE,
> +  BOOT_ON_S2_RESUME,
> +  BOOT_ON_S3_RESUME,
> +  BOOT_ON_S4_RESUME,
> +  BOOT_WITH_MINIMAL_CONFIGURATION,
> +  BOOT_ASSUMING_NO_CONFIGURATION_CHANGES,
> +  BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS,
> +  BOOT_WITH_FULL_CONFIGURATION,
> +  BOOT_ON_S5_RESUME
> +};
> +
> +EFI_PEI_NOTIFY_DESCRIPTOR mCapsuleNotifyList[1] = {
> +  {
> +    (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> +    &gPeiCapsulePpiGuid,
> +    CapsulePpiNotifyCallback
> +  }
> +};
> +
> +BOOLEAN
> +GetSleepTypeAfterWakeup (
> +  IN  CONST EFI_PEI_SERVICES          **PeiServices,
> +  OUT UINT16                    *SleepType
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +CapsulePpiNotifyCallback (
> +  IN EFI_PEI_SERVICES           **PeiServices,
> +  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
> +  IN VOID                       *Ppi
> +  )
> +{
> +  EFI_STATUS      Status;
> +  EFI_BOOT_MODE   BootMode;
> +  PEI_CAPSULE_PPI *Capsule;
> +
> +  Status = (*PeiServices)->GetBootMode((const EFI_PEI_SERVICES
> **)PeiServices, &BootMode);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  if (BootMode == BOOT_ON_S3_RESUME) {
> +    //
> +    // Determine if we're in capsule update mode
> +    //
> +    Status = (*PeiServices)->LocatePpi ((const EFI_PEI_SERVICES
> **)PeiServices,
> +                                        &gPeiCapsulePpiGuid,
> +                                        0,
> +                                        NULL,
> +                                        (VOID **)&Capsule
> +                                        );
> +
> +    if (Status == EFI_SUCCESS) {
> +      if (Capsule->CheckCapsuleUpdate ((EFI_PEI_SERVICES**)PeiServices)
> == EFI_SUCCESS) {
> +        BootMode = BOOT_ON_FLASH_UPDATE;
> +        Status = (*PeiServices)->SetBootMode((const EFI_PEI_SERVICES
> **)PeiServices, BootMode);
> +        ASSERT_EFI_ERROR (Status);
> +      }
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +#ifdef NOCS_S3_SUPPORT
> +EFI_STATUS
> +UpdateBootMode (
> +  IN CONST EFI_PEI_SERVICES     **PeiServices
> +  )
> +{
> +  EFI_STATUS      Status;
> +  EFI_BOOT_MODE   BootMode;
> +  UINT16          SleepType;
> +  CHAR16          *strBootMode;
> +
> +  Status = (*PeiServices)->GetBootMode(PeiServices, &BootMode);
> +  ASSERT_EFI_ERROR (Status);
> +  if (BootMode  == BOOT_IN_RECOVERY_MODE){
> +    return Status;
> +  }
> +
> +  //
> +  // Let's assume things are OK if not told otherwise
> +  //
> +  BootMode = BOOT_WITH_FULL_CONFIGURATION;
> +
> +  if (GetSleepTypeAfterWakeup (PeiServices, &SleepType)) {
> +    switch (SleepType) {
> +      case V_PCH_ACPI_PM1_CNT_S3:
> +        BootMode = BOOT_ON_S3_RESUME;
> +        Status = (*PeiServices)->NotifyPpi (PeiServices,
> &mCapsuleNotifyList[0]);
> +        ASSERT_EFI_ERROR (Status);
> +        break;
> +
> +      case V_PCH_ACPI_PM1_CNT_S4:
> +        BootMode = BOOT_ON_S4_RESUME;
> +        break;
> +
> +      case V_PCH_ACPI_PM1_CNT_S5:
> +        BootMode = BOOT_ON_S5_RESUME;
> +        break;
> +    } // switch (SleepType)
> +  }
> +
> +  if (IsFastBootEnabled (PeiServices)) {
> +    DEBUG ((EFI_D_INFO, "Prioritizing Boot mode to
> BOOT_WITH_MINIMAL_CONFIGURATION\n"));
> +    PrioritizeBootMode (&BootMode,
> BOOT_WITH_MINIMAL_CONFIGURATION);
> +  }
> +
> +  switch (BootMode) {
> +    case BOOT_WITH_FULL_CONFIGURATION:
> +      strBootMode = L"BOOT_WITH_FULL_CONFIGURATION";
> +      break;
> +    case BOOT_WITH_MINIMAL_CONFIGURATION:
> +      strBootMode = L"BOOT_WITH_MINIMAL_CONFIGURATION";
> +      break;
> +    case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
> +      strBootMode = L"BOOT_ASSUMING_NO_CONFIGURATION_CHANGES";
> +      break;
> +    case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:
> +      strBootMode =
> L"BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS";
> +      break;
> +    case BOOT_WITH_DEFAULT_SETTINGS:
> +      strBootMode = L"BOOT_WITH_DEFAULT_SETTINGS";
> +      break;
> +    case BOOT_ON_S4_RESUME:
> +      strBootMode = L"BOOT_ON_S4_RESUME";
> +      break;
> +    case BOOT_ON_S5_RESUME:
> +      strBootMode = L"BOOT_ON_S5_RESUME";
> +      break;
> +    case BOOT_ON_S2_RESUME:
> +      strBootMode = L"BOOT_ON_S2_RESUME";
> +      break;
> +    case BOOT_ON_S3_RESUME:
> +      strBootMode = L"BOOT_ON_S3_RESUME";
> +
> +      break;
> +    case BOOT_ON_FLASH_UPDATE:
> +      strBootMode = L"BOOT_ON_FLASH_UPDATE";
> +      break;
> +    case BOOT_IN_RECOVERY_MODE:
> +      strBootMode = L"BOOT_IN_RECOVERY_MODE";
> +      break;
> +    default:
> +      strBootMode = L"Unknown boot mode";
> +  } // switch (BootMode)
> +
> +  DEBUG ((EFI_D_ERROR, "Setting BootMode to %s\n", strBootMode));
> +  Status = (*PeiServices)->SetBootMode(PeiServices, BootMode);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +#endif
> +
> +/**
> +  Get sleep type after wakeup
> +
> +  @param PeiServices       Pointer to the PEI Service Table.
> +  @param SleepType         Sleep type to be returned.
> +
> +  @retval TRUE              A wake event occured without power failure.
> +  @retval FALSE             Power failure occured or not a wakeup.
> +
> +**/
> +BOOLEAN
> +GetSleepTypeAfterWakeup (
> +  IN  CONST EFI_PEI_SERVICES          **PeiServices,
> +  OUT UINT16                    *SleepType
> +  )
> +{
> +  UINT16  Pm1Sts;
> +  UINT16  Pm1Cnt;
> +  UINT16  GenPmCon1;
> +  //
> +  // VLV BIOS Specification 0.6.2 - Section 18.4, "Power Failure
> Consideration"
> +  //
> +  // When the SUS_PWR_FLR bit is set, it indicates the SUS well power is lost.
> +  // This bit is in the SUS Well and defaults to 1�b1 based on RSMRST#
> assertion (not cleared by any type of reset).
> +  // System BIOS should follow cold boot path if SUS_PWR_FLR (PBASE +
> 0x20[14]),
> +  // GEN_RST_STS (PBASE + 0x20[9]) or PWRBTNOR_STS (ABASE + 0x00[11])
> is set to 1�b1
> +  // regardless of the value in the SLP_TYP (ABASE + 0x04[12:10]) field.
> +  //
> +  GenPmCon1 = MmioRead16 (PMC_BASE_ADDRESS +
> R_PCH_PMC_GEN_PMCON_1);
> +
> +  //
> +  // Read the ACPI registers
> +  //
> +  Pm1Sts  = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS);
> +  Pm1Cnt  = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT);
> +
> +  if ((GenPmCon1 & (B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR |
> B_PCH_PMC_GEN_PMCON_GEN_RST_STS)) ||
> +     (Pm1Sts & B_PCH_ACPI_PM1_STS_PRBTNOR)) {
> +	  //
> +    // If power failure indicator, then don't attempt s3 resume.
> +    // Clear PM1_CNT of S3 and set it to S5 as we just had a power failure, and
> memory has
> +    // lost already.  This is to make sure no one will use PM1_CNT to check for
> S3 after
> +    // power failure.
> +	  //
> +    if ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) ==
> V_PCH_ACPI_PM1_CNT_S3) {
> +      Pm1Cnt = ((Pm1Cnt & ~B_PCH_ACPI_PM1_CNT_SLP_TYP) |
> V_PCH_ACPI_PM1_CNT_S5);
> +      IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT, Pm1Cnt);
> +    }
> +	  //
> +    // Clear Wake Status (WAK_STS)
> +    //
> +  }
> +  //
> +  // Get sleep type if a wake event occurred and there is no power failure
> +  //
> +  if ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) ==
> V_PCH_ACPI_PM1_CNT_S3) {
> +    *SleepType = Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP;
> +    return TRUE;
> +  } else if ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) ==
> V_PCH_ACPI_PM1_CNT_S4) {
> +    *SleepType = Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP;
> +    return TRUE;
> +  }
> +  return FALSE;
> +}
> +
> +BOOLEAN
> +EFIAPI
> +IsFastBootEnabled (
> +  IN CONST EFI_PEI_SERVICES           **PeiServices
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  EFI_PEI_READ_ONLY_VARIABLE2_PPI *PeiReadOnlyVarPpi;
> +  UINTN                           VarSize;
> +  SYSTEM_CONFIGURATION            SystemConfiguration;
> +  BOOLEAN                         FastBootEnabledStatus;
> +
> +  FastBootEnabledStatus = FALSE;
> +  Status = (**PeiServices).LocatePpi (
> +                             PeiServices,
> +                             &gEfiPeiReadOnlyVariable2PpiGuid,
> +                             0,
> +                             NULL,
> +                             (void **)&PeiReadOnlyVarPpi
> +                             );
> +  if (Status == EFI_SUCCESS) {
> +    VarSize = sizeof (SYSTEM_CONFIGURATION);
> +    Status = PeiReadOnlyVarPpi->GetVariable (
> +                                  PeiReadOnlyVarPpi,
> +                                  PLATFORM_SETUP_VARIABLE_NAME,
> +                                  &gEfiSetupVariableGuid,
> +                                  NULL,
> +                                  &VarSize,
> +                                  &SystemConfiguration
> +                                  );
> +    if (Status == EFI_SUCCESS) {
> +      if (SystemConfiguration.FastBoot != 0) {
> +        FastBootEnabledStatus = TRUE;
> +      }
> +    }
> +  }
> +
> +  return FastBootEnabledStatus;
> +}
> +
> +/**
> +  Given the current boot mode, and a proposed new boot mode, determine
> +  which has priority. If the new boot mode has higher priority, then
> +  make it the current boot mode.
> +
> +  @param CurrentBootMode    pointer to current planned boot mode
> +  @param NewBootMode        proposed boot mode
> +
> +  @retval EFI_NOT_FOUND      if either boot mode is not recognized
> +  @retval EFI_SUCCESS        if both boot mode values were recognized and
> +                             were processed.
> +**/
> +EFI_STATUS
> +PrioritizeBootMode (
> +  IN OUT EFI_BOOT_MODE    *CurrentBootMode,
> +  IN EFI_BOOT_MODE        NewBootMode
> +  )
> +{
> +  UINT32 CurrentIndex;
> +  UINT32 NewIndex;
> +
> +  //
> +  // Find the position of the current boot mode in our priority array
> +  //
> +  for ( CurrentIndex = 0;
> +        CurrentIndex < ARRAY_SIZE (mBootModePriority);
> +        CurrentIndex++) {
> +    if (mBootModePriority[CurrentIndex] == *CurrentBootMode) {
> +      break;
> +    }
> +  }
> +  if (CurrentIndex >= ARRAY_SIZE (mBootModePriority)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  //
> +  // Find the position of the new boot mode in our priority array
> +  //
> +  for ( NewIndex = 0;
> +        NewIndex < ARRAY_SIZE (mBootModePriority);
> +        NewIndex++) {
> +    if (mBootModePriority[NewIndex] == NewBootMode) {
> +      //
> +      // If this new boot mode occurs before the current boot mode in the
> +      // priority array, then take it.
> +      //
> +      if (NewIndex < CurrentIndex) {
> +        *CurrentBootMode = NewBootMode;
> +      }
> +      return EFI_SUCCESS;
> +    }
> +  }
> +  return EFI_NOT_FOUND;
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/CommonHeader.h
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/CommonHeader.h
> new file mode 100644
> index 0000000000..283993b44c
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/CommonHeader.h
> @@ -0,0 +1,60 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +**/
> +
> +#ifndef __COMMON_HEADER_H_
> +#define __COMMON_HEADER_H_
> +
> +
> +
> +#include <FrameworkPei.h>
> +
> +#include <IndustryStandard/SmBus.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <Ppi/AtaController.h>
> +#include <Guid/Capsule.h>
> +#include <Ppi/Cache.h>
> +#include <Ppi/MasterBootMode.h>
> +#include <Guid/MemoryTypeInformation.h>
> +#include <Guid/RecoveryDevice.h>
> +#include <Ppi/ReadOnlyVariable2.h>
> +#include <Ppi/FvLoadFile.h>
> +#include <Ppi/DeviceRecoveryModule.h>
> +#include <Ppi/Capsule.h>
> +#include <Ppi/Reset.h>
> +#include <Ppi/Stall.h>
> +#include <Ppi/BootInRecoveryMode.h>
> +#include <Guid/FirmwareFileSystem2.h>
> +#include <Ppi/MemoryDiscovered.h>
> +#include <Ppi/RecoveryModule.h>
> +#include <Ppi/Smbus2.h>
> +#include <Ppi/FirmwareVolumeInfo.h>
> +#include <Ppi/EndOfPeiPhase.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PeimEntryPoint.h>
> +#include <Library/BaseLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PciCf8Lib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/ReportStatusCodeLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/SmbusLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/ResetSystemLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PerformanceLib.h>
> +#include <Library/CacheMaintenanceLib.h>
> +#include <Library/MtrrLib.h>
> +
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/MemoryCallback.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/MemoryCallback.c
> new file mode 100644
> index 0000000000..7dcc2c3ce9
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/MemoryCallback.c
> @@ -0,0 +1,154 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +  This file includes a memory call back function notified when MRC is done,
> +  following action is performed in this file,
> +    1. ICH initialization after MRC.
> +    2. SIO initialization.
> +    3. Install ResetSystem and FinvFv PPI.
> +    4. Set MTRR for PEI
> +    5. Create FV HOB and Flash HOB
> +
> +
> +**/
> +
> +
> +#include "CommonHeader.h"
> +#include "Platform.h"
> +#include <Ppi/Cache.h>
> +#include <Library/BaseCryptLib.h>
> +#include <Library/PciLib.h>
> +#include "VlvAccess.h"
> +
> +
> +EFI_PEI_PPI_DESCRIPTOR  mPpiListRecoveryBootMode[] = {
> +{ (EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> +  &gEfiPeiBootInRecoveryModePpiGuid,
> +  NULL
> +}
> +};
> +
> +#if 0
> +STATIC
> +EFI_STATUS
> +GetMemorySize (
> +  IN  CONST EFI_PEI_SERVICES    **PeiServices,
> +  OUT UINT64              *LowMemoryLength,
> +  OUT UINT64              *HighMemoryLength
> +  )
> +{
> +  EFI_STATUS              Status;
> +  EFI_PEI_HOB_POINTERS    Hob;
> +
> +  *HighMemoryLength = 0;
> +  *LowMemoryLength = 0x100000;
> +  //
> +  // Get the HOB list for processing
> +  //
> +  Status = (*PeiServices)->GetHobList (PeiServices, (void **)&Hob.Raw);
> +  if (EFI_ERROR(Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Collect memory ranges
> +  //
> +  while (!END_OF_HOB_LIST (Hob)) {
> +    if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
> +      if (Hob.ResourceDescriptor->ResourceType ==
> EFI_RESOURCE_SYSTEM_MEMORY) {
> +        //
> +        // Need memory above 1MB to be collected here
> +        //
> +        if (Hob.ResourceDescriptor->PhysicalStart >= 0x100000 &&
> +            Hob.ResourceDescriptor->PhysicalStart < (EFI_PHYSICAL_ADDRESS)
> 0x100000000) {
> +          *LowMemoryLength += (UINT64) (Hob.ResourceDescriptor-
> >ResourceLength);
> +        } else if (Hob.ResourceDescriptor->PhysicalStart >=
> (EFI_PHYSICAL_ADDRESS) 0x100000000) {
> +          *HighMemoryLength += (UINT64) (Hob.ResourceDescriptor-
> >ResourceLength);
> +        }
> +      }
> +    }
> +    Hob.Raw = GET_NEXT_HOB (Hob);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +#endif
> +/**
> +  This function will be called when MRC is done.
> +
> +  @param  PeiServices General purpose services available to every PEIM.
> +  @param  NotifyDescriptor Information about the notify event..
> +  @param  Ppi The notify context.
> +
> +  @retval EFI_SUCCESS If the function completed successfully.
> +**/
> +EFI_STATUS
> +EFIAPI
> +MemoryDiscoveredPpiNotifyCallback (
> +  IN EFI_PEI_SERVICES           **PeiServices,
> +  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
> +  IN VOID                       *Ppi
> +  )
> +{
> +
> +  EFI_BOOT_MODE    BootMode;
> +  UINT32           Pages;
> +  VOID*            Memory;
> +  UINTN            Size;
> +
> +  //
> +  // Allocate LM memory and configure PDM if enabled by user.
> +  // ConfigureLM(PeiServices);
> +  //
> +  (*PeiServices)->GetBootMode (
> +                    (const EFI_PEI_SERVICES **)PeiServices,
> +                    &BootMode
> +                    );
> +
> +  if (BootMode != BOOT_ON_S3_RESUME) {
> +    Size = (PcdGet32 (PcdFlashFvRecovery2Base) - PcdGet32
> (PcdFlashFvMainBase)) + FixedPcdGet32(PcdFlashFvRecovery2Size);
> +    Pages=  Size/0x1000;
> +
> +    Memory = AllocatePages ( Pages );
> +    CopyMem(Memory , (VOID *) FixedPcdGet32(PcdFlashFvMainBase) ,
> Size);
> +
> +    //
> +    // We don't verify just load
> +    //
> +    PeiServicesInstallFvInfoPpi (
> +      NULL,
> +      (VOID *) ((UINTN) Memory + (PcdGet32 (PcdFlashFvRecovery2Base) -
> PcdGet32 (PcdFlashFvMainBase))),
> +      PcdGet32 (PcdFlashFvRecovery2Size),
> +      NULL,
> +      NULL
> +      );
> +
> +    PeiServicesInstallFvInfoPpi (
> +      NULL,
> +      (VOID *)  Memory,
> +      PcdGet32 (PcdFlashFvMainSize),
> +      NULL,
> +      NULL
> +      );
> +
> +  }
> +
> +  if (BootMode == BOOT_ON_S3_RESUME) {
> +    PeiServicesInstallFvInfoPpi (
> +    NULL,
> +    (VOID *) (UINTN) (PcdGet32 (PcdFlashFvRecovery2Base)),
> +    PcdGet32 (PcdFlashFvRecovery2Size),
> +    NULL,
> +    NULL
> +    );
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.c
> new file mode 100644
> index 0000000000..eba1dfff30
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.c
> @@ -0,0 +1,1198 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +**/
> +
> +#include "CommonHeader.h"
> +
> +#include "Platform.h"
> +#include <Library/PciCf8Lib.h>
> +#include "PlatformBaseAddresses.h"
> +#include "PchAccess.h"
> +#include <Guid/PlatformInfo.h>
> +#include "PchCommonDefinitions.h"
> +#include <Ppi/MfgMemoryTest.h>
> +#include <Guid/SetupVariable.h>
> +#include <Guid/Vlv2Variable.h>
> +#include <Ppi/fTPMPolicy.h>
> +
> +//
> +// Start::Alpine Valley platform
> +//
> +enum {
> +  SMBUS_READ_BYTE,
> +  SMBUS_WRITE_BYTE,
> +  SMBUS_READ_BLOCK,
> +  SMBUS_WRITE_BLOCK
> +};
> +
> +#define EC_BASE           0xE0000000
> +
> +//
> +// DEVICE 0 (Memroy Controller Hub)
> +//
> +#define MC_BUS              0x00
> +#define MC_DEV              0x00
> +#define MC_FUN              0x00
> +#define MC_DEV_FUN          (MC_DEV << 3)
> +#define MC_BUS_DEV_FUN      ((MC_BUS << 8) + MC_DEV_FUN)
> +
> +//
> +// SysCtl SMBus address and block size
> +//
> +#define AV_SC_SMBUS_ADDRESS        	0x60
> +#define AV_SC_BYTE_LEN            	1
> +#define AV_SC_BLOCK_LEN            	4
> +#define AV_SC_SMBUS_WRCMD           1
> +#define AV_SC_SMBUS_RDCMD           0
> +
> +//
> +// SysCtl registers offset
> +//
> +#define AV_SC_REG_PLATFORM_ID               24  // 0x18
> +#define AV_SC_REG_BOARD_ID                  28  // 0x1C
> +#define AV_SC_REG_FAB_ID                    32  // 0x20
> +#define AV_SC_REG_ECO_ID                    68  // 0x44
> +#define AV_SC_REG_DDR_DAUGHTER_CARD_ID      144 // 0x90
> +#define AV_SC_REG_SODIMM_CONFIG             36
> +
> +//
> +// ID values
> +//
> +#define AV_SC_PLATFORM_ID_TABLET   0
> +#define AV_SC_PLATFORM_ID_NETBOOK  2
> +#define AV_SC_PLATFORM_ID_INTERPOSER 3 // Configuration TBD
> +#define AV_SC_BOARD_ID_AV_SVP      1492
> +
> +#define BUS_TRIES                 3       // How many times to retry on Bus Errors
> +
> +#define GTT_SIZE_1MB        1
> +#define GTT_SIZE_2MB        2
> +
> +#define PciCfg16Read( PciExpressBase, Bus, Device, Function, Register ) \
> +  MmioRead16(PciExpressBase + \
> +    (UINTN)(Bus << 20) + \
> +    (UINTN)(Device << 15) + \
> +    (UINTN)(Function << 12) + \
> +    (UINTN)(Register))
> +#define PciCfg16Write( PciExpressBase, Bus, Device, Function, Register,
> Data ) \
> +    MmioWrite16(PciExpressBase + \
> +      (UINTN)(Bus << 20) + \
> +      (UINTN)(Device << 15) + \
> +      (UINTN)(Function << 12) + \
> +      (UINTN)(Register), \
> +      (UINT16)Data)
> +
> +
> +//
> +//Memory Test Manufacturing mode
> +//
> +UINT32 DataPatternForMemoryTest[] = {
> +    0x55555555, 0xAAAAAAAA, 0x55555510, 0x555555EF, 0x55555510,
> 0x555555EF, 0x55555510, 0x555555EF,
> +    0x55555555, 0xAAAAAAAA, 0x55551055, 0x5555EF55, 0x55551055,
> 0x5555EF55, 0x55551055, 0x5555EF55,
> +    0x55555555, 0xAAAAAAAA, 0x55105555, 0x55EF5555, 0x55105555,
> 0x55EF5555, 0x55105555, 0x55EF5555,
> +    0x55555555, 0xAAAAAAAA, 0x10555555, 0xEF555555, 0x10555555,
> 0xEF555555, 0x10555555, 0xEF555555
> +};
> +#define DATA_PATTERN_ARRAY_SIZE (sizeof(DataPatternForMemoryTest)
> / sizeof(UINT32))
> +
> +//
> +//Memory Test Manufacturing mode
> +//
> +//
> +// The global indicator, the FvFileLoader callback will modify it to TRUE after
> loading PEIM into memory
> +//
> +BOOLEAN ImageInMemory = FALSE;
> +
> +EFI_STATUS
> +EFIAPI
> +Stall (
> +  IN CONST EFI_PEI_SERVICES   **PeiServices,
> +  IN CONST EFI_PEI_STALL_PPI      *This,
> +  IN UINTN              Microseconds
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +MfgMemoryTest (
> +  IN  CONST EFI_PEI_SERVICES                   **PeiServices,
> +  IN  PEI_MFG_MEMORY_TEST_PPI           *This,
> +  IN  UINT32                             BeginAddress,
> +  IN  UINT32                             MemoryLength
> +  );
> +
> +static EFI_PEI_STALL_PPI  mStallPpi = {
> +  PEI_STALL_RESOLUTION,
> +  Stall
> +};
> +
> +static PEI_MFG_MEMORY_TEST_PPI mPeiMfgMemoryTestPpi = {
> +  MfgMemoryTest
> +};
> +
> +static EFI_PEI_PPI_DESCRIPTOR mInstallStallPpi[] = {
> +  {
> +  EFI_PEI_PPI_DESCRIPTOR_PPI,
> +  &gEfiPeiStallPpiGuid,
> +  &mStallPpi
> +  },
> +  {
> +    EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
> +    &gPeiMfgMemoryTestPpiGuid,
> +    &mPeiMfgMemoryTestPpi
> +  }
> + };
> +
> +EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList[1] = {
> +  {
> +    (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> +    &gEfiPeiMemoryDiscoveredPpiGuid,
> +    MemoryDiscoveredPpiNotifyCallback
> +  }
> +};
> +
> +EFI_STATUS
> +EFIAPI
> +InstallMonoStatusCode (
> +  IN EFI_FFS_FILE_HEADER       *FfsHeader,
> +  IN CONST EFI_PEI_SERVICES          **PeiServices
> +  );
> +
> +
> +EFI_STATUS
> +ReadPlatformIds (
> +  IN CONST EFI_PEI_SERVICES             **PeiServices,
> +  IN OUT EFI_PLATFORM_INFO_HOB          *PlatformInfoHob
> +  );
> +
> +//
> +// Start::Alpine Valley platform
> +//
> +EFI_STATUS
> +PeiSmbusExec (
> +  UINT16 SmbusBase,
> +  UINT8 SlvAddr,
> +  UINT8 Operation,
> +  UINT8 Offset,
> +  UINT8 *Length,
> +  UINT8 *Buffer
> +  );
> +
> +
> +/**
> +
> +  Detemine Turbot board
> +  @return 0: Not Turbot board
> +          1: Turbot board
> +
> +**/
> +UINT32
> +DetermineTurbotBoard (
> +  void
> +  )
> +{
> +  UINTN PciD31F0RegBase = 0;
> +  UINT32 GpioValue = 0;
> +  UINT32 TmpVal = 0;
> +  UINT32 MmioConf0 = 0;
> +  UINT32 MmioPadval = 0;
> +  UINT32 PConf0Offset = 0x200; //GPIO_S5_4 pad_conf0 register offset
> +  UINT32 PValueOffset = 0x208; //GPIO_S5_4 pad_value register offset
> +  UINT32 SSUSOffset = 0x2000;
> +  UINT32 IoBase = 0;
> +
> +  DEBUG ((EFI_D_ERROR, "DetermineTurbotBoard() Entry\n"));
> +  PciD31F0RegBase = MmPciAddress (0,
> +                      0,
> +                      PCI_DEVICE_NUMBER_PCH_LPC,
> +                      PCI_FUNCTION_NUMBER_PCH_LPC,
> +                      0
> +                    );
> +  IoBase = MmioRead32 (PciD31F0RegBase + R_PCH_LPC_IO_BASE) &
> B_PCH_LPC_IO_BASE_BAR;
> +
> +  MmioConf0 = IoBase + SSUSOffset + PConf0Offset;
> +  MmioPadval = IoBase + SSUSOffset + PValueOffset;
> +  //0xFED0E200/0xFED0E208 is pad_Conf/pad_val register address of
> GPIO_S5_4
> +  DEBUG ((EFI_D_ERROR, "MmioConf0[0x%x], MmioPadval[0x%x]\n",
> MmioConf0, MmioPadval));
> +
> +  MmioWrite32 (MmioConf0, 0x2003CC00);
> +
> +  TmpVal = MmioRead32 (MmioPadval);
> +  TmpVal &= ~0x6; //Clear bit 1:2
> +  TmpVal |= 0x2; // Set the pin as GPI
> +  MmioWrite32 (MmioPadval, TmpVal);
> +
> +  GpioValue = MmioRead32 (MmioPadval);
> +
> +  DEBUG ((EFI_D_ERROR, "Gpio_S5_4 value is 0x%x\n", GpioValue));
> +  return (GpioValue & 0x1);
> +}
> +
> +
> +
> +EFI_STATUS
> +FtpmPolicyInit (
> +  IN CONST EFI_PEI_SERVICES             **PeiServices,
> +  IN SYSTEM_CONFIGURATION         *pSystemConfiguration
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  EFI_PEI_PPI_DESCRIPTOR          *mFtpmPolicyPpiDesc;
> +  SEC_FTPM_POLICY_PPI             *mFtpmPolicyPpi;
> +
> +
> +  DEBUG((EFI_D_INFO, "FtpmPolicyInit Entry \n"));
> +
> +  if (NULL == PeiServices ||  NULL == pSystemConfiguration) {
> +    DEBUG((EFI_D_ERROR, "Input error. \n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Status = (*PeiServices)->AllocatePool(
> +                             PeiServices,
> +                             sizeof (EFI_PEI_PPI_DESCRIPTOR),
> +                             (void **)&mFtpmPolicyPpiDesc
> +                             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = (*PeiServices)->AllocatePool(
> +                             PeiServices,
> +                             sizeof (SEC_FTPM_POLICY_PPI),
> +                             (void **)&mFtpmPolicyPpi
> +                             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Initialize PPI
> +  //
> +  (*PeiServices)->SetMem ((VOID *)mFtpmPolicyPpi, sizeof
> (SEC_FTPM_POLICY_PPI), 0);
> +  mFtpmPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
> +  mFtpmPolicyPpiDesc->Guid = &gSeCfTPMPolicyPpiGuid;
> +  mFtpmPolicyPpiDesc->Ppi = mFtpmPolicyPpi;
> +
> +
> +  DEBUG((EFI_D_INFO, "pSystemConfiguration->fTPM = 0x%x \n",
> pSystemConfiguration->fTPM));
> +  if(pSystemConfiguration->fTPM == 1) {
> +    mFtpmPolicyPpi->fTPMEnable = TRUE;
> +  } else {
> +    mFtpmPolicyPpi->fTPMEnable = FALSE;
> +  }
> +
> +  Status = (*PeiServices)->InstallPpi(
> +                             PeiServices,
> +                             mFtpmPolicyPpiDesc
> +                             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  DEBUG((EFI_D_INFO, "FtpmPolicyInit done \n"));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  This routine attempts to acquire the SMBus
> +
> +  @retval FAILURE as failed
> +  @retval SUCCESS as passed
> +
> +**/
> +EFI_STATUS
> +AcquireBus (
> +    UINT16	SmbusBase
> +  )
> +{
> +  UINT8 StsReg;
> +
> +  StsReg  = 0;
> +  StsReg  = (UINT8)IoRead8(SmbusBase + R_PCH_SMBUS_HSTS);
> +  if (StsReg & B_PCH_SMBUS_IUS) {
> +    return EFI_DEVICE_ERROR;
> +  } else if (StsReg & B_PCH_SMBUS_HBSY) {
> +    //
> +    // Clear Status Register and exit
> +    //
> +    // Wait for HSTS.HBSY to be clear
> +	  //
> +    do { StsReg = (UINT8) IoRead8(SmbusBase+R_PCH_SMBUS_HSTS); }
> while ((StsReg & B_PCH_SMBUS_HBSY) != 0);
> +
> +	  //
> +    // Clear all status bits
> +	  //
> +    IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, 0xFE);
> +    return EFI_SUCCESS;
> +  } else {
> +    //
> +    // Clear out any odd status information (Will Not Clear In Use)
> +    //
> +    IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, StsReg);
> +    return EFI_SUCCESS;
> +  }
> +}
> +//
> +// End::Alpine Valley platform
> +//
> +
> +/**
> +  This function checks the memory range in PEI.
> +
> +  @param  PeiServices     Pointer to PEI Services.
> +  @param  This            Pei memory test PPI pointer.
> +  @param  BeginAddress    Beginning of the memory address to be checked.
> +  @param  MemoryLength    Bytes of memory range to be checked.
> +  @param  Operation       Type of memory check operation to be performed.
> +  @param  ErrorAddress    Return the address of the error memory address.
> +
> +  @retval  EFI_SUCCESS         The operation completed successfully.
> +  @retval  EFI_DEVICE_ERROR    Memory test failed. It's not safe to use this
> range of memory.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +MfgMemoryTest (
> +  IN  CONST EFI_PEI_SERVICES                   **PeiServices,
> +  IN  PEI_MFG_MEMORY_TEST_PPI           *This,
> +  IN  UINT32                             BeginAddress,
> +  IN  UINT32                             MemoryLength
> +  )
> +{
> +  UINT32 i;
> +  UINT32 memAddr;
> +  UINT32 readData;
> +  UINT32 xorData;
> +  UINT32 TestFlag = 0;
> +  memAddr = BeginAddress;
> +
> +  //
> +  //Output Message for MFG
> +  //
> +  DEBUG ((EFI_D_ERROR, "MFGMODE SET\n"));
> +
> +  //
> +  //Writting the pattern in defined location.
> +  //
> +  while (memAddr < (BeginAddress+MemoryLength)) {
> +    for (i = 0; i < DATA_PATTERN_ARRAY_SIZE; i++) {
> +      if (memAddr > (BeginAddress+MemoryLength -4)) {
> +        memAddr = memAddr + 4;
> +        break;
> +      }
> +      *((volatile UINT32*) memAddr) = DataPatternForMemoryTest[i];
> +      memAddr = memAddr + 4;
> +    }
> +  }
> +
> +  //
> +  //Verify the pattern.
> +  //
> +  memAddr = BeginAddress;
> +  while (memAddr < (BeginAddress+MemoryLength)) {
> +  for (i = 0; i < DATA_PATTERN_ARRAY_SIZE; i++) {
> +    if (memAddr > (BeginAddress+MemoryLength -4)) {
> +      memAddr = memAddr + 4;
> +      break;
> +    }
> +    readData = *((volatile UINT32*) memAddr);
> +    xorData = readData ^ DataPatternForMemoryTest[i];
> +
> +	  //
> +    // If xorData is nonzero, this particular memAddr has a failure.
> +	  //
> +    if (xorData != 0x00000000) {
> +      DEBUG ((EFI_D_ERROR, "Expected value....: %x\n",
> DataPatternForMemoryTest[i]));
> +      DEBUG ((EFI_D_ERROR, "ReadData value....: %x\n", readData));
> +      DEBUG ((EFI_D_ERROR, "Pattern failure at....: %x\n", memAddr));
> +      TestFlag = 1;
> +    }
> +    memAddr = memAddr + 4;
> +    }
> +  }
> +  if (TestFlag) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  //Output Message for MFG
> +  //
> +  DEBUG ((EFI_D_ERROR, "MFGMODE MEMORY TEST PASSED\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +BOOLEAN
> +IsRtcUipAlwaysSet (
> +  IN CONST EFI_PEI_SERVICES       **PeiServices
> +  )
> +{
> +
> +  EFI_PEI_STALL_PPI *StallPpi;
> +  UINTN             Count;
> +
> +  (**PeiServices).LocatePpi (PeiServices, &gEfiPeiStallPpiGuid, 0, NULL,
> (void **)&StallPpi);
> +
> +  for (Count = 0; Count < 500; Count++) { // Maximum waiting approximates
> to 1.5 seconds (= 3 msec * 500)
> +    IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA);
> +    if ((IoRead8 (R_PCH_RTC_TARGET2) & B_PCH_RTC_REGISTERA_UIP) == 0)
> {
> +      return FALSE;
> +    }
> +
> +    StallPpi->Stall (PeiServices, StallPpi, 3000);
> +  }
> +
> +  return TRUE;
> +}
> +
> +EFI_STATUS
> +RtcPowerFailureHandler (
> +  IN CONST EFI_PEI_SERVICES       **PeiServices
> +  )
> +{
> +
> +  UINT16          DataUint16;
> +  UINT8           DataUint8;
> +  BOOLEAN         RtcUipIsAlwaysSet;
> +  DataUint16        = MmioRead16 (PMC_BASE_ADDRESS +
> R_PCH_PMC_GEN_PMCON_1);
> +  RtcUipIsAlwaysSet = IsRtcUipAlwaysSet (PeiServices);
> +  if ((DataUint16 & B_PCH_PMC_GEN_PMCON_RTC_PWR_STS) ||
> (RtcUipIsAlwaysSet)) {
> +    //
> +    // Execute the sequence below. This will ensure that the RTC state
> machine has been initialized.
> +    //
> +    // Step 1.
> +    // BIOS clears this bit by writing a '0' to it.
> +    //
> +    if (DataUint16 & B_PCH_PMC_GEN_PMCON_RTC_PWR_STS) {
> +      //
> +      // Set to invalid date in order to reset the time to
> +      // BIOS build time later in the boot (SBRUN.c file).
> +      //
> +      IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_YEAR);
> +      IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);
> +      IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_MONTH);
> +      IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);
> +      IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_DAYOFMONTH);
> +      IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);
> +      IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_DAYOFWEEK);
> +      IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);
> +
> +      IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_SECONDSALARM);
> +      IoWrite8 (R_PCH_RTC_TARGET2, 0x00);
> +      IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_MINUTESALARM);
> +      IoWrite8 (R_PCH_RTC_TARGET2, 0x00);
> +      IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_HOURSALARM);
> +      IoWrite8 (R_PCH_RTC_TARGET2, 0x00);
> +    }
> +
> +    //
> +    // Step 2.
> +    // Set RTC Register 0Ah[6:4] to '110' or '111'.
> +    //
> +    IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA);
> +    IoWrite8 (R_PCH_RTC_TARGET2, (V_PCH_RTC_REGISTERA_DV_DIV_RST1
> | V_PCH_RTC_REGISTERA_RS_976P5US));
> +
> +    //
> +    // Step 3.
> +    // Set RTC Register 0Bh[7].
> +    //
> +    IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
> +    DataUint8 = (IoRead8 (R_PCH_RTC_TARGET2) |
> B_PCH_RTC_REGISTERB_SET);
> +    IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
> +    IoWrite8 (R_PCH_RTC_TARGET2, DataUint8);
> +
> +    //
> +    // Step 4.
> +    // Set RTC Register 0Ah[6:4] to '010'.
> +    //
> +    IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA);
> +    IoWrite8 (R_PCH_RTC_TARGET2,
> (V_PCH_RTC_REGISTERA_DV_NORM_OP |
> V_PCH_RTC_REGISTERA_RS_976P5US));
> +
> +    //
> +    // Step 5.
> +    // Clear RTC Register 0Bh[7].
> +    //
> +    IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
> +    DataUint8 = (IoRead8 (R_PCH_RTC_TARGET2) &
> (UINT8)~B_PCH_RTC_REGISTERB_SET);
> +    IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
> +    IoWrite8 (R_PCH_RTC_TARGET2, DataUint8);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +VOID
> +PchBaseInit (
> +  VOID
> +  )
> +{
> +  //
> +  // Program ACPI Power Management I/O Space Base Address
> +  //
> +  MmioWrite16 (
> +    MmPciAddress (0,
> +      DEFAULT_PCI_BUS_NUMBER_PCH,
> +      PCI_DEVICE_NUMBER_PCH_LPC,
> +      PCI_FUNCTION_NUMBER_PCH_LPC,
> +      R_PCH_LPC_ACPI_BASE
> +    ),
> +    (UINT16)((ACPI_BASE_ADDRESS & B_PCH_LPC_ACPI_BASE_BAR) |
> B_PCH_LPC_ACPI_BASE_EN)
> +  );
> +
> +  //
> +  // Program GPIO Base Address
> +  //
> +  MmioWrite16 (
> +    MmPciAddress (0,
> +      DEFAULT_PCI_BUS_NUMBER_PCH,
> +      PCI_DEVICE_NUMBER_PCH_LPC,
> +      PCI_FUNCTION_NUMBER_PCH_LPC,
> +      R_PCH_LPC_GPIO_BASE
> +    ),
> +    (UINT16)((GPIO_BASE_ADDRESS & B_PCH_LPC_GPIO_BASE_BAR) |
> B_PCH_LPC_GPIO_BASE_EN)
> +  );
> +
> +  //
> +  // Set PMC Base Address
> +  //
> +  MmioWrite32 (
> +    MmPciAddress (0,
> +      DEFAULT_PCI_BUS_NUMBER_PCH,
> +      PCI_DEVICE_NUMBER_PCH_LPC,
> +      PCI_FUNCTION_NUMBER_PCH_LPC,
> +      R_PCH_LPC_PMC_BASE
> +    ),
> +    (UINT32)((PMC_BASE_ADDRESS & B_PCH_LPC_PMC_BASE_BAR) |
> B_PCH_LPC_PMC_BASE_EN)
> +  );
> +
> +  //
> +  // Set IO Base Address
> +  //
> +  MmioWrite32 (
> +    MmPciAddress (0,
> +      DEFAULT_PCI_BUS_NUMBER_PCH,
> +      PCI_DEVICE_NUMBER_PCH_LPC,
> +      PCI_FUNCTION_NUMBER_PCH_LPC,
> +      R_PCH_LPC_IO_BASE
> +    ),
> +    (UINT32)((IO_BASE_ADDRESS & B_PCH_LPC_IO_BASE_BAR) |
> B_PCH_LPC_IO_BASE_EN)
> +  );
> +
> +  //
> +  // Set ILB Base Address
> +  //
> +  MmioWrite32 (
> +    MmPciAddress (0,
> +      DEFAULT_PCI_BUS_NUMBER_PCH,
> +      PCI_DEVICE_NUMBER_PCH_LPC,
> +      PCI_FUNCTION_NUMBER_PCH_LPC,
> +      R_PCH_LPC_ILB_BASE
> +    ),
> +    (UINT32)((ILB_BASE_ADDRESS & B_PCH_LPC_ILB_BASE_BAR) |
> B_PCH_LPC_ILB_BASE_EN)
> +  );
> +
> +  //
> +  // Set PUnit Base Address
> +  //
> +  MmioWrite32 (
> +    MmPciAddress (0,
> +      DEFAULT_PCI_BUS_NUMBER_PCH,
> +      PCI_DEVICE_NUMBER_PCH_LPC,
> +      PCI_FUNCTION_NUMBER_PCH_LPC,
> +      R_PCH_LPC_PUNIT_BASE
> +    ),
> +    (UINT32)((PUNIT_BASE_ADDRESS & B_PCH_LPC_PUNIT_BASE_BAR) |
> B_PCH_LPC_PUNIT_BASE_EN)
> +  );
> +
> +  //
> +  // Set SPI Base Address
> +  //
> +  MmioWrite32 (
> +    MmPciAddress (0,
> +      DEFAULT_PCI_BUS_NUMBER_PCH,
> +      PCI_DEVICE_NUMBER_PCH_LPC,
> +      PCI_FUNCTION_NUMBER_PCH_LPC,
> +      R_PCH_LPC_SPI_BASE
> +    ),
> +    (UINT32)((SPI_BASE_ADDRESS & B_PCH_LPC_SPI_BASE_BAR) |
> B_PCH_LPC_SPI_BASE_EN)
> +  );
> +
> +  //
> +  // Set Root Complex Base Address
> +  //
> +  MmioWrite32 (
> +    MmPciAddress (0,
> +      DEFAULT_PCI_BUS_NUMBER_PCH,
> +      PCI_DEVICE_NUMBER_PCH_LPC,
> +      PCI_FUNCTION_NUMBER_PCH_LPC,
> +      R_PCH_LPC_RCBA
> +    ),
> +    (UINT32)((RCBA_BASE_ADDRESS & B_PCH_LPC_RCBA_BAR) |
> B_PCH_LPC_RCBA_EN)
> +  );
> +
> +  //
> +  // Set MPHY Base Address
> +  //
> +  MmioWrite32 (
> +    MmPciAddress (0,
> +      DEFAULT_PCI_BUS_NUMBER_PCH,
> +      PCI_DEVICE_NUMBER_PCH_LPC,
> +      PCI_FUNCTION_NUMBER_PCH_LPC,
> +      R_PCH_LPC_MPHY_BASE
> +    ),
> +    (UINT32)((MPHY_BASE_ADDRESS & B_PCH_LPC_MPHY_BASE_BAR) |
> B_PCH_LPC_MPHY_BASE_EN)
> +  );
> +  MmioWrite16 (
> +    MmPciAddress (0,
> +      DEFAULT_PCI_BUS_NUMBER_PCH,
> +      PCI_DEVICE_NUMBER_PCH_SMBUS,
> +      PCI_FUNCTION_NUMBER_PCH_SMBUS,
> +      R_PCH_SMBUS_BASE
> +    ),
> +    (UINT16)(SMBUS_BASE_ADDRESS & B_PCH_SMBUS_BASE_BAR)
> +  );
> +
> +  MmioOr8 (
> +    MmPciAddress (0,
> +      DEFAULT_PCI_BUS_NUMBER_PCH,
> +      PCI_DEVICE_NUMBER_PCH_SMBUS,
> +      PCI_FUNCTION_NUMBER_PCH_SMBUS,
> +      R_PCH_SMBUS_PCICMD
> +    ),
> +    B_PCH_SMBUS_PCICMD_IOSE
> +  );
> +
> +}
> +
> +/**
> +  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
> +PeiInitPlatform (
> +  IN       EFI_PEI_FILE_HANDLE  FileHandle,
> +  IN CONST EFI_PEI_SERVICES     **PeiServices
> +  )
> +{
> +  UINTN                            SmbusRegBase;
> +  EFI_PLATFORM_INFO_HOB            PlatformInfo;
> +  EFI_STATUS                       Status= EFI_SUCCESS;
> +  EFI_PEI_READ_ONLY_VARIABLE2_PPI  *Variable = NULL;
> +  UINTN                            VariableSize;
> +  SYSTEM_CONFIGURATION             SystemConfiguration;
> +  UINT32                           GGC = 0;
> +
> +  EFI_PEI_PPI_DESCRIPTOR          *mVlvMmioPolicyPpiDesc;
> +  VLV_MMIO_POLICY_PPI             *mVlvMmioPolicyPpi;
> +
> +  ZeroMem (&PlatformInfo, sizeof(PlatformInfo));
> +
> +  Status =  InstallMonoStatusCode(FileHandle, PeiServices);
> +  ASSERT_EFI_ERROR (Status);
> +
> +
> +  //
> +  // Initialize Stall PPIs
> +  //
> +  Status = (*PeiServices)->InstallPpi (PeiServices, &mInstallStallPpi[0]);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = (*PeiServices)->NotifyPpi (PeiServices,
> &mMemoryDiscoveredNotifyList[0]);
> +  ASSERT_EFI_ERROR (Status);
> +  SmbusRegBase = PchPciDeviceMmBase (
> +                   DEFAULT_PCI_BUS_NUMBER_PCH,
> +                   PCI_DEVICE_NUMBER_PCH_SMBUS,
> +                   PCI_FUNCTION_NUMBER_PCH_SMBUS
> +                   );
> +  //
> +  // Since PEI has no PCI enumerator, set the BAR & I/O space enable
> ourselves
> +  //
> +  MmioAndThenOr32 (SmbusRegBase + R_PCH_SMBUS_BASE,
> B_PCH_SMBUS_BASE_BAR, SMBUS_BASE_ADDRESS);
> +
> +  MmioOr8 (SmbusRegBase + R_PCH_SMBUS_PCICMD,
> B_PCH_SMBUS_PCICMD_IOSE);
> +
> +  PchBaseInit();
> +
> +  //
> +  //Todo: confirm if we need program 8254
> +  //
> +  // Setting 8254
> +  // Program timer 1 as refresh timer
> +  //
> +  IoWrite8 (0x43, 0x54);
> +  IoWrite8 (0x41, 0x12);
> +
> +  //
> +  // RTC power failure handling
> +  //
> +  RtcPowerFailureHandler (PeiServices);
> +
> +
> +  PchMmPci32( 0, 0, 2, 0, 0x50) = 0x210;
> +
> +  VariableSize = sizeof (SYSTEM_CONFIGURATION);
> +  ZeroMem (&SystemConfiguration, VariableSize);
> +
> +  //
> +  // Obtain variable services
> +  //
> +  Status = (*PeiServices)->LocatePpi(
> +                             PeiServices,
> +                             &gEfiPeiReadOnlyVariable2PpiGuid,
> +                             0,
> +                             NULL,
> +                             (void **)&Variable
> +                             );
> +  ASSERT_EFI_ERROR(Status);
> +  Status = Variable->GetVariable (
> +                       Variable,
> +                       L"Setup",
> +                       &gEfiSetupVariableGuid,
> +                       NULL,
> +                       &VariableSize,
> +                       &SystemConfiguration
> +					   );
> +  if (EFI_ERROR (Status) || VariableSize != sizeof(SYSTEM_CONFIGURATION))
> {
> +    //The setup variable is corrupted
> +    VariableSize = sizeof(SYSTEM_CONFIGURATION);
> +    Status = Variable->GetVariable(
> +              Variable,
> +              L"SetupRecovery",
> +              &gEfiSetupVariableGuid,
> +              NULL,
> +              &VariableSize,
> +              &SystemConfiguration
> +              );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +  if (EFI_ERROR (Status)) {
> +    GGC = ((2 << 3) | 0x200);
> +    PciCfg16Write(EC_BASE, 0, 2, 0, 0x50, GGC);
> +    GGC = PciCfg16Read(EC_BASE, 0, 2, 0, 0x50);
> +    DEBUG((EFI_D_INFO , "GGC: 0x%08x GMSsize:0x%08x\n", GGC, (GGC &
> (BIT7|BIT6|BIT5|BIT4|BIT3))>>3));
> +  } else {
> +    if (SystemConfiguration.Igd == 1 &&
> SystemConfiguration.PrimaryVideoAdaptor != 2) {
> +      GGC = (SystemConfiguration.IgdDvmt50PreAlloc << 3) |
> +            (SystemConfiguration.GTTSize == GTT_SIZE_1MB ? 0x100: 0x200);
> +      PciCfg16Write(EC_BASE, 0, 2, 0, 0x50, GGC);
> +      GGC = PciCfg16Read(EC_BASE, 0, 2, 0, 0x50);
> +      DEBUG((EFI_D_INFO , "GGC: 0x%08x GMSsize:0x%08x\n", GGC, (GGC &
> (BIT7|BIT6|BIT5|BIT4|BIT3))>>3));
> +    }
> +  }
> +
> +  //
> +  // Initialize PlatformInfo HOB
> +  //
> +  Status = ReadPlatformIds(PeiServices, &PlatformInfo);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // 0 -> Disable , 1 -> Enable
> +  //
> +  if(SystemConfiguration.CfioPnpSettings == 1) {
> +    DEBUG((EFI_D_INFO, "CheckCfioPnpSettings: CFIO Pnp Settings
> Enabled\n"));
> +    PlatformInfo.CfioEnabled = 1;
> +  } else {
> +    DEBUG((EFI_D_INFO, "CheckCfioPnpSettings: CFIO Pnp Settings
> Disabled\n"));
> +    PlatformInfo.CfioEnabled = 0;
> +  }
> +
> +  //
> +  // Build HOB for PlatformInfo
> +  //
> +  BuildGuidDataHob (
> +    &gEfiPlatformInfoGuid,
> +    &PlatformInfo,
> +    sizeof (EFI_PLATFORM_INFO_HOB)
> +    );
> +
> +
> +#ifdef FTPM_ENABLE
> +  Status = FtpmPolicyInit(PeiServices, &SystemConfiguration);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG((EFI_D_ERROR, "fTPM init failed.\n"));
> +  }
> +#endif
> +
> +
> +  //
> +  // Set the new boot mode for MRC
> +  //
> +#ifdef NOCS_S3_SUPPORT
> +  Status = UpdateBootMode (PeiServices);
> +  ASSERT_EFI_ERROR (Status);
> +#endif
> +
> +  DEBUG((EFI_D_INFO, "Setup MMIO size ... \n\n"));
> +
> +  //
> +  // Setup MMIO size
> +  //
> +  Status = (*PeiServices)->AllocatePool(
> +                             PeiServices,
> +                             sizeof (EFI_PEI_PPI_DESCRIPTOR),
> +                             (void **)&mVlvMmioPolicyPpiDesc
> +                             );
> +  ASSERT_EFI_ERROR (Status);
> +  Status = (*PeiServices)->AllocatePool(
> +                             PeiServices,
> +                             sizeof (VLV_MMIO_POLICY_PPI),
> +                             (void **)&mVlvMmioPolicyPpi
> +                             );
> +  ASSERT_EFI_ERROR (Status);
> +  (*PeiServices)->SetMem (
> +                    (VOID *)mVlvMmioPolicyPpi,
> +                    sizeof (VLV_MMIO_POLICY_PPI),
> +                    0
> +                    );
> +  mVlvMmioPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
> +  mVlvMmioPolicyPpiDesc->Guid = &gVlvMmioPolicyPpiGuid;
> +  mVlvMmioPolicyPpiDesc->Ppi = mVlvMmioPolicyPpi;
> +  switch (SystemConfiguration.MmioSize) {
> +    case 0:      // 768MB
> +      mVlvMmioPolicyPpi->MmioSize = 0x300;
> +      break;
> +    case 1:      // 1GB
> +      mVlvMmioPolicyPpi->MmioSize = 0x400;
> +      break;
> +    case 2:      // 1.25GB
> +      mVlvMmioPolicyPpi->MmioSize = 0x500;
> +      break;
> +    case 3:      // 1.5GB
> +      mVlvMmioPolicyPpi->MmioSize = 0x600;
> +      break;
> +    case 4:      // 2GB
> +      mVlvMmioPolicyPpi->MmioSize = 0x800;
> +      break;
> +    default:
> +      mVlvMmioPolicyPpi->MmioSize = 0x800;
> +      break;
> +  }
> +  Status = (*PeiServices)->InstallPpi(
> +                             PeiServices,
> +                             mVlvMmioPolicyPpiDesc
> +                             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> +EFI_STATUS
> +ReadPlatformIds (
> +  IN CONST EFI_PEI_SERVICES             **PeiServices,
> +  IN OUT EFI_PLATFORM_INFO_HOB          *PlatformInfoHob
> +  )
> +{
> +  {
> +    EFI_STATUS                      Status = EFI_SUCCESS;
> +    UINT8                           FabId = 0;
> +    UINTN                           DataSize;
> +    EFI_PLATFORM_INFO_HOB           TmpHob;
> +    EFI_PEI_READ_ONLY_VARIABLE2_PPI *PeiVar;
> +    UINT32                          CompatibleBoard = 0;
> +
> +    Status = (**PeiServices).LocatePpi (
> +                               PeiServices,
> +                               &gEfiPeiReadOnlyVariable2PpiGuid,
> +                               0,
> +                               NULL,
> +                               (void **)&PeiVar
> +                               );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    DataSize = sizeof (EFI_PLATFORM_INFO_HOB);
> +    Status = PeiVar->GetVariable (
> +                       PeiVar,
> +                       L"PlatformInfo",
> +                       &gEfiVlv2VariableGuid,
> +                       NULL,
> +                       &DataSize,
> +                       &TmpHob
> +					   );
> +
> +    if (Status == EFI_SUCCESS) {
> +      PlatformInfoHob->BoardId        = TmpHob.BoardId;
> +      PlatformInfoHob->MemCfgID       = TmpHob.MemCfgID;
> +      PlatformInfoHob->BoardRev       = TmpHob.BoardRev;
> +      PlatformInfoHob->PlatformFlavor = TmpHob.PlatformFlavor;
> +      return Status;
> +    }
> +
> +    CompatibleBoard = DetermineTurbotBoard();
> +   if (1 == CompatibleBoard) {
> +     PlatformInfoHob->BoardId    = BOARD_ID_MINNOW2_TURBOT;
> +     DEBUG ((EFI_D_INFO,  "I'm MinnowBoard Turbot!\n"));
> +   } else {
> +     PlatformInfoHob->BoardId    = BOARD_ID_MINNOW2;
> +     DEBUG ((EFI_D_INFO,  "I'm MinnowBoard Max!\n"));
> +   }
> +
> +
> +    PlatformInfoHob->MemCfgID   = 0;
> +    PlatformInfoHob->BoardRev   = FabId + 1;	// FabId = 0 means FAB1
> (BoardRev = 1), FabId = 1 means FAB2 (BoardRev = 2)...
> +    PlatformInfoHob->PlatformFlavor = FlavorMobile;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +//
> +// Start::Alpine Valley platform
> +//
> +/**
> +  This routine reads SysCtl registers
> +
> +  @param SmbusBase   SMBUS Base Address
> +  @param SlvAddr     Targeted Smbus Slave device address
> +  @param Operation   Which SMBus protocol will be used
> +  @param Offset      Offset of the register
> +  @param  Length     Number of bytes
> +  @param  Buffer     Buffer contains values read from registers
> +
> +  @retval SUCCESS as passed
> +  @retval Others as failed
> +
> +**/
> +EFI_STATUS
> +PeiSmbusExec (
> +  UINT16 SmbusBase,
> +  UINT8 SlvAddr,
> +  UINT8 Operation,
> +  UINT8 Offset,
> +  UINT8 *Length,
> +  UINT8 *Buffer
> +  )
> +{
> +  EFI_STATUS  Status=EFI_SUCCESS;
> +  UINT8       AuxcReg;
> +  UINT8       SmbusOperation = 0;
> +  UINT8       StsReg;
> +  UINT8       SlvAddrReg;
> +  UINT8       HostCmdReg;
> +  UINT8       BlockCount = 0;
> +  BOOLEAN     BufferTooSmall;
> +  UINT8       Index;
> +  UINT8       *CallBuffer;
> +  UINT8  	  RetryCount = BUS_TRIES;
> +
> +  //
> +  // MrcSmbusExec supports byte and block read.
> +  // Only allow Byte or block access
> +  //
> +  if (!((*Length  == AV_SC_BYTE_LEN) || (*Length == AV_SC_BLOCK_LEN)))
> {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // See if its ok to use the bus based upon INUSE_STS bit.
> +  //
> +  Status = AcquireBus (SmbusBase);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  CallBuffer = Buffer;
> +
> +  //
> +  //SmbStatus Bits of interest
> +  //[6] = IUS (In Use Status)
> +  //[4] = FAIL
> +  //[3] = BERR (Bus Error = transaction collision)
> +  //[2] = DERR (Device Error = Illegal Command Field, Unclaimed Cycle, Host
> Device Timeout, CRC Error)
> +  //[1] = INTR (Successful completion of last command)
> +  //[0] = HOST BUSY
> +  //
> +  //
> +  // This is the main operation loop.  If the operation results in a Smbus
> +  // collision with another master on the bus, it attempts the requested
> +  // transaction again at least BUS_TRIES attempts.
> +  //
> +  while (RetryCount--) {
> +    //
> +    // Operation Specifics (pre-execution)
> +    //
> +    Status          = EFI_SUCCESS;
> +    SlvAddrReg      = SlvAddr;
> +    HostCmdReg      = Offset;
> +    AuxcReg         = 0;
> +
> +	switch (Operation) {
> +
> +	case SMBUS_WRITE_BYTE:
> +    IoWrite8 (SmbusBase+R_PCH_SMBUS_HD0, CallBuffer[0]);
> +		SmbusOperation = V_PCH_SMBUS_SMB_CMD_BYTE_DATA;
> +	break;
> +
> +    case SMBUS_READ_BYTE:
> +      SmbusOperation = V_PCH_SMBUS_SMB_CMD_BYTE_DATA;
> +	  	SlvAddrReg |= B_PCH_SMBUS_RW_SEL_READ;
> +      if (*Length < 1) {
> +        Status = EFI_INVALID_PARAMETER;
> +      }
> +      	*Length = 1;
> +	break;
> +
> +    case SMBUS_WRITE_BLOCK:
> +      SmbusOperation  = V_PCH_SMBUS_SMB_CMD_BLOCK;
> +      IoWrite8 (SmbusBase+R_PCH_SMBUS_HD0, *(UINT8 *) Length);
> +     	BlockCount = (UINT8) (*Length);
> +     	if ((*Length < 1) || (*Length > 32)) {
> +        Status = EFI_INVALID_PARAMETER;
> +        break;
> +    	}
> +      	AuxcReg |= B_PCH_SMBUS_E32B;
> +	break;
> +
> +    case SMBUS_READ_BLOCK:
> +      SmbusOperation = V_PCH_SMBUS_SMB_CMD_BLOCK;
> +     	SlvAddrReg |= B_PCH_SMBUS_RW_SEL_READ;
> +     	if ((*Length < 1) || (*Length > 32)) {
> +        Status = EFI_INVALID_PARAMETER;
> +        break;
> +     	}
> +      	AuxcReg |= B_PCH_SMBUS_E32B;
> +	break;
> +
> +    default:
> +      	Status = EFI_INVALID_PARAMETER;
> +	break;
> +    }
> +
> +    //
> +    // Set Auxiliary Control register
> +    //
> +    IoWrite8 (SmbusBase+R_PCH_SMBUS_AUXC, AuxcReg);
> +
> +    //
> +    // Reset the pointer of the internal buffer
> +    //
> +    IoRead8 (SmbusBase+R_PCH_SMBUS_HCTL);
> +
> +    //
> +    // Now that the 32 byte buffer is turned on, we can write th block data
> +    // into it
> +    //
> +    if (Operation == SMBUS_WRITE_BLOCK) {
> +      for (Index = 0; Index < BlockCount; Index++) {
> +        //
> +        // Write next byte
> +        //
> +        IoWrite8 (SmbusBase+R_PCH_SMBUS_HBD, CallBuffer[Index]);
> +      }
> +    }
> +
> +    //
> +    // Set SMBus slave address for the device to read
> +    //
> +    IoWrite8(SmbusBase+R_PCH_SMBUS_TSA, SlvAddrReg);
> +
> +    //
> +    //
> +    // Set Command register for the offset to read
> +    //
> +    IoWrite8(SmbusBase+R_PCH_SMBUS_HCMD, HostCmdReg );
> +
> +    //
> +    // Set Control Register to Set "operation command" protocol and start bit
> +    //
> +    IoWrite8(SmbusBase+R_PCH_SMBUS_HCTL, (UINT8) (SmbusOperation +
> B_PCH_SMBUS_START));
> +
> +    //
> +    // Wait for IO to complete
> +    //
> +	do { StsReg = (UINT8) IoRead8(SmbusBase+0); } while ((StsReg &
> (BIT4|BIT3|BIT2|BIT1)) == 0);
> +
> +	  if (StsReg & B_PCH_SMBUS_DERR) {
> +      Status = EFI_DEVICE_ERROR;
> +      break;
> +    } else if (StsReg & B_PCH_SMBUS_BERR) {
> +      //
> +      // Clear the Bus Error for another try
> +      //
> +      Status = EFI_DEVICE_ERROR;
> +      IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BERR);
> +
> +      //
> +      // Clear Status Registers
> +      //
> +      IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
> +      IoWrite8(SmbusBase+R_PCH_SMBUS_AUXS, B_PCH_SMBUS_CRCE);
> +
> +      continue;
> +    }
> +
> +    //
> +    // successfull completion
> +    // Operation Specifics (post-execution)
> +    //
> +    switch (Operation) {
> +
> +    case SMBUS_READ_BYTE:
> +      CallBuffer[0] = (UINT8)(IoRead8 (SmbusBase+R_PCH_SMBUS_HD0));
> +      break;
> +
> +    case SMBUS_WRITE_BLOCK:
> +      IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS,
> B_PCH_SMBUS_BYTE_DONE_STS);
> +      break;
> +
> +    case SMBUS_READ_BLOCK:
> +      BufferTooSmall = FALSE;
> +
> +      //
> +      // Find out how many bytes will be in the block
> +      //
> +      BlockCount = (UINT8)(IoRead8 (SmbusBase+R_PCH_SMBUS_HD0));
> +      if (*Length < BlockCount) {
> +        BufferTooSmall = TRUE;
> +      } else {
> +        for (Index = 0; Index < BlockCount; Index++) {
> +          //
> +          // Read the byte
> +          //
> +          CallBuffer[Index] = (UINT8)IoRead8
> (SmbusBase+R_PCH_SMBUS_HBD);
> +        }
> +      }
> +
> +      *Length = BlockCount;
> +      if (BufferTooSmall) {
> +        Status = EFI_BUFFER_TOO_SMALL;
> +      }
> +      break;
> +
> +    default:
> +      break;
> +    };
> +
> +    if ((StsReg & B_PCH_SMBUS_BERR) && (Status == EFI_SUCCESS)) {
> +      //
> +      // Clear the Bus Error for another try
> +      //
> +      Status = EFI_DEVICE_ERROR;
> +      IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BERR);
> +
> +      continue;
> +    } else {
> +      break;
> +    }
> +  }
> +
> +  //
> +  // Clear Status Registers and exit
> +  //
> +  IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
> +  IoWrite8(SmbusBase+R_PCH_SMBUS_AUXS, B_PCH_SMBUS_CRCE);
> +  IoWrite8(SmbusBase+R_PCH_SMBUS_AUXC, 0);
> +  return Status;
> +}
> +//
> +// End::Alpine Valley platform
> +//
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.h
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.h
> new file mode 100644
> index 0000000000..e1817b28c6
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.h
> @@ -0,0 +1,213 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +**/
> +
> +
> +#ifndef __PEI_PLATFORM_H__
> +#define __PEI_PLATFORM_H__
> +
> +#define PEI_STALL_RESOLUTION            1
> +#define STALL_PEIM_SIGNATURE   SIGNATURE_32('p','p','u','s')
> +
> +typedef struct {
> +  UINT32                      Signature;
> +  EFI_FFS_FILE_HEADER         *FfsHeader;
> +  EFI_PEI_NOTIFY_DESCRIPTOR   StallNotify;
> +} STALL_CALLBACK_STATE_INFORMATION;
> +
> +#define STALL_PEIM_FROM_THIS(a) CR (a,
> STALL_CALLBACK_STATE_INFORMATION, StallNotify,
> STALL_PEIM_SIGNATURE)
> +
> +#ifdef NOCS_S3_SUPPORT
> +
> +/**
> +  Peform the boot mode determination logic
> +  If the box is closed, then
> +  1. If it's first time to boot, it's boot with full config .
> +  2. If the ChassisIntrution is selected, force to be a boot with full config
> +  3. Otherwise it's boot with no change.
> +
> +  @param  PeiServices General purpose services available to every PEIM.
> +  @param  BootMode The detected boot mode.
> +
> +  @retval EFI_SUCCESS if the boot mode could be set
> +**/
> +EFI_STATUS
> +UpdateBootMode (
> +  IN CONST EFI_PEI_SERVICES     **PeiServices
> +  );
> +#endif
> +
> +/**
> +  This function reset the entire platform, including all processor and devices,
> and
> +  reboots the system.
> +
> +  Declaration of this function goes to
> MdeModulePkg/Include/Library/ResetSystemLib.h
> +
> +  @param  PeiServices General purpose services available to every PEIM.
> +
> +  @retval EFI_SUCCESS if it completed successfully.
> +**/
> +// EFI_STATUS
> +// EFIAPI
> +// ResetSystem (
> +  // IN CONST EFI_PEI_SERVICES          **PeiServices
> +  // );
> +
> +/**
> +  This function will be called when MRC is done.
> +
> +  @param  PeiServices        General purpose services available to every PEIM.
> +  @param  NotifyDescriptor   Information about the notify event..
> +  @param  Ppi                The notify context.
> +
> +  @retval EFI_SUCCESS        If the function completed successfully.
> +**/
> +EFI_STATUS
> +EFIAPI
> +MemoryDiscoveredPpiNotifyCallback (
> +  IN EFI_PEI_SERVICES                     **PeiServices,
> +  IN EFI_PEI_NOTIFY_DESCRIPTOR            *NotifyDescriptor,
> +  IN VOID                                 *Ppi
> +  );
> +
> +/**
> +  This is the callback function notified by FvFileLoader PPI, it depends on
> FvFileLoader PPI to load
> +  the PEIM into memory.
> +
> +  @param  PeiServices       General purpose services available to every PEIM.
> +  @param  NotifyDescriptor  The context of notification.
> +  @param  Ppi               The notify PPI.
> +
> +  @retval EFI_SUCCESS       if it completed successfully.
> +**/
> +EFI_STATUS
> +EFIAPI
> +FvFileLoaderPpiNotifyCallback (
> +  IN EFI_PEI_SERVICES           **PeiServices,
> +  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
> +  IN VOID                       *Ppi
> +  );
> +
> +/**
> +  This function provides a blocking stall for reset at least the given number of
> microseconds
> +  stipulated in the final argument.
> +
> +  @param  PeiServices    General purpose services available to every PEIM.
> +  @param  this Pointer   to the local data for the interface.
> +  @param  Microseconds   number of microseconds for which to stall.
> +
> +  @retval EFI_SUCCESS    the function provided at least the required stall.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Stall (
> +  IN CONST EFI_PEI_SERVICES   **PeiServices,
> +  IN CONST EFI_PEI_STALL_PPI  *This,
> +  IN UINTN                    Microseconds
> +  );
> +
> +/**
> +  This function initialize recovery functionality by installing the recovery PPI.
> +
> +  @param  PeiServices  General purpose services available to every PEIM.
> +
> +  @retval EFI_SUCCESS  If the interface could be successfully installed.
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitializeRecovery (
> +  IN EFI_PEI_SERVICES     **PeiServices
> +  );
> +
> +/**
> +  This function
> +    1. Calling MRC to initialize memory.
> +    2. Install EFI Memory.
> +    3. Capsule coalesce if capsule boot mode.
> +    4. Create HOB of system memory.
> +
> +  @param  PeiServices Pointer to the PEI Service Table
> +
> +  @retval EFI_SUCCESS If it completes successfully.
> +
> +**/
> +EFI_STATUS
> +MemoryInit (
> +  IN EFI_PEI_SERVICES          **PeiServices
> +  );
> +
> +/**
> +  This function provides the implementation of AtaController PPI Enable
> Channel function.
> +
> +  @param  PeiServices General purpose services available to every PEIM.
> +  @param  this Pointer to the local data for the interface.
> +  @param  ChannelMask This parameter is used to specify primary or slavery
> IDE channel.
> +
> +  @retval EFI_SUCCESS  Procedure returned successfully.
> +**/
> +EFI_STATUS
> +EnableAtaChannel (
> +  IN EFI_PEI_SERVICES               **PeiServices,
> +  IN PEI_ATA_CONTROLLER_PPI         *This,
> +  IN UINT8                          ChannelMask
> +  );
> +
> +/**
> +  This function provides the implementation of AtaController PPI Get IDE
> channel Register Base Address
> +
> +  @param  PeiServices      General purpose services available to every PEIM.
> +  @param  this             Pointer to the local data for the interface.
> +  @param  IdeRegsBaseAddr  Pointer to IDE_REGS_BASE_ADDR struct,
> which is used to record
> +                           IDE Command and Control regeisters Base Address.
> +
> +  @retval EFI_SUCCESS  Procedure returned successfully.
> +**/
> +EFI_STATUS
> +GetIdeRegsBaseAddr (
> +  IN EFI_PEI_SERVICES               **PeiServices,
> +  IN PEI_ATA_CONTROLLER_PPI         *This,
> +  IN IDE_REGS_BASE_ADDR             *IdeRegsBaseAddr
> +  );
> +
> +/**
> +  This function provides the implementation to properly setup both LM &
> PDM functionality.
> +
> +  @param  PeiServices      General purpose services available to every PEIM.
> +
> +  @retval EFI_SUCCESS  Procedure returned successfully.
> +
> +**/
> +EFI_STATUS
> +ConfigureLM(
> +  IN EFI_PEI_SERVICES **PeiServices
> +  );
> +
> +#include <Ppi/VlvMmioPolicy.h>
> +
> +BOOLEAN
> +EFIAPI
> +IsFastBootEnabled (
> +  IN CONST EFI_PEI_SERVICES **PeiServices
> +  );
> +
> +EFI_STATUS
> +PrioritizeBootMode (
> +  IN OUT EFI_BOOT_MODE    *CurrentBootMode,
> +  IN EFI_BOOT_MODE        NewBootMode
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +CapsulePpiNotifyCallback (
> +  IN EFI_PEI_SERVICES           **PeiServices,
> +  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
> +  IN VOID                       *Ppi
> +  );
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/PlatformPei.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/PlatformPei.inf
> new file mode 100644
> index 0000000000..c976273ce3
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/PlatformPei.inf
> @@ -0,0 +1,129 @@
> +#
> +#
> +# Copyright (c)  1999  - 2018, Intel Corporation. All rights reserved
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +# This PEIM includes 3 parts, pre memory initialization, MRC
> +#  wrapper and post memory initialization.
> +#  On pre memory, following action is performed,
> +#  1. Initizluize GMCH.
> +#  2. Detect boot mode.
> +#  3. Detect video adapter to determine whether we need pre allocated
> +#  memory.
> +#
> +#  After that MRC wrapper calls MRC to initialize memory and install a PPI
> +#  notify to do post memory
> +#  initialization. MRC wrapper performance following actions,
> +#  1. Install EFI Memory.
> +#  2. Capsule coalesce if capsule boot mode.
> +#  3. Create HOB of system memory.
> +#  Note: MRC supports 3 kinds of chipsets including Lakeport, Glenwood
> and Mukilteo,
> +#   so please don't define MACRO MUKILTEO_SUPPORT on Lakeport here.
> +#
> +#  On post memory, following action is performed,
> +#  1. TC initialization after MRC.
> +#  2. SIO initialization.
> +#  3. Install ResetSystem and FinvFv PPI, relocate Stall to memory on
> +#   recovery boot mode.
> +#  4. Set MTRR for PEI
> +#  5. Create FV HOB and Flash HOB
> +#  6. Install RecoveryModule and AtaController PPI if on recovery boot
> mode.
> +#
> +#  This PEIM does not have any register access directly, it depends on
> +#  IntelTCLib, TCAccess libraries to access Chipset
> +#  registers.
> +#
> +#  Platform.c - Provide main flow and entrypoint of PEIM.
> +#  MemoryCallback.c - Includes a memory call back function notified when
> +#     MRC is done.
> +#
> +#
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = PlatformPeim
> +  FILE_GUID                      = 9618C0DC-50A4-496c-994F-7241F282ED01
> +  MODULE_TYPE                    = PEIM
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = PeiInitPlatform
> +  PI_SPECIFICATION_VERSION	   = 0x0001000A
> +
> +[sources.common]
> +  Platform.c
> +  Platform.h
> +  MemoryCallback.c
> +  CommonHeader.h
> +  Stall.c
> +  BootMode.c
> +
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  IntelFrameworkPkg/IntelFrameworkPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +  Vlv2SocBinPkg/Vlv2SocBinPkg.dec
> +  UefiCpuPkg/UefiCpuPkg.dec
> +  CryptoPkg/CryptoPkg.dec
> +
> +[LibraryClasses]
> +  PeimEntryPoint
> +  DebugLib
> +  HobLib
> +  IoLib
> +  MultiPlatformLib
> +  MtrrLib
> +  PerformanceLib
> +  MonoStatusCodeLib
> +  BaseCryptLib
> +  PciLib
> +
> +[Ppis]
> +  gEfiPeiStallPpiGuid
> +  gPeiSpeakerInterfacePpiGuid
> +  gEfiPeiMemoryDiscoveredPpiGuid
> +  gVlvPolicyPpiGuid
> +  gEfiPeiReadOnlyVariable2PpiGuid
> +  gEfiPeiResetPpiGuid
> +  gEfiEndOfPeiSignalPpiGuid
> +  gEfiFindFvPpiGuid
> +  gPeiCapsulePpiGuid
> +  gEfiPeiBootInRecoveryModePpiGuid
> +  gEfiPeiRecoveryModulePpiGuid
> +  gEfiPeiDeviceRecoveryModulePpiGuid
> +  gPeiCachePpiGuid
> +  gEfiPeiMasterBootModePpiGuid
> +  gEfiPeiSmbusPpiGuid
> +  gPeiMfgMemoryTestPpiGuid
> +  gPeiSha256HashPpiGuid
> +  gVlvMmioPolicyPpiGuid
> +  gSeCfTPMPolicyPpiGuid
> +
> +[Guids]
> +  gEfiSetupVariableGuid
> +  gEfiPlatformInfoGuid
> +  gEfiPlatformBootModeGuid
> +  gEfiPlatformCpuInfoGuid
> +  gEfiGlobalVariableGuid
> +  gRecoveryOnFatFloppyDiskGuid
> +  gRecoveryOnFatUsbDiskGuid
> +  gRecoveryOnFatIdeDiskGuid
> +  gRecoveryOnDataCdGuid
> +  gMfgModeVariableGuid
> +  gEfiNormalSetupGuid
> +  gEfiVlv2VariableGuid
> +
> +[Pcd.common]
> +  gPlatformModuleTokenSpaceGuid.PcdFlashFvMainBase
> +  gPlatformModuleTokenSpaceGuid.PcdFlashFvMainSize
> +  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Base
> +  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Size
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +  gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress
> +  gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize
> +[Depex]
> +  TRUE
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Stall.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Stall.c
> new file mode 100644
> index 0000000000..5e68f803db
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Stall.c
> @@ -0,0 +1,90 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  Stall.c
> +
> +Abstract:
> +
> +  Produce Stall Ppi.
> +
> +--*/
> +
> +
> +#include "CommonHeader.h"
> +#include "PlatformBaseAddresses.h"
> +#include "PchRegs.h"
> +
> +/**
> +  Waits for at least the given number of microseconds.
> +
> +  @param PeiServices     General purpose services available to every PEIM.
> +  @param This            PPI instance structure.
> +  @param Microseconds    Desired length of time to wait.
> +
> +  @retval EFI_SUCCESS    If the desired amount of time was passed.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Stall (
> +  IN CONST EFI_PEI_SERVICES   **PeiServices,
> +  IN CONST EFI_PEI_STALL_PPI      *This,
> +  IN UINTN              Microseconds
> +  )
> +{
> +  UINTN   Ticks;
> +  UINTN   Counts;
> +  UINT32  CurrentTick;
> +  UINT32  OriginalTick;
> +  UINT32  RemainingTick;
> +
> +  if (Microseconds == 0) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  OriginalTick = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_TMR);
> +  OriginalTick &= (V_PCH_ACPI_PM1_TMR_MAX_VAL - 1);
> +  CurrentTick = OriginalTick;
> +
> +  //
> +  // The timer frequency is 3.579545MHz, so 1 ms corresponds to 3.58 clocks
> +  //
> +  Ticks = Microseconds * 358 / 100 + OriginalTick + 1;
> +
> +  //
> +  // The loops needed for timer overflow
> +  //
> +  Counts = (UINTN)RShiftU64((UINT64)Ticks, 24);
> +
> +  //
> +  // Remaining clocks within one loop
> +  //
> +  RemainingTick = Ticks & 0xFFFFFF;
> +
> +  //
> +  // Do not intend to use TMROF_STS bit of register PM1_STS, because this
> add extra
> +  // one I/O operation, and may generate SMI
> +  //
> +  while (Counts != 0) {
> +    CurrentTick = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_TMR)
> & B_PCH_ACPI_PM1_TMR_VAL;
> +    if (CurrentTick <= OriginalTick) {
> +      Counts--;
> +    }
> +    OriginalTick = CurrentTick;
> +  }
> +
> +  while ((RemainingTick > CurrentTick) && (OriginalTick <= CurrentTick)) {
> +    OriginalTick  = CurrentTick;
> +    CurrentTick   = IoRead32 (ACPI_BASE_ADDRESS +
> R_PCH_ACPI_PM1_TMR) & B_PCH_ACPI_PM1_TMR_VAL;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.dec
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.dec
> new file mode 100644
> index 0000000000..4653f63a66
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.dec
> @@ -0,0 +1,211 @@
> +#/** @file
> +# Platform Package
> +#
> +# This package provides platform specific modules.
> +# Copyright (c) 2009  - 2015, Intel Corporation. All rights reserved.<BR>
> +#
> +
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> +
> +#
> +#
> +#**/
> +
> +[Defines]
> +  DEC_SPECIFICATION              = 0x00010005
> +  PACKAGE_NAME                   = PlatformPkg
> +  PACKAGE_GUID                   = 463B3B00-0D18-4a5f-90C0-D5B851D2574B
> +  PACKAGE_VERSION                = 0.1
> +
> +[Includes]
> +  .
> +  Include
> +  Include/Library
> +
> +[Ppis]
> +  gPeiSpeakerInterfacePpiGuid  = { 0x30ac275e, 0xbb30, 0x4b84, { 0xa1, 0xcd,
> 0x0a, 0xf1, 0x32, 0x2c, 0x89, 0xc0 }}
> +  gPeiUsbControllerPpiGuid     = { 0x3BC1F6DE, 0x693E, 0x4547, { 0xA3, 0x00,
> 0x21, 0x82, 0x3C, 0xA4, 0x20, 0xB2 }}
> +  gPeiMfgMemoryTestPpiGuid     = { 0xab294a92, 0xeaf5, 0x4cf3, { 0xab,
> 0x2b, 0x2d, 0x4b, 0xed, 0x4d, 0xb6, 0x3d }}
> +  gPeiSha256HashPpiGuid        = { 0x950e191b, 0x8524, 0x4f51, { 0x80, 0xa1,
> 0x5c, 0x4f, 0x1b, 0x03, 0xf3, 0x5c }}
> +
> +[Guids]
> +  gEfiPlatformBootModeGuid                = { 0xce845704, 0x1683, 0x4d38, { 0xa4,
> 0xf9, 0x7d, 0x0b, 0x50, 0x77, 0x57, 0x93 } }
> +  gEfiPlatformInfoGuid                    = { 0x1e2acc41, 0xe26a, 0x483d, { 0xaf, 0xc7,
> 0xa0, 0x56, 0xc3, 0x4e, 0x08, 0x7b } }
> +  gEfiMemoryConfigDataGuid                = { 0x80dbd530, 0xb74c, 0x4f11, { 0x8c,
> 0x03, 0x41, 0x86, 0x65, 0x53, 0x28, 0x31 } }
> +  gPlatformModuleTokenSpaceGuid           = { 0x69d13bf0, 0xaf91, 0x4d96,
> { 0xaa, 0x9f, 0x21, 0x84, 0xc5, 0xce, 0x3b, 0xc0 } }
> +  gEfiSerialPortTokenSpaceGuid            = { 0x5fad2389, 0x2bc7, 0x4bd2, { 0x83,
> 0xd3, 0x42, 0x9f, 0xb6, 0xae, 0xa3, 0x3f } }
> +  gEfiIchTokenSpaceGuid                   = { 0xe38c11e3, 0x968f, 0x47b8, { 0xac,
> 0xef, 0xac, 0xc0, 0x69, 0x3d, 0xb9, 0xff } }
> +  gEfiPchTokenSpaceGuid                   = { 0x89a1b278, 0xa1a1, 0x4df7, { 0xb1,
> 0x37, 0xde, 0x5a, 0xd7, 0xc4, 0x79, 0x13 } }
> +  gEfiSioVariableGuid                     = { 0x560bf58a, 0x1e0d, 0x4d7e, { 0x95, 0x3f,
> 0x29, 0x80, 0xa2, 0x61, 0xe0, 0x31 } }
> +  gProcessorProducerGuid                  = { 0x1bf06aea, 0x5bec, 0x4a8d, { 0x95,
> 0x76, 0x74, 0x9b, 0x09, 0x56, 0x2d, 0x30 } }
> +  gEfiPowerOnHobGuid                      = { 0x0468a601, 0xc535, 0x46fd, { 0xa9,
> 0x5d, 0xbb, 0xab, 0x99, 0x1b, 0x17, 0x8c } }
> +  gEfiPlatformCpuInfoGuid                 = { 0xbb9c7ab7, 0xb8d9, 0x4bf3, { 0x9c,
> 0x29, 0x9b, 0xf3, 0x41, 0xe2, 0x17, 0xbc } }
> +  gEfiBiosIdGuid                          = { 0xC3E36D09, 0x8294, 0x4b97, { 0xA8, 0x57,
> 0xD5, 0x28, 0x8F, 0xE3, 0x3E, 0x28 } }
> +  gEfiPlatformBootModeGuid                = { 0xce845704, 0x1683, 0x4d38, { 0xa4,
> 0xf9, 0x7d, 0x0b, 0x50, 0x77, 0x57, 0x93 } }
> +  gEfiBoardFeaturesGuid                   = { 0x94b9e8ae, 0x8877, 0x479a, { 0x98,
> 0x42, 0xf5, 0x97, 0x4b, 0x82, 0xce, 0xd3 } }
> +  gItkDataVarGuid                         = { 0x3812723d, 0x7e48, 0x4e29, { 0xbc, 0x27,
> 0xf5, 0xa3, 0x9a, 0xc9, 0x4e, 0xf1 } }
> +  gDmiDataGuid                            = { 0x70e56c5e, 0x280c, 0x44b0, { 0xa4, 0x97,
> 0x09, 0x68, 0x1a, 0xbc, 0x37, 0x5e } }
> +  gIdccDataHubGuid                        = { 0x788e1d9f, 0x1eab, 0x47d2, { 0xa2, 0xf3,
> 0x78, 0xca, 0xe8, 0x7d, 0x60, 0x12 } }
> +  gEfiSetupVariableGuid                   = { 0xec87d643, 0xeba4, 0x4bb5, { 0xa1,
> 0xe5, 0x3f, 0x3e, 0x36, 0xb2, 0x0d, 0xa9 } }
> +  gEfiPlatformInfoGuid                    = { 0x1e2acc41, 0xe26a, 0x483d, { 0xaf, 0xc7,
> 0xa0, 0x56, 0xc3, 0x4e, 0x08, 0x7b } }
> +  gMfgModeVariableGuid                    = { 0xEF14FD78, 0x0793, 0x4e2b, { 0xAC,
> 0x6D, 0x06, 0x28, 0x47, 0xE0, 0x17, 0x91 } }
> +  gEfiAcpiTableStorageGuid                = { 0x7e374e25, 0x8e01, 0x4fee, { 0x87,
> 0xf2, 0x39, 0x0c, 0x23, 0xc6, 0x06, 0xcd } }
> +  gACPIOSFRMfgStringVariableGuid          = { 0x72234213, 0x0fd7, 0x48a1,
> { 0xa5, 0x9f, 0xb4, 0x1b, 0xc1, 0x07, 0xfb, 0xcd } }
> +  gACPIOSFRRefDataBlockVariableGuid       = { 0x72234213, 0x0fd7, 0x48a1,
> { 0xa5, 0x9f, 0xb4, 0x1b, 0xc1, 0x07, 0xfb, 0xcd } }
> +  gACPIOSFRModelStringVariableGuid        = { 0xca1bcad9, 0xe021, 0x4547,
> { 0xa1, 0xb0, 0x5b, 0x22, 0xc7, 0xf6, 0x87, 0xf4 } }
> +  gEfiAcpiTableStorageGuid                = { 0x7e374e25, 0x8e01, 0x4fee, { 0x87,
> 0xf2, 0x39, 0x0c, 0x23, 0xc6, 0x06, 0xcd } }
> +  gEfiPciLanInfoGuid                      = { 0x0d9a1427, 0xe02a, 0x437d, { 0x92, 0x6b,
> 0xaa, 0x52, 0x1f, 0xd7, 0x22, 0xba } }
> +  gEfiNormalSetupGuid                     = { 0xec87d643, 0xeba4, 0x4bb5, { 0xa1,
> 0xe5, 0x3f, 0x3e, 0x36, 0xb2, 0x0d, 0xa9 } }
> +  gFirmwareIdGuid                         = { 0x5e559c23, 0x1faa, 0x4ae1, { 0x8d, 0x4a,
> 0xc6, 0xcf, 0x02, 0x6c, 0x76, 0x6f } }
> +  gBmpImageGuid                           = { 0x878AC2CC, 0x5343, 0x46F2, { 0xB5, 0x63,
> 0x51, 0xF8, 0x9D, 0xAF, 0x56, 0xBA } }
> +  gOsSelectionVariableGuid                = { 0x86843f56, 0x675d, 0x40a5, { 0x95,
> 0x30, 0xbc, 0x85, 0x83, 0x72, 0xf1, 0x03 } }
> +
> +[Protocols]
> +  gEfiActiveBiosProtocolGuid              = { 0xebbe2d1b, 0x1647, 0x4bda, { 0xab,
> 0x9a, 0x78, 0x63, 0xe3, 0x96, 0xd4, 0x1a } }
> +  gEfiPlatformCpuProtocolGuid             = { 0xbd26cdc9, 0xa092, 0x462a, { 0x87,
> 0x7a, 0x5a, 0xb6, 0xad, 0xce, 0x48, 0x12 } }
> +  gDxePchPlatformPolicyProtocolGuid       = { 0x4b0165a9, 0x61d6, 0x4e23,
> { 0xa0, 0xb5, 0x3e, 0xc7, 0x9c, 0x2e, 0x30, 0xd5 } }
> +  gEfiTpmMpDriverProtocolGuid             = { 0xde161cfe, 0x1e60, 0x42a1, { 0x8c,
> 0xc3, 0xee, 0x7e, 0xf0, 0x73, 0x52, 0x12 } }
> +  gEfiLpcWpce791PolicyProtocolGuid        = { 0xab2bee2f, 0xc1a6, 0x4399,
> { 0x85, 0x3d, 0xc0, 0x7c, 0x77, 0x4f, 0xfd, 0x0d } }
> +  gUsbPolicyGuid                          = { 0xf617b358, 0x12cf, 0x414a, { 0xa0, 0x69,
> 0x60, 0x67, 0x7b, 0xda, 0x13, 0xb4 } }
> +  gEfiSpeakerInterfaceProtocolGuid        = { 0x400b4476, 0x3081, 0x11d6,
> { 0x87, 0xed, 0x00, 0x06, 0x29, 0x45, 0xc3, 0xb9 } }
> +  gDxeVlvPlatformPolicyGuid               = { 0x5bab88ba, 0xe0e2, 0x4674, { 0xb6,
> 0xad, 0xb8, 0x12, 0xf6, 0x88, 0x1c, 0xd6 } }
> +  gEfiSmbiosSlotPopulationGuid            = { 0xef7bf7d6, 0xf8ff, 0x4a76, { 0x82,
> 0x47, 0xc0, 0xd0, 0xd1, 0xcc, 0x49, 0xc0 } }
> +  gObservableProtocolGuid                 = { 0xe227c522, 0xd5fe, 0x4a53, { 0x87,
> 0xb1, 0x0f, 0xbe, 0x57, 0x0f, 0x98, 0xe9 } }
> +  gEfiCk505ClockPlatformInfoGuid          = { 0x3c485ea4, 0x449a, 0x46ce,
> { 0xbb, 0x08, 0x2a, 0x33, 0x6e, 0xa9, 0x6b, 0x4e } }
> +  gEfiLpcWpc83627PolicyProtocolGuid       = { 0xd3ecc567, 0x9fd5, 0x44c1,
> { 0x86, 0xcf, 0x5d, 0xa7, 0xa2, 0x4f, 0x4b, 0x5d } }
> +  gEfiTcoResetProtocolGuid                = { 0xa6a79162, 0xe325, 0x4c30, { 0xbc,
> 0xc3, 0x59, 0x37, 0x30, 0x64, 0xef, 0xb3 } }
> +  gEfiWatchdogTimerDriverProtocolGuid     = { 0xd5b06d16, 0x2ea1, 0x4def,
> { 0x98, 0xd0, 0xa0, 0x5d, 0x40, 0x72, 0x84, 0x17 } }
> +  gEfiPlatformIdeInitProtocolGuid         = { 0x377c66a3, 0x8fe7, 0x4ee8, { 0x85,
> 0xb8, 0xf1, 0xa2, 0x82, 0x56, 0x9e, 0x3b } }
> +  gEfiPciPlatformProtocolGuid             = { 0x07d75280, 0x27d4, 0x4d69, { 0x90,
> 0xd0, 0x56, 0x43, 0xe2, 0x38, 0xb3, 0x41 } }
> +  gEnhancedSpeedstepProtocolGuid          = { 0x91a1ddcf, 0x5374, 0x4939,
> { 0x89, 0x51, 0xd7, 0x29, 0x3f, 0x1a, 0x78, 0x6f } }
> +  gEfiAcpiSupportProtocolGuid             = { 0xdbff9d55, 0x89b7, 0x46da, { 0xbd,
> 0xdf, 0x67, 0x7d, 0x3d, 0xc0, 0x24, 0x1d } }
> +  gEfiAcpiS3SaveProtocolGuid              = { 0x125f2de1, 0xfb85, 0x440c, { 0xa5,
> 0x4c, 0x4d, 0x99, 0x35, 0x8a, 0x8d, 0x38 } }
> +  gEfiCpuIoProtocolGuid                   = { 0xB0732526, 0x38C8, 0x4b40, { 0x88,
> 0x77, 0x61, 0xC7, 0xB0, 0x6A, 0xAC, 0x45 } }
> +  gPlatformGOPPolicyGuid                  = { 0xec2e931b, 0x3281, 0x48a5, { 0x81,
> 0x07, 0xdf, 0x8a, 0x8b, 0xed, 0x3c, 0x5d } }
> +  gEfiGopDisplayBrightnessProtocolGuid    = { 0x6ff23f1d, 0x877c, 0x4b1b,
> { 0x93, 0xfc, 0xf1, 0x42, 0xb2, 0xee, 0xa6, 0xa7 } }
> +  gEfiUsbKeyboardConnectGuid              = { 0xad9c4381, 0x1ede, 0x430c,
> { 0x8d, 0x42, 0x23, 0x76, 0x7c, 0x46, 0x5d, 0x52 } }
> +
> +
> +[PcdsFixedAtBuild]
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashNvStorageBase|0xFFF60000|UIN
> T32|0x20000007
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashNvStorageSize|0x00010000|UIN
> T32|0x20000008
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashNvStorageEventLogBase|0xFFF6
> C000|UINT32|0x30000007
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashNvStorageEventLogSize|0x00002
> 000|UINT32|0x30000008
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoveryBase|0xFFF80000|UI
> NT32|0x20000004
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoverySize|0x00080000|UI
> NT32|0x20000005
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashFvShellBase|0xFFF50000|UINT32
> |0x20000009
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashFvShellSize|0x00000000|UINT32
> |0x20000010
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashFvMainBase|0xFF800000|UINT3
> 2|0x20000001
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashFvMainSize|0x00500000|UINT32
> |0x20000002
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress|0xFF800000|U
> INT32|0x10000001
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize|0x00800000|UINT32|0
> x10000002
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashTestMenuBase|0xFF000000|UIN
> T32|0x20000011
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashTestMenuSize|0x00010000|UINT
> 32|0x20000012
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Base|0xFFFA0000|
> UINT32|0x20000013
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Size|0x00040000|UI
> NT32|0x20000014
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashMicroCodeAddress|0xFFF90000|
> UINT32|0x20000015
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashMicroCodeSize|0x00002000|UIN
> T32|0x20000016
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashMicroCode2Address|0xFFF92000
> |UINT32|0x20000017
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashMicroCode2Size|0x0000C800|UI
> NT32|0x20000018
> +
> gPlatformModuleTokenSpaceGuid.PcdIFWISigBaseAddress|0x0F00|UINT32|
> 0x20000019
> +
> gPlatformModuleTokenSpaceGuid.PcdPBTNDisableInterval|0x01F4|UINT32|
> 0x2000001A
> +
> gPlatformModuleTokenSpaceGuid.PcdTouchAttributes|2|UINT32|0x200000
> 20
> +
> gPlatformModuleTokenSpaceGuid.PcdTouchCIDString|"I2C05\\S004A"|VOID
> *|0x20000021
> +  gPlatformModuleTokenSpaceGuid.PcdFullIconFile             |{ 0x69, 0x00,
> 0x39, 0x82, 0x30, 0xa6, 0x4b, 0x4c, 0x85, 0xfc, 0x95, 0xe9, 0x49, 0xc9, 0xf0,
> 0x76 }|VOID*|0x20000022
> +  gPlatformModuleTokenSpaceGuid.PcdSimpleIconFile           |{ 0x4b, 0xf7,
> 0xee, 0x4b, 0x30, 0xa3, 0x49, 0x67, 0xa4, 0xad, 0xa4, 0xb1, 0xca, 0xe4, 0x4b,
> 0x0d }|VOID*|0x20000023
> +  gPlatformModuleTokenSpaceGuid.PcdCapitalLetterKeyboardFile|{ 0x82,
> 0x38, 0x75, 0xd8, 0x83, 0xa2, 0x4c, 0x37, 0xb6, 0xea, 0x04, 0xac, 0xc3, 0x06,
> 0x0f, 0x07 }|VOID*|0x20000024
> +  gPlatformModuleTokenSpaceGuid.PcdSmallLetterKeyboardFile  |{ 0x4c,
> 0x66, 0x39, 0xa2, 0x09, 0x0e, 0x4d, 0xc9, 0x9f, 0x55, 0x0f, 0xcb, 0x72, 0x60,
> 0x26, 0x11 }|VOID*|0x20000025
> +  gPlatformModuleTokenSpaceGuid.PcdDigitKeyboardFile        |{ 0x3f, 0xfe,
> 0x2c, 0x17, 0x92, 0x5d, 0x49, 0x7d, 0x87, 0x0a, 0x46, 0x14, 0xe4, 0x58, 0xd8,
> 0x5e }|VOID*|0x20000026
> +  gPlatformModuleTokenSpaceGuid.PcdSimpleKeyboardFile       |{ 0x5c,
> 0xd4, 0xfc, 0x98, 0xbf, 0x79, 0x41, 0x10, 0xa2, 0xd3, 0x87, 0xbe, 0x82, 0xd0,
> 0x90, 0x52 }|VOID*|0x20000027
> +
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashSpidOffset|0x1000|UINT32|0x20
> 00002A
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashSpidSize|0x00001000|UINT32|0x
> 2000002B
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashEmOffset|0x3000|UINT32|0x200
> 0002C
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashEmSize|0x1000|UINT32|0x20000
> 02D
> +
> +
> gEfiSerialPortTokenSpaceGuid.PcdSerialRegisterBase|0x3f8|UINT64|0x00000
> 001
> +
> gEfiSerialPortTokenSpaceGuid.PcdSerialBoudRate|115200|UINT32|0x000000
> 02
> +
> +
> gEfiPchTokenSpaceGuid.PcdPchAcpiIoPortBaseAddress|0x400|UINT16|0x00
> 00000B
> +
> +   ## FFS filename to find the shell application.
> +  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile|{ 0xB7, 0xD6,
> 0x7A, 0xC5, 0x15, 0x05, 0xA8, 0x40, 0x9D, 0x21, 0x55, 0x16, 0x52, 0x85, 0x4E,
> 0x37 }|VOID*|0x40000004
> +
> +
> gEfiIchTokenSpaceGuid.PcdPeiIchUhciControllerIoPortBaseAddress|0x4000|
> UINT16|0x30000017
> +
> gEfiIchTokenSpaceGuid.PcdPeiIchEhciControllerMemoryBaseAddress|0xFC0
> 00000|UINT32|0x30000019
> +
> +
> +
> gPlatformModuleTokenSpaceGuid.PcdRamLogBaseAddress|0x20000|UINT3
> 2|0x00000013
> +
> gPlatformModuleTokenSpaceGuid.PcdRamLogBaseLength|0x80000|UINT32
> |0x00000014
> +
> gPlatformModuleTokenSpaceGuid.PcdRamLogBaseCarAddress|0xFEF86000|
> UINT32|0x00000015
> +
> gPlatformModuleTokenSpaceGuid.PcdRamLogBaseCarLength|0x2000|UINT3
> 2|0x00000016
> +
> +
> +  #Pcd for Flash Update tool
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashChipBase|0xFF800000|UINT32|0
> x40000001
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashChipSize|0x00800000|UINT32|0x
> 40000002
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashDescriptorBase|0xFF800000|UIN
> T32|0x40000003
> +
> gPlatformModuleTokenSpaceGuid.PcdFlashDescriptorSize|0x00001000|UINT
> 32|0x40000004
> +
> gPlatformModuleTokenSpaceGuid.PcdTxeRomBase|0xFF801000|UINT32|0x
> 40000009
> +
> gPlatformModuleTokenSpaceGuid.PcdTxeRomSize|0x003FF000|UINT32|0x4
> 000000A
> +
> gPlatformModuleTokenSpaceGuid.PcdBiosRomBase|0xFFC00000|UINT32|0x
> 4000000B
> +
> gPlatformModuleTokenSpaceGuid.PcdBiosRomSize|0x00400000|UINT32|0x
> 4000000C
> +
> +  # PCDs for System Firmware FMP instance
> +
> gPlatformModuleTokenSpaceGuid.PcdSystemFirmwareFmpLowestSupporte
> dVersion|0x00000000|UINT32|0x40000100
> +
> gPlatformModuleTokenSpaceGuid.PcdSystemFirmwareFmpVersion|0x00000
> 000|UINT32|0x40000101
> +
> gPlatformModuleTokenSpaceGuid.PcdSystemFirmwareFmpVersionString|""
> |VOID*|0x40000102
> +
> +[PcdsFeatureFlag]
> +  ## This PCD specifies whether StatusCode is reported via ISA Serial port.
> +
> gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseIsaSerial|TRUE|BOOLEAN|
> 0x00000020
> +
> +  ## This PCD specifies whether StatusCode is reported via USB Serial port.
> +
> gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseUsbSerial|TRUE|BOOLEAN
> |0x00000021
> +
> +  ## This PCD specifies whether StatusCode is reported via RAM.
> +
> gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseRam|FALSE|BOOLEAN|0x0
> 0000022
> +
> +  ## Platform BDS PCD to control whether to dispatch additional option rom,
> e.g.: PXE, AHCI
> +
> gPlatformModuleTokenSpaceGuid.PcdBdsDispatchAdditionalOprom|TRUE|B
> OOLEAN|0x00000024
> +
> +  #new added feature for BIOS usb recovery
> +
> gEfiIchTokenSpaceGuid.PcdEhciRecoveryEnabled|TRUE|BOOLEAN|0x000000
> 26
> +
> +[PcdsDynamic,PcdsDynamicEx]
> +
> gPlatformModuleTokenSpaceGuid.PcdInConfigMode|FALSE|BOOLEAN|0x80
> 000001
> +
> gPlatformModuleTokenSpaceGuid.PcdConnectUSBKeyboardonWaitForKeyS
> troke|FALSE|BOOLEAN|0x80000002
> +
> gPlatformModuleTokenSpaceGuid.PcdEnableWatchdogSwSmiInputValue|0|
> UINT8|0x80000003
> +#
> +#device firmware update support
> +#
> +#I2C and SPI support
> +[Protocols]
> +
> +  gEfiMmioDeviceProtocolGuid = { 0x24486226, 0xf8c2, 0x41f5, { 0xb9, 0xdd,
> 0x78, 0x3e, 0x9e, 0x56, 0xde, 0xa0 } }
> +  gEfiI2cBusConfigurationManagementProtocolGuid = { 0x75032015, 0xd156,
> 0x423e, { 0xbf, 0xa3, 0x7a, 0x65, 0xab, 0xa4, 0x71, 0x5 } }
> +  gEfiI2cAcpiProtocolGuid = { 0xf30c2915, 0x5782, 0x4e6a, { 0xa8, 0x46, 0x5,
> 0xba, 0xbc, 0xe7, 0xb6, 0xa0 } }
> +  gEfiI2cMasterProtocolGuid = { 0x578c315a, 0x68cf, 0x4e81, { 0xb5, 0xc6,
> 0x22, 0xdb, 0x40, 0xd0, 0x10, 0xbc } }
> +  gEfiI2cHostProtocolGuid = { 0x70b221af, 0xfdff, 0x4fde, { 0x99, 0x68, 0x1a,
> 0xf6, 0x23, 0xa9, 0x56, 0xd9 } }
> +  gEfiI2cBusProtocolGuid = { 0x9fa1b225, 0x3346, 0x461b, { 0xa0, 0x69, 0xed,
> 0x1, 0xb6, 0x73, 0xd2, 0x40 } }
> +  gEfiI2cSlaveProtocolGuid = { 0xf2c1910e, 0xf5c9, 0x4b72, { 0xb2, 0x43, 0x6d,
> 0x59, 0x9, 0x6a, 0x79, 0xf0 } }
> +
> +#  gEfiSpiAcpiProtocolGuid = { 0x9f49a879, 0x3d71, 0x42b3, { 0xa0, 0xad,
> 0xdd, 0xb1, 0xf3, 0x30, 0x10, 0xa3 } }
> +#  gEfiSpiHostProtocolGuid = { 0x951b65e5, 0x8872, 0x41ed, { 0xad, 0x1d,
> 0xd5, 0x68, 0x1f, 0x4a, 0xf0, 0x33 } }
> +#  gEfiSpiBusProtocolGuid =  { 0x137b3044, 0xf6d7, 0x473e, { 0xa6, 0x25, 0x9f,
> 0xb9, 0x25, 0x5, 0xc1, 0x80 } }
> +
> +#  gLpssDummyProtocolGuid = { 0xaf4cc162, 0xd41c, 0x455a, { 0xab, 0x45,
> 0x6d, 0xbc, 0xc1, 0xcd, 0x32, 0xf3 } }
> +  gEfiSpiProtocolGuid               = { 0x1156efc6, 0xea32, 0x4396, { 0xb5, 0xd5,
> 0x26, 0x93, 0x2e, 0x83, 0xc3, 0x13 }}
> +  gEfiGpioOperationProtocolGuid     = { 0x38DDFE8F, 0x8991, 0x44AA, { 0x98,
> 0x89, 0x83, 0xF4, 0x91, 0x84, 0x65, 0xB0 }}
> +  gEfiEsrtOperationProtocolGuid     = { 0x4549AB47, 0x6E60, 0x4293, { 0xB9,
> 0x1D, 0x31, 0xB6, 0x10, 0xAD, 0x80, 0x56 }}
> +
> +[Guids]
> +  gEfiFwDisplayCapsuleGuid       = { 0x3b8c8162, 0x188c, 0x46a4, { 0xae, 0xc9,
> 0xbe, 0x43, 0xf1, 0xd6, 0x56, 0x97 } }
> +  gEfiFirmwareClassGuid          = { 0xb122a262, 0x3551, 0x4f48, { 0x88, 0x92,
> 0x55, 0xf6, 0xc0, 0x61, 0x42, 0x90 } }
> +  gEfiDFUVerGuid                 = { 0x0dc73aed, 0xcbf6, 0x4a25, { 0xa6, 0x8d, 0x59,
> 0xc8, 0x0f, 0x44, 0xc7, 0xc3 } }
> +  gEfiEsrtTableGuid              = { 0xb122a263, 0x3661, 0x4f68, { 0x99, 0x29, 0x78,
> 0xf8, 0xb0, 0xd6, 0x21, 0x80 } }
> +  gEfiCapsuleCrashLogVarGuid     = { 0xf3ff1468, 0x04ba, 0x4966, { 0x9f, 0xb2,
> 0xe4, 0xa7, 0x90, 0x05, 0x46, 0x50 } }
> +  gEfiCapsuleCrashGuid           = { 0x0e1d2972, 0x65af, 0x4ac1, { 0xbf, 0xa3,
> 0xce, 0xf4, 0xab, 0x0c, 0x38, 0xfe } }
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf
> new file mode 100644
> index 0000000000..098602b9d8
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf
> @@ -0,0 +1,1073 @@
> +#/** @file
> +# FDF file of Platform.
> +#
> +# Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +#**/
> +
> +[Defines]
> +DEFINE FLASH_BASE       = 0xFFC00000     #The base address of the 4Mb
> FLASH Device.
> +DEFINE FLASH_SIZE       = 0x00400000     #The flash size in bytes of the 4Mb
> FLASH Device.
> +DEFINE FLASH_BLOCK_SIZE = 0x1000        #The block size in bytes of the 4Mb
> FLASH Device.
> +DEFINE FLASH_NUM_BLOCKS = 0x400           #The number of blocks in 4Mb
> FLASH Device.
> +DEFINE FLASH_AREA_BASE_ADDRESS                                = 0xFF800000
> +DEFINE FLASH_AREA_SIZE                                        = 0x00800000
> +
> +DEFINE FLASH_REGION_VLVMICROCODE_OFFSET                       = 0x00000000
> +DEFINE FLASH_REGION_VLVMICROCODE_SIZE                         = 0x00040000
> +DEFINE FLASH_REGION_VLVMICROCODE_BASE                         = 0xFFC00000
> +
> +DEFINE FLASH_REGION_VPD_OFFSET                                = 0x00040000
> +DEFINE FLASH_REGION_VPD_SIZE                                  = 0x0003E000
> +
> +DEFINE
> FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_WORKING_OFFSET =
> 0x0007E000
> +DEFINE
> FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_WORKING_SIZE   =
> 0x00002000
> +
> +
> +DEFINE
> FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_SPARE_OFFSET   =
> 0x00080000
> +DEFINE FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_SPARE_SIZE
> = 0x00040000
> +
> +!if $(MINNOW2_FSP_BUILD) == TRUE
> +DEFINE FLASH_REGION_FSPBIN_OFFSET                             = 0x000C0000
> +DEFINE FLASH_REGION_FSPBIN_SIZE                               = 0x00048000
> +DEFINE FLASH_REGION_FSPBIN_BASE                               = 0xFFCC0000
> +
> +DEFINE FLASH_REGION_AZALIABIN_OFFSET                          = 0x00108000
> +DEFINE FLASH_REGION_AZALIABIN_SIZE                            = 0x00008000
> +DEFINE FLASH_REGION_AZALIABIN_BASE                            = 0xFFD08000
> +
> +!endif
> +
> +DEFINE FLASH_REGION_FVMAIN_OFFSET                             = 0x00110000
> +DEFINE FLASH_REGION_FVMAIN_SIZE                               = 0x00210000
> +
> +DEFINE FLASH_REGION_FV_RECOVERY2_OFFSET                       = 0x00320000
> +DEFINE FLASH_REGION_FV_RECOVERY2_SIZE                         = 0x00070000
> +
> +DEFINE FLASH_REGION_FV_RECOVERY_OFFSET                        = 0x00390000
> +DEFINE FLASH_REGION_FV_RECOVERY_SIZE                          = 0x00070000
> +
> +#########################################################
> #######################
> +#
> +# FD Section
> +# The [FD] Section is made up of the definition statements and a
> +# description of what goes into  the Flash Device Image.  Each FD section
> +# defines one flash "device" image.  A flash device image may be one of
> +# the following: Removable media bootable image (like a boot floppy
> +# image,) an Option ROM image (that would be "flashed" into an add-in
> +# card,) a System "Flash"  image (that would be burned into a system's
> +# flash) or an Update ("Capsule") image that will be used to update and
> +# existing system flash.
> +#
> +#########################################################
> #######################
> +[FD.Vlv]
> +BaseAddress   =
> $(FLASH_BASE)|gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddre
> ss #The base address of the 3Mb FLASH Device.
> +Size          =
> $(FLASH_SIZE)|gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize
> #The flash size in bytes of the 3Mb FLASH Device.
> +ErasePolarity = 1
> +BlockSize     = $(FLASH_BLOCK_SIZE)          #The block size in bytes of the 3Mb
> FLASH Device.
> +NumBlocks     = $(FLASH_NUM_BLOCKS)          #The number of blocks in 3Mb
> FLASH Device.
> +
> +#
> +#Flash location override based on actual flash map
> +#
> +SET gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress            =
> $(FLASH_AREA_BASE_ADDRESS)
> +SET gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize                   =
> $(FLASH_AREA_SIZE)
> +
> +SET gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress =
> $(FLASH_REGION_VLVMICROCODE_BASE) + 0x60
> +SET gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize =
> $(FLASH_REGION_VLVMICROCODE_SIZE) - 0x60
> +
> +!if $(MINNOW2_FSP_BUILD) == TRUE
> +# put below PCD value setting into dsc file
> +#SET gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress
> = $(FLASH_REGION_VLVMICROCODE_BASE)
> +#SET gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize
> = $(FLASH_REGION_VLVMICROCODE_SIZE)
> +#SET gFspWrapperTokenSpaceGuid.PcdFlashMicroCodeOffset                    =
> 0x60
> +#SET gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheAddress                   =
> $(FLASH_AREA_BASE_ADDRESS)
> +#SET gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheSize                      =
> $(FLASH_AREA_SIZE)
> +#SET gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase                          =
> $(FLASH_REGION_FSPBIN_BASE)
> +#SET gFspWrapperTokenSpaceGuid.PcdFlashFvFspSize                          =
> $(FLASH_REGION_FSPBIN_SIZE)
> +
> +!endif
> +#########################################################
> #######################
> +#
> +# Following are lists of FD Region layout which correspond to the locations
> of different
> +# images within the flash device.
> +#
> +# Regions must be defined in ascending order and may not overlap.
> +#
> +# A Layout Region start with a eight digit hex offset (leading "0x" required)
> followed by
> +# the pipe "|" character, followed by the size of the region, also in hex with
> the leading
> +# "0x" characters. Like:
> +# Offset|Size
> +# PcdOffsetCName|PcdSizeCName
> +# RegionType <FV, DATA, or FILE>
> +# Fv Size can be adjusted; FVMAIN_COMPACT can be reduced to 0x120000,
> and FV_RECOVERY can be enlarged to 0x80000
> +#
> +#########################################################
> #######################
> +  #
> +  # CPU Microcodes
> +  #
> +
> +$(FLASH_REGION_VLVMICROCODE_OFFSET)|$(FLASH_REGION_VLVMICR
> OCODE_SIZE)
> +gPlatformModuleTokenSpaceGuid.PcdFlashMicroCodeAddress|gPlatform
> ModuleTokenSpaceGuid.PcdFlashMicroCodeSize
> +FV = MICROCODE_FV
> +$(FLASH_REGION_VPD_OFFSET)|$(FLASH_REGION_VPD_SIZE)
> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gEfi
> MdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
> +#NV_VARIABLE_STORE
> +DATA = {
> +  ## This is the EFI_FIRMWARE_VOLUME_HEADER
> +  # ZeroVector []
> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +  # FileSystemGuid: gEfiSystemNvDataFvGuid         =
> +  #  { 0xFFF12B8D, 0x7696, 0x4C8B, { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F,
> 0x50 }}
> +  0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
> +  0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
> +  # FvLength: 0x80000
> +  0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
> +  #Signature "_FVH"       #Attributes
> +  0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,
> +  #HeaderLength #CheckSum #ExtHeaderOffset #Reserved #Revision
> +  0x48, 0x00, 0x2A, 0x09, 0x00, 0x00, 0x00, 0x02,
> +  #Blockmap[0]: 7 Blocks * 0x10000 Bytes / Block
> +  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
> +  #Blockmap[1]: End
> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +  ## This is the VARIABLE_STORE_HEADER
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  #Signature: gEfiAuthenticatedVariableGuid =
> +  #  { 0xaaf32c78, 0x947b, 0x439a, { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77,
> 0x92 }}
> +  0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,
> +  0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,
> +!else
> +  #Signature: gEfiVariableGuid =
> +  #  { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe,
> 0x7d }}
> +  0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41,
> +  0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d,
> +!endif
> +  #Size: 0x3E000
> (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - 0x48
> (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x03DFB8
> +  # This can speed up the Variable Dispatch a bit.
> +  0xB8, 0xDF, 0x03, 0x00,
> +  #FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1:
> UINT32
> +  0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
> +}
> +
> +
> +$(FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_WORKING_OFFSET
> )|$(FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_WORKING_SIZE)
> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|g
> EfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
> +#NV_FTW_WORKING
> +DATA = {
> +  # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature =
> gEdkiiWorkingBlockSignatureGuid         =
> +  #  { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b,
> 0x95 }}
> +  0x2B, 0x29, 0x58, 0x9E, 0x68, 0x7C, 0x7D, 0x49,
> +  0xA0, 0xCE, 0x65, 0x0,  0xFD, 0x9F, 0x1B, 0x95,
> +
> +  # Crc:UINT32            #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
> +  0xE2, 0x33, 0xF2, 0x3,  0xFE, 0xFF, 0xFF, 0xFF,
> +  # WriteQueueSize: UINT64 #Size: 0x2000 - 0x20 (FTW_WORKING_HEADER)
> = 0x1FE0
> +  0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
> +}
> +
> +$(FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_SPARE_OFFSET)|$(
> FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_SPARE_SIZE)
> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfi
> MdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
> +
> +!if $(MINNOW2_FSP_BUILD) == TRUE
> +
> +  $(FLASH_REGION_FSPBIN_OFFSET)|$(FLASH_REGION_FSPBIN_SIZE)
> +
> gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase|gFspWrapperTokenSpace
> Guid.PcdFlashFvFspSize
> +  FILE = Vlv2SocBinPkg/FspBinary/FvFsp.bin
> +
> +
> +
> $(FLASH_REGION_AZALIABIN_OFFSET)|$(FLASH_REGION_AZALIABIN_SIZE)
> +  FILE = Vlv2TbltDevicePkg/FspAzaliaConfigData/AzaliaConfig.bin
> +
> +!endif
> +
> +  #
> +  # Main Block
> +  #
> +$(FLASH_REGION_FVMAIN_OFFSET)|$(FLASH_REGION_FVMAIN_SIZE)
> +gPlatformModuleTokenSpaceGuid.PcdFlashFvMainBase|gPlatformModule
> TokenSpaceGuid.PcdFlashFvMainSize
> +FV = FVMAIN_COMPACT
> +
> +  #
> +  # FV Recovery#2
> +  #
> +$(FLASH_REGION_FV_RECOVERY2_OFFSET)|$(FLASH_REGION_FV_RECOV
> ERY2_SIZE)
> +gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Base|gPlatformM
> oduleTokenSpaceGuid.PcdFlashFvRecovery2Size
> +FV = FVRECOVERY2
> +
> +  #
> +  # FV Recovery
> +  #
> +$(FLASH_REGION_FV_RECOVERY_OFFSET)|$(FLASH_REGION_FV_RECOVE
> RY_SIZE)
> +gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoveryBase|gPlatformMo
> duleTokenSpaceGuid.PcdFlashFvRecoverySize
> +FV = FVRECOVERY
> +
> +#########################################################
> #######################
> +#
> +# FV Section
> +#
> +# [FV] section is used to define what components or modules are placed
> within a flash
> +# device file.  This section also defines order the components and modules
> are positioned
> +# within the image.  The [FV] section consists of define statements, set
> statements and
> +# module statements.
> +#
> +#########################################################
> #######################
> +[FV.MICROCODE_FV]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = FALSE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +
> +FILE RAW = 197DB236-F856-4924-90F8-CDF12FB875F3 {
> +
> $(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/$(DXE_ARCHITEC
> TURE)/MicrocodeUpdates.bin
> +}
> +
> +!if $(RECOVERY_ENABLE)
> +[FV.FVRECOVERY_COMPONENTS]
> +FvAlignment        = 16         #FV alignment and FV attributes setting.
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +
> +INF  RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chUsb.inf
> +INF  MdeModulePkg/Bus/Pci/EhciPei/EhciPei.inf
> +INF  MdeModulePkg/Bus/Usb/UsbBusPei/UsbBusPei.inf
> +INF  MdeModulePkg/Bus/Usb/UsbBotPei/UsbBotPei.inf
> +INF  FatPkg/FatPei/FatPei.inf
> +INF  MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf
> +INF
> SignedCapsulePkg/Universal/RecoveryModuleLoadPei/RecoveryModuleLoa
> dPei.inf
> +!endif
> +
> +#########################################################
> #######################
> +#
> +# FV Section
> +#
> +# [FV] section is used to define what components or modules are placed
> within a flash
> +# device file.  This section also defines order the components and modules
> are positioned
> +# within the image.  The [FV] section consists of define statements, set
> statements and
> +# module statements.
> +#
> +#########################################################
> #######################
> +[FV.FVRECOVERY2]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16         #FV alignment and FV attributes setting.
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +FvNameGuid         = B73FE497-B92E-416e-8326-45AD0D270092
> +
> +
> +
> +INF $(PLATFORM_PACKAGE)/PlatformInitPei/PlatformInitPei.inf
> +
> +!if $(MINNOW2_FSP_BUILD) == FALSE
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chSmbusArpDisabled.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/Vl
> vInitPeim.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chInitPeim.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chSpiPeim.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> eiSmmAccess.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> eiSmmControl.inf
> +INF UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/M
> pS3.inf
> +!endif
> +
> +# INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/Pi
> SmmCommunicationPei.inf
> +!if $(TPM_ENABLED) == TRUE
> +INF SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
> +INF SecurityPkg/Tcg/TcgPei/TcgPei.inf
> +INF SecurityPkg/Tcg/PhysicalPresencePei/PhysicalPresencePei.inf
> +!endif
> +!if $(FTPM_ENABLE) == TRUE
> +INF  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf #use PCD config
> +!endif
> +INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
> +
> +!if $(ACPI50_ENABLE) == TRUE
> + INF
> MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/Firmwa
> rePerformancePei.inf
> +!endif
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +INF
> MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCode
> RouterPei.inf
> +!endif
> +
> +!if $(RECOVERY_ENABLE)
> +FILE FV_IMAGE = 1E9D7604-EF45-46a0-BD8A-71AC78C17AC1 {
> +  SECTION PEI_DEPEX_EXP = {gEfiPeiMemoryDiscoveredPpiGuid AND
> gEfiPeiBootInRecoveryModePpiGuid}
> +  SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF {    # LZMA
> COMPRESS GUID
> +    SECTION FV_IMAGE = FVRECOVERY_COMPONENTS
> +  }
> +}
> +!endif
> +
> +[FV.FVRECOVERY]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16         #FV alignment and FV attributes setting.
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +FvNameGuid         = B73FE497-B92E-416e-8326-45AD0D270091
> +
> +
> +!if $(MINNOW2_FSP_BUILD) == TRUE
> +INF IntelFspWrapperPkg/FspWrapperSecCore/FspWrapperSecCore.inf
> +!else
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/S
> ecCore.inf
> +!endif
> +
> +INF MdeModulePkg/Core/Pei/PeiMain.inf
> +!if $(MINNOW2_FSP_BUILD) == TRUE
> +INF Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.inf
> +INF IntelFspWrapperPkg/FspInitPei/FspInitPei.inf
> +!endif
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/C
> puPeim.inf
> +INF
> MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
> +INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
> +
> +INF $(PLATFORM_PACKAGE)/PlatformPei/PlatformPei.inf
> +
> +!if $(MINNOW2_FSP_BUILD) == FALSE
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/S
> eCUma.inf
> +!endif
> +
> +!if $(FTPM_ENABLE) == TRUE
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/fT
> PMInitPeim.inf
> +!endif
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +  INF  SourceLevelDebugPkg/DebugAgentPei/DebugAgentPei.inf
> +!endif
> +
> +
> +!if $(CAPSULE_ENABLE) == TRUE
> +INF  MdeModulePkg/Universal/CapsulePei/CapsulePei.inf
> +!if $(DXE_ARCHITECTURE) == "X64"
> +INF  MdeModulePkg/Universal/CapsulePei/CapsuleX64.inf
> +!endif
> +!endif
> +
> +!if $(MINNOW2_FSP_BUILD) == FALSE
> +!if $(PCIESC_ENABLE) == TRUE
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chEarlyInitPeim.inf
> +!endif
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/M
> emoryInit.inf
> +!endif
> +
> +INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
> +
> +[FV.FVMAIN]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +FvNameGuid         = A881D567-6CB0-4eee-8435-2E72D33E45B5
> +
> +APRIORI DXE {
> +  INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
> +  INF
> MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportSt
> atusCodeRouterRuntimeDxe.inf
> +  INF
> MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHan
> dlerRuntimeDxe.inf
> +  }
> +
> +FILE FREEFORM = C3E36D09-8294-4b97-A857-D5288FE33E28 {
> +    SECTION RAW =
> $(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/$(DXE_ARCHITEC
> TURE)/BiosId.bin
> +  }
> +
> +  #
> +  # EDK II Related Platform codes
> +  #
> +
> +  !if $(MINNOW2_FSP_BUILD) == TRUE
> +  INF IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.inf
> +  !endif
> +
> +INF MdeModulePkg/Core/Dxe/DxeMain.inf
> +INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
> +!if $(ACPI50_ENABLE) == TRUE
> +INF
> MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/Firmw
> arePerformanceDxe.inf
> +INF
> MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/Firm
> warePerformanceSmm.inf
> +!endif
> +
> +
> +INF IntelFrameworkModulePkg/Universal/CpuIoDxe/CpuIoDxe.inf
> +INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
> +INF
> MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportSt
> atusCodeRouterRuntimeDxe.inf
> +INF
> MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHan
> dlerRuntimeDxe.inf
> +INF
> MdeModulePkg/Universal/ReportStatusCodeRouter/Smm/ReportStatusCod
> eRouterSmm.inf
> +INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
> +INF UefiCpuPkg/CpuDxe/CpuDxe.inf
> +INF $(PLATFORM_PACKAGE)/Metronome/Metronome.inf
> +INF IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf
> +!if $(ARCH) == IA32
> +INF USE=IA32 MdeModulePkg/Logo/Logo.inf
> +!else
> +INF USE=X64 MdeModulePkg/Logo/Logo.inf
> +!endif
> +INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
> +INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
> +INF
> MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.in
> f
> +INF
> IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3SaveDxe.i
> nf
> +
> +INF
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.i
> nf
> +INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
> +INF $(PLATFORM_PACKAGE)/FvbRuntimeDxe/FvbSmm.inf
> +INF
> MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.i
> nf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchSpiSmm.inf
> +!if $(SECURE_BOOT_ENABLE)
> +INF
> SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfi
> gDxe.inf
> +!endif
> +
> +INF
> MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
> +
> +INF
> MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCoun
> terRuntimeDxe.inf
> +INF
> PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntime
> Dxe.inf
> +INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
> +INF $(PLATFORM_PACKAGE)/FvbRuntimeDxe/FvbRuntimeDxe.inf
> +
> +
> +INF $(PLATFORM_PACKAGE)/PlatformSetupDxe/PlatformSetupDxe.inf
> +
> +!if $(DATAHUB_ENABLE) == TRUE
> +INF IntelFrameworkModulePkg/Universal/DataHubDxe/DataHubDxe.inf
> +!endif
> +INF
> IntelFrameworkModulePkg/Universal/StatusCode/DatahubStatusCodeHandl
> erDxe/DatahubStatusCodeHandlerDxe.inf
> +INF
> MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryT
> estDxe.inf
> +
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/Dptf.inf
> +
> +  #
> +  # EDK II Related Silicon codes
> +  #
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchS3SupportDxe.inf
> +
> +!if $(USE_HPET_TIMER) == TRUE
> +INF PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf
> +!else
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SmartTimer.inf
> +!endif
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SmmControl.inf
> +
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchSmbusDxe.inf
> +
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/IntelPchLegacyInterrupt.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchReset.inf
> +
> +!if $(MINNOW2_FSP_BUILD) == FALSE
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchInitDxe.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchInitSmm.inf
> +!endif
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchSmiDispatcher.inf
> +!if $(PCIESC_ENABLE) == TRUE
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchPcieSmm.inf
> +!endif
> +
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchSpiRuntime.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchPolicyInitDxe.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchBiosWriteProtect.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SmmAccess.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PciHostBridge.inf
> +!if $(MINNOW2_FSP_BUILD) == FALSE
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/VlvInitDxe.inf
> +!else
> +INF
> IntelFrameworkModulePkg/Universal/LegacyRegionDxe/LegacyRegionDxe.i
> nf
> +INF Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInitDxe.inf
> +!endif
> +!if $(MINNOW2_FSP_BUILD) == FALSE
> +  !if $(SEC_ENABLE) == TRUE
> +  INF  RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/HeciDrv.inf
> +  INF  RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SeCPolicyInitDxe.inf
> +  !endif
> +!endif
> +!if $(TPM_ENABLED) == TRUE
> +INF SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf
> +INF SecurityPkg/Tcg/TcgDxe/TcgDxe.inf
> +INF RuleOverride = DRIVER_ACPITABLE
> SecurityPkg/Tcg/TcgSmm/TcgSmm.inf
> +!endif
> +!if $(FTPM_ENABLE) == TRUE
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/T
> pm2DeviceSeCPei.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/Tpm2DeviceSeCDxe.inf
> +INF SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf
> +INF SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/FtpmSmm.inf
> +!endif
> +
> +#
> +# EDK II Related Platform codes
> +#
> +INF $(PLATFORM_PACKAGE)/PlatformSmm/PlatformSmm.inf
> +INF $(PLATFORM_PACKAGE)/PlatformInfoDxe/PlatformInfoDxe.inf
> +INF $(PLATFORM_PACKAGE)/PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf
> +INF $(PLATFORM_PACKAGE)/PlatformDxe/PlatformDxe.inf
> +INF $(PLATFORM_PACKAGE)/PciPlatform/PciPlatform.inf
> +INF $(PLATFORM_PACKAGE)/SaveMemoryConfig/SaveMemoryConfig.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PlatformCpuPolicy.inf
> +INF $(PLATFORM_PACKAGE)/PpmPolicy/PpmPolicy.inf
> +INF
> $(PLATFORM_PACKAGE)/SmramSaveInfoHandlerSmm/SmramSaveInfoHand
> lerSmm.inf
> +!if $(GOP_DRIVER_ENABLE) == TRUE
> + INF $(PLATFORM_PACKAGE)/PlatformGopPolicy/PlatformGopPolicy.inf
> + FILE DRIVER = FF0C8745-3270-4439-B74F-3E45F8C77064 {
> +  SECTION DXE_DEPEX_EXP = {gPlatformGOPPolicyGuid}
> +  SECTION PE32 =
> Vlv2SocBinPkg/GOP/7.2.1011/RELEASE_VS2008x86/$(DXE_ARCHITECTURE)/I
> ntelGopDriver.efi
> +  SECTION UI = "IntelGopDriver"
> +}
> +!endif
> +
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PnpDxe.inf
> +  #
> +  # SMM
> +  #
> +INF MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
> +INF MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
> +INF UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
> +
> +INF UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
> +INF MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
> +INF UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
> +INF
> $(PLATFORM_PACKAGE)/SmmSwDispatch2OnSmmSwDispatchThunk/SmmS
> wDispatch2OnSmmSwDispatchThunk.inf
> +
> +#
> +# Remove the following two SMM binary modules that prevent platform
> from booting to UEFI Shell
> +#
> +#INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PowerManagement2.inf
> +#INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/DigitalThermalSensor.inf
> +
> +  #
> +  # ACPI
> +  #
> +INF
> MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutor
> Dxe.inf
> +INF $(PLATFORM_PACKAGE)/BootScriptSaveDxe/BootScriptSaveDxe.inf
> +INF
> IntelFrameworkModulePkg/Universal/Acpi/AcpiSupportDxe/AcpiSupportDx
> e.inf
> +INF RuleOverride = ACPITABLE2
> Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTable
> s/PowerManagementAcpiTables.inf
> +
> +INF RuleOverride = ACPITABLE
> $(PLATFORM_RC_PACKAGE)/AcpiTablesPCAT/AcpiTables.inf
> +
> +INF $(PLATFORM_PACKAGE)/AcpiPlatform/AcpiPlatform.inf
> +
> +INF
> MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraph
> icsResourceTableDxe.inf
> +
> +  #
> +  # PCI
> +  #
> +INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
> +
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/ISPDxe.inf
> +
> +
> +#
> +# ISA
> +#
> +INF $(PLATFORM_PACKAGE)/Wpce791/Wpce791.inf
> +INF IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBusDxe.inf
> +INF IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaIoDxe.inf
> +!if $(SOURCE_DEBUG_ENABLE) != TRUE
> +INF  IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf
> +!endif
> +#INF IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf
> +#INF
> IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf
> +
> +#
> +# SDIO
> +#
> +#INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/MmcHost.inf
> +#INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/MmcMediaDevice.inf
> +#
> +# IDE/SCSI/AHCI
> +#
> +INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
> +
> +INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
> +
> +INF
> MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
> +!if $(SATA_ENABLE) == TRUE
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SataController.inf
> +#
> +
> +#
> +INF MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
> +INF MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
> +!if $(SCSI_ENABLE) == TRUE
> +INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
> +INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
> +!endif
> +#
> +!endif
> +# Console
> +#
> +INF
> MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
> +INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
> +INF
> MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleD
> xe.inf
> +INF
> IntelFrameworkModulePkg/Universal/Console/VgaClassDxe/VgaClassDxe.in
> f
> +INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
> +INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
> +INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
> +INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
> +  #
> +  # USB
> +  #
> +!if $(USB_ENABLE) == TRUE
> +INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
> +INF MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
> +INF
> MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
> +INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
> +INF MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
> +INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
> +INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
> +!endif
> +
> +
> +  #
> +  # SMBIOS
> +  #
> +INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
> +INF $(PLATFORM_PACKAGE)/SmBiosMiscDxe/SmBiosMiscDxe.inf
> +
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SmbiosMemory.inf
> +
> +
> +#
> +# FAT file system
> +#
> +INF FatPkg/EnhancedFatDxe/Fat.inf
> +
> +#
> +# UEFI Shell
> +#
> +INF  ShellPkg/Application/Shell/Shell.inf
> +
> +#
> +# dp command
> +#
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +INF
> ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf
> +!endif
> +
> +!if $(GOP_DRIVER_ENABLE) == TRUE
> +FILE FREEFORM = 878AC2CC-5343-46F2-B563-51F89DAF56BA {
> +  SECTION RAW = Vlv2SocBinPkg/GOP/7.2.1011/VBT/MNW2/Vbt.bin
> +  SECTION UI = "IntelGopVbt"
> +}
> +!endif
> +
> +#
> +# Network Modules
> +#
> +!if $(NETWORK_ENABLE) == TRUE
> +  FILE DRIVER = 22DE1691-D65D-456a-993E-A253DD1F308C {
> +    SECTION PE32 =
> Vlv2SocBinPkg/UNDI/RtkUndiDxe/$(DXE_ARCHITECTURE)/RtkUndiDxe.efi
> +    SECTION UI = "UNDI"
> +  }
> +  INF  MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf
> +  INF  MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
> +  INF  MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
> +  INF  MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
> +  INF  MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
> +  INF  MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
> +  INF  MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
> +  INF  MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
> +  INF  NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
> +  INF  NetworkPkg/TcpDxe/TcpDxe.inf
> +  !if $(NETWORK_IP6_ENABLE) == TRUE
> +  INF  NetworkPkg/Ip6Dxe/Ip6Dxe.inf
> +  INF  NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
> +  INF  NetworkPkg/Udp6Dxe/Udp6Dxe.inf
> +  INF  NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
> +  !endif
> +  !if $(NETWORK_VLAN_ENABLE) == TRUE
> +  INF
> MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf
> +  !endif
> +  !if $(NETWORK_ISCSI_ENABLE) == TRUE
> +    INF  NetworkPkg/IScsiDxe/IScsiDxe.inf
> +  !endif
> +!endif
> +
> +!if $(CAPSULE_ENABLE)
> +INF  MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxe.inf
> +
> +#
> +# Minnow Max System Firmware FMP
> +#
> +INF  FILE_GUID = $(FMP_MINNOW_MAX_SYSTEM)
> FmpDevicePkg/FmpDxe/FmpDxe.inf
> +
> +#
> +# Sample Device FMP
> +#
> +INF  FILE_GUID = $(FMP_GREEN_SAMPLE_DEVICE)
> FmpDevicePkg/FmpDxe/FmpDxe.inf
> +INF  FILE_GUID = $(FMP_BLUE_SAMPLE_DEVICE)
> FmpDevicePkg/FmpDxe/FmpDxe.inf
> +INF  FILE_GUID = $(FMP_RED_SAMPLE_DEVICE)
> FmpDevicePkg/FmpDxe/FmpDxe.inf
> +
> +!endif
> +
> +!if $(MICOCODE_CAPSULE_ENABLE)
> +INF
> IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDx
> e.inf
> +!endif
> +
> +!if $(RECOVERY_ENABLE)
> +FILE FREEFORM =
> PCD(gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiRsa2048Sha256TestPubli
> cKeyFileGuid) {
> +     SECTION RAW =
> BaseTools/Source/Python/Rsa2048Sha256Sign/TestSigningPublicKey.bin
> +     SECTION UI = "Rsa2048Sha256TestSigningPublicKey"
> +     }
> +!endif
> +
> +[FV.FVMAIN_COMPACT]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +
> +
> +
> +FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
> +!if $(LZMA_ENABLE) == TRUE
> +# LZMA Compress
> +       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF
> PROCESSING_REQUIRED = TRUE {
> +          SECTION FV_IMAGE = FVMAIN
> +       }
> +!else
> +!if $(DXE_COMPRESS_ENABLE) == TRUE
> +# Tiano Compress
> +       SECTION GUIDED A31280AD-481E-41B6-95E8-127F4C984779
> PROCESSING_REQUIRED = TRUE {
> +          SECTION FV_IMAGE = FVMAIN
> +       }
> +!else
> +# No Compress
> +       SECTION COMPRESS PI_NONE {
> +          SECTION FV_IMAGE = FVMAIN
> +       }
> +!endif
> +!endif
> +     }
> +
> +[FV.SETUP_DATA]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +#NumBlocks         = 0x10
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +
> +#########################################################
> #######################
> +#
> +# Rules are use with the [FV] section's module INF type to define
> +# how an FFS file is created for a given INF file. The following Rule are the
> default
> +# rules for the different module type. User can add the customized rules to
> define the
> +# content of the FFS file.
> +#
> +#########################################################
> #######################
> +[Rule.Common.SEC]
> +  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
> +    PE32  PE32    Align = 8       $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    RAW BIN       Align = 16      |.com
> +  }
> +
> +[Rule.Common.SEC.BINARY]
> +  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
> +    PE32  PE32    Align = 8       |.efi
> +    RAW BIN       Align = 16      |.com
> +  }
> +
> +[Rule.Common.PEI_CORE]
> +  FILE PEI_CORE = $(NAMED_GUID)            {
> +    PE32       PE32    Align = Auto      $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI       STRING="$(MODULE_NAME)" Optional
> +    VERSION  STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.PEIM]
> +  FILE PEIM = $(NAMED_GUID) {
> +     PEI_DEPEX PEI_DEPEX Optional
> $(INF_OUTPUT)/$(MODULE_NAME).depex
> +     PE32        PE32   Align = Auto     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +     UI        STRING="$(MODULE_NAME)" Optional
> +     VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.PEIM.BINARY]
> +  FILE PEIM = $(NAMED_GUID) {
> +     PEI_DEPEX PEI_DEPEX Optional        |.depex
> +     PE32        PE32   Align = Auto     |.efi
> +     UI        STRING="$(MODULE_NAME)" Optional
> +     VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.PEIM.BIOSID]
> +  FILE PEIM = $(NAMED_GUID) {
> +     RAW       BIN                       BiosId.bin
> +     PEI_DEPEX PEI_DEPEX Optional
> $(INF_OUTPUT)/$(MODULE_NAME).depex
> +     PE32        PE32   Align = Auto     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +     UI        STRING="$(MODULE_NAME)" Optional
> +     VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.USER_DEFINED.APINIT]
> +  FILE RAW = $(NAMED_GUID) Fixed Align=4K {
> +     RAW SEC_BIN |.com
> +     }
> +#cjia 2011-07-21
> +[Rule.Common.USER_DEFINED.LEGACY16]
> +  FILE FREEFORM = $(NAMED_GUID) {
> +     UI  STRING="$(MODULE_NAME)" Optional
> +     RAW BIN |.bin
> +     }
> +#cjia
> +
> +[Rule.Common.USER_DEFINED.ASM16]
> +  FILE FREEFORM = $(NAMED_GUID) {
> +     UI  STRING="$(MODULE_NAME)" Optional
> +     RAW BIN |.com
> +   }
> +
> +[Rule.Common.DXE_CORE]
> +  FILE DXE_CORE = $(NAMED_GUID) {
> +    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.UEFI_DRIVER]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional
> $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.UEFI_DRIVER.BINARY]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional       |.depex
> +    PE32      PE32                     |.efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.UEFI_DRIVER.NATIVE_BINARY]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional
> $(WORKSPACE)/$(PLATFORM_PACKAGE)/IntelGopDepex/IntelGopDriver.de
> pex
> +    PE32      PE32                    |.efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.DXE_DRIVER]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional
> $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.DXE_DRIVER.BINARY]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional       |.depex
> +    PE32      PE32                     |.efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.DXE_DRIVER.DRIVER_ACPITABLE]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional
> $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +    RAW ACPI  Optional                |.acpi
> +    RAW ASL   Optional                |.aml
> +  }
> +
> +[Rule.Common.DXE_RUNTIME_DRIVER]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional
> $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.DXE_RUNTIME_DRIVER.BINARY]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional       |.depex
> +    PE32      PE32                     |.efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.DXE_SMM_DRIVER]
> +  FILE SMM = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional
> $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.DXE_SMM_DRIVER.BINARY]
> +  FILE SMM = $(NAMED_GUID) {
> +    SMM_DEPEX SMM_DEPEX                |.depex
> +    PE32      PE32                     |.efi
> +    RAW       BIN  Optional            |.aml
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.DXE_SMM_DRIVER.DRIVER_ACPITABLE]
> +  FILE SMM = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional
> $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +    RAW ACPI  Optional                |.acpi
> +    RAW ASL   Optional                |.aml
> +  }
> +
> +[Rule.Common.SMM_CORE]
> +  FILE SMM_CORE = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional
> $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.SMM_CORE.BINARY]
> +  FILE SMM_CORE = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional       |.depex
> +    PE32      PE32                     |.efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.UEFI_APPLICATION]
> +  FILE APPLICATION = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional
> $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.UEFI_APPLICATION.UI]
> +  FILE APPLICATION = $(NAMED_GUID) {
> +    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI        STRING="Enter Setup"
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.USER_DEFINED]
> +  FILE FREEFORM = $(NAMED_GUID) {
> +    UI  STRING="$(MODULE_NAME)" Optional
> +    RAW BIN                |.bin
> +  }
> +
> +[Rule.Common.USER_DEFINED.BINARY]
> +  FILE FREEFORM = $(NAMED_GUID) {
> +    UI  STRING="$(MODULE_NAME)" Optional
> +    RAW BIN                |.bin
> +  }
> +
> +[Rule.Common.USER_DEFINED.ACPITABLE]
> +  FILE FREEFORM = $(NAMED_GUID) {
> +    RAW ACPI  Optional            |.acpi
> +    RAW ASL   Optional            |.aml
> +  }
> +
> +[Rule.Common.USER_DEFINED.ACPITABLE2]
> +  FILE FREEFORM = $(NAMED_GUID) {
> +    RAW ASL   Optional            |.aml
> +  }
> +
> +[Rule.Common.ACPITABLE]
> +  FILE FREEFORM = $(NAMED_GUID) {
> +    RAW ACPI  Optional            |.acpi
> +    RAW ASL   Optional            |.aml
> +  }
> +
> +[Rule.Common.PEIM.FMP_IMAGE_DESC]
> +  FILE PEIM = $(NAMED_GUID) {
> +     RAW BIN                  |.acpi
> +     PEI_DEPEX PEI_DEPEX Optional
> $(INF_OUTPUT)/$(MODULE_NAME).depex
> +     PE32      PE32    Align=4K          $(INF_OUTPUT)/$(MODULE_NAME).efi
> +     UI       STRING="$(MODULE_NAME)" Optional
> +     VERSION  STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgConfig.dsc
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgConfig.dsc
> new file mode 100644
> index 0000000000..6d556c1be2
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgConfig.dsc
> @@ -0,0 +1,107 @@
> +#/** @file
> +# platform configuration file.
> +#
> +# Copyright (c) 2012  - 2016, Intel Corporation. All rights reserved.<BR>
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +#
> +#**/
> +
> +#
> +# TRUE is ENABLE. FASLE is DISABLE.
> +#
> +
> +#
> +# FSP selection
> +#
> +DEFINE MINNOW2_FSP_BUILD = FALSE
> +
> +
> +DEFINE SCSI_ENABLE = TRUE
> +
> +
> +#
> +# To enable extra configuration for clk gen
> +#
> +DEFINE CLKGEN_CONFIG_EXTRA_ENABLE=TRUE
> +
> +#
> +# Feature selection
> +#
> +
> +#
> +# Select system timer which is used to produce Timer Arch Protocol:
> +# TRUE  - HPET timer is used.
> +# FALSE - 8254 timer is used.
> +#
> +DEFINE USE_HPET_TIMER = TRUE
> +
> +
> +#
> +# Feature selection
> +#
> +
> +DEFINE TPM_ENABLED = FALSE
> +
> +DEFINE ACPI50_ENABLE = TRUE
> +DEFINE PERFORMANCE_ENABLE = FALSE
> +
> +
> +DEFINE LFMA_ENABLE = FALSE              # Load module at fixed address
> feature
> +DEFINE DXE_COMPRESS_ENABLE = TRUE
> +DEFINE DXE_CRC32_SECTION_ENABLE = TRUE
> +DEFINE SSE2_ENABLE = FALSE
> +
> +DEFINE SECURE_BOOT_ENABLE = TRUE
> +DEFINE USER_IDENTIFICATION_ENABLE = FALSE
> +DEFINE VARIABLE_INFO_ENABLE = FALSE
> +DEFINE S3_ENABLE = TRUE
> +DEFINE CAPSULE_ENABLE = TRUE
> +DEFINE CAPSULE_RESET_ENABLE = TRUE
> +DEFINE RECOVERY_ENABLE = FALSE
> +DEFINE MICOCODE_CAPSULE_ENABLE = TRUE
> +
> +DEFINE GOP_DRIVER_ENABLE = TRUE
> +DEFINE DATAHUB_ENABLE = TRUE
> +DEFINE DATAHUB_STATUS_CODE_ENABLE = TRUE
> +DEFINE USB_ENABLE = TRUE
> +
> +DEFINE ISA_SERIAL_STATUS_CODE_ENABLE = TRUE
> +DEFINE USB_SERIAL_STATUS_CODE_ENABLE = FALSE
> +DEFINE RAM_SERIAL_STATUS_CODE_ENABLE = FALSE
> +
> +DEFINE ENBDT_S3_SUPPORT = TRUE
> +
> +DEFINE LZMA_ENABLE = TRUE
> +DEFINE S4_ENABLE = TRUE
> +DEFINE NETWORK_ENABLE = TRUE
> +DEFINE NETWORK_IP6_ENABLE = TRUE
> +DEFINE NETWORK_ISCSI_ENABLE = FALSE
> +DEFINE NETWORK_VLAN_ENABLE = FALSE
> +
> +DEFINE SATA_ENABLE       = TRUE
> +DEFINE PCIESC_ENABLE     = TRUE
> +
> +#
> +# Enable source level debug default
> +#
> +DEFINE SOURCE_DEBUG_ENABLE     = FALSE
> +
> +#
> +# Capsule Pubic Certificate.  Default is EDK_TEST.  Options are:
> +#   SAMPLE_DEVELOPMENT                    - Only signtool
> SAMPLE_DEVELOPMENT
> +#   SAMPLE_DEVELOPMENT_SAMPLE_PRODUCTION  - Both signtool
> SAMPLE_DEVELOPMENT and SAMPLE_PRODUCTION
> +#   EDKII_TEST                            - Only openssl EDK II test certificate
> +#   NEW_ROOT                              - Only openssl new VLV2 certificate
> +#
> +DEFINE CAPSULE_PKCS7_CERT = EDKII_TEST
> +
> +#
> +# Define ESRT GUIDs for Firmware Management Protocol instances
> +#
> +DEFINE FMP_MINNOW_MAX_SYSTEM   = 4096267b-da0a-42eb-b5eb-
> fef31d207cb4
> +DEFINE FMP_RED_SAMPLE_DEVICE   = 72E2945A-00DA-448E-9AA7-
> 075AD840F9D4
> +DEFINE FMP_BLUE_SAMPLE_DEVICE  = 149DA854-7D19-4FAA-A91E-
> 862EA1324BE6
> +DEFINE FMP_GREEN_SAMPLE_DEVICE = 79179BFD-704D-4C90-9E02-
> 0AB8D968C18A
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGcc.fdf
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGcc.fdf
> new file mode 100644
> index 0000000000..1ba6124a69
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGcc.fdf
> @@ -0,0 +1,1033 @@
> +#/** @file
> +# FDF file of Platform.
> +#
> +# Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +#**/
> +
> +[Defines]
> +DEFINE FLASH_BASE       = 0xFFC00000     #The base address of the 4Mb
> FLASH Device.
> +DEFINE FLASH_SIZE       = 0x00400000     #The flash size in bytes of the 4Mb
> FLASH Device.
> +DEFINE FLASH_BLOCK_SIZE = 0x1000        #The block size in bytes of the 4Mb
> FLASH Device.
> +DEFINE FLASH_NUM_BLOCKS = 0x400           #The number of blocks in 4Mb
> FLASH Device.
> +DEFINE FLASH_AREA_BASE_ADDRESS                                = 0xFF800000
> +DEFINE FLASH_AREA_SIZE                                        = 0x00800000
> +
> +DEFINE FLASH_REGION_VLVMICROCODE_OFFSET                       = 0x00000000
> +DEFINE FLASH_REGION_VLVMICROCODE_SIZE                         = 0x00040000
> +DEFINE FLASH_REGION_VLVMICROCODE_BASE                         = 0xFFC00000
> +
> +DEFINE FLASH_REGION_VPD_OFFSET                                = 0x00040000
> +DEFINE FLASH_REGION_VPD_SIZE                                  = 0x0003E000
> +
> +DEFINE
> FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_WORKING_OFFSET =
> 0x0007E000
> +DEFINE
> FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_WORKING_SIZE   =
> 0x00002000
> +
> +
> +DEFINE
> FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_SPARE_OFFSET   =
> 0x00080000
> +DEFINE FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_SPARE_SIZE
> = 0x00040000
> +
> +!if $(MINNOW2_FSP_BUILD) == TRUE
> +DEFINE FLASH_REGION_FSPBIN_OFFSET                             = 0x000C0000
> +DEFINE FLASH_REGION_FSPBIN_SIZE                               = 0x00048000
> +DEFINE FLASH_REGION_FSPBIN_BASE                               = 0xFFCC0000
> +
> +DEFINE FLASH_REGION_AZALIABIN_OFFSET                          = 0x00108000
> +DEFINE FLASH_REGION_AZALIABIN_SIZE                            = 0x00008000
> +DEFINE FLASH_REGION_AZALIABIN_BASE                            = 0xFFD08000
> +
> +!endif
> +
> +DEFINE FLASH_REGION_FVMAIN_OFFSET                             = 0x00110000
> +DEFINE FLASH_REGION_FVMAIN_SIZE                               = 0x00215000
> +
> +DEFINE FLASH_REGION_FV_RECOVERY2_OFFSET                       = 0x00325000
> +DEFINE FLASH_REGION_FV_RECOVERY2_SIZE                         = 0x0006B000
> +
> +DEFINE FLASH_REGION_FV_RECOVERY_OFFSET                        = 0x00390000
> +DEFINE FLASH_REGION_FV_RECOVERY_SIZE                          = 0x00070000
> +
> +#########################################################
> #######################
> +#
> +# FD Section
> +# The [FD] Section is made up of the definition statements and a
> +# description of what goes into  the Flash Device Image.  Each FD section
> +# defines one flash "device" image.  A flash device image may be one of
> +# the following: Removable media bootable image (like a boot floppy
> +# image,) an Option ROM image (that would be "flashed" into an add-in
> +# card,) a System "Flash"  image (that would be burned into a system's
> +# flash) or an Update ("Capsule") image that will be used to update and
> +# existing system flash.
> +#
> +#########################################################
> #######################
> +[FD.Vlv]
> +BaseAddress   =
> $(FLASH_BASE)|gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddre
> ss #The base address of the 3Mb FLASH Device.
> +Size          =
> $(FLASH_SIZE)|gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize
> #The flash size in bytes of the 3Mb FLASH Device.
> +ErasePolarity = 1
> +BlockSize     = $(FLASH_BLOCK_SIZE)          #The block size in bytes of the 3Mb
> FLASH Device.
> +NumBlocks     = $(FLASH_NUM_BLOCKS)          #The number of blocks in 3Mb
> FLASH Device.
> +
> +#
> +#Flash location override based on actual flash map
> +#
> +SET gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress            =
> $(FLASH_AREA_BASE_ADDRESS)
> +SET gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize                   =
> $(FLASH_AREA_SIZE)
> +
> +SET gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress =
> $(FLASH_REGION_VLVMICROCODE_BASE) + 0x60
> +SET gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize =
> $(FLASH_REGION_VLVMICROCODE_SIZE) - 0x60
> +
> +!if $(MINNOW2_FSP_BUILD) == TRUE
> +# put below PCD value setting into dsc file
> +#SET gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress
> = $(FLASH_REGION_VLVMICROCODE_BASE)
> +#SET gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize
> = $(FLASH_REGION_VLVMICROCODE_SIZE)
> +#SET gFspWrapperTokenSpaceGuid.PcdFlashMicroCodeOffset                    =
> 0x60
> +#SET gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheAddress                   =
> $(FLASH_AREA_BASE_ADDRESS)
> +#SET gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheSize                      =
> $(FLASH_AREA_SIZE)
> +#SET gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase                          =
> $(FLASH_REGION_FSPBIN_BASE)
> +#SET gFspWrapperTokenSpaceGuid.PcdFlashFvFspSize                          =
> $(FLASH_REGION_FSPBIN_SIZE)
> +
> +!endif
> +#########################################################
> #######################
> +#
> +# Following are lists of FD Region layout which correspond to the locations
> of different
> +# images within the flash device.
> +#
> +# Regions must be defined in ascending order and may not overlap.
> +#
> +# A Layout Region start with a eight digit hex offset (leading "0x" required)
> followed by
> +# the pipe "|" character, followed by the size of the region, also in hex with
> the leading
> +# "0x" characters. Like:
> +# Offset|Size
> +# PcdOffsetCName|PcdSizeCName
> +# RegionType <FV, DATA, or FILE>
> +# Fv Size can be adjusted; FVMAIN_COMPACT can be reduced to 0x120000,
> and FV_RECOVERY can be enlarged to 0x80000
> +#
> +#########################################################
> #######################
> +# Since the Fce tool don't have gcc version, we can't handle default variable
> in Linux,
> +# so we hardcode the default value of variable here.
> +# Please note that we MUST update the binary once the default value is
> changed.
> +
> +#
> +  # CPU Microcodes
> +  #
> +
> +$(FLASH_REGION_VLVMICROCODE_OFFSET)|$(FLASH_REGION_VLVMICR
> OCODE_SIZE)
> +gPlatformModuleTokenSpaceGuid.PcdFlashMicroCodeAddress|gPlatform
> ModuleTokenSpaceGuid.PcdFlashMicroCodeSize
> +FV = MICROCODE_FV
> +$(FLASH_REGION_VPD_OFFSET)|$(FLASH_REGION_VPD_SIZE)
> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gEfi
> MdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
> +FILE = Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageVariable.bin
> +
> +$(FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_WORKING_OFFSET
> )|$(FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_WORKING_SIZE)
> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|g
> EfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
> +FILE = Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwWorking.bin
> +
> +$(FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_SPARE_OFFSET)|$(
> FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_SPARE_SIZE)
> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfi
> MdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
> +FILE = Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwSpare.bin
> +
> +!if $(MINNOW2_FSP_BUILD) == TRUE
> +
> +  $(FLASH_REGION_FSPBIN_OFFSET)|$(FLASH_REGION_FSPBIN_SIZE)
> +
> gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase|gFspWrapperTokenSpace
> Guid.PcdFlashFvFspSize
> +  FILE = Vlv2SocBinPkg/FspBinary/FvFsp.bin
> +
> +
> +
> $(FLASH_REGION_AZALIABIN_OFFSET)|$(FLASH_REGION_AZALIABIN_SIZE)
> +  FILE = Vlv2TbltDevicePkg/FspAzaliaConfigData/AzaliaConfig.bin
> +
> +!endif
> +
> +  #
> +  # Main Block
> +  #
> +$(FLASH_REGION_FVMAIN_OFFSET)|$(FLASH_REGION_FVMAIN_SIZE)
> +gPlatformModuleTokenSpaceGuid.PcdFlashFvMainBase|gPlatformModule
> TokenSpaceGuid.PcdFlashFvMainSize
> +FV = FVMAIN_COMPACT
> +
> +  #
> +  # FV Recovery#2
> +  #
> +$(FLASH_REGION_FV_RECOVERY2_OFFSET)|$(FLASH_REGION_FV_RECOV
> ERY2_SIZE)
> +gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Base|gPlatformM
> oduleTokenSpaceGuid.PcdFlashFvRecovery2Size
> +FV = FVRECOVERY2
> +
> +  #
> +  # FV Recovery
> +  #
> +$(FLASH_REGION_FV_RECOVERY_OFFSET)|$(FLASH_REGION_FV_RECOVE
> RY_SIZE)
> +gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoveryBase|gPlatformMo
> duleTokenSpaceGuid.PcdFlashFvRecoverySize
> +FV = FVRECOVERY
> +
> +#########################################################
> #######################
> +#
> +# FV Section
> +#
> +# [FV] section is used to define what components or modules are placed
> within a flash
> +# device file.  This section also defines order the components and modules
> are positioned
> +# within the image.  The [FV] section consists of define statements, set
> statements and
> +# module statements.
> +#
> +#########################################################
> #######################
> +[FV.MICROCODE_FV]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = FALSE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +
> +FILE RAW = 197DB236-F856-4924-90F8-CDF12FB875F3 {
> +
> $(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/$(DXE_ARCHITEC
> TURE)/MicrocodeUpdates.bin
> +}
> +
> +!if $(RECOVERY_ENABLE)
> +[FV.FVRECOVERY_COMPONENTS]
> +FvAlignment        = 16         #FV alignment and FV attributes setting.
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +
> +INF  RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chUsb.inf
> +INF  MdeModulePkg/Bus/Pci/EhciPei/EhciPei.inf
> +INF  MdeModulePkg/Bus/Usb/UsbBusPei/UsbBusPei.inf
> +INF  MdeModulePkg/Bus/Usb/UsbBotPei/UsbBotPei.inf
> +INF  FatPkg/FatPei/FatPei.inf
> +INF  MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf
> +INF
> SignedCapsulePkg/Universal/RecoveryModuleLoadPei/RecoveryModuleLoa
> dPei.inf
> +!endif
> +
> +#########################################################
> #######################
> +#
> +# FV Section
> +#
> +# [FV] section is used to define what components or modules are placed
> within a flash
> +# device file.  This section also defines order the components and modules
> are positioned
> +# within the image.  The [FV] section consists of define statements, set
> statements and
> +# module statements.
> +#
> +#########################################################
> #######################
> +[FV.FVRECOVERY2]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16         #FV alignment and FV attributes setting.
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +FvNameGuid         = B73FE497-B92E-416e-8326-45AD0D270092
> +
> +
> +
> +INF $(PLATFORM_PACKAGE)/PlatformInitPei/PlatformInitPei.inf
> +
> +!if $(MINNOW2_FSP_BUILD) == FALSE
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chSmbusArpDisabled.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/Vl
> vInitPeim.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chInitPeim.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chSpiPeim.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> eiSmmAccess.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> eiSmmControl.inf
> +INF UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/M
> pS3.inf
> +!endif
> +
> +# INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/Pi
> SmmCommunicationPei.inf
> +!if $(TPM_ENABLED) == TRUE
> +INF SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
> +INF SecurityPkg/Tcg/TcgPei/TcgPei.inf
> +INF SecurityPkg/Tcg/PhysicalPresencePei/PhysicalPresencePei.inf
> +!endif
> +!if $(FTPM_ENABLE) == TRUE
> +INF  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf #use PCD config
> +!endif
> +INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
> +
> +!if $(ACPI50_ENABLE) == TRUE
> + INF
> MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/Firmwa
> rePerformancePei.inf
> +!endif
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +INF
> MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCode
> RouterPei.inf
> +!endif
> +
> +!if $(RECOVERY_ENABLE)
> +FILE FV_IMAGE = 1E9D7604-EF45-46a0-BD8A-71AC78C17AC1 {
> +  SECTION PEI_DEPEX_EXP = {gEfiPeiMemoryDiscoveredPpiGuid AND
> gEfiPeiBootInRecoveryModePpiGuid}
> +  SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF {    # LZMA
> COMPRESS GUID
> +    SECTION FV_IMAGE = FVRECOVERY_COMPONENTS
> +  }
> +}
> +!endif
> +
> +[FV.FVRECOVERY]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16         #FV alignment and FV attributes setting.
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +FvNameGuid         = B73FE497-B92E-416e-8326-45AD0D270091
> +
> +
> +!if $(MINNOW2_FSP_BUILD) == TRUE
> +INF IntelFspWrapperPkg/FspWrapperSecCore/FspWrapperSecCore.inf
> +!else
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/S
> ecCore.inf
> +!endif
> +
> +INF MdeModulePkg/Core/Pei/PeiMain.inf
> +!if $(MINNOW2_FSP_BUILD) == TRUE
> +INF Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.inf
> +INF IntelFspWrapperPkg/FspInitPei/FspInitPei.inf
> +!endif
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/C
> puPeim.inf
> +INF
> MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
> +INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
> +
> +INF $(PLATFORM_PACKAGE)/PlatformPei/PlatformPei.inf
> +
> +!if $(MINNOW2_FSP_BUILD) == FALSE
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/S
> eCUma.inf
> +!endif
> +
> +!if $(FTPM_ENABLE) == TRUE
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/fT
> PMInitPeim.inf
> +!endif
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +  INF  SourceLevelDebugPkg/DebugAgentPei/DebugAgentPei.inf
> +!endif
> +
> +
> +!if $(CAPSULE_ENABLE) == TRUE
> +INF  MdeModulePkg/Universal/CapsulePei/CapsulePei.inf
> +!if $(DXE_ARCHITECTURE) == "X64"
> +INF  MdeModulePkg/Universal/CapsulePei/CapsuleX64.inf
> +!endif
> +!endif
> +
> +!if $(MINNOW2_FSP_BUILD) == FALSE
> +!if $(PCIESC_ENABLE) == TRUE
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chEarlyInitPeim.inf
> +!endif
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/M
> emoryInit.inf
> +!endif
> +
> +INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
> +
> +[FV.FVMAIN]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +FvNameGuid         = A881D567-6CB0-4eee-8435-2E72D33E45B5
> +
> +APRIORI DXE {
> +  INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
> +  INF
> MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportSt
> atusCodeRouterRuntimeDxe.inf
> +  INF
> MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHan
> dlerRuntimeDxe.inf
> +  }
> +
> +FILE FREEFORM = C3E36D09-8294-4b97-A857-D5288FE33E28 {
> +    SECTION RAW =
> $(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/$(DXE_ARCHITEC
> TURE)/BiosId.bin
> +  }
> +
> +  #
> +  # EDK II Related Platform codes
> +  #
> +
> +  !if $(MINNOW2_FSP_BUILD) == TRUE
> +  INF IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.inf
> +  !endif
> +
> +INF MdeModulePkg/Core/Dxe/DxeMain.inf
> +INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
> +!if $(ACPI50_ENABLE) == TRUE
> +INF
> MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/Firmw
> arePerformanceDxe.inf
> +INF
> MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/Firm
> warePerformanceSmm.inf
> +!endif
> +
> +
> +INF IntelFrameworkModulePkg/Universal/CpuIoDxe/CpuIoDxe.inf
> +INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
> +INF
> MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportSt
> atusCodeRouterRuntimeDxe.inf
> +INF
> MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHan
> dlerRuntimeDxe.inf
> +INF
> MdeModulePkg/Universal/ReportStatusCodeRouter/Smm/ReportStatusCod
> eRouterSmm.inf
> +INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
> +INF UefiCpuPkg/CpuDxe/CpuDxe.inf
> +INF $(PLATFORM_PACKAGE)/Metronome/Metronome.inf
> +INF IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf
> +!if $(ARCH) == IA32
> +INF USE=IA32 MdeModulePkg/Logo/Logo.inf
> +!else
> +INF USE=X64 MdeModulePkg/Logo/Logo.inf
> +!endif
> +INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
> +INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
> +INF
> MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.in
> f
> +INF
> IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3SaveDxe.i
> nf
> +
> +INF
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.i
> nf
> +INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
> +INF $(PLATFORM_PACKAGE)/FvbRuntimeDxe/FvbSmm.inf
> +INF
> MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.i
> nf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchSpiSmm.inf
> +!if $(SECURE_BOOT_ENABLE)
> +INF
> SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfi
> gDxe.inf
> +!endif
> +
> +INF
> MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
> +
> +INF
> MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCoun
> terRuntimeDxe.inf
> +INF
> PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntime
> Dxe.inf
> +INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
> +INF $(PLATFORM_PACKAGE)/FvbRuntimeDxe/FvbRuntimeDxe.inf
> +
> +
> +INF $(PLATFORM_PACKAGE)/PlatformSetupDxe/PlatformSetupDxe.inf
> +
> +!if $(DATAHUB_ENABLE) == TRUE
> +INF IntelFrameworkModulePkg/Universal/DataHubDxe/DataHubDxe.inf
> +!endif
> +INF
> IntelFrameworkModulePkg/Universal/StatusCode/DatahubStatusCodeHandl
> erDxe/DatahubStatusCodeHandlerDxe.inf
> +INF
> MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryT
> estDxe.inf
> +
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/Dptf.inf
> +
> +  #
> +  # EDK II Related Silicon codes
> +  #
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchS3SupportDxe.inf
> +
> +!if $(USE_HPET_TIMER) == TRUE
> +INF PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf
> +!else
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SmartTimer.inf
> +!endif
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SmmControl.inf
> +
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchSmbusDxe.inf
> +
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/IntelPchLegacyInterrupt.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchReset.inf
> +
> +!if $(MINNOW2_FSP_BUILD) == FALSE
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchInitDxe.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchInitSmm.inf
> +!endif
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchSmiDispatcher.inf
> +!if $(PCIESC_ENABLE) == TRUE
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchPcieSmm.inf
> +!endif
> +
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchSpiRuntime.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchPolicyInitDxe.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchBiosWriteProtect.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SmmAccess.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PciHostBridge.inf
> +!if $(MINNOW2_FSP_BUILD) == FALSE
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/VlvInitDxe.inf
> +!else
> +INF
> IntelFrameworkModulePkg/Universal/LegacyRegionDxe/LegacyRegionDxe.i
> nf
> +INF Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInitDxe.inf
> +!endif
> +!if $(MINNOW2_FSP_BUILD) == FALSE
> +  !if $(SEC_ENABLE) == TRUE
> +  INF  RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/HeciDrv.inf
> +  INF  RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SeCPolicyInitDxe.inf
> +  !endif
> +!endif
> +!if $(TPM_ENABLED) == TRUE
> +INF SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf
> +INF SecurityPkg/Tcg/TcgDxe/TcgDxe.inf
> +INF RuleOverride = DRIVER_ACPITABLE
> SecurityPkg/Tcg/TcgSmm/TcgSmm.inf
> +!endif
> +!if $(FTPM_ENABLE) == TRUE
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/T
> pm2DeviceSeCPei.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/Tpm2DeviceSeCDxe.inf
> +INF SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf
> +INF SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/FtpmSmm.inf
> +!endif
> +
> +#
> +# EDK II Related Platform codes
> +#
> +INF $(PLATFORM_PACKAGE)/PlatformSmm/PlatformSmm.inf
> +INF $(PLATFORM_PACKAGE)/PlatformInfoDxe/PlatformInfoDxe.inf
> +INF $(PLATFORM_PACKAGE)/PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf
> +INF $(PLATFORM_PACKAGE)/PlatformDxe/PlatformDxe.inf
> +INF $(PLATFORM_PACKAGE)/PciPlatform/PciPlatform.inf
> +INF $(PLATFORM_PACKAGE)/SaveMemoryConfig/SaveMemoryConfig.inf
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PlatformCpuPolicy.inf
> +INF $(PLATFORM_PACKAGE)/PpmPolicy/PpmPolicy.inf
> +INF
> $(PLATFORM_PACKAGE)/SmramSaveInfoHandlerSmm/SmramSaveInfoHand
> lerSmm.inf
> +!if $(GOP_DRIVER_ENABLE) == TRUE
> + INF $(PLATFORM_PACKAGE)/PlatformGopPolicy/PlatformGopPolicy.inf
> + FILE DRIVER = FF0C8745-3270-4439-B74F-3E45F8C77064 {
> +  SECTION DXE_DEPEX_EXP = {gPlatformGOPPolicyGuid}
> +  SECTION PE32 =
> Vlv2SocBinPkg/GOP/7.2.1011/RELEASE_VS2008x86/$(DXE_ARCHITECTURE)/I
> ntelGopDriver.efi
> +  SECTION UI = "IntelGopDriver"
> +}
> +!endif
> +
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PnpDxe.inf
> +  #
> +  # SMM
> +  #
> +INF MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
> +INF MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
> +INF UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
> +
> +INF UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
> +INF MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
> +INF UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
> +INF
> $(PLATFORM_PACKAGE)/SmmSwDispatch2OnSmmSwDispatchThunk/SmmS
> wDispatch2OnSmmSwDispatchThunk.inf
> +
> +#
> +# Remove the following two SMM binary modules that prevent platform
> from booting to UEFI Shell
> +#
> +#INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PowerManagement2.inf
> +#INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/DigitalThermalSensor.inf
> +
> +  #
> +  # ACPI
> +  #
> +INF
> MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutor
> Dxe.inf
> +INF $(PLATFORM_PACKAGE)/BootScriptSaveDxe/BootScriptSaveDxe.inf
> +INF
> IntelFrameworkModulePkg/Universal/Acpi/AcpiSupportDxe/AcpiSupportDx
> e.inf
> +INF RuleOverride = ACPITABLE2
> Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTable
> s/PowerManagementAcpiTables.inf
> +
> +INF RuleOverride = ACPITABLE
> $(PLATFORM_RC_PACKAGE)/AcpiTablesPCAT/AcpiTables.inf
> +
> +INF $(PLATFORM_PACKAGE)/AcpiPlatform/AcpiPlatform.inf
> +
> +INF
> MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraph
> icsResourceTableDxe.inf
> +
> +  #
> +  # PCI
> +  #
> +INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
> +
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/ISPDxe.inf
> +
> +
> +#
> +# ISA
> +#
> +INF $(PLATFORM_PACKAGE)/Wpce791/Wpce791.inf
> +INF IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBusDxe.inf
> +INF IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaIoDxe.inf
> +!if $(SOURCE_DEBUG_ENABLE) != TRUE
> +INF  IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf
> +!endif
> +#INF IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf
> +#INF
> IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf
> +
> +#
> +# SDIO
> +#
> +#INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/MmcHost.inf
> +#INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/MmcMediaDevice.inf
> +#
> +# IDE/SCSI/AHCI
> +#
> +INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
> +
> +INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
> +
> +INF
> MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
> +!if $(SATA_ENABLE) == TRUE
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SataController.inf
> +#
> +
> +#
> +INF MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
> +INF MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
> +!if $(SCSI_ENABLE) == TRUE
> +INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
> +INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
> +!endif
> +#
> +!endif
> +# Console
> +#
> +INF
> MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
> +INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
> +INF
> MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleD
> xe.inf
> +INF
> IntelFrameworkModulePkg/Universal/Console/VgaClassDxe/VgaClassDxe.in
> f
> +INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
> +INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
> +INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
> +INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
> +  #
> +  # USB
> +  #
> +!if $(USB_ENABLE) == TRUE
> +INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
> +INF MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
> +INF
> MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
> +INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
> +INF MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
> +INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
> +INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
> +!endif
> +
> +
> +  #
> +  # SMBIOS
> +  #
> +INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
> +INF $(PLATFORM_PACKAGE)/SmBiosMiscDxe/SmBiosMiscDxe.inf
> +
> +INF RuleOverride = BINARY
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SmbiosMemory.inf
> +
> +
> +#
> +# FAT file system
> +#
> +INF FatPkg/EnhancedFatDxe/Fat.inf
> +
> +#
> +# UEFI Shell
> +#
> +INF  ShellPkg/Application/Shell/Shell.inf
> +
> +#
> +# dp command
> +#
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +INF
> ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf
> +!endif
> +
> +!if $(GOP_DRIVER_ENABLE) == TRUE
> +FILE FREEFORM = 878AC2CC-5343-46F2-B563-51F89DAF56BA {
> +  SECTION RAW = Vlv2SocBinPkg/GOP/7.2.1011/VBT/MNW2/Vbt.bin
> +  SECTION UI = "IntelGopVbt"
> +}
> +!endif
> +
> +#
> +# Network Modules
> +#
> +!if $(NETWORK_ENABLE) == TRUE
> +  FILE DRIVER = 22DE1691-D65D-456a-993E-A253DD1F308C {
> +    SECTION PE32 =
> Vlv2SocBinPkg/UNDI/RtkUndiDxe/$(DXE_ARCHITECTURE)/RtkUndiDxe.efi
> +    SECTION UI = "UNDI"
> +  }
> +  INF  MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf
> +  INF  MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
> +  INF  MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
> +  INF  MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
> +  INF  MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
> +  INF  MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
> +  INF  MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
> +  INF  MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
> +  INF  NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
> +  INF  NetworkPkg/TcpDxe/TcpDxe.inf
> +  !if $(NETWORK_IP6_ENABLE) == TRUE
> +  INF  NetworkPkg/Ip6Dxe/Ip6Dxe.inf
> +  INF  NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
> +  INF  NetworkPkg/Udp6Dxe/Udp6Dxe.inf
> +  INF  NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
> +  !endif
> +  !if $(NETWORK_VLAN_ENABLE) == TRUE
> +  INF
> MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf
> +  !endif
> +  !if $(NETWORK_ISCSI_ENABLE) == TRUE
> +    INF  NetworkPkg/IScsiDxe/IScsiDxe.inf
> +  !endif
> +!endif
> +
> +!if $(CAPSULE_ENABLE)
> +INF  MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxe.inf
> +
> +#
> +# Minnow Max System Firmware FMP
> +#
> +INF  FILE_GUID = $(FMP_MINNOW_MAX_SYSTEM)
> FmpDevicePkg/FmpDxe/FmpDxe.inf
> +
> +#
> +# Sample Device FMP
> +#
> +INF  FILE_GUID = $(FMP_GREEN_SAMPLE_DEVICE)
> FmpDevicePkg/FmpDxe/FmpDxe.inf
> +INF  FILE_GUID = $(FMP_BLUE_SAMPLE_DEVICE)
> FmpDevicePkg/FmpDxe/FmpDxe.inf
> +INF  FILE_GUID = $(FMP_RED_SAMPLE_DEVICE)
> FmpDevicePkg/FmpDxe/FmpDxe.inf
> +
> +!endif
> +
> +!if $(MICOCODE_CAPSULE_ENABLE)
> +INF
> IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDx
> e.inf
> +!endif
> +
> +!if $(RECOVERY_ENABLE)
> +FILE FREEFORM =
> PCD(gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiRsa2048Sha256TestPubli
> cKeyFileGuid) {
> +     SECTION RAW =
> BaseTools/Source/Python/Rsa2048Sha256Sign/TestSigningPublicKey.bin
> +     SECTION UI = "Rsa2048Sha256TestSigningPublicKey"
> +     }
> +!endif
> +
> +[FV.FVMAIN_COMPACT]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +
> +
> +
> +FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
> +!if $(LZMA_ENABLE) == TRUE
> +# LZMA Compress
> +       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF
> PROCESSING_REQUIRED = TRUE {
> +          SECTION FV_IMAGE = FVMAIN
> +       }
> +!else
> +!if $(DXE_COMPRESS_ENABLE) == TRUE
> +# Tiano Compress
> +       SECTION GUIDED A31280AD-481E-41B6-95E8-127F4C984779
> PROCESSING_REQUIRED = TRUE {
> +          SECTION FV_IMAGE = FVMAIN
> +       }
> +!else
> +# No Compress
> +       SECTION COMPRESS PI_NONE {
> +          SECTION FV_IMAGE = FVMAIN
> +       }
> +!endif
> +!endif
> +     }
> +
> +[FV.SETUP_DATA]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +#NumBlocks         = 0x10
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +
> +#########################################################
> #######################
> +#
> +# Rules are use with the [FV] section's module INF type to define
> +# how an FFS file is created for a given INF file. The following Rule are the
> default
> +# rules for the different module type. User can add the customized rules to
> define the
> +# content of the FFS file.
> +#
> +#########################################################
> #######################
> +[Rule.Common.SEC]
> +  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
> +    PE32  PE32    Align = 8       $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    RAW BIN       Align = 16      |.com
> +  }
> +
> +[Rule.Common.SEC.BINARY]
> +  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
> +    PE32  PE32    Align = 8       |.efi
> +!if $(MINNOW2_FSP_BUILD) == TRUE
> +    RAW   RAW                     |.raw
> +!else
> +    RAW   BIN     Align = 16      |.com
> +!endif
> +  }
> +
> +[Rule.Common.PEI_CORE]
> +  FILE PEI_CORE = $(NAMED_GUID)            {
> +    PE32       PE32    Align = Auto      $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI       STRING="$(MODULE_NAME)" Optional
> +    VERSION  STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.PEIM]
> +  FILE PEIM = $(NAMED_GUID) {
> +     PEI_DEPEX PEI_DEPEX Optional
> $(INF_OUTPUT)/$(MODULE_NAME).depex
> +     PE32        PE32   Align = Auto     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +     UI        STRING="$(MODULE_NAME)" Optional
> +     VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.PEIM.BINARY]
> +  FILE PEIM = $(NAMED_GUID) {
> +     PEI_DEPEX PEI_DEPEX Optional        |.depex
> +     PE32        PE32   Align = Auto     |.efi
> +     UI        STRING="$(MODULE_NAME)" Optional
> +     VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.PEIM.BIOSID]
> +  FILE PEIM = $(NAMED_GUID) {
> +     RAW       BIN                       BiosId.bin
> +     PEI_DEPEX PEI_DEPEX Optional
> $(INF_OUTPUT)/$(MODULE_NAME).depex
> +     PE32        PE32   Align = Auto     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +     UI        STRING="$(MODULE_NAME)" Optional
> +     VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.USER_DEFINED.APINIT]
> +  FILE RAW = $(NAMED_GUID) Fixed Align=4K {
> +     RAW SEC_BIN |.com
> +     }
> +#cjia 2011-07-21
> +[Rule.Common.USER_DEFINED.LEGACY16]
> +  FILE FREEFORM = $(NAMED_GUID) {
> +     UI  STRING="$(MODULE_NAME)" Optional
> +     RAW BIN |.bin
> +     }
> +#cjia
> +
> +[Rule.Common.USER_DEFINED.ASM16]
> +  FILE FREEFORM = $(NAMED_GUID) {
> +     UI  STRING="$(MODULE_NAME)" Optional
> +     RAW BIN |.com
> +   }
> +
> +[Rule.Common.DXE_CORE]
> +  FILE DXE_CORE = $(NAMED_GUID) {
> +    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.UEFI_DRIVER]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional
> $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.UEFI_DRIVER.BINARY]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional       |.depex
> +    PE32      PE32                     |.efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.UEFI_DRIVER.NATIVE_BINARY]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional
> $(WORKSPACE)/$(PLATFORM_PACKAGE)/IntelGopDepex/IntelGopDriver.de
> pex
> +    PE32      PE32                    |.efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.DXE_DRIVER]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional
> $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.DXE_DRIVER.BINARY]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional       |.depex
> +    PE32      PE32                     |.efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.DXE_DRIVER.DRIVER_ACPITABLE]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional
> $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +    RAW ACPI  Optional                |.acpi
> +    RAW ASL   Optional                |.aml
> +  }
> +
> +[Rule.Common.DXE_RUNTIME_DRIVER]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional
> $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.DXE_RUNTIME_DRIVER.BINARY]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional       |.depex
> +    PE32      PE32                     |.efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.DXE_SMM_DRIVER]
> +  FILE SMM = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional
> $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.DXE_SMM_DRIVER.BINARY]
> +  FILE SMM = $(NAMED_GUID) {
> +    SMM_DEPEX SMM_DEPEX                |.depex
> +    PE32      PE32                     |.efi
> +    RAW       BIN  Optional            |.aml
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.DXE_SMM_DRIVER.DRIVER_ACPITABLE]
> +  FILE SMM = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional
> $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +    RAW ACPI  Optional                |.acpi
> +    RAW ASL   Optional                |.aml
> +  }
> +
> +[Rule.Common.SMM_CORE]
> +  FILE SMM_CORE = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional
> $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.SMM_CORE.BINARY]
> +  FILE SMM_CORE = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional       |.depex
> +    PE32      PE32                     |.efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.UEFI_APPLICATION]
> +  FILE APPLICATION = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional
> $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.UEFI_APPLICATION.UI]
> +  FILE APPLICATION = $(NAMED_GUID) {
> +    PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI        STRING="Enter Setup"
> +    VERSION   STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.USER_DEFINED]
> +  FILE FREEFORM = $(NAMED_GUID) {
> +    UI  STRING="$(MODULE_NAME)" Optional
> +    RAW BIN                |.bin
> +  }
> +
> +[Rule.Common.USER_DEFINED.BINARY]
> +  FILE FREEFORM = $(NAMED_GUID) {
> +    UI  STRING="$(MODULE_NAME)" Optional
> +    RAW BIN                |.bin
> +  }
> +
> +[Rule.Common.USER_DEFINED.ACPITABLE]
> +  FILE FREEFORM = $(NAMED_GUID) {
> +    RAW ACPI  Optional            |.acpi
> +    RAW ASL   Optional            |.aml
> +  }
> +
> +[Rule.Common.USER_DEFINED.ACPITABLE2]
> +  FILE FREEFORM = $(NAMED_GUID) {
> +    RAW ASL   Optional            |.aml
> +  }
> +
> +[Rule.Common.ACPITABLE]
> +  FILE FREEFORM = $(NAMED_GUID) {
> +    RAW ACPI  Optional            |.acpi
> +    RAW ASL   Optional            |.aml
> +  }
> +
> +[Rule.Common.PEIM.FMP_IMAGE_DESC]
> +  FILE PEIM = $(NAMED_GUID) {
> +     RAW BIN                  |.acpi
> +     PEI_DEPEX PEI_DEPEX Optional
> $(INF_OUTPUT)/$(MODULE_NAME).depex
> +     PE32      PE32    Align=4K          $(INF_OUTPUT)/$(MODULE_NAME).efi
> +     UI       STRING="$(MODULE_NAME)" Optional
> +     VERSION  STRING="$(INF_VERSION)" Optional
> BUILD_NUM=$(BUILD_NUMBER)
> +  }
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc
> new file mode 100644
> index 0000000000..b9faf558b7
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc
> @@ -0,0 +1,1711 @@
> +#/** @file
> +# Platform description.
> +#
> +# Copyright (c) 2012  - 2019, 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]
> +  PLATFORM_NAME                       = Vlv2TbltDevicePkg
> +  PLATFORM_GUID                       = 465B0A0B-7AC1-443b-8F67-7B8DEC145F90
> +  PLATFORM_VERSION                    = 0.1
> +  DSC_SPECIFICATION                   = 0x00010005
> +
> +  #
> +  # Set platform specific package/folder name, same as passed from
> PREBUILD script.
> +  # PLATFORM_PACKAGE would be the same as PLATFORM_NAME as well
> as package build folder
> +  # DEFINE only takes effect at R9 DSC and FDF.
> +  #
> +  DEFINE      PLATFORM_PACKAGE                = Vlv2TbltDevicePkg
> +  DEFINE      PLATFORM_RC_PACKAGE             = Vlv2DeviceRefCodePkg
> +  DEFINE      PLATFORM_BINARY_PACKAGE         = Vlv2SocBinPkg
> +  OUTPUT_DIRECTORY                    = Build/$(PLATFORM_PACKAGE)
> +  SUPPORTED_ARCHITECTURES             = IA32|X64
> +  BUILD_TARGETS                       = DEBUG|RELEASE
> +  SKUID_IDENTIFIER                    = DEFAULT
> +
> +  DEFINE CPU_ARCH                 =ValleyView2
> +  DEFINE PROJECT_SC_FAMILY        =IntelPch
> +  DEFINE PROJECT_SC_ROOT
> =../$(PLATFORM_RC_PACKAGE)/ValleyView2Soc/SouthCluster
> +  DEFINE PROJECT_VLV_ROOT
> =../$(PLATFORM_RC_PACKAGE)/ValleyView2Soc/NorthCluster
> +
> +  DEFINE RC_BINARY_RELEASE        = TRUE
> +  #
> +  # Platform On/Off features are defined here
> +  #
> +  #
> +  # Platform Support:: Set only one token except Crestview Hills
> +  #
> +  #   3.BayleyBay
> +  #     ENBDT_PF_ENABLE  = TRUE
> +  #
> +  !include $(PLATFORM_PACKAGE)/AutoPlatformCFG.txt
> +  !include $(PLATFORM_PACKAGE)/PlatformPkgConfig.dsc
> +
> +!if $(X64_CONFIG) == TRUE
> +  DEFINE      DXE_ARCHITECTURE        = X64
> +  DEFINE      EDK_DXE_ARCHITECTURE    = X64
> +  DEFINE      UNDI_DXE_ARCHITECTURE   = 64
> +!else
> +  DEFINE      DXE_ARCHITECTURE        = IA32
> +  DEFINE      EDK_DXE_ARCHITECTURE    = Ia32
> +  DEFINE      UNDI_DXE_ARCHITECTURE   = 32
> +!endif
> +
> +  FLASH_DEFINITION                    =
> $(PLATFORM_PACKAGE)/PlatformPkgGcc.fdf
> +!if $(LFMA_ENABLE) == TRUE
> +  FIX_LOAD_TOP_MEMORY_ADDRESS         = 0xFFFFFFFFFFFFFFFF
> +  DEFINE   TOP_MEMORY_ADDRESS         = 0xFFFFFFFFFFFFFFFF
> +!else
> +  FIX_LOAD_TOP_MEMORY_ADDRESS         = 0x0
> +  DEFINE   TOP_MEMORY_ADDRESS         = 0x0
> +!endif
> +
> +  DEFINE   PLATFORM_PCIEXPRESS_BASE   = 0E0000000
> +
> +  DEFINE SEC_ENABLE = FALSE
> +  DEFINE SEC_DEBUG_INFO_ENABLE = FALSE
> +  DEFINE FTPM_ENABLE = FALSE
> +
> +#########################################################
> #######################
> +#
> +# SKU Identification section - list of all SKU IDs supported by this
> +#                              Platform.
> +#
> +#########################################################
> #######################
> +[SkuIds]
> +  0|DEFAULT              # The entry: 0|DEFAULT is reserved and always required.
> +
> +#########################################################
> #######################
> +#
> +# Library Class section - list of all Library Classes needed by this Platform.
> +#
> +#########################################################
> #######################
> +[LibraryClasses.common]
> +  #
> +  # Entry point
> +  #
> +
> PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.in
> f
> +  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
> +
> DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint
> .inf
> +
> UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntry
> Point.inf
> +
> UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiA
> pplicationEntryPoint.inf
> +
> DxeSmmDriverEntryPoint|IntelFrameworkPkg/Library/DxeSmmDriverEntryP
> oint/DxeSmmDriverEntryPoint.inf
> +
> +  #
> +  # Basic
> +  #
> +  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
> +!if $(SSE2_ENABLE) == TRUE
> +
> BaseMemoryLib|MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2
> .inf
> +!else
> +
> BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibR
> epStr.inf
> +!endif
> +  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
> +  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
> +  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
> +  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
> +
> PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibP
> ci.inf
> +  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
> +  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
> +
> CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCac
> heMaintenanceLib.inf
> +  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
> +
> PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/Base
> PeCoffGetEntryPointLib.inf
> +!if $(RC_BINARY_RELEASE) == TRUE
> +
> PchPlatformLib|Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLib.in
> f
> +!endif
> +  #
> +  # UEFI & PI
> +  #
> +
> UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBo
> otServicesTableLib.inf
> +
> UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib
> /UefiRuntimeServicesTableLib.inf
> +  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
> +  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
> +  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
> +
> UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiService
> sLib.inf
> +  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
> +
> UefiDecompressLib|MdeModulePkg/Library/BaseUefiTianoCustomDecompr
> essLib/BaseUefiTianoCustomDecompressLib.inf
> +
> PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/P
> eiServicesTablePointerLibIdt.inf
> +  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
> +  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
> +
> DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTabl
> eLib.inf
> +  UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
> +  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
> +
> GenericBdsLib|$(PLATFORM_PACKAGE)/Override/IntelFrameworkModuleP
> kg/Library/GenericBdsLib/GenericBdsLib.inf
> +
> BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupp
> ortLib.inf
> +  SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
> +
> PlatformBdsLib|$(PLATFORM_PACKAGE)/Library/PlatformBdsLib/PlatformB
> dsLib.inf
> +  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
> +  DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
> +
> FlashDeviceLib|$(PLATFORM_PACKAGE)/Library/FlashDeviceLib/FlashDevice
> Lib.inf
> +
> UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBoo
> tManagerLib.inf
> +  #
> +  # Framework
> +  #
> +!if $(S3_ENABLE) == TRUE
> +
> S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootSc
> riptLib.inf
> +!else
> +
> S3BootScriptLib|MdePkg/Library/BaseS3BootScriptLibNull/BaseS3BootScriptL
> ibNull.inf
> +!endif
> +  S3IoLib|MdePkg/Library/BaseS3IoLib/BaseS3IoLib.inf
> +  S3PciLib|MdePkg/Library/BaseS3PciLib/BaseS3PciLib.inf
> +
> +  #
> +  # Generic Modules
> +  #
> +!if $(USB_ENABLE) == TRUE
> +  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
> +!endif
> +!if $(SCSI_ENABLE) == TRUE
> +  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
> +!endif
> +!if $(NETWORK_ENABLE) == TRUE
> +  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
> +  IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
> +  UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
> +  TcpIoLib|MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf
> +  DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
> +!endif
> +!if $(S3_ENABLE) == TRUE
> +  S3Lib|IntelFrameworkModulePkg/Library/PeiS3Lib/PeiS3Lib.inf
> +!endif
> +
> +
> OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibN
> ull/OemHookStatusCodeLibNull.inf
> +!if $(CAPSULE_ENABLE) == TRUE
> +  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf
> +!else
> +
> CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.i
> nf
> +!endif
> +
> FmpAuthenticationLib|MdeModulePkg/Library/FmpAuthenticationLibNull/F
> mpAuthenticationLibNull.inf
> +  IniParsingLib|SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.inf
> +
> PlatformFlashAccessLib|Vlv2TbltDevicePkg/Feature/Capsule/Library/Platfor
> mFlashAccessLib/PlatformFlashAccessLib.inf
> +
> MicrocodeFlashAccessLib|Vlv2TbltDevicePkg/Feature/Capsule/Library/Platfo
> rmFlashAccessLib/PlatformFlashAccessLib.inf
> +
> DisplayUpdateProgressLib|MdeModulePkg/Library/DisplayUpdateProgressLi
> bGraphics/DisplayUpdateProgressLibGraphics.inf
> +
> SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchroniz
> ationLib.inf
> +
> SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementL
> ib/DxeSecurityManagementLib.inf
> +  IoApicLib|PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf
> +
> DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/Bas
> eDebugPrintErrorLevelLib.inf
> +
> +  #
> +  # CPU
> +  #
> +  MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf
> +
> LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.in
> f
> +
> CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeC
> puExceptionHandlerLib.inf
> +  MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
> +
> +  #
> +  # ICH
> +  #
> +  SmbusLib|$(PLATFORM_PACKAGE)/Library/SmbusLib/SmbusLib.inf
> +  SmmLib|$(PLATFORM_PACKAGE)/Library/PchSmmLib/PchSmmLib.inf
> +
> +  #
> +  # Platform
> +  #
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +
> ResetSystemLib|$(PLATFORM_PACKAGE)/Library/ResetSystemLib/ResetSys
> temLib.inf
> +
> +
> PlatformCmosLib|$(PLATFORM_PACKAGE)/Library/PlatformCmosLib/Platfor
> mCmosLib.inf
> +
> +  #
> +  # Misc
> +  #
> +
> MonoStatusCodeLib|$(PLATFORM_PACKAGE)/MonoStatusCode/MonoStat
> usCode.inf
> +!if $(TARGET) == RELEASE
> +  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
> +
> SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.in
> f
> +!else
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +
> SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
> +!endif
> +
> +
> PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanc
> eLibNull.inf
> +  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +!if $(TPM_ENABLED) == TRUE
> +  TpmCommLib|SecurityPkg/Library/TpmCommLib/TpmCommLib.inf
> +
> Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12Comma
> ndLib.inf
> +
> Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLib
> DTpm.inf
> +
> +!endif
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibD
> ebug/PeCoffExtraActionLibDebug.inf
> +
> DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicati
> onLibSerialPort/DebugCommunicationLibSerialPort.inf
> +
> PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePla
> tformHookLibNull.inf
> +
> SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPort
> Lib16550.inf
> +!else
> +
> PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BaseP
> eCoffExtraActionLibNull.inf
> +
> DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLi
> bNull.inf
> +!endif
> +
> +  #
> +  # CryptLib
> +  #
> +!if $(TPM_ENABLED) == TRUE
> +  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
> +  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
> +!endif
> +
> + BiosIdLib|$(PLATFORM_PACKAGE)/Library/BiosIdLib/BiosIdLib.inf
> + CpuIA32Lib|$(PLATFORM_PACKAGE)/Library/CpuIA32Lib/CpuIA32Lib.inf
> +
> +
> StallSmmLib|$(PLATFORM_PACKAGE)/Library/StallSmmLib/StallSmmLib.inf
> +
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
> +  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
> +
> PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecu
> reLibNull.inf
> +
> TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTp
> mMeasurementLib.inf
> +  AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
> +  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
> +!else
> +
> TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/Tp
> mMeasurementLibNull.inf
> +
> AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableL
> ibNull.inf
> +!endif
> +  VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
> +!if $(RC_BINARY_RELEASE) == TRUE
> +  I2cLib|Vlv2TbltDevicePkg/Library/I2CLib/I2CLibNull.inf
> +!endif
> +  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
> +  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
> +  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
> +!if $(FTPM_ENABLE) == TRUE || $(NETWORK_ISCSI_ENABLE) == TRUE
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> +  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
> +  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
> +!endif
> +
> TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTp
> mMeasurementLib.inf
> +
> Tcg2PhysicalPresenceLib|SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/D
> xeTcg2PhysicalPresenceLib.inf
> +
> Tcg2PpVendorLib|SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorL
> ibNull.inf
> +
> +
> +
> Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandL
> ib.inf
> +!if $(MINNOW2_FSP_BUILD) == TRUE
> +  FspApiLib|IntelFspWrapperPkg/Library/BaseFspApiLib/BaseFspApiLib.inf
> +
> FspPlatformInfoLib|IntelFspWrapperPkg/Library/BaseFspPlatformInfoLibSa
> mple/BaseFspPlatformInfoLibSample.inf
> +
> FspPlatformSecLib|Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSe
> cLibVlv2/FspPlatformSecLibVlv2.inf
> +
> FspHobProcessLib|Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcess
> LibVlv2/FspHobProcessLibVlv2.inf
> +!endif
> +
> +  BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
> +
> +[LibraryClasses.IA32.SEC]
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +
> PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanc
> eLibNull.inf
> +!endif
> +  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
> +  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +
> +[LibraryClasses.IA32.PEIM, LibraryClasses.IA32.PEI_CORE,
> LibraryClasses.IA32.SEC]
> +  #
> +  # PEI phase common
> +  #
> +
> +  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
> +
> MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemory
> AllocationLib.inf
> +
> ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiR
> eportStatusCodeLib.inf
> +
> ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiEx
> tractGuidedSectionLib.inf
> +
> MultiPlatformLib|$(PLATFORM_PACKAGE)/Library/MultiPlatformLib/MultiPl
> atformLib.inf
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
> +
> CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecP
> eiCpuExceptionHandlerLib.inf
> +  MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
> +
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +
> PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanc
> eLib.inf
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +!endif
> +
> +!if $(TARGET) == RELEASE
> +  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
> +
> SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.in
> f
> +!else
> +
> DebugLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDx
> eDebugLibReportStatusCode.inf
> +
> SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
> +!endif
> +
> +
> LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf
> +
> HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoR
> outerPei.inf
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAg
> entLib.inf
> +!endif
> +
> + !if $(MINNOW2_FSP_BUILD) == TRUE
> +
> PlatformFspLib|Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.in
> f
> + !endif
> +!if $(FTPM_ENABLE) == TRUE
> +
> Tpm2DeviceLib|Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2Devi
> ceLibSeC.inf
> +!endif
> +
> +[LibraryClasses.X64]
> +  #
> +  # DXE phase common
> +  #
> +  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
> +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +
> MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemo
> ryAllocationLib.inf
> +
> ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/Dx
> eReportStatusCodeLib.inf
> +
> ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeE
> xtractGuidedSectionLib.inf
> +
> +
> TcgPhysicalPresenceLib|SecurityPkg/Library/DxeTcgPhysicalPresenceLib/Dxe
> TcgPhysicalPresenceLib.inf
> +!if $(TPM_ENABLED) == TRUE
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> +!endif
> +
> +
> LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.in
> f
> +
> EfiRegTableLib|$(PLATFORM_PACKAGE)/Library/EfiRegTableLib/EfiRegTable
> Lib.inf
> +
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> +!endif
> +
> +
> HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoR
> outerDxe.inf
> +
> +[LibraryClasses.X64.DXE_DRIVER]
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +
> PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanc
> eLibNull.inf
> +
> CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/Custo
> mizedDisplayLib.inf
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +
> PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerforma
> nceLib.inf
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +!endif
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgen
> tLib.inf
> +!endif
> +
> +
> FlashDeviceLib|$(PLATFORM_PACKAGE)/Library/FlashDeviceLib/FlashDevice
> LibDxe.inf
> +
> +[LibraryClasses.X64.DXE_CORE]
> +  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
> +
> MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLi
> b/DxeCoreMemoryAllocationLib.inf
> +  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +
> PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCore
> PerformanceLib.inf
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +!endif
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgen
> tLib.inf
> +!endif
> +
> +[LibraryClasses.X64.DXE_SMM_DRIVER]
> +
> MmServicesTableLib|MdePkg/Library/MmServicesTableLib/MmServicesTabl
> eLib.inf
> +
> SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesT
> ableLib.inf
> +
> ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/S
> mmReportStatusCodeLib.inf
> +
> MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMe
> moryAllocationLib.inf
> +
> LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.i
> nf
> +
> PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanc
> eLibNull.inf
> +  SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
> +
> SmmCpuPlatformHookLib|UefiCpuPkg/Library/SmmCpuPlatformHookLibNull
> /SmmCpuPlatformHookLibNull.inf
> +
> SmmCpuFeaturesLib|UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFea
> turesLib.inf
> +
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> +  !if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +  !endif
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAge
> ntLib.inf
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +!endif
> +
> CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/Smm
> CpuExceptionHandlerLib.inf
> +
> +[LibraryClasses.X64.SMM_CORE]
> +
> MemoryAllocationLib|MdeModulePkg/Library/PiSmmCoreMemoryAllocatio
> nLib/PiSmmCoreMemoryAllocationLib.inf
> +
> SmmServicesTableLib|MdeModulePkg/Library/PiSmmCoreSmmServicesTabl
> eLib/PiSmmCoreSmmServicesTableLib.inf
> +
> ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/S
> mmReportStatusCodeLib.inf
> +
> SmmCorePlatformHookLib|MdeModulePkg/Library/SmmCorePlatformHook
> LibNull/SmmCorePlatformHookLibNull.inf
> +  SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
> +
> +!if $(TPM_ENABLED) == TRUE
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> +!endif
> +
> +
> PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanc
> eLibNull.inf
> +
> +!if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +!endif
> +
> +[LibraryClasses.X64.DXE_RUNTIME_DRIVER]
> +
> ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCod
> eLib/RuntimeDxeReportStatusCodeLib.inf
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
> +!endif
> +!if $(TPM_ENABLED) == TRUE
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
> +!endif
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgen
> tLib.inf
> +!endif
> +
> +!if $(CAPSULE_ENABLE) == TRUE
> +
> CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsule
> Lib.inf
> +!endif
> +
> +[LibraryClasses.common.UEFI_DRIVER]
> +  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgen
> tLib.inf
> +!endif
> +
> +[LibraryClasses.X64.UEFI_APPLICATION]
> +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgen
> tLib.inf
> +!endif
> +
> +#########################################################
> #######################
> +#
> +# Pcd Section - list of all EDK II PCD Entries defined by this Platform
> +#
> +#########################################################
> #######################
> +[PcdsFeatureFlag.common]
> +!if $(MINI_BIOS_ENABLE) == FALSE
> +  gPlatformModuleTokenSpaceGuid.PcdBdsDispatchAdditionalOprom|TRUE
> +!else
> +
> gPlatformModuleTokenSpaceGuid.PcdBdsDispatchAdditionalOprom|FALSE
> +!endif
> +#
> +# If PcdDxeIplSwitchToLongMode is TRUE, DxeIpl will load a 64-bit DxeCore
> and switch to long mode to hand over to DxeCore.
> +#
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|TRUE
> +
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserGrayOutTextStatement|TR
> UE
> +
> +!if $(CAPSULE_RESET_ENABLE) == TRUE
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|TRUE
> +!else
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|FALS
> E
> +!endif
> +  gEfiCpuTokenSpaceGuid.PcdCpuSmmEnableBspElection|FALSE
> +!if $(DATAHUB_STATUS_CODE_ENABLE) == TRUE
> +
> gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeUseDataHub
> |TRUE
> +!else
> +
> gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeUseDataHub
> |FALSE
> +!endif
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreImageLoaderSearchTeSecti
> onFirst|FALSE
> +!if $(TARGET) == RELEASE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
> +!else
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
> +!endif
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE
> +!if $(ISA_SERIAL_STATUS_CODE_ENABLE) == TRUE
> +  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseIsaSerial|TRUE
> +!else
> +  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseIsaSerial|FALSE
> +!endif
> +!if $(USB_SERIAL_STATUS_CODE_ENABLE) == TRUE
> +  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseUsbSerial|TRUE
> +!else
> +  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseUsbSerial|FALSE
> +!endif
> +!if $(RAM_SERIAL_STATUS_CODE_ENABLE) == TRUE
> +  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseRam|TRUE
> +!else
> +  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseRam|FALSE
> +!endif
> +
> +
> +  ## This PCD specifies whether PS2 keyboard does a extended verification
> during start.
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdPs2KbdExtendedVerification|FALSE
> +
> +  ## This PCD specifies whether PS2 mouse does a extended verification
> during start.
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdPs2MouseExtendedVerification|FA
> LSE
> +
> +!if $(VARIABLE_INFO_ENABLE) == TRUE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics|TRUE
> +!else
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics|FALSE
> +!endif
> +
> +  gEfiCpuTokenSpaceGuid.PcdCpuSmmBlockStartupThisAp|TRUE
> +
> +!if $(SOURCE_DEBUG_ENABLE)
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmDebug|TRUE
> +!endif
> +
> +[PcdsFixedAtBuild.common]
> +!if $(MINNOW2_FSP_BUILD) == TRUE
> +# $(FLASH_REGION_VLVMICROCODE_BASE)
> +
> gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress|0xFFC00000
> +# $(FLASH_REGION_VLVMICROCODE_SIZE)
> +
> gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize|0x0004000
> 0
> +  gFspWrapperTokenSpaceGuid.PcdFlashMicroCodeOffset|0x60
> +# $(FLASH_AREA_BASE_ADDRESS)
> +  gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheAddress|0xFF800000
> +# $(FLASH_AREA_SIZE)
> +  gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheSize|0x00800000
> +# $(FLASH_REGION_FSPBIN_BASE)
> +  gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase|0xFFCC0000
> +!endif
> +
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +!if $(MINNOW2_FSP_BUILD) == TRUE
> +  # in FSP, when this got used, the memory already is up
> +  gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0x00080000
> +!else
> +  gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0xFEF80000
> +!endif
> +  gEfiCpuTokenSpaceGuid.PcdTemporaryRamSize|0x00010000
> +
> +!else
> +  !if $(MINNOW2_FSP_BUILD) == TRUE
> +    gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0x00080000
> +  !else
> +    gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0xFEF80000
> +  !endif
> +  gEfiCpuTokenSpaceGuid.PcdTemporaryRamSize|0x00010000
> +  gEfiCpuTokenSpaceGuid.PcdPeiTemporaryRamStackSize|0x3C00
> +!endif
> +
> +
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x22000
> +!else
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x4000
> +!endif
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize|0x00000800
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x4
> 00
> +  gEfiCpuTokenSpaceGuid.PcdCpuIEDRamSize|0x400000
> +
> gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemory
> Size|0x10000
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|FALSE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAriSupport|FALSE
> +  gEfiCpuTokenSpaceGuid.PcdCpuSmmApSyncTimeout|1000
> +!if $(S4_ENABLE) == TRUE
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationC
> hange|TRUE
> +!else
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationC
> hange|FALSE
> +!endif
> +!if $(TARGET) == RELEASE
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0
> +  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x3
> +!else
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
> +  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
> +!endif
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0x1
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPerformanceLogEntries|60
> +!endif
> +
> +
> gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdEbdaReservedMemorySi
> ze|0x10000
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable|$(
> TOP_MEMORY_ADDRESS)
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserSubtitleTextColor|0x0
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldTextColor|0x01
> +  gEfiCpuTokenSpaceGuid.PcdCpuIEDEnabled|TRUE
> +
> gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBiosVideoCheckVbeEna
> ble|TRUE
> +
> gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBiosVideoCheckVgaEnab
> le|TRUE
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
> +  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl|FAL
> SE
> +
> gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod|2
> +!endif
> +
> +  #
> +  # Set SMM stack size to 16 KB.
> +  #
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize|0x4000
> +
> +  #
> +  # Clear unused single certificate PCD
> +  #
> +  gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer|{0}
> +
> +  #
> +  # Lock all updatable firmware devices at End of DXE
> +  #
> +
> gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceLockEventGuid|{GUID(gEfiE
> ndOfDxeEventGroupGuid)}
> +#
> gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceLockEventGuid|{GUID(gEfiE
> ventReadyToBootGuid)}
> +
> +  #
> +  # Set PcdFmpDeviceTestKeySha256Digest to {0} to disable test key
> detection
> +  #
> +#  gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceTestKeySha256Digest|{0}
> +
> +[PcdsFixedAtBuild.IA32]
> +!if $(TARGET) == RELEASE
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0
> +  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x3
> +!else
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
> +  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
> +!endif
> +
> +!if $(RECOVERY_ENABLE)
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdRecoveryFileName|L"VLV2REC.Cap
> "
> +!endif
> +
> +[PcdsPatchableInModule.common]
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x803805c6
> +
> gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0x$(PLATFORM_PC
> IEXPRESS_BASE)
> +
> gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLegacyBiosCacheLegacy
> Region|FALSE
> +
> +  ## This PCD specifies whether to use the optimized timing for best PS2
> detection performance.
> +  #  Note this PCD could be set to TRUE for best boot performance and set to
> FALSE for best device compatibility.
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFastPS2Detection|TRUE
> +
> +
> ##########################################################
> #############################################
> +  #
> +  # Begin of MRC parameters
> +  #
> +
> +  ## Memory Parameter Patchable.
> +  #  FALSE - MRC Parameters are fixed for MinnowBoard Max<BR>
> +  #  TRUE  - MRC Parameters are patchable by following PCDs<BR>
> +  # @Prompt Memory Parameter Patchable.
> +  # @ValidList 0x80000001 | 0, 1
> +  gVlvRefCodePkgTokenSpaceGuid.PcdMemoryParameterPatchable|FALSE
> +
> +  ## Memory Down or DIMM slot.
> +  #  0 - DIMM<BR>
> +  #  1 - Memory Down<BR>
> +  # @Prompt Enable Memory Down
> +  # @ValidList 0x80000001 | 0, 1
> +  gVlvRefCodePkgTokenSpaceGuid.PcdEnableMemoryDown|1
> +
> +  ## The speed of DRAM.
> +  #  0 - 800 MHz<BR>
> +  #  1 - 1066 MHz<BR>
> +  #  2 - 1333 MHz<BR>
> +  #  3 - 1600 MHz<BR>
> +  # @Prompt DRAM Speed
> +  # @ValidList 0x80000001 | 0, 1, 2, 3
> +  gVlvRefCodePkgTokenSpaceGuid.PcdDramSpeed|1
> +
> +  ## DRAM Type.
> +  #  0 - DDR3<BR>
> +  #  1 - DDR3L<BR>
> +  #  2 - DDR3U<BR>
> +  #  3 - DDR3All<BR>
> +  #  4 - LPDDR2<BR>
> +  #  5 - LPDDR3<BR>
> +  #  6 - DDR4<BR>
> +  # @Prompt DRAM Type
> +  # @ValidList 0x80000001 | 0, 1, 2, 3, 4, 5, 6
> +  gVlvRefCodePkgTokenSpaceGuid.PcdDramType|1
> +
> +  ## Please populate DIMM slot 0 if only one DIMM is supported.
> +  #  0 - Disable<BR>
> +  #  1 - Enable<BR>
> +  # @Prompt DIMM 0 Enable
> +  # @ValidList 0x80000001 | 0, 1
> +  gVlvRefCodePkgTokenSpaceGuid.PcdEnableDimm0|1
> +
> +  ## DIMM 1 has to be identical to DIMM 0.
> +  #  0 - Disable<BR>
> +  #  1 - Enable<BR>
> +  # @Prompt DIMM 1 Enable Type
> +  # @ValidList 0x80000001 | 0, 1
> +  gVlvRefCodePkgTokenSpaceGuid.PcdEnableDimm1|0
> +
> +  ## DRAM device data width.
> +  #  0 - x8<BR>
> +  #  1 - x16<BR>
> +  #  2 - x32<BR>
> +  # @Prompt DIMM_DWIDTH
> +  # @ValidList 0x80000001 | 0, 1, 2
> +  gVlvRefCodePkgTokenSpaceGuid.PcdDimmDataWidth|1
> +
> +  ## DRAM device data density.
> +  #  0 - 1 Gbit<BR>
> +  #  1 - 2 Gbit<BR>
> +  #  2 - 4 Gbit<BR>
> +  #  3 - 8 Gbit<BR>
> +  # @Prompt DIMM_Density
> +  # @ValidList 0x80000001 | 0, 1, 2, 3
> +  gVlvRefCodePkgTokenSpaceGuid.PcdDimmDensity|2
> +
> +  ## DRAM device data bus width.
> +  #  0 - 8 bits<BR>
> +  #  1 - 16 bits<BR>
> +  #  2 - 32 bits<BR>
> +  #  3 - 64 bits<BR>
> +  # @Prompt DIMM_BusWidth
> +  # @ValidList 0x80000001 | 0, 1, 2, 3
> +  gVlvRefCodePkgTokenSpaceGuid.PcdDimmBusWidth|3
> +
> +  ## Ranks Per DIMM or Sides Per DIMM.
> +  #  0 - 1 Rank<BR>
> +  #  1 - 2 Ranks<BR>
> +  # @Prompt DIMM_Sides
> +  # @ValidList 0x80000001 | 0, 1
> +  gVlvRefCodePkgTokenSpaceGuid.PcdRankPerDimm|0
> +
> +  ## tCL.<BR><BR>
> +  # @Prompt tCL
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTcl|11
> +
> +  ## tRP and tRCD in DRAM clk - 5:12.5ns, 6:15ns, etc.
> +  # @Prompt tRP_tRCD
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTrpTrcd|11
> +
> +  ## tWR in DRAM clk.
> +  # @Prompt tWR
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTwr|12
> +
> +  ## tWTR in DRAM clk.
> +  # @Prompt tWTR
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTwtr|6
> +
> +  ## tRRD in DRAM clk.
> +  # @Prompt tRRD
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTrrd|6
> +
> +  ## tRTP in DRAM clk.
> +  # @Prompt tRTP
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTrtp|6
> +
> +  ## tFAW in DRAM clk.
> +  # @Prompt tFAW
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTfaw|32
> +
> +  #
> +  # End of MRC parameters.
> +  #
> +
> ##########################################################
> #####################################
> +
> +[PcdsDynamicHii.common.DEFAULT]
> +
> gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlo
> balVariableGuid|0x0|5 # Variable: L"Timeout"
> +
> gEfiMdePkgTokenSpaceGuid.PcdHardwareErrorRecordLevel|L"HwErrRecSup
> port"|gEfiGlobalVariableGuid|0x0|1 # Variable: L"HwErrRecSupport"
> +
> +[PcdsDynamicDefault.common.DEFAULT]
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr|0x
> 0
> +  !if $(TPM_ENABLED) == TRUE
> +    gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{0x7b, 0x3a, 0xcd,
> 0x72, 0xA5, 0xFE, 0x5e, 0x4f, 0x91, 0x65, 0x4d, 0xd1, 0x21, 0x87, 0xbb, 0x13}
> +  !endif
> +
> +  ## This PCD defines the video horizontal resolution.
> +  #  This PCD could be set to 0 then video resolution could be at highest
> resolution.
> +  #gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|0
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|800
> +  ## This PCD defines the video vertical resolution.
> +  #  This PCD could be set to 0 then video resolution could be at highest
> resolution.
> +  #gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|0
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600
> +
> +  ## This PCD defines the Console output column and the default value is 25
> according to UEFI spec.
> +  #  This PCD could be set to 0 then console output could be at max column
> and max row.
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|31
> +  ## This PCD defines the Console output row and the default value is 80
> according to UEFI spec.
> +  #  This PCD could be set to 0 then console output could be at max column
> and max row.
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|100
> +
> +  ## The PCD is used to specify the video horizontal resolution of text setup.
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|80
> 0
> +  ## The PCD is used to specify the video vertical resolution of text setup.
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|600
> +  ## The PCD is used to specify the console output column of text setup.
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutColumn|100
> +  ## The PCD is used to specify the console output column of text setup.
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutRow|31
> +
> +!if $(TPM_ENABLED) == TRUE
> +  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInitializationPolicy|1
> +  gEfiSecurityPkgTokenSpaceGuid.PcdTpmScrtmPolicy|1
> +!endif
> +
> +[PcdsDynamicExDefault.common.DEFAULT]
> +  gEfiVLVTokenSpaceGuid.PcdTCSmbaIoBaseAddress|0x1040
> +  gEfiVLVTokenSpaceGuid.PcdEmmcManufacturerId|0
> +  gEfiVLVTokenSpaceGuid.PcdProductSerialNumber|0
> +  gEfiVLVTokenSpaceGuid.PcdMeasuredBootEnable|TRUE
> +  gEfiVLVTokenSpaceGuid.PcdFTPMErrorOccur|FALSE
> +  gEfiVLVTokenSpaceGuid.PcdFTPMErrorSkip|FALSE
> +  gEfiVLVTokenSpaceGuid.PcdFTPMCommand|0
> +  gEfiVLVTokenSpaceGuid.PcdFTPMResponse|0
> +  gEfiVLVTokenSpaceGuid.PcdFTPMNotRespond|FALSE
> +  gEfiVLVTokenSpaceGuid.PcdFTPMStatus|0
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateSmmDataP
> tr|0
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr|0
> +  gEfiCpuTokenSpaceGuid.PcdCpuS3DataAddress|0
> +  gEfiCpuTokenSpaceGuid.PcdCpuHotPlugDataAddress|0
> +  gEfiCpuTokenSpaceGuid.PcdCpuCallbackSignal|0
> +  gEfiCpuTokenSpaceGuid.PcdCpuConfigContextBuffer|0
> +  gEfiVLVTokenSpaceGuid.PcdCpuLockBoxDataAddress|0
> +  gEfiVLVTokenSpaceGuid.PcdCpuSmramCpuDataAddress|0
> +  gEfiVLVTokenSpaceGuid.PcdCpuLockBoxSize|0
> +
> +[PcdsDynamicExDefault.X64.DEFAULT]
> +!if $(RECOVERY_ENABLE)
> +
> gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareFileGuid|{G
> UID("AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215")}|VOID*|0x10
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdSystemFmpCapsuleImageTypeIdGu
> id|{GUID("4096267b-da0a-42eb-b5eb-fef31d207cb4")}|VOID*|0x10
> +!endif
> +
> +[Components.IA32]
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/S
> ecCore.inf
> +
> +  !if $(MINNOW2_FSP_BUILD) == TRUE
> +  IntelFspWrapperPkg/FspWrapperSecCore/FspWrapperSecCore.inf {
> +    !if $(TARGET) == DEBUG
> +
> +    <LibraryClasses>
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +    !endif
> +  }
> +  Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.inf
> +  IntelFspWrapperPkg/FspInitPei/FspInitPei.inf {
> +    !if $(TARGET) == DEBUG
> +    <LibraryClasses>
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +    !endif
> +  }
> +  !endif
> +
> +  MdeModulePkg/Core/Pei/PeiMain.inf {
> +!if $(TARGET) == DEBUG
> +    <PcdsFixedAtBuild>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
> +!endif
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
> +  }
> +
> +  $(PLATFORM_PACKAGE)/MonoStatusCode/MonoStatusCode.inf {
> +!if $(TARGET) == DEBUG
> +    <PcdsFixedAtBuild>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
> +!endif
> +  }
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/M
> emoryInit.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
> +    <BuildOptions>
> +      !if $(FTPM_ENABLE)==TRUE
> +        *_*_IA32_CC_FLAGS = /D FTPM_ENABLE
> +      !endif
> +  }
> +
> +!if $(RC_BINARY_RELEASE) == TRUE
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/S
> eCUma.inf
> +!endif
> +
> +!if $(FTPM_ENABLE) == TRUE
> +$(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/f
> TPMInitPeim.inf
> +!endif
> +
> +!if $(RC_BINARY_RELEASE) == TRUE
> +  $(PLATFORM_PACKAGE)/PlatformPei/PlatformPei.inf {
> +    <BuildOptions>
> +      *_*_IA32_CC_FLAGS      = -DRC_BINARY_RELEASE
> +  !if $(TARGET) == DEBUG
> +      <PcdsFixedAtBuild>
> +        gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
> +  !endif
> +  }
> +!endif
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +  SourceLevelDebugPkg/DebugAgentPei/DebugAgentPei.inf{
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAg
> entLib.inf
> +
> PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePla
> tformHookLibNull.inf
> +
> SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPort
> Lib16550.inf
> +    }
> +!endif
> +
> +!if $(FTPM_ENABLE) == TRUE
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/T
> pm2DeviceSeCPei.inf
> +!endif
> +
> +!if $(TPM_ENABLED) == TRUE
> +  SecurityPkg/Tcg/PhysicalPresencePei/PhysicalPresencePei.inf
> +  SecurityPkg/Tcg/TcgPei/TcgPei.inf {
> +    <LibraryClasses>
> +
> NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
> +
> NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.in
> f
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +}
> +!endif
> +
> + $(PLATFORM_PACKAGE)/PlatformInitPei/PlatformInitPei.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x803805c6
> +    <LibraryClasses>
> +!if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +!endif
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +  }
> +  $(PLATFORM_PACKAGE)/FvInfoPei/FvInfoPei.inf
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/Vl
> vInitPeim.inf
> +!if $(PCIESC_ENABLE) == TRUE
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chEarlyInitPeim.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
> +  }
> +!endif
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chInitPeim.inf
> +
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chSmbusArpDisabled.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chSpiPeim.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> eiSmmAccess.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> eiSmmControl.inf
> +  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/C
> puPeim.inf
> +  UefiCpuPkg/CpuIoPei/CpuIoPei.inf
> +  UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/M
> pS3.inf
> +#
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/Pi
> SmmCommunicationPei.inf
> +
> +!if $(RECOVERY_ENABLE)
> +  #
> +  # Recovery
> +  #
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chUsb.inf
> +  MdeModulePkg/Bus/Pci/EhciPei/EhciPei.inf
> +  MdeModulePkg/Bus/Usb/UsbBusPei/UsbBusPei.inf
> +  MdeModulePkg/Bus/Usb/UsbBotPei/UsbBotPei.inf
> +  FatPkg/FatPei/FatPei.inf
> +  MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf
> +
> SignedCapsulePkg/Universal/RecoveryModuleLoadPei/RecoveryModuleLoa
> dPei.inf {
> +    <LibraryClasses>
> +
> FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibRsa2048Sh
> a256/FmpAuthenticationLibRsa2048Sha256.inf
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +  }
> +!endif
> +
> +!if $(CAPSULE_ENABLE) == TRUE
> +  MdeModulePkg/Universal/CapsulePei/CapsulePei.inf
> +!endif
> +  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
> +    <LibraryClasses>
> +!if $(LZMA_ENABLE) == TRUE
> +
> NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDec
> ompressLib.inf
> +!endif
> +  }
> +
> + MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
> +
> MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
> +
> +!if $(FTPM_ENABLE) == TRUE
> +   SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
> +    <LibraryClasses>
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +
> NULL|SecurityPkg/Library\HashInstanceLibSha1/HashInstanceLibSha1.inf
> +
> NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.in
> f
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +  }
> +!endif
> +!if $(TPM_ENABLED) == TRUE
> +  SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +  }
> +!endif
> +!if $(ACPI50_ENABLE) == TRUE
> +
> MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/Firmwa
> rePerformancePei.inf{
> +    <LibraryClasses>
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +  }
> +
> +!endif
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +
> MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCode
> RouterPei.inf
> +!endif
> +[Components.X64]
> +  !if $(MINNOW2_FSP_BUILD) == TRUE
> +  IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.inf {
> +    !if $(TARGET) == DEBUG
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
> +    <LibraryClasses>
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +    !endif
> +  }
> +
> +  !endif
> +  #
> +  # EDK II Related Platform codes
> +  #
> +  MdeModulePkg/Core/Dxe/DxeMain.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
> +    <LibraryClasses>
> +!if $(DXE_CRC32_SECTION_ENABLE) == TRUE
> +
> NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32G
> uidedSectionExtractLib.inf
> +!endif
> +!if $(LZMA_ENABLE) == TRUE
> +
> NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDec
> ompressLib.inf
> +!endif
> +!if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +!endif
> +  }
> +
> IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3SaveDxe.i
> nf {
> +    <PcdsPatchableInModule>
> +        gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
> +    <PcdsFixedAtBuild>
> +        gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x27
> +    <LibraryClasses>
> +    !if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +    !endif
> +       <BuildOptions>
> +        ICC:*_*_*_CC_FLAGS = -D MDEPKG_NDEBUG
> +        GCC:RELEASE_*_*_CC_FLAGS = -D MDEPKG_NDEBUG
> +  }
> +  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +  }
> +  IntelFrameworkModulePkg/Universal/CpuIoDxe/CpuIoDxe.inf
> +  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
> +
> +
> MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportSt
> atusCodeRouterRuntimeDxe.inf
> +
> MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHan
> dlerRuntimeDxe.inf  {
> +    <LibraryClasses>
> +!if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +!endif
> +  }
> +
> +!if $(CAPSULE_ENABLE) == TRUE
> +  MdeModulePkg/Universal/CapsulePei/CapsuleX64.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +
> MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemory
> AllocationLib.inf
> +      HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
> +
> CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecP
> eiCpuExceptionHandlerLib.inf
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAg
> entLib.inf
> +!endif
> +  }
> +!endif
> +
> +
> MdeModulePkg/Universal/ReportStatusCodeRouter/Smm/ReportStatusCod
> eRouterSmm.inf
> +  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf{
> +    <LibraryClasses>
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +
> NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib
> .inf
> +!endif
> +!if $(USER_IDENTIFICATION_ENABLE)
> +
> NULL|SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.in
> f
> +!endif
> +!if $(TPM_ENABLED) == TRUE
> +
> NULL|SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLi
> b.inf
> +!endif
> +!if $(FTPM_ENABLE) == TRUE
> +
> NULL|SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBoot
> Lib.inf
> +!endif
> +  }
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/MpCpu.inf
> +  $(PLATFORM_PACKAGE)/Metronome/Metronome.inf
> +
> +  IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf{
> +    <LibraryClasses>
> +      OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
> +      IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
> +      BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> +
> PlatformBdsLib|$(PLATFORM_PACKAGE)/Library/PlatformBdsLib/PlatformB
> dsLib.inf
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +
> SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
> +    !if $(FTPM_ENABLE) == TRUE
> +
> Tpm2DeviceLib|Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2Devi
> ceLibSeC.inf
> +    !else
> +
> Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2
> .inf
> +    !endif
> +  }
> +
> +  $(PLATFORM_PACKAGE)/UiApp/UiApp.inf
> +
> +  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
> +  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
> +
> MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.in
> f
> +
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.i
> nf
> +  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf {
> +    <LibraryClasses>
> +      NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
> +
> SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
> +  }
> +  $(PLATFORM_PACKAGE)/FvbRuntimeDxe/FvbSmm.inf
> +
> MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.i
> nf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchSpiSmm.inf
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +
> SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfi
> gDxe.inf {
> +    <LibraryClasses>
> +
> PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecu
> reLibNull.inf
> +    <BuildOptions>
> +      #
> +      # Specify GUID gEfiIfrBootMaintenanceGuid, to install Secure Boot
> Configuration menu
> +      # into Boot Maintenance Manager menu
> +      #
> +      *_*_*_VFR_FLAGS   = -g b2dedc91-d59f-48d2-898a-12490c74a4e0
> +  }
> +!endif
> +   MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf {
> +    <LibraryClasses>
> +      FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
> +  }
> +
> +
> MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCoun
> terRuntimeDxe.inf
> +
> PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntime
> Dxe.inf
> +  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
> +
> +  $(PLATFORM_PACKAGE)/FvbRuntimeDxe/FvbRuntimeDxe.inf
> +
> +  $(PLATFORM_PACKAGE)/PlatformSetupDxe/PlatformSetupDxe.inf
> +
> +!if $(DATAHUB_ENABLE) == TRUE
> +  IntelFrameworkModulePkg/Universal/DataHubDxe/DataHubDxe.inf {
> +    <PcdsFixedAtBuild>
> +      gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|0
> +  }
> +!endif
> +
> IntelFrameworkModulePkg/Universal/StatusCode/DatahubStatusCodeHandl
> erDxe/DatahubStatusCodeHandlerDxe.inf
> +
> MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryT
> estDxe.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchS3SupportDxe.inf
> +  !if $(USE_HPET_TIMER) == TRUE
> +    PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf
> +  !else
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SmartTimer.inf
> +  !endif
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SmmControl.inf
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchSmbusDxe.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/IntelPchLegacyInterrupt.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchReset.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchInitDxe.inf{
> +    <PcdsPatchableInModule>
> +        gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
> +  }
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchInitSmm.inf
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchSmiDispatcher.inf
> +
> +!if $(PCIESC_ENABLE) == TRUE
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchPcieSmm.inf
> +!endif
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchSpiRuntime.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchPolicyInitDxe.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchBiosWriteProtect.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SmmAccess.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PciHostBridge.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/VlvInitDxe.inf
> +
> +
> IntelFrameworkModulePkg/Universal/LegacyRegionDxe/LegacyRegionDxe.i
> nf
> +
> +  #
> +  # Performance Application; Set PERFORMANCE_ENABLE=TRUE for normal
> boot performance and smm performance data
> +  #
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +
> ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf
> {
> +    <PcdsFixedAtBuild>
> +      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> +  }
> +!endif
> +
> +  Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInitDxe.inf{
> +    <LibraryClasses>
> +!if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +!endif
> +      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  }
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/Dptf.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PnpDxe.inf
> +
> +!if $(SEC_ENABLE) == TRUE
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/HeciDrv.inf {
> +!if $(SEC_DEBUG_INFO_ENABLE) == TRUE
> +    <BuildOptions>
> +      *_*_X64_CC_FLAGS      = /DSEC_DEBUG_INFO=1
> +!else
> +    <BuildOptions>
> +      *_*_X64_CC_FLAGS      = /DSEC_DEBUG_INFO=0
> +!endif
> +  }
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SeCPolicyInitDxe.inf
> +!endif
> +
> +!if $(FTPM_ENABLE) == TRUE
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/Tpm2DeviceSeCDxe.inf
> +  SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf
> +  SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf{
> +    <LibraryClasses>
> +
> NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
> +
> NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.in
> f
> +      PcdLib|MdePkg/Library\DxePcdLib/DxePcdLib.inf
> +
> Tpm2DeviceLib|Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2Devi
> ceLibSeC.inf
> +  }
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/FtpmSmm.inf
> +!endif
> +!if $(TPM_ENABLED) == TRUE
> +  SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +  }
> +
> +  SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +    <BuildOptions>
> +      #
> +      # specify GUID gEfiIfrNotInTPVPageGuid, this page will not
> +      # be showed in TPV page.
> +      #
> +      *_*_*_VFR_FLAGS   = -g e58809f8-fbc1-48e2-883a-a30fdc4b441e
> +  }
> +
> +  SecurityPkg/Tcg/TcgDxe/TcgDxe.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  }
> +  SecurityPkg/Tcg/TcgSmm/TcgSmm.inf
> +!endif
> +  #
> +  # EDK II Related Platform codes
> +  #
> +  $(PLATFORM_PACKAGE)/PlatformSmm/PlatformSmm.inf{
> +    <LibraryClasses>
> +    !if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +    !endif
> +          PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  }
> +  $(PLATFORM_PACKAGE)/PlatformInfoDxe/PlatformInfoDxe.inf
> +  $(PLATFORM_PACKAGE)/PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf
> +  $(PLATFORM_PACKAGE)/PlatformDxe/PlatformDxe.inf
> +
> +  $(PLATFORM_PACKAGE)/PciPlatform/PciPlatform.inf
> +  $(PLATFORM_PACKAGE)/SaveMemoryConfig/SaveMemoryConfig.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PlatformCpuPolicy.inf
> +  $(PLATFORM_PACKAGE)/PpmPolicy/PpmPolicy.inf
> +
> $(PLATFORM_PACKAGE)/SmramSaveInfoHandlerSmm/SmramSaveInfoHand
> lerSmm.inf
> +!if $(GOP_DRIVER_ENABLE) == TRUE
> +  $(PLATFORM_PACKAGE)/PlatformGopPolicy/PlatformGopPolicy.inf
> +
> +!endif
> +
> +
> +  #
> +  # SMM
> +  #
> +  MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
> +  MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
> +  UefiCpuPkg/CpuDxe/CpuDxe.inf
> +  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
> +  UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
> +  MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
> +  UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
> +
> $(PLATFORM_PACKAGE)/SmmSwDispatch2OnSmmSwDispatchThunk/SmmS
> wDispatch2OnSmmSwDispatchThunk.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PowerManagement2.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/DigitalThermalSensor.inf
> +
> +  #
> +  # ACPI
> +  #
> +
> MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutor
> Dxe.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
> +    <PcdsFixedAtBuild>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x27
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  }
> +
> +  $(PLATFORM_PACKAGE)/BootScriptSaveDxe/BootScriptSaveDxe.inf
> +
> IntelFrameworkModulePkg/Universal/Acpi/AcpiSupportDxe/AcpiSupportDx
> e.inf
> +
> Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTable
> s/PowerManagementAcpiTables.inf
> +
> +  $(PLATFORM_RC_PACKAGE)/AcpiTablesPCAT/AcpiTables.inf
> +
> +  $(PLATFORM_PACKAGE)/AcpiPlatform/AcpiPlatform.inf
> +
> +
> MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraph
> icsResourceTableDxe.inf
> +
> +  #
> +  # PCI
> +  #
> +  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
> +
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/ISPDxe.inf
> +
> +
> +#
> +# ISA
> +#
> +  $(PLATFORM_PACKAGE)/Wpce791/Wpce791.inf
> +  IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBusDxe.inf
> +  IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaIoDxe.inf
> +  IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf
> +  IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf
> +
> IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf
> +#
> +# SDIO
> +#
> +#
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/MmcHost.inf
> +#
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/MmcMediaDevice.inf
> +!if $(ACPI50_ENABLE) == TRUE
> +
> MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/Firmw
> arePerformanceDxe.inf {
> +    <LibraryClasses>
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +  }
> +
> MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/Firm
> warePerformanceSmm.inf {
> +    <LibraryClasses>
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +  }
> +!endif
> +
> +#
> +# IDE/SCSI/AHCI
> +#
> +  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
> +  IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBusDxe.inf
> +  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
> +  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
> +
> MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
> +  FatPkg/EnhancedFatDxe/Fat.inf
> +  ShellPkg/Application/Shell/Shell.inf {
> +    <LibraryClasses>
> +
> ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellComma
> ndLib.inf
> +
> NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2Comma
> ndsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1Comma
> ndsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3Comma
> ndsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1Com
> mandsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1Com
> mandsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1Com
> mandsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1
> CommandsLib.inf
> +
> HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingL
> ib.inf
> +      PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
> +
> BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfg
> CommandLib.inf
> +    <PcdsFixedAtBuild>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
> +      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> +      gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
> +  }
> +!if $(SATA_ENABLE) == TRUE
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SataController.inf
> +!endif
> +  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
> +!if $(SCSI_ENABLE) == TRUE
> +  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
> +  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
> +!endif
> +#
> +# Console
> +#
> +  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
> +  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
> +
> MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleD
> xe.inf
> +
> IntelFrameworkModulePkg/Universal/Console/VgaClassDxe/VgaClassDxe.in
> f
> +  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
> +  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
> +  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
> +  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
> +
> +  #
> +  # USB
> +  #
> +!if $(USB_ENABLE) == TRUE
> +  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
> +  MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
> +  MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
> +  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
> +  MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
> +  MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
> +  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
> +
> +!endif
> +
> +  #
> +  # SMBIOS
> +  #
> +  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
> +  $(PLATFORM_PACKAGE)/SmBiosMiscDxe/SmBiosMiscDxe.inf
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SmbiosMemory.inf
> +  #
> +  # CPU/FW Microde
> +  #
> +  Vlv2SocBinPkg/Microcode/MicrocodeUpdates.inf {
> +    <BuildOptions>
> +      *_*_*_GENFW_FLAGS = -a 0x800 -p 0xFF
> +  }
> +
> +
> +
> +!if $(NETWORK_ENABLE) == TRUE
> +  !if $(NETWORK_ISCSI_ENABLE) == TRUE
> +    NetworkPkg/IScsiDxe/IScsiDxe.inf
> +  !endif
> +  !if $(NETWORK_VLAN_ENABLE) == TRUE
> +    MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf
> +  !endif
> +  !if $(CSM_ENABLE) == TRUE
> +    IntelFrameworkModulePkg/Csm/BiosThunk/Snp16Dxe/Snp16Dxe.inf
> +  !endif
> +!endif
> +
> +!if $(NETWORK_ENABLE) == TRUE
> +  #
> +  # UEFI network modules
> +  #
> +    MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
> +    MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf
> +
> +    MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
> +    MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
> +    MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
> +    MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
> +    MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
> +    NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
> +    NetworkPkg/TcpDxe/TcpDxe.inf
> +    MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
> +    !if $(NETWORK_IP6_ENABLE) == TRUE
> +      NetworkPkg/Ip6Dxe/Ip6Dxe.inf
> +      NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
> +      NetworkPkg/Udp6Dxe/Udp6Dxe.inf
> +      NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
> +    !endif
> +!endif
> +
> +!if $(CAPSULE_ENABLE) || $(MICOCODE_CAPSULE_ENABLE)
> +  MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxe.inf
> +  MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> +!endif
> +
> +!if $(CAPSULE_ENABLE)
> +  !include Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc
> +  !include Vlv2TbltDevicePkg/FmpGreenSampleDevice.dsc
> +  !include Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc
> +  !include Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc
> +!endif
> +
> +!if $(MICOCODE_CAPSULE_ENABLE)
> +
> IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDx
> e.inf {
> +    <LibraryClasses>
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +
> SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
> +  }
> +!endif
> +
> +[BuildOptions]
> +#
> +# Define Build Options both for EDK and EDKII drivers.
> +#
> +
> +#
> +# Define token for different Platform
> +#
> +!if $(MINNOW2_FSP_BUILD) == TRUE
> +  DEFINE MINNOW2_FSP_OPTION = -DMINNOW2_FSP_BUILD
> +!else
> +  DEFINE MINNOW2_FSP_OPTION =
> +!endif
> +
> +!if $(ENBDT_PF_BUILD) == TRUE
> +  DEFINE ENBDT_PF_ENABLE = -DENBDT_PF_ENABLE=1
> +!else
> +  DEFINE ENBDT_PF_ENABLE = -DENBDT_PF_ENABLE=0
> +!endif
> +
> +
> +!if $(CLKGEN_CONFIG_EXTRA_ENABLE) == TRUE
> +  DEFINE CLKGEN_CONFIG_EXTRA_BUILD_OPTION = -
> DCLKGEN_CONFIG_EXTRA=1
> +!else
> +  DEFINE CLKGEN_CONFIG_EXTRA_BUILD_OPTION =
> +!endif
> +
> +
> +
> +!if $(PCIESC_ENABLE) == TRUE
> +  DEFINE PCIESC_SUPPORT_BUILD_OPTION = -DPCIESC_SUPPORT=1
> +!else
> +  DEFINE PCIESC_SUPPORT_BUILD_OPTION =
> +!endif
> +!if $(SATA_ENABLE) == TRUE
> +  DEFINE SATA_SUPPORT_BUILD_OPTION = -DSATA_SUPPORT=1
> +!else
> +  DEFINE SATA_SUPPORT_BUILD_OPTION =
> +!endif
> +!if $(ENBDT_S3_SUPPORT) == TRUE
> +  DEFINE ENBDT_S3_SUPPORT_OPTIONS = -DNOCS_S3_SUPPORT
> +!else
> +  DEFINE ENBDT_S3_SUPPORT_OPTIONS =
> +!endif
> +
> +!if $(X64_CONFIG) == TRUE
> +  DEFINE X64_BUILD_ENABLE = -DX64_BUILD_ENABLE=1
> +!else
> +  DEFINE X64_BUILD_ENABLE =
> +!endif
> +
> +!if $(FTPM_ENABLE) == TRUE
> +  DEFINE DSC_FTPM_BUILD_OPTIONS = -DFTPM_ENABLE
> +!else
> +  DEFINE DSC_FTPM_BUILD_OPTIONS =
> +!endif
> +!if $(TPM_ENABLED) == TRUE
> +  DEFINE DSC_TPM_BUILD_OPTIONS = -DTPM_ENABLED
> +!else
> +  DEFINE DSC_TPM_BUILD_OPTIONS =
> +!endif
> +
> +
> +  DEFINE EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS =
> $(MINNOW2_FSP_OPTION) $(MINNOW2_BUILD_OPTION)
> $(ENBDT_PF_ENABLE) $(EXTERNAL_VGA_BUILD_OPTION)
> $(PCIE_ENUM_WA_BUILD_OPTION) $(X0_WA_ENABLE_BUILD_OPTION)
> $(A0_WA_ENABLE_BUILD_OPTION) $(MICROCODE_FREE_BUILD_OPTIONS)
> $(SIMICS_BUILD_OPTIONS) $(HYBRID_BUILD_OPTIONS)
> $(COMPACT_BUILD_OPTIONS) $(VP_BUILD_OPTIONS)
> $(SYSCTL_ID_BUILD_OPTION) $(CLKGEN_CONFIG_EXTRA_BUILD_OPTION)
> $(SYSCTL_X0_CONVERT_BOARD_OPTION) $(ENBDT_S3_SUPPORT_OPTIONS)
> $(SATA_SUPPORT_BUILD_OPTION) $(PCIESC_SUPPORT_BUILD_OPTION)
> $(DSC_FTPM_BUILD_OPTIONS) $(DSC_FTPM_ERROR_WR_BUILD_OPTIONS)
> $(DSC_TPM_BUILD_OPTIONS) $(DSC_BYTI_SECURE_BOOT_BUILD_OPTIONS)
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +  DEFINE PDB_BUILD_OPTION = /Zi
> +!endif
> +
> +  GCC:*_*_*_CC_FLAGS = -Wno-missing-braces
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +  MSFT:*_*_X64_GENFW_FLAGS  = --keepexceptiontable
> +  GCC:*_*_X64_GENFW_FLAGS   = --keepexceptiontable
> +  INTEL:*_*_X64_GENFW_FLAGS = --keepexceptiontable
> +  DEFINE SOURCE_LEVEL_DEBUG_BUILD_OPTIONS =
> +!else
> +  DEFINE SOURCE_LEVEL_DEBUG_BUILD_OPTIONS =
> +
> +!endif
> +
> +#
> +# Force PE/COFF sections to be aligned at 4KB boundaries to support page
> level
> +# protection of DXE_RUNTIME_DRIVER modules
> +#
> +[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
> +  MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
> +  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
> +
> +#
> +# Force PE/COFF sections to be aligned at 4KB boundaries to support page
> level
> +# protection of DXE_SMM_DRIVER/SMM_CORE modules
> +#
> +[BuildOptions.common.EDKII.DXE_SMM_DRIVER,
> BuildOptions.common.EDKII.SMM_CORE]
> +  MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
> +  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
> +
> +[BuildOptions.Common.EDK]
> +
> +#
> +# Define token for different Platform
> +#
> +!if $(ENBDT_PF_BUILD) == TRUE
> +  DEFINE ENBDT_PF_ENABLE = -DENBDT_PF_ENABLE=1
> +!else
> +  DEFINE ENBDT_PF_ENABLE = -DENBDT_PF_ENABLE=0
> +!endif
> +
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +  RELEASE_*_*_DLINK_FLAGS = -DEBUG
> +!endif
> +
> +!if $(S3_ENABLE) == TRUE
> +  DEFINE DSC_S3_BUILD_OPTIONS = -DEFI_S3_RESUME
> +!else
> +  DEFINE DSC_S3_BUILD_OPTIONS =
> +!endif
> +
> +!if $(ENBDT_S3_SUPPORT) == TRUE
> +  DEFINE ENBDT_S3_SUPPORT_OPTIONS = -DNOCS_S3_SUPPORT
> +!else
> +  DEFINE ENBDT_S3_SUPPORT_OPTIONS =
> +!endif
> +
> +!if $(X64_CONFIG) == TRUE
> +  DEFINE X64_BUILD_ENABLE = -DX64_BUILD_ENABLE=1
> +!else
> +  DEFINE X64_BUILD_ENABLE =
> +!endif
> +
> +
> +  DEFINE EDK_GLUE_LIB_DEBUG  =
> +  DEFINE DEBUG_BUILD_OPTIONS = -D EFI_DEBUG -D DEBUG_MODE=1
> /GL- $(EDK_GLUE_LIB_DEBUG) -
> DEDKII_GLUE_DebugPrintErrorLevel=(EFI_D_ERROR)
> +  DEFINE EDK_DSC_FEATURE_BUILD_OPTIONS = $(DSC_S3_BUILD_OPTIONS)
> $(DSC_ACPI_BUILD_OPTIONS) $(DSC_SEC_BUILD_OPTIONS)
> $(DSC_FTPM_BUILD_OPTIONS) $(DSC_FTPM_ERROR_WR_BUILD_OPTIONS)
> $(DSC_TPM_BUILD_OPTIONS) $(SOFTSDV_BUILD_OPTIONS)
> $(SIMICS_BUILD_OPTIONS) $(HYBRID_BUILD_OPTIONS)
> $(COMPACT_BUILD_OPTIONS) $(VP_BUILD_OPTIONS)
> $(QT_BUILD_OPTIONS) $(DSC_BYTI_SECURE_BOOT_BUILD_OPTIONS) -
> D$(PROJECT_SC_CHIPSET)
> +
> +  DEFINE EDK_DSC_OTHER_BUILD_OPTIONS =
> $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS) $(SV_BUILD_OPTIONS)
> $(INTEL_FASTBOOT_BUILD_OPTION)
> +  DEFINE EDK_DSC_GLOBAL_BUILD_OPTIONS = $(ENBDT_PF_ENABLE)
> $(EDK_DSC_FEATURE_BUILD_OPTIONS)
> $(EDK_DSC_OTHER_BUILD_OPTIONS) -D
> EFI_SPECIFICATION_VERSION=0x00020000  -D
> PI_SPECIFICATION_VERSION=0x00000009  -D
> TIANO_RELEASE_VERSION=0x00080006 -D
> SUPPORT_DEPRECATED_PCI_CFG_PPI -D CSM_SMMENTRY_PORT8DATA8 -D
> EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE) -D
> MAX_VARIABLE_SIZE=0x2000 -D EFI_FIRMWARE_VENDOR="L/"INTEL/"" -D
> EFI_BUILD_VERSION="L/"EDKII/"" -DEFI_PEI_REPORT_STATUS_CODE_ON
> $(ENBDT_S3_SUPPORT_OPTIONS)
> +
> +  *_*_IA32_ASM_FLAGS         = -DEFI32 -D
> EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h -
> DNOCS_S3_SUPPORT
> +  DEBUG_*_IA32_CC_FLAGS      = -D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_IA32_CC_FLAGS    = -D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  DEBUG_*_IA32_VFRPP_FLAGS   = -D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_IA32_VFRPP_FLAGS = -D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  DEBUG_*_IA32_APP_FLAGS     = -D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_IA32_APP_FLAGS   = -D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  DEBUG_*_IA32_PP_FLAGS      = -D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_IA32_PP_FLAGS    = -D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  *_*_IA32_ASLPP_FLAGS       = -D
> EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
> +  *_*_IA32_ASLCC_FLAGS       = -D
> EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
> +  *_*_IA32_ASM16_FLAGS       = -D
> EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h
> +
> +  *_*_X64_ASM_FLAGS          = -DEFIX64 -D
> EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h -
> DNOCS_S3_SUPPORT
> +  DEBUG_*_X64_CC_FLAGS       = -D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_X64_CC_FLAGS     = -D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  DEBUG_*_X64_VFRPP_FLAGS    = -D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_X64_VFRPP_FLAGS  = -D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  DEBUG_*_X64_APP_FLAGS      = -D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_X64_APP_FLAGS    = -D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  DEBUG_*_X64_PP_FLAGS       = -D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_X64_PP_FLAGS     = -D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  *_*_X64_ASLPP_FLAGS        = -D
> EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
> +  *_*_X64_ASLCC_FLAGS        = -D
> EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
> +  *_*_X64_ASM16_FLAGS        = -D
> EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h
> + # *_*_*_BUILD_FLAGS = -s
> +  *_*_*_VFR_FLAGS   = -c
> +  *_*_*_BUILD_FLAGS = -c
> +
> +[BuildOptions.Common.EDKII]
> +  *_*_IA32_ASM_FLAGS     = $(VP_BUILD_OPTIONS) -D
> EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h -
> DNOCS_S3_SUPPORT
> +
> +  *_*_IA32_CC_FLAGS      = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +  *_*_IA32_VFRPP_FLAGS   = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +  *_*_IA32_APP_FLAGS     = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +  *_*_IA32_PP_FLAGS      = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +  *_*_IA32_ASLPP_FLAGS   = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +
> +  *_*_X64_CC_FLAGS       = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> $(SOURCE_LEVEL_DEBUG_BUILD_OPTIONS)
> +  *_*_X64_VFRPP_FLAGS    = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +  *_*_X64_APP_FLAGS      = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +  *_*_X64_PP_FLAGS       = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +  *_*_X64_ASLPP_FLAGS    = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +
> +
> +[Components.X64]
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/I2cBus.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
> +  }
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/I2cHost.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
> +  }
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/I2cPortA0Pio.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x00000043
> +  }
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/I2cMmioDeviceDxe.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x00000043
> +  }
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgIA32.dsc
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgIA32.dsc
> new file mode 100644
> index 0000000000..2324794841
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgIA32.dsc
> @@ -0,0 +1,1699 @@
> +#/** @file
> +# Platform description.
> +#
> +# Copyright (c) 2012  - 2019, 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]
> +  PLATFORM_NAME                       = Vlv2TbltDevicePkg
> +  PLATFORM_GUID                       = 465B0A0B-7AC1-443b-8F67-7B8DEC145F90
> +  PLATFORM_VERSION                    = 0.1
> +  DSC_SPECIFICATION                   = 0x00010005
> +
> +  #
> +  # Set platform specific package/folder name, same as passed from
> PREBUILD script.
> +  # PLATFORM_PACKAGE would be the same as PLATFORM_NAME as well
> as package build folder
> +  # DEFINE only takes effect at R9 DSC and FDF.
> +  #
> +  DEFINE      PLATFORM_PACKAGE                = Vlv2TbltDevicePkg
> +  DEFINE      PLATFORM_RC_PACKAGE             = Vlv2DeviceRefCodePkg
> +  DEFINE      PLATFORM_BINARY_PACKAGE         = Vlv2SocBinPkg
> +  OUTPUT_DIRECTORY                    = Build/$(PLATFORM_PACKAGE)
> +  SUPPORTED_ARCHITECTURES             = IA32
> +  BUILD_TARGETS                       = DEBUG|RELEASE
> +  SKUID_IDENTIFIER                    = DEFAULT
> +
> +  DEFINE CPU_ARCH                 =ValleyView2
> +  DEFINE PROJECT_SC_FAMILY        =IntelPch
> +  DEFINE PROJECT_SC_ROOT
> =../$(PLATFORM_RC_PACKAGE)/ValleyView2Soc/SouthCluster
> +  DEFINE PROJECT_VLV_ROOT
> =../$(PLATFORM_RC_PACKAGE)/ValleyView2Soc/NorthCluster
> +
> +  DEFINE RC_BINARY_RELEASE        = TRUE
> +  #
> +  # Platform On/Off features are defined here
> +  #
> +  #
> +  # Platform Support:: Set only one token except Crestview Hills
> +  #
> +  #   3.BayleyBay
> +  #     ENBDT_PF_ENABLE  = TRUE
> +  #
> +  !include $(PLATFORM_PACKAGE)/AutoPlatformCFG.txt
> +  !include $(PLATFORM_PACKAGE)/PlatformPkgConfig.dsc
> +
> +!if $(X64_CONFIG) == TRUE
> +  DEFINE      DXE_ARCHITECTURE        = X64
> +  DEFINE      EDK_DXE_ARCHITECTURE    = X64
> +  DEFINE      UNDI_DXE_ARCHITECTURE   = 64
> +!else
> +  DEFINE      DXE_ARCHITECTURE        = IA32
> +  DEFINE      EDK_DXE_ARCHITECTURE    = Ia32
> +  DEFINE      UNDI_DXE_ARCHITECTURE   = 32
> +!endif
> +
> +  FLASH_DEFINITION                    = $(PLATFORM_PACKAGE)/PlatformPkg.fdf
> +!if $(LFMA_ENABLE) == TRUE
> +  FIX_LOAD_TOP_MEMORY_ADDRESS         = 0xFFFFFFFFFFFFFFFF
> +  DEFINE   TOP_MEMORY_ADDRESS         = 0xFFFFFFFFFFFFFFFF
> +!else
> +  FIX_LOAD_TOP_MEMORY_ADDRESS         = 0x0
> +  DEFINE   TOP_MEMORY_ADDRESS         = 0x0
> +!endif
> +
> +  DEFINE   PLATFORM_PCIEXPRESS_BASE   = 0E0000000
> +
> +  DEFINE SEC_ENABLE = FALSE
> +  DEFINE SEC_DEBUG_INFO_ENABLE = FALSE
> +  DEFINE FTPM_ENABLE = FALSE
> +
> +#########################################################
> #######################
> +#
> +# SKU Identification section - list of all SKU IDs supported by this
> +#                              Platform.
> +#
> +#########################################################
> #######################
> +[SkuIds]
> +  0|DEFAULT              # The entry: 0|DEFAULT is reserved and always required.
> +
> +#########################################################
> #######################
> +#
> +# Library Class section - list of all Library Classes needed by this Platform.
> +#
> +#########################################################
> #######################
> +[LibraryClasses.common]
> +  #
> +  # Entry point
> +  #
> +
> PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.in
> f
> +  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
> +
> DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint
> .inf
> +
> UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntry
> Point.inf
> +
> UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiA
> pplicationEntryPoint.inf
> +
> DxeSmmDriverEntryPoint|IntelFrameworkPkg/Library/DxeSmmDriverEntryP
> oint/DxeSmmDriverEntryPoint.inf
> +
> +  #
> +  # Basic
> +  #
> +  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
> +!if $(SSE2_ENABLE) == TRUE
> +
> BaseMemoryLib|MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2
> .inf
> +!else
> +
> BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibR
> epStr.inf
> +!endif
> +  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
> +  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
> +  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
> +  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
> +
> PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibP
> ci.inf
> +  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
> +  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
> +
> CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCac
> heMaintenanceLib.inf
> +  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
> +
> PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/Base
> PeCoffGetEntryPointLib.inf
> +!if $(RC_BINARY_RELEASE) == TRUE
> +
> PchPlatformLib|Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLib.in
> f
> +!endif
> +  #
> +  # UEFI & PI
> +  #
> +
> UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBo
> otServicesTableLib.inf
> +
> UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib
> /UefiRuntimeServicesTableLib.inf
> +  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
> +  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
> +  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
> +
> UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiService
> sLib.inf
> +  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
> +
> UefiDecompressLib|MdeModulePkg/Library/BaseUefiTianoCustomDecompr
> essLib/BaseUefiTianoCustomDecompressLib.inf
> +
> PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/P
> eiServicesTablePointerLibIdt.inf
> +  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
> +  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
> +
> DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTabl
> eLib.inf
> +  UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
> +  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
> +
> GenericBdsLib|$(PLATFORM_PACKAGE)/Override/IntelFrameworkModuleP
> kg/Library/GenericBdsLib/GenericBdsLib.inf
> +
> BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupp
> ortLib.inf
> +  SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
> +
> PlatformBdsLib|$(PLATFORM_PACKAGE)/Library/PlatformBdsLib/PlatformB
> dsLib.inf
> +  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
> +  DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
> +
> FlashDeviceLib|$(PLATFORM_PACKAGE)/Library/FlashDeviceLib/FlashDevice
> Lib.inf
> +
> UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBoo
> tManagerLib.inf
> +  #
> +  # Framework
> +  #
> +!if $(S3_ENABLE) == TRUE
> +
> S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootSc
> riptLib.inf
> +!else
> +
> S3BootScriptLib|MdePkg/Library/BaseS3BootScriptLibNull/BaseS3BootScriptL
> ibNull.inf
> +!endif
> +  S3IoLib|MdePkg/Library/BaseS3IoLib/BaseS3IoLib.inf
> +  S3PciLib|MdePkg/Library/BaseS3PciLib/BaseS3PciLib.inf
> +
> +  #
> +  # Generic Modules
> +  #
> +!if $(USB_ENABLE) == TRUE
> +  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
> +!endif
> +!if $(SCSI_ENABLE) == TRUE
> +  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
> +!endif
> +!if $(NETWORK_ENABLE) == TRUE
> +  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
> +  IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
> +  UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
> +  TcpIoLib|MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf
> +  DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
> +!endif
> +!if $(S3_ENABLE) == TRUE
> +  S3Lib|IntelFrameworkModulePkg/Library/PeiS3Lib/PeiS3Lib.inf
> +!endif
> +
> +
> OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibN
> ull/OemHookStatusCodeLibNull.inf
> +!if $(CAPSULE_ENABLE) == TRUE
> +  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf
> +!else
> +
> CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.i
> nf
> +!endif
> +
> FmpAuthenticationLib|MdeModulePkg/Library/FmpAuthenticationLibNull/F
> mpAuthenticationLibNull.inf
> +  IniParsingLib|SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.inf
> +
> PlatformFlashAccessLib|Vlv2TbltDevicePkg/Feature/Capsule/Library/Platfor
> mFlashAccessLib/PlatformFlashAccessLib.inf
> +
> MicrocodeFlashAccessLib|Vlv2TbltDevicePkg/Feature/Capsule/Library/Platfo
> rmFlashAccessLib/PlatformFlashAccessLib.inf
> +
> DisplayUpdateProgressLib|MdeModulePkg/Library/DisplayUpdateProgressLi
> bGraphics/DisplayUpdateProgressLibGraphics.inf
> +
> SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchroniz
> ationLib.inf
> +
> SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementL
> ib/DxeSecurityManagementLib.inf
> +  IoApicLib|PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf
> +
> DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/Bas
> eDebugPrintErrorLevelLib.inf
> +
> +  #
> +  # CPU
> +  #
> +  MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf
> +
> LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.in
> f
> +
> CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeC
> puExceptionHandlerLib.inf
> +  MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
> +
> +  #
> +  # ICH
> +  #
> +  SmbusLib|$(PLATFORM_PACKAGE)/Library/SmbusLib/SmbusLib.inf
> +  SmmLib|$(PLATFORM_PACKAGE)/Library/PchSmmLib/PchSmmLib.inf
> +
> +  #
> +  # Platform
> +  #
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +
> ResetSystemLib|$(PLATFORM_PACKAGE)/Library/ResetSystemLib/ResetSys
> temLib.inf
> +
> +
> PlatformCmosLib|$(PLATFORM_PACKAGE)/Library/PlatformCmosLib/Platfor
> mCmosLib.inf
> +
> +  #
> +  # Misc
> +  #
> +
> MonoStatusCodeLib|$(PLATFORM_PACKAGE)/MonoStatusCode/MonoStat
> usCode.inf
> +!if $(TARGET) == RELEASE
> +  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
> +
> SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.in
> f
> +!else
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +
> SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
> +!endif
> +
> +
> PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanc
> eLibNull.inf
> +  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +!if $(TPM_ENABLED) == TRUE
> +  TpmCommLib|SecurityPkg/Library/TpmCommLib/TpmCommLib.inf
> +
> Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12Comma
> ndLib.inf
> +
> Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLib
> DTpm.inf
> +
> +!endif
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibD
> ebug/PeCoffExtraActionLibDebug.inf
> +
> DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicati
> onLibSerialPort/DebugCommunicationLibSerialPort.inf
> +
> PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePla
> tformHookLibNull.inf
> +
> SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPort
> Lib16550.inf
> +!else
> +
> PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BaseP
> eCoffExtraActionLibNull.inf
> +
> DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLi
> bNull.inf
> +!endif
> +
> +  #
> +  # CryptLib
> +  #
> +!if $(TPM_ENABLED) == TRUE
> +  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
> +  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
> +!endif
> +
> + BiosIdLib|$(PLATFORM_PACKAGE)/Library/BiosIdLib/BiosIdLib.inf
> + CpuIA32Lib|$(PLATFORM_PACKAGE)/Library/CpuIA32Lib/CpuIA32Lib.inf
> +
> +
> StallSmmLib|$(PLATFORM_PACKAGE)/Library/StallSmmLib/StallSmmLib.inf
> +
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
> +  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
> +
> PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecu
> reLibNull.inf
> +
> TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTp
> mMeasurementLib.inf
> +  AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
> +  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
> +!else
> +
> TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/Tp
> mMeasurementLibNull.inf
> +
> AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableL
> ibNull.inf
> +!endif
> +  VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
> +!if $(RC_BINARY_RELEASE) == TRUE
> +  I2cLib|Vlv2TbltDevicePkg/Library/I2CLib/I2CLibNull.inf
> +!endif
> +  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
> +  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
> +  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
> +!if $(FTPM_ENABLE) == TRUE || $(NETWORK_ISCSI_ENABLE) == TRUE
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> +  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
> +  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
> +!endif
> +
> TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTp
> mMeasurementLib.inf
> +
> Tcg2PhysicalPresenceLib|SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/D
> xeTcg2PhysicalPresenceLib.inf
> +
> Tcg2PpVendorLib|SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorL
> ibNull.inf
> +
> +
> +
> Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandL
> ib.inf
> +!if $(MINNOW2_FSP_BUILD) == TRUE
> +  FspApiLib|IntelFspWrapperPkg/Library/BaseFspApiLib/BaseFspApiLib.inf
> +
> FspPlatformInfoLib|IntelFspWrapperPkg/Library/BaseFspPlatformInfoLibSa
> mple/BaseFspPlatformInfoLibSample.inf
> +
> FspPlatformSecLib|Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSe
> cLibVlv2/FspPlatformSecLibVlv2.inf
> +
> FspHobProcessLib|Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcess
> LibVlv2/FspHobProcessLibVlv2.inf
> +!endif
> +
> +  BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
> +
> +[LibraryClasses.IA32.SEC]
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +
> PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanc
> eLibNull.inf
> +!endif
> +  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
> +  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +
> +[LibraryClasses.IA32.PEIM, LibraryClasses.IA32.PEI_CORE,
> LibraryClasses.IA32.SEC]
> +  #
> +  # PEI phase common
> +  #
> +
> +  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
> +
> MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemory
> AllocationLib.inf
> +
> ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiR
> eportStatusCodeLib.inf
> +
> ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiEx
> tractGuidedSectionLib.inf
> +
> MultiPlatformLib|$(PLATFORM_PACKAGE)/Library/MultiPlatformLib/MultiPl
> atformLib.inf
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
> +
> CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecP
> eiCpuExceptionHandlerLib.inf
> +  MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
> +
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +
> PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanc
> eLib.inf
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +!endif
> +
> +!if $(TARGET) == RELEASE
> +  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
> +
> SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.in
> f
> +!else
> +
> DebugLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDx
> eDebugLibReportStatusCode.inf
> +
> SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
> +!endif
> +
> +
> LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf
> +
> HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoR
> outerPei.inf
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAg
> entLib.inf
> +!endif
> +
> + !if $(MINNOW2_FSP_BUILD) == TRUE
> +
> PlatformFspLib|Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.in
> f
> + !endif
> +!if $(FTPM_ENABLE) == TRUE
> +
> Tpm2DeviceLib|Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2Devi
> ceLibSeC.inf
> +!endif
> +
> +[LibraryClasses.IA32]
> +  #
> +  # DXE phase common
> +  #
> +  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
> +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +
> MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemo
> ryAllocationLib.inf
> +
> ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/Dx
> eReportStatusCodeLib.inf
> +
> ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeE
> xtractGuidedSectionLib.inf
> +
> +
> TcgPhysicalPresenceLib|SecurityPkg/Library/DxeTcgPhysicalPresenceLib/Dxe
> TcgPhysicalPresenceLib.inf
> +!if $(TPM_ENABLED) == TRUE
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> +!endif
> +
> +
> LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.in
> f
> +
> EfiRegTableLib|$(PLATFORM_PACKAGE)/Library/EfiRegTableLib/EfiRegTable
> Lib.inf
> +
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> +!endif
> +
> +
> HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoR
> outerDxe.inf
> +
> +[LibraryClasses.IA32.DXE_DRIVER]
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +
> PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanc
> eLibNull.inf
> +
> CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/Custo
> mizedDisplayLib.inf
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +
> PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerforma
> nceLib.inf
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +!endif
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgen
> tLib.inf
> +!endif
> +
> +
> FlashDeviceLib|$(PLATFORM_PACKAGE)/Library/FlashDeviceLib/FlashDevice
> LibDxe.inf
> +
> +[LibraryClasses.IA32.DXE_CORE]
> +  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
> +
> MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLi
> b/DxeCoreMemoryAllocationLib.inf
> +  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +
> PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCore
> PerformanceLib.inf
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +!endif
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgen
> tLib.inf
> +!endif
> +
> +[LibraryClasses.IA32.DXE_SMM_DRIVER]
> +
> MmServicesTableLib|MdePkg/Library/MmServicesTableLib/MmServicesTabl
> eLib.inf
> +
> SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesT
> ableLib.inf
> +
> ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/S
> mmReportStatusCodeLib.inf
> +
> MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMe
> moryAllocationLib.inf
> +
> LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.i
> nf
> +
> PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanc
> eLibNull.inf
> +  SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
> +
> SmmCpuPlatformHookLib|UefiCpuPkg/Library/SmmCpuPlatformHookLibNull
> /SmmCpuPlatformHookLibNull.inf
> +
> SmmCpuFeaturesLib|UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFea
> turesLib.inf
> +
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> +  !if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +  !endif
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAge
> ntLib.inf
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +!endif
> +
> CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/Smm
> CpuExceptionHandlerLib.inf
> +
> +[LibraryClasses.IA32.SMM_CORE]
> +
> MemoryAllocationLib|MdeModulePkg/Library/PiSmmCoreMemoryAllocatio
> nLib/PiSmmCoreMemoryAllocationLib.inf
> +
> SmmServicesTableLib|MdeModulePkg/Library/PiSmmCoreSmmServicesTabl
> eLib/PiSmmCoreSmmServicesTableLib.inf
> +
> ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/S
> mmReportStatusCodeLib.inf
> +
> SmmCorePlatformHookLib|MdeModulePkg/Library/SmmCorePlatformHook
> LibNull/SmmCorePlatformHookLibNull.inf
> +  SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
> +
> +!if $(TPM_ENABLED) == TRUE
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> +!endif
> +
> +
> PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanc
> eLibNull.inf
> +
> +!if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +!endif
> +
> +[LibraryClasses.IA32.DXE_RUNTIME_DRIVER]
> +
> ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCod
> eLib/RuntimeDxeReportStatusCodeLib.inf
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
> +!endif
> +!if $(TPM_ENABLED) == TRUE
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
> +!endif
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgen
> tLib.inf
> +!endif
> +
> +!if $(CAPSULE_ENABLE) == TRUE
> +
> CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsule
> Lib.inf
> +!endif
> +
> +[LibraryClasses.common.UEFI_DRIVER]
> +  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgen
> tLib.inf
> +!endif
> +
> +[LibraryClasses.IA32.UEFI_APPLICATION]
> +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgen
> tLib.inf
> +!endif
> +
> +#########################################################
> #######################
> +#
> +# Pcd Section - list of all EDK II PCD Entries defined by this Platform
> +#
> +#########################################################
> #######################
> +[PcdsFeatureFlag.common]
> +!if $(MINI_BIOS_ENABLE) == FALSE
> +  gPlatformModuleTokenSpaceGuid.PcdBdsDispatchAdditionalOprom|TRUE
> +!else
> +
> gPlatformModuleTokenSpaceGuid.PcdBdsDispatchAdditionalOprom|FALSE
> +!endif
> +#
> +# If PcdDxeIplSwitchToLongMode is TRUE, DxeIpl will load a 64-bit DxeCore
> and switch to long mode to hand over to DxeCore.
> +#
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|FALSE
> +
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserGrayOutTextStatement|TR
> UE
> +
> +!if $(CAPSULE_RESET_ENABLE) == TRUE
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|TRUE
> +!else
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|FALS
> E
> +!endif
> +  gEfiCpuTokenSpaceGuid.PcdCpuSmmEnableBspElection|FALSE
> +!if $(DATAHUB_STATUS_CODE_ENABLE) == TRUE
> +
> gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeUseDataHub
> |TRUE
> +!else
> +
> gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeUseDataHub
> |FALSE
> +!endif
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreImageLoaderSearchTeSecti
> onFirst|FALSE
> +!if $(TARGET) == RELEASE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
> +!else
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
> +!endif
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE
> +!if $(ISA_SERIAL_STATUS_CODE_ENABLE) == TRUE
> +  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseIsaSerial|TRUE
> +!else
> +  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseIsaSerial|FALSE
> +!endif
> +!if $(USB_SERIAL_STATUS_CODE_ENABLE) == TRUE
> +  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseUsbSerial|TRUE
> +!else
> +  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseUsbSerial|FALSE
> +!endif
> +!if $(RAM_SERIAL_STATUS_CODE_ENABLE) == TRUE
> +  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseRam|TRUE
> +!else
> +  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseRam|FALSE
> +!endif
> +
> +
> +  ## This PCD specifies whether PS2 keyboard does a extended verification
> during start.
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdPs2KbdExtendedVerification|FALSE
> +
> +  ## This PCD specifies whether PS2 mouse does a extended verification
> during start.
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdPs2MouseExtendedVerification|FA
> LSE
> +
> +!if $(VARIABLE_INFO_ENABLE) == TRUE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics|TRUE
> +!else
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics|FALSE
> +!endif
> +
> +  gEfiCpuTokenSpaceGuid.PcdCpuSmmBlockStartupThisAp|TRUE
> +
> +!if $(SOURCE_DEBUG_ENABLE)
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmDebug|TRUE
> +!endif
> +
> +[PcdsFixedAtBuild.common]
> +!if $(MINNOW2_FSP_BUILD) == TRUE
> +# $(FLASH_REGION_VLVMICROCODE_BASE)
> +
> gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress|0xFFC00000
> +# $(FLASH_REGION_VLVMICROCODE_SIZE)
> +
> gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize|0x0004000
> 0
> +  gFspWrapperTokenSpaceGuid.PcdFlashMicroCodeOffset|0x60
> +# $(FLASH_AREA_BASE_ADDRESS)
> +  gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheAddress|0xFF800000
> +# $(FLASH_AREA_SIZE)
> +  gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheSize|0x00800000
> +# $(FLASH_REGION_FSPBIN_BASE)
> +  gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase|0xFFCC0000
> +!endif
> +
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +!if $(MINNOW2_FSP_BUILD) == TRUE
> +  # in FSP, when this got used, the memory already is up
> +  gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0x00080000
> +!else
> +  gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0xFEF80000
> +!endif
> +  gEfiCpuTokenSpaceGuid.PcdTemporaryRamSize|0x00010000
> +
> +!else
> +  !if $(MINNOW2_FSP_BUILD) == TRUE
> +    gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0x00080000
> +  !else
> +    gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0xFEF80000
> +  !endif
> +  gEfiCpuTokenSpaceGuid.PcdTemporaryRamSize|0x00010000
> +  gEfiCpuTokenSpaceGuid.PcdPeiTemporaryRamStackSize|0x3C00
> +!endif
> +
> +
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x22000
> +!else
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x4000
> +!endif
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize|0x00000800
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x4
> 00
> +  gEfiCpuTokenSpaceGuid.PcdCpuIEDRamSize|0x400000
> +
> gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemory
> Size|0x10000
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|FALSE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAriSupport|FALSE
> +  gEfiCpuTokenSpaceGuid.PcdCpuSmmApSyncTimeout|1000
> +!if $(S4_ENABLE) == TRUE
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationC
> hange|TRUE
> +!else
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationC
> hange|FALSE
> +!endif
> +!if $(TARGET) == RELEASE
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0
> +  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x3
> +!else
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
> +  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
> +!endif
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0x1
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPerformanceLogEntries|60
> +!endif
> +
> +
> gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdEbdaReservedMemorySi
> ze|0x10000
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable|$(
> TOP_MEMORY_ADDRESS)
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserSubtitleTextColor|0x0
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldTextColor|0x01
> +  gEfiCpuTokenSpaceGuid.PcdCpuIEDEnabled|TRUE
> +
> gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBiosVideoCheckVbeEna
> ble|TRUE
> +
> gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBiosVideoCheckVgaEnab
> le|TRUE
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
> +  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl|FAL
> SE
> +
> gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod|2
> +!endif
> +
> +  #
> +  # Set SMM stack size to 16 KB.
> +  #
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize|0x4000
> +
> +  #
> +  # Clear unused single certificate PCD
> +  #
> +  gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer|{0}
> +
> +  #
> +  # Lock all updatable firmware devices at End of DXE
> +  #
> +
> gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceLockEventGuid|{GUID(gEfiE
> ndOfDxeEventGroupGuid)}
> +#
> gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceLockEventGuid|{GUID(gEfiE
> ventReadyToBootGuid)}
> +
> +  #
> +  # Set PcdFmpDeviceTestKeySha256Digest to {0} to disable test key
> detection
> +  #
> +#  gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceTestKeySha256Digest|{0}
> +
> +[PcdsFixedAtBuild.IA32]
> +!if $(TARGET) == RELEASE
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0
> +  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x3
> +!else
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
> +  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
> +!endif
> +
> +!if $(RECOVERY_ENABLE)
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdRecoveryFileName|L"VLV2REC.Cap
> "
> +!endif
> +
> +[PcdsPatchableInModule.common]
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x803805c6
> +
> gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0x$(PLATFORM_PC
> IEXPRESS_BASE)
> +
> gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLegacyBiosCacheLegacy
> Region|FALSE
> +
> +  ## This PCD specifies whether to use the optimized timing for best PS2
> detection performance.
> +  #  Note this PCD could be set to TRUE for best boot performance and set to
> FALSE for best device compatibility.
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFastPS2Detection|TRUE
> +
> +
> ##########################################################
> #############################################
> +  #
> +  # Begin of MRC parameters
> +  #
> +
> +  ## Memory Parameter Patchable.
> +  #  FALSE - MRC Parameters are fixed for MinnowBoard Max<BR>
> +  #  TRUE  - MRC Parameters are patchable by following PCDs<BR>
> +  # @Prompt Memory Parameter Patchable.
> +  # @ValidList 0x80000001 | 0, 1
> +  gVlvRefCodePkgTokenSpaceGuid.PcdMemoryParameterPatchable|FALSE
> +
> +  ## Memory Down or DIMM slot.
> +  #  0 - DIMM<BR>
> +  #  1 - Memory Down<BR>
> +  # @Prompt Enable Memory Down
> +  # @ValidList 0x80000001 | 0, 1
> +  gVlvRefCodePkgTokenSpaceGuid.PcdEnableMemoryDown|1
> +
> +  ## The speed of DRAM.
> +  #  0 - 800 MHz<BR>
> +  #  1 - 1066 MHz<BR>
> +  #  2 - 1333 MHz<BR>
> +  #  3 - 1600 MHz<BR>
> +  # @Prompt DRAM Speed
> +  # @ValidList 0x80000001 | 0, 1, 2, 3
> +  gVlvRefCodePkgTokenSpaceGuid.PcdDramSpeed|1
> +
> +  ## DRAM Type.
> +  #  0 - DDR3<BR>
> +  #  1 - DDR3L<BR>
> +  #  2 - DDR3U<BR>
> +  #  3 - DDR3All<BR>
> +  #  4 - LPDDR2<BR>
> +  #  5 - LPDDR3<BR>
> +  #  6 - DDR4<BR>
> +  # @Prompt DRAM Type
> +  # @ValidList 0x80000001 | 0, 1, 2, 3, 4, 5, 6
> +  gVlvRefCodePkgTokenSpaceGuid.PcdDramType|1
> +
> +  ## Please populate DIMM slot 0 if only one DIMM is supported.
> +  #  0 - Disable<BR>
> +  #  1 - Enable<BR>
> +  # @Prompt DIMM 0 Enable
> +  # @ValidList 0x80000001 | 0, 1
> +  gVlvRefCodePkgTokenSpaceGuid.PcdEnableDimm0|1
> +
> +  ## DIMM 1 has to be identical to DIMM 0.
> +  #  0 - Disable<BR>
> +  #  1 - Enable<BR>
> +  # @Prompt DIMM 1 Enable Type
> +  # @ValidList 0x80000001 | 0, 1
> +  gVlvRefCodePkgTokenSpaceGuid.PcdEnableDimm1|0
> +
> +  ## DRAM device data width.
> +  #  0 - x8<BR>
> +  #  1 - x16<BR>
> +  #  2 - x32<BR>
> +  # @Prompt DIMM_DWIDTH
> +  # @ValidList 0x80000001 | 0, 1, 2
> +  gVlvRefCodePkgTokenSpaceGuid.PcdDimmDataWidth|1
> +
> +  ## DRAM device data density.
> +  #  0 - 1 Gbit<BR>
> +  #  1 - 2 Gbit<BR>
> +  #  2 - 4 Gbit<BR>
> +  #  3 - 8 Gbit<BR>
> +  # @Prompt DIMM_Density
> +  # @ValidList 0x80000001 | 0, 1, 2, 3
> +  gVlvRefCodePkgTokenSpaceGuid.PcdDimmDensity|2
> +
> +  ## DRAM device data bus width.
> +  #  0 - 8 bits<BR>
> +  #  1 - 16 bits<BR>
> +  #  2 - 32 bits<BR>
> +  #  3 - 64 bits<BR>
> +  # @Prompt DIMM_BusWidth
> +  # @ValidList 0x80000001 | 0, 1, 2, 3
> +  gVlvRefCodePkgTokenSpaceGuid.PcdDimmBusWidth|3
> +
> +  ## Ranks Per DIMM or Sides Per DIMM.
> +  #  0 - 1 Rank<BR>
> +  #  1 - 2 Ranks<BR>
> +  # @Prompt DIMM_Sides
> +  # @ValidList 0x80000001 | 0, 1
> +  gVlvRefCodePkgTokenSpaceGuid.PcdRankPerDimm|0
> +
> +  ## tCL.<BR><BR>
> +  # @Prompt tCL
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTcl|11
> +
> +  ## tRP and tRCD in DRAM clk - 5:12.5ns, 6:15ns, etc.
> +  # @Prompt tRP_tRCD
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTrpTrcd|11
> +
> +  ## tWR in DRAM clk.
> +  # @Prompt tWR
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTwr|12
> +
> +  ## tWTR in DRAM clk.
> +  # @Prompt tWTR
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTwtr|6
> +
> +  ## tRRD in DRAM clk.
> +  # @Prompt tRRD
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTrrd|6
> +
> +  ## tRTP in DRAM clk.
> +  # @Prompt tRTP
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTrtp|6
> +
> +  ## tFAW in DRAM clk.
> +  # @Prompt tFAW
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTfaw|32
> +
> +  #
> +  # End of MRC parameters.
> +  #
> +
> ##########################################################
> #####################################
> +
> +[PcdsDynamicHii.common.DEFAULT]
> +
> gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlo
> balVariableGuid|0x0|5 # Variable: L"Timeout"
> +
> gEfiMdePkgTokenSpaceGuid.PcdHardwareErrorRecordLevel|L"HwErrRecSup
> port"|gEfiGlobalVariableGuid|0x0|1 # Variable: L"HwErrRecSupport"
> +
> +[PcdsDynamicDefault.common.DEFAULT]
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr|0x
> 0
> +  !if $(TPM_ENABLED) == TRUE
> +    gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{0x7b, 0x3a, 0xcd,
> 0x72, 0xA5, 0xFE, 0x5e, 0x4f, 0x91, 0x65, 0x4d, 0xd1, 0x21, 0x87, 0xbb, 0x13}
> +  !endif
> +
> +  ## This PCD defines the video horizontal resolution.
> +  #  This PCD could be set to 0 then video resolution could be at highest
> resolution.
> +  #gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|0
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|800
> +  ## This PCD defines the video vertical resolution.
> +  #  This PCD could be set to 0 then video resolution could be at highest
> resolution.
> +  #gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|0
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600
> +
> +  ## This PCD defines the Console output column and the default value is 25
> according to UEFI spec.
> +  #  This PCD could be set to 0 then console output could be at max column
> and max row.
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|31
> +  ## This PCD defines the Console output row and the default value is 80
> according to UEFI spec.
> +  #  This PCD could be set to 0 then console output could be at max column
> and max row.
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|100
> +
> +  ## The PCD is used to specify the video horizontal resolution of text setup.
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|80
> 0
> +  ## The PCD is used to specify the video vertical resolution of text setup.
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|600
> +  ## The PCD is used to specify the console output column of text setup.
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutColumn|100
> +  ## The PCD is used to specify the console output column of text setup.
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutRow|31
> +
> +!if $(TPM_ENABLED) == TRUE
> +  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInitializationPolicy|1
> +  gEfiSecurityPkgTokenSpaceGuid.PcdTpmScrtmPolicy|1
> +!endif
> +
> +[PcdsDynamicExDefault.common.DEFAULT]
> +  gEfiVLVTokenSpaceGuid.PcdTCSmbaIoBaseAddress|0x1040
> +  gEfiVLVTokenSpaceGuid.PcdEmmcManufacturerId|0
> +  gEfiVLVTokenSpaceGuid.PcdProductSerialNumber|0
> +  gEfiVLVTokenSpaceGuid.PcdMeasuredBootEnable|TRUE
> +  gEfiVLVTokenSpaceGuid.PcdFTPMErrorOccur|FALSE
> +  gEfiVLVTokenSpaceGuid.PcdFTPMErrorSkip|FALSE
> +  gEfiVLVTokenSpaceGuid.PcdFTPMCommand|0
> +  gEfiVLVTokenSpaceGuid.PcdFTPMResponse|0
> +  gEfiVLVTokenSpaceGuid.PcdFTPMNotRespond|FALSE
> +  gEfiVLVTokenSpaceGuid.PcdFTPMStatus|0
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateSmmDataP
> tr|0
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr|0
> +  gEfiCpuTokenSpaceGuid.PcdCpuS3DataAddress|0
> +  gEfiCpuTokenSpaceGuid.PcdCpuHotPlugDataAddress|0
> +  gEfiCpuTokenSpaceGuid.PcdCpuCallbackSignal|0
> +  gEfiCpuTokenSpaceGuid.PcdCpuConfigContextBuffer|0
> +  gEfiVLVTokenSpaceGuid.PcdCpuLockBoxDataAddress|0
> +  gEfiVLVTokenSpaceGuid.PcdCpuSmramCpuDataAddress|0
> +  gEfiVLVTokenSpaceGuid.PcdCpuLockBoxSize|0
> +
> +[PcdsDynamicExDefault.X64.DEFAULT]
> +!if $(RECOVERY_ENABLE)
> +
> gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareFileGuid|{G
> UID("AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215")}|VOID*|0x10
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdSystemFmpCapsuleImageTypeIdGu
> id|{GUID("4096267b-da0a-42eb-b5eb-fef31d207cb4")}|VOID*|0x10
> +!endif
> +
> +[Components.IA32]
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/S
> ecCore.inf
> +
> +  !if $(MINNOW2_FSP_BUILD) == TRUE
> +  IntelFspWrapperPkg/FspWrapperSecCore/FspWrapperSecCore.inf {
> +    !if $(TARGET) == DEBUG
> +
> +    <LibraryClasses>
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +    !endif
> +  }
> +  Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.inf
> +  IntelFspWrapperPkg/FspInitPei/FspInitPei.inf {
> +    !if $(TARGET) == DEBUG
> +    <LibraryClasses>
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +    !endif
> +  }
> +  !endif
> +
> +  MdeModulePkg/Core/Pei/PeiMain.inf {
> +!if $(TARGET) == DEBUG
> +    <PcdsFixedAtBuild>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
> +!endif
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
> +  }
> +
> +  $(PLATFORM_PACKAGE)/MonoStatusCode/MonoStatusCode.inf {
> +!if $(TARGET) == DEBUG
> +    <PcdsFixedAtBuild>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
> +!endif
> +  }
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/M
> emoryInit.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
> +    <BuildOptions>
> +      !if $(FTPM_ENABLE)==TRUE
> +        *_*_IA32_CC_FLAGS = /D FTPM_ENABLE
> +      !endif
> +  }
> +
> +!if $(RC_BINARY_RELEASE) == TRUE
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/S
> eCUma.inf
> +!endif
> +
> +!if $(FTPM_ENABLE) == TRUE
> +$(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/f
> TPMInitPeim.inf
> +!endif
> +
> +!if $(RC_BINARY_RELEASE) == TRUE
> +  $(PLATFORM_PACKAGE)/PlatformPei/PlatformPei.inf {
> +    <BuildOptions>
> +      *_*_IA32_CC_FLAGS      = /DRC_BINARY_RELEASE
> +  !if $(TARGET) == DEBUG
> +      <PcdsFixedAtBuild>
> +        gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
> +  !endif
> +  }
> +!endif
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +  SourceLevelDebugPkg/DebugAgentPei/DebugAgentPei.inf{
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAg
> entLib.inf
> +
> PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePla
> tformHookLibNull.inf
> +
> SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPort
> Lib16550.inf
> +    }
> +!endif
> +
> +!if $(FTPM_ENABLE) == TRUE
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/T
> pm2DeviceSeCPei.inf
> +!endif
> +
> +!if $(TPM_ENABLED) == TRUE
> +  SecurityPkg/Tcg/PhysicalPresencePei/PhysicalPresencePei.inf
> +  SecurityPkg/Tcg/TcgPei/TcgPei.inf {
> +    <LibraryClasses>
> +
> NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
> +
> NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.in
> f
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +}
> +!endif
> +
> + $(PLATFORM_PACKAGE)/PlatformInitPei/PlatformInitPei.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x803805c6
> +    <LibraryClasses>
> +!if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +!endif
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +  }
> +  $(PLATFORM_PACKAGE)/FvInfoPei/FvInfoPei.inf
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/Vl
> vInitPeim.inf
> +!if $(PCIESC_ENABLE) == TRUE
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chEarlyInitPeim.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
> +  }
> +!endif
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chInitPeim.inf
> +
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chSmbusArpDisabled.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chSpiPeim.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> eiSmmAccess.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> eiSmmControl.inf
> +  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/C
> puPeim.inf
> +  UefiCpuPkg/CpuIoPei/CpuIoPei.inf
> +  UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/M
> pS3.inf
> +#
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/Pi
> SmmCommunicationPei.inf
> +
> +!if $(RECOVERY_ENABLE)
> +  #
> +  # Recovery
> +  #
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chUsb.inf
> +  MdeModulePkg/Bus/Pci/EhciPei/EhciPei.inf
> +  MdeModulePkg/Bus/Usb/UsbBusPei/UsbBusPei.inf
> +  MdeModulePkg/Bus/Usb/UsbBotPei/UsbBotPei.inf
> +  FatPkg/FatPei/FatPei.inf
> +  MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf
> +
> SignedCapsulePkg/Universal/RecoveryModuleLoadPei/RecoveryModuleLoa
> dPei.inf {
> +    <LibraryClasses>
> +
> FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibRsa2048Sh
> a256/FmpAuthenticationLibRsa2048Sha256.inf
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +  }
> +!endif
> +
> +!if $(CAPSULE_ENABLE) == TRUE
> +  MdeModulePkg/Universal/CapsulePei/CapsulePei.inf
> +!endif
> +  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
> +    <LibraryClasses>
> +!if $(LZMA_ENABLE) == TRUE
> +
> NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDec
> ompressLib.inf
> +!endif
> +  }
> +
> + MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
> +
> MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
> +
> +!if $(FTPM_ENABLE) == TRUE
> +   SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
> +    <LibraryClasses>
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +
> NULL|SecurityPkg/Library\HashInstanceLibSha1/HashInstanceLibSha1.inf
> +
> NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.in
> f
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +  }
> +!endif
> +!if $(TPM_ENABLED) == TRUE
> +  SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +  }
> +!endif
> +!if $(ACPI50_ENABLE) == TRUE
> +
> MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/Firmwa
> rePerformancePei.inf{
> +    <LibraryClasses>
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +  }
> +
> +!endif
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +
> MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCode
> RouterPei.inf
> +!endif
> +[Components.IA32]
> +  !if $(MINNOW2_FSP_BUILD) == TRUE
> +  IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.inf {
> +    !if $(TARGET) == DEBUG
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
> +    <LibraryClasses>
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +    !endif
> +  }
> +
> +  !endif
> +  #
> +  # EDK II Related Platform codes
> +  #
> +  MdeModulePkg/Core/Dxe/DxeMain.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
> +    <LibraryClasses>
> +!if $(DXE_CRC32_SECTION_ENABLE) == TRUE
> +
> NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32G
> uidedSectionExtractLib.inf
> +!endif
> +!if $(LZMA_ENABLE) == TRUE
> +
> NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDec
> ompressLib.inf
> +!endif
> +!if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +!endif
> +  }
> +
> IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3SaveDxe.i
> nf {
> +    <PcdsPatchableInModule>
> +        gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
> +    <PcdsFixedAtBuild>
> +        gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x27
> +    <LibraryClasses>
> +    !if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +    !endif
> +       <BuildOptions>
> +        ICC:*_*_*_CC_FLAGS = /D MDEPKG_NDEBUG
> +        GCC:*_*_*_CC_FLAGS = -D MDEPKG_NDEBUG
> +  }
> +  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +  }
> +  IntelFrameworkModulePkg/Universal/CpuIoDxe/CpuIoDxe.inf
> +  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
> +
> +
> MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportSt
> atusCodeRouterRuntimeDxe.inf
> +
> MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHan
> dlerRuntimeDxe.inf  {
> +    <LibraryClasses>
> +!if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +!endif
> +  }
> +
> +
> MdeModulePkg/Universal/ReportStatusCodeRouter/Smm/ReportStatusCod
> eRouterSmm.inf
> +  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf{
> +    <LibraryClasses>
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +
> NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib
> .inf
> +!endif
> +!if $(USER_IDENTIFICATION_ENABLE)
> +
> NULL|SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.in
> f
> +!endif
> +!if $(TPM_ENABLED) == TRUE
> +
> NULL|SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLi
> b.inf
> +!endif
> +!if $(FTPM_ENABLE) == TRUE
> +
> NULL|SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBoot
> Lib.inf
> +!endif
> +  }
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/MpCpu.inf
> +  $(PLATFORM_PACKAGE)/Metronome/Metronome.inf
> +
> +  IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf{
> +    <LibraryClasses>
> +      OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
> +      IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
> +      BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> +
> PlatformBdsLib|$(PLATFORM_PACKAGE)/Library/PlatformBdsLib/PlatformB
> dsLib.inf
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +
> SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
> +    !if $(FTPM_ENABLE) == TRUE
> +
> Tpm2DeviceLib|Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2Devi
> ceLibSeC.inf
> +    !else
> +
> Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2
> .inf
> +    !endif
> +  }
> +
> +  $(PLATFORM_PACKAGE)/UiApp/UiApp.inf
> +
> +  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
> +  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
> +
> MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.in
> f
> +
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.i
> nf
> +  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf {
> +    <LibraryClasses>
> +      NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
> +
> SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
> +  }
> +  $(PLATFORM_PACKAGE)/FvbRuntimeDxe/FvbSmm.inf
> +
> MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.i
> nf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchSpiSmm.inf
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +
> SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfi
> gDxe.inf {
> +    <LibraryClasses>
> +
> PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecu
> reLibNull.inf
> +    <BuildOptions>
> +      #
> +      # Specify GUID gEfiIfrBootMaintenanceGuid, to install Secure Boot
> Configuration menu
> +      # into Boot Maintenance Manager menu
> +      #
> +      *_*_*_VFR_FLAGS   = -g b2dedc91-d59f-48d2-898a-12490c74a4e0
> +  }
> +!endif
> +   MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf {
> +    <LibraryClasses>
> +      FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
> +  }
> +
> +
> MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCoun
> terRuntimeDxe.inf
> +
> PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntime
> Dxe.inf
> +  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
> +
> +  $(PLATFORM_PACKAGE)/FvbRuntimeDxe/FvbRuntimeDxe.inf
> +
> +  $(PLATFORM_PACKAGE)/PlatformSetupDxe/PlatformSetupDxe.inf
> +
> +!if $(DATAHUB_ENABLE) == TRUE
> +  IntelFrameworkModulePkg/Universal/DataHubDxe/DataHubDxe.inf {
> +    <PcdsFixedAtBuild>
> +      gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|0
> +  }
> +!endif
> +
> IntelFrameworkModulePkg/Universal/StatusCode/DatahubStatusCodeHandl
> erDxe/DatahubStatusCodeHandlerDxe.inf
> +
> MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryT
> estDxe.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchS3SupportDxe.inf
> +  !if $(USE_HPET_TIMER) == TRUE
> +    PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf
> +  !else
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SmartTimer.inf
> +  !endif
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SmmControl.inf
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchSmbusDxe.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/IntelPchLegacyInterrupt.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchReset.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchInitDxe.inf{
> +    <PcdsPatchableInModule>
> +        gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
> +  }
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchInitSmm.inf
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchSmiDispatcher.inf
> +
> +!if $(PCIESC_ENABLE) == TRUE
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchPcieSmm.inf
> +!endif
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchSpiRuntime.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchPolicyInitDxe.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchBiosWriteProtect.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SmmAccess.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PciHostBridge.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/VlvInitDxe.inf
> +
> +
> IntelFrameworkModulePkg/Universal/LegacyRegionDxe/LegacyRegionDxe.i
> nf
> +
> +  #
> +  # Performance Application; Set PERFORMANCE_ENABLE=TRUE for normal
> boot performance and smm performance data
> +  #
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +
> ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf
> {
> +    <PcdsFixedAtBuild>
> +      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> +  }
> +!endif
> +
> +  Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInitDxe.inf{
> +    <LibraryClasses>
> +!if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +!endif
> +      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  }
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/Dptf.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PnpDxe.inf
> +
> +!if $(SEC_ENABLE) == TRUE
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/HeciDrv.inf {
> +!if $(SEC_DEBUG_INFO_ENABLE) == TRUE
> +    <BuildOptions>
> +      *_*_X64_CC_FLAGS      = /DSEC_DEBUG_INFO=1
> +!else
> +    <BuildOptions>
> +      *_*_X64_CC_FLAGS      = /DSEC_DEBUG_INFO=0
> +!endif
> +  }
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SeCPolicyInitDxe.inf
> +!endif
> +
> +!if $(FTPM_ENABLE) == TRUE
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/Tpm2DeviceSeCDxe.inf
> +  SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf
> +  SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf{
> +    <LibraryClasses>
> +
> NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
> +
> NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.in
> f
> +      PcdLib|MdePkg/Library\DxePcdLib/DxePcdLib.inf
> +
> Tpm2DeviceLib|Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2Devi
> ceLibSeC.inf
> +  }
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/FtpmSmm.inf
> +!endif
> +!if $(TPM_ENABLED) == TRUE
> +  SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +  }
> +
> +  SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +    <BuildOptions>
> +      #
> +      # specify GUID gEfiIfrNotInTPVPageGuid, this page will not
> +      # be showed in TPV page.
> +      #
> +      *_*_*_VFR_FLAGS   = -g e58809f8-fbc1-48e2-883a-a30fdc4b441e
> +  }
> +
> +  SecurityPkg/Tcg/TcgDxe/TcgDxe.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  }
> +  SecurityPkg/Tcg/TcgSmm/TcgSmm.inf
> +!endif
> +  #
> +  # EDK II Related Platform codes
> +  #
> +  $(PLATFORM_PACKAGE)/PlatformSmm/PlatformSmm.inf{
> +    <LibraryClasses>
> +    !if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +    !endif
> +          PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  }
> +  $(PLATFORM_PACKAGE)/PlatformInfoDxe/PlatformInfoDxe.inf
> +  $(PLATFORM_PACKAGE)/PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf
> +  $(PLATFORM_PACKAGE)/PlatformDxe/PlatformDxe.inf
> +
> +  $(PLATFORM_PACKAGE)/PciPlatform/PciPlatform.inf
> +  $(PLATFORM_PACKAGE)/SaveMemoryConfig/SaveMemoryConfig.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PlatformCpuPolicy.inf
> +  $(PLATFORM_PACKAGE)/PpmPolicy/PpmPolicy.inf
> +
> $(PLATFORM_PACKAGE)/SmramSaveInfoHandlerSmm/SmramSaveInfoHand
> lerSmm.inf
> +!if $(GOP_DRIVER_ENABLE) == TRUE
> +  $(PLATFORM_PACKAGE)/PlatformGopPolicy/PlatformGopPolicy.inf
> +
> +!endif
> +
> +
> +  #
> +  # SMM
> +  #
> +  MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
> +  MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
> +  UefiCpuPkg/CpuDxe/CpuDxe.inf
> +  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
> +  UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
> +  MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
> +  UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
> +
> $(PLATFORM_PACKAGE)/SmmSwDispatch2OnSmmSwDispatchThunk/SmmS
> wDispatch2OnSmmSwDispatchThunk.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PowerManagement2.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/DigitalThermalSensor.inf
> +
> +  #
> +  # ACPI
> +  #
> +
> MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutor
> Dxe.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
> +    <PcdsFixedAtBuild>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x27
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  }
> +
> +  $(PLATFORM_PACKAGE)/BootScriptSaveDxe/BootScriptSaveDxe.inf
> +
> IntelFrameworkModulePkg/Universal/Acpi/AcpiSupportDxe/AcpiSupportDx
> e.inf
> +
> Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTable
> s/PowerManagementAcpiTables.inf
> +
> +  $(PLATFORM_RC_PACKAGE)/AcpiTablesPCAT/AcpiTables.inf
> +
> +  $(PLATFORM_PACKAGE)/AcpiPlatform/AcpiPlatform.inf
> +
> +
> MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraph
> icsResourceTableDxe.inf
> +
> +  #
> +  # PCI
> +  #
> +  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
> +
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/ISPDxe.inf
> +
> +
> +#
> +# ISA
> +#
> +  $(PLATFORM_PACKAGE)/Wpce791/Wpce791.inf
> +  IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBusDxe.inf
> +  IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaIoDxe.inf
> +  IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf
> +  IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf
> +
> IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf
> +#
> +# SDIO
> +#
> +#
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/MmcHost.inf
> +#
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/MmcMediaDevice.inf
> +!if $(ACPI50_ENABLE) == TRUE
> +
> MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/Firmw
> arePerformanceDxe.inf {
> +    <LibraryClasses>
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +  }
> +
> MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/Firm
> warePerformanceSmm.inf {
> +    <LibraryClasses>
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +  }
> +!endif
> +
> +#
> +# IDE/SCSI/AHCI
> +#
> +  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
> +  IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBusDxe.inf
> +  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
> +  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
> +
> MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
> +  FatPkg/EnhancedFatDxe/Fat.inf
> +  ShellPkg/Application/Shell/Shell.inf {
> +    <LibraryClasses>
> +
> ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellComma
> ndLib.inf
> +
> NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2Comma
> ndsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1Comma
> ndsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3Comma
> ndsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1Com
> mandsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1Com
> mandsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1Com
> mandsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1
> CommandsLib.inf
> +
> HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingL
> ib.inf
> +      PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
> +
> BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfg
> CommandLib.inf
> +    <PcdsFixedAtBuild>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
> +      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> +      gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
> +  }
> +!if $(SATA_ENABLE) == TRUE
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SataController.inf
> +!endif
> +  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
> +!if $(SCSI_ENABLE) == TRUE
> +  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
> +  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
> +!endif
> +#
> +# Console
> +#
> +  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
> +  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
> +
> MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleD
> xe.inf
> +
> IntelFrameworkModulePkg/Universal/Console/VgaClassDxe/VgaClassDxe.in
> f
> +  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
> +  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
> +  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
> +  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
> +
> +  #
> +  # USB
> +  #
> +!if $(USB_ENABLE) == TRUE
> +  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
> +  MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
> +  MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
> +  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
> +  MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
> +  MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
> +  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
> +
> +!endif
> +
> +  #
> +  # SMBIOS
> +  #
> +  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
> +  $(PLATFORM_PACKAGE)/SmBiosMiscDxe/SmBiosMiscDxe.inf
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SmbiosMemory.inf
> +  #
> +  # CPU/FW Microde
> +  #
> +  Vlv2SocBinPkg/Microcode/MicrocodeUpdates.inf {
> +    <BuildOptions>
> +      *_*_*_GENFW_FLAGS = -a 0x800 -p 0xFF
> +  }
> +
> +
> +
> +!if $(NETWORK_ENABLE) == TRUE
> +  !if $(NETWORK_ISCSI_ENABLE) == TRUE
> +    NetworkPkg/IScsiDxe/IScsiDxe.inf
> +  !endif
> +  !if $(NETWORK_VLAN_ENABLE) == TRUE
> +    MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf
> +  !endif
> +  !if $(CSM_ENABLE) == TRUE
> +    IntelFrameworkModulePkg/Csm/BiosThunk/Snp16Dxe/Snp16Dxe.inf
> +  !endif
> +!endif
> +
> +!if $(NETWORK_ENABLE) == TRUE
> +  #
> +  # UEFI network modules
> +  #
> +    MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
> +    MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf
> +
> +    MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
> +    MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
> +    MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
> +    MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
> +    MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
> +    NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
> +    NetworkPkg/TcpDxe/TcpDxe.inf
> +    MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
> +    !if $(NETWORK_IP6_ENABLE) == TRUE
> +      NetworkPkg/Ip6Dxe/Ip6Dxe.inf
> +      NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
> +      NetworkPkg/Udp6Dxe/Udp6Dxe.inf
> +      NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
> +    !endif
> +!endif
> +
> +!if $(CAPSULE_ENABLE) || $(MICOCODE_CAPSULE_ENABLE)
> +  MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxe.inf
> +  MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> +!endif
> +
> +!if $(CAPSULE_ENABLE)
> +  !include Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc
> +  !include Vlv2TbltDevicePkg/FmpGreenSampleDevice.dsc
> +  !include Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc
> +  !include Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc
> +!endif
> +
> +!if $(MICOCODE_CAPSULE_ENABLE)
> +
> IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDx
> e.inf {
> +    <LibraryClasses>
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +
> SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
> +  }
> +!endif
> +
> +[BuildOptions]
> +#
> +# Define Build Options both for EDK and EDKII drivers.
> +#
> +
> +#
> +# Define token for different Platform
> +#
> +!if $(MINNOW2_FSP_BUILD) == TRUE
> +  DEFINE MINNOW2_FSP_OPTION = /DMINNOW2_FSP_BUILD
> +!else
> +  DEFINE MINNOW2_FSP_OPTION =
> +!endif
> +
> +!if $(ENBDT_PF_BUILD) == TRUE
> +  DEFINE ENBDT_PF_ENABLE = /DENBDT_PF_ENABLE=1
> +!else
> +  DEFINE ENBDT_PF_ENABLE = /DENBDT_PF_ENABLE=0
> +!endif
> +
> +
> +!if $(CLKGEN_CONFIG_EXTRA_ENABLE) == TRUE
> +  DEFINE CLKGEN_CONFIG_EXTRA_BUILD_OPTION =
> /DCLKGEN_CONFIG_EXTRA=1
> +!else
> +  DEFINE CLKGEN_CONFIG_EXTRA_BUILD_OPTION =
> +!endif
> +
> +
> +
> +!if $(PCIESC_ENABLE) == TRUE
> +  DEFINE PCIESC_SUPPORT_BUILD_OPTION = /DPCIESC_SUPPORT=1
> +!else
> +  DEFINE PCIESC_SUPPORT_BUILD_OPTION =
> +!endif
> +!if $(SATA_ENABLE) == TRUE
> +  DEFINE SATA_SUPPORT_BUILD_OPTION = /DSATA_SUPPORT=1
> +!else
> +  DEFINE SATA_SUPPORT_BUILD_OPTION =
> +!endif
> +!if $(ENBDT_S3_SUPPORT) == TRUE
> +  DEFINE ENBDT_S3_SUPPORT_OPTIONS = /DNOCS_S3_SUPPORT
> +!else
> +  DEFINE ENBDT_S3_SUPPORT_OPTIONS =
> +!endif
> +
> +!if $(X64_CONFIG) == TRUE
> +  DEFINE X64_BUILD_ENABLE = /DX64_BUILD_ENABLE=1
> +!else
> +  DEFINE X64_BUILD_ENABLE =
> +!endif
> +
> +!if $(FTPM_ENABLE) == TRUE
> +  DEFINE DSC_FTPM_BUILD_OPTIONS = /DFTPM_ENABLE
> +!else
> +  DEFINE DSC_FTPM_BUILD_OPTIONS =
> +!endif
> +!if $(TPM_ENABLED) == TRUE
> +  DEFINE DSC_TPM_BUILD_OPTIONS = /DTPM_ENABLED
> +!else
> +  DEFINE DSC_TPM_BUILD_OPTIONS =
> +!endif
> +
> +
> +  DEFINE EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS =
> $(MINNOW2_FSP_OPTION) $(MINNOW2_BUILD_OPTION)
> $(ENBDT_PF_ENABLE) $(EXTERNAL_VGA_BUILD_OPTION)
> $(PCIE_ENUM_WA_BUILD_OPTION) $(X0_WA_ENABLE_BUILD_OPTION)
> $(A0_WA_ENABLE_BUILD_OPTION) $(MICROCODE_FREE_BUILD_OPTIONS)
> $(SIMICS_BUILD_OPTIONS) $(HYBRID_BUILD_OPTIONS)
> $(COMPACT_BUILD_OPTIONS) $(VP_BUILD_OPTIONS)
> $(SYSCTL_ID_BUILD_OPTION) $(CLKGEN_CONFIG_EXTRA_BUILD_OPTION)
> $(SYSCTL_X0_CONVERT_BOARD_OPTION) $(ENBDT_S3_SUPPORT_OPTIONS)
> $(SATA_SUPPORT_BUILD_OPTION) $(PCIESC_SUPPORT_BUILD_OPTION)
> $(DSC_FTPM_BUILD_OPTIONS) $(DSC_FTPM_ERROR_WR_BUILD_OPTIONS)
> $(DSC_TPM_BUILD_OPTIONS) $(DSC_BYTI_SECURE_BOOT_BUILD_OPTIONS)
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +  DEFINE PDB_BUILD_OPTION = /Zi
> +!endif
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +  MSFT:*_*_X64_GENFW_FLAGS  = --keepexceptiontable
> +  GCC:*_*_X64_GENFW_FLAGS   = --keepexceptiontable
> +  INTEL:*_*_X64_GENFW_FLAGS = --keepexceptiontable
> +!if $(TARGET) == DEBUG
> +  DEFINE SOURCE_LEVEL_DEBUG_BUILD_OPTIONS = /Od /Oy-
> +!endif
> +!else
> +  DEFINE SOURCE_LEVEL_DEBUG_BUILD_OPTIONS =
> +
> +!endif
> +
> +#
> +# Force PE/COFF sections to be aligned at 4KB boundaries to support page
> level
> +# protection of DXE_RUNTIME_DRIVER modules
> +#
> +[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
> +  MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
> +  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
> +
> +#
> +# Force PE/COFF sections to be aligned at 4KB boundaries to support page
> level
> +# protection of DXE_SMM_DRIVER/SMM_CORE modules
> +#
> +[BuildOptions.common.EDKII.DXE_SMM_DRIVER,
> BuildOptions.common.EDKII.SMM_CORE]
> +  MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
> +  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
> +
> +[BuildOptions.Common.EDK]
> +
> +#
> +# Define token for different Platform
> +#
> +!if $(ENBDT_PF_BUILD) == TRUE
> +  DEFINE ENBDT_PF_ENABLE = /DENBDT_PF_ENABLE=1
> +!else
> +  DEFINE ENBDT_PF_ENABLE = /DENBDT_PF_ENABLE=0
> +!endif
> +
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +  RELEASE_*_*_DLINK_FLAGS = /DEBUG
> +!endif
> +
> +!if $(S3_ENABLE) == TRUE
> +  DEFINE DSC_S3_BUILD_OPTIONS = /DEFI_S3_RESUME
> +!else
> +  DEFINE DSC_S3_BUILD_OPTIONS =
> +!endif
> +
> +!if $(ENBDT_S3_SUPPORT) == TRUE
> +  DEFINE ENBDT_S3_SUPPORT_OPTIONS = /DNOCS_S3_SUPPORT
> +!else
> +  DEFINE ENBDT_S3_SUPPORT_OPTIONS =
> +!endif
> +
> +!if $(X64_CONFIG) == TRUE
> +  DEFINE X64_BUILD_ENABLE = /DX64_BUILD_ENABLE=1
> +!else
> +  DEFINE X64_BUILD_ENABLE =
> +!endif
> +
> +
> +  DEFINE EDK_GLUE_LIB_DEBUG  =
> +  DEFINE DEBUG_BUILD_OPTIONS = /D EFI_DEBUG /D DEBUG_MODE=1
> /GL- $(EDK_GLUE_LIB_DEBUG)
> /DEDKII_GLUE_DebugPrintErrorLevel=(EFI_D_ERROR)
> +  DEFINE EDK_DSC_FEATURE_BUILD_OPTIONS = $(DSC_S3_BUILD_OPTIONS)
> $(DSC_ACPI_BUILD_OPTIONS) $(DSC_SEC_BUILD_OPTIONS)
> $(DSC_FTPM_BUILD_OPTIONS) $(DSC_FTPM_ERROR_WR_BUILD_OPTIONS)
> $(DSC_TPM_BUILD_OPTIONS) $(SOFTSDV_BUILD_OPTIONS)
> $(SIMICS_BUILD_OPTIONS) $(HYBRID_BUILD_OPTIONS)
> $(COMPACT_BUILD_OPTIONS) $(VP_BUILD_OPTIONS)
> $(QT_BUILD_OPTIONS) $(DSC_BYTI_SECURE_BOOT_BUILD_OPTIONS)
> /D$(PROJECT_SC_CHIPSET)
> +
> +  DEFINE EDK_DSC_OTHER_BUILD_OPTIONS =
> $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS) $(SV_BUILD_OPTIONS)
> $(INTEL_FASTBOOT_BUILD_OPTION)
> +  DEFINE EDK_DSC_GLOBAL_BUILD_OPTIONS = $(ENBDT_PF_ENABLE)
> $(EDK_DSC_FEATURE_BUILD_OPTIONS)
> $(EDK_DSC_OTHER_BUILD_OPTIONS) /D
> EFI_SPECIFICATION_VERSION=0x00020000  /D
> PI_SPECIFICATION_VERSION=0x00000009  /D
> TIANO_RELEASE_VERSION=0x00080006 /D
> SUPPORT_DEPRECATED_PCI_CFG_PPI /D CSM_SMMENTRY_PORT8DATA8 /D
> EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE) /D
> MAX_VARIABLE_SIZE=0x2000 /D EFI_FIRMWARE_VENDOR="L/"INTEL/"" /D
> EFI_BUILD_VERSION="L/"EDKII/"" /DEFI_PEI_REPORT_STATUS_CODE_ON
> $(ENBDT_S3_SUPPORT_OPTIONS)
> +
> +  *_*_IA32_ASM_FLAGS         = /DEFI32 /D
> EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h
> /DNOCS_S3_SUPPORT
> +  DEBUG_*_IA32_CC_FLAGS      = /D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_IA32_CC_FLAGS    = /D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  DEBUG_*_IA32_VFRPP_FLAGS   = /D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_IA32_VFRPP_FLAGS = /D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  DEBUG_*_IA32_APP_FLAGS     = /D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_IA32_APP_FLAGS   = /D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  DEBUG_*_IA32_PP_FLAGS      = /D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_IA32_PP_FLAGS    = /D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  *_*_IA32_ASLPP_FLAGS       = /D
> EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
> +  *_*_IA32_ASLCC_FLAGS       = /D
> EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
> +  *_*_IA32_ASM16_FLAGS       = /D
> EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h
> +
> +  *_*_X64_ASM_FLAGS          = /DEFIX64 /D
> EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h
> /DNOCS_S3_SUPPORT
> +  DEBUG_*_X64_CC_FLAGS       = /D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_X64_CC_FLAGS     = /D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  DEBUG_*_X64_VFRPP_FLAGS    = /D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_X64_VFRPP_FLAGS  = /D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  DEBUG_*_X64_APP_FLAGS      = /D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_X64_APP_FLAGS    = /D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  DEBUG_*_X64_PP_FLAGS       = /D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_X64_PP_FLAGS     = /D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  *_*_X64_ASLPP_FLAGS        = /D
> EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
> +  *_*_X64_ASLCC_FLAGS        = /D
> EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
> +  *_*_X64_ASM16_FLAGS        = /D
> EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h
> + # *_*_*_BUILD_FLAGS = -s
> +  *_*_*_VFR_FLAGS   = -c
> +  *_*_*_BUILD_FLAGS = -c
> +
> +[BuildOptions.Common.EDKII]
> +  *_*_IA32_ASM_FLAGS     = $(VP_BUILD_OPTIONS) /D
> EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h
> /DNOCS_S3_SUPPORT
> +
> +  *_*_IA32_CC_FLAGS      = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +  *_*_IA32_VFRPP_FLAGS   = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +  *_*_IA32_APP_FLAGS     = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +  *_*_IA32_PP_FLAGS      = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +  *_*_IA32_ASLPP_FLAGS   = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +
> +  *_*_X64_CC_FLAGS       = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> $(SOURCE_LEVEL_DEBUG_BUILD_OPTIONS)
> +  *_*_X64_VFRPP_FLAGS    = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +  *_*_X64_APP_FLAGS      = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +  *_*_X64_PP_FLAGS       = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +  *_*_X64_ASLPP_FLAGS    = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +
> +
> +[Components.IA32]
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/I2cBus.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
> +  }
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/I2cHost.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
> +  }
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/I2cPortA0Pio.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x00000043
> +  }
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/I2cMmioDeviceDxe.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x00000043
> +  }
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgX64.dsc
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgX64.dsc
> new file mode 100644
> index 0000000000..10d44d5652
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgX64.dsc
> @@ -0,0 +1,1714 @@
> +#/** @file
> +# Platform description.
> +#
> +# Copyright (c) 2012  - 2019, 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]
> +  PLATFORM_NAME                       = Vlv2TbltDevicePkg
> +  PLATFORM_GUID                       = 465B0A0B-7AC1-443b-8F67-7B8DEC145F90
> +  PLATFORM_VERSION                    = 0.1
> +  DSC_SPECIFICATION                   = 0x00010005
> +
> +  #
> +  # Set platform specific package/folder name, same as passed from
> PREBUILD script.
> +  # PLATFORM_PACKAGE would be the same as PLATFORM_NAME as well
> as package build folder
> +  # DEFINE only takes effect at R9 DSC and FDF.
> +  #
> +  DEFINE      PLATFORM_PACKAGE                = Vlv2TbltDevicePkg
> +  DEFINE      PLATFORM_RC_PACKAGE             = Vlv2DeviceRefCodePkg
> +  DEFINE      PLATFORM_BINARY_PACKAGE         = Vlv2SocBinPkg
> +  OUTPUT_DIRECTORY                    = Build/$(PLATFORM_PACKAGE)
> +  SUPPORTED_ARCHITECTURES             = IA32|X64
> +  BUILD_TARGETS                       = DEBUG|RELEASE
> +  SKUID_IDENTIFIER                    = DEFAULT
> +
> +  DEFINE CPU_ARCH                 =ValleyView2
> +  DEFINE PROJECT_SC_FAMILY        =IntelPch
> +  DEFINE PROJECT_SC_ROOT
> =../$(PLATFORM_RC_PACKAGE)/ValleyView2Soc/SouthCluster
> +  DEFINE PROJECT_VLV_ROOT
> =../$(PLATFORM_RC_PACKAGE)/ValleyView2Soc/NorthCluster
> +
> +  DEFINE RC_BINARY_RELEASE        = TRUE
> +  #
> +  # Platform On/Off features are defined here
> +  #
> +  #
> +  # Platform Support:: Set only one token except Crestview Hills
> +  #
> +  #   3.BayleyBay
> +  #     ENBDT_PF_ENABLE  = TRUE
> +  #
> +  !include $(PLATFORM_PACKAGE)/AutoPlatformCFG.txt
> +  !include $(PLATFORM_PACKAGE)/PlatformPkgConfig.dsc
> +
> +!if $(X64_CONFIG) == TRUE
> +  DEFINE      DXE_ARCHITECTURE        = X64
> +  DEFINE      EDK_DXE_ARCHITECTURE    = X64
> +  DEFINE      UNDI_DXE_ARCHITECTURE   = 64
> +!else
> +  DEFINE      DXE_ARCHITECTURE        = IA32
> +  DEFINE      EDK_DXE_ARCHITECTURE    = Ia32
> +  DEFINE      UNDI_DXE_ARCHITECTURE   = 32
> +!endif
> +
> +  FLASH_DEFINITION                    = $(PLATFORM_PACKAGE)/PlatformPkg.fdf
> +!if $(LFMA_ENABLE) == TRUE
> +  FIX_LOAD_TOP_MEMORY_ADDRESS         = 0xFFFFFFFFFFFFFFFF
> +  DEFINE   TOP_MEMORY_ADDRESS         = 0xFFFFFFFFFFFFFFFF
> +!else
> +  FIX_LOAD_TOP_MEMORY_ADDRESS         = 0x0
> +  DEFINE   TOP_MEMORY_ADDRESS         = 0x0
> +!endif
> +
> +  DEFINE   PLATFORM_PCIEXPRESS_BASE   = 0E0000000
> +
> +  DEFINE SEC_ENABLE = FALSE
> +  DEFINE SEC_DEBUG_INFO_ENABLE = FALSE
> +  DEFINE FTPM_ENABLE = FALSE
> +
> +#########################################################
> #######################
> +#
> +# SKU Identification section - list of all SKU IDs supported by this
> +#                              Platform.
> +#
> +#########################################################
> #######################
> +[SkuIds]
> +  0|DEFAULT              # The entry: 0|DEFAULT is reserved and always required.
> +
> +#########################################################
> #######################
> +#
> +# Library Class section - list of all Library Classes needed by this Platform.
> +#
> +#########################################################
> #######################
> +[LibraryClasses.common]
> +  #
> +  # Entry point
> +  #
> +
> PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.in
> f
> +  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
> +
> DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint
> .inf
> +
> UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntry
> Point.inf
> +
> UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiA
> pplicationEntryPoint.inf
> +
> DxeSmmDriverEntryPoint|IntelFrameworkPkg/Library/DxeSmmDriverEntryP
> oint/DxeSmmDriverEntryPoint.inf
> +
> +  #
> +  # Basic
> +  #
> +  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
> +!if $(SSE2_ENABLE) == TRUE
> +
> BaseMemoryLib|MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2
> .inf
> +!else
> +
> BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibR
> epStr.inf
> +!endif
> +  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
> +  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
> +  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
> +  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
> +
> PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibP
> ci.inf
> +  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
> +  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
> +
> CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCac
> heMaintenanceLib.inf
> +  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
> +
> PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/Base
> PeCoffGetEntryPointLib.inf
> +!if $(RC_BINARY_RELEASE) == TRUE
> +
> PchPlatformLib|Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLib.in
> f
> +!endif
> +  #
> +  # UEFI & PI
> +  #
> +
> UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBo
> otServicesTableLib.inf
> +
> UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib
> /UefiRuntimeServicesTableLib.inf
> +  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
> +  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
> +  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
> +
> UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiService
> sLib.inf
> +  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
> +
> UefiDecompressLib|MdeModulePkg/Library/BaseUefiTianoCustomDecompr
> essLib/BaseUefiTianoCustomDecompressLib.inf
> +
> PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/P
> eiServicesTablePointerLibIdt.inf
> +  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
> +  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
> +
> DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTabl
> eLib.inf
> +  UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
> +  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
> +
> GenericBdsLib|$(PLATFORM_PACKAGE)/Override/IntelFrameworkModuleP
> kg/Library/GenericBdsLib/GenericBdsLib.inf
> +
> BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupp
> ortLib.inf
> +  SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
> +
> PlatformBdsLib|$(PLATFORM_PACKAGE)/Library/PlatformBdsLib/PlatformB
> dsLib.inf
> +  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
> +  DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
> +
> FlashDeviceLib|$(PLATFORM_PACKAGE)/Library/FlashDeviceLib/FlashDevice
> Lib.inf
> +
> UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBoo
> tManagerLib.inf
> +  #
> +  # Framework
> +  #
> +!if $(S3_ENABLE) == TRUE
> +
> S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootSc
> riptLib.inf
> +!else
> +
> S3BootScriptLib|MdePkg/Library/BaseS3BootScriptLibNull/BaseS3BootScriptL
> ibNull.inf
> +!endif
> +  S3IoLib|MdePkg/Library/BaseS3IoLib/BaseS3IoLib.inf
> +  S3PciLib|MdePkg/Library/BaseS3PciLib/BaseS3PciLib.inf
> +
> +  #
> +  # Generic Modules
> +  #
> +!if $(USB_ENABLE) == TRUE
> +  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
> +!endif
> +!if $(SCSI_ENABLE) == TRUE
> +  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
> +!endif
> +!if $(NETWORK_ENABLE) == TRUE
> +  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
> +  IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
> +  UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
> +  TcpIoLib|MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf
> +  DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
> +!endif
> +!if $(S3_ENABLE) == TRUE
> +  S3Lib|IntelFrameworkModulePkg/Library/PeiS3Lib/PeiS3Lib.inf
> +!endif
> +
> +
> OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibN
> ull/OemHookStatusCodeLibNull.inf
> +!if $(CAPSULE_ENABLE) == TRUE
> +  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf
> +!else
> +
> CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.i
> nf
> +!endif
> +
> FmpAuthenticationLib|MdeModulePkg/Library/FmpAuthenticationLibNull/F
> mpAuthenticationLibNull.inf
> +  IniParsingLib|SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.inf
> +
> PlatformFlashAccessLib|Vlv2TbltDevicePkg/Feature/Capsule/Library/Platfor
> mFlashAccessLib/PlatformFlashAccessLib.inf
> +
> MicrocodeFlashAccessLib|Vlv2TbltDevicePkg/Feature/Capsule/Library/Platfo
> rmFlashAccessLib/PlatformFlashAccessLib.inf
> +
> DisplayUpdateProgressLib|MdeModulePkg/Library/DisplayUpdateProgressLi
> bGraphics/DisplayUpdateProgressLibGraphics.inf
> +
> SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchroniz
> ationLib.inf
> +
> SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementL
> ib/DxeSecurityManagementLib.inf
> +  IoApicLib|PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf
> +
> DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/Bas
> eDebugPrintErrorLevelLib.inf
> +
> +  #
> +  # CPU
> +  #
> +  MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf
> +
> LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.in
> f
> +
> CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeC
> puExceptionHandlerLib.inf
> +  MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
> +
> +  #
> +  # ICH
> +  #
> +  SmbusLib|$(PLATFORM_PACKAGE)/Library/SmbusLib/SmbusLib.inf
> +  SmmLib|$(PLATFORM_PACKAGE)/Library/PchSmmLib/PchSmmLib.inf
> +
> +  #
> +  # Platform
> +  #
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +
> ResetSystemLib|$(PLATFORM_PACKAGE)/Library/ResetSystemLib/ResetSys
> temLib.inf
> +
> +
> PlatformCmosLib|$(PLATFORM_PACKAGE)/Library/PlatformCmosLib/Platfor
> mCmosLib.inf
> +
> +  #
> +  # Misc
> +  #
> +
> MonoStatusCodeLib|$(PLATFORM_PACKAGE)/MonoStatusCode/MonoStat
> usCode.inf
> +!if $(TARGET) == RELEASE
> +  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
> +
> SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.in
> f
> +!else
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +
> SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
> +!endif
> +
> +
> PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanc
> eLibNull.inf
> +  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +!if $(TPM_ENABLED) == TRUE
> +  TpmCommLib|SecurityPkg/Library/TpmCommLib/TpmCommLib.inf
> +
> Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12Comma
> ndLib.inf
> +
> Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLib
> DTpm.inf
> +
> +!endif
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibD
> ebug/PeCoffExtraActionLibDebug.inf
> +
> DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicati
> onLibSerialPort/DebugCommunicationLibSerialPort.inf
> +
> PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePla
> tformHookLibNull.inf
> +
> SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPort
> Lib16550.inf
> +!else
> +
> PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BaseP
> eCoffExtraActionLibNull.inf
> +
> DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLi
> bNull.inf
> +!endif
> +
> +  #
> +  # CryptLib
> +  #
> +!if $(TPM_ENABLED) == TRUE
> +  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
> +  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
> +!endif
> +
> + BiosIdLib|$(PLATFORM_PACKAGE)/Library/BiosIdLib/BiosIdLib.inf
> + CpuIA32Lib|$(PLATFORM_PACKAGE)/Library/CpuIA32Lib/CpuIA32Lib.inf
> +
> +
> StallSmmLib|$(PLATFORM_PACKAGE)/Library/StallSmmLib/StallSmmLib.inf
> +
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
> +  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
> +
> PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecu
> reLibNull.inf
> +
> TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTp
> mMeasurementLib.inf
> +  AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
> +  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
> +!else
> +
> TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/Tp
> mMeasurementLibNull.inf
> +
> AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableL
> ibNull.inf
> +!endif
> +  VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
> +!if $(RC_BINARY_RELEASE) == TRUE
> +  I2cLib|Vlv2TbltDevicePkg/Library/I2CLib/I2CLibNull.inf
> +!endif
> +  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
> +
> ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellComma
> ndLib.inf
> +
> HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingL
> ib.inf
> +  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
> +  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
> +!if $(FTPM_ENABLE) == TRUE || $(NETWORK_ISCSI_ENABLE) == TRUE
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> +  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
> +  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
> +!endif
> +
> TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTp
> mMeasurementLib.inf
> +
> Tcg2PhysicalPresenceLib|SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/D
> xeTcg2PhysicalPresenceLib.inf
> +
> Tcg2PpVendorLib|SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorL
> ibNull.inf
> +
> +
> +
> Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandL
> ib.inf
> +!if $(MINNOW2_FSP_BUILD) == TRUE
> +  FspApiLib|IntelFspWrapperPkg/Library/BaseFspApiLib/BaseFspApiLib.inf
> +
> FspPlatformInfoLib|IntelFspWrapperPkg/Library/BaseFspPlatformInfoLibSa
> mple/BaseFspPlatformInfoLibSample.inf
> +
> FspPlatformSecLib|Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSe
> cLibVlv2/FspPlatformSecLibVlv2.inf
> +
> FspHobProcessLib|Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcess
> LibVlv2/FspHobProcessLibVlv2.inf
> +!endif
> +
> +  BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
> +
> +[LibraryClasses.IA32.SEC]
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +
> PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanc
> eLibNull.inf
> +!endif
> +  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
> +  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +
> +[LibraryClasses.IA32.PEIM, LibraryClasses.IA32.PEI_CORE,
> LibraryClasses.IA32.SEC]
> +  #
> +  # PEI phase common
> +  #
> +
> +  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
> +
> MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemory
> AllocationLib.inf
> +
> ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiR
> eportStatusCodeLib.inf
> +
> ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiEx
> tractGuidedSectionLib.inf
> +
> MultiPlatformLib|$(PLATFORM_PACKAGE)/Library/MultiPlatformLib/MultiPl
> atformLib.inf
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
> +
> CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecP
> eiCpuExceptionHandlerLib.inf
> +  MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
> +
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +
> PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanc
> eLib.inf
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +!endif
> +
> +!if $(TARGET) == RELEASE
> +  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
> +
> SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.in
> f
> +!else
> +
> DebugLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDx
> eDebugLibReportStatusCode.inf
> +
> SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
> +!endif
> +
> +
> LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf
> +
> HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoR
> outerPei.inf
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAg
> entLib.inf
> +!endif
> +
> + !if $(MINNOW2_FSP_BUILD) == TRUE
> +
> PlatformFspLib|Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.in
> f
> + !endif
> +!if $(FTPM_ENABLE) == TRUE
> +
> Tpm2DeviceLib|Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2Devi
> ceLibSeC.inf
> +!endif
> +
> +[LibraryClasses.X64]
> +  #
> +  # DXE phase common
> +  #
> +  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
> +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +
> MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemo
> ryAllocationLib.inf
> +
> ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/Dx
> eReportStatusCodeLib.inf
> +
> ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeE
> xtractGuidedSectionLib.inf
> +
> +
> TcgPhysicalPresenceLib|SecurityPkg/Library/DxeTcgPhysicalPresenceLib/Dxe
> TcgPhysicalPresenceLib.inf
> +!if $(TPM_ENABLED) == TRUE
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> +!endif
> +
> +
> LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.in
> f
> +
> EfiRegTableLib|$(PLATFORM_PACKAGE)/Library/EfiRegTableLib/EfiRegTable
> Lib.inf
> +
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> +!endif
> +
> +
> HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoR
> outerDxe.inf
> +
> +[LibraryClasses.X64.DXE_DRIVER]
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +
> PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanc
> eLibNull.inf
> +
> CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/Custo
> mizedDisplayLib.inf
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +
> PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerforma
> nceLib.inf
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +!endif
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgen
> tLib.inf
> +!endif
> +
> +
> FlashDeviceLib|$(PLATFORM_PACKAGE)/Library/FlashDeviceLib/FlashDevice
> LibDxe.inf
> +
> +[LibraryClasses.X64.DXE_CORE]
> +  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
> +
> MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLi
> b/DxeCoreMemoryAllocationLib.inf
> +  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +
> PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCore
> PerformanceLib.inf
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +!endif
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgen
> tLib.inf
> +!endif
> +
> +[LibraryClasses.X64.DXE_SMM_DRIVER]
> +
> MmServicesTableLib|MdePkg/Library/MmServicesTableLib/MmServicesTabl
> eLib.inf
> +
> SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesT
> ableLib.inf
> +
> ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/S
> mmReportStatusCodeLib.inf
> +
> MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMe
> moryAllocationLib.inf
> +
> LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.i
> nf
> +
> PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanc
> eLibNull.inf
> +  SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
> +
> SmmCpuPlatformHookLib|UefiCpuPkg/Library/SmmCpuPlatformHookLibNull
> /SmmCpuPlatformHookLibNull.inf
> +
> SmmCpuFeaturesLib|UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFea
> turesLib.inf
> +
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> +  !if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +  !endif
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAge
> ntLib.inf
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +!endif
> +
> CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/Smm
> CpuExceptionHandlerLib.inf
> +
> +[LibraryClasses.X64.SMM_CORE]
> +
> MemoryAllocationLib|MdeModulePkg/Library/PiSmmCoreMemoryAllocatio
> nLib/PiSmmCoreMemoryAllocationLib.inf
> +
> SmmServicesTableLib|MdeModulePkg/Library/PiSmmCoreSmmServicesTabl
> eLib/PiSmmCoreSmmServicesTableLib.inf
> +
> ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/S
> mmReportStatusCodeLib.inf
> +
> SmmCorePlatformHookLib|MdeModulePkg/Library/SmmCorePlatformHook
> LibNull/SmmCorePlatformHookLibNull.inf
> +  SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
> +
> +!if $(TPM_ENABLED) == TRUE
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
> +!endif
> +
> +
> PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanc
> eLibNull.inf
> +
> +!if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +!endif
> +
> +[LibraryClasses.X64.DXE_RUNTIME_DRIVER]
> +
> ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCod
> eLib/RuntimeDxeReportStatusCodeLib.inf
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
> +!endif
> +!if $(TPM_ENABLED) == TRUE
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
> +!endif
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgen
> tLib.inf
> +!endif
> +
> +!if $(CAPSULE_ENABLE) == TRUE
> +
> CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsule
> Lib.inf
> +!endif
> +
> +[LibraryClasses.common.UEFI_DRIVER]
> +  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgen
> tLib.inf
> +!endif
> +
> +[LibraryClasses.X64.UEFI_APPLICATION]
> +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgen
> tLib.inf
> +!endif
> +
> +#########################################################
> #######################
> +#
> +# Pcd Section - list of all EDK II PCD Entries defined by this Platform
> +#
> +#########################################################
> #######################
> +[PcdsFeatureFlag.common]
> +!if $(MINI_BIOS_ENABLE) == FALSE
> +  gPlatformModuleTokenSpaceGuid.PcdBdsDispatchAdditionalOprom|TRUE
> +!else
> +
> gPlatformModuleTokenSpaceGuid.PcdBdsDispatchAdditionalOprom|FALSE
> +!endif
> +#
> +# If PcdDxeIplSwitchToLongMode is TRUE, DxeIpl will load a 64-bit DxeCore
> and switch to long mode to hand over to DxeCore.
> +#
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|TRUE
> +
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserGrayOutTextStatement|TR
> UE
> +
> +!if $(CAPSULE_RESET_ENABLE) == TRUE
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|TRUE
> +!else
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|FALS
> E
> +!endif
> +  gEfiCpuTokenSpaceGuid.PcdCpuSmmEnableBspElection|FALSE
> +!if $(DATAHUB_STATUS_CODE_ENABLE) == TRUE
> +
> gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeUseDataHub
> |TRUE
> +!else
> +
> gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeUseDataHub
> |FALSE
> +!endif
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreImageLoaderSearchTeSecti
> onFirst|FALSE
> +!if $(TARGET) == RELEASE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
> +!else
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
> +!endif
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE
> +!if $(ISA_SERIAL_STATUS_CODE_ENABLE) == TRUE
> +  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseIsaSerial|TRUE
> +!else
> +  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseIsaSerial|FALSE
> +!endif
> +!if $(USB_SERIAL_STATUS_CODE_ENABLE) == TRUE
> +  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseUsbSerial|TRUE
> +!else
> +  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseUsbSerial|FALSE
> +!endif
> +!if $(RAM_SERIAL_STATUS_CODE_ENABLE) == TRUE
> +  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseRam|TRUE
> +!else
> +  gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseRam|FALSE
> +!endif
> +
> +
> +  ## This PCD specifies whether PS2 keyboard does a extended verification
> during start.
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdPs2KbdExtendedVerification|FALSE
> +
> +  ## This PCD specifies whether PS2 mouse does a extended verification
> during start.
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdPs2MouseExtendedVerification|FA
> LSE
> +
> +!if $(VARIABLE_INFO_ENABLE) == TRUE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics|TRUE
> +!else
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics|FALSE
> +!endif
> +
> +  gEfiCpuTokenSpaceGuid.PcdCpuSmmBlockStartupThisAp|TRUE
> +
> +!if $(SOURCE_DEBUG_ENABLE)
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmDebug|TRUE
> +!endif
> +
> +[PcdsFixedAtBuild.common]
> +!if $(MINNOW2_FSP_BUILD) == TRUE
> +# $(FLASH_REGION_VLVMICROCODE_BASE)
> +
> gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress|0xFFC00000
> +# $(FLASH_REGION_VLVMICROCODE_SIZE)
> +
> gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize|0x0004000
> 0
> +  gFspWrapperTokenSpaceGuid.PcdFlashMicroCodeOffset|0x60
> +# $(FLASH_AREA_BASE_ADDRESS)
> +  gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheAddress|0xFF800000
> +# $(FLASH_AREA_SIZE)
> +  gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheSize|0x00800000
> +# $(FLASH_REGION_FSPBIN_BASE)
> +  gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase|0xFFCC0000
> +!endif
> +
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +!if $(MINNOW2_FSP_BUILD) == TRUE
> +  # in FSP, when this got used, the memory already is up
> +  gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0x00080000
> +!else
> +  gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0xFEF80000
> +!endif
> +  gEfiCpuTokenSpaceGuid.PcdTemporaryRamSize|0x00010000
> +
> +!else
> +  !if $(MINNOW2_FSP_BUILD) == TRUE
> +    gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0x00080000
> +  !else
> +    gEfiCpuTokenSpaceGuid.PcdTemporaryRamBase|0xFEF80000
> +  !endif
> +  gEfiCpuTokenSpaceGuid.PcdTemporaryRamSize|0x00010000
> +  gEfiCpuTokenSpaceGuid.PcdPeiTemporaryRamStackSize|0x3C00
> +!endif
> +
> +
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x22000
> +!else
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x4000
> +!endif
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize|0x00000800
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x4
> 00
> +  gEfiCpuTokenSpaceGuid.PcdCpuIEDRamSize|0x400000
> +
> gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemory
> Size|0x10000
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|FALSE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAriSupport|FALSE
> +  gEfiCpuTokenSpaceGuid.PcdCpuSmmApSyncTimeout|1000
> +!if $(S4_ENABLE) == TRUE
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationC
> hange|TRUE
> +!else
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationC
> hange|FALSE
> +!endif
> +!if $(TARGET) == RELEASE
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0
> +  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x3
> +!else
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
> +  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
> +!endif
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0x1
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPerformanceLogEntries|60
> +!endif
> +
> +
> gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdEbdaReservedMemorySi
> ze|0x10000
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable|$(
> TOP_MEMORY_ADDRESS)
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserSubtitleTextColor|0x0
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldTextColor|0x01
> +  gEfiCpuTokenSpaceGuid.PcdCpuIEDEnabled|TRUE
> +
> gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBiosVideoCheckVbeEna
> ble|TRUE
> +
> gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBiosVideoCheckVgaEnab
> le|TRUE
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
> +  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl|FAL
> SE
> +
> gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod|2
> +!endif
> +
> +  #
> +  # Set SMM stack size to 16 KB.
> +  #
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize|0x4000
> +
> +  #
> +  # Clear unused single certificate PCD
> +  #
> +  gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer|{0}
> +
> +  #
> +  # Lock all updatable firmware devices at End of DXE
> +  #
> +
> gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceLockEventGuid|{GUID(gEfiE
> ndOfDxeEventGroupGuid)}
> +#
> gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceLockEventGuid|{GUID(gEfiE
> ventReadyToBootGuid)}
> +
> +  #
> +  # Set PcdFmpDeviceTestKeySha256Digest to {0} to disable test key
> detection
> +  #
> +#  gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceTestKeySha256Digest|{0}
> +
> +[PcdsFixedAtBuild.IA32]
> +!if $(TARGET) == RELEASE
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0
> +  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x3
> +!else
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
> +  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
> +!endif
> +
> +!if $(RECOVERY_ENABLE)
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdRecoveryFileName|L"VLV2REC.Cap
> "
> +!endif
> +
> +[PcdsPatchableInModule.common]
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x803805c6
> +
> gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0x$(PLATFORM_PC
> IEXPRESS_BASE)
> +
> gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLegacyBiosCacheLegacy
> Region|FALSE
> +
> +  ## This PCD specifies whether to use the optimized timing for best PS2
> detection performance.
> +  #  Note this PCD could be set to TRUE for best boot performance and set to
> FALSE for best device compatibility.
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFastPS2Detection|TRUE
> +
> +
> ##########################################################
> #############################################
> +  #
> +  # Begin of MRC parameters
> +  #
> +
> +  ## Memory Parameter Patchable.
> +  #  FALSE - MRC Parameters are fixed for MinnowBoard Max<BR>
> +  #  TRUE  - MRC Parameters are patchable by following PCDs<BR>
> +  # @Prompt Memory Parameter Patchable.
> +  # @ValidList 0x80000001 | 0, 1
> +  gVlvRefCodePkgTokenSpaceGuid.PcdMemoryParameterPatchable|FALSE
> +
> +  ## Memory Down or DIMM slot.
> +  #  0 - DIMM<BR>
> +  #  1 - Memory Down<BR>
> +  # @Prompt Enable Memory Down
> +  # @ValidList 0x80000001 | 0, 1
> +  gVlvRefCodePkgTokenSpaceGuid.PcdEnableMemoryDown|1
> +
> +  ## The speed of DRAM.
> +  #  0 - 800 MHz<BR>
> +  #  1 - 1066 MHz<BR>
> +  #  2 - 1333 MHz<BR>
> +  #  3 - 1600 MHz<BR>
> +  # @Prompt DRAM Speed
> +  # @ValidList 0x80000001 | 0, 1, 2, 3
> +  gVlvRefCodePkgTokenSpaceGuid.PcdDramSpeed|1
> +
> +  ## DRAM Type.
> +  #  0 - DDR3<BR>
> +  #  1 - DDR3L<BR>
> +  #  2 - DDR3U<BR>
> +  #  3 - DDR3All<BR>
> +  #  4 - LPDDR2<BR>
> +  #  5 - LPDDR3<BR>
> +  #  6 - DDR4<BR>
> +  # @Prompt DRAM Type
> +  # @ValidList 0x80000001 | 0, 1, 2, 3, 4, 5, 6
> +  gVlvRefCodePkgTokenSpaceGuid.PcdDramType|1
> +
> +  ## Please populate DIMM slot 0 if only one DIMM is supported.
> +  #  0 - Disable<BR>
> +  #  1 - Enable<BR>
> +  # @Prompt DIMM 0 Enable
> +  # @ValidList 0x80000001 | 0, 1
> +  gVlvRefCodePkgTokenSpaceGuid.PcdEnableDimm0|1
> +
> +  ## DIMM 1 has to be identical to DIMM 0.
> +  #  0 - Disable<BR>
> +  #  1 - Enable<BR>
> +  # @Prompt DIMM 1 Enable Type
> +  # @ValidList 0x80000001 | 0, 1
> +  gVlvRefCodePkgTokenSpaceGuid.PcdEnableDimm1|0
> +
> +  ## DRAM device data width.
> +  #  0 - x8<BR>
> +  #  1 - x16<BR>
> +  #  2 - x32<BR>
> +  # @Prompt DIMM_DWIDTH
> +  # @ValidList 0x80000001 | 0, 1, 2
> +  gVlvRefCodePkgTokenSpaceGuid.PcdDimmDataWidth|1
> +
> +  ## DRAM device data density.
> +  #  0 - 1 Gbit<BR>
> +  #  1 - 2 Gbit<BR>
> +  #  2 - 4 Gbit<BR>
> +  #  3 - 8 Gbit<BR>
> +  # @Prompt DIMM_Density
> +  # @ValidList 0x80000001 | 0, 1, 2, 3
> +  gVlvRefCodePkgTokenSpaceGuid.PcdDimmDensity|2
> +
> +  ## DRAM device data bus width.
> +  #  0 - 8 bits<BR>
> +  #  1 - 16 bits<BR>
> +  #  2 - 32 bits<BR>
> +  #  3 - 64 bits<BR>
> +  # @Prompt DIMM_BusWidth
> +  # @ValidList 0x80000001 | 0, 1, 2, 3
> +  gVlvRefCodePkgTokenSpaceGuid.PcdDimmBusWidth|3
> +
> +  ## Ranks Per DIMM or Sides Per DIMM.
> +  #  0 - 1 Rank<BR>
> +  #  1 - 2 Ranks<BR>
> +  # @Prompt DIMM_Sides
> +  # @ValidList 0x80000001 | 0, 1
> +  gVlvRefCodePkgTokenSpaceGuid.PcdRankPerDimm|0
> +
> +  ## tCL.<BR><BR>
> +  # @Prompt tCL
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTcl|11
> +
> +  ## tRP and tRCD in DRAM clk - 5:12.5ns, 6:15ns, etc.
> +  # @Prompt tRP_tRCD
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTrpTrcd|11
> +
> +  ## tWR in DRAM clk.
> +  # @Prompt tWR
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTwr|12
> +
> +  ## tWTR in DRAM clk.
> +  # @Prompt tWTR
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTwtr|6
> +
> +  ## tRRD in DRAM clk.
> +  # @Prompt tRRD
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTrrd|6
> +
> +  ## tRTP in DRAM clk.
> +  # @Prompt tRTP
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTrtp|6
> +
> +  ## tFAW in DRAM clk.
> +  # @Prompt tFAW
> +  gVlvRefCodePkgTokenSpaceGuid.PcdTfaw|32
> +
> +  #
> +  # End of MRC parameters.
> +  #
> +
> ##########################################################
> #####################################
> +
> +[PcdsDynamicHii.common.DEFAULT]
> +
> gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlo
> balVariableGuid|0x0|5 # Variable: L"Timeout"
> +
> gEfiMdePkgTokenSpaceGuid.PcdHardwareErrorRecordLevel|L"HwErrRecSup
> port"|gEfiGlobalVariableGuid|0x0|1 # Variable: L"HwErrRecSupport"
> +
> +[PcdsDynamicDefault.common.DEFAULT]
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr|0x
> 0
> +  !if $(TPM_ENABLED) == TRUE
> +    gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{0x7b, 0x3a, 0xcd,
> 0x72, 0xA5, 0xFE, 0x5e, 0x4f, 0x91, 0x65, 0x4d, 0xd1, 0x21, 0x87, 0xbb, 0x13}
> +  !endif
> +
> +  ## This PCD defines the video horizontal resolution.
> +  #  This PCD could be set to 0 then video resolution could be at highest
> resolution.
> +  #gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|0
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|800
> +  ## This PCD defines the video vertical resolution.
> +  #  This PCD could be set to 0 then video resolution could be at highest
> resolution.
> +  #gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|0
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600
> +
> +  ## This PCD defines the Console output column and the default value is 25
> according to UEFI spec.
> +  #  This PCD could be set to 0 then console output could be at max column
> and max row.
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|31
> +  ## This PCD defines the Console output row and the default value is 80
> according to UEFI spec.
> +  #  This PCD could be set to 0 then console output could be at max column
> and max row.
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|100
> +
> +  ## The PCD is used to specify the video horizontal resolution of text setup.
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|80
> 0
> +  ## The PCD is used to specify the video vertical resolution of text setup.
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|600
> +  ## The PCD is used to specify the console output column of text setup.
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutColumn|100
> +  ## The PCD is used to specify the console output column of text setup.
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutRow|31
> +
> +!if $(TPM_ENABLED) == TRUE
> +  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInitializationPolicy|1
> +  gEfiSecurityPkgTokenSpaceGuid.PcdTpmScrtmPolicy|1
> +!endif
> +
> +[PcdsDynamicExDefault.common.DEFAULT]
> +  gEfiVLVTokenSpaceGuid.PcdTCSmbaIoBaseAddress|0x1040
> +  gEfiVLVTokenSpaceGuid.PcdEmmcManufacturerId|0
> +  gEfiVLVTokenSpaceGuid.PcdProductSerialNumber|0
> +  gEfiVLVTokenSpaceGuid.PcdMeasuredBootEnable|TRUE
> +  gEfiVLVTokenSpaceGuid.PcdFTPMErrorOccur|FALSE
> +  gEfiVLVTokenSpaceGuid.PcdFTPMErrorSkip|FALSE
> +  gEfiVLVTokenSpaceGuid.PcdFTPMCommand|0
> +  gEfiVLVTokenSpaceGuid.PcdFTPMResponse|0
> +  gEfiVLVTokenSpaceGuid.PcdFTPMNotRespond|FALSE
> +  gEfiVLVTokenSpaceGuid.PcdFTPMStatus|0
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateSmmDataP
> tr|0
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr|0
> +  gEfiCpuTokenSpaceGuid.PcdCpuS3DataAddress|0
> +  gEfiCpuTokenSpaceGuid.PcdCpuHotPlugDataAddress|0
> +  gEfiCpuTokenSpaceGuid.PcdCpuCallbackSignal|0
> +  gEfiCpuTokenSpaceGuid.PcdCpuConfigContextBuffer|0
> +  gEfiVLVTokenSpaceGuid.PcdCpuLockBoxDataAddress|0
> +  gEfiVLVTokenSpaceGuid.PcdCpuSmramCpuDataAddress|0
> +  gEfiVLVTokenSpaceGuid.PcdCpuLockBoxSize|0
> +
> +[PcdsDynamicExDefault.X64.DEFAULT]
> +!if $(RECOVERY_ENABLE)
> +
> gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareFileGuid|{G
> UID("AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215")}|VOID*|0x10
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdSystemFmpCapsuleImageTypeIdGu
> id|{GUID("4096267b-da0a-42eb-b5eb-fef31d207cb4")}|VOID*|0x10
> +!endif
> +
> +[Components.IA32]
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/S
> ecCore.inf
> +
> +  !if $(MINNOW2_FSP_BUILD) == TRUE
> +  IntelFspWrapperPkg/FspWrapperSecCore/FspWrapperSecCore.inf {
> +    !if $(TARGET) == DEBUG
> +
> +    <LibraryClasses>
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +    !endif
> +  }
> +  Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.inf
> +  IntelFspWrapperPkg/FspInitPei/FspInitPei.inf {
> +    !if $(TARGET) == DEBUG
> +    <LibraryClasses>
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +    !endif
> +  }
> +  !endif
> +
> +  MdeModulePkg/Core/Pei/PeiMain.inf {
> +!if $(TARGET) == DEBUG
> +    <PcdsFixedAtBuild>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
> +!endif
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
> +  }
> +
> +  $(PLATFORM_PACKAGE)/MonoStatusCode/MonoStatusCode.inf {
> +!if $(TARGET) == DEBUG
> +    <PcdsFixedAtBuild>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
> +!endif
> +  }
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/M
> emoryInit.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
> +    <BuildOptions>
> +      !if $(FTPM_ENABLE)==TRUE
> +        *_*_IA32_CC_FLAGS = /D FTPM_ENABLE
> +      !endif
> +  }
> +
> +!if $(RC_BINARY_RELEASE) == TRUE
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/S
> eCUma.inf
> +!endif
> +
> +!if $(FTPM_ENABLE) == TRUE
> +$(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/f
> TPMInitPeim.inf
> +!endif
> +
> +!if $(RC_BINARY_RELEASE) == TRUE
> +  $(PLATFORM_PACKAGE)/PlatformPei/PlatformPei.inf {
> +    <BuildOptions>
> +      *_*_IA32_CC_FLAGS      = /DRC_BINARY_RELEASE
> +  !if $(TARGET) == DEBUG
> +      <PcdsFixedAtBuild>
> +        gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E
> +  !endif
> +  }
> +!endif
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +  SourceLevelDebugPkg/DebugAgentPei/DebugAgentPei.inf{
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAg
> entLib.inf
> +
> PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePla
> tformHookLibNull.inf
> +
> SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPort
> Lib16550.inf
> +    }
> +!endif
> +
> +!if $(FTPM_ENABLE) == TRUE
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/T
> pm2DeviceSeCPei.inf
> +!endif
> +
> +!if $(TPM_ENABLED) == TRUE
> +  SecurityPkg/Tcg/PhysicalPresencePei/PhysicalPresencePei.inf
> +  SecurityPkg/Tcg/TcgPei/TcgPei.inf {
> +    <LibraryClasses>
> +
> NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
> +
> NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.in
> f
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +}
> +!endif
> +
> + $(PLATFORM_PACKAGE)/PlatformInitPei/PlatformInitPei.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x803805c6
> +    <LibraryClasses>
> +!if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +!endif
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +  }
> +  $(PLATFORM_PACKAGE)/FvInfoPei/FvInfoPei.inf
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/Vl
> vInitPeim.inf
> +!if $(PCIESC_ENABLE) == TRUE
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chEarlyInitPeim.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
> +  }
> +!endif
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chInitPeim.inf
> +
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chSmbusArpDisabled.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chSpiPeim.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> eiSmmAccess.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> eiSmmControl.inf
> +  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/C
> puPeim.inf
> +  UefiCpuPkg/CpuIoPei/CpuIoPei.inf
> +  UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/M
> pS3.inf
> +#
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/Pi
> SmmCommunicationPei.inf
> +
> +!if $(RECOVERY_ENABLE)
> +  #
> +  # Recovery
> +  #
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/IA32/P
> chUsb.inf
> +  MdeModulePkg/Bus/Pci/EhciPei/EhciPei.inf
> +  MdeModulePkg/Bus/Usb/UsbBusPei/UsbBusPei.inf
> +  MdeModulePkg/Bus/Usb/UsbBotPei/UsbBotPei.inf
> +  FatPkg/FatPei/FatPei.inf
> +  MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf
> +
> SignedCapsulePkg/Universal/RecoveryModuleLoadPei/RecoveryModuleLoa
> dPei.inf {
> +    <LibraryClasses>
> +
> FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibRsa2048Sh
> a256/FmpAuthenticationLibRsa2048Sha256.inf
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +  }
> +!endif
> +
> +!if $(CAPSULE_ENABLE) == TRUE
> +  MdeModulePkg/Universal/CapsulePei/CapsulePei.inf
> +!endif
> +  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
> +    <LibraryClasses>
> +!if $(LZMA_ENABLE) == TRUE
> +
> NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDec
> ompressLib.inf
> +!endif
> +  }
> +
> + MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
> +
> MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
> +
> +!if $(FTPM_ENABLE) == TRUE
> +   SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
> +    <LibraryClasses>
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +
> NULL|SecurityPkg/Library\HashInstanceLibSha1/HashInstanceLibSha1.inf
> +
> NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.in
> f
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +  }
> +!endif
> +!if $(TPM_ENABLED) == TRUE
> +  SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +  }
> +!endif
> +!if $(ACPI50_ENABLE) == TRUE
> +
> MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/Firmwa
> rePerformancePei.inf{
> +    <LibraryClasses>
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +  }
> +
> +!endif
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +
> MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCode
> RouterPei.inf
> +!endif
> +[Components.X64]
> +  !if $(MINNOW2_FSP_BUILD) == TRUE
> +  IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.inf {
> +    !if $(TARGET) == DEBUG
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
> +    <LibraryClasses>
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +    !endif
> +  }
> +
> +  !endif
> +  #
> +  # EDK II Related Platform codes
> +  #
> +  MdeModulePkg/Core/Dxe/DxeMain.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
> +    <LibraryClasses>
> +!if $(DXE_CRC32_SECTION_ENABLE) == TRUE
> +
> NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32G
> uidedSectionExtractLib.inf
> +!endif
> +!if $(LZMA_ENABLE) == TRUE
> +
> NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDec
> ompressLib.inf
> +!endif
> +!if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +!endif
> +  }
> +
> IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3SaveDxe.i
> nf {
> +    <PcdsPatchableInModule>
> +        gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
> +    <PcdsFixedAtBuild>
> +        gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x27
> +    <LibraryClasses>
> +    !if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +    !endif
> +       <BuildOptions>
> +        ICC:*_*_*_CC_FLAGS = /D MDEPKG_NDEBUG
> +        GCC:*_*_*_CC_FLAGS = -D MDEPKG_NDEBUG
> +  }
> +  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +  }
> +  IntelFrameworkModulePkg/Universal/CpuIoDxe/CpuIoDxe.inf
> +  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
> +
> +
> MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportSt
> atusCodeRouterRuntimeDxe.inf
> +
> MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHan
> dlerRuntimeDxe.inf  {
> +    <LibraryClasses>
> +!if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +!endif
> +  }
> +
> +!if $(CAPSULE_ENABLE) == TRUE
> +  MdeModulePkg/Universal/CapsulePei/CapsuleX64.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +
> MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemory
> AllocationLib.inf
> +      HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
> +
> CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecP
> eiCpuExceptionHandlerLib.inf
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAg
> entLib.inf
> +!endif
> +  }
> +!endif
> +
> +
> MdeModulePkg/Universal/ReportStatusCodeRouter/Smm/ReportStatusCod
> eRouterSmm.inf
> +  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf{
> +    <LibraryClasses>
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +
> NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib
> .inf
> +!endif
> +!if $(USER_IDENTIFICATION_ENABLE)
> +
> NULL|SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.in
> f
> +!endif
> +!if $(TPM_ENABLED) == TRUE
> +
> NULL|SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLi
> b.inf
> +!endif
> +!if $(FTPM_ENABLE) == TRUE
> +
> NULL|SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBoot
> Lib.inf
> +!endif
> +  }
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/MpCpu.inf
> +  $(PLATFORM_PACKAGE)/Metronome/Metronome.inf
> +
> +  IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf{
> +    <LibraryClasses>
> +      OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
> +      IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
> +      BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> +
> PlatformBdsLib|$(PLATFORM_PACKAGE)/Library/PlatformBdsLib/PlatformB
> dsLib.inf
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +
> SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
> +    !if $(FTPM_ENABLE) == TRUE
> +
> Tpm2DeviceLib|Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2Devi
> ceLibSeC.inf
> +    !else
> +
> Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2
> .inf
> +    !endif
> +  }
> +
> +  $(PLATFORM_PACKAGE)/UiApp/UiApp.inf
> +
> +  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
> +  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
> +
> MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.in
> f
> +
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.i
> nf
> +  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf {
> +    <LibraryClasses>
> +      NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
> +
> SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
> +  }
> +  $(PLATFORM_PACKAGE)/FvbRuntimeDxe/FvbSmm.inf
> +
> MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.i
> nf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchSpiSmm.inf
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +
> SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfi
> gDxe.inf {
> +    <LibraryClasses>
> +
> PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecu
> reLibNull.inf
> +    <BuildOptions>
> +      #
> +      # Specify GUID gEfiIfrBootMaintenanceGuid, to install Secure Boot
> Configuration menu
> +      # into Boot Maintenance Manager menu
> +      #
> +      *_*_*_VFR_FLAGS   = -g b2dedc91-d59f-48d2-898a-12490c74a4e0
> +  }
> +!endif
> +   MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf {
> +    <LibraryClasses>
> +      FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
> +  }
> +
> +
> MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCoun
> terRuntimeDxe.inf
> +
> PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntime
> Dxe.inf
> +  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
> +
> +  $(PLATFORM_PACKAGE)/FvbRuntimeDxe/FvbRuntimeDxe.inf
> +
> +  $(PLATFORM_PACKAGE)/PlatformSetupDxe/PlatformSetupDxe.inf
> +
> +!if $(DATAHUB_ENABLE) == TRUE
> +  IntelFrameworkModulePkg/Universal/DataHubDxe/DataHubDxe.inf {
> +    <PcdsFixedAtBuild>
> +      gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|0
> +  }
> +!endif
> +
> IntelFrameworkModulePkg/Universal/StatusCode/DatahubStatusCodeHandl
> erDxe/DatahubStatusCodeHandlerDxe.inf
> +
> MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryT
> estDxe.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchS3SupportDxe.inf
> +  !if $(USE_HPET_TIMER) == TRUE
> +    PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf
> +  !else
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SmartTimer.inf
> +  !endif
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SmmControl.inf
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchSmbusDxe.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/IntelPchLegacyInterrupt.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchReset.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchInitDxe.inf{
> +    <PcdsPatchableInModule>
> +        gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
> +  }
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchInitSmm.inf
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchSmiDispatcher.inf
> +
> +!if $(PCIESC_ENABLE) == TRUE
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchPcieSmm.inf
> +!endif
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchSpiRuntime.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchPolicyInitDxe.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PchBiosWriteProtect.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SmmAccess.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PciHostBridge.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/VlvInitDxe.inf
> +
> +
> IntelFrameworkModulePkg/Universal/LegacyRegionDxe/LegacyRegionDxe.i
> nf
> +
> +  #
> +  # Performance Application; Set PERFORMANCE_ENABLE=TRUE for normal
> boot performance and smm performance data
> +  #
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +
> ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf
> {
> +    <PcdsFixedAtBuild>
> +      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> +  }
> +!endif
> +
> +  Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInitDxe.inf{
> +    <LibraryClasses>
> +!if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +!endif
> +      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  }
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/Dptf.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PnpDxe.inf
> +
> +!if $(SEC_ENABLE) == TRUE
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/HeciDrv.inf {
> +!if $(SEC_DEBUG_INFO_ENABLE) == TRUE
> +    <BuildOptions>
> +      *_*_X64_CC_FLAGS      = /DSEC_DEBUG_INFO=1
> +!else
> +    <BuildOptions>
> +      *_*_X64_CC_FLAGS      = /DSEC_DEBUG_INFO=0
> +!endif
> +  }
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SeCPolicyInitDxe.inf
> +!endif
> +
> +!if $(FTPM_ENABLE) == TRUE
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/Tpm2DeviceSeCDxe.inf
> +  SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf
> +  SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf{
> +    <LibraryClasses>
> +
> NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
> +
> NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.in
> f
> +      PcdLib|MdePkg/Library\DxePcdLib/DxePcdLib.inf
> +
> Tpm2DeviceLib|Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2Devi
> ceLibSeC.inf
> +  }
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/FtpmSmm.inf
> +!endif
> +!if $(TPM_ENABLED) == TRUE
> +  SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +  }
> +
> +  SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +    <BuildOptions>
> +      #
> +      # specify GUID gEfiIfrNotInTPVPageGuid, this page will not
> +      # be showed in TPV page.
> +      #
> +      *_*_*_VFR_FLAGS   = -g e58809f8-fbc1-48e2-883a-a30fdc4b441e
> +  }
> +
> +  SecurityPkg/Tcg/TcgDxe/TcgDxe.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  }
> +  SecurityPkg/Tcg/TcgSmm/TcgSmm.inf
> +!endif
> +  #
> +  # EDK II Related Platform codes
> +  #
> +  $(PLATFORM_PACKAGE)/PlatformSmm/PlatformSmm.inf{
> +    <LibraryClasses>
> +    !if $(TARGET) != RELEASE
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +    !endif
> +          PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  }
> +  $(PLATFORM_PACKAGE)/PlatformInfoDxe/PlatformInfoDxe.inf
> +  $(PLATFORM_PACKAGE)/PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf
> +  $(PLATFORM_PACKAGE)/PlatformDxe/PlatformDxe.inf
> +
> +  $(PLATFORM_PACKAGE)/PciPlatform/PciPlatform.inf
> +  $(PLATFORM_PACKAGE)/SaveMemoryConfig/SaveMemoryConfig.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PlatformCpuPolicy.inf
> +  $(PLATFORM_PACKAGE)/PpmPolicy/PpmPolicy.inf
> +
> $(PLATFORM_PACKAGE)/SmramSaveInfoHandlerSmm/SmramSaveInfoHand
> lerSmm.inf
> +!if $(GOP_DRIVER_ENABLE) == TRUE
> +  $(PLATFORM_PACKAGE)/PlatformGopPolicy/PlatformGopPolicy.inf
> +
> +!endif
> +
> +
> +  #
> +  # SMM
> +  #
> +  MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
> +  MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
> +  UefiCpuPkg/CpuDxe/CpuDxe.inf
> +  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
> +  UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
> +  MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
> +  UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
> +
> $(PLATFORM_PACKAGE)/SmmSwDispatch2OnSmmSwDispatchThunk/SmmS
> wDispatch2OnSmmSwDispatchThunk.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/PowerManagement2.inf
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/DigitalThermalSensor.inf
> +
> +  #
> +  # ACPI
> +  #
> +
> MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutor
> Dxe.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
> +    <PcdsFixedAtBuild>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x27
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  }
> +
> +  $(PLATFORM_PACKAGE)/BootScriptSaveDxe/BootScriptSaveDxe.inf
> +
> IntelFrameworkModulePkg/Universal/Acpi/AcpiSupportDxe/AcpiSupportDx
> e.inf
> +
> Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTable
> s/PowerManagementAcpiTables.inf
> +
> +  $(PLATFORM_RC_PACKAGE)/AcpiTablesPCAT/AcpiTables.inf
> +
> +  $(PLATFORM_PACKAGE)/AcpiPlatform/AcpiPlatform.inf
> +
> +
> MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraph
> icsResourceTableDxe.inf
> +
> +  #
> +  # PCI
> +  #
> +  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
> +
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/ISPDxe.inf
> +
> +
> +#
> +# ISA
> +#
> +  $(PLATFORM_PACKAGE)/Wpce791/Wpce791.inf
> +  IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBusDxe.inf
> +  IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaIoDxe.inf
> +  IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf
> +  IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf
> +
> IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf
> +#
> +# SDIO
> +#
> +#
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/MmcHost.inf
> +#
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/MmcMediaDevice.inf
> +!if $(ACPI50_ENABLE) == TRUE
> +
> MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/Firmw
> arePerformanceDxe.inf {
> +    <LibraryClasses>
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +  }
> +
> MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/Firm
> warePerformanceSmm.inf {
> +    <LibraryClasses>
> +
> TimerLib|$(PLATFORM_PACKAGE)/Library/IntelPchAcpiTimerLib/IntelPchAc
> piTimerLib.inf
> +  }
> +!endif
> +
> +#
> +# IDE/SCSI/AHCI
> +#
> +  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
> +  IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBusDxe.inf
> +  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
> +  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
> +
> MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
> +  FatPkg/EnhancedFatDxe/Fat.inf
> +  ShellPkg/Application/Shell/Shell.inf {
> +    <LibraryClasses>
> +
> ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellComma
> ndLib.inf
> +
> NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2Comma
> ndsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1Comma
> ndsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3Comma
> ndsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1Com
> mandsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1Com
> mandsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1Com
> mandsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1
> CommandsLib.inf
> +
> HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingL
> ib.inf
> +      PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
> +
> BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfg
> CommandLib.inf
> +    <PcdsFixedAtBuild>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
> +      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> +      gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
> +  }
> +!if $(SATA_ENABLE) == TRUE
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SataController.inf
> +!endif
> +  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
> +!if $(SCSI_ENABLE) == TRUE
> +  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
> +  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
> +!endif
> +#
> +# Console
> +#
> +  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
> +  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
> +
> MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleD
> xe.inf
> +
> IntelFrameworkModulePkg/Universal/Console/VgaClassDxe/VgaClassDxe.in
> f
> +  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
> +  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
> +  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
> +  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
> +
> +  #
> +  # USB
> +  #
> +!if $(USB_ENABLE) == TRUE
> +  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
> +  MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
> +  MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
> +  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
> +  MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
> +  MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
> +  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
> +
> +!endif
> +
> +  #
> +  # SMBIOS
> +  #
> +  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
> +  $(PLATFORM_PACKAGE)/SmBiosMiscDxe/SmBiosMiscDxe.inf
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/SmbiosMemory.inf
> +  #
> +  # CPU/FW Microde
> +  #
> +  Vlv2SocBinPkg/Microcode/MicrocodeUpdates.inf {
> +    <BuildOptions>
> +      *_*_*_GENFW_FLAGS = -a 0x800 -p 0xFF
> +  }
> +
> +
> +
> +!if $(NETWORK_ENABLE) == TRUE
> +  !if $(NETWORK_ISCSI_ENABLE) == TRUE
> +    NetworkPkg/IScsiDxe/IScsiDxe.inf
> +  !endif
> +  !if $(NETWORK_VLAN_ENABLE) == TRUE
> +    MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf
> +  !endif
> +  !if $(CSM_ENABLE) == TRUE
> +    IntelFrameworkModulePkg/Csm/BiosThunk/Snp16Dxe/Snp16Dxe.inf
> +  !endif
> +!endif
> +
> +!if $(NETWORK_ENABLE) == TRUE
> +  #
> +  # UEFI network modules
> +  #
> +    MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
> +    MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf
> +
> +    MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
> +    MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
> +    MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
> +    MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
> +    MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
> +    NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
> +    NetworkPkg/TcpDxe/TcpDxe.inf
> +    MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
> +    !if $(NETWORK_IP6_ENABLE) == TRUE
> +      NetworkPkg/Ip6Dxe/Ip6Dxe.inf
> +      NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
> +      NetworkPkg/Udp6Dxe/Udp6Dxe.inf
> +      NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
> +    !endif
> +!endif
> +
> +!if $(CAPSULE_ENABLE) || $(MICOCODE_CAPSULE_ENABLE)
> +  MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxe.inf
> +  MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> +!endif
> +
> +!if $(CAPSULE_ENABLE)
> +  !include Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc
> +  !include Vlv2TbltDevicePkg/FmpGreenSampleDevice.dsc
> +  !include Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc
> +  !include Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc
> +!endif
> +
> +!if $(MICOCODE_CAPSULE_ENABLE)
> +
> IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDx
> e.inf {
> +    <LibraryClasses>
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.
> inf
> +      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +
> SerialPortLib|$(PLATFORM_PACKAGE)/Library/SerialPortLib/SerialPortLib.inf
> +  }
> +!endif
> +
> +[BuildOptions]
> +#
> +# Define Build Options both for EDK and EDKII drivers.
> +#
> +
> +#
> +# Define token for different Platform
> +#
> +!if $(MINNOW2_FSP_BUILD) == TRUE
> +  DEFINE MINNOW2_FSP_OPTION = /DMINNOW2_FSP_BUILD
> +!else
> +  DEFINE MINNOW2_FSP_OPTION =
> +!endif
> +
> +!if $(ENBDT_PF_BUILD) == TRUE
> +  DEFINE ENBDT_PF_ENABLE = /DENBDT_PF_ENABLE=1
> +!else
> +  DEFINE ENBDT_PF_ENABLE = /DENBDT_PF_ENABLE=0
> +!endif
> +
> +
> +!if $(CLKGEN_CONFIG_EXTRA_ENABLE) == TRUE
> +  DEFINE CLKGEN_CONFIG_EXTRA_BUILD_OPTION =
> /DCLKGEN_CONFIG_EXTRA=1
> +!else
> +  DEFINE CLKGEN_CONFIG_EXTRA_BUILD_OPTION =
> +!endif
> +
> +
> +
> +!if $(PCIESC_ENABLE) == TRUE
> +  DEFINE PCIESC_SUPPORT_BUILD_OPTION = /DPCIESC_SUPPORT=1
> +!else
> +  DEFINE PCIESC_SUPPORT_BUILD_OPTION =
> +!endif
> +!if $(SATA_ENABLE) == TRUE
> +  DEFINE SATA_SUPPORT_BUILD_OPTION = /DSATA_SUPPORT=1
> +!else
> +  DEFINE SATA_SUPPORT_BUILD_OPTION =
> +!endif
> +!if $(ENBDT_S3_SUPPORT) == TRUE
> +  DEFINE ENBDT_S3_SUPPORT_OPTIONS = /DNOCS_S3_SUPPORT
> +!else
> +  DEFINE ENBDT_S3_SUPPORT_OPTIONS =
> +!endif
> +
> +!if $(X64_CONFIG) == TRUE
> +  DEFINE X64_BUILD_ENABLE = /DX64_BUILD_ENABLE=1
> +!else
> +  DEFINE X64_BUILD_ENABLE =
> +!endif
> +
> +!if $(FTPM_ENABLE) == TRUE
> +  DEFINE DSC_FTPM_BUILD_OPTIONS = /DFTPM_ENABLE
> +!else
> +  DEFINE DSC_FTPM_BUILD_OPTIONS =
> +!endif
> +!if $(TPM_ENABLED) == TRUE
> +  DEFINE DSC_TPM_BUILD_OPTIONS = /DTPM_ENABLED
> +!else
> +  DEFINE DSC_TPM_BUILD_OPTIONS =
> +!endif
> +
> +
> +  DEFINE EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS =
> $(MINNOW2_FSP_OPTION) $(MINNOW2_BUILD_OPTION)
> $(ENBDT_PF_ENABLE) $(EXTERNAL_VGA_BUILD_OPTION)
> $(PCIE_ENUM_WA_BUILD_OPTION) $(X0_WA_ENABLE_BUILD_OPTION)
> $(A0_WA_ENABLE_BUILD_OPTION) $(MICROCODE_FREE_BUILD_OPTIONS)
> $(SIMICS_BUILD_OPTIONS) $(HYBRID_BUILD_OPTIONS)
> $(COMPACT_BUILD_OPTIONS) $(VP_BUILD_OPTIONS)
> $(SYSCTL_ID_BUILD_OPTION) $(CLKGEN_CONFIG_EXTRA_BUILD_OPTION)
> $(SYSCTL_X0_CONVERT_BOARD_OPTION) $(ENBDT_S3_SUPPORT_OPTIONS)
> $(SATA_SUPPORT_BUILD_OPTION) $(PCIESC_SUPPORT_BUILD_OPTION)
> $(DSC_FTPM_BUILD_OPTIONS) $(DSC_FTPM_ERROR_WR_BUILD_OPTIONS)
> $(DSC_TPM_BUILD_OPTIONS) $(DSC_BYTI_SECURE_BOOT_BUILD_OPTIONS)
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +  DEFINE PDB_BUILD_OPTION = /Zi
> +!endif
> +
> +!if $(SOURCE_DEBUG_ENABLE) == TRUE
> +  MSFT:*_*_X64_GENFW_FLAGS  = --keepexceptiontable
> +  GCC:*_*_X64_GENFW_FLAGS   = --keepexceptiontable
> +  INTEL:*_*_X64_GENFW_FLAGS = --keepexceptiontable
> +!if $(TARGET) == DEBUG
> +  DEFINE SOURCE_LEVEL_DEBUG_BUILD_OPTIONS = /Od /Oy-
> +!endif
> +!else
> +  DEFINE SOURCE_LEVEL_DEBUG_BUILD_OPTIONS =
> +
> +!endif
> +
> +#
> +# Force PE/COFF sections to be aligned at 4KB boundaries to support page
> level
> +# protection of DXE_RUNTIME_DRIVER modules
> +#
> +[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
> +  MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
> +  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
> +
> +#
> +# Force PE/COFF sections to be aligned at 4KB boundaries to support page
> level
> +# protection of DXE_SMM_DRIVER/SMM_CORE modules
> +#
> +[BuildOptions.common.EDKII.DXE_SMM_DRIVER,
> BuildOptions.common.EDKII.SMM_CORE]
> +  MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
> +  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
> +
> +[BuildOptions.Common.EDK]
> +
> +#
> +# Define token for different Platform
> +#
> +!if $(ENBDT_PF_BUILD) == TRUE
> +  DEFINE ENBDT_PF_ENABLE = /DENBDT_PF_ENABLE=1
> +!else
> +  DEFINE ENBDT_PF_ENABLE = /DENBDT_PF_ENABLE=0
> +!endif
> +
> +!if $(PERFORMANCE_ENABLE) == TRUE
> +  RELEASE_*_*_DLINK_FLAGS = /DEBUG
> +!endif
> +
> +!if $(S3_ENABLE) == TRUE
> +  DEFINE DSC_S3_BUILD_OPTIONS = /DEFI_S3_RESUME
> +!else
> +  DEFINE DSC_S3_BUILD_OPTIONS =
> +!endif
> +
> +!if $(ENBDT_S3_SUPPORT) == TRUE
> +  DEFINE ENBDT_S3_SUPPORT_OPTIONS = /DNOCS_S3_SUPPORT
> +!else
> +  DEFINE ENBDT_S3_SUPPORT_OPTIONS =
> +!endif
> +
> +!if $(X64_CONFIG) == TRUE
> +  DEFINE X64_BUILD_ENABLE = /DX64_BUILD_ENABLE=1
> +!else
> +  DEFINE X64_BUILD_ENABLE =
> +!endif
> +
> +
> +  DEFINE EDK_GLUE_LIB_DEBUG  =
> +  DEFINE DEBUG_BUILD_OPTIONS = /D EFI_DEBUG /D DEBUG_MODE=1
> /GL- $(EDK_GLUE_LIB_DEBUG)
> /DEDKII_GLUE_DebugPrintErrorLevel=(EFI_D_ERROR)
> +  DEFINE EDK_DSC_FEATURE_BUILD_OPTIONS = $(DSC_S3_BUILD_OPTIONS)
> $(DSC_ACPI_BUILD_OPTIONS) $(DSC_SEC_BUILD_OPTIONS)
> $(DSC_FTPM_BUILD_OPTIONS) $(DSC_FTPM_ERROR_WR_BUILD_OPTIONS)
> $(DSC_TPM_BUILD_OPTIONS) $(SOFTSDV_BUILD_OPTIONS)
> $(SIMICS_BUILD_OPTIONS) $(HYBRID_BUILD_OPTIONS)
> $(COMPACT_BUILD_OPTIONS) $(VP_BUILD_OPTIONS)
> $(QT_BUILD_OPTIONS) $(DSC_BYTI_SECURE_BOOT_BUILD_OPTIONS)
> /D$(PROJECT_SC_CHIPSET)
> +
> +  DEFINE EDK_DSC_OTHER_BUILD_OPTIONS =
> $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS) $(SV_BUILD_OPTIONS)
> $(INTEL_FASTBOOT_BUILD_OPTION)
> +  DEFINE EDK_DSC_GLOBAL_BUILD_OPTIONS = $(ENBDT_PF_ENABLE)
> $(EDK_DSC_FEATURE_BUILD_OPTIONS)
> $(EDK_DSC_OTHER_BUILD_OPTIONS) /D
> EFI_SPECIFICATION_VERSION=0x00020000  /D
> PI_SPECIFICATION_VERSION=0x00000009  /D
> TIANO_RELEASE_VERSION=0x00080006 /D
> SUPPORT_DEPRECATED_PCI_CFG_PPI /D CSM_SMMENTRY_PORT8DATA8 /D
> EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE) /D
> MAX_VARIABLE_SIZE=0x2000 /D EFI_FIRMWARE_VENDOR="L/"INTEL/"" /D
> EFI_BUILD_VERSION="L/"EDKII/"" /DEFI_PEI_REPORT_STATUS_CODE_ON
> $(ENBDT_S3_SUPPORT_OPTIONS)
> +
> +  *_*_IA32_ASM_FLAGS         = /DEFI32 /D
> EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h
> /DNOCS_S3_SUPPORT
> +  DEBUG_*_IA32_CC_FLAGS      = /D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_IA32_CC_FLAGS    = /D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  DEBUG_*_IA32_VFRPP_FLAGS   = /D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_IA32_VFRPP_FLAGS = /D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  DEBUG_*_IA32_APP_FLAGS     = /D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_IA32_APP_FLAGS   = /D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  DEBUG_*_IA32_PP_FLAGS      = /D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_IA32_PP_FLAGS    = /D EFI32
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  *_*_IA32_ASLPP_FLAGS       = /D
> EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
> +  *_*_IA32_ASLCC_FLAGS       = /D
> EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
> +  *_*_IA32_ASM16_FLAGS       = /D
> EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h
> +
> +  *_*_X64_ASM_FLAGS          = /DEFIX64 /D
> EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h
> /DNOCS_S3_SUPPORT
> +  DEBUG_*_X64_CC_FLAGS       = /D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_X64_CC_FLAGS     = /D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  DEBUG_*_X64_VFRPP_FLAGS    = /D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_X64_VFRPP_FLAGS  = /D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  DEBUG_*_X64_APP_FLAGS      = /D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_X64_APP_FLAGS    = /D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  DEBUG_*_X64_PP_FLAGS       = /D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS) $(DEBUG_BUILD_OPTIONS)
> +  RELEASE_*_X64_PP_FLAGS     = /D EFIX64
> $(EDK_DSC_GLOBAL_BUILD_OPTIONS)
> +  *_*_X64_ASLPP_FLAGS        = /D
> EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
> +  *_*_X64_ASLCC_FLAGS        = /D
> EDKII_GLUE_PciExpressBaseAddress=0x$(PLATFORM_PCIEXPRESS_BASE)
> +  *_*_X64_ASM16_FLAGS        = /D
> EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h
> + # *_*_*_BUILD_FLAGS = -s
> +  *_*_*_VFR_FLAGS   = -c
> +  *_*_*_BUILD_FLAGS = -c
> +
> +[BuildOptions.Common.EDKII]
> +  *_*_IA32_ASM_FLAGS     = $(VP_BUILD_OPTIONS) /D
> EDKII_GLUE_PciExpressBaseAddress=$(PLATFORM_PCIEXPRESS_BASE)h
> /DNOCS_S3_SUPPORT
> +
> +  *_*_IA32_CC_FLAGS      = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +  *_*_IA32_VFRPP_FLAGS   = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +  *_*_IA32_APP_FLAGS     = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +  *_*_IA32_PP_FLAGS      = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +  *_*_IA32_ASLPP_FLAGS   = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +
> +  *_*_X64_CC_FLAGS       = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> $(SOURCE_LEVEL_DEBUG_BUILD_OPTIONS)
> +  *_*_X64_VFRPP_FLAGS    = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +  *_*_X64_APP_FLAGS      = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +  *_*_X64_PP_FLAGS       = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +  *_*_X64_ASLPP_FLAGS    = $(EDK_EDKII_DSC_FEATURE_BUILD_OPTIONS)
> +
> +
> +[Components.X64]
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/I2cBus.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
> +  }
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/I2cHost.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043
> +  }
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/I2cPortA0Pio.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x00000043
> +  }
> +
> +
> $(PLATFORM_BINARY_PACKAGE)/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_
> ARCHITECTURE)/I2cMmioDeviceDxe.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x00000043
> +  }
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Boot.vfi
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Boot.vfi
> new file mode 100644
> index 0000000000..9c155e5328
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Boot.vfi
> @@ -0,0 +1,72 @@
> +//
> +//
> +// Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +//
> 
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +//
> 
> +//
> +//
> +// Module Name:
> +//
> +//   Boot.vfi
> +//
> +// Abstract:
> +//
> +//   Driver Setup formset.
> +//
> +// Revision History:
> +//
> +// --*/
> +
> +
> +form formid = BOOT_CONFIGURATION_FORM_ID,
> +
> +  title  = STRING_TOKEN(STR_BOOT_CONFIGURATION_TITLE);
> +
> +
> +  oneof varid  = Setup.FastBoot,
> +    prompt   = STRING_TOKEN(STR_FAST_BOOT_PROMPT),
> +    help     = STRING_TOKEN(STR_FAST_BOOT_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags= DEFAULT |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE),  value=1, flags=
> MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +
> +  oneof varid  = Setup.SecureBoot,
> +    prompt   = STRING_TOKEN(STR_SECURITY_BOOT_PROMPT),
> +    help     = STRING_TOKEN(STR_SECURITY_BOOT_HELP),
> +        option text = STRING_TOKEN(STR_DISABLE), value=0, flags= DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +        option text = STRING_TOKEN(STR_ENABLE),  value=1, flags=
> RESET_REQUIRED;
> +  endoneof;
> +
> +
> +  oneof varid  = Setup.QuietBoot,
> +    prompt   = STRING_TOKEN(STR_QUIETBOOT_PROMPT),
> +    help     = STRING_TOKEN(STR_QUIETBOOT_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE),  value=1, flags=0 |
> RESET_REQUIRED;
> +  endoneof;
> +
> +
> +
> +  oneof   varid   = Setup.LogBootTime,
> +      prompt      = STRING_TOKEN(STR_LOG_BOOT_TIME_PROMPT),
> +      help        = STRING_TOKEN(STR_LOG_BOOT_TIME_HELP),
> +      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = 0 |
> RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_ENABLE),  value = 1, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +
> +  suppressif ideqval Setup.LogBootTime == 0x00;
> +    text
> +      help   = STRING_TOKEN(STR_NULL_STRING),
> +      text   = STRING_TOKEN(STR_LOG_BOOT_TIME_RECORD),
> +      text   = STRING_TOKEN(STR_LOG_BOOT_TIME_VALUE),
> +      flags  = 0,
> +      key    = 0;
> +  endif;
> +
> +endform;
> +
> +
> +
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Configuration.h
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Configuration.h
> new file mode 100644
> index 0000000000..7d7920c244
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Configuration.h
> @@ -0,0 +1,56 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +    Configuration.h
> +
> +Abstract:
> +
> +    Driver configuration include file
> +
> +Revision History:
> +  ------------------------------------------------------------------------------
> +  Rev   Date<MM/DD/YYYY>    Name    Description
> +  ------------------------------------------------------------------------------
> +
> +  ------------------------------------------------------------------------------
> +--*/
> +
> +#ifndef _CONFIGURATION_H
> +#define _CONFIGURATION_H
> +
> +//
> +// System Setup Page. Do not have to be sequential but have to be unique
> +//
> +#define ROOT_FORM_ID                        1
> +#define ROOT_MAIN_FORM_ID                   2
> +#define CPU_CONFIGURATION_FORM_ID           3
> +#define CPU_PWR_CONFIGURATION_FORM_ID       4
> +#define BOOT_CONFIGURATION_FORM_ID          5
> +#define IGD_FORM_ID                         6
> +#define SECURITY_CONFIGURATION_FORM_ID      7
> +#define SOUTH_CLUSTER_FORM_ID               8
> +#define DPTF_FORM_ID                        9
> +#define PLATFORM_INFORMATION_FORM_ID        10
> +#define DRIVE_CONFIGURATION_ID              11
> +#define SENSOR_CONFIGURATION_ID             12
> +#define LPSS_CONFIGURATION_ID               13
> +#define UNCORE_FORM_ID                      14
> +#define TPM_FORM_ID                         15
> +#define THERMAL_FORM_ID                     16
> +#define PASSWORD_SETTING_ID                 17
> +#define LAN_OPTIONS_FORM_ID                 18
> +#define AZALIA_OPTIONS_FORM_ID              19
> +#define MISC_OPTIONS_FORM_ID                20
> +#define USB_OPTIONS_FORM_ID                 21
> +#define PCIE_DEVICE_OPTIONS_FORM_ID         22
> +#define SYSTEM_COMPONENT_FORM_ID            23
> +#define DEBUG_CONFIGURATION_FORM_ID         24
> +#endif // #ifndef _CONFIGURATION_H
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/DebugConfig.vfi
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/DebugConfig.vfi
> new file mode 100644
> index 0000000000..eea41a5202
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/DebugConfig.vfi
> @@ -0,0 +1,118 @@
> +//
> +//
> +// Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +//
> 
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +//
> 
> +//
> +//
> +//
> +// Module Name:
> +//
> +//   DebugConfiguration.vfi
> +//
> +// Abstract:
> +//
> +//   Debug Configuration formset.
> +//
> +
> +
> +// --*/
> +
> +form formid = DEBUG_CONFIGURATION_FORM_ID,
> +  title    = STRING_TOKEN(STR_DEBUG_CONFIGURATION_TITLE);
> +
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +  subtitle text = STRING_TOKEN(STR_ACPIMEMDBG_STRING);
> +
> +  //ACPI Memory Debug Switch
> +    oneof varid   = Setup.ACPIMemDbg,
> +      prompt      = STRING_TOKEN (STR_ACPIMEMDBG_SWTICH),
> +      help        = STRING_TOKEN (STR_ACPIMEMDBG_SWTICH_HELP),
> +      option text = STRING_TOKEN (STR_ENABLE),  value = 1, flags =  DEFAULT
> | MANUFACTURING | RESET_REQUIRED;
> +      option text = STRING_TOKEN (STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +    endoneof;
> +
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +
> +    oneof varid   = Setup.ExISupport,
> +      prompt      = STRING_TOKEN(STR_EXISUPPORT_PROMPT),
> +      help        = STRING_TOKEN(STR_EXISUPPORT_HELP),
> +      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags =
> RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT |
> RESET_REQUIRED;
> +    endoneof;
> + subtitle text = STRING_TOKEN(STR_WITT_CONFIGURATION_TITLE);
> +
> +  oneof varid   = Setup.WittEnable,
> +    prompt      = STRING_TOKEN(STR_WITT_PROMPT),
> +    help        = STRING_TOKEN(STR_WITT_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE),  value = 1, flags =
> RESET_REQUIRED;
> +  endoneof;
> +
> +  oneof varid   = Setup.UtsEnable,
> +    prompt      = STRING_TOKEN(STR_UTS_PROMPT),
> +    help        = STRING_TOKEN(STR_UTS_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE),  value = 1, flags =
> RESET_REQUIRED;
> +  endoneof;
> +
> +  //
> +  //Lakemore Settings
> +  //
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +  subtitle text = STRING_TOKEN(STR_LM_INFORMATION_TITLE);
> +
> +    grayoutif ideqval Setup.PunitBIOSConfig == 0x1;
> +      oneof varid   = Setup.LmMemSize,
> +        prompt      = STRING_TOKEN (STR_LM_MEMORY_PROMPT),
> +        help        = STRING_TOKEN (STR_LM_MEMORY_HELP),
> +        option text = STRING_TOKEN (STR_LM_MEMORY_16MB),  value =
> 16384, flags = RESET_REQUIRED;
> +        option text = STRING_TOKEN (STR_LM_MEMORY_8MB),   value = 8192,
> flags = RESET_REQUIRED;
> +        option text = STRING_TOKEN (STR_LM_MEMORY_1MB),   value = 1024,
> flags = RESET_REQUIRED;
> +        option text = STRING_TOKEN (STR_LM_MEMORY_128KB), value = 128,
> flags = RESET_REQUIRED;
> +        option text = STRING_TOKEN (STR_LM_MEMORY_0MB),   value = 0,
> flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
> +      endoneof;
> +    endif;
> +
> +    oneof varid   = Setup.PunitBIOSConfig,
> +      prompt      = STRING_TOKEN (STR_PUINT_BIOS_CONFIG_DISPLAY),
> +      help        = STRING_TOKEN (STR_PUINT_BIOS_CONFIG_DISPLAY_HELP),
> +      option text = STRING_TOKEN (STR_PUINT_BIOS_PDM),         value = 3,
> flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
> +      option text = STRING_TOKEN (STR_PUINT_BIOS_PERFORMANCE), value
> = 2,  flags = RESET_REQUIRED;
> +      option text = STRING_TOKEN (STR_PUINT_BIOS_POWERSAVE),   value =
> 1,  flags = RESET_REQUIRED;
> +	  option text = STRING_TOKEN (STR_PUINT_BIOS_RESERVED),    value
> = 0,  flags = RESET_REQUIRED;
> +    endoneof;
> +
> +    suppressif NOT ideqval Setup.PunitBIOSConfig == 0x3;
> +      oneof varid   = Setup.PDMConfig,
> +        prompt      = STRING_TOKEN (STR_PDM_OUTPUT_CONFIG_SWTICH),
> +        help        = STRING_TOKEN
> (STR_PDM_OUTPUT_CONFIG_SWTICH_HELP),
> +        option text = STRING_TOKEN (STR_DISABLE), value = 0, flags = DEFAULT
> | MANUFACTURING | RESET_REQUIRED;
> +        option text = STRING_TOKEN (STR_PDM_OUTPUT_MEM), value = 1,
> flags = RESET_REQUIRED;
> +        option text = STRING_TOKEN (STR_PDM_OUTPUT_IO),  value = 2, flags
> = RESET_REQUIRED;
> +      endoneof;
> +    endif;
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +  oneof varid   = Setup.ENDBG2,
> +    prompt      = STRING_TOKEN (STR_ENABLE_DBG2),
> +    help        = STRING_TOKEN (STR_ENABLE_DBG2_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE),  value = 1, flags = DEFAULT |
> RESET_REQUIRED;
> +  endoneof;
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +  oneof varid = Setup.DisableCodec262,
> +  prompt   = STRING_TOKEN(STR_CODEC262_DISABLED_PROMPT),
> +  help     = STRING_TOKEN(STR_CODEC262_DISABLED_HELP),
> +  option text = STRING_TOKEN(STR_YES), value = 1, flags = RESET_REQUIRED;
> +  option text = STRING_TOKEN(STR_NO), value = 0, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +
> +endform;
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/FwVersionStrings.un
> i
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/FwVersionStrings.un
> i
> new file mode 100644
> index 0000000000..175ceb1a16
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/FwVersionStrings.un
> i
> @@ -0,0 +1,40 @@
> +//
> +// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//
> +// Module Name:
> +//
> +//   InventoryStrings.uni
> +//
> +// Abstract:
> +//
> +//   String definitions for Inventory file.
> +//
> +// Revision History:
> +//
> +// --*/
> +
> +
> +/=#
> +
> +#langdef en-US "English"
> +#langdef fr-FR "Francais"
> +
> +#string STR_SOC_STRING                                  #language en-US "VLV SOC"
> +#string STR_SOC_VALUE                                   #language en-US "N/A"
> +#string STR_MRC_VERSION_STRING                          #language en-US "MRC
> Version"
> +#string STR_MRC_VERSION_VALUE                           #language en-US "N/A"
> +#string STR_PUNIT_FW_STRING                             #language en-US "PUNIT FW
> Patch"
> +#string STR_PUNIT_FW_VALUE                              #language en-US "N/A"
> +#string STR_ULPMC_FW_STRING                             #language en-US "ULPMC
> FW"
> +#string STR_ULPMC_FW_VALUE                              #language en-US "N/A"
> +#string STR_KSC_FW_STRING                               #language en-US "KSC FW"
> +#string STR_KSC_FW_VALUE                                #language en-US "N/A"
> +#string STR_SEC_FW_STRING                               #language en-US "TXE FW"
> +#string STR_SEC_FW_VALUE                                #language en-US "N/A"
> +#string STR_GOP_STRING                                  #language en-US "GOP"
> +#string STR_GOP_VALUE                                   #language en-US "N/A"
> +#string STR_PMC_FW_STRING                               #language en-US "PMC FW
> Patch"
> +#string STR_PMC_FW_VALUE                                #language en-US "N/A"
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Main.vfi
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Main.vfi
> new file mode 100644
> index 0000000000..6093262e3f
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Main.vfi
> @@ -0,0 +1,331 @@
> +//
> +//
> +// Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +//
> 
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +//
> 
> +//
> +//
> +//
> +// Module Name:
> +//
> +//   Main.vfi
> +//
> +// Abstract:
> +//
> +//   Driver Setup formset.
> +//
> +// Revision History:
> +//
> +// --*/
> +
> +form formid = ROOT_MAIN_FORM_ID,
> +
> +  title    = STRING_TOKEN(STR_MAIN_TITLE);
> +
> +  subtitle text = STRING_TOKEN(STR_BIOS_INFORMATION_TITLE);
> +
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_IFWI_VERSION_STRING),
> +    text   = STRING_TOKEN(STR_IFWI_VERSION_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_BIOS_VERSION_STRING),
> +    text   = STRING_TOKEN(STR_BIOS_VERSION_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_BIOS_VENDOR_STRING),
> +    text   = STRING_TOKEN(STR_BIOS_VENDOR_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_CORE_VERSION_STRING),
> +    text   = STRING_TOKEN(STR_CORE_VERSION_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_BIOS_BUILD_TIME_STRING),
> +    text   = STRING_TOKEN(STR_BIOS_BUILD_TIME_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +
> +  subtitle text = STRING_TOKEN(STR_PROCESSOR_INFO_STRING);
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_PROCESSOR_VERSION_STRING),
> +    text   = STRING_TOKEN(STR_PROCESSOR_VERSION_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_PROCESSOR_SKU_STRING),
> +    text   = STRING_TOKEN(STR_PROCESSOR_SKU_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_PROCESSOR_SPEED_STRING),
> +    text   = STRING_TOKEN(STR_PROCESSOR_SPEED_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_PROCESSOR_ID_STRING),
> +    text   = STRING_TOKEN(STR_PROCESSOR_ID_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_PROCESSOR_MICROCODE_STRING),
> +    text   = STRING_TOKEN(STR_PROCESSOR_MICROCODE_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_PROCESSOR_CORE_STRING),
> +    text   = STRING_TOKEN(STR_PROCESSOR_CORE_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_EM64T_CAPABILITY_STRING),
> +    text   = STRING_TOKEN(STR_EM64T_CAPABILITY_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +
> +  goto PLATFORM_INFORMATION_FORM_ID,
> +    prompt = STRING_TOKEN(STR_PLATFORM_INFORMATION_TITLE),
> +    help   = STRING_TOKEN(STR_PLATFORM_INFORMATION_HELP);
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +  //
> +  // Date and Time section
> +  //
> +  date    year varid  = Date.Year,    // Note that it is a member of NULL, so the
> RTC will be the system resource to retrieve and save from
> +    prompt      = STRING_TOKEN(STR_DATE_PROMPT),
> +    help        = STRING_TOKEN(STR_DATE_YEAR_HELP),
> +    minimum     = 2003,
> +    maximum     = 2100,
> +    step        = 1,
> +    default     = 2003,
> +
> +    month varid = Date.Month,    // Note that it is a member of NULL, so the
> RTC will be the system resource to retrieve and save from
> +    prompt      = STRING_TOKEN(STR_DATE_PROMPT),
> +    help        = STRING_TOKEN(STR_DATE_MONTH_HELP),
> +    minimum     = 1,
> +    maximum     = 12,
> +    step        = 1,
> +    default     = 1,
> +
> +    day varid   = Date.Day,          // Note that it is a member of NULL, so the RTC
> will be the system resource to retrieve and save from
> +    prompt      = STRING_TOKEN(STR_DATE_PROMPT),
> +    help        = STRING_TOKEN(STR_DATE_DAY_HELP),
> +    minimum     = 1,
> +    maximum     = 31,
> +    step        = 0x1,
> +    default     = 1,
> +
> +    // If the day is 31 AND months is any of the following 2, 4, 6, 9, 11
> +    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),
> +      ideqval Date.Day == 31
> +      AND
> +      ideqvallist Date.Month == 2 4 6 9 11
> +    endif
> +
> +    // If the day is 30 AND month is 2
> +    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),
> +      ideqval Date.Day == 30
> +      AND
> +      ideqval Date.Month == 2
> +    endif
> +
> +    // If the day is 29 AND month is 2 AND it year is NOT a leapyear
> +    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),
> +      ideqval Date.Day == 0x29
> +      AND
> +      ideqval Date.Month == 2
> +      AND
> +      NOT
> +      ideqvallist Date.Year == 2004 2008 2012 2016 2020 2024 2028 2032 2036
> 2040 2044 2048 2052 2056 2060 2064 2068 2072 2076 2080 2084 2088 2092 2096
> +    endif
> +
> +  enddate;
> +
> +  time    hour varid  = Time.Hours,         // Note that it is a member of NULL, so
> the RTC will be the system resource to retrieve and save from
> +    prompt      = STRING_TOKEN(STR_TIME_PROMPT),
> +    help        = STRING_TOKEN(STR_TIME_HOUR_HELP),
> +    minimum     = 0,
> +    maximum     = 23,
> +    step        = 1,
> +    default     = 0,
> +
> +    minute varid  = Time.Minutes,       // Note that it is a member of NULL, so
> the RTC will be the system resource to retrieve and save from
> +    prompt        = STRING_TOKEN(STR_TIME_PROMPT),
> +    help          = STRING_TOKEN(STR_TIME_MINUTE_HELP),
> +    minimum       = 0,
> +    maximum       = 59,
> +    step          = 1,
> +    default       = 0,
> +
> +    second varid  = Time.Seconds,       // Note that it is a member of NULL, so
> the RTC will be the system resource to retrieve and save from
> +    prompt        = STRING_TOKEN(STR_TIME_PROMPT),
> +    help          = STRING_TOKEN(STR_TIME_SECOND_HELP),
> +    minimum       = 0,
> +    maximum       = 59,
> +    step          = 1,
> +    default       = 0,
> +  endtime;
> +
> +endform;
> +
> +form formid = PLATFORM_INFORMATION_FORM_ID,
> +
> +  title    = STRING_TOKEN(STR_PLATFORM_INFORMATION_TITLE);
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +
> +  subtitle text = STRING_TOKEN(STR_PLATFORM_FIRMWARE_STRING);
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_SOC_STRING),
> +    text   = STRING_TOKEN(STR_SOC_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_MRC_VERSION_STRING),
> +    text   = STRING_TOKEN(STR_MRC_VERSION_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_PUNIT_FW_STRING),
> +    text   = STRING_TOKEN(STR_PUNIT_FW_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_PMC_FW_STRING),
> +    text   = STRING_TOKEN(STR_PMC_FW_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_KSC_FW_STRING),
> +    text   = STRING_TOKEN(STR_KSC_FW_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_SEC_VERSION_STRING),
> +    text   = STRING_TOKEN(STR_SEC_VERSION_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  suppressif ideqval Setup.GOPEnable == 0;
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_GOP_STRING),
> +    text   = STRING_TOKEN(STR_GOP_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +  endif;
> +
> +  suppressif ideqval Setup.GOPEnable == 1;
> +  text
> +    help   = STRING_TOKEN(STR_CHIP_IGD_VBIOS_REV_HELP),
> +    text   = STRING_TOKEN(STR_CHIP_IGD_VBIOS_REV_NAME),
> +    text   = STRING_TOKEN(STR_CHIP_IGD_VBIOS_REV_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +  endif;
> +
> +  text
> +    help   = STRING_TOKEN(STR_CPU_FLAVOR_HELP),
> +    text   = STRING_TOKEN(STR_CPU_FLAVOR_NAME),
> +    text   = STRING_TOKEN(STR_CPU_FLAVOR_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  text
> +    help   = STRING_TOKEN(STR_BOARD_ID_HELP),
> +    text   = STRING_TOKEN(STR_BOARD_ID_NAME),
> +    text   = STRING_TOKEN(STR_BOARD_ID_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  text
> +    help   = STRING_TOKEN(STR_FAB_ID_HELP),
> +    text   = STRING_TOKEN(STR_FAB_ID_STRING),
> +    text   = STRING_TOKEN(STR_FAB_ID_VALUE),
> +    flags  = 0,
> +    key = 0;
> +
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +
> +  subtitle text = STRING_TOKEN(STR_MEMORY_INFORMATION_STRING);
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_TOTAL_MEMORY_SIZE_PROMPT),
> +    text   = STRING_TOKEN(STR_TOTAL_MEMORY_SIZE_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_SYSTEM_MEMORY_SPEED_STRING),
> +    text   = STRING_TOKEN(STR_SYSTEM_MEMORY_SPEED_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_PROCESSOR_L1_DATA_CACHE_STRING),
> +    text   = STRING_TOKEN(STR_PROCESSOR_L1_DATA_CACHE_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_PROCESSOR_L1_INSTR_CACHE_STRING),
> +    text   = STRING_TOKEN(STR_PROCESSOR_L1_INSTR_CACHE_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_PROCESSOR_L2_CACHE_STRING),
> +    text   = STRING_TOKEN(STR_PROCESSOR_L2_CACHE_VALUE),
> +    flags  = 0,
> +    key    = 0;
> +
> +endform;
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.c
> new file mode 100644
> index 0000000000..0bfa3e7cf4
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.c
> @@ -0,0 +1,929 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +**/
> +
> +#include "PlatformSetupDxe.h"
> +#include "Guid/SetupVariable.h"
> +#include <Protocol/FormBrowserEx2.h>
> +
> +
> +#define EFI_CALLBACK_INFO_SIGNATURE SIGNATURE_32 ('C', 'l', 'b', 'k')
> +#define EFI_CALLBACK_INFO_FROM_THIS(a)  CR (a, EFI_CALLBACK_INFO,
> ConfigAccess, EFI_CALLBACK_INFO_SIGNATURE)
> +
> +typedef struct {
> +  UINTN                           Signature;
> +  EFI_HANDLE                      DriverHandle;
> +  EFI_HII_HANDLE                  RegisteredHandle;
> +  SYSTEM_CONFIGURATION            FakeNvData;
> +  SYSTEM_CONFIGURATION            BackupNvData;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +  EFI_HII_CONFIG_ACCESS_PROTOCOL  ConfigAccess;
> +} EFI_CALLBACK_INFO;
> +
> +#pragma pack(1)
> +
> +//
> +// HII specific Vendor Device Path definition.
> +//
> +typedef struct {
> +  VENDOR_DEVICE_PATH             VendorDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL       End;
> +} HII_VENDOR_DEVICE_PATH;
> +
> +#pragma pack()
> +
> +//
> +// uni string and Vfr Binary data.
> +//
> +extern UINT8  VfrBin[];
> +extern UINT8  PlatformSetupDxeStrings[];
> +
> +EFI_HANDLE            mImageHandle;
> +
> +//
> +// module global data
> +//
> +#define EFI_NORMAL_SETUP_GUID \
> +  { 0xec87d643, 0xeba4, 0x4bb5, 0xa1, 0xe5, 0x3f, 0x3e, 0x36, 0xb2, 0xd,
> 0xa9 }
> +
> +EFI_GUID                     mNormalSetupGuid = EFI_NORMAL_SETUP_GUID;
> +
> +EFI_GUID                     mSystemConfigGuid =
> SYSTEM_CONFIGURATION_GUID;
> +CHAR16                       mVariableName[] = L"Setup";
> +CHAR16                       mSetupName[] = L"Setup";
> +EFI_CALLBACK_INFO           *mCallbackInfo;
> +BOOLEAN                      GlobalReset=FALSE;
> +
> +HII_VENDOR_DEVICE_PATH  mHiiVendorDevicePath = {
> +  {
> +    {
> +      HARDWARE_DEVICE_PATH,
> +      HW_VENDOR_DP,
> +      {
> +        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
> +        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
> +      }
> +    },
> +    EFI_CALLER_ID_GUID
> +  },
> +  {
> +    END_DEVICE_PATH_TYPE,
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +    {
> +      (UINT8) (END_DEVICE_PATH_LENGTH),
> +      (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
> +    }
> +  }
> +};
> +
> +/**
> +  This function allows a caller to extract the current configuration for one
> +  or more named elements from the target driver.
> +
> +  @param  This         Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +  @param  Request      A null-terminated Unicode string in <ConfigRequest>
> format.
> +  @param  Progress     On return, points to a character in the Request string.
> +                       Points to the string's null terminator if request was successful.
> +                       Points to the most recent '&' before the first failing name/value
> +                       pair (or the beginning of the string if the failure is in the
> +                       first name/value pair) if the request was not successful.
> +  @param  Results      A null-terminated Unicode string in <ConfigAltResp>
> format which
> +                       has all values filled in for the names in the Request string.
> +                       String to be allocated by the called function.
> +
> +  @retval EFI_SUCCESS            The Results is filled with the requested values.
> +  @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the
> results.
> +  @retval EFI_INVALID_PARAMETER  Request is NULL, illegal syntax, or
> unknown name.
> +  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in
> this driver.
> +
> +**/
> +
> +VOID
> +CheckSystemConfigLoad(SYSTEM_CONFIGURATION *SystemConfigPtr);
> +
> +VOID
> +CheckSystemConfigSave(SYSTEM_CONFIGURATION *SystemConfigPtr);
> +
> +VOID
> +ConfirmSecureBootTest();
> +
> +VOID
> +LoadLpssDefaultValues (
> +  IN EFI_CALLBACK_INFO                       *Private
> +  )
> +{
> +  //
> +  // Load LPSS and SCC default configurations for Android
> +  //
> +  Private->FakeNvData.LpsseMMCEnabled            = FALSE;
> +  Private->FakeNvData.LpssSdioEnabled            = TRUE;
> +  Private->FakeNvData.LpssSdcardEnabled          = TRUE;
> +  Private->FakeNvData.LpssSdCardSDR25Enabled     = FALSE;
> +  Private->FakeNvData.LpssSdCardDDR50Enabled     = TRUE;
> +  Private->FakeNvData.LpssMipiHsi                = FALSE;
> +  Private->FakeNvData.LpsseMMC45Enabled          = TRUE;
> +  Private->FakeNvData.LpsseMMC45DDR50Enabled     = TRUE;
> +  Private->FakeNvData.LpsseMMC45HS200Enabled     = FALSE;
> +  Private->FakeNvData.LpsseMMC45RetuneTimerValue = 8;
> +  Private->FakeNvData.eMMCBootMode               = 1;     // Auto Detect
> +
> +  Private->FakeNvData.GOPEnable = TRUE;
> +  Private->FakeNvData.SecureBoot = TRUE;
> +  Private->FakeNvData.UsbAutoMode = TRUE;
> +  Private->FakeNvData.UsbXhciSupport = TRUE;
> +  Private->FakeNvData.PchUsb30Mode = TRUE;
> +  Private->FakeNvData.LegacyUSBBooting = FALSE;
> +  Private->FakeNvData.PchUsb20 = FALSE;
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +SystemConfigExtractConfig (
> +  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
> +  IN  CONST EFI_STRING                       Request,
> +  OUT EFI_STRING                             *Progress,
> +  OUT EFI_STRING                             *Results
> +  )
> +{
> +  EFI_STATUS                       Status;
> +  EFI_CALLBACK_INFO                *Private;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL  *HiiConfigRouting;
> +  EFI_STRING                       ConfigRequestHdr;
> +  EFI_STRING                       ConfigRequest;
> +  BOOLEAN                          AllocatedRequest;
> +  UINTN                            Size;
> +  UINTN                            BufferSize;
> +  VOID                             *SystemConfigPtr;
> +
> +
> +  if (Progress == NULL || Results == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *Progress = Request;
> +  if ((Request != NULL) && !HiiIsConfigHdrMatch (Request,
> &mSystemConfigGuid, mVariableName)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  ConfigRequestHdr = NULL;
> +  ConfigRequest    = NULL;
> +  Size             = 0;
> +  AllocatedRequest = FALSE;
> +
> +  Private          = EFI_CALLBACK_INFO_FROM_THIS (This);
> +
> +  SetupInfo();
> +
> +  HiiConfigRouting = Private->HiiConfigRouting;
> +  ConfigRequest = Request;
> +  if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
> +    //
> +    // Request has no request element, construct full request string.
> +    // Allocate and fill a buffer large enough to hold the <ConfigHdr>
> template
> +    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW"
> followed by a Null-terminator
> +    //
> +    ConfigRequestHdr = HiiConstructConfigHdr (&mSystemConfigGuid,
> mVariableName, Private->DriverHandle);
> +    Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
> +    ConfigRequest = AllocateZeroPool (Size);
> +    ASSERT (ConfigRequest != NULL);
> +    AllocatedRequest = TRUE;
> +    BufferSize = sizeof (SYSTEM_CONFIGURATION);
> +    UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX",
> ConfigRequestHdr, (UINT64)BufferSize);
> +    FreePool (ConfigRequestHdr);
> +  }
> +  SystemConfigPtr = GetVariable(mSetupName, &mNormalSetupGuid);
> +
> +
> +  if (SystemConfigPtr == NULL) {
> +    ZeroMem(&Private->FakeNvData, sizeof(SYSTEM_CONFIGURATION));
> +    ZeroMem(&Private->BackupNvData, sizeof(SYSTEM_CONFIGURATION));
> +  } else {
> +    CheckSystemConfigLoad(SystemConfigPtr);
> +    CopyMem(&Private->FakeNvData, SystemConfigPtr,
> sizeof(SYSTEM_CONFIGURATION));
> +    CopyMem(&Private->BackupNvData, SystemConfigPtr,
> sizeof(SYSTEM_CONFIGURATION));
> +    FreePool(SystemConfigPtr);
> +  }
> +
> +  //
> +  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
> +  //
> +  Status = HiiConfigRouting->BlockToConfig (
> +                               HiiConfigRouting,
> +                               ConfigRequest,
> +                               (UINT8 *) &Private->FakeNvData,
> +                               sizeof (SYSTEM_CONFIGURATION),
> +                               Results,
> +                               Progress
> +                               );
> +
> +  //
> +  // Free the allocated config request string.
> +  //
> +  if (AllocatedRequest) {
> +    FreePool (ConfigRequest);
> +    ConfigRequest = NULL;
> +  }
> +
> +  //
> +  // Set Progress string to the original request string.
> +  //
> +  if (Request == NULL) {
> +    *Progress = NULL;
> +  } else if (StrStr (Request, L"OFFSET") == NULL) {
> +    *Progress = Request + StrLen (Request);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function processes the results of changes in configuration.
> +
> +  @param  This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +  @param  Configuration   A null-terminated Unicode string in
> <ConfigRequest> format.
> +  @param  Progress        A pointer to a string filled in with the offset of the
> most
> +                          recent '&' before the first failing name/value pair (or the
> +                          beginning of the string if the failure is in the first
> +                          name/value pair) or the terminating NULL if all was successful.
> +
> +  @retval EFI_SUCCESS            The Results is processed successfully.
> +  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
> +  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in
> this driver.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SystemConfigRouteConfig (
> +  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
> +  IN  CONST EFI_STRING                       Configuration,
> +  OUT EFI_STRING                             *Progress
> +  )
> +{
> +  EFI_CALLBACK_INFO                         *Private;
> +  SYSTEM_CONFIGURATION                       *FakeNvData;
> +
> +  if (Configuration == NULL || Progress == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  *Progress = Configuration;
> +
> +  if (!HiiIsConfigHdrMatch (Configuration, &mSystemConfigGuid,
> mVariableName)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  *Progress = Configuration + StrLen (Configuration);
> +  Private    = EFI_CALLBACK_INFO_FROM_THIS (This);
> +  FakeNvData = &Private->FakeNvData;
> +  if (!HiiGetBrowserData (&mSystemConfigGuid, mVariableName, sizeof
> (SYSTEM_CONFIGURATION), (UINT8 *) FakeNvData)) {
> +    //
> +    // FakeNvData can't be got from SetupBrowser, which doesn't need to be
> set.
> +    //
> +    return EFI_SUCCESS;
> +  }
> +
> +  if (Private->FakeNvData.ReservedO != Private->BackupNvData.ReservedO)
> {
> +    Private->BackupNvData.ReservedO = Private->FakeNvData.ReservedO;
> +    LoadLpssDefaultValues (Private);
> +
> +    //
> +    // Pass changed uncommitted data back to Form Browser
> +    //
> +    HiiSetBrowserData (&mSystemConfigGuid, mVariableName, sizeof
> (SYSTEM_CONFIGURATION), (UINT8 *) FakeNvData, NULL);
> +  }
> +
> +  gRT->SetVariable(
> +         mSetupName,
> +         &mNormalSetupGuid,
> +         EFI_VARIABLE_NON_VOLATILE |
> EFI_VARIABLE_BOOTSERVICE_ACCESS,
> +         sizeof(SYSTEM_CONFIGURATION),
> +         &Private->FakeNvData
> +         );
> +
> +  CheckSystemConfigSave(&Private->FakeNvData);
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This is the function that is called to provide results data to the driver.  This
> data
> +  consists of a unique key which is used to identify what data is either being
> passed back
> +  or being asked for.
> +
> +  @param  This           Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +  @param  Action         A null-terminated Unicode string in <ConfigRequest>
> format.
> +  @param  KeyValue       A unique Goto OpCode callback value which record
> user's selection.
> +                         0x100 <= KeyValue <0x500 : user select a controller item in the
> first page;
> +                         KeyValue == 0x1234       : user select 'Refresh' in first page, or
> user select 'Go to Previous Menu' in second page
> +                         KeyValue == 0x1235       : user select 'Pci device filter' in first
> page
> +                         KeyValue == 0x1500       : user select 'order ... priority' item in
> second page
> +                         KeyValue == 0x1800       : user select 'commint changes' in third
> page
> +                         KeyValue == 0x2000       : user select 'Go to Previous Menu' in
> third page
> +  @param  Type           The type of value for the question.
> +  @param  Value          A pointer to the data being sent to the original
> exporting driver.
> +  @param  ActionRequest  On return, points to the action requested by the
> callback function.
> +
> +  @retval EFI_SUCCESS    Always returned.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SystemConfigCallback (
> +  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
> +  IN  EFI_BROWSER_ACTION                     Action,
> +  IN  EFI_QUESTION_ID                        KeyValue,
> +  IN  UINT8                                  Type,
> +  IN  EFI_IFR_TYPE_VALUE                     *Value,
> +  OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest
> +  )
> +{
> +  EFI_CALLBACK_INFO             *Private;
> +  SYSTEM_CONFIGURATION          *FakeNvData;
> +  SYSTEM_CONFIGURATION          *SetupData;
> +  UINTN                         SizeOfNvStore;
> +  EFI_INPUT_KEY                 Key;
> +  CHAR16                        *StringBuffer1;
> +  CHAR16                        *StringBuffer2;
> +  CHAR16                        *StringBuffer3;
> +  EFI_STATUS                    Status;
> +  UINTN                         DataSize;
> +  UINT8                         OsSelection;
> +  EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL *FormBrowserEx2;
> +
> +  StringBuffer1 = AllocateZeroPool (200 * sizeof (CHAR16));
> +  ASSERT (StringBuffer1 != NULL);
> +  StringBuffer2 = AllocateZeroPool (200 * sizeof (CHAR16));
> +  ASSERT (StringBuffer2 != NULL);
> +  StringBuffer3 = AllocateZeroPool (200 * sizeof (CHAR16));
> +  ASSERT (StringBuffer3 != NULL);
> +
> +  switch (Action) {
> +  case EFI_BROWSER_ACTION_CHANGING:
> +  {
> +    if (KeyValue == 0x1235) {
> +      StrCpy (StringBuffer1, L"Will you disable PTT ? ");
> +      StrCpy (StringBuffer2, L"Enter (YES)  /   Esc (NO)");
> +
> +      //
> +      // Popup a menu to notice user
> +      //
> +      do {
> +        CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key,
> StringBuffer1, StringBuffer2, NULL);
> +      } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar !=
> CHAR_CARRIAGE_RETURN));
> +
> +      //
> +      // If the user hits the YES Response key,
> +      //
> +      if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
> +
> +      }
> +    } else if (KeyValue == 0x1236) {
> +      StrCpy (StringBuffer1, L"Will you revoke trust ? ");
> +      StrCpy (StringBuffer2, L"Enter (YES)  /   Esc (NO)");
> +
> +      //
> +      // Popup a menu to notice user
> +      //
> +      do {
> +        CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key,
> StringBuffer1, StringBuffer2, NULL);
> +      } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar !=
> CHAR_CARRIAGE_RETURN));
> +
> +      //
> +      // If the user hits the YES Response key,
> +      //
> +      if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
> +
> +      }
> +	 } else if (KeyValue == 0x1239) {
> +	   if (Value->u8 == 0x00) {
> +       StrCpy (StringBuffer1, L"WARNING: SOC may be damaged due to high
> temperature");
> +       StrCpy (StringBuffer2, L"when DPTF is disabled and IGD turbo is
> enabled.");
> +       StrCpy (StringBuffer3, L"Press Enter/ESC to continue...");
> +
> +        //
> +        // Popup a menu to notice user
> +        //
> +        do {
> +          CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key,
> StringBuffer1, StringBuffer2, StringBuffer3, NULL);
> +        } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar !=
> CHAR_CARRIAGE_RETURN));
> +    }
> +    } else if (KeyValue == 0x1240) { // secure erase feature of eMMC
> +	    //
> +      // Popup a menu to notice user
> +      //
> +      StrCpy (StringBuffer1, L"WARNING: All your data on the eMMC will be
> lost");
> +      StrCpy (StringBuffer2, L"Do you really want to enable secure erase on
> eMMC?");
> +      StrCpy (StringBuffer3, L"       Enter (YES)    /    Esc (NO)        ");
> +
> +      do {
> +        CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key,
> StringBuffer1, StringBuffer2, StringBuffer3,NULL);
> +      } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar !=
> CHAR_CARRIAGE_RETURN));
> +
> +      //
> +      // If the user hits the ESC Response key,
> +      //
> +      if (Key.ScanCode == SCAN_ESC) {
> +        Private = EFI_CALLBACK_INFO_FROM_THIS (This);
> +        FakeNvData = &Private->FakeNvData;
> +
> +        Status = HiiGetBrowserData (
> +		               &mSystemConfigGuid,
> +				           mVariableName,
> +				           sizeof (SYSTEM_CONFIGURATION),
> +				           (UINT8 *) FakeNvData
> +				           );
> +        if (!EFI_ERROR (Status)) {
> +             FakeNvData->SecureErase = 0;
> +             HiiSetBrowserData (
> +               &mSystemConfigGuid,
> +               mVariableName,
> +               sizeof (SYSTEM_CONFIGURATION),
> +               (UINT8 *) FakeNvData,
> +               NULL
> +               );
> +        }
> +        break;
> +      }
> +
> +      //
> +      // If the user hits the YES Response key
> +      //
> +      if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
> +        //
> +        // Save change
> +        //
> +        Private = EFI_CALLBACK_INFO_FROM_THIS (This);
> +        FakeNvData = &Private->FakeNvData;
> +
> +        Status = HiiGetBrowserData (
> +		               &mSystemConfigGuid,
> +				           mVariableName,
> +				           sizeof (SYSTEM_CONFIGURATION),
> +				          (UINT8 *) FakeNvData
> +				          );
> +        if (!EFI_ERROR (Status)) {
> +          Status = gRT->SetVariable (
> +                          L"Setup",
> +                          &mNormalSetupGuid,
> +                          EFI_VARIABLE_NON_VOLATILE |
> EFI_VARIABLE_BOOTSERVICE_ACCESS,
> +                          sizeof(SYSTEM_CONFIGURATION),
> +                          &Private->FakeNvData
> +                          );
> +        }
> +
> +        //
> +        // Reset system
> +        //
> +        gRT->ResetSystem(
> +		           EfiResetCold,
> +			         EFI_SUCCESS,
> +			         0,
> +			         NULL
> +			         );
> +
> +    }
> +
> +
> +    }
> +    else if (KeyValue == 0xF001) {
> +      //
> +      // Popup a menu to notice user
> +      //
> +      StrCpy (StringBuffer1, L"Do you want to Commit Changes and Exit?");
> +      StrCpy (StringBuffer2, L"         Enter (YES) / Esc (NO)        ");
> +
> +      do {
> +        CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key,
> StringBuffer1, StringBuffer2, NULL);
> +      } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar !=
> CHAR_CARRIAGE_RETURN));
> +
> +      //
> +      // If the user hits the YES Response key
> +      //
> +      if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
> +        //
> +        // Save change
> +        //
> +        Private = EFI_CALLBACK_INFO_FROM_THIS (This);
> +        FakeNvData = &Private->FakeNvData;
> +
> +        Status = HiiGetBrowserData (
> +		           &mSystemConfigGuid,
> +				   mVariableName,
> +				   sizeof (SYSTEM_CONFIGURATION),
> +				   (UINT8 *) FakeNvData
> +				   );
> +        if (!EFI_ERROR (Status)) {
> +          Status = gRT->SetVariable (
> +                          L"Setup",
> +                          &mNormalSetupGuid,
> +                          EFI_VARIABLE_NON_VOLATILE |
> EFI_VARIABLE_BOOTSERVICE_ACCESS,
> +                          sizeof(SYSTEM_CONFIGURATION),
> +                          &Private->FakeNvData
> +                          );
> +        }
> +
> +		//
> +		// Update Secure Boot configuration changes
> +		//
> +        CheckSystemConfigSave(FakeNvData);
> +
> +        //
> +        // Reset system
> +        //
> +        if (GlobalReset == TRUE) {
> +          //
> +          // Issue full reset
> +          //
> +          IoWrite8 (
> +            (UINTN) 0XCF9,
> +            (UINT8) 0x02
> +            );
> +
> +          IoWrite8 (
> +            (UINTN) 0xCF9,
> +            (UINT8) 0x0E
> +            );
> +        } else {
> +        	gRT->ResetSystem(
> +			       EfiResetCold,
> +				   EFI_SUCCESS,
> +				   0,
> +				   NULL
> +				   );
> +        }
> +      }
> +    } else if (KeyValue == 0xF002) {
> +      //
> +      // Popup a menu to notice user
> +      //
> +      StrCpy (StringBuffer1, L"Do you want to Discard Changes and Exit?");
> +      StrCpy (StringBuffer2, L"         Enter (YES) / Esc (NO)         ");
> +
> +      do {
> +        CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key,
> StringBuffer1, StringBuffer2, NULL);
> +      } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar !=
> CHAR_CARRIAGE_RETURN));
> +
> +      //
> +      // If the user hits the YES Response key
> +      //
> +      if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
> +        //
> +        // Reset system
> +        //
> +        gRT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
> +      }
> +    } else if (KeyValue == 0xF003) {
> +      //
> +      // Popup a menu to notice user
> +      //
> +      StrCpy (StringBuffer1, L"Do you want to load setup defaults and Exit?");
> +      StrCpy (StringBuffer2, L"         Enter (YES) / Esc (NO)             ");
> +
> +      do {
> +        CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key,
> StringBuffer1, StringBuffer2, NULL);
> +      } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar !=
> CHAR_CARRIAGE_RETURN));
> +
> +      //
> +      // If the user hits the YES Response key
> +      //
> +      if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
> +
> +        Status = gBS->LocateProtocol (&gEdkiiFormBrowserEx2ProtocolGuid,
> NULL, (VOID **) &FormBrowserEx2);
> +        FormBrowserEx2->ExecuteAction(BROWSER_ACTION_DEFAULT,
> EFI_HII_DEFAULT_CLASS_STANDARD);
> +
> +        FakeNvData = AllocateZeroPool (sizeof(SYSTEM_CONFIGURATION));
> +
> +        if (FakeNvData == NULL) {
> +          return EFI_OUT_OF_RESOURCES;
> +        }
> +
> +        Status = HiiGetBrowserData (
> +		           &mSystemConfigGuid,
> +				   mVariableName,
> +				   sizeof (SYSTEM_CONFIGURATION),
> +				   (UINT8 *) FakeNvData
> +				   );
> +
> +        if (!EFI_ERROR (Status)) {
> +          Status = gRT->SetVariable (
> +                          L"Setup",
> +                          &mNormalSetupGuid,
> +                            EFI_VARIABLE_NON_VOLATILE |
> EFI_VARIABLE_BOOTSERVICE_ACCESS,
> +                          sizeof(SYSTEM_CONFIGURATION),
> +                          FakeNvData
> +                          );
> +        }
> +
> +        FreePool (FakeNvData);
> +
> +        DataSize = sizeof(OsSelection);
> +        Status = gRT->GetVariable(
> +                        L"OsSelection",
> +                        &gOsSelectionVariableGuid,
> +                        NULL,
> +                        &DataSize,
> +                        &OsSelection
> +                        );
> +
> +        if (EFI_ERROR(Status) || (OsSelection != FakeNvData->ReservedO)) {
> +          OsSelection = FakeNvData->ReservedO;
> +          Status = gRT->SetVariable (
> +                          L"OsSelection",
> +                          &gOsSelectionVariableGuid,
> +                          EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
> +                          sizeof(OsSelection),
> +                          &OsSelection
> +                          );
> +        }
> +
> +        //
> +        // Reset system
> +        //
> +        gRT->ResetSystem(
> +		       EfiResetCold,
> +			   EFI_SUCCESS,
> +			   0,
> +			   NULL
> +			   );
> +      }
> +    } else if ((KeyValue == 0x123A) || (KeyValue == 0x123B) || (KeyValue ==
> 0x123C)) {
> +        StrCpy (StringBuffer1, L"WARNING: Enable or disable USB Controllers
> will ");
> +        StrCpy (StringBuffer2, L"make global reset to restart system.");
> +        StrCpy (StringBuffer3, L"Press Enter/ESC to continue...");
> +        //
> +        // Popup a menu to notice user
> +        //
> +        do {
> +          CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key,
> StringBuffer1, StringBuffer2, StringBuffer3, NULL);
> +        } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar !=
> CHAR_CARRIAGE_RETURN));
> +
> +        FakeNvData = AllocateZeroPool (sizeof(SYSTEM_CONFIGURATION));
> +        Status = HiiGetBrowserData (
> +		           &mSystemConfigGuid,
> +				   mVariableName,
> +				   sizeof (SYSTEM_CONFIGURATION),
> +				   (UINT8 *) FakeNvData
> +				   );
> +        //
> +        // Get variable data
> +        //
> +        SizeOfNvStore = sizeof(SYSTEM_CONFIGURATION);
> +        SetupData = AllocateZeroPool (sizeof(SYSTEM_CONFIGURATION));
> +        Status = gRT->GetVariable(
> +                        L"Setup",
> +                        &mNormalSetupGuid,
> +                        NULL,
> +                        &SizeOfNvStore,
> +                        SetupData
> +                        );
> +        if ((SetupData->UsbAutoMode != FakeNvData->UsbAutoMode) ||
> +        	   (SetupData->UsbXhciSupport != FakeNvData->UsbXhciSupport) ||
> +        	   (SetupData->PchUsb20 != FakeNvData->PchUsb20)) {
> +          GlobalReset = TRUE;
> +        } else {
> +          GlobalReset = FALSE;
> +        }
> +
> +    }
> +  }
> +  break;
> +
> +  default:
> +    break;
> +  }
> +
> +  FreePool (StringBuffer1);
> +  FreePool (StringBuffer2);
> +  FreePool (StringBuffer3);
> +
> +  //
> +  // Workaround for Load Default for "DPTF Enable"
> +  //
> +  if (Action == EFI_BROWSER_ACTION_DEFAULT_STANDARD) {
> +    if (KeyValue == 0x1239) {
> +      return EFI_NOT_FOUND;
> +    }
> +  }
> +
> +  if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) {
> +    //
> +    // Do nothing for UEFI OPEN/CLOSE Action
> +    //
> +    return EFI_SUCCESS;
> +  }
> +
> +  Private = EFI_CALLBACK_INFO_FROM_THIS (This);
> +  FakeNvData = &Private->FakeNvData;
> +  if (!HiiGetBrowserData (&mSystemConfigGuid, mVariableName, sizeof
> (SYSTEM_CONFIGURATION), (UINT8 *) FakeNvData)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) && (Private-
> >FakeNvData.ReservedO != Private->BackupNvData.ReservedO)) {
> +    Private->BackupNvData.ReservedO = Private->FakeNvData.ReservedO;
> +    LoadLpssDefaultValues (Private);
> +  }
> +
> +  //
> +  // When user selected the secure erase, set it to disable
> +  //
> +  if((KeyValue == 0x1240) && (Action == EFI_BROWSER_ACTION_CHANGED))
> {
> +    FakeNvData->SecureErase = 0;
> +  }
> +
> +  if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action ==
> EFI_BROWSER_ACTION_CHANGED)) {
> +    //
> +    // If function 0 is disabled, function 1 ~ 7 also required to be disabled.
> +    //
> +    if (Private->FakeNvData.LpssDma0Enabled == 0) {
> +      Private->FakeNvData.LpssHsuart0Enabled = 0;
> +      Private->FakeNvData.LpssHsuart1Enabled = 0;
> +      Private->FakeNvData.LpssPwm0Enabled    = 0;
> +      Private->FakeNvData.LpssPwm1Enabled    = 0;
> +      Private->FakeNvData.LpssSpiEnabled     = 0;
> +    }
> +
> +
> +    //
> +    // If function 0 is disabled, function 1 ~ 7 also required to be disabled.
> +    //
> +    if (Private->FakeNvData.LpssDma1Enabled == 0) {
> +      Private->FakeNvData.LpssI2C0Enabled = 0;
> +      Private->FakeNvData.LpssI2C1Enabled = 0;
> +      Private->FakeNvData.LpssI2C2Enabled = 0;
> +      Private->FakeNvData.LpssI2C3Enabled = 0;
> +      Private->FakeNvData.LpssI2C4Enabled = 0;
> +      Private->FakeNvData.LpssI2C5Enabled = 0;
> +      Private->FakeNvData.LpssI2C6Enabled = 0;
> +    }
> +  }
> +
> +
> +  //
> +  // Pass changed uncommitted data back to Form Browser
> +  //
> +  HiiSetBrowserData (&mSystemConfigGuid, mVariableName, sizeof
> (SYSTEM_CONFIGURATION), (UINT8 *) FakeNvData, NULL);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  The driver Entry Point. The function will export a disk device class formset
> and
> +  its callback function to hii database.
> +
> +  @param  ImageHandle    The firmware allocated handle for the EFI image.
> +  @param  SystemTable    A pointer to the EFI System Table.
> +
> +  @retval EFI_SUCCESS    The entry point is executed successfully.
> +  @retval other          Some error occurs when executing this entry point.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +PlatformSetupDxeInit (
> +  IN EFI_HANDLE                   ImageHandle,
> +  IN EFI_SYSTEM_TABLE             *SystemTable
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_FORM_BROWSER2_PROTOCOL  *FormBrowser2;
> +
> +  mImageHandle = ImageHandle;
> +
> +  //
> +  // There should only be one Form Configuration protocol
> +  //
> +  Status = gBS->LocateProtocol (
> +                 &gEfiFormBrowser2ProtocolGuid,
> +                 NULL,
> +                 (VOID **) &FormBrowser2
> +                 );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  mCallbackInfo = AllocateZeroPool (sizeof (EFI_CALLBACK_INFO));
> +  if (mCallbackInfo == NULL) {
> +    return EFI_BAD_BUFFER_SIZE;
> +  }
> +
> +  mCallbackInfo->Signature = EFI_CALLBACK_INFO_SIGNATURE;
> +  mCallbackInfo->ConfigAccess.ExtractConfig = SystemConfigExtractConfig;
> +  mCallbackInfo->ConfigAccess.RouteConfig   = SystemConfigRouteConfig;
> +  mCallbackInfo->ConfigAccess.Callback      = SystemConfigCallback;
> +
> +  //
> +  // Install Device Path Protocol and Config Access protocol to driver handle
> +  // Install Platform Driver Override Protocol to driver handle
> +  //
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &mCallbackInfo->DriverHandle,
> +                  &gEfiDevicePathProtocolGuid,
> +                  &mHiiVendorDevicePath,
> +                  &gEfiHiiConfigAccessProtocolGuid,
> +                  &mCallbackInfo->ConfigAccess,
> +                  NULL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    goto Finish;
> +  }
> +
> +  //
> +  // Publish our HII data
> +  //
> +  mCallbackInfo->RegisteredHandle = HiiAddPackages (
> +                                      &mSystemConfigGuid,
> +                                      mCallbackInfo->DriverHandle,
> +                                      VfrBin,
> +                                      PlatformSetupDxeStrings,
> +                                      NULL
> +                                      );
> +  if (mCallbackInfo->RegisteredHandle == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto Finish;
> +  }
> +
> +  mHiiHandle = mCallbackInfo->RegisteredHandle;
> +
> +  //
> +  // Locate ConfigRouting protocol
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiHiiConfigRoutingProtocolGuid,
> +                  NULL,
> +                  (VOID **) &mCallbackInfo->HiiConfigRouting
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    goto Finish;
> +  }
> +
> +  //
> +  // Clear all the globle variable
> +  //
> +  return EFI_SUCCESS;
> +
> +Finish:
> +  if (mCallbackInfo->DriverHandle != NULL) {
> +    gBS->UninstallMultipleProtocolInterfaces (
> +           mCallbackInfo->DriverHandle,
> +           &gEfiDevicePathProtocolGuid,
> +           &mHiiVendorDevicePath,
> +           &gEfiHiiConfigAccessProtocolGuid,
> +           &mCallbackInfo->ConfigAccess,
> +           NULL
> +           );
> +  }
> +
> +  if (mCallbackInfo->RegisteredHandle != NULL) {
> +    HiiRemovePackages (mCallbackInfo->RegisteredHandle);
> +  }
> +
> +  if (mCallbackInfo != NULL) {
> +    FreePool (mCallbackInfo);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  Unload its installed protocol.
> +
> +  @param[in]  ImageHandle       Handle that identifies the image to be
> unloaded.
> +
> +  @retval EFI_SUCCESS           The image has been unloaded.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PlatformSetupDxeUnload (
> +  IN EFI_HANDLE  ImageHandle
> +  )
> +{
> +  if (mCallbackInfo != NULL) {
> +    if (mCallbackInfo->DriverHandle != NULL) {
> +      gBS->UninstallMultipleProtocolInterfaces (
> +             mCallbackInfo->DriverHandle,
> +             &gEfiDevicePathProtocolGuid,
> +             &mHiiVendorDevicePath,
> +             &gEfiHiiConfigAccessProtocolGuid,
> +             &mCallbackInfo->ConfigAccess,
> +             NULL
> +             );
> +    }
> +
> +    if (mCallbackInfo->RegisteredHandle != NULL) {
> +      HiiRemovePackages (mCallbackInfo->RegisteredHandle);
> +    }
> +
> +    FreePool (mCallbackInfo);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.h
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.h
> new file mode 100644
> index 0000000000..53372bb922
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.h
> @@ -0,0 +1,97 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +**/
> +
> +#ifndef _PLAT_OVER_MNGR_H_
> +#define _PLAT_OVER_MNGR_H_
> +
> +#include <FrameworkDxe.h>
> +
> +#include <Protocol/HiiConfigAccess.h>
> +#include <Protocol/HiiConfigRouting.h>
> +#include <Protocol/HiiDatabase.h>
> +#include <Protocol/FormBrowser2.h>
> +#include <Protocol/LoadedImage.h>
> +#include <Protocol/FirmwareVolume2.h>
> +#include <Protocol/PciIo.h>
> +#include <Protocol/BusSpecificDriverOverride.h>
> +#include <Protocol/ComponentName2.h>
> +#include <Protocol/ComponentName.h>
> +#include <Protocol/DriverBinding.h>
> +#include <Protocol/DevicePathToText.h>
> +#include <Protocol/DevicePath.h>
> +#include <Protocol/PlatformDriverOverride.h>
> +#include <Protocol/DataHub.h>
> +#include <Guid/MdeModuleHii.h>
> +#include <Guid/VariableFormat.h>
> +#include <Guid/DataHubRecords.h>
> +
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/DxeServicesTableLib.h>
> +#include <Library/HiiLib.h>
> +#include <Library/BiosIdLib.h>
> +#include <Library/CpuIA32.h>
> +#include <Library/HobLib.h>
> +#include <Guid/PlatformInfo.h>
> +#include <IndustryStandard/Pci22.h>
> +
> +#include "Guid/SetupVariable.h"
> +#include "Guid/OsSelection.h"
> +
> +#include <CpuType.h>
> +#include <Guid/PlatformCpuInfo.h>
> +#include <Protocol/SimpleTextIn.h>
> +#include <Protocol/FrameworkFormBrowser.h>
> +extern EFI_HII_HANDLE   mHiiHandle;
> +
> +UINT32
> +ConvertBase10ToRaw (
> +  IN  EFI_EXP_BASE10_DATA             *Data);
> +
> +UINT32
> +ConvertBase2ToRaw (
> +  IN  EFI_EXP_BASE2_DATA             *Data);
> +
> +EFI_STATUS
> +GetStringFromToken (
> +  IN      EFI_GUID                  *ProducerGuid,
> +  IN      STRING_REF                Token,
> +  OUT     CHAR16                    **String
> +  );
> +
> +VOID
> +SwapEntries (
> +  IN  CHAR8 *Data
> +  );
> +
> +VOID
> +AsciiToUnicode (
> +  IN    CHAR8     *AsciiString,
> +  IN    CHAR16    *UnicodeString
> +  );
> +
> +VOID
> +EFIAPI
> +SetupInfo (
> +  );
> +
> +
> +extern EFI_HANDLE mImageHandle;
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.i
> nf
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.i
> nf
> new file mode 100644
> index 0000000000..6d7e7c3f6c
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.i
> nf
> @@ -0,0 +1,141 @@
> +#
> +#
> +# Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +#
> +#
> +#  This driver produces UEFI PLATFORM_DRIVER_OVERRIDE_PROTOCOL if
> this protocol doesn't exist.
> +#  It doesn't install again if this protocol exists.
> +#  It only implements one interface GetDriver of
> PLATFORM_DRIVER_OVERRIDE_PROTOCOL protocol
> +#  and doesn't support other two interfaces GetDriverPath, DriverLoaded.
> +#
> +#  This driver also offers an UI interface in device manager to let user
> configure
> +#  platform override protocol to override the default algorithm for matching
> +#  drivers to controllers.
> +#
> +#  The main flow:
> +#  1. It dynamicly locate all controller device path.
> +#  2. It dynamicly locate all drivers which support binding protocol.
> +#  3. It export and dynamicly update two menu to let user select the
> +#     mapping between drivers to controllers.
> +#  4. It save all the mapping info in NV variables for the following boot,
> +#     which will be consumed by GetDriver API of the produced the platform
> override protocol.
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = PlatformSetupDxe
> +  FILE_GUID                      = C1A69A12-8653-4fde-A215-48FCD95288C3
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = PlatformSetupDxeInit
> +  UNLOAD_IMAGE                   = PlatformSetupDxeUnload
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +
> +[Sources]
> +  VfrStrings.uni
> +  FwVersionStrings.uni
> +  Vfr.vfr
> +  Main.vfi
> +  Boot.vfi
> +  PlatformSetupDxe.c
> +  SetupInfoRecords.c
> +  PlatformSetupDxe.h
> +  Security.vfi
> +  SouthClusterConfig.vfi
> +  Thermal.vfi
> +  SetupFunctions.c
> +  UnCore.vfi
> +  SystemComponent.vfi
> +  DebugConfig.vfi
> +  UqiList.uni
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  IntelFrameworkPkg/IntelFrameworkPkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec    #for PchAccess.h
> +  SecurityPkg/SecurityPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +  UefiLib
> +  UefiDriverEntryPoint
> +  UefiBootServicesTableLib
> +  HiiLib
> +  BaseMemoryLib
> +  MemoryAllocationLib
> +  DevicePathLib
> +  DxeServicesTableLib
> +  UefiRuntimeServicesTableLib
> +  PrintLib
> +  BiosIdLib
> +  CpuIA32Lib
> +  IoLib
> +
> +[Guids]
> +  ##  This GUID C Name is not required for build since it is from UefiLib and
> not directly used by this module source.
> +  ##  gEfiGlobalVariableGuid                      ## SOMETIMES_CONSUMED ##
> Variable:L"PlatformLang" this variable specifies the platform supported
> language string (RFC 4646 format)
> +  ##  gEfiGlobalVariableGuid                      ## SOMETIMES_CONSUMED ##
> Variable:L"Lang" this variable specifies the platform supported language
> string (ISO 639-2 format)
> +  ##
> +  # There could be more than one variables, from PlatDriOver, PlatDriOver1,
> PlatDriOver2,...
> +  #
> +  # gEfiCallerIdGuid                            ## Private  ## Variable:L"PlatDriOver"
> +  gEfiIfrTianoGuid                              ## CONSUMES ## Guid
> +  gEfiProcessorSubClassGuid
> +  gEfiMiscSubClassGuid
> +  gEfiCacheSubClassGuid
> +  gEfiMemorySubClassGuid
> +  gEfiPlatformInfoGuid
> +  gEfiNormalSetupGuid
> +  gEfiSecureBootEnableDisableGuid
> +  gOsSelectionVariableGuid
> +  gEfiGlobalVariableGuid
> +
> +[Protocols]
> +  gEfiComponentName2ProtocolGuid                ## SOMETIMES_CONSUMED
> (Get Driver Name if ComponentName2Protocol exists)
> +  gEfiComponentNameProtocolGuid                 ## SOMETIMES_CONSUMED
> (Get Driver Name if ComponentNameProtocol exists and
> ComponentName2Protocol doesn't exist)
> +  gEfiFirmwareVolume2ProtocolGuid               ## SOMETIMES_CONSUMED
> (Get Driver Name from EFI UI section if ComponentName2Protocol and
> ComponentNameProtocol don't exist)
> +  gEfiPciIoProtocolGuid                         ## SOMETIMES_CONSUMED (Find the
> PCI device if PciIo protocol is installed)
> +  gEfiPciRootBridgeIoProtocolGuid
> +  gEfiBusSpecificDriverOverrideProtocolGuid     ## SOMETIMES_CONSUMED
> (Check whether the PCI device contains one or more efi drivers in its option
> rom by this protocol)
> +
> +  gEfiDriverBindingProtocolGuid                 ## SOMETIMES_CONSUMED
> +  gEfiLoadedImageProtocolGuid                   ## SOMETIMES_CONSUMED
> +  gEfiLoadedImageDevicePathProtocolGuid         ##
> SOMETIMES_CONSUMED (Show the drivers in the second page that support
> DriverBindingProtocol, LoadedImageProtocol and
> LoadedImageDevicePathProtocol)
> +  gEfiDevicePathProtocolGuid                    ## SOMETIMES_CONSUMED (Show
> the controller device in the first page that support DevicePathProtocol)
> +
> +  gEfiFormBrowser2ProtocolGuid                  ## CONSUMED
> +  gEfiHiiConfigRoutingProtocolGuid              ## CONSUMED
> +  gEfiHiiConfigAccessProtocolGuid               ## PRODUCED
> +  gEfiDevicePathToTextProtocolGuid              ## CONSUMED
> +  gEdkiiFormBrowserEx2ProtocolGuid
> +
> +  gEfiDataHubProtocolGuid
> +  gEfiLegacyBiosProtocolGuid
> +  gEfiSimpleNetworkProtocolGuid
> +
> +  gEfiDiskInfoProtocolGuid                      ## CONSUMED
> +  gEfiMpServiceProtocolGuid
> +  gDxePchPlatformPolicyProtocolGuid
> +  gEfiCpuIo2ProtocolGuid
> +  gEfiTdtOperationProtocolGuid
> +  gEfiSmbiosProtocolGuid                        ## PROTOCOL CONSUMES
> +
> +[Pcd.common]
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +
> +[Depex]
> +  gEfiFormBrowser2ProtocolGuid AND gEfiHiiConfigRoutingProtocolGuid
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Security.vfi
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Security.vfi
> new file mode 100644
> index 0000000000..49669e684d
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Security.vfi
> @@ -0,0 +1,104 @@
> +//
> +//
> +// Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +//
> 
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +//
> 
> +//
> +//
> +//
> +// Module Name:
> +//
> +//   Security.vfi
> +//
> +// Abstract:
> +//
> +//   Driver Setup formset.
> +//
> +// --*/
> +
> +//
> +// Security Configuration Form
> +//
> +
> +
> +form formid = SECURITY_CONFIGURATION_FORM_ID,
> +  title    = STRING_TOKEN(STR_SECURITY_CONFIGURATION_TITLE);
> +
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +  //
> +  //TPM related
> +  //
> +  subtitle text = STRING_TOKEN(STR_TPM_CONFIGURATION_PROMPT);
> +grayoutif ideqval Setup.ETpm== 0x1;
> +  oneof   varid   = Setup.fTPM,
> +    prompt      = STRING_TOKEN(STR_PTT_PROMPT),
> +    help        = STRING_TOKEN(STR_PTT_HELP),
> +      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags =
> RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_DISABLE), value= 0, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +endif;
> +
> +grayoutif ideqval Setup.fTPM == 0x1;
> +  oneof   varid   = Setup.ETpm,
> +    prompt      = STRING_TOKEN(STR_TPM_PROMPT),
> +    help        = STRING_TOKEN(STR_TPM_HELP),
> +      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags =
> RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_DISABLE), value= 0, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +endif;
> +
> +suppressif ideqval Setup.fTPM == 0;
> +  oneof varid = Setup.MeasuredBootEnable,
> +    prompt      = STRING_TOKEN(STR_MEASURED_BOOT_ENABLE_PROMPT),
> +    help        = STRING_TOKEN(STR_MEASURED_BOOT_ENABLE_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value = 1, flags =  DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +endif;
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +
> +  subtitle text =
> STRING_TOKEN(STR_PASSWORD_CONFIGURATION_SUBTITLE);
> +
> +  password varid  = Setup.AdminPassword,
> +    prompt      = STRING_TOKEN(STR_ADMIN_PASSWORD),
> +    help        = STRING_TOKEN(STR_ADMIN_PASSWORD_HELP),
> +    flags       = 0,
> +    minsize     = 0,
> +    maxsize     = PASSWORD_MAX_SIZE,
> +    encoding    = 1,
> +  endpassword;
> +
> +  password varid  = Setup.UserPassword,
> +    prompt      = STRING_TOKEN(STR_USER_PASSWORD),
> +    help        = STRING_TOKEN(STR_USER_PASSWORD_HELP),
> +    flags       = 0,
> +    minsize     = 0,
> +    maxsize     = PASSWORD_MAX_SIZE,
> +    encoding    = 1,
> +  endpassword;
> +suppressif TRUE;
> +  password varid  = Setup.AdminPassword,
> +    prompt      = STRING_TOKEN(STR_CHANGE_ADMIN_PASSWORD),
> +    help        = STRING_TOKEN(STR_CHANGE_ADMIN_PASSWORD_HELP),
> +    flags       = 0,
> +    minsize     = 0,
> +    maxsize     = PASSWORD_MAX_SIZE,
> +    encoding    = 1,
> +  endpassword;
> +
> +  password varid  = Setup.UserPassword,
> +    prompt      = STRING_TOKEN(STR_CHANGE_USER_PASSWORD),
> +    help        = STRING_TOKEN(STR_CHANGE_USER_PASSWORD_HELP),
> +    flags       = 0,
> +    minsize     = 0,
> +    maxsize     = PASSWORD_MAX_SIZE,
> +    encoding    = 1,
> +  endpassword;
> +endif;
> +
> +endform;
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupFunctions.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupFunctions.c
> new file mode 100644
> index 0000000000..a84b425826
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupFunctions.c
> @@ -0,0 +1,85 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +    SetupFunctions.c
> +
> +Abstract:
> +
> +Revision History
> +
> +--*/
> +
> +#include "PlatformSetupDxe.h"
> +
> +VOID
> +AsciiToUnicode (
> +  IN    CHAR8     *AsciiString,
> +  IN    CHAR16    *UnicodeString
> +  )
> +{
> +  UINT8           Index;
> +
> +  Index = 0;
> +  while (AsciiString[Index] != 0) {
> +    UnicodeString[Index] = (CHAR16)AsciiString[Index];
> +    Index++;
> +  }
> +}
> +
> +VOID
> +SwapEntries (
> +  IN  CHAR8 *Data
> +  )
> +{
> +  UINT16  Index;
> +  CHAR8   Temp8;
> +
> +  Index = 0;
> +  while (Data[Index] != 0 && Data[Index+1] != 0) {
> +    Temp8 = Data[Index];
> +    Data[Index] = Data[Index+1];
> +    Data[Index+1] = Temp8;
> +    Index +=2;
> +  }
> +
> +  return;
> +}
> +
> +UINT32
> +ConvertBase10ToRaw (
> +  IN  EFI_EXP_BASE10_DATA             *Data)
> +{
> +  UINTN         Index;
> +  UINT32        RawData;
> +
> +  RawData = Data->Value;
> +  for (Index = 0; Index < (UINTN) Data->Exponent; Index++) {
> +     RawData *= 10;
> +  }
> +
> +  return  RawData;
> +}
> +
> +UINT32
> +ConvertBase2ToRaw (
> +  IN  EFI_EXP_BASE2_DATA             *Data)
> +{
> +  UINTN         Index;
> +  UINT32        RawData;
> +
> +  RawData = Data->Value;
> +  for (Index = 0; Index < (UINTN) Data->Exponent; Index++) {
> +     RawData <<= 1;
> +  }
> +
> +  return  RawData;
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupInfoRecords.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupInfoRecords.c
> new file mode 100644
> index 0000000000..c404ada588
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupInfoRecords.c
> @@ -0,0 +1,1855 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +    SetupInfoRecords.c
> +
> +Abstract:
> +
> +    This is the filter driver to retrieve data hub entries.
> +
> +Revision History:
> +--*/
> +
> +#include "PlatformSetupDxe.h"
> +#include <Protocol/LegacyBios.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +#include <Protocol/SimpleNetwork.h>
> +#include <Protocol/DevicePath.h>
> +#include <Protocol/DiskInfo.h>
> +#include <Protocol/IdeControllerInit.h>
> +#include <Protocol/MpService.h>
> +#include <Protocol/PchPlatformPolicy.h>
> +#include <Protocol/CpuIo2.h>
> +#include <Protocol/Smbios.h>
> +#include <IndustryStandard/SmBios.h>
> +#include <Library/IoLib.h>
> +#include <Library/I2CLib.h>
> +#include <Guid/GlobalVariable.h>
> +
> +#include "Valleyview.h"
> +#include "VlvAccess.h"
> +#include "PchAccess.h"
> +#include "SetupMode.h"
> +#include "PchCommonDefinitions.h"
> +#include <PlatformBaseAddresses.h>
> +
> +
> +typedef struct {
> +  UINT8  ID;
> +  CHAR8  String[16];
> +} VLV_REV;
> +
> +typedef struct {
> +  UINT8 RevId;
> +  CHAR8 String[16];
> +} SB_REV;
> +
> +//
> +// Silicon Steppings
> +//
> +SB_REV  SBRevisionTable[] = {
> +  {V_PCH_LPC_RID_0, "(A0 Stepping)"},
> +  {V_PCH_LPC_RID_1, "(A0 Stepping)"},
> +  {V_PCH_LPC_RID_2, "(A1 Stepping)"},
> +  {V_PCH_LPC_RID_3, "(A1 Stepping)"},
> +  {V_PCH_LPC_RID_4, "(B0 Stepping)"},
> +  {V_PCH_LPC_RID_5, "(B0 Stepping)"},
> +  {V_PCH_LPC_RID_6, "(B1 Stepping)"},
> +  {V_PCH_LPC_RID_7, "(B1 Stepping)"},
> +  {V_PCH_LPC_RID_8, "(B2 Stepping)"},
> +  {V_PCH_LPC_RID_9, "(B2 Stepping)"},
> +  {V_PCH_LPC_RID_A, "(B3 Stepping)"},
> +  {V_PCH_LPC_RID_B, "(B3 Stepping)"},
> +  {V_PCH_LPC_RID_C, "(C0 Stepping)"},
> +  {V_PCH_LPC_RID_D, "(C0 Stepping)"}
> +};
> +
> +#define LEFT_JUSTIFY  0x01
> +#define PREFIX_SIGN   0x02
> +#define PREFIX_BLANK  0x04
> +#define COMMA_TYPE    0x08
> +#define LONG_TYPE     0x10
> +#define PREFIX_ZERO   0x20
> +
> +#define ICH_REG_REV                 0x08
> +#define MSR_IA32_PLATFORM_ID        0x17
> +
> +
> +BOOLEAN                         mSetupInfoDone = FALSE;
> +UINT8                           mUseProductKey = 0;
> +EFI_EXP_BASE10_DATA             mProcessorFrequency;
> +EFI_EXP_BASE10_DATA             mProcessorFsbFrequency;
> +
> +EFI_GUID                        mProcessorProducerGuid;
> +EFI_HII_HANDLE                  mHiiHandle;
> +EFI_PLATFORM_CPU_INFO           mPlatformCpuInfo;
> +SYSTEM_CONFIGURATION            mSystemConfiguration;
> +EFI_PLATFORM_INFO_HOB           *mPlatformInfo;
> +
> +
> +#define memset SetMem
> +
> +UINT16                mMemorySpeed         = 0xffff;
> +EFI_PHYSICAL_ADDRESS  mMemorySizeChannelASlot0  = 0;
> +UINT16                mMemorySpeedChannelASlot0 = 0xffff;
> +EFI_PHYSICAL_ADDRESS  mMemorySizeChannelASlot1  = 0;
> +UINT16                mMemorySpeedChannelASlot1 = 0xffff;
> +EFI_PHYSICAL_ADDRESS  mMemorySizeChannelBSlot0  = 0;
> +UINT16                mMemorySpeedChannelBSlot0 = 0xffff;
> +EFI_PHYSICAL_ADDRESS  mMemorySizeChannelBSlot1  = 0;
> +UINT16                mMemorySpeedChannelBSlot1 = 0xffff;
> +EFI_PHYSICAL_ADDRESS  mMemorySizeChannelCSlot0  = 0;
> +UINT16                mMemorySpeedChannelCSlot0 = 0xffff;
> +EFI_PHYSICAL_ADDRESS  mMemorySizeChannelCSlot1  = 0;
> +UINT16                mMemorySpeedChannelCSlot1 = 0xffff;
> +UINTN                 mMemoryMode          = 0xff;
> +
> +#define CHARACTER_NUMBER_FOR_VALUE  30
> +  typedef struct {
> +  EFI_STRING_TOKEN            MemoryDeviceLocator;
> +  EFI_STRING_TOKEN            MemoryBankLocator;
> +  EFI_STRING_TOKEN            MemoryManufacturer;
> +  EFI_STRING_TOKEN            MemorySerialNumber;
> +  EFI_STRING_TOKEN            MemoryAssetTag;
> +  EFI_STRING_TOKEN            MemoryPartNumber;
> +  EFI_INTER_LINK_DATA         MemoryArrayLink;
> +  EFI_INTER_LINK_DATA         MemorySubArrayLink;
> +  UINT16                      MemoryTotalWidth;
> +  UINT16                      MemoryDataWidth;
> +  UINT64                      MemoryDeviceSize;
> +  EFI_MEMORY_FORM_FACTOR      MemoryFormFactor;
> +  UINT8                       MemoryDeviceSet;
> +  EFI_MEMORY_ARRAY_TYPE       MemoryType;
> +  EFI_MEMORY_TYPE_DETAIL      MemoryTypeDetail;
> +  UINT16                      MemorySpeed;
> +  EFI_MEMORY_STATE            MemoryState;
> +} EFI_MEMORY_ARRAY_LINK;
> +
> +
> +typedef struct {
> +  EFI_PHYSICAL_ADDRESS        MemoryArrayStartAddress;
> +  EFI_PHYSICAL_ADDRESS        MemoryArrayEndAddress;
> +  EFI_INTER_LINK_DATA         PhysicalMemoryArrayLink;
> +  UINT16                      MemoryArrayPartitionWidth;
> +} EFI_MEMORY_ARRAY_START_ADDRESS;
> +
> +
> +typedef enum {
> +  PCH_SATA_MODE_IDE = 0,
> +  PCH_SATA_MODE_AHCI,
> +  PCH_SATA_MODE_RAID,
> +  PCH_SATA_MODE_MAX
> +} PCH_SATA_MODE;
> +
> +/**
> +  Acquire the string associated with the Index from smbios structure and
> return it.
> +  The caller is responsible for free the string buffer.
> +
> +  @param OptionalStrStart   The start position to search the string
> +  @param Index              The index of the string to extract
> +  @param String             The string that is extracted
> +
> +  @retval EFI_SUCCESS       The function returns EFI_SUCCESS always.
> +
> +**/
> +EFI_STATUS
> +GetOptionalStringByIndex (
> +  IN      CHAR8                   *OptionalStrStart,
> +  IN      UINT8                   Index,
> +  OUT     CHAR16                  **String
> +  )
> +{
> +  UINTN          StrSize;
> +
> +  if (Index == 0) {
> +    *String = AllocateZeroPool (sizeof (CHAR16));
> +    return EFI_SUCCESS;
> +  }
> +
> +  StrSize = 0;
> +  do {
> +    Index--;
> +    OptionalStrStart += StrSize;
> +    StrSize           = AsciiStrSize (OptionalStrStart);
> +  } while (OptionalStrStart[StrSize] != 0 && Index != 0);
> +
> +  if ((Index != 0) || (StrSize == 1)) {
> +    //
> +    // Meet the end of strings set but Index is non-zero, or
> +    // Find an empty string
> +    //
> +    return EFI_NOT_FOUND;
> +  } else {
> +    *String = AllocatePool (StrSize * sizeof (CHAR16));
> +    AsciiStrToUnicodeStr (OptionalStrStart, *String);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  VSPrint worker function that prints a Value as a decimal number in Buffer
> +
> +  @param Buffer  Location to place ascii decimal number string of Value.
> +  @param Value   Decimal value to convert to a string in Buffer.
> +  @param Flags   Flags to use in printing decimal string, see file header for
> details.
> +  @param Width   Width of hex value.
> +
> +  Number of characters printed.
> +
> +**/
> +UINTN
> +EfiValueToString (
> +  IN  OUT CHAR16  *Buffer,
> +  IN  INT64       Value,
> +  IN  UINTN       Flags,
> +  IN  UINTN       Width
> +  )
> +{
> +  CHAR16    TempBuffer[CHARACTER_NUMBER_FOR_VALUE];
> +  CHAR16    *TempStr;
> +  CHAR16    *BufferPtr;
> +  UINTN     Count;
> +  UINTN     ValueCharNum;
> +  UINTN     Remainder;
> +  CHAR16    Prefix;
> +  UINTN     Index;
> +  BOOLEAN   ValueIsNegative;
> +  UINT64    TempValue;
> +
> +  TempStr         = TempBuffer;
> +  BufferPtr       = Buffer;
> +  Count           = 0;
> +  ValueCharNum    = 0;
> +  ValueIsNegative = FALSE;
> +
> +  if (Width > CHARACTER_NUMBER_FOR_VALUE - 1) {
> +    Width = CHARACTER_NUMBER_FOR_VALUE - 1;
> +  }
> +
> +  if (Value < 0) {
> +    Value           = -Value;
> +    ValueIsNegative = TRUE;
> +  }
> +
> +  do {
> +    TempValue = Value;
> +    Value = (INT64)DivU64x32 ((UINT64)Value, 10);
> +    Remainder = (UINTN)((UINT64)TempValue - 10 * Value);
> +    *(TempStr++) = (CHAR16)(Remainder + '0');
> +    ValueCharNum++;
> +    Count++;
> +    if ((Flags & COMMA_TYPE) == COMMA_TYPE) {
> +      if (ValueCharNum % 3 == 0 && Value != 0) {
> +        *(TempStr++) = ',';
> +        Count++;
> +      }
> +    }
> +  } while (Value != 0);
> +
> +  if (ValueIsNegative) {
> +    *(TempStr++)    = '-';
> +    Count++;
> +  }
> +
> +  if ((Flags & PREFIX_ZERO) && !ValueIsNegative) {
> +    Prefix = '0';
> +  } else {
> +    Prefix = ' ';
> +  }
> +
> +  Index = Count;
> +  if (!(Flags & LEFT_JUSTIFY)) {
> +    for (; Index < Width; Index++) {
> +      *(TempStr++) = Prefix;
> +    }
> +  }
> +
> +  //
> +  // Reverse temp string into Buffer.
> +  //
> +  if (Width > 0 && (UINTN) (TempStr - TempBuffer) > Width) {
> +    TempStr = TempBuffer + Width;
> +  }
> +  Index = 0;
> +  while (TempStr != TempBuffer) {
> +    *(BufferPtr++) = *(--TempStr);
> +    Index++;
> +  }
> +
> +  *BufferPtr = 0;
> +  return Index;
> +}
> +
> +static CHAR16 mHexStr[] = { L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7',
> +                            L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F' };
> +
> +/**
> +  VSPrint worker function that prints a Value as a hex number in Buffer
> +
> +  @param  Buffer  Location to place ascii hex string of Value.
> +  @param  Value   Hex value to convert to a string in Buffer.
> +  @param  Flags   Flags to use in printing Hex string, see file header for
> details.
> +  @param  Width   Width of hex value.
> +
> +  @retval         Number of characters printed.
> +
> +**/
> +UINTN
> +EfiValueToHexStr (
> +  IN  OUT CHAR16  *Buffer,
> +  IN  UINT64      Value,
> +  IN  UINTN       Flags,
> +  IN  UINTN       Width
> +  )
> +{
> +  CHAR16  TempBuffer[CHARACTER_NUMBER_FOR_VALUE];
> +  CHAR16  *TempStr;
> +  CHAR16  Prefix;
> +  CHAR16  *BufferPtr;
> +  UINTN   Count;
> +  UINTN   Index;
> +
> +  TempStr   = TempBuffer;
> +  BufferPtr = Buffer;
> +
> +  //
> +  // Count starts at one since we will null terminate. Each iteration of the
> +  // loop picks off one nibble. Oh yea TempStr ends up backwards
> +  //
> +  Count = 0;
> +
> +  if (Width > CHARACTER_NUMBER_FOR_VALUE - 1) {
> +    Width = CHARACTER_NUMBER_FOR_VALUE - 1;
> +  }
> +
> +  do {
> +    Index = ((UINTN)Value & 0xf);
> +    *(TempStr++) = mHexStr[Index];
> +    Value = RShiftU64 (Value, 4);
> +    Count++;
> +  } while (Value != 0);
> +
> +  if (Flags & PREFIX_ZERO) {
> +    Prefix = '0';
> +  } else {
> +    Prefix = ' ';
> +  }
> +
> +  Index = Count;
> +  if (!(Flags & LEFT_JUSTIFY)) {
> +    for (; Index < Width; Index++) {
> +      *(TempStr++) = Prefix;
> +    }
> +  }
> +
> +  //
> +  // Reverse temp string into Buffer.
> +  //
> +  if (Width > 0 && (UINTN) (TempStr - TempBuffer) > Width) {
> +    TempStr = TempBuffer + Width;
> +  }
> +  Index = 0;
> +  while (TempStr != TempBuffer) {
> +    *(BufferPtr++) = *(--TempStr);
> +    Index++;
> +  }
> +
> +  *BufferPtr = 0;
> +  return Index;
> +}
> +
> +/*++
> +  Converts MAC address to Unicode string.
> +  The value is 64-bit and the resulting string will be 12
> +  digit hex number in pairs of digits separated by dashes.
> +
> +  @param  String    string that will contain the value
> +  @param  MacAddr   add argument and description to function comment
> +  @param  AddrSize  add argument and description to function comment
> +
> +**/
> +CHAR16 *
> +StrMacToString (
> +  OUT CHAR16              *String,
> +  IN  EFI_MAC_ADDRESS     *MacAddr,
> +  IN  UINT32              AddrSize
> +  )
> +{
> +  UINT32  i;
> +
> +  for (i = 0; i < AddrSize; i++) {
> +
> +    EfiValueToHexStr (
> +      &String[2 * i],
> +      MacAddr->Addr[i] & 0xFF,
> +      PREFIX_ZERO,
> +      2
> +      );
> +  }
> +
> +  //
> +  // Terminate the string.
> +  //
> +  String[2 * AddrSize] = L'\0';
> +
> +  return String;
> +}
> +
> +VOID UpdateLatestBootTime() {
> +  UINTN                         VarSize;
> +  EFI_STATUS                   Status;
> +  UINT64                       TimeValue;
> +  CHAR16                       Buffer[40];
> +  if (mSystemConfiguration.LogBootTime != 1) {
> +    return;
> +  }
> +  VarSize = sizeof(TimeValue);
> +  Status = gRT->GetVariable(
> +                  BOOT_TIME_NAME,
> +                  &gEfiNormalSetupGuid,
> +                  NULL,
> +                  &VarSize,
> +                  &TimeValue
> +				          );
> +  if (EFI_ERROR(Status)) {
> +    return;
> +  }
> +  UnicodeSPrint (Buffer, sizeof (Buffer), L"%d ms", (UINT32)TimeValue);
> +  HiiSetString(mHiiHandle,STRING_TOKEN(STR_LOG_BOOT_TIME_VALUE),
> Buffer, NULL);
> +}
> +
> +/**
> +  Get Cache Type for the specified Cache. This function is invoked when
> there is data records
> +  available in the Data Hub.
> +
> +  Get Cache Type function arguments:
> +
> +  @param  Instance        The instance number of the subclass with the same
> ProducerName..
> +  @param  SubInstance     The instance number of the RecordType for the
> same Instance.
> +  @param  CacheType       Cache type, see definition of
> EFI_CACHE_TYPE_DATA.
> +
> +  @retval EFI_STATUS
> +
> +**/
> +EFI_STATUS
> +GetCacheType(
> +  IN  UINT16                            Instance,
> +  IN  UINT16                            SubInstance,
> +  IN  EFI_CACHE_TYPE_DATA*              CacheType)
> +{
> +  EFI_STATUS                  Status;
> +  EFI_DATA_HUB_PROTOCOL       *DataHub;
> +  EFI_DATA_RECORD_HEADER      *Record;
> +  UINT64                      MonotonicCount;
> +  EFI_CACHE_VARIABLE_RECORD*  CacheVariableRecord;
> +  EFI_SUBCLASS_TYPE1_HEADER   *DataHeader;
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiDataHubProtocolGuid,
> +                  NULL,
> +                  (void **)&DataHub
> +                  );
> +  ASSERT_EFI_ERROR(Status);
> +
> +  //
> +  // Get all available data records from data hub
> +  //
> +  MonotonicCount = 0;
> +  Record = NULL;
> +
> +  do {
> +    Status = DataHub->GetNextRecord (
> +	                    DataHub,
> +						&MonotonicCount,
> +						NULL,
> +						&Record
> +						);
> +    if (!EFI_ERROR(Status)) {
> +      if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {
> +        DataHeader  = (EFI_SUBCLASS_TYPE1_HEADER *)(Record + 1);
> +
> +        if(CompareGuid(&Record->DataRecordGuid, &gEfiCacheSubClassGuid)
> &&
> +          (DataHeader->RecordType == CacheTypeRecordType) &&
> +          (DataHeader->Instance == Instance) &&
> +          (DataHeader->SubInstance == SubInstance)) {
> +          CacheVariableRecord     = (EFI_CACHE_VARIABLE_RECORD
> *)(DataHeader + 1);
> +          if(CacheType){
> +            *CacheType = CacheVariableRecord->CacheType;
> +            return EFI_SUCCESS;
> +          }
> +        }
> +      }
> +    }
> +  } while(!EFI_ERROR(Status) && (MonotonicCount != 0));
> +
> +  return EFI_NOT_FOUND;
> +}
> +
> +/**
> +  Setup data filter function. This function is invoked when there is data
> records
> +  available in the Data Hub.
> +
> +
> +  Standard event notification function arguments:
> +  @param Event          The event that is signaled.
> +  @param Context        Not used here.
> +
> +  @retval EFI_STATUS
> +
> +**/
> +VOID
> +PrepareSetupInformation (
> +  )
> +{
> +
> +  EFI_STATUS                  Status;
> +  EFI_DATA_HUB_PROTOCOL       *DataHub;
> +  EFI_DATA_RECORD_HEADER      *Record;
> +  UINT8                       *SrcData;
> +  EFI_SUBCLASS_TYPE1_HEADER   *DataHeader;
> +  CHAR16                      *NewString;
> +  CHAR16                      *NewString2;
> +  CHAR16                      *NewStringToken;
> +  STRING_REF                  TokenToUpdate;
> +  EFI_PROCESSOR_VERSION_DATA  *ProcessorVersion;
> +  UINTN                       Index;
> +  UINTN                       DataOutput;
> +
> +  EFI_PROCESSOR_MICROCODE_REVISION_DATA   *CpuUcodeRevisionData;
> +  EFI_MEMORY_ARRAY_START_ADDRESS          *MemoryArray;
> +  EFI_MEMORY_ARRAY_LINK                   *MemoryArrayLink;
> +  UINT64                      MonotonicCount;
> +
> +  CHAR16                      Version[100];         //Assuming that strings are < 100
> UCHAR
> +  CHAR16                      ReleaseDate[100];     //Assuming that strings are < 100
> UCHAR
> +  CHAR16                      ReleaseTime[100];     //Assuming that strings are < 100
> UCHAR
> +
> +  NewString = AllocateZeroPool (0x100);
> +  NewString2 = AllocateZeroPool (0x100);
> +  SetMem(Version, sizeof(Version), 0);
> +  SetMem(ReleaseDate, sizeof(ReleaseDate), 0);
> +  SetMem(ReleaseTime, sizeof(ReleaseTime), 0);
> +
> +  //
> +  // Get the Data Hub Protocol. Assume only one instance
> +  //
> +  Status = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, (void
> **)&DataHub);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  //
> +  // Get all available data records from data hub
> +  //
> +  MonotonicCount = 0;
> +  Record = NULL;
> +
> +  do {
> +    Status = DataHub->GetNextRecord (DataHub, &MonotonicCount, NULL,
> &Record);
> +    if (!EFI_ERROR(Status)) {
> +      if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {
> +        DataHeader  = (EFI_SUBCLASS_TYPE1_HEADER *)(Record + 1);
> +        SrcData     = (UINT8  *)(DataHeader + 1);
> +
> +        //
> +        // Processor
> +        //
> +        if (CompareGuid(&Record->DataRecordGuid,
> &gEfiProcessorSubClassGuid)) {
> +          CopyMem (&mProcessorProducerGuid, &Record->ProducerName,
> sizeof(EFI_GUID));
> +          switch (DataHeader->RecordType) {
> +            case ProcessorCoreFrequencyRecordType:
> +              CopyMem(&mProcessorFrequency, SrcData,
> sizeof(EFI_EXP_BASE10_DATA));
> +              Index = EfiValueToString (
> +			            NewString,
> +						ConvertBase10ToRaw
> ((EFI_EXP_BASE10_DATA *)SrcData)/1000000000,
> +						PREFIX_ZERO,
> +						0
> +						);
> +              StrCat (NewString, L".");
> +              EfiValueToString (
> +			    NewString + Index + 1,
> +				((ConvertBase10ToRaw
> ((EFI_EXP_BASE10_DATA *)SrcData)%1000000000)/10000000),
> +				PREFIX_ZERO,
> +				0
> +				);
> +              StrCat (NewString, L" GHz");
> +              TokenToUpdate = (STRING_REF)STR_PROCESSOR_SPEED_VALUE;
> +              HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL);
> +              break;
> +
> +            case ProcessorVersionRecordType:
> +              ProcessorVersion = (EFI_PROCESSOR_VERSION_DATA *)SrcData;
> +              NewStringToken = HiiGetPackageString(&mProcessorProducerGuid,
> *ProcessorVersion, NULL);
> +              TokenToUpdate = (STRING_REF)STR_PROCESSOR_VERSION_VALUE;
> +              HiiSetString(mHiiHandle, TokenToUpdate, NewStringToken, NULL);
> +              break;
> +            case CpuUcodeRevisionDataRecordType:
> +              CpuUcodeRevisionData =
> (EFI_PROCESSOR_MICROCODE_REVISION_DATA *) SrcData;
> +              if (CpuUcodeRevisionData->ProcessorMicrocodeRevisionNumber !=
> 0) {
> +                EfiValueToHexStr (
> +				  NewString,
> +                  CpuUcodeRevisionData->ProcessorMicrocodeRevisionNumber,
> +                  PREFIX_ZERO,
> +                  8
> +				  );
> +                TokenToUpdate =
> (STRING_REF)STR_PROCESSOR_MICROCODE_VALUE;
> +                HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL);
> +              }
> +              break;
> +            default:
> +              break;
> +          }
> +
> +        //
> +        // Cache
> +        //
> +        } else if (CompareGuid(&Record->DataRecordGuid,
> &gEfiCacheSubClassGuid) &&
> +                   (DataHeader->RecordType == CacheSizeRecordType)) {
> +          if (DataHeader->SubInstance == EFI_CACHE_L1) {
> +            EFI_CACHE_TYPE_DATA              CacheType;
> +            if (EFI_SUCCESS == GetCacheType(DataHeader->Instance,
> DataHeader->SubInstance,&CacheType)){
> +              if (CacheType == EfiCacheTypeData) {
> +                TokenToUpdate =
> (STRING_REF)STR_PROCESSOR_L1_DATA_CACHE_VALUE;
> +              } else if (CacheType == EfiCacheTypeInstruction) {
> +                  TokenToUpdate =
> (STRING_REF)STR_PROCESSOR_L1_INSTR_CACHE_VALUE;
> +              } else {
> +                continue;
> +              }
> +            } else {
> +              continue;
> +            }
> +          }
> +          else if (DataHeader->SubInstance == EFI_CACHE_L2) {
> +            TokenToUpdate = (STRING_REF)STR_PROCESSOR_L2_CACHE_VALUE;
> +          } else {
> +            continue;
> +          }
> +          if (ConvertBase2ToRaw((EFI_EXP_BASE2_DATA *)SrcData)) {
> +            DataOutput = ConvertBase2ToRaw((EFI_EXP_BASE2_DATA
> *)SrcData) >> 10;
> +            EfiValueToString (NewString, DataOutput, PREFIX_ZERO, 0);
> +
> +            StrCat (NewString, L" KB");
> +            if (DataHeader->SubInstance == EFI_CACHE_L3) {
> +              HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL);
> +            } else if(DataHeader->SubInstance == EFI_CACHE_L2 &&
> mPlatformCpuInfo.CpuPackage.CoresPerPhysicalPackage > 1){
> +			  //
> +              // Show XxL2 string
> +			  //
> +              EfiValueToString (
> +			    NewString2,
> +                mPlatformCpuInfo.CpuPackage.CoresPerPhysicalPackage,
> +                PREFIX_ZERO,
> +                0
> +				);
> +              StrCat(NewString2, L"x ");
> +              StrCat(NewString2, NewString);
> +              HiiSetString(mHiiHandle, TokenToUpdate, NewString2, NULL);
> +            } else {
> +              HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL);
> +            }
> +          }
> +
> +        //
> +        // Memory
> +        //
> +        } else if (CompareGuid(&Record->DataRecordGuid,
> &gEfiMemorySubClassGuid)) {
> +          switch (DataHeader->RecordType) {
> +            case EFI_MEMORY_ARRAY_LINK_RECORD_NUMBER:
> +              MemoryArrayLink = (EFI_MEMORY_ARRAY_LINK *)SrcData;
> +
> +              if (MemoryArrayLink->MemorySpeed > 0) {
> +                //
> +                // Save the lowest speed memory module
> +                //
> +                if (MemoryArrayLink->MemorySpeed < mMemorySpeed) {
> +                  mMemorySpeed = MemoryArrayLink->MemorySpeed;
> +                }
> +                switch (DataHeader->SubInstance) {
> +                  case 1:
> +                    mMemorySpeedChannelASlot0 = MemoryArrayLink-
> >MemorySpeed;
> +                    mMemorySizeChannelASlot0 = MemoryArrayLink-
> >MemoryDeviceSize;
> +                    break;
> +                  case 2:
> +                    mMemorySpeedChannelASlot1 = MemoryArrayLink-
> >MemorySpeed;
> +                    mMemorySizeChannelASlot1 = MemoryArrayLink-
> >MemoryDeviceSize;
> +                    break;
> +                  case 3:
> +                    mMemorySpeedChannelBSlot0 = MemoryArrayLink-
> >MemorySpeed;
> +                    mMemorySizeChannelBSlot0 = MemoryArrayLink-
> >MemoryDeviceSize;
> +                    break;
> +                  case 4:
> +                    mMemorySpeedChannelBSlot1 = MemoryArrayLink-
> >MemorySpeed;
> +                    mMemorySizeChannelBSlot1 = MemoryArrayLink-
> >MemoryDeviceSize;
> +                    break;
> +                  case 5:
> +                    mMemorySpeedChannelCSlot0 = MemoryArrayLink-
> >MemorySpeed;
> +                    mMemorySizeChannelCSlot0 = MemoryArrayLink-
> >MemoryDeviceSize;
> +                    break;
> +                  case 6:
> +                    mMemorySpeedChannelCSlot1 = MemoryArrayLink-
> >MemorySpeed;
> +                    mMemorySizeChannelCSlot1 = MemoryArrayLink-
> >MemoryDeviceSize;
> +                    break;
> +                  default:
> +                    break;
> +                  }
> +              }
> +              break;
> +
> +            case EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER:
> +              MemoryArray = (EFI_MEMORY_ARRAY_START_ADDRESS *)SrcData;
> +              if (MemoryArray->MemoryArrayEndAddress - MemoryArray-
> >MemoryArrayStartAddress) {
> +              	DataOutput = (UINTN)RShiftU64((MemoryArray-
> >MemoryArrayEndAddress - MemoryArray->MemoryArrayStartAddress + 1),
> 20);
> +              	EfiValueToString (NewString, DataOutput / 1024,
> PREFIX_ZERO, 0);
> +              	if(DataOutput % 1024) {
> +              	  StrCat (NewString, L".");
> +              	  DataOutput = ((DataOutput % 1024) * 1000) / 1024;
> +              	  while(!(DataOutput % 10))
> +              	    DataOutput = DataOutput / 10;
> +                  EfiValueToString (NewString2, DataOutput, PREFIX_ZERO, 0);
> +                  StrCat (NewString, NewString2);
> +                }
> +                StrCat (NewString, L" GB");
> +                TokenToUpdate =
> (STRING_REF)STR_TOTAL_MEMORY_SIZE_VALUE;
> +                HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL);
> +              }
> +              break;
> +
> +            default:
> +              break;
> +          }
> +        }
> +      }
> +    }
> +  } while (!EFI_ERROR(Status) && (MonotonicCount != 0));
> +
> +  Status = GetBiosVersionDateTime (
> +             Version,
> +			 ReleaseDate,
> +			 ReleaseTime
> +			 );
> +
> +  DEBUG ((EFI_D_ERROR, "GetBiosVersionDateTime :%s %s %s \n", Version,
> ReleaseDate, ReleaseTime));
> +  if (!EFI_ERROR (Status)) {
> +    UINTN         Length = 0;
> +    CHAR16        *BuildDateTime;
> +
> +    Length = StrLen(ReleaseDate) + StrLen(ReleaseTime);
> +
> +    BuildDateTime = AllocateZeroPool ((Length+2) * sizeof(CHAR16));
> +    StrCpy (BuildDateTime, ReleaseDate);
> +    StrCat (BuildDateTime, L" ");
> +    StrCat (BuildDateTime, ReleaseTime);
> +
> +    TokenToUpdate = (STRING_REF)STR_BIOS_VERSION_VALUE;
> +    DEBUG ((EFI_D_ERROR, "update STR_BIOS_VERSION_VALUE\n"));
> +    HiiSetString(mHiiHandle, TokenToUpdate, Version, NULL);
> +
> +    TokenToUpdate = (STRING_REF)STR_BIOS_BUILD_TIME_VALUE;
> +    DEBUG ((EFI_D_ERROR, "update STR_BIOS_BUILD_TIME_VALUE\n"));
> +    HiiSetString(mHiiHandle, TokenToUpdate, BuildDateTime, NULL);
> +  }
> +
> +  //
> +  // Calculate and update memory speed display in Main Page
> +  //
> +  //
> +  // Update the overall memory speed
> +  //
> +  if (mMemorySpeed != 0xffff) {
> +    EfiValueToString (NewString, mMemorySpeed, PREFIX_ZERO, 0);
> +    StrCat (NewString, L" MHz");
> +
> +    TokenToUpdate = (STRING_REF)STR_SYSTEM_MEMORY_SPEED_VALUE;
> +    HiiSetString(mHiiHandle, TokenToUpdate, NewString, NULL);
> +  }
> +
> +  gBS->FreePool(NewString);
> +  gBS->FreePool(NewString2);
> +
> +  return;
> +}
> +
> +/**
> +
> +  Routine Description: update the SETUP info for "Additional Information"
> which is SMBIOS info.
> +
> +  @retval EFI_STATUS
> +
> +**/
> +EFI_STATUS
> +UpdateAdditionalInformation (
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINT64                          MonotonicCount;
> +  EFI_DATA_HUB_PROTOCOL           *DataHub;
> +  EFI_DATA_RECORD_HEADER          *Record;
> +  EFI_SUBCLASS_TYPE1_HEADER       *DataHeader;
> +  EFI_SMBIOS_PROTOCOL             *Smbios;
> +  EFI_SMBIOS_HANDLE               SmbiosHandle;
> +  EFI_SMBIOS_TABLE_HEADER         *SmbiosRecord;
> +  SMBIOS_TABLE_TYPE0              *Type0Record;
> +  UINT8                           StrIndex;
> +  CHAR16                          *BiosVersion = NULL;
> +  CHAR16                          *IfwiVersion = NULL;
> +  UINT16                          SearchIndex;
> +  EFI_STRING_ID                   TokenToUpdate;
> +#if defined( RVP_SUPPORT ) && RVP_SUPPORT
> +  EFI_MISC_SYSTEM_MANUFACTURER    *SystemManufacturer;
> +#endif
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiDataHubProtocolGuid,
> +                  NULL,
> +                  (void **)&DataHub
> +                  );
> +
> +  ASSERT_EFI_ERROR(Status);
> +
> +  MonotonicCount  = 0;
> +  Record = NULL;
> +  do {
> +    Status = DataHub->GetNextRecord (
> +                        DataHub,
> +                        &MonotonicCount,
> +                        NULL,
> +                        &Record
> +                        );
> +    if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {
> +      DataHeader  = (EFI_SUBCLASS_TYPE1_HEADER *)(Record + 1);
> +
> +      if (CompareGuid(&Record->DataRecordGuid, &gEfiMiscSubClassGuid)
> &&
> +          (DataHeader->RecordType ==
> EFI_MISC_SYSTEM_MANUFACTURER_RECORD_NUMBER)) {
> +#if defined( RVP_SUPPORT ) && RVP_SUPPORT
> +        //
> +        // System Information
> +        //
> +        SystemManufacturer = (EFI_MISC_SYSTEM_MANUFACTURER
> *)(DataHeader + 1);
> +
> +        //
> +        // UUID  (System Information)
> +        //
> +        SMBIOSString = EfiLibAllocateZeroPool (0x100);
> +        GuidToString ( &SystemManufacturer->SystemUuid, SMBIOSString,
> 0x00 );
> +
> +        TokenToUpdate = (STRING_REF)STR_SYSTEM_UUID_VALUE;
> +        HiiSetString(mHiiHandle, TokenToUpdate, SMBIOSString, NULL);
> +
> +        gBS->FreePool(SMBIOSString);
> +#endif
> +      }
> +    }
> +  } while (!EFI_ERROR(Status) && (MonotonicCount != 0));
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiSmbiosProtocolGuid,
> +                  NULL,
> +                  (VOID **) &Smbios
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +  do {
> +    Status = Smbios->GetNext (
> +                       Smbios,
> +                       &SmbiosHandle,
> +                       NULL,
> +                       &SmbiosRecord,
> +                       NULL
> +                       );
> +    if (SmbiosRecord->Type == EFI_SMBIOS_TYPE_BIOS_INFORMATION) {
> +      Type0Record = (SMBIOS_TABLE_TYPE0 *) SmbiosRecord;
> +      StrIndex = Type0Record->BiosVersion;
> +      GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type0Record +
> Type0Record->Hdr.Length), StrIndex, &BiosVersion);
> +      TokenToUpdate = STRING_TOKEN (STR_BIOS_VERSION_VALUE);
> +      for (SearchIndex = 0x0; SearchIndex < SMBIOS_STRING_MAX_LENGTH;
> SearchIndex++) {
> +        if (BiosVersion[SearchIndex] == 0x0020) {
> +          BiosVersion[SearchIndex] = 0x0000;
> +          IfwiVersion = (CHAR16 *)(&BiosVersion[SearchIndex+1]);
> +          break;
> +        } else if (BiosVersion[SearchIndex] == 0x0000) {
> +          break;
> +        }
> +      }
> +      HiiSetString (mHiiHandle, TokenToUpdate, BiosVersion, NULL);
> +
> +      //
> +      // Check IfwiVersion, to avoid no IFWI version in SMBIOS Type 0
> strucntion
> +      //
> +      if(IfwiVersion) {
> +        TokenToUpdate = STRING_TOKEN (STR_IFWI_VERSION_VALUE);
> +        HiiSetString (mHiiHandle, TokenToUpdate, IfwiVersion, NULL);
> +      }
> +    }
> +  } while (!EFI_ERROR(Status));
> +
> +  UpdateLatestBootTime();
> +
> +  return  EFI_SUCCESS;
> +}
> +
> +VOID
> +UpdateCPUInformation ()
> +{
> +  CHAR16
> 	Buffer[40];
> +  UINT16                                FamilyId;
> +  UINT8                                 Model;
> +  UINT8                                 SteppingId;
> +  UINT8                                 ProcessorType;
> +  EFI_STATUS                            Status;
> +  EFI_MP_SERVICES_PROTOCOL              *MpService;
> +  UINTN                                 MaximumNumberOfCPUs;
> +  UINTN                                 NumberOfEnabledCPUs;
> +  UINT32
> 	Buffer32 = 0xFFFFFFFF;   // Keep buffer with unknown device
> +
> +  EfiCpuVersion (&FamilyId, &Model, &SteppingId, &ProcessorType);
> +
> +  //
> +  //we need raw Model data
> +  //
> +  Model = Model & 0xf;
> +
> +  //
> +  //Family/Model/Step
> +  //
> +  UnicodeSPrint (Buffer, sizeof (Buffer), L"%d/%d/%d", FamilyId,  Model,
> SteppingId);
> +  HiiSetString(mHiiHandle,STRING_TOKEN(STR_PROCESSOR_ID_VALUE),
> Buffer, NULL);
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiMpServiceProtocolGuid,
> +                  NULL,
> +                  (void **)&MpService
> +                  );
> +  if (!EFI_ERROR (Status)) {
> +    //
> +    // Determine the number of processors
> +    //
> +    MpService->GetNumberOfProcessors (
> +                 MpService,
> +                 &MaximumNumberOfCPUs,
> +                 &NumberOfEnabledCPUs
> +                 );
> +    UnicodeSPrint (Buffer, sizeof (Buffer), L"%d", MaximumNumberOfCPUs);
> +    HiiSetString(mHiiHandle,STRING_TOKEN(STR_PROCESSOR_CORE_VALUE),
> Buffer, NULL);
> +  }
> +  //
> +  // Update Mobile / Desktop / Tablet SKU
> +  //
> +  Buffer32 =(UINT32) RShiftU64 (EfiReadMsr (MSR_IA32_PLATFORM_ID), 50)
> & 0x07;
> +
> +  switch(Buffer32){
> +      case 0x0:
> +        UnicodeSPrint (Buffer, sizeof (Buffer), L"(%d) - ISG SKU SOC", Buffer32);
> +        break;
> +      case 0x01:
> +        UnicodeSPrint (Buffer, sizeof (Buffer), L"(%d) - Mobile SKU SOC",
> Buffer32);
> +        break;
> +      case 0x02:
> +        UnicodeSPrint (Buffer, sizeof (Buffer), L"(%d) - Desktop SKU SOC",
> Buffer32);
> +        break;
> +      case 0x03:
> +        UnicodeSPrint (Buffer, sizeof (Buffer), L"(%d) - Mobile SKU SOC",
> Buffer32);
> +        break;
> +      default:
> +        UnicodeSPrint (Buffer, sizeof (Buffer), L"(%d) - Unknown SKU SOC",
> Buffer32);
> +        break;
> +    }
> +  HiiSetString(mHiiHandle,STRING_TOKEN(STR_PROCESSOR_SKU_VALUE),
> Buffer, NULL);
> +
> +}
> +
> +
> +EFI_STATUS
> +SearchChildHandle(
> +  EFI_HANDLE Father,
> +  EFI_HANDLE *Child
> +  )
> +{
> +  EFI_STATUS                                                 Status;
> +  UINTN                                                          HandleIndex;
> +  EFI_GUID                                                     **ProtocolGuidArray = NULL;
> +  UINTN                                                          ArrayCount;
> +  UINTN                                                          ProtocolIndex;
> +  UINTN                                                          OpenInfoCount;
> +  UINTN                                                          OpenInfoIndex;
> +  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY  *OpenInfo = NULL;
> +  UINTN                                                          mHandleCount;
> +  EFI_HANDLE                                                 *mHandleBuffer= NULL;
> +
> +  //
> +  // Retrieve the list of all handles from the handle database
> +  //
> +  Status = gBS->LocateHandleBuffer (
> +                  AllHandles,
> +                  NULL,
> +                  NULL,
> +                  &mHandleCount,
> +                  &mHandleBuffer
> +                  );
> +
> +  for (HandleIndex = 0; HandleIndex < mHandleCount; HandleIndex++)
> +  {
> +    //
> +    // Retrieve the list of all the protocols on each handle
> +    //
> +    Status = gBS->ProtocolsPerHandle (
> +                    mHandleBuffer[HandleIndex],
> +                    &ProtocolGuidArray,
> +                    &ArrayCount
> +                    );
> +    if (!EFI_ERROR (Status))
> +    {
> +      for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++)
> +      {
> +        Status = gBS->OpenProtocolInformation (
> +                        mHandleBuffer[HandleIndex],
> +                        ProtocolGuidArray[ProtocolIndex],
> +                        &OpenInfo,
> +                        &OpenInfoCount
> +                        );
> +        if (!EFI_ERROR (Status))
> +        {
> +          for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount;
> OpenInfoIndex++)
> +          {
> +            if(OpenInfo[OpenInfoIndex].AgentHandle == Father)
> +            {
> +              if ((OpenInfo[OpenInfoIndex].Attributes &
> EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) ==
> EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER)
> +              {
> +                *Child = mHandleBuffer[HandleIndex];
> +		  Status = EFI_SUCCESS;
> +		  goto TryReturn;
> +              }
> +            }
> +          }
> +	   Status = EFI_NOT_FOUND;
> +        }
> +      }
> +      if(OpenInfo != NULL)
> +      {
> +        FreePool(OpenInfo);
> +	 OpenInfo = NULL;
> +      }
> +    }
> +    FreePool (ProtocolGuidArray);
> +    ProtocolGuidArray = NULL;
> +  }
> +TryReturn:
> +  if(OpenInfo != NULL)
> +  {
> +    FreePool (OpenInfo);
> +    OpenInfo = NULL;
> +  }
> +  if(ProtocolGuidArray != NULL)
> +  {
> +    FreePool(ProtocolGuidArray);
> +    ProtocolGuidArray = NULL;
> +  }
> +  if(mHandleBuffer != NULL)
> +  {
> +    FreePool (mHandleBuffer);
> +    mHandleBuffer = NULL;
> +  }
> +  return Status;
> +}
> +
> +EFI_STATUS
> +JudgeHandleIsPCIDevice(
> +  EFI_HANDLE    Handle,
> +  UINT8            Device,
> +  UINT8            Funs
> +  )
> +{
> +  EFI_STATUS  Status;
> +  EFI_DEVICE_PATH   *DPath;
> +
> +  Status = gBS->HandleProtocol (
> +                  Handle,
> +                  &gEfiDevicePathProtocolGuid,
> +                  (VOID **) &DPath
> +                  );
> +  if(!EFI_ERROR(Status))
> +  {
> +    while(!IsDevicePathEnd(DPath))
> +    {
> +      if((DPath->Type == HARDWARE_DEVICE_PATH) && (DPath->SubType ==
> HW_PCI_DP))
> +      {
> +        PCI_DEVICE_PATH   *PCIPath;
> +
> +        PCIPath = (PCI_DEVICE_PATH*) DPath;
> +        DPath = NextDevicePathNode(DPath);
> +        if(IsDevicePathEnd(DPath) && (PCIPath->Device == Device) &&
> (PCIPath->Function == Funs))
> +        {
> +          return EFI_SUCCESS;
> +        }
> +      }
> +      else
> +      {
> +        DPath = NextDevicePathNode(DPath);
> +      }
> +    }
> +  }
> +  return EFI_UNSUPPORTED;
> +}
> +
> +EFI_STATUS
> +GetDriverName(
> +  EFI_HANDLE   Handle,
> +  CHAR16         *Name
> +  )
> +{
> +  EFI_DRIVER_BINDING_PROTOCOL        *BindHandle = NULL;
> +  EFI_STATUS                                        Status;
> +  UINT32                                               Version;
> +  UINT16                                               *Ptr;
> +  Status = gBS->OpenProtocol(
> +                  Handle,
> +                  &gEfiDriverBindingProtocolGuid,
> +                  (VOID**)&BindHandle,
> +                  NULL,
> +                  NULL,
> +                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                  );
> +
> +  if (EFI_ERROR(Status))
> +  {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  Version = BindHandle->Version;
> +  Ptr = (UINT16*)&Version;
> +  UnicodeSPrint(Name, 40, L"%d.%d.%d", Version >> 24 , (Version >>16)&
> 0x0f ,*(Ptr));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +GetGOPDriverName(
> +  CHAR16 *Name
> +  )
> +{
> +  UINTN                         HandleCount;
> +  EFI_HANDLE                *Handles= NULL;
> +  UINTN                         Index;
> +  EFI_STATUS                Status;
> +  EFI_HANDLE                Child = 0;
> +
> +  Status = gBS->LocateHandleBuffer(
> +		              ByProtocol,
> +		              &gEfiDriverBindingProtocolGuid,
> +		              NULL,
> +		              &HandleCount,
> +		              &Handles
> +                  );
> +  for (Index = 0; Index < HandleCount ; Index++)
> +  {
> +    Status = SearchChildHandle(Handles[Index], &Child);
> +    if(!EFI_ERROR(Status))
> +    {
> +      Status = JudgeHandleIsPCIDevice(
> +                 Child,
> +                 0x02,
> +                 0x00
> +                 );
> +      if(!EFI_ERROR(Status))
> +      {
> +        return GetDriverName(Handles[Index], Name);
> +      }
> +    }
> +  }
> +  return EFI_UNSUPPORTED;
> +}
> +
> +EFI_STATUS
> +UpdatePlatformInformation (
> +  )
> +{
> +  UINT32                   MicroCodeVersion;
> +  CHAR16                   Buffer[40];
> +  UINT8                    IgdVBIOSRevH;
> +  UINT8                    IgdVBIOSRevL;
> +  UINT16                   EDX;
> +  EFI_IA32_REGISTER_SET    RegSet;
> +  EFI_LEGACY_BIOS_PROTOCOL *LegacyBios = NULL;
> +  EFI_STATUS               Status;
> +  UINT8                    CpuFlavor=0;
> +  EFI_PEI_HOB_POINTERS     GuidHob;
> +  UINTN                    NumHandles;
> +  EFI_HANDLE                        *HandleBuffer;
> +  UINTN                             Index;
> +  DXE_PCH_PLATFORM_POLICY_PROTOCOL  *PchPlatformPolicy;
> +  UINTN                             PciD31F0RegBase;
> +  UINT8                             count;
> +  UINT8                             Data8;
> +  UINT8                             PIDData8;
> +
> +  CHAR16                            Name[40];
> +  UINT32                            MrcVersion;
> +
> +  //
> +  // 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);
> +    }
> +  }
> +
> +  //
> +  //VBIOS version
> +  //
> +  Status = gBS->LocateProtocol(
> +                  &gEfiLegacyBiosProtocolGuid,
> +                  NULL,
> +                  (void **)&LegacyBios
> +                  );
> +  if (!EFI_ERROR (Status)) {
> +  RegSet.X.AX = 0x5f01;
> +  Status = LegacyBios->Int86 (LegacyBios, 0x10, &RegSet);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  //
> +  // simulate AMI int15 (ax=5f01) handler
> +  // check NbInt15.asm in AMI code for asm edition
> +  //
> +  EDX = (UINT16)((RegSet.E.EBX >> 16) & 0xffff);
> +  IgdVBIOSRevH = (UINT8)(((EDX & 0x0F00) >> 4) | (EDX & 0x000F));
> +  IgdVBIOSRevL = (UINT8)(((RegSet.X.BX & 0x0F00) >> 4) | (RegSet.X.BX &
> 0x000F));
> +
> +  if (IgdVBIOSRevH==0 && IgdVBIOSRevL==0){
> +    HiiSetString(mHiiHandle,
> STRING_TOKEN(STR_CHIP_IGD_VBIOS_REV_VALUE), L"N/A", NULL);
> +  } else {
> +    UnicodeSPrint (Buffer, sizeof (Buffer), L"%02X%02X",
> IgdVBIOSRevH,IgdVBIOSRevL);
> +    HiiSetString(mHiiHandle,
> STRING_TOKEN(STR_CHIP_IGD_VBIOS_REV_VALUE), Buffer, NULL);
> +    }
> +  }
> +
> +  Status = GetGOPDriverName(Name);
> +
> +  if (!EFI_ERROR(Status))
> +  {
> +    HiiSetString(mHiiHandle, STRING_TOKEN(STR_GOP_VALUE), Name,
> NULL);
> +  }
> +
> +
> +  //
> +  // CpuFlavor
> +  // ISG-DC Tablet        000
> +  // VLV-QC Tablet        001
> +  // VLV-QC Desktop       010
> +  // VLV-QC Notebook      011
> +  //
> +  CpuFlavor = RShiftU64 (EfiReadMsr (MSR_IA32_PLATFORM_ID), 50) & 0x07;
> +
> +  switch(CpuFlavor){
> +    case 0x0:
> +      UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-DC Tablet",
> CpuFlavor);
> +      break;
> +    case 0x01:
> +      UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC
> Notebook", CpuFlavor);
> +      break;
> +    case 0x02:
> +      UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC Desktop",
> CpuFlavor);
> +      break;
> +    case 0x03:
> +      UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC
> Notebook", CpuFlavor);
> +      break;
> +    default:
> +      UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"Unknown CPU",
> CpuFlavor);
> +      break;
> +  }
> +  HiiSetString(mHiiHandle,STRING_TOKEN(STR_CPU_FLAVOR_VALUE),
> Buffer, NULL);
> +
> +  if ( NULL != mPlatformInfo) {
> +    //
> +    //BoardId
> +    //
> +    switch(mPlatformInfo->BoardId){
> +      case 0x2:
> +        UnicodeSPrint (Buffer, sizeof (Buffer), L"BAY LAKE RVP(%02x)",
> mPlatformInfo->BoardId);
> +        break;
> +
> +      case 0x4:
> +        UnicodeSPrint (Buffer, sizeof (Buffer), L"BAY LAKE FFRD(%02x)",
> mPlatformInfo->BoardId);
> +        break;
> +
> +      case 0x5:
> +        UnicodeSPrint (Buffer, sizeof (Buffer), L"BAY ROCK RVP DDR3L (%02x)",
> mPlatformInfo->BoardId);
> +        break;
> +
> +      case 0x20:
> +        UnicodeSPrint (Buffer, sizeof (Buffer), L"BAYLEY BAY (%02x)",
> mPlatformInfo->BoardId);
> +        break;
> +
> +      case 0x30:
> +        UnicodeSPrint (Buffer, sizeof (Buffer), L"BAKER SPORT (%02x)",
> mPlatformInfo->BoardId);
> +        break;
> +
> +      case 0x0:
> +        UnicodeSPrint (Buffer, sizeof (Buffer), L"ALPINE VALLEY (%x)",
> mPlatformInfo->BoardId);
> +        break;
> +
> +      case 0x3:
> +        UnicodeSPrint (Buffer, sizeof (Buffer), L"BAY LAKE FFD8 (%x)",
> mPlatformInfo->BoardId);
> +        break;
> +
> +      default:
> +        UnicodeSPrint (Buffer, sizeof (Buffer), L"Unknown BOARD (%02x)",
> mPlatformInfo->BoardId);
> +        break;
> +    }
> +    HiiSetString(mHiiHandle,STRING_TOKEN(STR_BOARD_ID_VALUE), Buffer,
> NULL);
> +
> +
> +    //
> +    // Get Board FAB ID Info from protocol, update into the NVS area.
> +    // bit0~bit3 are for Fab ID, 0x0F means unknow FAB.
> +    //
> +    if(mPlatformInfo->BoardRev == 0x0F) {
> +      UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", L"Unknown FAB");
> +      HiiSetString(mHiiHandle,STRING_TOKEN(STR_FAB_ID_VALUE), Buffer,
> NULL);
> +    } else {
> +      UnicodeSPrint (Buffer, sizeof (Buffer), L"%2x", mPlatformInfo-
> >BoardRev);
> +      HiiSetString(mHiiHandle,STRING_TOKEN(STR_FAB_ID_VALUE), Buffer,
> NULL);
> +    }
> +  }
> +
> +  //
> +  //Update MRC Version
> +  //
> +  MrcVersion = 0x00000000;
> +  MrcVersion &= 0xffff;
> +  Index = EfiValueToString (Buffer, MrcVersion/100, PREFIX_ZERO, 0);
> +  StrCat (Buffer, L".");
> +  EfiValueToString (Buffer + Index + 1, (MrcVersion%100)/10, PREFIX_ZERO,
> 0);
> +  EfiValueToString (Buffer + Index + 2, (MrcVersion%100)%10, PREFIX_ZERO,
> 0);
> +  HiiSetString(mHiiHandle,STRING_TOKEN(STR_MRC_VERSION_VALUE),
> Buffer, NULL);
> +
> +  //
> +  //Update Soc Version
> +  //
> +
> +  //
> +  // Retrieve all instances of PCH Platform Policy protocol
> +  //
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gDxePchPlatformPolicyProtocolGuid,
> +                  NULL,
> +                  &NumHandles,
> +                  &HandleBuffer
> +                  );
> +  if (!EFI_ERROR (Status)) {
> +    //
> +    // Find the matching PCH Policy protocol
> +    //
> +    for (Index = 0; Index < NumHandles; Index++) {
> +      Status = gBS->HandleProtocol (
> +                      HandleBuffer[Index],
> +                      &gDxePchPlatformPolicyProtocolGuid,
> +                      (void **)&PchPlatformPolicy
> +                      );
> +      if (!EFI_ERROR (Status)) {
> +        PciD31F0RegBase = MmPciAddress (
> +                            0,
> +                            PchPlatformPolicy->BusNumber,
> +                            PCI_DEVICE_NUMBER_PCH_LPC,
> +                            PCI_FUNCTION_NUMBER_PCH_LPC,
> +                            0
> +                            );
> +
> +         Data8 = MmioRead8 (PciD31F0RegBase + R_PCH_LPC_RID_CC);
> +         count = ARRAY_SIZE (SBRevisionTable);
> +         for (Index = 0; Index < count; Index++) {
> +           if(Data8 == SBRevisionTable[Index].RevId) {
> +              UnicodeSPrint (Buffer, sizeof (Buffer), L"%02x %a", Data8,
> SBRevisionTable[Index].String);
> +              HiiSetString(mHiiHandle,STRING_TOKEN(STR_SOC_VALUE), Buffer,
> NULL);
> +             break;
> +           }
> +         }
> +        break;
> +      }
> +    }
> +  }
> +
> +  //
> +  // Microcode Revision
> +  //
> +  EfiWriteMsr (EFI_MSR_IA32_BIOS_SIGN_ID, 0);
> +  EfiCpuid (EFI_CPUID_VERSION_INFO, NULL);
> +  MicroCodeVersion = (UINT32) RShiftU64 (EfiReadMsr
> (EFI_MSR_IA32_BIOS_SIGN_ID), 32);
> +  UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", MicroCodeVersion);
> +
> HiiSetString(mHiiHandle,STRING_TOKEN(STR_PROCESSOR_MICROCODE_VAL
> UE), Buffer, NULL);
> +
> +  //
> +  // Punit Version
> +  //
> +  Data8 = 0;
> +  UnicodeSPrint (Buffer, sizeof (Buffer), L"0x%x", Data8);
> +  HiiSetString(mHiiHandle,STRING_TOKEN(STR_PUNIT_FW_VALUE), Buffer,
> NULL);
> +
> +  //
> +  //  PMC Version
> +  //
> +  Data8 = (UINT8)((MmioRead32 (PMC_BASE_ADDRESS +
> R_PCH_PMC_PRSTS)>>16)&0x00FF);
> +  PIDData8 = (UINT8)((MmioRead32 (PMC_BASE_ADDRESS +
> R_PCH_PMC_PRSTS)>>24)&0x00FF);
> +  UnicodeSPrint (Buffer, sizeof (Buffer), L"0x%X_%X",PIDData8, Data8);
> +  HiiSetString(mHiiHandle,STRING_TOKEN(STR_PMC_FW_VALUE), Buffer,
> NULL);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +  Update SATA Drivesize Strings for Setup and Boot order
> +
> +  @param NewString - pointer to string.
> +  @param DeviceSpeed - speed of drive.
> +
> +**/
> +VOID
> +GetDeviceSpeedString (
> +  CHAR16                      *NewString,
> +  IN UINTN                    DeviceSpeed
> +  )
> +{
> +  if (DeviceSpeed == 0x01) {
> +    StrCat (NewString, L"1.5Gb/s");
> +  } else if (DeviceSpeed == 0x02) {
> +    StrCat (NewString, L"3.0Gb/s");
> +  } else if (DeviceSpeed == 0x03) {
> +    StrCat (NewString, L"6.0Gb/s");
> +  } else if (DeviceSpeed == 0x0) {
> +
> +  }
> +}
> +
> +UINT8
> +GetChipsetSataPortSpeed (
> +  UINTN PortNum
> +  )
> +{
> +  UINT32                      DeviceSpeed;
> +  UINT8                       DeviceConfigStatus;
> +  UINT32                      IdeAhciBar;
> +  EFI_PHYSICAL_ADDRESS        MemBaseAddress = 0;
> +  UINT8                       FunNum;
> +
> +  DeviceSpeed = 0x01; // generation 1
> +
> +
> +  //
> +  // Allocate the AHCI BAR
> +  //
> +    FunNum = PCI_FUNCTION_NUMBER_PCH_SATA;
> +    MemBaseAddress = 0x0ffffffff;
> +    gDS->AllocateMemorySpace (
> +           EfiGcdAllocateMaxAddressSearchBottomUp,
> +           EfiGcdMemoryTypeMemoryMappedIo,
> +           N_PCH_SATA_ABAR_ALIGNMENT,  // 2^11: 2K Alignment
> +           V_PCH_SATA_ABAR_LENGTH,     // 2K Length
> +           &MemBaseAddress,
> +           mImageHandle,
> +           NULL
> +           );
> +    IdeAhciBar = MmioRead32 (
> +                   MmPciAddress (
> +				     0,
> +                     0,
> +                     PCI_DEVICE_NUMBER_PCH_SATA,
> +                     FunNum,
> +                     R_PCH_SATA_ABAR
> +                     )
> +                   );
> +    IdeAhciBar &= 0xFFFFF800;
> +    DeviceConfigStatus = 0;
> +    if (IdeAhciBar == 0) {
> +      DeviceConfigStatus = 1;
> +      IdeAhciBar = (UINT32)MemBaseAddress;
> +      MmioWrite32 (
> +        MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_SATA, FunNum,
> R_PCH_SATA_ABAR),
> +        IdeAhciBar
> +        );
> +      MmioOr16 (
> +        MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_SATA, FunNum,
> R_PCH_SATA_COMMAND),
> +        B_PCH_SATA_COMMAND_MSE
> +        );
> +    }
> +
> +    if (mSystemConfiguration.SataType == PCH_SATA_MODE_IDE){
> +      //
> +      // Program the "Ports Implemented Register"
> +      //
> +      MmioAndThenOr32 (IdeAhciBar + R_PCH_SATA_AHCI_PI,
> (UINT32)~(B_PCH_SATA_PORT0_IMPLEMENTED +
> B_PCH_SATA_PORT1_IMPLEMENTED),
> (UINT32)(B_PCH_SATA_PORT0_IMPLEMENTED +
> B_PCH_SATA_PORT1_IMPLEMENTED));
> +    }
> +
> +    switch (PortNum)
> +    {
> +      case 0:
> +        DeviceSpeed = *(volatile UINT32 *)(UINTN)(IdeAhciBar +
> R_PCH_SATA_AHCI_P0SSTS);
> +        break;
> +      case 1:
> +        DeviceSpeed = *(volatile UINT32 *)(UINTN)(IdeAhciBar +
> R_PCH_SATA_AHCI_P1SSTS);
> +        break;
> +    }
> +
> +    if (MemBaseAddress) {
> +      gDS->FreeMemorySpace (
> +             MemBaseAddress,
> +             V_PCH_SATA_ABAR_LENGTH
> +             );
> +    }
> +
> +  if (DeviceConfigStatus) {
> +    IdeAhciBar = 0;
> +    MmioWrite32 (
> +      MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_SATA, FunNum,
> R_PCH_SATA_ABAR),
> +      IdeAhciBar
> +      );
> +  }
> +
> +  DeviceSpeed = (UINT8)((DeviceSpeed >> 4) & 0x0F);
> +
> +  return (UINT8)DeviceSpeed;
> +}
> +
> +/**
> +
> +  IDE data filter function.
> +
> +**/
> +void
> +IdeDataFilter (void)
> +{
> +  EFI_STATUS                  Status;
> +  UINTN                       HandleCount;
> +  EFI_HANDLE                  *HandleBuffer;
> +  EFI_DISK_INFO_PROTOCOL      *DiskInfo;
> +  EFI_DEVICE_PATH_PROTOCOL    *DevicePath, *DevicePathNode;
> +  PCI_DEVICE_PATH             *PciDevicePath;
> +  UINTN                       Index;
> +  UINT8                       Index1;
> +  UINT32                      BufferSize;
> +  UINT32                      DriveSize;
> +  UINT32                      IdeChannel;
> +  UINT32                      IdeDevice;
> +  EFI_ATA_IDENTIFY_DATA       *IdentifyDriveInfo;
> +  CHAR16                      *NewString;
> +  CHAR16                      SizeString[20];
> +  STRING_REF                  NameToUpdate;
> +  CHAR8                       StringBuffer[0x100];
> +  UINT32                      DeviceSpeed;
> +  UINTN                       PortNumber;
> +
> +  //
> +  // Assume no line strings is longer than 256 bytes.
> +  //
> +  NewString = AllocateZeroPool (0x100);
> +  PciDevicePath = NULL;
> +
> +  //
> +  // Fill IDE Infomation
> +  //
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gEfiDiskInfoProtocolGuid,
> +                  NULL,
> +                  &HandleCount,
> +                  &HandleBuffer
> +				  );
> +
> +  if (EFI_ERROR (Status)) {
> +    return;
> +  }
> +
> +  for (Index = 0; Index < HandleCount; Index++) {
> +
> +    Status = gBS->HandleProtocol (
> +                    HandleBuffer[Index],
> +                    &gEfiDevicePathProtocolGuid,
> +                    (VOID*)&DevicePath
> +				    );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    DevicePathNode = DevicePath;
> +    while (!IsDevicePathEnd (DevicePathNode) ) {
> +      if  ((DevicePathType (DevicePathNode) == HARDWARE_DEVICE_PATH)
> &&
> +           ( DevicePathSubType (DevicePathNode) == HW_PCI_DP)) {
> +        PciDevicePath = (PCI_DEVICE_PATH *) DevicePathNode;
> +        break;
> +      }
> +      DevicePathNode    = NextDevicePathNode (DevicePathNode);
> +    }
> +
> +    if (PciDevicePath == NULL) {
> +      continue;
> +    }
> +
> +    //
> +    // Check for onboard IDE
> +    //
> +    if (PciDevicePath->Device== PCI_DEVICE_NUMBER_PCH_SATA) {
> +      Status = gBS->HandleProtocol (
> +	                  HandleBuffer[Index],
> +					  &gEfiDiskInfoProtocolGuid,
> +					  (void **)&DiskInfo
> +					  );
> +      ASSERT_EFI_ERROR (Status);
> +
> +      Status = DiskInfo->WhichIde (
> +	                       DiskInfo,
> +                           &IdeChannel,
> +                           &IdeDevice
> +						   );
> +      ASSERT_EFI_ERROR (Status);
> +
> +      IdentifyDriveInfo = AllocatePool (sizeof(EFI_ATA_IDENTIFY_DATA));
> +
> +      BufferSize = sizeof(EFI_ATA_IDENTIFY_DATA);
> +      Status = DiskInfo->Identify (
> +	                       DiskInfo,
> +                           IdentifyDriveInfo,
> +                           &BufferSize
> +                           );
> +      ASSERT_EFI_ERROR(Status);
> +
> +      //
> +      // Onboard SATA Devices
> +      //
> +      if (PciDevicePath->Function == PCI_FUNCTION_NUMBER_PCH_SATA) {
> +        if (IdeChannel == 0 && IdeDevice == 0) {
> +          NameToUpdate = (STRING_REF)STR_SATA0_NAME;
> +        } else if (IdeChannel == 1 && IdeDevice == 0) {
> +          NameToUpdate = (STRING_REF)STR_SATA1_NAME;
> +        } else {
> +          continue;
> +        }
> +      } else {
> +        continue;
> +      }
> +
> +      ZeroMem(StringBuffer, sizeof(StringBuffer));
> +      CopyMem(
> +        StringBuffer,
> +        (CHAR8 *)&IdentifyDriveInfo->ModelName,
> +        sizeof(IdentifyDriveInfo->ModelName)
> +        );
> +      SwapEntries(StringBuffer);
> +      AsciiToUnicode(StringBuffer, NewString);
> +
> +	  //
> +      // Chap it off after 16 characters
> +	  //
> +      NewString[16] = 0;
> +
> +      //
> +      // For HardDisk append the size. Otherwise display atapi
> +      //
> +      if ((IdentifyDriveInfo->config & 0x8000) == 00) {
> +        //
> +        // 48 bit address feature set is supported, get maximum capacity
> +        //
> +        if ((IdentifyDriveInfo->command_set_supported_83 & 0x0400) == 0) {
> +        DriveSize = (((((IdentifyDriveInfo->user_addressable_sectors_hi << 16)
> +
> +                      IdentifyDriveInfo->user_addressable_sectors_lo) / 1000) * 512)
> / 1000);
> +        } else {
> +          DriveSize    = IdentifyDriveInfo-
> >maximum_lba_for_48bit_addressing[0];
> +          for (Index1 = 1; Index1 < 4; Index1++) {
> +            //
> +            // Lower byte goes first: word[100] is the lowest word, word[103] is
> highest
> +            //
> +            DriveSize |= LShiftU64(IdentifyDriveInfo-
> >maximum_lba_for_48bit_addressing[Index1], 16 * Index1);
> +          }
> +          DriveSize = (UINT32) DivU64x32(MultU64x32(DivU64x32(DriveSize,
> 1000), 512), 1000);
> +        }
> +
> +        StrCat (NewString, L"(");
> +        EfiValueToString (SizeString, DriveSize/1000, PREFIX_BLANK, 0);
> +        StrCat (NewString, SizeString);
> +        StrCat (NewString, L".");
> +        EfiValueToString (SizeString, (DriveSize%1000)/100, PREFIX_BLANK, 0);
> +        StrCat (NewString, SizeString);
> +        StrCat (NewString, L"GB");
> +      } else {
> +        StrCat (NewString, L"(ATAPI");
> +      }
> +
> +      //
> +      // Update SPEED.
> +      //
> +      PortNumber = (IdeDevice << 1) + IdeChannel;
> +      DeviceSpeed = GetChipsetSataPortSpeed(PortNumber);
> +
> +      if (DeviceSpeed) {
> +        StrCat (NewString, L"-");
> +        GetDeviceSpeedString( NewString, DeviceSpeed);
> +      }
> +
> +      StrCat (NewString, L")");
> +
> +      HiiSetString(mHiiHandle, NameToUpdate, NewString, NULL);
> +
> +    }
> +  }
> +
> +  if (HandleBuffer != NULL) {
> +    gBS->FreePool (HandleBuffer);
> +  }
> +
> +  gBS->FreePool(NewString);
> +
> +  return;
> +}
> +
> +
> +VOID
> +EFIAPI
> +SetupInfo (void)
> +{
> +  EFI_STATUS                  Status;
> +  UINTN                       VarSize;
> +  EFI_PEI_HOB_POINTERS        GuidHob;
> +
> +  if (mSetupInfoDone) {
> +      return;
> +  }
> +
> +  VarSize = sizeof(SYSTEM_CONFIGURATION);
> +  Status = gRT->GetVariable(
> +                  NORMAL_SETUP_NAME,
> +                  &gEfiNormalSetupGuid,
> +                  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",
> +              &gEfiNormalSetupGuid,
> +              NULL,
> +              &VarSize,
> +              &mSystemConfiguration
> +              );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +  //
> +  // 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);
> +    }
> +  }
> +
> +
> +  PrepareSetupInformation();
> +  UpdateAdditionalInformation ();
> +  UpdatePlatformInformation();
> +  UpdateCPUInformation();
> +  IdeDataFilter();
> +  mSetupInfoDone = TRUE;
> +
> +  return;
> +}
> +
> +
> +#define EFI_SECURE_BOOT_MODE_NAME                   L"SecureBoot"
> +
> +VOID
> +CheckSystemConfigLoad(SYSTEM_CONFIGURATION *SystemConfigPtr)
> +{
> +  EFI_STATUS              Status;
> +  UINT8                   SecureBoot;
> +  UINTN                   DataSize;
> +
> +
> +  DataSize = sizeof(SecureBoot);
> +  Status = gRT->GetVariable (
> +                  EFI_SECURE_BOOT_MODE_NAME,
> +                  &gEfiGlobalVariableGuid,
> +                  NULL,
> +                  &DataSize,
> +                  &SecureBoot
> +                  );
> +
> +  if (EFI_ERROR(Status)) {
> +    SystemConfigPtr->SecureBoot = 0;
> +  } else {
> +    SystemConfigPtr->SecureBoot = SecureBoot;
> +  }
> +}
> +
> +
> +//
> +// "SecureBootEnable" variable for the Secure boot feature enable/disable.
> +//
> +#define EFI_SECURE_BOOT_ENABLE_NAME      L"SecureBootEnable"
> +extern EFI_GUID gEfiSecureBootEnableDisableGuid;
> +
> +
> +VOID
> +CheckSystemConfigSave(SYSTEM_CONFIGURATION *SystemConfigPtr)
> +{
> +  EFI_STATUS              Status;
> +  UINT8                   SecureBootCfg;
> +  BOOLEAN                 SecureBootNotFound;
> +  UINTN                   DataSize;
> +
> +
> +    //
> +    // Secure Boot configuration changes
> +	//
> +    DataSize = sizeof(SecureBootCfg);
> +    SecureBootNotFound = FALSE;
> +    Status = gRT->GetVariable (
> +                    EFI_SECURE_BOOT_ENABLE_NAME,
> +                    &gEfiSecureBootEnableDisableGuid,
> +                    NULL,
> +                    &DataSize,
> +                    &SecureBootCfg
> +                    );
> +
> +    if (EFI_ERROR(Status)) {
> +      SecureBootNotFound = TRUE;
> +    }
> +    if (SecureBootNotFound) {
> +      Status = gRT->GetVariable (
> +                      EFI_SECURE_BOOT_ENABLE_NAME,
> +                      &gEfiSecureBootEnableDisableGuid,
> +                      NULL,
> +                      &DataSize,
> +                      &SecureBootCfg
> +                      );
> +      ASSERT_EFI_ERROR(Status);
> +    }
> +    if ((SecureBootCfg) != SystemConfigPtr->SecureBoot) {
> +      SecureBootCfg = !SecureBootCfg;
> +      Status = gRT->SetVariable (
> +                      EFI_SECURE_BOOT_ENABLE_NAME,
> +                      &gEfiSecureBootEnableDisableGuid,
> +                      EFI_VARIABLE_NON_VOLATILE |
> EFI_VARIABLE_BOOTSERVICE_ACCESS,
> +                      sizeof (UINT8),
> +                      &SecureBootCfg
> +                      );
> +    }
> +
> +}
> +
> +VOID
> +ConfirmSecureBootTest()
> +{
> +
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SouthClusterConfig.
> vfi
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SouthClusterConfig.
> vfi
> new file mode 100644
> index 0000000000..f7ed978c8b
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SouthClusterConfig.
> vfi
> @@ -0,0 +1,933 @@
> +// /** @file
> +//
> +// Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
> +//
> +
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +//
> +
> +//
> +//
> +//
> +// Module Name:
> +//
> +//   SourthClusterConfig.vfi
> +//
> +// Abstract:
> +//
> +//   Driver Setup formset.
> +//
> +//Revision History:
> +//  ------------------------------------------------------------------------------
> +//  Rev   Date<MM/DD/YYYY>    Name    Description
> +//  ------------------------------------------------------------------------------
> +
> +// **/
> +
> +//
> +// South Cluster Configuration Form
> +//
> +
> +form formid = SOUTH_CLUSTER_FORM_ID,
> +  title    = STRING_TOKEN(STR_SOUTH_CLUSTER_TITLE);
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +
> +  //
> +  // Jump to PCIe Configuration Form
> +  //
> +  goto PCIE_DEVICE_OPTIONS_FORM_ID,
> +    prompt = STRING_TOKEN(STR_PCIE_OPTIONS_FORM_TITLE),
> +    help = STRING_TOKEN(STR_PCIE_OPTIONS_FORM_HELP);
> +
> +  //
> +  // Jump to USB Configuration Form
> +  //
> +  goto USB_OPTIONS_FORM_ID,
> +    prompt = STRING_TOKEN(STR_USB_OPTIONS_FORM_TITLE),
> +    help = STRING_TOKEN(STR_USB_OPTIONS_FORM_HELP);
> +  //
> +  // Jump to Azalia Configuration Form
> +  //
> +  goto AZALIA_OPTIONS_FORM_ID,
> +    prompt = STRING_TOKEN(STR_AZALIA_OPTIONS_FORM_TITLE),
> +    help   = STRING_TOKEN(STR_AZALIA_OPTIONS_FORM_HELP);
> +
> +  //
> +  // Jump to Drive Configuration Form
> +  //
> +  goto DRIVE_CONFIGURATION_ID,
> +    prompt = STRING_TOKEN(STR_IDE_FORM_TITLE),
> +    help   = STRING_TOKEN(STR_IDE_FORM_HELP);
> +  //
> +  // Jump to LAN Configuration Form
> +  //
> +
> +  //
> +  // Jump to LPSS Configuration Form
> +  //
> +  goto LPSS_CONFIGURATION_ID,
> +    prompt = STRING_TOKEN(STR_LPSS_SCC_FORM_TITLE),
> +    help   = STRING_TOKEN(STR_LPSS_SCC_FORM_HELP);
> +
> +  //
> +  // Jump to Misc Configuration Form
> +  //
> +  goto MISC_OPTIONS_FORM_ID,
> +    prompt = STRING_TOKEN(STR_MISC_OPTION_FORM_TITLE),
> +    help   = STRING_TOKEN(STR_MISC_OPTION_FORM_HELP);
> +endform;
> +
> +form formid = PCIE_DEVICE_OPTIONS_FORM_ID,
> +
> +  title    = STRING_TOKEN(STR_PCIE_OPTIONS_FORM_TITLE);
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +
> +    oneof varid   = Setup.PcieRootPortSpeed[0],
> +      prompt      = STRING_TOKEN (STR_PCIE_SPEED_PROMPT0),
> +      help        = STRING_TOKEN (STR_PCIE_SPEED_HELP),
> +      option text = STRING_TOKEN (STR_AUTO), value = 0, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +      option text = STRING_TOKEN (STR_GEN1), value = 1, flags =
> RESET_REQUIRED;
> +      option text = STRING_TOKEN (STR_GEN2), value = 2, flags =
> RESET_REQUIRED;
> +    endoneof;
> +    oneof varid   = Setup.PcieRootPortSpeed[1],
> +      prompt      = STRING_TOKEN (STR_PCIE_SPEED_PROMPT1),
> +      help        = STRING_TOKEN (STR_PCIE_SPEED_HELP),
> +      option text = STRING_TOKEN (STR_AUTO), value = 0, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +      option text = STRING_TOKEN (STR_GEN1), value = 1, flags =
> RESET_REQUIRED;
> +      option text = STRING_TOKEN (STR_GEN2), value = 2, flags =
> RESET_REQUIRED;
> +    endoneof;
> +    oneof varid   = Setup.PcieRootPortSpeed[2],
> +      prompt      = STRING_TOKEN (STR_PCIE_SPEED_PROMPT2),
> +      help        = STRING_TOKEN (STR_PCIE_SPEED_HELP),
> +      option text = STRING_TOKEN (STR_AUTO), value = 0, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +      option text = STRING_TOKEN (STR_GEN1), value = 1, flags =
> RESET_REQUIRED;
> +      option text = STRING_TOKEN (STR_GEN2), value = 2, flags =
> RESET_REQUIRED;
> +    endoneof;
> +    oneof varid   = Setup.PcieRootPortSpeed[3],
> +      prompt      = STRING_TOKEN (STR_PCIE_SPEED_PROMPT3),
> +      help        = STRING_TOKEN (STR_PCIE_SPEED_HELP),
> +      option text = STRING_TOKEN (STR_AUTO), value = 0, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +      option text = STRING_TOKEN (STR_GEN1), value = 1, flags =
> RESET_REQUIRED;
> +      option text = STRING_TOKEN (STR_GEN2), value = 2, flags =
> RESET_REQUIRED;
> +    endoneof;
> +  //
> +  //PCIe Port
> +  //
> +  oneof varid  = Setup.IchPciExp[0],
> +    prompt   = STRING_TOKEN(STR_ICH_PCIERP1_PROMPT),
> +    help     = STRING_TOKEN(STR_ICH_PCIERP_HELP),
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |
> RESET_REQUIRED;
> +  endoneof;
> +
> +  suppressif ideqval Setup.IchPciExp[0] == 0x0;
> +    oneof varid    = Setup.IchPciExp[1],
> +      prompt   = STRING_TOKEN(STR_ICH_PCIERP2_PROMPT),
> +      help     = STRING_TOKEN(STR_ICH_PCIERP_HELP),
> +      option text = STRING_TOKEN(STR_ENABLE), value=1, flags=
> RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_DISABLE), value=0, flags= DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +    endoneof;
> +  endif;
> +
> +  suppressif NOT ideqval Setup.IchPciExp[0] == 0x0;
> +  text
> +    help   = STRING_TOKEN(STR_ICH_PCIERP_HELP),
> +    text   = STRING_TOKEN(STR_ICH_PCIERP2_PROMPT),
> +    text   = STRING_TOKEN(STR_ICH_PCIERP_DISABLE_HELP),
> +    flags  = 0,
> +    key    = 0;
> +  endif;
> +
> +  suppressif ideqval Setup.IchPciExp[0] == 0x0;
> +    oneof varid    = Setup.IchPciExp[2],
> +      prompt   = STRING_TOKEN(STR_ICH_PCIERP3_PROMPT),
> +      help     = STRING_TOKEN(STR_ICH_PCIERP_HELP),
> +      option text = STRING_TOKEN(STR_ENABLE), value=1, flags=DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |
> RESET_REQUIRED;
> +    endoneof;
> +  endif;
> +
> +  suppressif NOT ideqval Setup.IchPciExp[0] == 0x0;
> +  text
> +    help   = STRING_TOKEN(STR_ICH_PCIERP_HELP),
> +    text   = STRING_TOKEN(STR_ICH_PCIERP3_PROMPT),
> +    text   = STRING_TOKEN(STR_ICH_PCIERP_DISABLE_HELP),
> +    flags  = 0,
> +    key    = 0;
> +  endif;
> +
> +  suppressif ideqval Setup.IchPciExp[0] == 0x0;
> +    oneof varid    = Setup.IchPciExp[3],
> +      prompt   = STRING_TOKEN(STR_ICH_PCIERP4_PROMPT),
> +      help     = STRING_TOKEN(STR_ICH_PCIERP_HELP),
> +      option text = STRING_TOKEN(STR_ENABLE), value=1, flags= DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_DISABLE), value=0, flags= 0 |
> RESET_REQUIRED;
> +    endoneof;
> +  endif;
> +
> +  suppressif NOT ideqval Setup.IchPciExp[0] == 0x0;
> +  text
> +    help   = STRING_TOKEN(STR_ICH_PCIERP_HELP),
> +    text   = STRING_TOKEN(STR_ICH_PCIERP4_PROMPT),
> +    text   = STRING_TOKEN(STR_ICH_PCIERP_DISABLE_HELP),
> +    flags  = 0,
> +    key    = 0;
> +  endif;
> +
> +
> +endform;
> +
> +form formid = USB_OPTIONS_FORM_ID,
> +
> +  title    = STRING_TOKEN(STR_USB_OPTIONS_FORM_TITLE);
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +
> +  oneof   varid   = Setup.UsbAutoMode,
> +    questionid  = 0x123A,
> +    prompt      = STRING_TOKEN(STR_USB_AUTO_MODE_PROMPT),
> +    help        = STRING_TOKEN(STR_USB_AUTO_MODE_HELP),
> +    flags       = INTERACTIVE,
> +    option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +  endoneof;
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +  //
> +  //XHCI support
> +  //
> +  grayoutif ideqval Setup.UsbAutoMode == 0x1;
> +    grayoutif ideqval Setup.PchUsb20 == 0x1;
> +      oneof   varid   = Setup.UsbXhciSupport,
> +        questionid  = 0x123B,
> +        prompt      = STRING_TOKEN(STR_USB_XHCI_SUPPORT_PROMPT),
> +        help        = STRING_TOKEN(STR_USB_XHCI_SUPPORT_HELP),
> +        flags       = INTERACTIVE,
> +        option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT
> | MANUFACTURING | RESET_REQUIRED;
> +        option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +      endoneof;
> +
> +      suppressif ideqval Setup.UsbXhciSupport == 0x0;
> +        oneof   varid   = Setup.Hsic0,
> +          prompt      = STRING_TOKEN(STR_USB_HSIC_0_PROMPT),
> +          help        = STRING_TOKEN(STR_USB_HSIC_0_HELP),
> +          option text = STRING_TOKEN(STR_ENABLE), value = 1, flags =
> RESET_REQUIRED;
> +          option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> DEFAULT | MANUFACTURING | RESET_REQUIRED;
> +        endoneof;
> +      endif;
> +
> +      oneof varid   = Setup.PchUsb30Mode,
> +        prompt      = STRING_TOKEN(STR_PCH_USB30_MODE_PROMPT),
> +        help        = STRING_TOKEN(STR_PCH_USB30_MODE_HELP),
> +        option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT
> | MANUFACTURING |RESET_REQUIRED;
> +        option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +      endoneof;
> +
> +  oneof   varid   = Setup.UsbXhciLpmSupport,
> +        prompt      = STRING_TOKEN(STR_USB_XHCI_LPM_SUPPORT_PROMPT),
> +        help        = STRING_TOKEN(STR_USB_XHCI_LPM_SUPPORT_HELP),
> +
> +        option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT
> | MANUFACTURING | RESET_REQUIRED;
> +        option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +
> +      endoneof;
> +    endif;
> +  endif;
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +
> +  oneof varid   = Setup.PchUsbOtg,
> +    prompt      = STRING_TOKEN(STR_PCH_USB_OTG_PROMPT),
> +    help        = STRING_TOKEN(STR_PCH_USB_OTG_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT |
> MANUFACTURING |RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_PCI_MODE_STRING), value = 1, flags =
> RESET_REQUIRED;
> +  endoneof;
> +
> +  oneof varid   = Setup.PchUsbVbusOn,
> +    prompt      = STRING_TOKEN(STR_PCH_USB_VBUS_PROMPT),
> +    help        = STRING_TOKEN(STR_PCH_USB_VBUS_HELP),
> +    option text = STRING_TOKEN(STR_OFF), value = 0, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ON), value = 1, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_AUTO), value = 2, flags =
> RESET_REQUIRED;
> +  endoneof;
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +
> +  //
> +  //EHCI support
> +  //
> +  grayoutif ideqval Setup.UsbAutoMode == 0x1;
> +    grayoutif ideqval Setup.UsbXhciSupport == 0x1;
> +      oneof   varid   = Setup.PchUsb20,
> +        questionid  = 0x123C,
> +        prompt   = STRING_TOKEN(STR_PCH_USB21_PROMPT),
> +        help     = STRING_TOKEN(STR_PCH_USB2_HELP),
> +        flags    = INTERACTIVE,
> +        option text = STRING_TOKEN(STR_ENABLE), value = 1, flags =
> RESET_REQUIRED;
> +        option text = STRING_TOKEN(STR_DISABLE), value= 0, flags= DEFAULT |
> MANUFACTURING |RESET_REQUIRED;
> +      endoneof;
> +
> +      oneof varid  = Setup.PchUsbRmh,
> +        prompt   = STRING_TOKEN(STR_PCH_USBRMH_PROMPT),
> +        help     = STRING_TOKEN(STR_PCH_USBRMH_HELP),
> +        option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +        option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT
> | MANUFACTURING | RESET_REQUIRED;
> +      endoneof;
> +
> +      oneof varid  = Setup.PchEhciDebug,
> +        prompt   = STRING_TOKEN(STR_PCH_USB_EHCIDEBUG_PROMPT),
> +        help     = STRING_TOKEN(STR_PCH_USB_EHCIDEBUG_HELP),
> +        option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT
> | MANUFACTURING | RESET_REQUIRED;
> +        option text = STRING_TOKEN(STR_ENABLE),  value = 1, flags =
> RESET_REQUIRED;
> +      endoneof;
> +
> +      suppressif TRUE;
> +        oneof varid   = Setup.EhciPllCfgEnable,
> +        prompt      = STRING_TOKEN(STR_EHCI_PLL_CFG_PROMPT),
> +        help        = STRING_TOKEN(STR_EHCI_PLL_CFG_RTD3_DIS_HELP),
> +        option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT
> | MANUFACTURING | RESET_REQUIRED;
> +        option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +        endoneof;
> +      endif;
> +    endif;
> +
> +    //
> +    // Usb ports per-port disable control enable
> +    //
> +    oneof varid   = Setup.PchUsbPerPortCtl,
> +      prompt      = STRING_TOKEN(STR_PCH_USB_PER_PORT_PROMPT),
> +      help        = STRING_TOKEN(STR_PCH_USB_PER_PORT_HELP),
> +      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +    endoneof;
> +
> +    suppressif ideqval Setup.PchUsbPerPortCtl == 0x0;
> +      oneof varid  = Setup.PchUsbPort[0],
> +      prompt   = STRING_TOKEN(STR_PCH_USB_PORT0_PROMPT),
> +      help     = STRING_TOKEN(STR_PCH_USB_PORT_DIS_HELP),
> +      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +      endoneof;
> +
> +      oneof varid  = Setup.PchUsbPort[1],
> +      prompt   = STRING_TOKEN(STR_PCH_USB_PORT1_PROMPT),
> +      help     = STRING_TOKEN(STR_PCH_USB_PORT_DIS_HELP),
> +      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +      endoneof;
> +
> +      oneof varid  = Setup.PchUsbPort[2],
> +      prompt   = STRING_TOKEN(STR_PCH_USB_PORT2_PROMPT),
> +      help     = STRING_TOKEN(STR_PCH_USB_PORT_DIS_HELP),
> +      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +      endoneof;
> +
> +      oneof varid  = Setup.PchUsbPort[3],
> +      prompt   = STRING_TOKEN(STR_PCH_USB_PORT3_PROMPT),
> +      help     = STRING_TOKEN(STR_PCH_USB_PORT_DIS_HELP),
> +      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +      endoneof;
> +    endif;
> +
> +
> +  endif;
> +
> +endform;
> +
> +//
> +// SATA Controller
> +//
> +form formid = DRIVE_CONFIGURATION_ID,
> +
> +  title    = STRING_TOKEN(STR_IDE_FORM_TITLE);
> +
> +  //
> +  // Title on Drive Configuration Page
> +  //
> +  text
> +    help   = STRING_TOKEN(STR_NULL_STRING),
> +    text   = STRING_TOKEN(STR_IDE_FORM_TITLE),
> +    text   = STRING_TOKEN(STR_NULL_STRING),
> +    flags  = 0,
> +    key    = 0;
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +
> +  subtitle text = STRING_TOKEN(STR_CHIPSET_SATA_STRING);
> +
> +  oneof varid   = Setup.Sata,
> +    prompt      = STRING_TOKEN(STR_SATA_PROMPT),
> +    help        = STRING_TOKEN(STR_SATA_HELP),
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |
> RESET_REQUIRED;
> +  endoneof;
> +
> +    oneof varid   = Setup.SataTestMode,
> +      prompt      = STRING_TOKEN(STR_SATA_TEST_MODE_PROMPT),
> +      help        = STRING_TOKEN(STR_SATA_TEST_MODE_HELP),
> +      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags =
> RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +    endoneof;
> +
> +  suppressif ideqval Setup.Sata == 0x00;
> +    oneof varid   = Setup.SataType,
> +      prompt      = STRING_TOKEN(STR_SATA_TYPE_PROMPT),
> +      help        = STRING_TOKEN(STR_SATA_TYPE_HELP1),
> +      option text = STRING_TOKEN(STR_SATA_IDE), value = 0, flags =
> RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_SATA_AHCI), value = 1, flags =
> DEFAULT | MANUFACTURING | RESET_REQUIRED;
> +    endoneof;
> +
> +    text
> +      help   = STRING_TOKEN(STR_NULL_STRING),
> +      text   = STRING_TOKEN(STR_SATA0_STRING),
> +      text   = STRING_TOKEN(STR_SATA0_NAME),
> +      flags  = 0,
> +      key    = 0;
> +
> +    text
> +      help   = STRING_TOKEN(STR_NULL_STRING),
> +      text   = STRING_TOKEN(STR_SATA1_STRING),
> +      text   = STRING_TOKEN(STR_SATA1_NAME),
> +      flags  = 0,
> +      key    = 0;
> +
> +    suppressif ideqval Setup.SataType == 0x0;
> +      oneof varid   = Setup.Sata0HotPlugCap,
> +        prompt      = STRING_TOKEN(STR_SATA0_HOTPLUG_CAP_PROMPT),
> +        help        = STRING_TOKEN(STR_SATA_HOTPLUG_CAP_HELP),
> +        option text = STRING_TOKEN(STR_ENABLE), value= 1, flags=DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +        option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |
> RESET_REQUIRED;
> +      endoneof;
> +
> +      oneof varid   = Setup.Sata1HotPlugCap,
> +        prompt      = STRING_TOKEN(STR_SATA1_HOTPLUG_CAP_PROMPT),
> +        help        = STRING_TOKEN(STR_SATA_HOTPLUG_CAP_HELP),
> +        option text = STRING_TOKEN(STR_ENABLE), value= 1, flags=DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +        option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |
> RESET_REQUIRED;
> +      endoneof;
> +    endif;
> +
> +  endif;  //SATA enable
> +
> +endform;
> +
> +form formid = LPSS_CONFIGURATION_ID,
> +
> +  title    = STRING_TOKEN(STR_LPSS_SCC_FORM_TITLE);
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +  oneof varid   = Setup.LpssPciModeEnabled,
> +    prompt      = STRING_TOKEN(STR_LPSS_PCI_PROMPT),
> +    help        = STRING_TOKEN(STR_LPSS_PCI_HELP),
> +    option text = STRING_TOKEN(STR_ACPI_MODE), value=0, flags=DEFAULT
> | MANUFACTURING | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_PCI_MODE), value=1, flags=0|
> RESET_REQUIRED;
> +  endoneof;
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +
> +  subtitle text = STRING_TOKEN(STR_SCC_SETTING_SUBTITLE);
> +  oneof varid   = Setup.eMMCBootMode,
> +    prompt      = STRING_TOKEN(STR_EMMC_BOOT_PROMPT),
> +    help        = STRING_TOKEN(STR_EMMC_BOOT_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_AUTO_DETECT), value=1,
> flags=DEFAULT | MANUFACTURING | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_EMMC_BOOT_41), value=2, flags=0 |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_EMMC_BOOT_45), value=3, flags=0 |
> RESET_REQUIRED;
> +  endoneof;
> +
> +
> +
> +   oneof varid   = Setup.SecureErase,
> +    questionid  = 0x1240,
> +    prompt      = STRING_TOKEN(STR_SECURE_ERASE_PROMPT),
> +    help        = STRING_TOKEN(STR_SECURE_ERASE_HELP),
> +    flags       = INTERACTIVE,
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags= DEFAULT
> |MANUFACTURING | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=
> RESET_REQUIRED;
> +  endoneof;
> +
> +
> +
> +   subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +grayoutif NOT ideqval Setup.eMMCBootMode == 0x3;
> +  oneof varid   = Setup.LpsseMMC45Enabled,
> +    prompt      = STRING_TOKEN(STR_SCC_EMMC45_PROMPT),
> +    help        = STRING_TOKEN(STR_SCC_EMMC45_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |
> MANUFACTURING | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=DEFAULT |
> RESET_REQUIRED;
> +  endoneof;
> +  oneof varid   = Setup.LpsseMMC45DDR50Enabled,
> +    prompt      = STRING_TOKEN(STR_SCC_EMMC45_DDR50_PROMPT),
> +    help        = STRING_TOKEN(STR_SCC_EMMC45_DDR50_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |
> MANUFACTURING | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=DEFAULT |
> RESET_REQUIRED;
> +  endoneof;
> +    oneof varid   = Setup.LpsseMMC45HS200Enabled,
> +    prompt      = STRING_TOKEN(STR_SCC_EMMC45_HS200_PROMPT),
> +    help        = STRING_TOKEN(STR_SCC_EMMC45_HS200_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |
> MANUFACTURING | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=DEFAULT|
> RESET_REQUIRED;
> +  endoneof;
> +
> +  grayoutif ideqval Setup.LpsseMMC45DDR50Enabled == 0x1;
> +  oneof varid  = Setup.LpsseMMC45RetuneTimerValue,
> +    prompt = STRING_TOKEN(STR_SCC_EMMC45_RE_TUNE_TIMER_VALUE),
> +    help   =
> STRING_TOKEN(STR_SCC_EMMC45_RE_TUNE_TIMER_VALUE_HELP),
> +    option text = STRING_TOKEN(STR_EMMC45_TIMER_0), value = 0, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_EMMC45_TIMER_1), value =1, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_EMMC45_TIMER_2), value =2, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_EMMC45_TIMER_3), value =3, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_EMMC45_TIMER_4), value =4, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_EMMC45_TIMER_5), value =5, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_EMMC45_TIMER_6), value =6, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_EMMC45_TIMER_7), value =7, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_EMMC45_TIMER_8), value =8, flags =
> MANUFACTURING| DEFAULT|RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_EMMC45_TIMER_9), value =9, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_EMMC45_TIMER_10), value =10, flags
> = RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_EMMC45_TIMER_11), value =11, flags
> = RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_EMMC45_TIMER_12), value =12, flags
> = RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_EMMC45_TIMER_13), value =13, flags
> = RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_EMMC45_TIMER_14), value =14, flags
> = RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_EMMC45_TIMER_15), value =15, flags
> = RESET_REQUIRED;
> +  endoneof;
> +  endif;    // grayoutif ideqval Setup.LpsseMMC45DDR50Enabled == 0x1;
> + endif;     // grayoutif NOT ideqval Setup.eMMCBootMode == 0x1;
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +  oneof varid   = Setup.LpssSdioEnabled,
> +    prompt      = STRING_TOKEN(STR_SCC_SDIO_PROMPT),
> +    help        = STRING_TOKEN(STR_SCC_SDIO_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +
> +  oneof varid   = Setup.LpssSdcardEnabled,
> +    prompt      = STRING_TOKEN(STR_SCC_SDCARD_PROMPT),
> +    help        = STRING_TOKEN(STR_SCC_SDCARD_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=
> DEFAULT|MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +
> +
> +grayoutif NOT ideqval Setup.LpssSdcardEnabled == 0x1;
> +  grayoutif ideqval Setup.LpssSdCardDDR50Enabled == 0x1;
> +  oneof varid   = Setup.LpssSdCardSDR25Enabled,
> +    prompt      = STRING_TOKEN(STR_SCC_SD_SDR25_PROMPT),
> +    help        = STRING_TOKEN(STR_SCC_SD_SDR25_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=0 |
> RESET_REQUIRED;
> +  endoneof;
> +  endif; // grayoutif ideqval Setup.LpsseMMC45DDR50Enabled == 0x1;
> +
> +  grayoutif ideqval Setup.LpssSdCardSDR25Enabled == 0x1;
> +    oneof varid   = Setup.LpssSdCardDDR50Enabled,
> +    prompt      = STRING_TOKEN(STR_SCC_SD_DDR50_PROMPT),
> +    help        = STRING_TOKEN(STR_SCC_SD_DDR50_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=0 |
> RESET_REQUIRED;
> +    endoneof;
> +  endif; // grayoutif ideqval Setup.LpssSdCardSDR25Enabled == 0x1;
> +
> +  oneof varid   = Setup.SdCardRemovable,
> +    prompt      = STRING_TOKEN(STR_SCC_SDCARD_REMOVABILITY),
> +    help        = STRING_TOKEN(STR_SCC_SDCARD_REMOVABILITY_HELP),
> +    option text = STRING_TOKEN(STR_SCC_SDCARD_NON_REMOVABLE),
> value=0, flags=0 | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_SCC_SDCARD_REMOVABLE), value=1,
> flags=DEFAULT | MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +
> +endif;     // grayoutif NOT ideqval Setup.LpssSdcardEnabled == 0x1;
> +
> +
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +
> +  subtitle text = STRING_TOKEN(STR_LPSS1_SETTING_SUBTITLE);
> +
> +  oneof varid   = Setup.LpssDma0Enabled,
> +    prompt      = STRING_TOKEN(STR_LPSS_DMA1_PROMPT),
> +    help        = STRING_TOKEN(STR_LPSS_DMA1_HELP),
> +    flags       = INTERACTIVE,
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +
> +  grayoutif ideqval Setup.LpssDma0Enabled == 0x00;
> +  oneof varid   = Setup.LpssHsuart0Enabled,
> +    prompt      = STRING_TOKEN(STR_LPSS_HSUART1_PROMPT),
> +    help        = STRING_TOKEN(STR_LPSS_HSUART1_HELP_ENBDT_DEV_LIST),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=
> MANUFACTURING  | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= 0 | DEFAULT
> | RESET_REQUIRED;
> +  endoneof;
> +  endif;
> +
> +  //Add control flow
> +  grayoutif ideqval Setup.LpssHsuart0Enabled == 0x00;
> +  oneof varid   = Setup.LpssHsuart0FlowControlEnabled,
> +    prompt      =
> STRING_TOKEN(STR_LPSS_HSUART1_FLOWCONTROL_PROMPT),
> +    help        = STRING_TOKEN(STR_LPSS_HSUART1_HELP_ENBDT_DEV_LIST),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |DEFAULT |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=
> MANUFACTURING  | RESET_REQUIRED;
> +  endoneof;
> +  endif;
> +
> +  grayoutif ideqval Setup.LpssDma0Enabled == 0x00;
> +  oneof varid   = Setup.LpssHsuart1Enabled,
> +    prompt      = STRING_TOKEN(STR_LPSS_HSUART2_PROMPT),
> +    help        = STRING_TOKEN(STR_LPSS_HSUART2_HELP_ENBDT_DEV_LIST),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0,
> flags=MANUFACTURING  | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= 0 | DEFAULT
> | RESET_REQUIRED;
> +  endoneof;
> +  endif;
> +
> +  //Add control flow
> +  grayoutif ideqval Setup.LpssHsuart1Enabled == 0x00;
> +  oneof varid   = Setup.LpssHsuart1FlowControlEnabled,
> +    prompt      =
> STRING_TOKEN(STR_LPSS_HSUART2_FLOWCONTROL_PROMPT),
> +    help        = STRING_TOKEN(STR_LPSS_HSUART1_HELP_ENBDT_DEV_LIST),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |DEFAULT |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=
> MANUFACTURING  | RESET_REQUIRED;
> +  endoneof;
> +  endif;
> +
> +
> +  grayoutif ideqval Setup.LpssDma0Enabled == 0x00;
> +  oneof varid   = Setup.LpssPwm0Enabled,
> +    prompt      = STRING_TOKEN(STR_PWM1_PROMPT),
> +    help        = STRING_TOKEN(STR_PWM1_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0,
> flags=MANUFACTURING  | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= 0 | DEFAULT
> | RESET_REQUIRED;
> +  endoneof;
> +  endif;
> +
> +  grayoutif ideqval Setup.LpssDma0Enabled == 0x00;
> +  oneof varid   = Setup.LpssPwm1Enabled,
> +    prompt      = STRING_TOKEN(STR_PWM2_PROMPT),
> +    help        = STRING_TOKEN(STR_PWM2_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0,
> flags=MANUFACTURING  | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= 0 | DEFAULT
> | RESET_REQUIRED;
> +  endoneof;
> +  endif;
> +
> +  grayoutif ideqval Setup.LpssDma0Enabled == 0x00;
> +  oneof varid   = Setup.LpssSpiEnabled,
> +    prompt      = STRING_TOKEN(STR_LPSS_SPI_PROMPT),
> +    help        = STRING_TOKEN(STR_LPSS_SPI_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0,
> flags=MANUFACTURING  | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= 0 |DEFAULT |
> RESET_REQUIRED;
> +  endoneof;
> +  endif;
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +
> +  subtitle text = STRING_TOKEN(STR_LPSS2_SETTING_SUBTITLE);
> +
> +  oneof varid   = Setup.LpssDma1Enabled,
> +    prompt      = STRING_TOKEN(STR_LPSS_DMA2_PROMPT),
> +    help        = STRING_TOKEN(STR_LPSS_DMA2_HELP),
> +    flags       = INTERACTIVE,
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0
> |RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +
> +/*
> +  grayoutif ideqval Setup.LpssDma1Enabled == 0x00;
> +  oneof varid   = Setup.LpssI2C0Enabled,
> +    prompt      = STRING_TOKEN(STR_LPSS_I2C1_PROMPT),
> +    help        = STRING_TOKEN(STR_LPSS_I2C1_HELP_ENBDT_DEV_LIST),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |DEFAULT
> |RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=
> MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +  endif;
> +
> +
> +  grayoutif ideqval Setup.LpssDma1Enabled == 0x00;
> +  oneof varid   = Setup.LpssI2C1Enabled,
> +    prompt      = STRING_TOKEN(STR_LPSS_I2C2_PROMPT),
> +    help        = STRING_TOKEN(STR_LPSS_I2C2_HELP_ENBDT_DEV_LIST),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |DEFAULT |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=
> MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +  endif;
> +
> +  grayoutif ideqval Setup.LpssDma1Enabled == 0x00;
> +  oneof varid   = Setup.LpssI2C2Enabled,
> +    prompt      = STRING_TOKEN(STR_LPSS_I2C3_PROMPT),
> +    help        = STRING_TOKEN(STR_LPSS_I2C3_HELP_ENBDT_DEV_LIST),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |DEFAULT |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=
> MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +  endif;
> +
> +  grayoutif ideqval Setup.LpssDma1Enabled == 0x00;
> +  oneof varid   = Setup.LpssI2C3Enabled,
> +    prompt      = STRING_TOKEN(STR_LPSS_I2C4_PROMPT),
> +    help        = STRING_TOKEN(STR_LPSS_I2C4_HELP_ENBDT_DEV_LIST),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |DEFAULT |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=
> MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +  endif;
> +
> +  grayoutif ideqval Setup.LpssDma1Enabled == 0x00;
> +  oneof varid   = Setup.LpssI2C4Enabled,
> +    prompt      = STRING_TOKEN(STR_LPSS_I2C5_PROMPT),
> +    help        = STRING_TOKEN(STR_LPSS_I2C5_HELP_ENBDT_DEV_LIST),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0 |DEFAULT |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=
> MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +  endif;
> +*/
> +  grayoutif ideqval Setup.LpssDma1Enabled == 0x00;
> +  oneof varid   = Setup.LpssI2C5Enabled,
> +    prompt      = STRING_TOKEN(STR_LPSS_I2C6_PROMPT),
> +    help        = STRING_TOKEN(STR_LPSS_I2C6_HELP_ENBDT_DEV_LIST),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0
> |RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags=  DEFAULT
> |MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +  endif;
> +
> +  grayoutif ideqval Setup.LpssDma1Enabled == 0x00;
> +  oneof varid   = Setup.LpssI2C6Enabled,
> +    prompt      = STRING_TOKEN(STR_LPSS_I2C7_PROMPT),
> +    help        = STRING_TOKEN(STR_LPSS_I2C7_HELP_ENBDT_DEV_LIST),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=0
> |RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=1, flags= DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +  endif;
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +
> +  subtitle text = STRING_TOKEN(STR_I2C_DEVICE_SETTING_SUBTITLE);
> +
> +  oneof varid   = Setup.I2CTouchAd,
> +    prompt      = STRING_TOKEN(STR_I2C_TOUCH_PROMPT),
> +    help        = STRING_TOKEN(STR_I2C_TOUCH_HELP),
> +    option text = STRING_TOKEN(STR_AUTO), value=0, flags=DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_I2C_FVP), value=0x4B, flags=0 |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_I2C_FFRD), value=0x4A, flags=0 |
> RESET_REQUIRED;
> +  endoneof;
> +
> + subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +
> + oneof varid = Setup.SAR1,
> +    prompt         = STRING_TOKEN(STR_SAR_SENSOR_PROMPT),
> +    help           = STRING_TOKEN(STR_SAR_SENSOR_HELP),
> +    option text    = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT |
> MANUFACTURING |RESET_REQUIRED;
> +    option text    = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +  endoneof;
> +endform;
> +
> +
> +//
> +//LAN Controller
> +//
> +form formid = LAN_OPTIONS_FORM_ID,
> +
> +  title    = STRING_TOKEN(STR_LAN_OPTIONS_FORM_TITLE);
> +
> +  subtitle text = STRING_TOKEN(STR_LAN_OPTIONS_FORM_TITLE);
> +
> +  oneof varid = Setup.Lan,
> +    prompt   = STRING_TOKEN(STR_PCH_LAN_CONTROLLER),
> +    help     = STRING_TOKEN(STR_PCH_LAN_CONTROLLER_HELP),
> +    option text = STRING_TOKEN(STR_ENABLE), value = 1, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +
> +  suppressif ideqval Setup.Lan == 0;
> +    oneof varid = Setup.WakeOnLanS5,
> +      prompt   = STRING_TOKEN(STR_PCH_LAN_WOL_PROMPT),
> +      help     = STRING_TOKEN(STR_PCH_LAN_WOL_HELP),
> +      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags =  DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +    endoneof;
> +
> +    oneof varid = Setup.SlpLanLowDc,
> +      prompt   = STRING_TOKEN(STR_PCH_SLP_LAN_LOW_DC_PROMPT),
> +      help     = STRING_TOKEN(STR_PCH_SLP_LAN_LOW_DC_HELP),
> +      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags =  DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +    endoneof;
> +
> +    oneof varid = Setup.BootNetwork,
> +      prompt   = STRING_TOKEN(STR_PCH_PXEROM_CONTROL),
> +      help     = STRING_TOKEN(STR_PCH_PXEROM_CONTROL_HELP),
> +      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags =
> RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT |
> MANUFACTURING |RESET_REQUIRED;
> +    endoneof;
> +  endif;
> +
> +endform;
> +
> +//
> +// Azalia Configuration
> +//
> +form formid = AZALIA_OPTIONS_FORM_ID,
> +
> +  title    = STRING_TOKEN(STR_AZALIA_OPTIONS_FORM_TITLE);
> +
> +  subtitle text = STRING_TOKEN(STR_AZALIA_OPTIONS_FORM_TITLE);
> +  oneof varid   = Setup.Lpe,
> +      prompt      = STRING_TOKEN(STR_LPE_PROMPT),
> +      help        = STRING_TOKEN(STR_LPE_HELP),
> +      option text = STRING_TOKEN(STR_DISABLE), value=0, flags=DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_LPE_PCI_MODE), value=1, flags=0 |
> RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_LPE_ACPI_MODE), value=2, flags=0 |
> RESET_REQUIRED;
> +  endoneof;
> +
> +  grayoutif NOT ideqval Setup.Lpe == 0x2;
> +  oneof varid   = Setup.LpeAudioReportedByDSDT,
> +      prompt      = STRING_TOKEN(STR_LPE_REPORTED_BY_DSDT_PROMPT),
> +      help        = STRING_TOKEN(STR_LPE_REPORTED_BY_DSDT_HELP),
> +      option text = STRING_TOKEN(STR_DISABLE), value=0, flags=DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_ENABLE), value=1,
> flags=RESET_REQUIRED;
> +  endoneof;
> +  endif;
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +  suppressif ideqval Setup.AzaliaDs == 0x1;
> +    oneof varid  = Setup.PchAzalia,
> +      prompt   = STRING_TOKEN(STR_PCH_AZALIA_PROMPT),
> +      help     = STRING_TOKEN(STR_PCH_AZALIA_HELP),
> +      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = 0 |
> RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +    endoneof;
> +  endif;
> +
> +  suppressif ideqval Setup.AzaliaDs == 0x0;
> +    text
> +      help   = STRING_TOKEN(STR_PCH_AZALIA_DS_SUPPORT),
> +      text   = STRING_TOKEN(STR_PCH_AZALIA_PROMPT),
> +      text   = STRING_TOKEN(STR_ENABLE),
> +      flags  = 0,
> +      key    = 0;
> +  endif;
> +
> +  suppressif ideqval Setup.PchAzalia == 0x0;
> +    oneof varid  = Setup.AzaliaVCiEnable,
> +      prompt   = STRING_TOKEN(STR_AZALIA_VC_PROMPT),
> +      help     = STRING_TOKEN(STR_AZALIA_VC_HELP),
> +      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +    endoneof;
> +  endif;
> +
> +  suppressif ideqval Setup.PchAzalia == 0x0;
> +    oneof varid  = Setup.AzaliaDs,
> +      prompt   = STRING_TOKEN(STR_AZALIA_DS_PROMPT),
> +      help     = STRING_TOKEN(STR_AZALIA_DS_HELP),
> +      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags =
> RESET_REQUIRED;
> +    endoneof;
> +  endif;
> +
> +  suppressif ideqval Setup.PchAzalia == 0x0;
> +    oneof varid  = Setup.AzaliaPme,
> +      prompt   = STRING_TOKEN(STR_AZALIA_PME_PROMPT),
> +      help     = STRING_TOKEN(STR_AZALIA_PME_HELP),
> +      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +    endoneof;
> +
> +    oneof varid  = Setup.HdmiCodec,
> +      prompt   = STRING_TOKEN(STR_HDMI_CODEC_PROMPT),
> +      help     = STRING_TOKEN(STR_HDMI_CODEC_HELP),
> +      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +    endoneof;
> +  endif;
> +
> +endform;
> +
> +//
> +//  Misc Configuration
> +//
> +form formid = MISC_OPTIONS_FORM_ID,
> +
> +  title    = STRING_TOKEN(STR_MISC_OPTION_FORM_TITLE);
> +
> +  subtitle text = STRING_TOKEN(STR_MISC_OPTION_FORM_TITLE);
> +  //
> +  // HPET Disable/Enable
> +  //
> +  oneof   varid   = Setup.Hpet,
> +    prompt      = STRING_TOKEN(STR_HPET_PROMPT),
> +    help        = STRING_TOKEN(STR_HPET_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0x00,
> flags=RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value=0x01, flags=DEFAULT |
> RESET_REQUIRED;
> +  endoneof;
> +
> +  oneof varid  = Setup.StateAfterG3,
> +     prompt   = STRING_TOKEN(STR_STATE_AFTER_G3),
> +     help     = STRING_TOKEN(STR_STATE_AFTER_G3_HELP),
> +     option text = STRING_TOKEN(STR_S0_AFTER_G3_STRING), value = 0,
> flags = DEFAULT | RESET_REQUIRED;
> +     option text = STRING_TOKEN(STR_S5_AFTER_G3_STRING), value = 1,
> flags = MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +
> +  oneof varid  = Setup.EnableClockSpreadSpec,
> +     prompt   = STRING_TOKEN(STR_CLOCK_SPREAD_SPEC_ENABLE),
> +     help     = STRING_TOKEN(STR_CLOCK_SPREAD_SPEC_ENABLE_HELP),
> +     option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +     option text = STRING_TOKEN(STR_ENABLE), value = 1, flags =
> RESET_REQUIRED;
> +  endoneof;
> +
> +
> +  oneof varid  = Setup.UartInterface,
> +    prompt   = STRING_TOKEN(STR_PCH_UART_SELECT),
> +    help     = STRING_TOKEN(STR_PCH_UART_SELECT_HELP),
> +    option text = STRING_TOKEN(STR_UART_SELECT_PCU), value = 0, flags =
> DEFAULT | MANUFACTURING | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_UART_SELECT_SIO), value = 1, flags =
> RESET_REQUIRED;
> +  endoneof;
> +
> +  suppressif ideqval Setup.LpssHsuart0Enabled == 1 OR ideqval
> Setup.UartInterface == 1;
> +    oneof varid  = Setup.PcuUart1,
> +      prompt   = STRING_TOKEN(STR_PCU_UART_A),
> +      help     = STRING_TOKEN(STR_PCU_UART_A_HELP),
> +      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +    endoneof;
> +  endif;
> +
> +  oneof varid = Setup.SpiRwProtect,
> +    prompt         = STRING_TOKEN(STR_PCH_SPI_WP_PROMPT),
> +    help           = STRING_TOKEN(STR_PCH_SPI_WP_HELP),
> +    option text    = STRING_TOKEN(STR_PCH_SPI_WP_DISABLE), value = 0,
> flags = DEFAULT | MANUFACTURING |RESET_REQUIRED;
> +    option text    = STRING_TOKEN(STR_PCH_SPI_WP_ENABLE), value = 1,
> flags = RESET_REQUIRED;
> +  endoneof;
> +
> +  oneof varid = Setup.MmioSize,
> +    prompt         = STRING_TOKEN(STR_MMIO_PROMPT),
> +    help           = STRING_TOKEN(STR_MMIO_HELP),
> +    option text    = STRING_TOKEN(STR_MMIO_0_75G_STRING), value = 0,
> flags = RESET_REQUIRED;
> +    option text    = STRING_TOKEN(STR_MMIO_1G_STRING), value = 1, flags
> = RESET_REQUIRED;
> +    option text    = STRING_TOKEN(STR_MMIO_1_25G_STRING), value = 2,
> flags = RESET_REQUIRED;
> +    option text    = STRING_TOKEN(STR_MMIO_1_5G_STRING), value = 3,
> flags = RESET_REQUIRED;
> +    option text    = STRING_TOKEN(STR_MMIO_2G_STRING), value = 4, flags
> = DEFAULT | MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +
> +  oneof varid = Setup.PcieDynamicGating,
> +    prompt         = STRING_TOKEN(STR_PCIEDYNCLK_PROMPT),
> +    help           = STRING_TOKEN(STR_PCIEDYNCLK_HELP),
> +    option text    = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT
> | MANUFACTURING |RESET_REQUIRED;
> +    option text    = STRING_TOKEN(STR_ENABLE), value = 1, flags =
> RESET_REQUIRED;
> +  endoneof;
> +
> +  oneof varid = Setup.GpioWakeCapability,
> +    prompt         = STRING_TOKEN(STR_GPIO_WAKE_CAPABILITY_ENABLE),
> +    help           =
> STRING_TOKEN(STR_GPIO_WAKE_CAPABILITY_ENABLE_HELP),
> +    option text    = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT
> | MANUFACTURING |RESET_REQUIRED;
> +    option text    = STRING_TOKEN(STR_ENABLE), value = 1, flags =
> RESET_REQUIRED;
> +  endoneof;
> +
> +  oneof varid = Setup.RtcBattery,
> +    prompt         = STRING_TOKEN(STR_RTC_BATTERY),
> +    help           = STRING_TOKEN(STR_RTC_BATTERY_HELP),
> +    option text    = STRING_TOKEN(STR_RTC_BATTERY_NOT_PRESENT), value
> = 0, flags = RESET_REQUIRED;
> +    option text    = STRING_TOKEN(STR_RTC_BATTERY_PRESENT), value = 1,
> flags = DEFAULT | MANUFACTURING |RESET_REQUIRED;
> +  endoneof;
> +
> +endform;
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SystemComponent.
> vfi
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SystemComponent.
> vfi
> new file mode 100644
> index 0000000000..96cf470eaf
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SystemComponent.
> vfi
> @@ -0,0 +1,81 @@
> +//
> +//
> +// Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +//
> 
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +//
> 
> +//
> +//
> +//
> +// Module Name:
> +//
> +//   SystemComponent.vfr
> +//
> +// Abstract:
> +//
> +//   Driver Setup formset.
> +//
> +// Revision History:
> +//   ------------------------------------------------------------------------------
> +//   Rev   Date<MM/DD/YYYY>    Name    Description
> +//   ------------------------------------------------------------------------------
> +
> +// --*/
> +
> +form formid = SYSTEM_COMPONENT_FORM_ID,
> +
> +  title  = STRING_TOKEN(STR_SYSTEM_COMPONENT_TITLE);
> +/*
> +  oneof   varid   = Setup.CRIDSettings,
> +    prompt      = STRING_TOKEN(STR_CRID_PROMPT),
> +    help        = STRING_TOKEN(STR_CRID_SETTING_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> MANUFACTURING | DEFAULT | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_CRID_0_STRING),  value = 1, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_CRID_1_STRING),  value = 2, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_CRID_2_STRING),  value = 3, flags =
> RESET_REQUIRED;
> +  endoneof;
> +*/
> +
> +  subtitle text = STRING_TOKEN(STR_PNP_CONFIGURATION_TITLE);
> +  oneof   varid   = Setup.PnpSettings,
> +    prompt      = STRING_TOKEN(STR_PNP_SETTING_PROMPT),
> +    help        = STRING_TOKEN(STR_PNP_SETTING_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +#if (PNP_DEBUG == 1)
> +    option text = STRING_TOKEN(STR_PNP_POWER_STRING),  value = 1,
> flags = RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_PNP_PERFORMANCE_STRING),  value
> = 2, flags = RESET_REQUIRED;
> +#endif
> +    option text =
> STRING_TOKEN(STR_PNP_POWER_PERFORMANCE_STRING), value = 3, flags
> = DEFAULT | MANUFACTURING | RESET_REQUIRED;
> +    option text =
> STRING_TOKEN(STR_PNP_POWER_PERFORMANCE_STRING_A0), value = 4,
> flags = 0 | RESET_REQUIRED;
> +    option text =
> STRING_TOKEN(STR_PNP_POWER_PERFORMANCE_STRING_B0), value = 5,
> flags = 0 | RESET_REQUIRED;
> +  endoneof;
> +
> +  oneof   varid   = Setup.CfioPnpSettings,
> +    prompt      = STRING_TOKEN(STR_CFIO_PNP_SETTING_PROMPT),
> +    help        = STRING_TOKEN(STR_CFIO_PNP_SETTING_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> MANUFACTURING | DEFAULT | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = 0 |
> RESET_REQUIRED;
> +  endoneof;
> + oneof   varid   = Setup.TristateLpc,
> +    prompt      = STRING_TOKEN(STR_TRISTATE_LPC_PROMPT),
> +    help        = STRING_TOKEN(STR_TRISTATE_LPC_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> MANUFACTURING | DEFAULT | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = 0 |
> RESET_REQUIRED;
> +  endoneof;
> +
> +
> +
> +
> +
> +
> +  oneof varid   = Setup.PchFSAOn,
> +    prompt      = STRING_TOKEN(STR_PCH_FSA_PROMPT),
> +    help        = STRING_TOKEN(STR_PCH_FSA_HELP),
> +    option text = STRING_TOKEN(STR_OFF), value = 0, flags = DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ON), value = 1, flags =
> RESET_REQUIRED;
> +  endoneof;
> +
> +
> +
> +endform;
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Thermal.vfi
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Thermal.vfi
> new file mode 100644
> index 0000000000..63063a73b2
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Thermal.vfi
> @@ -0,0 +1,106 @@
> +//
> +//
> +// Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +//
> 
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +//
> 
> +//
> +//
> +//
> +// Module Name:
> +//
> +//   DPTF.vfr
> +//
> +// Abstract:
> +//
> +//   Driver Setup formset.
> +//
> +// Revision History:
> +//   ------------------------------------------------------------------------------
> +//   Rev   Date<MM/DD/YYYY>    Name    Description
> +//   ------------------------------------------------------------------------------
> +
> +// --*/
> +
> +form formid = THERMAL_FORM_ID,
> +
> +  title  = STRING_TOKEN(STR_THERMAL_TITLE);
> +
> +  subtitle text = STRING_TOKEN(STR_THERMAL_CONFIGURATION);
> +  oneof   varid   = Setup.CriticalThermalTripPoint,
> +    prompt      =
> STRING_TOKEN(STR_ACPI_CRITICAL_THERMAL_TRIP_POINT),
> +    help        =
> STRING_TOKEN(STR_ACPI_CRITICAL_THERMAL_TRIP_POINT_HELP),
> +    option text = STRING_TOKEN (STR_85_C), value = 85, flags=0 |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN (STR_87_C), value = 87, flags=0 |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN (STR_90_C), value = 90, flags=0 |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN (STR_105_C), value = 105, flags=0 |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN (STR_110_C), value = 110, flags=0 |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN (STR_200_C), value = 200, flags=DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +  oneof   varid   = Setup.PassiveThermalTripPoint,
> +    prompt      = STRING_TOKEN
> (STR_ACPI_PASSIVE_THERMAL_TRIP_POINT),
> +    help        = STRING_TOKEN
> (STR_ACPI_PASSIVE_THERMAL_TRIP_POINT_HELP),
> +    option text = STRING_TOKEN (STR_85_C), value = 85, flags=0 |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN (STR_87_C), value = 87, flags=0 |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN (STR_90_C), value = 90, flags=0 |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN (STR_100_C), value = 100, flags=0 |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN (STR_105_C), value = 105, flags=0 |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN (STR_180_C), value = 180, flags=DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +
> +  suppressif TRUE;
> +    numeric varid = Setup.PassiveTc1Value,
> +      prompt  = STRING_TOKEN (STR_ACPI_PASSIVE_TC1_VALUE),
> +      help    = STRING_TOKEN (STR_ACPI_PASSIVE_TC1_VALUE_HELP),
> +      flags   = 0 | RESET_REQUIRED,
> +      minimum = 1,
> +      maximum = 16,
> +      step    = 1,
> +      default = 1,
> +    endnumeric;
> +
> +    numeric varid = Setup.PassiveTc2Value,
> +      prompt  = STRING_TOKEN (STR_ACPI_PASSIVE_TC2_VALUE),
> +      help    = STRING_TOKEN (STR_ACPI_PASSIVE_TC2_VALUE_HELP),
> +      flags   = 0 | RESET_REQUIRED,
> +      minimum = 1,
> +      maximum = 16,
> +      step    = 1,
> +      default = 5,
> +    endnumeric;
> +
> +    numeric varid = Setup.PassiveTspValue,
> +      prompt  = STRING_TOKEN (STR_ACPI_PASSIVE_TSP_VALUE),
> +      help    = STRING_TOKEN (STR_ACPI_PASSIVE_TSP_VALUE_HELP),
> +      flags   = 0 | RESET_REQUIRED,
> +      minimum = 2,
> +      maximum = 50,
> +      step    = 2,
> +      default = 50,
> +    endnumeric;
> +  endif;
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +
> +  oneof varid    = Setup.DisableActiveTripPoints,
> +        prompt      = STRING_TOKEN(STR_DATP_PROMPT),
> +        help        = STRING_TOKEN(STR_DATP_HELP),
> +        option text = STRING_TOKEN(STR_DISABLED), value = 0, flags =
> DEFAULT | MANUFACTURING | RESET_REQUIRED;
> +        option text = STRING_TOKEN(STR_ENABLED),  value = 1, flags =
> RESET_REQUIRED;
> +  endoneof;
> +
> +  suppressif TRUE;
> +  oneof varid     = Setup.EnableDigitalThermalSensor,
> +    prompt      = STRING_TOKEN(STR_DTS_PROMPT),
> +    help        = STRING_TOKEN(STR_DTS_PROMPT_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE),  value = 1, flags =
> MANUFACTURING |RESET_REQUIRED |DEFAULT;
> +  endoneof;
> +  endif;
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +
> +
> +
> +endform;
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UnCore.vfi
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UnCore.vfi
> new file mode 100644
> index 0000000000..ed6bb3a00b
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UnCore.vfi
> @@ -0,0 +1,235 @@
> +//
> +//
> +// Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +//
> 
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +//
> 
> +//
> +//
> +//
> +// Module Name:
> +//
> +//   UncoreConfiguration.vfi
> +//
> +// Abstract:
> +//
> +//   Driver Setup formset.
> +//
> +
> +
> +// --*/
> +
> +form formid = UNCORE_FORM_ID,
> +  title    = STRING_TOKEN(STR_UNCORE_CONFIGURATION_TITLE);
> +
> +  subtitle text = STRING_TOKEN(STR_GOP_TITLE);
> +
> +  oneof varid    = Setup.GOPEnable,
> +    prompt   = STRING_TOKEN(STR_GOP_VBIOS_SWITCH),
> +    help     = STRING_TOKEN(STR_GOP_VBIOS_SWITCH_HELP),
> +    option text = STRING_TOKEN(STR_ENABLE), value =1, flags =
> MANUFACTURING | DEFAULT | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +  endoneof;
> +
> +  oneof varid  = Setup.GOPBrightnessLevel,
> +    prompt = STRING_TOKEN(STR_GOP_BRIGHTNESS_LEVEL),
> +    help   = STRING_TOKEN(STR_GOP_BRIGHTNESS_LEVEL_HELP),
> +    option text = STRING_TOKEN(STR_GOP_BRIGHT_20), value =2, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_GOP_BRIGHT_40), value =3, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_GOP_BRIGHT_60), value =4, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_GOP_BRIGHT_80), value =5, flags =
> MANUFACTURING| DEFAULT| RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_GOP_BRIGHT_100), value =6, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_GOP_BRIGHT_120), value =7, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_GOP_BRIGHT_140), value =8, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_GOP_BRIGHT_160), value =9, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_GOP_BRIGHT_180), value =10, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_GOP_BRIGHT_200), value =11, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_GOP_BRIGHT_220), value =12, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_GOP_BRIGHT_240), value =13, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_GOP_BRIGHT_255), value =14, flags =
> RESET_REQUIRED;
> +  endoneof;
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +  subtitle text = STRING_TOKEN(STR_IGD_TITLE);
> +
> +  suppressif ideqval Setup.PrimaryVideoAdaptor == 0x2;
> +    oneof varid  = Setup.Igd,
> +      prompt   = STRING_TOKEN (STR_IGD_PROMPT),
> +      help     = STRING_TOKEN (STR_IGD_HELP),
> +      option text = STRING_TOKEN(STR_DISABLE), value=0,
> flags=RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_ENABLE),  value=1, flags=DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +    endoneof;
> +  endif;
> +
> +  oneof varid    = Setup.PrimaryVideoAdaptor,
> +    prompt   = STRING_TOKEN(STR_PRIMARY_DISPLAY),
> +    help     = STRING_TOKEN(STR_PRIMARY_DISPLAY_HELP),
> +    option text = STRING_TOKEN(STR_AUTOMATIC), value = 3, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_IGD_STRING), value = 0, flags =
> DEFAULT |MANUFACTURING |RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_PCI_STRING),  value = 2, flags =
> RESET_REQUIRED;
> +  endoneof;
> +
> +
> +  oneof varid = Setup.PavpMode,
> +    prompt   = STRING_TOKEN(STR_PAVC_PROMPT),
> +    help     = STRING_TOKEN(STR_PAVC_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_PAVP_LITE_MODE), value = 1, flags =
> MANUFACTURING | DEFAULT | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_PAVP_SERPENT_MODE), value = 2,
> flags = RESET_REQUIRED;
> +  endoneof;
> +
> +
> +  oneof varid    = Setup.GTTSize,
> +    prompt   = STRING_TOKEN(STR_GTT_SIZE),
> +    help     = STRING_TOKEN(STR_GTT_SIZE_HELP),
> +    option text = STRING_TOKEN(GTT_SIZE_1MB), value = 1, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(GTT_SIZE_2MB), value = 2, flags =  DEFAULT
> | MANUFACTURING | RESET_REQUIRED;
> +  endoneof;
> +
> +  oneof varid    = Setup.IgdApertureSize,
> +    prompt   = STRING_TOKEN(STR_APERTURE_SIZE),
> +    help     = STRING_TOKEN(STR_APERTURE_SIZE_HELP),
> +    option text = STRING_TOKEN(APERTURE_SIZE_128MB), value = 1, flags =
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(APERTURE_SIZE_256MB), value = 2, flags =
> DEFAULT | MANUFACTURING | RESET_REQUIRED;
> +    option text = STRING_TOKEN(APERTURE_SIZE_512MB), value = 3, flags =
> RESET_REQUIRED;
> +  endoneof;
> +
> +  oneof varid   = Setup.IgdDvmt50PreAlloc,
> +    prompt  = STRING_TOKEN(STR_DVMT50_PRE_ALLOC),
> +    help    = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_HELP),
> +//    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_32M), value =
> 1, flags = RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_64M), value = 2,
> flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_96M), value = 3,
> flags = RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_128M), value =
> 4, flags = RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_160M), value =
> 5, flags = RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_192M), value =
> 6, flags = RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_224M), value =
> 7, flags = RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_256M), value =
> 8, flags = RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_288M), value =
> 9, flags = RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_320M), value =
> 10, flags = RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_352M), value =
> 11, flags = RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_384M), value =
> 12, flags = RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_416M), value =
> 13, flags = RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_448M), value =
> 14, flags = RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_480M), value =
> 15, flags = RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DVMT50_PRE_ALLOC_512M), value =
> 16, flags = RESET_REQUIRED;
> +  endoneof;
> +
> +  oneof   varid   = Setup.IgdDvmt50TotalAlloc,
> +    prompt  = STRING_TOKEN(STR_DVMT50_DVMT ),
> +    help    = STRING_TOKEN(STR_DVMT50_DVMT_HELP),
> +    option text = STRING_TOKEN(STR_DVMT50_ALLOC_128), value = 1, flags
> = RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DVMT50_ALLOC_256), value = 2, flags
> = DEFAULT | MANUFACTURING | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DVMT50_ALLOC_MAX), value = 3,
> flags = RESET_REQUIRED;
> +  endoneof;
> +
> +  //
> +  //Igd Thermal
> +  //
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +
> +  subtitle text = STRING_TOKEN(STR_IGD_LCD_CONTROL);
> +
> +  oneof varid    = Setup.LidStatus,
> +    prompt   = STRING_TOKEN(STR_FORCE_LID_STATUS_PROMPT),
> +    help     = STRING_TOKEN(STR_FORCE_LID_STATUS_ENBDT_HELP),
> +    option text = STRING_TOKEN(STR_LID_STATUS__OFF_PROMPT), value =
> 0, flags = 0 | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_LID_STATUS__ON_PROMPT), value =
> 1, flags = 0 | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_LID_STATUS__AUTO_PROMPT), value
> = 2, flags = MANUFACTURING| DEFAULT| RESET_REQUIRED;
> +  endoneof;
> +
> +  oneof varid    = Setup.IgdLcdIBia,
> +    prompt   = STRING_TOKEN(STR_VIDEO_LCD_IBIA),
> +    help     = STRING_TOKEN(STR_VIDEO_LCD_IBIAHLP),
> +    option text = STRING_TOKEN(STR_VIDEO_LCD_IBIAA), value = 0, flags
> =MANUFACTURING| DEFAULT| RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_VIDEO_LCD_IBIAD), value = 1, flags =
> 0| RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_VIDEO_LCD_IBIAL1), value = 2, flags =
> 0| RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_VIDEO_LCD_IBIAL2), value = 3, flags =
> 0| RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_VIDEO_LCD_IBIAL3), value = 4, flags =
> 0| RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_VIDEO_LCD_IBIAL4), value = 5, flags =
> 0| RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_VIDEO_LCD_IBIAL5), value = 6, flags =
> 0| RESET_REQUIRED;
> +  endoneof;
> +
> +  oneof varid  = Setup.AlsEnable,
> +    prompt   = STRING_TOKEN (STR_ACPI_ALS_ENABLE),
> +    help     = STRING_TOKEN (STR_ACPI_ALS_ENABLE_HELP),
> +    option text = STRING_TOKEN(STR_DISABLE), value=0, flags=DEFAULT |
> MANUFACTURING | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_ENABLE),  value=1, flags=0 |
> RESET_REQUIRED;
> +  endoneof;
> +
> +
> +  oneof   varid   = Setup.IgdFlatPanel,
> +    prompt      = STRING_TOKEN(STR_IGD_FLAT_PANEL_PROMPT),
> +    help        = STRING_TOKEN(STR_IGD_FLAT_PANEL_HELP),
> +    option text = STRING_TOKEN(STR_AUTOMATIC), value=0x00,
> flags=DEFAULT | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_640X480), value=0x01,
> flags=RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_800X600), value=0x02,
> flags=RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_1024X768), value=0x03,
> flags=RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_1280X1024), value=0x04,
> flags=RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_1366X768), value=0x05,
> flags=RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_1680X1050), value=0x06,
> flags=RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_1920X1200), value=0x07,
> flags=RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_1280X800), value=0x08,
> flags=RESET_REQUIRED;
> +  endoneof;
> +
> +  oneof   varid   = Setup.BootDisplayDevice,
> +    prompt      = STRING_TOKEN(STR_BOOT_DISPLAY_DEVICE_PROMPT),
> +    help        = STRING_TOKEN(STR_BOOT_DISPLAY_DEVICE_HELP),
> +    option text = STRING_TOKEN(STR_AUTOMATIC), value=0x00,
> flags=DEFAULT | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_VGAPORT), value=0x01,
> flags=RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_HDMIPORTB), value=0x02,
> flags=RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DPPORTB), value=0x03,
> flags=RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DPPORTC), value=0x04,
> flags=RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_EDPPORTC), value=0x05,
> flags=RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DSIPORTA), value=0x06,
> flags=RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DSIPORTC), value=0x07,
> flags=RESET_REQUIRED;
> +
> +  endoneof;
> +  //
> +  //Pannel Scaling
> +  //
> +  oneof   varid   = Setup.PanelScaling,
> +    prompt      = STRING_TOKEN(STR_PANNEL_SCALING_PROMPT),
> +    help        = STRING_TOKEN(STR_PANNEL_SCALING_HELP),
> +    option text = STRING_TOKEN(STR_AUTOMATIC), value=0x00,
> flags=DEFAULT | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_PANNEL_SCALING_STRETCH),
> value=0x01, flags=RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_PANNEL_SCALING_CENTER),
> value=0x02, flags=RESET_REQUIRED;
> +  endoneof;
> +
> +  //
> +  //GMCH BLC Control
> +  //
> +  oneof   varid   = Setup.IgdLcdIGmchBlc,
> +    prompt      = STRING_TOKEN(STR_VIDEO_LCD_IGMCHBLC_PROMPT),
> +    help        = STRING_TOKEN(STR_VIDEO_LCD_IGMCHBLC_HELP),
> +    option text = STRING_TOKEN(STR_VIDEO_LCD_IGMCHBLC1), value=0x00,
> flags=DEFAULT | RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_VIDEO_LCD_IGMCHBLC2), value=0x01,
> flags=RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_VIDEO_LCD_IGMCHBLC3), value=0x02,
> flags=RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_VIDEO_LCD_IGMCHBLC4), value=0x03,
> flags=RESET_REQUIRED;
> +  endoneof;
> +
> +  subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +  //
> +  //ISP Configuration
> +  //
> +  subtitle text = STRING_TOKEN(STR_ISP_CONFIGURATION_TITLE);
> +
> +  oneof varid   = Setup.ISPEn,
> +    prompt      = STRING_TOKEN(STR_ISP_ENABLED),
> +    help        = STRING_TOKEN(STR_ISP_ENABLED_HELP),
> +    option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = DEFAULT |
> RESET_REQUIRED;
> +    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +  endoneof;
> +
> +  grayoutif ideqval Setup.ISPEn == 0;
> +    oneof varid  = Setup.ISPDevSel,
> +      prompt   = STRING_TOKEN (STR_ISP_PCICONFIGURATION_TITLE),
> +      help     = STRING_TOKEN (STR_ISP_PCICONFIGURATION_HELP),
> +      option text = STRING_TOKEN(STR_DISABLE), value = 0, flags =
> RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_ISP_PCICONFIG_B0D2F0_TITLE),
> value = 1, flags = MANUFACTURING | DEFAULT | RESET_REQUIRED;
> +      option text = STRING_TOKEN(STR_ISP_PCICONFIG_B0D3F0_TITLE),
> value = 2, flags = RESET_REQUIRED;
> +   endoneof;
> +  endif;
> +
> +endform;
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UqiList.uni
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UqiList.uni
> new file mode 100644
> index 0000000000..504539a02f
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UqiList.uni
> @@ -0,0 +1,452 @@
> +// /** @file
> +//
> +// Copyright (c) 2013 - 2016 Intel Corporation. All rights reserved
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//
> +// Module Name:
> +//
> +//   UqiList.uni
> +//
> +// Abstract:
> +//
> +//   UQI (Universal Question Identifier) allocation for setup options.
> +//
> +//   This file should define UQIs in the following range only: [0x0000...0x7FFF]
> +//
> +// **/
> +
> +/=#
> +
> +//----------------------------------------------------------------------------
> +//
> +//   Purpose: The translations in this file are intended to be globally
> +//   consistent.  All products should use the same translation for the
> +//   same functional question.
> +//
> +//   Usage:
> +//
> +//   1. DO NOT OVERRIDE THIS FILE!
> +//      The translations in this file should be globally consistent across
> +//      all of our products.
> +//
> +//   2. Never delete tokens from this file
> +//
> +//   3. When adding a new question:
> +//
> +//      * Always do a thorough check of the tokens below to determine if
> +//        a question is already represented.  This is important, because
> +//        we want to generate scripts based on these tokens which will
> +//        work on our entire product line.
> +//
> +//      * Always choose the first available new token number for your
> +//        new token.  Do not worry about "grouping" your questions
> +//        together.  That goal will only make it more difficult to manage
> +//        the token numbering.  Always add your new token to the correct
> +//        place to preserve numerical ordering.  This makes it easy to
> +//        determine which token should be used next.
> +//
> +//----------------------------------------------------------------------------
> +
> +#langdef uqi "uqi"
> +
> +//
> +// Keep in numerical order to prevent token reuse
> +//
> +#string STR_FAST_BOOT_PROMPT                            #language uqi  "\x0001"
> +#string STR_MEMORY_CHECK_SETUP                          #language uqi  "\x0002"
> +#string STR_NUM_AUTO_BOOT                               #language uqi  "\x0003"
> +#string STR_LOAD_OPTION_FORCE_RECON                     #language uqi
> "\x0004"
> +#string STR_ONE_OF_PROMPT                               #language uqi  "\x0005"
> +#string STR_CHECK_BOX_PROMPT                            #language uqi  "\x0006"
> +#string STR_TEST_OPCODE                                 #language uqi  "\x0007"
> +#string STR_TEST_OPCODE2                                #language uqi  "\x0008"
> +#string STR_ERROR_POPUP                                 #language uqi  "\x0009"
> +#string STR_NUMERIC_READONLY_PROMPT                     #language uqi
> "\x000A"
> +#string STR_NUMERIC_MANUAL_PROMPT                       #language uqi
> "\x000B"
> +#string STR_TALL_HEX_PROMPT                             #language uqi  "\x000C"
> +#string STR_NAME_VALUE_VAR_NAME0                        #language uqi
> "\x000D"
> +#string STR_NAME_VALUE_VAR_NAME1                        #language uqi
> "\x000E"
> +#string STR_NUMERIC_STEP_PROMPT                         #language uqi  "\x000F"
> +#string STR_DEFAULT_VALUE_FROM_ACCESS_PROMPT            #language uqi
> "\x0010"
> +#string STR_DEFAULT_VALUE_FROM_CALLBACK_PROMPT          #language
> uqi  "\x0011"
> +#string STR_SERIAL_PORT                                 #language uqi  "\x0012"
> +#string STR_SERIAL_PORT_STATUS                          #language uqi  "\x0013"
> +#string STR_SERIAL_PORT_IO_ADDRESS                      #language uqi  "\x0014"
> +#string STR_SERIAL_PORT_IRQ                             #language uqi  "\x0015"
> +#string STR_TEXT_REFRESH_GUID_COUNT                     #language uqi
> "\x0016"
> +#string STR_IP4_CONFIGURE                               #language uqi  "\x0017"
> +#string STR_IP4_ENABLE_DHCP                             #language uqi  "\x0018"
> +#string STR_ISCSI_DEVICE_ENABLE                         #language uqi  "\x0019"
> +#string STR_ISCSI_ENABLE_DHCP                           #language uqi  "\x001A"
> +#string STR_ISCSI_ENABLE_DHCP_ON_TARGET                 #language uqi
> "\x001B"
> +#string STR_ISCSI_TARGET_PORT                           #language uqi  "\x001C"
> +#string STR_CHAP_TYPE_PROMPT                            #language uqi  "\x001D"
> +#string STR_VLAN_VID_PROMPT                             #language uqi  "\x001E"
> +#string STR_VLAN_PRIORITY_PROMPT                        #language uqi  "\x001F"
> +#string STR_PCI_DEVICE_FILTER_PROMPT                    #language uqi  "\x0020"
> +#string STR_IP6_DAD_TRANSMIT_COUNT                      #language uqi
> "\x0021"
> +#string STR_POLICY_TYPE_PROMPT                          #language uqi  "\x0022"
> +#string STR_ISCSI_MODE_PROMPT                           #language uqi  "\x0023"
> +#string STR_IP_MODE_PROMPT                              #language uqi  "\x0024"
> +#string STR_ISCSI_CONFIG_RETRY                          #language uqi  "\x0025"
> +#string STR_ISCSI_CONFIG_TIMEOUT                        #language uqi  "\x0026"
> +#string STR_AUTHEN_TYPE_PROMPT                          #language uqi  "\x0027"
> +#string STR_NULL                                        #language uqi  "\x0028"
> +#string STR_HIDE_TPM_PROMPT                             #language uqi  "\x0029"
> +#string STR_TPM_OPERATION                               #language uqi  "\x002A"
> +#string STR_MOR_PROMPT                                  #language uqi  "\x002B"
> +#string STR_SECURE_BOOT_PROMPT                          #language uqi  "\x002C"
> +#string STR_USB_SUPPORT                                 #language uqi  "\x002D"
> +#string STR_USB_LEGACY_SUPPORT                          #language uqi  "\x002E"
> +#string STR_USB_XHCI_SUPPORT                            #language uqi  "\x002F"
> +#string STR_USB_BIOS_XHCI_HANDOFF                       #language uqi  "\x0030"
> +#string STR_USB_BIOS_EHCI_HANDOFF                       #language uqi  "\x0031"
> +#string STR_USB_6064                                    #language uqi  "\x0032"
> +#string STR_USB_HOTPLUG_FDD                             #language uqi  "\x0033"
> +#string STR_USB_HOTPLUG_HDD                             #language uqi  "\x0034"
> +#string STR_USB_HOTPLUG_CDROM                           #language uqi  "\x0035"
> +#string STR_USB_CONTROL_TIME_OUT                        #language uqi  "\x0036"
> +#string STR_USB_MASS_RESET_DELAY                        #language uqi  "\x0037"
> +#string STR_USB_POWERGOOD_DELAY                         #language uqi  "\x0038"
> +#string STR_USB_DELAY_NUM_VALUE                         #language uqi  "\x0039"
> +#string STR_USB_MASS_DEVICE1                            #language uqi  "\x003A"
> +#string STR_USB_MASS_DEVICE2                            #language uqi  "\x003B"
> +#string STR_USB_MASS_DEVICE3                            #language uqi  "\x003C"
> +#string STR_USB_MASS_DEVICE4                            #language uqi  "\x003D"
> +#string STR_USB_MASS_DEVICE5                            #language uqi  "\x003E"
> +#string STR_USB_MASS_DEVICE6                            #language uqi  "\x003F"
> +#string STR_USB_MASS_DEVICE7                            #language uqi  "\x0040"
> +#string STR_USB_MASS_DEVICE8                            #language uqi  "\x0041"
> +#string STR_USB_MASS_DEVICE9                            #language uqi  "\x0042"
> +#string STR_USB_MASS_DEVICE10                           #language uqi  "\x0043"
> +#string STR_USB_MASS_DEVICE11                           #language uqi  "\x0044"
> +#string STR_USB_MASS_DEVICE12                           #language uqi  "\x0045"
> +#string STR_USB_MASS_DEVICE13                           #language uqi  "\x0046"
> +#string STR_USB_MASS_DEVICE14                           #language uqi  "\x0047"
> +#string STR_USB_MASS_DEVICE15                           #language uqi  "\x0048"
> +#string STR_USB_MASS_DEVICE16                           #language uqi  "\x0049"
> +#string STR_SECURITY_BOOT_PROMPT                        #language uqi  "\x004A"
> +#string STR_QUIETBOOT_PROMPT                            #language uqi  "\x004B"
> +#string STR_LOG_BOOT_TIME_PROMPT                        #language uqi  "\x004C"
> +#string STR_EXECUTE_DISABLE_BIT_PROMPT                  #language uqi
> "\x004D"
> +#string STR_LIMIT_CPUID_MAX_PROMPT                      #language uqi
> "\x004E"
> +#string STR_PROC_HOT_ENABLE                             #language uqi  "\x004F"
> +#string STR_VTX2_PROMPT                                 #language uqi  "\x0050"
> +#string STR_CORE_FRE_MULTIP_SELECT_PROMPT               #language uqi
> "\x0051"
> +#string STR_TM1_PROMPT                                  #language uqi  "\x0052"
> +#string STR_TM2_PROMPT                                  #language uqi  "\x0053"
> +#string STR_DTS_PROMPT                                  #language uqi  "\x0054"
> +#string STR_ACTIVE_PROCESSOR_CORES_PROMPT               #language uqi
> "\x0055"
> +#string STR_CPU_IST_PROMPT                              #language uqi  "\x0056"
> +#string STR_BOOT_P_STATE                                #language uqi  "\x0057"
> +#string STR_PROCESSOR_TURBO_MODE                        #language uqi  "\x0058"
> +#string STR_CSTATE_PROMPT                               #language uqi  "\x0059"
> +#string STR_CXE_PROMPT                                  #language uqi  "\x005A"
> +#string STR_HARDC4E_PROMPT                              #language uqi  "\x005B"
> +#string STR_MAX_C_STATE_SUPPORT_PROMPT                  #language uqi
> "\x005C"
> +#string STR_PPM_C4_EXIT_PROMPT                          #language uqi  "\x005D"
> +#string STR_CX_POPDOWN_PROMPT                           #language uqi  "\x005E"
> +#string STR_CX_POPUP_PROMPT                             #language uqi  "\x005F"
> +#string STR_SEC_SETTING_PROMPT                          #language uqi  "\x0060"
> +#string STR_SEC_FLASH_UPDATE_PROMPT                     #language uqi
> "\x0061"
> +#string STR_SEC_FIRMWARE_UPDATE_PROMPT                  #language uqi
> "\x0062"
> +#string STR_FIRMWARE_TPM_PROMPT                         #language uqi  "\x0063"
> +#string STR_TPM_PROMPT                                  #language uqi  "\x0064"
> +#string STR_TDT_CONFIG_PROMPT                           #language uqi  "\x0065"
> +#string STR_TDT_RECOVERY_PROMPT                         #language uqi  "\x0066"
> +#string STR_TDT_SUSPEND_PROMPT                          #language uqi  "\x0067"
> +#string STR_ICH_PCIERP1_PROMPT                          #language uqi  "\x0068"
> +#string STR_ICH_PCIERP2_PROMPT                          #language uqi  "\x0069"
> +#string STR_ICH_PCIERP3_PROMPT                          #language uqi  "\x006A"
> +#string STR_ICH_PCIERP4_PROMPT                          #language uqi  "\x006B"
> +#string STR_USB_DEBUG_PROMPT                            #language uqi  "\x006C"
> +#string STR_USB_XHCI_SUPPORT_PROMPT                     #language uqi
> "\x006D"
> +#string STR_PCH_USB21_PROMPT                            #language uqi  "\x006E"
> +#string STR_PCH_USB30_MODE_PROMPT                       #language uqi
> "\x006F"
> +#string STR_PCH_USB30_STREAMS                           #language uqi  "\x0070"
> +#string STR_PCH_USB_PER_PORT_PROMPT                     #language uqi
> "\x0071"
> +#string STR_PCH_USB_PORT0_PROMPT                        #language uqi  "\x0072"
> +#string STR_PCH_USB_PORT1_PROMPT                        #language uqi  "\x0073"
> +#string STR_PCH_USB_PORT2_PROMPT                        #language uqi  "\x0074"
> +#string STR_PCH_USB_PORT3_PROMPT                        #language uqi  "\x0075"
> +#string STR_PCH_USBRMH_PROMPT                           #language uqi  "\x0076"
> +#string STR_SATA_PROMPT                                 #language uqi  "\x0077"
> +#string STR_SATA_TYPE_PROMPT                            #language uqi  "\x0078"
> +#string STR_SATA0_HOTPLUG_CAP_PROMPT                    #language uqi
> "\x0079"
> +#string STR_SATA1_HOTPLUG_CAP_PROMPT                    #language uqi
> "\x007A"
> +#string STR_LPSS_EMMC_PROMPT                            #language uqi  "\x007B"
> +#string STR_LPSS_SDIO_PROMPT                            #language uqi  "\x007C"
> +#string STR_LPSS_SDCARD_PROMPT                          #language uqi  "\x007D"
> +#string STR_LPSS_DMA_PROMPT                             #language uqi  "\x007E"
> +#string STR_LPSS_I2C1_PROMPT                            #language uqi  "\x007F"
> +#string STR_LPSS_I2C2_PROMPT                            #language uqi  "\x0080"
> +#string STR_LPSS_PCM_PROMPT                             #language uqi  "\x0081"
> +#string STR_LPSS_I2S_PROMPT                             #language uqi  "\x0082"
> +#string STR_LPSS_HSUART1_PROMPT                         #language uqi  "\x0083"
> +#string STR_LPSS_HSUART2_PROMPT                         #language uqi  "\x0084"
> +#string STR_LPSS_SPI_PROMPT                             #language uqi  "\x0085"
> +#string STR_PCH_LAN_CONTROLLER                          #language uqi  "\x0086"
> +#string STR_PCH_LAN_WOL_PROMPT                          #language uqi  "\x0087"
> +#string STR_PCH_SLP_LAN_LOW_DC_PROMPT                   #language uqi
> "\x0088"
> +#string STR_PCH_PXEROM_CONTROL                          #language uqi  "\x0089"
> +#string STR_LPE_PROMPT                                  #language uqi  "\x008A"
> +#string STR_PCH_AZALIA_PROMPT                           #language uqi  "\x008B"
> +#string STR_AZALIA_VC_PROMPT                            #language uqi  "\x008C"
> +#string STR_AZALIA_DS_PROMPT                            #language uqi  "\x008D"
> +#string STR_AZALIA_PME_PROMPT                           #language uqi  "\x008E"
> +#string STR_HDMI_CODEC_PROMPT                           #language uqi  "\x008F"
> +#string STR_HPET_PROMPT                                 #language uqi  "\x0090"
> +#string STR_HPET_BOOTTIME_PROMPT                        #language uqi  "\x0091"
> +#string STR_STATE_AFTER_G3                              #language uqi  "\x0092"
> +#string STR_PCH_UART_SELECT                             #language uqi  "\x0093"
> +#string STR_PCU_UART_A                                  #language uqi  "\x0094"
> +#string STR_PCU_UART_B                                  #language uqi  "\x0095"
> +#string STR_ACPI_CRITICAL_THERMAL_TRIP_POINT            #language uqi
> "\x0096"
> +#string STR_ACPI_PASSIVE_THERMAL_TRIP_POINT             #language uqi
> "\x0097"
> +#string STR_ACPI_PASSIVE_TC1_VALUE                      #language uqi  "\x0098"
> +#string STR_ACPI_PASSIVE_TC2_VALUE                      #language uqi  "\x0099"
> +#string STR_ACPI_PASSIVE_TSP_VALUE                      #language uqi  "\x009A"
> +#string STR_DPTF_PROMPT                                 #language uqi  "\x009B"
> +#string STR_LPM_PROMPT                                  #language uqi  "\x009C"
> +#string STR_CTDP_PROMPT                                 #language uqi  "\x009D"
> +#string STR_MEMORY_PROMPT                               #language uqi  "\x009E"
> +#string STR_DPTF_ACTIVE_TRIP_POINT_PROMPT               #language uqi
> "\x009F"
> +#string STR_DPTF_PASSIVE_TRIP_POINT_PROMPT              #language uqi
> "\x00A0"
> +#string STR_SKIN_SENSOR_PROMPT                          #language uqi  "\x00A1"
> +#string STR_PCH_PROMPT                                  #language uqi  "\x00A2"
> +#string STR_PRIMARY_DISPLAY                             #language uqi  "\x00A3"
> +#string STR_VIDEO_RS2_PROMPT                            #language uqi  "\x00A4"
> +#string STR_DVMT40_PRE_ALLOC                            #language uqi  "\x00A5"
> +#string STR_GFX_BOOST_PROMPT                            #language uqi  "\x00A6"
> +#string STR_IGD_THERMAL_PROMPT                          #language uqi  "\x00A7"
> +#string STR_SPREAD_SPECTRUM_CLOCK_PROMPT                #language uqi
> "\x00A8"
> +#string STR_VIDEO_LCD_IBIA                              #language uqi  "\x00A9"
> +#string STR_ACPI_ALS_ENABLE                             #language uqi  "\x00AA"
> +#string STR_IGD_FLAT_PANEL_PROMPT                       #language uqi  "\x00AB"
> +#string STR_BOOT_DISPLAY_DEVICE_PROMPT                  #language uqi
> "\x00AC"
> +#string STR_PANNEL_SCALING_PROMPT                       #language uqi
> "\x00AD"
> +#string STR_VIDEO_LCD_IGMCHBLC_PROMPT                   #language uqi
> "\x00AE"
> +#string STR_MEMORY_SCRAMBLER_PROMPT                     #language uqi
> "\x00AF"
> +#string STR_CSTATE_C4                                   #language uqi  "\x00B0"
> +#string STR_CSTATE_C6                                   #language uqi  "\x00B1"
> +#string STR_SEC_EOP_PROMPT                              #language uqi  "\x00B2"
> +#string STR_PCH_USB_PORT4_PROMPT                        #language uqi  "\x00B3"
> +#string STR_PCH_USB_PORT5_PROMPT                        #language uqi  "\x00B4"
> +#string STR_PCH_USB_PORT6_PROMPT                        #language uqi  "\x00B5"
> +#string STR_PCH_USB_PORT7_PROMPT                        #language uqi  "\x00B6"
> +#string STR_HDMI_CODEC_PORTB_PROMPT                     #language uqi
> "\x00B7"
> +#string STR_HDMI_CODEC_PORTC_PROMPT                     #language uqi
> "\x00B8"
> +#string STR_HDMI_CODEC_PORTD_PROMPT                     #language uqi
> "\x00B9"
> +#string STR_CONVERT_BOARD_SELECT                        #language uqi  "\x00BA"
> +#string STR_DPTF_CLPM_PROMPT                            #language uqi  "\x00BB"
> +#string STR_PROCESSOR_DPTF_PROMPT                       #language uqi
> "\x00BC"
> +#string STR_DPTF_SYSTHERM0_PROMPT                       #language uqi
> "\x00BD"
> +#string STR_DPTF_SYSTHERM1_PROMPT                       #language uqi  "\x00BE"
> +#string STR_DPTF_SYSTHERM2_PROMPT                       #language uqi  "\x00BF"
> +#string STR_DPTF_SYSTHERM3_PROMPT                       #language uqi  "\x00C0"
> +#string STR_DPTF_CHARGER_PROMPT                         #language uqi  "\x00C1"
> +#string STR_DPTF_DISPLAY_PROMPT                         #language uqi  "\x00C2"
> +#string STR_DPTF_SOC_PROMPT                             #language uqi  "\x00C3"
> +#string STR_GOP_VBIOS_SWITCH                            #language uqi  "\x00C4"
> +#string STR_PAVC_PROMPT                                 #language uqi  "\x00C5"
> +#string STR_GTT_SIZE                                    #language uqi  "\x00C6"
> +#string STR_APERTURE_SIZE                               #language uqi  "\x00C7"
> +#string STR_DVMT50_PRE_ALLOC                            #language uqi  "\x00C8"
> +#string STR_FORCE_LID_STATUS_PROMPT                     #language uqi
> "\x00C9"
> +#string STR_TREE_DEVICE_PROMPT                          #language uqi  "\x00CA"
> +#string STR_TPM2_REVOKE_TRUST_PROMPT                    #language uqi
> "\x00CB"
> +#string STR_PCH_USB_OTG_PROMPT                          #language uqi  "\x00CC"
> +#string STR_LPSS_PCI_PROMPT                             #language uqi  "\x00CD"
> +#string STR_SCC_EMMC_PROMPT                             #language uqi  "\x00CE"
> +#string STR_SCC_SDIO_PROMPT                             #language uqi  "\x00CF"
> +#string STR_SCC_SDCARD_PROMPT                           #language uqi  "\x00D0"
> +#string STR_MIPI_HSI_PROMPT                             #language uqi  "\x00D1"
> +#string STR_LPSS_DMA1_PROMPT                            #language uqi  "\x00D2"
> +#string STR_LPSS_DMA2_PROMPT                            #language uqi  "\x00D3"
> +#string STR_LPSS_I2C3_PROMPT                            #language uqi  "\x00D4"
> +#string STR_LPSS_I2C4_PROMPT                            #language uqi  "\x00D5"
> +#string STR_LPSS_I2C5_PROMPT                            #language uqi  "\x00D6"
> +#string STR_LPSS_I2C6_PROMPT                            #language uqi  "\x00D7"
> +#string STR_LPSS_I2C7_PROMPT                            #language uqi  "\x00D8"
> +#string STR_PWM1_PROMPT                                 #language uqi  "\x00D9"
> +#string STR_PWM2_PROMPT                                 #language uqi  "\x00DA"
> +#string STR_LPSS_LPE_PROMPT                             #language uqi  "\x00DB"
> +#string STR_PMIC_ACPI_OBJECT_PROMPT                     #language uqi
> "\x00DC"
> +#string STR_S0IX_PROMPT                                 #language uqi  "\x00DD"
> +#string STR_DPTF_CRITICAL_TEMP                          #language uqi  "\x00DE"
> +#string STR_DPTF_PASSIVE_TEMP                           #language uqi  "\x00DF"
> +#string STR_DPTF_SDBG                                   #language uqi  "\x00E0"
> +#string STR_DPTF_CLPO                                   #language uqi  "\x00E1"
> +#string STR_DPTF_CLPO_START_PINDEX                      #language uqi  "\x00E2"
> +#string STR_DPTF_CLPO_STEP_SIZE                         #language uqi  "\x00E3"
> +#string STR_DPTF_CLPO_PWR_CTRL                          #language uqi  "\x00E4"
> +#string STR_DPTF_CLPO_PERF_CTRL                         #language uqi  "\x00E5"
> +#string STR_DPTF_DPPM                                   #language uqi  "\x00E6"
> +#string STR_ISP_ENABLED                                 #language uqi  "\x00E7"
> +#string STR_ISP_PCICONFIGURATION_TITLE                  #language uqi
> "\x00E8"
> +#string STR_IGD_PROMPT                                  #language uqi  "\x00E9"
> +#string STR_PNP_SETTING_PROMPT                          #language uqi  "\x00EA"
> +#string STR_DPTF_SYSTHERM4_PROMPT                       #language uqi  "\x00EB"
> +#string STR_ACPIMEMDBG_SWTICH                           #language uqi  "\x00EC"
> +#string STR_SECURE_BOOT                                 #language uqi  "\x00ED"
> +#string STR_SECURE_BOOT_MODE                            #language uqi  "\x00EE"
> +#string STR_PCIE_SPEED_PROMPT0                          #language uqi  "\x00EF"
> +#string STR_PCIE_SPEED_PROMPT1                          #language uqi  "\x00F0"
> +#string STR_PCIE_SPEED_PROMPT2                          #language uqi  "\x00F1"
> +#string STR_PCIE_SPEED_PROMPT3                          #language uqi  "\x00F2"
> +#string STR_SATA_TEST_MODE_PROMPT                       #language uqi
> "\x00F3"
> +#string STR_CLOCK_SPREAD_SPEC_ENABLE                    #language uqi
> "\x00F4"
> +#string STR_BATTERY_ACPI_OBJECT_PROMPT                  #language uqi
> "\x00F5"
> +#string STR_MFGMODE                                     #language uqi  "\x00F6"
> +#string STR_PCH_USB_VBUS_PROMPT                         #language uqi  "\x00F7"
> +#string STR_PCH_USB_EHCIDEBUG_PROMPT                    #language uqi
> "\x00F8"
> +#string STR_CRID_PROMPT                                 #language uqi  "\x00F9"
> +#string STR_GOP_BRIGHTNESS_LEVEL                        #language uqi  "\x00FA"
> +#string STR_ULPMC_FW_LOCK_PROMPT                        #language uqi
> "\x00FC"
> +#string STR_SECURE_BOOT_MODE_PROMPT                     #language uqi
> "\x00FD"
> +#string STR_DELETE_PK                                   #language uqi  "\x00FE"
> +#string STR_I2C_TOUCH_PROMPT                            #language uqi  "\x00FF"
> +#string STR_PCH_SPI_WP_PROMPT                           #language uqi  "\x0100"
> +#string STR_PMWEIGHTS_PROMPT                            #language uqi  "\x0101"
> +#string STR_FORM_BOOT_CHG_TITLE                         #language uqi  "\x0102"
> +#string STR_FORM_DRV_CHG_TITLE                          #language uqi  "\x0103"
> +#string STR_TALL_MANUAL_PROMPT                          #language uqi  "\x0104"
> +#string STR_NUMERIC_PROMPT                              #language uqi  "\x0105"
> +#string STR_NUMERIC_PROMPT1                             #language uqi  "\x0106"
> +#string STR_ACTIVE_CORE_COUNT_PROMPT                    #language uqi
> "\x0107"
> +#string STR_PBA_CONFIG_PROMPT                           #language uqi  "\x0108"
> +#string STR_IGD_TURBO_PROMPT                            #language uqi  "\x0109"
> +#string STR_IGD_TURBO_HELP                              #language uqi  "\x010A"
> +#string STR_EHCI_PLL_CFG_PROMPT                         #language uqi  "\x010B"
> +#string STR_EHCI_PLL_CFG_RTD3_DIS_HELP                  #language uqi
> "\x010C"
> +#string STR_LM_MEMORY_PROMPT                            #language uqi  "\x010D"
> +#string STR_PDM_OUTPUT_CONFIG_SWTICH                    #language uqi
> "\x010E"
> +#string STR_PUINT_BIOS_CONFIG_DISPLAY                   #language uqi
> "\x010F"
> +#string STR_SCC_SDIO_MODE_PROMPT                        #language uqi  "\x0110"
> +#string STR_ISCT_CONFIGURATION                          #language uqi  "\x0111"
> +#string STR_ISCT_NOTIFICATION_CONTROL_PROMPT            #language uqi
> "\x0112"
> +#string STR_ISCT_WLAN_CONTROL_PROMPT                    #language uqi
> "\x0113"
> +#string STR_ISCT_WWAN_CONTROL_PROMPT                    #language uqi
> "\x0114"
> +#string STR_EXISUPPORT_PROMPT                           #language uqi  "\x0115"
> +#string STR_PCH_FSA_PROMPT                              #language uqi  "\x0116"
> +#string STR_PCH_FSA_HELP                                #language uqi  "\x0117"
> +#string STR_USB_AUTO_MODE_PROMPT                        #language uqi
> "\x0118"
> +#string STR_SCC_EMMC45_PROMPT                           #language uqi  "\x0119"
> +#string STR_SCC_EMMC45_HELP                             #language uqi  "\x011A"
> +#string STR_SCC_EMMC45_DDR50_PROMPT                     #language uqi
> "\x011B"
> +#string STR_SCC_EMMC45_DDR50_HELP                       #language uqi  "\x011C"
> +#string STR_SCC_EMMC45_HS200_PROMPT                     #language uqi
> "\x011D"
> +#string STR_SCC_EMMC45_HS200_HELP                       #language uqi  "\x011E"
> +#string STR_SCC_EMMC45_RE_TUNE_TIMER_VALUE              #language uqi
> "\x011F"
> +#string STR_SCC_EMMC45_RE_TUNE_TIMER_VALUE_HELP         #language
> uqi  "\x0120"
> +#string STR_CFIO_PNP_SETTING_PROMPT                     #language uqi
> "\x0121"
> +#string STR_CFIO_PNP_SETTING_HELP                       #language uqi  "\x0122"
> +#string STR_EMMC_BOOT_PROMPT                            #language uqi  "\x0123"
> +#string STR_EMMC_BOOT_HELP                              #language uqi  "\x0124"
> +#string STR_WITT_PROMPT                                 #language uqi  "\x0125"
> +#string STR_SECURE_BOOT_TEST_PROMPT                     #language uqi
> "\x0126"
> +#string STR_TRISTATE_LPC_PROMPT                         #language uqi  "\x0127"
> +#string STR_DOP_CG_PROMPT                               #language uqi  "\x0128"
> +#string STR_PSS_ENABLE_PROMPT                           #language uqi  "\x0129"
> +#string STR_PSS_ENABLE_HELP                             #language uqi  "\x012A"
> +#string STR_ISCT_SLEEP_DURATION_FORMAT                  #language uqi
> "\x012B"
> +#string STR_ISCT_RF_KILL_SUPPORT                        #language uqi  "\x012C"
> +#string STR_SECURE_BOOT_UPP_PROMPT                      #language uqi
> "\x012D"
> +#string STR_MEASURED_BOOT_ENABLE_PROMPT                 #language uqi
> "\x012E"
> +#string STR_MEASURED_BOOT_ENABLE_HELP                   #language uqi
> "\x012F"
> +#string STR_PTT_PROMPT                                  #language uqi  "\x0130"
> +#string STR_CHECK_SHA256_HASH_MASTER_BOOT_CODES         #language
> uqi  "\x0131"
> +#string STR_USB_XHCI_LPM_SUPPORT_PROMPT      #language uqi  "\x0132"
> +
> +#string STR_VIRTUAL_KB_PROMPT                           #language uqi  "\x0135"
> +#string STR_VIRTUAL_KB_HELP                             #language uqi  "\x0136"
> +#string STR_TREE_OPERATION                              #language uqi  "\x0137"
> +#string STR_SLP_S0IX_N_PROMPT                           #language uqi  "\x0138"
> +#string STR_SLP_S0IX_N_HELP                             #language uqi  "\x0139"
> +#string STR_DPTF_AMBIENTTRIPPOINTCHANGE_PROMPT          #language
> uqi  "\x013A"
> +#string STR_DPTF_THERM0_PCAT_PROMPT                     #language uqi
> "\x013B"
> +#string STR_DPTF_THERM1_PCAT_PROMPT                     #language uqi
> "\x013C"
> +#string STR_DPTF_THERM2_PCAT_PROMPT                     #language uqi
> "\x013D"
> +#string STR_MMIO_PROMPT                                 #language uqi  "\x013E"
> +#string STR_UTS_PROMPT                                 #language uqi  "\x013F"
> +#string STR_UTS_HELP                                   #language uqi  "\x0140"
> +#string STR_WLAN_NGFF_CARD                              #language uqi  "\x0141"
> +#string STR_WLAN_UHPAM_CARD                             #language uqi  "\x0142"
> +#string STR_ENABLE_DBG2                                 #language uqi  "\x0143"
> +#string STR_DPTF_ALLOWHIGHERPERFORMANCE_PROMPT          #language
> uqi  "\x0144"
> +#string STR_DATP_PROMPT                                 #language uqi  "\x0145"
> +#string STR_DPTF_OFFLINING                              #language uqi  "\x0146"
> +#string STR_SAR_SENSOR_PROMPT                           #language uqi  "\x0147"
> +#string STR_DPTF_BRAND_STRING                           #language uqi  "\x0148"
> +#string STR_CODEC262_DISABLED_PROMPT                    #language uqi
> "\x0149"
> +#string STR_CODEC262_DISABLED_HELP                      #language uqi  "\x014A"
> +
> +//SD CARD SDR25 and DDR50
> +#string STR_SCC_SD_SDR25_PROMPT                         #language uqi  "\x014B"
> +#string STR_SCC_SD_SDR25_HELP                           #language uqi  "\x014C"
> +#string STR_SCC_SD_DDR50_PROMPT                         #language uqi  "\x014D"
> +#string STR_SCC_SD_DDR50_HELP                           #language uqi  "\x014E"
> +#string STR_SB_PROFILE_PROMPT                           #language uqi  "\x014F"
> +#string STR_SECURE_BOOT_PRO_KEY_PROMPT                  #language uqi
> "\x0150"
> +
> +#string STR_OS_SELETION_PROMPT                          #language uqi  "\x0151"
> +#string STR_OS_SELETION_HELP                            #language uqi  "\x0152"
> +#string STR_WINDOWS                                     #language uqi  "\x0153"
> +#string STR_ANDROID                                     #language uqi  "\x0154"
> +#string STR_AESNI_PROMPT                                #language uqi  "\x0155"
> +
> +#string STR_LPSS_I2C1_HELP_ENBDT_DEV_LIST               #language uqi
> "\x0156"
> +#string STR_LPSS_I2C2_HELP_ENBDT_DEV_LIST               #language uqi
> "\x0157"
> +#string STR_LPSS_I2C3_HELP_ENBDT_DEV_LIST               #language uqi
> "\x0158"
> +#string STR_LPSS_I2C4_HELP_ENBDT_DEV_LIST               #language uqi
> "\x0159"
> +#string STR_LPSS_I2C5_HELP_ENBDT_DEV_LIST               #language uqi
> "\x015A"
> +#string STR_LPSS_I2C6_HELP_ENBDT_DEV_LIST               #language uqi
> "\x015B"
> +#string STR_LPSS_I2C7_HELP_ENBDT_DEV_LIST               #language uqi
> "\x015C"
> +#string STR_LPSS_HSUART1_HELP_ENBDT_DEV_LIST            #language uqi
> "\x015D"
> +#string STR_LPSS_HSUART2_HELP_ENBDT_DEV_LIST            #language uqi
> "\x015E"
> +
> +#string STR_SECURE_ERASE_PROMPT                         #language uqi  "\x015F"
> +#string STR_SEC_FIRMWARE_WRITE_PROMPT                   #language uqi
> "\x0160"
> +
> +#string STR_BOOT_DISPLAY_MIPIDSI_PROMPT                 #language uqi
> "\x0161"
> +#string STR_SEC_FIRMWARE_TOGGLE_PROMPT                  #language uqi
> "\x0162"
> +#string STR_PCIEDYNCLK_PROMPT                           #language uqi  "\x0163"
> +#string STR_PAVP_LITE_MODE                              #language uqi  "\x0164"
> +#string STR_PAVP_SERPENT_MODE                           #language uqi  "\x0165"
> +#string STR_SCC_SDCARD_FORWIN_PROMPT                    #language uqi
> "\x0166"
> +#string STR_DROIDBOOT_PROMPT                            #language uqi  "\x0167"
> +#string STR_ANDROIDBOOT_PROMPT                          #language uqi  "\x0168"
> +
> +#string STR_CRITICAL_BATTERY_LIMIT_PROMPT    #language uqi  "\x0169"
> +#string STR_CRITICAL_BATTERY_LIMIT_HELP      #language uqi  "\x016A"
> +#string STR_CRITICAL_BATTERY_LIMIT_FEATURE_PROMPT  #language uqi
> "\x016B"
> +#string STR_CRITICAL_BATTERY_LIMIT_FEATURE_HELP    #language uqi
> "\x016C"
> +#string STR_WINDOWS7                                    #language uqi  "\x016D"
> +#string STR_LPSSDEVHIDE_PROMPT                          #language uqi  "\x016E"
> +#string STR_EM1_IAAPPSRUN_PROMPT                        #language uqi  "\x016F"
> +#string STR_EM1_IAAPPSCAP_PROMPT                        #language uqi  "\x0170"
> +#string STR_EM1_CAP_OR_VOLTAGE_PROMPT                   #language uqi
> "\x0171"
> +#string STR_EM1_BOOT_ON_INVALID_BAT_PROMPT              #language uqi
> "\x0172"
> +
> +#string STR_USB_HSIC_0_PROMPT                           #language uqi  "\x0173"
> +#string STR_USB_HSIC_0_HELP                             #language uqi  "\x0174"
> +#string STR_LEGACYUSBBOOTING_PROMPT                     #language uqi
> "\x0175"
> +#string STR_STR_LEGACYUSBBOOTING_HELP                   #language uqi
> "\x0176"
> +#string STR_LWINDOWS7                           #language uqi  "\x0177"
> +#string STR_WEC7                                #language uqi  "\x0178"
> +#string STR_LINUX                                #language uqi  "\x0179"
> +#string STR_WARNING_POPUP                               #language uqi  "\x017A"
> +#string STR_LPSS_HSUART1_FLOWCONTROL_PROMPT             #language uqi
> "\x017B"
> +#string STR_LPSS_HSUART2_FLOWCONTROL_PROMPT             #language uqi
> "\x017C"
> +#string STR_SCC_SDCARD_REMOVABILITY                     #language uqi
> "\x017D"
> +#string STR_SCC_SDCARD_REMOVABLE                        #language uqi  "\x017E"
> +#string STR_SCC_SDCARD_NON_REMOVABLE                    #language uqi
> "\x017F"
> +#string STR_SCC_SDCARD_REMOVABILITY_HELP                #language uqi
> "\x0180"
> +#string STR_RTC_BATTERY                                 #language uqi  "\x0181"
> +#string STR_RTC_BATTERY_NOT_PRESENT                     #language uqi
> "\x0182"
> +#string STR_RTC_BATTERY_PRESENT                         #language uqi  "\x0183"
> +#string STR_RTC_BATTERY_HELP                            #language uqi  "\x0184"
> +#string STR_LPE_REPORTED_BY_DSDT_PROMPT                 #language uqi
> "\x0185"
> +#string STR_LPE_REPORTED_BY_DSDT_HELP                   #language uqi
> "\x0186"
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Vfr.vfr
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Vfr.vfr
> new file mode 100644
> index 0000000000..77976322de
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Vfr.vfr
> @@ -0,0 +1,123 @@
> +//
> +//
> +//
> +// Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +//
> 
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +//
> 
> +//
> +//
> +#include "Configuration.h"
> +#include "PlatformSetupDxeStrDefs.h"
> +#include "Guid/SetupVariable.h"
> +
> +formset
> +  guid     = SYSTEM_CONFIGURATION_GUID,
> +  title    = STRING_TOKEN(STR_SYSTEM_SETUP_TITLE),
> +  help     = STRING_TOKEN(STR_SYSTEM_SETUP_HELP),
> +  class    = 1,
> +  subclass = 0,
> +
> +
> +  varstore SYSTEM_CONFIGURATION, name = Setup, guid =
> SYSTEM_CONFIGURATION_GUID;
> +  form formid = ROOT_FORM_ID,
> +    title    = STRING_TOKEN(STR_SYSTEM_SETUP_TITLE);
> +
> +    //
> +    // Jump to  2)Main Form
> +    //
> +    goto ROOT_MAIN_FORM_ID,
> +      prompt = STRING_TOKEN(STR_MAIN_TITLE),
> +      help   = STRING_TOKEN(STR_MAIN_HELP);
> +
> +    //
> +    // Jump to  3)Uncore Configuration Form
> +    //
> +    goto UNCORE_FORM_ID,
> +      prompt = STRING_TOKEN(STR_UNCORE_CONFIGURATION_TITLE),
> +      help   = STRING_TOKEN(STR_UNCORE_CONFIGURATION_HELP);
> +
> +    //
> +    // Jump to  4)South Cluster  Configuration Form
> +    //
> +    goto SOUTH_CLUSTER_FORM_ID,
> +      prompt = STRING_TOKEN(STR_SOUTH_CLUSTER_TITLE),
> +      help   = STRING_TOKEN(STR_SOUTH_CLUSTER_HELP);
> +
> +    // Jump to  5)Boot Form
> +    //
> +    goto BOOT_CONFIGURATION_FORM_ID,
> +      prompt = STRING_TOKEN(STR_BOOT_CONFIGURATION_TITLE),
> +      help   = STRING_TOKEN(STR_BOOT_CONFIGURATION_HELP);
> +
> +    //
> +    // Jump to  6)Security Configuration Form
> +    //
> +    goto SECURITY_CONFIGURATION_FORM_ID,
> +      prompt = STRING_TOKEN(STR_SECURITY_CONFIGURATION_TITLE),
> +      help   = STRING_TOKEN(STR_SECURITY_CONFIGURATION_HELP);
> +
> +    //
> +    // Jump to  7)Thermal Form
> +    //
> +    goto THERMAL_FORM_ID,
> +      prompt = STRING_TOKEN(STR_THERMAL_TITLE),
> +      help   = STRING_TOKEN(STR_THERMAL_HELP);
> +
> +    //
> +    // Jump to 8) System Component Form
> +    goto SYSTEM_COMPONENT_FORM_ID,
> +      prompt = STRING_TOKEN(STR_SYSTEM_COMPONENT_TITLE),
> +      help   = STRING_TOKEN(STR_SYSTEM_COMPONENT_HELP);
> +
> +    //
> +    // Jump to  10)Debug Configuration Form
> +    //
> +#if (BYTI_PF_ENABLE == 0)
> +    goto DEBUG_CONFIGURATION_FORM_ID,
> +      prompt = STRING_TOKEN(STR_DEBUG_CONFIGURATION_TITLE),
> +      help   = STRING_TOKEN(STR_DEBUG_CONFIGURATION_HELP);
> +#endif
> +
> +    subtitle text = STRING_TOKEN(STR_NULL_STRING);
> +    //
> +    // Commit change and exit
> +    //
> +    text
> +      help   = STRING_TOKEN(STR_COMMIT_CHANGE_AND_EXIT_HELP),
> +      text   = STRING_TOKEN(STR_COMMIT_CHANGE_AND_EXIT_PROMPT),
> +      text   = STRING_TOKEN(STR_COMMIT_CHANGE_AND_EXIT_PROMPT),
> +      flags  = INTERACTIVE,
> +      key    = 0xF001;
> +
> +    //
> +    // Discard change and exit
> +    //
> +    text
> +      help   = STRING_TOKEN(STR_DISCARD_CHANGE_AND_EXIT_HELP),
> +      text   = STRING_TOKEN(STR_DISCARD_CHANGE_AND_EXIT_PROMPT),
> +      text   = STRING_TOKEN(STR_DISCARD_CHANGE_AND_EXIT_PROMPT),
> +      flags  = INTERACTIVE,
> +      key    = 0xF002;
> +
> +    //
> +    // Load default and exit
> +    //
> +    text
> +      help   = STRING_TOKEN(STR_LOAD_DEFAULT_AND_EXIT_HELP),
> +      text   = STRING_TOKEN(STR_LOAD_DEFAULT_AND_EXIT_PROMPT),
> +      text   = STRING_TOKEN(STR_LOAD_DEFAULT_AND_EXIT_PROMPT),
> +      flags  = INTERACTIVE,
> +      key    = 0xF003;
> +  endform;
> +
> +  #include "Main.vfi"
> +  #include "UnCore.vfi"
> +  #include "SouthClusterConfig.vfi"
> +  #include "Boot.vfi"
> +  #include "Security.vfi"
> +  #include "Thermal.vfi"
> +  #include "SystemComponent.vfi"
> +  #include "DebugConfig.vfi"
> +endformset;
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/VfrStrings.uni
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/VfrStrings.uni
> new file mode 100644
> index 0000000000..42c767e30d
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/VfrStrings.uni
> @@ -0,0 +1,1417 @@
> +// /** @file
> +// Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//
> +// Module Name:
> +//
> +//   Strings.vfr
> +//
> +// Abstract:
> +//
> +//   String definitions for Platform Setup formset.
> +//
> +// Revision History:
> +//
> +// **/
> +
> +//
> +// NOTE: for SETUP engine spacing, the following character spaces denote
> how much room in each section you have.
> +//       In the Help Text section "                       " -this is 23 spaces wide.
> +//       In the Far left panel "                                     " -this is 37 spaces wide.
> +//       In the middle section "                                     " -this is 37 spaces wide.
> +//
> +/=#
> +
> +#langdef   en-US "English"
> +#langdef   fr-FR "Français"
> +
> +// STR_LANG_NAME is dummy for font extrace tool.  Without this,
> +// some characters for language selection menu will not be displayed
> +// correctly.
> +#string STR_LANG_NAME #language  fr-FR "Français"
> +#string STR_LANG_NAME #language  en-US "English"
> +
> +//Root form
> +#string STR_SYSTEM_SETUP_TITLE                          #language en-US "System
> Setup"
> +#string STR_SYSTEM_SETUP_HELP                           #language en-US "Press
> <Enter> to select the System Configuration Setup options."
> +
> +#string STR_MAIN_TITLE                                  #language en-US "Main"
> +#string STR_MAIN_HELP                                   #language en-US ""
> +
> +#string STR_CPU_CONFIGURATION_TITLE                     #language en-US "CPU
> Configuration"
> +#string STR_CPU_CONFIGURATION_HELP                      #language en-US ""
> +
> +#string STR_CPU_POWERMNG_TITLE                          #language en-US "CPU
> Power Management"
> +#string STR_CPU_POWERMNG_HELP                           #language en-US ""
> +
> +#string STR_BOOT_CONFIGURATION_TITLE                    #language en-US
> "Boot"
> +#string STR_BOOT_CONFIGURATION_HELP                     #language en-US ""
> +
> +#string STR_IGD_TITLE                                   #language en-US "IGD
> Configuration"
> +#string STR_IGD_HELP                                    #language en-US ""
> +
> +#string STR_MEMORY_CONFIGURATION_TITLE                  #language en-US
> "Memory Configuration"
> +#string STR_MEMORY_CONFIGURATION_HELP                   #language en-US ""
> +
> +#string STR_ISP_ENABLED                                 #language en-US "ISP
> Enable/Disable"
> +#string STR_ISP_ENABLED_HELP                            #language en-US
> "Enable/Disable ISP PCI Device Selection."
> +
> +#string STR_ISP_CONFIGURATION_TITLE                     #language en-US "ISP
> PCI Device Configuration"
> +#string STR_ISP_PCICONFIGURATION_TITLE                  #language en-US "ISP
> PCI Device Selection"
> +#string STR_ISP_PCICONFIGURATION_HELP                   #language en-US
> "Default ISP is PCI B0D2F0 for Window Boot. Linux Boot to select B0D3F0"
> +#string STR_ISP_PCICONFIG_B0D2F0_TITLE                  #language en-US "ISP
> PCI Device as B0D2F0"
> +#string STR_ISP_PCICONFIG_B0D3F0_TITLE                  #language en-US "ISP
> PCI Device as B0D3F0"
> +
> +#string STR_SECURITY_CONFIGURATION_TITLE                #language en-US
> "Security Configuration"
> +#string STR_SECURITY_CONFIGURATION_HELP                 #language en-US ""
> +
> +#string STR_SOUTH_CLUSTER_TITLE                         #language en-US "South
> Cluster Configuration"
> +#string STR_SOUTH_CLUSTER_HELP                          #language en-US ""
> +
> +#string STR_UNCORE_CONFIGURATION_TITLE                  #language en-US
> "Uncore Configuration"
> +#string STR_UNCORE_CONFIGURATION_HELP                   #language en-US ""
> +
> +#string STR_DPTF_CONFIGURATION_TITLE                    #language en-US
> "DPTF"
> +#string STR_DPTF_CONFIGURATION_HELP                     #language en-US ""
> +
> +#string STR_THERMAL_TITLE                               #language en-US "Thermal"
> +#string STR_THERMAL_HELP                                #language en-US ""
> +
> +#string STR_SYSTEM_COMPONENT_TITLE                      #language en-US
> "System Component"
> +#string STR_SYSTEM_COMPONENT_HELP                       #language en-US ""
> +
> +#string STR_DEBUG_CONFIGURATION_TITLE                  #language en-US
> "Debug Configuration"
> +#string STR_DEBUG_CONFIGURATION_HELP                   #language en-US ""
> +
> +//
> +// Main form definition
> +//
> +#string STR_DATE_PROMPT                                 #language en-US "System
> Date"
> +
> +
> +#string STR_DATE_YEAR_HELP                              #language en-US  "Displays
> and changes the System Date from the Real-Time Clock. Format is
> Month/Day/Year. "
> +#string STR_DATE_MONTH_HELP                             #language en-US  "Displays
> and changes the System Date from the Real-Time Clock. Format is
> Month/Day/Year. "
> +#string STR_DATE_DAY_HELP                               #language en-US  "Displays and
> changes the System Date from the Real-Time Clock. Format is
> Month/Day/Year. "
> +#string STR_ERROR_POPUP                                 #language en-US  "Try Again"
> +#string STR_BIOS_INFORMATION_TITLE                      #language en-US  "Bios
> Information"
> +
> +#string STR_NULL_STRING                                 #language en-US  ""
> +#string STR_NULL_STRING                                 #language fr-FR  ""
> +
> +#string STR_BIOS_VENDOR_STRING                          #language en-US "BIOS
> Vendor"
> +#string STR_BIOS_VENDOR_STRING                          #language fr-FR "Verdor
> du BIOS"
> +
> +#string STR_BIOS_VENDOR_VALUE                           #language en-US  "Intel
> Corporation"
> +#string STR_BIOS_VENDOR_VALUE                           #language fr-FR  ""
> +
> +#string STR_BIOS_VERSION_STRING                         #language en-US "BIOS
> Version"
> +#string STR_BIOS_VERSION_STRING                         #language fr-FR "Version
> du BIOS"
> +
> +#string STR_BIOS_VERSION_VALUE                          #language en-US  ""
> +#string STR_BIOS_VERSION_VALUE                          #language fr-FR  ""
> +
> +#string STR_IFWI_VERSION_STRING                         #language en-US "IFWI
> Version"
> +#string STR_IFWI_VERSION_STRING                         #language fr-FR "Version
> du IFWI"
> +
> +#string STR_IFWI_VERSION_VALUE                          #language en-US  ""
> +#string STR_IFWI_VERSION_VALUE                          #language fr-FR  ""
> +
> +#string STR_BIOS_BUILD_TIME_STRING                      #language en-US "Build
> Time"
> +#string STR_BIOS_BUILD_TIME_VALUE                       #language en-US "NA"
> +
> +#string STR_CORE_VERSION_STRING                         #language en-US "Core
> Version"
> +#string STR_CORE_VERSION_VALUE                          #language en-US "UEFI
> 2.40"
> +
> +#string STR_SEC_VERSION_STRING                          #language en-US "TXE FW
> Version"
> +#string STR_SEC_VERSION_VALUE                           #language en-US ""
> +
> +#string STR_SEC_CAPABILITY_STRING                       #language en-US "TXE FW
> Capabilities"
> +#string STR_SEC_CAPABILITY_VALUE                        #language en-US ""
> +
> +#string STR_SEC_FEATURE_STRING                          #language en-US "TXE FW
> Features"
> +#string STR_SEC_FEATURE_VALUE                           #language en-US ""
> +
> +#string STR_SEC_OEMTAG_STRING                           #language en-US "TXE FW
> OEM Tag"
> +#string STR_SEC_OEMTAG_VALUE                            #language en-US ""
> +
> +#string STR_SEC_FILE_SYSTEM_INTEGRITY_VALUE_STRING      #language
> en-US "TXE File System Integrity Value"
> +#string STR_SEC_FILE_SYSTEM_INTEGRITY_VALUE             #language en-US
> ""
> +
> +#string STR_SEC_TEMP_DISABLE_HELP                       #language en-US "TXE
> Temporary Disable"
> +#string STR_SEC_TEMP_DISABLE_STRING                     #language en-US "TXE
> Firmware Mode"
> +#string STR_SEC_TEMP_DISABLE_PROMPT                     #language en-US "TXE
> Temporary Disable"
> +
> +#string STR_SEC_LOCAL_FW_UPDATE_HELP                    #language en-US
> "TXE Disable/Enable TXE Local Fw Update"
> +#string STR_SEC_LOCAL_FW_UPDATE_STRING                  #language en-US
> "TXE Local Fw Update"
> +#string STR_SEC_LOCAL_FW_UPDATE_PROMPT                  #language en-US
> "TXE Temporary Disable"
> +
> +#string STR_SEC_FIRMWARE_WRITE_PROMPT                   #language en-US
> "TXE Firmware R/W Mode"
> +#string STR_SEC_FIRMWARE_WRITE_VALUE                    #language en-US ""
> +
> +#string STR_SEC_FIRMWARE_TOGGLE_PROMPT                   #language en-US
> "TXE Firmware R/W Toggle"
> +#string STR_SEC_FIRMWARE_TOGGLE_HELP                     #language en-US
> "Use to Toggle between R/W and R/O"
> +#string STR_SEC_FIRMWARE_TOGGLE_NO                       #language en-US
> "No"
> +#string STR_SEC_FIRMWARE_TOGGLE_YES                      #language en-US
> "Yes"
> +
> +#string STR_SEC_HMRFPO_HELP                             #language en-US "TXE
> HMRFPO Disable"
> +#string STR_SEC_HMRFPO_STRING                           #language en-US "TXE
> HMRFPO "
> +#string STR_SEC_HMRFPO_PROMPT                           #language en-US "TXE
> HMRFPO Disable"
> +
> +#string STR_SEC_EOP_HELP                                #language en-US "Send EOP
> Message Befor Enter OS"
> +#string STR_SEC_EOP_PROMPT                              #language en-US "TXE EOP
> Message"
> +
> +#string STR_PLATFORM_INFORMATION_TITLE                  #language en-US
> "Platform Information"
> +#string STR_PLATFORM_INFORMATION_HELP                   #language en-US
> "Display platform information"
> +
> +#string STR_PROCESSOR_INFO_STRING                       #language en-US
> "Processor Information"
> +#string STR_PROCESSOR_VERSION_STRING                    #language en-US
> "Processor Type"
> +#string STR_PROCESSOR_VERSION_VALUE                     #language en-US
> "N/A"
> +#string STR__STRING                                     #language en-US "  "
> +#string STR__VALUE                                      #language en-US ""
> +#string STR_PROCESSOR_SPEED_STRING                      #language en-US
> "Processor Speed"
> +#string STR_PROCESSOR_SPEED_VALUE                       #language en-US ""
> +#string STR_PROCESSOR_MICROCODE_STRING                  #language en-US
> "Microcode Revision"
> +#string STR_PROCESSOR_MICROCODE_VALUE                   #language en-US
> "Not loaded"
> +#string STR_PROCESSOR_CORE_STRING                       #language en-US
> "Number of Cores"
> +#string STR_PROCESSOR_CORE_VALUE                        #language en-US "1"
> +#string STR_EM64T_CAPABILITY_STRING                     #language en-US "Intel(r)
> 64 Architecture Capable"
> +#string STR_EM64T_CAPABILITY_VALUE                      #language en-US
> "Support"
> +
> +#string STR_PLATFORM_FIRMWARE_STRING                    #language en-US
> "Platform firmware Information"
> +
> +#string STR_MFGMODE                                    #language en-US "Manufacture
> Mode"
> +#string STR_MFGMODE_HELP                               #language en-US
> "Manufacture Mode Status"
> +
> +
> +
> +#string STR_MEMORY_INFORMATION_STRING                   #language en-US
> "Memory Information"
> +#string STR_TOTAL_MEMORY_SIZE_PROMPT                    #language en-US
> "Total Memory"
> +#string STR_TOTAL_MEMORY_SIZE_VALUE                     #language en-US ""
> +#string STR_MEMORY_SPEED_PROMPT                         #language en-US
> "DIMM Frequency"
> +#string STR_MEMORY_SPEED_PROMPT_VALUE                   #language en-US
> ""
> +#string STR_PROCESSOR_L1_DATA_CACHE_STRING              #language en-US
> "L1 Data Cache"
> +#string STR_PROCESSOR_L1_DATA_CACHE_VALUE               #language en-US
> "N/A"
> +#string STR_PROCESSOR_L1_INSTR_CACHE_STRING             #language en-US
> "L1 Instruction Cache"
> +#string STR_PROCESSOR_L1_INSTR_CACHE_VALUE              #language en-US
> "N/A"
> +#string STR_PROCESSOR_L2_CACHE_STRING                   #language en-US "L2
> Cache RAM"
> +#string STR_PROCESSOR_L2_CACHE_VALUE                    #language en-US
> "NO"
> +#string STR_SYSTEM_MEMORY_SPEED_STRING                  #language en-US
> "Memory Speed"
> +#string STR_SYSTEM_MEMORY_SPEED_VALUE                   #language en-US
> ""
> +
> +#string STR_CHIP_IGD_VBIOS_REV_HELP                     #language en-US "IGD
> VBIOS Version"
> +#string STR_CHIP_IGD_VBIOS_REV_NAME                     #language en-US "IGD
> VBIOS Version"
> +#string STR_CHIP_IGD_VBIOS_REV_VALUE                    #language en-US
> "N/A"
> +
> +#string STR_CPU_FLAVOR_HELP                             #language en-US "CPU
> Flavor"
> +#string STR_CPU_FLAVOR_NAME                             #language en-US "CPU
> Flavor"
> +#string STR_CPU_FLAVOR_VALUE                            #language en-US "N/A"
> +
> +#string STR_BOARD_INFORMATION_STRING                    #language en-US
> "Board Information"
> +#string STR_BOARD_ID_HELP                               #language en-US "Displays the
> Board ID."
> +#string STR_BOARD_ID_NAME                               #language en-US "Board ID"
> +#string STR_BOARD_ID_VALUE                              #language en-US "N/A"
> +
> +//
> +// CPU INFORMATION
> +//
> +#string STR_CPU_FORM_SUBTITLE                           #language en-US
> "Processor Information"
> +
> +#string STR_PROCESSOR_VERSION_HELP                      #language en-US
> "Displays the Processor Type."
> +#string STR_PROCESSOR_VERSION_STRING                    #language en-US
> "Type"
> +#string STR_PROCESSOR_VERSION_VALUE                     #language en-US
> "N/A"
> +
> +#string STR_PROCESSOR_SKU_HELP        #language en-US "Displays the
> Processor SKU Type."
> +#string STR_PROCESSOR_SKU_STRING      #language en-US "SKU Type"
> +#string STR_PROCESSOR_SKU_VALUE        #language en-US "N/A"
> +
> +#string STR_PROCESSOR_SPEED_STRING                      #language en-US
> "Speed"
> +#string STR_PROCESSOR_SPEED_VALUE                       #language en-US "N/A"
> +#string STR_PROCESSOR_SPEED_HELP                        #language en-US
> "Displays the Processor Speed."
> +
> +#string STR_PROCESSOR_ID_STRING                         #language en-US
> "Family/Model/Step"
> +#string STR_PROCESSOR_ID_VALUE                          #language en-US "N/A"
> +#string STR_PROCESSOR_ID_HELP                           #language en-US
> "Family/Model/Step of Processor"
> +
> +#string STR_PROCESSOR_STEPPING_STRING                   #language en-US
> "Stepping"
> +#string STR_PROCESSOR_STEPPING_VALUE                    #language en-US
> "Unknown"
> +#string STR_PROCESSOR_STEPPING_HELP                     #language en-US
> "Displays the Processor Stepping."
> +
> +
> +#string STR_FAB_ID_HELP                                 #language en-US "Displays the
> Fab ID"
> +#string STR_FAB_ID_STRING                               #language en-US "Fab ID"
> +#string STR_FAB_ID_VALUE                                #language en-US "N/A"
> +
> +#string STR_TIME_PROMPT                                 #language en-US "System
> Time"
> +#string STR_TIME_HOUR_HELP                              #language en-US "Displays
> and changes the System Time from the Real-Time Clock. Clock is displayed in
> 24-hour format. "
> +#string STR_TIME_MINUTE_HELP                            #language en-US "Displays
> and changes the System Time from the Real-Time Clock. Clock is displayed in
> 24-hour format. 9"
> +#string STR_TIME_SECOND_HELP                            #language en-US "Displays
> and changes the System Time from the Real-Time Clock. Clock is displayed in
> 24-hour format. "
> +
> +//
> +// Boot form definition
> +//
> +#string STR_FAST_BOOT_PROMPT                            #language en-US "Fast
> Boot"
> +#string STR_FAST_BOOT_HELP                              #language en-US "Enable or
> Disable FastBoot features. \n Most probes are skipped to reduce time cost
> during boot."
> +#string STR_SECURITY_BOOT_PROMPT                        #language en-US "UEFI
> Security Boot"
> +#string STR_SECURITY_BOOT_HELP                          #language en-US
> "Disable/Enable UEFI Security boot feature"
> +#string STR_LOG_BOOT_TIME_PROMPT                        #language en-US
> "BootTime Log"
> +#string STR_LOG_BOOT_TIME_HELP                          #language en-US
> "BootTime for OS Booting"
> +#string STR_LOG_BOOT_TIME_RECORD                        #language en-US "
> Latest BootTime"
> +#string STR_LOG_BOOT_TIME_VALUE                         #language en-US "No
> Record"
> +#string STR_QUIETBOOT_PROMPT                            #language en-US "Silent
> Boot"
> +#string STR_QUIETBOOT_HELP                              #language en-US "Disable
> console output and show logo if it is enabled."
> +#string STR_LEGACYUSBBOOTING_PROMPT                     #language en-US
> "Legacy USB Booting"
> +#string STR_STR_LEGACYUSBBOOTING_HELP                   #language en-US
> "Enable or Disable Legacy USB Booting features."
> +#string STR_DROIDBOOT_PROMPT                            #language en-US "Droid
> Boot"
> +#string STR_DROIDBOOT_HELP                              #language en-US "Go to
> Droidboot to flash Android Image"
> +#string STR_ANDROIDBOOT_PROMPT                            #language en-US
> "Android Boot"
> +#string STR_ANDROIDBOOT_HELP                              #language en-US "Boot
> android OS"
> +
> +// Enable or Disable or Automatic
> +#string STR_ENABLE                                      #language en-US  "Enable"
> +#string STR_ENABLE                                      #language fr-FR  "Activé"
> +
> +#string STR_DISABLE                                     #language en-US  "Disable"
> +#string STR_DISABLE                                     #language fr-FR  "Désactivé"
> +
> +#string STR_PCI_MODE                                     #language en-US  "PCI Mode"
> +#string STR_ACPI_MODE                                    #language en-US  "ACPI Mode"
> +
> +#string STR_ENABLED                                      #language en-US  "Enabled"
> +#string STR_ENABLED                                      #language fr-FR  "Activé"
> +
> +#string STR_DISABLED                                     #language en-US  "Disabled"
> +#string STR_DISABLED                                     #language fr-FR  "Désactivé"
> +#string STR_AUTOMATIC                                   #language en-US  "Auto"
> +#string STR_AUTOMATIC                                   #language fr-FR  "Auto"
> +
> +#string STR_ON                                          #language en-US  "ON"
> +#string STR_OFF                                         #language en-US  "OFF"
> +
> +#string STR_YES                                         #language en-US  "YES"
> +#string STR_NO                                          #language en-US  "NO"
> +
> +//
> +//CPU Features Configuration
> +//
> +#string STR_ACTIVE_CORE_COUNT_PROMPT                    #language en-US
> "Active Processor Cores"
> +#string STR_ACTIVE_CORE_COUNT_PROMPT_HELP               #language en-US
> "Number of cores to enable in each processor package."
> +
> +#string STR_AESNI_PROMPT                                #language en-US "AESNI
> Feature"
> +#string STR_AESNI_PROMPT_HELP                           #language en-US
> "Enable/Disable AESNI ."
> +
> +#string STR_EXECUTE_DISABLE_BIT_PROMPT                  #language en-US
> "Execute Disable Bit"
> +#string STR_EXECUTE_DISABLE_BIT_HELP                    #language en-US
> "Execute Disable Bit prevent certain classes of malicious buffer overflow
> attacks when combined with a supporting OS"
> +
> +#string STR_LIMIT_CPUID_MAX_PROMPT                      #language en-US
> "Limit CPUID Maximum"
> +#string STR_LIMIT_CPUID_MAX_HELP                        #language en-US
> "Disabled for Windows XP"
> +
> +#string STR_CORE_FRE_MULTIP_SELECT_PROMPT               #language en-US
> "Core Frequency Multiplier select"
> +#string STR_CORE_FRE_MULTIP_SELECT_HELP                 #language en-US
> "for Debug only"
> +
> +#string STR_VTX2_PROMPT                                 #language en-US "VTX-2"
> +#string STR_VTX2_HELP                                   #language en-US "To enable or
> disable the VTX-2 Mode support"
> +
> +#string STR_PROC_HOT_ENABLE                             #language en-US  "Bi-
> directional PROCHOT#"
> +#string STR_PROC_HOT_ENABLE_HELP                        #language en-US  "When
> a processor thermal sensor trips (either core), the PROCHOT# will be
> driven.\nIf bi-direction is enabled, external agents can drive PROCHOT# to
> throttle the processor."
> +#string STR_TM1_PROMPT                                  #language en-US  "TM1 "
> +#string STR_TM1_PROMPT_HELP                             #language en-US
> "Enable/Disable TM1"
> +#string STR_TM2_PROMPT                                  #language en-US  "TM2 "
> +#string STR_TM2_PROMPT_HELP                             #language en-US
> "Enable/Disable TM2"
> +#string STR_DTS_PROMPT                                  #language en-US  "DTS "
> +#string STR_DTS_PROMPT_HELP                             #language en-US
> "Enabled/Disable Digital Thermal Sensor"
> +#string STR_ACTIVE_PROCESSOR_CORES_PROMPT               #language en-US
> "Active Processor Cores"
> +#string STR_ACTIVE_PROCESSOR_CORES_HELP                 #language en-US
> "Number of cores to enable in each processor package"
> +#string STR_PROCESSOR_HT_MODE                           #language en-US "Intel(r)
> Hyper-Threading Technology"
> +#string STR_PROCESSOR_HT_MODE_HELP                      #language en-US
> "When disabled, only one thread per active core will be available."
> +#string STR_CAPABILITY_NOT_SUPPORT                      #language en-US "Not
> Supported"
> +
> +#string STR_ALL                                         #language en-US "ALL"
> +#string STR_1                                           #language en-US  "1"
> +
> +//
> +//CPU Power Option
> +//
> +#string STR_SYSTEM_POWER_OPTIONS                        #language en-US
> "System Power Options"
> +#string STR_BOOT_P_STATE                                #language en-US "Boot
> performance mode"
> +#string STR_BOOT_P_STATE_HELP                           #language en-US "Select
> the performance state that the BIOS will set before OS handoff."
> +#string STR_BOOT_P_STATE_MAX                            #language en-US "Max
> Performance"
> +#string STR_BOOT_P_STATE_MIN                            #language en-US "Max
> Battery"
> +#string STR_BOOT_P_STATE_FLEX                           #language en-US "Flexible
> Ratio(Override)"
> +#string STR_CPU_IST_PROMPT                              #language en-US "Intel(R)
> SpeedStep(tm)"
> +#string STR_CPU_IST_HELP                                #language en-US "Allows more
> than two frequency ranges to be supported."
> +#string STR_CSTATE_PROMPT                               #language en-US "C-States"
> +#string STR_CSTATE_PROMPT_HELP                          #language en-US
> "Enable/Disable C States"
> +#string STR_CXE_PROMPT                                  #language en-US "  Enhanced C-
> states"
> +#string STR_CXE_PROMPT_HELP                             #language en-US
> "Enable/Disable C1E, C2E and C4E. When enabled, CPU will switch to
> minimum speed when all cores enter C-State."
> +#string STR_HARDC4E_PROMPT                              #language en-US  "Hard C4E"
> +#string STR_HARDC4E_PROMPT_HELP                         #language en-US
> "Enable/Disable Hard C4E"
> +#string STR_PROCESSOR_TURBO_MODE                        #language en-US
> "Intel(r) Turbo Boost Technology"
> +#string STR_PROCESSOR_TURBO_MODE_HELP                   #language en-US
> "Enable to automatically allow processor cores to run faster than the base
> operating frequency if it's operating below power, current, and temperature
> specification limits. Turbo will be disabled under auto mode if SoC is B0
> Stepping"
> +#string STR_MAX_C_STATE_SUPPORT_PROMPT                  #language en-US
> "  Max C State"
> +#string STR_MAX_C_STATE_SUPPORT_HELP                    #language en-US
> "This option controls the Max C State that the processor will support."
> +#string STR_CSTATE_C7                                   #language en-US  "C7"
> +#string STR_CSTATE_C6                                   #language en-US  "C6"
> +#string STR_CSTATE_C4                                   #language en-US  "C4"
> +#string STR_CSTATE_C1                                   #language en-US  "C1"
> +#string STR_CX_POPDOWN_PROMPT                           #language en-US "C-
> state POPDOWN"
> +#string STR_CX_POPDOWN_PROMPT_HELP                      #language en-US
> "Disabling the option, prevents automatic return to a previous C3 or C4
> states"
> +#string STR_CX_POPUP_PROMPT                             #language en-US "C-state
> POPUP"
> +#string STR_CX_POPUP_PROMPT_HELP                        #language en-US "On
> enabled, SB observes bus master request, will take system from a C3/C4
> state to a C2 state and auto enables bus masters."
> +#string STR_PPM_C4_EXIT_PROMPT                          #language en-US "C4 Exit
> Timing"
> +#string STR_PPM_C4_EXIT_HELP                            #language en-US "This
> option controls a programmable time for the CPU voltage to stabilize when
> exiting from a C4 state."
> +#string STR_PPM_DEFAULT_C4_EXIT                         #language en-US
> "Default"
> +#string STR_PPM_FAST_C4_EXIT                            #language en-US "Fast"
> +#string STR_PPM_SLOW_C4_EXIT                            #language en-US "Slow"
> +#string STR_PPM_FORCE_SLOW_C4_EXIT                      #language en-US
> "Force Slow"
> +
> +
> +//
> +// IGD Configuration form
> +//
> +#string STR_IGD_LCD_CONTROL                            #language en-US "IGD - LCD
> Control"
> +#string STR_BOOT_DISPLAY_DEVICE_PROMPT                 #language en-US
> "IGD Boot Type"
> +#string STR_BOOT_DISPLAY_DEVICE_HELP                   #language en-US
> "Select preference for Integrated Graphics Device (IGD) display interface
> used when system boots."
> +#string STR_EDP                                        #language en-US "eDP"
> +#string STR_HDMI                                       #language en-US "HDMI"
> +#string STR_MIPI2DSI                                   #language en-US "MIPI-DSI"
> +#string STR_VGAPORT                                    #language en-US "VGA Port"
> +#string STR_HDMIPORTB                                  #language en-US "HDMI"
> +#string STR_DPPORTB                                    #language en-US "DP Port B"
> +#string STR_DPPORTC                                    #language en-US "DP Port C"
> +#string STR_EDPPORTC                                   #language en-US "eDP"
> +#string STR_DSIPORTA                                   #language en-US "DSI PORT A"
> +#string STR_DSIPORTC                                   #language en-US "DSI PORT C"
> +
> +#string STR_IGD_FLAT_PANEL_PROMPT                      #language en-US "LCD
> Panel Type"
> +#string STR_IGD_FLAT_PANEL_HELP                        #language en-US "Select
> the LCD panel used by Internal Graphics Device by selecting the appropriate
> setup item."
> +#string STR_640X480                                    #language en-US "640 x 480"
> +#string STR_800X600                                    #language en-US "800 x 600"
> +#string STR_1024X768                                   #language en-US "1024 x 768"
> +#string STR_1280X1024                                  #language en-US "1280 x 1024"
> +#string STR_1366X768                                   #language en-US "1366 x 768"
> +#string STR_1680X1050                                  #language en-US "1680 x 1050"
> +#string STR_1920X1200                                  #language en-US "1920 x 1200"
> +#string STR_1280X800                                   #language en-US "1280 x 800"
> +
> +#string STR_IGD_LCD_CONTROL                            #language en-US "IGD - LCD
> Control"
> +#string STR_IGD_FIXED_GRAPHICS_MEMORY_SIZE             #language en-US
> "IGD Fixed Graphics Memory"
> +#string STR_128MB                                      #language en-US "128 MB"
> +#string STR_256MB                                      #language en-US "256 MB"
> +
> +#string STR_IGD_THERMAL_PROMPT                         #language en-US "IGD
> Thermal"
> +#string STR_IGD_THERMAL_HELP                           #language en-US "Check to
> enable thermal monitoring on IGD."
> +
> +#string STR_GFX_BOOST_PROMPT                           #language en-US "GFX
> Boost"
> +#string STR_GFX_BOOST_HELP                             #language en-US
> "Enable/Disable GFX boost"
> +
> +#string STR_SPREAD_SPECTRUM_CLOCK_PROMPT               #language en-US
> "Spread Spectrum clock"
> +#string STR_SPREAD_SPECTRUM_CLOCK_HELP                 #language en-US
> "Enable/Disable Spread Spectrum clock"
> +
> +#string STR_FORCE_LID_STATUS_PROMPT                    #language en-US
> "Force Lid Status"
> +#string STR_LID_STATUS__AUTO_PROMPT                    #language en-US
> "Auto"
> +#string STR_LID_STATUS__ON_PROMPT                      #language en-US "ON"
> +#string STR_LID_STATUS__OFF_PROMPT                     #language en-US "OFF"
> +#string STR_FORCE_LID_STATUS_TABLET_HELP               #language en-US
> "For test: force to set lid status as on or off"
> +#string STR_FORCE_LID_STATUS_ENBDT_HELP                #language en-US
> "For AUTO: BIOS updates LID Status as per Virtual LID Switch. For ON/OFF:
> BIOS force to set lid status as ON or OFF"
> +
> +#string STR_PANNEL_SCALING_PROMPT                      #language en-US "Panel
> Scaling"
> +#string STR_PANNEL_SCALING_HELP                        #language en-US "Select
> the LCD panel scaling option used by Internal Graphics Device."
> +#string STR_PANNEL_SCALING_STRETCH                     #language en-US
> "Centering"
> +#string STR_PANNEL_SCALING_CENTER                      #language en-US
> "Stretching"
> +
> +#string STR_VIDEO_LCD_IGMCHBLC_PROMPT                  #language en-US
> "GMCH BLC Control"
> +#string STR_VIDEO_LCD_IGMCHBLC_HELP                    #language en-US  "Back
> Light Control Setting"
> +#string STR_VIDEO_LCD_IGMCHBLC1                        #language en-US  "PWM-
> Inverted"
> +#string STR_VIDEO_LCD_IGMCHBLC2                        #language en-US
> "GMBus-Inverted"
> +#string STR_VIDEO_LCD_IGMCHBLC3                        #language en-US  "PWM-
> Normal"
> +#string STR_VIDEO_LCD_IGMCHBLC4                        #language en-US
> "GMBus-Normal"
> +
> +
> +#string STR_VIDEO_LCD_IBIA                             #language en-US  "BIA"
> +#string STR_VIDEO_LCD_IBIAA                            #language en-US  "Auto"
> +#string STR_VIDEO_LCD_IBIAD                            #language en-US  "Disabled"
> +#string STR_VIDEO_LCD_IBIAL1                           #language en-US  "Level 1"
> +#string STR_VIDEO_LCD_IBIAL2                           #language en-US  "Level 2"
> +#string STR_VIDEO_LCD_IBIAL3                           #language en-US  "Level 3"
> +#string STR_VIDEO_LCD_IBIAL4                           #language en-US  "Level 4"
> +#string STR_VIDEO_LCD_IBIAL5                           #language en-US  "Level 5"
> +#string STR_VIDEO_LCD_IBIAHLP                          #language en-US  ">>Auto:
> GMCH Use VBIOS Default;           >>Level n: Enabled with Selected
> Aggressiveness Level."
> +
> +#string STR_PRIMARY_DISPLAY                            #language en-US  "Primary
> Display"
> +#string STR_PRIMARY_DISPLAY_HELP                       #language en-US  "Select
> which of IGD/PCI Graphics device should be Primary Display"
> +#string STR_IGD_STRING                                 #language en-US  "IGD"
> +#string STR_PCI_STRING                                 #language en-US  "PCIe"
> +
> +#string STR_VIDEO_RS2_PROMPT                           #language en-US
> "RC6(Render Standby)"
> +#string STR_VIDEO_RS2_HELP                             #language en-US  "Check to
> enable render standby support, RC6 should be enabled if S0ix is
> enabled.\n\nThis item will be read only if S0ix is enabled"
> +
> +#string STR_PAVC_PROMPT                                #language en-US  "PAVC"
> +#string STR_PAVC_HELP                                  #language en-US  "Enable/Disable
> Protected Audio Video Control"
> +#string STR_PAVP_LITE_MODE                             #language en-US  "LITE Mode"
> +#string STR_PAVP_SERPENT_MODE                          #language en-US
> "SERPENT Mode"
> +#string STR_DVMT40_TITLE                               #language en-US  "DVMT4.0
> Graphic memory setting"
> +#string STR_DVMT40_PRE_ALLOC                           #language en-US  "DVMT
> Pre-Allocated"
> +#string STR_DVMT40_PRE_ALLOC_1M                        #language en-US  "1M"
> +#string STR_DVMT40_PRE_ALLOC_8M                        #language en-US  "8M"
> +#string STR_DVMT40_PRE_ALLOC_HELP                      #language en-US  "Select
> DVMT 4.0 Pre-Allocated (UMA) Graphics Memory size used by the Internal
> Graphics Device."
> +#string STR_LOCK_ECO_PROMPT                            #language en-US  "ECO
> Lock"
> +#string STR_LOCK_ECO_HELP                              #language en-US
> "Enable/Disable ECO Lock"
> +#string STR_DOP_CG_PROMPT                              #language en-US  "DOP CG"
> +#string STR_DOP_CG__HELP                               #language en-US
> "Enable/Disable DOP Clock Gating"
> +
> +//
> +// DVMT5.0 Graphics Memory
> +//
> +#string STR_DVMT50_TITLE                        #language en-US "DVMT5.0 Graphic
> memory setting"
> +#string STR_DVMT50_PRE_ALLOC                    #language en-US "DVMT Pre-
> Allocated"
> +#string STR_DVMT50_PRE_ALLOC_0M                 #language en-US "0M"
> +#string STR_DVMT50_PRE_ALLOC_32M                #language en-US "32M"
> +#string STR_DVMT50_PRE_ALLOC_64M                #language en-US "64M"
> +#string STR_DVMT50_PRE_ALLOC_96M                #language en-US "96M"
> +#string STR_DVMT50_PRE_ALLOC_128M               #language en-US "128M"
> +#string STR_DVMT50_PRE_ALLOC_160M               #language en-US "160M"
> +#string STR_DVMT50_PRE_ALLOC_192M               #language en-US "192M"
> +#string STR_DVMT50_PRE_ALLOC_224M               #language en-US "224M"
> +#string STR_DVMT50_PRE_ALLOC_256M               #language en-US "256M"
> +#string STR_DVMT50_PRE_ALLOC_288M               #language en-US "288M"
> +#string STR_DVMT50_PRE_ALLOC_320M               #language en-US "320M"
> +#string STR_DVMT50_PRE_ALLOC_352M               #language en-US "352M"
> +#string STR_DVMT50_PRE_ALLOC_384M               #language en-US "384M"
> +#string STR_DVMT50_PRE_ALLOC_416M               #language en-US "416M"
> +#string STR_DVMT50_PRE_ALLOC_448M               #language en-US "448M"
> +#string STR_DVMT50_PRE_ALLOC_480M               #language en-US "480M"
> +#string STR_DVMT50_PRE_ALLOC_512M               #language en-US "512M"
> +
> +#string STR_DVMT50_PRE_ALLOC_HELP               #language en-US "Select
> DVMT 5.0 Pre-Allocated (Fixed) Graphics Memory size used by the Internal
> Graphics Device"
> +#string STR_DVMT50_DVMT                         #language en-US "DVMT Total Gfx
> Mem"
> +#string STR_DVMT50_DVMT_HELP                    #language en-US "Select
> DVMT5.0 Total Graphic Memory size used by the Internal Graphics Device"
> +#string STR_DVMT50_ALLOC_128                    #language en-US "128M"
> +#string STR_DVMT50_ALLOC_256                    #language en-US "256M"
> +#string STR_DVMT50_ALLOC_MAX                    #language en-US "MAX"
> +#string STR_GTT_SIZE                            #language en-US "GTT Size"
> +#string STR_GTT_SIZE_HELP                       #language en-US "Select the GTT
> Size "
> +#string GTT_SIZE_1MB                            #language en-US "1MB"
> +#string GTT_SIZE_2MB                            #language en-US "2MB"
> +#string STR_APERTURE_SIZE                       #language en-US "Aperture Size"
> +#string STR_APERTURE_SIZE_HELP                  #language en-US "Select the
> Aperture Size"
> +#string APERTURE_SIZE_128MB                     #language en-US "128MB"
> +#string APERTURE_SIZE_256MB                     #language en-US "256MB"
> +#string APERTURE_SIZE_512MB                     #language en-US "512MB"
> +
> +#string STR_IGD_PROMPT                          #language en-US  "Integrated
> Graphics Device"
> +#string STR_IGD_HELP                            #language en-US  "Enable : Enable
> Integrated Graphics Device (IGD) when selected as the Primary Video
> Adaptor. Disable: Alwarys disable IGD"
> +
> +#string STR_ACPI_ALS_ENABLE                            #language en-US  "ALS
> Support"
> +#string STR_ACPI_ALS_ENABLE_HELP                       #language en-US  "Valid
> only for ACPI."
> +
> +#string STR_SEC_CONFIGURATION_SUBTITLE                 #language en-US "TXE
> Configuration"
> +
> +#string STR_SEC_SETTING_PROMPT                         #language en-US "TXE"
> +#string STR_SEC_SETTING_HELP                           #language en-US ""
> +
> +#string STR_TPM_CONFIGURATION_PROMPT                   #language en-US
> "TPM Configuration"
> +
> +#string STR_FIRMWARE_TPM_PROMPT                        #language en-US
> "fTPM"
> +#string STR_FIRMWARE_TPM_HELP                          #language en-US
> "Enable/Disable fTPM"
> +
> +#string STR_PTT_PROMPT                                 #language en-US "PTT"
> +#string STR_PTT_HELP                                   #language en-US "Enable/Disable
> PTT"
> +
> +#string STR_TPM_PROMPT                                 #language en-US "Discrete
> TPM"
> +#string STR_TPM_HELP                                   #language en-US "Enable/Disable
> TPM"
> +
> +#string STR_MEASURED_BOOT_ENABLE_PROMPT                #language en-US
> "Measured Boot"
> +#string STR_MEASURED_BOOT_ENABLE_HELP                  #language en-US
> "Enable/Disable Measured Boot"
> +
> +#string STR_SEC_FLASH_UPDATE_PROMPT                    #language en-US "TXE
> HMRFPO "
> +#string STR_SEC_FLASH_UPDATE_HELP                      #language en-US ""
> +
> +#string STR_SEC_FIRMWARE_UPDATE_PROMPT                 #language en-US
> "TXE Firmware Update"
> +#string STR_SEC_FIRMWARE_UPDATE_HELP                   #language en-US ""
> +#string STR_SEC_UNCONFIGURATION_PROMPT                 #language en-US
> "TXE Unconfiguration Perform"
> +#string STR_SEC_UNCONFIGURATION_HELP                   #language en-US
> "Revert TXE settings to factory defaults"
> +#string STR_PTT_SUBTITLE                               #language en-US "Platform Trust
> Technology"
> +#string STR_PTT_DISABLE_PROMPT                         #language en-US "PTT
> Disable"
> +#string STR_PTT_DISABLE_HELP                           #language en-US "Disable PTT
> "
> +
> +#string STR_REVOKE_TRUST_PROMPT                        #language en-US
> "Revoke Trust"
> +#string STR_REVOKE_TRUST_HELP                          #language en-US
> "Enable/Disable Revoke Trust"
> +
> +#string STR_PASSWORD_CONFIGURATION_SUBTITLE            #language en-
> US "Password Setting"
> +#string STR_PASSWORD_CONFIGURATION_HELP                #language en-US
> "Password Setting"
> +
> +#string STR_TDT_TITLE                                  #language en-US "Intel(R) Anti-
> Theft Technology Configuration"
> +
> +#string STR_TDT_CONFIG_PROMPT                          #language en-US "Intel(R)
> ATAM"
> +#string STR_TDT_CONFIG_HELP                            #language en-US
> "Enable/Disable BIOS AT Code from Running."
> +
> +#string STR_PBA_CONFIG_PROMPT                          #language en-US "Intel(R)
> AT Platform PBA"
> +#string STR_PBA_CONFIG_HELP                            #language en-US
> "Enable/Disable BIOS AT Code from Running."
> +
> +#string STR_TDT_RECOVERY_PROMPT                        #language en-US "AT
> Recovery"
> +#string STR_TDT_RECOVERY_HELP                          #language en-US "Set the
> number of times AT Recovery attempts will be allowed"
> +
> +#string STR_TDT_SUSPEND_PROMPT                         #language en-US "Intel(R)
> AT Suspend Mode"
> +#string STR_TDT_SUSPEND_HELP                           #language en-US "Request
> that platform enter AT Suspend Mode - Only Available when AT Enrolled"
> +
> +#string STR_ADMIN_PASSWORD                             #language en-US "Setup
> Administrator Password"
> +#string STR_ADMIN_PASSWORD_HELP                        #language en-US "Set
> Setup Administrator Password"
> +#string STR_USER_PASSWORD                              #language en-US "User
> Password"
> +#string STR_USER_PASSWORD_HELP                         #language en-US "Set
> User Password"
> +#string STR_CHANGE_ADMIN_PASSWORD                      #language en-US
> "Change Supervisor Password"
> +#string STR_CHANGE_ADMIN_PASSWORD_HELP                 #language en-US
> "Change Setup Administrator Password"
> +#string STR_CHANGE_USER_PASSWORD                       #language en-US
> "Change User Password"
> +#string STR_CHANGE_USER_PASSWORD_HELP                  #language en-US
> "Change User Password"
> +#string STR_SB_TITLE                                   #language en-US "Secure Boot
> Configuration"
> +#string STR_CHECK_SHA256_HASH_MASTER_BOOT_CODES        #language
> en-US "Check SHA256 Hash of Master Boot Codes"
> +#string STR_CHECK_SHA256_HASH_MASTER_BOOT_CODES_HELP
> #language en-US "Enable/Disable the checking of SHA256 hash of Master
> Boot Codes"
> +//
> +//South Cluster Configuration
> +//
> +#string STR_HPET_PROMPT                                #language en-US "High Precision
> Timer"
> +#string STR_HPET_HELP                                  #language en-US "Enable or
> Disable the High Precision Event Timer."
> +#string STR_HPET_BOOTTIME_PROMPT                       #language en-US "Boot
> Time with HPET Timer"
> +#string STR_HPET_BOOTTIME_HELP                         #language en-US "Boot
> time calculation with High Precision Event Timer enabled."
> +
> +#string STR_HPET_SUBTITLE                              #language en-US "High Precision
> Event Timer Configuration"
> +
> +#string STR_USB_CONFIG_SUBTITLE                        #language en-US "USB
> Configuration"
> +#string STR_USB_DEBUG_PROMPT                           #language en-US "USB
> Debug"
> +#string STR_USB_DEBUG_HELP                             #language en-US "Enable or
> Disable USB debug feature"
> +#string STR_USB_XHCI_SUPPORT_PROMPT                    #language en-US
> "XHCI Controller"
> +#string STR_USB_XHCI_SUPPORT_HELP                      #language en-US
> "Enable/Disable XHCI Controller "
> +
> +#string STR_USB_HSIC_0_PROMPT                          #language en-US "  HSIC #0"
> +#string STR_USB_HSIC_0_HELP                            #language en-US
> "Enable/Disable HSIC #0. Enabling HSIC #0 will also enable USB4640 USB HUB
> with an useless card reader and impact responsiveness."
> +
> +#string STR_USB_XHCI_LPM_SUPPORT_PROMPT                #language en-US
> "USB2 Link Power Management"
> +#string STR_USB_XHCI_LPM_SUPPORT_HELP                  #language en-US
> "Enable/Disable USB2 Link Power Management "
> +
> +#string STR_USB_AUTO_MODE_PROMPT                       #language en-US "USB
> Controller Auto Mode"
> +#string STR_USB_AUTO_MODE_HELP                         #language en-US "If
> enabled, EHCI is enabled as default for A0. For A1 and later, XHCI is enabled
> as default."
> +
> +#string STR_PCH_USB30_MODE_PROMPT                      #language en-US
> "XHCI Mode"
> +#string STR_PCH_USB30_MODE_HELP                        #language en-US "Mode
> of operation of xHCI controller."
> +#string STR_PCH_USB30_STREAMS                          #language en-US "XHCI
> Streams"
> +#string STR_PCH_USB30_STREAMS_HELP                     #language en-US
> "Enable/Disable XHCI Streams"
> +//
> +// USB Devices
> +//
> +#string STR_USB_OPTIONS_FORM_TITLE                     #language en-US "USB
> Configuration"
> +#string STR_USB_OPTIONS_FORM_HELP                      #language en-US "USB
> Configuration Settings"
> +
> +#string STR_PCH_USB21_PROMPT                           #language en-US "EHCI
> Controller"
> +#string STR_PCH_USB2_HELP                              #language en-US "Control the
> USB EHCI (USB 2.0) functions."
> +#string STR_PCH_USB_PER_PORT_PROMPT                    #language en-US
> "USB Per-Port Control"
> +#string STR_PCH_USB_PER_PORT_HELP                      #language en-US
> "Control each of the USB ports (0~3) enable/disable"
> +#string STR_PCH_USB_PORT0_PROMPT                       #language en-US "USB
> Port #0"
> +#string STR_PCH_USB_PORT1_PROMPT                       #language en-US "USB
> Port #1"
> +#string STR_PCH_USB_PORT2_PROMPT                       #language en-US "USB
> Port #2"
> +#string STR_PCH_USB_PORT3_PROMPT                       #language en-US "USB
> Port #3"
> +#string STR_PCH_USB_PORT4_PROMPT                       #language en-US "USB
> Port #4"
> +#string STR_PCH_USB_PORT5_PROMPT                       #language en-US "USB
> Port #5"
> +#string STR_PCH_USB_PORT6_PROMPT                       #language en-US "USB
> Port #6"
> +#string STR_PCH_USB_PORT7_PROMPT                       #language en-US "USB
> Port #7"
> +#string STR_PCH_USB_PORT_DIS_HELP                      #language en-US
> "Enable/Disable USB port"
> +#string STR_PCH_USBRMH_PROMPT                          #language en-US "USB
> RMH Mode"
> +#string STR_PCH_USBRMH_HELP                            #language en-US
> "Enable/Disable PCH USB Rate Matching Hubs mode"
> +#string STR_PCH_USB_EHCIDEBUG_PROMPT                   #language en-US
> "USB EHCI debug"
> +#string STR_PCH_USB_EHCIDEBUG_HELP                     #language en-US
> "Enable/Disable PCH EHCI debug capability"
> +
> +#string STR_PCH_USB_OTG_PROMPT                         #language en-US "USB
> OTG Support"
> +#string STR_PCH_USB_OTG_HELP                           #language en-US
> "Enable/Disable USB OTG Support"
> +#string STR_PCH_USB_VBUS_PROMPT                        #language en-US "USB
> VBUS"
> +#string STR_PCH_USB_VBUS_HELP                          #language en-US "VBUS
> should be ON in HOST mode. It should be OFF in OTG device mode. VBUS is
> forced to Auto mode for FFRD-PR1 since FSA mux will control it."
> +#string STR_PCH_FSA_PROMPT                             #language en-US "FSA ON"
> +#string STR_PCH_FSA_HELP                               #language en-US "FSA should be
> ON for PR1"
> +
> +#string STR_PCI_MODE_STRING                            #language en-US "PCI Mode"
> +#string STR_ACPI_MODE_STRING                           #language en-US "ACPI
> Mode"
> +
> +#string STR_SMARTAUTO_STRING                           #language en-US "Smart
> Auto"
> +
> +#string STR_DEVICE_SUBTITLE                            #language en-US "Onboard
> Devices"
> +
> +#string STR_LAN_PROMPT                                 #language en-US "LAN"
> +#string STR_LAN_HELP                                   #language en-US "Enables or
> Disables the Onboard LAN Controller."
> +
> +//
> +// GbE
> +//
> +#string STR_LAN_OPTIONS_FORM_TITLE                     #language en-US  "LAN
> Configuration"
> +#string STR_LAN_OPTIONS_FORM_HELP                      #language en-US  "LAN
> Configuration Settings"
> +
> +#string STR_PCH_LAN_CONTROLLER                         #language en-US  "LAN
> Controller"
> +#string STR_PCH_LAN_CONTROLLER_HELP                    #language en-US
> "Enable/Disable onboard NIC"
> +#string STR_PCH_LAN_WOL_PROMPT                         #language en-US  "
> Wake on LAN Enable"
> +#string STR_PCH_LAN_WOL_HELP                           #language en-US
> "Enable/Disable integrated LAN to wake the system"
> +#string STR_PCH_SLP_LAN_LOW_DC_PROMPT                  #language en-US  "
> SLP_LAN# Low on DC Power"
> +#string STR_PCH_SLP_LAN_LOW_DC_HELP                    #language en-US
> "Enable/Disable SLP_LAN# Low on DC Power"
> +
> +#string STR_PCH_PXEROM_CONTROL                         #language en-US "PXE
> ROM"
> +#string STR_PCH_PXEROM_CONTROL_HELP                    #language en-US
> "Enable/Disable PXE Option ROM execution for onboard LAN"
> +
> +//
> +// Azalia
> +//
> +#string STR_AZALIA_OPTIONS_FORM_TITLE                  #language en-US
> "Audio Configuration"
> +#string STR_AZALIA_OPTIONS_FORM_HELP                   #language en-US
> "Audio Configuration Settings"
> +
> +#string STR_PCH_AZALIA_PROMPT                          #language en-US "Audio
> Controller"
> +#string STR_PCH_AZALIA_HELP                            #language en-US "Control
> Detection of the Azalia device.\n\nDisabled = Azalia will be unconditionally
> disabled\n\nEnabled = Azalia will be unconditionally Enabled\n\nAuto =
> Azalia will be enabled if present, disabled otherwise"
> +#string STR_PCH_AZALIA_DS_SUPPORT                      #language en-US
> "Always enable Azalia while Azalia Docking Support is enabled"
> +
> +#string STR_AZALIA_VC_PROMPT                           #language en-US "  Azalia
> VCi Enable"
> +#string STR_AZALIA_VC_HELP                             #language en-US
> "Enable/Disable Virtual Channel 1 of Audio Controller"
> +#string STR_AZALIA_DS_PROMPT                           #language en-US "  Azalia
> Docking Support Enable"
> +#string STR_AZALIA_DS_HELP                             #language en-US
> "Enable/Disable Azalia Docking Support of Audio Controller"
> +#string STR_AZALIA_PME_PROMPT                          #language en-US "  Azalia
> PME Enable"
> +#string STR_AZALIA_PME_HELP                            #language en-US
> "Enable/Disable Power Management capability of Audio Controller"
> +#string STR_HDMI_CODEC_PROMPT                          #language en-US "  Azalia
> HDMI Codec"
> +#string STR_HDMI_CODEC_HELP                            #language en-US
> "Enable/Disable internal HDMI codec for Azalia"
> +
> +#string STR_HDMI_CODEC_PORTB_PROMPT                    #language en-US "
> Azalia HDMI codec Port B"
> +#string STR_HDMI_CODEC_PORTC_PROMPT                    #language en-US "
> Azalia HDMI codec Port C"
> +#string STR_HDMI_CODEC_PORTD_PROMPT                    #language en-US "
> Azalia HDMI codec Port D"
> +#string STR_HDMI_CODEC_PORT_HELP                       #language en-US
> "Enable/Disable internal HDMI codec Port for Azalia"
> +//
> +// Misc.
> +//
> +#string STR_MISC_OPTION_FORM_TITLE                     #language en-US
> "Miscellaneous Configuration"
> +#string STR_MISC_OPTION_FORM_HELP                      #language en-US
> "Enable/Disable Misc. Features"
> +
> +#string STR_HPET_PROMPT                                #language en-US "High Precision
> Timer"
> +#string STR_HPET_HELP                                  #language en-US "Enable or
> Disable the High Precision Event Timer"
> +#string STR_HPET_BOOTTIME_PROMPT                       #language en-US "Boot
> Time with HPET Timer"
> +#string STR_HPET_BOOTTIME_HELP                         #language en-US "Boot
> time calculation with High Precision Event Timer enabled"
> +
> +
> +#string STR_CLOCK_SPREAD_SPEC_ENABLE                   #language en-US
> "Clock Spread Spectrum"
> +#string STR_CLOCK_SPREAD_SPEC_ENABLE_HELP              #language en-US
> "Enable Clock Chip's Spread Spectrum feature"
> +
> +
> +#string STR_STATE_AFTER_G3                             #language en-US "State After
> G3"
> +#string STR_STATE_AFTER_G3_HELP                        #language en-US "Specify
> what state to go to when power is re-applied after a power failure (G3
> state)"
> +#string STR_S0_AFTER_G3_STRING                         #language en-US "S0 State"
> +#string STR_S5_AFTER_G3_STRING                         #language en-US "S5 State"
> +
> +#string STR_PCH_UART_SELECT                            #language en-US "UART
> Interface Selection"
> +#string STR_PCH_UART_SELECT_HELP                       #language en-US "Select
> which UART interface to use"
> +#string STR_UART_SELECT_PCU                            #language en-US "Internal
> UART"
> +#string STR_UART_SELECT_SIO                            #language en-US "SuperIO
> UART"
> +
> +#string STR_PCU_UART_A                                 #language en-US "PCU UART
> COM 1"
> +#string STR_PCU_UART_A_HELP                            #language en-US
> "Enable/Disable Onboard PCU UART COM 1"
> +#string STR_PCU_UART_B                                 #language en-US "PCU UART
> COM 2"
> +#string STR_PCU_UART_B_HELP                            #language en-US
> "Enable/Disable Onboard PCU UART COM 2"
> +
> +#string STR_AUDIO_PROMPT                               #language en-US  "Audio"
> +#string STR_AUDIO_HELP                                 #language en-US  "Enables or
> Disables Onboard Audio."
> +
> +#string STR_LPE_PROMPT                                 #language en-US  "LPE"
> +#string STR_LPE_HELP                                   #language en-US  "Enables or
> Disables Onboard LPE Sub-System."
> +
> +#string STR_GPIO_WAKE_CAPABILITY_ENABLE                #language en-US
> "GPIO Wake Capability"
> +#string STR_GPIO_WAKE_CAPABILITY_ENABLE_HELP           #language en-US
> "Enable or Disable GPIO Wake Capability"
> +
> +#string STR_RTC_BATTERY                                #language en-US "RTC Battery
> Presence"
> +#string STR_RTC_BATTERY_PRESENT                        #language en-US "Present"
> +#string STR_RTC_BATTERY_NOT_PRESENT                    #language en-US "Not
> Present"
> +#string STR_RTC_BATTERY_HELP                           #language en-US "RTC Battery
> is Present or Not Present"
> +
> +#string STR_LPE_REPORTED_BY_DSDT_PROMPT                #language en-US
> "LPE Audio Reported By DSDT"
> +#string STR_LPE_REPORTED_BY_DSDT_HELP                  #language en-US
> "Recommended solution is to keep option disabled and expose LPE Audio
> device with an EFI application that updates the SSDT"
> +
> +//
> +// PCI Express
> +//
> +#string STR_PCIE_OPTIONS_FORM_TITLE                    #language en-US  "PCI
> Express Configuration"
> +#string STR_PCIE_OPTIONS_FORM_HELP                     #language en-US  "PCI
> Express Configuration Settings"
> +#string STR_ICH_PCIERP1_PROMPT                         #language en-US  "PCI
> Express Root Port 1"
> +#string STR_ICH_PCIERP2_PROMPT                         #language en-US  "PCI
> Express Root Port 2"
> +#string STR_ICH_PCIERP3_PROMPT                         #language en-US  "PCI
> Express Root Port 3"
> +#string STR_ICH_PCIERP4_PROMPT                         #language en-US  "PCI
> Express Root Port 4"
> +#string STR_ICH_PCIERP_HELP                            #language en-US  "Control the
> PCI Express Root Port."
> +#string STR_ICH_PCIERP_DISABLE_HELP                    #language en-US  "This
> Root Port is disabled because Root Port 1 is disabled."
> +#string STR_PCIEDYNCLK_PROMPT                          #language en-US  "PCI
> Express Dynamic Clock Gating"
> +#string STR_PCIEDYNCLK_HELP                            #language en-US
> "Enable/Disable PCIE Dynamic Clock Gating"
> +
> +#string STR_IDE_FORM_TITLE                             #language en-US "SATA Drives"
> +#string STR_IDE_FORM_HELP                              #language en-US "Press <Enter>
> to select the SATA Device Configuration Setup options."
> +
> +#string STR_DISCRETE_SATA_STRING                       #language en-US
> "Discrete-SATA Controller Configuration"
> +#string STR_CHIPSET_SATA_STRING                        #language en-US "Chipset-
> SATA Controller Configuration"
> +
> +#string STR_SATA_PROMPT                                #language en-US  " Chipset
> SATA"
> +#string STR_SATA_HELP                                  #language en-US  "Enables or
> Disables the Chipset SATA Controller.  The Chipset SATA controller supports
> the 2 black internal SATA ports (up to 3Gb/s supported per port)."
> +
> +#string STR_SATA_TYPE_PROMPT                           #language en-US  " Chipset
> SATA Mode"
> +#string STR_SATA_TYPE_PROMPT                           #language fr-FR  "
> Configurer SATA comme"
> +
> +#string STR_SATA_TYPE_HELP                             #language en-US  "This will
> configure SATA into the corresponding types."
> +#string STR_SATA_TYPE_HELP                             #language fr-FR  "Configure
> SATA selon les types correspondants."
> +#string STR_SATA_TYPE_HELP1                            #language en-US  "IDE:
> Compatibility mode disables AHCI support. AHCI: Supports advanced SATA
> features such as Native Command Queuing.     \nWarning: OS may not boot if
> this setting is changed after OS install."
> +
> +#string STR_SATA_IDE                                   #language en-US  "IDE"
> +#string STR_SATA_AHCI                                  #language en-US  "AHCI"
> +
> +#string STR_SATA0_STRING                               #language en-US "  SATA Port 0"
> +#string STR_SATA0_STRING                               #language fr-FR "  Port SATA 0"
> +
> +#string STR_SATA0_NAME                                 #language en-US  "[Not
> Installed]"
> +#string STR_SATA0_NAME                                 #language fr-FR  "[Absent]"
> +
> +#string STR_MSATA_STRING                               #language en-US "  mSATA
> Port"
> +
> +#string STR_SATA1_STRING                               #language en-US "  SATA Port 1"
> +#string STR_SATA1_STRING                               #language fr-FR "  Port SATA 1"
> +
> +#string STR_SATA1_NAME                                 #language en-US  "[Not
> Installed]"
> +#string STR_SATA1_NAME                                 #language fr-FR  "[Absent]"
> +
> +#string STR_SATA0_HOTPLUG_CAP_PROMPT                   #language en-US "
> SATA Port 0 Hot Plug Capability"
> +#string STR_SATA1_HOTPLUG_CAP_PROMPT                   #language en-US "
> SATA Port 1 Hot Plug Capability"
> +#string STR_SATA_HOTPLUG_CAP_HELP                      #language en-US "If
> enabled, SATA port will be reported as Hot Plug capable."
> +
> +#string STR_SENSOR_FORM_TITLE                          #language en-US "Sensor
> setting"
> +#string STR_SENSOR_FORM_HELP                           #language en-US "Press
> <Enter> to select the Sensor Configuration Setup options."
> +
> +//
> +//Sensor Settings
> +//
> +#string STR_SENSOR_SUBTITLE                            #language en-US  "Sensor
> Modules Setting"
> +#string STR_ACCELEROMETER_PROMPT                       #language en-US
> "Accelerometer"
> +#string STR_ACCELEROMETER_HELP                         #language en-US  "This will
> configure disable/enable Accelerometer."
> +#string STR_GYROMETER_PROMPT                           #language en-US
> "Gyrometer"
> +#string STR_GYROMETER_HELP                             #language en-US  "This will
> configure disable/enable Gyrometer."
> +#string STR_BAROMETER_PROMPT                           #language en-US
> "Barometer"
> +#string STR_BAROMETER_HELP                             #language en-US  "This will
> configure disable/enable Barometer."
> +#string STR_PROXIMITY_SENSOR_PROMPT                    #language en-US
> "Proximity Sensor"
> +#string STR_PROXIMITY_SENSOR_HELP                      #language en-US  "This
> will configure disable/enable Proximity Sensor."
> +#string STR_COMPASS_PROMPT                             #language en-US
> "Compass"
> +#string STR_COMPASS_HELP                               #language en-US  "This will
> configure disable/enable Compass."
> +#string STR_NFS_PROMPT                                 #language en-US  "NFS"
> +#string STR_NFS_HELP                                   #language en-US  "This will
> configure disable/enable NFS."
> +
> +#string STR_LPSS_SCC_FORM_TITLE                        #language en-US  "LPSS &
> SCC Configuration"
> +#string STR_LPSS_SCC_FORM_HELP                         #language en-US  ""
> +
> +#string STR_LPSS_PCI_PROMPT                            #language en-US  "LPSS & SCC
> Devices Mode"
> +#string STR_LPSS_PCI_HELP                              #language en-US
> "Enable/Disable LPSS & SCC Devices Mode"
> +
> +#string STR_SCC_SETTING_SUBTITLE                       #language en-US  "SCC
> Configuration"
> +#string STR_SCC_EMMC_PROMPT                            #language en-US  "SCC
> eMMC Support"
> +#string STR_SCC_EMMC_HELP                              #language en-US
> "Enable/Disable SCC eMMC Support"
> +#string STR_SCC_SDIO_PROMPT                            #language en-US  "SCC SDIO
> Support "
> +#string STR_SCC_SDIO_HELP                              #language en-US
> "Enable/Disable SCC SDIO Support"
> +#string STR_SCC_SDCARD_PROMPT                          #language en-US  "SCC SD
> Card Support"
> +#string STR_SCC_SDCARD_HELP                            #language en-US
> "Enable/Disable SCC SD Card Support"
> +#string STR_SCC_SDCARD_FORWIN_PROMPT                   #language en-US
> "SCC SD Card for Windows"
> +#string STR_SCC_SDCARD_FORWIN_HELP                     #language en-US
> "Enable/Disable SCC SD Card for Windows"
> +#string STR_SCC_SDIO_MODE_PROMPT                       #language en-US  "SCC
> SDIO Mode for WIFI"
> +#string STR_SCC_SDIO_MODE_HELP                         #language en-US  "Select
> SDIO mode for WIFI, only for A0/A1 stepping."
> +#string STR_SCC_SDCARD_REMOVABILITY                    #language en-US  "ACPI
> Reporting MMC/SD Media As"
> +#string STR_SCC_SDCARD_REMOVABLE                       #language en-US
> "Removable"
> +#string STR_SCC_SDCARD_NON_REMOVABLE                   #language en-US
> "Non-Removable"
> +#string STR_SCC_SDCARD_REMOVABILITY_HELP               #language en-US
> "ACPI Reporting MMC/SD Media to Win 8 as non-Removable."
> +
> +#string STR_SDIO_DEFAULT_MODE                          #language en-US  "Default"
> +#string STR_SDIO_DDR50_MODE                            #language en-US  "DDR50"
> +
> +#string STR_LPSS1_SETTING_SUBTITLE                     #language en-US  "LPSS 1
> Configuration"
> +#string STR_LPSS2_SETTING_SUBTITLE                     #language en-US  "LPSS 2
> Configuration"
> +#string STR_LPSS_DMA1_PROMPT                           #language en-US  "LPSS
> DMA #1 Support"
> +#string STR_LPSS_DMA1_HELP                             #language en-US
> "Enable/Disable LPSS DMA #1 Support"
> +#string STR_LPSS_DMA2_PROMPT                           #language en-US  "LPSS
> DMA #2 Support"
> +#string STR_LPSS_DMA2_HELP                             #language en-US
> "Enable/Disable LPSS DMA #2 Support"
> +#string STR_LPSS_I2C1_PROMPT                           #language en-US  "LPSS I2C
> #1 Support"
> +#string STR_LPSS_I2C1_HELP                             #language en-US
> "Enable/Disable LPSS I2C #1 Support"
> +#string STR_LPSS_I2C2_PROMPT                           #language en-US  "LPSS I2C
> #2 Support"
> +#string STR_LPSS_I2C2_HELP                             #language en-US
> "Enable/Disable LPSS I2C #2 Support"
> +#string STR_LPSS_I2C3_PROMPT                           #language en-US  "LPSS I2C
> #3 Support"
> +#string STR_LPSS_I2C3_HELP                             #language en-US
> "Enable/Disable LPSS I2C #3 Support"
> +#string STR_LPSS_I2C4_PROMPT                           #language en-US  "LPSS I2C
> #4 Support"
> +#string STR_LPSS_I2C4_HELP                             #language en-US
> "Enable/Disable LPSS I2C #4 Support"
> +#string STR_LPSS_I2C5_PROMPT                           #language en-US  "LPSS I2C
> #5 Support"
> +#string STR_LPSS_I2C5_HELP                             #language en-US
> "Enable/Disable LPSS I2C #5 Support"
> +#string STR_LPSS_I2C6_PROMPT                           #language en-US  "Low
> Speed Expansion I2C (#5)"
> +#string STR_LPSS_I2C6_HELP                             #language en-US
> "Enable/Disable Low Speed Expansion I2C (#5);I2C Controller PCI device
> Dev24: Func6; Schematic names it I2C5, ACPI table names it I2C6"
> +#string STR_LPSS_I2C7_PROMPT                           #language en-US  "High
> Speed Expansion I2C (#6)"
> +#string STR_LPSS_I2C7_HELP                             #language en-US
> "Enable/Disable High Speed Expansion I2C (#6);I2C Controller PCI device
> Dev24: Func7; Schematic names it I2C6, ACPI table names it I2C7"
> +#string STR_LPSS_I2S_PROMPT                            #language en-US  "LPSS I2S
> Support"
> +#string STR_LPSS_I2S_HELP                              #language en-US
> "Enable/Disable LPSS I2S Support"
> +#string STR_LPSS_HSUART1_PROMPT                        #language en-US  "LPSS
> HSUART #1 Support"
> +#string STR_LPSS_HSUART1_FLOWCONTROL_PROMPT            #language en-
> US  "LPSS HSUART #1 FlowCtrl"
> +#string STR_LPSS_HSUART2_FLOWCONTROL_PROMPT            #language en-
> US  "LPSS HSUART #2 FlowCtrl"
> +#string STR_LPSS_HSUART1_HELP                          #language en-US
> "Enable/Disable LPSS HSUART #1 Support"
> +#string STR_LPSS_HSUART2_PROMPT                        #language en-US  "LPSS
> HSUART #2 Support"
> +#string STR_LPSS_HSUART2_HELP                          #language en-US
> "Enable/Disable LPSS HSUART #2 Support"
> +#string STR_LPSS_SPI_PROMPT                            #language en-US  "LPSS SPI
> Support"
> +#string STR_LPSS_SPI_HELP                              #language en-US
> "Enable/Disable LPSS SPI Support"
> +
> +#string STR_LPSS_I2C1_HELP_ENBDT_DEV_LIST              #language en-US
> "Disable/Enable LPSS I2C #1 Support\n\n  "
> +#string STR_LPSS_I2C2_HELP_ENBDT_DEV_LIST              #language en-US
> "Disable/Enable LPSS I2C #2 Support\n\n  "
> +#string STR_LPSS_I2C3_HELP_ENBDT_DEV_LIST              #language en-US
> "Disable/Enable LPSS I2C #3 Support\n\n  "
> +#string STR_LPSS_I2C4_HELP_ENBDT_DEV_LIST              #language en-US
> "Disable/Enable LPSS I2C #4 Support\n\n  "
> +#string STR_LPSS_I2C5_HELP_ENBDT_DEV_LIST              #language en-US
> "Disable/Enable LPSS I2C #5 Support\n\n  "
> +#string STR_LPSS_I2C6_HELP_ENBDT_DEV_LIST              #language en-US
> "Enable/Disable Low Speed Expansion I2C (#5);I2C Controller PCI device
> Dev24: Func6; Schematic names it I2C5, ACPI table names it I2C6\n\n  "
> +#string STR_LPSS_I2C7_HELP_ENBDT_DEV_LIST              #language en-US
> "Enable/Disable High Speed Expansion I2C (#6);I2C Controller PCI device
> Dev24: Func7; Schematic names it I2C6, ACPI table names it I2C7\n\n  "
> +#string STR_LPSS_HSUART1_HELP_ENBDT_DEV_LIST           #language en-US
> "Disable/Enable LPSS High Speed UART
> #1\n\nEnabled(RX/TX/RTS/CTS)\nW\O
> FlowCtrl(RX/TX+GPIOx2)\nDisabled(GPIOx4)"
> +#string STR_LPSS_HSUART2_HELP_ENBDT_DEV_LIST           #language en-US
> "Disable/Enable LPSS High Speed UART
> #2\n\nEnabled(RX/TX/RTS/CTS)\nW\O
> FlowCtrl(RX/TX+GPIOx2)\nDisabled(GPIOx4)"
> +
> +#string STR_I2C_DEVICE_SETTING_SUBTITLE                #language en-US  "I2C
> Devics Configuration"
> +#string STR_I2C_TOUCH_PROMPT                           #language en-US  "I2C
> Touch Devic Address"
> +#string STR_I2C_TOUCH_HELP                             #language en-US  "I2C Touch
> Address Select:\n  RVP/iCDK(0x4B)\n  FFRD(0x4A)"
> +#string STR_I2C_FFRD                                   #language en-US  "0x4A"
> +#string STR_I2C_FVP                                    #language en-US  "0x4B"
> +
> +
> +#string STR_PWM1_PROMPT                                #language en-US  "LPSS PWM
> #1 Support"
> +#string STR_PWM1_HELP                                  #language en-US
> "Enable/DisableLPSS PWM #1 Support"
> +#string STR_PWM2_PROMPT                                #language en-US  "LPSS PWM
> #2 Support"
> +#string STR_PWM2_HELP                                  #language en-US
> Enable/Disable"LPSS PWM #2 Support"
> +#string STR_MIPI_HSI_PROMPT                            #language en-US  "MIPI HSI
> Support"
> +#string STR_MIPI_HSI_HELP                              #language en-US
> "Enable/Disable MIPI HSI Support \n Note: Official BIOS cannot support MIPI
> display directly even you select enable here. MIPI VBT is specific to different
> panel, user need replace VBT manually."
> +#string STR_LPE_PROMPT                                 #language en-US  "LPE Audio
> Support"
> +#string STR_LPE_HELP                                   #language en-US  "Enable/Disable
> LPE Audio Support"
> +#string STR_LPE_PCI_MODE                               #language en-US  "LPE Audio
> PCI mode"
> +#string STR_LPE_ACPI_MODE                              #language en-US  "LPE Audio
> ACPI mode"
> +
> +//
> +// ISCT Configuration
> +//
> +#string STR_ISCT_FORM_TITLE                            #language en-US  "ISCT
> Configuration"
> +#string STR_ISCT_FORM_HELP                             #language en-US  "ISCT / AOAC
> Configuration Settings"
> +
> +#string STR_ISCT_CONFIGURATION                         #language en-US  "ISCT
> Configuration"
> +#string STR_ISCT_CONFIGURATION_HELP                    #language en-US
> "Enable/Disable ISCT Feature"
> +
> +#string STR_ISCT_NOTIFICATION_CONTROL_PROMPT           #language en-
> US  "ISCT Notification Control"
> +#string STR_ISCT_NOTIFICATION_CONTROL_HELP             #language en-US
> "Enable/Disable ISCT Notification Control"
> +#string STR_ISCT_WLAN_CONTROL_PROMPT                   #language en-US
> "ISCT WLAN Power Control"
> +#string STR_ISCT_WLAN_CONTROL_HELP                     #language en-US
> "Enable/Disable ISCT WLAN Power Control"
> +#string STR_ISCT_WWAN_CONTROL_PROMPT                   #language en-US
> "ISCT WWAN Power Control"
> +#string STR_ISCT_WWAN_CONTROL_HELP                     #language en-US
> "Enable/Disable ISCT WWAN Power Control"
> +
> +#string STR_ISCT_SLEEP_DURATION_FORMAT                 #language en-US
> "ISCT Sleep Duration Value Format"
> +#string STR_ISCT_SLEEP_DURATION_FORMAT_HELP            #language en-US
> "ISCT Sleep Duration is only in Seconds Format, Actual time format is not
> supported"
> +
> +#string STR_ISCT_RF_KILL_SUPPORT                       #language en-US  "ISCT RF
> Kill Support"
> +#string STR_ISCT_RF_KILL_SUPPORT_HELP                  #language en-US  "ISCT
> RF Kill (Radio On/Off) is based on Soft switch, No physical switch available"
> +
> +#string STR_SECONDS                                    #language en-US  "Seconds"
> +#string STR_ACTUAL_TIME                                #language en-US  "Actual Time"
> +
> +#string STR_RF_KILL_SOFT                               #language en-US  "Soft Switch"
> +#string STR_RF_KILL_PHYSICAL                           #language en-US  "Physical
> Switch"
> +
> +#string STR_WLAN_PRESENCE_FORM_TITLE                   #language en-US
> "WLAN Card Presence"
> +#string STR_WLAN_NGFF_CARD                         #language en-US  "NGFF Card
> Inserted"
> +#string STR_WLAN_NGFF_HELP                         #language en-US  "Set 'YES' If
> NGFF Card is Inserted"
> +#string STR_WLAN_UHPAM_CARD                            #language en-US  "UHPAM
> Card Inserted"
> +#string STR_WLAN_UHPAM_HELP                            #language en-US  "Set 'YES'
> If UHPAM Card is Inserted"
> +
> +//
> +// THERMAL INFORMATION
> +//
> +
> +//
> +// S0iX supported or not
> +//
> +#string STR_S0IX_PROMPT                                #language en-US  "S0ix"
> +#string STR_S0IX_HELP                                  #language en-US  "Set platform to
> configure S0ix supported or not"
> +
> +#string STR_THERMAL_CONFIGURATION                      #language en-US
> "Processor Participant"
> +#string STR_THERMAL_CONFIGURATION_HELP                 #language en-US
> "Thermal Configuration Parameters"
> +
> +
> +#string STR_ACPI_PASSIVE_THERMAL_TRIP_POINT            #language en-US
> "Passive Trip Point"
> +#string STR_ACPI_PASSIVE_THERMAL_TRIP_POINT_HELP       #language en-
> US "This value controls the temperature of the ACPI Passive Trip Point - the
> point in which the OS will begin throttling the processor."
> +#string STR_ACPI_CRITICAL_THERMAL_TRIP_POINT           #language en-US
> "Critical Trip Point"
> +#string STR_ACPI_CRITICAL_THERMAL_TRIP_POINT_HELP      #language en-
> US "This value controls the temperature of the ACPI Critical Trip Point - the
> point in which the OS will shut the system off."
> +#string STR_15_C                                       #language en-US "15 C"
> +#string STR_23_C                                       #language en-US "23 C"
> +#string STR_31_C                                       #language en-US "31 C"
> +#string STR_39_C                                       #language en-US "39 C"
> +#string STR_47_C                                       #language en-US "47 C"
> +#string STR_55_C                                       #language en-US "55 C"
> +#string STR_63_C                                       #language en-US "63 C"
> +#string STR_71_C                                       #language en-US "71 C"
> +#string STR_79_C                                       #language en-US "79 C"
> +#string STR_85_C                                       #language en-US "85 C"
> +#string STR_87_C                                       #language en-US "87 C"
> +#string STR_90_C                                       #language en-US "90 C"
> +#string STR_95_C                                       #language en-US "95 C"
> +#string STR_100_C                                      #language en-US "100 C"
> +#string STR_103_C                                      #language en-US "103 C"
> +#string STR_105_C                                      #language en-US "105 C"
> +#string STR_110_C                                      #language en-US "110 C"
> +#string STR_111_C                                      #language en-US "111 C"
> +#string STR_119_C                                      #language en-US "119 C"
> +#string STR_180_C                                      #language en-US "180 C"
> +#string STR_200_C                                      #language en-US "200 C"
> +#string STR_POR                                        #language en-US "POR"
> +#string STR_0LEN                                       #language en-US ""
> +
> +#string STR_ACPI_PASSIVE_TC1_VALUE                     #language en-US "
> Passive TC1 Value"
> +#string STR_ACPI_PASSIVE_TC1_VALUE_HELP                #language en-US
> "This value sets the TC1 value for the ACPI Passive Cooling Formula. Range 1 -
> 16"
> +#string STR_ACPI_PASSIVE_TC2_VALUE                     #language en-US "
> Passive TC2 Value"
> +#string STR_ACPI_PASSIVE_TC2_VALUE_HELP                #language en-US
> "This value value sets the TC2 value for the ACPI Passive Cooling Formula.
> Range 1 - 16"
> +#string STR_ACPI_PASSIVE_TSP_VALUE                     #language en-US "
> Passive TSP Value"
> +#string STR_ACPI_PASSIVE_TSP_VALUE_HELP                #language en-US
> "This item sets the TSP value for the ACPI Passive Cooling Formula.  It
> represents in tenths of a second how often the OS will read the temperature
> when passive cooling is enabled. Range 2 - 32"
> +
> +#string STR_DPTF_CONFIGURATION                         #language en-US "DPTF
> Configuration"
> +
> +#string STR_DATP_PROMPT                                #language en-US "Active Trip
> Points"
> +#string STR_DATP_HELP                                  #language en-US "Disable Active
> Trip Points"
> +
> +
> +//
> +// DPTF Form
> +//
> +#string STR_DPTF_PROMPT                                #language en-US  "DPTF"
> +#string STR_DPTF_HELP                                  #language en-US  "Enable/Disable
> DPTF"
> +#string STR_ACTIVE_PROMPT                              #language en-US  "Active"
> +#string STR_ACTIVE_HELP                                #language en-US  ""
> +#string STR_CTDP_PROMPT                                #language en-US  "CTDP"
> +#string STR_CTDP_HELP                                  #language en-US  ""
> +#string STR_COOLING_MODE_PROMPT                        #language en-US
> "Cooling Mode"
> +#string STR_COOLING_MODE_HELP                          #language en-US  ""
> +#string STR_CRITICAL_PROMPT                            #language en-US  "Critical"
> +#string STR_CRITICAL_HELP                              #language en-US  ""
> +
> +#string STR_DPTF_CLPM_PROMPT                           #language en-US  "CLPM"
> +
> +#string STR_DPTF_CLPM_HELP                             #language en-US  "Current
> Low Power Mode"
> +
> +#string STR_DPTF_LPM_APP                               #language en-US  "Application
> specific"
> +
> +#string STR_DPTF_LPM_OS                                #language en-US  "OS level"
> +
> +#string STR_DPTF_SYSTHERM0_PROMPT                      #language en-US  "T1
> Sensor"            // Skin Temperature Sensor 0
> +#string STR_DPTF_SYSTHERM0_HELP                        #language en-US
> "Enable/Disable T1 skin sensor"
> +#string STR_DPTF_THERM0_PCAT_PROMPT                    #language en-US
> "CPU Sensors"
> +#string STR_DPTF_THERM0_PCAT_HELP                      #language en-US
> "Enable/Disable CPU Temperature Sensors"
> +
> +#string STR_DPTF_SYSTHERM1_PROMPT                      #language en-US
> "Display Board Sensor" //System Thermal Sensor 1
> +#string STR_DPTF_SYSTHERM1_HELP                        #language en-US
> "Enable/Disable Display Board skin Sensor"
> +#string STR_DPTF_THERM1_PCAT_PROMPT                    #language en-US
> "Ambient Sensors"
> +#string STR_DPTF_THERM1_PCAT_HELP                      #language en-US
> "Enable/Disable Ambient Temperature Sensors"
> +
> +#string STR_DPTF_SYSTHERM2_PROMPT                      #language en-US  "SOC
> Board Sensor"     //System Thermal Sensor 2
> +#string STR_DPTF_SYSTHERM2_HELP                        #language en-US
> "Enable/Disable SOC Board skin Sensor"
> +#string STR_DPTF_THERM2_PCAT_PROMPT                    #language en-US
> "DDR Sensors"
> +#string STR_DPTF_THERM2_PCAT_HELP                      #language en-US
> "Enable/Disable DDR Temperature Sensors"
> +
> +#string STR_DPTF_SYSTHERM3_PROMPT                      #language en-US
> "Charger Board Sensor" //System Thermal Sensor 3
> +#string STR_DPTF_SYSTHERM3_HELP                        #language en-US
> "Enable/Disable ULPMC Skin Temperature Sensor"
> +#string STR_DPTF_SYSTHERM4_PROMPT                      #language en-US
> "Ambient Temperature"
> +#string STR_DPTF_SYSTHERM4_HELP                        #language en-US
> "Enable/Disable Ambient Temperature"
> +#string STR_DPTF_AMBIENTTRIPPOINTCHANGE_PROMPT         #language
> en-US  "Ambient based Trip Point Change"
> +#string STR_DPTF_AMBIENTTRIPPOINTCHANGE_HELP           #language en-
> US  "This controls the Action part of the Ambient participant. When disabled,
> trip points would not be changed when Ambient participant notifies the FW
> of a new ambient temperature via _ATI."
> +#string STR_DPTF_ALLOWHIGHERPERFORMANCE_PROMPT         #language
> en-US  "Allow higher performance on AC/USB"
> +#string STR_DPTF_ALLOWHIGHERPERFORMANCE_HELP           #language en-
> US  "On AC/USB power source allow for higher performance and relax tablet
> skin temperature to higher limits. Warning: Note users may feel warm tablet
> skin."
> +#string STR_DPTF_CHARGER_PROMPT                        #language en-US
> "Charger Participant"
> +#string STR_DPTF_CHARGER_HELP                          #language en-US
> "Enable/Disable Charger Participant Device"
> +#string STR_DPTF_DISPLAY_PROMPT                        #language en-US  "Display
> Participant"
> +#string STR_DPTF_DISPLAY_HELP                          #language en-US
> "Enable/Disable Display Participant Device"
> +#string STR_DPTF_SOC_PROMPT                            #language en-US  "Power
> Participant"
> +#string STR_DPTF_SOC_HELP                              #language en-US
> "Enable/Disable Power Participant Device"
> +#string STR_PROCESSOR_DPTF_PROMPT                      #language en-US  "DPTF
> Processor"
> +#string STR_PROCESSOR_DPTF_HELP                        #language en-US
> "Enable/Disable Processor Participant Device"
> +
> +#string STR_PASSIVE_PROMPT                             #language en-US  "Passive"
> +#string STR_PASSIVE_HELP                               #language en-US  ""
> +
> +#string STR_DPTF_GENERIC_PARTICIPANT                   #language en-US  "DPTF
> Generic Sensor Participant"
> +#string STR_DPTF_CRITICAL_TEMP                         #language en-US  "Critical"
> +#string STR_DPTF_PASSIVE_TEMP                          #language en-US  "Passive"
> +#string STR_DPTF_CRITICAL_TEMP_HELP                    #language en-US
> "Critical Temperature"
> +#string STR_DPTF_PASSIVE_TEMP_HELP                     #language en-US
> "Passive Temperature"
> +#string STR_DPTF_25_C                                  #language en-US  "25 C"
> +#string STR_DPTF_30_C                                  #language en-US  "30 C"
> +#string STR_DPTF_35_C                                  #language en-US  "35 C"
> +#string STR_DPTF_40_C                                  #language en-US  "40 C"
> +#string STR_DPTF_45_C                                  #language en-US  "45 C"
> +#string STR_DPTF_50_C                                  #language en-US  "50 C"
> +#string STR_DPTF_55_C                                  #language en-US  "55 C"
> +#string STR_DPTF_60_C                                  #language en-US  "60 C"
> +#string STR_DPTF_65_C                                  #language en-US  "65 C"
> +#string STR_DPTF_70_C                                  #language en-US  "70 C"
> +#string STR_DPTF_75_C                                  #language en-US  "75 C"
> +#string STR_DPTF_80_C                                  #language en-US  "80 C"
> +#string STR_DPTF_85_C                                  #language en-US  "85 C"
> +#string STR_DPTF_90_C                                  #language en-US  "90 C"
> +#string STR_DPTF_95_C                                  #language en-US  "95 C"
> +#string STR_DPTF_100_C                                 #language en-US  "100 C"
> +#string STR_DPTF_105_C                                 #language en-US  "105 C"
> +#string STR_DPTF_110_C                                 #language en-US  "110 C"
> +#string STR_DPTF_115_C                                 #language en-US  "115 C"
> +#string STR_DPTF_120_C                                 #language en-US  "120 C"
> +#string STR_DPTF_125_C                                 #language en-US  "125 C"
> +#string STR_DPTF_52_C                                  #language en-US  "52 C"
> +#string STR_DPTF_61_C                                  #language en-US  "61 C"
> +#string STR_DPTF_64_C                                  #language en-US  "64 C"
> +#string STR_DPTF_43_C                                  #language en-US  "43 C"
> +#string STR_DPTF_57_C                                  #language en-US  "57 C"
> +#string STR_DPTF_62_C                                  #language en-US  "62 C"
> +#string STR_DPTF_78_C                                  #language en-US  "78 C"
> +#string STR_DPTF_81_C                                  #language en-US  "81 C"
> +
> +#string STR_DPTF_GENERIC0_PART_PCAT                    #language en-US  "CPU
> Sensor Participants"
> +#string STR_DPTF_GENERIC1_PART_PCAT                    #language en-US
> "Ambient Sensor Participants"
> +#string STR_DPTF_GENERIC2_PART_PCAT                    #language en-US  "DDR
> Sensor Participants"
> +#string STR_DPTF_GENERIC0_PARTICIPANT                  #language en-US
> "DPTF T1 Sensor Participant"
> +#string STR_DPTF_GENERIC1_PARTICIPANT                  #language en-US
> "DPTF Display Board Sensor Participant"
> +#string STR_DPTF_GENERIC2_PARTICIPANT                  #language en-US
> "DPTF SOC Board Sensor Participant"
> +#string STR_DPTF_SDP                                   #language en-US  "Scenario Design
> Power"
> +
> +#string STR_DPTF_BRAND_STRING                          #language en-US  "Brand
> String"
> +#string STR_DPTF_BRAND_STRING_HELP                     #language en-US
> "Brand string for the processor, example Nxxx or Jxxx"
> +
> +#string STR_DPTF_N3510                                 #language en-US  "N3510/20"
> +#string STR_DPTF_N2910                                 #language en-US  "N2910/20"
> +#string STR_DPTF_N2810                                 #language en-US  "N2810/15/20"
> +#string STR_DPTF_N2805                                 #language en-US  "N2805/06"
> +#string STR_DPTF_J2850                                 #language en-US  "J2850/2900"
> +#string STR_DPTF_J1850                                 #language en-US  "J1850/1900"
> +#string STR_DPTF_J1750                                 #language en-US  "J1750/1800"
> +
> +#string STR_DPTF_GENERIC3_PARTICIPANT                  #language en-US
> "DPTF Charger Board Sensor Participant"
> +#string STR_DPTF_GENERIC4_PARTICIPANT                  #language en-US
> "DPTF Generic Sensor4 Participant"
> +#string STR_DPTF_CRITICAL_TEMP                         #language en-US  "Critical"
> +#string STR_DPTF_PASSIVE_TEMP                          #language en-US  "Passive"
> +#string STR_DPTF_CRITICAL_TEMP_HELP                    #language en-US
> "Critical Temperature"
> +#string STR_DPTF_PASSIVE_TEMP_HELP                     #language en-US
> "Passive Temperature"
> +#string STR_DPTF_CLPM                                  #language en-US  "CLPM"
> +#string STR_DPTF_CLPM_HELP                             #language en-US  "Current
> Low Power Mode"
> +#string STR_DPTF_LPM_APP                               #language en-US  "Application
> specific"
> +#string STR_DPTF_LPM_OS                                #language en-US  "OS level"
> +#string STR_DPTF_SDBG                                  #language en-US  "Super Debug"
> +#string STR_DPTF_SDBG_HELP                             #language en-US  "Super
> debug is for validation purpose"
> +#string STR_DPTF_OFFLINING                             #language en-US  "Processor
> Offlining"
> +#string STR_DPTF_OFFLINING_HELP                        #language en-US  "Enable
> or disable processor offlining, passive policy only"
> +#string STR_DPTF_CLPO                                  #language en-US  "Current Logical
> Processor Offlining"
> +#string STR_DPTF_CLPO_HELP                             #language en-US  "Controls
> LPO Control preferences. Used only by Passive policy"
> +#string STR_DPTF_CLPO_START_PINDEX                     #language en-US  "Start
> P-State"
> +#string STR_DPTF_CLPO_START_PINDEX_HELP                #language en-US
> "Instructs the policy when to initiate Active Core control if enabled"
> +#string STR_DPTF_CLPO_PSTATE_INDEX0                    #language en-US  "P0"
> +#string STR_DPTF_CLPO_PSTATE_INDEX1                    #language en-US  "P1"
> +#string STR_DPTF_CLPO_PSTATE_INDEX2                    #language en-US  "P2"
> +#string STR_DPTF_CLPO_PSTATE_INDEX3                    #language en-US  "P3"
> +#string STR_DPTF_CLPO_PSTATE_INDEX4                    #language en-US  "P4"
> +#string STR_DPTF_CLPO_PSTATE_INDEX5                    #language en-US  "P5"
> +#string STR_DPTF_CLPO_PSTATE_INDEX6                    #language en-US  "P6"
> +#string STR_DPTF_CLPO_PSTATE_INDEX7                    #language en-US  "P7"
> +#string STR_DPTF_CLPO_PSTATE_INDEX8                    #language en-US  "P8"
> +#string STR_DPTF_CLPO_PSTATE_INDEX9                    #language en-US  "P9"
> +#string STR_DPTF_CLPO_PSTATE_INDEX10                   #language en-US  "P10"
> +#string STR_DPTF_CLPO_PSTATE_INDEX11                   #language en-US  "P11"
> +#string STR_DPTF_CLPO_PSTATE_INDEX12                   #language en-US  "P12"
> +#string STR_DPTF_CLPO_STEP_SIZE                        #language en-US  "Step
> size"
> +#string STR_DPTF_CLPO_STEP_SIZE_HELP                   #language en-US
> "Instructs the policy to take away logical processors in the specified
> percentage steps."
> +#string STR_DPTF_CLPO_STEP_SIZE_VALUE_25               #language en-US
> "25%"
> +#string STR_DPTF_CLPO_STEP_SIZE_VALUE_50               #language en-US
> "50%"
> +#string STR_DPTF_CLPO_STEP_SIZE_VALUE_75               #language en-US
> "75%"
> +#string STR_DPTF_CLPO_PWR_CTRL                         #language en-US  "Power
> Control Setting"
> +#string STR_DPTF_CLPO_PWR_CTRL_HELP                    #language en-US
> "Instructs the policy whether to use Core offliing if Active core control is
> enabled to be used in P0 or when power control is applied"
> +#string STR_DPTF_CLPO_PERF_CTRL                        #language en-US
> "Performance Control Setting"
> +#string STR_DPTF_CLPO_PERF_CTRL_HELP                   #language en-US
> "Instructs the policy whether to use Core offliing if Active core control is
> enabled to be used in P1 or when performance control is applied"
> +#string STR_DPTF_SMT_OFFFLINING                        #language en-US  "SMT
> Offlining"
> +#string STR_DPTF_CORE_OFFFLINING                       #language en-US  "Core
> Offlining"
> +#string STR_DPTF_DPPM                                  #language en-US  "DPPM"
> +#string STR_DPTF_DPPM_HELP                             #language en-US  "Controls
> DPPM policies"
> +
> +#string STR_DYNAMIC_PLATFORM_THER_FRAME_PROMPT         #language
> en-US  "Dynamic Platform&Thermal Framework"
> +#string STR_DYNAMIC_PLATFORM_THER_FRAME_HELP           #language en-
> US  ""
> +#string STR_DYNAMIC_PLATFORM_THER_FRAME_PROMPT         #language
> en-US  "Dynamic Platform&Thermal Framework"
> +#string STR_DYNAMIC_PLATFORM_THER_FRAME_HELP           #language en-
> US  ""
> +
> +#string STR_DPTF_PASSIVE_TRIP_POINT_PROMPT             #language en-US "
> Passive Trip Point"
> +#string STR_DPTF_PASSIVE_TRIP_POINT_HELP               #language en-US ""
> +#string STR_DPTF_ACTIVE_TRIP_POINT_PROMPT              #language en-US "
> Active Trip Point"
> +#string STR_DPTF_ACTIVE_TRIP_POINT_HELP                #language en-US ""
> +#string STR_DPTF_CRITICAL_TRIP_POINT_PROMPT            #language en-US "
> Critical Trip Point"
> +#string STR_DPTF_CRITICAL_TRIP_POINT_HELP              #language en-US ""
> +#string STR_DPTF_HOT_TRIP_POINT_PROMPT                 #language en-US "
> Hot Trip Point"
> +#string STR_DPTF_HOT_TRIP_POINT_HELP                   #language en-US ""
> +#string STR_NEW                                        #language en-US  "New"
> +#string STR_LEGACY                                     #language en-US  "Legacy"
> +#string STR_CPU                                        #language en-US  "CPU"
> +#string STR_SA                                         #language en-US  "SA"
> +
> +//
> +//Memory
> +//
> +#string STR_MEMORY_SCRAMBLER_PROMPT                    #language en-US
> "Memory Scrambler"
> +#string STR_MEMORY_SCRAMBLER_HELP                      #language en-US
> "Enable/Disable Memory Scrambler support."
> +
> +#string STR_GOP_TITLE                                  #language en-US "GOP
> Configuration"
> +#string STR_GOP_VBIOS_SWITCH                           #language en-US "GOP
> Driver"
> +#string STR_GOP_BRIGHTNESS_LEVEL                       #language en-US "GOP
> Brightness Level"
> +#string STR_GOP_BRIGHTNESS_LEVEL_HELP                  #language en-US "Set
> GOP Brightness Level; Value ranges from 0-255"
> +#string STR_GOP_VBIOS_SWITCH_HELP                      #language en-US
> "Enable GOP Driver will unload VBIOS; Disable it will load VBIOS"
> +#string STR_GOP_BRIGHT_0                               #language en-US "0"
> +#string STR_GOP_BRIGHT_20                              #language en-US "20"
> +#string STR_GOP_BRIGHT_40                              #language en-US "40"
> +#string STR_GOP_BRIGHT_60                              #language en-US "60"
> +#string STR_GOP_BRIGHT_80                              #language en-US "80"
> +#string STR_GOP_BRIGHT_100                             #language en-US "100"
> +#string STR_GOP_BRIGHT_120                             #language en-US "120"
> +#string STR_GOP_BRIGHT_140                             #language en-US "140"
> +#string STR_GOP_BRIGHT_160                             #language en-US "160"
> +#string STR_GOP_BRIGHT_180                             #language en-US "180"
> +#string STR_GOP_BRIGHT_200                             #language en-US "200"
> +#string STR_GOP_BRIGHT_220                             #language en-US "220"
> +#string STR_GOP_BRIGHT_240                             #language en-US "240"
> +#string STR_GOP_BRIGHT_255                             #language en-US "255"
> +
> +
> +//
> +//System Components
> +//
> +#string STR_PMIC_CONFIGURATION_TITLE                   #language en-US
> "PMIC Configuration"
> +#string STR_PMIC_ACPI_OBJECT_PROMPT                    #language en-US
> "PMIC ACPI OBJECT"
> +#string STR_PMIC_ACPI_OBJECT_HELP                      #language en-US
> "Enable/Disable PMIC ACPI Device."
> +
> +#string STR_PNP_CONFIGURATION_TITLE                    #language en-US
> "System Power and Performance(PnP) Configuration"
> +#string STR_PNP_SETTING_PROMPT                         #language en-US "SoC PnP
> Setting"
> +#string STR_PNP_SETTING_HELP                           #language en-US "Select SoC
> PnP setting mode. Auto detect mode will load the SoC PnP table against
> stepping."
> +#string STR_PNP_POWER_STRING                           #language en-US
> "Performance"
> +#string STR_PNP_PERFORMANCE_STRING                     #language en-US
> "Power"
> +#string STR_PNP_POWER_PERFORMANCE_STRING               #language en-US
> "Auto Detect"
> +#string STR_PNP_POWER_PERFORMANCE_STRING_A0            #language en-
> US "Ax Stepping"
> +#string STR_PNP_POWER_PERFORMANCE_STRING_B0            #language en-
> US "Bx Stepping"
> +
> +#string STR_CFIO_PNP_SETTING_PROMPT                    #language en-US
> "CFIO/GPIO PnP Setting"
> +#string STR_CFIO_PNP_SETTING_HELP                      #language en-US
> "Enable/Disable CFIO/GPIO PnP setting mode. When enabled, CFIO/GPIO
> unused pins will be in tri-state for power saving."
> +
> +#string STR_TRISTATE_LPC_PROMPT                        #language en-US "LPC PnP
> Setting"
> +#string STR_TRISTATE_LPC_HELP                          #language en-US
> "Enable/Disable LPC PnP Setting. When enabled, the Lpc will diable clock and
> be placed in tri-state for power saveing when Bios hands over control to OS.
> If there is device connected to LPC bus, this setting should not be enabled."
> +
> +#string STR_SLP_S0IX_N_PROMPT                          #language en-US "Asset
> SLP_S0IX_N in S0ix"
> +#string STR_SLP_S0IX_N_HELP                            #language en-US
> "Auto/Enable/Disable Asset SLP_S0IX_N in S0ix. In Auto mode, PMC will
> assert SLP_S0IX_N ONLY for PR1.4 and beyond, RVP plus Rohm B3 or Dialog
> C0 or Maxim. In Enable mode, PMC will assert the SLP_S0IX_N to save power
> regardless the board type."
> +
> +#string STR_CRID_SETTING_HELP                          #language en-US "Select the
> Revision ID reflected in PCI config space"
> +#string STR_CRID_PROMPT                                #language en-US "CRID Setting"
> +#string STR_CRID_0_STRING                              #language en-US "CRID_0"
> +#string STR_CRID_1_STRING                              #language en-US "CRID_1"
> +#string STR_CRID_2_STRING                              #language en-US "CRID_2"
> +
> +#string STR_PCIE_SPEED_PROMPT0                         #language en-US "PCIe 0
> Speed"
> +#string STR_PCIE_SPEED_PROMPT1                         #language en-US "PCIe 1
> Speed"
> +#string STR_PCIE_SPEED_PROMPT2                         #language en-US "PCIe 2
> Speed"
> +#string STR_PCIE_SPEED_PROMPT3                         #language en-US "PCIe 3
> Speed"
> +#string STR_SATA_TEST_MODE_PROMPT                      #language en-US
> "SATA Test Mode"
> +#string STR_PCIE_SPEED_HELP                            #language en-US "Configure
> PCIe Speed"
> +#string STR_AUTO                                       #language en-US "Auto"
> +#string STR_GEN1                                       #language en-US "Gen1"
> +#string STR_GEN2                                       #language en-US "Gen2"
> +#string STR_SATA_TEST_MODE_HELP                        #language en-US "Test
> Mode Enable/Disable"
> +
> +#string STR_SECURE_BOOT_MODE_HELP                      #language en-US
> "Secure Boot Mode - Custom & Standard"
> +#string STR_SECURE_BOOT                                #language en-US "SecureBoot"
> +#string STR_CLEAR_ALL_KEYS                             #language en-US "Clear all
> Keys"
> +#string STR_CLEAR_ALL_KEYS_HELP                        #language en-US "Clears PK,
> KEK, DB and DBx. Clearing Keys should be done in Custom Mode"
> +#string STR_LOAD_DEFAULTS_KEYS                         #language en-US "Load
> UEFI Secure Boot Defaults and Exit"
> +#string STR_LOAD_DEFAULTS_KEYS_HELP                    #language en-US "Loads
> PK,KEK, DBx and DB. Should be done in Custom Mode"
> +#string STR_SECURE_BOOT_UPP_PROMPT                     #language en-US
> "User Physical Present"
> +#string STR_SECURE_BOOT_UPP_HELP                       #language en-US "User is
> Physical Present User"
> +#string STR_SECURE_BOOT_MODE_PROMPT                    #language en-US
> "UEFI Secure Boot Mode"
> +#string STR_SECURE_BOOT_MODE_HELP                      #language en-US "Set
> UEFI Secure Boot Mode to STANDARD mode or CUSTOM mode, this change
> is effect after save. And after reset, the mode will return to STANDARD
> mode"
> +#string STR_SB_STANDARD_MODE                           #language en-US
> "STANDARD"
> +#string STR_SB_CUSTOM_MODE                             #language en-US "CUSTOM"
> +#string STR_SECURE_BOOT_PRO_KEY_PROMPT                 #language en-US
> "UEFI Secure Boot Key"
> +#string STR_SECURE_BOOT_PRO_KEY_HELP                   #language en-US "Set
> the UEFI Secure Boot Key to Development Key or Production Key, Change
> Key should be done in Custom Mode"
> +#string STR_DEV_KEY                                    #language en-US "Development
> Key"
> +#string STR_PRO_KEY                                    #language en-US "Production Key"
> +
> +// ACPI Memory Debug
> +//
> +#string STR_ACPIMEMDBG_STRING                          #language en-US "ACPI
> Memory Debug Switch"
> +#string STR_ACPIMEMDBG_SWTICH                          #language en-US "ACPI
> Memory Debug"
> +#string STR_ACPIMEMDBG_SWTICH_HELP                     #language en-US
> "Enable or Disable ACPI Memory Debug"
> +
> +#string STR_EXISUPPORT_PROMPT                          #language en-US "ExI"
> +#string STR_EXISUPPORT_HELP                            #language en-US
> "Enabled/Disabled ExI"
> +
> +#string STR_PMWEIGHTS_PROMPT                           #language en-US "PM
> Weights"
> +#string STR_PMWEIGHTS_HELP                             #language en-US
> "Enabled/Disabled PM Weights"
> +
> +#string STR_LPSSDEVHIDE_PROMPT                         #language en-US
> "Unsupported LPSS Device"
> +#string STR_LPSSDEVHIDE_HELP                           #language en-US "Hide
> unsupported LPSS devices when in ACPI Mode"
> +#string STR_HIDE                                       #language en-US "Hide"
> +#string STR_UNHIDE                                     #language en-US "UnHide"
> +
> +#string STR_BATTERY_CONFIGURATION_TITLE                #language en-US
> "Battery Charging Configuration"
> +#string STR_BATTERY_ACPI_OBJECT_PROMPT                 #language en-US
> "Battery solution"
> +#string STR_BATTERY_ACPI_OBJECT_HELP                   #language en-US "If it
> does not match, battery will not work properly."
> +#string STR_NON_ULPMC                                  #language en-US "Non ULPMC
> solution"
> +#string STR_ULPMC                                      #language en-US "ULPMC solution"
> +
> +#string STR_CRITICAL_BATTERY_LIMIT_PROMPT              #language en-US
> "Critical Battery Limit"
> +#string STR_CRITICAL_BATTERY_LIMIT_HELP                #language en-US "Limit
> in percentage below which the system is not allowed to boot.
> +
> +#string STR_CRITICAL_BATTERY_LIMIT_FEATURE_PROMPT    #language en-
> US "Critical Battery Limit Feature"
> +#string STR_CRITICAL_BATTERY_LIMIT_FEATURE_HELP      #language en-US
> "Enable or Disable Critical Battery Limit Feature."
> +
> +#string STR_ULPMC_FW_LOCK_PROMPT                       #language en-US
> "ULPMC Firmware Lock"
> +#string STR_ULPMC_FW_LOCK_HELP                         #language en-US "Enable
> or Disable Lock ULPMC Firmware Update."
> +#string STR_WITT_CONFIGURATION_TITLE                   #language en-US "WITT
> Configuration"
> +#string STR_WITT_PROMPT                                #language en-US "Enable WITT"
> +#string STR_WITT_HELP                                  #language en-US "Enable or
> Disable WITT"
> +#string STR_UTS_PROMPT                                 #language en-US "Enable
> UTS(Uart Test Suite)"
> +#string STR_UTS_HELP                                   #language en-US "Enable or Disable
> Uart Test suite"
> +#string STR_PCH_SPI_WP_PROMPT                          #language en-US "BIOS
> Read/Write Protection"
> +#string STR_PCH_SPI_WP_HELP                            #language en-US "Enable or
> Disable BIOS SPI region read/write protect."
> +#string STR_PCH_SPI_WP_DISABLE                         #language en-US "Disable"
> +#string STR_PCH_SPI_WP_ENABLE                          #language en-US "Enable"
> +#string STR_IGD_TURBO_PROMPT                           #language en-US  "IGD
> Turbo"
> +#string STR_IGD_TURBO_HELP                             #language en-US  "Select the
> IGD Turbo feature, if Auto selected, IGD Turbo will only be enabled when
> SOC stepping is B0 or above."
> +#string STR_EHCI_PLL_CFG_PROMPT                        #language en-US "EHCI PLL
> Configure"
> +#string STR_EHCI_PLL_CFG_RTD3_DIS_HELP                 #language en-US
> "Enable/Disable EHCI PLL Configure For RTD3"
> +
> +// Codec ALC-262 disabled
> +#string STR_CODEC262_DISABLED_PROMPT                   #language en-US
> "Disable Codec ALC-262"
> +#string STR_CODEC262_DISABLED_HELP                     #language en-US
> "Enable/Disable Codec ALC-262."
> +
> +// SAR Sensor
> +#string STR_SAR_SENSOR_PROMPT                          #language en-US "SAR
> Sensor"
> +#string STR_SAR_SENSOR_HELP                            #language en-US "Enable or
> Disable SAR sensor"
> +
> +//Lakemore
> +//
> +#string STR_LM_INFORMATION_TITLE                      #language en-US
> "Lakemore Configuration:"
> +#string STR_LM_MEMORY_HELP                            #language en-US "Specify
> the amount of main memory to be reserved for Lakemore.  The memory will
> be allocated right after MRC initialization and its location will be stored into
> the Lakemore STOREMEMBAR registers."
> +#string STR_LM_MEMORY_PROMPT                          #language en-US
> "Memory Allocation Size"
> +#string STR_LM_MEMORY_16MB                            #language en-US "16000
> KiB"
> +#string STR_LM_MEMORY_8MB                             #language en-US "8000 KiB"
> +#string STR_LM_MEMORY_1MB                             #language en-US "1000 KiB"
> +#string STR_LM_MEMORY_128KB                           #language en-US "128 KiB"
> +#string STR_LM_MEMORY_0MB                             #language en-US "0 KiB"
> +
> +#string STR_PUINT_BIOS_CONFIG_DISPLAY                 #language en-US
> "PDM/Dfx Setting"
> +#string STR_PUINT_BIOS_CONFIG_DISPLAY_HELP            #language en-US
> "PDM On: Enable PDM and keep Dfx powered.\n\nPerf Mode: Disable PDM
> and keep Dfx powered. Allows more VISA signals to be used for HW
> debug.\n\nPower Save: Disable PDM, turn off Dfx power and Visa
> clocks.\n\nNOTE: If previous setting was POWERSAVE, then cold boot will be
> needed for Dfx to come back up."
> +#string STR_PUINT_BIOS_PDM                            #language en-US "PDM On"
> +#string STR_PUINT_BIOS_PERFORMANCE                    #language en-US "Perf
> Mode"
> +#string STR_PUINT_BIOS_POWERSAVE                      #language en-US "Power
> Save"
> +#string STR_PUINT_BIOS_RESERVED                       #language en-US "Debug
> Reserved"
> +
> +#string STR_PDM_OUTPUT_CONFIG_SWTICH                  #language en-US
> "PDM Msg Output"
> +#string STR_PDM_OUTPUT_CONFIG_SWTICH_HELP             #language en-US
> "Configure VISA and Lakemore for PDM with the given output.\n\nIf
> MainMem is selected then be sure to allocate memory for the output msgs
> in the above setting."
> +#string STR_PDM_OUTPUT_MEM                            #language en-US "Main
> Memory"
> +#string STR_PDM_OUTPUT_IO                             #language en-US "IO - TBD"
> +
> +#string STR_ENABLE_DBG2                               #language en-US "Enable DBG2
> Table"
> +#string STR_ENABLE_DBG2_HELP                          #language en-US
> "Enable/Disable DBG2 ACPI Table for Windbg"
> +
> +//eMMC
> +//
> +#string STR_SCC_EMMC_PROMPT                            #language en-US  "SCC
> eMMC 4.41 Support"
> +#string STR_SCC_EMMC_HELP                              #language en-US
> "Enable/Disable SCC eMMC 4.41 Support"
> +
> +#string STR_SCC_EMMC45_PROMPT                         #language en-US  "SCC
> eMMC45 Support"
> +#string STR_SCC_EMMC45_HELP                           #language en-US
> "Enable/Disable SCC eMMC 4.5 Support"
> +#string STR_SCC_EMMC45_DDR50_PROMPT                   #language en-US
> "DDR50 Capability Support"
> +#string STR_SCC_EMMC45_DDR50_HELP                     #language en-US
> "Enable/Disable SCC eMMC 4.5 DDR 50 support"
> +#string STR_SCC_EMMC45_HS200_PROMPT                   #language en-US
> "HS200 Capability Support"
> +#string STR_SCC_EMMC45_HS200_HELP                     #language en-US
> "Enable/Disable SCC eMMC 4.5 HS 200 support"
> +#string STR_SCC_EMMC45_RE_TUNE_TIMER_VALUE            #language en-US
> "Re Tune Timer Value"
> +#string STR_SCC_EMMC45_RE_TUNE_TIMER_VALUE_HELP       #language
> en-US  "Set the re tune timer value"
> +
> +#string STR_SCC_EMMC45_SETTING_SUBTITLE               #language en-US
> "SCC eMMC 4.5 Configuration"
> +#string STR_EMMC45_TIMER_0                            #language en-US "0"
> +#string STR_EMMC45_TIMER_1                            #language en-US "1"
> +#string STR_EMMC45_TIMER_2                            #language en-US "2"
> +#string STR_EMMC45_TIMER_3                            #language en-US "3"
> +#string STR_EMMC45_TIMER_4                            #language en-US "4"
> +#string STR_EMMC45_TIMER_5                            #language en-US "5"
> +#string STR_EMMC45_TIMER_6                            #language en-US "6"
> +#string STR_EMMC45_TIMER_7                            #language en-US "7"
> +#string STR_EMMC45_TIMER_8                            #language en-US "8"
> +#string STR_EMMC45_TIMER_9                            #language en-US "9"
> +#string STR_EMMC45_TIMER_10                           #language en-US "10"
> +#string STR_EMMC45_TIMER_11                           #language en-US "11"
> +#string STR_EMMC45_TIMER_12                           #language en-US "12"
> +#string STR_EMMC45_TIMER_13                           #language en-US "13"
> +#string STR_EMMC45_TIMER_14                           #language en-US "14"
> +#string STR_EMMC45_TIMER_15                           #language en-US "15"
> +
> +#string STR_EMMC_BOOT_PROMPT                          #language en-US "SCC
> eMMC Boot Controller"
> +#string STR_EMMC_BOOT_HELP                            #language en-US
> "Disable/Select eMMC Boot mode; Auto Detect mode can switch the eMMC
> controller against the stepping"
> +#string STR_AUTO_DETECT                               #language en-US "Auto Detect"
> +#string STR_EMMC_BOOT_41                              #language en-US "eMMC 4.41"
> +#string STR_EMMC_BOOT_45                              #language en-US "eMMC 4.5"
> +
> +// SD card DDR50 and SD25
> +#string STR_SCC_SD_SDR25_PROMPT                       #language en-US "SDR25
> Capability Support for SDCard"
> +#string STR_SCC_SD_SDR25_HELP                         #language en-US
> "Disable/Enable SDR25 Capability in SD Card controller;
> +#string STR_SCC_SD_DDR50_PROMPT                       #language en-US "DDR50
> Capability Support for SDCard"
> +#string STR_SCC_SD_DDR50_HELP                         #language en-US
> "Disable/Enable DDR50 Capability in SD Card controller;
> +
> +#string STR_SECURE_ERASE_PROMPT                       #language en-US "eMMC
> Secure Erase"
> +#string STR_SECURE_ERASE_HELP                         #language en-US
> "Disable/Enable eMMC Secure Erase. When enabled, all the data on eMMC
> will be erased."
> +
> +
> +//
> +//Exit Option
> +//
> +#string STR_COMMIT_CHANGE_AND_EXIT_PROMPT             #language en-
> US "Commit Changes and Exit"
> +#string STR_COMMIT_CHANGE_AND_EXIT_HELP               #language en-US
> "Save the setup changes and exit"
> +
> +#string STR_DISCARD_CHANGE_AND_EXIT_PROMPT            #language en-US
> "Discard Changes and Exit"
> +#string STR_DISCARD_CHANGE_AND_EXIT_HELP              #language en-US
> "Discard the setup changes and exit"
> +
> +#string STR_LOAD_DEFAULT_AND_EXIT_PROMPT              #language en-US
> "Load Defaults and Exit"
> +#string STR_LOAD_DEFAULT_AND_EXIT_HELP                #language en-US
> "Load the setup defaults and Exit"
> +
> +#string STR_PSS_ENABLE_PROMPT                         #language en-US "PSS
> Storage"
> +#string STR_PSS_ENABLE_HELP                           #language en-US
> "Disable/Enable PSS-based secure boot"
> +#string STR_PSS_CONFIGURATION_TITLE                   #language en-US "PSS
> Settings"
> +
> +//
> +//Virtual Keyboard Option
> +//
> +#string STR_VIRTUAL_KB_TITLE                          #language en-US  "Virtual
> Keyboard Configuration"
> +#string STR_VIRTUAL_KB_PROMPT                         #language en-US  "Virtual
> Keyboard Support"
> +#string STR_VIRTUAL_KB_HELP                           #language en-US
> "Enable/Disable Virtual Keyboard"
> +
> +//
> +// MMIO Option
> +//
> +#string STR_MMIO_PROMPT                               #language en-US  "PCI MMIO
> Size"
> +#string STR_MMIO_0_75G_STRING                         #language en-US "0.75GB"
> +#string STR_MMIO_1G_STRING                            #language en-US "1GB"
> +#string STR_MMIO_1_25G_STRING                         #language en-US "1.25GB"
> +#string STR_MMIO_1_5G_STRING                         #language en-US "1.5GB"
> +#string STR_MMIO_2G_STRING                            #language en-US "2GB"
> +#string STR_MMIO_HELP                                 #language en-US  "Setup PCI
> MMIO Size 0.75G, 1G, 1.25G, 1.5G, 2GB Size"
> +
> +//
> +// OS Selection Option
> +//
> +#string STR_OS_SELETION_PROMPT                        #language en-US "OS
> Selection"
> +#string STR_OS_SELETION_HELP                          #language en-US "OS
> Selection"
> +#string STR_WINDOWS                                   #language en-US "Windows 8.X"
> +#string STR_ANDROID                                   #language en-US "Android"
> +#string STR_WINDOWS7                                  #language en-US "Windows 7 UEFI
> 64bit"
> +#string STR_LWINDOWS7                                 #language en-US "Win7 32/64
> Legacy"
> +#string STR_WEC7                                      #language en-US "WEC7"
> +#string STR_LINUX                                     #language en-US "Linux"
> +#string STR_BOOT_DISPLAY_MIPIDSI_PROMPT               #language en-US
> "MIPI DSI"
> +#string STR_BOOT_DISPLAY_MIPIDSI_HELP                 #language en-US
> "Disable/enable MIPI DSI."
> +
> +
> +//
> +// EM-1 Selection Option
> +//
> +#string STR_EM1_IAAPPSRUN_PROMPT                       #language en-US
> "IA_APPS_RUN"
> +#string STR_EM1_IAAPPSRUN_HELP                         #language en-US "Voltage
> in mV"
> +#string STR_EM1_IAAPPSCAP_PROMPT                       #language en-US
> "IA_APPS_CAP"
> +#string STR_EM1_IAAPPSCAP_HELP                         #language en-US
> "Percentage"
> +#string STR_EM1_CAP_OR_VOLTAGE_PROMPT                  #language en-US
> "USE IA_APPS_RUN or CAP"
> +#string STR_EM1_CAP_OR_VOLTAGE_HELP                    #language en-US "Use
> Voltage or Capacity to decide boot flow"
> +#string STR_EM1_BOOT_ON_INVALID_BAT_PROMPT             #language en-
> US "Boot on invalid battery"
> +#string STR_EM1_BOOT_ON_INVALID_BAT_HELP               #language en-US
> "Allow to boot from invalid battery"
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/Platform.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/Platform.c
> new file mode 100644
> index 0000000000..8b46fbdfd1
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/Platform.c
> @@ -0,0 +1,997 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +    Platform.c
> +
> +Abstract:
> +
> +    This is a generic template for a child of the IchSmm driver.
> +
> +
> +--*/
> +
> +#include "SmmPlatform.h"
> +#include <Protocol/CpuIo2.h>
> +
> +
> +//
> +// Local variables
> +//
> +typedef struct {
> +  UINT8     Device;
> +  UINT8     Function;
> +} EFI_PCI_BUS_MASTER;
> +
> +EFI_PCI_BUS_MASTER  mPciBm[] = {
> +  { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1 },
> +  { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2 },
> +  { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3 },
> +  { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4 },
> +  { PCI_DEVICE_NUMBER_PCH_USB, PCI_FUNCTION_NUMBER_PCH_EHCI }
> +};
> +
> +
> +UINT16                                  mAcpiBaseAddr;
> +SYSTEM_CONFIGURATION                    mSystemConfiguration;
> +EFI_SMM_VARIABLE_PROTOCOL               *mSmmVariable;
> +EFI_GLOBAL_NVS_AREA_PROTOCOL            *mGlobalNvsAreaPtr;
> +
> +UINT16
> 	                mPM1_SaveState16;
> +UINT32
> 	                mGPE_SaveState32;
> +
> +BOOLEAN                                 mSetSmmVariableProtocolSmiAllowed = TRUE;
> +
> +
> +//
> +// Variables. Need to initialize this from Setup
> +//
> +BOOLEAN                                 mWakeOnLanS5Variable;
> +BOOLEAN                                 mWakeOnRtcVariable;
> +UINT8                                   mWakeupDay;
> +UINT8                                   mWakeupHour;
> +UINT8                                   mWakeupMinute;
> +UINT8                                   mWakeupSecond;
> +
> +//
> +// Use an enum. 0 is Stay Off, 1 is Last State, 2 is Stay On
> +//
> +UINT8                                   mAcLossVariable;
> +
> +
> +static
> +UINT8 mTco1Sources[] = {
> +  IchnNmi
> +};
> +
> +UINTN
> +DevicePathSize (
> +  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath
> +  );
> +
> +VOID
> +S4S5ProgClock();
> +
> +EFI_STATUS
> +InitRuntimeScriptTable (
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  );
> +
> +VOID
> +S5SleepWakeOnRtcCallBack (
> +  IN  EFI_HANDLE                    DispatchHandle,
> +  IN  EFI_SMM_SX_DISPATCH_CONTEXT   *DispatchContext
> +  );
> +
> +
> +VOID
> +EnableS5WakeOnRtc();
> +
> +UINT8
> +HexToBcd(
> +  UINT8 HexValue
> +  );
> +
> +UINT8
> +BcdToHex(
> +  IN UINT8 BcdValue
> +  );
> +
> +
> +VOID
> +CpuSmmSxWorkAround(
> +  );
> +
> +/**
> +  Initializes the SMM Handler Driver
> +
> +  @param ImageHandle
> +  @param SystemTable
> +
> +  @retval None
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitializePlatformSmm (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS                                Status;
> +  UINT8                                     Index;
> +  EFI_HANDLE                                Handle;
> +  EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT     PowerButtonContext;
> +  EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL
> *PowerButtonDispatch;
> +  EFI_SMM_ICHN_DISPATCH_CONTEXT             IchnContext;
> +  EFI_SMM_ICHN_DISPATCH_PROTOCOL            *IchnDispatch;
> +  EFI_SMM_SX_DISPATCH_PROTOCOL              *SxDispatch;
> +  EFI_SMM_SX_DISPATCH_CONTEXT               EntryDispatchContext;
> +  EFI_SMM_SW_DISPATCH_PROTOCOL              *SwDispatch;
> +  EFI_SMM_SW_DISPATCH_CONTEXT               SwContext;
> +  UINTN                                     VarSize;
> +  EFI_BOOT_MODE                             BootMode;
> +
> +  Handle = NULL;
> +
> +  //
> +  //  Locate the Global NVS Protocol.
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiGlobalNvsAreaProtocolGuid,
> +                  NULL,
> +                  (void **)&mGlobalNvsAreaPtr
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +
> +  //
> +  // Get the ACPI Base Address
> +  //
> +
> +  mAcpiBaseAddr = PchLpcPciCfg16( R_PCH_LPC_ACPI_BASE ) &
> B_PCH_LPC_ACPI_BASE_BAR;
> +
> +  VarSize = sizeof(SYSTEM_CONFIGURATION);
> +  Status = SystemTable->RuntimeServices->GetVariable(
> +                          L"Setup",
> +                          &gEfiSetupVariableGuid,
> +                          NULL,
> +                          &VarSize,
> +                          &mSystemConfiguration
> +                          );
> +  if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
> +    //The setup variable is corrupted
> +    VarSize = sizeof(SYSTEM_CONFIGURATION);
> +    Status = SystemTable->RuntimeServices->GetVariable(
> +              L"SetupRecovery",
> +              &gEfiSetupVariableGuid,
> +              NULL,
> +              &VarSize,
> +              &mSystemConfiguration
> +              );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +  if (!EFI_ERROR(Status)) {
> +    mAcLossVariable = mSystemConfiguration.StateAfterG3;
> +
> +    //
> +    // If LAN is disabled, WOL function should be disabled too.
> +    //
> +    if (mSystemConfiguration.Lan == 0x01){
> +      mWakeOnLanS5Variable = mSystemConfiguration.WakeOnLanS5;
> +    } else {
> +      mWakeOnLanS5Variable = FALSE;
> +    }
> +
> +    mWakeOnRtcVariable = mSystemConfiguration.WakeOnRtcS5;
> +  }
> +
> +  BootMode = GetBootModeHob ();
> +
> +  //
> +  // Get the Power Button protocol
> +  //
> +  Status = gBS->LocateProtocol(
> +                  &gEfiSmmPowerButtonDispatchProtocolGuid,
> +                  NULL,
> +                  (void **)&PowerButtonDispatch
> +                  );
> +  ASSERT_EFI_ERROR(Status);
> +
> +  if (BootMode != BOOT_ON_FLASH_UPDATE) {
> +    //
> +    // Register for the power button event
> +    //
> +    PowerButtonContext.Phase = PowerButtonEntry;
> +    Status = PowerButtonDispatch->Register(
> +                                    PowerButtonDispatch,
> +                                    PowerButtonCallback,
> +                                    &PowerButtonContext,
> +                                    &Handle
> +                                    );
> +    ASSERT_EFI_ERROR(Status);
> +  }
> +  //
> +  // Get the Sx dispatch protocol
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiSmmSxDispatchProtocolGuid,
> +                  NULL,
> +                                  (void **)&SxDispatch
> +                  );
> +  ASSERT_EFI_ERROR(Status);
> +
> +  //
> +  // Register entry phase call back function
> +  //
> +  EntryDispatchContext.Type  = SxS3;
> +  EntryDispatchContext.Phase = SxEntry;
> +
> +  Status = SxDispatch->Register (
> +                         SxDispatch,
> +                           (EFI_SMM_SX_DISPATCH)SxSleepEntryCallBack,
> +                         &EntryDispatchContext,
> +                         &Handle
> +                         );
> +
> +
> +  EntryDispatchContext.Type  = SxS4;
> +
> +  Status = SxDispatch->Register (
> +                         SxDispatch,
> +                         S4S5CallBack,
> +                         &EntryDispatchContext,
> +                         &Handle
> +                         );
> +  ASSERT_EFI_ERROR(Status);
> +
> +
> +  EntryDispatchContext.Type  = SxS5;
> +
> +  Status = SxDispatch->Register (
> +                         SxDispatch,
> +                         S4S5CallBack,
> +                         &EntryDispatchContext,
> +                         &Handle
> +                         );
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Status = SxDispatch->Register (
> +                         SxDispatch,
> +                         S5SleepAcLossCallBack,
> +                         &EntryDispatchContext,
> +                         &Handle
> +                         );
> +  ASSERT_EFI_ERROR(Status);
> +
> +  //
> +  //  Get the Sw dispatch protocol
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiSmmSwDispatchProtocolGuid,
> +                  NULL,
> +                                  (void **)&SwDispatch
> +                  );
> +  ASSERT_EFI_ERROR(Status);
> +
> +  //
> +  // Register ACPI enable handler
> +  //
> +  SwContext.SwSmiInputValue = ACPI_ENABLE;
> +  Status = SwDispatch->Register (
> +                         SwDispatch,
> +                         EnableAcpiCallback,
> +                         &SwContext,
> +                         &Handle
> +                         );
> +  ASSERT_EFI_ERROR(Status);
> +
> +  //
> +  // Register ACPI disable handler
> +  //
> +  SwContext.SwSmiInputValue = ACPI_DISABLE;
> +  Status = SwDispatch->Register (
> +                         SwDispatch,
> +                         DisableAcpiCallback,
> +                         &SwContext,
> +                         &Handle
> +                         );
> +  ASSERT_EFI_ERROR(Status);
> +
> +
> +  //
> +  // Register for SmmReadyToBootCallback
> +  //
> +  SwContext.SwSmiInputValue = SMI_SET_SMMVARIABLE_PROTOCOL;
> +  Status = SwDispatch->Register(
> +                         SwDispatch,
> +                         SmmReadyToBootCallback,
> +                         &SwContext,
> +                         &Handle
> +                         );
> +  ASSERT_EFI_ERROR(Status);
> +
> +  //
> +  // Get the ICHn protocol
> +  //
> +  Status = gBS->LocateProtocol(
> +                  &gEfiSmmIchnDispatchProtocolGuid,
> +                  NULL,
> +                  (void **)&IchnDispatch
> +                  );
> +  ASSERT_EFI_ERROR(Status);
> +
> +  //
> +  // Register for the events that may happen that we do not care.
> +  // This is true for SMI related to TCO since TCO is enabled by BIOS WP
> +  //
> +  for (Index = 0; Index < sizeof(mTco1Sources)/sizeof(UINT8); Index++) {
> +    IchnContext.Type = mTco1Sources[Index];
> +    Status = IchnDispatch->Register(
> +                             IchnDispatch,
> +                             (EFI_SMM_ICHN_DISPATCH)DummyTco1Callback,
> +                             &IchnContext,
> +                             &Handle
> +                             );
> +    ASSERT_EFI_ERROR( Status );
> +  }
> +
> +  //
> +  // Lock TCO_EN bit.
> +  //
> +  IoWrite16( mAcpiBaseAddr + R_PCH_TCO_CNT, IoRead16( mAcpiBaseAddr
> + R_PCH_TCO_CNT ) | B_PCH_TCO_CNT_LOCK );
> +
> +  //
> +  // Set to power on from G3 dependent on WOL instead of AC Loss variable
> in order to support WOL from G3 feature.
> +  //
> +  //
> +  // Set wake from G3 dependent on AC Loss variable and Wake On LAN
> variable.
> +  // This is because no matter how, if WOL enabled or AC Loss variable not
> disabled, the board needs to wake from G3 to program the LAN WOL settings.
> +  // This needs to be done after LAN enable/disable so that the PWR_FLR
> state clear not impacted the WOL from G3 feature.
> +  //
> +  if (mAcLossVariable != 0x00) {
> +    SetAfterG3On (TRUE);
> +  } else {
> +    SetAfterG3On (FALSE);
> +  }
> +
> +
> +
> +
> +  return EFI_SUCCESS;
> +}
> +
> +VOID
> +EFIAPI
> +SmmReadyToBootCallback (
> +  IN  EFI_HANDLE                    DispatchHandle,
> +  IN  EFI_SMM_SW_DISPATCH_CONTEXT   *DispatchContext
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  if (mSetSmmVariableProtocolSmiAllowed)
> +  {
> +  	//
> +    // It is okay to use gBS->LocateProtocol here because
> +    // we are still in trusted execution.
> +    //
> +  Status = gBS->LocateProtocol(
> +                  &gEfiSmmVariableProtocolGuid,
> +                  NULL,
> +                  (void **)&mSmmVariable
> +                  );
> +
> +    ASSERT_EFI_ERROR(Status);
> +
> +    //
> +    // mSetSmmVariableProtocolSmiAllowed will prevent this function from
> +    // being executed more than 1 time.
> +    //
> +    mSetSmmVariableProtocolSmiAllowed = FALSE;
> +  }
> +
> +}
> +
> +/**
> +
> +  @param DispatchHandle   The handle of this callback, obtained when
> registering
> +  @param DispatchContext  The predefined context which contained sleep
> type and phase
> +
> +
> +  @retval EFI_SUCCESS     Operation successfully performed
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SxSleepEntryCallBack (
> +  IN  EFI_HANDLE                    DispatchHandle,
> +  IN  EFI_SMM_SX_DISPATCH_CONTEXT   *DispatchContext
> +  )
> +{
> +  EFI_STATUS              Status;
> +
> +  Status = SaveRuntimeScriptTable ();
> +  if (EFI_ERROR(Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Workaround for S3 wake hang if C State is enabled
> +  //
> +  CpuSmmSxWorkAround();
> +
> +  return EFI_SUCCESS;
> +}
> +
> +VOID
> +CpuSmmSxWorkAround(
> +  )
> +{
> +  UINT64           MsrValue;
> +
> +  MsrValue = AsmReadMsr64 (0xE2);
> +
> +  if (MsrValue & BIT15) {
> +    return;
> +  }
> +
> +  if (MsrValue & BIT10) {
> +    MsrValue &= ~BIT10;
> +    AsmWriteMsr64 (0xE2, MsrValue);
> +  }
> +}
> +
> +VOID
> +ClearP2PBusMaster(
> +  )
> +{
> +  UINT8             Command;
> +  UINT8             Index;
> +
> +  for (Index = 0; Index < sizeof(mPciBm)/sizeof(EFI_PCI_BUS_MASTER);
> Index++) {
> +    Command = MmioRead8 (
> +                MmPciAddress (0,
> +                  DEFAULT_PCI_BUS_NUMBER_PCH,
> +                  mPciBm[Index].Device,
> +                  mPciBm[Index].Function,
> +                  PCI_COMMAND_OFFSET
> +                )
> +              );
> +    Command &= ~EFI_PCI_COMMAND_BUS_MASTER;
> +    MmioWrite8 (
> +      MmPciAddress (0,
> +        DEFAULT_PCI_BUS_NUMBER_PCH,
> +        mPciBm[Index].Device,
> +        mPciBm[Index].Function,
> +        PCI_COMMAND_OFFSET
> +      ),
> +      Command
> +    );
> +  }
> +}
> +
> +/**
> +
> +  Set the AC Loss to turn on or off.
> +
> +**/
> +VOID
> +SetAfterG3On (
> +  BOOLEAN Enable
> +  )
> +{
> +  UINT8             PmCon1;
> +
> +  //
> +  // ICH handling portion
> +  //
> +  PmCon1 = MmioRead8 ( PMC_BASE_ADDRESS +
> R_PCH_PMC_GEN_PMCON_1 );
> +  PmCon1 &= ~B_PCH_PMC_GEN_PMCON_AFTERG3_EN;
> +  if (Enable) {
> +    PmCon1 |= B_PCH_PMC_GEN_PMCON_AFTERG3_EN;
> +  }
> +  MmioWrite8 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1,
> PmCon1);
> +
> +}
> +
> +/**
> +  When a power button event happens, it shuts off the machine
> +
> +**/
> +VOID
> +EFIAPI
> +PowerButtonCallback (
> +  IN  EFI_HANDLE                              DispatchHandle,
> +  IN  EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT   *DispatchContext
> +  )
> +{
> +  //
> +  // Check what the state to return to after AC Loss. If Last State, then
> +  // set it to Off.
> +  //
> +  UINT16  data16;
> +
> +  if (mWakeOnRtcVariable) {
> +    EnableS5WakeOnRtc();
> +  }
> +
> +  if (mAcLossVariable == 1) {
> +    SetAfterG3On (TRUE);
> +  }
> +
> +  ClearP2PBusMaster();
> +
> +  //
> +  // Program clock chip
> +  //
> +  S4S5ProgClock();
> +
> +
> +  data16 = (UINT16)(IoRead16(mAcpiBaseAddr + R_PCH_ACPI_GPE0a_EN));
> +  data16 &= B_PCH_ACPI_GPE0a_EN_PCI_EXP;
> +
> +
> +  //
> +  // Clear Sleep SMI Status
> +  //
> +  IoWrite16 (mAcpiBaseAddr + R_PCH_SMI_STS,
> +                (UINT16)(IoRead16 (mAcpiBaseAddr + R_PCH_SMI_STS) |
> B_PCH_SMI_STS_ON_SLP_EN));
> +  //
> +  // Clear Sleep Type Enable
> +  //
> +  IoWrite16 (mAcpiBaseAddr + R_PCH_SMI_EN,
> +                (UINT16)(IoRead16 (mAcpiBaseAddr + R_PCH_SMI_EN) &
> (~B_PCH_SMI_EN_ON_SLP_EN)));
> +
> +  //
> +  // Clear Power Button Status
> +  //
> +  IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_STS,
> B_PCH_ACPI_PM1_STS_PWRBTN);
> +
> +  //
> +  // Shut it off now!
> +  //
> +  IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT,
> V_PCH_ACPI_PM1_CNT_S5);
> +  IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT,
> B_PCH_ACPI_PM1_CNT_SLP_EN | V_PCH_ACPI_PM1_CNT_S5);
> +
> +  //
> +  // Should not return
> +  //
> +  CpuDeadLoop();
> +}
> +
> +
> +/**
> +  @param DispatchHandle  - The handle of this callback, obtained when
> registering
> +
> +  @param DispatchContext - The predefined context which contained sleep
> type and phase
> +
> +**/
> +VOID
> +EFIAPI
> +S5SleepAcLossCallBack (
> +  IN  EFI_HANDLE                    DispatchHandle,
> +  IN  EFI_SMM_SX_DISPATCH_CONTEXT   *DispatchContext
> +  )
> +{
> +  //
> +  // Check what the state to return to after AC Loss. If Last State, then
> +  // set it to Off.
> +  //
> +  if (mAcLossVariable == 1) {
> +    SetAfterG3On (TRUE);
> +  }
> +}
> +
> +/**
> +
> +  @param DispatchHandle   The handle of this callback, obtained when
> registering
> +  @param DispatchContext  The predefined context which contained sleep
> type and phase
> +
> +  @retval Clears the Save State bit in the clock.
> +
> +**/
> +VOID
> +EFIAPI
> +S4S5CallBack (
> +  IN  EFI_HANDLE                    DispatchHandle,
> +  IN  EFI_SMM_SX_DISPATCH_CONTEXT   *DispatchContext
> +  )
> +{
> +
> +  UINT32        Data32;
> +
> +  //
> +  // Enable/Disable USB Charging
> +  //
> +  if (mSystemConfiguration.UsbCharging == 0x01) {
> +    Data32 = IoRead32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL);
> +    Data32 |= BIT8;
> +    IoWrite32(GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL, Data32);
> +  }
> +
> +}
> +
> +
> +VOID
> +S4S5ProgClock()
> +{
> +}
> +
> +/**
> +  SMI handler to enable ACPI mode
> +
> +  Dispatched on reads from APM port with value 0xA0
> +
> +  Disables the SW SMI Timer.
> +  ACPI events are disabled and ACPI event status is cleared.
> +  SCI mode is then enabled.
> +
> +   Disable SW SMI Timer
> +
> +   Clear all ACPI event status and disable all ACPI events
> +   Disable PM sources except power button
> +   Clear status bits
> +
> +   Disable GPE0 sources
> +   Clear status bits
> +
> +   Disable GPE1 sources
> +   Clear status bits
> +
> +   Guarantee day-of-month alarm is invalid (ACPI 5.0 Section 4.8.2.4 "Real
> Time Clock Alarm")
> +
> +   Enable SCI
> +
> +  @param DispatchHandle  - EFI Handle
> +  @param DispatchContext - Pointer to the
> EFI_SMM_SW_DISPATCH_CONTEXT
> +
> +  @retval Nothing
> +
> +**/
> +VOID
> +EFIAPI
> +EnableAcpiCallback (
> +  IN  EFI_HANDLE                    DispatchHandle,
> +  IN  EFI_SMM_SW_DISPATCH_CONTEXT   *DispatchContext
> +  )
> +{
> +  UINT32 SmiEn;
> +  UINT16 Pm1Cnt;
> +  UINT16 wordValue;
> +  UINT32 RegData32;
> +
> +  //
> +  // Disable SW SMI Timer
> +  //
> +  SmiEn = IoRead32(mAcpiBaseAddr + R_PCH_SMI_EN);
> +  SmiEn &= ~B_PCH_SMI_STS_SWSMI_TMR;
> +  IoWrite32(mAcpiBaseAddr + R_PCH_SMI_EN, SmiEn);
> +
> +  wordValue = IoRead16(mAcpiBaseAddr + R_PCH_ACPI_PM1_STS);
> +  if(wordValue & B_PCH_ACPI_PM1_STS_WAK) {
> +	  IoWrite32((mAcpiBaseAddr + R_PCH_ACPI_GPE0a_EN), 0x0000);
> +	  IoWrite32((mAcpiBaseAddr + R_PCH_ACPI_GPE0a_STS), 0xffffffff);
> +  }
> +  else {
> +		mPM1_SaveState16 = IoRead16(mAcpiBaseAddr +
> R_PCH_ACPI_PM1_EN);
> +
> +		//
> +		// Disable PM sources except power button
> +		//
> +    // power button is enabled only for PCAT. Disabled it on Tablet platform
> +    //
> +    IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_EN,
> B_PCH_ACPI_PM1_EN_PWRBTN);
> +		IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_STS, 0xffff);
> +
> +		mGPE_SaveState32 = IoRead16(mAcpiBaseAddr +
> R_PCH_ACPI_GPE0a_EN);
> +		IoWrite32(mAcpiBaseAddr + R_PCH_ACPI_GPE0a_EN,
> 0x0000);
> +		IoWrite32(mAcpiBaseAddr + R_PCH_ACPI_GPE0a_STS,
> 0xffffffff);
> +
> +  }
> +
> +  //
> +  // Guarantee day-of-month alarm is invalid (ACPI 5.0 Section 4.8.2.4 "Real
> Time Clock Alarm")
> +  // Clear Status D reg VM bit, Date of month Alarm to make Data in CMOS
> RAM is no longer Valid
> +  //
> +  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_D);
> +  IoWrite8 (PCAT_RTC_DATA_REGISTER, 0x0);
> +
> +
> +	RegData32 = IoRead32(ACPI_BASE_ADDRESS +
> R_PCH_ALT_GP_SMI_EN);
> +	RegData32 &= ~(BIT7);
> +    IoWrite32((ACPI_BASE_ADDRESS + R_PCH_ALT_GP_SMI_EN),
> RegData32);
> +
> +
> +  //
> +  // Enable SCI
> +  //
> +  Pm1Cnt = IoRead16(mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT);
> +  Pm1Cnt |= B_PCH_ACPI_PM1_CNT_SCI_EN;
> +  IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT, Pm1Cnt);
> +
> +
> +}
> +
> +/**
> +  SMI handler to disable ACPI mode
> +
> +  Dispatched on reads from APM port with value 0xA1
> +
> +  ACPI events are disabled and ACPI event status is cleared.
> +  SCI mode is then disabled.
> +   Clear all ACPI event status and disable all ACPI events
> +   Disable PM sources except power button
> +   Clear status bits
> +   Disable GPE0 sources
> +   Clear status bits
> +   Disable GPE1 sources
> +   Clear status bits
> +   Disable SCI
> +
> +  @param DispatchHandle  - EFI Handle
> +  @param DispatchContext - Pointer to the
> EFI_SMM_SW_DISPATCH_CONTEXT
> +
> +  @retval Nothing
> +
> +**/
> +VOID
> +EFIAPI
> +DisableAcpiCallback (
> +  IN  EFI_HANDLE                    DispatchHandle,
> +  IN  EFI_SMM_SW_DISPATCH_CONTEXT   *DispatchContext
> +  )
> +{
> +  UINT16 Pm1Cnt;
> +
> +  IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_STS, 0xffff);
> +  IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_EN, mPM1_SaveState16);
> +
> +  IoWrite32(mAcpiBaseAddr + R_PCH_ACPI_GPE0a_STS, 0xffffffff);
> +  IoWrite32(mAcpiBaseAddr + R_PCH_ACPI_GPE0a_EN,
> mGPE_SaveState32);
> +
> +  //
> +  // Disable SCI
> +  //
> +  Pm1Cnt = IoRead16(mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT);
> +  Pm1Cnt &= ~B_PCH_ACPI_PM1_CNT_SCI_EN;
> +  IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT, Pm1Cnt);
> +
> +}
> +
> +/**
> +  When an unknown event happen.
> +
> + @retval None
> +
> +**/
> +VOID
> +DummyTco1Callback (
> +  IN  EFI_HANDLE                              DispatchHandle,
> +  IN  EFI_SMM_ICHN_DISPATCH_CONTEXT           *DispatchContext
> +  )
> +{
> +}
> +
> +UINTN
> +DevicePathSize (
> +  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath
> +  )
> +{
> +  EFI_DEVICE_PATH_PROTOCOL     *Start;
> +
> +  if (DevicePath == NULL) {
> +    return 0;
> +  }
> +
> +  //
> +  // Search for the end of the device path structure
> +  //
> +  Start = DevicePath;
> +  while (!IsDevicePathEnd (DevicePath)) {
> +    DevicePath = NextDevicePathNode (DevicePath);
> +  }
> +
> +  //
> +  // Compute the size and add back in the size of the end device path
> structure
> +  //
> +  return ((UINTN)DevicePath - (UINTN)Start) +
> sizeof(EFI_DEVICE_PATH_PROTOCOL);
> +}
> +
> +/**
> +
> +  @param DispatchHandle   The handle of this callback, obtained when
> registering
> +  @param DispatchContext  The predefined context which contained sleep
> type and phase
> +
> +**/
> +VOID
> +S5SleepWakeOnRtcCallBack (
> +  IN  EFI_HANDLE                    DispatchHandle,
> +  IN  EFI_SMM_SX_DISPATCH_CONTEXT   *DispatchContext
> +  )
> +{
> +  EnableS5WakeOnRtc();
> +}
> +
> +/**
> +
> + @retval 1. Check Alarm interrupt is not set.
> +         2. Clear Alarm interrupt.
> +         2. Set RTC wake up date and time.
> +         2. Enable RTC wake up alarm.
> +         3. Enable ICH PM1 EN Bit 10(RTC_EN)
> +
> +**/
> +VOID
> +EnableS5WakeOnRtc()
> +{
> +  UINT8             CmosData;
> +  UINTN             i;
> +  EFI_STATUS        Status;
> +  UINTN             VarSize;
> +
> +  //
> +  // make sure EFI_SMM_VARIABLE_PROTOCOL is available
> +  //
> +  if (!mSmmVariable) {
> +    return;
> +  }
> +
> +  VarSize = sizeof(SYSTEM_CONFIGURATION);
> +
> +  //
> +  // read the variable into the buffer
> +  //
> +  Status = mSmmVariable->SmmGetVariable(
> +                           L"Setup",
> +                           &gEfiSetupVariableGuid,
> +                           NULL,
> +                           &VarSize,
> +                           &mSystemConfiguration
> +                           );
> +  if (EFI_ERROR(Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
> +    //The setup variable is corrupted
> +    VarSize = sizeof(SYSTEM_CONFIGURATION);
> +    Status = mSmmVariable->SmmGetVariable(
> +              L"SetupRecovery",
> +              &gEfiSetupVariableGuid,
> +              NULL,
> +              &VarSize,
> +              &mSystemConfiguration
> +              );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +  if (!mSystemConfiguration.WakeOnRtcS5) {
> +    return;
> +  }
> +  mWakeupDay =
> HexToBcd((UINT8)mSystemConfiguration.RTCWakeupDate);
> +  mWakeupHour =
> HexToBcd((UINT8)mSystemConfiguration.RTCWakeupTimeHour);
> +  mWakeupMinute =
> HexToBcd((UINT8)mSystemConfiguration.RTCWakeupTimeMinute);
> +  mWakeupSecond =
> HexToBcd((UINT8)mSystemConfiguration.RTCWakeupTimeSecond);
> +
> +  //
> +  // Check RTC alarm interrupt is enabled.  If enabled, someone already
> +  // grabbed RTC alarm.  Just return.
> +  //
> +  IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_B);
> +  if(IoRead8(PCAT_RTC_DATA_REGISTER) & B_RTC_ALARM_INT_ENABLE){
> +    return;
> +  }
> +
> +  //
> +  // Set Date
> +  //
> +  IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_D);
> +  CmosData = IoRead8(PCAT_RTC_DATA_REGISTER);
> +  CmosData &= ~(B_RTC_DATE_ALARM_MASK);
> +  CmosData |= mWakeupDay ;
> +  for(i = 0 ; i < 0xffff ; i++){
> +    IoWrite8(PCAT_RTC_DATA_REGISTER, CmosData);
> +    SmmStall(1);
> +    if(((CmosData = IoRead8(PCAT_RTC_DATA_REGISTER)) &
> B_RTC_DATE_ALARM_MASK)
> +         == mWakeupDay){
> +      break;
> +    }
> +  }
> +
> +  //
> +  // Set Second
> +  //
> +  IoWrite8(PCAT_RTC_ADDRESS_REGISTER,
> RTC_ADDRESS_SECOND_ALARM);
> +  for(i = 0 ; i < 0xffff ; i++){
> +    IoWrite8(PCAT_RTC_DATA_REGISTER, mWakeupSecond);
> +    SmmStall(1);
> +    if(IoRead8(PCAT_RTC_DATA_REGISTER) == mWakeupSecond){
> +      break;
> +    }
> +  }
> +
> +  //
> +  // Set Minute
> +  //
> +  IoWrite8(PCAT_RTC_ADDRESS_REGISTER,
> RTC_ADDRESS_MINUTE_ALARM);
> +  for(i = 0 ; i < 0xffff ; i++){
> +    IoWrite8(PCAT_RTC_DATA_REGISTER, mWakeupMinute);
> +    SmmStall(1);
> +    if(IoRead8(PCAT_RTC_DATA_REGISTER) == mWakeupMinute){
> +      break;
> +    }
> +  }
> +
> +  //
> +  // Set Hour
> +  //
> +  IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_HOUR_ALARM);
> +  for(i = 0 ; i < 0xffff ; i++){
> +    IoWrite8(PCAT_RTC_DATA_REGISTER, mWakeupHour);
> +    SmmStall(1);
> +    if(IoRead8(PCAT_RTC_DATA_REGISTER) == mWakeupHour){
> +      break;
> +    }
> +  }
> +
> +  //
> +  // Wait for UIP to arm RTC alarm
> +  //
> +  IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_A);
> +  while (IoRead8(PCAT_RTC_DATA_REGISTER) & 0x80);
> +
> +  //
> +  // Read RTC register 0C to clear pending RTC interrupts
> +  //
> +  IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_C);
> +  IoRead8(PCAT_RTC_DATA_REGISTER);
> +
> +  //
> +  // Enable RTC Alarm Interrupt
> +  //
> +  IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_B);
> +  IoWrite8(PCAT_RTC_DATA_REGISTER,
> IoRead8(PCAT_RTC_DATA_REGISTER) | B_RTC_ALARM_INT_ENABLE);
> +
> +  //
> +  // Clear ICH RTC Status
> +  //
> +  IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_STS,
> B_PCH_ACPI_PM1_STS_RTC);
> +
> +  //
> +  // Enable ICH RTC event
> +  //
> +  IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_EN,
> +              (UINT16)(IoRead16(mAcpiBaseAddr + R_PCH_ACPI_PM1_EN) |
> B_PCH_ACPI_PM1_EN_RTC));
> +}
> +
> +UINT8
> +HexToBcd(
> +  IN UINT8 HexValue
> +  )
> +{
> +  UINTN   HighByte;
> +  UINTN   LowByte;
> +
> +  HighByte    = (UINTN)HexValue / 10;
> +  LowByte     = (UINTN)HexValue % 10;
> +
> +  return ((UINT8)(LowByte + (HighByte << 4)));
> +}
> +
> +UINT8
> +BcdToHex(
> +  IN UINT8 BcdValue
> +  )
> +{
> +  UINTN   HighByte;
> +  UINTN   LowByte;
> +
> +  HighByte    = (UINTN)((BcdValue >> 4) * 10);
> +  LowByte     = (UINTN)(BcdValue & 0x0F);
> +
> +  return ((UINT8)(LowByte + HighByte));
> +}
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/PlatformSmm.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/PlatformSmm.inf
> new file mode 100644
> index 0000000000..1b7b05d9b3
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/PlatformSmm.inf
> @@ -0,0 +1,93 @@
> +#
> +#
> +# Copyright (c)  1999  - 2018, Intel Corporation. All rights reserved
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +#
> +#
> +#  Module Name:
> +#
> +#   Platform.inf
> +#
> +#  Abstract:
> +#
> +#    Component description file for SMM Platform handler module
> +#
> +#--*/
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = PlatformSmm
> +  FILE_GUID                      = 99C20A37-042A-46e2-80F4-E4027FDBC86F
> +  MODULE_TYPE                    = DXE_SMM_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = InitializePlatformSmm
> +  PI_SPECIFICATION_VERSION       = 0x0001000A
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +[Sources]
> +  S3Save.c
> +  Platform.c
> +
> +[LibraryClasses]
> +  UefiDriverEntryPoint
> +  UefiBootServicesTableLib
> +  DebugLib
> +  IoLib
> +  BaseLib
> +  BaseMemoryLib
> +  DevicePathLib
> +  HobLib
> +  S3BootScriptLib
> +  StallSmmLib
> +  PchPlatformLib
> +
> +[Guids]
> +  gEfiSetupVariableGuid
> +  gDmiDataGuid
> +  gEfiAcpiVariableCompatiblityGuid
> +  gEfiPciLanInfoGuid
> +  gEfiPciLanInfoGuid
> +
> +[FeaturePcd]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode
> +
> +[Protocols]
> +  gEfiSmmBase2ProtocolGuid
> +  gEfiSmmIchnDispatchProtocolGuid
> +  gEfiGlobalNvsAreaProtocolGuid
> +  gEfiSmmSwDispatchProtocolGuid
> +  gEfiSmmPowerButtonDispatchProtocolGuid
> +  gEfiSmmSxDispatchProtocolGuid
> +  gEfiSmmVariableProtocolGuid
> +  gEfiCpuIo2ProtocolGuid
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  IntelFrameworkPkg/IntelFrameworkPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
> +
> +[Pcd.common]
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +
> +[Depex]
> +  gEfiSmmBase2ProtocolGuid                 AND
> +  gEfiSmmAccess2ProtocolGuid               AND
> +  gEfiSmmPowerButtonDispatchProtocolGuid  AND
> +  gEfiSmmSxDispatchProtocolGuid           AND
> +  gEfiSmmIchnDispatchProtocolGuid         AND
> +  gEfiSmmSwDispatchProtocolGuid           AND
> +  gEfiVariableArchProtocolGuid            AND
> +  gEfiVariableWriteArchProtocolGuid       AND
> +  gEfiGlobalNvsAreaProtocolGuid
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/S3Save.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/S3Save.c
> new file mode 100644
> index 0000000000..19089233b2
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/S3Save.c
> @@ -0,0 +1,377 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +    IchS3Save.c
> +
> +Abstract:
> +
> +    SMM S3 handler Driver implementation file
> +
> +Revision History
> +
> +**/
> +#include "SmmPlatform.h"
> +
> +extern  UINT16                          mAcpiBaseAddr;
> +EFI_PHYSICAL_ADDRESS                    mRuntimeScriptTableBase;
> +
> +EFI_STATUS
> +InitRuntimeScriptTable (
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS        Status;
> +  UINT32            VarAttrib;
> +  UINTN             VarSize;
> +  ACPI_VARIABLE_SET_COMPATIBILITY *AcpiVariableBase;
> +
> +  //
> +  // Allocate runtime ACPI script table space. We need it to save some
> +  // settings done by CSM, which runs after normal script table closed
> +  //
> +  Status = gBS->AllocatePages (
> +                  AllocateAnyPages,
> +                  EfiACPIReclaimMemory,
> +                  1,
> +                  &mRuntimeScriptTableBase
> +                  );
> +  if (EFI_ERROR(Status)) {
> +    return EFI_OUT_OF_RESOURCES ;
> +  }
> +
> +  //
> +  // Save runtime script table base into global ACPI variable
> +  //
> +  VarAttrib = EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_RUNTIME_ACCESS
> +              | EFI_VARIABLE_NON_VOLATILE;
> +  VarSize   = sizeof (UINTN);
> +  Status = SystemTable->RuntimeServices->GetVariable (
> +                          ACPI_GLOBAL_VARIABLE,
> +                          &gEfiAcpiVariableCompatiblityGuid,
> +                          &VarAttrib,
> +                          &VarSize,
> +                          &AcpiVariableBase
> +                          );
> +  if (EFI_ERROR(Status)) {
> +    return Status;
> +  }
> +
> +  AcpiVariableBase->RuntimeScriptTableBase = mRuntimeScriptTableBase;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +SaveRuntimeScriptTable (
> +  VOID
> +  )
> +{
> +  SMM_PCI_IO_ADDRESS    PciAddress;
> +  UINT32                Data32;
> +  UINT16                Data16;
> +  UINT8                 Data8;
> +  UINT8                 Mask;
> +  UINTN                 Index;
> +  UINTN                 Offset;
> +  UINT8                 RegTable[] = {
> +
> +	  //
> +    //Bus  ,   Dev,  Func,    DMI
> +	  //
> +      0x00 ,  0x00,  0x00,
> +
> +	  //
> +    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
> +	  //
> +      0x00 ,  0x08,  0x00,  0x00,  0x30,  0x00,  0x00,  0xa0,
> +
> +	  //
> +    //Bus  ,   Dev,  Func,    LPC device
> +	  //
> +      0x00 ,  0x1F,  0x00,
> +
> +	  //
> +    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
> +    //
> +      0x00 ,  0x08,  0x00,  0x07,  0x00,  0x00,  0x90,  0x00,
> +
> +	  //
> +    //Bus  ,   Dev,  Func,    PCIE device
> +	 //
> +      0x00 ,  0x1C,  0x00,
> +
> +	  //
> +    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
> +    //
> +      0xC0 ,  0x83,  0x30,  0x00,  0x00,  0x00,  0x00,  0x00,
> +
> +	  //
> +    //Bus  ,   Dev,  Func,    PCIE device
> +    //
> +	  0x00 ,  0x1C,  0x00,
> +
> +	  //
> +    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
> +    //
> +      0x03 ,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
> +
> +	  //
> +    //Bus  ,   Dev,  Func,    SATA device
> +	  //
> +      0x00 ,  0x13,  0x00,
> +
> +	  //
> +    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
> +    //
> +      0xf4 ,  0xab,  0x27,  0x10,  0xf1,  0x1d,  0x00,  0x40,
> +
> +    //
> +    //Bus  ,   Dev,  Func,    EHCI device
> +    //
> +     0x00 ,  0x1D,  0x00,
> +
> +    //
> +    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
> +    //
> +     0x10 ,  0x88,  0x00,  0x00,  0x00,  0x00,  0x00,  0x80,
> +
> +    //
> +    //Bus  ,   Dev,  Func,    SMBUS device
> +    //
> +     0x00 ,  0x1f,  0x03,
> +
> +    //
> +    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
> +    //
> +      0x10 ,  0x89,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
> +
> +    //
> +    //Bus  ,   Dev,  Func,    SMBUS device
> +    //
> +      0x00 ,  0x1f,  0x03,
> +
> +    //
> +    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
> +    //
> +      0x02 ,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
> +
> +    //
> +    //Bus  ,   Dev,  Func,    VGA bus1
> +    //
> +      0x01 ,  0x00,  0x00,
> +
> +    //
> +    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
> +    //
> +      0x58 ,  0x81,  0x18,  0x01,  0xb0,  0x00,  0x00,  0x00,
> +
> +    //
> +    //Bus  ,   Dev,  Func,    VGA bus1
> +    //
> +      0x01 ,  0x00,  0x00,
> +
> +    //
> +    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
> +    //
> +      0x02 ,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
> +
> +    //
> +    //Bus  ,   Dev,  Func,    VGA bus1 function 1
> +    //
> +      0x01 ,  0x00,  0x01,
> +
> +    //
> +    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
> +    //
> +      0x51 ,  0x80,  0x80,  0x01,  0x00,  0x00,  0x00,  0x00,
> +
> +    //
> +    //Bus  ,   Dev,  Func,    VGA bus1 function 1
> +    //
> +      0x01 ,  0x00,  0x01,
> +
> +    //
> +    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
> +    //
> +      0x02 ,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
> +
> +    //
> +    //Bus  ,   Dev,  Func,    IGD bus0 function 0
> +    //
> +      0x00 ,  0x02,  0x00,
> +
> +    //
> +    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
> +    //
> +      0x42 ,  0x81,  0x00,  0x00,  0x00,  0x00,  0x20,  0x00,
> +
> +    //
> +    //Bus  ,   Dev,  Func,    USB bus0 function 0
> +    //
> +      0x00 ,  0x16,  0x00,
> +
> +    //
> +    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
> +    //
> +      0x32 ,  0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
> +
> +    //
> +    //Bus  ,   Dev,  Func,    HD Audio bus0 function 0
> +    //
> +      0x00 ,  0x1B,  0x00,
> +
> +    //
> +    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
> +    //
> +      0x00 ,  0x00,  0x00,  0x00,  0x00,  0x00,  0x02,  0x00,
> +
> +    //
> +    //0xFF indicates the end of the table
> +    //
> +      0xFF
> + };
> +
> +  //
> +  // These registers have to set in byte order
> +  //
> +  UINT8                 ExtReg[] = { 0x9E, 0x9D };  // SMRAM settings
> +
> +
> +
> +  //
> +  // Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by
> CSM
> +  // and vital to S3 resume. That's why we put save code here
> +  //
> +  PciAddress.Bus      = 0;
> +  PciAddress.Device   = 0;
> +  PciAddress.Function = 0;
> +  PciAddress.ExtendedRegister = 0;
> +
> +  for (Index = 0; Index < 2; Index++) {
> +    //
> +    // Read SRAM setting from Pci(0, 0, 0)
> +    //
> +    PciAddress.Register = ExtReg[Index];
> +    Data8 = MmioRead8 (
> +              MmPciAddress (0,
> +                PciAddress.Bus,
> +                PciAddress.Device,
> +                PciAddress.Function,
> +                PciAddress.Register
> +              )
> +            );
> +
> +    //
> +    // Save latest settings to runtime script table
> +    //
> +    S3BootScriptSavePciCfgWrite(
> +      S3BootScriptWidthUint8,
> +      *(UINT64*)&PciAddress,
> +      1,
> +      &Data8
> +      );
> +  }
> +
> +
> +  //
> +  // Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by
> CSM
> +  // and vital to S3 resume. That's why we put save code here
> +  //
> +  Index = 0;
> +  while (RegTable[Index] != 0xFF) {
> +
> +    PciAddress.Bus      = RegTable[Index++];
> +    PciAddress.Device   = RegTable[Index++];
> +    PciAddress.Function = RegTable[Index++];
> +    PciAddress.Register = 0;
> +    PciAddress.ExtendedRegister = 0;
> +
> +    Data16 = MmioRead16 (
> +              MmPciAddress (0,
> +                PciAddress.Bus,
> +                PciAddress.Device,
> +                PciAddress.Function,
> +                PciAddress.Register
> +              )
> +            );
> +
> +    if (Data16 == 0xFFFF) {
> +      Index+=8;
> +      continue;
> +    }
> +
> +    for (Offset = 0, Mask = 0x01; Offset < 256; Offset+=4, Mask<<=1) {
> +
> +      if (Mask == 0x00) {
> +        Mask = 0x01;
> +      }
> +
> +      if (RegTable[Index + Offset/32] & Mask ) {
> +
> +        PciAddress.Register = (UINT8)Offset;
> +        Data32 = MmioRead32 (MmPciAddress (0, PciAddress.Bus,
> PciAddress.Device, PciAddress.Function, PciAddress.Register));
> +
> +        //
> +        // Save latest settings to runtime script table
> +        //
> +        S3BootScriptSavePciCfgWrite (
> +          S3BootScriptWidthUint32,
> +          *(UINT64*)&PciAddress,
> +          1,
> +          &Data32
> +        );
> +      }
> +    }
> +
> +    Index += 8;
> +
> +  }
> +
> +
> +  //
> +  // Save I/O ports to S3 script table
> +  //
> +
> +  //
> +  // Selftest KBC
> +  //
> +  Data8 = 0xAA;
> +  S3BootScriptSaveIoWrite (
> +    S3BootScriptWidthUint8,
> +    0x64,
> +    (UINTN)1,
> +    &Data8
> +    );
> +
> +  Data32 = IoRead32(mAcpiBaseAddr + R_PCH_SMI_EN);
> +
> +  S3BootScriptSaveIoWrite (
> +      S3BootScriptWidthUint32,
> +      (mAcpiBaseAddr + R_PCH_SMI_EN),
> +      1,
> +      &Data32
> +      );
> +
> +  //
> +  // Save B_ICH_TCO_CNT_LOCK so it will be done on S3 resume path.
> +  //
> +  Data16 = IoRead16(mAcpiBaseAddr + R_PCH_TCO_CNT);
> +
> +  S3BootScriptSaveIoWrite (
> +      S3BootScriptWidthUint16,
> +      mAcpiBaseAddr + R_PCH_TCO_CNT,
> +      1,
> +      &Data16
> +      );
> +
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmPlatform.h
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmPlatform.h
> new file mode 100644
> index 0000000000..8bf2ebafc1
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmPlatform.h
> @@ -0,0 +1,240 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  SmmPlatform.h
> +
> +Abstract:
> +
> +  Header file for
> +
> +++*/
> +
> +#ifndef _PLATFORM_H
> +#define _PLATFORM_H
> +
> +#include <PiSmm.h>
> +
> +
> +
> +#include <Protocol/SmmBase.h>
> +#include <Protocol/FirmwareVolume.h>
> +#include <Protocol/SmmPowerButtonDispatch.h>
> +#include <Protocol/SmmSxDispatch.h>
> +#include <Protocol/SmmSwDispatch.h>
> +#include <Protocol/SmmSwDispatch2.h>
> +#include <Protocol/SmmIchnDispatch.h>
> +#include <Protocol/SmmAccess.h>
> +#include <Protocol/SmmVariable.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +#include <Protocol/LoadedImage.h>
> +#include "Protocol/GlobalNvsArea.h"
> +#include <Guid/AcpiVariableCompatibility.h>
> +#include <Guid/SetupVariable.h>
> +#include <Guid/EfiVpdData.h>
> +#include <Guid/PciLanInfo.h>
> +#include <IndustryStandard/Pci22.h>
> +
> +#include "PchAccess.h"
> +#include "PlatformBaseAddresses.h"
> +
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/S3BootScriptLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PchPlatformLib.h>
> +#include <Library/StallSmmLib.h>
> +
> +
> +
> +typedef struct {
> +  UINT8     Register;
> +  UINT8     Function;
> +  UINT8     Device;
> +  UINT8     Bus;
> +  UINT32    ExtendedRegister;
> +} SMM_PCI_IO_ADDRESS;
> +
> +typedef struct {
> +  CHAR8     BoardAaNumber[7];
> +  UINTN     BoardFabNumber;
> +} BOARD_AA_NUMBER_DECODE;
> +
> +//
> +// BugBug -- Need to get these two values from acpi.h, but right now, they
> are
> +//           declared in platform-specific variants of this file, so no easy
> +//           way to pick-up the include file and work across platforms.
> +//           Need these definitions to go into a file like common\acpi.h.
> +//
> +#define ACPI_ENABLE                 0xA0
> +#define ACPI_DISABLE                0xA1
> +
> +#define APM_12_FUNCS                  0x50
> +#define SMI_SET_SMMVARIABLE_PROTOCOL  0x51  // this is used in
> Cpu\Pentium\Smm\Base\SmmBase.c
> +
> +#define SMI_CMD_GET_MSEG_STATUS     0x70
> +#define SMI_CMD_UPDATE_MSEG_SIZE    0x71
> +#define SMI_CMD_LOAD_STM            0x72
> +#define SMI_CMD_UNLOAD_STM          0x73
> +#define SMI_CMD_GET_SMRAM_RANGES    0x74
> +
> +
> +#define PCAT_RTC_ADDRESS_REGISTER   0x74
> +#define PCAT_RTC_DATA_REGISTER      0x75
> +
> +#define RTC_ADDRESS_SECOND          0x00
> +#define RTC_ADDRESS_SECOND_ALARM    0x01
> +#define RTC_ADDRESS_MINUTE          0x02
> +#define RTC_ADDRESS_MINUTE_ALARM    0x03
> +#define RTC_ADDRESS_HOUR            0x04
> +#define RTC_ADDRESS_HOUR_ALARM      0x05
> +
> +#define RTC_ADDRESS_REGISTER_A      0x0A
> +#define RTC_ADDRESS_REGISTER_B      0x0B
> +#define RTC_ADDRESS_REGISTER_C      0x0C
> +#define RTC_ADDRESS_REGISTER_D      0x0D
> +
> +#define B_RTC_ALARM_INT_ENABLE      0x20
> +#define B_RTC_ALARM_INT_STATUS      0x20
> +
> +#define B_RTC_DATE_ALARM_MASK       0x3F
> +
> +#define PCAT_CMOS_2_ADDRESS_REGISTER  0x72
> +#define PCAT_CMOS_2_DATA_REGISTER     0x73
> +
> +#define EC_C_PORT                     0x66
> +#define SMC_SMI_DISABLE               0xBC
> +#define SMC_ENABLE_ACPI_MODE          0xAA  // Enable ACPI mode
> +
> +#define IO_MISC 156
> +
> +
> +#define MAXIMUM_NUMBER_OF_PSTATES           12
> +#define  ICH_SMM_DATA_PORT                  0xB3
> +
> +#define EFI_IA32_PMG_CST_CONFIG               0x000000E2
> +#define   B_EFI_CST_CONTROL_LOCK                BIT15
> +#define   B_EFI_IO_MWAIT_REDIRECTION_ENABLE     BIT10
> +#define EFI_IA32_PMG_IO_CAPTURE_ADDR          0x000000E4
> +
> +extern EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *mPciRootBridgeIo;
> +
> +//
> +// Callback function prototypes
> +//
> +VOID
> +EFIAPI
> +PowerButtonCallback (
> +  IN  EFI_HANDLE                              DispatchHandle,
> +  IN  EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT   *DispatchContext
> +  );
> +
> +VOID
> +S5SleepWakeOnLanCallBack (
> +  IN  EFI_HANDLE                    DispatchHandle,
> +  IN  EFI_SMM_SX_DISPATCH_CONTEXT   *DispatchContext
> +  );
> +
> +VOID
> +EFIAPI
> +S5SleepAcLossCallBack (
> +  IN  EFI_HANDLE                    DispatchHandle,
> +  IN  EFI_SMM_SX_DISPATCH_CONTEXT   *DispatchContext
> +  );
> +
> +
> +VOID
> +EFIAPI
> +S4S5CallBack (
> +  IN  EFI_HANDLE                    DispatchHandle,
> +  IN  EFI_SMM_SX_DISPATCH_CONTEXT   *DispatchContext
> +  );
> +
> +VOID
> +EFIAPI
> +EnableAcpiCallback (
> +  IN  EFI_HANDLE                    DispatchHandle,
> +  IN  EFI_SMM_SW_DISPATCH_CONTEXT   *DispatchContext
> +  );
> +
> +VOID
> +EFIAPI
> +DisableAcpiCallback (
> +  IN  EFI_HANDLE                    DispatchHandle,
> +  IN  EFI_SMM_SW_DISPATCH_CONTEXT   *DispatchContext
> +  );
> +
> +VOID
> +EFIAPI
> +SmmReadyToBootCallback (
> +  IN  EFI_HANDLE                    DispatchHandle,
> +  IN  EFI_SMM_SW_DISPATCH_CONTEXT   *DispatchContext
> +  );
> +
> +VOID
> +DummyTco1Callback (
> +  IN  EFI_HANDLE                              DispatchHandle,
> +  IN  EFI_SMM_ICHN_DISPATCH_CONTEXT           *DispatchContext
> +  );
> +
> +
> +VOID
> +PerrSerrCallback (
> +  IN  EFI_HANDLE                              DispatchHandle,
> +  IN  EFI_SMM_ICHN_DISPATCH_CONTEXT           *DispatchContext
> +  );
> +
> +VOID
> +RiCallback (
> +  IN  EFI_HANDLE                              DispatchHandle,
> +  IN  EFI_SMM_ICHN_DISPATCH_CONTEXT           *DispatchContext
> +  );
> +
> +
> +VOID
> +SetAfterG3On (
> +  BOOLEAN Enable
> +  );
> +
> +VOID
> +TurnOffVregUsb (
> +  );
> +
> +VOID
> +PStateSupportCallback (
> +  IN  EFI_HANDLE                              DispatchHandle,
> +  IN  EFI_SMM_SW_DISPATCH_CONTEXT             *DispatchContext
> +  );
> +
> +VOID
> +PStateTransitionCallback (
> +  IN  EFI_HANDLE                              DispatchHandle,
> +  IN  EFI_SMM_SW_DISPATCH_CONTEXT             *DispatchContext
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +SxSleepEntryCallBack (
> +  IN  EFI_HANDLE                    DispatchHandle,
> +  IN  EFI_SMM_SX_DISPATCH_CONTEXT   *DispatchContext
> +  );
> +
> +EFI_STATUS
> +SaveRuntimeScriptTable (
> +  VOID
> +  );
> +
> +
> +#endif
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.c
> new file mode 100644
> index 0000000000..26599620ba
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.c
> @@ -0,0 +1,252 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +
> +    SmmScriptSave.c
> +
> +Abstract:
> +
> +    ScriptTableSave module at run time
> +
> +--*/
> +
> +#include "SmmScriptSave.h"
> +
> +//
> +// internal functions
> +//
> +
> +EFI_STATUS
> +BootScriptIoWrite  (
> +  IN EFI_SMM_SCRIPT_TABLE     *ScriptTable,
> +  IN VA_LIST                  Marker
> +  );
> +
> +EFI_STATUS
> +BootScriptPciCfgWrite  (
> +  IN EFI_SMM_SCRIPT_TABLE     *ScriptTable,
> +  IN VA_LIST                  Marker
> +  );
> +
> +VOID
> +SmmCopyMem (
> +  IN  UINT8    *Destination,
> +  IN  UINT8    *Source,
> +  IN  UINTN    ByteCount
> +  );
> +
> +//
> +// Function implementations
> +//
> +EFI_STATUS
> +SmmBootScriptWrite (
> +  IN OUT EFI_SMM_SCRIPT_TABLE    *ScriptTable,
> +  IN UINTN                       Type,
> +  IN UINT16                      OpCode,
> +  ...
> +  )
> +{
> +  EFI_STATUS    Status;
> +  VA_LIST       Marker;
> +
> +  if (ScriptTable == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Build script according to opcode
> +  //
> +  switch ( OpCode ) {
> +
> +    case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE:
> +      VA_START(Marker, OpCode);
> +      Status = BootScriptIoWrite (ScriptTable, Marker);
> +      VA_END(Marker);
> +      break;
> +
> +    case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE:
> +      VA_START(Marker, OpCode);
> +      Status = BootScriptPciCfgWrite(ScriptTable, Marker);
> +      VA_END(Marker);
> +      break;
> +
> +    default:
> +      Status = EFI_SUCCESS;
> +      break;
> +  }
> +
> +  return Status;
> +}
> +
> +
> +EFI_STATUS
> +SmmBootScriptCreateTable (
> +  IN OUT EFI_SMM_SCRIPT_TABLE    *ScriptTable,
> +  IN UINTN                       Type
> +  )
> +{
> +  BOOT_SCRIPT_POINTERS          Script;
> +  UINT8                         *Buffer;
> +
> +  if (ScriptTable == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Buffer = (UINT8*) ((UINTN)(*ScriptTable));
> +
> +  //
> +  // Fill Table Header
> +  //
> +  Script.Raw = Buffer;
> +  Script.TableInfo->OpCode      = EFI_BOOT_SCRIPT_TABLE_OPCODE;
> +  Script.TableInfo->Length      = sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER);
> +  Script.TableInfo->TableLength =
> sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER);
> +
> +  //
> +  // Update current table pointer
> +  //
> +  *ScriptTable = *ScriptTable + sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER);
> +  return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +SmmBootScriptCloseTable (
> +  IN EFI_SMM_SCRIPT_TABLE        ScriptTableBase,
> +  IN EFI_SMM_SCRIPT_TABLE        ScriptTablePtr,
> +  IN UINTN                       Type
> +  )
> +{
> +  BOOT_SCRIPT_POINTERS    Script;
> +
> +  //
> +  // Add final "termination" node to script table
> +  //
> +  Script.Raw               = (UINT8*) ((UINTN)ScriptTablePtr);
> +  Script.Terminate->OpCode = EFI_BOOT_SCRIPT_TERMINATE_OPCODE;
> +  Script.Terminate->Length = sizeof (EFI_BOOT_SCRIPT_TERMINATE);
> +  ScriptTablePtr          += sizeof (EFI_BOOT_SCRIPT_TERMINATE);
> +
> +
> +  //
> +  // Update Table Header
> +  //
> +  Script.Raw                    = (UINT8*) ((UINTN)ScriptTableBase);
> +  Script.TableInfo->OpCode      = EFI_BOOT_SCRIPT_TABLE_OPCODE;
> +  Script.TableInfo->Length      = sizeof (EFI_BOOT_SCRIPT_TABLE_HEADER);
> +  Script.TableInfo->TableLength = (UINT32)(ScriptTablePtr - ScriptTableBase);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +BootScriptIoWrite  (
> +  IN EFI_SMM_SCRIPT_TABLE     *ScriptTable,
> +  IN VA_LIST                  Marker
> +  )
> +{
> +  BOOT_SCRIPT_POINTERS    Script;
> +  EFI_BOOT_SCRIPT_WIDTH   Width;
> +  UINTN                   Address;
> +  UINTN                   Count;
> +  UINT8                   *Buffer;
> +  UINTN                   NodeLength;
> +  UINT8                   WidthInByte;
> +
> +  Width     = VA_ARG(Marker, EFI_BOOT_SCRIPT_WIDTH);
> +  Address   = VA_ARG(Marker, UINTN);
> +  Count     = VA_ARG(Marker, UINTN);
> +  Buffer    = VA_ARG(Marker, UINT8*);
> +
> +  WidthInByte = (UINT8)(0x01 << (Width & 0x03));
> +  Script.Raw  = (UINT8*) ((UINTN)(*ScriptTable));
> +  NodeLength  = sizeof (EFI_BOOT_SCRIPT_IO_WRITE) + (WidthInByte *
> Count);
> +
> +  //
> +  // Build script data
> +  //
> +  Script.IoWrite->OpCode  = EFI_BOOT_SCRIPT_IO_WRITE_OPCODE;
> +  Script.IoWrite->Length  = (UINT8)(NodeLength);
> +  Script.IoWrite->Width   = Width;
> +  Script.IoWrite->Address = Address;
> +  Script.IoWrite->Count   = (UINT32)Count;
> +  SmmCopyMem (
> +    (UINT8*)(Script.Raw + sizeof (EFI_BOOT_SCRIPT_IO_WRITE)),
> +    Buffer,
> +    WidthInByte * Count
> +    );
> +
> +  //
> +  // Update Script table pointer
> +  //
> +  *ScriptTable = *ScriptTable + NodeLength;
> +  return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +BootScriptPciCfgWrite  (
> +  IN EFI_SMM_SCRIPT_TABLE        *ScriptTable,
> +  IN VA_LIST                     Marker
> +  )
> +{
> +  BOOT_SCRIPT_POINTERS    Script;
> +  EFI_BOOT_SCRIPT_WIDTH   Width;
> +  UINT64                  Address;
> +  UINTN                   Count;
> +  UINT8                   *Buffer;
> +  UINTN                   NodeLength;
> +  UINT8                   WidthInByte;
> +
> +  Width     = VA_ARG(Marker, EFI_BOOT_SCRIPT_WIDTH);
> +  Address   = VA_ARG(Marker, UINT64);
> +  Count     = VA_ARG(Marker, UINTN);
> +  Buffer    = VA_ARG(Marker, UINT8*);
> +
> +  WidthInByte = (UINT8)(0x01 << (Width & 0x03));
> +  Script.Raw  = (UINT8*) ((UINTN)(*ScriptTable));
> +  NodeLength  = sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE) +
> (WidthInByte * Count);
> +
> +  //
> +  // Build script data
> +  //
> +  Script.PciWrite->OpCode  =
> EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE;
> +  Script.PciWrite->Length  = (UINT8)(NodeLength);
> +  Script.PciWrite->Width   = Width;
> +  Script.PciWrite->Address = Address;
> +  Script.PciWrite->Count   = (UINT32)Count;
> +  SmmCopyMem (
> +    (UINT8*)(Script.Raw + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE)),
> +    Buffer,
> +    WidthInByte * Count
> +    );
> +
> +  //
> +  // Update Script table pointer
> +  //
> +  *ScriptTable = *ScriptTable + NodeLength;
> +  return EFI_SUCCESS;
> +}
> +
> +VOID
> +SmmCopyMem (
> +  IN  UINT8    *Destination,
> +  IN  UINT8    *Source,
> +  IN  UINTN    ByteCount
> +  )
> +{
> +  UINTN   Index;
> +
> +  for (Index = 0; Index < ByteCount; Index++, Destination++, Source++) {
> +    *Destination = *Source;
> +  }
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.h
> b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.h
> new file mode 100644
> index 0000000000..d3eca8cdc0
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.h
> @@ -0,0 +1,50 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +    SmmScriptSave.h
> +
> +Abstract:
> +
> +  This is an implementation of the BootScript at run time.
> +
> +--*/
> +
> +#ifndef _RUNTIME_SCRIPT_SAVE_H
> +#define _RUNTIME_SCRIPT_SAVE_H
> +
> +#include "Efi.h"
> +#include "EfiBootScript.h"
> +
> +
> +typedef EFI_PHYSICAL_ADDRESS     EFI_SMM_SCRIPT_TABLE;
> +
> +EFI_STATUS
> +SmmBootScriptCreateTable (
> +  IN OUT EFI_SMM_SCRIPT_TABLE    *ScriptTable,
> +  IN UINTN                       Type
> +  );
> +
> +EFI_STATUS
> +SmmBootScriptWrite (
> +  IN OUT EFI_SMM_SCRIPT_TABLE    *ScriptTable,
> +  IN UINTN                       Type,
> +  IN UINT16                      OpCode,
> +  ...
> +  );
> +
> +EFI_STATUS
> +SmmBootScriptCloseTable (
> +  IN EFI_SMM_SCRIPT_TABLE        ScriptTableBase,
> +  IN EFI_SMM_SCRIPT_TABLE        ScriptTablePtr,
> +  IN UINTN                       Type
> +  );
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c
> b/Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c
> new file mode 100644
> index 0000000000..3583e324e6
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c
> @@ -0,0 +1,148 @@
> +/**
> +  Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +Module Name:
> +
> +
> +  PpmPolicy.c
> +
> +Abstract:
> +
> +  This file is a wrapper for Intel PPM Platform Policy driver.
> +  Get Setup Value to initilize Intel PPM DXE Platform Policy.
> +
> +--*/
> +#include "PpmPolicy.h"
> +#include <Protocol/MpService.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/CpuIA32.h>
> +
> +#include <PchRegs.h>
> +#include <Library/PchPlatformLib.h>
> +
> +#define EFI_CPUID_FAMILY                      0x0F00
> +#define EFI_CPUID_MODEL                       0x00F0
> +#define EFI_CPUID_STEPPING                    0x000F
> +
> +EFI_STATUS
> +EFIAPI
> +PpmPolicyEntry(
> +  IN EFI_HANDLE ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +)
> +{
> +  EFI_BOOT_SERVICES        *pBS;
> +  EFI_MP_SERVICES_PROTOCOL *MpService;
> +  EFI_CPUID_REGISTER        Cpuid01 = { 0, 0, 0, 0};
> +  EFI_HANDLE                Handle;
> +  EFI_STATUS                Status;
> +  UINTN                     CpuCount;
> +  UINTN                     CpuEnabledCount;
> +  UINT8                     CPUMobileFeature;
> +
> +  PCH_STEPPING              Stepping;
> +
> +  pBS = SystemTable->BootServices;
> +
> +  //
> +  // Set PPM policy structure to known value
> +  //
> +  pBS->SetMem (&mDxePlatformPpmPolicy,
> sizeof(PPM_PLATFORM_POLICY_PROTOCOL), 0);
> +
> +  //
> +  // Find the MpService Protocol
> +  //
> +  Status = pBS->LocateProtocol (&gEfiMpServiceProtocolGuid,
> +                                NULL,
> +                                (void **)&MpService
> +                               );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Get processor count from MP service.
> +  //
> +  Status = MpService->GetNumberOfProcessors (MpService, &CpuCount,
> &CpuEnabledCount);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Store the CPUID for use by SETUP items.
> +  //
> +  AsmCpuid (EFI_CPUID_VERSION_INFO, &Cpuid01.RegEax,
> &Cpuid01.RegEbx, &Cpuid01.RegEcx, &Cpuid01.RegEdx);
> +
> +  mDxePlatformPpmPolicy.Revision                       =
> PPM_PLATFORM_POLICY_PROTOCOL_REVISION_4;
> +
> +  //Read CPU Mobile feature from PLATFORM_ID_MSR MSR(0x17)
> NOTFB_I_AM_NOT_MOBILE_FUSE_CLIAMC00H Bit 28
> +  //Bit Description: { Disables Mobile features 0 = I am NOT a mobile part 1 =
> I am a mobile part (default)"}
> +  CPUMobileFeature = ((RShiftU64
> (AsmReadMsr64(EFI_MSR_IA32_PLATFORM_ID), 28)) & 0x1);
> +
> +  if (!EFI_ERROR(Status)) {
> +    if (CPUMobileFeature == 1){//CPU mobile feature
> +      mDxePlatformPpmPolicy.FunctionEnables.EnableGv       =
> ICH_DEVICE_ENABLE;
> +      mDxePlatformPpmPolicy.FunctionEnables.EnableCx       =
> ICH_DEVICE_ENABLE;
> +      mDxePlatformPpmPolicy.FunctionEnables.EnableCxe      =
> ICH_DEVICE_DISABLE;
> +      mDxePlatformPpmPolicy.FunctionEnables.EnableTm       =
> ICH_DEVICE_ENABLE;
> +      //MaxC7
> +      mDxePlatformPpmPolicy.FunctionEnables.EnableC7       =
> ICH_DEVICE_ENABLE;
> +      mDxePlatformPpmPolicy.FunctionEnables.EnableC6       =
> ICH_DEVICE_ENABLE;
> +      mDxePlatformPpmPolicy.FunctionEnables.EnableC4       =
> ICH_DEVICE_ENABLE;
> +
> +
> +    }else{//CPU desktop feature
> +       mDxePlatformPpmPolicy.FunctionEnables.EnableGv       =
> ICH_DEVICE_DISABLE;
> +       mDxePlatformPpmPolicy.FunctionEnables.EnableCx       =
> ICH_DEVICE_DISABLE;
> +       mDxePlatformPpmPolicy.FunctionEnables.EnableCxe      =
> ICH_DEVICE_DISABLE;
> +       mDxePlatformPpmPolicy.FunctionEnables.EnableTm       =
> ICH_DEVICE_DISABLE;
> +       mDxePlatformPpmPolicy.FunctionEnables.EnableC4       =
> ICH_DEVICE_DISABLE;
> +       mDxePlatformPpmPolicy.FunctionEnables.EnableC6       =
> ICH_DEVICE_DISABLE;
> +       mDxePlatformPpmPolicy.FunctionEnables.EnableC7       =
> ICH_DEVICE_DISABLE;
> +    }
> +
> +
> +    mDxePlatformPpmPolicy.FunctionEnables.EnableProcHot  =
> ICH_DEVICE_ENABLE;
> +    mDxePlatformPpmPolicy.FunctionEnables.TStatesEnable  =
> ICH_DEVICE_ENABLE;
> +
> +
> +    Stepping = PchStepping();
> +    if (Stepping < PchB3) {
> +      // If SoC is B0~B2 Stepping, disable the Turbo
> +      mDxePlatformPpmPolicy.FunctionEnables.EnableTurboMode=
> ICH_DEVICE_DISABLE;
> +    } else {
> +      mDxePlatformPpmPolicy.FunctionEnables.EnableTurboMode=
> ICH_DEVICE_ENABLE;
> +    }
> +
> +    mDxePlatformPpmPolicy.FunctionEnables.EnableTm      =
> ICH_DEVICE_ENABLE;
> +
> +    mDxePlatformPpmPolicy.FunctionEnables.EnableCMP      =
> ICH_DEVICE_ENABLE;
> +
> +  } else {
> +    mDxePlatformPpmPolicy.FunctionEnables.EnableGv       =
> ICH_DEVICE_ENABLE;
> +    mDxePlatformPpmPolicy.FunctionEnables.EnableCx       =
> ICH_DEVICE_ENABLE;
> +    mDxePlatformPpmPolicy.FunctionEnables.EnableCxe      =
> ICH_DEVICE_ENABLE;
> +    mDxePlatformPpmPolicy.FunctionEnables.EnableTm      =
> ICH_DEVICE_ENABLE;
> +    mDxePlatformPpmPolicy.FunctionEnables.EnableProcHot  =
> ICH_DEVICE_ENABLE;
> +    mDxePlatformPpmPolicy.FunctionEnables.EnableCMP       =
> ICH_DEVICE_DISABLE;
> +    mDxePlatformPpmPolicy.FunctionEnables.TStatesEnable  =
> ICH_DEVICE_ENABLE;
> +    mDxePlatformPpmPolicy.FunctionEnables.EnableTurboMode=
> ICH_DEVICE_ENABLE;
> +    mDxePlatformPpmPolicy.FunctionEnables.EnableC4       =
> ICH_DEVICE_ENABLE;
> +    mDxePlatformPpmPolicy.FunctionEnables.EnableC6       =
> ICH_DEVICE_ENABLE;
> +  }
> +
> +
> +
> +  mDxePlatformPpmPolicy.S3RestoreMsrSwSmiNumber                       =
> S3_RESTORE_MSR_SW_SMI;
> +
> +  Handle = NULL;
> +  Status = pBS->InstallMultipleProtocolInterfaces (
> +                                                  &Handle,
> +                                                  &gPpmPlatformPolicyProtocolGuid,
> +                                                  &mDxePlatformPpmPolicy,
> +                                                  NULL
> +                                                  );
> +
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h
> b/Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h
> new file mode 100644
> index 0000000000..346bb18724
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h
> @@ -0,0 +1,36 @@
> +/**
> +  Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  PpmPolicy.h
> +
> +Abstract:
> +
> +  Header file for the PpmPolicyInitDxe Driver.
> +
> +--*/
> +#include <PiDxe.h>
> +//
> +// Driver Produced Protocol Prototypes
> +//
> +#include <Protocol/PpmPlatformPolicy.h>
> +
> +PPM_PLATFORM_POLICY_PROTOCOL    mDxePlatformPpmPolicy;
> +
> +// Function Definition
> +#define  ICH_DEVICE_ENABLE       1
> +#define  ICH_DEVICE_DISABLE      0
> +
> +#define POWER_STATE_SWITCH_SMI                       43
> +#define ENABLE_C_STATE_IO_REDIRECTION_SMI            70
> +#define DISABLE_C_STATE_IO_REDIRECTION_SMI           71
> +#define ENABLE_SMI_C_STATE_COORDINATION_SMI          72
> +#define DISABLE_SMI_C_STATE_COORDINATION_SMI         73
> +#define ENABLE_P_STATE_HARDWARE_COORDINATION_SMI     74
> +#define DISABLE_P_STATE_HARDWARE_COORDINATION_SMI    75
> +#define S3_RESTORE_MSR_SW_SMI                        48
> +#define ENABLE_C6_RESIDENCY_SMI                      76
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf
> new file mode 100644
> index 0000000000..331076a2d4
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf
> @@ -0,0 +1,49 @@
> +#/*++
> +#
> +#  Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +#  Module Name:
> +#
> +#   PpmPolicy.inf
> +#
> +#  Abstract:
> +#
> +#    Implement platform power management policy
> +#
> +#--*/
> +
> +[defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = PpmPolicy
> +  FILE_GUID                      = 2EE72E7C-FB9E-4318-B888-33A315C7A91D
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = PpmPolicyEntry
> +
> +[Sources]
> +  PpmPolicy.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  Vlv2SocBinPkg/Vlv2SocBinPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +
> +[LibraryClasses]
> +  DebugLib
> +  BaseLib
> +  PchPlatformLib
> +  UefiDriverEntryPoint
> +
> +[Protocols]
> +  gEfiMpServiceProtocolGuid
> +  gPpmPlatformPolicyProtocolGuid
> +
> +[Guids]
> +  gEfiSetupVariableGuid
> +
> +[Depex]
> +  gEfiMpServiceProtocolGuid
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Readme.md
> b/Platform/Intel/Vlv2TbltDevicePkg/Readme.md
> new file mode 100644
> index 0000000000..cbbb465b69
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Readme.md
> @@ -0,0 +1,233 @@
> +# **EDK II firmware for Minnowboard Max/Turbot which is based on Intel
> Valleyview2 SoC (Byatrail platform)**
> +
> +----------
> +# Windows Pre-requisites
> +
> +* GIT client: Available from https://git-scm.com/downloads
> +
> +* Microsoft Visual Studio.
> +  - Visual Studio 2015 recommended and is used in the examples below.
> Visual Studio 2013 is also supported.
> +
> +* WINDDK
> +  - Download Microsoft Windows Driver Development Kit 3790.1830 and
> install it to C:\WINDDK\3790.1830.
> +
> +* Python 3
> +  - https://www.python.org/downloads/
> +
> +* Install iASL
> +   - Install the iasl compiler by downloading iasl-win-20160527.zip from the
> following
> +   location: "https://acpica.org/downloads/" and place the unzipped
> +   content ("iasl.exe") into the directory "C:\ASL" on your local hard drive
> +   (create the folder "C:\ASL" if it does not exist).
> +
> +* Install the NASM* assembly language compiler
> +   - Download NASM* 2.12.02 binaries from
> +   http://www.nasm.us/pub/nasm/releasebuilds/2.12.02/win64/nasm-
> 2.12.02-win64.zip and place the
> +   unzipped content ("nasm.exe") into the directory "C:\NASM" on your
> local hard drive
> +   (create the folder "C:\NASM" if it does not exist). Add the path
> "C:\NASM\" to system environment variable **NASM_PREFIX**.
> +
> +* Install Openssl
> +   - Download a pre-compiled Openssl Windows binary from
> +   https://wiki.openssl.org/index.php/Binaries. Search for a Windows binary
> in the list
> +   of "Third Party OpenSSL Related Binary Distributions". Go to the third
> party site to
> +   download the latest version. Download and extract to C:\Openssl, add the
> path of openssl.exe
> +   ("C:\openssl") to system environment variable **OPENSSL_PATH**.
> +
> +# Download and Build MinnowMax using Windows/Visual Studio
> +
> +Run the script below from an empty directory.  The script clones the EDK II
> +repository from GitHub and downloads and unzips the binary support files
> for the
> +MinnowBoard MAX.  It then sets up the environment for EDK II builds and
> builds
> +the MinnowBoard MAX firmware and generates UEFI Capsules that can be
> used to
> +update the MinnowBoard MAX firmware and three sample devices.
> +
> +```
> +git clone --recurse-submodules https://github.com/tianocore/edk2.git
> +
> +powershell "& {[Net.ServicePointManager]::SecurityProtocol =
> [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest -Uri
> "https://indy.fulgan.com/SSL/openssl-1.0.2r-x64_86-win64.zip -OutFile
> openssl-1.0.2r-x64_86-win64.zip"}"
> +powershell Expand-Archive openssl-1.0.2r-x64_86-win64.zip
> +
> +powershell "& {[Net.ServicePointManager]::SecurityProtocol =
> [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest -Uri
> "https://firmware.intel.com/sites/default/files/MinnowBoardMax-
> Development190216.zip -OutFile MinnowBoardMax-
> Development190216.zip"}"
> +powershell Expand-Archive MinnowBoardMax-Development190216.zip
> +sleep 1
> +rename MinnowBoardMax-Development190216 Vlv2Binaries
> +cd Vlv2Binaries
> +powershell Expand-Archive Vlv2SocBinPkg.zip .
> +sleep 1
> +cd ..
> +
> +powershell "& {[Net.ServicePointManager]::SecurityProtocol =
> [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest -Uri
> "https://www.nasm.us/pub/nasm/releasebuilds/2.13.03/win64/nasm-
> 2.13.03-win64.zip -OutFile nasm-2.13.03-win64.zip"}"
> +powershell Expand-Archive nasm-2.13.03-win64.zip .
> +
> +mkdir Conf
> +
> +set WORKSPACE=%CD%
> +set EDK_TOOLS_PATH=%WORKSPACE%\edk2\BaseTools
> +set EDK_TOOLS_BIN=%EDK_TOOLS_PATH%\BinWrappers\WindowsLike
> +set PACKAGES_PATH=%WORKSPACE%\edk2;%WORKSPACE%\Vlv2Binaries
> +path=%path%;%EDK_TOOLS_PATH%\Bin\Win32;%WORKSPACE%\openssl-
> 1.0.2r-x64_86-win64
> +set NASM_PREFIX=%WORKSPACE%\nasm-2.13.03\
> +
> +cd %WORKSPACE%\edk2
> +
> +call edkSetup.bat Rebuild
> +
> +cd Vlv2TbltDevicePkg
> +
> +Build_IFWI.bat /m /y MNW2 Debug
> +```
> +
> +Once all the code and tools are downloaded and installed, only the
> following
> +commands are required to setup the environment.  Run these from the
> same
> +directory used to install the source and binaries.
> +
> +```
> +set WORKSPACE=%CD%
> +set EDK_TOOLS_PATH=%WORKSPACE%\edk2\BaseTools
> +set EDK_TOOLS_BIN=%EDK_TOOLS_PATH%\BinWrappers\WindowsLike
> +set PACKAGES_PATH=%WORKSPACE%\edk2;%WORKSPACE%\Vlv2Binaries
> +path=%path%;%EDK_TOOLS_PATH%\Bin\Win32;%WORKSPACE%\openssl-
> 1.0.2r-x64_86-win64
> +set NASM_PREFIX=%WORKSPACE%\nasm-2.13.03\
> +
> +cd %WORKSPACE%\edk2
> +
> +call edkSetup.bat Rebuild
> +```
> +
> +Once the environment is setup, the MinnowBoard MAX firmware and
> capsules can be
> +rebuilt using the following commands.
> +
> +* Build Debug Image
> +
> +```
> +cd Vlv2TbltDevicePkg
> +Build_IFWI.bat /m /y MNW2 Debug
> +```
> +
> +* Build Release Image
> +
> +```
> +cd Vlv2TbltDevicePkg
> +Build_IFWI.bat /m /y MNW2 Release
> +```
> +
> +The generated firmware image is the newest `.bin` file in
> `edk2/Vlv2TbltDevicePkg/Stitch`.
> +The file is in the form `MNW2MAX1.X64.0084.D01.<DATE>.bin`.
> +
> +The CapsuleApp and generated UEFI Capsules are in
> `Build/Vlv2TbltDevicePkg/Capsules`
> +
> +# Linux Pre-requisites
> +
> +* The tool GenBiosId has a dependency on libc.so.6.  Make sure it is
> installed.
> +  Here are a few example installation commands:
> +
> +    sudo dnf install libc.so.6
> +
> +    apt-get install libc:i386
> +
> +# Download and Build MinnowMax using Linux/GCC
> +
> +Run the script below from an empty directory.  The script clones the EDK II
> +repository from GitHub and downloads and unzips the binary support files
> for the
> +MinnowBoard MAX.  It then sets up the environment for EDK II builds and
> builds
> +the MinnowBoard MAX firmware and generates UEFI Capsules that can be
> used to
> +update the MinnowBoard MAX firmware and three sample devices.
> +
> +```
> +git clone --recurse-submodules https://github.com/tianocore/edk2.git
> +
> +mkdir Vlv2Binaries
> +cd Vlv2Binaries
> +wget https://firmware.intel.com/sites/default/files/MinnowBoardMax-
> Development190216.zip
> +unzip MinnowBoardMax-Development190216.zip
> +unzip Vlv2SocBinPkg.zip
> +
> +cd ..
> +mkdir Conf
> +
> +export WORKSPACE=$PWD/edk2
> +export PACKAGES_PATH=$PWD/Vlv2Binaries
> +export EDK_TOOLS_PATH=$WORKSPACE/BaseTools
> +
> +cd edk2
> +cd Vlv2TbltDevicePkg
> +. Build_IFWI.sh MNW2 Debug
> +```
> +
> +Once all the code is downloaded and installed, only the following
> commands are
> +required to setup the environment.  Run these from the same directory
> used to
> +install the source and binaries.
> +
> +```
> +export WORKSPACE=$PWD/edk2
> +export PACKAGES_PATH=$PWD/Vlv2Binaries
> +export EDK_TOOLS_PATH=$WORKSPACE/BaseTools
> +
> +cd edk2
> +cd Vlv2TbltDevicePkg
> +```
> +
> +Once the environment is setup, the MinnowBoard MAX firmware and
> capsules can be
> +rebuilt using the following commands.
> +
> +
> +* Build Debug Image
> +
> +```
> +cd Vlv2TbltDevicePkg
> +./Build_IFWI.sh MNW2 Debug
> +```
> +
> +* Build Release Image
> +
> +```
> +cd Vlv2TbltDevicePkg
> +./Build_IFWI.sh MNW2 Release
> +```
> +
> +The generated firmware image is the
> `MNW2MAX_X64_D_0084_01_GCC.bin` file in
> +`edk2\Vlv2TbltDevicePkg\Stitch`
> +
> +The CapsuleApp and generated UEFI Capsules are in
> `Build\Vlv2TbltDevicePkg\Capsules`
> +
> +# Use DediProg to update FLASH image on a MinnowBoard MAX Target
> +
> +# Update MinnowBoard MAX Firmware from UEFI Capsules
> +
> +* Copy the `Build/Vlv2TbltDevicePkg/Capsules` directory to a USB FLASH
> drive
> +* Connect USB FLASH Drive to MinnowBoard MAX
> +* Boot MinnowBoard MAX to the Boot Manager
> +* Boot the `EFI Internal Shell` boot option
> +* Mount the USB FLASH Drive (usually `FS1`)
> +* Use `cd` command to go to `Capsules/TestCert` directory
> +* Run the following command to apply all four capsules
> +
> +```
> +CapsuleApp.efi Red.cap Green.cap Blue.cap MinnowMax.cap
> +```
> +
> +* The MinnowBoard MAX should reboot and the four capsules are applied
> in the
> +  order listed.  The progress bar matches the color name of the capsule.
> +  MinnowMax.cap uses the color purple.  Once all capsules are processed,
> the
> +  MinnowBoard MAX should reboot again using the new firmware images.
> +
> +# Generate and Test a UX BitMap Capsule
> +
> +* Use bitmap editor to generate a BMP file.  Recommend resolution of 600
> wide
> +  by 100 tell and either 24 or 32 bits per pixel.
> +* Save BMP file to USB FLASH drive
> +* Use CapsuleApp.efi to convert BMP file to a UX Capsule
> +
> +```
> +CapsuleApp.efi -G MyImage.bmp -O MyImage.cap
> +```
> +
> +* When updating firmware using capsules, add UX capsule to the list of
> capsules
> +  passed into CapsuleApp.efi.
> +
> +```
> +CapsuleApp.efi MyImage.cap Red.cap Green.cap Blue.cap MinnowMax.cap
> +```
> +
> +* When the capsules are processed the UX bitmap image should be
> displayed at the
> +  bottom of the screen.
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfi
> g.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfi
> g.c
> new file mode 100644
> index 0000000000..69c16c5a3f
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfi
> g.c
> @@ -0,0 +1,181 @@
> +/**
> +  Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +Module Name:
> +
> +  SaveMemoryConfig.c
> +
> +Abstract:
> +  This is the driver that locates the MemoryConfigurationData HOB, if it
> +  exists, and saves the data to nvRAM.
> +
> +
> +
> +--*/
> +
> +#include "SaveMemoryConfig.h"
> +
> +CHAR16    EfiMemoryConfigVariable[] = L"MemoryConfig";
> +
> +
> +EFI_STATUS
> +EFIAPI
> +SaveMemoryConfigEntryPoint (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  )
> +/*++
> +
> +  Routine Description:
> +    This is the standard EFI driver point that detects whether there is a
> +    MemoryConfigurationData HOB and, if so, saves its data to nvRAM.
> +
> +  Arguments:
> +    ImageHandle   - Handle for the image of this driver
> +    SystemTable   - Pointer to the EFI System Table
> +
> +  Returns:
> +    EFI_SUCCESS   - if the data is successfully saved or there was no data
> +    EFI_NOT_FOUND - if the HOB list could not be located.
> +    EFI_UNLOAD_IMAGE - It is not success
> +
> +--*/
> +{
> +  EFI_STATUS                      Status=EFI_SUCCESS;
> +  VOID                            *MemHobData;
> +  VOID                            *VariableData;
> +  UINTN                           BufferSize;
> +  BOOLEAN                         MfgMode;
> +  EFI_PLATFORM_SETUP_ID           *BootModeBuffer;
> +  EFI_PLATFORM_INFO_HOB           *PlatformInfoHobPtr;
> +  MEM_INFO_PROTOCOL               *MemInfoProtocol;
> +  EFI_HANDLE                      Handle;
> +  UINT8
> Channel, Slot;
> +  VOID                            *GuidHob;
> +
> +  VariableData   = NULL;
> +  MfgMode        = FALSE;
> +  Handle         = NULL;
> +  BootModeBuffer = NULL;
> +  MemHobData     = NULL;
> +  PlatformInfoHobPtr = NULL;
> +  BufferSize     = 0;
> +
> +  //
> +  // Get Platform Info HOB
> +  //
> +  GuidHob = GetFirstGuidHob (&gEfiPlatformInfoGuid);
> +  if (GuidHob == NULL) {
> +    Status = EFI_NOT_FOUND;
> +  }
> +  ASSERT_EFI_ERROR (Status);
> +
> +  PlatformInfoHobPtr = GET_GUID_HOB_DATA (GuidHob);
> +
> +  //
> +  // Get the BootMode guid hob
> +  //
> +  GuidHob = GetFirstGuidHob (&gEfiPlatformBootModeGuid);
> +  if (GuidHob == NULL) {
> +    Status = EFI_NOT_FOUND;
> +  }
> +  ASSERT_EFI_ERROR (Status);
> +
> +  BootModeBuffer = GET_GUID_HOB_DATA (GuidHob);
> +
> +
> +  //
> +  // Check whether in Manufacturing Mode
> +  //
> +  if (BootModeBuffer) {
> +    if ( !CompareMem (   //EfiCompareMem
> +            &BootModeBuffer->SetupName,
> +            MANUFACTURE_SETUP_NAME,
> +            StrSize (MANUFACTURE_SETUP_NAME)  //EfiStrSize
> +            ) ) {
> +      MfgMode = TRUE;
> +    }
> +  }
> +
> +  if (MfgMode) {
> +    //
> +    // Don't save Memory Configuration in Manufacturing Mode. Clear
> memory configuration.
> +    //
> +    Status = gRT->SetVariable (
> +              EfiMemoryConfigVariable,
> +              &gEfiVlv2VariableGuid,
> +              EFI_VARIABLE_NON_VOLATILE |
> EFI_VARIABLE_BOOTSERVICE_ACCESS,
> +              0,
> +              NULL
> +              );
> +  } else {
> +
> +    MemInfoProtocol =
> (MEM_INFO_PROTOCOL*)AllocateZeroPool(sizeof(MEM_INFO_PROTOCOL)
> );
> +    if (PlatformInfoHobPtr != NULL) {
> +      MemInfoProtocol->MemInfoData.memSize  = 0;
> +      for (Channel = 0; Channel < CH_NUM; Channel ++){
> +        for (Slot = 0; Slot < DIMM_NUM; Slot ++){
> +          MemInfoProtocol->MemInfoData.dimmSize[Slot + (Channel *
> DIMM_NUM)] = PlatformInfoHobPtr->MemData.DimmSize[Slot + (Channel
> * DIMM_NUM)];
> +        }
> +      }
> +  	  MemInfoProtocol->MemInfoData.memSize       =
> PlatformInfoHobPtr->MemData.MemSize;
> +  	  MemInfoProtocol->MemInfoData.EccSupport    =
> PlatformInfoHobPtr->MemData.EccSupport;
> +      MemInfoProtocol->MemInfoData.ddrFreq       = PlatformInfoHobPtr-
> >MemData.DdrFreq;
> +      MemInfoProtocol->MemInfoData.ddrType       = PlatformInfoHobPtr-
> >MemData.DdrType;
> +      if (MemInfoProtocol->MemInfoData.memSize == 0){
> +        //
> +        // We hardcode if MRC didn't fill these info in
> +        //
> +        MemInfoProtocol->MemInfoData.memSize     = 0x800; //per 1MB
> +        MemInfoProtocol->MemInfoData.dimmSize[0] = 0x800;
> +        MemInfoProtocol->MemInfoData.dimmSize[1] = 0;
> +        MemInfoProtocol->MemInfoData.EccSupport  = FALSE;
> +        MemInfoProtocol->MemInfoData.ddrType     = 5; //DDRType_LPDDR3
> +      }
> +
> +      Status = gBS->InstallMultipleProtocolInterfaces (
> +             &Handle,
> +             &gMemInfoProtocolGuid,
> +             MemInfoProtocol,
> +             NULL
> +             );
> +    }
> +
> +    Status = EFI_SUCCESS;
> +    if (BOOT_WITH_MINIMAL_CONFIGURATION != GetBootModeHob()){
> +      //
> +      // Get the Memory Config guid hob
> +      //
> +      GuidHob = GetFirstGuidHob (&gEfiMemoryConfigDataGuid);
> +      if (GuidHob == NULL) {
> +        Status = EFI_NOT_FOUND;
> +      }
> +      ASSERT_EFI_ERROR (Status);
> +
> +      MemHobData = GET_GUID_HOB_DATA (GuidHob);
> +      BufferSize = GET_GUID_HOB_DATA_SIZE (GuidHob);
> +
> +      Status = gRT->GetVariable (
> +                  EfiMemoryConfigVariable,
> +                  &gEfiVlv2VariableGuid,
> +                  NULL,
> +                  &BufferSize,
> +                  VariableData
> +                  );
> +      if (EFI_ERROR(Status) && (MemHobData != NULL)) {
> +        Status = gRT->SetVariable (
> +                      EfiMemoryConfigVariable,
> +                      &gEfiVlv2VariableGuid,
> +                      (EFI_VARIABLE_NON_VOLATILE |
> EFI_VARIABLE_BOOTSERVICE_ACCESS),
> +                      BufferSize,
> +                      MemHobData
> +                      );
> +      }
> +    }
> +
> +  } // if-else MfgMode
> +
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfi
> g.h
> b/Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfi
> g.h
> new file mode 100644
> index 0000000000..59ad09747a
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfi
> g.h
> @@ -0,0 +1,66 @@
> +/**
> +  Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +Module Name:
> +
> +  SaveMemoryConfig.h
> +
> +Abstract:
> +
> +  Header file for Save Previous Memory Configuration Driver.
> +
> +
> +
> +--*/
> +
> +
> +#ifndef _SAVE_MEMORY_CONFIG_DRIVER_H
> +#define _SAVE_MEMORY_CONFIG_DRIVER_H
> +
> +#include "Protocol/SetupMode.h"
> +#include "Guid/PlatformInfo.h"
> +#include "Library/HobLib.h"
> +#include "Library/DebugLib.h"
> +#include "Library/UefiBootServicesTableLib.h"
> +#include "Library/BaseMemoryLib.h"
> +#include "PlatformBootMode.h"
> +#include "Library/BaseLib.h"
> +#include "Library/UefiRuntimeServicesTableLib.h"
> +#include "Guid/GlobalVariable.h"
> +#include "Library/UefiLib.h"
> +#include "Guid/HobList.h"
> +#include "Guid/MemoryConfigData.h"
> +#include "Protocol/MemInfo.h"
> +#include "Library/MemoryAllocationLib.h"
> +#include <Guid/Vlv2Variable.h>
> +
> +//
> +// Prototypes
> +//
> +EFI_STATUS
> +EFIAPI
> +SaveMemoryConfigEntryPoint (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  )
> +/*++
> +
> +  Routine Description:
> +    This is the standard EFI driver point that detects whether there is a
> +    MemoryConfigurationData HOB and, if so, saves its data to nvRAM.
> +
> +  Arguments:
> +    ImageHandle   - Handle for the image of this driver
> +    SystemTable   - Pointer to the EFI System Table
> +
> +  Returns:
> +    EFI_SUCCESS   - if the data is successfully saved or there was no data
> +    EFI_NOT_FOUND - if the HOB list could not be located.
> +    EFI_UNLOAD_IMAGE - It is not success
> +
> +--*/
> +;
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfi
> g.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfi
> g.inf
> new file mode 100644
> index 0000000000..c2d693859d
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfi
> g.inf
> @@ -0,0 +1,60 @@
> +#/*++
> +#
> +#  Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +#
> +#
> +#  Module Name:
> +#
> +#   SaveMemoryConfig.inf
> +#
> +#  Abstract:
> +#
> +#
> +--*/
> +
> +[defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = SaveMemoryConfig
> +  FILE_GUID                      = E0ECBEC9-B193-4351-A488-36A655F22F9F
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = SaveMemoryConfigEntryPoint
> +
> +[sources.common]
> +  SaveMemoryConfig.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +
> +[LibraryClasses]
> +  UefiDriverEntryPoint
> +  UefiBootServicesTableLib
> +  HobLib
> +  DebugLib
> +  UefiRuntimeServicesTableLib
> +  UefiLib
> +  BaseLib
> +
> +[Protocols]
> +  gMemInfoProtocolGuid
> +
> +[Guids]
> +  gEfiMemoryConfigDataGuid
> +  gEfiPlatformInfoGuid
> +  gEfiPlatformBootModeGuid
> +  gEfiVlv2VariableGuid
> +  #gEfiHobListGuid
> +  #gEfiPlatformInfoGuid
> +  #gEfiPlatformBootModeGuid
> +  #gEfiGlobalVariableGuid
> +  #gEfiMemoryConfigDataGuid
> +
> +[Depex]
> +  gEfiVariableArchProtocolGuid AND
> +  gEfiVariableWriteArchProtocolGuid
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/CommonHeader.h
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/CommonHeader.h
> new file mode 100644
> index 0000000000..e339b31065
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/CommonHeader.h
> @@ -0,0 +1,39 @@
> +/**@file
> +  Common header file shared by all source files.
> +
> +  This file includes package header files, library classes and protocol, PPI &
> GUID definitions.
> +
> +  Copyright (c) 2006  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +**/
> +
> +#ifndef __COMMON_HEADER_H_
> +#define __COMMON_HEADER_H_
> +
> +
> +
> +#include <FrameworkDxe.h>
> +#include <IndustryStandard/SmBios.h>
> +#include <Protocol/Smbios.h>
> +
> +#include <Guid/DataHubRecords.h>
> +#include <Guid/MdeModuleHii.h>
> +
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/HiiLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/UefiLib.h>
> +#include <PchRegs.h>
> +#include <Library/PchPlatformLib.h>
> +#include <Library/PrintLib.h>
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufa
> cturer.uni
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufa
> cturer.uni
> new file mode 100644
> index 0000000000..32309bd97a
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufa
> cturer.uni
> @@ -0,0 +1,33 @@
> +// *++
> +//
> +// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//
> +// Module Name:
> +//
> +//   MiscBaseBoardManufacturer.uni
> +//
> +// Abstract:
> +//
> +//   Base board information
> +//
> +// Revision History:
> +//
> +// --*/
> +
> +
> +/=#
> +
> +#langdef en-US "English"
> +
> +#string STR_MISC_BASE_BOARD_MANUFACTURER     #language en-US
> "Circuitco"
> +#string STR_MISC_BASE_BOARD_PRODUCT_NAME     #language en-US
> "TABLET"
> +#string STR_MISC_BASE_BOARD_PRODUCT_NAME_FFD8     #language en-
> US  "BYT-T FFD8"
> +#string STR_MISC_BASE_BOARD_PRODUCT_NAME1     #language en-US
> "MinnowBoard MAX"
> +#string STR_MISC_BASE_BOARD_VERSION          #language en-US  "REV A"
> +#string STR_MISC_BASE_BOARD_VERSION_FFD8     #language en-US  "PR0"
> +#string STR_MISC_BASE_BOARD_SERIAL_NUMBER    #language en-US  "To
> be filled by O.E.M"
> +#string STR_MISC_BASE_BOARD_ASSET_TAG        #language en-US  "To be
> filled by O.E.M"
> +#string STR_MISC_BASE_BOARD_CHASSIS_LOCATION #language en-US
> "To be filled by O.E.M"
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufa
> cturerData.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufa
> cturerData.c
> new file mode 100644
> index 0000000000..068a32f390
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufa
> cturerData.c
> @@ -0,0 +1,58 @@
> +/** @file
> +
> +Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscBaseBoardManufacturerData.c
> +
> +Abstract:
> +
> +  Static data of Base board manufacturer information.
> +  Base board manufacturer information is Misc. subclass type 4 and SMBIOS
> type 2.
> +
> +
> +**/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +//
> +// Static (possibly build generated) Bios Vendor data.
> +//
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_BASE_BOARD_MANUFACTURER_D
> ATA, MiscBaseBoardManufacturer)
> += {
> +  STRING_TOKEN(STR_MISC_BASE_BOARD_MANUFACTURER),
> +  STRING_TOKEN(STR_MISC_BASE_BOARD_PRODUCT_NAME),
> +  STRING_TOKEN(STR_MISC_BASE_BOARD_VERSION),
> +  STRING_TOKEN(STR_MISC_BASE_BOARD_SERIAL_NUMBER),
> +  STRING_TOKEN(STR_MISC_BASE_BOARD_ASSET_TAG),
> +  STRING_TOKEN(STR_MISC_BASE_BOARD_CHASSIS_LOCATION),
> +  {                         // BaseBoardFeatureFlags
> +    1,                      // Motherboard
> +    0,                      // RequiresDaughterCard
> +    0,                      // Removable
> +    1,                      // Replaceable,
> +    0,                      // HotSwappable
> +    0,                      // Reserved
> +  },
> +  EfiBaseBoardTypeUnknown,  // BaseBoardType
> +  {                         // BaseBoardChassisLink
> +    EFI_MISC_SUBCLASS_GUID, // ProducerName
> +    1,                      // Instance
> +    1,                      // SubInstance
> +  },
> +  0,                        // BaseBoardNumberLinks
> +  {                         // LinkN
> +    EFI_MISC_SUBCLASS_GUID, // ProducerName
> +    1,                      // Instance
> +    1,                      // SubInstance
> +  },
> +};
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufa
> cturerFunction.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufa
> cturerFunction.c
> new file mode 100644
> index 0000000000..aa8c213d83
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufa
> cturerFunction.c
> @@ -0,0 +1,238 @@
> +/*++
> +
> +Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  MiscBaseBoardManufacturerFunction.c
> +
> +Abstract:
> +
> +  BaseBoard manufacturer information boot time changes.
> +  SMBIOS type 2.
> +
> +--*/
> +
> +
> +#include "CommonHeader.h"
> +#include "MiscSubclassDriver.h"
> +#include <Library/NetLib.h>
> +#include "Library/DebugLib.h"
> +#include <Uefi/UefiBaseType.h>
> +#include <Guid/PlatformInfo.h>
> +
> +
> +extern EFI_PLATFORM_INFO_HOB *mPlatformInfo;
> +
> +/**
> +  This function makes boot time changes to the contents of the
> +  MiscBaseBoardManufacturer (Type 2).
> +
> +  @param  RecordData                 Pointer to copy of RecordData from the Data
> Table.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
> +
> +**/
> +MISC_SMBIOS_TABLE_FUNCTION(MiscBaseBoardManufacturer)
> +{
> +  CHAR8                           *OptionalStrStart;
> +  UINTN                           ManuStrLen;
> +  UINTN                           ProductStrLen;
> +  UINTN                           VerStrLen;
> +  UINTN                           AssertTagStrLen;
> +  UINTN                           SerialNumStrLen;
> +  UINTN                           ChassisStrLen;
> +  EFI_STATUS                      Status;
> +  EFI_STRING                      Manufacturer;
> +  EFI_STRING                      Product;
> +  EFI_STRING                      Version;
> +  EFI_STRING                      SerialNumber;
> +  EFI_STRING                      AssertTag;
> +  EFI_STRING                      Chassis;
> +  STRING_REF                      TokenToGet;
> +  EFI_SMBIOS_HANDLE               SmbiosHandle;
> +  SMBIOS_TABLE_TYPE2              *SmbiosRecord;
> +  EFI_MISC_BASE_BOARD_MANUFACTURER   *ForType2InputData;
> +
> +  CHAR16                          *MacStr;
> +  EFI_HANDLE                      *Handles;
> +  UINTN                           BufferSize;
> +  CHAR16                          Buffer[40];
> +
> +  ForType2InputData = (EFI_MISC_BASE_BOARD_MANUFACTURER
> *)RecordData;
> +
> +  //
> +  // First check for invalid parameters.
> +  //
> +  if (RecordData == NULL || mPlatformInfo == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (BOARD_ID_MINNOW2_TURBOT == mPlatformInfo->BoardId) {
> +    UnicodeSPrint (Buffer, sizeof (Buffer),L"ADI");
> +
> HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_BASE_BOARD_MANUFA
> CTURER), Buffer, NULL);
> +  }
> +  TokenToGet = STRING_TOKEN
> (STR_MISC_BASE_BOARD_MANUFACTURER);
> +  Manufacturer = SmbiosMiscGetString (TokenToGet);
> +  ManuStrLen = StrLen(Manufacturer);
> +  if (ManuStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  if (BOARD_ID_MINNOW2_TURBOT == mPlatformInfo->BoardId) {
> +    UnicodeSPrint (Buffer, sizeof (Buffer),L"MinnowBoard Turbot");
> +
> HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_BASE_BOARD_PRODUC
> T_NAME1), Buffer, NULL);
> +  }
> +  TokenToGet = STRING_TOKEN
> (STR_MISC_BASE_BOARD_PRODUCT_NAME1);
> +  Product = SmbiosMiscGetString (TokenToGet);
> +  ProductStrLen = StrLen(Product);
> +  if (ProductStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_VERSION);
> +  Version = SmbiosMiscGetString (TokenToGet);
> +  VerStrLen = StrLen(Version);
> +  if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  //Get handle infomation
> +  //
> +  BufferSize = 0;
> +  Handles = NULL;
> +  Status = gBS->LocateHandle (
> +                  ByProtocol,
> +                  &gEfiSimpleNetworkProtocolGuid,
> +                  NULL,
> +                  &BufferSize,
> +                  Handles
> +                  );
> +
> +  if (Status == EFI_BUFFER_TOO_SMALL) {
> +  	Handles = AllocateZeroPool(BufferSize);
> +  	if (Handles == NULL) {
> +  		return (EFI_OUT_OF_RESOURCES);
> +  	}
> +  	Status = gBS->LocateHandle(
> +  	                ByProtocol,
> +  	                &gEfiSimpleNetworkProtocolGuid,
> +  	                NULL,
> +  	                &BufferSize,
> +  	                Handles
> +  	                );
> + }
> +
> +  //
> +  //Get the MAC string
> +  //
> +  Status = NetLibGetMacString (
> +             *Handles,
> +             NULL,
> +             &MacStr
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  SerialNumber = MacStr;
> +  SerialNumStrLen = StrLen(SerialNumber);
> +  if (SerialNumStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +  DEBUG ((EFI_D_ERROR, "MAC Address: %S\n", MacStr));
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_ASSET_TAG);
> +  AssertTag = SmbiosMiscGetString (TokenToGet);
> +  AssertTagStrLen = StrLen(AssertTag);
> +  if (AssertTagStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  TokenToGet = STRING_TOKEN
> (STR_MISC_BASE_BOARD_CHASSIS_LOCATION);
> +  Chassis = SmbiosMiscGetString (TokenToGet);
> +  ChassisStrLen = StrLen(Chassis);
> +  if (ChassisStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +
> +  //
> +  // Two zeros following the last string.
> +  //
> +  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE2) +
> ManuStrLen + 1 + ProductStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 +
> AssertTagStrLen + 1 + ChassisStrLen +1 + 1);
> +  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE2) + ManuStrLen +
> 1 + ProductStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 +
> AssertTagStrLen + 1 + ChassisStrLen +1 + 1);
> +
> +  SmbiosRecord->Hdr.Type =
> EFI_SMBIOS_TYPE_BASEBOARD_INFORMATION;
> +  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE2);
> +
> +  //
> +  // Make handle chosen by smbios protocol.add automatically.
> +  //
> +  SmbiosRecord->Hdr.Handle = 0;
> +
> +  //
> +  // Manu will be the 1st optional string following the formatted structure.
> +  //
> +  SmbiosRecord->Manufacturer = 1;
> +
> +  //
> +  // ProductName will be the 2st optional string following the formatted
> structure.
> +  //
> +  SmbiosRecord->ProductName  = 2;
> +
> +  //
> +  // Version will be the 3rd optional string following the formatted structure.
> +  //
> +  SmbiosRecord->Version = 3;
> +
> +  //
> +  // SerialNumber will be the 4th optional string following the formatted
> structure.
> +  //
> +  SmbiosRecord->SerialNumber = 4;
> +
> +  //
> +  // AssertTag will be the 5th optional string following the formatted
> structure.
> +  //
> +  SmbiosRecord->AssetTag = 5;
> +
> +  //
> +  // LocationInChassis will be the 6th optional string following the formatted
> structure.
> +  //
> +  SmbiosRecord->LocationInChassis = 6;
> +  SmbiosRecord->FeatureFlag =
> (*(BASE_BOARD_FEATURE_FLAGS*)&(ForType2InputData-
> >BaseBoardFeatureFlags));
> +  SmbiosRecord->ChassisHandle  = 0;
> +  SmbiosRecord->BoardType      = (UINT8)ForType2InputData-
> >BaseBoardType;
> +  SmbiosRecord->NumberOfContainedObjectHandles = 0;
> +
> +  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
> +
> +  //
> +  // Since we fill NumberOfContainedObjectHandles = 0 for simple, just after
> this filed to fill string
> +  //
> +  UnicodeStrToAsciiStr(Manufacturer, OptionalStrStart);
> +  UnicodeStrToAsciiStr(Product, OptionalStrStart + ManuStrLen + 1);
> +  UnicodeStrToAsciiStr(Version, OptionalStrStart + ManuStrLen + 1 +
> ProductStrLen + 1);
> +  UnicodeStrToAsciiStr(SerialNumber, OptionalStrStart + ManuStrLen + 1 +
> ProductStrLen + 1 + VerStrLen + 1);
> +  UnicodeStrToAsciiStr(AssertTag, OptionalStrStart + ManuStrLen + 1 +
> ProductStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1);
> +  UnicodeStrToAsciiStr(Chassis, OptionalStrStart + ManuStrLen + 1 +
> ProductStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen +
> 1);
> +
> +  //
> +  // Now we have got the full smbios record, call smbios protocol to add this
> record.
> +  //
> +  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +  Status = Smbios-> Add(
> +                      Smbios,
> +                      NULL,
> +                      &SmbiosHandle,
> +                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
> +                      );
> +
> +  FreePool(SmbiosRecord);
> +  return Status;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendor.uni
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendor.uni
> new file mode 100644
> index 0000000000..80b099d210
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendor.uni
> @@ -0,0 +1,26 @@
> +// *++
> +//
> +// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//
> +// Module Name:
> +//
> +//   MiscBiosVendor.uni
> +//
> +// Abstract:
> +//
> +//   BIOS vendor information.
> +//
> +// Revision History:
> +//
> +// --*/
> +
> +
> +/=#
> +
> +#langdef en-US "English"
> +
> +#string STR_MISC_BIOS_VENDOR           #language en-US  "Intel Corp."
> +#string STR_MISC_BIOS_VERSION          #language en-US  "Valleyview A0
> BIOS"
> +#string STR_MISC_BIOS_RELEASE_DATE     #language en-US  "08/06/2012"
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorData.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorData.c
> new file mode 100644
> index 0000000000..91e8efc228
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorData.c
> @@ -0,0 +1,101 @@
> +/** @file
> +
> +Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscBiosVendorData.c
> +
> +Abstract:
> +
> +  Static data of BIOS vendor information.
> +  BIOS vendor information is Misc. subclass type 2 and SMBIOS type 0.
> +
> +
> +**/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +//
> +// Static (possibly build generated) Bios Vendor data.
> +//
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_BIOS_VENDOR_DATA,
> MiscBiosVendor)
> += {
> +  STRING_TOKEN(STR_MISC_BIOS_VENDOR),       // BiosVendor
> +  STRING_TOKEN(STR_MISC_BIOS_VERSION),      // BiosVersion
> +  STRING_TOKEN(STR_MISC_BIOS_RELEASE_DATE), // BiosReleaseDate
> +  0xF000, // BiosStartingAddress
> +  {       // BiosPhysicalDeviceSize
> +    1,    // Value
> +    21 ,          // Exponent
> +  },
> +  {       // BiosCharacteristics1
> +    0,    // Reserved1                         :2
> +    0,    // Unknown                           :1
> +    0,    // BiosCharacteristicsNotSupported   :1
> +    0,    // IsaIsSupported                    :1
> +    0,    // McaIsSupported                    :1
> +    0,    // EisaIsSupported                   :1
> +    1,    // PciIsSupported                    :1
> +    0,    // PcmciaIsSupported                 :1
> +    0,    // PlugAndPlayIsSupported            :1
> +    0,    // ApmIsSupported                    :1
> +    1,    // BiosIsUpgradable                  :1
> +    1,    // BiosShadowingAllowed              :1
> +    0,    // VlVesaIsSupported                 :1
> +    0,    // EscdSupportIsAvailable            :1
> +    1,    // BootFromCdIsSupported             :1
> +    1,    // SelectableBootIsSupported         :1
> +    0,    // RomBiosIsSocketed                 :1
> +    0,    // BootFromPcmciaIsSupported         :1
> +    1,    // EDDSpecificationIsSupported       :1
> +    0,    // JapaneseNecFloppyIsSupported      :1
> +    0,    // JapaneseToshibaFloppyIsSupported  :1
> +    0,    // Floppy525_360IsSupported          :1
> +    0,    // Floppy525_12IsSupported           :1
> +    0,    // Floppy35_720IsSupported           :1
> +    0,    // Floppy35_288IsSupported           :1
> +    0,    // PrintScreenIsSupported            :1
> +    1,    // Keyboard8042IsSupported           :1
> +    1,    // SerialIsSupported                 :1
> +    1,    // PrinterIsSupported                :1
> +    1,    // CgaMonoIsSupported                :1
> +    0,    // NecPc98                           :1
> +
> +//
> +//BIOS Characteristics Extension Byte 1
> +//
> +    1,    // AcpiIsSupported                   :1
> +    1,    // UsbLegacyIsSupported              :1
> +    0,    // AgpIsSupported                    :1
> +    0,    // I20BootIsSupported                :1
> +    0,    // Ls120BootIsSupported              :1
> +    1,    // AtapiZipDriveBootIsSupported      :1
> +    0,    // Boot1394IsSupported               :1
> +    0,    // SmartBatteryIsSupported           :1
> +
> +//
> +//BIOS Characteristics Extension Byte 2
> +//
> +    1,    // BiosBootSpecIsSupported           :1
> +    1,    // FunctionKeyNetworkBootIsSupported :1
> +    0x1     // Reserved                          :19  Bit 2 is SMBiosIsTargContDistEnabled
> +  },
> +  {       // BiosCharacteristics2
> +    0x0001,// BiosReserved                      :16  Bit 0 is BIOS Splash Screen
> +    0,    // SystemReserved                    :16
> +    0     // Reserved                          :32
> +  },
> +  0xFF,   // BiosMajorRelease;
> +  0xFF,   // BiosMinorRelease;
> +  0xFF,   // BiosEmbeddedFirmwareMajorRelease;
> +  0xFF,   // BiosEmbeddedFirmwareMinorRelease;
> +};
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorFunctio
> n.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorFuncti
> on.c
> new file mode 100644
> index 0000000000..1817f456cb
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorFuncti
> on.c
> @@ -0,0 +1,336 @@
> +/*++
> +
> +Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscBiosVendorFunction.c
> +
> +Abstract:
> +
> +  BIOS vendor information boot time changes.
> +  Misc. subclass type 2.
> +  SMBIOS type 0.
> +
> +--*/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +#include <Library/BiosIdLib.h>
> +#include <Library/SpiFlash.H>
> +
> +EFI_SPI_PROTOCOL  *mSpiProtocol = NULL;
> +
> +
> +/**
> +  This function read the data from Spi Rom.
> +
> +  @param BaseAddress                The starting address of the read.
> +  @param Byte                       The pointer to the destination buffer.
> +  @param Length                     The number of bytes.
> +  @param SpiRegionType              Spi Region Type.
> +
> +  @retval Status
> +
> +**/
> +EFI_STATUS
> +FlashRead (
> +  IN  UINTN             BaseAddress,
> +  IN  UINT8             *Byte,
> +  IN  UINTN             Length,
> +  IN  SPI_REGION_TYPE   SpiRegionType
> +  )
> +{
> +  EFI_STATUS            Status = EFI_SUCCESS;
> +  UINT32                SectorSize;
> +  UINT32                SpiAddress;
> +  UINT8                 Buffer[SECTOR_SIZE_4KB];
> +
> +  SpiAddress = (UINT32)(UINTN)(BaseAddress);
> +  SectorSize = SECTOR_SIZE_4KB;
> +
> +  Status = mSpiProtocol->Execute (
> +                           mSpiProtocol,
> +                           SPI_READ,
> +                           SPI_WREN,
> +                           TRUE,
> +                           TRUE,
> +                           FALSE,
> +                           (UINT32) SpiAddress,
> +                           SectorSize,
> +                           Buffer,
> +                           SpiRegionType
> +                           );
> +
> +  if (EFI_ERROR (Status)) {
> +#ifdef _SHOW_LOG_
> +    Print(L"Read SPI ROM Failed [%08x]\n", SpiAddress);
> +#endif
> +    return Status;
> +  }
> +
> +  CopyMem (Byte, (void *)Buffer, Length);
> +
> +  return Status;
> +}
> +
> +/**
> +  This function returns the value & exponent to Base2 for a given
> +  Hex value. This is used to calculate the BiosPhysicalDeviceSize.
> +
> +  @param Value                      The hex value which is to be converted into
> value-exponent form
> +  @param Exponent                   The exponent out of the conversion
> +
> +  @retval EFI_SUCCESS               All parameters were valid and *Value &
> *Exponent have been set.
> +  @retval EFI_INVALID_PARAMETER     Invalid parameter was found.
> +
> +**/
> +EFI_STATUS
> +GetValueExponentBase2(
> +  IN OUT UINTN        *Value,
> +  OUT    UINTN        *Exponent
> +  )
> +{
> +  if ((Value == NULL) || (Exponent == NULL)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  while ((*Value % 2) == 0) {
> +    *Value=*Value/2;
> +    (*Exponent)++;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a byte, with
> '64k'
> +  as the unit.
> +
> +  @param  Base2Data              Pointer to Base2_Data
> +
> +  @retval EFI_SUCCESS            Transform successfully.
> +  @retval EFI_INVALID_PARAMETER  Invalid parameter was found.
> +
> +**/
> +UINT16
> +Base2ToByteWith64KUnit (
> +  IN      EFI_EXP_BASE2_DATA  *Base2Data
> +  )
> +{
> +  UINT16              Value;
> +  UINT16              Exponent;
> +
> +  Value     = Base2Data->Value;
> +  Exponent  = Base2Data->Exponent;
> +  Exponent -= 16;
> +  Value <<= Exponent;
> +
> +  return Value;
> +}
> +
> +
> +/**
> +  This function makes boot time changes to the contents of the
> +  MiscBiosVendor (Type 0).
> +
> +  @param  RecordData                 Pointer to copy of RecordData from the Data
> Table.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
> +
> +**/
> +MISC_SMBIOS_TABLE_FUNCTION(MiscBiosVendor)
> +{
> +  CHAR8                 *OptionalStrStart;
> +  UINTN                 VendorStrLen;
> +  UINTN                 VerStrLen;
> +  UINTN                 DateStrLen;
> +  CHAR16                *Version;
> +  CHAR16                *ReleaseDate;
> +  CHAR16                BiosVersion[100];         //Assuming that strings are < 100
> UCHAR
> +  CHAR16                BiosReleaseDate[100];     //Assuming that strings are < 100
> UCHAR
> +  CHAR16                BiosReleaseTime[100];     //Assuming that strings are < 100
> UCHAR
> +  EFI_STATUS            Status;
> +  EFI_STRING            Char16String;
> +  STRING_REF            TokenToGet;
> +  STRING_REF            TokenToUpdate;
> +  SMBIOS_TABLE_TYPE0    *SmbiosRecord;
> +  EFI_SMBIOS_HANDLE     SmbiosHandle;
> +  EFI_MISC_BIOS_VENDOR *ForType0InputData;
> +  BIOS_ID_IMAGE         BiosIdImage;
> +  UINT16                UVerStr[32];
> +  UINTN                 LoopIndex;
> +  UINTN                 CopyIndex;
> +  MANIFEST_OEM_DATA     *IFWIVerStruct;
> +  UINT8                 *Data8 = NULL;
> +  UINT16                SpaceVer[2]={0x0020,0x0000};
> +  UINT16                BIOSVersionTemp[100];
> +
> +  ForType0InputData        = (EFI_MISC_BIOS_VENDOR *)RecordData;
> +
> +  //
> +  // First check for invalid parameters.
> +  //
> +  if (RecordData == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  GetBiosId (&BiosIdImage);
> +
> +  //
> +  //  Add VLV2 BIOS Version and Release data
> +  //
> +  SetMem(BiosVersion, sizeof(BiosVersion), 0);
> +  SetMem(BiosReleaseDate, sizeof(BiosReleaseDate), 0);
> +  SetMem(BiosReleaseTime, sizeof(BiosReleaseTime), 0);
> +  Status = GetBiosVersionDateTime (BiosVersion, BiosReleaseDate,
> BiosReleaseTime);
> +  DEBUG ((EFI_D_ERROR, "GetBiosVersionDateTime :%s %s %s \n",
> BiosVersion, BiosReleaseDate, BiosReleaseTime));
> +  if (StrLen (BiosVersion) > 0) {
> +    TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_VERSION);
> +    HiiSetString (mHiiHandle, TokenToUpdate, BiosVersion, NULL);
> +  }
> +
> +  if (StrLen(BiosReleaseDate) > 0) {
> +    TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE);
> +    HiiSetString (mHiiHandle, TokenToUpdate, BiosReleaseDate, NULL);
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VENDOR);
> +  Char16String = SmbiosMiscGetString (TokenToGet);
> +  VendorStrLen = StrLen(Char16String);
> +  if (VendorStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VERSION);
> +  Version = SmbiosMiscGetString (TokenToGet);
> +
> +  ZeroMem (UVerStr, 2*32);
> +  ZeroMem (BIOSVersionTemp, 2*100);
> +  StrCat (BIOSVersionTemp,Version);
> +  Data8 = AllocatePool (SECTOR_SIZE_4KB);
> +  ZeroMem (Data8, SECTOR_SIZE_4KB);
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiSpiProtocolGuid,
> +                  NULL,
> +                 (VOID **)&mSpiProtocol
> +                 );
> +  if (!EFI_ERROR(Status)) {
> +    //
> +    // Get data form SPI ROM.
> +    //
> +    Status = FlashRead (
> +               MEM_IFWIVER_START,
> +               Data8,
> +               SECTOR_SIZE_4KB,
> +               EnumSpiRegionAll
> +               );
> +    if (!EFI_ERROR(Status)) {
> +      for(LoopIndex = 0; LoopIndex <= SECTOR_SIZE_4KB; LoopIndex++) {
> +        IFWIVerStruct = (MANIFEST_OEM_DATA *)(Data8 + LoopIndex);
> +        if(IFWIVerStruct->Signature == SIGNATURE_32('$','F','U','D')) {
> +          DEBUG ((EFI_D_ERROR, "the IFWI Length is:%d\n", IFWIVerStruct-
> >IFWIVersionLen));
> +          if(IFWIVerStruct->IFWIVersionLen < 32) {
> +            for(CopyIndex = 0; CopyIndex < IFWIVerStruct->IFWIVersionLen;
> CopyIndex++) {
> +              UVerStr[CopyIndex] = (UINT16)IFWIVerStruct-
> >IFWIVersion[CopyIndex];
> +            }
> +            UVerStr[CopyIndex] = 0x0000;
> +            DEBUG ((EFI_D_ERROR, "The IFWI Version is :%s,the IFWI Length
> is:%d\n", UVerStr,IFWIVerStruct->IFWIVersionLen));
> +            StrCat(BIOSVersionTemp,SpaceVer);
> +            StrCat(BIOSVersionTemp,UVerStr);
> +            DEBUG ((EFI_D_ERROR, "The BIOS and IFWI Version is :%s\n",
> BIOSVersionTemp));
> +          }
> +          break;
> +        }
> +      }
> +    }
> +  }
> +  FreePool(Data8);
> +
> +  VerStrLen = StrLen(BIOSVersionTemp);
> +  if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE);
> +  ReleaseDate = SmbiosMiscGetString (TokenToGet);
> +  DateStrLen = StrLen(ReleaseDate);
> +  if (DateStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Two zeros following the last string.
> +  //
> +  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE0) +
> VendorStrLen + 1 + VerStrLen + 1 + DateStrLen + 1 + 1);
> +  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE0) + VendorStrLen
> + 1 + VerStrLen + 1 + DateStrLen + 1 + 1);
> +
> +  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_BIOS_INFORMATION;
> +  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE0);
> +
> +  //
> +  // Make handle chosen by smbios protocol.add automatically.
> +  //
> +  SmbiosRecord->Hdr.Handle = 0;
> +
> +  //
> +  // Vendor will be the 1st optional string following the formatted structure.
> +  //
> +  SmbiosRecord->Vendor = 1;
> +
> +  //
> +  // Version will be the 2nd optional string following the formatted structure.
> +  //
> +  SmbiosRecord->BiosVersion = 2;
> +  SmbiosRecord->BiosSegment = (UINT16)ForType0InputData-
> >BiosStartingAddress;
> +
> +  //
> +  // ReleaseDate will be the 3rd optional string following the formatted
> structure.
> +  //
> +  SmbiosRecord->BiosReleaseDate = 3;
> +
> +  //
> +  // Tiger has no PCD value to indicate BIOS Size, just fill 0 for simply.
> +  //
> +  SmbiosRecord->BiosSize = 0;
> +  SmbiosRecord->BiosCharacteristics =
> *(MISC_BIOS_CHARACTERISTICS*)(&ForType0InputData-
> >BiosCharacteristics1);
> +
> +  //
> +  // CharacterExtensionBytes also store in ForType0InputData-
> >BiosCharacteristics1 later two bytes to save size.
> +  //
> +  SmbiosRecord->BIOSCharacteristicsExtensionBytes[0] = *((UINT8 *)
> &ForType0InputData->BiosCharacteristics1 + 4);
> +  SmbiosRecord->BIOSCharacteristicsExtensionBytes[1] = *((UINT8 *)
> &ForType0InputData->BiosCharacteristics1 + 5);
> +
> +  SmbiosRecord->SystemBiosMajorRelease =  ForType0InputData-
> >BiosMajorRelease;
> +  SmbiosRecord->SystemBiosMinorRelease =  ForType0InputData-
> >BiosMinorRelease;
> +  SmbiosRecord->EmbeddedControllerFirmwareMajorRelease =
> ForType0InputData->BiosEmbeddedFirmwareMajorRelease;
> +  SmbiosRecord->EmbeddedControllerFirmwareMinorRelease =
> ForType0InputData->BiosEmbeddedFirmwareMinorRelease;
> +
> +  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
> +  UnicodeStrToAsciiStr(Char16String, OptionalStrStart);
> +  UnicodeStrToAsciiStr(BIOSVersionTemp, OptionalStrStart + VendorStrLen
> + 1);
> +  UnicodeStrToAsciiStr(ReleaseDate, OptionalStrStart + VendorStrLen + 1 +
> VerStrLen + 1);
> +
> +  //
> +  // Now we have got the full smbios record, call smbios protocol to add this
> record.
> +  //
> +  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +  Status = Smbios-> Add(
> +                      Smbios,
> +                      NULL,
> +                      &SmbiosHandle,
> +                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
> +                      );
> +
> +  FreePool(SmbiosRecord);
> +  return Status;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationD
> ata.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationD
> ata.c
> new file mode 100644
> index 0000000000..6b0f562261
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationD
> ata.c
> @@ -0,0 +1,34 @@
> +/** @file
> +
> +Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscBootInformationData.c
> +
> +Abstract:
> +
> +  Static data of Boot information.
> +  Boot information is Misc. subclass type 26 and SMBIOS type 32.
> +
> +
> +**/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +//
> +// Static (possibly build generated) Bios Vendor data.
> +//
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_BOOT_INFORMATION_STATUS_D
> ATA, BootInformationStatus)
> += {
> +  EfiBootInformationStatusNoError,  // BootInformationStatus
> +  0                                 // BootInformationData
> +};
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationF
> unction.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationF
> unction.c
> new file mode 100644
> index 0000000000..0d4d50c663
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationF
> unction.c
> @@ -0,0 +1,82 @@
> +/*++
> +
> +Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscBootInformationFunction.c
> +
> +Abstract:
> +
> +  boot information boot time changes.
> +  SMBIOS type 32.
> +
> +--*/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +
> +/**
> +  This function makes boot time changes to the contents of the
> +  MiscBootInformation (Type 32).
> +
> +  @param  RecordData                 Pointer to copy of RecordData from the Data
> Table.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
> +
> +**/
> +
> +MISC_SMBIOS_TABLE_FUNCTION(BootInformationStatus)
> +{
> +  EFI_STATUS                         Status;
> +  EFI_SMBIOS_HANDLE                  SmbiosHandle;
> +  SMBIOS_TABLE_TYPE32                *SmbiosRecord;
> +  EFI_MISC_BOOT_INFORMATION_STATUS*  ForType32InputData;
> +
> +  ForType32InputData = (EFI_MISC_BOOT_INFORMATION_STATUS
> *)RecordData;
> +
> +  //
> +  // First check for invalid parameters.
> +  //
> +  if (RecordData == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Two zeros following the last string.
> +  //
> +  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE32) + 1 + 1);
> +  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE32) + 1 + 1);
> +
> +  SmbiosRecord->Hdr.Type =
> EFI_SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION;
> +  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE32);
> +
> +  //
> +  // Make handle chosen by smbios protocol.add automatically.
> +  //
> +  SmbiosRecord->Hdr.Handle = 0;
> +  SmbiosRecord->BootStatus = (UINT8)ForType32InputData-
> >BootInformationStatus;
> +
> +  //
> +  // Now we have got the full smbios record, call smbios protocol to add this
> record.
> +  //
> +  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +  Status = Smbios-> Add(
> +                      Smbios,
> +                      NULL,
> +                      &SmbiosHandle,
> +                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
> +                      );
> +  FreePool(SmbiosRecord);
> +  return Status;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufactur
> er.uni
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufactu
> rer.uni
> new file mode 100644
> index 0000000000..1c8dd35b37
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufactu
> rer.uni
> @@ -0,0 +1,28 @@
> +// *++
> +//
> +// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//
> +// Module Name:
> +//
> +//   MiscChassisManufacturer.uni
> +//
> +// Abstract:
> +//
> +//   Chassis information
> +//
> +// Revision History:
> +//
> +// --*/
> +
> +
> +/=#
> +
> +#langdef en-US "English"
> +
> +#string STR_MISC_CHASSIS_MANUFACTURER  #language en-US  "Circuitco"
> +#string STR_MISC_CHASSIS_VERSION       #language en-US  " "
> +#string STR_MISC_CHASSIS_SERIAL_NUMBER #language en-US  " "
> +#string STR_MISC_CHASSIS_ASSET_TAG     #language en-US  " "
> +#string STR_MISC_CHASSIS_SKU_NUMBER    #language en-US  " "
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufactur
> erData.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufactu
> rerData.c
> new file mode 100644
> index 0000000000..ee11c9eac4
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufactu
> rerData.c
> @@ -0,0 +1,57 @@
> +/** @file
> +
> +Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscChassisManufacturerData.c
> +
> +Abstract:
> +
> +  Static data is Chassis Manufacturer information.
> +  Chassis Manufacturer information is Misc. subclass type 5 and SMBIOS
> type 3.
> +
> +
> +**/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +//
> +// Static (possibly build generated) Chassis Manufacturer data.
> +//
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_CHASSIS_MANUFACTURER_DATA,
> MiscChassisManufacturer)
> += {
> +  STRING_TOKEN(STR_MISC_CHASSIS_MANUFACTURER),  //
> ChassisManufactrurer
> +  STRING_TOKEN(STR_MISC_CHASSIS_VERSION),       // ChassisVersion
> +  STRING_TOKEN(STR_MISC_CHASSIS_SERIAL_NUMBER), //
> ChassisSerialNumber
> +  STRING_TOKEN(STR_MISC_CHASSIS_ASSET_TAG),     // ChassisAssetTag
> +  {                               // ChassisTypeStatus
> +    EfiMiscChassisTypeUnknown,    // ChassisType
> +    0,                            // ChassisLockPresent
> +    0                             // Reserved
> +  },
> +  EfiChassisStateSafe,            // ChassisBootupState
> +  EfiChassisStateSafe,            // ChassisPowerSupplyState
> +  EfiChassisStateOther,           // ChassisThermalState
> +  EfiChassisSecurityStatusOther,  // ChassisSecurityState
> +  0,                              // ChassisOemDefined
> +  0,                              // ChassisHeight
> +  0,                              // ChassisNumberPowerCords
> +  0,                              // ChassisElementCount
> +  0,                              // ChassisElementRecordLength
> +  {                               // ChassisElements
> +    {0, 0, 0},                    // ChassisElementType
> +    0,                            // ChassisElementStructure
> +    EfiBaseBoardTypeUnknown,      // ChassisBaseBoard
> +    0,                            // ChassisElementMinimum
> +    0                             // ChassisElementMaximum
> +  },
> +};
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufactur
> erFunction.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufactu
> rerFunction.c
> new file mode 100644
> index 0000000000..c42ba3d0d1
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufactu
> rerFunction.c
> @@ -0,0 +1,158 @@
> +/*++
> +
> +Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscChassisManufacturerFunction.c
> +
> +Abstract:
> +
> +  Chassis manufacturer information boot time changes.
> +  SMBIOS type 3.
> +
> +--*/
> +
> +
> +#include "CommonHeader.h"
> +#include "MiscSubclassDriver.h"
> +#include <Guid/PlatformInfo.h>
> +
> +
> +extern EFI_PLATFORM_INFO_HOB *mPlatformInfo;
> +
> +/**
> +  This function makes boot time changes to the contents of the
> +  MiscChassisManufacturer (Type 3).
> +
> +  @param  RecordData                 Pointer to copy of RecordData from the Data
> Table.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
> +
> +**/
> +MISC_SMBIOS_TABLE_FUNCTION(MiscChassisManufacturer)
> +{
> +  CHAR8                           *OptionalStrStart;
> +  UINTN                           ManuStrLen;
> +  UINTN                           VerStrLen;
> +  UINTN                           AssertTagStrLen;
> +  UINTN                           SerialNumStrLen;
> +  EFI_STATUS                      Status;
> +  EFI_STRING                      Manufacturer;
> +  EFI_STRING                      Version;
> +  EFI_STRING                      SerialNumber;
> +  EFI_STRING                      AssertTag;
> +  STRING_REF                      TokenToGet;
> +  EFI_SMBIOS_HANDLE               SmbiosHandle;
> +  SMBIOS_TABLE_TYPE3              *SmbiosRecord;
> +  EFI_MISC_CHASSIS_MANUFACTURER   *ForType3InputData;
> +  CHAR16                          Buffer[40];
> +
> +  ForType3InputData = (EFI_MISC_CHASSIS_MANUFACTURER *)RecordData;
> +
> +  //
> +  // First check for invalid parameters.
> +  //
> +  if (RecordData == NULL || mPlatformInfo == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (BOARD_ID_MINNOW2_TURBOT == mPlatformInfo->BoardId) {
> +    UnicodeSPrint (Buffer, sizeof (Buffer),L"ADI");
> +
> HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_CHASSIS_MANUFACTUR
> ER), Buffer, NULL);
> +  }
> +  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_MANUFACTURER);
> +  Manufacturer = SmbiosMiscGetString (TokenToGet);
> +  ManuStrLen = StrLen(Manufacturer);
> +  if (ManuStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_VERSION);
> +  Version = SmbiosMiscGetString (TokenToGet);
> +  VerStrLen = StrLen(Version);
> +  if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_SERIAL_NUMBER);
> +  SerialNumber = SmbiosMiscGetString (TokenToGet);
> +  SerialNumStrLen = StrLen(SerialNumber);
> +  if (SerialNumStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_ASSET_TAG);
> +  AssertTag = SmbiosMiscGetString (TokenToGet);
> +  AssertTagStrLen = StrLen(AssertTag);
> +  if (AssertTagStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Two zeros following the last string.
> +  //
> +  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE3) +
> ManuStrLen + 1  + VerStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1
> + 1);
> +  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE3) + ManuStrLen +
> 1  + VerStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1 + 1);
> +
> +  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_ENCLOSURE;
> +  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE3);
> +
> +  //
> +  // Make handle chosen by smbios protocol.add automatically.
> +  //
> +  SmbiosRecord->Hdr.Handle = 0;
> +
> +  //
> +  // Manu will be the 1st optional string following the formatted structure.
> +  //
> +  SmbiosRecord->Manufacturer = 1;
> +  SmbiosRecord->Type = (UINT8)ForType3InputData-
> >ChassisType.ChassisType;
> +
> +  //
> +  // Version will be the 2nd optional string following the formatted structure.
> +  //
> +  SmbiosRecord->Version = 2;
> +
> +  //
> +  // SerialNumber will be the 3rd optional string following the formatted
> structure.
> +  //
> +  SmbiosRecord->SerialNumber = 3;
> +
> +  //
> +  // AssertTag will be the 4th optional string following the formatted
> structure.
> +  //
> +  SmbiosRecord->AssetTag = 4;
> +  SmbiosRecord->BootupState = (UINT8)ForType3InputData-
> >ChassisBootupState;
> +  SmbiosRecord->PowerSupplyState = (UINT8)ForType3InputData-
> >ChassisPowerSupplyState;
> +  SmbiosRecord->ThermalState = (UINT8)ForType3InputData-
> >ChassisThermalState;
> +  SmbiosRecord->SecurityStatus = (UINT8)ForType3InputData-
> >ChassisSecurityState;
> +  CopyMem (SmbiosRecord->OemDefined,(UINT8*)&ForType3InputData-
> >ChassisOemDefined, 4);
> +
> +  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
> +  UnicodeStrToAsciiStr(Manufacturer, OptionalStrStart);
> +  UnicodeStrToAsciiStr(Version, OptionalStrStart + ManuStrLen + 1);
> +  UnicodeStrToAsciiStr(SerialNumber, OptionalStrStart + ManuStrLen + 1 +
> VerStrLen + 1);
> +  UnicodeStrToAsciiStr(AssertTag, OptionalStrStart + ManuStrLen + 1 +
> VerStrLen + 1 + SerialNumStrLen + 1);
> +
> +  //
> +  // Now we have got the full smbios record, call smbios protocol to add this
> record.
> +  //
> +  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +  Status = Smbios-> Add(
> +                      Smbios,
> +                      NULL,
> +                      &SmbiosHandle,
> +                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
> +                      );
> +
> +  FreePool(SmbiosRecord);
> +  return Status;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDevice.un
> i
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDevice.un
> i
> new file mode 100644
> index 0000000000..9dd0b76ea2
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDevice.un
> i
> @@ -0,0 +1,35 @@
> +// *++
> +//
> +// Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//
> +// Module Name:
> +//
> +//   MiscMemoryDevice.uni
> +//
> +// Abstract:
> +//
> +//   Memory Device
> +//   Misc. subclass type 17.
> +//   SMBIOS type 17.
> +//
> +// Revision History:
> +//
> +// --*/
> +
> +
> +/=#
> +
> +#langdef   en-US "English"
> +
> +#string STR_MISC_MEM_DEV_LOCATOR_0          #language en-US
> "MODULE 0"
> +#string STR_MISC_MEM_DEV_LOCATOR_1          #language en-US
> "MODULE 1"
> +#string STR_MISC_MEM_DEV_LOCATOR0           #language en-US  "DIMM 0"
> +#string STR_MISC_MEM_DEV_LOCATOR1           #language en-US  "DIMM 1"
> +#string STR_MISC_MEM_BANK_LOCATOR0          #language en-US  "BANK 0"
> +#string STR_MISC_MEM_BANK_LOCATOR1          #language en-US  "BANK 1"
> +#string STR_MISC_MEM_MANUFACTURER          #language en-US  "Micron"
> +#string STR_MISC_MEM_SERIAL_NO             #language en-US  " "
> +#string STR_MISC_MEM_ASSET_TAG             #language en-US  " "
> +#string STR_MISC_MEM_PART_NUMBER           #language en-US  " "
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceDat
> a.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceDat
> a.c
> new file mode 100644
> index 0000000000..4a416dfdeb
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceDat
> a.c
> @@ -0,0 +1,45 @@
> +/*++
> +
> +Copyright (c) 2006  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscMemoryDeviceData.c
> +
> +Abstract:
> +
> +   Memory Device
> +   Misc. subclass type 17.
> +   SMBIOS type 17.
> +
> +--*/
> +
> +
> +#include "CommonHeader.h"
> +#include "MiscSubclassDriver.h"
> +
> +MISC_SMBIOS_TABLE_DATA(EFI_MEMORY_ARRAY_LINK_DATA,
> MiscMemoryDevice) = {
> +	STRING_TOKEN (STR_MISC_MEM_DEV_LOCATOR0),        // Memory
> Device locator
> +	STRING_TOKEN (STR_MISC_MEM_BANK_LOCATOR0),       // Memory
> Bank Locator
> +	STRING_TOKEN (STR_MISC_MEM_MANUFACTURER),        // Memory
> manufacturer
> +	STRING_TOKEN (STR_MISC_MEM_SERIAL_NO),           // Memory
> serial Number
> +	STRING_TOKEN (STR_MISC_MEM_ASSET_TAG),           // Memory
> Asset Tag
> +	STRING_TOKEN (STR_MISC_MEM_PART_NUMBER),         // Memory
> Part Number
> +	0,
> 			    // Memory Array Link
> +	0, 					                // Memory SubArray
> link
> +	0, 					                // UINT16
> MemoryTotalWidth
> +	0, 					                // UINT16
> MemoryDatawidth
> +	0,
> 		      // Memory Device Size
> +	EfiMemoryFormFactorDip, 	  // Memory Form Factor
> +    2,                        // UINT8 Memory Device type
> +	EfiMemoryTypeDram, 			    // Memory Type
> +    0,                        // Memory Type Detail
> +    0,
> 	    // Memory Speed
> +	0 					                // Memory State
> +
> +};
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceFu
> nction.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceFu
> nction.c
> new file mode 100644
> index 0000000000..3872312c30
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceFu
> nction.c
> @@ -0,0 +1,319 @@
> +/*++
> +
> +Copyright (c) 2006  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscMemoryDeviceFunction.c
> +
> +Abstract:
> +
> +   Memory Device
> +   Misc. subclass type 17.
> +   SMBIOS type 17.
> +
> +--*/
> +
> +
> +#include "CommonHeader.h"
> +#include "MiscSubclassDriver.h"
> +#include <Protocol/DataHub.h>
> +#include <Guid/DataHubRecords.h>
> +#include <Protocol/MemInfo.h>
> +
> +
> +#define FREQ_800           0x00
> +#define FREQ_1066          0x01
> +#define FREQ_1333          0x02
> +#define FREQ_1600          0x03
> +
> +#define MAX_SOCKETS  2
> +#define EfiMemoryTypeDdr3  0x18
> +
> +enum {
> +    DDRType_DDR3 = 0,
> +    DDRType_DDR3L = 1,
> +    DDRType_DDR3U = 2,
> +    DDRType_DDR3All = 3,
> +    DDRType_LPDDR2 = 4,
> +    DDRType_LPDDR3 = 5,
> +    DDRType_DDR4 = 6
> +};
> +
> +
> +typedef struct {
> +  EFI_PHYSICAL_ADDRESS        MemoryArrayStartAddress;
> +  EFI_PHYSICAL_ADDRESS        MemoryArrayEndAddress;
> +  EFI_INTER_LINK_DATA         PhysicalMemoryArrayLink;
> +  UINT16                      MemoryArrayPartitionWidth;
> +} EFI_MEMORY_ARRAY_START_ADDRESS;
> +
> +/**
> +  This function makes boot time changes to the contents of the
> +  MiscBiosVendor (Type 0).
> +
> +  @param  RecordData                 Pointer to copy of RecordData from the Data
> Table.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
> +
> +**/
> +VOID
> +GetType16Hndl (
> +  IN  EFI_SMBIOS_PROTOCOL      *Smbios,
> +  OUT  EFI_SMBIOS_HANDLE       *Handle
> +  )
> +{
> +  EFI_STATUS                 Status;
> +  EFI_SMBIOS_TYPE            RecordType;
> +  EFI_SMBIOS_TABLE_HEADER    *Buffer;
> +
> +  *Handle = 0;
> +   RecordType = EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY;
> +
> +    Status = Smbios->GetNext (
> +                       Smbios,
> +                       Handle,
> +                       &RecordType,
> +                       &Buffer,
> +                       NULL
> +                       );
> +    if (!EFI_ERROR(Status)) {
> +        return;
> +      }
> +  *Handle = 0xFFFF;
> +}
> +
> +MISC_SMBIOS_TABLE_FUNCTION( MiscMemoryDevice )
> +{
> +    CHAR8                           *OptionalStrStart;
> +    UINTN                           MemDeviceStrLen;
> +    UINTN                           MemBankLocatorStrLen;
> +    UINTN                           MemManufacturerStrLen;
> +    UINTN                           MemSerialNumberStrLen;
> +    UINTN                           MemAssetTagStrLen;
> +    UINTN                           MemPartNumberStrLen;
> +    CHAR16                          *MemDevice;
> +    CHAR16                          *MemBankLocator;
> +    CHAR16                          *MemManufacturer;
> +    CHAR16                          *MemSerialNumber;
> +    CHAR16                          *MemAssetTag;
> +    CHAR16                          *MemPartNumber;
> +    EFI_STATUS                      Status;
> +    STRING_REF                      TokenToGet;
> +    SMBIOS_TABLE_TYPE17             *SmbiosRecord;
> +    EFI_SMBIOS_HANDLE               SmbiosHandle;
> +    EFI_MEMORY_ARRAY_LINK_DATA      *ForType17InputData;
> +    UINT16                          DdrFreq=0;
> +    UINT16                          Type16Handle=0;
> +    MEM_INFO_PROTOCOL               *MemInfoHob;
> +    UINT8                           MemoryType;
> +
> +    UINT8                           Dimm;
> +    UINT8                           NumSlots;
> +    STRING_REF                      DevLocator[] = {
> +      STRING_TOKEN(STR_MISC_MEM_DEV_LOCATOR0),
> STRING_TOKEN(STR_MISC_MEM_DEV_LOCATOR1)
> +    };
> +    STRING_REF                      BankLocator[] = {
> +      STRING_TOKEN(STR_MISC_MEM_BANK_LOCATOR0),
> STRING_TOKEN(STR_MISC_MEM_BANK_LOCATOR1)
> +    };
> +
> +    //
> +    // First check for invalid parameters.
> +    //
> +    if (RecordData == NULL) {
> +        return EFI_INVALID_PARAMETER;
> +    }
> +    ForType17InputData        = (EFI_MEMORY_ARRAY_LINK_DATA
> *)RecordData;
> +
> +    //
> +    // Get Memory size parameters for each rank from the chipset registers
> +    //
> +    Status = gBS->LocateProtocol (
> +                    &gMemInfoProtocolGuid,
> +                    NULL,
> +                    (void **)&MemInfoHob
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    NumSlots = (UINT8)(MAX_SOCKETS);
> +
> +    //
> +    // Memory Freq
> +    //
> +    switch (MemInfoHob->MemInfoData.ddrFreq){
> +        case FREQ_800:
> +          DdrFreq = 800;
> +          break;
> +        case FREQ_1066:
> +          DdrFreq = 1066;
> +          break;
> +        case FREQ_1333:
> +          DdrFreq = 1333;
> +          break;
> +        case FREQ_1600:
> +          DdrFreq = 1600;
> +          break;
> +        default:
> +          DdrFreq = 0;
> +          break;
> +    }
> +
> +    //
> +    // Memory Type
> +    //
> +    switch  (MemInfoHob->MemInfoData.ddrType) {
> +        case DDRType_LPDDR2:
> +          MemoryType  = EfiMemoryTypeDdr2;
> +          break;
> +        case DDRType_DDR3:
> +        case DDRType_DDR3L:
> +        case DDRType_DDR3U:
> +        case DDRType_LPDDR3:
> +          MemoryType = EfiMemoryTypeDdr3;
> +          break;
> +        default:
> +          MemoryType = EfiMemoryTypeUnknown;
> +          break;
> +    }
> +
> +    for (Dimm = 0; Dimm < NumSlots; Dimm++) {
> +    //
> +    // Memory Device Locator
> +    //
> +    TokenToGet = DevLocator[Dimm];
> +    MemDevice = SmbiosMiscGetString (TokenToGet);
> +    MemDeviceStrLen = StrLen(MemDevice);
> +    if (MemDeviceStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +      return EFI_UNSUPPORTED;
> +    }
> +
> +    TokenToGet = DevLocator[Dimm];
> +    MemDevice = SmbiosMiscGetString (TokenToGet);
> +    MemDeviceStrLen = StrLen(MemDevice);
> +    if (MemDeviceStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +      return EFI_UNSUPPORTED;
> +    }
> +
> +    //
> +    // Memory Bank Locator
> +    //
> +    TokenToGet = BankLocator[Dimm];
> +    MemBankLocator = SmbiosMiscGetString (TokenToGet);
> +    MemBankLocatorStrLen = StrLen(MemBankLocator);
> +    if (MemBankLocatorStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +      return EFI_UNSUPPORTED;
> +    }
> +
> +    //
> +    // Memory Manufacturer
> +    //
> +    TokenToGet = STRING_TOKEN (STR_MISC_MEM_MANUFACTURER);
> +    MemManufacturer = SmbiosMiscGetString (TokenToGet);
> +    MemManufacturerStrLen = StrLen(MemManufacturer);
> +    if (MemManufacturerStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +      return EFI_UNSUPPORTED;
> +    }
> +
> +    //
> +    // Memory Serial Number
> +    //
> +    TokenToGet = STRING_TOKEN (STR_MISC_MEM_SERIAL_NO);
> +    MemSerialNumber = SmbiosMiscGetString (TokenToGet);
> +    MemSerialNumberStrLen = StrLen(MemSerialNumber);
> +    if (MemSerialNumberStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +      return EFI_UNSUPPORTED;
> +    }
> +
> +    //
> +    // Memory Asset Tag Number
> +    //
> +    TokenToGet = STRING_TOKEN (STR_MISC_MEM_ASSET_TAG);
> +    MemAssetTag = SmbiosMiscGetString (TokenToGet);
> +    MemAssetTagStrLen = StrLen(MemAssetTag);
> +    if (MemAssetTagStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +      return EFI_UNSUPPORTED;
> +    }
> +
> +    //
> +    // Memory Part Number
> +    //
> +    TokenToGet = STRING_TOKEN (STR_MISC_MEM_PART_NUMBER);
> +    MemPartNumber = SmbiosMiscGetString (TokenToGet);
> +    MemPartNumberStrLen = StrLen(MemPartNumber);
> +    if (MemPartNumberStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +      return EFI_UNSUPPORTED;
> +    }
> +
> +    //
> +    // Two zeros following the last string.
> +    //
> +    SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE17) +
> MemDeviceStrLen + 1 + MemBankLocatorStrLen + 1 +
> MemManufacturerStrLen + 1 + MemSerialNumberStrLen + 1 +
> MemAssetTagStrLen+1 + MemPartNumberStrLen + 1 + 1);
> +    ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE17) +
> MemDeviceStrLen + 1 + MemBankLocatorStrLen + 1 +
> MemManufacturerStrLen + 1 + MemSerialNumberStrLen + 1 +
> MemAssetTagStrLen+1 + MemPartNumberStrLen + 1 + 1);
> +
> +    SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_DEVICE;
> +    SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE17);
> +
> +    //
> +    // Make handle chosen by smbios protocol.add automatically.
> +    //
> +    SmbiosRecord->Hdr.Handle = 0;
> +
> +    //
> +    // Memory Array Handle will be the 3rd optional string following the
> formatted structure.
> +    //
> +    GetType16Hndl( Smbios, &Type16Handle);
> +    SmbiosRecord->MemoryArrayHandle = Type16Handle;
> +
> +    //
> +    // Memory Size
> +    //
> +    if ((MemInfoHob->MemInfoData.dimmSize[Dimm])!=0){
> +    SmbiosRecord->TotalWidth = 32;
> +    SmbiosRecord->DataWidth = 32;
> +    SmbiosRecord->Size = MemInfoHob->MemInfoData.dimmSize[Dimm];
> +    SmbiosRecord->Speed = DdrFreq;
> +    SmbiosRecord->ConfiguredMemoryClockSpeed = DdrFreq;
> +    SmbiosRecord->FormFactor = EfiMemoryFormFactorDimm;
> +    }
> +
> +    SmbiosRecord->DeviceSet =(UINT8) ForType17InputData-
> >MemoryDeviceSet;
> +    SmbiosRecord->DeviceLocator= 1;
> +    SmbiosRecord->BankLocator = 2;
> +
> +
> +    SmbiosRecord->Manufacturer = 3;
> +    SmbiosRecord->SerialNumber= 4;
> +    SmbiosRecord->AssetTag= 5;
> +    SmbiosRecord->PartNumber= 6;
> +    SmbiosRecord->Attributes = (UINT8) ForType17InputData->MemoryState;
> +    SmbiosRecord->MemoryType = MemoryType;
> +
> +    OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
> +    UnicodeStrToAsciiStr(MemDevice, OptionalStrStart);
> +    UnicodeStrToAsciiStr(MemBankLocator, OptionalStrStart +
> MemDeviceStrLen + 1);
> +    UnicodeStrToAsciiStr(MemManufacturer, OptionalStrStart +
> MemDeviceStrLen + 1 + MemBankLocatorStrLen + 1);
> +    UnicodeStrToAsciiStr(MemSerialNumber, OptionalStrStart +
> MemDeviceStrLen + 1 + MemBankLocatorStrLen + 1 +
> MemManufacturerStrLen + 1);
> +    UnicodeStrToAsciiStr(MemAssetTag, OptionalStrStart +
> MemDeviceStrLen + 1 + MemBankLocatorStrLen + 1 +
> MemManufacturerStrLen + 1 + MemSerialNumberStrLen + 1);
> +    UnicodeStrToAsciiStr(MemPartNumber, OptionalStrStart +
> MemDeviceStrLen + 1 + MemBankLocatorStrLen + 1 +
> MemManufacturerStrLen + 1 + MemSerialNumberStrLen + 1+
> MemAssetTagStrLen+1 );
> +
> +    //
> +    // Now we have got the full smbios record, call smbios protocol to add this
> record.
> +    //
> +    SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +    Status = Smbios-> Add(
> +                        Smbios,
> +                        NULL,
> +                        &SmbiosHandle,
> +                        (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
> +                        );
> +    FreePool(SmbiosRecord);
> +    }
> +    return Status;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstalla
> bleLanguagesData.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstalla
> bleLanguagesData.c
> new file mode 100644
> index 0000000000..1b41d8fac7
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstalla
> bleLanguagesData.c
> @@ -0,0 +1,38 @@
> +/** @file
> +
> +Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscNumberOfInstallableLanguagesData.c
> +
> +Abstract:
> +
> +  Static data of the Number of installable languages information.
> +  Number of installable languages information is Misc. subclass type 11 and
> SMBIOS type 13.
> +
> +
> +**/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +//
> +// Static (possibly build generated) Bios Vendor data.
> +//
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_NUMBER_OF_INSTALLABLE_LANG
> UAGES_DATA, NumberOfInstallableLanguages)
> += {
> +  1,    // NumberOfInstallableLanguages
> +  {     // LanguageFlags
> +    1,  // AbbreviatedLanguageFormat
> +    0   // Reserved
> +  },
> +  STRING_TOKEN(STR_MISC_SYSTEM_LANGUAGE_EN_US)  //
> CurrentLanguageNumber
> +};
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstalla
> bleLanguagesFunction.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstalla
> bleLanguagesFunction.c
> new file mode 100644
> index 0000000000..4a96a2c465
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstalla
> bleLanguagesFunction.c
> @@ -0,0 +1,251 @@
> +/*++
> +
> +Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
> +
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +
> +
> +Module Name:
> +
> +  MiscNumberOfInstallableLanguagesFunction.c
> +
> +Abstract:
> +
> +  This driver parses the mSmbiosMiscDataTable structure and reports
> +  any generated data.
> +
> +--*/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +/**
> +  Check whether the language is supported for given HII handle
> +
> +  @param   HiiHandle     The HII package list handle.
> +  @param   Offset        The offest of current lanague in the supported
> languages.
> +  @param   CurrentLang   The language code.
> +
> +  @retval  TRUE          Supported.
> +  @retval  FALSE         Not Supported.
> +
> +**/
> +VOID
> +EFIAPI
> +CurrentLanguageMatch (
> +  IN  EFI_HII_HANDLE                   HiiHandle,
> +  OUT UINT16                           *Offset,
> +  OUT CHAR8                            *CurrentLang
> +  )
> +{
> +  CHAR8     *DefaultLang;
> +  CHAR8     *BestLanguage;
> +  CHAR8     *Languages;
> +  CHAR8     *MatchLang;
> +  CHAR8     *EndMatchLang;
> +  UINTN     CompareLength;
> +
> +  Languages = HiiGetSupportedLanguages (HiiHandle);
> +  if (Languages == NULL) {
> +    return;
> +  }
> +
> +  CurrentLang  = GetEfiGlobalVariable (L"PlatformLang");
> +  DefaultLang  = (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang);
> +  BestLanguage = GetBestLanguage (
> +                   Languages,
> +                   FALSE,
> +                   (CurrentLang != NULL) ? CurrentLang : "",
> +                   DefaultLang,
> +                   NULL
> +                   );
> +  if (BestLanguage != NULL) {
> +    //
> +    // Find the best matching RFC 4646 language, compute the offset.
> +    //
> +    CompareLength = AsciiStrLen (BestLanguage);
> +    for (MatchLang = Languages, (*Offset) = 0; *MatchLang != '\0';
> (*Offset)++) {
> +      //
> +      // Seek to the end of current match language.
> +      //
> +      for (EndMatchLang = MatchLang; *EndMatchLang != '\0' &&
> *EndMatchLang != ';'; EndMatchLang++);
> +
> +      if ((EndMatchLang == MatchLang + CompareLength) &&
> AsciiStrnCmp(MatchLang, BestLanguage, CompareLength) == 0) {
> +        //
> +        // Find the current best Language in the supported languages
> +        //
> +        break;
> +      }
> +      //
> +      // best language match be in the supported language.
> +      //
> +      ASSERT (*EndMatchLang == ';');
> +      MatchLang = EndMatchLang + 1;
> +    }
> +    FreePool (BestLanguage);
> +  }
> +
> +  FreePool (Languages);
> +  if (CurrentLang != NULL) {
> +    FreePool (CurrentLang);
> +  }
> +  return ;
> +}
> +
> +
> +/**
> +  Get next language from language code list (with separator ';').
> +
> +  @param  LangCode       Input: point to first language in the list. On
> +                         Otput: point to next language in the list, or
> +                                NULL if no more language in the list.
> +  @param  Lang           The first language in the list.
> +
> +**/
> +VOID
> +EFIAPI
> +GetNextLanguage (
> +  IN OUT CHAR8      **LangCode,
> +  OUT CHAR8         *Lang
> +  )
> +{
> +  UINTN  Index;
> +  CHAR8  *StringPtr;
> +
> +  ASSERT (LangCode != NULL);
> +  ASSERT (*LangCode != NULL);
> +  ASSERT (Lang != NULL);
> +
> +  Index     = 0;
> +  StringPtr = *LangCode;
> +  while (StringPtr[Index] != 0 && StringPtr[Index] != ';') {
> +    Index++;
> +  }
> +
> +  CopyMem (Lang, StringPtr, Index);
> +  Lang[Index] = 0;
> +
> +  if (StringPtr[Index] == ';') {
> +    Index++;
> +  }
> +  *LangCode = StringPtr + Index;
> +}
> +
> +/**
> +  This function returns the number of supported languages on HiiHandle.
> +
> +  @param   HiiHandle    The HII package list handle.
> +
> +  @retval  The number of supported languages.
> +
> +**/
> +UINT16
> +EFIAPI
> +GetSupportedLanguageNumber (
> +  IN EFI_HII_HANDLE    HiiHandle
> +  )
> +{
> +  CHAR8   *Lang;
> +  CHAR8   *Languages;
> +  CHAR8   *LanguageString;
> +  UINT16  LangNumber;
> +
> +  Languages = HiiGetSupportedLanguages (HiiHandle);
> +  if (Languages == NULL) {
> +    return 0;
> +  }
> +
> +  LangNumber = 0;
> +  Lang = AllocatePool (AsciiStrSize (Languages));
> +  if (Lang != NULL) {
> +    LanguageString = Languages;
> +    while (*LanguageString != 0) {
> +      GetNextLanguage (&LanguageString, Lang);
> +      LangNumber++;
> +    }
> +    FreePool (Lang);
> +  }
> +  FreePool (Languages);
> +  return LangNumber;
> +}
> +
> +
> +/**
> +  This function makes boot time changes to the contents of the
> +  MiscNumberOfInstallableLanguages (Type 13).
> +
> +  @param  RecordData                 Pointer to copy of RecordData from the Data
> Table.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
> +
> +**/
> +MISC_SMBIOS_TABLE_FUNCTION(NumberOfInstallableLanguages)
> +{
> +  UINTN                                     LangStrLen;
> +  CHAR8                                     CurrentLang[SMBIOS_STRING_MAX_LENGTH + 1];
> +  CHAR8                                     *OptionalStrStart;
> +  UINT16                                    Offset;
> +  EFI_STATUS                                Status;
> +  EFI_SMBIOS_HANDLE                         SmbiosHandle;
> +  SMBIOS_TABLE_TYPE13                       *SmbiosRecord;
> +  EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES
> *ForType13InputData;
> +
> +  ForType13InputData =
> (EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES *)RecordData;
> +
> +  //
> +  // First check for invalid parameters.
> +  //
> +  if (RecordData == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  ForType13InputData->NumberOfInstallableLanguages =
> GetSupportedLanguageNumber (mHiiHandle);
> +
> +  //
> +  // Try to check if current langcode matches with the langcodes in installed
> languages
> +  //
> +  ZeroMem(CurrentLang, SMBIOS_STRING_MAX_LENGTH + 1);
> +  CurrentLanguageMatch (mHiiHandle, &Offset, CurrentLang);
> +  LangStrLen = AsciiStrLen(CurrentLang);
> +
> +  //
> +  // Two zeros following the last string.
> +  //
> +  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE13) +
> LangStrLen + 1 + 1);
> +  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE13) + LangStrLen + 1
> + 1);
> +
> +  SmbiosRecord->Hdr.Type =
> EFI_SMBIOS_TYPE_BIOS_LANGUAGE_INFORMATION;
> +  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE13);
> +
> +  //
> +  // Make handle chosen by smbios protocol.add automatically.
> +  //
> +  SmbiosRecord->Hdr.Handle = 0;
> +
> +  SmbiosRecord->InstallableLanguages = (UINT8)ForType13InputData-
> >NumberOfInstallableLanguages;
> +  SmbiosRecord->Flags = (UINT8)ForType13InputData-
> >LanguageFlags.AbbreviatedLanguageFormat;
> +  SmbiosRecord->CurrentLanguages = 1;
> +  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
> +  AsciiStrCpy(OptionalStrStart, CurrentLang);
> +
> +  //
> +  // Now we have got the full smbios record, call smbios protocol to add this
> record.
> +  //
> +  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +  Status = Smbios-> Add(
> +                      Smbios,
> +                      NULL,
> +                      &SmbiosHandle,
> +                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
> +                      );
> +  FreePool(SmbiosRecord);
> +  return Status;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemString.uni
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemString.uni
> new file mode 100644
> index 0000000000..c6eb8bf498
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemString.uni
> @@ -0,0 +1,25 @@
> +// *++
> +//
> +// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//
> +// Module Name:
> +//
> +//   MiscOemSring.uni
> +//
> +// Abstract:
> +//
> +//   Language Information
> +//
> +// Revision History:
> +//
> +// --*/
> +
> +
> +/=#
> +
> +#langdef en-US "English"
> +#string STR_INTEL_ETK_VER               #language en-US  "ETK_VER_02.01"
> +#string STR_INTEL_ETK_VER_FOR_ROEM      #language en-US
> "ETK_VER_02.00"
> +#string STR_MISC_OEM_EN_US              #language en-US  "English (US)"
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringData.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringData.c
> new file mode 100644
> index 0000000000..ceecaad549
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringData.c
> @@ -0,0 +1,34 @@
> +/** @file
> +
> +Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +    MiscOemStringData.c
> +
> +Abstract:
> +
> +  Static data of OEM String information.
> +  OEM String information is Misc. subclass type 9 and SMBIOS type 11.
> +
> +
> +**/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +//
> +// Static (possibly build generated) Bios Vendor data.
> +//
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_OEM_STRING, MiscOemString) = {
> +  STRING_TOKEN(STR_INTEL_ETK_VER)
> +};
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_OEM_STRING_DATA, OemString)
> += { STRING_TOKEN(STR_MISC_OEM_EN_US) };
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringFunctio
> n.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringFunctio
> n.c
> new file mode 100644
> index 0000000000..8624481149
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringFunctio
> n.c
> @@ -0,0 +1,89 @@
> +/*++
> +
> +Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  MiscOemStringFunction.c
> +
> +Abstract:
> +
> +  boot information boot time changes.
> +  SMBIOS type 11.
> +
> +--*/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +/**
> +  This function makes boot time changes to the contents of the
> +  MiscOemString (Type 11).
> +
> +  @param  RecordData                 Pointer to copy of RecordData from the Data
> Table.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
> +
> +**/
> +MISC_SMBIOS_TABLE_FUNCTION(OemString)
> +{
> +  UINTN                    OemStrLen;
> +  CHAR8                    *OptionalStrStart;
> +  EFI_STATUS               Status;
> +  EFI_STRING               OemStr;
> +  STRING_REF               TokenToGet;
> +  EFI_SMBIOS_HANDLE        SmbiosHandle;
> +  SMBIOS_TABLE_TYPE11      *SmbiosRecord;
> +
> +  //
> +  // First check for invalid parameters.
> +  //
> +  if (RecordData == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_OEM_EN_US);
> +  OemStr = SmbiosMiscGetString (TokenToGet);
> +  OemStrLen = StrLen(OemStr);
> +  if (OemStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Two zeros following the last string.
> +  //
> +  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE11) +
> OemStrLen + 1 + 1);
> +  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE11) + OemStrLen +
> 1 + 1);
> +
> +  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_OEM_STRINGS;
> +  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE11);
> +
> +  //
> +  // Make handle chosen by smbios protocol.add automatically.
> +  //
> +  SmbiosRecord->Hdr.Handle = 0;
> +  SmbiosRecord->StringCount = 1;
> +  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
> +  UnicodeStrToAsciiStr(OemStr, OptionalStrStart);
> +
> +  //
> +  // Now we have got the full smbios record, call smbios protocol to add this
> record.
> +  //
> +  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +  Status = Smbios-> Add(
> +                      Smbios,
> +                      NULL,
> +                      &SmbiosHandle,
> +                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
> +                      );
> +  FreePool(SmbiosRecord);
> +  return Status;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90.uni
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90.uni
> new file mode 100644
> index 0000000000..917a7b9d6e
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90.uni
> @@ -0,0 +1,31 @@
> +// *++
> +//
> +// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//
> +// Module Name:
> +//
> +//   MiscOemType0x90.uni
> +//
> +// Abstract:
> +//
> +//   Firmware Version Information
> +//   SMBIOS type 0x90.
> +//
> +// Revision History:
> +//
> +// --*/
> +
> +
> +/=#
> +#langdef   en-US "English"
> +
> +#string STR_MISC_SEC_VERSION                #language en-US  "NA"
> +#string STR_MISC_UCODE_VERSION              #language en-US  "NA"
> +#string STR_MISC_GOP_VERSION                #language en-US  "NA"
> +#string STR_MISC_PROCESSOR_STEPPING         #language en-US  "NA"
> +
> +
> +
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Data
> .c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Dat
> a.c
> new file mode 100644
> index 0000000000..9b348813a7
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Dat
> a.c
> @@ -0,0 +1,36 @@
> +/*++
> +
> +Copyright (c) 2012  - 2014, Intel Corporation.  All rights reserved.
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +
> +Module Name:
> +
> +  MiscOemType0x90Data.c
> +
> +Abstract:
> +
> +  This file contains the Misc Oem Data (SMBIOS data type 0x90)
> +
> +--*/
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +
> +//
> +// Static (possibly build generated) Oem data.
> +//
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_OEM_TYPE_0x90,
> MiscOemType0x90) = {
> +
> +STRING_TOKEN (STR_MISC_SEC_VERSION),
> +STRING_TOKEN (STR_MISC_UCODE_VERSION),
> +STRING_TOKEN (STR_MISC_GOP_VERSION),
> +STRING_TOKEN (STR_MISC_PROCESSOR_STEPPING),
> +
> +};
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Fun
> ction.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Fun
> ction.c
> new file mode 100644
> index 0000000000..684cda83ec
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Fun
> ction.c
> @@ -0,0 +1,442 @@
> +/*++
> +
> +Copyright (c) 1999  - 2014, Intel Corporation.  All rights reserved.
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +
> +Module Name:
> +
> +  MiscOemType0x88Function.c
> +
> +Abstract:
> +
> +  The function that processes the Smbios data type 0x88 before they
> +  are submitted to Data Hub
> +
> +--*/
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +#include <Library/PrintLib.h>
> +#include <Library/CpuIA32.h>
> +#include <Protocol/DxeSmmReadyToLock.h>
> +
> +
> +VOID
> +GetCPUStepping ( )
> +{
> +  CHAR16    Buffer[40];
> +
> +  UINT16                                FamilyId;
> +  UINT8                                 Model;
> +  UINT8                                 SteppingId;
> +  UINT8                                 ProcessorType;
> +
> +
> +  EfiCpuVersion (&FamilyId, &Model, &SteppingId, &ProcessorType);
> +
> +  //
> +  //we need raw Model data
> +  //
> +  Model = Model & 0xf;
> +
> +  //
> +  //Family/Model/Step
> +  //
> +  UnicodeSPrint (Buffer, sizeof (Buffer), L"%d/%d/%d", FamilyId,  Model,
> SteppingId);
> +
> HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_PROCESSOR_STEPPING),
> Buffer, NULL);
> +
> +}
> +
> +EFI_STATUS
> +SearchChildHandle(
> +  EFI_HANDLE Father,
> +  EFI_HANDLE *Child
> +  )
> +{
> +  EFI_STATUS                                                 Status;
> +  UINTN                                                          HandleIndex;
> +  EFI_GUID                                                     **ProtocolGuidArray = NULL;
> +  UINTN                                                          ArrayCount;
> +  UINTN                                                          ProtocolIndex;
> +  UINTN                                                          OpenInfoCount;
> +  UINTN                                                          OpenInfoIndex;
> +  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY  *OpenInfo = NULL;
> +  UINTN                                                          mHandleCount;
> +  EFI_HANDLE                                                 *mHandleBuffer= NULL;
> +
> +  //
> +  // Retrieve the list of all handles from the handle database
> +  //
> +  Status = gBS->LocateHandleBuffer (
> +                  AllHandles,
> +                  NULL,
> +                  NULL,
> +                  &mHandleCount,
> +                  &mHandleBuffer
> +                  );
> +
> +  for (HandleIndex = 0; HandleIndex < mHandleCount; HandleIndex++) {
> +    //
> +    // Retrieve the list of all the protocols on each handle
> +    //
> +    Status = gBS->ProtocolsPerHandle (
> +                    mHandleBuffer[HandleIndex],
> +                    &ProtocolGuidArray,
> +                    &ArrayCount
> +                    );
> +    if (!EFI_ERROR (Status)) {
> +      for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
> +        Status = gBS->OpenProtocolInformation (
> +                        mHandleBuffer[HandleIndex],
> +                        ProtocolGuidArray[ProtocolIndex],
> +                        &OpenInfo,
> +                        &OpenInfoCount
> +                        );
> +
> +        if (!EFI_ERROR (Status)) {
> +          for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount;
> OpenInfoIndex++) {
> +            if(OpenInfo[OpenInfoIndex].AgentHandle == Father) {
> +              if ((OpenInfo[OpenInfoIndex].Attributes &
> EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) ==
> EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
> +                *Child = mHandleBuffer[HandleIndex];
> +		  Status = EFI_SUCCESS;
> +		  goto TryReturn;
> +              }
> +            }
> +          }
> +	   Status = EFI_NOT_FOUND;
> +       }
> +      }
> +      if(OpenInfo != NULL) {
> +        FreePool(OpenInfo);
> +	      OpenInfo = NULL;
> +      }
> +    }
> +    if(ProtocolGuidArray != NULL) {
> +    FreePool (ProtocolGuidArray);
> +    ProtocolGuidArray = NULL;
> +    }
> +  }
> +TryReturn:
> +  if(OpenInfo != NULL) {
> +    FreePool (OpenInfo);
> +    OpenInfo = NULL;
> +  }
> +  if(ProtocolGuidArray != NULL) {
> +    FreePool(ProtocolGuidArray);
> +    ProtocolGuidArray = NULL;
> +  }
> +  if(mHandleBuffer != NULL) {
> +    FreePool (mHandleBuffer);
> +    mHandleBuffer = NULL;
> +  }
> +  return Status;
> +}
> +
> +EFI_STATUS
> +JudgeHandleIsPCIDevice(
> +  EFI_HANDLE    Handle,
> +  UINT8            Device,
> +  UINT8            Funs
> +  )
> +{
> +  EFI_STATUS  Status;
> +  EFI_DEVICE_PATH   *DPath;
> +
> +  Status = gBS->HandleProtocol (
> +                  Handle,
> +                  &gEfiDevicePathProtocolGuid,
> +                  (VOID **) &DPath
> +                  );
> +  if(!EFI_ERROR(Status)) {
> +    while(!IsDevicePathEnd(DPath)) {
> +      if((DPath->Type == HARDWARE_DEVICE_PATH) && (DPath->SubType ==
> HW_PCI_DP)) {
> +        PCI_DEVICE_PATH   *PCIPath;
> +        PCIPath = (PCI_DEVICE_PATH*) DPath;
> +        DPath = NextDevicePathNode(DPath);
> +
> +        if(IsDevicePathEnd(DPath) && (PCIPath->Device == Device) &&
> (PCIPath->Function == Funs)) {
> +          return EFI_SUCCESS;
> +        }
> +      } else {
> +        DPath = NextDevicePathNode(DPath);
> +      }
> +    }
> +  }
> +  return EFI_UNSUPPORTED;
> +}
> +
> +EFI_STATUS
> +GetDriverName(
> +  EFI_HANDLE   Handle
> +)
> +{
> +  EFI_DRIVER_BINDING_PROTOCOL        *BindHandle = NULL;
> +  EFI_STATUS                         Status;
> +  UINT32                             Version;
> +  UINT16                             *Ptr;
> +  CHAR16                             Buffer[40];
> +  STRING_REF                  TokenToUpdate;
> +  Status = gBS->OpenProtocol(
> +                  Handle,
> +                  &gEfiDriverBindingProtocolGuid,
> +                  (VOID**)&BindHandle,
> +                   NULL,
> +                   NULL,
> +                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                   );
> +
> +  if (EFI_ERROR(Status)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  Version = BindHandle->Version;
> +  Ptr = (UINT16*)&Version;
> +  UnicodeSPrint(Buffer, sizeof (Buffer), L"%d.%d.%d", Version >> 24 ,
> (Version >>16)& 0x0f ,*(Ptr));
> +
> +  TokenToUpdate = (STRING_REF)STR_MISC_GOP_VERSION;
> +  HiiSetString(mHiiHandle, TokenToUpdate, Buffer, NULL);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +GetGOPDriverName()
> +{
> +  UINTN                         HandleCount;
> +  EFI_HANDLE                *Handles= NULL;
> +  UINTN                         Index;
> +  EFI_STATUS                Status;
> +  EFI_HANDLE                Child = 0;
> +
> +  Status = gBS->LocateHandleBuffer(
> +		              ByProtocol,
> +		              &gEfiDriverBindingProtocolGuid,
> +		              NULL,
> +		              &HandleCount,
> +		              &Handles
> +                  );
> +
> +  for (Index = 0; Index < HandleCount ; Index++) {
> +    Status = SearchChildHandle(Handles[Index], &Child);
> +    if(!EFI_ERROR(Status)) {
> +      Status = JudgeHandleIsPCIDevice(Child, 0x02, 0x00);
> +      if(!EFI_ERROR(Status)) {
> +        return GetDriverName(Handles[Index]);
> +      }
> +    }
> +  }
> +  return EFI_UNSUPPORTED;
> +}
> +
> +VOID
> +GetUcodeVersion()
> +{
> +  UINT32                   MicroCodeVersion;
> +  CHAR16                   Buffer[40];
> +
> +  //
> +  // Microcode Revision
> +  //
> +  EfiWriteMsr (EFI_MSR_IA32_BIOS_SIGN_ID, 0);
> +  EfiCpuid (EFI_CPUID_VERSION_INFO, NULL);
> +  MicroCodeVersion = (UINT32) RShiftU64 (EfiReadMsr
> (EFI_MSR_IA32_BIOS_SIGN_ID), 32);
> +  UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", MicroCodeVersion);
> +  HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_UCODE_VERSION),
> Buffer, NULL);
> +}
> +
> +/**
> +  Publish the smbios OEM type 0x90.
> +
> +  @param Event   - Event whose notification function is being invoked
> (gEfiDxeSmmReadyToLockProtocolGuid).
> +  @param Context - Pointer to the notification functions context, which is
> implementation dependent.
> +
> +  @retval None
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AddSmbiosT0x90Callback (
> +  IN EFI_EVENT  Event,
> +  IN VOID       *Context
> +  )
> +{
> +  EFI_STATUS            Status;
> +  UINTN                 SECVerStrLen = 0;
> +  UINTN                 uCodeVerStrLen = 0;
> +  UINTN                 GOPStrLen = 0;
> +  UINTN                 SteppingStrLen = 0;
> +  SMBIOS_TABLE_TYPE90    *SmbiosRecord;
> +  EFI_SMBIOS_HANDLE     SmbiosHandle;
> +  CHAR16                *SECVer;
> +  CHAR16                *uCodeVer;
> +  CHAR16                *GOPVer;
> +  CHAR16                *Stepping;
> +  STRING_REF            TokenToGet;
> +  CHAR8                 *OptionalStrStart;
> +  EFI_SMBIOS_PROTOCOL               *SmbiosProtocol;
> +
> +  DEBUG ((EFI_D_INFO, "Executing SMBIOS T0x90 callback.\n"));
> +
> +  gBS->CloseEvent (Event);    // Unload this event.
> +
> +  //
> +  // First check for invalid parameters.
> +  //
> +  if (Context == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiSmbiosProtocolGuid,
> +                  NULL,
> +                  (VOID *) &SmbiosProtocol
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  GetUcodeVersion();
> +  GetGOPDriverName();
> +  GetCPUStepping();
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_SEC_VERSION);
> +  SECVer = SmbiosMiscGetString (TokenToGet);
> +  SECVerStrLen = StrLen(SECVer);
> +  if (SECVerStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_UCODE_VERSION);
> +  uCodeVer = SmbiosMiscGetString (TokenToGet);
> +  uCodeVerStrLen = StrLen(uCodeVer);
> +  if (uCodeVerStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_GOP_VERSION);
> +  GOPVer = SmbiosMiscGetString (TokenToGet);
> +  GOPStrLen = StrLen(GOPVer);
> +  if (GOPStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_PROCESSOR_STEPPING);
> +  Stepping = SmbiosMiscGetString (TokenToGet);
> +  SteppingStrLen = StrLen(Stepping);
> +
> +
> +  if (SteppingStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE90) +
> SECVerStrLen + 1 + uCodeVerStrLen + 1 + GOPStrLen + 1 + SteppingStrLen + 1
> + 1);
> +  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE90) + SECVerStrLen
> + 1 + uCodeVerStrLen + 1 + GOPStrLen + 1 + SteppingStrLen + 1 + 1);
> +
> +  SmbiosRecord->Hdr.Type =
> EFI_SMBIOS_TYPE_FIRMWARE_VERSION_INFO;
> +  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE90);
> +
> +  //
> +  // Make handle chosen by smbios protocol.add automatically.
> +  //
> +  SmbiosRecord->Hdr.Handle = 0;
> +
> +  //
> +  // SEC VERSION will be the 1st optional string following the formatted
> structure.
> +  //
> +  SmbiosRecord->SECVersion = 0;
> +
> +  //
> +  // Microcode VERSION will be the 2nd optional string following the
> formatted structure.
> +  //
> +  SmbiosRecord->uCodeVersion = 2;
> +
> +  //
> +  // GOP VERSION will be the 3rd optional string following the formatted
> structure.
> +  //
> +  SmbiosRecord->GOPVersion = 3;
> +
> +  //
> +  // CPU Stepping will be the 4th optional string following the formatted
> structure.
> +  //
> +  SmbiosRecord->CpuStepping = 4;
> +
> +  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
> +  UnicodeStrToAsciiStr(SECVer, OptionalStrStart);
> +  UnicodeStrToAsciiStr(uCodeVer, OptionalStrStart + SECVerStrLen + 1);
> +  UnicodeStrToAsciiStr(GOPVer, OptionalStrStart + SECVerStrLen + 1 +
> uCodeVerStrLen + 1);
> +  UnicodeStrToAsciiStr(Stepping, OptionalStrStart + SECVerStrLen + 1 +
> uCodeVerStrLen + 1 + GOPStrLen + 1);
> +
> +  //
> +  // Now we have got the full smbios record, call smbios protocol to add this
> record.
> +  //
> +  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +  Status = SmbiosProtocol-> Add(
> +                              SmbiosProtocol,
> +                              NULL,
> +                              &SmbiosHandle,
> +                              (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
> +                              );
> +
> +  FreePool(SmbiosRecord);
> +  return Status;
> +}
> +
> +
> +/**
> +  This function makes boot time changes to the contents of the
> +  MiscOemType0x90 (Type 0x90).
> +
> +  @param  RecordData                 Pointer to copy of RecordData from the Data
> Table.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
> +
> +**/
> +MISC_SMBIOS_TABLE_FUNCTION(MiscOemType0x90)
> +{
> +  EFI_STATUS                    Status;
> +  static BOOLEAN                CallbackIsInstalledT0x90 = FALSE;
> +  VOID                           *AddSmbiosT0x90CallbackNotifyReg;
> +  EFI_EVENT                      AddSmbiosT0x90CallbackEvent;
> +
> +  //
> +  // This callback will create a OEM Type 0x90 record.
> +  //
> +  if (CallbackIsInstalledT0x90 == FALSE) {
> +    CallbackIsInstalledT0x90 = TRUE;        	// Prevent more than 1
> callback.
> +    DEBUG ((EFI_D_INFO, "Create Smbios T0x90 callback.\n"));
> +
> +  //
> +  // gEfiDxeSmmReadyToLockProtocolGuid is ready
> +  //
> +  Status = gBS->CreateEvent (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_CALLBACK,
> +                  (EFI_EVENT_NOTIFY)AddSmbiosT0x90Callback,
> +                  RecordData,
> +                  &AddSmbiosT0x90CallbackEvent
> +                  );
> +
> +  ASSERT_EFI_ERROR (Status);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +
> +  }
> +
> +  Status = gBS->RegisterProtocolNotify (
> +                  &gEfiDxeSmmReadyToLockProtocolGuid,
> +                  AddSmbiosT0x90CallbackEvent,
> +                  &AddSmbiosT0x90CallbackNotifyReg
> +                  );
> +
> +  return Status;
> +  }
> +
> +  return EFI_SUCCESS;
> +
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94.uni
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94.uni
> new file mode 100644
> index 0000000000..2c8bf4ce49
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94.uni
> @@ -0,0 +1,42 @@
> +// *++
> +//
> +// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//
> +// Module Name:
> +//
> +//   MiscOemType0x94.uni
> +//
> +// Abstract:
> +//
> +//   Firmware Version Information
> +//   SMBIOS type 0x94.
> +//
> +// Revision History:
> +//
> +// --*/
> +
> +
> +/=#
> +#langdef   en-US "English"
> +
> +#string STR_MISC_PMIC_VERSION                #language en-US  "NA"
> +#string STR_MISC_TOUCH_VERSION               #language en-US  "NA"
> +#string STR_MISC_PROCESSOR_MICROCODE_VALUE        #language en-US
> "NA"
> +#string STR_MISC_ULPMC_FW_VALUE                   #language en-US  "NA"
> +#string STR_MISC_PUNIT_FW_VALUE                   #language en-US  "NA"
> +#string STR_MISC_PMC_FW_VALUE                     #language en-US  "NA"
> +#string STR_MISC_SOC_VALUE                        #language en-US  "NA"
> +#string STR_MISC_MRC_VERSION_VALUE                #language en-US  "NA"
> +#string STR_MISC_BOARD_ID_VALUE                   #language en-US  "NA"
> +#string STR_MISC_FAB_ID_VALUE                     #language en-US  "NA"
> +#string STR_MISC_CPU_FLAVOR_VALUE                 #language en-US  "NA"
> +#string STR_MISC_SECURE_BOOT                      #language en-US  "NA"
> +#string STR_MISC_BOOT_MODE                        #language en-US  "NA"
> +#string STR_MISC_SPEED_STEP                       #language en-US  "NA"
> +#string STR_MISC_CPU_TURBO                        #language en-US  "NA"
> +#string STR_MISC_CSTATE                           #language en-US  "NA"
> +#string STR_MISC_GFX_TURBO                        #language en-US  "NA"
> +#string STR_MISC_S0IX_VALUE                       #language en-US  "NA"
> +#string STR_MISC_RC6_VALUE                        #language en-US  "NA"
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Data
> .c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Dat
> a.c
> new file mode 100644
> index 0000000000..8709d61847
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Dat
> a.c
> @@ -0,0 +1,54 @@
> +/*++
> +
> +Copyright (c) 2012  - 2014, Intel Corporation.  All rights reserved.
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +
> +Module Name:
> +
> +  MiscOemType0x94Data.c
> +
> +Abstract:
> +
> +  This file contains the Misc version Data (SMBIOS data type 0x94)
> +
> +--*/
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +
> +//
> +// Static (possibly build generated) Oem data.
> +//
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_OEM_TYPE_0x94,
> MiscOemType0x94) = {
> +
> +STRING_TOKEN (STR_MISC_GOP_VERSION),
> +STRING_TOKEN (STR_MISC_SEC_VERSION),
> +STRING_TOKEN (STR_MISC_MRC_VERSION_VALUE),
> +STRING_TOKEN (STR_MISC_UCODE_VERSION),
> +STRING_TOKEN (STR_MISC_PUNIT_FW_VALUE),
> +STRING_TOKEN (STR_MISC_PMC_FW_VALUE),
> +STRING_TOKEN (STR_MISC_ULPMC_FW_VALUE),
> +STRING_TOKEN (STR_MISC_SOC_VALUE),
> +STRING_TOKEN (STR_MISC_BOARD_ID_VALUE),
> +STRING_TOKEN (STR_MISC_FAB_ID_VALUE),
> +STRING_TOKEN (STR_MISC_CPU_FLAVOR_VALUE),
> +STRING_TOKEN (STR_MISC_BIOS_VERSION),
> +STRING_TOKEN (STR_MISC_PMIC_VERSION),
> +STRING_TOKEN (STR_MISC_TOUCH_VERSION),
> +STRING_TOKEN (STR_MISC_SECURE_BOOT),
> +STRING_TOKEN (STR_MISC_BOOT_MODE),
> +STRING_TOKEN (STR_MISC_SPEED_STEP),
> +STRING_TOKEN (STR_MISC_CPU_TURBO),
> +STRING_TOKEN (STR_MISC_CSTATE),
> +STRING_TOKEN (STR_MISC_GFX_TURBO),
> +STRING_TOKEN (STR_MISC_S0IX_VALUE),
> +STRING_TOKEN (STR_MISC_RC6_VALUE),
> +
> +};
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Fun
> ction.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Fun
> ction.c
> new file mode 100644
> index 0000000000..15c180129c
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Fun
> ction.c
> @@ -0,0 +1,1218 @@
> +/*++
> +
> +Copyright (c) 1999  - 2014, Intel Corporation.  All rights reserved.
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +
> +Module Name:
> +
> +  MiscOemType0x94Function.c
> +
> +Abstract:
> +
> +  The function that processes the Smbios data type 0x94.
> +
> +--*/
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +#include <Protocol/DataHub.h>
> +#include <Library/HiiLib.h>
> +#include <Protocol/CpuIo2.h>
> +#include <Library/PrintLib.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +#include <Protocol/SimpleNetwork.h>
> +#include <Protocol/DevicePath.h>
> +#include <Protocol/DiskInfo.h>
> +#include <Protocol/IdeControllerInit.h>
> +#include <Protocol/MpService.h>
> +#include <Protocol/PchPlatformPolicy.h>
> +#include <Protocol/CpuIo2.h>
> +#include <Protocol/I2cBus.h>
> +
> +#include <Library/IoLib.h>
> +#include <Library/I2CLib.h>
> +#include <Library/CpuIA32.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Guid/PlatformInfo.h>
> +#include <Guid/SetupVariable.h>
> +#include <Guid/Vlv2Variable.h>
> +
> +#include "Valleyview.h"
> +#include "VlvAccess.h"
> +#include "PchAccess.h"
> +#include "SetupMode.h"
> +#include "PchCommonDefinitions.h"
> +#include <PlatformBaseAddresses.h>
> +
> +typedef struct {
> +  UINT8 RevId;
> +  CHAR8 String[16];
> +} SB_REV;
> +
> +//
> +// Silicon Steppings
> +//
> +SB_REV  SBRevisionTable[] = {
> +  {V_PCH_LPC_RID_0, "(A0 Stepping)"},
> +  {V_PCH_LPC_RID_1, "(A0 Stepping)"},
> +  {V_PCH_LPC_RID_2, "(A1 Stepping)"},
> +  {V_PCH_LPC_RID_3, "(A1 Stepping)"},
> +  {V_PCH_LPC_RID_4, "(B0 Stepping)"},
> +  {V_PCH_LPC_RID_5, "(B0 Stepping)"},
> +  {V_PCH_LPC_RID_6, "(B1 Stepping)"},
> +  {V_PCH_LPC_RID_7, "(B1 Stepping)"},
> +  {V_PCH_LPC_RID_8, "(B2 Stepping)"},
> +  {V_PCH_LPC_RID_9, "(B2 Stepping)"},
> +  {V_PCH_LPC_RID_A, "(B3 Stepping)"},
> +  {V_PCH_LPC_RID_B, "(B3 Stepping)"}
> +};
> +
> +#define LEFT_JUSTIFY  0x01
> +#define PREFIX_SIGN   0x02
> +#define PREFIX_BLANK  0x04
> +#define COMMA_TYPE    0x08
> +#define LONG_TYPE     0x10
> +#define PREFIX_ZERO   0x20
> +
> +#define ICH_REG_REV                 0x08
> +#define MSR_IA32_PLATFORM_ID        0x17
> +#define CHARACTER_NUMBER_FOR_VALUE  30
> +
> +
> +UINT8  ReadBuffer[20];  //Version report length
> +UINT8  WriteBuffer[22] =
> {0x40,0x01,0x14,0x00,0x06,0x51,0x02,0x07,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
> //Version request
> +
> +/**
> +
> +  VSPrint worker function that prints a Value as a decimal number in Buffer
> +
> +  @param Buffer  Location to place ascii decimal number string of Value.
> +  @param Value   Decimal value to convert to a string in Buffer.
> +  @param Flags   Flags to use in printing decimal string, see file header for
> details.
> +  @param Width   Width of hex value.
> +
> +  @retval Number of characters printed.
> +
> +**/
> +UINTN
> +EfiValueToString (
> +  IN  OUT CHAR16  *Buffer,
> +  IN  INT64       Value,
> +  IN  UINTN       Flags,
> +  IN  UINTN       Width
> +  )
> +{
> +  CHAR16    TempBuffer[CHARACTER_NUMBER_FOR_VALUE];
> +  CHAR16    *TempStr;
> +  CHAR16    *BufferPtr;
> +  UINTN     Count;
> +  UINTN     ValueCharNum;
> +  UINTN     Remainder;
> +  CHAR16    Prefix;
> +  UINTN     Index;
> +  BOOLEAN   ValueIsNegative;
> +  UINT64    TempValue;
> +
> +  TempStr         = TempBuffer;
> +  BufferPtr       = Buffer;
> +  Count           = 0;
> +  ValueCharNum    = 0;
> +  ValueIsNegative = FALSE;
> +
> +  if (Width > CHARACTER_NUMBER_FOR_VALUE - 1) {
> +    Width = CHARACTER_NUMBER_FOR_VALUE - 1;
> +  }
> +
> +  if (Value < 0) {
> +    Value           = -Value;
> +    ValueIsNegative = TRUE;
> +  }
> +
> +  do {
> +    TempValue = Value;
> +    Value = (INT64)DivU64x32 ((UINT64)Value, 10);
> +    Remainder = (UINTN)((UINT64)TempValue - 10 * Value);
> +    *(TempStr++) = (CHAR16)(Remainder + '0');
> +    ValueCharNum++;
> +    Count++;
> +    if ((Flags & COMMA_TYPE) == COMMA_TYPE) {
> +      if (ValueCharNum % 3 == 0 && Value != 0) {
> +        *(TempStr++) = ',';
> +        Count++;
> +      }
> +    }
> +  } while (Value != 0);
> +
> +  if (ValueIsNegative) {
> +    *(TempStr++)    = '-';
> +    Count++;
> +  }
> +
> +  if ((Flags & PREFIX_ZERO) && !ValueIsNegative) {
> +    Prefix = '0';
> +  } else {
> +    Prefix = ' ';
> +  }
> +
> +  Index = Count;
> +  if (!(Flags & LEFT_JUSTIFY)) {
> +    for (; Index < Width; Index++) {
> +      *(TempStr++) = Prefix;
> +    }
> +  }
> +
> +  //
> +  // Reverse temp string into Buffer.
> +  //
> +  if (Width > 0 && (UINTN) (TempStr - TempBuffer) > Width) {
> +    TempStr = TempBuffer + Width;
> +  }
> +  Index = 0;
> +  while (TempStr != TempBuffer) {
> +    *(BufferPtr++) = *(--TempStr);
> +    Index++;
> +  }
> +
> +  *BufferPtr = 0;
> +  return Index;
> +}
> +
> +static CHAR16 mHexStr[] = { L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7',
> +                            L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F' };
> +/**
> +  VSPrint worker function that prints a Value as a hex number in Buffer
> +
> +  @param Buffer   Location to place ascii hex string of Value.
> +  @param Value    Hex value to convert to a string in Buffer.
> +  @param Flags    Flags to use in printing Hex string, see file header for
> details.
> +  @param Width    Width of hex value.
> +
> +  @retval Number of characters printed.
> +
> +**/
> +UINTN
> +EfiValueToHexStr (
> +  IN  OUT CHAR16  *Buffer,
> +  IN  UINT64      Value,
> +  IN  UINTN       Flags,
> +  IN  UINTN       Width
> +  )
> +{
> +  CHAR16  TempBuffer[CHARACTER_NUMBER_FOR_VALUE];
> +  CHAR16  *TempStr;
> +  CHAR16  Prefix;
> +  CHAR16  *BufferPtr;
> +  UINTN   Count;
> +  UINTN   Index;
> +
> +  TempStr   = TempBuffer;
> +  BufferPtr = Buffer;
> +
> +  //
> +  // Count starts at one since we will null terminate. Each iteration of the
> +  // loop picks off one nibble. Oh yea TempStr ends up backwards
> +  //
> +  Count = 0;
> +
> +  if (Width > CHARACTER_NUMBER_FOR_VALUE - 1) {
> +    Width = CHARACTER_NUMBER_FOR_VALUE - 1;
> +  }
> +
> +  do {
> +    Index = ((UINTN)Value & 0xf);
> +    *(TempStr++) = mHexStr[Index];
> +    Value = RShiftU64 (Value, 4);
> +    Count++;
> +  } while (Value != 0);
> +
> +  if (Flags & PREFIX_ZERO) {
> +    Prefix = '0';
> +  } else {
> +    Prefix = ' ';
> +  }
> +
> +  Index = Count;
> +  if (!(Flags & LEFT_JUSTIFY)) {
> +    for (; Index < Width; Index++) {
> +      *(TempStr++) = Prefix;
> +    }
> +  }
> +
> +  //
> +  // Reverse temp string into Buffer.
> +  //
> +  if (Width > 0 && (UINTN) (TempStr - TempBuffer) > Width) {
> +    TempStr = TempBuffer + Width;
> +  }
> +  Index = 0;
> +  while (TempStr != TempBuffer) {
> +    *(BufferPtr++) = *(--TempStr);
> +    Index++;
> +  }
> +
> +  *BufferPtr = 0;
> +  return Index;
> +}
> +
> +/**
> +  Converts MAC address to Unicode string.
> +  The value is 64-bit and the resulting string will be 12
> +  digit hex number in pairs of digits separated by dashes.
> +
> +  @param String - string that will contain the value
> +  @param Val    - value to convert
> +
> +**/
> +CHAR16 *
> +StrMacToString (
> +  OUT CHAR16              *String,
> +  IN  EFI_MAC_ADDRESS     *MacAddr,
> +  IN  UINT32              AddrSize
> +  )
> +{
> +  UINT32  i;
> +
> +  for (i = 0; i < AddrSize; i++) {
> +
> +    EfiValueToHexStr (
> +      &String[2 * i],
> +      MacAddr->Addr[i] & 0xFF,
> +      PREFIX_ZERO,
> +      2
> +      );
> +  }
> +
> +  //
> +  // Terminate the string.
> +  //
> +  String[2 * AddrSize] = L'\0';
> +
> +  return String;
> +}
> +
> +
> +
> +EFI_STATUS
> +TJudgeHandleIsPCIDevice(
> +  EFI_HANDLE    Handle,
> +  UINT8            Device,
> +  UINT8            Funs
> +)
> +{
> +  EFI_STATUS  Status;
> +  EFI_DEVICE_PATH   *DPath;
> +  EFI_DEVICE_PATH   *DevicePath;
> +
> +  Status = gBS->HandleProtocol (
> +                  Handle,
> +                  &gEfiDevicePathProtocolGuid,
> +                  (VOID **) &DPath
> +                  );
> +  if(!EFI_ERROR(Status))
> +  {
> +    DevicePath = DPath;
> +    while(!IsDevicePathEnd(DPath))
> +    {
> +      if((DPath->Type == HARDWARE_DEVICE_PATH) && (DPath->SubType ==
> HW_PCI_DP))
> +      {
> +        PCI_DEVICE_PATH   *PCIPath;
> +
> +        PCIPath = (PCI_DEVICE_PATH*) DPath;
> +        DPath = NextDevicePathNode(DPath);
> +        if(IsDevicePathEnd(DPath) && (PCIPath->Device == Device) &&
> (PCIPath->Function == Funs))
> +        {
> +          return EFI_SUCCESS;
> +        }
> +      }
> +      else
> +      {
> +        DPath = NextDevicePathNode(DPath);
> +      }
> +    }
> +  }
> +  return EFI_UNSUPPORTED;
> +}
> +
> +EFI_STATUS
> +TSearchChildHandle(
> +  EFI_HANDLE Father,
> +  EFI_HANDLE *Child
> +  )
> +{
> +  EFI_STATUS                                                 Status;
> +  UINTN                                                          HandleIndex;
> +  EFI_GUID                                                     **ProtocolGuidArray = NULL;
> +  UINTN                                                          ArrayCount;
> +  UINTN                                                          ProtocolIndex;
> +  UINTN                                                          OpenInfoCount;
> +  UINTN                                                          OpenInfoIndex;
> +  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY  *OpenInfo = NULL;
> +  UINTN                                                          mHandleCount;
> +  EFI_HANDLE                                                 *mHandleBuffer= NULL;
> +
> +  //
> +  // Retrieve the list of all handles from the handle database
> +  //
> +  Status = gBS->LocateHandleBuffer (
> +                  AllHandles,
> +                  NULL,
> +                  NULL,
> +                  &mHandleCount,
> +                  &mHandleBuffer
> +                  );
> +
> +  for (HandleIndex = 0; HandleIndex < mHandleCount; HandleIndex++)
> +  {
> +    //
> +    // Retrieve the list of all the protocols on each handle
> +    //
> +    Status = gBS->ProtocolsPerHandle (
> +                    mHandleBuffer[HandleIndex],
> +                    &ProtocolGuidArray,
> +                    &ArrayCount
> +                    );
> +    if (!EFI_ERROR (Status))
> +    {
> +      for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++)
> +      {
> +        Status = gBS->OpenProtocolInformation (
> +                        mHandleBuffer[HandleIndex],
> +                        ProtocolGuidArray[ProtocolIndex],
> +                        &OpenInfo,
> +                        &OpenInfoCount
> +                        );
> +        if (!EFI_ERROR (Status))
> +        {
> +          for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount;
> OpenInfoIndex++)
> +          {
> +            if(OpenInfo[OpenInfoIndex].AgentHandle == Father)
> +            {
> +              if ((OpenInfo[OpenInfoIndex].Attributes &
> EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) ==
> EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER)
> +              {
> +                *Child = mHandleBuffer[HandleIndex];
> +		  Status = EFI_SUCCESS;
> +		  goto TryReturn;
> +              }
> +            }
> +          }
> +	   Status = EFI_NOT_FOUND;
> +        }
> +      }
> +      if(OpenInfo != NULL)
> +      {
> +        FreePool(OpenInfo);
> +	 OpenInfo = NULL;
> +      }
> +    }
> +    FreePool (ProtocolGuidArray);
> +    ProtocolGuidArray = NULL;
> +  }
> +TryReturn:
> +  if(OpenInfo != NULL)
> +  {
> +    FreePool (OpenInfo);
> +    OpenInfo = NULL;
> +  }
> +  if(ProtocolGuidArray != NULL)
> +  {
> +    FreePool(ProtocolGuidArray);
> +    ProtocolGuidArray = NULL;
> +  }
> +  if(mHandleBuffer != NULL)
> +  {
> +    FreePool (mHandleBuffer);
> +    mHandleBuffer = NULL;
> +  }
> +  return Status;
> +}
> +
> +EFI_STATUS
> +TGetDriverName(
> +  EFI_HANDLE   Handle,
> +  CHAR16         *Name
> +)
> +{
> +  EFI_DRIVER_BINDING_PROTOCOL        *BindHandle = NULL;
> +  EFI_STATUS                                        Status;
> +  UINT32                                               Version;
> +  UINT16                                               *Ptr;
> +  Status = gBS->OpenProtocol(
> +                  Handle,
> +                  &gEfiDriverBindingProtocolGuid,
> +                                   (VOID**)&BindHandle,
> +                  NULL,
> +                  NULL,
> +                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                  );
> +
> +  if (EFI_ERROR(Status))
> +  {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  Version = BindHandle->Version;
> +  Ptr = (UINT16*)&Version;
> +  UnicodeSPrint(Name, 40, L"%d.%d.%d", Version >> 24 , (Version >>16)&
> 0x0f ,*(Ptr));
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +TGetGOPDriverName(
> +  CHAR16 *Name
> +)
> +{
> +  UINTN                         HandleCount;
> +  EFI_HANDLE                *Handles= NULL;
> +  UINTN                         Index;
> +  EFI_STATUS                Status;
> +  EFI_HANDLE                Child = 0;
> +
> +  Status = gBS->LocateHandleBuffer(
> +		              ByProtocol,
> +		              &gEfiDriverBindingProtocolGuid,
> +		              NULL,
> +		              &HandleCount,
> +		              &Handles
> +                  );
> +  for (Index = 0; Index < HandleCount ; Index++)
> +  {
> +    Status = TSearchChildHandle(Handles[Index], &Child);
> +    if(!EFI_ERROR(Status))
> +    {
> +      Status = TJudgeHandleIsPCIDevice(Child, 0x02, 0x00);
> +      if(!EFI_ERROR(Status))
> +      {
> +        return TGetDriverName(Handles[Index], Name);
> +      }
> +    }
> +  }
> +  return EFI_UNSUPPORTED;
> +}
> +
> +EFI_STATUS
> +TGetTouchFirmwareVersion(
> + )
> +{
> + EFI_STATUS rc=EFI_SUCCESS;
> + UINTN      TouchVer = 0;
> + UINTN     Size = sizeof(UINTN);
> +
> +
> + CHAR16     Buffer[40];
> +
> + rc = gRT->GetVariable(
> +             L"TouchVer",
> +             &gEfiVlv2VariableGuid,
> +             NULL,
> +             &Size,
> +             &TouchVer
> +             );
> + if(!EFI_ERROR(rc)){
> +  UnicodeSPrint(Buffer, sizeof(Buffer), L"%02x.%02x",
> (TouchVer&0xFFFF)>>8,TouchVer&0xFF);
> +  HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_TOUCH_VERSION),
> Buffer, NULL);
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +UpdatePlatformInformation (
> +  )
> +{
> +  UINT32                   MicroCodeVersion;
> +  CHAR16                   Buffer[40];
> +  UINT8                    IgdVBIOSRevH;
> +  UINT8                    IgdVBIOSRevL;
> +  UINT16                   EDX;
> +  EFI_IA32_REGISTER_SET    RegSet;
> +  EFI_LEGACY_BIOS_PROTOCOL *LegacyBios = NULL;
> +  EFI_STATUS               Status;
> +  UINT8                    CpuFlavor=0;
> +  EFI_PEI_HOB_POINTERS     GuidHob;
> +  EFI_PLATFORM_INFO_HOB    *mPlatformInfo=NULL;
> +  UINTN                    NumHandles;
> +  EFI_HANDLE                        *HandleBuffer;
> +  UINTN                             Index;
> +  DXE_PCH_PLATFORM_POLICY_PROTOCOL  *PchPlatformPolicy;
> +  UINTN                             PciD31F0RegBase;
> +  UINT8                             count;
> +  UINT8                             Data8;
> +  UINT8                             Data8_1;
> +
> +  CHAR16                            Name[40];
> +  UINT32                            MrcVersion;
> +
> +  UINT8					KscFwRevH =0;
> +  UINT8					KscFwRevL =0;
> +
> +  //
> +  // 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);
> +    }
> +  }
> +
> +  //
> +  //VBIOS version
> +  //
> +  Status = gBS->LocateProtocol(
> +                  &gEfiLegacyBiosProtocolGuid,
> +                  NULL,
> +                  (VOID **)&LegacyBios
> +                  );
> +
> +  RegSet.X.AX = 0x5f01;
> +  Status = LegacyBios->Int86 (LegacyBios, 0x10, &RegSet);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  //
> +  // simulate AMI int15 (ax=5f01) handler
> +  // check NbInt15.asm in AMI code for asm edition
> +  //
> +  EDX = (UINT16)((RegSet.E.EBX >> 16) & 0xffff);
> +  IgdVBIOSRevH = (UINT8)(((EDX & 0x0F00) >> 4) | (EDX & 0x000F));
> +  IgdVBIOSRevL = (UINT8)(((RegSet.X.BX & 0x0F00) >> 4) | (RegSet.X.BX &
> 0x000F));
> +
> +  if (IgdVBIOSRevH==0 && IgdVBIOSRevL==0) {
> +    HiiSetString(mHiiHandle,
> STRING_TOKEN(STR_CHIP_IGD_VBIOS_REV_VALUE), L"N/A", NULL);
> +  } else {
> +    UnicodeSPrint (Buffer, sizeof (Buffer), L"%02X%02X",
> IgdVBIOSRevH,IgdVBIOSRevL);
> +    HiiSetString(mHiiHandle,
> STRING_TOKEN(STR_CHIP_IGD_VBIOS_REV_VALUE), Buffer, NULL);
> +  }
> +
> +  Status = TGetGOPDriverName(Name);
> +
> +  if(!EFI_ERROR(Status))
> +  {
> +    HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_GOP_VERSION),
> Name, NULL);
> +  }
> +
> +  //
> +  //CpuFlavor
> +  //
> +  //VLV
> +  //VLV-DC Tablet        000
> +  //VLV-QC Notebook      001
> +  //VLV-QC Desktop       010
> +  //
> +  //CPU flavor
> +  //
> +  CpuFlavor = RShiftU64 (EfiReadMsr (MSR_IA32_PLATFORM_ID), 50) & 0x07;
> +
> +  switch(CpuFlavor){
> +    case 0x0:
> +        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-DC Tablet",
> CpuFlavor);
> +        break;
> +    case 0x01:
> +        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC
> Notebook", CpuFlavor);
> +        break;
> +    case 0x02:
> +        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC
> Desktop", CpuFlavor);
> +        break;
> +    case 0x03:
> +        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC
> Notebook", CpuFlavor);
> +        break;
> +    default:
> +        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"Unknown CPU",
> CpuFlavor);
> +        break;
> +  }
> +
> HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_CPU_FLAVOR_VALUE),
> Buffer, NULL);
> +
> +  if ( NULL != mPlatformInfo) {
> +    //
> +    // Board Id
> +    //
> +    UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", mPlatformInfo->BoardId);
> +    HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_BOARD_ID_VALUE),
> Buffer, NULL);
> +
> +    //
> +    // FAB ID
> +    //
> +    UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", mPlatformInfo->BoardRev);
> +    HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_FAB_ID_VALUE),
> Buffer, NULL);
> +  }
> +
> +  //
> +  //Update MRC Version
> +  //
> +  MrcVersion = MmioRead32 (MmPciAddress (0, 0, 0, 0, 0xF0));
> +  MrcVersion &= 0xffff;
> +  Index = EfiValueToString (Buffer, MrcVersion/100, PREFIX_ZERO, 0);
> +  StrCat (Buffer, L".");
> +  EfiValueToString (Buffer + Index + 1, (MrcVersion%100)/10, PREFIX_ZERO,
> 0);
> +  EfiValueToString (Buffer + Index + 2, (MrcVersion%100)%10, PREFIX_ZERO,
> 0);
> +
> HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_MRC_VERSION_VALUE),
> Buffer, NULL);
> +
> +  //
> +  //Update Soc Version
> +  //
> +
> +  //
> +  // Retrieve all instances of PCH Platform Policy protocol
> +  //
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gDxePchPlatformPolicyProtocolGuid,
> +                  NULL,
> +                  &NumHandles,
> +                  &HandleBuffer
> +                  );
> +  if (!EFI_ERROR (Status)) {
> +    //
> +    // Find the matching PCH Policy protocol
> +    //
> +    for (Index = 0; Index < NumHandles; Index++) {
> +      Status = gBS->HandleProtocol (
> +                      HandleBuffer[Index],
> +                      &gDxePchPlatformPolicyProtocolGuid,
> +                      (VOID **) &PchPlatformPolicy
> +                      );
> +      if (!EFI_ERROR (Status)) {
> +        PciD31F0RegBase = MmPciAddress (
> +                            0,
> +                            PchPlatformPolicy->BusNumber,
> +                            PCI_DEVICE_NUMBER_PCH_LPC,
> +                            PCI_FUNCTION_NUMBER_PCH_LPC,
> +                            0
> +                            );
> +
> +         Data8 = MmioRead8 (PciD31F0RegBase + R_PCH_LPC_RID_CC);
> +         count = ARRAY_SIZE (SBRevisionTable);
> +         for (Index = 0; Index < count; Index++) {
> +           if(Data8 == SBRevisionTable[Index].RevId) {
> +              UnicodeSPrint (Buffer, sizeof (Buffer), L"%02x %a", Data8,
> SBRevisionTable[Index].String);
> +              HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SOC_VALUE),
> Buffer, NULL);
> +             break;
> +           }
> +         }
> +        break;
> +      }
> +    }
> +  }
> +
> +  //
> +  // Microcode Revision
> +  //
> +  EfiWriteMsr (EFI_MSR_IA32_BIOS_SIGN_ID, 0);
> +  EfiCpuid (EFI_CPUID_VERSION_INFO, NULL);
> +  MicroCodeVersion = (UINT32) RShiftU64 (EfiReadMsr
> (EFI_MSR_IA32_BIOS_SIGN_ID), 32);
> +  UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", MicroCodeVersion);
> +
> HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_PROCESSOR_MICROCO
> DE_VALUE), Buffer, NULL);
> +
> +
> +  //
> +  //Secure boot
> +  //
> +  Data8 = SystemConfiguration.SecureBoot;
> +  UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8);
> +  HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_SECURE_BOOT),
> Buffer, NULL);
> +
> +  //
> +  //Bootmode
> +  //
> +  BootMode = GetBootModeHob();
> +  UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", BootMode);
> +  HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_BOOT_MODE), Buffer,
> NULL);
> +
> +  //
> +  //SpeedStep
> +  //
> +  Data8 = 1;
> +  UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8);
> +  HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_SPEED_STEP), Buffer,
> NULL);
> +
> +  //
> +  //CPU Turbo
> +  //
> +  Data8 = 2;
> +  UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8);
> +  HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_CPU_TURBO), Buffer,
> NULL);
> +
> +  //
> +  //CState
> +  //
> +  Data8 = 3;
> +  UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8);
> +  HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_CSTATE), Buffer,
> NULL);
> +
> +  //
> +  //GFX Turbo
> +  //
> +  Data8 = SystemConfiguration.IgdTurboEnabled;
> +  UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8);
> +  HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_GFX_TURBO), Buffer,
> NULL);
> +
> +  Data8 = 0;
> +  UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8);
> +  HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_S0IX_VALUE), Buffer,
> NULL);
> +
> +  //
> +  //RC6
> +  //
> +  Data8 = 0;
> +  UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8);
> +  HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_RC6_VALUE), Buffer,
> NULL);
> +
> +  //
> +  // Punit Version
> +  //
> +  Data8 = 0;
> +  UnicodeSPrint (Buffer, sizeof (Buffer), L"0x%x", Data8);
> +  HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_PUNIT_FW_VALUE),
> Buffer, NULL);
> +
> +  //
> +  //  PMC Version
> +  //
> +  Data8 = (UINT8)((MmioRead32 (PMC_BASE_ADDRESS +
> R_PCH_PMC_PRSTS)>>16)&0x00FF);
> +  Data8_1 = (UINT8)((MmioRead32 (PMC_BASE_ADDRESS +
> R_PCH_PMC_PRSTS)>>24)&0x00FF);
> +  UnicodeSPrint (Buffer, sizeof (Buffer), L"0x%X_%X", Data8_1, Data8);
> +  HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_PMC_FW_VALUE),
> Buffer, NULL);
> +
> +  //
> +  //PMIC Version
> +  //
> +  Status = ByteReadI2C(PMICI2cBus, PMICI2cAdd, PMICVendorOffset, 1,
> &Data8);
> +  if(!EFI_ERROR(Status)){
> +  	Status = ByteReadI2C(PMICI2cBus, PMICI2cAdd, PMICRevOffset, 1,
> &Data8_1);
> +	if(!EFI_ERROR(Status)){
> +      UnicodeSPrint(Buffer, sizeof(Buffer), L"%02x.%02x", Data8, Data8_1);
> +      HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_PMIC_VERSION),
> Buffer, NULL);
> +	}
> +  }
> +
> +  TGetTouchFirmwareVersion();
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Smbios OEM type 0x94 callback.
> +
> +  @param Event    Event whose notification function is being invoked.
> +  @param Context  Pointer to the notification functions context, which is
> implementation dependent.
> +
> +  @retval None
> +
> +**/
> +VOID
> +AddSmbiosT0x94Callback (
> +  IN EFI_EVENT  Event,
> +  IN VOID       *Context
> +  )
> +{
> +  EFI_STATUS            Status;
> +  UINTN                 SECVerStrLen = 0;
> +  UINTN                 uCodeVerStrLen = 0;
> +  UINTN                 GOPStrLen = 0;
> +  UINTN                 MRCVersionStrLen = 0;
> +  UINTN                 PMCVersionStrLen = 0;
> +  UINTN                 ULPMCVersionStrLen = 0;
> +  UINTN                 PUNITVersionStrLen = 0;
> +  UINTN                 SOCVersionStrLen = 0;
> +  UINTN                 BOARDVersionStrLen = 0;
> +  UINTN                 FABVersionStrLen = 0;
> +  UINTN                 CPUFLAVORStrLen = 0;
> +  UINTN                 BIOSVersionStrLen = 0;
> +  UINTN                 PMICVersionStrLen = 0;
> +  UINTN                 TOUCHVersionStrLen = 0;
> +  UINTN                 SecureBootModeLen = 0;
> +  UINTN                 BootModeLen = 0;
> +  UINTN                 SpeedStepModeLen = 0;
> +  UINTN                 MaxCStateLen = 0;
> +  UINTN                 CpuTurboLen = 0;
> +  UINTN                 GfxTurboLen = 0;
> +  UINTN                 IdleReserveLen = 0;
> +  UINTN                 RC6Len = 0;
> +
> +  SMBIOS_TABLE_TYPE94    *SmbiosRecord;
> +  EFI_SMBIOS_HANDLE     SmbiosHandle;
> +  EFI_MISC_OEM_TYPE_0x94  *ForType94InputData;
> +  CHAR16                *SECVer;
> +  CHAR16                *uCodeVer;
> +  CHAR16                *GOPVer;
> +  CHAR16                *MrcVer;
> +  CHAR16                *PmcVer;
> +  CHAR16                *UlpmcVer;
> +  CHAR16                *PunitVer;
> +  CHAR16                *SocVer;
> +  CHAR16                *BoardVer;
> +  CHAR16                *FabVer;
> +  CHAR16                *CpuFlavor;
> +  CHAR16                *BiosVer;
> +  CHAR16                *PmicVer;
> +  CHAR16                *TouchVer = L"15.16";
> +  CHAR16                *SecureBootMode;
> +  CHAR16                *BootMode;
> +  CHAR16                *SpeedStepMode;
> +  CHAR16                *MaxCState;
> +  CHAR16                *CpuTurbo;
> +  CHAR16                *GfxTurbo;
> +  CHAR16                *IdleReserve;
> +  CHAR16                *RC6;
> +
> +  UINTN                 RecordLen = 0;
> +  UINTN                 StrIdx = 0;
> +
> +
> +  STRING_REF            TokenToGet;
> +  CHAR8                 *OptionalStrStart;
> +  EFI_SMBIOS_PROTOCOL               *SmbiosProtocol;
> +
> +  ForType94InputData        = (EFI_MISC_OEM_TYPE_0x94 *)Context;
> +
> +  DEBUG ((EFI_D_INFO, "Executing SMBIOS T0x94 callback.\n"));
> +
> +  gBS->CloseEvent (Event);    // Unload this event.
> +
> +  //
> +  // First check for invalid parameters.
> +  //
> +  if (Context == NULL) {
> +    return;
> +  }
> +
> +  UpdatePlatformInformation();
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiSmbiosProtocolGuid,
> +                  NULL,
> +                  (VOID **) &SmbiosProtocol
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_SEC_VERSION);
> +  SECVer = SmbiosMiscGetString (TokenToGet);
> +  SECVerStrLen = StrLen(SECVer);
> +  if (SECVerStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_UCODE_VERSION);
> +  uCodeVer = SmbiosMiscGetString (TokenToGet);
> +  uCodeVerStrLen = StrLen(uCodeVer);
> +  if (uCodeVerStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_GOP_VERSION);
> +  GOPVer = SmbiosMiscGetString (TokenToGet);
> +  GOPStrLen = StrLen(GOPVer);
> +  if (GOPStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_MRC_VERSION_VALUE);
> +  MrcVer = SmbiosMiscGetString (TokenToGet);
> +  MRCVersionStrLen = StrLen(MrcVer);
> +  if (MRCVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_PMC_FW_VALUE);
> +  PmcVer = SmbiosMiscGetString (TokenToGet);
> +  PMCVersionStrLen = StrLen(PmcVer);
> +  if (PMCVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_ULPMC_FW_VALUE);
> +  UlpmcVer = SmbiosMiscGetString (TokenToGet);
> +  ULPMCVersionStrLen = StrLen(UlpmcVer);
> +  if (ULPMCVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_PUNIT_FW_VALUE);
> +  PunitVer = SmbiosMiscGetString (TokenToGet);
> +  PUNITVersionStrLen = StrLen(PunitVer);
> +  if (PUNITVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_SOC_VALUE);
> +  SocVer = SmbiosMiscGetString (TokenToGet);
> +  SOCVersionStrLen = StrLen(SocVer);
> +  if (SOCVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_BOARD_ID_VALUE);
> +  BoardVer = SmbiosMiscGetString (TokenToGet);
> +  BOARDVersionStrLen = StrLen(BoardVer);
> +  if (BOARDVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_FAB_ID_VALUE);
> +  FabVer = SmbiosMiscGetString (TokenToGet);
> +  FABVersionStrLen = StrLen(FabVer);
> +  if (FABVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_CPU_FLAVOR_VALUE);
> +  CpuFlavor = SmbiosMiscGetString (TokenToGet);
> +  CPUFLAVORStrLen = StrLen(CpuFlavor);
> +  if (CPUFLAVORStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VERSION);
> +  BiosVer = SmbiosMiscGetString (TokenToGet);
> +  BIOSVersionStrLen = StrLen(BiosVer);
> +  if (BIOSVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_PMIC_VERSION);
> +  PmicVer = SmbiosMiscGetString (TokenToGet);
> +  PMICVersionStrLen = StrLen(PmicVer);
> +  if (PMICVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_TOUCH_VERSION);
> +  TouchVer = SmbiosMiscGetString (TokenToGet);
> +  TOUCHVersionStrLen = StrLen(TouchVer);
> +  if (TOUCHVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_SECURE_BOOT);
> +  SecureBootMode = SmbiosMiscGetString(TokenToGet);
> +  SecureBootModeLen = StrLen(SecureBootMode);
> +  if (SecureBootModeLen > SMBIOS_STRING_MAX_LENGTH) {
> +  	return;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_BOOT_MODE);
> +  BootMode = SmbiosMiscGetString(TokenToGet);
> +  BootModeLen = StrLen(BootMode);
> +  if (BootModeLen > SMBIOS_STRING_MAX_LENGTH) {
> +  	return;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_SPEED_STEP);
> +  SpeedStepMode = SmbiosMiscGetString(TokenToGet);
> +  SpeedStepModeLen = StrLen(SpeedStepMode);
> +  if (SpeedStepModeLen > SMBIOS_STRING_MAX_LENGTH) {
> +  	return;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_CPU_TURBO);
> +  CpuTurbo = SmbiosMiscGetString(TokenToGet);
> +  CpuTurboLen = StrLen(CpuTurbo);
> +  if (CpuTurboLen > SMBIOS_STRING_MAX_LENGTH) {
> +  	return;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_CSTATE);
> +  MaxCState = SmbiosMiscGetString(TokenToGet);
> +  MaxCStateLen = StrLen(MaxCState);
> +  if (MaxCStateLen > SMBIOS_STRING_MAX_LENGTH) {
> +  	return;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_GFX_TURBO);
> +  GfxTurbo = SmbiosMiscGetString(TokenToGet);
> +  GfxTurboLen = StrLen(GfxTurbo);
> +  if (GfxTurboLen > SMBIOS_STRING_MAX_LENGTH) {
> +  	return;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_S0IX_VALUE);
> +  IdleReserve = SmbiosMiscGetString(TokenToGet);
> +  IdleReserveLen = StrLen(IdleReserve);
> +  if (S0ixLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_RC6_VALUE);
> +  RC6 = SmbiosMiscGetString(TokenToGet);
> +  RC6Len = StrLen(RC6);
> +  if (RC6Len > SMBIOS_STRING_MAX_LENGTH) {
> +    return;
> +  }
> +
> +  RecordLen = sizeof (SMBIOS_TABLE_TYPE94) + SECVerStrLen + 1 +
> uCodeVerStrLen + 1 + GOPStrLen + 1 + PMCVersionStrLen + 1 + \
> +                      TOUCHVersionStrLen + 1 + PMICVersionStrLen + 1 +
> BIOSVersionStrLen + 1 + CPUFLAVORStrLen + 1 + \
> +                      BOARDVersionStrLen + 1 + FABVersionStrLen + 1 +
> PUNITVersionStrLen+ 1 + ULPMCVersionStrLen + 1 + \
> +                      MRCVersionStrLen + 1 + SOCVersionStrLen + 1 +
> SecureBootModeLen + 1 + BootModeLen + 1 + \
> +                      SpeedStepModeLen + 1 + CpuTurboLen + 1 + MaxCStateLen + 1
> + GfxTurboLen + 1 + + RC6Len + 1 + 1;
> +
> +  SmbiosRecord = AllocatePool(RecordLen);
> +
> +  ZeroMem(SmbiosRecord, RecordLen);
> +
> +  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_MISC_VERSION_INFO;
> +  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE94);
> +
> +  //
> +  // Make handle chosen by smbios protocol.add automatically.
> +  //
> +  SmbiosRecord->Hdr.Handle = 0;
> +
> +  SmbiosRecord->GopVersion = 1;
> +
> +  SmbiosRecord->SECVersion = 2;
> +
> +  SmbiosRecord->MRCVersion = 3;
> +
> +  SmbiosRecord->uCodeVersion = 4;
> +
> +  SmbiosRecord->PUnitVersion = 5;
> +
> +  SmbiosRecord->PMCVersion = 6;
> +
> +  SmbiosRecord->ULPMCVersion = 7;
> +
> +  SmbiosRecord->SoCVersion = 8;
> +
> +  SmbiosRecord->BoardVersion = 9;
> +
> +  SmbiosRecord->FabVersion = 10;
> +
> +  SmbiosRecord->CPUFlavor = 11;
> +
> +  SmbiosRecord->BiosVersion = 12;
> +
> +  SmbiosRecord->PmicVersion = 13;
> +
> +  SmbiosRecord->TouchVersion = 14;
> +
> +  SmbiosRecord->SecureBoot = 15;
> +
> +  SmbiosRecord->BootMode = 16;
> +
> +  SmbiosRecord->SpeedStepMode= 17;
> +
> +  SmbiosRecord->CPUTurboMode = 18;
> +
> +  SmbiosRecord->MaxCState = 19;
> +
> +  SmbiosRecord->GfxTurbo = 20;
> +  SmbiosRecord->IdleReserve = 21;
> +
> +  SmbiosRecord->RC6 = 22;
> +
> +
> +  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
> +  UnicodeStrToAsciiStr(GOPVer, OptionalStrStart);
> +  StrIdx +=  GOPStrLen + 1;
> +
> +  UnicodeStrToAsciiStr(SECVer, OptionalStrStart + StrIdx);
> +  StrIdx +=  SECVerStrLen + 1;
> +
> +  UnicodeStrToAsciiStr(MrcVer, OptionalStrStart + StrIdx);
> +  StrIdx +=  MRCVersionStrLen + 1;
> +
> +  UnicodeStrToAsciiStr(uCodeVer, OptionalStrStart + StrIdx);
> +  StrIdx +=  uCodeVerStrLen + 1;
> +
> +  UnicodeStrToAsciiStr(PunitVer, OptionalStrStart + StrIdx);
> +  StrIdx +=  PUNITVersionStrLen + 1;
> +
> +  UnicodeStrToAsciiStr(PmcVer, OptionalStrStart + StrIdx);
> +  StrIdx +=  PMCVersionStrLen + 1;
> +
> +  UnicodeStrToAsciiStr(UlpmcVer, OptionalStrStart + StrIdx);
> +  StrIdx +=  ULPMCVersionStrLen + 1;
> +
> +
> +  UnicodeStrToAsciiStr(SocVer, OptionalStrStart + StrIdx);
> +  StrIdx +=  SOCVersionStrLen +1;
> +
> +  UnicodeStrToAsciiStr(BoardVer, OptionalStrStart + StrIdx);
> +  StrIdx +=  BOARDVersionStrLen + 1;
> +
> +  UnicodeStrToAsciiStr(FabVer, OptionalStrStart + StrIdx);
> +  StrIdx +=  FABVersionStrLen + 1;
> +
> +  UnicodeStrToAsciiStr(CpuFlavor, OptionalStrStart + StrIdx);
> +  StrIdx +=  CPUFLAVORStrLen + 1;
> +
> +  UnicodeStrToAsciiStr(BiosVer, OptionalStrStart + StrIdx);
> +  StrIdx +=  BIOSVersionStrLen + 1;
> +
> +  UnicodeStrToAsciiStr(PmicVer, OptionalStrStart + StrIdx);
> +  StrIdx +=  PMICVersionStrLen + 1;
> +
> +  UnicodeStrToAsciiStr(TouchVer, OptionalStrStart + StrIdx);
> +  StrIdx +=  TOUCHVersionStrLen + 1;
> +
> +  UnicodeStrToAsciiStr(SecureBootMode, OptionalStrStart + StrIdx);
> +  StrIdx +=  SecureBootModeLen + 1;
> +
> +  UnicodeStrToAsciiStr(BootMode, OptionalStrStart + StrIdx);
> +  StrIdx +=  BootModeLen + 1;
> +
> +  UnicodeStrToAsciiStr(SpeedStepMode, OptionalStrStart + StrIdx);
> +  StrIdx +=  SpeedStepModeLen + 1;
> +
> +  UnicodeStrToAsciiStr(CpuTurbo, OptionalStrStart + StrIdx);
> +  StrIdx +=  CpuTurboLen + 1;
> +
> +  UnicodeStrToAsciiStr(MaxCState, OptionalStrStart + StrIdx);
> +  StrIdx +=  MaxCStateLen + 1;
> +
> +  UnicodeStrToAsciiStr(GfxTurbo, OptionalStrStart + StrIdx);
> +  StrIdx +=  GfxTurboLen + 1;
> +
> +  UnicodeStrToAsciiStr(IdleReserve, OptionalStrStart + StrIdx);
> +  StrIdx +=  S0ixLen + 1;
> +
> +  UnicodeStrToAsciiStr(RC6, OptionalStrStart + StrIdx);
> +  StrIdx +=  RC6Len + 1;
> +
> +  //
> +  // Now we have got the full smbios record, call smbios protocol to add this
> record.
> +  //
> +  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +  Status = SmbiosProtocol-> Add (
> +                              SmbiosProtocol,
> +                              NULL,
> +                              &SmbiosHandle,
> +                              (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
> +                              );
> +
> +  FreePool(SmbiosRecord);
> +  return;
> +}
> +
> +/**
> +  This function makes boot time changes to the contents of the
> +  MiscOemType0x94 (Type 0x94).
> +
> +  @param  RecordData                 Pointer to copy of RecordData from the Data
> Table.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
> +
> +**/
> +MISC_SMBIOS_TABLE_FUNCTION(MiscOemType0x94)
> +{
> +  EFI_STATUS                    Status;
> +  EFI_EVENT                     AddSmbiosT0x94CallbackEvent;
> +
> +  Status = EfiCreateEventReadyToBootEx (
> +             TPL_CALLBACK,
> +             AddSmbiosT0x94Callback,
> +             RecordData,
> +             &AddSmbiosT0x94CallbackEvent
> +             );
> +
> +  ASSERT_EFI_ERROR (Status);
> +  return Status;
> +
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDevice.un
> i
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDevice.un
> i
> new file mode 100644
> index 0000000000..85c60a06fe
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDevice.un
> i
> @@ -0,0 +1,26 @@
> +// *++
> +//
> +// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//
> +// Module Name:
> +//
> +//   MiscOnboardDevice.uni
> +//
> +// Abstract:
> +//
> +//   Onboard device information
> +//
> +// Revision History:
> +//
> +// --*/
> +
> +
> +/=#
> +
> +#langdef en-US "English"
> +
> +#string STR_MISC_ONBOARD_DEVICE_VIDEO   #language en-US  "Intel(R)
> ValleyView2 HD Graphics"
> +#string STR_MISC_ONBOARD_DEVICE_AUDIO   #language en-US  "Intel(R)
> HD Audio Device"
> +#string STR_MISC_ONBOARD_DEVICE_NETWORK #language en-US  ""
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceDat
> a.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceDa
> ta.c
> new file mode 100644
> index 0000000000..f82cfa8985
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceDa
> ta.c
> @@ -0,0 +1,48 @@
> +/** @file
> +
> +Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscOnboardDeviceData.c
> +
> +Abstract:
> +
> +  Static data of Onboard device information .
> +  The onboard device information is Misc. subclass type 8 and SMBIOS type
> 10.
> +
> +
> +**/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +//
> +// Static (possibly build generated) Bios Vendor data.
> +//
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_ONBOARD_DEVICE_DATA,
> MiscOnboardDeviceVideo) = {
> +  STRING_TOKEN(STR_MISC_ONBOARD_DEVICE_VIDEO),  //
> OnBoardDeviceDescription
> +  {                             // OnBoardDeviceStatus
> +    EfiOnBoardDeviceTypeVideo,  // DeviceType
> +    1,                          // DeviceEnabled
> +    0                           // Reserved
> +  },
> +  0                             // OnBoardDevicePath
> +};
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_ONBOARD_DEVICE_DATA,
> MiscOnboardDeviceAudio) = {
> +  STRING_TOKEN(STR_MISC_ONBOARD_DEVICE_AUDIO),    //
> OnBoardDeviceDescription
> +  {                                 // OnBoardDeviceStatus
> +    EfiOnBoardDeviceTypeSound,      // DeviceType
> +    1,                              // DeviceEnabled
> +    0                               // Reserved
> +  },
> +  0                                 // OnBoardDevicePath
> +};
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceFu
> nction.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceFu
> nction.c
> new file mode 100644
> index 0000000000..aef25065b8
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceFu
> nction.c
> @@ -0,0 +1,135 @@
> +/** @file
> +
> +Copyright (c) 1999  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscOnboardDeviceFunction.c
> +
> +Abstract:
> +
> +  Create the device path for the Onboard device.
> +  The Onboard device information is Misc. subclass type 8 and SMBIOS type
> 10.
> +
> +
> +**/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +
> +
> +/**
> +  This is a macro defined function, in fact, the function is
> +  MiscOnboardDeviceFunction (RecordType, RecordLen, RecordData,
> LogRecordData)
> +  This function makes boot time changes to the contents of the
> +  MiscOnboardDevice structure.
> +
> +  @param  MiscOnboardDevice      The string which is used to create the
> function
> +  The Arguments in fact:
> +  @param  RecordType             Type of record to be processed from the Data
> +                                 Table. mMiscSubclassDataTable[].RecordType
> +  @param  RecordLen              Size of static RecordData from the Data Table.
> +                                 mMiscSubclassDataTable[].RecordLen
> +  @param  RecordData             Pointer to RecordData, which will be written to
> +                                 the Data Hub
> +  @param  LogRecordData          TRUE to log RecordData to Data Hub. FALSE
> when
> +                                 there is no more data to log.
> +
> +  @retval EFI_SUCCESS            *RecordData and *LogRecordData have been
> set.
> +  @retval EFI_UNSUPPORTED        Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER  One of the following parameter
> conditions was
> +                                 true: RecordLen was zero. RecordData was NULL.
> +                                 LogRecordData was NULL.
> +
> +**/
> +MISC_SMBIOS_TABLE_FUNCTION (
> +  MiscOnboardDevice
> +  )
> +{
> +  CHAR8                         *OptionalStrStart;
> +  UINT8                         StatusAndType;
> +  UINTN                         DescriptionStrLen;
> +  EFI_STRING                    DeviceDescription;
> +  STRING_REF                    TokenToGet;
> +  EFI_STATUS                    Status;
> +  EFI_SMBIOS_HANDLE             SmbiosHandle;
> +  SMBIOS_TABLE_TYPE10           *SmbiosRecord;
> +  EFI_MISC_ONBOARD_DEVICE       *ForType10InputData;
> +
> +  ForType10InputData = (EFI_MISC_ONBOARD_DEVICE *)RecordData;
> +
> +  //
> +  // First check for invalid parameters.
> +  //
> +  if (RecordData == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  TokenToGet = 0;
> +  switch (ForType10InputData->OnBoardDeviceDescription) {
> +    case STR_MISC_ONBOARD_DEVICE_VIDEO:
> +      TokenToGet = STRING_TOKEN (STR_MISC_ONBOARD_DEVICE_VIDEO);
> +      break;
> +    case STR_MISC_ONBOARD_DEVICE_AUDIO:
> +      TokenToGet = STRING_TOKEN (STR_MISC_ONBOARD_DEVICE_AUDIO);
> +      break;
> +	default:
> +	break;
> +  }
> +
> +  DeviceDescription = SmbiosMiscGetString (TokenToGet);
> +  DescriptionStrLen = StrLen(DeviceDescription);
> +  if (DescriptionStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Two zeros following the last string.
> +  //
> +  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE10) +
> DescriptionStrLen + 1 + 1);
> +  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE10) +
> DescriptionStrLen + 1 + 1);
> +
> +  SmbiosRecord->Hdr.Type =
> EFI_SMBIOS_TYPE_ONBOARD_DEVICE_INFORMATION;
> +  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE10);
> +
> +  //
> +  // Make handle chosen by smbios protocol.add automatically.
> +  //
> +  SmbiosRecord->Hdr.Handle = 0;
> +
> +  //
> +  // Status & Type: Bit 7 Devicen Status, Bits 6:0 Type of Device
> +  //
> +  StatusAndType = (UINT8) ForType10InputData-
> >OnBoardDeviceStatus.DeviceType;
> +  if (ForType10InputData->OnBoardDeviceStatus.DeviceEnabled != 0) {
> +    StatusAndType |= 0x80;
> +  } else {
> +    StatusAndType &= 0x7F;
> +  }
> +
> +  SmbiosRecord->Device[0].DeviceType = StatusAndType;
> +  SmbiosRecord->Device[0].DescriptionString = 1;
> +  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
> +  UnicodeStrToAsciiStr(DeviceDescription, OptionalStrStart);
> +
> +  //
> +  // Now we have got the full smbios record, call smbios protocol to add this
> record.
> +  //
> +  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +  Status = Smbios-> Add(
> +                      Smbios,
> +                      NULL,
> +                      &SmbiosHandle,
> +                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
> +                      );
> +  FreePool(SmbiosRecord);
> +  return Status;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArray.uni
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArray.uni
> new file mode 100644
> index 0000000000..bed00e0de5
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArray.uni
> @@ -0,0 +1,25 @@
> +// *++
> +//
> +// Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//
> +// Module Name:
> +//
> +//   MiscPhysicalArray.uni
> +//
> +// Abstract:
> +//
> +//   BIOS Physical Memory
> +//   SMBIOS type 16.
> +//
> +// Revision History:
> +//
> +// --*/
> +
> +
> +/=#
> +#langdef   en-US "English"
> +
> +
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayData.
> c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayData.
> c
> new file mode 100644
> index 0000000000..66370f7eea
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayData.
> c
> @@ -0,0 +1,38 @@
> +/*++
> +
> +Copyright (c) 2006  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscPhysicalArrayData.c
> +
> +Abstract:
> +
> +  BIOS Physical Array static data.
> +  SMBIOS type 16.
> +
> +--*/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +
> +
> +//
> +// Static (possibly build generated) Physical Memory Array Dat.
> +//
> +MISC_SMBIOS_TABLE_DATA(EFI_MEMORY_ARRAY_LOCATION_DATA,
> MiscPhysicalMemoryArray) =
> +{
> +	EfiMemoryArrayLocationSystemBoard,
> 		// Memory location
> +	EfiMemoryArrayUseSystemMemory,
> 		    // Memory array use
> +	EfiMemoryErrorCorrectionNone,
> 		    // Memory error correction
> +	0,                                                      // Maximum Memory Capacity
> +	0x01						                            //
> Number of Devices
> +};
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayFunct
> ion.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayFunct
> ion.c
> new file mode 100644
> index 0000000000..67fc04152c
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayFunct
> ion.c
> @@ -0,0 +1,101 @@
> +/*++
> +
> +Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscPhysicalArrayFunction.c
> +
> +Abstract:
> +
> +  BIOS system Physical Array boot time changes.
> +  SMBIOS type 16.
> +
> +--*/
> +
> +
> +#include "CommonHeader.h"
> +#include "MiscSubclassDriver.h"
> +
> +
> +
> +/**
> +  This function makes boot time changes to the contents of the
> +  MiscPhysicalArrayFunction (Type 16).
> +
> +  @param  RecordData                 Pointer to copy of RecordData from the Data
> Table.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
> +
> +**/
> +
> +MISC_SMBIOS_TABLE_FUNCTION(MiscPhysicalMemoryArray)
> +{
> +    EFI_STATUS                      Status;
> +    EFI_SMBIOS_HANDLE               SmbiosHandle;
> +    SMBIOS_TABLE_TYPE16             *SmbiosRecord;
> +    EFI_MEMORY_ARRAY_LOCATION_DATA  *ForType16InputData;
> +    UINT32                           TopOfMemory = 8 * 1024 * 1024;
> +
> +    //
> +    // First check for invalid parameters.
> +    //
> +    if (RecordData == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +    }
> +
> +    ForType16InputData = (EFI_MEMORY_ARRAY_LOCATION_DATA
> *)RecordData;
> +
> +    //
> +    // Two zeros following the last string.
> +    //
> +    SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE16)  + 1);
> +    ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE16)  + 1);
> +
> +    SmbiosRecord->Hdr.Type =
> EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY;
> +    SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE16);
> +
> +    //
> +    // Make handle chosen by smbios protocol.add automatically.
> +    //
> +    SmbiosRecord->Hdr.Handle = 0;
> +
> +    //
> +    // ReleaseDate will be the 3rd optional string following the formatted
> structure.
> +    //
> +    SmbiosRecord->Location = *(UINT8 *) &ForType16InputData -
> >MemoryArrayLocation;
> +    SmbiosRecord->Use = *(UINT8 *) &ForType16InputData -
> >MemoryArrayUse;
> +    SmbiosRecord->MemoryErrorCorrection = *(UINT8 *)
> &ForType16InputData->MemoryErrorCorrection;
> +
> +    //
> +    // System does not provide the error information structure
> +    //
> +    SmbiosRecord->MemoryErrorInformationHandle = 0xFFFE;
> +
> +    //
> +    // Maximum memory capacity
> +    //
> +    SmbiosRecord-> MaximumCapacity = TopOfMemory;
> +    SmbiosRecord-> NumberOfMemoryDevices= 0x02;
> +
> +    //
> +    // Now we have got the full smbios record, call smbios protocol to add this
> record.
> +    //
> +    SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +    Status = Smbios-> Add(
> +                        Smbios,
> +                        NULL,
> +                       &SmbiosHandle,
> +                       (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
> +                       );
> +    FreePool(SmbiosRecord);
> +    return Status;
> +
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConne
> ctorDesignator.uni
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConne
> ctorDesignator.uni
> new file mode 100644
> index 0000000000..80fa99ecbe
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConne
> ctorDesignator.uni
> @@ -0,0 +1,31 @@
> +// *++
> +//
> +// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//
> +// Module Name:
> +//
> +//   MiscPortInternalConnectorDesignator.uni
> +//
> +// Abstract:
> +//
> +//   Port internal connector information
> +//
> +// Revision History:
> +//
> +// --*/
> +
> +
> +/=#
> +
> +#langdef en-US "English"
> +
> +#string STR_MISC_PORT_INTERNAL_IDE1      #language en-US  "J4J1"
> +#string STR_MISC_PORT_EXTERNAL_IDE1      #language en-US
> "SATA_CON1"
> +#string STR_MISC_PORT_INTERNAL_IDE2      #language en-US  "J4E3"
> +#string STR_MISC_PORT_EXTERNAL_IDE2      #language en-US
> "SATA_CON2"
> +#string STR_MISC_PORT_INTERNAL_ATX_POWER #language en-US  "J3J1"
> +#string STR_MISC_PORT_EXTERNAL_ATX_POWER #language en-US
> "ATX_PWR"
> +#string STR_MISC_PORT_INTERNAL_BTX_POWER #language en-US
> "BTX_PWR"
> +#string STR_MISC_PORT_EXTERNAL_BTX_POWER #language en-US  ""
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConne
> ctorDesignatorData.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConne
> ctorDesignatorData.c
> new file mode 100644
> index 0000000000..b98bab40ab
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConne
> ctorDesignatorData.c
> @@ -0,0 +1,56 @@
> +/** @file
> +
> +Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscPortInternalConnectorDesignatorData.c
> +
> +Abstract:
> +
> +  Static data of Port internal connector designator information.
> +  Port internal connector designator information is Misc. subclass type 6 and
> +  SMBIOS type 8.
> +
> +
> +**/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +//
> +// Static (possibly build generated) Port connector designations
> +//
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DE
> SIGNATOR_DATA, MiscPortIde1) = {
> +  STRING_TOKEN(STR_MISC_PORT_INTERNAL_IDE1),
> +  STRING_TOKEN(STR_MISC_PORT_EXTERNAL_IDE1),
> +  EfiPortConnectorTypeOnboardIde,
> +  EfiPortConnectorTypeNone,
> +  EfiPortTypeOther,
> +  0
> +};
> +
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DE
> SIGNATOR_DATA, MiscPortIde2) = {
> +  STRING_TOKEN(STR_MISC_PORT_INTERNAL_IDE2),
> +  STRING_TOKEN(STR_MISC_PORT_EXTERNAL_IDE2),
> +  EfiPortConnectorTypeOnboardIde,
> +  EfiPortConnectorTypeNone,
> +  EfiPortTypeOther,
> +  0
> +};
> +
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DE
> SIGNATOR_DATA, MiscPortAtxPower) = {
> +  STRING_TOKEN(STR_MISC_PORT_INTERNAL_ATX_POWER),
> +  STRING_TOKEN(STR_MISC_PORT_EXTERNAL_ATX_POWER),
> +  EfiPortConnectorTypeOther,
> +  EfiPortConnectorTypeNone,
> +  EfiPortTypeOther,
> +  0
> +};
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConne
> ctorDesignatorFunction.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConne
> ctorDesignatorFunction.c
> new file mode 100644
> index 0000000000..6bc088cd13
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConne
> ctorDesignatorFunction.c
> @@ -0,0 +1,152 @@
> +/** @file
> +
> +Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscPortInternalConnectorDesignatorFunction.c
> +
> +Abstract:
> +
> +  Create the device path for the Port internal connector designator.
> +  Port internal connector designator information is Misc. subclass type 6
> +  and SMBIOS type 8.
> +
> +
> +**/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +
> +/**
> +  This is a macro defined function, in fact, the function is
> +  MiscPortInternalConnectorDesignatorFunction (RecordType, RecordLen,
> RecordData, LogRecordData)
> +  This function makes boot time changes to the contents of the
> +  MiscPortConnectorInformation.
> +
> +  @param  MiscPortInternalConnectorDesignator  The string which is used to
> create
> +                                               the function
> +  The Arguments in fact:
> +  @param  RecordType                           Type of record to be processed from
> +                                               the Data Table.
> +                                               mMiscSubclassDataTable[].RecordType
> +  @param  RecordLen                            Size of static RecordData from the
> +                                               Data Table.
> +                                               mMiscSubclassDataTable[].RecordLen
> +  @param  RecordData                           Pointer to RecordData, which will be
> +                                               written to the Data Hub
> +  @param  LogRecordData                        TRUE to log RecordData to Data Hub.
> +                                               FALSE when there is no more data to
> +                                               log.
> +
> +  @retval EFI_SUCCESS                          *RecordData and *LogRecordData have
> +                                               been set.
> +  @retval EFI_UNSUPPORTED                      Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER                One of the following parameter
> +                                               conditions was true: RecordLen was
> +                                               zero. RecordData was NULL.
> +                                               LogRecordData was NULL.
> +
> +**/
> +MISC_SMBIOS_TABLE_FUNCTION (
> +  MiscPortInternalConnectorDesignator
> +  )
> +{
> +  CHAR8                                        *OptionalStrStart;
> +  UINTN                                        InternalRefStrLen;
> +  UINTN                                        ExternalRefStrLen;
> +  EFI_STRING                                   InternalRef;
> +  EFI_STRING                                   ExternalRef;
> +  STRING_REF                                   TokenForInternal;
> +  STRING_REF                                   TokenForExternal;
> +  EFI_STATUS                                   Status;
> +  SMBIOS_TABLE_TYPE8                           *SmbiosRecord;
> +  EFI_SMBIOS_HANDLE                            SmbiosHandle;
> +  EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR
> *ForType8InputData;
> +
> +  ForType8InputData =
> (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR *)RecordData;
> +
> +  //
> +  // First check for invalid parameters.
> +  //
> +  if (RecordData == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  TokenForInternal = 0;
> +  TokenForExternal = 0;
> +
> +  switch (ForType8InputData->PortInternalConnectorDesignator) {
> +
> +    case STR_MISC_PORT_INTERNAL_IDE1:
> +      TokenForInternal = STRING_TOKEN (STR_MISC_PORT_INTERNAL_IDE1);
> +      TokenForExternal = STRING_TOKEN(STR_MISC_PORT_EXTERNAL_IDE1);
> +      break;
> +    case STR_MISC_PORT_INTERNAL_IDE2:
> +      TokenForInternal = STRING_TOKEN (STR_MISC_PORT_INTERNAL_IDE2);
> +      TokenForExternal = STRING_TOKEN(STR_MISC_PORT_EXTERNAL_IDE2);
> +      break;
> +    case STR_MISC_PORT_INTERNAL_ATX_POWER:
> +      TokenForInternal = STRING_TOKEN
> (STR_MISC_PORT_INTERNAL_ATX_POWER);
> +      TokenForExternal =
> STRING_TOKEN(STR_MISC_PORT_EXTERNAL_ATX_POWER);
> +      break;
> +    default:
> +      break;
> +  }
> +
> +  InternalRef = SmbiosMiscGetString (TokenForInternal);
> +  InternalRefStrLen = StrLen(InternalRef);
> +  if (InternalRefStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  ExternalRef = SmbiosMiscGetString (TokenForExternal);
> +  ExternalRefStrLen = StrLen(ExternalRef);
> +  if (ExternalRefStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Two zeros following the last string.
> +  //
> +  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE8) +
> InternalRefStrLen + 1 + ExternalRefStrLen + 1 + 1);
> +  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE8) +
> InternalRefStrLen + 1 + ExternalRefStrLen + 1 + 1);
> +
> +  SmbiosRecord->Hdr.Type =
> EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION;
> +  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE8);
> +
> +  //
> +  // Make handle chosen by smbios protocol.add automatically.
> +  //
> +  SmbiosRecord->Hdr.Handle = 0;
> +  SmbiosRecord->InternalReferenceDesignator = 1;
> +  SmbiosRecord->InternalConnectorType = (UINT8)ForType8InputData-
> >PortInternalConnectorType;
> +  SmbiosRecord->ExternalReferenceDesignator = 2;
> +  SmbiosRecord->ExternalConnectorType = (UINT8)ForType8InputData-
> >PortExternalConnectorType;
> +  SmbiosRecord->PortType = (UINT8)ForType8InputData->PortType;
> +
> +  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
> +  UnicodeStrToAsciiStr(InternalRef, OptionalStrStart);
> +  UnicodeStrToAsciiStr(ExternalRef, OptionalStrStart + InternalRefStrLen + 1);
> +
> +  //
> +  // Now we have got the full smbios record, call smbios protocol to add this
> record.
> +  //
> +  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +  Status = Smbios-> Add(
> +                      Smbios,
> +                      NULL,
> +                      &SmbiosHandle,
> +                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
> +                      );
> +  FreePool(SmbiosRecord);
> +  return Status;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCache.u
> ni
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCache.u
> ni
> new file mode 100644
> index 0000000000..fee69bb139
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCache.u
> ni
> @@ -0,0 +1,22 @@
> +// *++
> +//
> +// Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//
> +// Module Name:
> +//
> +//   MiscProcessorCache.uni
> +//
> +// Abstract:
> +//
> +//
> +// Revision History:
> +//
> +// --*/
> +
> +
> +/=#
> +#langdef   en-US "English"
> +
> +#string STR_SOCKET_DESIGNATION                #language en-US  "0x01"
> \ No newline at end of file
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheDa
> ta.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheDa
> ta.c
> new file mode 100644
> index 0000000000..6af7f56107
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheDa
> ta.c
> @@ -0,0 +1,33 @@
> +/*++
> +
> +Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscBiosProcessorCache.c
> +
> +Abstract:
> +
> +  Processor cache static data.
> +  Misc. subclass type 7.
> +  SMBIOS type 7.
> +
> +--*/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +
> +//
> +// Static (possibly build generated) Processor cache data.
> +//
> +MISC_SMBIOS_TABLE_DATA(EFI_CACHE_VARIABLE_RECORD,
> MiscProcessorCache) = {
> +0
> +};
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheFu
> nction.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheFu
> nction.c
> new file mode 100644
> index 0000000000..ca121525a0
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheFu
> nction.c
> @@ -0,0 +1,189 @@
> +/*++
> +
> +Copyright (c) 2006  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscProcessorCacheFunction.c
> +
> +Abstract:
> +
> +  BIOS processor cache details.
> +  Misc. subclass type 7.
> +  SMBIOS type 7.
> +
> +--*/
> +#include "CommonHeader.h"
> +#include "MiscSubclassDriver.h"
> +#include <Protocol/DataHub.h>
> +#include <Guid/DataHubRecords.h>
> +
> +UINT32
> +ConvertBase2ToRaw (
> +  IN  EFI_EXP_BASE2_DATA             *Data)
> +{
> +  UINTN         Index;
> +  UINT32        RawData;
> +
> +  RawData = Data->Value;
> +  for (Index = 0; Index < (UINTN) Data->Exponent; Index++) {
> +     RawData <<= 1;
> +  }
> +
> +  return  RawData;
> +}
> +
> +
> +MISC_SMBIOS_TABLE_FUNCTION(MiscProcessorCache)
> +{
> +	EFI_SMBIOS_HANDLE     SmbiosHandle;
> +	SMBIOS_TABLE_TYPE7            *SmbiosRecordL1;
> +	SMBIOS_TABLE_TYPE7            *SmbiosRecordL2;
> +
> +	EFI_CACHE_SRAM_TYPE_DATA      CacheSramType;
> +	CHAR16                          *SocketDesignation;
> +	CHAR8                           *OptionalStrStart;
> +	UINTN                           SocketStrLen;
> +	STRING_REF                      TokenToGet;
> +	EFI_DATA_HUB_PROTOCOL           *DataHub;
> +	UINT64                          MonotonicCount;
> +	EFI_DATA_RECORD_HEADER          *Record;
> +	EFI_SUBCLASS_TYPE1_HEADER       *DataHeader;
> +	UINT8                           *SrcData;
> +	EFI_STATUS                      Status;
> +
> +	//
> +	// Memory Device LOcator
> +	//
> +	DEBUG ((EFI_D_ERROR, "type 7\n"));
> +
> +	TokenToGet = STRING_TOKEN (STR_SOCKET_DESIGNATION);
> +	SocketDesignation = SmbiosMiscGetString (TokenToGet);
> +	SocketStrLen = StrLen(SocketDesignation);
> +	if (SocketStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +	return EFI_UNSUPPORTED;
> +	}
> +
> +	SmbiosRecordL1 = AllocatePool(sizeof (SMBIOS_TABLE_TYPE7) + 7 +
> 1 + 1);
> +	ASSERT (SmbiosRecordL1 != NULL);
> +	ZeroMem(SmbiosRecordL1, sizeof (SMBIOS_TABLE_TYPE7) + 7 + 1 +
> 1);
> +
> +	SmbiosRecordL2 = AllocatePool(sizeof (SMBIOS_TABLE_TYPE7) + 7 +
> 1 + 1);
> +	ASSERT (SmbiosRecordL2 != NULL);
> +	ZeroMem(SmbiosRecordL2, sizeof (SMBIOS_TABLE_TYPE7) + 7 + 1 +
> 1);
> +
> +	//
> +	// Get the Data Hub Protocol. Assume only one instance
> +	//
> +	Status = gBS->LocateProtocol (
> +	                &gEfiDataHubProtocolGuid,
> +	                NULL,
> +	                (VOID **)&DataHub
> +	                );
> +	ASSERT_EFI_ERROR(Status);
> +
> +	MonotonicCount = 0;
> +	Record = NULL;
> +
> +	do {
> +	Status = DataHub->GetNextRecord (
> +	                    DataHub,
> +	                    &MonotonicCount,
> +	                    NULL,
> +	                    &Record
> +	                    );
> +		if (!EFI_ERROR(Status)) {
> +			if (Record->DataRecordClass ==
> EFI_DATA_RECORD_CLASS_DATA) {
> +				DataHeader  =
> (EFI_SUBCLASS_TYPE1_HEADER *)(Record + 1);
> +				SrcData     = (UINT8  *)(DataHeader + 1);
> +				if (CompareGuid(&Record->DataRecordGuid,
> &gEfiCacheSubClassGuid) && (DataHeader->RecordType ==
> CacheSizeRecordType)) {
> +          			if (DataHeader->SubInstance == EFI_CACHE_L1) {
> +						SmbiosRecordL1-
> >InstalledSize += (UINT16) (ConvertBase2ToRaw((EFI_EXP_BASE2_DATA
> *)SrcData) >> 10);
> +						SmbiosRecordL1-
> >MaximumCacheSize = SmbiosRecordL1->InstalledSize;
> +          			}
> +         			 else if (DataHeader->SubInstance == EFI_CACHE_L2)
> {
> +						SmbiosRecordL2-
> >InstalledSize += (UINT16) (ConvertBase2ToRaw((EFI_EXP_BASE2_DATA
> *)SrcData) >> 10);
> +						SmbiosRecordL2-
> >MaximumCacheSize = SmbiosRecordL2->InstalledSize;
> +          			} else {
> +           				 continue;
> +          			}
> +		  		}
> +	      	}
> +    	}
> +	} while (!EFI_ERROR(Status) && (MonotonicCount != 0));
> +
> +	//
> +	//Filling SMBIOS type 7 information for different cache levels.
> +	//
> +
> +	SmbiosRecordL1->Hdr.Type =
> EFI_SMBIOS_TYPE_CACHE_INFORMATION;
> +	SmbiosRecordL1->Hdr.Length = (UINT8) sizeof
> (SMBIOS_TABLE_TYPE7);
> +	SmbiosRecordL1->Hdr.Handle = 0;
> +
> +	SmbiosRecordL1->Associativity = CacheAssociativity8Way;
> +	SmbiosRecordL1->SystemCacheType = CacheTypeUnknown;
> +	SmbiosRecordL1->SocketDesignation = 0x01;
> +	SmbiosRecordL1->CacheSpeed = 0;
> +	SmbiosRecordL1->CacheConfiguration = 0x0180;
> +	ZeroMem (&CacheSramType, sizeof
> (EFI_CACHE_SRAM_TYPE_DATA));
> +	CacheSramType.Synchronous = 1;
> +	CopyMem(&SmbiosRecordL1->SupportedSRAMType,
> &CacheSramType, 2);
> +	CopyMem(&SmbiosRecordL1->CurrentSRAMType, &CacheSramType,
> 2);
> +	SmbiosRecordL1->ErrorCorrectionType = EfiCacheErrorSingleBit;
> +
> +
> +	SmbiosRecordL2->Hdr.Type =
> EFI_SMBIOS_TYPE_CACHE_INFORMATION;
> +	SmbiosRecordL2->Hdr.Length = (UINT8) sizeof
> (SMBIOS_TABLE_TYPE7);
> +	SmbiosRecordL2->Hdr.Handle = 0;
> +
> +	SmbiosRecordL2->Associativity = CacheAssociativity16Way;
> +	SmbiosRecordL2->SystemCacheType = CacheTypeInstruction;
> +	SmbiosRecordL2->SocketDesignation = 0x01;
> +	SmbiosRecordL2->CacheSpeed = 0;
> +	SmbiosRecordL2->CacheConfiguration = 0x0281;
> +	ZeroMem (&CacheSramType, sizeof
> (EFI_CACHE_SRAM_TYPE_DATA));
> +	CacheSramType.Synchronous = 1;
> +	CopyMem(&SmbiosRecordL2->SupportedSRAMType,
> &CacheSramType, 2);
> +	CopyMem(&SmbiosRecordL2->CurrentSRAMType, &CacheSramType,
> 2);
> +	SmbiosRecordL2->ErrorCorrectionType = EfiCacheErrorSingleBit;
> +
> +
> +
> +	//
> +	//Adding SMBIOS type 7 records to SMBIOS table.
> +	//
> +	SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +	OptionalStrStart = (CHAR8 *)(SmbiosRecordL1 + 1);
> +	UnicodeStrToAsciiStr(SocketDesignation, OptionalStrStart);
> +
> +	Smbios-> Add(
> +	           Smbios,
> +	           NULL,
> +	           &SmbiosHandle,
> +	           (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecordL1
> +	           );
> +
> +	//
> +	//VLV2 incorporates two SLM modules (quad cores) in the SoC. 2
> cores share BIU/L2 cache
> +	//
> +	SmbiosRecordL2->InstalledSize = (SmbiosRecordL2->InstalledSize)/2;
> +	SmbiosRecordL2->MaximumCacheSize = SmbiosRecordL2-
> >InstalledSize;
> +	SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +
> +	OptionalStrStart = (CHAR8 *)(SmbiosRecordL2 + 1);
> +	UnicodeStrToAsciiStr(SocketDesignation, OptionalStrStart);
> +
> +	Smbios-> Add(
> +	           Smbios,
> +	           NULL,
> +	           &SmbiosHandle,
> +	           (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecordL2
> +	           );
> +
> +	return EFI_SUCCESS;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformat
> ion.uni
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformat
> ion.uni
> new file mode 100644
> index 0000000000..2e6c79009b
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformat
> ion.uni
> @@ -0,0 +1,27 @@
> +// *++
> +//
> +// Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//
> +// Module Name:
> +//
> +//   MiscProcessorInformation.uni
> +//
> +// Abstract:
> +//
> +//
> +// Revision History:
> +//
> +// --*/
> +
> +
> +/=#
> +#langdef   en-US "English"
> +
> +#string STR_MISC_SOCKET_NAME                #language en-US  "VLV"
> +#string STR_MISC_PROCESSOR_MAUFACTURER      #language en-US  "Intel"
> +#string STR_MISC_PROCESSOR_VERSION          #language en-US  "Baytrail
> A0"
> +#string STR_MISC_PROCESSOR_SERIAL_NUMBER    #language en-US  " "
> +#string STR_MISC_ASSERT_TAG_DATA            #language en-US  " "
> +#string STR_MISC_PART_NUMBER                #language en-US  " "
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformat
> ionData.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformat
> ionData.c
> new file mode 100644
> index 0000000000..846e9ec838
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformat
> ionData.c
> @@ -0,0 +1,71 @@
> +/*++
> +
> +Copyright (c) 2006  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscOnboardDeviceData.c
> +
> +Abstract:
> +
> +  This driver parses the mMiscSubclassDataTable structure and reports
> +  any generated data to smbios.
> +
> +--*/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +
> +/*
> +  EFI_PROCESSOR_CORE_FREQUENCY_LIST_DATA
> ProcessorCoreFrequencyList;
> +  EFI_PROCESSOR_FSB_FREQUENCY_LIST_DATA
> ProcessorFsbFrequencyList;
> +  EFI_PROCESSOR_SERIAL_NUMBER_DATA        ProcessorSerialNumber;
> +  EFI_PROCESSOR_CORE_FREQUENCY_DATA       ProcessorCoreFrequency;
> +  EFI_PROCESSOR_FSB_FREQUENCY_DATA        ProcessorFsbFrequency;
> +  EFI_PROCESSOR_MAX_CORE_FREQUENCY_DATA
> ProcessorMaxCoreFrequency;
> +  EFI_PROCESSOR_MAX_FSB_FREQUENCY_DATA
> ProcessorMaxFsbFrequency;
> +  EFI_PROCESSOR_VERSION_DATA              ProcessorVersion;
> +  EFI_PROCESSOR_MANUFACTURER_DATA         ProcessorManufacturer;
> +  EFI_PROCESSOR_ID_DATA                   ProcessorId;
> +  EFI_PROCESSOR_TYPE_DATA                 ProcessorType;
> +  EFI_PROCESSOR_FAMILY_DATA               ProcessorFamily;
> +  EFI_PROCESSOR_VOLTAGE_DATA              ProcessorVoltage;
> +  EFI_PROCESSOR_APIC_BASE_ADDRESS_DATA    ProcessorApicBase;
> +  EFI_PROCESSOR_APIC_ID_DATA              ProcessorApicId;
> +  EFI_PROCESSOR_APIC_VERSION_NUMBER_DATA
> ProcessorApicVersionNumber;
> +  EFI_PROCESSOR_MICROCODE_REVISION_DATA   CpuUcodeRevisionData;
> +  EFI_PROCESSOR_STATUS_DATA               ProcessorStatus;
> +  EFI_PROCESSOR_SOCKET_TYPE_DATA          ProcessorSocketType;
> +  EFI_PROCESSOR_SOCKET_NAME_DATA          ProcessorSocketName;
> +  EFI_PROCESSOR_ASSET_TAG_DATA            ProcessorAssetTag;
> +  EFI_PROCESSOR_HEALTH_STATUS             ProcessorHealthStatus;
> +  EFI_PROCESSOR_PACKAGE_NUMBER_DATA       ProcessorPackageNumber;
> +} EFI_CPU_VARIABLE_RECORD;
> +*/
> +
> +
> +// Static (possibly build generated) Bios Vendor data.
> +//
> +MISC_SMBIOS_TABLE_DATA(EFI_CPU_DATA_RECORD,
> MiscProcessorInformation) = {
> +
> +0,
> +    /*
> +    STRING_TOKEN (STR_MISC_SOCKET_NAME),		            //
> Processor Socket Name
> +    STRING_TOKEN (STR_MISC_PROCESSOR_MAUFACTURER),		    //
> Processor Manufacturer
> +    STRING_TOKEN (STR_MISC_PROCESSOR_VERSION),		        //
> Processor Version Information
> +	STRING_TOKEN (STR_MISC_PROCESSOR_SERIAL_NUMBER),        //
> Serial Number
> +	STRING_TOKEN (STR_MISC_ASSERT_TAG_DATA),	            //
> Processor Assert TAg Data
> +    STRING_TOKEN (STR_MISC_PART_NUMBER)	                    //
> Processor Part Numbe
> +*/
> +};
> +
> +
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformat
> ionFunction.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformat
> ionFunction.c
> new file mode 100644
> index 0000000000..e01693ede7
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformat
> ionFunction.c
> @@ -0,0 +1,448 @@
> +/*++
> +
> +Copyright (c) 2006  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscProcessorInformationFunction.c
> +
> +Abstract:
> +
> +  Onboard processor information boot time changes.
> +  SMBIOS type 4.
> +
> +--*/
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +#include <Protocol/MpService.h>
> +#include <Protocol/DataHub.h>
> +#include <Guid/DataHubRecords.h>
> +#include <Library/CpuIA32.h>
> +
> +#define EfiProcessorFamilyIntelAtomProcessor    0x2B
> +
> +EFI_GUID                        mProcessorProducerGuid;
> +
> +
> +/**
> +  Get cache SMBIOS record handle.
> +
> +  @param  Smbios        Pointer to SMBIOS protocol instance.
> +  @param  CacheLevel    Level of cache, starting from one.
> +  @param  Handle        Returned record handle.
> +
> +**/
> +
> +VOID
> +GetCacheHandle (
> +  IN  EFI_SMBIOS_PROTOCOL      *Smbios,
> +  IN  UINT8                    CacheLevel,
> +  OUT  EFI_SMBIOS_HANDLE       *Handle
> +  )
> +{
> +  UINT16                     CacheConfig;
> +  EFI_STATUS                 Status;
> +  EFI_SMBIOS_TYPE            RecordType;
> +  EFI_SMBIOS_TABLE_HEADER    *Buffer;
> +
> +  *Handle = 0;
> +  RecordType = EFI_SMBIOS_TYPE_CACHE_INFORMATION;
> +
> +  do {
> +    Status = Smbios->GetNext (
> +                       Smbios,
> +                       Handle,
> +                       &RecordType,
> +                       &Buffer,
> +                       NULL
> +                       );
> +    if (!EFI_ERROR(Status)) {
> +      CacheConfig = *(UINT16*)((UINT8*)Buffer + 5);
> +      if ((CacheConfig & 0x7) == (CacheLevel -1) ) {
> +        return;
> +      }
> +    }
> +  } while (!EFI_ERROR(Status));
> +
> +  *Handle = 0xFFFF;
> +}
> +
> +
> +/**
> +  This function makes boot time changes to the contents of the
> +  MiscProcessorInformation (Type 4).
> +
> +  @param  RecordData                 Pointer to copy of RecordData from the Data
> Table.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
> +
> +**/
> +UINT32
> +ConvertBase10ToRaw (
> +  IN  EFI_EXP_BASE10_DATA             *Data)
> +{
> +  UINTN         Index;
> +  UINT32        RawData;
> +
> +  RawData = Data->Value;
> +  for (Index = 0; Index < (UINTN) Data->Exponent; Index++) {
> +     RawData *= 10;
> +  }
> +
> +  return  RawData;
> +}
> +
> +#define BSEL_CR_OVERCLOCK_CONTROL	0xCD
> +#define	FUSE_BSEL_MASK				0x03
> +
> +
> +
> +UINT16 miFSBFrequencyTable[4] = {
> +  83,          	// 83.3MHz
> +  100,          // 100MHz
> +  133,          // 133MHz
> +  117           // 116.7MHz
> +};
> +
> +/**
> +  Determine the processor core frequency
> +
> +  @param None
> +
> +  @retval Processor core frequency multiplied by 3
> +
> +
> +**/
> +UINT16
> +DetermineiFsbFromMsr (
> +  VOID
> +  )
> +{
> +  //
> +  // Determine the processor core frequency
> +  //
> +  UINT64	Temp;
> +  Temp = (EfiReadMsr (BSEL_CR_OVERCLOCK_CONTROL)) &
> FUSE_BSEL_MASK;
> +  return miFSBFrequencyTable[(UINT32)(Temp)];
> +
> +}
> +
> +MISC_SMBIOS_TABLE_FUNCTION (MiscProcessorInformation)
> +{
> +    CHAR8                           *OptionalStrStart;
> +    EFI_STRING                      SerialNumber;
> +    CHAR16                          *Version=NULL;
> +    CHAR16                          *Manufacturer=NULL;
> +    CHAR16                          *Socket=NULL;
> +    CHAR16                          *AssetTag=NULL;
> +    CHAR16                          *PartNumber=NULL;
> +    UINTN                           SerialNumberStrLen=0;
> +    UINTN                           VersionStrLen=0;
> +    UINTN                           ManufacturerStrLen=0;
> +    UINTN                           SocketStrLen=0;
> +    UINTN                           AssetTagStrLen=0;
> +    UINTN                           PartNumberStrLen=0;
> +    UINTN                           ProcessorVoltage=0xAE;
> +    UINT32                          Eax01;
> +    UINT32                          Ebx01;
> +    UINT32                          Ecx01;
> +    UINT32                          Edx01;
> +    STRING_REF                      TokenToGet;
> +    EFI_STATUS                      Status;
> +    EFI_SMBIOS_HANDLE               SmbiosHandle;
> +    SMBIOS_TABLE_TYPE4              *SmbiosRecord;
> +    EFI_CPU_DATA_RECORD             *ForType4InputData;
> +    UINT16                          L1CacheHandle=0;
> +    UINT16                          L2CacheHandle=0;
> +    UINT16                          L3CacheHandle=0;
> +    UINTN                           NumberOfEnabledProcessors=0 ;
> +    UINTN                           NumberOfProcessors=0;
> +    UINT64                          Frequency = 0;
> +    EFI_MP_SERVICES_PROTOCOL        *MpService;
> +    EFI_DATA_HUB_PROTOCOL           *DataHub;
> +    UINT64                          MonotonicCount;
> +    EFI_DATA_RECORD_HEADER          *Record;
> +    EFI_SUBCLASS_TYPE1_HEADER       *DataHeader;
> +    UINT8                           *SrcData;
> +    EFI_PROCESSOR_VERSION_DATA      *ProcessorVersion;
> +    CHAR16                          *NewStringToken;
> +    STRING_REF                      TokenToUpdate;
> +    PROCESSOR_ID_DATA               *ProcessorId = NULL;
> +
> +
> +    //
> +    // First check for invalid parameters.
> +    //
> +    if (RecordData == NULL) {
> +        return EFI_INVALID_PARAMETER;
> +    }
> +
> +    ForType4InputData = (EFI_CPU_DATA_RECORD *)RecordData;
> +
> +    ProcessorId = AllocateZeroPool(sizeof(PROCESSOR_ID_DATA));
> +    if (ProcessorId == NULL) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +
> +    //
> +    // Get the Data Hub Protocol. Assume only one instance
> +    //
> +    Status = gBS->LocateProtocol (
> +                    &gEfiDataHubProtocolGuid,
> +                    NULL,
> +                    (VOID **)&DataHub
> +                    );
> +    ASSERT_EFI_ERROR(Status);
> +
> +    MonotonicCount = 0;
> +    Record = NULL;
> +
> +    do {
> +      Status = DataHub->GetNextRecord (
> +                          DataHub,
> +                          &MonotonicCount,
> +                          NULL,
> +                          &Record
> +                          );
> +       if (!EFI_ERROR(Status)) {
> +         if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {
> +
> +            DataHeader  = (EFI_SUBCLASS_TYPE1_HEADER *)(Record + 1);
> +            SrcData     = (UINT8  *)(DataHeader + 1);
> +
> +            //
> +            // Processor
> +            //
> +            if (CompareGuid(&Record->DataRecordGuid,
> &gEfiProcessorSubClassGuid)) {
> +              CopyMem (&mProcessorProducerGuid, &Record->ProducerName,
> sizeof(EFI_GUID));
> +              switch (DataHeader->RecordType) {
> +                case ProcessorVoltageRecordType:
> +                  ProcessorVoltage = (((EFI_EXP_BASE10_DATA *)SrcData)-
> >Value)/100 + 0x80;
> +                  break;
> +                case ProcessorCoreFrequencyRecordType:
> +                  DEBUG ((EFI_D_ERROR, "ProcessorCoreFrequencyRecordType
> SrcData1 =%d\n", ConvertBase10ToRaw((EFI_EXP_BASE10_DATA
> *)SrcData)/1000000));
> +                  Frequency = (ConvertBase10ToRaw((EFI_EXP_BASE10_DATA
> *)SrcData)/1000000);
> +                  break;
> +                case ProcessorVersionRecordType:
> +                  ProcessorVersion = (EFI_PROCESSOR_VERSION_DATA *)SrcData;
> +                  NewStringToken =
> HiiGetPackageString(&mProcessorProducerGuid, *ProcessorVersion, NULL);
> +                  TokenToUpdate = (STRING_REF)STR_MISC_PROCESSOR_VERSION;
> +                  HiiSetString(mHiiHandle, TokenToUpdate, NewStringToken, NULL);
> +                  break;
> +                default:
> +                  break;
> +              }
> +            }
> +          }
> +        }
> +    } while (!EFI_ERROR(Status) && (MonotonicCount != 0));
> +
> +    //
> +    // Token to get for Socket Name
> +    //
> +    TokenToGet = STRING_TOKEN (STR_MISC_SOCKET_NAME);
> +    Socket = SmbiosMiscGetString (TokenToGet);
> +    SocketStrLen = StrLen(Socket);
> +    if (SocketStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +         return EFI_UNSUPPORTED;
> +    }
> +
> +    //
> +    // Token to get for Processor Manufacturer
> +    //
> +    TokenToGet = STRING_TOKEN (STR_MISC_PROCESSOR_MAUFACTURER);
> +    Manufacturer = SmbiosMiscGetString (TokenToGet);
> +    ManufacturerStrLen = StrLen(Manufacturer);
> +    if (ManufacturerStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +      return EFI_UNSUPPORTED;
> +    }
> +
> +    //
> +    // Token to get for Processor Version
> +    //
> +    TokenToGet = STRING_TOKEN (STR_MISC_PROCESSOR_VERSION);
> +    Version = SmbiosMiscGetString (TokenToGet);
> +    VersionStrLen = StrLen(Version);
> +    if (VersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +        return EFI_UNSUPPORTED;
> +    }
> +
> +    //
> +    // Token to get for Serial Number
> +    //
> +    TokenToGet = STRING_TOKEN
> (STR_MISC_PROCESSOR_SERIAL_NUMBER);
> +    SerialNumber = SmbiosMiscGetString (TokenToGet);
> +    SerialNumberStrLen = StrLen(SerialNumber);
> +    if (SerialNumberStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +        return EFI_UNSUPPORTED;
> +    }
> +
> +    //
> +    // Token to get for Assert Tag Information
> +    //
> +    TokenToGet = STRING_TOKEN (STR_MISC_ASSERT_TAG_DATA);
> +    AssetTag = SmbiosMiscGetString (TokenToGet);
> +    AssetTagStrLen = StrLen(AssetTag);
> +    if (AssetTagStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +        return EFI_UNSUPPORTED;
> +    }
> +
> +    //
> +    // Token to get for part number Information
> +    //
> +    TokenToGet = STRING_TOKEN (STR_MISC_PART_NUMBER);
> +    PartNumber = SmbiosMiscGetString (TokenToGet);
> +    PartNumberStrLen = StrLen(PartNumber);
> +    if (PartNumberStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +         return EFI_UNSUPPORTED;
> +    }
> +
> +    //
> +    // Two zeros following the last string.
> +    //
> +    SmbiosRecord = AllocateZeroPool(sizeof (SMBIOS_TABLE_TYPE4) +
> AssetTagStrLen + 1 + SocketStrLen + 1+ ManufacturerStrLen +1 +
> VersionStrLen+ 1+ SerialNumberStrLen + 1 + PartNumberStrLen+ 1 + 1);
> +
> +    SmbiosRecord->Hdr.Type =
> EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION;
> +    SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE4);
> +
> +    //
> +    // Make handle chosen by smbios protocol.add automatically.
> +    //
> +    SmbiosRecord->Hdr.Handle = 0;
> +
> +    SmbiosRecord-> Socket= 1;
> +    SmbiosRecord -> ProcessorManufacture = 2;
> +    SmbiosRecord -> ProcessorVersion = 3;
> +    SmbiosRecord ->SerialNumber =4;
> +
> +    SmbiosRecord-> AssetTag= 5;
> +    SmbiosRecord-> PartNumber= 6;
> +
> +    //
> +    // Processor Type
> +    //
> +    ForType4InputData-> VariableRecord.ProcessorType=
> EfiCentralProcessor;
> +    SmbiosRecord -> ProcessorType = ForType4InputData->
> VariableRecord.ProcessorType;
> +
> +    //
> +    // Processor Family
> +    //
> +    ForType4InputData-> VariableRecord.ProcessorFamily=
> EfiProcessorFamilyIntelAtomProcessor; //0x2B;;
> +    SmbiosRecord -> ProcessorFamily = ForType4InputData->
> VariableRecord.ProcessorFamily;
> +    SmbiosRecord -> ExternalClock = DetermineiFsbFromMsr();
> +
> +    //
> +    // Processor ID
> +    //
> +    AsmCpuid(0x001, &Eax01, &Ebx01, &Ecx01, &Edx01);
> +    ProcessorId->Signature = *(PROCESSOR_SIGNATURE *)&Eax01;
> +    ProcessorId->FeatureFlags = *(PROCESSOR_FEATURE_FLAGS *)&Edx01;
> +    SmbiosRecord -> ProcessorId = *(PROCESSOR_ID_DATA *)ProcessorId;
> +
> +    //
> +    // Processor Voltage
> +    //
> +    ForType4InputData-> VariableRecord.ProcessorVoltage=
> *(EFI_PROCESSOR_VOLTAGE_DATA *)&ProcessorVoltage;
> +    SmbiosRecord -> Voltage = *(PROCESSOR_VOLTAGE *)
> &(ForType4InputData-> VariableRecord.ProcessorVoltage);
> +
> +    //
> +    // Status
> +    //
> +    ForType4InputData-> VariableRecord.ProcessorHealthStatus=
> 0x41;//0x41;
> +    SmbiosRecord -> Status = ForType4InputData->
> VariableRecord.ProcessorHealthStatus;
> +
> +    //
> +    // Processor Upgrade
> +    //
> +    SmbiosRecord -> ProcessorUpgrade = 0x008;
> +
> +    //
> +    // Processor Family 2
> +    //
> +    SmbiosRecord -> ProcessorFamily2 = ForType4InputData->
> VariableRecord.ProcessorFamily;
> +
> +    //
> +    // Processor speed
> +    //
> +    SmbiosRecord-> CurrentSpeed = *(UINT16*) & Frequency;
> +    SmbiosRecord-> MaxSpeed = *(UINT16*) & Frequency;
> +
> +    //
> +    // Processor Characteristics
> +    //
> +    AsmCpuid(0x8000000, NULL, NULL, NULL, &Edx01);
> +    Edx01= Edx01 >> 28;
> +    Edx01 &= 0x01;
> +    SmbiosRecord-> ProcessorCharacteristics= (UINT16)Edx01;
> +
> +    //
> +    // Processor Core Count and Enabled core count
> +    //
> +    Status = gBS->LocateProtocol (
> +                    &gEfiMpServiceProtocolGuid,
> +                    NULL,
> +                    (void **)&MpService
> +                    );
> +    if (!EFI_ERROR (Status)) {
> +    //
> +    // Determine the number of processors
> +    //
> +    MpService->GetNumberOfProcessors (
> +                 MpService,
> +                 &NumberOfProcessors,
> +                 &NumberOfEnabledProcessors
> +                 );
> +    }
> +    SmbiosRecord-> CoreCount= (UINT8)NumberOfProcessors;
> +    SmbiosRecord-> EnabledCoreCount=
> (UINT8)NumberOfEnabledProcessors;
> +    SmbiosRecord-> ThreadCount= (UINT8)NumberOfEnabledProcessors;
> +    SmbiosRecord-> ProcessorCharacteristics = 0x2; // Unknown
> +
> +    //
> +    // Processor Cache Handle
> +    //
> +    GetCacheHandle( Smbios,1, &L1CacheHandle);
> +    GetCacheHandle( Smbios,2, &L2CacheHandle);
> +    GetCacheHandle( Smbios,3, &L3CacheHandle);
> +
> +    //
> +    // Updating Cache Handle Information
> +    //
> +    SmbiosRecord->L1CacheHandle  = L1CacheHandle;
> +    SmbiosRecord->L2CacheHandle  = L2CacheHandle;
> +    SmbiosRecord->L3CacheHandle  = L3CacheHandle;
> +
> +    OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
> +    UnicodeStrToAsciiStr(Socket, OptionalStrStart);
> +    UnicodeStrToAsciiStr(Manufacturer, OptionalStrStart + SocketStrLen + 1);
> +    UnicodeStrToAsciiStr(Version, OptionalStrStart + SocketStrLen + 1 +
> ManufacturerStrLen+ 1);
> +    UnicodeStrToAsciiStr(SerialNumber, OptionalStrStart + SocketStrLen + 1 +
> VersionStrLen + 1 + ManufacturerStrLen + 1);
> +    UnicodeStrToAsciiStr(AssetTag, OptionalStrStart + SerialNumberStrLen + 1
> + VersionStrLen + 1 + ManufacturerStrLen + 1 + SocketStrLen + 1);
> +    UnicodeStrToAsciiStr(PartNumber, OptionalStrStart + SerialNumberStrLen
> + 1 + VersionStrLen + 1 + ManufacturerStrLen + 1 + SocketStrLen + 1 +
> AssetTagStrLen + 1 );
> +
> +    //
> +    // Now we have got the full Smbios record, call Smbios protocol to add
> this record.
> +    //
> +    SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +    Status = Smbios-> Add(
> +                        Smbios,
> +                        NULL,
> +                        &SmbiosHandle,
> +                        (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
> +                        );
> +    if (EFI_ERROR (Status)) return Status;
> +    FreePool(SmbiosRecord);
> +    return Status;
> +
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesD
> ata.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesD
> ata.c
> new file mode 100644
> index 0000000000..e3b847f7ce
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesD
> ata.c
> @@ -0,0 +1,43 @@
> +/** @file
> +
> +Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +    MiscResetCapabilitiesData.c
> +
> +Abstract:
> +
> +  Static data of Reset Capabilities information.
> +  Reset Capabilities information is Misc. subclass type 17 and SMBIOS type 23.
> +
> +
> +**/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +//
> +// Static (possibly build generated) Bios Vendor data.
> +//
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_RESET_CAPABILITIES,
> MiscResetCapabilities)
> += {
> +  {       // ResetCapabilities
> +    0,    // Status
> +    0,    // BootOption
> +    0,    // BootOptionOnLimit
> +    0,    // WatchdogTimerPresent
> +    0     // Reserved
> +  },
> +  0xFFFF, // ResetCount
> +  0xFFFF, // ResetLimit
> +  0xFFFF, // ResetTimerInterval
> +  0xFFFF  // ResetTimeout
> +};
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesF
> unction.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesF
> unction.c
> new file mode 100644
> index 0000000000..67a549a6ba
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesF
> unction.c
> @@ -0,0 +1,85 @@
> +/*++
> +
> +Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  MiscResetCapabilitiesFunction.c
> +
> +Abstract:
> +
> +  ResetCapabilities.
> +  SMBIOS type 23.
> +
> +--*/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +/**
> +  This function makes boot time changes to the contents of the
> +  MiscOemString (Type 11).
> +
> +  @param  RecordData                 Pointer to copy of RecordData from the Data
> Table.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
> +
> +**/
> +MISC_SMBIOS_TABLE_FUNCTION(MiscResetCapabilities)
> +{
> +  EFI_STATUS               Status;
> +  EFI_SMBIOS_HANDLE        SmbiosHandle;
> +  SMBIOS_TABLE_TYPE23      *SmbiosRecord;
> +  EFI_MISC_RESET_CAPABILITIES   *ForType23InputData;
> +
> +  ForType23InputData = (EFI_MISC_RESET_CAPABILITIES *)RecordData;
> +
> +  //
> +  // First check for invalid parameters.
> +  //
> +  if (RecordData == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +
> +  //
> +  // Two zeros following the last string.
> +  //
> +  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE23) + 1 + 1);
> +  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE23) + 1 + 1);
> +
> +  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_RESET;
> +  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE23);
> +
> +  //
> +  // Make handle chosen by smbios protocol.add automatically.
> +  //
> +  SmbiosRecord->Hdr.Handle    = 0;
> +  SmbiosRecord->Capabilities  = *(UINT8*)&(ForType23InputData-
> >ResetCapabilities);
> +  SmbiosRecord->ResetCount    = (UINT16)ForType23InputData-
> >ResetCount;
> +  SmbiosRecord->ResetLimit    = (UINT16)ForType23InputData->ResetLimit;
> +  SmbiosRecord->TimerInterval = (UINT16)ForType23InputData-
> >ResetTimerInterval;
> +  SmbiosRecord->Timeout       = (UINT16)ForType23InputData-
> >ResetTimeout;
> +
> +  //
> +  // Now we have got the full smbios record, call smbios protocol to add this
> record.
> +  //
> +  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +  Status = Smbios-> Add(
> +                      Smbios,
> +                      NULL,
> +                      &SmbiosHandle,
> +                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
> +                      );
> +  FreePool(SmbiosRecord);
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.h
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.h
> new file mode 100644
> index 0000000000..67ea100fad
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.h
> @@ -0,0 +1,188 @@
> +/** @file
> +
> +Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscSubclassDriver.h
> +
> +Abstract:
> +
> +  Header file for MiscSubclass Driver.
> +
> +
> +**/
> +
> +#ifndef _MISC_SUBCLASS_DRIVER_H
> +#define _MISC_SUBCLASS_DRIVER_H
> +
> +
> +#include "CommonHeader.h"
> +
> +extern UINT8  MiscSubclassStrings[];
> +
> +
> +#define T14_FVI_STRING          "Driver/firmware version"
> +#define EFI_SMBIOS_TYPE_FIRMWARE_VERSION_INFO 0x90
> +#define EFI_SMBIOS_TYPE_MISC_VERSION_INFO 0x94
> +#define TOUCH_ACPI_ID    "I2C05\\SFFFF\\400K"
> +#define TOUCH_RESET_GPIO_MMIO  0xFED0C508
> +#define EFI_SMBIOS_TYPE_SEC_INFO 0x83
> +#define IntelIdentifer 0x6F725076
> +
> +//
> +// Data table entry update function.
> +//
> +typedef EFI_STATUS (EFIAPI EFI_MISC_SMBIOS_DATA_FUNCTION) (
> +  IN  VOID                 *RecordData,
> +  IN  EFI_SMBIOS_PROTOCOL  *Smbios
> +  );
> +
> +//
> +// Data table entry definition.
> +//
> +typedef struct {
> +  //
> +  // intermediat input data for SMBIOS record
> +  //
> +  VOID                              *RecordData;
> +  EFI_MISC_SMBIOS_DATA_FUNCTION     *Function;
> +} EFI_MISC_SMBIOS_DATA_TABLE;
> +
> +//
> +// Data Table extern definitions.
> +//
> +#define MISC_SMBIOS_TABLE_EXTERNS(NAME1, NAME2, NAME3) \
> +extern NAME1 NAME2 ## Data; \
> +extern EFI_MISC_SMBIOS_DATA_FUNCTION NAME3 ## Function
> +
> +
> +//
> +// Data Table entries
> +//
> +#define MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(NAME1,
> NAME2) \
> +{ \
> +  & NAME1 ## Data, \
> +  & NAME2 ## Function \
> +}
> +
> +//
> +// Global definition macros.
> +//
> +#define MISC_SMBIOS_TABLE_DATA(NAME1, NAME2) \
> +  NAME1 NAME2 ## Data
> +
> +#define MISC_SMBIOS_TABLE_FUNCTION(NAME2) \
> +  EFI_STATUS EFIAPI NAME2 ## Function( \
> +  IN  VOID                  *RecordData, \
> +  IN  EFI_SMBIOS_PROTOCOL   *Smbios \
> +  )
> +
> +#pragma pack(1)
> +
> +//
> +// This is definition for SMBIOS Oem data type 0x90
> +//
> +typedef struct {
> +  STRING_REF                         SECVersion;
> +  STRING_REF                         uCodeVersion;
> +  STRING_REF                         GOPVersion;
> +  STRING_REF                         CpuStepping;
> +} EFI_MISC_OEM_TYPE_0x90;
> +
> +//
> +// This is definition for SMBIOS Oem data type 0x90
> +//
> +typedef struct {
> +  SMBIOS_STRUCTURE          Hdr;
> +  SMBIOS_TABLE_STRING       SECVersion;
> +  SMBIOS_TABLE_STRING       uCodeVersion;
> +  SMBIOS_TABLE_STRING       GOPVersion;
> +  SMBIOS_TABLE_STRING       CpuStepping;
> +} SMBIOS_TABLE_TYPE90;
> +
> +typedef struct {
> +  STRING_REF                GopVersion;
> +  STRING_REF                UCodeVersion;
> +  STRING_REF                MRCVersion;
> +  STRING_REF                SECVersion;
> +  STRING_REF                ULPMCVersion;
> +  STRING_REF                PMCVersion;
> +  STRING_REF                PUnitVersion;
> +  STRING_REF                SoCVersion;
> +  STRING_REF                BoardVersion;
> +  STRING_REF                FabVersion;
> +  STRING_REF                CPUFlavor;
> +  STRING_REF                BiosVersion;
> +  STRING_REF                PmicVersion;
> +  STRING_REF                TouchVersion;
> +  STRING_REF                SecureBoot;
> +  STRING_REF                BootMode;
> +  STRING_REF                SpeedStepMode;
> +  STRING_REF                CPUTurboMode;
> +  STRING_REF                MaxCState;
> +  STRING_REF                GfxTurbo;
> +  STRING_REF                IdleReserve;
> +  STRING_REF                RC6;
> +}EFI_MISC_OEM_TYPE_0x94;
> +
> +typedef struct {
> +  SMBIOS_STRUCTURE          Hdr;
> +  SMBIOS_TABLE_STRING       GopVersion;
> +  SMBIOS_TABLE_STRING       uCodeVersion;
> +  SMBIOS_TABLE_STRING       MRCVersion;
> +  SMBIOS_TABLE_STRING       SECVersion;
> +  SMBIOS_TABLE_STRING       ULPMCVersion;
> +  SMBIOS_TABLE_STRING       PMCVersion;
> +  SMBIOS_TABLE_STRING       PUnitVersion;
> +  SMBIOS_TABLE_STRING       SoCVersion;
> +  SMBIOS_TABLE_STRING       BoardVersion;
> +  SMBIOS_TABLE_STRING       FabVersion;
> +  SMBIOS_TABLE_STRING       CPUFlavor;
> +  SMBIOS_TABLE_STRING       BiosVersion;
> +  SMBIOS_TABLE_STRING       PmicVersion;
> +  SMBIOS_TABLE_STRING       TouchVersion;
> +  SMBIOS_TABLE_STRING       SecureBoot;
> +  SMBIOS_TABLE_STRING       BootMode;
> +  SMBIOS_TABLE_STRING       SpeedStepMode;
> +  SMBIOS_TABLE_STRING       CPUTurboMode;
> +  SMBIOS_TABLE_STRING       MaxCState;
> +  SMBIOS_TABLE_STRING       GfxTurbo;
> +  SMBIOS_TABLE_STRING       IdleReserve;
> +  SMBIOS_TABLE_STRING       RC6;
> +}SMBIOS_TABLE_TYPE94;
> +
> +#pragma pack()
> +//
> +// Data Table Array
> +//
> +extern EFI_MISC_SMBIOS_DATA_TABLE mMiscSubclassDataTable[];
> +
> +//
> +// Data Table Array Entries
> +//
> +extern UINTN                        mMiscSubclassDataTableEntries;
> +extern EFI_HII_HANDLE               mHiiHandle;
> +
> +//
> +// Prototypes
> +//
> +EFI_STATUS
> +EFIAPI
> +MiscSubclassDriverEntryPoint (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  );
> +
> +EFI_STRING
> +EFIAPI
> +SmbiosMiscGetString (
> +  IN EFI_STRING_ID   StringId
> +  );
> +
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.uni
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.uni
> new file mode 100644
> index 0000000000..3a6ccf1d75
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.uni
> @@ -0,0 +1,35 @@
> +// *++
> +//
> +// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//
> +// Module Name:
> +//
> +//  MiscSubclassDriver.uni
> +//
> +// Abstract:
> +//
> +//   Misc Subclass information.
> +//
> +// Revision History:
> +//
> +// --*/
> +
> +/=#
> +
> +#langdef en-US "English"
> +
> +#string STR_MISC_SUBCLASS_DRIVER_TITLE #language en-US  "Not used"
> +
> +#include "MiscBaseBoardManufacturer.uni"
> +#include "MiscBiosVendor.uni"
> +#include "MiscChassisManufacturer.uni"
> +#include "MiscOemString.uni"
> +#include "MiscOnboardDevice.uni"
> +#include "MiscPortInternalConnectorDesignator.uni"
> +#include "MiscSystemLanguageString.uni"
> +#include "MiscSystemManufacturer.uni"
> +#include "MiscSystemOptionString.uni"
> +#include "MiscSystemSlotDesignation.uni"
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverData
> Table.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverDat
> aTable.c
> new file mode 100644
> index 0000000000..93347a1a04
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverDat
> aTable.c
> @@ -0,0 +1,98 @@
> +/** @file
> +
> +Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscSubclassDriverDataTable.c
> +
> +Abstract:
> +
> +  Create the mMiscSubclassDataTable structure, and it is used to report
> +  any generate data to the DataHub.
> +
> +
> +**/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +//
> +// External definitions referenced by Data Table entries.
> +//
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_BIOS_VENDOR_DATA,
> MiscBiosVendor, MiscBiosVendor);
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_MANUFACTURER_DAT
> A, MiscSystemManufacturer, MiscSystemManufacturer);
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_BASE_BOARD_MANUFACTURE
> R_DATA, MiscBaseBoardManufacturer, MiscBaseBoardManufacturer);
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_CHASSIS_MANUFACTURER_DA
> TA, MiscChassisManufacturer, MiscChassisManufacturer);
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_CACHE_VARIABLE_RECORD,
> MiscProcessorCache, MiscProcessorCache); //type 7
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_CPU_DATA_RECORD,
> MiscProcessorInformation, MiscProcessorInformation); //type 4
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MEMORY_ARRAY_LOCATION_DATA,
> MiscPhysicalMemoryArray,MiscPhysicalMemoryArray);
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MEMORY_ARRAY_LINK_DATA,
> MiscMemoryDevice, MiscMemoryDevice);
> +
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR
> _DESIGNATOR_DATA, MiscPortIde1, MiscPortInternalConnectorDesignator);
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR
> _DESIGNATOR_DATA, MiscPortIde2, MiscPortInternalConnectorDesignator);
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR
> _DESIGNATOR_DATA, MiscPortAtxPower,
> MiscPortInternalConnectorDesignator);
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION_
> DATA, MiscSystemSlotPCIEx16Slot1, MiscSystemSlotDesignation);
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION_
> DATA, MiscSystemSlotPCIEx16Slot2, MiscSystemSlotDesignation);
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION_
> DATA, MiscSystemSlotPCIEx4, MiscSystemSlotDesignation);
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION_
> DATA, MiscSystemSlotPCIEx1Slot1, MiscSystemSlotDesignation);
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION_
> DATA, MiscSystemSlotPCIEx1Slot2, MiscSystemSlotDesignation);
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION_
> DATA, MiscSystemSlotPCIEx1Slot3, MiscSystemSlotDesignation);
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION_
> DATA, MiscSystemSlotPCI1, MiscSystemSlotDesignation);
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION_
> DATA, MiscSystemSlotPCI2, MiscSystemSlotDesignation);
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION_
> DATA, MiscSystemSlotPCI3, MiscSystemSlotDesignation);
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_ONBOARD_DEVICE_DATA,
> MiscOnboardDeviceVideo, MiscOnboardDevice);
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_ONBOARD_DEVICE_DATA,
> MiscOnboardDeviceNetwork, MiscOnboardDevice);
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_ONBOARD_DEVICE_DATA,
> MiscOnboardDeviceAudio, MiscOnboardDevice);
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_NUMBER_OF_INSTALLABLE_LA
> NGUAGES_DATA, NumberOfInstallableLanguages,
> NumberOfInstallableLanguages);
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_LANGUAGE_STRING_
> DATA, SystemLanguageString, SystemLanguageString);
> +MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_BOOT_INFORMATION_STATUS
> _DATA, BootInformationStatus, BootInformationStatus);
> +
> +//
> +// Data Table.
> +//
> +EFI_MISC_SMBIOS_DATA_TABLE  mMiscSubclassDataTable[] = {
> +  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscBiosVendor,
> MiscBiosVendor),
> +
> MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemManufact
> urer, MiscSystemManufacturer),
> +
> MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscBaseBoardManu
> facturer, MiscBaseBoardManufacturer),
> +
> MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscChassisManufact
> urer, MiscChassisManufacturer),
> +
> MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscProcessorCache,
> MiscProcessorCache),  //type 7
> +
> MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscProcessorInform
> ation, MiscProcessorInformation),  //type 4
> +
> MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPhysicalMemory
> Array, MiscPhysicalMemoryArray),    //Type 16
> +
> MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscMemoryDevice,
> MiscMemoryDevice), //Type 17
> +  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortIde1,
> MiscPortInternalConnectorDesignator),
> +  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortIde2,
> MiscPortInternalConnectorDesignator),
> +  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortAtxPower,
> MiscPortInternalConnectorDesignator),
> +
> MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlotPCIEx
> 16Slot1, MiscSystemSlotDesignation),
> +
> MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlotPCIEx
> 16Slot2, MiscSystemSlotDesignation),
> +
> MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlotPCIEx
> 4, MiscSystemSlotDesignation),
> +
> MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlotPCIEx
> 1Slot1, MiscSystemSlotDesignation),
> +
> MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlotPCIEx
> 1Slot2, MiscSystemSlotDesignation),
> +
> MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlotPCIEx
> 1Slot3, MiscSystemSlotDesignation),
> +
> MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlotPCI1,
> MiscSystemSlotDesignation),
> +
> MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlotPCI2,
> MiscSystemSlotDesignation),
> +
> MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlotPCI3,
> MiscSystemSlotDesignation),
> +#if defined( ALWAYS_DISABLE_ONBOARD_VIDEO ) && \
> +    ( ALWAYS_DISABLE_ONBOARD_VIDEO != 0 )
> +
> MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscOnboardDevice
> Network, MiscOnboardDevice),
> +
> MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscOnboardDeviceA
> udio, MiscOnboardDevice),
> +#else
> +
> MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscOnboardDeviceV
> ideo, MiscOnboardDevice),
> +
> MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscOnboardDeviceA
> udio, MiscOnboardDevice),
> +#endif
> +
> MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(SystemLanguageStrin
> g, SystemLanguageString),
> +
> MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(BootInformationStat
> us, BootInformationStatus),
> +};
> +
> +//
> +// Number of Data Table entries.
> +//
> +UINTN mMiscSubclassDataTableEntries =
> +        (sizeof mMiscSubclassDataTable) /
> sizeof(EFI_MISC_SMBIOS_DATA_TABLE);
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverEntr
> yPoint.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverEntr
> yPoint.c
> new file mode 100644
> index 0000000000..e70732f5c2
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverEntr
> yPoint.c
> @@ -0,0 +1,182 @@
> +/** @file
> +
> +Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscSubclassDriverEntryPoint.c
> +
> +Abstract:
> +
> +  This driver parses the mMiscSubclassDataTable structure and reports
> +  any generated data to the DataHub.
> +
> +
> +**/
> +
> +
> +#include "CommonHeader.h"
> +#include "MiscSubclassDriver.h"
> +#include <Protocol/HiiString.h>
> +#include <Guid/PlatformInfo.h>
> +
> +
> +EFI_HII_HANDLE  mHiiHandle;
> +EFI_HII_STRING_PROTOCOL  *mHiiString;
> +EFI_PLATFORM_INFO_HOB *mPlatformInfo=NULL;
> +
> +EFI_STRING
> +EFIAPI
> +SmbiosMiscGetString (
> +  IN EFI_STRING_ID   StringId
> +  ){
> +
> +  EFI_STATUS  Status;
> +  UINTN       StringSize;
> +  CHAR16      TempString;
> +  EFI_STRING  String;
> +  String             = NULL;
> +
> +  //
> +  // Retrieve the size of the string in the string package for the BestLanguage
> +  //
> +  StringSize = 0;
> +  Status = mHiiString->GetString (
> +                         mHiiString,
> +                         "en-US",
> +                         mHiiHandle,
> +                         StringId,
> +                         &TempString,
> +                         &StringSize,
> +                         NULL
> +                         );
> +  //
> +  // If GetString() returns EFI_SUCCESS for a zero size,
> +  // then there are no supported languages registered for HiiHandle.  If
> GetString()
> +  // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is
> not present
> +  // in the HII Database
> +  //
> +  if (Status != EFI_BUFFER_TOO_SMALL) {
> +    goto Error;
> +  }
> +
> +  //
> +  // Allocate a buffer for the return string
> +  //
> +  String = AllocateZeroPool (StringSize);
> +  if (String == NULL) {
> +    goto Error;
> +  }
> +
> +  //
> +  // Retrieve the string from the string package
> +  //
> +  Status = mHiiString->GetString (
> +                         mHiiString,
> +                         "en-US",
> +                         mHiiHandle,
> +                         StringId,
> +                         String,
> +                         &StringSize,
> +                         NULL
> +                         );
> +  if (EFI_ERROR (Status)) {
> +    //
> +    // Free the buffer and return NULL if the supported languages can not be
> retrieved.
> +    //
> +    FreePool (String);
> +    String = NULL;
> +  }
> +Error:
> +
> +  return String;
> +}
> +
> +/**
> +  Standard EFI driver point.  This driver parses the mMiscSubclassDataTable
> +  structure and reports any generated data to the DataHub.
> +
> +  @param ImageHandle   - Handle for the image of this driver
> +  @param SystemTable   - Pointer to the EFI System Table
> +
> +  @retval EFI_SUCCESS      - The data was successfully reported to the Data
> Hub.
> +  @retval EFI_DEVICE_ERROR - Can not locate any protocols
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +MiscSubclassDriverEntryPoint (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  )
> +{
> +  UINTN                Index;
> +  EFI_STATUS           EfiStatus;
> +  EFI_SMBIOS_PROTOCOL  *Smbios;
> +  EFI_PEI_HOB_POINTERS GuidHob;
> +
> +
> +
> +  GuidHob.Raw = GetHobList ();
> +  if (GuidHob.Raw != NULL) {
> +    if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformInfoGuid,
> GuidHob.Raw)) != NULL) {
> +      mPlatformInfo = GET_GUID_HOB_DATA (GuidHob.Guid);
> +    }
> +  }
> +
> +  DEBUG ((EFI_D_ERROR, "PlatformInfoHob->BoardId [0x%x]\n",
> mPlatformInfo->BoardId));
> +
> +  //
> +  // Retrieve the pointer to the UEFI HII String Protocol
> +  //
> +  EfiStatus = gBS->LocateProtocol (
> +                     &gEfiHiiStringProtocolGuid,
> +                     NULL,
> +                     (VOID **) &mHiiString
> +                     );
> +  ASSERT_EFI_ERROR (EfiStatus);
> +
> +  EfiStatus = gBS->LocateProtocol(
> +                     &gEfiSmbiosProtocolGuid,
> +                     NULL,
> +                     (VOID**)&Smbios
> +                     );
> +
> +  if (EFI_ERROR(EfiStatus)) {
> +    DEBUG((EFI_D_ERROR, "Could not locate SMBIOS protocol.  %r\n",
> EfiStatus));
> +    return EfiStatus;
> +  }
> +
> +  mHiiHandle = HiiAddPackages (
> +                 &gEfiCallerIdGuid,
> +                 NULL,
> +                 MiscSubclassStrings,
> +                 NULL
> +                 );
> +  ASSERT (mHiiHandle != NULL);
> +
> +  for (Index = 0; Index < mMiscSubclassDataTableEntries; ++Index) {
> +    //
> +    // If the entry have a function pointer, just log the data.
> +    //
> +    if (mMiscSubclassDataTable[Index].Function != NULL) {
> +      EfiStatus = (*mMiscSubclassDataTable[Index].Function)(
> +        mMiscSubclassDataTable[Index].RecordData,
> +        Smbios
> +        );
> +
> +      if (EFI_ERROR(EfiStatus)) {
> +        DEBUG((EFI_D_ERROR, "Misc smbios store error.  Index=%d,
> ReturnStatus=%r\n", Index, EfiStatus));
> +        return EfiStatus;
> +      }
> +    }
> +  }
> +
> +  return EfiStatus;
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageSt
> ring.uni
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageSt
> ring.uni
> new file mode 100644
> index 0000000000..9f3fdf8a3f
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageSt
> ring.uni
> @@ -0,0 +1,24 @@
> +// *++
> +//
> +// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//
> +// Module Name:
> +//
> +//   MiscSystemLanguageString.uni
> +//
> +// Abstract:
> +//
> +//   System language information
> +//
> +// Revision History:
> +//
> +// --*/
> +
> +
> +/=#
> +
> +#langdef en-US "English"
> +
> +#string STR_MISC_SYSTEM_LANGUAGE_EN_US #language en-US  "enUS"
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageSt
> ringData.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageSt
> ringData.c
> new file mode 100644
> index 0000000000..a9def23560
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageSt
> ringData.c
> @@ -0,0 +1,34 @@
> +/** @file
> +
> +Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscSystemLanguageStringData.c
> +
> +Abstract:
> +
> +  Static data of System language string information.
> +  System language string information is Misc. subclass type 12 and SMBIOS
> type 13.
> +
> +
> +**/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +//
> +// Static (possibly build generated) Bios Vendor data.
> +//
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_LANGUAGE_STRING_DAT
> A, SystemLanguageString)
> += {
> +  0,
> +  STRING_TOKEN(STR_MISC_SYSTEM_LANGUAGE_EN_US)
> +};
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageSt
> ringFunction.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageSt
> ringFunction.c
> new file mode 100644
> index 0000000000..8abfa4074a
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageSt
> ringFunction.c
> @@ -0,0 +1,93 @@
> +/*++
> +
> +Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +  MiscResetCapabilitiesFunction.c
> +
> +Abstract:
> +
> +  ResetCapabilities.
> +  SMBIOS type 23.
> +
> +--*/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +/**
> +  This function makes boot time changes to the contents of the
> +  MiscOemString (Type 11).
> +
> +  @param  RecordData                 Pointer to copy of RecordData from the Data
> Table.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
> +
> +**/
> +
> +MISC_SMBIOS_TABLE_FUNCTION(SystemLanguageString)
> +{
> +  EFI_STATUS               Status;
> +  EFI_SMBIOS_HANDLE        SmbiosHandle;
> +  SMBIOS_TABLE_TYPE13      *SmbiosRecord;
> +  UINTN                    StrLeng;
> +  CHAR8                    *OptionalStrStart;
> +  EFI_STRING               Str;
> +  STRING_REF               TokenToGet;
> +
> +
> +  //
> +  // First check for invalid parameters.
> +  //
> +  if (RecordData == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_LANGUAGE_EN_US);
> +  Str = SmbiosMiscGetString (TokenToGet);
> +  StrLeng = StrLen(Str);
> +  if (StrLeng > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Two zeros following the last string.
> +  //
> +  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE13) + StrLeng +
> 1 + 1);
> +  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE13) + StrLeng + 1 +
> 1);
> +
> +  SmbiosRecord->Hdr.Type =
> EFI_SMBIOS_TYPE_BIOS_LANGUAGE_INFORMATION;
> +  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE13);
> +
> +  //
> +  // Make handle chosen by smbios protocol.add automatically.
> +  //
> +  SmbiosRecord->Hdr.Handle    = 0;
> +  SmbiosRecord->InstallableLanguages = 1;
> +  SmbiosRecord->Flags   = 1;
> +  SmbiosRecord->CurrentLanguages = 1;
> +  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
> +  UnicodeStrToAsciiStr(Str, OptionalStrStart);
> +
> +  //
> +  // Now we have got the full smbios record, call smbios protocol to add this
> record.
> +  //
> +  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +  Status = Smbios-> Add(
> +                      Smbios,
> +                      NULL,
> +                      &SmbiosHandle,
> +                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
> +                      );
> +  FreePool(SmbiosRecord);
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufactu
> rer.uni
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufactu
> rer.uni
> new file mode 100644
> index 0000000000..d587e0d7df
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufactu
> rer.uni
> @@ -0,0 +1,30 @@
> +// *++
> +//
> +// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//
> +// Module Name:
> +//
> +//   MiscSystemManufacturer.uni
> +//
> +// Abstract:
> +//
> +//   System manufacturer information
> +//
> +// Revision History:
> +//
> +// --*/
> +
> +
> +/=#
> +
> +#langdef en-US "English"
> +
> +#string STR_MISC_SYSTEM_MANUFACTURER   #language en-US  "Circuitco"
> +#string STR_MISC_SYSTEM_PRODUCT_NAME   #language en-US
> "VALLEYVIEW A0 PLATFORM"
> +#string STR_MISC_SYSTEM_VERSION        #language en-US  "A0"
> +#string STR_MISC_SYSTEM_SERIAL_NUMBER  #language en-US  "To be
> filled by O.E.M"
> +#string STR_MISC_SYSTEM_SKU_NUMBER     #language en-US  "To be filled
> by O.E.M"
> +#string STR_MISC_SYSTEM_FAMILY_NAME    #language en-US  "IA Tablet"
> +#string STR_MISC_SYSTEM_FAMILY_NAME1   #language en-US  "IA
> Notebook"
> \ No newline at end of file
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufactu
> rerData.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufactu
> rerData.c
> new file mode 100644
> index 0000000000..dc12fa8e16
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufactu
> rerData.c
> @@ -0,0 +1,48 @@
> +/** @file
> +
> +Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscSystemManufacturerData.c
> +
> +Abstract:
> +
> +  Static data of System manufacturer information.
> +  System manufacturer information is Misc. subclass type 3 and SMBIOS
> type 1.
> +
> +
> +**/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +//
> +// Static (possibly build generated) System Manufacturer data.
> +//
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_MANUFACTURER_DATA,
> MiscSystemManufacturer)
> += {
> +  STRING_TOKEN(STR_MISC_SYSTEM_MANUFACTURER),  //
> SystemManufactrurer
> +  STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME),  //
> SystemProductName
> +  STRING_TOKEN(STR_MISC_SYSTEM_VERSION),       // SystemVersion
> +  STRING_TOKEN(STR_MISC_SYSTEM_SERIAL_NUMBER), //
> SystemSerialNumber
> +  {                                            // SystemUuid
> +  	//
> +    // Undefined GUID but can be programmed later.
> +    //0xFFFFFFFF, 0xFFFF, 0xFFFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
> 0xFF
> +
> +    // Undefined GUID that cannot be programmed later.
> +    //0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> 0x00
> +	// TODO Hard code here for WHCT test.
> +	0xa5000288, 0x6462, 0x4524, 0x98, 0x6a, 0x9b, 0x77, 0x37, 0xe3, 0x15,
> 0xcf
> +	//
> +  },
> +  EfiSystemWakeupTypePowerSwitch  // SystemWakeupType
> +};
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufactu
> rerFunction.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufactu
> rerFunction.c
> new file mode 100644
> index 0000000000..63c4f50ed5
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufactu
> rerFunction.c
> @@ -0,0 +1,364 @@
> +/*++
> +
> +Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +
> +Module Name:
> +
> +  MiscSystemManufacturerFunction.c
> +
> +Abstract:
> +
> +  This driver parses the mMiscSubclassDataTable structure and reports
> +  any generated data.
> +
> +--*/
> +
> +
> +#include "CommonHeader.h"
> +#include "MiscSubclassDriver.h"
> +#include <Protocol/DxeSmmReadyToLock.h>
> +#include <Library/NetLib.h>
> +#include "Library/DebugLib.h"
> +#include <Uefi/UefiBaseType.h>
> +#include <Guid/PlatformInfo.h>
> +
> +
> +extern EFI_PLATFORM_INFO_HOB *mPlatformInfo;
> +
> +
> +/**
> +
> +  Publish the smbios type 1.
> +
> +  @param Event      Event whose notification function is being invoked
> (gEfiDxeSmmReadyToLockProtocolGuid).
> +  @param Context    Pointer to the notification functions context, which is
> implementation dependent.
> +
> +  @retval None
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AddSmbiosManuCallback (
> +  IN EFI_EVENT  Event,
> +  IN VOID       *Context
> +  )
> +{
> +
> +  CHAR8                             *OptionalStrStart;
> +  UINTN                             ManuStrLen;
> +  UINTN                             VerStrLen;
> +  UINTN                             PdNameStrLen;
> +  UINTN                             SerialNumStrLen;
> +  UINTN                             SkuNumberStrLen;
> +  UINTN				                FamilyNameStrLen;
> +  EFI_STATUS                        Status;
> +  EFI_STRING                        Manufacturer;
> +  EFI_STRING                        ProductName;
> +  EFI_STRING                        Version;
> +  EFI_STRING                        SerialNumber;
> +  EFI_STRING                        SkuNumber;
> +  EFI_STRING			            FamilyName;
> +  STRING_REF                        TokenToGet;
> +  EFI_SMBIOS_HANDLE                 SmbiosHandle;
> +  SMBIOS_TABLE_TYPE1                *SmbiosRecord;
> +  EFI_MISC_SYSTEM_MANUFACTURER      *ForType1InputData;
> +  EFI_SMBIOS_PROTOCOL               *Smbios;
> +  CHAR16                            Buffer[40];
> +
> +  CHAR16                            *MacStr;
> +  EFI_HANDLE                        *Handles;
> +  UINTN                             BufferSize;
> +  CHAR16                            PlatformNameBuffer[40];
> +
> +  ForType1InputData = (EFI_MISC_SYSTEM_MANUFACTURER *)Context;
> +
> +  //
> +  // First check for invalid parameters.
> +  //
> +  if (Context == NULL || mPlatformInfo == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID *)
> &Smbios);
> +  ASSERT_EFI_ERROR (Status);
> +
> +
> +  if (BOARD_ID_MINNOW2_TURBOT == mPlatformInfo->BoardId) {
> +    // Detect the board is Turbot board platform
> +    UnicodeSPrint (PlatformNameBuffer, sizeof
> (PlatformNameBuffer),L"%s",L"Minnowboard Turbot ");
> +  } else {
> +    UnicodeSPrint (PlatformNameBuffer, sizeof
> (PlatformNameBuffer),L"%s",L"Minnowboard Max ");
> +  }
> +
> +  //
> +  // Silicon Steppings
> +  //
> +  switch (PchStepping()) {
> +    case PchA0:
> +      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer,
> L"A0 PLATFORM");
> +
> HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NA
> ME), Buffer, NULL);
> +      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"A0");
> +      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION),
> Buffer, NULL);
> +      DEBUG ((EFI_D_ERROR, "A0 Stepping Detected\n"));
> +      break;
> +    case PchA1:
> +      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer,
> L"A1 PLATFORM");
> +
> HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NA
> ME), Buffer, NULL);
> +      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"A1");
> +      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION),
> Buffer, NULL);
> +      DEBUG ((EFI_D_ERROR, "A1 Stepping Detected\n"));
> +      break;
> +    case PchB0:
> +      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer,
> L"B0 PLATFORM");
> +
> HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NA
> ME), Buffer, NULL);
> +      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"B0");
> +      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION),
> Buffer, NULL);
> +      DEBUG ((EFI_D_ERROR, "B0 Stepping Detected\n"));
> +      break;
> +    case PchB1:
> +      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer,
> L"B1 PLATFORM");
> +
> HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NA
> ME), Buffer, NULL);
> +      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"B1");
> +      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION),
> Buffer, NULL);
> +      DEBUG ((EFI_D_ERROR, "B1 Stepping Detected\n"));
> +      break;
> +    case PchB2:
> +      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer,
> L"B2 PLATFORM");
> +
> HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NA
> ME), Buffer, NULL);
> +      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"B2");
> +      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION),
> Buffer, NULL);
> +      DEBUG ((EFI_D_ERROR, "B2 Stepping Detected\n"));
> +      break;
> +    case PchB3:
> +      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer,
> L"B3 PLATFORM");
> +
> HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NA
> ME), Buffer, NULL);
> +      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"B3");
> +      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION),
> Buffer, NULL);
> +      DEBUG ((EFI_D_ERROR, "B3 Stepping Detected\n"));
> +      break;
> +    case PchC0:
> +      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer,
> L"C0 PLATFORM");
> +
> HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NA
> ME), Buffer, NULL);
> +      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"C0");
> +      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION),
> Buffer, NULL);
> +      DEBUG ((EFI_D_ERROR, "C0 Stepping Detected\n"));
> +      break;
> +   case PchD0:
> +      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer,
> L"D0 PLATFORM");
> +
> HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NA
> ME), Buffer, NULL);
> +      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"D0");
> +      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION),
> Buffer, NULL);
> +      DEBUG ((EFI_D_ERROR, "D0 Stepping Detected\n"));
> +      break;
> +    default:
> +      DEBUG ((EFI_D_ERROR, "Unknow Stepping Detected\n"));
> +      break;
> +    }
> +
> +  if (BOARD_ID_MINNOW2_TURBOT == mPlatformInfo->BoardId) {
> +    UnicodeSPrint (Buffer, sizeof (Buffer),L"ADI");
> +
> HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_MANUFACTUR
> ER), Buffer, NULL);
> +  }
> +  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_MANUFACTURER);
> +  Manufacturer = SmbiosMiscGetString (TokenToGet);
> +  ManuStrLen = StrLen(Manufacturer);
> +  if (ManuStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_PRODUCT_NAME);
> +  ProductName = SmbiosMiscGetString (TokenToGet);
> +  PdNameStrLen = StrLen(ProductName);
> +  if (PdNameStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_VERSION);
> +  Version = SmbiosMiscGetString (TokenToGet);
> +  VerStrLen = StrLen(Version);
> +  if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  //Get handle infomation
> +  //
> +  BufferSize = 0;
> +  Handles = NULL;
> +  Status = gBS->LocateHandle (
> +                  ByProtocol,
> +                  &gEfiSimpleNetworkProtocolGuid,
> +                  NULL,
> +                  &BufferSize,
> +                  Handles
> +                  );
> +
> +  if (Status == EFI_BUFFER_TOO_SMALL) {
> +  	Handles = AllocateZeroPool(BufferSize);
> +  	if (Handles == NULL) {
> +  		return (EFI_OUT_OF_RESOURCES);
> +  	}
> +  	Status = gBS->LocateHandle(
> +  	                ByProtocol,
> +  	                &gEfiSimpleNetworkProtocolGuid,
> +  	                NULL,
> +  	                &BufferSize,
> +  	                Handles
> +  	                );
> + }
> +
> +  //
> +  //Get the MAC string
> +  //
> +  Status = NetLibGetMacString (
> +             *Handles,
> +             NULL,
> +             &MacStr
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  SerialNumber = MacStr;
> +  SerialNumStrLen = StrLen(SerialNumber);
> +  if (SerialNumStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SKU_NUMBER);
> +  SkuNumber = SmbiosMiscGetString (TokenToGet);
> +  SkuNumberStrLen = StrLen(SkuNumber);
> +  if (SkuNumberStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_FAMILY_NAME1);
> +  FamilyName = SmbiosMiscGetString (TokenToGet);
> +  FamilyNameStrLen = StrLen(FamilyName);
> +  if (FamilyNameStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Two zeros following the last string.
> +  //
> +  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE1) +
> ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 +
> SkuNumberStrLen + 1 + FamilyNameStrLen + 1 + 1);
> +  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE1) + ManuStrLen +
> 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 +
> SkuNumberStrLen + 1 + FamilyNameStrLen + 1 + 1);
> +
> +  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_INFORMATION;
> +  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE1);
> +
> +  //
> +  // Make handle chosen by smbios protocol.add automatically.
> +  //
> +  SmbiosRecord->Hdr.Handle = 0;
> +
> +  //
> +  // Manu will be the 1st optional string following the formatted structure.
> +  //
> +  SmbiosRecord->Manufacturer = 1;
> +
> +  //
> +  // ProductName will be the 2nd optional string following the formatted
> structure.
> +  //
> +  SmbiosRecord->ProductName = 2;
> +
> +  //
> +  // Version will be the 3rd optional string following the formatted structure.
> +  //
> +  SmbiosRecord->Version = 3;
> +
> +  //
> +  // Version will be the 4th optional string following the formatted structure.
> +  //
> +  SmbiosRecord->SerialNumber = 4;
> +
> +  SmbiosRecord->SKUNumber= 5;
> +  SmbiosRecord->Family= 6;
> +
> +  //
> +  // Unique UUID
> +  //
> +  ForType1InputData->SystemUuid.Data1 = PcdGet32
> (PcdProductSerialNumber);
> +  ForType1InputData->SystemUuid.Data4[0] = PcdGet8
> (PcdEmmcManufacturerId);
> +
> +  CopyMem ((UINT8 *) (&SmbiosRecord->Uuid),&ForType1InputData-
> >SystemUuid,16);
> +
> +  SmbiosRecord->WakeUpType = (UINT8)ForType1InputData-
> >SystemWakeupType;
> +
> +  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
> +  UnicodeStrToAsciiStr(Manufacturer, OptionalStrStart);
> +  UnicodeStrToAsciiStr(ProductName, OptionalStrStart + ManuStrLen + 1);
> +  UnicodeStrToAsciiStr(Version, OptionalStrStart + ManuStrLen + 1 +
> PdNameStrLen + 1);
> +  UnicodeStrToAsciiStr(SerialNumber, OptionalStrStart + ManuStrLen + 1 +
> PdNameStrLen + 1 + VerStrLen + 1);
> +
> +  UnicodeStrToAsciiStr(SkuNumber, OptionalStrStart + ManuStrLen + 1 +
> PdNameStrLen + 1 +  VerStrLen + 1 + SerialNumStrLen + 1);
> +  UnicodeStrToAsciiStr(FamilyName, OptionalStrStart + ManuStrLen + 1 +
> PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 +
> SkuNumberStrLen +1);
> +
> +  //
> +  // Now we have got the full smbios record, call smbios protocol to add this
> record.
> +  //
> +  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +  Status = Smbios-> Add(
> +                      Smbios,
> +                      NULL,
> +                      &SmbiosHandle,
> +                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
> +                      );
> +  FreePool(SmbiosRecord);
> +  return Status;
> +}
> +
> +/**
> +  This function makes boot time changes to the contents of the
> +  MiscSystemManufacturer (Type 1).
> +
> +  @param  RecordData                 Pointer to copy of RecordData from the Data
> Table.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
> +
> +**/
> +MISC_SMBIOS_TABLE_FUNCTION(MiscSystemManufacturer)
> +{
> +  EFI_STATUS                    Status;
> +  static BOOLEAN                CallbackIsInstalledManu = FALSE;
> +  VOID                           *AddSmbiosManuCallbackNotifyReg;
> +  EFI_EVENT                      AddSmbiosManuCallbackEvent;
> +
> +
> +  if (CallbackIsInstalledManu == FALSE) {
> +    CallbackIsInstalledManu = TRUE;        	// Prevent more than 1
> callback.
> +    DEBUG ((EFI_D_INFO, "Create Smbios Manu callback.\n"));
> +
> +  //
> +  // gEfiDxeSmmReadyToLockProtocolGuid is ready
> +  //
> +  Status = gBS->CreateEvent (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_CALLBACK,
> +                  (EFI_EVENT_NOTIFY)AddSmbiosManuCallback,
> +                  RecordData,
> +                  &AddSmbiosManuCallbackEvent
> +                  );
> +
> +  ASSERT_EFI_ERROR (Status);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +
> +  }
> +
> +  Status = gBS->RegisterProtocolNotify (
> +                  &gEfiDxeSmmReadyToLockProtocolGuid,
> +                  AddSmbiosManuCallbackEvent,
> +                  &AddSmbiosManuCallbackNotifyReg
> +                  );
> +
> +  return Status;
> +  }
> +
> +  return EFI_SUCCESS;
> +
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStrin
> g.uni
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStrin
> g.uni
> new file mode 100644
> index 0000000000..a90fa93cd6
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStrin
> g.uni
> @@ -0,0 +1,24 @@
> +// *++
> +//
> +// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//
> +// Module Name:
> +//
> +//   MiscSystemOptionString.uni
> +//
> +// Abstract:
> +//
> +//   System option language
> +//
> +// Revision History:
> +//
> +// --*/
> +
> +
> +/=#
> +
> +#langdef en-US "English"
> +
> +#string STR_MISC_SYSTEM_OPTION_EN_US   #language en-US  "English
> (US)"
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStrin
> gData.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStrin
> gData.c
> new file mode 100644
> index 0000000000..e8d5fb3ee9
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStrin
> gData.c
> @@ -0,0 +1,31 @@
> +/** @file
> +
> +Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscSystemOptionStringData.c
> +
> +Abstract:
> +
> +  Static data of System option string.
> +  System option string is Miscellaneous subclass type: 10 and SMBIOS type:
> 13.
> +
> +
> +**/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +//
> +// Static (possibly build generated) Bios Vendor data.
> +//
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_OPTION_STRING_DATA,
> SystemOptionString)
> += { STRING_TOKEN(STR_MISC_SYSTEM_OPTION_EN_US) };
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStrin
> gFunction.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStrin
> gFunction.c
> new file mode 100644
> index 0000000000..ee27a75e3a
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStrin
> gFunction.c
> @@ -0,0 +1,93 @@
> +/*++
> +
> +Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscSystemOptionStringFunction.c
> +
> +Abstract:
> +
> +  BIOS system option string boot time changes.
> +  SMBIOS type 12.
> +
> +--*/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +
> +/**
> +  This function makes boot time changes to the contents of the
> +  MiscSystemOptionString (Type 12).
> +
> +  @param  RecordData                 Pointer to copy of RecordData from the Data
> Table.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
> +
> +**/
> +MISC_SMBIOS_TABLE_FUNCTION(SystemOptionString)
> +{
> +  CHAR8                             *OptionalStrStart;
> +  UINTN                             OptStrLen;
> +  EFI_STRING                        OptionString;
> +  EFI_STATUS                        Status;
> +  STRING_REF                        TokenToGet;
> +  EFI_SMBIOS_HANDLE                 SmbiosHandle;
> +  SMBIOS_TABLE_TYPE12               *SmbiosRecord;
> +
> +  //
> +  // First check for invalid parameters.
> +  //
> +  if (RecordData == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_OPTION_EN_US);
> +  OptionString = SmbiosMiscGetString (TokenToGet);
> +  OptStrLen = StrLen(OptionString);
> +  if (OptStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Two zeros following the last string.
> +  //
> +  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE12) + OptStrLen
> + 1 + 1);
> +  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE12) + OptStrLen + 1
> + 1);
> +
> +  SmbiosRecord->Hdr.Type =
> EFI_SMBIOS_TYPE_SYSTEM_CONFIGURATION_OPTIONS;
> +  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE12);
> +
> +  //
> +  // Make handle chosen by smbios protocol.add automatically.
> +  //
> +  SmbiosRecord->Hdr.Handle = 0;
> +
> +  SmbiosRecord->StringCount = 1;
> +  OptionalStrStart = (CHAR8*) (SmbiosRecord + 1);
> +  UnicodeStrToAsciiStr(OptionString, OptionalStrStart);
> +
> +  //
> +  // Now we have got the full smbios record, call smbios protocol to add this
> record.
> +  //
> +  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +  Status = Smbios-> Add(
> +                      Smbios,
> +                      NULL,
> +                      &SmbiosHandle,
> +                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
> +                      );
> +
> +  FreePool(SmbiosRecord);
> +  return Status;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesigna
> tion.uni
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesign
> ation.uni
> new file mode 100644
> index 0000000000..f1d3e866e7
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesign
> ation.uni
> @@ -0,0 +1,34 @@
> +// *++
> +//
> +// Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//
> +// Module Name:
> +//
> +//   MiscSystemSlotDesignation.uni
> +//
> +// Abstract:
> +//
> +//   System slot information
> +//
> +// Revision History:
> +//
> +// --*/
> +
> +
> +/=#
> +
> +#langdef en-US "English"
> +#string STR_MISC_SYSTEM_SLOT_PCIEX16    #language en-US  "PCIE X16
> SLOT"
> +#string STR_MISC_SYSTEM_SLOT_PCIEX16_1  #language en-US  "PCIE X16
> SLOT 1"
> +#string STR_MISC_SYSTEM_SLOT_PCIEX16_2  #language en-US  "PCIE X16
> SLOT 2"
> +#string STR_MISC_SYSTEM_SLOT_PCIEX4     #language en-US  "PCIE X4
> SLOT"
> +#string STR_MISC_SYSTEM_SLOT_PCIEX1_1   #language en-US  "PCIE X1
> SLOT 1"
> +#string STR_MISC_SYSTEM_SLOT_PCIEX1_2   #language en-US  "PCIE X1
> SLOT 2"
> +#string STR_MISC_SYSTEM_SLOT_PCIEX1_3   #language en-US  "PCIE X1
> SLOT 3"
> +#string STR_MISC_SYSTEM_SLOT_PCI1       #language en-US  "PCI SLOT 1"
> +#string STR_MISC_SYSTEM_SLOT_PCI2       #language en-US  "PCI SLOT 2"
> +#string STR_MISC_SYSTEM_SLOT_PCI3       #language en-US  "PCI SLOT 3"
> +
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesigna
> tionData.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesign
> ationData.c
> new file mode 100644
> index 0000000000..48beeb52d3
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesign
> ationData.c
> @@ -0,0 +1,246 @@
> +/** @file
> +
> +Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +    MiscSystemSlotDesignationData.c
> +
> +Abstract:
> +
> +  Static data of System Slot Designation.
> +  System Slot Designation is Misc. subclass type 7 and SMBIOS type 9.
> +
> +
> +**/
> +
> +
> +#include "CommonHeader.h"
> +
> +#include "MiscSubclassDriver.h"
> +
> +
> +//
> +// Static (possibly build generated) Bios Vendor data.
> +//
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DAT
> A, MiscSystemSlotPCIEx16Slot1) = {
> +  STRING_TOKEN(STR_MISC_SYSTEM_SLOT_PCIEX16_1),    //
> SlotDesignation
> +  EfiSlotTypePciExpress,        // SlotType
> +  EfiSlotDataBusWidth16xOrx16,  // SlotDataBusWidth
> +  EfiSlotUsageAvailable,        // SlotUsage
> +  EfiSlotLengthShort,           // SlotLength
> +  0x06,                         // SlotId
> +  {                             // SlotCharacteristics
> +    0,                          // CharacteristicsUnknown  :1;
> +    0,                          // Provides50Volts         :1;
> +    1,                          // Provides33Volts         :1;
> +    0,                          // SharedSlot              :1;
> +    0,                          // PcCard16Supported       :1;
> +    0,                          // CardBusSupported        :1;
> +    0,                          // ZoomVideoSupported      :1;
> +    0,                          // ModemRingResumeSupported:1;
> +    0,                          // PmeSignalSupported      :1;
> +    0,                          // HotPlugDevicesSupported :1;
> +    0,                          // SmbusSignalSupported    :1;
> +    0                           // Reserved                :21;
> +  },
> +  0                             // SlotDevicePath
> +};
> +
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DAT
> A, MiscSystemSlotPCIEx16Slot2) = {
> +  STRING_TOKEN(STR_MISC_SYSTEM_SLOT_PCIEX16_2),    //
> SlotDesignation
> +  EfiSlotTypePciExpress,        // SlotType
> +  EfiSlotDataBusWidth16xOrx16,  // SlotDataBusWidth
> +  EfiSlotUsageAvailable,        // SlotUsage
> +  EfiSlotLengthShort,           // SlotLength
> +  0x04,                         // SlotId
> +  {                             // SlotCharacteristics
> +    0,                          // CharacteristicsUnknown  :1;
> +    0,                          // Provides50Volts         :1;
> +    1,                          // Provides33Volts         :1;
> +    0,                          // SharedSlot              :1;
> +    0,                          // PcCard16Supported       :1;
> +    0,                          // CardBusSupported        :1;
> +    0,                          // ZoomVideoSupported      :1;
> +    0,                          // ModemRingResumeSupported:1;
> +    0,                          // PmeSignalSupported      :1;
> +    0,                          // HotPlugDevicesSupported :1;
> +    0,                          // SmbusSignalSupported    :1;
> +    0                           // Reserved                :21;
> +  },
> +  0                             // SlotDevicePath
> +};
> +
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DAT
> A, MiscSystemSlotPCIEx4) = {
> +  STRING_TOKEN(STR_MISC_SYSTEM_SLOT_PCIEX4),    // SlotDesignation
> +  EfiSlotTypePciExpress,        // SlotType
> +  EfiSlotDataBusWidth4xOrx4,  // SlotDataBusWidth
> +  EfiSlotUsageAvailable,        // SlotUsage
> +  EfiSlotLengthShort,           // SlotLength
> +  0x03,                         // SlotId
> +  {                             // SlotCharacteristics
> +    0,                          // CharacteristicsUnknown  :1;
> +    0,                          // Provides50Volts         :1;
> +    1,                          // Provides33Volts         :1;
> +    0,                          // SharedSlot              :1;
> +    0,                          // PcCard16Supported       :1;
> +    0,                          // CardBusSupported        :1;
> +    0,                          // ZoomVideoSupported      :1;
> +    0,                          // ModemRingResumeSupported:1;
> +    0,                          // PmeSignalSupported      :1;
> +    0,                          // HotPlugDevicesSupported :1;
> +    0,                          // SmbusSignalSupported    :1;
> +    0                           // Reserved                :21;
> +  },
> +  0                             // SlotDevicePath
> +};
> +
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DAT
> A, MiscSystemSlotPCIEx1Slot1) = {
> +  STRING_TOKEN(STR_MISC_SYSTEM_SLOT_PCIEX1_1),    // SlotDesignation
> +  EfiSlotTypePciExpress,        // SlotType
> +  EfiSlotDataBusWidth1xOrx1,    // SlotDataBusWidth
> +  EfiSlotUsageAvailable,        // SlotUsage
> +  EfiSlotLengthShort,           // SlotLength
> +  0x02,                         // SlotId
> +  {                             // SlotCharacteristics
> +    0,                          // CharacteristicsUnknown  :1;
> +    0,                          // Provides50Volts         :1;
> +    1,                          // Provides33Volts         :1;
> +    0,                          // SharedSlot              :1;
> +    0,                          // PcCard16Supported       :1;
> +    0,                          // CardBusSupported        :1;
> +    0,                          // ZoomVideoSupported      :1;
> +    0,                          // ModemRingResumeSupported:1;
> +    1,                          // PmeSignalSupported      :1;
> +    0,                          // HotPlugDevicesSupported :1;
> +    1,                          // SmbusSignalSupported    :1;
> +    0                           // Reserved                :21;
> +  },
> +  0                             // SlotDevicePath
> +};
> +
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DAT
> A, MiscSystemSlotPCIEx1Slot2) = {
> +  STRING_TOKEN(STR_MISC_SYSTEM_SLOT_PCIEX1_2),    // SlotDesignation
> +  EfiSlotTypePciExpress,        // SlotType
> +  EfiSlotDataBusWidth1xOrx1,    // SlotDataBusWidth
> +  EfiSlotUsageAvailable,        // SlotUsage
> +  EfiSlotLengthShort,           // SlotLength
> +  0x15,                         // SlotId
> +  {                             // SlotCharacteristics
> +    0,                          // CharacteristicsUnknown  :1;
> +    0,                          // Provides50Volts         :1;
> +    1,                          // Provides33Volts         :1;
> +    0,                          // SharedSlot              :1;
> +    0,                          // PcCard16Supported       :1;
> +    0,                          // CardBusSupported        :1;
> +    0,                          // ZoomVideoSupported      :1;
> +    0,                          // ModemRingResumeSupported:1;
> +    1,                          // PmeSignalSupported      :1;
> +    0,                          // HotPlugDevicesSupported :1;
> +    1,                          // SmbusSignalSupported    :1;
> +    0                           // Reserved                :21;
> +  },
> +  0                             // SlotDevicePath
> +};
> +
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DAT
> A, MiscSystemSlotPCIEx1Slot3) = {
> +  STRING_TOKEN(STR_MISC_SYSTEM_SLOT_PCIEX1_3),    // SlotDesignation
> +  EfiSlotTypePciExpress,        // SlotType
> +  EfiSlotDataBusWidth1xOrx1,    // SlotDataBusWidth
> +  EfiSlotUsageAvailable,        // SlotUsage
> +  EfiSlotLengthShort,           // SlotLength
> +  0x16,                         // SlotId
> +  {                             // SlotCharacteristics
> +    0,                          // CharacteristicsUnknown  :1;
> +    0,                          // Provides50Volts         :1;
> +    1,                          // Provides33Volts         :1;
> +    0,                          // SharedSlot              :1;
> +    0,                          // PcCard16Supported       :1;
> +    0,                          // CardBusSupported        :1;
> +    0,                          // ZoomVideoSupported      :1;
> +    0,                          // ModemRingResumeSupported:1;
> +    1,                          // PmeSignalSupported      :1;
> +    0,                          // HotPlugDevicesSupported :1;
> +    1,                          // SmbusSignalSupported    :1;
> +    0                           // Reserved                :21;
> +  },
> +  0                             // SlotDevicePath
> +};
> +
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DAT
> A, MiscSystemSlotPCI1) = {
> +  STRING_TOKEN(STR_MISC_SYSTEM_SLOT_PCI1),    // SlotDesignation
> +  EfiSlotTypePci,               // SlotType
> +  EfiSlotDataBusWidth32Bit,     // SlotDataBusWidth
> +  EfiSlotUsageAvailable,        // SlotUsage
> +  EfiSlotLengthLong ,           // SlotLength
> +  0x07,                         // SlotId
> +  {                             // SlotCharacteristics
> +    0,                          // CharacteristicsUnknown  :1;
> +    0,                          // Provides50Volts         :1;
> +    1,                          // Provides33Volts         :1;
> +    0,                          // SharedSlot              :1;
> +    0,                          // PcCard16Supported       :1;
> +    0,                          // CardBusSupported        :1;
> +    0,                          // ZoomVideoSupported      :1;
> +    0,                          // ModemRingResumeSupported:1;
> +    1,                          // PmeSignalSupported      :1;
> +    0,                          // HotPlugDevicesSupported :1;
> +    1,                          // SmbusSignalSupported    :1;
> +    0                           // Reserved                :21;
> +  },
> +  0                             // SlotDevicePath
> +};
> +
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DAT
> A, MiscSystemSlotPCI2) = {
> +  STRING_TOKEN(STR_MISC_SYSTEM_SLOT_PCI2),    // SlotDesignation
> +  EfiSlotTypePci,               // SlotType
> +  EfiSlotDataBusWidth32Bit,     // SlotDataBusWidth
> +  EfiSlotUsageAvailable,        // SlotUsage
> +  EfiSlotLengthLong ,           // SlotLength
> +  0x18,                         // SlotId
> +  {                             // SlotCharacteristics
> +    0,                          // CharacteristicsUnknown  :1;
> +    0,                          // Provides50Volts         :1;
> +    1,                          // Provides33Volts         :1;
> +    0,                          // SharedSlot              :1;
> +    0,                          // PcCard16Supported       :1;
> +    0,                          // CardBusSupported        :1;
> +    0,                          // ZoomVideoSupported      :1;
> +    0,                          // ModemRingResumeSupported:1;
> +    1,                          // PmeSignalSupported      :1;
> +    0,                          // HotPlugDevicesSupported :1;
> +    1,                          // SmbusSignalSupported    :1;
> +    0                           // Reserved                :21;
> +  },
> +  0                             // SlotDevicePath
> +};
> +
> +MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DAT
> A, MiscSystemSlotPCI3) = {
> +  STRING_TOKEN(STR_MISC_SYSTEM_SLOT_PCI3),    // SlotDesignation
> +  EfiSlotTypePci,               // SlotType
> +  EfiSlotDataBusWidth32Bit,     // SlotDataBusWidth
> +  EfiSlotUsageAvailable,        // SlotUsage
> +  EfiSlotLengthLong ,           // SlotLength
> +  0x17,                         // SlotId
> +  {                             // SlotCharacteristics
> +    0,                          // CharacteristicsUnknown  :1;
> +    0,                          // Provides50Volts         :1;
> +    1,                          // Provides33Volts         :1;
> +    0,                          // SharedSlot              :1;
> +    0,                          // PcCard16Supported       :1;
> +    0,                          // CardBusSupported        :1;
> +    0,                          // ZoomVideoSupported      :1;
> +    0,                          // ModemRingResumeSupported:1;
> +    1,                          // PmeSignalSupported      :1;
> +    0,                          // HotPlugDevicesSupported :1;
> +    1,                          // SmbusSignalSupported    :1;
> +    0                           // Reserved                :21;
> +  },
> +  0                             // SlotDevicePath
> +};
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesigna
> tionFunction.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesign
> ationFunction.c
> new file mode 100644
> index 0000000000..7270ef826f
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesign
> ationFunction.c
> @@ -0,0 +1,127 @@
> +/*++
> +
> +Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  MiscSystemSlotDesignatorFunction.c
> +
> +Abstract:
> +
> +  BIOS system slot designator information boot time changes.
> +  SMBIOS type 9.
> +
> +--*/
> +
> +#include "MiscSubclassDriver.h"
> +
> +/**
> +  This function makes boot time changes to the contents of the
> +  MiscSystemSlotDesignator structure (Type 9).
> +
> +  @param  RecordData                 Pointer to copy of RecordData from the Data
> Table.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
> +
> +**/
> +MISC_SMBIOS_TABLE_FUNCTION(MiscSystemSlotDesignation)
> +{
> +  CHAR8                              *OptionalStrStart;
> +  UINTN                              SlotDesignationStrLen;
> +  EFI_STATUS                         Status;
> +  EFI_STRING                         SlotDesignation;
> +  STRING_REF                         TokenToGet;
> +  SMBIOS_TABLE_TYPE9                 *SmbiosRecord;
> +  EFI_SMBIOS_HANDLE                  SmbiosHandle;
> +  EFI_MISC_SYSTEM_SLOT_DESIGNATION*  ForType9InputData;
> +
> +  ForType9InputData = (EFI_MISC_SYSTEM_SLOT_DESIGNATION
> *)RecordData;
> +
> +  //
> +  // First check for invalid parameters.
> +  //
> +  if (RecordData == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  TokenToGet = 0;
> +  switch (ForType9InputData->SlotDesignation) {
> +    case STR_MISC_SYSTEM_SLOT_PCIEX16_1:
> +      TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SLOT_PCIEX16_1);
> +      break;
> +    case STR_MISC_SYSTEM_SLOT_PCIEX16_2:
> +      TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SLOT_PCIEX16_2);
> +      break;
> +    case STR_MISC_SYSTEM_SLOT_PCIEX4:
> +      TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SLOT_PCIEX4);
> +      break;
> +    case STR_MISC_SYSTEM_SLOT_PCIEX1_1:
> +      TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SLOT_PCIEX1_1);
> +      break;
> +    case STR_MISC_SYSTEM_SLOT_PCIEX1_2:
> +      TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SLOT_PCIEX1_2);
> +      break;
> +    case STR_MISC_SYSTEM_SLOT_PCIEX1_3:
> +      TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SLOT_PCIEX1_3);
> +      break;
> +    case STR_MISC_SYSTEM_SLOT_PCI1:
> +      TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SLOT_PCI1);
> +      break;
> +    case STR_MISC_SYSTEM_SLOT_PCI2:
> +      TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SLOT_PCI2);
> +      break;
> +    case STR_MISC_SYSTEM_SLOT_PCI3:
> +      TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SLOT_PCI3);
> +      break;
> +    default:
> +      break;
> +  }
> +
> +  SlotDesignation = SmbiosMiscGetString (TokenToGet);
> +  SlotDesignationStrLen = StrLen(SlotDesignation);
> +  if (SlotDesignationStrLen > SMBIOS_STRING_MAX_LENGTH) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Two zeros following the last string.
> +  //
> +  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE9) +
> SlotDesignationStrLen + 1 + 1);
> +  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE9)
> +SlotDesignationStrLen + 1 + 1);
> +
> +  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_SLOTS;
> +  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE9);
> +  SmbiosRecord->Hdr.Handle = 0;
> +  SmbiosRecord->SlotDesignation = 1;
> +  SmbiosRecord->SlotType = (UINT8)ForType9InputData->SlotType;
> +  SmbiosRecord->SlotDataBusWidth = (UINT8)ForType9InputData-
> >SlotDataBusWidth;
> +  SmbiosRecord->CurrentUsage = (UINT8)ForType9InputData->SlotUsage;
> +  SmbiosRecord->SlotLength = (UINT8)ForType9InputData->SlotLength;
> +  SmbiosRecord->SlotID = ForType9InputData->SlotId;
> +
> +  //
> +  // Slot Characteristics
> +  //
> +  CopyMem ((UINT8 *) &SmbiosRecord->SlotCharacteristics1,(UINT8 *)
> &ForType9InputData->SlotCharacteristics,2);
> +  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
> +  UnicodeStrToAsciiStr(SlotDesignation, OptionalStrStart);
> +  //
> +  // Now we have got the full smbios record, call smbios protocol to add this
> record.
> +  //
> +  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +  Status = Smbios-> Add(
> +                      Smbios,
> +                      NULL,
> +                      &SmbiosHandle,
> +                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
> +                      );
> +  FreePool(SmbiosRecord);
> +  return Status;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/SmBiosMiscDxe.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/SmBiosMiscDxe.inf
> new file mode 100644
> index 0000000000..37e54a92a8
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/SmBiosMiscDxe.inf
> @@ -0,0 +1,139 @@
> +## @file
> +# Component name for module MiscSubclass
> +#
> +# FIX ME!
> +# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = MiscSubclass
> +  FILE_GUID                      = 4EFFB560-B28B-4e57-9DAD-4344E32EA3BA
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = MiscSubclassDriverEntryPoint
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +
> +[Sources]
> +  MiscBaseBoardManufacturer.uni
> +  MiscBaseBoardManufacturerData.c
> +  MiscBaseBoardManufacturerFunction.c
> +  MiscBiosVendor.uni
> +  MiscBiosVendorData.c
> +  MiscBiosVendorFunction.c
> +  MiscBootInformationData.c
> +  MiscBootInformationFunction.c
> +  MiscChassisManufacturer.uni
> +  MiscChassisManufacturerData.c
> +  MiscChassisManufacturerFunction.c
> +  MiscNumberOfInstallableLanguagesData.c
> +  MiscNumberOfInstallableLanguagesFunction.c
> +  MiscOemString.uni
> +  MiscOemStringData.c
> +  MiscOemStringFunction.c
> +  MiscOnboardDevice.uni
> +  MiscOnboardDeviceData.c
> +  MiscOnboardDeviceFunction.c
> +  MiscPortInternalConnectorDesignator.uni
> +  MiscPortInternalConnectorDesignatorData.c
> +  MiscPortInternalConnectorDesignatorFunction.c
> +  MiscResetCapabilitiesData.c
> +  MiscResetCapabilitiesFunction.c
> +  MiscSystemLanguageString.uni
> +  MiscSystemLanguageStringData.c
> +  MiscSystemLanguageStringFunction.c
> +  MiscSystemManufacturer.uni
> +  MiscSystemManufacturerData.c
> +  MiscSystemManufacturerFunction.c
> +  MiscSystemOptionString.uni
> +  MiscSystemOptionStringData.c
> +  MiscSystemOptionStringFunction.c
> +  MiscSystemSlotDesignation.uni
> +  MiscSystemSlotDesignationData.c
> +  MiscSystemSlotDesignationFunction.c
> +  MiscSubclassDriver.h
> +  MiscSubclassDriver.uni
> +  MiscSubclassDriverDataTable.c
> +  MiscSubclassDriverEntryPoint.c
> +  CommonHeader.h
> +  MiscOemType0x90Function.c
> +  MiscOemType0x90Data.c
> +  MiscOemType0x90.uni
> +  MiscProcessorInformation.uni
> +  MiscProcessorInformationData.c
> +  MiscProcessorInformationFunction.c
> +  MiscProcessorCache.uni
> +  MiscProcessorCacheData.c
> +  MiscProcessorCacheFunction.c
> +  MiscPhysicalArray.uni
> +  MiscPhysicalArrayData.c
> +  MiscPhysicalArrayFunction.c
> +  MiscMemoryDevice.uni
> +  MiscMemoryDeviceData.c
> +  MiscMemoryDeviceFunction.c
> +
> +[Packages]
> +  MdeModulePkg/MdeModulePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  MdePkg/MdePkg.dec
> +  IntelFrameworkPkg/IntelFrameworkPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +
> +[LibraryClasses]
> +  HiiLib
> +  DevicePathLib
> +  UefiBootServicesTableLib
> +  UefiRuntimeServicesTableLib
> +  UefiDriverEntryPoint
> +  BaseMemoryLib
> +  DebugLib
> +  BaseLib
> +  MemoryAllocationLib
> +  PcdLib
> +  UefiLib
> +  BiosIdLib
> +  PrintLib
> +  CpuIA32Lib
> +  PchPlatformLib
> +  I2cLib
> +  NetLib
> +  HobLib
> +
> +[Guids]
> +  gEfiProcessorSubClassGuid
> +  gEfiCacheSubClassGuid
> +  gEfiNormalSetupGuid
> +  gEfiPlatformInfoGuid
> +  gEfiVlv2VariableGuid
> +
> +[Protocols]
> +  gEfiSmbiosProtocolGuid                        # PROTOCOL ALWAYS_CONSUMED
> +  gEfiDxeSmmReadyToLockProtocolGuid             # PROTOCOL
> ALWAYS_CONSUMED
> +  gEfiDataHubProtocolGuid
> +  gEfiMpServiceProtocolGuid
> +  gMemInfoProtocolGuid
> +  gEfiTdtOperationProtocolGuid
> +  gDxePchPlatformPolicyProtocolGuid
> +  gEfiSpiProtocolGuid
> +  gEfiSimpleNetworkProtocolGuid
> +
> +[Pcd]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareReleaseDateString
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
> +  gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang
> +  gEfiVLVTokenSpaceGuid.PcdEmmcManufacturerId
> +  gEfiVLVTokenSpaceGuid.PcdProductSerialNumber
> +
> +[Depex]
> + gEfiSmbiosProtocolGuid AND gMemInfoProtocolGuid AND
> gEfiMpServiceProtocolGuid AND gEfiSimpleNetworkProtocolGuid
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchTh
> unk/SmmSwDispatch2OnSmmSwDispatchThunk.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchTh
> unk/SmmSwDispatch2OnSmmSwDispatchThunk.c
> new file mode 100644
> index 0000000000..0dbd6f00e1
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchTh
> unk/SmmSwDispatch2OnSmmSwDispatchThunk.c
> @@ -0,0 +1,459 @@
> +/** @file
> +  SMM SwDispatch2 Protocol on SMM SwDispatch Protocol Thunk driver.
> +
> +  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +**/
> +
> +#include <PiDxe.h>
> +#include <FrameworkSmm.h>
> +
> +#include <Protocol/SmmSwDispatch2.h>
> +#include <Protocol/SmmSwDispatch.h>
> +#include <Protocol/SmmControl.h>
> +#include <Protocol/SmmCpu.h>
> +
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/SmmServicesTableLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/DebugLib.h>
> +
> +typedef struct {
> +  LIST_ENTRY                     Link;
> +  EFI_HANDLE                     DispatchHandle;
> +  UINTN                          SwSmiInputValue;
> +  UINTN                          DispatchFunction;
> +} EFI_SMM_SW_DISPATCH2_THUNK_CONTEXT;
> +
> +/**
> +  Register a child SMI source dispatch function for the specified software
> SMI.
> +
> +  This service registers a function (DispatchFunction) which will be called
> when the software
> +  SMI source specified by RegisterContext->SwSmiCpuIndex is detected. On
> return,
> +  DispatchHandle contains a unique handle which may be used later to
> unregister the function
> +  using UnRegister().
> +
> +  @param[in]  This                  Pointer to the
> EFI_SMM_SW_DISPATCH2_PROTOCOL instance.
> +  @param[in]  DispatchFunction      Function to register for handler when the
> specified software
> +                                    SMI is generated.
> +  @param[in, out]  RegisterContext  Pointer to the dispatch function's
> context.
> +                                    The caller fills this context in before calling
> +                                    the register function to indicate to the register
> +                                    function which Software SMI input value the
> +                                    dispatch function should be invoked for.
> +  @param[out] DispatchHandle        Handle generated by the dispatcher to
> track the
> +                                    function instance.
> +
> +  @retval EFI_SUCCESS            The dispatch function has been successfully
> +                                 registered and the SMI source has been enabled.
> +  @retval EFI_DEVICE_ERROR       The SW driver was unable to enable the
> SMI source.
> +  @retval EFI_INVALID_PARAMETER  RegisterContext is invalid. The SW SMI
> input value
> +                                 is not within valid range.
> +  @retval EFI_OUT_OF_RESOURCES   There is not enough memory (system
> or SMM) to manage this
> +                                 child.
> +  @retval EFI_OUT_OF_RESOURCES   A unique software SMI value could not
> be assigned
> +                                 for this dispatch.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmmSwDispatch2Register (
> +  IN  CONST EFI_SMM_SW_DISPATCH2_PROTOCOL  *This,
> +  IN        EFI_SMM_HANDLER_ENTRY_POINT2   DispatchFunction,
> +  IN  OUT   EFI_SMM_SW_REGISTER_CONTEXT    *RegisterContext,
> +  OUT       EFI_HANDLE                     *DispatchHandle
> +  );
> +
> +/**
> +  Unregister a child SMI source dispatch function for the specified software
> SMI.
> +
> +  This service removes the handler associated with DispatchHandle so that it
> will no longer be
> +  called in response to a software SMI.
> +
> +  @param[in] This                Pointer to the
> EFI_SMM_SW_DISPATCH2_PROTOCOL instance.
> +  @param[in] DispatchHandle      Handle of dispatch function to deregister.
> +
> +  @retval EFI_SUCCESS            The dispatch function has been successfully
> unregistered.
> +  @retval EFI_INVALID_PARAMETER  The DispatchHandle was not valid.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmmSwDispatch2UnRegister (
> +  IN CONST EFI_SMM_SW_DISPATCH2_PROTOCOL  *This,
> +  IN       EFI_HANDLE                     DispatchHandle
> +  );
> +
> +EFI_SMM_SW_DISPATCH2_PROTOCOL gSmmSwDispatch2 = {
> +  SmmSwDispatch2Register,
> +  SmmSwDispatch2UnRegister,
> +  0 // MaximumSwiValue
> +};
> +
> +EFI_SMM_SW_DISPATCH_PROTOCOL  *mSmmSwDispatch;
> +UINT8                         mSmiTriggerRegister;
> +UINT8                         mSmiDataRegister;
> +
> +EFI_SMM_CPU_PROTOCOL          *mSmmCpuProtocol;
> +LIST_ENTRY                    mSmmSwDispatch2ThunkQueue =
> INITIALIZE_LIST_HEAD_VARIABLE (mSmmSwDispatch2ThunkQueue);
> +
> +/**
> +  This function find SmmSwDispatch2Context by SwSmiInputValue.
> +
> +  @param SwSmiInputValue The SwSmiInputValue to indentify the
> SmmSwDispatch2 context
> +
> +  @return SmmSwDispatch2 context
> +**/
> +EFI_SMM_SW_DISPATCH2_THUNK_CONTEXT *
> +FindSmmSwDispatch2ContextBySwSmiInputValue (
> +  IN UINTN   SwSmiInputValue
> +  )
> +{
> +  LIST_ENTRY                            *Link;
> +  EFI_SMM_SW_DISPATCH2_THUNK_CONTEXT    *ThunkContext;
> +
> +  for (Link = mSmmSwDispatch2ThunkQueue.ForwardLink;
> +    Link != &mSmmSwDispatch2ThunkQueue;
> +    Link = Link->ForwardLink) {
> +    ThunkContext = BASE_CR (
> +                     Link,
> +                     EFI_SMM_SW_DISPATCH2_THUNK_CONTEXT,
> +                     Link
> +                     );
> +    if (ThunkContext->SwSmiInputValue == SwSmiInputValue) {
> +      return ThunkContext;
> +    }
> +  }
> +  return NULL;
> +}
> +
> +/**
> +  This function find SmmSwDispatch2Context by DispatchHandle.
> +
> +  @param DispatchHandle The DispatchHandle to indentify the
> SmmSwDispatch2Thunk context
> +
> +  @return SmmSwDispatch2Thunk context
> +**/
> +EFI_SMM_SW_DISPATCH2_THUNK_CONTEXT *
> +FindSmmSwDispatch2ContextByDispatchHandle (
> +  IN EFI_HANDLE   DispatchHandle
> +  )
> +{
> +  LIST_ENTRY                            *Link;
> +  EFI_SMM_SW_DISPATCH2_THUNK_CONTEXT    *ThunkContext;
> +
> +  for (Link = mSmmSwDispatch2ThunkQueue.ForwardLink;
> +       Link != &mSmmSwDispatch2ThunkQueue;
> +       Link = Link->ForwardLink) {
> +    ThunkContext = BASE_CR (
> +                     Link,
> +                     EFI_SMM_SW_DISPATCH2_THUNK_CONTEXT,
> +                     Link
> +                     );
> +    if (ThunkContext->DispatchHandle == DispatchHandle) {
> +      return ThunkContext;
> +    }
> +  }
> +  return NULL;
> +}
> +
> +/**
> +  Framework dispatch function for a Software SMI handler.
> +
> +  @param  DispatchHandle        The handle of this dispatch function.
> +  @param  DispatchContext       The pointer to the dispatch function's
> context.
> +                                The SwSmiInputValue field is filled in
> +                                by the software dispatch driver prior to
> +                                invoking this dispatch function.
> +                                The dispatch function will only be called
> +                                for input values for which it is registered.
> +
> +  @return None
> +
> +**/
> +VOID
> +EFIAPI
> +FrameworkDispatchFunction (
> +  IN  EFI_HANDLE                    DispatchHandle,
> +  IN  EFI_SMM_SW_DISPATCH_CONTEXT   *DispatchContext
> +  )
> +{
> +  EFI_SMM_SW_DISPATCH2_THUNK_CONTEXT    *ThunkContext;
> +  EFI_SMM_HANDLER_ENTRY_POINT2          DispatchFunction;
> +  EFI_SMM_SW_REGISTER_CONTEXT           RegisterContext;
> +  EFI_SMM_SW_CONTEXT                    SwContext;
> +  UINTN                                 Size;
> +  UINTN                                 Index;
> +  EFI_SMM_SAVE_STATE_IO_INFO            IoInfo;
> +  EFI_STATUS                            Status;
> +
> +  //
> +  // Search context
> +  //
> +  ThunkContext = FindSmmSwDispatch2ContextBySwSmiInputValue
> (DispatchContext->SwSmiInputValue);
> +  ASSERT (ThunkContext != NULL);
> +  if (ThunkContext == NULL) {
> +    return ;
> +  }
> +
> +  //
> +  // Construct new context
> +  //
> +  RegisterContext.SwSmiInputValue = DispatchContext->SwSmiInputValue;
> +  Size = sizeof(SwContext);
> +  SwContext.CommandPort = IoRead8 (mSmiTriggerRegister);
> +  SwContext.DataPort    = IoRead8 (mSmiDataRegister);
> +
> +  //
> +  // Try to find which CPU trigger SWSMI
> +  //
> +  SwContext.SwSmiCpuIndex = 0;
> +  for (Index = 0; Index < gSmst->NumberOfCpus; Index++) {
> +    Status = mSmmCpuProtocol->ReadSaveState (
> +                                mSmmCpuProtocol,
> +                                sizeof(IoInfo),
> +                                EFI_SMM_SAVE_STATE_REGISTER_IO,
> +                                Index,
> +                                &IoInfo
> +                                );
> +    if (EFI_ERROR (Status)) {
> +      continue;
> +    }
> +    if (IoInfo.IoPort == mSmiTriggerRegister) {
> +      //
> +      // Great! Find it.
> +      //
> +      SwContext.SwSmiCpuIndex = Index;
> +      break;
> +    }
> +  }
> +
> +  //
> +  // Dispatch
> +  //
> +  DispatchFunction = (EFI_SMM_HANDLER_ENTRY_POINT2)ThunkContext-
> >DispatchFunction;
> +  DispatchFunction (
> +    DispatchHandle,
> +    &RegisterContext,
> +    &SwContext,
> +    &Size
> +    );
> +  return ;
> +}
> +
> +/**
> +  Register a child SMI source dispatch function for the specified software
> SMI.
> +
> +  This service registers a function (DispatchFunction) which will be called
> when the software
> +  SMI source specified by RegisterContext->SwSmiCpuIndex is detected. On
> return,
> +  DispatchHandle contains a unique handle which may be used later to
> unregister the function
> +  using UnRegister().
> +
> +  @param[in]  This                  Pointer to the
> EFI_SMM_SW_DISPATCH2_PROTOCOL instance.
> +  @param[in]  DispatchFunction      Function to register for handler when the
> specified software
> +                                    SMI is generated.
> +  @param[in, out]  RegisterContext  Pointer to the dispatch function's
> context.
> +                                    The caller fills this context in before calling
> +                                    the register function to indicate to the register
> +                                    function which Software SMI input value the
> +                                    dispatch function should be invoked for.
> +  @param[out] DispatchHandle        Handle generated by the dispatcher to
> track the
> +                                    function instance.
> +
> +  @retval EFI_SUCCESS            The dispatch function has been successfully
> +                                 registered and the SMI source has been enabled.
> +  @retval EFI_DEVICE_ERROR       The SW driver was unable to enable the
> SMI source.
> +  @retval EFI_INVALID_PARAMETER  RegisterContext is invalid. The SW SMI
> input value
> +                                 is not within valid range.
> +  @retval EFI_OUT_OF_RESOURCES   There is not enough memory (system
> or SMM) to manage this
> +                                 child.
> +  @retval EFI_OUT_OF_RESOURCES   A unique software SMI value could not
> be assigned
> +                                 for this dispatch.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmmSwDispatch2Register (
> +  IN  CONST EFI_SMM_SW_DISPATCH2_PROTOCOL  *This,
> +  IN        EFI_SMM_HANDLER_ENTRY_POINT2   DispatchFunction,
> +  IN  OUT   EFI_SMM_SW_REGISTER_CONTEXT    *RegisterContext,
> +  OUT       EFI_HANDLE                     *DispatchHandle
> +  )
> +{
> +  EFI_SMM_SW_DISPATCH2_THUNK_CONTEXT    *ThunkContext;
> +  EFI_SMM_SW_DISPATCH_CONTEXT           DispatchContext;
> +  EFI_STATUS                            Status;
> +  UINTN                                 Index;
> +
> +  if (RegisterContext->SwSmiInputValue == (UINTN)-1) {
> +    //
> +    // If SwSmiInputValue is set to (UINTN) -1 then a unique value will be
> assigned and returned in the structure.
> +    //
> +    Status = EFI_NOT_FOUND;
> +    for (Index = 1; Index < gSmmSwDispatch2.MaximumSwiValue; Index++) {
> +      DispatchContext.SwSmiInputValue = Index;
> +      Status = mSmmSwDispatch->Register (
> +                                 mSmmSwDispatch,
> +                                 FrameworkDispatchFunction,
> +                                 &DispatchContext,
> +                                 DispatchHandle
> +                                 );
> +      if (!EFI_ERROR (Status)) {
> +        RegisterContext->SwSmiInputValue = Index;
> +        break;
> +      }
> +    }
> +    if (RegisterContext->SwSmiInputValue == (UINTN)-1) {
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +  } else {
> +    DispatchContext.SwSmiInputValue = RegisterContext->SwSmiInputValue;
> +    Status = mSmmSwDispatch->Register (
> +                               mSmmSwDispatch,
> +                               FrameworkDispatchFunction,
> +                               &DispatchContext,
> +                               DispatchHandle
> +                               );
> +  }
> +  if (!EFI_ERROR (Status)) {
> +    //
> +    // Register
> +    //
> +    Status = gSmst->SmmAllocatePool (
> +                      EfiRuntimeServicesData,
> +                      sizeof(*ThunkContext),
> +                      (VOID **)&ThunkContext
> +                      );
> +    ASSERT_EFI_ERROR (Status);
> +    if (EFI_ERROR (Status)) {
> +      mSmmSwDispatch->UnRegister (mSmmSwDispatch, *DispatchHandle);
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +
> +    ThunkContext->SwSmiInputValue  = RegisterContext->SwSmiInputValue;
> +    ThunkContext->DispatchFunction = (UINTN)DispatchFunction;
> +    ThunkContext->DispatchHandle   = *DispatchHandle;
> +    InsertTailList (&mSmmSwDispatch2ThunkQueue, &ThunkContext->Link);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  Unregister a child SMI source dispatch function for the specified software
> SMI.
> +
> +  This service removes the handler associated with DispatchHandle so that it
> will no longer be
> +  called in response to a software SMI.
> +
> +  @param[in] This                Pointer to the
> EFI_SMM_SW_DISPATCH2_PROTOCOL instance.
> +  @param[in] DispatchHandle      Handle of dispatch function to deregister.
> +
> +  @retval EFI_SUCCESS            The dispatch function has been successfully
> unregistered.
> +  @retval EFI_INVALID_PARAMETER  The DispatchHandle was not valid.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmmSwDispatch2UnRegister (
> +  IN CONST EFI_SMM_SW_DISPATCH2_PROTOCOL  *This,
> +  IN       EFI_HANDLE                     DispatchHandle
> +  )
> +{
> +  EFI_SMM_SW_DISPATCH2_THUNK_CONTEXT    *ThunkContext;
> +  EFI_STATUS                            Status;
> +
> +  Status = mSmmSwDispatch->UnRegister (mSmmSwDispatch,
> DispatchHandle);
> +  if (!EFI_ERROR (Status)) {
> +    //
> +    // Unregister
> +    //
> +    ThunkContext = FindSmmSwDispatch2ContextByDispatchHandle
> (DispatchHandle);
> +    ASSERT (ThunkContext != NULL);
> +    if (ThunkContext != NULL) {
> +      RemoveEntryList (&ThunkContext->Link);
> +      gSmst->SmmFreePool (ThunkContext);
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  Entry Point for this thunk driver.
> +
> +  @param[in] ImageHandle  Image handle of this driver.
> +  @param[in] SystemTable  A Pointer to the EFI System Table.
> +
> +  @retval EFI_SUCCESS  The entry point is executed successfully.
> +  @retval other        Some error occurred when executing this entry point.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmmSwDispatch2ThunkMain (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS               Status;
> +  EFI_SMM_CONTROL_PROTOCOL *SmmControl;
> +  EFI_SMM_CONTROL_REGISTER RegisterInfo;
> +
> +  //
> +  // Locate Framework SMM SwDispatch Protocol
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiSmmSwDispatchProtocolGuid,
> +                  NULL,
> +                  (VOID **)&mSmmSwDispatch
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +  gSmmSwDispatch2.MaximumSwiValue = mSmmSwDispatch-
> >MaximumSwiValue;
> +  if (gSmmSwDispatch2.MaximumSwiValue == 0x0) {
> +    DEBUG ((EFI_D_ERROR, "BUGBUG: MaximumSwiValue is 0, work-around
> to make it 0xFF\n"));
> +    gSmmSwDispatch2.MaximumSwiValue = 0xFF;
> +  }
> +
> +  //
> +  // Locate Framework SMM Control Protocol
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiSmmControlProtocolGuid,
> +                  NULL,
> +                  (VOID **)&SmmControl
> +                  );
> +
> +  ASSERT_EFI_ERROR (Status);
> +  Status = SmmControl->GetRegisterInfo (
> +                         SmmControl,
> +                         &RegisterInfo
> +                         );
> +  ASSERT_EFI_ERROR (Status);
> +  mSmiTriggerRegister = RegisterInfo.SmiTriggerRegister;
> +  mSmiDataRegister    = RegisterInfo.SmiDataRegister;
> +
> +  //
> +  // Locate PI SMM CPU protocol
> +  //
> +  Status = gSmst->SmmLocateProtocol (
> +                    &gEfiSmmCpuProtocolGuid,
> +                    NULL,
> +                    (VOID **)&mSmmCpuProtocol
> +                    );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Publish PI SMM SwDispatch2 Protocol
> +  //
> +  ImageHandle = NULL;
> +  Status = gSmst->SmmInstallProtocolInterface (
> +                    &ImageHandle,
> +                    &gEfiSmmSwDispatch2ProtocolGuid,
> +                    EFI_NATIVE_INTERFACE,
> +                    &gSmmSwDispatch2
> +                    );
> +  ASSERT_EFI_ERROR (Status);
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchTh
> unk/SmmSwDispatch2OnSmmSwDispatchThunk.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchTh
> unk/SmmSwDispatch2OnSmmSwDispatchThunk.inf
> new file mode 100644
> index 0000000000..4f95fc281e
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchTh
> unk/SmmSwDispatch2OnSmmSwDispatchThunk.inf
> @@ -0,0 +1,54 @@
> +## @file
> +#  Component description file for SMM SwDispatch2 Protocol on SMM
> SwDispatch Protocol Thunk driver.
> +#
> +#  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +#
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = SmmSwDispatch2OnSmmSwDispatchThunk
> +  FILE_GUID                      = 1410C6AC-9F4B-495b-9C23-8A5AEB0165E9
> +  MODULE_TYPE                    = DXE_SMM_DRIVER
> +  VERSION_STRING                 = 1.0
> +  PI_SPECIFICATION_VERSION       = 0x0001000A
> +  ENTRY_POINT                    = SmmSwDispatch2ThunkMain
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +[Sources]
> +  SmmSwDispatch2OnSmmSwDispatchThunk.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  IntelFrameworkPkg/IntelFrameworkPkg.dec
> +
> +[LibraryClasses]
> +  UefiDriverEntryPoint
> +  UefiBootServicesTableLib
> +  SmmServicesTableLib
> +  BaseLib
> +  IoLib
> +  DebugLib
> +
> +[Protocols]
> +  gEfiSmmControlProtocolGuid               # PROTOCOL ALWAYS_CONSUMED
> +  gEfiSmmSwDispatchProtocolGuid            # PROTOCOL ALWAYS_CONSUMED
> +  gEfiSmmCpuProtocolGuid                   # PROTOCOL ALWAYS_CONSUMED
> +  gEfiSmmSwDispatch2ProtocolGuid           # PROTOCOL ALWAYS_PRODUCED
> +
> +[Depex]
> +  gEfiSmmSwDispatchProtocolGuid AND
> +  gEfiSmmControlProtocolGuid AND
> +  gEfiSmmCpuProtocolGuid
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSav
> eInfoHandlerSmm.c
> b/Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSa
> veInfoHandlerSmm.c
> new file mode 100644
> index 0000000000..de257b35b5
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSa
> veInfoHandlerSmm.c
> @@ -0,0 +1,164 @@
> +/** @file
> +  A helper driver to save information to SMRAM after SMRR is enabled.
> +
> +  This driver is for ECP platforms.
> +
> +  Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +**/
> +
> +#include <PiSmm.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/SmmServicesTableLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/IoLib.h>
> +#include <Protocol/SmmSwDispatch.h>
> +#include <Protocol/SmmReadyToLock.h>
> +#include <Protocol/SmmControl.h>
> +#include <Guid/Vlv2DeviceRefCodePkgTokenSpace.h>
> +
> +#define SMM_FROM_SMBASE_DRIVER        0x55
> +#define SMM_FROM_CPU_DRIVER_SAVE_INFO 0x81
> +
> +#define EFI_SMRAM_CPU_NVS_HEADER_GUID \
> +  { \
> +    0x429501d9, 0xe447, 0x40f4, 0x86, 0x7b, 0x75, 0xc9, 0x3a, 0x1d, 0xb5,
> 0x4e \
> +  }
> +
> +UINT8    mSmiDataRegister;
> +BOOLEAN  mLocked = FALSE;
> +EFI_GUID mSmramCpuNvsHeaderGuid =
> EFI_SMRAM_CPU_NVS_HEADER_GUID;
> +
> +/**
> +  Dispatch function for a Software SMI handler.
> +
> +  @param  DispatchHandle        The handle of this dispatch function.
> +  @param  DispatchContext       The pointer to the dispatch function's
> context.
> +                                The SwSmiInputValue field is filled in
> +                                by the software dispatch driver prior to
> +                                invoking this dispatch function.
> +                                The dispatch function will only be called
> +                                for input values for which it is registered.
> +
> +  @return None
> +
> +**/
> +VOID
> +EFIAPI
> +SmramSaveInfoHandler (
> +  IN  EFI_HANDLE                    DispatchHandle,
> +  IN  EFI_SMM_SW_DISPATCH_CONTEXT   *DispatchContext
> +  )
> +{
> +  ASSERT (DispatchContext != NULL);
> +  ASSERT (DispatchContext->SwSmiInputValue ==
> SMM_FROM_SMBASE_DRIVER);
> +
> +  if (!mLocked && IoRead8 (mSmiDataRegister) ==
> SMM_FROM_CPU_DRIVER_SAVE_INFO) {
> +      CopyMem (
> +        (VOID *)(UINTN)(PcdGetEx64 (&gEfiVLVTokenSpaceGuid,
> PcdCpuLockBoxDataAddress)),
> +        (VOID *)(UINTN)(PcdGetEx64 (&gEfiVLVTokenSpaceGuid,
> PcdCpuSmramCpuDataAddress)),
> +        (UINTN)(PcdGetEx64 (&gEfiVLVTokenSpaceGuid, PcdCpuLockBoxSize))
> +        );
> +  }
> +}
> +
> +/**
> +  Smm Ready To Lock event notification handler.
> +
> +  It sets a flag indicating that SMRAM has been locked.
> +
> +  @param[in] Protocol   Points to the protocol's unique identifier.
> +  @param[in] Interface  Points to the interface instance.
> +  @param[in] Handle     The handle on which the interface was installed.
> +
> +  @retval EFI_SUCCESS   Notification handler runs successfully.
> + **/
> +EFI_STATUS
> +EFIAPI
> +SmmReadyToLockEventNotify (
> +  IN CONST EFI_GUID  *Protocol,
> +  IN VOID            *Interface,
> +  IN EFI_HANDLE      Handle
> +  )
> +{
> +  mLocked = TRUE;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Entry point function of this driver.
> +
> +  @param[in] ImageHandle  The firmware allocated handle for the EFI image.
> +  @param[in] SystemTable  A pointer to the EFI System Table.
> +
> +  @retval EFI_SUCCESS     The entry point is executed successfully.
> +  @retval other           Some error occurs when executing this entry point.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmramSaveInfoHandlerSmmMain (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  EFI_SMM_SW_DISPATCH_PROTOCOL  *SmmSwDispatch;
> +  EFI_SMM_SW_DISPATCH_CONTEXT   SmmSwDispatchContext;
> +  EFI_HANDLE                    DispatchHandle;
> +  EFI_SMM_CONTROL_PROTOCOL      *SmmControl;
> +  EFI_SMM_CONTROL_REGISTER      SmmControlRegister;
> +  VOID                          *Registration;
> +
> +  //
> +  // Get SMI data register
> +  //
> +  Status = SystemTable->BootServices->LocateProtocol (
> +                                        &gEfiSmmControlProtocolGuid,
> +                                        NULL,
> +                                        (VOID **)&SmmControl
> +                                        );
> +  ASSERT_EFI_ERROR (Status);
> +  Status = SmmControl->GetRegisterInfo (SmmControl,
> &SmmControlRegister);
> +  ASSERT_EFI_ERROR (Status);
> +  mSmiDataRegister = SmmControlRegister.SmiDataRegister;
> +
> +  //
> +  // Register software SMI handler
> +  //
> +
> +  Status = SystemTable->BootServices->LocateProtocol (
> +                                        &gEfiSmmSwDispatchProtocolGuid,
> +                                        NULL,
> +                                        (VOID **)&SmmSwDispatch
> +                                        );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  SmmSwDispatchContext.SwSmiInputValue =
> SMM_FROM_SMBASE_DRIVER;
> +  Status = SmmSwDispatch->Register (
> +                            SmmSwDispatch,
> +                            &SmramSaveInfoHandler,
> +                            &SmmSwDispatchContext,
> +                            &DispatchHandle
> +                            );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Register SMM Ready To Lock Protocol notification
> +  //
> +  Status = gSmst->SmmRegisterProtocolNotify (
> +                    &gEfiSmmReadyToLockProtocolGuid,
> +                    SmmReadyToLockEventNotify,
> +                    &Registration
> +                    );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSav
> eInfoHandlerSmm.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSa
> veInfoHandlerSmm.inf
> new file mode 100644
> index 0000000000..ec42c84472
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSa
> veInfoHandlerSmm.inf
> @@ -0,0 +1,60 @@
> +## @file
> +#
> +#  A helper driver to save information to SMRAM after SMRR is enabled.
> +#
> +#  Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +#
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = SmramSaveInfoHandlerSmm
> +  FILE_GUID                      = 63296C52-01CF-4eea-A47C-782A14DA6894
> +  MODULE_TYPE                    = DXE_SMM_DRIVER
> +  VERSION_STRING                 = 1.0
> +  PI_SPECIFICATION_VERSION       = 0x0001000A
> +
> +  ENTRY_POINT                    = SmramSaveInfoHandlerSmmMain
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +[Sources.common]
> +  SmramSaveInfoHandlerSmm.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  IntelFrameworkPkg/IntelFrameworkPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +
> +[LibraryClasses]
> +  UefiDriverEntryPoint
> +  UefiRuntimeServicesTableLib
> +  SmmServicesTableLib
> +  BaseLib
> +  BaseMemoryLib
> +  IoLib
> +
> +[Protocols]
> +  gEfiSmmSwDispatchProtocolGuid      ## CONSUMED
> +  gEfiSmmControlProtocolGuid         ## CONSUMED
> +  gEfiSmmReadyToLockProtocolGuid     ## CONSUMED
> +
> +[Pcd.common]
> +  gEfiVLVTokenSpaceGuid.PcdCpuLockBoxDataAddress
> +  gEfiVLVTokenSpaceGuid.PcdCpuSmramCpuDataAddress
> +  gEfiVLVTokenSpaceGuid.PcdCpuLockBoxSize
> +
> +[Depex]
> +  gEfiSmmSwDispatchProtocolGuid AND
> +  gEfiSmmControlProtocolGuid
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwSpare.bin
> b/Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwSpare.bin
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..7145947da44cf9920d9c593318
> 7dc96540ecd5ad
> GIT binary patch
> literal 262144
> zcmeIuF#!Mo0K%aDspoA6h(KY$fB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0
> RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> Wz<>b*1`HT5V8DO@0|pEj_<;c*e>=qh
> 
> literal 0
> HcmV?d00001
> 
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwWorking.bin
> b/Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwWorking.bin
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..dcb92498b93463a07d6dd695c
> f30ae9320414671
> GIT binary patch
> literal 8192
> zcmeIuu?;{_6hP6R7(<~Jr73J+0f`|PLyL*bAV$#hh$$53R<}M?+0OkiHtW`<Yssg
> h
> xKC?R__9A_~D*^-v5FkK+009C72oNAZfB*pk1PBlyK!5-
> N0t5&UAVA>f0uR>?&<Owl
> 
> literal 0
> HcmV?d00001
> 
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageVariable.bin
> b/Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageVariable.bin
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..7f8688b099f1e70491f16161a9
> 8c7b53c6b7a412
> GIT binary patch
> literal 253952
> zcmeI%O^8iV902hDdt-
> csBz8*8MwpQ%hEhIe#*B&i$RPO$VW}uzu_4JqQj&ZwrdW)P
> z5+x-IiKJ}A!oo+{Ai{p0^WKcd=;4Ktn%{Zd-
> g)Pq`#<OW?(M$r{YUgKN2h(ro!oU~
> zY4@SY&BNBTcSH;?bXecCa&fL_NGy)2BT_@Qw>48dcu)1GOZ!foY3SNNeSF*
> P-N&y#
> ztBBP-
> y}K{1m>(6zo~0|(Q}c#wMDyemXWJ%BX}wT)YkS<gHn$}@VrHz5hG>trXo{9-
> zj@tCQCDoUu@3vSOjj=G6r%fR+umZVUIoEP^n#7!;5yQIPWuKlJv*6T>rjZlspP
> bHL
> z%XQyf%dX^sJ!7I1AV6TS2$b{xG&W(Z8WnMOcGc!bvuc_TZW;Id!N<K-
> ^|3X58e?PZ
> zNSi`{009C72oNAZfB=C%7bxc$WlS2TI=wW0v8iU#&7Qlh=kDB?Hu3$rHBGU_6
> Uv{T
> z0uctAK&HHR*R{!IbJ{L;TwZtJ^~=^{XYb$aez<mgXDmuNm=!7KvMB0PE~Y(YT
> >58a
> z^8506n3h7OW&n7<CYy@E%Ue@=)e+~@y`<ss;kOswTwBuhYW}>sE2FzR)4g
> Oz?2K*2
> zc)zNYn8L3PDY^e|#VHy5A2pU<LrUQlOTI_xUd1l|NhR~cd1kI=Dr@6j>hQDG^
> z9y~
> z)%1>?$qX-
> 45^7(GY&M&pSeja)B|m=tR{^~!pYPDymZ|*G`0Z)>omr<iUo*ND#Q}%(
> z#qXQK??f(jOim#{fB*pk1PBlyK!5-
> N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk
> z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-
> N0t5&UAV7cs
> z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-
> N0t5&UAV7cs0RjXF5FkK+009C72oNAZ
> zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-
> N0t5&U
> zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-
> N0t5&UAV7cs0RjXF5FkK+009C7
> z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-
> N
> z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-
> N0t5&UAV7cs0RjXF5FkK+
> z009C72oNAZfB*pk1PBlyK!5-
> N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly
> zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-
> N0t5&UAV7cs0RjXF
> z5FkK+009C72oNAZfB*pk1PBlyK!5-
> N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk
> z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-
> N0t5&UAV7cs
> z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-
> N0t5&UAV7cs0RjXF5FkK+009C72oNAZ
> zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-
> N0t5&U
> zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-
> N0t5&UAV7cs0RjXF5FkK+009C7
> z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-
> N
> z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-
> N0t5&UAV7cs0RjXF5FkK+
> z009C72oNAZfB*pk1PBlyK!5-
> N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly
> zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-
> N0t5&UAV7cs0RjXF
> z5FkK+009C72oNAZfB*pk1PBlyK!5-
> N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk
> z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-
> N0t5&UAV7cs
> x0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-
> N0t5&UAV7cs0RjXF5Ev{1p8>TuLd5_8
> 
> literal 0
> HcmV?d00001
> 
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_HEADER.bin
> b/Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_HEADER.bin
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..ca10f7af61b91e1daf79e374c6
> c837ee06e6ea4c
> GIT binary patch
> literal 4096
> zcmezW9~DF`{lL%6z{14FB*3k}pva)gz`%g4LWMy9C;|Z>aWISJKRYACe`XN-
> zdWjX
> z5D!%Z*|dRYLwo`xSy+LDfCL}I0!K!u;9+(KhQmN#xdZtiJn*g^b-`!|jE2By2#kin
> zXb6mkz-S1JhQMeDjE2By2oN6vhZMvZSQS_m-
> a9~P11Oy!4i;B{%R~6`9t;ek3Ze=M
> WyCHnyZ5sS4?*qHCgWr|3bs+!{&RygH
> 
> literal 0
> HcmV?d00001
> 
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_HEADER_SPIL
> OCK.bin
> b/Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_HEADER_SPIL
> OCK.bin
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..f2dcb0067d1a48f08b4c404836
> 2443b5c7095aa9
> GIT binary patch
> literal 4096
> zcmezW9~DF`{lL%6z{14FB*3k}pva)gz`%g4LWMy9C;|Z>aWISJKRYACe`XN-
> zdWjX
> zAWsTa1lhEKXG44fBw1L2gn$Ge!vaS}sNi9C28P2xU%3PMAUyD{9d*HI2#kinX
> b6mk
> zz-
> S1JhQMeDjE2By2#kinXb2D=0*4gD7+4ip72Z2QX#*&oAPyE+fXhSp@*WHfq6(
> r4
> X3cDeE;%yrID(?fkvV-51v~?i>7>iv0
> 
> literal 0
> HcmV?d00001
> 
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/Vacant.bin
> b/Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/Vacant.bin
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..12d359146014baad9277a951b
> 237fd27e819db6e
> GIT binary patch
> literal 3928064
> zcmeIuF#!Mo0K%aDspo45h(KY$fB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0
> RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKf
> B^#r
> z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5
> V8DO@
> z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7
> %*VK
> zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
> 1`HT5
> zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd
> 0RsjM
> z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA
> z<>b*
> z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj
> Fkrxd
> z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r
> 3>YwA
> zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@
> 0|pEj
> rFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFz^EdVf>G}
> 
> literal 0
> HcmV?d00001
> 
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat
> b/Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat
> new file mode 100644
> index 0000000000..200ca05a23
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat
> @@ -0,0 +1,270 @@
> +@REM @file
> +@REM   Windows batch file to build BIOS ROM
> +@REM
> +@REM Copyright (c) 2006   - 2019, Intel Corporation. All rights reserved.<BR>
> +@REM
> +@REM   SPDX-License-Identifier: BSD-2-Clause-Patent
> +@REM
> +
> +@echo off
> +SetLocal EnableDelayedExpansion EnableExtensions
> +
> +set PLATFORM_BIN_PACKAGE=%WORKSPACE%\Vlv2SocBinPkg
> +if not exist %PLATFORM_BIN_PACKAGE% (
> +  if defined PACKAGES_PATH (
> +    for %%i IN (%PACKAGES_PATH%) DO (
> +      if exist %%~fi\Vlv2SocBinPkg (
> +        set PLATFORM_BIN_PACKAGE=%%~fi\Vlv2SocBinPkg
> +        goto PlatformBinPackageFound
> +      )
> +    )
> +  ) else (
> +    echo.
> +    echo !!! ERROR !!! Cannot find %PLATFORM_NAME% !!!
> +    echo.
> +    goto BldFail
> +  )
> +)
> +:PlatformBinPackageFound
> +
> +
> +:: Set script defaults
> +set exitCode=0
> +set BackupRom=1
> +set UpdateVBios=1
> +set SpiLock=0
> +set Stitch_Config=Stitch_Config.txt
> +copy /y nul Stitching.log >nul
> +
> +:: Set default Suffix as:  YYYY_MM_DD_HHMM
> +set hour=%time: =0%
> +reg copy "HKCU\Control Panel\International" "HKCU\Control
> Panel\International_Temp" /f >nul
> +reg add "HKCU\Control Panel\International" /v sShortDate /d
> "yyyy_MM_dd" /f >nul
> +for /f "tokens=1" %%i in ("%date%") do set today=%%i
> +reg copy "HKCU\Control Panel\International_Temp" "HKCU\Control
> Panel\International" /f >nul
> +reg delete "HKCU\Control Panel\International_Temp" /f >nul
> +set IFWI_Suffix=%today%_%hour:~0,2%%time:~3,2%
> +
> +:: Process input arguments
> +if "%~1"=="?"       goto Usage
> +if "%~1"=="/?"      goto Usage
> +if /i "%~1"=="Help" goto Usage
> +
> +:OptLoop
> +if /i "%~1"=="/nV" (
> +    set UpdateVBios=0
> +    shift
> +    goto OptLoop
> +)
> +if /i "%~1"=="/nB" (
> +    set BackupRom=0
> +    shift
> +    goto OptLoop
> +)
> +if /i "%~1"=="/yL" (
> +    set SpiLock=1
> +    shift
> +    goto OptLoop
> +)
> +
> +if /i "%~1"=="/B" (
> +    if "%~2"==""  goto Usage
> +    if not exist %~2 echo BIOS not found. & goto Usage
> +    set BIOS_Names=%~2
> +    set BIOS_File_Name=%~n2
> +    shift & shift
> +    goto OptLoop
> +)
> +if /i "%~1"=="/C" (
> +    if "%~2"==""  goto Usage
> +    if not exist %~2 echo ConfigFile not found. & goto Usage
> +    set Stitch_Config=%~2
> +    shift & shift
> +    goto OptLoop
> +)
> +if /i "%~1"=="/S" (
> +    if "%~2"==""  goto Usage
> +    set IFWI_Suffix=%~2
> +    shift & shift
> +    goto OptLoop
> +)
> +
> +if "%BIOS_File_Name:~0,4%"=="MNW2" (
> +   set Stitch_Config= MNW2_Stitch_Config.txt
> +)
> +if "%BIOS_File_Name:~3,4%"=="MNW2" (
> +   set Stitch_Config= MNW2_Stitch_Config.txt
> +)
> +
> +:: if no rom specified by user, search in ./ for ROM files
> +if "%BIOS_Names%"=="" (
> +    set "BIOS_Names= "
> +    for /f "tokens=*" %%i in ('dir /b *.rom') do set
> BIOS_Names=!BIOS_Names! %%i
> +    if "!BIOS_Names!"==" " (
> +        echo NO .ROM files found !!!
> +        goto Usage
> +    )
> +)
> +
> +:: Parse the Stitch_Config File
> +if not exist %Stitch_Config% (
> +    echo Stitch Configuration File %Stitch_Config% not found.
> +    goto ScriptFail
> +)
> +for /f "delims== tokens=1,2" %%i in (%Stitch_Config%) do (
> +    if /i "%%i"=="HEADER"      set IFWI_HEADER=%%j
> +    if /i "%%i"=="SEC_VERSION" set SEC_VERSION=%%j
> +    if /i "%%i"=="Source" (
> +        if /i "%%j"=="ALPHA" set Source_Prefix=A_
> +        if /i "%%j"=="BF" set Source_Prefix=BF_
> +        if /i "%%j"=="BE" set Source_Prefix=BE_
> +        if /i "%%j"=="PV" set Source_Prefix=PV_
> +        if /i "%%j"=="PR1" set Source_Prefix=PR1_
> +    )
> +)
> +
> +if %SpiLock% EQU 1 (
> +  set IFWI_HEADER_FILE=IFWIHeader\!IFWI_HEADER!_SPILOCK.bin
> +) else (
> +  set IFWI_HEADER_FILE=IFWIHeader\!IFWI_HEADER!.bin
> +)
> +
> +::
> **********************************************************
> ************
> +:: The Main Stitching Loop
> +::
> **********************************************************
> ************
> +echo %date%  %time% >>Stitching.log 2>&1
> +echo %date%  %time%
> +echo.
> +for %%i in (%BIOS_Names%) do (
> +
> +    REM  ----- Do NOT use :: for comments Inside of code blocks() -------
> +    set BIOS_Rom=%%i
> +    set BIOS_Name=%%~ni
> +    set BIOS_Version=!BIOS_Name:~-7,7!
> +
> +    REM extract PlatformType from BIOS filename
> +    set Platform_Type=!BIOS_Name:~0,4!
> +
> +    REM Special treat for BayLake FFD8
> +    set Temp_Name=!BIOS_Name:~0,7!
> +
> +
> +    REM Capitalize and validate the Platform_Type
> +    if /i "!Platform_Type!"=="MNW2" (
> +        set Platform_Type=MNW2
> +    ) else (
> +        echo Error - Unsupported PlatformType: !Platform_Type!
> +        goto Usage
> +    )
> +
> +
> +    REM search BIOS_Name for Arch substring:  either IA32 or X64
> +    if not "!BIOS_Name!"=="!BIOS_Name:_IA32_=!" (
> +        set Arch=IA32
> +    ) else if not "!BIOS_Name!"=="!BIOS_Name:_X64_=!" (
> +        set Arch=X64
> +    ) else (
> +        echo Error:  Could not determine Architecture for !BIOS_Rom!
> +        goto Usage
> +    )
> +    set
> IFWI_Prefix=!Platform_Type!_IFWI_%Source_Prefix%!Arch!_!!BIOS_Versio
> n!
> +
> +    REM search BIOS_Name for Build_Target substring: either R or D
> +    if not "!BIOS_Name!"=="!BIOS_Name:_R_=!" (
> +        set Build_Target=Release
> +        set IFWI_Prefix=!IFWI_Prefix!_R
> +    ) else if not "!BIOS_Name!"=="!BIOS_Name:_D_=!" (
> +        set Build_Target=Debug
> +        set IFWI_Prefix=!IFWI_Prefix!_D
> +    ) else (
> +        echo Error:  Could not determine Build Target for !BIOS_Rom!
> +        goto Usage
> +    )
> +
> +    REM Create a BIOS backup before Stitching
> +    if %BackupRom% EQU 1 (
> +        echo Creating backup of original BIOS rom.
> +        copy /y !BIOS_Rom! !BIOS_Rom!.orig >nul
> +    )
> +
> +    echo.  >>Stitching.log
> +    echo ********** Stitching !BIOS_Rom! **********  >>Stitching.log
> +    echo.  >>Stitching.log
> +    echo.
> +    echo Stitching IFWI for !BIOS_Rom! ...
> +    echo ---------------------------------------------------------------------------
> +    echo IFWI  Header: !IFWI_HEADER_FILE!,   SEC version: !SEC_VERSION!,
> +    echo BIOS Version: !BIOS_Version!
> +
> +    echo Platform Type: !Platform_Type!,     IFWI Prefix: %BIOS_ID%
> +    echo ---------------------------------------------------------------------------
> +
> +    echo -----------------------------
> +    echo.
> +    echo Generating IFWI... %BIOS_ID%.bin
> +    echo.
> +
> +    copy /b/y !IFWI_HEADER_FILE!
> + %PLATFORM_BIN_PACKAGE%\SEC\!SEC_VERSION!\VLV_SEC_REGION.bin
> + %PLATFORM_BIN_PACKAGE%\SEC\!SEC_VERSION!\Vacant.bin
> + !BIOS_Rom! %BIOS_ID%.bin
> +    echo.
> +    echo
> ==========================================================
> =================
> +)
> +@echo off
> +
> +::********************************************************
> **************
> +:: end of main loop
> +::********************************************************
> **************
> +
> +echo.
> +echo  -- All specified ROM files Stitched. --
> +echo.
> +goto Exit
> +
> +:Usage
> +echo.
> +echo
> **********************************************************
> ****************************************
> +echo This Script is used to Stitch together BIOS, GOP Driver, Microcode
> Patch and TXE FW
> +echo into a single Integrated Firmware Image (IFWI).
> +echo.
> +echo Usage: IFWIStitch.bat [flags] [/B BIOS.ROM] [/C Stitch_Config] [/S
> IFWI_Suffix]
> +echo.
> +echo    This script has NO Required arguments, so that the user can just
> double click from the GUI.
> +echo    However, this requires that the BIOS.ROM file name is formatted
> correctly.
> +echo.
> +echo    /nG             Do NOT update the GOP driver.  (applies to all ROM files
> for this run)
> +echo    /nV             Do NOT update the VBIOS.       (applies to all ROM files for
> this run)
> +echo    /nM             Do NOT update the Microcode.   (applies to all ROM files
> for this run)
> +echo    /nB             Do NOT backup BIOS.ROMs. (Default will backup to
> BIOS.ROM.Orig)
> +echo.
> +echo    BIOS.ROM:       A single BIOS ROM file to use for stitching
> +echo                    (DEFAULT: ALL .ROM files inside the current directory)
> +echo    Stitch_Config:  Text file containing version info of each FW
> component
> +echo                    (DEFAULT: Stitch_Config.txt)
> +echo    IFWI_Suffix:    Suffix to append to the end of the IFWI filename
> +echo                    (DEFAULT: YYYY_MM_DD_HHMM)
> +echo.
> +echo Examples:
> +echo    IFIWStitch.bat                                      : Stitch all ROMs with defaults
> +echo    IFIWStitch.bat /B C:/MyRoms/testBIOS.rom            : Stitch single ROM
> with defaults
> +echo    IFIWStitch.bat /B ../testBIOS.rom /S test123        : Stitch single ROM
> and add custom suffix
> +echo    IFIWStitch.bat /nM /nB /B testBIOS.rom /S test456   : Stitch single
> ROM, keep uCode from .rom,
> +echo                                                          don't create backup, and add custom
> suffix.
> +echo
> **********************************************************
> ******************************************
> +pause
> +exit /b 1
> +
> +:ScriptFail
> +set exitCode=1
> +
> +:Exit
> +echo  -- See Stitching.log for more info. --
> +echo.
> +echo %date%  %time%
> +echo.
> +if "%Platform_Type%"=="MNW2" (
> +  echo .
> +) else (
> +  echo only support MNW2 for this project!
> +pause
> +)
> +exit /b %exitCode%
> +EndLocal
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Stitch/MNW2_Stitch_Config.txt
> b/Platform/Intel/Vlv2TbltDevicePkg/Stitch/MNW2_Stitch_Config.txt
> new file mode 100644
> index 0000000000..82abe6548f
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Stitch/MNW2_Stitch_Config.txt
> @@ -0,0 +1,10 @@
> +#
> +# Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +
> +HEADER=IFWI_HEADER
> +SEC_VERSION=1.0.2.1060v5
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c
> b/Platform/Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c
> new file mode 100644
> index 0000000000..3e58a6d22a
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c
> @@ -0,0 +1,33 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +
> +**/
> +
> +/**
> +  The user Entry Point for Application. The user code starts with this function
> +  as the real entry point for the image goes into a library that calls this
> +  function.
> +
> +  @param[in] ImageHandle    The firmware allocated handle for the EFI
> image.
> +  @param[in] SystemTable    A pointer to the EFI System Table.
> +
> +  @retval EFI_SUCCESS       The entry point is executed successfully.
> +  @retval other             Some error occurs when executing this entry point.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitializeUserInterface (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf
> new file mode 100644
> index 0000000000..f7a0a83b80
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf
> @@ -0,0 +1,32 @@
> +#
> +#
> +# Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = UiApp
> +  FILE_GUID                      = 462CAA21-7614-4503-836E-8AB6F4662331
> +  MODULE_TYPE                    = UEFI_APPLICATION
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = InitializeUserInterface
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +
> +[Sources]
> +  FrontPage.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> +  UefiApplicationEntryPoint
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.c
> b/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.c
> new file mode 100644
> index 0000000000..ba81bd9def
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.c
> @@ -0,0 +1,929 @@
> +
> +/*++
> +
> +Copyright (c)  2011  - 2018, Intel Corporation. All rights reserved
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  IgdOpRegion.c
> +
> +Abstract:
> +
> +  This is part of the implementation of an Intel Graphics drivers OpRegion /
> +  Software SCI interface between system BIOS, ASL code, and Graphics
> drivers.
> +  The code in this file will load the driver and initialize the interface
> +
> +  Supporting Specifiction: OpRegion / Software SCI SPEC 0.70
> +
> +  Acronyms:
> +    IGD:        Internal Graphics Device
> +    NVS:        ACPI Non Volatile Storage
> +    OpRegion:   ACPI Operational Region
> +    VBT:        Video BIOS Table (OEM customizable data)
> +
> +--*/
> +
> +//
> +// Include files
> +//
> +
> +
> +#include "IgdOpRegion.h"
> +#include "VlvPlatformInit.h"
> +#include <FrameworkDxe.h>
> +#include <Uefi.h>
> +#include <PchRegs.h>
> +
> +#include <Guid/DataHubRecords.h>
> +
> +#include <Protocol/IgdOpRegion.h>
> +#include <Protocol/FrameworkHii.h>
> +#include <Protocol/FirmwareVolume2.h>
> +#include <Protocol/PlatformGopPolicy.h>
> +#include <Protocol/PciIo.h>
> +#include <Protocol/CpuIo.h>
> +#include <Protocol/GlobalNvsArea.h>
> +#include <Protocol/DxeSmmReadyToLock.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/S3BootScriptLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Protocol/DriverBinding.h>
> +#include <Library/PrintLib.h>
> +#include <Library/BaseMemoryLib.h>
> +
> +
> +
> +UINT8 gSVER[12] = "Intel";
> +
> +extern DXE_VLV_PLATFORM_POLICY_PROTOCOL  *DxePlatformSaPolicy;
> +
> +//
> +// Global variables
> +//
> +
> +IGD_OPREGION_PROTOCOL mIgdOpRegion;
> +EFI_GUID              mMiscSubClass = EFI_MISC_SUBCLASS_GUID;
> +EFI_EVENT             mConOutEvent;
> +EFI_EVENT             mSetGOPverEvent;
> +VOID                  *mConOutReg;
> +
> +#define DEFAULT_FORM_BUFFER_SIZE    0xFFFF
> +#ifndef ECP_FLAG
> +#if 0
> +/**
> +
> +  Get the HII protocol interface
> +
> +  @param Hii     HII protocol interface
> +
> +  @retval        Status code
> +
> +**/
> +static
> +EFI_STATUS
> +GetHiiInterface (
> +  OUT     EFI_HII_PROTOCOL    **Hii
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  //
> +  // There should only be one HII protocol
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiHiiProtocolGuid,
> +                  NULL,
> +                  (VOID **) Hii
> +                  );
> +
> +  return Status;;
> +}
> +#endif
> +#endif
> +
> +/**
> +
> +  Get VBT data.
> +
> +  @param[in] VbtFileBuffer    Pointer to VBT data buffer.
> +
> +  @retval EFI_SUCCESS      VBT data was returned.
> +  @retval EFI_NOT_FOUND    VBT data not found.
> +  @exception EFI_UNSUPPORTED  Invalid signature in VBT data.
> +
> +**/
> +EFI_STATUS
> +GetIntegratedIntelVbtPtr (
> +  OUT VBIOS_VBT_STRUCTURE **VbtFileBuffer
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  EFI_PHYSICAL_ADDRESS          VbtAddress = 0;
> +  UINTN                         FvProtocolCount;
> +  EFI_HANDLE                    *FvHandles;
> +  EFI_FIRMWARE_VOLUME2_PROTOCOL  *Fv;
> +  UINTN                         Index;
> +  UINT32                        AuthenticationStatus;
> +
> +  UINT8                         *Buffer;
> +  UINTN                         VbtBufferSize = 0;
> +
> +  Buffer = 0;
> +  FvHandles      = NULL;
> +  *VbtFileBuffer = NULL;
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gEfiFirmwareVolume2ProtocolGuid,
> +                  NULL,
> +                  &FvProtocolCount,
> +                  &FvHandles
> +                  );
> +
> +  if (!EFI_ERROR (Status)) {
> +    for (Index = 0; Index < FvProtocolCount; Index++) {
> +      Status = gBS->HandleProtocol (
> +                      FvHandles[Index],
> +                      &gEfiFirmwareVolume2ProtocolGuid,
> +                      (VOID **) &Fv
> +                      );
> +      VbtBufferSize = 0;
> +      Status = Fv->ReadSection (
> +                     Fv,
> +                     &gBmpImageGuid,
> +                     EFI_SECTION_RAW,
> +                     0,
> +                    (void **)&Buffer,
> +                     &VbtBufferSize,
> +                     &AuthenticationStatus
> +                     );
> +
> +      if (!EFI_ERROR (Status)) {
> +        VbtAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
> +        Status = EFI_SUCCESS;
> +        break;
> +      }
> +    }
> +  } else {
> +    Status = EFI_NOT_FOUND;
> +  }
> +
> +  if (FvHandles != NULL) {
> +    FreePool(FvHandles);
> +    FvHandles = NULL;
> +  }
> +
> +
> +  //
> +  // Check VBT signature
> +  //
> +  *VbtFileBuffer = (VBIOS_VBT_STRUCTURE *) (UINTN) VbtAddress;
> +  if (*VbtFileBuffer != NULL) {
> +    if ((*((UINT32 *) ((*VbtFileBuffer)->HeaderSignature))) !=
> VBT_SIGNATURE) {
> +      if (*VbtFileBuffer != NULL) {
> +        *VbtFileBuffer = NULL;
> +      }
> +      return EFI_UNSUPPORTED;
> +    }
> +    //
> +    // Check VBT size
> +    //
> +    if ((*VbtFileBuffer)->HeaderVbtSize > VbtBufferSize) {
> +      (*VbtFileBuffer)->HeaderVbtSize = (UINT16) VbtBufferSize;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +//
> +// Function implementations.
> +//
> +/**
> +
> +  Get a pointer to an uncompressed image of the Intel video BIOS.
> +
> +  Note: This function would only be called if the video BIOS at 0xC000 is
> +        missing or not an Intel video BIOS.  It may not be an Intel video BIOS
> +        if the Intel graphic contoller is considered a secondary adapter.
> +
> +
> +  @param VBiosROMImage  Pointer to an uncompressed Intel video BIOS.
> This pointer must
> +                        be set to NULL if an uncompressed image of the Intel Video
> BIOS
> +                        is not obtainable.
> +
> +
> +  @retval EFI_SUCCESS   VBiosPtr is updated.
> +
> +**/
> +EFI_STATUS
> +GetIntegratedIntelVBiosPtr (
> +  INTEL_VBIOS_OPTION_ROM_HEADER **VBiosImage
> +  )
> +{
> +  EFI_HANDLE                  *HandleBuffer;
> +  UINTN                       HandleCount;
> +  UINTN                       Index;
> +  INTEL_VBIOS_PCIR_STRUCTURE  *PcirBlockPtr;
> +  EFI_STATUS                  Status;
> +  EFI_PCI_IO_PROTOCOL         *PciIo;
> +  INTEL_VBIOS_OPTION_ROM_HEADER *VBiosRomImage;
> +
> +  //
> +  // Set as if an umcompressed Intel video BIOS image was not obtainable.
> +  //
> +  VBiosRomImage = NULL;
> +  *VBiosImage = NULL;
> +
> +  //
> +  // Get all PCI IO protocols
> +  //
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gEfiPciIoProtocolGuid,
> +                  NULL,
> +                  &HandleCount,
> +                  &HandleBuffer
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Find the video BIOS by checking each PCI IO handle for an Intel video
> +  // BIOS OPROM.
> +  //
> +  for (Index = 0; Index < HandleCount; Index++) {
> +    Status = gBS->HandleProtocol (
> +                    HandleBuffer[Index],
> +                    &gEfiPciIoProtocolGuid,
> +                    (void **)&PciIo
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    VBiosRomImage = PciIo->RomImage;
> +
> +    //
> +    // If this PCI device doesn't have a ROM image, skip to the next device.
> +    //
> +    if (!VBiosRomImage) {
> +      continue;
> +    }
> +
> +    //
> +    // Get pointer to PCIR structure
> +    //
> +    PcirBlockPtr = (INTEL_VBIOS_PCIR_STRUCTURE *)((UINT8 *)
> VBiosRomImage + VBiosRomImage->PcirOffset);
> +
> +    //
> +    // Check if we have an Intel video BIOS OPROM.
> +    //
> +    if ((VBiosRomImage->Signature == OPTION_ROM_SIGNATURE) &&
> +        (PcirBlockPtr->VendorId == IGD_VID) &&
> +        (PcirBlockPtr->ClassCode[0] == 0x00) &&
> +        (PcirBlockPtr->ClassCode[1] == 0x00) &&
> +        (PcirBlockPtr->ClassCode[2] == 0x03)
> +       ) {
> +      //
> +      // Found Intel video BIOS.
> +      //
> +      *VBiosImage = VBiosRomImage;
> +      return EFI_SUCCESS;
> +    }
> +  }
> +
> +  //
> +  // No Intel video BIOS found.
> +  //
> +
> +  //
> +  // Free any allocated buffers
> +  //
> +  return EFI_UNSUPPORTED;
> +}
> +
> +EFI_STATUS
> +SearchChildHandle(
> +  EFI_HANDLE Father,
> +  EFI_HANDLE *Child
> +  )
> +{
> +  EFI_STATUS            Status;
> +  UINTN                 HandleIndex;
> +  EFI_GUID              **ProtocolGuidArray = NULL;
> +  UINTN                 ArrayCount;
> +  UINTN                 ProtocolIndex;
> +  UINTN                 OpenInfoCount;
> +  UINTN                 OpenInfoIndex;
> +  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY  *OpenInfo = NULL;
> +  UINTN                 mHandleCount;
> +  EFI_HANDLE            *mHandleBuffer= NULL;
> +
> +  //
> +  // Retrieve the list of all handles from the handle database
> +  //
> +  Status = gBS->LocateHandleBuffer (
> +                  AllHandles,
> +                  NULL,
> +                  NULL,
> +                  &mHandleCount,
> +                  &mHandleBuffer
> +                  );
> +
> +  for (HandleIndex = 0; HandleIndex < mHandleCount; HandleIndex++) {
> +    //
> +    // Retrieve the list of all the protocols on each handle
> +    //
> +    Status = gBS->ProtocolsPerHandle (
> +                    mHandleBuffer[HandleIndex],
> +                    &ProtocolGuidArray,
> +                    &ArrayCount
> +                    );
> +    if (!EFI_ERROR (Status)) {
> +      for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
> +        Status = gBS->OpenProtocolInformation (
> +                        mHandleBuffer[HandleIndex],
> +                        ProtocolGuidArray[ProtocolIndex],
> +                        &OpenInfo,
> +                        &OpenInfoCount
> +                        );
> +        if (!EFI_ERROR (Status)) {
> +          for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount;
> OpenInfoIndex++) {
> +            if(OpenInfo[OpenInfoIndex].AgentHandle == Father) {
> +              if ((OpenInfo[OpenInfoIndex].Attributes &
> EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) ==
> EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
> +                *Child = mHandleBuffer[HandleIndex];
> +                Status = EFI_SUCCESS;
> +                goto TryReturn;
> +              }
> +            }
> +          }
> +          Status = EFI_NOT_FOUND;
> +        }
> +      }
> +      if(OpenInfo != NULL) {
> +        FreePool(OpenInfo);
> +        OpenInfo = NULL;
> +      }
> +    }
> +    FreePool (ProtocolGuidArray);
> +    ProtocolGuidArray = NULL;
> +  }
> +TryReturn:
> +  if(OpenInfo != NULL) {
> +    FreePool (OpenInfo);
> +    OpenInfo = NULL;
> +  }
> +  if(ProtocolGuidArray != NULL) {
> +    FreePool(ProtocolGuidArray);
> +    ProtocolGuidArray = NULL;
> +  }
> +  if(mHandleBuffer != NULL) {
> +    FreePool (mHandleBuffer);
> +    mHandleBuffer = NULL;
> +  }
> +  return Status;
> +}
> +
> +EFI_STATUS
> +JudgeHandleIsPCIDevice(
> +  EFI_HANDLE            Handle,
> +  UINT8                 Device,
> +  UINT8                 Funs
> +  )
> +{
> +  EFI_STATUS  Status;
> +  EFI_DEVICE_PATH   *DPath;
> +
> +  Status = gBS->HandleProtocol (
> +                  Handle,
> +                  &gEfiDevicePathProtocolGuid,
> +                  (VOID **) &DPath
> +                  );
> +  if(!EFI_ERROR(Status)) {
> +    while(!IsDevicePathEnd(DPath)) {
> +      if((DPath->Type == HARDWARE_DEVICE_PATH) && (DPath->SubType ==
> HW_PCI_DP)) {
> +        PCI_DEVICE_PATH   *PCIPath;
> +
> +        PCIPath = (PCI_DEVICE_PATH*) DPath;
> +        DPath = NextDevicePathNode(DPath);
> +        if(IsDevicePathEnd(DPath) && (PCIPath->Device == Device) &&
> (PCIPath->Function == Funs)) {
> +          return EFI_SUCCESS;
> +        }
> +      } else {
> +        DPath = NextDevicePathNode(DPath);
> +      }
> +    }
> +  }
> +  return EFI_UNSUPPORTED;
> +}
> +
> +EFI_STATUS
> +GetDriverName(
> +  EFI_HANDLE   Handle,
> +  CHAR16         *GopVersion
> +  )
> +{
> +  EFI_DRIVER_BINDING_PROTOCOL           *BindHandle = NULL;
> +  EFI_STATUS                            Status;
> +  UINT32                                Version;
> +  UINT16                                *Ptr;
> +
> +  Status = gBS->OpenProtocol(
> +                  Handle,
> +                  &gEfiDriverBindingProtocolGuid,
> +                  (VOID**)&BindHandle,
> +                  NULL,
> +                  NULL,
> +                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                  );
> +  if (EFI_ERROR(Status)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  Version = BindHandle->Version;
> +  Ptr = (UINT16*)&Version;
> +  UnicodeSPrint(GopVersion, 40, L"7.0.%04d", *(Ptr));
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +GetGOPDriverVersion(
> +  CHAR16 *GopVersion
> +  )
> +{
> +  UINTN                 HandleCount;
> +  EFI_HANDLE            *Handles= NULL;
> +  UINTN                 Index;
> +  EFI_STATUS            Status;
> +  EFI_HANDLE            Child = 0;
> +
> +  Status = gBS->LocateHandleBuffer(
> +                  ByProtocol,
> +                  &gEfiDriverBindingProtocolGuid,
> +                  NULL,
> +                  &HandleCount,
> +                  &Handles
> +                  );
> +  for (Index = 0; Index < HandleCount ; Index++) {
> +    Status = SearchChildHandle(Handles[Index], &Child);
> +    if(!EFI_ERROR(Status)) {
> +      Status = JudgeHandleIsPCIDevice(Child, 0x02, 0x00);
> +      if(!EFI_ERROR(Status)) {
> +        return GetDriverName(Handles[Index], GopVersion);
> +      }
> +    }
> +  }
> +  return EFI_UNSUPPORTED;
> +}
> +
> +
> +/**
> +  Get Intel GOP driver version and copy it into IGD OpRegion GVER. This
> version
> +  is picked up by IGD driver and displayed in CUI.
> +
> +  @param  Event             A pointer to the Event that triggered the callback.
> +  @param  Context           A pointer to private data registered with the
> callback function.
> +
> +  @retval EFI_SUCCESS       Video BIOS VBT information returned.
> +  @retval EFI_UNSUPPORTED   Could not find VBT information
> (*VBiosVbtPtr = NULL).
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetGOPVersionCallback (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  )
> +{
> +  CHAR16                GopVersion[16] = {0};
> +  EFI_STATUS            Status;
> +
> +  Status = GetGOPDriverVersion(GopVersion);
> +  if(!EFI_ERROR(Status)) {
> +    StrCpy((CHAR16*)&(mIgdOpRegion.OpRegion->Header.GOPV[0]),
> GopVersion);
> +    return Status;
> +  }
> +  return EFI_UNSUPPORTED;
> +}
> +
> +/**
> +  Get Intel video BIOS VBT information (i.e. Pointer to VBT and VBT size).
> +  The VBT (Video BIOS Table) is a block of customizable data that is built
> +  within the video BIOS and edited by customers.
> +
> +  @param  Event             A pointer to the Event that triggered the callback.
> +  @param  Context           A pointer to private data registered with the
> callback function.
> +
> +  @retval EFI_SUCCESS       Video BIOS VBT information returned.
> +  @retval EFI_UNSUPPORTED   Could not find VBT information
> (*VBiosVbtPtr = NULL).
> +
> +**/
> +EFI_STATUS
> +GetVBiosVbtCallback (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  )
> +{
> +  INTEL_VBIOS_PCIR_STRUCTURE    *PcirBlockPtr;
> +  UINT16                        PciVenderId;
> +  UINT16                        PciDeviceId;
> +  INTEL_VBIOS_OPTION_ROM_HEADER *VBiosPtr;
> +  VBIOS_VBT_STRUCTURE           *VBiosVbtPtr;
> +  VBIOS_VBT_STRUCTURE           *VbtFileBuffer = NULL;
> +
> +  VBiosPtr = (INTEL_VBIOS_OPTION_ROM_HEADER
> *)(UINTN)(VBIOS_LOCATION_PRIMARY);
> +  PcirBlockPtr = (INTEL_VBIOS_PCIR_STRUCTURE *)((UINT8 *)VBiosPtr +
> VBiosPtr->PcirOffset);
> +  PciVenderId = PcirBlockPtr->VendorId;
> +  PciDeviceId = PcirBlockPtr->DeviceId;
> +
> +  //
> +  // If the video BIOS is not at 0xC0000 or it is not an Intel video BIOS get
> +  // the integrated Intel video BIOS (must be uncompressed).
> +  //
> +  if ((VBiosPtr->Signature != OPTION_ROM_SIGNATURE) || (PciVenderId !=
> IGD_VID) || (PciDeviceId != IGD_DID_VLV)) {
> +    GetIntegratedIntelVBiosPtr (&VBiosPtr);
> +
> +    if(VBiosPtr) {
> +      //
> +      // Video BIOS found.
> +      //
> +      PcirBlockPtr = (INTEL_VBIOS_PCIR_STRUCTURE *)((UINT8 *)VBiosPtr +
> VBiosPtr->PcirOffset);
> +      PciVenderId = PcirBlockPtr->VendorId;
> +      if( (VBiosPtr->Signature != OPTION_ROM_SIGNATURE) ||
> (PciVenderId != IGD_VID)) {
> +        //
> +        // Intel video BIOS not found.
> +        //
> +        VBiosVbtPtr = NULL;
> +        return EFI_UNSUPPORTED;
> +      }
> +    } else {
> +      //
> +      // No Video BIOS found, try to get VBT from FV.
> +      //
> +      GetIntegratedIntelVbtPtr (&VbtFileBuffer);
> +      if (VbtFileBuffer != NULL) {
> +        //
> +        // Video BIOS not found, use VBT from FV
> +        //
> +        DEBUG ((EFI_D_ERROR, "VBT data found\n"));
> +        (gBS->CopyMem) (
> +                mIgdOpRegion.OpRegion->VBT.GVD1,
> +                VbtFileBuffer,
> +                VbtFileBuffer->HeaderVbtSize
> +                );
> +        FreePool (VbtFileBuffer);
> +        return EFI_SUCCESS;
> +      }
> +    }
> +    if ((VBiosPtr == NULL) ) {
> +      //
> +      // Intel video BIOS not found.
> +      //
> +      VBiosVbtPtr = NULL;
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +
> +  DEBUG ((EFI_D_ERROR, "VBIOS found at 0x%X\n", VBiosPtr));
> +  VBiosVbtPtr = (VBIOS_VBT_STRUCTURE *) ((UINT8 *) VBiosPtr + VBiosPtr-
> >VbtOffset);
> +
> +  if ((*((UINT32 *) (VBiosVbtPtr->HeaderSignature))) != VBT_SIGNATURE) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Initialize Video BIOS version with its build number.
> +  //
> +  mIgdOpRegion.OpRegion->Header.VVER[0] = VBiosVbtPtr-
> >CoreBlockBiosBuild[0];
> +  mIgdOpRegion.OpRegion->Header.VVER[1] = VBiosVbtPtr-
> >CoreBlockBiosBuild[1];
> +  mIgdOpRegion.OpRegion->Header.VVER[2] = VBiosVbtPtr-
> >CoreBlockBiosBuild[2];
> +  mIgdOpRegion.OpRegion->Header.VVER[3] = VBiosVbtPtr-
> >CoreBlockBiosBuild[3];
> +  (gBS->CopyMem) (
> +          mIgdOpRegion.OpRegion->VBT.GVD1,
> +          VBiosVbtPtr,
> +          VBiosVbtPtr->HeaderVbtSize
> +          );
> +
> +  //
> +  // Return final status
> +  //
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Graphics OpRegion / Software SCI driver installation function.
> +
> +  @param ImageHandle     Handle for this drivers loaded image protocol.
> +  @param SystemTable     EFI system table.
> +
> +  @retval EFI_SUCCESS    The driver installed without error.
> +  @retval EFI_ABORTED    The driver encountered an error and could not
> complete
> +                         installation of the ACPI tables.
> +
> +**/
> +EFI_STATUS
> +IgdOpRegionInit (
> +  void
> +  )
> +{
> +  EFI_HANDLE                    Handle;
> +  EFI_STATUS                    Status;
> +  EFI_GLOBAL_NVS_AREA_PROTOCOL  *GlobalNvsArea;
> +  UINT32                        DwordData;
> +  EFI_CPU_IO_PROTOCOL           *CpuIo;
> +  UINT16                        Data16;
> +  UINT16                        AcpiBase;
> +  VOID                          *gConOutNotifyReg;
> +
> +
> +  //
> +  //  Locate the Global NVS Protocol.
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiGlobalNvsAreaProtocolGuid,
> +                  NULL,
> +                  (void **)&GlobalNvsArea
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Allocate an ACPI NVS memory buffer as the IGD OpRegion, zero initialize
> +  // the first 1K, and set the IGD OpRegion pointer in the Global NVS
> +  // area structure.
> +  //
> +  Status = (gBS->AllocatePool) (
> +                   EfiACPIMemoryNVS,
> +                   sizeof (IGD_OPREGION_STRUC),
> +                  (void **)&mIgdOpRegion.OpRegion
> +                   );
> +  ASSERT_EFI_ERROR (Status);
> +  (gBS->SetMem) (
> +          mIgdOpRegion.OpRegion,
> +          sizeof (IGD_OPREGION_STRUC),
> +          0
> +          );
> +  GlobalNvsArea->Area->IgdOpRegionAddress =
> (UINT32)(UINTN)(mIgdOpRegion.OpRegion);
> +
> +  //
> +  // If IGD is disabled return
> +  //
> +  if (IgdMmPci32 (0) == 0xFFFFFFFF) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  //
> +  // Initialize OpRegion Header
> +  //
> +
> +  (gBS->CopyMem) (
> +          mIgdOpRegion.OpRegion->Header.SIGN,
> +          HEADER_SIGNATURE,
> +          sizeof(HEADER_SIGNATURE)
> +          );
> +
> +
> +  //
> +  // Set OpRegion Size in KBs
> +  //
> +  mIgdOpRegion.OpRegion->Header.SIZE = HEADER_SIZE/1024;
> +
> +  //
> +  // FIXME: Need to check Header OVER Field and the supported version.
> +  //
> +  mIgdOpRegion.OpRegion->Header.OVER = (UINT32) (LShiftU64
> (HEADER_OPREGION_VER, 16) + LShiftU64 (HEADER_OPREGION_REV, 8));
> +#ifdef ECP_FLAG
> +  CopyMem(mIgdOpRegion.OpRegion->Header.SVER, gSVER,
> sizeof(gSVER));
> +#else
> +  gBS->CopyMem(
> +         mIgdOpRegion.OpRegion->Header.SVER,
> +         gSVER,
> +         sizeof(gSVER)
> +         );
> +#endif
> +  DEBUG ((EFI_D_ERROR, "System BIOS ID is %a\n",
> mIgdOpRegion.OpRegion->Header.SVER));
> +
> +
> +  mIgdOpRegion.OpRegion->Header.MBOX = HEADER_MBOX_SUPPORT;
> +
> +  if( 1 == DxePlatformSaPolicy->IdleReserve) {
> +    mIgdOpRegion.OpRegion->Header.PCON = (mIgdOpRegion.OpRegion-
> >Header.PCON & 0xFFFC) | BIT1;
> +  } else {
> +    mIgdOpRegion.OpRegion->Header.PCON = (mIgdOpRegion.OpRegion-
> >Header.PCON & 0xFFFC) | (BIT1 | BIT0);
> +  }
> +
> +  //
> +  //For graphics driver to identify if LPE Audio/HD Audio is enabled on the
> platform
> +  //
> +  mIgdOpRegion.OpRegion->Header.PCON &=
> AUDIO_TYPE_SUPPORT_MASK;
> +  mIgdOpRegion.OpRegion->Header.PCON &= AUDIO_TYPE_FIELD_MASK;
> +  if ( 1 == DxePlatformSaPolicy->AudioTypeSupport ) {
> +    mIgdOpRegion.OpRegion->Header.PCON = HD_AUDIO_SUPPORT;
> +    mIgdOpRegion.OpRegion->Header.PCON |= AUDIO_TYPE_FIELD_VALID;
> +  }
> +
> +  //
> +  // Initialize OpRegion Mailbox 1 (Public ACPI Methods).
> +  //
> +  //<TODO> The initial setting of mailbox 1 fields is implementation specific.
> +  // Adjust them as needed many even coming from user setting in setup.
> +  //
> +  //Workaround to solve LVDS is off after entering OS in desktop platform
> +  //
> +  mIgdOpRegion.OpRegion->MBox1.CLID = DxePlatformSaPolicy-
> >IgdPanelFeatures.LidStatus;
> +
> +  //
> +  // Initialize OpRegion Mailbox 3 (ASLE Interrupt and Power Conservation).
> +  //
> +  //<TODO> The initial setting of mailbox 3 fields is implementation specific.
> +  // Adjust them as needed many even coming from user setting in setup.
> +  //
> +
> +  //
> +  // Do not initialize TCHE. This field is written by the graphics driver only.
> +  //
> +
> +  //
> +  // The ALSI field is generally initialized by ASL code by reading the
> embedded controller.
> +  //
> +
> +  mIgdOpRegion.OpRegion->MBox3.BCLP = BACKLIGHT_BRIGHTNESS;
> +
> +  mIgdOpRegion.OpRegion->MBox3.PFIT = (FIELD_VALID_BIT |
> PFIT_STRETCH);
> +  if ( DxePlatformSaPolicy->IgdPanelFeatures.PFITStatus == 2) {
> +  	//
> +    // Center
> +    //
> +    mIgdOpRegion.OpRegion->MBox3.PFIT = (FIELD_VALID_BIT |
> PFIT_CENTER);
> +  } else if (DxePlatformSaPolicy->IgdPanelFeatures.PFITStatus == 1) {
> +  	//
> +    // Stretch
> +    //
> +    mIgdOpRegion.OpRegion->MBox3.PFIT = (FIELD_VALID_BIT |
> PFIT_STRETCH);
> +  } else {
> +  	//
> +    // Auto
> +    //
> +    mIgdOpRegion.OpRegion->MBox3.PFIT = (FIELD_VALID_BIT |
> PFIT_SETUP_AUTO);
> +  }
> +
> +  //
> +  // Set Initial current Brightness
> +  //
> +  mIgdOpRegion.OpRegion->MBox3.CBLV = (INIT_BRIGHT_LEVEL |
> FIELD_VALID_BIT);
> +
> +  //
> +  // <EXAMPLE> Create a static Backlight Brightness Level Duty cycle
> Mapping Table
> +  // Possible 20 entries (example used 10), each 16 bits as follows:
> +  // [15] = Field Valid bit, [14:08] = Level in Percentage (0-64h), [07:00] =
> Desired duty cycle (0 - FFh).
> +  //
> +  //                                             %            Brightness
> +  mIgdOpRegion.OpRegion->MBox3.BCLM[0]   = ( (  0 << 8 ) + ( 0xFF - 0xFC )
> + WORD_FIELD_VALID_BIT);
> +  mIgdOpRegion.OpRegion->MBox3.BCLM[1]   = ( (  1 << 8 ) + ( 0xFF - 0xFC )
> + WORD_FIELD_VALID_BIT);
> +  mIgdOpRegion.OpRegion->MBox3.BCLM[2]   = ( ( 10 << 8 ) + ( 0xFF - 0xE5 )
> + WORD_FIELD_VALID_BIT);
> +  mIgdOpRegion.OpRegion->MBox3.BCLM[3]   = ( ( 19 << 8 ) + ( 0xFF - 0xCE )
> + WORD_FIELD_VALID_BIT);
> +  mIgdOpRegion.OpRegion->MBox3.BCLM[4]   = ( ( 28 << 8 ) + ( 0xFF - 0xB7 )
> + WORD_FIELD_VALID_BIT);
> +  mIgdOpRegion.OpRegion->MBox3.BCLM[5]   = ( ( 37 << 8 ) + ( 0xFF - 0xA0 )
> + WORD_FIELD_VALID_BIT);
> +  mIgdOpRegion.OpRegion->MBox3.BCLM[6]   = ( ( 46 << 8 ) + ( 0xFF - 0x89 )
> + WORD_FIELD_VALID_BIT);
> +  mIgdOpRegion.OpRegion->MBox3.BCLM[7]   = ( ( 55 << 8 ) + ( 0xFF - 0x72 )
> + WORD_FIELD_VALID_BIT);
> +  mIgdOpRegion.OpRegion->MBox3.BCLM[8]   = ( ( 64 << 8 ) + ( 0xFF - 0x5B )
> + WORD_FIELD_VALID_BIT);
> +  mIgdOpRegion.OpRegion->MBox3.BCLM[9]   = ( ( 73 << 8 ) + ( 0xFF - 0x44 )
> + WORD_FIELD_VALID_BIT);
> +  mIgdOpRegion.OpRegion->MBox3.BCLM[10]  = ( ( 82 << 8 ) + ( 0xFF - 0x2D )
> + WORD_FIELD_VALID_BIT);
> +  mIgdOpRegion.OpRegion->MBox3.BCLM[11]  = ( ( 91 << 8 ) + ( 0xFF - 0x16 )
> + WORD_FIELD_VALID_BIT);
> +  mIgdOpRegion.OpRegion->MBox3.BCLM[12]  = ( (100 << 8 ) + ( 0xFF - 0x00 )
> + WORD_FIELD_VALID_BIT);
> +
> +  mIgdOpRegion.OpRegion->MBox3.PCFT = ((UINT32) GlobalNvsArea-
> >Area->IgdPowerConservation) | BIT31;
> +  //
> +  // Create the notification and register callback function on the PciIo
> installation,
> +  //
> +  //
> +  Status = gBS->CreateEvent (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_CALLBACK,
> +                  (EFI_EVENT_NOTIFY)GetVBiosVbtCallback,
> +                  NULL,
> +                  &mConOutEvent
> +                  );
> +
> +  ASSERT_EFI_ERROR (Status);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +
> +  }
> +
> +  Status = gBS->RegisterProtocolNotify (
> +#ifdef ECP_FLAG
> +                  &gExitPmAuthProtocolGuid,
> +#else
> +                  &gEfiDxeSmmReadyToLockProtocolGuid,
> +#endif
> +                  mConOutEvent,
> +                  &gConOutNotifyReg
> +                  );
> +
> +  Status = gBS->CreateEvent (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_CALLBACK,
> +                  (EFI_EVENT_NOTIFY)SetGOPVersionCallback,
> +                  NULL,
> +                  &mSetGOPverEvent
> +                  );
> +
> +  ASSERT_EFI_ERROR (Status);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = gBS->RegisterProtocolNotify (
> +                  &gEfiGraphicsOutputProtocolGuid,
> +                  mSetGOPverEvent,
> +                  &gConOutNotifyReg
> +                  );
> +
> +
> +  //
> +  // Initialize hardware state:
> +  //   Set ASLS Register to the OpRegion physical memory address.
> +  //   Set SWSCI register bit 15 to a "1" to activate SCI interrupts.
> +  //
> +
> +  IgdMmPci32 (IGD_ASLS_OFFSET) =
> (UINT32)(UINTN)(mIgdOpRegion.OpRegion);
> +  IgdMmPci16AndThenOr (IGD_SWSCI_OFFSET, ~(BIT0), BIT15);
> +
> +  DwordData = IgdMmPci32 (IGD_ASLS_OFFSET);
> +  S3BootScriptSavePciCfgWrite (
> +    S3BootScriptWidthUint32,
> +    (UINTN) (EFI_PCI_ADDRESS  (IGD_BUS, IGD_DEV, IGD_FUN_0,
> IGD_ASLS_OFFSET)),
> +    1,
> +    &DwordData
> +    );
> +
> +
> +  DwordData = IgdMmPci32 (IGD_SWSCI_OFFSET);
> +  S3BootScriptSavePciCfgWrite (
> +    S3BootScriptWidthUint32,
> +    (UINTN) (EFI_PCI_ADDRESS  (IGD_BUS, IGD_DEV, IGD_FUN_0,
> IGD_SWSCI_OFFSET)),
> +    1,
> +    &DwordData
> +    );
> +
> +  AcpiBase =  MmPci16 (
> +                0,
> +                DEFAULT_PCI_BUS_NUMBER_PCH,
> +                PCI_DEVICE_NUMBER_PCH_LPC,
> +                PCI_FUNCTION_NUMBER_PCH_LPC,
> +                R_PCH_LPC_ACPI_BASE
> +                ) & B_PCH_LPC_ACPI_BASE_BAR;
> +
> +  //
> +  // Find the CPU I/O Protocol.  ASSERT if not found.
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiCpuIoProtocolGuid,
> +                  NULL,
> +                  (void **)&CpuIo
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  CpuIo->Io.Read (
> +              CpuIo,
> +              EfiCpuIoWidthUint16,
> +              AcpiBase + R_PCH_ACPI_GPE0a_STS,
> +              1,
> +              &Data16
> +              );
> +  //
> +  // Clear the B_PCH_ACPI_GPE0a_STS_GUNIT_SCI bit in
> R_PCH_ACPI_GPE0a_STS by writing a '1'.
> +  //
> +  Data16 |= B_PCH_ACPI_GPE0a_STS_GUNIT_SCI;
> +
> +  CpuIo->Io.Write (
> +              CpuIo,
> +              EfiCpuIoWidthUint16,
> +              AcpiBase + R_PCH_ACPI_GPE0a_STS,
> +              1,
> +              &Data16
> +              );
> +
> +  //
> +  // Install OpRegion / Software SCI protocol
> +  //
> +  Handle = NULL;
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &Handle,
> +                  &gIgdOpRegionProtocolGuid,
> +                  &mIgdOpRegion,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Return final status
> +  //
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.h
> b/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.h
> new file mode 100644
> index 0000000000..cd1d208d61
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.h
> @@ -0,0 +1,235 @@
> +
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  IgdOpRegion.h
> +
> +Abstract:
> +
> +  This is part of the implementation of an Intel Graphics drivers OpRegion /
> +  Software SCI interface between system BIOS, ASL code, and Graphics
> drivers.
> +
> +  Supporting Specifiction: OpRegion / Software SCI SPEC 0.70
> +
> +  Acronyms:
> +    IGD:        Internal Graphics Device
> +    NVS:        ACPI Non Volatile Storage
> +    OpRegion:   ACPI Operational Region
> +    VBT:        Video BIOS Table (OEM customizable data)
> +
> +--*/
> +
> +#ifndef _IGD_OPREGION_H_
> +#define _IGD_OPREGION_H_
> +
> +//
> +// Statements that include other header files.
> +//
> +#include "VlvPlatformInit.h"
> +#include "VlvCommonDefinitions.h"
> +#include <Uefi/UefiInternalFormRepresentation.h>
> +#include <FrameworkDxe.h>
> +
> +//
> +//
> +// OpRegion (Miscellaneous) #defines.
> +//
> +// OpRegion Header #defines.
> +//
> +
> +#define HEADER_SIGNATURE    "IntelGraphicsMem"
> +#define HEADER_SIZE         0x2000
> +#define HEADER_OPREGION_VER 0x0200
> +#define HEADER_OPREGION_REV 0x00
> +
> +//
> +//For VLV Tablet, MailBOX2(SCI)is not supported.
> +//
> +#define HEADER_MBOX_SUPPORT (HD_MBOX4 + HD_MBOX3 +
> HD_MBOX1)
> +#define HD_MBOX1            BIT0
> +#define HD_MBOX2            BIT1
> +#define HD_MBOX3            BIT2
> +#define HD_MBOX4            BIT3
> +#define HD_MBOX5            BIT4
> +#define SVER_SIZE           32
> +
> +//
> +//Audio Type support for VLV2 A0
> +//
> +#define AUDIO_TYPE_SUPPORT_MASK    0xFFFFFFF3
> +#define NO_AUDIO_SUPPORT           (0<<2)
> +#define HD_AUDIO_SUPPORT           (1<<2)
> +#define LPE_AUDIO_SUPPORT          (2<<2)
> +#define AUDIO_TYPE_FIELD_MASK      0xFFFFFFEF
> +#define AUDIO_TYPE_FIELD_VALID     (1<<4)
> +#define AUDIO_TYPE_FIELD_INVALID   (0<<4)
> +
> +//
> +// OpRegion Mailbox 1 EQUates.
> +//
> +// OpRegion Mailbox 3 EQUates.
> +//
> +#define ALS_ENABLE            BIT0
> +#define BLC_ENABLE            BIT1
> +#define BACKLIGHT_BRIGHTNESS  0xFF
> +#define FIELD_VALID_BIT       BIT31
> +#define WORD_FIELD_VALID_BIT  BIT15
> +#define PFIT_ENABLE           BIT2
> +#define PFIT_OPRN_AUTO        0x00000000
> +#define PFIT_OPRN_SCALING     0x00000007
> +#define PFIT_OPRN_OFF         0x00000000
> +#define PFIT_SETUP_AUTO       0
> +#define PFIT_SETUP_SCALING    1
> +#define PFIT_SETUP_OFF        2
> +#define INIT_BRIGHT_LEVEL     0x64
> +#define PFIT_STRETCH          6
> +#define PFIT_CENTER           1
> +
> +//
> +// GMCH PCI register access #defines.
> +//
> +
> +#define IgdMmPci32(Register)            MmPci32   (0, IGD_BUS, IGD_DEV,
> IGD_FUN_0, Register)
> +#define IgdMmPci16Or(Register, OrData)  MmPci16Or (0, IGD_BUS,
> IGD_DEV, IGD_FUN_0, Register, OrData)
> +#define IgdMmPci16AndThenOr(Register,AndData,OrData)
> MmPci16AndThenOr (0, IGD_BUS, IGD_DEV, IGD_FUN_0, Register, AndData,
> OrData)
> +
> +//
> +// Video BIOS / VBT #defines
> +//
> +#define IGD_DID_VLV             0x0F31
> +#define OPTION_ROM_SIGNATURE    0xAA55
> +#define VBIOS_LOCATION_PRIMARY  0xC0000
> +
> +#define VBT_SIGNATURE           SIGNATURE_32 ('$', 'V', 'B', 'T')
> +
> +//
> +// Typedef stuctures
> +//
> +#pragma pack (1)
> +typedef struct {
> +  UINT16  Signature;    // 0xAA55
> +  UINT8   Size512;
> +  UINT8   Reserved[21];
> +  UINT16  PcirOffset;
> +  UINT16  VbtOffset;
> +} INTEL_VBIOS_OPTION_ROM_HEADER;
> +#pragma pack ()
> +
> +#pragma pack (1)
> +typedef struct {
> +  UINT32  Signature;  // "PCIR"
> +  UINT16  VendorId;   // 0x8086
> +  UINT16  DeviceId;
> +  UINT16  Reserved0;
> +  UINT16  Length;
> +  UINT8   Revision;
> +  UINT8   ClassCode[3];
> +  UINT16  ImageLength;
> +  UINT16  CodeRevision;
> +  UINT8   CodeType;
> +  UINT8   Indicator;
> +  UINT16  Reserved1;
> +} INTEL_VBIOS_PCIR_STRUCTURE;
> +#pragma pack ()
> +
> +#pragma pack (1)
> +typedef struct {
> +  UINT8   HeaderSignature[20];
> +  UINT16  HeaderVersion;
> +  UINT16  HeaderSize;
> +  UINT16  HeaderVbtSize;
> +  UINT8   HeaderVbtCheckSum;
> +  UINT8   HeaderReserved;
> +  UINT32  HeaderOffsetVbtDataBlock;
> +  UINT32  HeaderOffsetAim1;
> +  UINT32  HeaderOffsetAim2;
> +  UINT32  HeaderOffsetAim3;
> +  UINT32  HeaderOffsetAim4;
> +  UINT8   DataHeaderSignature[16];
> +  UINT16  DataHeaderVersion;
> +  UINT16  DataHeaderSize;
> +  UINT16  DataHeaderDataBlockSize;
> +  UINT8   CoreBlockId;
> +  UINT16  CoreBlockSize;
> +  UINT16  CoreBlockBiosSize;
> +  UINT8   CoreBlockBiosType;
> +  UINT8   CoreBlockReleaseStatus;
> +  UINT8   CoreBlockHWSupported;
> +  UINT8   CoreBlockIntegratedHW;
> +  UINT8   CoreBlockBiosBuild[4];
> +  UINT8   CoreBlockBiosSignOn[155];
> +} VBIOS_VBT_STRUCTURE;
> +#pragma pack ()
> +
> +//
> +// Driver Private Function definitions
> +//
> +EFI_STATUS
> +GetSVER (
> +  OUT UINT8 *SVER
> +  );
> +
> +/**
> +  Acquire the string associated with the ProducerGuid and return it.
> +
> +  @param ProducerGuid  The Guid to search the HII database for
> +  @param Token         The token value of the string to extract
> +  @param String        The string that is extracted
> +
> +  @retval EFI_SUCCESS       The function completed successfully
> +  @retval EFI_NOT_FOUND     The requested string was not found
> +
> +**/
> +EFI_STATUS
> +GetStringFromToken (
> +  IN      EFI_GUID                  *ProducerGuid,
> +  IN      STRING_REF                Token,
> +  OUT     CHAR16                    **String
> +  );
> +
> +/**
> +
> +  Graphics OpRegion / Software SCI driver installation function.
> +
> +  @param Void
> +
> +  @retval EFI_SUCCESS     The driver installed without error.
> +  @retval EFI_ABORTED     The driver encountered an error and could not
> complete
> +                          installation of the ACPI tables.
> +**/
> +EFI_STATUS
> +IgdOpRegionInit (
> +  void
> +  );
> +
> +/**
> +  Extract information pertaining to the HiiHandle
> +
> +  @param HiiHandle        Hii handle
> +  @param ImageLength      For input, length of DefaultImage;
> +                          For output, length of actually required
> +
> +  @param DefaultImage     Image buffer prepared by caller
> +  @param Guid             Guid information about the form
> +
> +  @retval EFI_OUT_OF_RESOURCES     No enough buffer to allocate
> +  @retval EFI_BUFFER_TOO_SMALL     DefualtImage has no enough
> ImageLength
> +  @retval EFI_SUCCESS              Successfully extract data from Hii database.
> +
> +**/
> +EFI_STATUS
> +ExtractDataFromHiiHandle (
> +  IN      EFI_HII_HANDLE      HiiHandle,
> +  IN OUT  UINT16              *ImageLength,
> +  OUT     UINT8               *DefaultImage,
> +  OUT     EFI_GUID            *Guid
> +  );
> +#endif
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.c
> b/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.c
> new file mode 100644
> index 0000000000..75675fbf00
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.c
> @@ -0,0 +1,287 @@
> +
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  VlvPlatformInit.c
> +
> +Abstract:
> +
> +  This is the driver that initializes the Intel ValleyView.
> +
> +--*/
> +
> +#include "VlvPlatformInit.h"
> +#include <Protocol/VlvPlatformPolicy.h>
> +
> +extern DXE_VLV_PLATFORM_POLICY_PROTOCOL  *DxePlatformSaPolicy;
> +UINT64            GTTMMADR;
> +
> +DXE_VLV_PLATFORM_POLICY_PROTOCOL  *DxePlatformSaPolicy;
> +
> +/**
> +  "Poll Status" for GT Readiness
> +
> + @param  Base             Base address of MMIO
> + @param  Offset           MMIO Offset
> + @param  Mask             Mask
> + @param  Result           Value to wait for
> +
> + @retval None
> +
> +**/
> +VOID
> +PollGtReady_hang (
> +  UINT64 Base,
> +  UINT32 Offset,
> +  UINT32 Mask,
> +  UINT32 Result
> +  )
> +{
> +  UINT32  GtStatus;
> +
> +  //
> +  // Register read
> +  //
> +  GtStatus = MmioRead32 ((UINTN)Base+ Offset);
> +
> +  while (((GtStatus & Mask) != Result)) {
> +
> +    GtStatus = MmioRead32 ((UINTN)Base + Offset);
> +  }
> +
> +}
> +
> +/**
> +  Do Post GT PM Init Steps after VBIOS Initialization.
> +
> +  @param Event             A pointer to the Event that triggered the callback.
> +  @param Context           A pointer to private data registered with the callback
> function.
> +
> +  @retval EFI_SUCCESS        GC_TODO
> +
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +PostPmInitCallBack (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  )
> +{
> +  UINT64      OriginalGTTMMADR;
> +  UINT32      LoGTBaseAddress;
> +  UINT32      HiGTBaseAddress;
> +
> +  //
> +  // Enable Bus Master, I/O and Memory access on 0:2:0
> +  //
> +  PciOr8 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_CMD), (BIT2 | BIT1));
> +
> +  //
> +  // only 32bit read/write is legal for device 0:2:0
> +  //
> +  OriginalGTTMMADR  = (UINT64) PciRead32 (PCI_LIB_ADDRESS(0, IGD_DEV,
> 0,IGD_R_GTTMMADR));
> +  OriginalGTTMMADR  = LShiftU64 ((UINT64) PciRead32 (PCI_LIB_ADDRESS(0,
> IGD_DEV, 0,IGD_R_GTTMMADR + 4)), 32) | (OriginalGTTMMADR);
> +
> +  //
> +  // 64bit GTTMADR does not work for S3 save script table since it is
> executed in PEIM phase
> +  // Program temporarily 32bits GTTMMADR for POST and S3 resume
> +  //
> +  LoGTBaseAddress                   = (UINT32) (GTTMMADR & 0xFFFFFFFF);
> +  HiGTBaseAddress                   = (UINT32) RShiftU64 ((GTTMMADR &
> 0xFFFFFFFF00000000), 32);
> +  S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR),
> LoGTBaseAddress);
> +  S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR+4),
> HiGTBaseAddress);
> +
> +
> +
> +  //
> +  // Restore original GTTMMADR
> +  //
> +  LoGTBaseAddress                   = (UINT32) (OriginalGTTMMADR & 0xFFFFFFFF);
> +  HiGTBaseAddress                   = (UINT32) RShiftU64 ((OriginalGTTMMADR &
> 0xFFFFFFFF00000000), 32);
> +
> +  S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR),
> LoGTBaseAddress);
> +  S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR+4),
> HiGTBaseAddress);
> +
> +
> +  //
> +  // Lock the following registers, GGC, BDSM, BGSM
> +  //
> +  PciOr32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_MGGC_OFFSET), LockBit);
> +  PciOr32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_BSM_OFFSET), LockBit);
> +  PciOr32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_BGSM), LockBit);
> +
> +  gBS->CloseEvent (Event);
> +
> +  //
> +  // Return final status
> +  //
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +  Routine Description:
> +
> +  Initialize GT Post Routines.
> +
> +  @param ImageHandle              Handle for the image of this driver
> +  @param DxePlatformSaPolicy      SA DxePlatformPolicy protocol
> +
> +  @retval EFI_SUCCESS             GT POST initialization complete
> +
> +**/
> +EFI_STATUS
> +IgdPmHook (
> +  IN EFI_HANDLE                      ImageHandle,
> +  IN DXE_VLV_PLATFORM_POLICY_PROTOCOL *DxePlatformSaPolicyParam
> +  )
> +{
> +
> +  EFI_EVENT             mConOutEvent;
> +  VOID                  *gConOutNotifyReg;
> +
> +  EFI_STATUS            Status;
> +
> +  EFI_PHYSICAL_ADDRESS  MemBaseAddress;
> +  UINT32                LoGTBaseAddress;
> +  UINT32                HiGTBaseAddress;
> +
> +  GTTMMADR    = 0;
> +  Status      = EFI_SUCCESS;
> +
> +  //
> +  // If device 0:2:0 (Internal Graphics Device, or GT) is enabled, then Program
> GTTMMADR,
> +  //
> +  if (PciRead16(PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_VID))  != 0xFFFF) {
> +
> +    ASSERT (gDS!=NULL);
> +
> +    //
> +    // Enable Bus Master, I/O and Memory access on 0:2:0
> +    //
> +    PciOr8(PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_CMD), (BIT2 | BIT1 |
> BIT0));
> +
> +    //
> +    // Means Allocate 4MB for GTTMADDR
> +    //
> +    MemBaseAddress = 0x0ffffffff;
> +
> +    Status = gDS->AllocateMemorySpace (
> +                    EfiGcdAllocateMaxAddressSearchBottomUp,
> +                    EfiGcdMemoryTypeMemoryMappedIo,
> +                    GTT_MEM_ALIGN,
> +                    GTTMMADR_SIZE_4MB,
> +                    &MemBaseAddress,
> +                    ImageHandle,
> +                    NULL
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    //
> +    // Program GT PM Settings if GTTMMADR allocation is Successful
> +    //
> +    GTTMMADR                          = (UINTN) MemBaseAddress;
> +
> +    LoGTBaseAddress                   = (UINT32) (MemBaseAddress & 0xFFFFFFFF);
> +    HiGTBaseAddress                   = (UINT32) RShiftU64 ((MemBaseAddress &
> 0xFFFFFFFF00000000), 32);
> +
> +    PciWrite32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_GTTMMADR),
> LoGTBaseAddress);
> +    PciWrite32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_GTTMMADR+4),
> HiGTBaseAddress);
> +
> +
> +    S3PciRead32(PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_GTTMMADR));
> +
> +
> +    S3MmioRead32(IGD_R_GTTMMADR + 4);
> +
> +
> +    S3PciRead8(PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_CMD));
> +
> +    //
> +    // Do POST GT PM Init Steps after VBIOS Initialization in
> DoPostPmInitCallBack
> +    //
> +    Status = gBS->CreateEvent (
> +                    EVT_NOTIFY_SIGNAL,
> +                    TPL_CALLBACK,
> +                    (EFI_EVENT_NOTIFY)PostPmInitCallBack,
> +                    NULL,
> +                    &mConOutEvent
> +                    );
> +
> +    ASSERT_EFI_ERROR (Status);
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +
> +
> +    Status = gBS->RegisterProtocolNotify (
> +                    &gEfiGraphicsOutputProtocolGuid,
> +                    mConOutEvent,
> +                    &gConOutNotifyReg
> +                    );
> +
> +
> +
> +    MmioWrite64 (IGD_R_GTTMMADR, 0);
> +
> +    //
> +    // Free allocated resources
> +    //
> +    gDS->FreeMemorySpace (
> +           MemBaseAddress,
> +           GTTMMADR_SIZE_4MB
> +           );
> +
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +  This is the standard EFI driver point that detects
> +  whether there is an ICH southbridge in the system
> +  and if so, initializes the chip.
> +
> +  @param  ImageHandle             Handle for the image of this driver
> +  @param  SystemTable             Pointer to the EFI System Table
> +
> +  @retval EFI_SUCCESS             The function completed successfully
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VlvPlatformInitEntryPoint (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_STATUS                        Status;
> +
> +  Status = gBS->LocateProtocol (&gDxeVlvPlatformPolicyGuid, NULL, (void
> **)&DxePlatformSaPolicy);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // GtPostInit Initialization
> +  //
> +  DEBUG ((EFI_D_ERROR, "Initializing GT PowerManagement and other GT
> POST related\n"));
> +  IgdPmHook (ImageHandle, DxePlatformSaPolicy);
> +
> +  //
> +  // IgdOpRegion Install Initialization
> +  //
> +  DEBUG ((EFI_D_ERROR, "Initializing IGD OpRegion\n"));
> +  IgdOpRegionInit ();
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.h
> b/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.h
> new file mode 100644
> index 0000000000..5caf54bb8a
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.h
> @@ -0,0 +1,65 @@
> +
> +/*++
> +
> +Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +  VlvPlatformInit.h
> +
> +Abstract:
> +
> +  Header file for SA Initialization Driver.
> +
> +--*/
> +
> +#ifndef _VLV_PLATFORM_INIT_DXE_H_
> +#define _VLV_PLATFORM_INIT_DXE_H_
> +#include "PiDxe.h"
> +
> +#include <Protocol/VlvPlatformPolicy.h>
> +
> +#include "IgdOpRegion.h"
> +
> +#include <Library/DxeServicesTableLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +#include "Library/DebugLib.h"
> +#include "Library/S3IoLib.h"
> +#include "Library/S3PciLib.h"
> +#include "Library/IoLib.h"
> +#include "Library/PciLib.h"
> +#include "Library/S3BootScriptLib.h"
> +
> +//
> +// GT RELATED EQUATES
> +//
> +#define GTT_MEM_ALIGN        22
> +#define GTTMMADR_SIZE_4MB    0x400000
> +
> +#define IGD_BUS             0x00
> +#define IGD_DEV                  0x02
> +#define IGD_FUN_0                0x00
> +
> +#define IGD_R_VID                0x00
> +#define IGD_R_CMD                0x04
> +#define IGD_R_GTTMMADR           0x10
> +
> +#define IGD_R_BGSM               0x70
> +#define LockBit                  BIT0
> +
> +#define IGD_VID             0x8086
> +#define IGD_DID             0xA001
> +#define IGD_MGGC_OFFSET     0x0050      //GMCH Graphics Control Register
> 0x50
> +#define IGD_BSM_OFFSET      0x005C      //Base of Stolen Memory
> +#define IGD_SWSCI_OFFSET    0x00E0      //Software SCI 0xE0 2
> +#define IGD_ASLE_OFFSET     0x00E4      //System Display Event Register
> 0xE4 4
> +#define IGD_ASLS_OFFSET     0x00FC      // ASL Storage
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInitDxe.i
> nf
> b/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInitDxe.i
> nf
> new file mode 100644
> index 0000000000..9d277dd7cf
> --- /dev/null
> +++
> b/Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInitDxe.i
> nf
> @@ -0,0 +1,74 @@
> +#
> +#
> +#/*++
> +#
> +#  Copyright (c)  1999  - 2018, Intel Corporation. All rights reserved
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +#
> +#  Module Name:
> +#
> +#    VlvPlatformInit.inf
> +#
> +#  Abstract:
> +#
> +#    Component description file for wrapper driver of Vlv platform init part.
> +#
> +#--*/
> +
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = VlvPlatformInitDxe
> +  FILE_GUID                      = 1EC0EFC9-C93A-4b62-9B27-C059ABD80E92
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = VlvPlatformInitEntryPoint
> +
> +[Sources]
> +  VlvPlatformInit.c
> +  IgdOpRegion.c
> +
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  IntelFrameworkPkg/IntelFrameworkPkg.dec
> +  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +
> +[LibraryClasses]
> +  UefiDriverEntryPoint
> +  DebugLib
> +  UefiBootServicesTableLib
> +  S3BootScriptLib
> +  DxeServicesTableLib
> +  PchPlatformLib
> +  S3PciLib
> +  S3IoLib
> +  PciLib
> +  IoLib
> +
> +[Guids]
> +  gBmpImageGuid
> +  gEfiDxeServicesTableGuid
> +
> +[Protocols]
> +  gDxeVlvPlatformPolicyGuid
> +  gEfiDxeSmmReadyToLockProtocolGuid
> +  gIgdOpRegionProtocolGuid
> +  gEfiGlobalNvsAreaProtocolGuid
> +  gEfiPciIoProtocolGuid
> +  gEfiFirmwareVolume2ProtocolGuid
> +  gEfiCpuIoProtocolGuid
> +
> +[Depex]
> +  gDxeVlvPlatformPolicyGuid              AND
> +  gEfiPciRootBridgeIoProtocolGuid     AND
> +  gEfiCpuIoProtocolGuid                      AND
> +  gEfiDataHubProtocolGuid                 AND
> +  gEfiGlobalNvsAreaProtocolGuid       AND
> +  gEfiFirmwareVolume2ProtocolGuid   AND
> +  gEfiHiiDatabaseProtocolGuid
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.c
> new file mode 100644
> index 0000000000..f98265761b
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.c
> @@ -0,0 +1,340 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +
> +Module Name:
> +
> +    LpcDriver.c
> +
> +Abstract:
> +
> +    EFI Lpc Driver for a Generic PC Platform
> +
> +
> +
> +--*/
> +
> +#include "LpcDriver.h"
> +#include "IndustryStandard/Pci22.h"
> +
> +//
> +// This driver is for ACPI(PNP0A03,0)/PCI(0x1f,0)
> +//
> +
> +//
> +//  Lpc Driver Global Variables
> +//
> +
> +EFI_DRIVER_BINDING_PROTOCOL gLpcDriver = {
> +  LpcDriverSupported,
> +  LpcDriverStart,
> +  LpcDriverStop,
> +  0x10,
> +  NULL,
> +  NULL
> +};
> +
> +LPC_DEV mLpc = {
> +  LPC_DEV_SIGNATURE,
> +  NULL,
> +  {
> +    IsaDeviceEnumerate,
> +    IsaDeviceSetPower,
> +    IsaGetCurrentResource,
> +    IsaGetPossibleResource,
> +    IsaSetResource,
> +    IsaEnableDevice,
> +    IsaInitDevice,
> +    LpcInterfaceInit
> +  },
> +  NULL
> +};
> +
> +BOOLEAN  InitExecuted = FALSE;
> +
> +/**
> +    the entry point of the Lpc driver
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +LpcDriverEntryPoint(
> +  IN EFI_HANDLE           ImageHandle,
> +  IN EFI_SYSTEM_TABLE     *SystemTable
> +  )
> +{
> +
> +
> +  return EfiLibInstallDriverBinding (ImageHandle, SystemTable, &gLpcDriver,
> ImageHandle);
> +}
> +
> +/**
> +
> +  ControllerDriver Protocol Method
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +LpcDriverSupported (
> +  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
> +  IN EFI_HANDLE                     Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
> +  )
> +{
> +  EFI_STATUS                Status;
> +  EFI_PCI_IO_PROTOCOL       *PciIo;
> +  EFI_DEVICE_PATH_PROTOCOL  *IsaBridgeDevicePath;
> +
> +  ACPI_HID_DEVICE_PATH      *AcpiNode;
> +  PCI_DEVICE_PATH           *PciNode;
> +  PCI_TYPE00                Pci;
> +
> +  //
> +  // Get the ISA bridge's Device Path and test it
> +  // the following code is specific
> +  //
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiDevicePathProtocolGuid,
> +                  (VOID **)&IsaBridgeDevicePath,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = EFI_SUCCESS;
> +  AcpiNode =  (ACPI_HID_DEVICE_PATH *)IsaBridgeDevicePath;
> +  if (AcpiNode->Header.Type != ACPI_DEVICE_PATH ||
> +      AcpiNode->Header.SubType != ACPI_DP ||
> +      DevicePathNodeLength (&AcpiNode->Header) !=
> sizeof(ACPI_HID_DEVICE_PATH) ||
> +      AcpiNode -> HID != EISA_PNP_ID(0x0A03) ||
> +      AcpiNode -> UID != 0 ) {
> +    Status = EFI_UNSUPPORTED;
> +  } else {
> +    //
> +    // Get the next node
> +    //
> +    IsaBridgeDevicePath = NextDevicePathNode (IsaBridgeDevicePath);
> +    PciNode  = (PCI_DEVICE_PATH *)IsaBridgeDevicePath;
> +    if (PciNode->Header.Type != HARDWARE_DEVICE_PATH ||
> +        PciNode->Header.SubType != HW_PCI_DP ||
> +        DevicePathNodeLength (&PciNode->Header) != sizeof
> (PCI_DEVICE_PATH) ||
> +        PciNode -> Function != 0x00 ||
> +        PciNode -> Device != 0x1f ) {
> +      Status = EFI_UNSUPPORTED;
> +    }
> +  }
> +
> +  gBS->CloseProtocol (
> +         Controller,
> +         &gEfiDevicePathProtocolGuid,
> +         This->DriverBindingHandle,
> +         Controller
> +         );
> +
> +  if (EFI_ERROR (Status)) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Get PciIo protocol instance
> +  //
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiPciIoProtocolGuid,
> +                  (VOID **)&PciIo,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +
> +  if (EFI_ERROR(Status)) {
> +    return Status;
> +  }
> +
> +  Status = PciIo->Pci.Read (
> +                        PciIo,
> +                        EfiPciIoWidthUint32,
> +                        0,
> +                        sizeof(Pci) / sizeof(UINT32),
> +                        &Pci
> +                        );
> +
> +  if (!EFI_ERROR (Status)) {
> +    Status = EFI_SUCCESS; //TODO: force return success as temp solution
> EFI_UNSUPPORTED;
> +    if ((Pci.Hdr.Command & 0x03) == 0x03) {
> +      if (Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) {
> +        //
> +        // See if this is a standard PCI to ISA Bridge from the Base Code
> +        // and Class Code
> +        //
> +        if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA) {
> +          Status = EFI_SUCCESS;
> +        } else {
> +        }
> +
> +        //
> +        // See if this is an Intel PCI to ISA bridge in Positive Decode Mode
> +        //
> +        if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA_PDECODE &&
> +            Pci.Hdr.VendorId == 0x8086 &&
> +            Pci.Hdr.DeviceId == 0x7110) {
> +          Status = EFI_SUCCESS;
> +        } else {
> +        }
> +      } else {
> +      }
> +    }
> +    else {
> +    }
> +  }
> +
> +  gBS->CloseProtocol (
> +         Controller,
> +         &gEfiPciIoProtocolGuid,
> +         This->DriverBindingHandle,
> +         Controller
> +         );
> +  return Status;
> +}
> +
> +
> +/**
> +  Install EFI_ISA_ACPI_PROTOCOL
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +LpcDriverStart (
> +  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
> +  IN EFI_HANDLE                     Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
> +  )
> +{
> +  EFI_STATUS             Status;
> +  EFI_PCI_IO_PROTOCOL    *PciIo;
> +
> +  //
> +  // Get Pci IO
> +  //
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiPciIoProtocolGuid,
> +                  (VOID **)&PciIo,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +
> +  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
> +    return Status;
> +  }
> +
> +  mLpc.PciIo = PciIo;
> +
> +  //
> +  // Install IsaAcpi interface, the Sio interface is not installed!
> +  //
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &Controller,
> +                  &gEfiIsaAcpiProtocolGuid,
> +                  &mLpc.IsaAcpi,
> +                  NULL
> +                  );
> +  return Status;
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +LpcDriverStop (
> +  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,
> +  IN  EFI_HANDLE                     Controller,
> +  IN  UINTN                          NumberOfChildren,
> +  IN  EFI_HANDLE                     *ChildHandleBuffer
> +  )
> +{
> +  EFI_STATUS             Status;
> +  EFI_ISA_ACPI_PROTOCOL  *IsaAcpi;
> +  LPC_DEV                *LpcDev;
> +
> +  //
> +  // Get EFI_ISA_ACPI_PROTOCOL interface
> +  //
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiIsaAcpiProtocolGuid,
> +                  (VOID **)&IsaAcpi,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  LpcDev = LPC_ISA_ACPI_FROM_THIS (IsaAcpi);
> +
> +  //
> +  // Uninstall protocol interface: EFI_ISA_ACPI_PROTOCOL
> +  //
> +  Status = gBS->UninstallProtocolInterface (
> +                  Controller,
> +                  &gEfiIsaAcpiProtocolGuid,
> +                  &LpcDev->IsaAcpi
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  gBS->CloseProtocol (
> +         Controller,
> +         &gEfiPciIoProtocolGuid,
> +         This->DriverBindingHandle,
> +         Controller
> +         );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +VOID
> +LpcIoRead8 (
> +  IN  UINT16  Port,
> +  OUT UINT8   *Data
> +  )
> +{
> +  mLpc.PciIo->Io.Read(
> +                   mLpc.PciIo,
> +                   EfiPciWidthUint8,
> +                   EFI_PCI_IO_PASS_THROUGH_BAR,
> +                   Port,
> +                   1,
> +                   Data
> +                   );
> +}
> +
> +VOID
> +LpcIoWrite8 (
> +  IN  UINT16  Port,
> +  IN  UINT8   Data
> +  )
> +{
> +  mLpc.PciIo->Io.Write(
> +                   mLpc.PciIo,
> +                   EfiPciWidthUint8,
> +                   EFI_PCI_IO_PASS_THROUGH_BAR,
> +                   Port,
> +                   1,
> +                   &Data
> +                   );
> +}
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.h
> new file mode 100644
> index 0000000000..5e264485e7
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.h
> @@ -0,0 +1,112 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +    LpcDriver.h
> +
> +Abstract:
> +
> +    EFI Lpc Driver for a Generic PC Platform
> +
> +
> +
> +--*/
> +
> +#ifndef _LPC_DRIVER_H
> +#define _LPC_DRIVER_H
> +
> + #include "LpcSio.h"
> + #include "LpcIsaAcpi.h"
> +
> +#include "Protocol/IsaAcpi.h"
> +#include "Protocol/PciIo.h"
> +#include "Protocol/DriverBinding.h"
> +#include "Library/UefiBootServicesTableLib.h"
> +#include "IsaAcpiDxe/PcatIsaAcpi.h"
> +#include "IndustryStandard/Pci22.h"
> +#include "Protocol/LpcWpce791Policy.h"
> +
> +#include <Library/DebugLib.h>
> +
> +#define ICH_LPC_BRIDGE_BUS_DEV_FUNC 0x1F0000
> +
> +//
> +// LPC device private data structure
> +//
> +//#define LPC_DEV_SIGNATURE 'W87X'
> +#define LPC_DEV_SIGNATURE SIGNATURE_32('X', '7', '8', 'W') //'W87X'
> +#define EFI_WPCE791_PS2_KEYBOARD_ENABLE       0x01
> +#define EFI_WPCE791_PS2_KEYBOARD_DISABLE      0x00
> +
> +#define EFI_WPCE791_PS2_MOUSE_ENABLE       0x01
> +#define EFI_WPCE791_PS2_MOUSE_DISABLE      0x00
> +
> +
> +
> +typedef struct {
> +  UINTN                 Signature;
> +  EFI_HANDLE            Handle;
> +  EFI_ISA_ACPI_PROTOCOL IsaAcpi;
> +  EFI_PCI_IO_PROTOCOL   *PciIo;
> +
> +} LPC_DEV;
> +
> +#define LPC_ISA_ACPI_FROM_THIS(a) BASE_CR (a, LPC_DEV, IsaAcpi)
> +
> +//
> +// Driver entry point
> +//
> +EFI_STATUS
> +EFIAPI
> +LpcDriverEntryPoint (
> +  IN EFI_HANDLE           ImageHandle,
> +  IN EFI_SYSTEM_TABLE     *SystemTable
> +  );
> +
> +//
> +// Prototypes for Driver model protocol interface
> +//
> +EFI_STATUS
> +EFIAPI
> +LpcDriverSupported (
> +  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
> +  IN EFI_HANDLE                     Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +LpcDriverStart (
> +  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
> +  IN EFI_HANDLE                     Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +LpcDriverStop (
> +  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,
> +  IN  EFI_HANDLE                     Controller,
> +  IN  UINTN                          NumberOfChildren,
> +  IN  EFI_HANDLE                     *ChildHandleBuffer
> +  );
> +
> +VOID
> +LpcIoRead8 (
> +  IN  UINT16  Port,
> +  OUT UINT8   *Data
> +  );
> +
> +VOID
> +LpcIoWrite8 (
> +  IN  UINT16  Port,
> +  IN  UINT8   Data
> +  );
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c
> new file mode 100644
> index 0000000000..9c0b79b15c
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c
> @@ -0,0 +1,366 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +    LpcIsaAcpi.c
> +
> +Abstract: IsaAcpi implementation
> +
> +
> +
> +--*/
> +
> +#include "LpcDriver.h"
> +
> +//
> +// PS/2 Keyboard Controller
> +//
> +static EFI_ISA_ACPI_RESOURCE
> mLpcWpce791Ps2KeyboardDeviceResources[] = {
> +  {EfiIsaAcpiResourceIo,        0, 0x60, 0x64},
> +  {EfiIsaAcpiResourceInterrupt, 0, 1,     0},
> +  {EfiIsaAcpiResourceEndOfList, 0, 0,     0}
> +};
> +
> +//
> +// PS/2 Mouse Controller
> +//
> +static EFI_ISA_ACPI_RESOURCE  mLpcWpce791Ps2MouseDeviceResources[]
> = {
> +  {EfiIsaAcpiResourceIo,        0, 0x60, 0x64},
> +  {EfiIsaAcpiResourceInterrupt, 0, 12,     0},
> +  {EfiIsaAcpiResourceEndOfList, 0, 0,     0}
> +};
> +
> +//
> +// COM
> +//
> +static EFI_ISA_ACPI_RESOURCE  mLpcWpce791ComDeviceResources[] = {
> +  {EfiIsaAcpiResourceIo,        0, 0x3f8, 0x3ff},
> +  {EfiIsaAcpiResourceInterrupt, 0, 4,     0},
> +  {EfiIsaAcpiResourceEndOfList, 0, 0,     0}
> +};
> +
> +//
> +// Table of ISA Controllers
> +//
> +EFI_ISA_ACPI_RESOURCE_LIST mLpcWpce791DeviceList[] = {
> +  {{EISA_PNP_ID(0x303), 0}, mLpcWpce791Ps2KeyboardDeviceResources },
> // PS/2 Keyboard Controller
> +  {{EISA_PNP_ID(0xF03), 0}, mLpcWpce791Ps2MouseDeviceResources
> 	  }, // PS/2 Mouse Controller
> +  {{EISA_PNP_ID(0x501), 0}, mLpcWpce791ComDeviceResources	      },
> // COM
> +  {{0,                  0}, NULL                                  }  // End
> +};
> +
> +static ICH_DMA_INIT  mIchDmaInitTable [] = {
> +//
> +//Register OFFSET,           Value
> +//
> +
> +            0x0D8,           0x000,   // Reset DMA Controller 2
> +            0x0D0,           0x000,   // Enable DMA controller 2
> +            0x00C,           0x000,   // Reset DMA Controller 1
> +            0x008,           0x000,   // Enable DMA controller 1
> +
> +            //
> +            // Channel 4
> +            //
> +            0x0D6,           0x0c0,   // DMA contr. 2 Cascade mode, addr. increment,
> disable auto init.
> +            0x0D2,           0x000,   // Clear write request register
> +            0x0d4,           0x000,   // Enable DREQs for channel
> +
> +            //
> +            // Channel 0
> +            //
> +            0x00B,           0x040,   // DMA contr. 1 single mode, addr. increment,
> disable auto init.
> +            0x009,           0x000,   // Clear write request register
> +            0x00A,           0x000,   // Enable DREQs for channel
> +
> +            //
> +            // Channel 1
> +            //
> +            0x00B,           0x041,   // DMA contr. 1 single mode, addr. increment,
> disable auto init.
> +            0x009,           0x001,   // Clear write request register
> +            0x00A,           0x001,   // Enable DREQs for channel
> +
> +            //
> +            // Channel 2
> +            //
> +            0x00B,           0x042,   // DMA contr. 1 single mode, addr. increment,
> disable auto init.
> +            0x009,           0x002,   // Clear write request register
> +            0x00A,           0x002,   // Enable DREQs for channel
> +
> +            //
> +            // Channel 3
> +            //
> +            0x00B,           0x043,   // DMA contr. 1 single mode, addr. increment,
> disable auto init.
> +            0x009,           0x003,   // Clear write request register
> +            0x00A,           0x003,   // Enable DREQs for channel
> +
> +            //
> +            // Channel 5
> +            //
> +            0x0D6,           0x041,   // DMA contr. 2 single mode, addr. increment,
> disable auto init.
> +            0x0D2,           0x001,   // Clear write request register
> +            0x0D4,           0x001,   // Enable DREQs for channel
> +
> +            //
> +            // Channel 6
> +            //
> +            0x0D6,           0x042,   // DMA contr. 2 single mode, addr. increment,
> disable auto init.
> +            0x0D2,           0x002,   // Clear write request register
> +            0x0D4,           0x002,   // Enable DREQs for channel
> +
> +            //
> +            // Channel 7
> +            //
> +            0x0D6,           0x043,   // DMA contr. 2 single mode, addr. increment,
> disable auto init.
> +            0x0D2,           0x003,   // Clear write request register
> +            0x0D4,           0x003    // Enable DREQs for channel
> +
> +};
> +
> +//
> +// ISA ACPI Protocol Functions
> +//
> +/**
> +
> +  Enumerate the ISA devices on the ISA bus
> +
> +**/
> +VOID
> +IsaDeviceLookup (
> +  IN  EFI_ISA_ACPI_DEVICE_ID      *Device,
> +  OUT EFI_ISA_ACPI_RESOURCE_LIST  **IsaAcpiDevice,
> +  OUT EFI_ISA_ACPI_RESOURCE_LIST  **NextIsaAcpiDevice
> +  )
> +{
> +  UINTN  Index;
> +
> +  *IsaAcpiDevice = NULL;
> +  if (NextIsaAcpiDevice != NULL) {
> +    *NextIsaAcpiDevice = NULL;
> +  }
> +  if (Device == NULL) {
> +    Index = 0;
> +  } else {
> +    for(Index = 0; mLpcWpce791DeviceList[Index].Device.HID != 0; Index++) {
> +      if (Device->HID == mLpcWpce791DeviceList[Index].Device.HID &&
> +          Device->UID == mLpcWpce791DeviceList[Index].Device.UID    ) {
> +        break;
> +      }
> +    }
> +    if (mLpcWpce791DeviceList[Index].Device.HID == 0) {
> +      return;
> +    }
> +    *IsaAcpiDevice = &(mLpcWpce791DeviceList[Index]);
> +    Index++;
> +  }
> +  if (NextIsaAcpiDevice != NULL &&
> mLpcWpce791DeviceList[Index].Device.HID != 0){
> +    *NextIsaAcpiDevice = &(mLpcWpce791DeviceList[Index]);
> +  }
> +}
> +
> +
> +/**
> +  Enumerate the ISA devices on the ISA bus
> +  It is hard code now and future it will get from ACPI table
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +IsaDeviceEnumerate (
> +  IN     EFI_ISA_ACPI_PROTOCOL       *This,
> +  OUT    EFI_ISA_ACPI_DEVICE_ID      **Device
> +  )
> +{
> +  EFI_ISA_ACPI_RESOURCE_LIST  *IsaAcpiDevice;
> +  EFI_ISA_ACPI_RESOURCE_LIST  *NextIsaAcpiDevice;
> +
> +  IsaDeviceLookup (*Device, &IsaAcpiDevice, &NextIsaAcpiDevice);
> +  if (NextIsaAcpiDevice == NULL) {
> +    return EFI_NOT_FOUND;
> +  }
> +  *Device = &(NextIsaAcpiDevice->Device);
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Set ISA device power use sio
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +IsaDeviceSetPower (
> +  IN     EFI_ISA_ACPI_PROTOCOL       *This,
> +  IN     EFI_ISA_ACPI_DEVICE_ID      *Device,
> +  IN     BOOLEAN                     OnOff
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +
> +/**
> +  Get current Resource of the specific ISA device
> +  It is hardcode now and future will get from ACPI table
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +IsaGetCurrentResource (
> +  IN     EFI_ISA_ACPI_PROTOCOL        *This,
> +  IN     EFI_ISA_ACPI_DEVICE_ID       *Device,
> +  OUT    EFI_ISA_ACPI_RESOURCE_LIST   **ResourceList
> +  )
> +{
> +  IsaDeviceLookup (Device, ResourceList, NULL);
> +  if (*ResourceList == NULL || (*ResourceList)->ResourceItem == NULL) {
> +    return EFI_NOT_FOUND;
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +IsaGetPossibleResource (
> +  IN     EFI_ISA_ACPI_PROTOCOL       *This,
> +  IN     EFI_ISA_ACPI_DEVICE_ID      *Device,
> +  OUT    EFI_ISA_ACPI_RESOURCE_LIST  **ResourceList
> +  )
> +{
> +  //
> +  // Not supported yet
> +  //
> +  return EFI_UNSUPPORTED;
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +IsaSetResource (
> +  IN     EFI_ISA_ACPI_PROTOCOL       *This,
> +  IN     EFI_ISA_ACPI_DEVICE_ID      *Device,
> +  IN     EFI_ISA_ACPI_RESOURCE_LIST  *ResourceList
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +IsaEnableDevice (
> +  IN    EFI_ISA_ACPI_PROTOCOL        *This,
> +  IN    EFI_ISA_ACPI_DEVICE_ID       *Device,
> +  IN    BOOLEAN                      Enable
> +  )
> +{
> +
> +  return EFI_UNSUPPORTED;
> +}
> +
> +/**
> +
> +  Clear out Resource List if device is set to disable by platform policy
> +
> +**/
> +VOID
> +EmptyResourceList (
> +  IN  UINT32      DeviceHid
> +  )
> +{
> +  UINT8     Index;
> +  for (Index = 0; mLpcWpce791DeviceList[Index].Device.HID != 0; Index++) {
> +    if (DeviceHid == mLpcWpce791DeviceList[Index].Device.HID) {
> +      mLpcWpce791DeviceList[Index].ResourceItem = NULL;
> +    }
> +  }
> +  return;
> +}
> +
> +/**
> +
> +  Clear out Resource List if device is set to disable by platform policy
> +
> +**/
> +VOID
> +EmptyResourceListHidUid (
> +  IN  UINT32      DeviceHid,
> +  IN  UINT32      DeviceUid
> +  )
> +{
> +  UINT8     Index;
> +  for (Index = 0; mLpcWpce791DeviceList[Index].Device.HID != 0; Index++) {
> +    if ((DeviceHid == mLpcWpce791DeviceList[Index].Device.HID) &&
> +        (DeviceUid == mLpcWpce791DeviceList[Index].Device.UID)) {
> +      mLpcWpce791DeviceList[Index].ResourceItem = NULL;
> +    }
> +  }
> +  return;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +IsaInitDevice (
> +  IN    EFI_ISA_ACPI_PROTOCOL        *This,
> +  IN    EFI_ISA_ACPI_DEVICE_ID       *Device
> +  )
> +{
> +  EFI_WPCE791_POLICY_PROTOCOL      *LpcWpce791Policy;
> +  EFI_STATUS                      Status;
> +
> +  //
> +  // Disable configuration according to platform protocol
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiLpcWpce791PolicyProtocolGuid,
> +                  NULL,
> +                  (VOID **) &LpcWpce791Policy
> +                  );
> +  if (!EFI_ERROR(Status)) {
> +    if (LpcWpce791Policy->DeviceEnables.Ps2Keyboard ==
> EFI_WPCE791_PS2_KEYBOARD_DISABLE) {
> +      EmptyResourceList(EISA_PNP_ID(0x303));
> +      DisableLogicalDevice (SIO_KEYBOARD);
> +      EmptyResourceList(EISA_PNP_ID(0xF03));
> +      DisableLogicalDevice (SIO_KEYBOARD);
> +    }
> +    if (LpcWpce791Policy->DeviceEnables.Ps2Mouse ==
> EFI_WPCE791_PS2_MOUSE_DISABLE) {
> +      EmptyResourceList(EISA_PNP_ID(0xF03));
> +      DisableLogicalDevice (SIO_MOUSE);
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +LpcInterfaceInit (
> +  IN    EFI_ISA_ACPI_PROTOCOL        *This
> +  )
> +{
> +  EFI_PCI_IO_PROTOCOL             *PciIo;
> +  UINTN                           Index;
> +
> +  PciIo = (LPC_ISA_ACPI_FROM_THIS (This))->PciIo;
> +
> +  //
> +  // DMA controller initialize
> +  //
> +  for (Index=0; Index < (sizeof(mIchDmaInitTable)/sizeof(ICH_DMA_INIT));
> Index++) {
> +    PciIo->Io.Write (
> +                PciIo,
> +                EfiPciIoWidthUint8,
> +                EFI_PCI_IO_PASS_THROUGH_BAR,
> +                mIchDmaInitTable[Index].Register,
> +                1,
> +                &mIchDmaInitTable[Index].Value
> +                );
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h
> new file mode 100644
> index 0000000000..2291fd2c1d
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h
> @@ -0,0 +1,103 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +    LpcIsaAcpi.h
> +
> +Abstract:
> +
> +    Isa Acpi interface
> +
> +
> +
> +--*/
> +
> +#ifndef _LPC_ISA_ACPI_H
> +#define _LPC_ISA_ACPI_H
> +
> +
> +
> +#include "Protocol/IsaAcpi.h"
> +#include "Library/DevicePathLib.h"
> +
> +
> +typedef struct {
> +  UINT8  Register;
> +  UINT8  Value;
> +} ICH_DMA_INIT;
> +
> +//
> +// Prototypes for the ISA ACPI protocol interface
> +//
> +EFI_STATUS
> +EFIAPI
> +IsaDeviceEnumerate (
> +  IN     EFI_ISA_ACPI_PROTOCOL       *This,
> +  OUT    EFI_ISA_ACPI_DEVICE_ID      **Device
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +IsaDeviceSetPower (
> +  IN     EFI_ISA_ACPI_PROTOCOL       *This,
> +  IN     EFI_ISA_ACPI_DEVICE_ID      *Device,
> +  IN     BOOLEAN                     OnOff
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +IsaGetCurrentResource (
> +  IN     EFI_ISA_ACPI_PROTOCOL       *This,
> +  IN     EFI_ISA_ACPI_DEVICE_ID      *Device,
> +  OUT    EFI_ISA_ACPI_RESOURCE_LIST  **ResourceList
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +IsaGetPossibleResource (
> +  IN     EFI_ISA_ACPI_PROTOCOL       *This,
> +  IN     EFI_ISA_ACPI_DEVICE_ID      *Device,
> +  OUT    EFI_ISA_ACPI_RESOURCE_LIST  **ResourceList
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +IsaSetResource (
> +  IN     EFI_ISA_ACPI_PROTOCOL       *This,
> +  IN     EFI_ISA_ACPI_DEVICE_ID      *Device,
> +  IN     EFI_ISA_ACPI_RESOURCE_LIST  *ResourceList
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +IsaEnableDevice (
> +  IN    EFI_ISA_ACPI_PROTOCOL        *This,
> +  IN    EFI_ISA_ACPI_DEVICE_ID       *Device,
> +  IN    BOOLEAN                      Enable
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +IsaInitDevice (
> +  IN    EFI_ISA_ACPI_PROTOCOL        *This,
> +  IN    EFI_ISA_ACPI_DEVICE_ID       *Device
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +LpcInterfaceInit (
> +  IN    EFI_ISA_ACPI_PROTOCOL        *This
> +);
> +
> +VOID
> +EmptyResourceList (
> +  IN    UINT32      DeviceHid
> +);
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c
> b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c
> new file mode 100644
> index 0000000000..f23e48ccf2
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c
> @@ -0,0 +1,126 @@
> +/** @file
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +Module Name:
> +
> +    LpcSio.c
> +
> +Abstract: Sio implementation
> +
> +Revision History
> +
> +--*/
> +
> +#include "LpcDriver.h"
> +#include <Library/S3BootScriptLib.h>
> +
> +VOID
> +WriteRegister (
> +  IN  UINT8   Index,
> +  IN  UINT8   Data
> +  );
> +
> +typedef struct {
> +  UINT8 Register;
> +  UINT8 Value;
> +} EFI_SIO_TABLE;
> +
> +EFI_SIO_TABLE mSioTable[] = {
> +  //
> +  // Init keyboard controller
> +  //
> +  { REG_LOGICAL_DEVICE, SIO_KEYBOARD },
> +  { BASE_ADDRESS_HIGH, 0x00 },
> +  { BASE_ADDRESS_LOW, 0x60 },
> +  { BASE_ADDRESS_HIGH2, 0x00 },
> +  { BASE_ADDRESS_LOW2, 0x64 },
> +  { PRIMARY_INTERRUPT_SELECT, 0x01 },
> +  { ACTIVATE, 0x1 },
> +
> +  //
> +  // Init Mouse controller
> +  //
> +  { REG_LOGICAL_DEVICE, SIO_MOUSE },
> +  { BASE_ADDRESS_HIGH, 0x00 },
> +  { BASE_ADDRESS_LOW, 0x60 },
> +  { BASE_ADDRESS_HIGH2, 0x00 },
> +  { BASE_ADDRESS_LOW2, 0x64 },
> +  { PRIMARY_INTERRUPT_SELECT, 0x0c },
> +  { ACTIVATE, 0x1 },
> +
> +  { REG_LOGICAL_DEVICE, SIO_COM },
> +  { BASE_ADDRESS_HIGH, 0x03 },
> +  { BASE_ADDRESS_LOW, 0xf8 },
> +  { PRIMARY_INTERRUPT_SELECT, 0x04 },
> +  { ACTIVATE, 0x1 },
> +
> +
> +};
> +
> +VOID
> +LPCWPCE791SetDefault ()
> +{
> +  UINT8           Index;
> +
> +  for (Index = 0; Index < sizeof(mSioTable)/sizeof(EFI_SIO_TABLE); Index++)
> {
> +    WriteRegisterAndSaveToScript (mSioTable[Index].Register,
> mSioTable[Index].Value);
> +  }
> +
> +  return;
> +}
> +
> +VOID
> +DisableLogicalDevice (
> +  UINT8       DeviceId
> +  )
> +{
> +  WriteRegisterAndSaveToScript (REG_LOGICAL_DEVICE, DeviceId);
> +  WriteRegisterAndSaveToScript (ACTIVATE, 0);
> +  WriteRegisterAndSaveToScript (BASE_ADDRESS_HIGH, 0);
> +  WriteRegisterAndSaveToScript (BASE_ADDRESS_LOW, 0);
> +
> +  return;
> +}
> +
> +VOID
> +WriteRegister (
> +  IN  UINT8   Index,
> +  IN  UINT8   Data
> +  )
> +{
> +  LpcIoWrite8(CONFIG_PORT, Index);
> +  LpcIoWrite8(DATA_PORT, Data);
> +
> +  return;
> +}
> +
> +VOID
> +WriteRegisterAndSaveToScript (
> +  IN  UINT8   Index,
> +  IN  UINT8   Data
> +  )
> +{
> +  UINT8  Buffer[2];
> +
> +  LpcIoWrite8(CONFIG_PORT, Index);
> +  LpcIoWrite8(DATA_PORT, Data);
> +
> +  Buffer[0] = Index;
> +  Buffer[1] = Data;
> +  S3BootScriptSaveIoWrite (
> +    EfiBootScriptWidthUint8,
> +    INDEX_PORT,
> +    2,
> +    Buffer
> +    );
> +
> +  return;
> +}
> +
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h
> b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h
> new file mode 100644
> index 0000000000..52c1499e3d
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h
> @@ -0,0 +1,101 @@
> +/*++
> +
> +  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> 
> +
> +Module Name:
> +
> +    LpcSio.h
> +
> +Abstract:
> +
> +    Lpc driver's sio interface
> +
> +
> +
> +--*/
> +
> +#ifndef _LPC_SIO_H
> +#define _LPC_SIO_H
> +
> +#include "Protocol/PciRootBridgeIo.h"
> +
> +#define VARSIOINSTALLED L"VarSIOProcotolInstalled"
> +
> +//
> +// Port address
> +//
> +#define CONFIG_PORT               0x04E
> +#define INDEX_PORT                0x04E
> +#define DATA_PORT                 INDEX_PORT + 1
> +
> +//
> +// Logical Device
> +//
> +#define SIO_COM                   0x3
> +#define SIO_MSWC                  0x4
> +#define SIO_MOUSE                 0x5
> +#define SIO_KEYBOARD              0x6
> +#define SIO_SHM                   0xF
> +#define SIO_PM1                   0x11
> +#define SIO_PM2                   0x12
> +#define SIO_PM3                   0x17
> +#define SIO_ESHM                  0x1D
> +
> +//
> +// Global register
> +//
> +#define REG_LOGICAL_DEVICE        0x07
> +#define REG_DEVICE_ID             0x20
> +#define SIO_CONFIG_1              0x21
> +#define REG_CHIP_REV              0x24
> +#define SIO_CONFIG_5              0x25
> +#define SIO_CONFIG_6              0x26
> +#define REG_DEVICE_REV            0x27
> +#define SIO_CONFIG_9              0x29
> +#define SIO_CONFIG_D              0x2D
> +
> +#define ACTIVATE                  0x30
> +#define BASE_ADDRESS_HIGH         0x60
> +#define BASE_ADDRESS_LOW          0x61
> +#define BASE_ADDRESS_HIGH2        0x62
> +#define BASE_ADDRESS_LOW2         0x63
> +#define PRIMARY_INTERRUPT_SELECT  0x70
> +#define DMA_CHANNEL_SELECT        0x74
> +
> +EFI_STATUS
> +InitializeLpcSio (
> +  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *RootBridgeIo
> +  );
> +
> +//
> +// Prototypes for the sio internal function
> +//
> +//
> +// Internal function
> +//
> +VOID
> +LPCWPCE791SetDefault (
> +  VOID
> +  );
> +
> +VOID
> +WriteRegisterAndSaveToScript (
> +  IN  UINT8   Index,
> +  IN  UINT8   Data
> +  );
> +
> +VOID
> +FloppyWriteProtect (
> +  VOID
> +  );
> +
> +VOID
> +DisableLogicalDevice (
> +  UINT8       DeviceId
> +  );
> +
> +#endif
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/Wpce791.inf
> b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/Wpce791.inf
> new file mode 100644
> index 0000000000..5fd458e265
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Wpce791/Wpce791.inf
> @@ -0,0 +1,63 @@
> +#
> +#
> +# Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
> +#
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +#
> 
> +#
> +#
> +#
> +#  Module Name:
> +#
> +#    SiO791.inf
> +#
> +#  Abstract:
> +#
> +#    Component description file for SIO791 module.
> +#
> +--*/
> +
> +[defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = SIO791
> +  FILE_GUID                      = 04A76C80-06B9-445e-B73E-CB8C61A6A964
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = LpcDriverEntryPoint
> +
> +[sources.common]
> + LpcIsaAcpi.h
> + LpcSio.h
> + LpcDriver.h
> + LpcIsaAcpi.c
> + LpcSio.c
> + LpcDriver.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  Vlv2TbltDevicePkg/PlatformPkg.dec
> +  IntelFrameworkPkg/IntelFrameworkPkg.dec
> +  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
> +  PcAtChipsetPkg/PcAtChipsetPkg.dec
> +
> +
> +[LibraryClasses]
> +  UefiDriverEntryPoint
> +  UefiBootServicesTableLib
> +  DevicePathLib
> +  UefiLib
> +  S3BootScriptLib
> +  DebugLib
> +
> +[Ppis]
> +
> +[Protocols]
> +  gEfiPciIoProtocolGuid
> +  gEfiIsaAcpiProtocolGuid
> +  gEfiLpcWpce791PolicyProtocolGuid
> +
> +[Guids]
> +
> +[Depex]
> +  TRUE
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat
> b/Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat
> new file mode 100644
> index 0000000000..d8594053b0
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat
> @@ -0,0 +1,332 @@
> +@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
> +echo.
> +echo %date%  %time%
> +echo.
> +
> +
> +::********************************************************
> **************
> +:: Initial Setup
> +::********************************************************
> **************
> +if %WORKSPACE:~-1%==\ set WORKSPACE=%WORKSPACE:~0,-1%
> +set /a build_threads=1
> +set "Build_Flags= "
> +set exitCode=0
> +set Arch=X64
> +set Source=0
> +set PLATFORM_NAME=Vlv2TbltDevicePkg
> +
> +set CORE_PATH=%WORKSPACE%
> +if not exist %CORE_PATH%\edksetup.bat (
> +  if defined PACKAGES_PATH (
> +    for %%i IN (%PACKAGES_PATH%) DO (
> +      if exist %%~fi\edksetup.bat (
> +        set CORE_PATH=%%~fi
> +        goto CorePathFound
> +      )
> +    )
> +  ) else (
> +    echo.
> +    echo !!! ERROR !!! Cannot find edksetup.bat !!!
> +    echo.
> +    goto BldFail
> +  )
> +)
> +:CorePathFound
> +
> +set PLATFORM_PACKAGE=%WORKSPACE%\%PLATFORM_NAME%
> +if not exist %PLATFORM_PACKAGE% (
> +  if defined PACKAGES_PATH (
> +    for %%i IN (%PACKAGES_PATH%) DO (
> +      if exist %%~fi\%PLATFORM_NAME% (
> +        set PLATFORM_PACKAGE=%%~fi\%PLATFORM_NAME%
> +        goto PlatformPackageFound
> +      )
> +    )
> +  ) else (
> +    echo.
> +    echo !!! ERROR !!! Cannot find %PLATFORM_NAME% !!!
> +    echo.
> +    goto BldFail
> +  )
> +)
> +:PlatformPackageFound
> +
> +cd %CORE_PATH%
> +
> +:: Clean up previous build files.
> +if exist %WORKSPACE%\edk2.log del %WORKSPACE%\edk2.log
> +if exist %WORKSPACE%\unitool.log del %WORKSPACE%\unitool.log
> +if exist %WORKSPACE%\Conf\target.txt
> del %WORKSPACE%\Conf\target.txt
> +if exist %WORKSPACE%\Conf\tools_def.txt
> del %WORKSPACE%\Conf\tools_def.txt
> +if exist %WORKSPACE%\Conf\build_rule.txt
> del %WORKSPACE%\Conf\build_rule.txt
> +if exist %WORKSPACE%\Conf\.cache rmdir
> /q/s %WORKSPACE%\Conf\.cache
> +
> +:: Setup EDK environment. Edksetup puts new copies of target.txt,
> tools_def.txt, build_rule.txt in WorkSpace\Conf
> +:: Also run edksetup as soon as possible to avoid it from changing
> environment variables we're overriding
> +call %CORE_PATH%\edksetup.bat Rebuild
> +@echo off
> +
> +:: Define platform specific environment variables.
> +set config_file=%PLATFORM_PACKAGE%\PlatformPkgConfig.dsc
> +set auto_config_inc=%PLATFORM_PACKAGE%\AutoPlatformCFG.txt
> +
> +
> +
> +::create new AutoPlatformCFG.txt file
> +copy /y nul %auto_config_inc% >nul
> +
> +::********************************************************
> **************
> +:: Parse command line arguments
> +::********************************************************
> **************
> +
> +:: Optional arguments
> +:OptLoop
> +if /i "%~1"=="/?" goto Usage
> +
> +if /i "%~1"=="/l" (
> +    set Build_Flags=%Build_Flags% -j EDK2.log
> +    shift
> +    goto OptLoop
> +)
> +if /i "%~1"=="/y" (
> +    set Build_Flags=%Build_Flags% -
> y %PLATFORM_PACKAGE%\EDK2_%PLATFORM_PACKAGE%.report
> +    shift
> +    goto OptLoop
> +)
> +if /i "%~1"=="/m" (
> +    if defined NUMBER_OF_PROCESSORS (
> +        set /a build_threads=%NUMBER_OF_PROCESSORS%+1
> +    )
> +    shift
> +    goto OptLoop
> +)
> +if /i "%~1" == "/c" (
> +    echo Removing previous build files ...
> +    if exist build (
> +        del /f/s/q build > nul
> +        rmdir /s/q build
> +    )
> +    if exist %WORKSPACE%\Conf\.cache (
> +        del /f/s/q %WORKSPACE%\Conf\.cache > nul
> +        rmdir /s/q %WORKSPACE%\Conf\.cache
> +    )
> +    echo.
> +    shift
> +    goto OptLoop
> +)
> +
> +if /i "%~1"=="/x64" (
> +    set Arch=X64
> +    shift
> +    goto OptLoop
> +)
> +if /i "%~1"=="/IA32" (
> +    set Arch=IA32
> +    shift
> +    goto OptLoop
> +)
> +
> +:: Required argument(s)
> +if "%~1"=="" goto Usage
> +
> +::Remove the values for Platform_Type and Build_Target from BiosIdX.env
> and stage in Conf\
> +if "%Arch%"=="IA32" (
> +    findstr /b /v "BOARD_ID
> BUILD_TYPE" %PLATFORM_PACKAGE%\BiosIdR.env > %WORKSPACE%\Conf
> \BiosId.env
> +    echo DEFINE X64_CONFIG = FALSE  >> %auto_config_inc%
> +) else if "%Arch%"=="X64" (
> +    findstr /b /v "BOARD_ID
> BUILD_TYPE" %PLATFORM_PACKAGE%\BiosIdx64R.env > %WORKSPACE%\C
> onf\BiosId.env
> +    echo DEFINE X64_CONFIG = TRUE  >> %auto_config_inc%
> +)
> +
> +:: -- Build flags settings for each Platform --
> +echo Setting  %1  platform configuration and BIOS ID...
> +if /i "%~1" == "MNW2" (
> +    echo BOARD_ID = MNW2MAX >> %WORKSPACE%\Conf\BiosId.env
> +    echo DEFINE ENBDT_PF_BUILD = TRUE   >> %auto_config_inc%
> +
> +) else (
> +    echo Error - Unsupported PlatformType: %1
> +    goto Usage
> +)
> +set Platform_Type=%~1
> +
> +if /i "%~2" == "RELEASE" (
> +    set target=RELEASE
> +    echo BUILD_TYPE = R >> %WORKSPACE%\Conf\BiosId.env
> +) else (
> +    set target=DEBUG
> +    echo BUILD_TYPE = D >> %WORKSPACE%\Conf\BiosId.env
> +)
> +
> +::********************************************************
> **************
> +:: Additional EDK Build Setup/Configuration
> +::********************************************************
> **************
> +echo.
> +echo Setting the Build environment for
> VS2015/VS2013/VS2012/VS2010/VS2008...
> +if defined VS140COMNTOOLS (
> +  if not defined VSINSTALLDIR call "%VS140COMNTOOLS%\vsvars32.bat"
> +  if /I "%VS140COMNTOOLS%" == "C:\Program Files\Microsoft Visual Studio
> 14.0\Common7\Tools\" (
> +    set TOOL_CHAIN_TAG=VS2015
> +  ) else (
> +    set TOOL_CHAIN_TAG=VS2015x86
> +  )
> +) else if defined VS120COMNTOOLS (
> +  if not defined VSINSTALLDIR call "%VS120COMNTOOLS%\vsvars32.bat"
> +  if /I "%VS120COMNTOOLS%" == "C:\Program Files\Microsoft Visual Studio
> 12.0\Common7\Tools\" (
> +    set TOOL_CHAIN_TAG=VS2013
> +  ) else (
> +    set TOOL_CHAIN_TAG=VS2013x86
> +  )
> +) else if defined VS110COMNTOOLS (
> +  if not defined VSINSTALLDIR call "%VS110COMNTOOLS%\vsvars32.bat"
> +  if /I "%VS110COMNTOOLS%" == "C:\Program Files\Microsoft Visual Studio
> 11.0\Common7\Tools\" (
> +    set TOOL_CHAIN_TAG=VS2012
> +  ) else (
> +    set TOOL_CHAIN_TAG=VS2012x86
> +  )
> +) else if defined VS100COMNTOOLS (
> +  if not defined VSINSTALLDIR call "%VS100COMNTOOLS%\vsvars32.bat"
> +  if /I "%VS100COMNTOOLS%" == "C:\Program Files\Microsoft Visual Studio
> 10.0\Common7\Tools\" (
> +    set TOOL_CHAIN_TAG=VS2010
> +  ) else (
> +    set TOOL_CHAIN_TAG=VS2010x86
> +  )
> +) else if defined VS90COMNTOOLS (
> +  if not defined VSINSTALLDIR call "%VS90COMNTOOLS%\vsvars32.bat"
> +  if /I "%VS90COMNTOOLS%" == "C:\Program Files\Microsoft Visual Studio
> 9.0\Common7\Tools\" (
> +     set TOOL_CHAIN_TAG=VS2008
> +  ) else (
> +     set TOOL_CHAIN_TAG=VS2008x86
> +  )
> +) else (
> +  echo  --ERROR: VS2015/VS2013/VS2012/VS2010/VS2008 not installed
> correctly.
> VS140COMNTOOLS/VS120COMNTOOLS/VS110COMNTOOLS/VS100COMNTO
> OLS/VS90COMNTOOLS not defined ^^!
> +  echo.
> +  goto :BldFail
> +)
> +
> +echo Ensuring correct build directory is present for GenBiosId...
> +set
> BUILD_PATH=%WORKSPACE%\Build\%PLATFORM_NAME%\%TARGET%_%T
> OOL_CHAIN_TAG%
> +
> +echo Modifing Conf files for this build...
> +:: Remove lines with these tags from target.txt
> +findstr /V "TARGET  TARGET_ARCH  TOOL_CHAIN_TAG  BUILD_RULE_CONF
> ACTIVE_PLATFORM
> MAX_CONCURRENT_THREAD_NUMBER" %WORKSPACE%\Conf\target.txt >
> %WORKSPACE%\Conf\target.txt.tmp
> +
> +echo TARGET
> = %TARGET%                                  >> %WORKSPACE%\Conf\target.txt.tmp
> +if "%Arch%"=="IA32" (
> +    echo TARGET_ARCH =
> IA32                                       >> %WORKSPACE%\Conf\target.txt.tmp
> +) else if "%Arch%"=="X64" (
> +    echo TARGET_ARCH = IA32
> X64                                  >> %WORKSPACE%\Conf\target.txt.tmp
> +)
> +echo TOOL_CHAIN_TAG
> = %TOOL_CHAIN_TAG%                                  >> %WORKSPACE%\Conf\target.txt
> .tmp
> +echo BUILD_RULE_CONF =
> Conf/build_rule.txt                               >> %WORKSPACE%\Conf\target.txt.tmp
> +if %Source% == 0 (
> +  echo ACTIVE_PLATFORM
> = %PLATFORM_PACKAGE%/PlatformPkg%Arch%.dsc        >> %WORKSPACE%
> \Conf\target.txt.tmp
> +) else (
> +  echo ACTIVE_PLATFORM
> = %PLATFORM_PACKAGE%/PlatformPkg%Arch%Source.dsc  >> %WORKSPA
> CE%\Conf\target.txt.tmp
> +)
> +echo MAX_CONCURRENT_THREAD_NUMBER
> = %build_threads%                      >> %WORKSPACE%\Conf\target.txt.tmp
> +
> +move
> /Y %WORKSPACE%\Conf\target.txt.tmp %WORKSPACE%\Conf\target.txt >n
> ul
> +
> +::********************************************************
> **************
> +:: Build BIOS
> +::********************************************************
> **************
> +
> +echo Creating BiosId...
> +if not exist %BUILD_PATH%\IA32  mkdir %BUILD_PATH%\IA32
> +%PLATFORM_PACKAGE%\GenBiosId.exe -
> i %WORKSPACE%\Conf\BiosId.env -o %BUILD_PATH%\IA32\BiosId.bin -
> ob %WORKSPACE%\Conf\BiosId.bat
> +if "%Arch%"=="X64" (
> +   if not exist %BUILD_PATH%\X64  mkdir %BUILD_PATH%\X64
> +   %PLATFORM_PACKAGE%\GenBiosId.exe -
> i %WORKSPACE%\Conf\BiosId.env -o %BUILD_PATH%\X64\BiosId.bin -
> ob %WORKSPACE%\Conf\BiosId.bat
> +)
> +
> +if %ERRORLEVEL% NEQ 0 goto BldFail
> +
> +echo.
> +echo Invoking EDK2 build...
> +call build %Build_Flags%
> +
> +if %ERRORLEVEL% NEQ 0 goto BldFail
> +
> +::********************************************************
> **************
> +:: Post Build processing and cleanup
> +::********************************************************
> **************
> +
> +echo Running fce...
> +
> +pushd %PLATFORM_PACKAGE%
> +:: Extract Hii data from build and store in HiiDefaultData.txt
> +%PLATFORM_PACKAGE%\fce read -
> i %BUILD_PATH%\FV\Vlv.fd > %BUILD_PATH%\FV\HiiDefaultData.txt
> +
> +:: save changes to VlvXXX.fd
> +%PLATFORM_PACKAGE%\fce update -i %BUILD_PATH%\FV\Vlv.fd -
> s %BUILD_PATH%\FV\HiiDefaultData.txt -
> o %BUILD_PATH%\FV\Vlv%Arch%.fd
> +popd
> +
> +if %ERRORLEVEL% NEQ 0 goto BldFail
> +::echo FD successfully updated with default Hii values.
> +
> +:: 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
> +copy
> /y/b %BUILD_PATH%\FV\Vlv%Arch%.fd  %PLATFORM_PACKAGE%\Stitch\%
> BIOS_Name% >nul
> +copy
> /y/b %BUILD_PATH%\FV\Vlv%Arch%.fd  %BUILD_PATH%\FV\Vlv.ROM >nul
> +
> +echo.
> +echo Build location:     %BUILD_PATH%
> +echo BIOS ROM Created:   %BIOS_Name%
> +echo.
> +echo -------------------- The EDKII BIOS build has successfully completed. -----
> ---------------
> +echo.
> +
> +@REM build capsule here
> +echo > %BUILD_PATH%\FV\SYSTEMFIRMWAREUPDATECARGO.Fv
> +build -p %PLATFORM_PACKAGE%\PlatformCapsule.dsc
> +
> +goto Exit
> +
> +:Usage
> +echo.
> +echo
> **********************************************************
> *****************
> +echo Build BIOS rom for VLV platforms.
> +echo.
> +echo Usage: bld_vlv.bat [options] PlatformType [Build Target]
> +echo.
> +echo    /c    CleanAll before building
> +echo    /l    Generate build log file
> +echo    /y    Generate build report file
> +echo    /m    Enable multi-processor build
> +echo    /IA32 Set Arch to IA32 (default: X64)
> +echo    /X64  Set Arch to X64 (default: X64)
> +echo.
> +echo        Platform Types:  MNW2
> +echo        Build Targets:   Debug, Release  (default: Debug)
> +echo.
> +echo Examples:
> +echo    bld_vlv.bat MNW2                 : X64 Debug build for MinnowMax
> +echo    bld_vlv.bat /IA32 MNW2 release   : IA32 Release build for
> MinnowMax
> +echo.
> +echo
> **********************************************************
> *****************
> +set exitCode=1
> +goto Exit
> +
> +:BldFail
> +set exitCode=1
> +echo  -- Error:  EDKII BIOS Build has failed!
> +echo See EDK2.log for more details
> +
> +:Exit
> +echo %date%  %time%
> +exit /b %exitCode%
> +
> +EndLocal
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh
> b/Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh
> new file mode 100644
> index 0000000000..ec3a325db7
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh
> @@ -0,0 +1,256 @@
> +#!/usr/bin/env bash
> +##*******************************************************
> ***************
> +## Function define
> +##*******************************************************
> ***************
> +function Usage() {
> +  echo
> +  echo
> "**********************************************************
> *****************"
> +  echo "Build BIOS rom for VLV platforms."
> +  echo
> +  echo "Usage: bld_vlv.bat  PlatformType [Build Target]"
> +  echo
> +  echo
> +  echo "       Platform Types:  MNW2"
> +  echo "       Build Targets:   Debug, Release  (default: Debug)"
> +  echo
> +  echo
> "**********************************************************
> *****************"
> +  echo "Press any key......"
> +  read
> +  exit 0
> +}
> +
> +
> +echo -e $(date)
> +##*******************************************************
> ***************
> +## Initial Setup
> +##*******************************************************
> ***************
> +#WORKSPACE=$(pwd)
> +#build_threads=($NUMBER_OF_PROCESSORS)+1
> +Build_Flags=
> +exitCode=0
> +Arch=X64
> +SpiLock=0
> +
> +## Clean up previous build files.
> +if [ -e $(pwd)/EDK2.log ]; then
> +  rm $(pwd)/EDK2.log
> +fi
> +
> +if [ -e $(pwd)/Unitool.log ]; then
> +  rm $(pwd)/Unitool.log
> +fi
> +
> +if [ -e $(pwd)/Conf/target.txt ]; then
> +  rm $(pwd)/Conf/target.txt
> +fi
> +
> +if [ -e $(pwd)/Conf/BiosId.env ]; then
> +  rm $(pwd)/Conf/BiosId.env
> +fi
> +
> +if [ -e $(pwd)/Conf/tools_def.txt ]; then
> +  rm $(pwd)/Conf/tools_def.txt
> +fi
> +
> +if [ -e $(pwd)/Conf/build_rule.txt ]; then
> +  rm $(pwd)/Conf/build_rule.txt
> +fi
> +
> +
> +## Setup EDK environment. Edksetup puts new copies of target.txt,
> tools_def.txt, build_rule.txt in WorkSpace\Conf
> +## Also run edksetup as soon as possible to avoid it from changing
> environment variables we're overriding
> +. edksetup.sh BaseTools
> +make -C BaseTools
> +
> +## Define platform specific environment variables.
> +PLATFORM_PACKAGE=Vlv2TbltDevicePkg
> +config_file=$WORKSPACE/$PLATFORM_PACKAGE/PlatformPkgConfig.dsc
> +auto_config_inc=$WORKSPACE/$PLATFORM_PACKAGE/AutoPlatformCFG.t
> xt
> +
> +## default ECP (override with /ECP flag)
> +EDK_SOURCE=$WORKSPACE/EdkCompatibilityPkg
> +
> +## create new AutoPlatformCFG.txt file
> +if [ -f "$auto_config_inc" ]; then
> +  rm $auto_config_inc
> +fi
> +touch $auto_config_inc
> +
> +##*******************************************************
> ***************
> +## Parse command line arguments
> +##*******************************************************
> ***************
> +
> +## Optional arguments
> +for (( i=1; i<=$#; ))
> +  do
> +    if [ "$1" == "/?" ]; then
> +      Usage
> +    elif [ "$(echo $1 | tr 'a-z' 'A-Z')" == "/Q" ]; then
> +      Build_Flags="$Build_Flags --quiet"
> +      shift
> +    elif [ "$(echo $1 | tr 'a-z' 'A-Z')" == "/L" ]; then
> +      Build_Flags="$Build_Flags -j EKD2.log"
> +      shift
> +    elif [ "$(echo $1 | tr 'a-z' 'A-Z')" == "/C" ]; then
> +      echo Removing previous build files ...
> +      if [ -d "Build" ]; then
> +        rm -r Build
> +      fi
> +      shift
> +    elif [ "$(echo $1 | tr 'a-z' 'A-Z')" == "/ECP" ]; then
> +      ECP_SOURCE=$WORKSPACE/EdkCompatibilityPkgEcp
> +      EDK_SOURCE=$WORKSPACE/EdkCompatibilityPkgEcp
> +      echo DEFINE ECP_BUILD_ENABLE = TRUE >> $auto_config_inc
> +      shift
> +    elif [ "$(echo $1 | tr 'a-z' 'A-Z')" == "/X64" ]; then
> +      Arch=X64
> +      shift
> +    elif [ "$(echo $1 | tr 'a-z' 'A-Z')" == "/YL" ]; then
> +      SpiLock=1
> +      shift
> +    else
> +      break
> +    fi
> +  done
> +
> +
> +
> +
> +
> +## Required argument(s)
> +if [ "$2" == "" ]; then
> +  Usage
> +fi
> +
> +## Remove the values for Platform_Type and Build_Target from
> BiosIdX.env and stage in Conf
> +if [ $Arch == "IA32" ]; then
> +  cp $PLATFORM_PACKAGE/BiosIdR.env    Conf/BiosId.env
> +  echo DEFINE X64_CONFIG = FALSE      >> $auto_config_inc
> +else
> +  cp $PLATFORM_PACKAGE/BiosIdx64R.env  Conf/BiosId.env
> +  echo DEFINE X64_CONFIG = TRUE       >> $auto_config_inc
> +fi
> +sed -i '/^BOARD_ID/d' Conf/BiosId.env
> +sed -i '/^BUILD_TYPE/d' Conf/BiosId.env
> +
> +
> +
> +## -- Build flags settings for each Platform --
> +##    AlpineValley (ALPV):  SVP_PF_BUILD = TRUE,   ENBDT_PF_BUILD =
> FALSE,  TABLET_PF_BUILD = FALSE,  BYTI_PF_BUILD = FALSE, IVI_PF_BUILD =
> FALSE
> +##       BayleyBay (BBAY):  SVP_PF_BUILD = FALSE,  ENBDT_PF_BUILD = TRUE,
> TABLET_PF_BUILD = FALSE,  BYTI_PF_BUILD = FALSE, IVI_PF_BUILD = FALSE
> +##         BayLake (BLAK):  SVP_PF_BUILD = FALSE,  ENBDT_PF_BUILD = FALSE,
> TABLET_PF_BUILD = TRUE,   BYTI_PF_BUILD = FALSE, IVI_PF_BUILD = FALSE
> +##      Bakersport (BYTI):  SVP_PF_BUILD = FALSE,  ENBDT_PF_BUILD = FALSE,
> TABLET_PF_BUILD = FALSE,  BYTI_PF_BUILD = TRUE, IVI_PF_BUILD = FALSE
> +## Crestview Hills (CVHS):  SVP_PF_BUILD = FALSE,  ENBDT_PF_BUILD =
> FALSE,  TABLET_PF_BUILD = FALSE,  BYTI_PF_BUILD = TRUE, IVI_PF_BUILD =
> TRUE
> +##            FFD8 (BLAK):  SVP_PF_BUILD = FALSE,  ENBDT_PF_BUILD = FALSE,
> TABLET_PF_BUILD = TRUE,   BYTI_PF_BUILD = FALSE, IVI_PF_BUILD = FALSE
> +echo "Setting  $1  platform configuration and BIOS ID..."
> +if [ "$(echo $1 | tr 'a-z' 'A-Z')" == "MNW2" ]; then
> +  echo BOARD_ID = MNW2MAX             >> Conf/BiosId.env
> +  echo DEFINE ENBDT_PF_BUILD = TRUE  >> $auto_config_inc
> +else
> +  echo "Error - Unsupported PlatformType: $1"
> +  Usage
> +fi
> +
> +Platform_Type=$1
> +
> +if [ "$(echo $2 | tr 'a-z' 'A-Z')" == "RELEASE" ]; then
> +  TARGET=RELEASE
> +  BUILD_TYPE=R
> +  echo BUILD_TYPE = R >> Conf/BiosId.env
> +else
> +  TARGET=DEBUG
> +  BUILD_TYPE=D
> +  echo BUILD_TYPE = D >> Conf/BiosId.env
> +fi
> +
> +
> +##*******************************************************
> ***************
> +## Additional EDK Build Setup/Configuration
> +##*******************************************************
> ***************
> +echo "Ensuring correct build directory is present for GenBiosId..."
> +
> +echo Modifing Conf files for this build...
> +## Remove lines with these tags from target.txt
> +sed -i '/^ACTIVE_PLATFORM/d' Conf/target.txt
> +sed -i '/^TARGET /d' Conf/target.txt
> +sed -i '/^TARGET_ARCH/d' Conf/target.txt
> +sed -i '/^TOOL_CHAIN_TAG/d' Conf/target.txt
> +sed -i '/^MAX_CONCURRENT_THREAD_NUMBER/d' Conf/target.txt
> +
> +gcc_version=$(gcc -v 2>&1 | tail -1 | awk '{print $3}')
> +case $gcc_version in
> +    4.9.*|4.1[0-9].*|5.*.*|6.*.*)
> +      TARGET_TOOLS=GCC49
> +      ;;
> +    *)
> +      TARGET_TOOLS=GCC48
> +      ;;
> +esac
> +
> +ACTIVE_PLATFORM=$PLATFORM_PACKAGE/PlatformPkgGcc"$Arch".dsc
> +TOOL_CHAIN_TAG=$TARGET_TOOLS
> +MAX_CONCURRENT_THREAD_NUMBER=1
> +echo ACTIVE_PLATFORM = $ACTIVE_PLATFORM                           >>
> Conf/target.txt
> +echo TARGET          = $TARGET                                    >> Conf/target.txt
> +echo TOOL_CHAIN_TAG  = $TOOL_CHAIN_TAG                            >>
> Conf/target.txt
> +echo MAX_CONCURRENT_THREAD_NUMBER =
> $MAX_CONCURRENT_THREAD_NUMBER >> Conf/target.txt
> +if [ $Arch == "IA32" ]; then
> +  echo TARGET_ARCH   = IA32                                       >> Conf/target.txt
> +else
> +  echo TARGET_ARCH   = IA32 X64                                   >> Conf/target.txt
> +fi
> +
> +##*******************************************************
> ***************
> +## Build BIOS
> +##*******************************************************
> ***************
> +echo Skip "Running UniTool..."
> +echo "Make GenBiosId Tool..."
> +BUILD_PATH=Build/$PLATFORM_PACKAGE/"$TARGET"_"$TOOL_CHAIN_T
> AG"
> +if [ ! -d "$BUILD_PATH/$Arch" ]; then
> +  mkdir -p $BUILD_PATH/$Arch
> +fi
> +if [ -e "$BUILD_PATH/$Arch/BiosId.bin" ]; then
> +  rm -f $BUILD_PATH/$Arch/BiosId.bin
> +fi
> +
> +
> +./$PLATFORM_PACKAGE/GenBiosId -i Conf/BiosId.env -o
> $BUILD_PATH/$Arch/BiosId.bin
> +
> +
> +echo "Invoking EDK2 build..."
> +build
> +
> +if [ $SpiLock == "1" ]; then
> +
> IFWI_HEADER_FILE=./$PLATFORM_PACKAGE/Stitch/IFWIHeader/IFWI_HEA
> DER_SPILOCK.bin
> +else
> +
> IFWI_HEADER_FILE=./$PLATFORM_PACKAGE/Stitch/IFWIHeader/IFWI_HEA
> DER.bin
> +fi
> +
> +echo $IFWI_HEADER_FILE
> +
> +##*******************************************************
> ***************
> +## Post Build processing and cleanup
> +##*******************************************************
> ***************
> +
> +echo Skip "Running fce..."
> +
> +echo Skip "Running KeyEnroll..."
> +
> +## Set the Board_Id, Build_Type, Version_Major, and Version_Minor
> environment variables
> +VERSION_MAJOR=$(grep '^VERSION_MAJOR' Conf/BiosId.env | cut -d ' ' -f
> 3 | cut -c 1-4)
> +VERSION_MINOR=$(grep '^VERSION_MINOR' Conf/BiosId.env | cut -d ' ' -f
> 3 | cut -c 1-2)
> +BOARD_ID=$(grep '^BOARD_ID' Conf/BiosId.env | cut -d ' ' -f 3 | cut -c 1-7)
> +BIOS_Name="$BOARD_ID"_"$Arch"_"$BUILD_TYPE"_"$VERSION_MAJOR"
> _"$VERSION_MINOR".ROM
> +BIOS_ID="$BOARD_ID"_"$Arch"_"$BUILD_TYPE"_"$VERSION_MAJOR"_"$
> VERSION_MINOR"_GCC.bin
> +SEC_VERSION=1.0.2.1060v5
> +cat
> $IFWI_HEADER_FILE ../Vlv2Binaries/Vlv2SocBinPkg/SEC/$SEC_VERSION/VLV
> _SEC_REGION.bin ../Vlv2Binaries/Vlv2SocBinPkg/SEC/$SEC_VERSION/Vacant
> .bin $BUILD_PATH/FV/VLV.fd > ./$PLATFORM_PACKAGE/Stitch/$BIOS_ID
> +
> +
> +echo Skip "Running BIOS_Signing ..."
> +
> +echo
> +echo Build location:     $BUILD_PATH
> +echo BIOS ROM Created:   $BIOS_Name
> +echo
> +echo -------------------- The EDKII BIOS build has successfully completed. -----
> ---------------
> +echo
> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/cln.sh
> b/Platform/Intel/Vlv2TbltDevicePkg/cln.sh
> new file mode 100644
> index 0000000000..3511695f6f
> --- /dev/null
> +++ b/Platform/Intel/Vlv2TbltDevicePkg/cln.sh
> @@ -0,0 +1,62 @@
> +#!/usr/bin/env bash
> +echo
> +echo Run build cleanall...
> +echo
> +
> +echo
> +echo Directories to clean...
> +echo
> +
> +cd ..
> +
> +if [ -d "Build" ]; then
> +  rm -r Build
> +fi
> +
> +if [ -d "Conf/.cache" ]; then
> +  rm -r Conf/.cache
> +fi
> +
> +if [ -d "RomImages" ]; then
> +  rm -r RomImages
> +fi
> +
> +echo
> +echo Files to clean...
> +echo
> +
> +if [ -e $(pwd)/EDK2.log ]; then
> +  rm $(pwd)/EDK2.log
> +fi
> +
> +if [ -e $(pwd)/Unitool.log ]; then
> +  rm $(pwd)/Unitool.log
> +fi
> +
> +if [ -e $(pwd)/Conf/target.txt ]; then
> +  rm $(pwd)/Conf/target.txt
> +fi
> +
> +if [ -e $(pwd)/Conf/BiosId.env ]; then
> +  rm $(pwd)/Conf/BiosId.env
> +fi
> +
> +if [ -e $(pwd)/Conf/tools_def.txt ]; then
> +  rm $(pwd)/Conf/tools_def.txt
> +fi
> +
> +if [ -e $(pwd)/Conf/build_rule.txt ]; then
> +  rm $(pwd)/Conf/build_rule.txt
> +fi
> +
> +if [ -e $(pwd)/Conf/BuildEnv.sh ]; then
> +  rm $(pwd)/Conf/BuildEnv.sh
> +fi
> +
> +if [ -e $(pwd)/Vlv2TbltDevicePkg/AutoPlatformCFG.txt ]; then
> +  rm $(pwd)/Vlv2TbltDevicePkg/AutoPlatformCFG.txt
> +fi
> +
> +echo
> +echo All done...
> +echo
> --
> 2.21.0.windows.1


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [edk2-platforms: Patch 8/8] edk2-platforms: Update Maintainers.txt/Readme.md for imported packages
  2019-05-10  3:34 ` [edk2-platforms: Patch 8/8] edk2-platforms: Update Maintainers.txt/Readme.md for imported packages Michael D Kinney
  2019-05-10 18:04   ` [edk2-devel] " Leif Lindholm
@ 2019-05-13  2:52   ` Sun, Zailiang
  1 sibling, 0 replies; 23+ messages in thread
From: Sun, Zailiang @ 2019-05-13  2:52 UTC (permalink / raw)
  To: Kinney, Michael D, devel@edk2.groups.io
  Cc: Qian, Yi, Steele, Kelly, Ni, Ray, Kubacki, Michael A,
	Leif Lindholm, Ard Biesheuvel

Reviewed-by: Zailiang Sun <zailiang.sun@intel.com>

> -----Original Message-----
> From: Kinney, Michael D
> Sent: Friday, May 10, 2019 11:35 AM
> To: devel@edk2.groups.io
> Cc: Sun, Zailiang <zailiang.sun@intel.com>; Qian, Yi <yi.qian@intel.com>;
> Steele, Kelly <kelly.steele@intel.com>; Ni, Ray <ray.ni@intel.com>; Kubacki,
> Michael A <michael.a.kubacki@intel.com>; Leif Lindholm
> <leif.lindholm@linaro.org>; Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Subject: [edk2-platforms: Patch 8/8] edk2-platforms: Update
> Maintainers.txt/Readme.md for imported packages
> 
> https://bugzilla.tianocore.org/show_bug.cgi?id=1467
> https://bugzilla.tianocore.org/show_bug.cgi?id=1374
> https://bugzilla.tianocore.org/show_bug.cgi?id=1793
> 
> Update Maintainers.txt for the following packages:
> * Drivers/OptionRomPkg
> * Platform/BeagleBoard/BeagleBoardPkg
> * Platform/Intel/QuarkPlatformPkg
> * Platform/Intel/Vlv2TbltDevicePkg
> * Silicon/Intel/QuarkSocPkg
> * Silicon/Intel/Vlv2DeviceRefCodePkg
> * Silicon/TexasInsturments/Omap35xxPkg
> 
> Add the following platforms to Readme.md
> * BeagleBoard
> * MinnowBoard Max/Turbot
> * Galileo
> 
> Cc: Zailiang Sun <zailiang.sun@intel.com>
> Cc: Yi Qian <yi.qian@intel.com>
> Cc: Kelly Steele <kelly.steele@intel.com>
> Cc: Ray Ni <ray.ni@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>
> ---
>  Maintainers.txt | 20 ++++++++++++++++++++
>  Readme.md       |  9 +++++++++
>  2 files changed, 29 insertions(+)
> 
> diff --git a/Maintainers.txt b/Maintainers.txt index 6477591e68..7dd403a170
> 100644
> --- a/Maintainers.txt
> +++ b/Maintainers.txt
> @@ -38,12 +38,32 @@ W:
> https://github.com/tianocore/tianocore.github.io/wiki/Security
>  EDK II Packages:
>  ----------------
> 
> +Drivers/OptionRomPkg
> +W: https://github.com/tianocore/tianocore.github.io/wiki/OptionRomPkg
> +M: Ray Ni <ray.ni@intel.com>
> +
>  Platform
>  M: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>  M: Leif Lindholm <leif.lindholm@linaro.org>
>  M: Michael D Kinney <michael.d.kinney@intel.com>
> 
> +Platform/Intel/QuarkPlatformPkg
> +M: Michael D Kinney <michael.d.kinney@intel.com>
> +M: Kelly Steele <kelly.steele@intel.com>
> +
> +Platform/Intel/Vlv2TbltDevicePkg
> +M: Zailiang Sun <zailiang.sun@intel.com>
> +M: Yi Qian <yi.qian@intel.com>
> +
>  Silicon
>  M: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>  M: Leif Lindholm <leif.lindholm@linaro.org>
>  M: Michael D Kinney <michael.d.kinney@intel.com>
> +
> +Silicon/Intel/QuarkSocPkg
> +M: Michael D Kinney <michael.d.kinney@intel.com>
> +M: Kelly Steele <kelly.steele@intel.com>
> +
> +Silicon/Intel/Vlv2DeviceRefCodePkg
> +M: Zailiang Sun <zailiang.sun@intel.com>
> +M: Yi Qian <yi.qian@intel.com>
> diff --git a/Readme.md b/Readme.md
> index 95c0c14522..aac9f69d46 100644
> --- a/Readme.md
> +++ b/Readme.md
> @@ -208,6 +208,9 @@ they will be documented with the platform.
> 
>  ## [ARM](Platform/ARM/Readme.md)
> 
> +## BeagleBoard
> +* [BeagleBoard](Platform\BeagleBoard\BeagleBoardPkg)
> +
>  ## Hisilicon
>  * [D02](Platform/Hisilicon/D02)
>  * [D03](Platform/Hisilicon/D03)
> @@ -223,6 +226,12 @@ they will be documented with the platform.
>  ## Socionext
>  * [SynQuacer](Platform/Socionext/DeveloperBox)
> 
> +## Intel(R) Quark SoC X1000 based platforms
> +* [Galileo](Platform/Intel/QuarkPlatformPkg)
> +
> +## Minnowboard Max/Turbot based on Intel Valleyview2 SoC
> +* [Minnowboard Max](Platform/Intel/Vlv2TbltDevicePkg)
> +
>  # Maintainers
> 
>  See [Maintainers.txt](Maintainers.txt).
> --
> 2.21.0.windows.1


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [edk2-platforms: Patch 0/8] Add packages from edk2
  2019-05-10  3:34 [edk2-platforms: Patch 0/8] Add packages from edk2 Michael D Kinney
                   ` (9 preceding siblings ...)
  2019-05-11  2:12 ` Ni, Ray
@ 2019-05-13 21:03 ` Steele, Kelly
  10 siblings, 0 replies; 23+ messages in thread
From: Steele, Kelly @ 2019-05-13 21:03 UTC (permalink / raw)
  To: Kinney, Michael D, devel@edk2.groups.io
  Cc: Sun, Zailiang, Qian, Yi, Ni, Ray, Kubacki, Michael A,
	Leif Lindholm, Ard Biesheuvel



Reviewed-by: Kelly Steele <kelly.steele@intel.com>



> -----Original Message-----
> From: Kinney, Michael D
> Sent: May 09, 2019 20:34
> To: devel@edk2.groups.io
> Cc: Sun, Zailiang <zailiang.sun@intel.com>; Qian, Yi <yi.qian@intel.com>;
> Steele, Kelly <kelly.steele@intel.com>; Ni, Ray <ray.ni@intel.com>; Kubacki,
> Michael A <michael.a.kubacki@intel.com>; Leif Lindholm
> <leif.lindholm@linaro.org>; Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Subject: [edk2-platforms: Patch 0/8] Add packages from edk2
> 
> https://bugzilla.tianocore.org/show_bug.cgi?id=1467
> https://bugzilla.tianocore.org/show_bug.cgi?id=1374
> https://bugzilla.tianocore.org/show_bug.cgi?id=1793
> 
> Add the following platform, silicon, and driver packages from the edk2 repo
> to the edk2-platforms repo
> * Drivers/OptionRomPkg
> * Platform/BeagleBoard/BeagleBoardPkg
> * Platform/Intel/QuarkPlatformPkg
> * Platform/Intel/Vlv2TbltDevicePkg
> * Silicon/Intel/QuarkSocPkg
> * Silicon/Intel/Vlv2DeviceRefCodePkg
> * Silicon/TexasInsturments/Omap35xxPkg
> 
> Cc: Zailiang Sun <zailiang.sun@intel.com>
> Cc: Yi Qian <yi.qian@intel.com>
> Cc: Kelly Steele <kelly.steele@intel.com>
> Cc: Ray Ni <ray.ni@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>
> 
> Michael D Kinney (8):
>   Silicon/TexasInsturments: Import Omap35xxPkg from edk2
>   Platform/BeagleBoard: Import BeagleBoardPkg from edk2
>   Silicon/Intel: Import QuarkSocPkg from edk2
>   Platform/QuarkPlatformPkg: Import QuarkPlatformPkg from edk2
>   Platform/Vlv2DeviceRefCodePkg: Import Vlv2DeviceRefCodePkg from edk2
>   Platform/Vlv2TbltDevicePkg: Import Vlv2TbltDevicePkg from edk2
>   Drivers/OptionRomPkg: Import OptionRomPkg from edk2
>   edk2-platforms: Update Maintainers.txt/Readme.md for imported
> packages
> 
>  .../Application/BltLibSample/BltLibSample.c   |  279 +
>  .../Application/BltLibSample/BltLibSample.inf |   30 +
>  .../AtapiPassThruDxe/AtapiPassThru.c          | 3410 +++++++++++++
>  .../AtapiPassThruDxe/AtapiPassThru.h          | 1618 ++++++
>  .../AtapiPassThruDxe/AtapiPassThruDxe.inf     |   70 +
>  .../AtapiPassThruDxe/ComponentName.c          |  169 +
>  .../DriverSupportedEfiVersion.c               |   14 +
>  .../FtdiUsbSerialDxe/CompatibleDevices.txt    |    5 +
>  .../Bus/Usb/FtdiUsbSerialDxe/ComponentName.c  |  218 +
>  .../FtdiUsbSerialDxe/FtdiUsbSerialDriver.c    | 2580 ++++++++++
>  .../FtdiUsbSerialDxe/FtdiUsbSerialDriver.h    |  589 +++
>  .../Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf |   55 +
>  .../Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt       |   32 +
>  .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.c   | 1318 +++++
>  .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.h   |  969 ++++
>  .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf |   61 +
>  .../Usb/UsbNetworking/Ax88772/ComponentName.c |  178 +
>  .../Usb/UsbNetworking/Ax88772/DriverBinding.c |  507 ++
>  .../Usb/UsbNetworking/Ax88772/SimpleNetwork.c | 1503 ++++++
>  .../Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c  |  875 ++++
>  .../Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h  | 1026 ++++
>  .../Usb/UsbNetworking/Ax88772b/Ax88772b.inf   |   61 +
>  .../UsbNetworking/Ax88772b/ComponentName.c    |  175 +
>  .../UsbNetworking/Ax88772b/DriverBinding.c    |  696 +++
>  .../UsbNetworking/Ax88772b/SimpleNetwork.c    | 1657 ++++++
>  .../CirrusLogic5430Dxe/CirrusLogic5430.c      |  917 ++++
>  .../CirrusLogic5430Dxe/CirrusLogic5430.h      |  432 ++
>  .../CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf |   84 +
>  .../CirrusLogic5430GraphicsOutput.c           |  556 ++
>  .../CirrusLogic5430Dxe/CirrusLogic5430I2c.c   |  427 ++
>  .../CirrusLogic5430Dxe/CirrusLogic5430I2c.h   |   62 +
>  .../CirrusLogic5430UgaDraw.c                  |  412 ++
>  .../CirrusLogic5430Dxe/ComponentName.c        |  203 +
>  .../DriverSupportedEfiVersion.c               |   14 +
>  .../OptionRomPkg/CirrusLogic5430Dxe/Edid.c    |  525 ++
>  Drivers/OptionRomPkg/Include/Library/BltLib.h |  253 +
>  .../FrameBufferBltLib/FrameBufferBltLib.c     |  744 +++
>  .../FrameBufferBltLib/FrameBufferBltLib.inf   |   29 +
>  .../Library/GopBltLib/GopBltLib.c             |  449 ++
>  .../Library/GopBltLib/GopBltLib.inf           |   31 +
>  Drivers/OptionRomPkg/OptionRomPkg.dec         |   41 +
>  Drivers/OptionRomPkg/OptionRomPkg.dsc         |  113 +
>  Drivers/OptionRomPkg/ReadMe.txt               |   17 +
>  .../UndiRuntimeDxe/ComponentName.c            |  359 ++
>  Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c  | 1516 ++++++
>  Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c   | 3541 +++++++++++++
>  Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h   |  665 +++
>  Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c    | 1051 ++++
>  Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h  |  439 ++
>  .../OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c |  145 +
>  .../UndiRuntimeDxe/UndiRuntimeDxe.inf         |   72 +
>  Maintainers.txt                               |   20 +
>  .../BeagleBoardPkg/BeagleBoardPkg.dec         |   30 +
>  .../BeagleBoardPkg/BeagleBoardPkg.dsc         |  496 ++
>  .../BeagleBoardPkg/BeagleBoardPkg.fdf         |  308 ++
>  .../BeagleBoardPkg/ConfigurationHeader.bin    |  Bin 0 -> 512 bytes
>  .../BeagleBoardPkg/ConfigurationHeader.dat    |   41 +
>  .../Debugger_scripts/rvi_boot_from_ram.inc    |   15 +
>  .../Debugger_scripts/rvi_convert_symbols.sh   |   17 +
>  .../Debugger_scripts/rvi_dummy.axf            |  Bin 0 -> 7984 bytes
>  .../Debugger_scripts/rvi_hw_setup.inc         |   61 +
>  .../Debugger_scripts/rvi_load_symbols.inc     |   17 +
>  .../Debugger_scripts/rvi_symbols_macros.inc   |  188 +
>  .../Debugger_scripts/rvi_unload_symbols.inc   |  112 +
>  .../Debugger_scripts/trace32_load_symbols.cmm |  205 +
>  .../trace32_load_symbols_cygwin.cmm           |  182 +
>  .../BeagleBoardPkg/Include/BeagleBoard.h      |  173 +
>  .../Library/BeagleBoardLib/BeagleBoard.c      |  115 +
>  .../BeagleBoardLib/BeagleBoardHelper.S        |   41 +
>  .../BeagleBoardLib/BeagleBoardHelper.asm      |   47 +
>  .../Library/BeagleBoardLib/BeagleBoardLib.inf |   48 +
>  .../Library/BeagleBoardLib/BeagleBoardMem.c   |   74 +
>  .../Library/BeagleBoardLib/Clock.c            |   63 +
>  .../Library/BeagleBoardLib/PadConfiguration.c |  316 ++
>  .../Library/DxeHobPeCoffLib/DxeHobPeCoff.c    |  282 ++
>  .../DxeHobPeCoffLib/DxeHobPeCoffLib.inf       |   39 +
>  .../LzmaHobCustomDecompressLib.c              |   44 +
>  .../LzmaHobCustomDecompressLib.inf            |   45 +
>  .../MemoryInitPeiLib/MemoryInitPeiLib.c       |  192 +
>  .../MemoryInitPeiLib/MemoryInitPeiLib.inf     |   58 +
>  .../Library/ResetSystemLib/ResetSystemLib.c   |  149 +
>  .../Library/ResetSystemLib/ResetSystemLib.inf |   37 +
>  .../BeagleBoardPkg/PrePi/Arm/ArchPrePi.c      |   23 +
>  .../PrePi/Arm/ModuleEntryPoint.S              |  124 +
>  .../PrePi/Arm/ModuleEntryPoint.asm            |  142 +
>  .../BeagleBoardPkg/PrePi/LzmaDecompress.h     |   97 +
>  .../BeagleBoardPkg/PrePi/MainUniCore.c        |   33 +
>  .../BeagleBoardPkg/PrePi/PeiUniCore.inf       |   97 +
>  .../BeagleBoard/BeagleBoardPkg/PrePi/PrePi.c  |  179 +
>  .../BeagleBoard/BeagleBoardPkg/PrePi/PrePi.h  |   90 +
>  .../BeagleBoardPkg/Tools/GNUmakefile          |   14 +
>  .../BeagleBoardPkg/Tools/generate_image.c     |  402 ++
>  .../BeagleBoard/BeagleBoardPkg/Tools/makefile |   16 +
>  .../BeagleBoardPkg/Tools/replace.c            |  140 +
>  .../Acpi/AcpiTables/AcpiTables.inf            |   42 +
>  .../Acpi/AcpiTables/Cpu0Cst/Cpu0Cst.asl       |  399 ++
>  .../Acpi/AcpiTables/Cpu0Ist/Cpu0Ist.asl       |  159 +
>  .../Acpi/AcpiTables/Cpu0Tst/Cpu0Tst.asl       |  133 +
>  .../Acpi/AcpiTables/CpuPm/CpuPm.asl           |   73 +
>  .../Acpi/AcpiTables/Dsdt/AD7298.asi           |   38 +
>  .../Acpi/AcpiTables/Dsdt/ADC108S102.asi       |   33 +
>  .../Acpi/AcpiTables/Dsdt/CAT24C08.asi         |   34 +
>  .../Acpi/AcpiTables/Dsdt/CY8C9540A.asi        |   47 +
>  .../Acpi/AcpiTables/Dsdt/GpioClient.asi       |   89 +
>  .../Acpi/AcpiTables/Dsdt/LpcDev.asi           |  248 +
>  .../Acpi/AcpiTables/Dsdt/PCA9685.asi          |   34 +
>  .../Acpi/AcpiTables/Dsdt/PCAL9555A.asi        |   90 +
>  .../Acpi/AcpiTables/Dsdt/PciHostBridge.asi    |  195 +
>  .../Acpi/AcpiTables/Dsdt/PciIrq.asi           |  552 ++
>  .../Acpi/AcpiTables/Dsdt/PcieExpansionPrt.asi |  127 +
>  .../Acpi/AcpiTables/Dsdt/Platform.asl         |  347 ++
>  .../Acpi/AcpiTables/Dsdt/QNC.asi              |   49 +
>  .../Acpi/AcpiTables/Dsdt/QNCApic.asi          |   32 +
>  .../Acpi/AcpiTables/Dsdt/QNCLpc.asi           |   23 +
>  .../AcpiTables/Dsdt/QuarkSouthCluster.asi     |  110 +
>  .../Acpi/AcpiTables/Dsdt/Tpm.asi              |   45 +
>  .../Acpi/AcpiTables/Facs/Facs.aslc            |   74 +
>  .../Acpi/AcpiTables/Facs/Facs.h               |   29 +
>  .../Acpi/AcpiTables/Fadt/Fadt.h               |  102 +
>  .../Acpi/AcpiTables/Fadt/Fadt1.0.aslc         |   76 +
>  .../Acpi/AcpiTables/Fadt/Fadt2.0.aslc         |  157 +
>  .../Acpi/AcpiTables/Hpet/Hpet.aslc            |   68 +
>  .../Acpi/AcpiTables/Hpet/Hpet.h               |   45 +
>  .../Acpi/AcpiTables/Mcfg/Mcfg.aslc            |   75 +
>  .../Acpi/AcpiTables/Mcfg/Mcfg.h               |   56 +
>  .../Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.c     | 1402 +++++
>  .../Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.h     |  316 ++
>  .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.c      |  805 +++
>  .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.h      |  120 +
>  .../Acpi/Dxe/AcpiPlatform/AcpiPlatform.inf    |  196 +
>  .../Acpi/Dxe/AcpiPlatform/Madt.h              |  207 +
>  .../Acpi/Dxe/AcpiPlatform/MadtPlatform.c      |  300 ++
>  .../BootScriptExecutorDxe.inf                 |   77 +
>  .../Dxe/BootScriptExecutorDxe/IA32/S3Asm.S    |   44 +
>  .../Dxe/BootScriptExecutorDxe/IA32/S3Asm.asm  |   51 +
>  .../BootScriptExecutorDxe/IA32/SetIdtEntry.c  |   57 +
>  .../Dxe/BootScriptExecutorDxe/ScriptExecute.c |  379 ++
>  .../Dxe/BootScriptExecutorDxe/ScriptExecute.h |   70 +
>  .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.c     | 1011 ++++
>  .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.h     |  167 +
>  .../Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatform.inf   |   78 +
>  .../Acpi/DxeSmm/SmmPowerManagement/Ppm.c      |  372 ++
>  .../Acpi/DxeSmm/SmmPowerManagement/Ppm.h      |  150 +
>  .../SmmPowerManagement/SmmPowerManagement.c   |  113 +
>  .../SmmPowerManagement/SmmPowerManagement.h   |   52 +
>  .../SmmPowerManagement/SmmPowerManagement.inf |   74 +
>  .../Application/ForceRecovery/ForceRecovery.c |   47 +
>  .../ForceRecovery/ForceRecovery.inf           |   34 +
>  .../PlatformFlashAccessLibDxe.c               |  262 +
>  .../PlatformFlashAccessLibDxe.inf             |   47 +
>  .../PlatformFlashAccessLib/SpiFlashDevice.c   |  330 ++
>  .../PlatformFlashAccessLib/SpiFlashDevice.h   |  180 +
>  .../SystemFirmwareDescriptor.aslc             |   83 +
>  .../SystemFirmwareDescriptor.inf              |   40 +
>  .../SystemFirmwareDescriptorPei.c             |   60 +
>  .../SystemFirmwareUpdateConfig.ini            |   57 +
>  .../Include/Guid/CapsuleOnDataCD.h            |   23 +
>  .../Include/Guid/CapsuleOnFatFloppyDisk.h     |   23 +
>  .../Include/Guid/CapsuleOnFatIdeDisk.h        |   24 +
>  .../Include/Guid/CapsuleOnFatUsbDisk.h        |   24 +
>  .../Include/Guid/MemoryConfigData.h           |   23 +
>  .../Include/Guid/QuarkCapsuleGuid.h           |   46 +
>  .../Include/Guid/QuarkVariableLock.h          |   23 +
>  .../Include/Guid/SystemNvDataHobGuid.h        |   29 +
>  .../Include/Library/PlatformHelperLib.h       |  266 +
>  .../Include/Library/PlatformPcieHelperLib.h   |   56 +
>  .../Intel/QuarkPlatformPkg/Include/Pcal9555.h |   24 +
>  .../Intel/QuarkPlatformPkg/Include/Platform.h |  119 +
>  .../QuarkPlatformPkg/Include/PlatformBoards.h |  166 +
>  .../Include/Protocol/GlobalNvsArea.h          |   82 +
>  .../Include/Protocol/PlatformSmmSpiReady.h    |   23 +
>  .../PlatformBootManager.c                     |  472 ++
>  .../PlatformBootManager.h                     |   49 +
>  .../PlatformBootManagerLib.inf                |   83 +
>  .../PlatformBootManagerLib/PlatformData.c     |  275 +
>  .../Library/PlatformHelperLib/CommonHeader.h  |   51 +
>  .../DxePlatformHelperLib.inf                  |   70 +
>  .../PeiPlatformHelperLib.inf                  |   45 +
>  .../PlatformHelperLib/PlatformHelperDxe.c     |  337 ++
>  .../PlatformHelperLib/PlatformHelperLib.c     |  481 ++
>  .../PlatformHelperLib/PlatformHelperPei.c     |  159 +
>  .../Library/PlatformHelperLib/PlatformLeds.c  |  146 +
>  .../PlatformPcieHelperLib/CommonHeader.h      |   55 +
>  .../PlatformPcieHelperLib.c                   |  114 +
>  .../PlatformPcieHelperLib.inf                 |   41 +
>  .../Library/PlatformPcieHelperLib/SocUnit.c   |  125 +
>  .../Library/PlatformSecLib/Ia32/Flat32.S      |  796 +++
>  .../Library/PlatformSecLib/Ia32/Flat32.asm    |  685 +++
>  .../Library/PlatformSecLib/Ia32/Platform.inc  |  134 +
>  .../Library/PlatformSecLib/PlatformSecLib.c   |  207 +
>  .../Library/PlatformSecLib/PlatformSecLib.inf |   54 +
>  .../PlatformSecLib/PlatformSecLibModStrs.uni  |   18 +
>  .../PlatformSecureLib/PlatformSecureLib.c     |  164 +
>  .../PlatformSecureLib/PlatformSecureLib.inf   |   41 +
>  .../Library/Tpm12DeviceLibAtmelI2c/TisPc.c    |  408 ++
>  .../Tpm12DeviceLibAtmelI2c.inf                |   39 +
>  .../Tpm12DeviceLibAtmelI2c.uni                |   16 +
>  .../Library/Tpm12DeviceLibInfineonI2c/TisPc.c |  612 +++
>  .../Tpm12DeviceLibInfineonI2c.inf             |   39 +
>  .../Tpm12DeviceLibInfineonI2c.uni             |   16 +
>  .../Pci/Dxe/PciHostBridge/PciHostBridge.c     | 1397 +++++
>  .../Pci/Dxe/PciHostBridge/PciHostBridge.h     |  389 ++
>  .../Pci/Dxe/PciHostBridge/PciHostBridge.inf   |   61 +
>  .../Dxe/PciHostBridge/PciHostBridgeSupport.c  |  140 +
>  .../Pci/Dxe/PciHostBridge/PciHostResource.h   |   60 +
>  .../Pci/Dxe/PciHostBridge/PciRootBridge.h     |  693 +++
>  .../Pci/Dxe/PciHostBridge/PciRootBridgeIo.c   | 1610 ++++++
>  .../Pci/Dxe/PciPlatform/CommonHeader.h        |   31 +
>  .../Pci/Dxe/PciPlatform/PciPlatform.c         |  194 +
>  .../Pci/Dxe/PciPlatform/PciPlatform.h         |   82 +
>  .../Pci/Dxe/PciPlatform/PciPlatform.inf       |   54 +
>  .../Dxe/MemorySubClass/MemorySubClass.c       |  435 ++
>  .../Dxe/MemorySubClass/MemorySubClass.h       |   65 +
>  .../Dxe/MemorySubClass/MemorySubClass.inf     |   60 +
>  .../MemorySubClass/MemorySubClassStrings.uni  |   29 +
>  .../Dxe/PlatformInit/PlatformConfig.c         |  443 ++
>  .../Dxe/PlatformInit/PlatformInitDxe.c        |   87 +
>  .../Dxe/PlatformInit/PlatformInitDxe.h        |   58 +
>  .../Dxe/PlatformInit/PlatformInitDxe.inf      |   56 +
>  .../Dxe/SaveMemoryConfig/SaveMemoryConfig.c   |  118 +
>  .../Dxe/SaveMemoryConfig/SaveMemoryConfig.inf |   44 +
>  .../Platform/Dxe/Setup/CommonHeader.h         |   55 +
>  .../Platform/Dxe/Setup/DxePlatform.inf        |   76 +
>  .../Platform/Dxe/Setup/KeyboardLayout.c       |  262 +
>  .../Platform/Dxe/Setup/QNCRegTable.c          |   80 +
>  .../Platform/Dxe/Setup/SetupPlatform.c        |   97 +
>  .../Platform/Dxe/Setup/SetupPlatform.h        |   71 +
>  .../Platform/Dxe/Setup/Strings.uni            |   47 +
>  .../Platform/Dxe/Setup/processor.c            |   40 +
>  .../Platform/Dxe/SmbiosMiscDxe/CommonHeader.h |   34 +
>  .../MiscBaseBoardManufacturer.uni             |   19 +
>  .../MiscBaseBoardManufacturerData.c           |   45 +
>  .../MiscBaseBoardManufacturerFunction.c       |  181 +
>  .../Dxe/SmbiosMiscDxe/MiscBiosVendor.uni      |   18 +
>  .../Dxe/SmbiosMiscDxe/MiscBiosVendorData.c    |   92 +
>  .../SmbiosMiscDxe/MiscBiosVendorFunction.c    |  222 +
>  .../SmbiosMiscDxe/MiscBootInformationData.c   |   24 +
>  .../MiscBootInformationFunction.c             |   71 +
>  .../SmbiosMiscDxe/MiscChassisManufacturer.uni |   17 +
>  .../MiscChassisManufacturerData.c             |   36 +
>  .../MiscChassisManufacturerFunction.c         |  168 +
>  .../Dxe/SmbiosMiscDxe/MiscDevicePath.h        |   42 +
>  .../MiscNumberOfInstallableLanguagesData.c    |   28 +
>  ...MiscNumberOfInstallableLanguagesFunction.c |  240 +
>  .../Dxe/SmbiosMiscDxe/MiscOemString.uni       |   12 +
>  .../Dxe/SmbiosMiscDxe/MiscOemStringData.c     |   20 +
>  .../Dxe/SmbiosMiscDxe/MiscOemStringFunction.c |   78 +
>  .../Dxe/SmbiosMiscDxe/MiscOnboardDevice.uni   |   18 +
>  .../Dxe/SmbiosMiscDxe/MiscOnboardDeviceData.c |   49 +
>  .../SmbiosMiscDxe/MiscOnboardDeviceFunction.c |  105 +
>  .../MiscPortInternalConnectorDesignator.uni   |   53 +
>  .../MiscPortInternalConnectorDesignatorData.c |  184 +
>  ...cPortInternalConnectorDesignatorFunction.c |  292 ++
>  .../SmbiosMiscDxe/MiscSystemManufacturer.uni  |   20 +
>  .../MiscSystemManufacturerData.c              |   32 +
>  .../MiscSystemManufacturerFunction.c          |  198 +
>  .../SmbiosMiscDxe/MiscSystemOptionString.uni  |   14 +
>  .../MiscSystemOptionStringData.c              |   23 +
>  .../MiscSystemOptionStringFunction.c          |   81 +
>  .../MiscSystemSlotDesignation.uni             |   27 +
>  .../MiscSystemSlotDesignationData.c           |  357 ++
>  .../MiscSystemSlotDesignationFunction.c       |  285 ++
>  .../MiscSystemSlotOnboardDevices.uni          |   23 +
>  .../Platform/Dxe/SmbiosMiscDxe/SmbiosMisc.h   |  137 +
>  .../Dxe/SmbiosMiscDxe/SmbiosMiscDataTable.c   |  109 +
>  .../Dxe/SmbiosMiscDxe/SmbiosMiscDxe.inf       |  308 ++
>  .../Dxe/SmbiosMiscDxe/SmbiosMiscEntryPoint.c  |   82 +
>  .../Dxe/SmbiosMiscDxe/SmbiosMiscStrings.uni   |   26 +
>  .../Pei/PlatformConfig/PlatformConfigPei.c    |   81 +
>  .../Pei/PlatformConfig/PlatformConfigPei.inf  |   45 +
>  .../Platform/Pei/PlatformInit/BootMode.c      |  218 +
>  .../Platform/Pei/PlatformInit/CommonHeader.h  |   81 +
>  .../Pei/PlatformInit/Generic/Recovery.c       |  467 ++
>  .../Pei/PlatformInit/MemoryCallback.c         |  279 +
>  .../Platform/Pei/PlatformInit/MrcWrapper.c    | 1565 ++++++
>  .../Platform/Pei/PlatformInit/MrcWrapper.h    |  225 +
>  .../Platform/Pei/PlatformInit/PeiFvSecurity.c |  111 +
>  .../Platform/Pei/PlatformInit/PeiFvSecurity.h |   67 +
>  .../Pei/PlatformInit/PlatformEarlyInit.c      | 1227 +++++
>  .../Pei/PlatformInit/PlatformEarlyInit.h      |  301 ++
>  .../Pei/PlatformInit/PlatformEarlyInit.inf    |  193 +
>  .../Pei/PlatformInit/PlatformErratas.c        |  178 +
>  .../Platform/SpiFvbServices/FvbInfo.c         |  332 ++
>  .../Platform/SpiFvbServices/FwBlockService.c  | 2053 ++++++++
>  .../Platform/SpiFvbServices/FwBlockService.h  |  308 ++
>  .../Platform/SpiFvbServices/PlatformSmmSpi.c  |   31 +
>  .../SpiFvbServices/PlatformSmmSpi.inf         |   80 +
>  .../Platform/SpiFvbServices/PlatformSpi.inf   |   79 +
>  .../Platform/SpiFvbServices/SpiFlashDevice.c  |  331 ++
>  .../Platform/SpiFvbServices/SpiFlashDevice.h  |  181 +
>  Platform/Intel/QuarkPlatformPkg/Quark.dsc     |  948 ++++
>  Platform/Intel/QuarkPlatformPkg/Quark.fdf     |  907 ++++
>  Platform/Intel/QuarkPlatformPkg/QuarkMin.dsc  |  648 +++
>  Platform/Intel/QuarkPlatformPkg/QuarkMin.fdf  |  608 +++
>  .../QuarkPlatformPkg/QuarkPlatformPkg.dec     |  933 ++++
>  Platform/Intel/QuarkPlatformPkg/Readme.md     |  685 +++
>  Platform/Intel/Vlv2TbltDevicePkg/.gitignore   |    5 +
>  .../AcpiPlatform/AcpiPlatform.c               | 1338 +++++
>  .../AcpiPlatform/AcpiPlatform.h               |  219 +
>  .../AcpiPlatform/AcpiPlatform.inf             |   89 +
>  .../AcpiPlatform/AcpiPlatformHooks.c          |  493 ++
>  .../AcpiPlatform/AcpiPlatformHooks.h          |  127 +
>  .../AcpiPlatform/AcpiPlatformHooksLib.h       |   91 +
>  .../Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h     |   56 +
>  .../FirmwareUpdate/FirmwareUpdate.c           |  922 ++++
>  .../FirmwareUpdate/FirmwareUpdate.h           |  185 +
>  .../FirmwareUpdate/FirmwareUpdate.inf         |   83 +
>  .../FirmwareUpdate/FirmwareUpdateStrings.uni  |   45 +
>  Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe   |  Bin 0 -> 499712 bytes
>  Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env  |   25 +
>  Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env  |   25 +
>  .../Intel/Vlv2TbltDevicePkg/BiosIdx64D.env    |   25 +
>  .../Intel/Vlv2TbltDevicePkg/BiosIdx64R.env    |   25 +
>  .../BootScriptSaveDxe/BootScriptSaveDxe.inf   |   60 +
>  .../InternalBootScriptSave.h                  |  102 +
>  .../BootScriptSaveDxe/ScriptSave.c            |  626 +++
>  .../Intel/Vlv2TbltDevicePkg/Build_IFWI.bat    |  200 +
>  .../Intel/Vlv2TbltDevicePkg/Build_IFWI.sh     |  104 +
>  Platform/Intel/Vlv2TbltDevicePkg/FCE.exe      |  Bin 0 -> 632832 bytes
>  .../Capsule/GenerateCapsule/GenCapsuleAll.bat |   35 +
>  .../Capsule/GenerateCapsule/GenCapsuleAll.sh  |   28 +
>  .../GenerateCapsule/GenCapsuleMinnowMax.bat   |  131 +
>  .../GenerateCapsule/GenCapsuleMinnowMax.sh    |   65 +
>  .../GenCapsuleMinnowMaxRelease.bat            |  131 +
>  .../GenCapsuleMinnowMaxRelease.sh             |   65 +
>  .../GenerateCapsule/GenCapsuleSampleColor.bat |  137 +
>  .../GenerateCapsule/GenCapsuleSampleColor.sh  |   70 +
>  .../Feature/Capsule/GenerateCapsule/Lvfs.ddf  |   14 +
>  .../LvfsGenCapsuleMinnowMax.bat               |  139 +
>  .../LvfsGenCapsuleMinnowMaxRelease.bat        |  139 +
>  .../LvfsGenCapsuleSampleColor.bat             |  145 +
>  ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
>  ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
>  ...aceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc |    1 +
>  .../GenerateCapsule/template.metainfo.xml     |   27 +
>  .../Library/FmpDeviceLib/FmpDeviceLib.c       |  589 +++
>  .../Library/FmpDeviceLib/FmpDeviceLib.inf     |   46 +
>  .../Library/FmpDeviceLibSample/FmpDeviceLib.c |  412 ++
>  .../FmpDeviceLibSample/FmpDeviceLib.inf       |   34 +
>  .../PlatformFlashAccessLib.c                  |  685 +++
>  .../PlatformFlashAccessLib.inf                |   54 +
>  .../SystemFirmwareDescriptor.aslc             |   83 +
>  .../SystemFirmwareDescriptor.inf              |   40 +
>  .../SystemFirmwareDescriptorPei.c             |   60 +
>  .../SystemFirmwareUpdateConfig.ini            |   66 +
>  .../SystemFirmwareUpdateConfigGcc.ini         |   66 +
>  .../Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc |   55 +
>  .../Vlv2TbltDevicePkg/FmpCertificate.dsc      |   22 +
>  .../FmpGreenSampleDevice.dsc                  |   55 +
>  .../Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc  |   59 +
>  .../Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc  |   55 +
>  .../FspAzaliaConfigData/AzaliaConfig.bin      |  Bin 0 -> 3708 bytes
>  .../FspSupport/BootModePei/BootModePei.c      |   42 +
>  .../FspSupport/BootModePei/BootModePei.inf    |   40 +
>  .../FspHobProcessLibVlv2.c                    |  421 ++
>  .../FspHobProcessLibVlv2.inf                  |   74 +
>  .../FspPlatformSecLibVlv2.c                   |  144 +
>  .../FspPlatformSecLibVlv2.inf                 |   82 +
>  .../Ia32/AsmSaveSecContext.asm                |   45 +
>  .../SecFspPlatformSecLibVlv2/Ia32/Fsp.inc     |   45 +
>  .../Ia32/PeiCoreEntry.asm                     |  135 +
>  .../Ia32/SecEntry.asm                         |  338 ++
>  .../SecFspPlatformSecLibVlv2/Ia32/Stack.S     |   71 +
>  .../SecFspPlatformSecLibVlv2/Ia32/Stack.asm   |   76 +
>  .../SecFspPlatformSecLibVlv2/PlatformInit.c   |   36 +
>  .../SecFspPlatformSecLibVlv2/SaveSecContext.c |  108 +
>  .../SecGetPerformance.c                       |   83 +
>  .../SecPlatformInformation.c                  |   77 +
>  .../SecFspPlatformSecLibVlv2/SecRamInitData.c |   16 +
>  .../SecTempRamSupport.c                       |  149 +
>  .../SecFspPlatformSecLibVlv2/UartInit.c       |  192 +
>  .../Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c   |   68 +
>  .../Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf |   49 +
>  .../Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c |  170 +
>  .../FvbRuntimeDxe/FvbRuntimeDxe.inf           |   80 +
>  .../FvbRuntimeDxe/FvbService.c                | 1098 ++++
>  .../FvbRuntimeDxe/FvbService.h                |  182 +
>  .../FvbRuntimeDxe/FvbServiceDxe.c             |  199 +
>  .../FvbRuntimeDxe/FvbServiceSmm.c             |  127 +
>  .../FvbRuntimeDxe/FvbSmm.inf                  |   82 +
>  .../FvbRuntimeDxe/FvbSmmCommon.h              |   73 +
>  .../FvbRuntimeDxe/FvbSmmDxe.c                 |  944 ++++
>  .../FvbRuntimeDxe/FvbSmmDxe.h                 |  232 +
>  .../FvbRuntimeDxe/FvbSmmDxe.inf               |   50 +
>  Platform/Intel/Vlv2TbltDevicePkg/GenBiosId    |  Bin 0 -> 12236 bytes
>  .../Intel/Vlv2TbltDevicePkg/GenBiosId.exe     |  Bin 0 -> 384000 bytes
>  .../Include/AlertStandardFormatTable.h        |  122 +
>  .../Vlv2TbltDevicePkg/Include/ChipsetAccess.h |   28 +
>  .../Include/CommonIncludes.h                  |  115 +
>  .../Intel/Vlv2TbltDevicePkg/Include/CpuType.h |   59 +
>  .../Vlv2TbltDevicePkg/Include/FileHandleLib.h |  499 ++
>  .../Include/Guid/AcpiTableStorage.h           |   30 +
>  .../Include/Guid/AlertStandardFormat.h        |   86 +
>  .../Vlv2TbltDevicePkg/Include/Guid/BiosId.h   |   30 +
>  .../Include/Guid/BoardFeatures.h              |  214 +
>  .../Include/Guid/EfiVpdData.h                 |  156 +
>  .../Include/Guid/FirmwareId.h                 |   61 +
>  .../Include/Guid/HwWatchdogTimerHob.h         |  134 +
>  .../Vlv2TbltDevicePkg/Include/Guid/IdccData.h |  104 +
>  .../Vlv2TbltDevicePkg/Include/Guid/ItkData.h  |   70 +
>  .../Include/Guid/MemoryConfigData.h           |   32 +
>  .../Include/Guid/OsSelection.h                |   85 +
>  .../Include/Guid/PciLanInfo.h                 |   39 +
>  .../Include/Guid/PlatformCpuInfo.h            |  180 +
>  .../Include/Guid/PlatformInfo.h               |  433 ++
>  .../Include/Guid/SensorInfoVariable.h         |  279 +
>  .../Include/Guid/SetupVariable.h              | 1344 +++++
>  .../Intel/Vlv2TbltDevicePkg/Include/Hpet.h    |   40 +
>  .../Include/Library/BiosIdLib.h               |  104 +
>  .../Include/Library/CpuIA32.h                 |  345 ++
>  .../Include/Library/EfiRegTableLib.h          |  196 +
>  .../Vlv2TbltDevicePkg/Include/Library/Esrt.h  |   74 +
>  .../Vlv2TbltDevicePkg/Include/Library/Fd.h    |  264 +
>  .../Include/Library/FlashDeviceLib.h          |  122 +
>  .../Include/Library/I2CLib.h                  |   58 +
>  .../Include/Library/I2cMmioConfigLib.h        |   23 +
>  .../Include/Library/I2cPort_platform.h        |   26 +
>  .../Include/Library/PlatformFsaLib.h          |   50 +
>  .../Include/Library/PlatformFspLib.h          |   23 +
>  .../Include/Library/SpiFlash.H                |  239 +
>  .../Include/Library/StallSmmLib.h             |   40 +
>  .../Include/Library/UsbDeviceModeLib.h        |  181 +
>  .../Intel/Vlv2TbltDevicePkg/Include/Mcfg.h    |   69 +
>  .../Vlv2TbltDevicePkg/Include/McfgTable.h     |   65 +
>  .../Vlv2TbltDevicePkg/Include/Platform.h      |  133 +
>  .../Include/PlatformBootMode.h                |   35 +
>  .../Include/PlatformDefinitions.h             |   43 +
>  .../Include/Ppi/MfgMemoryTest.h               |   42 +
>  .../Include/Ppi/Sha256Hash.h                  |  131 +
>  .../Vlv2TbltDevicePkg/Include/Ppi/Speaker.h   |   65 +
>  .../Include/Ppi/UsbController.h               |   85 +
>  .../Include/Protocol/CK505ClockPlatformInfo.h |  126 +
>  .../Include/Protocol/EnhancedSpeedstep.h      |   76 +
>  .../Include/Protocol/GlobalNvsArea.h          |  475 ++
>  .../Include/Protocol/HwWatchdogTimer.h        |  235 +
>  .../Include/Protocol/I2cAcpi.h                |  107 +
>  .../Include/Protocol/I2cBus.h                 |  164 +
>  .../Include/Protocol/I2cBusMcg.h              |  163 +
>  .../Include/Protocol/I2cHostMcg.h             |  138 +
>  .../Include/Protocol/I2cMasterMcg.h           |  519 ++
>  .../Include/Protocol/I2cSlave.h               |  194 +
>  .../Include/Protocol/LpcWpc83627Policy.h      |   92 +
>  .../Include/Protocol/LpcWpce791Policy.h       |   55 +
>  .../Include/Protocol/MmioDevice.h             |   84 +
>  .../Include/Protocol/Observable.h             |  186 +
>  .../Include/Protocol/PlatformGopPolicy.h      |   68 +
>  .../Include/Protocol/PlatformIdeInit.h        |   43 +
>  .../Include/Protocol/SetupMode.h              |   79 +
>  .../Include/Protocol/SmbiosSlotPopulation.h   |   47 +
>  .../Include/Protocol/Speaker.h                |   65 +
>  .../Include/Protocol/TcoReset.h               |   67 +
>  .../Include/Protocol/TpmMp.h                  |  136 +
>  .../Include/Protocol/UsbPolicy.h              |  126 +
>  .../Include/Protocol/VlvPlatformPolicy.h      |  102 +
>  .../Vlv2TbltDevicePkg/Include/SetupMode.h     |   85 +
>  .../IntelGopDepex/IntelGopDriver.depex        |    1 +
>  .../Library/BiosIdLib/BiosIdLib.c             |  337 ++
>  .../Library/BiosIdLib/BiosIdLib.inf           |   50 +
>  .../Library/CpuIA32Lib/CpuIA32Lib.inf         |   41 +
>  .../Library/CpuIA32Lib/EfiCpuVersion.c        |   70 +
>  .../Library/CpuIA32Lib/IA32/CpuIA32.S         |  223 +
>  .../Library/CpuIA32Lib/IA32/CpuIA32.asm       |  206 +
>  .../Library/CpuIA32Lib/IA32/CpuIA32.c         |  177 +
>  .../Library/CpuIA32Lib/X64/Cpu.S              |  207 +
>  .../Library/CpuIA32Lib/X64/Cpu.asm            |  222 +
>  .../Library/EfiRegTableLib/EfiRegTableLib.c   |  282 ++
>  .../Library/EfiRegTableLib/EfiRegTableLib.inf |   47 +
>  .../Library/FlashDeviceLib/FlashDeviceLib.c   |  461 ++
>  .../Library/FlashDeviceLib/FlashDeviceLib.inf |   44 +
>  .../FlashDeviceLib/FlashDeviceLibDxe.c        |   56 +
>  .../FlashDeviceLib/FlashDeviceLibDxe.inf      |   43 +
>  .../FlashDeviceLibDxeRuntimeSmm.c             |  173 +
>  .../FlashDeviceLib/SpiChipDefinitions.h       |  835 +++
>  .../Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c |   46 +
>  .../Library/I2CLib/I2CLibNull.inf             |   39 +
>  .../Library/I2CLibDxe/I2CLib.c                |  735 +++
>  .../Library/I2CLibDxe/I2CLibDxe.inf           |   39 +
>  .../Library/I2CLibDxe/I2CRegs.h               |  126 +
>  .../Library/I2CLibPei/I2CAccess.h             |   44 +
>  .../Library/I2CLibPei/I2CDelayPei.c           |   46 +
>  .../Library/I2CLibPei/I2CDelayPei.h           |   30 +
>  .../Library/I2CLibPei/I2CIoLibPei.c           |  178 +
>  .../Library/I2CLibPei/I2CIoLibPei.h           |  153 +
>  .../Library/I2CLibPei/I2CLibPei.c             |  638 +++
>  .../Library/I2CLibPei/I2CLibPei.h             |  280 +
>  .../Library/I2CLibPei/I2CLibPei.inf           |   40 +
>  .../IntelPchAcpiTimerLib/CommonHeader.h       |   27 +
>  .../IntelPchAcpiTimerLib.c                    |  255 +
>  .../IntelPchAcpiTimerLib.inf                  |   51 +
>  .../BoardClkGens/BoardClkGens.c               |  430 ++
>  .../BoardClkGens/BoardClkGens.h               |  255 +
>  .../MultiPlatformLib/BoardGpios/BoardGpios.c  |  531 ++
>  .../MultiPlatformLib/BoardGpios/BoardGpios.h  |  324 ++
>  .../BoardJumpers/BoardJumpers.c               |   30 +
>  .../BoardJumpers/BoardJumpers.h               |   30 +
>  .../BoardOemIds/BoardOemIds.c                 |   43 +
>  .../BoardOemIds/BoardOemIds.h                 |   29 +
>  .../BoardSsidSvid/BoardSsidSvid.c             |   38 +
>  .../BoardSsidSvid/BoardSsidSvid.h             |   35 +
>  .../MultiPlatformLib/MultiPlatformLib.c       |  120 +
>  .../MultiPlatformLib/MultiPlatformLib.h       |   89 +
>  .../MultiPlatformLib/MultiPlatformLib.inf     |   77 +
>  .../MultiPlatformLib/PlatformInfoHob.c        |   54 +
>  .../Library/PchPlatformLib/PchPlatformLib.inf |   50 +
>  .../PchPlatformLib/PchPlatformLibrary.c       |  131 +
>  .../PchPlatformLib/PchPlatformLibrary.h       |   35 +
>  .../Library/PchSmmLib/CommonHeader.h          |   32 +
>  .../Library/PchSmmLib/PchSmmLib.c             |  157 +
>  .../Library/PchSmmLib/PchSmmLib.inf           |   46 +
>  .../Library/PlatformBdsLib/BdsPlatform.c      | 3098 ++++++++++++
>  .../Library/PlatformBdsLib/BdsPlatform.h      |  516 ++
>  .../Library/PlatformBdsLib/PlatformBdsLib.inf |  127 +
>  .../PlatformBdsLib/PlatformBdsStrings.uni     |   30 +
>  .../Library/PlatformBdsLib/PlatformData.c     |  306 ++
>  .../Library/PlatformCmosLib/PlatformCmosLib.c |  106 +
>  .../PlatformCmosLib/PlatformCmosLib.inf       |   30 +
>  .../Library/PlatformFspLib/PlatformFspLib.c   |   44 +
>  .../Library/PlatformFspLib/PlatformFspLib.inf |   49 +
>  .../Library/ResetSystemLib/ResetSystemLib.c   |  235 +
>  .../Library/ResetSystemLib/ResetSystemLib.inf |   47 +
>  .../SerialPortLib/PlatformSerialPortLib.h     |   53 +
>  .../Library/SerialPortLib/SerialPortLib.c     |  246 +
>  .../Library/SerialPortLib/SerialPortLib.inf   |   52 +
>  .../Library/SerialPortLib/SioInit.c           |  127 +
>  .../Library/SerialPortLib/SioInit.h           |   62 +
>  .../Library/SmbusLib/CommonHeader.h           |   26 +
>  .../Library/SmbusLib/SmbusLib.c               |  873 ++++
>  .../Library/SmbusLib/SmbusLib.inf             |   46 +
>  .../Library/StallSmmLib/StallSmm.c            |   89 +
>  .../Library/StallSmmLib/StallSmmLib.inf       |   51 +
>  .../Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.c    |  117 +
>  .../Tpm2DeviceLibSeCDxe/Tpm2DeviceLibSeC.inf  |   61 +
>  .../Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.c    |  145 +
>  .../Tpm2DeviceLibSeCPei/Tpm2DeviceLibSeC.inf  |   60 +
>  .../Intel/Vlv2TbltDevicePkg/Logo/Logo.bmp     |  Bin 0 -> 94434 bytes
>  .../Metronome/LegacyMetronome.c               |  185 +
>  .../Metronome/LegacyMetronome.h               |   64 +
>  .../Vlv2TbltDevicePkg/Metronome/Metronome.inf |   49 +
>  .../MonoStatusCode/EfiStatusCode.h            |  178 +
>  .../MonoStatusCode/MonoStatusCode.c           |  132 +
>  .../MonoStatusCode/MonoStatusCode.h           |  128 +
>  .../MonoStatusCode/MonoStatusCode.inf         |   72 +
>  .../MonoStatusCode/PeiPostCode.c              |  121 +
>  .../MonoStatusCode/PlatformStatusCode.c       |  381 ++
>  .../MonoStatusCode/PlatformStatusCode.h       |  138 +
>  .../Library/GenericBdsLib/BdsBoot.c           | 4490 +++++++++++++++++
>  .../Library/GenericBdsLib/BdsConnect.c        |  429 ++
>  .../Library/GenericBdsLib/BdsConsole.c        | 1061 ++++
>  .../Library/GenericBdsLib/BdsMisc.c           | 1575 ++++++
>  .../Library/GenericBdsLib/DevicePath.c        |   27 +
>  .../Library/GenericBdsLib/GenericBdsLib.inf   |  142 +
>  .../Library/GenericBdsLib/GenericBdsLib.uni   |   19 +
>  .../GenericBdsLib/GenericBdsStrings.uni       |   30 +
>  .../Library/GenericBdsLib/InternalBdsLib.h    |  173 +
>  .../Library/GenericBdsLib/String.c            |   26 +
>  .../Library/GenericBdsLib/String.h            |   42 +
>  .../PciPlatform/BoardPciPlatform.c            |   55 +
>  .../PciPlatform/PciPlatform.c                 |  367 ++
>  .../PciPlatform/PciPlatform.h                 |   83 +
>  .../PciPlatform/PciPlatform.inf               |   65 +
>  .../Vlv2TbltDevicePkg/PlatformCapsule.dsc     |   39 +
>  .../Vlv2TbltDevicePkg/PlatformCapsule.fdf     |   52 +
>  .../Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc  |   38 +
>  .../Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf  |   52 +
>  .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.c   |   60 +
>  .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.h   |   29 +
>  .../PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf |   55 +
>  .../PlatformDxe/AzaliaVerbTable.h             |  247 +
>  .../Vlv2TbltDevicePkg/PlatformDxe/BoardId.c   |  223 +
>  .../PlatformDxe/BoardIdDecode.c               |  129 +
>  .../PlatformDxe/BoardIdDecode.h               |   61 +
>  .../PlatformDxe/ClockControl.c                |  202 +
>  .../PlatformDxe/Configuration.h               |  692 +++
>  .../Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c |   89 +
>  .../PlatformDxe/IchPlatformPolicy.c           |  484 ++
>  .../PlatformDxe/IchRegTable.c                 |  134 +
>  .../PlatformDxe/IchTcoReset.c                 |  211 +
>  .../Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c  |   72 +
>  .../PlatformDxe/LegacySpeaker.c               |  161 +
>  .../PlatformDxe/LegacySpeaker.h               |   69 +
>  .../PlatformDxe/Observable/Observable.c       |  582 +++
>  .../PlatformDxe/Observable/Observable.h       |  137 +
>  .../Vlv2TbltDevicePkg/PlatformDxe/PciBus.h    |  379 ++
>  .../Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c |  506 ++
>  .../Vlv2TbltDevicePkg/PlatformDxe/Platform.c  | 1820 +++++++
>  .../PlatformDxe/PlatformDxe.h                 |  722 +++
>  .../PlatformDxe/PlatformDxe.inf               |  149 +
>  .../Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c |  154 +
>  .../Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c |  112 +
>  .../PlatformDxe/SioPlatformPolicy.c           |   82 +
>  .../PlatformDxe/SlotConfig.c                  |  148 +
>  .../PlatformDxe/SlotConfig.h                  |   80 +
>  .../PlatformGopPolicy/PlatformGopPolicy.c     |  201 +
>  .../PlatformGopPolicy/PlatformGopPolicy.inf   |   51 +
>  .../PlatformInfoDxe/PlatformInfoDxe.c         |  169 +
>  .../PlatformInfoDxe/PlatformInfoDxe.h         |   30 +
>  .../PlatformInfoDxe/PlatformInfoDxe.inf       |   52 +
>  .../PlatformInitPei/BootMode.c                |  434 ++
>  .../PlatformInitPei/CpuInitPeim.c             |   44 +
>  .../Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c  |  319 ++
>  .../PlatformInitPei/FlashMap.c                |  143 +
>  .../PlatformInitPei/LegacySpeaker.c           |  168 +
>  .../PlatformInitPei/LegacySpeaker.h           |   71 +
>  .../PlatformInitPei/MchInit.c                 |   72 +
>  .../PlatformInitPei/MemoryCallback.c          |  338 ++
>  .../PlatformInitPei/MemoryPeim.c              |  408 ++
>  .../PlatformInitPei/PchInitPeim.c             |  808 +++
>  .../PlatformInitPei/PlatformEarlyInit.c       | 1195 +++++
>  .../PlatformInitPei/PlatformEarlyInit.h       | 1499 ++++++
>  .../PlatformInitPei/PlatformInfoInit.c        |  181 +
>  .../PlatformInitPei/PlatformInitPei.inf       |  117 +
>  .../PlatformInitPei/PlatformSsaInitPeim.c     |   58 +
>  .../PlatformInitPei/Recovery.c                |  361 ++
>  .../Vlv2TbltDevicePkg/PlatformInitPei/Stall.c |   91 +
>  .../Vlv2TbltDevicePkg/PlatformPei/BootMode.c  |  346 ++
>  .../PlatformPei/CommonHeader.h                |   60 +
>  .../PlatformPei/MemoryCallback.c              |  154 +
>  .../Vlv2TbltDevicePkg/PlatformPei/Platform.c  | 1198 +++++
>  .../Vlv2TbltDevicePkg/PlatformPei/Platform.h  |  213 +
>  .../PlatformPei/PlatformPei.inf               |  129 +
>  .../Vlv2TbltDevicePkg/PlatformPei/Stall.c     |   90 +
>  .../Intel/Vlv2TbltDevicePkg/PlatformPkg.dec   |  211 +
>  .../Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf   | 1073 ++++
>  .../Vlv2TbltDevicePkg/PlatformPkgConfig.dsc   |  107 +
>  .../Vlv2TbltDevicePkg/PlatformPkgGcc.fdf      | 1033 ++++
>  .../Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc   | 1711 +++++++
>  .../Vlv2TbltDevicePkg/PlatformPkgIA32.dsc     | 1699 +++++++
>  .../Vlv2TbltDevicePkg/PlatformPkgX64.dsc      | 1714 +++++++
>  .../PlatformSetupDxe/Boot.vfi                 |   72 +
>  .../PlatformSetupDxe/Configuration.h          |   56 +
>  .../PlatformSetupDxe/DebugConfig.vfi          |  118 +
>  .../PlatformSetupDxe/FwVersionStrings.uni     |   40 +
>  .../PlatformSetupDxe/Main.vfi                 |  331 ++
>  .../PlatformSetupDxe/PlatformSetupDxe.c       |  929 ++++
>  .../PlatformSetupDxe/PlatformSetupDxe.h       |   97 +
>  .../PlatformSetupDxe/PlatformSetupDxe.inf     |  141 +
>  .../PlatformSetupDxe/Security.vfi             |  104 +
>  .../PlatformSetupDxe/SetupFunctions.c         |   85 +
>  .../PlatformSetupDxe/SetupInfoRecords.c       | 1855 +++++++
>  .../PlatformSetupDxe/SouthClusterConfig.vfi   |  933 ++++
>  .../PlatformSetupDxe/SystemComponent.vfi      |   81 +
>  .../PlatformSetupDxe/Thermal.vfi              |  106 +
>  .../PlatformSetupDxe/UnCore.vfi               |  235 +
>  .../PlatformSetupDxe/UqiList.uni              |  452 ++
>  .../PlatformSetupDxe/Vfr.vfr                  |  123 +
>  .../PlatformSetupDxe/VfrStrings.uni           | 1417 ++++++
>  .../Vlv2TbltDevicePkg/PlatformSmm/Platform.c  |  997 ++++
>  .../PlatformSmm/PlatformSmm.inf               |   93 +
>  .../Vlv2TbltDevicePkg/PlatformSmm/S3Save.c    |  377 ++
>  .../PlatformSmm/SmmPlatform.h                 |  240 +
>  .../PlatformSmm/SmmScriptSave.c               |  252 +
>  .../PlatformSmm/SmmScriptSave.h               |   50 +
>  .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c   |  148 +
>  .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h   |   36 +
>  .../Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf |   49 +
>  Platform/Intel/Vlv2TbltDevicePkg/Readme.md    |  233 +
>  .../SaveMemoryConfig/SaveMemoryConfig.c       |  181 +
>  .../SaveMemoryConfig/SaveMemoryConfig.h       |   66 +
>  .../SaveMemoryConfig/SaveMemoryConfig.inf     |   60 +
>  .../SmBiosMiscDxe/CommonHeader.h              |   39 +
>  .../MiscBaseBoardManufacturer.uni             |   33 +
>  .../MiscBaseBoardManufacturerData.c           |   58 +
>  .../MiscBaseBoardManufacturerFunction.c       |  238 +
>  .../SmBiosMiscDxe/MiscBiosVendor.uni          |   26 +
>  .../SmBiosMiscDxe/MiscBiosVendorData.c        |  101 +
>  .../SmBiosMiscDxe/MiscBiosVendorFunction.c    |  336 ++
>  .../SmBiosMiscDxe/MiscBootInformationData.c   |   34 +
>  .../MiscBootInformationFunction.c             |   82 +
>  .../SmBiosMiscDxe/MiscChassisManufacturer.uni |   28 +
>  .../MiscChassisManufacturerData.c             |   57 +
>  .../MiscChassisManufacturerFunction.c         |  158 +
>  .../SmBiosMiscDxe/MiscMemoryDevice.uni        |   35 +
>  .../SmBiosMiscDxe/MiscMemoryDeviceData.c      |   45 +
>  .../SmBiosMiscDxe/MiscMemoryDeviceFunction.c  |  319 ++
>  .../MiscNumberOfInstallableLanguagesData.c    |   38 +
>  ...MiscNumberOfInstallableLanguagesFunction.c |  251 +
>  .../SmBiosMiscDxe/MiscOemString.uni           |   25 +
>  .../SmBiosMiscDxe/MiscOemStringData.c         |   34 +
>  .../SmBiosMiscDxe/MiscOemStringFunction.c     |   89 +
>  .../SmBiosMiscDxe/MiscOemType0x90.uni         |   31 +
>  .../SmBiosMiscDxe/MiscOemType0x90Data.c       |   36 +
>  .../SmBiosMiscDxe/MiscOemType0x90Function.c   |  442 ++
>  .../SmBiosMiscDxe/MiscOemType0x94.uni         |   42 +
>  .../SmBiosMiscDxe/MiscOemType0x94Data.c       |   54 +
>  .../SmBiosMiscDxe/MiscOemType0x94Function.c   | 1218 +++++
>  .../SmBiosMiscDxe/MiscOnboardDevice.uni       |   26 +
>  .../SmBiosMiscDxe/MiscOnboardDeviceData.c     |   48 +
>  .../SmBiosMiscDxe/MiscOnboardDeviceFunction.c |  135 +
>  .../SmBiosMiscDxe/MiscPhysicalArray.uni       |   25 +
>  .../SmBiosMiscDxe/MiscPhysicalArrayData.c     |   38 +
>  .../SmBiosMiscDxe/MiscPhysicalArrayFunction.c |  101 +
>  .../MiscPortInternalConnectorDesignator.uni   |   31 +
>  .../MiscPortInternalConnectorDesignatorData.c |   56 +
>  ...cPortInternalConnectorDesignatorFunction.c |  152 +
>  .../SmBiosMiscDxe/MiscProcessorCache.uni      |   22 +
>  .../SmBiosMiscDxe/MiscProcessorCacheData.c    |   33 +
>  .../MiscProcessorCacheFunction.c              |  189 +
>  .../MiscProcessorInformation.uni              |   27 +
>  .../MiscProcessorInformationData.c            |   71 +
>  .../MiscProcessorInformationFunction.c        |  448 ++
>  .../SmBiosMiscDxe/MiscResetCapabilitiesData.c |   43 +
>  .../MiscResetCapabilitiesFunction.c           |   85 +
>  .../SmBiosMiscDxe/MiscSubclassDriver.h        |  188 +
>  .../SmBiosMiscDxe/MiscSubclassDriver.uni      |   35 +
>  .../MiscSubclassDriverDataTable.c             |   98 +
>  .../MiscSubclassDriverEntryPoint.c            |  182 +
>  .../MiscSystemLanguageString.uni              |   24 +
>  .../MiscSystemLanguageStringData.c            |   34 +
>  .../MiscSystemLanguageStringFunction.c        |   93 +
>  .../SmBiosMiscDxe/MiscSystemManufacturer.uni  |   30 +
>  .../MiscSystemManufacturerData.c              |   48 +
>  .../MiscSystemManufacturerFunction.c          |  364 ++
>  .../SmBiosMiscDxe/MiscSystemOptionString.uni  |   24 +
>  .../MiscSystemOptionStringData.c              |   31 +
>  .../MiscSystemOptionStringFunction.c          |   93 +
>  .../MiscSystemSlotDesignation.uni             |   34 +
>  .../MiscSystemSlotDesignationData.c           |  246 +
>  .../MiscSystemSlotDesignationFunction.c       |  127 +
>  .../SmBiosMiscDxe/SmBiosMiscDxe.inf           |  139 +
>  .../SmmSwDispatch2OnSmmSwDispatchThunk.c      |  459 ++
>  .../SmmSwDispatch2OnSmmSwDispatchThunk.inf    |   54 +
>  .../SmramSaveInfoHandlerSmm.c                 |  164 +
>  .../SmramSaveInfoHandlerSmm.inf               |   60 +
>  .../Stitch/Gcc/NvStorageFtwSpare.bin          |  Bin 0 -> 262144 bytes
>  .../Stitch/Gcc/NvStorageFtwWorking.bin        |  Bin 0 -> 8192 bytes
>  .../Stitch/Gcc/NvStorageVariable.bin          |  Bin 0 -> 253952 bytes
>  .../Stitch/IFWIHeader/IFWI_HEADER.bin         |  Bin 0 -> 4096 bytes
>  .../Stitch/IFWIHeader/IFWI_HEADER_SPILOCK.bin |  Bin 0 -> 4096 bytes
>  .../Stitch/IFWIHeader/Vacant.bin              |  Bin 0 -> 3928064 bytes
>  .../Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat   |  270 +
>  .../Stitch/MNW2_Stitch_Config.txt             |   10 +
>  .../Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c |   33 +
>  .../Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf   |   32 +
>  .../VlvPlatformInitDxe/IgdOpRegion.c          |  929 ++++
>  .../VlvPlatformInitDxe/IgdOpRegion.h          |  235 +
>  .../VlvPlatformInitDxe/VlvPlatformInit.c      |  287 ++
>  .../VlvPlatformInitDxe/VlvPlatformInit.h      |   65 +
>  .../VlvPlatformInitDxe/VlvPlatformInitDxe.inf |   74 +
>  .../Vlv2TbltDevicePkg/Wpce791/LpcDriver.c     |  340 ++
>  .../Vlv2TbltDevicePkg/Wpce791/LpcDriver.h     |  112 +
>  .../Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c    |  366 ++
>  .../Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h    |  103 +
>  .../Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c  |  126 +
>  .../Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h  |  101 +
>  .../Vlv2TbltDevicePkg/Wpce791/Wpce791.inf     |   63 +
>  Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat  |  332 ++
>  Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh   |  256 +
>  Platform/Intel/Vlv2TbltDevicePkg/cln.sh       |   62 +
>  Readme.md                                     |    9 +
>  .../Include/DdrMemoryController.h             |  251 +
>  .../QuarkNorthCluster/Include/IntelQNCBase.h  |   17 +
>  .../Include/IntelQNCConfig.h                  |  100 +
>  .../QuarkNorthCluster/Include/IntelQNCDxe.h   |   17 +
>  .../QuarkNorthCluster/Include/IntelQNCPeim.h  |   17 +
>  .../QuarkNorthCluster/Include/IntelQNCRegs.h  |   48 +
>  .../Include/Library/IntelQNCLib.h             |  284 ++
>  .../Include/Library/QNCAccessLib.h            |  161 +
>  .../Include/Library/QNCSmmLib.h               |   57 +
>  .../Include/Ppi/QNCMemoryInit.h               |   36 +
>  .../Include/Protocol/PchInfo.h                |   48 +
>  .../Include/Protocol/PlatformPolicy.h         |   31 +
>  .../Include/Protocol/QncS3Support.h           |   84 +
>  .../Include/Protocol/SmmIchnDispatch2.h       |  115 +
>  .../QuarkNorthCluster/Include/Protocol/Spi.h  |  345 ++
>  .../QuarkNorthCluster/Include/QNCAccess.h     |  177 +
>  .../Include/QNCCommonDefinitions.h            |  350 ++
>  .../QuarkNorthCluster/Include/QuarkNcSocId.h  |  751 +++
>  .../Library/IntelQNCLib/CommonHeader.h        |   32 +
>  .../Library/IntelQNCLib/IntelQNCLib.c         |  771 +++
>  .../Library/IntelQNCLib/IntelQNCLib.inf       |   57 +
>  .../Library/IntelQNCLib/PciExpress.c          |  932 ++++
>  .../Library/MtrrLib/MtrrLib.c                 | 2112 ++++++++
>  .../Library/MtrrLib/MtrrLib.inf               |   42 +
>  .../Library/MtrrLib/MtrrLib.uni               |   18 +
>  .../Library/QNCAccessLib/BaseAccess.c         |   28 +
>  .../Library/QNCAccessLib/QNCAccessLib.c       |  327 ++
>  .../Library/QNCAccessLib/QNCAccessLib.inf     |   37 +
>  .../Library/QNCAccessLib/RuntimeAccess.c      |  142 +
>  .../QNCAccessLib/RuntimeQNCAccessLib.inf      |   43 +
>  .../Library/QNCSmmLib/QNCSmmLib.c             |  313 ++
>  .../Library/QNCSmmLib/QNCSmmLib.inf           |   44 +
>  .../Library/ResetSystemLib/ResetSystemLib.c   |  379 ++
>  .../Library/ResetSystemLib/ResetSystemLib.inf |   46 +
>  .../Library/SmbusLib/CommonHeader.h           |   25 +
>  .../Library/SmbusLib/SmbusLib.c               |  797 +++
>  .../Library/SmbusLib/SmbusLib.inf             |   47 +
>  .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.c     |  446 ++
>  .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf   |   30 +
>  .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.uni   |   12 +
>  .../MemoryInit/Pei/MemoryInit.c               |   59 +
>  .../MemoryInit/Pei/MemoryInit.h               |   35 +
>  .../MemoryInit/Pei/MemoryInitPei.inf          |   70 +
>  .../MemoryInit/Pei/core_types.h               |   43 +
>  .../MemoryInit/Pei/gen5_iosf_sb_definitions.h |  738 +++
>  .../MemoryInit/Pei/general_definitions.h      |   84 +
>  .../QuarkNorthCluster/MemoryInit/Pei/hte.c    |  536 ++
>  .../QuarkNorthCluster/MemoryInit/Pei/hte.h    |   66 +
>  .../QuarkNorthCluster/MemoryInit/Pei/io.h     |  132 +
>  .../QuarkNorthCluster/MemoryInit/Pei/lprint.c |  382 ++
>  .../MemoryInit/Pei/meminit.c                  | 2638 ++++++++++
>  .../MemoryInit/Pei/meminit.h                  |   22 +
>  .../MemoryInit/Pei/meminit_utils.c            | 1574 ++++++
>  .../MemoryInit/Pei/meminit_utils.h            |   95 +
>  .../MemoryInit/Pei/memory_options.h           |   77 +
>  .../QuarkNorthCluster/MemoryInit/Pei/mrc.c    |   40 +
>  .../QuarkNorthCluster/MemoryInit/Pei/mrc.h    |  160 +
>  .../MemoryInit/Pei/platform.c                 |  186 +
>  .../MemoryInit/Pei/prememinit.c               |  187 +
>  .../MemoryInit/Pei/prememinit.h               |   15 +
>  .../QNCInit/Dxe/CommonHeader.h                |   49 +
>  .../QNCInit/Dxe/DxeQNCSmbus.c                 |  612 +++
>  .../QNCInit/Dxe/DxeQNCSmbus.h                 |  205 +
>  .../QNCInit/Dxe/LegacyRegion.c                |  237 +
>  .../QNCInit/Dxe/LegacyRegion.h                |  198 +
>  .../QuarkNorthCluster/QNCInit/Dxe/QNCInit.c   |  518 ++
>  .../QuarkNorthCluster/QNCInit/Dxe/QNCInit.h   |   49 +
>  .../QNCInit/Dxe/QNCInitDxe.inf                |   92 +
>  .../QNCInit/Dxe/QNCRootPorts.c                |   76 +
>  .../QuarkNorthCluster/QNCInit/Dxe/QNCSmbus.h  |   80 +
>  .../QNCInit/Dxe/QNCSmbusExec.c                |  246 +
>  .../S3Support/Dxe/QncS3Support.c              |  417 ++
>  .../S3Support/Dxe/QncS3Support.h              |  117 +
>  .../S3Support/Dxe/QncS3Support.inf            |   64 +
>  .../Smm/Dxe/SmmAccessDxe/SmmAccess.inf        |   49 +
>  .../Smm/Dxe/SmmAccessDxe/SmmAccessDriver.c    |  405 ++
>  .../Smm/Dxe/SmmAccessDxe/SmmAccessDriver.h    |  230 +
>  .../Smm/Dxe/SmmControlDxe/SmmControlDriver.c  |  358 ++
>  .../Smm/Dxe/SmmControlDxe/SmmControlDxe.inf   |   55 +
>  .../DxeSmm/QncSmmDispatcher/CommonHeader.h    |   45 +
>  .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmGpi.c   |   32 +
>  .../QncSmmDispatcher/QNC/QNCSmmHelpers.c      |  549 ++
>  .../QNC/QNCSmmPeriodicTimer.c                 |  424 ++
>  .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmQncn.c  |  211 +
>  .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmSw.c    |   90 +
>  .../DxeSmm/QncSmmDispatcher/QNC/QNCSmmSx.c    |  147 +
>  .../Smm/DxeSmm/QncSmmDispatcher/QNCSmm.h      |  868 ++++
>  .../Smm/DxeSmm/QncSmmDispatcher/QNCSmmCore.c  |  825 +++
>  .../QncSmmDispatcher/QNCSmmDispatcher.inf     |   81 +
>  .../DxeSmm/QncSmmDispatcher/QNCSmmHelpers.c   |  367 ++
>  .../DxeSmm/QncSmmDispatcher/QNCSmmHelpers.h   |  219 +
>  .../DxeSmm/QncSmmDispatcher/QNCSmmRegisters.h |   13 +
>  .../DxeSmm/QncSmmDispatcher/QNCxSmmHelpers.h  |  178 +
>  .../Smm/Pei/SmmAccessPei/SmmAccessPei.c       |  376 ++
>  .../Smm/Pei/SmmAccessPei/SmmAccessPei.inf     |   45 +
>  .../Smm/Pei/SmmControlPei/SmmControlPei.c     |  274 +
>  .../Smm/Pei/SmmControlPei/SmmControlPei.inf   |   51 +
>  .../QuarkNorthCluster/Spi/Common/SpiCommon.c  |  927 ++++
>  .../QuarkNorthCluster/Spi/Common/SpiCommon.h  |  317 ++
>  .../QuarkNorthCluster/Spi/PchSpiRuntime.inf   |   84 +
>  .../QuarkNorthCluster/Spi/PchSpiSmm.inf       |   50 +
>  .../QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.c |  205 +
>  .../QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.h |   79 +
>  .../QuarkNorthCluster/Spi/Smm/PchSpi.c        |  123 +
>  .../QuarkNorthCluster/Spi/Smm/PchSpi.h        |   47 +
>  Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dec     |  234 +
>  Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dsc     |  254 +
>  .../QuarkSouthCluster/Include/CEATA.h         |  114 +
>  .../QuarkSouthCluster/Include/I2cRegs.h       |   95 +
>  .../QuarkSouthCluster/Include/Ioh.h           |  248 +
>  .../QuarkSouthCluster/Include/IohAccess.h     |   18 +
>  .../Include/IohCommonDefinitions.h            |  342 ++
>  .../Include/Library/I2cLib.h                  |  152 +
>  .../Include/Library/IohLib.h                  |   36 +
>  .../QuarkSouthCluster/Include/MMC.h           |  274 +
>  .../QuarkSouthCluster/Include/SDCard.h        |  146 +
>  .../QuarkSouthCluster/Include/SDHostIo.h      |  333 ++
>  .../IohInit/Dxe/CommonHeader.h                |   55 +
>  .../QuarkSouthCluster/IohInit/Dxe/IohBds.h    |   83 +
>  .../QuarkSouthCluster/IohInit/Dxe/IohData.c   |   42 +
>  .../QuarkSouthCluster/IohInit/Dxe/IohInit.c   |   37 +
>  .../IohInit/Dxe/IohInitDxe.inf                |   76 +
>  .../Library/I2cLib/CommonHeader.h             |  214 +
>  .../QuarkSouthCluster/Library/I2cLib/I2cLib.c |  998 ++++
>  .../Library/I2cLib/I2cLib.inf                 |   62 +
>  .../Library/IohLib/CommonHeader.h             |   29 +
>  .../QuarkSouthCluster/Library/IohLib/IohLib.c |   99 +
>  .../Library/IohLib/IohLib.inf                 |   49 +
>  .../Sdio/Dxe/SDControllerDxe/ComponentName.c  |  227 +
>  .../Sdio/Dxe/SDControllerDxe/ComponentName.h  |  141 +
>  .../Sdio/Dxe/SDControllerDxe/SDController.c   | 1784 +++++++
>  .../Sdio/Dxe/SDControllerDxe/SDController.h   |  316 ++
>  .../Dxe/SDControllerDxe/SDControllerDxe.inf   |   56 +
>  .../Sdio/Dxe/SDMediaDeviceDxe/CEATA.c         |  647 +++
>  .../Sdio/Dxe/SDMediaDeviceDxe/CEATABlockIo.c  |  389 ++
>  .../Sdio/Dxe/SDMediaDeviceDxe/ComponentName.c |  215 +
>  .../Sdio/Dxe/SDMediaDeviceDxe/ComponentName.h |  139 +
>  .../Sdio/Dxe/SDMediaDeviceDxe/MMCSDBlockIo.c  |  538 ++
>  .../Sdio/Dxe/SDMediaDeviceDxe/MMCSDTransfer.c | 1708 +++++++
>  .../Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.c |  317 ++
>  .../Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.h |  462 ++
>  .../Dxe/SDMediaDeviceDxe/SDMediaDeviceDxe.inf |   60 +
>  .../QuarkSouthCluster/Usb/Common/Pei/UsbPei.c |  320 ++
>  .../QuarkSouthCluster/Usb/Common/Pei/UsbPei.h |   38 +
>  .../Usb/Common/Pei/UsbPei.inf                 |   53 +
>  .../Usb/Ohci/Dxe/ComponentName.c              |  219 +
>  .../Usb/Ohci/Dxe/ComponentName.h              |  141 +
>  .../Usb/Ohci/Dxe/Descriptor.h                 |  132 +
>  .../QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.c     | 2473 +++++++++
>  .../QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.h     |  663 +++
>  .../Usb/Ohci/Dxe/OhciDebug.c                  |   78 +
>  .../Usb/Ohci/Dxe/OhciDebug.h                  |   42 +
>  .../Usb/Ohci/Dxe/OhciDxe.inf                  |   71 +
>  .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.c  | 1390 +++++
>  .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.h  |  920 ++++
>  .../Usb/Ohci/Dxe/OhciSched.c                  |  528 ++
>  .../Usb/Ohci/Dxe/OhciSched.h                  |  225 +
>  .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.c  |  889 ++++
>  .../QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.h  |  387 ++
>  .../QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.c |  560 ++
>  .../QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.h |  152 +
>  .../Usb/Ohci/Pei/Descriptor.h                 |  131 +
>  .../QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.c  | 1386 +++++
>  .../QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.h  |  252 +
>  .../Usb/Ohci/Pei/OhciPei.inf                  |   56 +
>  .../QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.c  | 1386 +++++
>  .../QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.h  |  875 ++++
>  .../Usb/Ohci/Pei/OhciSched.c                  |  223 +
>  .../Usb/Ohci/Pei/OhciSched.h                  |  108 +
>  .../QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.c  |  560 ++
>  .../QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.h  |  231 +
>  .../QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.c |  491 ++
>  .../QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.h |  134 +
>  .../AcpiTablesPCAT/98_LINK.ASL                |  617 +++
>  .../AcpiTablesPCAT/AcpiTablePlatform.h        |   70 +
>  .../AcpiTablesPCAT/AcpiTables.inf             |   40 +
>  .../AcpiTablesPCAT/CPU.asl                    |   49 +
>  .../AcpiTablesPCAT/DSDT.ASL                   |   75 +
>  .../AcpiTablesPCAT/Facp/Facp.aslc             |  188 +
>  .../AcpiTablesPCAT/Facs/Facs.aslc             |   84 +
>  .../AcpiTablesPCAT/GloblNvs.asl               |  348 ++
>  .../AcpiTablesPCAT/Gpe.asl                    |   99 +
>  .../AcpiTablesPCAT/HOST_BUS.ASL               |  347 ++
>  .../AcpiTablesPCAT/Hpet/Hpet.aslc             |   63 +
>  .../AcpiTablesPCAT/INTELGFX.ASL               |  879 ++++
>  .../AcpiTablesPCAT/INTELISPDev2.ASL           |   71 +
>  .../AcpiTablesPCAT/IgdOGBDA.ASL               |  155 +
>  .../AcpiTablesPCAT/IgdOMOBF.ASL               |  485 ++
>  .../AcpiTablesPCAT/IgdOSBCB.ASL               |  274 +
>  .../AcpiTablesPCAT/IgdOpRn.ASL                |  299 ++
>  .../AcpiTablesPCAT/IoTVirtualDevice.asl       |  171 +
>  .../AcpiTablesPCAT/LPC_DEV.ASL                |  151 +
>  .../AcpiTablesPCAT/LpcB.asl                   |   59 +
>  .../AcpiTablesPCAT/Lpit/Lpit.aslc             |  223 +
>  .../AcpiTablesPCAT/Madt/Madt.h                |  189 +
>  .../AcpiTablesPCAT/Madt/Madt30.aslc           |  178 +
>  .../AcpiTablesPCAT/Mcfg/Mcfg.aslc             |   86 +
>  .../AcpiTablesPCAT/PCI_DRC.ASL                |   90 +
>  .../AcpiTablesPCAT/Pch.asl                    |  686 +++
>  .../AcpiTablesPCAT/PchAudio.asl               |   36 +
>  .../AcpiTablesPCAT/PchEhci.asl                |  269 +
>  .../AcpiTablesPCAT/PchLpss.asl                | 1093 ++++
>  .../AcpiTablesPCAT/PchPcie.asl                |   50 +
>  .../AcpiTablesPCAT/PchScc.asl                 |  610 +++
>  .../AcpiTablesPCAT/PchSmb.asl                 |  833 +++
>  .../AcpiTablesPCAT/PchXhci.asl                |  379 ++
>  .../AcpiTablesPCAT/PciTree.asl                |  377 ++
>  .../AcpiTablesPCAT/Platform.asl               |  703 +++
>  .../AcpiTablesPCAT/RTD3.asl                   |  197 +
>  .../AcpiTablesPCAT/RhProxy.asl                |  160 +
>  .../AcpiTablesPCAT/THERMAL.ASL                |  137 +
>  .../AcpiTablesPCAT/UsbSbd.asl                 |   93 +
>  .../AcpiTablesPCAT/Video.asl                  |   34 +
>  .../AcpiTablesPCAT/Vlv.asl                    |   39 +
>  .../AcpiTablesPCAT/Wsmt/Wsmt.aslc             |   54 +
>  .../AcpiTablesPCAT/token.asl                  |   39 +
>  .../Guid/Vlv2DeviceRefCodePkgTokenSpace.h     |   24 +
>  .../Include/Ppi/PttPassThruPpi.h              |   92 +
>  .../Include/Ppi/fTPMPolicy.h                  |   26 +
>  .../Include/Protocol/PttPassThru.h            |   91 +
>  .../Guid/PowerManagementAcpiTableStorage.h    |   27 +
>  .../CPU/Include/Ppi/VlvPolicy.h               |  104 +
>  .../CPU/Include/Protocol/PpmPlatformPolicy.h  |  132 +
>  .../ValleyView2Soc/CPU/Include/Types.h        |   55 +
>  .../AcpiTables/PowerManagementAcpiTables.inf  |   39 +
>  .../PowerManagement/AcpiTables/Ssdt/ApCst.asl |  110 +
>  .../PowerManagement/AcpiTables/Ssdt/ApIst.asl |  166 +
>  .../PowerManagement/AcpiTables/Ssdt/ApTst.asl |  262 +
>  .../AcpiTables/Ssdt/Cpu0Cst.asl               |  274 +
>  .../AcpiTables/Ssdt/Cpu0Ist.asl               |  260 +
>  .../AcpiTables/Ssdt/Cpu0Tst.asl               |  235 +
>  .../PowerManagement/AcpiTables/Ssdt/CpuPm.asl |  793 +++
>  .../Include/PlatformBaseAddresses.h           |   92 +
>  .../NorthCluster/Include/Ppi/Capsule.h        |   60 +
>  .../Include/Ppi/PlatformMemoryRange.h         |  144 +
>  .../Include/Ppi/PlatformMemorySize.h          |   46 +
>  .../NorthCluster/Include/Ppi/SmmAccess.h      |  165 +
>  .../NorthCluster/Include/Ppi/VlvMmioPolicy.h  |   39 +
>  .../NorthCluster/Include/Ppi/VlvPeiInit.h     |   35 +
>  .../NorthCluster/Include/Ppi/VlvPolicy.h      |  106 +
>  .../Include/Protocol/IgdOpRegion.h            |  213 +
>  .../NorthCluster/Include/Protocol/MemInfo.h   |   83 +
>  .../Include/Protocol/PlatformGopPolicy.h      |   67 +
>  .../Include/Protocol/VlvPlatformPolicy.h      |  105 +
>  .../NorthCluster/Include/Valleyview.h         |   55 +
>  .../NorthCluster/Include/VlvAccess.h          |  254 +
>  .../Include/VlvCommonDefinitions.h            |  252 +
>  .../SouthCluster/Include/Guid/PchInitVar.h    |   48 +
>  .../Include/Guid/SataControllerGuid.h         |   34 +
>  .../SouthCluster/Include/Guid/SmbusArpMap.h   |   30 +
>  .../SouthCluster/Include/Guid/Vlv2Variable.h  |   28 +
>  .../Include/IndustryStandard/CeAta.h          |  126 +
>  .../Include/IndustryStandard/Mmc.h            |  349 ++
>  .../Include/IndustryStandard/SdCard.h         |  157 +
>  .../SouthCluster/Include/Library/I2CLib.h     |  169 +
>  .../Include/Library/PchPlatformLib.h          |  115 +
>  .../SouthCluster/Include/PchAccess.h          |  471 ++
>  .../Include/PchCommonDefinitions.h            |  210 +
>  .../SouthCluster/Include/PchRegs.h            |  205 +
>  .../SouthCluster/Include/PchRegs/PchRegsHda.h |   50 +
>  .../Include/PchRegs/PchRegsLpss.h             |  486 ++
>  .../Include/PchRegs/PchRegsPcie.h             |   83 +
>  .../SouthCluster/Include/PchRegs/PchRegsPcu.h | 1201 +++++
>  .../Include/PchRegs/PchRegsRcrb.h             |   48 +
>  .../Include/PchRegs/PchRegsSata.h             |  245 +
>  .../SouthCluster/Include/PchRegs/PchRegsScc.h |   53 +
>  .../Include/PchRegs/PchRegsSmbus.h            |  149 +
>  .../SouthCluster/Include/PchRegs/PchRegsSpi.h |  119 +
>  .../SouthCluster/Include/PchRegs/PchRegsUsb.h |   92 +
>  .../SouthCluster/Include/Ppi/PchInit.h        |   75 +
>  .../SouthCluster/Include/Ppi/PchPeiInit.h     |   34 +
>  .../Include/Ppi/PchPlatformPolicy.h           |  161 +
>  .../SouthCluster/Include/Ppi/PchUsbPolicy.h   |   69 +
>  .../SouthCluster/Include/Ppi/PeiBlockIo.h     |  230 +
>  .../SouthCluster/Include/Ppi/Sdhc.h           |  359 ++
>  .../SouthCluster/Include/Ppi/SmbusPolicy.h    |   40 +
>  .../SouthCluster/Include/Ppi/Spi.h            |   42 +
>  .../Include/Protocol/ActiveBios.h             |  123 +
>  .../Include/Protocol/ActiveBiosProtocol.h     |  125 +
>  .../Protocol/DxePchPolicyUpdateProtocol.h     |   51 +
>  .../Include/Protocol/EmmcCardInfoProtocol.h   |   42 +
>  .../SouthCluster/Include/Protocol/Gpio.h      |  161 +
>  .../Include/Protocol/HwWatchdogTimer.h        |  294 ++
>  .../SouthCluster/Include/Protocol/I2cBus.h    |  164 +
>  .../Include/Protocol/PchExtendedReset.h       |   84 +
>  .../SouthCluster/Include/Protocol/PchInfo.h   |   60 +
>  .../Include/Protocol/PchPlatformPolicy.h      |  550 ++
>  .../SouthCluster/Include/Protocol/PchReset.h  |  114 +
>  .../Include/Protocol/PchS3Support.h           |  132 +
>  .../SouthCluster/Include/Protocol/SdHostIo.h  |  409 ++
>  .../Include/Protocol/SmbiosSlotPopulation.h   |   47 +
>  .../Include/Protocol/SmmIchnDispatchEx.h      |  159 +
>  .../SouthCluster/Include/Protocol/SmmSmbus.h  |   39 +
>  .../SouthCluster/Include/Protocol/Spi.h       |  260 +
>  .../SouthCluster/Include/Protocol/TcoReset.h  |   88 +
>  .../SouthCluster/Include/Rsci.h               |   28 +
>  .../SouthCluster/Include/TianoApi.h           |   61 +
>  .../Vlv2DeviceRefCodePkg.dec                  |  231 +
>  .../Omap35xxPkg/Flash/Flash.c                 |  768 +++
>  .../Omap35xxPkg/Flash/Flash.h                 |  100 +
>  .../Omap35xxPkg/Flash/Flash.inf               |   42 +
>  .../TexasInsturments/Omap35xxPkg/Gpio/Gpio.c  |  129 +
>  .../Omap35xxPkg/Gpio/Gpio.inf                 |   39 +
>  .../Omap35xxPkg/Include/Library/OmapDmaLib.h  |   84 +
>  .../Omap35xxPkg/Include/Library/OmapLib.h     |   38 +
>  .../Omap35xxPkg/Include/Omap3530/Omap3530.h   |   34 +
>  .../Include/Omap3530/Omap3530Dma.h            |  124 +
>  .../Include/Omap3530/Omap3530Gpio.h           |  125 +
>  .../Include/Omap3530/Omap3530Gpmc.h           |  101 +
>  .../Include/Omap3530/Omap3530I2c.h            |   56 +
>  .../Include/Omap3530/Omap3530Interrupt.h      |   45 +
>  .../Include/Omap3530/Omap3530MMCHS.h          |  208 +
>  .../Omap3530/Omap3530PadConfiguration.h       |  297 ++
>  .../Include/Omap3530/Omap3530Prcm.h           |  159 +
>  .../Include/Omap3530/Omap3530Timer.h          |   76 +
>  .../Include/Omap3530/Omap3530Uart.h           |   48 +
>  .../Include/Omap3530/Omap3530Usb.h            |   42 +
>  .../Omap35xxPkg/Include/TPS65950.h            |   74 +
>  .../InterruptDxe/HardwareInterrupt.c          |  396 ++
>  .../Omap35xxPkg/InterruptDxe/InterruptDxe.inf |   48 +
>  .../LcdGraphicsOutputBlt.c                    |  439 ++
>  .../LcdGraphicsOutputDxe.c                    |  394 ++
>  .../LcdGraphicsOutputDxe.h                    |  151 +
>  .../LcdGraphicsOutputDxe.inf                  |   46 +
>  .../DebugAgentTimerLib/DebugAgentTimerLib.c   |  159 +
>  .../DebugAgentTimerLib/DebugAgentTimerLib.inf |   42 +
>  .../Library/GdbSerialLib/GdbSerialLib.c       |   96 +
>  .../Library/GdbSerialLib/GdbSerialLib.inf     |   35 +
>  .../Omap35xxTimerLib/Omap35xxTimerLib.inf     |   40 +
>  .../Library/Omap35xxTimerLib/TimerLib.c       |  151 +
>  .../Library/OmapDmaLib/OmapDmaLib.c           |  170 +
>  .../Library/OmapDmaLib/OmapDmaLib.inf         |   43 +
>  .../Omap35xxPkg/Library/OmapLib/OmapLib.c     |   77 +
>  .../Omap35xxPkg/Library/OmapLib/OmapLib.inf   |   31 +
>  .../RealTimeClockLib/RealTimeClockLib.c       |  291 ++
>  .../RealTimeClockLib/RealTimeClockLib.inf     |   32 +
>  .../Library/SerialPortLib/SerialPortLib.c     |  208 +
>  .../Library/SerialPortLib/SerialPortLib.inf   |   40 +
>  .../Omap35xxPkg/MMCHSDxe/MMCHS.c              | 1492 ++++++
>  .../Omap35xxPkg/MMCHSDxe/MMCHS.h              |  169 +
>  .../Omap35xxPkg/MMCHSDxe/MMCHS.inf            |   48 +
>  .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.c       |  671 +++
>  .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.h       |   38 +
>  .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf     |   47 +
>  .../Omap35xxPkg/Omap35xxPkg.dec               |   52 +
>  .../Omap35xxPkg/Omap35xxPkg.dsc               |  183 +
>  .../Omap35xxPkg/PciEmulation/PciEmulation.c   |  107 +
>  .../Omap35xxPkg/PciEmulation/PciEmulation.inf |   41 +
>  .../Omap35xxPkg/SmbusDxe/Smbus.c              |  319 ++
>  .../Omap35xxPkg/SmbusDxe/Smbus.inf            |   39 +
>  .../Omap35xxPkg/TPS65950Dxe/TPS65950.c        |  110 +
>  .../Omap35xxPkg/TPS65950Dxe/TPS65950.inf      |   42 +
>  .../Omap35xxPkg/TimerDxe/Timer.c              |  370 ++
>  .../Omap35xxPkg/TimerDxe/TimerDxe.inf         |   51 +
>  1103 files changed, 259532 insertions(+)
>  create mode 100644
> Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.c
>  create mode 100644
> Drivers/OptionRomPkg/Application/BltLibSample/BltLibSample.inf
>  create mode 100644
> Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.c
>  create mode 100644
> Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.h
>  create mode 100644
> Drivers/OptionRomPkg/AtapiPassThruDxe/AtapiPassThruDxe.inf
>  create mode 100644
> Drivers/OptionRomPkg/AtapiPassThruDxe/ComponentName.c
>  create mode 100644
> Drivers/OptionRomPkg/AtapiPassThruDxe/DriverSupportedEfiVersion.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/CompatibleDevices.txt
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ComponentName.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.h
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.h
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/ComponentNam
> e.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/DriverBinding.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/SimpleNetwork.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/ComponentNa
> me.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/DriverBinding.c
>  create mode 100644
> Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwork
> .c
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.c
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.h
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430GraphicsOutput.c
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.c
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.h
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430UgaDraw.c
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/ComponentName.c
>  create mode 100644
> Drivers/OptionRomPkg/CirrusLogic5430Dxe/DriverSupportedEfiVersion.c
>  create mode 100644 Drivers/OptionRomPkg/CirrusLogic5430Dxe/Edid.c
>  create mode 100644 Drivers/OptionRomPkg/Include/Library/BltLib.h
>  create mode 100644
> Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.c
>  create mode 100644
> Drivers/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
>  create mode 100644 Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.c
>  create mode 100644 Drivers/OptionRomPkg/Library/GopBltLib/GopBltLib.inf
>  create mode 100644 Drivers/OptionRomPkg/OptionRomPkg.dec
>  create mode 100644 Drivers/OptionRomPkg/OptionRomPkg.dsc
>  create mode 100644 Drivers/OptionRomPkg/ReadMe.txt
>  create mode 100644
> Drivers/OptionRomPkg/UndiRuntimeDxe/ComponentName.c
>  create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/Decode.c
>  create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.c
>  create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/E100b.h
>  create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/Init.c
>  create mode 100644 Drivers/OptionRomPkg/UndiRuntimeDxe/Undi32.h
>  create mode 100644
> Drivers/OptionRomPkg/UndiRuntimeDxe/UndiAipImpl.c
>  create mode 100644
> Drivers/OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.dec
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.dsc
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/BeagleBoardPkg.fdf
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/ConfigurationHeader.bin
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/ConfigurationHeader.dat
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_boot_from_ra
> m.inc
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_convert_sym
> bols.sh
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_dummy.axf
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_hw_setup.inc
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_load_symbols
> .inc
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_symbols_mac
> ros.inc
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/rvi_unload_symb
> ols.inc
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/trace32_load_sy
> mbols.cmm
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Debugger_scripts/trace32_load_sy
> mbols_cygwin.cmm
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Include/BeagleBoard.h
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoar
> d.c
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoar
> dHelper.S
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoar
> dHelper.asm
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoar
> dLib.inf
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/BeagleBoar
> dMem.c
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/Clock.c
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/BeagleBoardLib/PadConfigur
> ation.c
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/DxeHobPeCoffLib/DxeHobP
> eCoff.c
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/DxeHobPeCoffLib/DxeHobP
> eCoffLib.inf
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/LzmaHobCustomDecompres
> sLib/LzmaHobCustomDecompressLib.c
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/LzmaHobCustomDecompres
> sLib/LzmaHobCustomDecompressLib.inf
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/MemoryInitPeiLib/MemoryI
> nitPeiLib.c
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/MemoryInitPeiLib/MemoryI
> nitPeiLib.inf
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/ResetSystemLib/ResetSyste
> mLib.c
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Library/ResetSystemLib/ResetSyste
> mLib.inf
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ArchPrePi.c
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ModuleEntryPoint.S
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/PrePi/Arm/ModuleEntryPoint.asm
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/PrePi/LzmaDecompress.h
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/PrePi/MainUniCore.c
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/PrePi/PeiUniCore.inf
>  create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/PrePi/PrePi.c
>  create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/PrePi/PrePi.h
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Tools/GNUmakefile
>  create mode 100644
> Platform/BeagleBoard/BeagleBoardPkg/Tools/generate_image.c
>  create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Tools/makefile
>  create mode 100644 Platform/BeagleBoard/BeagleBoardPkg/Tools/replace.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/AcpiTables.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Cst/Cpu0Cst.asl
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Ist/Cpu0Ist.asl
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Cpu0Tst/Cpu0Tst.asl
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/CpuPm/CpuPm.asl
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/AD7298.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/ADC108S102.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/CAT24C08.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/CY8C9540A.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/GpioClient.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/LpcDev.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PCA9685.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PCAL9555A.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PciHostBridge.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PciIrq.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/PcieExpansionPrt.as
> i
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Platform.asl
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNC.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNCApic.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QNCLpc.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/QuarkSouthCluster.
> asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Dsdt/Tpm.asi
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Facs/Facs.aslc
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Facs/Facs.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt1.0.aslc
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Fadt/Fadt2.0.aslc
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.aslc
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Mcfg/Mcfg.aslc
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/AcpiTables/Mcfg/Mcfg.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPciUpdate.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/Madt.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/MadtPlatform.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/BootScri
> ptExecutorDxe.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/S3
> Asm.S
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/S3
> Asm.asm
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/IA32/Se
> tIdtEntry.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/ScriptEx
> ecute.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/Dxe/BootScriptExecutorDxe/ScriptEx
> ecute.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatfor
> m.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatfor
> m.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/AcpiSmm/AcpiSmmPlatfor
> m.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/
> Ppm.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/
> Ppm.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/
> SmmPowerManagement.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/
> SmmPowerManagement.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Acpi/DxeSmm/SmmPowerManagement/
> SmmPowerManagement.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Application/ForceRecovery/ForceRecover
> y.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Application/ForceRecovery/ForceRecover
> y.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAc
> cessLib/PlatformFlashAccessLibDxe.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAc
> cessLib/PlatformFlashAccessLibDxe.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAc
> cessLib/SpiFlashDevice.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Feature/Capsule/Library/PlatformFlashAc
> cessLib/SpiFlashDevice.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareDescrip
> tor/SystemFirmwareDescriptor.aslc
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareDescrip
> tor/SystemFirmwareDescriptor.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareDescrip
> tor/SystemFirmwareDescriptorPei.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Feature/Capsule/SystemFirmwareUpdate
> Config/SystemFirmwareUpdateConfig.ini
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnDataCD.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatFloppyDisk.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatIdeDisk.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Guid/CapsuleOnFatUsbDisk.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Guid/MemoryConfigData.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Guid/QuarkCapsuleGuid.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Guid/QuarkVariableLock.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Guid/SystemNvDataHobGuid.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Library/PlatformHelperLib.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Library/PlatformPcieHelperLib.h
>  create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Pcal9555.h
>  create mode 100644 Platform/Intel/QuarkPlatformPkg/Include/Platform.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/PlatformBoards.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Protocol/GlobalNvsArea.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Include/Protocol/PlatformSmmSpiReady.
> h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/Platfor
> mBootManager.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/Platfor
> mBootManager.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/Platfor
> mBootManagerLib.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformBootManagerLib/Platfor
> mData.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/CommonHead
> er.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/DxePlatformHe
> lperLib.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PeiPlatformHel
> perLib.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelper
> Dxe.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelper
> Lib.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelper
> Pei.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformHelperLib/PlatformLeds.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/CommonH
> eader.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPci
> eHelperLib.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPci
> eHelperLib.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformPcieHelperLib/SocUnit.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Flat32.S
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Flat32.asm
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/Ia32/Platform.inc
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLib.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformSecLib/PlatformSecLibMo
> dStrs.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecur
> eLib.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecur
> eLib.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/TisPc.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12D
> eviceLibAtmelI2c.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12D
> eviceLibAtmelI2c.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/TisPc.
> c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/Tpm1
> 2DeviceLibInfineonI2c.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Library/Tpm12DeviceLibInfineonI2c/Tpm1
> 2DeviceLibInfineonI2c.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridgeSupp
> ort.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostResource.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridge.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridgeIo.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/CommonHeader.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/Memory
> SubClass.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/Memory
> SubClass.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/Memory
> SubClass.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/Memory
> SubClassStrings.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformConfi
> g.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDx
> e.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDx
> e.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDx
> e.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveM
> emoryConfig.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveM
> emoryConfig.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/CommonHeader.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/DxePlatform.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/KeyboardLayout.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/QNCRegTable.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/Strings.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/Setup/processor.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/CommonH
> eader.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseB
> oardManufacturer.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseB
> oardManufacturerData.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseB
> oardManufacturerFunction.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosV
> endor.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosV
> endorData.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosV
> endorFunction.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootI
> nformationData.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootI
> nformationFunction.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassi
> sManufacturer.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassi
> sManufacturerData.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassi
> sManufacturerFunction.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscDevic
> ePath.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumb
> erOfInstallableLanguagesData.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumb
> erOfInstallableLanguagesFunction.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemS
> tring.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemS
> tringData.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemS
> tringFunction.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnbo
> ardDevice.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnbo
> ardDeviceData.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnbo
> ardDeviceFunction.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortIn
> ternalConnectorDesignator.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortIn
> ternalConnectorDesignatorData.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortIn
> ternalConnectorDesignatorFunction.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSyste
> mManufacturer.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSyste
> mManufacturerData.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSyste
> mManufacturerFunction.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSyste
> mOptionString.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSyste
> mOptionStringData.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSyste
> mOptionStringFunction.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSyste
> mSlotDesignation.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSyste
> mSlotDesignationData.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSyste
> mSlotDesignationFunction.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSyste
> mSlotOnboardDevices.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMis
> c.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMis
> cDataTable.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMis
> cDxe.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMis
> cEntryPoint.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMis
> cStrings.uni
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformCon
> figPei.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformCon
> figPei.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/BootMode.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/CommonHeade
> r.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/Generic/Recov
> ery.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MemoryCallbac
> k.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyIn
> it.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyIn
> it.h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyIn
> it.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformErratas
> .c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FvbInfo.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.
> h
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi
> .c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi
> .inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSpi.inf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.c
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.h
>  create mode 100644 Platform/Intel/QuarkPlatformPkg/Quark.dsc
>  create mode 100644 Platform/Intel/QuarkPlatformPkg/Quark.fdf
>  create mode 100644 Platform/Intel/QuarkPlatformPkg/QuarkMin.dsc
>  create mode 100644 Platform/Intel/QuarkPlatformPkg/QuarkMin.fdf
>  create mode 100644
> Platform/Intel/QuarkPlatformPkg/QuarkPlatformPkg.dec
>  create mode 100644 Platform/Intel/QuarkPlatformPkg/Readme.md
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/.gitignore
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooksLib.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareU
> pdate.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareU
> pdate.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareU
> pdate.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareU
> pdateStrings.uni
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64D.env
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64R.env
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/BootScriptSaveDxe.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/InternalBootScriptSav
> e.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/ScriptSave.c
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.bat
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.sh
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FCE.exe
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenC
> apsuleAll.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenC
> apsuleAll.sh
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenC
> apsuleMinnowMax.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenC
> apsuleMinnowMax.sh
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenC
> apsuleMinnowMaxRelease.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenC
> apsuleMinnowMaxRelease.sh
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenC
> apsuleSampleColor.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenC
> apsuleSampleColor.sh
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Lvfs.d
> df
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsG
> enCapsuleMinnowMax.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsG
> enCapsuleMinnowMaxRelease.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsG
> enCapsuleSampleColor.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/NewR
> oot.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.i
> nc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMP
> LE_DEVELOPMENT.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7
> CertBufferXdr.inc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMP
> LE_DEVELOPMENT_SAMPLE_PRODUCTION.cer.gFmpDevicePkgTokenSpace
> Guid.PcdFmpDevicePkcs7CertBufferXdr.inc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/templ
> ate.metainfo.xml
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/F
> mpDeviceLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/F
> mpDeviceLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSa
> mple/FmpDeviceLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSa
> mple/FmpDeviceLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAc
> cessLib/PlatformFlashAccessLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAc
> cessLib/PlatformFlashAccessLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescrip
> tor/SystemFirmwareDescriptor.aslc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescrip
> tor/SystemFirmwareDescriptor.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescrip
> tor/SystemFirmwareDescriptorPei.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdate
> Config/SystemFirmwareUpdateConfig.ini
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdate
> Config/SystemFirmwareUpdateConfigGcc.ini
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/FmpCertificate.dsc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FmpGreenSampleDevice.dsc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspAzaliaConfigData/AzaliaConfig.bin
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.
> c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.i
> nf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLib
> Vlv2/FspHobProcessLibVlv2.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLib
> Vlv2/FspHobProcessLibVlv2.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/FspPlatformSecLibVlv2.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/FspPlatformSecLibVlv2.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/Ia32/AsmSaveSecContext.asm
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/Ia32/Fsp.inc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/Ia32/PeiCoreEntry.asm
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/Ia32/SecEntry.asm
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/Ia32/Stack.S
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/Ia32/Stack.asm
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/PlatformInit.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/SaveSecContext.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/SecGetPerformance.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/SecPlatformInformation.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/SecRamInitData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/SecTempRamSupport.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLib
> Vlv2/UartInit.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbRuntimeDxe.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceDxe.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceSmm.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmm.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmCommon.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.inf
>  create mode 100755 Platform/Intel/Vlv2TbltDevicePkg/GenBiosId
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/GenBiosId.exe
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/AlertStandardFormatTable.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/ChipsetAccess.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/CommonIncludes.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/CpuType.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/FileHandleLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AcpiTableStorage.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AlertStandardFormat.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BiosId.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BoardFeatures.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/EfiVpdData.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/FirmwareId.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/HwWatchdogTimerHob.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/IdccData.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/ItkData.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/MemoryConfigData.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/OsSelection.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PciLanInfo.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformCpuInfo.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/PlatformInfo.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SensorInfoVariable.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/SetupVariable.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Hpet.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/BiosIdLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/CpuIA32.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/EfiRegTableLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Esrt.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Library/Fd.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/FlashDeviceLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2CLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cMmioConfigLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/I2cPort_platform.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFsaLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/PlatformFspLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/SpiFlash.H
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/StallSmmLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Library/UsbDeviceModeLib.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Mcfg.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/McfgTable.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Include/Platform.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformBootMode.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/PlatformDefinitions.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/MfgMemoryTest.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Sha256Hash.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/Speaker.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Ppi/UsbController.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/CK505ClockPlatformInfo.
> h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/EnhancedSpeedstep.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/GlobalNvsArea.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/HwWatchdogTimer.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cAcpi.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBus.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cBusMcg.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cHostMcg.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cMasterMcg.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/I2cSlave.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpc83627Policy.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/LpcWpce791Policy.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/MmioDevice.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Observable.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformGopPolicy.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/PlatformIdeInit.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SetupMode.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/SmbiosSlotPopulation.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/Speaker.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TcoReset.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/TpmMp.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/UsbPolicy.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/Protocol/VlvPlatformPolicy.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Include/SetupMode.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/IntelGopDepex/IntelGopDriver.depex
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/BiosIdLib/BiosIdLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/CpuIA32Lib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/EfiCpuVersion.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.S
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.asm
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/IA32/CpuIA32.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.S
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/CpuIA32Lib/X64/Cpu.asm
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxe.
> c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxe.
> inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxe
> RuntimeSmm.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/FlashDeviceLib/SpiChipDefinitions.
> h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLib/I2CLibNull.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLibDxe.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CRegs.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CAccess.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/CommonHe
> ader.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpi
> TimerLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpi
> TimerLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens/B
> oardClkGens.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens/B
> oardClkGens.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/Boa
> rdGpios.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardGpios/Boa
> rdGpios.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers/B
> oardJumpers.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardJumpers/B
> oardJumpers.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/B
> oardOemIds.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardOemIds/B
> oardOemIds.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid/B
> oardSsidSvid.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardSsidSvid/B
> oardSsidSvid.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib
> .c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib
> .h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib
> .inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/MultiPlatformLib/PlatformInfoHob
> .c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibrar
> y.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLibrar
> y.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/CommonHeader.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformBdsString
> s.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformBdsLib/PlatformData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmosLi
> b.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmosLi
> b.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/PlatformFspLib/PlatformFspLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLib.i
> nf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/PlatformSerialPortLib
> .h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SerialPortLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SerialPortLib/SioInit.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/CommonHeader.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/SmbusLib/SmbusLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmm.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmmLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2Devic
> eLibSeC.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCDxe/Tpm2Devic
> eLibSeC.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2Devic
> eLibSeC.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Library/Tpm2DeviceLibSeCPei/Tpm2Devic
> eLibSeC.inf
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Logo/Logo.bmp
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Metronome/LegacyMetronome.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Metronome/Metronome.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/EfiStatusCode.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PeiPostCode.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libr
> ary/GenericBdsLib/BdsBoot.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libr
> ary/GenericBdsLib/BdsConnect.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libr
> ary/GenericBdsLib/BdsConsole.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libr
> ary/GenericBdsLib/BdsMisc.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libr
> ary/GenericBdsLib/DevicePath.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libr
> ary/GenericBdsLib/GenericBdsLib.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libr
> ary/GenericBdsLib/GenericBdsLib.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libr
> ary/GenericBdsLib/GenericBdsStrings.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libr
> ary/GenericBdsLib/InternalBdsLib.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libr
> ary/GenericBdsLib/String.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Libr
> ary/GenericBdsLib/String.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/BoardPciPlatform.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PciPlatform/PciPlatform.inf
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.dsc
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsule.fdf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.dsc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformCapsuleGcc.fdf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe
> .c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe
> .h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe
> .inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/AzaliaVerbTable.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardId.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/BoardIdDecode.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ClockControl.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Configuration.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/ExI.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchPlatformPolicy.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchRegTable.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IchTcoReset.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/IdccInfo.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/LegacySpeaker.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Observable/Observable.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciBus.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PciDevice.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Platform.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.inf
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/Rtc.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SensorVar.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SioPlatformPolicy.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformDxe/SlotConfig.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/BootMode.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/CpuInitPeim.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Dimm.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/FlashMap.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/LegacySpeaker.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MchInit.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryCallback.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/MemoryPeim.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PchInitPeim.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformEarlyInit.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInfoInit.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformInitPei.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/PlatformSsaInitPeim.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Recovery.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformInitPei/Stall.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/BootMode.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/CommonHeader.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/MemoryCallback.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Platform.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/PlatformPei.inf
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPei/Stall.c
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.dec
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkg.fdf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgConfig.dsc
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGcc.fdf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgIA32.dsc
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgX64.dsc
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Boot.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Configuration.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/DebugConfig.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/FwVersionStrings.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Main.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Security.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupFunctions.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SetupInfoRecords.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SouthClusterConfig.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/SystemComponent.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Thermal.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UnCore.vfi
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/UqiList.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/Vfr.vfr
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSetupDxe/VfrStrings.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/Platform.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/PlatformSmm.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/S3Save.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmPlatform.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PlatformSmm/SmmScriptSave.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Readme.md
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.
> h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.i
> nf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/CommonHeader.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufact
> urer.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufact
> urerData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBaseBoardManufact
> urerFunction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendor.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBiosVendorFunction.
> c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationDat
> a.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscBootInformationFun
> ction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturer
> .uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturer
> Data.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscChassisManufacturer
> Function.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDevice.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceData.
> c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceFunct
> ion.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstallable
> LanguagesData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscNumberOfInstallable
> LanguagesFunction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemString.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemStringFunction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Data.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Functi
> on.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Data.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x94Functi
> on.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDevice.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceData.
> c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOnboardDeviceFunct
> ion.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArray.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPhysicalArrayFunctio
> n.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnect
> orDesignator.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnect
> orDesignatorData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscPortInternalConnect
> orDesignatorFunction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCache.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheData.
> c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorCacheFunc
> tion.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformatio
> n.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformatio
> nData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscProcessorInformatio
> nFunction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesDat
> a.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscResetCapabilitiesFun
> ction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriver.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverDataT
> able.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSubclassDriverEntryP
> oint.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageStri
> ng.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageStri
> ngData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemLanguageStri
> ngFunction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacture
> r.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacture
> rData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemManufacture
> rFunction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionString.
> uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionString
> Data.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemOptionStringF
> unction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignati
> on.uni
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignati
> onData.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscSystemSlotDesignati
> onFunction.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmBiosMiscDxe/SmBiosMiscDxe.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchThun
> k/SmmSwDispatch2OnSmmSwDispatchThunk.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmmSwDispatch2OnSmmSwDispatchThun
> k/SmmSwDispatch2OnSmmSwDispatchThunk.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSaveI
> nfoHandlerSmm.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/SmramSaveInfoHandlerSmm/SmramSaveI
> nfoHandlerSmm.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwSpare.bin
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageFtwWorking.bin
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Stitch/Gcc/NvStorageVariable.bin
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_HEADER.bin
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_HEADER_SPILOC
> K.bin
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIHeader/Vacant.bin
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Stitch/IFWIStitch.bat
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Stitch/MNW2_Stitch_Config.txt
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/UiApp/FrontPage.c
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/UiApp/UiApp.inf
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/IgdOpRegion.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInit.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInitDxe.inf
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcDriver.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.c
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcIsaAcpi.h
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.c
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/Wpce791/LpcSio.h
>  create mode 100644
> Platform/Intel/Vlv2TbltDevicePkg/Wpce791/Wpce791.inf
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.bat
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/bld_vlv.sh
>  create mode 100644 Platform/Intel/Vlv2TbltDevicePkg/cln.sh
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/DdrMemoryControlle
> r.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCBase.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCConfig.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCDxe.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCPeim.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCRegs.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/IntelQNCLib.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/QNCAccessLib
> .h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Library/QNCSmmLib.
> h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Ppi/QNCMemoryInit.
> h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/PchInfo.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/PlatformPoli
> cy.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/QncS3Supp
> ort.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/SmmIchnDis
> patch2.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/Spi.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QNCAccess.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QNCCommonDefiniti
> ons.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Include/QuarkNcSocId.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/Common
> Header.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNC
> Lib.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNC
> Lib.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/PciExpres
> s.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.uni
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/BaseAc
> cess.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/QNCAc
> cessLib.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/QNCAc
> cessLib.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/Runtim
> eAccess.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/Runtim
> eQNCAccessLib.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCSmmLib/QNCSm
> mLib.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/QNCSmmLib/QNCSm
> mLib.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/Rese
> tSystemLib.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/Rese
> tSystemLib.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/CommonHe
> ader.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/SmbusLib.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/SmbusLib.in
> f
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/
> SmmCpuFeaturesLib.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/
> SmmCpuFeaturesLib.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/
> SmmCpuFeaturesLib.uni
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInit.
> c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInit.
> h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInit
> Pei.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/core_types.
> h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/gen5_iosf_s
> b_definitions.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/general_defi
> nitions.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/hte.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/hte.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/io.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/lprint.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit_util
> s.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit_util
> s.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/memory_op
> tions.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/mrc.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/mrc.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/platform.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/prememinit.
> c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/prememinit.
> h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/CommonHeade
> r.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.
> c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.
> h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInitDxe.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCRootPorts.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbus.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbusExec
> .c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Suppor
> t.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Suppor
> t.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Suppor
> t.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/S
> mmAccess.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/S
> mmAccessDriver.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/S
> mmAccessDriver.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmControlDxe/S
> mmControlDriver.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmControlDxe/S
> mmControlDxe.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDisp
> atcher/CommonHeader.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDisp
> atcher/QNC/QNCSmmGpi.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDisp
> atcher/QNC/QNCSmmHelpers.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDisp
> atcher/QNC/QNCSmmPeriodicTimer.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDisp
> atcher/QNC/QNCSmmQncn.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDisp
> atcher/QNC/QNCSmmSw.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDisp
> atcher/QNC/QNCSmmSx.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDisp
> atcher/QNCSmm.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDisp
> atcher/QNCSmmCore.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDisp
> atcher/QNCSmmDispatcher.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDisp
> atcher/QNCSmmHelpers.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDisp
> atcher/QNCSmmHelpers.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDisp
> atcher/QNCSmmRegisters.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDisp
> atcher/QNCxSmmHelpers.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmAccessPei/Sm
> mAccessPei.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmAccessPei/Sm
> mAccessPei.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/Sm
> mControlPei.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/Sm
> mControlPei.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Common/SpiCommon.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Common/SpiCommon.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiRuntime.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiSmm.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchSpi.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchSpi.h
>  create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dec
>  create mode 100644 Silicon/Intel/QuarkSocPkg/QuarkSocPkg.dsc
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/CEATA.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/I2cRegs.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Ioh.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/IohAccess.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/IohCommonDefinitio
> ns.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Library/I2cLib.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/Library/IohLib.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/MMC.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/SDCard.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Include/SDHostIo.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/CommonHeader.
> h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohBds.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohData.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohInit.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohInitDxe.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/CommonHeade
> r.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/I2cLib.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/I2cLib.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/CommonHead
> er.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/IohLib.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Library/IohLib/IohLib.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/C
> omponentName.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/C
> omponentName.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/S
> DController.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/S
> DController.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/S
> DControllerDxe.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe
> /CEATA.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe
> /CEATABlockIo.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe
> /ComponentName.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe
> /ComponentName.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe
> /MMCSDBlockIo.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe
> /MMCSDTransfer.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe
> /SDMediaDevice.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe
> /SDMediaDevice.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe
> /SDMediaDeviceDxe.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/ComponentNa
> me.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/ComponentNa
> me.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Descriptor.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDebug.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDebug.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDxe.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciSched.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciSched.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/Descriptor.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciPei.inf
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciSched.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciSched.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.h
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.c
>  create mode 100644
> Silicon/Intel/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/98_LINK.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTablePlatform.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTables.inf
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/CPU.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/DSDT.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facp/Facp.aslc
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Facs/Facs.aslc
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/GloblNvs.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Gpe.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/HOST_BUS.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Hpet/Hpet.aslc
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELGFX.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/INTELISPDev2.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOGBDA.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOMOBF.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOSBCB.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IgdOpRn.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/IoTVirtualDevice.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LPC_DEV.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/LpcB.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Lpit/Lpit.aslc
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Madt/Madt30.aslc
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Mcfg/Mcfg.aslc
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PCI_DRC.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Pch.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchAudio.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchEhci.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchLpss.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchPcie.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchScc.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchSmb.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PchXhci.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/PciTree.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Platform.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RTD3.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/RhProxy.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/THERMAL.ASL
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/UsbSbd.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Video.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Vlv.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/Wsmt/Wsmt.aslc
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/AcpiTablesPCAT/token.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Guid/Vlv2DeviceRefCodePkgTo
> kenSpace.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/PttPassThruPpi.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Ppi/fTPMPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/Include/Protocol/PttPassThru.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Guid/Po
> werManagementAcpiTableStorage.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Ppi/VlvP
> olicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Protocol/
> PpmPlatformPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/Include/Types.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/PowerManagementAcpiTables.inf
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/Ssdt/ApCst.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/Ssdt/ApIst.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/Ssdt/ApTst.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/Ssdt/Cpu0Cst.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/Ssdt/Cpu0Ist.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/Ssdt/Cpu0Tst.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManageme
> nt/AcpiTables/Ssdt/CpuPm.asl
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> PlatformBaseAddresses.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Ppi/Capsule.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Ppi/PlatformMemoryRange.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Ppi/PlatformMemorySize.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Ppi/SmmAccess.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Ppi/VlvMmioPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Ppi/VlvPeiInit.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Ppi/VlvPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Protocol/IgdOpRegion.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Protocol/MemInfo.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Protocol/PlatformGopPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Protocol/VlvPlatformPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> Valleyview.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> VlvAccess.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/NorthCluster/Include/
> VlvCommonDefinitions.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Guid/PchInitVar.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Guid/SataControllerGuid.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Guid/SmbusArpMap.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Guid/Vlv2Variable.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/I
> ndustryStandard/CeAta.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/I
> ndustryStandard/Mmc.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/I
> ndustryStandard/SdCard.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/L
> ibrary/I2CLib.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/L
> ibrary/PchPlatformLib.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchAccess.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchCommonDefinitions.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchRegs.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchRegs/PchRegsHda.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchRegs/PchRegsLpss.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchRegs/PchRegsPcie.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchRegs/PchRegsPcu.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchRegs/PchRegsRcrb.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchRegs/PchRegsSata.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchRegs/PchRegsScc.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchRegs/PchRegsSmbus.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchRegs/PchRegsSpi.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> PchRegs/PchRegsUsb.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Ppi/PchInit.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Ppi/PchPeiInit.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Ppi/PchPlatformPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Ppi/PchUsbPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Ppi/PeiBlockIo.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Ppi/Sdhc.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Ppi/SmbusPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Ppi/Spi.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/ActiveBios.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/ActiveBiosProtocol.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/DxePchPolicyUpdateProtocol.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/EmmcCardInfoProtocol.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/Gpio.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/HwWatchdogTimer.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/I2cBus.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/PchExtendedReset.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/PchInfo.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/PchPlatformPolicy.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/PchReset.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/PchS3Support.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/SdHostIo.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/SmbiosSlotPopulation.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/SmmIchnDispatchEx.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/SmmSmbus.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/Spi.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Protocol/TcoReset.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> Rsci.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/ValleyView2Soc/SouthCluster/Include/
> TianoApi.h
>  create mode 100644
> Silicon/Intel/Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
>  create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.c
>  create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.h
>  create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.inf
>  create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.c
>  create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapDmaLib.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapLib.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Dma
> .h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpio
> .h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpm
> c.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530I2c.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Inter
> rupt.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530MM
> CHS.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Pad
> Configuration.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Prc
> m.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Time
> r.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Uart
> .h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Usb.
> h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Include/TPS65950.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/HardwareInterrupt.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/InterruptDxe.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphic
> sOutputBlt.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphic
> sOutputDxe.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphic
> sOutputDxe.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphic
> sOutputDxe.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/Debu
> gAgentTimerLib.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/Debu
> gAgentTimerLib.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.i
> nf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/Omap3
> 5xxTimerLib.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/TimerLi
> b.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib
> .c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib
> .inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTime
> ClockLib.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTime
> ClockLib.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.i
> nf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.h
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dec
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dsc
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.inf
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/Timer.c
>  create mode 100644
> Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/TimerDxe.inf
> 
> --
> 2.21.0.windows.1


^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2019-05-13 21:03 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-05-10  3:34 [edk2-platforms: Patch 0/8] Add packages from edk2 Michael D Kinney
2019-05-10  3:34 ` [edk2-platforms: Patch 1/8] Silicon/TexasInsturments: Import Omap35xxPkg " Michael D Kinney
2019-05-10 17:56   ` Leif Lindholm
2019-05-10 19:16     ` Michael D Kinney
2019-05-10 19:54       ` Leif Lindholm
2019-05-10  3:34 ` [edk2-platforms: Patch 2/8] Platform/BeagleBoard: Import BeagleBoardPkg " Michael D Kinney
2019-05-10  3:34 ` [edk2-platforms: Patch 3/8] Silicon/Intel: Import QuarkSocPkg " Michael D Kinney
2019-05-10  3:34 ` [edk2-platforms: Patch 4/8] Platform/QuarkPlatformPkg: Import QuarkPlatformPkg " Michael D Kinney
2019-05-10  3:34 ` [edk2-platforms: Patch 5/8] Platform/Vlv2DeviceRefCodePkg: Import Vlv2DeviceRefCodePkg " Michael D Kinney
2019-05-13  2:52   ` Sun, Zailiang
2019-05-10  3:34 ` [edk2-platforms: Patch 6/8] Platform/Vlv2TbltDevicePkg: Import Vlv2TbltDevicePkg " Michael D Kinney
2019-05-13  2:52   ` Sun, Zailiang
2019-05-10  3:34 ` [edk2-platforms: Patch 7/8] Drivers/OptionRomPkg: Import OptionRomPkg " Michael D Kinney
2019-05-11  1:52   ` Ni, Ray
2019-05-10  3:34 ` [edk2-platforms: Patch 8/8] edk2-platforms: Update Maintainers.txt/Readme.md for imported packages Michael D Kinney
2019-05-10 18:04   ` [edk2-devel] " Leif Lindholm
2019-05-13  2:52   ` Sun, Zailiang
2019-05-10  5:14 ` [edk2-devel] [edk2-platforms: Patch 0/8] Add packages from edk2 Liming Gao
2019-05-10  6:17   ` Michael D Kinney
2019-05-10  7:32     ` Liming Gao
2019-05-10 18:49       ` Kubacki, Michael A
2019-05-11  2:12 ` Ni, Ray
2019-05-13 21:03 ` Steele, Kelly

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox